From 44901f88859fd98251633cdf04cd0911067b4cc8 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 3 Aug 2023 23:03:39 +0200 Subject: [PATCH 1/2] Fixed part of issue #1307: using pin names for the pin labels in DEF importer, generating pin names on pin name property + generating net names on net name property for pin shapes. --- .../lefdef/db_plugin/dbDEFImporter.cc | 14 ++-- .../lefdef/unit_tests/dbLEFDEFImportTests.cc | 9 +++ testdata/lefdef/issue-1307c/au.oas | Bin 0 -> 582 bytes testdata/lefdef/issue-1307c/in.def | 34 ++++++++++ testdata/lefdef/issue-1307c/in.lef | 63 ++++++++++++++++++ 5 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 testdata/lefdef/issue-1307c/au.oas create mode 100644 testdata/lefdef/issue-1307c/in.def create mode 100644 testdata/lefdef/issue-1307c/in.lef diff --git a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc index 1a58a5061..e68e60bb6 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc @@ -1153,8 +1153,7 @@ DEFImporter::read_pins (db::Layout &layout, db::Cell &design, double scale) { while (test ("-")) { - take (); // pin name - + std::string pin_name = get (); std::string net; std::string dir; std::map , std::vector > geometry; @@ -1281,7 +1280,7 @@ DEFImporter::read_pins (db::Layout &layout, db::Cell &design, double scale) if (flush || ! peek ("+")) { // TODO: put a label on every single object? - std::string label = net; + std::string label = pin_name; /* don't add the direction currently, a name is sufficient if (! dir.empty ()) { label += ":"; @@ -1296,9 +1295,14 @@ DEFImporter::read_pins (db::Layout &layout, db::Cell &design, double scale) if (! dl.empty ()) { db::properties_id_type prop_id = 0; - if (produce_pin_props ()) { + if (produce_pin_props () || produce_net_props ()) { db::PropertiesRepository::properties_set props; - props.insert (std::make_pair (pin_prop_name_id (), tl::Variant (label))); + if (produce_pin_props ()) { + props.insert (std::make_pair (pin_prop_name_id (), tl::Variant (label))); + } + if (produce_net_props ()) { + props.insert (std::make_pair (net_prop_name_id (), tl::Variant (net))); + } prop_id = layout.properties_repository ().properties_id (props); } diff --git a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc index 788770b82..f2bbd750d 100644 --- a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc +++ b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc @@ -882,6 +882,15 @@ TEST(131_patternname) run_test (_this, "patternname", "map:v.map+lef:v.lef+def:v.def", "au.oas.gz", default_options (), false); } +TEST(132_issue1307_pin_names) +{ + db::LEFDEFReaderOptions opt = default_options (); + opt.set_produce_pin_names (true); + opt.set_pin_property_name (2); + opt.set_cell_outline_layer ("OUTLINE (13/0)"); + run_test (_this, "issue-1307c", "lef:in.lef+def:in.def", "au.oas", opt, false); +} + TEST(200_lefdef_plugin) { db::Layout ly; diff --git a/testdata/lefdef/issue-1307c/au.oas b/testdata/lefdef/issue-1307c/au.oas new file mode 100644 index 0000000000000000000000000000000000000000..3c942ff581117e37c7597cce84535cf1598cb0f0 GIT binary patch literal 582 zcmY!lcJ=kt^>+;R4CduxWH!_@V0gjKC?n3q!6L)YEF;ds&!EJR>XUoMnybM;fb~F; z;|1o9>4KX(8~>b$4qRRSKbqrK6n{_8gJqfL$jXNzHa^&6B!{rtFC$hI5 zKl>z`Wr<|P0uu&apbwJ6g*~68S{QbIY?`yej$c?gnE7?fQXlr2J0$f^aGqRYTx9Uc z__Rim!N<)VMLrW4H%a`IJXoXlu*gl$ZGjuxL!Jdu8^d|HB_bsy8fWRBaGcWl(ZHY~ g@(cqr*fUIw2bdVAGBPSN7BenqWMpU Date: Sun, 6 Aug 2023 19:16:52 +0200 Subject: [PATCH 2/2] Update of LEF/DEF testdata (changed because of different labels and properties) --- .../lefdef/unit_tests/dbLEFDEFImportTests.cc | 22 +++++++++--------- testdata/lefdef/issue-489/au.oas | Bin 596 -> 556 bytes testdata/lefdef/lef-skips-end-library/au.oas | Bin 596 -> 556 bytes testdata/lefdef/mapfile/au.oas.gz | Bin 537 -> 617 bytes testdata/lefdef/masks-1/au.oas.gz | Bin 1036 -> 601 bytes testdata/lefdef/masks-1/au_map.oas.gz | Bin 1730 -> 762 bytes .../lefdef/masks-1/au_plugin_alt_lef.oas.gz | Bin 1652 -> 764 bytes testdata/lefdef/masks-1/au_plugin_def.oas.gz | Bin 1646 -> 762 bytes 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc index f2bbd750d..09590536e 100644 --- a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc +++ b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc @@ -326,26 +326,26 @@ TEST(lef8) TEST(def1) { - run_test (_this, "def1", "lef:in.lef+def:in.def", "au2.oas.gz", default_options ()); + run_test (_this, "def1", "lef:in.lef+def:in.def", "au2_2.oas.gz", default_options ()); } TEST(def2) { db::LEFDEFReaderOptions options = default_options (); options.set_cell_outline_layer ("OUTLINE (10/0)"); - run_test (_this, "def2", "lef:0.lef+lef:1.lef+def:in.def.gz", "au.oas.gz", options); + run_test (_this, "def2", "lef:0.lef+lef:1.lef+def:in.def.gz", "au_2.oas.gz", options); } TEST(def3) { db::LEFDEFReaderOptions options = default_options (); options.set_cell_outline_layer ("OUTLINE (13/0)"); - run_test (_this, "def3", "lef:in.lef+def:in.def", "au.oas.gz", options); + run_test (_this, "def3", "lef:in.lef+def:in.def", "au_2.oas.gz", options); } TEST(def4) { - run_test (_this, "def4", "lef:in.lef+def:in.def", "au2.oas.gz", default_options ()); + run_test (_this, "def4", "lef:in.lef+def:in.def", "au2_2.oas.gz", default_options ()); } TEST(def5) @@ -355,17 +355,17 @@ TEST(def5) TEST(def6) { - run_test (_this, "def6", "lef:cells.lef+lef:tech.lef+def:in.def.gz", "au-new.oas.gz", default_options ()); + run_test (_this, "def6", "lef:cells.lef+lef:tech.lef+def:in.def.gz", "au-new_2.oas.gz", default_options ()); } TEST(def7) { db::LEFDEFReaderOptions options = default_options (); options.set_placement_blockage_layer ("PLACEMENT_BLK (11/0)"); - run_test (_this, "def7", "lef:cells.lef+lef:tech.lef+def:in.def.gz", "au-new.oas.gz", options); + run_test (_this, "def7", "lef:cells.lef+lef:tech.lef+def:in.def.gz", "au-new_2.oas.gz", options); options.set_placement_blockage_layer ("PLACEMENT_BLK (60/0)"); - run_test (_this, "def7", "map:in.map+lef:cells.lef+lef:tech.lef+def:in.def.gz", "au2_with_map_file-new.oas.gz", options); + run_test (_this, "def7", "map:in.map+lef:cells.lef+lef:tech.lef+def:in.def.gz", "au2_with_map_file-new_2.oas.gz", options); } TEST(def8) @@ -377,9 +377,9 @@ TEST(def9) { db::LEFDEFReaderOptions options = default_options (); options.set_separate_groups (true); - run_test (_this, "def9", "lef:tech.lef+lef:cells_modified.lef+def:in.def", "au-new.oas.gz", options); + run_test (_this, "def9", "lef:tech.lef+lef:cells_modified.lef+def:in.def", "au-new_2.oas.gz", options); - run_test (_this, "def9", "lef:tech.lef+lef:cells_modified.lef+def:in.def", "au_nogroups-new.oas.gz", default_options ()); + run_test (_this, "def9", "lef:tech.lef+lef:cells_modified.lef+def:in.def", "au_nogroups-new_2.oas.gz", default_options ()); } TEST(def10) @@ -413,7 +413,7 @@ TEST(def14) { db::LEFDEFReaderOptions opt = default_options (); opt.set_macro_resolution_mode (1); - run_test (_this, "def14", "map:test.map+lef:tech.lef+lef:stdlib.lef+def:test.def", "au.oas.gz", opt); + run_test (_this, "def14", "map:test.map+lef:tech.lef+lef:stdlib.lef+def:test.def", "au_2.oas.gz", opt); } TEST(def15) @@ -429,7 +429,7 @@ TEST(def16) // (complete example) db::LEFDEFReaderOptions opt = default_options (); opt.set_macro_resolution_mode (1); - run_test (_this, "def16", "lef:a.lef+lef:tech.lef+def:a.def", "au.oas.gz", opt); + run_test (_this, "def16", "lef:a.lef+lef:tech.lef+def:a.def", "au_2.oas.gz", opt); } TEST(100) diff --git a/testdata/lefdef/issue-489/au.oas b/testdata/lefdef/issue-489/au.oas index 436fa32c63d123c4e7396be278b2389fb0dec065..a7cae1c1e5e9586447f11d1622f6afbfd9289b6e 100644 GIT binary patch delta 311 zcmV-70m%N;1gr#*6@LL77XkGfZOl6gfG`jRz;Z#*1BjOqvx$NH z$XijXcmG=m+FB2cjNqmzv3d_RnZV${)@##lx6EK(FCvDbjUSrA!BzxEU_U3CXB4axn5U$tZF#@iU2XOppPx82K5&d`97NMjl3> zMh4*wpjxq43@Hm3Ss56CnlH#fl!@^$Fo0Q100RVcWpi`_0j2^0g8=~}0doP30RaG$ JVFB&}004Doc5MIv literal 596 zcmd^1J5Iwu5S`tPv59wyL~shUvP6NX2#^~%cx6`dPacO)wFN?=ClW13h&VwS4njxi zV<1k!5Gahq4VdE1`^_ApDeQ5TphY!g;%s^f?>_WLNBiiC{T*~!imq;|+BEIWwzy1F0z|RNy)R9G82Z(s z&24Ff5+M5`+$v_%+Ll5JE_*x-$j_6x$thv-mkN0?BNyb)RGfZOl6gfG`jRz;Z#*1BjOqvx$NH z$XijXcmG=m+FB2cjNqmzv3d_RnZV${)@##lx6EK(FCvDbjUSrA!BzxEU_U3CXB4axn5U$tZF#@iU2XOppPx82K5&d`97NMjl3> zMh4*wpjxq43@Hm3Ss56CnlH#fl!@^$Fo0Q100RVcWpi`_0j2^0g8=~}0doP30RaG$ JVFB&}004Doc5MIv literal 596 zcmd^1J5Iwu5S`tPv59wyL~shUvP6NX2#^~%cx6`dPacO)wFN?=ClW13h&VwS4njxi zV<1k!5Gahq4VdE1`^_ApDeQ5TphY!g;%s^f?>_WLNBiiC{T*~!imq;|+BEIWwzy1F0z|RNy)R9G82Z(s z&24Ff5+M5`+$v_%+Ll5JE_*x-$j_6x$thv-mkN0?BNyb)RfBa{yBfcJ=kt^>+;R4CduxWH!_@ zV0gjKC?n3q!6L)YEF;ds&!EJR>XUoMnybM;fb~F;;|1o9>4KX(8~>b$4qRRSKbqrK z6n{_8gJqfv=z9s{K)`P1wjCUEy zH1A((ZJ?T|bAjax%ZsUBcJPTNYd?5b`~Iv?TGWSE-rBB5Bah3NFg6*5l}3Ct3tH4A zb#=7?&rJW;dZUQxp7RY-czD;=u2S3U;N0xKOCU(dCUy(QpT?|GrNxKk+5UVoRD9m1 ze0-JX$(@f+H1b;h;##B{#S*P_vitikzFRBS@9OIL!o|B*{glr0zlwHIUuH%;=Uv!s z_NsHI&E&cr8B8*#N*T_6PdXgxYz?ks#6%;t}(k`XBMgC(MYkK$Sh)Uf>Dz}xSD~7OLQ%h zNEIVQnim)sX)(fo4t#0)%ewmkyW95cGe)m^WP1MeD4o>g(Z8Ypq5JQXNhzrbH7EIk z6c=+$NfP>f_VAg*M-S|1c+2vbUvGoN<`tsC%EA1}T+GZNXVt|#&D`83s6{@^a+A|j zHfLal#SJqwZkV~kJRReU3riD=QkfY0Ss42m8I>7}8K*HaGBk`Rz`y_iinY&{ECT=l DBCa}O literal 537 zcmV+!0_Oc6iwFqMJyT);19WY0UomB7Wid86VJ>fBa{%R&KX21O7{>2>ah%+}ZWYzB zROE#L0RwKF2~}c9>PxWjKjqx=XR)F>m5``_A_mBU)Rm~ZgfGBN&+mDjdv$k~ZwMZEccPx~gibMW><*e~sJyK9HIW9rN2&0JA$LxB%crF$3;-Z;#TrmrB~_G1BNm%Bj_%9^EG*>l?gNDfjUbvmVd?7S+UPqlIe?mD>7X%zEcFcZXAPZ z95bZj*12Mw5QeB08`BI8zLMcLV!VM{*}W5D+&#s&(Z&=3ZGTpbw|E}wsCA~yw3*gA z%N^?`YT$Kb>}T@V`m%2RqMIthKeW7IU6&Cye**!E@TdAIKBtAJw6_(kyvG?r=Fi$@ b9plUT#uNkX4wQHQ^Frtk?jq&Ay959LGe-=3 diff --git a/testdata/lefdef/masks-1/au.oas.gz b/testdata/lefdef/masks-1/au.oas.gz index 4d8805a01800c5103809435b1407e25debe09012..63d18bc9aa49666a76fd79ec8185c1877f397d06 100644 GIT binary patch literal 601 zcmV-f0;c^RiwFqD&(CB419WY0UomB7Wid86VJ>fBa{yBfcJ=kt^>+;R4CduxWH!_@ zV0gjKC?n3q!6L)YEF;ds&!EJR>XUoMnybM;fb~F;;|1o9>4KX(8~>b$4qRRSKbqrK z6n{_8gJqf4#L&S!n=y8RBi|td9u`j-&X&(&SL_yg*oJs%us>k+ z?5j<`og5z$zDf3h+3s7VZyr?E>_7D3#leFo>$yudR`w+*RI6^;$l7qUg0aj3o zM^VdAi_i;d zak0g0i`fz9i@wL)*ZAe~@QRk^uIP2vbFtW=yN7tQ2WxKE)`~$i&MC z6gb5Q5lI6H00V0w;|xaGo{hYR3`AJ}7Yn%YP2xQ0Cis(8)Tu;M(6sx(mNg8_3TX?{ z8QltYb!a+?cdB`{I{);0ub1h%)_Urej1*<@<$|W4wwhQ^5nx_fy6+&1lvJs`8I>7}8M_%785%|uU|;|MkS$_x6$1bOAWJoY literal 1036 zcmd^7%Wl&^6rDTQ;M8_VOJk#gy4q2$= z^0Cd^35$BqSrYUIzQ=+=>i7K-dlq=<(}rRw5_sj^d#|N?)wtp69I~=V493)xDs{-o1Ih|2Ah`<}&vR;&QBet&-_#yqku> zz()m%ak-Vn-zN=d5mV=%=y=1i&hriRA^f2e$NB~n00KWb)iHM{ z(9e*O64pNwfbJKnlWf(zIfoL=J2)m}eG{Kp=b51q_fBa{yBfcJ=kt^>+;R4CduxWH!_@ zV0gjKC?n3q!6L)YEF;ds&!EJR>XUoMnybM;fb~F;;|1o9>4KX(8~>b$4qRRSKbqrK z6n{_8gJqf05a`k8Qo%W_nWQm7j zuggQ01Cxp`=@cvFoLA|Qy?A%e|KpRtovf&?u`bQMf8=$AtLlSqsrEAOe?R*Y;o2ep zWXFr_XYva258Rp;zLjK_JayUU*DZ5Py{gI_rcaEM*w!EZ(`}bIb%wQ38C#V5&*=AW z9hdJrQF!t60gflkcQP-?&YSg4QFeB^>bgd~Z8?@OB|TgsScB2esDwq=RU+&io{15dl^_xn27Ib2FGlSpx|O?r1? z#+w&fr|x^{HNRQ$bkX!i!4vE|E-O^}9KV?|L3Zzze@whgBDWdSDk>{Qnwd{AiZn9u zG6DroF+xPrKmx!R+{rkb(e&&_-a`f=EEnqe5>h7ka2R%ph=+8TrMjF|ve4B&z|bKn z(JVMeFNy22YelA5Sj^bX$jHzzq5uN}0DiM@ovi}^0Nd}BQvd(} literal 1730 zcmd^9%Wl&^6rDSh)~W4~md2q$>4F8SSP)__BQ}A!!BSp|(*i52B8h|q5f35J6-8_j z-@s?^2}xH~xBNiZRjd%*aPN$5#uWMkWHsk;&rD9Pax?V1!R>xC48np5!mZWW(qQ_h z>Rb<_Zu3zT2JN2Tih|zAZ~MdOVbB^q$mgnss*?A5e=}4aGmJ+4L3H2mbZq1K!HenB zXA|Q}7`0nrG#K^={&4hoO`v5>?6+DXv558kpc%b>`R3r&B=RCRax;vJoVP*~meJoE zb%LHRa)Q}9u*`0K(69CUQNtA=#`Ygr(>>JZpcxclPk=%LQ-42q{wlj*Z~IK`Sy zVW&wt85CjJGCdq5FPzvHn2d+U7LYM1D!vOFlW&>EZ%MJH)4*}^7BVQp+LCYSH1GMH zJL>4~N`!u}FIBN6H*Q&A%Ndkvo)FYbWLguUHgqX_s6r~zju|>LDbx6=EA&eWuL(-qX{{E?0 zCeGL6_Bicm7HhgExZKgypa?5332Kqkj_N3$R^4%IQl+O@(!1cPCI&;THvLxFnxP? zSo(m`rT4r5NF0M=rbMufGk#M1VQ!qk(pVa$Cpr8p{Bo^)4r9{X{xJ3nvO>4A diff --git a/testdata/lefdef/masks-1/au_plugin_alt_lef.oas.gz b/testdata/lefdef/masks-1/au_plugin_alt_lef.oas.gz index 9f2f877ccb2d5553180ef5266897829db2dff9a8..854bca284df4afc165f25009ce8dcb25e74bc5f9 100644 GIT binary patch literal 764 zcmV+;R4CduxWH!_@ zV0gjKC?n3q!6L)YEF;ds&!EJR>XUoMnybM;fb~F;;|1o9>4KX(8~>b$4qRRSKbqrK z6n{_8gJqf05a`k8Qo%W_nWQm7j zuggQ01Cxp`=@cvFoLA|Qy?A%e|KpRtovf&?u`bQMf8=$AtLlSqsrEAOe?R*Y;o2ep zWXFr_XYva258Rp;zLjK_JayUU*DZ5Py{gI_rcaEM*w!EZ(`}bIb%wQ38C#V5&*=AW z9hdJrQF!t60gflkcQP-?&YSg4QFeB^>bgd~Z8?@OB|TgsScB2esDwq=RU+&io{15dl^_xn27Ib2FGlSpx|O?r1? z#+w&fr|x^{HNRQ$bkX!i!4vE|E-O^}9KV?|L3Zzze@whgBDWdS7BDUZLXl?XQ;Z^w zOuURhu~Uq2!8DKYy6@svy4o8)`1W3T6{{>QBxj>yWhoR8bED;qPwB*&T!%_i9$s{C5Ec6} z_uH9;&sSc*y7|-(vHzQnvUmcIrXFOBII6jy3=Ui~< ucbWH?y9gSxbV)KYFfsP9GPW@?Dl--{b~7?EG>j;~zyJUYkJ_HI0{{T%5Q)_Q literal 1652 zcmd^9%Wl&^6rDSh)~W4~mc~Ir>4F79AQ8o0Mr;Bx!BSqT(*i52B94Rv5f8DZh%Mq9 z%3tsaX;)RZ{6K(Bmk2i8J7W)H${*lta$fgNjz_s3hr{UhxEn`t#RlQG+H7Sp^J#il z<7C);T$otB;D!^xls zobG2$3T(1~v=#_KE#{(vINNXK4GNLs?gBP+3SfJG42qERRZ~LD<#>&>MpkT%cB{?^ zN>w!^urU%fa@G-1TLRlMzRQeiMu>&XXrwjThAq)R)e%9*#?9@lB~JIPhz&guT;4Zr zP=w=3B5#XhTNjvuhhlW!jF_UbUC84b=h&J$i^hgd0lIH;1{oBQIaFVq?wd4d?35*@ z207g~6J=S|8^;z^R%1h_Wpv;2xZHjQ6<+%S^CS3#pW1soU+o>Q0CFdw$vJUs>ztof zf7n~+u(DQG?MVs$z&>B8|ALuq11y2W<_%VcD)TxiaB{KJYV#U0Q2%)hjWq^ekz83j z+iw{_@R2)gw&`^^@DDI!OYknA;h_3=dZi4G)^Q-ESv^<+lWTYC-_nM42M{nd+3Orb Xw(PL6vwc(C_iioJKz{f?KaBkbp{Jp& diff --git a/testdata/lefdef/masks-1/au_plugin_def.oas.gz b/testdata/lefdef/masks-1/au_plugin_def.oas.gz index dd9c9bc008868577076f620e8a1ffa688c5d1963..5edbb0bbedd13a10e29157382968e512e00d7ca4 100644 GIT binary patch literal 762 zcmV+;R4CduxWH!_@ zV0gjKC?n3q!6L)YEF;ds&!EJR>XUoMnybM;fb~F;;|1o9>4KX(8~>b$4qRRSKbqrK z6n{_8gJqf05a`k8Qo%W_nWQm7j zuggQ01Cxp`=@cvFoLA|Qy?A%e|KpRtovf&?u`bQMf8=$AtLlSqsrEAOe?R*Y;o2ep zWXFr_XYva258Rp;zLjK_JayUU*DZ5Py{gI_rcaEM*w!EZ(`}bIb%wQ38C#V5&*=AW z9hdJrQF!t60gflkcQP-?&YSg4QFeB^>bgd~Z8?@OB|TgsScB2esDwq=RU+&io{15dl^_xn27Ib2FGlSpx|O?r1? z#+w&fr|x^{HNRQ$bkX!i!4vE|E-O^}9KV?|L3Zzze@whgBDWdSDk>{Qnwd{AiZn9u zG6DroF+xPrKmx!R+{rkb(e&&_-a`f=EEnqe5>h7ka2R%ph=+8TrMjF|ve4B&z|bKn z(JVMeFNy22YelA5Sj^bX$jHzzq5uN}0DiM@ovi}^0NAXQssI20 literal 1646 zcmd^9%Wl&^6rDSh)~W4~mc~Iv?t%qEAW_9$Mr;Bx#Zq3X-2yACY7z+vDjq_jD~i}6 zzJbr+6Oyi~Zux-#n=TP-xOc`L#*{z6tDMKZXM8-$^(5-Yw}+i1PHHxYV5`Lz7Be5; zyP9PE&Z8`ew+B%-iw9}69qnWf<8Jz(TJdYXl6MFHGWedIWa)5}-HUoX*Lt@9eEQ_+ z#JZGZ+ubA^?F>iJPWpI7pk+nub-SXlh}FHglf8QJdjI7l3$q{#N=$%UxI`0H3spx19UGHdc}tw`TNxXAD7d_D z+Mo!>l|<1N$F?poB@d0!eKW=sm1iN3Uz}rW>MR-?It|c$lRL=oCixtr(Z-XHesfFED*`bkul{hikm!H9+D76f-4)t)27J z`VV{U92VBXY8+JXuj})b<}VoAHoy!>^lz{#)S1_w04Enat^3!If#%OSY%DSOisZuD zTz|^|!jIfx<5jQCfq#H8n}K)v3>P)O)5m1+X&D#NG;4-4U@~^I`E9ac-2ntlZT8x8 Y$it2|HrH>8``)cXwU8hG&ktk20XDXvwg3PC