Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.80) (envelope-from ) id 1ab1MR-0001Or-6B for pgsql-performance@arkaria.postgresql.org; Wed, 02 Mar 2016 07:38:19 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84) (envelope-from ) id 1ab1MQ-0003aE-DW for pgsql-performance@arkaria.postgresql.org; Wed, 02 Mar 2016 07:38:18 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84) (envelope-from ) id 1ab1Ki-0001fY-Q6 for pgsql-performance@postgresql.org; Wed, 02 Mar 2016 07:36:32 +0000 Received: from mail-qg0-x22a.google.com ([2607:f8b0:400d:c04::22a]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.84) (envelope-from ) id 1ab1KY-0007De-Kw for pgsql-performance@postgresql.org; Wed, 02 Mar 2016 07:36:31 +0000 Received: by mail-qg0-x22a.google.com with SMTP id w104so1941050qge.1 for ; Tue, 01 Mar 2016 23:36:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=meraki.net; s=google; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc; bh=OMsPJyXXfclSnNxZ2MUP79q1q0gGuhMGAYSH7JIx1vQ=; b=ag7e/9og8hSVujdlSXuYPd4eTASJg++4H5HsiQ+q6t1/LeToG11E8h6Wqx+vCQpXIv N1etHXvPWEorXKt60QzpLryfXRqHwaoe1JLtnKq9dzVon3fkxyFT/1gPJVlrFRQh5Udq e+q44mwbZpCRDd9jRNHvaM7XKdr8jVgMbLoeM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc; bh=OMsPJyXXfclSnNxZ2MUP79q1q0gGuhMGAYSH7JIx1vQ=; b=OvzaAjCOkw2nJ7aOY7NE31pI3IRLwaQtUQ1OHXHXd3UPctTRGZct2O2Bftnd2XVIcv 7cIZR9GVCEHlfF1uB1xA6cxTv+RBJDIsFUttCx+JHDdkXDLI/8MdDasVtYUlXn0+YrlZ p4xNcfbrPzyMcMjntN9M3+DL+qmFrVI/bY95evEoIr9NdYC79OeZQU4EwXzSmWPP8kX6 ksi5TYf2X1xGc+DZc3f74Ch08HEOKr5f4CIZjavurd0fgoKKqnURmeW744dw4yLMZF3B wMpDavirbIepbwN02TGheRaPQi1KraiulVWbSZnieAh9/L2/1v0nPSpW04I/hh3LKTL4 uFvQ== X-Gm-Message-State: AD7BkJKqilGjgzmngjMMcDWuY63BMoJITaj5vjMVwbtOPuV9FDIdguXkpq+IvqtMUs3jVm7KrEEGbl9nBTPJHSTJ MIME-Version: 1.0 X-Received: by 10.140.97.9 with SMTP id l9mr31514728qge.106.1456904180644; Tue, 01 Mar 2016 23:36:20 -0800 (PST) Received: by 10.55.139.66 with HTTP; Tue, 1 Mar 2016 23:36:20 -0800 (PST) In-Reply-To: References: Date: Tue, 1 Mar 2016 23:36:20 -0800 Message-ID: Subject: Re: Merge joins on index scans From: James Parks To: David Rowley Cc: postgres performance list Content-Type: multipart/alternative; boundary=001a113a977c28e03c052d0bf0e2 X-Pg-Spam-Score: -2.7 (--) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-performance Precedence: bulk Sender: pgsql-performance-owner@postgresql.org --001a113a977c28e03c052d0bf0e2 Content-Type: text/plain; charset=UTF-8 On Sun, Feb 28, 2016 at 2:06 AM, David Rowley wrote: > On 27 February 2016 at 11:07, James Parks wrote: > > > > CREATE TABLE a (id bigint primary key, nonce bigint); > > CREATE TABLE b (id bigint primary key, a_id bigint not null); > > CREATE INDEX a_idx ON b (a_id); > > > > The query: > > > > SELECT b.* FROM b JOIN a ON b.a_id = a.id WHERE a.nonce = ? ORDER BY > b.id > > ASC; > > > > (skip down to [1] and [2] to see the query performance) > > > > What I know: > > > > If you force the query planner to use a merge join on the above query, it > > takes 10+ minutes to complete using the data as per below. If you force > the > > query planner to use a hash join on the same data, it takes ~200 > > milliseconds. > > I believe I know what is going on here, but can you please test; > > SELECT b.* FROM b WHERE EXISTS (SELECT 1 FROM a ON b.a_id = a.id AND > a.nonce = ?) ORDER BY b.id ASC; > > using the merge join plan. > > Here's the query plan for that query (slight modifications to get it to run): postgres=# explain (analyze,buffers) SELECT b.* FROM b WHERE EXISTS (SELECT 1 FROM a WHERE b.a_id = a.id AND a.nonce = 64) ORDER BY b.id ASC; QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------- Sort (cost=16639.19..16855.62 rows=86572 width=16) (actual time=145.117..173.298 rows=83427 loops=1) Sort Key: b.id Sort Method: external merge Disk: 2112kB Buffers: shared hit=86193 read=881, temp read=269 written=269 I/O Timings: read=3.199 -> Merge Semi Join (cost=795.82..8059.09 rows=86572 width=16) (actual time=6.680..91.862 rows=83427 loops=1) Merge Cond: (b.a_id = a.id) Buffers: shared hit=86193 read=881 I/O Timings: read=3.199 -> Index Scan using a_idx on b (cost=0.00..3036.70 rows=86572 width=16) (actual time=0.005..25.193 rows=83427 loops=1) Buffers: shared hit=1064 read=374 I/O Timings: read=1.549 -> Index Scan using a_pkey on a (cost=0.00..26259.85 rows=891 width=8) (actual time=6.663..35.177 rows=237 loops=1) Filter: (nonce = 64) Rows Removed by Filter: 87939 Buffers: shared hit=85129 read=507 I/O Timings: read=1.650 Total runtime: 186.825 ms ... so, yes, it does indeed get a lot faster > If this performs much better then the problem is due to the merge join > mark/restore causing the join to have to transition through many > tuples which don't match the a.nonce = ? predicate. The mark and > restore is not required for the rewritten query, as this use a semi > join rather than a regular inner join. With the semi join the executor > knows that it's only meant to be matching a single tuple in "a", so > once the first match is found it can move to the next row in the outer > relation without having to restore the scan back to where it started > matching that inner row again. > > If I'm right, to get around the problem you could; create index on a > (nonce, id); > > postgres=# CREATE INDEX a_id_nonce_idx ON a (nonce, id); CREATE INDEX postgres=# explain (analyze,buffers) SELECT b.* FROM b JOIN a ON b.a_id = a.id WHERE a.nonce = 64 ORDER BY b.id ASC; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------- Sort (cost=3376.57..3376.92 rows=140 width=16) (actual time=144.340..160.875 rows=83427 loops=1) Sort Key: b.id Sort Method: external merge Disk: 2120kB Buffers: shared hit=368 read=522, temp read=266 written=266 -> Merge Join (cost=69.50..3371.58 rows=140 width=16) (actual time=0.056..88.409 rows=83427 loops=1) Merge Cond: (b.a_id = a.id) Buffers: shared hit=368 read=522 -> Index Scan using a_idx on b (cost=0.29..2724.58 rows=83427 width=16) (actual time=0.009..23.834 rows=83427 loops=1) Buffers: shared hit=171 read=518 -> Index Only Scan using a_id_nonce_idx on a (cost=0.42..2450.58 rows=820 width=8) (actual time=0.041..20.776 rows=83658 loops=1) Index Cond: (nonce = 64) Heap Fetches: 83658 Buffers: shared hit=197 read=4 Planning time: 0.241 ms Execution time: 172.346 ms Looks pretty fast to me. That being said, the number of rows returned by the Index Only Scan seems a bit high, as compared to the results below, so I added your patch below and got [2]. > If such an index is out of the question then a patch has been > submitted for review which should fix this problem in (hopefully) > either 9.6 or 9.7 > https://commitfest.postgresql.org/9/129/ > If you have a test environment handy, it would be nice if you could > test the patch on the current git head to see if this fixes your > problem. The findings would be quite interesting for me. Please note > this patch is for test environments only at this stage, not for > production use. > Can confirm that your patch there seems to improve performance. HEAD [1], with patch: postgres=# explain (analyze,buffers) SELECT b.* FROM b JOIN a ON b.a_id = a.id WHERE a.nonce = 64 ORDER BY b.id ASC; QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------- Sort (cost=7320.39..7320.75 rows=144 width=16) (actual time=162.199..181.497 rows=83427 loops=1) Sort Key: b.id Sort Method: external merge Disk: 2120kB Buffers: shared hit=85780 read=472, temp read=266 written=266 -> Merge Join (cost=808.17..7315.23 rows=144 width=16) (actual time=9.719..101.864 rows=83427 loops=1) Merge Cond: (b.a_id = a.id) Buffers: shared hit=85780 read=472 -> Index Scan using a_idx on b (cost=0.29..2721.49 rows=83427 width=16) (actual time=0.059..26.346 rows=83427 loops=1) Buffers: shared hit=460 read=229 -> Index Scan using a_pkey on a (cost=0.42..24394.88 rows=846 width=8) (actual time=9.651..41.231 rows=237 loops=1) Filter: (nonce = 64) Rows Removed by Filter: 87939 Buffers: shared hit=85320 read=243 Planning time: 0.289 ms Execution time: 195.071 ms HEAD [1], without patch: postgres=# explain (analyze,buffers) SELECT b.* FROM b JOIN a ON b.a_id = a.id WHERE a.nonce = 64 ORDER BY b.id ASC; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------- Sort (cost=7285.48..7285.83 rows=140 width=16) (actual time=710073.059..710089.924 rows=83427 loops=1) Sort Key: b.id Sort Method: external merge Disk: 2120kB Buffers: shared hit=2149282200 read=243, temp read=266 written=266 -> Merge Join (cost=685.28..7280.49 rows=140 width=16) (actual time=10.022..709878.946 rows=83427 loops=1) Merge Cond: (b.a_id = a.id) Buffers: shared hit=2149282200 read=243 -> Index Scan using a_idx on b (cost=0.29..2724.58 rows=83427 width=16) (actual time=0.013..59.103 rows=83427 loops=1) Buffers: shared hit=689 -> Index Scan using a_pkey on a (cost=0.42..24404.69 rows=820 width=8) (actual time=9.998..709595.905 rows=83658 loops=1) Filter: (nonce = 64) Rows Removed by Filter: 2201063696 Buffers: shared hit=2149281511 read=243 Planning time: 0.297 ms Execution time: 710101.931 ms Thank you for your response! This allows us to understand the situations in which we can run into trouble, and what we can do in most, if not all cases, to resolve. Regards, James [1] HEAD is "a892234 Change the format of the VM fork to add a second bit per page." as found on the Github mirror of postgres [2] postgres=# explain (analyze,buffers) SELECT b.* FROM b JOIN a ON b.a_id = a.id WHERE a.nonce = 64 ORDER BY b.id ASC; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------- Sort (cost=11000.03..11001.07 rows=417 width=16) (actual time=109.739..129.031 rows=83427 loops=1) Sort Key: b.id Sort Method: external merge Disk: 2120kB Buffers: shared hit=886, temp read=266 written=266 -> Merge Join (cost=0.71..10981.88 rows=417 width=16) (actual time=0.050..55.701 rows=83427 loops=1) Merge Cond: (b.a_id = a.id) Buffers: shared hit=886 -> Index Scan using a_idx on b (cost=0.29..3975.70 rows=83427 width=16) (actual time=0.017..23.647 rows=83427 loops=1) Buffers: shared hit=689 -> Index Only Scan using a_id_nonce_idx on a (cost=0.42..6787.31 rows=2451 width=8) (actual time=0.028..0.172 rows=237 loops=1) Index Cond: (nonce = 64) Heap Fetches: 237 Buffers: shared hit=197 Planning time: 0.153 ms Execution time: 142.994 ms --001a113a977c28e03c052d0bf0e2 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: base64 PGRpdiBkaXI9Imx0ciI+PGRpdiBjbGFzcz0iZ21haWxfZXh0cmEiPjxkaXYgY2xhc3M9ImdtYWls X3F1b3RlIj5PbiBTdW4sIEZlYiAyOCwgMjAxNiBhdCAyOjA2IEFNLCBEYXZpZCBSb3dsZXkgPHNw YW4gZGlyPSJsdHIiPiZsdDs8YSBocmVmPSJtYWlsdG86ZGF2aWQucm93bGV5QDJuZHF1YWRyYW50 LmNvbSIgdGFyZ2V0PSJfYmxhbmsiPmRhdmlkLnJvd2xleUAybmRxdWFkcmFudC5jb208L2E+Jmd0 Ozwvc3Bhbj4gd3JvdGU6PGJyPjxibG9ja3F1b3RlIGNsYXNzPSJnbWFpbF9xdW90ZSIgc3R5bGU9 Im1hcmdpbjowcHggMHB4IDBweCAwLjhleDtib3JkZXItbGVmdDoxcHggc29saWQgcmdiKDIwNCwy MDQsMjA0KTtwYWRkaW5nLWxlZnQ6MWV4Ij48c3Bhbj5PbiAyNyBGZWJydWFyeSAyMDE2IGF0IDEx OjA3LCBKYW1lcyBQYXJrcyAmbHQ7PGEgaHJlZj0ibWFpbHRvOmphbWVzLnBhcmtzQG1lcmFraS5u ZXQiIHRhcmdldD0iX2JsYW5rIj5qYW1lcy5wYXJrc0BtZXJha2kubmV0PC9hPiZndDsgd3JvdGU6 PGJyPg0KJmd0Ozxicj4NCiZndDsgQ1JFQVRFIFRBQkxFIGEgKGlkIGJpZ2ludCBwcmltYXJ5IGtl eSwgbm9uY2UgYmlnaW50KTs8YnI+DQomZ3Q7IENSRUFURSBUQUJMRSBiIChpZCBiaWdpbnQgcHJp bWFyeSBrZXksIGFfaWQgYmlnaW50IG5vdCBudWxsKTs8YnI+DQomZ3Q7IENSRUFURSBJTkRFWCBh X2lkeCBPTiBiIChhX2lkKTs8YnI+DQomZ3Q7PGJyPg0KJmd0OyBUaGUgcXVlcnk6PGJyPg0KJmd0 Ozxicj4NCiZndDsgU0VMRUNUIGIuKiBGUk9NIGIgSk9JTiBhIE9OIGIuYV9pZCA9IDxhIGhyZWY9 Imh0dHA6Ly9hLmlkIiByZWw9Im5vcmVmZXJyZXIiIHRhcmdldD0iX2JsYW5rIj5hLmlkPC9hPiBX SEVSRSBhLm5vbmNlID0gPyBPUkRFUiBCWSA8YSBocmVmPSJodHRwOi8vYi5pZCIgcmVsPSJub3Jl ZmVycmVyIiB0YXJnZXQ9Il9ibGFuayI+Yi5pZDwvYT48YnI+DQomZ3Q7IEFTQzs8YnI+DQomZ3Q7 PGJyPg0KJmd0OyAoc2tpcCBkb3duIHRvIFsxXSBhbmQgWzJdIHRvIHNlZSB0aGUgcXVlcnkgcGVy Zm9ybWFuY2UpPGJyPg0KJmd0Ozxicj4NCiZndDsgV2hhdCBJIGtub3c6PGJyPg0KJmd0Ozxicj4N CiZndDsgSWYgeW91IGZvcmNlIHRoZSBxdWVyeSBwbGFubmVyIHRvIHVzZSBhIG1lcmdlIGpvaW4g b24gdGhlIGFib3ZlIHF1ZXJ5LCBpdDxicj4NCiZndDsgdGFrZXMgMTArIG1pbnV0ZXMgdG8gY29t cGxldGUgdXNpbmcgdGhlIGRhdGEgYXMgcGVyIGJlbG93LiBJZiB5b3UgZm9yY2UgdGhlPGJyPg0K Jmd0OyBxdWVyeSBwbGFubmVyIHRvIHVzZSBhIGhhc2ggam9pbiBvbiB0aGUgc2FtZSBkYXRhLCBp dCB0YWtlcyB+MjAwPGJyPg0KJmd0OyBtaWxsaXNlY29uZHMuPGJyPg0KPGJyPg0KPC9zcGFuPkkg YmVsaWV2ZSBJIGtub3cgd2hhdCBpcyBnb2luZyBvbiBoZXJlLCBidXQgY2FuIHlvdSBwbGVhc2Ug dGVzdDs8YnI+DQo8YnI+DQpTRUxFQ1QgYi4qIEZST00gYiBXSEVSRSBFWElTVFMgKFNFTEVDVCAx IEZST00gYSBPTiBiLmFfaWQgPSA8YSBocmVmPSJodHRwOi8vYS5pZCIgcmVsPSJub3JlZmVycmVy IiB0YXJnZXQ9Il9ibGFuayI+YS5pZDwvYT4gQU5EPGJyPg0KYS5ub25jZSA9ID8pIE9SREVSIEJZ IDxhIGhyZWY9Imh0dHA6Ly9iLmlkIiByZWw9Im5vcmVmZXJyZXIiIHRhcmdldD0iX2JsYW5rIj5i LmlkPC9hPiBBU0M7PGJyPg0KPGJyPg0KdXNpbmcgdGhlIG1lcmdlIGpvaW4gcGxhbi48YnI+DQo8 YnI+PC9ibG9ja3F1b3RlPjxkaXY+PGJyPjwvZGl2PjxkaXY+SGVyZSYjMzk7cyB0aGUgcXVlcnkg cGxhbiBmb3IgdGhhdCBxdWVyeSAoc2xpZ2h0IG1vZGlmaWNhdGlvbnMgdG8gZ2V0IGl0IHRvIHJ1 bik6PGJyPjxicj48L2Rpdj48ZGl2PnBvc3RncmVzPSMgZXhwbGFpbiAoYW5hbHl6ZSxidWZmZXJz KSBTRUxFQ1QgYi4qIEZST00gYiBXSEVSRSBFWElTVFMgKFNFTEVDVCAxIEZST00gYSBXSEVSRSBi LmFfaWQgPSA8YSBocmVmPSJodHRwOi8vYS5pZCIgdGFyZ2V0PSJfYmxhbmsiPmEuaWQ8L2E+IEFO RCBhLm5vbmNlID0gNjQpIE9SREVSIEJZIDxhIGhyZWY9Imh0dHA6Ly9iLmlkIiB0YXJnZXQ9Il9i bGFuayI+Yi5pZDwvYT4gQVNDOzxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFFVRVJZIFBMQU7CoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDxicj4tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tPGJyPsKgU29ydMKgIChjb3N0PTE2NjM5LjE5Li4xNjg1NS42MiByb3dzPTg2NTcyIHdp ZHRoPTE2KSAoYWN0dWFsIHRpbWU9MTQ1LjExNy4uMTczLjI5OCByb3dzPTgzNDI3IGxvb3BzPTEp PGJyPsKgwqAgU29ydCBLZXk6IDxhIGhyZWY9Imh0dHA6Ly9iLmlkIiB0YXJnZXQ9Il9ibGFuayI+ Yi5pZDwvYT48YnI+wqDCoCBTb3J0IE1ldGhvZDogZXh0ZXJuYWwgbWVyZ2XCoCBEaXNrOiAyMTEy a0I8YnI+wqDCoCBCdWZmZXJzOiBzaGFyZWQgaGl0PTg2MTkzIHJlYWQ9ODgxLCB0ZW1wIHJlYWQ9 MjY5IHdyaXR0ZW49MjY5PGJyPsKgwqAgSS9PIFRpbWluZ3M6IHJlYWQ9My4xOTk8YnI+wqDCoCAt Jmd0O8KgIE1lcmdlIFNlbWkgSm9pbsKgIChjb3N0PTc5NS44Mi4uODA1OS4wOSByb3dzPTg2NTcy IHdpZHRoPTE2KSAoYWN0dWFsIHRpbWU9Ni42ODAuLjkxLjg2MiByb3dzPTgzNDI3IGxvb3BzPTEp PGJyPsKgwqDCoMKgwqDCoMKgwqAgTWVyZ2UgQ29uZDogKGIuYV9pZCA9IDxhIGhyZWY9Imh0dHA6 Ly9hLmlkIiB0YXJnZXQ9Il9ibGFuayI+YS5pZDwvYT4pPGJyPsKgwqDCoMKgwqDCoMKgwqAgQnVm ZmVyczogc2hhcmVkIGhpdD04NjE5MyByZWFkPTg4MTxicj7CoMKgwqDCoMKgwqDCoMKgIEkvTyBU aW1pbmdzOiByZWFkPTMuMTk5PGJyPsKgwqDCoMKgwqDCoMKgwqAgLSZndDvCoCBJbmRleCBTY2Fu IHVzaW5nIGFfaWR4IG9uIGLCoCAoY29zdD0wLjAwLi4zMDM2LjcwIHJvd3M9ODY1NzIgd2lkdGg9 MTYpIChhY3R1YWwgdGltZT0wLjAwNS4uMjUuMTkzIHJvd3M9ODM0MjcgbG9vcHM9MSk8YnI+wqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBCdWZmZXJzOiBzaGFyZWQgaGl0PTEwNjQgcmVhZD0z NzQ8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBJL08gVGltaW5nczogcmVhZD0xLjU0 OTxicj7CoMKgwqDCoMKgwqDCoMKgIC0mZ3Q7wqAgSW5kZXggU2NhbiB1c2luZyBhX3BrZXkgb24g YcKgIChjb3N0PTAuMDAuLjI2MjU5Ljg1IHJvd3M9ODkxIHdpZHRoPTgpIChhY3R1YWwgdGltZT02 LjY2My4uMzUuMTc3IHJvd3M9MjM3IGxvb3BzPTEpPGJyPsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgRmlsdGVyOiAobm9uY2UgPSA2NCk8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCBSb3dzIFJlbW92ZWQgYnkgRmlsdGVyOiA4NzkzOTxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIEJ1ZmZlcnM6IHNoYXJlZCBoaXQ9ODUxMjkgcmVhZD01MDc8YnI+wqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoCBJL08gVGltaW5nczogcmVhZD0xLjY1MDxicj7CoFRvdGFsIHJ1bnRp bWU6IDE4Ni44MjUgbXM8YnI+PGJyPjwvZGl2PjxkaXY+Li4uIHNvLCB5ZXMsIGl0IGRvZXMgaW5k ZWVkIGdldCBhIGxvdCBmYXN0ZXI8YnI+PC9kaXY+PGRpdj7CoDwvZGl2PjxibG9ja3F1b3RlIGNs YXNzPSJnbWFpbF9xdW90ZSIgc3R5bGU9Im1hcmdpbjowcHggMHB4IDBweCAwLjhleDtib3JkZXIt bGVmdDoxcHggc29saWQgcmdiKDIwNCwyMDQsMjA0KTtwYWRkaW5nLWxlZnQ6MWV4Ij4NCklmIHRo aXMgcGVyZm9ybXMgbXVjaCBiZXR0ZXIgdGhlbiB0aGUgcHJvYmxlbSBpcyBkdWUgdG8gdGhlIG1l cmdlIGpvaW48YnI+DQptYXJrL3Jlc3RvcmUgY2F1c2luZyB0aGUgam9pbiB0byBoYXZlIHRvIHRy YW5zaXRpb24gdGhyb3VnaCBtYW55PGJyPg0KdHVwbGVzIHdoaWNoIGRvbiYjMzk7dCBtYXRjaCB0 aGUgYS5ub25jZSA9ID8gcHJlZGljYXRlLiBUaGUgbWFyayBhbmQ8YnI+DQpyZXN0b3JlIGlzIG5v dCByZXF1aXJlZCBmb3IgdGhlIHJld3JpdHRlbiBxdWVyeSwgYXMgdGhpcyB1c2UgYSBzZW1pPGJy Pg0Kam9pbiByYXRoZXIgdGhhbiBhIHJlZ3VsYXIgaW5uZXIgam9pbi4gV2l0aCB0aGUgc2VtaSBq b2luIHRoZSBleGVjdXRvcjxicj4NCmtub3dzIHRoYXQgaXQmIzM5O3Mgb25seSBtZWFudCB0byBi ZSBtYXRjaGluZyBhIHNpbmdsZSB0dXBsZSBpbiAmcXVvdDthJnF1b3Q7LCBzbzxicj4NCm9uY2Ug dGhlIGZpcnN0IG1hdGNoIGlzIGZvdW5kIGl0IGNhbiBtb3ZlIHRvIHRoZSBuZXh0IHJvdyBpbiB0 aGUgb3V0ZXI8YnI+DQpyZWxhdGlvbiB3aXRob3V0IGhhdmluZyB0byByZXN0b3JlIHRoZSBzY2Fu IGJhY2sgdG8gd2hlcmUgaXQgc3RhcnRlZDxicj4NCm1hdGNoaW5nIHRoYXQgaW5uZXIgcm93IGFn YWluLjxicj4NCjxicj4NCklmIEkmIzM5O20gcmlnaHQsIHRvIGdldCBhcm91bmQgdGhlIHByb2Js ZW0geW91IGNvdWxkOyBjcmVhdGUgaW5kZXggb24gYTxicj4NCihub25jZSwgaWQpOzxicj4NCjxi cj48L2Jsb2NrcXVvdGU+PGRpdj48YnI+cG9zdGdyZXM9IyBDUkVBVEUgSU5ERVggYV9pZF9ub25j ZV9pZHggT04gYSAobm9uY2UsIGlkKTs8YnI+Q1JFQVRFIElOREVYPGJyPnBvc3RncmVzPSMgZXhw bGFpbiAoYW5hbHl6ZSxidWZmZXJzKSBTRUxFQ1QgYi4qIEZST00gYiBKT0lOIGEgT04gYi5hX2lk ID0gPGEgaHJlZj0iaHR0cDovL2EuaWQiPmEuaWQ8L2E+IFdIRVJFIGEubm9uY2UgPSA2NCBPUkRF UiBCWSA8YSBocmVmPSJodHRwOi8vYi5pZCI+Yi5pZDwvYT4gQVNDOzxicj7CoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCBRVUVSWSBQTEFOwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCA8YnI+LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tPGJyPsKgU29ydMKgIChjb3N0PTMzNzYuNTcuLjMzNzYuOTIgcm93cz0xNDAgd2lkdGg9MTYp IChhY3R1YWwgdGltZT0xNDQuMzQwLi4xNjAuODc1IHJvd3M9ODM0MjcgbG9vcHM9MSk8YnI+wqDC oCBTb3J0IEtleTogPGEgaHJlZj0iaHR0cDovL2IuaWQiPmIuaWQ8L2E+PGJyPsKgwqAgU29ydCBN ZXRob2Q6IGV4dGVybmFsIG1lcmdlwqAgRGlzazogMjEyMGtCPGJyPsKgwqAgQnVmZmVyczogc2hh cmVkIGhpdD0zNjggcmVhZD01MjIsIHRlbXAgcmVhZD0yNjYgd3JpdHRlbj0yNjY8YnI+wqDCoCAt Jmd0O8KgIE1lcmdlIEpvaW7CoCAoY29zdD02OS41MC4uMzM3MS41OCByb3dzPTE0MCB3aWR0aD0x NikgKGFjdHVhbCB0aW1lPTAuMDU2Li44OC40MDkgcm93cz04MzQyNyBsb29wcz0xKTxicj7CoMKg wqDCoMKgwqDCoMKgIE1lcmdlIENvbmQ6IChiLmFfaWQgPSA8YSBocmVmPSJodHRwOi8vYS5pZCI+ YS5pZDwvYT4pPGJyPsKgwqDCoMKgwqDCoMKgwqAgQnVmZmVyczogc2hhcmVkIGhpdD0zNjggcmVh ZD01MjI8YnI+wqDCoMKgwqDCoMKgwqDCoCAtJmd0O8KgIEluZGV4IFNjYW4gdXNpbmcgYV9pZHgg b24gYsKgIChjb3N0PTAuMjkuLjI3MjQuNTggcm93cz04MzQyNyB3aWR0aD0xNikgKGFjdHVhbCB0 aW1lPTAuMDA5Li4yMy44MzQgcm93cz04MzQyNyBsb29wcz0xKTxicj7CoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIEJ1ZmZlcnM6IHNoYXJlZCBoaXQ9MTcxIHJlYWQ9NTE4PGJyPsKgwqDCoMKg wqDCoMKgwqAgLSZndDvCoCBJbmRleCBPbmx5IFNjYW4gdXNpbmcgYV9pZF9ub25jZV9pZHggb24g YcKgIChjb3N0PTAuNDIuLjI0NTAuNTggcm93cz04MjAgd2lkdGg9OCkgKGFjdHVhbCB0aW1lPTAu MDQxLi4yMC43NzYgcm93cz04MzY1OCBsb29wcz0xKTxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIEluZGV4IENvbmQ6IChub25jZSA9IDY0KTxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIEhlYXAgRmV0Y2hlczogODM2NTg8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCBCdWZmZXJzOiBzaGFyZWQgaGl0PTE5NyByZWFkPTQ8YnI+wqBQbGFubmluZyB0aW1lOiAwLjI0 MSBtczxicj7CoEV4ZWN1dGlvbiB0aW1lOiAxNzIuMzQ2IG1zPGJyPjxicj48L2Rpdj48ZGl2Pkxv b2tzIHByZXR0eSBmYXN0IHRvIG1lLiBUaGF0IGJlaW5nIHNhaWQsIHRoZSBudW1iZXIgb2Ygcm93 cyByZXR1cm5lZCBieSB0aGUgSW5kZXggT25seSBTY2FuIHNlZW1zIGEgYml0IGhpZ2gsIGFzIGNv bXBhcmVkIHRvIHRoZSByZXN1bHRzIGJlbG93LCBzbyBJIGFkZGVkIHlvdXIgcGF0Y2ggYmVsb3cg YW5kIGdvdCBbMl0uPGJyPjwvZGl2PjxkaXY+PC9kaXY+PGRpdj7CoDwvZGl2PjxibG9ja3F1b3Rl IGNsYXNzPSJnbWFpbF9xdW90ZSIgc3R5bGU9Im1hcmdpbjowcHggMHB4IDBweCAwLjhleDtib3Jk ZXItbGVmdDoxcHggc29saWQgcmdiKDIwNCwyMDQsMjA0KTtwYWRkaW5nLWxlZnQ6MWV4Ij4NCklm IHN1Y2ggYW4gaW5kZXggaXMgb3V0IG9mIHRoZSBxdWVzdGlvbiB0aGVuIGEgcGF0Y2ggaGFzIGJl ZW48YnI+DQpzdWJtaXR0ZWQgZm9yIHJldmlldyB3aGljaCBzaG91bGQgZml4IHRoaXMgcHJvYmxl bSBpbiAoaG9wZWZ1bGx5KTxicj4NCmVpdGhlciA5LjYgb3IgOS43PGJyPg0KPGEgaHJlZj0iaHR0 cHM6Ly9jb21taXRmZXN0LnBvc3RncmVzcWwub3JnLzkvMTI5LyIgcmVsPSJub3JlZmVycmVyIiB0 YXJnZXQ9Il9ibGFuayI+aHR0cHM6Ly9jb21taXRmZXN0LnBvc3RncmVzcWwub3JnLzkvMTI5Lzwv YT48YnI+DQpJZiB5b3UgaGF2ZSBhIHRlc3QgZW52aXJvbm1lbnQgaGFuZHksIGl0IHdvdWxkIGJl IG5pY2UgaWYgeW91IGNvdWxkPGJyPg0KdGVzdCB0aGUgcGF0Y2ggb24gdGhlIGN1cnJlbnQgZ2l0 IGhlYWQgdG8gc2VlIGlmIHRoaXMgZml4ZXMgeW91cjxicj4NCnByb2JsZW0uIFRoZSBmaW5kaW5n cyB3b3VsZCBiZSBxdWl0ZSBpbnRlcmVzdGluZyBmb3IgbWUuIFBsZWFzZSBub3RlPGJyPg0KdGhp cyBwYXRjaCBpcyBmb3IgdGVzdCBlbnZpcm9ubWVudHMgb25seSBhdCB0aGlzIHN0YWdlLCBub3Qg Zm9yPGJyPg0KcHJvZHVjdGlvbiB1c2UuPGJyPjwvYmxvY2txdW90ZT48ZGl2Pjxicj48L2Rpdj48 ZGl2PkNhbiBjb25maXJtIHRoYXQgeW91ciBwYXRjaCB0aGVyZSBzZWVtcyB0byBpbXByb3ZlIHBl cmZvcm1hbmNlLjxicj48L2Rpdj48ZGl2Pjxicj5IRUFEIFsxXSwgd2l0aCBwYXRjaDo8YnI+PGJy PnBvc3RncmVzPSMgZXhwbGFpbiAoYW5hbHl6ZSxidWZmZXJzKSBTRUxFQ1QgYi4qIEZST00gYiBK T0lOIGEgT04gYi5hX2lkID0gPGEgaHJlZj0iaHR0cDovL2EuaWQiPmEuaWQ8L2E+IFdIRVJFIGEu bm9uY2UgPSA2NCBPUkRFUiBCWSA8YSBocmVmPSJodHRwOi8vYi5pZCI+Yi5pZDwvYT4gQVNDOzxi cj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIFFVRVJZIFBMQU7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIDxicj4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPGJyPsKgU29ydMKgIChj b3N0PTczMjAuMzkuLjczMjAuNzUgcm93cz0xNDQgd2lkdGg9MTYpIChhY3R1YWwgdGltZT0xNjIu MTk5Li4xODEuNDk3IHJvd3M9ODM0MjcgbG9vcHM9MSk8YnI+wqDCoCBTb3J0IEtleTogPGEgaHJl Zj0iaHR0cDovL2IuaWQiPmIuaWQ8L2E+PGJyPsKgwqAgU29ydCBNZXRob2Q6IGV4dGVybmFsIG1l cmdlwqAgRGlzazogMjEyMGtCPGJyPsKgwqAgQnVmZmVyczogc2hhcmVkIGhpdD04NTc4MCByZWFk PTQ3MiwgdGVtcCByZWFkPTI2NiB3cml0dGVuPTI2Njxicj7CoMKgIC0mZ3Q7wqAgTWVyZ2UgSm9p bsKgIChjb3N0PTgwOC4xNy4uNzMxNS4yMyByb3dzPTE0NCB3aWR0aD0xNikgKGFjdHVhbCB0aW1l PTkuNzE5Li4xMDEuODY0IHJvd3M9ODM0MjcgbG9vcHM9MSk8YnI+wqDCoMKgwqDCoMKgwqDCoCBN ZXJnZSBDb25kOiAoYi5hX2lkID0gPGEgaHJlZj0iaHR0cDovL2EuaWQiPmEuaWQ8L2E+KTxicj7C oMKgwqDCoMKgwqDCoMKgIEJ1ZmZlcnM6IHNoYXJlZCBoaXQ9ODU3ODAgcmVhZD00NzI8YnI+wqDC oMKgwqDCoMKgwqDCoCAtJmd0O8KgIEluZGV4IFNjYW4gdXNpbmcgYV9pZHggb24gYsKgIChjb3N0 PTAuMjkuLjI3MjEuNDkgcm93cz04MzQyNyB3aWR0aD0xNikgKGFjdHVhbCB0aW1lPTAuMDU5Li4y Ni4zNDYgcm93cz04MzQyNyBsb29wcz0xKTxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IEJ1ZmZlcnM6IHNoYXJlZCBoaXQ9NDYwIHJlYWQ9MjI5PGJyPsKgwqDCoMKgwqDCoMKgwqAgLSZn dDvCoCBJbmRleCBTY2FuIHVzaW5nIGFfcGtleSBvbiBhwqAgKGNvc3Q9MC40Mi4uMjQzOTQuODgg cm93cz04NDYgd2lkdGg9OCkgKGFjdHVhbCB0aW1lPTkuNjUxLi40MS4yMzEgcm93cz0yMzcgbG9v cHM9MSk8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBGaWx0ZXI6IChub25jZSA9IDY0 KTxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJvd3MgUmVtb3ZlZCBieSBGaWx0ZXI6 IDg3OTM5PGJyPsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgQnVmZmVyczogc2hhcmVkIGhp dD04NTMyMCByZWFkPTI0Mzxicj7CoFBsYW5uaW5nIHRpbWU6IDAuMjg5IG1zPGJyPsKgRXhlY3V0 aW9uIHRpbWU6IDE5NS4wNzEgbXM8YnI+PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5IRUFEIFsx XSwgd2l0aG91dCBwYXRjaDo8YnI+PGJyPnBvc3RncmVzPSMgZXhwbGFpbiAoYW5hbHl6ZSxidWZm ZXJzKSBTRUxFQ1QgYi4qIEZST00gYiBKT0lOIGEgT04gYi5hX2lkID0gPGEgaHJlZj0iaHR0cDov L2EuaWQiPmEuaWQ8L2E+IFdIRVJFIGEubm9uY2UgPSA2NCBPUkRFUiBCWSA8YSBocmVmPSJodHRw Oi8vYi5pZCI+Yi5pZDwvYT4gQVNDOzxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUVVFUlkgUExBTsKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDxicj4t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tPGJyPsKgU29ydMKgIChjb3N0PTcyODUuNDguLjcyODUuODMgcm93 cz0xNDAgd2lkdGg9MTYpIChhY3R1YWwgdGltZT03MTAwNzMuMDU5Li43MTAwODkuOTI0IHJvd3M9 ODM0MjcgbG9vcHM9MSk8YnI+wqDCoCBTb3J0IEtleTogPGEgaHJlZj0iaHR0cDovL2IuaWQiPmIu aWQ8L2E+PGJyPsKgwqAgU29ydCBNZXRob2Q6IGV4dGVybmFsIG1lcmdlwqAgRGlzazogMjEyMGtC PGJyPsKgwqAgQnVmZmVyczogc2hhcmVkIGhpdD0yMTQ5MjgyMjAwIHJlYWQ9MjQzLCB0ZW1wIHJl YWQ9MjY2IHdyaXR0ZW49MjY2PGJyPsKgwqAgLSZndDvCoCBNZXJnZSBKb2luwqAgKGNvc3Q9Njg1 LjI4Li43MjgwLjQ5IHJvd3M9MTQwIHdpZHRoPTE2KSAoYWN0dWFsIHRpbWU9MTAuMDIyLi43MDk4 NzguOTQ2IHJvd3M9ODM0MjcgbG9vcHM9MSk8YnI+wqDCoMKgwqDCoMKgwqDCoCBNZXJnZSBDb25k OiAoYi5hX2lkID0gPGEgaHJlZj0iaHR0cDovL2EuaWQiPmEuaWQ8L2E+KTxicj7CoMKgwqDCoMKg wqDCoMKgIEJ1ZmZlcnM6IHNoYXJlZCBoaXQ9MjE0OTI4MjIwMCByZWFkPTI0Mzxicj7CoMKgwqDC oMKgwqDCoMKgIC0mZ3Q7wqAgSW5kZXggU2NhbiB1c2luZyBhX2lkeCBvbiBiwqAgKGNvc3Q9MC4y OS4uMjcyNC41OCByb3dzPTgzNDI3IHdpZHRoPTE2KSAoYWN0dWFsIHRpbWU9MC4wMTMuLjU5LjEw MyByb3dzPTgzNDI3IGxvb3BzPTEpPGJyPsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgQnVm ZmVyczogc2hhcmVkIGhpdD02ODk8YnI+wqDCoMKgwqDCoMKgwqDCoCAtJmd0O8KgIEluZGV4IFNj YW4gdXNpbmcgYV9wa2V5IG9uIGHCoCAoY29zdD0wLjQyLi4yNDQwNC42OSByb3dzPTgyMCB3aWR0 aD04KSAoYWN0dWFsIHRpbWU9OS45OTguLjcwOTU5NS45MDUgcm93cz04MzY1OCBsb29wcz0xKTxi cj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIEZpbHRlcjogKG5vbmNlID0gNjQpPGJyPsKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUm93cyBSZW1vdmVkIGJ5IEZpbHRlcjogMjIwMTA2 MzY5Njxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIEJ1ZmZlcnM6IHNoYXJlZCBoaXQ9 MjE0OTI4MTUxMSByZWFkPTI0Mzxicj7CoFBsYW5uaW5nIHRpbWU6IDAuMjk3IG1zPGJyPsKgRXhl Y3V0aW9uIHRpbWU6IDcxMDEwMS45MzEgbXM8YnI+PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5U aGFuayB5b3UgZm9yIHlvdXIgcmVzcG9uc2UhIFRoaXMgYWxsb3dzIHVzIHRvIHVuZGVyc3RhbmQg dGhlIHNpdHVhdGlvbnMgaW4gd2hpY2ggd2UgY2FuIHJ1biBpbnRvIHRyb3VibGUsIGFuZCB3aGF0 IHdlIGNhbiBkbyBpbiBtb3N0LCBpZiBub3QgYWxsIGNhc2VzLCB0byByZXNvbHZlLjxicj48YnI+ PC9kaXY+PGRpdj5SZWdhcmRzLDxicj48L2Rpdj48ZGl2PkphbWVzPGJyPjwvZGl2PjxkaXY+PGJy PjwvZGl2PjxkaXY+WzFdIEhFQUQgaXMgJnF1b3Q7YTg5MjIzNCBDaGFuZ2UgdGhlIGZvcm1hdCBv ZiB0aGUgVk0gZm9yayB0byBhZGQgYSBzZWNvbmQgYml0IHBlciBwYWdlLiZxdW90OyBhcyBmb3Vu ZCBvbiB0aGUgR2l0aHViIG1pcnJvciBvZiBwb3N0Z3Jlczxicj48YnI+WzJdPGJyPnBvc3RncmVz PSMgZXhwbGFpbiAoYW5hbHl6ZSxidWZmZXJzKSBTRUxFQ1QgYi4qIEZST00gYiBKT0lOIGEgT04g Yi5hX2lkID0gPGEgaHJlZj0iaHR0cDovL2EuaWQiPmEuaWQ8L2E+IFdIRVJFIGEubm9uY2UgPSA2 NCBPUkRFUiBCWSA8YSBocmVmPSJodHRwOi8vYi5pZCI+Yi5pZDwvYT4gQVNDOzxicj7CoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgUVVFUlkgUExBTsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDxicj4tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tPGJyPsKgU29ydMKgIChjb3N0PTExMDAwLjAzLi4xMTAwMS4wNyByb3dzPTQxNyB3aWR0aD0x NikgKGFjdHVhbCB0aW1lPTEwOS43MzkuLjEyOS4wMzEgcm93cz04MzQyNyBsb29wcz0xKTxicj7C oMKgIFNvcnQgS2V5OiA8YSBocmVmPSJodHRwOi8vYi5pZCI+Yi5pZDwvYT48YnI+wqDCoCBTb3J0 IE1ldGhvZDogZXh0ZXJuYWwgbWVyZ2XCoCBEaXNrOiAyMTIwa0I8YnI+wqDCoCBCdWZmZXJzOiBz aGFyZWQgaGl0PTg4NiwgdGVtcCByZWFkPTI2NiB3cml0dGVuPTI2Njxicj7CoMKgIC0mZ3Q7wqAg TWVyZ2UgSm9pbsKgIChjb3N0PTAuNzEuLjEwOTgxLjg4IHJvd3M9NDE3IHdpZHRoPTE2KSAoYWN0 dWFsIHRpbWU9MC4wNTAuLjU1LjcwMSByb3dzPTgzNDI3IGxvb3BzPTEpPGJyPsKgwqDCoMKgwqDC oMKgwqAgTWVyZ2UgQ29uZDogKGIuYV9pZCA9IDxhIGhyZWY9Imh0dHA6Ly9hLmlkIj5hLmlkPC9h Pik8YnI+wqDCoMKgwqDCoMKgwqDCoCBCdWZmZXJzOiBzaGFyZWQgaGl0PTg4Njxicj7CoMKgwqDC oMKgwqDCoMKgDQogLSZndDvCoCBJbmRleCBTY2FuIHVzaW5nIGFfaWR4IG9uIGLCoCAoY29zdD0w LjI5Li4zOTc1LjcwIHJvd3M9ODM0MjcgDQp3aWR0aD0xNikgKGFjdHVhbCB0aW1lPTAuMDE3Li4y My42NDcgcm93cz04MzQyNyBsb29wcz0xKTxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IEJ1ZmZlcnM6IHNoYXJlZCBoaXQ9Njg5PGJyPsKgwqDCoMKgwqDCoMKgwqANCiAtJmd0O8KgIElu ZGV4IE9ubHkgU2NhbiB1c2luZyBhX2lkX25vbmNlX2lkeCBvbiBhwqAgKGNvc3Q9MC40Mi4uNjc4 Ny4zMSANCnJvd3M9MjQ1MSB3aWR0aD04KSAoYWN0dWFsIHRpbWU9MC4wMjguLjAuMTcyIHJvd3M9 MjM3IGxvb3BzPTEpPGJyPsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgSW5kZXggQ29uZDog KG5vbmNlID0gNjQpPGJyPsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgSGVhcCBGZXRjaGVz OiAyMzc8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBCdWZmZXJzOiBzaGFyZWQgaGl0 PTE5Nzxicj7CoFBsYW5uaW5nIHRpbWU6IDAuMTUzIG1zPGJyPsKgRXhlY3V0aW9uIHRpbWU6IDE0 Mi45OTQgbXM8YnI+PC9kaXY+PC9kaXY+PGJyPjwvZGl2PjwvZGl2Pg0K --001a113a977c28e03c052d0bf0e2--