zsh-workers
 help / color / mirror / code / Atom feed
* Substitution ${...///} slows down when certain UTF character occurs
@ 2015-09-26 12:19 Sebastian Gniazdowski
  2015-09-26 20:44 ` Bart Schaefer
  0 siblings, 1 reply; 19+ messages in thread
From: Sebastian Gniazdowski @ 2015-09-26 12:19 UTC (permalink / raw)
  To: zsh-workers

[-- Attachment #1: Type: text/plain, Size: 674 bytes --]

Hello
Half of the following example characters will cause the slowdown: –,
¥, Ń, Ł, Ǎ, Ǟ. I attach a script that does ${...///} substitution. It
is very slow for some chars and very fast for others. How to explain
and hopefully fix this?

Example script result:

( out_array=("${str//(#bi)wfeiwj/a}") ; )  0,02s user 0,00s system 97%
cpu 0,017 total
( out_array=("${str//(#bi)wfeiwj/a}") ; )  0,89s user 0,00s system 99%
cpu 0,890 total
( out_array=("${str//(#bi)wfeiwj/a}") ; )  3,70s user 0,01s system 99%
cpu 3,712 total
( out_array=("${str//(#bi)wfeiwj/a}") ; )  5,73s user 0,01s system 99%
cpu 5,743 total

Best regards,
Sebastian Gniazdowski

[-- Attachment #2: test-script.zsh --]
[-- Type: application/octet-stream, Size: 120420 bytes --]

#!/bin/zsh

emulate -LR zsh

str="c4d5148ca6 ce3a2d24203abfb385 30f5fe85434ae 75bdd124e2c238db971832271f39b878 b3d0be19f734149c4b85429b6 549991c47e811b8 cd61d5ff1142b8ee 4b 08e75c43b 4c8 90e2612b1b98c35c49234b8bbbabc125c773caa36be7947e5f513a83728fdb5d72486ece9f6f3ff5f71a8 ef 926db4a3e82 db7 cdc979edb50b3294ca1044f8fc70f42b533f614 4e60369be4afdf13ba53af422466cdd 7d404e168b1851987c31d15 53ef04d 43b 3ba5fb18a89dc49f137d46a7e92fcceecbe576bb6a2b270da5c3 0d4 1d475dab43035de76fbd401c63a59524dd459eb97d2c4164c58a860777dd336ab7279e71bc177586a454bb3f64b3b07c532fda 7184fb1c98808afeb8580e1261c45dd14 9 facbfb 3a70 699d24a 92c93da527c28f037978b092c485cc975bef2d76eaf3b3da913d235526f90 d928de0ed8a62d4c8da326 7f200d40baeb0f6b08d689d d87cf7493c92 74 2e2d881feb901176ff4c4eb0b61d2f05ca8612966e3b35ea 7ed2accb7487ad5b45e152fee3a9c 918e733b1a 8bf6b3b241f55a4 36d8a39e7bbd774c8ad82cd9998f4c68fc11e12 c0 cd e321f8a 3776f8b0b9fefcd7dbfb1f8c0ab5d1a6ce 76b92b4dd28209 6b4f475d8dd03b024fafa049ab82b c95 c4e5382403cef c6d693 c aed3437864ea e6 d3720b8bf13f2822469ad5f ebc11 ba4300104bfa13f9d7e3c691b8df989f8492 c1e9a002bcc7329eea17 86dce73e1bdea6a8e6de8f4c9e5e6eecfc13eec15bb9 1cc9185f bc54da07ea3 85e7d8ae0f90cfd 37dc531dcc05ca327cea18c43be18e 7f83bd2ee4cf144792 040728fd4a54347b671cdb119dff904fbc 982141905dea8357be7f206 97 231fe824329d be4d9aa17be 1bd08697be7eea7ec29d56  ea877 bd9f 3203198e2e04 d70b8fd 413730e379e154012eedc2ca506abd97ae 35 23ba675de539f5538f48dad2b37c640aba6db2a87788bbd4adc252 cefb64a37aaea13ab 55eef0973aae73e8b6d0b9272defff5a9cc36e5680 834e 90ce67692459288b628fdf1a62c5 db1645983e54ea1bca2ca e 2e84 da02ad6ca8d3b f0fce36bb8147e26232cbdcb3a 993514f02276baf7935574449 e1848634f635855d0 7721f8ca81ea975 a8e1447164135d84ff6fd65b3 2e272daca61 67813a0 e8a2f67 34395c8e8cd6b5d 4fc4c2b8527d2c81fc 9257abd8759536953972662315c7d2c4 005cf0 896a064029d45 82b4 863e77b5292619650303f21cd9d86b7f8e19ddd65 9 8914 753dcef2 7 d6850888 54fac8f5487b189b3 59ce9fdb56dc12d0af71af60c de0  d364c6d786 96f1c9a9c20a7f59e8a154a57  39095 0aa457ef6cb c41be81d99 9 57012 f f35cdff33360782b6e11df 3484 c991270 623795d 86b89b 94 b74e7370973532050407dd44c 9b7a b53cb44605e1946e184 7f1c4551fb1c01a6254e5af75ae0190acb705af7c0cab03a6619e7c2a98d44b4 47dbb13a057b 441def43c49a 248d202404  b4a320dc9340b3118b563128a73e7be4d6f8 3c7390bd742c3b7af38bac871e5d748 29 284cf165df04d 6736718b317b40b220969f7eb8a1c4220f7ae81461108ab625 469e4fe6785c3f585326eab811cea59e0b8d 5281 3bf8ead70793ce85f2bb4f206ab 7cfcf1e36 173151 da0 e58e4 0d44b33aa b98942f8bcf01bc40ffc267dfe272e8ae35e32520 ed9b4a44aee5f80efb641bdf 0302897e699d2669 78cc046 1782a29e39bea13795b693 6c8dd2375647657becd18da0a2710f59 edf69689e9a0 2a55 3fc7d65 f02ef2a19 8f e88e7ec6f5d8723 eaed4433d57cea34 fc86 39e771bf7d4dfe60c9e3c33d77641 b763d721cb9e8c 126536205dc53bd2 e6a9f47e7a3fc7df72 f9033430e9aec3035331ead2b4ef9c0ba3c37b4d45d38e07 b38 1e488c2d48674adab2efeb5e73cd0f9eaa760e11 8474debef0f173878b41b0445e0a40ed483b16767ab5 bfbc02a26dc3ea4c9a20d406f39a 677ff7120a304f05d92fae5d104c2554d0aa7f61318c2784e1dbc597d7a9d 4725b9b87a5a3325d6456fda8c14915 36dc 46 a7 a6d1b71003d61d5ee0df61ee7789f7e16ced2db6 ae2844f228851ffbd1b5ce70 ebe1e8f 821206dae4d76caca181e8d15 54 374 87 91d15f61b70ba633f0f5a732b6969551d72862f1b 63ddf793c 98a080c0a706 b90c10b4032ba9e2982 322b19a7962d577e784b7bd44e dcbe56b6 f c6e4158824ad4c777196a2114bd07a9b  31f83cb7711 eafe33d142d5b467ec959 5512746ea49eb7fa211d6764b74849b3e9b04 ed4 9b4e68d7483a5324c9dc74bb94678  301a90e75facaef5035e9bef4e2766797c8bbef 857da 94b95b7192037c6 b40575fd72d2c6ac2fe8ec22b2c5647dc0639e1f4408b3aa f5aca7ce245 1af87d9508dc65191af96 b29aaf08d 3a1 94dd   6985 96775502d 4818545c687a5696b14dadc581a22 cdde8fb92195a228d646e48  e22bd3 ce7b 645ab99234a8cd9edaa58938454ebd186222 fdff01 b055 f a180c078d4ec3bc5034901bc38fcce155fd8c 3eb03c1f0a5234a3b55d65e33a6663726dca9837cabae83392f0d5d9a0276004 e3f10a876c18357eb66f7951ce0babbe8809d07aa2caa353f048b91adfaca6f96a6 5d22 986f3f04 0761ff3 c4b327e5b e6e3f40 52da5 ed06a4 298c3876f6fa0aaa26ecf433859fe57a491729e5171b09c0726d1979c7068eae8ffb13fde35bd5a9965d0e366dc11f b3b6ab717bb5 2cfbdb256accc90ceff212eb16e0d5 b7859b97815dddbea78d93f52da0e6878734c 89 e99fd2ffec9c636af28db21b5158b175c97fbe62683f ef 65418d0633f8c0e87ccf 9 6b3053c6f7bff4b cac90abf43 1c5bd63c914 c5f44245c02306e8b2bf5 9db6d582602ae680d861 9cbb8c22339dc4 fec3f8c73d af5816fb821e9880048ed 2d3fd64334e80e46be1eaecf3c9c636d9048e6fb366adbac004466868d8 7a889676fd34cbb f9e954d45c21 fba8de1b7 cf8bf33017ba2932c0ed6eb80645a33c2ef b61445d5d9000d0e30d78a2b2f8a221c78b7633d9d5fb34 924a31ff257 b98b3d0f33c0 013d8d7fa697 ee8ac9c7cd9921eaf5 fc95b4b731dc40f1d98c1861f3f9f51ccd02f094a2a05d8f9ff0e848899c52f8f04ca9d8c8d755cb33d7904a35cbd39c666b 1c9136ff5fd1 0db65a3b2508f1e9bed927b 14d70c6411675ca84207d8899024146377441dd3f3020dde7e7e88f 95e46f2c4c422e7fc94a5be7e6b48f058951bfcc870531e80980c94fe497e8638c3770245212f e8de7a83d6 6c5097efebb3174f688dff30dffbf41dc81b40c 22608a44a6dae812539e4c78bea6dd377011f61d9ba659701cc7b8487  645c 7ee5916  b2a  550fd23778e0036f3d1888 f7a4 85a3f56024c167d9e1559199e761495f0f311ea41db7f5755ef0e18f715837f84473dd69454e84f4f76b3056b75c e7da6c824acf49277c2f66701f72cdea3ff51226135d351ef3d115 9f 6875a3c 377c84be7a711 5f340f682329b 53646d5f246 0 999c2d82c37eee613 944 6ea2a89d3030e7173bc8b12c86e0ba9ec4b1339ac 3ab204aaf521b54015a9354f5468d1255f77c5912 069 bdaec6dd992efcbb648bad8dcf043c1af71d07e50 51ca4aa5 f1be974ed401 805b57912 f6e44c6db40e8861a96  1d0f3bb2c8 3e3 9a9444a9494793 226f79117509ad e0ed8356e5219171d6ace94 dd3e 30787d4a6521af485d0 7b50b99 62f460777209c4f7cc8f60d491dc732c9bffb79fb bb66a5d1a123b3 a85 65f3a999b69a1ff372 f1e126ddf356dbc 72c 25c7e96ba60ebe4f60 53 c857 8f 502d54207b8ea08df313f6283365aa5bd34280c 22f1a1502f791c 78e71458f0ecc79 3bc39  7ba4 39b 4e1957 513ab147594e024f748c0c137 f340dbda4d 7084 99ec2c3dba05 4b97676e36c314d1f778 4c73 7d4c987e4972f7 4bc1586b29 b593e7b3ecc9f38d67d28022c0c67c8598c5 5cb235bfe4fb0e62fd050 919659190b1b d395239638a23eec8199874968c3b0704a09d064 24781389b1d12d5659c926d0248869e0d416d790c283 7993e099ce2955eb 7d9a476d661 ccf7a3d903cc 6 392f 8261f7d75f3ba9f9cea7dacf37528d5f60365 d58f2092e3cb a5e745c570ff38 75947eadac 15245eb7  3975742384cde84acc182f 3d9 a9970a2e5a e048a52063a67f327cca1 c4c2ebf62746b89da219 3943fb6 979a656e15527c128cb19e51af7f5ff06c091610eaa6cc6187078d5017efad5ec6 59a08fa30ea9fbd409a061da15347f 6358cbcf8c0e02b8b1e4378a4288d 765057165f2a0e6f0627b77 fb4021b51eb23affc7c94fa0 5078cbde91e5127255290 69b665 248bad0c3b 4b213c5f5c10b 347b2e344d52f06f1 86ab89a6955fa064637608dc300d 497  ef785 350bfe0b36610a7ad0888ea71f008596e63beae23e65ac1a4 fff3fe2740b78bfe291acd3e5d05543bb8f8a224ded58c966a839e8a03fb6c476eaca0666f82160aa 8313f07f4b3a0de19a6df0b47230 89617b8d 80 da0f551db 8aac18ee2a7ad60b0569bc340feda0253e7100831b9404849d046b6b42b1 7eaa 7e700889437c159f0e1 d a59429a53d 1 5109cb1c52e42b1e78d0ba5a97dc2 d5 69b9f1ee9926 21227d8d3 b909ce21c 9a65b1b9 9a2cc46e 72091dec385ea6e80d7f1127a20eaf6110fbf5a06b085ac06f8c8155a6244c8ef6c54cff86b 5108ec1214cf6 5011e 17a0e980af 9458b 34c16c935cd0c e8034a2b0a846697f812c a9 7d83edd cf49d5ca 9 53 57 924b75ce2b8abfd7335f5610c0ab242d9cf12 ed2d0bf88 e3f0554b00e9c3dbeba24b2a6cac033e89b990 6ff06 942ef229f f59c8d5b51e8a181a939d8 321730 7a013c f9f e21c686ab2e82 3 bfb20dbe8 d087eec 6eafd fa3547 05487acbd7aef 6d3107c42bd 28c779ec36dac 231ef5b a3976 4bf 99 a22657a3d4adcc8 3c68c900be0b 0 dde 81ae141311ade4530abdd024fd8 cbfcd3df52 8c74d30 7ea abc72 017adf8c2643c765db30 85dd799f7a241 b7839ece4861 17093c6b735a95fe4cd43 8f6ec4c13667545bc391d2410f2 15e8ed52f62f5 f78e7c12d962130749f885d  1c1c2e4523fec29910c523b8b7 5a9c19040cb3a4094847af399f86d293468f41faa8d70420af51974ccacf1300a3983b b51c fb 43b6b78ae04f89efce7ca4f0c0ed7f0df756 dc065a86545 2be700787c4c94584d22a7851a9 3a8 4aeaa4 4203bfed4aef2a77e9a4c f36cd7ab8d5648b55f952250b0d1e127a7bbd08a0 998100dd5b3fcdb766a2aa44fe f5e 1fe8409ea79634ceafced0147c  5dd81  c2b fcaf89d05318e  bcaf8c 184d63009f6e26a9773dd21fbebac4759cf6d367db343896ed088dd81903f767c31 4303c34bc7368d76234fc285  2685eeea14307216eaf8e8723d4f49745649f561cc1834c 23 1e115d3ce9a 4d1328f12e 3d9 3aad8d2ef1b98 de665bc157bd14a 07e71725b 5d034427330 6fdf03955a25aa3e bb 3a8171a751b9acac655b38c7 beb5cabc5e4fe5b2105bcb22 05961b430baa7708 e0e648 1ee47ccf 453527604 4cdea53c2d15e4a1d cbcdaa9b684cce2b40fc8d d255291e7d4ec8f77f0 2b 6220aa8f3cf a7 a0e766047 c97c1cd492f211a2d7 ede1d6bbdadc29 c2006020c4a0 3cc5 e515e265aea2b2f8bc09031d359488dafb820d9c3fc39985aff46fb5df3 1d 49e40b638f4da1aeaef0e2375 5f 59429977c4cf920d17c8651a 3127a d93bf31db9d372251ac94387aa7a732132edc65 5e1 da56a0288d3db1f2728451bafe76085581116d552c49d9c3ce 486 b93a0ca343433d0a fe761b0c74ad7f66a  d3047b671ec1e834ce72d1 62146ab0d1868ba37d43e71685a7f0 f8b459250810f3e06b4229da52a092b2d  c02d37818b3213685200674f653046869d52745ae40b76fc4d726ba050f  bb9098a 8809e2ac3575f2 699df830f92d9e09c985d8575e 25efeb63cbd3a87 22b66640f2e07d376bff4838a18014d8a 2548d354b 07211 141fe3cc9 3daaa19ba5062 d6 e0 cfb2ba6fd29729 4dc68e58d2112499fa96 5fdc41d316 f f6f95784dc6bc9f1dc1b76d4199738a404de9 f9368efe8ddd7be 0f4562db3637a8bcd  16303aa0f3ddc3605a2db58b65cc68 443c ba4 312acc25c5ed5397016f8cd904 bb 46f4 79240969c 442fd0865ba4d7ad319c6e1dde11fbe5d7 b 2cf6c053a03b3f2a2db6 94f2e00ac b1f09646496945066d0f7d 225a1f14fd803ca58ec78 930c4dfa9 9 faa63369087a58d93fd5 736eb8ecd649d5b0c3903fb63c02973b3996a75a5 0 925cf7941e d9d8ab8f095 9717a 45d0f668dac1db0cfefd0660500e0dcce353e2 322b792 e84 a8837415901 9 e3fa8e00c926cfd9 cecbb1ed030947161aeda81075 3676a b59f17ace7b37c7a995255 2fe6116ffd006d398090de56cb5cbc775e0534ad42c7012807a086c1e 1d3760e634c33978627 2d4aad3b6b474 e009 5a8e8e7469c9033800f7e a95181fa9ff95071414a4087 7d34b016ef02d7ce b486b694ff2302b45e4c5a0 eb4b5 713f0633337c5f4e0a 3e3b8677e08aa7c3b4c0555 12f119e 0bd84dce160abbc678eb b1d837 0bf630001831 644ca6c79417756 97839  52862e59ff647dc8a00a e c0be7fb15f0 83c9 960b0d427f477c80c  842f 47e2  b38b4093ab08 ee774def173e44e6393c11dc2 250aa03bda8e356bce627b721caf5c44d1c81e6cbc57a433f60408a8edce7de648c 3ddc53f0a2e6 3fa df6e1ec1a3dad0151af5cfd  7745a24b1f161767370d691  25d0319f3 5c8579f 1fdd3f201091b50c0c7b30ac a2c9cf5b44aae82e0326cdb3e9b2a4d1a1e1ea9e3225e57eeccb288c754e7fa27b015e ad 4488e26a9abd73 bf f5f1a18085eecc79 57fb835a7d1 5 76c9b85f563e6208ae58c8d0591ab23dbca732e3204777c80f55  fc307fbb1e8e8d37eb3c7e33e07a1 5120326f 9a10a 28a9e0f4c07482 fa 664a5d262c 4fa35a29f6d8e06  7efd2bcfe0 6a2be51658a3139ed05669685902fc63e1c35ea51cf43c4a5305e5a3227310945b37b4594c84732eb0b635b82bfb5c4 6c0d808b16b7dbb0af65ba28c0 7dae26971a0138786730dd2b3016321e5bc4a2ed2bea6cf04b4ba22b1d0e09d73bbad0bf2a4fef0534ae08147 77c6e0d23f0f3b3f 368327f2f6 85cc00afd7ac7a3668 bd856d1fc6 41624 71dfaf611d132784900bec78987fb483538be028c595ba4a694d16d902 7f483ebe6 d75db1473 6e6 69 44 5b3526f 3f2 cfa c2db6e7dcf1aed3b 79e17de59dee29 586070af70c1525 96d2723711ace426acd1a9 189db56116cc9ec1e566 4bb2715dd9361ca1cb960499270cdda3065aa2cb6e472c7 74db13fc1928b976a0be46a0d84e704 08f5745 c9746e8e2100aa7cd4 48d18a03058a93e7a a4452 4a34ddc94431d7fe16f24f8e 04e0920f359449074a81328362f187e83486dfe 97586096649258beecfec21fae2f23 49dc2 7ba42da6a341160b5c93 bf3b8fda1 b31657d91e4 dc8030fcb27a58ac8 156345cecb0fb69006d76 34d4e f61292d6eb64a7441e9687188f2411ee63636f58323 088  1eb0eef 9f73907cd5e76aa165601cfacba1013cb09d0722d10da89ce9249 b4abee40e2e f0eaf2016549dde3 8dad051b479e 702f39e9  e33dbba2a7b867b5 1d e32d484ff8f9d14bd66069ac84d9df370701ba0b9490e2d1 1ecb4f85761 7a9 04907 08a40684b637b47cc8 abbb05ee28abcea316cacd bdc8a 0f5b 65c153dd3be67e7b134e6fe95  563cd9e438 5ac5ad23f316f6a54eb9ed91 9aa0401 610969f a30f38fe07a007e55409bdb a452d01d0c  1b223189df3dfbcddb9fac0d6e069  90025e51d538c9c60c166768fbfee501258c0e9e7b9962789eca2ddac9c 15 71e42d83f7334a5534baee59 7 20c28f f e183a0e36fbe 145afebe8e35db1abca56a8f9b ed8d56e88142064fe156a24f 657c9207ab6deb5f4cafc14c5677371a64a762f5e34b049f 4681b8897 d5f33c0006133da9ae02c89c48 947e93ede3  63ca bc976733415d427a3eba77590 ea9c53c4f688 a258d1ed7d2c7ebd5 259e989 db19 687af6c4fdd 358 51009d3547f0b 7ea94b920 4969db88f1 31 bfcdcb662a8563488da6b c4bb6d300b2d34ae9dd2ac 990a0bb2db783c465b85451507be17b48cd6364f e6b9c40842324ff638cc776d2372ad1 7e12450c0c55 359f597d3c4ee63 97dfe6b8 8bad56 92cd57708e1faf1f0dab64c 34f267696d37e80361a2223a9e 3dfb3caf165ee4285e78114c7aefbb8fd33a988bc701d98050 2e9184d6d12573c739e1258cb1ab30c0e7ef0665f4c411a826562c74f a257109094aba0ef6bc58dc083f c02a13e087bd153c6d6379a9768c9 a419d4 3 2f2d68e8d9b94a8f5ca295d23d6 7c 4188afda3e6d5882 b4d6212c129630436c508bc1bb20601efade4fb accd79c28716c 7cc152593f4b6 e62a67a2 bf4fb1ed5546af25caa7900c755b5b26b908f9e9a e7794ec9cb6183472046 6dd05e 2 2 fa5c2c283cb7d0f3df942686dc97 e  52ba6b3bfc7fb2 cb1958eadf7da8c98 8f6fdcd8f929596d03b11eeebfa8d9e7b0cf1 a863 1 c7353888deab78e 3e85f60075a3188fc654838be4791e 9 62c3430d915ad994974cad30c1bdc69 97 ea 47d 6f d042baf  4504355073be02d 5147b b6cc92ef8d16dff965c127e61e96c2b08a  a e10 3931 1cb7f1bfb5691896649fb01713baf92510ae458b 11f234dd24c91c692a820896a1a6ee884388bb78ce1fc57cad4c93d057 eb3ee27c 4a7ea37e4c8c2f44011d da8301c867011d7946b0  d3725dbdcb187d3 bee905 25bf2c40a4b993cf65d2d963 ef250 7 153 24b2af723d8ebd7a661 d6c4243eab09105624e2f1c01b5d526486189a6efb94b3ca8a 4a3cd042a7e0ab6fd66 568bce44bc319c3c20866f1d e 4c1511c324e71c53dbcde6 ed2b 00f 2bf254e 25775a27855b9 aecdcd4e8e1ce248e488 9cf7a9127e018c473065d0b46ba2bf9ba43f0402a 3f08b0091ab3ea732c441f276006f5dcf956 3f491afbdf5130 34 86b 8 26a681d2477cccf58 b017af7a7e3d b 16c2615270685bcbe1416a9160 bbb8e7a7886fc5d6e0732f410a4e4390e186 a4771a85839ff098ffaf973eb19b58dc52193 ffb16 e2ba3 dfa28 fa0987 e 1ca0  177 9997653c223570ed9b15ad1 14e016e2bbef 11daf36b819ca87d125c895674de86136515471ccd2fdcd81 9a4ef616367540fcadecdb7362fb6b8798f849 49 8a42cf90c e7437794b70ea62b 7cad9854c44b9c5 8725711316c1746036f444aeb1a2 666c927948 10  de2e9e9cdd 72 8dc0b0744bccf2ef efe67e904000354756fe804c64fd84f e3f6e9654f 03c8748e283a6c573cb fc272c7ce4787f5dd09d35285c9e9dd 1417a357f14a 2a40fe08b2133331c b83d589090e4e5ab3d3 415fbe57a7a5 9b9a2c6769335 cb0f4a33c5deb825a9d5317b63 5f572 18b911c2181fee 31564129abad689988a f8078ead89 a2be83d4b835f  6676e301034fcdda1311  0eff633055e928c9a5415a86f4 9c20199 fd6c403a46c93 1906e43ec713fac1bb7fc7c2962fa 7ddde5ab8bb5fab a2bb98 fddd99f7da416b6c4ae8ef655de4f 1228591133e55d341495b3 c 1e7a015 e9 456f97a8ac6e54cf8e675e44ad1fbc7308437c06a5b d71 cad9a334 ee0 9e7c93411445b8d9b7feb26f335800ddfa731a7744f987635660b7ffed9 2e106412f7777d8569c788 13451a7c87afaa7dd6a047fb86981db5ad ef97b6ccb5 987e 8b83b7 32c5977dfae031709efb48b101dfec0ab2b30d 1cf4d05c08a13 39d2 1c95b8823 5826fe7fac79 49f521010f2 c4a0e5eeccdea352f3bc62 3fdcbfb9 502d1db841a2d9f54bb5bb3eb6ec93f7b51c f2a7a7076987 8130560dc0831b87731ad95831a299f653ff7352 960fc8cc18b10cedc8f39a2d5a5d 09e949d66eb2  8072e09f52633102f8fb47 80e5d76e c30c 67497c1a9 b1698eef6ae6adbab9271993cdf9d2668e67928e95b7a459 19b5b71727ee117dad967 5 70f3e2c3 a93873d74cbe2ed9f3002aa37 9b438f65e2 8fe59b6d27c0fbd54f90 5 aecbc7fb876ffa1ed4b9f079f4b7de55cfaf15a38b608a8 26d44c2153fef7c3a16 d8fd8ee d2d15c7df72aa1e5150dc6733118411e efef01c8100f5224beaec2a28821ace03617b3ef50c622cbdd4e8a 0bf8c6fd8d1 7dfbbaeaf1446179a79e4317ed1b785c0645f7c2d0f6afef 7dda cab8bd3550947f65 771 f7b207f6556635df5b934e7ebccc6e2b93a6cffe12f b7126aac846d18eed8c493a97380f5fcc6362571135 e444a5a39e18a 301d9216498ccf02c632fe93f47a653bf94d4ed865bd3d477eb02fb4413089195166c32be a47e1 1fc9c401634547bfc4e1b043e49698873d50 ebb6002fdfaeba49a06dd207d79167b85 0412e7b2bc41537ace9a1d5de7f782de04f9f4 a41401 e79bc7114f2 f3 95d9a5329609f128900a3bc34 60e7dab0b58017b332d5787760ed33 800432735062333 6e31dffab4eac0812d739ec5ae922b5b5e dc12d5b4e82126b4 6f6bb80ce83981953d 210340afd681868fefd9c122be1966828b4aa54c7d5c ecb02b27f43dc9095db 51d33d7bba47 feb68050f3 b52c819f107 ab62e335372d4ec5dddbc6e5 86147 41b0 e6305e3ac50544 b36a93255a9efa 19d6fc47fc97c1eb7 41fafa88ec4d6a cc8 ce85c63 fe2282 e949ab84509a193a2b04f94dbb6966c36555f2f316ef40eae8230a3 9 2fca1de2778bb2d4 abc12 c31c0c6316f1f22742a 866f e2d00abbed566990c8347c614c2ab85 c925 3 078020ea79e  b08202a0a92a4 5ec3c5211f42 7f2bd8e84c34 eff6ef5c135e78b1c69bd22 bee68ae685016cb 781207f186f143b8 e397b71bda76987b4131eea991eb617225ace5355c 2ee3 8ba22bd75154c787a4ce0f52471878 59 e7 00253563a4ba2bf5b d9864c325144e6d ee7128b8f549b7a032825dd7ae559f64ad4b 08e4de845880919d852790dbf3bbb019b7aa3bc25d9ca1285902b41d4adc 5ad31 d108cee2eefd3f9e123b3 9a5194f2dfc1ed69852adeed4d115facd1 f23dc928655dd7d 52a6 94 d720f956ec84870 ba51deb2 8579 ac96e63816930b80e1f849514fe748a0 46af 3bac bd6bdfd9 aa736c0e44b3002b8b7e479cc3f338 3dba5  633e59 7b54d801a087a3ed11dde7b7d7267c84d121ac5ec dee be9616d0 0406ea3e7c9dba9f0980ad70b5c786f 3e5944454465140202ccc973de4c99bab2316ec313b6fdd1620b39e1291f95291ceedd0 8b380 7469e0c653148ae68fb522fa5726cb f7149cc978ae2e159bb5f4389e d8 aad7abafb372ccf2ba031153201e134a91476 9662df2 3bebc623db8b1 2c45f536efd050267bb03a6335  98663 1a8cc bdd a94b 63 1551 3e8b9aae4ff609a91f7f39b3e4f60b e65988dcc03db e6619812d7a5 6198454f64947 c56b555b66 21186b42b0f13b2c6 0f5d5f9ad53081f31d53a8d69 f7084b2bd877ba 0eaadb639c41da892a2 2 5ba71 6aa 618e344 c95d8e 3f127f24b 979663af13696a4f0642d  bf9bca32a e 4f464ee503587f429d879d4 c904060 5001da9a06d84aea134f219168685 4395dd702c59ce6b 1 29 54d4eed67e638072e ac64bbb7c765137beecf6b24e400490dd108 0b27873d59484bf64bfc 5433a b5d42aef5e429 51 071303 f89c 7690ccbe66a0028ab98b7f5b3e28 1 6f8505ad945c2 1339988e2b96b5f8adf6f842c8491b3f18eb6e4c 0b227286cad59e265942ac3a0521409e0eef 8cbe02231195f800d3eb61d 4b988b32 92e5fc 23f3f54cb7b7a24cc2acad636 9434043 43252 3fb2e854415cd4c246a1192098e1f73f8991e6ee054295bede59 b11 b f92b 3a8de0074157dc474a3710d4b2ee0dc301e1c816524 16aaf66ab47af7e86cb386d588dad7933e42 7 8566a80eb3df31 6e637e436c61d5d7c5be8b3225409d3d19bd6607b15f58000b70e19019 ca07e4c273175d1 fd0cdf1f1 86893390bdb4c48d0e1dc 286b16 54267902710681de0e50907ec33fb85ac8f785e6 c15b56ed b6 d47727c6f86389 f3cd8f7028364f948f6 a8fd 9fe 9a5c47c294125325d895abbf74 89e9685ebb51bad4530175e6bc6c2e71cb21c43834 69017ba1205894 ec958b04ea6a0 8eb54a17b1 8fa21d38ba3a896e6b428192 1e3a7e 790ce7d 2f 86cf159455 7c9c6981825d475aa 24298a47526b73f664757748df61dfa47 d41625ccd11422047f0 3aaf10245464444ea8123 265a808bfb66dfe7f02d904 46f3 9423d38056d44905fc0f6 5d5c28877f3dca9e88a8f22415598414029d1c6e2624 e87a6ebb6890419686ff4 669d dd2d8944 cb f6a1a39150fcbf41318e49767087b2467d1564375d7a9dba483ec7d1031 a7ff242 c28c6317 92cec0b7f8ac9523af07fbdf9a030 c434e48f023cfc8b5fc26 5e3f3 67366f3a8f05e8 06c9eeebe0a488045d97577e41d6062e6e9d38a653f3c5d12799 4 9da0f6ac872519cf5cf 08a899dfa65eb7a4eed1fb2569ff37cdce991180b403c7ee947aa834826579577f93d912b3d9a9bfec70daade e5ae216207145f50 77b9d92f705b2ae57120df6376cb2ece86de83b65 22270a4a6dc45b3d0b957 72a747f0ac7fe67d7 5f8734d08bcd7 e0e6ea45a01c9c19490a10 58d9b4 2609416dd8a4 794b7602 239f50ac06841c52 ba78d 8dc77710b4ec2ba56471f74802f9888b 5b53 92d2 69bb7a 5e9001b5fdffdee2ff87b1a75163aad9bc478b2f6eb59 2 1434a8133 9 9d1713258c78d8d c68fb51f69 a921b92a84941ee4f57 e5e06 d6903490a67d2f25f6f54748593e4a98cb2f1858f0c212 db6453d 24b7 2930e8c5369b1bd612c5888 7ef98c08b70c781068432cd43642f5428905b407c9d72 776fd9 955a8560de741698 e 1cb5e393b95df   0433d289b5   ce406e31388c749bedc5 d478cc cb29256cf220de3200db721e06b501796f36491a05aba978f19f5ca27 94e900112726 3560d744edf4ced7690b3c122d e5c68f42be93bebb71e2 dc5a1b75c14406392918c1d5c69a7 6af5b80f2db0a28b4205f2dbb15b04b952702d4978 be4a6977aa5215864b51a2595983b08f85238926c7af6 39b701849bfbc472f90fb3ec 4b614 a77460 1c 511d50ebfc08575ede4 b60aa50fb0 ffa9c96792b7 fad7fd6725edca45c7 6ec5df6e 8 f24a105617db73cb65f c4b08516f856435a9 773e2f3fc9281cfb1f9af41ea61f 02c52 85bf52297e5f226ff13d1f8b96d8e72 2e9edf8f1e1a1e9a9343bd0 b5 f4abbd0c71cc73f1785a  a3604c3649a98a635c01 a71ed12a1d9720b19f904e86c82a10ecba5d0c2bfc15bb9ddcd  e17005799def56b9768570ff4a7403d3 0ca74fb2422cb20c7d4d16957510835cf1 3bd4dbe9305dbd37f3 8e7941637f4 1ee1befcdd6 ff79 f9df9ec52ca9c2b938003c76fbc0914ba666509f0af95f29b3d29d0 fc636fe47b533829 d75fccaaa7d994a54f 493d018f58761f56170bf6c3fd3  2604 efecefb c6006761c 4997860e372103e897a803a880ec761a1fe58 263f21094a6cb95cdeb0119bff02d487d34e91fc6c2ff54 33f9 d1 a9115c69 6d4acf5334afa39 5ba8cd9ea768b5e351c8b05613d671a9fd7e1 6d661692768ec86419b01 83956f185d2a5add922e dcbdb33ba919017b813531 1569412a 599 a 30ce5735b92b06419a521990374b705cd365e4 a9db2742225f88e e3e809ab3d fd39b 5dffefb0  ddbd1854531cf3 06b0e42fd0 35635 7 335f71752 6639a3991ca576d791f0df39d692e2529448 078d716fcb08914153bc4ec01b78be c089975d9e2  e7e40 17e c 9222c0dc009f630625a6efb302ba9124d18bb2a6d854a84dd a9 69f2df3c8672cd16705b32a8fe0d5146c e 658d25c4e5cb5afb 3ed8056ed99550193e5d0bd0bfe7e 4bc47356e49b f8170351f1f5957e387fa5d7f33af0cebabe365134a020059d99abbff4 55f75b42f2d08 91ad4742ead9aa03a940c1afad7 e 0ab4 cdd55ff2ec2 81d0cc  13 f074859f7 e8e9a1e5142 3 cf767c5d3c82d58d52e9c7 3db96a5 13 08a43c1220e92 4d06458ee90332 33641c863 30a55c23264a41833dad3e5d55d2c5fe0 81103dccd8f5e70ad 96255f8ef39d767 9c567 344 e17f7 8106d5 3 7997825711c b2e09f04e 833c0 84bad fc 0def6b2d8d71d279 555 d2 40a8bab25fdcea8583451148a95 8b451f4f5143b6238d5ed82a4bb276fa2c204eb42c5e6e706ab463880da35d648 0606784ca2828176302953a3ee7d84ecba eada6c061f103b1ec2e4b1a66c18dd74aaca68f4f14008f4e9afc27e6496463753b9d9118ef516de0c05f6e600923d32dd75526654982 ce c02f4b44822a09e0538d33cb09a08522d789f7 7 3f34049b31fd4950 724369aa79922 50a065  556ef729b27ad534e83bcf3d41 26 62bc3b0d3e8691551f02  e4d819534e9c7d80915b5981 0 29512fa3d6f68 db65dd75 a ae8558c506c2249 912664e01ede97680a47b29e 58ae80df d   b5d4330e3afc783b98d9917266c8 f8f d30006adcfccb 919936ff97106a4c884776a5829bcdb710b6f262 8598b61a02bbe776a292cc04cbcb487977946f2f2dc46 b07f7dd2e69e 9b9a8181ba22771104e656cccd69964e72841cc fae22e035636867c 0dc000 b8a822d40e73aa23c2079b426ef3d080fd0adea8c f322ef48940 6924f0 41ebe33ffd798 3c19bc8dfa7143dfe5c8b eab16d90125ac818c6d3f79f4fb219d30993bfc 66956262b4 ce42d54ced759bcad2 9 d53c922bf45429485eccdcd 80bfea56c90304eaabf1462ab2ab1bcabec6a6519b9c 3b7f50c  362a80e65b1fb2b797166c 541069 da6d0889b47c7e2 9bef9ee569881a51743f 5d5 cd2e 2e2b11 4e0382635777427e654060ef5646e  6b75bd446568326b983a14a837da206873 7cd25e76ed36a 453e 5d7d7b814 498a2ad26d5648fea1f1cbdc2d 05f8be111c4d72985cd896a c5a19cefa2b625b4cbd909d228ffe4dca7 e39a2688a5 c91ed7b67e71a70f8a3ddbef3f7dc86124d4f17ca5b032e8d49b0  a69f7482486d1a04b3cd5616e528cb717586f720c76dde1635c79dbfc10ab04f99d9 d675ff649de715d147e6c6cd0d12c3dc1e7394456df6cf2cb2 5b2fc7110b2 8fde7bb94d1f3 b63018c3a5cc86e922afe10107cb8adc9ebf6d1489b2af12 7e95fc 48c5b6a208cfe3fc9995377110350a0ad d2a5f6ad2 c3da66 1a139e5c00a5978eb4bf4adff9 28dd3dd1fbb21630f2f97c4f08c408d7a730567 0c2  928e975fae61db1 bafa3a0b3c7df0e9baf07674e3a847dda56bd6567e3e6e3f884 2dbc3f988db 45a3462a69 6d6356cceb79af6364281e77044326aa11540 2ef067a964a283a23b8 5164b116ec7f5c55e 9f70c  511bf2fbe7 aa2dafb93ecc8ceb5307d4453631b3e809a35106ff1b8f30c4c63c604cd35 69137288a53450cf38bc9d8dc09ba24f5da50e43cbbf  f80caea0585949513bc37a29dbf98d859a  05a bfbec4ccef1c3320d37aed 3cc6c5725c b8a0ff c 63ad17bfd6 7de13349c 4377 544 9aa9dfb52b0e8b6e733 82ce24 6 395fa5e6518cdbbb913c4f1d0e853043cc0 65d  46426f6b912a60a 089b8dd88a bbf00 caca8acb95a57de7adc1761b0 a 5eb2e3bc94e12b7158d85c01c9da54778c1  72fbb7 d2fb35c968b0 f731c1735b766672b71f6088dd3d ad470f1e7551f 664ecb 7d137ec6 57e592bc6626bbb4eb625009 e54c7b8040a0 f8f029eba5148394 46c8260c00c11e89e0a6b86646a3c6b2034e07668 fe251b11f8e42ace7fe44802c1f 4639a914344bc774827bdc8e050a08856b59d28668c0d359d53d32 5b674c89cb01090e 63a00a91ea555299271985 e a0c4fc982c14ed40fb306930c52f 31ab94500ab2c6fd2a f 0cd6cf45 fe2fd3dee0532bf8df74073d4aea27e3dabbad697 da8cc84d 486  48c2c272c157 4c05e7c14994b13b8 6b3c73 8c76b3 b38722484fbc49c3ee9af4 348f9f9807bb0ebd8efb1c2 825d71dddc26 4acd66b0012d084c3416a033cb74fb65 2 d51c 1218  2b7e5a0010 d29e78f83de84347bf7  e42aa0290133155d 38b 23a3b7  9b c02c3ec83dca8f311dbba 758a4d2945 1cf 7524c410 7a6cd b269c7810c88cb42e62887 f80ac 8c faa49d906dd f9 1cf35309a46b0a1f8d5ed70c  fed54d ef1f5058  c62 76df416d0dc77f1684e7c71be e258130a 67c0b dbbdd94d2e63bcf949   3db937a04faa1d 7472c6c2cee1c08 8f0cb 617690ca6dc4a2 edab167f934570a84b84958a5610eaebacc9b9a 6f4 a39d1bf53c 626fa27a93df4 1a16553151869470a8b306aa788a0adb56ed69 b767284 04d9f71a6a5f90f6309bce905469 e84b1872757081a5f71575ed3c241da485f77c6b 6f25618161915 5cd0117049e 85f4df 26a47eca90b0806229164 34e3bcb1d 9e8e099f70d1848 4 b66498e63a13122201d b3465c1 bc268f83d09f700ca d991fa342ac4600cc1abd 4ea dcba3260f e75621 2b49571a ce0a17afe04d 1 83e11091c04dae5a53643eff8b545afc157a7f7798c2936864 d5c99e054b76b0ccf4f23ee1363f4685df9 f867d0b9 402528b2 468c69b70ae a93e7064e  5193ef1047cbcbe5c 81 c9  c7 b538e8 9f10 5e408af4ee328ee8bccd2ba02dc85fcea9bb164624c 8e4a060ec5d387e227d68b7f3ccb8403d1c12 48 d85b24a36a7b4a0 49c4 be 7ce356e439b920e87d6e1f58 0c2e5281499a15d5a54706656d01ae54f03264f17e58a9f01186cf8bf4ae23196f0890fe3eccd3d a3 c34cd 33cc6ba3c3 5 8beb992f792a5a588e935087256c5168cb3b69d1dd18ef0d3c9986fbc1  4aa0a35e8eff3f8 28db6f51564913b9753398b93982caf6a1edc0afbc97623758f4d6cfdded8dc39 b 177668226573243af9 7dab4757efc9c3670318622 921130f5c 0cb8905430e3aacbd56 a3127468 7fbe24b91f587186f250cd7cdc2d8a9556fc42ac3bf8c0d6091d8 80c7dd1a 5 d715e71b 439387712 4f9c9dca0953f6a1471cba096357 b 84f65ae8e708e285dcdf3223bd 75304c9a99425a 8607109f3025b59af5b83 7f3c e2699ab223da43530bb1d6f1 5 f3e1476f05fb229e62a870e12ca824560d5f8f78f57d753921d1db48ad 1b  cb3c1c145c8101 db48815375a8c1661165c2982ae 3a7e883ed080b6 c5d8b8511f7fa d4380460e2ecf295af20b70056d8fdd 562acf7925a017ce295fcb6181afd935c2e4a99989d3ba430914617acb5b369258 baf0751a7617e323ccfa1f7ff1  82a408d8265529161e94be127c5a87094190a8826ae30a1920988e2f079442ec 46166e2 aaf1ede9b2d96ec2 19de83fd8a0d86a11e8d 8720a79ea4672b0f91eb0 0af55f43e82e6ef25c2ae8c45bc09e00b38e2417ddf6e2f3850dcc7f22377735960f56c 63474c  a fd88961e7c26df724e666cff84b5c 191add31486c591e331c f6be8513e940f288f64 80aefab2dc4ce95a5e150c71997ba2b42e6 9 40ae5d73 da970a3e3e66e 09a319050d11e337f6 c2402b4d97c80f0 6 71fe6403d11d788228a9decacc44a 39a75294 dd53395 2d0e 4e3b e52ce7e3e76f7a fb72 1650447bec3c1b 89f6c12c690de0f62c11ed71f947ce 59fa6429c2d0b6fba96a 4360897cf8be437733 acbbd2af470107  492617d 6032433f1e50a03 c899bc8e618a6bf5ad8 d53a0329c618 ad88a0a996f37e9cbbd6a994c3307b17a9988817def30a5d9ff5e5e 2 dcfa242d77e37b aa72b 4a2458ff83c414e7 7060915a2c2231 8 4492ebd272a94400e51f1f88a2 a58aea0c3d5f3d11cc4 f2f9d43b65d403027c0c19644645e941e131cbb5fcdf3e 6f446479 d0af3d2d3923fde45a257 bc7278eaa529071e 2fb82d1ff7958846e93e375261bf4b535e  a1194f21f73ca277ba8a ea67ac9c073d44485fe4ebcd47b5789a925085a9ade145fbc06a53c80ed143b5fb7 8239ee2d 316409bbdde83  57478724403acd3 a338bbfcc270ffc11f9c 1f63a75 a1c388667eadae8f3d8f78a8a17186ab8bda9 c02d16568d90e523813dce899 175 b463285ef3449085bd89b3aae0e62d90160141d 30e1c afe5dde8ce6554e60 7e263ccfb994bd3fe994892a793a ab711533e2601d3 d263a519f16febee7d0a0 20ca69797d901703e f 323704d555e3e8aaa dc743d3355fb1e3 01e41a044 1b85697c32fa1961fcc80a56196369b8b777b51e7d 987630bac8251dcdb2d9597e648d 3a335022f5657d25185357aebe2b5786a1d30172c ac6bb381d70c754ae99ee0c38ba687597d e108898ae78a31ad5d9079bb03abb714a2ec9b0c5f5627e96559 d582 5bc6826b3206310ce5a08ca3dbd b62 2caf1222  1b5 ef32883578fe677ad95bdbe6e3ab7767c 5eed4dc1 6bc18e560458011e3da26 e40dbf0 256a19360b8788a663a4d5b68e873ad87b8661b4f55e821e250cc17289 b4087b50cd7a058e2937731 8b 800d b a7423976de997b3f9dc3b140397ecf5e5dfc2 7 6f9a  79a74962eb6b59fa5b944b6ea80e35  b4ae7396  3d f44fd5a37929e5 84c62e4c40b88eee9da f e 65626279d1a5e5e59da 0f289c1d6a20 bef83f6d6 d586e9397540033ed8e792  d733f79ad7e34 f084a c54 3 0cd819 bd2a1a44a fd9d8e21aeddb0b979f70e9f40f7be067144b38e3b29303458500b173d36affd78b6e4ecb6848c00bd10b502a68d098a 13571 6859cd04d339d94 04cae5b5f2be1a4bb453f8a2d5fc6b57f 7dd79f6dfe2ab1d53b1e81 91e84fff8d8347db9b394e3fd0aba2860737004c1e2dcc05a4ae497b3e23469 ad6 52d1  4d2f99863  db2f24dc298e095fee9c90a5983c918 fe0fad2bd44c8b0215d72ec225eaf 7eefbe6021726128e 116b25391ed81cddc2e03c0e47c55b1a  b5d50b07979 3ea64b975ce49ba2d3ce4 921da5b830e8b b9c0e59c93ff e85885 def9854d7e 81cacd1f47f8aaed eb6e970306ce8166af876d4d225f90a373f2 9 6c73f3e5cfe9abd1ca16 e2b7a51b36bafd28 87e11fea cbe3 764170f661261f ba42eae0dad0a17695e e1997f20f1ea850d09e 8195 ceb3e5f7 53b6a3c17a 5b9cbc2afc65 02859e05b14 1 1 6e74662dfe d87  82c5c5262 d1bc16b8713383c ae3 a 2c07 fd79456 f81 c284d513e5ccc907e80 9ffb817 7f4a6621 67 65a95ef2c8415650169322b19d1483db5e  a9b8c034a32f85ad5bb3c2aa0237320b14e25b257280e9aab1 d122d31  9e825f10fdd0d426c3a5d60c3eaf20d69534532746 d26c70c8  d77f7fa0351 911d80e4135d453b382b75 a ccc3722d48c5fc2378d863fca7bf85d600ca3 8b4a 9e25331c1a54618c0923da0e04d4d00901832bad5f 2c5840a561c49ff7e0a de7f3da5d078f4c2fa84cc950f9d2da 3f695970ab36c54e00440f35  0b28f4b076354951 c828944 7371e03f343f8 a32e7f28 b245196a9230e5e092d 61b169c 005a 9c8 29fd93c9365a45844 a1338e722700942a3f3f8d64 affb8a17035800c591d4588ff12f91d3f3b79cdce19cb53d5dc4b92dc9996a9f1e3 040c0475a90a22 7c98cfc444bbd48e28c6b64bb9874 8b500b6ee 9c0f3b641aa483f86 b06  7ed081b5c 8a88335a b3e28f3c77ea6661a f27d 8ca 4d04fa1ace949b88f 60e9e062cb8 8e0564ddf89459087ddb f98eaaff 3 eac9f5ff6426c9dc303f6c4a 0f36349f1 afdebddb24a5c 2fe b53971bcc91ee8 ee2d7f85e3953de218b470473f7b8d80bc29 da0888bef7b7e5ce632104c449f5ee0dbfc dfb1f42b6f7f64dcede61bc2e15c6f23cac4bcf2edffc67832a1ba7206199021a 6fdbb1205d 54d0 2c4c4 3ec65a16bc936682aafc94725696e32a45962fbf39e04e93f90c5cb5152b7f74b60a64fe188bf064cc3b8861f402ba87 22812158b2cd9b1344a0b 85123744185 d3962c8adaa39c7e3b33 c9 db19097829b 6b8597afa2c283f5f1e381c1372cad394caa 91bc8dc3e25 7cb0e623253 059cb86238c3e7238ab72320262c 6efc601769c23822f2f64e0c19e5150a4b 75a4cad4b0428589d 7 c1e086fd530ecae0e21 a173d2ed3ddee3b 6471c6d754240c9ba697900e6eda7c4ed5fcbc1e04f87640b5045b685f54bf77b7221fa ca7b37a8cc8c6f3ba8 5b fe926f9db 6619d d8f8b019c7f7db920b 24d5a57c6a4e8cbd 0151cd204465a2ae008ba6 7682539de5ccb  c5d23848a1 3c6d228a7b1 44ca cdade13 b89 e379a54c71 301 963b6a19887aa142eb1746ff872ff396a316d76540e1c4c6ad0301b8fb0c18d97b07  b8b86d9772 a9fd4d7 a4be55c037b0b10a0bd03ac2f92c88070b482a49b200a7480b4f  4ed3299bc28 6 dc 07e023aff37d2cb47cd5d4c02fa5e2d1  9ac853bca17058a04504d013f4fb7524c7c66316f89f64f61a182623eb4763 cce11ffe0f5b78c5977c360719e e62a5f25 97398b4b62852 07f0 48b46b93f 132b9bf8b3e87c80935e140 7a1ba5e3da d91e8c6aed 8 c8d aa2f53a55bfbb 14fc30a9 afb4c9b50fe310c0401d8a84f59552cb 44dc6dc26021d1db56e8ae5d533cec 9570d b59dc ffe14  c49c0d 421df62fb966c9f23 015958dc6cefc2e469561a3a208425f5c70c00479 5304fce3b0df34c4ac3cf0678a405fa8601486ee51e3 612d78b44876 8a59549f622ae6ee60 cffccd8195bf98910061b51d45b0f5d 10a974db398d77338b77393 cdc563dea1444e523ca 71e8ad3c  76ba2074e31ecdb2d5a833980c666 1 834aa5aa39f35905b7bc06 a1dce1a3a094be5904cf91d755f140 ba26069fd23fa8c962f656c47feaf9b7dad458357d949b2e280d30 04ec6b851136 84df ae398d1db5 212a330177d49d36b8fa755bf edf ec3e75a518b0  b6fffaed f34af707155ba9c16e53c8ce7555f6cd75eb06bb 4bc6d64eb ef34a564 2d4155335a555e621b4c1beedebac89baf4a1126bbadfd654090a860b2b30c521ea9d9b ce7687d244bc4a6eb49b16a50c0f38f2d 6aa4bbaa8278495 81 91ff 6d e3e1ba8 a2aafd e2a 6 4eac4e6d bb7 9346 4118649177aac3f4a8b6b83a 5d f90 60601f6e792275c96d4a3917117a568285d713718 d421a8e 505d7d8b42ce15410a299c1b7975c474 2c28140102f5  1999dc72d284d1b79b452fae7dd bf8b37 5e8fc3b296a3bc1d0 8b a2 72df494 339c40e6dcaf06d5f6fb931689 cbff92161a71243f51 d8916 c173ad35d f cae25 dba e71f ef7f90da471672d3276cf8b30836f73e4c14 d11c19633c118354a2aa254c774610e404e411e3a8439b4b981a31ed0e57e5cc9df9b 8c557cf83e694060900b6d8f5 e 44003e2ff350e64533043d2d9bbf3997263d828fd1fce08afd1aed9408bd3607715f22a5e361fce5a2779fe8a 39fd 6343c86cca9ea9614f309ab6ddd3d0479fa16f3f4073d  5e8b5d2bfa729a 69a526 17bf2 0c180e5979feaf7b01418c1ef54e839d9cf8 4e057 00c96238557c 34593db eb02c24b5769 1edc7a9222eb7ded12050bd096444ba76843d3dd4015 e4e430cd5b9 fef3f85e70b4b85ad0 27db6ead327b1407490 8d2d58c49575f40c3cf dc9d 69 b7b483a8c2d28027782f68fb 96077c218b8bc b537 84bd 40c3737 75af57090dcf28897c445789a65c 32  c88 cc07dba5b03 7518fc40408269a6bd5da159aebdbdc41ce40f 91594db252b902c7191 74702890486a0c9d4a228a4d4bfaf3eeba1817fb 541c7a7e 52f688b05c63958a0075 01c753160ce5da4 30340936c50c6e3a3 c22484802f71b8854ab9dbab36b77151206660 90e7ccfa5a d34aefe3c3e3e5ceea6 4a4a687f3ee8e67 0b42843b0b40f8 327 257c2795 ff0e9 47 8a2ac5d 95ebbbc3a2e3c6f 9 6541da549435ea8f626 3e7c481796b9 76e507af34d7369a6d5 d093ddec2678ba1e4e42 f8c6e5950f5 d860886e5312947ddc7 5e11ab95 b01af730084e2bffaf5 472644fa0705a1e2f81633c0a0f2001f7cbd69d b1b1f5f89dd105 a 7c6d95de 3d139035ee75cc723 55575c5 53580d5deac0dd20484ab3 8aaedd9ded6db 7bc2d7217c af6a f6d5d3d a017edd78 85b9df55 e95d55 3dc872cdb8e9743553c879121d98408a507e3c8d2042954ad95fde f6b91ebe769cbbe63b849be138ed59730 e 32f7e924352926 43e3dd061a47aca0db8f771694e11aaea1c86d1f497a47b394e88f4d7f535e 879f2e6ed7325864a34448 bca118f4b0da97b5 90fd7d 752fa4ef537c96e99f677 087ce12bbf8245f17ae8 a8043019eaa544f621917da14f414cab0e8ed75112f5d377dc 77f56c697211e2263367bef5fa64afcb611cd53de6f5e4e7d95 d0d67a08a379fbfd4860811a31ed b48d7c081634cc7844cf68040aaea9ad537e337208c84affdb2830129d568d3774 e a45562a30b9fead398a992c cb41302b40ee151daf6a 7ceb5db1a83522170d49ba3d2bb200651cdd2d143a140b2 ef 05fa23a5dd7b5c  ba4dfdcf794877 63a0 e71 e7c2c241d24fe63 e19a  7adfc4952a12915cfe 7 72c1f604e6e90150c733c394035350b19c0039e 017c03d517dadba9a0536b627 1339b67c5a36a 4168a0f9da7ace226c7113a04d9675d473 7c761922276066713c7348010914 35f387bc993414ec3d5ea856afa71f5 5a1034 43ca9 78 7bd11970eefbf 9f4734dacb5ee245fa975f815034 b98c4 639db53d0fd8eb5 7231cf 3a776bf2ef094813 3836541094408ce7 aebae 75 1763b aef9a95780ec 9dec5dcdb908c4f9d452a7b  c94572250941e5c9b17284b5561408d647dd 6d9f6ff5610b470aee5e16b57a78948 3 5e10d 270bf4b07339ea51f58f59ca5224d2c 6aba80f90d6f904da 26cd3e006f48d5ab217c4d284036be4536fe1cc148e7ed e41c9ba7fb46ddafabda765 3f3dfc37e2  e e7b225c5c7ac5c7a66697f82a8d461432a1e632a1ede4c05d2a1 2aee9f8b a9e757 c87700 0b8cc6eeaffa df d893f82b23cd07aa13b5dbf 796f34d63198caa8c348fe28b67c973c51073a9484861ff9a2bc6e74fe1dc59b0e9 8 7030cfa2a40a04272741522cb0f58b7e2e7682081 764cc4b 65c7ce9ba8be045fce51eed257fd40d178 4bcba5fdb0c6ce5e043098441fd 3136024edc 32e9d 1d46e 59d150546cd92b6d7ce0df210beed 9890c25702cb 93069671d922fd04d b0fe15b632 69 412e 94c97025a26ee6222ed11c  26b fac741b2e6aaf87823744bcfa13 27b2e6 89  16742546eda87f18b77349 f507 9862ee271050857d8469b62ee13f2bd76e27b0cee 8c0cdf97528314 5de2f7c72c2475 20f56d4e859f7a348a e8864 7f26 6ee01 8971a21919881b828152acc66d4e656be822c06533aabfc44a113544f68fc5668517043b13cc69757c72f3d2a9ed3a2ef6ce7ddf1f3ddf8c457b9eaee16d2cfbb873f52ae36979f4f107f4 14a3860542ddf436d545d89976a525ba44be264 f34  865 95f0dea6be5af53cfa23fe2c45b04a90d44f81ab0707 3fe7401c66dc 05dd59c5724b3218fa64b409ba86cfa1e34d94e7bc516ef10a6888b5293ce4d5b407d6ff8ccf7fff72 e4b45e16 f520c4c  7 c9bbd6 2ac8b61c 99ef4a79ddb8 38555932417d6873e08bf096947aa52b8 e55692b6e0498c41f9 c94 bbc7b7649836d8e902 a1648dd6833e62 95afb80593ada8872 4898a2146742 7f1dc7e785f128bf607820a61c437160 6df28645 83a3809a7999e755f0e165d83f3bfac4 c319db4f3e979a3ce2 09963ded3a4ea6 31e 7668ae84b548209 eb 6e23aa23c6520365e120a 8aaf762 97eae6f2e1fef2e4342b  5a70643969042816d314284bc8 ed5fe362cac4bd32f101591a90d6dfed7fcb3f18652203f33122c6 82 f5b4f3 9ec2 0b64440be88c727afe2282a8d4e ae8f335 b64414838f1ad737861 ccefeeca8c2 a2c2470c20700351a733ad18e57583b85a0618639cfbc6 c3abc c1e016d0ead58d190e860ca857 6d1f08f36c06940 a09199ddf434c98219687b 68 2ddc8f3df92fe79010badd9a1f22f71cbce186bb758a13279efb443fea90941619bc89171 69be9e 75db 873ee 4aa09ac54d9bf7 6621c3574b9c8a1a0e5dbe174a682db4b80a27dc77fe9dbe3f9d4 90b89083485b4  41ba6c47eab 57 b37190 a313bfd01ce1426659157017832593c3f6fd3185 f5e85229197587f837412a24851 754f6c777eb9470c771f260c3a b012024e63 ef6189934eca07ba0bf1 51fb f7 d113449 1 4ee1be8ff49 0591300869a f 4d76d7a104fb68dd5054d5e81389ba46ad94 08 7b83bd18e89e309 ec7 ea2 d009da82c763f06d9e3281b933be2b6 cb88176cc753f81 6f4d0 231c f592336a61f50fb93df7973 349dd91332 bfe2aa345d3fabb3566bdee764d079220003d74b1b107093b0da 9f9ae ad0a15949b44a8 a2c22813a 6052 325942af6f 3eaef82b78 29cc9f530c84b9e6 2fed1 932b25c1f533f  358bfa83d878  1a422d79f3 8 52943 e32b756a5c75170f 780 16cb62ad01683d7616746ac1d314f6ef40a0c2aa41f 47a2a764de8c1f7800e5db3c  53 cd7f29d7b9c2de7  a00ea10b5bf848ce4ee1 c77ca 70929f505a5ad7e5a66012 ada70c7b3866b6eb48a0f457ba 9a29a1d90f96561553 ad45d05a02830ca433a52fff1 a 4e8f0e8053cf7d76378b8677b46386491c5bfd40d4a 248492f 81711b ea00 512ed277e4ac52db401e6b0ad6bf36d43a3779e02f1241 80e969c423 0d7f7d0c52859a01b22fa7 01f1108a5e73d37e2b7887070a5975c8df6af8287df7346fe989df97ec2a4f4dcc45927d4ff3f72e082d8ea51364dbe dce a7f94ae66ba417f9f4e1eeaab62a c63b352ff1e86c264559287492f493fd c125a0fa56647dacf7c6990d4af7bbd625eae916685eebc510c218de062ead3e3d 4 1803c9284a07b8d4dc73a2f597c43c258e 1800 3dd9405c 2f816c47650a113169503fb989833de 16641559866aca804d0b4ee2fe3eacc222c381b2a97007c9 b1 2b bd8 e a35 0 96fd9c9293ff9d 732bf50b74 c1abfd 83d72a1715334 e76a594b7e813a00cc7d23f48aa99b5e67af8 9c6c2d61339b34f5800b2d959f4bf27353bd f3 1d07 e633d3596f9948dc5b5da3 2367 087f45e142ffede69517f1fa1ef7834fc 9be312 08b2b106e70f7ddfbc2b2c546e5bf272d20f847b32 798 89d37dcfd364 5 66 ba9b44baee3c27f49c8f0dc3b53774 a25 9f4ee 7d2cd8500a3cc64c 6b4e0a0f853db0222fb20f5bac4e4025b4beaf6fc781ff8fbc6dd9e24841726aa29f6608bd8e305b0 2 570596041af6b31c0931fe3a523f31f6 b0e721e56 74b5b875eec5e88 f9be6e55eaabc91ec 285 89a 7 2e4e3d7df0871f8452 8b2 25 7c9dfa 90cfcbc93555b1faadc6 18dc 97e2f2e893d4fdb8e f94 4ce31ff056177b89ce61a395ff7a4becfa00df6 fe1 bd46f33bade1f 5737a9680e481a2f1f55f71819d9de578c65 151299b8971e0f47db75ab46fa 505 ecb427976b38ef9 e1dbb01d33 6faa4757ef1efcd29adaf 6f671b1444693d044b34028bfe9778194fce83005e82fbb3 3591bd6f 536c921c285 7f952b65cab9de983dd9bcc3421355c3f89309a b9967cb67 94ac71dfa8f1d4843ec5 8774da5cb27e 7f8960d3ae3b69258e69d9b d4f973dda4828fbc1b1d96229b2287cf9edcd976a6b604d673fd46b  4e5978025ab98b36290edfde4 2a3d5c5 df 0d4facc76cd7fb6cd513f94b66e079d2e6db8f6bb01f5f303af440db1855 01e9d8e5839365b1 e79382 404b 73 e29145116b53 90 395445fea665babdb1c5370 4fb93e1a4af5dc54ea05bfa742cbcb899c5b835849e7a26dc8a8b648f71558 d4c0 9b8a88c c4aee1e4befaa1bf1e4f743091272f584b6 588dae1 8617f8fc859b7c1b0763 8bb e9ec4abf15 39fc9 900 db872aa04a3465f3 17ab74c54 e6b399f dafadb690 b46e9cb0056e3fd5fd09838fc86e2c13167f8594157c365b9bf50e4416372a7 c99384c319b32be519f9d7e 39245 e5eb22a1c651ac5a53c66b50c40db3e4bd05cf1d45c5429beb62ba39e0068740dd bf10ccf5 2a937c11d3ae3a96f9f221e2570da6a9f343266b128ff0a79ffbf00ed5ed6a7 09d0661b29ac fde4f4ff2db7bb 6ad0c3c8e44f05687df0278d390b3fd 7d9f4069908530e33 9db5d bf6046cc37b7  689a 97e581fca2f811fb2e02c4b36cc8e418d19 650 691354902becad51d48f1f8af 6666ab37d6 30b0af3db0dce58a766d94 803486d1a90 a2b4b83b7f31a04132615efe76059ba e4  446c1fbb32881abfb628dd4a1b6fc114fd4c95bd8d e2a89 bf  6 fe1c d97fc 9ec1a a acfab24b24b7 475fe91c 570e8eb8 72d1285cd 95f61  1811f2013c6ee981add7be24d4176499b6b3b2e1874605c0  0b7574cb25 855ad207c 89bd332d4e998674dca504bf48a70d1378240316b2aae04b  4533cbf33a67e765e4f59a45 b4aaac6b2f2763f6d163e861060d671e94c a2 9 cf9 06baac6ee6a93d12da611bdbb71e4b1220e21037cbe4ad7e2b6a 75f 1dad477b391c149d7433f573d9 547efddebef 67a914199cfceceee3 830397546b2b6bdfb39cd4d13cdb20f 46 7d5126 ccba69460229 39cb160c247c8c7716c2fb5cf9 692087b076e93f1d05b544d3cf71f448e5614a 76233020cb9620643383  656807c1687 71e2e47fde055b0185b05 3a 915d 1  1e3c36450d36cbfd6e758fc3d35d9cf865   efcdc1977c7de1be1ef8c87da0e3b833d9585be 864ae5414f52ee86 d2934c36647edc e69e36cc730ed4a0d 214df2e06b9bbf0eb38f93 80a 2f2cd8658f656d090ffcaf259e9a06134ce5d5efc444691de7c9f05 b62d3cbf4abdfeea504489f34585d59b20 6945aacf34b250f24080c9d6 2c5b107 d6  bb9ef40 a21776bf298191b520360accbe86be8a4ad89af1712  8f517608a51368ab47859586b6a7dcb1 9d4a9149bd2ca0f7274ddf258129915ed79 930334eb66f2e09fd9abdf0995ffc8385c69484f 2fc0e33a 5c806a727d74c1dc85c41637b3876f353e14ef74206c f1d1df3ccac808c47d701dfa0f69 186e8c6df71 3233bcd8a57e40a1c3c97c91099931280e78a9a07c98bda5dac4a9ae13 c4ead8c0bc6 85f449a2c1025f2062c6c02b22e 072d8b0de 0f2cf2f0c2abbe05f456c4262fbc6 83103bc7a6719ef 0 f010c5d6d2dc47 f54a40ee0 1d08a438958074e12ce 12d746b9 9bd82 0966998842cd149a1 0923616de 7 01a93a262bb2625b700 4614772afb9849bdcec9aa 8a9c9b711 20716ca4c6b3f1 5e09ff6984c451f 63  b6fa400e 6305b33e3b05da2fa35967c5f6b987d9a2 1c 38fb3f83d12e3e63251fa7c 6fbc33fb3ae48a5377a5f167f78b11b756a9f0c2823e6a841444329ac090d3b3e89 59e636 e3e3285db a34172f772e18d0c33043 ca0 36b77f21 1d0576df e54d988b48e5df606070de369c27c9d73642aec5 9 4e3150f80e 8b5eb 777ee21969b5ede23337111b38475d8d50adab08b7a718e7ae32 9b0239 675 45e d13 197095e5e925598bf0dab1560005ca210d499b5877c72ce9cdbd63dd3254b4c3d80c3bcf90215588b8 3ebc8ec38be6a89f03db 193 a2a4fcfa8627d8061 30 514bc2d6589827612a41cfb98f2 6a 93626227e42 c375eee1bfe257 50 447b66936 78b2162927c230a8c18cc65e04c7d133408d20f cc28ac 907317e73654b6 7655e24f2e2800cea08dcb3 6d052e1903ed86edcbd42d0e29d5bd6e07568151dbce5e57ff7c3ce6441b9e676bb6dec587e9fd6e5955bf fcb13e096928188d 25 60 2c 09ebd9c fb01cbc0 0ad43c748fbfff  514ae41b 0897ab93d3a70187400d196edc23e6816aad782 057 7fb 6d9cfd0867c30b0709f24bb1f dde03 598e8a54e6c8 07e8a d7b792fe4d96d086f099bee4d7f3f7321556763724cf8058509ac82eed 04b02b6664c317e14564de 06e444ae216c517682c8639925a089 f87ed649633a4 983ade0150509d95b960be16928aa09b24cc97f70 84db7ad9d65c938ad  b9b223cdc56c0e5b46c8e 9004 b30da81a b872c4173441f69ef4d799f35674 5c6167ab56cc0b3bc06d2b4b1701fcac13275dc90b97cd64f6e4192afd6bfab6c4e fa4f667549efc186e2bfb584443edcd3850929b5fae852a47a3db4d 685 56a0cee5180ef6b5549 9518e9 e bc48daea73 757572e00b4baaa9c07f131c69c2bd10cd8489e 3de360a9485232799562746aad 366 ae04 f3f0131590935daf264f5786c65f8374927306fde 3aaa6a7118 98eea3ed0c31 1336e4fb9cd7  e5e b9007449e7 cb5574b1dde7b52523a91bffb06 d8a defa6081053a17 e62e d85eaf77f 45cb875350f232c86673f588 4f229e7dcc83 8db02936e3e2dad a0cec8503e737ec26 b8713a18 dadd5b8c337d7a9cf914 0865aa528dcc 5d0ee259471f653b4c4e7c1d0822a663446d5a3ca043b503a2927ca2802e7b802c50fe65b45eb6ac8703d1dbef1b164d37 03319480051eaf896ba42acb6bf 3e817036cde65479218fede0e36176320ead1f868a3923651430177 3a91a6c5a50abae44d0a11e4b6d de16f10d0b884e85f0588d ed 70bf537b9f50c90dc2919ac40198 cd34fe01a5f98375 f0fd023ecfd3e4d8225 d89d97a  1d87f04da65374911127cee78597027d2ff00e2fe88a  a4539c33 aca1273c84a52501983d521e 7b69e2d70a3a9 d2af5679ac f407f955a8 c9ba537944fc 466c4dd1b5495 b9a c41ffa440929658 a805d901e 5b 4a0e1c d8467946 d1f2da0 7a9b67 5267f771654f9adffd8f572e1bd1b6f7e8bf2c4fdc85d9e34a3230f4a35a147099874ac170e15e08682930 e66aee 9f7f7272d3db4da68 4cc713d8d5c6386da ad5f 25a fac7a1c31 b82b7ebd 0933227b7f03426a2fbc f6 ab45efc46fde 1849b95b2d46216c7a7d2a a595dee3f 7ad1dfb2171a1718e257475a976c7563 58e60fac5a393e4 e9ed 6a73d4 8b02ce6f4888163d856e0e128a 6ccd1c83fab1f8669d54cd8f73 68eb1acc41d6d1c635aaf f58bafb9674670050a13056a1db 7108ffe7d1281b889cf39524024cab6cbe2 1   561327d52f0af19f e033093f6d2b1ed1b60f3d100b831ea9249dd2ca601 6e31107cd4335c74d385 f043a42f7 203e55 644e71be a11f 8d5dad11f4c25f2b17a903a56ad67a2e9 ded1249f965ff7a487d2c90d92e9338ae8a97ff2fac73 77b333270e693c3f4d955e6f 9ba113c6182f0420c0 efb 6205f5fac4946dae56 c758d12a3979e878f670c8a2056c1  037944f4e3856a 6 448bed5ed7f52070d05a1b38 55095e0d35c 85ad0e181 b349f1d571abf e4edc0d814e0  6eb1aca9 f5fead3c7c2e90 538fb4316b920e18ec2f 59 0ae9d7a1f4b163904d 5  0aeeeec7c6685cf407037 5f470b15ee81  38bb4347730649 60355be222162d  9 728249123475c3409be91b36ce 3f0654a9 b5ad11 3b929c5037e6505cd6ab77f02df33b59777180f88fbba4399e2c771843 cf3a1d49 8e082db bae84 6b95e3b287fcf38b2b6cfbdd25 c8a0d0548c6 8e34b8353 87a26e  96f93bc9b45c6976e3d403d6b936ef320912aaaf e41c39ecc2fa98a1c3f3cf09e66a9156 7c49ca838 f47f 5e7c760ecf6b839b265a 331 283c87592c 510603a6a698 49bde239c983ec19b896cd7e61b2a8e96776a6d652cc b269 0b90 c8b601b3507f 99a6550233170d1da196286c6caef65bdf6 aa85f01344b72d5f4b a9db84ecca 9d b7d09813e12 3263b06f49dd1d01 1e7afbd90824a 4e46b5a8e14 5eefc5d138db48 5e829b9c127 203e661d6cb8aa38e0339f17640031ef0507e6 084f04e1 dc2fe58a2cf11d 0b fb689dfcd1da24285811e80879435f7e7 2f815a 68dc3889b62e5c4697dd8c6d99a20b8bd157100337fcf8fdc8 5ae04ac69a3de308723752dfe6 d f5dc0d03958d215 173b8dabbc 1a9d5846dd29da8016 675e590ccd4ffb2ab96943f33 94a380 5c97dcf4c602d8da0 ea6b 344e 71bec bfd 3db 7641e729cac90597fb5441201901776655f2c0fbb5a 76bc729dfca bd1bf07 939f9 6bb9419d00b890b62ab e40c067d54cb598687cc de4 b26c62ad5d66c63c7bb12ecb 16bc0e5c0070a0d2 b2a2ad2478886065ea971ceb88a0ed8801 37abe2b0b91428bf08 47d24e74d3 580a1fce2ac72c41f8e90e04c4080822e969 e6553e74 ad89c446d 71f1c99dcd0b6647230882e7b 4 9e7c0fd594121fd4ad54f dc091603 450bd331c17c3a9c2530 7 e6fe66b3ccb1029e3b32270599a8da5fd53d83c314736 5cafd5 c05 b63c12498b9a0d0a e42590f1268eedef0 dedf7d81b2 3b539614f5965b5e8 7ce4f83d4 bd1c7eaee124a5a4110e4ea2316cfeb c b2 ca95 6870f2c8b78 a081a8a73017ce5d3ce97c557 b0 bca42041556eee8b0f623bb27fe7b6984 bcc e3c914bd 1 969f8d1976ffe2ca6b9 a64a50fff23a5 e693c77 497ab02b76 956c 0eab962 37e0 8e cc702 3ac 0d680de72b02629ab83 720b90dc1723bbadb5f125ed04df0e77de5c5f75f0b8517b333b28e51543d0c9 a9e2746ce87 29 7e71336d 521e611730 d1bae0ef1 51faac9 dadac174b6692aa70ddc539a6725dda69df70b8ba07cb6f571ac3021a078f66e23e93afdbdb6674 cb1cb 8 0c0ecdd667e 4a56c c4 be7739be59c1 4617abbf94a988252 f1e6 fb437256e14155c 4 766d8 086df6063c456 3082f4 1 88f661c ec1 3ea 13198d560 7004d177a25f a13b4 f5fed 32f d1208ed41bfb8ab7949c5bd6751230148c327 2147fba86de2eba1fa8d8b7f95aa07e04f728fa00d53ab56465 206c655d2 d20b8e b767 c779ce 33aebe95cd34ed287cbf373f5cb77cc7cd132ba 9a9449579c48e6c 2d838b06 c820c1 f91914 a355f84d5 e d 3ed7abad8154b43c5f44ebe4a19c897a07 75a54e5 7f6b121a29017d471681f465b320 5e102a0630690ab63c 1600ca9966 8e d04f1ea467f8098f e639134bed3489 4954e09f3a3eccb5a8fa3e3cdaba21a18b7b   b6194a3da360e39de94 485 cf55 f72c424a153a9e9d580ecf1ef6485659  6cbed04f0501c8e 061180360f413886f03825a6b2b6adf61245714f3b67b71c 0efaa95f310a9 1d995f84d9f6 0e 1940ca f132e 5c77c75 a a612c52aba592a8e49162a14ca558b  0430de00570b 5770660 4e5167ec327c297acc64c600de0f92fac0dad4a0cf 89cf1e91a7cc9d3f a1d9a19a822b56817bfdae986352bfdebfd6d752f2a3c c7 abfc34df86f0874960f14a11139fface6 153430023f244b247eddc2d712521b11ced6bfc17bdbc62920d32790c8389d3e7dd974550aa06 b35db6ea2 a62032daa71 0b16b80f5aa20 6f394ea67fe90 3ae9f9e529b95bb35acc68b 867dd8ac3d2e60de31 beac29ca42f7d500428 fe9f6822f7f3858 74eb92f94db8e3425304f57dcc87529b85c974 c7ce 3ba3 2a6cf8a09ef461bc9a9e3c769adb227 3c183d22e40b73 567c768c94589d38b69551 5797b87ebc46d85998 33673450a75a3165e741e1101 46981beb42b0330b4b20f3a 9ca730dcf48f 1f0a4f5e6780 cc51879d8 8 97b 3a8a562db2e4be74 a6f0317fd6c6588287ca390f869a4c0535164aae102cc96ddc20dc867f5c7fc7469471763 21f6f2245c3477a86 26dcb534b51c7e3b442cb3e3861a414eb6614cff7dfdc8e00fe20774bfd4c25015af19d07919564920e3ddaa8e0ed491390df93bff030753e00557109e4a9445f7c264cc622f664eb0f2aa012fd3e 55cf9d b34ae3236 352c8 bdf2b1a1b19443cb11 ac29fc36d73246a2082980775 df  4c50ed3c4b204d1 838395a70 44de99381a360a4fe1275af8704311efc5 1237c68b3e30bc812d15e49959aab03297886d 320ed582b2961fff28b3a a8ef c4944672b27d bae3654e2e312688c6ac9b93f9c95a592a5a460d067b91adb6 465ef595d 22823 4bfd 955043d7 03e5afd67d81f167e011acb4d11e9adae5b7f476af8ac2ddd983 588ff3 b71a6e2cd76ea0a62a7d2ed9b25c025 980a3faec2 d6c91a2758cb6ad 8fb0ea91a8af1f735d0 2a404f8e932d0ebae607d9edcd884b9e4b8f40c7dac4f7c6b4e52c84bf9ff27f198c13259d277a225afb c3db69f239a813a d6 93c8b841c c8269  f29 8d7dc54 8 fff71089ed1cef3c4ec03b ace597e5b07973fb73fe4002dc4585e534 b7ea4caaab67765cc70c04353677b9ece6f32 02d86f37c598 bb148c2d8764c1102 9 b9197c03c6a40b5e2403d64828c593fa7c48df9c1601a630bf783d 64198116a301d9eb087f157ac1e30 267496608d087720b13e48993ac05d93449945ef5 1 e1eed64083 6f9eaec 05e2446e50320e95ae124960e5ba  8 ed4 2 7542e6c86dce214a3 a0c6561d355cc62b2a56fc50bf3a48914f20 8c864fc21eab9079d d43972832f34aa197d74e1dbd8ce61db 92f528ea8 7aad10305917d9011 46abd368961e95a972f6e68 38dc74a1773e7daf2d 0129234c6e6bf4a884eb27819650 a c265bac 287df 565817499bc23 1b2e 4d9004e5b7c5397a87311f002d37c4 6 5e92b6f47 c858acde5 a224eb42baf8a15efd47b8d1830baf3bcefef4bcd4ef7e82f847608 4158681e6ac4ddfe9c49 a12f8822678a4318d42 89df2f961aa27 bd240de951a7f46b58830e7ddb07ff3 80198721666ee8cbefcb5adb52d2697180ab2c42a30be3fb 520b41452a4 90ca7 4d8001a 83a676d85f1e2515433c c0b 671 9 24b61a8 40 fbdb39f  1c928d65e6 d22aedfaea16 dd95292e56d1312b408d79090d9180125d66a 5ffd48 0c85fcf95191bd4d570de07a65b53fb41110 52ba37ae fa2 6 c96 2d2dd011c380 7bc7e a3a63287bdbf9a4ea968f83ba1c4e8403a0f36f8f16bcf197dd 46a1ec050c220569 dd3f63f22abe559856 7317d636  e1258 6d54541a2b14b4f6c780a9 dc 331a9988c49991143b8ec59636282e6 928542d84f9bc 8084f6e202bd76801edbfccb472cf3d49675d1e2bac3f5762d1c7636d344717925e9502610f 0128785387b1 b7856 d60  d306e766d0739bb70b281a3371219f6a15c775a4fd4b79 306ae87 554230738d 6d570eaf2993932b06a 26d 5be81 8 914810fb157c0fe136965133f13 9b2d7c60ed4881716cd1b6fb1bcb02 40425c30e4c548b9 477103987d8bc9c146eea0f8441e93122eac1926 329432214f c7b67a 99748003a0bb93c1af a 1  f7e824b7c98ebe50dcda5e63077916991520c49eaced3d864e 23b7df4ba8cee33d54 dab2204e992 bfcd9ce3f2ad71388a38052629288155ada57131b9696470cb3c b6a7 f2a7c7ab4 c 81f8f7f7ba1caba94d76174dbfdd 81e1bb87bb8071ce ea83db2f9d948db241d48a135b2844ed774cfa161ec67c62 1b9dc40e0dcb2e937fb11d 45d29 d4 5a74272bd46e 74 556789bb d78 c3e1b0f23bffd9859c b42f0 bb41d452006290f86 b 17be18b4a5df3f701d42 33c16b54bb0779f2dd3d67bb7ab21277bbc5b035acc 4ec84cd3e3876078538d79d3179 f8dbb45bd261b9a  f66ec4c995 b0 c8ece79 03873ad837850f9 e326767ceba09298055e7bd2062263f365580a a574896ba0 465 2c5f e7b5764 5723c78 c0661  c79cf34b067340106098d01c17164ded45bc2011f952299904b01ffeb05 2d497be64fd7ee9fb048 f06298f786082f6bb83ff52e1816fe0279eef6bd94e010df5c80db94fe5118d 4a9c456c3cf529587bb6f9 db65bcf6edc0d9e ed4861 a23b81bfaab1fb034d0 41c389ca7f6e897b70c 6a9b9eb432be0 9523bf982 a3e8e9c485ef5e03daf502f aa 1527181d  56c 91061e0a417fb4589 e133833de49be172d13 e4bef 2b bd4e27045535fb0a3ab915d9b576da 094b23 8e 8989 307adb45a10c1d06c1faf1d99 80eb76f8511bcff  ecf1b1702979234 9e5c46c1fabde da97e02507e527203 8720ecaa586ff e4cb6b92590f  7da2051c 13573d345e3a76a65ee564b171504493231adea0c273 733216c6c85de1050d32255f27c1b3f aa46c3279cf66b6eb6cffc7ae195788abb75956e8a1bd5970 8b7230fe3c9c3 5b7bd8396ea3dee212062cc192548649812a417fbd70cdf55bd5fc5f66361 3ff71341e3fb0b 88508eede3d6422d3 0dbbcb7cdf0bae6020286911a212259242 cc0a 49139c4d7e4995e17fc4fd8e23a6c548bbb4cedaaf37041ee200df366847f9670b793f7 4210e7e661aaaa2c87f7793c a41a7e8 9e89b9531b16 2b3b58aac5f3b344 ffc8971840dd594fbcd55329980bb9df7a0a6c26363d48168e728b8ae41af1bd807211f1 eca6f1e0b 277f12eae13835510 e57cb89efaf6bfe7ac22 ef5449f1c2c732ef b219b17a644ccbeb838da bb34ab3267f29 4db 9cbc60db5  ca530a90b 5 dca6d90737f8d184525e64b6ba918 57c567d8 b 4796c5f4b355f57efbe639967 94352943c1256a9a15b51a17dd1d52b9fc122a36809443abc0b 9a48b8c76162 b9dc0bb  bf9e878ae f49dd06c18f4b ceeefc62ec146493c6187ca90cb39 2d34836927d0 5 89e17a5bdb760d96443a98201904cd118 c e a06c3f9075617f87de  3f080e5ce3a09d8cbcd26 86 bcbf8767512d27d 1a923aba399a59b7093d8779c036224c97daa8edeb38 366e5db1ce6d28b251 d78fcc374178 0b03 1d0 47ba4e4966cbc1d 64d0 21aec0f86f1ef8 d6fa585e86 474c38a472148cb501092b15dad332f16232 4e312 dba09f78b8b4341b58a10e5 464 feb 4f07b5275ebfccde365bb7cc  e8395 a4448a746d3e2 6fd6 088ce3e30df09d05b5ff99b3e85459a4b74dd50aec4e845d059e03977db9ca 76bc12e 3ef93186c598 56e8beef714046c36f977d6e86f c 57ee671 dd1e038e5175f2e3fd19bdc98d2fff9d9db2956f61c7dd6b54ab8db49784430f6d1430281c9b6 afe27abae14fca3f4aec8d1668b12c801231ef fad7ab1c3d 259657e84c abeee539e 620f1c1f3e17 c795c0025 07cd87a137ca33 9472e8bdb607a418c5ece5f7bf3 07d915e13a01c29898e1 333 b1ded c 19a  a6410d5 be0 a9afd1 48e2 2532 7 3eb06be89e70 0d75f0a8c1e45889f627ca2 0304f2 159f1989b3c56551eedabc7278f5cabbbf408d794ae0f07ac18c66b35218 17c2a3  16c 9e43e82cc dbc6e3d222e0 00f7f50 8f3bfd 1eabe3f914b4e1adc85721308120259c2bcca82baf 12bdbe832f407 279602c510ce 72c1f9c9c2ae9 bb8a85540d331 e912b5 f2d4d2a3987644e8 7 1e32fd90315d37b8897efa0 993fa0b02696e4146042149d 657db0 fc6f79fb12e 9560fbe1e257 d1ee818ee2f71e62bf2e1fa 313748a2e8cf52c45594cc 63650435b f2388e77f96667 a55c10e34d3feec 577020999 b80  c560f19e fb49807d25ce666775cb7288120837 e65f0bb2055f8b2e8280c c11d5ce80 ef6206950cd0fad0982d99a8b3b9 18662a022 3 d4a7ba8ab7274df 2b810 e be211622f0fd743f0f27 2138705772f2 fb7f94dfde67c920a3484fe444081e712eb8ce950299bc098ccdd 75b3b9cf396a0573f0e0e96b8b575c11c829a670 c96a 5be5409 44b85 21e0d4f6758f05877a5  f16 4ed76b81d5ac164ab a4113e46f5f5e8697acc3 186331 cbf240e7d5abe1a87d cd9175f459460a9945fc4a25f 129b0a2248cf 9759936af253a7f8ab827 e971b17562b3fd17f6 03a705c3aa77cfdc1 baf28e3bff7cbd3a236820525c9fac 9d ecccacd9eb40b8f414d024e577b47eb6a288c564b8fd bf9b2e1291e2 e9feab8037ad 5dd99d5bad0273c68 73d9f7e47ba49d9499cd8f4fdf3a2 8346caa7365d8dc179c af01f1430028db29881a16c07753dba6691fe4 16 424e41 95c0625e487c0b539223b65ceb903f8403889176 2354235a4ef3b8ca6d 847e4bd3 94ec38dacb8f8bb6 dd04b22d747 d4 23fc e8 618d2edc 21b95e597ff361b00c08d03e2d0ef42f4aa1e93cec24b7ecdd681ead14e 85a58948b35 a11d9575f9b75eb8d05ee9a134cda733d42ee5ce5d b506c430849008cd23a9d8dd852494b329918435fac90b5 f8510b cbd f1  d5a7f627af13209d7b1 2b1f19d2d06 67 836c9f8de8d8ffc9eec3747195da197271bfd474 97b8f2b94c21aa3e7763ec1 8ec04e5 31e18dd4ae3bbe5c728574cb6d71cd646e5  6b80e5ee91aa b 47 f ec87c98edb4ccb4e522c cf68a045d9dab020986836eca0468dbeb784e9a0afcf7c87 33d5c88 2ed2d308a7 201c0afbfb641a60aa0e e4 6dac9dd11553dd a bd0bf03e3f9c76154b4954ff8ccac871fe4a144895abf8cd5 b90d771eef7c2c32c04b9839720eebbeb35b8 73fa9d1 4eea9f5939395bed7e240b1aad052b2cce12042b8f48 ae27e7c e627c974208bf a6cb9803a5915971f59834a9e1f61b9ea32d44 ff2c818b594e10f5ec55083 a4f 979cfa  f61c8a734cae5f15ccc9d295bb0a2d f1f6578ac16 b03d3f946 204b35c59eea e2fe84be2121296404263 40f4 a06cd31e6633bdacb85739cebf16 d340d049233e2b18145ddbdc 2adf2d2eef3bded0cc9b84ccdecffe2fcddc 0ba65ae ce8c3118a1b6f0e6a3b24 9b8488ce9 fca43752166d1b75c56af061e18e e228c  d0aaa3003c0a0b54279f858fe74228dfd518daf86 970ebeb2f8357 985fbf277284933e76e18 eadf36 a5b4b75857dd a8816d1b602c6ec9d50d00360c80b6 04a21172 dbb8b  bb2f8f9da8a91f214ecc 62b01fe8789 89ef 670ab83c73 dc696671170b710e21e7d0a5b525903f11 137f0dc70 7959c0a 48 565649072210 3f6 13b6 3108d4cdbae98e394979631bc8c1a566 4b4a8eb42 8ee3beda2adade9a78a9d69e4735594a10b29c8da9dae32fea  f3c819b838e81f9e1f1c2dd8b9e5f3a 9251d7fbdc4be8c03c6c4b672fb9bae5e962c9b5f7444 9f5d5 f7c4b84cc16ee2b67 d9c29c8222dcc 7149f4 9 791c6ec1b00a9f2b46a db 414974a0954116de6427 872 4bb825 e1c7 7b50849c2ae67bd5aaeab99141300d 8a527bf33f 6 a355f9df e5a5aae4112240cea64f56e aa6626f8 fbcee9ab159e31baf19e4af142e3c9c3f9b359aa6e866c e5e9fc2597cdec3af72519cb4cdcbe59dc3c2b7a75dbe9d74c76f37c932d2481a9f4ad 8e990e53c4cf27 01 bf8 f80fe58dc957a1b861ab16d65a37d29a9131 d283 c884d34ceac7  e47fce c280dcc32f715a7d734b36da1f63bc1b3ab26c42b37fbe2 1e76 7842938e61ce05e493869450425 58e 539ae1d7f62 33f31de25  d961 14667d 16 e27 5b1ac71a178d486b  42df ed16ba8 ca0887c ed56ca45f7dec25aefee818065e554e1 66120 0ffad7d9 049fee1 0580bc5c5c3 e017f7a441c7c681c6dd597fec2 e55addd7d4612f8d324341dcaf92e6950fc75 5e9b8a6724b4ef9d37832f06f35825c96dc5387211ab65e330fdac1732c6ef28e bce9ec2  e43410f570bd54f29e059b36 59e9eb 9471bb85 5d8939e0f2bf9104aa0 271b6e6b958f47357afa 772b8eb b11d6 6646cf73e359e4e c47a6b119d134646b5034773b31f2c9ceea3e8619b08b26cdea 252a5153 e5fc215f4d216ce2f015338b2f9e6935431c d4bddcfb3e0d313920b429 5c0a744dfff404 6cdd4a4a4c3  fe feb15010757dd 35d7 3a7529561d7 2de68b33498466f 51761aab14954d  8025286a72 9b151 d3d3129310bfc55ec5 2a0 57 2b42 daa9a546bf55224a4c9e8749ca1a4271fe6fa 2997abaede15e65e7d10db5a8480e1d1e 1911964e7a3e9a f3af 20f9  da3d2e88f1d 05d32a50acb67ce eaa212cc005e44df24 e7ce 86155bd9d15f6daaf542d4fea31ab4e01a323568 1f3b45404ab06222ee92c7fda169a33c9a7c1e13 ae5e24037d61686c50dc8a1c9e67c580ce1  57325f66 eacff2afb6970 7 672f4e24a5d29c64 108f6de6049ab  7fc 0a9076 7456 aa520d2c8836e0c516f779580d0  2ca8191 6efc29ee9d0 d7fac640f4627ad048d14b29fd7a702e4d0a1d 8ec9dec8702dd95271a189 11ea405c4edee 55ad23 d2d96425 0071 e5edca2faec8854ae984a6029f29969b958  540ef6a93 8aeec24816cc743c0e476d70dab4502b88067ba499f62c3557f34 fa d3c2aabd 646e16db92b 01c c0799d5  ebe09e72c e7f12 130c8 247820991ef464ca658f2efb343d5547d28edab1 efafa01b41d923fefe2000b 189 3b892a33  1 3b1a101b21d b0d2d1a68103337205bcf9ddbd50e 08ac3d31052989d6521 2d36b78316 1239b83 5c7a45cccbb4a82aae2da c6597b5b 7f9f95 51d1b689073b65f026a6baaad3dea6d9003100f64068 8 3adcce0b1dcecfe d15e91f9a90 1470aa72aabdb d4dbb7d77f394543d6f94fd1a0dc0a157c52b5d5f8fcd319bb5b1f00d4e59eab890 9708d 56dcc258  c0629 2 a7744 9d603eaba7c37 9d4b81c33b2c93345a 692 87d56ebc3c70 eed b 840 47339906786bc355efa811 294e6766f221e5f5818f2de8 ecb5ea22c5de 5941f0382e5c66400736 0944d54a48723a44ea02e5e5ae799c53ae8757af0be63ab444cfd1b3 5c190cc7e 3a ac8d32b8b5b04f40e2966098ce06e54731b 80ca51562838335dd9fee3f3df05  eec7534e8511ebf a8e27 ac12f6 d125095f69e04f8724dd9ff4c2611 4721 45773f0d8b9ed288bd0 730f93d 07b  0c4 87e0d40bcbe8904220a87277844e1374806969e57234869c5f3128b28 2705cf3 4b3021 5db5c7bc b38c2bdb9a 3a7b3da586617bb307b62122 67e e6dbfea51  ad3 e34eed9b414f bbd24a07a 2 5dfb774644c6765de8bd1df34a493a89b014538639d c243cf7a47 3f36f 920be7c60bf1d46bb0bb8e ca14c5f6253121676331e908f56d1 ee94cd1d5ad4e83e82b8a c6c553bac  63de3 6620c52ac 395b 6f3488151e83e92507d14bf4068b41b14f50ab1c1433ff1c0 0c61fa6626 d66 9a3fda6991301a412dc0f21f363674e9ef d5e3ccf5729ec20c659b 51641c50a 883ed1d282ff1e83 7 e ea5d1aa9 c c13a699 3956241c6 6f654ec0e6991edf3a3 3040dfd3db06024be ac2c72a8f040264da9c095388a23a98983001e8871bce7dd 77160cba5d33817733c956b18655ea6a4aab43b6493f013e31ace 5c12dc4cd130b3f c5b38a37aa391a83eb 5bd20b0a27f413965947ae848e2521db 051fd 217ea4a7 516d 180cc8c 7253ade cab2b7 dcb fb84431bc3e8 5c55  5aff aba05fe 42f63f8 e281b99b 825d49a95e f3307d84725f6 1d513c4c5 62 813437d00209462980a550a0ab45ce9 f5a5648e73bb1cb34f e3d 386b370146a9febcd 014d71266e1b1aa6ba63 179fed99582 04db55 9c7072a20 8162b8746 08 b2403be0b46c5afd11e910eac288c8ee17c83cfa9ce02f151a f26f7244d43c5e565fab9e971b3437a111707d 55e 5935c0264dd4c7c95ae53 ea6238ad90 bad 22e66ef2327 61c1e2d155e1f51b 60b3ce822c dd 0e6c30d841a68ae8b93ad43a9913b687c 7f4e7d4278c75082fb08c356313 74a134  b b 2868a566f 70f 563 ae8f65a717ffe85a5b22737dca01966ead7d8f9fa5096  0e2241174  0c27a462a2e2e8443385b debcccc2f28faa939 88 9b0f da1fecf3ff3 20230a5 ff771fcdf9aac8 768c43bfcbad0c4e1cde9273e4a 468156596161dc5b6dc 58a716bb96767c3feb54f30b4d6a9fae909d 5f9872f fa98a31fb265165698a5db8f53176ace05403ca63ea369 9a8a3b69d58ea993677634d717 c30a  a39129 38b3787467 bf6d3a3ea8474db65ffb307e09863f6692a47d6a63e  13 acac 229bcdc5c39124a327b408140b09c4ebd2506af15 36e35021c0bf491f5cff74e81 ee4 fc8c4ffd6b9 3f9043a942c361e021fee07bb10f8e05de8184765a93aac fa1be9d4f092128d9 9c80e859c98822 ffd42830b 390456f65deaa28aaecc485ea 3bf4cd31840c 4f23b3bf fcad4d60f 66b7e906bae59c2cd0955e70b9dfd0326fedc332713 c754042ed318858bd75c01 08f1  cb6a9845 59e22d52 3418bcbd263a4825391 f1b738dde4cb53a0dd 94a0f44a33f acec511a6ff48b08d2cc892da 3ef 2f41d0b3999cfd1 57 6652e6ac1a0dabf807cd5e7d8749dd928477b57358710f2e1477b3250adeff80e e56102267d2b90f7923d9e75011be92a502f65aa287a9613 c1e6fd690ab17b1301d1c5 2d355 73 fc49da8635a73f9e0264f60bb2c 5b5757d876747e84ad2344da3e1a0ffdd4c7f46dd8e24e84b4c147510ef997 447578099e59e6a9ee31a3594b169764a6f896c1e3c15200a53caa0b  06bad44aa9d76afe 209e fbeff12 affae60be72376a78883500a03 946b5 1d459952a8beaddd 0c5 0b2422736 6e93f06f0af5 5fd9c6edc72f3e5e971899814a66d8150f7d7c8a86fb440eb5e3b4 405597373924768d cb3d6af74ab 746fbe9df7950f1b19f7a17144eaa8768ea422ff424 33f7d67 718cdc74f944ff1  53e0545373  8e c  5b7e5a5a7d0ada42a1e398c470cdfe71762f8932de57b548565004c 9cd6d04 b7 1c0f1bb8a9  bc6c5df69aa3c975464cd95f3abba12c3a68444eca32da1822e d 09328c9d84084f92251fb2fda9db95b37 263943c04f7c2d0b6002f7b6decd605f7a51bab0a9de da0a9a50c4a73433b57 e9cf18bd9b6 4be8b49ac244f0f1ef8820a064bf6 d8c 8cc74286371f90 ff52ad 84 f95907da1 0 992257c7dd957 8fe6e24ae  216b6f144193f114fedd05b5e5b9a85f5174e8d17610923c4 ad6ddd221cfe2541fcd7246ad 2 856c4cc930bab961 357ae1081e3f874890f4c1afc4f420a2f 5a 0c6ecad281ec158f3bc7600265 119e3431d1ede795 f493 0e93ccfab5f3eca9ab7d2ce16 4657e 44dda9d3b3a238b68 0a5606312a083a1dbca4fe863ee88d4a8 f52d1914388c38c6c03c76dcd600a582 02 8ccdfeadcd83203f9800739a8adfa56449e3d241cd23086ab e2d7bd56a9904ac5a3f8642e062e7f84dc540568ff5699b5338e3fd3001a11 d 39c 342fc56bc1a23ad67e9b c4bb1980bc10 7ee57d1d0a91a77791d1f34574eef 668af942bac0ce77ea0  5e927154   2ace29a23e4ee37da3b0a22239d2bce686c1abc5988f0064f6c6d05 fe c92832 e388f68d4f3103748c10bd6 6088b172079541d dff2e6e3b7af3dce73fdbaf54d48721167585f8c368bd169398802c18bc5 5d76da7d98c d97 a2a03 0 0 f5a7e76b348da304b10d08ac6af8a4208037b209862ade 74de6fc7ad4 a91bb43213def9a9690474289de236d9e075a 3758319f 188971c8c 1f98e3a85 714cceb03dead0 a33be2f2decbda573457 096251e624017a407def22cc6e66ae4866e9bf3d6ad9ee6261087b780f9e330 8da272b71796fd28d2fbbf5f1ad0e4b4a72 91ed6 11af8593 0368d5ac63e5a810bc7859f09952f12 809a2e93334e 45d4d a528fa0aade 732e7a 7c627132a8221a025a 387d7797aee40 ed0fb3ae4 f c0537927357cbeeb88cb1b b53e6b506d579aa98cb21669b66e1a943d492734521c98d745a38c0e29cd11ca4a62ed233c969e825f5eb958129ae 831f2e 2f6bc 9b2308e2 4b7d73a523d92 b10a8df65f69a4dd120827 10705ca39da8c9f80fe76265b3c4d889b9a8896882c40cad398b1ef8fe68f6c1f9e8 8e8 80e4 aa549e9588 ddb6727fc76d371373dde244c2b53a0b19d3ef97 f74f89354d7bc33065572168df1a594f6 89791fe 4f8c0d2b6ad8fb66 af2 95ed9797e2c56 adb9de3fc5 622f90ab577 619caab16e78eeac07dcfc9680700 0dd54815 2b 33f9710a135cae7c93ae83216c3591bb32b7f5d2b9aa 97a555d 4 3d9f5c55 ab799a31 2275178 856872086cf5dad4a2659511a1f7b1 c4b6 ac6c9517404e2b2f7a6c 4b430dd2a463a160c7b5d2f451bf1 76d4660d597132f5693d6de56a5e732037 c22390  ee4087498ee5bd697fef09 29e2874fc9 8c5 b14a7bff088 96f91f5513a 1d7cd0d432cb31f9ce82ea922bdd7c7ec9e9 b51e7f062 b954bc ff 258 ecccd556eb4a0d47 6ac4b8be7 52 c160021b25bdff0 501 17656fe309a ab ae529ac3c699bc 4d479 ad0b075c226 e8b635fe7166ed2f89eea3aa 84ea24a6b835847 f75 1674f1e379e 67cc7 65c27f349a8a0f9ecdc 57b7e9e79a0d409facd539a3fab9463ab5fbdc03c1ddb0b9ec17c32 7655930b963c3c2 7f2746d1f1d5de630d05ab1f198d1b2c07f2d4 7e1fc94068f9ba1c7fa 396073d55fc92470cacb04b01ccb19ec6837357219c10fbcee d0 f2a5fc62d5fb7656fc3c6fa73052bfbdd5fb0 951b7cca8b225f2077ab 5ba3341cc53135040297ffd41a5eefee40831e37a23704034 f3425be00d28d5b 547f37eb6b068 1da11daf5269b5d4f011059e91174bb37b55b8ccf707624d96aefbadfce81c8789a4dc1e930eca2fd4e2ec2a41680c e423423096832052a376e3c6c 42497abacc3e9 69 dc1449db82cf e67af87fa8f0a1271214e8d1ea2920383c72ca0baf1f31690e9ca2386a03f5cc49bd0635ca809944919e70a5aef19174f44716562c480ed 960e34d01f88815bcb12ecfc324eb4c f426c131ab584e146fa6cedcce48627e5 64a 367e5ba13cb51076e879dede25743 9ee32a66361ff03b24541415d50a 4e7dda233056545b8b06dc027c2f4e62a a2638cceb838d18b6f5b9 88f23803c9ba2198a8313c2c505e47d6c2903cfde2cfb32510570320e39dd23871d6c8af48cf3af41bc2c4cfadf724c9fc3 c042b149 7 1deac421ce1c5edf 8ab4 0833 184 b1691 5e 54221767cb9cf1477517319f45272aecfc2 8eb288 e 9e016fe7c 8dd91afa6b2171d decec7d9718a3 db82d333 6299878 035f022189c3dde192  51fcaa234d46f048220 79 5e2a89a134a373f6481e324ac07013f5d36110048 4a1a5d642573aeb8 85b6c580dc9bd5cd f0f3de2e92d26890f169d5004a1961ad3d  508bd7b7ae7063af23544b 5 c6034be1bae1a483c4ec8f0e5142da85c218df3dc7e5028aecad34c8c 4f2e6b5d7a76cb192f b134b2a96c53  2d5cd64d 89cbce368b615a08ec435ec2ccf26bc6f84d75 3d53b0ca925676674 4b5962c6c9d4b33 f71c5  88ce21 7 90d2cd6aa56f440df74dba2f83f385862b12c9b53b342af9af01004 f063f9f65f8147a68f0104277a33f578 45db8165505c356992 87e4773b55d3619a3f3af9de34bf8466f42ee1af2  0cb1208b8d9f6cfad8fcb7c0 827e40d5f8caa86a1ee60ad84151ac981166f 7cfa0c3c5d53d8a 84e3a64a804 deb94f6e4302232785ce7581fb7 7f62b b59bb27d405 d9fb904f5e022404adc00b66ed4d591a023d0a3 3f03bdabf689277906 d 48 719ae41e222e69a2 caa0f32831e851d 8 302975788ddb177d 2e1d7490e91486f6a94c54c0430f609846cee33a3a bc80c26 199c4aee371 3bb3e2d096380b266c4c6e6  11483b4717021ce5f008e154315321880af6 b159124bb dd95cc84e98 5 77044bb12e04c181f82d4876e6be6e44ebbed 5cf40cd01d73981de778d c29f27 d95a8028fc04a364eb 2be3e4de2f6e6262f2a3a14f4a015c524d726a b78370230279421a43aa3e0f74 2095368625 c cc15b6db3101626d 617d479277b5b45d32a6626e377db36effb98e86a a1a8e18a7e2b652e871d5781829727 0a 0993f0d4fb000437f 10e93fe98ed437 71f1 1c62b7c49dcc57a870e8229e96094b9d9c243f95090ae1e6b9a80273e136115c7 bc d717c 1e1ab1becbb8d40 9fbcdbe3e0eb296ecfb79c7f2ef302a560e7 5b 27ed7530862c12165bc4c78c03ef84211c6bb954 8  59f0282c3 6b803d2903fa5 8 b2b11f8c9b96231362aef0dbd09  3 c8f0e6db53 b06c5af1a4021823fe6644408a6f 13505a4 006448 b97f25fa370672d4a004368e5b3220b6 4c 377e7f41a6a134936a8cb45740591421d67852ee4400384777fdaa224fe780858ed 66 0 f6e2e30b8c418ea170c23ea8977a480bdc f19bcb292e5 f a d1cd d05f04b549976c600de2277976708cf15659be1c820bfe6 8379f22 a9d1300470fe4bb89e34f7559bfe21caaad4b2acb4f0d58ba63499d 37c31f545ba 9a834851cfc8ec26c09b3a1 00 7 c 148b38e6c7a6 106ba0376dcb892dfa2e1 6e3b 99772e60ea3f67c3475ef2415c e35a 6 6cdfe7ae75e380f27fb9bb946d7 1e d15b1907548d7d20  ff74e5f3fc56857c000 b8b9ac02174f24b57a494d5 1a61792725bebbe0a 2c7 5a79e7541c0e5994d9a9d1eab5f 589affa03c1e08ced970b7ce0df8c 1c2eb0ceff98948856b2dc8876acac55abe4 a1d48c2 29 e81d906e3 296deb0710af5eaddc0 97b6bcda107c36153f1df7feb20697d13b9f91e192d64 69400abd73527516f b79c6d3d1eea4 d51cdc12 d571bb28d9f6 587b84aa0d1b5c93943 2a bab50eac1c9e2690d2 3f8684cb720eaf775d2830a3279 b 01db6f7e d935087a9b869f526575842204c 884e5 e6bdff8 fd842cca9ebe b 588bfdd9e63d 623fd4761da42d2a8525d8b1c e16d74442bb96c14 1a4b116fafcd5d8e1205b63ad1c0bae6a 95d 5 e2e5a8a181d1715fe45f970fd 0dd3 9a5f4dc3f9ec8676efd 8d93e415cff545f898 3ddf09cb769 1f8e9378da58b6ede376b25fc43a9a283ab76d16967af1 31a124906 e73c4b9b67c04a2d6dfa51caecf0dde4e008 cf95be54a2e89da2 e144058b 3b6e2d5 80eb3fbb22 9ad8eb2dd08c83b728779ad86c96f319801698dea3604db3fc319d22070f12344f3153aa af 3e00ab415c7fa10 296f7e6a034637ebb7869e9d4fbde4cc495 e7ef3c8 6673f3872e2860efbb0d11acdf6ef4c9370e60b73 8f318 ce4b c4ed30b0a249ade519aed6e5e84daa93df276fd63ad8245beabf4bd81187348d391427e1d2bad4305b97840ec51864 8fa d35c7088ad6161e0 d90 faed9ca f0fd 6e1aa0792dc0937b4de7ca04823f2a5f845865a86b533b33d026e562ce595 cfa76302 86209039298b1398cb5a2f7026cd06c4ad283af6fa557a715 d769f2aaaefb42733ec6d809352e26 86c141839dff0b 77ba42e29f17 0 239594 256721fb3bd8bbd8e2fe92a54d05a6361 f4a72c678445a889ed348b029390 dfc6aa6f 76936842c4898d9f013a7246b7c8d48 26 3 05ac9350 8aa4335359968ecf0ab c4506cd7102bb698d9fff7e64bb41d2b06bbcd6de233a56eba504edc44f26b395e63ade76c 4ef 1 04a42a9ddcf9615822 3c41f179793 282373271b7  b9f6eedab0be039f9ab0957d5 f4c7048 22b3ea26ee1c0e96206dc0762942 7969b29154d0c85fc467fb71496d0766f7ca7aeedd972483e372073a5e 432898b4d11a35f5e2e57501427eb7027 c 492c5b6a 5bdba2b0b990b85eefbeac65a997a5590d42d2674 298fa1a10031 9b1ef31f24941682c 04fc04d286ab7bb b1ecfc18b04b521b57aec79b6aae393b4d62ade793febeb4f3ba340d8c9fafe9 bd1bd5ab23a7d7141f8498ed693 14788 02b61 d54c569406630 e0a67579c9add9a0176ef908834a dec78495bd7172199b8d0274 2 e7246b4599d6321c0c3504e3b3c3d12daa154ce1623e95d9a095be6f75d6ea6cd7cd9003ed4 227e1e488625f798323597486 28 d5a601f 867b652 8cd14 f166392a1e5dde9e8afb6082dadba1 3fd9480ff00d 3dc7a648e62489d3024862a8eca2aa678ff922f61ff 6a8f618bdd0ba 26e66f607fb4 ac667fa2d2b8 67512d4937a7f b559fc74f2369e885ca030f1679495 c11674442 f522d6d0f14cd7a 7d597e5c5a380f876c408cf71d8 ceb564 95014 6d0 63032dd5a77ef2b39ea3470 a 172d3c4f35865c7f0fde9a0d6 7cdb3f4089d4932941818d6de436d0a93edc62 81cbfbb5f5d1a7290ad786562a4ee1 848a a 4 459b806 a761c94f724b264 961c 91d152539447c4dbe704 cbee562448bb9c2 fb 3386c6df8ae9e43dded 2fb85e2dc7c5327b56c0e790c7398a829da6cf2e3ede56b66 1 120cd b2 a8e53e754187 0f8d0d 4137dbf4c133994c 1e32fa6f8c51e53415216fad31 489c28ad70bc2cb649d809bd3679bd5108cc36a20c45c7287e0040bd331 51748f9209e ff1df8142b59459ba 6645a3460ab34aac 8627c33a403262a9259a64fafcf79cab62e4ff9a0da4dd57b725740382e2d614 1215d720bdac 6a150c b3 8f83e961d580da6ce757595a73e6f6ce88 b 3ec8343 7 27631261d 3 7d03e84 08ed0a996 d33b3 149e2217ae35b32a26078dfa51ecc14034cdb78b00 735d7bf345b173b0b47cdda 2106a8ae 6ff6bf93def43c67d285d97f809bf417f499a43 7117c55bba81867bca0c8c330b e2676aa8fe1a 5c3e4 676a9e24 12917925b235588909ef6fbdb6829e1  ec9cb457a0 52355100b0f764f56f4c afbbbdc34d7e9a6c4a6fe023 e224d9 4f 423d12b7594393aacce2970 a6e94230644197a68b9 4dd46de5b  e fc50d2 3e9c2413  12a17d54 91bbb5a7c97c52e37bdf0287e711bbc69 cba541eaeaca7cbc226a2256ccb6c4ac5181229dadba5a8f235fdf0  9c3eea281ee480a55 0f6fb8e8594a1f7e502eef98a d8fdf7a57f9 e7933d3a698ffb9f6ccb06099 127569 c8d9266a13011b97e8223ad2a09386ef4c7 1efe5e46f52 fb8d13a118a832e19b2ee716351ff3a48 01c0debc6d41f494 098d4d61e570212a3479046ea41be3e13d3cbc5c463c2fa 2 67e29b8b8d086 66dfbc24a  1ac421820d293a22 2e5b491d745bb1a24bb595c0abd919a708b8 a3 2c0  95ff246efda47a7e633b7627 eab08ce 7b644b 9eaff46339f c 0dc2a54e62789c58a47ba713 e2d36ab4e5564e07c30a1ff3b7a1b0 69c1935 b99d1470f179c 6 e77c17 89594a54b31bb7cfcbf9969cd57da48ceff77705f841e4b64357e00 0c18713c44f2e8f4a5 70d12289b6 b35fe 7863ab01ea028d4b95840ce0f799240fb41074d15853c 769d618f0506 db3418  9ce1847a40df06f284949c 7 b36a9c 46b9ca804cc a13c be526b 72 e595bc5103 74fcf4be00901785285515ba3fccc84f9a025ec32 78d8944 fe3489c55d5141d5946415c7e61ce 15942d3 2a9d0dd58  53236d5716e  31dc c866 5006ce52b a57 b7bc27bd3a5b75f21cfb777799b3685c0dcc0c90e66c3e51  f 2e7d17b50f8140a62b2e33e7c8fca4a8ccb01603172e73577b8d0 a316cb4468e4b1e0fff746b d39e8c9d60c0e4f2ddf59cb323953d6e2bb0 ffbd3ee2c7a2ec837d926040b5cf399ef2323c3c02f33b28a3a7e04d6ed7 b3f15405b 662 6fe 772 8489 816625767f3168f8fb3 2829de156a7 a732dc787b 598117e66a4f f49 f4 fb 02 97941b479ea6  42074d19840bc9 3dd761037ec9a78d61f7a93db9287de426ae7d15be876b0a9dbf27d8d3ff 123f7a34  ca410c3 4c912e 3f51 f f021 7d726cf6a19a c2bc 2bbe204a b20ad6a8b2ad4d8572 f48a22c07258d099 e848d 723430ed b97237948d396d5703d0c63e72c3faa61545f1364d8603 789fbe47addac5e9c 9 b80338b00c3b84aee23eaa9a900815b 9318ce2e990134a173 847e9d471 441a1cd047e27d69e52ad17af9290 1ee5fddf992a48c2baf516ccff4222067f20ad1a627b8088a0 bd780cee2d1f68c9137fb69f7a05c35f4d5437 0da71f626747 04e23c5a08df742712470 fba62 b 9a99a3063ba bd 7deb55307ad0d736af65095581eae4fd836d26ebec1a4cece032bf2830c7829e8  6867962f9168d6416542f80eaf44aac0336 c87f7 098  077442947b75107d443d962cf85 1fc6ef3de6d62 8f1e91 308aa3de2857 77ee98c97e8020055270c80b156a2bcd132aa748d3b8d22b5ef9bcf4c2f9 41c0a5750ee3b98c369e 4ccbbf38dd 7ea386ab799 baa3c755fd a7 46f62c10 f066541bbc0aa45a8a883 9ca 8 9580da9e5b3cc8c8 de22ab2ff1dd4a08f8397 35b76929e5751ab1e7a6 b76afb7 e9033a415accdb04 b57eeba694f 375e885c9be 8878f4df363b854fb7a3afa69ab54 8db8628f2c67f7e94d0 cdb7a88170e0b80bf1fad6ed461ac5644199c721025386 ce09b8198f0f4c7d5369e3a df098b073f775795c0e4c4b6883240755c 200b381a989fa49e55e6ab09e 71ad4844b 2e9bfbb9308bf64b76292e390ee9 566a18bef74aff725c59af16ee6c35c 8c0 9bf849d9b6405efb3365497bb7 62c19e 746486298de4  be20b17cea7136 636b88 89538db99037ba02ab7af992c83db57 f052ed76f349 81182d308bd19dbfff9c106cb370a6b933fa1b8fa19ba83b26992a0d8a6d8b4001bf88f42ff106edf8d142a577b3b0 df99be328ae  1077bd7 96d0c3047142518fe72b209ca605e ee564b8f7e 1113416059b98f766e37c8f27049280 6  8c82f2769cab6e0d601f48bce3d30928db7f6deea3a5e3822f0e4b796f 1f8c666351 382b51249f640bd31af7c2b1ea2766c1bdcfc2464f2106f081a7fd151edf04d0ecca3f9137112 f42 9 a8dfa2de70a47 81ea9478f24736eaf96233b551c58b710087 61f13ab05 afef03f851e74a809d64eefaa52fb66bd7a2b367ec76647693bfdb8477 2a9f861a6ec50e132682b43 76c94186d28 6a4cb78514 a0cfc302a677617ea432 5b 0ccb68932006c7 8ab69c530c42156173fcbf 355f4faa2b63f0cd15029a92e51839 315410c be9c4c91c1e90c22150e5aabfc4b165f83a8495 d64a8833ba89d7a90ef84de7a 17c8 d6b4c249c6c80c127e302928c988e0348e15e92905aecf2408b d3ed54f8bbeac10a489469ca8906 2a0108744a093 781aeabce 2fd4d35dfa07749 d8d584ce2e 7e0442b7d0097b50f54ba 15a3ab41c4f2 14e1220e6 d41e31254 efa 6b3 0de5cedc 80f459c7f89c11fb31f61ca4e7b 90056f062 cf3f  cbc3860ce875bca0ee546c0 eb1411 430d952fa982435 5dabb0 94cc6eb5d433808e 9  5 bb 97ec81f4618605460d f55b64b7fd8c0d15a60e655a00 d6 24da6ec12   372c6c01bcf23be9808c6107c493214cec 4bb62 fde770ea7430a98ed9e95d1d16e8cb4 a9 cc7be9eccce818777f86ff4d7dbd931bcce5de3464115cd18bba066b80969c5 4e98da3e547ae2b 82a9cb2990136faf49816ce b 41e95a6a623 7 0081b76c88b3383923 aa834d 1d365d5020b790c3ef5ef 93e6fe605fef6cc688358add18f2a c1cc12ebf5c1dab5e3e2ec4ebaa4 40696ee 68389c65eb8208fff5af1ba65760379e724daa33581457ab87d9 27ba 123860  5bd87e6 de7d021ecba8749b bae 329cbb84e3d7ef07b8ac 2392d4da86c80aed3902ac2 0901067193fa54f497e43da38e990be78832c5e556737d 2e326dfe1e16d21d813c6fb7dd1756c39754b09585966075 a2dd663050c2f de673c2b60e8ca97 f39644f5 93c32d 06e7d6016de 8b33bc4701730 aa df  2c7 c68 1ce158573 75b55a3453d3bea94 44d4b8f6d19671501591219ee4c  31cf0d8bfc20e16c6cb6c8ce32a1cdf3ed546d2c7c25c621 9b01799ddc189e98cce03 e9784721eb095c99 30cc0324bc564542da90a8 db3 43b f927d6912e22026 98dbd47c6ddcaf14c7ac285ad72d02420329c1b0d667 cb64ea2de1 595ff15a15409ed3552ee5c851b083bace365d7b 2e328fb4c589d11dfec5416211cbd073f64b367a86   393abcbeb087a3f415180 c13da98d52813774de0a1c0c01b14aad b07c5e8b43d6f6c37ad3e152 0c1a155f3a6 d29a42c1b69c42cdbe2a56a848f84342f076cfaa07af58dc6 666ead93bab544b 27db5dc2424758 6a1f1d885c71 8 0bf70f9e8f ff1e60a6a cd39424eff  0101606fe8ad7bc bdf21bd64e59844bad749f814c98dc5ab9fcd4497a836a8 e987da5823d73cfa3a76 f6bdc7fc222a3b8 120433304 602e2 6f9742 fd7d74b487c 3 e18 5879d740204c67ac2627e5d 1431775aa863 caa 9cc8a4e5b c 376169 9b1fb033f3 c781b2d4bb1a9915811f63f2 356d66 da999320b87147cbfcd21cf4da37 8ba058f2e9f1a3 a600e3473065f3607bf3b6bec4a18fb6381fe50fb4c 393a92c911e8 5702e 8 d43802e 1efd2fa8da 65cf617 27653d7c06 cc3d12c6a599407d53 2824 df782af43e4cecfccac2c4938d04a164 66c1c226f5b25974 a83e7722ece6 0  4182d  dae 27bee7c45598a 317f3d88cbd386fc8d1d3bf0ca93a27b278a 9854b1 cf 736e719b678735a90 89b172101d90333 72673a82 7300f4e4 be8b9607add7abbcbf1eb 9e7cf db7cb01d7 0a9ee4e85dde9a51223928ecbdc6b52 16 0a88ca2ab7af0b2224762b2b5 73 0bb7e335fd7438 29052f75cc2d91abfd33  10f858c5a0fcc89dae5f2ceb06768e54089329574 ce88 1bd9cd603ce83c5 9a597fef e1358d007 8799e4 388e  4112c6fb6c3  f31fed097bd576d65473130823 bf2520f 365cd26b8d0eb1bcd4b351ac3fefbcf 47b7 d916e289e2df2d71ceb093 5ceb13f068a002f760327aac3f55a313db0078b052f0a80cfb12 407aa35 a6b ed50f818ba38819b2aff53df230bd97c4f06 b3ca9 b191a9aa3af8199e66b8153fa41ab9eed30c7caca304c38 96c6022f4b7cce a77ae96e6258a892967ca03a0bafb39e 7f9c8944a4b91e637 d54b04f2c08a1ee 1681cac  3a 32c9f9f 6917ce61db 45e102f3982e157 a2539771a004e 49f2 70ab1d20488f 20934217 d2d499 7e2773946d7d05ad 5aa e9c59eb347595f19c42771f e ea644b16e1012286400d77de8b c9b6a0 8d300f1 05e3f aa e4b71 d34ba06a4609c38aeb4084e275e02e8eab29d58450 db3 5 49b0a3c 314 1a00746c1d0a63e3fdf82bd29b4b8 7c6d7dc666f310d 7c5de4a7 dd3e92ae41cce9d 5214af441 4dd44f9b83cec1d5aceb e36eea4152e127c6a5c6862  0c27a779d 44b2de2 8bc5edf9337802b1 71d764 bb0129f6ee 14dac57d92 d61fda715071f01b87768efc09153f113e83b92be13c399cb221eeac01ed01c15f46f 87bba1882d 301c9b f3e8eb fcd506b580630489eebf19ff0b82f8683ca47 e1962aadafdbe4f33 951e7a5f9f9e29e6361c346519a290fe4015e793064543a7  112fabed8dd9f8e865 58b11d51f437f745a89f79310a638e8e96073a0 3349ccab39eaa2f f3bfa1a4fd814234 2e0ff6d326d d307c20048d43ed73126b07f1db9c0a45637c43146928800a 7b114b9212ffae52b5 14963 cf9100c5d59 37fb9d6a45fccd5b4c603715801  d7e5fb40b 19c0 37a33392d1de4ca763bc6b26f20da5c0bfd665 ce87c 438dc624e9fdecf1abed ebd915a32c1c0cba00cad76d58700e46c9c8a1da 0770f32345d01 7ec543214d9 a 2ee19908ca8a  3fc  9d6406d4b881d19cd92926b29eb4bfbdf999b4abd0a6c647 f89 3ea55271342 f be1d47faa07 5d15358 7e3d21 ffca   bf788c09 a 2ac2ed41b3545e1ec7669b7ac4c0d92b85f3ec37957a323e0a 7ea49ab781bab19ed272df4a588e8443cd7162518299e0161b1 a 9c815d7fc 860b8bcc20a04ac7e9995a 25329e151d38ab4d96abbfd45bdd70495974026 7562 0d1229 f77944 2bdd1e6582e2 25bfd a72 2059715805e0be98e72ea46dc9c6f9057dc8b451575fdc2fe 0e cc890a943eba2cbd5e866acb19d7e f 970fb1459dc1c700073c2b8001219c6bf e3701d1b678494c4dc ffe0321 3626f36607a33f3d1 2d492 a64826646f976368 04a6de 8d de6695e d230e61a29289626346a8332f1242324f5d6347a1603e4b086135f86d55a90b9e98edc344 8c749d7a 28ddb7912b2cc81f2d18462997 60594df7f770828753fa9ec4 1273a58a34172cd3f84330 ab7137b1d8842c7be369 a7bad79d1e50d44c 7d058e8cd 1c9b046d554f6d7fd4b71175aca432 ab 4fc48f3b0e81e271a24b00486473c5e7288 9785b 59b705f0ea9e11c1d325945b55c477ee b19c0c  846b807c4e3ee4024687daa 8ba0432eb2d7d6e5e69 c835b41ef9922a 0627d37a b0e0d587a1391b1 2a4bd a f 0f 5dc9c7a01b138b070a93680a38b6e9d5913 e357e5983ba3668e80 ef8139220b6928930070069a1506622b7  1938c712 c4d3e82cd595 0675cf32f3fa6 b9214562c1e59ad0a53089e5fb89 8ef 8df9f6da2106ebd346f6 64d1162b24 29b96 12a1852b6705988f   8fda43cb88f80deea9bee7cd58dd99934939d795cb3af08a2077a955 5825b2252985190258dffe5c0b3e62d5609153d7 8 f1a864fba17e3701e11ba6ce2a17c7899d7 1a393955fc389f7df45afb739edf50 b17465e98678654b c738ab2cb5982edae0 00b226f3a3b826964c53999403 135a8f dcbf41 2 0504334 84c471705e109a e5fc73a8f627acd3d86f0cb2f4c8cbb62c5b29bd d2f7ab b93dd7da0 a0847 fe8df0cefe4 d1b27a0cf24ad34c6a84a1f4 1b 60 42cc 5d5c6a03 6ffcbe155b1 1a 3159b83d4589de55 43ebea2f03 18d 111a5d 9f1db8a 7d124d2aa337cb7dc56 39268ca9bfc1fbcb8238f71d7e6  e64e02cb6532ccc4f4e1db66609e7a9c818d41fa191d a5cf8eb812affa 8981d3f61228f351f8  4 62fffc3c73d64895a14b468cf65a7c 0f133e232208bd5 7 6e17 6016ade739d436efdceaf3676e1cd8443fe704c7d59e2e7d38283905b99a18004231385a0d6989873853eae1e732c5e4592b16472d2ea2b02 7ff36 6 2dfa35c81bc5998a1c81733f592124b216fbcd80f 9a ee54aa1c20192230bcf9ff488508c045c b13b895ee 651ce0f8 fb58ed5 acb436e421389261c45 378be6e1849c6408c57 96aa06 babce5 d81b8e252 7 069701626f43262ffb0757cbee70540c68d4f77e8ff35183b55807c6d4252c d4873c3d 9775be5 b93e068 078f56ec22d561c8f28c322353a20a1de649 28bc840c44bd551f32e7394b7ba 8e5437 32eb0b 9dfc cfadb9eb 608af59d ca4b8277f8efcd89b3885 3d5eb195dbf7481dd39eb95c75f7 2c753b7c12fc7531e79 ef 1b bec7b86 eb8ccf04 e1811b570b52 540ab532 d17e838 00435be70cb7de1d3e9811a 2656a82cfa7ae519970227f76a1f0 3040dc0a0c4df d28ed2 2b71ee84e b613b7d5fd3  d06 9d330ff085ff817cf1c5a924c0c741e9 b4f 64 d48d03b076 24db1697fb6b 4ac852e679 19037b dc584d776a82b4e148359c10fbfc44e6ce2a3ae0999d9968fc36ccb31c1b9f f 117aa02c599d f 1d720f 438a7e2e6b828f3195a55b59bae7e6a907ed4e2fc8c8b2c 4f9 e9065869383038dbb 1b84 cb985 bc5a5291 d85725fbd2a7e8a565f334f6e1da58316 5e50e7176402b3aad9e611 bc208c0424463db1c3e6360bafe1f3a596ace080584  76f4b3 5fc2b7e 6e90a77a608a680 6d6 9 fbda5f5df77b6e8924  1e87528dfb161d28a 3b68151d57987 d87eaec2b087454cd9599 dd19c16c31 6036ec70cf8877ecc41 686bbd484f1ed8d15b99e6252f9 d65339483f8f95cf368da007f 665d07b71f98 6ab9a45b1f62c7c5a8299 797542 1df53feb6a973127055daf661fc9f2e02de044c5 a0e1d5ad f4d6 669c3ed3 93 d5adc964594d24f6f63ac9694dc1219 c844cb1308d05486a75e2188865c2bd1f052cabbfbcf749a08ab2 df29e6420d20afe3720fdbcd95e30 a9aa36e2 474342257  b304a3c57fad bbba6 90339e8 500ac3f66b366ae90e359b22d394b359c54f752265 f3b74d1dc16c91d5300bbebd261104fa48d3 1766304784e91f4f153f43bb145671e4de8 026f6cb488a381375ef8049c127eab0812caa2ac9c2a0e 3f7075d11580b79c 12c3bed ba7f16f3f63 458c91c0d3 2464e20e0f3844 65eb098ae928387065ff 291955e2512d431421a8f782fba8248e1c40f45c2b140659e6b2 971a687161036 4 0013 84ff cb7eb67f6c80fc2a034f1d06c7571f4eca9c407647217652cc7b4e5d5  f13f214a1fab2 27d1749d7ee4e b0dac44a9f7959dc2b 71 719337edb8c264aeb  653aeecaaa0b79ca7c5d205246b2898b02e0 85654af48483a69ae f4447 55acfdfe3 4da58dfa e1320530d2b1bdded456739d074aaac8d 5633106176cf42f860d77837572c6ae33 c2309a165d9d8b43ebd4ce00eb6513fc4175d59321ec05cfc945fe9692d 16 27e0734e2b61a f21a13bd5dada10aabc4bb27a 549891db820183af8a38f e64d8d2f1 d99a6  7 07c7a1b70f395392d38 f6148c5d59ebc414f6b0c1d8d2 d719928b554554480481 f05a4b8cdf219efa0111 91c4a 5f1cf60916c529bb54db447b c59c1f552224ccd1cab20 d0fe444550bf 1b0a771a57cd76f31de41 279a9c255105bed01da 338af31a6383f550b 119ad 0974a49760d0bbd59885902cf85ba9933bc7492f58b4182c38f48fb4c29256591 c706a8912 fcad5c4665aae0344 91805c5b6 786c0dc3b  591e84f8a1e701353a61e665a2a19a3f4ab3 266e64feb439a096cd8613 5c933904dba 7bb7cd794d1d5 3dc6e aaf035671 a311aa26f0 3837ecbad 4c69db93076 caedf5 1cae2e26 f29dd701801 b300571c 0835187797348c99bbc89d 55a7f7c1c4b6 e af2073b5b44bbe 4 07704e98f0d81e802f16dfcead3864f6 f279 0f37d5511afa9d8793a8784c6d8ee8 4e34f2 75fa93e69112800e4 2bdbebd09204ebeeb18f5058ce958dd9b06fb2730187f7201634f35 38d428f44bf32dc1b5f15472c6dd769da1 ca 0d507a890a4e6a eba482321 059aa2dd 0494eaf129aacd7d14a9f0a04aaf7fb832bf5102af 372ececc 20a924869d41f7e77a108 9936064f39a8d7 0d4787a26067c2e872fe6771452 6a0a07fc967899e6003 70 c2a18ef669e26 25054d9e281b79e5f8a05ea8d7ef845fb89bf2216b9d8d84d1bb57da6cfc381716ff7f3f 465a20a915007b6f1e451f41992009b866a7d8 84a2448f8121  88f6b512a807c9f02fb5d53ad62f089c9171949 9a4a48e411738b 7065910350b6 94e55720b69519 7a4afeebf  2aa3758e112 4cdda9 1f54011e5f3 0a7598c 1633772dcd510dc81726d1b0ae1650dc298cf28f43bd58fd549b188fa9557c96d3d277a741cd175 2f37e8ed5 57a3a cf0a9b653 8da4a  26b6581e78bf580c3c1a086de94217c 7c640d75f04527a84401e16275917681a0 791a16f150908cd80e9ccf0b1e4963 6e88 2a239ba915f5b 159bb1184a6b8 b71937124cf41f8a6e2f d3462e1f9d887dc88a283f3119f 8522de4247a 07795ea6c  bf2cb1b2769ebc03ebded810e dff00f7066152edeccd9a2078075bf9020b5552c622e8dc42bd 9cfc 33a199ac9bcb58d37a fe9328c2d4aa91ad6d 225bc2139e3e 3d76c4b3e7488b2 212b609c7d4daa63faf88a696d830b8 34ca2d83b3829c a97800de40cdb6ec91dc76773bcf 359d999883c 0d8ea78 e534d7079 1f218a0da6c639a39e92d0887f272853 710c1a399ced7bf6 253786acc a9002  8602f0b08bda9820 5d9 a619372b9632b8552e5c74f97e4cfba23c40458cd13ca9c26e9 5 3fa059d6f49907d069d7 f 723713 f81ca1b40c15be 46bf2e93c04e 2e387b 5a3864 77b688b65a9e7 9b544bd5ef072d6e2 7414f21e9784551e99217d3 f8 f01f9c3d56c844e c4 7dc217083943cddb60  0e064be9 8e52  10f62f435b1c780b809285475561261f19ba67 a1f43 5f6c7a9ce bc521d053129b090 9c98bf860 5bc72 f 693cf834  da  70ef744a873c36 a3f803b6 c539 50 77c38941e350c21603 c8a62d f82ae855ff842b17 ffb64aeee4fb 3c3f1f13c14016bc209318b4100717fbfa9c2e 77e830593bddb8c1322 27c15030ef37 a990ad9c4235b050fdd04a33baf7bef7ae81de 59b1434c39 04bb303 1 71369084 04d050636deb0405fc328 25 67d 08987b7 423f214dde007f ac0ff185ed544634c0ebdcfe ed5786dc2db6d8cb9d59db 184a411a9a1dc038 9ad54cd51e35514b3ad5e 16214503a4a25 8508f6f91 82bf3cf078c2be51742423 097cf96dd303654e7437ade140d730e58fcd57b 10c5e05c38fb14dc4fcc6b8d0d0e6d3b1684 676896aa40b 78df91 44e396c0a08ecb 3bed28f6d80a7c77199b5a01 7c504413fd49a11b585fdb7e75 c18bafc14d227ace156b6 a fae8548114d8c3bc364c33c058 f216 b372d28f3 6b117d0fc3d 8 24f8bbac878 8b89e4ccbd1942c8a b361d76b0a2e751300b1d25afdc30b312e638dec8b6d41a3da67942916349534184c9d6eb45b6 96241ff5007 a2d13acafa9a8b8dbde7f0b4a 5158e8336a 0ed1cde2725e8e 1 cf963170d1260be4d3b79f7d7bf1f33646 89a4cb45c62954f4f1f7be49bc6ada3c9d2eb 1988955762997ca 9277e1f1be c4 63bcda32b5657a9c9f909c26088ab71693f37 8225078105076c664c383b402dc61672e0eb4c87e43fa8f69dd33e727c0c87d52f8c2ede4b1b6cbf10ca3002c57b8380242a14ec622f431f3ba16b8f27771ef89bf 3f95915d5dee16aa4f12531b 6c96a42a2530074a3 b3264a5e2a27ccb 3f3f1b255b4e8e9134ed455365d39781282a43282db052543 969a78d7b 405f84cb609faaa455ec 93c805 3bec35bee5421a30d3ae4df6e5e90 9d0d2f7 d38671717e69860ba28481557179fcd896f930064c00ab5 6 75f0d3cd5559cccb48ee 4327264f66f5fe3c201958b5140dc16c9eb  f1894e09a60bf2f4a2ed43b3a063599e5148ff7494da38c63bfbb cb5224822f622c3bfe886b4e1c63658cf55a49a e987a6b6bb19dca bec1423988a5145 7 59ad325da6de9 a7d2f97e42c07346b8fc7c4 85 f449519a14ab78a09a11fd72b4c4dc56f7a7e5a5 e075ab535702b07ba121662b9a6af fae44 96282a cf7 0dde555512 ee095a0e 4820fe4105e82322c754544b85717 ea4c68dc93 00bb0d6569b84b099f3a659d3995cf42a2953084 3e5dd1685280 fe5990c56ebd47c6451c5521144d2a7cff6115a3abd1c7eb01df4f9c054b83e69d0822535de71d510965 8  7554a2dc4b0e7631d   752 8be326a2323846c90b19d1 5ff2ac73f b7a2bf51f2b8cc ae53d88755ae732bc8079ef e06 ba2a0d577592c 992f1b8b054c0c11 a5d109c3928 d1dd7170fc996 c9b35f62211e5e223  8412645cf26e54f e2d62d63d4ba5f3da8aad49dca556e 15c3742e9fe16c6d 9b44d5fd6f97 1d9831445eeb29  a3b9e5d 5 56 b96e570 2109722aae0 bea08f5503eafca8ad49b68a0aff792e1882865e85c81d09 70a7f23ac3d e1 fe2d83 ff8c860e07e0d4107cf8 442831f27e efc41 d62c64a41406c19e2bcee435a532 74d 032f3709faa 6ed e4ab16788d10a9 5b0ef056e909373a6369b53baa 83473faa5a f640409d0efe60617269f7a e9e8bf25 f  cb92cf3e2d14384c4cbb5f68219d87d4c8304ee6a6bd9f0e11fcb b800a3bde2fdcd3827d2568170652f4041c77d35a9982ce6d0d69b3060cd3ad9a3 88 a22e395feed5f6e34d7effcf74015 2efb618377b2618770339edb46d2ada76dd051492df b20b5864e 216565ac7edf953358a83fa9e7f734583780870bae0b5769173d27796 bb4ec201475bed3fa5be2cd3fc fe3d8d6c43b517afc4a12ed3952079b8fee607946449ca8ffdc6c45d f 946cf4ec25508 bfb62e6f38ff1c9855afad8d67b38 026d2c2e95 62dad9f51a4276232c3c4306534c34509c3bb3314a56e29d01ac2 1ab06c7bf35c6027b962 4fcab 78 b9bbe4 d8dfeb9d7e571 00150ffbf9b98 508bf47dad09a4a602307728c82c46adf8d5507fd66d7f6abe3ca961a661dbf5d52f1 a1291d201926abd620e78592c36ba93f213634b59e89917594be7ade9f5b0627cff4 c13ab6154028056fe0d4  c4efc3a5a9b8792c 7e8523e9e0636e68d0668b2381c6462200 64d56f1b5efccc5973d d1153a37d050ecca249bc39bc357e 20505adcd3 731 d83cf6c7458ac9107 b9 a46 8d2ce810b5f281f7dedb e81851844 71be2b e353a0ccf5f52a2f30a183a8b17c57c93d643d422648de4a30418 6 0b448047f9b1ac3f526c3 b90d3f4dffbf14a 7be c5952681b0ccd d17639 0 e 4 bf332d0849a e7e8f22e4adba58a32b55b3ecc364a9c3af e6674df76114971053c29c698b5d36c 5338637a0a837205ba985630817e27d 16405ce0d6011afc5dc177705ae2e038e4f6ffd00c251a0549a1d05eb6e1ae2c2f045f2f468d 4863bcb588b a19c94dcbe 37 be393833a99a8969f 5eac ce6d9f5b0e0426a11ef3a67dcaa b5a2a a04b13  971b710ec7a799ef7a3ddeff5eeb1564b133078ca7fc7c7dca ef4e56324d38a6 0270f297 5584a07dfd773a83bb23397fab6d62bfb9d24d1d8aa077bf 2260dff02c839a20d33 f56a2 8c9c53a49138fbe8fd1f6c2 2d5dbffb37 87687063983e3 7445e345 33efc97a1a606218ebebb152c4299794 2eaa5d0c42d404463b403 4b607481acf4a 66acadb352f9927f 791a6be690 faba7 e235cdf56e 228a765367dd9d5df640bb0c4366b7cd3e7a116c69259d5 e8abc193f41f86ed1d7 65f8 eb352ec48381b651f 1d864 e7bc1e92530b976c5008f6e0 7854529717fd86a8fde64cfb4fd5a34b a 0b797f9e4202 29005d527b876a92f46017a9c55c35fe288af4c9bdca cb1440abcae8cde09a128929b0ed595d5be7 54d0c5b336711f 180e4f8500f45c36363c4c86b62b3f7480eaa7e31191cbac  5e 33f 52094 3bcf1d62a3fd63eb7e1966e57b10ba04 9c8394f9c47a50b6b31 306f2892a66  73c33b8b77 7a5bb98e8de31de2fa32361c6 d3ab efdd98889bc872b8fe49ba8a693e702a35 b9 4594f926d4e9ef8500fd16234f791 a90f7cecdfcdf1 8546b1ee3a3049f0572d32d9 af2c54a4b981d5f8a4690588f 0f76aeb688deeb5d54f1556efae76e150816e60bc0f79c78a447dba04526f6206abd14 9cbe28be34081197375a1797061720055038fef4f884cef6afc4ad4128f9abe4e0c663bb693 bc0cb24 77e3 e3b9 54f75 7a768 8a1d394dc6a  027629e600c6e6a669b73ba86 9ea 85bed5c4a305e60c65a5f6a74cc f2a7b 609d21e07ec7 6c9068 cebd 1e6e95d6953ba7d 9d880aa8f405c187650c5828239d7cec53dfed2b7d72 279741ba6b3b1f8116ed60fbe8118567898 e55b6bacc4357 1e4d7879d924512 f10 74fd1f a1152c080f13b 0c94 fc4cccb955d21653bef260039e9d9 9e8c6952d4d51e0769ab154dff99651d6 f187 6185caea131946f13fd73cfcff256e1040c4 25e65 bc25ed2e331ecd7ef96b0492af595660045da2b17f3b427d671f1d43f9f3a1aaed4b7370700cfbb5 c3f31dd8ea77d071f0079b733118f6e9a8cc7ae3d4302d1d4e3b7f7b9 1 189a966f2d10926 28f1 22a9e4970bd 18a 6 c5eb8a575461cbe142 a723 128705aeee fc0c0dc99ddcc3bbaae5b2ecb  d8b355e1e8f f596ac410ec80bca498ac 399ffff4944589b6ede76fd c5c90e340 91 d19656d714c35 6889329553d1a20 c7e9ab88 1476099f7e62 d7 3  2f74b05b60eb394a7b74d186c2e24cd9063da1424a07f766b84fff137795e22197e3587121b888ac8c978 3c27d387a 6801ee8f394c94218 c7eb94f028505675d88fb35478922 1be76e46471f7 e f143d74ecb5bd53da40c6306 8d91b93e8d362460de9c 58a6d6 6e6e47b9ed1c39cfb97204aa2beb0cc203a057cd7cb4 3f185e5e a0a378a01993b349614b3f3e6d7d4cafd31ae90f54282 a92739c 3 871456d852ccec6e1556df6f b9843773dacf80f3bf2b8a36eefdf4aac 5effc1006e8 7bd5 062c138fe2838 1c1e893 f079a b40ea6c8 3b2cfd69c1e35d0efc0bad4a3ad 846fcd40d1ab5627841b 9e898e6e97fe53aecff113d8867a8c c1ad8414dfa2f1e10fbf8 39f86371809af5a163cbc31476c06bc d1874ff5 1d63c7 45d6b d3256415 7d b3f18e1e7628333ddb 5fbbfeb6c1e1b c5144f9443b3f 23e92b123031f a369771 4b3 64a1469 56b2a00bc9e29708165bca57469a7c 5da217 e5751c9e921 a0259af5e15a5c84ea9895dcd8c9bbf2a 5def65ee950d6c65 b438a322c20cfa666ad60 c3eb080a36442b62328567 c2fbbe22f19fa2cbbdf4ed 47838f85a 0305f714 1fe48a8cd262deed 8 28416a31accb4 1c5b8455a 4510b7d95 0674f7192bc a 7 f304e0c9e431452459f52a48fb15be36fa2e5afe25 fe922abdd751039e44d1130c75f6c130a970f2a28543 939203896632 b7c4e1d 4 c37296b6df7350c47a6738d46d5ea46583f878342340e2d5d1620ae9cefc 137602529 2ea9b5ed4f128d2f8802e4d a72951df3d792d3ac04e1b0ee6cf6aa5 c1a f5 ff919 f8c e3ad7bac46f223d8724c0f8f511e40e83ce9c8400070fe94e9b0f8d7 89c3c86df347c83 4f7fd0bae890ef84e871 1 14510c85  410872 e62c89afc2c0377 776feab8864c6c75aed 31 ea1a3960e46abc188f808beb1ad31548f51a6 28d01b 851735686 8ea1 faf3ff601a0090dda6b296c48d2d5b9495419 04ebe8dfe72c623ed7c8e7db783707ce08ed1 3e6ce0d16be03df160 9078  e12ece2a72a852e6e175bdaf afb57204692e92a5af4ca86576d74c0dbac76a1cf26c2327ca68ce69b2a3bcf61a5f78e081f5393d0fb58dc096561ee81f5467e15524362e80c982f929bfc1fd966207 a15d8354c598d69 5 0cbafcb03769c82e4ca43472c69dca9 5d98b71608c45 d010 fceea7bcac9 6c 78c068cb0e7c989760ad869114268ac810304556e14da049c7fbce77ab94 3838720950a634301 e 169f6a1efcbb23807a2 6d9dd3ec24197dd a45637de2b540c251a60e6f1 72c5915f1afb68e9633ef66cb64dacd0 eb73f1caec3093c4a5f32 3838672e39f6a09 0d8ad965d2c4 b90e229dbb0a4a7605fbc18205de1ff4fb0 8f461be79156c24702b7ba 74d4106e82acb03b77913a2e4012bc0c54  f8013 27 71c 8b91288d842570235b2b5aa2a1172dd88cda4d5591d66b759f54f8e9feaac58383bf9e ecace31f1de28a6a 01f7b6d5f55b32afa7de55039a1 1db8ff7e9f336cb100d7aa3ae5d505beddae9fd6ee98e1dcd6d0fa002f27ca 7162302361b3d2ed032f1622d935287ef 2cb5917f197933fe651472f7 8e90f6647 929e14a040a626540a453b 972a4df 42efc114dc a3 0b13711a068f8e39a1ebe0a7f0ab0c3e9c20 94c51dea79aa42fda8d3c43630a60c4 e2fd2db877439  10e98b2550fe5771435ef94c860b6d6172c4f917ae9acfc2eb478 f2c27 5ecc5f5807c59be124a03cb 6 ac8c544 7f3ca9666154b5 4b89a562cc5f6158ecaddb46dfc78bbc517e49747 0 28d0 87e 5b10ff8dcce5aadf4a190c43cd0fa1328324ddea82875bb124747cbf44d109 2e928f75d5974e edfc4fa8 76c2f28 1b0f d3228e585074c1 bba72a34560cc831 bdce2d1c5e9f9c06 580b33f2d003b69ee462a989419695cd5a5 6c1a399813b 7f8ae8b4178a4c ab06fba 94985c138ff5ddf2e02115a26 603967c0998e1ac2 f146 0ac4d2fe933776f6ed5beab667687c1c8e21e48ff 072dff343bf8d36497d1e11ae310 1f95c990ba9 aa60ea6031423814af8e32 001962295d5b0624c2efe 3e26f0a0 ac96be4 eaca94d87358 b4d9c9462b140353875 c0d06496 799b6a7d7f9886c e70eea961a20eca79d8461 1 6709333e391f82f0d4 2728d9f 911b1930ea5b7e9a22078f5d206021e9f4a3f28 0fd81fffe11d6f3 88a4fc112f2609ec6b18a49921fb ac568 af502b1d9 6 69ba8d1e75 0592696ed72bf5b53 487493dda1df1fee76d82 6 cebe61 5a8fb2d51206c  415396fa56 676 6bf87d9172da27268 177cc18bb74d3 6491f39053b91cb d5c46d 58d9ae4a 5451bfb818722adb9fad5a8 1af540 7c0c6627a242f27224d62f6 569be7910a105c76336f13520b3 cce3282aa7a591c8140 17f88d7 433f8760b62beaa55 ea0928f04189 0d92a7be62d f21686e6c1c339ed4b96e2f5b5af1dcb462fa54ca850c6af7 bd452dbcf500325273a4 6fa 929a 50e0e4d6a9888c8da1f731 a5e 5363eb4c50fc0655a7e3dc4e70d47150c6d612b2ffd5f7d375817e7c3c3a34911c609caf6678a4850c84d859a205d 81c768 4b47 934 526b32e 8b6d6edff 96c01ef 2616bfe b6e e70 72f0fe9 20764e8f74760ae85   19ba2f8a 06cd12b1b221498e 8fa727c0d7c7674934830c70 dfd3d63 9ddfc d8ccae2164b8d428f34 7fb3effc44593f9ede 9e36 000185054f1220424f6976b80ed4ac3a06d608443ff37d8face 37327a68c4b8650d47c5d5477b 186d9 86945c1416 0f5156e6a3bd7bd77ad5 018f093f04b74b92a9a9d d4c6d3 7602 ee 907859597dd 23420942ef 9fb10f1021ba6366 a7ad6e92493273b087e238fd 118 fa40618473196b363beb2f81 c87fdc022391378f3 094053e0330627a975e 243  c9eff 93b0e0e3142ce56dff 26e449896d71 a5 768eeb769c 0f0a145e6b15fd1066fe625525947a3 a106ca 64ff2 c2f 55dc0fd83 265097200 77ec19018c604 8236637a99ae173c9 97b8804d7a76fc3d92fadb71b2635fb8dec9643c2ac8fd e33d94a3a702ff 281e4f26a 9c4da0c1a52b7610108bab43e308af80cc 822667745fbc5855d74c87685e14f4 2686950a68417dd 6 c5be8992fc831 538 01fa 0be28a4a7f 8a3451ece82391ba9c08a7237 b96fd8cb8c08e21a2380deb8b7ece0 cfc7dc2c1915 0ea23 ab2b c1e4e2fc7cae24be8 070079c798f80b f48819ba941f4e7d13b6b38498338e8e1935af25af6d9a4c11f81640adbc484510bba97eba03 1e7b5b 9 635d170fc84590d7178 b5340ec716 c511014128153bd 09c7253b5a f186dea7770d 65ff3c5a5 ed3f338b04f844884f192741a3b8953ba0a4d 27189e9364ba6b0e1e4475f 7 ab749df058cc64914e0e1727a6 b3c0e 11ec3a12ed856c41a6 53a 9c95cfeb725698967131dcd7bd0bbbb2fc29ab88d3bcd19788d103 08 4cf8d39e72c9bc200dcee1208512c80a 0954e4bff916d1334491d0efdd5a7 c40cc 2569ac28fc5ea8b 5ac95fae6e82d8fc32898745737 115464bca9c62 f821fa000d3 147460b4d0d908d274d1df6b33d b7501e1c98728ad143 8fb9555bb05b654 515b5d6f786ea6b3b66dce3ce0ba8f7b27331 d1a 3ca1aa613377  d cb8404d47 a61b9954c27964bbf05b9 dd4afd6069 8280a2e 1541c 7 df0f3 d518af5 66f6704cf8cc df 29c66 e e77696b 04865eb2c 7886d046cfcd 58f54ebeca69694af41dff1980fa09f0585ae62e2749 0a95986e681e596 9f2aec2bd0f 554793eb8 3fbd2da5 e1c4f68660b0a3c618533de7e140bd6deaccb97 dacff8e e71fffb00 2aad3d4883eb0b058476fe0fd22e1e700  211e761ee0b9420ad1abb3d2 c6a0eb1b879b4e710b8dbb 81fd4e6ef6533 d f39a11dc3d1adbf9daca3d fd25f782ef41bb4522abeab0d6eab0efb5cdac6fe0c90d6035e7d9332b 60 b41275ef1a3f8525075006f1c53ccd95a3b e4a0150fc0a3254bf6e0d16a53cc4ab3120664fc1ed4486 0be80 ba128aa0e3 d494aaffeae73d7 2c3bca45120811e2 71ff6166a695e 39ee30bf2ac53c93909745280e6f5c3 ff4bf416c31f87ec3b12018ac 4c5d55c8a02b68d05712e6bc7fd4756b343a9da64b 242441ac bb8612ce98b412398627a4fd95 38 667ebf1175d7de77bca ec4 99b4 7a24ea3 f6776 c85d684ecd92ba3e54e4def2e55e70f48f ed0908aeab81 052c37c7e3c8018becb019 a1 44503e50bad5cf774408689ce3a09d3ebb9c8dce978dac368e 87cbb80f3cf1fb6f3bc4a8f f3d673d9907a4a2e41ea1b6440a4d2 0ae37 39e5748218ec8aa20aead2d6035c052ac6c73fedec368 63c5410a3a486336c0b69486fabf3 af64967717f97b789d3b4b97f36f511b02e900073279c 7961f 3906880 9b3342fcb2de 428129bd3f4d27f8753d53a07a45d9a185e0e3468 c9321bc1f2f978e9932b98dab51f a7bca 07e4e73aa40a4b036a0a7 9bda7eb349994aa173c1f aafd7a8 74c78 413f98892560d50ac01e77b54432831 444 d1f6588d58b48d754fcb0bea5 9efb7ad5131a 1f32ef957d6942de 4c56256ef85a0373bbbb59ba1899b2e706d08d5810d98125612de71342e2895680445a64a0460 e6be6f85a473f3b8 63131d9 93f44e74cfc5879ed66 b81b48bc0 07807852353a b98ee548a1b9032bf5633fdbdee93b6db05 e0c4be180c482 d816 bd1988f7108b56fbceee 8987e08270 5f3e9d9f 658b1c2672fc544a071eb 5e4373bc5 f29a94a786 a3219ad7b71ccb e9a07b17507b 19bdca1ab68b7c59e56ebf4b02afebcf23434 166236d87df598b74a5a0b  88504621accc2bd2a117e038ba9868a6922 bcb 0e2ee46e3ebff626f e64cc424c710b8f808b1fa03e04cee4e0392059698ab2fc 7af435e3d22eab83ae58 73a1d9191d7c9f661a6690d9e 5672 2d 825006898085b817b3066e7349749f42 f8d49a 26ebe465b9f3ab33299d1d5672 5f7a4e3998bc7152b6c1e77a42e7ea1178bbf536e4ef16 10d516fc55a0a89c 3b343e667a28fc85217046939f92dd241c494606d3b7e4f4d74bf5c786020c070625655b11 53d89286 96 7b15ed5369a42 2343da7bd0551e3ea7d f 8c30 ce9 cf4bc59d87b54ba1df939a5a33 81717bb0d905361f 51a8c0ee7fc0f594faef46dcfd3ec 2 2a2ec2193c89 6d80c33 accd35f8054fa06e4fe21366e 85 1d0ccb98521635d0a747f1b8207a797 ba1427ed5c46dcf83118e115a04fff680305d1d1c26e 2d94dcab678d1aed28998b7bfbd93c8afe71496e1eded36715 721098db8e667 ae4068305eea 08 3912a4f1ecd56 c06cefa2a10c88ac204 b30e92635e546c9 279779016023fe714 1 cbd1e7de5daf01cd21d3b0f311ff8 3da38f2a5771c25b4b737358888d63bb da593b796a52e5b7 7f2bed 23d4334 de228fbb35229f3 05b2b2184ef280c4184ff4 fe 6cc59ac443 e3bca83bb1b 31b78b5c3c2ee10d9601ab2c156a320f2b2faa a817 fd13a19579844f8318 3 ea096e0e7eb44400f9eacafb544c1c95ce857a 4  d04b70c15c08751a7811fe bf81a08b4a cc657763c08c82a2 a150fe84809527c942e95bc9e229 7 93d1591fda 14bfe f  64e7ef09350f647e1ad649cb17337719eb5c0788c997a24199919b75a0ec76a8a79be56195cdc 91f66343cdfcba389449 dd64f3295a8 25314d8bacd2e78d391591114a029a73c43c1 ad367ea42cb61513dd1 63d9ad0e601862ab7b162509679dd5268ee9850b1b 2bff532c63ca6e7c77afa457007015c84f230d483d81010e861 d1ab46c83891e3f2e0def4e6431388b4fac7809b125cba21256fc296e72  8b9fc25479972d029b7 008e836db7d078cf e0bc71515893a7fec 3e577e 66da45fc7a01f205f4a 9c9138832afc98eff1142480a33ca61eb7230790c 0b1 e41  d573b86c8873fb44055173cd0 9176845f6af2c3b5c4 b0427b5f d d5708d5690c6329dd52ec7aa96816c9c1a5c63a f010b0ae6 af220d1541a 324bd99af1cda6ac 55106898 0086495f91087da19fd1bdeb94677928e91 ab818f22fa0e3f952b47614eef405b445028d114591455b6054b9ece2e244acbd c0 c481224e48af8f39b8 230d6aafeed 929059 ca8ed3b5ae77696ff15a2266a57f0 e1d57152ebd807641196e3 6833b75b61c68ebcdea6091eb300392395d4 3e7f3f818800b9a66deb  0ce f090e6c48aa57fc  b47d98099cf2d1437e0e4a088b9a1049e5d3827 66d4804b542be76c55c3ebdc67dfd62 95c b5458acdc941 3b88 1fae296f8d7 057219 c754e902 bf b c8a1b81ce7be48610308bf867ce329a6c8820b2af680a0ce07a6964d 80050941 c7 17277cd 9cde5524409d1d7b3563c8bdf9c d6e7 88cc3db 4a3e63c33edbf 7b1cfdbbdc49aebf94dac6 14 1fd1a9f8db7df e5c9c1224acb2084f ec52d49269cf1725ed1ebea797d5beb19b7a2d64c73 2d516557a 5 a5cada8120279521  efdca0b840 2ec84a0 05cc4f5322493fd382e1e5976a8db020ae3dda32a10ade57515b06f6 05d3efb7d3340d58a33 5ebf583dc6 0b5fa8fc3389 e1800b6e8061b97c8190d8c555c60aa815b55d28a 17e 023326ad728 b8f5c7385 bbc5 7ca00d4880416 0dab 98d9 6877 25865437caa8139762c80787 ef88f b5  d1383c1b 0f066032e6 3e75e3a bcd78e5dbc82c9d055f513 67c2399423b56445135745f0af 3b58014f9edb270344f 8a34a7ffcdf64 146 5e b1e9c87229e59f 665c2c91f5c803cbe7f54e623b02af2 139 cd6eae31d479894828b947525  3a27162885e5 dc32f25ab03a8d5e31f66ad8243b38b4c5a8 55ef5f452c530 a2f8b82746c0b48043afbb0c6265aa52cad2bdb9325910bd2fcf71d5b6a42a938da489ce4b1a6d a408 47fd5ed2e4c9a3cfdb9d 7557ebb8bdc6a819c6c9d714140f60694983fa7180f8cfae3df89ee2d36f997f1d48 402 78 1087c bf 1fd1205d149612e55379fd  d861266cf2041a90fcd0f53  d907a1ee4d44b0854c8f87f7611d336cd62d77516b5692af824cc25f66196bb2054a5742ec07c c4bdea1d0f 15a96bfb2742f12e3197535ed7 5807ebfb0f8977 e571bd8ef  d692e6b83ed16d8 85537df7bc08ec 1f5e0d090bd8649fafeb6b3d8b53a3a2fdce27cc971 65b44acbdef7ccf3d6b5eceb7 b86aa7a55d  2 79e184db389f eea4eb0735a17026878a144cec9a135bf28c3b8b190fb4cc 1871724056ea53fe2c2689e 980a c36f96c06105 8f  63282f80b81 6384bd1ca2f1 aae1fe8e6aeaf58d3ed8e432bf7 c4a87bf13be23279 9 723d10fb ab2b12 bccfb f59ef8cff93280e5d36e88eebfd1e2 14607a5d9c17e05b3a7c64600 ad5f68c9dda3bd3f3fe3e2a03ef69ce8b5d5eb657a047d1e378 11 f0 0b796389781a3b59f1 071 27 8545d451ab8615f 7942eb55 fda162d81cd1165be2e13  42da2fd29678 6d542207df1b04e78 f58e8896ad291be81b7dc91a9c0c41a32f3 85edc26ccdef31868d92 a1eb f093f95519c991b1e 923f7e197 f871bcb9035ec8 20ca51  5ee055b7366b 09b6a5 df6fc5e41f7d9775387ef02c99 b60d38 2c2f3e0aa4599a4cd3dac6f24092 e5e6707f40fb9f9eeed0da55 a 4802 b74 fc 46a12421de3f 4b377aff22f4605e94ff0a de11fde73b68d234f cc6cd4281de c9e9829b652c78d5776 1f7a4ceaa 09ddca7b14b a66512804e211f96bdd7a507feab 4159aa312b368a5baf73acfbc085eb3b 8be12b8621f25d b2 4aa84eb5 cab1331307c82e9a5db 54cdf4a27a7366212d022338b53083a3cf5e9aa171d3cbff4 8746dc304ef54dc8bd2501d ab0f73b3990ed f702aeff1fba2b 9ca271ac0627c 3136 fea250a6ada4d8 c3fd5e9143c d1 87c78a05131514645c2  65c6c   fdb32e17873572d799e6ec329c8950da2c3 ce66dc a67b06d9345e7d6b38a846aebf1c454ae21e9a1220c67f46d 1b4d84d  8231cac11a72e39a26e71faebd99cf3cac27cc 7a5a 34383 c05 076c321e107606ac0be0 655be17a1587a1f47f243f1 230 43e9298f7f038d0 8399 0f60bae25 3bc643423b9ba7b7d0 b4ae6802e3cff8936f4a6e6584 bd684 a9f2cd25b949c25b4c02b0e094cca8ec6a9ff8 e19ed723a9cbad96cfdd19ee2a2fa9f99e2d8a178a 0a5c08a416bad e2a967aa79c1666dd73c4879a8d8ddfb8b02474bf4d8b326cf68f2f2b8 0 81c01fbc6339bb49770541ab9a0b aa afdbe64ef1de75de4f74a197a 13521461ea4 0efba9704d7e9a3 8a965e 69a8a32e89 b3bf59 2cb e3e708d5dfd39e4ff0e638f90e dcb88851e9b9b405774417180913f5bf6d6cb2dd9 686fb11 14b4cd12ad3a50af5bf 2c7ea2bae80124 564aec848000 96fff4f7 0d40db  1f40c1665f385c3f45a8fa  231c56aeaa685bc8d86ac83a2d352dcc9ad866cbac26b6ea7e64a66 2b52da872488a86f81a2733 f2f42de4443814c24d2a393eb158fdd243b870a98c795196c0 2b4ee49c 3dfbcb9568b7e25 39bcb3fbba39 6a 59b9612c5b8ff1056cc6a9f6e4bb5ff91d585261c31e00c b4778db2603e89f4a563fdab294bd0887e4 18 58c5d2c71a3fab440c 9b437a120ba179a740c13402303ac5b 415c2afb8ed 53e  06 50491217d 7fbf956bec4579 afec5bbe2e4d 56e9cfa 04d853c 7e0aafe748 146ad7d5728c7025a9b2058 39a d 8703 7961b7dddc7  a4ee8b4a26709123f2a17e 00156075fde73c4 bbb50d  e02d2d3 8bafd81a6882e482cb 397f18d385db3dd6bf 91338274d4e7 87e4e22c06e394707b02cd59ecd588e89 dd0 0bd1351055699da697d822579844c56c1e7310250e9c4 b2f16745 3  9fd5565c0bfce1e7436301 789c75 12d08d42ddda84 9df3a1b491eb6750365c 664 530ed35 c697d76 d3 d3a180e2256 700636dfb 87db88585d3d9c73403 e5ec0605b2a0f bb363bd43d7cd8babe1ca138957e057fa1d  5de0 7bfc ac2a03b2f95f6fc7f0182 75 27cf1eec01148 5c17c5 ca1ec3180933e5d3f4d 1 b7932 45ce7 cf50b014fdc59de2f6fb1e759b3a9e 9d26f131570fdce673c8d3756fb13a2859399e0455def cc7 74e369fb01150d6a5abace5abe7823f6adf060f 8e226f2bcb11e8b4409e6f8b22110648743160a1 00d49065f2a8757df88d3c7f9e9e6acb 358 4bfc953acb2654e6a e4d48302e07 ae7218fc 8ca06a845a111e8f9a9281c2044 2 9c3503d 1507ae541a7f3bdf04f0cc257bc77ab93e759b8c078270f9be3a2db7d0a2b0f423a05d771cc6981e6deafd0d49eed e09d3ecc1705624ad277f 06ed76  8b 0c6 dd3 cd0cc7415309e1ad81b7e4be3a9c131f5e5da775daea3f7679acd04ee481 a407589e cf803bab3bbe2c1930b019b709e26723bddc8b4a28456b9e2f9c9d5b697a71cd895b722 9761c14f489 156624e1c4d3827527f95f 278134379a3d7ffc1 bbf63e37f507b561cd94d162 b38c923e73 c49d656d 6 a d0636e94cf6a70a4c24e c969a718bcb842242bf8b2ceba19982102b05266a21839b44c17e2e45d32dc4901e 9daa0461fd0ad3a0a60bc42d711f9307c 5be af06715937cc97265 dc295cf b82be72c4f48151a0546 fa2ebc7ee5bdf6a14c389dcf4 d094867bb4a8 76839b4c89e7c5d1b8fa f0bebf8e8 703a10834655 b5fec9ba0a1ad9788347cd29e3efe fe3dfa387b77c5ba3 2ab72707c681 a434c2960596 f3ed55bdc3cf6775dad4 5069ef9efe e843cbe7160452dad03368df94e13af34 e879ebb25d a979879a5b 38fba3 ccfcc79e04edfc8d7ad018272a3d9137 5ef5926400637 229ab7ad90dc 328fc0fab923434d25853db5f0848e1544ef97de 82b501450a222a884aeaccb09002a32c6be96 7f137aa59cd24 01 1ce815c027930b4ad3c4fcb2fe997923e  adac76eec d7812a50b5f7f78713b10729ac68b16e86f2d8e610040597c2 35e5c9ac0 84921bee5a45c732edb3a41cc30dd93977dde5c703dfef70b9c0e36e4 040deac7877e56105fdade9fc8089043 18699   329f4fcbf13eb56677a5c8c77b36921da0fd79a24f35bd430c02a1e4b3fbb4e0aab3645a3623 2b21c4c6484971b58da32 25eb7d908d341 890dc 1d47fa5ae372b 22b6c9dfd05fded32b5d2633d69c1b 55552d3 0dcc8ad23efb44bca964f51f6c16482d65a439afbb074b2d8e94b7c763910eebe7d973e84b276fdd6fd04e4e64bbfd38224aeee087f0a736b2925ca755f7 07d1d797b8dddb91ed266de325152f9bb3f81899fc9818f386c7a27234b40f2b 7e165009aace04a9726d49e1c2497ef6fedc096f9 a4f7b17fe8cecf8 7ae66877f6575970381d06a80dd876 a09a3 cc11a62f6b8cbc6c902b94016a573353 1c51197991a 81c08edb2e051d819d646 2f7f26db95e5d5457ef 83ed207cc4f0f80c0914848373f5d40c83531d365 3183e84f963f85a25 c67ada9fd34a3220de254608b78276f1144a9  17540a0e4786e b0f958d19716d4daedfe5d95b543e 347e5237aa8080eefbf46dfdf41b bc45 406a24bd8487319e3dee3f66ff20090e60614c20428c34bf6a25 1fd01 d9b7604737a9ba1d625545c956f45db8e4e177c9d7 75e82 170185c4e8bcbbcdbcec091f ed042b28 393bd7f1bdf5c5d6fdea03 3978d592c619268f35716d0 7 65266fbd85b06ccbbe52dbc 21bbb9 3b93e849a1a71b6585254caf a 203bf99582fea1d4e22 b596bb be50d8f4d4df79db58b76c7889b7c49b22 1acf 1184 3b7b0c 14259b8c 14 d1c6a9971 80f277b881891790c8d36 c5c9659a4bc82a4c991bd071aa98087c6c249c99739aa13a 346c7891017425eebfa1171101f7cf b 8525 e201 e6 59cbc7792683  b0d8 d9 368125ba9ebc086841337a9   0 38246ef919f12cb6155e  a 2510c03131d822 f6b786f2d81b8ea06cdd1932751319462602743e9070f 282a6afce43302ad5bbe5d2d655d f830655bce7581a60cef33a147c647a50 f27408464c530c2239359026220aeb982c8dfbf28d9cd57c6eca8e5e655ae56a244514e7 15e127b62c5799cfab 8 cc6f 594 d42414a6544f1d5f1de49e59dfe0e827c31e494a973cee9cbca65e9a37c60cdf22f183c85 248e22bcad736c4a57201a0071f3a52be32049d06c2f2b 024d0640 7489cd2239b8 1c5cfbb2893567908788972d8cfd56abfa0635ae9621949578 b40c602be32f938744dd55e84a9  118e84c949d 1a85f4b5bfbe89a5a7ba4bdcd5cc4aab59a7d959 f94abd2c8602497d6709e8 4e44f9bdb8 e8751ed2 e0c1b7137792a60 26fdc6cbc900cbf801e5089a8141 082d016790f 7a24f20f6e70772ec15c8098a167f2ff183bb5b063556798f0461e27cf374 3f93f2f5c9c259f 736159ec  be03510578272a7c38c8129aae 2a3823d 4161d 6866d6d8e3cee 7eccbdf f4f9cab 56331e 351177cb 809ca7b43c2f13ced03 da2f69405885c0871cea77 f 63ac7fe1e1a031c1ea9b1ff11b930b608f 781 ef257 078532e53c1b19 365c43038a 7cb620c5c4ae61d3acc5 a52516441 eaa0065f2a3c0f 9f47b4dca92b7b0ad56bb3b  9d602c8f3bdee38cc9b0 0 4c22258 5138c792150dc72013e94 4302b 4ad83e2d3e832d1a 1bf8f2021af9e024d1640fdc8 964558b2b9b7bb7 b6e8 35 ae2f2bf038cbef2 ef3b6d39795825f3265bfa5eb0f2d4ea 5a 1807a7c6addd035e412 a06e7 ef184e 504699f5a2 97cdf06c991c79eee3bea3 390047947c5eb 93f8782fa019f604862222d3fdd3c37d4eef535ac074b8391b8c3 87a749 c55979c360c37 a2e2 30f04c792 046f7c04e7892d4 730deb84930e149f8357582d9499d7fa5ff0 84f9d85be635bd022bb9e6d9b71 bbb105aef3fbc2f1d15292c49d381 617b182a29bc2f1d959d6a3eac980648b02460e1f8e2c7 b461c30ccc029c9c60c325d041164c 442 a7412e0ac908fea149fc164 04840c 587dbc5bf3 390eb6649b7051792554ec03dcb 55f9f0a118599920aa0ea3e37a1ab06012c6fb28df95d36c42d22e4e63fa 2f348 d6485462f6fe89a85 8e93c1ba47 d8cf3df57021b192dd19dc 179f0df0d01b10bb21d7a25 8a966 26625f 1e192e 35f565e59d871ff0483b21577786358826ab78213ca7836 66 57a 90a5b56d575f10 93d7deb745e019f3cb2731f476aa9d9acf3a2c64fa810b430733ab1e0863d49b80187698f491ae17b3ed7390529e32bddb1c3de6aeb0d2c562a6e59c8d b7c855a9da0c7c13b760 e0336f330dc0d7f2ee48fde367a022a4605cc4 a3528 5a4ffe8031735d2129dbc706101a4d1 a59f0816be8046194a7af9f3fd 093ccad737d2dbcedbdf06 648 bad953370b3e186e1e6 d5e18f7f04c43b03e369a90 e f13 f6ed02327db0336c bfe034ffcbc a4808bdd 0bb22d85e7b22f16ce246c8b7 cfd3182fa2445f39eddaec4d222f01afcd d2c71b8f 6c6112b13 63fb1d55 4c873e6709aa71b 83115a27 714 588e2164d890858bd4 03bdb8b58 e259b23615059240d27e97c7e45a7cf8 b5 52119c 76a1 6e4e c0e623cb49bd98c9e9b9c2f 6 09047e537 f5aac250 8c8abb7da266d94d2564aa4d634bda214f710 23 219662901d608edc8972bb0cc57ca30df472c26b250f31ee87e131 f75a98bd73e2c61 a2ece0668a056fdc39c2012b455e7b139c36 458d3301b91e811a 61d6f7205bbfe1f03db95ec5121329 be00ab9f77bd8ab171fe640fee4aca006 b24a63eec4010eb7a0ca9f77d3 e e6f80aea4d8fdcdfcb eeec5b13ed9261fa03b2251a11194f20585c79277a 98 a7618149e400e45585787248c050 5a27b3 8f49d6f6bf1e8eafc1bb 7e5 81f9125 d660355e7307eb1d77d7bff9b3f31c2f980abef9de429383f3868 94d57d6694db443046083065c a e6f5e8873edaf8714 38bf3d543538ce8b7c fd4 dc03481e fdf8f5860f76c6 2544cf08462984 f9f3a75bc7558f6aeb799956cdc5eecfe9cebc0d5acad069 a3155b0 9 a40a60967b528f31c83b52ed9a2bab8d9ac9a2d8027 df6ef5b3de0c1233a1c84d858f44cfe2d5f3a406cf66f34c976f7e e11ea6df747 d0 4f6 ef9 6317723e02add da7f0 ec8500 fe45208b58d 96aa441a3161b83cc509f3e59 49  caa83128f6072c04736d653fce48f 0dc 3024e57277c5f8 194f4bdbfa4a09da154b986fd7b18281a23a6a44618 469a2e82c8634ef3ca6aade3d3794630479  7336542569dd645c74474 79048bdcf03351d537690 f52f2bb97ab2 6 f491c1 de90c9ce5b3aa0f05f  3776253f7af32a2bb7d44c90f1b3 03 39745710ac4dd909dd6a163712389d0a8d45eed5019deff69aa19c246809112837247 45ac259333ce82c4 fd5f7da3ec11df5 e8853 fc4471cac5d1524c5 86ceda80be87fb 42daa96ffefc2a753afaf70396de 71b2bdeab8303f8e7040 6a48757f184847ec0a 2be82be84 2998768c8 ffadba4684941e 25ca7a6a72a619771dbe2231a47323ae331b1df9862b7a85c 893e491aa4 ed7 425c8a5e38ae32c d3d59e98eaacc1ec5dc92729af1450d6c0a a81b56ae09a3487cb68 2e59584ff1 3a2ff083271249fff2b 83dde7b2a45990f40 a41c34b9a854b870de 7d35f4978891fe2d90 d094d0a14a67a4149d8b49e 975741 15 3ed6e8137 da 1c744ba8 749c7051f4 8208d35e3a207ad7e8914f6a48d 9c321796fe0e52417461a894f2d9e11ddc3 25db9bf e7dc5e2b1 3b7a25116bf4 2d0cf55795fcb c0f87c6 6e827e15 1b053 200 a77aad3fab4e8 06a00896c2d42 ecc3 2e9f9ac8a11d931cd0  8d1d676100f00a3c7399333 536a112dafad7d860151f0eb9405a06faf044b3 d1c809 e4b6748d1059cad7a5a9d0188   783be6349e0c2d c12306 769a28ff35 6 4df3f2df887c3f900f 98fda95f7d3317d46573fcd9118f bfa2c12f63744dae93b4 54e7a1ca 1298d8f668e95421d94fbd232390091a66591b37d55e22df3b603d2f a196 a dcc7c b58c3d050227a78334653583595f2963c8213 00fd5f44ba0fb2b6b7c8d700602357ce75 6c8b9a102f0a6e9 5e8 e2507d9a2de215135bb31b 41435cd775440f01ed958209c7def0db8e4 6 b064  e8fe7db9 2765d09dca7 ca7f90e222f6ecb0fbb5a9efdbec6445d360fa0083c57cacf0ec2515fa98a0a1b095a5969aae9335e6eeccb240b7da2bc 2da86c637f639338 05c15e3 d 53c746edb669ed 102e d e68a55 91222c98de52eb3619a4209a0e7fed866b87c a9a24d753ef51e945f6c4eb 95 7213c 519e21b4 345230a8b3d  dcb 0c5cc1992c21 ad6bc2 2c 2aa040e49c82a578b7aad 56326d2162b0db188237827d8de22c7c974 5c96d 82cfefefe1571247660018696f401db0bde3de61766 467f9e7ef5eec43e8f7e6329 95068cb76151ff98966de70dad5f147ea779445107fcb04fda6e77a8bb046aef7175d0798 1ad98f0df198d799fc4837 24288 82d104e9 c7224198a32d766 4b3e552c7950a13e04972ed9e669ff 93d cf3f9cbebbd94 96 25997ccfb97d56a94d07dbfa595b8991d8a379e80ce0cd3 5cc98d7879092ad34cb65837bf7a807 136b51 89ed646cc6e6b 32290cd41543d275680ea1fd80d84fabdcd73810d9efacdd8607c2fd12830c561e5588 edf0f948c82d90444c dfe93620a8d1581174b517254 87d7e8704795f9 c73fa274ebbe5cf80 d15d75cd2f698e4 39bfa8abde0465744a 14300a1111bf82fd 4d93e717108bcda30bc6b773d 64558a9232447f65d53 0bb3268279def0c7b0b2025 464f28803cf4fc24 b90d4b407a5bb8f625ea74a63c05d8a46250e72a9543d1ad8860 60d1 30b1c80191bf016e42b5ce83 3b707de1d4ed474252b04  67efe25af06e1d93  5c21d92 256d7981abd781a40b294bbe136c53230e8aa65 99f26e01c 315063 019eca bec82d434d5a998469e75085 628f99ef1506 d8   2acc7302c3 6e7d 6683079f52da5459578388a5 6f8b02868adfec0ecbe1e1d1182ca031bcfbc98dc001e16fa02ef2017ab15d50b7 cf9460f4ecdec3c c6fe8acec042 5994a86f3d46a44f637de1cd7d676d 4f114a68a6a65d0641593b9145c3e4bb1116a7690 02bcf05 f2ad8b8d1 4b48e9cfa447c5a95 91c57f30164f33 3abd0 d0ca3e2b0efa5d6024fa7496 608de15c65a047a8972f67fe7be2b876faad1d1bdbd 22b72ae6271a09 581a219c88986260b9f5b8 6d29d4038cbe0a6d27 aeaf722aaacb5afc90b9064cb effb62d28aa3a232a05f2 5d251e0c226e 6a85 07f1ece8cc8639 1c7a7d8f6b2f2 13f0c35 f5fe786195 a4a59e8 c86f95f9aa4a391bbd7530d28451596578740c9b50c4e2d2 c2889c5ddc9 3d152b61c5f8250 b9b99f541097ce050fc3 ff3558f39aef2c689a21999b 1ffd5d405fc763b2e4c88276 172b9d94 9c512e76035cbac 839fb5df68dbd0606fd6bf75163fae9 473e149 c941638adb 8d30a707fda281a95f194b099cc4a 6fb6f6f9cfd4493e60b9099bde081c00b56 2a 4843 65d3629af4726e42b2387456f031f6d19c7426dd511582df3356ad59 86b 2f2a4912 fc66d689434917165225e01fa5 3 8a65ac80078 8ac748bb05d3681c431e9fbd5d05a311a7e7819ccf5bed4fd810b4 4802b7 a2 ce741201db57669625b72bdd48f009db29cea2d2c1f3ea82f2863af82cd3b12e637a483c34 b11af 07d33e9fd27361af781bb611d25e93 e4003c212d70f377816ee9 87e91 f19bab0 33fc 92d4eae08bb e3bc55a5005d2a 2a884798211e31b4b5453  11ebb37a275 4110f8e0 eb6747783dc52083c6476e5f82a9f683f688bf8e57fa7e 96c9ea99af1f81232cec1897f736734c8b20  1 8da00c124e5be0394c5dbb8 43541f2f 4eb6f 3bcb9f53 2 52dddf79bc9443a4e5cb32d32856bb8f227f960 eaba9333bb994de3e7b4b8 5 fa200bfc92e85c88b98f0d5ac a318f88a3d359c6895c5afe7b24fbbb019 05  060efc11 faf8d2 f982e 6740fc4fd107 c1bddd 0d 5 f2a2d6201a9cf00a4fbb9 2424270c62dcebc30f0b 179f60397a201de18f66eef962867748192b76cd3bb3424132843e4883 aaab4a672d128764eab364bda976e982378177fd4e07eb3af5 aba01484c72dbc6e3a 23 f464c8a515ae003e70fe48  00f5178e382 5be01dd63 abe7 d8 91b57 dd78 d8fa8fd6c368a e9584a d91c3ba24291092830637dbcdd41852b14 e0d53 155ee71b55d78aff20f213491c4c7ff8 a52 94 b8fb 618e5f5dd30 6bfa72a08e0f0851e7b1d7bf00d09 e41f57983af7372e b6ef590fee3bea5c7ce4f 9750ae0aa50e5da07bd47bdb1fc e93a1a462cf13afb5ba618d7d97a 47a2 97314 048ddad7a03549cad37bdadea3c9f60cbff26d368a1e59721220abd1733db95500be6ced8241 21fc99be3181cdfa68e33 efedf6067406ef495a4caf6eaeffcd106e41 00d1fc1a2a c  8948a 21a7f1030e506 f09fc9a52d13 8156e26603085c80b7e3 cc99534 c1b1374a8cc9e6a2f8962aacbaf5c002d6a1637e330935c 2cde11d508ea22828c892673d6f2a7a010626d3be59b7e 195149988177  0bcd5c8435fb28560c 1 f455b1 8 8b238d1f 001af1b7d0e3ab6564fd9052f 3edf3021c  9300b620c57dc4db6307e81edc5f1786df27864 9bb6cfcd768e9 dc952d10d88336e687c68b4fb1f174fb2e9f7735f67f326d53b7e2dbc7f2f 5957ffb 7ce8f7d19db61bb45e3799930f153bb bb519d1d29fbda4f82a629f a6234cec0fa97f3 cb43fa3678200ccd74dac5d679539f8a9d605172461419e4767af62eb c79 7 ebf7a 21038 afb31b949ac0f13c023b7bc90bcd6f 71b746 a6667ec838e6ed58dadf19a79cf015 d4e 2e21eb428ee8b bfd2516c 9691d c53d9aa2bf54ad4fa4439b79f416b28 9688612b23864532c9a4d8e5e31b58513ab8b6bba5218f7b8b2189379e7437609b4ea 9de3e 84419988e 7c338 31d00c8 fb68c2a1b9fac8bc3b0 d62cc693f27a1a72a196068ce97a119d0457 4  201d9ec0d6eeccb 31504110673af00318cf a0c0703858ba145b1 6abe6398b4 c91c7dc47e6a48412661b9bb0a763f41c743d7f33a38179787020 f9afd90006b2188ced718f2596584d66a6fe0487a498abe071e336e8428f8f7fde cb414728efa3f61eccde906c52d2a357fe289113e61ee4edc6ea629ec50b4b e462dbabc6 a40492da64  c991dd326 4aa6a81d39dade2767725f43162e a9089e2c6 90f1779e243c28 65cb028ddd3748906eb8b 1653e1ee7 afd8ef7 8edfca898f38910 eef3ba47395972aa9 7c8ce25de 7e9182e5382c185a5995483340948f4a1  6cd956ecec3b8dca03eb003d38428e69eaff3 f1c410472 46b592f749e652e5e0c246855691e1 1dfc34a6 5e32d5383280e7725e55d8f 3a03cbb43959af 874 d18d 82b24a947a5b de4 7455a9ca 76b22e4fa518b249f2 6c3d59a5b9557dd0784a293a7ca12391f609 c5467723 daacdff1e697c97de94ac6a493da87eca91f383a 50d1421796484f4 e28531101 6d3ee9c3c8b1cf84b55d42050af638361df4ecbc83a 06668873d4f531aef77a0feef2ae2 c5436 2c6c90 552b95a56adcb609f2937e01884f8089ffefa68f4b8 ffe2 76b 9051930daab66db4c14 18167a0473aa43dda4d8f91be10e4473d8d6 88a09e b29ea6d01bc69c63cf4df0c403d41ae1bbce7525d 6068 4 8fb9 92bb3f316bf2dda c17155f0543 300abcabe970 6 77f7942530d96645ffa 785b12856158fa9157272c8c13d9f3c7 d13e22acc7fcf5 e6357852865cf39a1b8468c2bdaba7a9b4473145df8613 9db62f3df053106 03 f8c1e4986636b6d610ce38e22810ec90f13e904df68516f5472218b13080a5 9fa3 d 414ca34a9abbdfb8b8 ababd1228a4ccf666 2e76080523c6ee242e0924cb3481a4a578c82e6ef294321dae 39d806 1862cf41a0dc1bd436 10ffa3 26d8f10a4552 07 7c3 fad d8c905d66 56995 c04f661e990102b6fe1423bc5bd7a894c18d732f5ab 5fc842 d5da307fe507aa458725fbf5354c 5af 157 27ed5a6bf32610d383 a752bf92fb7f3f48fbfe1f2 ca5a5396cda2bf692dae3c7f1c5429ef58f333e79a4c4ac651d3688dc8c08d63f8c9db3 8fa538de146d8d074a37ad3078a 5 2df40e685 a233ac 127379d8ec9269293fd2f3c27e496 757729efe5e616a5ad d81 6bcb4e6a209e571b5f64b3e5b717cfa64d7d8ed9b17871 4d4e8f5fba7a726e1  026cd3aab 928 730c512fb46c68 c8 ff 571e734776783d19e7131871f581c41edd15e3a820c33 d120ea04a8cdb 18 f68368563c78b43fadf8f88640fa8037241d420 84b19cdfe22406d75f 29e010611971060f13fe4e 4446000 1c1e0b917690694 f573bf1e9c875260df7 ba40a2a3   b8ce1a33 a6c42b695469c66dd152cad460a72fc5d fff5577823 0011 812e1af8868e25965395ea71871e06c79c19d607cf44ddb5 763 ac0b2207f24ff0a236b9bdfab5d5052ae650 4ef c9aa00f1ca607c0a9977473715e0016770237da02b0d42bb762  0ed72c7dc153f8edb61c15d49c5b f95d746f7c8a769dfbc5dc8b9203cc4987ddc1e369146c0269ba65dba5d55a7 7c65ef5 bee70af19b444577f8370f86237 e18026f 2b30542 0138e527154f0946  a1669a82a7bd66a0e54d64 a814c1 4b663b7c44fb7ee665e448750bd8 58b13de aee8d2b3c5da8893a2838fb09e33b5f2068e9a1101903f7abb75 6ae6 ce178cb88  3c258b e09e73f4bcef1dd41c470dbc2 f 9a 8c7ed efa25efc 8f5372994a462a  70ab5dfccec4483045ec24aa8db0 16c50315bec490ae002f5420cfe02fd6a1a7472efcaa9401ecd3 06b9bcd5c2b7c 0a9f aab36f24f57d5d7350a339e3dd342b 2f149a8911d83a 5 fd96df70878a2820fee9b289b0d4d46ddaa0d411d705c54ab771d87 1ff00823637b98a608b1aeed9 8c1 ca19cd01a849f051d 8d005cfaf679bc901cd067a7 bf 4d358e213610b6749926a96dca32946cc69a29a68ac505c483e193 f26552f8a2895c2c5d4d02bd6e93 433d 054c28709d6659b2e1d98d dcf07ff256bf09ba0e7b3b2621425a2 81f24357d 3093c12 eaf  54004048190497c68104fe923d10e9af2b1a 40283078cb2222 07eb32d30f1f92bb28622d 505 7c9f119d74b03 9157 154c504f2c5a 3a c  7e64b d f1c79ce 39ff5839eeedd92424ba2581 c793fe6ecaa200cc526 3221 6cf56128f0f e2cece0e2f83 b923a2766adb2ae 29e02261062451930e99cbef5a58b6abae6e4febe8d9f853f43e2c63 e822d52cbe52a4139edb5f7738a6f4209cf6 842b82813e 557e1f734f3b62a9af1b5ad112701 b9fa402b9ba852f9325c1d22426c9b  0ab914 c6 9ca46c29c19b33a8 ab15a 137a12963ef6770c5e7fc828255bec5389a5bbd97cf0aef4e430b 81cf2a81987518606158 005 f1a74cbf 01e9ce68cf01af0a6e 98783 0462bb6890f3fca1bed4674f3b1242 e8b52e   7b81e00af5ef9bcb280dd0c a90 7ec4 ff00b3f264f837c81152b4c052e6bc46e1e40 d8313b20832d39d63ddcdb044a6cd 6eecd34dfd6a0a02d1f bc82f87088a543b1699604d6d7af92cb 1 ffcd49740f3e 97 cf  03db32aa2916f06b6a33de5c4 906e478250 155ba7cfb64f4edb28 68310a67 5350bb3bbecd30fdf08ca 81330f21e3e5a5de102d7625e74e34f7348d662f551afbe845a14300092ac4d954ba47c8e  607b9d6f0bbeca41a62a03e43 ba010942f 3d8d820e41 f2f19ea550482f825898 b37dd5 9a6687f3b0879 86f6db996cdeb50436d73a2bfa56723975f4 87b60c6176780df939 6b8e714743d 4e 571 e99cdbbb 54324038995b8c bb9629b51 fbcda471969 ff9eb9 9c85e8f0a4e9444cb52a 92e003a f7bc1f0b53f9b984a1d38745da004b67a8271ff 36c1768b 553745 74967c24e6e8 135d6a2ac25ce 5b6e8e62268a0688a803d 66dd6cf c2bf2f95f 5b08614880 af5b5c899005279d87e2fe657482db8777d0bb5e858811148  1 30 0c6ca4707a5663b7ca522eca7ccf 09bdeb78a 1e82c7a08f668b4fdbb366c26f983da1361ae daddd c 90c722a20  ea6b52eac4aff3cb874b277560d9 38a5 744ec75cf15 e31e677363ae736b8376a9af1a5435091249505b e73bb3ef8208a8ca279798b 6dd578d82042ac791 123c559f4b9b732e098debf40a  41 045c8edd6bd2ff 1cf423317c49aae892824e6799d2d69dfae2c16c1 c3bdbdaa738b5fa7865835a3a a747e024af7a6e55a1a dc3d4361077f8e6bdb8855c3b 37 5fac0958e78739d98 1d8323e6275236afdc48f53b8466 d06a53142a9c79b3bac4d43b7a1 98471e314454ed9b4aa6147d502cf8c108f8 6935c94 9ca93 f 3ced447ac932b39b cdde7f3 c844e81225a c0c7b0de12caf561e55d 28a50cee8b6c41739 02990da5f46ff 50af301cb7e98b1e462a2122d453cbf203ef7931a1cf5289741d08f36e4ceed f0ca64e80eb81b538bd99115f600e66641f7363d1f74cf6b5e3 c8f52c5f1ce1 af6fdac51bcc393e494a  3ae3 9 02d1eee2745305af80bfd5e 8bb6ea5a84 6ebd9be8c6 d49768c82593a13902ee8dbb6d2f5bc2b0c96e470e4777755c 77e356baab1c179171c7750c7e1b8aa4f87504b9c32577eb0 39b017ad9059 e9926d1b 9  52a24597eafef6cc2cdb3224e883a05ee3d0e42cb604 a4b2c32e4af3904a166429a4c105883be200 b5d5d24 6 dc8d3a73476d74e609d5a4b7e24b995cae4fd a689e94c246e1d7920067b98a7 d4 7 b21923e862 ddd8367b86b14 7 814e1824165830b72fbd2ca6774db6673427e722aff678435f5d a46dfca4eb1bf965f24ff32761f2b a7 1fd2728c855d7171aec4118e979013 027979288ba336ab3c ed 04a c8b aaa0fdef 8bc48c8902632c5c8c6891f48bf60d215cee 205468a70c0023491def50eec2ca77ddf80952  ef2725d8e89af0cc9 b3f726fc3c6c8d8d5e0a6bc7 d98f50e31ca599b48 f9345 5300665886489c5f5079e95  ad8579df0d4 1dd 8f57e47bc24556569aaedad7a1f578c25d663499160f2e8b45a52cc3d3 24c87 c 0658baa0269 ffda93de 3687b 3a94b8 929 4f99e5ac33 62b8af9ea903f2 8fe 733385df9e807055e673779e77b79196d7 5310e423f4 85a9cc4e 7d52c1891 1da2c903b1bea 190b178b8c 316ac7d0c0f9f624c3488 a53e839d678c56191 5 768d2bb fa3ad17b579b9 0f97a9fe76da9f4b5a0970b05b268e5bd423e0574352734a67917afe10 155e5fa104fce35dc862 f862c55f 4b3f058581c2b0c0da46bd244fa6be897b5101da4d 6873b6d8f 2b73ada309ae1c2334ac87f5bfb91cdb7a13d7f6942321b93d4e1538cfd5e61137d77a63 4005b4ee8079efb88a312ee7d84673c 6a1569bf1a29377321d36a438c1c363f4eaf94b78139 b 888d8ebe65c8f82d7d abc337f7 63f4 ccf2077a909afecd  312704129d86c1c 89c60ba5edc56bedd180a8 bbfeab21f ff5 6 7be55eae8d4 b  80514c5670d49a4 e77fca3de0acff47aa49c28b  f920ce9c9f1a26e5e3a2 7919bff5242d7b9e4247b5798cf3b00a65ba943f96d371 3db911fc5a26684eaaf5aa16fd3e7f8deeef01f952d5b22448910af35a3280a2a0394b6a5c1 a9afa3352c240c8ef3e8f65dba56cc02c479070fb8a372c3 a8defc3ee58ba44 e5a 758c6743ed21121a53e7b0a338565bbf18051f6 8 293b9bfcaf 34b9fbc409061821088f142f8f 9a8171631c8 f28f59fda b62846f8ae94144e47e61f 320feedf 5398828b4968d50dc40df687b7ac2297 aad8c532d67f4ac c9790758e492caab92dd22 88e5bd9e70 00a0dae47d825fd86e124bbca791382  9193c569c86b57f65b8c eccb63c5 d4f9611e87b820e5 5422bb3ef0ceb21ac0f47e3c1745a4c20902 41e57b27e063d955b1454 c fc  b7e8ac373a0158359725b28d0a2e ae5383e836b03ec45160f2054089a8004bccd7d91f 5519710a45fe86d371d1f5d91430d2e071441faa55e1514fc3a6438552890ddba3b51c5a87d85ff79ae90311c17b42 6de05351587dc2a865cc8fb01e33605579496e94add ced332d2176b1b7dcb62a261 b18dca7fb571472 99b 5d8937b7abd0bfbe3db0f816 0479066ec459212e67721d6ff 04bff4e3 d36365f73949eb84adeba 964b 19 aa8013b7780c7b d221053c0cf 0b3777def6ebe0 47d d86850b151 c985  dc8282e 19d65501cef832178d30f3ac866a519c6bb42a1 b77c5774dd72f4582ba0562bb34c83e0 972d6e57fc39c8a74745ea83dd7ba26abc4076 f 5c98 308c61336ee1bd392 2e97dbbf0f6c94959b0e89b1a 2b4 acf9bba7177d a0839012e0dba9825876d514805955 0f42c45323c4bda0b9c9205dbe0447 967dcc675ef1 d02ee2c77b61815f0da4f31461b1ff c67ab19e5ccc561f56f1d23c11716eddfcd326b59ce13411 555dde7a ec01a fca59391bb0384eb702518bafdbbd48827dd65560673b7d 4a 05e40fbc48dddb2df e b d98fb969fc0fbd38907552e 27a 1 d7 00  c4e1e2770816de6aaf04b29ef52b39f134e1d c3ca2196799 5e7ba9ea10ffda079 70ed5b8be0b96c1 aa2747d8c9f99685d8950341d3eccc 2f 663d00a00 8b8 ec05f6bc77333b870 ee9861dc4035e470dd60bd6f7b 2b5041c e1a3c7682d2b7 c 31cc83dc50cca5b1 1c9c8d dc6123353bf91dcf eb15af3ecb81dff 50d 2ba5111be919f 75de1ab2d83c389b3 24f7b 0e935841f8d2f9b941e16547fbcf9dc5440ffb9b5fd1c42 5d468f6"

char="–"
#char="¥"
#char="Ń"
#char="Ł"
#char="Ǎ"
#char="Ǟ"

str[60]=$char
time ( out_array=( "${str//(#bi)wfeiwj/a}" ) )
str[60]="a"

str[10000]=$char
time ( out_array=( "${str//(#bi)wfeiwj/a}" ) )
str[10000]="a"

str[50000]=$char
time ( out_array=( "${str//(#bi)wfeiwj/a}" ) )
str[50000]="a"

str[100000]=$char
time ( out_array=( "${str//(#bi)wfeiwj/a}" ) )
str[100000]="a"


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Substitution ${...///} slows down when certain UTF character occurs
  2015-09-26 12:19 Substitution ${...///} slows down when certain UTF character occurs Sebastian Gniazdowski
@ 2015-09-26 20:44 ` Bart Schaefer
  2015-09-27  8:13   ` Sebastian Gniazdowski
  0 siblings, 1 reply; 19+ messages in thread
From: Bart Schaefer @ 2015-09-26 20:44 UTC (permalink / raw)
  To: zsh-workers

On Sep 26,  2:19pm, Sebastian Gniazdowski wrote:
}
} I attach a script that does ${...///} substitution.

I worry that the attachement hasn't come through correctly?  When I
unpack the base64 into text, I get (in part)

str="c4d5148ca6 ce3a2d24203abfb385 30f5fe85434ae ... 5d468f6"

Is the value of $str supposed to look like that?  So the pattern in
the ${str//...} replacement never matches?

} It  is very slow for some chars and very fast for others. How to explain
} and hopefully fix this?

Each time pattryrefs() fails to find a match, it increments the area
to be searched by one character and then tries the entire pattern
match again.  So for a 120000-character string, it's doing a non-
matching search 120000 times.

I rewrote your test to use "float SECONDS" + "print $SECONDS" instead
of forking off subshells for "time" and to use loops so I didn't have
to comment things in and out.  Observations:

1. It's only fast for the Yen symbol, which is the only one that does
not have a byte with the high-order bit set.  This case is avoiding
this block in pattern.c:

2124	    if (!(patflags & (PAT_PURES|PAT_ANY))
2125		&& (needfullpath || unmetalen != stringlen)) {
2126		/*
2127		 * We need to copy if we need to prepend the path so far
2128		 * (in which case we copy both chunks), or if we have
2129		 * Meta characters.
2130		 */

I.e., unmetalen == stringlen, so we do not allocate and copy the entire
120k bytes of $str for each pattern comparison.

This means in the case where there are high-order characters, the search
algorithm becomes O(N)^2 rather than O(N).

2. It's consistently slower the longer the prefix string before the
high-order byte becomes.

I believe this means that once the search loop has "gotten past" the
high-order byte, it stops doing the O(N)^2 copy-and-scan and drops in
to the O(N) scan of the original input string.  But I haven't traced
it down to exactly where that happens.  The nested loops around line
2908 in glob.c, I suspect.

So this could be sped up by factoring out the unmetafication, but it
would require some pretty serious reworking of the relationship between
pattrylen() / pattryrefs() and their callers.


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Substitution ${...///} slows down when certain UTF character occurs
  2015-09-26 20:44 ` Bart Schaefer
@ 2015-09-27  8:13   ` Sebastian Gniazdowski
  2015-09-27 16:11     ` Bart Schaefer
  0 siblings, 1 reply; 19+ messages in thread
From: Sebastian Gniazdowski @ 2015-09-27  8:13 UTC (permalink / raw)
  To: zsh-workers

On 26 September 2015 at 22:44, Bart Schaefer <schaefer@brasslantern.com> wrote:
> On Sep 26,  2:19pm, Sebastian Gniazdowski wrote:
> }
> } I attach a script that does ${...///} substitution.
>
> I worry that the attachement hasn't come through correctly?  When I
> unpack the base64 into text, I get (in part)
>
> str="c4d5148ca6 ce3a2d24203abfb385 30f5fe85434ae ... 5d468f6"
>
> Is the value of $str supposed to look like that?  So the pattern in
> the ${str//...} replacement never matches?

Yes. I attached the string instead of code that generated it:
# cat /dev/urandom | env LC_CTYPE=C tr -cd 'a-f0-9 ' | head -c 120000

> } It  is very slow for some chars and very fast for others. How to explain
> } and hopefully fix this?
>
> Each time pattryrefs() fails to find a match, it increments the area
> to be searched by one character and then tries the entire pattern
> match again.  So for a 120000-character string, it's doing a non-
> matching search 120000 times.

That's a huge plus that it's still instant fast for strings of that
length if there is no unlucky unicode character.

> I rewrote your test to use "float SECONDS" + "print $SECONDS" instead
> of forking off subshells for "time" and to use loops so I didn't have
> to comment things in and out.  Observations:
>
> 1. It's only fast for the Yen symbol, which is the only one that does
> not have a byte with the high-order bit set.  This case is avoiding
> this block in pattern.c:

For me (OSX / zsh 5.0.2) it was fast for characters at even positions
in what I attached, i.e. for chars ¥,Ł,Ǟ. Didn't thought it can differ
for different environments, I now ran the test on different machines.
Ubuntu 12.10 / zsh 5.0.0 is the same. For FreeBSD / zsh 5.1.1-dev-0
(HEAD 50721a1 and 8d5c0c) it's different, fast characters are: ¥, Ł.
For zsh-5.1.1-dev-0 (HEAD 50721a1 and 8d5c0c) on OSX it's the same as
the FreeBSD case.

Best regards,
Sebastian Gniazdowski


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Substitution ${...///} slows down when certain UTF character occurs
  2015-09-27  8:13   ` Sebastian Gniazdowski
@ 2015-09-27 16:11     ` Bart Schaefer
  2015-09-28  8:51       ` Peter Stephenson
  2015-10-01 13:45       ` Substitution ${...///} slows down when certain UTF character occurs Sebastian Gniazdowski
  0 siblings, 2 replies; 19+ messages in thread
From: Bart Schaefer @ 2015-09-27 16:11 UTC (permalink / raw)
  To: zsh-workers

On Sep 27, 10:13am, Sebastian Gniazdowski wrote:
} Subject: Re: Substitution ${...///} slows down when certain UTF character 
}
} On 26 September 2015 at 22:44, Bart Schaefer <schaefer@brasslantern.com> wrote:
} > Each time pattryrefs() fails to find a match, it increments the area
} > to be searched by one character and then tries the entire pattern
} > match again.  So for a 120000-character string, it's doing a non-
} > matching search 120000 times.
} 
} That's a huge plus that it's still instant fast for strings of that
} length if there is no unlucky unicode character.

It'll get worse if there are partial matches, e.g., if you had 30000
repetitions of "wfei" and scanned for "wfeiwj" there'd be a whole lot
of backtracking.  There are no "w" anywhere in your sample $str so
each of the comparisons is only one equality test.

Still I think the biggest issue is that unmetafication happening too
low down.  Since pattry*() is being called repeatedly with the same two
first arguments (prog and string) it might be possible to cache the
unmetafied string after the first call.


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Substitution ${...///} slows down when certain UTF character occurs
  2015-09-27 16:11     ` Bart Schaefer
@ 2015-09-28  8:51       ` Peter Stephenson
  2015-09-28 11:30         ` Peter Stephenson
  2015-09-28 19:23         ` Peter Stephenson
  2015-10-01 13:45       ` Substitution ${...///} slows down when certain UTF character occurs Sebastian Gniazdowski
  1 sibling, 2 replies; 19+ messages in thread
From: Peter Stephenson @ 2015-09-28  8:51 UTC (permalink / raw)
  To: zsh-workers

On Sun, 27 Sep 2015 09:11:21 -0700
Bart Schaefer <schaefer@brasslantern.com> wrote:
> Still I think the biggest issue is that unmetafication happening too
> low down.  Since pattry*() is being called repeatedly with the same two
> first arguments (prog and string) it might be possible to cache the
> unmetafied string after the first call.

It would be good to optimise the cases where the calling code in glob.c
(for the parameter-style operators only) matches at different places along
the string, too, which means unmetafying at a higher level.  That's
quite a lot of work in the glob.c code, though, because we'll need to
deal with length and switch the multibyte handlers to umetafied.

I think a reasonable strategy would be to change the call sequence for
pattrylen() and pattryrefs(), which are the key ones, to pass in an
optional unmatefied string; some of the remaining calls in glob.c could
be premoted to pattrylen which is a strict superset of pattry.  That
would leave pattry() untouched for the majority of cases doing one-off
matching.

Ideally we only want to pass in either a metafied or unmetafied string.
I don't know off the top of my head how much work it is to fix up the
PAT_PURES optimisation where we've got an already unmetafied string but
it shouldn't be too much.

pws


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Substitution ${...///} slows down when certain UTF character occurs
  2015-09-28  8:51       ` Peter Stephenson
@ 2015-09-28 11:30         ` Peter Stephenson
  2015-09-28 19:23         ` Peter Stephenson
  1 sibling, 0 replies; 19+ messages in thread
From: Peter Stephenson @ 2015-09-28 11:30 UTC (permalink / raw)
  To: zsh-workers

On Mon, 28 Sep 2015 09:51:42 +0100
Peter Stephenson <p.stephenson@samsung.com> wrote:
> I think a reasonable strategy would be to change the call sequence for
> pattrylen() and pattryrefs(), which are the key ones, to pass in an
> optional unmatefied string; some of the remaining calls in glob.c could
> be premoted to pattrylen which is a strict superset of pattry.  That
> would leave pattry() untouched for the majority of cases doing one-off
> matching.
> 
> Ideally we only want to pass in either a metafied or unmetafied string.
> I don't know off the top of my head how much work it is to fix up the
> PAT_PURES optimisation where we've got an already unmetafied string but
> it shouldn't be too much.

The problem here is we're comparing against a string compiled into the
pattern which is metafied and now we have an unmetafied trial string.
So we can't do a direct comparison any more without some extra work.

1. Give up on the optimisation when we have an unmetafied string.  That
is, we'll still be comparing characters, but in the bowels of the
pattern code --- we won't optimise to a strcmp().  This seems a bad
thing to do when the whole point of the change is as an optimisation.

2. Use a partial optimisation by unmetafying the pattern string on the
fly.  So we're not using memcmp any more, but we'll have a tight loop
over characters and this can be done with local code at the point where
we currently do the memcmp().

3. Compile both metafied and unmetafied variants into the pattern.  This
is wasteful.

4. Have both metafied and unmetafied variants for the pattern when using
a pure string, but only produce, and cache, the unmetafied version when
needed for comparison.  This is more effective than caching the trial
string because the pattern is only compiled once for many uses of it ---
we only lose out here if somebody is looping over a pattern (not just a
trial string as in the glob code) many times i.e. either redoing
patcompile() or using a pre-compiled pattern, and the latter isn't all that
common in the code (I'm not sure where it does happen if it does).
This seems to push the inefficiency out of inner loops to a frequency
where it's probably not a noticeable factor any more.

5. Deal with both metafied and unmetafied strings in the calling code.
This is a messy last resort.

I think both 2. and 4. look promising.

pws


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Substitution ${...///} slows down when certain UTF character occurs
  2015-09-28  8:51       ` Peter Stephenson
  2015-09-28 11:30         ` Peter Stephenson
@ 2015-09-28 19:23         ` Peter Stephenson
  2015-09-29  8:44           ` Peter Stephenson
  1 sibling, 1 reply; 19+ messages in thread
From: Peter Stephenson @ 2015-09-28 19:23 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: zsh-workers

On Mon, 28 Sep 2015 09:51:42 +0100
Peter Stephenson <p.stephenson@samsung.com> wrote:
> It would be good to optimise the cases where the calling code in glob.c
> (for the parameter-style operators only) matches at different places along
> the string, too, which means unmetafying at a higher level.  That's
> quite a lot of work in the glob.c code, though, because we'll need to
> deal with length and switch the multibyte handlers to umetafied.
> 
> I think a reasonable strategy would be to change the call sequence for
> pattrylen() and pattryrefs(), which are the key ones, to pass in an
> optional unmatefied string; some of the remaining calls in glob.c could
> be premoted to pattrylen which is a strict superset of pattry.  That
> would leave pattry() untouched for the majority of cases doing one-off
> matching.

This does the back-end work, with a patstralloc structure that allows
you to maintain information about an unmetafied string over calls to
pattrylen() and pattryrefs().

It uses this version of the optimisation

> 4. Have both metafied and unmetafied variants for the pattern when using
> a pure string, but only produce, and cache, the unmetafied version when
> needed for comparison. This is more effective than caching the trial
> string because the pattern is only compiled once for many uses of it ---
> we only lose out here if somebody is looping over a pattern (not just a
> trial string as in the glob code) many times i.e. either redoing
> patcompile() or using a pre-compiled pattern, and the latter isn't all that
> common in the code (I'm not sure where it does happen if it does).
> This seems to push the inefficiency out of inner loops to a frequency
> where it's probably not a noticeable factor any more.

with the cached unmetafied pure string, where needed, within the
patstralloc structure.  However, the new code here to handle the
unmetafied case isn't tested yet as there's nothing using the new
interface, which is the next step.

pws


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Substitution ${...///} slows down when certain UTF character occurs
  2015-09-28 19:23         ` Peter Stephenson
@ 2015-09-29  8:44           ` Peter Stephenson
  2015-09-29 18:37             ` Peter Stephenson
  0 siblings, 1 reply; 19+ messages in thread
From: Peter Stephenson @ 2015-09-29  8:44 UTC (permalink / raw)
  To: zsh-workers

On Mon, 28 Sep 2015 20:23:12 +0100
Peter Stephenson <p.w.stephenson@ntlworld.com> wrote:
> This does the back-end work, with a patstralloc structure that allows
> you to maintain information about an unmetafied string over calls to
> pattrylen() and pattryrefs().

Bart pointed out I didn't actually attach the patch, but it's now
committed in f9d7651c25.  No noticeable change of behaviour is expected
yet.  I started looking at the front end last night; it's not difficult,
just quite a bewildering number of things to switch to unmetafied.
Overall it should actually be slightly simpler after the change because
we were remembering quite a lot of positions as unmetafied already.

pws


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Substitution ${...///} slows down when certain UTF character occurs
  2015-09-29  8:44           ` Peter Stephenson
@ 2015-09-29 18:37             ` Peter Stephenson
  2015-09-29 19:23               ` Bart Schaefer
  0 siblings, 1 reply; 19+ messages in thread
From: Peter Stephenson @ 2015-09-29 18:37 UTC (permalink / raw)
  To: Peter Stephenson, zsh-workers

This uses the new interface.  I haven't done any testing apart from the
normal test suite.

There's one change I still want to make, which is to put the remaining
allocatiion onto the heap --- it should be used infrequently enough to
make this feasible.  However, it's probably seeing what the effects are
before that.

There's a reasonable chance there's still some glitch with metafied
characters.  We could probably do with some more parameter substitution
tests involving Mikael's interesting characters, possibly more failure
cases, too.

pws

diff --git a/Src/glob.c b/Src/glob.c
index 8bf7352..0594f0a 100644
--- a/Src/glob.c
+++ b/Src/glob.c
@@ -2450,29 +2450,46 @@ matchpat(char *a, char *b)
 /* please do not laugh at this code. */
 
 /* Having found a match in getmatch, decide what part of string
- * to return.  The matched part starts b characters into string s
- * and finishes e characters in: 0 <= b <= e <= strlen(s)
+ * to return.  The matched part starts b characters into string imd->ustr
+ * and finishes e characters in: 0 <= b <= e <= imd->ulen on input
  * (yes, empty matches should work).
- * fl is a set of the SUB_* matches defined in zsh.h from SUB_MATCH onwards;
- * the lower parts are ignored.
- * replstr is the replacement string for a substitution
+ *
+ * imd->flags is a set of the SUB_* matches defined in zsh.h from
+ * SUB_MATCH onwards; the lower parts are ignored.
+ *
+ * imd->replstr is the replacement string for a substitution
+ *
+ * imd->replstr is metafied and the values put in imd->repllist are metafied.
  */
 
 /**/
 static char *
-get_match_ret(char *s, int b, int e, int fl, char *replstr,
-	      LinkList repllist)
+get_match_ret(Imatchdata imd, int b, int e)
 {
-    char buf[80], *r, *p, *rr;
-    int ll = 0, l = strlen(s), bl = 0, t = 0, i;
-
+    char buf[80], *r, *p, *rr, *replstr = imd->replstr;
+    int ll = 0, bl = 0, t = 0, add = 0, fl = imd->flags, i;
+
+    /* Account for b and e referring to unmetafied string */
+    for (p = imd->ustr; p < imd->ustr + b; p++)
+	if (imeta(*p))
+	    add++;
+    b += add;
+    for (; p < imd->ustr + e; p++)
+	if (imeta(*p))
+	    add++;
+    e += add;
+    for (; p < imd->ustr + imd->ulen; p++)
+	if (imeta(*p))
+	    add++;
+
+    /* Everything now refers to meatfied lengths. */
     if (replstr || (fl & SUB_LIST)) {
 	if (fl & SUB_DOSUBST) {
 	    replstr = dupstring(replstr);
 	    singsub(&replstr);
 	    untokenize(replstr);
 	}
-	if ((fl & (SUB_GLOBAL|SUB_LIST)) && repllist) {
+	if ((fl & (SUB_GLOBAL|SUB_LIST)) && imd->repllist) {
 	    /* We are replacing the chunk, just add this to the list */
 	    Repldata rd = (Repldata)
 		((fl & SUB_LIST) ? zalloc(sizeof(*rd)) : zhalloc(sizeof(*rd)));
@@ -2480,30 +2497,32 @@ get_match_ret(char *s, int b, int e, int fl, char *replstr,
 	    rd->e = e;
 	    rd->replstr = replstr;
 	    if (fl & SUB_LIST)
-		zaddlinknode(repllist, rd);
+		zaddlinknode(imd->repllist, rd);
 	    else
-		addlinknode(repllist, rd);
-	    return s;
+		addlinknode(imd->repllist, rd);
+	    return imd->mstr;
 	}
 	ll += strlen(replstr);
     }
     if (fl & SUB_MATCH)			/* matched portion */
 	ll += 1 + (e - b);
     if (fl & SUB_REST)		/* unmatched portion */
-	ll += 1 + (l - (e - b));
+	ll += 1 + (imd->mlen - (e - b));
     if (fl & SUB_BIND) {
 	/* position of start of matched portion */
-	sprintf(buf, "%d ", MB_METASTRLEN2END(s, 0, s+b) + 1);
+	sprintf(buf, "%d ", MB_METASTRLEN2END(imd->mstr, 0, imd->mstr+b) + 1);
 	ll += (bl = strlen(buf));
     }
     if (fl & SUB_EIND) {
 	/* position of end of matched portion */
-	sprintf(buf + bl, "%d ", MB_METASTRLEN2END(s, 0, s+e) + 1);
+	sprintf(buf + bl, "%d ",
+		MB_METASTRLEN2END(imd->mstr, 0, imd->mstr+e) + 1);
 	ll += (bl = strlen(buf));
     }
     if (fl & SUB_LEN) {
 	/* length of matched portion */
-	sprintf(buf + bl, "%d ", MB_METASTRLEN2END(s+b, 0, s+e));
+	sprintf(buf + bl, "%d ", MB_METASTRLEN2END(imd->mstr+b, 0,
+						   imd->mstr+e));
 	ll += (bl = strlen(buf));
     }
     if (bl)
@@ -2513,7 +2532,7 @@ get_match_ret(char *s, int b, int e, int fl, char *replstr,
 
     if (fl & SUB_MATCH) {
 	/* copy matched portion to new buffer */
-	for (i = b, p = s + b; i < e; i++)
+	for (i = b, p = imd->mstr + b; i < e; i++)
 	    *rr++ = *p++;
 	t = 1;
     }
@@ -2523,12 +2542,12 @@ get_match_ret(char *s, int b, int e, int fl, char *replstr,
 	if (t)
 	    *rr++ = ' ';
 	/* there may be unmatched bits at both beginning and end of string */
-	for (i = 0, p = s; i < b; i++)
+	for (i = 0, p = imd->mstr; i < b; i++)
 	    *rr++ = *p++;
 	if (replstr)
 	    for (p = replstr; *p; )
 		*rr++ = *p++;
-	for (i = e, p = s + e; i < l; i++)
+	for (i = e, p = imd->mstr + e; i < imd->mlen; i++)
 	    *rr++ = *p++;
 	t = 1;
     }
@@ -2710,26 +2729,18 @@ set_pat_end(Patprog p, char null_me)
 
 /*
  * Increment *tp over character which may be multibyte.
- * Return number of bytes that remain in the character after unmetafication.
+ * Return number of bytes.
+ * All unmetafied here.
  */
 
 /**/
-static int iincchar(char **tp)
+static int iincchar(char **tp, int left)
 {
     char *t = *tp;
-    int mbclen = mb_metacharlenconv(t, NULL);
-    int umlen = 0;
-
-    while (mbclen--) {
-	umlen++;
-	if (*t++ == Meta) {
-	    t++;
-	    mbclen--;
-	}
-    }
-    *tp = t;
+    int mbclen = mb_charlenconv(t, left, NULL);
+    *tp = t + mbclen;
 
-    return umlen;
+    return mbclen;
 }
 
 /**/
@@ -2737,7 +2748,7 @@ static int
 igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	  LinkList *repllistp)
 {
-    char *s = *sp, *t, *tmatch;
+    char *s = *sp, *t, *tmatch, *send;
     /*
      * Note that ioff counts (possibly multibyte) characters in the
      * character set (Meta's are not included), while l counts characters in
@@ -2752,36 +2763,52 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
      */
     int ioff, l = strlen(*sp), matched = 1, umltot = ztrlen(*sp);
     int umlen, nmatches;
-    /*
-     * List of bits of matches to concatenate with replacement string.
-     * The data is a struct repldata.  It is not used in cases like
-     * ${...//#foo/bar} even though SUB_GLOBAL is set, since the match
-     * is anchored.  It goes on the heap.
-     */
-    LinkList repllist = NULL;
+    struct patstralloc patstralloc;
+    struct imatchdata imd;
+
+    (void)patallocstr(p, s, l, umltot, 1, &patstralloc);
+    s = patstralloc.alloced;
+    DPUTS(!s, "forced patallocstr failed");
+    send = s + umltot;
+
+    imd.mstr = *sp;
+    imd.mlen = l;
+    imd.ustr = s;
+    imd.ulen = umltot;
+    imd.flags = fl;
+    imd.replstr = replstr;
+    imd.repllist = NULL;
 
     /* perform must-match test for complex closures */
     if (p->mustoff)
     {
-	/*
-	 * Yuk.  Probably we should rewrite this whole function to
-	 * use an unmetafied test string.
-	 *
-	 * Use META_HEAPDUP because we need a terminating NULL.
-	 */
-	char *muststr = metafy((char *)p + p->mustoff,
-			       p->patmlen, META_HEAPDUP);
+	char *muststr = (char *)p + p->mustoff;
 
-	if (!strstr(s, muststr))
-	    matched = 0;
+	matched = 0;
+	if (p->patmlen <= umltot)
+	{
+	    for (t = s; t <= send - p->patmlen; t++)
+	    {
+		if (!memcmp(muststr, t, p->patmlen)) {
+		    matched = 1;
+		    break;
+		}
+	    }
+	}
     }
 
     /* in case we used the prog before... */
     p->flags &= ~(PAT_NOTSTART|PAT_NOTEND);
 
     if (fl & SUB_ALL) {
-	int i = matched && pattrylen(p, s, -1, -1, NULL, 0);
-	*sp = get_match_ret(*sp, 0, i ? l : 0, fl, i ? replstr : 0, NULL);
+	int i = matched && pattrylen(p, s, umltot, 0, &patstralloc, 0);
+	if (!i) {
+	    /* Perform under no-match conditions */
+	    umltot = 0;
+	    imd.replstr = NULL;
+	}
+	*sp = get_match_ret(&imd, 0, umltot);
+	patfreestr(&patstralloc);
 	if (! **sp && (((fl & SUB_MATCH) && !i) || ((fl & SUB_REST) && i)))
 	    return 0;
 	return 1;
@@ -2809,25 +2836,27 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	     * Largest/smallest possible match at head of string.
 	     * First get the longest match...
 	     */
-	    if (pattrylen(p, s, -1, -1, NULL, 0)) {
-		/* patmatchlen returns metafied length, as we need */
+	    if (pattrylen(p, s, umltot, 0, &patstralloc, 0)) {
+		/* patmatchlen returns unmetafied length in this case */
 	        int mlen = patmatchlen();
 		if (!(fl & SUB_LONG) && !(p->flags & PAT_PURES)) {
+		    send = s + mlen;
 		    /*
 		     * ... now we know whether it's worth looking for the
 		     * shortest, which we do by brute force.
 		     */
 		    mb_charinit();
-		    for (t = s, umlen = 0; t < s + mlen; ) {
+		    for (t = s, umlen = 0; t < send; ) {
 			set_pat_end(p, *t);
-			if (pattrylen(p, s, t - s, umlen, NULL, 0)) {
+			if (pattrylen(p, s, umlen, 0, &patstralloc, 0)) {
 			    mlen = patmatchlen();
 			    break;
 			}
-			umlen += iincchar(&t);
+			umlen += iincchar(&t, send - t);
 		    }
 		}
-		*sp = get_match_ret(*sp, 0, mlen, fl, replstr, NULL);
+		*sp = get_match_ret(&imd, 0, mlen);
+		patfreestr(&patstralloc);
 		return 1;
 	    }
 	    break;
@@ -2845,20 +2874,23 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	     */
 	    mb_charinit();
 	    tmatch = NULL;
-	    for (ioff = 0, t = s, umlen = umltot; t < s + l; ioff++) {
+	    for (ioff = 0, t = s, umlen = umltot; t < send; ioff++) {
 		set_pat_start(p, t-s);
-		if (pattrylen(p, t, s + l - t, umlen, NULL, ioff))
+		if (pattrylen(p, t, umlen, 0, &patstralloc, ioff))
 		    tmatch = t;
 		if (fl & SUB_START)
 		    break;
-		umlen -= iincchar(&t);
+		umlen -= iincchar(&t, send - t);
 	    }
 	    if (tmatch) {
-		*sp = get_match_ret(*sp, tmatch - s, l, fl, replstr, NULL);
+		*sp = get_match_ret(&imd, tmatch - s, umltot);
+		patfreestr(&patstralloc);
 		return 1;
 	    }
-	    if (!(fl & SUB_START) && pattrylen(p, s + l, 0, 0, NULL, ioff)) {
-		*sp = get_match_ret(*sp, l, l, fl, replstr, NULL);
+	    if (!(fl & SUB_START) && pattrylen(p, s + umltot, 0, 0,
+					       &patstralloc, ioff)) {
+		*sp = get_match_ret(&imd, umltot, umltot);
+		patfreestr(&patstralloc);
 		return 1;
 	    }
 	    break;
@@ -2868,18 +2900,21 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	     * move forward along string until we get a match. *
 	     * Again there's no optimisation.                  */
 	    mb_charinit();
-	    for (ioff = 0, t = s, umlen = umltot; t < s + l; ioff++) {
+	    for (ioff = 0, t = s, umlen = umltot; t < send ; ioff++) {
 		set_pat_start(p, t-s);
-		if (pattrylen(p, t, s + l - t, umlen, NULL, ioff)) {
-		    *sp = get_match_ret(*sp, t-s, l, fl, replstr, NULL);
+		if (pattrylen(p, t, umlen, 0, &patstralloc, ioff)) {
+		    *sp = get_match_ret(&imd, t-s, umltot);
+		    patfreestr(&patstralloc);
 		    return 1;
 		}
 		if (fl & SUB_START)
 		    break;
-		umlen -= iincchar(&t);
+		umlen -= iincchar(&t, send - t);
 	    }
-	    if (!(fl & SUB_START) && pattrylen(p, s + l, 0, 0, NULL, ioff)) {
-		*sp = get_match_ret(*sp, l, l, fl, replstr, NULL);
+	    if (!(fl & SUB_START) && pattrylen(p, send, 0, 0,
+					       &patstralloc, ioff)) {
+		*sp = get_match_ret(&imd, umltot, umltot);
+		patfreestr(&patstralloc);
 		return 1;
 	    }
 	    break;
@@ -2887,18 +2922,20 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	case SUB_SUBSTR:
 	    /* Smallest at start, but matching substrings. */
 	    set_pat_start(p, l);
-	    if (!(fl & SUB_GLOBAL) && pattrylen(p, s + l, -1, -1, NULL, 0) &&
+	    if (!(fl & SUB_GLOBAL) &&
+		pattrylen(p, send, 0, 0, &patstralloc, 0) &&
 		!--n) {
-		*sp = get_match_ret(*sp, 0, 0, fl, replstr, NULL);
+		*sp = get_match_ret(&imd, 0, 0);
+		patfreestr(&patstralloc);
 		return 1;
 	    } /* fall through */
 	case (SUB_SUBSTR|SUB_LONG):
 	    /* longest or smallest at start with substrings */
 	    t = s;
 	    if (fl & SUB_GLOBAL) {
-		repllist = (fl & SUB_LIST) ? znewlinklist() : newlinklist();
+		imd.repllist = (fl & SUB_LIST) ? znewlinklist() : newlinklist();
 		if (repllistp)
-		     *repllistp = repllist;
+		     *repllistp = imd.repllist;
 	    }
 	    ioff = 0;		/* offset into string */
 	    umlen = umltot;
@@ -2906,10 +2943,10 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	    do {
 		/* loop over all matches for global substitution */
 		matched = 0;
-		for (; t < s + l; ioff++) {
+		for (; t < send; ioff++) {
 		    /* Find the longest match from this position. */
 		    set_pat_start(p, t-s);
-		    if (pattrylen(p, t, s + l - t, umlen, NULL, ioff)) {
+		    if (pattrylen(p, t, umlen, 0, &patstralloc, ioff)) {
 			char *mpos = t + patmatchlen();
 			if (!(fl & SUB_LONG) && !(p->flags & PAT_PURES)) {
 			    char *ptr;
@@ -2923,19 +2960,18 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 			     */
 			    for (ptr = t, umlen2 = 0; ptr < mpos;) {
 				set_pat_end(p, *ptr);
-				if (pattrylen(p, t, ptr - t, umlen2,
-					      NULL, ioff)) {
+				if (pattrylen(p, t, umlen2, 0,
+					      &patstralloc, ioff)) {
 				    mpos = t + patmatchlen();
 				    break;
 				}
-				umlen2 += iincchar(&ptr);
+				umlen2 += iincchar(&ptr, mpos - ptr);
 			    }
 			}
 			if (!--n || (n <= 0 && (fl & SUB_GLOBAL))) {
-			    *sp = get_match_ret(*sp, t-s, mpos-s, fl,
-						replstr, repllist);
+			    *sp = get_match_ret(&imd, t-s, mpos-s);
 			    if (mpos == t)
-				mpos += mb_metacharlenconv(mpos, NULL);
+				mpos += mb_charlenconv(mpos, send - mpos, NULL);
 			}
 			if (!(fl & SUB_GLOBAL)) {
 			    if (n) {
@@ -2945,9 +2981,10 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 				 * the next character, even if it overlaps
 				 * with what we just found.
 				 */
-				umlen -= iincchar(&t);
+				umlen -= iincchar(&t, send - t);
 				continue;
 			    } else {
+				patfreestr(&patstralloc);
 				return 1;
 			    }
 			}
@@ -2958,11 +2995,11 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 			matched = 1;
 			while (t < mpos) {
 			    ioff++;
-			    umlen -= iincchar(&t);
+			    umlen -= iincchar(&t, send - t);
 			}
 			break;
 		    }
-		    umlen -= iincchar(&t);
+		    umlen -= iincchar(&t, send - t);
 		}
 	    } while (matched);
 	    /*
@@ -2972,8 +3009,9 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	     */
 	    set_pat_start(p, l);
 	    if ((fl & (SUB_LONG|SUB_GLOBAL)) == SUB_LONG &&
-		pattrylen(p, s + l, -1, -1, NULL, 0) && !--n) {
-		*sp = get_match_ret(*sp, 0, 0, fl, replstr, repllist);
+		pattrylen(p, send, 0, 0, &patstralloc, 0) && !--n) {
+		*sp = get_match_ret(&imd, 0, 0);
+		patfreestr(&patstralloc);
 		return 1;
 	    }
 	    break;
@@ -2983,8 +3021,10 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	    /* Longest/shortest at end, matching substrings.       */
 	    if (!(fl & SUB_LONG)) {
 		set_pat_start(p, l);
-		if (pattrylen(p, s + l, 0, 0, NULL, umltot) && !--n) {
-		    *sp = get_match_ret(*sp, l, l, fl, replstr, NULL);
+		if (pattrylen(p, send, 0, 0, &patstralloc, umltot) &&
+		    !--n) {
+		    *sp = get_match_ret(&imd, umltot, umltot);
+		    patfreestr(&patstralloc);
 		    return 1;
 		}
 	    }
@@ -3001,13 +3041,13 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	    nmatches = 0;
 	    tmatch = NULL;
 	    mb_charinit();
-	    for (ioff = 0, t = s, umlen = umltot; t < s + l; ioff++) {
+	    for (ioff = 0, t = s, umlen = umltot; t < send; ioff++) {
 		set_pat_start(p, t-s);
-		if (pattrylen(p, t, s + l - t, umlen, NULL, ioff)) {
+		if (pattrylen(p, t, umlen, 0, &patstralloc, ioff)) {
 		    nmatches++;
 		    tmatch = t;
 		}
-		umlen -= iincchar(&t);
+		umlen -= iincchar(&t, send - t);
 	    }
 	    if (nmatches) {
 		char *mpos;
@@ -3017,14 +3057,14 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 		     */
 		    n = nmatches - n;
 		    mb_charinit();
-		    for (ioff = 0, t = s, umlen = umltot; t < s + l; ioff++) {
+		    for (ioff = 0, t = s, umlen = umltot; t < send; ioff++) {
 			set_pat_start(p, t-s);
-			if (pattrylen(p, t, s + l - t, umlen, NULL, ioff) &&
+			if (pattrylen(p, t, umlen, 0, &patstralloc, ioff) &&
 			    !n--) {
 			    tmatch = t;
 			    break;
 			}
-			umlen -= iincchar(&t);
+			umlen -= iincchar(&t, send - t);
 		    }
 		}
 		mpos = tmatch + patmatchlen();
@@ -3032,29 +3072,31 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 		if (!(fl & SUB_LONG) && !(p->flags & PAT_PURES)) {
 		    for (t = tmatch, umlen = 0; t < mpos; ) {
 			set_pat_end(p, *t);
-			if (pattrylen(p, tmatch, t - tmatch, umlen,
-				      NULL, ioff)) {
+			if (pattrylen(p, tmatch, umlen, 0,
+				      &patstralloc, ioff)) {
 			    mpos = tmatch + patmatchlen();
 			    break;
 			}
-			umlen += iincchar(&t);
+			umlen += iincchar(&t, mpos - t);
 		    }
 		}
-		*sp = get_match_ret(*sp, tmatch-s, mpos-s, fl,
-				    replstr, NULL);
+		*sp = get_match_ret(&imd, tmatch-s, mpos-s);
+		patfreestr(&patstralloc);
 		return 1;
 	    }
 	    set_pat_start(p, l);
-	    if ((fl & SUB_LONG) && pattrylen(p, s + l, 0, 0, NULL, umltot) &&
+	    if ((fl & SUB_LONG) && pattrylen(p, send, 0, 0,
+					     &patstralloc, umltot) &&
 		!--n) {
-		*sp = get_match_ret(*sp, l, l, fl, replstr, NULL);
+		*sp = get_match_ret(&imd, umltot, umltot);
+		patfreestr(&patstralloc);
 		return 1;
 	    }
 	    break;
 	}
     }
 
-    if (repllist && nonempty(repllist)) {
+    if (imd.repllist && nonempty(imd.repllist)) {
 	/* Put all the bits of a global search and replace together. */
 	LinkNode nd;
 	Repldata rd;
@@ -3062,10 +3104,15 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	char *ptr, *start;
 	int i;
 
+	/*
+	 * Use metafied string again.
+	 * Results from get_match_ret in repllist are all metafied.
+	 */
+	s = *sp;
 	if (!(fl & SUB_LIST)) {
 	    lleft = 0;		/* size of returned string */
-	    i = 0;			/* start of last chunk we got from *sp */
-	    for (nd = firstnode(repllist); nd; incnode(nd)) {
+	    i = 0;	       /* start of last chunk we got from *sp */
+	    for (nd = firstnode(imd.repllist); nd; incnode(nd)) {
 		rd = (Repldata) getdata(nd);
 		lleft += rd->b - i; /* previous chunk of *sp */
 		lleft += strlen(rd->replstr);	/* the replaced bit */
@@ -3074,7 +3121,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	    lleft += l - i;	/* final chunk from *sp */
 	    start = t = zhalloc(lleft+1);
 	    i = 0;
-	    for (nd = firstnode(repllist); nd; incnode(nd)) {
+	    for (nd = firstnode(imd.repllist); nd; incnode(nd)) {
 		rd = (Repldata) getdata(nd);
 		memcpy(t, s + i, rd->b - i);
 		t += rd->b - i;
@@ -3087,13 +3134,19 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	    start[lleft] = '\0';
 	    *sp = (char *)start;
 	}
+	patfreestr(&patstralloc);
 	return 1;
     }
-    if (fl & SUB_LIST)		/* safety: don't think this can happen */
+    if (fl & SUB_LIST) {	/* safety: don't think this can happen */
+	patfreestr(&patstralloc);
 	return 0;
+    }
 
     /* munge the whole string: no match, so no replstr */
-    *sp = get_match_ret(*sp, 0, 0, fl, 0, 0);
+    imd.replstr = NULL;
+    imd.repllist = NULL;
+    *sp = get_match_ret(&imd, 0, 0);
+    patfreestr(&patstralloc);
     return (fl & SUB_RETFAIL) ? 0 : 1;
 }
 
@@ -3111,7 +3164,7 @@ static int
 igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	  LinkList *repllistp)
 {
-    char *s = *sp, *t;
+    char *s = *sp, *t, *send;
     /*
      * Note that ioff and uml count characters in the character
      * set (Meta's are not included), while l counts characters in the
@@ -3119,36 +3172,48 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
      * lengths.
      */
     int ioff, l = strlen(*sp), uml = ztrlen(*sp), matched = 1, umlen;
-    /*
-     * List of bits of matches to concatenate with replacement string.
-     * The data is a struct repldata.  It is not used in cases like
-     * ${...//#foo/bar} even though SUB_GLOBAL is set, since the match
-     * is anchored.  It goes on the heap.
-     */
-    LinkList repllist = NULL;
+    struct patstralloc patstralloc;
+    struct imatchdata imd;
+
+    (void)patallocstr(p, s, l, uml, 1, &patstralloc);
+    s = patstralloc.alloced;
+    DPUTS(!s, "forced patallocstr failed");
+    send = s + uml;
+
+    imd.mstr = *sp;
+    imd.mlen = l;
+    imd.ustr = s;
+    imd.ulen = uml;
+    imd.flags = fl;
+    imd.replstr = replstr;
+    imd.repllist = NULL;
 
     /* perform must-match test for complex closures */
     if (p->mustoff)
     {
-	/*
-	 * Yuk.  Probably we should rewrite this whole function to
-	 * use an unmetafied test string.
-	 *
-	 * Use META_HEAPDUP because we need a terminating NULL.
-	 */
-	char *muststr = metafy((char *)p + p->mustoff,
-			       p->patmlen, META_HEAPDUP);
+	char *muststr = (char *)p + p->mustoff;
 
-	if (!strstr(s, muststr))
-	    matched = 0;
+	matched = 0;
+	if (p->patmlen <= uml)
+	{
+	    for (t = s; t <= send - p->patmlen; t++)
+	    {
+		if (!memcmp(muststr, t, p->patmlen)) {
+		    matched = 1;
+		    break;
+		}
+	    }
+	}
     }
 
     /* in case we used the prog before... */
     p->flags &= ~(PAT_NOTSTART|PAT_NOTEND);
 
     if (fl & SUB_ALL) {
-	int i = matched && pattry(p, s);
-	*sp = get_match_ret(*sp, 0, i ? l : 0, fl, i ? replstr : 0, NULL);
+	int i = matched && pattrylen(p, s, uml, 0, &patstralloc, 0);
+	if (!i)
+	    imd.replstr = NULL;
+	*sp = get_match_ret(&imd, 0, i ? l : 0);
 	if (! **sp && (((fl & SUB_MATCH) && !i) || ((fl & SUB_REST) && i)))
 	    return 0;
 	return 1;
@@ -3161,23 +3226,25 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	     * Largest/smallest possible match at head of string.
 	     * First get the longest match...
 	     */
-	    if (pattry(p, s)) {
+	    if (pattrylen(p, s, uml, 0, &patstralloc, 0)) {
 		/* patmatchlen returns metafied length, as we need */
 	        int mlen = patmatchlen();
 		if (!(fl & SUB_LONG) && !(p->flags & PAT_PURES)) {
+		    send = s + mlen;
 		    /*
 		     * ... now we know whether it's worth looking for the
 		     * shortest, which we do by brute force.
 		     */
 		    for (t = s, umlen = 0; t < s + mlen; METAINC(t), umlen++) {
 			set_pat_end(p, *t);
-			if (pattrylen(p, s, t - s, umlen, NULL, 0)) {
+			if (pattrylen(p, s, umlen, 0, &patstralloc, 0)) {
 			    mlen = patmatchlen();
 			    break;
 			}
 		    }
 		}
-		*sp = get_match_ret(*sp, 0, mlen, fl, replstr, NULL);
+		*sp = get_match_ret(&imd, 0, mlen);
+		patfreestr(&patstralloc);
 		return 1;
 	    }
 	    break;
@@ -3186,17 +3253,13 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	    /* Smallest possible match at tail of string:  *
 	     * move back down string until we get a match. *
 	     * There's no optimization here.               */
-	    for (ioff = uml, t = s + l, umlen = 0; t >= s;
+	    for (ioff = uml, t = send, umlen = 0; t >= s;
 		 t--, ioff--, umlen++) {
-		if (t > s && t[-1] == Meta)
-		    t--;
 		set_pat_start(p, t-s);
-		if (pattrylen(p, t, s + l - t, umlen, NULL, ioff)) {
-		    *sp = get_match_ret(*sp, t - s, l, fl, replstr, NULL);
+		if (pattrylen(p, t, umlen, 0, &patstralloc, ioff)) {
+		    *sp = get_match_ret(&imd, t - s, uml);
 		    return 1;
 		}
-		if (t > s+1 && t[-2] == Meta)
-		    t--;
 	    }
 	    break;
 
@@ -3204,61 +3267,59 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	    /* Largest possible match at tail of string:       *
 	     * move forward along string until we get a match. *
 	     * Again there's no optimisation.                  */
-	    for (ioff = 0, t = s, umlen = uml; t < s + l;
-		 ioff++, METAINC(t), umlen--) {
+	    for (ioff = 0, t = s, umlen = uml; t < send;
+		 ioff++, t++, umlen--) {
 		set_pat_start(p, t-s);
-		if (pattrylen(p, t, s + l - t, umlen, NULL, ioff)) {
-		    *sp = get_match_ret(*sp, t-s, l, fl, replstr, NULL);
+		if (pattrylen(p, t, send - t, umlen, &patstralloc, ioff)) {
+		    *sp = get_match_ret(&imd, t-s, uml);
 		    return 1;
 		}
-		if (*t == Meta)
-		    t++;
 	    }
 	    break;
 
 	case SUB_SUBSTR:
 	    /* Smallest at start, but matching substrings. */
 	    set_pat_start(p, l);
-	    if (!(fl & SUB_GLOBAL) && pattry(p, s + l) && !--n) {
-		*sp = get_match_ret(*sp, 0, 0, fl, replstr, NULL);
+	    if (!(fl & SUB_GLOBAL) &&
+		pattrylen(p, send, 0, 0, &patstralloc, 0) && !--n) {
+		*sp = get_match_ret(&imd, 0, 0);
 		return 1;
 	    } /* fall through */
 	case (SUB_SUBSTR|SUB_LONG):
 	    /* longest or smallest at start with substrings */
 	    t = s;
 	    if (fl & SUB_GLOBAL) {
-		repllist = newlinklist();
+		imd.repllist = newlinklist();
 		if (repllistp)
-		    *repllistp = repllist;
+		    *repllistp = imd.repllist;
 	    }
 	    ioff = 0;		/* offset into string */
 	    umlen = uml;
 	    do {
 		/* loop over all matches for global substitution */
 		matched = 0;
-		for (; t < s + l; METAINC(t), ioff++, umlen--) {
+		for (; t < send; t++, ioff++, umlen--) {
 		    /* Find the longest match from this position. */
 		    set_pat_start(p, t-s);
-		    if (pattrylen(p, t, s + l - t, umlen, NULL, ioff)) {
+		    if (pattrylen(p, t, send - t, umlen, &patstralloc, ioff)) {
 			char *mpos = t + patmatchlen();
 			if (!(fl & SUB_LONG) && !(p->flags & PAT_PURES)) {
 			    char *ptr;
 			    int umlen2;
 			    for (ptr = t, umlen2 = 0; ptr < mpos;
-				 METAINC(ptr), umlen2++) {
+				 ptr++, umlen2++) {
 				set_pat_end(p, *ptr);
 				if (pattrylen(p, t, ptr - t, umlen2,
-					      NULL, ioff)) {
+					      &patstralloc, ioff)) {
 				    mpos = t + patmatchlen();
 				    break;
 				}
 			    }
 			}
 			if (!--n || (n <= 0 && (fl & SUB_GLOBAL))) {
-			    *sp = get_match_ret(*sp, t-s, mpos-s, fl,
-						replstr, repllist);
+			    *sp = get_match_ret(&imd, t-s, mpos-s);
 			    if (mpos == t)
-				METAINC(mpos);
+				mpos++;
 			}
 			if (!(fl & SUB_GLOBAL)) {
 			    if (n) {
@@ -3278,13 +3339,13 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 			 * which is already marked for replacement.
 			 */
 			matched = 1;
-			for ( ; t < mpos; t++, ioff++, umlen--)
-			    if (*t == Meta)
-				t++;
+			while (t < mpos) {
+			    ioff++;
+			    umlen--;
+			    t++;
+			}
 			break;
 		    }
-		    if (*t == Meta)
-			t++;
 		}
 	    } while (matched);
 	    /*
@@ -3294,8 +3355,9 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	     */
 	    set_pat_start(p, l);
 	    if ((fl & (SUB_LONG|SUB_GLOBAL)) == SUB_LONG &&
-		pattry(p, s + l) && !--n) {
-		*sp = get_match_ret(*sp, 0, 0, fl, replstr, repllist);
+		pattrylen(p, send, 0, 0, &patstralloc, 0) && !--n) {
+		*sp = get_match_ret(&imd, 0, 0);
+		patfreestr(&patstralloc);
 		return 1;
 	    }
 	    break;
@@ -3305,47 +3367,50 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	    /* Longest/shortest at end, matching substrings.       */
 	    if (!(fl & SUB_LONG)) {
 		set_pat_start(p, l);
-		if (pattrylen(p, s + l, 0, 0, NULL, uml) && !--n) {
-		    *sp = get_match_ret(*sp, l, l, fl, replstr, NULL);
+		if (pattrylen(p, send, 0, 0, &patstralloc, uml) && !--n) {
+		    *sp = get_match_ret(&imd, uml, uml);
+		    patfreestr(&patstralloc);
 		    return 1;
 		}
 	    }
-	    for (ioff = uml - 1, t = s + l - 1, umlen = 1; t >= s;
+	    for (ioff = uml - 1, t = send - 1, umlen = 1; t >= s;
 		 t--, ioff--, umlen++) {
-		if (t > s && t[-1] == Meta)
-		    t--;
 		set_pat_start(p, t-s);
-		if (pattrylen(p, t, s + l - t, umlen, NULL, ioff) && !--n) {
+		if (pattrylen(p, t, send - t, umlen, &patstralloc, ioff) &&
+		    !--n) {
 		    /* Found the longest match */
 		    char *mpos = t + patmatchlen();
 		    if (!(fl & SUB_LONG) && !(p->flags & PAT_PURES)) {
 			char *ptr;
 			int umlen2;
 			for (ptr = t, umlen2 = 0; ptr < mpos;
-			     METAINC(ptr), umlen2++) {
+			     ptr++, umlen2++) {
 			    set_pat_end(p, *ptr);
-			    if (pattrylen(p, t, ptr - t, umlen2, NULL, ioff)) {
+			    if (pattrylen(p, t, umlen2, 0, &patstralloc,
+					  ioff)) {
 				mpos = t + patmatchlen();
 				break;
 			    }
 			}
 		    }
-		    *sp = get_match_ret(*sp, t-s, mpos-s, fl,
-					replstr, NULL);
+		    *sp = get_match_ret(&imd, t-s, mpos-s);
+		    patfreestr(&patstralloc);
 		    return 1;
 		}
 	    }
 	    set_pat_start(p, l);
-	    if ((fl & SUB_LONG) && pattrylen(p, s + l, 0, 0, NULL, uml) &&
+	    if ((fl & SUB_LONG) && pattrylen(p, send, 0, 0,
+					     &patstralloc, uml) &&
 		!--n) {
-		*sp = get_match_ret(*sp, l, l, fl, replstr, NULL);
+		*sp = get_match_ret(&imd, uml, uml);
+		patfreestr(&patstralloc);
 		return 1;
 	    }
 	    break;
 	}
     }
 
-    if (repllist && nonempty(repllist)) {
+    if (imd.repllist && nonempty(imd.repllist)) {
 	/* Put all the bits of a global search and replace together. */
 	LinkNode nd;
 	Repldata rd;
@@ -3353,8 +3418,13 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	char *ptr, *start;
 	int i;
 
+	/*
+	 * Use metafied string again.
+	 * Results from get_match_ret in repllist are all metafied.
+	 */
+	s = *sp;
 	i = 0;			/* start of last chunk we got from *sp */
-	for (nd = firstnode(repllist); nd; incnode(nd)) {
+	for (nd = firstnode(imd.repllist); nd; incnode(nd)) {
 	    rd = (Repldata) getdata(nd);
 	    lleft += rd->b - i; /* previous chunk of *sp */
 	    lleft += strlen(rd->replstr);	/* the replaced bit */
@@ -3363,7 +3433,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	lleft += l - i;	/* final chunk from *sp */
 	start = t = zhalloc(lleft+1);
 	i = 0;
-	for (nd = firstnode(repllist); nd; incnode(nd)) {
+	for (nd = firstnode(imd.repllist); nd; incnode(nd)) {
 	    rd = (Repldata) getdata(nd);
 	    memcpy(t, s + i, rd->b - i);
 	    t += rd->b - i;
@@ -3375,11 +3445,15 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	memcpy(t, s + i, l - i);
 	start[lleft] = '\0';
 	*sp = (char *)start;
+	patfreestr(&patstralloc);
 	return 1;
     }
 
     /* munge the whole string: no match, so no replstr */
-    *sp = get_match_ret(*sp, 0, 0, fl, 0, 0);
+    imd.replstr = NULL;
+    imd.repllist = NULL;
+    *sp = get_match_ret(&imd, 0, 0);
+    patfreestr(&patstralloc);
     return 1;
 }
 
diff --git a/Src/pattern.c b/Src/pattern.c
index 03ba37d..8de372c 100644
--- a/Src/pattern.c
+++ b/Src/pattern.c
@@ -2204,7 +2204,10 @@ pattrylen(Patprog prog, char *string, int len, int unmetalen,
  * the pattern module) at which we are trying to match.
  * This is added in to the positions recorded in patbeginp and patendp
  * when we are looking for substrings.  Currently this only happens
- * in the parameter substitution code.
+ * in the parameter substitution code.  It refers to a real character
+ * offset, i.e. is already in the form ready for presentation to the
+ * general public --- this is necessary as we don't have the
+ * information to convert it down here.
  *
  * Note this is a character offset, i.e. a single possibly metafied and
  * possibly multibyte character counts as 1.
@@ -2292,7 +2295,8 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin,
 	     */
 	    if (!patstralloc->progstrunmeta)
 	    {
-		patstralloc->progstrunmeta = dupstring(progstr);
+		patstralloc->progstrunmeta =
+		    dupstrpfx(progstr, (int)prog->patmlen);
 		unmetafy(patstralloc->progstrunmeta,
 			 &patstralloc->progstrunmetalen);
 	    }
@@ -2346,7 +2350,7 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin,
 		 * In the orignal structure, but it might be unmetafied
 		 * for use with an unmetafied test string.
 		 */
-		patinlen = (int)prog->patmlen;
+		patinlen = pstrlen;
 		/* if matching files, must update globbing flags */
 		patglobflags = prog->globend;
 
@@ -2360,7 +2364,7 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin,
 			 * Unmetafied: pstrlen contains unmetafied
 			 * length in bytes.
 			 */
-			str = metafy(patinstart, pstrlen, META_ALLOC);
+			str = metafy(patinstart, pstrlen, META_DUP);
 			mlen = CHARSUB(patinstart, patinstart + pstrlen);
 		    } else {
 			str = ztrduppfx(patinstart, patinlen);
@@ -2454,8 +2458,8 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin,
 	    /*
 	     * Optimization: if we didn't find any Meta characters
 	     * to begin with, we don't need to look for them now.
-	     * Only do this if we did the unmetfication internally,
-	     * since otherwise it's too hard to work out.
+	     *
+	     * For patstralloc pased in, we want the unmetafied length.
 	     */
 	    if (patstralloc == &patstralloc_struct &&
 		patstralloc->unmetalen != origlen) {
@@ -2588,7 +2592,9 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin,
 
 /*
  * Return length of previous succesful match.  This is
- * in metafied bytes, i.e. includes a count of Meta characters.
+ * in metafied bytes, i.e. includes a count of Meta characters,
+ * unless the match was done on an unmetafied string using
+ * a patstralloc stuct, in which case it, too is unmetafed.
  * Unusual and futile attempt at modular encapsulation.
  */
 
diff --git a/Src/zsh.h b/Src/zsh.h
index 32f2e0c..15fa5e4 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -480,6 +480,7 @@ typedef struct heap      *Heap;
 typedef struct heapstack *Heapstack;
 typedef struct histent   *Histent;
 typedef struct hookdef   *Hookdef;
+typedef struct imatchdata *Imatchdata;
 typedef struct jobfile   *Jobfile;
 typedef struct job       *Job;
 typedef struct linkedmod *Linkedmod;
@@ -1593,6 +1594,31 @@ typedef struct zpc_disables_save *Zpc_disables_save;
 /* Range: token followed by the (possibly multibyte) start and end */
 #define PP_RANGE  21
 
+/*
+ * Argument to get_match_ret() in glob.c
+ */
+struct imatchdata {
+    /* Metafied trial string */
+    char *mstr;
+    /* Its length */
+    int mlen;
+    /* Unmetafied string */
+    char *ustr;
+    /* Its length */
+    int ulen;
+    /* Flags (SUB_*) */
+    int flags;
+    /* Replacement string (metafied) */
+    char *replstr;
+    /*
+     * List of bits of matches to concatenate with replacement string.
+     * The data is a struct repldata.  It is not used in cases like
+     * ${...//#foo/bar} even though SUB_GLOBAL is set, since the match
+     * is anchored.  It goes on the heap.
+     */
+    LinkList repllist;
+};
+
 /* Globbing flags: lower 8 bits gives approx count */
 #define GF_LCMATCHUC	0x0100
 #define GF_IGNCASE	0x0200


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Substitution ${...///} slows down when certain UTF character occurs
  2015-09-29 18:37             ` Peter Stephenson
@ 2015-09-29 19:23               ` Bart Schaefer
  2015-09-30  8:59                 ` Peter Stephenson
  0 siblings, 1 reply; 19+ messages in thread
From: Bart Schaefer @ 2015-09-29 19:23 UTC (permalink / raw)
  To: zsh-workers

On Sep 29,  7:37pm, Peter Stephenson wrote:
}
} This uses the new interface.  I haven't done any testing apart from the
} normal test suite.

I ran my looping version of Sebastian's test program and got comparable
(fast!) times for all of his samples.


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Substitution ${...///} slows down when certain UTF character occurs
  2015-09-29 19:23               ` Bart Schaefer
@ 2015-09-30  8:59                 ` Peter Stephenson
  2015-09-30 14:04                   ` Peter Stephenson
  0 siblings, 1 reply; 19+ messages in thread
From: Peter Stephenson @ 2015-09-30  8:59 UTC (permalink / raw)
  To: zsh-workers

On Tue, 29 Sep 2015 12:23:56 -0700
Bart Schaefer <schaefer@brasslantern.com> wrote:
> On Sep 29,  7:37pm, Peter Stephenson wrote:
> }
> } This uses the new interface.  I haven't done any testing apart from the
> } normal test suite.
> 
> I ran my looping version of Sebastian's test program and got comparable
> (fast!) times for all of his samples.

OK, that suggests we're now allocating memory infrequently enough (as
intended) that it's safe to put it on the heap, which simplifies things
further.  One other unnecessary chunk removed.

pws

diff --git a/Src/glob.c b/Src/glob.c
index d998663..24e60d0 100644
--- a/Src/glob.c
+++ b/Src/glob.c
@@ -2478,9 +2478,6 @@ get_match_ret(Imatchdata imd, int b, int e)
 	if (imeta(*p))
 	    add++;
     e += add;
-    for (; p < imd->ustr + imd->ulen; p++)
-	if (imeta(*p))
-	    add++;
 
     /* Everything now refers to metafied lengths. */
     if (replstr || (fl & SUB_LIST)) {
@@ -2808,7 +2805,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	    imd.replstr = NULL;
 	}
 	*sp = get_match_ret(&imd, 0, umltot);
-	patfreestr(&patstralloc);
 	if (! **sp && (((fl & SUB_MATCH) && !i) || ((fl & SUB_REST) && i)))
 	    return 0;
 	return 1;
@@ -2856,7 +2852,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 		    }
 		}
 		*sp = get_match_ret(&imd, 0, mlen);
-		patfreestr(&patstralloc);
 		return 1;
 	    }
 	    break;
@@ -2884,13 +2879,11 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	    }
 	    if (tmatch) {
 		*sp = get_match_ret(&imd, tmatch - s, umltot);
-		patfreestr(&patstralloc);
 		return 1;
 	    }
 	    if (!(fl & SUB_START) && pattrylen(p, s + umltot, 0, 0,
 					       &patstralloc, ioff)) {
 		*sp = get_match_ret(&imd, umltot, umltot);
-		patfreestr(&patstralloc);
 		return 1;
 	    }
 	    break;
@@ -2904,7 +2897,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 		set_pat_start(p, t-s);
 		if (pattrylen(p, t, umlen, 0, &patstralloc, ioff)) {
 		    *sp = get_match_ret(&imd, t-s, umltot);
-		    patfreestr(&patstralloc);
 		    return 1;
 		}
 		if (fl & SUB_START)
@@ -2914,7 +2906,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	    if (!(fl & SUB_START) && pattrylen(p, send, 0, 0,
 					       &patstralloc, ioff)) {
 		*sp = get_match_ret(&imd, umltot, umltot);
-		patfreestr(&patstralloc);
 		return 1;
 	    }
 	    break;
@@ -2926,7 +2917,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 		pattrylen(p, send, 0, 0, &patstralloc, 0) &&
 		!--n) {
 		*sp = get_match_ret(&imd, 0, 0);
-		patfreestr(&patstralloc);
 		return 1;
 	    } /* fall through */
 	case (SUB_SUBSTR|SUB_LONG):
@@ -2984,7 +2974,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 				umlen -= iincchar(&t, send - t);
 				continue;
 			    } else {
-				patfreestr(&patstralloc);
 				return 1;
 			    }
 			}
@@ -3011,7 +3000,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	    if ((fl & (SUB_LONG|SUB_GLOBAL)) == SUB_LONG &&
 		pattrylen(p, send, 0, 0, &patstralloc, 0) && !--n) {
 		*sp = get_match_ret(&imd, 0, 0);
-		patfreestr(&patstralloc);
 		return 1;
 	    }
 	    break;
@@ -3024,7 +3012,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 		if (pattrylen(p, send, 0, 0, &patstralloc, umltot) &&
 		    !--n) {
 		    *sp = get_match_ret(&imd, umltot, umltot);
-		    patfreestr(&patstralloc);
 		    return 1;
 		}
 	    }
@@ -3081,7 +3068,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 		    }
 		}
 		*sp = get_match_ret(&imd, tmatch-s, mpos-s);
-		patfreestr(&patstralloc);
 		return 1;
 	    }
 	    set_pat_start(p, l);
@@ -3089,7 +3075,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 					     &patstralloc, umltot) &&
 		!--n) {
 		*sp = get_match_ret(&imd, umltot, umltot);
-		patfreestr(&patstralloc);
 		return 1;
 	    }
 	    break;
@@ -3134,11 +3119,9 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	    start[lleft] = '\0';
 	    *sp = (char *)start;
 	}
-	patfreestr(&patstralloc);
 	return 1;
     }
     if (fl & SUB_LIST) {	/* safety: don't think this can happen */
-	patfreestr(&patstralloc);
 	return 0;
     }
 
@@ -3146,7 +3129,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
     imd.replstr = NULL;
     imd.repllist = NULL;
     *sp = get_match_ret(&imd, 0, 0);
-    patfreestr(&patstralloc);
     return (fl & SUB_RETFAIL) ? 0 : 1;
 }
 
@@ -3244,7 +3226,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 		    }
 		}
 		*sp = get_match_ret(&imd, 0, mlen);
-		patfreestr(&patstralloc);
 		return 1;
 	    }
 	    break;
@@ -3357,7 +3338,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	    if ((fl & (SUB_LONG|SUB_GLOBAL)) == SUB_LONG &&
 		pattrylen(p, send, 0, 0, &patstralloc, 0) && !--n) {
 		*sp = get_match_ret(&imd, 0, 0);
-		patfreestr(&patstralloc);
 		return 1;
 	    }
 	    break;
@@ -3369,7 +3349,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 		set_pat_start(p, l);
 		if (pattrylen(p, send, 0, 0, &patstralloc, uml) && !--n) {
 		    *sp = get_match_ret(&imd, uml, uml);
-		    patfreestr(&patstralloc);
 		    return 1;
 		}
 	    }
@@ -3394,7 +3373,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 			}
 		    }
 		    *sp = get_match_ret(&imd, t-s, mpos-s);
-		    patfreestr(&patstralloc);
 		    return 1;
 		}
 	    }
@@ -3403,7 +3381,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 					     &patstralloc, uml) &&
 		!--n) {
 		*sp = get_match_ret(&imd, uml, uml);
-		patfreestr(&patstralloc);
 		return 1;
 	    }
 	    break;
@@ -3445,7 +3422,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	memcpy(t, s + i, l - i);
 	start[lleft] = '\0';
 	*sp = (char *)start;
-	patfreestr(&patstralloc);
 	return 1;
     }
 
@@ -3453,7 +3429,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
     imd.replstr = NULL;
     imd.repllist = NULL;
     *sp = get_match_ret(&imd, 0, 0);
-    patfreestr(&patstralloc);
     return 1;
 }
 
diff --git a/Src/pattern.c b/Src/pattern.c
index 8de372c..68a3409 100644
--- a/Src/pattern.c
+++ b/Src/pattern.c
@@ -2028,8 +2028,8 @@ pattrystart(void)
  *
  * Unmetafy a trial string for use in pattern matching, if needed.
  *
- * If it is needed, returns a zalloc()'d string; if not needed, returns
- * NULL.
+ * If it is needed, returns a heap allocated string; if not needed,
+ * returns NULL.
  *
  * prog is the pattern to be executed.
  * string is the metafied trial string.
@@ -2046,7 +2046,7 @@ pattrystart(void)
  *  unmetalenp is the umetafied length of a path segment preceeding
  *    the trial string needed for file mananagement; it is calculated as
  *    needed so does not need to be initialised.
- *  alloced is the memory allocated --- same as return value from
+ *  alloced is the memory allocated on the heap --- same as return value from
  *    function.
  */
 /**/
@@ -2097,7 +2097,7 @@ char *patallocstr(Patprog prog, char *string, int stringlen, int unmetalen,
 	int i, icopy, ncopy;
 
 	dst = patstralloc->alloced =
-	    zalloc(patstralloc->unmetalen + patstralloc->unmetalenp);
+	    zhalloc(patstralloc->unmetalen + patstralloc->unmetalenp);
 
 	if (needfullpath) {
 	    /* loop twice, copy path buffer first time */
@@ -2134,20 +2134,6 @@ char *patallocstr(Patprog prog, char *string, int stringlen, int unmetalen,
 
 
 /*
- * Free memory allocated by patallocstr().
- */
-
-/**/
-mod_export
-void patfreestr(Patstralloc patstralloc)
-{
-    if (patstralloc->alloced)
-	zfree(patstralloc->alloced,
-	      patstralloc->unmetalen + patstralloc->unmetalenp);
-}
-
-
-/*
  * Test prog against null-terminated, metafied string.
  */
 
@@ -2189,8 +2175,9 @@ pattrylen(Patprog prog, char *string, int len, int unmetalen,
  * done if there is no path prefix (pathpos == 0) as otherwise the path
  * buffer and unmetafied string may not match.  To do this,
  * patallocstr() is callled (use force = 1 to ensure it is alway
- * unmetafied); paststralloc points to existing storage.  When all
- * pattern matching is done, patfreestr() is called.
+ * unmetafied); paststralloc points to existing storage. Memory is
+ * on the heap.
+ *
  * patstralloc->alloced and patstralloc->unmetalen contain the
  * unmetafied string and its length.  In that case, the rules for the
  * earlier arguments change:
@@ -2387,8 +2374,6 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin,
 	    }
 	}
 
-	if (patstralloc == &patstralloc_struct)
-	    patfreestr(patstralloc);
 	return ret;
     } else {
 	int q = queue_signal_level();
@@ -2425,8 +2410,6 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin,
 	    }
 	}
 	if (!ret) {
-	    if (patstralloc == &patstralloc_struct)
-		patfreestr(patstralloc);
 	    return 0;
 	}
 
@@ -2583,9 +2566,6 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin,
 
 	restore_queue_signals(q);
 
-	if (patstralloc == &patstralloc_struct)
-	    patfreestr(patstralloc);
-
 	return ret;
     }
 }


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Substitution ${...///} slows down when certain UTF character occurs
  2015-09-30  8:59                 ` Peter Stephenson
@ 2015-09-30 14:04                   ` Peter Stephenson
  2015-09-30 21:19                     ` Bart Schaefer
  0 siblings, 1 reply; 19+ messages in thread
From: Peter Stephenson @ 2015-09-30 14:04 UTC (permalink / raw)
  To: zsh-workers

On Wed, 30 Sep 2015 09:59:50 +0100
Peter Stephenson <p.stephenson@samsung.com> wrote:
> On Tue, 29 Sep 2015 12:23:56 -0700
> Bart Schaefer <schaefer@brasslantern.com> wrote:
> > On Sep 29,  7:37pm, Peter Stephenson wrote:
> > }
> > } This uses the new interface.  I haven't done any testing apart from the
> > } normal test suite.
> > 
> > I ran my looping version of Sebastian's test program and got comparable
> > (fast!) times for all of his samples.
> 
> OK, that suggests we're now allocating memory infrequently enough (as
> intended) that it's safe to put it on the heap, which simplifies things
> further.  One other unnecessary chunk removed.

Except it doesn't work yet.

In some complex git completion --- reproducible only in one set up ---
the heap allocation is apparently going out of bounds.  Yet I've checked
and nothing seems able to happen that can affect this.  If I add
debugging, the same pointer is reported as returned from zhalloc() that
is later claimed to be out of bounds.  Yet with more debugging there's
no popheap() or switch_heap() happening, as by eye there can't be.  I'm
a bit stuck; how can a piece of memory returned by zhalloc() suddenly go
invalid?

valgrind agrees with gdb but doesn't give any more help.

Maybe we're just running out of memory after all?  That's a pretty big
stack...  I think it's a clue that the address reported as failed
usually ends in three 000's while as you'd expect the allocated address
is basically randomly 4-byte alligned in general.  A further clue is the
crash is never quite in the same place twice, just in some pattryrefs()
within igetmatch().

pushing and popping the heap locally doesn't work as we need to pass
stuff back on the heap.

Maybe I should just go back to zalloc().

pws

#0  0x0000000000495438 in pattryrefs (prog=0x2b3cc2f29fc0, 
    string=0x2b3cc2f2a000 <Address 0x2b3cc2f2a000 out of bounds>, stringlen=0, 
    unmetalenin=0, patstralloc=0x7fffa76b7fe0, patoffset=0, nump=0x0, 
    begp=0x0, endp=0x0) at pattern.c:2228
#1  0x00000000004953b3 in pattrylen (prog=0x2b3cc2f29fc0, 
    string=0x2b3cc2f2a000 <Address 0x2b3cc2f2a000 out of bounds>, len=0, 
    unmetalen=0, patstralloc=0x7fffa76b7fe0, offset=0) at pattern.c:2158
#2  0x0000000000445e82 in igetmatch (sp=0x7fffa76b8210, p=0x2b3cc2f29fc0, 
    fl=22, n=1, replstr=0x2b3cc2f29f90 ",", repllistp=0x0) at glob.c:3001
#3  0x000000000044502d in getmatch (sp=0x7fffa76b8210, 
    pat=0x2b3cc2f29f8c " ->", fl=22, n=1, replstr=0x2b3cc2f29f90 ",")
    at glob.c:2630
#4  0x00000000004a8d1b in paramsubst (l=0x7fffa76b88c0, n=0x7fffa76b88a0, 
    str=0x7fffa76b8610, qt=0, pf_flags=4) at subst.c:2939
#5  0x00000000004a33c7 in stringsubst (list=0x7fffa76b88c0, 
    node=0x7fffa76b88a0, pf_flags=4, asssub=0) at subst.c:236
#6  0x00000000004a271d in prefork (list=0x7fffa76b88c0, flags=6) at subst.c:77
#7  0x000000000043287a in addvars (state=0x7fffa76b9890, pc=0x1fa8918, 
    addflags=0) at exec.c:2291
#8  0x000000000042e603 in execsimple (state=0x7fffa76b9890) at exec.c:1118
#9  0x000000000042ebfb in execlist (state=0x7fffa76b9890, dont_change_job=1, 
    exiting=0) at exec.c:1255
#10 0x0000000000465f6c in execfor (state=0x7fffa76b9890, do_exec=0)
    at loop.c:175
#11 0x0000000000436a46 in execcmd (state=0x7fffa76b9890, input=0, output=0, 
    how=2, last1=2) at exec.c:3473
#12 0x000000000043113e in execpline2 (state=0x7fffa76b9890, pcode=1219, how=2, 
    input=0, output=0, last1=0) at exec.c:1747
#13 0x000000000042fbc5 in execpline (state=0x7fffa76b9890, slcode=133122, 
    how=2, last1=0) at exec.c:1525
#14 0x000000000042ed58 in execlist (state=0x7fffa76b9890, dont_change_job=1, 
    exiting=0) at exec.c:1284
#15 0x000000000042e4b8 in execode (p=0x1fa4340, dont_change_job=1, exiting=0, 
    context=0x4c213a "shfunc") at exec.c:1075
#16 0x000000000043b4ac in runshfunc (prog=0x1fa4340, wrap=0x0, 
    name=0x2b3cc2f255b8 "__git_recent_commits") at exec.c:5357
#17 0x00002b3cc22ca8f0 in comp_wrapper (prog=0x1fa4340, w=0x0, 
    name=0x2b3cc2f255b8 "__git_recent_commits") at complete.c:1459
#18 0x000000000043b3f2 in runshfunc (prog=0x1fa4340, wrap=0x2b3cc24e97c0, 
    name=0x2b3cc2f255b8 "__git_recent_commits") at exec.c:5342
#19 0x000000000043ae6c in doshfunc (shfunc=0x1fa8e88, doshargs=0x2b3cc2f254e8, 
    noreturnval=0) at exec.c:5223
#20 0x000000000043a0c4 in execshfunc (shf=0x1fa8e88, args=0x2b3cc2f254e8)
    at exec.c:4854
#21 0x0000000000436c0a in execcmd (state=0x7fffa76bace0, input=0, output=0, 
    how=2, last1=2) at exec.c:3525
#22 0x000000000043113e in execpline2 (state=0x7fffa76bace0, pcode=323, how=2, 
    input=0, output=0, last1=0) at exec.c:1747
#23 0x000000000042fbc5 in execpline (state=0x7fffa76bace0, slcode=4162, how=2, 
    last1=0) at exec.c:1525
#24 0x000000000042eef6 in execlist (state=0x7fffa76bace0, dont_change_job=1, 
    exiting=0) at exec.c:1326
#25 0x000000000042e4b8 in execode (p=0x1fa41f0, dont_change_job=1, exiting=0, 
    context=0x4c213a "shfunc") at exec.c:1075
#26 0x000000000043b4ac in runshfunc (prog=0x1fa41f0, wrap=0x0, 
    name=0x2b3cc2f25280 "__git_commit_objects_prefer_recent") at exec.c:5357
#27 0x00002b3cc22ca8f0 in comp_wrapper (prog=0x1fa41f0, w=0x0, 
    name=0x2b3cc2f25280 "__git_commit_objects_prefer_recent")
    at complete.c:1459
#28 0x000000000043b3f2 in runshfunc (prog=0x1fa41f0, wrap=0x2b3cc24e97c0, 
    name=0x2b3cc2f25280 "__git_commit_objects_prefer_recent") at exec.c:5342
#29 0x000000000043ae6c in doshfunc (shfunc=0x1fa7aa0, doshargs=0x2b3cc2f25168, 
    noreturnval=0) at exec.c:5223
#30 0x000000000043a0c4 in execshfunc (shf=0x1fa7aa0, args=0x2b3cc2f25168)
    at exec.c:4854
#31 0x0000000000436c0a in execcmd (state=0x7fffa76bf790, input=0, output=0, 
    how=18, last1=2) at exec.c:3525
#32 0x000000000043113e in execpline2 (state=0x7fffa76bf790, pcode=3971, 
    how=18, input=0, output=0, last1=0) at exec.c:1747
#33 0x000000000042fbc5 in execpline (state=0x7fffa76bf790, slcode=3074, 
    how=18, last1=0) at exec.c:1525
#34 0x000000000042ed58 in execlist (state=0x7fffa76bf790, dont_change_job=1, 
    exiting=0) at exec.c:1284
#35 0x0000000000466adc in execwhile (state=0x7fffa76bf790, do_exec=0)
    at loop.c:452
#36 0x0000000000436a46 in execcmd (state=0x7fffa76bf790, input=0, output=0, 
    how=18, last1=2) at exec.c:3473
#37 0x000000000043113e in execpline2 (state=0x7fffa76bf790, pcode=3907, 
    how=18, input=0, output=0, last1=0) at exec.c:1747
#38 0x000000000042fbc5 in execpline (state=0x7fffa76bf790, slcode=15362, 
    how=18, last1=0) at exec.c:1525
#39 0x000000000042ed58 in execlist (state=0x7fffa76bf790, dont_change_job=1, 
    exiting=0) at exec.c:1284
#40 0x0000000000466edc in execif (state=0x7fffa76bf790, do_exec=0)
    at loop.c:565
#41 0x0000000000436a46 in execcmd (state=0x7fffa76bf790, input=0, output=0, 
    how=18, last1=2) at exec.c:3473
#42 0x000000000043113e in execpline2 (state=0x7fffa76bf790, pcode=1987, 
    how=18, input=0, output=0, last1=0) at exec.c:1747
#43 0x000000000042fbc5 in execpline (state=0x7fffa76bf790, slcode=148482, 
    how=18, last1=0) at exec.c:1525
#44 0x000000000042ed58 in execlist (state=0x7fffa76bf790, dont_change_job=1, 
    exiting=0) at exec.c:1284
#45 0x0000000000466edc in execif (state=0x7fffa76bf790, do_exec=0)
    at loop.c:565
#46 0x0000000000436a46 in execcmd (state=0x7fffa76bf790, input=0, output=0, 
    how=18, last1=2) at exec.c:3473
#47 0x000000000043113e in execpline2 (state=0x7fffa76bf790, pcode=1603, 
    how=18, input=0, output=0, last1=0) at exec.c:1747
#48 0x000000000042fbc5 in execpline (state=0x7fffa76bf790, slcode=180226, 
    how=18, last1=0) at exec.c:1525
#49 0x000000000042ed58 in execlist (state=0x7fffa76bf790, dont_change_job=1, 
    exiting=0) at exec.c:1284
#50 0x0000000000465f6c in execfor (state=0x7fffa76bf790, do_exec=0)
    at loop.c:175
#51 0x0000000000436a46 in execcmd (state=0x7fffa76bf790, input=0, output=0, 
    how=2, last1=2) at exec.c:3473
#52 0x000000000043113e in execpline2 (state=0x7fffa76bf790, pcode=1539, how=2, 
    input=0, output=0, last1=0) at exec.c:1747
#53 0x000000000042fbc5 in execpline (state=0x7fffa76bf790, slcode=186370, 
    how=2, last1=0) at exec.c:1525
#54 0x000000000042ed58 in execlist (state=0x7fffa76bf790, dont_change_job=1, 
    exiting=0) at exec.c:1284
#55 0x0000000000466adc in execwhile (state=0x7fffa76bf790, do_exec=0)
    at loop.c:452
#56 0x0000000000436a46 in execcmd (state=0x7fffa76bf790, input=0, output=0, 
    how=2, last1=2) at exec.c:3473
#57 0x000000000043113e in execpline2 (state=0x7fffa76bf790, pcode=1475, how=2, 
    input=0, output=0, last1=0) at exec.c:1747
#58 0x000000000042fbc5 in execpline (state=0x7fffa76bf790, slcode=206850, 
    how=2, last1=0) at exec.c:1525
#59 0x000000000042ed58 in execlist (state=0x7fffa76bf790, dont_change_job=1, 
    exiting=0) at exec.c:1284
#60 0x000000000042e4b8 in execode (p=0x1fc1cf0, dont_change_job=1, exiting=0, 
    context=0x4c213a "shfunc") at exec.c:1075
#61 0x000000000043b4ac in runshfunc (prog=0x1fc1cf0, wrap=0x0, 
    name=0x2b3cc2f23520 "_alternative") at exec.c:5357
#62 0x00002b3cc22ca8f0 in comp_wrapper (prog=0x1fc1cf0, w=0x0, 
    name=0x2b3cc2f23520 "_alternative") at complete.c:1459
#63 0x000000000043b3f2 in runshfunc (prog=0x1fc1cf0, wrap=0x2b3cc24e97c0, 
    name=0x2b3cc2f23520 "_alternative") at exec.c:5342
#64 0x000000000043ae6c in doshfunc (shfunc=0x1de5530, doshargs=0x2b3cc2f23318, 
    noreturnval=0) at exec.c:5223
#65 0x000000000043a0c4 in execshfunc (shf=0x1de5530, args=0x2b3cc2f23318)
    at exec.c:4854
#66 0x0000000000436c0a in execcmd (state=0x7fffa76c0be0, input=0, output=0, 
    how=18, last1=2) at exec.c:3525
#67 0x000000000043113e in execpline2 (state=0x7fffa76c0be0, pcode=963, how=18, 
    input=0, output=0, last1=0) at exec.c:1747
#68 0x000000000042fbc5 in execpline (state=0x7fffa76c0be0, slcode=6146, 
    how=18, last1=0) at exec.c:1525
#69 0x000000000042ed58 in execlist (state=0x7fffa76c0be0, dont_change_job=1, 
    exiting=0) at exec.c:1284
#70 0x000000000042e4b8 in execode (p=0x1fa4228, dont_change_job=1, exiting=0, 
    context=0x4c213a "shfunc") at exec.c:1075
#71 0x000000000043b4ac in runshfunc (prog=0x1fa4228, wrap=0x0, 
    name=0x2b3cc2f227f8 "__git_commits") at exec.c:5357
#72 0x00002b3cc22ca8f0 in comp_wrapper (prog=0x1fa4228, w=0x0, 
    name=0x2b3cc2f227f8 "__git_commits") at complete.c:1459
#73 0x000000000043b3f2 in runshfunc (prog=0x1fa4228, wrap=0x2b3cc24e97c0, 
    name=0x2b3cc2f227f8 "__git_commits") at exec.c:5342
#74 0x000000000043ae6c in doshfunc (shfunc=0x1fa7df0, doshargs=0x2b3cc2f22730, 
    noreturnval=0) at exec.c:5223
#75 0x000000000043a0c4 in execshfunc (shf=0x1fa7df0, args=0x2b3cc2f22730)
    at exec.c:4854
#76 0x0000000000436c0a in execcmd (state=0x7fffa76c2030, input=0, output=0, 
    how=18, last1=2) at exec.c:3525
#77 0x000000000043113e in execpline2 (state=0x7fffa76c2030, pcode=1155, 
    how=18, input=0, output=0, last1=0) at exec.c:1747
#78 0x000000000042fbc5 in execpline (state=0x7fffa76c2030, slcode=5122, 
    how=18, last1=0) at exec.c:1525
#79 0x000000000042ed58 in execlist (state=0x7fffa76c2030, dont_change_job=1, 
    exiting=0) at exec.c:1284
#80 0x000000000042e4b8 in execode (p=0x1fa44c8, dont_change_job=1, exiting=0, 
    context=0x4c213a "shfunc") at exec.c:1075
#81 0x000000000043b4ac in runshfunc (prog=0x1fa44c8, wrap=0x0, 
    name=0x2b3cc2d0deb0 "__git_commit_ranges") at exec.c:5357
#82 0x00002b3cc22ca8f0 in comp_wrapper (prog=0x1fa44c8, w=0x0, 
    name=0x2b3cc2d0deb0 "__git_commit_ranges") at complete.c:1459
#83 0x000000000043b3f2 in runshfunc (prog=0x1fa44c8, wrap=0x2b3cc24e97c0, 
    name=0x2b3cc2d0deb0 "__git_commit_ranges") at exec.c:5342
#84 0x000000000043ae6c in doshfunc (shfunc=0x1fa9a00, doshargs=0x2b3cc2d0de18, 
    noreturnval=0) at exec.c:5223
#85 0x000000000043a0c4 in execshfunc (shf=0x1fa9a00, args=0x2b3cc2d0de18)
    at exec.c:4854
#86 0x0000000000436c0a in execcmd (state=0x7fffa76c4a40, input=0, output=0, 
    how=2, last1=2) at exec.c:3525
#87 0x000000000043113e in execpline2 (state=0x7fffa76c4a40, pcode=1923, how=2, 
    input=0, output=0, last1=0) at exec.c:1747
#88 0x000000000042fbc5 in execpline (state=0x7fffa76c4a40, slcode=4130, how=2, 
    last1=0) at exec.c:1525
#89 0x000000000042eda7 in execlist (state=0x7fffa76c4a40, dont_change_job=1, 
    exiting=0) at exec.c:1293
#90 0x0000000000466edc in execif (state=0x7fffa76c4a40, do_exec=0)
    at loop.c:565
#91 0x0000000000436a46 in execcmd (state=0x7fffa76c4a40, input=0, output=0, 
    how=2, last1=2) at exec.c:3473
#92 0x000000000043113e in execpline2 (state=0x7fffa76c4a40, pcode=1859, how=2, 
    input=0, output=0, last1=0) at exec.c:1747
#93 0x000000000042fbc5 in execpline (state=0x7fffa76c4a40, slcode=19458, 
    how=2, last1=0) at exec.c:1525
#94 0x000000000042ed58 in execlist (state=0x7fffa76c4a40, dont_change_job=1, 
    exiting=0) at exec.c:1284
#95 0x000000000046731d in execcase (state=0x7fffa76c4a40, do_exec=0)
    at loop.c:658
#96 0x0000000000436a46 in execcmd (state=0x7fffa76c4a40, input=0, output=0, 
    how=2, last1=2) at exec.c:3473
#97 0x000000000043113e in execpline2 (state=0x7fffa76c4a40, pcode=1091, how=2, 
    input=0, output=0, last1=0) at exec.c:1747
#98 0x000000000042fbc5 in execpline (state=0x7fffa76c4a40, slcode=129026, 
    how=2, last1=0) at exec.c:1525
#99 0x000000000042ed58 in execlist (state=0x7fffa76c4a40, dont_change_job=1, 
    exiting=0) at exec.c:1284
#100 0x000000000042e4b8 in execode (p=0x1eca350, dont_change_job=1, exiting=0, 
    context=0x4c213a "shfunc") at exec.c:1075
#101 0x000000000043b4ac in runshfunc (prog=0x1eca350, wrap=0x0, 
    name=0x2b3cc2b041b0 "_git-log") at exec.c:5357
#102 0x00002b3cc22ca8f0 in comp_wrapper (prog=0x1eca350, w=0x0, 
    name=0x2b3cc2b041b0 "_git-log") at complete.c:1459
#103 0x000000000043b3f2 in runshfunc (prog=0x1eca350, wrap=0x2b3cc24e97c0, 
    name=0x2b3cc2b041b0 "_git-log") at exec.c:5342
#104 0x000000000043ae6c in doshfunc (shfunc=0x1ea9648, 
    doshargs=0x2b3cc2b04148, noreturnval=0) at exec.c:5223
#105 0x000000000043a0c4 in execshfunc (shf=0x1ea9648, args=0x2b3cc2b04148)
    at exec.c:4854
#106 0x0000000000436c0a in execcmd (state=0x7fffa76c6950, input=0, output=0, 
    how=2, last1=2) at exec.c:3525
#107 0x000000000043113e in execpline2 (state=0x7fffa76c6950, pcode=1475, 
    how=2, input=0, output=0, last1=0) at exec.c:1747
#108 0x000000000042fbc5 in execpline (state=0x7fffa76c6950, slcode=3074, 
    how=2, last1=0) at exec.c:1525
#109 0x000000000042ed58 in execlist (state=0x7fffa76c6950, dont_change_job=1, 
    exiting=0) at exec.c:1284
#110 0x0000000000466edc in execif (state=0x7fffa76c6950, do_exec=0)
    at loop.c:565
#111 0x0000000000436a46 in execcmd (state=0x7fffa76c6950, input=0, output=0, 
    how=2, last1=2) at exec.c:3473
#112 0x000000000043113e in execpline2 (state=0x7fffa76c6950, pcode=1411, 
    how=2, input=0, output=0, last1=0) at exec.c:1747
#113 0x000000000042fbc5 in execpline (state=0x7fffa76c6950, slcode=40962, 
    how=2, last1=0) at exec.c:1525
#114 0x000000000042ed58 in execlist (state=0x7fffa76c6950, dont_change_job=1, 
    exiting=0) at exec.c:1284
#115 0x000000000042e4b8 in execode (p=0x1fa5a38, dont_change_job=1, exiting=0, 
    context=0x4c213a "shfunc") at exec.c:1075
#116 0x000000000043b4ac in runshfunc (prog=0x1fa5a38, wrap=0x0, 
    name=0x2b3cc2b03a18 "_call_function") at exec.c:5357
#117 0x00002b3cc22ca8f0 in comp_wrapper (prog=0x1fa5a38, w=0x0, 
    name=0x2b3cc2b03a18 "_call_function") at complete.c:1459
#118 0x000000000043b3f2 in runshfunc (prog=0x1fa5a38, wrap=0x2b3cc24e97c0, 
    name=0x2b3cc2b03a18 "_call_function") at exec.c:5342
#119 0x000000000043ae6c in doshfunc (shfunc=0x1e24578, 
    doshargs=0x2b3cc2b03938, noreturnval=0) at exec.c:5223
#120 0x000000000043a0c4 in execshfunc (shf=0x1e24578, args=0x2b3cc2b03938)
    at exec.c:4854
#121 0x0000000000436c0a in execcmd (state=0x7fffa76c9e20, input=0, output=0, 
    how=18, last1=2) at exec.c:3525
#122 0x000000000043113e in execpline2 (state=0x7fffa76c9e20, pcode=4099, 
    how=18, input=0, output=0, last1=0) at exec.c:1747
#123 0x000000000042fbc5 in execpline (state=0x7fffa76c9e20, slcode=5378, 
    how=18, last1=0) at exec.c:1525
#124 0x000000000042ed58 in execlist (state=0x7fffa76c9e20, dont_change_job=1, 
    exiting=0) at exec.c:1284
#125 0x0000000000466e21 in execif (state=0x7fffa76c9e20, do_exec=0)
    at loop.c:549
#126 0x0000000000436a46 in execcmd (state=0x7fffa76c9e20, input=0, output=0, 
    how=18, last1=2) at exec.c:3473
#127 0x000000000043113e in execpline2 (state=0x7fffa76c9e20, pcode=4099, 
    how=18, input=0, output=0, last1=0) at exec.c:1747
#128 0x000000000042fbc5 in execpline (state=0x7fffa76c9e20, slcode=41986, 
    how=18, last1=0) at exec.c:1525
#129 0x000000000042ed58 in execlist (state=0x7fffa76c9e20, dont_change_job=1, 
    exiting=0) at exec.c:1284
#130 0x000000000046731d in execcase (state=0x7fffa76c9e20, do_exec=0)
    at loop.c:658
#131 0x0000000000436a46 in execcmd (state=0x7fffa76c9e20, input=0, output=0, 
    how=18, last1=2) at exec.c:3473
#132 0x000000000043113e in execpline2 (state=0x7fffa76c9e20, pcode=3651, 
    how=18, input=0, output=0, last1=0) at exec.c:1747
#133 0x000000000042fbc5 in execpline (state=0x7fffa76c9e20, slcode=72706, 
    how=18, last1=0) at exec.c:1525
#134 0x000000000042ed58 in execlist (state=0x7fffa76c9e20, dont_change_job=1, 
    exiting=0) at exec.c:1284
#135 0x0000000000466edc in execif (state=0x7fffa76c9e20, do_exec=0)
    at loop.c:565
#136 0x0000000000436a46 in execcmd (state=0x7fffa76c9e20, input=0, output=0, 
    how=2, last1=2) at exec.c:3473
#137 0x000000000043113e in execpline2 (state=0x7fffa76c9e20, pcode=1987, 
    how=2, input=0, output=0, last1=0) at exec.c:1747
#138 0x000000000042fbc5 in execpline (state=0x7fffa76c9e20, slcode=144386, 
    how=2, last1=0) at exec.c:1525
#139 0x000000000042ed58 in execlist (state=0x7fffa76c9e20, dont_change_job=1, 
    exiting=0) at exec.c:1284
#140 0x000000000042e4b8 in execode (p=0x1fa53e0, dont_change_job=1, exiting=0, 
    context=0x4c213a "shfunc") at exec.c:1075
#141 0x000000000043b4ac in runshfunc (prog=0x1fa53e0, wrap=0x0, 
    name=0x2b3cc2064810 "_git") at exec.c:5357
#142 0x00002b3cc22ca8f0 in comp_wrapper (prog=0x1fa53e0, w=0x0, 
    name=0x2b3cc2064810 "_git") at complete.c:1459
#143 0x000000000043b3f2 in runshfunc (prog=0x1fa53e0, wrap=0x2b3cc24e97c0, 
    name=0x2b3cc2064810 "_git") at exec.c:5342
#144 0x000000000043ae6c in doshfunc (shfunc=0x1fb5860, 
    doshargs=0x2b3cc20647c8, noreturnval=0) at exec.c:5223
#145 0x000000000043a0c4 in execshfunc (shf=0x1fb5860, args=0x2b3cc20647c8)
    at exec.c:4854
#146 0x0000000000436c0a in execcmd (state=0x7fffa76cb270, input=0, output=0, 
    how=18, last1=2) at exec.c:3525
#147 0x000000000043113e in execpline2 (state=0x7fffa76cb270, pcode=131, 
    how=18, input=0, output=0, last1=0) at exec.c:1747
#148 0x000000000042fbc5 in execpline (state=0x7fffa76cb270, slcode=3074, 
    how=18, last1=0) at exec.c:1525
#149 0x000000000042ed58 in execlist (state=0x7fffa76cb270, dont_change_job=1, 
    exiting=0) at exec.c:1284
#150 0x000000000042e4b8 in execode (p=0x2b3cc2064758, dont_change_job=1, 
    exiting=0, context=0x4be8bf "eval") at exec.c:1075
#151 0x0000000000425d77 in eval (argv=0x2b3cc20646f0) at builtin.c:5399
#152 0x00000000004262d9 in bin_eval (nam=0x2b3cc20646d8 "eval", 
    argv=0x2b3cc20646f0, ops=0x7fffa76cb360, func=14) at builtin.c:5568
#153 0x000000000040ff88 in execbuiltin (args=0x2b3cc2064690, assigns=0x0, 
    bn=0x6dde00) at builtin.c:484
#154 0x00000000004372f8 in execcmd (state=0x7fffa76cca00, input=0, output=0, 
    how=2, last1=2) at exec.c:3642
#155 0x000000000043113e in execpline2 (state=0x7fffa76cca00, pcode=4099, 
    how=2, input=0, output=0, last1=0) at exec.c:1747
#156 0x000000000042fbc5 in execpline (state=0x7fffa76cca00, slcode=4130, 
    how=2, last1=0) at exec.c:1525
#157 0x000000000042eda7 in execlist (state=0x7fffa76cca00, dont_change_job=1, 
    exiting=0) at exec.c:1293
#158 0x0000000000466edc in execif (state=0x7fffa76cca00, do_exec=0)
    at loop.c:565
#159 0x0000000000436a46 in execcmd (state=0x7fffa76cca00, input=0, output=0, 
    how=2, last1=2) at exec.c:3473
#160 0x000000000043113e in execpline2 (state=0x7fffa76cca00, pcode=3971, 
    how=2, input=0, output=0, last1=0) at exec.c:1747
#161 0x000000000042fbc5 in execpline (state=0x7fffa76cca00, slcode=43010, 
    how=2, last1=0) at exec.c:1525
#162 0x000000000042ed58 in execlist (state=0x7fffa76cca00, dont_change_job=1, 
    exiting=0) at exec.c:1284
#163 0x000000000042e4b8 in execode (p=0x1ec9dd8, dont_change_job=1, exiting=0, 
    context=0x4c213a "shfunc") at exec.c:1075
#164 0x000000000043b4ac in runshfunc (prog=0x1ec9dd8, wrap=0x0, 
    name=0x2b3cc2063ed8 "_dispatch") at exec.c:5357
#165 0x00002b3cc22ca8f0 in comp_wrapper (prog=0x1ec9dd8, w=0x0, 
    name=0x2b3cc2063ed8 "_dispatch") at complete.c:1459
#166 0x000000000043b3f2 in runshfunc (prog=0x1ec9dd8, wrap=0x2b3cc24e97c0, 
    name=0x2b3cc2063ed8 "_dispatch") at exec.c:5342
#167 0x000000000043ae6c in doshfunc (shfunc=0x1e4b4a8, 
    doshargs=0x2b3cc2063d50, noreturnval=0) at exec.c:5223
#168 0x000000000043a0c4 in execshfunc (shf=0x1e4b4a8, args=0x2b3cc2063d50)
    at exec.c:4854
#169 0x0000000000436c0a in execcmd (state=0x7fffa76cde50, input=0, output=0, 
    how=18, last1=2) at exec.c:3525
#170 0x000000000043113e in execpline2 (state=0x7fffa76cde50, pcode=2627, 
    how=18, input=0, output=0, last1=0) at exec.c:1747
#171 0x000000000042fbc5 in execpline (state=0x7fffa76cde50, slcode=8194, 
    how=18, last1=0) at exec.c:1525
#172 0x000000000042ed58 in execlist (state=0x7fffa76cde50, dont_change_job=1, 
    exiting=0) at exec.c:1284
#173 0x000000000042e4b8 in execode (p=0x1e50be0, dont_change_job=1, exiting=0, 
    context=0x4c213a "shfunc") at exec.c:1075
#174 0x000000000043b4ac in runshfunc (prog=0x1e50be0, wrap=0x0, 
    name=0x2b3cc2063a30 "_normal") at exec.c:5357
#175 0x00002b3cc22ca8f0 in comp_wrapper (prog=0x1e50be0, w=0x0, 
    name=0x2b3cc2063a30 "_normal") at complete.c:1459
#176 0x000000000043b3f2 in runshfunc (prog=0x1e50be0, wrap=0x2b3cc24e97c0, 
    name=0x2b3cc2063a30 "_normal") at exec.c:5342
#177 0x000000000043ae6c in doshfunc (shfunc=0x1e59058, 
    doshargs=0x2b3cc20639c8, noreturnval=0) at exec.c:5223
#178 0x000000000043a0c4 in execshfunc (shf=0x1e59058, args=0x2b3cc20639c8)
    at exec.c:4854
#179 0x0000000000436c0a in execcmd (state=0x7fffa76cfd60, input=0, output=0, 
    how=2, last1=2) at exec.c:3525
#180 0x000000000043113e in execpline2 (state=0x7fffa76cfd60, pcode=7555, 
    how=2, input=0, output=0, last1=0) at exec.c:1747
#181 0x000000000042fbc5 in execpline (state=0x7fffa76cfd60, slcode=4130, 
    how=2, last1=0) at exec.c:1525
#182 0x000000000042eda7 in execlist (state=0x7fffa76cfd60, dont_change_job=1, 
    exiting=0) at exec.c:1293
#183 0x0000000000466edc in execif (state=0x7fffa76cfd60, do_exec=0)
    at loop.c:565
#184 0x0000000000436a46 in execcmd (state=0x7fffa76cfd60, input=0, output=0, 
    how=2, last1=2) at exec.c:3473
#185 0x000000000043113e in execpline2 (state=0x7fffa76cfd60, pcode=7427, 
    how=2, input=0, output=0, last1=0) at exec.c:1747
#186 0x000000000042fbc5 in execpline (state=0x7fffa76cfd60, slcode=117762, 
    how=2, last1=0) at exec.c:1525
#187 0x000000000042ed58 in execlist (state=0x7fffa76cfd60, dont_change_job=1, 
    exiting=0) at exec.c:1284
#188 0x000000000042e4b8 in execode (p=0x1e61cd0, dont_change_job=1, exiting=0, 
    context=0x4c213a "shfunc") at exec.c:1075
#189 0x000000000043b4ac in runshfunc (prog=0x1e61cd0, wrap=0x0, 
    name=0x2b3cc2063318 "_complete") at exec.c:5357
#190 0x00002b3cc22ca8f0 in comp_wrapper (prog=0x1e61cd0, w=0x0, 
    name=0x2b3cc2063318 "_complete") at complete.c:1459
#191 0x000000000043b3f2 in runshfunc (prog=0x1e61cd0, wrap=0x2b3cc24e97c0, 
    name=0x2b3cc2063318 "_complete") at exec.c:5342
#192 0x000000000043ae6c in doshfunc (shfunc=0x1e4abf0, 
    doshargs=0x2b3cc20632b0, noreturnval=0) at exec.c:5223
#193 0x000000000043a0c4 in execshfunc (shf=0x1e4abf0, args=0x2b3cc20632b0)
    at exec.c:4854
#194 0x0000000000436c0a in execcmd (state=0x7fffa76d3dd0, input=0, output=0, 
    how=18, last1=2) at exec.c:3525
#195 0x000000000043113e in execpline2 (state=0x7fffa76d3dd0, pcode=12803, 
    how=18, input=0, output=0, last1=0) at exec.c:1747
#196 0x000000000042fbc5 in execpline (state=0x7fffa76d3dd0, slcode=3074, 
    how=18, last1=0) at exec.c:1525
#197 0x000000000042ed58 in execlist (state=0x7fffa76d3dd0, dont_change_job=1, 
    exiting=0) at exec.c:1284
#198 0x0000000000466e21 in execif (state=0x7fffa76d3dd0, do_exec=0)
    at loop.c:549
#199 0x0000000000436a46 in execcmd (state=0x7fffa76d3dd0, input=0, output=0, 
    how=2, last1=2) at exec.c:3473
#200 0x000000000043113e in execpline2 (state=0x7fffa76d3dd0, pcode=12483, 
    how=2, input=0, output=0, last1=0) at exec.c:1747
#201 0x000000000042fbc5 in execpline (state=0x7fffa76d3dd0, slcode=48130, 
    how=2, last1=0) at exec.c:1525
#202 0x000000000042ed58 in execlist (state=0x7fffa76d3dd0, dont_change_job=1, 
    exiting=0) at exec.c:1284
#203 0x0000000000465f6c in execfor (state=0x7fffa76d3dd0, do_exec=0)
    at loop.c:175
#204 0x0000000000436a46 in execcmd (state=0x7fffa76d3dd0, input=0, output=0, 
    how=2, last1=2) at exec.c:3473
#205 0x000000000043113e in execpline2 (state=0x7fffa76d3dd0, pcode=11971, 
    how=2, input=0, output=0, last1=0) at exec.c:1747
#206 0x000000000042fbc5 in execpline (state=0x7fffa76d3dd0, slcode=90114, 
    how=2, last1=0) at exec.c:1525
#207 0x000000000042ed58 in execlist (state=0x7fffa76d3dd0, dont_change_job=1, 
    exiting=0) at exec.c:1284
#208 0x0000000000465f6c in execfor (state=0x7fffa76d3dd0, do_exec=0)
    at loop.c:175
#209 0x0000000000436a46 in execcmd (state=0x7fffa76d3dd0, input=0, output=0, 
    how=2, last1=2) at exec.c:3473
#210 0x000000000043113e in execpline2 (state=0x7fffa76d3dd0, pcode=10499, 
    how=2, input=0, output=0, last1=0) at exec.c:1747
#211 0x000000000042fbc5 in execpline (state=0x7fffa76d3dd0, slcode=220162, 
    how=2, last1=0) at exec.c:1525
#212 0x000000000042ed58 in execlist (state=0x7fffa76d3dd0, dont_change_job=1, 
    exiting=0) at exec.c:1284
#213 0x00000000004674e9 in exectry (state=0x7fffa76d3dd0, do_exec=0)
    at loop.c:722
#214 0x0000000000436a46 in execcmd (state=0x7fffa76d3dd0, input=0, output=0, 
    how=2, last1=2) at exec.c:3473
#215 0x000000000043113e in execpline2 (state=0x7fffa76d3dd0, pcode=3075, 
    how=2, input=0, output=0, last1=0) at exec.c:1747
#216 0x000000000042fbc5 in execpline (state=0x7fffa76d3dd0, slcode=1631234, 
    how=2, last1=0) at exec.c:1525
#217 0x000000000042ed58 in execlist (state=0x7fffa76d3dd0, dont_change_job=1, 
    exiting=0) at exec.c:1284
#218 0x000000000042e4b8 in execode (p=0x1ec9c88, dont_change_job=1, exiting=0, 
    context=0x4c213a "shfunc") at exec.c:1075
#219 0x000000000043b4ac in runshfunc (prog=0x1ec9c88, wrap=0x0, 
    name=0x2b3cc2056048 "_main_complete") at exec.c:5357
#220 0x00002b3cc22ca8f0 in comp_wrapper (prog=0x1ec9c88, w=0x0, 
    name=0x2b3cc2056048 "_main_complete") at complete.c:1459
#221 0x000000000043b3f2 in runshfunc (prog=0x1ec9c88, wrap=0x2b3cc24e97c0, 
    name=0x2b3cc2056048 "_main_complete") at exec.c:5342
#222 0x000000000043ae6c in doshfunc (shfunc=0x1e54a70, doshargs=0x0, 
    noreturnval=1) at exec.c:5223
#223 0x00002b3cc22cd2d9 in callcompfunc (s=0x2b3cc204bc98 "^ma", 
    fn=0x1e63628 "_main_complete") at compcore.c:838
#224 0x00002b3cc22cdba0 in makecomplist (s=0x2b3cc204bc98 "^ma", incmd=0, 
    lst=0) at compcore.c:987
#225 0x00002b3cc22cb803 in do_completion (dummy=0x2b3cc22bdbc8, 
    dat=0x7fffa76d4780) at compcore.c:347
#226 0x0000000000472f19 in runhookdef (h=0x2b3cc22bdbc8, d=0x7fffa76d4780)
    at module.c:996
#227 0x00002b3cc20a2a75 in docompletion (s=0x1f0c848 "^ma", lst=0, incmd=0)
    at zle_tricky.c:2293
#228 0x00002b3cc209e0a7 in docomplete (lst=0) at zle_tricky.c:859
#229 0x00002b3cc209c4e0 in completeword (args=0x2b3cc22be1b0)
    at zle_tricky.c:232
#230 0x00002b3cc209c3c1 in completecall (args=0x2b3cc22be1b0)
    at zle_tricky.c:208
#231 0x00002b3cc2088d9b in execzlefunc (func=0x2b3cc22ba298, 
    args=0x2b3cc22be1b0, set_bindk=0) at zle_main.c:1360
#232 0x00002b3cc2087ed7 in zlecore () at zle_main.c:1072
#233 0x00002b3cc20888d9 in zleread (lp=0x6f51c8, rp=0x0, flags=7, context=0, 
    init=0x2b3cc20aff88 "zle-line-init", 
    finish=0x2b3cc20aff78 "zle-line-finish") at zle_main.c:1263
#234 0x00002b3cc208b51a in zle_main_entry (cmd=1, ap=0x7fffa76d4dc0)
    at zle_main.c:1929
#235 0x0000000000456c42 in zleentry (cmd=1) at init.c:1523
#236 0x0000000000457df5 in inputline () at input.c:293
#237 0x0000000000457c56 in ingetc () at input.c:226
#238 0x000000000044aa6a in ihgetc () at hist.c:391
#239 0x00000000004621aa in gettok () at lex.c:605
#240 0x00000000004618a3 in zshlex () at lex.c:271
#241 0x00000000004884ea in parse_event (endtok=37) at parse.c:561
#242 0x00000000004532e6 in loop (toplevel=1, justonce=0) at init.c:146
#243 0x0000000000457142 in zsh_main (argc=1, argv=0x7fffa76d5348)
    at init.c:1678
#244 0x000000000040f2e4 in main (argc=1, argv=0x7fffa76d5348) at ./main.c:93


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Substitution ${...///} slows down when certain UTF character occurs
  2015-09-30 14:04                   ` Peter Stephenson
@ 2015-09-30 21:19                     ` Bart Schaefer
  2015-10-01  8:41                       ` Peter Stephenson
  0 siblings, 1 reply; 19+ messages in thread
From: Bart Schaefer @ 2015-09-30 21:19 UTC (permalink / raw)
  To: zsh-workers

On Sep 30,  3:04pm, Peter Stephenson wrote:
} Subject: Re: Substitution ${...///} slows down when certain UTF character 
}
} In some complex git completion --- reproducible only in one set up ---
} the heap allocation is apparently going out of bounds.  Yet I've checked
} and nothing seems able to happen that can affect this.  If I add
} debugging, the same pointer is reported as returned from zhalloc() that
} is later claimed to be out of bounds.  Yet with more debugging there's
} no popheap() or switch_heap() happening, as by eye there can't be.  I'm
} a bit stuck; how can a piece of memory returned by zhalloc() suddenly go
} invalid?
} 
} valgrind agrees with gdb but doesn't give any more help.

Did you --enable-zsh-heap-debug and --enable-zsh-valgrind ?  I always
forget at least the latter of those ...

} Maybe we're just running out of memory after all?

That seems really unlikely, unless the explicit zalloc version shows a
similar issue.  But I suppose if the heap is never popped it might be
possible to run out of memory on a deep recursive glob.  Perhaps a
call to freeheap() is needed somewhere prior to the popheap()?  Or
maybe there *is* a freeheap() happening where it isn't any longer safe
to do so -- did you check for that?

Even if out of memory, I wouldn't expect an existing pointer to go bad.
You'd just fail to get a new one.  And heaps are mmap()d if possible so
in that case you'd have to be out of address space, not just out of
memory?


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Substitution ${...///} slows down when certain UTF character occurs
  2015-09-30 21:19                     ` Bart Schaefer
@ 2015-10-01  8:41                       ` Peter Stephenson
  2015-10-01 14:28                         ` Heap corruption [the thread formerly known as substitution] Peter Stephenson
  0 siblings, 1 reply; 19+ messages in thread
From: Peter Stephenson @ 2015-10-01  8:41 UTC (permalink / raw)
  To: zsh-workers

On Wed, 30 Sep 2015 14:19:37 -0700
Bart Schaefer <schaefer@brasslantern.com> wrote:
> On Sep 30,  3:04pm, Peter Stephenson wrote:
> } In some complex git completion --- reproducible only in one set up ---
> } the heap allocation is apparently going out of bounds.  Yet I've checked
> } and nothing seems able to happen that can affect this.  If I add
> } debugging, the same pointer is reported as returned from zhalloc() that
> } is later claimed to be out of bounds.  Yet with more debugging there's
> } no popheap() or switch_heap() happening, as by eye there can't be.  I'm
> } a bit stuck; how can a piece of memory returned by zhalloc() suddenly go
> } invalid?
> } 
> } valgrind agrees with gdb but doesn't give any more help.
> 
> Did you --enable-zsh-heap-debug and --enable-zsh-valgrind ?  I always
> forget at least the latter of those ...

I don't have the full valgrind library framework, just the executable,
on the system where this is happening.  (This is 64-bit and I haven't
seen it with a 32-bit system I have more control over in the same repo.)
But I tried heap debug and the last bit of output doesn't look obviously
suspicious --- I don't see a sign it's allocating masses of memory, for
example. Indeed, the last thing it did was a push, not a pop.

> } Maybe we're just running out of memory after all?
> 
> That seems really unlikely, unless the explicit zalloc version shows a
> similar issue.

Yes, zhalloc() gets memory from zalloc() which explicitly tests, and
there's no obvious way you could get a pointer of the sort I've got.

> But I suppose if the heap is never popped it might be
> possible to run out of memory on a deep recursive glob.  Perhaps a
> call to freeheap() is needed somewhere prior to the popheap()?  Or
> maybe there *is* a freeheap() happening where it isn't any longer safe
> to do so -- did you check for that?

Yes, I looked for popping, freeing and swapping of heaps and there
doesn't appear to be any in the immediate vicint.

> Even if out of memory, I wouldn't expect an existing pointer to go bad.
> You'd just fail to get a new one.  And heaps are mmap()d if possible so
> in that case you'd have to be out of address space, not just out of
> memory?

I tried not using mmap and the symptom is the same.

I get the feeling there's something here that simply switching back to
zalloc() is likely to obscure rather than fix.

pws


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Substitution ${...///} slows down when certain UTF character occurs
  2015-09-27 16:11     ` Bart Schaefer
  2015-09-28  8:51       ` Peter Stephenson
@ 2015-10-01 13:45       ` Sebastian Gniazdowski
  1 sibling, 0 replies; 19+ messages in thread
From: Sebastian Gniazdowski @ 2015-10-01 13:45 UTC (permalink / raw)
  To: zsh-workers

[-- Attachment #1: Type: text/plain, Size: 1169 bytes --]

On 27 September 2015 at 18:11, Bart Schaefer
> It'll get worse if there are partial matches, e.g., if you had 30000
> repetitions of "wfei" and scanned for "wfeiwj" there'd be a whole lot
> of backtracking.  There are no "w" anywhere in your sample $str so
> each of the comparisons is only one equality test.

It's still instant fast for 30k of wfei (attached is the script). I
also tried generating a [wfeiwj]-only string, and it's also fast:

cat /dev/urandom | env LC_CTYPE=C tr -cd 'wfeiwj' | head -c 120000 > input

Gave it one more try with
"wfeiwjwoiejfowiejfowijefoiwjefoiwjefoijwoeifjwoiejf" (30k of it, and
was searching for it) and it becomes slower (times 0.15s instead of
0.012s) but is still instant fast.

>
> Still I think the biggest issue is that unmetafication happening too
> low down.  Since pattry*() is being called repeatedly with the same two
> first arguments (prog and string) it might be possible to cache the
> unmetafied string after the first call.

I wonder why it depends on Zsh version and/or environment (OS, etc.).
This doesn't seem related to unmetafication, unless it was changed
after 5.0.2.

Best regards,
Sebastian Gniazdowski

[-- Attachment #2: test-script.zsh --]
[-- Type: application/octet-stream, Size: 507 bytes --]

#!/usr/local/bin/zsh

emulate -LR zsh

str=""

i=30000
while (( i -- )); do
    str[1,0]="wfei"
done
#echo "$str" > input


#char="–"
char="¥"
#char="Ń"
#char="Ł"
#char="Ǎ"
#char="Ǟ"

str[60]=$char
time ( out_array=( "${str//(#bi)wfeiwj/a}" ) )
str[60]="a"

str[10000]=$char
time ( out_array=( "${str//(#bi)wfeiwj/a}" ) )
str[10000]="a"

str[50000]=$char
time ( out_array=( "${str//(#bi)wfeiwj/a}" ) )
str[50000]="a"

str[100000]=$char
time ( out_array=( "${str//(#bi)wfeiwj/a}" ) )
str[100000]="a"


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Heap corruption [the thread formerly known as substitution]
  2015-10-01  8:41                       ` Peter Stephenson
@ 2015-10-01 14:28                         ` Peter Stephenson
  2015-10-01 15:07                           ` Bart Schaefer
  2015-10-01 15:13                           ` Peter Stephenson
  0 siblings, 2 replies; 19+ messages in thread
From: Peter Stephenson @ 2015-10-01 14:28 UTC (permalink / raw)
  To: zsh-workers

On Thu, 1 Oct 2015 09:41:40 +0100
Peter Stephenson <p.stephenson@samsung.com> wrote:
> > On Sep 30,  3:04pm, Peter Stephenson wrote:
> > } In some complex git completion --- reproducible only in one set up ---
> > } the heap allocation is apparently going out of bounds.

Some progress.  I've copied some heap info at the point the allocation
takes place --- this is a bespoke debug structure but it's pointing to
standard shell info:

(gdb) p copied_heap_info 
$1 = {heap = 0x2b98ac551000, arena = 0x2b98ac551028, size = 16344, 
  alloc = 0x2b98ac555000}
(gdb) p *copied_heap_info.heap
$2 = {next = 0x0, size = 16384, used = 16344, sp = 0x27a13b0, heap_id = 38650}

That "alloc" is what gdb, valgrind and the OS itself agree is out of
bounds.  Sure enough, the sums say the heap finishes at 0x2b98ac555000,
heap + 16384 or equivalently arena + 16344.  Likely this is the last
heap allocated.

All the addresses look consistent, no obvious of corruption unless it's
being very sneaky, so this is starting to look like a real heap problem
when you happen to get a chance address clash (remember this is a 64-bit
system, if that's relevant).

Bart, any immediate reaction before I dig further?

pws


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Heap corruption [the thread formerly known as substitution]
  2015-10-01 14:28                         ` Heap corruption [the thread formerly known as substitution] Peter Stephenson
@ 2015-10-01 15:07                           ` Bart Schaefer
  2015-10-01 15:13                           ` Peter Stephenson
  1 sibling, 0 replies; 19+ messages in thread
From: Bart Schaefer @ 2015-10-01 15:07 UTC (permalink / raw)
  To: zsh-workers

On Oct 1,  3:28pm, Peter Stephenson wrote:
}
} All the addresses look consistent, no obvious of corruption unless it's
} being very sneaky, so this is starting to look like a real heap problem
} when you happen to get a chance address clash (remember this is a 64-bit
} system, if that's relevant).
} 
} Bart, any immediate reaction before I dig further?

I got nothin'.

Also, I'm going to be mostly unavailable for the next few days, so don't
wait for my responses if you don't want to.


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Heap corruption [the thread formerly known as substitution]
  2015-10-01 14:28                         ` Heap corruption [the thread formerly known as substitution] Peter Stephenson
  2015-10-01 15:07                           ` Bart Schaefer
@ 2015-10-01 15:13                           ` Peter Stephenson
  2015-10-03 18:59                             ` Peter Stephenson
  1 sibling, 1 reply; 19+ messages in thread
From: Peter Stephenson @ 2015-10-01 15:13 UTC (permalink / raw)
  To: zsh-workers

On Thu, 1 Oct 2015 15:28:23 +0100
Peter Stephenson <p.stephenson@samsung.com> wrote:
> That "alloc" is what gdb, valgrind and the OS itself agree is out of
> bounds.  Sure enough, the sums say the heap finishes at 0x2b98ac555000,
> heap + 16384 or equivalently arena + 16344.  Likely this is the last
> heap allocated.

More news: Penny Finally Drops.

Yes, the pointer isn't usable --- but the length is zero so it can't be
dereferenced anyway.  A pointer one off the end of a valid range is
valid as long it's not dereferenced, so only the pattern code needs
fixing.  Was broken regardless of heap storage, that just showed it up.

pws

diff --git a/Src/pattern.c b/Src/pattern.c
index 68a3409..53bbd14 100644
--- a/Src/pattern.c
+++ b/Src/pattern.c
@@ -2224,8 +2224,10 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin,
 	maxnpos = *nump;
 	*nump = 0;
     }
-    /* inherited from domatch, but why, exactly? */
-    if (*string == Nularg) {
+    /*
+     * Special signalling of empty tokinised string.
+     */
+    if ((!patstralloc || stringlen > 0) && *string == Nularg) {
 	string++;
 	if (unmetalenin > 0)
 	    unmetalenin--;
@@ -2233,8 +2235,10 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin,
 	    stringlen--;
     }
 
-    if (stringlen < 0)
+    if (stringlen < 0) {
+	DPUTS(patstralloc != NULL, "length needed with patstralloc");
 	stringlen = strlen(string);
+    }
     origlen = stringlen;
 
     if (patstralloc) {


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Heap corruption [the thread formerly known as substitution]
  2015-10-01 15:13                           ` Peter Stephenson
@ 2015-10-03 18:59                             ` Peter Stephenson
  0 siblings, 0 replies; 19+ messages in thread
From: Peter Stephenson @ 2015-10-03 18:59 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: zsh-workers

On Thu, 01 Oct 2015 16:13:41 +0100
Peter Stephenson <p.stephenson@samsung.com> wrote:
> -    /* inherited from domatch, but why, exactly? */
> -    if (*string == Nularg) {
> +    /*
> +     * Special signalling of empty tokinised string.
> +     */
> +    if ((!patstralloc || stringlen > 0) && *string == Nularg) {

One extra piece of sanity is that we should do this once and before any
unmetafication which will obscure the difference between Nulart and a
formerly metafied Nularg.

pws

diff --git a/Src/pattern.c b/Src/pattern.c
index 04d3e3d..8b07cca 100644
--- a/Src/pattern.c
+++ b/Src/pattern.c
@@ -2023,6 +2023,39 @@ pattrystart(void)
 }
 
 /*
+ * Fix up string length stuff.
+ *
+ * If we call patallocstr() with "force" to set things up early, it's
+ * done there, else it's done in pattryrefs().  The reason for the
+ * difference is in the latter case we may not be relying on
+ * patallocstr() having an effect.
+ */
+
+/**/
+static void
+patmungestring(char **string, int *stringlen, int *unmetalenin)
+{
+    /*
+     * Special signalling of empty tokenised string.
+     */
+    if (*stringlen > 0 && **string == Nularg) {
+	(*string)++;
+	/*
+	 * If we don't have an unmetafied length
+	 * and need it (we may not) we'll get it later.
+	 */
+	if (*unmetalenin > 0)
+	    (*unmetalenin)--;
+	if (*stringlen > 0)
+	    (*stringlen)--;
+    }
+
+    /* Ensure we have a metafied length */
+    if (*stringlen < 0)
+	*stringlen = strlen(*string);
+}
+
+/*
  * Allocate memeory for pattern match.  Note this is specific to use
  * of pattern *and* trial string.
  *
@@ -2039,7 +2072,8 @@ pattrystart(void)
  * force is 1 if we always unmetafy: this is useful if we are going
  *   to try again with different versions of the string.  If this is
  *   called from pattryrefs() we don't force unmetafication as it won't
- *   be optimal.
+ *   be optimal.  This option should be used if the resulting
+ *   patstralloc is going to be passed to pattrylen() / pattryrefs().
  * In patstralloc (supplied by caller, must last until last pattry is done)
  *  unmetalen is the unmetafied length of the string; it will be
  *    calculated if the input value is negative.
@@ -2056,6 +2090,9 @@ char *patallocstr(Patprog prog, char *string, int stringlen, int unmetalen,
 {
     int needfullpath;
 
+    if (force)
+	patmungestring(&string, &stringlen, &unmetalen);
+
     /*
      * For a top-level ~-exclusion, we will need the full
      * path to exclude, so copy the path so far and append the
@@ -2224,21 +2261,9 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin,
 	maxnpos = *nump;
 	*nump = 0;
     }
-    /*
-     * Special signalling of empty tokenised string.
-     */
-    if ((!patstralloc || stringlen > 0) && *string == Nularg) {
-	string++;
-	if (unmetalenin > 0)
-	    unmetalenin--;
-	if (stringlen > 0)
-	    stringlen--;
-    }
 
-    if (stringlen < 0) {
-	DPUTS(patstralloc != NULL, "length needed with patstralloc");
-	stringlen = strlen(string);
-    }
+    if (!patstralloc)
+	patmungestring(&string, &stringlen, &unmetalenin);
     origlen = stringlen;
 
     if (patstralloc) {


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2015-10-03 19:05 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-26 12:19 Substitution ${...///} slows down when certain UTF character occurs Sebastian Gniazdowski
2015-09-26 20:44 ` Bart Schaefer
2015-09-27  8:13   ` Sebastian Gniazdowski
2015-09-27 16:11     ` Bart Schaefer
2015-09-28  8:51       ` Peter Stephenson
2015-09-28 11:30         ` Peter Stephenson
2015-09-28 19:23         ` Peter Stephenson
2015-09-29  8:44           ` Peter Stephenson
2015-09-29 18:37             ` Peter Stephenson
2015-09-29 19:23               ` Bart Schaefer
2015-09-30  8:59                 ` Peter Stephenson
2015-09-30 14:04                   ` Peter Stephenson
2015-09-30 21:19                     ` Bart Schaefer
2015-10-01  8:41                       ` Peter Stephenson
2015-10-01 14:28                         ` Heap corruption [the thread formerly known as substitution] Peter Stephenson
2015-10-01 15:07                           ` Bart Schaefer
2015-10-01 15:13                           ` Peter Stephenson
2015-10-03 18:59                             ` Peter Stephenson
2015-10-01 13:45       ` Substitution ${...///} slows down when certain UTF character occurs Sebastian Gniazdowski

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).