public inbox for [email protected]help / color / mirror / Atom feed
[pgAdmin][RM5181] Add support for parameters toast_tuple_target and parallel_workers of table 7+ messages / 2 participants [nested] [flat]
* [pgAdmin][RM5181] Add support for parameters toast_tuple_target and parallel_workers of table @ 2020-03-30 14:17 Aditya Toshniwal <[email protected]> 0 siblings, 1 reply; 7+ messages in thread From: Aditya Toshniwal @ 2020-03-30 14:17 UTC (permalink / raw) To: pgadmin-hackers Hi Hackers, Attached is a patch to add support for parameters toast_tuple_target (PG v11+) and parallel_workers(PG 9.6+) of table. Refer - https://www.postgresql.org/docs/11/sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS . Both the parameters are added in the advanced tab of table dialog. The patch also fixes a related issue - RM5180, where autovacuum_enabled parameter is added automatically in the RE-SQL when table has been created with WITH parameter. Please review. -- Thanks and Regards, Aditya Toshniwal pgAdmin Hacker | Sr. Software Engineer | EnterpriseDB India | Pune "Don't Complain about Heat, Plant a TREE" Attachments: [application/octet-stream] RM5181_5180.patch (62.9K, 3-RM5181_5180.patch) download | inline diff: diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js index 61761794f..f1dd27dc5 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js @@ -291,6 +291,8 @@ define('pgadmin.node.table', [ triggercount: undefined, relpersistence: undefined, fillfactor: undefined, + toast_tuple_target: undefined, + parallel_workers: undefined, reloftype: undefined, typname: undefined, labels: undefined, @@ -779,6 +781,26 @@ define('pgadmin.node.table', [ return m.inSchema(); }, },{ + id: 'toast_tuple_target', label: gettext('Toast tuple target'), type: 'int', + mode: ['create', 'edit'], min: 128, min_version: 110000, + group: gettext('advanced'), + disabled: function(m) { + if(m.get('is_partitioned')) { + return true; + } + return m.inSchema(); + }, + },{ + id: 'parallel_workers', label: gettext('Parallel workers'), type: 'int', + mode: ['create', 'edit'], group: gettext('advanced'), min_version: 90600, + disabled: function(m) { + if(m.get('is_partitioned')) { + return true; + } + return m.inSchema(); + }, + }, + { id: 'relhasoids', label: gettext('Has OIDs?'), cell: 'switch', type: 'switch', mode: ['properties', 'create', 'edit'], group: gettext('advanced'), diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/create.sql index 478e6d752..dafc87aa2 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/create.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/create.sql @@ -77,7 +77,8 @@ CACHE {{c.seqcache|int}} {% endif %} {% endif %} WITH ( OIDS = {% if data.relhasoids %}TRUE{% else %}FALSE{% endif %}{% if data.fillfactor %}, - FILLFACTOR = {{ data.fillfactor }}{% endif %}{% if data.autovacuum_custom %}, + FILLFACTOR = {{ data.fillfactor }}{% endif %}{% if data.parallel_workers is defined and data.parallel_workers != '' and data.parallel_workers != None %}, + parallel_workers = {{ data.parallel_workers }}{% endif %}{% if data.autovacuum_custom %}, autovacuum_enabled = {% if data.autovacuum_enabled %}TRUE{% else %}FALSE{% endif %}{% endif %}{% if data.toast_autovacuum %}, toast.autovacuum_enabled = {% if data.toast_autovacuum_enabled %}TRUE{% else %}FALSE{% endif %} {% endif %}{% if data.autovacuum_enabled and data.vacuum_table|length > 0 %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/properties.sql index e9bb22827..3d31fe60e 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/properties.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/properties.sql @@ -27,6 +27,7 @@ SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS r WHERE i.inhrelid = rel.oid) AS inherited_tables_cnt, (CASE WHEN rel.relpersistence = 'u' THEN true ELSE false END) AS relpersistence, substring(array_to_string(rel.reloptions, ',') FROM 'fillfactor=([0-9]*)') AS fillfactor, + substring(array_to_string(rel.reloptions, ',') FROM 'parallel_workers=([0-9]*)') AS parallel_workers, (CASE WHEN (substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') = 'true') THEN true ELSE false END) AS autovacuum_enabled, substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold, @@ -56,7 +57,7 @@ SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS r typ.typrelid AS typoid, (CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable, -- Added for pgAdmin4 - (CASE WHEN array_length(rel.reloptions, 1) > 0 THEN true ELSE false END) AS autovacuum_custom, + (array_to_string(rel.reloptions, ',') like '%autovacuum%') AS autovacuum_custom, (CASE WHEN array_length(tst.reloptions, 1) > 0 AND rel.reltoastrelid != 0 THEN true ELSE false END) AS toast_autovacuum, (SELECT array_agg(provider || '=' || label) FROM pg_seclabels sl1 WHERE sl1.objoid=rel.oid AND sl1.objsubid=0) AS seclabels, diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/create.sql new file mode 100644 index 000000000..caec8f520 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/create.sql @@ -0,0 +1,187 @@ +{% import 'macros/schemas/security.macros' as SECLABEL %} +{% import 'macros/schemas/privilege.macros' as PRIVILEGE %} +{% import 'macros/variable.macros' as VARIABLE %} +{% import 'columns/macros/security.macros' as COLUMN_SECLABEL %} +{% import 'columns/macros/privilege.macros' as COLUMN_PRIVILEGE %} +{% import 'tables/sql/macros/constraints.macro' as CONSTRAINTS %} +{% import 'types/macros/get_full_type_sql_format.macros' as GET_TYPE %} +{#===========================================#} +{#====== MAIN TABLE TEMPLATE STARTS HERE ======#} +{#===========================================#} +{# + If user has not provided any details but only name then + add empty bracket with table name +#} +{% set empty_bracket = ""%} +{% if data.coll_inherits|length == 0 and data.columns|length == 0 and not data.typname and not data.like_relation and data.primary_key|length == 0 and data.unique_constraint|length == 0 and data.foreign_key|length == 0 and data.check_constraint|length == 0 and data.exclude_constraint|length == 0 %} +{% set empty_bracket = "\n(\n)"%} +{% endif %} +CREATE {% if data.relpersistence %}UNLOGGED {% endif %}TABLE {{conn|qtIdent(data.schema, data.name)}}{{empty_bracket}} +{% if data.typname %} + OF {{ data.typname }} +{% endif %} +{% if data.like_relation or data.coll_inherits or data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 or data.exclude_constraint|length > 0 %} +( +{% endif %} +{% if data.like_relation %} + LIKE {{ data.like_relation }}{% if data.like_default_value %} + + INCLUDING DEFAULTS{% endif %}{% if data.like_constraints %} + + INCLUDING CONSTRAINTS{% endif %}{% if data.like_indexes %} + + INCLUDING INDEXES{% endif %}{% if data.like_storage %} + + INCLUDING STORAGE{% endif %}{% if data.like_comments %} + + INCLUDING COMMENTS{% endif %}{% if data.columns|length > 0 %}, +{% endif %} + +{% endif %} +{### Add columns ###} +{% if data.columns and data.columns|length > 0 %} +{% for c in data.columns %} +{% if c.name and c.cltype %} + {% if c.inheritedfromtable %}-- Inherited from table {{c.inheritedfromtable}}: {% elif c.inheritedfromtype %}-- Inherited from type {{c.inheritedfromtype}}: {% endif %}{{conn|qtIdent(c.name)}} {% if is_sql %}{{c.displaytypname}}{% else %}{{ GET_TYPE.CREATE_TYPE_SQL(conn, c.cltype, c.attlen, c.attprecision, c.hasSqrBracket) }}{% endif %}{% if c.collspcname %} COLLATE {{c.collspcname}}{% endif %}{% if c.attnotnull %} NOT NULL{% endif %}{% if c.defval is defined and c.defval is not none and c.defval != '' %} DEFAULT {{c.defval}}{% endif %} +{% if c.colconstype == 'i' and c.attidentity and c.attidentity != '' %} +{% if c.attidentity == 'a' %} GENERATED ALWAYS AS IDENTITY{% elif c.attidentity == 'd' %} GENERATED BY DEFAULT AS IDENTITY{% endif %} +{% if c.seqincrement or c.seqcycle or c.seqincrement or c.seqstart or c.seqmin or c.seqmax or c.seqcache %} ( {% endif %} +{% if c.seqcycle is defined and c.seqcycle %} +CYCLE {% endif %}{% if c.seqincrement is defined and c.seqincrement|int(-1) > -1 %} +INCREMENT {{c.seqincrement|int}} {% endif %}{% if c.seqstart is defined and c.seqstart|int(-1) > -1%} +START {{c.seqstart|int}} {% endif %}{% if c.seqmin is defined and c.seqmin|int(-1) > -1%} +MINVALUE {{c.seqmin|int}} {% endif %}{% if c.seqmax is defined and c.seqmax|int(-1) > -1%} +MAXVALUE {{c.seqmax|int}} {% endif %}{% if c.seqcache is defined and c.seqcache|int(-1) > -1%} +CACHE {{c.seqcache|int}} {% endif %} +{% if c.seqincrement or c.seqcycle or c.seqincrement or c.seqstart or c.seqmin or c.seqmax or c.seqcache %}){% endif %} +{% endif %} +{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} +{% endif %} +{# Macro to render for constraints #} +{% if data.primary_key|length > 0 %}{% if data.columns|length > 0 %},{% endif %} +{{CONSTRAINTS.PRIMARY_KEY(conn, data.primary_key[0])}}{% endif %}{% if data.unique_constraint|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 %},{% endif %} +{{CONSTRAINTS.UNIQUE(conn, data.unique_constraint)}}{% endif %}{% if data.foreign_key|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 %},{% endif %} +{{CONSTRAINTS.FOREIGN_KEY(conn, data.foreign_key)}}{% endif %}{% if data.check_constraint|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 %},{% endif %} +{{CONSTRAINTS.CHECK(conn, data.check_constraint)}}{% endif %}{% if data.exclude_constraint|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 %},{% endif %} +{{CONSTRAINTS.EXCLUDE(conn, data.exclude_constraint)}}{% endif %} +{% if data.like_relation or data.coll_inherits or data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 or data.exclude_constraint|length > 0 %} + +){% endif %}{% if data.relkind is defined and data.relkind == 'p' %} PARTITION BY {{ data.partition_scheme }} {% endif %} + +{### If we are inheriting it from another table(s) ###} +{% if data.coll_inherits %} + INHERITS ({% for val in data.coll_inherits %}{% if loop.index != 1 %}, {% endif %}{{val}}{% endfor %}) +{% endif %} +WITH ( + OIDS = {% if data.relhasoids %}TRUE{% else %}FALSE{% endif %}{% if data.fillfactor %}, + FILLFACTOR = {{ data.fillfactor }}{% endif %}{% if data.parallel_workers is defined and data.parallel_workers != '' and data.parallel_workers != None %}, + parallel_workers = {{ data.parallel_workers }}{% endif %}{% if data.toast_tuple_target is defined and data.toast_tuple_target != '' and data.toast_tuple_target != None %}, + toast_tuple_target = {{ data.toast_tuple_target }}{% endif %}{% if data.autovacuum_custom %}, + autovacuum_enabled = {% if data.autovacuum_enabled %}TRUE{% else %}FALSE{% endif %}{% endif %}{% if data.toast_autovacuum %}, + toast.autovacuum_enabled = {% if data.toast_autovacuum_enabled %}TRUE{% else %}FALSE{% endif %} +{% endif %}{% if data.autovacuum_enabled and data.vacuum_table|length > 0 %} +{% for opt in data.vacuum_table %}{% if opt.name and opt.value %} +, + {{opt.name}} = {{opt.value}}{% endif %} +{% endfor %}{% endif %}{% if data.toast_autovacuum_enabled and data.vacuum_toast|length > 0 %} +{% for opt in data.vacuum_toast %}{% if opt.name and opt.value %} +, + toast.{{opt.name}} = {{opt.value}}{% endif %} +{% endfor %}{% endif %} + +{### SQL for Tablespace ###} +{% if data.spcname %} +) +TABLESPACE {{ conn|qtIdent(data.spcname) }}; +{% else %} +); +{% endif %} +{### Alter SQL for Owner ###} +{% if data.relowner %} + +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + OWNER to {{conn|qtIdent(data.relowner)}}; +{% endif %} +{### Security Labels on Table ###} +{% if data.seclabels and data.seclabels|length > 0 %} + +{% for r in data.seclabels %} +{{ SECLABEL.SET(conn, 'TABLE', data.name, r.provider, r.label, data.schema) }} +{% endfor %} +{% endif %} +{### ACL on Table ###} +{% if data.relacl %} + +{% for priv in data.relacl %} +{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }} +{% endfor %} +{% endif %} +{### SQL for COMMENT ###} +{% if data.description %} +COMMENT ON TABLE {{conn|qtIdent(data.schema, data.name)}} + IS {{data.description|qtLiteral}}; +{% endif %} +{#===========================================#} +{#====== MAIN TABLE TEMPLATE ENDS HERE ======#} +{#===========================================#} +{#===========================================#} +{# COLUMN SPECIFIC TEMPLATES STARTS HERE #} +{#===========================================#} +{% if data.columns and data.columns|length > 0 %} +{% for c in data.columns %} +{% if c.description %} + +COMMENT ON COLUMN {{conn|qtIdent(data.schema, data.name, c.name)}} + IS {{c.description|qtLiteral}}; +{% endif %} +{### Add variables to column ###} +{% if c.attoptions and c.attoptions|length > 0 %} + +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + {{ VARIABLE.SET(conn, 'COLUMN', c.name, c.attoptions) }} + +{% endif %} +{### Alter column statistics value ###} +{% if c.attstattarget is defined and c.attstattarget > -1 %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + ALTER COLUMN {{conn|qtTypeIdent(c.name)}} SET STATISTICS {{c.attstattarget}}; + +{% endif %} +{### Alter column storage value ###} +{% if c.attstorage is defined and c.attstorage != c.defaultstorage %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + ALTER COLUMN {{conn|qtTypeIdent(c.name)}} SET STORAGE {%if c.attstorage == 'p' %} +PLAIN{% elif c.attstorage == 'm'%}MAIN{% elif c.attstorage == 'e'%} +EXTERNAL{% elif c.attstorage == 'x'%}EXTENDED{% endif %}; + +{% endif %} +{### ACL ###} +{% if c.attacl and c.attacl|length > 0 %} + +{% for priv in c.attacl %} +{{ COLUMN_PRIVILEGE.APPLY(conn, data.schema, data.name, c.name, priv.grantee, priv.without_grant, priv.with_grant) }} +{% endfor %} +{% endif %} +{### Security Lables ###} +{% if c.seclabels and c.seclabels|length > 0 %} + +{% for r in c.seclabels %} +{{ COLUMN_SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.name, c.name, r.provider, r.label) }} +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} +{#===========================================#} +{# COLUMN SPECIFIC TEMPLATES ENDS HERE #} +{#===========================================#} +{#======================================#} +{# CONSTRAINTS SPECIFIC TEMPLATES #} +{#======================================#} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.primary_key)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.unique_constraint)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.foreign_key)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.check_constraint)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.exclude_constraint)}} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/properties.sql new file mode 100644 index 000000000..3ac7ceae8 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/properties.sql @@ -0,0 +1,77 @@ +SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS relacl_str, + (CASE WHEN length(spc.spcname) > 0 THEN spc.spcname ELSE + (SELECT sp.spcname FROM pg_database dtb + JOIN pg_tablespace sp ON dtb.dattablespace=sp.oid + WHERE dtb.oid = {{ did }}::oid) + END) as spcname, + (select nspname FROM pg_namespace WHERE oid = {{scid}}::oid ) as schema, + pg_get_userbyid(rel.relowner) AS relowner, rel.relhasoids, rel.relkind, + (CASE WHEN rel.relkind = 'p' THEN true ELSE false END) AS is_partitioned, + rel.relhassubclass, rel.reltuples::bigint, des.description, con.conname, con.conkey, + EXISTS(select 1 FROM pg_trigger + JOIN pg_proc pt ON pt.oid=tgfoid AND pt.proname='logtrigger' + JOIN pg_proc pc ON pc.pronamespace=pt.pronamespace AND pc.proname='slonyversion' + WHERE tgrelid=rel.oid) AS isrepl, + (SELECT count(*) FROM pg_trigger WHERE tgrelid=rel.oid AND tgisinternal = FALSE) AS triggercount, + (SELECT ARRAY(SELECT CASE WHEN (nspname NOT LIKE 'pg\_%') THEN + quote_ident(nspname)||'.'||quote_ident(c.relname) + ELSE quote_ident(c.relname) END AS inherited_tables + FROM pg_inherits i + JOIN pg_class c ON c.oid = i.inhparent + JOIN pg_namespace n ON n.oid=c.relnamespace + WHERE i.inhrelid = rel.oid ORDER BY inhseqno)) AS coll_inherits, + (SELECT count(*) + FROM pg_inherits i + JOIN pg_class c ON c.oid = i.inhparent + JOIN pg_namespace n ON n.oid=c.relnamespace + WHERE i.inhrelid = rel.oid) AS inherited_tables_cnt, + (CASE WHEN rel.relpersistence = 'u' THEN true ELSE false END) AS relpersistence, + substring(array_to_string(rel.reloptions, ',') FROM 'fillfactor=([0-9]*)') AS fillfactor, + substring(array_to_string(rel.reloptions, ',') FROM 'parallel_workers=([0-9]*)') AS parallel_workers, + substring(array_to_string(rel.reloptions, ',') FROM 'toast_tuple_target=([0-9]*)') AS toast_tuple_target, + (CASE WHEN (substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') = 'true') + THEN true ELSE false END) AS autovacuum_enabled, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.]?[0-9]*)') AS autovacuum_vacuum_scale_factor, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS autovacuum_analyze_threshold, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.]?[0-9]*)') AS autovacuum_analyze_scale_factor, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS autovacuum_vacuum_cost_delay, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS autovacuum_vacuum_cost_limit, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS autovacuum_freeze_min_age, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS autovacuum_freeze_max_age, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS autovacuum_freeze_table_age, + (CASE WHEN (substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') = 'true') + THEN true ELSE false END) AS toast_autovacuum_enabled, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS toast_autovacuum_vacuum_threshold, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.]?[0-9]*)') AS toast_autovacuum_vacuum_scale_factor, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS toast_autovacuum_analyze_threshold, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.]?[0-9]*)') AS toast_autovacuum_analyze_scale_factor, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS toast_autovacuum_vacuum_cost_delay, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS toast_autovacuum_vacuum_cost_limit, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS toast_autovacuum_freeze_min_age, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS toast_autovacuum_freeze_max_age, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS toast_autovacuum_freeze_table_age, + array_to_string(rel.reloptions, ',') AS table_vacuum_settings_str, + array_to_string(tst.reloptions, ',') AS toast_table_vacuum_settings_str, + rel.reloptions AS reloptions, tst.reloptions AS toast_reloptions, rel.reloftype, + CASE WHEN typ.typname IS NOT NULL THEN (select quote_ident(nspname) FROM pg_namespace WHERE oid = {{scid}}::oid )||'.'||quote_ident(typ.typname) ELSE typ.typname END AS typname, + typ.typrelid AS typoid, + (CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable, + -- Added for pgAdmin4 + (array_to_string(rel.reloptions, ',') like '%autovacuum%') AS autovacuum_custom, + (CASE WHEN array_length(tst.reloptions, 1) > 0 AND rel.reltoastrelid != 0 THEN true ELSE false END) AS toast_autovacuum, + + (SELECT array_agg(provider || '=' || label) FROM pg_seclabels sl1 WHERE sl1.objoid=rel.oid AND sl1.objsubid=0) AS seclabels, + (CASE WHEN rel.oid <= {{ datlastsysoid}}::oid THEN true ElSE false END) AS is_sys_table + -- Added for partition table + {% if tid %}, (CASE WHEN rel.relkind = 'p' THEN pg_get_partkeydef({{ tid }}::oid) ELSE '' END) AS partition_scheme {% endif %} +FROM pg_class rel + LEFT OUTER JOIN pg_tablespace spc on spc.oid=rel.reltablespace + LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0 AND des.classoid='pg_class'::regclass) + LEFT OUTER JOIN pg_constraint con ON con.conrelid=rel.oid AND con.contype='p' + LEFT OUTER JOIN pg_class tst ON tst.oid = rel.reltoastrelid + LEFT JOIN pg_type typ ON rel.reloftype=typ.oid +WHERE rel.relkind IN ('r','s','t','p') AND rel.relnamespace = {{ scid }}::oid +AND NOT rel.relispartition +{% if tid %} AND rel.oid = {{ tid }}::oid {% endif %} +ORDER BY rel.relname; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/update.sql new file mode 100644 index 000000000..0f27dbed2 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/update.sql @@ -0,0 +1,245 @@ +{% import 'macros/schemas/security.macros' as SECLABEL %} +{% import 'macros/schemas/privilege.macros' as PRIVILEGE %} +{% import 'macros/variable.macros' as VARIABLE %} +{#####################################################} +{## Rename table ##} +{#####################################################} +{% if data.name and data.name != o_data.name %} +ALTER TABLE {{conn|qtIdent(o_data.schema, o_data.name)}} + RENAME TO {{conn|qtIdent(data.name)}}; + +{% endif %} +{#####################################################} +{## Change table schema ##} +{#####################################################} +{% if data.schema and data.schema != o_data.schema %} +ALTER TABLE {{conn|qtIdent(o_data.schema, data.name)}} + SET SCHEMA {{conn|qtIdent(data.schema)}}; + +{% endif %} +{#####################################################} +{## Change table owner ##} +{#####################################################} +{% if data.relowner and data.relowner != o_data.relowner %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + OWNER TO {{conn|qtIdent(data.relowner)}}; + +{% endif %} +{#####################################################} +{## Update Inherits table definition ##} +{#####################################################} +{% if data.coll_inherits_added|length > 0 %} +{% for val in data.coll_inherits_added %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + INHERIT {{val}}; + +{% endfor %} +{% endif %} +{% if data.coll_inherits_removed|length > 0 %} +{% for val in data.coll_inherits_removed %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + NO INHERIT {{val}}; + +{% endfor %} +{% endif %} +{#####################################################} +{## Change hasOID attribute of table ##} +{#####################################################} +{% if data.relhasoids is defined and data.relhasoids != o_data.relhasoids %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET {% if data.relhasoids %}WITH{% else %}WITHOUT{% endif %} OIDS; + +{% endif %} +{#####################################################} +{## Change tablespace ##} +{#####################################################} +{% if data.spcname and data.spcname != o_data.spcname %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET TABLESPACE {{conn|qtIdent(data.spcname)}}; + +{% endif %} +{#####################################################} +{## change fillfactor settings ##} +{#####################################################} +{% if data.fillfactor and data.fillfactor != o_data.fillfactor %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET (FILLFACTOR={{data.fillfactor}}); +{% elif (data.fillfactor == '' or data.fillfactor == None) and data.fillfactor != o_data.fillfactor %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + RESET (FILLFACTOR); + +{% endif %} + +{## change parallel_workers settings ##} +{#####################################################} +{% if (data.parallel_workers == '' or data.parallel_workers == None) and data.parallel_workers != o_data.parallel_workers %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + RESET (parallel_workers); +{% elif data.parallel_workers is defined and data.parallel_workers != o_data.parallel_workers %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET (parallel_workers={{data.parallel_workers}}); + +{% endif %} + +{## change toast_tuple_target settings ##} +{#####################################################} +{% if (data.toast_tuple_target == '' or data.toast_tuple_target == None) and data.toast_tuple_target != o_data.toast_tuple_target %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + RESET (toast_tuple_target); +{% elif data.toast_tuple_target is defined and data.toast_tuple_target != o_data.toast_tuple_target %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET (toast_tuple_target={{data.toast_tuple_target}}); + +{% endif %} + +{###############################} +{## Table AutoVacuum settings ##} +{###############################} +{% if data.vacuum_table is defined and data.vacuum_table.set_values|length > 0 %} +{% set has_vacuum_set = true %} +{% endif %} +{% if data.vacuum_table is defined and data.vacuum_table.reset_values|length > 0 %} +{% set has_vacuum_reset = true %} +{% endif %} +{% if o_data.autovacuum_custom and data.autovacuum_custom == false %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( + autovacuum_enabled, + autovacuum_analyze_scale_factor, + autovacuum_analyze_threshold, + autovacuum_freeze_max_age, + autovacuum_vacuum_cost_delay, + autovacuum_vacuum_cost_limit, + autovacuum_vacuum_scale_factor, + autovacuum_vacuum_threshold, + autovacuum_freeze_min_age, + autovacuum_freeze_table_age +); +{% else %} +{% if data.autovacuum_enabled is defined or has_vacuum_set %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} SET ( +{% if data.autovacuum_enabled is defined and data.autovacuum_enabled != o_data.autovacuum_enabled %} + autovacuum_enabled = {% if data.autovacuum_enabled %}true{% else %}false{% endif %}{% if has_vacuum_set %}, +{% endif %} +{% endif %} +{% if has_vacuum_set %} +{% for opt in data.vacuum_table.set_values %}{% if opt.name and opt.value %} + {{opt.name}} = {{opt.value}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} +{% endif %} + +); +{% endif %} +{% if has_vacuum_reset %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( +{% for opt in data.vacuum_table.reset_values %}{% if opt.name %} + {{opt.name}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} + +); +{% endif %} +{% endif %} +{#####################################} +{## Toast table AutoVacuum settings ##} +{#####################################} +{% if data.vacuum_toast is defined and data.vacuum_toast.set_values|length > 0 %} +{% set has_vacuum_toast_set = true %} +{% endif %} +{% if data.vacuum_toast is defined and data.vacuum_toast.reset_values|length > 0 %} +{% set has_vacuum_toast_reset = true %} +{% endif %} +{% if o_data.toast_autovacuum and data.toast_autovacuum == false %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( + toast.autovacuum_enabled, + toast.autovacuum_freeze_max_age, + toast.autovacuum_vacuum_cost_delay, + toast.autovacuum_vacuum_cost_limit, + toast.autovacuum_vacuum_scale_factor, + toast.autovacuum_vacuum_threshold, + toast.autovacuum_freeze_min_age, + toast.autovacuum_freeze_table_age, + toast.autovacuum_analyze_threshold, + toast.autovacuum_analyze_scale_factor +); +{% else %} +{% if data.toast_autovacuum_enabled is defined or has_vacuum_toast_set %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} SET ( +{% if data.toast_autovacuum_enabled is defined and data.toast_autovacuum_enabled != o_data.toast_autovacuum_enabled %} + toast.autovacuum_enabled = {% if data.toast_autovacuum_enabled %}true{% else %}false{% endif %}{% if has_vacuum_toast_set %}, +{% endif %} +{% endif %} +{% if has_vacuum_toast_set %} +{% for opt in data.vacuum_toast.set_values %}{% if opt.name and opt.value %} + toast.{{opt.name}} = {{opt.value}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} +{% endif %} + +); +{% endif %} +{% if has_vacuum_toast_reset %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( +{% for opt in data.vacuum_toast.reset_values %}{% if opt.name %} + toast.{{opt.name}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} + +); +{% endif %} +{% endif %} +{#####################################################} +{## Change table comments ##} +{#####################################################} +{% if data.description is defined and data.description != o_data.description %} +COMMENT ON TABLE {{conn|qtIdent(data.schema, data.name)}} + IS {{data.description|qtLiteral}}; + +{% endif %} +{#####################################################} +{## Update table Privileges ##} +{#####################################################} +{% if data.relacl %} +{% if 'deleted' in data.relacl %} +{% for priv in data.relacl.deleted %} +{{ PRIVILEGE.UNSETALL(conn, 'TABLE', priv.grantee, data.name, data.schema) }} +{% endfor %} +{% endif %} +{% if 'changed' in data.relacl %} +{% for priv in data.relacl.changed %} +{{ PRIVILEGE.UNSETALL(conn, 'TABLE', priv.grantee, data.name, data.schema) }} +{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }} +{% endfor %} +{% endif %} +{% if 'added' in data.relacl %} +{% for priv in data.relacl.added %} +{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }} +{% endfor %} +{% endif %} +{% endif %} +{#####################################################} +{## Update table SecurityLabel ##} +{#####################################################} +{% if data.seclabels and data.seclabels|length > 0 %} +{% set seclabels = data.seclabels %} +{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %} +{% for r in seclabels.deleted %} +{{ SECLABEL.UNSET(conn, 'TABLE', data.name, r.provider, data.schema) }} +{% endfor %} +{% endif %} +{% if 'added' in seclabels and seclabels.added|length > 0 %} +{% for r in seclabels.added %} +{{ SECLABEL.SET(conn, 'TABLE', data.name, r.provider, r.label, data.schema) }} +{% endfor %} +{% endif %} +{% if 'changed' in seclabels and seclabels.changed|length > 0 %} +{% for r in seclabels.changed %} +{{ SECLABEL.SET(conn, 'TABLE', data.name, r.provider, r.label, data.schema) }} +{% endfor %} +{% endif %} + +{% endif %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/create.sql index c52861b0c..486bc3091 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/create.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/create.sql @@ -17,7 +17,7 @@ {% set empty_bracket = "\n(\n)"%} {% endif %} {% set with_clause = false%} -{% if data.fillfactor or data.autovacuum_custom or data.autovacuum_enabled or data.toast_autovacuum or data.toast_autovacuum_enabled or (data.autovacuum_enabled and data.vacuum_table|length > 0) or (data.toast_autovacuum_enabled and data.vacuum_toast|length > 0) %} +{% if data.fillfactor or data.parallel_workers or data.toast_tuple_target or data.autovacuum_custom or data.autovacuum_enabled or data.toast_autovacuum or data.toast_autovacuum_enabled or (data.autovacuum_enabled and data.vacuum_table|length > 0) or (data.toast_autovacuum_enabled and data.vacuum_toast|length > 0) %} {% set with_clause = true%} {% endif %} CREATE {% if data.relpersistence %}UNLOGGED {% endif %}TABLE {{conn|qtIdent(data.schema, data.name)}}{{empty_bracket}} @@ -86,7 +86,13 @@ CACHE {{c.seqcache|int}} {% endif %} {% set add_comma = false%} WITH ( {% if data.fillfactor %}{% set add_comma = true%} - FILLFACTOR = {{ data.fillfactor }}{% endif %}{% if data.autovacuum_custom %} + FILLFACTOR = {{ data.fillfactor }}{% endif %}{% if data.parallel_workers %} +{% if add_comma %}, +{% endif %} + parallel_workers = {{ data.parallel_workers }}{% set add_comma = true%}{% endif %}{% if data.toast_tuple_target %} +{% if add_comma %}, +{% endif %} + toast_tuple_target = {{ data.toast_tuple_target }}{% set add_comma = true%}{% endif %}{% if data.autovacuum_custom %} {% if add_comma %}, {% endif %} autovacuum_enabled = {% if data.autovacuum_enabled %}TRUE{% else %}FALSE{% endif %}{% set add_comma = true%}{% endif %}{% if data.toast_autovacuum %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/properties.sql index e7d19055d..3d9b1f622 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/properties.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/properties.sql @@ -27,6 +27,8 @@ SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS r WHERE i.inhrelid = rel.oid) AS inherited_tables_cnt, (CASE WHEN rel.relpersistence = 'u' THEN true ELSE false END) AS relpersistence, substring(array_to_string(rel.reloptions, ',') FROM 'fillfactor=([0-9]*)') AS fillfactor, + substring(array_to_string(rel.reloptions, ',') FROM 'parallel_workers=([0-9]*)') AS parallel_workers, + substring(array_to_string(rel.reloptions, ',') FROM 'toast_tuple_target=([0-9]*)') AS toast_tuple_target, (CASE WHEN (substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') = 'true') THEN true ELSE false END) AS autovacuum_enabled, substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold, @@ -56,7 +58,7 @@ SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS r typ.typrelid AS typoid, (CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable, -- Added for pgAdmin4 - (CASE WHEN array_length(rel.reloptions, 1) > 0 THEN true ELSE false END) AS autovacuum_custom, + (array_to_string(rel.reloptions, ',') like '%autovacuum%') AS autovacuum_custom, (CASE WHEN array_length(tst.reloptions, 1) > 0 AND rel.reltoastrelid != 0 THEN true ELSE false END) AS toast_autovacuum, (SELECT array_agg(provider || '=' || label) FROM pg_seclabels sl1 WHERE sl1.objoid=rel.oid AND sl1.objsubid=0) AS seclabels, diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/update.sql index 3ed12302d..e2415ad2a 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/update.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/update.sql @@ -61,6 +61,29 @@ ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET (FILLFACTOR); {% endif %} + +{## change parallel_workers settings ##} +{#####################################################} +{% if (data.parallel_workers == '' or data.parallel_workers == None) and data.parallel_workers != o_data.parallel_workers %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + RESET (parallel_workers); +{% elif data.parallel_workers is defined and data.parallel_workers != o_data.parallel_workers %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET (parallel_workers={{data.parallel_workers}}); + +{% endif %} + +{## change toast_tuple_target settings ##} +{#####################################################} +{% if (data.toast_tuple_target == '' or data.toast_tuple_target == None) and data.toast_tuple_target != o_data.toast_tuple_target %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + RESET (toast_tuple_target); +{% elif data.toast_tuple_target is defined and data.toast_tuple_target != o_data.toast_tuple_target %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET (toast_tuple_target={{data.toast_tuple_target}}); + +{% endif %} + {###############################} {## Table AutoVacuum settings ##} {###############################} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/create.sql new file mode 100644 index 000000000..a7447e36b --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/create.sql @@ -0,0 +1,174 @@ +{% import 'macros/schemas/security.macros' as SECLABEL %} +{% import 'macros/schemas/privilege.macros' as PRIVILEGE %} +{% import 'macros/variable.macros' as VARIABLE %} +{% import 'columns/macros/security.macros' as COLUMN_SECLABEL %} +{% import 'columns/macros/privilege.macros' as COLUMN_PRIVILEGE %} +{% import 'tables/sql/macros/constraints.macro' as CONSTRAINTS %} +{% import 'types/macros/get_full_type_sql_format.macros' as GET_TYPE %} +{#===========================================#} +{#====== MAIN TABLE TEMPLATE STARTS HERE ======#} +{#===========================================#} +{# + If user has not provided any details but only name then + add empty bracket with table name +#} +{% set empty_bracket = ""%} +{% if data.coll_inherits|length == 0 and data.columns|length == 0 and not data.typname and not data.like_relation and data.primary_key|length == 0 and data.unique_constraint|length == 0 and data.foreign_key|length == 0 and data.check_constraint|length == 0 and data.exclude_constraint|length == 0 %} +{% set empty_bracket = "\n(\n)"%} +{% endif %} +CREATE {% if data.relpersistence %}UNLOGGED {% endif %}TABLE {{conn|qtIdent(data.schema, data.name)}}{{empty_bracket}} +{% if data.typname %} + OF {{ data.typname }} +{% endif %} +{% if data.like_relation or data.coll_inherits or data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 or data.exclude_constraint|length > 0 %} +( +{% endif %} +{% if data.like_relation %} + LIKE {{ data.like_relation }}{% if data.like_default_value %} + + INCLUDING DEFAULTS{% endif %}{% if data.like_constraints %} + + INCLUDING CONSTRAINTS{% endif %}{% if data.like_indexes %} + + INCLUDING INDEXES{% endif %}{% if data.like_storage %} + + INCLUDING STORAGE{% endif %}{% if data.like_comments %} + + INCLUDING COMMENTS{% endif %}{% if data.columns|length > 0 %}, +{% endif %} + +{% endif %} +{### Add columns ###} +{% if data.columns and data.columns|length > 0 %} +{% for c in data.columns %} +{% if c.name and c.cltype %} + {% if c.inheritedfromtable %}-- Inherited from table {{c.inheritedfromtable}}: {% elif c.inheritedfromtype %}-- Inherited from type {{c.inheritedfromtype}}: {% endif %}{{conn|qtIdent(c.name)}} {% if is_sql %}{{c.displaytypname}}{% else %}{{ GET_TYPE.CREATE_TYPE_SQL(conn, c.cltype, c.attlen, c.attprecision, c.hasSqrBracket) }}{% endif %}{% if c.collspcname %} COLLATE {{c.collspcname}}{% endif %}{% if c.attnotnull %} NOT NULL{% endif %}{% if c.defval is defined and c.defval is not none and c.defval != '' %} DEFAULT {{c.defval}}{% endif %} +{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} +{% endif %} +{# Macro to render for constraints #} +{% if data.primary_key|length > 0 %}{% if data.columns|length > 0 %},{% endif %} +{{CONSTRAINTS.PRIMARY_KEY(conn, data.primary_key[0])}}{% endif %}{% if data.unique_constraint|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 %},{% endif %} +{{CONSTRAINTS.UNIQUE(conn, data.unique_constraint)}}{% endif %}{% if data.foreign_key|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 %},{% endif %} +{{CONSTRAINTS.FOREIGN_KEY(conn, data.foreign_key)}}{% endif %}{% if data.check_constraint|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 %},{% endif %} +{{CONSTRAINTS.CHECK(conn, data.check_constraint)}}{% endif %}{% if data.exclude_constraint|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 %},{% endif %} +{{CONSTRAINTS.EXCLUDE(conn, data.exclude_constraint)}}{% endif %} +{% if data.like_relation or data.coll_inherits or data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 or data.exclude_constraint|length > 0 %} + +){% endif %}{% if data.relkind is defined and data.relkind == 'p' %} PARTITION BY {{ data.partition_scheme }} {% endif %} + +{### If we are inheriting it from another table(s) ###} +{% if data.coll_inherits %} + INHERITS ({% for val in data.coll_inherits %}{% if loop.index != 1 %}, {% endif %}{{val}}{% endfor %}) +{% endif %} +WITH ( + OIDS = {% if data.relhasoids %}TRUE{% else %}FALSE{% endif %}{% if data.fillfactor %}, + FILLFACTOR = {{ data.fillfactor }}{% endif %}{% if data.autovacuum_custom %},{% if data.parallel_workers is defined and data.parallel_workers != '' %}, + parallel_workers = {{ data.parallel_workers }}{% endif %} + autovacuum_enabled = {% if data.autovacuum_enabled %}TRUE{% else %}FALSE{% endif %}{% endif %}{% if data.toast_autovacuum %}, + toast.autovacuum_enabled = {% if data.toast_autovacuum_enabled %}TRUE{% else %}FALSE{% endif %} +{% endif %}{% if data.autovacuum_enabled and data.vacuum_table|length > 0 %} +{% for opt in data.vacuum_table %}{% if opt.name and opt.value %} +, + {{opt.name}} = {{opt.value}}{% endif %} +{% endfor %}{% endif %}{% if data.toast_autovacuum_enabled and data.vacuum_toast|length > 0 %} +{% for opt in data.vacuum_toast %}{% if opt.name and opt.value %} +, + toast.{{opt.name}} = {{opt.value}}{% endif %} +{% endfor %}{% endif %} + +{### SQL for Tablespace ###} +{% if data.spcname %} +) +TABLESPACE {{ conn|qtIdent(data.spcname) }}; +{% else %} +); +{% endif %} +{### Alter SQL for Owner ###} +{% if data.relowner %} + +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + OWNER to {{conn|qtIdent(data.relowner)}}; +{% endif %} +{### Security Labels on Table ###} +{% if data.seclabels and data.seclabels|length > 0 %} + +{% for r in data.seclabels %} +{{ SECLABEL.SET(conn, 'TABLE', data.name, r.provider, r.label, data.schema) }} +{% endfor %} +{% endif %} +{### ACL on Table ###} +{% if data.relacl %} + +{% for priv in data.relacl %} +{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }} +{% endfor %} +{% endif %} +{### SQL for COMMENT ###} +{% if data.description %} +COMMENT ON TABLE {{conn|qtIdent(data.schema, data.name)}} + IS {{data.description|qtLiteral}}; +{% endif %} +{#===========================================#} +{#====== MAIN TABLE TEMPLATE ENDS HERE ======#} +{#===========================================#} +{#===========================================#} +{# COLUMN SPECIFIC TEMPLATES STARTS HERE #} +{#===========================================#} +{% if data.columns and data.columns|length > 0 %} +{% for c in data.columns %} +{% if c.description %} + +COMMENT ON COLUMN {{conn|qtIdent(data.schema, data.name, c.name)}} + IS {{c.description|qtLiteral}}; +{% endif %} +{### Add variables to column ###} +{% if c.attoptions and c.attoptions|length > 0 %} + +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + {{ VARIABLE.SET(conn, 'COLUMN', c.name, c.attoptions) }} + +{% endif %} +{### Alter column statistics value ###} +{% if c.attstattarget is defined and c.attstattarget > -1 %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + ALTER COLUMN {{conn|qtTypeIdent(c.name)}} SET STATISTICS {{c.attstattarget}}; + +{% endif %} +{### Alter column storage value ###} +{% if c.attstorage is defined and c.attstorage != c.defaultstorage %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + ALTER COLUMN {{conn|qtTypeIdent(c.name)}} SET STORAGE {%if c.attstorage == 'p' %} +PLAIN{% elif c.attstorage == 'm'%}MAIN{% elif c.attstorage == 'e'%} +EXTERNAL{% elif c.attstorage == 'x'%}EXTENDED{% endif %}; + +{% endif %} +{### ACL ###} +{% if c.attacl and c.attacl|length > 0 %} + +{% for priv in c.attacl %} + {{ COLUMN_PRIVILEGE.APPLY(conn, data.schema, data.name, c.name, priv.grantee, priv.without_grant, priv.with_grant) }} +{% endfor %} +{% endif %} +{### Security Lables ###} +{% if c.seclabels and c.seclabels|length > 0 %} + +{% for r in c.seclabels %} +{{ COLUMN_SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.name, c.name, r.provider, r.label) }} +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} +{#===========================================#} +{# COLUMN SPECIFIC TEMPLATES ENDS HERE #} +{#===========================================#} +{#======================================#} +{# CONSTRAINTS SPECIFIC TEMPLATES #} +{#======================================#} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.primary_key)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.unique_constraint)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.foreign_key)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.check_constraint)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.exclude_constraint)}} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/properties.sql new file mode 100644 index 000000000..4ed202d4f --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/properties.sql @@ -0,0 +1,76 @@ +SELECT *, + (CASE when pre_coll_inherits is NULL then ARRAY[]::varchar[] else pre_coll_inherits END) as coll_inherits +FROM ( + SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS relacl_str, + (CASE WHEN length(spc.spcname) > 0 THEN spc.spcname ELSE + (SELECT sp.spcname FROM pg_database dtb + JOIN pg_tablespace sp ON dtb.dattablespace=sp.oid + WHERE dtb.oid = {{ did }}::oid) + END) as spcname, + (select nspname FROM pg_namespace WHERE oid = {{scid}}::oid ) as schema, + pg_get_userbyid(rel.relowner) AS relowner, rel.relhasoids, + rel.relhassubclass, rel.reltuples::bigint, des.description, con.conname, con.conkey, + EXISTS(select 1 FROM pg_trigger + JOIN pg_proc pt ON pt.oid=tgfoid AND pt.proname='logtrigger' + JOIN pg_proc pc ON pc.pronamespace=pt.pronamespace AND pc.proname='slonyversion' + WHERE tgrelid=rel.oid) AS isrepl, + (SELECT count(*) FROM pg_trigger WHERE tgrelid=rel.oid) AS triggercount, + (SELECT ARRAY(SELECT CASE WHEN (nspname NOT LIKE 'pg\_%') THEN + quote_ident(nspname)||'.'||quote_ident(c.relname) + ELSE quote_ident(c.relname) END AS inherited_tables + FROM pg_inherits i + JOIN pg_class c ON c.oid = i.inhparent + JOIN pg_namespace n ON n.oid=c.relnamespace + WHERE i.inhrelid = rel.oid ORDER BY inhseqno)) AS pre_coll_inherits, + (SELECT count(*) + FROM pg_inherits i + JOIN pg_class c ON c.oid = i.inhparent + JOIN pg_namespace n ON n.oid=c.relnamespace + WHERE i.inhrelid = rel.oid) AS inherited_tables_cnt, + false AS relpersistence, + substring(array_to_string(rel.reloptions, ',') FROM 'fillfactor=([0-9]*)') AS fillfactor, + substring(array_to_string(rel.reloptions, ',') FROM 'parallel_workers=([0-9]*)') AS parallel_workers, + (CASE WHEN (substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') = 'true') + THEN true ELSE false END) AS autovacuum_enabled, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.]?[0-9]*)') AS autovacuum_vacuum_scale_factor, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS autovacuum_analyze_threshold, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.]?[0-9]*)') AS autovacuum_analyze_scale_factor, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS autovacuum_vacuum_cost_delay, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS autovacuum_vacuum_cost_limit, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS autovacuum_freeze_min_age, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS autovacuum_freeze_max_age, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS autovacuum_freeze_table_age, + (CASE WHEN (substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') = 'true') + THEN true ELSE false END) AS toast_autovacuum_enabled, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS toast_autovacuum_vacuum_threshold, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.]?[0-9]*)') AS toast_autovacuum_vacuum_scale_factor, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS toast_autovacuum_analyze_threshold, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.]?[0-9]*)') AS toast_autovacuum_analyze_scale_factor, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS toast_autovacuum_vacuum_cost_delay, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS toast_autovacuum_vacuum_cost_limit, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS toast_autovacuum_freeze_min_age, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS toast_autovacuum_freeze_max_age, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS toast_autovacuum_freeze_table_age, + array_to_string(rel.reloptions, ',') AS table_vacuum_settings_str, + array_to_string(tst.reloptions, ',') AS toast_table_vacuum_settings_str, + rel.reloptions AS reloptions, tst.reloptions AS toast_reloptions, NULL AS reloftype, NULL AS typname, + typ.typrelid AS typoid, + (CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable, + -- Added for pgAdmin4 + (array_to_string(rel.reloptions, ',') like '%autovacuum%') AS autovacuum_custom, + (CASE WHEN array_length(tst.reloptions, 1) > 0 AND rel.reltoastrelid != 0 THEN true ELSE false END) AS toast_autovacuum, + + ARRAY[]::varchar[] AS seclabels, + (CASE WHEN rel.oid <= {{ datlastsysoid}}::oid THEN true ElSE false END) AS is_sys_table + + FROM pg_class rel + LEFT OUTER JOIN pg_tablespace spc on spc.oid=rel.reltablespace + LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0 AND des.classoid='pg_class'::regclass) + LEFT OUTER JOIN pg_constraint con ON con.conrelid=rel.oid AND con.contype='p' + LEFT OUTER JOIN pg_class tst ON tst.oid = rel.reltoastrelid + + WHERE rel.relkind IN ('r','s','t') AND rel.relnamespace = {{ scid }} + {% if tid %} AND rel.oid = {{ tid }}::oid {% endif %} +) AS TableInformation + ORDER BY name diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/update.sql new file mode 100644 index 000000000..98e9ebf4b --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/update.sql @@ -0,0 +1,233 @@ +{% import 'macros/schemas/security.macros' as SECLABEL %} +{% import 'macros/schemas/privilege.macros' as PRIVILEGE %} +{% import 'macros/variable.macros' as VARIABLE %} +{#####################################################} +{## Rename table ##} +{#####################################################} +{% if data.name and data.name != o_data.name %} +ALTER TABLE {{conn|qtIdent(o_data.schema, o_data.name)}} + RENAME TO {{conn|qtIdent(data.name)}}; + +{% endif %} +{#####################################################} +{## Change table schema ##} +{#####################################################} +{% if data.schema and data.schema != o_data.schema %} +ALTER TABLE {{conn|qtIdent(o_data.schema, data.name)}} + SET SCHEMA {{conn|qtIdent(data.schema)}}; + +{% endif %} +{#####################################################} +{## Change table owner ##} +{#####################################################} +{% if data.relowner and data.relowner != o_data.relowner %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + OWNER TO {{conn|qtIdent(data.relowner)}}; + +{% endif %} +{#####################################################} +{## Update Inherits table definition ##} +{#####################################################} +{% if data.coll_inherits_added|length > 0 %} +{% for val in data.coll_inherits_added %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + INHERIT {{val}}; + +{% endfor %} +{% endif %} +{% if data.coll_inherits_removed|length > 0 %} +{% for val in data.coll_inherits_removed %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + NO INHERIT {{val}}; + +{% endfor %} +{% endif %} +{#####################################################} +{## Change hasOID attribute of table ##} +{#####################################################} +{% if data.relhasoids is defined and data.relhasoids != o_data.relhasoids %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET {% if data.relhasoids %}WITH{% else %}WITHOUT{% endif %} OIDS; + +{% endif %} +{#####################################################} +{## Change tablespace ##} +{#####################################################} +{% if data.spcname and data.spcname != o_data.spcname %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET TABLESPACE {{conn|qtIdent(data.spcname)}}; + +{% endif %} +{#####################################################} +{## change fillfactor settings ##} +{#####################################################} +{% if data.fillfactor and data.fillfactor != o_data.fillfactor %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET (FILLFACTOR={{data.fillfactor}}); +{% elif (data.fillfactor == '' or data.fillfactor == None) and data.fillfactor != o_data.fillfactor %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + RESET (FILLFACTOR); + +{% endif %} + +{## change parallel_workers settings ##} +{#####################################################} +{% if (data.parallel_workers == '' or data.parallel_workers == None) and data.parallel_workers != o_data.parallel_workers %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + RESET (parallel_workers); +{% elif data.parallel_workers is defined and data.parallel_workers != o_data.parallel_workers %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET (parallel_workers={{data.parallel_workers}}); + +{% endif %} +{###############################} +{## Table AutoVacuum settings ##} +{###############################} +{% if data.vacuum_table is defined and data.vacuum_table.set_values|length > 0 %} +{% set has_vacuum_set = true %} +{% endif %} +{% if data.vacuum_table is defined and data.vacuum_table.reset_values|length > 0 %} +{% set has_vacuum_reset = true %} +{% endif %} +{% if o_data.autovacuum_custom and data.autovacuum_custom == false %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( + autovacuum_enabled, + autovacuum_analyze_scale_factor, + autovacuum_analyze_threshold, + autovacuum_freeze_max_age, + autovacuum_vacuum_cost_delay, + autovacuum_vacuum_cost_limit, + autovacuum_vacuum_scale_factor, + autovacuum_vacuum_threshold, + autovacuum_freeze_min_age, + autovacuum_freeze_table_age +); +{% else %} +{% if data.autovacuum_enabled is defined or has_vacuum_set %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} SET ( +{% if data.autovacuum_enabled is defined and data.autovacuum_enabled != o_data.autovacuum_enabled %} + autovacuum_enabled = {% if data.autovacuum_enabled %}true{% else %}false{% endif %}{% if has_vacuum_set %}, +{% endif %} +{% endif %} +{% if has_vacuum_set %} +{% for opt in data.vacuum_table.set_values %}{% if opt.name and opt.value %} + {{opt.name}} = {{opt.value}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} +{% endif %} + +); +{% endif %} +{% if has_vacuum_reset %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( +{% for opt in data.vacuum_table.reset_values %}{% if opt.name %} + {{opt.name}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} + +); +{% endif %} +{% endif %} +{#####################################} +{## Toast table AutoVacuum settings ##} +{#####################################} +{% if data.vacuum_toast is defined and data.vacuum_toast.set_values|length > 0 %} +{% set has_vacuum_toast_set = true %} +{% endif %} +{% if data.vacuum_toast is defined and data.vacuum_toast.reset_values|length > 0 %} +{% set has_vacuum_toast_reset = true %} +{% endif %} +{% if o_data.toast_autovacuum and data.toast_autovacuum == false %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( + toast.autovacuum_enabled, + toast.autovacuum_freeze_max_age, + toast.autovacuum_vacuum_cost_delay, + toast.autovacuum_vacuum_cost_limit, + toast.autovacuum_vacuum_scale_factor, + toast.autovacuum_vacuum_threshold, + toast.autovacuum_freeze_min_age, + toast.autovacuum_freeze_table_age, + toast.autovacuum_analyze_threshold, + toast.autovacuum_analyze_scale_factor +); +{% else %} +{% if data.toast_autovacuum_enabled is defined or has_vacuum_toast_set %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} SET ( +{% if data.toast_autovacuum_enabled is defined and data.toast_autovacuum_enabled != o_data.toast_autovacuum_enabled %} + toast.autovacuum_enabled = {% if data.toast_autovacuum_enabled %}true{% else %}false{% endif %}{% if has_vacuum_toast_set %}, +{% endif %} +{% endif %} +{% if has_vacuum_toast_set %} +{% for opt in data.vacuum_toast.set_values %}{% if opt.name and opt.value %} + toast.{{opt.name}} = {{opt.value}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} +{% endif %} + +); +{% endif %} +{% if has_vacuum_toast_reset %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( +{% for opt in data.vacuum_toast.reset_values %}{% if opt.name %} + toast.{{opt.name}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} + +); +{% endif %} +{% endif %} +{#####################################################} +{## Change table comments ##} +{#####################################################} +{% if data.description is defined and data.description != o_data.description %} +COMMENT ON TABLE {{conn|qtIdent(data.schema, data.name)}} + IS {{data.description|qtLiteral}}; + +{% endif %} +{#####################################################} +{## Update table Privileges ##} +{#####################################################} +{% if data.relacl %} +{% if 'deleted' in data.relacl %} +{% for priv in data.relacl.deleted %} +{{ PRIVILEGE.UNSETALL(conn, 'TABLE', priv.grantee, data.name, data.schema) }} +{% endfor %} +{% endif %} +{% if 'changed' in data.relacl %} +{% for priv in data.relacl.changed %} +{{ PRIVILEGE.UNSETALL(conn, 'TABLE', priv.grantee, data.name, data.schema) }} +{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }} +{% endfor %} +{% endif %} +{% if 'added' in data.relacl %} +{% for priv in data.relacl.added %} +{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }} +{% endfor %} +{% endif %} +{% endif %} +{#####################################################} +{## Update table SecurityLabel ##} +{#####################################################} +{% if data.seclabels and data.seclabels|length > 0 %} +{% set seclabels = data.seclabels %} +{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %} +{% for r in seclabels.deleted %} +{{ SECLABEL.UNSET(conn, 'TABLE', data.name, r.provider, data.schema) }} +{% endfor %} +{% endif %} +{% if 'added' in seclabels and seclabels.added|length > 0 %} +{% for r in seclabels.added %} +{{ SECLABEL.SET(conn, 'TABLE', data.name, r.provider, r.label, data.schema) }} +{% endfor %} +{% endif %} +{% if 'changed' in seclabels and seclabels.changed|length > 0 %} +{% for r in seclabels.changed %} +{{ SECLABEL.SET(conn, 'TABLE', data.name, r.provider, r.label, data.schema) }} +{% endfor %} +{% endif %} + +{% endif %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/default/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/default/properties.sql index 932e7ffa5..47686a280 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/default/properties.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/default/properties.sql @@ -57,7 +57,7 @@ FROM ( typ.typrelid AS typoid, (CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable, -- Added for pgAdmin4 - (CASE WHEN array_length(rel.reloptions, 1) > 0 THEN true ELSE false END) AS autovacuum_custom, + (array_to_string(rel.reloptions, ',') like '%autovacuum%') AS autovacuum_custom, (CASE WHEN array_length(tst.reloptions, 1) > 0 AND rel.reltoastrelid != 0 THEN true ELSE false END) AS toast_autovacuum, ARRAY[]::varchar[] AS seclabels, ^ permalink raw reply [nested|flat] 7+ messages in thread
* Re: [pgAdmin][RM5181] Add support for parameters toast_tuple_target and parallel_workers of table @ 2020-04-01 09:21 Akshay Joshi <[email protected]> parent: Aditya Toshniwal <[email protected]> 0 siblings, 1 reply; 7+ messages in thread From: Akshay Joshi @ 2020-04-01 09:21 UTC (permalink / raw) To: Aditya Toshniwal <[email protected]>; +Cc: pgadmin-hackers Hi Aditya API/RESQL test cases are failing for EPAS/PG 9.6 and maybe above. Please fix and resend the patch. On Mon, Mar 30, 2020 at 7:47 PM Aditya Toshniwal < [email protected]> wrote: > Hi Hackers, > > Attached is a patch to add support for parameters toast_tuple_target (PG > v11+) and parallel_workers(PG 9.6+) of table. Refer - > https://www.postgresql.org/docs/11/sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS > . > > Both the parameters are added in the advanced tab of table dialog. > > The patch also fixes a related issue - RM5180, where autovacuum_enabled > parameter is added automatically in the RE-SQL when table has been created > with WITH parameter. > > Please review. > > -- > Thanks and Regards, > Aditya Toshniwal > pgAdmin Hacker | Sr. Software Engineer | EnterpriseDB India | Pune > "Don't Complain about Heat, Plant a TREE" > -- *Thanks & Regards* *Akshay Joshi* *Sr. Software Architect* *EnterpriseDB Software India Private Limited* *Mobile: +91 976-788-8246* ^ permalink raw reply [nested|flat] 7+ messages in thread
* Re: [pgAdmin][RM5181] Add support for parameters toast_tuple_target and parallel_workers of table @ 2020-04-01 10:05 Aditya Toshniwal <[email protected]> parent: Akshay Joshi <[email protected]> 0 siblings, 1 reply; 7+ messages in thread From: Aditya Toshniwal @ 2020-04-01 10:05 UTC (permalink / raw) To: Akshay Joshi <[email protected]>; +Cc: pgadmin-hackers Hi Akshay, On Wed, Apr 1, 2020 at 2:51 PM Akshay Joshi <[email protected]> wrote: > Hi Aditya > > API/RESQL test cases are failing for EPAS/PG 9.6 and maybe above. Please > fix and resend the patch. > The SQL is corrected for 9.6 versions. Others seems to be working fine. Attached is the updated patch. Please review. > > On Mon, Mar 30, 2020 at 7:47 PM Aditya Toshniwal < > [email protected]> wrote: > >> Hi Hackers, >> >> Attached is a patch to add support for parameters toast_tuple_target (PG >> v11+) and parallel_workers(PG 9.6+) of table. Refer - >> https://www.postgresql.org/docs/11/sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS >> . >> >> Both the parameters are added in the advanced tab of table dialog. >> >> The patch also fixes a related issue - RM5180, where autovacuum_enabled >> parameter is added automatically in the RE-SQL when table has been created >> with WITH parameter. >> >> Please review. >> >> -- >> Thanks and Regards, >> Aditya Toshniwal >> pgAdmin Hacker | Sr. Software Engineer | EnterpriseDB India | Pune >> "Don't Complain about Heat, Plant a TREE" >> > > > -- > *Thanks & Regards* > *Akshay Joshi* > > *Sr. Software Architect* > *EnterpriseDB Software India Private Limited* > *Mobile: +91 976-788-8246* > -- Thanks and Regards, Aditya Toshniwal pgAdmin Hacker | Sr. Software Engineer | EnterpriseDB India | Pune "Don't Complain about Heat, Plant a TREE" Attachments: [application/octet-stream] RM5181_5180_v2.patch (63.1K, 3-RM5181_5180_v2.patch) download | inline diff: diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js index 61761794f..f1dd27dc5 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js @@ -291,6 +291,8 @@ define('pgadmin.node.table', [ triggercount: undefined, relpersistence: undefined, fillfactor: undefined, + toast_tuple_target: undefined, + parallel_workers: undefined, reloftype: undefined, typname: undefined, labels: undefined, @@ -779,6 +781,26 @@ define('pgadmin.node.table', [ return m.inSchema(); }, },{ + id: 'toast_tuple_target', label: gettext('Toast tuple target'), type: 'int', + mode: ['create', 'edit'], min: 128, min_version: 110000, + group: gettext('advanced'), + disabled: function(m) { + if(m.get('is_partitioned')) { + return true; + } + return m.inSchema(); + }, + },{ + id: 'parallel_workers', label: gettext('Parallel workers'), type: 'int', + mode: ['create', 'edit'], group: gettext('advanced'), min_version: 90600, + disabled: function(m) { + if(m.get('is_partitioned')) { + return true; + } + return m.inSchema(); + }, + }, + { id: 'relhasoids', label: gettext('Has OIDs?'), cell: 'switch', type: 'switch', mode: ['properties', 'create', 'edit'], group: gettext('advanced'), diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/create.sql index 478e6d752..dafc87aa2 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/create.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/create.sql @@ -77,7 +77,8 @@ CACHE {{c.seqcache|int}} {% endif %} {% endif %} WITH ( OIDS = {% if data.relhasoids %}TRUE{% else %}FALSE{% endif %}{% if data.fillfactor %}, - FILLFACTOR = {{ data.fillfactor }}{% endif %}{% if data.autovacuum_custom %}, + FILLFACTOR = {{ data.fillfactor }}{% endif %}{% if data.parallel_workers is defined and data.parallel_workers != '' and data.parallel_workers != None %}, + parallel_workers = {{ data.parallel_workers }}{% endif %}{% if data.autovacuum_custom %}, autovacuum_enabled = {% if data.autovacuum_enabled %}TRUE{% else %}FALSE{% endif %}{% endif %}{% if data.toast_autovacuum %}, toast.autovacuum_enabled = {% if data.toast_autovacuum_enabled %}TRUE{% else %}FALSE{% endif %} {% endif %}{% if data.autovacuum_enabled and data.vacuum_table|length > 0 %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/properties.sql index e9bb22827..3d31fe60e 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/properties.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/properties.sql @@ -27,6 +27,7 @@ SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS r WHERE i.inhrelid = rel.oid) AS inherited_tables_cnt, (CASE WHEN rel.relpersistence = 'u' THEN true ELSE false END) AS relpersistence, substring(array_to_string(rel.reloptions, ',') FROM 'fillfactor=([0-9]*)') AS fillfactor, + substring(array_to_string(rel.reloptions, ',') FROM 'parallel_workers=([0-9]*)') AS parallel_workers, (CASE WHEN (substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') = 'true') THEN true ELSE false END) AS autovacuum_enabled, substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold, @@ -56,7 +57,7 @@ SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS r typ.typrelid AS typoid, (CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable, -- Added for pgAdmin4 - (CASE WHEN array_length(rel.reloptions, 1) > 0 THEN true ELSE false END) AS autovacuum_custom, + (array_to_string(rel.reloptions, ',') like '%autovacuum%') AS autovacuum_custom, (CASE WHEN array_length(tst.reloptions, 1) > 0 AND rel.reltoastrelid != 0 THEN true ELSE false END) AS toast_autovacuum, (SELECT array_agg(provider || '=' || label) FROM pg_seclabels sl1 WHERE sl1.objoid=rel.oid AND sl1.objsubid=0) AS seclabels, diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/create.sql new file mode 100644 index 000000000..caec8f520 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/create.sql @@ -0,0 +1,187 @@ +{% import 'macros/schemas/security.macros' as SECLABEL %} +{% import 'macros/schemas/privilege.macros' as PRIVILEGE %} +{% import 'macros/variable.macros' as VARIABLE %} +{% import 'columns/macros/security.macros' as COLUMN_SECLABEL %} +{% import 'columns/macros/privilege.macros' as COLUMN_PRIVILEGE %} +{% import 'tables/sql/macros/constraints.macro' as CONSTRAINTS %} +{% import 'types/macros/get_full_type_sql_format.macros' as GET_TYPE %} +{#===========================================#} +{#====== MAIN TABLE TEMPLATE STARTS HERE ======#} +{#===========================================#} +{# + If user has not provided any details but only name then + add empty bracket with table name +#} +{% set empty_bracket = ""%} +{% if data.coll_inherits|length == 0 and data.columns|length == 0 and not data.typname and not data.like_relation and data.primary_key|length == 0 and data.unique_constraint|length == 0 and data.foreign_key|length == 0 and data.check_constraint|length == 0 and data.exclude_constraint|length == 0 %} +{% set empty_bracket = "\n(\n)"%} +{% endif %} +CREATE {% if data.relpersistence %}UNLOGGED {% endif %}TABLE {{conn|qtIdent(data.schema, data.name)}}{{empty_bracket}} +{% if data.typname %} + OF {{ data.typname }} +{% endif %} +{% if data.like_relation or data.coll_inherits or data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 or data.exclude_constraint|length > 0 %} +( +{% endif %} +{% if data.like_relation %} + LIKE {{ data.like_relation }}{% if data.like_default_value %} + + INCLUDING DEFAULTS{% endif %}{% if data.like_constraints %} + + INCLUDING CONSTRAINTS{% endif %}{% if data.like_indexes %} + + INCLUDING INDEXES{% endif %}{% if data.like_storage %} + + INCLUDING STORAGE{% endif %}{% if data.like_comments %} + + INCLUDING COMMENTS{% endif %}{% if data.columns|length > 0 %}, +{% endif %} + +{% endif %} +{### Add columns ###} +{% if data.columns and data.columns|length > 0 %} +{% for c in data.columns %} +{% if c.name and c.cltype %} + {% if c.inheritedfromtable %}-- Inherited from table {{c.inheritedfromtable}}: {% elif c.inheritedfromtype %}-- Inherited from type {{c.inheritedfromtype}}: {% endif %}{{conn|qtIdent(c.name)}} {% if is_sql %}{{c.displaytypname}}{% else %}{{ GET_TYPE.CREATE_TYPE_SQL(conn, c.cltype, c.attlen, c.attprecision, c.hasSqrBracket) }}{% endif %}{% if c.collspcname %} COLLATE {{c.collspcname}}{% endif %}{% if c.attnotnull %} NOT NULL{% endif %}{% if c.defval is defined and c.defval is not none and c.defval != '' %} DEFAULT {{c.defval}}{% endif %} +{% if c.colconstype == 'i' and c.attidentity and c.attidentity != '' %} +{% if c.attidentity == 'a' %} GENERATED ALWAYS AS IDENTITY{% elif c.attidentity == 'd' %} GENERATED BY DEFAULT AS IDENTITY{% endif %} +{% if c.seqincrement or c.seqcycle or c.seqincrement or c.seqstart or c.seqmin or c.seqmax or c.seqcache %} ( {% endif %} +{% if c.seqcycle is defined and c.seqcycle %} +CYCLE {% endif %}{% if c.seqincrement is defined and c.seqincrement|int(-1) > -1 %} +INCREMENT {{c.seqincrement|int}} {% endif %}{% if c.seqstart is defined and c.seqstart|int(-1) > -1%} +START {{c.seqstart|int}} {% endif %}{% if c.seqmin is defined and c.seqmin|int(-1) > -1%} +MINVALUE {{c.seqmin|int}} {% endif %}{% if c.seqmax is defined and c.seqmax|int(-1) > -1%} +MAXVALUE {{c.seqmax|int}} {% endif %}{% if c.seqcache is defined and c.seqcache|int(-1) > -1%} +CACHE {{c.seqcache|int}} {% endif %} +{% if c.seqincrement or c.seqcycle or c.seqincrement or c.seqstart or c.seqmin or c.seqmax or c.seqcache %}){% endif %} +{% endif %} +{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} +{% endif %} +{# Macro to render for constraints #} +{% if data.primary_key|length > 0 %}{% if data.columns|length > 0 %},{% endif %} +{{CONSTRAINTS.PRIMARY_KEY(conn, data.primary_key[0])}}{% endif %}{% if data.unique_constraint|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 %},{% endif %} +{{CONSTRAINTS.UNIQUE(conn, data.unique_constraint)}}{% endif %}{% if data.foreign_key|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 %},{% endif %} +{{CONSTRAINTS.FOREIGN_KEY(conn, data.foreign_key)}}{% endif %}{% if data.check_constraint|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 %},{% endif %} +{{CONSTRAINTS.CHECK(conn, data.check_constraint)}}{% endif %}{% if data.exclude_constraint|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 %},{% endif %} +{{CONSTRAINTS.EXCLUDE(conn, data.exclude_constraint)}}{% endif %} +{% if data.like_relation or data.coll_inherits or data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 or data.exclude_constraint|length > 0 %} + +){% endif %}{% if data.relkind is defined and data.relkind == 'p' %} PARTITION BY {{ data.partition_scheme }} {% endif %} + +{### If we are inheriting it from another table(s) ###} +{% if data.coll_inherits %} + INHERITS ({% for val in data.coll_inherits %}{% if loop.index != 1 %}, {% endif %}{{val}}{% endfor %}) +{% endif %} +WITH ( + OIDS = {% if data.relhasoids %}TRUE{% else %}FALSE{% endif %}{% if data.fillfactor %}, + FILLFACTOR = {{ data.fillfactor }}{% endif %}{% if data.parallel_workers is defined and data.parallel_workers != '' and data.parallel_workers != None %}, + parallel_workers = {{ data.parallel_workers }}{% endif %}{% if data.toast_tuple_target is defined and data.toast_tuple_target != '' and data.toast_tuple_target != None %}, + toast_tuple_target = {{ data.toast_tuple_target }}{% endif %}{% if data.autovacuum_custom %}, + autovacuum_enabled = {% if data.autovacuum_enabled %}TRUE{% else %}FALSE{% endif %}{% endif %}{% if data.toast_autovacuum %}, + toast.autovacuum_enabled = {% if data.toast_autovacuum_enabled %}TRUE{% else %}FALSE{% endif %} +{% endif %}{% if data.autovacuum_enabled and data.vacuum_table|length > 0 %} +{% for opt in data.vacuum_table %}{% if opt.name and opt.value %} +, + {{opt.name}} = {{opt.value}}{% endif %} +{% endfor %}{% endif %}{% if data.toast_autovacuum_enabled and data.vacuum_toast|length > 0 %} +{% for opt in data.vacuum_toast %}{% if opt.name and opt.value %} +, + toast.{{opt.name}} = {{opt.value}}{% endif %} +{% endfor %}{% endif %} + +{### SQL for Tablespace ###} +{% if data.spcname %} +) +TABLESPACE {{ conn|qtIdent(data.spcname) }}; +{% else %} +); +{% endif %} +{### Alter SQL for Owner ###} +{% if data.relowner %} + +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + OWNER to {{conn|qtIdent(data.relowner)}}; +{% endif %} +{### Security Labels on Table ###} +{% if data.seclabels and data.seclabels|length > 0 %} + +{% for r in data.seclabels %} +{{ SECLABEL.SET(conn, 'TABLE', data.name, r.provider, r.label, data.schema) }} +{% endfor %} +{% endif %} +{### ACL on Table ###} +{% if data.relacl %} + +{% for priv in data.relacl %} +{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }} +{% endfor %} +{% endif %} +{### SQL for COMMENT ###} +{% if data.description %} +COMMENT ON TABLE {{conn|qtIdent(data.schema, data.name)}} + IS {{data.description|qtLiteral}}; +{% endif %} +{#===========================================#} +{#====== MAIN TABLE TEMPLATE ENDS HERE ======#} +{#===========================================#} +{#===========================================#} +{# COLUMN SPECIFIC TEMPLATES STARTS HERE #} +{#===========================================#} +{% if data.columns and data.columns|length > 0 %} +{% for c in data.columns %} +{% if c.description %} + +COMMENT ON COLUMN {{conn|qtIdent(data.schema, data.name, c.name)}} + IS {{c.description|qtLiteral}}; +{% endif %} +{### Add variables to column ###} +{% if c.attoptions and c.attoptions|length > 0 %} + +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + {{ VARIABLE.SET(conn, 'COLUMN', c.name, c.attoptions) }} + +{% endif %} +{### Alter column statistics value ###} +{% if c.attstattarget is defined and c.attstattarget > -1 %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + ALTER COLUMN {{conn|qtTypeIdent(c.name)}} SET STATISTICS {{c.attstattarget}}; + +{% endif %} +{### Alter column storage value ###} +{% if c.attstorage is defined and c.attstorage != c.defaultstorage %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + ALTER COLUMN {{conn|qtTypeIdent(c.name)}} SET STORAGE {%if c.attstorage == 'p' %} +PLAIN{% elif c.attstorage == 'm'%}MAIN{% elif c.attstorage == 'e'%} +EXTERNAL{% elif c.attstorage == 'x'%}EXTENDED{% endif %}; + +{% endif %} +{### ACL ###} +{% if c.attacl and c.attacl|length > 0 %} + +{% for priv in c.attacl %} +{{ COLUMN_PRIVILEGE.APPLY(conn, data.schema, data.name, c.name, priv.grantee, priv.without_grant, priv.with_grant) }} +{% endfor %} +{% endif %} +{### Security Lables ###} +{% if c.seclabels and c.seclabels|length > 0 %} + +{% for r in c.seclabels %} +{{ COLUMN_SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.name, c.name, r.provider, r.label) }} +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} +{#===========================================#} +{# COLUMN SPECIFIC TEMPLATES ENDS HERE #} +{#===========================================#} +{#======================================#} +{# CONSTRAINTS SPECIFIC TEMPLATES #} +{#======================================#} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.primary_key)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.unique_constraint)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.foreign_key)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.check_constraint)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.exclude_constraint)}} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/properties.sql new file mode 100644 index 000000000..3ac7ceae8 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/properties.sql @@ -0,0 +1,77 @@ +SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS relacl_str, + (CASE WHEN length(spc.spcname) > 0 THEN spc.spcname ELSE + (SELECT sp.spcname FROM pg_database dtb + JOIN pg_tablespace sp ON dtb.dattablespace=sp.oid + WHERE dtb.oid = {{ did }}::oid) + END) as spcname, + (select nspname FROM pg_namespace WHERE oid = {{scid}}::oid ) as schema, + pg_get_userbyid(rel.relowner) AS relowner, rel.relhasoids, rel.relkind, + (CASE WHEN rel.relkind = 'p' THEN true ELSE false END) AS is_partitioned, + rel.relhassubclass, rel.reltuples::bigint, des.description, con.conname, con.conkey, + EXISTS(select 1 FROM pg_trigger + JOIN pg_proc pt ON pt.oid=tgfoid AND pt.proname='logtrigger' + JOIN pg_proc pc ON pc.pronamespace=pt.pronamespace AND pc.proname='slonyversion' + WHERE tgrelid=rel.oid) AS isrepl, + (SELECT count(*) FROM pg_trigger WHERE tgrelid=rel.oid AND tgisinternal = FALSE) AS triggercount, + (SELECT ARRAY(SELECT CASE WHEN (nspname NOT LIKE 'pg\_%') THEN + quote_ident(nspname)||'.'||quote_ident(c.relname) + ELSE quote_ident(c.relname) END AS inherited_tables + FROM pg_inherits i + JOIN pg_class c ON c.oid = i.inhparent + JOIN pg_namespace n ON n.oid=c.relnamespace + WHERE i.inhrelid = rel.oid ORDER BY inhseqno)) AS coll_inherits, + (SELECT count(*) + FROM pg_inherits i + JOIN pg_class c ON c.oid = i.inhparent + JOIN pg_namespace n ON n.oid=c.relnamespace + WHERE i.inhrelid = rel.oid) AS inherited_tables_cnt, + (CASE WHEN rel.relpersistence = 'u' THEN true ELSE false END) AS relpersistence, + substring(array_to_string(rel.reloptions, ',') FROM 'fillfactor=([0-9]*)') AS fillfactor, + substring(array_to_string(rel.reloptions, ',') FROM 'parallel_workers=([0-9]*)') AS parallel_workers, + substring(array_to_string(rel.reloptions, ',') FROM 'toast_tuple_target=([0-9]*)') AS toast_tuple_target, + (CASE WHEN (substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') = 'true') + THEN true ELSE false END) AS autovacuum_enabled, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.]?[0-9]*)') AS autovacuum_vacuum_scale_factor, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS autovacuum_analyze_threshold, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.]?[0-9]*)') AS autovacuum_analyze_scale_factor, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS autovacuum_vacuum_cost_delay, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS autovacuum_vacuum_cost_limit, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS autovacuum_freeze_min_age, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS autovacuum_freeze_max_age, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS autovacuum_freeze_table_age, + (CASE WHEN (substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') = 'true') + THEN true ELSE false END) AS toast_autovacuum_enabled, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS toast_autovacuum_vacuum_threshold, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.]?[0-9]*)') AS toast_autovacuum_vacuum_scale_factor, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS toast_autovacuum_analyze_threshold, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.]?[0-9]*)') AS toast_autovacuum_analyze_scale_factor, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS toast_autovacuum_vacuum_cost_delay, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS toast_autovacuum_vacuum_cost_limit, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS toast_autovacuum_freeze_min_age, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS toast_autovacuum_freeze_max_age, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS toast_autovacuum_freeze_table_age, + array_to_string(rel.reloptions, ',') AS table_vacuum_settings_str, + array_to_string(tst.reloptions, ',') AS toast_table_vacuum_settings_str, + rel.reloptions AS reloptions, tst.reloptions AS toast_reloptions, rel.reloftype, + CASE WHEN typ.typname IS NOT NULL THEN (select quote_ident(nspname) FROM pg_namespace WHERE oid = {{scid}}::oid )||'.'||quote_ident(typ.typname) ELSE typ.typname END AS typname, + typ.typrelid AS typoid, + (CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable, + -- Added for pgAdmin4 + (array_to_string(rel.reloptions, ',') like '%autovacuum%') AS autovacuum_custom, + (CASE WHEN array_length(tst.reloptions, 1) > 0 AND rel.reltoastrelid != 0 THEN true ELSE false END) AS toast_autovacuum, + + (SELECT array_agg(provider || '=' || label) FROM pg_seclabels sl1 WHERE sl1.objoid=rel.oid AND sl1.objsubid=0) AS seclabels, + (CASE WHEN rel.oid <= {{ datlastsysoid}}::oid THEN true ElSE false END) AS is_sys_table + -- Added for partition table + {% if tid %}, (CASE WHEN rel.relkind = 'p' THEN pg_get_partkeydef({{ tid }}::oid) ELSE '' END) AS partition_scheme {% endif %} +FROM pg_class rel + LEFT OUTER JOIN pg_tablespace spc on spc.oid=rel.reltablespace + LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0 AND des.classoid='pg_class'::regclass) + LEFT OUTER JOIN pg_constraint con ON con.conrelid=rel.oid AND con.contype='p' + LEFT OUTER JOIN pg_class tst ON tst.oid = rel.reltoastrelid + LEFT JOIN pg_type typ ON rel.reloftype=typ.oid +WHERE rel.relkind IN ('r','s','t','p') AND rel.relnamespace = {{ scid }}::oid +AND NOT rel.relispartition +{% if tid %} AND rel.oid = {{ tid }}::oid {% endif %} +ORDER BY rel.relname; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/update.sql new file mode 100644 index 000000000..0f27dbed2 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/update.sql @@ -0,0 +1,245 @@ +{% import 'macros/schemas/security.macros' as SECLABEL %} +{% import 'macros/schemas/privilege.macros' as PRIVILEGE %} +{% import 'macros/variable.macros' as VARIABLE %} +{#####################################################} +{## Rename table ##} +{#####################################################} +{% if data.name and data.name != o_data.name %} +ALTER TABLE {{conn|qtIdent(o_data.schema, o_data.name)}} + RENAME TO {{conn|qtIdent(data.name)}}; + +{% endif %} +{#####################################################} +{## Change table schema ##} +{#####################################################} +{% if data.schema and data.schema != o_data.schema %} +ALTER TABLE {{conn|qtIdent(o_data.schema, data.name)}} + SET SCHEMA {{conn|qtIdent(data.schema)}}; + +{% endif %} +{#####################################################} +{## Change table owner ##} +{#####################################################} +{% if data.relowner and data.relowner != o_data.relowner %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + OWNER TO {{conn|qtIdent(data.relowner)}}; + +{% endif %} +{#####################################################} +{## Update Inherits table definition ##} +{#####################################################} +{% if data.coll_inherits_added|length > 0 %} +{% for val in data.coll_inherits_added %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + INHERIT {{val}}; + +{% endfor %} +{% endif %} +{% if data.coll_inherits_removed|length > 0 %} +{% for val in data.coll_inherits_removed %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + NO INHERIT {{val}}; + +{% endfor %} +{% endif %} +{#####################################################} +{## Change hasOID attribute of table ##} +{#####################################################} +{% if data.relhasoids is defined and data.relhasoids != o_data.relhasoids %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET {% if data.relhasoids %}WITH{% else %}WITHOUT{% endif %} OIDS; + +{% endif %} +{#####################################################} +{## Change tablespace ##} +{#####################################################} +{% if data.spcname and data.spcname != o_data.spcname %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET TABLESPACE {{conn|qtIdent(data.spcname)}}; + +{% endif %} +{#####################################################} +{## change fillfactor settings ##} +{#####################################################} +{% if data.fillfactor and data.fillfactor != o_data.fillfactor %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET (FILLFACTOR={{data.fillfactor}}); +{% elif (data.fillfactor == '' or data.fillfactor == None) and data.fillfactor != o_data.fillfactor %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + RESET (FILLFACTOR); + +{% endif %} + +{## change parallel_workers settings ##} +{#####################################################} +{% if (data.parallel_workers == '' or data.parallel_workers == None) and data.parallel_workers != o_data.parallel_workers %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + RESET (parallel_workers); +{% elif data.parallel_workers is defined and data.parallel_workers != o_data.parallel_workers %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET (parallel_workers={{data.parallel_workers}}); + +{% endif %} + +{## change toast_tuple_target settings ##} +{#####################################################} +{% if (data.toast_tuple_target == '' or data.toast_tuple_target == None) and data.toast_tuple_target != o_data.toast_tuple_target %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + RESET (toast_tuple_target); +{% elif data.toast_tuple_target is defined and data.toast_tuple_target != o_data.toast_tuple_target %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET (toast_tuple_target={{data.toast_tuple_target}}); + +{% endif %} + +{###############################} +{## Table AutoVacuum settings ##} +{###############################} +{% if data.vacuum_table is defined and data.vacuum_table.set_values|length > 0 %} +{% set has_vacuum_set = true %} +{% endif %} +{% if data.vacuum_table is defined and data.vacuum_table.reset_values|length > 0 %} +{% set has_vacuum_reset = true %} +{% endif %} +{% if o_data.autovacuum_custom and data.autovacuum_custom == false %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( + autovacuum_enabled, + autovacuum_analyze_scale_factor, + autovacuum_analyze_threshold, + autovacuum_freeze_max_age, + autovacuum_vacuum_cost_delay, + autovacuum_vacuum_cost_limit, + autovacuum_vacuum_scale_factor, + autovacuum_vacuum_threshold, + autovacuum_freeze_min_age, + autovacuum_freeze_table_age +); +{% else %} +{% if data.autovacuum_enabled is defined or has_vacuum_set %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} SET ( +{% if data.autovacuum_enabled is defined and data.autovacuum_enabled != o_data.autovacuum_enabled %} + autovacuum_enabled = {% if data.autovacuum_enabled %}true{% else %}false{% endif %}{% if has_vacuum_set %}, +{% endif %} +{% endif %} +{% if has_vacuum_set %} +{% for opt in data.vacuum_table.set_values %}{% if opt.name and opt.value %} + {{opt.name}} = {{opt.value}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} +{% endif %} + +); +{% endif %} +{% if has_vacuum_reset %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( +{% for opt in data.vacuum_table.reset_values %}{% if opt.name %} + {{opt.name}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} + +); +{% endif %} +{% endif %} +{#####################################} +{## Toast table AutoVacuum settings ##} +{#####################################} +{% if data.vacuum_toast is defined and data.vacuum_toast.set_values|length > 0 %} +{% set has_vacuum_toast_set = true %} +{% endif %} +{% if data.vacuum_toast is defined and data.vacuum_toast.reset_values|length > 0 %} +{% set has_vacuum_toast_reset = true %} +{% endif %} +{% if o_data.toast_autovacuum and data.toast_autovacuum == false %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( + toast.autovacuum_enabled, + toast.autovacuum_freeze_max_age, + toast.autovacuum_vacuum_cost_delay, + toast.autovacuum_vacuum_cost_limit, + toast.autovacuum_vacuum_scale_factor, + toast.autovacuum_vacuum_threshold, + toast.autovacuum_freeze_min_age, + toast.autovacuum_freeze_table_age, + toast.autovacuum_analyze_threshold, + toast.autovacuum_analyze_scale_factor +); +{% else %} +{% if data.toast_autovacuum_enabled is defined or has_vacuum_toast_set %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} SET ( +{% if data.toast_autovacuum_enabled is defined and data.toast_autovacuum_enabled != o_data.toast_autovacuum_enabled %} + toast.autovacuum_enabled = {% if data.toast_autovacuum_enabled %}true{% else %}false{% endif %}{% if has_vacuum_toast_set %}, +{% endif %} +{% endif %} +{% if has_vacuum_toast_set %} +{% for opt in data.vacuum_toast.set_values %}{% if opt.name and opt.value %} + toast.{{opt.name}} = {{opt.value}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} +{% endif %} + +); +{% endif %} +{% if has_vacuum_toast_reset %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( +{% for opt in data.vacuum_toast.reset_values %}{% if opt.name %} + toast.{{opt.name}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} + +); +{% endif %} +{% endif %} +{#####################################################} +{## Change table comments ##} +{#####################################################} +{% if data.description is defined and data.description != o_data.description %} +COMMENT ON TABLE {{conn|qtIdent(data.schema, data.name)}} + IS {{data.description|qtLiteral}}; + +{% endif %} +{#####################################################} +{## Update table Privileges ##} +{#####################################################} +{% if data.relacl %} +{% if 'deleted' in data.relacl %} +{% for priv in data.relacl.deleted %} +{{ PRIVILEGE.UNSETALL(conn, 'TABLE', priv.grantee, data.name, data.schema) }} +{% endfor %} +{% endif %} +{% if 'changed' in data.relacl %} +{% for priv in data.relacl.changed %} +{{ PRIVILEGE.UNSETALL(conn, 'TABLE', priv.grantee, data.name, data.schema) }} +{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }} +{% endfor %} +{% endif %} +{% if 'added' in data.relacl %} +{% for priv in data.relacl.added %} +{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }} +{% endfor %} +{% endif %} +{% endif %} +{#####################################################} +{## Update table SecurityLabel ##} +{#####################################################} +{% if data.seclabels and data.seclabels|length > 0 %} +{% set seclabels = data.seclabels %} +{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %} +{% for r in seclabels.deleted %} +{{ SECLABEL.UNSET(conn, 'TABLE', data.name, r.provider, data.schema) }} +{% endfor %} +{% endif %} +{% if 'added' in seclabels and seclabels.added|length > 0 %} +{% for r in seclabels.added %} +{{ SECLABEL.SET(conn, 'TABLE', data.name, r.provider, r.label, data.schema) }} +{% endfor %} +{% endif %} +{% if 'changed' in seclabels and seclabels.changed|length > 0 %} +{% for r in seclabels.changed %} +{{ SECLABEL.SET(conn, 'TABLE', data.name, r.provider, r.label, data.schema) }} +{% endfor %} +{% endif %} + +{% endif %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/create.sql index c52861b0c..486bc3091 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/create.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/create.sql @@ -17,7 +17,7 @@ {% set empty_bracket = "\n(\n)"%} {% endif %} {% set with_clause = false%} -{% if data.fillfactor or data.autovacuum_custom or data.autovacuum_enabled or data.toast_autovacuum or data.toast_autovacuum_enabled or (data.autovacuum_enabled and data.vacuum_table|length > 0) or (data.toast_autovacuum_enabled and data.vacuum_toast|length > 0) %} +{% if data.fillfactor or data.parallel_workers or data.toast_tuple_target or data.autovacuum_custom or data.autovacuum_enabled or data.toast_autovacuum or data.toast_autovacuum_enabled or (data.autovacuum_enabled and data.vacuum_table|length > 0) or (data.toast_autovacuum_enabled and data.vacuum_toast|length > 0) %} {% set with_clause = true%} {% endif %} CREATE {% if data.relpersistence %}UNLOGGED {% endif %}TABLE {{conn|qtIdent(data.schema, data.name)}}{{empty_bracket}} @@ -86,7 +86,13 @@ CACHE {{c.seqcache|int}} {% endif %} {% set add_comma = false%} WITH ( {% if data.fillfactor %}{% set add_comma = true%} - FILLFACTOR = {{ data.fillfactor }}{% endif %}{% if data.autovacuum_custom %} + FILLFACTOR = {{ data.fillfactor }}{% endif %}{% if data.parallel_workers %} +{% if add_comma %}, +{% endif %} + parallel_workers = {{ data.parallel_workers }}{% set add_comma = true%}{% endif %}{% if data.toast_tuple_target %} +{% if add_comma %}, +{% endif %} + toast_tuple_target = {{ data.toast_tuple_target }}{% set add_comma = true%}{% endif %}{% if data.autovacuum_custom %} {% if add_comma %}, {% endif %} autovacuum_enabled = {% if data.autovacuum_enabled %}TRUE{% else %}FALSE{% endif %}{% set add_comma = true%}{% endif %}{% if data.toast_autovacuum %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/properties.sql index e7d19055d..3d9b1f622 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/properties.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/properties.sql @@ -27,6 +27,8 @@ SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS r WHERE i.inhrelid = rel.oid) AS inherited_tables_cnt, (CASE WHEN rel.relpersistence = 'u' THEN true ELSE false END) AS relpersistence, substring(array_to_string(rel.reloptions, ',') FROM 'fillfactor=([0-9]*)') AS fillfactor, + substring(array_to_string(rel.reloptions, ',') FROM 'parallel_workers=([0-9]*)') AS parallel_workers, + substring(array_to_string(rel.reloptions, ',') FROM 'toast_tuple_target=([0-9]*)') AS toast_tuple_target, (CASE WHEN (substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') = 'true') THEN true ELSE false END) AS autovacuum_enabled, substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold, @@ -56,7 +58,7 @@ SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS r typ.typrelid AS typoid, (CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable, -- Added for pgAdmin4 - (CASE WHEN array_length(rel.reloptions, 1) > 0 THEN true ELSE false END) AS autovacuum_custom, + (array_to_string(rel.reloptions, ',') like '%autovacuum%') AS autovacuum_custom, (CASE WHEN array_length(tst.reloptions, 1) > 0 AND rel.reltoastrelid != 0 THEN true ELSE false END) AS toast_autovacuum, (SELECT array_agg(provider || '=' || label) FROM pg_seclabels sl1 WHERE sl1.objoid=rel.oid AND sl1.objsubid=0) AS seclabels, diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/update.sql index 3ed12302d..e2415ad2a 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/update.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/update.sql @@ -61,6 +61,29 @@ ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET (FILLFACTOR); {% endif %} + +{## change parallel_workers settings ##} +{#####################################################} +{% if (data.parallel_workers == '' or data.parallel_workers == None) and data.parallel_workers != o_data.parallel_workers %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + RESET (parallel_workers); +{% elif data.parallel_workers is defined and data.parallel_workers != o_data.parallel_workers %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET (parallel_workers={{data.parallel_workers}}); + +{% endif %} + +{## change toast_tuple_target settings ##} +{#####################################################} +{% if (data.toast_tuple_target == '' or data.toast_tuple_target == None) and data.toast_tuple_target != o_data.toast_tuple_target %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + RESET (toast_tuple_target); +{% elif data.toast_tuple_target is defined and data.toast_tuple_target != o_data.toast_tuple_target %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET (toast_tuple_target={{data.toast_tuple_target}}); + +{% endif %} + {###############################} {## Table AutoVacuum settings ##} {###############################} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/create.sql new file mode 100644 index 000000000..a7447e36b --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/create.sql @@ -0,0 +1,174 @@ +{% import 'macros/schemas/security.macros' as SECLABEL %} +{% import 'macros/schemas/privilege.macros' as PRIVILEGE %} +{% import 'macros/variable.macros' as VARIABLE %} +{% import 'columns/macros/security.macros' as COLUMN_SECLABEL %} +{% import 'columns/macros/privilege.macros' as COLUMN_PRIVILEGE %} +{% import 'tables/sql/macros/constraints.macro' as CONSTRAINTS %} +{% import 'types/macros/get_full_type_sql_format.macros' as GET_TYPE %} +{#===========================================#} +{#====== MAIN TABLE TEMPLATE STARTS HERE ======#} +{#===========================================#} +{# + If user has not provided any details but only name then + add empty bracket with table name +#} +{% set empty_bracket = ""%} +{% if data.coll_inherits|length == 0 and data.columns|length == 0 and not data.typname and not data.like_relation and data.primary_key|length == 0 and data.unique_constraint|length == 0 and data.foreign_key|length == 0 and data.check_constraint|length == 0 and data.exclude_constraint|length == 0 %} +{% set empty_bracket = "\n(\n)"%} +{% endif %} +CREATE {% if data.relpersistence %}UNLOGGED {% endif %}TABLE {{conn|qtIdent(data.schema, data.name)}}{{empty_bracket}} +{% if data.typname %} + OF {{ data.typname }} +{% endif %} +{% if data.like_relation or data.coll_inherits or data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 or data.exclude_constraint|length > 0 %} +( +{% endif %} +{% if data.like_relation %} + LIKE {{ data.like_relation }}{% if data.like_default_value %} + + INCLUDING DEFAULTS{% endif %}{% if data.like_constraints %} + + INCLUDING CONSTRAINTS{% endif %}{% if data.like_indexes %} + + INCLUDING INDEXES{% endif %}{% if data.like_storage %} + + INCLUDING STORAGE{% endif %}{% if data.like_comments %} + + INCLUDING COMMENTS{% endif %}{% if data.columns|length > 0 %}, +{% endif %} + +{% endif %} +{### Add columns ###} +{% if data.columns and data.columns|length > 0 %} +{% for c in data.columns %} +{% if c.name and c.cltype %} + {% if c.inheritedfromtable %}-- Inherited from table {{c.inheritedfromtable}}: {% elif c.inheritedfromtype %}-- Inherited from type {{c.inheritedfromtype}}: {% endif %}{{conn|qtIdent(c.name)}} {% if is_sql %}{{c.displaytypname}}{% else %}{{ GET_TYPE.CREATE_TYPE_SQL(conn, c.cltype, c.attlen, c.attprecision, c.hasSqrBracket) }}{% endif %}{% if c.collspcname %} COLLATE {{c.collspcname}}{% endif %}{% if c.attnotnull %} NOT NULL{% endif %}{% if c.defval is defined and c.defval is not none and c.defval != '' %} DEFAULT {{c.defval}}{% endif %} +{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} +{% endif %} +{# Macro to render for constraints #} +{% if data.primary_key|length > 0 %}{% if data.columns|length > 0 %},{% endif %} +{{CONSTRAINTS.PRIMARY_KEY(conn, data.primary_key[0])}}{% endif %}{% if data.unique_constraint|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 %},{% endif %} +{{CONSTRAINTS.UNIQUE(conn, data.unique_constraint)}}{% endif %}{% if data.foreign_key|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 %},{% endif %} +{{CONSTRAINTS.FOREIGN_KEY(conn, data.foreign_key)}}{% endif %}{% if data.check_constraint|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 %},{% endif %} +{{CONSTRAINTS.CHECK(conn, data.check_constraint)}}{% endif %}{% if data.exclude_constraint|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 %},{% endif %} +{{CONSTRAINTS.EXCLUDE(conn, data.exclude_constraint)}}{% endif %} +{% if data.like_relation or data.coll_inherits or data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 or data.exclude_constraint|length > 0 %} + +){% endif %}{% if data.relkind is defined and data.relkind == 'p' %} PARTITION BY {{ data.partition_scheme }} {% endif %} + +{### If we are inheriting it from another table(s) ###} +{% if data.coll_inherits %} + INHERITS ({% for val in data.coll_inherits %}{% if loop.index != 1 %}, {% endif %}{{val}}{% endfor %}) +{% endif %} +WITH ( + OIDS = {% if data.relhasoids %}TRUE{% else %}FALSE{% endif %}{% if data.fillfactor %}, + FILLFACTOR = {{ data.fillfactor }}{% endif %}{% if data.autovacuum_custom %},{% if data.parallel_workers is defined and data.parallel_workers != '' %}, + parallel_workers = {{ data.parallel_workers }}{% endif %} + autovacuum_enabled = {% if data.autovacuum_enabled %}TRUE{% else %}FALSE{% endif %}{% endif %}{% if data.toast_autovacuum %}, + toast.autovacuum_enabled = {% if data.toast_autovacuum_enabled %}TRUE{% else %}FALSE{% endif %} +{% endif %}{% if data.autovacuum_enabled and data.vacuum_table|length > 0 %} +{% for opt in data.vacuum_table %}{% if opt.name and opt.value %} +, + {{opt.name}} = {{opt.value}}{% endif %} +{% endfor %}{% endif %}{% if data.toast_autovacuum_enabled and data.vacuum_toast|length > 0 %} +{% for opt in data.vacuum_toast %}{% if opt.name and opt.value %} +, + toast.{{opt.name}} = {{opt.value}}{% endif %} +{% endfor %}{% endif %} + +{### SQL for Tablespace ###} +{% if data.spcname %} +) +TABLESPACE {{ conn|qtIdent(data.spcname) }}; +{% else %} +); +{% endif %} +{### Alter SQL for Owner ###} +{% if data.relowner %} + +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + OWNER to {{conn|qtIdent(data.relowner)}}; +{% endif %} +{### Security Labels on Table ###} +{% if data.seclabels and data.seclabels|length > 0 %} + +{% for r in data.seclabels %} +{{ SECLABEL.SET(conn, 'TABLE', data.name, r.provider, r.label, data.schema) }} +{% endfor %} +{% endif %} +{### ACL on Table ###} +{% if data.relacl %} + +{% for priv in data.relacl %} +{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }} +{% endfor %} +{% endif %} +{### SQL for COMMENT ###} +{% if data.description %} +COMMENT ON TABLE {{conn|qtIdent(data.schema, data.name)}} + IS {{data.description|qtLiteral}}; +{% endif %} +{#===========================================#} +{#====== MAIN TABLE TEMPLATE ENDS HERE ======#} +{#===========================================#} +{#===========================================#} +{# COLUMN SPECIFIC TEMPLATES STARTS HERE #} +{#===========================================#} +{% if data.columns and data.columns|length > 0 %} +{% for c in data.columns %} +{% if c.description %} + +COMMENT ON COLUMN {{conn|qtIdent(data.schema, data.name, c.name)}} + IS {{c.description|qtLiteral}}; +{% endif %} +{### Add variables to column ###} +{% if c.attoptions and c.attoptions|length > 0 %} + +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + {{ VARIABLE.SET(conn, 'COLUMN', c.name, c.attoptions) }} + +{% endif %} +{### Alter column statistics value ###} +{% if c.attstattarget is defined and c.attstattarget > -1 %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + ALTER COLUMN {{conn|qtTypeIdent(c.name)}} SET STATISTICS {{c.attstattarget}}; + +{% endif %} +{### Alter column storage value ###} +{% if c.attstorage is defined and c.attstorage != c.defaultstorage %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + ALTER COLUMN {{conn|qtTypeIdent(c.name)}} SET STORAGE {%if c.attstorage == 'p' %} +PLAIN{% elif c.attstorage == 'm'%}MAIN{% elif c.attstorage == 'e'%} +EXTERNAL{% elif c.attstorage == 'x'%}EXTENDED{% endif %}; + +{% endif %} +{### ACL ###} +{% if c.attacl and c.attacl|length > 0 %} + +{% for priv in c.attacl %} + {{ COLUMN_PRIVILEGE.APPLY(conn, data.schema, data.name, c.name, priv.grantee, priv.without_grant, priv.with_grant) }} +{% endfor %} +{% endif %} +{### Security Lables ###} +{% if c.seclabels and c.seclabels|length > 0 %} + +{% for r in c.seclabels %} +{{ COLUMN_SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.name, c.name, r.provider, r.label) }} +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} +{#===========================================#} +{# COLUMN SPECIFIC TEMPLATES ENDS HERE #} +{#===========================================#} +{#======================================#} +{# CONSTRAINTS SPECIFIC TEMPLATES #} +{#======================================#} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.primary_key)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.unique_constraint)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.foreign_key)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.check_constraint)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.exclude_constraint)}} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/properties.sql new file mode 100644 index 000000000..80451f12d --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/properties.sql @@ -0,0 +1,72 @@ +SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS relacl_str, + (CASE WHEN length(spc.spcname) > 0 THEN spc.spcname ELSE + (SELECT sp.spcname FROM pg_database dtb + JOIN pg_tablespace sp ON dtb.dattablespace=sp.oid + WHERE dtb.oid = {{ did }}::oid) + END) as spcname, + (select nspname FROM pg_namespace WHERE oid = {{scid}}::oid ) as schema, + pg_get_userbyid(rel.relowner) AS relowner, rel.relhasoids, + rel.relhassubclass, rel.reltuples::bigint, des.description, con.conname, con.conkey, + EXISTS(select 1 FROM pg_trigger + JOIN pg_proc pt ON pt.oid=tgfoid AND pt.proname='logtrigger' + JOIN pg_proc pc ON pc.pronamespace=pt.pronamespace AND pc.proname='slonyversion' + WHERE tgrelid=rel.oid) AS isrepl, + (SELECT count(*) FROM pg_trigger WHERE tgrelid=rel.oid AND tgisinternal = FALSE) AS triggercount, + (SELECT ARRAY(SELECT CASE WHEN (nspname NOT LIKE 'pg\_%') THEN + quote_ident(nspname)||'.'||quote_ident(c.relname) + ELSE quote_ident(c.relname) END AS inherited_tables + FROM pg_inherits i + JOIN pg_class c ON c.oid = i.inhparent + JOIN pg_namespace n ON n.oid=c.relnamespace + WHERE i.inhrelid = rel.oid ORDER BY inhseqno)) AS coll_inherits, + (SELECT count(*) + FROM pg_inherits i + JOIN pg_class c ON c.oid = i.inhparent + JOIN pg_namespace n ON n.oid=c.relnamespace + WHERE i.inhrelid = rel.oid) AS inherited_tables_cnt, + (CASE WHEN rel.relpersistence = 'u' THEN true ELSE false END) AS relpersistence, + substring(array_to_string(rel.reloptions, ',') FROM 'fillfactor=([0-9]*)') AS fillfactor, + substring(array_to_string(rel.reloptions, ',') FROM 'parallel_workers=([0-9]*)') AS parallel_workers, + (CASE WHEN (substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') = 'true') + THEN true ELSE false END) AS autovacuum_enabled, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.]?[0-9]*)') AS autovacuum_vacuum_scale_factor, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS autovacuum_analyze_threshold, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.]?[0-9]*)') AS autovacuum_analyze_scale_factor, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS autovacuum_vacuum_cost_delay, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS autovacuum_vacuum_cost_limit, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS autovacuum_freeze_min_age, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS autovacuum_freeze_max_age, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS autovacuum_freeze_table_age, + (CASE WHEN (substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') = 'true') + THEN true ELSE false END) AS toast_autovacuum_enabled, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS toast_autovacuum_vacuum_threshold, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.]?[0-9]*)') AS toast_autovacuum_vacuum_scale_factor, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS toast_autovacuum_analyze_threshold, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.]?[0-9]*)') AS toast_autovacuum_analyze_scale_factor, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS toast_autovacuum_vacuum_cost_delay, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS toast_autovacuum_vacuum_cost_limit, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS toast_autovacuum_freeze_min_age, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS toast_autovacuum_freeze_max_age, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS toast_autovacuum_freeze_table_age, + array_to_string(rel.reloptions, ',') AS table_vacuum_settings_str, + array_to_string(tst.reloptions, ',') AS toast_table_vacuum_settings_str, + rel.reloptions AS reloptions, tst.reloptions AS toast_reloptions, rel.reloftype, + CASE WHEN typ.typname IS NOT NULL THEN (select quote_ident(nspname) FROM pg_namespace WHERE oid = {{scid}}::oid )||'.'||quote_ident(typ.typname) ELSE typ.typname END AS typname, + typ.typrelid AS typoid, + (CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable, + -- Added for pgAdmin4 + (array_to_string(rel.reloptions, ',') like '%autovacuum%') AS autovacuum_custom, + (CASE WHEN array_length(tst.reloptions, 1) > 0 AND rel.reltoastrelid != 0 THEN true ELSE false END) AS toast_autovacuum, + + (SELECT array_agg(provider || '=' || label) FROM pg_seclabels sl1 WHERE sl1.objoid=rel.oid AND sl1.objsubid=0) AS seclabels, + (CASE WHEN rel.oid <= {{ datlastsysoid}}::oid THEN true ElSE false END) AS is_sys_table +FROM pg_class rel + LEFT OUTER JOIN pg_tablespace spc on spc.oid=rel.reltablespace + LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0 AND des.classoid='pg_class'::regclass) + LEFT OUTER JOIN pg_constraint con ON con.conrelid=rel.oid AND con.contype='p' + LEFT OUTER JOIN pg_class tst ON tst.oid = rel.reltoastrelid + LEFT JOIN pg_type typ ON rel.reloftype=typ.oid +WHERE rel.relkind IN ('r','s','t') AND rel.relnamespace = {{ scid }}::oid +{% if tid %} AND rel.oid = {{ tid }}::oid {% endif %} +ORDER BY rel.relname; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/update.sql new file mode 100644 index 000000000..98e9ebf4b --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/update.sql @@ -0,0 +1,233 @@ +{% import 'macros/schemas/security.macros' as SECLABEL %} +{% import 'macros/schemas/privilege.macros' as PRIVILEGE %} +{% import 'macros/variable.macros' as VARIABLE %} +{#####################################################} +{## Rename table ##} +{#####################################################} +{% if data.name and data.name != o_data.name %} +ALTER TABLE {{conn|qtIdent(o_data.schema, o_data.name)}} + RENAME TO {{conn|qtIdent(data.name)}}; + +{% endif %} +{#####################################################} +{## Change table schema ##} +{#####################################################} +{% if data.schema and data.schema != o_data.schema %} +ALTER TABLE {{conn|qtIdent(o_data.schema, data.name)}} + SET SCHEMA {{conn|qtIdent(data.schema)}}; + +{% endif %} +{#####################################################} +{## Change table owner ##} +{#####################################################} +{% if data.relowner and data.relowner != o_data.relowner %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + OWNER TO {{conn|qtIdent(data.relowner)}}; + +{% endif %} +{#####################################################} +{## Update Inherits table definition ##} +{#####################################################} +{% if data.coll_inherits_added|length > 0 %} +{% for val in data.coll_inherits_added %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + INHERIT {{val}}; + +{% endfor %} +{% endif %} +{% if data.coll_inherits_removed|length > 0 %} +{% for val in data.coll_inherits_removed %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + NO INHERIT {{val}}; + +{% endfor %} +{% endif %} +{#####################################################} +{## Change hasOID attribute of table ##} +{#####################################################} +{% if data.relhasoids is defined and data.relhasoids != o_data.relhasoids %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET {% if data.relhasoids %}WITH{% else %}WITHOUT{% endif %} OIDS; + +{% endif %} +{#####################################################} +{## Change tablespace ##} +{#####################################################} +{% if data.spcname and data.spcname != o_data.spcname %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET TABLESPACE {{conn|qtIdent(data.spcname)}}; + +{% endif %} +{#####################################################} +{## change fillfactor settings ##} +{#####################################################} +{% if data.fillfactor and data.fillfactor != o_data.fillfactor %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET (FILLFACTOR={{data.fillfactor}}); +{% elif (data.fillfactor == '' or data.fillfactor == None) and data.fillfactor != o_data.fillfactor %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + RESET (FILLFACTOR); + +{% endif %} + +{## change parallel_workers settings ##} +{#####################################################} +{% if (data.parallel_workers == '' or data.parallel_workers == None) and data.parallel_workers != o_data.parallel_workers %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + RESET (parallel_workers); +{% elif data.parallel_workers is defined and data.parallel_workers != o_data.parallel_workers %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET (parallel_workers={{data.parallel_workers}}); + +{% endif %} +{###############################} +{## Table AutoVacuum settings ##} +{###############################} +{% if data.vacuum_table is defined and data.vacuum_table.set_values|length > 0 %} +{% set has_vacuum_set = true %} +{% endif %} +{% if data.vacuum_table is defined and data.vacuum_table.reset_values|length > 0 %} +{% set has_vacuum_reset = true %} +{% endif %} +{% if o_data.autovacuum_custom and data.autovacuum_custom == false %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( + autovacuum_enabled, + autovacuum_analyze_scale_factor, + autovacuum_analyze_threshold, + autovacuum_freeze_max_age, + autovacuum_vacuum_cost_delay, + autovacuum_vacuum_cost_limit, + autovacuum_vacuum_scale_factor, + autovacuum_vacuum_threshold, + autovacuum_freeze_min_age, + autovacuum_freeze_table_age +); +{% else %} +{% if data.autovacuum_enabled is defined or has_vacuum_set %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} SET ( +{% if data.autovacuum_enabled is defined and data.autovacuum_enabled != o_data.autovacuum_enabled %} + autovacuum_enabled = {% if data.autovacuum_enabled %}true{% else %}false{% endif %}{% if has_vacuum_set %}, +{% endif %} +{% endif %} +{% if has_vacuum_set %} +{% for opt in data.vacuum_table.set_values %}{% if opt.name and opt.value %} + {{opt.name}} = {{opt.value}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} +{% endif %} + +); +{% endif %} +{% if has_vacuum_reset %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( +{% for opt in data.vacuum_table.reset_values %}{% if opt.name %} + {{opt.name}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} + +); +{% endif %} +{% endif %} +{#####################################} +{## Toast table AutoVacuum settings ##} +{#####################################} +{% if data.vacuum_toast is defined and data.vacuum_toast.set_values|length > 0 %} +{% set has_vacuum_toast_set = true %} +{% endif %} +{% if data.vacuum_toast is defined and data.vacuum_toast.reset_values|length > 0 %} +{% set has_vacuum_toast_reset = true %} +{% endif %} +{% if o_data.toast_autovacuum and data.toast_autovacuum == false %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( + toast.autovacuum_enabled, + toast.autovacuum_freeze_max_age, + toast.autovacuum_vacuum_cost_delay, + toast.autovacuum_vacuum_cost_limit, + toast.autovacuum_vacuum_scale_factor, + toast.autovacuum_vacuum_threshold, + toast.autovacuum_freeze_min_age, + toast.autovacuum_freeze_table_age, + toast.autovacuum_analyze_threshold, + toast.autovacuum_analyze_scale_factor +); +{% else %} +{% if data.toast_autovacuum_enabled is defined or has_vacuum_toast_set %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} SET ( +{% if data.toast_autovacuum_enabled is defined and data.toast_autovacuum_enabled != o_data.toast_autovacuum_enabled %} + toast.autovacuum_enabled = {% if data.toast_autovacuum_enabled %}true{% else %}false{% endif %}{% if has_vacuum_toast_set %}, +{% endif %} +{% endif %} +{% if has_vacuum_toast_set %} +{% for opt in data.vacuum_toast.set_values %}{% if opt.name and opt.value %} + toast.{{opt.name}} = {{opt.value}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} +{% endif %} + +); +{% endif %} +{% if has_vacuum_toast_reset %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( +{% for opt in data.vacuum_toast.reset_values %}{% if opt.name %} + toast.{{opt.name}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} + +); +{% endif %} +{% endif %} +{#####################################################} +{## Change table comments ##} +{#####################################################} +{% if data.description is defined and data.description != o_data.description %} +COMMENT ON TABLE {{conn|qtIdent(data.schema, data.name)}} + IS {{data.description|qtLiteral}}; + +{% endif %} +{#####################################################} +{## Update table Privileges ##} +{#####################################################} +{% if data.relacl %} +{% if 'deleted' in data.relacl %} +{% for priv in data.relacl.deleted %} +{{ PRIVILEGE.UNSETALL(conn, 'TABLE', priv.grantee, data.name, data.schema) }} +{% endfor %} +{% endif %} +{% if 'changed' in data.relacl %} +{% for priv in data.relacl.changed %} +{{ PRIVILEGE.UNSETALL(conn, 'TABLE', priv.grantee, data.name, data.schema) }} +{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }} +{% endfor %} +{% endif %} +{% if 'added' in data.relacl %} +{% for priv in data.relacl.added %} +{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }} +{% endfor %} +{% endif %} +{% endif %} +{#####################################################} +{## Update table SecurityLabel ##} +{#####################################################} +{% if data.seclabels and data.seclabels|length > 0 %} +{% set seclabels = data.seclabels %} +{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %} +{% for r in seclabels.deleted %} +{{ SECLABEL.UNSET(conn, 'TABLE', data.name, r.provider, data.schema) }} +{% endfor %} +{% endif %} +{% if 'added' in seclabels and seclabels.added|length > 0 %} +{% for r in seclabels.added %} +{{ SECLABEL.SET(conn, 'TABLE', data.name, r.provider, r.label, data.schema) }} +{% endfor %} +{% endif %} +{% if 'changed' in seclabels and seclabels.changed|length > 0 %} +{% for r in seclabels.changed %} +{{ SECLABEL.SET(conn, 'TABLE', data.name, r.provider, r.label, data.schema) }} +{% endfor %} +{% endif %} + +{% endif %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/default/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/default/properties.sql index 932e7ffa5..47686a280 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/default/properties.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/default/properties.sql @@ -57,7 +57,7 @@ FROM ( typ.typrelid AS typoid, (CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable, -- Added for pgAdmin4 - (CASE WHEN array_length(rel.reloptions, 1) > 0 THEN true ELSE false END) AS autovacuum_custom, + (array_to_string(rel.reloptions, ',') like '%autovacuum%') AS autovacuum_custom, (CASE WHEN array_length(tst.reloptions, 1) > 0 AND rel.reltoastrelid != 0 THEN true ELSE false END) AS toast_autovacuum, ARRAY[]::varchar[] AS seclabels, ^ permalink raw reply [nested|flat] 7+ messages in thread
* Re: [pgAdmin][RM5181] Add support for parameters toast_tuple_target and parallel_workers of table @ 2020-04-01 11:40 Akshay Joshi <[email protected]> parent: Aditya Toshniwal <[email protected]> 0 siblings, 1 reply; 7+ messages in thread From: Akshay Joshi @ 2020-04-01 11:40 UTC (permalink / raw) To: Aditya Toshniwal <[email protected]>; +Cc: pgadmin-hackers Hi Aditya Tested on 9.6, test cases are fixed but wrong SQL generated for tables: CREATE TABLE public.test ( col1 bigint ) WITH ( OIDS = FALSE,, parallel_workers = 56 autovacuum_enabled = TRUE, Also parameter parallel_workers is not showing until we enabled the autovacuum parameters. Please fix and resend the patch. On Wed, Apr 1, 2020 at 3:35 PM Aditya Toshniwal < [email protected]> wrote: > Hi Akshay, > > On Wed, Apr 1, 2020 at 2:51 PM Akshay Joshi <[email protected]> > wrote: > >> Hi Aditya >> >> API/RESQL test cases are failing for EPAS/PG 9.6 and maybe above. Please >> fix and resend the patch. >> > The SQL is corrected for 9.6 versions. Others seems to be working fine. > Attached is the updated patch. > Please review. > >> >> On Mon, Mar 30, 2020 at 7:47 PM Aditya Toshniwal < >> [email protected]> wrote: >> >>> Hi Hackers, >>> >>> Attached is a patch to add support for parameters toast_tuple_target (PG >>> v11+) and parallel_workers(PG 9.6+) of table. Refer - >>> https://www.postgresql.org/docs/11/sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS >>> . >>> >>> Both the parameters are added in the advanced tab of table dialog. >>> >>> The patch also fixes a related issue - RM5180, where autovacuum_enabled >>> parameter is added automatically in the RE-SQL when table has been created >>> with WITH parameter. >>> >>> Please review. >>> >>> -- >>> Thanks and Regards, >>> Aditya Toshniwal >>> pgAdmin Hacker | Sr. Software Engineer | EnterpriseDB India | Pune >>> "Don't Complain about Heat, Plant a TREE" >>> >> >> >> -- >> *Thanks & Regards* >> *Akshay Joshi* >> >> *Sr. Software Architect* >> *EnterpriseDB Software India Private Limited* >> *Mobile: +91 976-788-8246* >> > > > -- > Thanks and Regards, > Aditya Toshniwal > pgAdmin Hacker | Sr. Software Engineer | EnterpriseDB India | Pune > "Don't Complain about Heat, Plant a TREE" > -- *Thanks & Regards* *Akshay Joshi* *Sr. Software Architect* *EnterpriseDB Software India Private Limited* *Mobile: +91 976-788-8246* ^ permalink raw reply [nested|flat] 7+ messages in thread
* Re: [pgAdmin][RM5181] Add support for parameters toast_tuple_target and parallel_workers of table @ 2020-04-01 12:07 Akshay Joshi <[email protected]> parent: Akshay Joshi <[email protected]> 0 siblings, 1 reply; 7+ messages in thread From: Akshay Joshi @ 2020-04-01 12:07 UTC (permalink / raw) To: Aditya Toshniwal <[email protected]>; +Cc: pgadmin-hackers Documentation and Screenshot need to be updated. On Wed, Apr 1, 2020 at 5:10 PM Akshay Joshi <[email protected]> wrote: > Hi Aditya > > Tested on 9.6, test cases are fixed but wrong SQL generated for tables: > CREATE TABLE public.test > ( > col1 bigint > ) > WITH ( > OIDS = FALSE,, > parallel_workers = 56 autovacuum_enabled = TRUE, > > Also parameter parallel_workers is not showing until we enabled the > autovacuum parameters. > > Please fix and resend the patch. > > On Wed, Apr 1, 2020 at 3:35 PM Aditya Toshniwal < > [email protected]> wrote: > >> Hi Akshay, >> >> On Wed, Apr 1, 2020 at 2:51 PM Akshay Joshi < >> [email protected]> wrote: >> >>> Hi Aditya >>> >>> API/RESQL test cases are failing for EPAS/PG 9.6 and maybe above. Please >>> fix and resend the patch. >>> >> The SQL is corrected for 9.6 versions. Others seems to be working fine. >> Attached is the updated patch. >> Please review. >> >>> >>> On Mon, Mar 30, 2020 at 7:47 PM Aditya Toshniwal < >>> [email protected]> wrote: >>> >>>> Hi Hackers, >>>> >>>> Attached is a patch to add support for parameters toast_tuple_target >>>> (PG v11+) and parallel_workers(PG 9.6+) of table. Refer - >>>> https://www.postgresql.org/docs/11/sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS >>>> . >>>> >>>> Both the parameters are added in the advanced tab of table dialog. >>>> >>>> The patch also fixes a related issue - RM5180, where autovacuum_enabled >>>> parameter is added automatically in the RE-SQL when table has been created >>>> with WITH parameter. >>>> >>>> Please review. >>>> >>>> -- >>>> Thanks and Regards, >>>> Aditya Toshniwal >>>> pgAdmin Hacker | Sr. Software Engineer | EnterpriseDB India | Pune >>>> "Don't Complain about Heat, Plant a TREE" >>>> >>> >>> >>> -- >>> *Thanks & Regards* >>> *Akshay Joshi* >>> >>> *Sr. Software Architect* >>> *EnterpriseDB Software India Private Limited* >>> *Mobile: +91 976-788-8246* >>> >> >> >> -- >> Thanks and Regards, >> Aditya Toshniwal >> pgAdmin Hacker | Sr. Software Engineer | EnterpriseDB India | Pune >> "Don't Complain about Heat, Plant a TREE" >> > > > -- > *Thanks & Regards* > *Akshay Joshi* > > *Sr. Software Architect* > *EnterpriseDB Software India Private Limited* > *Mobile: +91 976-788-8246* > -- *Thanks & Regards* *Akshay Joshi* *Sr. Software Architect* *EnterpriseDB Software India Private Limited* *Mobile: +91 976-788-8246* ^ permalink raw reply [nested|flat] 7+ messages in thread
* Re: [pgAdmin][RM5181] Add support for parameters toast_tuple_target and parallel_workers of table @ 2020-04-01 12:35 Aditya Toshniwal <[email protected]> parent: Akshay Joshi <[email protected]> 0 siblings, 1 reply; 7+ messages in thread From: Aditya Toshniwal @ 2020-04-01 12:35 UTC (permalink / raw) To: Akshay Joshi <[email protected]>; +Cc: pgadmin-hackers Hi Hackers, Attached is the updated patch. The issue was on PG9.6, fixed that. Docs updated. Please review. On Wed, Apr 1, 2020 at 5:37 PM Akshay Joshi <[email protected]> wrote: > Documentation and Screenshot need to be updated. > > On Wed, Apr 1, 2020 at 5:10 PM Akshay Joshi <[email protected]> > wrote: > >> Hi Aditya >> >> Tested on 9.6, test cases are fixed but wrong SQL generated for tables: >> CREATE TABLE public.test >> ( >> col1 bigint >> ) >> WITH ( >> OIDS = FALSE,, >> parallel_workers = 56 autovacuum_enabled = TRUE, >> >> Also parameter parallel_workers is not showing until we enabled the >> autovacuum parameters. >> >> Please fix and resend the patch. >> >> On Wed, Apr 1, 2020 at 3:35 PM Aditya Toshniwal < >> [email protected]> wrote: >> >>> Hi Akshay, >>> >>> On Wed, Apr 1, 2020 at 2:51 PM Akshay Joshi < >>> [email protected]> wrote: >>> >>>> Hi Aditya >>>> >>>> API/RESQL test cases are failing for EPAS/PG 9.6 and maybe above. >>>> Please fix and resend the patch. >>>> >>> The SQL is corrected for 9.6 versions. Others seems to be working fine. >>> Attached is the updated patch. >>> Please review. >>> >>>> >>>> On Mon, Mar 30, 2020 at 7:47 PM Aditya Toshniwal < >>>> [email protected]> wrote: >>>> >>>>> Hi Hackers, >>>>> >>>>> Attached is a patch to add support for parameters toast_tuple_target >>>>> (PG v11+) and parallel_workers(PG 9.6+) of table. Refer - >>>>> https://www.postgresql.org/docs/11/sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS >>>>> . >>>>> >>>>> Both the parameters are added in the advanced tab of table dialog. >>>>> >>>>> The patch also fixes a related issue - RM5180, >>>>> where autovacuum_enabled parameter is added automatically in the RE-SQL >>>>> when table has been created with WITH parameter. >>>>> >>>>> Please review. >>>>> >>>>> -- >>>>> Thanks and Regards, >>>>> Aditya Toshniwal >>>>> pgAdmin Hacker | Sr. Software Engineer | EnterpriseDB India | Pune >>>>> "Don't Complain about Heat, Plant a TREE" >>>>> >>>> >>>> >>>> -- >>>> *Thanks & Regards* >>>> *Akshay Joshi* >>>> >>>> *Sr. Software Architect* >>>> *EnterpriseDB Software India Private Limited* >>>> *Mobile: +91 976-788-8246* >>>> >>> >>> >>> -- >>> Thanks and Regards, >>> Aditya Toshniwal >>> pgAdmin Hacker | Sr. Software Engineer | EnterpriseDB India | Pune >>> "Don't Complain about Heat, Plant a TREE" >>> >> >> >> -- >> *Thanks & Regards* >> *Akshay Joshi* >> >> *Sr. Software Architect* >> *EnterpriseDB Software India Private Limited* >> *Mobile: +91 976-788-8246* >> > > > -- > *Thanks & Regards* > *Akshay Joshi* > > *Sr. Software Architect* > *EnterpriseDB Software India Private Limited* > *Mobile: +91 976-788-8246* > -- Thanks and Regards, Aditya Toshniwal pgAdmin Hacker | Sr. Software Engineer | EnterpriseDB India | Pune "Don't Complain about Heat, Plant a TREE" Attachments: [application/octet-stream] RM5181_5180_v3.patch (254.8K, 3-RM5181_5180_v3.patch) download | inline diff: diff --git a/docs/en_US/images/table_advanced.png b/docs/en_US/images/table_advanced.png old mode 100755 new mode 100644 index 7d7f1fd7f61fa26a571b27944ff54cba7d121d33..02228122a77548fe7de14d3b286502719904087f GIT binary patch literal 88949 zcmZ^~1z4QF(l?A0ciQ4kf#O!&-Mzr#?i6?Th2rjR#ogWAU5dNA%eOt}Jm=~E{oZ%? zy02uDnIv;(lFa-j8zL_&h6IlT4+aK?Bq1)W2nGgG0(x*@p+O}u;U9>>zz}84goNZJ zgoKFX?W~Q>ERDdx#6#j$VE{@)7#SLh5~jYe;&5#tB(NW%&;>(@h?G&|qduTZhQSH+ zMbMONsLP{4If|%?e9}T7vgp&s=sQ!#K%k;N-lAgtzLw`x-hS0~?P-6W$!zkb#Ki0j z4c3O!E}Z~8f{dc4jT#UOsO&E+s1lC^gE;VkPV<4&$%?Yw+R6cs^S$TWy>&E2+WndO z^LXX$oeEkoS`Z8j9mcjmo_G-GLI~zk#ZOKT<}(=Nwqgdw^jQ|TD2@yn04V5Q!qLp> zPR7y9ua^kh7i@(DV+x;0G=a=oLA)&$6ky$%YJ;n4`TjK;B1<fYU7lzUfjA<-1>p7e z>2r`%C*?Il#)-F$F|ys&<B~rhHdK8u8$FOFl5hK+X5c;Hg?rZr1!mDy-_@{{$^_7m z+N6~8Jqg;j;TtnKhQ3hnx@3U4d$2+=06RIaN^A@Yo~{&ISMY>x2Pi6FiEP{Wjh<Y+ zWMVWX;F>6i`9nG#<p!Dg0Np3bZuHtTmMhB3DoA#z@m<pa){9;94yxym!>eB+65a~{ zy|^3R%3oxqeUsq9L}}x`4DgpCR7I1p5lb5QFMSGWVuWP1Gis&s;tF0OF%u3BB9xkl z0S;K48a@8>^{7&;3c$?mQ-<2=6_@d>JcVfI^!gZ#E21bn4HhZR$m>Rgnf>*fbS&3A zc?`MPb>G<#yx>-yfxDrrt-5;}&2Xsv;SVBKrBCFh16#QW8v(Ny+f&tkjlwc%E~3cZ z(rM%bt*F9~bg)n~Spl>krNKG)r{{mqB6*v+b%PTQ3b3Mrvy~a^3jb^tgU^J^f_;ID zhW!dX5ctboBn$P3580eWjx8$xjP`rvAXFsrIE(@j%9~2Dm;_84nZKAk>0^HjSbqvk zYVo-SK8$%z9nLNoy_9ul43;P&nJ9Ws$ao_*LGbhT)CD$TD$IDlCrr+(rJRejDFru? zCaD9el}y5?k&d56GzUH}o6BL$9iv#zK55!6umoUB#LVNpV?MaN@K2i?0+ThEvvzg1 zC3YsSsoXHk4>^14TtB&>@)5H?D5bR%6dmUrvkc}GA0*yR^`>wDl+Sc07T%h4X4PQV z6?8Q85vtl2%}%hKFt~zQz%iUYSoG8B0>8W1AoD0rWP@8@9=X^NNABQydz8s3lYKtB zJ<~cPto6*||E5*P2XXdk39;#mhGyqhXSz=BmIPD}u!?(?XBAxDQ|#NytW?3%vk$|B z=RB>C1qc7~`nvZ;4c!qB*mLP7)A>WGeJf%EWaC1n8lC(w0t=_+Em7xhew6aBO1f~C zo6f^XE@0LhD1HK1SdjVxB;ru9y6Js3ydz!T7!XEb^0V-0AWJ&cE5R)xRyt)XVZQnL zZ(y-Qjr&V&;4~ub%Tc&MyLDPj0*PSZvPltpKUE2ypsDsk>XG`2W1)xlk`{?W$ApWc zkuf2t`NWZa9#l6ZRRq3-;qgZhn?yV9VAv5J3ciW1<zh(+h07z%g5&#ED<I<plIMJ! zvUH$Q4@k(8nxv}5`0dM@Gcb95z)}n88FZ%)Hq(`q#IhGu#Yl${ny;spgqP|cuNM!X zo%gBh^nQY$_jNQlw;>ttRBOad>xp(jr|T@-vcKqiQ1`%H3(oAU*towWc=_ln%RteH z{sPP0?IOskhm##AFR>`ND8~+`szkBL5-o0sjvvBn!%~25AIuyQ8gd-m5-b*S+6(N} zMh`KRv?GIx(wFd11TTuK4XX8b2yjTAm2i`qC)SAO8Qk3YRvo7)UH-+If{<K?oR9ck z;fC_=6Q3lFh<LJqn>SS+-`LgW}UK=<j0YU@XxoLg{j4Ijr(>is$k=M+XOs2M<SK zGtmd5Gey%&W%i=`?c-c2#AAW|`S~+(wPdwrwYjw#wTTX#zkLa$<#I766DN-k1`h8J ztR1nNdmLSx1%Ed+&ozfPCpu;xE8Lvivb)9J{Jf#My*tvHJ)SQ-;5x9seSEUNDY->C zSf4y+(Zve;7R)lp2C%IBy;0hwBoveFua}fPS=nn7yJ_14L=4j#*<kt*1{F3I78@o@ zniHLiHt}`f*Q#luLaIV!RrclAZNu%u{<(f&7*`V3jPH=a9%CZYJwpZaI!YB*H#P}Q zwW)Yd)QHep5+Vy6D_U|~@(ELu@zq+K5sq<+Me}Oy&`mkE)t)}<xMj+cTTQI-Z=vv@ zCzQ{Kw7AVC2iAMPnnGP$AEmEl_Ap1?X=!LlXbdqdXd*NmG?-}pY3*rL)d}iPs`UX- z>Jp_Y>iAVp{zju)l~(}e(vPJC7WT*D7WucL$E?S^xMHbaQuR}{Se<_q)myI6ti;!s z)$=&1I2oK8FU_sI8p~Cgtc0Gbu4LAGZ*Lq#ZC$hp#r7zPeH6<uh&E{3#;0gjikkUe zs9snyE^Jb7Uw+NGFGcq&G%<8Be|a~D`snDC%2sQCnKz7K)H%rka9W9L^^Gk;BU__w z<#ls(bE+p4$cE(2+ifMh9K1^^8~LzvwwtlvzVv!0-V<#giV<mv{n!8u1$O2xZx>Vi zW?r=~H>ueVRVdFD&Yh2JKJ2@|IlgUEEm;t=CbVvH_IFN<OqUCi3!gx$N8^fUOY-bb z+`!%9TDZ?T=i;;Ofau`y@_uZ2+<&sZ_vT!-tu?*bn?ixKgm?hQh2(@#^Tqb%gLe9$ z26O3e?oaSx1scJ>;RD|$yS*Jd7yE?Js?ZMcv(TE&Yhz85m{8SZ@MQI5Jws1rUS*x$ zefN*<nx5kxcal~TV^O^DFT$cCbdjxHH5+g)j;$GtyavXR9B3k;lELb@w?xZi>IA=; zFz~sIPkvT8>z^3pG0IdCC1AFY+*zd=tj;#-^rH>*g_jWAvwIo7ls?SBg#`@3t$fs` z2>L=N)0(~$mnUs5GcP48S1#ohi=LtwJ<aIV`>?b<QJ9i1shBz=ZZ>45G3`bXAOm2@ zX8ujx_U-jacpzkkA|u_9mC|}Td&n*JG4|dVl}VAQ-o#^L;L75$ExC0xWt0G1wNm{; z8jD7g@&p|!m`Yf#8lsx2I>Q*ouww8G9VUdj?>Bn6VcCv|tl@Z28e3CUlZO5Cwc?f2 zZtOMl6^b}ge$(_vC7MF%%xOCN`1oPYf+ra*mO3#4vh^JPPai*zL5W^;dI=ony~w(D zFjQ7HU!2zNn7J3?N+-&8F!UJp=U~hI><;xx37PmbYME}tWARq{T*FbrHZHJdIBu41 z!PQ`Bwci@-y0WLVzd!z7x7gO0^DyTZ2SrPUL3S-k;Dvdq<ymA^)Oyo@|F&)o2&Rvt zvDDaUG9Am2GwQCk-#y!n-zCIAz{q^o+d)z0yP+RapRS*EKYTLkHJUbBNQ9wXSJ9JK z_<m{AxA-}nT8(-{rCpuHb#7@`As$ynNtIgF`MZcJOGTANjpZ1yZmVvgSg6=}E@^?L z*tJHs@$Bkp;}!{*hBeOG<vn+2AQhLCm35wTR>g|MifZ-7#r|q<hOf%IctyWH-(zH; zY`P48Wve0m*L6|JidDO(8IO8J>G^VW`}XwsWcnDA6%wv9qjUT@bW428`vb@J{;_+` zUG16C`Hw}DjtXNw18+6bY4+TzLW$McskG%)FWph!d5rgj*AB#Yqho<%|2be73N4Q` zkEUJYyZBV}T5fgj?}6$_9?SGqx95k4ZB@B2t|=#`qn%`>&BBPxy)<4s@{Q518ZQ%+ zG=oeF&U4T9OTUG{*ABPW=8mzJvdf%_zCEe-MD=B{2EukchsVYEN$SG#tMZHv4EwTI zx9QtdwrOjJ)lX|4Zq(=Vq3iJ8$1ObP$eXfDTCXkf_oL@?Z)Y#h<;dp|Lia-FIxbNc z8+SroJtmQ#B6%GWxC{8oJ@jw$&WZ+R{Ixc<65o<8#P*q&YTD1H`H<d9UC(Yj)^)nP zwGOb?XC4LLa^BDT=w)=QJXwyEEvz-q+ZG-xp4Z~qSUg)!@t=Pm-cz1u-pD-jKgr)t zJsOM@{*rTkx_*8(^5D?%{M4x{R8tN1;7$#8^BoK;apO_XZ!e<|L)e~8ne-yFa*ys8 zhBX+@hLoe`J^_?2n<er!5u0UkuA4psKMxN~s>&y|3<4ZFoYqU!wY&R{S}>nkh)ywA zZ}0Wyx3|bty~+kKc1~scj_+`2Ye-&*%Gny!<cJT1ao*s~4BjIy0C0JbgOOkakT8~! z0iy!tVZorl(ZL`=IdISy3>*gx>R)*<FiCLS|K=6Jzy5~?0t^gj2KM1UH0q%A&nF7> zfVlsYLdFDv!GM0DgPwpai2tF6D9M8SZypC!2PU8-Bq0Gxl??2RjI8WUtsM-)B>%Jx zXCtm=4+e%o_U8eYQ2cTM@{SzMz5^TpGSZv|)<5X<46XHz=v;o-{AmY_+l3R9{bA&w zN96Lu(#oFGg@@!{6r7;^pJI9vqJNP%Sn!YlWaNp2tnG}5Sm?gdF_7@W6A=+{+Zh^j zDhiAKhaL2bhs4yu!G@Eb-r3oi&Y79c+RlWYk%NPSo`H#;iHR0OL2K`7<)G(6Yh_RR z??(Qo9bqGT13NPt2QzCcqCf5G>03KG@Q{%F>FB?oe~;71#q583va<h=SReuE|J2Yk z(lOBg-`E_?jQ<~Oe`@~C_Aj~q-5vLz#z1OeWG7_(<A;%z1MmO7aqfTh^pDE_9p}Fp z<;`4-ECIr1AWnObOuUTW7?}RU_J3CWUs=`uVr69b_BZQaRe!Pm5rR|B&I~kCy+3b} zmyw(P|5x^Z(kmL-TU$E*Ay>9CbKnJy@Lw$dNAZ8Sxat2)%wH4rZ!P#&DM$@?;koJm zt5Ur1S98|<U|{@U62b!CUBFM$VY2W=<_6@n<+R<1!DFHXiBR3*(P2d>rv(%~eLwjL z)#v9$qVoOIXJLLQ1+*x-HleSArr<IBuu;&yQ5lJ?+GoyQ_V!lfBW)FHJHNk}#5_AW z4<|Ffr(dlz*VOP}(5q#bTbjo_J&_+y<pLY+Kj49jb)wn)PtuI<`(1K)SSl|sJ6iz< zC)H@Ovt4niq!4}HN_Fh>f64yEv>1jaPN|@!rA0B4peiv`JXcqJt0I)=Y&0>3g-+j0 zx&g}$5#jUigg=|8)6#pLx6Kc&?pIEZrrT{PY;!)mh|ogM|8@>)RkubA%)lJ&>*8!j z1=!-raRB5$TInM431o?y^P3v{Z2Lb${*M48AJR%ibsviU*{vS2ydvz;MZf9^YXNO- zO!L6*Mr&Dh6t5~?Y&tb}a-t5`e~0KpT3JLqX;uy2QCn9Iu`ml&;cHjUAy@9LMd1~o z&sv=@MlU&isI&vUB*OFkcV1BX#}zdaGo#uYCwvP%y{gR2e>BBGJb7pYhMfbiZs9@* z^HMX_>9|!Pz>X_`u=R~e@6jo$BPS=P6>YBk07zF?S66Mb*=;i_DqT`syz|?6J-)xc zzua)w4F9jmS=5Ea0&XX9N4_qX$OCCgEW!%9{F)n!B~(<{q%Luq5gNV|d?holvox0o zd7Fru-@}OR@{}^<H?kG2NJvQF$0N3!;CpW!O=1)pmK-sR<hhSZcUqSC85$bMUgbY| zS>w0d^!SlY6(ChiCZrf*U}o1Bc|GQc9OALz3u8DGL#C*rg5e-~PW}qo<z&KdPL`B- zAG%P6JAEPj3H6BiL@FD90SaW(sbKJIe58|^MDCVMGUc^rkQ6=l)18MYcrW49Ds_D= z>*iEAMiQj>?w$XdL0usdUG5-mNI9i(gEabiAv4RM#J;zsaV}96;w*Dkt;QS$IxoYb z8)~y?aGucof@~4D_`9h5I?Cj_95p9A0FCF!oZVua;ya02X<mJ8sc`!@v#6Vyhp{n9 zyZFX3K$W1^<A~01Af|R>gw^}YKHqL^=8GXw&GCnWKwmI0cCIb!g*_9omr%D)L;fhd zU*DhCmF(u#bdWwwch<N#)pGlFs=V<_zF$Uq4<fOxMlsK)ao7uLlaZPI8tQRi38n1) zWFkg-=;-L!wZ1iA%UNuJy5s%#(gMiAVpaI9kEU@b)vvi7clx^hBK~-Pw_+{j=vZgj z@p|X`t3J`%(G=T9=A2%!dRZgnhz<FeG&2=|?WM!r8tGwoo^j=y-FH>w={}T*d`g<h zSJ~k4mNkrOEg}<3qrLPgjwQ$Ox8nj-j@t-r!{BtjRL?nE$76V!Z9n$as{KS@V<-kK zJd{SOOO=h4S(Wj4Dw~{2nR<M*ncheO?MHDE+tE$u1uf^HNN<mf*2{j}<I0!akwh4^ zD3i3Is#-koS+6}E1qI?nZMUM<`!#og`%wCJ_7810(^7uYG&#AV;qYG4_Y>({s!7Xo z!@yR95YOYX2GBM_ETkU3q3)HpO+Jyy$EWMd=f#*@*XZT&kJ%^I75*%Hz5f2D>a=8p z`8WsFf&PGrjC?a!;icRkNk|{b_vUh8K@U7cRYQuom8)Xf`5BX=+o@ci$7|tDZ16&) z;MO@fQlY9A$sz@<=o==$?R^!S`78dKhU2pLBjmMl^9w2AqxfKuVApU}CAxJeZG9Bq z+hrs%;xvcT2>_eLJkDc}IWrnl$Aj@<VPRq9N5gM&Af8=t7&fzL5F$2-9N()0Q3Sx| z{Q}7Mfu!}k{dst2C{`$?FvCp}ndfGb=y=f}@^g7C9VT{OsXq(~a&xx(db_8PV!_Gt z{W)R58SzY_mQ%82({2Kj+l?v5^(gZ$NE=}<rO)P6b!ZFI?0$yfaVXL?ZunJ3#KW%I zr1iPq&Z$CbuUOWEBjR&@w`x8tKrL)z<AS~B`=4F)&*r*=4Zcl9ty+#)GalS=(SQk^ zOVGM6#`hGx>h*j|yzqS1LVwL0k#8ZBE*qm9&F0wbeN|F-brGiSdNarA>YyIZeJPsW zT3stbkf}_8a(rueOYw4<Tz7R>oWO4<GJPyxrLP~I#%`-W8A<8rl@wNmN8t6a=^I`{ z9%lp*HI^I6t6q5dPBDOIAC~qWd%asVK!6}@b^qHLlcu87Gw>n9>*;V4kEC_o>v`z7 zqJxg`?E)yI9W`Y?!NZo6RpoQm@%~0!L6PA?(!1+6U#fPj3ymG-{Q;*jsX6@naxKri zlBTDpzoz4y@>P6=2N|l=mFPgE=ZQgA%yNs|IVy_aD`-t}_wu~IT<>0u(4&BC>OQ?L zk-Z46Gpy3ONbaj(O|QOP-$lNciyq>L_rH>QJ&VN>XYj#<ka*LO!Ild_W>U({by5 zhPyFhC`G12jK|w`X5#epbXGB~ucgd6a+w;7!0_*Gw^_21R7YA<6f;ZNp<(rivFaWl z(W3HWV#jbwv-yTn$<P^k%{dD^nFQM?K0FIm+snB7U^G%c!Y@eoi5)LwpTg{EiU1hI zr3M3GpJ7QxU<<f;M95FR36!_IaV~i_{PrjN*!^6{_expmTv`S&Cyp@5^mM9h)^^>E z4@MM5>(<cLMhj-7=LIRL6LA<{lzIXs*jGOOiqcZVfVoccjQGBnpR*9Jz9=3<2Lou{ zus0n0X&=Q+By4fKN{hq@T)&V&2vDTCki#@ZIjk<U-_>0x&eyM4QM;d1i2>+CjTWzv zqhBKbK1p#=ed}skc|OQGzTPg3V0Jw8T|n?a3mNw@j=tVCbRaQL{0iEfc+j;dcKTV$ zdK9Yk5jt^j;QqYui_(y(P)%H1qU6{Sj;qNOJT`BsB9)u+FYnm60|XVvTUw?Db0eZU zi};Wt3%6n1d}9C7k=|lc45@-^TN->Hc0142ssX4gvoFq@?g+a{29a=Cc#g9QdSge+ zt<xsPk2`}m+{fy+s2hnoUTXbTT&$Wk7_3fgYc9DjTbLcN+Nh(C)?+A!pCc{#aWA4| zoLG~1J>B;DlQc^QRd^H7lMEgqBFK=cZs#3DBDW*B#&dvVP>Gs$5=13S4nx8>AOE(F z=1Czg2sK)kD|Gm<xlL`7uvxcpU&@@%Z%XaN*rf^wsjMC6sL`|<4V3{vcvo8LIW6!b zoIFXLJoUy}^<h;OaRa5AILhR*1)K315cHwwekZLV<GKWAk{|$kIN|+vt;@j@18>`t zA7X~mRXivK_!Ot(>go!}9afPm<uW=-KYTICa3%j3c_T^^f&xI@R>&1Slv3qO&~9@> zBYUXg#UL@`^n5+mNu>AKL`cpDE5N)O<U2h1@dm9$(iz8_Fx_(A&Q&VW2k)`wx(~Hf zAeXl01RLDLE@py<p*nw&L&!#mP@(L{E<-aj@we>(Sck<@=<9^OZ`vN`GF+_G+w{!& z?X*Hm1E*Uuaqj*8%w#&5)tSBAqs3Wg9AETKP9~*nE}^BZOiHaXH&`7%=cYx0WX`DB z)U1-AtX%lY;t}6(F*T;blHBZ&&>GPDB>kyhU6Q@`JR3-WP7_E2UdfUw+W&NOm`g8& zk1jppep;sr=yAK~f`QqBGwb2}$+a2qu{-6vPiHb-jo~uxW6N1{$><zrlM_fT2BeAa z+^*oIXv)(<+OCfwyKp@~6qLN=*RGiH(pG4XaP{ExmUmu`$DP>SVA6;vxR2z9+TDWf zyIrA5ap^oJr+xIp23M12tBtnATn_vg$IdW_Sg2m)6h)E$G#80ceGK$I1Q>LkGmLL; z@V5etf_M|aUrw#P5k%P@Vz3|7XR4GEl!KKgellUR=BWZ=mnRoVcAF!Qj#4<)T1zE^ zkk2r?aUERwo9G~aA#Jk6OtX|WlGjxy#C-xDI%{M2{V-q*D6NXPf#G}b#dDYxxH_qs z2zn?{tw0tN#|^dfzHeEFf`G#U&@ExWce^j@0f$h$AA}xf3wb|dJXFI_MPL>HOomq; z*n<hVVDY?PF6~Yo7lLk!)}PnzyF;}s3vYK~<)FJIHHYD&@NB_G#ux-~xEEfk$|}M> z39<9NRYd~v!2sr+SCA{Q@eR9+1@OT5B<`iNpBEP8O`;5$*V9<Ynl1__xa$u=(kb64 zOIt)>=C`XI=aIQiP`4fl|6V-Jkl@=Q09jW#AkX#E<{{VmqpZsUtO4P3seYD0rm_p- z_;g)?{UzH3@BWLIC-ur_4%+WK>AT@qM=iHZX3rVZC4#g8%`{o66N+THW0HeMMmFz~ zhrg9N4)WYk*M!)1yiHZwPIy}j5l@uR%axu)DC?b{CV{-4*02m<zy`nOMK?TFl?qNL zm77Rr3JPMWt-CIp6$Y|oRkU9H)KxQ*qQ<zcPXDMA;Fnfi(%H~{OS|NL-UeA^q(e_r z(3;klQ4pm!AM15-fdb7pty?6FVWyAD5$P?Vdy1pTBboTQvIl$wzS5<-4+BG4`%F+w z`(lgy((aQXM!K30VwYB(o3e|4MBtz<c(#biaDZ|$ZNsGN-N{lmA`J|?#CmbA{y&^C z(AngJpttJZQR$ARc~BdfNxl-cO#Z7EBjX|6?Wkz;IOBrKCEfPd{LLAo^IP}q;HE|` zHB*qnZoY4+_T8c)wpwz`8&6f*QHrwXafb?R5w$svp{`M~`uEU$0cWrSwPKz6Vyo!; zqtKmFA?Ts3HL~Kg;@KW27<u0#%QEu7-ej_m-l<HH2v9@;XzRg7;=jBB+vabrgTkBz zv)~^T7Z+!-cu#Q(YsMaa9Px~g?9@Acp>I*x`8?8DY~F$!g=s{BY(|vY+qXVn5R=#z zU}QLJ^>vrL{jniG5%>>Ji5NAwDRLL)UXo626k}qGA`+jZBuaW$wQEdgng}6*CBO*m z0p_j9x76f^LWx;$31i6mFZY#5JWVPM6lo1GAx$J91usT3VfJIyP=*m>+okCwLc?)b zt%N+{3ij3MzDJYm5%Q8Yuc!rpm-}>dP~zePW{V|T3-gshve(()J}NI7><BL@JmkHf zP9NQ#L6vv?HFC7_2dt@4^3obFR66Ppz2opcnbC~bHQdXRLfnRZc9%5{w!C{LW-+dt z>jWlt`b&At-aA*@DeM@=kJ%P!^V3Gxq(4pw1OB-b;K9Jz!!L1_2H4f6*SqcUxnBG} z3uAZV#EApm?2P>QtS53cg=?9o!W)ga=hIO6%vkH$Pi101e9>sO^h%Hui)h;U^198` zw?EVxa|k=Jmnglz@V8CqKmj4~7D%`BvYcxG95Np){fKQ`Sahl|wf(;y`5)WSvK-b> z2dlX$XLHx-FLS&T?dw;NH;plSYGd@b4`cH|{{w`Y*8OWK`{F;22M{jcdnQB_HD^iB z<CrO#QS-Oy02)}7D3OfHZJE3C--84Vg+H5EzFRv3VQtEKawX$C{$^PdtJc`A+~GD0 z%pcKcteCVdzLFdD+R~0j*kbK3y^KYYmXkK;DV4@sRFAGlG`+wzRPHb$GjjyG2wQ80 zrN)!tSJ#JW4(MGr^^G}>VzAw9;{ge(ye~$#5^0fb?H^Oq<|C?*t7xtVCT>QYGNeBm zNCH?F2t2ph%hE|ZcwGD4dav}~BhvO`d^?%|6`Gf{R#&EW`q;K<nwtrc_!0)T+c$$O z@0zZFWkVO56~p?4KPtO4O|iY`Sl-z5LaSAtn_okE8MFUDX4^@BC=RrswxZ!n&$;a& zU(hFBf2rP`BY4CZh#0K5=Ti5&WJDfuB6#jQ<aE!F%6MEsdmOTVsowPW7Sp6*lT94s zy9=G5O@G|wB;Q_gRE<o~VdV(eL@dz+Nm8g(5!&(CH*l9n;icJe+DvM<)u_cWQDD8J zs+gxEiSzB3j@x<3*DPw+J(eHDhu_7U!R)dRV;68UP4pO5E?qNf4&xdvpA4^$<1S>_ zqxB321izXqChj;A9{@}_KT(MWW~tKQ+dVojw22U=p;g`}-@ns-OXJT&b)+(Eo1e`= zzvC<WD(4OD7@kS^Pc^~w_2bWijj_(`pn?t8g!}sx01@gUL9|a4t3v&w*w;^_bI81F z4M%nKAAnHjQ1QZFAjlt0`+rdC#*&u=zHDJNf3Eg=w8T-L_V{V9=E|>YQ0$HyTkhJ( zLe~vyxjES97Tf70hh0t^4Avp3bg%ib>7^w%tUxM~MQ5-2*yAWh$r!hFbUGWCuVuW@ zDv&(%bV|R0BaVaaJc!r23?Aoho|U!MDt)Me%Yh}0GuPT=#z8D2eU3$y)0<%|P<sCb zAzSv7A99d3omR~4_!A=6o}`K0E8yWzZ_8skRr-Og*W+B(cDuv!k}t8J{f;fYzEoBk zx>)F8EJP4*2hem+8oj+d+Py>GOa1uqqj674>(MR&W*}cGao7(EA+NcalUCbRt(0)z zDIED=es=cDA17xtg@sxOKpSz0rL)2z#zm2#HQ=>pJz$9S#x9lGuHNC@1s&Eo%n*E= zlRK0j**Ainkx!FAu10m;K)OlJcGr{XCWOysvWdZWn0dOqrLG=Y(;iXhh%`O9823gb zfziLbnpW<8jX@JLq*NgB!&69}tSD2Z#!<5X@A$z_Yq_WUW7j4Vp<X2KZOo{bg&ymr z)|F60N=nKka4ND4&?Kl*p^a}y{>)4bGqAYicqNW^Eo7{$tei$;zqY!HcckX&=~+Nu zS)0d(ozPiMJ6cZbkzRXjChE^^MyPAtp<JQ@^|_iSDWzNj-$09Ybc=k%XaQqQ<pofm z&(Z-}x*7mQuYMgleGcq*Vb4y!%m}x|$wi{`w)+ek^;&V9`PwD+$oVI^tz9Z5nx3uX z%=max&PkvWFt&QjC4rTa`tE$V>Ci9CXe40>WFoiJx0zR%G^5J8t2f%{b%tHCT1{vw z>6p2nu@Zb(mQg7qnY?^El=F@eLgD#7&iC%Y;WFK22Xfb?goK2Cp)ykD`CWvjYiT5D zY2cMaVOTw)TiKqP>R}`rjHHYkfDV1TBQd%7=H_N1&iRq6qtU4w|3UdTkm=TQ)kF9u z|1Ve#gaYCV=ZGn?K}f^kjL>^OO1VDnCNfh2l1E9~>+K_)tlWCNhH96(x7b0u*~I<j z+w*xM2)Y8a-?yC)4S>K6pU-*mtw<=)jhf9V5lh{Nc|}^bSWHa?xo*4hs!aF3c74^2 zvihd?VU-~7Td@5y+&TaTA#{XMLp#o-KMeca0unS}8eEP?yP(ahVsnn`!uO~ZLJ#Bc zgF0aoEjO~O{+Gb3mee;2$J=nVIeAC_8e4Xy2w}@mlg*F~8*Cuit*P~5MR__+#kdz+ z>Vxd#5|POIMX1h;;M4s%{rcNo!)}d<mkKi9i_PQ8`Wptczzws9jA}$x&G7^KkL6kh z@sxFt7${9!KdA+o#MeN0Qxb7SC?<VEg~u-S)wC3Spv_Ep?Oo_`#853mi|o;-?vIcz zc!kXS1-P%6yWkBKo~IU9ee_-m5u8U~A0H>Y35LTh9riGfCEQs|+%y{Fr^-3%G1jkw zw^L6n^{RNSTQ3VnlbI=I2o1+ps5;;gTuV7pEF%(}FSg|f(&xAkaSFY!Zsf(<pMReZ zn`N@gXoLKcD5bAT2apT%@s?Djx%(-0n~4rpnd!K!&TFoPnl@cf*?eEZst~R$FHcOF zVi)$-mq;B^l9iRIcU3!{;_*Np_f<{iE6r?+`&ko((n3_E6-AnjUz*dhncd6fz{oz| zyK6F+vz4go*=vUT8FoMHmPXs&sunmY1IX%&V?`{BZAxDoMIF3s=y?5MKAk5~)UfWw z_0abAbX-(jT^;A7-2_$3{3Vf~>7^#5uJI3ybu^Rt<{&9y6g<DUm_+Lae353YZodem z&#OhtbEuT?9RWczVsdG251YW5N0!}jIhdhY5R{ufEqd4fLK}GxRojzWR$CU>fH5CY zx)7p&`!CEViTid|iIPF1-NRLqYjqaeBn^#0gF;~|ht|_B@R%Rxi`jk(=V4x~U_0E@ zY4a?_dE7W&EzZJlQ7^0G&6HT73XR+X%S`rMuPbaAql?utF6GkpbI~<jJ7b-lvP{(4 zY@AiYP-%v%naWX1M+<LVtNAUbzz+w=<VM?e?1_WCx{LW965^>tQ20aUXtS_Tj8}`R z?m1UwZZhIlkE^c<xxGkL$CIUQfWSSEu4yMmh1skOPY8%Sb^|#ZO(vC)hhfI&o7<6< zDUXg`KBP)3Oj)NHc&uq>{|FR*DlD@JU5L-!6xHCpU$yT6@TV4daK^?fPNyqwr6~G~ zs#dE}{4g1grw*@Mcz^DAm(p^W5=r(L<=d{>`;wSu*y^E^%B#y|w=+1~@&0-q$Gej^ zOBC1qdbc9<s?a@WUQb&zKj0uGjlH5I+poX^2B@9|p?8Uj+tPcS3li>z`;r!KRfsHC zdE?yIqhWN+CgX@Mt4=FFh&dZ4+si@DFT<S@+xx=+A2i=Z?^J)t^}L34phd~TX7~Fi z8i>Ai?&q}Y=i9PTZpQ<e(Ic1QE_K&Y#(_c5_VopXFUq)(U~{|JxHNZF*MjiEQ1pe1 zn|wosTD=eza$;E!is`ROX5VF={aN&^?S4&ncmbL+KR;gph6crX)fUM8bdZ}901yqs zBHrEI)x+8Hg&}~&fQt|j5y|oQ;|Ae!-AaUFs|gxb*gK;j&^eAKkfQSE&!4))#4@V* z>`@De?Kk-h@qD_SK2hr`8b8QZtUKCtCBAQ=-)s+kM9lEG8e)LrH5^10z$~3S;C4D$ zjM@Vsr>JDF)wlB+Qnt3XNf@oi<t>H}7n?bd{@f26{(8%&AWS0DhY$+|=iApEIjnoA zw5YM~NL~jLs{@4I+@G*tFM4b%teSQ)h;_=6u}9e(*opNi-iRR6>inbSyslz%@I@*) zw}D=gAN<}yk&6&{=;1;`)(zj!*(MViU4%Tf+i;vr%2LT+-$CJzJ_c)ZD|oXiQ@M0b zmRZIloU6Cz^>=8zWVj>-JwcbBd%O&uAL?_(BLCntfo@Lgp7();wpZjl5zPaN=tt!D z(aiznkq1{uN5<!CZAKt$8unHLCRV;Mu>wGFCe-2eD(H4aOsC><M(fB;h_&*AQ4Jt| z?qykw$7fqQAFjx<$u`8QVO=Ggp7}HkLYUhN{aJ3y0!Iutr>QthCoZp6Z`kH41fXxv zbMLi<L&{g*cciL!quvzDt1G+LN~+^GBprYFBNDO#&aF|@vJ+MZGToKk4m>>{iV}AZ zi)v~;$g2CYyplP;xxcyF4G2xZyE1bk;>K7}A9T35#;<ZcLb;wKt9DNZ(l%gy?W1DD zua`V?KY?<+3S7uD5lQC0dpWM2sn-}e*whHPD1WQsEcTDnjsN3b8v*g1qK1cuZQh+% zez1W;H06_S&)GJahdl=+zaVEto|0l>Vr(KaUoz`Y$)tobgSC5Ix5L>4areEHCK}7< z-NaKH_fjkbHH=eYnnktx(S<#aW`ORKLJp`%w~21julbom7)n*OCNGmAoDsY?A8&Bk zpU|G<mf;f&y050riC1iL@os2A(Tf<*``>J}q(?6>ycgh8zzc?zfN`3Skn2OS6hI^X zTJR^kWwh5Xo}U{P_w;&#j2ui(vc^D&JxQFDgy<m3sHvQ;uFDjGnaQY?jm`mXv=~7w zVLFZTnqy(><6bH_41?hbi5$Zh<ZUcY$|5)yrd&a<o5I!YCi7@WDF<c2Ps7qY$xKF) z2P;)M{ye)ZVS^pivP0&LCaY4V!S7EC9fBR=ykU&1au-``cJ!V8?y??FV*ToMb<m%& zOb(B$R!I}x`EhJ?OY>2LbV}>OV8SGHC3J>PK6#R2`Jzbi{(@Xp8Xn`($AiE<Is$DR zn1;le4ude5<t=`2hm_3sVQSJxi{o79c*A12e$H8h1|uMx9){zjvS+76=hYm``e3^# zcb3u^!fDl3OpkT@>9_*LfE}RLb~em&U3*OE%esWiHchp>MHad{NE$hcc(B*8pzS_% z58Cb~mvWhQd?_JuFyarwX5=QMQGUB@hgXl#wFLAFiEy4ZZVMWa;KyG%cRXtyTwrq( z<x3}S6S<%o1rzOr4NDD(tbOATM%@=3xAfE&Pb&n4ko*T3@?}H{Av-e(n;CzH=dPNh zJF0x$Z?xUs0imchFQAPO`SJkIY;f-Y@f~#T2aSK^<MdUM<sfr_=rt$;pZT#P0P`Fj z=^;GMvA^P*rQlQv!-nUN$^LpE#s|M&>Zs3PEQu#pSUn@l1?P{DgeGbdSz{LvO81ui z;@~n1j@JwJ=zzs7J~_38Ws^LOoexR4ThQb0vbE;rE|8R9G#u><okrB;kkg3!W-oML zgOztMC@#g(M6WBIzBw4_-v8Qk(TxCEesBePKU%ijVjy$t<5j`<*jyJJj4Tal*OWvo zMwo=yK>PdKGq5oZ=+x;cAO;I#^nPN(hYKAE!u?rmv8VmOZKI>**xrBlU7c7U>;&}O zC)kn#2XiOJ;J2hCr$6jP7Zwg(Vy;oex4BVCXp(t1?YpX}X;FB(-Nz*wk0+*{d8?#2 z@KB$LkR|Z7zDXQvEh!ndKi1<t#vbPh!wi)LA;(l`dR4qQk1_cd&#_!(+gr!+z3!uF zxy=Zzsnts&zdm~J$dENO9@gv)sd+bw{QP!W*#)^{k+}AGkV$VuwLC#b%QdmJ#W4S* z_BZU~*lq0Y{Bt2{UO=OEyW><i(_<fpq}B5XeymO$b%v*u<U$;o@bEU_Q`*j}?!^yF zQ^b38Me#PDuL^R=96P8@hXtvA(5w5ok(}xvU2SCmv$H;&A&Q@cBJi?lShFj+;O}Ai z5%DCP9$;h3Yc`$7|0@__b21soe>QlovHqmuvO$W-Ge`9mbYNN>KoZL!jz-brnVCUG zeHZT*fWiMXXbU@fO=z=?$u$oyD1WH&74sDXC2M;i62&O%Q~`S0^GGQZ9;J$t^mC=( zB<@nSoPpY0$Ghhb)QQ(Dxm+Y)>V>$}_Jn%asxKAP6|GFU$ghW=pE|)+W(ws{?qSiP zlXJ_Mylha28g7zrvbpi>D~5pW;9@#~mM_I6s=zy`buh+4lw5Ce6j%<r5Q&SE4MK+= z0rW`jE%B+PQQcX+(k_K{B3<@=^@1K^z0ys?qg1yLe~&FWp6zVYOwT*GJi<p%0MoX= zQ%IBH3FMy)oBiq_1Yw{%sp~JszY;e-G`)`KyrG{Fdg3|aG0Axr>KHVq^I`x6e2j=| zu{Bj08M(j0+y=3NsqOJ@4W_=;H|2BK_(7s@Gd%cXHgAfXoPL;=)3RxZCZ3#U0xL6J z?#TOH*07eMXrY!A(<z24Vt$vlMEPTq($kk*c)D<rA>4RI)8$A>HfeZ6Gc!z4a+MuP z7FR$LSCn0~L|8IJ%UIp-&@NDE?5-lOb_-}vMq{B^peWsOq#M)p_ImD}ss9s3jJvE? z?<m=#Y!R<{2N6NbKSA+ov6x0{A@%7hu_G-cH{Ds1t8sQ`fE=b{MvjjsUzj$nq>d~f zUj$mUfZ}F|Q5wa(M~*TYK?##w8cs!0B2}xPRtbJlUi3!*rRTDA(JkA@H_&B(FSiRF zZ!DTMVcQ@`d^{jJf$|e|D(i(bz(kgY=RVWD5RxC&00bFw@&~eW4jQ+<UuV7t9J+IZ zu8BYCI))axo(3z@Ty|0pX%*5@9?Bj<O2g*TF_M{`C7WbOn3*I($l<vavyj+_6V4=Y zirc2>V}mcS-zbs9BsUvzp4n$UYr<>U(ttmXn()RZ4=a}_d`+Y!%}OUy9dZfIL<&Wn z^yRAxOFj3bx;^eFIG%oi3RTp3dgN1j5>$*Tz?hsh<9o0;@}<xo74O)e+E*e}?GWwT z_$@M`Na20|bJksITFLOea0K?uZKny<`H0$HaYiRIQvw*aJ<&v?*>Sx#J^QB9`1STE z^>CNp<?SH`SE+&LK^m6t{{CI!^|<4(IbwjBzAfWv$f%(J$HA<-W9~gsHLvg#HubSz zqbPU0{aameGwba}EPXz&`<rsnQ_ziFgz>4j?8|(95ilb~bhecpztazoj50f1+v{;x z&n?4Cn$}qF=(f0|9NyMctQO6F7Mm<FyA6PEg2U$|hG#2W5V2L^?;$xP8!U)#Y`#!H zl+0U5du%BNyWluowEnWkwwcB^>$w~qc--S@T7lu~6~z0wFvurPJ+Q}taiNxn?1$^& zbCgNr)WkuLjpV{}(5`Nr$dHgEVPy{!VVhA=ll^{yssG+VAtlUdWOIpVq+^1>A?KP; zTi-%*TpSKzH`!@0FYVc}n&{{Iidv3>f@mZauCq!5<6<mgkk70yS>`D~a8IIL-~a6r z#p}W!wV&`xNOhU|KC`v#6utbMs&wX^d4BSKW021(wX5c%cPXKAkMzO7q%Wf%V`LSo zn5T#wSx7S8SD?Cn4~r+dV|N;konjbNoCs|_rRPC)RvdcMEJ!VHZDbyA1<cYJ_m{nO zaEE^wJ%i4vV$aj%yD=BztJx!he(g|;0cqoOc1G^muV_ym!!qxP6nbVz5oTUT9lX+p zcJdIo<7(Ae&_J7V6n1bn3xAag=8%^>BDAklscTjPAK~P_?<FDco81NBTA`jI3d2~t zT5r1RJ;j-k6u7zM7{EJ^E;15h%e`{LrEXKEQG6-Y<)+nhobx5&uDY5H1$lj^8cWg| z8?{%%;4pYZl7fDRnT2$x-~95UY#io9yUo_{<?eSPNl|F1x(<C0F*9b9-L?)t4b0%r z^Oojc?~h?7f87k3y&+Aba3~`t=B@667~n|q&E?22b>u0~f<^#WBJO1#h=IgoQiJeO z#vAZ-16?oj7l}^XsYH#!5Yu%3iA13F&@;n6K5QuVf=FLV!hNYPU~XlepkJ542sJVd zPLto;!!*>^ry!P;z*h2Y9<^Y|MY8{=uxq8}X61=by3=S^3POJzbH-hlzTa&|5fjY^ zK=x@y6b3f?5e354DS<8{e?&Z_6w1{Q0tbMn(&<9*0|s<yW#-#Wp+AjHr9)S4thaOo zI(MC5JLU5^H<fsIjGDUU7bTO?d9&;6>T2`&8yfm(1vjhm4!URTUn+Cvb>&Pf>n%CL z7zfinylvD*dn+S5*A#N_3eGEfaib~E5ihqv!0*N=t_EF-*c@4^u#knkJR^p>?>AQj z7t1-`6%6@0N()5P7Dt8^_+r4u+vZVSHlB6-fSPaUk@wu>Pf%UqfAt0^Fd;F63* zv94LgxT8%RdD$^6E*=B;EXK8FY?CR?0}pZi0Br7yA)xV5srcnRO0=1zo|kciGp~!S z>=$L$GK-LqB#&vME64+ea1_9CM9YWg7;rZ-WsF%FFm)E}@8Ow*XdCSx7>D^9#}CW= zjeXgtNjttx@OdA{f>fz?-(#Q4Zn8Hd+xt5@TFzB<j0}>-@;E_Ho9Z#nZK@jbO>bm# z#F+yS0Cm{ms)m$iDs>>kQPdK*UN9~Z>4-kUKz|++ag9GW442UuPptyI%2AkUfTt_k zhj*I69o<)*-gLbelrK`Ne8xy$=Sv&GenWo{#=EL>24{fn*x8Ry6MtaNtnjpvC#C#T zI7B_kcrTD?xjAMh3RovGQ$#Ix3{(^CF2z$BhavP3uf&<&*HbnQ>tbv#&q+TXg=3bI z9#bm(N<aS{k9~4s22)|8GnmrbewCDFn|)j?9Ott!2GgcYxL&<4!^LK!n<FQ$ZR2^^ zJDwVez`7(K%zW);IcJam(g#m*xcTo_ddoWD-}UPKor1MjVerJXnoA6cezVF19ahV7 zV^AHwd)$nXuSY(L5b>-}rbxSGutbde)+IzS;u%K64>uDJN;FR4q{G9*k@4bx2|w-; z^JdR8n_|F;;NZ-a5BY|_k9hZu)oW1q6d`<g8jCnLr|K;fITo5*fy)FM89~ge+D<(q zokx8)sCF^+B>~0=7%aFE8Y(qkbmI`fZX>|QDRJFH*tB6%%??D}wnkbTmh+fi;i<eS zS&&vxYwV-oL27LL`dg15ac&r=V96!xVR3*LWBxh{*~Ca%$MMDb7i7xlAd^4(_^{uZ zbn>R$z)Y5-ubt3$+W-xm7wns<bv(!3tE_FK5U`oB(&H!4y_@vI&O@TEMH_M?NHlzw z{Z)i{zA8lD-|)Xia%=tTyP{u8V?|I1ro(JdF^)f7P2Z-lo=O$MMH^$oqF8g+Uhs=$ z?EF>^JN${{|9DQ5a9q$vt7JTyXiwj+M%Qtu@VK7Vchx=GAg?5$Q#8wZfWuCfTIKJ- zT22f>xNMO&n)Y1IeSdXaJz`1*u8~I=MlfCXYrW;hX~}AqA-Qn@nMrR{MNuh}9Hm$Q zz&RP!#Ma!0jDq*`vlM(nS-I-T%>5@1OPtJ$r+(u@Wo?Z4hPx9rx*i~M9M=S=Iw-tP z!P1P#kAV4|<z-Gj@iKHID$-v3)6A3f^_4%?1$h<E%>_db<Y(dF=fT?IIkY3F)A1vy zg;};6)^7iZRq7U<fSLAfo08mK5okU<J8?0uT9akySHEcUt&1ozx2;Kf#x{39+0ZL6 z(YAu{?JJS*(Scr1OxeFgI8mWI)g<UzPMD@Jbp$hI@CxG9sGuUu&5-jlfdVDZaXn98 zhlj3c31H1eV##ITQOcAhGY~^X$)tj~l6+jlAQyW#bp^QsX8l+iFZe@+fQ=n}kq==U zG#@vB*?~Y0!|C~Gx!+{8Qc%B`qX18lauyvu?qCNZtsqqou8T)CW&lg98GkY-%D$m3 z6{rKcB#<BxFafI0unT$^#Tmw<=8y21zLJW){9?1k|A1m)9b~;a0L8IPBSTQ#2;2k6 z_Vb9*hl$R%d2sajKaaV8Xf5e%%T9~reKOsEu>l|Uu{GFqKg<_DFgM!r?VWE*;V#ht z|EM0^@2uJgTWhAadp8Bvl>O&Y;;|rcl!I^-65eObtNyV9`%b%IrFJw7&iovLL*yjz zn1{V6gi9)FT7-14_{gqqyf3~UL<}@k4e<TVSQ(bY+NH{UmwDq}8SGSs?bMk=xi$L4 zymH3?h%rLNaUX%gkqv0dn(B+$;S_969O{~QC{I^(R!uDa!>_P~cn%Nq2f-^sI>I3{ zG2UiF%Mtz$w(Mr6gX{#XjeLkiF96_&h=w&Mizx8ypV#mqoEHO?K8*s<u9V=R1w$Wd zBsj6A&<rS>WigxI6&Ki)8f+@Y+-O(DIQ5~wK;uy(R3BFULgCyb2RYhWUm-CpyZ}yE z!j+t#iX5Yx4R)c$I89;$SrQ!Q9K4JVDddg^2S<ke2<>QS-{J<grg>E=)YIV#kv}GO zp^c36`jbP4@;S!J)|Vh#fYWnqW_ai&c)a@9UOh(Q6+Z`*D<1zUhs<pJ?sZuKG#b}9 zA38u2%5N@L*rNx~7|a7ym-dRyWI%Uz1SEyk+}%!dnRlKEQ<I1j5?7yUJ<bMsb~Zf8 zQDye%HK`oKMOEs4i`~i-Pq89{TP3u|f3CjmTw`+F<6d%_RZ*`9-L2y|{}q3y#bLK~ z#$*og)`HRa0z6Ojl7Lt$u{eUnUUXaJcRku|>Jro_KmkKt7g4SgV7<ILZ3J=?ZJ+4* z*NbWF@Loq{b9o2U-S#Hu9^-5;<r}ViLH1OdN&yO$+o~k~qDGalI1W%yHFchqD~;s7 zxVi|)P1kfg%+DE-h2S7MXQ#D`4k7#y`j+Te_mY&KLs&4DWujeHvi#N=>V&%NCuu$9 z9!M93m7algo0&*s8y9H{=6P!339$*#t%|C0#6k|GMJd+xU&Eq{Ih`mEncxV(NUk+N z#01=*tO>5s@M2Y;O{d9L!932ZZp*FR@Z1R8uq7lg@yjztpk`*Cg`xHnmwK=t#r;0t znCjxw73Topy7wQNe4u6w_ym*PztQOex<`7jF~GyRB?(%H_a6J{PRL(U-oo7>vW<T* z9Q!`s9pfIEp=Noz6paq@J}G6Ej`mi$8((5aZa<ssM8h~#GXB=bP5|MOH-g?zmi@}w z3DqnugWXit+r0gWp<d3>cuog;$=E2%s2Veu$WX{0W)$-gSJ?)rC*Jea5N6Ozq8RfR zrn3M-K=0Uh9yvwCQR!61-@@FbS>LhBldbkBLlgB2WaQ*5X5glxMyDE0;~XFyCN(p? z-yVHmrYRXj#DsG67UMpenWX`^UBD5xepx{D+<?t+vE$%j=tO|RPLN1Jn0>Mwk8zb3 z9{o4i;E)AIrlsuKgL)wlavlz-074>@*tlO)w#RPCVV{!(0x=<6rr?->b*N&b)s1*# zv}&z}_#;%|OLw30Tcxr4FS|Y<+M?>gvI?g_JviucXX7l@F{x{(bKvYrFI3_}-1;~B z#lv`XMl|>KAnLU;bcWJIJrZW#Z}VpiB?@E~(Qsno*=2e?70KTbJYDo;y@kkmkw|k* z`J#>2(pnv02>I8=Q!?Q({R%C>_5XaE1P=YK1H$fdj+>YqW1mcCEOm!GLvA}I4R4cx zUuob`jqn^lj&#SXYGD^(6=h2A_Cp#5FAni7kNWi#yFK<W?>q?Ie=jlgUh+B#z95-h zYq6wo{}p(%_dMfX?seGcxwF3@n*jO~B-+|r$5sSowTsaY<4WxI{ImINDe$wj%knT) z>^)f?Q?aIpJCi`nS}V^DY>xXQprMGPo5}~gb9WPE=#SHt8lC8#uJF#?d0M+i&pNYO z5XQsQ6%(=R@6Q6Rayq}LXenbz$<L_XJv<6D9cP5DL;=PZSuc-#C{X%ty}m6&siDQ) z)Be~`G4qbjJd_LTyc*X-I$X%`M})(jL?$ztwWKeWsH6ltA((PW+WTFh?O_6u&HOJ5 z#_jdU(6vjDDD3jb-Qm8AB>s0MHBeE7LXJ(tV-2f#SNS@*R%#uA9tF9F&w!Lp|1b1X z)5gS_wP;V`_S^@|Slcean_W@0wQNs11cRe~1>dG(93NqAE17(;h2yIiJ16{cr1X+p zg-o=6b}2w_9lOmt4tF7ZN40~!A7fj`Bj6>zMU}cKSg+;{zqv69!nVW3!7(~QP!d}A zsq!I2!LF5h@|ie7V4u%81e%qEak1ZRzO3E1;}XChpj5O!9fh^8nmCZi;h~gCXEW!I zfBWVM<H_;b+*E#-osa<v@x;o(8{pl?xc?ORa3z85f);)m3FD|OX+%>%b90P(!p!Gx zj75qKgf+p4X_m#$%QQ@bg7gAiC^rvk^<%Cs?a0+!g?TdQ@lD)3YkZCHDf*4s&;7)i zAi_^4VQs`{$!Y&hakLuS1*RVs(HJ1*`c*&V1HIa&i<<MQ)3%^@D4h+MHehF$*LZ8x z76mSsR*A21U?a4KNnMi<0~+FVx%nsj0Md@QP`3Ux1_eI25)$|S$JJQ?wY9Bn7<X+8 z6t^P9p}1R1af-VXg1Z%WcTaIC?(R~cXmEG;;O_kCxu@sc`_E)114EL{+AC{)-@Bjp z-9-jwb#mC!G`OGWy0tx9Qmzt9)3YbA5tRgB`J<wM1@B4|`HMbqkKLLHJAR7M&6o(0 zfbB^b&5}3Nm%>mK$$KY*ryWc~P4FtJQDzzo@2QLu-8cQwa0dB&#p-5RwBTU^#2k3; zB{3T|p4A^tqhCts_{MQaU1m<MJ7Wf!wB=~d2Npy{cF;PHjJ!caG)B7o9y4HuL1?Xi zk|P}_N+iDVS9V0uYhqjs&whVI<c;wvQKJ2y-`fq+v2OxLs7T*xcxIO#UJDn%BnOCl ztMV!Eau98=6@BM_|G<a35^Ll6pp{)inP$)W1V58csvbeWL5HQ2vG#DiPZ+{w;jy1U z2GigDN-RA`$uJoyi3-7<g+k93AZ!R_sOmG4+8O7#C9<;idBw4Jt(RH7@QpmL$1yZ6 z`~j~WIdVS@$#)81^MGfTwf(4_&e2cCr;R*%z|hZ(>eb^-e~wyRM9a@Qc6PC7`+7wH z)1;%R>ZawrGJq+dXz69@QUNb&>09d|zp<%$U)a?vt}Gj79=m8OqdqGMqf5eu;iQQY ziFp2}bIYPq+QdnrT3`ghlGdllx6}YCDz@xzu`+Ykx#gjZN{hheB;$GWeklB=X)OHg zj-v(wGE8~bkGknK3Q@fJerdPap0GLuV`>ABBa8j?&5J)TDuxmT+vv97sFq+I85tJ= zM_dNE$KsX385x`s&ZI($QJL(jy-`GT{)oA=L2)W->C<2CUmX)aVS8QIJV&($lLnxI zaWS>f+?EVCCOQ;?%c47N7VQ>;5Z{NqbBekbdnjmE@GexE`gWcxJ5f+=fp8Ua4>xY8 znbs^u3~(ck6W5c_#l=I58Seg2JplBA{VL{8_`}Wn)1+ql$A)s=c<5}d<+B>na~=sA z+l}nEIo-VS{dmups1eY$@`Dj#xHAg(QkMWcxWOo)Cz9<ShsN*oBBLj~ptS8|%~hy~ znl5p$s5e*;#tYa4?J7(kF30r;#9&<Y0o^cYUjW*a7@o)==*m)28M9gL!QR_Xq#~qY zu|Cfcr2C~S0sZNZVkDP63GQ*%(`&)Hm$Uq9ANWi@ut${e6a7H#B{Bw%;pzOuAS$$Y z3+n>0pCcmZ55m560-nDD)(fvp*&GM26VDnLy^em4<i$AFm(`B=FjP1my#tHdy%fTX zX|)%b4Wl?B7T+H8c2LG^$-Niqn9vE63A(cfM$VO%zPizSO^W-(VJMZ4`4olaL!YOu z8aL9VK9^5yv$uh}HCiIHiCxpavZ6!4Mfej#1f@X|=b{q>Gd|b*V6eI>Q3k(_tSXze zdwKl%hJ}T4KkL(mErCGfvbMJIg~d@nV<l&RcG`Bl4BoD^x`k^UZc@VH3RvA(5jf*W z6QQRa9k*{dFX^d?TGJ@$x--g(5k4AkpxuzDmL@1jW2L5TQN2-l%dh4&zhQJ?VdI8W z!>IH*pFH9|wPd6|&_q$!q#}M>T9=Y5RZr`#E-Al`Ws4d_(kFjS2tnBTxS5{MoIK>z z1=9su``GwW^dvTDHti!n5OK?Y4a{tM*L&ONC3%-L67?H2Fy800kGP`HVaRmQ);?aV z+L33oBAOu(wBsLX>UfO42)zo~G|c`LH!{(BwH^nM(v3Ia6f)j*Su@PXq<6GnQk&P5 z-ZUUY@P+W4${WU-fCiKyj@?g8g)F~5DB=chM%UC1fQ^>8D=h5>UTY*3=+JBi$z0qb z-fck)evd~frDFm!G*P5rU;>Vz4^bC7bIXpY*8oOd-L0g+e5%|LMY4PFl1H<VMy0wR zve44QrKJ8RB6^x#R_pnRpsUtqaUYfmjRkIEdt23p!!$#Wjz((F`r0Zz4>^MJ0imQG zCvC0}AZ8y(g8xN}N7lIXHC(KBD_PFqzE^;SQ~0Ju%t7l+iZHJ%)?h5d>;2R4i^z-G zTh$%obZTm*^MQho;Pmy^mrA1>8;<E@)>Z9L`FSYK`5*`eHv8DDzH1rRWW()P$CkX( zG_lae<q8?KJ91bPgETFjAG!;Q0o*U#?d#V2j8@vCab}X4%y_%0vefHUOaopJ!F48) z#Uj;?=P2zl4gwG6_LY@++j(lu_KWgwEP8&#+lu9U4{Wq+%=^gIQgFKsq5{PZ@wv)+ zOu{cCN3&M4Jlf?uXnQ?ME)uNdHq<g;>c@K~eKF|i(IgJ0WY)uIYUcTV4cG@_#)7_! z;>)hSGyY{Tk5p5mK7N$3k?BZHxqmXd94#C?P+T;G-hh%0Mo_9k3h!o&99aK;38Lb| zADu`Mx|?eX>~Y-$+5n~1Ks0JDr3F2aXJOr&4jcB7;UL_;(9uvJz2NiAI+l$m&pB)Q z*YwRtT0W+t=)9W70gFd1X=#u6WJX4>rj1``n-1q&nl{2@Va`@|r4iaRPa&zyc;>!4 z26t53nkze`uNOHEv=l}tT`O@F!wJqq0lm9O!qh&$(&D&XF3wdZ0$I?-UyN+itRv@) z&RezP<u!M2z$W;)S2CLs<=TWh5H5B1?d(8I@Vy2BsyxtL$2DL*&Nbh2^0_L_vf3e! z1OJZO7{ryjbbW1>D|;|pm&hU5&`89%^tfU1xbfJ;Y2vD}>eF#Y-n|vD(2^gesma%S zGxs<%%bIF!r`t3rnWpVV4X{st|IIN9t;-g7geMm(u3wp7Z{TZ@_~XWFyBVPLK?Wl! zJ(pc%r51h}|A3?2U7Uf}avPFkN~v?jLPpEK@GgWSj=8IgJ~Wf9zH=&w+Dac@SXkzD zeI^zodvgBRH{oIlVK~)Ck#aL1tFC*Tdup91zr%cZ-U$}9dz=%3EEmHmrmpG)7c}K} zb|ictRH1NEQ0NmwRA6e_^<ceAl8IvdfLP+z7=Ga0Z{O|~j_=q)tt%Ucd}d%?Ggeu= zvBt2)y3QN|1Pwhv2weQ&0LSa+6U)x0so7F*sP!DsXLqy|)zl?x4f)Az^HkkyLWs1Q z5?@A*diITYr`G`l?sokooJmYxb`}@Lzq__U1Z`J+kO<+Mh2c=fdB6CuG)X~_WCbWB z7jG3PE`!%<<S{Ci#GF<2p}^VjU8FbsFzAu8Y<K%Wr}V^jI}oY>Sp6fa?vu3=R_i@j zx9s60@p&VuO=jE*#kKcuw%JugpBQ9LK9Ys=DwgS;&bj>!7bW>wTlgp{G|XgQKaN(Z z$Cms}|6nn~lTp<1z@iM=Hy-RY$<(5kZx&nO649teiS4B=>C3anGe5>In3dB|R4PO} zG6S<RS6iZ11JQjov|N9!r)>_!Xm*8K(JO^WLq0#tiR<P4JDq0yut=td+m)W(Kn1MH zzWfRG2abHTWSMEkANB9)lL+dg=-@tb`CueW@)lhi_eJIPEVwehRmj(yq(dK=@YJ}; znQ3ckz-v2>Rx9MjDb`)~?nBXo?f6FAAwdXJQ-2-;`A$hq8jiGnQ%t;X>aKgN+YG#X z^BeFcg(EACY(`t#PIl;e&QC>`9)|Vs(9Wt>Yx06|CiMJ(?|bIpM#5%`{r4!Pf6Agq z7$>ROZI7p$v~lOtIAVX!7{l(TgxQa50$mZ#>X^;BDx3az)f0?)04C(3OV`o(ix=i} zg1enizn2b5r#C}RN;^M4_gf+?bNG0!9QCs|8Van2YOuWB8*GGGR7kseJLMetmyKyo z9NWiaW|k{Je$&_(bymis>Ii=`ohO1lxy00-p^Z@Z&G@U^@!xnbrf*?neUZ4tM*VwB z$_U{b05K6bZ6nHtk|C<(@V8muCv_0ik2eV4f8mWzrD96WJrL}-^Hpgk<{r$<qmvzN zdqX}js|EWr`>g8p{^uoCc&l7rES065C@})~7w}*2(CaU3XZOVzHx?L9UfSxd|J0oL zYoM5XT|$&Au<}n9!2i<G{FE_^36;&ws^;JWSV=}k#@Lm_w%puCZtXrPZjH$CQ-}Ze z_Y{@JOhV*#AE)UwbaY;ayqAWCyfRlV6rAPzlvkT;MBFuq8+iQxvF$6LpPC@L$w!%+ z*{PYl(Bhq54x>avPq81$DrLICg*h?t(^s}y+FSP@eWa{Vt7mQGn3n&=wX4a;o~vBS z02~p^QtDvGZ$84>ufvrzx;1CV$c7nPUFta1^bjg>QH2(fu(Hl)_LW8a1wDIkTqzZn zRsOL9bK=7#I7pe9nFTkX1~lidK8|91L=tmxvEr0<OfNO=8}vlQg3jnSH#eV4l&yce zq&GNNd!G-sgZzJVJb%pmskAWW+~$^+NjUUsfp$&RY89$MoBiU=2vJc4scEIwIaj7i zbhz>wJ@?LJs1@YJV!>!r1w0kasS^U%)sU0?mpMWk>GYMdt40xncCB*36*vz<e%&V) z?=XNao2^yOIZ6oCmggAiWGm!l11t0{4>Z=rooY(qbxr?sCVWN3d^qwgxq5b$ovejW zzkJ-h(Ng8p#Gol5{y4Px4Hd@VE^J3T7ri_E-}Uwl0!&Yj8C%MtR|;Ql8`Wtn<XVku zYnSj(bqfR2P0ha#4Duvgg4778Q*q(9RT9qvCweJ~_kgy3&#m7F{)QTcFcgr8XSC2k zs%9X1q=|zBGopgJ^{J8I?{8m}ushb?{m<n*0MsW@>C4E<xVVYaUQY91foh5;(BNPf z5SfBm$mxG9A+~S};#reMIHD+$+l_l|H%8BoO}`;_VfA@q+B`kdp9WvjSv^zIyjL){ zeIHKHXFU|d9Unt1?1z|Vcp)wfyoVmUO_uOfv>Wg+Ds%}VQHiR`K-f0@r9TY1hDfCw zz%1nQxaDLJ0^oi)gV;TiefEBBeODt=vuJZQ5ul!=rtGPXGtj>1g!7UF%FJeXeAQVD z%N!c5_~TRb^&lU6Up@F!MN^X+1Y`yZ>6|0-9E6B%FP)@QN)UNfE;-z!8)Py9^6pjq zQIZ87WO?*E+VZNa8!TInobhu)BdV+IHBPS=&j%y+@n50FMiLv%K5qO-uUM}jN8Y^^ z^AU3)dW(8>F$@EJ@b=2&>R{R)0+<gHH>{Fl3OvRvxq-{h7c43OEMz21i;9WxsJQ*V zk!23+-Vb)KK&-^7rRwAmdU*z&zgj-HHeZZ^WM0z5?96*T5N`_t2_S#by!1Uw|F#ml zu&|)Oxq%NI=_E6_$s15pVnsh^B)#kP&)I9o-a8#RK=Y9S&rVMd0=(PB^E)2nmhM+u z0H-mXzscx<aS0;om!>n^yD@BuKxVWy?ko7a4PZOP>eDl3LZvEgXBmokoJeJBj!cI8 zHGUJgd~tge_#!K59EuS~u{Az1Q3^Q1e!P{zCL9(O#TVa%PH1Zjfw<iyQ*!NPwWEd) zpArE+qg*je6}H$e5K=f#nTttqJ3%S8Rhu*>!Dq!D#F$MIMaXsR8Kwjr!tRjI6m(AZ zLK@UA6Udh9-DmjqsONd5;#)}q@$!=QKQijp*W%91u*$VS0Mvq;mPv7SbyC+YY@XAf zuz*yndgP=0!oFrqf8y9>Rc*|Fk|S24g~1=fPNHADGB<28JV)+gMqPfod)Lm<<l#<c zoS#c8ZA+}a)N4CD4YPR#A36G1#v;G2R|D_6G#xKkY=uxpCvmNMC^0=heU#Fa_75!3 z>wuo<c=2H|6{RLsd3Cnte*<!Fj_?7WpR>7Mjt2ww#tb@Ng*#mWsJbT$+8DH~>*|;& z8|BT-OSVJ%NaG<;06zoAoIR+_&z^y*u(&wx;kZeQ#AQve?ki&)xfWXDN}GFdXUo%e zIOt$E&=2aSqN?f(IK(Sh9W1Fe(obea0x@X{&mmwCy^Xs%TIBLD`_bI2`8zQ};igLX zYhplu(w>-7X1keRv+cU5M!jWI1Zjuo=WzZcc$rjA#wjkNGb^LZ&Go&jSv}zXWI^yY z>{OfXJ#sVGiienP=9L>+v^ozWCJ9keJK5N!kr_+??);vpW;=pkDugm8Yi6hsk%)S_ zze2r>)BP|yXEDxYIa0b`iNvf`FGFhr0OV!SM>&T+GuVY(bS^}AZACNH(l~zH0Wo(l z*tA`#(qaPG+WduIHvh90RZ5cid<h&)nFZq&y~X7IdiyiF3LaK&f@7~yU27H#EqQ>Y z9G{exJH;RtteH4JH}|HiI&WPJmeXI(C3uJdP2uCmo)okA@-OK$5+1iM_}r#hay2tS zqSMnH1I~*!%=C4YCwp0=`h2FRWIB{{h41P*;v&K#<odsk{aAbBbFpIHd4Fg!G6sEj zr(lY3it2Tyq*3TkcN|~fsqFOx$_$3lXMI{TfS8IG3gk~%Ds}G~=#2&w3XCe+u9I3$ znw6gI?=oS3#@L<PHr$a38)ij`yz7g=|AEOR9}rAIfMyMebclr@(R^uQ3Z!m(<oH=e zNp3C>;|^liC$cN*M5$TgEm>DLDY9G${EP7m7eobz%LN#G;|gIH{=$5{AO`-_-wu_I z<8i(z4acu$5gfw#Te72wBrd`$E}Q81oR;59HS45)1I0m{f!atc)nu{iu9@z~Jgx^t z1xQi_(FfO%jEVqKr;K{QTOU{q3RySDTuTV0E>G5h>kP?ZF!_9YF)G9iu?4u3)z|9v z)4PqCC9jAS{)s}EE5z0>{b?`+NuEI6f-D`wk4(*b6c9pQx=WFB!x1s_V2lk4rCS)Z z)@n5H3ZKm=ywVwGyULQy2mLLJaKR0|(f$Ng^-V_bV0N&l!p>+aO@ZgeC5vsf7ZyDo z+Eb+%CJI<L)oJhr;@zM1ZPkAEnAh7Tud64q+xk+ieBp8sI$(cB1vK!R@NEWq?79oZ zh+zl{7lTt0kuZ}=UcB;%`1fNf)AY|NF+twe&9Xu0`xUq=cIU$t-WvHu0Ot*n_^wH4 zx8}u1EbhH5|E&R<%&BeaZ}4%w3Ad0?145GgLJ-!7=k>fq{VXCQ(N&sLCd6VPS~wXr z2gz_Tf)H!x<I!I1F(d2U!5~?#<u?q`F+88Q$0bOKOJn&CE5$xvLt<J6NZb$K$7q$N zLAXPQ(}pPMc*tDGIyl?x3w|6s`i(Fp$v>KDEm}3CA3}zjoH5`U@($?oEitPR4CsMF z6qq^95bHtzQj-IqkNDeEJ@30(jSxC%>>vzc0wYG9W_EQ4$jQ=sKgr&5RG(@aB?g%- z?T_2ch^PzzQD$RNTFkqNo#nqP97_VE!=~Mg!PTVSDJ1@oH6$`pT`iht=R1qs_(^If zKrE?I%xJpwJ#AQCkjOZ~U@g3qW2EWA6bLF@pjdO@J$z4XMBX$4S5!$cp<@^uaTG_r z=^EL*#fj$@z20-{<67|U{+f_92G1iBe*JcmL7%U^CwU1_&ZJy>Im@Wwi}Ru<X4BD3 z>hwk}nao3cA0yW)ZOIf&K$Lpu$nDVX<@+q2EwDd0s8n+~6FAKgvIsHu6CA7^&es4A zri$1u>XPjtu?~T}L+m_o5r`~A=+pTVu9ek6l217qHJpTT;T|OIridp+@QLpo@^>Lh zUS~Qag5(p%ByIne#NyA`4Bk+$(saN=#(OUiv-pINx<7gMj;VVt2YpqYNLQ@QY(hA< zx~N@3_<7|N)K}T|gn^kYHmy#3XooFUhznyaSjGq&7%WZX^%!C@d&cACOiXe6w_DxU zPu!<{;ohNFS~triDT>v<3hmWmdbt<~N+F>$rPE%TD&|9e2N8n#%7IBM9X<Vwh<7%| zT1i&|o!DDg=0Jdt97fkI9=O_%ZCS&|Od9DY=Z{YVp)?t}No56rz#2L3Gb3VUkfYC5 z57V#&;G6=-Orr=9dxo6VXGj?2rk3x3STcQ+uVoE{q%-mC^+%riDrGOo5Jh4jN(SVv zlX<8Uj&g6J0W@EIrnw4f<o_(fu7Tjg@tU6cdB#O@H3tM8GP)o?<95EeO~p`JCxv82 zC{WwJ88$P;MVUW?;SxHQHt<P;;k(R>m}XxTG2sI2`i?2#PCuf_)qGSH>F%ESoxRmv zHkbNX)XjngGb=rdT|};yM+o=3=>>UOL({<h`bZ%VzOAId1{kaJ<xkDY0CPEic^08H z^wS_spFf~=L-eJ>j`w&b3P3EMDp%#aWf=@dkMyO_s-bNt{UWG*-CZh*|Dap5uw6>g z!V!H*hj)xLi@6*PNPTHI#w3NuMBqNVl|-G4C6`au=>u$#yX)`UiiXhAZ!2G11_8W2 z`K#A@%|@}x^zRD`$DC?V_G-<T;aQR=4u8OX{nc;fi04O{CtsmhWcGQ0O(*PUAIgS^ zw`{N1+%IgFuf4n=LhD8mIf1Jw798sy5_VGsb$?{Zp03ZtU16pp3<dpF_mdSi9b+Me z_K3-wBB-vAj0!a9-5BwiU<%Un&<OVZ8lssviPGj$D}bvn&jux|L`#hWL=<#`=p2-x z0b+vWW!y=7Yr%rXMR^zN!QmHM3+EiJJAK#^9$mM)Bme1{^fx7Zs)E{ye+>0GE(N5r z2C;a}t4|Q;9aaJoJCW^q6hqf5m>&Jp>?iEbPb{9vM+HB8WO^KizYluxw_l(cMY6b0 zAyAsgvIBxO1=6T>HYeVx1h=sCj5bg9Q40~|D<@a4sx+*+ZiMy$ZUk=P%Ia677=K(r z=Z5Jf+C!GQ{>|to=GLoGka}t0(PV+5?38;6pkBnw<@jdHTPXwRT{x8awAII3*TP*| zQU^WHe!7_-=@ZMR`wkMEkREVU;<A{|wcv^zwhdLfohw+Qd)5AMjB4|9bM!n`P0y7B z3eK#~%yFjqYnw^t%x_y71C9QR>P(I`Bm!)Go7S0REs!x^-o=5GBHW*7V-!Nt6um=x zH6ZO*n*LG3=$s7)SB>ZhUC}bCSzAZR3YcwJg}R}kectO9#uVd>bXWN0hv=R0u$urw zZUMtyAZ5p#Uw8%sRfvwdW@XS41yBdxw!h#|J=kuo|6ZL}AdR>?@Xww{s}A=TZ@)&O z5IWe-pS6H5lup>m1x!Z|*Eeq1iy*y&Ix2)$4<smMwo7|DItc=%zGZn&<iC1~P3agz zL>vMQWjbNIG7%T&#TybmjVG1i?i_YlZlRDIcC_3Q-O72PqBG{+s%hI7+?npFGk*}q zShX{n$*iR3A~*81?z+BR92AtVKmYX8>jBaJerQtOVqDSw@QkJy+1;{|DVtg78zBwM z65oNMdqa6n!hZ7%<ss`}EdpH3Q3{!X%!L?>9hT++F|$IITyQUPY~J(NWFtB_p>hdR zouH}VX*}SVNml?eIogvthH%@il~nzsemW)yV9THPij=r=ZJ}Aoaf|A`BUuE;Uv-HR zGlQg0e-5(*Lp?VyM$$-D2jhpz=E!zjJkJ5VujqE$R3+Gy5^(sn<mX@Kq3=YFC8de9 zzDWzJ2Mr+JoyuKq!!v*8!!_8jMb8epRMcgdW@z)7)6`_+AohoO?)%SF&(g=v>d5yl z80FfOX995jno$wh8FJ@RnQy7?h7HArMo>oJL7*QY&%%;6CFjIJkVLVX$!M(X*RP}^ z!Y69VDD!_Rkb7xdas(gohG3%WSGD{UY&n5Ap9McUr?CinX#3QCi-CdaVf|c99rLKM zs;RA=fGknp5{U<Wtmotud3iLcbboWSeC($#Fr4JWqFvq`E0fw91yDqE;Mkj)ApcQ! z%FQ4ceKF#k!D!7XB%O*Tt*gb)*Smhkvp!%Uy(#f`S1*g{JI%|<tkX`{+9&do=@?OE zE4-+d2+q6Tzc@%)NZZ`0B=?6QWp^dkMbMXu!5960Er$G=dNPlLSD=Vf=B+RpbbyFa z4Udt&)kZK*2=vR0mUWzxkbSGimBp$;_;e*%Do~a7<vdXZ0*vPM%Ev3M{F0L|!VPRC zD?eoN(MF<gCXcuHmP!MoDqlpSy3dmjmTiu*x5DJl`o)8(lQc77myRJlD-<rxEzY6! z)-KK-;zS<c=unqSOLB0?kJnkm_V&W%iZZE=v59gBw=qKoC6Rc?n^ZGcm9sqlsV}%; zbVRbmnANF1eEsQX#HKI8eZ(8pcY5!Y(Z-43&%a+)y5Y9BOE&tl&)of7YHVfoC8yKz zoz2aMVI*j|eKM_5IG&>kp6^UaQ5KNQhiT~pd?9UZE~H%(gQ~zcFLN5|^^IkL$sQ9_ z0E*QG-}F9L<M7PkXm&~Oa#^*JBNMNDhx%HPV5jg3e7IFd1(?)2@{?IgjElcTF5h8f z-x+oN2V0i<+4eb}uk%pfIle=)S^U(LpGf7~rYt!4S(dq>NMEGUp_wviv3sikWkKmj z#VMxD2)LgsW&(e@Dj7!eZOj1ByJ@Z4rOa&Xpn$e*>=#iQT!;mX<5P#3Q<sduvbud{ z3-ll4Hh2GSyi<8$EO>NHq*L&!7v_g*@(l4iA4&x^<sJ_|L<`ayi&=j-(=x<gmXQMY z{3~a<!=Xe$;-NN*25vD#6w?cPLvEY?ReZQ%0waWHfzXck@FiF9(iTRwb(L3n(ICcm zaD}J)`*1bwcyZ3<;eTFG*+f?9Ok{15(ouF=k4?{Ay-+_$V(1`FW~IU$=jPdj(RZ~F zG{H%6=Ah%T;yido`eW=;<ArL(1|u*`FZ&=-@3MudOu>#$xve?s_C8kOv&;4b74YR= z#Aq{a;fv*4?_nQxHMLAvS1$J=KDwtT#kA6P($_cdS>OtH*driKa8Zd(!Z!Vco@8~< z1c}q;Zu4!cfZ6P~G|@>DPaxOoIVw(v=rsN6?Kc(O><#5YHz%BvtHk!0)4@DxrkAV0 zf!=owKj!9cwNzBf9`a@aJ&*AV_`ZrCAPK@Z8P`$5pEjln!mv{iKrPB90@XfG9}pBx z(=<&embD+8{Jm-Z4lCs(gW+wNpPDM=W9JC8OK!WyFNpkAULq+`blP0hWM6&nC9_l@ zjGaX;tPmdNCPk?yYhhYXRSI8RRkHm@CA0KHDojWEI!JO`-{*O(=)7FGWyHbNOrq$6 z^gWPcWvT;e+A;BuKI#k6e0sO9j?zlYZ31+>R<P%=&?!%(T7>^qUH9I=Jo~8>=wFEc zk!gNwaojLglw(&MC332ZpXLq!E|&g&azybhXMSy4z3_fbAokB0{wwZOc=5NqXBEL8 z^uND;#x@0x*XqP-P7gDdlyz<T28KW_0*qEcWmt7i>Hi$8EGBgCdQQ%@y6ocX0w)g- zE}xmRvoRPkpWe=bWrE9^61Ri@8q8*BXy;NoM#jXjuyaoPlV-s5fH@(SyX`s|)R(fN zqF9o+I7Wo4`0DD3t}i1T|K#U!Qo`MGkA@|dbTw*g%v-d1DNGC;7%NwC&g3ivLsb@v zDhFfWe}A4j=+z{fUHl^w&-G)kg~x3J0M)kR6D*qpv!yAisWl9f;CuGM3XSD{deBam zmz$@#REOBoyEZpf?k~$k*3H1*(mdqf%UZ*xWnzk3F;@Y2^wy@3RK%Nq^ThXwpMIC` zr4xfRH@g&8Yw%w&O1@pfS&iIQJj1e*%hj51zYW&S*&@BQShnSHll%89jhVsOPtIM3 zIet)ak3DyR_Y<DY97D+^EB|NoEAh$3uI$|XV^nlw)=iiMxjKgIWLpoxBy3fWMh+jd zz)oHcA4fn(f994WER4mSp2>%kOKYf@fgFlPCc@g9a?ZBOBuX2996UTkp%Kuf73&5h zXcE!;di!hUP!jG$sY-e+6%`d-gE}6VQz{mrzLdPe!tgHnf2P3CUSDDHOWq<|NZ8!3 z8c5$~ZefuaQ@<zwp8i*Lp2q4FQ#{0DJaE1Zf@LM<wvFMxIeb%8UX<jIk@7Aaw~a<# z=t_vkcB6BmLa#&Ea-28^rBerzNW$;(;>l()V{u+2@BJw#dhSzbnYBi3(DVW;6SLVc z_6UbW2=i`h9&SO+Z58Q0V>+>HKItFb^*`w>y#7Bmqh^w)a`#W!phAd}CgyG0$qno0 zrP}ZFnESuAKcU~P-*ixJ_C_RV*)&PsEEXq%UOYmVyib;;w57K~X-I$;&#q3l6VUIj zFXcUCiq$Gc)b*UeL&DTmQ@VEZdFQhoj~W=<wmHg|hd4+qxp9@XR5wo_(G8>=dFpFx zjkenF2hlVt*R0;tGh>QReKu#(_@wKwees;O{C5rVcg!&v7tFGeM&Qu&e!{bL%Mp{% z^T4PPsH{F|T1s$q@**q@Wxwd%#n7mih?HaZ+^1!?k`7G;2<HDf|4CX(3h-MR%Bhs` z$*CG{k$b@d2IN7%+&-*s-4og*`qLcKfK+GT;xtqd<}H!Ag=wo2@)Hv1y3v0@4k&ie zC#HG`3Uu<ZqeUT#=bC%o>%mS@PYti1!QhjoEG`@#zWP@?epq%c4wG}Vj6bE*--n&$ zkL0*qy#NUnj_DEcM*u<m^i*1yq;w_4_vOjXcy*;S{f9g@L8q~l5})JCwaS#L3zyii ze)81l?Y?tB_tma8s#<cGO=pwYUUs<Af#eOh*zXyTqT$XKWV$Kl%V**uZ9_cU?^_P5 zOLCRpZpAr93!YapXw@r2#K!<4kJH@K{R%$o4%z7G^SLdFz&xaf!v|mCubH04VKS-L z_E2sREj;$9o|H6+aVS$rK3_hS8WsU<Y!hUEN*+A8H*V;Z>{o5|{}P~<{e**o&_=b& z)#?=%l2w&6vmC*|f?I1ouxjcQ-CfOv_q$P{hX_r<Nu@`1c{>RFmXMfa@@oz`X?SpO zMNvtMavNuRqQRy^pQ8;tvba6;L6Dj<C>jawCdU67Sj5avx*@8}eA_d+mHb{FbbH1( z82Qp9=jGHn+WpGE(;pEerSpQ4z5QArYom`em4TH1P=9~9rD5=d{x#;D8nw`U2$KbE zEF^tqpoo;`%g95A!?q69pqW$4GrRuw#gG5~YNnFHEZ3s>m|d_@d5`j61uUIrS^)ZE z7`sqa7@)b2Z(m>b6g^jit=&I&JU_8!AvCC}n1VH5AxQ!TN$_bh9K#;><AnOhNd;Ab zD2LSHcoi`#p7;Gv(fsfEB34!PCd?CX=&#^Q5szo_YN-cbM+-4Y0~umVUYyD<Pn5{{ zj#|SX4{3xZ@H)(YgNJb~(~5liG2L6IVwiDiCc{b09@mad7a52U%^L&wN(BjY+R$-_ zGymcP3*-B7Jp9G6>9F~MNl{4$@3PvdbYJmS@87NMcj(eJWo6PuozQSID_<QN6n5zY zQK1oL7njRvjD8ctEMBsDywqEz({-&X3k~yr{6wqa!U10_QFTb3br-5)$@HLxiVC3- zNsiHlq^AfNQu8JWN@*t-uZjU-*xA{GfCbk|IRmJAsJKjtf}Rikqh4ngBGG}Uc!(fN zrz>-VIxx7#c;J^mX1v{I?|u~QKCp#aW=?X&(?n#>7Ye35J*Y|yT0F6=j%?!pUDJeI z(3Oi-`K;|92SVmMq3g@E&9M})tSl|JQnl~9R$=sYJXcK6pn}x{bQbd_L07gVlFZl% zC>w{C<Lf`rdBx~D<LH0$fw*c#+8?JYq-}JlE7y)1U}MqXxUdG#hd^I?nuRO?003E2 zjBFAV%M+=y|McTHGh@p;BJ$z7t7d8yeD?D>#QN+i^0d@rFzr6xzZ=i*y`ET@Oyrg~ zW+KOV(6N6?knkGOVsDU6qp4X$_281<J(rXEnjQVaGXc<h=djGZ1w$gB_=5#?-@$?T zU2HkIz{BEdVmCE$p){&<JTxp~P+fKZTVBiWt?W+bb0<zeeY^~o_nl^SDKB<L(80>C z`-5AN_$_5a9#<-^n^&{lQSdl8dFQ=^_c=h`B!W|4n2mE07@A^e+&>Ebf69>t$}xlL zFb>5g6SBNkv*?et$_<5V;Z*OExK9|hzppS!ZO+i{Yu8&M??{`?;8pI7q~bAD+U=8v z<hnoK?M`SZ?W?ND?0RpPm<;3rAHN(o-$36zeZ(8YbQDsn&)xv3|Mp$Yp|72&J;|<~ zW-_Vi+^H>pS;Nr57~`^xgcoVM%O~6l1RC#^!)p!BwtLk-9sq^VnKcE@`;G28NIle^ zU5A|rIN3`b(to_;vJAzc-}zIs|2^8vLBf9}OL{yInY-8hgqhD$+OeeM@Os4XRj%$) ziYEEkNr${{DE9Kju$LB_h^bDBNg`_L6C_VouHY2h?fixB!0n4}zhBk{SqY<*LLXh{ zk}e?s8!T-sGT%|IUYq8-NnN)u_0yM`JQogZpBr)rINTyGXRY$DAx%Eyf+GHTg0&5Y z$E_`oH1c~sX!d=!z%Ppt7<yfP4DxekCi4b;#E?sO<mcayQCP$p3hpD0;obYQg9E7$ z4~;4}A<ewp$B&~Cx<@^~Hp}$j3Q5(^K_Kb89Bp9if0sMf5<Y-zNNU&mQ?}(Gi<hCk zQ8MlB<62;3Gq%v~y!OeUZgR3+m-|rijdgMLH^2zoe1I@Za?ozyf`SrR6e@Htsh@$- zcaCgzeGQ2ej&wSm@_iT9aKBhgGxEON?GNR**m7<}0l=>6Kvj7G6M3}<D5(2vShHJf zOneV&+~Dn`C%u92M*Ow}_C64<sL{)08ItWuafwB)O=iYKhs}xgbkB!>uH6y&vcr@( zS?V@>sLZJ#mnS;%deEC#48<t*UgUw)_Aun@z*rO9%fH)c<`1svZk=HfWD$?tyFkYn zX(EG93_QV*o2y{OP^II>u}DjJl#`dlXt&1&ZfI*|s6#y99OVJ8@g&;QUgLRxe$R&? zEM?bE$=Km^88$N;6!QP~*4Id_nUv1TpCMIM@>^(2Mls5SvYr84+yZ|~QFij)7%8IJ zoekRw4Wcfd;H(YOU~*KGTu$vjit*q1biVwMHL}J@)wW=O4!<{-tw@*%H}l)O^nrJt z43vUgu98C1gz>X8k1|m`XaBQxL<!$ej;$|4HR}Op^=m$nRTtaLaJ#JkDX@Hp;h<?s zQU@Zhzw-V893a!Wl9gi3$jPwPBDHL!)LoK!Dr%O|rry@2^PksQi|QY7FU_DTTLm`g zK+%*~8E&znK>1!a1D3lihm!!>6;`xX^lzC@qDB|xnw|~cqzHmLe%%dcE1c0Qx1EQ3 z&F10I$psdx&0^~by+T2*&~Dy3*Aoh{)K=sRL*J}uqgO6)FU{}U)6T8^F|it*9zT6! zxFHB11T~!&^rf5>w(zfRQ57D&EW1`>xe>W%_eip(ee?I{w6xwO=@s5WAfvn9j*@c} zoC4A5k`kASip#(NH6|VVy9#C*PU<G&p5EToVwGuw4(01Ile7_Q@q@z48_L<dWvCVA z5l<rDM@nIi0_e)=x9B<MPLanQTFg}U$*Z;gBlXj7H@MI42(XvkXxTlRaU$f5bU)uF zGZEQYO@kauhaV~o5Kzuszx{XxewF#HK{qf+iF~b!bzi~MX`m9^s4FWwJdvfBO-EnR zZ@FgkZYFmJZ2H5qeXEH`Lcfh1%3#|c!&0KxWZ{4?Wm4ORbLYQ0su>}ePQTpl3Z_2r ze2odqJ3vF>jyw)c$zAsZl@%1+P}c#e;~bQ}JMN#YK$sAzR#v&i`ip(_La*%UT9;VX zQP39`-j+{){=$cHj0f%!zGP&5r|3_g_n&FU2?Zmk$_3S*5%@pV2n~#m_xRMn!H$MQ z>(syR0?GV@f@^L!o`wK*jj|aZGqCsE+D2<cnf^Kaxks!qS+|AtrRoKY82-WhAmQj7 zl4NEROLM@*`9BRTAuNogj!NmK-D0^;M7;`YJE3sNsf&I#x$tITMa3*><~MrwBkh0k zfAuefp-Rj(G|X<*<-t_P_xeXhbxr{SwLVxrg^&cp11?`pqy8)}#qvmTq2u~bVgzFK z7e>$w85|^#Fju?y=UYIyp=*yBHy2*P0ClE|9g#FJg0Qcu^48RzoB9a?C7U>?;!gC9 zocA&>x<b@D8@8sX?fOJ&Ep2H-wz9M&AhF?#I>vfcgyk8-l95KrZ8Jymukh{qBqj)? zShJ56>_B3O6-+g0+!D3vu%hW&%3wznpDc|SpUJ2@F}k5C=xo);t#?uLV_<`KwyCF% zn<$=*kx?QoaM5Yu+j0jk&2{AVuXSofp>Q$Yi(P*FAicxtyc%}9R_(i9JMQRh4fR8l zT_QW`*~iKDc@S3LF29`Nt}{E&0OdM2h|9CCoZ({gEvV)~{nG@qoCSBUtHvX@E*mK- z2zU1J(9~{|(tsNzB*>)`XU9-ZT$9&{2^``}N<@p^>^+NnPO2atZ<l~H<L8Mbj@sq1 zgM+&Fc>`HL-R?GxoZ5aKh+c&Hcp~}8mxjHX&K5&B0G75M?7TJv{v(Ar!a?+c^K(Uw zMpKPjI9|OPb8Bl|X3!;MzC|tJM=vrW>3`Wat12pzq;pp_3OR7|2mvSAyXF6xRzG_K zp!DJo%T!f*O=L>;&v;*`Y^zheWpp;&gn#Dag@sS5aAxGHW6n2y{<o+!MTD?UZxbd^ zu@<n~l)j{uI-_vPPw61d6{t?i{%EN^_4u=nLHd4ABu7t@sR8qcm}_--f1k-Izb2gW zkUtZ?5*iDlq9F7e4_Hv9Alg8(YfG$Ya|QmHePo!Bm#-a9(N8mEG1B?%=KO5l(dp7m z(aNQojthoy&J4LE+@o3tWCR5v=y0`K^R&o+7@hwkS^TbkhY@`-;#K--Z9JzB+BLBz zNCd)iKR?Z#uubO(Q90o>dx}6}+PS&nfJf-8sIbQ~U5pX8F<WtQua;L!So<4TjIiY1 zddWuK8!r&BMSHVl=xDu_AbN&id?GL3Ry4>U7Y1~xiS55DD=Wi!Z~U@r8rd21chLv9 zVpmMp5|A?5_t03?vuvdZ*-1$|y?nu$nwt84Mia&N?`T3aF$NeNu4|`|()@(9q(qhe zjgR45U3xEy#%+Sq^>befhaSAIM_`4E58O6`k32P!0`nj@@nBYj6NxOWBIKyLDQESL zWEEiTO%jh}C5SgYY=fatRB?M9OX2h$bgg@vd4l#0KWJX}d*I2zp+!U5jk}G@YMT48 z=VHB-hezu>b_;50Jmv(G4EHaeqDc(>UQwWs(o7JM(X_UHOyb)~A~`uS@GUq%g<%n3 zl&!aU(RI5#%&QL|<|x36I$5ccuC8XwvuHS;5D&B}8oq;PKE+lqm#y8LX<PJD|ES}x zq`0+#IvQWL_)XgA9d+x~5a~|(?0gv22=XMiaF+F4rS8V&MxN|qy<(w__C!!=+4-QR zKuTXg$IRxf%kH=O=K9K`>rUg+A5SOki@6oTsBv=XEeSfXC7Irzec=9nWQicN+rEWr zEj%?9O;~Y)WUb(KQ_+7=@;Y0488G`G2iz|hu08rbr~W#Y1T*svC3{-tS7I@i|2+A@ zlS3C8MTv4-H5JtX`ZSy`!uU2^DlRKC`N3kHMS%>F&;p#1qhrKEyx|?hiFO6K5k`W% z;IjgW`-aV{9H%!$A>F^~MqY<|VC8&ooC#H|jjq>T#M++w<k=mBuC^%f74I%>_SLR` zfSZme{#1HqCbK;Mbx0cL1={{hTlm)YwuVk;=V`s0IF%;-moH#TZVD-ZU4q>D?&oe} ze4!~!@(8M1mk*)><>g$u?jI?B<ZP9<c+(*n_$<r36NdTwF?I^ae_zabqzbAD3rZuC zmNL(-m<>x}KRS<&jEpy?)7Pq#tM<gw#gYTHKTAOZT>)Q_b1F<KRwlM8$NYjF&vM|a zO-4yVLqlVg<dPXA88y{;kOrv2@doa%z?X?B25cT%w2<~Xnqijdu3^<ftT&2~xuWA9 zq8|u~E!11=Vs|dAw2tm9&~R|5thik`C1=C9jb<!YJAqa41&m976%}0k^nI#c3%_G? z++&fnT+!YcNw$KJVZ>SumPwFyd2o$fjEa|f&T_uWlW>Hfz*_Xp?gd2Qrq;BRYnx(1 zQtcN((x`p9*0T95Cs#g{d6Vpxq1Au7PASXIq|>ZEQ=w&Yg+|J%2r<^0ts_8gsuD94 zf%cw(E&=x8X3^Dmpw-oZ(R(yQAkikr=m66{d%-vXWjrm7=+5$(h_7SEjRaz)uR2Ao zZ3BRC>vm#VA4V40tRLZC*EN#7DQgV-cdXGRvaT^|2!;`$I#Hr^e4TCZaB;t@(<^r- zW$Jx>APXZSV&*@Qd0i1paKd9e#iG%;h8q4fG%^Cg$=W7=sqT*GSiUTOTghL((V)Iv zalavMx(l*+$HSw6LBdZ<8H^t1WHI|WE$r)5dPT<IX~-$tXbvofJS~4}k2&g0cb$%7 zpV0lTP)Zv%b|>9=_4Y*gDA1E&(C2b%GkWlrmC|T+<qb|Dt9|c~+4(wz!nmD!QFh$a zK0}_qS1ng(n$>%HEh#0X7>iGBGV+~*kgTwqGFQBZ?A2k-tt!qEEgmtBRnCpmm2-w? z@0<Oxsvld$V?+X9LlPsSFlwk4o_2+vndax`oiR?@FOt%ndeL5=^Eq2`*_=DL5oKr~ zjhbY-N(nw~QSQ%_rJ_6po}YGiG+1B*j?5bUo`W0L7gi~pH6O+POj}`?zChtRfszp^ z7kPn9{nw^5k!2fbBqAXtS~ks}bZ<v3*Z_m?Izi~Kras)31Rn!M{1K(U7{orVmDX&( zxk9KnC1Hj|z=&faUhF^mwoD1@^weaM8AoW-q{Gy@=h4Ys1W_c48kgt`GQA*pYiA&x zwGhx@L_lxTD7CnOwOgEiA(O?<FSnqeL?OfQs_$1oYLh<#CI?|QjlaL&G%AlqPeBm5 zDSiO^<8GeXcBzJmw6aT#<Kdj7T&7*|&=}LB0#3UI{=TXZ+)f@|I*qsc4o`AXU$|^4 z!oZ~b(?=5T^Y<kspW*pi(}eg>U^H5c>twhAaS_A<+Vv+3G?1X&L@K=sAoP=)q^5C( zn-CZ19H0lH#W}-jpuGqVeqkV9q=Fbq>IZOuIus6qsTCRHcFq_g1Ywmj0-)H~@$)M+ zX$bA)#SCtrryF2Q9Vi?(%*(S+;{X#it+m!{FGj9@PV2=Q<@aoMbE~mjBNS(UjT{5@ z_k*1ih6A@mLT+mEV^lH}S;*=9<<Td6E`vD7qXpR>!+N-qJ@9Nthx07ZbZDOmCl?lA zG-m30bHoM6bat08rxi(^DH}3G8Qp`$d{*?jo^*f5c$9@U&U6?1<5Mb&>}Y@8v5gDv zhuTG=ZJBqZoYXWlqx=Q%@ORW-DJiuIX%yc{v?ZR}Qy3t?I^OX`zi+KYMn;Y+sUduW z6DZXump()oYVDjRZ7mY(#w!NcjUtW%W?C4a6RMz5=)PH5@kg8-vIuVtzV!dDh-B)L z!D=XKESK#H#15)-85eauY5Qj7zTC{=X5B3lLD^g9`Eb31&cuNIdgp`jkn*U#g}|ug zVss4ruSQ(6La5fBZi%Q^wdb2^x9SU(!%quM<Z$HlY9{9Wpy}`WI13tg&3dC+M_(zR zUy=Ri;oJK;>yrUgI}J*9P&AFfK7JwwGxe_mLfTr7JNwt)-@kX?jtd`E%5IkLHG6#j zReW<w8f6{1itFo^sq1ski&TsA(e^NxF3_U9S+srevdooi9HIG!)pQVU!vH(%i53$Z zpWpx)(MNKRQ{o$UlmVe#UX@)H6Pik1T0tu5_NnhtOx^d7P++F)jHxO1$kE8efP7@t z-CN{>eux3vc`5>~5*fBg0dFB91gQpERsQKn@@^J&bYQM((`fD#n{KP6M1gUFzmiY= zVrvoVL&P>4dE|_Lip%YLF*IR^h)yIJoR!IZb5!vMP(^#Tf0NsH#<#aY7nf<#e6UQC z|L(il$S!Gtb!K%K{3Ue7%2}=f<N<m`j>i)!GsUxZpczKCd?yPWS&CFAUaH(*zjmrW zA-=boG*r`dDy#h*5ijsC#aBck8p4OBdVk`rJ7s-4xjjg#m%sdsH*htpOI6W!U+tz% z%0>>1&B)ie%%<KVI~?PDb?7sT16xa`?vIJuF*OCtnW$7~y=%1Fk8ow4!}!i60Gl55 z3o$-EMT_%s<r7xkJ^@V3_pvE)Bm0t>SHvXd1}K~Cy*P@TA1LLk*`IOGs<2|@WO87B zU3|s$WfAx$Q*c%Ca1!qtUbm=csPdr(H4>ITk7QAx1}UpVZ+KS0@7>*FjXXz`bA{vK z)cm^-twX0Xq5)loPo3^3>U*N1+PQDQo|Pt}Ua!aU@<I{?_)~osP%FxU$FbL~X!?cz z-L(}?;LIz8_`}MAf<)6gt3vm4$wt-&{JG6b9KuCI1kd|c2XX>Y*@G?}?)C+~^?U1i z4L2`AXx<sNmhIISH{BK26Uw_QX3~UVt$Iy7p;kZeY*}K7a-kRRuEX8e=Uv`CT4@9f z0!vXQ^6X^io(k-UguZ^S5H1&Daz%1s*8ArZ-dm(2V{=PW=5*gR5LNgV<d$GDf#Dr- z-W|7oVLjTzVC?!~r^>0xgDdgpy9>MltA-`AX#V@gUtCsn@NP^+X8Uwm;f!eO6{GEB z1@fs3HXS$F9)dQ$kB`0&Mk9yvSFHlfP(HK)j3FXc)5VEl$KC_^!;4NczT!=nG-@D7 z#6p0_?Eq1@gXiTarq-VCfy(RbkbxdYl{;5>&dNi)j(h(l_tA7tg(FXNVwVFO`MFZm z?=?;#BSu(+cr=&-w?0F9mEyYIPqIx%JA^VzIaWyEK2lF{#DFsPY;>l|$k0Cpq7NKF zlJL=$#A#W>@*Nq!|B7yBaR!_?R_pigC$&nuOw`qDPyVJy<vJ4~@acReQN7OPN%R%% za)`>Z^^Y#TKeyg1InfnY04{b;90eyP0gtz#oJd6~shqrfrnOF2%rpBX?emqLJGSZU zuEofTGK&GXYD1hpoSH?uGx<@9>k$r>p|^EWkn0hjM_1bN!rjOpu1HOllshd@#`z33 z-gDyMe!BH8&%vAgY@kUi!@&VQBprlU3jjLcCW43g5)<bA#fpyf*Ze8|Dzsj#-Wit5 zt@HV1DQr$DD8|w1S0Ue`f$WlcNvDy$NuuvWwZATu>+m@*WEDU2hM>U~leMz)30JWN zG#=$Mvk8j|Jl$hrh1|<Kji?U^jy20_rQ2nRBPvCXzi-@Ni27DBqVHo?J24G*JH{Ms zV1Wv8Mmz61gmb?{*M8fIAhJ5wR-*3*CMsXqKuQnw{b!8VZeRbjRB*iuoB<t<5_o!) zTwe?s1(@&%x*nhfP-20f6=fWiH88oOxaRMlGQ`GN$G34$)j}5$q2W3Y&a9JCzT3jg zOqP+Dou%|gH-2%^A-9f2WCeb|MggDZ=R6R6g<IaI4R2IN^Ah!Iz<Lc93lTx;jt{L? z?-K;-V-9X?=``?PXY-4*U$;2brsg}e>AGJ<Z)2nf>JNRl+nEncuY@I?3Um<D*lp@D zdN{T2TKSw#jRG#WHbG3H4R-h_7yzqJh<xRSAWlqYf!L=nZy=J5P<arjl-giD|Mj9n zbgnz!{kU0&_uDar+T#`-eK6@;+F%WopC}AOl!tw;{?OOmQRmi3ABwRbeV@L!a58Z! zru6o(!-Shr{JrO<-NIF0&8MX#0cu1<+;6G*JF?@`xO+I=${g%3WFBsJ`kd_*bIe%O z^vb@fj+4=eB0<G12A%pT_%%#~vJa7lJ>6!Z?eGP@4T$LifBAyjR~eAi9okeK^4_U0 zhLltdVyu4bOLRIC)^}SN9Dl^J&BM(MJ3k#09W{jWOo`fKR>%&qx5kAk{lO2%dC*g! z?2W$`sUwGFNa1}bp}V@(MZw~NawPIul-q6LbV$y}$^>#F4s^<&uA8#jrzG;pZpD`K zkLe?or)Ans!%j))0DZiLpRNX>oC;h~zQm#^3LU#nHP7Bn33UTFf3`~KSA}>meJFDW zoJ#bg#TICOSQG<#_8Ictei(fUXc-byzFRu-u7KFty8ZOkx|1mPhW%yS8FFs&gVX#{ zIo^<>bUEVf)~Xe!W@qhX_4|_5heoZN+I{Ti=Rw!mqnWCJW!e_EX{pqFlpjxLGv!GG zWru-?<z6O;hgbFUdRpZ&hB_OMdm2`yYSGT|e-%Gzg>VF2HJUVE>#88P5+QRe=%z=` zCZI*8c=MHj95o}L5}}oRXmcC=4IkkIM%Z*v?r{B|KGPhI4zJ|x=crRD`3Sm<U33Bj zg}O<kC2g$0y$nQd4;ZRWTs)NZL%*`U8KM1nd;NbZ22%#eVqam7Q?sDXqGD9=tx)*m z9l`zg8dQpD<e8v)-=o++by<w?5z^Gkfa76*)`G^b2`3pJ(P_fMmD6B>HLSCL8<D=? zpRv2PM*;<j>CipqfB+YMG9=+zLoyO$E8(u|SZ1khYBy=EldC~#Hi@j)NK;_^LTC7e zD>P*}UvsrA9U&8WvNO8Tr1R?*2kvCxG+=WXoLVso82!-vEKc8ZFyQfxGtQw8h@=-` z>xnPyB@)|?zy)Hch?<>$px<g+`HVF-gn|Tj0C~d}I$>9B40yT%;W}`mb}k(|!ROY& zn!MI074Ejzg3?a&jk`9+s!=0T@g^6Yn>;$iG>T4H8JDaj)4n~eeZf%e;<qsRKKQyZ zF|mmjHXtN)<fMaVg3>*-()2Jk_6fu15zuP;CpWjq-ophJ<_b&K2Uu(=S<5oX<iU~U z>HVa{?cK95<b=Me)+d}<)vF)R2R98BIRquC9XZW%^@jRt+S(NGyj?;vnV|2TNTX)| z$JJSfRn>HVpH7hy5Rfiu=}zhH?oJ6gq?9yDNq2V%NOyO4H%K13<K5nm-rm3Wy7+?& z&e?m<%$}LGzU#BrP#Hz+_%2mTzbdZY?43Z7fY66&dI#w@`VLmi%TN-!W+d-lVc`wr z3zBx;6MJ&iL&ef&?GU4B#obCpG<(7sv`<`k0o|<Mes3^xI#5{1swo_N#Z<@ByNR*V z5c)5WrX5dD{)}ph0t{!{zJEgsFYe!o!C8TzP?DxG8*Tm{p9oSU<H|GhRWYO!mnG6) zb3L+c9OkWB#7=vun4sW$wZwm)F`UJB0A9VlZ2|RrmImJlPSUV?x}XBuika$ta_b#^ z70kcaKv?5?Q=%-%F0wJDiXxO~JB17Ri3<q{>9D$Zsu&a)i}m{*6s$(bh-aaro6?(6 zc4%L42~sLilSvSV4u<dt^u;viw=q&mMopfQ7t3l_-UJuSFk^`mF=EmX&y<~e;6|Gt zR3e?w-+UTdp}Ok?tEd#}ZmKq6409iol?oVl+Yd%Re*8$m&E4=B2YRZ7D#mDfb-2qD zQnalZfmolfC`-6nROz$-UUEso-xi|!j*X#(AfU#^c*0W%2&@8aQ&QTXl0ijkb}lsh zjACU@CY`<o!+Tm7l%wI@Eh;V+gE+mg`b5R0k;ebK`BR@E^s4bN2`IX|yBD&Z`XUrW zx2vy9luBkcNGmLWv#ePlVBkGI%wy(I<*q|iQv4pJ0(hvE(QWsFm7*MtQpU=XT0Mk1 zOJ=KQo>ILb<J{lIoc%ZSf|B&A%FWo#ERE6>^p7yFAP1&=8s4x5{(e7b$QAB)owL!4 zPYSro@e*9i)w}v?bwu3`_UBG5s>*CoZ``fCN8ul+Cj@`rn9~8_jreGhEL^c~H9{FE zJ;Oce4fX~j9i7bXS?Iecyc}CG5fKeyJGZRqBk@E90<Pm4{EZC{8x*@ScKnT|Ik<m^ z9g&sQ7tc+NM1|>$mW4%`nVI<_ngMrjk6qJ4LZXj}6hpXzwBo175Qo6NPNP{EV8E4y zOf^$epS9nEB|pf8`}_L?S-pi0A1@8?O${~you{uBpJO4X`q)*L<bGjW7d6}$nZH=A zEJhR=C!vj@T*mEQH<k1F+u%X-D8c5RDFO_qoC(x)nmN{IYF=I)_74wYW~ofNa45Kx z4i2Z^oZqREl9FvFS=&Yaav*E5jL=uqb{**DZPx2BP0&2z^sBY@GL<mB(bDuit5x_P z*7&$U3#{|WmEsJXV4K^W#nK5@5+PB?LV2Ft8LyC<=ecyExG#*&I(MkA4bFYmjk3a$ za*9&m_jT(GT265V46_hjsf?OOTWLV`58?yaS7fBv+JDzqa(hzDf*K9j7YL;fO`j|i zm$bZ|))*=3RjvC62V>ca)dz7|^83ZphhhQnJP9IT>_QIh`^fno41PEc7FJ@L$di&Q z^=0dO8nq~*EP4h8xdzZdS?`H^`MX3`w@{cpRx!>%_wS=*$4&kPp@1yyF`tYjRh>~Q zA<CnrA|=Ip*?3mQ=l_zkG0EaFb2|lo;c5!hM;0k9MZw=v_``BhZFF)nuNZ$90Y7qe zF)lPA!^>aObpo9-$i-ghufRgZ>YE*Ff+de7EX{L8K}{_QYfWnjnBrS|i^vU5d!*hs zn`CEuR78VghMlrN-MvqfwfM3=;YtzK@ny?HERCP$nJ=Ao5+#;f9z7C4SM`+KyCb(M z&c{pC>xS#hW`~@XtC@ZwW8XF~&c6zWc5EWaGjtLAzY*D=p!i~XTUky~;r0=i+o{e8 zJU)5#UL-zlBMeFF*xnW5Y;-d6^HyB{M6-uH;xxxQx*MaGuC6W#Fu$klO;#CjvJ@`A zQH;L@K5ZOhG+;JsdHhm(T0HL)n}H<A7*l<3YDC14GvKVHfjI}vL;9CM-Z_nwA3f^+ z$jC?>pkk7v-$_-1V|uehkyY1r`_V3Cu8(F%JMe+(U((bH;jSQDVOqIV=cIXNa8-S! z?V?(-OUeu&x7Lch`_EQvfC)$xGh<_T-6dMuG&d<Y7>l_yX~3FEAuWmvC(urIGm~6C z7#puo4v3}+yP&O;_R3)-EWSUr08W!pDBEUAwQ2KZlj)w_*SRpw(DWk!I*IprscIrm zR(n3D!)_*VvU*UU8%`oNVeKO2T~nFpz5@tzd?fKP<YCp*McN!|(BtYbD%q|{%^AF6 zx$%<F;Q9(C*yaZ&E*8ZXRgu=)9_tBmi36pG-LP3*3V;+;*A7y@?584(wPUwYD7X1a zr)KCj;LoI`?;kRKYAn|GFuFVMW@fo`d@I1KecX60H~;j=z6mjEpA#t3M#AkfV#DRx zQ}`_*;jP2zX{F*p({&n;Y(edZWi5v1aae42w6f1`%L{DG#&@sWp3+B?>H?Y>AFo%> zPKdl{>9v2bj<1%>y8u$IM<T~;8SL}Fnp32pAVz`bjZqkH@yunJ6df(CwDa*CLomv) zDkDi#MC(I0G_!X*#<@{XSJyy(I{if14TF+~YhTyQM)wz!lgLaAe0<s}vs8M(3(avi zk0v)A)w{I1io*ZUq}hp-G$?W@{B%B_Z!(!@H;un|`kiW=Ol^HSpq5ppxt!<6;}=F= zd2H``9kG}A<a?U8m3FIoSkdW&^SddunT837Z7dLjWNNBgMUiRl`%bs{NSjcetDi!9 z+FlZINdbds?AK%OwYQJUXL_b0$@hH~W~(>di!xs($)Z*$=p}*aj-|4x`T!)Nx*=ha z+2ieLYhQt4=Z{Zm097|S0tPZ|<E*_M3x|?hC3?c}DekZGlhOE&ek3|>4s%Ea#~~vj z#XUDa=;I2kzp`BTQK;iO-hI|9z(?8NA5!Tt%U^%FgTK|v*h;yZ?j4@uvEqh36PcD~ zMrfXb`X5y<r4Po6Tx~q{C3rIwYw%ZU^YrUsS5G^SC=qLpyTkhP+<50)GKTXQ$!OF5 zZ=z?waUc@XM~?c%X`PVJaMYue-=d>SbuXKTcoL)1ayJ;{DCN0ScZS4Xx4k@XF)Mz3 z<#e76<3Dc*D*IB<_ZG7YURn9*j!qH%s{+K<=h+`0^G6oM!rjCS!BJa@{Tc6j<tl9t z%p_&`h>O)qA`|nU1v_!I1{rMeSEh`@Ol^yokML*8t4;#>7mm`)oJlW<-YMK&6J-dy z1+iMky%n{R|NQb|V3?kHl+OPK(95V=A8sGdZuHaR3_Hao@<J_=*@VpHeITCiSw@R+ zYE)**^^3Ed^4E0GvB&B^;vh#$$d5+7F5PW?_K+35Uo}058^-(gZlZ%?t$KLY9x`;A zOg+~6UqyzB(ibm8)fF0fnvBbANW*QdJxFG&{XOESK?u@&e;8uIOCWf|psk9g=X4q| z<&k8gyYX{G{4)am+de=RB0XY`U?;hr^f*?im{HA>;hXl?7+vv{jnslv&0N`_<D4^g z4?*J3=|ebjo_#&Ok!4i>)T5oF-}+?gkSd$>Cd66L70O1m_JKM&uWvv0S8}eX<1z|I zGRG_3(@bulEC*KkIG#R|n~sKtg>9$VoPvf%#%Uq`Q1%<AxyC&>`OGKMYRJ8n^kusa z+$ypcugBD#k7(GLknQNYxbp7tvQDdmWkoHZ7O3gym>ZeiA{%0#bX<+qEr@=>?$b~E zBy;qE!DaQH<qHnO45uEqIttt0c?(1CyKoIPD^Vg$EYuaS_e$+VxTm{YN-Qs-78Tkb zBZ)1VuhC_Yk?5|TPOoVByb~Ug+zL5N7X&5kv7q|hU2H2z+<!2yymk6!=vgAvIkwh@ zkP)86k^UHKV-%5@O0B|wEWlO9BF-QlZc^lOe_Ru(IulTMhpUh);89J`%uoaw9{nok zBHC3t10!OpMp6uQ!NbW^k}4`cfKZM0S%i6dl)Tw!l{*sxGT{{c{`{M)bz})z)wP`+ zY$@6>uHjL}NHuzGsYoOvb0Rp<qe{Sj^Yt=g>-})~7Jrzc=j}8{wRLOk{8ITUMEzFQ zc?p9*J#h-uipJbFqBf@qq4|rVj<pitkP77wO;33BKfe)48hwg+xq-*Ho8qCD__{Xq zCg`u!1fV|D-?cPBUE3PnR%oLk{+!dJJ0nbtriMTg4Wxm0a3Fl!;Ok<jtIEN0h4t$n zvZj}F+435F5KT!ECrx>|x$a%r?xZAJfW<&L`ja>xRUnP5^>LWdv|278K=Hx?BMY;l z;OB0ylQJ!6!_(DevBs7P^=U)h@iI2Pe^;L_ZoX=_576oi{9@6HzP~red#fO1sccxN z6#!%!t@#yxkAy=dw9*BmO%6|OhE5fJG{?+Jh&!;87qI?}nF;s0`?+oOILiC+o}vo3 z!wJx<_7wx;C(jQcKYOMhe+fm31(dOwg}Xt_2u+L5+<09QftCjhxApGl0rf$(emk#A zWVfT(_{$Wjuw-OwpCE4G=5D)|(;{Ab09BVCwH^P=`0F6@i3;O<GD7pJxc|g)iO~?J zR;utm9oV|?2Q!#c{U~xwI<YW{;iFstXP*`ZXLh~ya1}cB4MNlX$p;FbTyAukPtGSs z809>tL&j}`pg<TlNzJdep8deCfy9(f=9KidtKF!_Cn~$g;)y7sw?g+moKkJE#@ZZY zlvJ|Pd_QME=9GWEzbtJmmfZh_z%2q&|K|!(CUl+wrWxhWrTQ-cBnJ0=ZtgogN7Gfc zFD5k<{9)IcjHZ-%CE?XBC+-{=f?c}ZSk*~*)Hf|>%QQ=&QyF4@1)Gh3p7nAW3>3dT z0?uVhD1<mIC*XEsw>!#cf6r=T5dFh?QSa^&Z0FaDrvK%mZTYVA{>3EgRdr&Zu!#f@ zU+;)+!$Jh4t2dQg3i%#)7?wYcUYGqe+w9^G1M%K<we2FdW8S(CH|YMFn4}$@c-Q@7 z?tlCSA%s`^Ra}g%V{aUv<Pb;gEXaOhmux~4z(4wfys0U<2Urt$W=syQJzk3Tio|QT znO^91(1t*&pt+!-jX<pOuCJr-t6s<)qK*gqKisq(glJ4;WeG1vaFe)`IH8}1z8*2s zHCl@UMOb?Ui@TbQm$})q^<Y9M;H(sF!x5~@YTa^cAg<{9)3ovb*h7Im%H&4?P5H8a zAN6lM4oVPnyd@T4f<OWp5`4_uNT`B!&LaF_82#ii?aPgR2Ej;&;or2m2E$-;{q8iF zdF%b-@zR=M4>$k!O%v(0r08f`hl;2PR)!rD9?vw!-!2ZYI@x%#=jWMfx>7iOvFkX; zH+BS6HD@cWhOMm~0t$)dK?*90q&VQ5&v$0inAeEDL1L$;vUBhba7^%u!BMxA$4>Ux z;X)-O^_3c=5gv`oc_aFvo^KD5S9hHF=w3Ly0YSp}zv(i`bARjS^rRAOh~vDr;NWb8 ze<gThxa_HbdX=qbP9*a75E1bd!K^ERyK#)L;ZfHu=9G_PZY)PKGgine#zlwM@Fn5+ zf%Z#~JDe^S9?qO^gU+HE@!wT8vJFutL(B+^mpCV7gFXTk2KP*Giu*LkHa5_dDQCqr zipc1t+xKvjTN27kfuV9M$=XXFbKU2LhE!K)Q(d?@Exj}B#J)|&@?xTjN{N=s#Sx^Z z4Bipw-M~9V!o?Mx0ovmQ2Jq4VZSUj1dmiBCpcPbTbobw5I=3hcVEGjhkqCM!tDfIm zF9O&#_v3c)p{twe!*oQ$r}O&{@$tPJ>EN2$)a~k{)S!dEmqF8j3FpMIwo<P)hc2*u zPbUrq5^fvJ)}y+t!1yD0__~wZml#(zgejJ&#lJrPpBVQ)+mQ7&uo=U>9}cvVZ)1^X z*cTdN{MV>yJ0-E-;?nULwKO#stkA+GAw)%h3f{dOI<_~#4k6Qz8IZk*t64dSjW-Dw zq(Up0Wl=an`T^)&DNxg8f{k7yX@VQ7Y4qDiF1z;3jKza+qxu{pl&x*&Qtq{$biMmC zUN$JNihG&Y(;&zosAyVVuir8I@IET#n42U9Y<n|>^Fe}FJy#BTcec`c#E2Ej%`+CT zEM_?rxL}I_0^l))&$p|XS9@R)JhE=0rxqXP@nmMYJ@=_F;ec?|@>ve3FXnX^TQF?{ z(W}<WN3L)U!^;xumdDbGLrO+FyAp?vS5(UwQ_|`W4&>QtK4vUmRG<FD(AsLMJGEZE z((|L7=0(xBe5TZox(iwa?0sLhjzOa{QLWR32NH$*rLnVti{Qo*xuY^0)d3Z@^1<CW z)xyS#?ZPh~&r3U98ks3CQ&;uxd$VP|on67jWwK>9vV-+!vGms3t#OPDGj2P`UoK3g z)=e>Qc+fqZ&bJ?-K~80%HE-2uvpS6-MIl<}PB!3WHUn_pZs8D<L#)=FVYCpptV+}# zHH)~#&rWYQ9-SHNmCLR^v@Di2xoF12OMCb8l=B?x_N+R@kJ1-^Tiq5)+%Ic%Zi?TY zUQg|HS#JCat~jev?BVd01RWI7wOaR1hp{g=Tw~np>XkJ5^Gd87xt4o`6M8l=T-9?g zO*G1aLEgQd*S9;@%g(p7+IO@;o)Y1?+O?_t-c5rZ@#p={Q+Y0l*)L<N*3Ud<!Oh3o zL)+K2ME6UV*Zg{VxL{rl#&TWt75c~6kGzl7;MCS8?xw}w1{cp3=i3jzzM!Y5-KRe9 z0B%@npxumHxvcYiiYsf{+&rs$jHRa?(4S|TI&y6QtzOX-b#j!q+Qzu_r)Do+@dtXY z)YRF6n_9LVhA`pK(9sKpr&(N@XcdX1L#OXD2DlHxAYf?qiqJme&`xR7mL&YK5;ACD z9$X&Pb4{kt6-v}nu|C2fKz?F+s{*}cH1^_;_7v$OFlrM38_v}Ssn$!p{_@X60%Fj< z4I~O4*BISa%Q}cN!haopa{Cv)3m$5?aP}`$jxAom@G>z6wL)mD1to*8*9(X~266Bz zBU|XD54CJJ*EY|3uB$i>)#9#hEK&Z6Z5Jd!bX#?Qa%F8psB@hrX2kkwR(=+hE*_%3 z<)CbJGacU&@Xt5hRP0|I#l*#FHI~`_{k|_|GDKS7f5cT`Hga;2&!GLHZxa~FMp#K$ zb~W5i1wWRk)$zx=jFXUFB1L5x&F!O?_L{8y+dy9=M4(rKgW#b91T70&+G*%iCRkWZ zryJ}J>D3YzOGWtNyJ_GYUYwV^cR+`iPn+tgV9nZUQ%PSlq{^7Y$Hc_AxkQu)*rfjM zZoE)ISlvifR$rs)(2Rtm8+1W+cMXk%mU<fLI67_We#sE#I(<gWyxjeYrFtIGI68f6 zMnr_kTCLcII-gDR%79TgSor=tTb@f>?OW#Wc6OMP40LOpNj-VLW8oQ!=ouQeD)9$f ztk`J-23TI&t*g|sn?@!#YfpGcXms8Cg(6m|OG+C?MkXU2<wKKrWsENnVA_%78NKAo zmg_VdoNO2oWs|L5SRWa?9Om5qF(>h0eHR3-IYFw~bz@ZJQ6CImHC!VjA*+`3XvTBT ztmld#2r4R8IN7YKY1P_%IH-QsnnJOgdsCFQBJAnHe0b3{J0rVX67Z)V;C&Z@AQej3 z!)ZOwwDv#|ot;RKKMCTIAcHl=#>Nyvz9L+^s$|+jlP6NY!=SbwI-Bck{k_Ql3Rgd$ zWNVaOf9ZnT_Y<5a&Z`_CF^WhkEjpBNqb=B+a}SqsP}Qr)17BmTu$B42{_UHB$Ib|& zYDHapJZ-UzD}gCG6XMp4?<G<t#Cbmi8;|~q*-(Ch*{_OQblWe(CK?y(TNaHTr^)QM zt{0-Ji>4F`9LlnTE@Jz$gCst9`G!sPw$$_wo8I|HnXbdR-uj%k-JN%+<<jqv{QE9* z`QnYjt-1NY7g7zdkS;F5aIBi@e&L<MDIsev^|Jl0VvN<C55=791jBws2D@i+D*HJ+ z_;pPAu}-`N>SaTv8q+hY6;xeX9jX>3+pOZ9t*Q9{zh<pvvcW=eU4q5lSXs5M-C(|7 zo#PqO#V0=CkXF|@COeSr)H@5_Kf*Ju?}AIfj6}%>iJppzN&3l&J!T|Y7+Mq>B!Hf> zufh81r5J#u0UNh4*eQSG`eq#}!J37GL!Fs<qIww3vPc;+6J_pm4Iev}l&h=%e2jji z-F-=24LUk5H99&vH*@37+o&&_Em!R?5vFZY7g?kQm@1esFfpxnUFO~};ITk1b-ELo zY;W}k3q6{+3_wZ_4$R!2M6R%O-@VTd*|O#oJok4^<g^MF+4DSq99gau%g^j+HWNs= zNc&5?6a@PaEvqX!3-lHdz(FYDprcdcvzNr<mo-aGOis!|V841b$9%LVRKJ~fVA6R9 zqI^kW1n`omsIIMhCrp?{+q}=GNyAvQaf97BPYPv?cT|oenk?J9*Q->GE=R2GNF?`1 zJ$74X(u~YZ_*hsJM4l%tPB!s$E~{?EIu7&Qj^|;s1K+y848b5MQYlnG*VJF}b?|6l zGbAtq(i%C(vVGVP_s76b^-dwO$y>T3;9GlhAI!028L*_Q5{K<PC2pc7Gw1<<D<R6X z+z}+qM#8TqHy!Eovp{0L*`-zPa8;Qy{0*IEy&I(&^aHsi;UC))!q?GXmyNDC(|mdo zw$%l!=eZNF^--?PFtNeARd(bhJqjcO$)4og$3EU<2Je$~mu6#pHzuN77YoR%pn!lu zK<e3wInCa_^?nrZk>?b3bgbM?ALXN+EjIA_MFJJilsfSb3eVRY2Zf9gA3e!S^Sq6J z`srAIkd|JQffB7s<D8$)Eva|6YR&xkV{)*|N<yMwe%rEDqeHmEBxvU2-B-)A)p-5b zkbIeM5&REr10R-K#5XoKkKV{E5%RMz;9)|d94LHTzP!Kq!nhrZ>_wancNJH1sDn(< zjtuYa^r8GSyGokpEdf_TVrj3VNu9ePPqk#6ZR3?x)y-?6l;YxiCiINb->blw2Evp? z$wGhO_pdWI{0Mwa*#yg{8XeGhSOm6dv|E0?j*ku1l~&VISP5Lr25o}4oc3rjpSNWt zB^6P3aK0rbl9Vp~h^jE|mCkXV^)Qm=+XfuU?crJd*n2PMRvr6wQ9PtbD*EW??V3gK zH`?->s88%J;W}RP6lQVNrHTPs%^~C1^jcB}Gqytq0HG^>OYBv%<k>qs(I~IKH&LBz zVrBvm)X3Y7V0OzJ!Md+_d}2Vr-iZBEg?-`0;k0(+v$4rm-?*B0ULY|!Ir$v-Gpia@ zn!ei|kA(14XNzjUZUaiP$x?88rOh-qGIa3N+>}OhtMcT;F!W-*thA&$DxI(d8s2xq z!I#aw1AEjKB^nkSe_j@1UpzkB)5xF*R{2fws!C>63$wl6Dv?iA8&anuS0^XLnkU_# zaQPeyLPqmsF-`Wj5ShK7crpD73k&ygA439Okh95u<N466==Hp)uc;?5lObMWW^O)s zP~JipO({Rk*@;mq(7O;=kjiRWRHEHD!)y9BI=?rP*HL6@QOkf(9bvnqgm*7@gN31` z@Nl78IzTFN=3d}--qR%+Vz~zN<;DK0cFUu4_7973VYrusMir&5(Bl)iU$(!pjKplI zmF}ssb%fnSG;+O67d8<|_*8Gzy!A68L$MQX;qfyaS{~E5;yxe!IGV3bNa)vh<<^1j z8l9cO1H9*92{5u$|66u_-6<iuH5ygOMrn+=$Jts<`i*Wk!QQkE4i)=s!?6~Z1$p`T zg|8oVya;e}327qc{DU0(#tboVXGC7+5k>;)xI&(6I!U7oSgHJ{j@!=sZmxB{GqV+- z$N>TexqyKDL1+cbdmLI}6s4=fN_!|9vXv<^Gjsv`%nf09B`j<01|q+b$TvxpGzL*P zg!<(E1mu*Il0sfBC@Jpi0lQmy$seMnS!Yz`r5l_N7;y1|zPO*Up^jM2SC+HxTw-X} z-O%DU!9os|>37a^J|`^df?=EWKl@$iP1ri!Gu~JQ=(x_jXsk)_zPwNMaH{dSVm7>i zm~SwyeerWyw~|f9U~%MCh<Z8gzzM%aN-ad`|4b{3w^00qS$M44WEG*V3a+W{*T?iY zdQKsresc>KZX+(>bRqg=4qIlhN=Q+w!zR_h0$cIcY44NG^4_32T{QaweR^stg>E(e z(-qHg9K2J;R98qeaCCZ<<0A@(_VS9dOnY>4Y%~}huE95CQFo}=`KA~LCre{gFM{iI zZH$<R|HIfTC#gtx6%tNkW8>|W^r!R(Kp-YJ1ry?C>OPu38N?abW1F%1?6RAV5+<@5 zer>uOxt}P1hQRz@7KV3X76n1<b5HWNE(Gw5k~r8@yxZ2QJnV|-G;5R=EFW0%3Kp`m zSl#EX_Ez&7FAit=;f#j$8<xBtU=H|HbaaZYwINc_Wd8t^J`@V~@TOs1G+kN_k`+I! zro{kOjm}n^E&j(4uVnC-7y|leicC$GbMAm3*nV2ZW||W{J(tI@ooauMY6*B@p~D_) zmxtx+mHh07`2H+d<SnrLv#i&r?dh}5bB1^0d;XLghT>n}P$S?Ypj-}l?2Da)7h7jV z91B8KgN=t&)>3WCRI71TrX`MgmRs%0KUJGVEjb<#;C-;~6GrBC*`oo3(8yN4+q$lv z?tVZmv@?VV?hR;;*L^bnV%iPCkk>}K<`ttdTZBMx5#+0C-`?9TGXIE&i_Y*RzC2cR za3)D(x*y6UR!+6rc~UJTBsB7Z&gnU5f$0UzRz%#slDXGE=DcrogrIEtl(@t+rx})R z{!g0Twt}yRP^k<9RU(HpdF7v7FqpC;9`>$x==q+5%m*WVJ#%G~YxY%#)z)8A0MW6k zcG;66{);d0Tk_ss9b(r+oZnkZ76}Q}Tm=~)$FcAnPw=^1-!1e0_&Kv$=~l&i7qmL? z8ilAW1tthBErXDWJbyC^wFBEPAFcN87hm7%>zC^hk@l_VsOfHCaDum@UdMZRn!UJ< z$F4Oq6S1n)(^WqT+#cj*%O=dLobh^P^J#ZZ`+1Hp7B_^5Khxc=&i?>E^BS?K=r~9z zrKdzVW5-ehVuooswsv+kcKhFOa2pY1e%}K@@j{E0hZ^5!SsUTY+w<K-v=^$3SRy2O z1)twN>>rfdK)l+J9DQ7e#e+Ht9;q)%qsFS>D0s_zIkk7y7UYw1>6du6rJwdKvs1he zpr;Qkp1-L66w|KdlY=}WA?dlyMqP=9C%Q@eg@03qKVS5&4ia2H$ppT{CxOK)3N3rW zqE)lN9XcvXQ^RTisP;TL5SwB|>|6=t>$jIc^u-Li=w(s<Rdj?v4C4i_m*aHx=XxU` z8b_}?H5uAqFIR|XjI8Ln|6}rSDTUAM)$<z;sIq$k0m3D=!pGV6kEm|X#10OHluDOr zf@l1C^bpgtlhZ|MiN8(bH4$>Of5c9ND9u#(cQDjO+`!>qjLq)X6+&{|`=%)4$9KY5 zp8(ew&8d{?;6mw$$BA|PdOQehZDUPaf7O7W17yxjlzDm#eq8vP$UZNS7xB5T=`QJj zo~Q%H0Fxgr)nS28Ku&ZQh@7hEcrj?#*u(+xGqT-Om&_28CZlSF{JQ=5s`z=>%on4K zX2d>gOEtF10N5&eTzCFqFVC-F&9s}i%we;4QAOiiAl<y8I$qx)7j&B~>rZsJRIhAr zv(=~Q>?QX)HJIalMjEEb+vECWkE^6z-g?n*%a|j2I+#u4HiI<;l^krcyZxnCcJI_x z>jyhq69@Q?!9F48ORabB3(aTc?i_vJhLz_TUG|3F|Bw8TlYzQ>J!S4($OV~NHaH1+ z=&DU#^GGq&<#!?*pJemsHA*rRucZeWKkk9(u+}h3g0LPS;&v#$jpl~t!3hVZzA`l7 zgQGM2Acdeflp6Xl7qrWfmlCQHK?6g}o6>TXfie})K*CC*r+}S>dzp#y$soQ8(T&8Y z4eAnhug~rWvUViS5gF>fsKw{=mz$j7^_zX0S8gBI+#fO9ntcy~h*YFow8{juj7$;& zqqnwkVsy!zmUs6(Po55MD_Kli4QPtqzxG!b->ENGQayO@wRO4lQHVX*dd4z3*HkHM zrI-R_f>r$6SMhD5@-ZjrdEj&iwH-1H-y_ZJe#kZP)Dw;t3L=^AgAE8IMr&?PFL-gU z$kauN@zuTqGYh=~hy>h6;UIQkE+SC0#i(+=B-u}ng#V0wX}E^DAoPiDznzI3!Q|6- zRH9(DPddWO5@lXnkb+Z)LZO>zr6c@c?(ZX0Conz)D-v|TmOyU0>eWBxCb#(xG-bFR zRCWi#Z;g(DhCd2ZcBg81KA2kDUxMtzFS$02liLe~)Jfyikk>#4=W;jGm3;lj!z9i? zRGFSuev$-i#4K)J`_zp~^=1#^_ctW^zyV6Jz6ws;k-fI>RT^x)FAdW}hB`s9wjQQe z)rgZ?Zuhe(5|=beluoj)jqFX#H#2*n;9?XJh>miNMr7`4J6ib5*||@t;2O_lwHa<N z1Dn-q@fn+?tVLNTq@p#SpH@M`b=U7ff-_@~o)_Ct;v3(G?VtX7f*8Jd0gx(%W@e<m z+~g2o8Y9K?Y2>Hn88C(Hu0*&0(^aQ<ED3MC?|CPbKr|YXy@VF4d<=U(Jv|*n2Oc}~ zZziCvUl?Mvc@qQ9z7k@`4elkROsrZ#CRMO5!CY-^uSXG-+BDIVz?*EVsI2YRN1j6- z%_)b~E1o$h7kGjy$^|ocG_?QQ067s6r#N4%k(+cY^N+v~YoJG`c(@9tvh)VT)*T6I zaYspI;z_6n)clr5-#~KOS;fCqv+j+^#ZQ0`A>y|$(o!lfvONg2gKr!(x=q1R<4E!0 z-MIhpCidwxesz^!W$Q{gM=dlK_cuqCAq@4Z7;9s_U68`3%p1H_Wf>H{u&dgJ*q0sd zp{_R4(E9LnmFensKUkR5_<Mcwff*oK^Zs1y$o%n-jr;q7$N|0fKValP839G2K1S7A zbqR@oL@wa38T&9+M6bmwv_K0(lK+vZ6zHK|JL)uwRA}*d(aHYz9}xiNc7V=M{I4Jd zbXWlaaJz+5W6S?4VD98?ZvT9;OaRLFVTJ}=<@~Y19lXi?+ZvA)oc^UE{nFMTd?zN9 zsz~4dl*kt(MpmCgZkHOzgWy2@ZH-vO0Qbb-Hs#?83p_zaMvjh*G@xc+p!Tq}iVSU6 z@=UcN4xL$BGoYrS!JyKTAEE87`u%jiNthWLrCdC5HiA%S9)LSu`P>G1>$CzTIqxD! z+S!>?P^W=}^o5*(QtPvypUf*laD1wf7?-P(^wf^ta%0~Ki61#Ds|u_$6JH66>*#mt z|JekB#0vLrYSe1b>)aE8NQemvD5&w!g@tE#jYN{Qa<-;DF%DT}D%1?rQJ26J-PL~- zoT&Op!N4sHfJ2#3SZZ3U@Tw(&L4keR>GV<fjQvs6m_3CFFVz;M-fA2q^Bw%pQs>P4 zg&!)!pNsG%QZ8H)krvO|0%6jme%whaX@rJZwpS2@Ln8zWl1fG_ZfCdZGB3o6zSC3F zE55FNW>Z(rLXbpIP4=5^aWVHM@w>l{-NL3HYDt>ucl_-u+B0KtGD~fn@Oq?uY{T^V ziL5lN>0Y36c8-)|TO3EJa*m8tnoMw-aguWdo>Ydr+^50iy3HCd-UkJ2PGk1E^Tt6S zx4*%{BGKe>!>iT$ItQ`r@c`r0rf-8M@%xSO0$OnA+o9_V@Ph@VAw_Bkqm?-aCneZL z24M<zR>Gf30$^j}tkML>{H@?@5U-Nz+b*o;5$*p7VscJUdZR~pX*AtdDD4$<r&Mcs zejOP4uo01^4N?KYBAmW1!n!2f3dM30hRWd>b08%q+CM9HbdVqcU#vW#0q^9dP=*!M z5AN1wVyVfhbMkG2z(8Er{oX8v#)IozbE1f7ljPrhA_(P$@J78NRB^@kCx|=eG^)kf zaM2~5C~XP!22n+Jg4F4iFq?WAuXo<kQ}nsXuCEip3oN=sJTP~TJV!nFPMR$xV`?&> zTu)6V1lF$D#pTI?SC;+H1PTilR81e*PFD&uhi-!=B0`V@Z>`X6HLmiYiV&TNii%2R zjznoHVQ`+yZ=`gPW#wpW5;HMUV&uK~-25G18I_6c1Jp^5**2EcZun8IdF{yAa9-)z z)e;3pv0tVZCB=dPeem>&!su7%#cRSTNIg=AD8q>+%aX8Yq?qq>J)RU6e7`53id=?R znkoYK*N&0lVZNTlg!p)>+uK`lt*gD{fZ%Rc5iTySv-KeGpzq_o&AkL9j>pgD-9C5I zmEk19AYHVa?~l<D{4vXo&WXASLj?DLqZd_DB7<4R>7Caj1L2qEWT0l4skaElWep@M z&e2Hn6}!0$#7hYY`MN1hRyyXI8Y$ln6Q~d9dpi{CIQ5wH&)_01Wl*PUH!?wI9{nB+ zwC^xQ6l$qxFOZSrbEUBdAFr2<g<oz==H@?L<uskO#>?Em!on`bygz;&R{)(hkdk7< z1x~3lS#4>qISMz_jCx)2Q^VAhmgi+7l4?PU$5rCl<Fz)0j(9@3UbWH)*MU?0(*o^w z35#5G{YSHSH%&z%<xMh(sF2wzBRJpf;+g$HxQVSeTE>|9FEw+huO2KUhlipVY_$h2 z<MoMUH#berYmS&f8?Wnc&pw)NmOWw=8A3A5RG*?}bpLL`m;#Iyc%d*(1C$TjOWM$f zO33RPV~!=vs?L{pB4R{9iVb!Qa$#m=mFZA<BZ$^vgYfxulWLA>s~i4S$BRyPmS-VA zqMP4kN!h%BrGKCA&NU&Qz7(f_eq$i{C*RO0LDkiCk7P8Zw2VxNiHS*{zeD!chBRZe z_v5bjS=BueD@mjEtXx%gmO>D7XB|c)jJ<Xp5q|{#{Wqt*DWNB)Q8!8*hgH)p?7pt? z_vFmX!Xpirv&_~z<y%J)I}+Drsir$WAuAnv^*okokF_cPtna>eWcFPYTB+<8w=c>u zy7FBj>clFF1Yb~N#sQ#d<WiFkqPqNHAj*O4JK(4aAs`1ie?w&p$T6l=I&BNWIll+j z_5&)=aN~T1vN=E!`o|$w^P=^B!J&@?x7^EdJ0HFc8IC3gQpCl+zA?>u1)>M|!vM;Q z!}-Am*Ue=1SUrFZh)L$Dv5W8if}@%EEAw>K>v32PK{a?Z0J-J6GeA#TEw{<}e|qXR z+RMBYY6>T0kz1&-&CW!=&jq-rX_B5MNU=7(HyP{!d#E|P`kFNHLw8yX+`CS0&y#N0 z8xswhCFHDO@wy&LIkKN(UNk$$94=LjdgXvVtcrP^jzI0L=9Vt^uB`e(@W>|p0mOR~ z1&`iSS#N0u-1!L<zAFE5;Y_#Z)l{9Y0-xXJ*8mWDiR|02+zy6kQKsIbE>U>{Cp~<w zQwtV}339>En>|`=jYl3yrdYLGq(n=sU3HFrI42s_;&N?UaRZK3G2U@Hx5!%gg$M$) z;fF<l5_WtZ^`d#cy++<g{1U^V=dCK2%&yt8d=n-j?jdqAdfcdebtD@V*Wd4Wl{mRo zRsZoq<HzB&XS|+MONhyu2tsE^0J2OS!1MJ*W_HR<b<C8v=+F#fCQIj!=;lbk2Xc+3 z;PwlIg+i27W0piMC-+O+d1o>8&pVFbPF}!c8>x4fIS7AhI_w{c%}sV$l!mweMt!ej zDq-}sS?G%}5L0l*lm2Hj7(+mu8miJ-3E77xB!ysx&@DWv)U#jjc3dQIk-TT8H@!JQ zXEsp~SPZ1X62|(Biuw@re8N+IF+sbvqiq*I_MLc`N6Fn8Odg#tqv|^^Rn~Hbl*nS| zE0gq2jJXn7B}S}2oM5pu%yh8j+xB2f48R-3zdZV8x<MUnx>!@ny(sttDg6CeM5_Qj zCS?lg?5b;(h{cwmjLp}F&BT1RRdUQyXn2%wtB>pGmQk;%Hd$AZfqLjRex5)=HM?~? z$3E_pZ%>KW&8dy$Oi3c*hZHj9P4bNR8LxM+K`@d=7QwH6MnpU}J+<(<UZY@S&4OIC z;!5VfOTt}($xwA4-)mMHmCB^P)0$vmHocmdo+#Fp?q^&>jq7o{v}F5dRTk_-Ke@7+ zDVYW+H=I12DUtk-XI40AMU-<vFK7grf{V0kkM|#6#Pec>DdaLmk)&;EF{nobS#a3o z^#n3J-$~aWo)KwZdzzWGIG=OG6FqOyVCC?Xj2vsp_lBo#83dZceeUWK!OZFI7Cl?e zlXV>Lj+gu#+BbFaCL|akK8{}73OQ&fkk7+;F-94HVbhhAbV%n`e(d32{y3h#<eO=Z zXg4UpPn)m6q)ZOuj0gsDSM3f@e9x8y^kXXUdLTyM1r*H&*x3}j(~9{A^gTfr0)jGq zsSzo;RDSNA)iR~qbM$DA{OE@Xu}+8`2Hjl0Vk6Uun<!@Y8v{wc1j^CohZ+&9d3&t7 z+lw-e8d`ae|Jk{CDL%bnn#pF?<ZA1P0pdSImX&{w1R;nD&k8g}X&B+ep*bfcv;I8s zSgtzf{TT0l=8+V%hBD($3_*gYnBTj(AaYjC3q!qO{2tV5-Pu$*5>cF0*>5Occ0Pk$ z{FbfzYb#BLA+*1_yH>-G50h$MkBdPR01<Ai!SbV7&Me(}b~qQQ0tx&M=BR{7@2zsa zEC&<HVj><R<PgjlGl|&K#gI4sRfCI1MEnm^;gpBR?d!uXjE$^|V=Gd|Rss2yq-F&z zDvG|IBkBoW1}%(DV{-ZCqPqOQVYU5u!RosT5@IG)3K7#!pOh2N_u#)Jxwqv(gihSZ ze@)Y`Q)t}aagKTCxy`*(3~Yz=$s6$7&B`)1C9*9<<qp2O(;q{HG+edO^splf{qmnq z4_PMiY_%<?8>&lm8^xUW1>bgMWDz=zzV8w?r~!{D!b=R#UQJT4vkSvpU`c5undd?I z<G1O(=(-!Hz!@0k(4_*j&x#k5k^b2Gp0;Js)d0F_Zp5zCYz@nvzyHA+dK)O`nX7w$ zb+#zLYvb2OY~nfEd7o0JM+9^7G4D*JS|`n2rCch;eT}T6bAb2p=5)Hr@~dD$oW&Ab z4Nr{~17d~Ze#PiFhSF$q25u#!i`bG^MX~y*JAd@YY<Q08ui`-U0oT6GQsw0am-yoH zW=*ft^LzS{SIWYV;M`}4+OlQSu{9EG!pPXzTtBr+8v<@DJ$Z7OqHuQr2WAxI9w6EP zFC5r?BN|E|mz0#85bECj0%YcXXnbVA4?z{W8)NjQM_utwUwS?dBB!7b^*SGWJj*81 zHwL}LWmYlP^QHv~PO2xm-6c}$ta|R+)^CZ&Ti1Fe1mGC7Ve#ey>qXqJavOZrhK|dZ z90Ok`M<Xjb;U$175+-YHLd@#$dbST&+SR!1?mPYg_C0j4%6W3toEk_oNy|1MMWk66 z#Otr6>pe7!>dn|Ell{tzQI4YfQ9)=R0g1DVAXG2GZZXk?=1`B?h4bPLvA?@79y&tH zWepFJ|Ckf%?tqmLe=wV?z&*gLef}_#pWYX`J!lj2AYay?_6^kK>CjJd&|wE86&#_C zqd(u)yRq9&Ltq6YFeB(q{sQ(PY?d2Jzov6)?s&5I<|XXU6-Mh6f(%7kFcV1@C<I(a z^5a@PBJ{pRCzEZ01XXNoQe?O;RWz%uVoUUE#rR4IN(Ni~7(A|z^9iR+xB%g=QbPQ8 zG1v>M3$6O?Y>8%;OcM7p3_~~y5xX#@TuM$w%`&+hUklm*kcGcB86m(5rsJ*to?p~N zv)R8Hi|I4f3A*`kt`?#=YL@@<XsS5;9jd%=Eq{2qPP5*O=XG;4`{iq_eP$1O&wwHx zCyo0B$}*OkbyHCdNl+P22f~Q}oRKUZi_QkyVb`O<M_Y$KZY>ov<c;;1_Ff0;>6_t6 zy+hKYTsm+fkaA?&yb&%PUAhY9dPRV#`vDNFTtdX&t8Q)33%Y`6YDnl#@zk82J0WBw zVaX~+-Kd%DXc}gs-XRL?$b*=&(AwsDq+u0s^nyYv3y{g4qrYiMD5uUKxxItMUTAvu zg*UxE=KGeGMp>#|JAUHtI_NQZIXfU*yY!1pH!7DD^?a+I0}|V(gG>lTIwBUeYMevG zN1sJ1_>O*QOyrL?f@N2mr9K_WHb-<K-qBX;!hfUjjm_C<;%1!Pov8ODWa{`~=<to( z2AFYRVj7>K&~nMpVcx*(&K7}i4sev`n+0UOJixLOExOu``Gfb4ccuP3e?tH0m_9E> zBAPJsUE%WfZ!+J23`mzI^rhsaSdX?@1*<zDbaJsr3!zY<US?rJr=y97hE{}ciBP}j zgx@I7AYPquSQ05^aCot;Kxn$Y7XTsF!5(fn;pHl3ZdJ>t$L=$m@$?koJ;RNvnd<F! z=8z1Tp<cdn2FB4J!$JD`!`{E61FE=pnjq)WFb>L&=i?7u1SPhv4s3%6=wMK=&Zo%l z!&CM!ZTQzH{`yt^Ft<C6rOY-b5Fyh<8t&Q}!n2PZxq~K`J+>39V(?;n6lXe=VC#UP z4~rhnUL&yA>IF#Cy7#D3j^{9#i*vmqzg<#t1wJUYs}gq(XeQq+m^7Xp!jTmy)cd8H z>joFx+STn&3?uaO!ZQ6vwWK18U)6D1WQ$VW#7W{#_tl%$t!773Cz{3OF^dx}h*mVs zarQ4u7i)F5KyFJ+bdN{p{3DllWIp%EhGYpP&yVuE`xnNd0FWY&`TZuh#_F;5tfMh~ zFQbJx6^~vfbc*HJ#PU&7RdM*vSRBPi9ZOk9*Q39l*~Gw`*5{+cHAs~0<n?cdEd>GQ zWa#`N#-rh}LRWXxDm8dI&<7FKT0|s=efv~SsL6fQ1<8(%KUm*ip?{R|-DnwR5sD$% zVu1h@np-eVVDIBWY%zr?7!vC{$;>h;qgBb%yLOxm74zcn8i3o=<XO0Kz(2qLLD`l& zNALOSXi*AabxQRDBc}-TX8zZAW1I+UxSmTL5O{d#M(XH}KDR1SYkN-XaC3q7pp9v_ z^0z8NJ6#fWaR~TAhx;)hn{*GIZjG`zMG4hMj&ij^Fh%OXA?SPYKLpKR+1I$6uG9Rh z1Ysdeahg>lfo3hSG1Io4#<NMNbUa0EQt{dc!f7Fwpl`-E;Fg7QHr(MIKj#yj)_jls zH?2M64hAm_aIe(n-?vt7mJu@GQ$g<12T7nfWg>O72YEo@QQ2z!alm`i1+y`Wdx>!A z5n!Mm6fqFgecAt~m_-UcVx9=Jt3K8aV*i`j`0JMpB|w*pB{hQk<NN%gyEXwS?b0>M zyzyVzfE-YK3mzeiL#HvHDAy6c{Yfm1Y&#`YxYzUmazkgUjsNfGGt4jjTf2CL{$80g z5pk@_omt;Ajpt9_Kp?_!0_qw>s~~H{U*QfgK6*;nSFFVc|CIuPhozwq9JR^~PVoKv zL5U1AAhWf|Y)K>ZzkgIjL*O0V&s^wbXGJ>uH%<0;dr?T$q@|^Eb8<vp-lAvC1sO94 z72OT)hJXCCl>Tb9{TUj9Ww3HsaBw80Y?6eb;ku&mt1MQ4CKJe1Qi!y30|YgCR2YVT zIZ>cT+WKWPR(Olivd{`7fXY%)C<n928lZb#VKx<jQZXIgSH-}?qfBP^q!no1mAl<Z zM!~?wc8>YZSI>w!n)dhk<>a6)Y1I5af6l3^(@4ATWnng&6YN(o#KXX|0<y%}I5{Qs zJhn}7S*!|d=Fd{McDDL}f<LM+4_B$)B7<qp>it0g9(nx#HOL6PfTLpnosbH<<%XqL zZr-Bp;KamxW~+<Wx07TMl8%F0%p`bk-WVNZ(%7sUf;y&cv)|2}I&54Pgx3Ejr;i*B z0w#RMi;by3$ViQZolmk8>gD2Bd!P3~QWO9-6bkae;%8{j#v>%8v7Rl7noswlBj9$9 zVHx3-R#H~pe!N~8e=N>*NpAtFD;55V9fi5jzY{tb_&>dmh5%zFFlrUsT_mnUxEII> zzR;D~AMbrEw%XEdFsb;5<+r`F#3=DAjm*k6X8i!l{z}NzRTE#TLyL=xd$u{q5O;en z5Rc5zr17C~TMU=Qtc3URP#{;g@#<TAe7+$pP%&#ot+VaF1ySr^*1p;x46B+}gho9C z?6+Sq^6*W{1_T8ai?cRq1&a5I;EOmt#uHwZmFd*$@F(;1UX|-q3AtbGQ$M>uxnUNi z52aBV_k>3mm)FZt%D$o1A4+G8*SRCZAA&W2P*+hQzr9VHhuuFysxbP`oCrbm_lGGy zJ|DVK;SW5EF}|hv6rn<+#+1?eJwxG4wLnZnOsdZioNFgK=e(ls-OGD#a5BE4*;U$L zESI|KusB?EuqiJPO~~gy(9(Qwx*fV*1O9S*Zo|jNH(aB9by(x3l`4({B96mSHe&jl zTnK?UMGtAg;BV8x1gK*`^*6%a>}R!oo)>~)?f#D^MPfw?-3IwdL*Dya1p}IxKjbtB zK}vlvrX`jqYweXlogvLqWi1qZ{*Hkh0Gq&;l&lon)L>dxwXylC<8+z}5MX3nT=Q1? zF>Wfl%O5PU&QSkO`AET3bitpdDk?Eyd>wNnLxreet|d?0Sy0vst^vp565^QoG^Fc= zB_Rr;1VUPbm{9%!ZerIws6}6x*f!a+@q<AJM=pC8s`uN@m*1TarzFjWICb4G_sO0; zZYgfJ%e`oqJ)ELTO5V&Te<K~IQ6nQIwGE|HZ^?V75&n0YNn|)ejX9#_jRjG3rwN_) zB25n*6iU71kZGN0Vq?otk?+x~E@I5N`{{SR9X6{M3&3F7Pv;xR`xLsmlnSUMZv@Xt ztF4yB7#g<3nN9auZ`bDqBE#@oqm=Vg&3d06`iM+d%+GDqeE6FitZWW!zC@RXMAjhv z3s?TL9QD9_%BL)K5Z!)NGFGJ}muLkRQ|Frq<IwR?na@wV4GMp_?&4~rUD!H#rS8U^ zsydl>dRDypFp^hx*9rEbZ+(1B-zs(CkE|L^$z;U6X`KGJc;up$AZTb9MO1sPDC^+& z-v+lMx(f4JPul!r4*H|tKJn(y1w~y3i~6iNEnllzj@1VNlgpr0mOj8&z5w%ieOS%G z!9ht$%V<)mTG5Wi$oTqbkrqfc)$-{3Qs&i_LrGB`*|jrldR?abEzhr50Vl5nY4&x< zr_`EI5(w3LnxQ|+5wNC$-a~Ms;GrkI91-{CMt92qhlYmo;VIMtbQ1+t?Wd!-lo*S3 z*s>P)^O6ouaysqW4;~sa?hUu&ixH0$6y0%DT=lW3bpGa5fRo?H>5wyHyHM2L?wrMS z$2|imK)*af=+BB4uZjXg{*%<R=1;C*XEdFxCM1-GEY4S{ja7Vb#rU>QoeAFtx-Mgk z>0}^e`Qd^0iz&*4=Nzi<ehhofo+97pn7^5M<n~$U7HAbnBw7yK%p-#?UQ^j-FUF)k z)zX&5i~o0n!ej9zqp4s@hqe6;BmILUagqRmptQ*NSSry!Mw%d$uV5RCULkv&Ldi@Z z;o#r>6arC2Fyl&D9Y|8}i4Xeqiv0Ppdhe4qy)b61`FHIg_JyDVwnQI&;w16Em!@I? zHq_|b{qv>2&qmw^JOkVfY?j;KEq%-t(cVXOv)TDa(+FZ6NAk2=cS+>$`^jNIfu89~ zA0dk2-2A2`9X;KWdJ}y-8a0=_$HUJ<D%^fQgariD4m1kVw~2`fZky7pG}X{)?xr^- z`#0zo6FDKTUcHi1RE&Bv@%*V3??!j`%B?)!yrPx&xHhvmzo~LgU(e0kR9COIM5=jv zo8Hdbja_w0&8?TlD!YmKvVL`bv$4b~xh%!b3;g(DnLcXPV>z~)e^q6i?Rw;(oFBaT zVOgKw`(DS(dvJf}x->g)8zAiOKgGA$s?{6~-0#rZwc7Eo+Qz(hoGov1r&$0Ou1gSn zXe^QjH$0YlfQzkCpU&#t0gr$X?AaHzHQeK|`10;nS@E$2bVseX&H!#`o^3|12a<>8 zk3E}6W}0n3Ucn^Mx08@ypc68Hc5fWawLW&dDrPh9{RSxvA<QNqpf4pAO2JK|B>evK z!HG0BF_k3C?*Yt6LyU<d{I=BeslUHJ_N`|coK%(uN(`+KPmwG{>)q$-#;lC*K%D4H zR~`mBy55ny#-D+gXnRl0z%He9MKHB80Ogq{HsyPsf7N0<0@v19HICsUu6m(dV8q5i z*&tIeqdO~_E&9Im_sD06!MuCQ)|}+@tiiTyQa)-t;S*A3W6mu>>$bv0Dq|IcLd&~h z2ncZFM*MC|TEmp~!uC&S5umNiX&!_?B&r9b!U;xf5Fe0|6r`bk8gf2_Whs<WNMrvF z<Lx0%g}kr+YIH=w2wYUAj8zM&`k9b*K{<c@_q&ER2ZJX)R1}IR??T^T!<Sz4S@daR zV*_vWR(1KR$O`8?l@sQW(4lOeCI$Npz~|?hbpj3{qhQ%t{*(lXMVQjlS1U{`G6OOi zX?B_~WK})q;P))Rb#<JGC@94$Z`ORjhS)R{4gJJ6oBht{`N7YpQT^~~Ona(ImkEDK zyDtL5iLM!39V&e%pjC^>cyHHv<^I?SoosFG0!x32_Iqz~Mdwt5b|)yAu<{F5<(+%~ z{yhjyrq1&nmavS>SHWPli!uM#ZRB8D^^(Yo3s%JO5G&e&h`SCDsdhZ-cE$0EjS2<n zkdqQxo2UOh>@@;L+#Cb4S9P=avk>l9rxPJHHFZswv*`8KINO`XZOikyM^Ll4cV(<9 zV)Cis?_xc^cT_;J4%z16s-jVlY>-My;IHzb+W<)vPe}tu{6_kRw)eo4CA0IAD^_&o z{x}Vj+Q?$)u7!fa_w8;Iu(23Q>}ab79lh3%@0RaxRYL#N0th|H01;C29xg+-3ZCcf zm}sX01y{KXZNqs_Z_-Uq)<~F*cW}QYCtG)Hpf!~*knW#iS6UF=6Z5CMJLUf%_W!8* z%CM^1t!p|&+;m86x?4)RL8OuHF6r*>l<pQJrMo+&yGy#ezvX$3&w0PUT<jHh%zLge z<{aZfHji?>9FQn$HoU*sagyEOI|fuX0mkC;$7MIK?{*JC;{N{r#ezxJVE(7Le52t+ zC&o>}t2Rn4uXs`S6Pz1T#+w`~1f8djF3;aua62(kG~w=A!_ChpJen&%=9=Ff^|u|b zStniN%?{638XSw0v|*cqb|bdR`Mj^QBQF-ujkgXehyL5>N|cSTzIJ{QduyN9!UHJf zc`YfG)f4iTWCr8&6ytGxjXABijH~{|rC~hErP3#xOtm}0CA{jf#pa2UxCo5}8rs`4 z{Ul*p44R&2c?9vN<zRgUUu<lw)|e@VMq8U_s=MgO*L{*hcfB|lzust(-ZbbcTiu^B zk(dMG&<Q3s5@=r)nO1;XUS9r&$O#+Ok!YDnGU*3+=|nX}P}6K0#)kL2ce&a5XA2;f zJeea5kDlTAc*C~w@W)<z#l#JM>DkX6PJiT4TY%sM>Eu9!&!b{(=bAUj4aGl_N3{zs zsXxKi$Mz>_RtdJy%uc7*^o}R~;R)wK2fIRbkMU%)v-RVuu6y9k7mv$P4kMwNdIFW` z>XH_xp`!~ufA;^1*FXhByl63=qH`)IT7PPFRo060Q7nei1FBtFzTP4D!$$vl1bfk_ zXxoOmsmdn&9*sNlZSh*+S^$)XYvinz#xh%ZKpL3ayiLxGhdmJy5%It~>~}l0y2>>> z?9-H~*G_u68*TW(RymEDn`Oq6(Z^{Zwv+&JDi3ddnPS3`qZJ?j-rX5Yohcy$lzIOM zmjPb_3W~hi4Dq5%fMQ0KMyu7Jy7(@G)(BDwO-BY=5+#JMb^Eh2KxENAKi<|?f0B@> z*m=6YgzcJXtu-iIjRunY$tFjOXWy+s{|E#|Tf{?GHyz8hwv`hD1l=bIe}sT>|62#Z zpB8J<j~yr~BIoAT(1mWPIh^~MB$L6V_O%W@L^YSr4NDGdsRDB2gTz@>u5^$67H69Y zAc)E=cyM5IlS5d8C`)x>=@M`2_3454lZ*^|n(fi!X*-9;QoXe`|Fj$*E$uMR*xhOl zLA=FWdB#G}Qw5~sdVhv>bGhe#^(mvkkWY{AcKzD7(=lCwVC=Xqddg&JiLWqVx*&W= z>F6ZT(m0ZMsolRzti?c_KlB~`94zC|Caqt!tzULrinQCJcOHoT*|He02~gCf9>6%f znPfCvoL1b9YCf3=-gQzd?7IA}vNj!Tnm_XT^r4lAxXNV%3YXt2msbG%vUMtjqGPvD zUS)j>>3R{`Z@98J^QVTnakqSF`vsmb_JfyABCki*>#lv39#A&QWK)4rTz|9Q{@g2a zom{ykWjaksGP_a%1C;VhlL@hMK_Ya9$e|;!<OAk9sXqP^0sW52FY5;@h4rB<9-Zfc zi|yX+BN^Ot0i>%1wdON4DO`@lmcmD#Pv`y0lsxz0SoE<UesOm9>}2w~OHH3FH%<kR z1{8k23pThtS-Akbx96joL%Lue48HyzNx^cnSqBPP&bmR;+a!z!rr)N80I`%}&#ZLI zlX<w~6`T*o5eq>5BmT9pX`(4kl&i~i#`weoMFsii#DS~*sWPqY&PHG4wnCI9U6}K< zloYdTpDDoYoR0q>kkj~|K+D+%v)tZqlfS-Z`?U0SBJA1bM+Yi&FtSh&6z@#4YM=}< zBJ#Jl1VjnBAih%XdTL>>d!WeG<n~o_@kgOqq#Nt0(niDCaKdEmXLq0_f7oz&FNekH z3Fg|XHg3Ac!5yAQ`?*%{nag#n?ACA=WGv~X+%|h@@4Dm7IOyNha(&ahodf?W`-}UP z1ee3BhEMfYkn~WPU6V03nP|1iv6|;%KJGWcdv2$e2r#z-7X7{Y!!<aYFdqt+%Oii; zZuofeORFib+g1FWj=Lye2F}o#<L3K$JP>~`DgH)Dq~qC5q@ELIEu68<w6ZuvC9oeQ z2P}c&j3eTB-iy7&-V%lq&g*u=w6U)*ZHw~getn?y`+HzVK)u8Ez_%)geTB<2*<_~9 zmmGlzx=pPy{#OrN4y*K*hl3J71C)`o74AnlMmLloWIPJbhpWzl1mXKB8SYV-4_yd0 zgcW#xxW__LLaJ_*PtbvKxB+9?3<yi}^PDAk_h->KEqz=4(e?Vk&SC51vY0Jp+4yKa zO@-VXn&b};8Uj4$t&NCHH>3ki#c;1|{ws$A0|$A_)A<3C*Sgwdj9nZWAC#h&GAZdE z4gVHLw-3&3Otm$9CN@^zory1}GN1d)N^oFsQG<sXq1QHZ<9b)P^bVs|m1>hk{p;^j z_QAx_wFPMRx$>0<xs@E|Kmug4<$0GqZI|=!vpcV|+~D~af3qUAJZ(bGMn6_#Oj!?S z-)vgI#O>N8!m0lEK=WxE`JAS+zf)n|gw;GgZa(x+tCoE%wX)0#Kulb{5tUR-GMz7; zl%y+PcFpVJgxgwD-u7GAkz84sD*u-fxVCSvf^)oZ5`u<SlaD8Wu0t&&Gf%+T`z8iY z1nv-_C#XPdEd9|ygmrA1n>-5wLM4arJZ+8`kk&QlyNQFA$UDq%Z`PQzL#$hxmu~_W zt<`Yv@J%hPmK!E6a`{w1L)my>=$4pGwq@8%we53h)9wWO{^e}3bUYX<ATk;q&Xy&D za^N|w=Ys=m-XkcHRhX5xk_<!#G;L&vdevLf{#PU0MiX&;&16?AgT*N9I!LbtDpLzl z8hymf&wJ`y3`dM2FygwNE+z-ik3h3byoOb)Fi9;fhBm=lEJ1vH!bHv}R+Ae_ER8Vu zLqPVFI&?I3$rj&YQbb(n@GYdy$g8H;^>Ehk%$%k*Xq@giEI^>+@+HQ}fMi4P>zKEZ zHHpfwerPxr`tiB0pk}rPJD?()Z<4>jtl5#9t3Rxft392!#j~fx)<8J`zJ(3qK*>UV zFZ+DIo0XP?x^i_l0liW0dTAWK6~K9vdp?X(e5SCe-N{!<s@IWth}F;BQ`Yquw$;G@ zZJc5@qoapC7QLiy<J#n~t_;wLhn>_isI&dK*^GvIf+#P*9^cO!7Etanz4Z)w2Nyzo zU$S=GeG9S15n@xibSqkqS|9#A5d23UQXH?mrDRRxEveXw`z+M9ty800Mf5*dZnhUN zn#NDfQ6`{tW~=m`NRCz28@gg0BsurvK%3TZrDWAyP=hJK#wo55*h0v@r^5G-?maG_ z$B&xH<PN9f#bM9aTYGd!PPW_ekpYRMSsDr<HV+8<vdlk~KZ8fEERGj2gDM#iKWEvm z5sLVz+<o*#+CQpYt3}$OyhZ6lAxFVXZhEs)?%L?OsMRcEoaq%*8_pj6)G&^tQA;Wj z$S@Tu3gL&uocjE5O?${9j(xx0>A#cVyjm$J9J2Bj8L5`RZLM1Tmgfbs1AY^;lD|6` z#35VgtWEh+AtL03pc;TJFv0~1ZyUZ%zfB~CO|NNqeX}>w9kn$EkncmYWltO4(3)CC z@Q%Iq@L<%i6P!g`sP`l|JVY|YeV%dXg>8?+OF;yyuXG=qmmBY`l2kyq|8(h3BSZ2S zWLsyukLQJ$=**RCmD$}|+ppAo(WWQt|KuuOQq>L_uZo_g0(^miWDN+k(rI~X53gSd zUF0$!4&&+~=O?f;y=DHWwjBzIHgu4JUIlMVBWMG5tq4N=f+>9JEtkYzvRV%zN^^%6 zDO*)y$3N{&=HKS}z{+F59<|aQyfig8m6TX?pOiP>G&PjB=J-jV$_WDAg|L%Ui2Kj{ zYbncy7cNDNyt`fQAMA%4cfCF^UXC{IW~#MY(Gx^S>wZ3hYT7;FCd0sFyrBeBytCn+ zZ*~S58LKfXBF!(R4z=M5zGyov#G74pwAN2F)mrTIjHX_*5g3AJQCsHUh-|`$BXooc zLz#(Y5e+N*u@#xBa71E3rt73z@HFTi@H6nq5E?V}w!2-MpRWY0(F~9ktTER{2OI<W z6vZQvn+pWgc~3NW>ikS2kQ~b!MY&9!JSS%z8%Ae-XE<qiitat5T9wF?S|unJi3Dj) zjZAoZgl}krHk`}mvk$&73-ddaMUt%|&HBA1&Gs0*8(YAAp6n^=EC${gmJCH{57e$w zBNz`wSH&{8isiaDH_%t9#fKH&nE~M{VZ#j3*gs!Ufy9}sgTG`XVf3s3NEC_+p#H#w ziI9gO!?Zw=s#<fF(iUExZ8E~N{Zgrl$e}F)-68!pAM{c@b=s8CEn&GCqb$5vzos(5 zukDeEE$B(jQTqv777NV>Z<#!f5%UHitL4?}36}S1Jj?Xg(W&Y9dd}6}TGo1+2?KeS z6l$*R`8Kt~@k~-RSj!@Gcd<y(q^|fukpiz?ERrw$<@vYw-u-T7qM0P4w#)Uy(&-0V zGvSX5AJGbivbr^ieYd+7g924%2kCfw7g1yj4!$r${SFQd{LI;&Y%C6S9uW~1uk^&( zmrH(k=hLJ24FiEef>m!^OpgdEq^;F>9H2ZL0BTD!Cz=Ub=w7Hy~nDZNCeT8Rt-* zjK*hH7!q*U=ze3tfJK{wjDUZz0U8Frr0CzBXL&soJz?qU^`1f^Hs!VAg6fphb?=ll z2IDvCO`c-q{6v+B4(_toUY;L^lPd&}VDLOa1YBPNeDIf+geaa=kj=!%_w=y}fO$X# zttTO=rQO{UU=dPm1*O3dBA_HdU}=3&-j`_q&veMaVED42*erQ7m7^$T{_ZpW8O+lR zThx?@VqnyX3`Vr8h)&}hva#=pM9xR&Xok3<?Ty62!k_M}X$@%A_q2)YLB>mDLV>%h z1iA)?u#95hEvT%<T^b>-IG**xJ!%4LF<*-JupOC{YkDy#9$4JoKa&Z!zsHB-v@R+# z!<ZonK$HvRH&Ma}{0^EUlE9A55ZQP#=tNzX7_o-g`Tf3b4tArr64BF$(cclHDm@{` zTQk@R%JeGut>!6_v&0?m!1c&h-)WcT5>?z`(q&}kfUw_Nk0ZxOKAh^J=rz0xX&s|l z$D@9EzNkp4BhrQF(Kd{|B$8|dDyT34e_^8NQ?^R+xPb74Lj0G^t<~U1_z0}u)@`lG zDjV*f8SLo~1369osbu$$!pzzk7nW+mz7pSxkp7&dFWJKvff#gnBWl|%%*Qv-ubbmQ z)*mK<8}&_YF5}Y=GbH^`JnjN*$ae?~ny_+FcpndfgX?1q1|T7sEN$OzLU#G!u^iy# zhP6d7%!~Wcxx3S<w5Pp+YGAO5LjL$+4)G$!Cc<J;JBsB}kl-lI$*Jm4HOK;MaGK4N zXl$UrjW>tkAjJ+pZ4K=pC75QapcLGyr86CfpBMeH4{NT8c%;C(zwXEGe6#@pewyK$ zc;;4RQK1H~|9}aH6wRiCIS44#PvASEt#eOat`Q&{9Yx|0SSAuA{3gYBb9@~WZ4hS? zRmo;4p#Sa2=r@ilQPG*@&ih_VIV(f`H8K;|0;&2)JV^W2^(JAKe&a8{=Vg|qQamkw z27B0lU1KZ(O*3CqTFZ(>QFHX)aLp_P<2Un(l~=bM49u~I`TTeI5uwQ8B4S&Lk7p3o zdY79%D2+-_{y1{cRBkh9y@(<hCYl=J*2=3od@t>=gn??~w0gW%`eS*T{-?I%Fi~?$ zUBPLwRmPx0BGBHWuJg}}37}F%`WT_mWT@2UafQIiu?5!D{d2d!H{~T+=V~vN-$^K) zrAntM)kfi5k<ex|H!b}8SUx0jmk3m9Wv)_6`dXw!?<SNBk&pB$%D;`j{M|8-NvP}J zk=c?pu?q}q;beouirryGKr|e4Z`@8FWOGmYvw3Nt{(C)SL|;v>DTRr}t@m=njvr!U zXWnxn)8u-gR4D&!w#A`fl$8FQgkyD`7kX3tXHounPF7?X8*6D9nFP5Yw(7H4#}5iC zBG9JqcV)#VI#4>I5psG_)>uhNv(RE?<WSnzyM~b}-E&Gu`8!&YzHBPYUzV`^IH>#J z89%ei4DOdGf9;_Ei0R3Fb6V<Ubiiq$lF(9oqj!)-|Io#!prsewhW{wOCI*V13uJI2 z7%!wPqA*JM9^4vTbu(<Pq1>hw)heTQf5Y|bX5!so`dBJYbizzgshiP`#{0PuXIIbc zw}ZNyE?*NeU$io%rptdU%j>IMOM9tlh=0T+!25_fQzGRmJya~^olw?o+j_6Vw+4X! zAE<&&Xoufi=%|IVsmTtSOXn6<9l%2Jz>?VTX_MKqkdIDwJ|VNc-#CSiZ9G*K|Nc6= zxWxJBuAij0m{iMlJc@OF^myY$0oHJ@Iy85vo?~;pVJ}$TUWh(^ELgVHP$qD1Tj0<T z$GtIdCpaSgIE8nA)ATEf;8M!-5z8@V=&-w3UZKB+<KEa}jN@^hM6hizE+Usv(Q532 z<2RElnvyc=`uh4)y!)u@^ug--?zYyl>W5z!_(sWFL$i*hz}678>*>q1o}s#TqO<2= zC{l9+UE`lu%`xp5hqI94Jw|bnfCi^I90?w&N|vXC-<niObGw6o-Fyq)p8uI}__V~Z zq@CB|p*Xf@UN=yGx)e>|$Z|0{JK(UKi$AF5ZgM~Hfn~I=lqW8_?9+{xl)DL6GRxFE z4PfK7<g!dx8<@;>4^&uZ>>DxyKYnxqs)mhjj*nf}rl#`lFc;s6&hXIX<<UqeR;j~Q z)R=dRLIhx1Q*`&+flM2kijDuSbpc_~juG|QbT7=x^DuXXDs^Tt^}KIHy4v+i64Od- zn12rJKPLoSu)t`0<CNoYF++v9O;RY$7cCg`KGc?`RtxTbW6C+H+~uvp9DRwTGTy7> zchdhvn!f?Zmt?)kNNEM){a%q$ZE>)`^L@!;>kjQ?#++u;OSYOkrF!|ls~-_&x@wV3 zChr{-AA8?e!S6yQ8h>l0Onf9!71|bMBSQ;<fA4uulASp7+x;YMWPp6OxSpe5<vJIN zN#Mn&V$(m_7R_PCY7pjU4S0?mZL&U1gihcG{SOWP?Is5JGEeHiJ9I`|V9@-!aw-uS z0un_@M+Yn^^HCI!-8xUPP+_pUTWcUYm|MU1ey}Y@XwSm<aCCP2V^lA0jwoSl#vWHm zFc-y|ZTN4gTm!C}LMO{5Ic;r1bBq5bJO7-na#iYZOsOkps1WkKCCY+d+S5K{Jw3M+ z*-N?GnXn`eDi7~ia7^?gsVD@W5e?GnZkq0<Tr&%yD9KVx9cze=AJ56;{UR_xAg*Wq z_o2gl>|x?dx%x%z@erX_wO4Dt?!144jF?@NBt^y#ww}OGoc<;ZFE7>1e$}13gVBXG zt6yTy8-*OCEDHiH+EYatKR5Ukthw>tGi@+H#LedaJNh4CG&#`sp-L#6<yoU4^=8_e zo15?Q`zXoeU-@_ge;Ds>D=0ffc|buw?LXP(6)A<w4Gj&VzRKOz%<jUw?P6~$7S_o- zoSFKykj#!sdk2kf70<~3CmfFBquQ+C<N*`rvcmeE`NRF???5FRv_RX*H(Ev?^No#n z<igLG%rQ~L#N%Xacx8!8F_Co)&m3Bx)nc0Ubf&`8mCNxh+U!y)+$sZS4tlS_b~|pf z>i;h0Enxv^uE^8$qCPlC8y<=nqNKo)FDtG<i!f2biH8qpz6h@_cBF1^Tn}0(tXIwV zrER;@(k22X#j8zw)8b9Z*L#Ih_8reWUOp`9J{i~ATB*N>is=YKgWKG;yPE-F+rjDx zDoUS903^C3_ii;^DHf=Q55Ytf5r&P8H=O+_6q5w8D%@BVqLz|9RAG{3aA`_-8G#7h ztDqn&%#fQF+w)wh()?GdMdsggX&eEiVlAVj&?+NF$%Ny|?$Sl`*H9TTmSh9C6y~Q4 z&HDaaaR3sOyr8Fw%2#2X0cv;68C>aocE^d}eblWVqm{{CG|S2YS8|$y37ZTo^K-Sb z^*C;4iA6^$=FbgPb{AA3o;ubUT)uEu2SVb}-v|7t=(gV=y~~E+*CFnj>C6@R8QZFF z<RJd<+oB;fctw|>SDEWs8qA6|-{5%^dDeYfpw}bP3k<~i*sC9(olSIceqO|)CIsed z^TNQvQKk0t_44%eq$Xqi@=$uh=I_<|(UkY<Mwed{AG_-7z|SJX2ZVR;5(CBA$mitW zJwV#_-+zOZX^C#>OV{P?r6lK#%U!B17(^fYZb6wP%WZ&e^tIFX#o^`$v4hwy&cnU{ z39P-LZ>xCh-b|x~>G6p$8rE>hz~*AIt=!7LaVjW8pe$A?1}Elyi`qb`OCnFE_Vs3r zFcG)JKsVn3vEJdn+3^-m4@Q3s?BVu}r3N)IvG##dAeEri@&sv(#jXsoW)NpCs2`@0 zD7ilxoVT#%E&dtn^+@&mWPfI6ro+WH;$oB02f)MoT$N`q&e8WNRT5`-Fpkn}sxLA= zEsa)nCjKjFe|n*h4+Ni13unk!aQl&l;GJ}9Ujyu#m_$(v5AE;$bx2RM#XCJ#lSjRa z-K2M_1}0*|+dL;OEYdh^K3=ZRj1F@(hz>0D{*xc72gR{$*sL~JamF$ZO8?oT<1wf< z&uyv}hM2P){QUfqA<>22El*Ir{k@?|6aD>3n;%bmcTEsbVLrj)@;dAhjk+Az4(*@_ z+k2-AGq&HQqo~GA0p%x>GJMqiMDAm}m#mhm?NK|fl6zTU1$**QDjI&J<(if0fUO?e z(1w@5d%YDAS8Z*pbJkX3BY;4<>Udodw{Cl(0m`W`G*EKT`R<<twLY~3;y2e~JQ79W zti5<X?!E9Y3l|m2AfC%eNyVIVPptrxF5q3jI6yz^`zXTKXLq&^naZ=zGc+=SQaWC5 z22C)kN*`Dj4D(s0e9!8lQj|M_G1>^nbELZ$B(-|lyereRRhPDZ$jFbaHAMR2)QIc~ zo>j88mX(y^lF@KJDkv$`6xsK1tHy=q>=|m*@`_-{;*2WaWJ#YpHwc>Qp8A<&!Occm zLbd60$UhPk5qD7VH{^XGglubUN;Z!yeIL8s3puvtdB_$P$xD~WNvFP0YY)%+VT*dP z)go!zm1zPh#r?i_cQB(&!z6vezb}ekT!Ns~1+a|@t3gD%G1%<+SqM|2E87F%E&B!u ziPYQsRUv;Q3h}Dr3*Q0kof|?C#J-Ob3gV7ww4GEADVU6rht(&FF!cMWv8QmB*EyRO z%RNg`_(Sq95Hiwtfz@2Ti{)eoVHMTSwh=Ha=qM;ukK-RnNi%p{nm9wQwOjT~9yT7; zNRY@DW0VJwbU9!R90Tc8nSna8z?fXZgW!Mw1*&Gsb>EJw;3yO_aL*e%C}@94wJc8@ zc<)!AP1|f4l;{OiVO-GS<y{x&6?$JF&pPMf($D<^+QP{l70pl1Yxdw3hwj>%t9l(6 z75_lC^}gGTEFA&uubn28$f@_eUx}ai`JCV_H;cT|hXD{g)ozLCJ$nPVY^fqJ2)QY) z?aqp!)(TfNt}i+}Lp;hB1Jb#(?L1POP5B=@Kn~_T1yn7T31%X@svsa1APS(Y=$2bW zkDbCnZ>aw`VrEx5pAx?3`pSvP1gX*Hf!lg_LA%}GGm(T{CgLI{r><VCDmPcE{z)$f zpRroW;s#tRL5=`;4L_P4&eBge+MAfK5jSBVeh5Ii-i#tlcmbTyD4v6>-d4s|Vi5(7 zZ*{ypPm_=cg|J90B$hSr&FLfp0-8zV4~`Z^_DKvFm@^8C*2@jPQ3RiJL$JP0*IKBg zO!lifpRS5-Y-}iiu!i%F>|$cmr96Kf(RxKrOb`SjST9z^d8t+5JS99_;|Z8t?NR5W zW&2QdOB0i@C>TQaUtKv6?iz=M?n?lit#0^{t$MXvf@(Oo(}4&;Nn!Gwr%ouBEwOAk zV}DHJu+FWsT&haP(tqX|nYGwk08oq~&}MjL=g<<MIDOE8LjnSUT)(;oU2{=WhZ@yv zv1jB<8yaHJYhKYJ<8X!yR)Bf0=ES#i44&>T1M(L_t65DAbzqP1j=Sf2HZ32`UN*n8 z>OJA4+At-`d@mU47Fs(Ypr+)ARxVu<@n<*@z4Tg>Kp(>u&d6P|UH;-s-R&w6LM#3E z*!3Y<e|WB#r7NkZ^1btU>!eRo6C8?vA#kCq=6UK5GCNM4k&>9oCqyul>X+F*+yca( z8M1FzT|a9=DVJ$7Br?R*S}xTg>OuIrA4aO|1I2;`)@=`d54XpnB@Mh16cRs(rS{w} z3nE!}CXsrD9(J&^CL`x`NXbyKqd`CSf&wqYiju~G#yl7GM=>W<7p+AwpGQdO@_P#E zLerO)Mh8Dc5(FyE_a|vy@MYSKv10GQA|Fh=<c>1W_H@AcmKyb8ggCSaJC|dl>*s2T znyN=c26N>EHMZSuwvqEKuB1B^;ZOzhIox#L!Oyq+M{myk9gj}M@i@v0`Oj*&ODEyq z9TgTOX^ZH1+#rsoJo8?kOe8q!Fb3cr_qq)ysy0AH;C_sMN66X1;%OxH8H*83Q|}WT z^-GMS_c~~5Va(A#rplFnG~va*sv2j>c`y2Q?KABivHn1I+ZFC@uss{V`XBJ?W)BPx z3}D?8&5~D2;a!eRR>f{T>=R;2R%6k9&v3t)NJ!G6+NIRc6h|2VmzTg|3{<K>d$dv~ zJ!_u-rhCG-UDbM3V>f=Q<os{$Y>fJYZJ1`dM;eS(0CY`E0g_Kbh4VU>d*4X)Me*%t zRn;qWGwFDShK9&ux*5KH9~ooB7$)?PtbFqd@R2#k+;vma)Japlag>UhnmiisKm6d= zxFNjT@}CqRTWvKvNnc>~xI-YWCekM|Ec%M<zI)8EACzX5w`A3>H~@aqyggbF737&| zbDy(vds!&lj~i>t@qKom0+@qObJ}du+v)bJAN41m!aP}Cuhw;p-g|Lq1lV)7Ox#xQ zRwmTLYH=CSARo=8QOLA}bS-Qm#_B(DF?${Pd+2Ku!f@Z5>Ahn(6^~<R6Dj?MbDN-| zHO%GC>^g$_3@FoV_=R3A6oRJ$v9(5~o&~Qi{qA{!G<t=a_I3ju##(Quj1&u*sc-TD z;&Ni?$e%mr9HmR+>x6wCyQM|~i7b(V4W({vPgS$=wWI}|ydJCD$imeH(%8g+d|vP5 z0~7iwX36Ztc<1xJ9}?xnl68xi!7r{feSNMs8-4ze16CxA4tU%r_=lQH%d|`{eMyqJ zaxn0BXsbTg`=zc|+x}D3O`aNDDY24x&PRoK3l}`LPgHI%mC<{x(JzwnsPv}y2iHRS ztuEg%7n!G1|3xK41x}*MJLO6YF^l!W_-SY)2UH~`Su_wi<myjWiU1;ix=qWyazyW; z)$wpvs1L=Iz{^{eK3YZI&qohwm_P!nG&tFqfW;8!@he<4IrHa&iONYnQc_`wVl|#X zvpWNxNaR>pGz7JkF;4$aTg1dF<GtZ!KW%Nr&0a#c6et-^LK@ztJKo?BCkL7ONs0CM zj6ZuneK<B8J}XwD{LUZ2%*z`|l1CCq<&TmY;OYJa+LmHRsO1gemS6x3u8utVH2lPg zy)nOAqNf}4%IWT|Y{`6>`#q-0=LONDL>~m$3WPj*EH83O%5X<@5(bPoCA4;BJ!y7D zu!M(`Q>N4_DG9VDOP%E~diw8Q8QpE&?!9PynVvy<(t$E7O^$`$tv3a_a1k4dk9f@z zPnX|!_e<2OsblF&I+ppI`~?jbg}hr3k>*qhHDojb;3j{!R$gs&kvrUzqf@i+!~^ME z;4gxEqzwBT1TKuny!6YNL-xtraAiO;O!)}TN8)Xy*>rKq-=tnH4PjnFf~~nosp^dd ziSmYjgto^ZhWg9nDO#J^(Dd+vn<Oh>&AHg+m7w~?aqzohj}E5bBeT}K61o>(P9nYG zr%p*JxOII9TDm$|O<f@a%$XQzE?EtDIM@rJQV3$VJ$OSDH(v~YAHq;xx*k~%wvXOV zAJGHitL8V`<l(BqLtubh59-m=cwEgS+T^os*p+`<Cu*e|;U|aS7g6xwHY2ex)vj&G zOiDl5HXdC%`W29g8S<|s(s`HCaY1(i(pCJAxpi1jApXgA{u_i0`xDnA#wF=x43Cdp zehHE~C^#ileSro1(;a*su1R$25;m=zuA2cd<?yc;72D!sV&hAv&%rBTuT2DG*|W_C zVb-k$?A~1*OXAD!l+!8C+t*N_qnRdAd7DGIDvX#o&_3pMP1!nIddYe4itmEE=51b< zm)fU8_S2Z6my-V5oR6QC$5W-3io|zKB{{wP>W+D(=o{!cX|yS_HI>$<8UGDzVkkd= zQNMu7g}2ZK++FrIf(f(b4f=+JGMATy4i?MsJUhMevpg@DM<2Z2{p`8HAR$lulIHp* z;N5muV>%f(HOr$hEoQQj505XIe+5aO8TLu|Tzdun4YMIyu$*j#dX%2R-EQy;4dWXW zyMCyOKv@zA++{c-BtysJMK-B3tZ~L+WqH#Oe)99Bh?DkRr+u`Sd{xWnb2qo9(4P#Y z#hk{eG~i}TOe`J|NeDr<CWG)wzo#hvU7o1prVwn)W3m``5gMO_hhFT=?|{)r$_jir zF~2oO9Yb(vf}){~JBnQ#kp`bf;zm2t+jFM%P647Xa~aNS!wm00p&GD@2I)WA4f@|r zY%LyIWgl8Mq+p#VGje+Kl&RIL(M_r5U!SeLXh*0CQxuExObaNSU|~J7)=g(geZpQd z>+~P9(96Li_+%(FHcxcdo>T~KcLToWv>OHWOM=dXK6sU*C1H~n?+BF!{>=ac5>P9o z+?1@8@8O7ah%8jk39+-NXtxAOs^|UYn;h}Xac3k09FOK3Lw=~iU}LF~#ZaQK(P>J4 z9>u_hkP`KGP$NT`E%i{7BSRK=o8sVOBgCg%=6&|U9p7QA4Z`P?cs1hxOvg90g`yfF z!gQF%cz;<-M<^*NneW|xQKibt+gb`Mt6CAz!xN<v`e+mHQ&x50eYz@qMEk(CgQ2F2 zidGE&7_C1s6^c%+0Js$(wPonCs2X|sX(0>v=_!eEQbi!ns>hI&fC7r_42CT!t`Am% zw}$&Bl5{*69*LSdfa1&wrele(rFZds*F6TC!EbO~XlGB3HNF!Pq6C4!(nt$y*W00r z7bJm6oOSdPMU?2}m0M%q+j%drDSE<tGjs{i&z%?Au@kjgG<6{u)ivs_IEZUAOKs#( zg5kUQl`&atyw=;7aAE_kc31<E!oZBFEJb_MDB3>{2FY}6eoI+1g5Ds#p>osnu~C}J zH`masSDL6W->m%?+?H!cXt3%lQW~b|@C|cOG8YL)&}L!{eE_t*l%?-DyVMc8TzZvM zhM~w~m}4OCMCt&+ObP4*spcoiRGU@Ki{H;c2Se1e7B>PS#%9MwWeB2PQnGLk2XR9T zDA$ER18&Xr5c&PDO6H%f8x%l8<p<eI@!?Hssrpw|Z^YJ4!PnjAtGt+=OG>Hy#Jx1F zx4P7#4b&*TU$u!rn~%$vjJE5~h?^g{9quHWPMYvsiLs%c-N$!SwCR!R%3GdT4m!6z z09=Nr9D%|EAJexiwOc$Q$Zr#l$)iU?E&FO3-Mdhn@VPml*{>IkSt*BG|HnH5b|E1< zQ4x`_KrFXq`_tEnh(d7TAhr(CP8>rf-9|GYdkUNNDM=a~32f86Rlfgq^aZ`_ci@+f z-6tf5TrB)P8gA|+xU;Yq>xI<k<!af=F*6J!6Qd8x9HH0OQtxW7ar+ZJ&+kn*-&usv z<v!d^SyNF2b+g;@yZ9vEce=9%^atNnR}gAo>CG`pK>n!G!L;GQ=vEH{l_v~Qm^cz# z(%B{??ble}+j7!RNc|g}LW$NlTVv(_!?-aK#XKM11)U_vz$1~Dn)*r+5m?VhUDI;G z6+uqeN=4lV)uc8NnN<k*Jp=^=ghZ1$2=m1ncmlC|FTBWlAh;G~Rt!ZWVlV=GY72qV z(eIfZbrZ2<NAEdcXI7r!L74l_MW|lR>l;LcAU|i21!PnXt>2A5llt~AJ8~Z$Qs`?z zJ3%RV?EAC4+AKJKj-d+cK7aN>9zv1N0$`#>I9hk`IJ~ktT^H~ri~Y>xq=;=WwvJOC zl8Q3Y0EIUo=GP2EHy(l>jt$>|_BK7j<7jEjm$kT?QP=kc72WYSrOsr7ynm5Ov{iiX ztoF9BEZ{O=w;f{ga?gIuA1eUqHEW@GC?{R0<;#=CSt`rt0v^MM8Du-CsWSc_dx8PE zY~AVJf!Klm*1ED}SSeX!o8`931$q&mKSgREmq$apXY1&?a*d`c&<5*2yqpuPK&Djx z&JG^XpW*k_?<=vM&i1+wA`)8ZH;C@(B&ioDqM&54ibKdnD7gU+M?s1W(lE?pBF>=F z9QuL);`wP&_k5;zPe5smlhy>bLw7iel+KxksQW;5G}vt&S<&S(!PSyhg*sszZtw~i zFuuHbnh3seN`%HDgVS!BONLqat?DHIZIbswWa1V+bec8=vg=Td`bG?0uts;;j02U2 z6!4BuuwB8}L_~HXnw!kTB}D5uNKAg#CyU5wX4YSMU|HlbSwFWOsA`mO>jr~O#Eh}T z@er^GMjK1818WrjT}#TSHbfjVdnGc1Gy}23!cJNQmpi|a3DsHoY9JehyV?vq3+&TP zP=$&NA6cG#8;Cb>!qX%THD=Y^8_nKfuEU!fCR?gCW#cz(_!~w^b2qOJKo@QP)W4tn z;m1f?UF8{H7;Q94U-ol<RgJ&kt;VD3(Y<3W;{&tPxIs@0<kcvM|2&t<`e3n<G|r62 zVSBPkdTEc>%aVp6kM+F1meA@zQhfKhVUVPZ^Twj>_asu!qV=!umk+5We~}kfV;If$ z+u0&K0fQiQN9$w+pS}A^>+{TKc+=I*wfQn)e^Ri^r{p53n{MO{Q8}VI<W9FxD(s7_ zYuxdA4rJVMS%F%99yY0XCECA(vhDz5<85hY1yKl6w8wy)L-BFsj9bCwI?ruvwhCh~ z^5tmDLH7NzC>{#t=+fPQg&Ifh|34{o$44l~1Gsff*ij`IO<{<DnY*R;oA79+9}OBP zn%UKb>*<^<e9Ohw7Wc%B{#~WgkdWjh(i?OKIAJOn?5worYK3qx8gYMf!SO3p8_yfL zLG!70$<!Hy8HI&XnfiCi|G=%;ouumzP_%5PtaovxZ~na`aJG(npvqM(dW^M3Y5qlK z|L_UwVjYeg5acDb9${Zv{@&sbpFN5V=?HDwwyQ1vFO~9#<o+NaKwmPtPIid$7bg8r z83q_;8adm`W={M6{#6d<00y$QbQW=BG4%htG%Dnrr!w0wbNd#n)U#w-FKUPa(z9-6 z4IjOm3`==!WzTrxoDALt@8lbnxM&WQg~P+PzrP><0>G6)g@(07+IXX1HDO_Ahm}Ut za)v0%f|ye2eOMliERP-WZ!-u;$H+*h@C}B4`q5Jvb{&-G&%6siq5aF!$e_qo9l&6W znrkBX{CIG2k4s9z#>8OxxD8r043y=Qpu0E%Iju+EY&GGRUmf?+U@AB{v0Kj!sVALT z==?WRag2np@+c=KFDc(BEIY*g!}fr|l6;O~?3N2Mg$jxQ+v8841Y3oCb&FoEuKJa? zOeZjq^h0RW{&?nMt(kPAtLt@1%+0^UJ52*st`QtxI(vYquu&Tdfl$Pup$PChueOkJ z%CZOeQ`&UJDQXKf`o|Oxce_d$1cV}1Cy8v;FH*(IV<U=#af1#HhZ0T4sYTO825)zE zcjqXiXf*y#w&^rLLt9Q4$|l_Y-hW+FDbHCa;!kxN6uG#(MwMf_<Tsz!4KrIy{7t7V z)9LGlrCL5F)&RrRbgN(0bh$47;B+FC>NV`RZLo~38Cx3pcb<Lwd?8LIl$Z(4_KN## zwUs`@!>nKK|2|>hE3!rW#JWDBE%c?@-j14<Tbxf2K;U2QCZ?-IL-4!NA^6I!?|oNY zVeh9KEinjq&=|c+aDplR?!0U>5;=YHSa%LtX8j=4@W|tLP^u<=cAz%O&9)HFxalhM zm~qQIVF3oaw&d2<R#oTlfJDvZKo}LDkpHkgG63sSHSAM(_fwfw?pr7S`^RX6c3i2A zIgzf^pPCe<6&32O@lQk+LTy9;Qj70tpc?w&?j9Ayl(BYx{~mfk+j}#|=K<yKA5f9F zJQg~gKP5L-aG=BtweBKCg!J((2Hy!$vM4y9B9=+{DbJ_9IALVA(G*1i1af|}4gMB< z*ML>4|A!EIBHLq7Uby(qnPfR8>h3|O5JBKx^uOgOjSjh-$J`vc$Gef!StX!u%xw$W zeRNWlV1k9aOR6e{LaZ%iA3e-*jgZ9AnUK4O*WL9X@?-hl(QDjJA}1iHI8|->m;-aL z$`I?#sSN*zF1jHLtX#7|@V2`wg_S3&UoN{+{PxvkCzr8pJo0~o{E0;Ffr8Rmxy_d( zHd>{DQbXnP?qzi9m1k-1*la@K@fkm6I@D;!YKUz&XPIYqQmt_&(es6K86?#!{V{>p zYfc<_fn@F6+(ye`<ulbY9%q?1hKk(x25Gp*rkj)Z(x6q=Ku<k-oB!}eSr=9*c6`^T z3n`mXg%U7O0J8`XM=?cjw@ei2e#CN<yCobcRTU{K{)^?ZL9G)L{ZPd@K0TzpRbF<@ zkdNacF2PDAU+E?ZG^8~Aexs&@0ud)51t`AQh1I{nz`}k5eXw)KQ>-Wcnxg`#v86fj zv!>thKF@FGXO(9P(<i2SY^DO~jH{&RbR}~&ae!0%0Kg-7O;@>>d#QuFQ@`d#I@yx3 z%_9kT<J}zgCG0_DVUCWc6J&0VC+6zShcOLc7gxKlD)xFR1&U>P{~kT|FaeCdAI=MT z2o(Xuguvf{qy<HS0_}pSHH_z+nr;aFl5v-~GYJw5JS;D7s|Z$UF(A&B*AoCUNNa6V z;HhQJ%mDV1>_{$7rSn)G91fCoW%2oGjrnkKc}Yw0Fn@bv)sWxbVms%6tCLv8H4$@9 z4E-=UZ7XcH8rA*O)4x&Cpt%e+4@-2S%96pK3#NBHW^~w%zuXfshx=|~Y>z-gw@%|q zRbob<^gpT)AHeLY!qWH#<b;HHo-e_S@*W=PF&rqe+pSk!_6|>Xw#20a+zw|%yq8z# z@o90w{G-p`w7vFSsi8kgOG#yKZyOSqsI|BqHJX@=KU^Osm%2&rfrXidxO^)Jg`z&( z`o>l*D=3S_M0r>l)R`X6%YM?(z^xzt^$U$9BQcTUSQKtczJs<S@*Po1@3AXe`oit) zZDF2x^f<5cnoKYVjHY0{nEl$)vaHWb#1VWR79Cx9bycJAkk(W{{{XGc?fkV6{?&nh z#eVMi>Y)AQ6M!BCwB)}2&cq=J#feFFNUu9ymR6C?5TU-0V9o;T(&Nzci%n5PeJ?4L z+B{rJ`t{MBjF;uvtx;L=Lsb~bJ1RZPleyTa|CaxB5UoG(R?ZI4Se-~z#I(H}3}d+8 zRm4cE5;&jC3j#K!oX4xRiWfY|BFAg(N!l(iYIY_ThJefHera`o*bXZZk<Zd=xYO~n z;0E!F)U@Q267&-<;9i(6a3<vq_r4mo(+86SP|xHW???IY)fOKOZOE=G>=T}0C(V15 zfemyQJPdp~OTA9k=j1vuhLDdTIo<+9!;FSP&#W1oUJ>eNOL218TW9Cz-*pp>4pQ5M zKenJ5`pc0-KriE$H~r=+$0K=$g@b!D(Zdet=k+16yom+5Mn7GT0TueFZ$Ka{5+s5N za9@C(?z>#KyK&<8EI+`G{CV)tYtY^WfEvp<prIy~l9J-*-`T4>w_JCB@4;IE3yxa- z(4IWHyPENv2ViQJJwxbs_~KI&1(Q~|VuC>XvWFaih#Yj`l*-yz9($R_WWK%F<S)|x z(mNa7*8h_m`2YubrmDpR1c2?sMuwSx;#hXUv)uiMs!3VwCBrm3UFBtUn727U)dY~P ztIgq`Oy4fCS>Q;LG7}{M_m08@S``GfuYiUV%5Y2!3PrYdjr%Pmv1SIBbHTe~Zj47B zpDW)AJtQHZBT#}n<*2EeRwz2NHK51H<g$i7iJUSkAMimA4Xo3+J;`O1&=3;~s@WeW zPOY<E5-XJXF6SWiw$^GzOoDo`prY3Kx;TNQU@tjp8feDax7fFCuNq0XI%NDj5FN@o z;6SJG2|D>JMa3i3)#>W<+wwFKK)WEZjX4M?Tt;LdJR!uuMWud#>;`aC1%NU#8_QgY zk5863UaBulj>?$dOs69AdXcp^1@!Qb@{c|rtLa4Gx%Bt<%2T1wp71cp%JOTo#>>7w zubDXfYTP~N?A}Y%ur7RUzO_pA8uKIpC*#b$mCwiZ>WrQX23uiSuE-)`F@C@7kIZR> z*S~)%WC<dizKxLiYBrh&l!qw1ep)d*sk#P;8ma^Q6&WFooVUa^)84hX+B{r_{~W=- z>Vnw-4?`r?_b^vvkG)v!o)q)Lpg#(+)9v;-rN-*moFd;$^QVA>jyQ#G8~&Kx#2C_E ztMghS^$F&1(s>7x+3@etnn-%z3KTzt_UqpkS0~NZe?Sni=dq(tCCT_*TxO;IL?snJ za@X8X+x)TUH3cqrN54OwrZMD$u*9Y6`OkvgMf(7Akjb9QzDgMjk$21Qn3P`T*ItHp zvL>5PTRxG(-R3~U-ylH(Z7fvJ_p-0z;Febg&)1du>BER$HFmvrwveh-F2ouJ!h5%C zNfY1ZNdd>FUy7%oapXDePxY$~^aLhvZ%)@_RkXZtpHK5Z`@yFs@?$3%fvoT_cVX^5 zF@m11?o!Jn#yt0&&-=do<GWd2Qdu5PsMp6+{-F;HUN{5!I*D|-3@g8~0UVs^er*`1 zdFp6kZAx@EOZv0-W8g{CGliQ|pCUl_fBM7G{m~7JV5FthdDvgBrR`@$GK9)x+$~ft zuM#7jb{pudo#Lg5Z_}!XcRF4fQ+&aG6WYI2iJ}ZW7Sdqc{p3mI^K))_*+U2yt=xT% zl1C)o>wi@|5TtSziAvewX?%1*W!g<1hxQ}3Mxo5a1ZgG9PK4P@Aky!t&^XFFY2lQw zt~?T2O%6tAy0Af``t4&VnN96m<?g2N&B#(IT#*cI+Y0An0W;Os?JrjyU~p{Qe2I#6 zDz^zcG9J6o0A0bP-l&wUY+?PHoByvgrf*hlJM2Y|cLvep^*Y|4ju#XVa~F0;+LrrQ zSa!U`qO~0^k>|!IF)dQY@0lPqKRd5@g0y(<St<);OfKFCEtWXTLN%@oD6c75a3Fre zWpxROnKjAsPC4;j7i>CRZQhIGJ}qE2iOiSgF-nh*Co)LkI<})&$`nes2HIv)PC#du z`Fndf4-tcVA>Z;0Z4;=5b!@^zj7G}!>U}KAn={MG+IV`w5=gsadE9FCkFR$`qXuYR zfIF?Njsdl=r~l9P-;xhzFC<*A%asm*RM`Y6h+hIQ>dt<7h9CIo6W*atv6Cd5A$5t( zfO<&#WO0r%-lF&kBTU!JbYNg8N7iICkCLz@Ef1#Vd)#25>DDh#2Wa$Jq`t`9UGO8Q z^>Sm4ilz#-Oto21q7<94YG~VOM2+o#6DNS2Yy-%JZN4QAK-Yw<*xUOe`Nk4pi2;9) zUsJyb3=eS0ibcZ_%m)>pHt4&0*U<A3tsp8C^mOWuoDms})MQpn_r^Ccun2{4@q1du ze`?np57V<af?@&3N&0-YDEdO`<=tdvlj?*S@e6A}-R)bj=%-7shi|K{&J>R!U31kw zzX-XN9|EmS48LGpA1%bey?sx|SAa7df=are;FesLaSua#_A7&Xf62Nn7jRle{Fdpm zK}J#gbikC!P)FDCghg(ZG^RZKE2Ei34S#?EA?NFkR1PAx<^W$=zZsxqst*|z&P_vx z>8AT07ja9h>xyrg9BLsLtKsc?o@Dw_yxw-q=XEZhLkRQ7GfwOFErti6d9McwA01uz z^mUh%c!}t=gEDFbI@4?O^lC#qYw`>=52pS%-!mv3mEo;*R~K7i|1L2JYYh9zM-hAM z7ojPJMjsN5fJu|^x^Y)h@0@d!$ZX-t%N?GdYVDzIIyHW7qV@5;s-lI+B>!h7e8Lf? zY1CjR0>FmhAqY)|7Z~cl6dwRB9%I`5ot{Hg)9oMfQcdiL#G)Uclq&TJku-G^Fo)^D zq`p1OrwK4DME$NU`dJ^48b$*8Xo?{V#QSB_Q8wXq<mpDB)GSsCkm2ob^Q1MLWBG4) zd)t1-!1^KO2KS05dqqb?V5Ec~`0&N(k~<kpz8$82vYsnll3Me6#B4o(Xy2ErBV2Qw zYdu0=QXCRw6;v2~?_M)%K)_`5whJ*S$i$fE6VUwj-Rt@BbCxPyP~}G%QfT-+ACLt3 zKs<`tFYJs4)QfCv55ug~^K=wj)#}?yi;gSzR{?CPmLKzA$Em(+G+2nX5>xm_AvgN7 z)D@0yDrz1wpTzQ2i8SY<4I8CZk7rcT`nQFR0CDm#%1s@v^WNtAZuP2r6SKx`>RnXx zd+E@AnaRY~U@D#gonMIB6h6Ul|A*I?`+zW=Iz}^%-qk09(3aQgmNhur(vC>oO_JU6 zhe)Yyj;RZNy&yVuMn{9!heJxLr0H6P6@pbj94`K5ajfRa`5SS?;3HAGS&Ia13IMkE zRSXesWY1bJQ}hq`e}+`{e0+o-z_`bEq6{%#P<UY6_9BRbj}s+}`AVnlc2(KGzjW#q zU&(WSmnVe7Jet)_Mo_7c!!p3J=!@a@=z?J8_1fyZS4BOw_e~u9{WD{ugvY0ir7)N- zbJ>%xY=IF9hzVgdP_z-SoM7%mGQP%`=U?t0_GjkS3h;imi)mt^1VYfhKHeP5W_i3s z(yg;7?<rKJjr&5I??k=DI{xCt+|f4g;tIs~5S0pjz15970|yqij67Hu1sfkQ`Q=O3 z&Y@ZVi|U&jaVaex5h{6lY+d><f4_u^egBlA?Lp@vb}i(I%W~nn$GhF`4^O?&2e5Vy z;SMrDNn~(2#x@15`yCPc!oUD-e+M@XnHTUm1BQNP+qv&<D(43zb=|D0IFV@g#tiju zCcI6Catq?)4c(5uwU7J3@}Cbqn^vCjy^bhK>4K1apZ4-n9C!g!tApv3vh4dB%g5mD zYJ|U90Cfr&s5wQt)ImlVs4xsX-aL<fgc#xELWH*U`p9DWewt439S6^J+Ro4xrsn1} zZvw?h8+holOE`xF=?tojpN+K>yeY9YuoPnm$zsU!(J7;buWInmuqCYDY23&7U_a?q zuG7-eYLqsT1|#Q!+tSE!8a{Z*A5H2S4hlmYBDQRI`Yfffpw7dz7YnKGbiy)1Qb}^c zzC~@;cNsSK)(wp2cq|BlJwH@_E^QJm9AYhb!b-9zDk;5?t}XZ%OTq`JJq`$n5O-z? zRhVWdsfKl^gSnqsF}yI<;&+sHnKI2!Z*Ei~Q6>>dd|(C6>|qhFf5VDS6=;3JW@5g& zxk!ZlWVu)uS0{w8%D0L&lNegGe0$#qx`ifvEzq#~4tl-hTX7nWq+`tbWuh}d{nZhs zF`4W5P0?)!xZtyDA;Xc%!$4kixDI8Pq*fPF3D1J0IT{IqE+q26=Js$w7&(@m|NJOX za<@G1(}01L6t7|B?6LE*^xU}+WslAAOfx7r{-DF)T(4@lQgtEB{jkh={4*n;c!t5^ zg-|6wQ2HQi;!3?aheW&oaW|dP>&IU6tB<e#_g=n`q(IsDK#+!FR^~a6miKYO)lZeR zbtXNIsZE_kfchXTWaJDJBx(2A2&K&W25W}kztf9Tz8h$8dDn~dA=BL#JJwc$mM}U- z)nPnY0hSJ<*QKEoeooRTuDU78HL5=$L900PiBocC&-d?OXCrVDt=GNkYU&B-`Y2XG zK|%9NsG_6BtR~>GF8X=+Nu<Ku55TKc?dB0)NE6b<A+!d#bCbXbP;LWo@=Wj%ntrIq z0K~a4SLaJfa#;T~?*%cm(cTtWGoo$;s#J3210mKIvb-c>J5I4KeF{~&34R1)V=;=j zV=SSrNGsqUZxQ|89K}SpjU)@cuiSfEsV?Y%>V%|t^#j@tcDTF<<S7}MG%V1{M0htY z^qZMt4nZ?oR22ui4|)V;1|k5r37YcmCQOIvmnbSb%MY;|SPy2a9+8au!6a6zY2AaF zytKOn60kuaEDtZQzj4b2`*E~13N6**jC0q0;7{hsIM8Z8h(plM>p+9?_}~7LA3%@J znxC~#VMomGBf?>&d8XuH9xB<BC8clH2Z_ec6!lnjI4BbFo<zoL%wRI)!FU5mB^Q^5 zZC?l9fcfFFhoiZD0g>@S;>-eG2~xBHu;B(Yi^)MQ-_5u2Xf28>5ur@8a0w`vDU1Pf z!@M#x{}3o5=^)M&kLkhDQB<CFFp`=nQkLSmv=O1f=~7$t3-Vw9&!sPZ1IQ<&tN5*y zI!W|lGPA}OjT^$cT^`7gy)U2=fT-fiR?a{52b4kyuOpJ24jNf-Smm?^Z&Ak-9`2MT zddvVWPan%$M@H!0fRNFi@g7}&U=!8;muc`d_7}+brbJ|}c0)&EDn8HrT9d}X!JLmC zFs$ZTQ#p{VRkbq}itp~O*gajJl)^J@J1c9nl$)7B_W!8*=IFTE?(Nui(y*}`+qRvF zt+rufHMSe8vEA6VZM!ii`KHhNK7D`Rzq4k|S#$3D+-L6#`{Es8-4zy$=ivmdo~}Nq zX#L*4awI2|t$i>zTQ*PkSjzL(`L=w@vFD9Xo}h|$yB!ES)l_#F$E;V=>UuF`D&`!b zZ_wQtwejM`iTVRhZV{^KnHVdZmDxv`+mS!DGL7FKV##eeqv%;v;YI7;lh=mWAEQzg zu<UXGqYQv<$o!~G3_<D<D%NVb>GN!T^_g&;EWvB(V>Fj+L0yc4bX-IPS?Sh8@Zl&< z&-mp~S}OB#CC#RRVW}95>+d#F{Dm5HatRtS7?5XYn&l%P$H=I2gWcK4SG@sea`}T? z<^QUA<PYF@(R8km)i~{32wZ-_$W1nj+UT*gF3|x~AbfXyoJ4y#Y97xVdEN#-1w*?x zsxk`Ocm6NlOG5&#ZLcr)hki&aUC~AV5)CHmzdeki^ld3b0+Rx*qYRk?-#fSNFBS+g zJAD8V59X%%lu>Zt+A4AKkt@NKEz?c8rzOvSOVvuUtriu@;Zj>mVLh%-P;;uwU5cTl ze{ry1Ajx!R_lN|rzWIL-{y)5dB*+%QCiukb{4c=!$IC&$3jwlsJmaeZ|Bvhl-D=<u zR6Rg#81fez|ML@Kf1DL!LSm)a|M#as7S_exaylLRdTK-LzpM7gm3B;?W7cq-ZAz5; zf4_hC-ETmrf_kfAH8>n>Ltn$ECkDo445wkdqmFT8v^0j5qP~v06$QjRd~P=%-4K2F z7wHC<0I@mGs$hq|tQ^S2a&mHn**QN4)1}uF^jI}oS=^7VtekRR@bO7z$w(IR3^Xcl z)Ppc&rmEnEl%v1&MGjozpBrJ#e_M?H5iIXy_guliz(5^rl+JfgLDRuO9wD{w<K%Rg zwNT|KOJHlQ0qHDgyn34ky)B@p>R*!yyCBG{!P((dNU(|qhJSZ=m76%HzEbbPm&uzX zOH52G3M0V3M%%S%crSu-8j+1tHcEjVc1$bbW+esEC+4lSwe6U!tNgpc(}*D^Ebz)W zWhu)vdgW}nNTGz)jTID(1D=6vPi>bXpq%J14UUM4<k3ZkLM7aa!lU1$j!sSGsmWm) zW9bs)HJ4iKzfR^DtszShI!=bocncM<);-46Pp~i*K#3XHF6H}wr5$w=pg&(HaHn9p z_2VtO=>!)6>34y30yBlLAqhU7#hVl|i73%(QvpdzdCr!wkZspi^xcoCcHD&d^Ou;Z z@@7P<=kdk3rmu#@QtkD&|L&w5&;sX{5uBu|w2w##7v8O}(`HwceZ2}}2PGYol`iu% zCnjZ*XK!_ZrG4^YmuP_7-qqKUg3exeeigoK3-CIbVG2j-8>ll_w!53pHg2ZYL;UZe z6R<#3@@<!xH=t*~9aQo%`Nj%;{>*#^58q#tgh0zipZ>9@x7bCTyPq=C43Wx9Cn9`w zITR_Ys_DILs&Z(*J|j7a{(p3Xx@gHr*#B{uB>ZuhC|o3R=7VFS5A_6y_6!n1)g1+* zX;MXEziL#NHBPWVkoD)43;P;gqmeA;X)?@CE=G7OtOuc`F!wjxc`~i+_Ufh+dDi?N zDgh3B5t&t1Gkt1*>MYoVMbLIhp5|N#*3?*n_?|LR0~*Xfr?Aj+I#{4)W*{?0r<}oW z1v6co);e|X{8+`Vn-NT=GP0yG(x-qHtB?EtT7=a8xIB4Vb5qg>xxQHLFTgDw#`FTE zU*(I$=rZAX%tz?}i&t=E_0wA3R9d%HO6{lRmk6Q6;q=9-<u?E21AN=ASVu;iL;>de zdn(F)LhD}3?sJ_|mf?I^9})9jz1nCQxc$UTpAgV1Cpa|ow1y38SX=&{E;JAU!XR7A z@vwzIE0=4XgnJ24m6H|2L|5CYJs0jX5FP>HBT00H^=ESLxh-6?m!~HcBO@bZ*@`xr zThv;l2-3p38pHJ6iZ%;{Dys6L$DcnfRh?TG*v)62oX7WWtfcJnjED)3ly)Ui^N9hb zRu}%_2-`yto-tI@WlmbND}azbU>72eR%5-*|FLAHN#tmPD0A$gWUdfgR{E?s*y|wv zUA0htC`T#cc-+t9g3%)X!TcFA`CRRa`uaeae?-^vizLHDDV36v6387O4~pcgv{6er z{SXQ9g9Z|J3kwa6bhUQi)Ujw>AIvZS;~i@nIyM;POe!UcNEFd+04Jn3{*)soAC*w9 z&?)4upub8`yvfj&iAX3(@i=w)6^BvDJICr^F%IQlFdIa=TB6!UmG@x4jhg+z`%ja6 zl|jiAXv`qIAGo`Zd)#-mE7}$7b~Gj8aj{%P%S9b>FrF#)zULSV89V#4Ph3_;5vMjS zDM^BvpD&QJ+;GrrUd%uztmCZ2FGj@GNqb=wRD23C>yx$!<DB#akuo!DneoL7CGK+k zIC?pRMm!QCX`_dN`uV|yjGUP(Wk2y3Y>tB9VY=DyBwq!fvYx)8EY5ml3dcLYljQJK z81;3togG-Y`Ui4|?-*ZAl{aju;DM?}8BHfq#Yl*ry$5(6t&}7ji7N{3|90<n$5>3* zmtl9=S$00JkJvxgK8zxgh>`C!n9$Lc#A$`|t6s=Zq?7qeh^~QrNowUBwKmeE40-Qf z$M~SGN*WF?bg43v?`U|Cq+q?(O(qK#^E>e6e%fi0U*W<|=4__nLlh{Im!YVdrUTTK zTZ6RSSj0Qb6zJd4uOVOCX+Y@yYlK0GwIWsdFVa|2SIZb8B^Dw+j3LsKr^n}bW?xaU z-oDJPSmk<Xe3490mUg3AZ94cn<P`_JcMmjKWG@*s6jT^W9_%R`sCeAP(_G%#LR%Kq zisYf7_`V<fb<+pu*f_U1qV`Xm*UfGRhz0WII@N12IVo_yqD(kG&~wN?t!fWXW&|n> zm@O_J73wXb4~;f$ga+LR-b5^aKXts{yv$K(MZI#_6)UmEcRpr>wC>vium5`EO2GQt z;MwBd%VxC@TY*3*z?D#7Kn3b|&UOnEoygz&M)1#lYv3*;4X+Mpv|EmM=s0&+>9GHR zOw6AsV+M{nnHliD(cWqe8WSc8r^WD|Y2bC7Z2}H05@gOUAdtlAuq531-XT9^P_|(I z9V+;Hu<TQo0IW4Agk-KpjoN0jLyScSYg<BGuuTFnRWzjPw8Ps|LQvo2;c`=|Tb{Jl z`9d`7j0(&#LNG2yDTN8p4+Mk4_=y39egX9ds2TkN(cmyEd6KiPNVQo!o4V?^R#;Fl zojjgiEar^Vu=O@OJ8KO>^IvtRuuewA+ce5J<+Gf`4J<6E?AKc)7zU?VSXfbpKr*HL zC&ZMgoNlqD&kHfcucN)9*Mm_Xm|Jq93)7@>{Jit8G|RKOF7s>Tl4smarDiuEYn;Ok zj}hd2I*DJmdQnM77wmG_n9t;$eDnrgB(H7NRuiZ(=QH$uxVLSgnTe<V+9YWpD*u6Q zWBJf{<geT;M1K_xg?pT7$H%t1ZN8vZ0P2Fn^wVO;=F2qUj&JYo3MGV?e?Dw_hB$t6 zxxXAu4ll3)S;pkSxFQ-b#2+)8HgeoHd=dm-Zhhyflu*e6tEB__x_OU>XKShpJ092A zR1YpMLEtnnX&?$;_H)M--S{@`eOxchGzhqk$f_=8(rF8Qz84HUcxTtz6MDH#DDSMw zL9#tA2SupTzRFIz*lNudi&$P?EsFYJrnaFFf1xr)Tns_A^dWUXs_qFWeml)(o=#BW zmjxl<NreDcmI~cweH;f6<zj{#mU0}{DI^NYGD_^g9m}S^Kr~HFL?L9?9!N+{6_YYC zEdlB9YA&lziwr0;qW$(y{B4W%MwOpk-&9xH-Gl%FcOTt_hqjwc-EZW<t!T=t<3xP+ zE_eGEb%?Xse8h05Ydl7?{#Qqb3oDTRfyHU4`{F*oTHc>aeZE$ID^V*tI+`Zm>+kzK zw!CXa_7b1P|23YKt?uaewwPVX*+Abk!bMhUoJe)f28eVeYf>we-=)2hqs;;W*nX9} zWwU|E009a-P$YMV&+AuCWFk)e!eJ3rg@B-l_Zw%vntA#V6JFPS>$}xugq0x4C;~BN zey+fQD4~>!u2kn^O57P-!||P6r#?EQ?8W+e_0*QlU&aFMx35Ug_D=+jKG)$_C0bL^ zhcVcr)cQEY-e+IahTkf16<WR%zpNTs0|zQhrh!{PH`-L7edp`5Cj#<)zDQs&Tq;O% zPjkLj6PRWBzM9#Js@%jho%fy>bfa@%6doFiMWXQw`SlWn?L1C_6YyPRn6RR#{wyg( zrwJP*z}S+**WtN6cDp$W6WUZ@AzGOZ+f%EzUi4}4ui6aTm7GD0X&3uE>6MZ9k=$y3 zB`PlxSBS#gkxxK?!`ngqzr?bzlf)n52u4{xLQ0~+Of*fTNLAHpb^v*<LC-Dq!U1$- z67hfYi>9Ph#cD<T-UMe^W+h_=hQ_MRUK7MIA6UXsUMSrg9J57xuS^yX%91^h(1sT^ z5%?7k?-b-w-Pm%I9uiyq?NpR1;YZKI-CfRwWk$F6;OI{A<1g-$`Bq$HkjS_2aJy-x zY7;DLfq6^t#+p)3jPHtF$jdf`!GLa$m-8O()Hl}LecFX<tuLYvWx5z$>}YnfvyfQ8 za|RUd-bVzsuz!A5S?#<m%j<p(1#B@R>zovf=5-FGLR~m5tLn%BVYsaLL`q8hK!$`h z;Q@NJSId<5jzj~mH++w$q(!_z8nS9x^?m1s9<4BQ?Bv<dDdCl_w^AqHH;uwK@+Xg% z+rx48m>51ux17Kb-07e2yVmEy<G1U1*mJF7aypR(;te>8QQ`kZ0IeF~=1R@6BNVD@ z1p|tzm{a+aG|L||8>=S|&Fv`7ACw4K9P49wQ178L_}vkda`g}+BPABnW}0xgy9@l@ z<sftdFKrEoP2#Q*A-<6amP}xT7XHv|Mw@NYZeXT==HU}!&h~0n+AFGSX!Lv_u0<VX zD6eTIWC3f*6)Zg4PW}yat20X@=3RRTfi>&a02w5-MOp0ML2t=0O8k~C-bfEn^f!hZ z#OQu*tV7!q%E-aP!o%5oAg9ABV<p_fCKq7feNl>d|8--A+N_IcC+p>+$U*-1cn>RO znQ-9&#sr5dBFc5A-JRr0iz#zR*>$olDKA~d0h58qhsHCr2y0FNM<thcrxj1da$BHB zH3$FIlFUlm3uzGaQ(Xj%VajWD0q18#CE#BlAjADW0ZN0c=6I>sW8nS8Y)F>b<`~EY zSSL{f`SOGv9&}g6EL5Z<^hDzQvQAiI)kBBCswp~DtsSIg?de(LGEZP9le$kHs_&Ua zgb~rFd+T3-gF8&@ONNB)CY4K;3nCX;eFobaJ`zS$7|oBH`ih@5*)7YK7bx*_h<O>; zgl~SFg%-_lyIhgT_I+kqcfP5(9e#h4Lj~TU>vTaAv)^6Q|KV^860r<^LXK7)$+cD6 z@Fi$}{=?@w4`#Z}F4`FbS9?*X(=XeUK%TaIhQ><4>!v}PSZ_l{2mq@BfFEt07T5nH zv91G=TIga~){a&w6=hK^Gu;qf`KuR@1zg|@yULoD*SECI)zQFcr_3k0MVaDKQuhe# z@;6y^<m48Of15xX1n|Ryp|to3$8u{=u9N9}Y9j7$p&r@GDMgp$W@)X+N`oK|hRkQ} z>6jMM%qKhKpiUYLX=7!h*fuy)^32_AN1no=DE+x^K`%v0{~!c0blwr1F$Os%%flLM zoCTQ#VaeDn$W=1lG{!W`nG{1G$&!+ypMOLXnwoz3#ILI8%=e3izUUZ%zp6p@R|L!{ zEQjogE9J}F<A*o@tZygyX;-(H?7kaHgwb^02O@bQE;?>FqY*)T+U52B=+W-G_fUJw zbZ+2F$s#_W?;3#%<VXcuU~aOq(+?a(iKqows%UqXeizn&D}!x~g!=M>F5yeqR@&_$ zzY-Ih;FRF&Z;C3tySft`fNY`8ev@OWrbO>Z#6sHN)>Tb7N0YG(hE!Wl?{`41(}Y0G z^R)^6cRvXHAm&456oAWeVu`4c2(Ji|$O?$ZGA$nnF?ZZ~I;=Jyjrb$RumQ;wv?)|@ zo7{)2XA3LlGy9pok!VWCxBS*K&rgwGKD-vZRzZgPx)eGs3Iq8Fyqx5J$z%BSM{?gU zVSG|g&qHh*`is>W1jipRYBTI_Z!?-r&tYo;#`kmCQ*hn75AWM<m}3Pkyx+;&uU0zU zIo?UrzH|rOzQK~r0DXTbp07xa{sM7-C{)`H>~>3V9uXDAz8+hGSEoT`-J987!D4z1 z$sSXeAPWEBw?VJ<bwLXJS7<78ojBx;aSJ{8XxQ@Kex}6obb(R-1$pB<b&1gCWh1xi zUDI;^Dxt`s*6v9n>5<@&zR3E0$sfFBdsT$wIclfpvZ@bCLW3HMWwaCNh>f9jOZXD` z3_4EdF{u^dhQ&YmG9>nlLdM2G;XnR(mPBc+mJKK;?P{%24o9(D{_g2N4e!$4_E@2{ ztkVW}LJ{Pcp(a)urB6ui%77ySin&CjiVfpW%muYyW1j?nq2+X{M}Lo<z*+jVu$j`U z=U<*rXpcq-t^zCUB{DajC^Qh_Jr{_iKnb_?48{~1#(R^%Y`s?8Jy$2i)uG9#|5acs zqYL*b)we_8#RQYauOg>Xzn8MTwK3#$y3g4Ay8DIO^-HWiSEbDS!rwiz{?YH{(<90+ zG?P8P)<H+?1ODbQ%j>-k01>hro{5XDRxUCO)U^>wC>bG0jZX+t;}gSG#z3(i^+Q1q zCk75}n?@H@A0gJpDO;o<rkCd{!p)(ouGVVM9}l7tljA~RvKl>!r;=raR)q6TA+xH$ z*j5dTbqHmPKW3S1qUk&iioz&<GO5iQ8~RRI-*jroPO*+f2Ihr!49?<$8BJ7VkP#CC zxfR;){iD%vkgV^XFuF*Xs`QiDN=Nw5xpPTpi}l}rm?IR}&*Vyf<;Eb~UMgo|h^_@T z3=-Z6<RX}G*chOrqln(G&M{#rj)`GgcGbD}o?Y7D0<|k76vrSFp9GQ=XyB5{qz7f0 zx5^KR(&>#OD2O0bvsC^K^b2)Wi#zyKs^vR2_m+k)5DwaN>=}l>&*Nv=Loq<vR%g&q zCkSE)M{D4L{q4qK-TunZ(9X>qm^4|Xu98o6xInVJmcEx@C+kwUU+$s$->xJLF7bE6 zNp#i38dzyrPNN#sh!~jJMhr04?Q&H~i19fIx7EDX)(_X5O-I2pm|%>ofFXPS`sW-V zmEZJgF~`T->Zt4OdP@~9#AeZV)P)P~{BNgd1ZCt^wuIcJU=aoQ3aMOMnxdC41%{*c zSXm3N5%6Ft{0MH0{(+%tAdkr_w$sQ6dxoa&GJ_17yGwDp@fXHVY|4^J!<nT$9>Uer zmA+KPaU`%cnaIzMH3jSS^A-Pslc2#J#e_Qc;(}#SU``q}aUa1(ORgX}BQAsyu1*X* zS@kj9xAHW1h+aC(aLg0cS(75tu(-bX*x97p^y}Hew%~gw6%$lD|5d|-mQB%HGqWtG zIo$6Q4lmy3H42cT-HH*}(XbjJ`xhxa`2e2U;Vc7BS;o{|6!n1s!luN|%2NF9FFvR* zmb0*Fw4dey0+IhJW&hx-Jb&<2o@{TT)_?!PAKiFExS!516`*2bxh4speaXMa!auX9 zl$jtZUqD#x|3_{9gZvf?LfGh32)eGQ{{PoVMpquSVT3H-`5y}V2RA;!1c}p&m2Mk8 z|BC_s`816kqOuj-Dr26?+n>F&J5{SJS>RgrQaH)R;WbUehnC(qMPB2_Zl0T>jLtDI zo+Nv|<EWxSf++o7GA4dyEe7aPQ5fLx@0I+i!i0z08(MlnQ;z_9^?*RpuD0fpHvCe% z85^to<sJL7g^uMk|K*s`6)Aw4=Ev!Hqw6UCx*&(gU(KznM>VwnTiP7BC6M^uMoR4A z10@7$>Bh#!-ub=+v^+#Ad~IsNdFCrR2K``TuD=Foc#$Qh_B^0*4+lrt)iv6DvO)_` zTH3nszvaRKVe~E$P4}9;aDI``&yUKoHgxvOje#JqeH^SFgNUwx06$IFW>sjH;~?^P ztN?L0tIgz<MjHu`+?*paH2kl)HVp@ay{9ic*=gp3tK6B`(uJO&I^o8KgnV!bcaXY} zhheL$wSHO|zg>>!z``V^&|H|Ay*8?h#(eOrD)(B<4f;%9Mn%!0wwmlb%Ar<b>I^$F zIq3%YCHr@iq|yAj!cmw#Q}6Zm@%vMR51FqJNsHID_{Q_d6w8f}MW6D?TrT4{(3}z) z_E{&Ed$-614hJMTkGNd$4zXT{K|H!huVMtjy<!6Oe?1vFHKc#w-qBQ50XZ^K#Kg6= zKX9+qE~d3|=f;23<`Lc^b&ifS+%$ev8EnCMJ!0I<T1X{dP>Ux~Zzt%7ikQxIr{9*i z7wGkHbdv}&i2vE0e|E0|4ESP&xQ&iIE3Vkh2e?8|1aMn>`?ufnqKM@h_W@9cz1XB5 z`6G3ug4Nb)670HfV;i)v$)Hnfg-11OXhxIOfPjO=M7>x!gDm1NNJb)+@3Cc7QH_6j zd;(6;KDS>wlxm<y1&>fuC6lJ}U0bh!1JmyMj;8tOhtTr1<Bx`1`9B)++lPG#UF{mf zx$ym`Cy%fy+Va|cxvxyCS@gVLgC)XiOqu7s|Mvt`gC5BF=->-3CaAOWIQW9h8+i1+ zX;M^i&3NPNg=y<e($<n=oqA)Xax@J>^8G7_Vu2c&#EfK-4Ljs<OP*NN9h+w!1#KRD zNhK9n*iY#Hn>&?80a3ZROF*Op&C_*a9hSXJp=2|h^J(EEHWve4!BeRky;h4=k<5=W zq!xCxR9nZ`-rNLkv<w)?@3nQgQfAA(?h7m+RHZXyC?+i>1K9v}3l3G^i8E<wd6Hh2 z&bt-|^{#>5-VDnUtY?m+D_p!r^fD85fioV(|DGT0;7|-qyDP%q%UdSg0ct%uwrfY3 zl(ErWU8L7{clOuf6Y}PKy&^Y8v3s`SZ+cnTU42)z-5TFjBVu*!%e@l@3*;@XK<U(l z(dVmE^>S2GE-4B*6(Jap-Nk;Q0T9-&Kep$}^rW7FMtS1Ip$hyWHw%|05w;)o91tlQ z>7BnOo}Vo#noPsU@|{H0Sp7wR37{c<r6k3bdm7*eC5<)WXb+EH-)4;|VAp=fQ&%l6 zoA2r|=7H9!qdtmFPnQD)(iBd`Du>%F$6s?7djL)>7K<A1S$raiOeL;w=Ul#+8%H^1 z_j1=Dw}d|EEY>trRgX^$7w#6#>}|u`^>Kkgs3f5_hnr<ek8ic`%*=Onv>%_`NKFCX z-_qV3UF67ewYyxr<S+_uhjXSOJ!Xj3c~$K6As7L5L9D8??%*j!4A&Uo(S`?y{lM;a z(ioX)>X*TfxxTixbUK626@Txw8Pu1UB-BmiaqmSH!_x^(*Je|1%Rz@16hcM@9Y048 zY%xLsZcZ}*r73IU5Z!@$1r({U;_mM5atnbpXo`tKe7Q-zMfp;d+}X6Dsq8PwXd)p+ ze{gUtw5`iI0SZAfnNVLHAqqAFeK#M%A`S+2@g@2m*?wx`geIe)kRW9b4=T!R*?nB} zZ>rkT)pK%klUr{}p|%Ll{*mFBJ}sK<#Y56Qcp`}bBlTt4wF`gGn-dK1u)f|0_BMgq za<heR>WdV+u3O6b#_DE2w4*cDnWBs=&CO{w(x0XVV*?<3I$O+%%f^XMm0ZPoJKkbx zsw~?yv2n&B!kTT2H3@i>d`6SBndw_XoAGf>xBcOef5#dbtfx&1mS5Px_p^i+y#D^B zgl6PkESiEn?8b_8s}W_PNMW7)@5@m60WPs)m-ljW?yG_B*GlRS7Ca0wO8p!S!5^n` z(2L1Ng@o{WW~`Oq{LBl_D!iy_Yt>q^+7-+n1o+$N^)ycZQm*3|;BMM31gls-b@S5p z8%hKJ_PAL77NNq+C@{!)NLu5=$lt6=)Be5sKO;%~ko_fPH0_^HEC0Wbg)#qdkeGta zyzKuwJd~m6M00XmwKUVq7ecaaHM+`Cfn)v3+1?+B{!>#3gZTUR0Zrf-orT6=c^;0& z0fmOOvdSTczJb<7(tJBg8Ik=)U-{T>tYAatR0?beGQ<zO;^S4FPB^WwPZEWSfFsLA zNbpU{L={TshNjv79$fw-WXguVoAgD1-m;)-&u{6(szDFRm8PMHCm(|?z6MKwxi**n zVSV&dHq%0c#IhwZ$xvfoJ9?WU$=YU+u<Eyi>lMP2zF)fg*Plc;s}(0D#TYsbki;op zGEj)4amV5eS7}2xCpRk8_^!9zYFF>7A8aRuFjB-rqA5ls$UZaHYL)K;e@~H~%+vtB zR=YVl+BEB7SN(YugcBsX-W~+}4c*#E9!NSKw(?6%pmZJi@1luThCbY$X|L#|dG%E& zO7qH;yv|@A_Kg@h;N|Yt07|_{?&Lps3f`BgSzIn|Y@BJ;bMP+h|7c@vEboZ)8}=3d z2G>bSB~7=(%HTmvGmpm7e3cVB!kqMEzOK09w)d-T;Dd`oRRIBeO<;W8xnwtZ2YZVz z?#W7Sl95$q(+E<kAp)A=QZ7K9WtFik4k%6-u8`9!g;^riWaa+ZqvEY*EAHSXVW_(o z-uZQpmSCyrL+8TGDSM9%$!$lV)YG^ab&2JJ6~ayv!F;I?XP2<-)ybp)Y_zhXE7RTO zY{MfojI6f3@bQ0k&Ad2i@}&UmqmSQ<lGPWmckimg9E%yGhb(!Y51W+&A^Yc^-X6~J zajTc9L!Snhh$EwL6{qM*gS2~Pjgjt+KXJ+T5sJkQ_X=K**MNp-CZ?Nxj^Veom+vTv z;C0op*wkqr4n#^gJ6C8Hn4DuXKls51U5KB$>`d{7*UgQ+{IUMmT!(3>4T!=S&uGuM zAIQux>O8>J`+(;0yWC09L9pO(Z?*y#rEmkVf~bDbQn!0x*NI>@&np5VH|p&d!KngR z`o*g&LzgB5LiWO-ywfAPkVcTWc_@=y&!Y-91bE|xI(cXJ(mh-n*4w;E9xlZ|`l*rC zq)1y~z+DyapVDAT9qp6v;4B-f^=LG3F5i|N8rHu!`4VSAeZUZNcgWKAc%Z_w*jya1 z!JdeA_T`Hn+ptlpGk<EBHjYG-t$Dcfsh?jr9X$vV-c2aBFN1S$jvwZl-xdXrJY?P! zy;(fV`z>sEz@(3G|2ed#WG%6YUlVCL#84wEBUuJL7u@;gXB-xR89pX`FByG%*9hF` z7By7cRVfo=@-MJh-6k6mYdcvf);BK4E<?#q=LKdzh4J9xwCk27-Nl>&`a*rxr=O(F zNjDv9EmLwY|D2aOEaXOS9ldG$yXPA6>K|@?oXEPZ30-xU<&pP@K6dn}y<{L2N}@Vt zq$VkJ`-8{ZuaC<kudkqk6?SxN?2Y^USYGB)HT%>DZWZB<$DNia-yuJDomw*TL_>!= z;Rh^yqiu<G{1&AKrk9MFFdNaF(Z7Q4hoG9|rAan=@op`|f_+Qg&n-ixQBYBW7@+&H zTbiz2g5+CJIYp)6^_q5zfjyy&;Tm;(L0y48;6(Yuu4?K(Z8kd;RJms;@UxxRRH^Z) z(M9$Y#>)YxzH=Ebz+IiD#rnAY)cG4y^n_f-VGr!m4iyfIi$PiH-t|88j6nvSdz{8f ztuDio@!&#%*zj@4WA2a1;{xo%A0#?Y9CDHdwOT%igR1)K2fNyZga2*o??7z;pvdvz z`}15w?j0ZikeZx*vcYXH)<8@r%Q{tNY9Lc`!C?z!mtyA5t-f5Vn^he?;^^pTR)h7* z<?ZD~SL&ndzV9QJMEGPqBj+Q3PpxtTS$D`|eZnsH9?Kgf!S+wbQH&2o=cZPi+CdPD zrF9|K-&-tkMtGSrlceqP)i-#$R2y;qYk;5spy+6+ktHXNPj&pNQzqOF!%*q3<eNs9 zcv~1f5lg0o`S9m%Ss%~{FHoF{koWKG)WmL->*Y4qtNYc@1#B<3=yzMX$|dkG;k;!= z)%)1HKl$FelsEU1Gz_xj8UNcG6k9{dIzUl+a;!^*@r%KoJwPO;?Z&6MG-&}lP9a$G z_7btK_g)06N5{u8Hx&#G4ezgRD=?&^m$XX0V$*Tezj!+MfSa>8h@M3ZY)f-{xAXTI z;zW#RQjXeV)b%YigtHlH0xZuz=w^+YHPk|avU>OgfO84`^C2ks`tq7V_lx77i+}mP zL<2<?q@{BJt**0InA9|^tN|^q$A9ABu0w_mCN~WJmF5sIK^%bQnMenNvZNHUys-+` zvMf({=<6139bRB!yzPE?T<vQWI}PF)oDmAAH#uOo!6Kh2EgE=ZhfH3VI)Be-=~=m* zMVr9?2nY4_GL>3UZiU1{`eG-0XX1EraWL_gC2!_*ZRPtaBYTLJ>fbhm=zjnG%FL;i z0R`JUK330QFX(0tPc1WUzN<^PdvLrH8ry=fD0V6q#vhk3dpp_h<^hPhIeR{PS=6`W z-QVJJ`jrZ}+iz*T(}$Q?jgz0p_n)ne0)-S7&={Qf<3l44r`}8G**Pc!lh$8ITV*p` zMjSK<zT^e`WW}7ooeI@)TyR9bdAQ0B|0MssP$Avww9(#qK1u6i*#_oqh=H~B@oj&K zp_*XT^G3I1b{SK)tg*52?K-NH)p`puRv*97*wM5J7_0pl&chDK#Wyl0jzz>!$n+D; z*Vh_#xsVtpqD6XWaFAlI8+Nz`$vyh~%tgW7J1Dj9ldyV?$y>$-k+t-tVq$uV)El8U zJZ&bqG3kl$rx4GPQRbfj*qx)neLY$pfe6tbYdr*r6vB3Fj*i3GhB<RZYV-*A4@qBC zTA$3J@Z}wVZE{v5CfN|wx3=Y#7G$m6Fy7>)B4mp!?2Gkm)5yw2jcQ>F4RZ<2u`tL4 z(sDjeLABgI=^s$r3_E@L1=4u?@m=Zz6O5V0-hFP-*T41Nt+BzLxu71D9VA-CrKQQ@ z0-VXlvu?-%L*F(23uy`O3WNFXf_l!$ECEowpg5ymBf|t=zwf3g>fj8%r86_9F5ZRd z3Zrh@kHXCdDPFfTJSzC7`UIJ!h)E$iNSNEEQ1s32uS#rp{*lLvS(ckzM?7Vg*JBGC z6TjxqH`+rSIv#ROYHdyknqAsCcpa9i{gavWMC^5&@;badW*@J1tu8yfZ;uZRRnnAr ziMYRnUgjrnBlMv&1z1FIFp>Z-F<06xN$yTp(`TN}b!b6z=k`L4ofmXWAERQkRB<2d zoHhrz$Ct(zj!c-@Kx3<q76~ucnj=I-MIS|entvs+QfnGkVECDpb@5tAO`_XiPGZh> zOvv@KXm1kGn3`<QC+%jypMjzHQ&nC26To}J=y@^&J24B|(Pp|i@{B(m2|g!6DqBY7 zHJGt)4B9nNb@q7BT#shkEN#yGf;L$P&9GGtoT2tx5`%P^%(C6E1Tpc#7I?(lwYHxS zrlHaVm-ymbRg`^2f`$`|5${$xi>Zw%(tNVD4+Zs;HHz7sti$bCWJrlqks?S`?wWSD zZWkVoR20F~7LI}GR%a`0b`_JqLS!rUpW4)4R|0IW|7XFdPtkO~<P0>fVqVjRS0-=$ z=gBL{*`tCKgTkULuYd}F!<ji+wQ%?%GQnztXcDey_$5{<1#<B<x6OB9NLZ8{kgZe| z6kMZ#dzPL`zjyk++KTbJwA8je5e*JL_WP$GFfw>2(lNBeT$E6R{gNE-N$?7dvc{?k z;EGn+!n4dvLj(3*nC7#!hPt?LMZhf!ZNSP9S`R4*ltstDV5O!oo_ctHu>hc?q<_J5 zN|-wv#|61d^<RVzvu-XM77fxj`7x;M4Too~t%jv1ZdYWIwUe(Xu=#mswWI0k{7}FP z`9Dw`ckDmguGxP`T3If`5ik{!VdrTVGTH)rnoK`{teV_ADXU_2R2FeLo*SNlZk3tv z(@Z+m3`NJ)Y5n9F_YriVfv3e`P<)kqCO&@Z^_i1zzr0<sJlMeqbtvjP7IU(izRZ!k zH)oWtW=dfa1iI}=sf$WN>p`FkhL9uF&`Hw8%R(M0?}uJfPXb+48)itByDEP*U=nE_ z5lfPxssUw{-4bKOMFu060jH*cUT3eB=J9C5o_NI?uV>zOW49)ATcL!xd<hKv4ULO- zpB67SkAOCPDTk7<bC@W*!!DGmwuP4Zn%~B2=su>)Z~a924?((G81vDO<RS&G$%U{K zzxtCn3IR5@lfQ|Jt9`hilgdv}9WFP#Yh6}3$pxEa_vK73GI%g>aZf{-o(u}2PkMff zeLE=W$CzivKs}Rg2Hpo96vU#w%xf9w861)}BQY28%V~OtEFRRuX+tqUR0M;;Bf`TE z50`3`MG~GabTD^%d{QR{#f{WHpEn_^nD;~>c2Hwu7l=A>P+z$tr*%+g>z`4Tj`88L z*>^tfSAAbmh}TdAd|s>90oevW*Q?CtLjN=g-m^ZO08CL?$ZCK4K|$&50JjhTePcdk zw5Yj8k$1WP#0-yP9=nKSvz&<Sqg7iIx7i&~xUTw1u`3bcqS`y;p_C~|Nl96NHHbYl z3LM6&CyL28(a_eWA@Qk~0KG3@Dvqq4CdQ5>0~MlH{lJ0yZ!bPH?(R>dHQ76tJnmbT zLdn~`!T9_c8nqup00HvqMn*YEM7-imFB3>SVEyRBbiMw8u#`MJ&}usztY$-K+t0Wd zYQX}Y_p%7`6w=zJCNRT^!wErmp9q=h;uX>b+4rpmzAn32q+Pzg*b07%=m4emGNTK4 z{P2gnvEBT(G2{QRba!~oBpY>b^vh?4k3qbr+DVVg&MOgl@cI4W*dSGa!vN#cdZ&wT z<1H#G%g<V=2Q*q5rWD_TeVM9Q#aiaWU*#`mF-TDt<YXd51#l~~sir1oM_nBl5Iwr; znzZSSMY0Ym%?v+MNrNb{Yk7D80emir221uf2amb6)`KE;xOyK`A_++oBnQB5A}CSQ ziR@$)6EN)j#Cv2}Ppbx}g1(bnKz*(cZXhY|@Aas9YCWwa*%ASkfF_5DCFr?O<mZ=l z{Ahe!&l@x+lLwbJ;Q@B~0AbFOF=#wpFS%;(MTlVp#X0|M8XWKl;Z+I0OIJGiVu_ba zl6UEYiPj0Y)~EamR+GLj?t9xIW@EqLshEy$CXrNJ?t@o){v0|~N?B%k?&FsP@5DYw zBDvNddOwVAviowaJLgkSPz;UXvmvpV6NH_-K5_XC`GAjK6j;c<=7#tN9-p&Pjehvd zkYbt4&#Z=tX?`*%E*8#Zw`4VA#rd#^`$kn~0idm`Y=bzZ_1URRVO3t8*MulK)#?Cd z@wXhoyWib$MFN;R^T9@~{9C*3>wkaCW$<w=f$B-V?nQ0FLoTC>tS70Dcty|^K&DpA zh@G2bj#{VN4Luav&@;sXP+XAMKWPg--LfTQ>i*VBZl@v-MhyuY;MQq)2HYT9nn*|# zw7oq$&SBcXV1Tx*wC^es!j6gQ7?%(PVkyt#7e`#RuX1m&HpT-)E?B$57J_ibVP?d% zU3p~_tgM`}(b!2cHk$r@5696#nngb$T3uZsRQ9^M_%Vx(3|G*@E*8~%e0nKa>wUi? z#ULfbJeUuE_~1G`y(62-U*0)}CnO)8qB&GVYmE^`#C0fgs;h~duDO;ilW!8_=1&YS z=}&<genP7QZO$rKS*0&%{d13mIf>|ntw6{XyWQeMx+EYK3^K9X2hnG~ymSs^X--N_ z0l?><s#(-G*zAW(wpLHIyt?ecr3ldkpPdmt&0_i{Q%(x*IygL~)Bkj<GB{X?*WhBf z@B3(kUJX~T1C>}k&{clAY?%c?hMc@#Rh2APG@h7Hq$q135;yHL^Oo3+hJ6T&OX3p` z3zMly)tv_u=kI_gBiad@Cu>hMK1lrd#QeQ6ouWCT7TCT1Fa!|#HS2W)gBqQ%yg0$O zq8)z}gm?)Zx9%{+cIx>K<WMy*aKNEsY`YP3cUq2MwcZh@8ou;-seXN8jxe7e;X-cS zxwW%}1>(fB4~V12qW8iezWm7YSt6v(URicr0OiR!B*zGDP<bj|rid952jFmaE1>A$ zUde7`np7X$dJ&ufJa6H+B5Ji4_2@T~!=|bg(~bzt#+vVKkgzsHp9|u%eUT7r1I%xa zR4n|iLAGC6T@T&}{BvjI3v3yoUN^DBp?ChrQ2ii(uuJcmdm>h^BjvEjGx|LUk1B-& zoY$BbVj1e&(gB>?c0dT_u`-i1`4}<UWQpra{Qb#_&PdsI6Y(S%;QN)%C-bjJAyh7G z^_hKa#zSEEc=%)m`_vTs%Fz@>`?4JJ@TE42BPR-c<|NY0r@4i$yhFC{zm1mL*fcIO zxD;R>kVB{%v`z9nhO_4Ecr*<d*{G3vMXLzhpW7+mq1g80%XGr>DSU*LmQ!@V#y@{L zvzyF0KY$(oY^FhC^7dGj#xaT~xA_I=!pd`nF&okNTg<7)TGBtXxU@80io{bMGz>%H z7?VT#SxRE$Bmb?I{@3Q=i8rgwjQ#UwiLU?b4*@83wFUBz5Qx53rn-zoMk!k0$ZA4k z$;XlSln-7_hDhh;ArZM`;yK9+nbB2O_^|{lfSHW*bGHp>5jn01XHJJVxY<dj03Aeo zJEi(lBmr^{JVzDnZ~6`$NoD(D3alJWx4dEj<98SU5z+;*(H7TrUibjtnT!lV+CFto zNC2L7r@S~luxPV4R}5x!#n&NL@BLJg;kjj)5&5M@I05?p=K1s>_jAb?czkm2Q+>8( z774+uS$m4kUOqQUIZ2CT{@X2P7VaZD&=h+v?>AP)^=}qN?bO0n%|{g&g+cW)f{qkg z$z20UoWm5kyQeT@&CSihdllbolUN{)be_E!nX5h_u$vf$apGrO{|E)Ge=jPA2Fyw^ z)xd4C4rT~mo@|8^0K-lPa_`H<R~`dR^DMbKU6NsndL(_Y29r?(nVx|1M-gu`iu!yl zCArv%9}Dl?`_*Rw?p@fsCi@*<#lE{0WA22R;u6*&juw>feD52)P1*^!fe$)AO{<{A zSZw9v$An7jUj6*Jd2Fc>re`2&QkW)dKB3-;1ER&l7|MF!{Z&$vmi+VcF&kb%*QYjE zI}yCcKsTbv=XX~0idPaTUqXd_LLQUQ6Tc(w;R*Q!H?68qoGe&MzCS7$O6@oPS!!)4 zFJZsU4|E?#aw=YDv$JA5U!UNQ5h?qULC!A?g7E&j0>??z%ap@pe#n0D#1fUwn>jB< zJU)WW?}Vuz6UHCp!^U(OhPH3N>g#9lKc0pdo#K(X_4Y+Uk#jv1r$5G)YlvaG6gt?v zlvQn$*A*_HsWyV9C7bM-_SRRJ5sD4^MaReK8ObB}Y(Iz1ZfgNJ<V0IrLm6+N{k}9M z#s1)y81QbJN4sI(cIlQsgp4>k@-I}PxKYcort$$D@f>L?9_Cv>712?_>5gwWSYnvD zJPO~f`w->cVQ>MkNV!NzXA~UOYD5B`i0_M8f^%Hq5#pDXgTGD*zdE$vS>(^}cWqx* zwb`(jq;$0f6bJV@d^=l$GR5d>U~|ru;4-7ICPeyFIS&a1EzaZ^ej_J|8vo5os_u%x zx#yN2l1t}^fRG}ty@&G2D47L1M}Z#KZ2DZ|6WsnInM!<gkcM?N3nN&r_eu8fbxKgm zaN=~$_4I{vYC4=+82a?}Q<n4a7<0Upm0=MT66eDqg;yQ%$Vh^=l{$U3b{T>N4DD3f zz%5FU{>S|!YBN;!`gS8BPY8k)RkYRoYL|0#h@SBKJFb~EZBWsvs!c?>6~<B9s!#Go zeU~-Q;R1!DK@iw|+hg;tQKo5%t{wE<WIIW*o7-1i!M-=S?w{fk$3Iy_cypPbN#~ld zt&M>d`Jq?+@@7&n2wL-Us8-7`nd8ztz2s#6hXE?YlQHSn9jS-LRfjlwrcV7|el&TC zVk5{72l}2-KMM*>c{}B^26psY`afQg#eo8#!YUVfooqVriqR>LNomRBR@*PZ>{wB| zFN;U}?E1r-#!8=bv<zr>cS8v5DZ)r0WvW(M;%`s5MkyL+eEUMRr&lNKo7U_!FAj;v zVWTV8ONpQEm<zy`7(I6xmosanX4q=YMt;Iy^w0l<wj4%Yf{;$R^6`6{q9FY`V&?As zgn-XS1+M+wzuXNr4i(MD5r2vETuDZ~B<KPXLY~d9d&-sVVjP>^7&e0@(9|@_o*uW+ zn&x|9Bb(QcT7eCa$Oi{vm=0FJ%Yqj?kmv<<G@o8DE)3XPef?(3MkK_~s(xU=JHimX zGvYm>SUZAm%jB3Aef*3UJ4JrlC`YP!7vffUFjqjsALW2Tyd)Jaw~cH%?pgxD<LxEF ztd`{-unj>^d0rd|BcmuEnvgihV2UU<>#zEa3@+f_Wq3efD$j=zzB-5qXI_lXNVe-9 z7?x`|Tndhsue)-$w?|mwiJ~v0yHc<0Qk4!}e=n97L(5Uli!73-(3;Amow<Z#fK(9` zXTSN+Q~ugYCd`UOM0Aex;+yTGTIdHwX*ACZEPvb0oF|n?SR+uRG-Bw&e)Rn=c|XzW z1J^ps_p`B3GP&cimZ4WPOWR8G$@|+LSIo%z!v?dP_dCjR1opn1;Wy$|wt@6}>44g+ z^Vt~gPUdWCUt>6&aae<I_cA)SFG540VfLodv!8K*BFXKK0jYU!z)NB_#7YB?<I91t zH#uhJgjJEO!--7O(9?-^&vkE`aZJkedX0UDn5RJmdBaEVPPn~{WBp?JC`U^x;bU6A za8eVI3a*$+;T;_Wy&biSi^xIIl8RM9f5hR3J(O?9slL5;!DtCqGlJa5H|Ga}`c8Lt zR>L5Wr>cXBZTmjlwel9}(`BoZJb)d3sm3;i|6#Ep_|c-L%`c+(v*EWgvIcgUZ-*q8 za-Sb{q9AL`w*+Q8QbET*GuY2|jJB{=EteU8)D>#ayiA(?k2U3elHlDUnUUVMjP+?` zBL0q8KI#egKZpAswVPoDb!22)gQ2=z8;Zy}C^BK$qDLrALx!9l3~X19Fwt$~5d%~@ zkkXN+=!N0=p^ySxIgW)JZ%=TbP_Zn{Rxg<MgXyV;YO^O2_!(+<dKhdBwH!8}<HvN6 zl(kC@foM!4V-xQlU{Ke0g?qiE?O>wO#M>>ocf)-j#)abBlD>R!+zo(c^*Dnv<(g@* z4Ygap236E2)=$&Ghty*?L*htTZukw<WFhyp-_L1D<Wk0;kQ#17bEoePu9CaZS)?3a zwtURg+fF5Vy`1GlExS904$GUWi?M34MwV18r5q=mJsm)`<ezRMN-SsVTNq)`fR(&g zh7z<!s|NweN>n;0!D1kVFaawoYjvG!?O2v~(liS1=8cD9PqWJ@Cr@PCYgQB?OOL!- z8APB@%VL!wGv$vN5<b^RG9kMdwdL|`y>BrjLK{|kGF$Np2{n&a)zf{o$c>$Rl>J^u zMM~)o`b;HWw;!v$UtHN3<ynVP1r<SAM;YKwf%>VO=c?l;vn;T)!$}(RtX@N19%4Vv zIKjXW9c08s)Nd>g4+7Vq<g_0uL4Q|Xx!g)pYIQ|TyFk%X)rO<_%M*6&5I8V@%*Hd` zc_recJvWmQ7g?ou_{~wnr*lY}E7e@+n3Gk|=jXK7;r>4Sy1Yi<>;3WU=&$s-{%H`7 zu~feud&NEl!n5&1`qwA!X!u05OOOw_yearaiyJdmbmC1g3{cGQ>Xov*@7g8=<6{5? z0l9YqxXjLoZ6ir91#Uu|4%tT=C4zKPD3VU-&qBZ$>nRkmmtmrE?hl#JOd?TKrxeym zJ?cV4Z)%XBS0;2sUZZy$qskXRe}y)^QJt)tCOPahhlb^BN?@vcEje~$>nBxn0X7U1 zB>al5n=ho~hA<MrqtSsps$h<zL3+J4R&*E?uDuh?Q8&ID)X&;c-92S}DuGC0OiWdY zfD)chkj0-W%d{(Vy96=fRngY6$FiAJep7W}xP0PJSJ(Ys&SdbK$p5=*asqR&F=#WT zKrWjrpUIFI$v0jD0RHW_Q7ICM;20x_G<DuD;+qM<1YsOt!xlCF*+9ZMHD*Z~o-d8D zG^waXwP7&Vw6u3vYQxEvZ3do=r|#>@?vri0)G^2fJU8xq54bva3(0KJX0cEzHMeJC z-ivqre5VJ^mV%bNvv^(_Lp-C;jvM-B8mk|5h~QqP!g^tT;mSk9{L)v$R}FbzqFzaM zg?VCxYJNp>C@EzT&Jpwd8SrYHOMoLapEXb~C=X^6mty{LOTuquayFDX7$!;l2Z3%H z;g_x{qBIQwYL*H~o|U}PUf;qbjjxd4-;^NSEr>5n<|`1-D;i+$NIKzl?$Yu7Zn}Sg z^99Ox(IgmsDeflM+LSQvCoY1;%Xm7yEPYqKl@edX&hGlkf*TC&isZcd>8Z+GukODk z_#+~?k6t1koy`7A7RhJJHXq0g$4}Ajc<h<83*~B64T|<5r5`=ew;B>?uF^zy>m3Zr z?qgio3`T1m+*Y)#aNmDax>#iv?r{Fj#ze#psh!zKl=^%;Rs{Tgma?-omVW>lY3hv> z4nKO6(VbejSgv&He6Zg<VuaAN<Lm#;6{Xi)ePrA82r;$9wj0}_orf!LJA*%*vvlnu zk)n<~<F<}uFA~@Aw&Cl664IEW25ET<+dTeKd#yYP_e)Xo0>eZAfPQyA9V~_-pQ2?h zxg|^AM0Qa-vw$x;;~up)7(!m%Q`@)afU8zE_bzt}1?SavRD{IUM&&qT879K-pPTUL zN}6-&M#*}Xl<<ptSHQE}ngRkzmY5@Z!M?EWG&DY*1PEheAV9}rQ|xeHtasshs&7>j z{d_Y2tan<hT|AbkX1*UM60>1;n_RfxP>zY&uQZ$Co@p)rkT{-t!EmSmll-})tEe1N zU-WA7uCHdl&eC#UnI8a|(=s^QZylFOe<QPM{XR0&X0c_zRricNL>oqTd`?^5Qrap& zh5Bwv{AJ@N;HydyuQoG0ecdk#9%kD*$wyErrg|v0rEtCA^C^SXJ)wbd_%LxkOYaXV z<9{FKm%?0(Dm?eVRK>heHxdk*!T;3ldf<{(r#N}~yi@P}`H5Lwax}}A!d0R7^0lRH z@LPh`?(I>#8L%b`Gzch@5*T+--bp!utl})F%!F_<T^~W^D3Z{`H?ni!Kp$~OGcMPd z-~F{z<!&*;WaWg%q(zSNeVB`??Cd1y`+jdeIpb^)FV+W-;x?E04?hkMTVvS|Q@#w~ z>EL${@P`mgL<(m3_U;JQ8`b@TBl+J4`W>#e;~UJL!}7Z+38*+z&t>Y<th05t-@`&2 zUT4<*yk2WOi4fviY}!8gkN_GedwLUEQUxub++kFMXz{yvYP6uFhgE@jXo=>Zg`ILm ztFAhxT8prFl;q5vzt`#uV<Vos7o!I{l>w56qRREcsH5C8Ojo9&e#`GRSQ1K1#eHYX z{JIj{ShnL)7MNt!fjE5F(57kN#;=4E<7{9f5S2VH2jCp}Z$r~Y-sM(Nb?LUS<>l*H zb!A8F9b+rF__F3=KEaWDQT)_^+`eE(Fljr<KJL_A-x8pkvLNQp&aF6UEw%du-0Q)E z3CyIjf;Nb@nd_<*G<#6(1>IbJR2MFh?7<t4GqC8kdG2u`X0?~_t(!h@ix8?<x9s6k z49Uuks$g>6%8zP+<~`?x;@^5MQwMA(xz(fqd(Fp|!<JuVc)XUH6T1s%ql48uCYFeP zUW>b|qo74=Bt*A)oG8F3%;u}%1e{fjEpvyI7wli0Pe%g7G_7JlVBVi6Vu}Xp7U+;M zx|sESHA_v<+c)F#@|j?c-*R)eGULG85cl|ez3S<dF~%mtoxlb(qrtwjlF7~6W5+7c zg*$Kka8KSsgD0Bucf>NjATNH#eR!K@WV4t$w%1SAUqcmvE~(ltB((fBxrTGPk39RD z=SbmXlTTwuE)SIeBuj+vwzQQymdp3Imi!{%m@O-;t!CYxBFgLcHR_+9F}$eCbak|? zw2n6zwN>wnnho*N4r213YI1h+2czXQFId8&E*6d01h!~W_;}Bjv!g?H>)mrXv~%z= zH5Nb&&RKv4(=_nq$4Vx1tcBf#rujdW#R@jW>;3oMCy$X1=aL{pnZxi4S7>o^UR!-a zf3%;4=BBVrzar08XA>(gTd}6|TUDg@adAFWl=>_ZOz$-b(zEOjpz184k;3UU216~{ zlPCqBz>V}4nyjkQ%^-{@f~lbaq=>VwS8kN*xNmrG*wrgLSal6f7xLLU*(UI-4kySb zPhU(0(o&og)Ans1&By6V6Y)(=C_kR9DPaBR%$+J$0Oyw73LKpl_pqqM!dIYn)A${Q z&qX2aZGBdr+S4U-)+G&(dTOz9a}TNd^oUj<(lIlGa4h|R>XSH0%Vkc<2~NZ}v~@&t z96p^mvNvWq$@mAl^^?f?3U}0+cmN2gi<UK3!M9k^y#Q`-TdyiQ_@q24AO&DhJ18eQ zcZ1%3iK@G{Iqeh7G@Pxn%`i}JF9V(<zc0Tiyon$i!!?>*MlnhO>c&Vdp;pOh3YXm_ zY6XuGK}{zMTPGEp@g2i1W3-FMfTw|NE5Rgrpd~QU>A<+<z&y>;XR>W9|LexY|C{9U zQib_RPG_1HUY&2K=C-V-t2x^2`kC$KddIbFoEM+a;<iqGvMu+{vMU_NSnON751iP| zQfgLxJ#IzkwF&1ng_lP+ePm#tF;``d=C?c096F1;QENu^+#`Ng|Ni|mnZ9Rjcz^a~ z#;pH5E1MKfsY*@iY-XAiwzWK0Bfr{9`RAg4-S;c9yrqS+7DO(Ysl>S^zkH$L*80nP zydKq5TFtt2?Rr|lP1_~ins*{tq<q6>D<yeP&(z`2)t#Sv9%f-%L+yTZUi0WxUj-D* zLwS>5dtNMy3d=1{R>|6Oc2(FpaW`+a>mEn8i&^SrWd58p$<!?@-4fou<yF3L>;3n( zrP;ezmc`b;zALS|DtD&z7M66S%yPl+$FlQhze(Tv(YJOp`_b^-Y`II9KD}I4nX_ii zxlM2{OSvsDz5kxq`&wD>RoT$nQ$O6+kBolCru%Vr5U^^t&NW%BdvL{Ur8&CE&^9$J z)9(}9@#D-)<DyyJO9XCh>e^L%U+s1^w1$MVzTdJlK3$^za@jkT4z1V#!!4<zrN4LD zZd(pD0W{zn!E(!->6GWoWqJ$5)`|GdSut@>vg;*gJ0E7NU1uVq57jNKz0ZbbtQey| zOU68}>no1lNLaaSSs2p`ogJH29m`=omK(xsRg!Ua>X&&;x3f{40<7Sg8AO*YPh92| ef9lTKcmEmp$Ln&NX-%5T00f?{elF{r5}E)!!+yd5 literal 69325 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 VC2>Xm(kb|(te}3cK+Yuae*h5h=#u~d diff --git a/docs/en_US/table_dialog.rst b/docs/en_US/table_dialog.rst index d825c43b5..abb009649 100644 --- a/docs/en_US/table_dialog.rst +++ b/docs/en_US/table_dialog.rst @@ -395,6 +395,14 @@ Use the fields in the *Advanced* tab to define advanced features for the table: * Use the *Fill Factor* field to specify a fill factor for the table. The fill factor for a table is a percentage between 10 and 100. 100 (complete packing) is the default. +* Use the *Toast tuple target* field to set toast_tuple_target storage + parameter of the table. The toast_tuple_target value is in bytes and has + minimum value of 128. This field will be enabled only for + PostgreSQL version >= 11 +* Use the *Parallel workers* field to set parallel_workers storage + parameter of the table. The parallel_workers sets the number of workers that + should be used to assist a parallel scan of the table. This field will be + enabled only for PostgreSQL version >= 9.6 * Move the *Has OIDs?* switch to the *Yes* position to specify that each row within a table has a system-assigned object identifier. The default is *No*. * Move the *Unlogged?* switch to the *Yes* position to disable logging for the diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js index 61761794f..f1dd27dc5 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js @@ -291,6 +291,8 @@ define('pgadmin.node.table', [ triggercount: undefined, relpersistence: undefined, fillfactor: undefined, + toast_tuple_target: undefined, + parallel_workers: undefined, reloftype: undefined, typname: undefined, labels: undefined, @@ -779,6 +781,26 @@ define('pgadmin.node.table', [ return m.inSchema(); }, },{ + id: 'toast_tuple_target', label: gettext('Toast tuple target'), type: 'int', + mode: ['create', 'edit'], min: 128, min_version: 110000, + group: gettext('advanced'), + disabled: function(m) { + if(m.get('is_partitioned')) { + return true; + } + return m.inSchema(); + }, + },{ + id: 'parallel_workers', label: gettext('Parallel workers'), type: 'int', + mode: ['create', 'edit'], group: gettext('advanced'), min_version: 90600, + disabled: function(m) { + if(m.get('is_partitioned')) { + return true; + } + return m.inSchema(); + }, + }, + { id: 'relhasoids', label: gettext('Has OIDs?'), cell: 'switch', type: 'switch', mode: ['properties', 'create', 'edit'], group: gettext('advanced'), diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/create.sql index 478e6d752..dafc87aa2 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/create.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/create.sql @@ -77,7 +77,8 @@ CACHE {{c.seqcache|int}} {% endif %} {% endif %} WITH ( OIDS = {% if data.relhasoids %}TRUE{% else %}FALSE{% endif %}{% if data.fillfactor %}, - FILLFACTOR = {{ data.fillfactor }}{% endif %}{% if data.autovacuum_custom %}, + FILLFACTOR = {{ data.fillfactor }}{% endif %}{% if data.parallel_workers is defined and data.parallel_workers != '' and data.parallel_workers != None %}, + parallel_workers = {{ data.parallel_workers }}{% endif %}{% if data.autovacuum_custom %}, autovacuum_enabled = {% if data.autovacuum_enabled %}TRUE{% else %}FALSE{% endif %}{% endif %}{% if data.toast_autovacuum %}, toast.autovacuum_enabled = {% if data.toast_autovacuum_enabled %}TRUE{% else %}FALSE{% endif %} {% endif %}{% if data.autovacuum_enabled and data.vacuum_table|length > 0 %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/properties.sql index e9bb22827..3d31fe60e 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/properties.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/10_plus/properties.sql @@ -27,6 +27,7 @@ SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS r WHERE i.inhrelid = rel.oid) AS inherited_tables_cnt, (CASE WHEN rel.relpersistence = 'u' THEN true ELSE false END) AS relpersistence, substring(array_to_string(rel.reloptions, ',') FROM 'fillfactor=([0-9]*)') AS fillfactor, + substring(array_to_string(rel.reloptions, ',') FROM 'parallel_workers=([0-9]*)') AS parallel_workers, (CASE WHEN (substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') = 'true') THEN true ELSE false END) AS autovacuum_enabled, substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold, @@ -56,7 +57,7 @@ SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS r typ.typrelid AS typoid, (CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable, -- Added for pgAdmin4 - (CASE WHEN array_length(rel.reloptions, 1) > 0 THEN true ELSE false END) AS autovacuum_custom, + (array_to_string(rel.reloptions, ',') like '%autovacuum%') AS autovacuum_custom, (CASE WHEN array_length(tst.reloptions, 1) > 0 AND rel.reltoastrelid != 0 THEN true ELSE false END) AS toast_autovacuum, (SELECT array_agg(provider || '=' || label) FROM pg_seclabels sl1 WHERE sl1.objoid=rel.oid AND sl1.objsubid=0) AS seclabels, diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/create.sql new file mode 100644 index 000000000..caec8f520 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/create.sql @@ -0,0 +1,187 @@ +{% import 'macros/schemas/security.macros' as SECLABEL %} +{% import 'macros/schemas/privilege.macros' as PRIVILEGE %} +{% import 'macros/variable.macros' as VARIABLE %} +{% import 'columns/macros/security.macros' as COLUMN_SECLABEL %} +{% import 'columns/macros/privilege.macros' as COLUMN_PRIVILEGE %} +{% import 'tables/sql/macros/constraints.macro' as CONSTRAINTS %} +{% import 'types/macros/get_full_type_sql_format.macros' as GET_TYPE %} +{#===========================================#} +{#====== MAIN TABLE TEMPLATE STARTS HERE ======#} +{#===========================================#} +{# + If user has not provided any details but only name then + add empty bracket with table name +#} +{% set empty_bracket = ""%} +{% if data.coll_inherits|length == 0 and data.columns|length == 0 and not data.typname and not data.like_relation and data.primary_key|length == 0 and data.unique_constraint|length == 0 and data.foreign_key|length == 0 and data.check_constraint|length == 0 and data.exclude_constraint|length == 0 %} +{% set empty_bracket = "\n(\n)"%} +{% endif %} +CREATE {% if data.relpersistence %}UNLOGGED {% endif %}TABLE {{conn|qtIdent(data.schema, data.name)}}{{empty_bracket}} +{% if data.typname %} + OF {{ data.typname }} +{% endif %} +{% if data.like_relation or data.coll_inherits or data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 or data.exclude_constraint|length > 0 %} +( +{% endif %} +{% if data.like_relation %} + LIKE {{ data.like_relation }}{% if data.like_default_value %} + + INCLUDING DEFAULTS{% endif %}{% if data.like_constraints %} + + INCLUDING CONSTRAINTS{% endif %}{% if data.like_indexes %} + + INCLUDING INDEXES{% endif %}{% if data.like_storage %} + + INCLUDING STORAGE{% endif %}{% if data.like_comments %} + + INCLUDING COMMENTS{% endif %}{% if data.columns|length > 0 %}, +{% endif %} + +{% endif %} +{### Add columns ###} +{% if data.columns and data.columns|length > 0 %} +{% for c in data.columns %} +{% if c.name and c.cltype %} + {% if c.inheritedfromtable %}-- Inherited from table {{c.inheritedfromtable}}: {% elif c.inheritedfromtype %}-- Inherited from type {{c.inheritedfromtype}}: {% endif %}{{conn|qtIdent(c.name)}} {% if is_sql %}{{c.displaytypname}}{% else %}{{ GET_TYPE.CREATE_TYPE_SQL(conn, c.cltype, c.attlen, c.attprecision, c.hasSqrBracket) }}{% endif %}{% if c.collspcname %} COLLATE {{c.collspcname}}{% endif %}{% if c.attnotnull %} NOT NULL{% endif %}{% if c.defval is defined and c.defval is not none and c.defval != '' %} DEFAULT {{c.defval}}{% endif %} +{% if c.colconstype == 'i' and c.attidentity and c.attidentity != '' %} +{% if c.attidentity == 'a' %} GENERATED ALWAYS AS IDENTITY{% elif c.attidentity == 'd' %} GENERATED BY DEFAULT AS IDENTITY{% endif %} +{% if c.seqincrement or c.seqcycle or c.seqincrement or c.seqstart or c.seqmin or c.seqmax or c.seqcache %} ( {% endif %} +{% if c.seqcycle is defined and c.seqcycle %} +CYCLE {% endif %}{% if c.seqincrement is defined and c.seqincrement|int(-1) > -1 %} +INCREMENT {{c.seqincrement|int}} {% endif %}{% if c.seqstart is defined and c.seqstart|int(-1) > -1%} +START {{c.seqstart|int}} {% endif %}{% if c.seqmin is defined and c.seqmin|int(-1) > -1%} +MINVALUE {{c.seqmin|int}} {% endif %}{% if c.seqmax is defined and c.seqmax|int(-1) > -1%} +MAXVALUE {{c.seqmax|int}} {% endif %}{% if c.seqcache is defined and c.seqcache|int(-1) > -1%} +CACHE {{c.seqcache|int}} {% endif %} +{% if c.seqincrement or c.seqcycle or c.seqincrement or c.seqstart or c.seqmin or c.seqmax or c.seqcache %}){% endif %} +{% endif %} +{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} +{% endif %} +{# Macro to render for constraints #} +{% if data.primary_key|length > 0 %}{% if data.columns|length > 0 %},{% endif %} +{{CONSTRAINTS.PRIMARY_KEY(conn, data.primary_key[0])}}{% endif %}{% if data.unique_constraint|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 %},{% endif %} +{{CONSTRAINTS.UNIQUE(conn, data.unique_constraint)}}{% endif %}{% if data.foreign_key|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 %},{% endif %} +{{CONSTRAINTS.FOREIGN_KEY(conn, data.foreign_key)}}{% endif %}{% if data.check_constraint|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 %},{% endif %} +{{CONSTRAINTS.CHECK(conn, data.check_constraint)}}{% endif %}{% if data.exclude_constraint|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 %},{% endif %} +{{CONSTRAINTS.EXCLUDE(conn, data.exclude_constraint)}}{% endif %} +{% if data.like_relation or data.coll_inherits or data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 or data.exclude_constraint|length > 0 %} + +){% endif %}{% if data.relkind is defined and data.relkind == 'p' %} PARTITION BY {{ data.partition_scheme }} {% endif %} + +{### If we are inheriting it from another table(s) ###} +{% if data.coll_inherits %} + INHERITS ({% for val in data.coll_inherits %}{% if loop.index != 1 %}, {% endif %}{{val}}{% endfor %}) +{% endif %} +WITH ( + OIDS = {% if data.relhasoids %}TRUE{% else %}FALSE{% endif %}{% if data.fillfactor %}, + FILLFACTOR = {{ data.fillfactor }}{% endif %}{% if data.parallel_workers is defined and data.parallel_workers != '' and data.parallel_workers != None %}, + parallel_workers = {{ data.parallel_workers }}{% endif %}{% if data.toast_tuple_target is defined and data.toast_tuple_target != '' and data.toast_tuple_target != None %}, + toast_tuple_target = {{ data.toast_tuple_target }}{% endif %}{% if data.autovacuum_custom %}, + autovacuum_enabled = {% if data.autovacuum_enabled %}TRUE{% else %}FALSE{% endif %}{% endif %}{% if data.toast_autovacuum %}, + toast.autovacuum_enabled = {% if data.toast_autovacuum_enabled %}TRUE{% else %}FALSE{% endif %} +{% endif %}{% if data.autovacuum_enabled and data.vacuum_table|length > 0 %} +{% for opt in data.vacuum_table %}{% if opt.name and opt.value %} +, + {{opt.name}} = {{opt.value}}{% endif %} +{% endfor %}{% endif %}{% if data.toast_autovacuum_enabled and data.vacuum_toast|length > 0 %} +{% for opt in data.vacuum_toast %}{% if opt.name and opt.value %} +, + toast.{{opt.name}} = {{opt.value}}{% endif %} +{% endfor %}{% endif %} + +{### SQL for Tablespace ###} +{% if data.spcname %} +) +TABLESPACE {{ conn|qtIdent(data.spcname) }}; +{% else %} +); +{% endif %} +{### Alter SQL for Owner ###} +{% if data.relowner %} + +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + OWNER to {{conn|qtIdent(data.relowner)}}; +{% endif %} +{### Security Labels on Table ###} +{% if data.seclabels and data.seclabels|length > 0 %} + +{% for r in data.seclabels %} +{{ SECLABEL.SET(conn, 'TABLE', data.name, r.provider, r.label, data.schema) }} +{% endfor %} +{% endif %} +{### ACL on Table ###} +{% if data.relacl %} + +{% for priv in data.relacl %} +{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }} +{% endfor %} +{% endif %} +{### SQL for COMMENT ###} +{% if data.description %} +COMMENT ON TABLE {{conn|qtIdent(data.schema, data.name)}} + IS {{data.description|qtLiteral}}; +{% endif %} +{#===========================================#} +{#====== MAIN TABLE TEMPLATE ENDS HERE ======#} +{#===========================================#} +{#===========================================#} +{# COLUMN SPECIFIC TEMPLATES STARTS HERE #} +{#===========================================#} +{% if data.columns and data.columns|length > 0 %} +{% for c in data.columns %} +{% if c.description %} + +COMMENT ON COLUMN {{conn|qtIdent(data.schema, data.name, c.name)}} + IS {{c.description|qtLiteral}}; +{% endif %} +{### Add variables to column ###} +{% if c.attoptions and c.attoptions|length > 0 %} + +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + {{ VARIABLE.SET(conn, 'COLUMN', c.name, c.attoptions) }} + +{% endif %} +{### Alter column statistics value ###} +{% if c.attstattarget is defined and c.attstattarget > -1 %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + ALTER COLUMN {{conn|qtTypeIdent(c.name)}} SET STATISTICS {{c.attstattarget}}; + +{% endif %} +{### Alter column storage value ###} +{% if c.attstorage is defined and c.attstorage != c.defaultstorage %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + ALTER COLUMN {{conn|qtTypeIdent(c.name)}} SET STORAGE {%if c.attstorage == 'p' %} +PLAIN{% elif c.attstorage == 'm'%}MAIN{% elif c.attstorage == 'e'%} +EXTERNAL{% elif c.attstorage == 'x'%}EXTENDED{% endif %}; + +{% endif %} +{### ACL ###} +{% if c.attacl and c.attacl|length > 0 %} + +{% for priv in c.attacl %} +{{ COLUMN_PRIVILEGE.APPLY(conn, data.schema, data.name, c.name, priv.grantee, priv.without_grant, priv.with_grant) }} +{% endfor %} +{% endif %} +{### Security Lables ###} +{% if c.seclabels and c.seclabels|length > 0 %} + +{% for r in c.seclabels %} +{{ COLUMN_SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.name, c.name, r.provider, r.label) }} +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} +{#===========================================#} +{# COLUMN SPECIFIC TEMPLATES ENDS HERE #} +{#===========================================#} +{#======================================#} +{# CONSTRAINTS SPECIFIC TEMPLATES #} +{#======================================#} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.primary_key)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.unique_constraint)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.foreign_key)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.check_constraint)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.exclude_constraint)}} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/properties.sql new file mode 100644 index 000000000..3ac7ceae8 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/properties.sql @@ -0,0 +1,77 @@ +SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS relacl_str, + (CASE WHEN length(spc.spcname) > 0 THEN spc.spcname ELSE + (SELECT sp.spcname FROM pg_database dtb + JOIN pg_tablespace sp ON dtb.dattablespace=sp.oid + WHERE dtb.oid = {{ did }}::oid) + END) as spcname, + (select nspname FROM pg_namespace WHERE oid = {{scid}}::oid ) as schema, + pg_get_userbyid(rel.relowner) AS relowner, rel.relhasoids, rel.relkind, + (CASE WHEN rel.relkind = 'p' THEN true ELSE false END) AS is_partitioned, + rel.relhassubclass, rel.reltuples::bigint, des.description, con.conname, con.conkey, + EXISTS(select 1 FROM pg_trigger + JOIN pg_proc pt ON pt.oid=tgfoid AND pt.proname='logtrigger' + JOIN pg_proc pc ON pc.pronamespace=pt.pronamespace AND pc.proname='slonyversion' + WHERE tgrelid=rel.oid) AS isrepl, + (SELECT count(*) FROM pg_trigger WHERE tgrelid=rel.oid AND tgisinternal = FALSE) AS triggercount, + (SELECT ARRAY(SELECT CASE WHEN (nspname NOT LIKE 'pg\_%') THEN + quote_ident(nspname)||'.'||quote_ident(c.relname) + ELSE quote_ident(c.relname) END AS inherited_tables + FROM pg_inherits i + JOIN pg_class c ON c.oid = i.inhparent + JOIN pg_namespace n ON n.oid=c.relnamespace + WHERE i.inhrelid = rel.oid ORDER BY inhseqno)) AS coll_inherits, + (SELECT count(*) + FROM pg_inherits i + JOIN pg_class c ON c.oid = i.inhparent + JOIN pg_namespace n ON n.oid=c.relnamespace + WHERE i.inhrelid = rel.oid) AS inherited_tables_cnt, + (CASE WHEN rel.relpersistence = 'u' THEN true ELSE false END) AS relpersistence, + substring(array_to_string(rel.reloptions, ',') FROM 'fillfactor=([0-9]*)') AS fillfactor, + substring(array_to_string(rel.reloptions, ',') FROM 'parallel_workers=([0-9]*)') AS parallel_workers, + substring(array_to_string(rel.reloptions, ',') FROM 'toast_tuple_target=([0-9]*)') AS toast_tuple_target, + (CASE WHEN (substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') = 'true') + THEN true ELSE false END) AS autovacuum_enabled, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.]?[0-9]*)') AS autovacuum_vacuum_scale_factor, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS autovacuum_analyze_threshold, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.]?[0-9]*)') AS autovacuum_analyze_scale_factor, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS autovacuum_vacuum_cost_delay, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS autovacuum_vacuum_cost_limit, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS autovacuum_freeze_min_age, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS autovacuum_freeze_max_age, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS autovacuum_freeze_table_age, + (CASE WHEN (substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') = 'true') + THEN true ELSE false END) AS toast_autovacuum_enabled, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS toast_autovacuum_vacuum_threshold, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.]?[0-9]*)') AS toast_autovacuum_vacuum_scale_factor, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS toast_autovacuum_analyze_threshold, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.]?[0-9]*)') AS toast_autovacuum_analyze_scale_factor, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS toast_autovacuum_vacuum_cost_delay, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS toast_autovacuum_vacuum_cost_limit, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS toast_autovacuum_freeze_min_age, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS toast_autovacuum_freeze_max_age, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS toast_autovacuum_freeze_table_age, + array_to_string(rel.reloptions, ',') AS table_vacuum_settings_str, + array_to_string(tst.reloptions, ',') AS toast_table_vacuum_settings_str, + rel.reloptions AS reloptions, tst.reloptions AS toast_reloptions, rel.reloftype, + CASE WHEN typ.typname IS NOT NULL THEN (select quote_ident(nspname) FROM pg_namespace WHERE oid = {{scid}}::oid )||'.'||quote_ident(typ.typname) ELSE typ.typname END AS typname, + typ.typrelid AS typoid, + (CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable, + -- Added for pgAdmin4 + (array_to_string(rel.reloptions, ',') like '%autovacuum%') AS autovacuum_custom, + (CASE WHEN array_length(tst.reloptions, 1) > 0 AND rel.reltoastrelid != 0 THEN true ELSE false END) AS toast_autovacuum, + + (SELECT array_agg(provider || '=' || label) FROM pg_seclabels sl1 WHERE sl1.objoid=rel.oid AND sl1.objsubid=0) AS seclabels, + (CASE WHEN rel.oid <= {{ datlastsysoid}}::oid THEN true ElSE false END) AS is_sys_table + -- Added for partition table + {% if tid %}, (CASE WHEN rel.relkind = 'p' THEN pg_get_partkeydef({{ tid }}::oid) ELSE '' END) AS partition_scheme {% endif %} +FROM pg_class rel + LEFT OUTER JOIN pg_tablespace spc on spc.oid=rel.reltablespace + LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0 AND des.classoid='pg_class'::regclass) + LEFT OUTER JOIN pg_constraint con ON con.conrelid=rel.oid AND con.contype='p' + LEFT OUTER JOIN pg_class tst ON tst.oid = rel.reltoastrelid + LEFT JOIN pg_type typ ON rel.reloftype=typ.oid +WHERE rel.relkind IN ('r','s','t','p') AND rel.relnamespace = {{ scid }}::oid +AND NOT rel.relispartition +{% if tid %} AND rel.oid = {{ tid }}::oid {% endif %} +ORDER BY rel.relname; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/update.sql new file mode 100644 index 000000000..0f27dbed2 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/11_plus/update.sql @@ -0,0 +1,245 @@ +{% import 'macros/schemas/security.macros' as SECLABEL %} +{% import 'macros/schemas/privilege.macros' as PRIVILEGE %} +{% import 'macros/variable.macros' as VARIABLE %} +{#####################################################} +{## Rename table ##} +{#####################################################} +{% if data.name and data.name != o_data.name %} +ALTER TABLE {{conn|qtIdent(o_data.schema, o_data.name)}} + RENAME TO {{conn|qtIdent(data.name)}}; + +{% endif %} +{#####################################################} +{## Change table schema ##} +{#####################################################} +{% if data.schema and data.schema != o_data.schema %} +ALTER TABLE {{conn|qtIdent(o_data.schema, data.name)}} + SET SCHEMA {{conn|qtIdent(data.schema)}}; + +{% endif %} +{#####################################################} +{## Change table owner ##} +{#####################################################} +{% if data.relowner and data.relowner != o_data.relowner %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + OWNER TO {{conn|qtIdent(data.relowner)}}; + +{% endif %} +{#####################################################} +{## Update Inherits table definition ##} +{#####################################################} +{% if data.coll_inherits_added|length > 0 %} +{% for val in data.coll_inherits_added %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + INHERIT {{val}}; + +{% endfor %} +{% endif %} +{% if data.coll_inherits_removed|length > 0 %} +{% for val in data.coll_inherits_removed %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + NO INHERIT {{val}}; + +{% endfor %} +{% endif %} +{#####################################################} +{## Change hasOID attribute of table ##} +{#####################################################} +{% if data.relhasoids is defined and data.relhasoids != o_data.relhasoids %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET {% if data.relhasoids %}WITH{% else %}WITHOUT{% endif %} OIDS; + +{% endif %} +{#####################################################} +{## Change tablespace ##} +{#####################################################} +{% if data.spcname and data.spcname != o_data.spcname %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET TABLESPACE {{conn|qtIdent(data.spcname)}}; + +{% endif %} +{#####################################################} +{## change fillfactor settings ##} +{#####################################################} +{% if data.fillfactor and data.fillfactor != o_data.fillfactor %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET (FILLFACTOR={{data.fillfactor}}); +{% elif (data.fillfactor == '' or data.fillfactor == None) and data.fillfactor != o_data.fillfactor %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + RESET (FILLFACTOR); + +{% endif %} + +{## change parallel_workers settings ##} +{#####################################################} +{% if (data.parallel_workers == '' or data.parallel_workers == None) and data.parallel_workers != o_data.parallel_workers %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + RESET (parallel_workers); +{% elif data.parallel_workers is defined and data.parallel_workers != o_data.parallel_workers %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET (parallel_workers={{data.parallel_workers}}); + +{% endif %} + +{## change toast_tuple_target settings ##} +{#####################################################} +{% if (data.toast_tuple_target == '' or data.toast_tuple_target == None) and data.toast_tuple_target != o_data.toast_tuple_target %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + RESET (toast_tuple_target); +{% elif data.toast_tuple_target is defined and data.toast_tuple_target != o_data.toast_tuple_target %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET (toast_tuple_target={{data.toast_tuple_target}}); + +{% endif %} + +{###############################} +{## Table AutoVacuum settings ##} +{###############################} +{% if data.vacuum_table is defined and data.vacuum_table.set_values|length > 0 %} +{% set has_vacuum_set = true %} +{% endif %} +{% if data.vacuum_table is defined and data.vacuum_table.reset_values|length > 0 %} +{% set has_vacuum_reset = true %} +{% endif %} +{% if o_data.autovacuum_custom and data.autovacuum_custom == false %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( + autovacuum_enabled, + autovacuum_analyze_scale_factor, + autovacuum_analyze_threshold, + autovacuum_freeze_max_age, + autovacuum_vacuum_cost_delay, + autovacuum_vacuum_cost_limit, + autovacuum_vacuum_scale_factor, + autovacuum_vacuum_threshold, + autovacuum_freeze_min_age, + autovacuum_freeze_table_age +); +{% else %} +{% if data.autovacuum_enabled is defined or has_vacuum_set %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} SET ( +{% if data.autovacuum_enabled is defined and data.autovacuum_enabled != o_data.autovacuum_enabled %} + autovacuum_enabled = {% if data.autovacuum_enabled %}true{% else %}false{% endif %}{% if has_vacuum_set %}, +{% endif %} +{% endif %} +{% if has_vacuum_set %} +{% for opt in data.vacuum_table.set_values %}{% if opt.name and opt.value %} + {{opt.name}} = {{opt.value}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} +{% endif %} + +); +{% endif %} +{% if has_vacuum_reset %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( +{% for opt in data.vacuum_table.reset_values %}{% if opt.name %} + {{opt.name}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} + +); +{% endif %} +{% endif %} +{#####################################} +{## Toast table AutoVacuum settings ##} +{#####################################} +{% if data.vacuum_toast is defined and data.vacuum_toast.set_values|length > 0 %} +{% set has_vacuum_toast_set = true %} +{% endif %} +{% if data.vacuum_toast is defined and data.vacuum_toast.reset_values|length > 0 %} +{% set has_vacuum_toast_reset = true %} +{% endif %} +{% if o_data.toast_autovacuum and data.toast_autovacuum == false %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( + toast.autovacuum_enabled, + toast.autovacuum_freeze_max_age, + toast.autovacuum_vacuum_cost_delay, + toast.autovacuum_vacuum_cost_limit, + toast.autovacuum_vacuum_scale_factor, + toast.autovacuum_vacuum_threshold, + toast.autovacuum_freeze_min_age, + toast.autovacuum_freeze_table_age, + toast.autovacuum_analyze_threshold, + toast.autovacuum_analyze_scale_factor +); +{% else %} +{% if data.toast_autovacuum_enabled is defined or has_vacuum_toast_set %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} SET ( +{% if data.toast_autovacuum_enabled is defined and data.toast_autovacuum_enabled != o_data.toast_autovacuum_enabled %} + toast.autovacuum_enabled = {% if data.toast_autovacuum_enabled %}true{% else %}false{% endif %}{% if has_vacuum_toast_set %}, +{% endif %} +{% endif %} +{% if has_vacuum_toast_set %} +{% for opt in data.vacuum_toast.set_values %}{% if opt.name and opt.value %} + toast.{{opt.name}} = {{opt.value}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} +{% endif %} + +); +{% endif %} +{% if has_vacuum_toast_reset %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( +{% for opt in data.vacuum_toast.reset_values %}{% if opt.name %} + toast.{{opt.name}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} + +); +{% endif %} +{% endif %} +{#####################################################} +{## Change table comments ##} +{#####################################################} +{% if data.description is defined and data.description != o_data.description %} +COMMENT ON TABLE {{conn|qtIdent(data.schema, data.name)}} + IS {{data.description|qtLiteral}}; + +{% endif %} +{#####################################################} +{## Update table Privileges ##} +{#####################################################} +{% if data.relacl %} +{% if 'deleted' in data.relacl %} +{% for priv in data.relacl.deleted %} +{{ PRIVILEGE.UNSETALL(conn, 'TABLE', priv.grantee, data.name, data.schema) }} +{% endfor %} +{% endif %} +{% if 'changed' in data.relacl %} +{% for priv in data.relacl.changed %} +{{ PRIVILEGE.UNSETALL(conn, 'TABLE', priv.grantee, data.name, data.schema) }} +{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }} +{% endfor %} +{% endif %} +{% if 'added' in data.relacl %} +{% for priv in data.relacl.added %} +{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }} +{% endfor %} +{% endif %} +{% endif %} +{#####################################################} +{## Update table SecurityLabel ##} +{#####################################################} +{% if data.seclabels and data.seclabels|length > 0 %} +{% set seclabels = data.seclabels %} +{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %} +{% for r in seclabels.deleted %} +{{ SECLABEL.UNSET(conn, 'TABLE', data.name, r.provider, data.schema) }} +{% endfor %} +{% endif %} +{% if 'added' in seclabels and seclabels.added|length > 0 %} +{% for r in seclabels.added %} +{{ SECLABEL.SET(conn, 'TABLE', data.name, r.provider, r.label, data.schema) }} +{% endfor %} +{% endif %} +{% if 'changed' in seclabels and seclabels.changed|length > 0 %} +{% for r in seclabels.changed %} +{{ SECLABEL.SET(conn, 'TABLE', data.name, r.provider, r.label, data.schema) }} +{% endfor %} +{% endif %} + +{% endif %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/create.sql index c52861b0c..486bc3091 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/create.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/create.sql @@ -17,7 +17,7 @@ {% set empty_bracket = "\n(\n)"%} {% endif %} {% set with_clause = false%} -{% if data.fillfactor or data.autovacuum_custom or data.autovacuum_enabled or data.toast_autovacuum or data.toast_autovacuum_enabled or (data.autovacuum_enabled and data.vacuum_table|length > 0) or (data.toast_autovacuum_enabled and data.vacuum_toast|length > 0) %} +{% if data.fillfactor or data.parallel_workers or data.toast_tuple_target or data.autovacuum_custom or data.autovacuum_enabled or data.toast_autovacuum or data.toast_autovacuum_enabled or (data.autovacuum_enabled and data.vacuum_table|length > 0) or (data.toast_autovacuum_enabled and data.vacuum_toast|length > 0) %} {% set with_clause = true%} {% endif %} CREATE {% if data.relpersistence %}UNLOGGED {% endif %}TABLE {{conn|qtIdent(data.schema, data.name)}}{{empty_bracket}} @@ -86,7 +86,13 @@ CACHE {{c.seqcache|int}} {% endif %} {% set add_comma = false%} WITH ( {% if data.fillfactor %}{% set add_comma = true%} - FILLFACTOR = {{ data.fillfactor }}{% endif %}{% if data.autovacuum_custom %} + FILLFACTOR = {{ data.fillfactor }}{% endif %}{% if data.parallel_workers %} +{% if add_comma %}, +{% endif %} + parallel_workers = {{ data.parallel_workers }}{% set add_comma = true%}{% endif %}{% if data.toast_tuple_target %} +{% if add_comma %}, +{% endif %} + toast_tuple_target = {{ data.toast_tuple_target }}{% set add_comma = true%}{% endif %}{% if data.autovacuum_custom %} {% if add_comma %}, {% endif %} autovacuum_enabled = {% if data.autovacuum_enabled %}TRUE{% else %}FALSE{% endif %}{% set add_comma = true%}{% endif %}{% if data.toast_autovacuum %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/properties.sql index e7d19055d..3d9b1f622 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/properties.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/properties.sql @@ -27,6 +27,8 @@ SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS r WHERE i.inhrelid = rel.oid) AS inherited_tables_cnt, (CASE WHEN rel.relpersistence = 'u' THEN true ELSE false END) AS relpersistence, substring(array_to_string(rel.reloptions, ',') FROM 'fillfactor=([0-9]*)') AS fillfactor, + substring(array_to_string(rel.reloptions, ',') FROM 'parallel_workers=([0-9]*)') AS parallel_workers, + substring(array_to_string(rel.reloptions, ',') FROM 'toast_tuple_target=([0-9]*)') AS toast_tuple_target, (CASE WHEN (substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') = 'true') THEN true ELSE false END) AS autovacuum_enabled, substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold, @@ -56,7 +58,7 @@ SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS r typ.typrelid AS typoid, (CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable, -- Added for pgAdmin4 - (CASE WHEN array_length(rel.reloptions, 1) > 0 THEN true ELSE false END) AS autovacuum_custom, + (array_to_string(rel.reloptions, ',') like '%autovacuum%') AS autovacuum_custom, (CASE WHEN array_length(tst.reloptions, 1) > 0 AND rel.reltoastrelid != 0 THEN true ELSE false END) AS toast_autovacuum, (SELECT array_agg(provider || '=' || label) FROM pg_seclabels sl1 WHERE sl1.objoid=rel.oid AND sl1.objsubid=0) AS seclabels, diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/update.sql index 3ed12302d..e2415ad2a 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/update.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/12_plus/update.sql @@ -61,6 +61,29 @@ ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET (FILLFACTOR); {% endif %} + +{## change parallel_workers settings ##} +{#####################################################} +{% if (data.parallel_workers == '' or data.parallel_workers == None) and data.parallel_workers != o_data.parallel_workers %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + RESET (parallel_workers); +{% elif data.parallel_workers is defined and data.parallel_workers != o_data.parallel_workers %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET (parallel_workers={{data.parallel_workers}}); + +{% endif %} + +{## change toast_tuple_target settings ##} +{#####################################################} +{% if (data.toast_tuple_target == '' or data.toast_tuple_target == None) and data.toast_tuple_target != o_data.toast_tuple_target %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + RESET (toast_tuple_target); +{% elif data.toast_tuple_target is defined and data.toast_tuple_target != o_data.toast_tuple_target %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET (toast_tuple_target={{data.toast_tuple_target}}); + +{% endif %} + {###############################} {## Table AutoVacuum settings ##} {###############################} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/create.sql new file mode 100644 index 000000000..87df7a386 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/create.sql @@ -0,0 +1,174 @@ +{% import 'macros/schemas/security.macros' as SECLABEL %} +{% import 'macros/schemas/privilege.macros' as PRIVILEGE %} +{% import 'macros/variable.macros' as VARIABLE %} +{% import 'columns/macros/security.macros' as COLUMN_SECLABEL %} +{% import 'columns/macros/privilege.macros' as COLUMN_PRIVILEGE %} +{% import 'tables/sql/macros/constraints.macro' as CONSTRAINTS %} +{% import 'types/macros/get_full_type_sql_format.macros' as GET_TYPE %} +{#===========================================#} +{#====== MAIN TABLE TEMPLATE STARTS HERE ======#} +{#===========================================#} +{# + If user has not provided any details but only name then + add empty bracket with table name +#} +{% set empty_bracket = ""%} +{% if data.coll_inherits|length == 0 and data.columns|length == 0 and not data.typname and not data.like_relation and data.primary_key|length == 0 and data.unique_constraint|length == 0 and data.foreign_key|length == 0 and data.check_constraint|length == 0 and data.exclude_constraint|length == 0 %} +{% set empty_bracket = "\n(\n)"%} +{% endif %} +CREATE {% if data.relpersistence %}UNLOGGED {% endif %}TABLE {{conn|qtIdent(data.schema, data.name)}}{{empty_bracket}} +{% if data.typname %} + OF {{ data.typname }} +{% endif %} +{% if data.like_relation or data.coll_inherits or data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 or data.exclude_constraint|length > 0 %} +( +{% endif %} +{% if data.like_relation %} + LIKE {{ data.like_relation }}{% if data.like_default_value %} + + INCLUDING DEFAULTS{% endif %}{% if data.like_constraints %} + + INCLUDING CONSTRAINTS{% endif %}{% if data.like_indexes %} + + INCLUDING INDEXES{% endif %}{% if data.like_storage %} + + INCLUDING STORAGE{% endif %}{% if data.like_comments %} + + INCLUDING COMMENTS{% endif %}{% if data.columns|length > 0 %}, +{% endif %} + +{% endif %} +{### Add columns ###} +{% if data.columns and data.columns|length > 0 %} +{% for c in data.columns %} +{% if c.name and c.cltype %} + {% if c.inheritedfromtable %}-- Inherited from table {{c.inheritedfromtable}}: {% elif c.inheritedfromtype %}-- Inherited from type {{c.inheritedfromtype}}: {% endif %}{{conn|qtIdent(c.name)}} {% if is_sql %}{{c.displaytypname}}{% else %}{{ GET_TYPE.CREATE_TYPE_SQL(conn, c.cltype, c.attlen, c.attprecision, c.hasSqrBracket) }}{% endif %}{% if c.collspcname %} COLLATE {{c.collspcname}}{% endif %}{% if c.attnotnull %} NOT NULL{% endif %}{% if c.defval is defined and c.defval is not none and c.defval != '' %} DEFAULT {{c.defval}}{% endif %} +{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} +{% endif %} +{# Macro to render for constraints #} +{% if data.primary_key|length > 0 %}{% if data.columns|length > 0 %},{% endif %} +{{CONSTRAINTS.PRIMARY_KEY(conn, data.primary_key[0])}}{% endif %}{% if data.unique_constraint|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 %},{% endif %} +{{CONSTRAINTS.UNIQUE(conn, data.unique_constraint)}}{% endif %}{% if data.foreign_key|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 %},{% endif %} +{{CONSTRAINTS.FOREIGN_KEY(conn, data.foreign_key)}}{% endif %}{% if data.check_constraint|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 %},{% endif %} +{{CONSTRAINTS.CHECK(conn, data.check_constraint)}}{% endif %}{% if data.exclude_constraint|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 %},{% endif %} +{{CONSTRAINTS.EXCLUDE(conn, data.exclude_constraint)}}{% endif %} +{% if data.like_relation or data.coll_inherits or data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 or data.exclude_constraint|length > 0 %} + +){% endif %}{% if data.relkind is defined and data.relkind == 'p' %} PARTITION BY {{ data.partition_scheme }} {% endif %} + +{### If we are inheriting it from another table(s) ###} +{% if data.coll_inherits %} + INHERITS ({% for val in data.coll_inherits %}{% if loop.index != 1 %}, {% endif %}{{val}}{% endfor %}) +{% endif %} +WITH ( + OIDS = {% if data.relhasoids %}TRUE{% else %}FALSE{% endif %}{% if data.fillfactor %}, + FILLFACTOR = {{ data.fillfactor }}{% endif %}{% if data.parallel_workers is defined and data.parallel_workers != '' and data.parallel_workers != None %}, + parallel_workers = {{ data.parallel_workers }}{% endif %}{% if data.autovacuum_custom %}, + autovacuum_enabled = {% if data.autovacuum_enabled %}TRUE{% else %}FALSE{% endif %}{% endif %}{% if data.toast_autovacuum %}, + toast.autovacuum_enabled = {% if data.toast_autovacuum_enabled %}TRUE{% else %}FALSE{% endif %} +{% endif %}{% if data.autovacuum_enabled and data.vacuum_table|length > 0 %} +{% for opt in data.vacuum_table %}{% if opt.name and opt.value %} +, + {{opt.name}} = {{opt.value}}{% endif %} +{% endfor %}{% endif %}{% if data.toast_autovacuum_enabled and data.vacuum_toast|length > 0 %} +{% for opt in data.vacuum_toast %}{% if opt.name and opt.value %} +, + toast.{{opt.name}} = {{opt.value}}{% endif %} +{% endfor %}{% endif %} + +{### SQL for Tablespace ###} +{% if data.spcname %} +) +TABLESPACE {{ conn|qtIdent(data.spcname) }}; +{% else %} +); +{% endif %} +{### Alter SQL for Owner ###} +{% if data.relowner %} + +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + OWNER to {{conn|qtIdent(data.relowner)}}; +{% endif %} +{### Security Labels on Table ###} +{% if data.seclabels and data.seclabels|length > 0 %} + +{% for r in data.seclabels %} +{{ SECLABEL.SET(conn, 'TABLE', data.name, r.provider, r.label, data.schema) }} +{% endfor %} +{% endif %} +{### ACL on Table ###} +{% if data.relacl %} + +{% for priv in data.relacl %} +{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }} +{% endfor %} +{% endif %} +{### SQL for COMMENT ###} +{% if data.description %} +COMMENT ON TABLE {{conn|qtIdent(data.schema, data.name)}} + IS {{data.description|qtLiteral}}; +{% endif %} +{#===========================================#} +{#====== MAIN TABLE TEMPLATE ENDS HERE ======#} +{#===========================================#} +{#===========================================#} +{# COLUMN SPECIFIC TEMPLATES STARTS HERE #} +{#===========================================#} +{% if data.columns and data.columns|length > 0 %} +{% for c in data.columns %} +{% if c.description %} + +COMMENT ON COLUMN {{conn|qtIdent(data.schema, data.name, c.name)}} + IS {{c.description|qtLiteral}}; +{% endif %} +{### Add variables to column ###} +{% if c.attoptions and c.attoptions|length > 0 %} + +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + {{ VARIABLE.SET(conn, 'COLUMN', c.name, c.attoptions) }} + +{% endif %} +{### Alter column statistics value ###} +{% if c.attstattarget is defined and c.attstattarget > -1 %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + ALTER COLUMN {{conn|qtTypeIdent(c.name)}} SET STATISTICS {{c.attstattarget}}; + +{% endif %} +{### Alter column storage value ###} +{% if c.attstorage is defined and c.attstorage != c.defaultstorage %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + ALTER COLUMN {{conn|qtTypeIdent(c.name)}} SET STORAGE {%if c.attstorage == 'p' %} +PLAIN{% elif c.attstorage == 'm'%}MAIN{% elif c.attstorage == 'e'%} +EXTERNAL{% elif c.attstorage == 'x'%}EXTENDED{% endif %}; + +{% endif %} +{### ACL ###} +{% if c.attacl and c.attacl|length > 0 %} + +{% for priv in c.attacl %} + {{ COLUMN_PRIVILEGE.APPLY(conn, data.schema, data.name, c.name, priv.grantee, priv.without_grant, priv.with_grant) }} +{% endfor %} +{% endif %} +{### Security Lables ###} +{% if c.seclabels and c.seclabels|length > 0 %} + +{% for r in c.seclabels %} +{{ COLUMN_SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.name, c.name, r.provider, r.label) }} +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} +{#===========================================#} +{# COLUMN SPECIFIC TEMPLATES ENDS HERE #} +{#===========================================#} +{#======================================#} +{# CONSTRAINTS SPECIFIC TEMPLATES #} +{#======================================#} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.primary_key)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.unique_constraint)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.foreign_key)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.check_constraint)}} +{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.exclude_constraint)}} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/properties.sql new file mode 100644 index 000000000..80451f12d --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/properties.sql @@ -0,0 +1,72 @@ +SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS relacl_str, + (CASE WHEN length(spc.spcname) > 0 THEN spc.spcname ELSE + (SELECT sp.spcname FROM pg_database dtb + JOIN pg_tablespace sp ON dtb.dattablespace=sp.oid + WHERE dtb.oid = {{ did }}::oid) + END) as spcname, + (select nspname FROM pg_namespace WHERE oid = {{scid}}::oid ) as schema, + pg_get_userbyid(rel.relowner) AS relowner, rel.relhasoids, + rel.relhassubclass, rel.reltuples::bigint, des.description, con.conname, con.conkey, + EXISTS(select 1 FROM pg_trigger + JOIN pg_proc pt ON pt.oid=tgfoid AND pt.proname='logtrigger' + JOIN pg_proc pc ON pc.pronamespace=pt.pronamespace AND pc.proname='slonyversion' + WHERE tgrelid=rel.oid) AS isrepl, + (SELECT count(*) FROM pg_trigger WHERE tgrelid=rel.oid AND tgisinternal = FALSE) AS triggercount, + (SELECT ARRAY(SELECT CASE WHEN (nspname NOT LIKE 'pg\_%') THEN + quote_ident(nspname)||'.'||quote_ident(c.relname) + ELSE quote_ident(c.relname) END AS inherited_tables + FROM pg_inherits i + JOIN pg_class c ON c.oid = i.inhparent + JOIN pg_namespace n ON n.oid=c.relnamespace + WHERE i.inhrelid = rel.oid ORDER BY inhseqno)) AS coll_inherits, + (SELECT count(*) + FROM pg_inherits i + JOIN pg_class c ON c.oid = i.inhparent + JOIN pg_namespace n ON n.oid=c.relnamespace + WHERE i.inhrelid = rel.oid) AS inherited_tables_cnt, + (CASE WHEN rel.relpersistence = 'u' THEN true ELSE false END) AS relpersistence, + substring(array_to_string(rel.reloptions, ',') FROM 'fillfactor=([0-9]*)') AS fillfactor, + substring(array_to_string(rel.reloptions, ',') FROM 'parallel_workers=([0-9]*)') AS parallel_workers, + (CASE WHEN (substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') = 'true') + THEN true ELSE false END) AS autovacuum_enabled, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.]?[0-9]*)') AS autovacuum_vacuum_scale_factor, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS autovacuum_analyze_threshold, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.]?[0-9]*)') AS autovacuum_analyze_scale_factor, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS autovacuum_vacuum_cost_delay, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS autovacuum_vacuum_cost_limit, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS autovacuum_freeze_min_age, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS autovacuum_freeze_max_age, + substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS autovacuum_freeze_table_age, + (CASE WHEN (substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') = 'true') + THEN true ELSE false END) AS toast_autovacuum_enabled, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS toast_autovacuum_vacuum_threshold, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.]?[0-9]*)') AS toast_autovacuum_vacuum_scale_factor, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS toast_autovacuum_analyze_threshold, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.]?[0-9]*)') AS toast_autovacuum_analyze_scale_factor, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS toast_autovacuum_vacuum_cost_delay, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS toast_autovacuum_vacuum_cost_limit, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS toast_autovacuum_freeze_min_age, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS toast_autovacuum_freeze_max_age, + substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS toast_autovacuum_freeze_table_age, + array_to_string(rel.reloptions, ',') AS table_vacuum_settings_str, + array_to_string(tst.reloptions, ',') AS toast_table_vacuum_settings_str, + rel.reloptions AS reloptions, tst.reloptions AS toast_reloptions, rel.reloftype, + CASE WHEN typ.typname IS NOT NULL THEN (select quote_ident(nspname) FROM pg_namespace WHERE oid = {{scid}}::oid )||'.'||quote_ident(typ.typname) ELSE typ.typname END AS typname, + typ.typrelid AS typoid, + (CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable, + -- Added for pgAdmin4 + (array_to_string(rel.reloptions, ',') like '%autovacuum%') AS autovacuum_custom, + (CASE WHEN array_length(tst.reloptions, 1) > 0 AND rel.reltoastrelid != 0 THEN true ELSE false END) AS toast_autovacuum, + + (SELECT array_agg(provider || '=' || label) FROM pg_seclabels sl1 WHERE sl1.objoid=rel.oid AND sl1.objsubid=0) AS seclabels, + (CASE WHEN rel.oid <= {{ datlastsysoid}}::oid THEN true ElSE false END) AS is_sys_table +FROM pg_class rel + LEFT OUTER JOIN pg_tablespace spc on spc.oid=rel.reltablespace + LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0 AND des.classoid='pg_class'::regclass) + LEFT OUTER JOIN pg_constraint con ON con.conrelid=rel.oid AND con.contype='p' + LEFT OUTER JOIN pg_class tst ON tst.oid = rel.reltoastrelid + LEFT JOIN pg_type typ ON rel.reloftype=typ.oid +WHERE rel.relkind IN ('r','s','t') AND rel.relnamespace = {{ scid }}::oid +{% if tid %} AND rel.oid = {{ tid }}::oid {% endif %} +ORDER BY rel.relname; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/update.sql new file mode 100644 index 000000000..98e9ebf4b --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/9.6_plus/update.sql @@ -0,0 +1,233 @@ +{% import 'macros/schemas/security.macros' as SECLABEL %} +{% import 'macros/schemas/privilege.macros' as PRIVILEGE %} +{% import 'macros/variable.macros' as VARIABLE %} +{#####################################################} +{## Rename table ##} +{#####################################################} +{% if data.name and data.name != o_data.name %} +ALTER TABLE {{conn|qtIdent(o_data.schema, o_data.name)}} + RENAME TO {{conn|qtIdent(data.name)}}; + +{% endif %} +{#####################################################} +{## Change table schema ##} +{#####################################################} +{% if data.schema and data.schema != o_data.schema %} +ALTER TABLE {{conn|qtIdent(o_data.schema, data.name)}} + SET SCHEMA {{conn|qtIdent(data.schema)}}; + +{% endif %} +{#####################################################} +{## Change table owner ##} +{#####################################################} +{% if data.relowner and data.relowner != o_data.relowner %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + OWNER TO {{conn|qtIdent(data.relowner)}}; + +{% endif %} +{#####################################################} +{## Update Inherits table definition ##} +{#####################################################} +{% if data.coll_inherits_added|length > 0 %} +{% for val in data.coll_inherits_added %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + INHERIT {{val}}; + +{% endfor %} +{% endif %} +{% if data.coll_inherits_removed|length > 0 %} +{% for val in data.coll_inherits_removed %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + NO INHERIT {{val}}; + +{% endfor %} +{% endif %} +{#####################################################} +{## Change hasOID attribute of table ##} +{#####################################################} +{% if data.relhasoids is defined and data.relhasoids != o_data.relhasoids %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET {% if data.relhasoids %}WITH{% else %}WITHOUT{% endif %} OIDS; + +{% endif %} +{#####################################################} +{## Change tablespace ##} +{#####################################################} +{% if data.spcname and data.spcname != o_data.spcname %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET TABLESPACE {{conn|qtIdent(data.spcname)}}; + +{% endif %} +{#####################################################} +{## change fillfactor settings ##} +{#####################################################} +{% if data.fillfactor and data.fillfactor != o_data.fillfactor %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET (FILLFACTOR={{data.fillfactor}}); +{% elif (data.fillfactor == '' or data.fillfactor == None) and data.fillfactor != o_data.fillfactor %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + RESET (FILLFACTOR); + +{% endif %} + +{## change parallel_workers settings ##} +{#####################################################} +{% if (data.parallel_workers == '' or data.parallel_workers == None) and data.parallel_workers != o_data.parallel_workers %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + RESET (parallel_workers); +{% elif data.parallel_workers is defined and data.parallel_workers != o_data.parallel_workers %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} + SET (parallel_workers={{data.parallel_workers}}); + +{% endif %} +{###############################} +{## Table AutoVacuum settings ##} +{###############################} +{% if data.vacuum_table is defined and data.vacuum_table.set_values|length > 0 %} +{% set has_vacuum_set = true %} +{% endif %} +{% if data.vacuum_table is defined and data.vacuum_table.reset_values|length > 0 %} +{% set has_vacuum_reset = true %} +{% endif %} +{% if o_data.autovacuum_custom and data.autovacuum_custom == false %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( + autovacuum_enabled, + autovacuum_analyze_scale_factor, + autovacuum_analyze_threshold, + autovacuum_freeze_max_age, + autovacuum_vacuum_cost_delay, + autovacuum_vacuum_cost_limit, + autovacuum_vacuum_scale_factor, + autovacuum_vacuum_threshold, + autovacuum_freeze_min_age, + autovacuum_freeze_table_age +); +{% else %} +{% if data.autovacuum_enabled is defined or has_vacuum_set %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} SET ( +{% if data.autovacuum_enabled is defined and data.autovacuum_enabled != o_data.autovacuum_enabled %} + autovacuum_enabled = {% if data.autovacuum_enabled %}true{% else %}false{% endif %}{% if has_vacuum_set %}, +{% endif %} +{% endif %} +{% if has_vacuum_set %} +{% for opt in data.vacuum_table.set_values %}{% if opt.name and opt.value %} + {{opt.name}} = {{opt.value}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} +{% endif %} + +); +{% endif %} +{% if has_vacuum_reset %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( +{% for opt in data.vacuum_table.reset_values %}{% if opt.name %} + {{opt.name}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} + +); +{% endif %} +{% endif %} +{#####################################} +{## Toast table AutoVacuum settings ##} +{#####################################} +{% if data.vacuum_toast is defined and data.vacuum_toast.set_values|length > 0 %} +{% set has_vacuum_toast_set = true %} +{% endif %} +{% if data.vacuum_toast is defined and data.vacuum_toast.reset_values|length > 0 %} +{% set has_vacuum_toast_reset = true %} +{% endif %} +{% if o_data.toast_autovacuum and data.toast_autovacuum == false %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( + toast.autovacuum_enabled, + toast.autovacuum_freeze_max_age, + toast.autovacuum_vacuum_cost_delay, + toast.autovacuum_vacuum_cost_limit, + toast.autovacuum_vacuum_scale_factor, + toast.autovacuum_vacuum_threshold, + toast.autovacuum_freeze_min_age, + toast.autovacuum_freeze_table_age, + toast.autovacuum_analyze_threshold, + toast.autovacuum_analyze_scale_factor +); +{% else %} +{% if data.toast_autovacuum_enabled is defined or has_vacuum_toast_set %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} SET ( +{% if data.toast_autovacuum_enabled is defined and data.toast_autovacuum_enabled != o_data.toast_autovacuum_enabled %} + toast.autovacuum_enabled = {% if data.toast_autovacuum_enabled %}true{% else %}false{% endif %}{% if has_vacuum_toast_set %}, +{% endif %} +{% endif %} +{% if has_vacuum_toast_set %} +{% for opt in data.vacuum_toast.set_values %}{% if opt.name and opt.value %} + toast.{{opt.name}} = {{opt.value}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} +{% endif %} + +); +{% endif %} +{% if has_vacuum_toast_reset %} +ALTER TABLE {{conn|qtIdent(data.schema, data.name)}} RESET ( +{% for opt in data.vacuum_toast.reset_values %}{% if opt.name %} + toast.{{opt.name}}{% if not loop.last %}, +{% endif %} +{% endif %} +{% endfor %} + +); +{% endif %} +{% endif %} +{#####################################################} +{## Change table comments ##} +{#####################################################} +{% if data.description is defined and data.description != o_data.description %} +COMMENT ON TABLE {{conn|qtIdent(data.schema, data.name)}} + IS {{data.description|qtLiteral}}; + +{% endif %} +{#####################################################} +{## Update table Privileges ##} +{#####################################################} +{% if data.relacl %} +{% if 'deleted' in data.relacl %} +{% for priv in data.relacl.deleted %} +{{ PRIVILEGE.UNSETALL(conn, 'TABLE', priv.grantee, data.name, data.schema) }} +{% endfor %} +{% endif %} +{% if 'changed' in data.relacl %} +{% for priv in data.relacl.changed %} +{{ PRIVILEGE.UNSETALL(conn, 'TABLE', priv.grantee, data.name, data.schema) }} +{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }} +{% endfor %} +{% endif %} +{% if 'added' in data.relacl %} +{% for priv in data.relacl.added %} +{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }} +{% endfor %} +{% endif %} +{% endif %} +{#####################################################} +{## Update table SecurityLabel ##} +{#####################################################} +{% if data.seclabels and data.seclabels|length > 0 %} +{% set seclabels = data.seclabels %} +{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %} +{% for r in seclabels.deleted %} +{{ SECLABEL.UNSET(conn, 'TABLE', data.name, r.provider, data.schema) }} +{% endfor %} +{% endif %} +{% if 'added' in seclabels and seclabels.added|length > 0 %} +{% for r in seclabels.added %} +{{ SECLABEL.SET(conn, 'TABLE', data.name, r.provider, r.label, data.schema) }} +{% endfor %} +{% endif %} +{% if 'changed' in seclabels and seclabels.changed|length > 0 %} +{% for r in seclabels.changed %} +{{ SECLABEL.SET(conn, 'TABLE', data.name, r.provider, r.label, data.schema) }} +{% endfor %} +{% endif %} + +{% endif %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/default/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/default/properties.sql index 932e7ffa5..47686a280 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/default/properties.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/tables/sql/default/properties.sql @@ -57,7 +57,7 @@ FROM ( typ.typrelid AS typoid, (CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable, -- Added for pgAdmin4 - (CASE WHEN array_length(rel.reloptions, 1) > 0 THEN true ELSE false END) AS autovacuum_custom, + (array_to_string(rel.reloptions, ',') like '%autovacuum%') AS autovacuum_custom, (CASE WHEN array_length(tst.reloptions, 1) > 0 AND rel.reltoastrelid != 0 THEN true ELSE false END) AS toast_autovacuum, ARRAY[]::varchar[] AS seclabels, ^ permalink raw reply [nested|flat] 7+ messages in thread
* Re: [pgAdmin][RM5181] Add support for parameters toast_tuple_target and parallel_workers of table @ 2020-04-01 12:51 Akshay Joshi <[email protected]> parent: Aditya Toshniwal <[email protected]> 0 siblings, 0 replies; 7+ messages in thread From: Akshay Joshi @ 2020-04-01 12:51 UTC (permalink / raw) To: Aditya Toshniwal <[email protected]>; +Cc: pgadmin-hackers Thanks, patch applied. On Wed, Apr 1, 2020 at 6:05 PM Aditya Toshniwal < [email protected]> wrote: > Hi Hackers, > > Attached is the updated patch. The issue was on PG9.6, fixed that. > Docs updated. > > Please review. > > On Wed, Apr 1, 2020 at 5:37 PM Akshay Joshi <[email protected]> > wrote: > >> Documentation and Screenshot need to be updated. >> >> On Wed, Apr 1, 2020 at 5:10 PM Akshay Joshi < >> [email protected]> wrote: >> >>> Hi Aditya >>> >>> Tested on 9.6, test cases are fixed but wrong SQL generated for tables: >>> CREATE TABLE public.test >>> ( >>> col1 bigint >>> ) >>> WITH ( >>> OIDS = FALSE,, >>> parallel_workers = 56 autovacuum_enabled = TRUE, >>> >>> Also parameter parallel_workers is not showing until we enabled the >>> autovacuum parameters. >>> >>> Please fix and resend the patch. >>> >>> On Wed, Apr 1, 2020 at 3:35 PM Aditya Toshniwal < >>> [email protected]> wrote: >>> >>>> Hi Akshay, >>>> >>>> On Wed, Apr 1, 2020 at 2:51 PM Akshay Joshi < >>>> [email protected]> wrote: >>>> >>>>> Hi Aditya >>>>> >>>>> API/RESQL test cases are failing for EPAS/PG 9.6 and maybe above. >>>>> Please fix and resend the patch. >>>>> >>>> The SQL is corrected for 9.6 versions. Others seems to be working fine. >>>> Attached is the updated patch. >>>> Please review. >>>> >>>>> >>>>> On Mon, Mar 30, 2020 at 7:47 PM Aditya Toshniwal < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Hackers, >>>>>> >>>>>> Attached is a patch to add support for parameters toast_tuple_target >>>>>> (PG v11+) and parallel_workers(PG 9.6+) of table. Refer - >>>>>> https://www.postgresql.org/docs/11/sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS >>>>>> . >>>>>> >>>>>> Both the parameters are added in the advanced tab of table dialog. >>>>>> >>>>>> The patch also fixes a related issue - RM5180, >>>>>> where autovacuum_enabled parameter is added automatically in the RE-SQL >>>>>> when table has been created with WITH parameter. >>>>>> >>>>>> Please review. >>>>>> >>>>>> -- >>>>>> Thanks and Regards, >>>>>> Aditya Toshniwal >>>>>> pgAdmin Hacker | Sr. Software Engineer | EnterpriseDB India | Pune >>>>>> "Don't Complain about Heat, Plant a TREE" >>>>>> >>>>> >>>>> >>>>> -- >>>>> *Thanks & Regards* >>>>> *Akshay Joshi* >>>>> >>>>> *Sr. Software Architect* >>>>> *EnterpriseDB Software India Private Limited* >>>>> *Mobile: +91 976-788-8246* >>>>> >>>> >>>> >>>> -- >>>> Thanks and Regards, >>>> Aditya Toshniwal >>>> pgAdmin Hacker | Sr. Software Engineer | EnterpriseDB India | Pune >>>> "Don't Complain about Heat, Plant a TREE" >>>> >>> >>> >>> -- >>> *Thanks & Regards* >>> *Akshay Joshi* >>> >>> *Sr. Software Architect* >>> *EnterpriseDB Software India Private Limited* >>> *Mobile: +91 976-788-8246* >>> >> >> >> -- >> *Thanks & Regards* >> *Akshay Joshi* >> >> *Sr. Software Architect* >> *EnterpriseDB Software India Private Limited* >> *Mobile: +91 976-788-8246* >> > > > -- > Thanks and Regards, > Aditya Toshniwal > pgAdmin Hacker | Sr. Software Engineer | EnterpriseDB India | Pune > "Don't Complain about Heat, Plant a TREE" > -- *Thanks & Regards* *Akshay Joshi* *Sr. Software Architect* *EnterpriseDB Software India Private Limited* *Mobile: +91 976-788-8246* ^ permalink raw reply [nested|flat] 7+ messages in thread
end of thread, other threads:[~2020-04-01 12:51 UTC | newest] Thread overview: 7+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2020-03-30 14:17 [pgAdmin][RM5181] Add support for parameters toast_tuple_target and parallel_workers of table Aditya Toshniwal <[email protected]> 2020-04-01 09:21 ` Akshay Joshi <[email protected]> 2020-04-01 10:05 ` Aditya Toshniwal <[email protected]> 2020-04-01 11:40 ` Akshay Joshi <[email protected]> 2020-04-01 12:07 ` Akshay Joshi <[email protected]> 2020-04-01 12:35 ` Aditya Toshniwal <[email protected]> 2020-04-01 12:51 ` Akshay Joshi <[email protected]>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox