Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sRglh-000ArS-2S for pgsql-hackers@arkaria.postgresql.org; Wed, 10 Jul 2024 23:30:38 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1sRgld-009bzj-OO for pgsql-hackers@arkaria.postgresql.org; Wed, 10 Jul 2024 23:30:33 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sRgld-009bzb-12 for pgsql-hackers@lists.postgresql.org; Wed, 10 Jul 2024 23:30:33 +0000 Received: from mail.postgrespro.ru ([93.174.131.139]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sRglT-001Sz7-1N for pgsql-hackers@postgresql.org; Wed, 10 Jul 2024 23:30:32 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=postgrespro.ru; s=mx2023; t=1720654220; bh=t9vYdkki1uSmS7hJhM/DnZMfjm+VEdVsK1/jFrliIRA=; h=Message-ID:Date:User-Agent:Subject:From:To:Cc:References: In-Reply-To:From; b=5O7kL1g6THcsSH0NFQvOdnAti8p0T7CqTx+Zq+Z1tsTiQG7k+1H07nSR8IwAInq/U GYMG9MRZHhTgEqwryYVOsTSpQRREDLb4gEaVU2hr0492s1z2N6e2908wu859XJGJ6C vfskGi/lUT8FX7NfLl9fhhvpUhCpgwdkR0wqnO3s/gAa/yi1+anyyJiRv5qYu2Yh85 42/D3ocHiRKlPniDrCYJ2veE0s0I7UODQzgb3+j0UiKdRoxeBRZONzX029W77dfRjh 1UreDjMwSOB4Ud0I03hC2nxO+dMa90iQ2vo0WTWp3o6CBFR8ybOJHZxVeLF9/jZdfH mO7/epmHH33hw== Received: from [192.168.113.77] (unknown [176.59.160.167]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: a.rybakina@postgrespro.ru) by mail.postgrespro.ru (Postfix/587) with ESMTPSA id E577B60298; Thu, 11 Jul 2024 02:30:19 +0300 (MSK) Content-Type: multipart/mixed; boundary="------------3caDxovxFfbd3FFYZrytmE8M" Message-ID: Date: Thu, 11 Jul 2024 02:30:22 +0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: POC, WIP: OR-clause support for indexes From: Alena Rybakina To: pgsql-hackers@postgresql.org Cc: Robert Haas , Peter Geoghegan , Alexander Korotkov , jian he , Marcos Pegoraro , teodor@sigaev.ru, Andrei Lepikhov , Tomas Vondra , Peter Eisentraut , Ranier Vilela References: <567ED6CA.2040504@sigaev.ru> <6850c306-4e9d-40b7-8096-1f3c7d29cd9e@postgrespro.ru> <0f50882c-e639-4856-aab6-6ccfec848164@postgrespro.ru> <75265eac-aa87-41dc-bf1b-13c11ce2d499@postgrespro.ru> Content-Language: en-US In-Reply-To: <75265eac-aa87-41dc-bf1b-13c11ce2d499@postgrespro.ru> X-KSMG-AntiPhishing: NotDetected, bases: 2024/07/10 23:02:00 X-KSMG-AntiSpam-Interceptor-Info: not scanned X-KSMG-AntiSpam-Status: not scanned, disabled by settings X-KSMG-AntiVirus: Kaspersky Secure Mail Gateway, version 2.1.0.7854, bases: 2024/07/10 21:42:00 #25942395 X-KSMG-AntiVirus-Status: NotDetected, skipped X-KSMG-LinksScanning: not scanned, disabled by settings X-KSMG-Message-Action: skipped X-KSMG-Rule-ID: 1 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk This is a multi-part message in MIME format. --------------3caDxovxFfbd3FFYZrytmE8M Content-Type: multipart/alternative; boundary="------------s30quJsIBG0tPPxP9Fq16PsC" --------------s30quJsIBG0tPPxP9Fq16PsC Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit On 27.06.2024 23:06, Alena Rybakina wrote: > Tobe honest,I've alreadystartedwritingcodetodothis,butI'm facedwitha > misunderstandingof howto correctlycreatea > conditionfor"OR"expressionsthatare notsubjectto transformation. >> >> For example,the expressions b=1in the query below: >> >> alena@postgres=# explain select * from x where ( (a =5 or a=4) and a >> = ANY(ARRAY[5,4])) or (b=1); QUERY PLAN >> ---------------------------------------------------------------------------------- >> Seq Scan on x (cost=0.00..123.00 rows=1 width=8) Filter: ((((a = 5) >> OR (a = 4)) AND (a = ANY ('{5,4}'::integer[]))) OR (b = 1)) (2 rows) >> >> I see that two expressions have remained unchanged and it only works >> for "AND" binary operations. >> >> But I think it might be worth applying this together, where does the >> optimizer generate indexes (build_paths_for_OR function)? >> Iimplementedsuchcode,butatthe analysisstageinplanner,anditwasn'tfullyreadyyet,butIwas ableto drawsomeimportantconclusions.Firstof all,Ifacedtheproblemof the inequalityof the numberof columnsinthe expressionwiththe requiredone,atleastsomeextracolumnappeared,judgingby the crust.Ihaven'tfullyrealizedityet andhaven'tfixedit. #0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=134300960061248)     at ./nptl/pthread_kill.c:44 #1  __pthread_kill_internal (signo=6, threadid=134300960061248) at ./nptl/pthread_kill.c:78 #2  __GI___pthread_kill (threadid=134300960061248, signo=signo@entry=6) at ./nptl/pthread_kill.c:89 #3  0x00007a2560042476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 #4  0x00007a25600287f3 in __GI_abort () at ./stdlib/abort.c:79 #5  0x00005573f9df62a8 in ExceptionalCondition (     conditionName=0x5573f9fec4c8 "AttrNumberIsForUserDefinedAttr(list_attnums[i]) || !bms_is_member(attnum, clauses_attnums)", fileName=0x5573f9fec11c "dependencies.c", lineNumber=1525) at assert.c:66 #6  0x00005573f9b8b85f in dependencies_clauselist_selectivity (root=0x5573fad534e8,     clauses=0x5573fad0b2d8, varRelid=0, jointype=JOIN_INNER, sjinfo=0x0, rel=0x5573fad54b38,     estimatedclauses=0x7ffe2e43f178) at dependencies.c:1525 #7  0x00005573f9b8fed9 in statext_clauselist_selectivity (root=0x5573fad534e8, clauses=0x5573fad0b2d8,     varRelid=0, jointype=JOIN_INNER, sjinfo=0x0, rel=0x5573fad54b38, estimatedclauses=0x7ffe2e43f178,     is_or=false) at extended_stats.c:2035 --Type for more, q to quit, c to continue without paging-- #8  0x00005573f9a57f88 in clauselist_selectivity_ext (root=0x5573fad534e8, clauses=0x5573fad0b2d8,     varRelid=0, jointype=JOIN_INNER, sjinfo=0x0, use_extended_stats=true) at clausesel.c:153 #9  0x00005573f9a57e30 in clauselist_selectivity (root=0x5573fad534e8, clauses=0x5573fad0b2d8,     varRelid=0, jointype=JOIN_INNER, sjinfo=0x0) at clausesel.c:106 #10 0x00005573f9a62e03 in set_baserel_size_estimates (root=0x5573fad534e8, rel=0x5573fad54b38)     at costsize.c:5247 #11 0x00005573f9a51aa5 in set_plain_rel_size (root=0x5573fad534e8, rel=0x5573fad54b38,     rte=0x5573fad0ec58) at allpaths.c:581 #12 0x00005573f9a516ce in set_rel_size (root=0x5573fad534e8, rel=0x5573fad54b38, rti=1,     rte=0x5573fad0ec58) at allpaths.c:411 #13 0x00005573f9a514c7 in set_base_rel_sizes (root=0x5573fad534e8) at allpaths.c:322 #14 0x00005573f9a5119d in make_one_rel (root=0x5573fad534e8, joinlist=0x5573fad0adf8) at allpaths.c:183 #15 0x00005573f9a94d45 in query_planner (root=0x5573fad534e8,     qp_callback=0x5573f9a9b59e , qp_extra=0x7ffe2e43f540) at planmain.c:280 #16 0x00005573f9a977a8 in grouping_planner (root=0x5573fad534e8, tuple_fraction=0, setops=0x0)     at planner.c:1520 #17 0x00005573f9a96e47 in subquery_planner (glob=0x5573fad533d8, parse=0x5573fad0ea48, parent_root=0x0,     hasRecursion=false, tuple_fraction=0, setops=0x0) at planner.c:1089 #18 0x00005573f9a954aa in standard_planner (parse=0x5573fad0ea48,     query_string=0x5573fad8b3b0 "explain analyze SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = '1'", cursorOptions=2048, boundParams=0x0) at planner.c:415 #19 0x00005573f9a951d4 in planner (parse=0x5573fad0ea48, --Type for more, q to quit, c to continue without paging--     query_string=0x5573fad8b3b0 "explain analyze SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = '1'", cursorOptions=2048, boundParams=0x0) at planner.c:282 #20 0x00005573f9bf4e2e in pg_plan_query (querytree=0x5573fad0ea48,     query_string=0x5573fad8b3b0 "explain analyze SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = '1'", cursorOptions=2048, boundParams=0x0) at postgres.c:904 #21 0x00005573f98613e7 in standard_ExplainOneQuery (query=0x5573fad0ea48, cursorOptions=2048, into=0x0,     es=0x5573fad57da0,     queryString=0x5573fad8b3b0 "explain analyze SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = '1'", params=0x0, queryEnv=0x0) at explain.c:489 #22 0x00005573f9861205 in ExplainOneQuery (query=0x5573fad0ea48, cursorOptions=2048, into=0x0,     es=0x5573fad57da0,     queryString=0x5573fad8b3b0 "explain analyze SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = '1'", params=0x0, queryEnv=0x0) at explain.c:445 #23 0x00005573f9860e35 in ExplainQuery (pstate=0x5573fad57c90, stmt=0x5573fad8b5a0, params=0x0,     dest=0x5573fad57c00) at explain.c:341 #24 0x00005573f9bff3a8 in standard_ProcessUtility (pstmt=0x5573fad8b490,     queryString=0x5573fad8b3b0 "explain analyze SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = '1'", readOnlyTree=false, context=PROCESS_UTILITY_QUERY, params=0x0,     queryEnv=0x0, dest=0x5573fad57c00, qc=0x7ffe2e43fcd0) at utility.c:863 #25 0x00005573f9bfe91a in ProcessUtility (pstmt=0x5573fad8b490,     queryString=0x5573fad8b3b0 "explain analyze SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = '1'", readOnlyTree=false, context=PROCESS_UTILITY_QUERY, params=0x0, --Type for more, q to quit, c to continue without paging--     queryEnv=0x0, dest=0x5573fad57c00, qc=0x7ffe2e43fcd0) at utility.c:523 #26 0x00005573f9bfd195 in PortalRunUtility (portal=0x5573fac6bcf0, pstmt=0x5573fad8b490,     isTopLevel=false, setHoldSnapshot=true, dest=0x5573fad57c00, qc=0x7ffe2e43fcd0) at pquery.c:1158 #27 0x00005573f9bfced2 in FillPortalStore (portal=0x5573fac6bcf0, isTopLevel=false) at pquery.c:1031 #28 0x00005573f9bfd778 in PortalRunFetch (portal=0x5573fac6bcf0, fdirection=FETCH_FORWARD, count=10,     dest=0x5573fa1d6880 ) at pquery.c:1442 #29 0x00005573f9992675 in _SPI_cursor_operation (portal=0x5573fac6bcf0, direction=FETCH_FORWARD,     count=10, dest=0x5573fa1d6880 ) at spi.c:3019 #30 0x00005573f9990849 in SPI_cursor_fetch (portal=0x5573fac6bcf0, forward=true, count=10) at spi.c:1805 #31 0x00007a25603e0aa5 in exec_for_query (estate=0x7ffe2e440200, stmt=0x5573fad067c8,     portal=0x5573fac6bcf0, prefetch_ok=true) at pl_exec.c:5889 #32 0x00007a25603de728 in exec_stmt_dynfors (estate=0x7ffe2e440200, stmt=0x5573fad067c8)     at pl_exec.c:4647 #33 0x00007a25603d8b1c in exec_stmts (estate=0x7ffe2e440200, stmts=0x5573fad06ec8) at pl_exec.c:2100 #34 0x00007a25603d8697 in exec_stmt_block (estate=0x7ffe2e440200, block=0x5573fad06f18) at pl_exec.c:1943 #35 0x00007a25603d7d9e in exec_toplevel_block (estate=0x7ffe2e440200, block=0x5573fad06f18)     at pl_exec.c:1634 #36 0x00007a25603d5a2e in plpgsql_exec_function (func=0x5573fac2c1e0, fcinfo=0x5573fad2af60,     simple_eval_estate=0x0, simple_eval_resowner=0x0, procedure_resowner=0x0, atomic=true)     at pl_exec.c:623 #37 0x00007a25603f277f in plpgsql_call_handler (fcinfo=0x5573fad2af60) at pl_handler.c:277 #38 0x00005573f993589a in ExecMakeTableFunctionResult (setexpr=0x5573facfd8c8, econtext=0x5573facfd798, --Type for more, q to quit, c to continue without paging--     argContext=0x5573fad2ae60, expectedDesc=0x5573facfe130, randomAccess=false) at execSRF.c:234 #39 0x00005573f995299c in FunctionNext (node=0x5573facfd588) at nodeFunctionscan.c:94 #40 0x00005573f993735f in ExecScanFetch (node=0x5573facfd588, accessMtd=0x5573f99528e6 ,     recheckMtd=0x5573f9952ced ) at execScan.c:131 #41 0x00005573f99373d8 in ExecScan (node=0x5573facfd588, accessMtd=0x5573f99528e6 ,     recheckMtd=0x5573f9952ced ) at execScan.c:180 #42 0x00005573f9952d46 in ExecFunctionScan (pstate=0x5573facfd588) at nodeFunctionscan.c:269 #43 0x00005573f9932c7f in ExecProcNodeFirst (node=0x5573facfd588) at execProcnode.c:464 #44 0x00005573f9925df5 in ExecProcNode (node=0x5573facfd588)     at ../../../src/include/executor/executor.h:274 #45 0x00005573f9928bf9 in ExecutePlan (estate=0x5573facfd360, planstate=0x5573facfd588,     use_parallel_mode=false, operation=CMD_SELECT, sendTuples=true, numberTuples=0,     direction=ForwardScanDirection, dest=0x5573fad8f6e0, execute_once=true) at execMain.c:1646 #46 0x00005573f992653d in standard_ExecutorRun (queryDesc=0x5573fad87f70,     direction=ForwardScanDirection, count=0, execute_once=true) at execMain.c:363 #47 0x00005573f9926316 in ExecutorRun (queryDesc=0x5573fad87f70, direction=ForwardScanDirection,     count=0, execute_once=true) at execMain.c:304 #48 0x00005573f9bfcb7d in PortalRunSelect (portal=0x5573fac6bbe0, forward=true, count=0,     dest=0x5573fad8f6e0) at pquery.c:924 #49 0x00005573f9bfc7a5 in PortalRun (portal=0x5573fac6bbe0, count=9223372036854775807, isTopLevel=true,     run_once=true, dest=0x5573fad8f6e0, altdest=0x5573fad8f6e0, qc=0x7ffe2e440a60) at pquery.c:768 #50 0x00005573f9bf5512 in exec_simple_query ( --Type for more, q to quit, c to continue without paging--     query_string=0x5573fabea030 "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = ''1''');") at postgres.c:1274 #51 0x00005573f9bfa5b7 in PostgresMain (dbname=0x5573fab52240 "regression",     username=0x5573fac27c98 "alena") at postgres.c:4680 #52 0x00005573f9bf137e in BackendMain (startup_data=0x7ffe2e440ce4 "", startup_data_len=4)     at backend_startup.c:105 #53 0x00005573f9b06852 in postmaster_child_launch (child_type=B_BACKEND, startup_data=0x7ffe2e440ce4 "",     startup_data_len=4, client_sock=0x7ffe2e440d30) at launch_backend.c:265 #54 0x00005573f9b0cd66 in BackendStartup (client_sock=0x7ffe2e440d30) at postmaster.c:3593 #55 0x00005573f9b09db1 in ServerLoop () at postmaster.c:1674 #56 0x00005573f9b09678 in PostmasterMain (argc=8, argv=0x5573fab500d0) at postmaster.c:1372 #57 0x00005573f99b5f79 in main (argc=8, argv=0x5573fab500d0) at main.c:197 Secondly,Isawdiffchangesinqueriesthatshowedcaseswherethe optimizerdid noteliminateoneofthe redundantexpressionsandprocessedbothof them.Thisindicatestheproblemthatthe optimizerhas notlearnedhow to handleitinallcases.IthinkI'll needtoaddsomecodetohandleit.  EXPLAIN (COSTS OFF)  SELECT count(*) FROM tenk1    WHERE hundred = 42 AND (thousand = 42 OR thousand = 99 OR tenthous < 2) OR thousand = 41; -                                                         QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------   Aggregate     ->  Bitmap Heap Scan on tenk1 -         Recheck Cond: (((hundred = 42) AND ((thousand = ANY ('{42,99}'::integer[])) OR (tenthous < 2))) OR (thousand = 41)) +         Recheck Cond: (((((thousand = 42) AND (thousand = ANY ('{42,99}'::integer[]))) OR ((thousand = 99) AND (thousand = ANY ('{42,99}'::integer[])))) OR (tenthous < 2)) OR (thousand = 41)) +         Filter: (((hundred = 42) AND ((((thousand = 42) OR (thousand = 99)) AND (thousand = ANY ('{42,99}'::integer[]))) OR (tenthous < 2))) OR (thousand = 41))           ->  BitmapOr -               ->  BitmapAnd -                     ->  Bitmap Index Scan on tenk1_hundred -                           Index Cond: (hundred = 42) +               ->  BitmapOr                       ->  BitmapOr                             ->  Bitmap Index Scan on tenk1_thous_tenthous -                                 Index Cond: (thousand = ANY ('{42,99}'::integer[])) +                                 Index Cond: ((thousand = 42) AND (thousand = ANY ('{42,99}'::integer[])))                             ->  Bitmap Index Scan on tenk1_thous_tenthous -                                 Index Cond: (tenthous < 2) +                                 Index Cond: ((thousand = 99) AND (thousand = ANY ('{42,99}'::integer[]))) +                     ->  Bitmap Index Scan on tenk1_thous_tenthous +                           Index Cond: (tenthous < 2)                 ->  Bitmap Index Scan on tenk1_thous_tenthous                       Index Cond: (thousand = 41) -(14 rows) +(15 rows)  SELECT count(*) FROM tenk1    WHERE hundred = 42 AND (thousand = 42 OR thousand = 99 OR tenthous < 2) OR thousand = 41; @@ -1986,20 +1987,21 @@  EXPLAIN (COSTS OFF)  SELECT count(*) FROM tenk1    WHERE hundred = 42 AND (thousand = 42 OR thousand = 41 OR thousand = 99 AND tenthous = 2); -                                                          QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------   Aggregate     ->  Bitmap Heap Scan on tenk1 -         Recheck Cond: ((hundred = 42) AND ((thousand = ANY ('{41,42}'::integer[])) OR ((thousand = 99) AND (tenthous = 2)))) -         ->  BitmapAnd -               ->  Bitmap Index Scan on tenk1_hundred -                     Index Cond: (hundred = 42) +         Recheck Cond: ((((thousand = 42) AND (thousand = ANY ('{41,42}'::integer[]))) OR ((thousand = 41) AND (thousand = ANY ('{41,42}'::integer[])))) OR ((thousand = 99) AND (tenthous = 2))) +         Filter: (hundred = 42) +         ->  BitmapOr                 ->  BitmapOr                       ->  Bitmap Index Scan on tenk1_thous_tenthous -                           Index Cond: (thousand = ANY ('{41,42}'::integer[])) +                           Index Cond: ((thousand = 42) AND (thousand = ANY ('{41,42}'::integer[])))                       ->  Bitmap Index Scan on tenk1_thous_tenthous -                           Index Cond: ((thousand = 99) AND (tenthous = 2)) -(11 rows) +                           Index Cond: ((thousand = 41) AND (thousand = ANY ('{41,42}'::integer[]))) +               ->  Bitmap Index Scan on tenk1_thous_tenthous +                     Index Cond: ((thousand = 99) AND (tenthous = 2)) +(12 rows)  SELECT count(*) FROM tenk1    WHERE hundred = 42 AND (thousand = 42 OR thousand = 41 OR thousand = 99 AND tenthous = 2); diff -U3 /home/alena/postgrespro5/src/test/regress/expected/inherit.out /home/alena/postgrespro5/src/test/regress/results/inherit.out --- /home/alena/postgrespro5/src/test/regress/expected/inherit.out 2024-06-20 12:28:52.324011724 +0300 +++ /home/alena/postgrespro5/src/test/regress/results/inherit.out 2024-07-11 02:00:55.404006843 +0300 @@ -2126,7 +2126,7 @@                                     QUERY PLAN  ---------------------------------------------------------------------------------   Seq Scan on part_ab_cd list_parted -   Filter: (((a)::text = 'ab'::text) OR ((a)::text = ANY ('{NULL,cd}'::text[]))) +   Filter: (((a)::text = ANY ('{NULL,cd}'::text[])) OR ((a)::text = 'ab'::text))  (2 rows)  explain (costs off) select * from list_parted where a = 'ab'; diff -U3 /home/alena/postgrespro5/src/test/regress/expected/join.out /home/alena/postgrespro5/src/test/regress/results/join.out --- /home/alena/postgrespro5/src/test/regress/expected/join.out 2024-06-28 11:05:44.304135987 +0300 +++ /home/alena/postgrespro5/src/test/regress/results/join.out 2024-07-11 02:00:58.152006921 +0300 @@ -4210,10 +4210,17 @@  select * from tenk1 a join tenk1 b on    (a.unique1 = 1 and b.unique1 = 2) or    ((a.unique2 = 3 or a.unique2 = 7) and b.hundred = 4); -                                                       QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +-----------------------------------------------------------------------------------------------------------------------------------------------------------------   Nested Loop -   Join Filter: (((a.unique1 = 1) AND (b.unique1 = 2)) OR ((a.unique2 = ANY ('{3,7}'::integer[])) AND (b.hundred = 4))) +   Join Filter: (((a.unique1 = 1) AND (b.unique1 = 2)) OR (((a.unique2 = 3) OR (a.unique2 = 7)) AND (a.unique2 = ANY ('{3,7}'::integer[])) AND (b.hundred = 4))) +   ->  Bitmap Heap Scan on tenk1 a +         Recheck Cond: ((unique1 = 1) OR (unique2 = ANY ('{3,7}'::integer[]))) +         ->  BitmapOr +               ->  Bitmap Index Scan on tenk1_unique1 +                     Index Cond: (unique1 = 1) +               ->  Bitmap Index Scan on tenk1_unique2 +                     Index Cond: (unique2 = ANY ('{3,7}'::integer[]))     ->  Bitmap Heap Scan on tenk1 b           Recheck Cond: ((unique1 = 2) OR (hundred = 4))           ->  BitmapOr @@ -4221,25 +4228,24 @@                       Index Cond: (unique1 = 2)                 ->  Bitmap Index Scan on tenk1_hundred                       Index Cond: (hundred = 4) -   ->  Materialize -         ->  Bitmap Heap Scan on tenk1 a -               Recheck Cond: ((unique1 = 1) OR (unique2 = ANY ('{3,7}'::integer[]))) -               ->  BitmapOr -                     ->  Bitmap Index Scan on tenk1_unique1 -                           Index Cond: (unique1 = 1) -                     ->  Bitmap Index Scan on tenk1_unique2 -                           Index Cond: (unique2 = ANY ('{3,7}'::integer[])) -(17 rows) +(16 rows)  SET enable_or_transformation = on;  explain (costs off)  select * from tenk1 a join tenk1 b on    (a.unique1 = 1 and b.unique1 = 2) or    ((a.unique2 = 3 or a.unique2 = 7) and b.hundred = 4); -                                                       QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +-----------------------------------------------------------------------------------------------------------------------------------------------------------------   Nested Loop -   Join Filter: (((a.unique1 = 1) AND (b.unique1 = 2)) OR ((a.unique2 = ANY ('{3,7}'::integer[])) AND (b.hundred = 4))) +   Join Filter: (((a.unique1 = 1) AND (b.unique1 = 2)) OR (((a.unique2 = 3) OR (a.unique2 = 7)) AND (a.unique2 = ANY ('{3,7}'::integer[])) AND (b.hundred = 4))) +   ->  Bitmap Heap Scan on tenk1 a +         Recheck Cond: ((unique1 = 1) OR (unique2 = ANY ('{3,7}'::integer[]))) +         ->  BitmapOr +               ->  Bitmap Index Scan on tenk1_unique1 +                     Index Cond: (unique1 = 1) +               ->  Bitmap Index Scan on tenk1_unique2 +                     Index Cond: (unique2 = ANY ('{3,7}'::integer[]))     ->  Bitmap Heap Scan on tenk1 b           Recheck Cond: ((unique1 = 2) OR (hundred = 4))           ->  BitmapOr @@ -4247,37 +4253,29 @@                       Index Cond: (unique1 = 2)                 ->  Bitmap Index Scan on tenk1_hundred                       Index Cond: (hundred = 4) -   ->  Materialize -         ->  Bitmap Heap Scan on tenk1 a -               Recheck Cond: ((unique1 = 1) OR (unique2 = ANY ('{3,7}'::integer[]))) -               ->  BitmapOr -                     ->  Bitmap Index Scan on tenk1_unique1 -                           Index Cond: (unique1 = 1) -                     ->  Bitmap Index Scan on tenk1_unique2 -                           Index Cond: (unique2 = ANY ('{3,7}'::integer[])) -(17 rows) +(16 rows)  explain (costs off)  select * from tenk1 a join tenk1 b on    (a.unique1 < 20 or a.unique1 = 3 or a.unique1 = 1 and b.unique1 = 2) or    ((a.unique2 = 3 or a.unique2 = 7) and b.hundred = 4); - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------   Nested Loop -   Join Filter: ((a.unique1 < 20) OR (a.unique1 = 3) OR ((a.unique1 = 1) AND (b.unique1 = 2)) OR ((a.unique2 = ANY ('{3,7}'::integer[])) AND (b.hundred = 4))) +   Join Filter: (((a.unique1 = 1) AND (b.unique1 = 2)) OR (((a.unique2 = 3) OR (a.unique2 = 7)) AND (a.unique2 = ANY ('{3,7}'::integer[])) AND (b.hundred = 4)) OR (a.unique1 < 20) OR (a.unique1 = 3))     ->  Seq Scan on tenk1 b     ->  Materialize           ->  Bitmap Heap Scan on tenk1 a -               Recheck Cond: ((unique1 < 20) OR (unique1 = 3) OR (unique1 = 1) OR (unique2 = ANY ('{3,7}'::integer[]))) +               Recheck Cond: ((unique1 = 1) OR (unique2 = ANY ('{3,7}'::integer[])) OR (unique1 < 20) OR (unique1 = 3))                 ->  BitmapOr                       ->  Bitmap Index Scan on tenk1_unique1 -                           Index Cond: (unique1 < 20) -                     ->  Bitmap Index Scan on tenk1_unique1 -                           Index Cond: (unique1 = 3) -                     ->  Bitmap Index Scan on tenk1_unique1                             Index Cond: (unique1 = 1)                       ->  Bitmap Index Scan on tenk1_unique2                             Index Cond: (unique2 = ANY ('{3,7}'::integer[])) +                     ->  Bitmap Index Scan on tenk1_unique1 +                           Index Cond: (unique1 < 20) +                     ->  Bitmap Index Scan on tenk1_unique1 +                           Index Cond: (unique1 = 3)  (15 rows) Thirdly,Ihaveevidencethatthismayaffecttheunderestimationof power.I'll lookinto thisin detaillater. diff -U3 /home/alena/postgrespro5/src/test/regress/expected/stats_ext.out /home/alena/postgrespro5/src/test/regress/results/stats_ext.out --- /home/alena/postgrespro5/src/test/regress/expected/stats_ext.out 2024-06-28 11:05:44.304135987 +0300 +++ /home/alena/postgrespro5/src/test/regress/results/stats_ext.out 2024-07-11 02:01:06.596007159 +0300 @@ -1156,19 +1156,19 @@  SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51) AND b = ''1''');   estimated | actual  -----------+-------- -         2 |    100 +         1 |    100  (1 row)  SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51) AND (b = ''1'' OR b = ''2'')');   estimated | actual  -----------+-------- -         4 |    100 +         1 |    100  (1 row)  SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 2 OR a = 51 OR a = 52) AND (b = ''1'' OR b = ''2'')');   estimated | actual  -----------+-------- -         8 |    200 +         1 |    200  (1 row)  -- OR clauses referencing different attributes @@ -1322,19 +1322,19 @@  SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51) AND b = ''1''');   estimated | actual  -----------+-------- -       100 |    100 +         2 |    100  (1 row)  SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51) AND (b = ''1'' OR b = ''2'')');   estimated | actual  -----------+-------- -       100 |    100 +         2 |    100  (1 row)  SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 2 OR a = 51 OR a = 52) AND (b = ''1'' OR b = ''2'')');   estimated | actual  -----------+-------- -       200 |    200 +         8 |    200  (1 row) -- Regards, Alena Rybakina Postgres Professional:http://www.postgrespro.com The Russian Postgres Company --------------s30quJsIBG0tPPxP9Fq16PsC Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit
On 27.06.2024 23:06, Alena Rybakina wrote:
To be honest, I've already started writing code to do this, but I'm faced with a misunderstanding of how to correctly create a condition for "OR" expressions that are not subject to transformation.

For example, the expressions b=1 in the query below:

alena@postgres=# explain select * from x where ( (a =5 or a=4) and a = ANY(ARRAY[5,4])) or (b=1); QUERY PLAN ---------------------------------------------------------------------------------- Seq Scan on x (cost=0.00..123.00 rows=1 width=8) Filter: ((((a = 5) OR (a = 4)) AND (a = ANY ('{5,4}'::integer[]))) OR (b = 1)) (2 rows)

I see that two expressions have remained unchanged and it only works for "AND" binary operations.

But I think it might be worth applying this together, where does the optimizer generate indexes (build_paths_for_OR function)?

I implemented such code, but at the analysis stage in planner, and it wasn't fully ready yet, but I was able to draw some important conclusions. First of all, I faced the problem of the inequality of the number of columns in the expression with the required one, at least some extra column appeared, judging by the crust. I haven't fully realized it yet and haven't fixed it.

#0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=134300960061248)
    at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (signo=6, threadid=134300960061248) at ./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (threadid=134300960061248, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#3  0x00007a2560042476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4  0x00007a25600287f3 in __GI_abort () at ./stdlib/abort.c:79
#5  0x00005573f9df62a8 in ExceptionalCondition (
    conditionName=0x5573f9fec4c8 "AttrNumberIsForUserDefinedAttr(list_attnums[i]) || !bms_is_member(attnum, clauses_attnums)", fileName=0x5573f9fec11c "dependencies.c", lineNumber=1525) at assert.c:66
#6  0x00005573f9b8b85f in dependencies_clauselist_selectivity (root=0x5573fad534e8,
    clauses=0x5573fad0b2d8, varRelid=0, jointype=JOIN_INNER, sjinfo=0x0, rel=0x5573fad54b38,
    estimatedclauses=0x7ffe2e43f178) at dependencies.c:1525
