pax_global_header00006660000000000000000000000064152237535220014520gustar00rootroot0000000000000052 comment=adaa6fc0ca1da8847f216f76899df3f731878e83 pgsql-ogr-fdw-1.1.9/000077500000000000000000000000001522375352200142215ustar00rootroot00000000000000pgsql-ogr-fdw-1.1.9/.astylerc000066400000000000000000000003451522375352200160520ustar00rootroot00000000000000--style=allman --indent=tab=4 --max-code-length=120 --lineend=linux --unpad-paren --pad-oper --pad-header --align-pointer=type --align-reference=type --break-closing-braces --add-braces --break-return-type --break-after-logical pgsql-ogr-fdw-1.1.9/.editorconfig000066400000000000000000000006731522375352200167040ustar00rootroot00000000000000# http://editorconfig.org # top-most EditorConfig file root = true # these are the defaults [*] charset = utf-8 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true # Test files need kid gloves [*.{source,out}] insert_final_newline = true trim_trailing_whitespace = false # C files want tab indentation [*.{c,h,md}] indent_style = tab indent_size = 4 # Makefiles want tab indentation [Makefile] indent_style = tab pgsql-ogr-fdw-1.1.9/.github/000077500000000000000000000000001522375352200155615ustar00rootroot00000000000000pgsql-ogr-fdw-1.1.9/.github/workflows/000077500000000000000000000000001522375352200176165ustar00rootroot00000000000000pgsql-ogr-fdw-1.1.9/.github/workflows/ci.yml000066400000000000000000000014301522375352200207320ustar00rootroot00000000000000# GitHub Actions for pgSQL OGR-FDW # # Paul Ramsey name: "CI" on: [push, pull_request] jobs: linux: name: PG ${{ matrix.pg }} runs-on: ubuntu-latest container: image: pgxn/pgxn-tools strategy: fail-fast: false matrix: pg: [15, 16, 17, 18, 19] steps: - name: 'Check Out' uses: actions/checkout@v6 - name: 'Start PostgreSQL ${{ matrix.pg }}' run: pg-start ${{ matrix.pg }} - name: 'Install GDAL' run: | apt-get update apt-get -y install libgdal-dev - name: 'Build & Install' run: | export PG_CFLAGS=-Werror make && make install - name: 'Test' run: PGUSER=postgres make installcheck || (cat regression.diffs && false) pgsql-ogr-fdw-1.1.9/.gitignore000066400000000000000000000002371522375352200162130ustar00rootroot00000000000000*.o *.a *.so *.dll *.dylib *.pc ogr_fdw_info.dSYM/ ogr_fdw_info* sql/ogr_fdw.sql expected/ogr_fdw.out results/ regression.diffs regression.out tmp_check/ log/ pgsql-ogr-fdw-1.1.9/FAQ.md000066400000000000000000000040321522375352200151510ustar00rootroot00000000000000# Frequently Asked Questions ### ODBC connections work in `ogr_fdw_info.exe` but not in the database, why? 1. One possibility is that you registered DSN under USER instead of System. It should be system since otherwise it will only work under the account you are logged in as. Since `ogr_fdw_info.exe` is a client app, it will give you a false sense of success since ODBC will in server, run under the context of the PostgreSQL service account. Verify that you have a System DSN (and **not** a User DSN). 2. If you used the Windows installer for PostgreSQL, it starts up PostgreSQL using Network Service account. I always manually switch it to a real user account since I need it to access some network resources. I never tested, but I suspect ODBC keys may not be readable by Network Service account. If change #1 doesn't work, try changing PostgreSQL to run under a regular user account. Make sure that user has full control of the PostgreSQL data folder. ### Do I need ODBC to read an MS Access database? You shouldn't need to do ODBC for MS Access, should be able to do: ogr_fdw_info.exe -s "D:\FDW Data\My Folder\MYFILE.MDB" As an added bonus, using a direct access shouldn't need to read ODBC registry keys since it's a DNSless connection. ### Why doesn't my MS Access connection work? If your MS Access database is on a network share, your PostgreSQL service account needs to be able to access it by the path you use. For MS Access databases it also has to have write permissions. The reason is MS Access databases use a locking file to manage access, so all users that have read permission also need to have write permission into the folder to create the lock file and delete the lock file (if they are the last ones in) if it doesn't exist. Also note: even if the PostgreSQL service account can access the folder `\\S\Files`, if you map it to say `S:\` the connection will not work if the mapped drive is not set under the user account that PostgreSQL runs under. (That said – it's safer to use UNCs (`\\S\Files`) instead of mapped drives. pgsql-ogr-fdw-1.1.9/LICENSE.md000066400000000000000000000020721522375352200156260ustar00rootroot00000000000000Copyright (C) 2014 Paul Ramsey Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.pgsql-ogr-fdw-1.1.9/META.json000066400000000000000000000023671522375352200156520ustar00rootroot00000000000000{ "name": "ogr_fdw", "abstract": "OGR foreign data wrapper", "description": "OGR FDW allows you to connect to any OGR supported data source.", "version": "1.1.0", "maintainer": [ "Paul Ramsey " ], "license": { "mit": "http://en.wikipedia.org/wiki/MIT_License" }, "prereqs": { "runtime": { "requires": { "PostgreSQL": "9.3.0" }, "recommends": { "PostgreSQL": "9.3.4" } } }, "provides": { "ogr_fdw": { "file": "ogr_fdw--1.1.sql", "docfile": "README.md", "version": "1.1.0", "abstract": "OGR FDW wrapper" } }, "resources": { "homepage": "https://github.com/pramsey/pgsql-ogr-fdw/", "bugtracker": { "web": "https://github.com/pramsey/pgsql-ogr-fdw/issues" }, "repository": { "url": "https://github.com/pramsey/pgsql-ogr-fdw.git", "web": "https://github.com/pramsey/pgsql-ogr-fdw/", "type": "git" } }, "generated_by": "Paul Ramsey", "meta-spec": { "version": "1.0.0", "url": "http://pgxn.org/meta/spec.txt" }, "tags": [ "ogr", "gdal", "gis", "fdw", "postgis" ] } pgsql-ogr-fdw-1.1.9/Makefile000066400000000000000000000043271522375352200156670ustar00rootroot00000000000000# ogr_fdw/Makefile MODULE_big = ogr_fdw OBJS = \ ogr_fdw.o \ ogr_fdw_deparse.o \ ogr_fdw_common.o \ ogr_fdw_func.o \ stringbuffer_pg.o EXTENSION = ogr_fdw DATA = \ ogr_fdw--1.0--1.1.sql \ ogr_fdw--1.1.sql EXTVERSION = $(shell grep default_version $(EXTENSION).control | \ cut -f2 -d= | tr -d "'" | tr -d " ") REGRESS = ogr_fdw EXTRA_CLEAN = sql/*.sql expected/*.out GDAL_CONFIG = gdal-config GDAL_CFLAGS = $(shell $(GDAL_CONFIG) --cflags) GDAL_LIBS = $(shell $(GDAL_CONFIG) --libs) # For MacOS # GDAL_LIBS += -rpath $(shell $(GDAL_CONFIG) --prefix)/lib PG_CONFIG = pg_config REGRESS_OPTS = --encoding=UTF8 PG_CFLAGS += -D OGR_FDW_VERSION=\"$(EXTVERSION)\" PG_CPPFLAGS += $(GDAL_CFLAGS) LIBS += $(GDAL_LIBS) SHLIB_LINK := $(LIBS) PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS) PG_VERSION_NUM = $(shell pg_config --version | cut -f2 -d' ' | awk -F. '{printf "%d%04d", $$1, $$2}') HAS_IMPORT_SCHEMA = $(shell [ $(PG_VERSION_NUM) -ge 90500 ] && echo yes) # order matters, file first, import last REGRESS = file pgsql ifeq ($(HAS_IMPORT_SCHEMA),yes) REGRESS += import endif # work around pg15 change to regression file variable # substitution for @abs_srcdir@ until we can drop older # version support # https://github.com/postgres/postgres/commit/d1029bb5a26cb84b116b0dee4dde312291359f2a PG15 := $(shell [ $(PG_VERSION_NUM) -ge 150000 ] && echo yes) ifeq ($(PG15),yes) sql/%.sql: input/%.source perl -pe 's#\@abs_srcdir\@#$(PWD)#g' < $< > $@ expected/%.out: output/%.source perl -pe 's#\@abs_srcdir\@#$(PWD)#g' < $< > $@ SQLFILES := sql/file.sql sql/import.sql sql/pgsql.sql sql/postgis.sql OUTFILES := expected/file.out expected/import.out expected/pgsql.out expected/postgis.out installcheck: $(SQLFILES) $(OUTFILES) endif ############################################################### # Build the utility program after PGXS to override the # PGXS environment CFLAGS = $(GDAL_CFLAGS) LIBS = $(GDAL_LIBS) ogr_fdw_info$(X): ogr_fdw_info.o ogr_fdw_common.o stringbuffer.o $(CC) $(CFLAGS) -o $@ $^ $(LIBS) clean-exe: rm -f ogr_fdw_info$(X) ogr_fdw_info.o stringbuffer.o install-exe: all $(INSTALL_PROGRAM) ogr_fdw_info$(X) '$(DESTDIR)$(bindir)' all: ogr_fdw_info$(X) clean: clean-exe install: install-exe pgsql-ogr-fdw-1.1.9/README.md000066400000000000000000000377501522375352200155140ustar00rootroot00000000000000[![Build Status](https://github.com/pramsey/pgsql-ogr-fdw/actions/workflows/ci.yml/badge.svg)](https://github.com/pramsey/pgsql-ogr-fdw/actions/workflows/ci.yml) # PostgreSQL OGR Foreign Data Wrapper ## Motivation OGR is the **vector** half of the [GDAL](http://www.gdal.org/) spatial data access library. It allows access to a [large number of GIS data formats](http://www.gdal.org/ogr_formats.html) using a [simple C API](http://www.gdal.org/ogr__api_8h.html) for data reading and writing. Since OGR exposes a simple table structure and PostgreSQL [foreign data wrappers](https://wiki.postgresql.org/wiki/Foreign_data_wrappers) allow access to table structures, the fit seems pretty perfect. ## Limitations This implementation currently has the following limitations: * **PostgreSQL 11 or higher.** * **Limited non-spatial query restrictions are pushed down to OGR.** OGR only supports a [minimal set](https://gdal.org/user/ogr_sql_dialect.html) of SQL operators (>, <, <=, >=, =). * **Only bounding box filters (&&) are pushed down.** Spatial filtering is possible, but only bounding boxes, and only using the && operator. * **OGR connections every time** Rather than pooling OGR connections, each query makes (and disposes of) **two** new ones, which seems to be the largest performance drag at the moment for restricted (small) queries. * **All columns are retrieved every time.** PostgreSQL foreign data wrappers don't require all columns all the time, and some efficiencies can be gained by only requesting the columns needed to fulfill a query. This would be a minimal efficiency improvement, but can be removed given some development time, since the OGR API supports returning a subset of columns. ## Download * Windows * Via [Stackbuilder](https://www.postgresql.org/download/windows/) (part of PostGIS Bundle) * Linux * [Arch Linux](https://aur.archlinux.org/packages/pgsql-ogr-fdw/) * [Ubuntu](https://launchpad.net/ubuntu/+source/pgsql-ogr-fdw), [PGDG Apt: Debian / Ubuntu](https://apt.postgresql.org) * [PGDG Yum: Redhat EL, CentOS, Rocky](https://yum.postgresql.org/) * OSX ## Basic Operation In order to access geometry data from OGR, the PostGIS extension has to be installed: if it is not installed, geometry will be represented as bytea columns, with well-known binary (WKB) values. To build the wrapper, make sure you have the GDAL library and development packages (is `gdal-config` on your path?) installed, as well as the PostgreSQL development packages (is `pg_config` on your path?) Build the wrapper with `make` and `make install`. Now you are ready to create a foreign table. First install the `postgis` and `ogr_fdw` extensions in your database. ```sql -- Install the required extensions CREATE EXTENSION postgis; CREATE EXTENSION ogr_fdw; ``` For a test data set, copy the `pt_two` example shape file from the `data` directory to a location where the PostgreSQL server can read it (like `/tmp/test/` for example). Use the `ogr_fdw_info` tool to read an OGR data source and output a server and table definition for a particular layer. (You can write these manually, but the utility makes it a little more foolproof.) ``` # ogr_fdw_info -f Supported Formats: -> "PCIDSK" (read/write) -> "netCDF" (read/write) ... -> "HTTP" (readonly) # ogr_fdw_info -s /tmp/test Layers: pt_two # ogr_fdw_info -s /tmp/test -l pt_two CREATE SERVER "myserver" FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource '/tmp/test', format 'ESRI Shapefile' ); CREATE FOREIGN TABLE "pt_two" ( fid integer, "geom" geometry(Point, 4326), "name" varchar, "age" integer, "height" real, "birthdate" date ) SERVER "myserver" OPTIONS (layer 'pt_two'); ``` Copy the `CREATE SERVER` and `CREATE FOREIGN SERVER` SQL commands into the database and you'll have your foreign table definition. ``` Foreign table "public.pt_two" Column | Type | Modifiers | FDW Options ----------+-------------------+-----------+------------- fid | integer | | geom | geometry | | name | character varying | | age | integer | | height | real | | birthday | date | | Server: tmp_shape FDW Options: (layer 'pt_two') ``` And you can query the table directly, even though it's really just a shape file. ```sql SELECT * FROM pt_two; ``` ``` fid | geom | name | age | height | birthday -----+--------------------------------------------+-------+-----+--------+------------ 0 | 0101000000C00497D1162CB93F8CBAEF08A080E63F | Peter | 45 | 5.6 | 1965-04-12 1 | 010100000054E943ACD697E2BFC0895EE54A46CF3F | Paul | 33 | 5.84 | 1971-03-25 ``` You can also apply filters, and see the portions that will be pushed down to the OGR driver, by setting the debug level to `DEBUG1`. ```sql SET client_min_messages = debug1; SELECT name, age, height FROM pt_two WHERE height < 5.7 AND geom && ST_MakeEnvelope(0, 0, 1, 1); ``` ``` DEBUG: OGR SQL: (height < 5.7) DEBUG: OGR spatial filter (0 0, 1 1) name | age | height -------+-----+-------- Peter | 45 | 5.6 (1 row) ``` ## Examples ### WFS FDW Since we can access any OGR data source as a table, how about a public WFS server? ```sql CREATE EXTENSION postgis; CREATE EXTENSION ogr_fdw; CREATE SERVER geoserver FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource 'WFS:https://demo.geo-solutions.it/geoserver/wfs', format 'WFS' ); CREATE FOREIGN TABLE topp_states ( fid bigint, the_geom Geometry(MultiSurface,4326), gml_id varchar, state_name varchar, state_fips varchar, sub_region varchar, state_abbr varchar, land_km double precision, water_km double precision, persons double precision, families double precision, houshold double precision, male double precision, female double precision, workers double precision, drvalone double precision, carpool double precision, pubtrans double precision, employed double precision, unemploy double precision, service double precision, manual double precision, p_male double precision, p_female double precision, samp_pop double precision ) SERVER "geoserver" OPTIONS (layer 'topp:states'); ``` ### FGDB FDW Unzip the `Querying.zip` file from the `data` directory to get a `Querying.gdb` file, and put it somewhere public (like `/tmp`). Now run the `ogr_fdw_info` tool on it to get a table definition. ```sql CREATE SERVER fgdbtest FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource '/tmp/Querying.gdb', format 'OpenFileGDB' ); CREATE FOREIGN TABLE cities ( fid integer, geom geometry(Point, 4326), city_fips varchar, city_name varchar, state_fips varchar, state_name varchar, state_city varchar, type varchar, capital varchar, elevation integer, pop1990 integer, popcat integer ) SERVER fgdbtest OPTIONS (layer 'Cities'); ``` Query away! ### PostgreSQL FDW Wraparound action! Handy for testing. Connect your database back to your database and watch the fur fly. This is only for testing, for best performance you should use postgres_fdw foreign data wrapper even when querying a PostGIS enabled database. ```sql CREATE TABLE apostles ( fid serial primary key, geom geometry(Point, 4326), joined integer, name text, height real, born date, clock time, ts timestamp ); INSERT INTO apostles (name, geom, joined, height, born, clock, ts) VALUES ('Peter', 'SRID=4326;POINT(30.31 59.93)', 1, 1.6, '1912-01-10', '10:10:01', '1912-01-10 10:10:01'), ('Andrew', 'SRID=4326;POINT(-2.8 56.34)', 2, 1.8, '1911-02-11', '10:10:02', '1911-02-11 10:10:02'), ('James', 'SRID=4326;POINT(-79.23 42.1)', 3, 1.72, '1910-03-12', '10:10:03', '1910-03-12 10:10:03'), ('John', 'SRID=4326;POINT(13.2 47.35)', 4, 1.45, '1909-04-01', '10:10:04', '1909-04-01 10:10:04'), ('Philip', 'SRID=4326;POINT(-75.19 40.69)', 5, 1.65, '1908-05-02', '10:10:05', '1908-05-02 10:10:05'), ('Bartholomew', 'SRID=4326;POINT(-62 18)', 6, 1.69, '1907-06-03', '10:10:06', '1907-06-03 10:10:06'), ('Thomas', 'SRID=4326;POINT(-80.08 35.88)', 7, 1.68, '1906-07-04', '10:10:07', '1906-07-04 10:10:07'), ('Matthew', 'SRID=4326;POINT(-73.67 20.94)', 8, 1.65, '1905-08-05', '10:10:08', '1905-08-05 10:10:08'), ('James Alpheus', 'SRID=4326;POINT(-84.29 34.07)', 9, 1.78, '1904-09-06', '10:10:09', '1904-09-06 10:10:09'), ('Thaddaeus', 'SRID=4326;POINT(79.13 10.78)', 10, 1.88, '1903-10-07', '10:10:10', '1903-10-07 10:10:10'), ('Simon', 'SRID=4326;POINT(-85.97 41.75)', 11, 1.61, '1902-11-08', '10:10:11', '1902-11-08 10:10:11'), ('Judas Iscariot', 'SRID=4326;POINT(35.7 32.4)', 12, 1.71, '1901-12-09', '10:10:12', '1901-12-09 10:10:12'); CREATE SERVER wraparound FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource 'Pg:dbname=fdw user=postgres', format 'PostgreSQL' ); CREATE FOREIGN TABLE apostles_fdw ( fid integer, geom geometry(Point, 4326), joined integer, name text, height real, born date, clock time, ts timestamp ) SERVER wraparound OPTIONS (layer 'apostles'); SELECT * FROM apostles_fdw; ``` ## Advanced Features ### Writeable FDW Tables If the OGR driver you are using supports it, you can insert/update/delete records from your FDW tables. For file-backed drivers, the user under which `postgres` runs will need read/write access to the file being altered. For database-backed drivers, your connection needs a user with read/write permissions to the database. By default, servers and tables are updateable if the OGR driver supports it, but you can turn off updateability at a server or table level using the `updateable` option: ```sql ALTER SERVER myserver OPTIONS (ADD updateable 'false'); ALTER FOREIGN TABLE mytable OPTIONS (ADD updateable 'false'); ``` Writeable tables only work if you have included a `fid` column in your table definition. By default, tables imported by `IMPORT FOREIGN SCHEMA` or using the example SQL code from `ogr_fdw_info` include a `fid` column. ### Column Name Mapping You can create an FDW table with any subset of columns from the OGR source you like, just by using the same column names as the source: ```sql CREATE FOREIGN TABLE typetest_fdw_partial ( clock time, name varchar ) SERVER wraparound OPTIONS (layer 'typetest'); ``` You can also explicitly map remote column names to different local names using the `column_name` option: ```sql CREATE FOREIGN TABLE typetest_fdw_mapped ( fid bigint, supertime time OPTIONS (column_name 'clock'), thebestnamething varchar OPTIONS (column_name 'name') ) SERVER wraparound OPTIONS (layer 'typetest'); ``` ### Automatic Foreign Table Creation **This feature is only available with PostgreSQL 9.5 and higher** You can use the PostgreSQL `IMPORT FOREIGN SCHEMA` command to [import table definitions from an OGR data source](http://www.postgresql.org/docs/9.5/static/sql-importforeignschema.html). #### Import All Tables If you want to import all tables in the OGR data source use the special schema called "ogr_all". ```sql CREATE SCHEMA fgdball; IMPORT FOREIGN SCHEMA ogr_all FROM SERVER fgdbtest INTO fgdball; ``` #### Import a Subset of Tables Not all OGR data sources have a concept of schema, so we use the remote schema string as a prefix to match OGR layers. The matching is case sensitive, so make sure casing matches your layer names. For example, the following will only import tables that start with *CitiesIn*. As long as you quote, you can handle true schemaed databases such as SQL Server or PostgreSQL by using something like *"dbo."* ```sql CREATE SCHEMA fgdbcityinf; IMPORT FOREIGN SCHEMA "CitiesIn" FROM SERVER fgdbtest INTO fgdbcityinf; ``` You can also use PostgreSQL clauses `LIMIT TO` and `EXCEPT` to restrict the tables you are importing. ```sql CREATE SCHEMA fgdbcitysub; -- import only layer called Cities IMPORT FOREIGN SCHEMA ogr_all LIMIT TO(cities) FROM server fgdbtest INTO fgdbcitysub ; -- import only layers not called Cities or Countries IMPORT FOREIGN SCHEMA ogr_all EXCEPT (cities, countries) FROM server fgdbtest INTO fgdbcitysub; -- With table laundering turned off, need to use exact layer names DROP SCHEMA IF EXISTS fgdbcitysub CASCADE; -- import with un-laundered table name IMPORT FOREIGN SCHEMA ogr_all LIMIT TO("Cities") FROM server fgdbtest INTO fgdbcitysub OPTIONS (launder_table_names 'false') ; ``` #### Mixed Case and Special Characters In general, PostgreSQL prefers table names with [simple numbers and letters](http://www.postgresql.org/docs/9.5/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS), no punctuation or special characters. By default, when `IMPORT FOREIGN SCHEMA` is run on an OGR foreign data server, the table names and column names are "laundered" -- all upper case is converted to lowercase and special characters such as spaces and punctuation are replaced with "_". Laundering is not desirable in all cases. You can override this behavior with two `IMPORT FOREIGN SCHEMA` options specific to `ogr_fdw` servers: `launder_column_names` and `launder_table_names`. To preserve casing and other funky characters in both column names and table names, do the following: ```sql CREATE SCHEMA fgdbcitypreserve; IMPORT FOREIGN SCHEMA ogr_all FROM SERVER fgdbtest INTO fgdbpreserve OPTIONS ( launder_table_names 'false', launder_column_names 'false' ); ``` ### GDAL Options The behavior of your GDAL/OGR connection can be altered by passing GDAL `config_options` to the connection when you set up the server. Most GDAL/OGR drivers have some specific behaviours that are controlled by configuration options. For example, the "[ESRI Shapefile](http://www.gdal.org/drv_shapefile.html)" driver includes a `SHAPE_ENCODING` option that controls the character encoding applied to text data. Since many Shapefiles are encoded using LATIN1, and most PostgreSQL databases are encoded in UTF-8, it is useful to specify the encoding to get proper handling of special characters like accents. ```sql CREATE SERVER myserver_latin1 FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource '/tmp/test', format 'ESRI Shapefile', config_options 'SHAPE_ENCODING=LATIN1' ); ``` Multiple config options can be passed at one time by supplying a **space-separated** list of options. If you are using GDAL 2.0 or higher, you can also pass "open options" to your OGR foreign data wrapper, using the `open_options` parameter. In GDAL 2.0, the global `SHAPE_ENCODING` option has been superceded by a driver-specific `ENCODING` option, which can be called like this: ```sql CREATE SERVER myserver_latin1 FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource '/tmp/test', format 'ESRI Shapefile', open_options 'ENCODING=LATIN1' ); ``` ### GDAL Debugging If you are getting odd behavior and you want to see what GDAL is doing behind the scenes, enable debug logging in your server: ```sql CREATE SERVER myserver_latin1 FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource '/tmp/test', format 'ESRI Shapefile', config_options 'SHAPE_ENCODING=LATIN1 CPL_DEBUG=ON' ); ``` GDAL-level messages will be logged at the PostgreSQL **DEBUG2** level, so to see them when running a query, alter your `client_min_messages` setting. ```sql SET client_min_messages = debug2; ``` Once you've figured out your issue, don't forget to remove the `CPL_DEBUG` option from your server definition, and set your messages back to **NOTICE** level. ```sql SET client_min_messages = notice; ALTER SERVER myserver_latin1 OPTIONS ( SET config_options 'SHAPE_ENCODING=LATIN1' ); ``` ### Utility Functions To view the current FDW and GDAL version. ```sql SELECT ogr_fdw_version(); ``` To view the drivers supported by this GDAL. ```sql SELECT unnest(ogr_fdw_drivers()); ``` ### Character Encoding To access sources that have a non-UTF-8 encoding, you may need to specify the character encoding in your server creation line. OGR FDW uses the transcoding built into PostgreSQL, and thus supports all the [encodings that PostgreSQL does](https://www.postgresql.org/docs/current/multibyte.html#CHARSET-TABLE). ```sql CREATE SERVER odbc_latin1 FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource 'ODBC:username@servicename', format 'ODBC', character_encoding 'WIN1250' ); CREATE FOREIGN TABLE featuretable_fdw ( name text, geom geometry(Point, 4326) ) SERVER odbc_latin1 OPTIONS (layer 'featuretable'); ``` pgsql-ogr-fdw-1.1.9/ci/000077500000000000000000000000001522375352200146145ustar00rootroot00000000000000pgsql-ogr-fdw-1.1.9/ci/gdal_build.sh000066400000000000000000000004661522375352200172440ustar00rootroot00000000000000#!/bin/bash GDAL_VERSION=$1 echo "Building GDAL $GDAL_VERSION" wget http://download.osgeo.org/gdal/$GDAL_VERSION/gdal-$GDAL_VERSION.tar.xz tar xJf gdal-$GDAL_VERSION.tar.xz; cd gdal-$GDAL_VERSION ./configure --prefix=/usr --enable-debug --without-libtool make -j4 sudo make install cd .. gdalinfo --version pgsql-ogr-fdw-1.1.9/ci/pg_hba.conf000066400000000000000000000006031522375352200167020ustar00rootroot00000000000000# TYPE DATABASE USER ADDRESS METHOD # "local" is for Unix domain socket connections only local all postgres trust # IPv4 local connections: host all postgres 127.0.0.1/32 trust # IPv6 local connections: host all postgres ::1/128 trust pgsql-ogr-fdw-1.1.9/data/000077500000000000000000000000001522375352200151325ustar00rootroot00000000000000pgsql-ogr-fdw-1.1.9/data/2launder.dbf000066400000000000000000000004501522375352200173220ustar00rootroot00000000000000_¡C2ameC2ageNHeightNb-rthdateD Peter 45 5.6019650412 Paul 33 5.8419710325 pgsql-ogr-fdw-1.1.9/data/2launder.prj000066400000000000000000000002171522375352200173630ustar00rootroot00000000000000GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]pgsql-ogr-fdw-1.1.9/data/2launder.shp000066400000000000000000000002341522375352200173610ustar00rootroot00000000000000' NèTéC¬Ö—â¿À‰^åJFÏ?À—Ñ,¹?Œºï €æ? À—Ñ,¹?Œºï €æ? TéC¬Ö—â¿À‰^åJFÏ?pgsql-ogr-fdw-1.1.9/data/2launder.shx000066400000000000000000000001641522375352200173730ustar00rootroot00000000000000' :èTéC¬Ö—â¿À‰^åJFÏ?À—Ñ,¹?Œºï €æ?2 @ pgsql-ogr-fdw-1.1.9/data/Querying.zip000066400000000000000000006153361522375352200174770ustar00rootroot00000000000000PK ‰q�E Querying.gdb/UT Â\�Tú\�Tux õPK‰q�EWá�¦*XQuerying.gdb/a00000001.freelistUT Â\�TÂ\�Tux õíס Á|tBÿÝÁ ÇìšK ©$«�óÿï­oÝPK‰q�EÄÞË–Pn!Querying.gdb/a00000001.gdbindexesUT Â\�TÂ\�Tux õcb```b7†xO ÍÀ Äÿÿ3I& †ˆñqC"CCC*C1ƒC%ƒ�Ÿ äAÔ10€tp±ЬpW†  ¸M 8PK‰q�EòÅ.ÍaQuerying.gdb/a00000001.gdbtableUT Â\�T×\�Tux õmŽ» Â0…�µ VT¼‚Î>…ƒ¥ µ»‰ˆM±qðm|Içúÿ©Šƒ��$ß9¹TÄœ¨”CTÊyöÞsîó‚|^„¨ûž¿…À’‡k+(h+\)°|ÈLjòî:\ìw÷ÜÊËRX¡Í ï7NÂErK%«kW΄UBÇò˜³o ö]áÌ„~L,5ÕMšŸUæÒ)1þ—&÷LºF�h}_Ûç·ØÆ2Óê 6æä‘zEQ_*«Ê–ûx¹�Ò£aÕ$~À PK‰q�E°UôÝH Querying.gdb/a00000001.gdbtablxUT Â\�T×\�Tux õíÊA €0ÑÝN@ ªõPh@ VØ! æ%²M:EDÖ–Ú\ÛkÑÉ 9ÉE’¯+yl\í{J’$I’$Iú¿|‡PK‰q�E´(û2¸'Querying.gdb/a00000001.TablesByName.atxUT Â\�TÂ\�Tux õí˜M‚0…þG/ÁÍ bÑ&j‰Å·á¨¾¶ �&2‹ùÈ›6aóe¦]¬‘Øôû 3gÌŒY2+fÊdøž cà‘ |^ý,.¨àDù°ÇÛXÜhhDú….œqe=¡ˆ=u´õ8rW�6ýOý´¬ÿ?¥C?i·dè7VŸÞù…¹Öœ¬å�.¸:¾‘äçi—N]° ¶•ˆ>ýZ&͸Œ¦2º¨(Š¢(Š¢üN—gýWýã/@ØßPK‰q�E0ìåó°Querying.gdb/a00000002.gdbtableUT Â\�TÂ\�Tux õ�TñkÓ@>éêæèt*‚ Ht7p•I-Óß’ôÒÓd$˜þnËešDÒ+nþUþ…â»Ø¤^šlîÞûÞ÷½ïòz„ÐSX V­~¿–‡ýåYä7ÄæB´ù×èÊPŽBÈ(EzçQP”@šÃÊ‘½<•�ž5)ŠPŒ.‘ v)ì!·%Zì÷ÖªooÓ7‚ÏÈùÆ”�Et1ãJH9�âS.²4Š/9åq–©rW?Q]U'Ø Ç�ªdÃ'Æq_Â<˜`gЉûe ÙÖ³ä{Îæs¾’É* GW�à»fjÅ){!¡zšåh5Äs ±3UÏôpà™_qçˆhE~[X  ¿£Qiøµ0\Dή¸eyByÍñ^­xÍs·ŸØCI:N´Rê­�‚³’Ы8Y$«û�Ç?ë—Üo檃ˆ%€�eàû#RÉ„lù/áƒ6>Yº[Ä ÇOª�æÛº3=u±çáq)¿_\pzQ}qe²„ñüº&MÔ=ªŽOÃ2m\6Ð 8 žE3˜“6õw-,ky¨œHŒÜ'Qr¿˜Å5Ñ—²¨6ËÎk‚oª¥Á^ }V5¢Úã YuÐb•¦aS Ç·ñÞ`~x[m‹CÔíÂ?ÇUM;¨ˆÂÀßXõ q–ç4NçÕ{$wØÈtCË�-}þPK‰q�EzA}n Querying.gdb/a00000002.gdbtablxUT Â\�TÂ\�Tux õíͱ ÂPFá—<…´é^�  8Dº¤Ê(‚�Ö!œ � 8�}Vðp†Tçƒÿ4·¸9¥TÅJì»ÅÒJ6R¸�ÉL.äI¾äTGFò ÒåÈDò&í!Ò“;y‘†o¹I’$I’$Iû¨þÃPK‰q�E)¤!*!Querying.gdb/a00000003.gdbindexesUT Â\�TÂ\�Tux õcd```b7†xO ÍÀ Äÿÿ3I& †ˆPK‰q�E9E€� Querying.gdb/a00000003.gdbtableUT Â\�TÂ\�Tux õcf```âß@ÌÊ€Ü,ZÊÿÄ`!F&O6&¶`† †W† TÀ"ØÜrŠR� Ì¬È"‘ö +”!�!“¡(Ž®* *…G�/TÄ] 7Èì†| ºT†" ú<†d ,Ç…SÆ—ÌS�¿ÿLdtwõwwŽVñáîÁñ†–&J:.Ž!¡¾ÑJ.HBÁ®Aþž.ÑJ13cs Ccs=#K =#Ss##cS3ãØX�€ O_W  îE©©yå™ÉJ:z±:¡~ž!@sSÓ�â`!CsSc#K#SCKKc VpÌ4¤€Ða`º¡EÏÌÏúï8ì€Îï}»uÁ÷cìþ¬üxÉ7)ÀFÿ{t9ŠGýò‹J2âsS‹2“ó@ž1Fò3VY„÷݃ÀÞ7Àê}#CCмÿï?T€Ñ�-úröO¼@Ðûû]ý⺼œ‡º÷!³òŒ®Yçþ°j‰Ô›¨ÞGâÀá}PK‰q�E¸¡ÅÒ- Querying.gdb/a00000003.gdbtablxUT Â\�TÂ\�Tux õíÈÁ Á¨øÓ.ì¿F° ™� \FD´ld3;5vϳê|¦½ÊPK‰q�E,+ƒÁY1Querying.gdb/a00000004.CatItemsByPhysicalName.atxUT Â\�TÂ\�Tux õíØA € Fá§Ô=¼J„�t½ŽÚ@.:@‹�þOf1»‡;èx›¾í‘ï%çg¤pØdv÷}……‰ÕUßi=•Ùê6«ÍÎîODDDDDäÏ®ÚË?¾~nPK‰q�EeF8Øž)Querying.gdb/a00000004.CatItemsByType.atxUT Â\�TÂ\�Tux õí×KªC1à´´[¹3ÁÄ“¡1ɦgí½éc¥à‚ÂB·ðvßuýÌ—à¾á’Š *'ƒ¬HÐfJ�lÚTî­/=+BkâI!c^;O;…šeAaSÈ3TŠ 6©U:¨ÇÓ/ãœsÎ9çœs¿íïõé?ë±…OÿPK‰q�E>‘;Dž#Querying.gdb/a00000004.FDO_UUID.atxUT Â\�TÂ\�Tux õí×M 1à´´WéNÐó³41¹Ô0go§íÜ¡üàÁ[.\B·ðu?ûåÈ5¸_ØHÙªµ \%CB"¨( jÁ¨ÑÄZLûV:5ÔÉ Ò¤Úºtƒ¸$éÄ¡¹à¾õ˜õ\À,) �8Ùf¦E½}ƒ�[á.gYfæÌþÀNd8q On\8*±˜&Ok(þó[Ç.¹SóR|l˜7:ÆYsî³ùÔ›¹Ä#±—kç ò;zRF*1÷û6—x²bºË¨ýC¯¨iɵv?�ìOÖëÞPK‰q�EY@©(•¶GQuerying.gdb/a00000004.gdbtableUT Â\�T×\�Tux õì]}Œ#çYŸ${Ée›£ª”HP�::AïBvý¹»¶/ç|^ßž“õ®³ö^î’§Yûµ=wãgf¼­@A4"€Š¨"QQ>R"´T ¨(@€jJT>DùƒŠö? TUÓ…ÏóÎŒ=¶Çk{×»çÝ}|ºõ;ïû¼¿yŸ�÷}ž÷™ß'ÂüÿÇGîNÁ÷O|ø~?´tšŸìÏÚ}6Ý|H8½*l·&”KÈ ‹‚pÿÔ½Sëº}ð��Þ;Uv„PÓ�šZd¡ŽSŸŒSÂCy¡í¦ ‚,¨B7ÁT*, ¦¦îÁŠ.ò ú0ø.M�åœ#,÷L  ‰Ø4uÒdM¨:"Lݱ‡æOiÜ·.¬ Ë­ÃéE «#ü·à¿%á!áÔ™E(–` È—Æ!½Í§³pÈ Ñ=VNçŠ8^ƒS3÷iû42à©Ðµ§…S§ !ÙóÂgïY2ª°$¤�ùç…³Né¦ð,”ð;,$„¸0-3 §”P�å8åbª‚�®êà¢n‘Ö�nAˆ 18 óºoÀ÷<ÔEà_JHyþÍò`æ=çŒÖNPX[Ü0j9ÄÑ�~Ì$ c¶ÇË„ªCߦ ÃyæàQ~nþäÿ|ñ³ßûòÛÉ÷?÷í¯æ6òOºßß^ùÓ÷þ²ôöÃ[oý­þFôâ¥Óóéü�§Þþý¹�Êk±üE&ŒðÞÏÜzËzõ•'?ókøùÚ“öœ:ñ1ø»ý½×Þ¸õ7¢_Z|ý‡îûùÛÒGôäöwþŽ=œù¹G¾’xùßÿé °€˜Âoß äïþØ«ÛïÿèŸäâ§ÿï§~ö�Ïüò…þÀüòKÆêÅ—#bóÆ¿½ÿƒÏêÆm³!—؃Ϯ®=]ȧÒAøæ”´˜iµˆÛ¦rÁÚi°'Îá_ͼài<'n×U¨š'ÎÕ,«q!ÜÚÚ lEºQ FB¡pðZn¹Pª±º<«h¦%kÞ^ƒ;¹´ö¹;è™i(�’^šœÒ ¦ŒÒR¶ ‡¡sI)-[²ªWó²UK¾ ½‡ÒŠ\gI)h¥kŠZ6˜–ÙnÈZ™•“Y5ôè®—Z|a4I<ÿ²^’ÕE€Þ�MÖj–‚�”펗咥;yC¯f“º®†´®i¬d)ºV° E«ioU»&«Ut®(MQAOF“� &¥E½.ƒÌ{5˜2 ygµb·ƒ¨‚eRÊÉ·tã*3LMF¥`DZ”S´öQZ½ÇÒ¥fµ¢l{š;+à,mÃI¢UÿÒwïÜÙ~÷›Ó?òñßXÿÃ+_ü³`ñ ýnãñ·îÿ‡ßÜ~fùóïýNõS�ý›N+–ÂLdq:�-f3…ìÊåռЮ>ÿ0XlQÞPYK]ÛjœT‹ w[l›=?Ûõ¶ŽjÅh®&³Z6¼XäÒýx¤ÅØáTâ·ä(± Û®€ak®ŽÝs¶kÐH+JµiÈh§O³�-Ý(ÛÖìS}E6WáthÀRÐ9�àÏe…©eÎçꥧ2ébvQ vTKKy~€Él÷7ù²s]Ýz{u“w Á>5'iI³u´Ší6)k®4U%íŠÉS#­±›Šâ´yoJ™²by;µŽ¥`ÇèöÆK~mõªËGJUdÓSÛ>–rz™©ž¦öq?îí5ªŸl&½ü�ƒ™•T.ÓËŒ]ëËŒÝ4™Ì3k¹^fìZ_fì¦Éd&¯7` ó14§ÞßÔœÆÁ,e5‹U™qÈ<ú&|¸jµøóÕjžXe…‰_mÙ ýÔe·‚¾:�!nI/£›úx,5¿°�ˆ‡gÓáðÜl8¼™�§"ñÙPh!”ˆ¥._ž›Ëü48N-e®�R°]\c*÷IfMi¤UÙä|ú8^�±“¯Üú¬CRàì–T}CVa ÎJï­’Ü’Çå}êÖdÓb†—¨§&³mÁøaÀ`‡ f`ÑË�Ó¶S`ðèq'Ú×·zú¸E”OGguïùy”`ºª2#Çê;€0û{q?êsvPÑ‹ÂÏVü—ÄÝ‘õ­;w.¾û«Ÿ|âÃWãºøÒõŸ¿÷õùÚ�?¸m6f^¾ï©ß:;óßÿõü¯¿wÚ²n†OÛaçÍðƒ/¸Uˆ‚ÿOjrƒ |ÐËL¶šã6Ð/í¦9báèÍpÿ`ÛöŠzä‘ÎrDêbKL/;Û¼´ª0Íráp·ÙŽ×ú’Íж½nµ[|ײvóàÕÿHÆ|^÷ŠÁ©ö•�Ó6X`$uf;Ãû¿¾B«°º]¿y9›/ô²ëiòeÙÓ>™±  ÿ¾ÀÓÔŸ·IÞ!Š©b¦�â¼mþÆê!˜döüuçmÛ…½É×Y?öì¶]س &tûz=ï£7»ÖûÊ›&tIå³ÅÔ²Ïâ6ø¯ nëdr•YÎ\M³«+½|eT¶Éã >œyºNêî|5»Ñ�Ï&Ömðßĺ­“ËV:UôåŠ×÷cŠ7ÞÅ�ù|$: ÏÃv<NáÆ<4{)“^€�y<49–ž‹,Äic~Ò6æ²ëFÑ�K·aõËhhSeo<ßÛ(¥ Ø!ê’ì­â5¬œ²zȺ*í“x©zj°¢ʧ.k•:L õbº½�iWIÎÆ¶=犥ÞÀË.Þ‰o"ZDîN!¯+š%Û�6]ûôÎÞ£«�7ç±Ú¯yÎSó¯)4`¢€Á¦|»½Cí¨•R =¯ºŽ—™Vµj^‚žn_VïeJçòŸ)IùHÊGR>’ò‘”�¤|$å#)IùHÊGR>’ò‘“œ�´7.¢^­×5L2‰ 7•”ª¤T%¥*)UI©JJUÞÍTeö‡áâ¿JUÞo{²ûíDåN¶®+Iù÷Á“‘¤ìŸ¢¤%%()AI JJPR‚’”” ¤%%()AI JJPR‚’”” *AÙa;m“©`q+`)×r<Ç5„Âñù…x8 ÅæbR�·H×ño8XHDÃáH$4‹E#±y)È »¼�œ]ˆñ…ØB<� Eç‰0v‡èæñ…D84™�%báÐöÆVÊ”R¦ô„dJí¹H&O&Ò/O�ºçëwþdúÍOýÞÜ;_ÿߟ|ós_zäµ;ß}øÍ׿RÞüê/>ö+ñ�uAø>”ÞÁÒ{wîܱKÿyéw*b¦°–ý«/ˆ¦^±¶dƒ¤ ^©ÔYY‘“pX’ü»Ì´äÂ<ðå”�ºf2wI<_gUyc†ÿ¨ÛÞLò’Û»R·’Ùª˜XX°!°‚ŸIoXøš²²Rµ h—*ºQOJñ[Á–Øh¥šlBfh€·JAÓ*äfFR*+&lO7’RI³t£Úp IðÓŠ¡kuX8dU´×S\c&“[Ìj¦Ê²Ø Kñ î�â™ÛT\Ò*«2°@‡HÞT½D —[ö[m]‚†q Ö€#!µ qã.U ºœ4ÄÚ 7î’æZ¸¢•a96«?Ò¡~pHƒÔÏIºÔÅú¨?Øò@à´åŒ¢ úÇr«`p{€VÅq.2N¹´ƒ–ÜÔnkàó€�u«˜ä�ÇTõªRJ®èb¹Ùà« ˜¯Û“\¯ ‘'�™XÛ3ã—$ªÛDkì/g7àr›À´” ŸÕ ~†®ç%Îê’n`p§A°ƒ™c~:Ô„=JˆZ0urJUÐðPV@ 'Ÿá½½KM©ÆJ·al„– ™ÏpóàXvøiµ&&Dñ$pBˆÅíÁpÖLåc0< ,n)VM´\6Œ]VqL­Á@üЊ0’ÈÚ‘D;à´xRÜ«®-ƒb ètc±;N …"è¸íÀÄCôb{Ð/óx¶üWÂØËȘçÑÙ”‰ÎÍ@ín¸‹lstIÑdŒ‹5��q­}�‘˜�ÙMjc–ô‰³y¥„àg“ÏÜŽ6W¶2)þY¼Žuü³ƒ²ëø÷RêRÕn_®FSϤ|?Aøœ™ŽñCh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh„Fh“�6÷XþÉ�Эýy>Þyщ†­øÎü&¹¡Ù^çÄêbu®_;¶u{Ò¡�d4¯§!¹¡¡¡¡e4Œêöš! -ÚIDà fné «WáCr#4B„æzœ1W.m•ú]Ñ!¹ÚqFC¯±W¯ƒó§wlî¬eF‘N íh á|q£­ÑÐp> §ñÆhn=Ö¹¿jâîzwF¤B;ºh~3f«FšÞ¹àΤíxåŠß5Ò~³�tJhG ­ùÌ´»_föxgöîήõŽÍ�Š´@hGÍ»#éçÚ^f·�´@h'ÍÏ'tgÎv›/¤B;hnÖx¯¾ÁΘùùÒ¡O4÷ú¤_Lucëw×4é”ÐŽÞ�0{õ4£�mÐÓ9¤ÓãŒÖÝïÅæNò<õ£Öû�õ=´î}v·t:ªvh.Œk/ƒ3ÆÏöp_3h/{�»�aæÃxb¤a|í`´Ã}úÆ•jéÌô8®ÑÌmEïõ2îð8kö¿’ïeLýìà ®Qº±Ø^¸u½µí³ÏË ŒÜlçh9š ãE+]»¼�Zp=ÌÉØŸwW¿WÞùѽûÙmŸP³ž¬÷î µïœÇ™3ŽLÁä{™Q",WøÝ½<¶QäHÖ{tÐüVL?Os�c;Ü7Çʨùߥ3Œgñ›‘g¦Ç•o ë½[hîªîú–IÚgÖ^f·«7d!„Öûqw‘îÇ•� ¹íæiÈBÍßbÜùrfÚÍ–ù=ù> ~áî  º†CövÒмžÆÝ§zóÞœRï»&ÜÜÁ¨ï<¶ñçF}ò¥�¶ß;&ÈÞŽškIíë ^ßãÞµ‰ó¢ß•N¿ñþ_¦ÿû‘ö‹:úNœî=&´á¬Äooc_ñ<ø»Möò4äpœÒ.„v7ÑúíŸGß/�íø¡õ^_Øo¦ÖÛ°»¡ƒ�Y‡ñ&B;yh~;a×Óx#¶Îû-û]#uë]ß�Ìþ oäx>sGhn¤?ŒõŒ{lÞ½°×ÖûݯÕíC:3Û£äÚío†“Ûn÷j{çËɰ7ûþ·Q4pTïµ9u-o÷çíí®°îtþº¥w\Ý3f”wÁŽ[ ‡“Á8*kï°‘µ�6ŽŒûÝ”¾wûnÏú~ö·Û›ö]_A‘Ãd �ò+]Û=h´q¬è”#´“Œ6Ú�ó£�m?w#�N mòÐþ7øúåè:£Áý¾ñÿøét�DÈzGû <Çó܇ע“SoŽz˜ŒòI³úõ�ñ¢¹Ï9wÿ:ÞxǶ·{ FÙ-u憵ïüßÌs\,„Ö�ñ u^IqŸKÇ/Nô>ù8Êû:ºï=È_èpÏáÆ•˜«<>rxoü8¾hÝûw/à®·—•Bt÷­QxûDý<†÷¹„ƒ•›÷º’wÕ8ú²Û*à½OƒžÅNއì¾3òþ"ÆnöAç߯Nþu™~у÷)ªa"‹“¿ì{h‡½’|fz·3êÚ7¾çŒŽŸ…ø­í÷JQü6)Qô~ü½wÖ&§£æÊÉBmrІ™uÃÇoÃ>ÛÖŽðO¶özwYïd£yw¸ƒæÃÞŸw>YZè·ÿ!{»ÛhvÄ…ºæÔA>¡}ø~Þ—N:í]‰Èz' Íû¼ÀnÙ‚Ñ~­†´0´ÝsªûýEkÒÂ~ÐܧkÿW mñ›ŸW'¹¡í†F^†Ð�Ð�Ð�Ð�Ð�Ð�Ð�~‰ÐmT´áï%¹¡Ùhý®î¸Okïí75H „v²ÐÜ's\/Dñ¡Ú0hî“9äe�Ð�Ð�Ð�Ð�Ð�Ð�Ð�Ð�Ð�Ð�Ð�Ð�Ð�Ð�Ð�Ð�Ð�Ð�Ð�Ð�Ð�Ð�ÐíÿÙ»šG’¬>¬B s@â§P Úê.Õ§»³-²ì¬ª¤ý5™YÕÝCµFYé°�ÓéLofºªÍ i8!§Ý Bö°àîÜà€8 ÿž@hø½ˆL;]vMïŒvW#ˆšÙªÈˆ¿÷ýâEÚÚQh M¡)4…¦ÐšBSh M¡)4…¦ÐšBSh M¡)4…öMý?*4…öuоîyYÙM¡ýGËÿ+›Ên M¡)4…¦ÐšBSh M¡)4…¦ÐšBSh M¡)4…¦ÐšBSh M¡)4…¦ÐšBSh M¡)4…¦ÐšBSh M¡)4…¦ÐšBSh M¡)4…¦ÐšBSh M¡)4…¦ÐšBSh M¡)4…¦ÐšBûù i•¶›ºM­âLæÓ›ÐõŒOýÐ�Mmˆ%sh†£¨©ñðÖ�Û<ñ˜½½ç;Žuiì4»¾GI4JÙK?Fw {5`WîÌW‰4ñ"áqù \#Êl±I‘” P)ˆU)Š›H»Ë‡+#+Ѭs‹tt¢YÔá·[ÎSpd´cMyÚ¿ù,c à¦vž‹ RXÉw´Ât=²´Êr¡™�l¥È®²&|eM¯éU†Ûë¸õj­Z=¢°Í—Éûdã]²z»‹þh�l÷Þ¶Í]÷Éï‰ Y ’¥5—O}¢X­ifÒ›Y:7Sa­Û÷æ~ sJÝ—�š1D/]Ø´|FS”î›é2°úW¹zà»Iavõ¬uÑ…¥ÕóCÚÛiì‡ã‡ •,êÿ³P¦§w�MeäìVeäÒ·Sǰº›ÊÈÙ­ÊÈ¥o§2ƒh†¶%вùí¡–-¾_%3Lù˜Ç¿`�âH\Á¶hµ\Ù®×rù[ë¬Z£q´Õ[rá!wÉÕ_€¿ÖŸqkuè˜úþ±~xtÔ8©íµjµƒ½Z­]ß;Ñë'{tÙjëggÆáðÔšñÊÉF•ÕÐâ�8“’‰?kn"ôÜr ˆé]q»Ý¶¡h· ¶f)vçAtã�!«ôÅ)-Ž¼Ê–9ËÅ=;.mÌïRÈ�‡3S±©]¶¶°yºKo€ä“8D<[ {òá®xKTØL¦Þä/º„4Ž‚€Ç]>½Aïc>|Šo£Þ•MÅ& æ ý_ó_þøWµ¼¥Ní)½³ÉÞßRx«Lµ³ãvû¬^Û;mUk{­zÁ¤îÕöO÷÷�võ´FÁ”‘k­˜»t—Çå?�zòäSbÑñaþÚaµ^…\S½ÈvÖªXÜ×*Ë)±(Ȫ�ÚAý„v.§(˜îmÌghéÞ¶|F@6ÏôŽmH,8x~øÉ„Û‘GªWkGûõ†~º·P«î4t¨~¼¿W?©Ÿ6Ú§‡úIýªßÛ&:Ë¢Wý”Oé9n¼Ð*v±9H§ 9’‡¢Ý|Ó·¾.¡;‘—½p üð­;^ß6òŽüúÚÒÏ{ºÕqݺ>ÃÜyûôS}`^'îtðäšbâúã9�(ºåñðF«dpô>4J#/ Ö€‰mÀtx’õxŠö-½•„M©ÓJ²JÁ^„~×⣦–Þ×ñœGãØ�M|O«¤BÁ1f¼dý�ÛyËþ´ÅéäS}ÊcßsÃOk�“}ñ^Šˆ!05]—ö»Aúl…Þ"p3K¹|9·åtx�öÛz‹ªî~wœ>#=_¾phxnôa©?ø.üì{óÛí¶"(µuç²[ØÑ~½=¸0,4ûE&–MTÕÕÑþñImÿ¸\-Õ'åúáq½^GξySXf×(2<�9ï|oRØÕÞ”.{¦SŒ�A¹NT;>8DæÖqìï¿)é—ÎEß2�×…�ôZ·°�^¿yCF«dV£ñ«~ì�ý�÷ö�r£ðsÒÔz~ýþ¯×w¼zm#8=ÖðÓ88�YÊuñS“,VôüI�E�ÊlUP}²ûÉ uE²†ÓÝŽÓ]ÇénÁé®á¼zíD8m(¸iꤌШÖO Ìa½V;æh=2c­“ 9×fཪTú“ Êî”Ý Ê <ÄÜóé„¥Ij¦íÆ Ívø(íDáØOçC.Íq"ÝX‘Ye¶iL!“Œœ× "Ae¤Š„:¸*~¨®\TW”E�' s¢(°£yìñç;­§×˜â”Q±N®ež_·yò6E³ 3Ðm¹‰Þ]gA‡Óá6û�‚&“rzóîúŒ»é<æ¢Cs¢âÓ£óùNþR~‡Ñ1ù|y°_Ýi>¼“AD:ó®í‰;ã#!d ¢ûYü©<ÛÊÉdFTÛN›öýÓ†É=ì#¶C×lù{‡‘å/Ѳ:sø»”UñOéÌ�“´ôQ駤Dx¥½þ}FW_¶C¿7œìc˜q û(Û¡ß›öO¾1Ì8È "Ì$þnri0 `°h|mC ÄœMv_£l´Éê°úÍ�’�®”¢k”Њ?cµRrÚa‰æœò®)™Š•û]\E¶Å>š>ÐBVû·ü=…Süð‡á«�¿³7›ì¤\+ï—�Žq}”øò“ãØŸ¥òóVÑ®yòP~Ü*Þ'kîM’Æ®—6¡5Z{Öu?‹â<ŸbNN£_LX�uc ‹F,�p¸ñ˜')ó$é�ŸNü�I”2cH¦+#pcÎnÜ„#Aê»![U?&¯ŒdG"e£8šbeÍ¢ÅQß’œ‰VY ¯Íæñ,JøV-ÐWÞúC!d\Þ¡à†aÎú„‚­ jްEO—V!g¬%óÙ ¡0jv² �wìnÂC6ô“YàRµ�Äú)«=­•àlúp–ÛåÇðÒÞòÛqE‘8i›í®c2úäÔ‡iÌÐD¶[Ü óëT ­ )g´T|Ea‹‘Ð1Ëo/ŒÒpã²±–ZE’ˆîFš®ÑÞr/è’ >…¦¢³‰/8ð¡/Ô!É´Jþ¤%èåçÚ<Ð"È) ˜è¶ é |óUÍO’9Ï@äX,J èºÀèoZ|ˆx&%x-ð!Iè»%viëÂ0’†¨éFÖ4è[$Q8Eлt  C8¡ØãnìM`醚§¼$ŒÎ“¨O�Ø.F™£àê~kæ™§l›^2ã·Ú¬þ„]{Â5ðe¾9÷÷7”+�‰(¤ûØš«®¯õ«®>¸Ö-î�9Ü&+áfùŒØNÈ2+«àLqê£è ¦ó8†„Ma©5Åu¶"ˆ3o‹Û#QV[¥û>¿æD•ÕÆÊŠ!îGé<—Lôô¨Ç­ˆzâ¸œÒæ3ÑuSÜ{FõöŽÊ‘œG• 8 ",#× 6™ #ÄíM4QÄÇMí™}³þu¦½ãZùè qx¹å2ÝÝ$;¬—�ë�jq¹Œ�îG÷èˆì¤Z=>@A—Ë#šoÐì—�€iå2ä^ ˆ¡¡ý ‘årSC L¾Jæl�Œ‘¦Ñôaiòuñe”‡•‹t|.­dÖξ�$¿ùDù.þ¼M›½(äâ;Mâ)›æ‹æ,òÃ4_Àój¥xm%¸õƒ€W*ϼ,ÐZhe‰¹œÈ–r©ò§l|:‹pnÉí�+’ÓK¥äƒÈm••\Ïóp&¥MÝÍ>ŽË0ÅIšF¬ã{8Ð8ޱ0XБ˜“jó„Ë‘“9âÎÃ!»Y°éšŽè.”óR:?gÆ~vZOÝ…´»uÅe¹Œ³6�ý›¹¨="h’À$Bœ”Ù@¤;#ãÀâDÞ¾í†Ñ]Öø‰”$áéʆïÕ¼Ìô„ØÊ9ªW‰}ñùÐïÔŸÿ�%7Ø”£3qÃÅÚ±)8‘ŒŒ4C›2^5J‚Â[^¥9p±Š<ߥÈpS© ø‡�>|ä<¨ã†vOq¨l#¤àÉ㱓÷1¹ËFÂmñpÏ‹f ð åáÆŒª©ï•꬗âƒüSwÆü)Úæ„=æåq™•Çþ¨ÄÊŸÍø„©W~¸£ˆ˜ PRø°Ãû¡T1Á"o® –¯™hÀÙòM5F6ŽMh³4é‡à�!�Ì ^Þfz=Nž @3�1?)Z‘ÞŒKž.»¢/ÈíéCŠ ;?_tjéòS�ß"šfÒx"hN‘=!eói"2)œ\G 7H{£˜‹†ÙO~^zå�‘òx*á–»Mƾ „Daºt9¢$YKZyO"3ºÅ>ˆÌÊ¢ \[¹øOWÕÌõÞ†Ñ]À‡!"ˆG;W\|tÞ8ÒÑ÷árG¢§.. ³�L¥‘øÂ&õɳìJ&!/QP¡‘õ%s·ó՜ȳ(LOnA‘ù(ëm óKêËЧ‘�Š”]¹-pï² –C�E‘‡"x ùŠ6�¹›f°B‡½³ …Ó„‘;þT0y鯔­Ò m?ñ]Sœ5¡wrµ`Û)ÛEKwÞ¡ÂLÞgðµÃäÇ(B†‰ ·¶!Am”ñ¹¾Ü$z×?uŇ~Ùé‚6g é€A�}á›*ŠËà/?ŠK²êC„2ÚÐ1»&ѽÔ-Kï9¯Kb·\i=Û M˰íÎk¦·^ôú/;FûܰA£;lɳÕï9ºÙ³™Ýï¬×ïaâ¬ouÅ—°J¬mœ-ƒ¾Å Ëê[v9KŸ> z}'àìK³Óa]Ãp–âì‚Ü0Ú¶@z5ªî˜ýžýlµóÒ6XÿìÈ)æ{fÖ°.Ðøˆ-:V �YKïÑSŽÖê[HŒv¦‰)õ0{W€è�“L½×‚(=ðÁ*ɲżöEÿ²Ó†/õ×6»‚·ÎÈÒÎ¥Þ[„oá8cà°3!ó¦×˜mˆEç‚é§ý+£ÄÞ ™» !‹e˜=ôÎϤðØÑí=Ó.í@Yâ9+F°«Þ{Í^˜½v‰&í΄ŒcvÓÀ’Ù£HƒJìûÉ2¹ÐN_Š—ÑæØ0;¡w «u�GýÔì˜`HòŸ™N��ú:è–c¶.;ºÅ—Ö oÒDïDw†¢o¡�Ê* Jƒ<Ž�-ß½ñ?]<�jR:Èg—5’z½-Å-/Õ» ãKf±d&ÛšÑ0Òé"z‘ª:}òB—XYi–õ>æé÷òìÉW”�¼ÍÎ]Ñme–Òøám„§JV ŽØ²Î#ïiGœ^¹þZ7-lˆ8èõ™qe í J ùò­×®�s; Û¾õØ~BI€?íÂ1­¾í"ŠZ—–Ñ%<Ú—§¶c:—ŽÁÎû}™¸¶a]IÛÁ.Ú#ÙÄ“­w ™x§—¶)O‰ÞkÄ¢¤˜a;„/ÉZý."K3Q–±¹Ä�d›�‡¦ý:ëÐèj6W³Sò®?hnä9¾»ž—toz#¿1ÒKB ¯šÌ·…qöjW´©û–‡ùMfÕw†÷¢ç ø­ ÍÒ÷JeË/ŠœèÀdäŽ ÃP FâËâ!»bN½ÙªÉZïÀ‹þZ^éE)–wUj~¦~’dÝ|áê!‹iv-Á½HÞh©ƒÊ® Å6X4‰Ûnù+n\žýhžÜ“®$ÔÎZ™Ê½�)îí£+¸¸ö�‡ ßö]ŒlŠV¢j§e4¡ÓÚˆáŽ!¸—ØßS;ë(¢{Ø|¹ý�«œWÛ(K$šå�B¼•‚g8—K›ÞñÙ�Á\нnl„…�ÈëÎ/Ä9"1¦­_¬ša�”Ó&'<øÁxªî»,K# a�&î�›ÊÁE"j2m’ð'EÐLLðhTA.桃Q;˜ ëV£“2©V9*².¿boÀɇeÌìH�Ñ>¬nE¼OÈs±ƒ‹Gjg^l¾âÖ›n­Z®VöŽJ¸w&“ y{³F{øê…:"ÚäÔªÅêÞaï*”/’‘`d^ÇÙU™�‰˜É±ã5dÄoUÐ å‹tãÖŽž‹ÌÌOò°Æ=xZ)²)<ã=UtÃ=êëÀŠÚœÁIàÀƒQE›A ¤šÈ, �ÖÊbJ EGªÈñ0²]Ë�Í€¤]m¢‘(áöˆ¥¸%w·ˆH,¨HÂçP=r¹bÎõùX,0{#h4nÆ�à†Íl *42�Ó&›�Î$ǺðH‚„(wùôÂ÷8Û¥á} z>ºâ ]Ÿ¨¢&ÑÛÚ1‚qüÙ”�T‘aEJâ§øT9<ÜÆF¦‚' wø¦î˜Bš´¬ -ï«OŠÏ²;NŽËvùþ~¬zs÷jÉK't"&¦$E>¡JÊwZ}’Ó Z?ÏPÝ÷fQ¨ÔäV™™c¡érÐV1OîÀÝvf¡©¬‡Ð­¦µ#³Àjã·ãq$å8Œ�0 «î¢*H�€÷¼5ŽÒ  èÐÁûyÆÃxû ¢Ö —ÅIŒ(7íŸgàà0]°(—ˆm÷§ñ×UàD´¬˜…yš‘4‹ä� %ª´ ÞÑnˆ'<÷Æ·•â˜AÄadgcÉnÉÐIä«0[d?›rËÌ^(Oc;ÒLѵ-ÄR —K {ƒas¯X,핪Õ#EIôQöäDp' ‘E­3kTývLÉ6 ÆÖLÁ--Ï'o0R.ø?í…«ÑÅR©\ª�-/ ʓ֩í‹'©‚Òå^Ó‘=x#”…¾È%NìQÍÀžàò�Â2žïˆáHqؘõ�œ@QÔGÈU*€� Ǽv²EãH`ÙlE„OÞºš�q´0FÔP¾è ìV!ácAr–ËébãÄÁ•fZî1Øeß‹„xÓowmT¾ÌW„Ù¶Ék£2KÑXK2.’U¾M'¹tØ� ÍZ¤œˆ”TY® ŠóÔ#(VX(ŠŸè[eš–ÜãTÙDhâ]�õ„”-—B÷{ L.'¢èʱAÂ2!DAéH1¥ˆÜÅ!Sé„!"°–(Dºh‰ÍGé1¹l$¢U™7Ãû0yÑ:¥D>d«FÓÈ^ÚþLùÌ^Ð�Þ‘8�‚ Ïì œJUS˜{šà©¡o­uçlÌ=N»0¸¥8‰BRI!áÖž‰ë§øÝÄ+u³n»ÊYv‰Á£ãÆ+Ïô±y~ðKÇÌìFÐZõ¾óí@0Ç5yr,‡uÌq{ˆböh\–x´JÖW1‰Ó€rz©chZœ|i×êî9îÉd[¥‡*�î |pÅ6tEÒtŠ‘ïRLÔÜXlÉ1Œ†^@)¤ÅI5é½*ê,u¹c‚qñÏ·UAw©ôÕŽƒ™^9Ö»mÕr²¢ZÏ ›¹­JK•ø—° °ühküè—냋ÑeàÑ‹)AMÛ©íÕRm3ϼœE[Âïuñ{àwŽ¿%ü³Ö"þY@ ¤eÃrÚfíp‹ìÿviN~;ãçÜÚüà›Eø�¾£ÀÅ+ÓÛR%o–ÄëÍìÞù¸A´RÆf¶w³ÁŸØ`°b¢-,ô\—,Öm,ˆ´k7-ƒãµd•b§ &‚ݕٓG¸Ê¼?̈‹ï lñ˜h #^9ºçˆ/Ùlð¼ç 2JŸ,+û¶Ï�e¹m—ø#&æs~Ã\[^{�Ѥl·üxq~e*•W%nSgFR.8['f!-ê#›\Ê„ì&‰‰?lp·E€è1î;ZfÅÑ‘á|rî»Î䱿8!M3‹®ŸÁØ‘÷:à ôÒtÔ¯ eI“¦÷.‰ªN:,+}нdbçš°q/'ޱX¨!Õ“ó`ŒŠ¿š±‰UiÂ-LïƒâJfÍ\7£+ãy@cÊ1Xyöb¦¬òë�ÕM"ltŠ/çwùu’à‹£éÈg#¬“¾a˜U%4OÄ×=6O”˜îƒÍº 7õ§3WzË#‹Çrl©sJö?g'âOÕ‘€Å§a·f-ÓË[f�{c¼ü‚7.FŽ[8Ãøí%ãwMKxBð�ƽ ¶jPcªÝ ˜¦ »ÈƃùÓÆòTÖËL�gæÂžX錒Êúp�È©ˆK×’/ÏŒBüfày°Í­šçÓ18îC£R OÞ¨ÊÇ�WÕ&|òqCÈ�à·G˜Y[uHÅØ²�HWÅÇax%ƒ0øB…s¥#ï�B oÀÈ[æ”~ƒZ«=ÁÉ+ŸeÚ –‰lwÂÇæù´Þc•?£�“Æ¥G“¨ÖôXõÉ� T“èQ!îd!æ Æ`Õâ°éé $ǤXÇ‚K¹x�p“²¶}XþláY¸ædíAn.>èŠ#[†Üåt ‡Ñ£ž³‹{ûû‡{ÕÃÃ#ò'~�‰[`æ9ø) Ïöâ«Kx¾Ba7>Æ‘!+OÉÃÔÙÝçu�æhú)u†‹pÄ­ P?׆>Åï$w1ñ%»Ô}52�ò8ÄKÀ¯~?…Æ÷—óx‰H‚ÒTÁ�ÎÚ€‹ø Šc LÜC΋fP6~ÜÚ^üPwÓ¿ò\L*“&�hJ2Ù©µ ççŽP|: ,©‚ ¯ ¦/°¦î :âìÀdǸGÃ÷šêÞ‹ºø+ä°�cÅÚ)ÑSßíÖۃǬô´Ì&à{cÖùü¦Ãò–ë/ÑÒ�Äø­º·ZJ]aUW\o¾ÿ*/©²·Téâ芦ÄwJã[ª3xwaNrLn äâP¢ä"ëŠ ¨ÃÌí%xÞö=ìä¶jú‚hÌ{xf»ݨúмՔŸîÁ,Ñg—¶peÛ2 ‚SU=‰údÃÍe¦°=Öí7Ê�¸s¦ ÆÏgÕêQ:²rœ)ˆéèQr?ð-°MSñD3k˜ºe#–è½âþ¿¨#3¼ 5 ¸›ÜƒâöÌŠÄå•v㞉/ŒÈö‘‡-„Ù—ºÈwDtî²&õi©JþZP@:6{Ã(‰ž…ù¨’$b<Œ+tä»®Eá2� Ž~pZ&yž²Ö5}O€Û hD2M\¥ºÀ>Š�§`Ù…5 -<ÈÜ‚[Cð}QáóŸï_B¡™çqng¯î1üÔ"Џüé¯þ=Ûn�[Üͻ󯧥¨h¤]X ¨ØÆÝ¼y馉`\~Âû`xâ"¦ÁOHЇ)„ú%øuœLî9·®Ñä4À—ðdü‘Sîx6Æ mf9Ã~¼¹�ýD²ÀþRñp û“�q€Ñ6-uz=5ã‡@¢†Ž4.&NÓ¢õæÌÃ[g^^#uüX#G€01îÔªu}fÏÄ¿d÷N^‹¢“YùŒØ2c œFÙM·Y×�³r¸Tˆ–3R÷^eÔ³ÜÑðtîè*!8ùTrB´Ò°ä…øZ}‰À`¼BL‘eÑ‚ª±.¸õÚ†N¨˜4_äíJªVœPÊ›Vº�„ÐâZ(¤… €¼‰)#pãë_èô©ÆˆàWá5 'ÑŽ—nÒá/~0„¥~¾à;@«à/ÿAú¸�/ÿöG!E[Hc–ÐOÈŸK83ZúÈ~zH…3“r”Çö ¹U8…¤'êËÝ©¯y“¶À/¨ï:âGøžïœ9JÎNíÛw•Y÷ªU§Í7øÓÇsüÑ~…?�ëÇc‘:®Ô¿­¯ü§¿À®Ñ4šFÓhM£i4�¦Ñ4šFÓhM£i4�¦Ñ4šFÓhM£i4�¦Ñ4šFÓhM£i4�¦Ñ4šFÓhM£i4�¦Ñ4šFÓhM£i4�¦Ñ4šFÓhM£i4�¦Ñ4šFÓhM£i4�¦Ñ4Ú—ˆ¶ÿ�Î~Òã¦Ñ4Zòïgø—žY4ÌÅoöào=nM£ +‚s¢×ï¯ËǼEk£¹ Ñ¾d´´¥Ñã¦Ñ4šFÓhM£i4�ö)£¡WwßÍ�ö%¢áî"üä?齆zÜ4šFÛ„¦, Θ—ÇWÖº=nísFC«q_«ƒóg¹mjVÝeFižj´O ç‹ò¶î††ó-MÚGS阦þª‰Zÿ,¯Œ44Ú§‹¶jÆÜFª‘fy.¨™t}4z¹êŒtÝlÓ<ÕhŸ.Jó×_©õÊmfOzÖaéÅݵ嶭¢Ò\ÐhŸ.ZzE²Î&$Væ&OsA£}‰h«lÂâÎÙMóEsA£}hj×ø¾¶A옭²?š íóDSç“«|ªѶuQÓš§íÓ‹„¹¯¥¹[Û6ÝÎÑ<ýœÑ½ûûÈÜ—]myWKóiôtñ&ôm%yí6·¦os^“í©Z‘Ýw…¤çÂC¡}úmÓ=èÕh7EnÞ$Ù÷ÿâÇ*NhéýøÐ>Uýv›�«å¯jÜ¥—ê$TË›F»�6MöT9 x3Úû~Y&A{ßÛg¿OïÊ=¶µ–Á³Jöp]³i-û!W·™Ûñ‘nck7£=ìí5BÈ¥¯¿ÚÆY‘žYwÓèËVFEÀã¬yM~Ÿ6­“ƒuF©|±ûôVYka³ÎÊà©Ýλí9è¹°]4ëû“k䂲0_ÆúôvQýé±HÏ�ÅÕÏMëü5ëµôþ2hIä<Μmì|üVæ.– ü½¸Üܶ»Œ£–ÞOm•Æ\ei>dÛö˱›vÔVGéÜÆ²¬š‘_µ­ý-½¿šÒêʶ|L묇ZËÜtz£%D£-ÿS«Hõ/í•}ãv“¥Ñ¢ÑVKŒš/_¥vËVÝ|ÿìÂ/ƒ¶é GËÛ—†–¶4j�šÞHï)-kBíÜõa›Û¶ý=‡»Þ|IÐÞ7bBËÛç…¦$)9_HÛµ‰óbÝIçªñûÿ}™õßGz_Ô»¯Äuì±F»�”¬ZÛˆÏmrŸÛ�·ë©¾á¢Ñ~I´uë绯44Ú燶|¾ð¾;µ¢m·] }Ø™õ_Ðh_Úª•°²4i�-o¹îŒT¥o:Ü^$óêŒô>ÈçyçN£)Oÿ6Ò³í¶¥×ÂiY_¯µhC²;ÛwÙkÛ´¾¹Ý¸Ý«�ž/_†¼‰ø·»pàS�=U’·�ø¼ûE…-¶ û×-ÓíZœ1wùì¶¹ð0;ŸŠî½­g-ж±ãþKŽ~wû—žõëäï¦/í+[¡=‡�í.7XõÙî‡FÛ†F×ûoíKF»[äüÝÛö>Ñš§íãCûðƒoÝ]Ö|ß/þ~<Ý4"ZzïöÇs;÷>Òý�=MïQßfGùK“ý×C¶‹¦î9/þu¼í¶í~±wY-e÷n+éV™çs‘­C¶ƒ–=IQ÷Ò¶ñ'–o>Þå{‹±¢ò/t¨:”_‰{•Ÿ�„<Ü?>_´Åõ€Z (}ûáv¥]}5 kß Zg1Ò÷>츥ϕÒZãÓ—�›´@:NCßžÝ8~8?äæ•Qú/bÜäaèý·my„ÿ¹Ì:ï!}‹ê6žÅ—î¿}ØïÐÞö$ùë¯nš1wÕ}Û»gôùIÈ*-�|WJûo‹ý>ö>=ë²§wÝ+×¢Ñ>´Û̺Ûûo·½Û–xø_6îÝ¡¥÷ãFK¯p7͇ûßwþ²¸°ný£åí—Fòæ61¨›lBþ>ßK×<]ÖDZz?&´ô}�›v îö×j4¶ƒvóžêûþEkÍ…÷AS·kþ¯h´÷óßVYu=nM£Ý„¦­ŒFÓhM£i4�¦Ñ4šFÓhM£i´‡CÓI£i´»¢Ý>T�›FÓhmÝ鎺­}¿¿©¡¹ Ñ¾,4u3GY!í¿i4�v4u3G[�¦Ñ4šFÓhM£i4�¦Ñ4šFÓhM£i4�¦Ñ4šFÓhM£i4�¦Ñ4šFÓhM£i4�¦Ñ4šFÓhM£i4�¦Ñ4šFÓhM£i4�¦Ñ4šFÓhM£i4�¦Ñ4šFÓhM£i4�¦Ñ4šFûÜÑô5šF» Ú]ÿò²7�ö¥£©¿²©ÇM£i4�¦Ñ4šFÓhM£i4�¦Ñ4šFÓhM£i4�¦Ñ4šFÓhM£i4�¦Ñ4šFÓhM£i4�¦Ñ4šFÓhM£i4�¦Ñ4šFÓhM£i4�¦Ñ4šFÓhM£i4�¦Ñ4šFÓhM£i4�¦Ñ4šFÓhÍ(4ÍȬ…áÅlr ÏÇŽgóšaCVÛn{#¿fpïÒ š<´Ø`îYÏw†ýW­�ZDZ?ôGûÎñlÿ*dߟ±×<ßcùÛ=ž9®ÍÊOŠÅÇlÀƒKÇâìÌ´Þ±Ê3ÖôÛ¬X/ÚV*æKùb¾|pxhâÊDNMo\3\ø93ǼáÛœ]šîŒ?ßáÞ³ü™óç;¯;Ðø4¼&å»áDf-«‡NäòLg Ûá!v×((‚š1…Ç?˜ÔŒ3ùÔ°UõÅR «L2à%¡/¤k´¡7ßðyX3¢ š]sÂÙlæØ=ß9,WFOªÕ£½âÁß+•lkï¨RÚß+‹åbѪšOž`EqÑšñŽÏ¯üÀÎtˆ�‚ÌÀ®ÇU†S3êO‡ó)à3Ç—T?Š„OgÁkºT!- ûFŽ,3A˜Ø/ƒÓKhƒåOyºúCª^¤½ ¿i¬ÒýĶ„3£‹šì¶QH'd`Tް6� pkîµ®§¦gs»62Ý�C¹Åt£)Œ™QlIs˜á©|£9ImH¿ 9 ô$Zí©I¢ªNRŒ†ï�œñ, çã›Ø#X�üÒ {P]ÌE¾ðãÄá®MÝíÿ®Õ¶›F!“l¼8£äpë:\„z˜óÞ(Cöh¡Ør©Eò…&ˆªë®c† 9IšÑUã.d'iU³$~ë!Y’g´ÃîÌuÍsðå §RÀËøyæÀ 1rñ«Ñ²ÁíKŠßAY¤ûv¿‘ ©¸< 2yåȼÍð‚´Q0_7 ¢§·„mtõ¬ß{½ÜS‘º²£"ks?QàxãÛ÷r�éÖ;­åΈԕ�Ygg†­~g¹3"uegDÖÇÙ™3 ú~… ÉôÕ¢&37w©íE|̃îSàÓÂhE¯âœÕýг?Zf•ªÕ'+¹%2Ö±Kä>¿²ïàØ5NÑžÿãƒrå R:(ïUKuXæ7‹{Ç­Æ“½"¬óNàRý°ÒDm´¾ʧBòØç.ïð™’�=Yay)ù9Í« ¤ÇmÍ€eF ¼‚®nºÐiÔÒI†zJù…i}Ü÷ M´”ÒºŽ ýÐ`�Ã)ÐçZî�Ì›xô÷eÄyk��TõøˆönR…q¨—ë'w* |×åA‡OÎÁÉ‚Á\ï~$¼¯e�Bá&r88“© CœÎ1ȆÇDÊPŸùŽJ(ÉtÉ€JÓ¿�Š í¤8Ù¡”R)?P .F`"¸²×‰ƒ˜I5ê7Ó,]x?åÞ8ºH,¥Ð˜GËãÙò.¹ \èÂè}ßq¼ÚÞa)ÿd¿z°_…O*åƒê‘Q ã þܯäöËGÕýÃý£jõÐ(P7¯k{åüa¹Z,—¨üAI‡(?1û¨X<Ü/Â?˜§ûT³e�aÊÁ¹‡åí²®âþ80§ŽÕðÁ«v<\ŽÑjÿÝ7ÃÚ‹VïEcð—¿ùyæGÏàé÷]?ˆ.~_ŸðÀ±Lï÷ИŠÈÌ5ëÃWIÙ¼�npö²ÕŸU�ö˜[”¹O*‡G¥Êa¾˜+W�pcµ\.—Š¥Ì�õÛ�–ªàEÀ¹wåX²,Š~̽궇ª| Ifépÿ R®–aôªû•Ê�¹ú«áË^¿=|# àj_’ãÁ�?ì¿ñ}/pÆÈÄJµš¯¦þU� 2Óxs•Ê4¾3°LP½%øWÝ?‚®åËô¯P2ÏøAA•�Ÿ°W Ʋ´L–ô�Ez•`t2ôò 1ôa2ãJµv”¶€ÈíCƒÊ¥Ò!µŽK?$Ï0’Ehl*Åè,å¦RŒ—Îøâ,à–C+<93i0ÕFÑ©ï��hfsèÆQ'[: $Ô5²™B¶eQ´•Œ´Ôk©ÿ’¤~yתößÿêïj; ÷—žâ¹†<ãh�†ÖC.ºv¥“Ãfó¤\Ú;nK{û�rqï¨^?Ø+ïWŽ+•V³x\j�k'É�ØHܰ«•qp«ehrœD™C céLU¹(3)ÉÀí?YRíýÅI”)J–Jû`èŠ"S”wn¡ JÁ¬…b*… k'õÓAK`�»5;w�ð‚ÛMß®K`‰«õã½Ê~©¸·_ݯC×+{å£òqµy|P?*B׊ѾXÚÇr@ià»|\:ôQûo*È&!ºT ªÐóY> Ëæ ØSß’r®ã½3ÇÙb#ÇåO …·oש7¾©¿yÛøoO íEóø÷õ³öÛÐDÇ,|‹mûíŒsXþäÇö¹Q�px^èG¾å»`¬Öeè±.�®üà šèSÒ²Bj(,T« ¥5#Zìc¢{�BDCŠf·Ô×è\ÚxFbh0ÿ~’mío\P�k5û�¬ÀG»ïû›qô û J•�?»ÑVÅÊ^Å Í ô‰ÝJ*Q¶+¡Úl¿’Ò± KЧìXÒ0aË2D7Ù³˜�lZRLØ5´‚5|–6 _WX/¢N‘àû›Í%ÞdKHㆯ˶OT‘Pàû©*„]#ª²°?$¨ I§³§“Åé¬ÀédpRö“ÖØMÙ“ )µ3“BVR´u‰²³†²³D™1¢˜ˆ¶•h—r05cPÅp‰Ž.åˆYÕnâ3ŠŒ‘@/ëõ’€fD�z0Q~ ]9iWP‹C6ô}wàÏ‹?ßi<} É€8a¨¬Ã·bž¿mòð]äOqºc9÷¯ßÊß@ÖáRžBbb˜�ίߦ�€¡Ÿ~Ûah-Ÿï(ºÃÐD>ßA«Y)îÔÖ—dÐD²´ Q# !:?¿v-^L‘êVÖ†‰2ì×l7¼Åφ?hÏÊlȯ#V„ÿåNœ Œr¿Îݪ!9ÄËí•àÿÏpšíàÏå Ž*÷®e ¸3Ìvðçr •£{×€€²±U ÃD¿—k©2`¨¢zç�"DU�Ü9…ŠäÓrUÅû3E‚&� Mê>l¹[)jÚa¿¦m2œw5rtÄT,,zpá;0¡ñÄfµsÉ7„‹¡ÿ»>`, “ç±ì(_ÊWòOŸ�/"«g‰x$rÕÓurO„#Ñ‘¸až‡Q`ZQ z n=ë˜?ù�šOÇà-ðCæJo,dþˆEœ¹f0æaÄ,AzåDŽÇJž±!�LK˜gçfÈmC"uL�%Ú�‰Í[G$e£ÀŸ@¨ pû<$ýªJŒBÜxc: ¦~ÈWöüÊKÇÆ&xŒ‹ÝL`ƒ­*�þxT­éÙ©nŽ`E?MdXª ªb#œM§ £Ú©,¢½cWÜc¶N]µAbÕOYéi)ÌÆÿ'..ÂÔÿ¬8Zž¸�"_,F›�a›ÉEk{@È‹s[-¥J%\@ª#¢¾ƒ³ˆîEÞÒB#3Œ‚ !ïi’¡½äV 6´ä“zJžõˆ¹íPwÊ´€VoFþ¡\áA“�£0ò¶ ¥S¨WåNθÏ”)0 ¯ñ :¬dûÜy·ÃpÍu %žcæØ«A�FÐ 5®Æj-Œ´ô½ ½‰‹4Â!Ê7ëF:„�šEÈí¹?ó@‰�kÆÌìólȯڃ?€v‹lts™LíµÃB\dƒEÀõÑ]¼ç ]dC3üÙ�ÚÚ¯BkE6´;i¨K�ôþè MÙ5åâ¦6Ë|Œ(ò'ë[£ò)Úl}ç(ÍgÜЂm°+"ƒq¾Ó¯wQ­ë{œb~éM&óym*Î|â÷$'m�V\:®ËÓ9Y§R ø 3rbÆ 2KµJ½É'¨‚O¦>Ø-ñ„%„ÂRo"9î”x¢X!Ó²,°IQ­n‘³æÒ‹À’F>;u,0h̘çÎÑ$*Rcrñ4”&‡L°4†6;Ÿ³ÉÌ�˜-9°JN`³©DsAzÉÁ B¬ásE%X©0´�Žg¹3òRàÿ+[£ù§?þó~¯#l)4‡œ¢ý/ÿ!ž…à+´LÐ`©jÙ…2œÿÊé¢h?§><;ÒZO̹ viÒbæ2ØÚ(pÎg¤{HhCl7c‚0ÏÎhº3²È«‹�s׿’ހЖ„•cN˜EŒuušì5FÀîÕm”Š�²/uté”äâè–�„æf�‡³ù ¦�’‰âd²ÀŸ›n4ßœf'üPýR‚ñ`"ÄM±MȾ =˜#ŠiÌr�’03 0gÃDÀÊpm8Ð�`ÎúRª Ö†jþÓD›™Ö;Ï¿r¹�B‚€u4UÇ)ˆê“~,î°é‘ �iªÙ¥Ed£Ÿ<•± 8™¨½H�ŠFèÉîáÍ5!gA1¥8¹EÌG¡o#~AýÊsðiÑ”MØæšWr ‰AÁBI<hyBÜŒ¤, qÃ=�˜Fƒ|êL¨’ïÌg«…¦Z® ^S �Ð+‘›Û ¶ .°ó 4ÌŦÏ“+0£ 2Œ„–Vm6A·A�{0×ã2€„{ý“Âo¤u7g]DAB-/E¡F1ðËñmZ¤Ál�îìVal›óPÔ#…’–q·8¬›„`¿l±f}Xgõn“õ[§õa«É:ð³ß®ŸX½ßb­ï§¯š�|ʰÀi»ÓFºïêý~½;|“£Ò"§ÑêZXè¬ß Nß°zã›nï»ÓVóEk4õ!‹ëlôºÃz»;`ƒ^§Åº½.$œôú %ϱfë¤ÕÂC¯ÏZý~¯?ÈËéÓ¨no¨°û]ûô”uZ­aÜœG@Þj5„ôý Ö‡í^wð,)ùjÐb½“�cHï¶»0ýWgÐãg@Eê�{‹³F½‹o ­Ñë÷�¤Õ”=i‹~´»¯¢û9ЮwД.ԹؖÃ;xÙ{uÚ„V|W3`¯�['8ÒÃWõS*B¼ƵΆì„Ú¼Ì56hQæð%«÷^·rlƒ0Hvµ¨-ýV»Kâ�{~m��ú`¯=Èí@g‡Ð¼aRŒk½û†}Óî6s¬ÕÆÒJ@ppÚ�³Óv ²Ú]”4‡;†ò82ªÑÞhž¤UØ0ìˆÞiõ/áµ~Ü>mC…Øþ“ö°‹`÷ëì¬Þ¶¯Në}vöªÖ´Ä]“wJ¿î¬-´©aŽ`¶œ:æ¹ã:Ñü)i<Ô!0¥]•ëHôõV(7¥ª…ŒÇ•¢2áÖœ“Èօ|šªu‰¿a‚ÒŠ–3è¾à}ŸÌÒòµôÊT.K`]$V´èAÉeBÚ &'qÕ AmqÃâÙñgáBërÔméâ]j}/CðÈ»Bú8Õ¨<ƒ°p3ÎÁSV‘ò¢ÙHŠblƒ KÆ0'¸Ž£Íã“©ÜÛ˜âÞ>º‚‹kx¸ðmßõÇÈà¡h%ªvZF:­�î‚{‰ýÍ1µ³ŽR º‡Í—Ûÿ¸Ê qµ�²D¢É‘±QÞ(Ä[)x†s¹´éŸÑÌ¥ØëÆFXxñgÝù…¸BN$Æ4¢õ‹U3,�rÚä„?OÕÃ}7€eiD�!¬ÑÄrsB9˜¢HDM¦mCþ¤š‰ ¾�*HÂÅÑÙP¢J êàí†xÂso|[y ŽDFv6f�ì– �D¾ ³Eö³)·lÁì…ò4¶#ÍÝŠ±�eŇ`™šTcÙªmòª‘:ab'Þ=–âÞ�â«xÝÄ õÁ� Œ(g!F‡Î~¯ü=ÜI0ŽæùyÀ/3³5D+¨¤ñ�h”ƒ9n�$g„qŒÍ÷ê(€’„t‰ «Ï*.pPN/õcŒŒ“/íZÝ=ÇÍ;™l«ôPE5ž�c¾ºØ³„®(BÒm1ò]Љú�‹-9†Ñp (åÂÔuRMz¯Š:K]î˜`éýómUÐ]ªçã`æ…WŽõn[µœ¬¨…—èóo«’ÁR%þ%¬î,?Ú?ºÃå:ÀûÁP?X^‰)!LÿVj{µTÛÌ3/gÑ–ð{ÝEü,‚ÇßþYkÿ, Ò²¯`ÑÌÚáÙÿíÒœüvÆÏ¹µ%øÁ7‹ð3|GQ¤W¦·¥JÞ,‰×›Ù;¼€sƒh¥ŒÍ6¬êfƒ%¾¼´Á`ÅD[0X¸ŒX²X·± Ò®Q»¼©�¨%«[ýš¸y ÌÞMæýaF\|jÈÇD[ñÊÑ=G|ÉfÃRh¾ Ó¡tº²²o‹»ñªEî¡&>Lj‰ùœß0×V�×^ch/Û-?^œ_™J录ÛÔ™‘�” …ÅÖ‰ÙCH‹úöÖ&—2!»Ibâï=ÝmE&zŒ›À–Dq¨j8Ÿœû®óyG'kÿŸ½s‰mdK pbÐÐÐ,v%_év_Mâò+‰Ý]mäÄNw¸yÝØÝ·û’ÖU¥|ìT·]å[U΃B �`+6°Ah$fˆ³˜Õ¬F,aÁl` Vüÿ9uªŽíò+qÒyüé{“ªóøÎûœÿ<þS¶Ï›™Åu!ï¸ôèۿ͆è‰iËVn„>MÍ3�ñW1c‚9¾ËÂjb�³qa-:ð2"å“}m]&6­¨T‡ hÞ+™ÄÂêw:}eÔxž2<˜-%{ÑR’äúu©Ö…‘VÊåˆát‰�P\qN pµ†ÉoŒìJ®©�ˆKϦ7”ÈÝ•µ®­Øs{ýN(Œæ,î!áùoKnk_²#­nì©ÜŸ±XÏOã:¹e:iËÔ™ÓFM$TiÙ}µê|a/aÏâvÍå».×ͰǔKiüô:_= šxJÂC³v¸En·CK¨!¶Ì¡Êl%iîýqn„MÙ@.׫¿Ü7ôèÍÀÍù&³ÊŽËÏ$à¦v ü¸-iTÚã*¸Œ>¹¸:ç¶Zð×áü”ly¼—<ð¬ÕYÀûªhoõ3ðÄž„‘gëT5C�ðä¼eöø_èÖÊ«ØxÃçЬÓDíI—µÍ£sèõ>“ö}~tä»Õ Ê[õ=­´º*hÀC)Ò£DêQ©à�¸rt†½×‡šcòƒ%¶-–ÛâÆL\š|WqÑ'žMÙÁôÇìG�ÝU_Šv£cF Öa|w�¢´Z¸éYÌd– …µåÒÚZ‘Kƒ]×8D¢™G §h¸Ñé‘áf?ó2q'8:¦“¸ ü1wo•�Ô»wD-QuGOÙP‹ªpÀ¬cè¾)7\~˜*VŒñÄ5¾Šò  ÃMy5²_Ûì4~»Ã�”ÉÓ¨ÑBySÁóµå:‡µø¡"ÏÄý´ˆ·Æ¯q4‡¿,RuO�Ž Cv&U¾½: SöZ`óMs(ÒK÷=+ì‚= õ7UmbE!Ø9¦¶Žk4l¹*•�¤¶¨‡•+mK©zò+&Ov+[õÏ´ìÓœÖÙ­ŽÎ'©o‡*Çsj4sÑH£Y*g}b©o›Ý%-\@YŠÎuÅZÅ ÚÀ�U2x^´R|¬:¬jëFebØÎEûhÒ„_©oe9Љ{”нüþ«èïb\úž— %,mø“/Œ¸9Z(Ú²¶{°‘Û‰g ×x«h¹¨Ç\Ûñé Q "wü1,}ϵ`lê‰'Þ²ŠÊ“˜z ôŠ›1®'÷/Q/­ï±N¬¾Þ›}+šDWvý�&®{ ãÇ%4ˆ!´>åV�(!"q'å°Ÿâ½T>}&\€9fF{J.s'"{†Ú£4 ‰Q6&dhËítÜS~v ,abÁPÎ`6ËX«ê©V;ã—;°f\ñàÃ-ˆ5ïñÏß >�Êî xê;cÍA=J ïœC¢¸Mçßþà/5T;ôÄÒ'éι‡º‚Š+žÓ˜ ȃ¦OÒæIGuùò•ópÇE8èyïÑÁ¤H*' ×1>ášsí ‡œ �%œð0X“5Üvšx lzñçŠÕT§?w2TüÙÌÚ˜â�oF�AÛ´äQ‚ž=xᎶo‡ƒ‹‰Íß´ø|³ï   “wêÑuôXæ‚gâ!`«¼ëj;жŒWïB5¾M^I�Ìã9‰ÅÍU‹Ç糸¤T-»%•�Ã#èኆë¡pÇõ:AÈçÁaIˆXVx;A¹Ò Ä)mÔçæÇü‚¡®Æ:fÖˆ ¡MÏäí%TuåÁŠíâPí Ï‘Äç™q.äó‰d@¨‡ŽtñPè“‘'‘…Ô€’ÄV4u Nñâz ˜Šá]ÛP°uÜÑ/ ñ›ÝðceºâVWú}“Ëb g#·â=Pòl9ï‡ÎRÄÞB¸äéqŠägÜ”O»ñ^¯é‘×^ã͈ÏSû¶…ðTù‹ùþîi­Âªoñ·‹¿Îñ×Ö+ü½^Yo ûív¾òE%ñ‡>ÇG4¢�hD#шF4¢�hD#шF4¢�hD#шF4¢�hD#шF4¢�hD#шF4¢�hD#шF4¢�hD#шF4¢�hD#шF4¢ÝGZá»ûï)߈F´øçøQÛÅ mñÎüKùF4¢‰QÛÄ^µ]g�vã •Ñî3Mi(߈F4¢�hD#Ñn3 ¥º‹®P)í>Òp…WÞ»«{¯á‡ò�hD›F“# ¶˜—ë§Ö¸Ê7¢ÝeŽu°ýŒÆM¶ªyZ•)Ñn Û‹”¶æ£a{À‘F•Ѥ9šÉ¯šÈùÏè̈J�h·—–Ôbf©Õèf´-È–tVl½LÚ#×Ú¨L‰v{iX›=”ó•YZ�ÚêÐ÷ðêÚhÜ’\Q)íöÒÔɸ1!e&IxT D»�´¤1axålR{¡R Ú] ÉU㋎ bÅ,iü¡R ÚݤÉýÉ$™ê*â6îÔ4•)ÑnßI˜‹Ž4óÅmšv•é]¦ K÷©s÷¹�&¹šuô¡Ú{ûhÃëHÃ+F”oÉy6I*ëoãVç&Qi̺½½å¼#ÍíHé°&ô¬5y”6‹Öô,û5ƒ)•3²‹Î�¨-\í~ôoÓô “i“NnNªÙ¿ñ#©$¨öÞ<ÚmíßfY¹½UcžTÊ�PªoD›­7�×T?Þ8™vÙ›ebÚeµÏ>V™Î[:Ô5—Á“T÷p^3m.{•³�YÚÃbd¤YÆÚé´ëÕ¾‘9„¥ôèá"öЍeÍ×£�Ž2ò<¶šË÷ä‰Ó¸zpU{”R»Hjåh-Ƭëe0�äjç|kÔK³Þlža)Èæ~ÌOg;Õ¯æ…Ú>†g?“æùWÕê©ö~Z|r[Î"V nþ(3�„%sÿϧÇmž|¤Ú{{hI=fÒHs•q»Þ›c§­¨%ŸÒ™edIj‘�.j½�jïÇ¢É^]Ž-7ižu]s™I»7TCˆ6ú#g‘òG•ÊîG¾Mi¨†-¹ÆÈöòè¡\-KÒ|¿ ãÂÇ¡MÛáúvßhêH#ç©ê:€º¦4zׄ\;˜÷ްéq[üšÃ¼š/1í²'&¨¾Ý-š¬Iñþ‚:öÈS›Ø.Æít&͈/ÿ}™ñ÷#]–:ÿLœÎm¶Z’4·;žWÚä"Ú�³¥”4\ˆö1iãæÏóϨˆv÷h£û —]©q›u6tµ-ë:n Úý£%Í„åH£Jlƒç-Çí‘Jóiûƒ‹;Éœ¼‚¡®ƒÜM�;¢II–ڳ踩saµ®�;¯5<† ®lϳÖ6m~3[¾M:«­¶—ûQßÄù·yJà¶ž)•5oçó.v*l8ƒ_·Tã5Übæ¹ vÑ¥p=+·¥ï�U²´E¬¸Ì|Ã{·?v«Wÿ&Ý´/Ç ’nm VÚÛ½jÚ"ztZ#Ú}¦Íwr~þ¸]æ4•)Ñníê¿Á7n�nP¼ì�ÿw¯L§åÕÞù~0?£÷¡ÖèëL©ºF=ËŠò}«!ôõ�ÅÒ¤žóð×ñ·‹�%˜g¶4¸æ0kíPCH¾™ç®ÔêCCÜI‘zi‹øâĨæã<÷u Ÿ½Ê/tÈ0¤\‰k•w§†\ß�w—6<�sÙß^ݪÒå­QЏƒh܈¡ê%\m¾©ûJj¯qûkȤ^@=§AºØ³åãÕÉ!“gFê1&IØW½þ¶(‰ðæïËŒ“T-ªY$‹û.¿]í=´³î$?z8©ÅÌÛ÷-NÏèîÕ�¤^ ¾WŠä·›"E_f¼W[Ýu¦tÞµrª!D»9´YZÝìòÛ¬ºm±„¿Kᢧ;¨öÞlš:Ã�Ö.®ï|¿JaÜü‡êÛǦ ‰ Ëf–3¨ÓÆ„øøeîK§2퉨öÞ$šª/0iµ`¾¯ÕP),†6yMõ²_´¦R¸ Mj×\ÿW ˆv9ù-iT§|#Ñ&Ñh”!шF4¢�hD#шF4¢]�¾ŽD4¢ÍK›ý,(åш&hãvw¤¶öž©A¥@´ûE“š9r"ù�hD›…&5sh”!шF4¢�hD#шF4¢�hD#шF4¢�hD#шF4¢�hD#шF4¢�hD#шF4¢�hD#шF4¢�hD#шF4¢�hD#шF´»N£‰F´yhó~y™ò�h÷�&¿²IùF4¢�hD#шF4¢�hD#шF4¢�hD#шF4¢�hD#шF4¢�hD#шF4¢�hD#шF4¢�hD#шF4¢�hD#шF4¢�hD#Ñ®†fèU30ˆÞ8îw�ÓîÀóºí˜ÞyÙh‚ÕVsËi¹eƒ9'¶We¾¥ÕÏëyªqðª–*ïØ–çún+о´�¦{êkoöµ×Ìóm×ÑVÒYíÉzßî4µÜj&ó™VgÞ‰m1mß´>hùgZ­~°¥U<ëÅV]ËfÒø/WÈ = LÄaÛtÚe£¿ûf›m¸M¦�˜�>{žbNJ³Ü¾xçÏS¯ê)ˆ¼ê ^cÿvsÃÌbV6<æ7ì ÃÖ6ó ]Z–��®nzVäæ2ÙLf«­´ÆÒg�‰E\~ôð[<пýíoý÷Ÿýsþ?þõg¿ñÓÿý_üÑ}ÿçÿîoÐþëþøwüÞ¿üä;òOø«üž~ŠOÿù+?÷àì~öð׿÷ç¯þþå?üPoüÍ/¿÷ìá'qöÅöþï¯ÚúÝ?fEKǸ=ÜØjlÕê[»›{¿t?øÁ¯ÕZÃ<ê0|ÕÎ|ûi�áùcüíøOËÇÚY·Fàæùãã è=ÕõÓÓÓôi>ízmÚpV³³]·ŽY×\¶?0‹Å¾¦{’nEØî™ïÙiËíê>wéë¢;Õ¡;Í>.�•·½oÇe%y†®Z¼©¶¢UmC×í1§vÖ3�&k–[fÇgàwØÜ¨ŠFÉ» ŒQµÁsG .Ò¨֡%@ïÎÿa+‰±±DÛ‘�H†›®Ó²Û}�÷®ŸG]^²ñKÓ߃௔ðÅ€_›6ë4y:÷Ö³¶Ñتú€±ñbŸ¿`ŽÔÎüÑ*Pñ<ó|¯5àìñ�·Q_÷¢ ‚æN¢ÜŒÞöÐElglù»ýNsZf“bá7}Ûƒìi�^�ZF&ÅSôÝ�»‹¥eÿ`ïµLG¥c›¾b¿;Ð�v«ø}\êë�g;íq ©¦‰Ù­ìÔF#L#¬nfbµƒ�ÑÄÓÄÄ«›™˜}·}XBE Í“«Zh9=I[NÀÚÌ»æ4y.hRÙ$§+²¾±…•-•VKKXŒ+.a{ å5øòÌÆ6Sß[«¬¬®–ŠÙå�,åÙl5·\¬ä@ZÑ¥´VÙÜ,j¿ƒwmÔÞ4Â'=~<`>&ùÇvo£cú<�  7~ÌeÅ$j¾�ɰ�œ‚ÁîEÇ=2;‡°§W� ù¤ yz‚Ù� R«§:1©�ˆ0ÔÃóPŽM]hw^gÁcœO‰7>ˆŽ[?òñ1Ÿs)ž1«GÃçRBà¹�óvX÷dÈÌñ£x’ëÇB¨¥€¹"ÿ•ÿ÷�¾cH¹%µ§8 gC5¨¤PB`‹•)»¹V­næ²Ëë™ìra#—�ÊTYYÎòëù|­šYÏbe �3Q2Q~J9�Ä##nÙ°!û³+™\\Knd œúÌfÀ23,iÄ-¹³L)[ÈÑgd„•iÈ£4A«!oÒ„#Ë›•ízM° €ûGÛ?fͪkaÒ3ÙÕ|®TY_β™åB©P�¤¯å—sÅÜz©º¾R)æÖ éCÞ¸d©–ª 3(|G¦‡ª+€Ó®� s=ìFç̓ö½íZáô½c;`>;à­ewˆà‡‡•»•ƒ½Ï77ÁìEuýëÊþÖ¡ov{æb�8ü¢Ï¼sètÓíæÌ�WÜÀµÜ΃íh(Im— Ã~Àeá°,ÒÇLW²ÃrAÞ…Y&L‡Ó“¼¶göŽm fŠ<�0qk[þàüõÅFýë]× Ž¿®t™g[¦óu¶TÌóY:†³7ÝÁØ~Ú žÅô Œ‚íà\ŽOuF‡±noê,*óøÓvð Óùåç ||QÛƒœú­O¡€Ÿ}ÓwÁ 9ßbKÕJãÕŽâ£:Å}}ÿeí„}5�ƒ:ºÊ(®VókÅl~-�YÊ•ŠéÜÊZ.—ƒ6ûîÝÒþÁÖNM ð…ǘsj[ÇŠwHÚ»¥W»[ 5b¬ .e× +Ðrs+0òùwK•W�—{[�·ŠG\$Q¼áòÊ»w˜iz˜køüfϳ۶ƒ¯ËùR)]R~Š%îZq‚ïo§ûx;èãÍÛ:´†¯Yø)Š�-éÿÉŠ bøþ•D»Ù wõÕ ö«˜;àì$sv9; œ�Λ· F¬ÜhTLCÕÈ®äŠHÌJ.›]c z„™5è”ÇsÀJ/#ýÕˆË�1.wF\¾´ÛÇû³laÑ…)îvÄM·Y+Øv�¶ô›LdGQ$tÄF´ª­*>c• +Œ0à/ãû t=#öHÐÆ�ô®Œ÷®Ð-ZÌ÷µ†ëvênß³ØóÔÆÓC0bWÃÎÚ?íü°Êü›� h„^ŽÜ³Ãð/¸ƒÑá$\òCC?�n23è{ŒKh W}Ki8b>OÉ%®”†ÃäóÔÈB>“*�÷©AqÌ;¬›=Öâ‘Ü€bç½÷µÛÒþq]%�6ÕáÑF~´O´N³Å%(~qÁPËi vhø·´i{~°ôÉÒLYBÞÒrþ{†S_-…¿G(æ/Ãp>ª¥ð÷hùâ…C@`‚˜ B6ñ¿£¡”4¬ÀDiîŒâDL8_ƒ€Â§Ñ V2/”' §QáÂ9¶»± p¤Éeçhr\èn¸ü�ÚÈPR•�Œ‹§¥TYu;®ÁŒˆgá"éÌîµXà¼`#›'Z—mns…uɆ7WXs4Á‚¬«—ÉÆE5ÆùB�·Y.(©ã¨�•úð4KóVF\Ü¿�a×>aSv~q’:~ï7Þí ·´b:›Î§W×V ]ðÅF©g÷±½ÈçÓj˜Ì»‹|ƒÈ0�üÀ3­  Ý̽µó½ëÉÏc¸ :_ë„Ó%_s[ZpÌ´Žéµ™h–pzjǶ£ JZÓà¤ËY¡Ócڑ鳦 Cwj›Ž‹'šXÓÁ|D§ZËs»`ã:Ìæ˜Ïû?_bèQä�^ßë¹>KLLüNì&FÁјXä€bhÊ@ =ÖtšJ2[HH§‰¦DAløý^ªB«¼zðQ ÕN�™£5m¿×1±Rq$ýTË>Í.AaãÿÀ‰¼‹]gQ~V´ù OLÔ"—‹ÂåêNcKÃ�B²f˱Ú@^5åzGzuŒ¤01¾#Ÿ�I0¥›õ­ÀY ° ]8áÓ_Ȥî€ÛfmBL ~ò”ò©o‹ï糦͓ƒ13tùfø0�Û¸Ìãh^ɱh|:1íA¸ÒÖ°}¿ÏBˆxæ–‚i� Ó-V>`M¨ïM J­cCLÛ\Ò^Õ+dT?`K<Óµ'ÕÏ8ˆ{çOaAAQ{Pne¹ÒðTKJ—hñO6ªZî3íÐâEe)=Ëò¾`¼d�p\0(ªÃÃÊë�Êþa候ÍFŠMˆ*£ò `¸wœ"DõP�+gtzM¨¦}σ–yvˆTc`à:´áŽÃÒæ}ä=4”¸Âfp�Nš@¹JGzìQ�ô!ÿßÞÕ-µ­lé3·©Ê;tqsH Ø’‰·k 6‰kƒÍ¶ Ù¹R´cKÞ’lâsu.ÎÌíÌÍ<À<Ä<Ê~’Yku·$ÿÛ`H€•JaYÝúúgýv÷Zr?¢] Xtƒ>>P•c‹É­b¿GgvìÜ€£¾½Eu¤îƒ–ëHPÀaº"´ªa£žß^}”øu©x ’}5½³½¿“{ÿöðÝ;è·*F·'«½ÛÍíïvw�ómUÍÇ Œ±zXí PØ ]C7‚þD½·{¹ýwoz«Š¡ßiG;tIW°`œÓeU\*£ÜÌë³.ÇɈã ;»7¦œb/fŽ Ñ|&ÍëÙÖñ7*Ðå�>¾Å¥zàK á¡oú¶–z�çǦ¾§%Y 4µÂÀëtd¶$¯Û4j?°àX frC™^™oú š�Ý^vK]áJa™oêv2(õE]¨Çòé<ØŽã€MŠKe‡`.ý,iˆSσ&ÁŒù�!šDSµØ�¤ºji“C&XCW\ E·ß‰=�–-°J^芞ÆCUu Á #¤‘¡è¨F°=Rah=ßéôÉK�ÿSÛqå¯þg³q¦l)t‡œªûÿ›H!ø U4X¦YqcG§#¸õÕ}Õ´Ÿ½®=m­»öPÍ…Øä³�,ƒ­�CïªOº‡˜6Â~0v!ŒrâœÄ]àäÀ�EžþØ•ì·Úð"Õ“HÆé.yN”#lÖ ÎA{m‰¿þù_àï Ô_ÿüoÝØ�ŽèJðLl8b6©%ì#t GnÊuê(Q 'ÙÍQÓaGQàx6r†«Ñ€ýêõ«ÖÌ1NŒî•i‘y ßï?Æ�¬Md Ým'è ¡-_w a(P›zΖ=ëÄ`Ä ÿ]»'¼.¸Í‘Ø”¹ëœÈ]{í-‘û£'¯¡bìäÞ@°‚!ží€J‘îL¼çÓ€*Óç ºEìÕ#\$GI81ÊqÌc×h4Éôàø€9 D=èžq õ¸6£7À šb‹²³HKbjÓ—¶]v‘+,c_ÊèÒ+(ÀM=5yÄ4G =>Jó9ˆ�œ‰ìd‹0Ú�x¸Ý%9Ì^ôPã2Œ˰«ØÍ�Mñ¾ #"²iBrà’hD°d� `c¸6 =@8MÍUÐê±éþ‡T›ÙÎ7?¸íH9„Û¨˜�ÓÙ.´ &ü>Xæa×c ½LzHmŠOD?¹§�Èzò áa\צSym]ÀÍéÂÑ@SëøfÔ(¶zy�K‹4�Îæ!¬ƒ]{©v4SÒ2.”Ž„u“bìÏUQ)·Ê¢\¯ˆfõ´ÜªVÄümÖʧ–(7«¢úûñéEnŸ‡ |à´vVÃz_ÊÍf¹ÞúºEO«’ãjݪâCçͪe�~åã_ë�/§ÕʧªuÊ-‘´yܨ·Êµº%¬ÆYUÔu¸qÒhžQ”ä–¨TOªÇ-¸h4EµÙl4­œŸ@Õ-Ó�1Ø/µÓSqV­¶’îüªW«‹�~?Ôr«Ö¨[Ó'/¬ªhœŒ�Áýz­³Ñ¼8‡Dz¤ ¥KtX—ëøÍ 7šM¨R­è‘ÔÔ8jõK€¨B ÔÊõcèJÚ�RìË”éµ>7.N+Ћ/寖¸j�àL·.ʧôÑW=o‰êó$Õ„U¥ÂÖgQ>j\V·ÄfÐäªR_šÕZ�Øw kÈek»fmmÀ`[нVÚÌk¹þUüZ«W¶Dµ†OÁÉ©��ŸÖªPT«#§Á”qÖåzƒdŽÚ1.¨¶»ämÐ`’Þxþ €oy­ ‡mÃø´m‰[D¶7âMÓÔ¢zYA´>£`¨Í·z%�ÄmYšmÍMë °øÑi•sܰZDAà¢ã‹fõ Aà«uqdµj­‹VU|j4”àZÕæ%�ОÂSø�„�¾YåÓª¼£ «F„GA¯W¤‰% bU«…øªÚqã 8‹¾Còv£bAî�}‰_ 5h.Æþ 8“. æ‚›ÀÙ5ì-a�vi!f±ž„ëêïUàÛró«ndø· («‘¸ž•Q5–›5 UJ)"�þò§fUÏIsBCMÒ-ñ¹ñh­”á*ök4IqúIL”^ùò¹J - Àí¦Ðísù² Ä«Zå²Ȧ/ KVMËQîø³SË-­x”ÂÕ R>?ËÍá\[-莻yR®�Á f^O‘–XC2HV úƒ Sùª=4\š�ÓÒìHú² Ëpn”ÿû¨\âºióÆHÑ~|„Þ?¤f~`îͨõ&ñ^•±¥{FPÌ7A6¼ð�^0¢49Aˆ+RCðI‚J+XΠû‚aí#KË«´ÿÊ=ç6Ñ[©™TÙ_ã )¨¸£V½.¨*'×Túà&8°‚?ìq“P�…©“ÀjáZoí’ÛÛߤoV2©ßé>\~#Ÿ·#¯Á5Á»ø­\~Rrä�)/ÈnC\Õ1ì¾RÊ+–蛥NÖ¨ž¥W²¤'U¬Öªèüt½(ÒÞ|fé¡”©^–ÀºH­hуÒË„¬LNâ´‚Ùâ†Å³ô£±ÞmѰµ‹Gõ2ëËd‚gš8ÒÇ™NåÌ€ƒ›q†A¨ò“O•ãôQ >raÉm)ªãl@÷d·§÷6z¸·�®àøÚ.n7è×H ¡ê%ªvZF:­�î‚{‰ãÝfg¹@ »¯·ÿq•ájy‰XS"aã\1Ÿl¥àÎ`bÓ;9Ü¥3˜�ÚëÆN8˜)0ëüBe„Q•b/¦õ‹S*:Àå´É AxÝ3wÝÖO# La‰·%í.•àSEµd».Ü¿âÖµÁ YN¸F†Õa)¬[‹ù¤ZQß*íD]ÞŠ¯àäÃ2$;VÕhÖ·"Ù�§ ä¡ÚÁÅ# ³3¯6_që-€‹Népwooû`÷Îô­¢NV,ѾùBQý‡ òJ‡…ÃíýCŒ�|·Gåê6VhÛß“âw‡ºob¡Ä�—�ÿa¢Ú¨\Ý/Þ!£ÒÁ‡BAعnÖ¸ï>ìD®1-Ó'p�zKœÁŠÚB…“Ѓ‹b^=ªÈ ¥ÕÄÈÂjÃZY‰´Rt¤Š<SOԱܵ·›M4b%Üq µôîUR *âð!4O‡\%sMy­˜�6t7ãNpæß•ªÓ&›âÎ8ǹñ‰ ,U…¨ìÈÞMàK±IÓûô||+A»¾73D]¢o3çæ! ú× $h¦¶V¤Ä~†N{ûûo?жíDàÉ‚àn½ÀÔ €(¤™A˪ª»Û…Ã÷…�£;N^GlÊmü|cF˜P÷#jÉ�y±Ð�ºF.­¡”TÐñhõIN/hýœ@ußèÇ‘Q“k%æ–ˆìŽm•ÐdêÖFö*Æz!ÐzQV; ¬6.áq;gRÏõ¥‘�`Õ;h„òš!à{ÎiEi�uèàJüÙ—Q²ý¢ÖŠ&ÙIͨ´Ý?ûàà]‘h+e+ÚîJãÇmèÅ´¬èG9’H’"}EgC©*Í›ƒw´ê ϽñÛÔq, ÊQìŽõ’ÝÒ±ÍHWe¶È~Vô–-˜½HŸÆži3Ey˜ˆe@ ÛV«²](ìlï˜úª�žœ(ª¢ÀPµØ¡J³ Æ U¿S²ƒ±6S°¤åyò#ÃáŠîð×Ë.ìììîìQWgë“Öž¨+­‚²Ï]Ò‘=x#T„¾È»]*âHpùNa¿l¨á ¸ß–6�qÔòðܵ˜×eªf6�ÔÚQð¾†zÁ¨T¨ôS¦pœÉdj}Çæ�;ÿ}¤ÿâq"•P4kõÃi ™²’nSÒ{Ò9ȧsõBŒ�¥eU4$®-0Ęþ»eäGðhG]õÁ‚Œ`U¤ãá©K¡å‘ÂÀZ¨Ò€Ù£ÑéÉQè4îR!T üë9µT©JEO»áJp¾õxÇ"�K˜qár°ßÅm5@ýЮÓÁt¡±, Âu³.}zO¥9 Ué ézöwoôÑ$T_wÛTˆ'¿ C‡$œ#j¨\ P+ŸÒ1¯)+µ¸¸(8¸ÒÌò='"ïû±boúìÌL›Ñå¦âhßt^·.2uœ W·M¹K'¹tØ� Íš¤”H”̳$š:””™KP¬°PTÑ·éZšhmŠ©¢�Ét³+R±BœÈ­i0½œˆã[Ï 1 tkô(d~|ÊÌ}ÂPX5Ô}ÕW¶G*h�©#Ú*œ\ø}LX˩޹È%úb´i4‘I=J7è‚)ï»c:Ð’à©ó(�`¸·àTš–¢ôØÓO }3èmg(®¥/i×£'‘OɧԚA3•¾€^I¥y´2©¯ ȵ;J.5ytÜxlwÀƒ}l_]…ràÙ#»´–G½€ßeˆv âš<=–JÂ:†¸=D1{4/4šÆëÓˆ$iB%})ahZr{à–Ê�+Ü/Ò·]s?2�tçà‹€{¨¶É`(¦"‰S‚¼Êcªý£ãñžÁlxÑ <Õnñ2]ºWCgC>³Á¸Wëj >ÑújGaß�n=çÛºZ9™Ò ­gÐÍ\W#ÖD#ÁN¯�õÖd`p1º Ž0 øÒ“· Ðøæç(yÁ@“ˆ4(‰ †t–,©âƒ(Ž%´q9§ºAÅø.gwü½Ô•àÖï`P™TèDSWÓ#ÐZ Jþìã %©ÐQèh:˜2˜M`Íä zêìÀG¸G#·+&ïÅ$þ*>,ÇàX‰Z†õÌ;°7ëåšõFì|Ø]ð½±èj8/cXg¹®˜DK9‰I­É[Ýɤ°š×ùù¯:I5?š¥J‰£Sº’ä”&YªgvøíÆîn ½�²•„¥‰¬SP[#ÙKp½î<ì4[5› šÐ.”ÙÞMŽnÌzÍ|++¦Þ­…wð±˜Þ‹¶†”QìK? §$¦šºRíéŽÛ“DÛ¢Þ<Þ=Kg«Úø~»R9ÎFV^§Š ’zt©©ئžº"Éje²lÔÒ½WÜÿBsd†©PýPvÒŒ1xÜí;±J^y°Œ{¡Þ@¢ûGô¤/“Èž D nPÒzŠ´Ô^÷qâ°Û f™ª¨é“GsK#&Ó8eBÛA§ÜR¸ ÂÂB¢Ÿ!CË4‘烨~§÷ H7%ÍÈH§©.°�êU+øìØš„dnÁ­!ø�^ Žð9ŒÏðPß÷¥tGS÷¾‹Õë^þú×ÿÌt UØâf®3 1=-S‹fº Û¸™³�l%˜—?0 O\T…^øVhˆ By~�$„{ÎÕïhrŽÁ—ðuü‘3îù.Æ -&ÿîù13rù©Êùw û3ÈŸ¾ŒŒ¶í˜Óëž�\„ú5ò´q±Qüm‡Ö›}³Îüœ>ÆÚÉe‰ÂĸS§T„ÛW ~éî�N‹¢“YýŒÄ2c ’fÉMÙ¬³çÙ8\¦XËk›¼Wõ¬w4‚�;J%'ŸšCJ¨^�_*·cŒ)ÄY�©çF:ß o脺¡Mò¢³+©YuB©3­0t! ¡ÅµPD ˜�‰©#p“ô/túLgTð«òГ¨%K7ípª/AØ‚¥¾¾àk¡U&?ƒÞ>蟺Ègêæ³ù ôò'ÔÎŽ'Þ‚‰oˆ1á̤õ±}Z]ƒœ|:óã™!m�o„1/^Å·dþ²qî9È9¥ß¾íõë·Õ2ý«|Å¿þâŸÚþ=*]«òÓë½òoå©ÿøG\�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ�Ñ^"ÚÛ?ÿƒç�Ñ-ý÷'üËÊÅ(–â;{ð“ç�ÑMY”‰Fåúí¬r,·6LF{ÉhYKÃóÆhŒÆhŒÆhŒÆhŒö”ÑЫ»ëS�Ñ^"îà.ÂÁûÆ%üãyc4F[„f, JÌç£[g։ϣ=g4´wµ:(?“}3RµŠD1Míi ¡¼ok54”´4YÍÜÇ{æWMÌúgreÄT`´§‹6Mb–áj¬3) F’¾´?O;#�%mLSF{ºhÈͯ_™õÊ2Ò“•:|z|wm²oÓj1íé¢eW$³lBjeæyxLF{‰hÓlÂøÎÙ̽Om|i|LjçmúœÍóÊÔþ۬ݹy¨l³ž®¶\ÕÒ<�‘ŽgB/ËÉ“hËdM/s^3:R³"»ë ‰eá±Ð^†~[”=m^äæ<ξû?¦Q‚¹÷çC{ªúm™�«É·j¬2JsÊüÆhËiÓtOõÇYÀùh÷}³LŠvßì³EÓU©Ã²°®µ JÌ4ÞÃuÍ¢µìC®>–‘‡õøHËØÚÅh�›}cf©ôúÕ:ΊX²VÓè“VÆDÀ£ÔÜ_“ߥO³øà¡Î(�/v—Ñk­lÖãYœ#³Û¹ÚžËÂzÑœßO¾#Œ…yëÓå¢ú³s‘•�ñÕϼuþCI=sï�AK#çQrÖ±Sðó[™U<,3ø9¾\Ü·U摹÷é MÓ˜Ó,ÍCöíqß»hGmz”Î2–ešD¾~µ®ýæÞ…f´º±-?Ó:ë±Ö2óNo˜CmòŸYEšY¯ìeÌÛÚä.Ù�Ë�”3\íG¢ÍZ?¯¾^`*0ÚóC›<_¸ïN­êÛ²«¡‡•¬Çx“£½<´i+aci²Ûh¼å¬3RsÑùàú"™§ï`d÷AžgΣOîYwß²ká,¯ÏŠ×·!£;Û«ìµ-Zß,7oóbµ³òò2øMÅ¿­B�§ ªFj8oñyw‹ ïÁè¯[fû5.1«¼ vÝTxœŒ§¢{—õ¬Ú:vÜä¼á{·´ÔÏâ¿yoÚ7¶‚=‡Ÿm• V>Û}h´uhtÞc´—Œ¶Zäüê}»O4Ó”Ñ~>´‡ÿ ¾Y{t£Þà}ßøÿühºhF˜{Wû‡ó¹ž¼�,G?æH³{ÔËì(¿4á_Y/šÉsÿu¼õöín±«¬–F÷–åŽl ÓßÌó\8„uÈzÐFORL^Ú:~qb2óq•÷uŒÇŠ>ä/t˜6Œ_‰{•χCï�Ïm|=`ÖFß>Ü®¢›·Fa+êD³,F6/áaç-{®”ÕOŸCæi�lœçb/7�ç‡Ì_ecž‡ýÐûoëòþs™YÞC6‹jÏâ¥ûoûÚeO’_¿š'1«ê¾õå=?™¦Ò÷J±ÿö³xÑ÷±÷Y©{Ì‘®ºWÎÂh?Ú2R·¼ÿ¶ln[êá¿l*Ü5ºƒ¹÷çFË®pÉÃÝó�_f­˜ß~4šò¸�6ËÄ .² iø}Þ—Î4�ÔD̽?Z6_`ÞnÁj¿VÃTXÚü=Õûþ¢5Sá>h&»æñ•€Ñîç¿M³ê•ÏòB×�K‘I"˜ºîçðt}p‚žÌ6¿OÍ«»T_ÕSŸ4WÙqb_"›zjB`"­a¤:ؤëXv“Û¤¿ôcêª~Ùx»ûþpƒ¨¤ï‹À'Lƒ3Ú`õÜúDä4¥XÕ°y¶â~îmnkêÂr’é@>Ó­|¶»‘šwõåR:±&ðJÐ;€H¶‚^p*Ù)#ÎKî#sèº×2èʸqõGD×p$,?™Ë,È[É”˜'Žýx”³Šù¤ d® 6Ÿm.?Òùüȸº.hi�âîv ;»…=$¥*FêËØF—^¿ú·¿ýíoÿPK‰q�EWú÷1 Querying.gdb/a00000004.gdbtablxUT Â\�T×\�Tux õíÄ� € EÁ/’3EùQc¸—Nwð^MRVש׵wï3î–´'ÀO”Ó6PK‰q�E�}LrËpQuerying.gdb/a00000004.spxUT Â\�TÂ\�Tux õíÝÍQA…ÑFQ Áäoa†öÐîn.aêœ*x,¾º‹)ÖÐZkçv÷ö„/€Gôõ½«ßÏmís¹ÇÜSîµk÷îv¹ÇÜSî²—®ÒUºJWéZÏ^Ï^Ï^Ï^Ï^ºJWé*]¥k#{#{#{#{#{é*]¥«t•®ÍìÍìÍìÍìÍ쥫t•®ÒÝ®oÀÿ½z°z<½­G«ç7ô`ýÞ=X½ÝÏæú¾¼–|Éç PK‰q�Ecàšzk1Querying.gdb/a00000005.CatRelsByDestinationID.atxUT Â\�TÂ\�Tux õíÐKÂ0 PwagÉù8‰—N].UõìPH½›yÒŒf=DDWú¸�6üÇ–¼Äk\†6®’QãÑ%{ ËußúL&¾Vµ…똅§ÎàüÐê«,Þºìx~ît9ú�ç�¾ûPK‰q�E Kc=U,Querying.gdb/a00000005.CatRelsByOriginID.atxUT Â\�TÂ\�Tux õíл €0 P»ÐYŠã$e¾K!f‡D@OGsO:ÛÅU&"šé6öBð§=Ù“l�U}aç²çhMe£¥i¢YÚñ­…oÀk¥©Ï‘³£ç¾PK‰q�EÞwéES(Querying.gdb/a00000005.CatRelsByType.atxUT Â\�TÂ\�Tux õíÐ;€0 Pwa‹DÕHaM?\ qvhìl,~’“ ž#n}O ?í%ÛºOµªhô,ÉÕ$d­žÊR-Ûñ­ÅoÑkÆÐfÏÙà¹/PK‰q�E›�”‰j#Querying.gdb/a00000005.FDO_UUID.atxUT Â\�TÂ\�Tux õíÐA B1 Шwq°5mÌ2mÚK}þÙµ¢Â¿�›y0af"¢3}\þc3ב+ç¢�Eº²§ÖØ¢ÞG”GÌHûÖç­›dádÓX\„[Ò5ëÔ2­ºíø&ü\é´î;Ï…¾ýPK‰q�ErÐ'ö0XQuerying.gdb/a00000005.freelistUT Â\�TÂ\�Tux õí׫ DÁ¥<š¦5> A‚'3æ�Ø®$éS�m~Töÿ¿dß·žÛè³PK‰q�Ežé¾€>!Querying.gdb/a00000005.gdbindexesUT Â\�TÂ\�Tux õm�] AF¡½ ¸ñƒØ”+%®µ$‘�uãׯ3&­vg¦3Ïû>Ï4}`( rVìdÏ…#^,Õ`,UÕqͤ]ÏþÜ[gT»„\=©õ‰Ì)t¯M¹R2ã­÷É™“ÜZþøj³>MæäžKµÐW|÷{"q ¿ÎX%Ó6òðÞüM­PK‰q�E¦A™Querying.gdb/a00000005.gdbtableUT Â\�TÂ\�Tux õcf```âI@Ì Äž 0“Bk@ù y(ÎÎÀáÏ�Ä�Å�Ê�ÌPÔâÂÀÀÆÂÄÊ áp«1U1d2¤qD�K�…ͨ¥¦(ÀÂPÉPq¸�2%`mI ¥@H-+WP0¬®(œ ‘`daeØýÿÿÿ¿³8ì*d˜š�7Eo›®qÀ{êü�Y›b��º,âc¾—øÑF~V:ÏŸ} 2}¦uì9¿á_Ãê�wž˜¬qÞå.ã·úÂóã Ÿºñ_•)<çJºxm,ûwkÚJtƒsIVÏ Ýì±u¯~È:že8 R«óšY­zÜeáî¹Éo#î_D7hZ¯­T˜… CCd;Ó¢«7U°PK‰q�EÜ:() Querying.gdb/a00000005.gdbtablxUT Â\�TÂ\�Tux õíÈÁ ±=DlÏþ«ñ«�æ3#Iu£›yÖ=»|§^×PK‰q�EºÌî¹$5Querying.gdb/a00000006.CatRelTypesByBackwardLabel.atxUT Â\�TÂ\�Tux õí˜ÝN„0…þ­ÿú}ˆÆ›Õ_Ùê‘’‚1û6>ª§C%ëÞ씤CL§$ý2Í´¸Eo'Ô uFùøuE�S uJ-¨kꂺ¤©cì·k”¨°‚ÂŒx–­G¼ñ>õ•’©F‡œ”5Éç=G«íðEZ�Lü-ý.¾íl†”¿Rø¦Êؼøv)ŒTÅ3[ g·D!ý=÷ÄÇj9šËY.O#Ù £zžHe…« Ÿ­v¨’{¶ >%cVÞRXJë›q‹�‰ùvYÆžã¹óõýc•¬‰9^‡yV‘o/ßÿ•&¼ú}‘ýÍúõ;D>èۉ Þ±�¯Ÿ?+LZv:íÏZÛ§·VRµíÈ|Ñ¢E‹-ûQ‰ÿ²ÿû àü_PK‰q�E|µ’ù6Querying.gdb/a00000006.CatRelTypesByDestItemTypeID.atxUT Â\�TÂ\�Tux õí˜ËjE! EÏíû}û�ÔćÑèO]ο7} :ì ÐB]°@d£‰à@·mÛž·ÎÜG÷ø9wî^»7î�ûàÞºî¥{pŸÜ{÷j[ü§$¦uH…9%HM 4Fj‘#—bû/¤J(X$T�œ:�„:R‚ÔGš[mSÿnJ(d5Ë 6(¥2µή6| öc™qxÿ=�0ƒ)ÄÞ$‰4ìŒûI18b| É Õ¦�X§¤ªh3í§n�[ÇEªõAÕSJ\jLM*ç怜 ¥8X–T¢÷Hâ"² 1L¯~ú9àà œ»W“#�`ÌÐVɦ†-îë†-‹Åb±X,ÿ——÷WüáË/ÀÛøPK‰q�ETUÅ_ò4Querying.gdb/a00000006.CatRelTypesByForwardLabel.atxUT Â\�TÂ\�Tux õí˜MnÂ0…”B[~�à»´ªÔE. ¤”T�.z›•Ïq²Ceò³ž<“M>ÏØ–I)hXÅ-üŒqp·qwñîà'ü‚{:¯WåÚé D[潜ވ}¾WÊì®ã¤óèm¡}´‹†èm¢´‡Ð6 cýçºÓ µšðy©…F8;{‘ÇÅ׫µço|N�Æ|÷ xúù®õ¨[Ü™8Ï«~m kÂÙ„ÖšREG¯Ÿpiêç4‡gFg­»©ëõ3ã»á,Ô®%�õ‚£7Rú}ü+§^ÏÉùbš4•íã»Á{ªf9ÂßwUÌ¥¿uØ1¾›Îü毦³Ë° ÷ï["¾ïmœßv®`²M7ϒͲïiaÌñõT|6{Æ´t+hÞžvÍçºøê°7~;—�×Ç—ÃÆ‹³D‰%JäïÕ {ƒÿúÀüPK‰q�EÀ/T8Querying.gdb/a00000006.CatRelTypesByOriginItemTypeID.atxUT Â\�TÂ\�Tux õí—ÉŠ1 @{²Nö|En[‹%e[þ©¦ÿ}ÔÉeŽ É-~ð ¨zT A|¹\.?/x—~K¿¤ïÓÏé�ôkú6}JŸÓ�é÷ôMú!ýôꇿãж¼‡uØÛ ðj ¬cŽÀQ[mªëö`űØÅÖ \˜ Kd*egÙsÌÛU‹’Zéy'°—¬pÆ —ÑÇö¬H«ykà{tàa.RaîíÅ£bÃ’ß;î°æ`͹ Ã芄.t¯‰ )56ßà<ÔhêD2ǽÒ*¸båg™PÀT³Ç²¸5å(š•jÝS8ÙÞÙfÚ¨¯ªÑ½R}´Ê‡%Gê�›AàÞ†G�J±÷,}-¥G«Õ�±Æ€%–•ÖÜ*[NOTx«e·Ûuçæ)Ú†&Ó�¥2U�ÔM–/õŸVç;‡Ãáp8þ_~ý>Õ?½:Á߯_PK‰q�E‘ü¼,Querying.gdb/a00000006.CatRelTypesByUUID.atxUT Â\�TÂ\�Tux õíXKÎ- œ<þ<ÿ*ò¥–[%�äc6jíHÍ>j�¨Ñµùa5iºw.$k©FY}2b!Ÿkvîmu²Ú'±("gw�»sT9&œTÕÈF锿±kÔ(�©a­ •˜]EÆY—R±®U|ÏÙë㞥ÖÜ"Øœ@'ª.2‹C-8zÌ6"å©Â"Ã.ÏPÕI�BÈ&l%kòv¨Ö�ép?c<{¿á«Û¢Rlí‡{Ž•~éׯ™‡pÄK·G–=T{ÌPl2{š †ûâLÒu/Í\*ûqݰ .\¸páÂ… þ]üxùªõÇ_€çø'PK‰q�EdÍÁ­Z!Querying.gdb/a00000006.gdbindexesUT Â\�TÂ\�Tux õ�‘] ‚@EOÔCE=VôgL„ ¢ž#-¢+Lˆ~½]WȰÚr¹:{çì̺[𒇋ÏR س!$a,:RšVônHïù®4b¥ùLþ‘9w.Š®8Š9W%{²:5©ð‡Öõ>1;¶ÒI|"?zåºm³¿œÿ̬½\%õ±³ö3™*iV>“ÂïY×{œõ—7åcÖLô õZ/¿Óo\ßZßQ&äð£CK²‘PK‰q�EõFÉ—¹×Querying.gdb/a00000006.gdbtableUT Â\�TÂ\�Tux õ…U LSW>Õ‚ üùé”'‹Œ7pnˆ:i)T  ²²˜×öµ<)ïµï= D\òW,ƒ-²d2Ø Œ³ItË ™‹Ä��6dºèÆFÔl„°¸ûÚµO6š4÷}çž{¿s¾{Ϲk@†þwÐß Ü¿q×#`~^ÊH|ÀG :8è�5(¼¥k¤¹�ë룥Z`€2pȯr ,èkÙA‰ë\¾²ƒT82ˆ÷#'¹Ÿ h´i 23`€ 4êдÍ=rFLz(ø?5âT }(ÄŠ£)'�Öx¡•óUmCPÐWiåd°vòà]ù‰EkÉé¶1mùv}³ü·ÖÝû.z_k¶eet/´›Þ‰µ¡9¸ÎL¨) Á•ÐL�çp–àü3q 7,æœ�|g8ROZp™Ô&8c‚7@O?5z)%#¹æ‹¼ð‚Æãc¿o«ø©üzpê™ Å®LÙ_ö–1'fÚ£5·pÓ ¹°\kÌ&,fR� x£9°İE1Úˆ=9 pŠç— ÔŒnØôlò¥¿íÿL†|73–m-6ÎnWTsÉþ*“f�¯�µì¨\{¸%jÇ3yM a*çŠBaÆYVMåÐÚL›J#_Ey’¸Ù\Š-© 8bNϧÄj,-ÈçøY;-ß{-³~òVvKͼBœöìÜÞ*©Ã˜Ö~8ⳘÓIú@%]ˆ“”š² TЇ ,æš0Ê—¤Ü)Wó\w”M÷âç7¦7´¾ ž> N± mÆï˜¶yAÕ_~vÿý$C°Ú�#iJk|\‚�41O×MËÅááèÚ¢P:eþ†�wS>íÝyùøýà$ú€íÁU"$åTè7/UÞãm6Œšr�2¤*Ús!Lk Tä“fƒKÀÁÓtç%¾žµ§ïPmWP¥õÃídüɶËGõê¡éà?}'Y±›=±è ³ ×1¤~µƒÞ">h×b̵ ��G_;øÞ†¸Ìw‡} O÷½¯×›8žÏx<ËnµˆV/DSÿ—£oì™Ñ:²Föu�—ÝKýœWÅ|Ý3Éõ½¯N­‹¯òSsDáÒAø/_?Þì¾|ˆÎå!�3ÎNs–�°6ýz¨Êއtظ±ÖÊ^è¯IïÈúvaýÏј8ó­ž™§t!Á!!…VË}›8÷å –T(æãšÛ·1rc³ 3ŸkN>C™ò}µ iBýFk P,GRÎ.€  GÑLW6­·å(ú’¾N|³³B\‡âw&Xxg/@ÏWfµr³ñ´Gõ­Cª4eµ÷�=·?ùøyµ•åÎO¼–l—^`4q»þë�A·Û¥¡€eî&ë2„{^tg zkyeçl¿$ô*†R#4=£÷®ˆËJÌèævµ81çŠ�]ÿPK‰q�E銊S Querying.gdb/a00000006.gdbtablxUT Â\�TÂ\�Tux õíÊ» €@DÑ]×&®Ø¥ ˆ‘©hd£Z�à X„Á=0¼BˆZÖ*­÷±;]¡œÎãlI¹�µTF?/ÎP+‡“ev.gj€¿‰ßìPK‰q�EJN÷øô0-Querying.gdb/a00000007.CatItemTypesByName.atxUT Â\�TÂ\�Tux õíšÙJÃP†§®uß÷-¯"ÖªŠÄ¢×il15%Iµ}ÕÿLNPÒz#J�ÿð› s¶™‰ˆ*ð¼ ŸRu~J1ê}×®M Qù;"Ú™=‹)¢Gag_D-°´pÏœ}Ž] ïÍ™J‡žK哯Q>qúª�Óq @—€1bJI1­ƒÁÐô1ƒ�!“%BâWä“6ëèÓ�gp,rü]€ÌÌ�€×èì|ö†Ÿ^ñ>¦§’ù.Ádö�ÈÒ™Сk\ [ùQ½âÙÛÙ·G*Bü<�'ïY+Ž5i„·<Ò|Є<›Mö’Ï ÍÑ32—@è^çr_¦v¦³-i|òæ‡Ë#/ûvq–ÐÆ]OÌNløz ÉÖfyë_‘OZg|&wI8 L?õµ„>v™,âüÊSµ}4ý¾ü=Uíuž‡·àuxÞ†Wà�ùþoFÎ zb(r}•v1Êgv¦XlÛ[Yç|W`Müåë1¡Éˆ†âølfž€Ò¸Œãw¦¢ë¿J¥R©T*•ê¿êÍÉÿû?ÏOÍó;PK‰q�Eöy5Querying.gdb/a00000007.CatItemTypesByParentTypeID.atxUT Â\�TÂ\�Tux õíØÉjÃ0…awžçy ®¥«¥,é¾TÉ»÷¤M¡‹.B7mA?|Æ„ƒ1Æ’a†çá£'X�5Ø„mØ�#8†8…s¸„+¸�;x\\g öá.à`na`vá îaoèÍ{5‹è›Ãg³W'5§&‰TÅ×PI’ Ä­¹Éb¬}ÕW?]Åèð¡ñ”¼Qâ8VÊ�•&IÑ(;õ‰ÿûJØŒ¹Ö‘¤ª;I4òZrm&z/aéUðQmó,†‰%ÊÌ™l™Ä‰L¾¿ìªr²ÎGž­Ç݇F©f&—›NS±!ùô+ÕjRqBÚ"ÞœæFJ&Ê*MòØÊ¨~Ö¿Á{½^¯×ëõþv/ï¿øW¾ü 0?PK‰q�Eà+]{2-Querying.gdb/a00000007.CatItemTypesByUUID.atxUT Â\�TÂ\�Tux õíXI®+7 ôÏ<Ïó¼ÊŽ€$Rµ¤$òR†ïžê$‹!‹&PFî'‘UEÏ�ÇãñÇãŸúxøøøxü | |÷/÷à3àwààSà}àWà7à]àsà#àCà àGà=àmà{àà-àà+à§Ç]W=›Ÿa“2­�=d³)ID[U«Žq^OîKKÍAÒw�x&ùYƒÆ(í°ñ\µ½žG¼[�¶š$E˜fØK.—ž{í×ï¨ÇgÛ'‰x#+mÒ™}eãQdÍ×s”ÁÃÊÄ·� øÑµ;¼¯¹ÒÁâQÍUÉsá¬eFÞ{¥�éÅ£6m,¹x‚+öê$­ÌX„ÖM‚›w¾XÊ}tĬBbŽe ã=v³Õ÷ºX£vÌL×$Ü:Ùà·rsI”Öhñê™ ”ý�‡$-›£¤´ä)kÔÜŸ±-’Ä©Öp òµb);”y Ü7Êð1@�el¬º…y��#_÷7ø]wÝu×]wÝu×ÿ»þüû?ü7ÿùàzþ PK‰q�Eݦ�r(!Querying.gdb/a00000007.gdbindexesUT Â\�TÂ\�Tux õca``àb7†x NbÈbHeHf(aðŠ10ñÿÿŒ@’ˆ1兀ؙ!Ì/Êä2„0T2YÅ N@V(BT21€È$ FˆK0!(Wäåea2è&‚ü€[!7úår�w‰ÖûÝ3-ù‚‹KR‹œKsòÓu�Z:VÎ=d×óݵ;Fâ©Üó}[Þ~4océIóXâ%³C£Û&™'(1/=UÁ%?713ÀU™Ò··Yg9ÍX”÷|ɱu—Ñ]Æ’ŸŸ“”_a TÛËÀ°øO–ÿÜ_në›fÙ~bVÓ,çŸë¾ÎÇt~§ÏSD‚R ŠR‹SóJK2óóœs‹‹A!…î tKØ îÑ*E÷#ºR^Ǥ⒢Ää’�ĤœT5 ë=lgçVú¬úµ$}¢vg*º ¬`• ¿¢›¥1çÂÿ‚ª~jÖ÷uÅýÌî ÈâÔ ÚÚ?…åÝ‹/û7©&ϹÐݯüЄ Õc Ô#ÔmÖ£·°ÎgšÅÉc~™/ûѽ-䜟’š¢–˜S ‹�U¦¯ª+Ú¼ü=w{pO‰ŽÀ° ¿0«´€zøÿk(òwh5R(�½ñ‡ Ýkœá@·$&§‚’_Ó’«ó˜ÒÜ{ïÙ' M.ÄH~ÁÉ©¹ÀHK†Ù ®¾¥Wü䓜¦¾måßåúgFÒFw0ɪÕ^«½û[Õk»Ã,©7‡/Š«¸£«e�D/gEq�N+³×<%�7¯¢gÿB�,^·ÔÄ’Ò¢THÚe‚T5ƒgÙŽ¿\öû‰NÌ^Ȉn2_piQYj%²ÃÍKMËRŒ×{,ÙWaS£±õ4z€²‡¤_¨örPaYÚ[Uçö'^·t?vtã9Bò ò��_iT\þmÞ�ÅRË]»ÎX1]¸ƒ®Xê ®%©yÅÀ\òÃi[ÇJ¦žû_Æ[Ö  ;ˆÏ7¿8ø DñZ±åfÓUa÷)-ξßЭâ‡>LÈ/èé½@âJ-Î/-JNYàYX\²õN¸S'ËÎ"?£¥Àbjȋӯŭœ³È¥Aófô's–�¸ $¨P„g7,>Ÿì¹ë�ðû?œw‹Ñ½Î�tPŽ‚[b°ø墇ËÙ¶EÿšãÜ2'oŽJcp5ºÃ„‚RsÀåKqFf$�¨µ¡{– °x–¤æ‚2º 02<ê`þPK‰q�E•¥DÊ} Querying.gdb/a00000007.gdbtablxUT Â\�TÂ\�Tux õíÍ¡ Â`Eá¿´à AB:GB‚a WWÃMº�€0ÓÚŽÐw6Àž“ÜÏ<ñò”RÛÇ–±g,½a„· Ôð‚Ö‹àwh ‡"pƒ>0AYW¨¡ƒ¶ÿ/l0¥¡VB‚ ÈEу ì�8n!·Žÿþµ¿.€ï~@-ÆŸ/€¯¿ƒï-Æ¿‹à'‹¨¯àïpæ 8gœ=À:¯=a ë°7áxæ…x64þ è÷gðIħ`¨0ëø©Q‹ ��Ö>Ķ‘]äã2øÞ‡ðYu™x�~Ö—O¾v/MЗíúÁ ¯Ï߯ËñklÕrû¿ËVþ{ü*õ'Ï2GêB5ŸN¾þ=tþïw|^^×üð`ÇŠåʱÚýš¯V•/W¿ˆ¼©]µœr€øŒjÍ,゚:ip ¿„,€L€Tq „ñG œ‚Å7Bp°àïã7œ5p­"àšÓp½(§Ù”«>7OEÂhÐxí(§Åx¨‹8T|ä%âà¥ð“hËÍg'RW ²ºK´`2ðfS8±¯ä#ie°–7±ôW0âŠÀÜö¬ÌPý]Oë·è²’Ö³kèõ’°GÅÔb–“ÚðX:¢·ç#˜sp”Žc¢ˆ»¶¨Ã�CKDTO냉~`éëÛ^ QÞ®Þ´)Ü,M烤ôÌœq«]û|¸e"²ºfsWØ�6ÚY†� 5mˆeôzÏÉ€¯+©É•=Z88Ò6ý8¼­Ž7X¡3Àu0Êcñ[b¸?yâ~KNø&ö#°ÚI°ã+à¬B‹­’Ÿõ‚[)7ÏžG`7šÓÒF#È@Q¨¬Ð«íàÈ‘ –" `ÚÀjÃY—çÿqŠ Ïö^mµe±Ë.<7�»gHœz+÷—ô�ä¯/U`wA0Í @<–Á.ø¥Ãdœ7]8§Ø{»³ e€»š8F€Cy~­túlù‚‚r„Á7*‹wýnçWn©ôœõ¹ÚÉKo Ý¾dõzFùëÅóÒùs3Êh笡`îbLal̵N�{Û­ „™íeøO3;r˜í|‡¢¬ÈÛXÔJsO`ð¦ÃxS$ÂHšó "K¹¹¾ìt;(z”9t!Þ4˨Լ�¡Í’Ðz(°r·"eô:H™8ZZ‚ s0ÇV¥¡ÍzIŸG<ˆå®æîöpd¨ìd¾hšÔ2vNÛ@OzRPÌ1ôîHs|=8fi�/BPW�àÓÎq wãW“¸’“»�4€œË‰wmpBU¦¤½û€"b²gçV -³Úsñ®ÊÔÓ¬ ³‘…û;kÎY@ü�é…âª0ÇVeŒQ¹BDV]Þœh±{®œÃÈ_L!UÖ²Z^O%×èîÇ„–ñt héyÚœ'º §µk•þôZé/}�šTÂorw–ÝÙ�]y¥鬦CiŽ—Dyº“•ÙvÖÒe%3e7¦“«šŽPAå7IâþAAr;©ù¹¥&á~`7„ âÍaÒü þˆL>ÐÓ²7—œ+·ô°Äp’}$0w“¶t�áƒñÖŒQÓf#aÔÒÒ¼Uº‹–щ‘!`i¼‘Z!Z ‡I¯g¤ÙðžQ¡�º§-�~lW4&‘;.ˆŒ1”7 a’Ä}ïMR–Fº6¦â`Q¡¸ËEIÆ&}>IÐGÇ+o׃¡ôÎ2lqŽ:¼*Í)¯ ‚‚+ãðS¢–½ªëÁ·�Gª­! ‡œ3›X+éî�Hˆj‹³76�ó5‡òKÅÁðxNšIî„vyí¦†±‘”/VƒUçã¿o-éÑ=XŠ\}ª2Ã=+�gb°±¤b{¨-»ø´ôa”~m4Ê´óïTÃÔî½”›'Y£@We饕š$4÷JXÀɔà EOÍ¡ŒÆÈk‰U‚%5Ævƒ¶ÎÓu X‚|§‰hš;Ù„Œ³¹-`kOn;®@ _jˆI>¦Kæ˜H?:8 öL$UaÎùÑÆ[©´áÜ–å„s›+Fû‡Áø®ì‹˜4s`89‰õKÒèÂ9dAsŽZÚ@kIi;Ö·•´¶l¤´ ø,•,µî°“dT°é 㘙tº©¶x̺²/•‹D_Ås°æ¾ì® ÑóZIah,.Ml5=Ÿcõqñ§•¨ Ê]«ÁS› ¼ï=lMLàOkU>Œž“v5Â�ˆÈæ˜#°æžÝW½«?&B®0Ál6°Ò’—ïFZ¾ƒ›:3ÀŽÔ®ö„õ@ؘ(4gbµ’àþŸ—÷uÝHlc­'ÓJ­.+atC_zX[Í¥¨ODdÙ ”*™®ÝÁŒÃž§eŽcTþ��pG ®·>!ŽïJéÿ± TìWbu\©áµ´IžQoÍ%ÐT[öM=(Jx�WáOCB òÐko� 8¸é”#â¹³?mþ/™ÊbÃ&» þŒQ û¡iª¾œ½ªÌH[ ³á`óa›e} å!¢T38k%pïÆ.4‚ë¹§ˆ��ÿ<”8Ò²r‘Ðpç=´¦WNÖ2ëBÊwœþˆD5up"­´ íØ*êJm¢9i”ÿB" väu›™¸VsyqG¶õ�ê;׉æxÖ(CÚ ŽÄ\Ûwç*ÚÁXtî¾JÑÔZÕ*^Fßÿûmìʹ]tÖ–ä �“)Ö†„§vµO��0¬œ6Jv'µoìüÕ°?æPލ{€YÐñÚpy•ÿƒ3ñ×N7Ýi³nú’û‘$Í�Œy�7ú™ümo>q®T�®Áª‰vOJÔ’À‚¦“Ä2°@øJvQïò&�QùÐF¥c0ëaÈL¬nšlûWq¦”‹–ñ[ 2£w;V´×mg2ɤ™µË•¬˜�+ŠÕ‚¶æÓÏJÊÃ7Jï�Š+ž`QrÖ0‚Vf’Ÿý÷"êØ@î‹› ¢é\7ÖAO ^•É¡D0Àݨ$ºÈ�TæÒì‡åm`[ôàm±2kx¸�`T°ÔÈŠá¢×HÊ®<õ¢Œîß{ç‘»î·T°Û6±2ÍKÊ/I™´ãŠËçæªL8BRÙþcû¬IeÛûý˜‡¦Zm†=ÌL-áØå¢G­àä�ïrÅ6=ˆ5ðfãZV2ßý»lBÀÎ…Bf"ƒ[[Â-G·Þ©¥c£˜O¯M¶<˜M¼9BÒð†e„Nv:®÷y>t$+oú3Iè»6P˜*ý•Ï} <í­Ç®£mñÑõS;ÅŸ‹S¬bhîÃ…(#o4ñéü#ôÂ:KaG¬¶}å•­ù¶³ðF&"|’ZéXd@Åñ‘,io‹³À\€í‰�2Í´»[&yâ!sb¶ŠfqcôHóÔ&Øsò€Ê.·œg„ ?ï½Õ ä6÷—ØPACËÔ¹‘ ÚÕk5P/$»ëUþ° ž±L=ü¥yø×ÅY‚ª2uŒ!ÂƥŷémÂÈšZ$¾ähŽ Þ`¦õ:I"èç5­õ¤^Û.tômD'øÒk?‹d®åLÓ¡^ð¤§sÇ÷bæ20…ô2IJŠEïX4TýÇ=-b±FÃéþ©{)ŽƒU1—,àÆÀý>œ;ž!áŒi /è”,'c´Û‡ óksZÀãmßì/ÑláZÁg•kÜo{é¶;T|IëU¯œÚþ¦üÇ’Ð×T\¡tH£Ÿ©“°«‘Î_ÒÜKÙÆê‰ß¡±Ë̹h8Ü}ªþ/MçÉ)Î1æÈÓy8º¸b³bßÙÎÓ•èHÝ ‚€ú55o0˜9Öå`¤þha‡åZKj¼âhorºjñuö6Cmä�B %_�-v%Ipl<9k‹âLÚÞ s‚R¦ò†ƒ`Œ¥Á I)‹ïØÑ½IQ�“3Z�ÀsÔt£DWa¢2O㸟ñày½û[m5y)ø©ÝƒMPK±]ļr‘òEù‰àæý•1Šä¸}{1øM[°R-ðF#Ë…MãÇ +!\ɡ̺XEѱ²ã𕞚_?ϨTó‘Ó=ÇFG’Øi›ömSd\mˆ«Fx7†ð�²t×üŒD`püÀÁ-ŠôľÒrr™ˆ{£s°9Ô‡�|ÜêLÜÞ1ØYwœmM?_„®]BØ0Ž5†£’‰~ޤû-Ù]yâ'páÀÕï Iǧ‡{Ì& 3¼}sÓh¿›} ÃÁ¡rÃ�£ë§i§›šbש3£@Üùã‡Ä)‚Í#áVeúÛÐ’¥ä!’b‡ž€Ä»Wwç¢ÛÉ9¨W®¤×­eŒ¡f!Џb{MÙéIÄÜSX÷#xÑ|ü<¾Lu ¡¹0(6Ñ·¿ß´ÞI�Éïz&Nv£ ´àÙ!‚Yà imAiSÚSçk Æ@B|׃R ]ž,Øaü:IhÈû$ɳ �í½®�ØØƒŸÓÅËΠëT)Xõ?“­~ùDM߸Õay‚-:¯^� €dTVÎ&nY]ÍYýàæóÌ^|S<Û‡ •åþ©K€‰¬ÛûúÀ�‚Üì3äúZ¯¥¥\Üù.Y‚èmÃ¥wÁîÇ�1Î-J<\:Ž‘4âJ€WŸï«Ã@…·Àê˜uèÌ)„ öм_‘„Mê¾zŒo»-Þ¡«ÃtÉ ÌÌ\XØ?éßæÛÜ™Ýì|íÚ™'’͛ёհ‡ùþŽ<ç@cò�à¢?¶'?çŸxýš)�´wö±'±w¹©¥z<­)ÍȶÚÐU®$lÏT\g|›}œ)Ž¿`ÀêtøIèêBìmï�K½N6E'ˆöþÄr:#/H¦®.;.ŽÜ»»Ú®#j{ÃÜ3™õõò=tõkÄÏÞ¯“Ò†Á¹Šñê||ù ‰£ci­ pédýoo÷~ÊŠ+ÄîÞf­‰7Û–½—¡‡`km=;Ÿ=Ïl¬Äß/˜"ÐZZ‡.yÃVOËL�þÑ«†–‚§�`kU¥O`m=aCÀ™XN¾~êÀ:÷Àñ‹àNOÂCü]¾KPúÒz½Q<ö9v.ÜôØÒGŠK °m #˜ÂáöS+�àbmx^�a… ‰\÷ÎèM� ±r<‡R‘G_®°áÔËÐgS×Ûò²j£·¯�Þ‹¿Fâuʺ7%I¤´ÿ PK‰q�EøQÐr Querying.gdb/a00000009.gdbtablxUT Â\�TÂ\�Tux õíÑÍ+ÃqÀñÍÓfŒ�Íóãæay:¸p‘‡â$R’B\Ü$–•ƒ#¥ô[Š<\´XRŽ"„#…–r[ù¼Ëáó®Ïëô{èûùÆ›L&³Œ!“(ŒîÀ/ôÜB „)ÁøxwÖàÜIB'ø! ßPo&ažÀez`®Á’,4Á4„à<6aVàì)Bøá¾À—* Ã*Ü€Õ.´Ã<ÃÔ¦ ã°/�—. ‚°9„V˜�Cø„*'®Àš!4Ã,„! 5™ÂìÃ7Ô¹„QØ„W(t ½° g—%´Àœƒ3[èƒ%¸k{�E¸W.'î!3O€ ܃#_肜@  ¸؃(TrX‡G(-â¢`ÞÀ[̆`žÁS"ŒÁ6ëÆ ös—û<â1OhÃ3žÓš¼¤Uä˜Cšr�<ä)—¹ÂMnq‘Å\ã:�¹Á%®Ò,ºnNsŠ3œå'8Iç8O�RÉ$óÿŒû`ú}mmÅß6›´A4Pý.ùRÍÖ³AQÃõ~ˆÎWª¹¨áqJ5ˆi®¨áõö± Ù¨ALsE­ŠZÕU>leLƒ˜æ¢VÅÔqÓŸ ZÓLL³1 Šš+j¸îú4ó‡f£uû¥?4ókóÅýRР®é¯%š«ÛÎGÛ¿mø½|‹ö ›ÜÉ“I&™dþ½)¯)‹žÎ~¾?PK‰q�E¾—{Ÿ+B!Querying.gdb/a0000000a.gdbindexesUT Â\�TÂ\�Tux õcd``àb7†x vbðbpepfaðŠ10ñÿÿŒ@’ˆ1åPK‰q�EÉ^4l> Querying.gdb/a0000000a.gdbtableUT Â\�TÂ\�Tux õ�™]ŒGÀÇw¾³ï;Mš&M“°¥4—kØkš/çõùÒ«íó�Ý„> 1Þ�³‡ÛÝ1³»÷H¨H•‰¨(BE"R?N•è* !Y•x+B¨ðP ¡¾ðñ€ú@)üg½^�}³¾&:%·þÍgþßó÷(Bè.ü¼ ?c¨÷gútçßóÑïâó´øO ¡ Ê®¡ZEËÈ@5ôÊ#4žIWÐZC· ¥¥Ëh •€BéjçA ~Ù€G(}.|0^A µ@ F>ˆN�¡lqx¶�ÊðÌAÐË!šé —Ð ø{µ?Ÿüf¤\˜*±Àõµ ÁÜNÔßïŸ.“�MxnÙØµÞ1Zˆèɪ¿¨­²¦;ï…ðè |ñN =•å£ B™ïŸí¸±ð‡+œº&Ñ–­Ì-í9O¬;öm„æ;/©Nä1÷øÍøSe¶�µªÉ|Š¿z|2B37±M7ñ®¼ÿ«úLŽW÷,—ìÅ›�¹×Ò· 4QïÛ´l»c]ŒØ£Åù%פÄu‰^›C¯¤<è‰/ômG«0ûÉV­}H^ÀRµ5_ÍJú\ã44Ã�›¾B¸™Ð„Ý…3|6âf+¬ÙÞw…K9Ð +ù_NK¹¼Â §":”éJb`_:"AºF:Ÿ&ªŸ<&%Ýõ ½Ï”1ûÕŒôb6õµêÕá¥zƒÂ½ÎÛ¢J¯=ó-ɵ J^' öB#ôH· …dAK)ü¥’ ;ioÓdñÏFð ÿÒíù%Qï‡Q±üJ´üD¸œèK"ÅÃò¡}ùûÐ4~.Zx¼¡§‹8V{ôÇÇ¥ê-+°=¥õ¾*ÕsŠˆ-ažP`?x Ðzû{MðüŸž“²y‡^! Z#u×ÿb¡K~¬?Ä�ž‰=ÒY´J° Ý=ßó\®õIÿ"Bƒë˜GZÍ®QLõ™Þ‚¨»­;ÙY>eÊwÂÃzÔm¸ àq:è^ �V3IÙ?›:`š N¼büvâÀñ+� ¸H!»z:�O�,;ë6ÚûqZ> ԉ䃓¼`ƒ9¶-¥aì)êÅ@ÆÓ"µ-Fd?'-pÆ;v‚s}·.¥³ª¸ºV~´(¥áZ“ø›Œ[Z‰º ‚?ÊË<‡Òš„='µBž•Ï-lëîÛ’ðßAHÄyMÀý•ÄUÌ>¼ÚÜÂn_z—$¿qA 6@Ÿ¬’Ö Vx¸$Ø>ÌÝË… „õ×`ޏÔßK Žvî�tíS.ŒçàKXº†?^΢ÞÈhBVÏÁcЇ_í¦Ðra.óD#ËN^²�•´ô–ªy�tJ|ø–ƒ©ÚY„nDøq× Î<�º�!ïúG¶käraÒ`»óžf°ía»ûÎh×ñ˸ĎGÔ Ø|¸w’p\V.o¼Ôótûþáxw3•åL ®oÔkÆ‚•£Ú•ÑnRY¯‚¡©7|ÁÌX×õ*Ë“ÏC¦õˆ�âÐE yQ5pÂ=hé†O‘}½»µruNt<ÚM¼³E¼zÀ÷â×ɣ߿ÌöÆÎ™v>’¦§ÄODèX�œÅ®!c÷âÖ»\�}ì $üÛQµs¨7Ê^ršD žUà{O¢Þ({mW¤(åynŽuG¡°Éc!¿ß÷ÿë·'YÇY‡0'0À¢†ƒ„M;i'ÄíEø¿¬É?ßÇ}—Å%ô÷ñ?øo\ò?kL±fýÿï]Œ|cÁèG\æD†y¸H¸±%È‚í?Ã|„G¢…Œu–i¯ke�ûáãÞx¤oèx”à¿ñðÿ W3ÍB\ªÐþó¯ß»upð¯‰{ȺWW0ÿüµáWì?úŸžïýÕËÔÙ{GNÿPûÏ/ ÿµxµòLg7§E™ÅûuØ»Äïl¯àó.ž�ÿ5kþý¿ª~qväWsZì%øOÞüoÇñ4²^�a³ôHGñšÀ¬°^ÿ!YžÄXÂýÔï^3&ê~ù÷ÆDm¬×Íñuø�ãz­Íöâ¶ÇI«Ý¬ÃøÏ;4œíÇÿ±Ÿõ9úËÁQ,À˜k³ãøß�33ÌÑü iþ¶—´%9 ó·üöŽøÏ»¥µì¸�”Šì§/ÍÙW̱Ü#³³“+ÎÚJÏ¿&àYž’ÚÛâÿrP*Ì<Òàõ3r‡K;ŽFonnv4±X0æ bDh{¡OÔ(»·güÆóxŒÈpö!éW*Ùk<ŽÙ¥ÂAª�šñ8„À •Y°XÝï°È²a�úæf®ßv¯e¯Í—¬,oÖ Çb·BzF©r�Ù³t=ÖŠßÕg]®EMÕOײSë®§ ­®™³ù"��³ëˆÒQá`õ¹L¥P*Œ0I=Ìé}Lí¶?xpy39دöªéĘOȱ<&=guHª:­T!’zˆ?Ü«Aü„A,L©ºôà%;3¬k&ªy<1‡}D®P:¼Æï:ŠokµOzNé€gQL¨ Ü»ˆÅš¹ªY��¸ž‰‡—“nö²S"×W²`ÐŽH`ñ‰ÔNn/3½&„È yíd±|Þ×0wŒA‹-É‹ðèYb·¹ßKÂhb!—˱8%Çòb�Çg‚AÒ‚�ü-–ñOxôªÔÅß»½±RÍî^¨¸îãð„‚]Ç1ŠÕnÅY™�‰•&ML+ óþ~ æYs´øåF\r»¨nr88-‘H¸oi8;"U]²ÿ s,3^mhöƒ32…½£½•�Ì^~V!u�ÙX]°“ž‘aö1ú>¢À×çzÀrB{pt2ÃÓºâIËí:�zð›imÄ»>éÉíyul�ÒÙõ;S«æl‘HÀç¾}Jfï`uXzNfuÒAöfј´Ûš{è+‰C ÛhlõZmHÛ¹"&]ý÷Åå ù³ý_ÉT2£U�õ�ÞÞA„í?8ïÅ*—´r7Ô’æÔžÓ‰áx\Ž�³ó Jª°±: T�³7! ¤ º›à·+5|�½q-?¬ãrÛïò³©ú& *àŠ„‚¿?.•+dVä2;›÷˜i‘Ÿ9§�]2–h¿ý¼LÒÌË9­˜ ÚŒ©cÇÍFŽ_«Ã} ù|÷{'åvxfÈ*¼w@®:£ÂkbÔiº}wÔ ñ/LwååEc5+XÕ…ú?÷¨„y‰8‚Ð /…BöžfÒ_R(.*•6F�’lßé=‘fŒ§™NËâbÊ[ÝëØ‹Sù/ÊWArÅÖ‚�Xrl¥dŒ&D·Ø¾—tF‹fzÙ,�]œ«eO'{Η_Ԇױ;3*½*³�=‰PÄù�f¶÷ªd²sïí•*.)VÇ¥ªs&´ÞvBj~«éÑ�é17þJs²[{>¡¶yáÖ*˜5k‘øŸvÛÙÈT0#X?)”ª÷ö(l±z¶"œ˜0uø7Û÷÷…¦ßϘ~ëGbCðB¨ã‚š‚oÂHE| çmbýì@Ð>•©Tø×&L Ÿ2«_¢Yá?1Àϲ¦kjžÔ²W"»Êï¤Â,öcó‚÷½ @Bßžù§?¥õTHÖÓ‡¾×êØk�…ñ+q0i"lö̘I2ž�rR$ŒÚ“3p5S51#µì�Àk¥'cÁûÎ ù[#«Cò³¶vRSòDnÏ{žL3ñvLgêüg].3x4Ed®ÆhDŒÏý;FÄ0�ï��Ûœ•™V&¤íöý™ é}�s;dz-«Ž4_“ öC"�pvžÂ²%W˜6I¤Åö½|ù{ͨ´«S»Ö1[Çnª¾9›* O ö+0¦ýYücc ôíûÈa4ÔŸ™>VÃjïÞõ¨coxyŒ\ƒ>ÀÙùîGгv2Ø*X+x±LHi¹}oÍÑŒH«©:n/Ýksîd;Å®Ç5úàÞ¬…Xw¼±W)sTYÙ¼³Û«á׬…ì�l¤¶J3k!!k}%skþ�4^ ku¥wh;àJbk´™! Ö|ŸÈUç@¶LL�„Ò|Q´æëðI¹‚×Õõ^zʘ+­Ë£Ù Q}Æ’ T=¸‡^4\MÉbA^»zq¹> à°&ãpÌN^Pž“*Œ—�PõàÞÍ}�õ-=©›-JOMšê`'5õÞè__ÁÜYãÿíu~+Qw@«s¹b1hõ÷>•ž1Öê@ݺ‡ÿÁ É¿Ñô �²ÂK¢=›Ù‹^þ3%¹+—XK8ß#‚xJ†~ÆV&³Ú#Sœ±5¤X“ûµÆ¡“cq×}2kךØþI/³ ;‘Èš#°xÕ“‰ä€5¥Ÿ_~Jç‰ê]–n>¼ˆÖ’“²/ßþÅ" Çì�üôiŒa(؄ȠµcÁþßtVDý"i1ëœÉ™›³åi°´"!O`¹OfouD‰m•‰½ ôøsfÒb‡´^m¯ëb)Ö)~ÞK>€ˆ-›µàõOðV1áII‡uˆ1Z÷PžŸ€£ûâ’©™»)Di`Oä;d­Àn¼‡M�ÜF.U˜Ðßè²Ô'k:S1�5yFô>(«cw¸=¹]�áÍÂû?{•_iPß;)½x ëüSrˆñÔ˜˜øÅ7ì-Æù”1½VÝ3€Æã o}¦k�fuÜÎT\Mšm? ;:¤x>V¹RËvíxú²ê)îJ ÄN’ùqÇKØq¼`l1„´µ÷¼?j=½çÏÃæSjÙ™ùc/a<4ñÄæ %¦³L@ÞžåwŸjº�jõâÃÚÍ2l”6ãn®„>À].×ò¤ÒG¿&C7Ò`ûN¸!ÔŽc±|,e­¡–�5˜}ãk™äÌyx^¤[„Z„¼}�ŒÿªÕhQññuKm­ìùñð‡ÏZ—!}Âå ,�(í±N3�,ƒz“?ôSšé¤+óC3�µì¶¤IŸž&˜l�æ'/`?Ò”wDÈÛ3þsMÚÉ_î*_ ­eû>è‚.¸|‰µÀò8ȇeå&òeÐ`ûNî~Ngü^6ú õÔ²Û«�¯dÝ�N¬¹Øí·;‚/7Þž„þ yêŸÑQÙ��1çÇYjöz³We{>,°5¼ÌŽÙ]:A.5Yò´[ö €ã¸hXþˆ�jññjjU³W®øV>ʹb׊}÷o<·ŽÇ>¡m]ÊxŽKQv;Ï3ëåËšñó9–ûq„§°Çú鬩  Óè:äðÞð»ëzµšíQ›”‡9kÇ|÷i™ÊFfÊ÷²^Þ¯éS›[·œú ÓœÑbevq…È.G æX|,=/³wP^4ujCZ0�®ØÀwü‚†œ}º±è4³ÌÞLx�tÏyL¨�˱Ø'?sN®°7yDZ0�±`±E¯ñãËá�î(2Тê2Ì£«^ö©ê¬Ò¡2p.XÿíÿjL†ö\)ðaaúýe7ÔÑ>Ÿ™¸ùœ-æ‹ÄKrŒ²&i¢‡¹Éˆ¡VnÊÖ»ƒô±ý®=è]Z§}\¼0Gäöö8ˆ’Ò� ¡1`—wa�ñí®_ëõ(™ŒÇëuûYÃË$ÿ.ä›Q*U¶2©�¡ËE¨ œæí�ÿ¥íÆ�Ò©Ü�^v@f_…óð&ŠoS�±…Øî�/¶ƒÐ`û}xäG´d&,ÜìYé[g·­ä9¹Î¾ kØrÁJVjRŒ€Ì0m�ðD~@ï�Ììg«.ìÊp¿Üȱ�€ Ý#·?/U�9g‘4`¶¶?F´­ ·vçHßtïµ`44Ó:øîÜÆnð|R6ž,âØWÀ>.Ż˄×+ ™¿£S´)3nsÓ‹­l/¯ˆ”' K°1¸P*"Ãü\ĆÝDœÍé¦'jµ²²˜^z3ß½š­vŸ‹~³D¢6Çl7V+|ktL%;‹¡øÖ„Â@}N- Ž‘Ý:zû£Õì¦J÷êè;ö®Í+g¿’Ë.š8FÖ9߇!vþm&Ç©³ÕlçÙëÍ÷=ÉX9Bû™�½ÒÄ89Býq¾kPã<_êÕâÚÎ |>ôbï4�H$Øy ¯¨ÔŠüãàZèA*ÎjøÓ†ÕAA=/K*úÙÎÍÝÏÆ–á”ë ÅOØÖ¾·OuJ›³2«½p‚{‰V\¤õN€ÿÙBÞq4à{,Ö¿3æ\›Cw›vèÑ<Àž­�h._ÍÏ“ˆÞÚ㈵Í{L±Ãlš(lÒæzØV?RÉÎã=‹#þï8š�§[|…žíêù"¯gw[Ù�‚\/J[„ƒ©Y3ðq�ãc'lótba©2¦7Å#µ¯·=ðõÅ`\!6 æûíÏàߟ–(GBdÐ>Ç0¿hX;à�­/ºn¨Ùƒ7ââRœ1š;æœ]'¥vç• M9�±‚&Û{a�ïÓ¹°„º>ïôGCì¤ÈÇuY/ 3+Àiø_eà–Ð$†åF¼³\~C/M®gExÓX{³´3?}iRÐx'Z—)lìd†KChÚb3¬Ž¾Ï¸sÚ¬Óõæ•¥”äZvžÛxiÉ €Yc£÷mƵ·"Q¿‰hMüM3Å¥uýjFÀí çZv§‹sÖ­1Ü6ZØeù\ªÀ"‰¥Öx¿ñ9TÕÝ»yt»‘Xï9•ZËVÏDVx�.�B(¬û ê¬ÊTÌEèÛ3=ËØ­A¾9ê›·ñ´�ÝYúxæîÚÇç ¾%VÊ/­leØÍµƒz7ý9'�ô8çX©Õëýý!K¾h¬øI¿O̹P,Zœtxß ûƒŽFf”�¼·ñÞ,ÓÌ„V¸{¯ŒUmªÙ›]kË‹ €‡Ý Ž9Ôã«GɃ„N�¼‰HjL+\µM·ãÕì¶Ø€J¼Yñ¾Çšï{8›;­T)é}ϧ£Xÿ@:ùµ¼áùx¢†=½Ôêö –Ç“œ]”P8auP¥üJFá²Þ ¾fâ~¯5ï/‚3ÓkÙ‘Ë—Ç«€98˵8$ý«ÌŽd¿h¥ô�»ôá»´§›±êVWË.ιØQøÖ\¼Kbv¡°–B Ãê^Œáe¹ƒJXßxÑ0;™QËÎx~¿Ü·„¬‰ÀšóýãÊ‹2;;[G•½Ã{ääP¡�Kí V7ÜžïO™ «ßh�Úù€ð—…jv啺¶§wˆépػ픶6þ¾56önY®´¶¹Q;ìÖ¤f—ß{¹˜‘ØPk±G&ÕFÒø@Ó 3~u—NÉeVŒ„‡Ì:£�{‰~O³ŒÒ$|á.Mš‘ ùBýDÉÙ,Ö¥4{Î=…µ^µìõB¯Ÿô8SÆCÄÛÇî¢Ôñœœ–/¾^Øóø:Sª­„iêm¾Ú­fõN�&‚Žâá O±-QÑÂE R2þñu•†­ß1H ÷"sS‚jÙE áµ>q°ü|W`~Lêð%”?Ò ¤í|áz#x×åä-"N³‹¾î]ÞÈ)Ü7-¯jŽù\Ž\ˆ8/5BdÐþŒ}¯ÿÚGß…p«tNN¹€Ã_^./…YI„Â7ö¨”Êsv—˜d£´nÂ`ÚâÑþ²�¶’%ý×r³ÐÐ�亴;>–û�P÷‹=òÏ!x6Ì4C½åXçÐÒ2ÿzæZ?Ö%ní¡Dì w‘^°“1Ã0ˆ70âñPÚµÛ,Xï¸Ý‹üúš‡[òQÂÓd¾°´@æË cHÈzqØÞ÷éUI/›Z~~=�¥LßÊ›o^lÍ7; ’ã ÆH "ƒvs—© ¹k­H› h@ê{�¹ž€&�H$b R¤õ•‰ù#d/ãíüía—Å„f‡å¤¡±€å—EYš�Ëç Ýv IGœ½tÜ`�ß¾KÇ# ]á5>Xb®†] º­‘¾øÍW£)(3!3|±Þˆ\ S‡eí5³¨-bñÙãLŒ*”HDœ755jØYÓ\�0D%�ôÆ}ùOtþ+)8rõ–ÄŒg.#î™Dòyœ]XÍ[íQÉÏÚ‚ÿg(8ÐBOË?§SVµ >ùk™�¨´q(Äç&0Êsù–'ðþ»(51rB×&1ÒÏ…ô|Þpžkz€º£«Ÿx@!vßü\j£�Êí­É€O#mHé±ùkyR{DÚS¦žJ @åCé½]© ÀðpÞÚ«´s<Z.Ý –´Ò›Ðþ�h1o‹ì¸õbÓ9?‹MXl Åf{U—ìp`ˆD=&'~OkÙø¬éØY¬e‹úoMw'‘åÁ³eËsHyÁxOUîŸÑzg#¾ür¥{r�ÌI�‡]ÃsÄ;O(¡ ÈÞFjg„Hh1â/Ä´õnÏ}>ƒõÎPnþu bÏG¦v—Î+Mî*÷ Ã5ÔÒÛ:©;¤±»:­ø·¬ÖÇœ@,àZœPÚË4ÖØÈz«ÑÂ$¹´e³ê2ï–˜%¼�‡D†±¦…&z2óü?èó”ùäñ¾G—ÑfEZÑl™B¡˜c†#SòBˆ Ú?`kZ{�.`|ñrpén˜šÝqÙÏ»$xžTî 8–‡¤—döÆþ!~Ã-1mË’DÄÆà)½2êåìòˆG_$@§¤ŽöRGC+Hh X:�?-�Ù~é9~þèQÄbñ€;86uœoƒ(V:bmfÊ� mPO0^é´–XŽÍJêíÀª,ÌïV1Czh+ù&TæíÏîÜ;¯“ky¬ÏN ˜q¹††b\Ëœ‰ ˆßÞk+¿pAvQÊœŠ œ´ÑŠ:F+°¦³ƒ×^ºÌT`E‘Ò–êLÖ…+àZ¾°‘1ö� ]okÏ•ÐuR~m¾‹cX’Öò<¯€¬ÃÝ�]”Ž*«½J•B¦²7H=‰¾I–þûgt€æãTœç’P�â®&o„BØ¢XKÌŽHííɱ¤�(â/”ªsf<¡†2,=ËàÕ½GÛ†Ö¨ÔÕ™äÓî?WïÂ�ãŽÖäP a8„ÈL@ ž€kL‰öäÚµy:¯ÏMÍv*[º3zÌ"Öì“xWÒ™,òwf½#ðo-“v�õÖúK¯”§]wCéwÓÕ+/çÀ³OïØjRŠbœ´ê9{MˆÅ*ÜG›…—m·êZüQRCùbëêœsò±ÝbÜy#D¨ Ü�ñ®9w”ÖkaÃÏÚ»q,ÔîçÕµB8ÄÑð$ŠßJÊIí}d<\Î'tÄq­6sñ96Ôy¾êÙÅ9ˆ¾­Åbö~¹Bjyc’^ô²”C»<=­•á9¾h³11=°x!ŸoyÈÑ;�¤ôÆhm1]Ëð·Þ£¯{,ö&ÜT? @±qþÝÓ 0`k�5Vd¶1´ÑñðQÚÚøÞ}Ü^ߌf²7'7ç ,ŽÈÊóJ…ÜÈ£'dï½=ònù6Ç„ ¬©[OnΟkÍ·€³XMÌÈ—à¾òé?ÆxÿëEÏâhílÆ\™?ê-ò‡áH¬Å–8¤TØ’-gTJ^-ñ] xÿ=ÚT-¸ô?˜Å¦«æZo Ř‹�$¹bZ‹‘zN¸êÇô©bÇÝèÕº´ö´;+ì™Fh¬…»öƒy=®’ÊÉÙ½‘ìX õ ýÂ销ß�©ù64Ø5ÙÙþCr¸"‰í‘*Î*Uú5äïZ}€íD;w­µþ× }�ŸoÓt÷ …ÖÂ�{ì”Êóš#ã_øŠµ_AŒÿš÷ç b³×Hé“'¨t~f=å1ˆµ5G$üîG ˜?Tnå%“†z¦å½Ô·2ãã‡BPy¾ûÃõþ9±B±Ü/u´Úk‡§ÑH �üG øÃ~:·1轞•é�ÊŸLÕ­õkdGÄEXvì�M ¡1`1Ê'ïÒª!4®+1¡‡ZuÃ%¹ {„X5Hqüg\®Äë»OÖE´êZÚô™mõ DE.‰“OÍ‘&�ð�½Jl'L‡æ¤‰ÞFý‚ì†sÜ’WØûùU¯¤âN¢Å|�ùI[(‘‡(¡Ù©KdÑÍ ÚXüêÔ=îÛx÷\®›vo,œèöGI3£åy­°‹%<( ²Åºþ‚ÌØã–èò†?À¼õ¾GÛùŲÝëX)<ÚtO(l)ãÀÖr�£JaoÒ…'t° ¼íz:B� Ìðj›LDq> “þ s�Áåñ9o|ª‚ã {™&íJè¤y cñ> wqÂý«Á¹˜ÇžóYusäg×î �,1í%sô {Š1—ÿîF»`S ý1ÎÉ�(h)*åj4d2ÍIíȸ¡Ó-Ò¥sz0Îg¿ g±©k´®xÔe¥¹�·WÀ¢px�C©–É8ŸÐÀ Ì_Ï»´®v ïq[.C©å wZ‹ˆ®æ‹–ÇÎÚh bio†�õr×í|ƒ».-�OFVª‘ß5�Ô±<À Dü�Çí¤ÏÖèÚRIŒav’6N³ÏœgŠ“Pç„OpõmÐ5pmc5)6„Ìàµâ_JãyzDN¸T éC&o±ùfÇ•8Î=oÈ¡Q¾ÛÎÑî^‹_Î G-µÙΩésšG È›"öŒµ3ʇ _™’)lâ÷ EÆ;…{^�­a«#ŸÌ_�"BE‘»íNK— ÎôtÊ}üãïÛÓ²7åæ½Œ�­øõèf*OÈ嘟ÀÎí)÷„UËÆùçètýèå¨�ªÜvwÙ¦ïº7h,,°Oý•ž”¡Oº›•ƒø÷�· jz«¯×w¶ ¡ù~ÿ'.d÷â(Ö’ø–̺ê,¡i“ ø÷·—>“h÷hKMº¥fwÆ,¨ý�` à´Óì° O™Á9%¡0P¿Ãµ?1Èê¶Üwê‹@™eÓ Ï6fá®—ÃyƒyÆÅê¸Rw˜ j"ue®G÷ãíÿ‚¹‡IÞó¥1¨ýžÿÜøËYb.á j¬öÀí�§·®'0н¯wPF²°ãanBSr½ûðAÎÜ,Ìâˆí‘© ÁÎã½AÒ@Òóìm±Å4ãñ�œ—÷}ZÕ—\™iÍR× ÒäðÑéÙY0’ ÃX7Û1žÍÏe*ì :˜ 8„ª·ÂèX6ïJAÅ@E Rç÷úzÊ"vî¶·½(u<-#O7Ñ#& tûì+Œ¶ü!½Ïœ�ºš:b�Çt¬oçĬæ)�Ùn;;¥£ì¯F€„HmÜ?ŠiÀ¼êŠòªò´ÖY”922 Aœ„Ë·$) “n*¡3Ãųø{ =‹y›�¾ÍCž(¶i%»i9B±Øœh¼AŒs6ÂWB –šïÓ®¾§óÕ€®úÝ{svuh²›xLoi\ý­–†´Ñý`4 .ivúvù·×Ä Í�ÇÍ̓°Òž¨}2«ã2c犴ÓxMŠ~M§J®<÷¬vŽ@®O.ߺÖ�ÑÄb¼Þz¡=�2Ì…ˆuûåu<òýi›TÿÈ#ìÚ&»¨t|Ê¿y–¨T¬�Ëe*Ì£qÐIÈLÛÌf±þÌ¥&ߥêÆT� Š-ônÐì?!‡}ÈQ¥4Ã*ÃÞfïºAš¯yÔ%! ¼­\ËôM*I$' »Ï:Ú;HiÏüÕèá z'éZþíŒa×k8<ìϨ¬($"Èásá,Õê3»óÆò‡‰Úb ÌÐaí½¸¹ß½íŽÔ A ùÀdt,Èññ5LÔXˆt7GNápÝ÷Cz%rž§µD œÑ»�3sf¡ VÀZ�ªä§¡4Ù¸Vðê4oo‘Ò=´ )yè™Ò;=ËŽvÊ튽EVB,˜…OŽŽôTBcÀjßf±† r ›Ï‚=C]bPg�§kZ€‰±Í1ÿDêxNêˆcuC­*ÖY¤Z¼ ­JðÁ¦Ël|O4RO?Y M%ËÊ ̉óç`Be•�Û…‡Ë¢‹Ýj‹×ÆÓ’PNFATBì4.ß½RPJg 1�¼Â㨰'W<ô7�¶–˜½k஺Ç5¥Ý*½†<’S&ænÎ�J (TTHíHnÌPe•á¶³ù=ƒDÂÍÉ›W ¯¡M¿9ïˆpP ì§å€ÆhÔ=à2~×�l>Èö€Çãl­K�´)iÀ .c¦þ'ˆïàÞ’ÆÜXä´é_Ò´1 �·HðXOÚÊN+/A.Ð0@²V¥b ]Ut†vÁ#i=ÈŹöÍ$­NØ5¹ª σàÈÁ„ËËÓ•Ö½�ý…½i÷‚ª&‚’PúJ®znfšÈ‡c¹G~öU�]º"æQ%‰Xәϡ ¿áÚ¹&ä|%´»c㉹š'LìNƒIEë\Ýë%»ñÏW~EGës‹/ƒšQùâ`ÅØãi²‰ù]Ñ:u=Pw ãË5Z¹´ùFG¥n è’¾Áø&WÂcãÙ5£Tа[Ø}FÛH÷òÐ’Ž�ìG.î­KƒÓà±qà±ÙÙ@é6õœWW¾Û‚Åz|�Ž-“‹ ÖýQR^ù½i"‡#”ð-wÛ�–‘ÛüÆE@g¿‹×óêAz³võl†úbß~úA_ß48â8¬7‡gw ò3öÃy¯Òˆ x¨;Þ¥·Ä£û—«æ�ëÐ@æÆX~¹¢¯M˜˜H!ðu·ô‰Kú3zÄ£=•›îÍhÚÉwª½¶<ðÌL™ZZ‘ÞÐÿ€1þë·ôÒz^]îËLAáOî¥4wMCòJ$昑Ûh�èë•<Ý]pGŒ’LWq¥¤<¼zM�}¼Ûž¶ƒÈÁ š�pÔ°E‡Ð@b°Ü1ˆ�Y ­Oà«ö‰ë»ÓÅ[›Ü¸K¶Þ<ì=J¹=õä ù3ü%[²X?y®±³Z%¡fqxr-M¯­{>j� ±‹ómÍ ×ÇídR{),,=NhÂðöxº~ó�€z·Û±©h3vþZsð?0ß#½d*ÎÑC#�¥„ÑÞO|ÕÐÊFS'{%¦ 5¶žpˆÄ>ŠÅBJÝ€†?38wðnhQÐêÍïrz@™SšKÍžª™&5ˆx)Ãõ8¹Ô¤´qtIÜŸc¨¿ý’Î�Ü)©~�™éŽ\7›|ëJ¦É½.öQäJǯ™<ΞD7Üx¼ÇZ=4 ²Wû6L]é݆ö&äu;·<á ò\'1›”Nâë²_¿€ðªEl6¶ù„ ²ó®‡÷§OCì‚·÷N2Y ozsGˆÚjßï°Xáé´äÖæ;Åub¦jŠV‡ãaEùØm°Ø#·±‘}©TQ[Š�,P#Çé8(ïÁböHCêm¹½š@°àN�¥æBž§óF1®@w¸¡ÄSå ¢_^¹}'(c95Tݼ{6=èëž•+¤­>Å>^Ñ ÌFw—¡éÖ‹ 3>þ=W22î• Ì�ÐñbèâH>b®%dîºc…Ÿ`ž×>Ö°þ…ööÛÍ‚¨š‘F”[4‹�­´À ‡p†³JÛׇˆ ^^H~XS:ƒÖ2*3†‚ÁZ’›3¤,�Ćñ¦Þå™ÿÁól÷ZúåN†x¥¢µ¸Gî�‚4óŒ}!fž�'–ÚÕîoî ?«�é\HAƒEC£Õ ˜€c¼hšûFØÛÕÊÀô¡Awƒ__ãZ%{ñz~_ØU°ªbU•J{’û¦ tfu'þùÓŸä-^\sqV‹\ã�êƒ\±€ˆ[FÌ  UBš0˜Ö˜¿£ü ßyÞ{»•_vŸ›‚:±µp´#OäÓq�´OP`'ƒ›ŽåíáuÅÕ¨íeÂ2à¶ �ÇÛy—Ñ>?I][™�‘2 Üw¥ÿIR#Š{<511RjÍ×�PL X¨—ì¯Ç0È–®.‰ZªiD+qÞýS¤^˜�u§ò¼Le‘ìTS¨݃·ÍH{_òU%ÎÐp]On whmzC‹E˃جb3Á�¡� t]†þ�Xì+ SJ1Ïâ“;bPS˵–À` á #²¿8çã�a0�WmðöX}~MÆh=z4îÒÔ5Åk\ìòìU*ÎÀ†7%9|Ýë%V*Ù›6¶•ãiOBP^{pùè}`O¾#Žöç@ž�L7�Ú–¿‹¦ã�Þ…ä•‘�2{;¶+ЄØç¿~/‹�ÐhÌ 'æëW´š,iMè¯a·çÔ§]»G�àE¨•%¡½ëÝfkÂXîLÂVƒª¯'û5y¡õ¥�þž¶)(`âŠ$Ž®ÎòEHÛ+Ê·~I?G^^¹éŸW„¦{n< &ð"O´ó#ŽÍ`•å†}}û>N7ÔÇ�ùTF% âÒ×ÍšerÞÒ.“®RÅp¹¨;È_óhßì;•Ø2…RS^Ž87LÁ½u±¾¡ŠçéB@–õÚ� ž‘ Lxî­nDk×Ç7 ëA<ᔄ½�\^2%œ@fðp`Ϻ'¥}®¬Þ�7ê#QNÞÝæüÚ)M.ïrG]=’ñË.¯eT‰}@ïðæÚåîì§1È#TíÕT=¥yT`¹G…GkO�]·Ão`öšFûJ®/×½§kòQµöÌTå)ÊsÍ+Ïœƒ‡� +)�¨oî�tfr)©¢àErêÎJ󪮜bžƒÖ×–ûHwÌú-Œsßý[ÄüRk†j–ý¼ŠPõƒ[�7ʉJã ÄoÄKlÏ|â�ü»¡N‡VÛ‹hÐÏé“›˜°œÐÇa È£ñyúÃ2Q Öá$�”Ü]1’O‰NËÛ`æ×>¥•@ùÆýøû¹(`£zäY1@rpHbyDj¯½‘h-yý#åE©™µ„�,Ž/ü…þAÒè��©ì”Sæ6[|‡èaI#=ŸjP½ê_:á>ƒ|’Vo]Ž�"W†9¯.ýËŒK•õtü_1Ð×!dįžQ*¼u»­kÞ c1Ĩq¸Ä¨)Ï™¬Þ"tmô‡= >LÑw¹Â¯=Í%N7 ÒØ/p„ó1{©ñ½]6á:ꪠki¢GBãRpœwûÚâ\L#Ä3–�Q³×ܤ2å¬ëÅ<ð Ò~�(¬ t�O@S1ʃ” óé§CÒ¯d†Î+¡ë-Kæû´sÝ÷ò™—oW%ZÛ¬¾Ö¡Ñ¿|Þ®ƒvà¾0å�†‘n }ëÏã[»é#ÖΨ«·§Ñ�[[}D8,4¼�cAÌ®æ'm�ú ß Ð9¤ÖÎ¥ôDŸ|”Õô0°9ŒˆÞoj û§Jx×Ua,õІaûC<¥îtL0[T°åQŠ*Ë ô†­DnÜ\RIÏ8ÚN‚HO:¯aÞ¾wY³µ“0”:s5´u/Všò)<�˜ rcœií¸q«¥Ïß#Ͷ�u¸�†]}º4¯ï8jÝ+p¯Ñê—ô¼…—¤•„•%¢ÎàâË1€'æJð¼�’Ú�3²®„Ä`�@Ny/­qššº¼=q,R7žâîª81o;�Ãf{}“Öå}w|ü}PglKÞœ kHÕ`Ÿ\±M:‡¯—Î�BÚiºôVµ÷ìÓ¬T²^�ê¤ oqXF.jk B M¢PW¸Äkä³ê�æ•�|²³fû7&!ÍåqÍ>‘)Î+UF1?¡Qu–ÿh°ó*Û}דzb�WjäcW‚µ™–¤úÕ¤‰%t=Óð_WèÐÖùùrRj_"¼]_»€|x¸Mc½Lžn’zbYûD£º´ÏñnÖ¥5&¡ÍÔ—�—“ âW¯Ui¾Nc¨ ßôÉ*înƒ’žgÞñý‹µh±Éwcf…Ì+Ö0ìOdP abáyz…3#(æ­€¢*z ÜcQç‹Õ�þåI¸Œ" Ð^G©­Qð@hzWé‡Ñ•œÓÕu!‰¨Í3Ø©À¸<‰˜ó6ùÊÂ6KZ1° P¯ñ:.+zœû8Á£ ©Ã» C_LjŠ{„»Ïƒ´—ÛªÞ:�§¯|ÜY-[lë�AMnr¯-jD ûüD”LÅy„¬“Χë‡ÐÄ5Ìéáæz1š¬o~žµò8"±¶üÈ€= 1ìÕ`¬ø+]�Ô61ð ³> w½ˆ�œƒI«ΤÊg·óÖ¶Q©�Îÿû>–Éùwh7:=d½2Ù#Íw{ôLNÂs•xLoj޶¶t{I#5 *_ înç¹®TùUå£ÎÑÛy€Êåð¬yì}² س2p*€Bïp‹ýtïeiõýˆœ|4P±–˜?’HËÙk+“�sÀüYCÝIèßðÕ€�vP�TRvKg|B"šOM©M…>°½sÌ>–)H C‹%¡m�ÿ' ܳŸÞ�]-“.yʼnHݲÒ7N” äKˆì3÷ TŠ.gò{H!ü’öˆ›}ž&ն䣠¥Ä §q¯5Êag¤&rQ„JÏrâûô' #êê+PÐußœÅQ²ßÅB^3•ê’É !�·ž„ÁØýÇh•’•윿ќˆ\Ç[:_ŽLB=7ö´%¹†öT¬ó®b” ZÆ6ç–ë'sbPÈ‹® zÀ ´fLÞÕ¸"TWr奻i+2•7:]Ôuen.¶\•å˜}!Uœs0YÅMè `Þë,V¬5}¸ .ª L÷ËGÝÁAhMòU{¿üRjgxšh­w#ã7x�Å;ØT™Ð3>6|­g ÌO’7¾ùü�{¥ ðäg�vÐÀM 8ücZqÎ.—÷/<ŒAmc…Oaƒ’ç–`q’ôv¿²âæù˜=á»vopÞ9ŽÅqå,°vx1ô‹½€¤½5û6þ}.íýº=Í*^ºƒBÂ&ûýúaâÄø'è 6²_I�2µô’?4øènIÛÓÄäüFÔÖÑ ¶Áš‹gm÷y™½æ²ºà ¸ò/=c‹C;{3Ñ@‹­7dægô;¬ �N÷×n4 �|ïîžIRüÅãì<¬TØÀ)È»›4Úº#{ÜÕwh5æäוӓˆZRœÒº&É—”@M;:ؽºsEG@ߺ�d<ï}?¥û¨ÎÎíËÎGNw¼:AƒàåíÔ\ÈÇk`”æ#ôíMÁê:{±ÚõÂye< ]›s¾}%\�%IžjÞ2ÊœêJ w¬é Ø+g¦jlxšÝÖPø2³c’¼¨&à ½Rø*.}'ÁZïéëï}�ź–Oo�ôÔ²+)áù¨­?h>²uRSê"±<,=s¢ãÇ!€¬÷Qùqúð*%j¢Ç§ºuzxm4µž€Ëì„×ö°’3RH1¨ÿ•Ü¥j É»=P…ò2 ž¥4À†ƒ+;Oâ0/‘ƒÔæ’QZNðªtn^òcÑß︒ètµýJ#ŠTG7UOjòï H%©lá»A&˜$MÌÿƒazêioj-³·}sÊ 5ù½ô­&!n …Zðz´I¥Oš0˜j¬ô¹ïÐ1^ÐòzJ_WêíÙHj¯LÀð-N(Lú£„º½pNœ õÏ•‚¿ÌÕhhªðÆ“òIòaZ¾íUÚ*�NŠIïñ̢ݴ‰º•êÔ˜€2†+«  ¾*ςؙ(�ã(³¿ÿšÎDǺ__\¼�†ú£‹L·–Iíáê�!жøÒ;´L zÍ/ô¬×#ׯÞÕÙ‚Iò¹Š•ÚÛ:š¬ñ"t†áTŒñ¾hUþ<½”Õ7Q�ª‡#]‡ó‰Å“HÐa©ƒ­ÑBÒÖüÚ`FƒÞ¡R-q¹¿T’yU…— ç‚�ì¸Ù)Y;£‹ãüo|õzãÏ4vçõ„öÝ@é+�r`K𭹜]$¢Â^ ½±CEè½�°¨¦+¼#R¢C²«Q‡{ÿ`d øbþ럪”†ÛUCÐíÿõÚÏó_ »‹Òs<³B³ÈÖ‚+Æ'¤gàÁGÃ*z¡Î÷�ª¬�Ï\«òüïÅ,v`‰/wž�ð¸=INšE|æ&¯�\æ`\öþª2 ì¡Àà�ìþ'%KwBó‘:p}m<“yB> êy×Ñ5´W~³O[ã�è]Tïš™¡¾�rÔI‹Ki“ä’Ôºš\¾n°äcT_ÌjjµBYîrï¶çü ÔÔŸÕ`BxR;';¯4 Ž ik¡9ˆq—�Ò/›?*ºÚp'¸Åz=ˆÌ ¼Âwj°/àˆ}SitBߺ¸á|à'ô)WÀ³ÀÊá±äzƒD:ð$ÿaéE»šRÕ<½OÜÀ’}ø�Ô猖‹Õ�îÕÈ+u%öÙ ¢VñÒì:�UÖ.¦ø& ¾á+‰J™—sW#Æk0ßÍÙwÈ:r¹Ø’|ýn¬¼íMšB¡®š·ómW„¤&µÝô‹By.IE ñD-б3ñ±T¡}wÌ0§ ÒÝ­û-^¤&:;uÕymmh. ­¤ú´4Å‚Ó׃vi &sI¤�žæÎ5¨Á‰Š¯+(HGmÅK9·c`ƒqÅÖbtÒVfwÚPQÒÖóz sú¦ÁòÞwžmvy`™{z¹²?jÒགྷ ˆ.úâØlÏÔ aIêÜõ~ßt´y¯/¢°„Oðæ« “ã'môÆ`–¾7ºH?Xpz§@¦º�&Ìä<Á`ã×i÷öYâÓ¶¡¾tÔé2œ1}…øÝ| |eM®0q„´íçæÏÇvPj}=¾Î»··©ýSÕ›NÀ3ܹ5;(UÙ(¶Ø$ÝK9‡±„D¥7IÌøÓ§Ã^±h>&;gÍIsÎÂÀ9‹ÒÄq)!ê=ÅðX²ƒr“Û6ïõay[qëíºLo…ˆshø’.FŠÁ¹ÿ¸ƒ 9G ƒ ±¹¯l$xEo�t §Ig·¨—齪 �,·Y£Älµ¯5EÞžMKC•ã/"¯mN`+#±–p¾K!#²õªðÜÐ:J¾ñ{Ûá‰ô× ›rgæo5¢¢Ô;õëë \¼Vû¤ rÙÛ”¶€[wÂÁ¸ æºñyíÓ~ËOç3Ôx@Õ%^ЉX€…ꇚÿoi¼ý¨>è¢ÕÓÊPW·úe»¡!;¥z:ĶžcùéE¹ÂøZ ¡é=îUwŽÞê®ÕÓ1Éϰ˜÷xvfe‚|þ@"°<%·{õ$œñ,‘6Û¤Õ1ôÒ>: òN] îhD±÷ë 2 Ž@ ˜í‘1Q–‰ 4лÆ ¡3,c‹÷ÖÒPó±�E@„À×r�\œChhx³Q¿�%òŸŽÒÉGß¶™çùé(v¼h¦`~*œù\: ’Ú!óôž„‡Mø‰�5jSjÛ^úc¬ÐËùUsDð4Ÿz”^´7¡„t'‘°c„ô÷€²:ÂÆÖ��KVi€ ðf'dR·Oi°õú8Á§Õ˜/Ji?‚哾~µ+¯OÜl¦/t‚ÍšD`qø’bk�OšlÝ dO- Îöµ¥4¢$çá¨Y ´óq™ô´ÒƤ�ÚÇN0Hy-þ£«÷QêPn‘Ïô)™å˜GNMáItN¶†hbnjŸ4L›¼ã5u%…W¤N$NM�†ÃyK{o«¢iÒŠ>·)zŸŠÙ¡‚öIŸ(4ßä¼ È!¼ ½Gfåí†7®„*‘¿èipèúüãË©Ahº9u `$ÌZ$ìÜ+³‘j_®ÔUÍšÞIÿª+�\œê¨q-œOCckaêµ ²•°H¾ÁlNÓ± ´ Ç«} SëQŽÌ­ÕMÆÕ#¿‰'Ï»•'àˆ–‡e�CÝÊ£$mVý1ÚŽzÜ�N)%C—óPRafnöØ|·¯§Ù>GÅ9¹êœa^ßZ·ÖðÅ�$ƒ— ûÚÛýÒÑ|zxj4€aƒHnÕ\’ÚY“ž3ºôÄy¥Aü0Ü•M:€)î±à‹ü*ƒg6žob�öÃÝûà«zKBH ÂNÁ¿Ëèª'ÿ¥”ÕŒé¨W=: XB‰˜”°¿zçÜ tÒ�¬œ…özz{··å&¹{4"¿ÉÒé¥Q)\\Æ¡Ó9Ù–Û›4Ù&—7ºÿD×q¯†,wŒ‡¢ÉÒ`Ÿè†ËåI`uN;þÅ‘>ü]¯ðºñ1]!sem6råz:J¨+˜k l„œ7™rÖ­®j@í·\0ZÍÿжn  6¶«¯=o�¬/%®‡˜~ÝÌ”‚6[ÏB\¬úÝOÔ\iqjs# ò ­Áóyä%ÀÓv2ÍW¢M>´Ùº¸?ÿ-‹Õœ;Tí�2êBË �‡ûÑ\~5(í'$fnþ€åíÒÏéÈw¤È;{Ü5 ?I[ʆ¹ …PŸ¬:G»¤7?Ðô®Xýz�¡ÉX¾>’ަ½‚ž’}%"žãûšÇ[Mßd �Ô�0êNæ{j‡^…¿ó7‹°?z·Ü×PÅP̓Ná°Ç¨NU¬Wèûá±@Sè£õ’ox´ºÝl BÎ÷oß">Ÿ+0'©ì³éM!0Hg0D·h/Ù)+§º². Ÿ&O‚È‹ø|Î[¤*Æ�2]6$Òå Åõ¯tî`ñjÓ3§‰´’ã}ã! b/Ž'@§”šÇpL¸dÖºÜ ÈáYoÚLö?ò�ë˜LC®Ñ%©yýä“Y8v&Ç&Œ C÷$øÑ›èî;t˜áZ[ô|*. å•VÝ»ÝOÌ.Œè¨ò+¹ÑÝP}ðPG.Óš®ºËõzpz#êŒÎž^{D<°øày˜v:tþÀ?CPüËÔ7XëºTõl4 Íõõ‘e€ŠDä©{¥BFœBcHÒbë­‰�‹?§ó³)3î}Óá�hàéÃÀÁ^è…ÃpÐI)¼ýf² oÝg·œ¡ÕHÏôXKHU#¿UAúã˜ÍòäE8;9£t0yâGÚlÝÏ{ ¹O„t­&,ûÞÇ»5#ïQ"ôƒu3žZ¶w¸¯\ÊŒk½¨Ú΃Ê÷ÿª²ÕÚ4ä×S”ÑCvó­ÛF{�'Öwu‚ žÿBû“M CeA%h(µËÉ…t#æˆDè#[©Qù!émJ™ÁÀWVƒ{kØéWÕj¯ÝÂ硬;)bO¿ÚËÓûœ#ÀßGŸ–LL/—µ/ä¢é©žšù{«g-1? ’Ùhžò0¸.Ï×ÿò¼¨^ó#ƒ‹#“]®ö¤£¸Å[�Èw{×!©ê‚LeŸ…0ªåÕ;â? %§Ì]JíeÅœkË+³Céh3Áïiz;Y$,@ß=H¡Ò¼ß+3 ,н…ù <¾ßà€{a.·ï,ufÁ`kÑ ØEDG¤ð Ó&K—²|>òs�NS={<íäÑ€b7'ûÜ[P¾×é%…ÔtR›4ØZ˜îÀ4Lpæµ²Äëk ¨­äzó•Ò‰˜úÀf«Ì9iÀ°ým8ì{Lï·�¹ç±r'~ãqÓùä,ŽžvoëMC“­ñ[t•OÛÍúØ›q�¨¼?ºø^IÄt‚S™éì‡àU¾õ{ã_nÐsÞÏg×½Ñä@vÿh !%Ž|5ZfÚ¨rõž(²Ä Ž^t9²z`&8 ÛçÆ„éè:²Q­Åœ7á Ž9Lš±îa›ÿÆXáGé«¶qOë“û°?¾R12¯ÖH/×PzÁ¤š�^®¾mgðŸwPIÏŸ1šY¡îаhšƒôFHèÌ«YjDMµÝΩgÍãbžáÉÞã2u„Ä}•F€åÿ÷ ô‘CEöÍÂkOÒÐâ`uìr5q9…ä…:§’„¶}Â×þ>ílæ–æ»�ԣ͞»�€Ïƒëºè�£�ý¶è[÷a†§£XD'kü–ú¢ªÖPežÛrYŒL–%y „I8˜p6¡�öÆÉþ1}V¢~öÀ£ª­u†å/tU’¬ƒ�”ÖØ9lናzŠß¢¼û›méùî �h¸<#®£œ¸ !ŽÛðv°U)/˜v$Û%Cÿ · ÷HÂòPˆw\: qzRçSAÒ°GöÉT�ª3pé¸ô�’«™o’=¢ÝÉSNna·*cPÃÆdZrÙ©±Áâ ø”'ùR|›ñŒ­�{GéL&ÜïâþšÎ^µÕ…¸ûÍÆ Þ˜øÆbj-Fq„(“À’Šo]ôaÜL«úáÆ‹4¼¸þ¨t‚©ƒ¶Ø+=Z%‡ä•©�¡W�í ëç_Ñõ ó‚Ÿ�ܬEm‘©W+K‰‰àbU»û¼­Leï°EÝìvç!¿Æ_gìñ§Ú2ÐGùƒ]½Øuê÷(Õ¨J>ç;´ª4¥‚º‹åû ™yÄGûìƒÿðåœöëih-8°>ªNÀ ÞÖ~¹p«Òjëü¯äþžŽ!â.�¹g»Å¢Þâë1>ГH•ð47&áIz- Q›ÍÅ0o1ï:iíò3ßÄÊî§x!“&;:‹IZGàz/’˜ÚwÐdûMòúúé×v¯®M·(äê±îÒU†vï·�HÁ�WÈ.i¦œf�4¡³Æ_|LçŽ<[#çrŸ×#¿®è;±yĖЬ;�HUv§•*¥ãY[ÓÙ3ݽÊ* ·ÿ¿éØ%èz[õƒ—Ñh:!o>,›0+”ðÍŽœ9$S¨.q©{ƒq£XH— W¹ßóó+W³×3²îOfM�W³á®=£ï©¯Lè•tü cœ- �›¨G³Ü±/™3–ï^”OÒn�ÓÚ£´ßÊ�Ò~ÎÍ'ÕæDÛhÃÛ÷ÙÇ×¢ÐpAšsÛm2PÏÚò°ò+™½éÁd†A¸õ¥Áwf¢?rîm@eåÃ1™OÕœ²‹[0Hèz‰¨ð=t¾L}¯ûVÀXÊ)�öÎ Þ‡ËykŸLªÂë»Uj—4Ò~iÃ%OÒ'Ëqå!k+j´Øørù  òá@FS&=a+^…º×1½1�\E¯Î𓨘ì{iȯnéV×Mbxù\4a¯\¦0õ�"¡ëyu_þ7í2ÇÜ\ Žœi@Né1s%7I�Ló2¿ùƶ©4n²õÖ„XY'­O’9תÓP[¢«“W:XI¨f4‡#iÃb½ºN`zácú� ?§[×=c‘‡zº=�„Ð�„y$~¯­üŒô¬Ò@ªH ½ô~¼Áíø|÷¨Ð»/Ó�SÿRzSŠF0ƒZ!0^|úÖæïéç–ËÔ÷ª\Z¢QúTCè-@óx|‰‰í”g EžPµÏ¿â½ó¶˜.³+nˆîoHLCÑ9ƒ^�7&4ßU‡[¦ H€´õâ`6ôÓi½¼´ˆð,¿ä35à1ž c‡ÏVXÀ¾¬öÜÚDm¶î' C?Y§e­þjÁê|Eêí󸙑L2¾ k§dØ™³'9}f€¿­¬ù`ägéh*6¤°(øY*¾=X‘HB —³k�ÔÁÁNÆ\28=ÐùÃk§uõrÎóÇS=x×=ó�Ð|>…cö‘âœ&/DG(!åíó¿¦%­­¡êIqMš¾‘w/ŽIÏñ!Q!#—&hÑ D½+õ36t6)­,!1~4eÞWß»;¡ùF)g×a9<ç{Iã'èWh@[¼ƒ¿ C–ŸÌ»¥£êâ–Ô‡1äL\·Áev_ÉMå Y/ñq÷§t½@c}yò"öº‡f"�χ�ˆ•Élþ?®<*Ê+Ë3iy`4i{Μ™žåLœ?ºÛ,=Vµ&s¦�3é˜DÇ왞Óó…”¡BQØ,I˜3=G)”Md•¥Ø‹½Xˆ,…,"‚‚lE�²Fe‘y÷Uõ½¯ æßº�ËûÞ»ïÝõýî6ÒEl¿íi˜o¦�‘\®™yªkćdªl5%‰*ñ¬?cüUr›\Œu¾ÑðfîÚŽÕ•Ì–�ïÉAe‹É“‰³äå-6<©TûÁuÀN7Þ_æÓ°õå=�“W3PAl{t;°Ã2-æí>Ê(O濽¼lÞ¸ñ)|·8�‰Y]Œ ¿‚½Ï€ˆ¼šD…—ˆyæ‘؈ÿÆ&+µ¦±Þ…rŽ78�wÒòt6ÐRsédT‚ɬä*Ÿ›18~€ˆ¾ûÒö¿@�Ý™™ŠkA¥ƒçŸ^!‰,X¼Ï¼¼·¯Ú”²<–xj¯Ä›xZŽtooú…ð{ÉØHè žØÆ÷éØa‘+å ®=J¨V‡þÈ Z‘ΕôªÛÛPctîéÄK³¤'ˆP„þÝO¡r³_õtV çÙQú­ÁLDæl×F.j|øxìv@‹6#´MYð?x<™”—+l”*!™ç[‡óÄoè¥�V=ÉA�í �Ú£Aæo÷§|ؼñå& ¥,„¾ŒÒÔõ’fJ˜§™…¿ûú9Oî£;grQÇÄÆfÑyâxƒûõ1㯴Ñ;]R�ðWtÅ”v)¡­-µæ F,†‘ŠÒ§ÂËÓOégûÔAHÙ@ú‚Þ�àök�)©-ŽK³ÍùOCgÍØá/†­n3²9;a†¿?B¯]G÷�êþÀfS¡&ù©é ¡¿—‡ý·>0ÀþǬ*sé°lhfQjjD)º’?4K0@óøcžQÚ¢Pü�–ç옜©ÌP¬t:—ûƒHø Û‰»\÷œè§^oý†~°Ýv¶$e¾¨ …DÞ¼xöþ;v€L¡»¦/ŒØþ~‰ì¡W øfÞÔ™Í\¤^Î8kª©À–©©ø†±YB5¯À1È+ý@ìçoܘԆ’*ŠÖI,ï)v…Ê×[nß9ܹtfýF ½Ðu‘]‹ý h@ n $ööØ�ʉ±5fXÞ<ìÚ‰º5Íó�ާ %-Ž�¯æÕü¨&zX*â9Rú2$@w)•î”ýÕ>Í»Øë”‹¥™uÉhdsNÛvÆt‘ ¦{éK?o…MؔЭ²ñ,noÒÑ›•úœéò½£áÑtŒñ´ÉÜÄ&ú!’«¡g ó×kœ¾ýmißÕÝ�]nEêŠh}Ö¦‘¤Äbú'?ƒœP­߇žò¿¥%÷yyþø³•”síldÖ’€ c e»l0°ýn¹`î¯ÿ-� £É-Øê7$ÞI €BÊæ�±Î1· ²§t„;eÇ ¹ñ?½N'kêRóc‡D†’¾>Ã"Yn�Hìäêå­‚òxî3ÁVãô¼.iœí¸É«yXÀt=ñyóFÈ/�ÿØ[n'ø#e½GüÛã4pAåÜ媪=¶*kÃ�™œWÒýaû¢[ IŽÇÑ' e|ò\ÀJ.º\0Ùùt&(Åž ‰u¹ÛÁë$T–ßãÅiÆÞu³¥"v%m Ÿ.Î%ìø<©Äù3w¹²øÜÈiäá~_új)�¸:­A½1“ÁÀPä"”òMÍtM»Î�b2ÍRø¿t'77t#s£ MÌuO�àê€%vªð…‚½Çå*•�¿ò;F¥`œ„«òs³)̦_¦f÷¦&=kªE�W6C�´9”î}ÏË]µ…ˆÍ-­ÁèΪùñð·ôÌMCëå3øBMŠ]›��Ɔ§hŸ í„Õ/ÏÞ†ÃÈ�ë~£Ì±K«p´´é¢›Jš Äøo€%ý¹+Ôʨ|·pV¹VcýНðšìþ’>¯+J²òÛPíÓŽsÁrÍà?r>ôÕõ0bûÙ+ÁuÑx ãÝ SEµh#é^ëiÙN‘@ìtDej®Å©ÚÎÙò7ùôƒË¥»g²ÒPNYGû½i#é~+€Ç *RŒËØ )IèN)) õDsaSí�¬f¤¾Ü“–,¡ôˆî„h·¬Ô*‰Pß'‘¿@aEuö-ÞJFKÕ•ySpT âÞù8£d|!À9(@´îßÞ¸O.ÓNC²öÖÍÊ" j��讚€Ã *$ÇUr_†{˜�he‘¹ éï¾t=`db9=ë\��‡ïðøâ}ǽ½|NÉÝ|·r5œ� 2w"æôï<;Úÿ$´¯©s=„ ¦…äÅæè·Xu ³vg_'Çy½Ж^‹Fjn¬w�™Š/rÆ¥ U²6Åç¬ÝÒñ…©ê[õË1åhnj­¸nŒ\Ø…Þýã‰Ï³mûFBeÍÏ?ˆ~QtæFæyõX2jÔÞ/ì5’6Ñ"á/¶ê¤¶YF2ŠNÙ7ýš®ˆ¯¼\ÚºVX�ÒÓîmF�’/dèˆÒSámSƒ$"{�íÓ‚>Ü[õ`¢ýêØ&àrV¿V+Ðð2sÀëêÃûãG4 Æ5mÖȰË$²ÝÇår…ÍeO¨–°£Þ§[ÛV–õj³QçâÄ”º¾Ÿï“:¿-?©`°Äº3„ÀZÉÓPñ¤å…ØÀ =2®.ôÖöÁÄ$ø¶ÆŽ£Ârn+5@ÝY ý£€ÖB}�×s/ëÑÜ�K«}w ä‘®fz›½"#X“vì¡“O©%žæ Õ¢ºÜÕ¸ªÛ’ ��z>�>´±…È'sÙÄ_|¸s˓ҧ±n2+ÿá•P¤ëxRT@˜‚Ör<æÉ¸ã„�·ç+oèëäÂgÃSül—ƒCé+ŽÔÙÑ_îO{òÐqa"%¯¿¶G„U�ó<2? ?�Ð,â¿spˆ�ŽI÷ä›Ú›P§&#¶˜I$ Ïùco?ϯ (o³z„¾ó9ü™.XOHÉŽ­EsY™ãÝí°GX5ö~¦PzÈ}~{ÞÙYT2È<ó_CŸ³*N÷ÐüÒö…¦BÔù(7¸¸ÂÁ決õ².™5yIOTôsº¬�„Ö„†|ÔÓX×›ÐFÄÔ…' ñFÉfD~73º‡9„Éh·¦aµ(:fâ2*mŽH_n5‰Ž@âtTþ=c§V h,ØåNKò]XdïÍPÔÛ—5|˜ñ¡„àeW/?•›B¹ÿ°»ÏÔëS±µá æ÷úzÁªú j’2�n°¢«øI± $†w]>Ì÷/ð¥N¿ÇšœQaVRBa5]¸Ë�º5¯ÿÕeÄ_"¬D.|²£JãéC2¾öv2s݇gVû?tûËÅùøŽ�ðb¤;T¿ÔB&(• ,Ϭ»@~fuïS4ÓOORW³ï,¬#ci¦ºûè¼Ò<ô‘;ãm÷ø²øóûämúŽYo|œÑ\‚4y= Í‚�í”w�ÄòìÜ0‚%qMoÑÇNw~¥¿»¥……t§K¬€Å.{àõ”¿©”Ž âôí��/Ä ÍZÁÒ^³¹¡}¢pÔqd£,^¯7�P‘_9ß@ù¼P¶ë_ÆÝI(#¿ZÍíspÈ4ÃÊ~nQ.wKÔÏW›ÐÜjçÌY`#”ˆdÖ†ÍAÈû€ßþÞrOF˜š¯š–á@ ]‘¿Ò�¤6Ž7¡0c_õ£Z©�€È®¯7ãkŸ;°óõ3w�v•³ Ê+*kѽœõЦb½ˆ¤ÂÝB Ë ‚ò¶ÛGF˜×ä4æe¡OÞèp¥îÖ%|!†œÞ&\ùR™Ðé#lKËmúO˜hÖ 8þ؃¯Óïk�1sÓ‰U¡()þ^Lµ†ˆ§L(úù±“'ý|}÷zçð~� •íô¾œ>5D´´JŸ:>W�ÅeUÁÿ0¶ó ¼$ê"$hÞ“{c‘pr²Õ%]Ç¼Ž™¸–qÔQ“Ðx?,‰Ü*RïEW¥œ1çé¬V!Y"Ø ¨þˆva®ÆeÞСö�ÞùÑD"©|žx÷ÇX<�±…•ÏcÛ^ý&]ØÕvg°kN_Œú›nèàÜÛë ì]}cŽ>Z–ÑõŸXË.ûѵ‹çoO — 6¢¸Ž¡©Ž+†­&d¾Œç6V¬ mÅý2‹F½½_“`¼ÑЀô×gºÂ�!”vJ6Yýlà} iç-YӞ峕éÃÙ&cx|qà²ÁœDÞòwmã2"ë»Là·Æ§‘£Ï·Œ k‹Qjmùæò%¢ÅùR዇ü||*ÎZÒÿó.Ïœ˜rÝÂè)Ô„iu¨cãY”&Î`Lu<äî‹3§|ýõoLíe-×ÜzJ{~uɨcjJÃéòXXTȵ£÷ÕÙB!+PšNc„>Z‹�¹[ŒJOG=L>Ør‹�]ÏS_‘ÌŠÕåÓíuÄœ»©±ô‰ž³Y(³¸÷iP ‰ä€  #S…/å• XŠ zXìË ëIoß¼3·Ø€ é÷c"ÍŠ N‡··¿�x:¡Zo·ï0“¥Wiå–T‘3ÚÜ€Ò+†t.˜‹<Ážãøè*÷“jÛÐ"O°óîv¿E›¨—"’žOÅcW¸úic6ü1}¢Œ'QnÜ{�t¡Ùº×ðAtÈw¡‹Y4SÃs“5¨¸(­?2ÄE$•Jb‡„…l½=}‹§ pl8}TWt3ÙýÅh%¬¾«/Ì`ê $G{D€qȺx€ÂÚôõƒtL41'¢_»ØˆÂbÊz{�V2z›ñVØ‹Vêö+ú/ЊúÚI«‹™ÏAÏ‚:矬¨PêôöÄ•Œ?Û{€ßYSýÞüÞÚ„{õÚ£”[׊‘î§GÿGØ•GEyeyÒ ØIÏÌ™3Ë9ÓÌ™¦'Ëùj/2Étã$9­1QOì¤Ïé™RÊHS€S@l'“3 û"‹Å¾T± Å*;ȦH@ ),,VQe™w_UQõ¾*˜¹�[÷{Ë}÷Þwïïö^ 5:Iþ^w_lN{K¨³„Ý×½#™Nß(,Î [kCЦõùT`.åïxDâe„¬e-¼‘º½H‡?øþûô"éµe†ÚG{*–—Cà€3<’‘~Þô¤`uÆK·ñ�·±�Î2‰T!c¹W6ËÑX̵à²$àú¤A4äRy[ÃïÒ"•dÕÅO–£¥tmùèSÌ�¿ï„ÄÃïX°TT S¬X�þˆÕ�'¶¼«5¯e…N+—Ïp-h´¬Ç2 Ò¦�Ëè¨}¤Í(LxûÙüA x.¤­XÖž>ìþ d€IÄYàÔLÇQÛâ®N×(PßJ–ª8 ¾PàxÄß?Àûœõƒù»UÝ’ú?è{~¥îisKt*‰(Sê7õp¡ˆ¹â}î9€ÐZ(æ Y¬ ŸxÑÑüÐüû=ã5íèbýÅŽªu=i©Ìå¹�ŽŠì¶)'è©KýO:3 4w¼ìÒÓ6´<ØÑü쵞À¹1û¿ô%%p$CÖÏVuÁË•_Óª+ó§µ»ÚÜF4Ü?;|‡+v"ð¦~©×Žö‚!o‚~ã‹¿ÀB¦0´¾¹µÖ[ŸŸ€-Þ¤ Û)¯ôà 0bè1uÊË÷ôi) uç“| ³vù�–º´¤¨7M}½^oˆl^ƒ)æá½BØ�øùËìFØ`ˆ¹�^¶rzs^ZÔF%´£Èg+ q«z‚Îãì;vJ"÷#µ:ì~)˜J¯ÙÜi z0¾ £¿Iƒ‚ */G1Ã59jv-hB¶,ÜÙ·ÿ™žÚŠÅ�ì„Ü ô@÷$áî Éçð„ûM)žæm` ûuw%ùŸžÚë †š–\lN„ÍŒ?‡_ 5;G!@¸ƒÝO5��‡@îéSZø¸)8¬¨i—µKKDjãöó£çm&þn¥‘~ÿ��£/ÉËΟjCºþ­ágó°îbWð—_Jÿ+@âãã{ÊËRºm£ÍaäîSñ.—žŠ‘ÛOŸÞSjPõ •º}NOšýñ™}ÐrÞŠzl~ƒÐ- (w°xUfû¦»C­Ô…µ£ÁbÝRáÉã^zOÙÕ „¾»Üž¬ÜÚÙ¸‹7ÇÔVS521«'ˆ@"€Õ8çÆW­(YrºEn(Jht§y¶Ü™.º¼ØŠÊ²CÛ O®óô=+ñ?å q=6O [x<ö䇴'ÔÔZ›£Ù“ù¸´Ã ‡r6ü?ûŸú�§vµ�7(#t: ‘yž†¤?‰##$cvžÈ¬Ûø5ÐÉMÈ mkkB-=�ª®§ ;�ψñ=öß2éÏ«0À\8‹ÒYÀ%c×cš_ ¤¢ö6µV¹b6Î>Åj¨4YŇ@5Ç$¥õkÔ$%e-c…=Ô5£7á:~ãëãE,=úJ´Jƒ{ 9&Œ6¹9 +9èAfÅjŠÖ¦3‘H,2×ïÙx×@Û}wU± ÛWÚÊK²z5(.¦{6 øs@"ôII gÿ!Z¶`…ÿ+vz40¶²Rƒ*4wWõzâbÃëK‰\â`{©©Û±†p0HèP{íLEQBvKÔ£I«:X.hª�U$¸%ìƒ t OØ ÇY™Õ¥ªæðÄœv´Õ KiБÍ*æqœK¼á�OzŠ�PKÈôýPv€~Óœ½»¥W·iÐVJÊc5°p°�¿vŒ†�Aÿ3úþßè ‰+ó-9›M�(®vÔ°š­#ÎW°ß]*sý? cþŒËß{X"?v¯#¶Û`Äî»ÀõúÁ »`¨+¯±oOµâùÂL–2``;+‘{á5ã¢/¤ßK<$Ž<#b§i¿~Œ�ÛstØvõòúffvßžþ†‘ö LàÄRÌQ©�/͇±È\Â|Æ�ŒûÞ^‰ÎiÊQ×£¥È„õû:0.¹hR„¯c–£•å $«{æë!¼-9·p³&åÍ>¸˜2¹ñ8bgc?S¦µŸLÈ&~ëøãô,�s©ÿγͨªa ¡&YodßÙX�d/§“Э0|‡|æ<ˆ [Þ‹ü0x5K¡# �\Hè”Ê=¤�+L¯/M€|üŠGG¦^=Xk T#…VÛ©JÐAðG uÊž !©h !Y—ìWÓËya #14¬õ?Ò†+�6ny|täÏÆýlñcàÏæG`¼ŽkŸÓÛx!(27u -(:»µñdãs¿½��«}XÛØMðÿ(3Áwtp6º+%nuª{�*¡S=ÒòybáÞ#r_û·!›0‹ë¬,sESØàÖhzWW?£#=$VM=YÑþvìqKåÅڅׇ’žÔå*Q^HAfu”ZŽ „"§g$r™”$Þ°��l¤�Ð*¬;$ò‰næ jM*�‰á„|w/¨E¢»üý$ûµ§ü;Oø^ŸŒ0±|€WéÙôsúŶ¤Êª™tãFzOB„Θ¢Ï¸ÀÖ‘ÔìÓ‹Dì¼Hoâ ˜ýŒžÔéåýüÇY(x|¬q6\Gò<ÇÃ_›I 4“Ä#XÔ}ŸÑ“:þ86;© Å½Ð¤Ž„êH‹5®Øù¸T.—º~& ðgmB6ñ{�E?da¢¶&Æn¶¢­L?B ÷ëUqÕ×Ñrp^AåÉ|Ä—žAìãÂÎ:‘AfŸK¹Æê40>Ùø¨ª¬åÄ®wf�BÜZ—£RO09�Ñgz�È€�×iË,g=œÕo¥ÄT¶¡Á�)ð%¡}…»’±Iâ3{2Èsà3ùö]Z1­öΪ¯¡ŠÜèùåõ)Èú¹q­{XXét Y)¦“Êô4¿gLÕßÔ-4 –DCÉë×Sð¤åÆ0uˆ„ÓÈN}ï¸'>žÞ¬©àï^@Èà_ùà·´™ßÒÓñ¸µ]N»º6W»@,«xÞÏŸß³Rë7}wݕȊå&)b¦âôuh,¢¡l~u Ì|W°�:¥rˆ;Ò¿@¨¦ù�ÎÐ?eÒvÝ�+™×*j[�¡âJÆÐ*Y=!)RÏ�LµÍâ )ˆ°ÍÏé à¥�úâôZ5º|«úY)0Ävµ�ïxHzRâC­ù»‰ÑXÉ ³-u®]ëHîEºù�’ï“b.xìp—c-³#¶»ÅH>‹¹øÿ‰~?¹½Ùwi,U…ZÊ¢†‡ïA~µ›O¼\;RmƲß�h±å�^OÏÞfh»*ªV…f*Öçµ$CŸ|�Ì[ Æì }L´*ÙÀœÜϰ¢HÙ“_)QݪbN …OüÖQ_iÑsX*ñð=g“ c¬Ú0ÿæ÷4²WÿF×ô­E%ÚjÊYÚº ÚFìö cË*sò¿ BW±]駃SÑ1aúr%Zh¬M¼ly>‡óÖg¾§O{K|\úùã½Ì–•Œ±ðýk¼ð�jég]M|aïpRh‘‡HÁ_ÌìqÇZߺåù«U ü†ö3sªîWfv¢¹ÌÐjåOhú‡°ÛêM¦Ñn½ŒÙù@fcÖ^ÒFYXVA{V« )^L¿|8h,Ws-i²¬MD«Æ_þ�°QªªÉ ìFƒQùÙw�›ÒHOHOî„þAì,ò-,ëçïÓÕüW5‰WósThxzMY7@ê\…|‘Ëau¶[&IX– »"NбTCåÈÄã�,T—Þ¿ÙÞóÀÃK´ç ì;›‚FB1gN`wÞ¥ †·4SeUX¾"Ãüøm˜h¿�ŽyùzyÚØÌ@²Hæ Y+z:Cq¡GqóÒ%TÓž ìønØ\pÁZÒïŒD&#× e_¢I¸b¼¯¾=IŸù¤{¥Ù·Ö•hL}5úyTk¹ ù\çO� ‚Ù6[žÐM /`NOúiÛy8Pӳ؞„“+ÚŸöñøbÀ–”p+Á,}Ç Ç@õ:žðb*4ÞІ,ŒêúHa±�Cª—OûBv1�4³Õ=SÇh«qe©O§oU¢Œçy[•}¤2—axNÇN�‘xÛ v²e~…å{êüµ 7"¯®t¥ãU�›,®¾IJ áyÕ˜ÌÈ®"¤¢‹ºÿSàÖœŠ”—“tW�T½Ùõé½c¥ºàMèán­$È�Ÿ™H�×éÏ|Rõ"»$O‰cªfÔ=ä¸q"'’£ãMŸ6Y:«sàŠY:Ÿ§MÃÅ�œÙì8ÒÅwNÔv’20èJeÝ®$žjSfA“†Ð#é°FjdjÕhµ isëÚZ;`{ðD|¾³ ÎÄŽŒ„n‘´ŒÔda™K˜Ê_ÔmtM(QRÏìV]9«Ø‹øåA™—ñôc#“ü·Í¹…J\*º‘t�–6"¡ªòÅ«n´¼5Û©!·"1ãt+o?püÆç»=ãë!uýÜ�Ø(ØÐ‚!¦l*i })öW×?-U¢àù»ñš&ØØ\_èò6(´É^Á<  —ééešl¤_¼®y}>±‘Ü´bFè yls#�Bo=ö­æGJ²fS•(4W2Úû‘Ïpx{ݱOúp³rí€H Xf²«ý̹±ÁÓuÅ5=hAѧ«ƒuì¿5µÅ46S@Èõ©µˆ(Ø­µÿ÷7ôuVœÞ4ö?„N[[ß±x´Í¯ƒ¦[𵜫™©"U–Øwp!OvØ4ô°�L2ÀÂt3�þ-ýùÝÓå+á!*Þ]V]zß§ÜýæÀ…½Ï'#,\ƒ0Wë%¢ªîEÔFSªn ^,!’B7fßöžµkºÃóK-f³Àê6YWÑù@—‰n-JÈ­Ër?‘ºþN";isãbš•SèÁJ‹-¹®S¢áKñôD@{JŽ{�nT6è \ëNäÕ˜Ñ?ÒÆ%m`Œ¶[ƒÊšRG�)¹±Tr±žÌ­êq@:Ñ·tÞÏ­”ÒýD ½^=uµ˜ ðÌ^’®! °N´%§dÌ¢Îá3×€†G§õnÝ@ªÐÐÀrà$qøÌþž>~¾r×CX!ûÙIíŠH ›ú‡jom…¾ÊêA!k+ƒEp�B‘‹1yÒŒnd£÷ɠݨðú4žßÌÅœ!"¯4±ˆ\\ؤv9(#—µÝý h˵à[Zu•^Òv­e¡ŠõUƒ”€PÄ@‘Ìû®¦¨› ˜7¦›æ½ÜÂ4Ø¿&µ²@ƒ=£À'³µjâgŠxÌÛàgÂ9Ý¡@˜ ²Hú s<èMß„¯g iUJ¤Ë‰ŠR‘x\—¹¯ÌÕh´ØÂð¬Ž+(ç©èÄIµnìItG1Znšü)¯�@½0ÜíöÈìVÆ UYÿý7ôÙ°öŽâÎk%ŠÖ”7æ�·Ó>riÉlñ¼Õ*?cŒa5±~z)w)ë§ÆÄžé\¸¡}—‹©é�]üc@kç¾¢ŸüÂ34Å�½¨¢ä^Û 0ºáSîx\à³C\� °êQ¥ÖÐ3XjXšU£™¨®ËÊ¢Oø|}ì!÷”Ø‚áñ©HúW_³œ•4EÞm|wô¬UôÇç�Nª.eÞgä6¸m„hÕ¹í½|zÃÌ&D\½–‚�Óû9c³ Æ7x| Ú¥]$82À2�€Ášôñ›©)5Ä)”è⡠ÍJbã1BSB¯}ü`2Àüz‰·à-S=£9B¡É˜�™ÁúC5<7V9€`º ¹D¶£!£Ll±{à cuµ©Ÿ»ù0û¹ê¢ö{Yc‡#�¥Ók3ÑòåÐì8~�vMG”ç=V¢× íaYÄÍ�çD¬e{, ™®ùŸûšV>Šä+׆ñ¬ŠY¬KË$v#v@IeŠÛž­r)!‚p„ÞŒÕÉÚ—Q/°6»<Ó ¹b±ˆ‹>•úH¿—ØÈ~'¡T—åèºIÈ÷ÞrpˆÐaÖneiä@—µÍG ’�w•@èDÒ]Êdç}lo)kÐaÏšâÍ1÷é«Ašõlÿ5MÇÄ&‘x£ŸyÛTJ�lR¨ï·3£0pw‹àÛið kH…ª:f2´ FÍÆ9ƒf3çéØ(6v\,éýŽu­~þá(¶.òê^ ÜN0:†"±£»Ä_ò½§ÄÖ/Ü.}¹=ÜÝYåýcMÍ]«é¨is¢3˜6 wÏ'ž¶�4ÅÄJQ±¥_YªzÔ“O‹U¨(?¡³;Žè\ž€ƒxž’ÊÙú›�LOÉ„&DŽ4|ïÒhϸâJ-ŽHŸªˆ3.‚¥•§� m«úÊ7äï°*£RækÓPÿJAdšQ6|-9�y’+ÚÊÿ„¿[‡Så´2œ�jXéËV¡–»s/c‰'&ñähÛìlB²j.¯¢wÚÈDøhE» ÝÏiI¾H„‚(•ý�c•¯ss™?ÿ/Ä1Þ.nxÕ­ë@Õ÷jl‹!XbØv:ž¬ñ�˶˜Ãª…4œ„”`Z¹vW®&ç¤ç¡ö”¡ÇÅ1$ð$šãk,3NdÁ´  b†¾�cŸ õf`·8²csª*´ #rãýâ�ÄõS©a×ò‚!ôQøˆ¢Q0›Z‹ÙFŒtmEÀjˆ"¡i—`J��i}Øø9ík¾¬¿“WšÔƒjµs‹*`)€7 §ÝµŒå™è›¿ÁlFýh §;“·‡âTJÔTZ‘Ùn h£\7gãn¶›·t«˜ƒ¬.éAó-5¡øíû?®<*Ê+ËkOûDÔd’éÓÓçLNwæLŸÉ¤'§§Ö¯Št§ÏD“‘IKÚ‰éx2½L*Z Á)4izþh�}-d_«Š}§Xd”UöUe…A”Ýy÷ÕWð½ªOú_î;—W߻ᄏþnzw»‡ñs2²C;ŸÓòK2fq‹ïý’®]\/ò 𸃲ëV<=Œi¹�¾‚åÇ…¯hOØ�¦´£§ðôÍ =¹»‰õª¿Ïrè5¢ ±eýú¢�X4 uHY߉€foV+±0þ8*3•_{ÐâN߆<}åªê‚ƒÅaƆ*{}‡~ [V»—4hÜ3'?Î�¤ Ä™•­ƒ“ O@„wwׇw—ð+zÈ :?($ ³­y�©�¡H„wð:�äÙS¦È:v§XÑîk«§ÍzCnyÀ\A,*ô ¬p3zÈÆê4Ì'¶æ#DÓèNÌæ­_Ðq›©¦–¥Ò~ìfUé‚ÝÈ3 µý+h¥Ê…7ƒCVÐ?ÞÚ¬Æo4{+9cRƒú–‡ª<ÝÈ‘3)©\&•"æg�‰´!0÷ý£[çõ·4(Ù_‘³m€Ðµ�ØæÀIž¹ ˜²Ë- ³‘Ÿ¤Ë€‡c·Kšs‘¶©²4wÝ ~øYzÓä$Ø)vF�Z6·ˆ÷Æ ¢Õÿ'?K«n ßk@5º¶²Šçˆ\2Œà( ø£zlY´÷?ê0ÐO”{@èvÐfÊ�í+�$ „"ôáU•³ÊÂ<+)˜É–'= -áEÛÃwlÄæµÕ…/üBÊVÇUl.’Ç…²Ù�[éü·Þ¥SæÁɽ/_4 � ¿þé‹'dõê/ÀAú’€±ýã÷¨�F ýnî-™”9¡í�X6�òG‘ÈúSÅe%oM!stë»ý4ÎYÁ“‚¼ FÔ>QÙRüD"@ÖfA´^µK²hïsúA}N±qÞAϱï×·UêSú¾­œÉMýTæ°ÌNùÐ2f’z‚ö«*n§å{†jÑKÓø› ðUårlß|�Œg-˜åܸÐeÌÏÝ 3õú„ææ\º%¨sÍFVÄÇ®ª¾V8]´€¼ÝÍG^ }‘ο¯¯tßè¼7~@;]®Í}·V*ÇvÄIg]Æim’±oßú_ht³ ¿ÑÙ‡†f´âwÿN °a ¼ÈŠL tQò»†{Ãæ¿øˆ~Zk†oEÅvhPLe³Úþ‹\Œý’`àK *­´BÎÓŽ æ–_×Xœµ7l”nÌÁ·”‹DR,…§L„�wY:@U‡Ù¢Î޵ðÇUÉhÈorjiÖ@\rl9•Yy �^ý SdòøM Ö9Y‘áU%ÍhêéjÀ4°� DxÅÚ’–÷^°÷"¸3ÐB–¤‰Ðá–�z×דÃf dD¼�9|Šä¼Í±ô�•ŽT³ýÝøö0ÉÇ#[‚£ü¢ôÓ°g‘X E:]T:¹r¸ðg–O' M´¥MÊŠ—þ/Jõ¨&Ã/Ãø@µ´ä¨­ÃÙ‹Î*WÞÉdË2-#"ÚøíY›ëó¯Ö¢¾»†ð¨ÇpZF,y æÉ^P)•üYXB¿þÿEŸRuÊ‹‘‡ê;h!¤÷nÑHªT.&XV—FÏsKö>¥XÚ$Ú*÷ÊÏբ΀ù1ðo¤9;]�Á[ļ¸H0áÛ!:˜ç9�0”‰²WëÒý€!vD"«Ó¬7GµÂ DÜh’É6##FÝ[+6›‘>À»˜p‰I²ÂÑÔäË7)‹ÓÂùÊŸ|C?y~µE©m‰èÖäÀ|þ¤Áˆÿ!?j2"�@*Ô # 8>ã�=éZÌu]ÇhŠé=î?ó7?�‘eý<Þ>YA§Ü-¥Ïe k3»7¼½ ªÌu®Øä!³SÙnaËìÐÙmþ;æQÄ>|¦ú¦ª­è�ö�Ôª+ í{` ›d…%�ÂFwÊR `ÍÞ%>GÇDº»¢óŸÔjPå³Ò§…ð2¡X|ø˜3Ø­|Є¾û1n~�–¶4kâÜ‚#´(»°¾¶jÌ@€ðl$X•8:»ðÞYBçœYÀÇt*(¯§Ôs¥ Åm ¤VC¶ÄØ�ôŸX¾'È×5p‡Ttò ¨m¥,~¼]¿Ø´�x”Ò†Z[®oÝnØGK_3þà/ªWΰ!ë^}ð0Hí[3Y]‰/UgÜHFêÄ€íÈ~rlÄ¢Cv.öŠïN=…@d¿Ôö_N£ocõ ».´< Õé®·”õÁ·•ËÄv  ×Úƒ?s¾§æ„†{jBi‡F‹Ê[Òï>»kÔ÷ráQVßófÃÉ Î„Øþ÷h¥–¥×m{d¡'Ï7žVK™´û¹³£òœ3×(‘Ñâ£þ�åÖôÚç4”çFµ ±Žáµö^âí<ÓÀw¾©¸j®ùgÞû)£©üÑüÄb½ ©ãª¼z‰©ÃåVà•’48œýeš�Ú›š˜Ï­¯×"�Ò´’îE€Ÿ:|ÌñªIÑZ”ýÈvð¾Âœz?£ÃÄCaQC}H;þ,µ¥‡øžRé!Ð…¬±´£ …eU�yü÷ ÝÔØó´Ç« Í&7õÌu+Ð&m]NNËã´'ß eäï0ß‘цSbtÙ̵-–<ª/ë$1 ‰œ9Bü�Ø;W¨ ÝT'‹·{ΓÖ�q¹wæ§[õHmhŽìë †¸D.�öGxÅ¿v¥ÚK$rnËà�OÑÎbga…ïL!*Ž îëî Ö'@�@�> b‘û +X–Ð=/£ïÊÃô:Ÿy˜‘t3¦X2R‰Ddýö›�ù$„¼«€Îãí­3f¸êµÕÚlÑn gK¡ Û�‡Ž«L˜æSÖ0•3t s<ñ3šãâì€ç|¯MÌ6“MJD2¹qpOä•Pi%yÁ F~´ïùƒåk!hÌ{Ϋ²î³ VÓ‡~  #DZ$zTüŽ–ð#Kq7Ëôèžß��­rÀ�e&l†ØL(œóMýÝmãfÈïìÓ¢æÉÎéÀfòŽŠlDè#gGžÒ~ Ñ?òÏ ÅeêÞdì­-Ú »¦n"â"·AË¥£ó{‹Ñð„L»g?•Óèj©e=í Ô0_ñ¸¹Ñ@†òÈ„¯�ÀÇ zÞX0Yòê[Q‘G �-ô-î õСÔÚÛƒùäßÀ³|ÐVqé’³ù‹-æ¼Ø0íÈÒ.[±&vrlA‹žLrê@˜û§p¼zIy…UB´DÂ0=„¬ÂheóÆD‡_�� ôD<¯%.ƒ}ëߨ^5Q‹Ðéh¸o-Esºõå‡XŠŠÚ»RÂk‰ Ä –¢³ΟWRR„))•Ó‘“õ�§�iîI¨f*{}­Ž]$’0V'o„‡Yë!¡±ÌÞÁÒý7ŸÓê«e9;"®?Þ•nO�™X,–‹‘­Bõ­¤'!qܦ__¡M»è)ƒG\®En—wÕ�`¾Ö,à-"d–_8fô»ófÉø©þ˜Ì-Ò¦äjnÁů¯ì >{‹Ò4Bã `<%¦ÿê¬aܯpúÀ¬ÏõíùjÐ12‘Xz08vÒOT(¡³ ÿò£}û¾ù„Κ,6´Fµ¨õY¿Ï0„£à¨Ñ³uväyLÉ úNù s’±=˜ëS¤CcÁAÀUD,ŽdÐ!egs,x˜Óîì§pãš«ý«ÇÓõHÿ¢?}ó&0’â—}|õ¬£·‡šüÙÔK ‡ÐO Ht`pWδicëbC+á» X‹˜Ò-ìÂݱ´˜‰çÿÒ— 0æAsSb ªÊ}y¿¢ŒD.År�pv±Wš÷5Ëw›¤¡ýcÅlblgÎTh~vªŠï,�/5°3â­¡oÆÎÙØ6³£á9â¿ü'Ì+ù=%9 §a¥>?hk¡Ã À Y’ßÞB, ïž#3û¯Ó¶núdÝÝʹL䞘8îSj|Ê%"d§ÀJIIÉŠ%Ü(Wó/i±­.\­ŠìÐ!�­‘ì–à#”b±%3O_Q\!M=Ô…:÷’2tŠ[?Üëñ_ª êXÿ’ráéa[ÅŸ•Žoç¹¥„¾ûc}1Ïšáý$eWfUݯFk^³ƒ^ÀS(‰EÖÇaš’ñ¹µ4\ÈvŸ?džKÆ»ô/­ðßÜV£µ¸Œ°Åbâ&Û$cü6ï):§¡©ÿÿ̰¸õù%î‹ø‡O¯Ìß jS€�Ø“ 'Ë”©‘FUÆ•\¢ùµ¤÷5•kÐÒ²ÇfÙ £$•[“OH¢N–v�TÎqAÂÞ¥ßÄŽÙ¡¬áüh”½ØÐ5QDLs±Tj} Z?�Î9«ÎsãØ@byI1¯ÉKt3eG}ïv¶ ®×O%”‘xc#|†0\Q¹¾}Üñê×¼�1²ŒÌ>a&�åºÕþ¨V-R÷çx/€ð`_ÍÆÊ[“<–!Ò•Ÿšµ{§g�mh<PbWaß"0ÌRÁ¡3Ø€P}}ë<˘£€öÀ3�zϤc½VuãÞÑHž=�Y@ |àøÀ™hcN¤†Óà v€ò =@©1/i+üy&Zðö,W瓜“P"·>¥T©\�]ô”, ±¼ëú YíãØÄh|~Å”=jX‰Ö›F*x)Ì)µŒ)™ó3_¥ßÆô ·ìù Ú¸Qrm&�\c ÃX™æ~š™P@c ®H!êïiC²wª»å‘[#JPG¶ç‘‡VdCawðÌKQàªÖé´~^JKÍÞÖ¢ÌëþzÏ<’˜µŠÚ]u2Ö½q·GHìö¾€¢V;úÛÅWŒltö4 •î ãY°={Ìí”*( àÙ³‹‰{;3mÖ[à»�ЦCEÝ›¡™$Ë#J�­ó×Ñ,Bá°ú•0ó\JDñ|˜mT—ÅofÏ\,¼ft'•ß²ø ÿ\LÍt±u§?[wFSûµÔ­ï ¨N7ºÓ2úÄÙÑAi¡˜�dšÄ¶ü{tØI«›‹™OÅžiÒvóÝ4xÖÄ"FrÄh XØ„ÈÙÙû n-.kl+Z‡–S—}Òˆg �ˆ¬N¨o"—Ôg{¢Ðé¾i6oº©{ >¶J�RÆk¯Tí”2Q¾ÐÙóõ†ˆ¶�ìMû€OkN4*xºÕ9cÜ%#C¼z€�LÓ,0¯Ú :i?Vêÿ$£5ÍŽ&^ØP”XÁ!á/#‘’Y³<!p¶æï`ädªn}~m];ØÒ€ê6R{҂ɹbôæAþ�<”©Ïß²ºVîm%LÛD9¾9%ùU5¨2kèÙj 1P'QØ4®%�M�˜ÑW¤ƒ'a/®ÝŠêÈEa‰5…-‚“)eÐIg•‚íBþ̉uØýp?uÚ=Ú1Ÿ‚-_ä1µ´˜@\tF&8ø*¥g”jm"4òÝ÷÷ísû=�h¾žrs9‹N_^ù³`†íe s�Ϩ8–þÿvåQQ]ižþƒ«¨Y'ÓÓ3�Îäœ9§;�ÄÉ«½j&=�Ml[c&dL§§Ó™‰2"ä°tÚ™œ9l"ÈA@�’EvÙ­…µXTö¥YDd�¹ß}¯¨º¯Šòÿ¡¾ëwß»ïÞo»ß÷ý€jö…\?æ�V—¥aÏáAj`ë9âù*ÌklY›gåÀ�A×—ðCúþ†Öêõ+m3…Ã�¨7º1)3˜Ã¨öv…>+žüWfLðeövv?ãAªjÆ¢KsúrÑDÄŒ*=˜¤h@¤™TX@-—9V¥)̼†W­l7,3¬.ðj6ºXÜL‚¥ØÚîˆO°·çIó;2B0[·½^tÊÌ�ß�Æ•B4ÑÜÝHi±Dºý°‹+g–Y6í†FÌwh�ÁâõÉ ¾Õ’›„ü'ºëæÎÉ,Éw~ä�7.‡jH[V@6ö3Ä�öϹ‰‹j ÍC‘³Å°Qb¡üåO8à+_• 0G*ù_Úa-Ðûô4LÅ jÕZÚ°?¼3àÎ9òötâÀÀMY7fˆt€?ªüŠÖ—-‰úÀ¸Ò*QSâO® Dá¶½Þn§Ü­š²ôMÛ% :ß§•H¤OJ|vJ.*¾>™7âG>‰\.|�­Ð;ìz {üT×N š½íå3¼²ÎË‹‘>ªt&ýZ׌/¹»ÃzÂáW²`m¦Í¢�Q¦Ú÷ïÐO6:¸>¯Ã®A÷³3yO|ˆ`1Ò)¿³zºÕŒ]› -ðcî|óóPÁµ Õ½� ’+d^ânö­0$t3†NïÑ[åAQOÈTjªnö?“¾A0? �“‡ÒÍk ÔO“mð?[ØoéÚ¹ªíòúœM�;Ó¹Np: Öm¯ÒÍz8���Mbñ£ ìèXd÷x¼�6·Õ=]_#xµB¹œ-²â‹‰žÊ@Ëç†TI UÅö¸Oz)’ø-£ já_æü/cŠéèÍ(}UºÚ=”Û2O`’±£ó:¬°ûÂý{|&vcŸÒËÅ/9i–‡WúÜ´û_üŠÎôÍ4d_¨Gþ«1ƒ™s‹ ºÙB<×ÓÖÒZ¥6“l`’¯? �f”¬„¨JrQ�öaYØÁ2ÂrË~ve©¢|‰”Š!Ÿ<@»°ñ>}­ èâYßø®Yh)V° Ø1-Å›7Û û-žA[Kürm.j»·š7K°É°�ö*k¢BÄÚ:€!æñ6^€¢5j*êzE$ª¯l žaQEåŒk)¸»*©Ü'á¦UÓˆUèÁwi‰–œ±”Q“�…üÏ—¯vNìT¹Pj²TÍ SåNÓô^zÍ6BGuç.£«µsw¦X‰&”¢Ã^^Êï•i ŠM^C˜É;{y€k“«±3K:´ÜÑX2Iä5Àó}èæé©ú–©š@6σäåí%M÷.Ÿ½Y‡ª.E,�Hc¼*¤!ìAw·c[$«RÖàît Îÿiª6N‡Ô‚ÓVL°é\Œý^g�£Ö”�BLqK�¶Ò»¸‹}ô¬†;‘êûDÙ1Rñ+XÙA~L+^ACf—s,ÝŒßcÕP2¤EËšÞÓï“=‚=ò¿?à È�x9HÈÝàYñ”ÈhÛ‡ï—2Ú( ŒöKS碵ÙÕì\ýbò]Ž^înÇ-*kÑXˆ7æ£`Ú£ïìT5ÚŸ‹Ô3ã=*�”bù‹œ†t?­tåCK1›¨9X±%ü‘×y«ïád`�Á~JÛ™9;D@üŒQ…X‚|›‚¡>¯ØÙEï¦7{nÖÃó=3ö•µI ÀL,að=¨.<äWB2öàþ¹�Ýo¹^¹'�A•„Ùܹ)ê^1,,Ý|©X.ø©£³—Òû¤³×nE7þŇœ�¡¶¿Ò Dì¸PÒ]¦Aº³³Î’éD")³ƒm¥³�€BZ`äˆÌaþ žý×t˜óaohÉ\½Á>Ì×`X öw²ž>LŒÐÌÔ½K.Å”w-Æ�¨ÑÅ™{¾«`„ f×)’³ýxÏH†˜ž*l†ß¦ýÞѱآ«õTY×µô Ø2�ŒÙ‰uÃqg7¶ÎÄ¢I4Œ0q¼ãsßð`ÙÒKË—"´(11T3\%ŒT ƒë@Ù9Aš0ò#Úx÷úP<¡FtZÙ•êØ‰ÜØä¸T¢ŽØ·RHvA•Ý1cì‰çM+Lù­Ÿn³³ë¹H?£Oæ|í{tÿlÀ�a@U„�ùþ…³›ò[WKÌ@–ºùÖbÌäE1- kµë:Õy jÈ(o�g'³ý3¸=÷´Òm[b–3…?ÿùKбä\AŠ~Cƒª“ç› €Þ%BÁ.¶µ3ö¿Ü,®+ÈŽcloDg.Ç¥wué³òQˆ*!u¸¾¶¿Õö±RB黹ÍoÊó�Á‚ã3. ó�FÃ:âÉÕè5hjqµ¨8IR©Äž­ŸâG <§>›“$ßpÜûýòj/nèPMÐÀâ\|v{w@G«ƒ�B‰É[Oq jÞ¢ë]¦ï –>СàQÍ}d �”‘ïtÄòóô›ÄŸ²ÀñÅô­çøf{…W·(?`C�R/^Ÿèí%¯!C;V-JËDÓØõ¯h!�žpo¥! ïÙ'¾áͽjJÄ0t‡< B#Auî¥ÓLó‹G—5×4(gÒ·WÓKpÒD2f—£¬1ãbðå ±ýU§E´zÑoeyηõ>»½ÞÓ(ä"±½£ÒÕù”¹Û¿�3¼õÞãÝ«¯'ÜÖ à²'��d°á°Ïí¸«u83Bçb©j÷*×ÒȸÛ.ŽVëPØÕ™ËaÀ?ƒL¸ƒtxäÖ”×ã“m¿ú©}tK�þÚ¿GZ ʻܗ1t�|ư°Q²8CÂSmÏ Ž¢ÅÙ½ÒÔ³=7± 1´Ý#øURlÍíW:�Äl”Ö Í`·,?ÅLJ#鬥Z¿)ß�³tµ?;GOžY�]¶I–2�Œ1í¶H¼£oÓjñ|}dtq¤­¶u‡×Ü%hSŒ ‰î$Üo6ÅlÞ›þ?ÝN^wT}ltMX*:Ó‘µ>Ö1Î6 îØï è¤âŠÎ„ª™}hÿÍ.ín@›ï--z�ØÜ ì„X1‹X|¸� ך‡äTc+è4ògÚ\‹XÈHU¥h�6:ï’–°“ÈdÌvcìÑò“™ã®Òñ´ÔÕ…Ÿ ¯AÉkñ7:ÈÒ $2{(|;Å{4B±Áˆ&zÓEÌs}Q©:ÔѰ’NžV(Ùìb’KAÞ À�­§�;óÃtäÞ/|­ýRŽ †êU0�XvåA÷c.– �LÛé�…_Ò§w9µ«r*X‡ {£'ÛaH…"‘ùà�^ Û>[}BïØÅÑg Á ¨­Öoµ¼�(;F Ùöö]”Nü;/ ™u„Oy—“#gÔý:4œQD˜‰%r±4$= „ç|üDÉó ®y9,Y ½)†VƒýFÊFrR;…½{ÀnpùÖÛÕXÖ´SN�[EG¹«Æ?K&óÃΪó4(Äo¦8­™,¶à_Ù¯ô<Š…§ÓIS°Ä)”rl .~ˆ;žÞÆÎCåëóXcŸ ïšl"ÇS,“¼�M#O—ï¾Sº�Þý…‡;×�Ã\+ü'Û«þçJZUܺ4Q” Aù«º(vb Á‘ôôTº8Y™A²T€Nû¥Ãt5þ@|YLHƒ]H¬¨vR™\"pp<åâuÂJ´‡PŸí9F÷ÅŸ˜Kl}¦F!Ç" úq6õ\~h°ÏVkYìma{–¿}�®9¾Ö6Ööxæ*LO^¨ÑßE$—¼âèíä¤ôôvsSîþ=éegi�Á8ÛsÙÿ3�&Qk!L­AYºj• æá˼D=öÕª×AF™RpÀëJãõ®Ž»Þ1��£ÄÒ ‚û�ðØevpIÖÄ`Úª/Âqz›Ž6-éÃâÛ4(ª¹÷úlØ0bðp?†¬ÓƒÎ–«OÈ&– Ìkí;ªGhkTÔÙQ5ŠH¹8Õ ,edí`,‡�}ïìje¥mG §1ëoÑíéR›†zê±]ôدÒPO@S±5øâgXÔ{*�9{Z_h2Èô1˜W½œ¶8 ƒ›Ó±ÅQ˜}=º·žÄäB‰Ã§ÎžNînžá3Bµ½Iº~M÷@š×·¬_OÔ¡†YC´¶ž]uF‚ö±]Žy#�l³Oá>ªÿöî½À'u×uh°Nì ˆÌ¶�ÜO�RZ ´šmþ¯s(,Ç9þOÛ’Î÷ŸÃꣽ 3øc×V,~ÕdBnÖöðô Ûzª.ÌýK7ºªz-p²Øß·MÕ'w¥Õ�@,�íúXé�Qk± 2`ëI /.Ÿïœ^ê¼ÒÑiÕö8×§–ò�w¶Ïõ$�¿ÊþÌÊKýߨÙEr|¾6æØÜô¿–º¤FÁªç×´DéÉqöpw³¿�Ølnõ'ÌùÆk>«¦öÂ$^ø¹vÃ-1/å"ùK¤œêsw·“ð®Déý cžƒ z€žÇÇg²¦!_‹ômS)i8Z ‰�y ªæÞ4G“åõv‘<ï¦íçïÓA¥‰[I•~T:WU¬†÷‘a‰åp; N®JK÷–зžãß1s%çèo‚AoϨ£kÐ`j{ÿ­qR~�-‘CÆÛvz­€¶5H×ÿGßàò��Î&=6ÍnßO-»EL3 C`š}ëérÌÙº"ƒLbè]üà‡ií{/¾o}kß»Iëq Õo\&:ìWzcÂÛ"lH¨ÏѾ‡h�Uys¬k”ùõˆGÓÕ$Ž7ZŸªçBƒR’rÑ“ÂË!Å0�\*�~Úîî,L½)± ~7óòŽÐIþÓÚùµ”: žöI ¯f%Œ”Ùn̾³‚Æ-1¿-ã·žâÝ–ŒgÎMFT¡µËeO{«H ŠÐ¹ ^pŸÐ¸Ò8l �LñÓšTµ(±+4úf‰·I$Ø\?íîi©ðÍö—ú»´‹©¾;W0‹ý¿<ŸÅ3•$ì„åôŽýî®^žÖ„8!۞⇡…xWÎÃ;w:óPÛD|d.LAà˜�…7lŽÒDƒûiÐÁÂÊ¾Ç ç4¨¿n|òQxX¥0;¶Ð](•<ò$w´/_ÉkºD&QH`ïÍFWfÕ’ “•þ:f²ÿ¿i9‘~¡'%>Y‡²æòóVÊ`#0R¹Ìa¯Ë_�Y"´~ªí¥]>F‡Œ†Tq*ý(þzÝ�¯¨ËÈmŸX&Ú±¥Æ!ä­§ø+æš~˜>iù I‘)ú,´Úß8uµŒ¸w 6Yöx;�öð¦j_àw³ÏwSL›V9wS'«45H_ßvÇ¿Œˆ{F&F‡”ÐMÔBÚc’�ö’˜c;¯3ÇÆÓÖ›#))èÉãó1a¥Ä¥ÇV úRy«E^¶¹ÂÔW :i}ó­ü’+ ¦;Tôd#29ë&<©ïMóÒ)¾òºí/wä:CLßÔ’™¥F½]Áéd(nÛÁæ °.À�?Á¬~ÃDk [H»­±o.¯Í1”Œ“¾…b!Úçíá|Ò2ÔBˆfW ?ºÐʹåÚèÕû7k�¿^�?ZBFùc¥ªÉ^5ºZݺÐNž�Q™]þ²‰êfÔVØ’U"üö3Çéc”ßxãY‹iWëššŠXCZ"ÜÄ=ú�§+X�¼H´ÄÖ=6Äú²�im™Qüp¦uN‹ ‹*:g a“ȱ`u hµ¬)F;5@Ýz†XÐ’ßÒµ­¶^„½ï …ìêB¢�$ñöCήÖ,B´½[ÞÐñ‰¾"}OH•>ŽŸN† 9#”:ìñÀ+e%€@¨¶gPåÓ÷p‹OBÓô×5èALÈ|l! ×cwe»£³“ÒÛÉÛ2&JÈÜþùž4*Ê+K2±ž`b4ÉôdzúœIúœÉÉÌé±óµ’“dMŒéè´ ™¤O~ÌL©Õ-'13� ‹`�," ‹ û" " ÅǦ€ˆl¢lJ�EPÙæÝ÷}%õª¾*þÖ}ußûî{ï¾»ßáüÈiã­!º;·áªA¤ Ž+Ÿ.âØ<üäªr÷!¹�–)©r³ºééÛª½8qÕĪ4— �Ú˜:Ÿ8Ñ«/$â´B"áøNþ嘕]†Ø'Ã0o¿7½Ð·ï—•µékPêT`{8L£À…qúZ­>¬úá[vHàöçP1´3{ª%$÷©Ed„^{Z`45œ³ñn �þÖÐ÷Ë"㤳íÞõ˜J¬Ÿ$ô5à ©\Âlù7O¾ °ÕWÀžÅb$‰C´2“r÷qS&ÖÚ'†¯j Hl‘¿w„ú6ÖMFð(3 ®õõç( ³nÜ·°x˜E}­µùÀ`¡qï¨\-¬Ø6b0ÖÉD:/c¡º©¯µ/µvõcó‰­A,QbëÁ×6O¤S…ÐØ:š‡„…,NÝ×Ö"Ý�º ÿ|B…³ÓGjS“T .PÛ‹É*Ë‹f¸ÚÞ®ú ¶ö'väqR¬ºtƒûÆN§`{'ŒWöÏ´pØü8)/:ߢ°â’ž<â-�ˡ˗ð"Pºá±ôwttÜ•™;ɋѢ_…_c·.Î/âõ’{\ç:«§� âÉ %ÝuµtÒFN'³7Y¤-¨›‰Ê#OšT*%AßÄ™d¡�p}™ ¹IB›· «–’VËkQÄ­ÂÞÅ\øp±ÔEÆ �Uíz²‰,>ÆØ¿ÛkbZë­Z舋ébQ]¢–] ó0Œ\AnÆ.ü´«Ý­ÓÔå¨f/[ìaQúrªF§GIý×t†\¢DÈÄÌæ}*®{«µ Ðg²Ž£{�v5¦EÖN•Ì]@�‚cs#4NÞB:åJÐPI¡5ëØ�÷!íLm½ž>𨙆’Û.ÄäS¢ÄY¹i¿Úû˜Eò;_:#ú�3­xtkW›R03YºœMâð· ÏÔ*okF€ü‹n w4ô#y¦-&kšE¥:�¿1‹hù¥Âq§Úç°—ÊʶF€ö7&ò=:F,Ü÷jЩ=*}|1®3‹o9CŒ)_bƒK’!¶§ ØÑôËt6>4©ŠE�ºÖß,ÂÕäùæ}njá·L\uƒ�ÿ@?GsŸœ(š­E‹9Kó™Ä$ˆE9GW•`!nÐJéÚWp÷T[x‹Ö |Wof›�³Bö*w÷õžãÏl¦ôå€qX�,9#gsG»Y¤/ª¼ÓH>FªÄ²ž+xˆ8�Úž¸GÍÛt÷ùËm½Ææ4Û’M¾ÜÐ~µ§·U;;³N[ÿ¾ iÃמ£šÁüâw­¨>¦]ohªšÌ ig1é.ã-x— ˜?âЈõ;Þ²Ó¤ÏuÄUwe¡öµØà“biYºi¯•4ÅýÈ×õÂË™(¢]Ê~ÁÎVÕ öμÎz²*ð‚lÞãyÀSH"P�\âþ´)©³¨'B×§GÉ·:õ´œ5ä>|¸ðŽ0,Ûßõú=´]¥øa€oï¤�/ži¹–F¾[)aœHÖ¤`¼#�ÛŸcùK:°ìB¬_cl#~AR´yiĦ”»ˆ„t±�K·?µ¨Qßq59åd ¯»±z�‹ª“;£OTù£ägžØáX!vå}Ñ&�*(ðŽv&Ë)Å�S3¸wNÊl5½sŽ»[;qÄÒ�J ¥î¦oYÅ�ñ¦ÒÊZx¡\—œJ}‰ÌÉÖ;J ögxÝ•ÎúM®hìÕV°¨=7/54•˜ºÅ å Ÿ¨¼©M2,-ëœft—¿¤båXGAÒíZà—9�BT‰X¶…±BÛHÀö—ýDAÄÖÛ�)­Kz”•¬»�B„ZL\§O½¿·a‰ pÛs€fþó:ò)Õo­703 �f :…l10 ŒVÐùm–!y#ø•daA¦­4Þë/eÑÔÙÜÓÅ)Dš`”b§½êïÝ|„ !t—Ó-z+§ÎÎÏe±(7ª1a.È.w–K_Øí½„Ø>�Ó[ùÙû4�+\¾vþ‹ ƒÃ+“y÷­3_8J­:äùƒÕ^b¸ýuïàƒ{ÿÌÏÑü0âÆ2‹ü‚ºõWιTgñËÜsÎ{£I©H‹'Fm ѽKË9†‚®Åà[zÕ{?¹:‰«`V�\�9âæ#¡²ž}£Ù±�ŽïÈ»¨Y`±&?>à·œ™H¤&¨èÎý_Xý“˜Õoyì„}žê9®Éž)©3ˆž”ÅÌž# dÌ6ŽÏTz3mžÀy„ ˜ßEZ$u^>ç¿ä›P‹ 'ïÌ„PŽ�ëW"Ì¥ÈûdÍÑÒ÷}¸Õÿ¡¶ Íž>]R“(|&“Ýw¶?Åóžô1ô‡<Š�¬E}#ùa“ D´»(_æØí^7̬xþ…`ƒGm`k?²°Ü8u¶ß J5ú–ö'o Ö¯·ìRy÷„2nGÌ¥˜ cã_ÿ:†©7²·=÷¤A¤ �‰žŠ7òEûTø¯æMÏàW;ƼÕÚ�é…k. •´g²¨g®¿c6ž¾8+$ècw.OÔ"ðÅÙž l˵ž´­£ôTWQW-‹Ò¢šz½D"–¸8íQñ:êƒ9�åÓ Pš·ìÐÓ�GÂ+Ú›çXÔ¤Ë½ÄÆsâªL§ؓ‚þ^ê¬eUÙ¶&ígô+š1Õq²»…E�JóâIt£tq"fÆB ög8üG:wQã·<3–ë�r›ÓN�Å‘PF&ÛL(ðµÐc€ñwÖÍ ©ÿEG=tO›X,ÇM¦ûãÈ»£3/Á ÍZƒZ¿?Jsõ³ã*üWºbÈõvÃ)M-ZJnhåK\L5 >Ä,PP!ƒì“ã×rÚÐÙ’hh/bÑ£œž ›„ ã²m7V;Å2û®x[­„2Æö< Àíð ÍÚE™kå™Xâí3äß/ƒy #c^àŠv ;”ÉÛ³ßt—Ò¢žoVO™ÑÈ¢àx¶:›�M‚™$/ê}­òðQYŃöiöømZÛ,ÈÎΙ<‡´—ªÓ}É·¸0ɳ� ‹JÓ63¤}‹6�èVNg,ë‘.£±9/–( ¨<à¶ÆGH@»`6Ò¤_Ц섕¥Á ,wjBýÓa F"e ã¸Ð»ÂÁ(†Ðó6­×—¦Ì…E_eQÀÕä„�XòŽ`qâ%®ª >C†lp:?¦=NÚìêë—§ôh-õécM,±ÚbáMDØ�€ÁV¶Y³4§\È÷­J1ˆ~9Ûœt#> Ÿ²íä3¸œnK›<`¶—Õ®tu�‘¤�ñÀ|;ò³3bÈÅ•‰/™Ü‡îîG„lj2ñv•¥½t%„+ýÙ}‰µ:äwÇïÄR4ñßHdÌ‹ûCë@/¾®±%Û�!¼¦üFö} �]k%ø9hKºÿ(šdÈÉd|\ÐLz«Õßš‘‚€í/»ú š è’ïUõu³(;³g¹8š{GäRþ~’’k ò ë%±&�ÏÀ6 3~l\sÐíƒhvõFCÌ#–K\dÛÖÑ¿D7·¸Üþ]ùè#:p"±­­æÁ%M-¯ÞŽ"’†R!ßJ$ `ªTV>Aï@Ö[4 ‹éX¾À¢È²îŠÔ äA©Vǯñš�¨­¸Ú^6wù×ÕT§ùòZN¦~®Ý»Û77@ôw¥\ù²Ée¹žìa-N’‘ö‰4»ƒûÆ’zËZôˆ�Œ]íöçdf«ëAOŸƒ‡ß |B¡iÌFæÏ, “Aýba@ð@Z ­íhõ'!Î ¯î… W^žžîTW”õ†¯Ðáá+-Ï7Ä&”EëXvfv¤ðɤR©Øé�Õмé�•R Pû+Îü™Ö.ÙñæÒǃU¨'µ·(ËŸs�I¥N»�aæâmC9ƒögùDbQ_n¦îVÍIj[¬lò%1ŒRé1îêÃê#B¡=0‚'Í—צ×è&/ú¥ÀÁ†Ñy‘.Çw¥Ò—»HdŽ®PÍÚZ1J(þìé­:ä¹™Q �íà6‡-úýf苞v-êQØlFi�/y°n�8…R DUòÌUý&ÜšZ==Ÿ¸èŸQPІsO¯ø­�QŠå¦ˆ¡#Màϸö?Švó¥LOÕBFYQK™-ÝI›Z%᭛ä 3o2l5æR'>¥%Ý]cJŸA�ÒbŸööj±D¬dD»Ü…ÓÏÄ)CoºÐÄ� ÖVvFžEk¾ ÁZÀ�/0#{‘d ›Â�ÌšÖ�'îßcªØA»J“–WsZ ¢äÛ¾Ú À†eïgö-3i~µ¿N}J×Î�·†Ö£á*ÿSµ+3Ã(�§Ýݾ;Ù÷B§F˜õP}ߢPYÕÉ“Q·A¼ ˜ÉÓJ©D"‘mÙëéñáX<óø ðnÄŸ–Âæ’äêôh s$o|N4óÚboÿa�b÷GKéô™†…ŒøÖ zt«9¡c V^·ÍûÜ}¯¢Êæ‘ßyD¯ácäñ{ZOXêX8³”€ E=s•€HÆÈ�IÑRkë.Ñ/ШŒ¶–Ö^œÏ\1D¹£ á€NŒ%æ³·Ód0>�75ÿÓ‹V{c4C+Íãzßḧ|: gdXLûBu˜¼›–Oyü¢•ÐŽ’¨m_¾Ö Ê×?èœ%ϦŒÏçøŽUæ'”Àxd¯`‚†fÒÁ² ©ÃÍÃUh%¿œm›ƒãùgø8ºc]\êÇÑ,Cͬ ÏQ^úò¸©›yƒzõËrì¥'@T¬Q@z·;)lju×jŸžïBßÎ’¡À±œÅbÔÄvgFÀ Î Åæ!Z¨À›£Ö¹Tÿ&‡ŸÞ¢¹H]œß\YÄ ´2WÂj�’bdb™ãl…¦^(šúölvp�ñé=n¦;Å™1—³JPL|FZÜ,°hg‰Dº}�ꈗÏFâh›(ЋúÖ»tTβoͣθ\4•0öhîtÒDûTÞtTùÙ”÷…÷í7�ô‰ˆJ/?9±¬G¥¹ÆrÀ#fðUrÜ¥ò†r;Ö.~^§*Ä×ÎGí¹›’²‚sNOD” üÊ‹%¥di2,í¿ºïà.•Ç!wõÑ£öHAÆÚ&Å7˜G¼h;Vñ/ “zÔÆÎ�C í‡ß«=ÔֵЎ©ã<ý.]¸¯h!vµg¾•g”kÈI•réÖ½PWú��Xû‚Ÿ£xÒ/€�òmúù�‹«ìÃŒw¸s~Þ0|âÒ·s¡ vØ/¶¾P Ïi?--L_h¸�¦G³¡ím‰Sü€éjUÿ�µøðuœï�1ÛÂhSâ{ó|Ø@½¨åaÉ•ÞIòN¸€Ö¨>tˆGÉvÊý¼¶óÏ?GíÚÝ œÙ@Ì7šZŠÒCäÓ3èS¬ƒº #mĆ·þ�O>t¦qx­±n< † äÐZl‹«çSýV+€u"È1¯´•}|ùÌRöx ê+ ×.M‘I!‘OógjÒüTXÀ%ÃL5êñ5ü»÷éêŠÝóÃE9íѸñTÍà•cîň §�вž}û¿˜¿;¿ù•Vvâá­úÔ0Z}‰,O‰ 'Ú¯þÖÍê½�j/eõ':)8 :j²Q�¯ß¸P?ŒAÌ0 S³EW9ñz¿è�¯ä4Ÿ­+(,Ì3ˆŠ†/Φ��òí�ùðc«GŒylðGVX4z8y»ª|ÅVt­"6óüò`s²¤ì�âE‹êd€‰s¿êàpó+:˺0ñájôæ þwÿŸ°'Š:ÍNk‡ÐÑÙlvS[ÙJvª’ªÝÙ¹úæÇd'S^5»«ÎXÎá&µ•J‹mè Ц�8³ÙJAEåPΦ¹ZnTäèn ‘CEä’[›Cnå’|ïë_Û¿¯ýÑòg¿Çû}çûÞýNEFˆßÑm šU+ù ççño÷Òiuú™þ©û]™¨e ,>vî¤ÌSÀØ86Æv¼ãÓòŸÿG3bë—& Xºï ªŸ} +€Õ� ^�cþÃÐRëéÚ¦ÙGm&´±XùÜò˜°<"·ƒŠ€@/o>åÀö‹•§ÞÑ$—ú烻Ϛг¶¡ôB’¿ÝÊýøï"sJRÀB¾G?�aÕOÇ�ƒ.ú”¾Ðµa8U2ZU JÊ$?³«™Œwÿ3=´Ës3Ÿ?ªFE¥Ù @¿Œíóõ•òeˆ°}hFL+î}ú:›ºWóK‹ÐHzÉêèà(ñ Ie¶*™v]]d濾÷y×´É$µàáË]j1ä& �H&@ûøÓ)ð Ž÷ÝJ‰�×Ö—cô¨÷lìÑ`;2±T¶ã°Êù#M°œ©)ˆv…–wšTdéÑÅ 3ó}䱓zÊÞùÊkj§ß<çßÚw’®t×q§yÌ\6äÞV]M¾…ß�©@itÀnÀW˜Õ¬¿ï–³0×`h¿† ­cOcûÄw;–ŽüTTñòz‚ã|ÄÍ¿¢#÷‡R&ëÚ/%£™cäÀ#«&.– ¬‰ûÊ{_k:%y“iÓiý“¸¥ú¬h5,=ÿ^7‡0GqÝå RñZ ܇‹å+]Mð™ñJuö„5ÏtfNv²úŒì­C>�|F´ß�]Ý�ѵi3ÒŒ7Ê*L()«!9Š…øußaë·ÌïV"8vº Ó ˆi7BÃéœÈæ|]¦´É‹/†DQxñýydYv^Bö-­,W¦Ô›ŠPí¥&]×}Ø(©H(û1‰4óVúÈ�)|NxS�U'Råð§´˜ò¢ t~¹ 3Æ'ÙZ E¬hvÅÝê@?ÿ“J/¾ÐiÑ+Åù7˜ÎL½es�m=Q)ø&"~Ñ EÍf³6>ƒß.OÚ¯úNåëÐ>‘@lK€GœQDË/W´ÆKS ¨ª)v1¿…¼a ㉟[/•ïQÇž�âǘu(M›X0¨éǶ9xm´–ÔË’òÔ›n öÓ �y®†Ñm;2:Ã/Ì^CC+½÷›F­u»™¿:¬:ªô{ƒ¹š`:׿`«°©lÖH]è|nž iÂʲêaa~ÎDÙš“ú�€îœ©yü™vË^™Mëk6!m’&=ÆLX>f6Û­RÛò5Õ†*èåÎÿ"¥%ðlCìÝÄZ=ŸL¯]­YM*d˜íG”>XƵF\½¾`ÇNW‡ÏËÓŠpbƒ)®Û¨A}ËSËÏ]#YCéÈ�ËP8´ $œ–‰bíZ¯k4ÝŒ(E—ŸGÆ-Ô’5‹E¿8è§ôRžÀÊRÀ搜¿ þ»6�t!ÿc:Xÿ¸‡ ¹sk´6G£G†«:Mlí(Û‘jÛ!e@€¿µ1›¶›u@9íÌt!fÍÜâ–ÅáØôtQcŠ®%öf¨Ó¾¼¼amnçLæÓ÷éhÚÖÜ+Ó`i,ºQV|ͯ)ƒ…}«+cs^G�ÞPð*½ðC}šðÓczÔx3áÒX5»ð‚×^å§V)œ-ý¥ÉSñÈ›¿zÝJ�‘HÑ~…ê»Àï8æ{ò3§£Và�vl©;36X‚4á7η\·²èW£PqO*±ùV©þ%,œTB8§ßç[Ú~¢í¾« »¥Gº¾Ð� ¥£lñW|€°¼êÃX¸ŒkïÄq1�XÒÜÐÒÔÑkB%¢ooè�&©þó¥Ï1|øy•L©óê?$è[zƒúãº2›¦óQHäZL<ùˆX(9t±Ë&äÈ&:Šn¨Qó¤ð”EæœY.aM(’�àã pú>šó�÷玲K!±õÏ£F‡\ éQ çáS!ÜŽ]¾PÕFîý§¹£jÛ@,¸b¥*›-¶'n5%¸K�ZË”=,"ršäUà>^9Üz^©��}'{þlZÔJ‘vñA¸UÕÝK) "œ‡@²ÃºèGå~ü6!ÀrââÆ çpÍ#®›uÚzÌ鈺Luð%|3„Üb+<Ò=`ØOf¦úùoh�ÒÀ¥yËúÊ�Kk^[úí|Øf�§X°ó��Bî/ÇS°–>æhM¶5ÎÅœ,SBóœþ3¹ s JK˜jªÊ%E>Ð5KxTá÷Z×,r¡¯Ã]4çNGgêÑÂjä�Ô«0gèÜö*\ŠgÆþjÆÐ¦Vû �GÜ4}£¶I‡æFKÂãu£¤q’X°ƒTâ:®ò �C#Xns=á« �àôû˜˜X¨,š.JƧíf¹v>HèîG¼•ŠMÁ°„a†.)›9 }]Lߪɱ„¹ÕÂRÔ:¹š~á2±jˆ°NÚl¦—v¬û1ÍêÏhÎ\YÕ– KEqiƼÖxr«<±ëa0Â:†¬°WðI<¸ßî¡_ªò„â ÔÛT™nˆ b9v°ÎÚMgO°œŸ…{RºIy}å™ÏsòPóËõ¹ˆ8«kU,qÛ‹¥Î“$“Ín‡ÿÿ3[÷ÊV9bÚt¦´æì°KIËíÌÅKðºz@QÈ/Õ nb©õG+• ü&�»Zï�Í)Ùq.6­3I�Ššj�ŠØÅÿšu¶ái;“g®sKÆúàŽÜMí)hÆúS½và|¢\Û­Qj¹Ÿ—7O»»Lƒeï-ó*ú€µ…æ'”Õ Ú³Ýcaó<±ˆí¾OŽY6oõL·Ẕ·ŒIiúÅܱ¬Rs. Ÿ°ÜžŽ±.‹H‚¾R#Y˜œËw“þæ÷ô“o˜}Ò–]—�ºMåEº(Øn|d$îÄGüµ2=ÈR;¶O:Èñép°)áqÒ§6§�Ž"¾A¡Dâú;<1o_¿w~@¿þˆ~Fמ6ÅW ¬‚ÐþÎH¢»1h¹Ñ‚›]W@a+Áycb‰lì¯ÍQ|:¶8ûÎÕ4nìœ0ž‡Õ D‚·¿V‚Ïl“†;žIP%ð÷zqË5Ƭ«aèLmPMë9"a™Äm·B€…c…C˜Ú^|�th–¹¸-Dk2"moA]bñM@hÖ¾“ðÀ¼^úÙihÖyL2Ü¡å|áøDôíŠBTqóîHk8Ñòã¾Gåï­òr¨~ ΩÒ8ô�M¯šž4N™�.:5&$Œœ*Ì/I°·Š·—ˆ+§\ÃT–Þ£E5ÝÂZdDA5:W2¶’b•S°M’�6yP†�j:Ìõº'xÿòãȇ‰Ã.Q]K+qÁVªH>Vqgø•�¯6±Y‹6;c\Э�‡Z2õ�ŒU¦!‹ÜÈýü�ñ[‚}lp('>£}†ÎÛËë2˜C/ßÙ°€ ´uÀØt% Žó •Ê>ÕêWùIEšž§Ft.<ß8ñÒWÌ–qP¡öbîþNî«ô!Øtæ×üˆN«šAbá²·CE ²éÑ’#j¯ŽI»¹³“@áñ¯A#âMNµ×rë¢ë{¯—w:%¼®�^™,r!Vw¶ï"šøƒÝTÈžHÛE�ŸÔEO�ÜBúêÇYáÏ,¤«Œ‡"l|”þ¼›J8‘K˜ÚÂç´3ùZ{±áŠ> �™È z¶`!ï2t0ÐÏKé`…!Ž û??ÛJ—E5•<݈E­Ýù·b�´’’mÛ¯TÛªÒr6³ô:~d½\æ}ålO¡ñ¾ŵ< žzÐZÂõw*̼å|#±óÖÄ_æ�2Øõì\¿y­ÝKZ1]Ÿ¶€Ë–Á÷`ß o5ôØâóÙ2Ü{òLLñ1M³&súrkÃ5÷¬k!ÒA˜ßsÓÉy”-¡½LÜ^‹ŸÒ Y³•©å ¡·]’Ú7bÎM©'ã)r'Z‘Oàñã yÜ&†øgÎ$ÿå:ä¢á~Ýé¥ÄT¤‰yR6Bè@¡‡Ê!biuâÁ¼ˆ¤}ÍY«– øÂ´p½Ë²ðÀB"%¬ê︉d3žbÅñ3ý ¥-Þ½™†ÙhUaÕ h ðó-pÝMŽ™¯�׃µøSè ðkš•EôžªÈCæYSvZ;œ2™L Ù~¬á¶êoœî12÷tüìºffHLãíª Êj»W[wŸÈ bÙ;Ðpœj‡Ô�þþJÞŒÀs~ë,ŸÓº² yÅAÐmvª9›|‹Á‚”ôâ-žHÀÎ?1£ oà@èlÏÀ½LtîJ÷Dû="ñIdŒÛ.¿cÖÉ”,E`œµÙ3F3º¡ëÓ�Å5h*g}déŽõ½g;©°ø®ÍžÎ“OÁp]§?Á´¶~NkB+ÃÆÉŒ²´ª{š9ÞLvP"¹ñV(HjŸ� 0ر¦ãAî£/R‚.òVýF>Zèí¯¿ÖH8š@b/ÖgwÁÏœ9+ èÌÚ;3Ý7†µ5¨5¹ë^D=, VÃvîV;�' HÎwJ÷#ZPÍŠŸ›�Ò¢¤Æü«Ãf2`¼#Û¿PõQ°’*-ø˜3ðç{i�¸ò"£¸-ÍÜÌJ‹©# ØZmÆ[Ú•)²›YK!Œþcº¼iüÙõ�0}.êkn¼=l"ÜDÊ0oAgM.O"?r¬(Ô’–³�=f j¯ ‹ì*B©‡D´s�Z~ò ù&I0X’[ñÀ~ì�€¤‹íí¨D½ºÈÐe#LRˆe!w¬RzÉIÛ(>�Ò±‚òF^÷l09mæbº¤”“ø�ƒ½'~øîƒû1Eh\›w žž2÷=r_[ì4§]†pH=þ�.ÏÝ}'o°þi*?ÕrH‰ð¿È\?—{Ëý¨Ç�üÎ!åCûIuçË—_¶ÐTòzIe8ñßÛTˆŸÀi�‰Á#Û¢þœª@Ò?‘ܺð҈̉맞–Âð$bÛžt¯ò{žÈkñ›Û>6ôÏ6³qñr†qÖ„6Œ�+†Rò¸zŠÿp@¡ôT+0{'Æ}’ãýá!¥ŸÂÚ°‚?`ÒÓiÓx²’~E«îµí !µiÔüâüX|] b“…›/–Õç¡�S©/›‹ˆÒõr¬ì�î;Æé Óÿ"×�œTc-*_+º¿P…Jj2ËÓ �’ ÖÛ÷¨ðŒ6�4#8ìðþ �ëïß§×´~íqÚÃH2þŸ°g�jòÊçL.i»ÝÎLçì_žÙÙÕÚuçKò%$ÓžÙ±jë´:ӵݶv;ÛF̶<§ug÷¬ˆ¼ßOyˆ„‡€(/ O�"ÈQÂ[â ²÷w“˜Ü�ÿqøÝüîýîã÷~Ü�¯Î!’)Ë2ÛßSb’J*“Ù(§$Ù²€sÆ?Ña2ñZJCµh9­ëia6Ì"°<‹ç Û®t2`óIŠvÓæ3ŸÄ…ÒÛ�*ÔRx'+6›Ð,ü\Ñ>™ò„\Áa°ŒEé‚ÈØ_»Òä/pèRVߤ UœíZQ `1G¶òý[IÖ¬ ¥¿}õ1�ê?94Ò3³È3dÜMŸT¬X(‚ÌÞSî¦CãFk _F”õýÌâ70KxÙË=þ~½ÔWûâj[Ö8iè"AïÉPPÎòo«uíÒú`Ðà•”Ž¦ ¤™Ñ�¶üPXÉOI 'Ê5šZ'`4—éL€ÎÙ»×U!ÕèiôðL`c]$RÑë‡=1‰!šôžCrÒ.`]»UÉfÖaØÅrNÌUtW|ÊàC-J쪾› s‰\ 抬XvÊVÉx2`óË”@ ý Ã{jʪP^LLp`&l�o�1NcŸ›|)‹ ²H2-xÙ§ß§)uEjÕäl ª{q§Ë�AÔJ–/ú9&_îÇeÆ’ˆ{ÌÍlT§d7+ÆïnNR}ó£¢îA=¯a8¬áZyàb~z��é2GР霿ÃÎî¯l©¾�¾WÏå¢�²ªåŽËã$·DÊ8‘ŸÆ§{ÜDj1H‰-^+ØäØã´Š­ÎiÍóÏGZÍÍNl2^ëô¥ÌÃLЬÞ€¬p%¹ÑRÛ�;k=õ>Õh@_S—®"–=`P“Ç'n²ã¶Ò‘\¶bAÛ?¢ý.¡g c/hQgæÀ\ë¥qÒ—GÀl߯”ÿ W� y[4xs¦ ó0Þ4Õ_xq%ÉOÏ+뉟½h$˜ƉLc)çܤ;î/ng÷»ohÙ)l1ÿÅr†š#n§¦…≠¿Î ¼P,ÇRW½‡¾ Á#úÑÖA-:Û¾’–J(®±!ê [Õ0øV’TÛ©ÿ·mÔm¨J¨ö‹G3YjŸÒbåŠ]пžr÷p=½.,ƒL¸Žb$Û’éÀo}}ÒBsžéÎ>ìML!ªµT,AG¡V»Mã!€- Çm. h¦5aQ1�‰eh5%:×7…È8"¡ØL^Çð'nà]&ƒ,ˆOàEÚï¥ïTÿêX[M”Íß½Ú˜¦Âн@b¬Á¾�Ã�Œ°:럘¬T^fÃ~øý�Ê-jöoŠ×E�“èp¾àïþ¡oJ«Ré›} ùÉ’�޹¨3$ÇÜ[ÂTk5.h*ôf ðÛƒ²ã˜ÂÚ®q@FXhàŠ=ôûº’—Sׇ•ÕÍÓç€U,0¯} ð<åJ„.Û %È(«(+w>ͨ¦Ç†JÂÔzž¡&im,‚XòRÆáS7O¥Çz!ˆM؆ñs]é¡ã9ïWO� ÔóBš/�æ‡ÿÖ‰”]ïuæ7“=ŒÐçï·QÆ·égýqÙjÔuãfÅåb¾a¥‡ÏdP—ß�v€°Rkmã·bZÙ/X½ž¡EmUWƒCßHH;ùãŠÓ¶†oQ Œ“×Z²z}(;Ú›‰2ž�Ík9Æáˆ»«Û O�ãôÓ$0²;øjñÏÓš^j䳕òÇ‹<ÕùÅŽŸèH�‘íUþEv\ÆÕedÂ5ˆoBÌWt@ÝÊ‹„°<ßj4?6ssñ±Žce¡U4ÔàûÞVà@ vÿüºnOñ‹™’gùj4UÙH!2†EŸ¸¹+<ݨ˜YüïÍæó=´ó7RñrÐãr¤z¢*ï^Ö�Ÿ•Ø”y�ʶ"Rþr¹2üñÿ±*«.=‹[V£§±þqÑz)Ÿux_æ®Ä¿£â`E4÷ÿ7ÇUºVWT–¤BQñþõóðá|‰@âðÉI¹ü8”6£Ž™À¬ÊüZH¤þA¿ÚÅk—Qqmh¾� ¤"�Égn” è�a€šÖö¾5A{èH«•€¹Æ¤š$T ZHl�!‡­¥¬5ŽOßR×ì($ïnO6Ö53Ï&nf¤”«QEZo×Ô´ÎTKí—�¦Ý#Ö%´I.j£±;ôQsZÀ¥s·Ú+T¨øÅŠáɔކå3Φ/;é©p÷¢¿”ÀÿîØ¥”Ÿ�Á]U¾µíh^¤v×vªûU@qu{ôÓE^PiýijIxÈдmûçnr™÷Ž#ÄûÂ!H7­öWXùŸQrÌ,ùþ½QuzÞÑ¢•óðÕDMß/÷øË:QE`QÒ�^Ä�/éWöT Éß”ÊÇÃÐhóݺŒ1BD"Æ ’N>ôô’Ÿtã°im{1¢Ü_Òþß…d]ynoÏpfü¾æPu¾Ë”PðQ¾>–À¦˜‹ìì~ïJg êÇ/„v«ÑÆeõíû:Rø�¾ñ'ü¥ OÏïö| ž–ÃøéY—l!c6Ôf#¤ùÙt¦Tßy×ÄK¹=—Uóð… Ÿåísswõ\·h3mB¸.ÐÝžû&{SÇyϵ÷€: D."ǽ'Íý$9 ›/ל¥m¾Óýµé·y i7®w Á…e°HŠ>ÀÔRÎ È\„ávvï iF³0’^q» Í_ÈnÔÝâŒÓçe(˜—9!ö|†€Í¯„ó7éÎÜ…«YÙ—«ÐÓL¿Å€82,”A¦»ÙHOoüù°ÁÅ;iCÀÙÅë¥k†’Úþ¢³>_Â狜?Äê°—§Íè72ÀK‡Wû?Ñç?S¬9W1®FÍÏÆâj#–üÌvcjc'+Ý`VääK_ÚÝWÝ¿Ò�‹²cï4§ôGããXùó­Jÿñ-¨¾Âï©ÅŸ6–&ù6-ÞR!ƒ_cïT7Y—€�D(¹«›)$‘~°UgìXúâúO=_ÐóJRúF—î|@;öžRâë½—–8ì?Š1:ïjlëgÖªµUÉùñ¨¯o>½°Kgl?Ë:`Fèá~L¦à†$Єm/éÓ÷i¶ú §nñÌ€­®TçwUcùÛñ…ÌË˦“žÀ-l5£Y{—æ_/bËË‹g/¡öÆßÀ)f¬Øºl*-õÔŠÖì¢E}_ÕDí`³=�‹‹ll'’ TPÿ܈J’™a9WÆ�óoZâ,»y¿¡$3qi‘‡�uIMP Á�ø2hŠãDZNâC|¯Ïù ¹òKNX@Q‰_5RÅé+Ó[u$,ZÂ�ÈUwÙ /›‰GdÈæT'd7·ZV–ž�¦ú[Š|È4bÌ¢y_È=(¥–ü×êy|ñ Í¿V|®%MT!m§æYz³ŽTŒuyÔÄ!2ǹàŸ;£ á7ÃcÔjÔ ž^¾Iä|FÊüÌèב)•ž ’ËÀQcÉ ë1Nèå¾ÌŽÚ8Lº/FVF*1Ž`®ÿŽÔߦI [ŽÞ¡E!Ã`´_˜_&Jñ)é,ª~ÃbåÚyôÖPÚŒ!¸iÉûðÙW½K{Ñ®F ŽõV¡–.CCv-Q§$¦â?^¶Ëß�[pÉßЫή;78ðc5Jk%ò ¾šŽe' °ÝV¹3€›^°ô+œöpCéêÖÑükH«Z¬&œP rÚw lð¤ö…€u€dbøÛ^@´J3¿‚ïAÒWt¦IWìlqy²žw#uâÞ-àc]$"+eœ#Ô„î)–ŽZ”´0|í®O›-ÏþXßvƒH|)³šŠ¬�ü%0«<ƒ/9E⻋.\ðó+CÃ¥ÄÖJ£�é"r:ˆ%¥ñ‰ÒßJÀ&|»0¢SÁv”Þ4ܤö�Ì)Fyš Ð™ "j¹@®´§ò[™ÑøhËbcÌï /òM9ý6Òû—V.ªQZCýª�²øY§Ã˜Œ¸sÝ�dõŠrp*÷ÞXkO»©B«ÏWÂSKÈm‘H%ŽD{ ‡ÁQ0Њs%þ'}ùÕA­=´`Ð<¾g!bHLŠÒU!_w"KÙ*Œ%z]´o-±'÷V~/-¨?µº€hIb‹½§Î—–(Û‡Fò�Õóâº3bsáãÅ|>ãh Âó�¯3ƒmY=ýÏt·ÛùR}HH¶ž×eˆL_ÕÝLĈœHî­-—o>ÅŸÔô‰“¾åzž®F�Sð±b,p2z‚l¼NÞ|Šƒ_Ó¦\Mis@Ê\9Ò”?�MÊ6š}†2åÒ�ŒÀMÊ›³�æ÷æžLb>=ŸÝš¢&,_èâ‚Y¾°—Ó î9t‹ _Ó/®s2óv[y(J‰ÓÇW«ˆ² Å’À^oW7RARÀ �d^2/{¬ËȪžÚÅ·h×ãÕ¨þæ[*=¯;æöعtBbX>óš¹hŸ×Ž#$©™£À˜�×ìü¦�]ÃNÚ\Ñp9$*9A�æ•FùÃ< D—š«}[kÞKt)|ýß¾Ms”®�ß¼ÑKè�.á^Èã14aY‰3>!ow[|�ÀM¿Æû˜²‡^švÉ/£A[€æïäu,„b�ŽÜ‹i2ªê¶ø¥#Æ c*ú-M#¶úôT¢�v50 D˜¬8À ;¹¬Î$Ú´;â?Â;ø3MѦ—‹KócPwSSWYª”²ö‡=�÷�æVΘ•±w§€ŽÂ?S•|;¿¾�Œ¯ä÷ê™@‚¹Ë‡ž'OʼIH½^Þx½°�‡Þ¦§(ËɿԒ\‰ÔeQºGc¤$ žâc£{¨è)xsÅ®ÎÔêß_ÚÖü³#Ã*ÑÉð�`˜‚/Ä b¾ Õ�FO@[Øm]iô“³Õ³³(¥5|Ú0;î:|pèSÏïÉK£ÐÐÆè;ñÎüC MàW•øNÞ®@íê‹ñ3°A|–ÔxûÎÿÂÙ o<ÅO1îùoè¸îáË‘ƒþµY¨9übÒ�0…PÈðæ¤]kï¬^^é<->ÔÄži›H©A�u!Õ€I$³Ì+æˆ dF©¥~Ë/ 8õwôs^θ”4§EË}µ×ò) u}I;Ñ J[Õý…–*�rz•73|Â{®Ô ’Ñô+}Sc¤‚„ye¯7ÞBowWÛîC2Æ„Ôܱ47�ll,nó­D†Á©â¢)r‘."GˆÐµyLÝø˜ ¾Ýç¯vT±êÔèú M…¨&L!O3@ÿTç#Ĩ°%í‘O¥Ù28ÝPKj}Ïù«jP[}vÜø}¸Í"±€qþ K§EoskÈÓÖlÇhVwÓ…®µ?[»^‰ºnåEuÞ'·¿2{bo“Ë8k&°Í¸ûohRWT‘¯F�ÓõÕ£pA$|‰„wXæEwD€ÿZ]ÞJNjk´aΧ²u¯Ì–V�‘J™b�3¾g�ƒA]¹k…›S‹7¾ {ä…Lw>iª@ÅW} †Œ¼Iy¼®nÐ(ŽKP¸ù ÇèRqQyï…£´§¥úÔ~à0BF"~ýÀ®r…—;>B£e܋à È(«æ3JN&Yݽ¹ôê›ò4¼¬ºˆ(‹ùæö}¤á±«§·%)³|*Ï\…˼ÓOÒBî'æT¢BCLÄÙ>²ÓB†q6v)0Uåîô¦õÐl×7´ÁlÁpÙÿLs-Ï:×KX­Ô…q÷7�I`•. ëå'Ó‡�S•;U‰j&Ã|—zÆH9<,NAßM…lI$À-,Tgh§rpÏx¾*³ÍN§ŽÜ‚‹$ƪï€ôÓàlâM•:ü¦ìÔi´u¡öΓ±œG˜ DtÔEvb!u|O¦ðv'Éô ÖöÓëïCfÉ¿">ÿJðH24NÕ‡´Œ‘>†u2>zrY©ø=*áóߢß|·_@]Ê­¬ÿ'ìɃ¢¼òÄTx hÆd·j³S»Uîîì&3“dúî&“š”š¨It´ÔÔlö¨MGÛÈ‚�âHÂÔÔŠrJ#·ÍÝ€4 ‡Ð ÐÍ! —(‡€ŠÍ%§ �´ ìû½þšî÷uÓÿñ{ýûÞ÷ûÞûÝšž4Lw·Â‹‹Å‘Ë>’¯ÍÔž˜ïÀ,� ‘%vWFèñu¼¹¼x¯y”Ä]y.ÇNK½½¬[rÍÝajIùtýØå[ Êù%hh>8²�q1#–l#SÆŒ‡“¬a�.`š…ï£SÕ*^Ì%²µèŠ¢¹¥ÿ&ùΘÖ;>728_£ìco޽ïý#.UÒ�Äó b34Ë7PQUbêBÃ(Iãq¶‘1|¶Å+Y`êëAxÖpáº×¡•qXKï›{ÐÜ@8>Ö‘�>ó½À�½c¾ëfçßy‹1öbJLÈ[V–4jÑÚÝ+†äz#ëç ]öBû)›*(�oü hk¢ ¥]®WJs5AéEHý¼»ø0Ðf¡.)À¹ªBgÇc‹=z‘9ïñð“íÚíc™À±hRfÙ“Êô Ïug†µöjQfý´:H;JºÏàO¸Ûû;?_?6 ànú ÿí}ùÊf‡{³ä(j ymJC 9ŸçtÐ […¾VV!À˜Ízáמff¾šúý ?/\Æ«´µö|å("âýãzžø‡ë¼k׺“€­×À/ì‹È¸OèÁŽÞE7gU¨WÙÓR6JZ±ãW05H´((€ÿ[ÐýŽÎâÉ ¬êª+U!u¿¦¡O ò+†LÝήÃRwªnG²YÊ£œCK8u׫¨&º´z¿„9>�÷ޱÿ,¤Ë¾—1i¯G/±ØñËßÐŒ©Zn(Â"âÙ•‘{=€“ )d;HäÀß™ƒÆº‚œMÅÜ4óÓeY˜OPßU¡W Óò¦ÂíArìsóÄf²1ÚcÁì¹›õÑxŸ•ö‘Ù9–:·�°™YlDïJBq'±éâÉn6D Í‹YžÛ„UýÂBpêhkk¹F˜’˜/0—̱âbÊ©üñ_hý®1sA“™¦E1Ym¡…€Ìs0s92‹¶®vÙ[4~k÷÷é™W3³CêÚz-ªNˆ^yX@tQHüÜÃÝX)Ëvûˆ…›¯<ú‚Çç*uÙƒ!HÖ8?‘ wc�–©ž§¥¾¾RÚãG` 9vb‰r$†&ÇÀjSNÓ¤¥uëkzs`·Ö¨öɼ=m¨»¸ñnábè>¥“© Š[÷¯kÐ``Y¹>. ¸]Þ9äåéû=¨‚þ¦zW¶`ß;Eg¿ÿ?Ú}òhvf47IƒêÎ�-_ÍšÇá ·í—yŸa¬ €7~D>~De:ƒ™Žm̘/GE/›ã³ˆ*æA®ƒç &‘QÈu6K-.[œFí×4¾ W±ÚΨ.>=ZžÂ@(qèTxÀøúghgð€vX72‹t%¿Ë0z/tHö3ä¡°x?€LiBøÚýò:Iq".²6pA‹zJB29EBŽË~™' Äót“YÑSdï,…QtaB{bUÔ‹‹UH=¿š¨HN/’9;°Yè&ó–2£NY&—Èn°REø€–'#UÙ}Éã*¤�U]šN%ÝE%"'̨Y ¶äÿäýóÑvfùùæÉæ{5(´/0³AÎ$‡ùDÇty殯ßü ÿzÎ�¶‹ÄötvåaåýÞ¼"Pq`~íNc—x8¬»ˆ±T,`�}Flªµ7) ù™]ÍC-Žiò‰â¸âNãŠ9Û€š¦bSVjYÀPßd‡_qh‰Ú)WÖŽõjPÙrky2�R‚ TÇÃÖþUÙx¿»05¦¿¡ ¤‡%Ñ­Iš;޽©�/v6Ö90ŠÉg=oW#P†Æ‡ßqpx•B ŽÒùÜî;·n:]_z*O‚Û c›¿vw“ž¶zscÞü¯P–åJÓr¨éÙÒP®)f2§p¸\±pû~©VõVÖ}€¦€.Fõc"}YÛû¦Ú"zU¨1N>˜¯ – ŒôØ‹™ ÊûºÑÉu­ò*Fâ,7Žò0'}¥R~> +jSýaá ¢‹ˆyÂíF]ä ÔÏ[fåЂö�SúÇ4Gè¯)©®B¡S+�ò/ X=u!Ù]ÀÁ¦€À®ú ‰·G$´8õaÔ³œ»-Žk%Cò§ „úŠy[¿ñûNÊ$쳿ÀÊ€¶þ¡;m¤^êl˜ÀúvÒhÛâ|1F11Ñ1¾³V>{®Ý L)¤’ý=¦¯[7ü¸±Vƒ:î?¾OtU>tÕ“6ÒÌ>Íßþ”šä_kê͞Ɩêð@âXlŸO,IOãýø×ìW°ýGä»Ó¯œug²ÅqèFÔýG1À%¸B1Ϩ¥Ö `öã>Oxô'­z=Uiˆ@­}3·?:¸uÆÔ¦S½$´ÏëV&"‡ÝÄ&†œ�oW¥ ²þò’GÑÀ†Á¹µõóS§°Ì„þ“tîÏÂõu¿øW¬ Ô�iíóõÈ�}e"ÐñEVû³ôȉ̻›FñÅTZÛ@JJa¥: µ�פ*¢ÓåsEð�|H¯vG{þz#ž70—vy-¬å)Õ�UhV¢ÏºDb àò:"õ‘ž”yJ­B vmàâÿð=0;þzytzL2 ÷-¥^2º\9;IÓ£n2FY’€,Ù¤‚™_TÎ7]iÔ¢¶âËŠù(IýÁÌÎ8Ì]åØ,UÓU°i_VßÌì MT½¦E)s‚ç"ˆbŒÍ:çƒ2ãU T3dR‹¾Åh¾ü”Ît¼3|# k«%ò¶ðQf¼.²ÉK ÈÔ† „ýWôËGte¿ÌRT!]P�îf¸qgbá6Ò×åØikÏŸ@°©Ùß˧ ǘèóáUé”¦Õ Æ„ Á†£Qñòõ:#=a%$›=åÝô‹´-ONÍÞÓ Ý¥�•ÁPâm–`{·Ï2ãŒ8¶ÿÀ?¢ã¾^L;Í.¯^¿ªÐÈ‘nªme,n#ˆ>È¥—á‡�ÒE6»°��Ï(¸¾…jés¹¡ðœzNƒj_äuÖFÈnÃ&Ÿí°*o¼é ¼éÀ/hW@Ÿ¡-$>bÊQ½R~-’lš+qÞÚï £¿ôó<áëf•³C–0ÛÖ¿íàð¿¬ÁSêåWO*¨ÐŠ®5±$¾¨P"8ýQödÁã:%óôõ;áîïS§$ëa˜'xgå_Ð<¸¡ÿúõ«*¤¿™¡l "vžÐUàB®ßñÓøpø°8ƒð¤Šü�æKAã‹·Û°Â^»VMBF©8±•w@ûGÍ÷¢+¯/˜|­Eq�••¥ADnc�z»QnKm9BÈûySºš‰õßÎzZš]£A�χG£á!"±H,ÜzÔë„íH®ØÜ£oö_ŠhIZ“t'òFÞ”cL¡z9î<Ñè¸"¡Ó^,?­s¶lãí~�-™¿rišèµ•‘ƒJ¬ ÔVçž#Ê€h}ƲMÎDØ'|ÚÚA©¯l.ïÑ¢Ðù‚œŽ5¨ø|ÇéðIc·m¶’o7X—‰Qþ�n“[wÙ�Ð4¤Aʵé–äU�±\V¼“Ô³xy~ö%isÌN´Â‹6~Ðü„û]t˜¾¥qòÒÀY-ÒÝ�ì>âÂXø­X�afIJ®½ý¡ñd(ÔïhÙÙØq¶§¿3Ý:•&ò¥Žxùâ·˜�‹PqísÒ*è Kì?æ¾­ÂÖÆ ŒÄb+y ¶¨Ù ®ËCµ4Y±â¸v“  àâ_Ótªk¸§zQƒÚš"†r½DÀÇ—Àì%e} €nÒókPÈÃÚÞæÀpd¨Œ_~¡ƒ» Uǽ~�¹K)ÍBl®´ú¦³�¯z¶Pª_]ÎÓwUH=woñ`âŠ%<ð#ã.¡¹�š Áá�si—QPÑhÀx¨Êò.·:¬àb­d�ÌÃצh à�ß=&± šº°”¥‡a!¨¨~@ýtQòL,äì0 ú%ÀMóŠßtpøËšÉô¶‡¾Z.Ò ¢Ç=Ñk :è}÷Ó¶Œ'°�7 ³ö”ÐøaõÒÙ«=r´0ú ið9¡‰HÈÛNB¶ È n2Måö�gç 4¬~”ºò H ‘`ô©-7#Û?ad•V ¨’sÛ"PdûlÈ$³cú œ8ªétTjŒÅ°*(-nÂe ý‰Vi&.^êMˆ×¢ŽÅñks€Œ/cnNœ4ßa¾f墯«4àß8}”öSªõã íK4Û^Ö èB!O¸ý J"üm½-Y°1Iã¡£îg¬Öx£>%G…žÅ¾îz< 'Lì*á9ïú’Qß§O™-'a Ü8@Ÿ€†Šù�,•‡GÒ€ KžÐyyL€o— Š…žn,1’×ß9�†úÞÇN€Øã¿_ñÆÊ¯›Ìаàd…§ˆþZÄ�•&ê°™Ÿ–£¬('GW1y½länš¸ºï=Z]m¯x2¯AÅ…#Úûcp)DàË?.uÇ2æ. p Oø'»iŸ‰>B~­-¦ ÍgUFgŒ�¡ÆaënOS¹3;Ž-ZëÐ\ ó,}›Êú'ŸU¢¸´›WµÃ:Ò¹jâ! Ó]©;K`ev.ŸÒ¦ûìÂå€e Ò÷FVD2®ˆðCÈ_ó;þ›ö�àë@Ä?Ó5Å3í½O§3±^ôüá½ÇäJˆ¸¼_„Ü™�ɤÆ|«0¸=×_${ì¦�ʳͫ÷‚Z¤_íì«…ç…˜¾eì~e*Mck—°„ùn°ß‘�hM,n¶f¼ë*>ºE ­C@h0ŸÑA™§ìg)+ñŒ/´”mÏÏÓÞë^EøµÎè‹èlüRi>Áþ~s« —Äì�¶/¶P“ç+ËëÃäZÔ6™UÙõî¿?ãÐh’"h+)ØÔ²qÓ’]xãù½&-*k O΄Ç@o¡ã¯Ÿ¬bYÂì8Vo4�.W0aX]Ó ÃùË—€ ò`8.ü¥¾¶5GgþRE´»iM9ÛýøRzV8þti€¦Ù“ùŸñ‚f+T�)€\ÿ�wuÿ–ÃUW±ò ¸É1)¾~epqù®áÖ½2)–Ùî2é®ë×Iƒ�èØÇ³~Ýë›Í*¤m^Ë»ó�œ®€ÇòÉP<š,°Ðn¿Osü—!s ¹wcPëHnH-`ä EbŽEž’yÈ`[Â/<»c Å=õE]�k•H8=6óˆ'‰yè(ôesÚÄA^Í2$s—–¢±�Tß0Ý Üú'/�S»Ž{K`}jÿ ‡øôÀûÜåôLåÌmÇȼºÚ6x‚˜ÏåHvš {wÙ®ãÒÓ^ÖŽ,3u~×Ááèq–å8Øþèºå6—”–^lGéeR6ahw`œuoÕqqsK�·[o\jyÕŠ+â‹™¨Ón¿ïü¼=­;6À’Mº¼Oû6k;ë2ºó´(¦`ª Ÿ<†ç*î8äæ{â´ÌTÀN"vÝLÍåré[“=×Ý0SŽ£G“_Ü&äê*’¸ìóöòÄ\ÈË_êÁ"�[È¡ÓÑÛ¾0º8ž¥A��ã’:᣺º y;ŽûûxyúìÚ‹ b•/@VØ'Îg|ún&êS®^“£¸°žÅˆN‰øÉöƒ2Ù{>»Žù�9ãæË9À“Q ¨ËhÞ–¨×®´Ü‰@cÝe•7;€Ü|Ì w�~ðgÕKå†of– ’–�vß½�”x?j8é®ćß!샃2>ƒÆB(:Ý™B5Ë4ûwSEþíáêŠi¬Û•ÔôU܆½AƒË^\îß~ææC}aT‰‰£8qIÕÄE ôXºg+µÍâŠÑœìDŠ” †Ü&: —+pÜMÄ,R"Õ"Þ_h-“:T5I”6ù²S 8ؘ²©iv ‹côæÇt²Ö\ÔrZ�\ƒ†J•)-ć­DtXênÍÜhãó“Žñþó·t'�Áç±Óån9e΄^ôX»äз—™ÛÑÁáÛ_Óºw×å¤C¾…Þ’ç>i&ŸZ �8qÒßØÖŠ¥ÉÐþqÿÑ•V`Ææ/tEdF ýXËREáX³F‡=¤P—@�JžYåÞ��ùÏ/hCI°–;vNŽÆRBJîÞ„û.�q¦ÄgOˆ±²Ô$æy¦Û1º`)«Ä6åùâÕ¬b?˜�l t„änó´úÕ Ôþ«W$½Au+ŠºÔW{qè,Š,ÓtÂø\(>= õ÷¡ï×¢&ÕÉÁáûÏéšÔŠú©s“ØBÖ^¯×‘|:�†5yúºA×|z§j§ ¦îÝ”(пtn<9N‹¢Ï÷דãÚÑŸ¤î2o[Õ5nÿ9¿¡“ªûZ Àu8𫝭ӑI¹�ªìå-5v^ö±Êå“lf6½û[šR1Ç_Gª5èYjáBL-ðVŽ� »>uÊ88ˆ%Ajÿ ×OÒÉÐåºÉ×'çcÛï×[Ÿ‹�¦0ÁºÃ�]Ÿmæd?ÿ�ƒƒàË7©®L�½ e«×h!»ûna q±óÄÜmP'Á”ÜÐ쌀-ô¿Ö­ð�Ò•¾[¨¶w,q´ζ §=²“P.Åî cf�Züª!í374ä5§¿Æoüª©=¡šœ>¡DüÖ^·3`Óx2ŸŽõ¾°dcÂ:ü=6ž~KgIÎ++ÎFjÐ|]Óüm-Ün‘ÀUäDJ‚¤?³%9À˜=×b,Ùé÷×Ï ôD·Ç¢•e¥Fd\ íó3Z`4Ÿ�E@ŸËêýWW·Ü>Œ­ºÙze¶JCÔ È60VZØReÜþ©úÏÝôxœšnelY“õ+Õä{q$’¿Ù#…x>V öz{ùøx{IOú°¹¬³ÿ,þAú}Š'TWUC•èIÏ\”úÿ »ö¨¦¯<¯;›‹XWÝÙîN»3{Öîž³�éŽ=É�:‹ÕE¶€ãmÖ¼º’UŒùd1zê~‹ \T­öD‘d,‰@è/6ãØÏЬ>®JÌê¦öj¹&l^‰ªÏç#á"‰x"ñ¶Odžžv²®ÑÌí'˜Û[ïÓYtm˲ •Hÿ°áRs$I‰ˆ…»-;ºnƲêk—DÇoÜèËÞ5ÝÕó²›xÍþ7ó"ˆ:‚ ú¦¦›_Éž¶ç8ÞÕoNÒªòÀ’xFš -åŒ,„ÁFàWA¸\³�“HRæXøÌ0À¼ì ¼ì?�g5»ªÈm¿”…g稂I„z–™:ª°¾“p@=?B¿ÿŒöÈ7Ä…Œ«ñ$UVVÁΊ¸B>úT®°½„äø×¿ÉuW–Ãïa‰á“q~>€Ü?�€»Íak|‚uDuoü“¸Òé¶Se¡÷Ko5rz ÊýI0X ïÄ{¨À+²Ûˆ°À‘#^Ò‚ô­T ZSý…ªØîFNDycT®ŸIQ•0Û) Kì;©�·™ Øx’§˜oÂq:•0*?>;4Bƒü’Ên&À$|è‚hª¤0aá³¶ÈŽ·_ø Ôœìy©K»Ã©½Q›¢ò… ã2!ß2ðO’è—ÍvÁÇÓüÀŠ©k3«ZﵨPHnzG´‰€cõÂÜ:Ì®9HXé£ùGh“ä²®vtàj#çúólý¸·É:f˜�®rùH}Ùã*Uœ²ýÒdÐÆK÷ż'÷ÓføòpelºŽSyïÞð]˜H,taÄf|@mKô\ÖÐXöA#äDú‰T”´W†L¹rë;Îv$®ÃC'`fS©ô�éèO*ðÖ °–”4ÿ r V�¤ÃÍk¶FTÇÀÂOšòÉÊ ŒEÉ+ÉÃeã0Ô)£CgÎHÏIYÉ$ëúŒ>¹¿¢- ð°²Æé  ô| f(o vi§'�.+Ù´®gïiZèÎÔ¾Hkä.× ŽI�ËŽ}Šc2ϽûnP®j“COø-Ý4µ¾#ª5º ÛøM#í…OŒ!˜ÏÛ ‚Öëc K}f·KL+|³º;çob=Ì8S3; [-áóù; t³ÒŽŽÉ¿³­ë&ƒ6^>¼'¨¢eT°îEs¼=ð7F×ÁD\ž�ë´[üØRd¶@3¯:sI¿ÚmMwãFU¨spdt|V-`ø’u7'½„h%ñß§/IMÔò3Ý}%òKéh7 Â[*ÆvÈÎ#²£¤i$qѱ/bæù!æÙô5½ÂUg\D­u®¦”ú�$‹‰Ïßößö|‘@´åc6‰¦ÁWsîÝŠ^^‰F£¹±— ÀM„¥âεÔ»uñ¢õâ(@¥WÓRm²"ºa$»‘³”·:­}h$�Ðx\¬ï1ªØVósù›½�±^ì9Õ«¬D¿FN^çùù˜J¢¸ÛKÝXCö¥ÍL–=~õÀHpâ¹P÷wê¨=&B5©�˜Ãâ¯é¤×&Çtœ¼’þâÔ^£ DL¸ËäéßøW“QÖ9§iß¶OOinŸ^‰ƒçÕs=&ÍŒ'v>!f;ç‰P-øÝ˜�‘•ï°[«NÎÓqô�Ïf;;1 i¤ß¹Û±îÄ<*λ˜öã{Ç„„½8�|c‚ªÂ�™HÄç ­•<¶×–¿ö[ŘÑÝ_ÑsB½¿÷ ~ õ¡£93Ý )¸Œ˜‹ö?nÇëÎuÎÝï_ÐFaôÝ›«%¹�œÆöÖÛaÀ^ˆ÷Ë„ÙJ*Iíø„7;õ¾¦_ÈêÕóã—Úê9/¦Òõ]p†q:⎕¹Âöãu㾃> |¤h0mxv1÷**Ð<è¸ÚN_ÈwúXaÌ 7oö»x�zâ ï͸Ø7©DÉÍW½#€[ÁbΧ²SRø? l¼Ì_`î_ºÒ¶ßÕ{¹w{ñ›5Ù®¿ÝŸ’/æ ¶¿´=£•�- ƒà¥ºL_ƒÑ¤Ü§c‰HÑØ§'—•'ä;“ôâša] Z€=ñºn‹h€‚Ò•€îë­Jäû$æ|R+QE%>–N§OÛ=¹„¼ñ| °Ù,ˆëñÜËù³øméðÑ5IÊ– WrO7H†b][ 9>j‹Sn‡‘i!êàFÎjw`oùòŠ]Do€ßáœô‡½¦œp‚‡ ߤäû/¬ àø®Úì!°6†îêàȈx».;aI®f!‡ñ]ÑaÓNÒ8sê„UýS¶™T�ÞMu êþ"‘{O;&>&:ÈÚ�FNÿÃjï2µØ³Pz-ø>1æhˆÊæ";íó:aò™QÕ „fu…\ÿHûc/EUú=¯çøM?­zR òz4áSäy¿¥r/Û‡” 0sÄ'|‹ZcrŽY–W–Ö¡‰Ôq&³ »kKàÐHø\†ó�û÷rÛŸOhVO‡ú—tà1!+­sî±å´×‹Jˆ2- ·aÛÓÞ×"Ä�7 HÐ_hùe"W×Ú<ÍYJN½QQLÌ#übàEzZV~�-í^_ß²%‚Gë 9a)‘÷‚K‘¡êAÍJÈ6þÆ;>’*e³ƒÎBXà'8Ø>>Gûº´ÆÄÚîÎ|4PÒPVDöò¯‘Ķ=ŸJÁÍcm¼7ñ ?¾CÇôª^]3t(ÑÃÉ’ÂÔB£ ®•Y«½§Ÿ.ž„²ÃC?¦¡Œk’nä\\Æ"^›œŸK4H¾�»"–ÈŠíšÉK_^Ìô½.“.4¾Ò�oBåq#ê{9ÄßÁ`ãþÃS§å�EÁöÅÌêǿ޲åŠíØPÇ×-d6rÒ >‰Q—‰iÉe¸Îzœ4· ´¹§@ßx?]@Î@×`e…$^ ,W£Á¾ÉŽî òÌ‰Ä úDêuZÆ*s"órïcï¾MogõÔ�~uC> º®�˜K5„C² öyÅ?ÚÞv’1V1Í¿³àÙk&ê«PtBÅ+C21/%ŒÀ’¸¼Hßd¶q)Yk(ö@~N‹¥çwάø¡Ê€ž™^`‡¿'€uº}~”ALU¦Í̬z.«ÿmfͳÑ-§¦&´êvñã|篤nRûÁoB73¼ŽyˆÌ­6-&MÜå±e•¿/ÊLð[ † Àyl'é�{öË<éÚ B´œD§-[¼G÷L®_2’ÇòÑPOO‡ÒäÀ”0æ"&³m¾Á!'#­¾ÊgúS×OGu]ó-@ªáúáGqÄý¶3%cÌv‡fª5Ð&س‰é‚€ézŽÞTeŒ%j£€/Üñ…ü„§Lqƾ£Ÿ ±ª¯£_ŽÚÑÁá»×’PG‘zv.„¸‹ñ[I‡ÇX¦, ° ¸ýq?-;ï? ž44pô¥�ê’û/cûþ³¤°ë¶ž`öÄL®� ßâ–2£¾°°¥®®ê’úÁA.r·ý?Ž¤ÈŒ]’„‰ŽÕ ¿,:ºÞ³d˜.GÙêÖkZe¿é±þ”¸¨,.sÓö²|±0ÌñTŸ¼K_‰îG¥}åS œ&µwJ@L?òƒ¯«çžÏðÿÚ1F�nÞœ_T×g[©CQÐß [hऎŒ„�_쇤‘D¼ƒd¥›{…Úð$CÌ<ÔoqYY«¸º÷oùiÐhLÍØýÈ~bë»0»×¶Â’ÒÉza�ãÝXÐ6ÄPR_O˜OjJIiŠ�‰x"1�2ÅQc„üݼ ¯cIsÒ\ec©p�/ œëöÕr|L4ø†ôÈñk®râ>±‹ÃHFX)-»=i÷ÉXLj>©³]S×i“‚áK�7c½<+µÐÊÕAàäÞü …c\(3´uk9Õ‰ ‰ÙAýf'W…}‹�±*˜À{¶å癦Қ5ক‘Yui9ÊkZ¼Sç— ©œöcugŸ�û“ë¸ÈŠdrý–é ÔôßoÖr2Ÿ,÷d›––¥6<- Í˜ÁP4-¸òneC´œ‚¢‰æ—  À*íŽ/dÇÀq`ÿó�!fž»0›7þj+e‡iƒhWæ8µ aþ¯.ÀÀuÂv�Ý %T3»Å~ó'Ú¬[Œˆ¾®¿ÃÉœM‹mòî‡0‘˜Ç8ýK-¹›í/&TK{eÌ¡+ƒ«7Ò’W8éÏ ¼V $ §i£ç!·uq­:8ò—è8ͱcPWv%EËñ®¯(¯š2@v„ qežrû¢Ÿ ° cR™ÝÊÖÔVM¹5S[3kœi¾~omjcÔ„�h⚇›ìneZì„N�¶btþX¡å!o”§ˆ4ò„æ¡òéD‚‚òên 4ÐòP‚½÷Üþúv¶ÿr.§ïwï¹çž{Îïœ" ÂÙI®9Óˆì~Êå’Î5íxEÓHë:=jôyï(l-¸û½÷*BBX£chö³HÉ(w‘¶LýÕ“å¹u:jt"1Öb€ï—"m·›2E²`äG]AºžîÞS^äñ½¥™°Þ½¨¡õcI#½˜©X$f¼w òà*~ Te½�Õ{Ö×&†騩œžŸ—† Ø/a¼_-\˜Î2üP¬ýdº^U4T|)À¤ú[-ý …ahPÐ1Nlˆxýøä$%j³=¨íwêôÛySI­Ôjœ±?ü!>B©Äv숎H, r_…ƒùW' £>»çZµŽÊ™O‰»+Ëg$<ïÝÊ#x%8äèìÌ‹�†oÉê1)éFU'²â;jò = Ë¤èFÙds.@[Wïa7�—+‡È PñM—ONšjéîÚ΄Õ.vIIE^;8kÒcš{ù�v ðd�\ÏÕSÍ}Í-sÀ¢9Œ×ö�£�FÄ‘$Œ¨Å3|ö“Ìt£æØ… zjf¼¬µÃö�DÂóò³A_\Ì ×&,ñÉ7fÎó[“·ãbé!ëRËE=H¯@„žÄ{1>’Ì•Åvª1H¾RœP:•“µÙ/sè!í’éf;>¬|ôÅJ‘u·¾%<À!ºíçTй;,'µ.^C[O Åjá$ªÔçs…­eµ “_cÿžÙØ¡ÙÔ4�Ž2„W.¦4ƒ8ˆEÐí7=±CлÃÕátvΓ°�Ù¤Á1l¸¤N0fÐ]1w2š€!²Õ™7wÈË·|¤–”ËB�=Ÿ0„å Ý"#IÓ¹˜ÇóªVª«ûÞˆ±ŽT}ÞWúŸ•G8€ÜE¡áÅYhÙD”]έI¹¬ÓSúé8MV�íB—Bëƒ`ùA®Ë|Í_ø‹´ÒZ}¢íè]‚¤{MLLÕ Q‰½üý”‡åGå.‰0˜è NßûšôÑ<{6q5MUAç«~9›xÝ€ý‰È.ÿ )¾CÎÛíP¤àwžÿC:^& —$O™)‹~õ¹¥Ö€}4|è0;¥3øh,³¿þÚÃÃÞÁf÷Z‚AF¤uLG�Ÿ�šj¨6àÈ›€·òÌÀWºÂÜøkÀÈfèÏKN.+³ûIAAmÖªÏVWÛ÷ÔkŸR¤tlÇ …E;óÓÂB3Ÿ0W>¾{ƒž˜3ôUe†T×û¡ ¡ìWIg<€åø%è�m¤/¯éQöJŽIEÇß.«HŽPnƒ·q¿"ˆ9¢”®ûb¾Cû�ùG§¥Ë¬JîB6X‡¦j¶o)RûH|ƒe!Êï¸Äë·‚1Ê>D‚Eú§WæTÓµôÐèÉ¡�k\¤X Á‰àˆAà+Ì/<Èa �âàË÷Î�+Š.£ãoFÍ´”ƒâFöšÀj9²éI®n<„åÉ÷ñð¸çK~yï�¬+ùg®ÑaÇãnO±X"ðù飸v“í¯ã�¿Q‘¦�õIkÅô(²›ÕšÕ¡8¸¤;ðû‘Œó‚:Ë0 Ílè{Ò�Y8Û‘”v®‚žK1”kóa)ùbºHüh/`鼊@w¯bŸý/ùcg**êÌžù7TÉWçªÀØç ‘§T '½bËçP¸ÏWHûÉŽÊ /_!¦»ÿ�Ò`²zäDÿåš”äIÏñ¦²±²Ù*Ü%›¾…DT® @Ÿ"ÃU¥…qßtw±b…=Ñ$åÚÀóÜf³ç•—Ñ…ãUp($"½_¦8¬PÌ1áÕÌ·"®¿û#‹ÔZÇNÖ«&=£Òº–ãO`„Z›C²ÀPrqÄâ×íï[¡dŠOë|ÆòÙôIÏÔKñ æQX>t¦øX¦ •‘kÃwÛ—Â0yñäÔ#³¯]j0{Æ�æž:oÄÛŠ®˜úaY€ÓÔ�âþª?NN½ûtwRò�ÙÓ¼0›ß>XLÝOýoæ˜à~]þ" Ñ -+é]ᓞEƒ‹µé­À{Šü”AÊÀP§eǤW²ÿêWˆãƒ$ŠðõXç'£;Ðʄ痷˜uU ¿Bž÷®£ö~CŽüyî»òRˆ¥YLÊ|×lsÊh‰ÅóLe㳇74#­:qdéÉS¡>gÈ_l_ô�„Ä®¤(êF$ļ$|¡dëÅ1C<Â�å~AZäË)c·âºkéÒ—/5‹¹‘Š‚7? –”+¸/b<Ä�çgvªò²ZxJ3¯¥,fKL ðò4‰Od‡9à‚˜ÄÂ:п'Í�i•Éš™;©óÔL«ñtݪ T3TüÞ*?èl¥bËK„NìÞ0Ò±|âÉÉ6sÉp]ûÜ„õ¤„qèî슷^/Á£Ìm¤e¹<\`ÉAûQßÝÞø &'– o@àp�,$$@~Ô¹à�Yóé/�ÐM7{tT޵»¸hÞ„[©óy›> U âvÈâ»qþ¿H™îœÌëˆÒRµ–ýĬ wt’6 «çÇŽÙ^Ÿ ÎH¡¦kE?VÒ¨¦_ô6g4M™À½¸= æ|Ç:˜ç€³÷úG[�!û'ç Ü?�¸¨¦Í†¾¥ì'À�Ç0Ìæ5¡¶•.&YòÖÓRuhnš¯É)NÖ_©^n)  ù1±À’ÏC8R® ¶õDs.2É[/£ñšÛÙwI·Ý3ýƒÕáB5=U׫zd²Ùè¯Ï?Ê�91Ã4½ôßH�ðܸ:Rn¸D[ »­¥# …PÔ'Kÿð­kCf½äéW/ŸÃrÒkÙ˜»˜|ò¼š64NFv˜° Š ^ï„|?W Dd÷�T¾ü= Tê.šÍüíÐÍÜòäAÎ#0Ð@Äæ³tj ‚hîzüçäyÊ’·Ü¡¡Ç³[¬Ïú°Ð£y‚ã54È5Ÿ{ß� r¶r ö¡EM[{jg†€º½"èD¹eG°\þƒKhD~õ„µˆ÷;ï“e‘úgÕ†L5�Ó7ŸšÝk€|!ów{å²#¡Ál[Þ�\|_·)®Zô#[�¶is_·)aÉ^ûˆùq7ȲHÌGF zÅÙŠË‘’ Ä×Ô…�:U9Ž)ÖU¢ÝMmÈ»Y ? ‹|¯O€£ÌywÅn«ƒŸª÷?ÈÛÀ ŽÖÏÕµQcgúZÓ;à|ÚÃs·ò ÂõE†Iì“ýûÅv2¤é[LZÑRÖ܉¤B� € "‘È ç†Ï�ª<5¾ØæûµÃóSWFº,éjºty¦ÞÔ‚'‘ ˜7m©ækï"§ã Cܯ°Ä©aáÅ‘ÊÑ‹:ÊbÐ]¼e‚�#åy} Rø+d!1f­:@AB¿!�˃ÚR}î-¥¿š¡²6™påB C¢üQÆåP"Ë ¬XS-©+ËškŠ.†UÑá/Ârï]‡%å‹$PóX�ª�}#@v8~¡~d„²?aðäÕËtX¢åR-È+_Ä}üBCüAÎHL´9£=+¯&µ\G%F–˜Tj, h‰�¢’çêeºV‰bRï;¡KæžDdÔÒyýêìÕ‹¶#$96ó%e “Y~HŠªß#-„æªð‹ú´Vê~xYgünÓ#d¼¶!uäÀ‘0´ŽD�´ˆ¹Yò‰®:Ÿd¬h¥*òË3Ës`ñÀÞ�º¯P6Âeñ€øj™¢ýˆœïXÛ…ò'39´&þlý½ó&ìJFæÖ®eA\�&ÆÁL�F|ÞŸÚ@„Ã†Ž•Ü,-ei‰v"�€�ãZ[¶Gfˆ`í¶ q18õ¯]²¨ûæË´ÔŒ^ßЕ ,ÑpØŸì[®4=<Àûô÷uN7Qî³ØÄ±Uª©}¶®$Ë„�-ŒpÓGÂàèŃ©vÚäáñON0‡†Ú¦Kƒ½:ª»¯³82ÓÄ–ï\»øÏ`( *çÙjtv‰¬HºöÈRÛF¥6&÷.¤c‹ ÇDB”þ¸Ø¯ëb�ßfÄÂ*¶©7»‚8gT�_y¬¥òNVžÃ뙪°~{eø!抎Zëúòá2Gy¹åáPi½ŽŠ×šÔwSð�‹›±% ± s=×âµ=Ý(û+yS«5‰h–££Æ¬šh˜%jבA®PÑZγ²W¾Ø@D[¦—Z/'E§ÒújÍtd²É–ÂPû”��.•€Â²úÆÓÃÃGLªœøäôÒ¼"-SXwêv~äø’�»Á¯p84˜+Ÿj µRB·:%OåfÌi©øÚÉeSˆŸ¯X*òÙ¸et*âBmÀ–ãˆÉ_‘¾…ã`ae¾–ÒWÜ‹0a4…/oÔØµ×ÞáT¬EûÀŸ0Í�Aƒð‘ÁáBôÞÎlÖô‡c½ÈˆÞØ/ amq—+†ØëýCÓúI§ÿg+Æôá=7j{^¼I¯€f½).ªˆ÷ŠîßÉgû³¸U™ŽšI?‘fÂýÆ{7Ò 6cÀ墺ð�8uþ7™o|T«_È£¯´Å^I9�wBÏV(æã åO®Í_WÂtá3ræNß®Ñg騞Sãc+€0|†þ4˜³Ë.&²óCóý›í¤¿¡'j±nâf}åvÛÐÊ à&BoˆÍŸ #£ ”q¾çñ–¥)‰ß IQï¸òKÜÊ d£G·-À�²Z¯Sä²Gº, ªT'n ܬñ7#’ûtTéRuãê¼mÇ}%Ôö@ÇE€i¯^ÐeÄòÙŸH‹ª¯²l±W¯¥nDލ²Úñ„›A·áfŠ#þúÍUíÍ6m"î°~Uvá…«:Êp©rõç§F÷ûJ›ö(ƒeßÉlAWdޝÔQV'�¬ÃLZLÂX]3{ºÂàO¡D$òöƒ¾68ù*Ë.ñùJNÊÑ�¼ÖSg­yôÌtûhõ„òe6î“ôG“úÖùáÊ_×oVHØCnú“¸ÎŒ¾Õ²X•52ŽåHŠôÛ^…ü 'ì“Y~ï"Fßÿ�ô¸XO–×Eœ¦¯4&ê³€²ÄBo¤ßvboy¹òÖkýoB¦ÿÓwÉÉ…]>7£2ê(kCñ˜õ1F³J%’�;eAÜhwL¶×ŽƒŽ¾ÇÉËz¹g®#ñ~µZyF1 ›+H^{ÐÅ%÷çÈ�ªÄqWéâlí4.EGgÑ–šØ‰ØXÚ<Ú¹3È“Ê)œ’j“OOD§–ÑmñSºóÃ}Éç3è©é��=®(- °¬·‡ÇO9ŧãš&3šÒèž·’G`'øb!ã5`8á0ÙŽÙAGâ“mN ŸÔ9%K*5÷Kc‰®g!@€Ðq–s(0LeÙý ÑÿBâÕî„•=lZÔR–¥}阷Ðd·\d0ÕîE~u•"àÀôÙówÚ©¶çƒ±Ó}F\À@*v9 ÕÞA q¨uê1µ`^¹@7E/Yï;pR{zŠâJɤj•¬$H zlë&Ïìå‹§þeÙJ�ÞñÄì|!Öé³S î&›Yn#hg£ö‘¯¾Ú¦’ø�Ç:j)ih¡è†¼óÅo›Q|ˆÃJÄt õ$Šœ^jTTI_F!]ZjXhí†B†­Û_N*ˆ,·.´yûH ˆ!Ípo2¡�ºÜø²ª«#¾„úØÕ»à‹ô#Ôü8 ´•ÛvJ52Ë/1JW�ËÖ;XŸ9¯£ôªþSCZ›®ó•Ð;Cp•6ÆD–tݬûšDߪ. 6ß¿…Î×`ì\l ž�YÖ;dGB‚•¯²äð˜W_› ¡Íu$J9âÉÓÔ»Q)tzõêÒ…fŒìgD‚·±¥³[® B¡-û]ÓÏñ¨WÿÒnd;/8ÅD^L'u[s‘ú®É0�jÆrÊâ·@÷¡ƒÁ\Ï�uœ#œ«LÕ=y<Ü–cÎ_Þ8®º§¥–"ÚŸ‚L‰ùÿOØ•E•eiÊžwAE'fzfúÏô 31ѵEG?’Ì$éš®«ºV­êÒ®‰Žš™˜,M…I+�.­îŠ�Í…%AÙ÷]v“}A ÙÙ2PQDA�¹çæKx÷ñ´þ¾sãÄ}÷ž{î9çžó‰\òsK±ùËlj2ÒÒN :ÛõÐz²ÏçYÅ“õt´xu$ª-o„4jQH¶Ì8AÇf rÜŒx†~,�’�ð(¬³¥e]¯][Ȇÿ–”×ü\�å.•üÔaí–Ð7qaÁâ"=3ô°ùÂý,Rþçá#åi@i €n� ¨ßÐÑ/÷b2®­•£�¶˜’Ñ,R÷£�É÷îWvQº»�ú’!/Ÿõî¯h“ våâZiK#ã{íö\&¹ÁY‰Ù$pÖx‰$ü:¯ÂÈ>’Ž=F?ñ¾£ë/G)×';ÒGÌ¢\j0‹®GD@ ãÒþ7ôe|?yz­½¢‘IX‹j.M%î°‚•Û|¡<ìzÔõ°˜C¬ØDÅúOÌâWat9ÏxÜÂrQ—ž‰MM!‡Xé®?ºo¶ØÞþÈ´ÕÉ ¨vܦí˜0Ÿ°›ÆœfôfCx}"Ñ>2‰”Ù§Òˆ �c/-GéWrqjUjw#S³5^̤ŽR©yqûF£¹€Ì‹ W}Nók¼ÝP4WŽÚgÎÜO€D[{…Ö'd]$õƒ�y&à|8-@%YgJV".¢â¨+•±–e 1_€øÂOSÆ—AÇì ²±Óû´Éz-ò7fM‡†‘Œqì<Ú`cËÓ…ôÆäŠË7ß%`6Ï^§#Rƒ×ž”¯!ïÒ•ÈÎRß g{÷¹h\=<]•îb¿L†ðÚªÅþ–~›(¾œv«³ m¦{.À:8ʱë«þÎK½½µ!òpý ÚØ‰îMXkkb‚¯åÍ.ž%uGŽ)ÝÅâdÇòO˜×©ÿ¡°W×­­¿[ˆ|ÛGgüHÍ›ƒ“Ä{ú¤¬I0? ñæ÷þÛôß>¿˜ Ë@Õ+³Ã—MP+/ǾôAõ ,0*aò!òlüG¯ÓoÃm†õ°È Z4™?¿¾d‚™“}¢>é¶ ø‹�x¯&¯$ÒÖÌPnbTF¼‘©,Ë~<³h"¿éÀ’DsâÏš!$ŽW3>´_©i-pqp"f%¤ Ý[‹ 8¼d¤²= úþ$Ø· ±G låtúï"wP¸ùÃÆ˜áÀ840Z]ñì pT(äÖ_(�xVºló›!¶ƒ°£ßÒ§,ÿ\[|gó94Û´œh˜7Œ–Ýóžæ8±±¶»‚„n1°‰=(hYYU�šÛÓÂ<{ªó½òØ—!è}H�vVº‹¦NoéýS˜G©‚ŽßÜÓf7ßí¯B!í½• Ó°±2óõwâ¤HG½vI»vPýuµ�:3Ú×™B£6~ê0ƒlÖŸ¹~£Ò(Ým›ï,ÿ°{GïÒ×r×XmHTD Ê¿]ÙÕ8eâêÿwïS=ª:Í™|z«òÿÀÞ/ }"&Ïv>ibʆn”›þ8+EººiÔ"•ÍN[¦MðÊò}Pï6Ÿ�÷OE•³Úù!éËg/µ†Þ1ÇÔÛ2=x�#ÿ ¯Ö;,]tfíñs�Q϶·Nô™ˆ· ‘Ø€·õ£b΂ä'L^··A?S`Qà„žénÖ.¥õÀbBß/¬›OºzªÝ”"^&+åïså«´î;Ÿ—|þé`2zÖ´¥ï±V`3|�³ú{@(°#�ç…<0‚c9‡yÕÆÓyúQkçj‹ž™õ©¯.–r¨'âxöi¼~)‘³ßŒtBÆrh m….'Wºí~tªó¸nx"äj5Ê�¿7qŽ$"ìµ —´/Èv’ŽÜýß±ùwÚòPeUAK ðd¥øÈÛ:cóÔÍ’‹C2€ãØ ‡þ´E^fœ-¼q Œ˜º:¼ÉJ*d Øî‡•\P†âGÈ¿çxjËGi SÕ2Z“9Y‰¢ÖR¦ÖW�Ø`ƒÂbëƒxG¶kBãýnn+-4µ3á�¯?mgÆ#ï„,®É[™LŽ2¿Fì‘lÓ?Ž÷Vÿ}×›‚î%u41ëÝWZf€›T"‘Z›û܉ 1•‡½1•ù µ½KêÒuHWSª»ì¤NŽ ©­9­GÔC&x¿ûïïÐ*+ö‚~#>¦‰©NëÉŽ$eŽŽ 5vÓõ[Mâ ÊèýcôÎfy_º–Ø]… çêžÍ¹Cy(Oª¶ìÚ LÊÌ?˜Í"KjRO\uTp"ªñ�iìy`$e] ùϹ.æÊK;‚±íÕ�{ùUŸû1½UQÙ5�C/51ÅÞ%Á�# E¬£K‘JIÜøíEŠŽRþ%ºA§Üik¹½:§gªëòªV�FâµK{8¯ý ad Ïæ\|›¶9ý»¶Guç¢õБ¸ `Ê:)ìåÖÎàÛ©…!Bã-îꇴ§8Ø÷l®7 �úç•‘ÿÞý®Gޏ©6|f; áxj°•ý® ûmUyØ£Á…8T[òfzÚX:9IؽB•§§¸‚ c8¦ëÐ2óMzž±+]Ñ•sQñÔݹ``ê ÀËeû‰ÚÅÝã¢CFp,c-6~ƒŽÐ kM‰©>!(e£/ú¬7¹c¤ö,úR} :zÒ›CH¯¯ñ?{þŸà¾ê{ªªï`{§ú7 pJœdRë¯\=Øó6?¨;¨†õ|•N#I MhgÒ½«Öž ôâ$‡x•8ô¡rì–ñmߤ�-¤œK.EëÍòÌìàÊäåj‰IÃÛ‘W `-‘ObcQÍÌ`Yô3øŽG�/yÿ¥�¡ò 0Ghv½Ó·†²Û]oóxæ’Dö2‰õg˜—øc²=Õ Q.£bpäXcØ\z2°”Ú°h 8J vï¦\›%F\yË¨Š’GZ¼'Ò†/�¦añžÎ¼9µ‹ ÀH{7ST¼xàI­˜[Õ�´,Æ^�¹Ö߀š}Î¥Ï@Ë¡�È÷Jì¡ ], ñ&"8*µÍy«ÉqÌŠ~z0nÚ@ÛX `ÛgJ»¯Tǰ?ã ATVÁÿ,!#8–¿Åjûë Úk‹OIž¬ŠB)Ë�/Ý3�ÓÇÊ­?…?ôv§&4Ž4è®~ƒÖŒÅåùí£WQX¿6ozÐ@êqì®ýj ±F¾ß¦pd<Œ‘ßãÃwA�ƒÚ}7þùSïT2Õ?@DG&a±è|ÀÎBn„hy×Ål\­X}WÖª–òP~ÔØL8pc±=Ä2Îjµ»¸Š%tKÕµ­••‡ —bïBÁÕ:ß&¿'dæq?L™vŠï„”÷5†wbyîgÔÔ`£É�]ÝÁt×µÕõ€¢�è7:äÇN$I¾iÉÚá9�zÓp݉‘—ª˜´Üæâ¹.<ŸH!ÙÔËo…Ên?éΟ¡¿ÜWóñ|…Ý.¹ã“ü\‹jB³Ò—: Т¯×.³±cNc£U­|Ëx²Ç»½ÈÅ�,~fFåúÍœI¨ýN]øPˆ6·ä@éáBŽÞ¯¡7Ä�íOÆý‚W;e÷ÖTJW8·¯¿ò§2¼>%Ö”ãŸ×¼¸ž�²Îådõ·Åé¤`w“ЯJü ÃNžáÙ¤³ l0¦-8 õæOG?у֔;A’‹›iâ–³|ëbü_l¶Ì´_]÷^¸€òÏ$/ÇÖÈ;¾ÀòXiýAðMߢaØ»bº37’ïºà;qµ b”˜W?Ä—B|±DÜÂ2üÁ×´9�Òºð´¬æ ž/X*©©cžù 'þ3ò=aBæ?†ÐQá.mu¾oEhÊèÍ¿nàÊK|&<”BV¼·(ÕnŒ6ÐYŽWÅpiÏj8[x%¡Ò@Ýñj~ªÒ¸cåþb3‹ ã¶}3<ôÝÝi-¹pæÆÚfüN‚v¦vI!SÈö˜7È’Ç_VBñ²ºï´²ÚËU£þÑ&:1vóæ5|>­}½Ø² {ð¾A@û×fT.±Éó%OþGvÕ3qµi-ùú3›ª� ,‚»ù¬“P\‹‘/žý_±5ö¹À¼\Œž›ì(BSAea34kÁƒö|�‘BYZšâÅø$šµ�üÚ ä¥v&­é�j>9n‰ÔfŸZsX­QŠ´(�oõ:¡VO€á2³êç?’8ÀlDô6¬æHÌ„em¾Pj9OE_ª/? É»&Í1CË"øô…ÎënëPçt~Q°—0¢o̺¢‹ql´m¥Å´ú›e«ZÖ6‘ê—c07öcm¹ S1_„ àqôH¥«sô�i K©�LÖåù‘Î,X¾¹vÃs‡J#þ´CFð, ¿xÐzÌß0qO7Z„Öz†£€¥þ }¨Qº(ÅÅ– °@iäýk´“‰â¾šÔH´1ô0a>&éààÄ:¦ö| êŸ •÷ÏnÑA…+iÃs1(®fu67É@ÔáküýÓ–Ô¡GdŽß«`½CîÖu×ä� Î¾ú‚ÉD³ÀC¬^ƒow»÷4õ÷ÂX= °ôiÇ?\y—¶Òüî?5µ0)AÞ7Ì^K™ù<é$4K�2VÒyë43Ó�ûƒU�Vi[Ñer¯àXTžôr;©Üv¥lõš‚nÑ‚î:¡IWç¯M%¡ÜG™‹%að¯ uÖ`o˜4…Ú€ÚÚÚ^ÌÏæ]Ú¤̉ ñ«KFÝéÑ—&µ09'©„EOœÖ¸+…Ì�ÓÍÿŠ™}.£5OGCZBj´mÄGÌ\Ó’eó ì¾P»º{Šk|û­_ÎÆ§íÔßÒ`,ié« qëÅhݸ_ \a½Yô¾—æEòlïD¢¦ü㪊rm(ìjmPÊ®ÌÈÚ´#¡ŽKÔrà›’§!CÅŸæ×fx6Þâ=È<œîL̺›àG¶Îp6,hè|‰!dŽ_=¾~!ˆº]»Ò4•‰º‹bŸ§�‡ó&ƒ7ËϕǹÆB{L¶õdé‡'–Ç¥•X”….=òOœ,Cóú܆³À.ªÝ_ª?mG`…Å#Ž[Ó„¸¼ª†ÎV¹Z­M-�BKYéëχÀ¾wp`w;»�ötU†„ÎS ?ðf;Ïgwö'¡‡méùëC ¹ðÚÛ7‘ÀP9vç1ŸôoNŒú�ë)F5³=a“kC¤I 䄸(OªÜÌ)W¢ÒC\8³”OBƒóú¹1<¦ªt¡¡CÛ‚Æž[R�Š9h^x±�!Ï.ÌóßÅ3Ñëq¹³Ah}TŸÑµŒy:Jì±DRº¸©¾óRº�/ÉV{6;¼áñ¯ Ðù{FîåV”£š¡[åiKCà)Ø!å‹gHFð²á~)(LÍkÓ§ÜOÎG å¥Y£‹C¤-‹œEŸ©ÜÕ®ñs ¸IÆc{û$çþo¶OJ˜X˜e|¯'ô?üÈR7ã&+O¨=¶=“/¶üþÙʪFЛo¹Ñw¢›¡5ɦâ‹s°ŽX‡í> ù+”ŒâIê›oÓû¥»5ÓU“‰šÓ6’s‚¤ÊðÏÚüË€ò˜×¶°8¡r‹ t…;ðï[^üž· „¬­2…¦µö¾É!bÊäÌû^x’;¤ æ�ê>@RùÌMëã½Ønÿ®<(Ê$ËW÷l%¢öîÎnÇÆ^ãîþÑöN;ÔAѽ;âô±Ý:öêôôôvÄD”Z-Œest‡3rß·€rCIq%r#—r—H÷¡È- ÷µù²ª¨Ê�¯˜ýC2yæ—ùò�¿÷Òš>÷ž̪øéTT�÷º|¢Øœ>~ÞÍùløèì¦ì°2Fì¯c6ÿ!Ÿñ>M_þRO³ÚP¨ã#FàÜ¡£žÅÇn®öÎÌÐ3<ó„¿óÞ¥××§¾«¼ÓYŒº·Uc1ZXA�]Ä5Öf®ô;Þ£ßypݨñ™�Aùy1¡@’/Ä·ÍòS¹¡Ë -‚Ȩiápàë�QL–×ßGµ{ É›O�öüy–ûÝDØ9]l´�ßÅ‹«ÿ%Í„µ¡ñ·× PÒNHcg;0!è”cЇFz Œò-“Mb@ebF"SÅȳ1VÙØFü¦pÓŒ‚a"üѳéèOÀà¬r ¿�;z»0üA#ÐómèWR™„­%4 ×xYÓ¿£©•,?žw_DSI½©ÁupÖ<¬Žœws¹.¿&er4 jžc4ðóž}¶2䙉<ÛGZGjAXˆøðþVv• ÆöÍxïŽ|FÇ‹M4‡Îå¡„ÛÆg«�žžÕÁqÍ�3™c"ÑæÞ§Ù;£Ý'9p2õ§¦úU“»Âƒ`³Ã•ër3gBfÚ‹c’ÁN´1x;lz²¶=RÖvwV‚b` }é 3m&L8Ü.ŒV_½©%JÕ³B´Ü´Ó_ ZÛš'æ9ãb/5«È=Ísx7§øËÞ­u1Rù–q(—CÎ>»Ëô¼èŒI}ÿ>Mq²6ðÙôƒ{h¼>>68ÎGˆUÞ±óWÎ;8±†Éý;~d|·ËÀAOK»zÇF^qûoûEd÷ëS…GtˆÁ�¤”�I¢ð«óÿÂáðµt y±u/¥AíƒöBê*<2û‰/ˆÍÒ¯’’HfÆÌšò+¿n¥¥Î⎲¾dK…Ü•žiIéýDŒ¥ŽñM1VÉs ˜xLí´¾`ÐðÖ�2lxÔ«h››Òä5{Úkd�igS­B~n²º‰ËŒ”†Ý®Öx”øx¢2ž¨~‘€gñ)´s>$ƒ&µ®ÂjúéìÖ|ï¦â ®ÿúÌÔvì`˜ú¡ìÄç9Vë'.Ê/ˤ.'N’ëþñ.ËËrÆPV'¦ó Í@ã­éu]\ÏÇ1� ð߈x6<ÁQb?_�'tY 6û(ÞÅ#ØÌ•Ñ­¥h+e;'U·‡¥ÄåùÛ ×Ýd,MhÌß&b2îÚ‚ØHŒz™‚ü[W&׺^º9^v� ^oõŸ0¹t9Ý|¸v§×wµ ޾* ï'ñ±>Þa^Ã�I&'Ÿ“O[øé¾ê¶òÎ%®Zý*"¨òmmTÀ�qiȸêøONŠ-ã�Ç{Cw—kâ�:¶fEÚO�À�ËÅ.º{:“LÐSôÁ¤þãÚ�-HPÌyVµsÃÇ·:Ó�"Ô±Ys¿”°U¢‘1œSù#�Ö {�íe½9(´ú~É–‘�Ø9µÙh~ÉCSyÌ7é¯èMœØ-]HöAŠ–¼º.ß~R9'Tzâ·ºWª™Ö=ßšJK}{’¶(5Ù¯íp÷æK¼o#  }ÍçG'ï5ù±¡§Àqgí<½u)«Ýšg±Þhg~¶?yOK:`k ßċت? ÂŒ¦¤ŽDÿE‡ãw{÷ü£r=ÑÆ“Ðù©m-Ô‰ ðW~)•`gЙ$[_ikÄKÊ¡CÜ;´ÔéêWøtNq+‚3f²×´'�"“¹Ý8ˆÁ”aÆëú”.c}ÑÚï�šÆffn¯juie÷+·ë ÁÈ [jûÿ—Qv“¸0âåƒrË»ê%-à`Û줮öЪ†iÚP’ÿú¯]ýwc&Tí*T¦xÐ01§ó«Š£ŸIœœ$70‡¹˜ ’õI �se¼†U×^¡IEî³»u@U¾Ø±KöRÙev{Idâ¬í`R£"úâV­ù¶õxµp#W‚Ã_ÍÀGóy"ÁÑ3®øžBž¥c L0”b}|ùÿèȧoZrÅFZR †fFMi‹Å‘Å%}fžUãÙZSâ*PÌp/êêŸôæù µûFÞüs­Þ½xËp¬([÷¢Û_§›ñ¬Œ[ôAÕõ¥‹…Z]-ö¨®~ý6X(’ †î ˜âÏZiöY)L+è.JGe™Ý#c#ZRãcÍCgð5qr9 ý¬M�àP�¦/Ébã­Š™Ü‘�S:¬…ؘ-6j°Éζ42¨§VöWÆ‚²ýN4•áݪò4¼›â{¨Ù@“_ËßB•¨›³Ô‰áK‘Q=¹ ¼*Ï÷éÊùùµ�ÉŽ{j®{VmMã38¾@ ¶¸à cï¹£æ½{h¹[v�æ¡èùĶÕ^Ú*-[Ëè‚ÏX™tWcu‚VÔÕéþ­åÓ2ƒ½ÆkÜ‘:¤¶g¶C«‡ñ�'nYvÔÁãgÁáTž¤ElüÐøXð´7zòHQÑ[Àƒb'ÈUâtí€dEÉŠº“´vÚô]u_,(E;“£%Ù�°4‘ÏÇrÙÕCR0Ç„(7‰v¬v“‡º—î)Ðݘ©”Ê8s@OYþÆM¦[×A™‘#Ocºy†�_U5ï®å‡ ¹G©žùõ°H¾cG xù’£ƒ«=3AÃ&ëûý¿¾A]�¶mĨ/Òdæ<~ ¢ ž…±¸d/ùÞé€ÑEÆôÄ~Š—"eÀw¶Ó–4Úûh0ºcöõ#-i9…wðŒì²ÔŠe×ï<º1ê× ¯¯ïÅ­ÀÔ5·61q`¯–ˆF¡µè˜�äºÔÙ…½ÿ8™ah�…iMd½I­Ôûí&,ÞE¡Ê…‘Âr�:$…ÕÀú0Óù1ÉÞA9Ró‡´ú[}y·IUáƒÚF—V&J Ak(÷‘„‘ùõçúíÖ‚àM­{w3·¨!ßc±>;œVk'¹ ù‡S¾»àÂRYH¦žÄ{WL+�®™É…¼ä|”æ—õ¤6ÎÞ \,�c™XÿÞÑóŒgK§w+cÒóËÐÊýÀ¦àt¢nñçZ|¦ËìšÑµFô=LE}™ÖµIÏ»ƒ²6æ¹ã+¯(a‘Ø æaGû.§+öò¶ ™ §øàmgãÏtÜúyLJ\ö�:£R”±„¢ØJ(øÒqÂÍoïe—¬]'ö¡pÓðò°‚^èb}ìfSc8r�k_L#»)²á¿è†yH&c‹×“ zŠ—¡êÝ@‘о٤æfwg<ÉThIE,Fç$¬­ÁÈ y€;úè­¡ÍpiGWyÀ7X•–ê�ªc[ÞßÁnÙQâtÊÎÍU%*‹3Î?Èñ‘ñdÖá¬vý]�–;]?q·å.D¥?M±%г |�Ý1ö†߯ÃÌÖú”ÖNÏTuå�Eɨb6âEN¬ÞŠ/à?'ùëÒ+R¶T'™¡'ù&™s’®4p¯Éôo�ŠBsCÑEñ„Ùx�®“Jœ¡y}z0d"·Î}@ÓZÉ ÎŽvlp²&ZKÚMãÛ…?ï+S5Y )ÕÔ(¦a–eU-šA�X4\Я,‹$2P€)èÊ¥\ÄÃɨ>úó�xMŽtl¥jüNÕ�ÿ·:½#§3LK"ºk gN62´8}‹Ã¹oE‹¾JÕó®¥ì-®B« ¿ª³\±B?ƒ>fy9áÓéÿük:±lP)i™õq~*4\5™Õ æT‘Yî÷hf78L*Í £›xQ8´¥Quþ�ä1îÖ¨_ëP18 •ØGØ1ÄFÂ7ßÐ_K UaÿÌáü[!]™œõ)‰\ICÝùÁ›Y:{UÏNAy‹Ãd:˜røuftçˆV5‡ª‡”(PS<{ËvòÖ–geÒ襤ñÎ�ªcäôþúˆïhÅì±14U£B›%¹“>ZÒN»†–±¬áX¾1†x=­¿Ó†½XkKR>ó^àæ î5y·Á¶»ŽŽ)Ä�ÍdÊá{ÑÏ£µTuþxh@8VÖ³�QË;}ˆö8éÇw^êxÃÞ�‰�f†h¯èƒ¾†¦ãK…ž£Eh0¸·%iSCºX‰ô6”�³äÚ5vq“ïõUêKo{âë|¿e ·p{,f~E¾ˆX$~ 7å'>vÆ'Éòz<Ì1I ÿ§˜¥cêÔí|zØüd{굆¨‹xGöNa=J‚»ÖçGñ / i½]|;³0®…›ò"nªhÐÀ1ROfæ¹qSX4öcHü¢ ôÊ•Þr¤ÞZŸ� ËÁÓ†À vRg3 ‘Q<û1ÝgM>²:}1Ç *Æ7â—É~B—l_º}ë&uÆ0ÏD<üþï9œ‘!ºu·Ö½>zPË]p/��[ÒÀ‡Pø–¶Ïí¥Ã[Þ¦"‚L0ôpÇ{YýíåUí©ãºÒÐTÛ­•ÌE Øp>1«ØIœ®ˆ ˜@âáhþ�G» I•ÑU›ï¢åŠèŒ’�¾’ÜÂÀùd�ñs�@"üsKÊòmxPዃü†6¦4ä¼ðJ‰ ÒLÆ µy˜àŸnѪdÆ#ni%#-<®X[‚PÍÇCØEü^ÂÔ˜dÈ$¥õ-ÃÝ,‹ôéÚÙÌC {Ù^õdq�ßùKi'«Â¿ÖµÃÚç�ÐÚ$5øþЯô`}Lr+·±«À£©Gê³IklnÒˆ2ÖËnmK)÷üwhÐL¢¯ÇK÷á4´ìµÚ\7Ÿ À>¸bÏSP2E´I!}.&qéMª AÆâTPhq,jº“°·6E¼Ò³PHo€ªZñBžø«¿3ŠOóÂj—½QRm☿HBeÖ§W®K\ì™Ø(+“º£O°gÄÈí*Cî·Ä ÿåç£õ�Dl øx/åÎÎû±¦ó)Ø·Äß~ÃR4h��ø”؆P% ÊÎ!ñoðÞ"xM,ˆœ¤ÎW¢Õ‡(BúÿS†¢ò¬+÷\žç*žøÝ êÐi¼µ:f2£¨È”Õ[ ˆ^ (Œz™†â–»šg[ÈרXóŽ’¯aÅ‘q˜‰ãEÚ£èNnŠ {©Bãý›mOàêó1W¢ór'g¹ÔŒÊ6²-æ/ΞWaÈY)’5�Ñ[ܲùš­g ÒS‹o�ÎJœn‚Ók4ÕÈÏõ„†±Õ'}�á:†eǵÝEÊÊâÇ ä vhI¶Tò´ƒJ øsㆃÖiŒàâO>¢“ø %žÅ)y¨3Lá=Q®ÑµÊ‡RClãJœtÆ<‹ ³Lœ„–LZ'…ÇÏõ<)@ê¬íúÍR"�±¹m Ø,�åÃJæ�˜Zv*}ÒÛmñQ™P‹¦,¬ž¢¦r!äÌJ�Œë ®ãU^ù7õ´¥Áîð±ÕqüKÉUé C/(Ö-‚i‡Û¨?ÿ5}®µO*Ó{¸+÷2“ûîÁç°Ÿf�]K(qb 3ñöEúûG°=u‰–Y!máóe‘·ÑxDnHd*ì8”E×'³Ù¢ d‚iïŒo9TRïöæ;=+9¨)ôiÙlœÒqB¾Á+afn™p¸ìþ%Ôß·­¬ËEIQÊ©­Â(Ð=Ä$¿Ë~­ÅÔÒ³Æé`wQõdAáF$JÈëh™ˆ‚kÈ&Â^êLÀÄÌ€‚˜r�Ûþ‡v+ÒýS^7%!ÕôtSÑm ‰OÛŠŽ|$““xÇ›<+è~Y‚ïfa34(‚zƒºÅk ¸kmnƒ[–õl=BC^‚›�¹X—L4ê2b²®»Œ¤sÑz_M[SzXô"¾HY[ai‡°Þ“™³Ú¬Œâð,¶4¾þ€ÖÚ¶Øð¾©Htw}ƳÚWC^¯ò~¬/ tpu•Šß_0ž' ŽãÔ"m_æ�Ü[­IÏEÞÅÁÁ@V ´²Zœ—¸É®:°_(2CO2 î³§Ñ�±±ˆ�‚4Õ<ªõ!‰­PdÈ6Q'BF ¼,®]yS¹Pšà“‹ÆSËJ;}ˆõË·ÁJËlW3¶/7Ïæ?ÁÄÏŠhý_ÛZZßà‡†s¶GFÒ ˆ¼qÕ O-2¤§¥À´Äz·Dnh™òÚϳg½ �ÕÇEOõ ÁoC'Ÿç¤�º9IOœ•:¹BËCöÊ,Û¿déËBiûOuOUÛSÑÉ]é�Š ËÇŸ ¸§+Ö¦gdÜð>£%‡sì�t_õûQîÛ«{Ù¨¶lm íyy�Nˆí?™ÔÑÅŒª'3L„Ýï~FÇ ònõúÜmmáv¦?y2k„¹èœÜñ†ü Ë’Æþ¹P¿úãHú}ž…¶‘@�/ôp+ðáú@”ðyú÷y.3šÎÛÂèá{úÙiÚY}‘ú4îÖ€å¶ä´¯jà*ˆmø¢£—®Èá1=‚4¦nŒêŒWªÒª3ysèÖ¨;ò/®K\r<ÀNsÏÈ\ݘe¦<Tõw\'ú Ú…(r¯ß*(BÙÍé±ù=ÀûÐ}×òœ›ãe©³Ù´–­‘¨?¦“É(Ò ¯ŠÑtró{3ŠªZúth7è¿,sdÏÞð©p”Ù>þ‡ÙòÓxy!u^‰÷b¹ñØ6Aç$äÁG†mne4[¾ÀêWõ>�~”ÝSöÿ„]yPTwž×Ù¼ŠI¬T2³•©še¦jk6É&Ût¿n^Wjg×c¢™�DÇ8fvwf§ZèÑ®p8·f²Ê)‡Ü‡Ò€r Í}ˆ\P@úu rrˆœ*rˆûûþºô¯yÍüGñýÕ·ïw|Ÿï=HÍg”<«ƒ¹A¶íQ¤æÃn�æ0LãU›wwìøú”Eg²¾ª73•¾Ø1ÖTNz ›ƒJ'…4ð"@ �L¼¾DLÎ×�¼nÏ-ø'_ˆ¦§{*»j»M Aic©’-UJ6ôò;- UMÅ$½^ÐSÕsK�›‹ºqœˆŒÙ³ïÌ™MCþVÓ,4·3ŠÝ[vH½.&FSÜã´Z­žšïî+©+è†(()ÒaO¨œ¼Ü­d⼪‰öõq2ùÉÑ‘«†$)×ó»1¸ÂÙYHÔXî«Ø,SîOh_GŽ“¡ÉãÉ=]e¹t{ÆÐµà||'$2‘í>>ëNPy�!|=-$Âÿ‰¼щ:¯iz)uQ_Á\6¾H¤î…BåHS9«ðô0¡â1fÑèý‘”¯W/eùëG"éTõtü|0•02‘Ýaw¯�Lq B²ž†[@|G*9I¥9£÷´±t]`DØ,0”�K×W^Þ^^§^–H¨fìJ,6Ó{‡_ëÛoÐëÃ>YS XÊdFÂQhkq¬�jbç‹ÖðŸ�¢z¥|¹¯±<•.m›ºœcü\„)£‰�ëØòm"?9X¼É0–ðôö©«u­TBIæ‹úHŒPDޏ/Òý‘ZwRá!¤ý‹Íûûø’¬�0·�¹øPOMfÍ�Þ 3NQ uÁóŒRÈš€É&~çö õ¿�Tê|¯L^ˆm¥ÚóowV^~2VÆîþÜÓEaBåé%Àlÿ¤ä!ÏæJåPñõ6-•³´úü~¨q%XÖ´PþEå%¸¬y¡qqÁNŸ8Sýt)l‘Rg½ªn é6Ùiùj¢–fD£‰ÖÈ-c/Ûß’áAÃ=åEÕMí”o|S²úœ$F$Û~†d…`kLæóMÑ®w[~ Óâ}[ýÛ¨ëkóI~0;†‘Ù¡ }FîTBÕ…™�Î�o!.ž¡'¹75—âÛ©ØÜûWï-pizFl²%Eº“P‘7ÑFð;PDMaQW¡¬¦|­ ›¾=>]7j0æÿ²v‡ÀâËw>5W!0ÙÄo ¶þ_Z˜yRFúçÇ´TË@Úêê°`´ƒKKØCûr…›³@8‡l3¬øOæwä'§ª×žu¢�)zx÷±w¢“°¶Òs” ´¡Û褴1Šs"…ïJ|ajuP>�ÿ 3¬qó“:bØIh§"¬}ÂÓ{³¶›ÈÀȪ¢¦Ðž6êb×õÈ”>n;ÁˆßÇm'¼•n`ˆEo¬ÂþŸNÿø@¨ÅÆN�O­"Ò¸‡Õ7¦’èë¾éšÚ^Ø|†eDôqï3J÷­vIL廿¢™öŸ#Èש£iëíTBïh[f‡ž|™ÒwTÖÞ\<‚/ˆ.âù@ã}äUZ}BlbÀB:ݼò¬(©ï=”f>æîjqˆŒÿ72úšÔÙ³ä†4çF¼Ì¸N燴¥G#‘Hβà\D(O@ÇÁd>m “÷Å…/=Ps-©(‹£ZÒ&qpÈå-½÷k¨Ÿ�€ÚÅÇPvÒÃÝS¨_&»½´;¼Ÿü½x¿×-/º¨G¯2 gÛ Ð�C$bß;~ýÒy7t³ì\Baz�ßÃc·ÿ=·H³&w°/òF;¤3,û· =NÄÈv!½Ëù±EÐ�Gdp(�Ð52™™^CsEW‚[ ‰%¢ÝGaêÆJÈæ ›IjæiX¨è[( ¿w‹žÍòK½�Ï.Ã@y×m’ ñ 3óïD·‘ëïL\¿�›-æ¨ê ‹Âî·U$y¶Uá¦pV؆yy`�À®Š$f3.úRÔÆ†Ýõ~…îIŸž¿K*a¡æ.W‰Õ‚­žaú‰-*ª´ �ž´QµQ5šñ»\D*¦�|ë&ÔNùËNý�È�×ÝM1=픿6t%µ–”•²â7�Ÿv÷ö„:>Gßl�LÄcÌÜ\)ñÆÌWÜ/~2˜ÝÌQëeOCÃ�©ÚHÙ"UMᬨŒÉÖÏê/� —–Aâ¿›ó±©ÁU››ri¼Þ€ób¤ŒÍ~o„†Ü¶ÊrLåÃćWRÙâ¢^/ôßMµ·÷ßy줎rV´ë¨ zÀΪ”çˆ, ™mPÃq2^=åi¾¡??�îi žåðÔÄ2‘�eg�Út˜fbög´†?ÿ/ñ<¸ÔÚ•Ø­¡§¯ÎäT3 |Ê.lÆ6–¯¶bËygâvè7ä½_hÓéÊ©â¹;7jîp&R †ŠšÒo‰ñ²‰_öÛ;v|oÑLF Î×ÓÑ/û›ª�ŸXŠÄϦ[ÐÖ CL®ýikÆ9³gß)w€`àkÚIˆÞÅGÈÓÒ+%×F/Ò…úâˆÊRαô jI=þ?Ÿv�ÀÈÐ'äöúÖ­µe騖±ÈòÕãýp`Œ÷Ã]@Äd>Ž­YÇmòm}²ú0¿_Oåd–Í‘§HôFž€¸=œUÂ]Ï6;¢Y¼ø¢¨Y_ÄÀã¬Ù.*¿)§n¸²"¹œÙk aªÊ7–‘³Ù±ããOHÏYâp}ÈÕ(UÑ‘»–|E +£öý/zµ’$­¿œ¡wM*ù–d.Õ]{ü”£*µ—sË °Àf ¯‡“ÂYà¢`ªY'ñ´*#;þ›Ë_Þ»™é£§VïÖ÷h°te¤{�±íö¼� Úû”Àá†a|Z$ZËŸ†’�9Ú‚úo7DÒ×¢âÓjð«Ê:Šì?9+]Μ†©’3 ›�ÅŸüœtóÍ,<çúµu=.Þ' ÊX±˜�–08¢@h»ÙÍe2ôÍj1)ÄÊÇ+´:¥î~Y ÁBÌQ*ã ³ „¸c:Ÿû O¿#s'¢ƒ£ús{‘Ó~ß\” /‹ƒH.Û‹#p`ž‡'=TÊ­�Àð0눉�wH\4ØÍ�ꨡmÚ€\Œ¶% CÿöŒ`_LÖ¬P{?šxØ")Ù.¥g÷ܹ££*³+Zgr@úŠX‰È�J¸êEe�lâ÷þ›uty~™sU WÖõ”úfeW#ð“H¤,k •¢ç‡É|S„Ÿ, —†�–æÔè©ÖŽ•›97 ¸±LFS�¿O Ó›Ùh¡^Šf×ð>éí˜m¬zÕ;£¥F{ª*¦³ ¸kx§ 2�Û)¥‹R°oÖ†äøÚ‡®O¤D=ºÑru�Ï÷U’Ñ,%b±È„#¬>x�‰k šá…?�ÑÞ�5¥ÉÅK�ÔÝÞ„[ÍÀ•…Î{þÓÛÉIaM_ÅC¬Ÿ¥vô°ùKÉ{àYÓ¤+A÷ 1U?�…UX‘£w�<¨rêè!Û´ÖÝBËpù;RÍ~5ß:ø!ê‰>Í`†é kw\é ÆmÁp^<¬ì_Γ ñt.«! = ºç1¥é°H÷€ºÑn É ˜µÕú*Ô¡_ˆ”’FÕç~�'32õÔ\SôLüœ¬Èæ3${‡©¼;²Ùß’‡¬3>­³º“£Bbg¢opË£ÙʪÀ#xg?L-’¼UMuñÏ c èºÅ¸‰©ëp«¤,‚Ÿ{¸º kLÞ¬ù´÷ŸI’|§¤½,IGujïÌt¤�üƒºHô¸>yÛ šVcù$·4×?}­¥^·ÄV.¤Â1Œƒè-'í˜ÎCN,7ŠÙ¬þhr?¼L~syYÚ0(gí·¢Vt)Õ°,ƒ”³Ó דB}çÙ oí0âwûßw()ùù‚Úo�£žæõ¤`~`˜Ù³_áâ|NåfTÈ´†‡ð:ÄS÷ÖNBë‰�î�_|®¥ú'VBÔÀáöÍýʳJ—óÖ —l1 !>Ã!E^~¾a ®Ë—öï©ÀLBÛ!•ñ›“Þ¸š´y¼$MÜ~ ™‘¦Ç“O9Xzé£, K'—%'c¨)f¥»*7üç‚>^dý-#ÞÿfôêÖs*4S•Ø›åÇ]3àâ�ȯµÇ-Nê|ˆ7^’CáådF„­–?ïÖQÃÁe·V’°^àȲ»€™Rw\Ý@ç±âôŽ; ŸÖJR†S³hõ¤®¢/ã™\¶{‚$èÙ÷òR�z ¦ò/ZØûbò{+4ù)Ú‡UøLÓnv2ˆX·=æî‰4 ÅÖóŽÉ&~û¡�r3Ù2¥jn6òñm=>ó<»õŠÕ–1v|Ë¡NÑx„õ]Ú�f½çSòægÆO?Ð×ë¨ë3Ã7n]ÁÚ‘ÈQLuG°GêÑ4çchIC,ô˜pŸäEN¯§jëkŠB�å8ßEhº˜hâ6ŽØ¼w�¼ñ�I£ÑþTÏ|R æ&•ËebÈ_èà)Då÷‡;LL’~¥q)^· £Ò5³ó¯â€Ÿm�Í$Ö=Tîiê›Ô‡¦÷©-'ŸWP2·†°|{Yfô\sb€taÉÉšÅôümÉsFù¡âïŒÁo5ꂎJ,˜¹ddéèȼƒYEºª—U‡0¸½Ùô'G,¬’7Ö}fGÑ­ÌÊ ŽÅ&p´€¦»oõšâA¦Ox‰yü†LiRO&5,§ÐíCsÑa±XsppÜý�nF«œ` Ú>\”ï²Â§Œ踪ËtËRõë@üCЮĺÅîssö€$Á_o» ýŸïLÚ²Fh;ïsT´oüze –vP†MlT·SFð0ë«·9Óä3z¼üV„¿Ž*¬ˆóÇ žWz2  o3žÿŽ o‡¡@SÚ¥§¢k¢Â±A½oâœBûã`Yt²z¢1æ0>$Ÿ¥°¾Ê¹+7Ðc?t�Ó†ÁúBì/ýµÂÅÍ[ã‘¿`ü3(ŸW24œMOMFÇ´< †å•#=nØœìÑAsèó+û[§ëœi”X¬ôé,å8jöù‹å„`,$Ð Û�…ôñsjè¶áO|±Ê'ÍxÑ1áÍSz-”4Sd0ubßcJ�pwS9 ú»7�Èç¿2Þ¶oxÇXøƒµu÷¦f1;Ȩ�ÊEïo-h$¿BpÅ NÅC·_”¸_’W®-ôÊ‹'c×éÔ¦ËOÊ.Á³DÙR8{B#026…ÝÄW¢9ÿ8ƒtOÔÞ¯JÍëÓQ×ZÖ³ ±�Fì ¢œ2ø`šYˆóÏžZÔ$ÊÓdwÎi©¡ð˜@_ÌÌQŠ0õo«i¦x¬— x’%—“¬Ï*BHª§nhÁk„šíªÀl—†\‡� ˜egd鯳ÌÐÄúrÔÐz[ÏK_¬ê"ÕðG'TÊsøÑùøk$Ù=Ý=¬l˜qô¶öêc‹t�~uÆä:ÅZµ¶ßÇCHå²½‡N*ð_XÇxØö%|LNVÞÙV[3Q¬§êòFŸqðS2 8sŽyŸT9»{»/K¶ÍzÆyá´�KOÔ 5Y¸hhõÅpTî­ \]•R “Mû «brMðí"ò×ãÂ2Ê èÑa™…>ØÎJEošß6� g&î~oQ.×pW3RßÍQܽ›—F.b‚\ÌØU9¹ÛS�êK�G˜X¦".9 {‹ôÕåEõµ:s[[¼Œ·é@{`+ì)<œq‚Í–-ÙT“þŠØx¦“I=¡-,Hç¨æØ�—ÙÀSÌ îmÞõü±©‰ÇV[#µýN|úÈÂ_›R«™á¨ð›m‹qx�¤b¹Ø–ß÷­ dÓÌ]w‚$ûŽÌÇ&/T ~%yE¯`g9KðvVœz5‘切üÔÔ €o:·Xq#hi°“ ×h*»°{[.{ç ÒS þYó8Û-e©7W¾;Æ"ódE³X3éÇQýk>¡ XHÙ®ÏÝN¹(E ¦óÆ=Äãg¹$r^~6”â[S@‡ë›^€¡ƒX&•Rç­„ `ºÙ ?"3–ËúZênÒ•%AuÀ!mrM)[¤ñI²ÙÖÛM*£ˆGéM³ÍÍ™tmÛˆ&x¾ wΖÊlÁ¶Õ’…i|ŠRn¹¤jZÓ¸^_µšEþ?aWÕ•æµÇ÷0F“ÌÉLNŸ3›sΜL¦;EQg2ÝÇ%&éÑ´Ý:“;3™R*JUžBbœLú”Rì Ê&X¥È.û¦à(KUQÅ&P €‚l²ËÜïÖ{Ô»Å+ò�x/_½wß½ßý–ß÷ûŒ• �Ó LŒlÕm,�ONO`$Ê�Ä–�¤qœ¶Xÿ 8!Ÿ6†ç^XÀ” ÄôA_ï“N*'ñº�„´9p\éÂËòŠ TFÅÙÐ>,Ñ ·HÃr>‘ó.Ü츠·þÁ¶¯¿b9BÒ«bôôƒzÍ…¤øDJ%²Í{|1^å´C)Œ­«¾!ícpGsG”�j^²æ,Lb%,†sˆ”0oНÿ{N“hõà ½~¶ÌD™Ï6ÂOH0m¶ x»|K8œ$‡Ñ¶ª?iãÜgy¿^ÔO¥§œ1Pç,+Kù P=3 „Rõ_ƒIÙ:lûîø§š¨ˆ©U˜œøhtβ$ôÕ)%O� ²Xnh5¥ØH`¹‹Î¿,ñ×Ó+ºÉ±F�†”™«`Ö§WõéçÃç�|íå_¼FQ—Z›j¬­THrKý>µ2!”)+•H>O Â‹ÛñÚ† ‡�YwÍÿñ+}êÙØÂõëã\ /½Å²•;UxÛÊ ‰JùˆŒóÏ]jîA+›^Ð;ŽˆÈ�ÍC:Uþx’óõ“èÛÛäýr>-¤Ëh¤šMO¯�‚žuÐÜ>ä,Èùò2x˜õó 0VGò¯7ŸÕ嘮ӱ ÷[C±Óànkox�¤]ä`†s±[œvZeÍû�|À¦â±»íÕªÏ08Õï‹>« ·‡óÆÍ¥ÖÖ JV»ÎïF2Äe$faIWáÍ‘j1~¼±·ßfioî—+môEÛw)äG�¯}oÉ“ýö'òì<­í}Ùi ’›ÓSA¬Pæ*‘¹Øluž>Œ2âÞCŠkHqÅ×R/$g(¿¸PýL\Rb�Hä²[e£¿XsKÁ(›ØSW¾‘Àrh[/Ï_;g J/GdÍZá(º¢?ÙºÓK¥ôPË�$žaÊú*®Ø¡MyGÁXRP�‘2œ�ÕágdÈ÷¾þ¥J}ÄY†Ï`KY‘¬{¸øqÝ…�—~h]›µw­xƒÊd¤êOñc[ñ0#OŠDÔ~KqsËÑ7—¨Žé¥ár«Í±’ ·€cõ R%<÷žÀH{âÔ$©4&§üËB�ÔhHUxn¯…éùÚ^_¤ÐÕ|‹Û2ɰV’Fçò|xPrø51Íú î¨&”ÀÐ&<(;<ζzG2ÞO%-žW×/¤Tø›(Ã휼‘ØL71¤HÕ*^¨…�cü*óÛ!«áûË‚�g_ù´¦³KŠÅÂÍ»jµ'Ÿ'�‡YkD4“dùšê[µÝ¡)®êyRWtë±]‰[�pªN¨Óä©ñ‹»5Š!p÷{§A”Þ.;Õ'ÑöåC'Ú³­Pÿsü#²‰XÀó;æ¦P=~®§>¬ÝÂ@n·Ùª&vžô{‰|@<Áù™Nët/ò™-áÑCççôthjþ£n ~}´å¶T®òæ:,�dµJø]¨Üú�t{2®§GåAnËPUUmÁ—®T&Ù‚+¢œœs˜À&[��Ü­$ÀäyÉÒµø…ªþlOh(HDïè*ÛöG…R*'êÏa!æHŽË™Á¹ò4`öE uWÓ½ÙlÁ ,ѶOjo•�܉P<‡COñ>SÕ|˜í°1Øva(OO_©޼ B¥R(÷8ä{ÈrÈe„çÊ­l¡¹O{Œ�f>H¡ýM³æVxd™ÈUBÿNU Uª0Â2‘¡'œ‘¸�¶–Ú¦'O ÔrÑ‹¨”V¬Ô„bPjâËwé W½g ‰Þþ)ïqrkAU£�*ŸhIm0a{X†ü<¨Cæ;À0gãÿÇ?�NMMnpIe‹ž®¾8?d„��ì]É6ÜÍQΕÈ�Ö¿,þò}Ò’:¬OFj.¿&(³ÅÂðYºìTÊ�+<½y«]k‚Opõ­MdÄš˜½�‚,DóÌÙÒfPK®b7¤ä为{mݧ�&îß¿ù”Tr+~AOg Ô|ØÍJÜd¸¤â�J­–+�òµp·?¸YS.¿ š‘Iyù+ÏÍT€þjc{#Vš‘ì�ÝÐÀÝÀ^Nò?0‰Í ô%¹!£fnªÛ@M]¾U]×h³W�:9%÷ôÄX?þH!žÆò#Á“üd§ 'b TŽ!þA[ޏŠD Ì„AñŒõ7@Îç$lÃ8ë¦8\O÷꓃ï4`õŠŒ"†èh�Ú×Óƒ‰Ú:¨Xן ƒ–’;-îUéËÀgª:Â?r¾‡¥@0rú„ZáÃsaIíœ\ÿe¡L˜œ�Ú¤O´´Õèèh]ôÊð}8½2¡L¶y¿üˆ—b sþ¸€AúɃ4(Æ.ç.Δ¦Ó“ -í¡÷±¢J…,b¤º®B¤R (þ=òë5§ú_ÒÓÝwç´‹wm í*dî1–‹Âq‘]×Q�Eè©OHÈôyIo‰&*ÇHÝ�¿X¯Ã?‚´Œ€þ=:/ÇøúqØ ÃÊ‘€]L¡9ûÉÊâoÞ)�C;[“–ÒS‹C î¡ËÁ“¶zkcvÖGpœO‘yíÚ°Àñ¢~´¡ëËòÃAœÈ 9Z[Ùv ¼v žÂB»�˜K;È�X® 5P�—gZŠnƒL@åÇ _e=d +�€¢'¥E•VäM›¨œ¦˜›Woão$è`UñÀÎ$v‚•Û?öÁ},y¼<;ñJWÇܰ«‘Ï„útM„žňͯ¶ØX®E¯;Õ*xx}­ö!©$̓suC:›¤)è©€Wæ�}ž'�{ÊùCx†ó_yY!�‰ ýÒòx¿¿‘j|˜’п"‡y«M³oÇÕAO�´”å&”1‰Y¡ ¯¶ÂCŒ¬_¢5,ÙM" ´/3®–©î'#õKÅø2Gnç[‡|}N"cf¯J…¾/˜Að³¬ï~M>vlØhÑ„ŽN¨JŒ+/Æî%6jøœ�½¬ãK¨cùÇ¿ ÛC%=»RÑò�¸ª•Î¥BœÁ@îò–ƒ d.ðŸ8<�Y@naÚ‰|ÁfʺÏÔ¼j¡V^Yt/@¢Ø]ì*z›)·â< «Ø•[¬WΰÂîeC¨K—-O4tNiÑJL¡…i…¾—“šqÑâœFQ iã!Rw EÜ×vÏ"]}἟¹À–´Û0®ÞÐJ…/Èéóó÷HÊ»®‰è¡%Ç\<”¡§³ò ï=ˇ¯"‘ÉDo §ÿ{…‡B­à1hñŒõïík{Éìß@æƒÑž Ýg¡zuE•]YXy¹ÊD¯cåeK óÑ‘­"5§�”ÖÃdf´8;§z¢²•è ¼�…�[W™�â_`<Æš.èÞ}¥%ƒ7º þ¤œ#�XmºaS^bmS^|*‹HÑl¼GÆÑ#› S3Óô´©ãaGR&öCdn"ä‡(=¼êû�îüFáX< 3Ößn>äh+ƒgK-TuYâ€î΃‹�øLéÁƒyÇc žÒp2‰™t1§bpÁDMšâÎé,%”l>è«tRÌÃΟ7™KdXYK$òì`Oib:]{e(þÞUl.I²M1¡A¼ÿ¿þZø¿O¢‚b냳¬�Fª¾½8+d Átys/ëK;Iü9Îß"IåÒõkìªé8[Dä.ÍW¤ál’@*Þºÿ44Åa®~V4�£*ß’“roöÍ- ½0Pw“bÃSl &�à-ˆÉIl†SnÏûæ]›ÍÁFOîWݯ2Y©À £AÉpÌ '²oU˜–‰ ÕÙqV¾H-–Ý% Û:+[Š{ éêÔŽ.CþZH‘n>¨Âü“N8CaÊ:ôÙHr™Ï™¶}z4°©�ê½3x' ÿ p3œŒ¶Ø3÷©¹åÝÐÚ쯗Ȩ®V—7g´PÝWoÖ×_²+sZM…�W—ãUd(o¾eÕl‡ÎÚ�F‡tW&&â¸ú ï@w¤J¹c·—üôŽÝÇå^ßñ8ŒxæúÛxÄ�sÁoÑ?K›a¡&‹úãKpÈÊM,‚DÑ|=•|Œs®ùf‡ðÏ C�6¢OG>ŸÉIMÀçbµaÀépWŠíí ûÞ‘ *¾ž[/¡ È�Ö�C`"™d¦âûØËÇSÉG(†çpžÑûò¾‘h9e¤2¬ÉÓ q8p.vnÙ­ò8´Â‡/xnoq“ÎbÛë†_ÕäMä‡Ð‘׺:gâðm#� (dxi1ü߬ �üø?dÆ:»+/µ>ÇJ5W¶«ã°mè&oc•âö/pjîþÄÖÿæ?ý†dˆ,讹¥O§«kÓš.଑L,ܼS‰lº“ŽLµxŒyâ{Ð}áy�¥÷Œ�ä–©¬ÇÚó7/`Å"• èÏÔß{ò%Va�óe²m§‰-<É+h-éF_fF›_iK¬JdÐ^ø�JÍ›Uý9K¾{šDŸ6çdN‡†¦Ñ‰·#lhB‰h+�é*ÔÌ%™PÜÖu!¿B�ïÏ@Q¼Ù%7´Úg³FêJÝrg^¸Í—IßaìñÕ†ÇøÉúðäõMÔ?@žbÃó¦ÃZ±\0f‹„I%¸ÏŠâŸŒÇ9¥�Ï~O~UóõÄÐÆŒ`´EÒÎd€@¡ÔYO\2;ήƃœ¯š+%ãØsAõ#eAzz9ëÒK½öˆ@ì&y}¯ ÷XYûtx˜‘7„^÷ïÉ:%ƒ]íº— ]˜1¢±Ø˜/%.@A�ÛÐÙŸ pÛbÿHÆüV¬š´ûVª¼ìeh~°í¼ #ÄᨭGª¬Bë8Cª¯‚ˆÙéèh#•XÔ„qÈ,Üö¹âÔ Ü˜‹÷ÎÅs8}p“CipÞ„¿aÈH�Ë­Z ²*Å’mØe@ùz*¾å+±ç@èI¦g*kŽ¥Íwö›¨ÚÉ{¯â1C$’lþÂÓËCå-çÃv¢áŸ¡®|�L#ß·>¿_:×GÕ>�Ë`3™‚7VM&ËK´®ƒœjó_;4üŽ;k|xýÞ‘™�E Ы¾†k&�­emØÛK� —ÿÕ?“=uâC®¼Hh5R~C9åË~6ü‘š/óU:c»ÁSœ¯Ãq$?¤ˆ4£›¢ïßë³Rã¥]1cKf8\2!—׉X©ôõg´Ã®î"IÌš�d]¼J�¿™{”‰î2¹Ik‰ëñ(#î+$îòoHà¼VWДªë•Æ2ÅBw7Á›æñðô±/S˜“}ùnq;ÒˆY%¹†�TÚsµ¿`ØŒkÖ‘™¾ËS %ëÐN˜)rþ/ѳM¼±‰ ùÓXWÚ²-èµS³º—Ÿá׊ˆŒ_ûsÏc¾<Üx7@šEÞ‘ɯr²G³èùÂÜô¶!xo�À C¥‘S¥ø_‡Ü Œ9ßÞB/_@‚Zî> ì~š@‡§v£@>Z3‘€Ã|ÇÒu#ºDv~F–iï6uâ³é•ä;‰‘¶'–¸‹Yèƒï1è1Îß~æqÏ2ø56–Ó;ÓœÔÒ‰–"GWø|ÀŒÑ2"õñ÷rGü9p¾×9,*ì!Ðukžv¶]¦âfçûáp‚Í ûúðµ’r#ø g¿r@ÅeŒÌGµRç,SU± P*ƒJ‡ÞŠ£¼Ü¿2{û¤1´­º<ÉlÛXCˆÝȺ3Ög}f@ „²·q^Æý³[~™Öj9/ŸšÉyÔO¾!Kë³gâ_�•K?nˆx”Ù _ £Ómù7§ÄÄ„ú ”éÀÜ3_99—JćÝóë©@IñÆ*`— zÉ=abi…ÖàÈ~²ÕKíÊbRÔlÝ«__~dÆäQîLKSvg�¯oAÌ|çÐ{(60h¨*•ž(+o‡]&v…¾·rO5O£<È¡óÓHúA9Ï­+ç§Ò±a³+�ÍfL}#lþTåÍÀ+ˆd¬ØÞÈ ,ÏIžÕ¾ºÈ‘ÌN#õ8¢®± „¹JÝE’-{ä€Ï±ykòÑî"®EÿdÎÁVÜ3’M�Wܸa O]x×1²’Ð;~�MFC /úçö4]¢ ÓÁ#ÿŸ°ïŽkûÊò%EƒÓ6»³³;ï3ïy?3;;ΔHBufvgbÇŽ'qoì‰7Ó>OÅÖ#˜Iœý¼÷°éUtÓ{Ç#z5ÝTŒ1–)6Ý# ¼{®$øÝ²ó¯Î�íçžú=ÀKÌå ¸¶§/aÝÛ¨Îï‡=†/5ß;A èdCïÊ|– -æ6y\í%g^ÂãÚÀƒ O%‰�PMìNA-ÐÑë·Ö\\»q iŒÝ©éé'=¶°¬ß"¾6ŽÂWäÆúýËÏé—®¹z|kõQgÒ#öŸ8z$  =H,V¨“OL«½Ý­Ö‘o'’0&ÍL�åïÁçÀø²þ›VË[ÃW{ҒѨ!1d±³ßäM=pÂU~™4-¥�Û Ý I_è€øÌ•³É¨Î#_ÕÒA$šPÈíS|ûdSì*¯L–ä ËëøBÿ+ e·<÷Q~IG*êHWgz–PFbs?æ29 ÷QÜ€hâöð§/›¦«9¶¼âÇ7i.4°•œf¬E€šùýJ/¡™˜µá¡þ5ïP5T…Wò�:Ó0TØÒOÐG¡ƒ/ùà[ªlFhœJÏÉÁµl®¨—ZÛrៈ/Ôè¢ZÇ3|¤€cò¹Q÷0Ä êƒWù]ND±&1¢¡Ÿ¤/bõè�‹à"Ä„“ý%…’Õ¡œ|bâY†¬¬Š�ÓûÝ·Zw3íô«ƒkA€KÅ|Ák§@»„õ£ùJ+ ð£Ÿöé÷ieÚ3©ýzå$göšnu¤ºŸÔAq¹Xcm�˜‘àƒ•ÖÃoÑp6³m~�"ÑbLÊ•»UDoáI¨ÆsõbçÒYz«[+ëÍO2PIÇbàh…Q§Æú96¤�ØÁ"B1±šÅÃêåÒµr‹áÅ^¡øíkI©«*7Š}©�PB_è}BW¬Â­sŒ¥¯ðâxbÖ�Âd4<´9X¬¸B)VLŽ@3Ô lf„ÆÓ¾JgŒÆôŽzõªqÜSׂ}Ë@^ °Š¼ *ÂF$&Tóÿª••S>íèj½×?¿¨å$<žŠ/…M°ˆø6�©o¹°‚П}E ¿ïÇŸÒâ0slvdii’ã>’«OÊ!ž[:ï)¾<Û�ìšòÝøÐ¼ìlEáI$‡•tù h9ÍšùÉÜ4b� …RcË«SrˆcA”‚hªPØñ§Ï¿Ýž?¦åQ²Û²o¼f’Ó‘ZQ¯Jè'™{@sÞ2£ÇÎc$)Öà±§ËèBÖ‚ë*M[Vjô�ÜL¹ÖOZÑ“öåçðÓµ”TÀjì¢bu¹JŒ�»?™ˆêË·ªÉYÇÿ߆LÜF,½L¸ÕûGik43DW^“œ…ÔªyUM9îv|�õ{Ί/¾P°®!1pÎìOÓGt!2нm%E_Y‰,ð!æ E¶g\]ìeŽJ¥ ûMïùœ Ÿ]ÝÛ,·«Ûã ZNò­º–U_ã–‹ì-'RÝÒ–[fÏXЄW‹FdŽ'#uíØ�QobKK°öHÆkÌ? [!ì9^À��ÒFÉðØäÝêA-g#µùi´7QÌíø|›�íåxŸ-UHº‰!ÖD­‚Öèܸ‰Ä^±÷B‘¾¨¸:ɳŸ½Š¹6ǽ«Ä†´’݇šÇ¥\éù=ý|­ùMy\÷F%uÅÕýîý$sCÌGïûJщ»i†5ÖVV·_|�½ËëêNÏ[>H“]“½£#}í‚Ú p"-Ì™^±€éþÁiZ^¶Wl„b™Ôqûž!sS($R©ˆc¹9Ž„ö^ù›ÿD_ºüÿ¾ÕˆT´œ™z3d]ú‰��osú2>2×ýú‰Ý®¶óCÌf†Kog{[ð`âBjë w_…YbiÍ5ZD‡N9Êe.9‚1W)ÝÙô%.+cÿÉ\�:Á-g%7jÂð¸R®àõÓ®ŽÏ»:ï&P1Fø€ÁqADsLÐnT–yè8ýúÁ¸9hÜXë7ƒÛ[Èu$08þG�’š¨MëÓ§ë8Ñ�«†Ã�#¬s›c.öX+SX,c“ìñ:æô‡¬¨´Â{^UÕZNIìÖ˜û}dk󤂨2utùÜr!!›+?0‹ÈÇô�iÔgÕÖlù"MÛ²æî”Ž4¥æÓ-l=]¹tûÿeºæ �ßøÎxR£Ú‰Ö”Lê î%å 8ï`6Ô… ?3ӳߣŸŽî)ãë›ÞH»UÞ�: ; njÛ3X™;ªtT:]¦­€½Œt`&û”ÞÖY¾qåQÊ�ѯ¨‡u`‰ ¤üW?„É9œ³T!/dTË|ŒÇõëcôIΊ. œÖrýGú|ºÈ¦ŠÄ›cNö 'Å% È»„nbø¨»¢×M?seÆ�탶FC4�:ìÈqN9‚?ƒÜ”ìuµIÁ ÚÓE­Ë>qºæ1o¤ÉŸÕwèH÷F®Äö¤ü+Åþ˜¡1Ö­¢„vTL,ef ©ÀÜtoÂL`{ϘšLgh öüb/ã1m™™«ÓS*ûÆïLë8�ˆ›m0E)~¤Ñ'2ËØ•@|öۓ±²ZâÓÖr‘î~F{¹7 ÛN¿7Ù›‚õ-þ+ÇImÚ!�2”k�Pq�LVÂWÉü“º+ëEh1É£¬í¦Î©@'eÏêy÷-q (?¹' S\â"Û«½&ŠPM×ÓÄåZ"ÁøbîÁÓ®€yôl€Wòcìëgioq¢_ÝhƬ–“?æPm¼>Ð:ùÏô@‹• $ÔÀ§¯dÀàj¥þ‰7ªØ¾éÞYrÇŽË0£ Ìh f&8_ó¼ïë²bÔÈw§«¼˜ñ¥žðà{J4;ŠEÏ—–ÛyÀWÌÛÿ¦eÙÂ5ÿkÉe:Žjtps°œ\#¬ºqN)¿’]¶�*Ü•eOñLŸfÓšØ“Ž¦â‰ø!ÎVÒbæÃR�e®Pb}ÄYö•Å&�@5#ÎbXm¸»ÃÕuî¥>(º8±­¥žž?-Ÿ(ìÏËœX™ž„ÆìÒúèœÑ;«¾#ÞhñÑdgî Ø ‘ˆÇ·>ª¼x æN�ÁiùZw}’Þ_Yç�ÚÖÒÓ‡2‰ø'h{β‹r’_@I¥{¼éL»À&ƒŸæMGªÑNpwãdðâãe¶>�ÝyÙ3î |an§†¹|mGwžÈ©ÌXðFk†»s„¥DdÇG@Cgjlð;cl.,wìÏŒ»aWÒP×5�Ï­tò2ñìø¯½ãˆÿYš‚Ñt^o—e#žç±_Я€ÿý®1Ͷ7*ÔfÖK¾Ñ׎˜ñåu9tê�ÎS"èŒ1Vþ™¶À;}ÚRÆ|ðS¼š²¸šª# Ä|Éè»ü•ŒÞVB1±:‰yÈs"t#?e'ó­D‹fM Nc¿§[`U×ÝñP£Ž1·Òê¸�\‰Xø†©•¾Žr’c98"3oþûoÒšêòôòÝñ o4똗B]ØHzÆå}/!2uòèlŠ’ük� “œ’èNCáÆÅ*ÆÁ£XC%oŸË[CÈ ~~ïÓjeuNlRïÄgª8&eà9|b × h”ç”ÎX d»ÈæpÈVV�_ÒIãeë%ùcx¾MS …a áEX‚[Ÿ•]"z9S;cl‡?¢/­ïí’ñÈÖ(TМ•å ËEÛÏdß(•ÆK±Ï“D¾`°ôçÒ¯ÚBã•âp•7šH,ZÓª`£ùvBÑ?7ž~MÁ4 _1ã4jÚÜò¿6š¶sÇå¶m ? Ò™š‰ó ÎQ²@Léø?ÑÀ׉¡¹OftœŠôÎñ­@ã«Ë È’[€"âîU3ýO3£›V/UÛ×oÇø É–¶š¼b$aíñõß9�|.™ ‡™["ØS/a|«ŸÒ ñŠÓÔx£eáËÀ‘¡c®ŽPtǼ»ð;³‹[�¼3U=8¢ãÔÝ»r{ÛŸè0ø8�êV‹ö3!?[ƒ‰Ä³M¿’ nÉW3u�8‚5µð/°ÙÌçîŽï;×½Öv¯ZY9¦åVswÅÚJ–©só= ;1ÂÖGäx�”Ü"ÆÜWrè2ì6´�÷ ù�¶½‰µ ¾Öeöû ðÌ¥$£RmVί=ìÍp‹ÃÛ±“èÞœì„B±ˆsÂÕÙ…’ägƈ~äN£§E§%%§µ¨QÍÎôý&w‘Dh'ÜgÿZJ=†MúÞ?AA�+l½º\QÓ±æ�ê7—§»®Î"‰[8Nr¨�=+gÝ4B6�T…§ú�¿ kÀjó{7ºuœÙöÅŽ¢«dD|Á�#J�Ï–à€ü|OÑBÚST²Ò;—´í…’Û5Ù£Wt¤—+4' 3Ì£Üa.-™ú ~ævzõ¶6XÇ™R=¹;ã¦#­P¸æV(òs–Ú¸îí94.þÎÊ”•Ýá±XäÖ®ãÄe7Ž=Õ‚§HÌãC?„£²¿XB¦²‰ŸÏÓõ÷/PWzªKß´˜êƒªÖ»õî-¸Š@v½ ‘ÚU´70 fôý?ÑÙ*Y7Úã"†8…º‘uãÀ$|paA~¥¥N ›A ô:úݚѹÜ«Fy­áMÁÀ�gg‡Míoy�ÉG ø½ÿù º�Jâ ƒa}nŽãÞÜP™ùXK ‹EذQìAö²EùÂtÈùßµ²ª:LŸ˜Ç7ãfGÑÖoy­}U á-‘Dh}Dæ‚§}ñE>ßæ¤ÒU�… 2@4'uAB‰ˆ¶Ì·6o–âÓ>eXÖøü¦Ÿ|Fv2¡š“ôñD»iÕíÆ@\¡ÿˆÒ&­Ý#ìÄ€#€yýÕUq‰6»ÅJú;š:p™q„'¯,——÷ê8·7uíK°!<‘”÷]¢|8È}ì¬ü™Qdœ�;*¾¶àï�¯Ÿ{­¿¦ ý²”èàèO408Z2›%’ˆ hjì�Ù‚—ÍÅ©/[Y餴¦�¿Ñ|Ó ÕÏl\Sn�Èø ˜É�Æ:£12L±„/˜Y@¿¢m§ò››êÉ/Tp=¢ùÁC-Isãr��ÓÏ’p•*K¿þî:DùHÊ•oU¬®s6îªïkIé?6O(?ÿ|SJB31;ü>”¥µ§”î›ÅE:NcIlI0ðx|ÁÁ“Јì5¦ä Ë<ËÂ?Ñ×Úz°Ú­Îm zÏ­ëaýø€|àì,ÛŽ3mçÒÆSBHCþÖ¶�³˜¾²óPoœH€NÊ.ÀgIø�ÁHj*ap0G–Ûfæõ7u­¶3f{’Üf‘TôªÑÁúÌÌðͳ"8ü0D¿cWÒ =Fu>¨1»©(þÖ«ÅüW�ÈíÏ[rç2cÜÛG阘Lμ¢Ûâlä„Þé˜Ð‚;WŠžÓeÚz$¿3¥¾M[Éí«¾KáyÞh4®-­pXk*NµyÇÙє˔€>Ÿm¿D=-ÍkúõÚ^oT§ÖÞê‚ó‡e•ÀÁÊY¦pV°¬nµ9‡� ¹Ñ$’¸?ù’Ç£DÌGÿFß»ô¢�æmw´Ó¤O «Ô’œ})&O+/Qñò;ƒÑ©¯èìƒÍ‚À–áäÞ‘î±UN^>@�ì�ñ\êáSžFù§´ŠT=ß^7‘ŽJZ·Öý€×Û èWè‹Æò¼ÅĪóø‘íçíß™i›»ç�Ú:ʇ7ÔÚÝŒ|¹ƒÌyß½bæãø|d\,³ܹ8=ž©ãÔǨ5šB�Ç"¾TðÚo/\”;+ž @>bœáàsôÊ­ç¤E×z£0�Ro�– ú ù6Êœ\Œy”Ì•Ñ~Áõ_ÑYægHËEÚú€î¨ ØN�^¹w]?wd§ЉÕ=ü×忦YEúFåùU!�ÿ“�òt2,±˜äS»œg¹ …™’þGz?7zóÂx¡�ÚÞÒÚ4rf|É�#®`7°Â@a:¡Yår·CâWõB‘¾´jÎXaûL(DŸ¸ûƒu; ÍÄìטË/Y-÷PÕ|t\0j[|'QKš¶ó¹¯`ãÕEa¶=ØÆ‚d/¬™�¹,wÑSÕܪYŒ+DS;ÃO+�¥ÀN"‘vßvBaL5óM×´ïÁôäD@8ª[m×Ö%Ù! �Q¤k¶œ=8ò�9C êŽÅôâm¯Ü×ßJÆ2««âµ$¼Éã"ËÌ�Y÷L­9{}#;d j,m¦­m…ÅíT;F8]é´7€Ù¡;Ë/È@˜:~ᣠ€´­x‘²[[š:®¤.©P˜ßÌFv°ÖÔÇöôygùßä$å†5RfsRbiý%Ñ3ÃFÒ7·9ý)ñÃu*`ÈB¾íWrù¥¯d,ÙDh fu¬ö‡3«‘½eù¨qp0þz�–tSóž:å$B„lâ÷sÌèÎç´b"óD¶ge_ËÎãç�ÖØ �qÚž§O[{�j¡=l�ã»åñ(ÞЉqÛb ´ô:§¼ wfßཋò4°½;B£.hʧõ½^Hµ·‘8ÓG bD‚Gå¤�+M²£ ´šOiõxz5 éêDò\)/Té�•@ÀçZuTP>±Uc½Û{’!A�`ât_¶ÒÃôåÝhº?á�òâ†çn÷™`>¬Mƒj(-]+ã;fÎ3Y˜ŽÊIŸ™âø‡nOyôì#÷UH[�ËaôÝÓi¾ðÁó/G�ˆtãªÊPß�–WSF{aú;ftŒ•?»}?%53'•Ä--uÃeŠE\Î)9aû¹¢‰Û˜�ÇIšÛíŒåÔðð‡UJÝPK,ä·`sê÷BB4q[zÃÊjä-úMº“]4”û”Ó¼9>UÖDæÊ·ÙQœ3¹�¨Ýš‰™›�••ð÷ôC>ݵ>rËm´´¬uÖô‘P!WòÊéKò‹ç-äǪ‰ÝÖËVVµÚ†×í¬yå¡ÀßÔÂ*`‡o”ÄúS…ƒ ’˜é·HŒÖ ÇBy1s�±Ý~(°²Ùýq9ÌS ä Ì i(‡”p÷Ý}ˆ9 ¾EÛ÷–#×õA÷8þS;S%0(W=ãjï®™3|«Ÿàå zÛè[5ã�eVìd§ß@‹C±†'ÀÊN€ÿû›Ø$ƒ4ãr™Ã¡ßº3,%ƒÀÇŒ´¦ ?Ò6UÐ5ýòݬ@Òñ°49¸Û�5zBz'Ëä $¦ø'ôNÄ%ÏßIõòEu·«†Õ! ”Å\*ã좰g•ƒ×ÿûŒ•v”ìÑR˜…¶Ú‚úÊa'ø<žèÀ;øÕQس•fB31³Ç#rû ­³ ªƒÖú5ÎxNTEÍv/Äò¸b¾õ‡ ‡}ÅáŒþÎß=heeÿ§¨a…,^×Ïe¢Ø„„¹é­^šØ�Ó²¿Éœœd¬—‰$±ÿúgã{h†œUL�6�¢.µî‘áq/4ïÈÙ³ GSkóÆÒ~»çBÎxÐmºMÂ/¿��TQ<ÖZ6× Q~,�i W*Ö¿'®¡äcœGïó€!g1¥%iêGÔÀŽ'aÁ�÷ÙAÎNû$$†eùŸ?¦yùi=c W2PlFŽÁo¨^!@§¸~!#%­Te¤`¯å ˜I+±Iã=ÜS°½ÁÙ¼we\ÛÙKrÛ%ô1^$Ú7O~g>û?¿@¡´ô-øø ­PïO`dÇãŠ$¯ ‹©¯dÎ—Ø X¸ß†èÒ-¤ÏdÏ�ñ'… ‹÷k‹óEMdâðæs€öüáþADµ§ í[›k©H}ÝïjO ¬‡Ügœ•,�Øø» ) �p“Ï:ÿ[›-5¡þ(õqC±gœY�˜ E PÌÊ$$ÆAø†U]§ºãW4Ò‚TK Céäü ÂW>’]‚v'JûóXýdû.à ËÉßÐûµ²¾Þ¦¹Š|»T5)1½`Bµ9âŒRmÌé\1U §}�ÞâaßÔFo},ºÑ5T][Œ÷²]�å4B5±;x$¿¥/ÐpèBZÁÆ"§9ûÖHÉN DÙ‰¬O+í•ÎÎJV$ +${o ö3VRö½ê⢡@䛸²¦]ïG66Ñ~$³Wžs0.s¸4$MÔ×´¯¬C“Þ=_…fÝUù™ó= +Iø\[R›~^ö7¹EÕp¯hgÏñ¥ÓÚÄN†OI~}ºÑ^žTý ‡ø*„|ôŽãç2'V¹$¡˜ ¾ñ_¿e=j®HŒ +[‹ñFµ^#·fzàà‚t9‹çJ›Û´Ìɧñãf*â²Úôœ ¯¶®´iX|žÂ+§ÐîÚO éDÊ(t£ ºj]Èõ ÏH´áÓ¨›${ p­ÉÙ•cAÿ2ƒßË'郛Z´ž¼š‹CóSµ=`Hð“o‚?e#ŸJv}ˆMÜa-HäÀtjlò­™îíi!k&‹ÐÅû€jÅŒ¸†yx³‹î 37zlsêR߄uÄ|R CZœÓçV°ç“X[Y~K+# ]Ã)e÷=QHv¢wIm)XIl¡ùŸ´+)�Êk»÷Sú:5îè¯÷ÞNCÑÁÑ3îÀ øÏ?þ†té a¢]8³øÆ$ÒÌöewíHcˆû:§wª«ýJp ¡ðBµ>Ì‹?›ø|ÏÖÊê_Yâ¸Øš›EWîqÚ*®¯¦§÷@¶™Ž„òœŒ´‚§Š™ÂâûØŠþÖq˜. Ëììšæ$N.l«zHôFÈÝ=ôóÈÝC|Lüþ‘OËþˆ�G‹>7Q˜×Ó¥ÒØß#棓®_|©pb¡÷ìî߯0‡mVŠYþ˜¾¡¸$ E'ÅÀa€œW›SXì›ê�Y^zFJìc£oÓv5`´j>> õ§÷tÄ?¾€'ØŒ8l¥¹°‘‹{À±Ðå,ö#ºâagÙýÖrA,J�JÒ„÷-ˆÏ=xB�óžá{ Ÿ0Ê:cR餲†Ö•øöô0;55’Œ+ mM)ã¾É#Ýla?¼I“SsŠ£P•Æ­E½­!Xú.úÐþ¨òÂç|k@eæÃþŒ¾êsí%ù騣¨Þ§rSA\¼Hè]å%ȶ§—�··|Ç1�ßõÒŒóˆÞ'"x{Ît®jŒQ Ñ�³²ËöÎJ—}ÁLéî£â�ÿþ{¿¡A©¢¶Vw´¨¾*Eç7£!P-øªŸ¾ôóC§”Nûº:>Wņ�•áç´dZ¼µ’�•úè¨r·é{‚ØÅÀJWÇK�=Áj°²g½�Á\þî´÷AÛºÓWV€–·6ÆžŽiHû¨ ®N._)ìÙ°~ŒN€Î3MþæMYR=LöD5Úï­aØH„±!ÊÜ –BHÏ×åžúÑ×0(mx®¼À…MeÄ{õkHá_ð*)üpÇdÑå”Ã÷õ?Ó®ãîúˆºÇmj‹êªÉD%þ±×òTÒN\*²="S8}î á64͆\È¡ÃôuÑVõÞ¹1�ƒF'’õO»!#Px°¹å Üã!Ù+ºÕã¿ÿ¿±ô L]p[yp%Õ©‹}K7€`„<­Þ-Y?„l~íð¨xï²—×í6Q•€â›s½£V»IÉ­¼Î2âO Ã4@31ÖŸÕ4 Ò¬eqza!xãu°òÄÚ5Án¥Qh>b¡g:$Ôw^ÀZ�{ò„ÈãØùwºÈ$a±Ú¿u2ÕOT¶÷øÁI’J\›aò¯ŠÅ��Ÿ={1¼Ô<û‰�åpßâ0ä5b(ôî6:lñipuÂÇuß; 4Óxy`ü„Æ_Œ(ª}š×›„¶º:¦G®t›bhXNB2;µO„ðü}úšå ˆW¹MU'¡ÍœÆ·í.È|ˆ éZYÊ¿bñ>FˆÄ?? OnêÀ#ÃpBŠÐ?íˆ}ÚE:âp¹ ÒØy|Ð䬋KȦ¨e-¨@ÓFŸŠ9#Ü/lA7±‹Ru[³ë†.pÚ‰¸¯1M‰ïû//|óüqÿÊtHÌëõ0}mþŽ'ÊÛ ŸÚè‚h€?*ïcá}ÙB,@úmúô¿¤‡Æ!÷å©ÑH´jеo�uǯåÁ#2ˆhà[rnß1á2àdÿR•?{‰ �­>,¿9�‚êtYuOºLÊ:ë ê&k‘�òüñ¾ð>-~ï´�\�Ð'¡Õ›‹ ÑÀ](ÄRÌææ!³ ?ê¢éHƒ%œ¢k2G c‹I)¨b>9ji¥ î‡@,ü;c]…Ìq¯g-†à#sÜ 3š8MwJ‰Üغ?Û‘„4�o>½\¡Uøñ¿?c ä‹oñjJ».›ÃV ïçÇ£‰Ü¾ë+Ë]¤)¼ò=\\Lh�û jéÞ"ô¥Ë;Fãk.6MÔgÞLBS¹ÃÉ“ ÀK0®¹3ˆñPÓÏП?lÃQZC�Ü®œÊ‰C7JÀÿp.:¢pT~­°àmñ)Wäb1½ƒYkK³ýqh<0­°ñAq£ó¹¯ˆ¤ÝЉýÑŽ.à="¥¢hqÖwÊãÒdõ5,ÍvAä?f¶§ÏË� a@¶ÏÆ!ôg/ô ueurÍOÎn­ñ‹Gã†x¿e=œ=‘Z©É\/)@¿Ù_dƘÏÿ­J„�F¦oÇ¢Øî¹±­{]$²„�œ÷\¿0¦îÇÃS¯Ý{‰Æ¥5?Î15Ý3C I(¢w:©p Ž1À€Ùž•9;›‘Ï©# Ô矅¬ÿ c ºŒ™¬x4”[~›\f, mñÃo/;§tµ„ÈI¾0§R@#_9}+4™Oæ{ÆcÑÎXø¬ß8al3Q½÷ß ø‚iFÿ;ýî¥>)»_eÈG]í“Y�:ÁB¬ƒÑYj%ÝBZ(¿aCá&¶E†Î× }`èVh/\ˆ ¾fìú¦°·$~ÈL�ŸÑªnáÔlÍb‡?Íòô(éé‰ÀŽ�Žóa)߈€ª ù’vDŒT&D^�ôDщêávóÛ€Þ1ö�¢Ê�öž„5<”�ïYSõæ½õå =1HUÛÛÒ@_ü7Ö§Pѵ/ñMòÁ ~erÙ˜«ëŒ$5 UJÚÝ¥j²xo2÷ÃÒ²‘¯l ޱ r++ݹ… þªÂ‰þ]¤ÆKÀµ6�ií¤ÝžJÇÄOÙèÕéô¡(Ì«ãn} LÚïSþö)Ê„Ê�̇J ßàÉéqu8ÚYÔ.î\‡cÍÛ mNʾ�]–_º´_W²¹l³˜¹HÃExßïŠmCak~©!À�'A_[g%Ávaq#DÆAIÑ÷8!Q§A�€æÖ\réxBá+¤ƒŽ©Žvßá ËÀ\Šÿž`veOÐtÙu±ܤM'z�X þÒŒ;Jí-MÜš šÙ$•æ6­š³nç£äŒ…äúdãIæ ÿh—2…óÏ>”Ë”_‘ê®CPfˆ[áäò¿åy~Ìj¬Òð¸µd •¤­ä”$vcÅ܃§ðô/È,L��™^´£²3¶~§,Îõ¢ïÇÀŽqyB‘5h߀TOù)xT̳�å<öz¢ï^\OCª'å ]À‰+ó…P/ç(œ zæ@c0›6bês[gwšý‘ç A0óEBÑ«TvV©$);4�Ÿ¿’ßq¦MƒÕú Ø¨�|VÙµL®’„g·â@Ÿ =Ÿï_éË�·�›y*”èW9LÞ9�Xž¡€òŠ”½EË]uûôfò– åy Œ5ø�ça¹kjcL¥ÐÈ %оŸÚµåòÁí 4•�\ïÞeêKðÿ »ò 6�,ŸlÅm°g&“©Ú©šÝ¢¶¶*s¥Fº˜ìNâ+vb'N%ž$[{•l+„�Gg2›Ù5—9$À˜Sœ æ’0`sƒ!Éæ2`0c, æ6`À\Û¯%Œº…Å¿zŸúëî¯û�¿÷¶…$¾ØÎô¡]Àtè7ºÒb¦üç‹byuŠñÂTrg!)nÕõÐ8®œí‡%d?ì.%_¾yoà1ýÿ‹F¼*Cºoe ª�¢õ^mвÉÚˆb'�à{¥ùYŸÓ&ã7±Û©Þ¾QEÃFý°UÕ¦f?|nÝKà&DöÐEò»ãOý•Ÿe¶ë¶‰¾vx:;W‰´S)Ñ×Mñ+:Â#³ BÙâ ^ } %ÏçM$ ™ž�µ|ËèXAF‡0Ï·wXÚz­{€ÃþâU ëWù|4e9Ñ%­�ÄÏ’Á8|Žó!Ìžìí> ­g×!Ìí÷ÒªaðåfUÎb š¾�taØD:èYQ¥“nÈ#tî|ôGF5œÕ7·]P¡š‚ÁÐ.3 ÈÁüÜé©�%{×.ŸS_¾—°üâ§ìúe­Nj¸©DÑ+A‘÷™HIY¾ôõ:Æ:Ši�÷/OóáÉ©ØÐ™˜TdJ‹ö¿o‚ &2—�Û çP<¡©êR¡´é+é±03^�3´6ôÚLi"dÇsõù‘¾òé1Š1}™ ÅVΔgÈ\ݸîüD&w—xošN°‘ub&Œw·¸¹^©@+åa‰þÆ'â½¾Þ-r�”ÍÛÀTÇñÏ:óe-kv±ߤþÖÑGþ~&çñ�÷I¡¡*óÉ ÉmêIßò¨Œ°;áÉ(jgÉH:<‰TãQÚÝdëx¥xˆ:D¯7%ÞNíîR¢ªÊ„‰ÄE#x?ø|¶O]€ Ñ¥¯¸4y1Ø’�Çq·’”¨=ÅÐ~yÞH2VxëMg6¹u„l›˜#¢-ÉŽ¢å�Úb%ê N)L‡ñ@&pœ>“œ–œ�Ò9>D¼·íUª{aù@YÏès Z+Rßœ�¡\±E¼ý3‰§Äç$vqÝ(V Þ¬îwh÷zHî•ñöÎxÔ½Ô•¥?:-±Þû5=©ˆþÑâÙ´@TÐ6U¡ƒ‘ø®7¡Óa,]\ŽHè¢@±ê&È£.¨)žË DíO²o7¶I­UŽx—UR­×i¢K­¾8Ùkø[¼êJÈÞºû‰Ka¨b­ëJC¬ÛT|çÏe§¥ÞX¤.®t¹µ®OiÉìØ—TŸ¥Dƒ‰«… p |¾óC¹§Y Ï™£ý#“èQèדY‡ÙjGÕÈ\a«nbÎÎÃR‰»¯Ôþèq7:AL¶Ù—-ºp4±c$µ?® (6’NmÎN –ŠzÒ`~F›Y9°‹‚Œ•ÌgîÅ*ÑÚjí N +ƒ¼m»±NGë2ð³Í8o¢™ÔBÞªZ1«DÆ'7b.I¯77ÞòwûOÉs¥àžgÒhqëÚ•]Ïʶµ‰èàÈD#ÈH‘oû>©'¶þe´„Q#M3U�jÌmuÃJ”óy\h<ÙzlBãlfüÙ—i\ªÖïDô‰�Ê_Î]»¢CÙye k�\%2³Yœ†Ðm„Ç/|èÈÊê…>s}��GdOˆ{@ÀÙq–ÚG´C¨6Fa“1ö¬;4õ÷=7ŽHWQ¡Ø«“g¤¬¸%$›µVÑbBÒÓVØpÕ]�N.2H;;±ýéŒÄó­=ÂïëÕ6ðÁ eÐs)5á7CQ÷ٔЄ~iš"ä[ª¯z�¢ybªøÂ›¿¦µ=ÍJIT_µu,<‰ê3@4PÀ¼±ï½¨#Ø ¼¦ésiœ¹v½¿�Ü\ Né…/Ê 8ÛŽ—ØÁ/8è7@@ýë%Z©�È{œØ£@íWÃ+«: ¤(^ænowÒ–‰©J@-sv½Ì\ufuI‹…_;[;|ÇýÚ]ñ2-š“u±Œ·°Á†Ôrhá§_ªÓàûçîøõÔH/¬&ÓÒêÓ§ d›m› ¥Ïm}zmGèxžu±Vm€>– ÙzñÛ{ÅPi¯ _Ów´î\Õ@Õ”-%/>¸�G¾+ècû¤å†ù¢úÜË“ÐÅÿ ã5=#:Ô4r¹T›c å“y‚Ÿ€±ò…×òÍ� yf=å�“ö}†u†‹ómya¨=&W5o°4®ã;a%ÏŽ³Êzî¤;|Èø\ÏNÔÄMë�_yEab ¬Õ «3ÎûO¸K-•ŽèÕÑæÆ�¼GOL‘ó$pik5 ç*'" ¤£�ãô¡\j©ÃDÉ(>¥_ÿíwt²ÃýÄñ C¸ø×gúÁÄDXe–kÞéåÚŒ ´m ïÇÐÅþ¡ëÓTÛ¤››h‚ÌÌÐ~p~±ÐH6郗yô¢UÊÑhŒ³¦ÊíW™›,® ±Ó—Ç}d ã\”:óÏ]´ªr æÁ#�ù•ª•!š 2�ÿãtXjÍ3¢Ù¯ÛÆÑƒp±è4ûx01Ú6¯Eã©�gt7�þ�h,—IÙ]úƺn„¡ÿªDý/=±�¤k'î¯nk�½{¹»Šl—KÓýÌN,hRª¦ãFâ눰5EtcqƒÝJ«6.•‘ÝÇWr×WÒ“g$/`J œ?áX]úoL�Á¤š~s®)–•çb¯7‘. €×8%;ÅZh„b�pÿùtD¿¥§#dmtkïÕ«0a1æ–»¾ò€ô´—LX¼ÁO>ÌTZ¸™›µòX‹ê’ÚjjuM�fÄ�ž§¥ÐËQÎDž Ù:Tgëÿˆ.[Q§0”·hQýL„& ÆãpÜœŸîöô�ŽJPjy³Y’‡¬£Bkí÷C莆„¡´èj- ¯~ZdÖÂruÅ\ßZ²Ô>lOÈŽ?ScœÏ/¨�Ó¡ÉàJ½¦‰@ÖDt䌇ô„ŒÕ…6d O¯|÷[Ú£Ýhè‰�«Õ¢’ÓYY—È!åððU”?ù-©{@R‡ #­C‰Ö¯9B­hA¹}E1 ›H°‹+´ÈÀÃ’3’ã&ØE©‚ç~C»C«"#:ŠŸâ+u¯s¦: öVÈ œȰvä-gï!:ÞÙ�­"{=/A“Ôýl¦U‹&˯*F’À țлœ­._| Ÿ‘eœ¢­ Œ!®´faök*Т”’¥:]¢år`[Âz9ˆ;н/.˜Â¿dŠåeOÏ* Qþ­Èþ�„&’›ÀO¼�ïfþ(Bµ‰P>TÑVvK[pzbÖ býÆÇÂGb�¸2U­=Gè3Ô-0œ¡´ø0.c¨,S‹Œ!‘q-šH©1‘k€2FMÖ¹þ$0ÕIÖbÃG º´(«Ü¯¥nYO±=B¬u»Ë°a”}%þŽk®4„›µ(zíédᢼ혃îÍÕB(Ž×ìîJG¼–ç'âÚÔh¦uv0|NiZXâî´–··;ùå¯hÅ£†ÿ@Ç�bó«jư”Èš*ͽ> ›ÁºŠ��HNZ÷Œr�‰Ž×ðK¦Žjó¥Ü�ò� TÓ­ èÕ“æ"n²—ÚA Åæ.�òiïHäJSÒxf!šyz»¡£ 6̶m{eÇe¬ÞccÏA¡Ø?ìg�ù¯5FT¢‘ܱÅìFËH˜ã’‘65O\7ܱ�÷ïÖ€¿ûºÏ3uÑœz_‹ú/)oŸ¯‡Eºñ¹‚Ÿíñ…ðÀ—Ro_¹Ä…€‡X¤Ÿ»Å=Ø'¢#îússÏóòÔ(+¹4?¨^ÅçŠEo€Ó[êcEaÓ/�¿äÄŸhÏEïÈæGy…¨â²áÖB<Èhs†ÜÒ¾‘9vÜ�( ŽãÿHk"ùÑ�áx·ç‡�•é¡§!V5vAÒ‰‡�Ï‹F”Üào™usæ,=ç‰Û¦šr£¥=2Æ›nèÁ͉Ůó!xy±L‚­sÞ sõ¥ÓÍüŸõ·…å¨Ñˆ¦1/àšž`A0[ÿXrÚ xÚþÓ¤x'‹ötÝê†OYMÈõú’K¦œ°4üšÍdvŽž´§ápÞ+ˆ“÷l¼Eu³ÓûEã3�$§J�YO/—ƒù1™œ�8¼ãøì&�šs;5#¨yR�ÒV[Fr&-°lÎ.â„ùDâËð¶C”nÉI¤¤õЧ¡~]w—ÔhüÖZÄØx#@É]9BÛŽh_fÎ<âø5-V„̺¤ó È(¯ëW£•@c¹ ^Ãå`ìgÖŽ¤`¥º|‰åº„•ä1ǯ22fzÙ€ŸIuN�´÷.ÌwšáUàíÚ¾Ï×[zƒIáÚ8Âh!�NÑÈ 0 ‡ šé+þç`,R,…6Ç_“'lDÿòíd.É¿8wìA“w##VÁ�bÌþ^·jäI!'F%罘c#–i¤j2ŽiŠã5hDaY7w«DšY1mYuFŽD à“0W6=ÓÓH2΄"gKÆ™½=DÇ/8ù+ºÎàdn~ø-5 ÍOª¬"/Àz˜è'Geß{»¼ãýŽË^hÈÄZðäÇïyk‚}5wÍ뢲1ãžR;þÔÆÀædn æSˆ üItÕƒ™Ï†)Æh\Rùkh.ŠÚ.¤¦^ä4–FÂT�«asEp•öð2׊‰F,eäcRó×>Y,C×½pc`&f¯É`p\ ŽÂâ¢w0ò«@�öÿÈx—v'E–OoøQÑÝe ëp�„‡`·Ð™‘•ìøͰôQ'2Øý²þnnËÃ|*®¦,È×ë¥È’ß/Pe(¥ûV>VÚ“¤ÄŽQoî®PÍòºø„E †/F¿ó¼HìŽñü5±mØ8ÉÜ»DcˆÚÑŠåºrªp+39lRƒ�Ö‘œøA ±y!0Õè4çI�9$mîKŒ’SÁ¹U5©ƒx:.‡sbº=ÔrR‹%´NçHDë²îùb¼œ¯m�VµkÀ_�XØ1Ül~#<Àx‘ù-/#rnSuË1Zu­g¸á>zbðX“ùmo£´Éh†_?9Dô,©õK¬^®ö§&{ûWK5¸þ†Ç=õ7,@@3®Ë½J:b+ZÚò©ð|mAžLÞ,p2 Áá"p3)OÆD£‘wóH'ƒ¬¬¡¼¥ÝΤûÁÙ°~¹<Çãzë÷€9ñó[)½Dgù)ëÑÑè¼Òt#©œ�Œ3=„–P fj¾˜l$óG )á{÷,®úîL*Ú„�Ç+õI° `�@ªˆXê¶_Ñb€Cgx¡,š4YçÈÇÛ�Q¥¾¥Ë§ÂÆÚÞ4—‚Ç (U"OfhÝ~ÿñþ3úÿÉEç…6džÌåSÑí« Ú<Ùi.ïÄÞdì:c~ÑŒúò¡�É”úL958œ=ÓR�Ø—õÐЧl/z9 M¢ø|"ùá÷Cú¥ïÃ}‘k% Oó©Ö¥”$ÙÓœ.Âã|L̰<Ù½Qx�`¸auDÎäN³œª©Ðî„ka�‘X¥®xz™v0Űf¨ÑK=ENURª­ÛFFïóžL�¬ÌÑ3õƒ£À0¬P2¶ðÑ92Ó7«§éþÆŒœz$M�Ïnm !/ˆ® €¡™XF@5ÿ»—?%õõU߈èò 5ò¢~f(¥‰¢/è{§_6‘˜jÄ$N‘ÚK­b¤Gã#¡¢‡B6J“ð6"Ý÷¨þY³í¦›_²ìçš_&Ó=“P»«Õ�º|ÍÀ©€¯.A±ãšY|�Ÿ§‘ŠluwÙ\|¬„ª�–5ÅùÀÍãà$H–1�Hc¢ùRÎB†�?°$›*Z—SÑ·FGÚÖÔàf…Œ’o¼Ü…&¦&Pš!ù#ž&Ù\‘]_ûº„’ùE?ZžSC?).T?#+‘¶ýJ$vaf ÙÖjËà!Û«ùïSÌõ'-É)Iieyü�›]|Þ¯ôf§¬Œ�22K ó½ìÿ‰Ðâ— ~EÔnký|K·_6$¥ —ííä&WŽÃ±¾©÷¬èc—�k]eã->E”d~¹5¿I `± Ï"Ó ±xÖ¨†ƒt*è;ë×I|×»ñI9 r*=&æÞ³j5¶ð9œã Ÿ}¡xˆ‘£ð‡lXY–;U"AöÆDvÁ®ÿz�ú_�%’“·‰c�1s¿õ"wY+ SHµèðtíÚmøŽ½±yÓ®.�ÙßeбÞ8’‘£’…”ÖΚBÊIÛ]š£Æiä€]µE¶_¹Ò.&Uü\·ûœdn¡›mѱ9>¢ènH�=æ9Úq�@vÀDµàá¼Lü… m>Iw¤”"~¡uì�)2V2ï'äI©¼ÀÊá�udÖq¸GÏ{»£Ù=Xv˜nþ"l}B2ˆ,ŸZIò®œª*o,]Q�îŠê±s"o·@§ð#àq1©¿nmìN¾ÒH)Ù­Õ¦§“*0üìÑáA‚3ôU±Ñxˆ…ÀÍ)Òî{ž˜¥Ý–S ŸW¾Ou°9àK:ú…ÀUL{³†kùvÄ£s*'n–£ßh¦Ñ¥KzÞ>Û1¨‚P!zVïc“€-‚ŠÉæ×À!½££ÚæÙF5¯Ýj­êTáºOd(|}ã†è:íj�¢ùìå8ÿ¼ /ªU�ês®ê jP�RˆÚo/Ð7ÜÑizØÒž¶çDÎÈ£M˜iAg`¼*7C;G×äTLÁrðšBe(;rÐŒËÁàâØ/�OÊgjº¶é…œ k.ÇÓ!ñ~O¹ãN´˜9!÷´…[ó×/I )x®÷îh§”ºí_¼¨(Ãßà!E\ß¾ú€D-aþ+¶<2좓D¡c{ä8[ª<<Úõï"‘§šù,�vŸŒï,>M¿‹t‘©” Ž")æÈf8µh¸³-{Nõ¾YI «Å¤?©' v:yÐ�OÍ.ÔåÀ â"á}øK¡vØ ßo°à k ùñ×÷¤Xÿã�­e$ÅV—T™*ŒÑ‰”ðË¢î´ÛžóÜŸzl†Zj1Ôºõ%ÉÉšKÃãF'KÛÈO‡ÝÜËc�¾áæ…v �ëÌ.‘(ý7ƒª³—�X!}·%§‚_½èISA¢4:£?ðšÈËCÀÆð£¤ßÃ�‰Œ¨œRË©†ž´ŠÕîAÈáÃB—ýâFÂ÷Š бVÛ»QÙ#§š'¦WãÀ2O£ „jïŸhO“�í¾äÕûE6öX¹õ mb¸2¦$Ff<Î1âÌLNŠ€dþˆŒÜ^­÷£^TÖÕß…ÕñN;Ú[;9ŸEÊ£ñÁé·É×Þ€‘xáq»k;³ù�rªè¡2÷qÌnlƒ–x‘örˆM}ÀöF®n8ã�ŸÈ ² ž»m¥Ù~TØäòã<)4 µ6TŒ2ŠE‰š‹9£'Z{aDRRZÒÛ}—BTØY-ßÓ7h1ílêIܼßÊHVX›÷(«±©:¿ÁúÇAø§ò�pÓÿÔïhwW�‰2l1\àÆè€WžY®”è’âù´©@eçsm. �î rH†õž™YKr�ðÍÌáq�•´RYS �dzs8 2ÿ/¼SŒ¶ñóß‘±÷®�á×¹3RJ Ÿòná÷õ¹™Ø³ÁÌδñº—-µçG®‹j¬ïò£2 ¹%ð dÄ[]F2Y¥ÏßWÓ:îÙ–¢qºýuñ´œ.Íß½¥Â˜)|ÞÑKôuàhl±�€Úéû; Õ±=²º°ãGÅÔõFï*±eíhoõ…È�,‘Å6ÚCW;²Œbu´1§²q¿��â%(§H†�Ø#ligxŒ:yûϤÉ0PÖUÑŽt‹{Š# “ò I)LzÍ´ÜéÌ~ü¦ûTI>¼ñ­e­üž?5øF¹9º­„zw.Ÿk�ìHWfW!þ~íüB¯?“óÑ%.4·#+«5¶+aOåÀåQ¬ü€¿ŸÀƒvIÕa1yI²…ö¬=?$Y±¦4ô‘Ó7P8ˆ•w”¦uÛ€”ô¶†0d,q" €Òn„¦ëV”¸²ñ´9'@ú³°ñ-ìü',°…¡um*¤Û¨uÑk Jx£ö�; Ñr=L<#ZnO\^¿÷‘Ê}CKßú�”J¨í�|¥„¤]¿ÿ%íáÉÊO1Ù+¸~ÿSNΤ)+‹|)§º^Hî á™ÐjÐLnBfJ«Y:ö„þÐ5Tñl¸t¢ˆÙ¬>%âBJ«È] f1¢íŒ s¸6ü?’‘ŽÄ í»“r*®7.¶¹ xâ�\òhêúÃD£ÕÑÇÈÑŽõŽ7þ¹rj+/¢t³E‰{×òy\ܸ*!³¢®L½�Ç'ù»äµ‘–¶Ô§ {¶"™ R)qÊÔd¤ Ë•vÜWÖ`…¿ñ&ezò`ÜPq>Ra¼ÙH®‡Ç;ƒdº“P R�ñäxûŽ3Püú“I™ž(YÒu"ýÔ?M^R{zÝѯo <Ⱥù;8lO–aÔVêæŸÍ!$¢-½¬R åÀÈJ=|ö¦>Û˜ ߊhæç?÷{2÷P×äïþÚmYS}œ˜\˜K?{1Ï þn¡ÕÊgdúÅraßlF¯œ’…ú&ÉJa¯¡ª5ÒyX2��d~ú¿ý@#jw½ÉŒù”²| D®×<�„ô !»'ÚžÐgÿ5„äÃõUm»å”¬-L�*Û�”é÷qCHÓx+&fû74A”�ž™ï…šëׯ®"õfy<@÷,W‰UDdéí©ˆàoõ0Q-™“>Τ;hs"¨±S.§&Ÿdæâ§o‡ôPý°¨O˜l¡™«É�“—dƒqh¯%¾)KÙú½FÇi´×&»Ld§bÄ¡³7êîh�z�òt= ¿Nt‰m.¹Ó']EÎ&Ø(vÄlE yIuÜÚýêÇH‰”l·L&b ™‡À”MY=¦™ÿõÉŸ‘*È䣨GQcrj®«2Ì7Q¿ÁH{Öo0[v7¦ï;âAÙrù˜TÜ”ê—[¥Hqë’-„ÔÇ�å`˜(!âü4ÓÃË!ó0\FÉ>ËÒê~Éz«œÒ6NÞzö@‰û7:ò?Ä�Ž‹BO¢ÇhÌP‡½¥Wý±/O ïSíÊÚГ(�ò�†ëÌ;ãÈ·Á÷Ø´å&Z€eô÷HOP‡5´È©º¶˜–”0� gpk£×Ç(@±È]× ÃÊé‡Á©£rj,5hp6&)3 iàcÂC„N/MY]›ejèéX»~>¤L3\6/‰½QLfì9MfÇ-¶�·´€—$sA—¹£À+DFÛ3c`nÜû‡‘ Sýt±!6q†auÿà¦w¢çóŽ\ùE ðdI–äÅN`av åÞTäôpð}´0]]Çk<ߣu™, “ÌŸ Ï�äcY[Ñ… yhú²±ú‰nÝÊçáÌ€jº\‹ž·*ƒ£ï-?n»—ø¼DNUDŒõTÂ'ìì‘ipi±¦Qãæ?ÒÿW2¬°¹‘3›�äwS‹®uQÌ Éœã—\½o¸ é·Mä,Îlå&p½Ôh2/<¶¹2n·OUïÜ,lÚs}Ë œÇÎÂùñˆƒ¿þ’wN’⬎ìÆp$\v£ûº²ž+@‚!éqü+W�ÛMZÌþcðó{6}†|•“ Ó•Kˆîj‹û"á3|¬/àœ–›ï`”s ›“ñ ™ãU’ø¨ î¨I¡A0ßi8ûVàv SÁrD*´†„F~>3<•…XÉThwÆ4,úŒ£—BJއ€™orÆbFùßdب19#7Ù•éÅOỊ$×Qý]ýоjj Ús ÿfB"‰|Ø0“Ö½ˆ”Ùh×-�‡\¸¼Ã¸“óu“ô‹±„Èß‘‹é‰´’ˆXt†½ò‰a…pŸÿÁE¡›ËOb¤î°„ñ éî?2²TƒgW%È›¬,|2„O¢Þú“ezvþñûCÄ™î4‡„† û®j| ìhWàÎo\ê¼’¢ÌÜr ˜ŸýëÏÉÇ;ó9ª�4t-óÊ#{Z8IœÃ9qY�®+b·®ðóß±â0@6&kr£ÑÍlí˜Öhà;àh¿ %‹ÌbL²�$öY/ªì|}[ž §nçï®×ë_+Ÿ÷k£×ÊÎð0óm[¿óbø—×jnoeË©ù¦RÍz­þ<�î¥?¶\ML7ÿs~s…üFxˆïƒž¤?%ÏU->Tà9ziB/1kï ›ÿFÑ·dÊrÛZtüŒâ·Ó¥5÷စjsAt$mâ� ³–®‘ŠXißxkP0R:šªwÒêá ³Áæ[�·-[½e›â§dàî@GÝ‹9µÚûl ft¢+8I ÿÙWEÞÇhèßÄoëÓöx„QIê|:Y’˜–ã»Õ-¥Zó_o..Ôš? k6-íÂ4#UäŸhÒ{2ww»æI‚†š(ò{´ˆx `1q¹yº \¡�cýƒ³<­yû}¤Æ¿CóðmÉ*QõzccY“¿URqWYvP– Ä'¡·‡¾ßã;èEO{\§­9\L1¿™‹ÿI&‚vÎ/å·Ü°JÉïè{“icŵG:½ `,\¥Ýç5žÓŒŽþÿAncÒÈŸ…`«ÊÅűŽD+˜6gÝœ‘!B3Ë1ÊS¿ 8œžï³%>ÍÉ­9V»òeouŒ�´háPßx¹ h/b&L0ì †Í¼FÊÂÌâg)‰Õ3ïíTnûú—é›Zp¬¤¯ é_�=˜Ñ¿ÐB¡µSÞA?´À—çÉzÊ ñg ™Ò™÷Š^¥¿^ð)à Ÿ<ί® ßlˆÓ »�3údþ¨Â ÞæÿPK‰q�Eºôª¶Ã PQuerying.gdb/a0000000b.gdbtablxUT Â\�T×\�Tux õíÛõsUW(`,�àH $-NNñBêÔÝÝÝý«RŠ”R¼¸Kp‚C� Å ŠÜõܹÿÂý�=Ó§³gŸ³ö’÷}×:3$ž7§qOÁÀDT(xihø±Q�·‘�øÂ�oP°Hà>,AéЉ<ïâ$n+˜�Äâ�W±1%c5ê• ¼…5hP*ð1¶ ¥´·á:ž�ìD�2�A8Œfe¿"Œæ± 5b/bJÅÞÁYÜSNïQª¼Á`ÊW0hìC§øÀ/¸Œû*úJWr‹ÉÈ[9p+Fá<ºUñ]D÷„Àï8Ž–UŸcªT3J,D‰ê�;1г†¡âš× |†¨•xKQ¦V` ¦¡|íÀÈD|kŽõ¨X×-6¢z’–‘�äz�7°±ÉV‹Q¿~àKlC�žbª4 ¼‡LÄ7 <†é(ÐØ¬a8rТIàSlAÕ›/aJ6Ù‹kèÓLÄâ4R›¾ÃN4ja0Ø�¤–&YHlx+Û:ð(æ¡`›Àí‹‹�‡‹èÙ60¹hŸ‰sèÐ.ðv#¹½—c-*w06,E™Ž3Q¸S Fâ:útü�#hÓ%ð²P§«ØÅ:T¾9ð¢T7�ÉÈ×]2áwÆM=¬6¡zÏÀËXŠr½D æ¢po€ (ÐÇZbŽ£Õ-’Ù¨ÛW !±ýŒ³QðV `$ ݸ"-o×¶ ù¦ëQ©à)ÌC‘º‹ÙˆºÓtb$ΡË]2ÿ"ùîÀ›XŽØ{�`¢î øG‘rŸõÅ&Ô¼_XŒ’+& þÁ�e(û`à¬GŇÌGñ‡=Å,}Dèa.¡Ã£�oq}S-p]W'q­Ÿ�¦8‡®O~Äq4}JñÅA´y:ð5²Qû•™¨ÿ¬0C:*?x Qòy«Šˆ|Á* Å^ôaÌAÔK�þƒóhÿ²EF6’_4؉†¯Zsl@µ×„(¶£ÎëªÖ¢â2óPòM Šiˆ{+ðV¢üÛ†…Uˆ{'ð8f Ð»Vá,Rß³ú8�»Þ7JTû@b# %>4%˜�ÂîÅBýØÒb6 â½HG…O}S�ï3+�¡¸†>WOQþ ãÅ"Dx ý•¹ÂbDíÃX†èoÄ.V¢Â·ÖûÑü;{Ž¢ù÷VÛÐñ+ˆòÿS@‘‰„5æ£ðOV[Pëg € ¨ü‹üÅbÄþxSq½~3T\C¿AŠªý®eÌCéÁ¦£q ½ÿ0k8‚æCœ‡�o¨Å&&1ç‘:<ðv£ËŸŠ>ò�Ð2†à$Úý%óp }F*ˆúÛ¦Žñ¸Žþ£T$-0EÆ–"f¬õ@:ªŽ3±X†:ã­rÐr‚-ÑëUÑl¢Û�<)ð6£õd{ v¡îé‡,´›j^p]¦~ÂQ´œnŠq-fØz‘…Ä™" ¨4+ð Ö¡òìÀ“ÈD…9óPe®. zž¬Àd\Cïù�Sh³ÀV„Ó�ø Ýâ/D-R¤1e‹:ÌAÑ% KP{©ã– v™‚‚™(¼Ü‚b*¬pEZ¬T-°�ÓM;¶£Î*“ƒU¨¾Zr" Õ×x/– :ÃYK½Ö‰i(�)1×ñà:õÖ;µ`Žâ¦ 6lDµ�Þ†íHؤ0bnÚ,‘‰²[” ŒÂtßjwA6êosöÆ”ÉR‡° E¶›5 Ãi¤î°<È¿S{ø 'Ñv—·á2f›q\DÇÝbgÑq�8ÀQ4Ú«÷X�Šûïcjþ+­°ñûÍ3V#æ€`À\F�ƒÞ†=¸é��{Ñá°Ž õ…§Ñꨦp�)nˆÊÑ ,AéãNZHCÉf3uÒS,C‰SÎM�3蘫|!5O‹DìDí3F‰5hxÖja-*�³—! uÏÛa±]/ £áEA�ͨyIPcê\6,d!ñ?ÝÀ^$]ña¤£üU£ÄD仦”âgA‹ë&‡Ð*OÞpðÇ4Ì�óè”/ð3r�š?ðŽ¡m�ÀW؉:�—° � ~G: ÂAÜø;Q+*ð V£baMaâŠÇtD ôÁ0œA—b�_q ý‹Fâ:—|�]¨WÒÛ°%JÀ(¸ãp½¢“Y&pþÆuô,�³hãÃ(x3§kX„båòúQ‹\ÜQ>0WpW�D‰xO1y+Ãl䯤eŒEžÊ�[0ŪîÅ ”K¼‰%H¬xsU-ð æ põÀLÀx´†¥ÀUô©iîqÍŸcZÔ²ÒØ‚Úµoa-ªÔ <‰ˆ¨kHC‘$3„ɸ‚›ë B@£äÀ‡ÈBÕú�'0yX Ç´løûи‘°•^ÅJ”ob1yo ŽãhÓ4ð¶¡z³À HC©æ�7° e[ÁLm¸p í[IIìGýÖ& ëQµ�åÁ,D¥˜!LÁUtmø‡Ð<5ð1¶ J;ÃG6j¶¼ˆÅˆë ˜„ËèÑ10'ТSàkìDbgÉ„(×E®b:®¡K×Ào؃ú7ûv¡F7†EhÑ=0а‡ÞcÊõ´˜ŽÈ^�Û1z{9f£`Ÿ@_,BÌ-�1%ûJ{LCÁ~šÂhœFŸ[S{›|CjÞx �p‡ÂfÔëoÍ‘Ž¸¾‹å¨w§Ån$Ýe=�…Ô»Ý"}î18„†÷ÞÃ>4¾Ï{±ýïŒBÔ@9�¸é9ˆ]èô F‘ç!ñ‡4Ôy8ð-¶¢ù#j," <…5¨ñXàSìD—ÇÍrÑñ Õ¹¸õIჼOÉFLDé§U8ÌAÄ3sõ¬[¬E“ç¤=®àöç…(J¾ LBÙ7ìBÊK†€SH}Ù ¡È+F„(õªiHx-ð ¶!ùõÀ»8„noޡɛ�ð/º½e§Ãxômq€²ïˆ]ŒÃeÜó®èDå÷|¨ÿ¾¥ÅAtû@�ÅeôúPÆ#þ#óQücéŒ-Hý$0—ÐÿS;¢? ¼ŒÅ¨ðyà#ä ïê "¿TŸ1U¿2TlB«¯Å N£ÿ7ê. ~¸ËQé;a‹Mhû½UÀE øÁ- ÿÏ`° ~T°±?žÃ:$ü¬/8€^¿¨ÈE‡_?â:ý¦Æ¢Ô óŒ•hú»\À ôlˆúÆ‹‘¸„[‡¨È74p7&â:nfáq}†kÇ�ò§HÄet¡†á*úüXˆ„‘�×°‰+–ØŠ¤Q «3Z Ã$äcl˜‚Òcf!ϸ@? Âxx¼�&8d¢Ê?�瑎¤‰�w°Õ'¾ÄT�lÓÄôŸø§Z_,BÙirÐrº2‚]¨;#ð:!z¦Á` Êϲ`ÚÍ–GÈ;ÇÜc(Πý\é‚\tšç‡Ðj¾ƒ+váæÒ'Ñ%ÍÁÇpÛB-ãn[¤Öá :.ü€óè¶ÄÑ'Ñ{©ÉÆqtX¦ c7º,—µ(ºBÆ4\Gï•öJWá0—Ñe•xFìêÀCÈ@™5"sQ#Ãfƒt”ZëEøçÑ>ÓŽƒ}¨¿Îðq Ý×þ´Ý`ø¸ˆŽ�»Ð`“�™hµÙlàÚnñalDí­V…·9Ó`Zf9@b#jm×?œAÊO‘…„�v:ì@ê.G DeË_ŒDîÿ½Ý­À£ÄÁ�©¸Ž¾{…¢÷îÇ Düë»ø×ðÐ~U I·p:Ü¡ø!5pwVëp]Ž@“£�÷± Ž9N£}Žj‹hp\b7jŸP(° 1'�ù1EOÉKŒÆEÜŸ«k(qZ×0ÅÏxŠ ¸ˆ®gÕSìCÓs²ëPé¼[¬AÜ ŠuH¸h7ÅV$^ÒS,AôeÇ#LC¾ÿ?&á:^ ,EâUÕÛQóšÂ6Ô¾n÷Ã&$äÉŠ%¡sÞÀHDæ ôÅ(\DÏü�‰(S ðV¢DD>¿k›‘T0ð:²Q»Pà d!!2ð–#1*ð16¡JáÀÓ˜ƒE/c‹¾Ä^¤Ó2Ž¢YñÀœÇ­%£Q¼¤F1Q¥O`5âJë.ö£KtàBã2nq�˾Çyt� ü�shø{Ð).0—1 \`6âËÞBâ+žÄl”�¼�ýhT1ðö¢K¥|~îà¾Ê�©ÈS%p ¦ 6!ð–£nUS‡³¸½Z`>â«k+[#ðV£nÍÀÛØƒº‰�W°­kYE÷Ú�?p-ê† =ë†á:ú$†"=ê¦!2Yèa"êû0†ã8R¾C6Ú4Ô.àöFƆj�&¶#©‰Á`%ªßxsQ¾© F:¢›ÀRmxдEàWœ@JK�\¤´r‹¸³u`ê¶ ü„ x$E_×6ðþAtjàU,GL»À‡ØŒšíŸá8né ]ÙQ£˜�ˆNÒÓQ¶³F±åºÆd︋Pâfq€•HêøçÑ¿»B�3¸¹‡Ž#OO+�ñ¸Œ{iu{~À~ôì#^p -n ŒÀEÜÜ×ã(zô LÂUÜs«w Äm«PéöÀ{X…ä;Ì8ŽáÖþ 'Ña€tÆt»309hu—îb/’ï–)Ø…Ô{ân¾7ð£û}�q¨t¿a/’ºE’Ð(֡ŃÊ!¶£ÆC�ϱ µ¼†eˆyDÐ eÀ˜ƒ¢�©z؆Ú� ~Dý'`*?xHx*ðÒPêiˈ T{F-Á¤<ë{Pÿ9Äz´|ÞSd#å…À×8Žæ/ÊGÊKfûÐàe“ƒtļ"¼1¯ ~ Çt-ð;rÐçuUåßüØŒ¦oªÔÈEï·Dм­#‰ïÈ<� hô‰‘#M>Õ ¬GÂg*f#ös3ŽÍ¨ù…"�¥(ó¥(ÁT”ùÊZb"¿Ü�¿q]¾‘ÈA³oŸ" IßyÖ¢ò÷v+d¢ê¶wl@âÿ”¤#öÇÀ£˜†?úa(rÑîgµ»‘ü‹ÇjÄÿjïÆLäÿMލA�±å~¼‰5ˆl䘆ry¬G•!>ŒtÔ*^��úÃô {Ðh¸ï"•ÿX€Ò#÷c*òüè…A8ˆæ#å9¶ ño5 i(>J-Æí‘wŒˆÅ`œD˱¶lCíqƒtÄŽ<޹(1!0“q =þ‘88ŽVe-. ó$Oq­'{¶!qŠSv ÖTñ‡•ˆ™&k1‘Óí«˜„¼3d-áÚÍ”œ8‚Ö³¼ [Qs¶±aÊͱæX‰2sE¦!bžÁ_ÈEÛùöœÁ} Lò¥IILGÄB£Qt‘ý«Pe±5G&j,/X…ø¥Êæ¢Ø2ÇŒÂt\nÐÈAë�¯°�W:™c#꤫È@•U² [‘¼Z’`âÖè)f¡P†ðÁTä_«lb(N¢c¦S.Ž ÍºÀ·Ø‹†ë5� ¨°A4aªn4HCÙM–³±ÙÈ1g�ºEÄnÔÙjê��ÊÛTB,El–·a l· ˜ŽÈ|�‹èºÓÁÐr—Ù¨�-¸p-v tìC“=Ž ¸Ž~{FœFÊ>M! ÕÿõË+�¼ßa#Z° 8‡n�h‘‹N‡tGÑâ°‹m¨~Ä”  G•,AÙc~>à_4É |‚L$wH@*�ppÅ"”<)9± ɧœZp-s…ΡÃiU;PÄVT=ë½ÈDùsâ+sÞ{‘†âÄ2Pé¢EF.ù.æ¢äeãq �þ48€æWôÛP調Gâ¯Ù&�†×ÍÒ›'¨˜ƒby÷`2òæ ܆™(˜?0â4(Ø€j�‘ޝa9* ¼ƒ ”‹ <‚¹(¸ñz Ã)t,øûдh~ÿ&:�‰ÅocÊ<�Å(S"¿X‡J%Ï`Š–òrLG|éÀÓXˆªÑšÂR”)cИ…Ȳ�»1×ñXŒ§ˆŠ ôÇh�óaŒÅeÜ\.0Qåu+ÑÈ?9ÿYhø—Щ¢ÙÀuô©‰3¸£r` ®â©*:„ˆÂ8T¬ø ÇЪšFqM«á ÚÔŒÂÉ"õwbΣ}óŒKèÞPïq ­¾Â¿hÔ8ð>£U“À—Ø…ä›2P±©UÅLÄ7 <‰ù(Ý\ aJ¶Ü�I(Û2ð¦ _+ €IˆiíEX‹ä6n±�Rt›Q­­HÄRĤ^Àf´jg®°�Ûk GÑ´ƒ•Æ¿¨×1ð¢Y§Àç8�¶�Å$N¢u+ˆShÓÕ*à úÝ,š�¿[ ¦£@wÅKP¦GàAÌBáž�¾˜‰½Übâzë¶£VQ‚ŨzKàU¬Aý¾�°Íú>ÂFT¾Õ$b5boÓ LCäíRã�狇)(ÒßÂc6¢XKÌA±;­ÒPô®À½‹«èqw`N#åa†l$ÝxÙH¼/ð&Ö"î~a†È;Ðìâä} Ðóõ ´ÇHä"õ!õWÑëaßÅA4|DAÆT|4ð,¡ôcÊ&â:>ø‡Pÿ‰À[X…ºOÞÀn4}JÐ`+’ýíÌ›X…Øg1yžU 1ÇÑü9«Š5¨õ|à,GÜ ú‡é(ú¢XÜCÊK�á8…–/ ¬AÍW´‡,$¾*°¥^ÓŒÆ<üF`* ¾) 0 gÐæ-5'�ò¶bŽ�¨öŽ­ Pè]a†ù(òžµÄHœC×÷?áš~ »±1 jÌFÄGŠ%~ÇA4þX‡°Õ> <‡t”ÿT ÃLüLФ|®‚`3j|!^°u¾ÊXŠ2_I+üƒ<_~À>tù&ð  ñ·*2Qá;©†‰(ö½ÀHœFëÔœF»ÿÙ:�…ª?/Ö¡ÉOæûÑñgF’~±úX�R¿Ú‰1WÑñ7 àüHGÌïêFã,Rë²Pëß@⇘qLCÌP+ˆÉ(9L{‹3h=\Ÿq�þ4�؇ú#¤3V#î/ía.¢ÃHCÀtý;ð=v£Á(Û6²‘:ÚÛ°)cT.F×±�_‘gœžb JŽW1 å'8Ka=ªü#é°u&* Ø…“bO6aX†è)�'0 …¦JŒÄEtž&5]JbòÏ0‡³hëù†á4zÍ ŒÇ%tš­Öá"ÚÍ1WØ�ºsßá ZÏ“)ÈA×ù"—Ñc�–Q,Í© Py¡ÉÁ|TZd±¥›XÌBä#ÂHZê#p)Ë6£År€LTXᄌ Ô_©\c)J¤{Æã2º®2ÈFÝÕ�—±¥×(ᘀóh—øv¡ÖZïÀ*”ËT61ë Cp]×k{�´AUÁr$m´ïcÊoRð•6›?¬A½-³Ø�Æ[?v£î6s…ôÌÏØ‡FÛm•È·C%Ä ØiOFŠír‹­hš­Q@ãÝâ9è½Çn…ø½vlDÍ}†…¥¨ù¯§8‰vûÅv!é€Â>´;è×rÐì�MÑü°HÄ>48¢CX�¸£�Ç1 UŽ>ÆZTÈñëPå¸ò�ÍhsB¯p O:|"©§¡p®ÂL:­<`"ÏØ&°ñgýXÁZT<ç Qâ¼M[Qû‚`/:^”ˆ¾dïÆr$]R8„Fÿ9à º^ñ+ÑüªùÃV$\“¡X�Š×íÓX�h!üÆ#oÞ@ Bšç |ˆµ¨š¿€³N` žÄtDDúáoœC»‚�‘ˆ(ˆ…¨êO�?Â!´‰ |‰SèW80¹¸¥ˆV�‹;‹æ¢R±À3XˆÂÅ0 JÞÃ!ô,˜†¥�câJ^C6ÚD~Gþ2üXd aÙÀOøc¿`?ǾG6êÆ^ÆFܸn\7®×�ëÆuãºqݸn\7®×�ëÆuãºqݸn\ÿŸ¯ÿï?×ÿPK‰q�EA×Ìjˆ°Querying.gdb/a0000000b.spxUT Â\�TÂ\�Tux õíݘTÕÿà5A0Éí^T°@ƒTÅTJÂÀî`í.•PTL,@DEP0°»“ÿû…ëÎãºKùCÿ3Ïó>Ÿ™Ù™çÞ™½çÞsÎddddÔ`EVbeVaUªQ=ùûjÔÌHßÒ·ô-}KߪrËÊÈÈ}aîÜ:Åå“e¡œ6?sß�þ^>]Ö÷x†Ì‘3e�|;yý,™.Éô-}KßÒ·ô-}KßÒ·ômiÝ¢Îße…ù÷÷Qáß—ýØŸ8�nÄÁtç:ÖÊÈèÄ¡îÆáô`ÏmÇöìÈV«fd<¹bFFþÊ»±±y}@ ˜çtzÐ)9ÏPle4f6bc6¡ÍÙŒ´d+¶¡mbþì΋¼Ìd¦ò ÕX‹BŽæXާ?Ä9œËp.âb.ç ®äj®áZFPÎuÜÀMÜ­ÜÁHîçÆó8Oñ4Ï0‘3•ÏÊeÏU22¶VNÕùA9Ì� ¢ŒN}èËiœÎô£?Ä™ fCÆYœÍp.åîáAFó:3b»Ó“#èʼnœDo¢ò±k²k³ëR—z¨¿d4 !�Èœ_÷ÉÈ&—<Ôe2ŠbûRB)e4f}6  MÙˆ�Ù„MiÆælAK¶d+¶fZÑš6´¥íéÀvlÏì8¿Hÿtžë�óZvÕŒÕcþ¶É´¦mìçt¦+Sx…éÌáC>âs¾æ7æ²buó OÛ¾o2ƒ·˜ÅlÞá=>ŽíÏwüÀoüÎ ¦³«R›5X›FäÒ‹~ ãlÎç.å2næ.îæ!F3Ž'x–çxݾö‚Bx‰-̳ Ûr—ñ›zÍ–ü¦lNæBët)·q˜Í÷äqg°©é·§ïð)ßñ@|.MoŸ™ï–æq˜vwš³c›øBX�†dq¹é~ËOüÌ/üžœ \‘jñ:�³Y�-Øš8�ÁœÓ° ¿RÝýšÔæ“9ŒÃ9†Ø6öÓ¬MÖ¥ hD&9äS@!Å”PZcÞç¥|Œúû?�¹cÿ"}fsÇIŸŸòGe �Ç/”>_¹OÉ|nþy‡¿Ì¢”,N²$%K“,K²q’¾r'þ 3/�UÊü$ R²0É¢$‹+È’ÿH–.f–¥s¹ÎÆK˜¾OÊ—çÌKçbeþRÊ¢”,N²$IÇѹÏ/FæT�¹‹˜yIæW1KS²¬‚Œë—ÙK)s–RæV1K«˜e ÖwÞu¢:3’zÐõÿ2Ǭ�Ù€&lÈFlÌ&lJs6£›³[±5­hC{¶¥Û±#�Ø™]Ù�ÝÙƒ=Ù‹®ìþìÇþ@7¦;‡p‡ÓƒžÁ‘ÅÑñôâdN¥/§Ñ�þ àL3„¡ ã,Îæ†sçsrs —rYÔI¸‚«¸–”s7r3·p+·swq#¹Ÿxˆ‡Ëxç žä9^d S™ÉlÞá=>æ¾àG~‰ú�ŠmuVçmõ›9üÀo¬e%ϵÍ�Œ:—×lÁÖ´fwöâºq‡Ó“cèÅ©ôá ú1”\Ó]�õiJkÚÒŽŽt¦ r}8ƒAÜÆ(äžåy^`3ø”Ì'‹Š(a=š²!ñœuû„OùŽ5ìß Ù˺vå |¦3|_eÄyïéNoòÌãe^g:«ÆgÂ4š³¹K=Ó9Åëîöø ŠXŸ�iAKÚ²zm—Œùíh®ðxoy0�£<·+¯šþk¼ÍG|É÷üõGó©Gv”-zÿÝêÍ¿¯¤ ,Kw.à.åfnã&ð$O1‘ç™Î[Ìâ¾á{~c%uñ"N1ý~ôçJ®gó{�Ÿ9Ý:U'›ý-ÿÑñÜ7|m¿ãº§<‡Gy"êÙõ[ÇØ™d‘C.O;Æ~ƒ|DÎ�k¶êß‘ç~)—9æÉÇ|É´h—l¡~vŒ¿ƒ¼ßñônq½P~Ïa–mkËòïš÷gümº=®ÃšœçñùÑV™‹¸8Ö�Ëã:,Wr5×0‚r®ãznàFnâfnáVnãvîä.îæ^Fr?£x˜±Œ‹sŒçq&ð$Oó yžãº'“˜Ì”¸ÌìM‹8Gç0”çFlÊËÆùQ÷Žzª2›È‹LæM¾¢º2þUù]¥<�2U†›z<„›yC4ÇsWó£r]U¹öäT¦(èÆq}—gÙ—=ƒåØ›ÌnÒ€¾k°MÙ8êß´`+ZÓŽmÙ™ç½o&»r%7p3·qgÔÓ,ÿ3üF­¨»FÓz=L+ö‰6çѧº<ÇD^â¦ò*¯1�÷™ç|ø„Ïø’¯ø1ö5~a.+šæÊ¬B j±:uX‡úq>"úĹ/¯ÅÃŒáÆóO+Ó•q¯ÛD™^ËõŒd<Ïò:•ñª¼¦?·Ž?³ŠòY‹uiÈúlAK¶¦myÖkßd w0.Ú«(—k¹—ûâ|�²Å´¦dz£õø’·-ï÷qŽ…Õ<®É=Œ�õ´O[‡ëýí!N³N×ñoó-ß±Š×Ôb_Žóž ­[ZX·vìÀ\Ãm<Î*^· Èãep3ùÂú|Å·|O-ë[›:¬É:|æù«ÍïıOX§¢=�œ}'¢}†}6L&[¾íâÜ¥eÞÂýC9<Ú&ø[+ÚÑžméÄNìuzº²9›ó¹˜�ù4ú3ð9ßFžçõyùËïÝ¢$‹+É’*fé‚ÿc¹¯U!U’™)™UIfW’¹Iæ%™Ÿ’)YXA¥dñ"fI:—‹,M²lÁ~YþwÙ(ÉÌ 2{13¯‚̯$ *ÈÂJ²(Éâ”,© K“,K2ê'¯/” ÿGÙ(%31³ª˜Ù)™“’¹Iæý?Ëü%Ì‚ ²p1³(Éâ$Kì/åË2¥dfJf%™½ˆ™SÅÌMɼÅÌüJ²`)eaY´Œ²8É’”l˜Œ´¤Ù(ÉÌã)ý)³S2'ÉÜ”ÌKÉüJ² ’,ü—dFÒ6ù�úÿÏŽY‰¾¾ÑÆ8pEVbeªQ�¬FMjQ›:¬ÃºÔ¥ hm•É&‡| (¤ˆÊX� hBÓ¨7°9-Ù2êü´¢-íhÏvìH'vbWöâ æ 3Œk¸#ÚåòuÌË:7¡9›³ ­iK{:Љ�Ø9ÚŽ³7s=8’£9†Þôá4q/�1‹ßø�•”i5ÖdmR@ M£ÎÄFlÆ;ŠNÔƒø’¯ù–M§¹ò–çfó‹úÏoÑ~Z½h%jP“ÕY›«ü­®ºÑõ¼Ë7üÌÊѶ€jÔ‰ö4¤ùq�b®R—z‰Wxƒ™|Ä74¤ íÙ‰cÙ.®ë²‚û«³&ïªw}@¦ç/ä6Fñ–õ]W,›8)ÚU{î¾â¾cnÔm»�Ø”fìÌnteöçŽà8NäúÒ�þ âL†0”³9‡sÎù\ÀE\Êå\ÁÕŒ œ›¸…Û¸‹ûy€‡y”'˜ÀÓQÇgÛ^ßÛV?F•Õý«ä�ÇOÑ_ÃvZ�ŠxÒsS™Îv\Ê\m7l»{˜ÌÌbMϯçÜ¢¬ùš•=_WPʶìÅaœÎÙцÅ6ø˜žÁ‘Ç œHoNáTúr§s¸žÛy,ÆH°�Þà~ÛðIžâY¦1�O¢í<ëÙ6a7°‹úø œÈOÔöš6ÍñœÀÙì}â3¢<»pÇp|”/*×flEgvãÀhCAOzq<'Ñ—œKŽi¶Œöqþ.Ú0ð1›sƒ¹0úP磔ë‰\ÉÝŒá1žæMÞ¯1¯þÿ¯ú�ΪeQ:—(‹—r–¤dÔ–$3“ÌúeöbfN3·Š™·ˆ™ŸdA%Y˜ÎE%Y\A–$Yš’Q?›^…lTAfV’Y‹™Ù•dÎfnJæ-'™ÿgÁRÎÂ%Ì¢ÿq–,Ø¿Ëÿ*31³–Rf$íòÿ¨ÿuǶ âz¬?ÜÈ=Œb4cãú|ŒmcÈ�̈±ì¿Ÿ$Of(7ò<ÓO?ê˜ý�äjS�ú4 —"Š)¡ŒÍØœm؃=éÎÑœÈ`ÖQ?(dWÓí×&¹Ñ¼¶qü˜uc r!—q97QÏkÓ$ê•1¾˜çê³²ºÖ Öy2³ù„OÙ‡<ÈØhKn½wáNâNg Ws ×qwr/£y”§˜ÈK|Àç1f˜iþª KØ>®Ç²Ý¢�~ŒU¦ Ž1 £ïò!÷Zßyˆ1<ΞáE¦ò&o1‹ø˜ï©®üò¸ÃtÎP†ë{®5ûs'R÷ýýLêG;föåNâ2nàc¶W~{²/ûq=7p?£x…W™Æ ¾áV4íZÔf Ö‰y‘E6ë±1›Ä¹¯o@Es­í×�—m»IÑG„©Lã5^ç .är®æFp×s7s ·r·swr÷r#¹ŸQ<ÈC<ÌhÆð�2ž'¢îmb¿â%Ž%�]cycLÎâ^Ö²/Ì¥Yô�±ÝŸâžåy^`S¢_ Óãú6ŸÓ€F4åĨï³µ¨Ó°­«Û‡Ö¤AŒ hÛŽäU>�köÑÆÝ~°G0ˆ)ˆ±ù8˜îÑW!®ës2§qC8‡á\B[Ûj:r,ñ’}d*o2›¯âMl?Fp·sws#}<ËžæYžçe&1™7™çÁx›�ø˜¯øšïø5Ú³X–µhD.E”²>ÍÙ<®ùך?äJ¬Îš¼i{Íâ=ÞçC>â>�þ&œÏ\}Žâ\×Öœ×ÿÿ/¿w³—0sR27ɼEÌüYT1 S²h)gqǵo&DZUÉÌJ2ë_’ÙIæT1s“ÌKÉüI,a.å,ú�dq³$ÉÒ$£ŸÍ’dýtþ)$Ù0%¥dfJfU�ÙË8s*ÉÜJ2¯’̯b,gY¸”³(�‹”ë&¿ëT·’¬·”²þ"fF2æþõÿ›³ÞÅÝŒe?zrÇЋã9‘SéÃiœN?ú3€� âL3„¡œ}q9‡áœG]êш|J؆=¢>mz™Å;\ÎÃŒ¦™ßž8ˆãù!Ú¼ó;«xM�� úýª]ÉýŒç1æÆ˜dìÆAc¨Õ#‹| ¸—ÕmÖTOZ‹î‰:80.ÚÎG[zÚ±=û2—Õ¢­1§s)yí1Qïfƒ8‡á\Åuì¡~Ô#ú¹s£?8r;wr7÷1Š1Œe�ñ$OEÿ žãy&1™Wx�éÌ`&³x‡wy�÷™Ã‡|Äg|Á÷üÈOüfÛÌeõ£jTg5jR›5X‹µY‡u©K=êÓ€†4"“,²É!—| (¤ˆbJ(¥ŒÆ¬Çúl@š²!±1›°)ÍhÎf´`s¶ %[ÆïS°5ÛЊִ¡-í˜l=_áU¦3ƒ™¼ÅÛÌæÞeð1ŸFût¾ˆ¾÷|ã9ð-ßGß ~ä'~æ.áR®àJʹ‘x<úÔÄ8Ñî?Æ€à$NæÜèÇo?ߊVlK'öãîgKŸ‰�èÍJцÀþ~·3Žfl}óéãï±/ûÑ“ÓÂðhCà3±3»²{GÿÞä÷HûñGö÷†>+·¹'£YÝg¢”c˜Ä›¼Ï|Ì Þ³"+³z|æX‡zd’K…”PJãhKÀ4acšÑ"~Oƒ=86Æ,agËp"'Ñ›ÓÆÕ”sC´Í±Ç8‡ÑžIY½Â´¿Óz?ãð>õcúvØç6±]ZÆõqÚÑ9ÆÙç<¶÷šý9�2ûÝQñ›�œÁòCô¹°¼Ëg|礪%�wdvìÞ?•׸Ítïà>F3™)¼ÍlÞå§§>êÉ–ó)ï¹ÏrNáÞåw6�18èíîÙ'>7t‹sY1~?½9•� å,.är®d»˜~öfzr4}¹5~gÀwü};¬ïŽìÎÜ}gâwJ¢-‰|;úÆÄXÜbÚ·r'w1ŠGxŒ7˜É{¬ã:°«²vôA‰íhƘŒç±ø\1�g£¿Iô{Šóx¬ÅÚdSc›²Ð$~×4Æ`+ÚÐvåy¿}9ï{¶²Ì« óS²`eaYôg?-œ9K˜¹)™—d~³ ‚,L²h13þ�¿õ7™“dî2μå,óÓ™ÎtþcY°”²°‚,ªb/øÞ+O¾Ÿ)óR2ÿ”ÿò,\FYTÅ,NÉ’å›ûör˜ÿòÌH~ûü�úÿѦžÝÙƒ½ÙŸÃèÁñœÌéôgÃ8‹ó¸š\ÏMÜÊ�Œd cy‚§y†—y•×x�™Ìæ½?ŸOøŒÏù’¯ø‘Ÿù…_“q¯N jÆøá¬ÅÚÔ§ù4¥CÔ·èÄNq=�.ìÍ~ôä(úÐ�þ `g2Œó¹€‹¸Œ«¸†¢ík©Wª;\ÎQGáEõˆm•ñ®Á;ù1ûâ7Üb6ªSƒšÔоÔ1k°&ëR7~ËŽú4 !™Qg!�bÊ¢MÙ��¢.õBšÑœÍhAK¶dk¶¡­iO¶£#�èÌžìÅ>ìÇH7â`åpzr$Gs,ÇÑ‹“èÍ)œJúÒ��œÉ`†0”³9‡sÎù\ÈE\Ìe\Î\É5\K97p#·p;wq7÷p/÷3Šyˆ‡Í8áQÆó�ó,Ïñ/2™QÎö¡mb|ûØ—¢îÌ1ôжø¶ù¡ÎQœÌ©ôátsp!—p ×2‚›¸9ú[Øgšs‡r1šGx›oøŽhlíÈPÎæÎç".áŠË€«)�qùyßn9•YqŠÂzíLá¨Ø7b|D:G› ÝéÁ—|möÍ«øüÐ�èÈÞtãHŽŽßäFnæV^à>á[�szÜßuÑ�f1‡Çu)�1?¢ˆçÚÐ�íbìÑhËÀ ¦± «³6�È¥”õãÜ&­£? �Ù}¥y¿-ùŸø?‘ÎÿFV1‹*É’”ŒãÇt¦3�é\šYøÿ,‹þ¡,N²$%ãÿĬ*dá<‹1‹+ÉØ¾Ëcf$·®Iîç˜õ@ºÇñ2½¹‡Çù4ÆèsŒ¼>MÙŒ]8ˆéG†0,ÆàçJnäVä£ÞËÃŒãeQ׈¾Æ1v[Œ¿§"<^�Ú¬CVŒ+}”ýí©(ߌô-}Kßþ¿Ü–ôû¹(�ÿ/³8%K칳ʢ$‹—R–,ÈòÙIÿêw:NHßÒ·ô-}KßÒ·ôí¿q«Þ*¹ –Ñ©ÖügâñÿPK ‰q�E./šQuerying.gdb/gdbUT Â\�TÂ\�Tux õPK‰q�E�s ý�Querying.gdb/timestampsUT Â\�TÂ\�Tux õûÿ€@ˆ™€˜ ˆ™�øÿ( +PK ‰q�E íAQuerying.gdb/UTÂ\�Tux õPK‰q�EWá�¦*X¤�GQuerying.gdb/a00000001.freelistUTÂ\�Tux õPK‰q�EÄÞË–Pn!¤�ÊQuerying.gdb/a00000001.gdbindexesUTÂ\�Tux õPK‰q�EòÅ.Ía¤�uQuerying.gdb/a00000001.gdbtableUTÂ\�Tux õPK‰q�E°UôÝH ¤�›Querying.gdb/a00000001.gdbtablxUTÂ\�Tux õPK‰q�E´(û2¸'¤�<Querying.gdb/a00000001.TablesByName.atxUTÂ\�Tux õPK‰q�E0ìåó°¤�UQuerying.gdb/a00000002.gdbtableUTÂ\�Tux õPK‰q�EzA}n ¤�¿Querying.gdb/a00000002.gdbtablxUTÂ\�Tux õPK‰q�E)¤!*!¤�†Querying.gdb/a00000003.gdbindexesUTÂ\�Tux õPK‰q�E9E€� ¤�Querying.gdb/a00000003.gdbtableUTÂ\�Tux õPK‰q�E¸¡ÅÒ- ¤�è Querying.gdb/a00000003.gdbtablxUTÂ\�Tux õPK‰q�E,+ƒÁY1¤�n Querying.gdb/a00000004.CatItemsByPhysicalName.atxUTÂ\�Tux õPK‰q�EeF8Øž)¤�2 Querying.gdb/a00000004.CatItemsByType.atxUTÂ\�Tux õPK‰q�E>‘;Dž#¤�3 Querying.gdb/a00000004.FDO_UUID.atxUTÂ\�Tux õPK‰q�EW…Ÿ§ÙXq¤�. Querying.gdb/a00000004.freelistUTÂ\�Tux õPK‰q�E©Ó° ƒ6!¤�`Querying.gdb/a00000004.gdbindexesUTÂ\�Tux õPK‰q�EY@©(•¶G¤�>Querying.gdb/a00000004.gdbtableUTÂ\�Tux õPK‰q�EWú÷1 ¤�¿¤Querying.gdb/a00000004.gdbtablxUTÂ\�Tux õPK‰q�E�}LrËp¤�I¥Querying.gdb/a00000004.spxUTÂ\�Tux õPK‰q�Ecàšzk1¤�h¦Querying.gdb/a00000005.CatRelsByDestinationID.atxUTÂ\�Tux õPK‰q�E Kc=U,¤�>§Querying.gdb/a00000005.CatRelsByOriginID.atxUTÂ\�Tux õPK‰q�EÞwéES(¤�ù§Querying.gdb/a00000005.CatRelsByType.atxUTÂ\�Tux õPK‰q�E›�”‰j#¤�®¨Querying.gdb/a00000005.FDO_UUID.atxUTÂ\�Tux õPK‰q�ErÐ'ö0X¤�u©Querying.gdb/a00000005.freelistUTÂ\�Tux õPK‰q�Ežé¾€>!¤�þ©Querying.gdb/a00000005.gdbindexesUTÂ\�Tux õPK‰q�E¦A™¤�ÙªQuerying.gdb/a00000005.gdbtableUTÂ\�Tux õPK‰q�EÜ:() ¤�N¬Querying.gdb/a00000005.gdbtablxUTÂ\�Tux õPK‰q�EºÌî¹$5¤�ЬQuerying.gdb/a00000006.CatRelTypesByBackwardLabel.atxUTÂ\�Tux õPK‰q�E|µ’ù6¤�c®Querying.gdb/a00000006.CatRelTypesByDestItemTypeID.atxUTÂ\�Tux õPK‰q�ETUÅ_ò4¤�è¯Querying.gdb/a00000006.CatRelTypesByForwardLabel.atxUTÂ\�Tux õPK‰q�Eã"ÄÂ',¤�H±Querying.gdb/a00000006.CatRelTypesByName.atxUTÂ\�Tux õPK‰q�EÀ/T8¤�Õ²Querying.gdb/a00000006.CatRelTypesByOriginItemTypeID.atxUTÂ\�Tux õPK‰q�E‘ü¼,¤�›´Querying.gdb/a00000006.CatRelTypesByUUID.atxUTÂ\�Tux õPK‰q�EdÍÁ­Z!¤�½¶Querying.gdb/a00000006.gdbindexesUTÂ\�Tux õPK‰q�EõFÉ—¹×¤�Å·Querying.gdb/a00000006.gdbtableUTÂ\�Tux õPK‰q�E銊S ¤�×¼Querying.gdb/a00000006.gdbtablxUTÂ\�Tux õPK‰q�EJN÷øô0-¤�ƒ½Querying.gdb/a00000007.CatItemTypesByName.atxUTÂ\�Tux õPK‰q�Eöy5¤�Þ¿Querying.gdb/a00000007.CatItemTypesByParentTypeID.atxUTÂ\�Tux õPK‰q�Eà+]{2-¤�cÁQuerying.gdb/a00000007.CatItemTypesByUUID.atxUTÂ\�Tux õPK‰q�Eݦ�r(!¤�üÄQuerying.gdb/a00000007.gdbindexesUTÂ\�Tux õPK‰q�EHè É2©¤�ÉÅQuerying.gdb/a00000007.gdbtableUTÂ\�Tux õPK‰q�E•¥DÊ} ¤�TÊQuerying.gdb/a00000007.gdbtablxUTÂ\�Tux õPK‰q�E[ï:gCt!¤�*ËQuerying.gdb/a00000009.gdbindexesUTÂ\�Tux õPK‰q�EL¡ŽG&¤�ÈËQuerying.gdb/a00000009.gdbtableUTÂ\�Tux õPK‰q�EøQÐr ¤�?ÝQuerying.gdb/a00000009.gdbtablxUTÂ\�Tux õPK‰q�E˜Á¡­¤� ßQuerying.gdb/a00000009.spxUTÂ\�Tux õPK‰q�E¾—{Ÿ+B!¤� áQuerying.gdb/a0000000a.gdbindexesUTÂ\�Tux õPK‰q�EÉ^4l> ¤�‘áQuerying.gdb/a0000000a.gdbtableUTÂ\�Tux õPK‰q�E"íÞar ¤�(ëQuerying.gdb/a0000000a.gdbtablxUTÂ\�Tux õPK‰q�E[ï:gCt!¤�óìQuerying.gdb/a0000000b.gdbindexesUTÂ\�Tux õPK‰q�EM/†ü¨ß<¤�‘íQuerying.gdb/a0000000b.gdbtableUTÂ\�Tux õPK‰q�Eºôª¶Ã P¤�’ÍQuerying.gdb/a0000000b.gdbtablxUTÂ\�Tux õPK‰q�EA×Ìjˆ°¤�®æQuerying.gdb/a0000000b.spxUTÂ\�Tux õPK ‰q�E./š¤�ŠQuerying.gdb/gdbUTÂ\�Tux õPK‰q�E�s ý�¤�ØQuerying.gdb/timestampsUTÂ\�Tux õPK77ˆ@pgsql-ogr-fdw-1.1.9/data/enc.dbf000066400000000000000000000004471522375352200163610ustar00rootroot00000000000000_¡CnameC2ageNheightNbirthdateD Peter 45 5.6019650412 Pàul 33 5.8419710325pgsql-ogr-fdw-1.1.9/data/enc.prj000066400000000000000000000002171522375352200164140ustar00rootroot00000000000000GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]pgsql-ogr-fdw-1.1.9/data/enc.shp000066400000000000000000000002341522375352200164120ustar00rootroot00000000000000' NèTéC¬Ö—â¿À‰^åJFÏ?À—Ñ,¹?Œºï €æ? À—Ñ,¹?Œºï €æ? TéC¬Ö—â¿À‰^åJFÏ?pgsql-ogr-fdw-1.1.9/data/enc.shx000066400000000000000000000001641522375352200164240ustar00rootroot00000000000000' :èTéC¬Ö—â¿À‰^åJFÏ?À—Ñ,¹?Œºï €æ?2 @ pgsql-ogr-fdw-1.1.9/data/natural.dbf000066400000000000000000000002211522375352200172500ustar00rootroot00000000000000_aIDNNATURALC 1298372893 wood 239287328 landpgsql-ogr-fdw-1.1.9/data/no_geom.csv000066400000000000000000000001061522375352200172670ustar00rootroot00000000000000name,age,value Peter,34,10.2 John,77,3.4 Paul,45,19.2 Matthew,35,18.2 pgsql-ogr-fdw-1.1.9/data/no_geom_apost.csv000066400000000000000000000001341522375352200204760ustar00rootroot00000000000000name,age,"person's value" Peter,34,10.2 John,77,3.4 Paul,45,19.2 Matthew,35,18.2 "",44,34.3 pgsql-ogr-fdw-1.1.9/data/poly.dbf000066400000000000000000000003231522375352200165700ustar00rootroot00000000000000_a&IDN NAMEC 1 One 2 Two 3 Threepgsql-ogr-fdw-1.1.9/data/poly.shp000066400000000000000000000014601522375352200166320ustar00rootroot00000000000000' ˜èfHÌÛó¿b)PëW Ô¿K�Z¿Rè?v†Ä¼�!á?pfHÌÛó¿b)PëW Ô¿ø•µ~¥Ð¿8Žã8Žãà? fHÌÛó¿‰y;Cb¾?袋.ºèò¿.ogHÌÛÙ?ì ‰y;Cê¿8Žã8Žãà?´è¢‹.ºØ¿&PëW ÔÚ?ø•µ~¥Ð¿lÇqÇÁ?�µ~¥@Ý¿�“M6Ùd£¿º�!1ogè¿b)PëW Ô¿º�!1ogè¿b)PëW Ô¿´~¥@­_ñ¿óv†Ä¼Í¿¨õ+jñ¿óv†Ä¼Í¿fHÌÛó¿‰y;Cb¾?H`]tÑE·?¨õ+jÍ¿K�Z¿Rè?v†Ä¼�!á?lýJ�Z¿Ò?µ~¥@­ß?K�Z¿Rè?v†Ä¼�!á?K�Z¿Rè?v†Ä¼�!á?N�Z¿R æ?lÞÎ�˜·Ã¿`]tÑE·?¨õ+jÍ¿lýJ�Z¿Ò?µ~¥@­ß?¢fHÌÛó¿b)PëW Ô¿K�Z¿Rè?v†Ä¼�!á? fHÌÛó¿‰y;Cb¾?袋.ºèò¿.ogHÌÛÙ?ì ‰y;Cê¿8Žã8Žãà?´è¢‹.ºØ¿&PëW ÔÚ?ø•µ~¥Ð¿lÇqÇÁ?�µ~¥@Ý¿�“M6Ùd£¿º�!1ogè¿b)PëW Ô¿º�!1ogè¿b)PëW Ô¿´~¥@­_ñ¿óv†Ä¼Í¿¨õ+jñ¿óv†Ä¼Í¿fHÌÛó¿‰y;Cb¾?lýJ�Z¿Ò?µ~¥@­ß?K�Z¿Rè?v†Ä¼�!á?K�Z¿Rè?v†Ä¼�!á?N�Z¿R æ?lÞÎ�˜·Ã¿`]tÑE·?¨õ+jÍ¿lýJ�Z¿Ò?µ~¥@­ß?pgsql-ogr-fdw-1.1.9/data/poly.shx000066400000000000000000000001741522375352200166430ustar00rootroot00000000000000' >èfHÌÛó¿b)PëW Ô¿K�Z¿Rè?v†Ä¼�!á?2p¦Hò¢pgsql-ogr-fdw-1.1.9/data/pt_two.dbf000066400000000000000000000004471522375352200171300ustar00rootroot00000000000000_¡CnameC2ageNheightNbirthdateD Peter 45 5.6019650412 Paul 33 5.8419710325pgsql-ogr-fdw-1.1.9/data/pt_two.prj000066400000000000000000000002431522375352200171620ustar00rootroot00000000000000GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295], AUTH["EPSG",4326]] pgsql-ogr-fdw-1.1.9/data/pt_two.qpj000066400000000000000000000004011522375352200171550ustar00rootroot00000000000000GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]] pgsql-ogr-fdw-1.1.9/data/pt_two.shp000066400000000000000000000002341522375352200171610ustar00rootroot00000000000000' NèTéC¬Ö—â¿À‰^åJFÏ?À—Ñ,¹?Œºï €æ? À—Ñ,¹?Œºï €æ? TéC¬Ö—â¿À‰^åJFÏ?pgsql-ogr-fdw-1.1.9/data/pt_two.shx000066400000000000000000000001641522375352200171730ustar00rootroot00000000000000' :èTéC¬Ö—â¿À‰^åJFÏ?À—Ñ,¹?Œºï €æ?2 @ pgsql-ogr-fdw-1.1.9/expected/000077500000000000000000000000001522375352200160225ustar00rootroot00000000000000pgsql-ogr-fdw-1.1.9/expected/.gitignore000066400000000000000000000001071522375352200200100ustar00rootroot00000000000000# Ignore everything in this directory * # Except this file !.gitignore pgsql-ogr-fdw-1.1.9/input/000077500000000000000000000000001522375352200153605ustar00rootroot00000000000000pgsql-ogr-fdw-1.1.9/input/file.source000066400000000000000000000072751522375352200175340ustar00rootroot00000000000000 CREATE EXTENSION ogr_fdw; CREATE SERVER myserver FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource '@abs_srcdir@/data', format 'ESRI Shapefile' ); ------------------------------------------------ CREATE FOREIGN TABLE pt_1 ( fid integer, geom bytea, name varchar, age integer, height double precision, birthdate date ) SERVER myserver OPTIONS ( layer 'pt_two' ); SELECT * FROM pt_1 WHERE fid = 1; ------------------------------------------------ CREATE FOREIGN TABLE pt_2 ( fid integer, name varchar ) SERVER myserver OPTIONS ( layer 'pt_two' ); SELECT * FROM pt_2 ORDER BY name; ------------------------------------------------ CREATE FOREIGN TABLE pt_3 ( geom bytea, name varchar ) SERVER myserver OPTIONS ( layer 'pt_two' ); SELECT * FROM pt_3 ORDER BY name; ------------------------------------------------ CREATE FOREIGN TABLE poly_1 ( fid bigint, geom bytea, id double precision, name varchar(5) ) SERVER myserver OPTIONS (layer 'poly'); SELECT length(geom) FROM poly_1 WHERE name = 'Three'; ------------------------------------------------ -- Laundering and explicit column naming test CREATE FOREIGN TABLE column_name_test ( fid integer, name varchar OPTIONS (column_name '2ame'), theage integer OPTIONS (column_name 'age'), height real OPTIONS (column_name 'Height'), birthdate date OPTIONS (column_name 'b-rthdate') ) SERVER myserver OPTIONS (layer '2launder'); SELECT * FROM column_name_test ORDER BY fid; -- Check that columns are reverse-laundered when generating -- OGR SQL filters SET client_min_messages = debug1; SELECT name FROM column_name_test WHERE name = 'Paul'; SET client_min_messages = notice; ------------------------------------------------ -- GDAL options passing tests CREATE SERVER myserver_latin1 FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource '@abs_srcdir@/data', format 'ESRI Shapefile', config_options 'SHAPE_ENCODING=LATIN1' ); CREATE FOREIGN TABLE e_1 ( fid integer, name varchar ) SERVER myserver_latin1 OPTIONS ( layer 'enc' ); SET client_min_messages = debug1; SELECT fid, name FROM e_1 WHERE fid = 1; SET client_min_messages = notice; ------------------------------------------------ -- Using encoding option directly CREATE SERVER myserver_latin1_direct FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource '@abs_srcdir@/data', format 'ESRI Shapefile', character_encoding 'LATIN1' ); CREATE FOREIGN TABLE e_2 ( fid integer, name varchar ) SERVER myserver_latin1_direct OPTIONS ( layer 'enc' ); SELECT fid, name FROM e_2 WHERE fid = 1; ------------------------------------------------ -- Geometryless test CREATE SERVER csvserver FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource '@abs_srcdir@/data/no_geom.csv', format 'CSV' ); CREATE FOREIGN TABLE no_geom ( fid bigint, name varchar, age varchar, value varchar ) SERVER csvserver OPTIONS (layer 'no_geom'); SELECT c.* FROM generate_series(1,4) g JOIN no_geom c ON (c.fid = g.g); ------------------------------------------------ -- FGDB test CREATE SERVER fgdbserver FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource '/vsizip/@abs_srcdir@/data/Querying.zip/Querying.gdb', format 'OpenFileGDB' ); CREATE FOREIGN TABLE cities ( fid bigint, shape bytea, city_fips varchar(5), city_name varchar(40), state_fips varchar(2), state_name varchar(25), state_city varchar(7), type varchar(25), capital varchar(1), elevation integer, pop1990 integer, popcat integer ) SERVER "fgdbserver" OPTIONS (layer 'Cities'); SET client_min_messages = LOG; SELECT fid, city_name, pop1990 FROM cities WHERE pop1990 = 17710; SELECT fid, city_name, pop1990 FROM cities WHERE city_name = 'Williston'; pgsql-ogr-fdw-1.1.9/input/import.source000066400000000000000000000040021522375352200201100ustar00rootroot00000000000000set client_min_messages=NOTICE; ------------------------------------------------ CREATE SCHEMA imp1; IMPORT FOREIGN SCHEMA ogr_all LIMIT TO (n2launder) FROM SERVER myserver INTO imp1; SELECT c.column_name, c.data_type, attfdwoptions FROM information_schema._pg_foreign_table_columns AS fc INNER JOIN information_schema.columns AS c ON fc.nspname = c.table_schema AND fc.relname = c.table_name AND fc.attname = c.column_name WHERE fc.nspname = 'imp1' and fc.relname = 'n2launder' ORDER BY c.ordinal_position; SELECT * FROM imp1.n2launder WHERE fid = 0; ------------------------------------------------ CREATE SCHEMA imp2; IMPORT FOREIGN SCHEMA ogr_all LIMIT TO ("natural") FROM SERVER myserver INTO imp2; SELECT c.column_name, c.data_type, attfdwoptions FROM information_schema._pg_foreign_table_columns AS fc INNER JOIN information_schema.columns AS c ON fc.nspname = c.table_schema AND fc.relname = c.table_name AND fc.attname = c.column_name WHERE fc.nspname = 'imp2' and fc.relname = 'natural' ORDER BY c.ordinal_position; SELECT "natural" FROM imp2."natural"; ------------------------------------------------ CREATE SERVER svr_test_apost FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource '@abs_srcdir@/data/no_geom_apost.csv', format 'CSV' ); CREATE SCHEMA imp3; IMPORT FOREIGN SCHEMA ogr_all LIMIT TO (no_geom_apost) FROM SERVER svr_test_apost INTO imp3; SELECT c.column_name, c.data_type, attfdwoptions FROM information_schema._pg_foreign_table_columns AS fc INNER JOIN information_schema.columns AS c ON fc.nspname = c.table_schema AND fc.relname = c.table_name AND fc.attname = c.column_name WHERE fc.nspname = 'imp3' and fc.relname = 'no_geom_apost' ORDER BY c.ordinal_position; SELECT name,age FROM imp3.no_geom_apost WHERE name = 'Paul'; SELECT name,age FROM imp3.no_geom_apost WHERE name IS NULL; SELECT name,age FROM imp3.no_geom_apost WHERE name = ''; ------------------------------------------------ pgsql-ogr-fdw-1.1.9/input/pgsql.source000066400000000000000000000106271522375352200177360ustar00rootroot00000000000000---------------------------------------------------------------------- -- Create local table CREATE TABLE bytea_local ( fid serial primary key, geom bytea, name varchar, age bigint, size integer, value float8, num numeric(6,2), dt date, tm time, dttm timestamp, varch char(8), yn char ); ---------------------------------------------------------------------- -- Populate local table INSERT INTO bytea_local (name, geom, age, size, value, num, dt, tm, dttm, varch, yn) VALUES ('Jim', '14232'::bytea, 23, 1, 4.3, 5.5, '2010-10-10'::date, '13:23:21'::time, '2010-10-10 13:23:21'::timestamp, 'this', 'y' ), ('Marvin', '55555'::bytea, 34, 2, 5.4, 10.13, '2011-11-11'::date, '15:21:45'::time, '2011-11-11 15:21:45'::timestamp, 'that', 'n' ), (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); ---------------------------------------------------------------------- -- Create remote table CREATE SERVER pgserver FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource 'PG:dbname=contrib_regression host=localhost', format 'PostgreSQL' ); CREATE FOREIGN TABLE bytea_fdw ( fid bigint, geom bytea, name varchar, age bigint, size integer, value float8, num numeric(6,2), dt date, tm time, dttm timestamp, varch char(8), yn char ) SERVER pgserver OPTIONS (layer 'bytea_local'); SELECT fid, name, geom, age, size, value, num, dt, tm, dttm, varch, yn FROM bytea_fdw; SELECT a.name, b.name FROM bytea_local a JOIN bytea_fdw b USING (fid); EXPLAIN VERBOSE SELECT fid, name, geom, age, size, value, num, dt, tm, dttm, varch, yn FROM bytea_fdw; ---------------------------------------------------------------------- -- Remote Query and OGR SQL pushdown SET client_min_messages = DEBUG1; SELECT fid, name, geom, age, size, value, num, dt, tm, dttm, varch, yn FROM bytea_fdw WHERE fid = 4; SELECT fid, name, dt FROM bytea_fdw WHERE name IS NULL; SELECT fid, name FROM bytea_fdw WHERE name = 'Jim' AND age <= 30; SELECT fid, name, dt FROM bytea_fdw WHERE name = 'Jim' AND age <= 30 AND dt > '2010-10-1'::date; SELECT fid, name FROM bytea_fdw WHERE name = 'Jim' OR name IS NULL; ---------------------------------------------------------------------- -- Cached query case, exercised by statement handles or -- functions. CREATE OR REPLACE FUNCTION get_names() RETURNS varchar AS $$ BEGIN RETURN (SELECT string_agg(name,',') FROM bytea_fdw WHERE name = 'Jim' OR name IS NULL); END; $$ LANGUAGE 'plpgsql'; SELECT get_names(); DROP FUNCTION get_names(); ---------------------------------------------------------------------- -- Remote Update INSERT INTO bytea_fdw (name, geom, age, size, value, num, dt, tm, dttm, varch, yn) VALUES ('Margaret', '2222'::bytea, 12, 5, 1.4, 19.13, '2001-11-23'::date, '9:12:34'::time, '2001-02-11 09:23:11'::timestamp, 'them', 'y' ) RETURNING fid, name, geom, age, size, value, num, dt, tm, dttm, varch, yn; UPDATE bytea_fdw SET name = 'Maggie', num = 45.34, yn = 'n' WHERE age = 12; SELECT fid, name, num, yn FROM bytea_fdw WHERE fid = 4; UPDATE bytea_fdw SET dt = '2089-12-13', tm = '01:23:45' WHERE num = 45.34; SELECT fid, dt, tm FROM bytea_fdw WHERE fid = 4; DELETE FROM bytea_fdw WHERE fid = 4; SELECT a.fid, a.name, b.name FROM bytea_local a JOIN bytea_fdw b USING (fid); ---------------------------------------------------------------------- -- Populate local array table SET client_min_messages = NOTICE; CREATE TABLE array_local ( fid integer primary key, geom bytea, txt text[], int int2[], flt float4[], b boolean[] ); INSERT INTO array_local (fid,txt, int, flt, b) VALUES (1, ARRAY['Jim'], ARRAY[1,2,3], ARRAY[3.4,5.6,7.8], ARRAY[true,false]), (2, ARRAY['Jim',NULL,'Joe'], ARRAY[1,3,NULL,4], ARRAY[4.5,NULL,3.4], ARRAY[false,NULL]), (3, NULL, NULL, NULL, NULL); ---------------------------------------------------------------------- -- Create remote array table CREATE FOREIGN TABLE array_fdw ( fid bigint, geom bytea, txt text[], int int4[], flt float8[], b boolean[] ) SERVER pgserver OPTIONS (layer 'array_local'); SELECT fid, txt, int, flt, b FROM array_fdw; ---------------------------------------------------------------------- -- Update remote array table UPDATE array_fdw SET txt = ARRAY['newJim', 'newJoe'], int = ARRAY[-2, -1, 0, 1, 2], flt = ARRAY[-0.1, 0.0, 0.1] WHERE fid = 3; SELECT txt, int, flt FROM array_fdw WHERE fid = 3; pgsql-ogr-fdw-1.1.9/input/postgis.source000066400000000000000000000050571522375352200203010ustar00rootroot00000000000000CREATE EXTENSION postgis; CREATE TABLE geometry_local ( fid serial primary key, geom geometry(Point, 4326), name varchar, age bigint, size integer, value float8, num numeric(6,2), dt date, tm time, dttm timestamp, varch char(8), yn char ); ---------------------------------------------------------------------- -- Populate local table INSERT INTO geometry_local (name, geom, age, size, value, num, dt, tm, dttm, varch, yn) VALUES ('Jim', 'SRID=4326;POINT(0 0)', 23, 1, 4.3, 5.5, '2010-10-10'::date, '13:23:21'::time, '2010-10-10 13:23:21'::timestamp, 'this', 'y' ); INSERT INTO geometry_local (name, geom, age, size, value, num, dt, tm, dttm, varch, yn) VALUES ('Marvin', 'SRID=4326;POINT(100 0)', 34, 2, 5.4, 10.13, '2011-11-11'::date, '15:21:45'::time, '2011-11-11 15:21:45'::timestamp, 'that', 'n' ); INSERT INTO geometry_local (name, geom, age, size, value, num, dt, tm, dttm, varch, yn) VALUES (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); ---------------------------------------------------------------------- -- Create remote table CREATE SERVER pgservergeom FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource 'PG:dbname=contrib_regression host=localhost', format 'PostgreSQL' ); CREATE FOREIGN TABLE geometry_fdw ( fid integer, geom geometry(point, 4326), name varchar, age bigint, size integer, value float8, num numeric(6,2), dt date, tm time, dttm timestamp, varch char(8), yn char ) SERVER pgservergeom OPTIONS (layer 'geometry_local'); SELECT fid, name, geom, age, size, value, num, dt, tm, dttm, varch, yn FROM geometry_fdw; SELECT a.name, b.name FROM geometry_local a JOIN geometry_fdw b USING (fid); EXPLAIN VERBOSE SELECT fid, name, geom, age, size, value, num, dt, tm, dttm, varch, yn FROM geometry_fdw; ---------------------------------------------------------------------- -- Remote Query and OGR SQL pushdown SET client_min_messages = DEBUG1; SELECT name, age, ST_AsText(geom) FROM geometry_fdw WHERE name = 'Jim' AND age <= 30 AND geom && ST_MakeEnvelope(-1, -1, 1, 1, 4326); SELECT name, ST_AsText(geom) FROM geometry_fdw WHERE ST_Intersects(geom, ST_MakeEnvelope(-1, -1, 1, 1, 4326)); SELECT name, ST_AsText(geom) FROM geometry_fdw WHERE geom && ST_MakeEnvelope(-180, -90, 180, 90, 4326); SELECT name, ST_AsText(geom) FROM geometry_fdw WHERE ST_MakeEnvelope(-180, -90, 180, 90, 4326) && geom; SELECT name, ST_AsText(geom) FROM geometry_fdw WHERE ST_MakeEnvelope(-180, -90, 180, 90, 4326) && ST_MakeEnvelope(-180, -90, 180, 90, 4326); pgsql-ogr-fdw-1.1.9/ogr_fdw--1.0--1.1.sql000066400000000000000000000004531522375352200173160ustar00rootroot00000000000000CREATE OR REPLACE FUNCTION ogr_fdw_version() RETURNS text AS 'MODULE_PATHNAME', 'ogr_fdw_version' LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; CREATE OR REPLACE FUNCTION ogr_fdw_drivers() RETURNS text[] AS 'MODULE_PATHNAME', 'ogr_fdw_drivers' LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; pgsql-ogr-fdw-1.1.9/ogr_fdw--1.1.sql000066400000000000000000000013771522375352200167530ustar00rootroot00000000000000/* ogr_fdw/ogr_fdw--1.1.sql */ -- complain if script is sourced in psql, rather than via CREATE EXTENSION \echo Use "CREATE EXTENSION ogr_fdw" to load this file. \quit CREATE FUNCTION ogr_fdw_handler() RETURNS fdw_handler AS 'MODULE_PATHNAME' LANGUAGE 'c' STRICT; CREATE FUNCTION ogr_fdw_validator(text[], oid) RETURNS void AS 'MODULE_PATHNAME' LANGUAGE 'c' STRICT; CREATE FOREIGN DATA WRAPPER ogr_fdw HANDLER ogr_fdw_handler VALIDATOR ogr_fdw_validator; CREATE OR REPLACE FUNCTION ogr_fdw_version() RETURNS text AS 'MODULE_PATHNAME', 'ogr_fdw_version' LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; CREATE OR REPLACE FUNCTION ogr_fdw_drivers() RETURNS text[] AS 'MODULE_PATHNAME', 'ogr_fdw_drivers' LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; pgsql-ogr-fdw-1.1.9/ogr_fdw.c000066400000000000000000002643461522375352200160330ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * ogr_fdw.c * foreign-data wrapper for GIS data access. * * Copyright (c) 2014-2015, Paul Ramsey * *------------------------------------------------------------------------- */ /* * PostgreSQL */ #include "postgres.h" /* * System */ #include #include /* * Require PostgreSQL >= 9.3 */ #if PG_VERSION_NUM < 90300 #error "OGR FDW requires PostgreSQL version 9.3 or higher" #else /* * Definition of stringToQualifiedNameList */ #if PG_VERSION_NUM >= 100000 #include "utils/regproc.h" #endif /* * Local structures */ #include "ogr_fdw.h" /* * Set up as a PgSQL module */ #ifdef PG_MODULE_MAGIC_EXT PG_MODULE_MAGIC_EXT( .name = "ogr_fdw", .version = OGR_FDW_VERSION ); #else PG_MODULE_MAGIC; #endif /* * Describes the valid options for objects that use this wrapper. */ struct OgrFdwOption { const char* optname; Oid optcontext; /* Oid of catalog in which option may appear */ bool optrequired; /* Flag mandatory options */ bool optfound; /* Flag whether options was specified by user */ }; #define OPT_DRIVER "format" #define OPT_SOURCE "datasource" #define OPT_LAYER "layer" #define OPT_COLUMN "column_name" #define OPT_CONFIG_OPTIONS "config_options" #define OPT_OPEN_OPTIONS "open_options" #define OPT_UPDATEABLE "updateable" #define OPT_CHAR_ENCODING "character_encoding" #define OGR_FDW_FRMT_INT64 "%lld" #define OGR_FDW_CAST_INT64(x) (long long)(x) /* * Valid options for ogr_fdw. * ForeignDataWrapperRelationId (no options) * ForeignServerRelationId (CREATE SERVER options) * UserMappingRelationId (CREATE USER MAPPING options) * ForeignTableRelationId (CREATE FOREIGN TABLE options) * * {optname, optcontext, optrequired, optfound} */ static struct OgrFdwOption valid_options[] = { /* OGR column mapping */ {OPT_COLUMN, AttributeRelationId, false, false}, /* OGR datasource options */ {OPT_SOURCE, ForeignServerRelationId, true, false}, {OPT_DRIVER, ForeignServerRelationId, false, false}, {OPT_UPDATEABLE, ForeignServerRelationId, false, false}, {OPT_CONFIG_OPTIONS, ForeignServerRelationId, false, false}, {OPT_CHAR_ENCODING, ForeignServerRelationId, false, false}, #if GDAL_VERSION_MAJOR >= 2 {OPT_OPEN_OPTIONS, ForeignServerRelationId, false, false}, #endif /* OGR layer options */ {OPT_LAYER, ForeignTableRelationId, true, false}, {OPT_UPDATEABLE, ForeignTableRelationId, false, false}, /* EOList marker */ {NULL, InvalidOid, false, false} }; /* * SQL functions */ extern Datum ogr_fdw_handler(PG_FUNCTION_ARGS); extern Datum ogr_fdw_validator(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(ogr_fdw_handler); PG_FUNCTION_INFO_V1(ogr_fdw_validator); void _PG_init(void); /* * FDW query callback routines */ static void ogrGetForeignRelSize(PlannerInfo* root, RelOptInfo* baserel, Oid foreigntableid); static void ogrGetForeignPaths(PlannerInfo* root, RelOptInfo* baserel, Oid foreigntableid); static ForeignScan* ogrGetForeignPlan(PlannerInfo* root, RelOptInfo* baserel, Oid foreigntableid, ForeignPath* best_path, List* tlist, List* scan_clauses #if PG_VERSION_NUM >= 90500 , Plan* outer_plan #endif ); static void ogrBeginForeignScan(ForeignScanState* node, int eflags); static TupleTableSlot* ogrIterateForeignScan(ForeignScanState* node); static void ogrReScanForeignScan(ForeignScanState* node); static void ogrEndForeignScan(ForeignScanState* node); /* * FDW modify callback routines */ #if PG_VERSION_NUM >= 140000 static void ogrAddForeignUpdateTargets(PlannerInfo* planinfo, unsigned int rte_index, RangeTblEntry* target_rte, Relation target_relation); #else static void ogrAddForeignUpdateTargets(Query* parsetree, RangeTblEntry* target_rte, Relation target_relation); #endif static void ogrBeginForeignModify(ModifyTableState* mtstate, ResultRelInfo* rinfo, List* fdw_private, int subplan_index, int eflags); static TupleTableSlot* ogrExecForeignInsert(EState* estate, ResultRelInfo* rinfo, TupleTableSlot* slot, TupleTableSlot* planSlot); static TupleTableSlot* ogrExecForeignUpdate(EState* estate, ResultRelInfo* rinfo, TupleTableSlot* slot, TupleTableSlot* planSlot); static TupleTableSlot* ogrExecForeignDelete(EState* estate, ResultRelInfo* rinfo, TupleTableSlot* slot, TupleTableSlot* planSlot); static void ogrEndForeignModify(EState* estate, ResultRelInfo* rinfo); static int ogrIsForeignRelUpdatable(Relation rel); #if PG_VERSION_NUM >= 90500 static List* ogrImportForeignSchema(ImportForeignSchemaStmt* stmt, Oid serverOid); #endif /* * Helper functions */ static OgrConnection ogrGetConnectionFromTable(Oid foreigntableid, OgrUpdateable updateable); static void ogr_fdw_exit(int code, Datum arg); static void ogrReadColumnData(OgrFdwState* state); /* Global to hold GEOMETRYOID */ Oid GEOMETRYOID = InvalidOid; #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,1,0) static const char* const gdalErrorTypes[] = { "None", "AppDefined", "OutOfMemory", "FileIO", "OpenFailed", "IllegalArg", "NotSupported", "AssertionFailed", "NoWriteAccess", "UserInterrupt", "ObjectNull", "HttpResponse", "AWSBucketNotFound", "AWSObjectNotFound", "AWSAccessDenied", "AWSInvalidCredentials", "AWSSignatureDoesNotMatch" }; /* In theory this function should be declared "static void CPL_STDCALL" */ /* since this is the official signature of error handler callbacks. */ /* That would be needed if both GDAL and ogr_fdw were compiled with Visual */ /* Studio, but with non-Visual Studio compilers, the macro expands to empty, */ /* so if both GDAL and ogr_fdw are compiled with gcc things are fine. In case */ /* of mixes, crashes may occur but there is no clean fix... So let this as a note */ /* in case of future issue... */ static void ogrErrorHandler(CPLErr eErrClass, int err_no, const char* msg) { const char* gdalErrType = "unknown type"; if (err_no >= 0 && err_no < (int)sizeof(gdalErrorTypes) / sizeof(gdalErrorTypes[0])) { gdalErrType = gdalErrorTypes[err_no]; } switch (eErrClass) { case CE_None: elog(NOTICE, "GDAL %s [%d] %s", gdalErrType, err_no, msg); break; case CE_Debug: elog(DEBUG2, "GDAL %s [%d] %s", gdalErrType, err_no, msg); break; case CE_Warning: elog(WARNING, "GDAL %s [%d] %s", gdalErrType, err_no, msg); break; case CE_Failure: case CE_Fatal: default: elog(ERROR, "GDAL %s [%d] %s", gdalErrType, err_no, msg); break; } return; } #endif /* GDAL 2.1.0+ */ void _PG_init(void) { on_proc_exit(&ogr_fdw_exit, PointerGetDatum(NULL)); #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,1,0) /* Hook up the GDAL error handlers to PgSQL elog() */ CPLSetErrorHandler(ogrErrorHandler); CPLSetCurrentErrorHandlerCatchDebug(true); #endif } /* * ogr_fdw_exit: Exit callback function. */ static void ogr_fdw_exit(int code, Datum arg) { OGRCleanupAll(); } /* * Given extension oid, lookup installation namespace oid. * This side steps search_path issues with * TypenameGetTypid encountered in * https://github.com/pramsey/pgsql-ogr-fdw/issues/263 */ static Oid get_extension_nsp_oid(Oid extOid) { Oid result; SysScanDesc scandesc; HeapTuple tuple; ScanKeyData entry[1]; #if PG_VERSION_NUM < 120000 Relation rel = heap_open(ExtensionRelationId, AccessShareLock); ScanKeyInit(&entry[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(extOid)); #else Relation rel = table_open(ExtensionRelationId, AccessShareLock); ScanKeyInit(&entry[0], Anum_pg_extension_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(extOid)); #endif /* PG_VERSION_NUM */ scandesc = systable_beginscan(rel, ExtensionOidIndexId, true, NULL, 1, entry); tuple = systable_getnext(scandesc); /* We assume that there can be at most one matching tuple */ if (HeapTupleIsValid(tuple)) result = ((Form_pg_extension) GETSTRUCT(tuple))->extnamespace; else result = InvalidOid; systable_endscan(scandesc); #if PG_VERSION_NUM < 120000 heap_close(rel, AccessShareLock); #else table_close(rel, AccessShareLock); #endif return result; } /* * Get the geometry OID (if postgis is * installed) and cache it for quick lookup. */ Oid ogrGetGeometryOid(void) { /* Is value not set yet? */ if (GEOMETRYOID == InvalidOid) { const char *extName = "postgis"; const char *typName = "geometry"; bool missing_ok = true; Oid extOid, extNspOid, typOid; /* Got postgis extension? */ extOid = get_extension_oid(extName, missing_ok); if (!OidIsValid(extOid)) { elog(DEBUG2, "%s: lookup of extension '%s' failed", __func__, extName); GEOMETRYOID = BYTEAOID; return GEOMETRYOID; } /* Got namespace for extension? */ extNspOid = get_extension_nsp_oid(extOid); if (!OidIsValid(extNspOid)) { elog(DEBUG2, "%s: lookup of namespace for '%s' (%u) failed", __func__, extName, extOid); GEOMETRYOID = BYTEAOID; return GEOMETRYOID; } /* Got geometry type in namespace? */ typOid = GetSysCacheOid2(TYPENAMENSP, #if PG_VERSION_NUM >= 120000 Anum_pg_type_oid, #endif PointerGetDatum(typName), ObjectIdGetDatum(extNspOid)); elog(DEBUG2, "%s: lookup of type id for '%s' got %u", __func__, typName, typOid); /* Geometry type is good? */ if (OidIsValid(typOid) && get_typisdefined(typOid)) GEOMETRYOID = typOid; else GEOMETRYOID = BYTEAOID; } return GEOMETRYOID; } /* * Foreign-data wrapper handler function: return a struct with pointers * to my callback routines. */ Datum ogr_fdw_handler(PG_FUNCTION_ARGS) { FdwRoutine* fdwroutine = makeNode(FdwRoutine); /* Read support */ fdwroutine->GetForeignRelSize = ogrGetForeignRelSize; fdwroutine->GetForeignPaths = ogrGetForeignPaths; fdwroutine->GetForeignPlan = ogrGetForeignPlan; fdwroutine->BeginForeignScan = ogrBeginForeignScan; fdwroutine->IterateForeignScan = ogrIterateForeignScan; fdwroutine->ReScanForeignScan = ogrReScanForeignScan; fdwroutine->EndForeignScan = ogrEndForeignScan; /* Write support */ fdwroutine->AddForeignUpdateTargets = ogrAddForeignUpdateTargets; fdwroutine->BeginForeignModify = ogrBeginForeignModify; fdwroutine->ExecForeignInsert = ogrExecForeignInsert; fdwroutine->ExecForeignUpdate = ogrExecForeignUpdate; fdwroutine->ExecForeignDelete = ogrExecForeignDelete; fdwroutine->EndForeignModify = ogrEndForeignModify; fdwroutine->IsForeignRelUpdatable = ogrIsForeignRelUpdatable; #if PG_VERSION_NUM >= 90500 /* Support functions for IMPORT FOREIGN SCHEMA */ fdwroutine->ImportForeignSchema = ogrImportForeignSchema; #endif PG_RETURN_POINTER(fdwroutine); } /* * When attempting a soft open (allowing for failure and retry), * we might need to call the opening * routines twice, so all the opening machinery is placed here * for convenient re-calling. */ static OGRErr ogrGetDataSourceAttempt(OgrConnection* ogr, bool bUpdateable, char** open_option_list) { GDALDriverH ogr_dr = NULL; #if GDAL_VERSION_MAJOR >= 2 unsigned int open_flags = GDAL_OF_VECTOR; if (bUpdateable) { open_flags |= GDAL_OF_UPDATE; } else { open_flags |= GDAL_OF_READONLY; } #endif if (ogr->dr_str) { ogr_dr = GDALGetDriverByName(ogr->dr_str); if (!ogr_dr) { ereport(ERROR, (errcode(ERRCODE_FDW_UNABLE_TO_ESTABLISH_CONNECTION), errmsg("unable to find format \"%s\"", ogr->dr_str), errhint("See the formats list at http://www.gdal.org/ogr_formats.html"))); } #if GDAL_VERSION_MAJOR < 2 ogr->ds = OGR_Dr_Open(ogr_dr, ogr->ds_str, bUpdateable); #else { char** driver_list = CSLAddString(NULL, ogr->dr_str); ogr->ds = GDALOpenEx(ogr->ds_str, /* file/data source */ open_flags, /* open flags */ (const char* const*)driver_list, /* driver */ (const char* const*)open_option_list, /* open options */ NULL); /* sibling files */ CSLDestroy(driver_list); } #endif } /* No driver, try a blind open... */ else { #if GDAL_VERSION_MAJOR < 2 ogr->ds = OGROpen(ogr->ds_str, bUpdateable, &ogr_dr); #else ogr->ds = GDALOpenEx(ogr->ds_str, open_flags, NULL, (const char* const*)open_option_list, NULL); #endif } return ogr->ds ? OGRERR_NONE : OGRERR_FAILURE; } /* * Given a connection string and (optional) driver string, try to connect * with appropriate error handling and reporting. Used in query startup, * and in FDW options validation. */ static OGRErr ogrGetDataSource(OgrConnection* ogr, OgrUpdateable updateable) { char** open_option_list = NULL; bool bUpdateable = (updateable == OGR_UPDATEABLE_TRUE || updateable == OGR_UPDATEABLE_TRY); OGRErr err; /* Set the GDAL config options into the environment */ if (ogr->config_options) { char** option_iter; char** option_list = CSLTokenizeString(ogr->config_options); for (option_iter = option_list; option_iter && *option_iter; option_iter++) { char* key; const char* value; value = CPLParseNameValue(*option_iter, &key); if (!(key && value)) { elog(ERROR, "bad config option string '%s'", ogr->config_options); } elog(DEBUG1, "GDAL config option '%s' set to '%s'", key, value); CPLSetConfigOption(key, value); CPLFree(key); } CSLDestroy(option_list); } /* Parse the GDAL layer open options */ if (ogr->open_options) { open_option_list = CSLTokenizeString(ogr->open_options); } /* Cannot search for drivers if they aren't registered, */ /* but don't do registration if we already have drivers loaded */ if (GDALGetDriverCount() <= 0) { GDALAllRegister(); } /* First attempt at connection */ err = ogrGetDataSourceAttempt(ogr, bUpdateable, open_option_list); /* Failed on soft updateable attempt, try and fall back to readonly */ if ((!ogr->ds) && updateable == OGR_UPDATEABLE_TRY) { err = ogrGetDataSourceAttempt(ogr, false, open_option_list); /* Succeeded with readonly connection */ if (ogr->ds) { ogr->ds_updateable = ogr->lyr_updateable = OGR_UPDATEABLE_FALSE; } } /* Open failed, provide error hint if OGR gives us one. */ if (!ogr->ds) { const char* ogrerrmsg = CPLGetLastErrorMsg(); if (ogrerrmsg && !streq(ogrerrmsg, "")) { ereport(ERROR, (errcode(ERRCODE_FDW_UNABLE_TO_ESTABLISH_CONNECTION), errmsg("unable to connect to data source \"%s\"", ogr->ds_str), errhint("%s", ogrerrmsg))); } else { ereport(ERROR, (errcode(ERRCODE_FDW_UNABLE_TO_ESTABLISH_CONNECTION), errmsg("unable to connect to data source \"%s\"", ogr->ds_str))); } } CSLDestroy(open_option_list); return err; } static bool ogrCanReallyCountFast(const OgrConnection* con) { GDALDriverH dr = GDALGetDatasetDriver(con->ds); const char* dr_str = GDALGetDriverShortName(dr); if (streq(dr_str, "ESRI Shapefile") || streq(dr_str, "FileGDB") || streq(dr_str, "OpenFileGDB")) { return true; } return false; } static void ogrEreportError(const char* errstr) { const char* ogrerrmsg = CPLGetLastErrorMsg(); if (ogrerrmsg && !streq(ogrerrmsg, "")) { ereport(ERROR, (errcode(ERRCODE_FDW_ERROR), errmsg("%s", errstr), errhint("%s", ogrerrmsg))); } else { ereport(ERROR, (errcode(ERRCODE_FDW_ERROR), errmsg("%s", errstr))); } } /* * Make sure the datasource is cleaned up when we're done * with a connection. */ static void ogrFinishConnection(OgrConnection* ogr) { elog(DEBUG3, "%s: entered function", __func__); if (ogr->lyr && OGR_L_SyncToDisk(ogr->lyr) != OGRERR_NONE) { elog(NOTICE, "failed to flush writes to OGR data source"); } if (ogr->ds) { GDALClose(ogr->ds); } ogr->ds = NULL; } static OgrConnection ogrGetConnectionFromServer(Oid foreignserverid, OgrUpdateable updateable) { ForeignServer* server; OgrConnection ogr; ListCell* cell; OGRErr err; elog(DEBUG3, "%s: entered function", __func__); /* Null all values */ memset(&ogr, 0, sizeof(OgrConnection)); ogr.ds_updateable = OGR_UPDATEABLE_UNSET; ogr.lyr_updateable = OGR_UPDATEABLE_UNSET; server = GetForeignServer(foreignserverid); foreach (cell, server->options) { DefElem* def = (DefElem*) lfirst(cell); if (streq(def->defname, OPT_SOURCE)) { ogr.ds_str = defGetString(def); } if (streq(def->defname, OPT_DRIVER)) { ogr.dr_str = defGetString(def); } if (streq(def->defname, OPT_CONFIG_OPTIONS)) { ogr.config_options = defGetString(def); } if (streq(def->defname, OPT_OPEN_OPTIONS)) { ogr.open_options = defGetString(def); } if (streq(def->defname, OPT_CHAR_ENCODING)) { ogr.char_encoding = pg_char_to_encoding(defGetString(def)); } if (streq(def->defname, OPT_UPDATEABLE)) { if (defGetBoolean(def)) { ogr.ds_updateable = OGR_UPDATEABLE_TRUE; } else { ogr.ds_updateable = OGR_UPDATEABLE_FALSE; /* Over-ride the open mode to favour user-defined mode */ updateable = OGR_UPDATEABLE_FALSE; } } } if (!ogr.ds_str) { elog(ERROR, "FDW table '%s' option is missing", OPT_SOURCE); } /* * TODO: Connections happen twice for each query, having a * connection pool will certainly make things faster. */ /* Connect! */ err = ogrGetDataSource(&ogr, updateable); if (err == OGRERR_FAILURE) { elog(ERROR, "ogrGetDataSource failed"); } return ogr; } /* * Read the options (data source connection from server and * layer name from table) from a foreign table and use them * to connect to an OGR layer. Return a connection object that * has handles for both the datasource and layer. */ static OgrConnection ogrGetConnectionFromTable(Oid foreigntableid, OgrUpdateable updateable) { ForeignTable* table; /* UserMapping *mapping; */ /* ForeignDataWrapper *wrapper; */ ListCell* cell; OgrConnection ogr; elog(DEBUG3, "%s: entered function", __func__); /* Gather all data for the foreign table. */ table = GetForeignTable(foreigntableid); /* mapping = GetUserMapping(GetUserId(), table->serverid); */ ogr = ogrGetConnectionFromServer(table->serverid, updateable); elog(DEBUG3, "%s: ogr.ds_str = %s", __func__, ogr.ds_str); foreach (cell, table->options) { DefElem* def = (DefElem*) lfirst(cell); if (streq(def->defname, OPT_LAYER)) { ogr.lyr_str = defGetString(def); } if (streq(def->defname, OPT_UPDATEABLE)) { if (defGetBoolean(def)) { if (ogr.ds_updateable == OGR_UPDATEABLE_FALSE) { ereport(ERROR, ( errcode(ERRCODE_FDW_ERROR), errmsg("data source \"%s\" is not updateable", ogr.ds_str), errhint("cannot set table '%s' option to true", OPT_UPDATEABLE) )); } ogr.lyr_updateable = OGR_UPDATEABLE_TRUE; } else { ogr.lyr_updateable = OGR_UPDATEABLE_FALSE; } } } if (!ogr.lyr_str) { elog(ERROR, "FDW table '%s' option is missing", OPT_LAYER); } elog(DEBUG3, "%s: ogr.lyr_str = %s", __func__, ogr.lyr_str); /* Does the layer exist in the data source? */ ogr.lyr = GDALDatasetGetLayerByName(ogr.ds, ogr.lyr_str); if (!ogr.lyr) { const char* ogrerr = CPLGetLastErrorMsg(); ereport(ERROR, ( errcode(ERRCODE_FDW_TABLE_NOT_FOUND), errmsg("unable to connect to %s to \"%s\"", OPT_LAYER, ogr.lyr_str), (ogrerr && ! streq(ogrerr, "")) ? errhint("%s", ogrerr) : errhint("Does the layer exist?") )); } if (OGR_L_TestCapability(ogr.lyr, OLCStringsAsUTF8)) { ogr.char_encoding = PG_UTF8; } return ogr; } /* * Validate the options given to a FOREIGN DATA WRAPPER, SERVER, * USER MAPPING or FOREIGN TABLE that uses ogr_fdw. * * Raise an ERROR if the option or its value is considered invalid. */ Datum ogr_fdw_validator(PG_FUNCTION_ARGS) { List* options_list = untransformRelOptions(PG_GETARG_DATUM(0)); Oid catalog = PG_GETARG_OID(1); ListCell* cell; struct OgrFdwOption* opt; const char* source = NULL, *driver = NULL; const char* config_options = NULL, *open_options = NULL; OgrUpdateable updateable = OGR_UPDATEABLE_FALSE; /* Initialize found state to not found */ for (opt = valid_options; opt->optname; opt++) { opt->optfound = false; } /* * Check that only options supported by ogr_fdw, and allowed for the * current object type, are given. */ foreach (cell, options_list) { DefElem* def = (DefElem*) lfirst(cell); bool optfound = false; for (opt = valid_options; opt->optname; opt++) { if (catalog == opt->optcontext && streq(opt->optname, def->defname)) { /* Mark that this user option was found */ opt->optfound = optfound = true; /* Store some options for testing later */ if (streq(opt->optname, OPT_SOURCE)) { source = defGetString(def); } if (streq(opt->optname, OPT_DRIVER)) { driver = defGetString(def); } if (streq(opt->optname, OPT_CONFIG_OPTIONS)) { config_options = defGetString(def); } if (streq(opt->optname, OPT_OPEN_OPTIONS)) { open_options = defGetString(def); } if (streq(opt->optname, OPT_UPDATEABLE)) { if (defGetBoolean(def)) { updateable = OGR_UPDATEABLE_TRY; } } break; } } if (!optfound) { /* * Unknown option specified, complain about it. Provide a hint * with list of valid options for the object. */ const struct OgrFdwOption* opt; StringInfoData buf; initStringInfo(&buf); for (opt = valid_options; opt->optname; opt++) { if (catalog == opt->optcontext) appendStringInfo(&buf, "%s%s", (buf.len > 0) ? ", " : "", opt->optname); } ereport(ERROR, ( errcode(ERRCODE_FDW_INVALID_OPTION_NAME), errmsg("invalid option \"%s\"", def->defname), buf.len > 0 ? errhint("Valid options in this context are: %s", buf.data) : errhint("There are no valid options in this context."))); } } /* Check that all the mandatory options were found */ for (opt = valid_options; opt->optname; opt++) { /* Required option for this catalog type is missing? */ if (catalog == opt->optcontext && opt->optrequired && ! opt->optfound) { ereport(ERROR, ( errcode(ERRCODE_FDW_DYNAMIC_PARAMETER_VALUE_NEEDED), errmsg("required option \"%s\" is missing", opt->optname))); } } /* Make sure server connection can actually be established */ if (catalog == ForeignServerRelationId && source) { OgrConnection ogr; OGRErr err; ogr.ds_str = source; ogr.dr_str = driver; ogr.config_options = config_options; ogr.open_options = open_options; err = ogrGetDataSource(&ogr, updateable); if (err == OGRERR_FAILURE) { elog(ERROR, "ogrGetDataSource failed"); } if (ogr.ds) { GDALClose(ogr.ds); } } PG_RETURN_VOID(); } /* * Initialize an OgrFdwPlanState on the heap. */ static OgrFdwState* getOgrFdwState(Oid foreigntableid, OgrFdwStateType state_type) { OgrFdwState* state; size_t size; OgrUpdateable updateable = OGR_UPDATEABLE_FALSE; switch (state_type) { case OGR_PLAN_STATE: size = sizeof(OgrFdwPlanState); updateable = OGR_UPDATEABLE_FALSE; break; case OGR_EXEC_STATE: size = sizeof(OgrFdwExecState); updateable = OGR_UPDATEABLE_FALSE; break; case OGR_MODIFY_STATE: updateable = OGR_UPDATEABLE_TRUE; size = sizeof(OgrFdwModifyState); break; default: elog(ERROR, "invalid state type"); } state = palloc0(size); state->type = state_type; /* Connect! */ state->ogr = ogrGetConnectionFromTable(foreigntableid, updateable); state->foreigntableid = foreigntableid; return state; } /* * ogrGetForeignRelSize * Obtain relation size estimates for a foreign table */ static void ogrGetForeignRelSize(PlannerInfo* root, RelOptInfo* baserel, Oid foreigntableid) { /* Initialize the OGR connection */ OgrFdwState* state = (OgrFdwState*)getOgrFdwState(foreigntableid, OGR_PLAN_STATE); OgrFdwPlanState* planstate = (OgrFdwPlanState*)state; List* scan_clauses = baserel->baserestrictinfo; elog(DEBUG3, "%s: entered function", __func__); /* Set to NULL to clear the restriction clauses in OGR */ OGR_L_SetIgnoredFields(planstate->ogr.lyr, NULL); OGR_L_SetSpatialFilter(planstate->ogr.lyr, NULL); OGR_L_SetAttributeFilter(planstate->ogr.lyr, NULL); /* * The estimate number of rows returned must actually use restrictions. * Since OGR can't really give us a fast count with restrictions on * (usually involves a scan) and restrictions in the baserel mean we * must punt row count estimates. */ /* TODO: calculate the row width based on the attribute types of the OGR table */ /* * OGR asks drivers to honestly state if they can provide a fast * row count, but too many drivers lie. We are only listing drivers * we trust in ogrCanReallyCountFast() */ /* If we can quickly figure how many rows this layer has, then do so */ if (scan_clauses == NIL && OGR_L_TestCapability(planstate->ogr.lyr, OLCFastFeatureCount) == TRUE && ogrCanReallyCountFast(&(planstate->ogr))) { /* Count rows, but don't force a slow count */ int rows = OGR_L_GetFeatureCount(planstate->ogr.lyr, false); /* Only use row count if return is valid (>0) */ if (rows >= 0) { planstate->nrows = rows; baserel->rows = rows; } } /* Save connection state for next calls */ baserel->fdw_private = (void*) planstate; return; } /* * ogrGetForeignPaths * Create possible access paths for a scan on the foreign table * * Currently there is only one * possible access path, which simply returns all records in the order in * the data file. */ static void ogrGetForeignPaths(PlannerInfo* root, RelOptInfo* baserel, Oid foreigntableid) { OgrFdwPlanState* planstate = (OgrFdwPlanState*)(baserel->fdw_private); elog(DEBUG3, "%s: entered function", __func__); /* TODO: replace this with something that looks at the OGRDriver and */ /* makes a determination based on that? Better: add connection caching */ /* so that slow startup doesn't matter so much */ planstate->startup_cost = 25; /* TODO: more research on what the total cost is supposed to mean, */ /* relative to the startup cost? */ planstate->total_cost = planstate->startup_cost + baserel->rows; /* Built the (one) path we are providing. Providing fancy paths is */ /* really only possible with back-ends that can properly provide */ /* explain info on how they complete the query, not for something as */ /* obtuse as OGR. (So far, have only seen it w/ the postgres_fdw */ add_path(baserel, (Path*) create_foreignscan_path(root, baserel, #if PG_VERSION_NUM >= 90600 NULL, /* PathTarget */ #endif baserel->rows, #if PG_VERSION_NUM >= 180000 0, /* disabled_nodes */ #endif planstate->startup_cost, planstate->total_cost, NIL, /* no pathkeys */ NULL, /* no lateral_relids */ NULL /* no extra plan */ #if PG_VERSION_NUM >= 170000 , NIL /* no fdw_restrictinfo list */ #endif #if PG_VERSION_NUM >= 90500 , NIL /* no fdw_private list */ #endif ) ); /* no fdw_private data */ } /* * Convert an OgrFdwSpatialFilter into a List so it can * be safely passed through the fdw_private list. */ static List* ogrSpatialFilterToList(const OgrFdwSpatialFilter* spatial_filter) { List *l = NIL; if (spatial_filter) { l = lappend(l, makeInteger(spatial_filter->ogrfldnum)); l = lappend(l, makeFloat(psprintf("%.17g", spatial_filter->minx))); l = lappend(l, makeFloat(psprintf("%.17g", spatial_filter->miny))); l = lappend(l, makeFloat(psprintf("%.17g", spatial_filter->maxx))); l = lappend(l, makeFloat(psprintf("%.17g", spatial_filter->maxy))); } return l; } /* * Convert the List form back into an OgrFdwSpatialFilter * after passing through fdw_private. */ static OgrFdwSpatialFilter* ogrSpatialFilterFromList(const List* lst) { OgrFdwSpatialFilter* spatial_filter; if (lst == NIL) return NULL; Assert(list_length(lst) == 5); spatial_filter = palloc(sizeof(OgrFdwSpatialFilter)); spatial_filter->ogrfldnum = intVal(linitial(lst)); spatial_filter->minx = floatVal(lsecond(lst)); spatial_filter->miny = floatVal(lthird(lst)); spatial_filter->maxx = floatVal(lfourth(lst)); spatial_filter->maxy = floatVal(list_nth(lst, 4)); /* list_nth counts from zero */ return spatial_filter; } /* * fileGetForeignPlan * Create a ForeignScan plan node for scanning the foreign table */ static ForeignScan* ogrGetForeignPlan(PlannerInfo* root, RelOptInfo* baserel, Oid foreigntableid, ForeignPath* best_path, List* tlist, List* scan_clauses #if PG_VERSION_NUM >= 90500 , Plan* outer_plan #endif ) { Index scan_relid = baserel->relid; bool sql_generated; StringInfoData sql; List* params_list = NULL; List* fdw_private; OgrFdwPlanState* planstate = (OgrFdwPlanState*)(baserel->fdw_private); OgrFdwState* state = (OgrFdwState*)(baserel->fdw_private); OgrFdwSpatialFilter* spatial_filter = NULL; char* attribute_filter = NULL; elog(DEBUG3, "%s: entered function", __func__); /* Add in column mapping data to build SQL with the right OGR column names */ ogrReadColumnData(state); /* * TODO: Review the columns requested (via params_list) and only pull those back, using * OGR_L_SetIgnoredFields. This is less important than pushing restrictions * down to OGR via OGR_L_SetAttributeFilter (done) and (TODO) OGR_L_SetSpatialFilter. */ initStringInfo(&sql); sql_generated = ogrDeparse(&sql, root, baserel, scan_clauses, state, ¶ms_list, &spatial_filter); /* Extract the OGR SQL from the StringInfoData */ if (sql_generated && sql.len > 0) attribute_filter = sql.data; /* Log filters at debug level one as necessary */ if (attribute_filter) elog(DEBUG1, "OGR SQL: %s", attribute_filter); if (spatial_filter) elog(DEBUG1, "OGR spatial filter (%g %g, %g %g)", spatial_filter->minx, spatial_filter->miny, spatial_filter->maxx, spatial_filter->maxy); /* * Here we strip RestrictInfo * nodes from the clauses and ignore pseudoconstants (which will be * handled elsewhere). * Some FDW implementations (mysql_fdw) just pass this full list on to the * make_foreignscan function. postgres_fdw carefully separates local and remote * clauses and only passes the local ones to make_foreignscan, so this * is probably best practice, though re-applying the clauses is probably * the least of our performance worries with this fdw. For now, we just * pass them all to make_foreignscan, see no evil, etc. */ scan_clauses = extract_actual_clauses(scan_clauses, false); /* Pack the data we want to pass to the execution stage into a List. */ /* The members of this list must by copyable by PgSQL, which means */ /* they need to be Lists themselves, or Value nodes, otherwise when */ /* the plan gets copied the copy might fail. */ fdw_private = list_make3(makeString(attribute_filter), params_list, ogrSpatialFilterToList(spatial_filter)); /* Clean up our connection */ ogrFinishConnection(&(planstate->ogr)); /* Create the ForeignScan node */ return make_foreignscan(tlist, scan_clauses, scan_relid, NIL, /* no expressions to evaluate */ fdw_private #if PG_VERSION_NUM >= 90500 , NIL /* no scan_tlist */ , NIL /* no remote quals */ , outer_plan #endif ); } static bool pgCanConvertToOgr(Oid pg_type, OGRFieldType ogr_type) { struct PgOgrMap { Oid pg; OGRFieldType ogr; }; static struct PgOgrMap data[] = { {BOOLOID, OFTInteger}, /* 16 */ {BYTEAOID, OFTBinary}, /* 17 */ {CHAROID, OFTString}, /* 18 */ {NAMEOID, OFTString}, /* 19 */ #if GDAL_VERSION_MAJOR >= 2 {INT8OID, OFTInteger64}, /* 20 */ #else {INT8OID, OFTInteger}, /* 20 */ #endif {INT2OID, OFTInteger}, /* 21 */ {INT4OID, OFTInteger}, /* 23 */ {TEXTOID, OFTString}, /* 25 */ {FLOAT4OID, OFTReal}, /* 700 */ {FLOAT8OID, OFTReal}, /* 701 */ {BOOLARRAYOID, OFTIntegerList}, /* 1000 */ {CHARARRAYOID, OFTStringList}, /* 1002 */ {NAMEARRAYOID, OFTStringList}, /* 1003 */ {INT2ARRAYOID, OFTIntegerList}, /* 1005 */ {INT4ARRAYOID, OFTIntegerList}, /* 1007 */ {TEXTARRAYOID, OFTStringList}, /* 1009 */ {VARCHARARRAYOID, OFTStringList}, /* 1015 */ #if GDAL_VERSION_MAJOR >= 2 {INT8ARRAYOID, OFTInteger64List}, /* 1016 */ #endif {FLOAT4ARRAYOID, OFTRealList}, /* 1021 */ {FLOAT8ARRAYOID, OFTRealList}, /* 1022 */ {BPCHAROID, OFTString}, /* 1042 */ {VARCHAROID, OFTString}, /* 1043 */ {DATEOID, OFTDate}, /* 1082 */ {TIMEOID, OFTTime}, /* 1083 */ {TIMESTAMPOID, OFTDateTime}, /* 1114 */ {NUMERICOID, OFTReal}, /* 1700 */ {0, 0}}; struct PgOgrMap* map = data; while (map->pg) { if (ogr_type == map->ogr) return true; else map++; } return false; } static void pgCheckConvertToOgr(Oid pg_type, OGRFieldType ogr_type, const char *colname, const char *tblname) { if (pgCanConvertToOgr(pg_type, ogr_type)) return; ereport(ERROR, ( errcode(ERRCODE_FDW_INVALID_DATA_TYPE), errmsg("column \"%s\" of foreign table \"%s\" converts \"%s\" to OGR \"%s\"", colname, tblname, format_type_be(pg_type), OGR_GetFieldTypeName(ogr_type)) )); } static bool ogrCanConvertToPg(OGRFieldType ogr_type, Oid pg_type) { struct OgrPgMap { OGRFieldType ogr; Oid pg[16]; }; static struct OgrPgMap data[] = { {OFTInteger, {BOOLOID, INT4OID, INT8OID, NUMERICOID, FLOAT4OID, FLOAT8OID, TEXTOID, VARCHAROID, 0}}, {OFTReal, {NUMERICOID, FLOAT4OID, FLOAT8OID, TEXTOID, VARCHAROID, 0}}, {OFTBinary, {BYTEAOID, 0}}, {OFTString, {TEXTOID, VARCHAROID, CHAROID, BPCHAROID, JSONBOID, JSONOID, 0}}, {OFTDate, {DATEOID, TIMESTAMPOID, TEXTOID, VARCHAROID, 0}}, {OFTTime, {TIMEOID, TEXTOID, VARCHAROID, 0}}, {OFTDateTime, {TIMESTAMPOID, TEXTOID, VARCHAROID, 0}}, #if GDAL_VERSION_MAJOR >= 2 {OFTInteger64, {INT8OID, NUMERICOID, FLOAT8OID, TEXTOID, VARCHAROID, 0}}, {OFTInteger64List, {INT8ARRAYOID, FLOAT8ARRAYOID, TEXTARRAYOID, VARCHARARRAYOID, 0}}, #endif {OFTRealList, {FLOAT4ARRAYOID, FLOAT8ARRAYOID, TEXTARRAYOID, VARCHARARRAYOID, 0}}, {OFTStringList, {TEXTARRAYOID, VARCHARARRAYOID, NAMEARRAYOID, CHARARRAYOID, 0}}, {OFTIntegerList, {BOOLARRAYOID, INT2ARRAYOID, INT4ARRAYOID, INT8ARRAYOID, TEXTARRAYOID, VARCHARARRAYOID, 0}}, {256, {0}} /* Zero terminate list */ }; struct OgrPgMap* map = data; while (map->ogr <= OFTMaxType) { if (ogr_type == map->ogr) { Oid *typ = map->pg; while (*typ) { if (pg_type == *typ) return true; else typ++; } } map++; } return false; } static void ogrCheckConvertToPg(OGRFieldType ogr_type, Oid pg_type, const char *colname, const char *tblname) { if (ogrCanConvertToPg(ogr_type, pg_type)) return; if (ogr_type == OFTWideString || ogr_type == OFTWideStringList) { ereport(ERROR, ( errcode(ERRCODE_FDW_INVALID_DATA_TYPE), errmsg("column \"%s\" of foreign table \"%s\" uses an OGR OFTWideString, deprecated", colname, tblname) )); return; } ereport(ERROR, ( errcode(ERRCODE_FDW_INVALID_DATA_TYPE), errmsg("column \"%s\" of foreign table \"%s\" converts OGR \"%s\" to \"%s\"", colname, tblname, OGR_GetFieldTypeName(ogr_type), format_type_be(pg_type)) )); } #ifdef OGR_FDW_HEXWKB static char* hexchr = "0123456789ABCDEF"; static char* ogrBytesToHex(unsigned char* bytes, size_t size) { char* hex; int i; if (! bytes || ! size) { elog(ERROR, "ogrBytesToHex: invalid input"); return NULL; } hex = palloc(size * 2 + 1); hex[2 * size] = '\0'; for (i = 0; i < size; i++) { /* Top four bits to 0-F */ hex[2 * i] = hexchr[bytes[i] >> 4]; /* Bottom four bits to 0-F */ hex[2 * i + 1] = hexchr[bytes[i] & 0x0F]; } return hex; } #endif static void freeOgrFdwTable(OgrFdwTable* table) { if (table) { if (table->tblname) { pfree(table->tblname); } if (table->cols) { pfree(table->cols); } pfree(table); } } typedef struct { char* fldname; int fldnum; } OgrFieldEntry; static int ogrFieldEntryCmpFunc(const void* a, const void* b) { const char* a_name = ((OgrFieldEntry*)a)->fldname; const char* b_name = ((OgrFieldEntry*)b)->fldname; return strcasecmp(a_name, b_name); } /* * The execstate holds a foreign table relation id and an OGR connection, * this function finds all the OGR fields that match up to columns in the * foreign table definition, using columns name match and data type consistency * as the criteria for making a match. * The results of the matching are stored in the execstate before the function * returns. */ static void ogrReadColumnData(OgrFdwState* state) { Relation rel; TupleDesc tupdesc; int i; OgrFdwTable* tbl; OGRFeatureDefnH dfn; int ogr_ncols; int fid_count = 0; int geom_count = 0; int ogr_geom_count = 0; int field_count = 0; OgrFieldEntry* ogr_fields; int ogr_fields_count = 0; char* tblname = get_rel_name(state->foreigntableid); /* Blow away any existing table in the state */ if (state->table) { freeOgrFdwTable(state->table); state->table = NULL; } /* Fresh table */ tbl = palloc0(sizeof(OgrFdwTable)); /* One column for each PgSQL foreign table column */ #if PG_VERSION_NUM < 120000 rel = heap_open(state->foreigntableid, NoLock); #else rel = table_open(state->foreigntableid, NoLock); #endif /* PG_VERSION_NUM */ tupdesc = rel->rd_att; state->tupdesc = tupdesc; tbl->ncols = tupdesc->natts; tbl->cols = palloc0(tbl->ncols * sizeof(OgrFdwColumn)); tbl->tblname = pstrdup(tblname); /* Get OGR metadata ready */ dfn = OGR_L_GetLayerDefn(state->ogr.lyr); ogr_ncols = OGR_FD_GetFieldCount(dfn); #if (GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(1,11,0)) ogr_geom_count = OGR_FD_GetGeomFieldCount(dfn); #else ogr_geom_count = (OGR_FD_GetGeomType(dfn) != wkbNone) ? 1 : 0; #endif /* Prepare sorted list of OGR column names */ /* TODO: change this to a hash table, to avoid repeated strcmp */ /* We will search both the original and laundered OGR field names for matches */ ogr_fields_count = 2 * ogr_ncols; ogr_fields = palloc0(ogr_fields_count * sizeof(OgrFieldEntry)); for (i = 0; i < ogr_ncols; i++) { char* fldname = pstrdup(OGR_Fld_GetNameRef(OGR_FD_GetFieldDefn(dfn, i))); char* fldname_laundered = palloc(STR_MAX_LEN); strlcpy(fldname_laundered, fldname, STR_MAX_LEN); ogrStringLaunder(fldname_laundered); ogr_fields[2 * i].fldname = fldname; ogr_fields[2 * i].fldnum = i; ogr_fields[2 * i + 1].fldname = fldname_laundered; ogr_fields[2 * i + 1].fldnum = i; } qsort(ogr_fields, ogr_fields_count, sizeof(OgrFieldEntry), ogrFieldEntryCmpFunc); /* loop through foreign table columns */ for (i = 0; i < tbl->ncols; i++) { List* options; ListCell* lc; OgrFieldEntry* found_entry; OgrFieldEntry entry; Form_pg_attribute att_tuple = TupleDescAttr(tupdesc, i); OgrFdwColumn col = tbl->cols[i]; col.pgattnum = att_tuple->attnum; col.pgtype = att_tuple->atttypid; col.pgtypmod = att_tuple->atttypmod; col.pgattisdropped = att_tuple->attisdropped; /* Skip filling in any further metadata about dropped columns */ if (col.pgattisdropped) { continue; } /* Check for array type */ col.pgelmtype = get_element_type(col.pgtype); if (col.pgelmtype) { /* Extra type info needed to form the array */ col.pgisarray = true; } else col.pgelmtype = col.pgtype; /* Find the appropriate conversion functions */ getTypeInputInfo(col.pgelmtype, &col.pginputfunc, &col.pginputioparam); getTypeBinaryInputInfo(col.pgelmtype, &col.pgrecvfunc, &col.pgrecvioparam); getTypeOutputInfo(col.pgelmtype, &col.pgoutputfunc, &col.pgoutputvarlena); getTypeBinaryOutputInfo(col.pgelmtype, &col.pgsendfunc, &col.pgsendvarlena); /* Get the PgSQL column name */ #if PG_VERSION_NUM >= 110000 col.pgname = pstrdup(get_attname(rel->rd_id, att_tuple->attnum, false)); #else col.pgname = pstrdup(get_attname(rel->rd_id, att_tuple->attnum)); #endif /* Handle FID first */ if (strcaseeq(col.pgname, "fid") && (col.pgtype == INT4OID || col.pgtype == INT8OID)) { if (fid_count >= 1) { elog(ERROR, "FDW table '%s' includes more than one FID column", tblname); } col.ogrvariant = OGR_FID; col.ogrfldnum = fid_count++; tbl->cols[i] = col; continue; } /* If the OGR source has geometries, can we match them to Pg columns? */ /* We'll match to the first ones we find, irrespective of name */ if (geom_count < ogr_geom_count && col.pgtype == ogrGetGeometryOid()) { col.ogrvariant = OGR_GEOMETRY; col.ogrfldtype = OFTBinary; col.ogrfldnum = geom_count++; tbl->cols[i] = col; continue; } /* Now we search for matches in the OGR fields */ /* By default, search for the PgSQL column name */ entry.fldname = col.pgname; entry.fldnum = 0; /* * But, if there is a 'column_name' option for this column, we * want to search for *that* in the OGR layer. */ options = GetForeignColumnOptions(state->foreigntableid, i + 1); foreach (lc, options) { DefElem* def = (DefElem*) lfirst(lc); if (streq(def->defname, OPT_COLUMN)) { entry.fldname = defGetString(def); break; } } /* Search PgSQL column name in the OGR column name list */ found_entry = bsearch(&entry, ogr_fields, ogr_fields_count, sizeof(OgrFieldEntry), ogrFieldEntryCmpFunc); /* Column name matched, so save this entry, if the types are consistent */ if (found_entry) { OGRFieldDefnH fld = OGR_FD_GetFieldDefn(dfn, found_entry->fldnum); OGRFieldType fldtype = OGR_Fld_GetType(fld); /* Error if types mismatched when column names match */ ogrCheckConvertToPg(fldtype, col.pgtype, col.pgname, tblname); col.ogrvariant = OGR_FIELD; col.ogrfldnum = found_entry->fldnum; col.ogrfldtype = fldtype; field_count++; } else { col.ogrvariant = OGR_UNMATCHED; } tbl->cols[i] = col; } elog(DEBUG2, "ogrReadColumnData matched %d FID, %d GEOM, %d FIELDS out of %d PGSQL COLUMNS", fid_count, geom_count, field_count, tbl->ncols); /* Clean up */ state->table = tbl; for (i = 0; i < 2 * ogr_ncols; i++) { if (ogr_fields[i].fldname) { pfree(ogr_fields[i].fldname); } } pfree(ogr_fields); #if PG_VERSION_NUM < 120000 heap_close(rel, NoLock); #else table_close(rel, NoLock); #endif /* PG_VERSION_NUM */ return; } /* * ogrLookupGeometryFunctionOid * * Find the procedure Oids of useful functions so we can call * them later. In the case where multiple functions have the * same signature, in different namespaces (???) we might have * problems, but that seems very unlikely. * * https://github.com/pramsey/pgsql-ogr-fdw/issues/266 */ static Oid ogrLookupGeometryFunctionOid(const char* proname) { CatCList *clist; int i; Oid result = InvalidOid; /* This only works if PostGIS is installed */ if (ogrGetGeometryOid() == InvalidOid || ogrGetGeometryOid() == BYTEAOID) { return result; } if (!proname) return result; /* Search syscache by name only */ clist = SearchSysCacheList1(PROCNAMEARGSNSP, CStringGetDatum(proname)); if (!clist) return InvalidOid; for (i = 0; i < clist->n_members; i++) { HeapTuple proctup = &clist->members[i]->tuple; Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup); Oid *proargtypes = procform->proargtypes.values; int pronargs = procform->pronargs; #if PG_VERSION_NUM >= 120000 Oid procoid = procform->oid; #else Oid procoid = HeapTupleGetOid(proctup); #endif /* ST_SetSRID(geometry, integer) */ if (streq(proname, "st_setsrid") && pronargs == 2 && proargtypes[0] == ogrGetGeometryOid()) { result = procoid; break; } /* postgis_typmod_srid(typmod) */ else if (streq(proname, "postgis_typmod_srid") && pronargs == 1) { /* postgis_typmod_srid(integer) */ result = procoid; break; } else { elog(ERROR, "%s could not find function '%s'", __func__, proname); } } ReleaseSysCacheList(clist); return result; } /* * ogrBeginForeignScan */ static void ogrBeginForeignScan(ForeignScanState* node, int eflags) { OgrFdwState* state; OgrFdwExecState* execstate; OgrFdwSpatialFilter* spatial_filter; Oid foreigntableid = RelationGetRelid(node->ss.ss_currentRelation); ForeignScan* fsplan = (ForeignScan*)node->ss.ps.plan; elog(DEBUG3, "%s: entered function", __func__); /* Do nothing in EXPLAIN (no ANALYZE) case */ if (eflags & EXEC_FLAG_EXPLAIN_ONLY) return; /* Initialize OGR connection */ state = getOgrFdwState(foreigntableid, OGR_EXEC_STATE); execstate = (OgrFdwExecState*)state; /* Read the OGR layer definition and PgSQL foreign table definitions */ ogrReadColumnData(state); /* Collect the procedure Oids for PostGIS functions we might need */ execstate->setsridfunc = ogrLookupGeometryFunctionOid("st_setsrid"); execstate->typmodsridfunc = ogrLookupGeometryFunctionOid("postgis_typmod_srid"); /* Get OGR SQL generated by the deparse step during the planner function. */ execstate->sql = (char*) strVal(list_nth(fsplan->fdw_private, 0)); /* TODO: Use the parse step attribute list to restrict requested columns */ // execstate->retrieved_attrs = (List *) list_nth(fsplan->fdw_private, 1); /* Get spatial filter generated by the deparse step. */ spatial_filter = ogrSpatialFilterFromList(list_nth(fsplan->fdw_private, 2)); if (spatial_filter) { OGR_L_SetSpatialFilterRectEx(execstate->ogr.lyr, spatial_filter->ogrfldnum, spatial_filter->minx, spatial_filter->miny, spatial_filter->maxx, spatial_filter->maxy ); } if (execstate->sql && strlen(execstate->sql) > 0) { OGRErr err = OGR_L_SetAttributeFilter(execstate->ogr.lyr, execstate->sql); if (err != OGRERR_NONE) { const char* ogrerr = CPLGetLastErrorMsg(); if (ogrerr && ! streq(ogrerr, "")) { ereport(NOTICE, (errcode(ERRCODE_FDW_ERROR), errmsg("unable to set OGR SQL '%s' on layer", execstate->sql), errhint("%s", ogrerr))); } else { ereport(NOTICE, (errcode(ERRCODE_FDW_ERROR), errmsg("unable to set OGR SQL '%s' on layer", execstate->sql))); } } } else { OGR_L_SetAttributeFilter(execstate->ogr.lyr, NULL); } /* Save the state for the next call */ node->fdw_state = (void*) execstate; return; } /* * Rather than explicitly try and form PgSQL datums, use the type * input functions, that accept cstring representations, and convert * to the input format. We have to lookup the right input function for * each column in the foreign table. */ static Datum pgDatumFromCString(const char* cstr, const OgrFdwColumn *col, int char_encoding, bool *is_null) { size_t cstr_len = cstr ? strlen(cstr) : 0; Datum value = (Datum) 0; char *cstr_decoded; /* Zero length implies NULL for all non-strings */ if (cstr_len == 0 && (col->ogrfldtype != OFTString && col->ogrfldtype != OFTStringList)) { *is_null = true; return value; } cstr_decoded = char_encoding ? pg_any_to_server(cstr, cstr_len, char_encoding) : pstrdup(cstr); value = OidFunctionCall3(col->pginputfunc, CStringGetDatum(cstr_decoded), ObjectIdGetDatum(InvalidOid), Int32GetDatum(col->pgtypmod)); /* Free cstr_decoded if it is a copy */ if (cstr != cstr_decoded) pfree(cstr_decoded); *is_null = false; return value; } static inline void ogrNullSlot(Datum* values, bool* nulls, int i) { values[i] = PointerGetDatum(NULL); nulls[i] = true; } /* * The ogrIterateForeignScan is getting a new TupleTableSlot to handle * for each iteration. Each slot contains an entry for every column in * in the foreign table, that has to be filled out, either with a value * or a NULL for columns that either have been deleted or were not requested * in the query. * * The tupledescriptor tells us about the types of each slot. * For now we assume our slot has exactly the same number of * records and equivalent types to our OGR layer, and that our * foreign table's first two columns are an integer primary key * using int8 as the type, and then a geometry using bytea as * the type, then everything else. */ static OGRErr ogrFeatureToSlot(const OGRFeatureH feat, TupleTableSlot* slot, const OgrFdwExecState* execstate) { const OgrFdwTable* tbl = execstate->table; int i; Datum* values = slot->tts_values; bool* nulls = slot->tts_isnull; TupleDesc tupdesc = slot->tts_tupleDescriptor; int have_typmod_funcs = (execstate->setsridfunc && execstate->typmodsridfunc); #define CSTR_SZ 256 char cstr[CSTR_SZ]; /* Check our assumption that slot and setup data match */ if (tbl->ncols != tupdesc->natts) { elog(ERROR, "FDW metadata table and exec table have mismatching number of columns"); return OGRERR_FAILURE; } /* For each pgtable column, get a value from OGR */ for (i = 0; i < tbl->ncols; i++) { OgrFdwColumn col = tbl->cols[i]; const char* pgname = col.pgname; Oid pgtype = col.pgtype; int ogrfldnum = col.ogrfldnum; OGRFieldType ogrfldtype = col.ogrfldtype; OgrColumnVariant ogrvariant = col.ogrvariant; /* * Fill in dropped attributes with NULL */ if (col.pgattisdropped) { ogrNullSlot(values, nulls, i); continue; } if (ogrvariant == OGR_FID) { GIntBig fid = OGR_F_GetFID(feat); bool is_null = false; if (fid == OGRNullFID) { ogrNullSlot(values, nulls, i); } else { char fidstr[256]; snprintf(fidstr, 256, OGR_FDW_FRMT_INT64, OGR_FDW_CAST_INT64(fid)); values[i] = pgDatumFromCString(fidstr, &col, execstate->ogr.char_encoding, &is_null); nulls[i] = is_null; } } else if (ogrvariant == OGR_GEOMETRY) { int wkbsize; int varsize; bytea* varlena; unsigned char* wkb; OGRErr err; #if (GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(1,11,0)) OGRGeometryH geom = OGR_F_GetGeomFieldRef(feat, ogrfldnum); #else OGRGeometryH geom = OGR_F_GetGeometryRef(feat); #endif /* No geometry ? NULL */ if (! geom) { /* No geometry column, so make the output null */ ogrNullSlot(values, nulls, i); continue; } /* * Start by generating standard PgSQL variable length byte * buffer, with WKB filled into the data area. */ wkbsize = OGR_G_WkbSize(geom); varsize = wkbsize + VARHDRSZ; varlena = palloc(varsize); wkb = (unsigned char*)VARDATA(varlena); err = OGR_G_ExportToWkb(geom, wkbNDR, wkb); SET_VARSIZE(varlena, varsize); /* Couldn't create WKB from OGR geometry? error */ if (err != OGRERR_NONE) { return err; } if (pgtype == BYTEAOID) { /* * Nothing special to do for bytea, just send the varlena data through! */ nulls[i] = false; values[i] = PointerGetDatum(varlena); } else if (pgtype == ogrGetGeometryOid()) { /* * For geometry we need to convert the varlena WKB data into a serialized * geometry (aka "gserialized"). For that, we can use the type's "recv" function * which takes in WKB and spits out serialized form, or the "input" function * that takes in HEXWKB. The "input" function is more lax about geometry * structure errors (unclosed polys, etc). */ #ifdef OGR_FDW_HEXWKB char* hexwkb = ogrBytesToHex(wkb, wkbsize); /* * Use the input function to convert the WKB from OGR into * a PostGIS internal format. */ nulls[i] = false; values[i] = OidFunctionCall1(col.pginputfunc, PointerGetDatum(hexwkb)); pfree(hexwkb); #else /* * The "recv" function expects to receive a StringInfo pointer * on the first argument, so we form one of those ourselves by * hand. Rather than copy into a fresh buffer, we'll just use the * existing varlena buffer and point to the data area. * * The "recv" function tests for basic geometry validity, * things like polygon closure, etc. So don't feed it junk. */ StringInfoData strinfo; strinfo.data = (char*)wkb; strinfo.len = wkbsize; strinfo.maxlen = strinfo.len; strinfo.cursor = 0; /* * Use the recv function to convert the WKB from OGR into * a PostGIS internal format. */ nulls[i] = false; values[i] = OidFunctionCall1(col.pgrecvfunc, PointerGetDatum(&strinfo)); #endif /* * Apply the typmod restriction to the incoming geometry, so it's * not really a restriction anymore, it's more like a requirement. * * TODO: In the case where the OGR input actually *knows* what SRID * it is, we should actually apply *that* and let the restriction run * its usual course. */ if (have_typmod_funcs && col.pgtypmod >= 0) { Datum srid = OidFunctionCall1(execstate->typmodsridfunc, Int32GetDatum(col.pgtypmod)); values[i] = OidFunctionCall2(execstate->setsridfunc, values[i], srid); } } else { elog(NOTICE, "conversion to geometry called with column type not equal to bytea or geometry"); ogrNullSlot(values, nulls, i); } } else if (ogrvariant == OGR_FIELD) { #if (GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,2,0)) int field_not_null = OGR_F_IsFieldSet(feat, ogrfldnum) && ! OGR_F_IsFieldNull(feat, ogrfldnum); #else int field_not_null = OGR_F_IsFieldSet(feat, ogrfldnum); #endif /* Ensure that the OGR data type fits the destination Pg column */ ogrCheckConvertToPg(ogrfldtype, pgtype, pgname, tbl->tblname); /* Only convert non-null fields */ if (!field_not_null) { ogrNullSlot(values, nulls, i); continue; } switch (ogrfldtype) { case OFTBinary: { /* * Convert binary fields to bytea directly */ int bufsize; GByte* buf = OGR_F_GetFieldAsBinary(feat, ogrfldnum, &bufsize); int varsize = bufsize + VARHDRSZ; bytea* varlena = palloc(varsize); memcpy(VARDATA(varlena), buf, bufsize); SET_VARSIZE(varlena, varsize); nulls[i] = false; values[i] = PointerGetDatum(varlena); break; } case OFTInteger: case OFTReal: case OFTString: #if GDAL_VERSION_MAJOR >= 2 case OFTInteger64: #endif { /* * Convert numbers and strings via a string representation. * Handling numbers directly would be faster, but require a lot of extra code. * For now, we go via text. */ const char* cstr_in = OGR_F_GetFieldAsString(feat, ogrfldnum); bool is_null = false; values[i] = pgDatumFromCString(cstr_in, &col, execstate->ogr.char_encoding, &is_null); nulls[i] = is_null; break; } case OFTDate: case OFTTime: case OFTDateTime: { /* * OGR date/times have a weird access method, so we use that to pull * out the raw data and turn it into a string for PgSQL's (very * sophisticated) date/time parsing routines to handle. */ int year, month, day, hour, minute, second, tz; bool is_null = false; OGR_F_GetFieldAsDateTime(feat, ogrfldnum, &year, &month, &day, &hour, &minute, &second, &tz); if (ogrfldtype == OFTDate) { snprintf(cstr, CSTR_SZ, "%d-%02d-%02d", year, month, day); } else if (ogrfldtype == OFTTime) { snprintf(cstr, CSTR_SZ, "%02d:%02d:%02d", hour, minute, second); } else { #if (GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,7,0)) const char* tsstr = OGR_F_GetFieldAsISO8601DateTime(feat, ogrfldnum, NULL); strlcpy(cstr, tsstr, CSTR_SZ); #else snprintf(cstr, CSTR_SZ, "%d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, second); #endif } values[i] = pgDatumFromCString(cstr, &col, PG_SQL_ASCII, &is_null); nulls[i] = is_null; break; } #if GDAL_VERSION_MAJOR >= 2 case OFTInteger64List: { int ilist_size; const int64 *ilist = (int64*)OGR_F_GetFieldAsInteger64List(feat, ogrfldnum, &ilist_size); ArrayBuildState *abs = initArrayResult(col.pgelmtype, CurrentMemoryContext, false); for (uint32 i = 0; i < ilist_size; i++) { bool is_null = false; snprintf(cstr, CSTR_SZ, OGR_FDW_FRMT_INT64, OGR_FDW_CAST_INT64(ilist[i])); abs = accumArrayResult(abs, pgDatumFromCString(cstr, &col, execstate->ogr.char_encoding, &is_null), is_null, col.pgelmtype, CurrentMemoryContext); } values[i] = makeArrayResult(abs, CurrentMemoryContext); nulls[i] = false; break; } #endif case OFTIntegerList: { int ilist_size; const int *ilist = OGR_F_GetFieldAsIntegerList(feat, ogrfldnum, &ilist_size); ArrayBuildState *abs = initArrayResult(col.pgelmtype, CurrentMemoryContext, false); for (uint32 i = 0; i < ilist_size; i++) { bool is_null = false; snprintf(cstr, CSTR_SZ, "%d", ilist[i]); abs = accumArrayResult(abs, pgDatumFromCString(cstr, &col, execstate->ogr.char_encoding, &is_null), is_null, col.pgelmtype, CurrentMemoryContext); } values[i] = makeArrayResult(abs, CurrentMemoryContext); nulls[i] = false; break; } case OFTRealList: { int rlist_size; const double *rlist = OGR_F_GetFieldAsDoubleList(feat, ogrfldnum, &rlist_size); ArrayBuildState *abs = initArrayResult(col.pgelmtype, CurrentMemoryContext, false); for (uint32 i = 0; i < rlist_size; i++) { bool is_null = false; snprintf(cstr, CSTR_SZ, "%g", rlist[i]); abs = accumArrayResult(abs, pgDatumFromCString(cstr, &col, execstate->ogr.char_encoding, &is_null), is_null, col.pgelmtype, CurrentMemoryContext); } values[i] = makeArrayResult(abs, CurrentMemoryContext); nulls[i] = false; break; } case OFTStringList: { ArrayBuildState *abs = initArrayResult(col.pgelmtype, CurrentMemoryContext, false); char **cstrs = OGR_F_GetFieldAsStringList(feat, ogrfldnum); while (*cstrs) { bool is_null = false; abs = accumArrayResult(abs, pgDatumFromCString(*cstrs, &col, execstate->ogr.char_encoding, &is_null), is_null, col.pgelmtype, CurrentMemoryContext); cstrs++; } values[i] = makeArrayResult(abs, CurrentMemoryContext); nulls[i] = false; break; } default: { elog(ERROR, "unsupported OGR type \"%s\"", OGR_GetFieldTypeName(ogrfldtype)); break; } } /* !switch */ } /* Fill in unmatched columns with NULL */ else if (ogrvariant == OGR_UNMATCHED) { ogrNullSlot(values, nulls, i); } else { elog(ERROR, "OGR FDW unsupported column variant in \"%s\", %d", pgname, ogrvariant); return OGRERR_FAILURE; } } /* done! */ return OGRERR_NONE; } static void ogrStaticText(char* text, const char* str) { size_t len = strlen(str); memcpy(VARDATA(text), str, len); SET_VARSIZE(text, len + VARHDRSZ); return; } /* * EWKB includes a flag that indicates an SRID embedded in the * binary. The EWKB has an endian byte, four bytes of type information * and then 4 bytes of optional SRID information. If that info is * there, we want to over-write it, and remove the SRID flag, to * generate more "standard" WKB for OGR to consume. */ static size_t ogrEwkbStripSrid(unsigned char* wkb, size_t wkbsize) { unsigned int type = 0; int has_srid = 0; size_t newwkbsize = wkbsize; memcpy(&type, wkb + 1, 4); /* has_z = type & 0x80000000; */ /* has_m = type & 0x40000000; */ has_srid = type & 0x20000000; /* Flatten SRID flag away */ type &= 0xDFFFFFFF; memcpy(wkb + 1, &type, 4); /* If there was an SRID number embedded, overwrite it */ if (has_srid) { newwkbsize -= 4; /* no space for SRID number needed */ memmove(wkb + 5, wkb + 9, newwkbsize - 5); } return newwkbsize; } OGRErr pgDatumToOgrGeometry (Datum pg_geometry, Oid pgsendfunc, OGRGeometryH* ogr_geometry) { OGRErr err; bytea* wkb_bytea = DatumGetByteaP(OidFunctionCall1(pgsendfunc, pg_geometry)); unsigned char* wkb = (unsigned char*)VARDATA_ANY(wkb_bytea); size_t wkbsize = VARSIZE_ANY_EXHDR(wkb_bytea); wkbsize = ogrEwkbStripSrid(wkb, wkbsize); err = OGR_G_CreateFromWkb(wkb, NULL, ogr_geometry, wkbsize); if (wkb_bytea) pfree(wkb_bytea); return err; } static OGRErr ogrSlotToFeature(const TupleTableSlot* slot, OGRFeatureH feat, const OgrFdwTable* tbl) { int i; Datum* values = slot->tts_values; bool* nulls = slot->tts_isnull; TupleDesc tupdesc = slot->tts_tupleDescriptor; int year, month, day, hour, minute, second; /* Prepare date-time part tokens for use later */ char txtyear[STR_MAX_LEN]; char txtmonth[STR_MAX_LEN]; char txtday[STR_MAX_LEN]; char txthour[STR_MAX_LEN]; char txtminute[STR_MAX_LEN]; char txtsecond[STR_MAX_LEN]; ogrStaticText(txtyear, "year"); ogrStaticText(txtmonth, "month"); ogrStaticText(txtday, "day"); ogrStaticText(txthour, "hour"); ogrStaticText(txtminute, "minute"); ogrStaticText(txtsecond, "second"); /* Check our assumption that slot and setup data match */ if (tbl->ncols != tupdesc->natts) { elog(ERROR, "FDW metadata table and slot table have mismatching number of columns"); return OGRERR_FAILURE; } /* For each pgtable column, set a value on the feature OGR */ for (i = 0; i < tbl->ncols; i++) { OgrFdwColumn col = tbl->cols[i]; const char* pgname = col.pgname; Oid pgtype = col.pgtype; Oid pgoutputfunc = col.pgoutputfunc; int ogrfldnum = col.ogrfldnum; OGRFieldType ogrfldtype = col.ogrfldtype; OgrColumnVariant ogrvariant = col.ogrvariant; /* Skip dropped attributes */ if (col.pgattisdropped) { continue; } /* Skip the FID, we have to treat it as immutable anyways */ if (ogrvariant == OGR_FID) { if (nulls[i]) { OGR_F_SetFID(feat, OGRNullFID); } else { if (pgtype == INT4OID) { int32 val = DatumGetInt32(values[i]); OGR_F_SetFID(feat, val); } else if (pgtype == INT8OID) { int64 val = DatumGetInt64(values[i]); OGR_F_SetFID(feat, val); } else { elog(ERROR, "unable to handle non-integer fid"); } } continue; } /* TODO: For updates, we should only set the fields that are */ /* in the target list, and flag the others as unchanged */ if (ogrvariant == OGR_GEOMETRY) { OGRErr err; if (nulls[i]) { #if (GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(1,11,0)) err = OGR_F_SetGeomFieldDirectly(feat, ogrfldnum, NULL); #else err = OGR_F_SetGeometryDirectly(feat, NULL); #endif continue; } else { OGRGeometryH geom; err = pgDatumToOgrGeometry (values[i], col.pgsendfunc, &geom); if (err != OGRERR_NONE) return err; #if (GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(1,11,0)) err = OGR_F_SetGeomFieldDirectly(feat, ogrfldnum, geom); #else err = OGR_F_SetGeometryDirectly(feat, geom); #endif } } else if (ogrvariant == OGR_FIELD) { /* Ensure that the OGR data type fits the destination Pg column */ pgCheckConvertToOgr(pgtype, ogrfldtype, pgname, tbl->tblname); /* Skip NULL case */ if (nulls[i]) { OGR_F_UnsetField(feat, ogrfldnum); continue; } switch (pgtype) { case BOOLOID: { int8 val = DatumGetBool(values[i]); OGR_F_SetFieldInteger(feat, ogrfldnum, val); break; } case INT2OID: { int16 val = DatumGetInt16(values[i]); OGR_F_SetFieldInteger(feat, ogrfldnum, val); break; } case INT4OID: { int32 val = DatumGetInt32(values[i]); OGR_F_SetFieldInteger(feat, ogrfldnum, val); break; } case INT8OID: { int64 val = DatumGetInt64(values[i]); #if GDAL_VERSION_MAJOR >= 2 OGR_F_SetFieldInteger64(feat, ogrfldnum, val); #else if (val < INT_MAX) { OGR_F_SetFieldInteger(feat, ogrfldnum, (int32)val); } else { elog(ERROR, "unable to coerce int64 into int32 OGR field"); } #endif break; } case NUMERICOID: { Datum d; float8 f; /* Convert to string */ d = OidFunctionCall1(pgoutputfunc, values[i]); /* Convert back to float8 */ f = DatumGetFloat8(DirectFunctionCall1(float8in, d)); OGR_F_SetFieldDouble(feat, ogrfldnum, f); break; } case FLOAT4OID: { OGR_F_SetFieldDouble(feat, ogrfldnum, DatumGetFloat4(values[i])); break; } case FLOAT8OID: { OGR_F_SetFieldDouble(feat, ogrfldnum, DatumGetFloat8(values[i])); break; } case TEXTOID: case VARCHAROID: case NAMEOID: case BPCHAROID: /* char(n) */ { bytea* varlena = (bytea*)DatumGetPointer(values[i]); size_t varsize = VARSIZE_ANY_EXHDR(varlena); char* str = palloc0(varsize + 1); memcpy(str, VARDATA_ANY(varlena), varsize); OGR_F_SetFieldString(feat, ogrfldnum, str); pfree(str); break; } case CHAROID: /* char */ { char str[2]; str[0] = DatumGetChar(values[i]); str[1] = '\0'; OGR_F_SetFieldString(feat, ogrfldnum, str); break; } case BYTEAOID: { struct varlena *detoasted_dat = (struct varlena *) PG_DETOAST_DATUM(values[i]); size_t varsize = VARSIZE_ANY_EXHDR(detoasted_dat); OGR_F_SetFieldBinary(feat, ogrfldnum, varsize, (GByte*)VARDATA_ANY(detoasted_dat)); break; } case DATEOID: { /* Convert date to timestamp */ Datum d = DirectFunctionCall1(date_timestamp, values[i]); /* Read out the parts */ year = lround(DatumGetFloat8(DirectFunctionCall2(timestamp_part, PointerGetDatum(txtyear), d))); month = lround(DatumGetFloat8(DirectFunctionCall2(timestamp_part, PointerGetDatum(txtmonth), d))); day = lround(DatumGetFloat8(DirectFunctionCall2(timestamp_part, PointerGetDatum(txtday), d))); OGR_F_SetFieldDateTime(feat, ogrfldnum, year, month, day, 0, 0, 0, 0); break; } /* TODO: handle time zones explicitly */ case TIMEOID: case TIMETZOID: { /* Read the parts of the time */ hour = lround(DatumGetFloat8(DirectFunctionCall2(time_part, PointerGetDatum(txthour), values[i]))); minute = lround(DatumGetFloat8(DirectFunctionCall2(time_part, PointerGetDatum(txtminute), values[i]))); second = lround(DatumGetFloat8(DirectFunctionCall2(time_part, PointerGetDatum(txtsecond), values[i]))); OGR_F_SetFieldDateTime(feat, ogrfldnum, 0, 0, 0, hour, minute, second, 0); break; } case TIMESTAMPOID: case TIMESTAMPTZOID: { Datum d = values[i]; year = lround(DatumGetFloat8(DirectFunctionCall2(timestamp_part, PointerGetDatum(txtyear), d))); month = lround(DatumGetFloat8(DirectFunctionCall2(timestamp_part, PointerGetDatum(txtmonth), d))); day = lround(DatumGetFloat8(DirectFunctionCall2(timestamp_part, PointerGetDatum(txtday), d))); hour = lround(DatumGetFloat8(DirectFunctionCall2(timestamp_part, PointerGetDatum(txthour), d))); minute = lround(DatumGetFloat8(DirectFunctionCall2(timestamp_part, PointerGetDatum(txtminute), d))); second = lround(DatumGetFloat8(DirectFunctionCall2(timestamp_part, PointerGetDatum(txtsecond), d))); OGR_F_SetFieldDateTime(feat, ogrfldnum, year, month, day, hour, minute, second, 0); break; } case BOOLARRAYOID: case INT2ARRAYOID: case INT4ARRAYOID: { ArrayType *arr = DatumGetArrayTypeP(values[i]); size_t sz = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr)); Datum d; bool isnull; int *ints = palloc(sizeof(int) * sz); int num_ints = 0; ArrayIterator it = array_create_iterator(arr, 0, NULL); while (array_iterate(it, &d, &isnull)) { if (isnull) continue; ints[num_ints++] = DatumGetInt32(d); } OGR_F_SetFieldIntegerList(feat, ogrfldnum, num_ints, ints); pfree(ints); break; } case CHARARRAYOID: case NAMEARRAYOID: case TEXTARRAYOID: case VARCHARARRAYOID: { ArrayType *arr = DatumGetArrayTypeP(values[i]); Datum d; bool isnull; char** papszList = NULL; ArrayIterator it = array_create_iterator(arr, 0, NULL); while (array_iterate(it, &d, &isnull)) { char *cstr; if (isnull) continue; cstr = text_to_cstring(DatumGetTextP(d)); papszList = CSLAddString(papszList, cstr); pfree(cstr); } OGR_F_SetFieldStringList(feat, ogrfldnum, papszList); CSLDestroy(papszList); break; } case FLOAT4ARRAYOID: case FLOAT8ARRAYOID: { ArrayType *arr = DatumGetArrayTypeP(values[i]); size_t sz = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr)); Datum d; bool isnull; double *floats = palloc(sizeof(double) * sz); int num_floats = 0; ArrayIterator it = array_create_iterator(arr, 0, NULL); while (array_iterate(it, &d, &isnull)) { if (isnull) continue; floats[num_floats++] = DatumGetFloat8(d); } OGR_F_SetFieldDoubleList(feat, ogrfldnum, num_floats, floats); pfree(floats); break; } /* TODO: array types for string, integer, float */ default: { elog(ERROR, "OGR FDW unsupported PgSQL column type in \"%s\", %d", pgname, pgtype); return OGRERR_FAILURE; } } } /* Fill in unmatched columns with NULL */ else if (ogrvariant == OGR_UNMATCHED) { OGR_F_UnsetField(feat, ogrfldnum); } else { elog(ERROR, "OGR FDW unsupported column variant in \"%s\", %d", pgname, ogrvariant); return OGRERR_FAILURE; } } /* done! */ return OGRERR_NONE; } /* * ogrIterateForeignScan * Read next record from OGR and store it into the * ScanTupleSlot as a virtual tuple */ static TupleTableSlot* ogrIterateForeignScan(ForeignScanState* node) { OgrFdwExecState* execstate = (OgrFdwExecState*) node->fdw_state; TupleTableSlot* slot = node->ss.ss_ScanTupleSlot; OGRFeatureH feat; elog(DEBUG3, "%s: entered function", __func__); /* * Clear the slot. If it gets through w/o being filled up, that means * we're all done. */ ExecClearTuple(slot); /* * First time through, reset reading. Then keep reading until * we run out of records, then return a cleared (NULL) slot, to * notify the core we're done. */ if (execstate->rownum == 0) { OGR_L_ResetReading(execstate->ogr.lyr); } /* If we rectreive a feature from OGR, copy it over into the slot */ feat = OGR_L_GetNextFeature(execstate->ogr.lyr); if (feat) { /* convert result to arrays of values and null indicators */ if (OGRERR_NONE != ogrFeatureToSlot(feat, slot, execstate)) { ogrEreportError("failure reading OGR data source"); } /* store the virtual tuple */ ExecStoreVirtualTuple(slot); /* increment row count */ execstate->rownum++; /* Release OGR feature object */ OGR_F_Destroy(feat); } return slot; } /* * ogrReScanForeignScan * Rescan table, possibly with new parameters */ static void ogrReScanForeignScan(ForeignScanState* node) { OgrFdwExecState* execstate = (OgrFdwExecState*) node->fdw_state; elog(DEBUG3, "%s: entered function", __func__); OGR_L_ResetReading(execstate->ogr.lyr); execstate->rownum = 0; return; } /* * ogrEndForeignScan * Finish scanning foreign table and dispose objects used for this scan */ static void ogrEndForeignScan(ForeignScanState* node) { OgrFdwExecState* execstate = (OgrFdwExecState*) node->fdw_state; elog(DEBUG3, "%s: entered function", __func__); if (execstate) { elog(DEBUG2, "OGR FDW processed %d rows from OGR", execstate->rownum); ogrFinishConnection(&(execstate->ogr)); } return; } /* ======================================================== */ /* WRITE SUPPORT */ /* ======================================================== */ /* if the scanning functions above respected the targetlist, we would only be getting back the SET target=foo columns in the slots below, so we would need to add the "fid" to all targetlists (and also disallow fid changing perhaps). since we always pull complete tables in the scan functions, the slots below are basically full tables, in fact they include (?) one entry for each OGR column, even when the table does not include the column, just nulling out the entries that are not in the table definition it might be better to update the scan code to properly manage target lists first, and then come back here and do things properly we will need a ogrSlotToFeature to feed into the OGR_L_SetFeature and OGR_L_CreateFeature functions. Also will use OGR_L_DeleteFeature and fid value in ogrGetForeignPlan we get a tlist that includes just the attributes we are interested in, can use that to pare down the request perhaps */ static int ogrGetFidColumn(const TupleDesc td) { int i; for (i = 0; i < td->natts; i++) { Form_pg_attribute att_tuple = TupleDescAttr(td, i); NameData attname = att_tuple->attname; Oid atttypeid = att_tuple->atttypid; if ((atttypeid == INT4OID || atttypeid == INT8OID) && strcaseeq("fid", attname.data)) { return i; } } return -1; } /* * ogrAddForeignUpdateTargets * * For now we no-op this callback, as we are making the presence of * "fid" in the FDW table definition a requirement for any update. * It might be possible to add nonexisting "junk" columns? In which case * there could always be a virtual fid travelling with the queries, * and the FDW table itself wouldn't need such a column? */ #if PG_VERSION_NUM >= 140000 static void ogrAddForeignUpdateTargets(PlannerInfo* planinfo, unsigned int rte_index, RangeTblEntry* target_rte, Relation target_relation) { Query* parsetree = planinfo->parse; Form_pg_attribute att; Var* var; TupleDesc tupdesc = target_relation->rd_att; int fid_column = ogrGetFidColumn(tupdesc); elog(DEBUG3, "%s: entered function", __func__); if (fid_column < 0) { elog(ERROR, "table '%s' does not have a 'fid' column", RelationGetRelationName(target_relation)); } att = TupleDescAttr(tupdesc, fid_column); /* Make a Var representing the desired value */ var = makeVar(parsetree->resultRelation, att->attnum, att->atttypid, att->atttypmod, att->attcollation, 0); add_row_identity_var(planinfo, var, rte_index, "fid"); } #else /* PG_VERSION_NUM < 140000 */ static void ogrAddForeignUpdateTargets(Query* parsetree, RangeTblEntry* target_rte, Relation target_relation) { ListCell* cell; Form_pg_attribute att; Var* var; TargetEntry* tle; TupleDesc tupdesc = target_relation->rd_att; int fid_column = ogrGetFidColumn(tupdesc); elog(DEBUG3, "%s: entered function", __func__); if (fid_column < 0) { elog(ERROR, "table '%s' does not have a 'fid' column", RelationGetRelationName(target_relation)); } #if PG_VERSION_NUM >= 110000 att = &tupdesc->attrs[fid_column]; #else att = tupdesc->attrs[fid_column]; #endif /* Make a Var representing the desired value */ var = makeVar(parsetree->resultRelation, att->attnum, att->atttypid, att->atttypmod, att->attcollation, 0); /* Wrap it in a resjunk TLE with the right name ... */ tle = makeTargetEntry((Expr*)var, list_length(parsetree->targetList) + 1, pstrdup(NameStr(att->attname)), true); parsetree->targetList = lappend(parsetree->targetList, tle); foreach (cell, parsetree->targetList) { TargetEntry* target = (TargetEntry*) lfirst(cell); elog(DEBUG4, "parsetree->targetList %s:%d", target->resname, target->resno); } } #endif /* * ogrBeginForeignModify * For now the only thing we'll do here is set up the connection * and pass that on to the next functions. */ static void ogrBeginForeignModify(ModifyTableState* mtstate, ResultRelInfo* rinfo, List* fdw_private, int subplan_index, int eflags) { Oid foreigntableid; OgrFdwState* state; elog(DEBUG3, "%s: entered function", __func__); foreigntableid = RelationGetRelid(rinfo->ri_RelationDesc); state = getOgrFdwState(foreigntableid, OGR_MODIFY_STATE); /* Read the OGR layer definition and PgSQL foreign table definitions */ ogrReadColumnData(state); /* Save OGR connection, etc, for later */ rinfo->ri_FdwState = state; return; } /* * ogrExecForeignUpdate * Find out what the fid is, get the OGR feature for that FID, * and then update the values on that feature. */ static TupleTableSlot* ogrExecForeignUpdate(EState* estate, ResultRelInfo* rinfo, TupleTableSlot* slot, TupleTableSlot* planSlot) { OgrFdwModifyState* modstate = rinfo->ri_FdwState; TupleDesc td = slot->tts_tupleDescriptor; Relation rel = rinfo->ri_RelationDesc; Oid foreigntableid = RelationGetRelid(rel); int fid_column; Oid fid_type; Datum fid_datum; int64 fid; OGRFeatureH feat; OGRErr err; Form_pg_attribute attrs; elog(DEBUG3, "%s: entered function", __func__); /* Is there a fid column? */ fid_column = ogrGetFidColumn(td); if (fid_column < 0) { elog(ERROR, "cannot find 'fid' column in table '%s'", get_rel_name(foreigntableid)); } #if PG_VERSION_NUM >= 120000 slot_getallattrs(slot); #endif /* What is the value of the FID for this record? */ fid_datum = slot->tts_values[fid_column]; attrs = TupleDescAttr(td, fid_column); fid_type = attrs->atttypid; if (fid_type == INT8OID) { fid = DatumGetInt64(fid_datum); } else { fid = DatumGetInt32(fid_datum); } elog(DEBUG2, "ogrExecForeignUpdate fid=" OGR_FDW_FRMT_INT64, OGR_FDW_CAST_INT64(fid)); /* Get the OGR feature for this fid */ feat = OGR_L_GetFeature(modstate->ogr.lyr, fid); /* If we found a feature, then copy data from the slot onto the feature */ /* and then back into the layer */ if (! feat) { ogrEreportError("failure reading OGR feature"); } err = ogrSlotToFeature(slot, feat, modstate->table); if (err != OGRERR_NONE) { ogrEreportError("failure populating OGR feature"); } err = OGR_L_SetFeature(modstate->ogr.lyr, feat); if (err != OGRERR_NONE) { ogrEreportError("failure writing back OGR feature"); } OGR_F_Destroy(feat); /* TODO: slot handling? what happens with RETURNING clauses? */ return slot; } // typedef struct TupleTableSlot // { // NodeTag type; // bool tts_isempty; /* true = slot is empty */ // bool tts_shouldFree; /* should pfree tts_tuple? */ // bool tts_shouldFreeMin; /* should pfree tts_mintuple? */ // bool tts_slow; /* saved state for slot_deform_tuple */ // HeapTuple tts_tuple; /* physical tuple, or NULL if virtual */ // TupleDesc tts_tupleDescriptor; /* slot's tuple descriptor */ // MemoryContext tts_mcxt; /* slot itself is in this context */ // Buffer tts_buffer; /* tuple's buffer, or InvalidBuffer */ // int tts_nvalid; /* # of valid values in tts_values */ // Datum *tts_values; /* current per-attribute values */ // bool *tts_isnull; /* current per-attribute isnull flags */ // MinimalTuple tts_mintuple; /* minimal tuple, or NULL if none */ // HeapTupleData tts_minhdr; /* workspace for minimal-tuple-only case */ // long tts_off; /* saved state for slot_deform_tuple */ // } TupleTableSlot; // typedef struct tupleDesc // { // int natts; /* number of attributes in the tuple */ // Form_pg_attribute *attrs; // /* attrs[N] is a pointer to the description of Attribute Number N+1 */ // TupleConstr *constr; /* constraints, or NULL if none */ // Oid tdtypeid; /* composite type ID for tuple type */ // int32 tdtypmod; /* typmod for tuple type */ // bool tdhasoid; /* tuple has oid attribute in its header */ // int tdrefcount; /* reference count, or -1 if not counting */ // } *TupleDesc; // // typedef struct ResultRelInfo // { // NodeTag type; // Index ri_RangeTableIndex; // Relation ri_RelationDesc; // int ri_NumIndices; // RelationPtr ri_IndexRelationDescs; // IndexInfo **ri_IndexRelationInfo; // TriggerDesc *ri_TrigDesc; // FmgrInfo *ri_TrigFunctions; // List **ri_TrigWhenExprs; // Instrumentation *ri_TrigInstrument; // struct FdwRoutine *ri_FdwRoutine; // void *ri_FdwState; // List *ri_WithCheckOptions; // List *ri_WithCheckOptionExprs; // List **ri_ConstraintExprs; // JunkFilter *ri_junkFilter; // ProjectionInfo *ri_projectReturning; // ProjectionInfo *ri_onConflictSetProj; // List *ri_onConflictSetWhere; // } ResultRelInfo; // typedef struct TargetEntry // { // Expr xpr; // Expr *expr; /* expression to evaluate */ // AttrNumber resno; /* attribute number (see notes above) */ // char *resname; /* name of the column (could be NULL) */ // Index ressortgroupref;/* nonzero if referenced by a sort/group // * clause */ // Oid resorigtbl; /* OID of column's source table */ // AttrNumber resorigcol; /* column's number in source table */ // bool resjunk; /* set to true to eliminate the attribute from // * final target list */ // } TargetEntry; // TargetEntry * // makeTargetEntry(Expr *expr, // AttrNumber resno, // char *resname, // bool resjunk) // Var * // makeVar(Index varno, // AttrNumber varattno, // Oid vartype, // int32 vartypmod, // Oid varcollid, // Index varlevelsup) // typedef struct Var // { // Expr xpr; // Index varno; /* index of this var's relation in the range // * table, or INNER_VAR/OUTER_VAR/INDEX_VAR */ // AttrNumber varattno; /* attribute number of this var, or zero for // * all */ // Oid vartype; /* pg_type OID for the type of this var */ // int32 vartypmod; /* pg_attribute typmod value */ // Oid varcollid; /* OID of collation, or InvalidOid if none */ // Index varlevelsup; /* for subquery variables referencing outer // * relations; 0 in a normal var, >0 means N // * levels up */ // Index varnoold; /* original value of varno, for debugging */ // AttrNumber varoattno; /* original value of varattno */ // int location; /* token location, or -1 if unknown */ // } Var; static TupleTableSlot* ogrExecForeignInsert(EState* estate, ResultRelInfo* rinfo, TupleTableSlot* slot, TupleTableSlot* planSlot) { OgrFdwModifyState* modstate = rinfo->ri_FdwState; OGRFeatureDefnH ogr_fd = OGR_L_GetLayerDefn(modstate->ogr.lyr); OGRFeatureH feat = OGR_F_Create(ogr_fd); int fid_column; OGRErr err; GIntBig fid; elog(DEBUG3, "%s: entered function", __func__); #if PG_VERSION_NUM >= 120000 /* * PgSQL 12 passes an unpopulated slot to us, and for now * we force it to populate itself and then read directly * from it. For future, using the slot_getattr() infra * would be cleaner, but version dependent. */ slot_getallattrs(slot); #endif /* Copy the data from the slot onto the feature */ if (!feat) { ogrEreportError("failure creating OGR feature"); } err = ogrSlotToFeature(slot, feat, modstate->table); if (err != OGRERR_NONE) { ogrEreportError("failure populating OGR feature"); } err = OGR_L_CreateFeature(modstate->ogr.lyr, feat); if (err != OGRERR_NONE) { ogrEreportError("failure writing OGR feature"); } fid = OGR_F_GetFID(feat); OGR_F_Destroy(feat); /* Update the FID for RETURNING slot */ fid_column = ogrGetFidColumn(slot->tts_tupleDescriptor); if (fid_column >= 0) { slot->tts_values[fid_column] = Int64GetDatum(fid); slot->tts_isnull[fid_column] = false; slot->tts_nvalid++; } return slot; } static TupleTableSlot* ogrExecForeignDelete(EState* estate, ResultRelInfo* rinfo, TupleTableSlot* slot, TupleTableSlot* planSlot) { OgrFdwModifyState* modstate = rinfo->ri_FdwState; TupleDesc td = planSlot->tts_tupleDescriptor; Relation rel = rinfo->ri_RelationDesc; Oid foreigntableid = RelationGetRelid(rel); int fid_column; Oid fid_type; Datum fid_datum; int64 fid; OGRErr err; Form_pg_attribute attrs; elog(DEBUG3, "%s: entered function", __func__); /* Is there a fid column? */ fid_column = ogrGetFidColumn(td); if (fid_column < 0) { elog(ERROR, "cannot find 'fid' column in table '%s'", get_rel_name(foreigntableid)); } #if PG_VERSION_NUM >= 120000 slot_getallattrs(planSlot); #endif /* What is the value of the FID for this record? */ fid_datum = planSlot->tts_values[fid_column]; attrs = TupleDescAttr(td, fid_column); fid_type = attrs->atttypid; if (fid_type == INT8OID) { fid = DatumGetInt64(fid_datum); } else { fid = DatumGetInt32(fid_datum); } elog(DEBUG2, "ogrExecForeignDelete fid=" OGR_FDW_FRMT_INT64, OGR_FDW_CAST_INT64(fid)); /* Delete the OGR feature for this fid */ err = OGR_L_DeleteFeature(modstate->ogr.lyr, fid); if (err != OGRERR_NONE) { return NULL; } else { return slot; } } static void ogrEndForeignModify(EState* estate, ResultRelInfo* rinfo) { OgrFdwModifyState* modstate = rinfo->ri_FdwState; elog(DEBUG3, "%s: entered function", __func__); ogrFinishConnection(&(modstate->ogr)); return; } static int ogrIsForeignRelUpdatable(Relation rel) { const int readonly = 0; int foreign_rel_updateable = 0; TupleDesc td = RelationGetDescr(rel); OgrConnection ogr; Oid foreigntableid = RelationGetRelid(rel); elog(DEBUG3, "%s: entered function", __func__); /* Before we say "yes"... */ /* Does the foreign relation have a "fid" column? */ /* Is that column an integer? */ if (ogrGetFidColumn(td) < 0) { elog(NOTICE, "no \"fid\" column in foreign table '%s'", get_rel_name(foreigntableid)); return readonly; } /* Is it backed by a writable OGR driver? */ /* Can we open the relation in read/write mode? */ ogr = ogrGetConnectionFromTable(foreigntableid, OGR_UPDATEABLE_TRY); /* Something in the open process set the readonly flags */ /* Perhaps user has manually set the foreign table option to readonly */ if (ogr.ds_updateable == OGR_UPDATEABLE_FALSE || ogr.lyr_updateable == OGR_UPDATEABLE_FALSE) { return readonly; } /* No data source or layer objects? Readonly */ if (!(ogr.ds && ogr.lyr)) { return readonly; } if (OGR_L_TestCapability(ogr.lyr, OLCRandomWrite)) { foreign_rel_updateable |= (1 << CMD_UPDATE); } if (OGR_L_TestCapability(ogr.lyr, OLCSequentialWrite)) { foreign_rel_updateable |= (1 << CMD_INSERT); } if (OGR_L_TestCapability(ogr.lyr, OLCDeleteFeature)) { foreign_rel_updateable |= (1 << CMD_DELETE); } ogrFinishConnection(&ogr); return foreign_rel_updateable; } #if PG_VERSION_NUM >= 90500 /* * PostgreSQL 9.5 or above. Import a foreign schema */ static List* ogrImportForeignSchema(ImportForeignSchemaStmt* stmt, Oid serverOid) { List* commands = NIL; ForeignServer* server; ListCell* lc; bool import_all = false; bool launder_column_names, launder_table_names; OgrConnection ogr; int i; char layer_name[STR_MAX_LEN]; char table_name[STR_MAX_LEN]; elog(DEBUG3, "%s: entered function", __func__); /* Are we importing all layers in the OGR datasource? */ import_all = streq(stmt->remote_schema, "ogr_all"); /* Make connection to server */ server = GetForeignServer(serverOid); ogr = ogrGetConnectionFromServer(serverOid, OGR_UPDATEABLE_FALSE); /* Launder by default */ launder_column_names = launder_table_names = true; /* Read user-provided statement laundering options */ foreach (lc, stmt->options) { DefElem* def = (DefElem*) lfirst(lc); if (streq(def->defname, "launder_column_names")) { launder_column_names = defGetBoolean(def); } else if (streq(def->defname, "launder_table_names")) { launder_table_names = defGetBoolean(def); } else ereport(ERROR, (errcode(ERRCODE_FDW_INVALID_OPTION_NAME), errmsg("invalid option \"%s\"", def->defname))); } for (i = 0; i < GDALDatasetGetLayerCount(ogr.ds); i++) { bool import_layer = false; OGRLayerH ogr_lyr = GDALDatasetGetLayer(ogr.ds, i); if (! ogr_lyr) { elog(DEBUG1, "Skipping OGR layer %d, unable to read layer", i); continue; } /* Layer name is never laundered, since it's the link back to OGR */ strlcpy(layer_name, OGR_L_GetName(ogr_lyr), STR_MAX_LEN); /* * We need to compare against created table names * because PgSQL does an extra check on CREATE FOREIGN TABLE */ strlcpy(table_name, layer_name, STR_MAX_LEN); if (launder_table_names) { ogrStringLaunder(table_name); } /* * Only include if we are importing "ogr_all" or * the layer prefix starts with the remote schema */ import_layer = import_all || (strncmp(layer_name, stmt->remote_schema, strlen(stmt->remote_schema)) == 0); /* Apply restrictions for LIMIT TO and EXCEPT */ if (import_layer && ( stmt->list_type == FDW_IMPORT_SCHEMA_LIMIT_TO || stmt->list_type == FDW_IMPORT_SCHEMA_EXCEPT)) { /* Limited list? Assume we are taking no items */ if (stmt->list_type == FDW_IMPORT_SCHEMA_LIMIT_TO) { import_layer = false; } /* Check the list for our items */ foreach (lc, stmt->table_list) { RangeVar* rv = (RangeVar*) lfirst(lc); /* Found one! */ if (streq(rv->relname, table_name)) { if (stmt->list_type == FDW_IMPORT_SCHEMA_LIMIT_TO) { import_layer = true; } else { import_layer = false; } break; } } } if (import_layer) { OGRErr err; stringbuffer_t buf; stringbuffer_init(&buf); err = ogrLayerToSQL(ogr_lyr, server->servername, launder_table_names, launder_column_names, NULL, ogrGetGeometryOid() != BYTEAOID, &buf ); if (err != OGRERR_NONE) { elog(ERROR, "unable to generate IMPORT SQL for '%s'", table_name); } commands = lappend(commands, pstrdup(stringbuffer_getstring(&buf))); stringbuffer_release(&buf); } } elog(NOTICE, "Number of tables to be created %d", list_length(commands)); ogrFinishConnection(&ogr); return commands; } #endif /* PostgreSQL 9.5+ for ogrImportForeignSchema */ #endif /* PostgreSQL 9.3+ version check */ pgsql-ogr-fdw-1.1.9/ogr_fdw.control000066400000000000000000000002301522375352200172450ustar00rootroot00000000000000# ogr_fdw extension comment = 'foreign-data wrapper for GIS data access' default_version = '1.1' module_pathname = '$libdir/ogr_fdw' relocatable = true pgsql-ogr-fdw-1.1.9/ogr_fdw.h000066400000000000000000000130021522375352200160150ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * ogr_fdw.h * foreign-data wrapper for GIS data access. * * Copyright (c) 2014-2015, Paul Ramsey * *------------------------------------------------------------------------- */ #pragma once /* * PostgreSQL */ #include "postgres.h" #include "access/heapam.h" #include "access/htup_details.h" #include "access/reloptions.h" #include "access/sysattr.h" #include "access/transam.h" #include "access/tupdesc.h" #include "catalog/indexing.h" #include "catalog/namespace.h" #include "catalog/pg_collation.h" #include "catalog/pg_extension.h" #include "catalog/pg_foreign_table.h" #include "catalog/pg_foreign_server.h" #include "catalog/pg_namespace.h" #include "catalog/pg_operator.h" #include "catalog/pg_proc.h" #include "catalog/pg_type.h" #include "commands/copy.h" #include "commands/defrem.h" #include "commands/explain.h" #include "commands/extension.h" #include "commands/vacuum.h" #include "foreign/fdwapi.h" #include "foreign/foreign.h" #include "mb/pg_wchar.h" #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" #include "optimizer/pathnode.h" #include "optimizer/planmain.h" #include "optimizer/restrictinfo.h" #include "parser/parsetree.h" #include "storage/ipc.h" #include "utils/builtins.h" #include "utils/catcache.h" #include "utils/date.h" #include "utils/fmgroids.h" #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/numeric.h" #include "utils/rel.h" #include "utils/syscache.h" #include "utils/timestamp.h" #if PG_VERSION_NUM < 120000 #include "nodes/relation.h" #include "optimizer/var.h" #else #include "executor/tuptable.h" #include "optimizer/appendinfo.h" #endif #ifdef PACKAGE_URL #undef PACKAGE_URL #endif /* GDAL/OGR includes and compat */ #include "ogr_fdw_gdal.h" #include "ogr_fdw_common.h" /* Local configuration defines */ #define OGR_FDW_VERSION "1.1" /* Use hexwkb input by default, but have option to use */ /* the binary recv input instead. Binary input is strict */ /* on geometry structure (no unclosed polys, etc) and */ /* hexwkb is not. */ #define OGR_FDW_HEXWKB TRUE extern Oid GEOMETRYOID; typedef enum { OGR_UNMATCHED, OGR_GEOMETRY, OGR_FID, OGR_FIELD } OgrColumnVariant; typedef enum { OGR_UPDATEABLE_FALSE, OGR_UPDATEABLE_TRUE, OGR_UPDATEABLE_UNSET, OGR_UPDATEABLE_TRY } OgrUpdateable; typedef struct OgrFdwColumn { /* PgSQL metadata */ int pgattnum; /* PgSQL attribute number */ int pgattisdropped; /* PgSQL attribute dropped? */ char* pgname; /* PgSQL column name */ Oid pgtype; /* PgQL data type */ int pgtypmod; /* PgSQL type modifier */ bool pgisarray; Oid pgelmtype; /* If column is array then this is nonzero */ /* For reading. If array, for array element type. */ Oid pginputfunc; /* PgSQL convert cstring to type */ Oid pginputioparam; Oid pgrecvfunc; /* PgSQL convert binary to type */ Oid pgrecvioparam; /* For writing. If array, for array element type. */ Oid pgoutputfunc; /* PgSQL convert type to cstring */ bool pgoutputvarlena; Oid pgsendfunc; /* PgSQL convert type to binary */ bool pgsendvarlena; /* OGR metadata */ OgrColumnVariant ogrvariant; int ogrfldnum; OGRFieldType ogrfldtype; } OgrFdwColumn; typedef struct OgrFdwTable { int ncols; char* tblname; OgrFdwColumn* cols; } OgrFdwTable; typedef struct OgrFdwSpatialFilter { int ogrfldnum; double minx, miny, maxx, maxy; } OgrFdwSpatialFilter; typedef struct OgrConnection { const char* ds_str; /* datasource connection string */ const char* dr_str; /* driver (format) name */ char* lyr_str; /* layer name */ const char* config_options; /* GDAL config options */ const char* open_options; /* GDAL open options */ OgrUpdateable ds_updateable; OgrUpdateable lyr_updateable; int char_encoding; /* Is OGR layer UTF? Has user provided encoding open option? */ GDALDatasetH ds; /* GDAL datasource handle */ OGRLayerH lyr; /* OGR layer handle */ } OgrConnection; typedef enum { OGR_PLAN_STATE, OGR_EXEC_STATE, OGR_MODIFY_STATE } OgrFdwStateType; typedef struct OgrFdwState { OgrFdwStateType type; Oid foreigntableid; OgrConnection ogr; /* connection object */ OgrFdwTable* table; TupleDesc tupdesc; } OgrFdwState; typedef struct OgrFdwPlanState { OgrFdwStateType type; Oid foreigntableid; OgrConnection ogr; OgrFdwTable* table; TupleDesc tupdesc; int nrows; /* estimate of number of rows in file */ Cost startup_cost; Cost total_cost; bool* pushdown_clauses; } OgrFdwPlanState; typedef struct OgrFdwExecState { OgrFdwStateType type; Oid foreigntableid; OgrConnection ogr; OgrFdwTable *table; TupleDesc tupdesc; char* sql; /* OGR SQL for attribute filter */ int rownum; /* how many rows have we read thus far? */ Oid setsridfunc; /* ST_SetSRID() */ Oid typmodsridfunc; /* postgis_typmod_srid() */ } OgrFdwExecState; typedef struct OgrFdwModifyState { OgrFdwStateType type; Oid foreigntableid; OgrConnection ogr; /* connection object */ OgrFdwTable* table; TupleDesc tupdesc; } OgrFdwModifyState; /* Shared function signatures */ bool ogrDeparse(StringInfo buf, PlannerInfo* root, RelOptInfo* foreignrel, List* exprs, OgrFdwState* state, List** params_list, OgrFdwSpatialFilter** sf); Oid ogrGetGeometryOid(void); OGRErr pgDatumToOgrGeometry (Datum pg_geometry, Oid pgsendfunc, OGRGeometryH* ogr_geometry); pgsql-ogr-fdw-1.1.9/ogr_fdw_common.c000066400000000000000000000241171522375352200173710ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * ogr_fdw_common.c * foreign-data wrapper for GIS data access. * * Copyright (c) 2014-2016, Paul Ramsey * *------------------------------------------------------------------------- */ #include "ogr_fdw_gdal.h" #include "ogr_fdw_common.h" #include "stringbuffer.h" #include "pg_config_manual.h" /* Prototype for function that must be defined in PostgreSQL (it is) */ /* and in ogr_fdw_info (it is) */ const char * quote_identifier(const char *ident); /* * Append a SQL string literal representing "val" to buf. */ static void ogrDeparseStringLiteral(stringbuffer_t *buf, const char *val) { const char *valptr; /* * Rather than making assumptions about the remote server's value of * standard_conforming_strings, always use E'foo' syntax if there are any * backslashes. This will fail on remote servers before 8.1, but those * are long out of support. */ if ( strchr(val, '\\') != NULL ) { stringbuffer_append_char(buf, 'E'); } stringbuffer_append_char(buf, '\''); for ( valptr = val; *valptr; valptr++ ) { char ch = *valptr; if ( ch == '\'' || ch == '\\' ) { stringbuffer_append_char(buf, ch); } stringbuffer_append_char(buf, ch); } stringbuffer_append_char(buf, '\''); } void ogrStringLaunder(char *str) { int i, j = 0; char tmp[NAMEDATALEN]; memset(tmp, 0, NAMEDATALEN); for(i = 0; str[i]; i++) { char c = tolower(str[i]); /* First character is a numeral, prefix with 'n' */ if ( i == 0 && (c >= 48 && c <= 57) ) { tmp[j++] = 'n'; } /* Replace non-safe characters w/ _ */ if ( (c >= 48 && c <= 57) || /* 0-9 */ (c >= 65 && c <= 90) || /* A-Z */ (c >= 97 && c <= 122) /* a-z */ ) { /* Good character, do nothing */ } else { c = '_'; } tmp[j++] = c; /* Avoid mucking with data beyond the end of our stack-allocated strings */ if ( j >= NAMEDATALEN - 1) break; } strncpy(str, tmp, NAMEDATALEN); } static void ogrTypeToPgType(OGRFieldDefnH ogr_fld, char *pgtype, size_t width) { OGRFieldType ogr_type = OGR_Fld_GetType(ogr_fld); #if GDAL_VERSION_MAJOR >= 2 OGRFieldSubType ogr_subtype = OGR_Fld_GetSubType(ogr_fld); #endif switch(ogr_type) { case OFTInteger: #if GDAL_VERSION_MAJOR >= 2 if (ogr_subtype == OFSTBoolean) { snprintf(pgtype, width, "boolean"); break; } else #endif snprintf(pgtype, width, "integer"); break; case OFTReal: snprintf(pgtype, width, "double precision"); break; case OFTString: { int ogr_fld_width; #if GDAL_VERSION_MAJOR >= 2 if (ogr_subtype == OFSTJSON) { snprintf(pgtype, width, "jsonb"); break; } #endif ogr_fld_width = OGR_Fld_GetWidth(ogr_fld); /* MaxAttrSize = 10*1024*1024 */ if (ogr_fld_width > 0 && ogr_fld_width < 10*1024*1024) snprintf(pgtype, width, "varchar(%d)", ogr_fld_width); else snprintf(pgtype, width, "varchar"); break; } case OFTBinary: snprintf(pgtype, width, "bytea"); break; case OFTDate: snprintf(pgtype, width, "date"); break; case OFTTime: snprintf(pgtype, width, "time"); break; case OFTDateTime: snprintf(pgtype, width, "timestamp"); break; case OFTIntegerList: snprintf(pgtype, width, "integer[]"); break; case OFTRealList: snprintf(pgtype, width, "double precision[]"); break; case OFTStringList: snprintf(pgtype, width, "varchar[]"); break; #if GDAL_VERSION_MAJOR >= 2 case OFTInteger64: snprintf(pgtype, width, "bigint"); break; case OFTInteger64List: snprintf(pgtype, width, "bigint[]"); break; #endif default: CPLError(CE_Failure, CPLE_AssertionFailed, "unsupported GDAL type '%s'", OGR_GetFieldTypeName(ogr_type)); return; } return; } static void ogrGeomTypeToPgGeomType(stringbuffer_t *buf, OGRwkbGeometryType gtype) { switch(wkbFlatten(gtype)) { case wkbUnknown: stringbuffer_append(buf, "Geometry"); break; case wkbPoint: stringbuffer_append(buf, "Point"); break; case wkbLineString: stringbuffer_append(buf, "LineString"); break; case wkbPolygon: stringbuffer_append(buf, "Polygon"); break; case wkbMultiPoint: stringbuffer_append(buf, "MultiPoint"); break; case wkbMultiLineString: stringbuffer_append(buf, "MultiLineString"); break; case wkbMultiPolygon: stringbuffer_append(buf, "MultiPolygon"); break; case wkbGeometryCollection: stringbuffer_append(buf, "GeometryCollection"); break; #if GDAL_VERSION_MAJOR >= 2 case wkbCircularString: stringbuffer_append(buf, "CircularString"); break; case wkbCompoundCurve: stringbuffer_append(buf, "CompoundCurve"); break; case wkbCurvePolygon: stringbuffer_append(buf, "CurvePolygon"); break; case wkbMultiCurve: stringbuffer_append(buf, "MultiCurve"); break; case wkbMultiSurface: stringbuffer_append(buf, "MultiSurface"); break; #endif case wkbNone: CPLError(CE_Failure, CPLE_AssertionFailed, "Cannot handle OGR geometry type wkbNone"); break; default: CPLError(CE_Failure, CPLE_AssertionFailed, "Cannot handle OGR geometry type '%d'", gtype); } #if GDAL_VERSION_MAJOR >= 2 if ( wkbHasZ(gtype) ) #else if ( gtype & wkb25DBit ) #endif stringbuffer_append(buf, "Z"); #if GDAL_VERSION_MAJOR >= 2 && GDAL_VERSION_MINOR >= 1 if ( wkbHasM(gtype) ) stringbuffer_append(buf, "M"); #endif return; } static OGRErr ogrColumnNameToSQL (const char *ogrcolname, const char *pgtype, int launder_column_names, stringbuffer_t *buf) { char pgcolname[NAMEDATALEN]; strncpy(pgcolname, ogrcolname, NAMEDATALEN); ogrStringLaunder(pgcolname); if ( launder_column_names ) { stringbuffer_aprintf(buf, ",\n %s %s", quote_identifier(pgcolname), pgtype); if ( ! strcaseeq(pgcolname, ogrcolname) ) { stringbuffer_append(buf, " OPTIONS (column_name "); ogrDeparseStringLiteral(buf, ogrcolname); stringbuffer_append(buf, ")"); } } else { /* OGR column is PgSQL compliant, we're all good */ if ( streq(pgcolname, ogrcolname) ) stringbuffer_aprintf(buf, ",\n %s %s", quote_identifier(ogrcolname), pgtype); /* OGR is mixed case or non-compliant, we need to quote it */ else stringbuffer_aprintf(buf, ",\n \"%s\" %s", ogrcolname, pgtype); } return OGRERR_NONE; } OGRErr ogrLayerToSQL (const OGRLayerH ogr_lyr, const char *fdw_server, int launder_table_names, int launder_column_names, const char *fdw_table_name, int use_postgis_geometry, stringbuffer_t *buf) { int geom_field_count, i; char table_name[NAMEDATALEN]; OGRFeatureDefnH ogr_fd = OGR_L_GetLayerDefn(ogr_lyr); stringbuffer_t gbuf; stringbuffer_init(&gbuf); if ( ! ogr_fd ) { CPLError(CE_Failure, CPLE_AssertionFailed, "unable to get OGRFeatureDefnH from OGRLayerH"); return OGRERR_FAILURE; } #if GDAL_VERSION_MAJOR >= 2 || GDAL_VERSION_MINOR >= 11 geom_field_count = OGR_FD_GetGeomFieldCount(ogr_fd); #else geom_field_count = (OGR_L_GetGeomType(ogr_lyr) != wkbNone); #endif /* Process table name */ if (fdw_table_name == NULL) { strncpy(table_name, OGR_L_GetName(ogr_lyr), NAMEDATALEN); if (launder_table_names) ogrStringLaunder(table_name); } else { strncpy(table_name, fdw_table_name, NAMEDATALEN); } /* Create table */ stringbuffer_aprintf(buf, "CREATE FOREIGN TABLE %s (\n", quote_identifier(table_name)); /* For now, every table we auto-create will have a FID */ stringbuffer_append(buf, " fid bigint"); /* Handle all geometry columns in the OGR source */ for ( i = 0; i < geom_field_count; i++ ) { int srid = 0; #if GDAL_VERSION_MAJOR >= 2 || GDAL_VERSION_MINOR >= 11 OGRGeomFieldDefnH gfld = OGR_FD_GetGeomFieldDefn(ogr_fd, i); OGRwkbGeometryType gtype = OGR_GFld_GetType(gfld); const char *geomfldname = OGR_GFld_GetNameRef(gfld); OGRSpatialReferenceH gsrs = OGR_GFld_GetSpatialRef(gfld); #else OGRwkbGeometryType gtype = OGR_FD_GetGeomType(ogr_fd); const char *geomfldname = "geom"; OGRSpatialReferenceH gsrs = OGR_L_GetSpatialRef(ogr_lyr); #endif /* Skip geometry type we cannot handle */ if ( gtype == wkbNone ) continue; /* Clear out our geometry type buffer */ stringbuffer_clear(&gbuf); /* PostGIS geometry type has lots of complex stuff */ if ( use_postgis_geometry ) { /* Add geometry type info */ stringbuffer_append(&gbuf, "Geometry("); ogrGeomTypeToPgGeomType(&gbuf, gtype); /* See if we have an EPSG code to work with */ if ( gsrs ) { const char *charAuthType; const char *charSrsCode; OSRAutoIdentifyEPSG(gsrs); charAuthType = OSRGetAttrValue(gsrs, "AUTHORITY", 0); charSrsCode = OSRGetAttrValue(gsrs, "AUTHORITY", 1); if ( charAuthType && strcaseeq(charAuthType, "EPSG") && charSrsCode && atoi(charSrsCode) > 0 ) { srid = atoi(charSrsCode); } } /* Add EPSG number, if figured it out */ if ( srid ) { stringbuffer_aprintf(&gbuf, ",%d)", srid); } else { stringbuffer_append(&gbuf, ")"); } } /* Bytea is simple */ else { stringbuffer_append(&gbuf, "bytea"); } /* Use geom field name if we have it */ if ( geomfldname && strlen(geomfldname) > 0 ) { ogrColumnNameToSQL(geomfldname, stringbuffer_getstring(&gbuf), launder_column_names, buf); } /* Or a numbered generic name if we don't */ else if ( geom_field_count > 1 ) { stringbuffer_aprintf(buf, ",\n geom%d %s", i, stringbuffer_getstring(&gbuf)); } /* Or just a generic name */ else { stringbuffer_aprintf(buf, ",\n geom %s", stringbuffer_getstring(&gbuf)); } } /* Write out attribute fields */ for ( i = 0; i < OGR_FD_GetFieldCount(ogr_fd); i++ ) { char pgtype[NAMEDATALEN]; OGRFieldDefnH ogr_fld = OGR_FD_GetFieldDefn(ogr_fd, i); ogrTypeToPgType(ogr_fld, pgtype, sizeof(pgtype)); ogrColumnNameToSQL(OGR_Fld_GetNameRef(ogr_fld), pgtype, launder_column_names, buf); } /* * Add server name and layer-level options. We specify remote * layer name as option */ stringbuffer_aprintf(buf, "\n) SERVER %s\nOPTIONS (", quote_identifier(fdw_server)); stringbuffer_append(buf, "layer "); ogrDeparseStringLiteral(buf, OGR_L_GetName(ogr_lyr)); stringbuffer_append(buf, ");\n"); return OGRERR_NONE; } pgsql-ogr-fdw-1.1.9/ogr_fdw_common.h000066400000000000000000000015341522375352200173740ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * ogr_fdw_common.h * foreign-data wrapper for GIS data access. * * Copyright (c) 2014-2015, Paul Ramsey * *------------------------------------------------------------------------- */ #pragma once #include #include #include "stringbuffer.h" #define STR_MAX_LEN 256 /* Utility macros for string equality */ #define streq(s1,s2) (strcmp((s1),(s2)) == 0) #define strcaseeq(s1,s2) (strcasecmp((s1),(s2)) == 0) /* Re-write a string in place with laundering rules */ void ogrStringLaunder(char *str); OGRErr ogrLayerToSQL (const OGRLayerH ogr_lyr, const char *fwd_server, int launder_table_names, int launder_column_names, const char *fdw_table_name, int use_postgis_geometry, stringbuffer_t *buf); pgsql-ogr-fdw-1.1.9/ogr_fdw_deparse.c000066400000000000000000000412011522375352200175150ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * ogr_fdw_deparse.c * foreign-data wrapper for GIS data access. * * Copyright (c) 2014-2015, Paul Ramsey * * Convert parse tree to a QueryExpression as described at * http://gdal.org/ogr_sql.html *------------------------------------------------------------------------- */ /* * Local structures */ #include "ogr_fdw.h" typedef struct OgrDeparseCtx { PlannerInfo* root; /* global planner state */ RelOptInfo* foreignrel; /* the foreign relation we are planning for */ StringInfo buf; /* output buffer to append to */ List** params_list; /* exprs that will become remote Params */ OgrFdwSpatialFilter* spatial_filter; /* spatial filter bounds and fieldnumber */ OgrFdwState* state; /* to convert local column names to OGR names */ } OgrDeparseCtx; /* Local function signatures */ static bool ogrDeparseExpr(Expr* node, OgrDeparseCtx* context); // static void ogrDeparseOpExpr(OpExpr* node, OgrDeparseCtx *context); static void setStringInfoLength(StringInfo str, int len) { str->len = len; str->data[len] = '\0'; } static void stringInfoReverse(StringInfo str, unsigned int len) { if (str->len > len) str->len -= len; } static char* ogrStringFromDatum(Datum datum, Oid type) { StringInfoData result; regproc typoutput; HeapTuple tuple; char* str, *p; /* Special handling for boolean */ if (type == BOOLOID) { if (datum) { return "1=1"; } else { return "1=0"; } } /* get the type's output function */ tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type)); if (!HeapTupleIsValid(tuple)) { elog(ERROR, "cache lookup failed for type %u", type); } typoutput = ((Form_pg_type)GETSTRUCT(tuple))->typoutput; ReleaseSysCache(tuple); initStringInfo(&result); /* Special handling to convert a geometry to a bbox needed here */ if (type == ogrGetGeometryOid()) { elog(ERROR, "got a GEOMETRY!"); return NULL; } /* render the constant in OGR SQL */ switch (type) { case TEXTOID: case DATEOID: case TIMESTAMPOID: case TIMESTAMPTZOID: case CHAROID: case BPCHAROID: case VARCHAROID: case NAMEOID: str = DatumGetCString(OidFunctionCall1(typoutput, datum)); /* Don't return a zero length string, return an empty string */ if (str[0] == '\0') { return "''"; } /* wrap string with ' */ appendStringInfoChar(&result, '\''); for (p = str; *p; ++p) { /* Escape single quotes as doubled '' */ if (*p == '\'') { appendStringInfoChar(&result, '\''); } appendStringInfoChar(&result, *p); } appendStringInfoChar(&result, '\''); break; case INT8OID: case INT2OID: case INT4OID: case OIDOID: case FLOAT4OID: case FLOAT8OID: case NUMERICOID: appendStringInfoString(&result, DatumGetCString(OidFunctionCall1(typoutput, datum))); break; default: elog(DEBUG1, "could not convert type (%d) to OGR query form", type); return NULL; } return result.data; } static bool ogrDeparseConst(Const* constant, OgrDeparseCtx* context) { /* TODO: Can OGR do anythign w/ NULL? */ if (constant->constisnull) { appendStringInfoString(context->buf, "NULL"); } /* Use geometry as a spatial filter? */ else if (constant->consttype == ogrGetGeometryOid()) { /* * For geometry we need to convert the gserialized constant into * an OGRGeometry for the OGR spatial filter. * For that, we can use the type's "send" function * which takes in gserialized and spits out EWKB. */ Oid sendfunction; bool typeIsVarlena; Datum wkbdatum; char* gser; char* wkb; char* wkt; int wkb_size; OGRGeometryH ogrgeom; /* * Given a type oid (geometry in this case), * look up the "send" function that takes in * serialized input and outputs the binary (WKB) form. */ getTypeBinaryOutputInfo(constant->consttype, &sendfunction, &typeIsVarlena); wkbdatum = OidFunctionCall1(sendfunction, constant->constvalue); /* * Convert the WKB into an OGR geometry */ gser = DatumGetPointer(wkbdatum); wkb = VARDATA(gser); wkb_size = VARSIZE(gser) - VARHDRSZ; OGR_G_CreateFromWkb((unsigned char*)wkb, NULL, &ogrgeom, wkb_size); OGR_G_ExportToWkt(ogrgeom, &wkt); elog(DEBUG1, "ogrDeparseConst got a geometry: %s", wkt); CPLFree(wkt); OGR_G_DestroyGeometry(ogrgeom); /* * geometry doesn't play a role in the deparsed SQL */ return false; } else { /* get a string representation of the value */ char* c = ogrStringFromDatum(constant->constvalue, constant->consttype); if (c == NULL) { return false; } else { appendStringInfoString(context->buf, c); } } return true; } static bool ogrDeparseParam(Param* node, OgrDeparseCtx* context) { elog(DEBUG3, "got into ogrDeparseParam code"); return false; } static bool ogrIsLegalVarName(const char* varname) { size_t len = strlen(varname); int i; for (i = 0; i < len; i++) { char c = varname[i]; /* First char must be a-zA-Z */ if (i == 0 && !((c >= 97 && c <= 122) || (c >= 65 && c <= 90))) { return false; } /* All other chars must be 0-9a-zA-Z_ */ if (!((c >= 97 && c <= 122) || (c >= 65 && c <= 90) || (c >= 48 && c <= 59) || (c == 96))) { return false; } } return true; } static bool ogrDeparseVarOgrColumn(const Var* node, const OgrDeparseCtx* context, OgrFdwColumn *col) { /* Var belongs to foreign table */ int i; OgrFdwTable* table = context->state->table; for (i = 0; i < table->ncols; i++) { if (table->cols[i].pgattnum == node->varattno) { *col = table->cols[i]; return true; } } return false; } static const char * ogrDeparseVarName(const Var* node, const OgrDeparseCtx* context) { /* Var belongs to foreign table */ OGRLayerH lyr = context->state->ogr.lyr; OgrFdwColumn col; if (ogrDeparseVarOgrColumn(node, context, &col)) { const char* fldname = NULL; if (col.ogrvariant == OGR_FID) { fldname = OGR_L_GetFIDColumn(lyr); if (! fldname || strlen(fldname) == 0) { fldname = "fid"; } } else if (col.ogrvariant == OGR_FIELD) { OGRFeatureDefnH fd = OGR_L_GetLayerDefn(lyr); OGRFieldDefnH fld = OGR_FD_GetFieldDefn(fd, col.ogrfldnum); fldname = OGR_Fld_GetNameRef(fld); } if (fldname) return fldname; } return NULL; } static bool ogrDeparseVar(const Var* node, OgrDeparseCtx* context) { StringInfoData* buf = context->buf; /* varno must not be any of OUTER_VAR, INNER_VAR and INDEX_VAR. */ Assert(!IS_SPECIAL_VARNO(node->varno)); if (node->varno == context->foreignrel->relid && node->varlevelsup == 0) { const char* fldname = ogrDeparseVarName(node, context); if (fldname) { if (ogrIsLegalVarName(fldname)) { appendStringInfoString(buf, fldname); } else { appendStringInfo(buf, "\"%s\"", fldname); } } else { return false; } } else { elog(ERROR, "got to param handling section of ogrDeparseVar"); return false; } return true; } static int ogrOperatorCmpFunc(const void* a, const void* b) { return strcasecmp(*(const char**)a, *(const char**)b); } static bool ogrOperatorIsSupported(const char* opname) { /* IMPORTANT */ /* This array MUST be in sorted order or the bsearch will fail */ static const char* ogrOperators[10] = { "!=", "&&", "<", "<=", "<>", "=", ">", ">=", "~~", "~~*" }; elog(DEBUG3, "ogrOperatorIsSupported got operator '%s'", opname); return NULL != bsearch(&opname, ogrOperators, 10, sizeof(char*), ogrOperatorCmpFunc); } static bool ogrDeparseOpExprSpatial(OpExpr* node, OgrDeparseCtx* context) { Expr* r_arg = lfirst(list_head(node->args)); Expr* l_arg = lfirst(list_tail(node->args)); Expr* exprconst = NULL; Const* constant = NULL; Var* var = NULL; OgrFdwColumn col; OGRLayerH lyr; OGRFeatureDefnH fdh; OGRGeomFieldDefnH gfdh; OGRGeometryH geom; OGREnvelope env; OGRErr err; const char* fldname; elog(DEBUG4, "%s:%d entered ogrDeparseOpExprSpatial", __FILE__, __LINE__); /* We need a Geometry T_Const on one side and a T_Var */ /* column on the other side that is from the FDW relation */ /* Both of those implies and OGR spatial filter can be reasonably */ /* set. */ if (nodeTag(l_arg) == T_Var) { var = (Var*)l_arg; exprconst = r_arg; } else if (nodeTag(r_arg) == T_Var) { var = (Var*)r_arg; exprconst = l_arg; } else return false; if (nodeTag(exprconst) == T_Const) { constant = (Const*)exprconst; } else return false; /* Const isn't a geometry type? Done. */ if (constant->consttype != ogrGetGeometryOid() || constant->constisnull || constant->constbyval) return false; /* Var doesn't match an OGR field? Done. */ if (!ogrDeparseVarOgrColumn(var, context, &col)) return false; /* Matched field isn't an OGR geometry? Done. */ if (col.ogrvariant != OGR_GEOMETRY) return false; lyr = context->state->ogr.lyr; fdh = OGR_L_GetLayerDefn(lyr); gfdh = OGR_FD_GetGeomFieldDefn(fdh, col.ogrfldnum); fldname = OGR_GFld_GetNameRef(gfdh); elog(DEBUG4, "%s:%d geometry fieldname '%s'", __FILE__, __LINE__, fldname); err = pgDatumToOgrGeometry (constant->constvalue, col.pgsendfunc, &geom); if (err != OGRERR_NONE) return false; elog(DEBUG4, "%s:%d geometry constant is %s", __FILE__, __LINE__, OGR_G_ExportToJson(geom)); OGR_G_GetEnvelope(geom, &env); OGR_G_DestroyGeometry(geom); context->spatial_filter = palloc(sizeof(OgrFdwSpatialFilter)); context->spatial_filter->minx = env.MinX; context->spatial_filter->maxx = env.MaxX; context->spatial_filter->miny = env.MinY; context->spatial_filter->maxy = env.MaxY; context->spatial_filter->ogrfldnum = col.ogrfldnum; elog(DEBUG4, "%s:%d OGR spatial filter is (%f %f, %f %f)", __FILE__, __LINE__, env.MinX, env.MinY, env.MaxX, env.MaxY); return false; } static bool ogrDeparseOpExpr(OpExpr* node, OgrDeparseCtx* context) { StringInfo buf = context->buf; HeapTuple tuple; Form_pg_operator form; char oprkind; char* opname; ListCell* arg; bool result = true; /* Retrieve information about the operator from system catalog. */ tuple = SearchSysCache1(OPEROID, ObjectIdGetDatum(node->opno)); if (!HeapTupleIsValid(tuple)) { elog(ERROR, "cache lookup failed for operator %u", node->opno); } form = (Form_pg_operator) GETSTRUCT(tuple); oprkind = form->oprkind; opname = NameStr(form->oprname); /* Don't deparse expressions we cannot support */ if (! ogrOperatorIsSupported(opname)) { ReleaseSysCache(tuple); return false; } /* Overlaps operator is special case: if one side is a */ /* constant (T_Const), and the other is a table column (T_Var), */ /* then we can pass it as a spatial filter to OGR */ if (strcmp("&&", opname) == 0) { ReleaseSysCache(tuple); return ogrDeparseOpExprSpatial(node, context); } /* Sanity check. */ Assert((oprkind == 'r' && list_length(node->args) == 1) || (oprkind == 'l' && list_length(node->args) == 1) || (oprkind == 'b' && list_length(node->args) == 2)); /* Always parenthesize the operator expression. */ appendStringInfoChar(buf, '('); /* Deparse left operand. */ if (oprkind == 'r' || oprkind == 'b') { arg = list_head(node->args); /* recurse for nested operations */ result &= ogrDeparseExpr(lfirst(arg), context); appendStringInfoChar(buf, ' '); } /* Special case, the 'LIKE' operator is converted to ~~ */ /* by PgSQL, so we have to convert it back here */ /* All OGR string comparisons are case insensitive, so we just */ /* use 'ILIKE' all the time. */ if (streq(opname, "~~") || streq(opname, "~~*")) { opname = "ILIKE"; } /* Operator symbol */ appendStringInfoString(buf, opname); /* Deparse right operand. */ if (oprkind == 'l' || oprkind == 'b') { arg = list_tail(node->args); appendStringInfoChar(buf, ' '); /* recurse for nested operations */ result &= ogrDeparseExpr(lfirst(arg), context); } appendStringInfoChar(buf, ')'); ReleaseSysCache(tuple); return result; } static bool ogrDeparseBoolExpr(BoolExpr* node, OgrDeparseCtx* context) { const char* op = NULL; /* keep compiler quiet */ ListCell* lc; bool first = true; bool result = true; int len_save_all, len_save_part; int boolop = node->boolop; int result_total = 0; StringInfo buf = context->buf; switch (boolop) { case AND_EXPR: op = "AND"; break; case OR_EXPR: op = "OR"; break; /* OGR SQL cannot handle "NOT" */ case NOT_EXPR: return false; } len_save_all = buf->len; appendStringInfoChar(buf, '('); foreach (lc, node->args) { len_save_part = buf->len; /* Connect expressions and parenthesize each condition */ if (! first) { appendStringInfo(buf, " %s ", op); } /* Unparse the expression, if possible */ result = ogrDeparseExpr((Expr*) lfirst(lc), context); result_total += result; /* We can backtrack just this term for AND expressions */ if (boolop == AND_EXPR && ! result) { setStringInfoLength(buf, len_save_part); } /* We have to drop the whole thing if we can't get every part of an OR expression */ if (boolop == OR_EXPR && ! result) { break; } /* Don't flip the "first" bit until we get a good expression */ if (first && result) { first = false; } } appendStringInfoChar(buf, ')'); /* We have to drop the whole thing if we can't get every part of an OR expression */ if (boolop == OR_EXPR && ! result) { setStringInfoLength(buf, len_save_all); } return result_total > 0; } static bool ogrDeparseRelabelType(RelabelType* node, OgrDeparseCtx* context) { if (node->relabelformat != COERCE_IMPLICIT_CAST) { elog(WARNING, "Received a non-implicit relabel expression but did not handle it"); } return ogrDeparseExpr(node->arg, context); } static bool ogrDeparseNullTest(NullTest* node, OgrDeparseCtx* context) { StringInfo buf = context->buf; /* Only push down simple "col IS NULL" tests */ if (nodeTag(node->arg) != T_Var) return false; appendStringInfoString(buf, "("); if(!ogrDeparseVar((Var*)(node->arg), context)) { stringInfoReverse(buf, 1); return false; } if (node->nulltesttype == IS_NULL) { appendStringInfoString(buf, " IS NULL)"); } else { appendStringInfoString(buf, " IS NOT NULL)"); } return true; } static bool ogrDeparseExpr(Expr* node, OgrDeparseCtx* context) { if (node == NULL) { return false; } switch (nodeTag(node)) { case T_OpExpr: return ogrDeparseOpExpr((OpExpr*) node, context); case T_Const: return ogrDeparseConst((Const*) node, context); case T_Var: return ogrDeparseVar((Var*) node, context); case T_Param: return ogrDeparseParam((Param*) node, context); case T_BoolExpr: /* Handle "OR" and "NOT" queries */ return ogrDeparseBoolExpr((BoolExpr*) node, context); case T_NullTest: /* Handle "IS NULL" queries */ return ogrDeparseNullTest((NullTest*) node, context); case T_RelabelType: return ogrDeparseRelabelType((RelabelType*) node, context); case T_ScalarArrayOpExpr: /* TODO: Handle this to support the "IN" operator */ elog(DEBUG2, "unsupported OGR FDW expression type, T_ScalarArrayOpExpr"); return false; #if PG_VERSION_NUM < 120000 case T_ArrayRef: elog(DEBUG2, "unsupported OGR FDW expression type, T_ArrayRef"); return false; #else case T_SubscriptingRef: elog(DEBUG2, "unsupported OGR FDW expression type, T_SubscriptingRef"); return false; #endif case T_ArrayExpr: elog(DEBUG2, "unsupported OGR FDW expression type, T_ArrayExpr"); return false; case T_FuncExpr: elog(DEBUG2, "unsupported OGR FDW expression type, T_FuncExpr"); return false; case T_DistinctExpr: elog(DEBUG2, "unsupported OGR FDW expression type, T_DistinctExpr"); return false; default: elog(DEBUG2, "unsupported OGR FDW expression type for deparse: %d", (int) nodeTag(node)); return false; } } bool ogrDeparse(StringInfo buf, PlannerInfo* root, RelOptInfo* foreignrel, List* exprs, OgrFdwState* state, List** params_list, OgrFdwSpatialFilter** sf) { OgrDeparseCtx context; ListCell* lc; bool first = true; /* initialize result list to empty */ if (params_list) { *params_list = NIL; } /* Set up context struct for recursion */ memset(&context, 0, sizeof(OgrDeparseCtx)); context.buf = buf; context.root = root; context.foreignrel = foreignrel; context.params_list = params_list; context.state = state; context.spatial_filter = NULL; foreach (lc, exprs) { RestrictInfo* ri = (RestrictInfo*) lfirst(lc); int len_save = buf->len; bool result; /* Connect expressions with "AND" and parenthesize each condition */ if (! first) { appendStringInfoString(buf, " AND "); } /* Unparse the expression, if possible */ result = ogrDeparseExpr(ri->clause, &context); if (! result) { /* Couldn't unparse some portion of the expression, so rewind the stringinfo */ setStringInfoLength(buf, len_save); } /* Don't flip the "first" bit until we get a good expression */ if (first && result) { first = false; } } if (context.spatial_filter) *sf = context.spatial_filter; return true; } pgsql-ogr-fdw-1.1.9/ogr_fdw_func.c000066400000000000000000000041741522375352200170350ustar00rootroot00000000000000 /*------------------------------------------------------------------------- * * ogr_fdw_func.c * Helper functions for OGR FDW * * Copyright (c) 2020, Paul Ramsey * *------------------------------------------------------------------------- */ #include "ogr_fdw.h" #include "ogr_fdw_gdal.h" #include #include #include // #include #include #include /** */ Datum ogr_fdw_drivers(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(ogr_fdw_drivers); Datum ogr_fdw_drivers(PG_FUNCTION_ARGS) { /* Array building */ size_t arr_nelems = 0; Datum *arr_elems; ArrayType *arr; Oid elem_type = TEXTOID; int16 elem_len; bool elem_byval; char elem_align; int num_drivers; int i; if (GDALGetDriverCount() <= 0) GDALAllRegister(); #if (GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(1,11,0)) num_drivers = GDALGetDriverCount(); #else num_drivers = OGRGetDriverCount(); #endif if (num_drivers < 1) PG_RETURN_NULL(); arr_elems = palloc0(num_drivers * sizeof(Datum)); get_typlenbyvalalign(elem_type, &elem_len, &elem_byval, &elem_align); for (i = 0; i < num_drivers; i++) { #if GDAL_VERSION_MAJOR <= 1 OGRSFDriverH hDriver = OGRGetDriver(i); text *txtName = cstring_to_text(OGR_Dr_GetName(hDriver)); arr_elems[arr_nelems++] = PointerGetDatum(txtName); #else GDALDriverH hDriver = GDALGetDriver(i); if (GDALGetMetadataItem(hDriver, GDAL_DCAP_VECTOR, NULL) != NULL) { const char *strName = OGR_Dr_GetName(hDriver); text *txtName = cstring_to_text(strName); arr_elems[arr_nelems++] = PointerGetDatum(txtName); } #endif } arr = construct_array(arr_elems, arr_nelems, elem_type, elem_len, elem_byval, elem_align); PG_RETURN_ARRAYTYPE_P(arr); } /** */ Datum ogr_fdw_version(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(ogr_fdw_version); Datum ogr_fdw_version(PG_FUNCTION_ARGS) { const char *gdal_ver = GDAL_RELEASE_NAME; const char *ogr_fdw_ver = OGR_FDW_VERSION; char ver_str[256]; snprintf(ver_str, sizeof(ver_str), "OGR_FDW=\"%s\" GDAL=\"%s\"", ogr_fdw_ver, gdal_ver); PG_RETURN_TEXT_P(cstring_to_text(ver_str)); } pgsql-ogr-fdw-1.1.9/ogr_fdw_gdal.h000066400000000000000000000031251522375352200170110ustar00rootroot00000000000000 #pragma once /* * Quiet warnings due to double use of * pkgconfig macros in GDAL and PgSQL */ #ifdef PACKAGE_VERSION #undef PACKAGE_VERSION #endif #ifdef PACKAGE_TARNAME #undef PACKAGE_TARNAME #endif #ifdef PACKAGE_STRING #undef PACKAGE_STRING #endif #ifdef PACKAGE_NAME #undef PACKAGE_NAME #endif #ifdef PACKAGE_BUGREPORT #undef PACKAGE_BUGREPORT #endif #ifdef PACKAGE_VERSION #undef PACKAGE_VERSION #endif /* * OGR library API */ #include "gdal.h" #include "ogr_api.h" #include "ogr_srs_api.h" #include "cpl_error.h" #include "cpl_string.h" /* * As far as possible code is GDAL2 compliant, and these * mappings are used to convert to GDAL1-style function * names. For GDALDatasetH opening, there are specific * code blocks to handle version differences between * GDALOpenEx() and OGROpen() */ #if GDAL_VERSION_MAJOR < 2 /* Redefine variable types */ #define GDALDatasetH OGRDataSourceH #define GDALDriverH OGRSFDriverH /* Rename GDAL2 functions to OGR equivs */ #define GDALGetDriverCount() OGRGetDriverCount() #define GDALGetDriver(i) OGRGetDriver(i) #define GDALAllRegister() OGRRegisterAll() #define GDALGetDriverByName(name) OGRGetDriverByName(name) #define GDALClose(ds) OGR_DS_Destroy(ds) #define GDALDatasetGetLayerByName(ds,name) OGR_DS_GetLayerByName(ds,name) #define GDALDatasetGetLayerCount(ds) OGR_DS_GetLayerCount(ds) #define GDALDatasetGetLayer(ds,i) OGR_DS_GetLayer(ds,i) #define GDALGetDriverShortName(dr) OGR_Dr_GetName(dr) #define GDALGetDatasetDriver(ds) OGR_DS_GetDriver(ds) #define GDALDatasetTestCapability(ds,cap) OGR_Dr_TestCapability(ds,cap) #endif /* GDAL 1 support */ pgsql-ogr-fdw-1.1.9/ogr_fdw_info.c000066400000000000000000000256211522375352200170350ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * ogr_fdw_info.c * Commandline utility to read an OGR layer and output a * SQL "create table" statement. * * Copyright (c) 2014-2015, Paul Ramsey * *------------------------------------------------------------------------- */ /* postgresql */ #include "pg_config_manual.h" /* getopt */ #include /* * OGR library API */ #include "ogr_fdw_gdal.h" #include "ogr_fdw_common.h" static void usage(void); static OGRErr ogrListLayers(const char* source); static OGRErr ogrFindLayer(const char* source, int layerno, const char** layer); static OGRErr ogrGenerateSQL(const char* server, const char* layer, const char* table, const char* source, const char* options); static int reserved_word(const char* pgcolumn); static char * ogr_fdw_strupr(char* str) { int i; for (i = 0; i < strlen(str); i++) { str[i] = toupper(str[i]); } return str; } static char * strip_spaces(char* str) { unsigned char *cur = (unsigned char *)str; unsigned char *head = cur; while (*head != '\0') { if (*head != ' ') { *cur = *head; ++cur; } ++head; } *cur = '\0'; return str; } /* Define this no-op here, so that code */ /* in the ogr_fdw_common module works */ const char* quote_identifier(const char* ident); static char identifier[NAMEDATALEN+3]; const char* quote_identifier(const char* ident) { #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3, 13, 0) int len = (int)CPL_MIN(strlen(ident), NAMEDATALEN - 1); #else int len = (int)MIN(strlen(ident), NAMEDATALEN - 1); #endif if (reserved_word(ident)) { snprintf(identifier, sizeof(identifier), "\"%.*s\"", len, ident); } else { snprintf(identifier, sizeof(identifier), "%.*s", len, ident); } return identifier; } static char config_options[STR_MAX_LEN] = {0}; static void formats(void) { int i; GDALAllRegister(); printf("Supported Formats:\n"); for (i = 0; i < GDALGetDriverCount(); i++) { GDALDriverH ogr_dr = GDALGetDriver(i); int vector = FALSE; int createable = TRUE; const char* tmpl; #if GDAL_VERSION_MAJOR >= 2 char** papszMD = GDALGetMetadata(ogr_dr, NULL); vector = CSLFetchBoolean(papszMD, GDAL_DCAP_VECTOR, FALSE); createable = CSLFetchBoolean(papszMD, GDAL_DCAP_CREATE, FALSE); #else createable = GDALDatasetTestCapability(ogr_dr, ODrCCreateDataSource); #endif /* Skip raster data sources */ if (! vector) { continue; } /* Report sources w/ create capability as r/w */ if (createable) { tmpl = " -> \"%s\" (read/write)\n"; } else { tmpl = " -> \"%s\" (readonly)\n"; } printf(tmpl, GDALGetDriverShortName(ogr_dr)); } exit(0); } static void usage(void) { printf( "usage: ogr_fdw_info -s -l -i -t -n -o \n" " ogr_fdw_info -s \n" "usage: ogr_fdw_info -f\n" " Show what input file formats are supported.\n" "\n"); printf( "note (1): You can specify either -l (layer name) or -i (layer index)\n" " if you specify both -l will be used\n" "note (2): config options are specified as a comma deliminated list without the OGR__ prefix\n" " so OGR_XLSX_HEADERS = FORCE OGR_XLSX_FIELD_TYPES = STRING would become:\n" " \"HEADERS = FORCE,FIELD_TYPES = STRING\"" "\n"); exit(0); } int main(int argc, char** argv) { int ch; char* source = NULL; const char* layer = NULL, *server = NULL, *table = NULL, *options = NULL; int layer_index = -1; OGRErr err = OGRERR_NONE; /* If no options are specified, display usage */ if (argc == 1) { usage(); } while ((ch = getopt(argc, argv, "hfs:l:t:n:i:o:")) != -1) { switch (ch) { case 's': source = optarg; break; case 'l': layer = optarg; break; case 'f': formats(); break; case 't': table = optarg; break; case 'n': server = optarg; break; case 'i': layer_index = atoi(optarg) - 1; break; case 'o': options = optarg; break; case '?': case 'h': default: usage(); break; } } if (source && ! layer && layer_index == -1) { err = ogrListLayers(source); } else if (source && (layer || layer_index > -1)) { if (! layer) { err = ogrFindLayer(source, layer_index, &layer); } if (err == OGRERR_NONE) { err = ogrGenerateSQL(server, layer, table, source, options); } } else if (! source && ! layer) { usage(); } if (err != OGRERR_NONE) { printf("OGR Error: %s\n\n", CPLGetLastErrorMsg()); exit(1); } OGRCleanupAll(); exit(0); } static OGRErr ogrListLayers(const char* source) { GDALDatasetH ogr_ds = NULL; int i; GDALAllRegister(); #if GDAL_VERSION_MAJOR < 2 ogr_ds = OGROpen(source, FALSE, NULL); #else ogr_ds = GDALOpenEx(source, GDAL_OF_VECTOR | GDAL_OF_READONLY, NULL, NULL, NULL); #endif if (! ogr_ds) { CPLError(CE_Failure, CPLE_AppDefined, "Could not connect to source '%s'", source); return OGRERR_FAILURE; } printf("Format: %s\n\n", GDALGetDriverShortName(GDALGetDatasetDriver(ogr_ds))); printf("Layers:\n"); for (i = 0; i < GDALDatasetGetLayerCount(ogr_ds); i++) { OGRLayerH ogr_lyr = GDALDatasetGetLayer(ogr_ds, i); if (! ogr_lyr) { return OGRERR_FAILURE; } printf(" %s\n", OGR_L_GetName(ogr_lyr)); } printf("\n"); GDALClose(ogr_ds); return OGRERR_NONE; } static OGRErr ogrGenerateSQL(const char* server, const char* layer, const char* table, const char* source, const char* options) { OGRErr err; GDALDatasetH ogr_ds = NULL; GDALDriverH ogr_dr = NULL; OGRLayerH ogr_lyr = NULL; char server_name[NAMEDATALEN]; stringbuffer_t buf; char **option_iter; char **option_list; GDALAllRegister(); #if GDAL_VERSION_MAJOR < 2 ogr_ds = OGROpen(source, FALSE, &ogr_dr); #else ogr_ds = GDALOpenEx(source, GDAL_OF_VECTOR | GDAL_OF_READONLY, NULL, NULL, NULL); #endif if (! ogr_ds) { CPLError(CE_Failure, CPLE_AppDefined, "Could not connect to source '%s'", source); return OGRERR_FAILURE; } if (! ogr_dr) ogr_dr = GDALGetDatasetDriver(ogr_ds); strncpy(server_name, server == NULL ? "myserver" : server, sizeof(server_name)); if (options != NULL) { char *p; char stripped_config_options[STR_MAX_LEN] = {0}; char option[NAMEDATALEN]; const char *short_name = GDALGetDriverShortName(ogr_dr); strncpy(stripped_config_options, options, STR_MAX_LEN - 1); p = strtok(strip_spaces(stripped_config_options), ","); while (p != NULL) { if (strcmp(short_name, "XLSX") == 0 || strcmp(short_name, "XLSX") == 0 || strcmp(short_name, "ODS") == 0) { /* Unify the handling of the options of spreadsheet file options as they are all the same except they have their * Driver Short Name included in the option */ sprintf(option, "OGR_%s_%s ", short_name, ogr_fdw_strupr(p)); } else { sprintf(option, "%s ", ogr_fdw_strupr(p)); } strcat(config_options, option); p = strtok(NULL, ","); } } option_list = CSLTokenizeString(config_options); for ( option_iter = option_list; option_iter && *option_iter; option_iter++ ) { char *key; const char *value; value = CPLParseNameValue(*option_iter, &key); if (! (key && value)) CPLError(CE_Failure, CPLE_AppDefined, "bad config option string '%s'", config_options); CPLSetConfigOption(key, value); CPLFree(key); } CSLDestroy( option_list ); ogr_lyr = GDALDatasetGetLayerByName(ogr_ds, layer); if (! ogr_lyr) { CPLError(CE_Failure, CPLE_AppDefined, "Could not find layer '%s' in source '%s'", layer, source); return OGRERR_FAILURE; } /* Output SERVER definition */ printf("\nCREATE SERVER %s\n" " FOREIGN DATA WRAPPER ogr_fdw\n" " OPTIONS (\n" " datasource '%s',\n" " format '%s'", quote_identifier(server_name), source, GDALGetDriverShortName(ogr_dr)); if (strlen(config_options) > 0) { printf(",\n config_options '%s');\n", config_options); } else { printf(");\n"); } stringbuffer_init(&buf); err = ogrLayerToSQL(ogr_lyr, server_name, TRUE, /* launder table names */ TRUE, /* launder column names */ table,/* output table name */ TRUE, /* use postgis geometry */ &buf); GDALClose(ogr_ds); if (err != OGRERR_NONE) { return err; } printf("\n%s\n", stringbuffer_getstring(&buf)); stringbuffer_release(&buf); return OGRERR_NONE; } static OGRErr ogrFindLayer(const char *source, int layerno, const char** layer) { GDALDatasetH ogr_ds = NULL; int i; char **option_iter; char **option_list; GDALAllRegister(); option_list = CSLTokenizeString(config_options); for (option_iter = option_list; option_iter && *option_iter; option_iter++) { char *key; const char *value; value = CPLParseNameValue(*option_iter, &key); if (! (key && value)) CPLError(CE_Failure, CPLE_AppDefined, "bad config option string '%s'", config_options); CPLSetConfigOption(key, value); CPLFree(key); } CSLDestroy(option_list); #if GDAL_VERSION_MAJOR < 2 ogr_ds = OGROpen(source, FALSE, NULL); #else ogr_ds = GDALOpenEx(source, GDAL_OF_VECTOR | GDAL_OF_READONLY, NULL, NULL, NULL); #endif if (! ogr_ds) { CPLError(CE_Failure, CPLE_AppDefined, "Could not connect to source '%s'", source); return OGRERR_FAILURE; } for (i = 0; i < GDALDatasetGetLayerCount(ogr_ds); i++) { if (i == layerno) { OGRLayerH ogr_lyr = GDALDatasetGetLayer(ogr_ds, i); if (! ogr_lyr) { return OGRERR_FAILURE; } *layer = OGR_L_GetName(ogr_lyr); return OGRERR_NONE; } } GDALClose(ogr_ds); return OGRERR_FAILURE; } static int reserved_word(const char * pgcolumn) { char* reserved[] = { "all", "analyse", "analyze", "and", "any", "array", "as", "asc", "asymmetric", "authorization", "binary", "both", "case", "cast", "check", "collate", "collation", "column", "concurrently", "constraint", "create", "cross", "current_catalog", "current_date", "current_role", "current_schema", "current_time", "current_timestamp", "current_user", "default", "deferrable", "desc", "distinct", "do", "else", "end", "except", "false", "fetch", "for", "foreign", "freeze", "from", "full", "grant", "group", "having", "ilike", "in", "initially", "inner", "intersect", "into", "is", "isnull", "join", "lateral", "leading", "left", "like", "limit", "localtime", "localtimestamp", "natural", "not", "notnull", "null", "offset", "on", "only", "or", "order", "outer", "overlaps", "placing", "primary", "references", "returning", "right", "select", "session_user", "similar", "some", "symmetric", "table", "tablesample", "then", "to", "trailing", "true", "union", "unique", "user", "using", "variadic", "verbose", "when", "where", "window", "with" }; int i; for (i = 0; i < sizeof(reserved)/sizeof(reserved[0]); i++) { if (strcmp(pgcolumn, reserved[i]) == 0) return 1; } return 0; } pgsql-ogr-fdw-1.1.9/output/000077500000000000000000000000001522375352200155615ustar00rootroot00000000000000pgsql-ogr-fdw-1.1.9/output/file.source000066400000000000000000000121211522375352200177170ustar00rootroot00000000000000CREATE EXTENSION ogr_fdw; CREATE SERVER myserver FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource '@abs_srcdir@/data', format 'ESRI Shapefile' ); ------------------------------------------------ CREATE FOREIGN TABLE pt_1 ( fid integer, geom bytea, name varchar, age integer, height double precision, birthdate date ) SERVER myserver OPTIONS ( layer 'pt_two' ); SELECT * FROM pt_1 WHERE fid = 1; fid | geom | name | age | height | birthdate -----+----------------------------------------------+------+-----+--------+------------ 1 | \x010100000054e943acd697e2bfc0895ee54a46cf3f | Paul | 33 | 5.84 | 03-25-1971 (1 row) ------------------------------------------------ CREATE FOREIGN TABLE pt_2 ( fid integer, name varchar ) SERVER myserver OPTIONS ( layer 'pt_two' ); SELECT * FROM pt_2 ORDER BY name; fid | name -----+------- 1 | Paul 0 | Peter (2 rows) ------------------------------------------------ CREATE FOREIGN TABLE pt_3 ( geom bytea, name varchar ) SERVER myserver OPTIONS ( layer 'pt_two' ); SELECT * FROM pt_3 ORDER BY name; geom | name ----------------------------------------------+------- \x010100000054e943acd697e2bfc0895ee54a46cf3f | Paul \x0101000000c00497d1162cb93f8cbaef08a080e63f | Peter (2 rows) ------------------------------------------------ CREATE FOREIGN TABLE poly_1 ( fid bigint, geom bytea, id double precision, name varchar(5) ) SERVER myserver OPTIONS (layer 'poly'); SELECT length(geom) FROM poly_1 WHERE name = 'Three'; length -------- 307 (1 row) ------------------------------------------------ -- Laundering and explicit column naming test CREATE FOREIGN TABLE column_name_test ( fid integer, name varchar OPTIONS (column_name '2ame'), theage integer OPTIONS (column_name 'age'), height real OPTIONS (column_name 'Height'), birthdate date OPTIONS (column_name 'b-rthdate') ) SERVER myserver OPTIONS (layer '2launder'); SELECT * FROM column_name_test ORDER BY fid; fid | name | theage | height | birthdate -----+-------+--------+--------+------------ 0 | Peter | 45 | 5.6 | 04-12-1965 1 | Paul | 33 | 5.84 | 03-25-1971 (2 rows) -- Check that columns are reverse-laundered when generating -- OGR SQL filters SET client_min_messages = debug1; SELECT name FROM column_name_test WHERE name = 'Paul'; DEBUG: OGR SQL: ("2ame" = 'Paul') name ------ Paul (1 row) SET client_min_messages = notice; ------------------------------------------------ -- GDAL options passing tests CREATE SERVER myserver_latin1 FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource '@abs_srcdir@/data', format 'ESRI Shapefile', config_options 'SHAPE_ENCODING=LATIN1' ); CREATE FOREIGN TABLE e_1 ( fid integer, name varchar ) SERVER myserver_latin1 OPTIONS ( layer 'enc' ); SET client_min_messages = debug1; SELECT fid, name FROM e_1 WHERE fid = 1; DEBUG: GDAL config option 'SHAPE_ENCODING' set to 'LATIN1' DEBUG: OGR SQL: (fid = 1) DEBUG: GDAL config option 'SHAPE_ENCODING' set to 'LATIN1' fid | name -----+------ 1 | Pàul (1 row) SET client_min_messages = notice; ------------------------------------------------ -- Using encoding option directly CREATE SERVER myserver_latin1_direct FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource '@abs_srcdir@/data', format 'ESRI Shapefile', character_encoding 'LATIN1' ); CREATE FOREIGN TABLE e_2 ( fid integer, name varchar ) SERVER myserver_latin1_direct OPTIONS ( layer 'enc' ); SELECT fid, name FROM e_2 WHERE fid = 1; fid | name -----+------ 1 | Pàul (1 row) ------------------------------------------------ -- Geometryless test CREATE SERVER csvserver FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource '@abs_srcdir@/data/no_geom.csv', format 'CSV' ); CREATE FOREIGN TABLE no_geom ( fid bigint, name varchar, age varchar, value varchar ) SERVER csvserver OPTIONS (layer 'no_geom'); SELECT c.* FROM generate_series(1,4) g JOIN no_geom c ON (c.fid = g.g); fid | name | age | value -----+---------+-----+------- 1 | Peter | 34 | 10.2 2 | John | 77 | 3.4 3 | Paul | 45 | 19.2 4 | Matthew | 35 | 18.2 (4 rows) ------------------------------------------------ -- FGDB test CREATE SERVER fgdbserver FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource '/vsizip/@abs_srcdir@/data/Querying.zip/Querying.gdb', format 'OpenFileGDB' ); CREATE FOREIGN TABLE cities ( fid bigint, shape bytea, city_fips varchar(5), city_name varchar(40), state_fips varchar(2), state_name varchar(25), state_city varchar(7), type varchar(25), capital varchar(1), elevation integer, pop1990 integer, popcat integer ) SERVER "fgdbserver" OPTIONS (layer 'Cities'); SET client_min_messages = LOG; SELECT fid, city_name, pop1990 FROM cities WHERE pop1990 = 17710; fid | city_name | pop1990 -----+--------------+--------- 9 | Port Angeles | 17710 (1 row) SELECT fid, city_name, pop1990 FROM cities WHERE city_name = 'Williston'; fid | city_name | pop1990 -----+-----------+--------- 8 | Williston | 13131 (1 row) pgsql-ogr-fdw-1.1.9/output/import.source000066400000000000000000000067321522375352200203250ustar00rootroot00000000000000set client_min_messages=NOTICE; ------------------------------------------------ CREATE SCHEMA imp1; IMPORT FOREIGN SCHEMA ogr_all LIMIT TO (n2launder) FROM SERVER myserver INTO imp1; NOTICE: Number of tables to be created 1 SELECT c.column_name, c.data_type, attfdwoptions FROM information_schema._pg_foreign_table_columns AS fc INNER JOIN information_schema.columns AS c ON fc.nspname = c.table_schema AND fc.relname = c.table_name AND fc.attname = c.column_name WHERE fc.nspname = 'imp1' and fc.relname = 'n2launder' ORDER BY c.ordinal_position; column_name | data_type | attfdwoptions -------------+-------------------+------------------------- fid | bigint | geom | bytea | n2ame | character varying | {column_name=2ame} age | integer | height | double precision | b_rthdate | date | {column_name=b-rthdate} (6 rows) SELECT * FROM imp1.n2launder WHERE fid = 0; fid | geom | n2ame | age | height | b_rthdate -----+----------------------------------------------+-------+-----+--------+------------ 0 | \x0101000000c00497d1162cb93f8cbaef08a080e63f | Peter | 45 | 5.6 | 04-12-1965 (1 row) ------------------------------------------------ CREATE SCHEMA imp2; IMPORT FOREIGN SCHEMA ogr_all LIMIT TO ("natural") FROM SERVER myserver INTO imp2; NOTICE: Number of tables to be created 1 SELECT c.column_name, c.data_type, attfdwoptions FROM information_schema._pg_foreign_table_columns AS fc INNER JOIN information_schema.columns AS c ON fc.nspname = c.table_schema AND fc.relname = c.table_name AND fc.attname = c.column_name WHERE fc.nspname = 'imp2' and fc.relname = 'natural' ORDER BY c.ordinal_position; column_name | data_type | attfdwoptions -------------+-------------------+--------------- fid | bigint | id | double precision | natural | character varying | (3 rows) SELECT "natural" FROM imp2."natural"; natural --------- wood land (2 rows) ------------------------------------------------ CREATE SERVER svr_test_apost FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource '@abs_srcdir@/data/no_geom_apost.csv', format 'CSV' ); CREATE SCHEMA imp3; IMPORT FOREIGN SCHEMA ogr_all LIMIT TO (no_geom_apost) FROM SERVER svr_test_apost INTO imp3; NOTICE: Number of tables to be created 1 SELECT c.column_name, c.data_type, attfdwoptions FROM information_schema._pg_foreign_table_columns AS fc INNER JOIN information_schema.columns AS c ON fc.nspname = c.table_schema AND fc.relname = c.table_name AND fc.attname = c.column_name WHERE fc.nspname = 'imp3' and fc.relname = 'no_geom_apost' ORDER BY c.ordinal_position; column_name | data_type | attfdwoptions ----------------+-------------------+-------------------------------- fid | bigint | name | character varying | age | character varying | person_s_value | character varying | {"column_name=person's value"} (4 rows) SELECT name,age FROM imp3.no_geom_apost WHERE name = 'Paul'; name | age ------+----- Paul | 45 (1 row) SELECT name,age FROM imp3.no_geom_apost WHERE name IS NULL; name | age ------+----- (0 rows) SELECT name,age FROM imp3.no_geom_apost WHERE name = ''; name | age ------+----- | 44 (1 row) ------------------------------------------------ pgsql-ogr-fdw-1.1.9/output/pgsql.source000066400000000000000000000165271522375352200201440ustar00rootroot00000000000000---------------------------------------------------------------------- -- Create local table CREATE TABLE bytea_local ( fid serial primary key, geom bytea, name varchar, age bigint, size integer, value float8, num numeric(6,2), dt date, tm time, dttm timestamp, varch char(8), yn char ); ---------------------------------------------------------------------- -- Populate local table INSERT INTO bytea_local (name, geom, age, size, value, num, dt, tm, dttm, varch, yn) VALUES ('Jim', '14232'::bytea, 23, 1, 4.3, 5.5, '2010-10-10'::date, '13:23:21'::time, '2010-10-10 13:23:21'::timestamp, 'this', 'y' ), ('Marvin', '55555'::bytea, 34, 2, 5.4, 10.13, '2011-11-11'::date, '15:21:45'::time, '2011-11-11 15:21:45'::timestamp, 'that', 'n' ), (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); ---------------------------------------------------------------------- -- Create remote table CREATE SERVER pgserver FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource 'PG:dbname=contrib_regression host=localhost', format 'PostgreSQL' ); CREATE FOREIGN TABLE bytea_fdw ( fid bigint, geom bytea, name varchar, age bigint, size integer, value float8, num numeric(6,2), dt date, tm time, dttm timestamp, varch char(8), yn char ) SERVER pgserver OPTIONS (layer 'bytea_local'); SELECT fid, name, geom, age, size, value, num, dt, tm, dttm, varch, yn FROM bytea_fdw; fid | name | geom | age | size | value | num | dt | tm | dttm | varch | yn -----+--------+--------------+-----+------+-------+-------+------------+----------+--------------------------+----------+---- 1 | Jim | \x3134323332 | 23 | 1 | 4.3 | 5.50 | 10-10-2010 | 13:23:21 | Sun Oct 10 13:23:21 2010 | this | y 2 | Marvin | \x3535353535 | 34 | 2 | 5.4 | 10.13 | 11-11-2011 | 15:21:45 | Fri Nov 11 15:21:45 2011 | that | n 3 | | | | | | | | | | | (3 rows) SELECT a.name, b.name FROM bytea_local a JOIN bytea_fdw b USING (fid); name | name --------+-------- Jim | Jim Marvin | Marvin | (3 rows) EXPLAIN VERBOSE SELECT fid, name, geom, age, size, value, num, dt, tm, dttm, varch, yn FROM bytea_fdw; QUERY PLAN ----------------------------------------------------------------------------- Foreign Scan on public.bytea_fdw (cost=25.00..1025.00 rows=1000 width=170) Output: fid, name, geom, age, size, value, num, dt, tm, dttm, varch, yn (2 rows) ---------------------------------------------------------------------- -- Remote Query and OGR SQL pushdown SET client_min_messages = DEBUG1; SELECT fid, name, geom, age, size, value, num, dt, tm, dttm, varch, yn FROM bytea_fdw WHERE fid = 4; DEBUG: OGR SQL: (fid = 4) fid | name | geom | age | size | value | num | dt | tm | dttm | varch | yn -----+------+------+-----+------+-------+-----+----+----+------+-------+---- (0 rows) SELECT fid, name, dt FROM bytea_fdw WHERE name IS NULL; DEBUG: OGR SQL: (name IS NULL) fid | name | dt -----+------+---- 3 | | (1 row) SELECT fid, name FROM bytea_fdw WHERE name = 'Jim' AND age <= 30; DEBUG: OGR SQL: (age <= 30) AND (name = 'Jim') fid | name -----+------ 1 | Jim (1 row) SELECT fid, name, dt FROM bytea_fdw WHERE name = 'Jim' AND age <= 30 AND dt > '2010-10-1'::date; DEBUG: OGR SQL: (age <= 30) AND (dt > '10-01-2010') AND (name = 'Jim') fid | name | dt -----+------+------------ 1 | Jim | 10-10-2010 (1 row) SELECT fid, name FROM bytea_fdw WHERE name = 'Jim' OR name IS NULL; DEBUG: OGR SQL: ((name = 'Jim') OR (name IS NULL)) fid | name -----+------ 1 | Jim 3 | (2 rows) ---------------------------------------------------------------------- -- Cached query case, exercised by statement handles or -- functions. CREATE OR REPLACE FUNCTION get_names() RETURNS varchar AS $$ BEGIN RETURN (SELECT string_agg(name,',') FROM bytea_fdw WHERE name = 'Jim' OR name IS NULL); END; $$ LANGUAGE 'plpgsql'; SELECT get_names(); DEBUG: OGR SQL: ((name = 'Jim') OR (name IS NULL)) get_names ----------- Jim (1 row) DROP FUNCTION get_names(); ---------------------------------------------------------------------- -- Remote Update INSERT INTO bytea_fdw (name, geom, age, size, value, num, dt, tm, dttm, varch, yn) VALUES ('Margaret', '2222'::bytea, 12, 5, 1.4, 19.13, '2001-11-23'::date, '9:12:34'::time, '2001-02-11 09:23:11'::timestamp, 'them', 'y' ) RETURNING fid, name, geom, age, size, value, num, dt, tm, dttm, varch, yn; fid | name | geom | age | size | value | num | dt | tm | dttm | varch | yn -----+----------+------------+-----+------+-------+-------+------------+----------+--------------------------+----------+---- 4 | Margaret | \x32323232 | 12 | 5 | 1.4 | 19.13 | 11-23-2001 | 09:12:34 | Sun Feb 11 09:23:11 2001 | them | y (1 row) UPDATE bytea_fdw SET name = 'Maggie', num = 45.34, yn = 'n' WHERE age = 12; DEBUG: OGR SQL: (age = 12) SELECT fid, name, num, yn FROM bytea_fdw WHERE fid = 4; DEBUG: OGR SQL: (fid = 4) fid | name | num | yn -----+--------+-------+---- 4 | Maggie | 45.34 | n (1 row) UPDATE bytea_fdw SET dt = '2089-12-13', tm = '01:23:45' WHERE num = 45.34; DEBUG: OGR SQL: (num = 45.34) SELECT fid, dt, tm FROM bytea_fdw WHERE fid = 4; DEBUG: OGR SQL: (fid = 4) fid | dt | tm -----+------------+---------- 4 | 12-13-2089 | 01:23:45 (1 row) DELETE FROM bytea_fdw WHERE fid = 4; DEBUG: OGR SQL: (fid = 4) SELECT a.fid, a.name, b.name FROM bytea_local a JOIN bytea_fdw b USING (fid); fid | name | name -----+--------+-------- 1 | Jim | Jim 2 | Marvin | Marvin 3 | | (3 rows) ---------------------------------------------------------------------- -- Populate local array table SET client_min_messages = NOTICE; CREATE TABLE array_local ( fid integer primary key, geom bytea, txt text[], int int2[], flt float4[], b boolean[] ); INSERT INTO array_local (fid,txt, int, flt, b) VALUES (1, ARRAY['Jim'], ARRAY[1,2,3], ARRAY[3.4,5.6,7.8], ARRAY[true,false]), (2, ARRAY['Jim',NULL,'Joe'], ARRAY[1,3,NULL,4], ARRAY[4.5,NULL,3.4], ARRAY[false,NULL]), (3, NULL, NULL, NULL, NULL); ---------------------------------------------------------------------- -- Create remote array table CREATE FOREIGN TABLE array_fdw ( fid bigint, geom bytea, txt text[], int int4[], flt float8[], b boolean[] ) SERVER pgserver OPTIONS (layer 'array_local'); SELECT fid, txt, int, flt, b FROM array_fdw; fid | txt | int | flt | b -----+--------------+-----------+---------------+------- 1 | {Jim} | {1,2,3} | {3.4,5.6,7.8} | {t,f} 2 | {Jim,"",Joe} | {1,3,0,4} | {4.5,0,3.4} | {f,f} 3 | | | | (3 rows) ---------------------------------------------------------------------- -- Update remote array table UPDATE array_fdw SET txt = ARRAY['newJim', 'newJoe'], int = ARRAY[-2, -1, 0, 1, 2], flt = ARRAY[-0.1, 0.0, 0.1] WHERE fid = 3; SELECT txt, int, flt FROM array_fdw WHERE fid = 3; txt | int | flt -----------------+---------------+-------------- {newJim,newJoe} | {-2,-1,0,1,2} | {-0.1,0,0.1} (1 row) pgsql-ogr-fdw-1.1.9/output/postgis.source000066400000000000000000000106471522375352200205030ustar00rootroot00000000000000CREATE EXTENSION postgis; CREATE TABLE geometry_local ( fid serial primary key, geom geometry(Point, 4326), name varchar, age bigint, size integer, value float8, num numeric(6,2), dt date, tm time, dttm timestamp, varch char(8), yn char ); ---------------------------------------------------------------------- -- Populate local table INSERT INTO geometry_local (name, geom, age, size, value, num, dt, tm, dttm, varch, yn) VALUES ('Jim', 'SRID=4326;POINT(0 0)', 23, 1, 4.3, 5.5, '2010-10-10'::date, '13:23:21'::time, '2010-10-10 13:23:21'::timestamp, 'this', 'y' ); INSERT INTO geometry_local (name, geom, age, size, value, num, dt, tm, dttm, varch, yn) VALUES ('Marvin', 'SRID=4326;POINT(100 0)', 34, 2, 5.4, 10.13, '2011-11-11'::date, '15:21:45'::time, '2011-11-11 15:21:45'::timestamp, 'that', 'n' ); INSERT INTO geometry_local (name, geom, age, size, value, num, dt, tm, dttm, varch, yn) VALUES (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); ---------------------------------------------------------------------- -- Create remote table CREATE SERVER pgservergeom FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource 'PG:dbname=contrib_regression host=localhost', format 'PostgreSQL' ); CREATE FOREIGN TABLE geometry_fdw ( fid integer, geom geometry(point, 4326), name varchar, age bigint, size integer, value float8, num numeric(6,2), dt date, tm time, dttm timestamp, varch char(8), yn char ) SERVER pgservergeom OPTIONS (layer 'geometry_local'); SELECT fid, name, geom, age, size, value, num, dt, tm, dttm, varch, yn FROM geometry_fdw; fid | name | geom | age | size | value | num | dt | tm | dttm | varch | yn -----+--------+----------------------------------------------------+-----+------+-------+-------+------------+----------+--------------------------+----------+---- 1 | Jim | 0101000020E610000000000000000000000000000000000000 | 23 | 1 | 4.3 | 5.50 | 10-10-2010 | 13:23:21 | Sun Oct 10 13:23:21 2010 | this | y 2 | Marvin | 0101000020E610000000000000000059400000000000000000 | 34 | 2 | 5.4 | 10.13 | 11-11-2011 | 15:21:45 | Fri Nov 11 15:21:45 2011 | that | n 3 | | | | | | | | | | | (3 rows) SELECT a.name, b.name FROM geometry_local a JOIN geometry_fdw b USING (fid); name | name --------+-------- Jim | Jim Marvin | Marvin | (3 rows) EXPLAIN VERBOSE SELECT fid, name, geom, age, size, value, num, dt, tm, dttm, varch, yn FROM geometry_fdw; QUERY PLAN -------------------------------------------------------------------------------- Foreign Scan on public.geometry_fdw (cost=25.00..1025.00 rows=1000 width=166) Output: fid, name, geom, age, size, value, num, dt, tm, dttm, varch, yn (2 rows) ---------------------------------------------------------------------- -- Remote Query and OGR SQL pushdown SET client_min_messages = DEBUG1; SELECT name, age, ST_AsText(geom) FROM geometry_fdw WHERE name = 'Jim' AND age <= 30 AND geom && ST_MakeEnvelope(-1, -1, 1, 1, 4326); DEBUG: OGR SQL: (age <= 30) AND (name = 'Jim') DEBUG: OGR spatial filter (-1 -1, 1 1) name | age | st_astext ------+-----+------------ Jim | 23 | POINT(0 0) (1 row) SELECT name, ST_AsText(geom) FROM geometry_fdw WHERE ST_Intersects(geom, ST_MakeEnvelope(-1, -1, 1, 1, 4326)); DEBUG: OGR spatial filter (-1 -1, 1 1) name | st_astext ------+------------ Jim | POINT(0 0) (1 row) SELECT name, ST_AsText(geom) FROM geometry_fdw WHERE geom && ST_MakeEnvelope(-180, -90, 180, 90, 4326); DEBUG: OGR spatial filter (-180 -90, 180 90) name | st_astext --------+-------------- Jim | POINT(0 0) Marvin | POINT(100 0) (2 rows) SELECT name, ST_AsText(geom) FROM geometry_fdw WHERE ST_MakeEnvelope(-180, -90, 180, 90, 4326) && geom; DEBUG: OGR spatial filter (-180 -90, 180 90) name | st_astext --------+-------------- Jim | POINT(0 0) Marvin | POINT(100 0) (2 rows) SELECT name, ST_AsText(geom) FROM geometry_fdw WHERE ST_MakeEnvelope(-180, -90, 180, 90, 4326) && ST_MakeEnvelope(-180, -90, 180, 90, 4326); name | st_astext --------+-------------- Jim | POINT(0 0) Marvin | POINT(100 0) | (3 rows) pgsql-ogr-fdw-1.1.9/sql/000077500000000000000000000000001522375352200150205ustar00rootroot00000000000000pgsql-ogr-fdw-1.1.9/sql/.gitignore000066400000000000000000000001071522375352200170060ustar00rootroot00000000000000# Ignore everything in this directory * # Except this file !.gitignore pgsql-ogr-fdw-1.1.9/stringbuffer.c000066400000000000000000000173421522375352200170740ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * stringbuffer.c * simple stringbuffer * * Copyright (c) 2009, Paul Ramsey * Copyright (c) 2002 Thamer Alharbash * *------------------------------------------------------------------------- */ #include "stringbuffer.h" #pragma GCC diagnostic push #ifndef __clang__ #pragma GCC diagnostic ignored "-Wsuggest-attribute=format" #endif /** * Allocate a new stringbuffer_t. Use stringbuffer_destroy to free. */ stringbuffer_t* stringbuffer_create(void) { return stringbuffer_create_with_size(STRINGBUFFER_STARTSIZE); } static void stringbuffer_init_with_size(stringbuffer_t* s, size_t size) { s->str_start = malloc(size); s->str_end = s->str_start; s->capacity = size; memset(s->str_start, 0, size); } void stringbuffer_release(stringbuffer_t* s) { if (s->str_start) { free(s->str_start); } } void stringbuffer_init(stringbuffer_t* s) { stringbuffer_init_with_size(s, STRINGBUFFER_STARTSIZE); } /** * Allocate a new stringbuffer_t. Use stringbuffer_destroy to free. */ stringbuffer_t* stringbuffer_create_with_size(size_t size) { stringbuffer_t* s; s = malloc(sizeof(stringbuffer_t)); stringbuffer_init_with_size(s, size); return s; } /** * Free the stringbuffer_t and all memory managed within it. */ void stringbuffer_destroy(stringbuffer_t* s) { stringbuffer_release(s); if (s) { free(s); } } /** * Reset the stringbuffer_t. Useful for starting a fresh string * without the expense of freeing and re-allocating a new * stringbuffer_t. */ void stringbuffer_clear(stringbuffer_t* s) { s->str_start[0] = '\0'; s->str_end = s->str_start; } /** * If necessary, expand the stringbuffer_t internal buffer to accomodate the * specified additional size. */ static inline void stringbuffer_makeroom(stringbuffer_t* s, size_t size_to_add) { size_t current_size = (s->str_end - s->str_start); size_t capacity = s->capacity; size_t required_size = current_size + size_to_add; while (capacity < required_size) { capacity *= 2; } if (capacity > s->capacity) { s->str_start = realloc(s->str_start, capacity); s->capacity = capacity; s->str_end = s->str_start + current_size; } } /** * Return the last character in the buffer. */ char stringbuffer_lastchar(stringbuffer_t* s) { if (s->str_end == s->str_start) { return 0; } return * (s->str_end - 1); } /** * Append the specified string to the stringbuffer_t. */ void stringbuffer_append(stringbuffer_t* s, const char* a) { int alen = strlen(a); /* Length of string to append */ int alen0 = alen + 1; /* Length including null terminator */ stringbuffer_makeroom(s, alen0); memcpy(s->str_end, a, alen0); s->str_end += alen; } /** * Append the specified character to the stringbuffer_t. */ void stringbuffer_append_char(stringbuffer_t* s, char c) { stringbuffer_makeroom(s, 2); /* space for char + null terminator */ * (s->str_end) = c; /* add char */ s->str_end += 1; * (s->str_end) = 0; /* null terminate */ } /** * Returns a reference to the internal string being managed by * the stringbuffer. The current string will be null-terminated * within the internal string. */ const char* stringbuffer_getstring(stringbuffer_t* s) { return s->str_start; } /** * Returns a newly allocated string large enough to contain the * current state of the string. Caller is responsible for * freeing the return value. */ char* stringbuffer_getstringcopy(stringbuffer_t* s) { size_t size = (s->str_end - s->str_start) + 1; char* str = malloc(size); memcpy(str, s->str_start, size); str[size - 1] = '\0'; return str; } /** * Returns the length of the current string, not including the * null terminator (same behavior as strlen()). */ int stringbuffer_getlength(stringbuffer_t* s) { return (s->str_end - s->str_start); } /** * Clear the stringbuffer_t and re-start it with the specified string. */ void stringbuffer_set(stringbuffer_t* s, const char* str) { stringbuffer_clear(s); stringbuffer_append(s, str); } /** * Copy the contents of src into dst. */ void stringbuffer_copy(stringbuffer_t* dst, stringbuffer_t* src) { stringbuffer_set(dst, stringbuffer_getstring(src)); } /** * Appends a formatted string to the current string buffer, * using the format and argument list provided. Returns -1 on error, * check errno for reasons, documented in the printf man page. */ static int stringbuffer_avprintf(stringbuffer_t* s, const char* fmt, va_list ap) { int maxlen = (s->capacity - (s->str_end - s->str_start)); int len = 0; /* Length of the output */ va_list ap2; /* Make a copy of the variadic arguments, in case we need to print twice */ /* Print to our buffer */ va_copy(ap2, ap); len = vsnprintf(s->str_end, maxlen, fmt, ap2); va_end(ap2); /* Propogate errors up */ if (len < 0) #if defined(__MINGW64_VERSION_MAJOR) len = _vscprintf(fmt, ap2); /**Assume windows flaky vsnprintf that returns -1 if initial buffer to small and add more space **/ #else return len; #endif /* We didn't have enough space! */ /* Either Unix vsnprint returned write length larger than our buffer */ /* or Windows vsnprintf returned an error code. */ if (len >= maxlen) { stringbuffer_makeroom(s, len + 1); maxlen = (s->capacity - (s->str_end - s->str_start)); /* Try to print a second time */ len = vsnprintf(s->str_end, maxlen, fmt, ap); /* Printing error? Error! */ if (len < 0) { return len; } /* Too long still? Error! */ if (len >= maxlen) { return -1; } } /* Move end pointer forward and return. */ s->str_end += len; return len; } /** * Appends a formatted string to the current string buffer, * using the format and argument list provided. * Returns -1 on error, check errno for reasons, * as documented in the printf man page. */ int stringbuffer_aprintf(stringbuffer_t* s, const char* fmt, ...) { int r; va_list ap; va_start(ap, fmt); r = stringbuffer_avprintf(s, fmt, ap); va_end(ap); return r; } /** * Trims whitespace off the end of the stringbuffer. Returns * the number of characters trimmed. */ int stringbuffer_trim_trailing_white(stringbuffer_t* s) { char* ptr = s->str_end; int dist = 0; /* Roll backwards until we hit a non-space. */ while (ptr > s->str_start) { ptr--; if ((*ptr == ' ') || (*ptr == '\t')) { continue; } else { ptr++; dist = s->str_end - ptr; *ptr = '\0'; s->str_end = ptr; return dist; } } return dist; } /** * Trims zeroes off the end of the last number in the stringbuffer. * The number has to be the very last thing in the buffer. Only the * last number will be trimmed. Returns the number of characters * trimmed. * * eg: 1.22000 -> 1.22 * 1.0 -> 1 * 0.0 -> 0 */ int stringbuffer_trim_trailing_zeroes(stringbuffer_t* s) { char* ptr = s->str_end; char* decimal_ptr = NULL; int dist; if (s->str_end - s->str_start < 2) { return 0; } /* Roll backwards to find the decimal for this number */ while (ptr > s->str_start) { ptr--; if (*ptr == '.') { decimal_ptr = ptr; break; } if ((*ptr >= '0') && (*ptr <= '9')) { continue; } else { break; } } /* No decimal? Nothing to trim! */ if (! decimal_ptr) { return 0; } ptr = s->str_end; /* Roll backwards again, with the decimal as stop point, trimming contiguous zeroes */ while (ptr >= decimal_ptr) { ptr--; if (*ptr == '0') { continue; } else { break; } } /* Huh, we get anywhere. Must not have trimmed anything. */ if (ptr == s->str_end) { return 0; } /* If we stopped at the decimal, we want to null that out. It we stopped on a numeral, we want to preserve that, so push the pointer forward one space. */ if (*ptr != '.') { ptr++; } /* Add null terminator re-set the end of the stringbuffer. */ *ptr = '\0'; dist = s->str_end - ptr; s->str_end = ptr; return dist; } pgsql-ogr-fdw-1.1.9/stringbuffer.h000066400000000000000000000030161522375352200170720ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * stringbuffer.h * simple stringbuffer * * Copyright (c) 2009, Paul Ramsey * Copyright (c) 2002 Thamer Alharbash * *------------------------------------------------------------------------- */ #pragma once #include #include #include #include #define STRINGBUFFER_STARTSIZE 128 typedef struct { size_t capacity; char *str_end; char *str_start; } stringbuffer_t; extern stringbuffer_t *stringbuffer_create_with_size(size_t size); extern stringbuffer_t *stringbuffer_create(void); extern void stringbuffer_init(stringbuffer_t *s); extern void stringbuffer_release(stringbuffer_t *s); extern void stringbuffer_destroy(stringbuffer_t *sb); extern void stringbuffer_clear(stringbuffer_t *sb); void stringbuffer_set(stringbuffer_t *sb, const char *s); void stringbuffer_copy(stringbuffer_t *sb, stringbuffer_t *src); extern void stringbuffer_append(stringbuffer_t *sb, const char *s); extern void stringbuffer_append_char(stringbuffer_t *s, char c); extern int stringbuffer_aprintf(stringbuffer_t *sb, const char *fmt, ...); extern const char *stringbuffer_getstring(stringbuffer_t *sb); extern char *stringbuffer_getstringcopy(stringbuffer_t *sb); extern int stringbuffer_getlength(stringbuffer_t *sb); extern char stringbuffer_lastchar(stringbuffer_t *s); extern int stringbuffer_trim_trailing_white(stringbuffer_t *s); extern int stringbuffer_trim_trailing_zeroes(stringbuffer_t *s); pgsql-ogr-fdw-1.1.9/stringbuffer_pg.c000066400000000000000000000016431522375352200175570ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * stringbuffer.c * simple stringbuffer * * Copyright (c) 2009, Paul Ramsey * Copyright (c) 2002 Thamer Alharbash * *------------------------------------------------------------------------- */ /* * We need a version of stringbuffer that uses palloc/pfree/repalloc * for use inside PgSQL. (We are sharing code in ogr_fdw_common.c * between the commandline utility and the backend module, so we * cannot just depend on the PgSQL standard string handling utility) * We rebuild it here, but with the pgsql memory stuff in place * of the standard system calls */ #include "stringbuffer.h" void * palloc(size_t sz); void pfree(void *ptr); void * repalloc(void *ptr, size_t sz); #define malloc(sz) palloc(sz) #define free(ptr) pfree(ptr) #define realloc(ptr,sz) repalloc(ptr,sz) #include "stringbuffer.c"