#7  0x00005573f9b8fed9 in statext_clauselist_selectivity (root=0x5573fad534e8, clauses=0x5573fad0b2d8,
    varRelid=0, jointype=JOIN_INNER, sjinfo=0x0, rel=0x5573fad54b38, estimatedclauses=0x7ffe2e43f178,
    is_or=false) at extended_stats.c:2035
--Type <RET> for more, q to quit, c to continue without paging--
#8  0x00005573f9a57f88 in clauselist_selectivity_ext (root=0x5573fad534e8, clauses=0x5573fad0b2d8,
    varRelid=0, jointype=JOIN_INNER, sjinfo=0x0, use_extended_stats=true) at clausesel.c:153
#9  0x00005573f9a57e30 in clauselist_selectivity (root=0x5573fad534e8, clauses=0x5573fad0b2d8,
    varRelid=0, jointype=JOIN_INNER, sjinfo=0x0) at clausesel.c:106
#10 0x00005573f9a62e03 in set_baserel_size_estimates (root=0x5573fad534e8, rel=0x5573fad54b38)
    at costsize.c:5247
#11 0x00005573f9a51aa5 in set_plain_rel_size (root=0x5573fad534e8, rel=0x5573fad54b38,
    rte=0x5573fad0ec58) at allpaths.c:581
#12 0x00005573f9a516ce in set_rel_size (root=0x5573fad534e8, rel=0x5573fad54b38, rti=1,
    rte=0x5573fad0ec58) at allpaths.c:411
#13 0x00005573f9a514c7 in set_base_rel_sizes (root=0x5573fad534e8) at allpaths.c:322
#14 0x00005573f9a5119d in make_one_rel (root=0x5573fad534e8, joinlist=0x5573fad0adf8) at allpaths.c:183
#15 0x00005573f9a94d45 in query_planner (root=0x5573fad534e8,
    qp_callback=0x5573f9a9b59e <standard_qp_callback>, qp_extra=0x7ffe2e43f540) at planmain.c:280
#16 0x00005573f9a977a8 in grouping_planner (root=0x5573fad534e8, tuple_fraction=0, setops=0x0)
    at planner.c:1520
#17 0x00005573f9a96e47 in subquery_planner (glob=0x5573fad533d8, parse=0x5573fad0ea48, parent_root=0x0,
    hasRecursion=false, tuple_fraction=0, setops=0x0) at planner.c:1089
#18 0x00005573f9a954aa in standard_planner (parse=0x5573fad0ea48,
    query_string=0x5573fad8b3b0 "explain analyze SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = '1'", cursorOptions=2048, boundParams=0x0) at planner.c:415
#19 0x00005573f9a951d4 in planner (parse=0x5573fad0ea48,
--Type <RET> for more, q to quit, c to continue without paging--
    query_string=0x5573fad8b3b0 "explain analyze SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = '1'", cursorOptions=2048, boundParams=0x0) at planner.c:282
#20 0x00005573f9bf4e2e in pg_plan_query (querytree=0x5573fad0ea48,
    query_string=0x5573fad8b3b0 "explain analyze SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = '1'", cursorOptions=2048, boundParams=0x0) at postgres.c:904
#21 0x00005573f98613e7 in standard_ExplainOneQuery (query=0x5573fad0ea48, cursorOptions=2048, into=0x0,
    es=0x5573fad57da0,
    queryString=0x5573fad8b3b0 "explain analyze SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = '1'", params=0x0, queryEnv=0x0) at explain.c:489
#22 0x00005573f9861205 in ExplainOneQuery (query=0x5573fad0ea48, cursorOptions=2048, into=0x0,
    es=0x5573fad57da0,
    queryString=0x5573fad8b3b0 "explain analyze SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = '1'", params=0x0, queryEnv=0x0) at explain.c:445
#23 0x00005573f9860e35 in ExplainQuery (pstate=0x5573fad57c90, stmt=0x5573fad8b5a0, params=0x0,
    dest=0x5573fad57c00) at explain.c:341
#24 0x00005573f9bff3a8 in standard_ProcessUtility (pstmt=0x5573fad8b490,
    queryString=0x5573fad8b3b0 "explain analyze SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = '1'", readOnlyTree=false, context=PROCESS_UTILITY_QUERY, params=0x0,
    queryEnv=0x0, dest=0x5573fad57c00, qc=0x7ffe2e43fcd0) at utility.c:863
#25 0x00005573f9bfe91a in ProcessUtility (pstmt=0x5573fad8b490,
    queryString=0x5573fad8b3b0 "explain analyze SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = '1'", readOnlyTree=false, context=PROCESS_UTILITY_QUERY, params=0x0,
--Type <RET> for more, q to quit, c to continue without paging--
    queryEnv=0x0, dest=0x5573fad57c00, qc=0x7ffe2e43fcd0) at utility.c:523
#26 0x00005573f9bfd195 in PortalRunUtility (portal=0x5573fac6bcf0, pstmt=0x5573fad8b490,
    isTopLevel=false, setHoldSnapshot=true, dest=0x5573fad57c00, qc=0x7ffe2e43fcd0) at pquery.c:1158
#27 0x00005573f9bfced2 in FillPortalStore (portal=0x5573fac6bcf0, isTopLevel=false) at pquery.c:1031
#28 0x00005573f9bfd778 in PortalRunFetch (portal=0x5573fac6bcf0, fdirection=FETCH_FORWARD, count=10,
    dest=0x5573fa1d6880 <spi_printtupDR>) at pquery.c:1442
#29 0x00005573f9992675 in _SPI_cursor_operation (portal=0x5573fac6bcf0, direction=FETCH_FORWARD,
    count=10, dest=0x5573fa1d6880 <spi_printtupDR>) at spi.c:3019
#30 0x00005573f9990849 in SPI_cursor_fetch (portal=0x5573fac6bcf0, forward=true, count=10) at spi.c:1805
#31 0x00007a25603e0aa5 in exec_for_query (estate=0x7ffe2e440200, stmt=0x5573fad067c8,
    portal=0x5573fac6bcf0, prefetch_ok=true) at pl_exec.c:5889
#32 0x00007a25603de728 in exec_stmt_dynfors (estate=0x7ffe2e440200, stmt=0x5573fad067c8)
    at pl_exec.c:4647
#33 0x00007a25603d8b1c in exec_stmts (estate=0x7ffe2e440200, stmts=0x5573fad06ec8) at pl_exec.c:2100
#34 0x00007a25603d8697 in exec_stmt_block (estate=0x7ffe2e440200, block=0x5573fad06f18) at pl_exec.c:1943
#35 0x00007a25603d7d9e in exec_toplevel_block (estate=0x7ffe2e440200, block=0x5573fad06f18)
    at pl_exec.c:1634
#36 0x00007a25603d5a2e in plpgsql_exec_function (func=0x5573fac2c1e0, fcinfo=0x5573fad2af60,
    simple_eval_estate=0x0, simple_eval_resowner=0x0, procedure_resowner=0x0, atomic=true)
    at pl_exec.c:623
#37 0x00007a25603f277f in plpgsql_call_handler (fcinfo=0x5573fad2af60) at pl_handler.c:277
#38 0x00005573f993589a in ExecMakeTableFunctionResult (setexpr=0x5573facfd8c8, econtext=0x5573facfd798,
--Type <RET> for more, q to quit, c to continue without paging--
    argContext=0x5573fad2ae60, expectedDesc=0x5573facfe130, randomAccess=false) at execSRF.c:234
#39 0x00005573f995299c in FunctionNext (node=0x5573facfd588) at nodeFunctionscan.c:94
#40 0x00005573f993735f in ExecScanFetch (node=0x5573facfd588, accessMtd=0x5573f99528e6 <FunctionNext>,
    recheckMtd=0x5573f9952ced <FunctionRecheck>) at execScan.c:131
#41 0x00005573f99373d8 in ExecScan (node=0x5573facfd588, accessMtd=0x5573f99528e6 <FunctionNext>,
    recheckMtd=0x5573f9952ced <FunctionRecheck>) at execScan.c:180
#42 0x00005573f9952d46 in ExecFunctionScan (pstate=0x5573facfd588) at nodeFunctionscan.c:269
#43 0x00005573f9932c7f in ExecProcNodeFirst (node=0x5573facfd588) at execProcnode.c:464
#44 0x00005573f9925df5 in ExecProcNode (node=0x5573facfd588)
    at ../../../src/include/executor/executor.h:274
#45 0x00005573f9928bf9 in ExecutePlan (estate=0x5573facfd360, planstate=0x5573facfd588,
    use_parallel_mode=false, operation=CMD_SELECT, sendTuples=true, numberTuples=0,
    direction=ForwardScanDirection, dest=0x5573fad8f6e0, execute_once=true) at execMain.c:1646
#46 0x00005573f992653d in standard_ExecutorRun (queryDesc=0x5573fad87f70,
    direction=ForwardScanDirection, count=0, execute_once=true) at execMain.c:363
#47 0x00005573f9926316 in ExecutorRun (queryDesc=0x5573fad87f70, direction=ForwardScanDirection,
    count=0, execute_once=true) at execMain.c:304
#48 0x00005573f9bfcb7d in PortalRunSelect (portal=0x5573fac6bbe0, forward=true, count=0,
    dest=0x5573fad8f6e0) at pquery.c:924
#49 0x00005573f9bfc7a5 in PortalRun (portal=0x5573fac6bbe0, count=9223372036854775807, isTopLevel=true,
    run_once=true, dest=0x5573fad8f6e0, altdest=0x5573fad8f6e0, qc=0x7ffe2e440a60) at pquery.c:768
#50 0x00005573f9bf5512 in exec_simple_query (
--Type <RET> for more, q to quit, c to continue without paging--
    query_string=0x5573fabea030 "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = ''1''');") at postgres.c:1274
#51 0x00005573f9bfa5b7 in PostgresMain (dbname=0x5573fab52240 "regression",
    username=0x5573fac27c98 "alena") at postgres.c:4680
#52 0x00005573f9bf137e in BackendMain (startup_data=0x7ffe2e440ce4 "", startup_data_len=4)
    at backend_startup.c:105
#53 0x00005573f9b06852 in postmaster_child_launch (child_type=B_BACKEND, startup_data=0x7ffe2e440ce4 "",
    startup_data_len=4, client_sock=0x7ffe2e440d30) at launch_backend.c:265
#54 0x00005573f9b0cd66 in BackendStartup (client_sock=0x7ffe2e440d30) at postmaster.c:3593
#55 0x00005573f9b09db1 in ServerLoop () at postmaster.c:1674
#56 0x00005573f9b09678 in PostmasterMain (argc=8, argv=0x5573fab500d0) at postmaster.c:1372
#57 0x00005573f99b5f79 in main (argc=8, argv=0x5573fab500d0) at main.c:197


Secondly, I saw diff changes in queries that showed cases where the optimizer did not eliminate one of the redundant expressions and processed both of them. This indicates the problem that the optimizer has not learned how to handle it in all cases. I think I'll need to add some code to handle it.

 EXPLAIN (COSTS OFF)
 SELECT count(*) FROM tenk1
   WHERE hundred = 42 AND (thousand = 42 OR thousand = 99 OR tenthous < 2) OR thousand = 41;
-                                                         QUERY PLAN                                                          
------------------------------------------------------------------------------------------------------------------------------
+                                                                                           QUERY PLAN                                                                                            
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  Aggregate
    ->  Bitmap Heap Scan on tenk1
-         Recheck Cond: (((hundred = 42) AND ((thousand = ANY ('{42,99}'::integer[])) OR (tenthous < 2))) OR (thousand = 41))
+         Recheck Cond: (((((thousand = 42) AND (thousand = ANY ('{42,99}'::integer[]))) OR ((thousand = 99) AND (thousand = ANY ('{42,99}'::integer[])))) OR (tenthous < 2)) OR (thousand = 41))
+         Filter: (((hundred = 42) AND ((((thousand = 42) OR (thousand = 99)) AND (thousand = ANY ('{42,99}'::integer[]))) OR (tenthous < 2))) OR (thousand = 41))
          ->  BitmapOr
-               ->  BitmapAnd
-                     ->  Bitmap Index Scan on tenk1_hundred
-                           Index Cond: (hundred = 42)
+               ->  BitmapOr
                      ->  BitmapOr
                            ->  Bitmap Index Scan on tenk1_thous_tenthous
-                                 Index Cond: (thousand = ANY ('{42,99}'::integer[]))
+                                 Index Cond: ((thousand = 42) AND (thousand = ANY ('{42,99}'::integer[])))
                            ->  Bitmap Index Scan on tenk1_thous_tenthous
-                                 Index Cond: (tenthous < 2)
+                                 Index Cond: ((thousand = 99) AND (thousand = ANY ('{42,99}'::integer[])))
+                     ->  Bitmap Index Scan on tenk1_thous_tenthous
+                           Index Cond: (tenthous < 2)
                ->  Bitmap Index Scan on tenk1_thous_tenthous
                      Index Cond: (thousand = 41)
-(14 rows)
+(15 rows)
 
 SELECT count(*) FROM tenk1
   WHERE hundred = 42 AND (thousand = 42 OR thousand = 99 OR tenthous < 2) OR thousand = 41;
@@ -1986,20 +1987,21 @@
 EXPLAIN (COSTS OFF)
 SELECT count(*) FROM tenk1
   WHERE hundred = 42 AND (thousand = 42 OR thousand = 41 OR thousand = 99 AND tenthous = 2);
-                                                          QUERY PLAN                                                          
-------------------------------------------------------------------------------------------------------------------------------
+                                                                                            QUERY PLAN                                                                                            
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  Aggregate
    ->  Bitmap Heap Scan on tenk1
-         Recheck Cond: ((hundred = 42) AND ((thousand = ANY ('{41,42}'::integer[])) OR ((thousand = 99) AND (tenthous = 2))))
-         ->  BitmapAnd
-               ->  Bitmap Index Scan on tenk1_hundred
-                     Index Cond: (hundred = 42)
+         Recheck Cond: ((((thousand = 42) AND (thousand = ANY ('{41,42}'::integer[]))) OR ((thousand = 41) AND (thousand = ANY ('{41,42}'::integer[])))) OR ((thousand = 99) AND (tenthous = 2)))
+         Filter: (hundred = 42)
+         ->  BitmapOr
                ->  BitmapOr
                      ->  Bitmap Index Scan on tenk1_thous_tenthous
-                           Index Cond: (thousand = ANY ('{41,42}'::integer[]))
+                           Index Cond: ((thousand = 42) AND (thousand = ANY ('{41,42}'::integer[])))
                      ->  Bitmap Index Scan on tenk1_thous_tenthous
-                           Index Cond: ((thousand = 99) AND (tenthous = 2))
-(11 rows)
+                           Index Cond: ((thousand = 41) AND (thousand = ANY ('{41,42}'::integer[])))
+               ->  Bitmap Index Scan on tenk1_thous_tenthous
+                     Index Cond: ((thousand = 99) AND (tenthous = 2))
+(12 rows)
 
 SELECT count(*) FROM tenk1
   WHERE hundred = 42 AND (thousand = 42 OR thousand = 41 OR thousand = 99 AND tenthous = 2);
diff -U3 /home/alena/postgrespro5/src/test/regress/expected/inherit.out /home/alena/postgrespro5/src/test/regress/results/inherit.out
--- /home/alena/postgrespro5/src/test/regress/expected/inherit.out    2024-06-20 12:28:52.324011724 +0300
+++ /home/alena/postgrespro5/src/test/regress/results/inherit.out    2024-07-11 02:00:55.404006843 +0300
@@ -2126,7 +2126,7 @@
                                    QUERY PLAN                                    
 ---------------------------------------------------------------------------------
  Seq Scan on part_ab_cd list_parted
-   Filter: (((a)::text = 'ab'::text) OR ((a)::text = ANY ('{NULL,cd}'::text[])))
+   Filter: (((a)::text = ANY ('{NULL,cd}'::text[])) OR ((a)::text = 'ab'::text))
 (2 rows)
 
 explain (costs off) select * from list_parted where a = 'ab';
diff -U3 /home/alena/postgrespro5/src/test/regress/expected/join.out /home/alena/postgrespro5/src/test/regress/results/join.out
--- /home/alena/postgrespro5/src/test/regress/expected/join.out    2024-06-28 11:05:44.304135987 +0300
+++ /home/alena/postgrespro5/src/test/regress/results/join.out    2024-07-11 02:00:58.152006921 +0300
@@ -4210,10 +4210,17 @@
 select * from tenk1 a join tenk1 b on
   (a.unique1 = 1 and b.unique1 = 2) or
   ((a.unique2 = 3 or a.unique2 = 7) and b.hundred = 4);
-                                                       QUERY PLAN                                                       
-------------------------------------------------------------------------------------------------------------------------
+                                                                           QUERY PLAN                                                                            
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------
  Nested Loop
-   Join Filter: (((a.unique1 = 1) AND (b.unique1 = 2)) OR ((a.unique2 = ANY ('{3,7}'::integer[])) AND (b.hundred = 4)))
+   Join Filter: (((a.unique1 = 1) AND (b.unique1 = 2)) OR (((a.unique2 = 3) OR (a.unique2 = 7)) AND (a.unique2 = ANY ('{3,7}'::integer[])) AND (b.hundred = 4)))
+   ->  Bitmap Heap Scan on tenk1 a
+         Recheck Cond: ((unique1 = 1) OR (unique2 = ANY ('{3,7}'::integer[])))
+         ->  BitmapOr
+               ->  Bitmap Index Scan on tenk1_unique1
+                     Index Cond: (unique1 = 1)
+               ->  Bitmap Index Scan on tenk1_unique2
+                     Index Cond: (unique2 = ANY ('{3,7}'::integer[]))
    ->  Bitmap Heap Scan on tenk1 b
          Recheck Cond: ((unique1 = 2) OR (hundred = 4))
          ->  BitmapOr
@@ -4221,25 +4228,24 @@
                      Index Cond: (unique1 = 2)
                ->  Bitmap Index Scan on tenk1_hundred
                      Index Cond: (hundred = 4)
-   ->  Materialize
-         ->  Bitmap Heap Scan on tenk1 a
-               Recheck Cond: ((unique1 = 1) OR (unique2 = ANY ('{3,7}'::integer[])))
-               ->  BitmapOr
-                     ->  Bitmap Index Scan on tenk1_unique1
-                           Index Cond: (unique1 = 1)
-                     ->  Bitmap Index Scan on tenk1_unique2
-                           Index Cond: (unique2 = ANY ('{3,7}'::integer[]))
-(17 rows)
+(16 rows)
 
 SET enable_or_transformation = on;
 explain (costs off)
 select * from tenk1 a join tenk1 b on
   (a.unique1 = 1 and b.unique1 = 2) or
   ((a.unique2 = 3 or a.unique2 = 7) and b.hundred = 4);
-                                                       QUERY PLAN                                                       
-------------------------------------------------------------------------------------------------------------------------
+                                                                           QUERY PLAN                                                                            
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------
  Nested Loop
-   Join Filter: (((a.unique1 = 1) AND (b.unique1 = 2)) OR ((a.unique2 = ANY ('{3,7}'::integer[])) AND (b.hundred = 4)))
+   Join Filter: (((a.unique1 = 1) AND (b.unique1 = 2)) OR (((a.unique2 = 3) OR (a.unique2 = 7)) AND (a.unique2 = ANY ('{3,7}'::integer[])) AND (b.hundred = 4)))
+   ->  Bitmap Heap Scan on tenk1 a
+         Recheck Cond: ((unique1 = 1) OR (unique2 = ANY ('{3,7}'::integer[])))
+         ->  BitmapOr
+               ->  Bitmap Index Scan on tenk1_unique1
+                     Index Cond: (unique1 = 1)
+               ->  Bitmap Index Scan on tenk1_unique2
+                     Index Cond: (unique2 = ANY ('{3,7}'::integer[]))
    ->  Bitmap Heap Scan on tenk1 b
          Recheck Cond: ((unique1 = 2) OR (hundred = 4))
          ->  BitmapOr
@@ -4247,37 +4253,29 @@
                      Index Cond: (unique1 = 2)
                ->  Bitmap Index Scan on tenk1_hundred
                      Index Cond: (hundred = 4)
-   ->  Materialize
-         ->  Bitmap Heap Scan on tenk1 a
-               Recheck Cond: ((unique1 = 1) OR (unique2 = ANY ('{3,7}'::integer[])))
-               ->  BitmapOr
-                     ->  Bitmap Index Scan on tenk1_unique1
-                           Index Cond: (unique1 = 1)
-                     ->  Bitmap Index Scan on tenk1_unique2
-                           Index Cond: (unique2 = ANY ('{3,7}'::integer[]))
-(17 rows)
+(16 rows)
 
 explain (costs off)
 select * from tenk1 a join tenk1 b on
   (a.unique1 < 20 or a.unique1 = 3 or a.unique1 = 1 and b.unique1 = 2) or
   ((a.unique2 = 3 or a.unique2 = 7) and b.hundred = 4);
-                                                                          QUERY PLAN                                                                           
----------------------------------------------------------------------------------------------------------------------------------------------------------------
+                                                                                               QUERY PLAN                                                                                               
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  Nested Loop
-   Join Filter: ((a.unique1 < 20) OR (a.unique1 = 3) OR ((a.unique1 = 1) AND (b.unique1 = 2)) OR ((a.unique2 = ANY ('{3,7}'::integer[])) AND (b.hundred = 4)))
+   Join Filter: (((a.unique1 = 1) AND (b.unique1 = 2)) OR (((a.unique2 = 3) OR (a.unique2 = 7)) AND (a.unique2 = ANY ('{3,7}'::integer[])) AND (b.hundred = 4)) OR (a.unique1 < 20) OR (a.unique1 = 3))
    ->  Seq Scan on tenk1 b
    ->  Materialize
          ->  Bitmap Heap Scan on tenk1 a
-               Recheck Cond: ((unique1 < 20) OR (unique1 = 3) OR (unique1 = 1) OR (unique2 = ANY ('{3,7}'::integer[])))
+               Recheck Cond: ((unique1 = 1) OR (unique2 = ANY ('{3,7}'::integer[])) OR (unique1 < 20) OR (unique1 = 3))
                ->  BitmapOr
                      ->  Bitmap Index Scan on tenk1_unique1
-                           Index Cond: (unique1 < 20)
-                     ->  Bitmap Index Scan on tenk1_unique1
-                           Index Cond: (unique1 = 3)
-                     ->  Bitmap Index Scan on tenk1_unique1
                            Index Cond: (unique1 = 1)
                      ->  Bitmap Index Scan on tenk1_unique2
                            Index Cond: (unique2 = ANY ('{3,7}'::integer[]))
+                     ->  Bitmap Index Scan on tenk1_unique1
+                           Index Cond: (unique1 < 20)
+                     ->  Bitmap Index Scan on tenk1_unique1
+                           Index Cond: (unique1 = 3)
 (15 rows)


Thirdly, I have evidence that this may affect the underestimation of power. I'll look into this in detail later.

diff -U3 /home/alena/postgrespro5/src/test/regress/expected/stats_ext.out /home/alena/postgrespro5/src/test/regress/results/stats_ext.out
--- /home/alena/postgrespro5/src/test/regress/expected/stats_ext.out    2024-06-28 11:05:44.304135987 +0300
+++ /home/alena/postgrespro5/src/test/regress/results/stats_ext.out    2024-07-11 02:01:06.596007159 +0300
@@ -1156,19 +1156,19 @@
 SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51) AND b = ''1''');
  estimated | actual
 -----------+--------
-         2 |    100
+         1 |    100
 (1 row)
 
 SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51) AND (b = ''1'' OR b = ''2'')');
  estimated | actual
 -----------+--------
-         4 |    100
+         1 |    100
 (1 row)
 
 SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 2 OR a = 51 OR a = 52) AND (b = ''1'' OR b = ''2'')');
  estimated | actual
 -----------+--------
-         8 |    200
+         1 |    200
 (1 row)
 
 -- OR clauses referencing different attributes
@@ -1322,19 +1322,19 @@
 SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51) AND b = ''1''');
  estimated | actual
 -----------+--------
-       100 |    100
+         2 |    100
 (1 row)
 
 SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51) AND (b = ''1'' OR b = ''2'')');
  estimated | actual
 -----------+--------
-       100 |    100
+         2 |    100
 (1 row)
 
 SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 2 OR a = 51 OR a = 52) AND (b = ''1'' OR b = ''2'')');
  estimated | actual
 -----------+--------
-       200 |    200
+         8 |    200
 (1 row)

-- 
Regards,
Alena Rybakina
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company
--------------s30quJsIBG0tPPxP9Fq16PsC-- --------------3caDxovxFfbd3FFYZrytmE8M Content-Type: text/plain; charset=UTF-8; name="or.diff.no-cfbot" Content-Disposition: attachment; filename="or.diff.no-cfbot" Content-Transfer-Encoding: base64 ZGlmZiAtLWdpdCBhL3NyYy9iYWNrZW5kL25vZGVzL3F1ZXJ5anVtYmxlZnVuY3MuYyBiL3Ny Yy9iYWNrZW5kL25vZGVzL3F1ZXJ5anVtYmxlZnVuY3MuYwppbmRleCAxMjlmYjQ0NzA5OS4u YjJiNDU3YjYxNGMgMTAwNjQ0Ci0tLSBhL3NyYy9iYWNrZW5kL25vZGVzL3F1ZXJ5anVtYmxl ZnVuY3MuYworKysgYi9zcmMvYmFja2VuZC9ub2Rlcy9xdWVyeWp1bWJsZWZ1bmNzLmMKQEAg LTE0MCw2ICsxNDAsMzMgQEAgSnVtYmxlUXVlcnkoUXVlcnkgKnF1ZXJ5KQogCXJldHVybiBq c3RhdGU7CiB9CiAKK0p1bWJsZVN0YXRlICoKK0p1bWJsZUV4cHIoRXhwciAqZXhwciwgdWlu dDY0ICpxdWVyeUlkKQoreworCUp1bWJsZVN0YXRlICpqc3RhdGUgPSBOVUxMOworCisJQXNz ZXJ0KHF1ZXJ5SWQgIT0gTlVMTCk7CisKKwlqc3RhdGUgPSAoSnVtYmxlU3RhdGUgKikgcGFs bG9jKHNpemVvZihKdW1ibGVTdGF0ZSkpOworCisJLyogU2V0IHVwIHdvcmtzcGFjZSBmb3Ig cXVlcnkganVtYmxpbmcgKi8KKwlqc3RhdGUtPmp1bWJsZSA9ICh1bnNpZ25lZCBjaGFyICop IHBhbGxvYyhKVU1CTEVfU0laRSk7CisJanN0YXRlLT5qdW1ibGVfbGVuID0gMDsKKwlqc3Rh dGUtPmNsb2NhdGlvbnNfYnVmX3NpemUgPSAzMjsKKwlqc3RhdGUtPmNsb2NhdGlvbnMgPSAo TG9jYXRpb25MZW4gKikKKwkJcGFsbG9jKGpzdGF0ZS0+Y2xvY2F0aW9uc19idWZfc2l6ZSAq IHNpemVvZihMb2NhdGlvbkxlbikpOworCWpzdGF0ZS0+Y2xvY2F0aW9uc19jb3VudCA9IDA7 CisJanN0YXRlLT5oaWdoZXN0X2V4dGVybl9wYXJhbV9pZCA9IDA7CisKKwkvKiBDb21wdXRl IHF1ZXJ5IElEICovCisJX2p1bWJsZU5vZGUoanN0YXRlLCAoTm9kZSAqKSBleHByKTsKKwkq cXVlcnlJZCA9IERhdHVtR2V0VUludDY0KGhhc2hfYW55X2V4dGVuZGVkKGpzdGF0ZS0+anVt YmxlLAorCQkJCQkJCQkJCQkJanN0YXRlLT5qdW1ibGVfbGVuLAorCQkJCQkJCQkJCQkJMCkp OworCisJcmV0dXJuIGpzdGF0ZTsKK30KKwogLyoKICAqIEVuYWJsZXMgcXVlcnkgaWRlbnRp ZmllciBjb21wdXRhdGlvbi4KICAqCmRpZmYgLS1naXQgYS9zcmMvYmFja2VuZC9wYXJzZXIv cGFyc2VfZXhwci5jIGIvc3JjL2JhY2tlbmQvcGFyc2VyL3BhcnNlX2V4cHIuYwppbmRleCAw MGNkNzM1OGViYi4uMDIxNmQ2MWI4MDEgMTAwNjQ0Ci0tLSBhL3NyYy9iYWNrZW5kL3BhcnNl ci9wYXJzZV9leHByLmMKKysrIGIvc3JjL2JhY2tlbmQvcGFyc2VyL3BhcnNlX2V4cHIuYwpA QCAtMTYsMTIgKzE2LDE1IEBACiAjaW5jbHVkZSAicG9zdGdyZXMuaCIKIAogI2luY2x1ZGUg ImNhdGFsb2cvcGdfYWdncmVnYXRlLmgiCisjaW5jbHVkZSAiY2F0YWxvZy9wZ19vcGVyYXRv ci5oIgogI2luY2x1ZGUgImNhdGFsb2cvcGdfcHJvYy5oIgogI2luY2x1ZGUgImNhdGFsb2cv cGdfdHlwZS5oIgogI2luY2x1ZGUgImNvbW1hbmRzL2RiY29tbWFuZHMuaCIKKyNpbmNsdWRl ICJjb21tb24vaGFzaGZuLmgiCiAjaW5jbHVkZSAibWlzY2FkbWluLmgiCiAjaW5jbHVkZSAi bm9kZXMvbWFrZWZ1bmNzLmgiCiAjaW5jbHVkZSAibm9kZXMvbm9kZUZ1bmNzLmgiCisjaW5j bHVkZSAibm9kZXMvcXVlcnlqdW1ibGUuaCIKICNpbmNsdWRlICJvcHRpbWl6ZXIvb3B0aW1p emVyLmgiCiAjaW5jbHVkZSAicGFyc2VyL2FuYWx5emUuaCIKICNpbmNsdWRlICJwYXJzZXIv cGFyc2VfYWdnLmgiCkBAIC00MSw2ICs0NCw5IEBACiAjaW5jbHVkZSAidXRpbHMvbHN5c2Nh Y2hlLmgiCiAjaW5jbHVkZSAidXRpbHMvdGltZXN0YW1wLmgiCiAjaW5jbHVkZSAidXRpbHMv eG1sLmgiCisjaW5jbHVkZSAidXRpbHMvc3lzY2FjaGUuaCIKKworYm9vbAkJZW5hYmxlX29y X3RyYW5zZm9ybWF0aW9uID0gdHJ1ZTsKIAogLyogR1VDIHBhcmFtZXRlcnMgKi8KIGJvb2wJ CVRyYW5zZm9ybV9udWxsX2VxdWFscyA9IGZhbHNlOwpAQCAtMTEwLDYgKzExNiw0MTUgQEAg c3RhdGljIEV4cHIgKm1ha2VfZGlzdGluY3Rfb3AoUGFyc2VTdGF0ZSAqcHN0YXRlLCBMaXN0 ICpvcG5hbWUsCiBzdGF0aWMgTm9kZSAqbWFrZV9udWxsdGVzdF9mcm9tX2Rpc3RpbmN0KFBh cnNlU3RhdGUgKnBzdGF0ZSwKIAkJCQkJCQkJCQkgQV9FeHByICpkaXN0aW5jdGEsIE5vZGUg KmFyZyk7CiAKK3R5cGVkZWYgc3RydWN0IE9yQ2xhdXNlR3JvdXBLZXkKK3sKKwlOb2RlVGFn CXR5cGU7CisKKwlFeHByICAgKmV4cHI7IC8qIFBvaW50ZXIgdG8gdGhlIGV4cHJlc3Npb24g dHJlZSB3aGljaCBoYXMgYmVlbiBhIHNvdXJjZSBmb3IKKwkJCQkJdGhlIGhhc2hrZXkgdmFs dWUgKi8KKwlPaWQJCW9wbm87CisJT2lkCQlleHBydHlwZTsKK30gT3JDbGF1c2VHcm91cEtl eTsKKwordHlwZWRlZiBzdHJ1Y3QgT3JDbGF1c2VHcm91cEVudHJ5Cit7CisJT3JDbGF1c2VH cm91cEtleQlrZXk7CisKKwlMaXN0CQkJICAgKmNvbnN0czsKKwlMaXN0IAkJCSAgICpleHBy czsKKwlGdW5jdGlvbkNhbGxJbmZvCWZjaW5mbzsKK30gT3JDbGF1c2VHcm91cEVudHJ5Owor CisvKgorICogSGFzaCBmdW5jdGlvbiB0byBmaW5kIGNhbmRpZGF0ZSBjbGF1c2VzLgorICov CitzdGF0aWMgdWludDMyCitvcmNsYXVzZV9oYXNoKGNvbnN0IHZvaWQgKmRhdGEsIFNpemUg a2V5c2l6ZSkKK3sKKwlPckNsYXVzZUdyb3VwS2V5ICAgKmtleSA9IChPckNsYXVzZUdyb3Vw S2V5ICopIGRhdGE7CisJdWludDY0CQkJCWV4cHJIYXNoOworCisJQXNzZXJ0KGtleXNpemUg PT0gc2l6ZW9mKE9yQ2xhdXNlR3JvdXBLZXkpKTsKKwlBc3NlcnQoSXNBKGRhdGEsIEludmFs aWQpKTsKKworCSh2b2lkKSBKdW1ibGVFeHByKGtleS0+ZXhwciwgJmV4cHJIYXNoKTsKKwor CXJldHVybiBoYXNoX2NvbWJpbmUoKHVpbnQzMikgZXhwckhhc2gsCisJCQkJCQloYXNoX2Nv bWJpbmUoKHVpbnQzMikga2V5LT5vcG5vLAorCQkJCQkJCQkJICh1aW50MzIpIGtleS0+ZXhw cnR5cGUpKTsKK30KKworc3RhdGljIHZvaWQgKgorb3JjbGF1c2Vfa2V5Y29weSh2b2lkICpk ZXN0LCBjb25zdCB2b2lkICpzcmMsIFNpemUga2V5c2l6ZSkKK3sKKwlPckNsYXVzZUdyb3Vw S2V5ICpzcmNfa2V5ID0gKE9yQ2xhdXNlR3JvdXBLZXkgKikgc3JjOworCU9yQ2xhdXNlR3Jv dXBLZXkgKmRzdF9rZXkgPSAoT3JDbGF1c2VHcm91cEtleSAqKSBkZXN0OworCisJQXNzZXJ0 KHNpemVvZihPckNsYXVzZUdyb3VwS2V5KSA9PSBrZXlzaXplKTsKKwlBc3NlcnQoSXNBKHNy YywgSW52YWxpZCkpOworCisJZHN0X2tleS0+dHlwZSA9IFRfSW52YWxpZDsKKwlkc3Rfa2V5 LT5leHByID0gc3JjX2tleS0+ZXhwcjsKKwlkc3Rfa2V5LT5vcG5vID0gc3JjX2tleS0+b3Bu bzsKKwlkc3Rfa2V5LT5leHBydHlwZSA9IHNyY19rZXktPmV4cHJ0eXBlOworCXJldHVybiBk c3Rfa2V5OworfQorCisvKgorICogRHluYWhhc2ggbWF0Y2ggZnVuY3Rpb24gdG8gdXNlIGlu IG9yX2dyb3VwX2h0YWIKKyAqLworc3RhdGljIGludAorb3JjbGF1c2VfbWF0Y2goY29uc3Qg dm9pZCAqZGF0YTEsIGNvbnN0IHZvaWQgKmRhdGEyLCBTaXplIGtleXNpemUpCit7CisJT3JD bGF1c2VHcm91cEtleSAgICprZXkxID0gKE9yQ2xhdXNlR3JvdXBLZXkgKikgZGF0YTE7CisJ T3JDbGF1c2VHcm91cEtleSAgICprZXkyID0gKE9yQ2xhdXNlR3JvdXBLZXkgKikgZGF0YTI7 CisKKwlBc3NlcnQoc2l6ZW9mKE9yQ2xhdXNlR3JvdXBLZXkpID09IGtleXNpemUpOworCUFz c2VydChJc0Eoa2V5MSwgSW52YWxpZCkpOworCUFzc2VydChJc0Eoa2V5MiwgSW52YWxpZCkp OworCisJaWYgKGtleTEtPm9wbm8gPT0ga2V5Mi0+b3BubyAmJgorCQlrZXkxLT5leHBydHlw ZSA9PSBrZXkyLT5leHBydHlwZSAmJgorCQllcXVhbChrZXkxLT5leHByLCBrZXkyLT5leHBy KSkKKwkJcmV0dXJuIDA7CisKKwlyZXR1cm4gMTsKK30KKworc3RhdGljIEZ1bmN0aW9uQ2Fs bEluZm8gbG9jZmNpbmZvID0gTlVMTDsKKworc3RhdGljIGludAorc2FvcF9jb25zdF9jb21w YXJhdG9yKGNvbnN0IExpc3RDZWxsICphLCBjb25zdCBMaXN0Q2VsbCAqYikKK3sKKwlOb2Rl ICAgKmxlZnRvcCA9IChOb2RlICopIGxmaXJzdChhKTsKKwlOb2RlICAgKnJpZ2h0b3AgPSAo Tm9kZSAqKSBsZmlyc3QoYik7CisKKwlpZiAoSXNBKGxlZnRvcCwgUmVsYWJlbFR5cGUpKQor CQlsZWZ0b3AgPSAoTm9kZSAqKSAoKFJlbGFiZWxUeXBlICopIGxlZnRvcCktPmFyZzsKKwor CWlmIChJc0EocmlnaHRvcCwgUmVsYWJlbFR5cGUpKQorCQlyaWdodG9wID0gKE5vZGUgKikg KChSZWxhYmVsVHlwZSAqKSByaWdodG9wKS0+YXJnOworCisJQXNzZXJ0KElzQShsZWZ0b3As IENvbnN0KSAmJiBJc0EocmlnaHRvcCwgQ29uc3QpKTsKKworCWxvY2ZjaW5mby0+YXJnc1sw XS52YWx1ZSA9ICgoQ29uc3QgKikgbGVmdG9wKS0+Y29uc3R2YWx1ZTsKKwlsb2NmY2luZm8t PmFyZ3NbMF0uaXNudWxsID0gZmFsc2U7CisJbG9jZmNpbmZvLT5hcmdzWzFdLnZhbHVlID0g KChDb25zdCAqKSByaWdodG9wKS0+Y29uc3R2YWx1ZTsKKwlsb2NmY2luZm8tPmFyZ3NbMV0u aXNudWxsID0gZmFsc2U7CisJcmV0dXJuIERhdHVtR2V0SW50MzIoRnVuY3Rpb25DYWxsSW52 b2tlKGxvY2ZjaW5mbykpOworfQorCitzdGF0aWMgTGlzdCAqCitzYW9wX2RlbGV0ZV9kdXBs aWNhdGVzKFBhcnNlU3RhdGUgKnBzdGF0ZSwgT3JDbGF1c2VHcm91cEVudHJ5ICplbnRyeSwK KwkJCQkJICAgT2lkIHNjYWxhcl90eXBlKQoreworCUxpc3RDZWxsICAgKmxjOworCUxpc3QJ ICAgKnJlc3VsdDsKKworCWxvY2ZjaW5mbyA9IGVudHJ5LT5mY2luZm87CisJbGlzdF9zb3J0 KGVudHJ5LT5jb25zdHMsIHNhb3BfY29uc3RfY29tcGFyYXRvcik7CisKKwlyZXN1bHQgPSBs aXN0X21ha2UxKGxpbml0aWFsKGVudHJ5LT5jb25zdHMpKTsKKwlmb3JfZWFjaF9mcm9tKGxj LCBlbnRyeS0+Y29uc3RzLCAxKQorCXsKKwkJTm9kZSAqbm9kZSA9IChOb2RlICopIGxmaXJz dChsYyk7CisKKwkJaWYgKGVxdWFsKGxsYXN0KHJlc3VsdCksIG5vZGUpKQorCQkJY29udGlu dWU7CisKKwkJbm9kZSA9IGNvZXJjZV90b19jb21tb25fdHlwZShwc3RhdGUsIG5vZGUsIHNj YWxhcl90eXBlLCAiSU4iKTsKKwkJcmVzdWx0ID0gbGFwcGVuZChyZXN1bHQsIG5vZGUpOwor CX0KKworCXJldHVybiByZXN1bHQ7Cit9CisKKy8qCisgKiBUcmFuc2Zvcm1PckV4cHJUb0FO WSAtCisgKgkgIERpc2NvdmVyIHRoZSBhcmdzIG9mIGFuIE9SIGV4cHJlc3Npb24gYW5kIHRy eSB0byBncm91cCBzaW1pbGFyIE9SCisgKgkgIGV4cHJlc3Npb25zIHRvIGFuIEFOWSBvcGVy YXRpb24uCisgKgkgIFRyYW5zZm9ybWF0aW9uIG11c3QgYmUgYWxyZWFkeSBkb25lIG9uIGlu cHV0IGFyZ3MgbGlzdCBiZWZvcmUgdGhlIGNhbGwuCisgKgkgIFRyYW5zZm9ybWF0aW9uIGdy b3VwcyB0d28tc2lkZWQgZXF1YWxpdHkgb3BlcmF0aW9ucy4gT25lIHNpZGUgb2Ygc3VjaCBh bgorICoJICBvcGVyYXRpb24gbXVzdCBiZSBwbGFpbiBjb25zdGFudCBvciBjb25zdGFudCBl eHByZXNzaW9uLiBUaGUgb3RoZXIgc2lkZSBvZgorICoJICB0aGUgY2xhdXNlIG11c3QgYmUg YSB2YXJpYWJsZSBleHByZXNzaW9uIHdpdGhvdXQgdm9sYXRpbGUgZnVuY3Rpb25zLgorICoJ ICBUaGUgZ3JvdXBpbmcgdGVjaG5pcXVlIGlzIGJhc2VkIG9uIGFuIGVxdWl2YWxlbmNlIG9m IHZhcmlhYmxlIHNpZGVzIG9mIHRoZQorICoJICBleHByZXNzaW9uOiB1c2luZyBxdWVyeUlk IGFuZCBlcXVhbCgpIHJvdXRpbmUsIGl0IGdyb3VwcyBjb25zdGFudCBzaWRlcyBvZgorICoJ ICBzaW1pbGFyIGNsYXVzZXMgaW50byBhbiBhcnJheS4gQWZ0ZXIgdGhlIGdyb3VwaW5nIHBy b2NlZHVyZSwgZWFjaCBjb3VwbGUKKyAqCSAgKCd2YXJpYWJsZSBleHByZXNzaW9uJyBhbmQg J2NvbnN0YW50IGFycmF5JykgZm9ybSBhIG5ldyBTQU9QIG9wZXJhdGlvbiwKKyAqCSAgd2hp Y2ggaXMgYWRkZWQgdG8gdGhlIGFyZ3MgbGlzdCBvZiB0aGUgcmV0dXJuaW5nIGV4cHJlc3Np b24uCisgKgorICoJICBOT1RFOiBmdW5jdGlvbiByZXR1cm5zIE9SIEJvb2xFeHByIGlmIG1v cmUgdGhhbiBvbmUgY2xhdXNlIGFyZSBkZXRlY3RlZCBpbgorICoJICB0aGUgZmluYWwgYXJn cyBsaXN0LCBvciBTY2FsYXJBcnJheU9wRXhwciBpZiBhbGwgYXJncyB3ZXJlIGdyb3VwZWQg aW50bworICoJICB0aGUgc2luZ2xlIFNBT1AgZXhwcmVzc2lvbi4KKyAqLworc3RhdGljIE5v ZGUgKgorVHJhbnNmb3JtT3JFeHByVG9BTlkoUGFyc2VTdGF0ZSAqcHN0YXRlLCBMaXN0ICph cmdzLCBpbnQgbG9jYXRpb24pCit7CisJTGlzdAkJCQkgICAqb3JfbGlzdCA9IE5JTDsKKwlM aXN0CQkJCSAgICpncm91cHMgPSBOSUw7CisJTGlzdCAJCQkJICAgKnVuY29udmluaWVudF9v cnMgPSBOSUw7CisJTGlzdENlbGwJCQkgICAqbGM7CisJSEFTSENUTAkJCQkJaW5mbzsKKwlI VEFCIAkJCQkgICAqb3JfZ3JvdXBfaHRhYiA9IE5VTEw7CisJaW50IAkJCQkJbGVuX29ycyA9 IGxpc3RfbGVuZ3RoKGFyZ3MpOworCU9yQ2xhdXNlR3JvdXBFbnRyeQkgICAqZW50cnkgPSBO VUxMOworCisJQXNzZXJ0KGVuYWJsZV9vcl90cmFuc2Zvcm1hdGlvbiAmJiBsZW5fb3JzID4g MSk7CisKKwlNZW1TZXQoJmluZm8sIDAsIHNpemVvZihpbmZvKSk7CisJaW5mby5rZXlzaXpl ID0gc2l6ZW9mKE9yQ2xhdXNlR3JvdXBLZXkpOworCWluZm8uZW50cnlzaXplID0gc2l6ZW9m KE9yQ2xhdXNlR3JvdXBFbnRyeSk7CisJaW5mby5oYXNoID0gb3JjbGF1c2VfaGFzaDsKKwlp bmZvLmtleWNvcHkgPSBvcmNsYXVzZV9rZXljb3B5OworCWluZm8ubWF0Y2ggPSBvcmNsYXVz ZV9tYXRjaDsKKwlvcl9ncm91cF9odGFiID0gaGFzaF9jcmVhdGUoIk9SIEdyb3VwcyIsCisJ CQkJCQkJCWxlbl9vcnMsCisJCQkJCQkJCSZpbmZvLAorCQkJCQkJCQlIQVNIX0VMRU0gfCBI QVNIX0ZVTkNUSU9OIHwgSEFTSF9DT01QQVJFIHwgSEFTSF9LRVlDT1BZKTsKKworCWZvcmVh Y2gobGMsIGFyZ3MpCisJeworCQlOb2RlCQkJCSAgICpvcnF1YWwgPSBsZmlyc3QobGMpOwor CQlOb2RlCQkJCSAgICpjb25zdF9leHByOworCQlOb2RlCQkJCSAgICpuY29uc3RfZXhwcjsK KwkJT3JDbGF1c2VHcm91cEtleQkJaGFzaGtleTsKKwkJYm9vbAkJCQkJZm91bmQ7CisJCU9p ZAkJCQkJCW9wbm87CisJCU9pZAkJCQkJCWV4cHJ0eXBlOworCQlOb2RlCQkJCSAgICpsZWZ0 b3AsICpyaWdodG9wOworCQlUeXBlQ2FjaGVFbnRyeQkJICAgKnR5cGVudHJ5OworCisJCWlm ICghSXNBKG9ycXVhbCwgT3BFeHByKSkKKwkJeworCQkJdW5jb252aW5pZW50X29ycyA9IGxh cHBlbmQodW5jb252aW5pZW50X29ycywgb3JxdWFsKTsKKwkJCWNvbnRpbnVlOworCQl9CisK KwkJb3BubyA9ICgoT3BFeHByICopIG9ycXVhbCktPm9wbm87CisJCWlmIChnZXRfb3BfcmV0 dHlwZShvcG5vKSAhPSBCT09MT0lEKQorCQl7CisJCQkvKiBPbmx5IG9wZXJhdG9yIHJldHVy bmluZyBib29sZWFuIHN1aXRzIE9SIC0+IEFOWSB0cmFuc2Zvcm1hdGlvbiAqLworCQkJdW5j b252aW5pZW50X29ycyA9IGxhcHBlbmQodW5jb252aW5pZW50X29ycywgb3JxdWFsKTsKKwkJ CWNvbnRpbnVlOworCQl9CisKKwkJLyoKKwkJICogRGV0ZWN0IHRoZSBjb25zdGFudCBzaWRl IG9mIHRoZSBjbGF1c2UuIFJlY2FsbCBub24tY29uc3RhbnQKKwkJICogZXhwcmVzc2lvbiBj YW4gYmUgbWFkZSBub3Qgb25seSB3aXRoIFZhcnMsIGJ1dCBhbHNvIHdpdGggUGFyYW1zLAor CQkgKiB3aGljaCBpcyBub3QgYm9uZGVkIHdpdGggYW55IHJlbGF0aW9uLiBUaHVzLCB3ZSBk ZXRlY3QgdGhlIGNvbnN0CisJCSAqIHNpZGUgLSBpZiBhbm90aGVyIHNpZGUgaXMgY29uc3Rh bnQgdG9vLCB0aGUgb3JxdWFsIGNvdWxkbid0IGJlCisJCSAqIGFuIE9wRXhwci4KKwkJICog R2V0IHBvaW50ZXJzIHRvIGNvbnN0YW50IGFuZCBleHByZXNzaW9uIHNpZGVzIG9mIHRoZSBx dWFsLgorCQkgKi8KKwkJbGVmdG9wID0gZ2V0X2xlZnRvcChvcnF1YWwpOworCQlpZiAoSXNB KGxlZnRvcCwgUmVsYWJlbFR5cGUpKQorCQkJbGVmdG9wID0gKE5vZGUgKikgKChSZWxhYmVs VHlwZSAqKSBsZWZ0b3ApLT5hcmc7CisJCXJpZ2h0b3AgPSBnZXRfcmlnaHRvcChvcnF1YWwp OworCQlpZiAoSXNBKHJpZ2h0b3AsIFJlbGFiZWxUeXBlKSkKKwkJCXJpZ2h0b3AgPSAoTm9k ZSAqKSAoKFJlbGFiZWxUeXBlICopIHJpZ2h0b3ApLT5hcmc7CisKKwkJaWYgKElzQShsZWZ0 b3AsIENvbnN0KSkKKwkJeworCQkJb3BubyA9IGdldF9jb21tdXRhdG9yKG9wbm8pOworCisJ CQlpZiAoIU9pZElzVmFsaWQob3BubykpCisJCQl7CisJCQkJLyogY29tbXV0YXRvciBkb2Vz bid0IGV4aXN0LCB3ZSBjYW4ndCByZXZlcnNlIHRoZSBvcmRlciAqLworCQkJCXVuY29udmlu aWVudF9vcnMgPSBsYXBwZW5kKHVuY29udmluaWVudF9vcnMsIG9ycXVhbCk7CisJCQkJY29u dGludWU7CisJCQl9CisKKwkJCW5jb25zdF9leHByID0gZ2V0X3JpZ2h0b3Aob3JxdWFsKTsK KwkJCWNvbnN0X2V4cHIgPSBnZXRfbGVmdG9wKG9ycXVhbCk7CisJCX0KKwkJZWxzZSBpZiAo SXNBKHJpZ2h0b3AsIENvbnN0KSkKKwkJeworCQkJY29uc3RfZXhwciA9IGdldF9yaWdodG9w KG9ycXVhbCk7CisJCQluY29uc3RfZXhwciA9IGdldF9sZWZ0b3Aob3JxdWFsKTsKKwkJfQor CQllbHNlCisJCXsKKwkJCXVuY29udmluaWVudF9vcnMgPSBsYXBwZW5kKHVuY29udmluaWVu dF9vcnMsIG9ycXVhbCk7CisJCQljb250aW51ZTsKKwkJfQorCisJCS8qCisJCSAqIFRyYW5z Zm9ybWF0aW9uIG9ubHkgd29ya3Mgd2l0aCBib3RoIHNpZGUgdHlwZSBpcyBub3QKKwkJICog eyBhcnJheSB8IGNvbXBvc2l0ZSB8IGRvbWFpbiB8IHJlY29yZCB9LgorCQkgKiBBbHNvLCBm b3JiaWQgaXQgZm9yIHZvbGF0aWxlIGV4cHJlc3Npb25zLgorCQkgKi8KKwkJZXhwcnR5cGUg PSBleHByVHlwZShuY29uc3RfZXhwcik7CisJCWlmICh0eXBlX2lzX3Jvd3R5cGUoZXhwclR5 cGUoY29uc3RfZXhwcikpIHx8CisJCQl0eXBlX2lzX3Jvd3R5cGUoZXhwcnR5cGUpIHx8CisJ CQljb250YWluX3ZvbGF0aWxlX2Z1bmN0aW9ucygoTm9kZSAqKSBuY29uc3RfZXhwcikpCisJ CXsKKwkJCXVuY29udmluaWVudF9vcnMgPSBsYXBwZW5kKHVuY29udmluaWVudF9vcnMsIG9y cXVhbCk7CisJCQljb250aW51ZTsKKwkJfQorCisJCXR5cGVudHJ5ID0gbG9va3VwX3R5cGVf Y2FjaGUoZXhwcnR5cGUsIFRZUEVDQUNIRV9DTVBfUFJPQ19GSU5GTyk7CisKKwkJLyoKKwkJ ICogV2l0aGluIHRoaXMgdHJhbnNmb3JtYXRpb24gd2UgcmVtb3ZlIGR1cGxpY2F0ZXMuIFRv IGF2b2lkCisJCSAqIHF1YWRyYXRpYyBiZWhhdmlvciB3ZSBuZWVkIHRvIHNvcnQgY2xhdXNl cyBhZnRlciBtYWtpbmcgYSBsaXN0IG9mCisJCSAqIGVsZW1lbnRzLiBTbywgbmVlZCBzb3J0 IG9wZXJhdG9yIHRvIGltcGxlbWVudCB0aGF0LgorCQkgKi8KKwkJaWYgKCFPaWRJc1ZhbGlk KHR5cGVudHJ5LT5jbXBfcHJvY19maW5mby5mbl9vaWQpKQorCQl7CisJCQl1bmNvbnZpbmll bnRfb3JzID0gbGFwcGVuZCh1bmNvbnZpbmllbnRfb3JzLCBvcnF1YWwpOworCQkJY29udGlu dWU7CisJCX0KKworCQkvKgorCQkqIEF0IHRoaXMgcG9pbnQgd2UgZGVmaW5pdGVseSBoYXZl IGEgdHJhbnNmb3JtYWJsZSBjbGF1c2UuCisJCSogQ2xhc3NpZnkgaXQgYW5kIGFkZCBpbnRv IHNwZWNpZmljIGdyb3VwIG9mIGNsYXVzZXMsIG9yIGNyZWF0ZSBuZXcKKwkJKiBncm91cC4K KwkJKi8KKwkJaGFzaGtleS50eXBlID0gVF9JbnZhbGlkOworCQloYXNoa2V5LmV4cHIgPSAo RXhwciAqKSBuY29uc3RfZXhwcjsKKwkJaGFzaGtleS5vcG5vID0gb3BubzsKKwkJaGFzaGtl eS5leHBydHlwZSA9IGV4cHJ0eXBlOworCQllbnRyeSA9IGhhc2hfc2VhcmNoKG9yX2dyb3Vw X2h0YWIsICZoYXNoa2V5LCBIQVNIX0VOVEVSLCAmZm91bmQpOworCisJCWlmICh1bmxpa2Vs eShmb3VuZCkpCisJCXsKKwkJCWVudHJ5LT5jb25zdHMgPSBsYXBwZW5kKGVudHJ5LT5jb25z dHMsIGNvbnN0X2V4cHIpOworCQkJZW50cnktPmV4cHJzID0gbGFwcGVuZChlbnRyeS0+ZXhw cnMsIG9ycXVhbCk7CisJCX0KKwkJZWxzZQorCQl7CisJCQllbnRyeS0+Y29uc3RzID0gbGlz dF9tYWtlMShjb25zdF9leHByKTsKKwkJCWVudHJ5LT5leHBycyA9IGxpc3RfbWFrZTEob3Jx dWFsKTsKKworCQkJLyogUHJlcGFyZSBmdW5jYWxsIGZvciBzb3J0IGNvbXBhcmF0b3IgKi8K KwkJCWVudHJ5LT5mY2luZm8gPQorCQkJCQkJKEZ1bmN0aW9uQ2FsbEluZm8pIHBhbGxvYyhT aXplRm9yRnVuY3Rpb25DYWxsSW5mbygyKSk7CisJCQlJbml0RnVuY3Rpb25DYWxsSW5mb0Rh dGEoKihlbnRyeS0+ZmNpbmZvKSwKKwkJCQkJCQkJCSAmdHlwZW50cnktPmNtcF9wcm9jX2Zp bmZvLCAyLAorCQkJCQkJCQkJIHR5cGVudHJ5LT50eXBjb2xsYXRpb24sIE5VTEwsIE5VTEwp OworCisJCQkvKgorCQkJICogQWRkIHRoZSBlbnRyeSB0byB0aGUgbGlzdC4gSXQgaXMgbmVl ZGVkIGV4Y2x1c2l2ZWx5IHRvIG1hbmFnZSB0aGUKKwkJCSAqIHByb2JsZW0gd2l0aCB0aGUg b3JkZXIgb2YgdHJhbnNmb3JtZWQgY2xhdXNlcyBpbiBleHBsYWluLgorCQkJICogSGFzaCB2 YWx1ZSBjYW4gZGVwZW5kIG9uIHRoZSBwbGF0Zm9ybSBhbmQgdmVyc2lvbi4gSGVuY2UsCisJ CQkgKiBzZXF1ZW50YWwgc2NhbiBvZiB0aGUgaGFzaCB0YWJsZSB3b3VsZCBwcm9uZSB0byBj aGFuZ2UgdGhlIG9yZGVyCisJCQkgKiBvZiBjbGF1c2VzIGluIGxpc3RzIGFuZCwgYXMgYSBy ZXN1bHQsIGJyZWFrIHJlZ3Jlc3Npb24gdGVzdHMKKwkJCSAqIGFjY2lkZW50aWFsbHkuCisJ CQkgKi8KKwkJCWdyb3VwcyA9IGxhcHBlbmQoZ3JvdXBzLCBlbnRyeSk7CisJCX0KKwl9CisK KwkvKiBMZXQncyBjb252ZXJ0IGVhY2ggZ3JvdXAgb2YgY2xhdXNlcyB0byBhbiBJTiBvcGVy YXRpb24uICovCisKKwkvKgorCSAqIEdvIHRocm91Z2ggdGhlIGxpc3Qgb2YgZ3JvdXBzIGFu ZCBjb252ZXJ0IGVhY2gsIHdoZXJlIG51bWJlciBvZgorCSAqIGNvbnN0cyBtb3JlIHRoYW4g MS4gdHJpdmlhbCBncm91cHMgbW92ZSB0byBPUi1saXN0IGFnYWluCisJICovCisJZm9yZWFj aCAobGMsIGdyb3VwcykKKwl7CisJCU9pZAkJCQkgICAgc2NhbGFyX3R5cGU7CisJCU9pZAkJ CQkJYXJyYXlfdHlwZTsKKworCQlpZiAoIUlzQShsZmlyc3QobGMpLCBJbnZhbGlkKSkKKwkJ eworCQkJdW5jb252aW5pZW50X29ycyA9IGxhcHBlbmQodW5jb252aW5pZW50X29ycywgbGZp cnN0KGxjKSk7CisJCQljb250aW51ZTsKKwkJfQorCisJCWVudHJ5ID0gKE9yQ2xhdXNlR3Jv dXBFbnRyeSAqKSBsZmlyc3QobGMpOworCisJCUFzc2VydChsaXN0X2xlbmd0aChlbnRyeS0+ Y29uc3RzKSA+IDApOworCQlBc3NlcnQobGlzdF9sZW5ndGgoZW50cnktPmV4cHJzKSA9PSBs aXN0X2xlbmd0aChlbnRyeS0+Y29uc3RzKSk7CisKKwkJaWYgKGxpc3RfbGVuZ3RoKGVudHJ5 LT5jb25zdHMpID09IDEpCisJCXsKKwkJCS8qCisJCQkgKiBPbmx5IG9uZSBlbGVtZW50IHJl dHVybnMgb3JpZ2luIGV4cHJlc3Npb24gaW50byB0aGUgQm9vbEV4cHIgYXJncworCQkJICog bGlzdCB1bmNoYW5nZWQuCisJCQkgKi8KKwkJCWxpc3RfZnJlZShlbnRyeS0+Y29uc3RzKTsK KwkJCXVuY29udmluaWVudF9vcnMgPSBsaXN0X2NvbmNhdCh1bmNvbnZpbmllbnRfb3JzLCBl bnRyeS0+ZXhwcnMpOworCQkJY29udGludWU7CisJCX0KKworCQkvKgorCQkgKiBEbyB0aGUg dHJhbnNmb3JtYXRpb24uCisJCSAqLworCisJCXNjYWxhcl90eXBlID0gZW50cnktPmtleS5l eHBydHlwZTsKKwkJYXJyYXlfdHlwZSA9IE9pZElzVmFsaWQoc2NhbGFyX3R5cGUpID8gZ2V0 X2FycmF5X3R5cGUoc2NhbGFyX3R5cGUpIDoKKwkJCQkJCQkJCQkJICAgSW52YWxpZE9pZDsK KworCQlpZiAoT2lkSXNWYWxpZChhcnJheV90eXBlKSkKKwkJeworCQkJLyoKKwkJCSAqIE9L OiBjb2VyY2UgYWxsIHRoZSByaWdodC1oYW5kIG5vbi1WYXIgaW5wdXRzIHRvIHRoZSBjb21t b24KKwkJCSAqIHR5cGUgYW5kIGJ1aWxkIGFuIEFycmF5RXhwciBmb3IgdGhlbS4KKwkJCSAq LworCQkJTGlzdAkJCSAgICphZXhwcnMgPSBOSUw7CisJCQlBcnJheUV4cHIJCSAgICpuZXdh ID0gTlVMTDsKKwkJCVNjYWxhckFycmF5T3BFeHByICAqc2FvcGV4cHIgPSBOVUxMOworCQkJ SGVhcFR1cGxlCQkJb3BlcnR1cDsKKwkJCUZvcm1fcGdfb3BlcmF0b3IJb3BlcmZvcm07CisJ CQlMaXN0CQkJICAgKm5hbWVsaXN0ID0gTklMOworCisJCQlhZXhwcnMgPSBzYW9wX2RlbGV0 ZV9kdXBsaWNhdGVzKHBzdGF0ZSwgZW50cnksIHNjYWxhcl90eXBlKTsKKworCQkJbmV3YSA9 IG1ha2VOb2RlKEFycmF5RXhwcik7CisJCQkvKiBhcnJheV9jb2xsaWQgd2lsbCBiZSBzZXQg YnkgcGFyc2VfY29sbGF0ZS5jICovCisJCQluZXdhLT5lbGVtZW50X3R5cGVpZCA9IHNjYWxh cl90eXBlOworCQkJbmV3YS0+YXJyYXlfdHlwZWlkID0gYXJyYXlfdHlwZTsKKwkJCW5ld2Et Pm11bHRpZGltcyA9IGZhbHNlOworCQkJbmV3YS0+ZWxlbWVudHMgPSBhZXhwcnM7CisJCQlu ZXdhLT5sb2NhdGlvbiA9IC0xOworCisJCQlvcGVydHVwID0gU2VhcmNoU3lzQ2FjaGUxKE9Q RVJPSUQsCisJCQkJCQkJCQkgIE9iamVjdElkR2V0RGF0dW0oZW50cnktPmtleS5vcG5vKSk7 CisJCQlpZiAoIUhlYXBUdXBsZUlzVmFsaWQob3BlcnR1cCkpCisJCQkJZWxvZyhFUlJPUiwg ImNhY2hlIGxvb2t1cCBmYWlsZWQgZm9yIG9wZXJhdG9yICV1IiwKKwkJCQkJIGVudHJ5LT5r ZXkub3Bubyk7CisKKwkJCW9wZXJmb3JtID0gKEZvcm1fcGdfb3BlcmF0b3IpIEdFVFNUUlVD VChvcGVydHVwKTsKKwkJCWlmICghT3BlcmF0b3JJc1Zpc2libGUoZW50cnktPmtleS5vcG5v KSkKKwkJCQluYW1lbGlzdCA9IGxhcHBlbmQobmFtZWxpc3QsIG1ha2VTdHJpbmcoZ2V0X25h bWVzcGFjZV9uYW1lKG9wZXJmb3JtLT5vcHJuYW1lc3BhY2UpKSk7CisKKwkJCW5hbWVsaXN0 ID0gbGFwcGVuZChuYW1lbGlzdCwgbWFrZVN0cmluZyhwc3RyZHVwKE5hbWVTdHIob3BlcmZv cm0tPm9wcm5hbWUpKSkpOworCQkJUmVsZWFzZVN5c0NhY2hlKG9wZXJ0dXApOworCisJCQlz YW9wZXhwciA9CisJCQkJKFNjYWxhckFycmF5T3BFeHByICopCisJCQkJCW1ha2Vfc2NhbGFy X2FycmF5X29wKHBzdGF0ZSwKKwkJCQkJCQkJCQkgbmFtZWxpc3QsCisJCQkJCQkJCQkJIHRy dWUsCisJCQkJCQkJCQkJIChOb2RlICopIGVudHJ5LT5rZXkuZXhwciwKKwkJCQkJCQkJCQkg KE5vZGUgKikgbmV3YSwKKwkJCQkJCQkJCQkgLTEpOworCisJCQlvcl9saXN0ID0gbGFwcGVu ZChvcl9saXN0LCBtYWtlQm9vbEV4cHIoQU5EX0VYUFIsIGxpc3RfbWFrZTIobWFrZUJvb2xF eHByKE9SX0VYUFIsIGVudHJ5LT5leHBycywgbG9jYXRpb24pLCBzYW9wZXhwciksIC0xKSk7 CisJCX0KKwkJZWxzZQorCQl7CisJCQkvKgorCQkJICogSWYgdGhlIGNvbnN0IG5vZGUgKHJp Z2h0IHNpZGUgb2Ygb3BlcmF0b3IgZXhwcmVzc2lvbikgJ3MgdHlwZQorCQkJICogIGRvbid0 IGhhdmUg4oCcdHJ1ZeKAnSBhcnJheSB0eXBlLCB0aGVuIHdlIGNhbm5ub3QgZG8gdGhlIHRy YW5zZm9ybWF0aW9uLgorCQkJICogV2Ugc2ltcGx5IGNvbmNhdGVuYXRlIHRoZSBleHByZXNz aW9uIG5vZGUuCisJCQkgKgorCQkJICovCisJCQlsaXN0X2ZyZWUoZW50cnktPmNvbnN0cyk7 CisJCQl1bmNvbnZpbmllbnRfb3JzID0gbGlzdF9jb25jYXQodW5jb252aW5pZW50X29ycywg ZW50cnktPmV4cHJzKTsKKwkJfQorCX0KKwlpZih1bmNvbnZpbmllbnRfb3JzICE9IE5JTCkK KwkJb3JfbGlzdCA9IGxhcHBlbmQob3JfbGlzdCwgbGlzdF9sZW5ndGgodW5jb252aW5pZW50 X29ycykgPiAxID8gbWFrZUJvb2xFeHByKE9SX0VYUFIsIHVuY29udmluaWVudF9vcnMsIGxv Y2F0aW9uKSA6IGxpbml0aWFsKHVuY29udmluaWVudF9vcnMpKTsKKwloYXNoX2Rlc3Ryb3ko b3JfZ3JvdXBfaHRhYik7CisJbGlzdF9mcmVlKGdyb3Vwcyk7CisKKwkvKiBPbmUgbW9yZSB0 cmljazogYXNzZW1ibGUgY29ycmVjdCBjbGF1c2UgKi8KKwlyZXR1cm4gKE5vZGUgKikgKChs aXN0X2xlbmd0aChvcl9saXN0KSA+IDEpID8KKwkJCQkJIG1ha2VCb29sRXhwcihPUl9FWFBS LCBvcl9saXN0LCBsb2NhdGlvbikgOgorCQkJCQkgbGluaXRpYWwob3JfbGlzdCkpOworfQog CiAvKgogICogdHJhbnNmb3JtRXhwciAtCkBAIC0xNDMyLDYgKzE4NDcsMTEgQEAgdHJhbnNm b3JtQm9vbEV4cHIoUGFyc2VTdGF0ZSAqcHN0YXRlLCBCb29sRXhwciAqYSkKIAkJYXJncyA9 IGxhcHBlbmQoYXJncywgYXJnKTsKIAl9CiAKKwkvKiBNYWtlIGFuIGF0dGVtcHQgdG8gZ3Jv dXAgc2ltaWxhciBPUiBjbGF1c2VzIGludG8gQU5ZIG9wZXJhdGlvbiAqLworCWlmIChlbmFi bGVfb3JfdHJhbnNmb3JtYXRpb24gJiYgYS0+Ym9vbG9wID09IE9SX0VYUFIgJiYKKwkJbGlz dF9sZW5ndGgoYXJncykgPjApCisJCXJldHVybiBUcmFuc2Zvcm1PckV4cHJUb0FOWShwc3Rh dGUsIGFyZ3MsIGEtPmxvY2F0aW9uKTsKKwogCXJldHVybiAoTm9kZSAqKSBtYWtlQm9vbEV4 cHIoYS0+Ym9vbG9wLCBhcmdzLCBhLT5sb2NhdGlvbik7CiB9CiAKZGlmZiAtLWdpdCBhL3Ny Yy9iYWNrZW5kL3V0aWxzL21pc2MvZ3VjX3RhYmxlcy5jIGIvc3JjL2JhY2tlbmQvdXRpbHMv bWlzYy9ndWNfdGFibGVzLmMKaW5kZXggNDZjMjU4YmUyODIuLmY1ZGEwOTdmY2RmIDEwMDY0 NAotLS0gYS9zcmMvYmFja2VuZC91dGlscy9taXNjL2d1Y190YWJsZXMuYworKysgYi9zcmMv YmFja2VuZC91dGlscy9taXNjL2d1Y190YWJsZXMuYwpAQCAtMTAwNyw2ICsxMDA3LDE3IEBA IHN0cnVjdCBjb25maWdfYm9vbCBDb25maWd1cmVOYW1lc0Jvb2xbXSA9CiAJCXRydWUsCiAJ CU5VTEwsIE5VTEwsIE5VTEwKIAl9LAorCXsKKwkJeyJlbmFibGVfb3JfdHJhbnNmb3JtYXRp b24iLCBQR0NfVVNFUlNFVCwgUVVFUllfVFVOSU5HX09USEVSLAorCQkJZ2V0dGV4dF9ub29w KCJUcmFuc2Zvcm0gYSBzZXF1ZW5jZSBvZiBPUiBjbGF1c2VzIHRvIGFuIGFycmF5IGV4cHJl c3Npb24uIiksCisJCQlnZXR0ZXh0X25vb3AoIlRoZSBwbGFubmVyIHdpbGwgcmVwbGFjZSBl eHByZXNzaW9uIGxpa2UgJ3g9YzEgT1IgeD1jMiAuLiciCisJCQkJCQkgInRvIHRoZSBleHBy ZXNzaW9uICd4ID0gQU5ZKEFSUkFZW2MxLGMyLC4uXSknIiksCisJCQlHVUNfRVhQTEFJTgor CQl9LAorCQkmZW5hYmxlX29yX3RyYW5zZm9ybWF0aW9uLAorCQl0cnVlLAorCQlOVUxMLCBO VUxMLCBOVUxMCisJfSwKIAl7CiAJCS8qCiAJCSAqIE5vdCBmb3IgZ2VuZXJhbCB1c2UgLS0t IHVzZWQgYnkgU0VUIFNFU1NJT04gQVVUSE9SSVpBVElPTiBhbmQgU0VUCmRpZmYgLS1naXQg YS9zcmMvaW5jbHVkZS9ub2Rlcy9xdWVyeWp1bWJsZS5oIGIvc3JjL2luY2x1ZGUvbm9kZXMv cXVlcnlqdW1ibGUuaAppbmRleCBmMWM1NWM4MDY3Zi4uYTlhZTA0OGFmNTIgMTAwNjQ0Ci0t LSBhL3NyYy9pbmNsdWRlL25vZGVzL3F1ZXJ5anVtYmxlLmgKKysrIGIvc3JjL2luY2x1ZGUv bm9kZXMvcXVlcnlqdW1ibGUuaApAQCAtNjUsNiArNjUsNyBAQCBleHRlcm4gUEdETExJTVBP UlQgaW50IGNvbXB1dGVfcXVlcnlfaWQ7CiAKIGV4dGVybiBjb25zdCBjaGFyICpDbGVhblF1 ZXJ5dGV4dChjb25zdCBjaGFyICpxdWVyeSwgaW50ICpsb2NhdGlvbiwgaW50ICpsZW4pOwog ZXh0ZXJuIEp1bWJsZVN0YXRlICpKdW1ibGVRdWVyeShRdWVyeSAqcXVlcnkpOworZXh0ZXJu IEp1bWJsZVN0YXRlICpKdW1ibGVFeHByKEV4cHIgKmV4cHIsIHVpbnQ2NCAqcXVlcnlJZCk7 CiBleHRlcm4gdm9pZCBFbmFibGVRdWVyeUlkKHZvaWQpOwogCiBleHRlcm4gUEdETExJTVBP UlQgYm9vbCBxdWVyeV9pZF9lbmFibGVkOwpkaWZmIC0tZ2l0IGEvc3JjL2luY2x1ZGUvb3B0 aW1pemVyL29wdGltaXplci5oIGIvc3JjL2luY2x1ZGUvb3B0aW1pemVyL29wdGltaXplci5o CmluZGV4IDdiNjNjNWNmNzE4Li4zNWFiNTc3NTAxOSAxMDA2NDQKLS0tIGEvc3JjL2luY2x1 ZGUvb3B0aW1pemVyL29wdGltaXplci5oCisrKyBiL3NyYy9pbmNsdWRlL29wdGltaXplci9v cHRpbWl6ZXIuaApAQCAtNTAsNiArNTAsNyBAQCBzdHJ1Y3QgUGxhbm5lZFN0bXQ7CiBzdHJ1 Y3QgUGFyYW1MaXN0SW5mb0RhdGE7CiBzdHJ1Y3QgSGVhcFR1cGxlRGF0YTsKIAorZXh0ZXJu IFBHRExMSU1QT1JUIGJvb2wgZW5hYmxlX29yX3RyYW5zZm9ybWF0aW9uOwogCiAvKiBpbiBw YXRoL2NsYXVzZXNlbC5jOiAqLwogCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZWdyZXNzL2V4 cGVjdGVkL2pvaW4ub3V0IGIvc3JjL3Rlc3QvcmVncmVzcy9leHBlY3RlZC9qb2luLm91dApp bmRleCA2YjE2YzNhNjc2OS4uY2NmMjgwMDAxYTAgMTAwNjQ0Ci0tLSBhL3NyYy90ZXN0L3Jl Z3Jlc3MvZXhwZWN0ZWQvam9pbi5vdXQKKysrIGIvc3JjL3Rlc3QvcmVncmVzcy9leHBlY3Rl ZC9qb2luLm91dApAQCAtNDIxMCwxMCArNDIxMCwxMCBAQCBleHBsYWluIChjb3N0cyBvZmYp CiBzZWxlY3QgKiBmcm9tIHRlbmsxIGEgam9pbiB0ZW5rMSBiIG9uCiAgIChhLnVuaXF1ZTEg PSAxIGFuZCBiLnVuaXF1ZTEgPSAyKSBvcgogICAoKGEudW5pcXVlMiA9IDMgb3IgYS51bmlx dWUyID0gNykgYW5kIGIuaHVuZHJlZCA9IDQpOwotICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUVVFUlkgUExBTiAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAotLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQor ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IFFVRVJZIFBMQU4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICBOZXN0ZWQgTG9vcAotICAgSm9pbiBGaWx0 ZXI6ICgoKGEudW5pcXVlMSA9IDEpIEFORCAoYi51bmlxdWUxID0gMikpIE9SICgoKGEudW5p cXVlMiA9IDMpIE9SIChhLnVuaXF1ZTIgPSA3KSkgQU5EIChiLmh1bmRyZWQgPSA0KSkpCisg ICBKb2luIEZpbHRlcjogKCgoYS51bmlxdWUxID0gMSkgQU5EIChiLnVuaXF1ZTEgPSAyKSkg T1IgKChhLnVuaXF1ZTIgPSBBTlkgKCd7Myw3fSc6OmludGVnZXJbXSkpIEFORCAoYi5odW5k cmVkID0gNCkpKQogICAgLT4gIEJpdG1hcCBIZWFwIFNjYW4gb24gdGVuazEgYgogICAgICAg ICAgUmVjaGVjayBDb25kOiAoKHVuaXF1ZTEgPSAyKSBPUiAoaHVuZHJlZCA9IDQpKQogICAg ICAgICAgLT4gIEJpdG1hcE9yCkBAIC00MjIzLDE2ICs0MjIzLDY0IEBAIHNlbGVjdCAqIGZy b20gdGVuazEgYSBqb2luIHRlbmsxIGIgb24KICAgICAgICAgICAgICAgICAgICAgIEluZGV4 IENvbmQ6IChodW5kcmVkID0gNCkKICAgIC0+ICBNYXRlcmlhbGl6ZQogICAgICAgICAgLT4g IEJpdG1hcCBIZWFwIFNjYW4gb24gdGVuazEgYQotICAgICAgICAgICAgICAgUmVjaGVjayBD b25kOiAoKHVuaXF1ZTEgPSAxKSBPUiAodW5pcXVlMiA9IDMpIE9SICh1bmlxdWUyID0gNykp CisgICAgICAgICAgICAgICBSZWNoZWNrIENvbmQ6ICgodW5pcXVlMSA9IDEpIE9SICh1bmlx dWUyID0gQU5ZICgnezMsN30nOjppbnRlZ2VyW10pKSkKICAgICAgICAgICAgICAgIC0+ICBC aXRtYXBPcgogICAgICAgICAgICAgICAgICAgICAgLT4gIEJpdG1hcCBJbmRleCBTY2FuIG9u IHRlbmsxX3VuaXF1ZTEKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZGV4IENvbmQ6 ICh1bmlxdWUxID0gMSkKICAgICAgICAgICAgICAgICAgICAgIC0+ICBCaXRtYXAgSW5kZXgg U2NhbiBvbiB0ZW5rMV91bmlxdWUyCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBJbmRl eCBDb25kOiAodW5pcXVlMiA9IDMpCisgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmRl eCBDb25kOiAodW5pcXVlMiA9IEFOWSAoJ3szLDd9Jzo6aW50ZWdlcltdKSkKKygxNyByb3dz KQorCitTRVQgZW5hYmxlX29yX3RyYW5zZm9ybWF0aW9uID0gb247CitleHBsYWluIChjb3N0 cyBvZmYpCitzZWxlY3QgKiBmcm9tIHRlbmsxIGEgam9pbiB0ZW5rMSBiIG9uCisgIChhLnVu aXF1ZTEgPSAxIGFuZCBiLnVuaXF1ZTEgPSAyKSBvcgorICAoKGEudW5pcXVlMiA9IDMgb3Ig YS51bmlxdWUyID0gNykgYW5kIGIuaHVuZHJlZCA9IDQpOworICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFFVRVJZIFBMQU4gICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCistLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0KKyBOZXN0ZWQgTG9vcAorICAgSm9pbiBGaWx0ZXI6ICgoKGEudW5pcXVlMSA9 IDEpIEFORCAoYi51bmlxdWUxID0gMikpIE9SICgoYS51bmlxdWUyID0gQU5ZICgnezMsN30n OjppbnRlZ2VyW10pKSBBTkQgKGIuaHVuZHJlZCA9IDQpKSkKKyAgIC0+ICBCaXRtYXAgSGVh cCBTY2FuIG9uIHRlbmsxIGIKKyAgICAgICAgIFJlY2hlY2sgQ29uZDogKCh1bmlxdWUxID0g MikgT1IgKGh1bmRyZWQgPSA0KSkKKyAgICAgICAgIC0+ICBCaXRtYXBPcgorICAgICAgICAg ICAgICAgLT4gIEJpdG1hcCBJbmRleCBTY2FuIG9uIHRlbmsxX3VuaXF1ZTEKKyAgICAgICAg ICAgICAgICAgICAgIEluZGV4IENvbmQ6ICh1bmlxdWUxID0gMikKKyAgICAgICAgICAgICAg IC0+ICBCaXRtYXAgSW5kZXggU2NhbiBvbiB0ZW5rMV9odW5kcmVkCisgICAgICAgICAgICAg ICAgICAgICBJbmRleCBDb25kOiAoaHVuZHJlZCA9IDQpCisgICAtPiAgTWF0ZXJpYWxpemUK KyAgICAgICAgIC0+ICBCaXRtYXAgSGVhcCBTY2FuIG9uIHRlbmsxIGEKKyAgICAgICAgICAg ICAgIFJlY2hlY2sgQ29uZDogKCh1bmlxdWUxID0gMSkgT1IgKHVuaXF1ZTIgPSBBTlkgKCd7 Myw3fSc6OmludGVnZXJbXSkpKQorICAgICAgICAgICAgICAgLT4gIEJpdG1hcE9yCisgICAg ICAgICAgICAgICAgICAgICAtPiAgQml0bWFwIEluZGV4IFNjYW4gb24gdGVuazFfdW5pcXVl MQorICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5kZXggQ29uZDogKHVuaXF1ZTEgPSAx KQogICAgICAgICAgICAgICAgICAgICAgLT4gIEJpdG1hcCBJbmRleCBTY2FuIG9uIHRlbmsx X3VuaXF1ZTIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZGV4IENvbmQ6ICh1bmlx dWUyID0gNykKLSgxOSByb3dzKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5kZXgg Q29uZDogKHVuaXF1ZTIgPSBBTlkgKCd7Myw3fSc6OmludGVnZXJbXSkpCisoMTcgcm93cykK KworZXhwbGFpbiAoY29zdHMgb2ZmKQorc2VsZWN0ICogZnJvbSB0ZW5rMSBhIGpvaW4gdGVu azEgYiBvbgorICAoYS51bmlxdWUxIDwgMjAgb3IgYS51bmlxdWUxID0gMyBvciBhLnVuaXF1 ZTEgPSAxIGFuZCBiLnVuaXF1ZTEgPSAyKSBvcgorICAoKGEudW5pcXVlMiA9IDMgb3IgYS51 bmlxdWUyID0gNykgYW5kIGIuaHVuZHJlZCA9IDQpOworICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBR VUVSWSBQTEFOICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCistLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyBOZXN0ZWQgTG9vcAorICAgSm9pbiBG aWx0ZXI6ICgoYS51bmlxdWUxIDwgMjApIE9SIChhLnVuaXF1ZTEgPSAzKSBPUiAoKGEudW5p cXVlMSA9IDEpIEFORCAoYi51bmlxdWUxID0gMikpIE9SICgoYS51bmlxdWUyID0gQU5ZICgn ezMsN30nOjppbnRlZ2VyW10pKSBBTkQgKGIuaHVuZHJlZCA9IDQpKSkKKyAgIC0+ICBTZXEg U2NhbiBvbiB0ZW5rMSBiCisgICAtPiAgTWF0ZXJpYWxpemUKKyAgICAgICAgIC0+ICBCaXRt YXAgSGVhcCBTY2FuIG9uIHRlbmsxIGEKKyAgICAgICAgICAgICAgIFJlY2hlY2sgQ29uZDog KCh1bmlxdWUxIDwgMjApIE9SICh1bmlxdWUxID0gMykgT1IgKHVuaXF1ZTEgPSAxKSBPUiAo dW5pcXVlMiA9IEFOWSAoJ3szLDd9Jzo6aW50ZWdlcltdKSkpCisgICAgICAgICAgICAgICAt PiAgQml0bWFwT3IKKyAgICAgICAgICAgICAgICAgICAgIC0+ICBCaXRtYXAgSW5kZXggU2Nh biBvbiB0ZW5rMV91bmlxdWUxCisgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmRleCBD b25kOiAodW5pcXVlMSA8IDIwKQorICAgICAgICAgICAgICAgICAgICAgLT4gIEJpdG1hcCBJ bmRleCBTY2FuIG9uIHRlbmsxX3VuaXF1ZTEKKyAgICAgICAgICAgICAgICAgICAgICAgICAg IEluZGV4IENvbmQ6ICh1bmlxdWUxID0gMykKKyAgICAgICAgICAgICAgICAgICAgIC0+ICBC aXRtYXAgSW5kZXggU2NhbiBvbiB0ZW5rMV91bmlxdWUxCisgICAgICAgICAgICAgICAgICAg ICAgICAgICBJbmRleCBDb25kOiAodW5pcXVlMSA9IDEpCisgICAgICAgICAgICAgICAgICAg ICAtPiAgQml0bWFwIEluZGV4IFNjYW4gb24gdGVuazFfdW5pcXVlMgorICAgICAgICAgICAg ICAgICAgICAgICAgICAgSW5kZXggQ29uZDogKHVuaXF1ZTIgPSBBTlkgKCd7Myw3fSc6Omlu dGVnZXJbXSkpCisoMTUgcm93cykKIAorUkVTRVQgZW5hYmxlX29yX3RyYW5zZm9ybWF0aW9u OwogLS0KIC0tIHRlc3QgcGxhY2VtZW50IG9mIG1vdmFibGUgcXVhbHMgaW4gYSBwYXJhbWV0 ZXJpemVkIGpvaW4gdHJlZQogLS0KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3JlZ3Jlc3MvZXhw ZWN0ZWQvcGFydGl0aW9uX3BydW5lLm91dCBiL3NyYy90ZXN0L3JlZ3Jlc3MvZXhwZWN0ZWQv cGFydGl0aW9uX3BydW5lLm91dAppbmRleCA3Y2E5ODM5N2FlYy4uOWMyYTRkNzU2MTkgMTAw NjQ0Ci0tLSBhL3NyYy90ZXN0L3JlZ3Jlc3MvZXhwZWN0ZWQvcGFydGl0aW9uX3BydW5lLm91 dAorKysgYi9zcmMvdGVzdC9yZWdyZXNzL2V4cGVjdGVkL3BhcnRpdGlvbl9wcnVuZS5vdXQK QEAgLTgyLDI1ICs4Miw0NyBAQCBleHBsYWluIChjb3N0cyBvZmYpIHNlbGVjdCAqIGZyb20g bHAgd2hlcmUgYSBpcyBudWxsOwogKDIgcm93cykKIAogZXhwbGFpbiAoY29zdHMgb2ZmKSBz ZWxlY3QgKiBmcm9tIGxwIHdoZXJlIGEgPSAnYScgb3IgYSA9ICdjJzsKLSAgICAgICAgICAg ICAgICAgICAgICAgIFFVRVJZIFBMQU4gICAgICAgICAgICAgICAgICAgICAgICAKLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0K KyAgICAgICAgICAgICAgICAgIFFVRVJZIFBMQU4gICAgICAgICAgICAgICAgICAgCistLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIEFwcGVuZAog ICAgLT4gIFNlcSBTY2FuIG9uIGxwX2FkIGxwXzEKLSAgICAgICAgIEZpbHRlcjogKChhID0g J2EnOjpicGNoYXIpIE9SIChhID0gJ2MnOjpicGNoYXIpKQorICAgICAgICAgRmlsdGVyOiAo YSA9IEFOWSAoJ3thLGN9Jzo6YnBjaGFyW10pKQogICAgLT4gIFNlcSBTY2FuIG9uIGxwX2Jj IGxwXzIKLSAgICAgICAgIEZpbHRlcjogKChhID0gJ2EnOjpicGNoYXIpIE9SIChhID0gJ2Mn OjpicGNoYXIpKQorICAgICAgICAgRmlsdGVyOiAoYSA9IEFOWSAoJ3thLGN9Jzo6YnBjaGFy W10pKQogKDUgcm93cykKIAogZXhwbGFpbiAoY29zdHMgb2ZmKSBzZWxlY3QgKiBmcm9tIGxw IHdoZXJlIGEgaXMgbm90IG51bGwgYW5kIChhID0gJ2EnIG9yIGEgPSAnYycpOwotICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRVUVSWSBQTEFOICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAg ICAgICAgICAgICAgICAgICAgICAgICAgIFFVRVJZIFBMQU4gICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIEFwcGVuZAogICAgLT4gIFNlcSBTY2Fu IG9uIGxwX2FkIGxwXzEKLSAgICAgICAgIEZpbHRlcjogKChhIElTIE5PVCBOVUxMKSBBTkQg KChhID0gJ2EnOjpicGNoYXIpIE9SIChhID0gJ2MnOjpicGNoYXIpKSkKKyAgICAgICAgIEZp bHRlcjogKChhIElTIE5PVCBOVUxMKSBBTkQgKGEgPSBBTlkgKCd7YSxjfSc6OmJwY2hhcltd KSkpCiAgICAtPiAgU2VxIFNjYW4gb24gbHBfYmMgbHBfMgotICAgICAgICAgRmlsdGVyOiAo KGEgSVMgTk9UIE5VTEwpIEFORCAoKGEgPSAnYSc6OmJwY2hhcikgT1IgKGEgPSAnYyc6OmJw Y2hhcikpKQorICAgICAgICAgRmlsdGVyOiAoKGEgSVMgTk9UIE5VTEwpIEFORCAoYSA9IEFO WSAoJ3thLGN9Jzo6YnBjaGFyW10pKSkKICg1IHJvd3MpCiAKK1NFVCBlbmFibGVfb3JfdHJh bnNmb3JtYXRpb24gPSBvbjsKK2V4cGxhaW4gKGNvc3RzIG9mZikgc2VsZWN0ICogZnJvbSBs cCB3aGVyZSBhID0gJ2EnIG9yIGEgPSAnYyc7CisgICAgICAgICAgICAgICAgICBRVUVSWSBQ TEFOICAgICAgICAgICAgICAgICAgIAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0KKyBBcHBlbmQKKyAgIC0+ICBTZXEgU2NhbiBvbiBscF9hZCBs cF8xCisgICAgICAgICBGaWx0ZXI6IChhID0gQU5ZICgne2EsY30nOjpicGNoYXJbXSkpCisg ICAtPiAgU2VxIFNjYW4gb24gbHBfYmMgbHBfMgorICAgICAgICAgRmlsdGVyOiAoYSA9IEFO WSAoJ3thLGN9Jzo6YnBjaGFyW10pKQorKDUgcm93cykKKworZXhwbGFpbiAoY29zdHMgb2Zm KSBzZWxlY3QgKiBmcm9tIGxwIHdoZXJlIGEgaXMgbm90IG51bGwgYW5kIChhID0gJ2EnIG9y IGEgPSAnYycpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRVUVSWSBQTEFOICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyBBcHBlbmQK KyAgIC0+ICBTZXEgU2NhbiBvbiBscF9hZCBscF8xCisgICAgICAgICBGaWx0ZXI6ICgoYSBJ UyBOT1QgTlVMTCkgQU5EIChhID0gQU5ZICgne2EsY30nOjpicGNoYXJbXSkpKQorICAgLT4g IFNlcSBTY2FuIG9uIGxwX2JjIGxwXzIKKyAgICAgICAgIEZpbHRlcjogKChhIElTIE5PVCBO VUxMKSBBTkQgKGEgPSBBTlkgKCd7YSxjfSc6OmJwY2hhcltdKSkpCisoNSByb3dzKQorCitS RVNFVCBlbmFibGVfb3JfdHJhbnNmb3JtYXRpb247CiBleHBsYWluIChjb3N0cyBvZmYpIHNl bGVjdCAqIGZyb20gbHAgd2hlcmUgYSA8PiAnZyc7CiAgICAgICAgICAgICAgUVVFUlkgUExB TiAgICAgICAgICAgICAKIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpA QCAtNTE1LDEwICs1MzcsMTAgQEAgZXhwbGFpbiAoY29zdHMgb2ZmKSBzZWxlY3QgKiBmcm9t IHJscCB3aGVyZSBhIDw9IDMxOwogKDI3IHJvd3MpCiAKIGV4cGxhaW4gKGNvc3RzIG9mZikg c2VsZWN0ICogZnJvbSBybHAgd2hlcmUgYSA9IDEgb3IgYSA9IDc7Ci0gICAgICAgICAgIFFV RVJZIFBMQU4gICAgICAgICAgIAotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0K KyAgICAgICAgICAgICAgICBRVUVSWSBQTEFOICAgICAgICAgICAgICAgIAorLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgU2VxIFNjYW4gb24gcmxwMiBy bHAKLSAgIEZpbHRlcjogKChhID0gMSkgT1IgKGEgPSA3KSkKKyAgIEZpbHRlcjogKGEgPSBB TlkgKCd7MSw3fSc6OmludGVnZXJbXSkpCiAoMiByb3dzKQogCiBleHBsYWluIChjb3N0cyBv ZmYpIHNlbGVjdCAqIGZyb20gcmxwIHdoZXJlIGEgPSAxIG9yIGIgPSAnYWInOwpAQCAtNTk2 LDEzICs2MTgsMTMgQEAgZXhwbGFpbiAoY29zdHMgb2ZmKSBzZWxlY3QgKiBmcm9tIHJscCB3 aGVyZSBhIDwgMSBvciAoYSA+IDIwIGFuZCBhIDwgMjUpOwogCiAtLSB3aGVyZSBjbGF1c2Ug Y29udHJhZGljdHMgc3ViLXBhcnRpdGlvbidzIGNvbnN0cmFpbnQKIGV4cGxhaW4gKGNvc3Rz IG9mZikgc2VsZWN0ICogZnJvbSBybHAgd2hlcmUgYSA9IDIwIG9yIGEgPSA0MDsKLSAgICAg ICAgICAgICAgIFFVRVJZIFBMQU4gICAgICAgICAgICAgICAKLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAgICAgICAgICAgICAgICAgUVVFUlkgUExB TiAgICAgICAgICAgICAgICAgICAgCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLQogIEFwcGVuZAogICAgLT4gIFNlcSBTY2FuIG9uIHJscDRf MSBybHBfMQotICAgICAgICAgRmlsdGVyOiAoKGEgPSAyMCkgT1IgKGEgPSA0MCkpCisgICAg ICAgICBGaWx0ZXI6IChhID0gQU5ZICgnezIwLDQwfSc6OmludGVnZXJbXSkpCiAgICAtPiAg U2VxIFNjYW4gb24gcmxwNV9kZWZhdWx0IHJscF8yCi0gICAgICAgICBGaWx0ZXI6ICgoYSA9 IDIwKSBPUiAoYSA9IDQwKSkKKyAgICAgICAgIEZpbHRlcjogKGEgPSBBTlkgKCd7MjAsNDB9 Jzo6aW50ZWdlcltdKSkKICg1IHJvd3MpCiAKIGV4cGxhaW4gKGNvc3RzIG9mZikgc2VsZWN0 ICogZnJvbSBybHAzIHdoZXJlIGEgPSAyMDsgICAvKiBlbXB0eSAqLwpAQCAtNjcxLDYgKzY5 MywxNjMgQEAgZXhwbGFpbiAoY29zdHMgb2ZmKSBzZWxlY3QgKiBmcm9tIHJscCB3aGVyZSAo YSA9IDEgYW5kIGEgPSAzKSBvciAoYSA+IDEgYW5kIGEgPQogICAgICAgICAgRmlsdGVyOiAo KChhID0gMSkgQU5EIChhID0gMykpIE9SICgoYSA+IDEpIEFORCAoYSA9IDE1KSkpCiAoMTEg cm93cykKIAorU0VUIGVuYWJsZV9vcl90cmFuc2Zvcm1hdGlvbiA9IG9uOworZXhwbGFpbiAo Y29zdHMgb2ZmKSBzZWxlY3QgKiBmcm9tIHJscCB3aGVyZSBhID0gMSBvciBhID0gNzsKKyAg ICAgICAgICAgICAgICBRVUVSWSBQTEFOICAgICAgICAgICAgICAgIAorLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgU2VxIFNjYW4gb24gcmxwMiBybHAK KyAgIEZpbHRlcjogKGEgPSBBTlkgKCd7MSw3fSc6OmludGVnZXJbXSkpCisoMiByb3dzKQor CitleHBsYWluIChjb3N0cyBvZmYpIHNlbGVjdCAqIGZyb20gcmxwIHdoZXJlIGEgPSAxIG9y IGIgPSAnYWInOworICAgICAgICAgICAgICAgICAgICAgIFFVRVJZIFBMQU4gICAgICAgICAg ICAgICAgICAgICAgIAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLQorIEFwcGVuZAorICAgLT4gIFNlcSBTY2FuIG9uIHJscDEgcmxw XzEKKyAgICAgICAgIEZpbHRlcjogKChhID0gMSkgT1IgKChiKTo6dGV4dCA9ICdhYic6OnRl eHQpKQorICAgLT4gIFNlcSBTY2FuIG9uIHJscDIgcmxwXzIKKyAgICAgICAgIEZpbHRlcjog KChhID0gMSkgT1IgKChiKTo6dGV4dCA9ICdhYic6OnRleHQpKQorICAgLT4gIFNlcSBTY2Fu IG9uIHJscDNhYmNkIHJscF8zCisgICAgICAgICBGaWx0ZXI6ICgoYSA9IDEpIE9SICgoYik6 OnRleHQgPSAnYWInOjp0ZXh0KSkKKyAgIC0+ICBTZXEgU2NhbiBvbiBybHA0XzEgcmxwXzQK KyAgICAgICAgIEZpbHRlcjogKChhID0gMSkgT1IgKChiKTo6dGV4dCA9ICdhYic6OnRleHQp KQorICAgLT4gIFNlcSBTY2FuIG9uIHJscDRfMiBybHBfNQorICAgICAgICAgRmlsdGVyOiAo KGEgPSAxKSBPUiAoKGIpOjp0ZXh0ID0gJ2FiJzo6dGV4dCkpCisgICAtPiAgU2VxIFNjYW4g b24gcmxwNF9kZWZhdWx0IHJscF82CisgICAgICAgICBGaWx0ZXI6ICgoYSA9IDEpIE9SICgo Yik6OnRleHQgPSAnYWInOjp0ZXh0KSkKKyAgIC0+ICBTZXEgU2NhbiBvbiBybHA1XzEgcmxw XzcKKyAgICAgICAgIEZpbHRlcjogKChhID0gMSkgT1IgKChiKTo6dGV4dCA9ICdhYic6OnRl eHQpKQorICAgLT4gIFNlcSBTY2FuIG9uIHJscDVfZGVmYXVsdCBybHBfOAorICAgICAgICAg RmlsdGVyOiAoKGEgPSAxKSBPUiAoKGIpOjp0ZXh0ID0gJ2FiJzo6dGV4dCkpCisgICAtPiAg U2VxIFNjYW4gb24gcmxwX2RlZmF1bHRfMTAgcmxwXzkKKyAgICAgICAgIEZpbHRlcjogKChh ID0gMSkgT1IgKChiKTo6dGV4dCA9ICdhYic6OnRleHQpKQorICAgLT4gIFNlcSBTY2FuIG9u IHJscF9kZWZhdWx0XzMwIHJscF8xMAorICAgICAgICAgRmlsdGVyOiAoKGEgPSAxKSBPUiAo KGIpOjp0ZXh0ID0gJ2FiJzo6dGV4dCkpCisgICAtPiAgU2VxIFNjYW4gb24gcmxwX2RlZmF1 bHRfbnVsbCBybHBfMTEKKyAgICAgICAgIEZpbHRlcjogKChhID0gMSkgT1IgKChiKTo6dGV4 dCA9ICdhYic6OnRleHQpKQorICAgLT4gIFNlcSBTY2FuIG9uIHJscF9kZWZhdWx0X2RlZmF1 bHQgcmxwXzEyCisgICAgICAgICBGaWx0ZXI6ICgoYSA9IDEpIE9SICgoYik6OnRleHQgPSAn YWInOjp0ZXh0KSkKKygyNSByb3dzKQorCitleHBsYWluIChjb3N0cyBvZmYpIHNlbGVjdCAq IGZyb20gcmxwIHdoZXJlIGEgPiAyMCBhbmQgYSA8IDI3OworICAgICAgICAgICAgICAgUVVF UlkgUExBTiAgICAgICAgICAgICAgICAKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tCisgQXBwZW5kCisgICAtPiAgU2VxIFNjYW4gb24gcmxwNF8xIHJscF8x CisgICAgICAgICBGaWx0ZXI6ICgoYSA+IDIwKSBBTkQgKGEgPCAyNykpCisgICAtPiAgU2Vx IFNjYW4gb24gcmxwNF8yIHJscF8yCisgICAgICAgICBGaWx0ZXI6ICgoYSA+IDIwKSBBTkQg KGEgPCAyNykpCisoNSByb3dzKQorCitleHBsYWluIChjb3N0cyBvZmYpIHNlbGVjdCAqIGZy b20gcmxwIHdoZXJlIGEgPSAyOTsKKyAgICAgICAgICBRVUVSWSBQTEFOICAgICAgICAgIAor LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgU2VxIFNjYW4gb24gcmxwNF9kZWZh dWx0IHJscAorICAgRmlsdGVyOiAoYSA9IDI5KQorKDIgcm93cykKKworZXhwbGFpbiAoY29z dHMgb2ZmKSBzZWxlY3QgKiBmcm9tIHJscCB3aGVyZSBhID49IDI5OworICAgICAgICAgICAg ICAgICBRVUVSWSBQTEFOICAgICAgICAgICAgICAgICAgCistLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyBBcHBlbmQKKyAgIC0+ICBTZXEgU2NhbiBv biBybHA0X2RlZmF1bHQgcmxwXzEKKyAgICAgICAgIEZpbHRlcjogKGEgPj0gMjkpCisgICAt PiAgU2VxIFNjYW4gb24gcmxwNV8xIHJscF8yCisgICAgICAgICBGaWx0ZXI6IChhID49IDI5 KQorICAgLT4gIFNlcSBTY2FuIG9uIHJscDVfZGVmYXVsdCBybHBfMworICAgICAgICAgRmls dGVyOiAoYSA+PSAyOSkKKyAgIC0+ICBTZXEgU2NhbiBvbiBybHBfZGVmYXVsdF8zMCBybHBf NAorICAgICAgICAgRmlsdGVyOiAoYSA+PSAyOSkKKyAgIC0+ICBTZXEgU2NhbiBvbiBybHBf ZGVmYXVsdF9kZWZhdWx0IHJscF81CisgICAgICAgICBGaWx0ZXI6IChhID49IDI5KQorKDEx IHJvd3MpCisKK2V4cGxhaW4gKGNvc3RzIG9mZikgc2VsZWN0ICogZnJvbSBybHAgd2hlcmUg YSA8IDEgb3IgKGEgPiAyMCBhbmQgYSA8IDI1KTsKKyAgICAgICAgICAgICAgICAgICAgICBR VUVSWSBQTEFOICAgICAgICAgICAgICAgICAgICAgIAorLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgQXBwZW5kCisgICAtPiAgU2Vx IFNjYW4gb24gcmxwMSBybHBfMQorICAgICAgICAgRmlsdGVyOiAoKGEgPCAxKSBPUiAoKGEg PiAyMCkgQU5EIChhIDwgMjUpKSkKKyAgIC0+ICBTZXEgU2NhbiBvbiBybHA0XzEgcmxwXzIK KyAgICAgICAgIEZpbHRlcjogKChhIDwgMSkgT1IgKChhID4gMjApIEFORCAoYSA8IDI1KSkp CisoNSByb3dzKQorCitleHBsYWluIChjb3N0cyBvZmYpIHNlbGVjdCAqIGZyb20gcmxwIHdo ZXJlIGEgPSAyMCBvciBhID0gNDA7CisgICAgICAgICAgICAgICAgICAgIFFVRVJZIFBMQU4g ICAgICAgICAgICAgICAgICAgIAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0KKyBBcHBlbmQKKyAgIC0+ICBTZXEgU2NhbiBvbiBybHA0XzEg cmxwXzEKKyAgICAgICAgIEZpbHRlcjogKGEgPSBBTlkgKCd7MjAsNDB9Jzo6aW50ZWdlcltd KSkKKyAgIC0+ICBTZXEgU2NhbiBvbiBybHA1X2RlZmF1bHQgcmxwXzIKKyAgICAgICAgIEZp bHRlcjogKGEgPSBBTlkgKCd7MjAsNDB9Jzo6aW50ZWdlcltdKSkKKyg1IHJvd3MpCisKK2V4 cGxhaW4gKGNvc3RzIG9mZikgc2VsZWN0ICogZnJvbSBybHAzIHdoZXJlIGEgPSAyMDsgICAv KiBlbXB0eSAqLworICAgICAgICBRVUVSWSBQTEFOICAgICAgICAKKy0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tCisgUmVzdWx0CisgICBPbmUtVGltZSBGaWx0ZXI6IGZhbHNlCisoMiBy b3dzKQorCitleHBsYWluIChjb3N0cyBvZmYpIHNlbGVjdCAqIGZyb20gcmxwIHdoZXJlIGEg PiAxIGFuZCBhID0gMTA7CS8qIG9ubHkgZGVmYXVsdCAqLworICAgICAgICAgICAgUVVFUlkg UExBTiAgICAgICAgICAgIAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQor IFNlcSBTY2FuIG9uIHJscF9kZWZhdWx0XzEwIHJscAorICAgRmlsdGVyOiAoKGEgPiAxKSBB TkQgKGEgPSAxMCkpCisoMiByb3dzKQorCitleHBsYWluIChjb3N0cyBvZmYpIHNlbGVjdCAq IGZyb20gcmxwIHdoZXJlIGEgPiAxIGFuZCBhID49MTU7CS8qIHJscDMgb253YXJkcywgaW5j bHVkaW5nIGRlZmF1bHQgKi8KKyAgICAgICAgICAgICAgICAgIFFVRVJZIFBMQU4gICAgICAg ICAgICAgICAgICAKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0KKyBBcHBlbmQKKyAgIC0+ICBTZXEgU2NhbiBvbiBybHAzYWJjZCBybHBfMQorICAg ICAgICAgRmlsdGVyOiAoKGEgPiAxKSBBTkQgKGEgPj0gMTUpKQorICAgLT4gIFNlcSBTY2Fu IG9uIHJscDNlZmdoIHJscF8yCisgICAgICAgICBGaWx0ZXI6ICgoYSA+IDEpIEFORCAoYSA+ PSAxNSkpCisgICAtPiAgU2VxIFNjYW4gb24gcmxwM251bGx4eSBybHBfMworICAgICAgICAg RmlsdGVyOiAoKGEgPiAxKSBBTkQgKGEgPj0gMTUpKQorICAgLT4gIFNlcSBTY2FuIG9uIHJs cDNfZGVmYXVsdCBybHBfNAorICAgICAgICAgRmlsdGVyOiAoKGEgPiAxKSBBTkQgKGEgPj0g MTUpKQorICAgLT4gIFNlcSBTY2FuIG9uIHJscDRfMSBybHBfNQorICAgICAgICAgRmlsdGVy OiAoKGEgPiAxKSBBTkQgKGEgPj0gMTUpKQorICAgLT4gIFNlcSBTY2FuIG9uIHJscDRfMiBy bHBfNgorICAgICAgICAgRmlsdGVyOiAoKGEgPiAxKSBBTkQgKGEgPj0gMTUpKQorICAgLT4g IFNlcSBTY2FuIG9uIHJscDRfZGVmYXVsdCBybHBfNworICAgICAgICAgRmlsdGVyOiAoKGEg PiAxKSBBTkQgKGEgPj0gMTUpKQorICAgLT4gIFNlcSBTY2FuIG9uIHJscDVfMSBybHBfOAor ICAgICAgICAgRmlsdGVyOiAoKGEgPiAxKSBBTkQgKGEgPj0gMTUpKQorICAgLT4gIFNlcSBT Y2FuIG9uIHJscDVfZGVmYXVsdCBybHBfOQorICAgICAgICAgRmlsdGVyOiAoKGEgPiAxKSBB TkQgKGEgPj0gMTUpKQorICAgLT4gIFNlcSBTY2FuIG9uIHJscF9kZWZhdWx0XzMwIHJscF8x MAorICAgICAgICAgRmlsdGVyOiAoKGEgPiAxKSBBTkQgKGEgPj0gMTUpKQorICAgLT4gIFNl cSBTY2FuIG9uIHJscF9kZWZhdWx0X2RlZmF1bHQgcmxwXzExCisgICAgICAgICBGaWx0ZXI6 ICgoYSA+IDEpIEFORCAoYSA+PSAxNSkpCisoMjMgcm93cykKKworZXhwbGFpbiAoY29zdHMg b2ZmKSBzZWxlY3QgKiBmcm9tIHJscCB3aGVyZSBhID0gMSBhbmQgYSA9IDM7CS8qIGVtcHR5 ICovCisgICAgICAgIFFVRVJZIFBMQU4gICAgICAgIAorLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0KKyBSZXN1bHQKKyAgIE9uZS1UaW1lIEZpbHRlcjogZmFsc2UKKygyIHJvd3MpCisK K2V4cGxhaW4gKGNvc3RzIG9mZikgc2VsZWN0ICogZnJvbSBybHAgd2hlcmUgKGEgPSAxIGFu ZCBhID0gMykgb3IgKGEgPiAxIGFuZCBhID0gMTUpOworICAgICAgICAgICAgICAgICAgICAg ICAgICAgIFFVRVJZIFBMQU4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLQorIEFwcGVuZAorICAgLT4gIFNlcSBTY2FuIG9uIHJscDIgcmxwXzEKKyAgICAg ICAgIEZpbHRlcjogKCgoYSA9IDEpIEFORCAoYSA9IDMpKSBPUiAoKGEgPiAxKSBBTkQgKGEg PSAxNSkpKQorICAgLT4gIFNlcSBTY2FuIG9uIHJscDNhYmNkIHJscF8yCisgICAgICAgICBG aWx0ZXI6ICgoKGEgPSAxKSBBTkQgKGEgPSAzKSkgT1IgKChhID4gMSkgQU5EIChhID0gMTUp KSkKKyAgIC0+ICBTZXEgU2NhbiBvbiBybHAzZWZnaCBybHBfMworICAgICAgICAgRmlsdGVy OiAoKChhID0gMSkgQU5EIChhID0gMykpIE9SICgoYSA+IDEpIEFORCAoYSA9IDE1KSkpCisg ICAtPiAgU2VxIFNjYW4gb24gcmxwM251bGx4eSBybHBfNAorICAgICAgICAgRmlsdGVyOiAo KChhID0gMSkgQU5EIChhID0gMykpIE9SICgoYSA+IDEpIEFORCAoYSA9IDE1KSkpCisgICAt PiAgU2VxIFNjYW4gb24gcmxwM19kZWZhdWx0IHJscF81CisgICAgICAgICBGaWx0ZXI6ICgo KGEgPSAxKSBBTkQgKGEgPSAzKSkgT1IgKChhID4gMSkgQU5EIChhID0gMTUpKSkKKygxMSBy b3dzKQorCitSRVNFVCBlbmFibGVfb3JfdHJhbnNmb3JtYXRpb247CiAtLSBtdWx0aS1jb2x1 bW4ga2V5cwogY3JlYXRlIHRhYmxlIG1jM3AgKGEgaW50LCBiIGludCwgYyBpbnQpIHBhcnRp dGlvbiBieSByYW5nZSAoYSwgYWJzKGIpLCBjKTsKIGNyZWF0ZSB0YWJsZSBtYzNwX2RlZmF1 bHQgcGFydGl0aW9uIG9mIG1jM3AgZGVmYXVsdDsKQEAgLTIwNzIsMTAgKzIyNTEsMTAgQEAg ZXhwbGFpbiAoY29zdHMgb2ZmKSBzZWxlY3QgKiBmcm9tIGhwIHdoZXJlIGEgPSAxIGFuZCBi ID0gJ2FiY2RlJzsKIAogZXhwbGFpbiAoY29zdHMgb2ZmKSBzZWxlY3QgKiBmcm9tIGhwIHdo ZXJlIGEgPSAxIGFuZCBiID0gJ2FiY2RlJyBhbmQKICAgKGMgPSAyIG9yIGMgPSAzKTsKLSAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgIFFVRVJZIFBMQU4gICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgUVVFUlkgUExBTiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIFNlcSBTY2FuIG9uIGhwMiBo cAotICAgRmlsdGVyOiAoKGEgPSAxKSBBTkQgKGIgPSAnYWJjZGUnOjp0ZXh0KSBBTkQgKChj ID0gMikgT1IgKGMgPSAzKSkpCisgICBGaWx0ZXI6ICgoYyA9IEFOWSAoJ3syLDN9Jzo6aW50 ZWdlcltdKSkgQU5EIChhID0gMSkgQU5EIChiID0gJ2FiY2RlJzo6dGV4dCkpCiAoMiByb3dz KQogCiBkcm9wIHRhYmxlIGhwMjsKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3JlZ3Jlc3MvZXhw ZWN0ZWQvc3RhdHNfZXh0Lm91dCBiL3NyYy90ZXN0L3JlZ3Jlc3MvZXhwZWN0ZWQvc3RhdHNf ZXh0Lm91dAppbmRleCA4YzRkYTk1NTA4NC4uNzY3ODc0NDE4MWMgMTAwNjQ0Ci0tLSBhL3Ny Yy90ZXN0L3JlZ3Jlc3MvZXhwZWN0ZWQvc3RhdHNfZXh0Lm91dAorKysgYi9zcmMvdGVzdC9y ZWdyZXNzL2V4cGVjdGVkL3N0YXRzX2V4dC5vdXQKQEAgLTEzMjIsMTkgKzEzMjIsMTkgQEAg U0VMRUNUICogRlJPTSBjaGVja19lc3RpbWF0ZWRfcm93cygnU0VMRUNUICogRlJPTSBmdW5j dGlvbmFsX2RlcGVuZGVuY2llcyBXSEVSRQogU0VMRUNUICogRlJPTSBjaGVja19lc3RpbWF0 ZWRfcm93cygnU0VMRUNUICogRlJPTSBmdW5jdGlvbmFsX2RlcGVuZGVuY2llcyBXSEVSRSAo YSA9IDEgT1IgYSA9IDUxKSBBTkQgYiA9ICcnMScnJyk7CiAgZXN0aW1hdGVkIHwgYWN0dWFs IAogLS0tLS0tLS0tLS0rLS0tLS0tLS0KLSAgICAgICAgOTkgfCAgICAxMDAKKyAgICAgICAx MDAgfCAgICAxMDAKICgxIHJvdykKIAogU0VMRUNUICogRlJPTSBjaGVja19lc3RpbWF0ZWRf cm93cygnU0VMRUNUICogRlJPTSBmdW5jdGlvbmFsX2RlcGVuZGVuY2llcyBXSEVSRSAoYSA9 IDEgT1IgYSA9IDUxKSBBTkQgKGIgPSAnJzEnJyBPUiBiID0gJycyJycpJyk7CiAgZXN0aW1h dGVkIHwgYWN0dWFsIAogLS0tLS0tLS0tLS0rLS0tLS0tLS0KLSAgICAgICAgOTkgfCAgICAx MDAKKyAgICAgICAxMDAgfCAgICAxMDAKICgxIHJvdykKIAogU0VMRUNUICogRlJPTSBjaGVj a19lc3RpbWF0ZWRfcm93cygnU0VMRUNUICogRlJPTSBmdW5jdGlvbmFsX2RlcGVuZGVuY2ll cyBXSEVSRSAoYSA9IDEgT1IgYSA9IDIgT1IgYSA9IDUxIE9SIGEgPSA1MikgQU5EIChiID0g JycxJycgT1IgYiA9ICcnMicnKScpOwogIGVzdGltYXRlZCB8IGFjdHVhbCAKIC0tLS0tLS0t LS0tKy0tLS0tLS0tCi0gICAgICAgMTk3IHwgICAgMjAwCisgICAgICAgMjAwIHwgICAgMjAw CiAoMSByb3cpCiAKIC0tIE9SIGNsYXVzZXMgcmVmZXJlbmNpbmcgZGlmZmVyZW50IGF0dHJp YnV0ZXMgYXJlIGluY29tcGF0aWJsZQpAQCAtMTY2NCwxOSArMTY2NCwxOSBAQCBTRUxFQ1Qg KiBGUk9NIGNoZWNrX2VzdGltYXRlZF9yb3dzKCdTRUxFQ1QgKiBGUk9NIGZ1bmN0aW9uYWxf ZGVwZW5kZW5jaWVzIFdIRVJFCiBTRUxFQ1QgKiBGUk9NIGNoZWNrX2VzdGltYXRlZF9yb3dz KCdTRUxFQ1QgKiBGUk9NIGZ1bmN0aW9uYWxfZGVwZW5kZW5jaWVzIFdIRVJFICgoYSAqIDIp ID0gMiBPUiAoYSAqIDIpID0gMTAyKSBBTkQgdXBwZXIoYikgPSAnJzEnJycpOwogIGVzdGlt YXRlZCB8IGFjdHVhbCAKIC0tLS0tLS0tLS0tKy0tLS0tLS0tCi0gICAgICAgIDk5IHwgICAg MTAwCisgICAgICAgMTAwIHwgICAgMTAwCiAoMSByb3cpCiAKIFNFTEVDVCAqIEZST00gY2hl Y2tfZXN0aW1hdGVkX3Jvd3MoJ1NFTEVDVCAqIEZST00gZnVuY3Rpb25hbF9kZXBlbmRlbmNp ZXMgV0hFUkUgKChhICogMikgPSAyIE9SIChhICogMikgPSAxMDIpIEFORCAodXBwZXIoYikg PSAnJzEnJyBPUiB1cHBlcihiKSA9ICcnMicnKScpOwogIGVzdGltYXRlZCB8IGFjdHVhbCAK IC0tLS0tLS0tLS0tKy0tLS0tLS0tCi0gICAgICAgIDk5IHwgICAgMTAwCisgICAgICAgMTAw IHwgICAgMTAwCiAoMSByb3cpCiAKIFNFTEVDVCAqIEZST00gY2hlY2tfZXN0aW1hdGVkX3Jv d3MoJ1NFTEVDVCAqIEZST00gZnVuY3Rpb25hbF9kZXBlbmRlbmNpZXMgV0hFUkUgKChhICog MikgPSAyIE9SIChhICogMikgPSA0IE9SIChhICogMikgPSAxMDIgT1IgKGEgKiAyKSA9IDEw NCkgQU5EICh1cHBlcihiKSA9ICcnMScnIE9SIHVwcGVyKGIpID0gJycyJycpJyk7CiAgZXN0 aW1hdGVkIHwgYWN0dWFsIAogLS0tLS0tLS0tLS0rLS0tLS0tLS0KLSAgICAgICAxOTcgfCAg ICAyMDAKKyAgICAgICAyMDAgfCAgICAyMDAKICgxIHJvdykKIAogLS0gT1IgY2xhdXNlcyBy ZWZlcmVuY2luZyBkaWZmZXJlbnQgYXR0cmlidXRlcwpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qv cmVncmVzcy9leHBlY3RlZC9zeXN2aWV3cy5vdXQgYi9zcmMvdGVzdC9yZWdyZXNzL2V4cGVj dGVkL3N5c3ZpZXdzLm91dAppbmRleCBkYmZkMGMxM2Q0Ni4uNjEyMzM1MWE5YTggMTAwNjQ0 Ci0tLSBhL3NyYy90ZXN0L3JlZ3Jlc3MvZXhwZWN0ZWQvc3lzdmlld3Mub3V0CisrKyBiL3Ny Yy90ZXN0L3JlZ3Jlc3MvZXhwZWN0ZWQvc3lzdmlld3Mub3V0CkBAIC0xNDcsNiArMTQ3LDcg QEAgc2VsZWN0IG5hbWUsIHNldHRpbmcgZnJvbSBwZ19zZXR0aW5ncyB3aGVyZSBuYW1lIGxp a2UgJ2VuYWJsZSUnOwogIGVuYWJsZV9tZW1vaXplICAgICAgICAgICAgICAgICB8IG9uCiAg ZW5hYmxlX21lcmdlam9pbiAgICAgICAgICAgICAgIHwgb24KICBlbmFibGVfbmVzdGxvb3Ag ICAgICAgICAgICAgICAgfCBvbgorIGVuYWJsZV9vcl90cmFuc2Zvcm1hdGlvbiAgICAgICB8 IG9uCiAgZW5hYmxlX3BhcmFsbGVsX2FwcGVuZCAgICAgICAgIHwgb24KICBlbmFibGVfcGFy YWxsZWxfaGFzaCAgICAgICAgICAgfCBvbgogIGVuYWJsZV9wYXJ0aXRpb25fcHJ1bmluZyAg ICAgICB8IG9uCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZWdyZXNzL3NxbC9jcmVhdGVfaW5k ZXguc3FsIGIvc3JjL3Rlc3QvcmVncmVzcy9zcWwvY3JlYXRlX2luZGV4LnNxbAppbmRleCBl Mjk2ODkxY2FiOC4uMDU3YzZkMmJkYTEgMTAwNjQ0Ci0tLSBhL3NyYy90ZXN0L3JlZ3Jlc3Mv c3FsL2NyZWF0ZV9pbmRleC5zcWwKKysrIGIvc3JjL3Rlc3QvcmVncmVzcy9zcWwvY3JlYXRl X2luZGV4LnNxbApAQCAtNzM4LDYgKzczOCw0MSBAQCBTRUxFQ1QgY291bnQoKikgRlJPTSB0 ZW5rMQogU0VMRUNUIGNvdW50KCopIEZST00gdGVuazEKICAgV0hFUkUgaHVuZHJlZCA9IDQy IEFORCAodGhvdXNhbmQgPSA0MiBPUiB0aG91c2FuZCA9IDk5KTsKIAorU0VUIGVuYWJsZV9v cl90cmFuc2Zvcm1hdGlvbiA9IG9uOworRVhQTEFJTiAoQ09TVFMgT0ZGKQorU0VMRUNUICog RlJPTSB0ZW5rMQorICBXSEVSRSB0aG91c2FuZCA9IDQyIEFORCAodGVudGhvdXMgPSAxIE9S IHRlbnRob3VzID0gMyBPUiB0ZW50aG91cyA9IDQyKTsKK1NFTEVDVCAqIEZST00gdGVuazEK KyAgV0hFUkUgdGhvdXNhbmQgPSA0MiBBTkQgKHRlbnRob3VzID0gMSBPUiB0ZW50aG91cyA9 IDMgT1IgdGVudGhvdXMgPSA0Mik7CisKK0VYUExBSU4gKENPU1RTIE9GRikKK1NFTEVDVCBj b3VudCgqKSBGUk9NIHRlbmsxCisgIFdIRVJFIGh1bmRyZWQgPSA0MiBBTkQgKHRob3VzYW5k ID0gNDIgT1IgdGhvdXNhbmQgPSA5OSk7CitTRUxFQ1QgY291bnQoKikgRlJPTSB0ZW5rMQor ICBXSEVSRSBodW5kcmVkID0gNDIgQU5EICh0aG91c2FuZCA9IDQyIE9SIHRob3VzYW5kID0g OTkpOworRVhQTEFJTiAoQ09TVFMgT0ZGKQorU0VMRUNUIGNvdW50KCopIEZST00gdGVuazEK KyAgV0hFUkUgaHVuZHJlZCA9IDQyIEFORCAodGhvdXNhbmQgPCA0MiBPUiB0aG91c2FuZCA8 IDk5IE9SIDQzID4gdGhvdXNhbmQgT1IgNDIgPiB0aG91c2FuZCk7CisKK0VYUExBSU4gKENP U1RTIE9GRikKK1NFTEVDVCBjb3VudCgqKSBGUk9NIHRlbmsxCisgIFdIRVJFIHRob3VzYW5k ID0gNDIgQU5EICh0ZW50aG91cyA9IDEgT1IgdGVudGhvdXMgPSAzKSBPUiB0aG91c2FuZCA9 IDQxOworU0VMRUNUIGNvdW50KCopIEZST00gdGVuazEKKyAgV0hFUkUgdGhvdXNhbmQgPSA0 MiBBTkQgKHRlbnRob3VzID0gMSBPUiB0ZW50aG91cyA9IDMpIE9SIHRob3VzYW5kID0gNDE7 CisKK0VYUExBSU4gKENPU1RTIE9GRikKK1NFTEVDVCBjb3VudCgqKSBGUk9NIHRlbmsxCisg IFdIRVJFIGh1bmRyZWQgPSA0MiBBTkQgKHRob3VzYW5kID0gNDIgT1IgdGhvdXNhbmQgPSA5 OSBPUiB0ZW50aG91cyA8IDIpIE9SIHRob3VzYW5kID0gNDE7CitTRUxFQ1QgY291bnQoKikg RlJPTSB0ZW5rMQorICBXSEVSRSBodW5kcmVkID0gNDIgQU5EICh0aG91c2FuZCA9IDQyIE9S IHRob3VzYW5kID0gOTkgT1IgdGVudGhvdXMgPCAyKSBPUiB0aG91c2FuZCA9IDQxOworCitF WFBMQUlOIChDT1NUUyBPRkYpCitTRUxFQ1QgY291bnQoKikgRlJPTSB0ZW5rMQorICBXSEVS RSBodW5kcmVkID0gNDIgQU5EICh0aG91c2FuZCA9IDQyIE9SIHRob3VzYW5kID0gNDEgT1Ig dGhvdXNhbmQgPSA5OSBBTkQgdGVudGhvdXMgPSAyKTsKK1NFTEVDVCBjb3VudCgqKSBGUk9N IHRlbmsxCisgIFdIRVJFIGh1bmRyZWQgPSA0MiBBTkQgKHRob3VzYW5kID0gNDIgT1IgdGhv dXNhbmQgPSA0MSBPUiB0aG91c2FuZCA9IDk5IEFORCB0ZW50aG91cyA9IDIpOworUkVTRVQg ZW5hYmxlX29yX3RyYW5zZm9ybWF0aW9uOworCiAtLQogLS0gQ2hlY2sgYmVoYXZpb3Igd2l0 aCBkdXBsaWNhdGUgaW5kZXggY29sdW1uIGNvbnRlbnRzCiAtLQpkaWZmIC0tZ2l0IGEvc3Jj L3Rlc3QvcmVncmVzcy9zcWwvam9pbi5zcWwgYi9zcmMvdGVzdC9yZWdyZXNzL3NxbC9qb2lu LnNxbAppbmRleCA4YmZlM2I3YmE2Ny4uYzc3YjVjNTBmMDEgMTAwNjQ0Ci0tLSBhL3NyYy90 ZXN0L3JlZ3Jlc3Mvc3FsL2pvaW4uc3FsCisrKyBiL3NyYy90ZXN0L3JlZ3Jlc3Mvc3FsL2pv aW4uc3FsCkBAIC0xNDA4LDYgKzE0MDgsMTYgQEAgZXhwbGFpbiAoY29zdHMgb2ZmKQogc2Vs ZWN0ICogZnJvbSB0ZW5rMSBhIGpvaW4gdGVuazEgYiBvbgogICAoYS51bmlxdWUxID0gMSBh bmQgYi51bmlxdWUxID0gMikgb3IKICAgKChhLnVuaXF1ZTIgPSAzIG9yIGEudW5pcXVlMiA9 IDcpIGFuZCBiLmh1bmRyZWQgPSA0KTsKK1NFVCBlbmFibGVfb3JfdHJhbnNmb3JtYXRpb24g PSBvbjsKK2V4cGxhaW4gKGNvc3RzIG9mZikKK3NlbGVjdCAqIGZyb20gdGVuazEgYSBqb2lu IHRlbmsxIGIgb24KKyAgKGEudW5pcXVlMSA9IDEgYW5kIGIudW5pcXVlMSA9IDIpIG9yCisg ICgoYS51bmlxdWUyID0gMyBvciBhLnVuaXF1ZTIgPSA3KSBhbmQgYi5odW5kcmVkID0gNCk7 CitleHBsYWluIChjb3N0cyBvZmYpCitzZWxlY3QgKiBmcm9tIHRlbmsxIGEgam9pbiB0ZW5r MSBiIG9uCisgIChhLnVuaXF1ZTEgPCAyMCBvciBhLnVuaXF1ZTEgPSAzIG9yIGEudW5pcXVl MSA9IDEgYW5kIGIudW5pcXVlMSA9IDIpIG9yCisgICgoYS51bmlxdWUyID0gMyBvciBhLnVu aXF1ZTIgPSA3KSBhbmQgYi5odW5kcmVkID0gNCk7CitSRVNFVCBlbmFibGVfb3JfdHJhbnNm b3JtYXRpb247CiAKIC0tCiAtLSB0ZXN0IHBsYWNlbWVudCBvZiBtb3ZhYmxlIHF1YWxzIGlu IGEgcGFyYW1ldGVyaXplZCBqb2luIHRyZWUKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3JlZ3Jl c3Mvc3FsL3BhcnRpdGlvbl9wcnVuZS5zcWwgYi9zcmMvdGVzdC9yZWdyZXNzL3NxbC9wYXJ0 aXRpb25fcHJ1bmUuc3FsCmluZGV4IGEwOWIyN2Q4MjBjLi45NzE3YzhjODM1YyAxMDA2NDQK LS0tIGEvc3JjL3Rlc3QvcmVncmVzcy9zcWwvcGFydGl0aW9uX3BydW5lLnNxbAorKysgYi9z cmMvdGVzdC9yZWdyZXNzL3NxbC9wYXJ0aXRpb25fcHJ1bmUuc3FsCkBAIC0yMSw2ICsyMSwx MiBAQCBleHBsYWluIChjb3N0cyBvZmYpIHNlbGVjdCAqIGZyb20gbHAgd2hlcmUgYSBpcyBu b3QgbnVsbDsKIGV4cGxhaW4gKGNvc3RzIG9mZikgc2VsZWN0ICogZnJvbSBscCB3aGVyZSBh IGlzIG51bGw7CiBleHBsYWluIChjb3N0cyBvZmYpIHNlbGVjdCAqIGZyb20gbHAgd2hlcmUg YSA9ICdhJyBvciBhID0gJ2MnOwogZXhwbGFpbiAoY29zdHMgb2ZmKSBzZWxlY3QgKiBmcm9t IGxwIHdoZXJlIGEgaXMgbm90IG51bGwgYW5kIChhID0gJ2EnIG9yIGEgPSAnYycpOworCitT RVQgZW5hYmxlX29yX3RyYW5zZm9ybWF0aW9uID0gb247CitleHBsYWluIChjb3N0cyBvZmYp IHNlbGVjdCAqIGZyb20gbHAgd2hlcmUgYSA9ICdhJyBvciBhID0gJ2MnOworZXhwbGFpbiAo Y29zdHMgb2ZmKSBzZWxlY3QgKiBmcm9tIGxwIHdoZXJlIGEgaXMgbm90IG51bGwgYW5kIChh ID0gJ2EnIG9yIGEgPSAnYycpOworUkVTRVQgZW5hYmxlX29yX3RyYW5zZm9ybWF0aW9uOwor CiBleHBsYWluIChjb3N0cyBvZmYpIHNlbGVjdCAqIGZyb20gbHAgd2hlcmUgYSA8PiAnZyc7 CiBleHBsYWluIChjb3N0cyBvZmYpIHNlbGVjdCAqIGZyb20gbHAgd2hlcmUgYSA8PiAnYScg YW5kIGEgPD4gJ2QnOwogZXhwbGFpbiAoY29zdHMgb2ZmKSBzZWxlY3QgKiBmcm9tIGxwIHdo ZXJlIGEgbm90IGluICgnYScsICdkJyk7CkBAIC05OSw2ICsxMDUsMjIgQEAgZXhwbGFpbiAo Y29zdHMgb2ZmKSBzZWxlY3QgKiBmcm9tIHJscCB3aGVyZSBhID4gMSBhbmQgYSA+PTE1Owkv KiBybHAzIG9ud2FyZHMsIGkKIGV4cGxhaW4gKGNvc3RzIG9mZikgc2VsZWN0ICogZnJvbSBy bHAgd2hlcmUgYSA9IDEgYW5kIGEgPSAzOwkvKiBlbXB0eSAqLwogZXhwbGFpbiAoY29zdHMg b2ZmKSBzZWxlY3QgKiBmcm9tIHJscCB3aGVyZSAoYSA9IDEgYW5kIGEgPSAzKSBvciAoYSA+ IDEgYW5kIGEgPSAxNSk7CiAKKworU0VUIGVuYWJsZV9vcl90cmFuc2Zvcm1hdGlvbiA9IG9u OworZXhwbGFpbiAoY29zdHMgb2ZmKSBzZWxlY3QgKiBmcm9tIHJscCB3aGVyZSBhID0gMSBv ciBhID0gNzsKK2V4cGxhaW4gKGNvc3RzIG9mZikgc2VsZWN0ICogZnJvbSBybHAgd2hlcmUg YSA9IDEgb3IgYiA9ICdhYic7CitleHBsYWluIChjb3N0cyBvZmYpIHNlbGVjdCAqIGZyb20g cmxwIHdoZXJlIGEgPiAyMCBhbmQgYSA8IDI3OworZXhwbGFpbiAoY29zdHMgb2ZmKSBzZWxl Y3QgKiBmcm9tIHJscCB3aGVyZSBhID0gMjk7CitleHBsYWluIChjb3N0cyBvZmYpIHNlbGVj dCAqIGZyb20gcmxwIHdoZXJlIGEgPj0gMjk7CitleHBsYWluIChjb3N0cyBvZmYpIHNlbGVj dCAqIGZyb20gcmxwIHdoZXJlIGEgPCAxIG9yIChhID4gMjAgYW5kIGEgPCAyNSk7CitleHBs YWluIChjb3N0cyBvZmYpIHNlbGVjdCAqIGZyb20gcmxwIHdoZXJlIGEgPSAyMCBvciBhID0g NDA7CitleHBsYWluIChjb3N0cyBvZmYpIHNlbGVjdCAqIGZyb20gcmxwMyB3aGVyZSBhID0g MjA7ICAgLyogZW1wdHkgKi8KK2V4cGxhaW4gKGNvc3RzIG9mZikgc2VsZWN0ICogZnJvbSBy bHAgd2hlcmUgYSA+IDEgYW5kIGEgPSAxMDsJLyogb25seSBkZWZhdWx0ICovCitleHBsYWlu IChjb3N0cyBvZmYpIHNlbGVjdCAqIGZyb20gcmxwIHdoZXJlIGEgPiAxIGFuZCBhID49MTU7 CS8qIHJscDMgb253YXJkcywgaW5jbHVkaW5nIGRlZmF1bHQgKi8KK2V4cGxhaW4gKGNvc3Rz IG9mZikgc2VsZWN0ICogZnJvbSBybHAgd2hlcmUgYSA9IDEgYW5kIGEgPSAzOwkvKiBlbXB0 eSAqLworZXhwbGFpbiAoY29zdHMgb2ZmKSBzZWxlY3QgKiBmcm9tIHJscCB3aGVyZSAoYSA9 IDEgYW5kIGEgPSAzKSBvciAoYSA+IDEgYW5kIGEgPSAxNSk7CitSRVNFVCBlbmFibGVfb3Jf dHJhbnNmb3JtYXRpb247CisKIC0tIG11bHRpLWNvbHVtbiBrZXlzCiBjcmVhdGUgdGFibGUg bWMzcCAoYSBpbnQsIGIgaW50LCBjIGludCkgcGFydGl0aW9uIGJ5IHJhbmdlIChhLCBhYnMo YiksIGMpOwogY3JlYXRlIHRhYmxlIG1jM3BfZGVmYXVsdCBwYXJ0aXRpb24gb2YgbWMzcCBk ZWZhdWx0OwpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVncmVzcy9zcWwvdGlkc2Nhbi5zcWwg Yi9zcmMvdGVzdC9yZWdyZXNzL3NxbC90aWRzY2FuLnNxbAppbmRleCAzMTNlMGZiOWI2Ny4u MDQ5OWJlZGI5ZWIgMTAwNjQ0Ci0tLSBhL3NyYy90ZXN0L3JlZ3Jlc3Mvc3FsL3RpZHNjYW4u c3FsCisrKyBiL3NyYy90ZXN0L3JlZ3Jlc3Mvc3FsL3RpZHNjYW4uc3FsCkBAIC0yMiw2ICsy MiwxMiBAQCBFWFBMQUlOIChDT1NUUyBPRkYpCiBTRUxFQ1QgY3RpZCwgKiBGUk9NIHRpZHNj YW4gV0hFUkUgY3RpZCA9ICcoMCwyKScgT1IgJygwLDEpJyA9IGN0aWQ7CiBTRUxFQ1QgY3Rp ZCwgKiBGUk9NIHRpZHNjYW4gV0hFUkUgY3RpZCA9ICcoMCwyKScgT1IgJygwLDEpJyA9IGN0 aWQ7CiAKK1NFVCBlbmFibGVfb3JfdHJhbnNmb3JtYXRpb24gPSBvbjsKK0VYUExBSU4gKENP U1RTIE9GRikKK1NFTEVDVCBjdGlkLCAqIEZST00gdGlkc2NhbiBXSEVSRSBjdGlkID0gJygw LDIpJyBPUiAnKDAsMSknID0gY3RpZDsKK1NFTEVDVCBjdGlkLCAqIEZST00gdGlkc2NhbiBX SEVSRSBjdGlkID0gJygwLDIpJyBPUiAnKDAsMSknID0gY3RpZDsKK1JFU0VUIGVuYWJsZV9v cl90cmFuc2Zvcm1hdGlvbjsKKwogLS0gY3RpZCA9IFNjYWxhckFycmF5T3AgLSBpbXBsZW1l bnRlZCBhcyB0aWRzY2FuCiBFWFBMQUlOIChDT1NUUyBPRkYpCiBTRUxFQ1QgY3RpZCwgKiBG Uk9NIHRpZHNjYW4gV0hFUkUgY3RpZCA9IEFOWShBUlJBWVsnKDAsMSknLCAnKDAsMiknXTo6 dGlkW10pOwpkaWZmIC0tZ2l0IGEvc3JjL3Rvb2xzL3BnaW5kZW50L3R5cGVkZWZzLmxpc3Qg Yi9zcmMvdG9vbHMvcGdpbmRlbnQvdHlwZWRlZnMubGlzdAppbmRleCA2MWFkNDE3Y2RlNi4u OTQ0NTA5MzkzMzEgMTAwNjQ0Ci0tLSBhL3NyYy90b29scy9wZ2luZGVudC90eXBlZGVmcy5s aXN0CisrKyBiL3NyYy90b29scy9wZ2luZGVudC90eXBlZGVmcy5saXN0CkBAIC0xNzE0LDYg KzE3MTQsOCBAQCBOdW1lcmljVmFyCiBPTV91aW50MzIKIE9QCiBPU0FQZXJHcm91cFN0YXRl CitPckNsYXVzZUdyb3VwRW50cnkKK09yQ2xhdXNlR3JvdXBLZXkKIE9TQVBlclF1ZXJ5U3Rh dGUKIE9TSW5mbwogT1NTTENpcGhlcgo= --------------3caDxovxFfbd3FFYZrytmE8M--