From 62e9fa763bfc9b208d60b3de4ff44c569b70ce20 Mon Sep 17 00:00:00 2001 From: hferee Date: Tue, 3 Sep 2024 13:34:43 +0000 Subject: [PATCH] deploy: cae160f9d2b292c1bcac36ad0826606894ed0523 --- GL.GLS.DLW_wf_lex.html | 147 + GL.GLS.GLS_additive_cut.html | 618 + GL.GLS.GLS_calcs.html | 199 + GL.GLS.GLS_ctr.html | 1167 + GL.GLS.GLS_cut_elim.html | 88 + GL.GLS.GLS_dec.html | 318 + GL.GLS.GLS_der_dec.html | 1296 + GL.GLS.GLS_exch.html | 2278 ++ GL.GLS.GLS_export.html | 51 + GL.GLS.GLS_inv_ImpR_ImpL.html | 734 + GL.GLS.GLS_termination_measure.html | 864 + GL.GLS.GLS_wkn.html | 584 + GL.Interpolation.UIGL_And_Or_rules.html | 261 + GL.Interpolation.UIGL_Canopy.html | 534 + GL.Interpolation.UIGL_Canopy_ImpL.html | 108 + GL.Interpolation.UIGL_Canopy_ImpR.html | 241 + ...terpolation.UIGL_Canopy_nodupseq_perm.html | 405 + GL.Interpolation.UIGL_Def_measure.html | 163 + GL.Interpolation.UIGL_Diam_N_imp_UI.html | 99 + GL.Interpolation.UIGL_Diam_UI_imp_N.html | 724 + ...terpolation.UIGL_Diam_UI_imp_N_prelim.html | 319 + GL.Interpolation.UIGL_LexSeq.html | 262 + GL.Interpolation.UIGL_N_imp_UI.html | 258 + GL.Interpolation.UIGL_PermutationT.html | 195 + GL.Interpolation.UIGL_PermutationTS.html | 368 + GL.Interpolation.UIGL_UIDiam_N.html | 113 + GL.Interpolation.UIGL_UIOne.html | 233 + GL.Interpolation.UIGL_UIThree.html | 808 + GL.Interpolation.UIGL_UITwo.html | 256 + GL.Interpolation.UIGL_UI_inter.html | 631 + GL.Interpolation.UIGL_UI_prelims.html | 767 + GL.Interpolation.UIGL_basics.html | 137 + GL.Interpolation.UIGL_braga.html | 497 + GL.Interpolation.UIGL_irred_high_level.html | 144 + GL.Interpolation.UIGL_irred_short.html | 334 + GL.Interpolation.UIGL_nodupseq.html | 641 + General.List_lemmasT.html | 1328 + General.ddT.html | 915 + General.dd_fc.html | 865 + General.existsT.html | 50 + General.gen.html | 398 + General.genT.html | 688 + General.gen_seq.html | 736 + General.gen_tacs.html | 275 + General.general_export.html | 54 + General.gentree.html | 592 + General.gstep.html | 809 + General.rtcT.html | 154 + General.swappedT.html | 437 + General.univ_gen_ext.html | 624 + General.univ_gen_mod.html | 228 + ISL.Cut.html | 356 + ISL.DecisionProcedure.html | 663 + ISL.Environments.html | 874 + ISL.Formulas.html | 238 + ISL.Optimizations.html | 820 + ISL.Order.html | 497 + ISL.PropQuantifiers.html | 1209 + ISL.SequentProps.html | 1019 + ISL.Sequents.html | 303 + ISL.Simp.html | 856 + K.Interpolation.K_Craig_Interp.html | 644 + K.Interpolation.UIK_Canopy.html | 623 + K.Interpolation.UIK_Def_measure.html | 163 + K.Interpolation.UIK_UIOne.html | 166 + K.Interpolation.UIK_UIThree.html | 709 + K.Interpolation.UIK_UITwo.html | 153 + K.Interpolation.UIK_UI_prelims.html | 623 + K.Interpolation.UIK_basics.html | 293 + K.Interpolation.UIK_braga.html | 335 + K.Interpolation.UIK_irred_high_level.html | 144 + K.Interpolation.UIK_irred_short.html | 332 + K.KS.KS_additive_cut.html | 668 + K.KS.KS_calc.html | 150 + K.KS.KS_ctr.html | 955 + K.KS.KS_cut_elim.html | 87 + K.KS.KS_dec.html | 296 + K.KS.KS_exch.html | 495 + K.KS.KS_exch_ImpL.html | 589 + K.KS.KS_exch_ImpR.html | 385 + K.KS.KS_exch_KR.html | 111 + K.KS.KS_exch_prelims.html | 538 + K.KS.KS_export.html | 50 + K.KS.KS_inv_ImpR_ImpL.html | 734 + K.KS.KS_termination.html | 579 + K.KS.KS_termination_ImpL.html | 286 + K.KS.KS_termination_ImpR.html | 392 + K.KS.KS_termination_KR.html | 146 + K.KS.KS_termination_init.html | 81 + K.KS.KS_termination_measure.html | 171 + K.KS.KS_termination_prelims.html | 411 + K.KS.KS_wkn.html | 518 + Syntax.CML_Syntax.html | 277 + Syntax.Syntax_export.html | 43 + Syntax.list_lems.html | 340 + Syntax.remove_list_lems.html | 688 + UIML_extraction.UIML_extraction.html | 94 + config.js | 72 + coqdoc.css | 244 + coqdocjs.css | 249 + coqdocjs.js | 189 + demo.html | 139 + index.html | 10 + indexpage.html | 6674 ++++ toc.html | 500 + uiml_demo.bc.js | 33245 ++++++++++++++++ 106 files changed, 86421 insertions(+) create mode 100644 GL.GLS.DLW_wf_lex.html create mode 100644 GL.GLS.GLS_additive_cut.html create mode 100644 GL.GLS.GLS_calcs.html create mode 100644 GL.GLS.GLS_ctr.html create mode 100644 GL.GLS.GLS_cut_elim.html create mode 100644 GL.GLS.GLS_dec.html create mode 100644 GL.GLS.GLS_der_dec.html create mode 100644 GL.GLS.GLS_exch.html create mode 100644 GL.GLS.GLS_export.html create mode 100644 GL.GLS.GLS_inv_ImpR_ImpL.html create mode 100644 GL.GLS.GLS_termination_measure.html create mode 100644 GL.GLS.GLS_wkn.html create mode 100644 GL.Interpolation.UIGL_And_Or_rules.html create mode 100644 GL.Interpolation.UIGL_Canopy.html create mode 100644 GL.Interpolation.UIGL_Canopy_ImpL.html create mode 100644 GL.Interpolation.UIGL_Canopy_ImpR.html create mode 100644 GL.Interpolation.UIGL_Canopy_nodupseq_perm.html create mode 100644 GL.Interpolation.UIGL_Def_measure.html create mode 100644 GL.Interpolation.UIGL_Diam_N_imp_UI.html create mode 100644 GL.Interpolation.UIGL_Diam_UI_imp_N.html create mode 100644 GL.Interpolation.UIGL_Diam_UI_imp_N_prelim.html create mode 100644 GL.Interpolation.UIGL_LexSeq.html create mode 100644 GL.Interpolation.UIGL_N_imp_UI.html create mode 100644 GL.Interpolation.UIGL_PermutationT.html create mode 100644 GL.Interpolation.UIGL_PermutationTS.html create mode 100644 GL.Interpolation.UIGL_UIDiam_N.html create mode 100644 GL.Interpolation.UIGL_UIOne.html create mode 100644 GL.Interpolation.UIGL_UIThree.html create mode 100644 GL.Interpolation.UIGL_UITwo.html create mode 100644 GL.Interpolation.UIGL_UI_inter.html create mode 100644 GL.Interpolation.UIGL_UI_prelims.html create mode 100644 GL.Interpolation.UIGL_basics.html create mode 100644 GL.Interpolation.UIGL_braga.html create mode 100644 GL.Interpolation.UIGL_irred_high_level.html create mode 100644 GL.Interpolation.UIGL_irred_short.html create mode 100644 GL.Interpolation.UIGL_nodupseq.html create mode 100644 General.List_lemmasT.html create mode 100644 General.ddT.html create mode 100644 General.dd_fc.html create mode 100644 General.existsT.html create mode 100644 General.gen.html create mode 100644 General.genT.html create mode 100644 General.gen_seq.html create mode 100644 General.gen_tacs.html create mode 100644 General.general_export.html create mode 100644 General.gentree.html create mode 100644 General.gstep.html create mode 100644 General.rtcT.html create mode 100644 General.swappedT.html create mode 100644 General.univ_gen_ext.html create mode 100644 General.univ_gen_mod.html create mode 100644 ISL.Cut.html create mode 100644 ISL.DecisionProcedure.html create mode 100644 ISL.Environments.html create mode 100644 ISL.Formulas.html create mode 100644 ISL.Optimizations.html create mode 100644 ISL.Order.html create mode 100644 ISL.PropQuantifiers.html create mode 100644 ISL.SequentProps.html create mode 100644 ISL.Sequents.html create mode 100644 ISL.Simp.html create mode 100644 K.Interpolation.K_Craig_Interp.html create mode 100644 K.Interpolation.UIK_Canopy.html create mode 100644 K.Interpolation.UIK_Def_measure.html create mode 100644 K.Interpolation.UIK_UIOne.html create mode 100644 K.Interpolation.UIK_UIThree.html create mode 100644 K.Interpolation.UIK_UITwo.html create mode 100644 K.Interpolation.UIK_UI_prelims.html create mode 100644 K.Interpolation.UIK_basics.html create mode 100644 K.Interpolation.UIK_braga.html create mode 100644 K.Interpolation.UIK_irred_high_level.html create mode 100644 K.Interpolation.UIK_irred_short.html create mode 100644 K.KS.KS_additive_cut.html create mode 100644 K.KS.KS_calc.html create mode 100644 K.KS.KS_ctr.html create mode 100644 K.KS.KS_cut_elim.html create mode 100644 K.KS.KS_dec.html create mode 100644 K.KS.KS_exch.html create mode 100644 K.KS.KS_exch_ImpL.html create mode 100644 K.KS.KS_exch_ImpR.html create mode 100644 K.KS.KS_exch_KR.html create mode 100644 K.KS.KS_exch_prelims.html create mode 100644 K.KS.KS_export.html create mode 100644 K.KS.KS_inv_ImpR_ImpL.html create mode 100644 K.KS.KS_termination.html create mode 100644 K.KS.KS_termination_ImpL.html create mode 100644 K.KS.KS_termination_ImpR.html create mode 100644 K.KS.KS_termination_KR.html create mode 100644 K.KS.KS_termination_init.html create mode 100644 K.KS.KS_termination_measure.html create mode 100644 K.KS.KS_termination_prelims.html create mode 100644 K.KS.KS_wkn.html create mode 100644 Syntax.CML_Syntax.html create mode 100644 Syntax.Syntax_export.html create mode 100644 Syntax.list_lems.html create mode 100644 Syntax.remove_list_lems.html create mode 100644 UIML_extraction.UIML_extraction.html create mode 100644 config.js create mode 100644 coqdoc.css create mode 100644 coqdocjs.css create mode 100644 coqdocjs.js create mode 100644 demo.html create mode 100644 index.html create mode 100644 indexpage.html create mode 100644 toc.html create mode 100644 uiml_demo.bc.js diff --git a/GL.GLS.DLW_wf_lex.html b/GL.GLS.DLW_wf_lex.html new file mode 100644 index 0000000..0db5f88 --- /dev/null +++ b/GL.GLS.DLW_wf_lex.html @@ -0,0 +1,147 @@ + + + + + + + + + + + + + +
+
+

GL.GLS.DLW_wf_lex

+ +
+(* Modification of the file by Dominique. *)
+ +
+(**************************************************************)
+(*   Copyright Dominique Larchey-Wendling *                 *)
+(*                                                            *)
+(*                             * Affiliation LORIA -- CNRS  *)
+(**************************************************************)
+(*      This file is distributed under the terms of the       *)
+(*         CeCILL v2 FREER SOFTWARE LICENSE AGREEMENT         *)
+(**************************************************************)
+ +
+Require Import List Arith Wellfounded.
+Import ListNotations.
+ +
+Set Implicit Arguments.
+ +
+Section measure_rect.
+ +
+  Variable (X : Type) (m : X -> nat) (P : X -> Type).
+ +
+  Hypothesis F : forall x, (forall y, m y < m x -> P y) -> P x.
+ +
+  Definition measure_rect x : P x.
+  Proof.
+    cut (Acc (fun x y => m x < m y) x); [ revert x | ].
+    + refine (
+        fix loop x Dx := @F x (fun y Dy => loop y _)
+      ).
+      apply (Acc_inv Dx), Dy.
+    + apply wf_inverse_image with (f := m), lt_wf.
+  Qed.
+ +
+End measure_rect.
+ +
+Tactic Notation "induction" "on" hyp(x) "as" ident(IH) "with" "measure" uconstr(f) :=
+  pattern x; revert x; apply measure_rect with (m := fun x => f); intros x IH.
+ +
+Section lex_wf.
+ +
+  Variable (X : Type) (R : X -> X -> Prop) (Rwf : well_founded R).
+ +
+  Reserved Notation "l '<lex' m" (at level 70). (* for lexicographic product *)
+ +
+  Inductive lex : list X -> list X -> Prop :=
+    | lex_skip x l m : l <lex m -> x::l <lex x::m
+    | lex_cons x y l m : length l = length m -> R x y -> x::l <lex y::m
+  where "l <lex m" := (lex l m).
+ +
+  Fact lex_length l m : l <lex m -> length l = length m.
+  Proof. induction 1; simpl; auto. Qed.
+ +
+  Fact lex_cons_inv l m :
+          l <lex m
+       -> match m with
+            | [] => False
+            | y::m =>
+            match l with
+              | [] => False
+              | x::l => x = y /\ lex l m
+                     \/ R x y /\ length l = length m
+            end
+          end.
+  Proof. inversion 1; auto. Qed.
+ +
+  Theorem lex_wf : well_founded lex.
+  Proof.
+    intros m; induction on m as IHm with measure (length m).
+    destruct m as [ | y m ].
+    + constructor; intros l Hl; apply lex_cons_inv in Hl; easy.
+    + revert m IHm.
+      induction y as [ y IHy' ] using (well_founded_induction Rwf).
+      intros m IHm.
+      assert (Acc lex m) as Hm.
+      1: apply IHm; simpl; auto.
+      assert (forall x l, R x y -> length l = length m -> Acc lex (x::l)) as IHy.
+      1: { intros x l Hx Hl; apply IHy'; auto.
+           intros; apply IHm.
+           simpl in *; rewrite <- Hl; auto. }
+      clear IHy' IHm.
+      revert Hm IHy.
+      induction 1 as [ m Hm IHm ]; intros IHy.
+      constructor; intros l Hl; apply lex_cons_inv in Hl.
+      destruct l as [ | x l ]; try tauto.
+      destruct Hl as [ (-> & Hl) | (Hx & Hl) ].
+      * apply IHm; auto.
+        apply lex_length in Hl as ->; auto.
+      * apply IHy; auto.
+  Qed.
+ +
+End lex_wf.
+
+
+ +
+ + + diff --git a/GL.GLS.GLS_additive_cut.html b/GL.GLS.GLS_additive_cut.html new file mode 100644 index 0000000..abb2169 --- /dev/null +++ b/GL.GLS.GLS_additive_cut.html @@ -0,0 +1,618 @@ + + + + + + + + + + + + + +
+
+

GL.GLS.GLS_additive_cut

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat Arith.
+Require Import Lia.
+ +
+Require Import GLS_calcs.
+Require Import GLS_termination_measure.
+Require Import GLS_exch.
+Require Import GLS_ctr.
+Require Import GLS_wkn.
+Require Import GLS_dec.
+Require Import GLS_inv_ImpR_ImpL.
+ +
+Set Implicit Arguments.
+ +
+Theorem GLS_cut_adm_main : forall n A s Γ0 Γ1 Δ0 Δ1,
+                      (n = size A) ->
+                      (s = (Γ0 ++ Γ1, Δ0 ++ Δ1)) ->
+                      (GLS_prv (Γ0 ++ Γ1, Δ0 ++ A :: Δ1)) ->
+                      (GLS_prv (Γ0 ++ A :: Γ1, Δ0 ++ Δ1)) ->
+                      (GLS_prv s).
+Proof.
+(* The proof is by induction on, first, size of the cut formula and on, second, the mhd
+   of the sequent-conclusion. *)

+induction n as [n PIH] using (well_founded_induction_type lt_wf).
+intros A s ; revert s A.
+refine (less_thanS_strong_inductionT _ _); intros s SIH.
+intros A Γ0 Γ1 Δ0 Δ1 size E D0 D1. inversion D0. inversion H.
+inversion D1. inversion H0.
+ +
+inversion X ; subst.
+ +
+(* Left rule is IdP *)
+- inversion H1. subst. apply list_split_form in H3. repeat destruct H3.
+  * destruct s.
+    + repeat destruct p. subst. inversion X1.
+    (* Right rule is IdP *)
+    { inversion H. subst. assert (J0 : InT (# P0) (Γ0 ++ # P :: Γ1)). rewrite <- H6. apply InT_or_app.
+      right. apply InT_eq. apply InT_app_or in J0. destruct J0.
+      - apply InT_split in i. destruct i. destruct s. subst. rewrite H2. repeat rewrite <- app_assoc.
+        assert (IdPRule [] (x ++ (# P0 :: x0) ++ Γ1, Δ2 ++ # P0 :: Δ3)). apply IdPRule_I. apply IdP in H0.
+        apply derI with (ps:=[]) ; auto.
+      - inversion i.
+        + inversion H3. subst. apply derI with (ps:=[]) ; auto. apply IdP ; apply IdPRule_I.
+        + apply InT_split in H3. destruct H3. destruct s. subst.
+          assert (J0 : InT (# P0) (Γ2 ++ # P :: Γ3)). rewrite H2. apply InT_or_app.
+          right. apply InT_or_app. right. apply InT_eq. apply InT_split in J0. destruct J0. destruct s.
+          rewrite e. apply derI with (ps:=[]) ; auto. apply IdP ; apply IdPRule_I. }
+    (* Right rule is BotL *)
+    { inversion H. subst. assert (J0 : InT () (Γ0 ++ # P :: Γ1)). rewrite <- H6. apply InT_or_app.
+      right. apply InT_eq. apply InT_app_or in J0. destruct J0.
+      - apply InT_split in i. destruct i. destruct s. subst. rewrite H2. rewrite <- app_assoc.
+        assert (BotLRule [] (x ++ ( :: x0) ++ Γ1, Δ0 ++ Δ1)). apply BotLRule_I. apply BotL in H0.
+        apply derI with (ps:=[]) ; auto.
+      - inversion i.
+        + inversion H3.
+        + apply InT_split in H3. destruct H3. destruct s. subst. rewrite H2. rewrite app_assoc.
+          assert (BotLRule [] ((Γ0 ++ x) ++ :: x0, Δ0 ++ Δ1)). apply BotLRule_I. apply BotL in H0.
+          pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) ((Γ0 ++ x) ++ :: x0, Δ0 ++ Δ1) H0 X0). assumption. }
+    (* Right rule is ImpR *)
+    { inversion H. subst. assert (InT # P (Γ0 ++ Γ1)). rewrite <- H2. apply InT_or_app.
+      right. apply InT_eq. apply InT_app_or in H0. destruct H0.
+      - apply InT_split in i. destruct i.
+        destruct s. subst. repeat rewrite <- app_assoc in D1. simpl in D1.
+        assert (E0: derrec_height D1 = derrec_height D1). reflexivity.
+        assert (J0 : ctr_L # P (x ++ # P :: x0 ++ # P :: Γ1, Δ0 ++ Δ1)
+        (x ++ # P :: x0 ++ Γ1, Δ0 ++ Δ1)). apply ctr_LI.
+        pose (@GLS_hpadm_ctr_L (derrec_height D1) (x ++ # P :: x0 ++ # P :: Γ1, Δ0 ++ Δ1)
+        D1 E0 (x ++ # P :: x0 ++ Γ1, Δ0 ++ Δ1) (# P) J0). destruct s. clear l. rewrite H2.
+        rewrite <- app_assoc. rewrite H7. assumption.
+      - apply InT_split in i. destruct i. destruct s. subst.
+        assert (E0: derrec_height D1 = derrec_height D1). reflexivity.
+        assert (J0 : ctr_L # P (Γ0 ++ # P :: x ++ # P :: x0, Δ0 ++ Δ1)
+        (Γ0 ++ # P :: x ++ x0, Δ0 ++ Δ1)). apply ctr_LI.
+        pose (@GLS_hpadm_ctr_L (derrec_height D1) (Γ0 ++ # P :: x ++ # P :: x0, Δ0 ++ Δ1)
+        D1 E0 (Γ0 ++ # P :: x ++ x0, Δ0 ++ Δ1) (# P) J0). destruct s. clear l. rewrite H2.
+        assert (J5 : list_exch_L (Γ0 ++ # P :: x ++ x0, Δ0 ++ Δ1) (Γ0 ++ x ++ # P :: x0, Δ0 ++ Δ1)).
+        assert (Γ0 ++ # P :: x ++ x0 = Γ0 ++ [# P] ++ x ++ [] ++ x0). reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ x ++ # P :: x0 = Γ0 ++ [] ++ x ++ [# P] ++ x0). reflexivity. rewrite H0. clear H0.
+        apply list_exch_LI. pose (GLS_adm_list_exch_L x1 J5). rewrite H7. assumption. }
+    (* Right rule is ImpL *)
+    { inversion H. subst. assert (InT # P (Γ0 ++ Γ1)). rewrite <- H2. apply InT_or_app.
+      right. apply InT_eq. apply InT_app_or in H0. destruct H0.
+      - apply InT_split in i. destruct i.
+        destruct s. subst. repeat rewrite <- app_assoc in D1. simpl in D1.
+        assert (E0: derrec_height D1 = derrec_height D1). reflexivity.
+        assert (J0 : ctr_L # P (x ++ # P :: x0 ++ # P :: Γ1, Δ0 ++ Δ1)
+        (x ++ # P :: x0 ++ Γ1, Δ0 ++ Δ1)). apply ctr_LI.
+        pose (@GLS_hpadm_ctr_L (derrec_height D1) (x ++ # P :: x0 ++ # P :: Γ1, Δ0 ++ Δ1)
+        D1 E0 (x ++ # P :: x0 ++ Γ1, Δ0 ++ Δ1) (# P) J0). destruct s. clear l. rewrite H2.
+        rewrite <- app_assoc. rewrite H7. assumption.
+      - apply InT_split in i. destruct i. destruct s. subst.
+        assert (E0: derrec_height D1 = derrec_height D1). reflexivity.
+        assert (J0 : ctr_L # P (Γ0 ++ # P :: x ++ # P :: x0, Δ0 ++ Δ1)
+        (Γ0 ++ # P :: x ++ x0, Δ0 ++ Δ1)). apply ctr_LI.
+        pose (@GLS_hpadm_ctr_L (derrec_height D1) (Γ0 ++ # P :: x ++ # P :: x0, Δ0 ++ Δ1)
+        D1 E0 (Γ0 ++ # P :: x ++ x0, Δ0 ++ Δ1) (# P) J0). destruct s. clear l. rewrite H2.
+        assert (J5 : list_exch_L (Γ0 ++ # P :: x ++ x0, Δ0 ++ Δ1) (Γ0 ++ x ++ # P :: x0, Δ0 ++ Δ1)).
+        assert (Γ0 ++ # P :: x ++ x0 = Γ0 ++ [# P] ++ x ++ [] ++ x0). reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ x ++ # P :: x0 = Γ0 ++ [] ++ x ++ [# P] ++ x0). reflexivity. rewrite H0. clear H0.
+        apply list_exch_LI. pose (GLS_adm_list_exch_L x1 J5). rewrite H7. assumption. }
+    (* Right rule is GLR *)
+    { inversion X3. subst. assert (InT # P (Γ0 ++ Γ1)). rewrite <- H2. apply InT_or_app.
+      right. apply InT_eq. apply InT_app_or in H. destruct H.
+      - apply InT_split in i. destruct i.
+        destruct s. subst. repeat rewrite <- app_assoc in D1. simpl in D1.
+        assert (E0: derrec_height D1 = derrec_height D1). reflexivity.
+        assert (J0 : ctr_L # P (x ++ # P :: x0 ++ # P :: Γ1, Δ0 ++ Δ1)
+        (x ++ # P :: x0 ++ Γ1, Δ0 ++ Δ1)). apply ctr_LI.
+        pose (@GLS_hpadm_ctr_L (derrec_height D1) (x ++ # P :: x0 ++ # P :: Γ1, Δ0 ++ Δ1)
+        D1 E0 (x ++ # P :: x0 ++ Γ1, Δ0 ++ Δ1) (# P) J0). destruct s. clear l. rewrite H2.
+        rewrite <- app_assoc. rewrite H6. assumption.
+      - apply InT_split in i. destruct i. destruct s. subst.
+        assert (E0: derrec_height D1 = derrec_height D1). reflexivity.
+        assert (J0 : ctr_L # P (Γ0 ++ # P :: x ++ # P :: x0, Δ0 ++ Δ1)
+        (Γ0 ++ # P :: x ++ x0, Δ0 ++ Δ1)). apply ctr_LI.
+        pose (@GLS_hpadm_ctr_L (derrec_height D1) (Γ0 ++ # P :: x ++ # P :: x0, Δ0 ++ Δ1)
+        D1 E0 (Γ0 ++ # P :: x ++ x0, Δ0 ++ Δ1) (# P) J0). destruct s. clear l. rewrite H2.
+        assert (J5 : list_exch_L (Γ0 ++ # P :: x ++ x0, Δ0 ++ Δ1) (Γ0 ++ x ++ # P :: x0, Δ0 ++ Δ1)).
+        assert (Γ0 ++ # P :: x ++ x0 = Γ0 ++ [# P] ++ x ++ [] ++ x0). reflexivity. rewrite H. clear H.
+        assert (Γ0 ++ x ++ # P :: x0 = Γ0 ++ [] ++ x ++ [# P] ++ x0). reflexivity. rewrite H. clear H.
+        apply list_exch_LI. pose (GLS_adm_list_exch_L x1 J5). rewrite H6. assumption. }
+    + repeat destruct s. repeat destruct p. subst. assert (IdPRule [] (Γ2 ++ # P :: Γ3, (Δ0 ++ x0) ++ # P :: Δ3)).
+      apply IdPRule_I. rewrite <- app_assoc in H. apply IdP in H.
+      pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[]) (Γ2 ++ # P :: Γ3, Δ0 ++ x0 ++ # P :: Δ3) H X0). assumption.
+  * repeat destruct s. repeat destruct p. subst. assert (IdPRule [] (Γ2 ++ # P :: Γ3, Δ2 ++ # P :: x ++ Δ1)).
+    apply IdPRule_I. apply IdP in H. rewrite <- app_assoc.
+    apply derI with (ps:=[]) ; auto.
+ +
+(* Left rule is BotL *)
+- inversion H1. subst. assert (BotLRule [] (Γ2 ++ :: Γ3, Δ0 ++ Δ1)).
+  apply BotLRule_I. apply BotL in H. apply derI with (ps:=[]) ; auto.
+ +
+(* Left rule is ImpR *)
+- inversion H1. subst. apply list_split_form in H3. destruct H3.
+  * destruct s.
+    + repeat destruct p. subst. inversion X1.
+      (* Right rule is IdP *)
+      { inversion H. subst. assert (J0 : InT (# P) (Γ0 ++ (A0 --> B) :: Γ1)). rewrite <- H6. apply InT_or_app.
+        right. apply InT_eq. apply InT_app_or in J0. destruct J0.
+        - apply InT_split in i. destruct i. destruct s. subst. rewrite H2. rewrite <- app_assoc.
+          assert (IdPRule [] (x ++ (# P :: x0) ++ Γ1, Δ2 ++ # P :: Δ3)). apply IdPRule_I. apply IdP in H0.
+          apply derI with (ps:=[]) ; auto.
+        - inversion i.
+          * inversion H3.
+          * apply InT_split in H3. destruct H3. destruct s. subst. rewrite H2. rewrite app_assoc.
+            assert (IdPRule [] ((Γ0 ++ x) ++ # P :: x0, Δ2 ++ # P :: Δ3)). apply IdPRule_I. apply IdP in H0.
+            apply derI with (ps:=[]) ; auto. }
+      (* Right rule is BotL *)
+      { inversion H. subst. rewrite H2. assert (J0 : InT () (Γ0 ++ (A0 --> B) :: Γ1)). rewrite <- H6. apply InT_or_app.
+        right. apply InT_eq. apply InT_app_or in J0. destruct J0.
+        - apply InT_split in i. destruct i. destruct s. subst. rewrite <- app_assoc.
+          assert (BotLRule [] (x ++ ( :: x0) ++ Γ1, Δ0 ++ Δ1)). apply BotLRule_I. apply BotL in H0.
+          apply derI with (ps:=[]) ; auto.
+        - inversion i.
+          * inversion H3.
+          * apply InT_split in H3. destruct H3. destruct s. subst. rewrite app_assoc.
+            assert (BotLRule [] ((Γ0 ++ x) ++ :: x0, Δ0 ++ Δ1)). apply BotLRule_I. apply BotL in H0.
+            apply derI with (ps:=[]) ; auto. }
+      (* Right rule is ImpR *)
+      { inversion H. subst. inversion X0. inversion X2. subst. clear X4. clear X6. rewrite <- H7 in D1.
+        assert (J1 : list_exch_L (Γ4 ++ A :: Γ5, Δ2 ++ B0 :: Δ3) (A :: Γ0 ++ A0 --> B :: Γ1, Δ2 ++ B0 :: Δ3)).
+        assert (Γ4 ++ A :: Γ5 = [] ++ [] ++ Γ4 ++ [A] ++ Γ5). reflexivity. rewrite H0. clear H0.
+        assert (A :: Γ0 ++ A0 --> B :: Γ1 = [] ++ [A] ++ Γ4 ++ [] ++ Γ5). rewrite <- H6. reflexivity.
+        rewrite H0. clear H0. apply list_exch_LI. pose (d:=GLS_adm_list_exch_L X5 J1). rewrite H2.
+        assert (ImpRRule [([] ++ A :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3)] ([] ++ Γ0 ++ Γ1, Δ2 ++ A --> B0 :: Δ3)). apply ImpRRule_I.
+        simpl in H0.
+        assert (J31: GLS_rules [(A :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3)] (Γ0 ++ Γ1, Δ2 ++ A --> B0 :: Δ3)).
+        apply ImpR ; try assumption.
+        assert (J21: In (A :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3) [(A :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3)]). apply in_eq.
+        assert (J3: (A :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3) << (Γ0 ++ Γ1, Δ0 ++ Δ1)). apply ImpR_applic_reduces_measure ; rewrite <- H7 ; auto.
+        assert (J5: size (A0 --> B) = size (A0 --> B)). reflexivity.
+        assert (J7 : (A :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3) = ((A :: Γ0) ++ Γ1, [] ++ Δ2 ++ B0 :: Δ3)). reflexivity.
+        pose (d0:=@SIH _ J3 (A0 --> B) (A :: Γ0) Γ1 [] (Δ2 ++ B0 :: Δ3) J5 J7). simpl in d0.
+        assert (J8 : list_exch_R (Γ0 ++ Γ1, Δ0 ++ A0 --> B :: Δ1) (Γ0 ++ Γ1, A0 --> B :: Δ2 ++ A --> B0 :: Δ3)).
+        assert (Δ0 ++ A0 --> B :: Δ1 = [] ++ [] ++ Δ0 ++ [A0 --> B] ++ Δ1). reflexivity. rewrite H3. clear H3.
+        assert (A0 --> B :: Δ2 ++ A --> B0 :: Δ3 = [] ++ [A0 --> B] ++ Δ0 ++ [] ++ Δ1). rewrite H7.
+        reflexivity. rewrite H3. clear H3. apply list_exch_RI. pose (d1:=GLS_adm_list_exch_R D0 J8).
+        assert (ImpRRule [([] ++ A :: Γ0 ++ Γ1, (A0 --> B :: Δ2) ++ B0 :: Δ3)] ([] ++ Γ0 ++ Γ1, (A0 --> B :: Δ2) ++ A --> B0 :: Δ3)).
+        apply ImpRRule_I. simpl in H3. pose (d2:=ImpR_inv d1 H3). pose (d3:=d0 d2 d).
+        apply ImpR in H0 ; try intro ; try apply f ; try rewrite <- H7 ; try auto ; try assumption.
+        pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[(A :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3)]) (Γ0 ++ Γ1, Δ2 ++ A --> B0 :: Δ3) H0). apply d4. apply dlCons ; auto. apply dlNil. }
+      (* Right rule is ImpL *)
+      { inversion H. subst. inversion X0. inversion X2. subst. clear X4. inversion X6. subst. clear X7.
+        clear X6. apply list_split_form in H6. destruct H6.
+        - destruct s.
+          * repeat destruct p. inversion e0. subst. rewrite H2.
+            assert (J1 : list_exch_L (Γ2 ++ A0 :: Γ3, Δ0 ++ B :: Δ1) (A0 :: Γ0 ++ Γ1, Δ0 ++ B :: Δ1)).
+            assert (Γ2 ++ A0 :: Γ3 = [] ++ [] ++ Γ2 ++ [A0] ++ Γ3). reflexivity. rewrite H0. clear H0.
+            assert (A0 :: Γ0 ++ Γ1 = [] ++ [A0] ++ Γ2 ++ [] ++ Γ3). rewrite <- H2. reflexivity.
+            rewrite H0. clear H0. apply list_exch_LI. pose (d:=GLS_adm_list_exch_L X3 J1).
+            assert (J2 : list_exch_R (A0 :: Γ0 ++ Γ1, Δ0 ++ B :: Δ1) (A0 :: Γ0 ++ Γ1, B :: Δ2 ++ Δ3)).
+            assert (Δ0 ++ B :: Δ1 = [] ++ [] ++ Δ0 ++ [B] ++ Δ1). reflexivity. rewrite H0. clear H0.
+            assert (B :: Δ2 ++ Δ3 = [] ++ [B] ++ Δ0 ++ [] ++ Δ1). rewrite H7. reflexivity. rewrite H0. clear H0.
+            apply list_exch_RI. pose (d0:=GLS_adm_list_exch_R d J2).
+            assert (J3: size A0 < size (A0 --> B)). simpl. lia.
+            assert (J4: size A0 = size A0). reflexivity.
+            assert (J6: (Γ2 ++ Γ3, B :: Δ2 ++ Δ3) = ([] ++ Γ2 ++ Γ3, (B :: Δ2) ++ Δ3)). reflexivity.
+            pose (d1:=PIH _ J3 A0 (Γ2 ++ Γ3, B :: Δ2 ++ Δ3) [] (Γ2 ++ Γ3) (B :: Δ2) Δ3 J4 J6). simpl in d1.
+            assert (J7 : wkn_R B (Γ2 ++ Γ3, Δ2 ++ A0 :: Δ3) (Γ2 ++ Γ3, B :: Δ2 ++ A0 :: Δ3)).
+            assert ((Γ2 ++ Γ3, Δ2 ++ A0 :: Δ3) = (Γ2 ++ Γ3, [] ++ Δ2 ++ A0 :: Δ3)). reflexivity. rewrite H0. clear H0.
+            assert ((Γ2 ++ Γ3, B :: Δ2 ++ A0 :: Δ3) = (Γ2 ++ Γ3, [] ++ B :: Δ2 ++ A0 :: Δ3)).
+            reflexivity. rewrite H0. clear H0. apply wkn_RI. rewrite <- H2 in X5.
+            assert (J8 : derrec_height X5 = derrec_height X5).
+            reflexivity. pose (GLS_wkn_R X5 J8 J7). destruct s. rewrite <- H2 in d0. pose (d2:=d1 x d0).
+            assert (J9: size B < size (A0 --> B)). simpl. lia.
+            assert (J10: size B = size B). reflexivity.
+            assert (J12: (Γ2 ++ Γ3, Δ2 ++ Δ3) = (Γ2 ++ Γ3, [] ++ Δ2 ++ Δ3)). reflexivity.
+            pose (d3:=PIH _ J9 B (Γ2 ++ Γ3, Δ2 ++ Δ3) Γ2 Γ3 [] (Δ2 ++ Δ3) J10 J12). simpl in d3.
+            assert (J30 : list_exch_L (Γ0 ++ B :: Γ1, Δ2 ++ Δ3) (B :: Γ2 ++ Γ3, Δ2 ++ Δ3)).
+            assert (Γ0 ++ B :: Γ1 = [] ++ [] ++ Γ0 ++ [B] ++ Γ1). reflexivity. rewrite H0. clear H0.
+            assert (B :: Γ2 ++ Γ3 = [] ++ [B] ++ Γ0 ++ [] ++ Γ1). rewrite H2. reflexivity.
+            rewrite H0. clear H0. apply list_exch_LI. pose (d4:=GLS_adm_list_exch_L X4 J30).
+            assert (J40 : list_exch_L (B :: Γ2 ++ Γ3, Δ2 ++ Δ3) (Γ2 ++ B :: Γ3, Δ2 ++ Δ3)).
+            assert (Γ2 ++ B :: Γ3 = [] ++ [] ++ Γ2 ++ [B] ++ Γ3). reflexivity. rewrite H0. clear H0.
+            assert (B :: Γ2 ++ Γ3 = [] ++ [B] ++ Γ2 ++ [] ++ Γ3). reflexivity. rewrite H0. clear H0.
+            apply list_exch_LI. pose (d5:=GLS_adm_list_exch_L d4 J40). pose (d3 d2 d5). rewrite <- H2. assumption.
+          * repeat destruct s. repeat destruct p. subst. rewrite H2. repeat rewrite <- app_assoc in X5. repeat rewrite <- app_assoc in X4.
+            simpl in X4. simpl in X5.
+            assert (J1 : list_exch_R (Γ0 ++ x0 ++ A --> B0 :: Γ5, Δ0 ++ A0 --> B :: Δ1) (Γ0 ++ x0 ++ A --> B0 :: Γ5, A0 --> B :: Δ2 ++ Δ3)).
+            assert (Δ0 ++ A0 --> B :: Δ1 = [] ++ [] ++ Δ0 ++ [A0 --> B] ++ Δ1). reflexivity. rewrite H0. clear H0.
+            assert (A0 --> B :: Δ2 ++ Δ3 = [] ++ [A0 --> B] ++ Δ0 ++ [] ++ Δ1). rewrite H7. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+            pose (d:=GLS_adm_list_exch_R D0 J1).
+            assert (ImpLRule [((Γ0 ++ x0) ++ Γ5, Δ2 ++ A :: Δ3); ((Γ0 ++ x0) ++ B0 :: Γ5, Δ2 ++ Δ3)] ((Γ0 ++ x0) ++ A --> B0 :: Γ5, Δ2 ++ Δ3)).
+            apply ImpLRule_I. simpl in H0. repeat rewrite <- app_assoc in H0.
+            assert (J3: (Γ0 ++ x0 ++ Γ5, Δ2 ++ A :: Δ3) << (Γ0 ++ x0 ++ A --> B0 :: Γ5, Δ2 ++ Δ3)). apply ImpL_applic_reduces_measure in H0.
+            destruct H0 ; auto.
+            assert (J5: size (A0 --> B) = size (A0 --> B)). reflexivity.
+            assert (J7 : (Γ0 ++ x0 ++ Γ5, Δ2 ++ A :: Δ3) = (Γ0 ++ x0 ++ Γ5, [] ++ Δ2 ++ A :: Δ3)). reflexivity. rewrite <- H7 in SIH.
+            pose (d0:=@SIH _ J3 (A0 --> B) Γ0 (x0 ++ Γ5) [] (Δ2 ++ A :: Δ3) J5 J7). simpl in d0.
+            assert (J3b: (Γ0 ++ x0 ++ B0 :: Γ5, Δ2 ++ Δ3) << (Γ0 ++ x0 ++ A --> B0 :: Γ5, Δ2 ++ Δ3)). apply ImpL_applic_reduces_measure in H0.
+            destruct H0 ; auto.
+            assert (J8: size (A0 --> B) = size (A0 --> B)). reflexivity.
+            assert (J10: (Γ0 ++ x0 ++ B0 :: Γ5, Δ2 ++ Δ3) = (Γ0 ++ x0 ++ B0 :: Γ5, [] ++ Δ2 ++ Δ3)). reflexivity.
+            pose (d1:=@SIH _ J3b (A0 --> B) Γ0 (x0 ++ B0 :: Γ5) [] (Δ2 ++ Δ3) J8 J10). simpl in d1.
+            assert (ImpLRule [((Γ0 ++ x0) ++ Γ5, (A0 --> B :: Δ2) ++ A :: Δ3); ((Γ0 ++ x0) ++ B0 :: Γ5, (A0 --> B :: Δ2) ++ Δ3)] ((Γ0 ++ x0) ++ A --> B0 :: Γ5, (A0 --> B :: Δ2) ++ Δ3)).
+            apply ImpLRule_I. repeat rewrite <- app_assoc in H3. pose (ImpL_inv d H3). destruct p as [d2 d3].
+            pose (d4:=d0 d2 X5). pose (d5:=d1 d3 X4). apply ImpL in H0 ; try intro ; try apply f ; try repeat rewrite <- app_assoc ; try rewrite <- H7 ;
+            try repeat rewrite app_nil_r ; try auto ; try assumption.
+            apply derI with (ps:=[(Γ0 ++ x0 ++ Γ5, Δ2 ++ A :: Δ3); (Γ0 ++ x0 ++ B0 :: Γ5, Δ2 ++ Δ3)]) ; auto.
+            apply dlCons ; auto. apply dlCons ; auto. apply dlNil.
+        - repeat destruct s. repeat destruct p. subst. rewrite H2. rewrite <- app_assoc. rewrite <- app_assoc in D0.
+          assert (J1 : list_exch_R (Γ4 ++ (A --> B0 :: x) ++ Γ1, Δ0 ++ A0 --> B :: Δ1) (Γ4 ++ (A --> B0 :: x) ++ Γ1, A0 --> B :: Δ2 ++ Δ3)).
+          assert (Δ0 ++ A0 --> B :: Δ1 = [] ++ [] ++ Δ0 ++ [A0 --> B] ++ Δ1). reflexivity. rewrite H0. clear H0.
+          assert (A0 --> B :: Δ2 ++ Δ3 = [] ++ [A0 --> B] ++ Δ0 ++ [] ++ Δ1). rewrite H7. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+          pose (d:=GLS_adm_list_exch_R D0 J1).
+          assert (ImpLRule [(Γ4 ++ x ++ Γ1, Δ2 ++ A :: Δ3); (Γ4 ++ (B0 :: x) ++ Γ1, Δ2 ++ Δ3)] (Γ4 ++ (A --> B0 :: x) ++ Γ1, Δ2 ++ Δ3)).
+          apply ImpLRule_I. simpl in H0.
+          assert (J3: (Γ4 ++ x ++ Γ1, Δ2 ++ A :: Δ3) << (Γ4 ++ A --> B0 :: x ++ Γ1, Δ2 ++ Δ3)). apply ImpL_applic_reduces_measure in H0.
+          destruct H0 ; auto. rewrite <- H7 in SIH. rewrite <- app_assoc in SIH.
+          assert (J5: size (A0 --> B) = size (A0 --> B)). reflexivity.
+          assert (J7 : (Γ4 ++ x ++ Γ1, Δ2 ++ A :: Δ3) = ((Γ4 ++ x) ++ Γ1, [] ++ Δ2 ++ A :: Δ3)). rewrite <- app_assoc. reflexivity.
+          pose (d0:=@SIH _ J3 (A0 --> B) (Γ4 ++ x) Γ1 [] (Δ2 ++ A :: Δ3) J5 J7). simpl in d0. repeat rewrite <- app_assoc in d0.
+          assert (J3b: (Γ4 ++ (B0 :: x) ++ Γ1, Δ2 ++ Δ3) << (Γ4 ++ A --> B0 :: x ++ Γ1, Δ2 ++ Δ3)). apply ImpL_applic_reduces_measure in H0.
+          destruct H0 ; auto.
+          assert (J8: size (A0 --> B) = size (A0 --> B)). reflexivity.
+          assert (J10: (Γ4 ++ B0 :: x ++ Γ1, Δ2 ++ Δ3) = ((Γ4 ++ B0 :: x) ++ Γ1, [] ++ Δ2 ++ Δ3)). rewrite <- app_assoc. reflexivity.
+          pose (d1:=@SIH _ J3b (A0 --> B) (Γ4 ++ B0 :: x) Γ1 [] (Δ2 ++ Δ3) J8 J10). simpl in d1.
+          assert (ImpLRule [(Γ4 ++ x ++ Γ1, (A0 --> B :: Δ2) ++ A :: Δ3); (Γ4 ++ (B0 :: x) ++ Γ1, (A0 --> B :: Δ2) ++ Δ3)] (Γ4 ++ (A --> B0 :: x) ++ Γ1, (A0 --> B :: Δ2) ++ Δ3)).
+          apply ImpLRule_I. repeat rewrite <- app_assoc in H3. pose (ImpL_inv d H3). destruct p as [d2 d3].
+          pose (d4:=d0 d2 X5). repeat rewrite <- app_assoc in d1. pose (d5:=d1 d3 X4). apply ImpL in H0 ; try intro ; try apply f ; try repeat rewrite <- app_assoc ; try rewrite <- H7 ;
+          try repeat rewrite app_nil_r ; try auto ; try assumption. apply derI with (ps:=[(Γ4 ++ x ++ Γ1, Δ2 ++ A :: Δ3); (Γ4 ++ B0 :: x ++ Γ1, Δ2 ++ Δ3)]) ; auto.
+          apply dlCons ; auto. apply dlCons ; auto. apply dlNil. }
+      (* Right rule is GLR *)
+      { inversion X3. subst. rewrite H2.
+        assert (GLRRule [(XBoxed_list ++ [Box A], [A])] (Γ0 ++ Γ1, Δ2 ++ Box A :: Δ3)).
+        apply GLRRule_I ; try assumption.
+        apply univ_gen_ext_splitR in X4. destruct X4. destruct s. repeat destruct p. subst.
+        apply univ_gen_ext_combine. assumption. apply univ_gen_ext_not_In_delete in u0. assumption.
+        intro. assert (In (A0 --> B) (x ++ x0)). apply in_or_app. auto. apply H5 in H0. destruct H0.
+        inversion H0. apply GLR in X5.
+        pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[(XBoxed_list ++ [Box A], [A])]) (Γ0 ++ Γ1, Δ2 ++ Box A :: Δ3) X5 X2).
+        assumption. }
+    + repeat destruct s. repeat destruct p. subst.
+      assert (J5 : list_exch_L (Γ0 ++ A :: Γ1, Δ0 ++ x0 ++ A0 --> B :: Δ3) (A :: Γ2 ++ Γ3, Δ0 ++ x0 ++ A0 --> B :: Δ3)).
+      rewrite H2. assert (Γ0 ++ A :: Γ1 = [] ++ [] ++ Γ0 ++ [A] ++ Γ1). reflexivity. rewrite H. clear H.
+      assert (A :: Γ0 ++ Γ1 = [] ++ [A] ++ Γ0 ++ [] ++ Γ1). reflexivity. rewrite H. clear H.
+      apply list_exch_LI. pose (d:=GLS_adm_list_exch_L D1 J5).
+      assert (ImpRRule [((A :: Γ2) ++ A0 :: Γ3, (Δ0 ++ x0) ++ B :: Δ3)] ((A :: Γ2) ++ Γ3, (Δ0 ++ x0) ++ A0 --> B :: Δ3)).
+      apply ImpRRule_I. repeat rewrite <- app_assoc in H. pose (d0:=ImpR_inv d H).
+      assert (ImpRRule [(Γ2 ++ A0 :: Γ3, (Δ0 ++ x0) ++ B :: Δ3)] (Γ2 ++ Γ3, (Δ0 ++ x0) ++ A0 --> B :: Δ3)).
+      apply ImpRRule_I. repeat rewrite <- app_assoc in H0.
+      assert ((Γ2 ++ A0 :: Γ3, Δ0 ++ x0 ++ B :: Δ3) << (Γ2 ++ Γ3, Δ0 ++ x0 ++ A0 --> B :: Δ3)). apply ImpR_applic_reduces_measure ; auto.
+      assert (GLS_rules [(Γ2 ++ A0 :: Γ3, Δ0 ++ x0 ++ B :: Δ3)] (Γ2 ++ Γ3, Δ0 ++ x0 ++ A0 --> B :: Δ3)).
+      apply ImpR. assumption.
+      assert (J3 : size A = size A). reflexivity.
+      assert (J4 : (Γ2 ++ A0 :: Γ3, Δ0 ++ x0 ++ B :: Δ3) = ([] ++ Γ2 ++ A0 :: Γ3, Δ0 ++ x0 ++ B :: Δ3)).
+      repeat rewrite <- app_assoc. reflexivity. rewrite <- H2 in SIH.
+      pose (d1:=@SIH _ H3 A [] (Γ2 ++ A0 :: Γ3) Δ0 (x0 ++ B :: Δ3) J3 J4). repeat rewrite <- app_assoc in d1. simpl in d1.
+      inversion X0. subst. repeat rewrite <- app_assoc in X4. pose (d2:=d1 X4 d0). pose (dlCons d2 X5).
+      pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[(Γ2 ++ A0 :: Γ3, Δ0 ++ x0 ++ B :: Δ3)]) (Γ2 ++ Γ3, Δ0 ++ x0 ++ A0 --> B :: Δ3) X3 d3). assumption.
+  * repeat destruct s. repeat destruct p. subst. repeat rewrite <- app_assoc. repeat rewrite <- app_assoc in D1.
+    assert (J5 : list_exch_L (Γ0 ++ A :: Γ1, Δ2 ++ (A0 --> B :: x) ++ Δ1) (A :: Γ2 ++ Γ3, Δ2 ++ (A0 --> B :: x) ++ Δ1)).
+    assert (Γ0 ++ A :: Γ1 = [] ++ [] ++ Γ0 ++ [A] ++ Γ1). reflexivity. rewrite H. clear H.
+    assert (A :: Γ2 ++ Γ3 = [] ++ [A] ++ Γ0 ++ [] ++ Γ1). rewrite H2. reflexivity. rewrite H. clear H.
+    apply list_exch_LI. pose (d:=GLS_adm_list_exch_L D1 J5).
+    assert (ImpRRule [((A :: Γ2) ++ A0 :: Γ3, Δ2 ++ B :: x ++ Δ1)] ((A :: Γ2) ++ Γ3, Δ2 ++ (A0 --> B :: x) ++ Δ1)).
+    apply ImpRRule_I. repeat rewrite <- app_assoc in H. pose (d0:=ImpR_inv d H).
+    assert (ImpRRule [(Γ2 ++ A0 :: Γ3, Δ2 ++ (B :: x) ++ Δ1)] (Γ2 ++ Γ3, Δ2 ++ (A0 --> B :: x) ++ Δ1)).
+    apply ImpRRule_I.
+    assert ((Γ2 ++ A0 :: Γ3, Δ2 ++ (B :: x) ++ Δ1) << (Γ2 ++ Γ3, Δ2 ++ (A0 --> B :: x) ++ Δ1)).
+    apply ImpR_applic_reduces_measure ; auto.
+    assert (GLS_rules [(Γ2 ++ A0 :: Γ3, Δ2 ++ (B :: x) ++ Δ1)] (Γ2 ++ Γ3, Δ2 ++ (A0 --> B :: x) ++ Δ1)).
+    apply ImpR ; try assumption. rewrite <- H2 in SIH.
+    assert (J3 : size A = size A). reflexivity.
+    assert (J4 : (Γ2 ++ A0 :: Γ3, Δ2 ++ (B :: x) ++ Δ1) = ([] ++ Γ2 ++ A0 :: Γ3, (Δ2 ++ B :: x) ++ Δ1)).
+    repeat rewrite <- app_assoc. reflexivity. repeat rewrite <- app_assoc in SIH.
+    pose (d1:=@SIH _ H3 A [] (Γ2 ++ A0 :: Γ3) (Δ2 ++ (B :: x)) Δ1 J3 J4). simpl in d1. repeat rewrite <- app_assoc in d1.
+    inversion X0. subst. pose (d2:=d1 X4 d0). pose (dlCons d2 X5).
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[(Γ2 ++ A0 :: Γ3, Δ2 ++ (B :: x) ++ Δ1)]) (Γ2 ++ Γ3, Δ2 ++ (A0 --> B :: x) ++ Δ1) X3 d3). assumption.
+ +
+(* Left rule is ImpL *)
+- inversion H1. subst. inversion X0. inversion X4. subst. clear X6. clear X4.
+  assert (J5 : list_exch_L (Γ0 ++ A :: Γ1, Δ0 ++ Δ1) (A :: Γ2 ++ A0 --> B :: Γ3, Δ0 ++ Δ1)).
+  rewrite H2. assert (Γ0 ++ A :: Γ1 = [] ++ [] ++ Γ0 ++ [A] ++ Γ1).
+  reflexivity. rewrite H. clear H.
+  assert (A :: Γ0 ++ Γ1 = [] ++ [A] ++ Γ0 ++ [] ++ Γ1). reflexivity. rewrite H. clear H.
+  apply list_exch_LI. pose (d:=GLS_adm_list_exch_L D1 J5). rewrite H3 in X5.
+  assert (J40 : list_exch_R (Γ2 ++ Γ3, Δ2 ++ A0 :: Δ3) (Γ2 ++ Γ3, A0 :: Δ0 ++ A :: Δ1)).
+  rewrite <- H3. assert (Δ2 ++ A0 :: Δ3 = [] ++ [] ++ Δ2 ++ [A0] ++ Δ3).
+  reflexivity. rewrite H. clear H.
+  assert (A0 :: Δ2 ++ Δ3 = [] ++ [A0] ++ Δ2 ++ [] ++ Δ3). reflexivity. rewrite H. clear H.
+  apply list_exch_RI. pose (d0:=GLS_adm_list_exch_R X3 J40).
+  assert (ImpLRule [(A :: Γ2 ++ Γ3, [] ++ A0 :: Δ0 ++ Δ1); (A :: Γ2 ++ B :: Γ3, [] ++ Δ0 ++ Δ1)] (A :: Γ2 ++ A0 --> B :: Γ3, [] ++ Δ0 ++ Δ1)).
+  assert ((A :: Γ2 ++ A0 --> B :: Γ3, [] ++ Δ0 ++ Δ1) = ((A :: Γ2) ++ A0 --> B :: Γ3, [] ++ Δ0 ++ Δ1)). reflexivity.
+  rewrite H. clear H.
+  assert ((A :: Γ2 ++ Γ3, [] ++ A0 :: Δ0 ++ Δ1) = ((A :: Γ2) ++ Γ3, [] ++ A0 :: Δ0 ++ Δ1)). reflexivity.
+  rewrite H. clear H.
+  assert ((A :: Γ2 ++ B :: Γ3, [] ++ Δ0 ++ Δ1) = ((A :: Γ2) ++ B :: Γ3, [] ++ Δ0 ++ Δ1)). reflexivity.
+  rewrite H. clear H. apply ImpLRule_I. simpl in H. pose (ImpL_inv d H). destruct p as [d1 d2].
+  assert (ImpLRule [(Γ2 ++ Γ3, [] ++ A0 :: Δ0 ++ Δ1); (Γ2 ++ B :: Γ3, [] ++ Δ0 ++ Δ1)] (Γ2 ++ A0 --> B :: Γ3, [] ++ Δ0 ++ Δ1)).
+  apply ImpLRule_I. simpl in H0.
+  assert (lt0: (Γ2 ++ Γ3, A0 :: Δ0 ++ Δ1) << (Γ2 ++ A0 --> B :: Γ3, Δ0 ++ Δ1)).
+   apply ImpL_applic_reduces_measure in H0. destruct H0 ; auto.
+  assert (GLS_rules [(Γ2 ++ Γ3, A0 :: Δ0 ++ Δ1); (Γ2 ++ B :: Γ3, Δ0 ++ Δ1)] (Γ2 ++ A0 --> B :: Γ3, Δ0 ++ Δ1)).
+  apply ImpL. assumption.
+  assert (J3 : size A = size A). reflexivity.
+  assert (J4 : (Γ2 ++ Γ3, A0 :: Δ0 ++ Δ1) = ([] ++ Γ2 ++ Γ3, (A0 :: Δ0) ++ Δ1)).
+  repeat rewrite <- app_assoc. reflexivity. rewrite <- H2 in SIH.
+  pose (d3:=@SIH _ lt0 A [] (Γ2 ++ Γ3) (A0 :: Δ0) Δ1 J3 J4). repeat rewrite <- app_assoc in d3. simpl in d3.
+  pose (d4:=d3 d0 d1).
+  assert (lt1: (Γ2 ++ B :: Γ3, Δ0 ++ Δ1) << (Γ2 ++ A0 --> B :: Γ3, Δ0 ++ Δ1)).
+   apply ImpL_applic_reduces_measure in H0. destruct H0 ; auto.
+  assert (J33 : size A = size A). reflexivity.
+  assert (J34 : (Γ2 ++ B :: Γ3, Δ0 ++ Δ1) = ([] ++ Γ2 ++ B :: Γ3, Δ0 ++ Δ1)).
+  repeat rewrite <- app_assoc. reflexivity.
+  pose (d5:=@SIH _ lt1 A [] (Γ2 ++ B :: Γ3) Δ0 Δ1 J33 J34). repeat rewrite <- app_assoc in d5. simpl in d5.
+  pose (d6:=d5 X5 d2). apply derI with (ps:=[(Γ2 ++ Γ3, A0 :: Δ0 ++ Δ1); (Γ2 ++ B :: Γ3, Δ0 ++ Δ1)]) ; auto.
+  apply dlCons ; auto. apply dlCons ; auto. apply dlNil.
+ +
+(* Left rule is GLR *)
+- inversion X3. subst. apply list_split_form in H2. destruct H2.
+  * destruct s.
+    + repeat destruct p. subst. inversion X1.
+      (* Right rule is IdP *)
+      { inversion H. subst. assert (J0 : InT (# P) (Γ0 ++ Box A0 :: Γ1)). rewrite <- H5. apply InT_or_app.
+        right. apply InT_eq. apply InT_app_or in J0. destruct J0.
+        - apply InT_split in i. destruct i. destruct s. subst. rewrite <- app_assoc. apply derI with (ps:=[]).
+          apply IdP. apply IdPRule_I. apply dlNil.
+        - inversion i.
+          * inversion H2.
+          * apply InT_split in H2. destruct H2. destruct s. subst. rewrite app_assoc. apply derI with (ps:=[]).
+          apply IdP. apply IdPRule_I. apply dlNil. }
+      (* Right rule is BotL *)
+      { inversion H. subst. assert (J0 : InT () (Γ0 ++ Box A0 :: Γ1)). rewrite <- H5. apply InT_or_app.
+        right. apply InT_eq. apply InT_app_or in J0. destruct J0.
+        - apply InT_split in i. destruct i. destruct s. subst. rewrite <- app_assoc. apply derI with (ps:=[]).
+          apply BotL. apply BotLRule_I. apply dlNil.
+        - inversion i.
+          * inversion H2.
+          * apply InT_split in H2. destruct H2. destruct s. subst. rewrite app_assoc. apply derI with (ps:=[]).
+          apply BotL. apply BotLRule_I. apply dlNil. }
+      (* Right rule is ImpR *)
+      { inversion H. subst. inversion X2. subst. clear X6. rewrite <- H6 in D1.
+        assert (J1 : list_exch_L (Γ2 ++ A :: Γ3, Δ2 ++ B :: Δ3) (A :: Γ0 ++ Box A0 :: Γ1, Δ2 ++ B :: Δ3)).
+        assert (Γ2 ++ A :: Γ3 = [] ++ [] ++ Γ2 ++ [A] ++ Γ3). reflexivity. rewrite H0. clear H0.
+        assert (A :: Γ0 ++ Box A0 :: Γ1 = [] ++ [A] ++ Γ2 ++ [] ++ Γ3). rewrite <- H5. reflexivity.
+        rewrite H0. clear H0. apply list_exch_LI. pose (d:=GLS_adm_list_exch_L X5 J1).
+        assert (ImpRRule [([] ++ A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ3)] ([] ++ Γ0 ++ Γ1, Δ2 ++ A --> B :: Δ3)). apply ImpRRule_I.
+        simpl in H0.
+        assert (J3: (A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ3) << (Γ0 ++ Γ1, Δ2 ++ A --> B :: Δ3)).
+        apply ImpR_applic_reduces_measure ; auto.
+        assert (J31: GLS_rules [(A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ3)] (Γ0 ++ Γ1, Δ2 ++ A --> B :: Δ3)).
+        apply ImpR ; try assumption. rewrite <- H6 in SIH.
+        assert (J5: size (Box A0) = size (Box A0)). reflexivity.
+        assert (J7 : (A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ3) = ((A :: Γ0) ++ Γ1, [] ++ Δ2 ++ B :: Δ3)). reflexivity.
+        pose (d0:=@SIH _ J3 (Box A0) (A :: Γ0) Γ1 [] (Δ2 ++ B :: Δ3) J5 J7). simpl in d0.
+        assert (J8 : list_exch_R (Γ0 ++ Γ1, Δ0 ++ Box A0 :: Δ1) (Γ0 ++ Γ1, Box A0 :: Δ2 ++ A --> B :: Δ3)).
+        assert (Δ0 ++ Box A0 :: Δ1 = [] ++ [] ++ Δ0 ++ [Box A0] ++ Δ1). reflexivity. rewrite H2. clear H2.
+        assert (Box A0 :: Δ2 ++ A --> B :: Δ3 = [] ++ [Box A0] ++ Δ0 ++ [] ++ Δ1). rewrite H6.
+        reflexivity. rewrite H2. clear H2. apply list_exch_RI. pose (d1:=GLS_adm_list_exch_R D0 J8).
+        assert (ImpRRule [([] ++ A ::Γ0 ++ Γ1, (Box A0 :: Δ2) ++ B :: Δ3)] ([] ++ Γ0 ++ Γ1, (Box A0 :: Δ2) ++ A --> B :: Δ3)).
+        apply ImpRRule_I. simpl in H2. pose (d2:=ImpR_inv d1 H2). pose (d3:=d0 d2 d). apply derI with (ps:=[(A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ3)]) ; auto.
+        apply dlCons ; auto. apply dlNil. }
+      (* Right rule is ImpL *)
+      { inversion H. subst. apply list_split_form in H5. destruct H5.
+        - destruct s.
+          + repeat destruct p. inversion e0.
+          + repeat destruct s. repeat destruct p. subst. repeat rewrite <- app_assoc in H. repeat rewrite <- app_assoc in X2.
+            assert (J2: list_exch_R (Γ0 ++ x0 ++ A --> B :: Γ3, Δ0 ++ Box A0 :: Δ1) (Γ0 ++ x0 ++ A --> B :: Γ3, Box A0 :: Δ2 ++ Δ3)).
+            assert (Δ0 ++ Box A0 :: Δ1 = [] ++ [] ++ Δ0 ++ [Box A0] ++ Δ1). reflexivity. rewrite H0. clear H0.
+            assert (Box A0 :: Δ2 ++ Δ3 = [] ++ [Box A0] ++ Δ0 ++ [] ++ Δ1). rewrite H6. reflexivity. rewrite H0. clear H0.
+            apply list_exch_RI. pose (d:=GLS_adm_list_exch_R D0 J2).
+            assert (ImpLRule [((Γ0 ++ x0) ++ Γ3, (Box A0 :: Δ2) ++ A :: Δ3); ((Γ0 ++ x0) ++ B :: Γ3, (Box A0 :: Δ2) ++ Δ3)]
+            ((Γ0 ++ x0) ++ A --> B :: Γ3, (Box A0 :: Δ2) ++ Δ3)). apply ImpLRule_I. simpl in H.
+            repeat rewrite <- app_assoc in H0. pose (ImpL_inv d H0). destruct p as [d0 d1].
+            assert (ImpLRule [((Γ0 ++ x0) ++ Γ3, Δ2 ++ A :: Δ3); ((Γ0 ++ x0) ++ B :: Γ3, Δ2 ++ Δ3)]
+            ((Γ0 ++ x0) ++ A --> B :: Γ3, Δ2 ++ Δ3)). apply ImpLRule_I. repeat rewrite <- app_assoc in H0.
+            repeat rewrite <- app_assoc in H2.
+            assert (J3: (Γ0 ++ x0 ++ Γ3, Δ2 ++ A :: Δ3) << (Γ0 ++ x0 ++ A --> B :: Γ3, Δ2 ++ Δ3)).
+            apply ImpL_applic_reduces_measure in H2. destruct H2 ; auto.
+            assert (J30: GLS_rules [(Γ0 ++ x0 ++ Γ3, Δ2 ++ A :: Δ3); (Γ0 ++ x0 ++ B :: Γ3, Δ2 ++ Δ3)]
+            (Γ0 ++ x0 ++ A --> B :: Γ3, Δ2 ++ Δ3)). apply ImpL ; try assumption.
+            repeat rewrite <- app_assoc in SIH. rewrite <- H6 in SIH.
+            assert (J3b: (Γ0 ++ x0 ++ B :: Γ3, Δ2 ++ Δ3) << (Γ0 ++ x0 ++ A --> B :: Γ3, Δ2 ++ Δ3)).
+            apply ImpL_applic_reduces_measure in H2. destruct H2 ; auto.
+            assert (J6: size (Box A0) = size (Box A0)). reflexivity.
+            assert (J8: (Γ0 ++ x0 ++ Γ3, Δ2 ++ A :: Δ3) = (Γ0 ++ x0 ++ Γ3, [] ++ Δ2 ++ A :: Δ3)). reflexivity.
+            pose (d2:=@SIH _ J3 (Box A0) Γ0 (x0 ++ Γ3) [] (Δ2 ++ A :: Δ3) J6 J8). simpl in d2. inversion X2.
+            subst. inversion X6. clear X6. subst. pose (d3:=d2 d0 X5).
+            assert (J11: (Γ0 ++ x0 ++ B :: Γ3, Δ2 ++ Δ3) = (Γ0 ++ x0 ++ B :: Γ3, [] ++ Δ2 ++ Δ3)). reflexivity.
+            pose (d4:=@SIH _ J3b (Box A0) Γ0 (x0 ++ B :: Γ3) [] (Δ2 ++ Δ3) J6 J11). simpl in d4. pose (d5:=d4 d1 X7).
+            pose (dlCons d5 X8). pose (dlCons d3 d6).
+            pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[(Γ0 ++ x0 ++ Γ3, Δ2 ++ A :: Δ3); (Γ0 ++ x0 ++ B :: Γ3, Δ2 ++ Δ3)]) (Γ0 ++ x0 ++ A --> B :: Γ3, Δ2 ++ Δ3) J30 d7).
+            assumption.
+        - repeat destruct s. repeat destruct p. subst. rewrite <- app_assoc in D0.
+          assert (J2: list_exch_R (Γ2 ++ (A --> B :: x) ++ Γ1, Δ0 ++ Box A0 :: Δ1) (Γ2 ++ (A --> B :: x) ++ Γ1, Box A0 :: Δ2 ++ Δ3)).
+          assert (Δ0 ++ Box A0 :: Δ1 = [] ++ [] ++ Δ0 ++ [Box A0] ++ Δ1). reflexivity. rewrite H0. clear H0.
+          assert (Box A0 :: Δ2 ++ Δ3 = [] ++ [Box A0] ++ Δ0 ++ [] ++ Δ1). rewrite H6. reflexivity. rewrite H0. clear H0.
+          apply list_exch_RI. pose (d:=GLS_adm_list_exch_R D0 J2).
+          assert (ImpLRule [(Γ2 ++ x ++ Γ1, (Box A0 :: Δ2) ++ A :: Δ3); (Γ2 ++ B :: x ++ Γ1, (Box A0 :: Δ2) ++ Δ3)]
+          (Γ2 ++ (A --> B :: x) ++ Γ1, (Box A0 :: Δ2) ++ Δ3)). apply ImpLRule_I. repeat rewrite <- app_assoc in H0.
+          pose (ImpL_inv d H0). destruct p as [d0 d1]. rewrite <- app_assoc.
+          assert (ImpLRule [(Γ2 ++ x ++ Γ1, Δ2 ++ A :: Δ3); (Γ2 ++ B :: x ++ Γ1, Δ2 ++ Δ3)]
+          (Γ2 ++ (A --> B :: x) ++ Γ1, Δ2 ++ Δ3)). apply ImpLRule_I.
+          assert (J3: (Γ2 ++ x ++ Γ1, Δ2 ++ A :: Δ3) << (Γ2 ++ (A --> B :: x) ++ Γ1, Δ2 ++ Δ3)).
+          apply ImpL_applic_reduces_measure in H2. destruct H2 ; auto.
+          assert (J30: GLS_rules [(Γ2 ++ x ++ Γ1, Δ2 ++ A :: Δ3); (Γ2 ++ B :: x ++ Γ1, Δ2 ++ Δ3)]
+          (Γ2 ++ (A --> B :: x) ++ Γ1, Δ2 ++ Δ3)). apply ImpL ; try assumption.
+          assert (J3b: (Γ2 ++ B :: x ++ Γ1, Δ2 ++ Δ3) << (Γ2 ++ (A --> B :: x) ++ Γ1, Δ2 ++ Δ3)).
+          apply ImpL_applic_reduces_measure in H2. destruct H2 ; auto.
+          repeat rewrite <- app_assoc in SIH. rewrite <- H6 in SIH.
+          assert (J6: size (Box A0) = size (Box A0)). reflexivity.
+          assert (J8: (Γ2 ++ x ++ Γ1, Δ2 ++ A :: Δ3) = ((Γ2 ++ x) ++ Γ1, [] ++ Δ2 ++ A :: Δ3)). rewrite <- app_assoc. reflexivity.
+          pose (d2:=@SIH _ J3 (Box A0) (Γ2 ++ x) Γ1 [] (Δ2 ++ A :: Δ3) J6 J8). simpl in d2. inversion X2. subst. inversion X6. clear X6.
+          subst. repeat rewrite <- app_assoc in d2. pose (d3:=d2 d0 X5).
+          assert (J11: (Γ2 ++ B :: x ++ Γ1, Δ2 ++ Δ3) = ((Γ2 ++ B :: x) ++ Γ1, [] ++ Δ2 ++ Δ3)). rewrite <- app_assoc. reflexivity.
+          pose (d4:=@SIH _ J3b (Box A0) (Γ2 ++ B :: x) Γ1 [] (Δ2 ++ Δ3) J6 J11). simpl in d4. repeat rewrite <- app_assoc in d4.
+          pose (d5:=d4 d1 X7). pose (dlCons d5 X8). pose (dlCons d3 d6).
+          pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[(Γ2 ++ x ++ Γ1, Δ2 ++ A :: Δ3); (Γ2 ++ B :: x ++ Γ1, Δ2 ++ Δ3)]) (Γ2 ++ (A --> B :: x) ++ Γ1, Δ2 ++ Δ3) J30 d7).
+          assumption. }
+      (* Right rule is GLR *)
+      { inversion X5. subst. inversion X0. subst. clear X8. inversion X2. subst. clear X9.
+        pose (univ_gen_ext_splitR _ _ X4). repeat destruct s. repeat destruct p.
+        pose (univ_gen_ext_splitR _ _ X6). repeat destruct s. repeat destruct p. subst. inversion u2.
+        - subst.
+          assert ((XBoxed_list (x ++ x0) ++ [Box A0], [A0]) = ((XBoxed_list (x ++ x0) ++ [Box A0]) ++ [], [] ++ [A0])).
+          repeat rewrite <- app_assoc. reflexivity.
+          assert (X7': derrec GLS_rules (fun _ : Seq => False) ((XBoxed_list (x ++ x0) ++ [Box A0]) ++ [], [] ++ [A0])).
+          rewrite <- H. assumption.
+          assert (J1: wkn_L (Box A) ((XBoxed_list (x ++ x0) ++ [Box A0]) ++ [], [] ++ [A0]) ((XBoxed_list (x ++ x0) ++ [Box A0]) ++ (Box A) :: [], [] ++ [A0])).
+          apply wkn_LI. assert (J2: derrec_height X7' = derrec_height X7'). reflexivity.
+          pose (GLS_wkn_L _ J2 J1). destruct s. clear l0. clear J2. clear X7'. clear J1.
+          assert (J3: wkn_R A ((XBoxed_list (x ++ x0) ++ [Box A0]) ++ [Box A], [] ++ [A0]) ((XBoxed_list (x ++ x0) ++ [Box A0]) ++ [Box A], [] ++ A :: [A0])).
+          apply wkn_RI. assert (J4: derrec_height x2 = derrec_height x2). reflexivity.
+          pose (GLS_wkn_R _ J4 J3). destruct s. clear l0. clear J4. clear J3. clear x2. clear H. simpl in x3.
+          rewrite XBox_app_distrib in x3. repeat rewrite <- app_assoc in x3.
+          rewrite XBox_app_distrib in X8. repeat rewrite <- app_assoc in X8. simpl in X8.
+          assert ((XBoxed_list x1 ++ A0 :: Box A0 :: XBoxed_list l ++ [Box A], [A]) =
+          (XBoxed_list x1 ++ (A0 :: [Box A0]) ++ [] ++ XBoxed_list l ++ [Box A], [A])).
+          reflexivity. rewrite H in X8. clear H.
+          assert (J5: list_exch_L (XBoxed_list x1 ++ [A0; Box A0] ++ [] ++ XBoxed_list l ++ [Box A], [A])
+          (XBoxed_list x1 ++ XBoxed_list l ++ [] ++ [A0; Box A0] ++ [Box A], [A])).
+          apply list_exch_LI.
+          pose (d:=GLS_adm_list_exch_L X8 J5). simpl in d. rewrite app_assoc in d.
+          rewrite <- XBox_app_distrib in d. assert (x1 ++ l = x ++ x0).
+          apply nobox_gen_ext_injective with (l:=(Γ0 ++ Γ1)) ; try assumption.
+          intro. intros. apply H4. apply in_or_app. apply in_app_or in H. destruct H.
+          auto. right. apply in_cons. assumption. apply univ_gen_ext_combine ; assumption.
+          rewrite H in d. clear J5. clear X8. simpl in x3. rewrite app_assoc in x3.
+          rewrite <- XBox_app_distrib in x3.
+          assert (J6: size A0 < size (Box A0)). simpl. lia.
+          assert (J7: size A0 = size A0). reflexivity.
+          assert (J9: (XBoxed_list (x ++ x0) ++ [Box A0; Box A], [A]) =
+          (XBoxed_list (x ++ x0) ++ [Box A0; Box A], [A] ++ [])). rewrite app_nil_r. reflexivity.
+          pose (d0:=@PIH (size A0) J6 A0 (XBoxed_list (x ++ x0) ++ [Box A0; Box A], [A]) (XBoxed_list (x ++ x0)) (Box A0 :: [Box A])
+          [A] [] J7 J9). rewrite app_nil_r in d0. pose (d1:=d0 x3 d).
+          assert (GLRRule [(XBoxed_list (x ++ x0) ++ [Box A0], [A0])] (x ++ x0, [Box A0])).
+          assert ((x ++ x0, [Box A0]) = (x ++ x0, [] ++ Box A0 :: [])). reflexivity. rewrite H0. clear H0.
+          apply GLRRule_I.
+          assumption. apply univ_gen_ext_refl.
+          assert (GLS_rules [(XBoxed_list (x ++ x0) ++ [Box A0], [A0])] (x ++ x0, [Box A0])).
+          apply GLR. assumption. pose (DersNilF:=dlNil GLS_rules (fun _ : Seq => False)).
+          pose (dlCons X7 DersNilF).
+          pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[(XBoxed_list (x ++ x0) ++ [Box A0], [A0])]) (x ++ x0, [Box A0]) X10 d2).
+          assert ([Box A0] = [Box A0] ++ []). reflexivity. rewrite H0 in d3.
+          assert (wkn_R A (x ++ x0, [Box A0] ++ []) (x ++ x0, [Box A0] ++ A :: [])). apply wkn_RI.
+          assert (J10: derrec_height d3 = derrec_height d3). reflexivity.
+          pose (GLS_wkn_R _ J10 H2). destruct s. clear l0. clear J10. clear H0. clear d3.
+          clear d2. clear X10. clear X8. clear J6. clear J9.
+          assert (J20: derrec_height x2 = derrec_height x2). reflexivity.
+          pose (@GLS_XBoxed_list_wkn_L (derrec_height x2) (x ++ x0) [] [] ([Box A0] ++ [A])).
+          repeat rewrite app_nil_r in s. repeat rewrite app_nil_l in s. pose (s x2 J20).
+          destruct s0. clear l0. clear J20. clear s. clear x2.
+          assert (XBoxed_list (x ++ x0) = XBoxed_list (x ++ x0) ++ []). rewrite app_nil_r. reflexivity.
+          rewrite H0 in x4. clear H0.
+          assert (wkn_L (Box A) (XBoxed_list (x ++ x0) ++ [], [Box A0] ++ [A]) (XBoxed_list (x ++ x0) ++ (Box A) :: [], [Box A0] ++ [A])).
+          apply wkn_LI.
+          assert (J10: derrec_height x4 = derrec_height x4). reflexivity.
+          pose (GLS_wkn_L _ J10 H0). destruct s. clear l0. clear J10. clear x4. clear H0.
+          assert (GLRRule [(XBoxed_list (x ++ x0) ++ [Box A], [A])] (Γ0 ++ Γ1, Δ0 ++ Δ1)).
+          rewrite <- H5. apply GLRRule_I ; try assumption.
+          destruct (dec_init_rules (Γ0 ++ Γ1, Δ2 ++ Box A :: Δ3)).
+          + repeat destruct s.
+            * apply IdP in i. pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+              (ps:=[]) (Γ0 ++ Γ1, Δ2 ++ Box A :: Δ3) i DersNilF). assumption.
+            * inversion i. apply Id_all_form.
+            * apply BotL in b. pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+              (ps:=[]) (Γ0 ++ Γ1, Δ2 ++ Box A :: Δ3) b DersNilF). assumption.
+          + assert ((XBoxed_list (x ++ x0) ++ [Box A], [A]) << (Γ0 ++ Γ1, Δ0 ++ Δ1)).
+            apply GLR_applic_reduces_measure ; try intro ; try apply f ; try rewrite H5 ; try auto ; try assumption.
+            assert (J40: GLS_rules [(XBoxed_list (x ++ x0) ++ [Box A], [A])] (Γ0 ++ Γ1, Δ0 ++ Δ1)).
+            apply GLR ; try assumption.
+            assert (J10: size (Box A0) = size (Box A0)). reflexivity.
+            assert (J12: (XBoxed_list (x ++ x0) ++ [Box A], [A]) = (XBoxed_list (x ++ x0) ++ [Box A], [] ++ [A]) ). reflexivity.
+            pose (d2:=@SIH _ H0 (Box A0) (XBoxed_list (x ++ x0)) [Box A] [] [A] J10 J12). simpl in d2. pose (d3:=d2 x2 d1). pose (dlCons d3 DersNilF).
+            pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[(XBoxed_list (x ++ x0) ++ [Box A], [A])]) (Γ0 ++ Γ1, Δ0 ++ Δ1) J40 d4).
+            rewrite H5. assumption.
+        - exfalso. apply H2. exists A0. reflexivity. }
+    + repeat destruct s. repeat destruct p. subst.
+      assert (GLRRule [(XBoxed_list ++ [Box A0], [A0])] (Γ0 ++ Γ1, (Δ0 ++ x0) ++ Box A0 :: Δ3)).
+      apply GLRRule_I ; try assumption. repeat rewrite <- app_assoc in X5.
+      assert (GLS_rules [(XBoxed_list ++ [Box A0], [A0])] (Γ0 ++ Γ1, Δ0 ++ x0 ++ Box A0 :: Δ3)).
+      apply GLR. assumption.
+      pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[(XBoxed_list ++ [Box A0], [A0])]) (Γ0 ++ Γ1, Δ0 ++ x0 ++ Box A0 :: Δ3) X6 X0). assumption.
+  * repeat destruct s. repeat destruct p. subst. rewrite <- app_assoc.
+    assert (GLRRule [(XBoxed_list ++ [Box A0], [A0])] (Γ0 ++ Γ1, Δ2 ++ (Box A0 :: x) ++ Δ1)).
+    apply GLRRule_I ; try assumption.
+    assert (GLS_rules [(XBoxed_list ++ [Box A0], [A0])] (Γ0 ++ Γ1, Δ2 ++ (Box A0 :: x) ++ Δ1)).
+    apply GLR. assumption.
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[(XBoxed_list ++ [Box A0], [A0])]) (Γ0 ++ Γ1, Δ2 ++ (Box A0 :: x) ++ Δ1) X6 X0). assumption.
+Qed.
+ +
+Theorem GLS_cut_adm : forall A Γ0 Γ1 Δ0 Δ1,
+                      (GLS_prv (Γ0 ++ Γ1, Δ0 ++ A :: Δ1)) ->
+                      (GLS_prv (Γ0 ++ A :: Γ1, Δ0 ++ Δ1)) ->
+                      (GLS_prv (Γ0 ++ Γ1, Δ0 ++ Δ1)).
+Proof.
+intros.
+assert (J1: size A = size A). reflexivity.
+assert (J3: (Γ0 ++ Γ1, Δ0 ++ Δ1) = (Γ0 ++ Γ1, Δ0 ++ Δ1)). reflexivity.
+pose (@GLS_cut_adm_main (size A) A
+(Γ0 ++ Γ1, Δ0 ++ Δ1) Γ0 Γ1 Δ0 Δ1 J1 J3). auto.
+Qed.
+ +
+
+
+ +
+ + + diff --git a/GL.GLS.GLS_calcs.html b/GL.GLS.GLS_calcs.html new file mode 100644 index 0000000..229dcf9 --- /dev/null +++ b/GL.GLS.GLS_calcs.html @@ -0,0 +1,199 @@ + + + + + + + + + + + + + +
+
+

GL.GLS.GLS_calcs

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat.
+ +
+Require Export general_export.
+ +
+Require Export Syntax_export.
+ +
+(* In this file we define two calculi based on multisets for the propositonal modal logic
+   GL. The first one, called GLS, is the main calculus for GL. The second one, named PSGLS,
+   is essentially the calculus GLS with further restrictions on the application of the
+   rules. In other words, the calculus PSGLS is a proof-search oriented version of GLS. *)

+ +
+(* To define our rules, we will need some notions on the language. *)
+ +
+Fixpoint XBoxed_list (Γ : list MPropF) : list MPropF:=
+  match Γ with
+  | [ ] => [ ]
+  | h :: t => (unBox_formula h :: h :: XBoxed_list t)
+  end
+.
+ +
+(* Now that we have defined these, we can prove some properties about them. *)
+ +
+Lemma XBox_app_distrib :
+  forall (l1 l2: list MPropF), XBoxed_list (l1 ++ l2) = (XBoxed_list l1) ++ (XBoxed_list l2).
+Proof.
+induction l1.
+- intro l2. rewrite app_nil_l with (l:=l2). simpl. reflexivity.
+- intro l2. simpl. rewrite IHl1. reflexivity.
+Qed.
+ +
+Lemma list_preserv_XBoxed_list : forall (l : list MPropF), incl l (XBoxed_list l).
+Proof.
+induction l.
+- simpl. unfold incl. intros. inversion H.
+- simpl. unfold incl. intros. inversion H.
+  * subst. apply in_cons. apply in_eq.
+  * apply in_cons. apply in_cons. apply IHl. assumption.
+Qed.
+ +
+(* We use a macro for sequents *)
+ +
+Definition Seq := (prod (list MPropF) (list MPropF)).
+ +
+(* ---------------------------------------------------------------------------------------------------------------------------------- *)
+ +
+(* Finally, we can define the rules which constitute our calculi. We gather
+   them in cacluli in a definition appearing later. *)

+ +
+Inductive IdPRule : rlsT Seq :=
+  | IdPRule_I : forall P (Γ0 Γ1 Δ0 Δ1 : list MPropF),
+          IdPRule [] (pair (Γ0 ++ # P :: Γ1) (Δ0 ++ # P :: Δ1))
+.
+ +
+Inductive IdBRule : rlsT Seq :=
+  | IdBRule_I : forall A Γ0 Γ1 Δ0 Δ1,
+          IdBRule [] (pair (Γ0 ++ Box A :: Γ1) (Δ0 ++ Box A :: Δ1))
+.
+ +
+Inductive BotLRule : rlsT Seq :=
+  | BotLRule_I : forall Γ0 Γ1 Δ,
+          BotLRule [] (pair (Γ0 ++ (Bot) :: Γ1) Δ)
+.
+ +
+Inductive ImpRRule : rlsT Seq :=
+  | ImpRRule_I : forall A B Γ0 Γ1 Δ0 Δ1,
+          ImpRRule [(pair (Γ0 ++ A :: Γ1) (Δ0 ++ B :: Δ1))]
+                    (pair (Γ0 ++ Γ1) (Δ0 ++ (A --> B) :: Δ1))
+.
+ +
+Inductive ImpLRule : rlsT Seq :=
+  | ImpLRule_I : forall A B Γ0 Γ1 Δ0 Δ1,
+          ImpLRule ((pair (Γ0 ++ Γ1) (Δ0 ++ A :: Δ1)) ::
+                     [(pair (Γ0 ++ B :: Γ1) (Δ0 ++ Δ1))])
+                    (pair (Γ0 ++ (A --> B) :: Γ1) (Δ0 ++ Δ1))
+.
+ +
+Inductive GLRRule : rlsT Seq :=
+  | GLRRule_I : forall A Γ0 Δ0 Δ1,
+          (is_Boxed_list ) -> (* have MS of boxed formulae prem L*)
+          (nobox_gen_ext Γ0) -> (* extend BΓ in Γ0, the L of the ccl *)
+         GLRRule [(pair ((XBoxed_list ) ++ [Box A]) [A])] (pair Γ0 (Δ0 ++ Box A :: Δ1))
+.
+ +
+(* At last we can define our calculus GLS and its proof-search version PSGLS. *)
+ +
+Inductive GLS_rules : rlsT Seq :=
+  | IdP : forall ps c, IdPRule ps c -> GLS_rules ps c
+  | BotL : forall ps c, BotLRule ps c -> GLS_rules ps c
+  | ImpR : forall ps c, ImpRRule ps c -> GLS_rules ps c
+  | ImpL : forall ps c, ImpLRule ps c -> GLS_rules ps c
+  | GLR : forall ps c, GLRRule ps c -> GLS_rules ps c
+.
+ +
+(* We can show that all identities are provable in GLS. *)
+ +
+Lemma Id_all_form : forall (A : MPropF) l0 l1 l2 l3,
+          derrec GLS_rules (fun _ => False) (l0 ++ A :: l1, l2 ++ A :: l3).
+Proof.
+assert (DersNilF: dersrec GLS_rules (fun _ : rel (list MPropF) => False) []).
+apply dersrec_nil.
+ +
+induction A.
+- intros. assert (IdPRule [] (l0 ++ # s :: l1, l2 ++ # s :: l3)). apply IdPRule_I. apply IdP in H.
+  pose (derI (rules:=GLS_rules) (prems:=fun _ : rel (list MPropF) => False) (ps:=[])
+  (l0 ++ # s :: l1, l2 ++ # s :: l3) H DersNilF). assumption.
+- intros. assert (BotLRule [] (l0 ++ :: l1, l2 ++ :: l3)). apply BotLRule_I. apply BotL in H.
+  pose (derI (rules:=GLS_rules) (prems:=fun _ : rel (list MPropF) => False) (ps:=[])
+  (l0 ++ :: l1, l2 ++ :: l3) H DersNilF). assumption.
+- intros. assert (ImpRRule [(l0 ++ A1 :: A1 --> A2 :: l1, l2 ++ A2 :: l3)] (l0 ++ A1 --> A2 :: l1, l2 ++ A1 --> A2 :: l3)).
+  apply ImpRRule_I. apply ImpR in H.
+  assert (ImpLRule [((l0 ++ [A1]) ++ l1, l2 ++ A1 :: A2 :: l3); ((l0 ++ [A1]) ++ A2 :: l1, l2 ++ A2 :: l3)] ((l0 ++ [A1]) ++ A1 --> A2 :: l1, l2 ++ A2 :: l3)).
+  apply ImpLRule_I. repeat rewrite <- app_assoc in H0. simpl in H0. apply ImpL in H0.
+  pose (IHA1 l0 l1 l2 (A2 :: l3)). pose (IHA2 (l0 ++ [A1]) l1 l2 l3). repeat rewrite <- app_assoc in d0. simpl in d0.
+  pose (dlCons d0 DersNilF). pose (dlCons d d1).
+  pose (derI (rules:=GLS_rules) (prems:=fun _ : rel (list MPropF) => False) (ps:=[(l0 ++ A1 :: l1, l2 ++ A1 :: A2 :: l3); (l0 ++ A1 :: A2 :: l1, l2 ++ A2 :: l3)])
+  (l0 ++ A1 :: A1 --> A2 :: l1, l2 ++ A2 :: l3) H0 d2). pose (dlCons d3 DersNilF).
+  pose (derI (rules:=GLS_rules) (prems:=fun _ : rel (list MPropF) => False) (ps:=[(l0 ++ A1 :: A1 --> A2 :: l1, l2 ++ A2 :: l3)])
+  (l0 ++ A1 --> A2 :: l1, l2 ++ A1 --> A2 :: l3) H d4). assumption.
+- intros. assert (GLRRule [(XBoxed_list (top_boxes (l0 ++ Box A :: l1)) ++ [Box A], [A])] (l0 ++ Box A :: l1, l2 ++ Box A :: l3)).
+  apply GLRRule_I. apply is_Boxed_list_top_boxes. rewrite top_boxes_distr_app. simpl. apply univ_gen_ext_combine.
+  apply nobox_gen_ext_top_boxes. apply univ_gen_ext_cons. apply nobox_gen_ext_top_boxes.
+  rewrite top_boxes_distr_app in X. simpl in X. rewrite XBox_app_distrib in X. simpl in X.
+  repeat rewrite <- app_assoc in X. simpl in X.
+  pose (IHA (XBoxed_list (top_boxes l0)) (Box A :: XBoxed_list (top_boxes l1) ++ [Box A]) [] []).
+  simpl in d. pose (dlCons d DersNilF). apply GLR in X.
+  pose (derI (rules:=GLS_rules) (prems:=fun _ : rel (list MPropF) => False) (ps:=[(XBoxed_list (top_boxes l0) ++ A :: Box A :: XBoxed_list (top_boxes l1) ++ [Box A], [A])])
+  (l0 ++ Box A :: l1, l2 ++ Box A :: l3) X d0). assumption.
+Qed.
+ +
+Definition GLS_prv s := derrec GLS_rules (fun _ => False) s.
+Definition GLS_drv s := derrec GLS_rules (fun _ => True) s.
+ +
+
+
+ +
+ + + diff --git a/GL.GLS.GLS_ctr.html b/GL.GLS.GLS_ctr.html new file mode 100644 index 0000000..051dba8 --- /dev/null +++ b/GL.GLS.GLS_ctr.html @@ -0,0 +1,1167 @@ + + + + + + + + + + + + + +
+
+

GL.GLS.GLS_ctr

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat Arith.
+Require Import Lia.
+ +
+Require Import GLS_calcs.
+Require Import GLS_inv_ImpR_ImpL.
+ +
+Set Implicit Arguments.
+ +
+(* Next are the definitions for contraction of one formula on the left, and
+on the right. Note that while the leftmost occurrence of the formula is kept,
+if we have exchange for our calculus it amounts to the same to keep the rightmost
+formula. *)

+ +
+Inductive ctr_L (fml : MPropF) : relationT Seq :=
+  | ctr_LI Γ0 Γ1 Γ2 Δ : ctr_L fml
+        (Γ0 ++ fml :: Γ1 ++ fml :: Γ2, Δ) (Γ0 ++ fml :: Γ1 ++ Γ2, Δ).
+ +
+Inductive ctr_R (fml : MPropF) : relationT Seq :=
+  | ctr_RI Γ Δ0 Δ1 Δ2 : ctr_R fml
+        (Γ, Δ0 ++ fml :: Δ1 ++ fml :: Δ2) (Γ, Δ0 ++ fml :: Δ1 ++ Δ2).
+ +
+(* Some lemmas on the preservation of inapplicability of rules through contraction. *)
+ +
+Lemma ctr_L_IdP_notapplic : forall s se A,
+    (@ctr_L A s se) ->
+    ((IdPRule [] s) -> False) ->
+    ((IdPRule [] se) -> False).
+Proof.
+intros s se A ctr. induction ctr. intros RA RAc. apply RA.
+inversion RAc. apply app2_find_hole in H. destruct H. destruct s.
+- destruct s.
+  + destruct p. inversion e0. subst. apply IdPRule_I.
+  + destruct p. destruct x.
+    * inversion e0. subst. apply IdPRule_I.
+    * inversion e0. subst.
+      assert (E: (Γ3 ++ # P :: x) ++ A :: Γ1 ++ A :: Γ2 = Γ3 ++ # P :: x ++ A :: Γ1 ++ A :: Γ2).
+      repeat rewrite <- app_assoc. reflexivity. rewrite E. apply IdPRule_I.
+- destruct p. destruct x.
+  + inversion e0. apply IdPRule_I.
+  + inversion e0. subst. apply app2_find_hole in H2. destruct H2. destruct s.
+    * destruct s.
+      { destruct p. subst.
+        assert (E: Γ0 ++ m :: Γ1 ++ m :: # P :: Γ4 = (Γ0 ++ m :: Γ1 ++ [m]) ++ # P :: Γ4).
+        repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E.
+        apply IdPRule_I. }
+      { destruct p. subst.
+        assert (E: Γ0 ++ m :: Γ1 ++ m :: x0 ++ # P :: Γ4 = (Γ0 ++ m :: Γ1 ++ m :: x0) ++ # P :: Γ4).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+        rewrite E. apply IdPRule_I. }
+    * destruct p. destruct x0.
+      { simpl in e1. subst.
+        assert (E: Γ0 ++ m :: (x ++ []) ++ m :: # P :: Γ4 = (Γ0 ++ m :: x ++ [] ++ [m]) ++ # P :: Γ4).
+        repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity.
+        rewrite E. apply IdPRule_I. }
+      { inversion e1. subst.
+        assert (E: Γ0 ++ m :: (x ++ # P :: x0) ++ m :: Γ2 = (Γ0 ++ m :: x) ++ # P :: x0 ++ m :: Γ2).
+        repeat rewrite <- app_assoc. simpl. reflexivity. rewrite E. apply IdPRule_I. }
+Qed.
+ +
+Lemma ctr_L_IdB_notapplic : forall s se A,
+    (@ctr_L A s se) ->
+    ((IdBRule [] s) -> False) ->
+    ((IdBRule [] se) -> False).
+Proof.
+intros s se A ctr. induction ctr. intros RA RAc. apply RA.
+inversion RAc. apply app2_find_hole in H. destruct H. destruct s.
+- destruct s.
+  + destruct p. inversion e0. subst. apply IdBRule_I.
+  + destruct p. destruct x.
+    * inversion e0. subst. apply IdBRule_I.
+    * inversion e0. subst.
+      assert (E: (Γ3 ++ Box A0 :: x) ++ A :: Γ1 ++ A :: Γ2 = Γ3 ++ Box A0 :: x ++ A :: Γ1 ++ A :: Γ2).
+      repeat rewrite <- app_assoc. reflexivity. rewrite E. apply IdBRule_I.
+- destruct p. destruct x.
+  + inversion e0. apply IdBRule_I.
+  + inversion e0. subst. apply app2_find_hole in H2. destruct H2. destruct s.
+    * destruct s.
+      { destruct p. subst.
+        assert (E: Γ0 ++ m :: Γ1 ++ m :: Box A0 :: Γ4 = (Γ0 ++ m :: Γ1 ++ [m]) ++ Box A0 :: Γ4).
+        repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E.
+        apply IdBRule_I. }
+      { destruct p. subst.
+        assert (E: Γ0 ++ m :: Γ1 ++ m :: x0 ++ Box A0 :: Γ4 = (Γ0 ++ m :: Γ1 ++ m :: x0) ++ Box A0 :: Γ4).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+        rewrite E. apply IdBRule_I. }
+    * destruct p. destruct x0.
+      { simpl in e1. subst.
+        assert (E: Γ0 ++ m :: (x ++ []) ++ m :: Box A0 :: Γ4 = (Γ0 ++ m :: x ++ [] ++ [m]) ++ Box A0 :: Γ4).
+        repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity.
+        rewrite E. apply IdBRule_I. }
+      { inversion e1. subst.
+        assert (E: Γ0 ++ m :: (x ++ Box A0 :: x0) ++ m :: Γ2 = (Γ0 ++ m :: x) ++ Box A0 :: x0 ++ m :: Γ2).
+        repeat rewrite <- app_assoc. simpl. reflexivity. rewrite E. apply IdBRule_I. }
+Qed.
+ +
+Lemma ctr_L_BotL_notapplic : forall s se A,
+    (@ctr_L A s se) ->
+    ((BotLRule [] s) -> False) ->
+    ((BotLRule [] se) -> False).
+Proof.
+intros s se A ctr. induction ctr. intros RA RAc. apply RA.
+inversion RAc. apply app2_find_hole in H. destruct H. destruct s.
+- destruct s.
+  + destruct p. inversion e0. subst. apply BotLRule_I.
+  + destruct p. destruct x.
+    * inversion e0. subst. apply BotLRule_I.
+    * inversion e0. subst.
+      assert (E: (Γ3 ++ :: x) ++ A :: Γ1 ++ A :: Γ2 = Γ3 ++ :: x ++ A :: Γ1 ++ A :: Γ2).
+      repeat rewrite <- app_assoc. reflexivity. rewrite E. apply BotLRule_I.
+- destruct p. destruct x.
+  + inversion e0. apply BotLRule_I.
+  + inversion e0. subst. apply app2_find_hole in H2. destruct H2. destruct s.
+    * destruct s.
+      { destruct p. subst.
+        assert (E: Γ0 ++ m :: Γ1 ++ m :: :: Γ4 = (Γ0 ++ m :: Γ1 ++ [m]) ++ :: Γ4).
+        repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E.
+        apply BotLRule_I. }
+      { destruct p. subst.
+        assert (E: Γ0 ++ m :: Γ1 ++ m :: x0 ++ :: Γ4 = (Γ0 ++ m :: Γ1 ++ m :: x0) ++ :: Γ4).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+        rewrite E. apply BotLRule_I. }
+    * destruct p. destruct x0.
+      { simpl in e1. subst.
+        assert (E: Γ0 ++ m :: (x ++ []) ++ m :: :: Γ4 = (Γ0 ++ m :: x ++ [] ++ [m]) ++ :: Γ4).
+        repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity.
+        rewrite E. apply BotLRule_I. }
+      { inversion e1. subst.
+        assert (E: Γ0 ++ m :: (x ++ :: x0) ++ m :: Γ2 = (Γ0 ++ m :: x) ++ :: x0 ++ m :: Γ2).
+        repeat rewrite <- app_assoc. simpl. reflexivity. rewrite E. apply BotLRule_I. }
+Qed.
+ +
+Lemma ctr_R_IdP_notapplic : forall s se A,
+    (@ctr_R A s se) ->
+    ((IdPRule [] s) -> False) ->
+    ((IdPRule [] se) -> False).
+Proof.
+intros s se A ctr. induction ctr. intros RA RAc. apply RA.
+inversion RAc. apply app2_find_hole in H1. destruct H1. destruct s.
+- destruct s.
+  + destruct p. inversion e0. subst. apply IdPRule_I.
+  + destruct p. destruct x.
+    * inversion e0. subst. apply IdPRule_I.
+    * inversion e0. subst.
+      assert (E: (Δ3 ++ # P :: x) ++ A :: Δ1 ++ A :: Δ2 = Δ3 ++ # P :: x ++ A :: Δ1 ++ A :: Δ2).
+      repeat rewrite <- app_assoc. reflexivity. rewrite E. apply IdPRule_I.
+- destruct p. destruct x.
+  + inversion e0. apply IdPRule_I.
+  + inversion e0. subst. apply app2_find_hole in H2. destruct H2. destruct s.
+    * destruct s.
+      { destruct p. subst.
+        assert (E: Δ0 ++ m :: Δ1 ++ m :: # P :: Δ4 = (Δ0 ++ m :: Δ1 ++ [m]) ++ # P :: Δ4).
+        repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E.
+        apply IdPRule_I. }
+      { destruct p. subst.
+        assert (E: Δ0 ++ m :: Δ1 ++ m :: x0 ++ # P :: Δ4 = (Δ0 ++ m :: Δ1 ++ m :: x0) ++ # P :: Δ4).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+        rewrite E. apply IdPRule_I. }
+    * destruct p. destruct x0.
+      { simpl in e1. subst.
+        assert (E: Δ0 ++ m :: (x ++ []) ++ m :: # P :: Δ4 = (Δ0 ++ m :: x ++ [] ++ [m]) ++ # P :: Δ4).
+        repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity.
+        rewrite E. apply IdPRule_I. }
+      { inversion e1. subst.
+        assert (E: Δ0 ++ m :: (x ++ # P :: x0) ++ m :: Δ2 = (Δ0 ++ m :: x) ++ # P :: x0 ++ m :: Δ2).
+        repeat rewrite <- app_assoc. simpl. reflexivity. rewrite E. apply IdPRule_I. }
+Qed.
+ +
+Lemma ctr_R_IdB_notapplic : forall s se A,
+    (@ctr_R A s se) ->
+    ((IdBRule [] s) -> False) ->
+    ((IdBRule [] se) -> False).
+Proof.
+intros s se A ctr. induction ctr. intros RA RAc. apply RA.
+inversion RAc. apply app2_find_hole in H1. destruct H1. destruct s.
+- destruct s.
+  + destruct p. inversion e0. subst. apply IdBRule_I.
+  + destruct p. destruct x.
+    * inversion e0. subst. apply IdBRule_I.
+    * inversion e0. subst.
+      assert (E: (Δ3 ++ Box A0 :: x) ++ A :: Δ1 ++ A :: Δ2 = Δ3 ++ Box A0 :: x ++ A :: Δ1 ++ A :: Δ2).
+      repeat rewrite <- app_assoc. reflexivity. rewrite E. apply IdBRule_I.
+- destruct p. destruct x.
+  + inversion e0. apply IdBRule_I.
+  + inversion e0. subst. apply app2_find_hole in H2. destruct H2. destruct s.
+    * destruct s.
+      { destruct p. subst.
+        assert (E: Δ0 ++ m :: Δ1 ++ m :: Box A0 :: Δ4 = (Δ0 ++ m :: Δ1 ++ [m]) ++ Box A0 :: Δ4).
+        repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E.
+        apply IdBRule_I. }
+      { destruct p. subst.
+        assert (E: Δ0 ++ m :: Δ1 ++ m :: x0 ++ Box A0 :: Δ4 = (Δ0 ++ m :: Δ1 ++ m :: x0) ++ Box A0 :: Δ4).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+        rewrite E. apply IdBRule_I. }
+    * destruct p. destruct x0.
+      { simpl in e1. subst.
+        assert (E: Δ0 ++ m :: (x ++ []) ++ m :: Box A0 :: Δ4 = (Δ0 ++ m :: x ++ [] ++ [m]) ++ Box A0 :: Δ4).
+        repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity.
+        rewrite E. apply IdBRule_I. }
+      { inversion e1. subst.
+        assert (E: Δ0 ++ m :: (x ++ Box A0 :: x0) ++ m :: Δ2 = (Δ0 ++ m :: x) ++ Box A0 :: x0 ++ m :: Δ2).
+        repeat rewrite <- app_assoc. simpl. reflexivity. rewrite E. apply IdBRule_I. }
+Qed.
+ +
+Lemma ctr_R_BotL_notapplic : forall s se A,
+    (@ctr_R A s se) ->
+    ((BotLRule [] s) -> False) ->
+    ((BotLRule [] se) -> False).
+Proof.
+intros s se A ctr RA RAe. apply RA.
+inversion RAe. destruct s. inversion ctr. subst. inversion H3.
+subst. apply BotLRule_I.
+Qed.
+ +
+(* The following lemmas make sure that if a rule is applied on a sequent s with
+premises ps, then the same rule is applicable on a sequent sc which is a contracted
+version of s, with some premises psc that are such that they are either the same premises
+(in case the contracted formula was weakened) or contracted versions of ps. *)

+ +
+Lemma ImpR_app_ctr_L : forall s sc A ps,
+  (@ctr_L A s sc) ->
+  (ImpRRule [ps] s) ->
+  (existsT2 psc, (ImpRRule [psc] sc) * (@ctr_L A ps psc)).
+Proof.
+intros s sc A ps ctr RA. inversion RA. inversion ctr. subst.
+inversion H. subst. apply app2_find_hole in H1. destruct H1. destruct s.
+- destruct s.
+  + destruct p. subst. exists (Γ2 ++ A0 :: A :: Γ3 ++ Γ4, Δ0 ++ B :: Δ1).
+    split. apply ImpRRule_I.
+    assert (E1: Γ2 ++ A0 :: A :: Γ3 ++ A :: Γ4 = (Γ2 ++ [A0]) ++ A :: Γ3 ++ A :: Γ4).
+    repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E1.
+    assert (E2: Γ2 ++ A0 :: A :: Γ3 ++ Γ4 = (Γ2 ++ [A0]) ++ A :: Γ3 ++ Γ4).
+    repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E2.
+    apply ctr_LI.
+  + destruct p. subst. destruct x.
+    * simpl in e0. subst. repeat rewrite app_nil_r.
+      exists (Γ2 ++ A0 :: A :: Γ3 ++ Γ4, Δ0 ++ B :: Δ1). split. apply ImpRRule_I.
+      assert (E1: Γ2 ++ A0 :: A :: Γ3 ++ A :: Γ4 = (Γ2 ++ [A0]) ++ A :: Γ3 ++ A :: Γ4).
+      repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E1.
+      assert (E2: Γ2 ++ A0 :: A :: Γ3 ++ Γ4 = (Γ2 ++ [A0]) ++ A :: Γ3 ++ Γ4).
+      repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E2.
+      apply ctr_LI.
+    * inversion e0. subst. apply app2_find_hole in H2. destruct H2. destruct s.
+      { destruct s.
+        - destruct p. subst. exists ((Γ2 ++ m :: Γ3) ++ A0 :: Γ4, Δ0 ++ B :: Δ1).
+          split.
+          assert (E: Γ2 ++ m :: Γ3 ++ Γ4 = (Γ2 ++ m :: Γ3) ++ Γ4).
+          rewrite <- app_assoc. reflexivity. rewrite E. apply ImpRRule_I.
+          assert (E1: (Γ2 ++ m :: Γ3) ++ A0 :: m :: Γ4 = Γ2 ++ m :: (Γ3 ++ [A0]) ++ m :: Γ4).
+          repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E1.
+          assert (E2: (Γ2 ++ m :: Γ3) ++ A0 :: Γ4 = Γ2 ++ m :: (Γ3 ++ [A0]) ++ Γ4).
+          repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E2.
+          apply ctr_LI.
+        - destruct p. subst. destruct x0.
+          + simpl in e1. subst. repeat rewrite app_nil_r.
+            exists ((Γ2 ++ m :: Γ3) ++ A0 :: Γ4, Δ0 ++ B :: Δ1). split.
+            assert (E: Γ2 ++ m :: Γ3 ++ Γ4 = (Γ2 ++ m :: Γ3) ++ Γ4).
+            rewrite <- app_assoc. reflexivity. rewrite E.
+            apply ImpRRule_I.
+            assert (E1: (Γ2 ++ m :: Γ3) ++ A0 :: m :: Γ4 = Γ2 ++ m :: (Γ3 ++ [A0]) ++ m :: Γ4).
+            repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E1.
+            assert (E2: (Γ2 ++ m :: Γ3) ++ A0 :: Γ4 = Γ2 ++ m :: (Γ3 ++ [A0]) ++ Γ4).
+            repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E2.
+            apply ctr_LI.
+          + inversion e1. subst.
+            exists ((Γ2 ++ m0 :: Γ3 ++ x0) ++ A0 :: Γ1, Δ0 ++ B :: Δ1). split.
+            assert (E: Γ2 ++ m0 :: Γ3 ++ x0 ++ Γ1 = (Γ2 ++ m0 :: Γ3 ++ x0) ++ Γ1).
+            repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E.
+            apply ImpRRule_I.
+            repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. apply ctr_LI. }
+      { destruct p. subst. exists ((Γ2 ++ m :: x) ++ A0 :: x0 ++ Γ4,Δ0 ++ B :: Δ1).
+        split. assert (E: Γ2 ++ m :: (x ++ x0) ++ Γ4 = (Γ2 ++ m :: x) ++ x0 ++ Γ4).
+        repeat rewrite <- app_assoc. reflexivity. rewrite E. apply ImpRRule_I.
+        assert (E1: (Γ2 ++ m :: x) ++ A0 :: x0 ++ m :: Γ4 = Γ2 ++ m :: (x ++ A0 :: x0) ++ m :: Γ4).
+        repeat rewrite <- app_assoc. reflexivity. rewrite E1.
+        assert (E2: (Γ2 ++ m :: x) ++ A0 :: x0 ++ Γ4 = Γ2 ++ m :: (x ++ A0 :: x0) ++ Γ4).
+        repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E2.
+        apply ctr_LI. }
+- destruct p. subst. exists (Γ0 ++ A0 :: x ++ A :: Γ3 ++ Γ4, Δ0 ++ B :: Δ1).
+  split. rewrite <- app_assoc. apply ImpRRule_I.
+  assert (E1: Γ0 ++ A0 :: x ++ A :: Γ3 ++ A :: Γ4 = (Γ0 ++ A0 :: x) ++ A :: Γ3 ++ A :: Γ4).
+  repeat rewrite <- app_assoc. reflexivity. rewrite E1.
+  assert (E2: Γ0 ++ A0 :: x ++ A :: Γ3 ++ Γ4 = (Γ0 ++ A0 :: x) ++ A :: Γ3 ++ Γ4).
+  repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E2.
+  apply ctr_LI.
+Qed.
+ +
+Lemma ImpL_app_ctr_L : forall s sc A ps1 ps2,
+  (@ctr_L A s sc) ->
+  (ImpLRule [ps1;ps2] s) ->
+  ((existsT2 psc1 psc2, (ImpLRule [psc1;psc2] sc) *
+                       (@ctr_L A ps1 psc1) *
+                       (@ctr_L A ps2 psc2))
+  +
+  (existsT2 B C invps11 invps12 invps21 invps22 invpsc11 invpsc22,
+                       (A = Imp B C) *
+                       (ImpLRule [invps11;invps12] ps1) *
+                       (ImpLRule [invps21;invps22] ps2) *
+                       (@ctr_R B invps11 invpsc11) *
+                       (@ctr_L C invps22 invpsc22) *
+                       (ImpLRule [invpsc11;invpsc22] sc))).
+Proof.
+intros s sc A ps1 ps2 ctr RA. inversion RA. inversion ctr. subst. inversion H.
+subst. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
+- inversion e0. subst. right. exists A0. exists B.
+  exists (Γ2 ++ Γ3 ++ Γ4, Δ0 ++ A0 :: A0 :: Δ1). exists (Γ2 ++ Γ3 ++ B :: Γ4, Δ0 ++ A0 :: Δ1).
+  exists (Γ2 ++ B :: Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ B :: Γ3 ++ B :: Γ4, Δ0 ++ Δ1).
+  exists (Γ2 ++ Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ B :: Γ3 ++ Γ4, Δ0 ++ Δ1). repeat split.
+  assert (Γ2 ++ Γ3 ++ Γ4 = (Γ2 ++ Γ3) ++ Γ4). rewrite <- app_assoc. reflexivity. rewrite H0.
+  clear H0. assert (Γ2 ++ Γ3 ++ B :: Γ4 = (Γ2 ++ Γ3) ++ B :: Γ4). rewrite <- app_assoc. reflexivity.
+  rewrite H0. clear H0. assert (Γ2 ++ Γ3 ++ A0 --> B :: Γ4 = (Γ2 ++ Γ3) ++ A0 --> B :: Γ4). rewrite <- app_assoc.
+  reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+  assert (Γ2 ++ B :: Γ3 ++ Γ4 = (Γ2 ++ B :: Γ3) ++ Γ4). rewrite <- app_assoc. reflexivity. rewrite H0.
+  clear H0. assert (Γ2 ++ B :: Γ3 ++ B :: Γ4 = (Γ2 ++ B :: Γ3) ++ B :: Γ4). rewrite <- app_assoc. reflexivity.
+  rewrite H0. clear H0. assert (Γ2 ++ B :: Γ3 ++ A0 --> B :: Γ4 = (Γ2 ++ B :: Γ3) ++ A0 --> B :: Γ4). rewrite <- app_assoc.
+  reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+  assert (Δ0 ++ A0 :: A0 :: Δ1 = Δ0 ++ A0 :: [] ++ A0 :: Δ1). reflexivity. rewrite H0. clear H0.
+  assert (Δ0 ++ A0 :: Δ1 = Δ0 ++ A0 :: [] ++ Δ1). reflexivity. rewrite H0. clear H0.
+  apply ctr_RI.
+- destruct x.
+  * simpl in e0. inversion e0. subst. right. exists A0. exists B.
+    exists (Γ2 ++ Γ3 ++ Γ4, Δ0 ++ A0 :: A0 :: Δ1). exists (Γ2 ++ Γ3 ++ B :: Γ4, Δ0 ++ A0 :: Δ1).
+    exists (Γ2 ++ B :: Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ B :: Γ3 ++ B :: Γ4, Δ0 ++ Δ1).
+    exists (Γ2 ++ Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ B :: Γ3 ++ Γ4, Δ0 ++ Δ1). repeat split.
+    assert (Γ2 ++ Γ3 ++ Γ4 = (Γ2 ++ Γ3) ++ Γ4). repeat rewrite <- app_assoc. reflexivity. rewrite H0.
+    clear H0. assert (Γ2 ++ Γ3 ++ B :: Γ4 = (Γ2 ++ Γ3) ++ B :: Γ4). rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. assert ((Γ2 ++ []) ++ Γ3 ++ A0 --> B :: Γ4 = (Γ2 ++ Γ3) ++ A0 --> B :: Γ4).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+    assert (Γ2 ++ B :: Γ3 ++ Γ4 = (Γ2 ++ B :: Γ3) ++ Γ4). rewrite <- app_assoc. reflexivity. rewrite H0.
+    clear H0. assert (Γ2 ++ B :: Γ3 ++ B :: Γ4 = (Γ2 ++ B :: Γ3) ++ B :: Γ4). rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. assert ((Γ2 ++ []) ++ B :: Γ3 ++ A0 --> B :: Γ4 = (Γ2 ++ B :: Γ3) ++ A0 --> B :: Γ4).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+    assert (Δ0 ++ A0 :: A0 :: Δ1 = Δ0 ++ A0 :: [] ++ A0 :: Δ1). reflexivity. rewrite H0. clear H0.
+    assert (Δ0 ++ A0 :: Δ1 = Δ0 ++ A0 :: [] ++ Δ1). reflexivity. rewrite H0. clear H0.
+    apply ctr_RI.
+  * inversion e0. subst. apply app2_find_hole in H2. destruct H2. repeat destruct s ; destruct p ; subst.
+    + inversion e1. subst. right. exists A0. exists B.
+      exists (Γ2 ++ Γ3 ++ Γ4, Δ0 ++ A0 :: A0 :: Δ1). exists (Γ2 ++ B :: Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1).
+      exists (Γ2 ++ Γ3 ++ B :: Γ4, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ B :: Γ3 ++ B :: Γ4, Δ0 ++ Δ1).
+      exists (Γ2 ++ Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ B :: Γ3 ++ Γ4, Δ0 ++ Δ1). repeat split.
+      repeat rewrite <- app_assoc. apply ImpLRule_I. repeat rewrite <- app_assoc. apply ImpLRule_I.
+      assert (Δ0 ++ A0 :: A0 :: Δ1 = Δ0 ++ A0 :: [] ++ A0 :: Δ1). reflexivity. rewrite H0. clear H0.
+      assert (Δ0 ++ A0 :: Δ1 = Δ0 ++ A0 :: [] ++ Δ1). reflexivity. rewrite H0. clear H0.
+      apply ctr_RI.
+    + destruct x0.
+      { simpl in e1. inversion e1. subst. right. exists A0. exists B.
+        exists (Γ2 ++ Γ3 ++ Γ1, Δ0 ++ A0 :: A0 :: Δ1). exists (Γ2 ++ B :: Γ3 ++ Γ1, Δ0 ++ A0 :: Δ1).
+        exists (Γ2 ++ Γ3 ++ B :: Γ1, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ B :: Γ3 ++ B :: Γ1, Δ0 ++ Δ1).
+        exists (Γ2 ++ Γ3 ++ Γ1, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ B :: Γ3 ++ Γ1, Δ0 ++ Δ1). repeat split.
+        repeat rewrite <- app_assoc. simpl. rewrite app_nil_r. apply ImpLRule_I. repeat rewrite <- app_assoc.
+        rewrite app_nil_r. apply ImpLRule_I.
+        assert (Δ0 ++ A0 :: A0 :: Δ1 = Δ0 ++ A0 :: [] ++ A0 :: Δ1). reflexivity. rewrite H0. clear H0.
+        assert (Δ0 ++ A0 :: Δ1 = Δ0 ++ A0 :: [] ++ Δ1). reflexivity. rewrite H0. clear H0.
+        apply ctr_RI. }
+      { inversion e1. subst. left. exists (Γ2 ++ m0 :: Γ3 ++ x0 ++ Γ1, Δ0 ++ A0 :: Δ1).
+        exists (Γ2 ++ m0 :: Γ3 ++ x0 ++ B :: Γ1, Δ0 ++ Δ1). repeat split.
+        assert (Γ2 ++ m0 :: Γ3 ++ x0 ++ Γ1 = (Γ2 ++ m0 :: Γ3 ++ x0) ++ Γ1). repeat rewrite <- app_assoc.
+        simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ m0 :: Γ3 ++ x0 ++ A0 --> B :: Γ1 = (Γ2 ++ m0 :: Γ3 ++ x0) ++ A0 --> B :: Γ1). repeat rewrite <- app_assoc.
+        simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ m0 :: Γ3 ++ x0 ++ B :: Γ1 = (Γ2 ++ m0 :: Γ3 ++ x0) ++ B :: Γ1). repeat rewrite <- app_assoc.
+        simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. apply ctr_LI.
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. apply ctr_LI. }
+    + destruct x0.
+      { simpl in e1. inversion e1. subst. right. exists A0. exists B.
+        exists (Γ2 ++ x ++ Γ4, Δ0 ++ A0 :: A0 :: Δ1). exists (Γ2 ++ B :: x ++ Γ4, Δ0 ++ A0 :: Δ1).
+        exists (Γ2 ++ x ++ B :: Γ4, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ B :: x ++ B :: Γ4, Δ0 ++ Δ1).
+        exists (Γ2 ++ x ++ Γ4, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ B :: x ++ Γ4, Δ0 ++ Δ1). repeat split.
+        repeat rewrite <- app_assoc. apply ImpLRule_I. repeat rewrite <- app_assoc. apply ImpLRule_I.
+        assert (Δ0 ++ A0 :: A0 :: Δ1 = Δ0 ++ A0 :: [] ++ A0 :: Δ1). reflexivity. rewrite H0. clear H0.
+        assert (Δ0 ++ A0 :: Δ1 = Δ0 ++ A0 :: [] ++ Δ1). reflexivity. rewrite H0. clear H0.
+        apply ctr_RI. rewrite <- app_assoc. simpl. apply ImpLRule_I. }
+      { inversion e1. subst. left. exists (Γ2 ++ m :: x ++ x0 ++ Γ4, Δ0 ++ A0 :: Δ1).
+        exists (Γ2 ++ m :: x ++ B :: x0 ++ Γ4, Δ0 ++ Δ1). repeat split.
+        assert (Γ2 ++ m :: x ++ x0 ++ Γ4 = (Γ2 ++ m :: x) ++ x0 ++ Γ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ m :: x ++ B :: x0 ++ Γ4 = (Γ2 ++ m :: x) ++ B :: x0 ++ Γ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ m :: (x ++ A0 --> B :: x0) ++ Γ4 = (Γ2 ++ m :: x) ++ A0 --> B :: x0 ++ Γ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+        assert ((Γ2 ++ m :: x) ++ x0 ++ m :: Γ4 = Γ2 ++ m :: (x ++ x0) ++ m :: Γ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ m :: x ++ x0 ++ Γ4 = Γ2 ++ m :: (x ++ x0) ++ Γ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0. apply ctr_LI.
+        assert ((Γ2 ++ m :: x) ++ B :: x0 ++ m :: Γ4 = Γ2 ++ m :: (x ++ B :: x0) ++ m :: Γ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ m :: x ++ B :: x0 ++ Γ4 = Γ2 ++ m :: (x ++ B :: x0) ++ Γ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0. apply ctr_LI. }
+- destruct x.
+  + simpl in e0. inversion e0. subst. right. exists A0. exists B.
+    exists (Γ0 ++ Γ3 ++ Γ4, Δ0 ++ A0 :: A0 :: Δ1). exists (Γ0 ++ Γ3 ++ B :: Γ4, Δ0 ++ A0 :: Δ1).
+    exists (Γ0 ++ B :: Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1). exists (Γ0 ++ B :: Γ3 ++ B :: Γ4, Δ0 ++ Δ1).
+    exists (Γ0 ++ Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1). exists (Γ0 ++ B :: Γ3 ++ Γ4, Δ0 ++ Δ1) . repeat split.
+    assert (Γ0 ++ Γ3 ++ Γ4 = (Γ0 ++ Γ3) ++ Γ4). repeat rewrite <- app_assoc. reflexivity. rewrite H0.
+    clear H0. assert (Γ0 ++ Γ3 ++ B :: Γ4 = (Γ0 ++ Γ3) ++ B :: Γ4). rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. assert (Γ0 ++ Γ3 ++ A0 --> B :: Γ4 = (Γ0 ++ Γ3) ++ A0 --> B :: Γ4).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+    assert (Γ0 ++ B :: Γ3 ++ Γ4 = (Γ0 ++ B :: Γ3) ++ Γ4). rewrite <- app_assoc. reflexivity. rewrite H0.
+    clear H0. assert (Γ0 ++ B :: Γ3 ++ B :: Γ4 = (Γ0 ++ B :: Γ3) ++ B :: Γ4). rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. assert (Γ0 ++ B :: Γ3 ++ A0 --> B :: Γ4 = (Γ0 ++ B :: Γ3) ++ A0 --> B :: Γ4).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+    assert (Δ0 ++ A0 :: A0 :: Δ1 = Δ0 ++ A0 :: [] ++ A0 :: Δ1). reflexivity. rewrite H0. clear H0.
+    assert (Δ0 ++ A0 :: Δ1 = Δ0 ++ A0 :: [] ++ Δ1). reflexivity. rewrite H0. clear H0.
+    apply ctr_RI. repeat rewrite <- app_assoc. simpl. apply ImpLRule_I.
+  + inversion e0. subst. left. exists (Γ0 ++ x ++ A :: Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1).
+    exists (Γ0 ++ B :: x ++ A :: Γ3 ++ Γ4, Δ0 ++ Δ1). repeat split. repeat rewrite <- app_assoc.
+    apply ImpLRule_I.
+    assert (Γ0 ++ x ++ A :: Γ3 ++ A :: Γ4 = (Γ0 ++ x) ++ A :: Γ3 ++ A :: Γ4). repeat rewrite <- app_assoc.
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ x ++ A :: Γ3 ++ Γ4 = (Γ0 ++ x) ++ A :: Γ3 ++ Γ4). repeat rewrite <- app_assoc.
+    reflexivity. rewrite H0. clear H0. apply ctr_LI.
+    assert (Γ0 ++ B :: x ++ A :: Γ3 ++ A :: Γ4 = (Γ0 ++ B :: x) ++ A :: Γ3 ++ A :: Γ4). repeat rewrite <- app_assoc.
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ B :: x ++ A :: Γ3 ++ Γ4 = (Γ0 ++ B :: x) ++ A :: Γ3 ++ Γ4). repeat rewrite <- app_assoc.
+    reflexivity. rewrite H0. clear H0. apply ctr_LI.
+Qed.
+ +
+Lemma GLR_app_ctr_L : forall s sc A ps,
+  (@ctr_L A s sc) ->
+  (GLRRule [ps] s) ->
+    ((GLRRule [ps] sc) +
+     (existsT2 psc1 psc2, (GLRRule [psc2] sc) * (@ctr_L (unBox_formula A) ps psc1) * (@ctr_L A psc1 psc2))).
+Proof.
+intros s sc A ps ctr RA. inversion RA. inversion ctr. rewrite <- H1 in H2.
+inversion H2. subst. apply univ_gen_ext_elem_deep with (l3:=Γ1) (l4:=Γ2 ++ A :: Γ3) (a:=A) in X.
+destruct X. 3: reflexivity.
+- destruct p. apply univ_gen_ext_elem_deep with (l3:=Γ1 ++ Γ2) (l4:=Γ3) (a:=A) in u. destruct u. destruct p.
+3: rewrite <- app_assoc. 3: reflexivity.
+  * left. apply GLRRule_I.
+    assumption.
+    apply univ_gen_ext_add_elem_deep. rewrite app_assoc. assumption. assumption.
+  * exfalso. apply f. repeat destruct s. repeat destruct p. subst. apply is_box_is_in_boxed_list with (A:=A) in H0 .
+    unfold is_boxedT. destruct H0. exists x1. auto. apply in_or_app. right. apply in_eq.
+- repeat destruct s. repeat destruct p. apply univ_gen_ext_elem_deep with (l3:=Γ2) (l4:=Γ3) (a:=A) in u0.
+  destruct u0. 3: reflexivity.
+  * destruct p. exfalso. subst. apply is_box_is_in_boxed_list with (A:=A) in H0. apply f. unfold is_boxedT.
+    destruct H0. exists x1. auto. apply in_or_app. right. apply in_eq.
+  * repeat destruct s. repeat destruct p. right. subst.
+    exists ((XBoxed_list x) ++ (XBoxed_list [A]) ++ (XBoxed_list x1) ++ A :: (XBoxed_list x2) ++ [Box A0], [A0]).
+    exists (XBoxed_list (x ++ A :: x1 ++ x2) ++ [Box A0], [A0]). split.
+    + split.
+      { apply GLRRule_I.
+        intro. intros. apply H0. apply in_app_or in H. destruct H. apply in_or_app. left. assumption.
+        inversion H. subst. apply in_or_app. right. apply in_eq. apply in_app_or in H1. destruct H1.
+        apply in_or_app. right. apply in_cons. apply in_or_app. left. assumption.
+        apply in_or_app. right. apply in_cons. apply in_or_app. right. apply in_cons.
+        assumption.
+        apply univ_gen_ext_combine. assumption. apply univ_gen_ext_cons. apply univ_gen_ext_combine.
+        assumption. assumption. }
+      { repeat rewrite cons_single. repeat rewrite XBox_app_distrib. simpl.
+        assert (E1: (XBoxed_list x ++ unBox_formula A :: A :: XBoxed_list x1 ++ unBox_formula A :: A :: XBoxed_list x2) ++ [Box A0] =
+                     (XBoxed_list x ++ unBox_formula A :: (A :: XBoxed_list x1) ++ unBox_formula A :: (A :: XBoxed_list x2 ++ [Box A0]))).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E1.
+        assert (E2: XBoxed_list x ++ unBox_formula A :: A :: XBoxed_list x1 ++ A :: XBoxed_list x2 ++ [Box A0] =
+                    XBoxed_list x ++ unBox_formula A :: (A :: XBoxed_list x1) ++ (A :: XBoxed_list x2 ++ [Box A0])).
+        repeat rewrite <- app_assoc. reflexivity. rewrite E2. apply ctr_LI with (Γ2:= A :: XBoxed_list x2 ++ [Box A0]). }
+    + simpl. repeat rewrite XBox_app_distrib. simpl. repeat rewrite XBox_app_distrib.
+      assert (E1: XBoxed_list x ++ unBox_formula A :: A :: XBoxed_list x1 ++ A :: XBoxed_list x2 ++ [Box A0] =
+                  (XBoxed_list x ++ [unBox_formula A]) ++ A :: XBoxed_list x1 ++ A :: XBoxed_list x2 ++ [Box A0]).
+      repeat rewrite <- app_assoc. rewrite <- cons_single. reflexivity. rewrite E1.
+      assert (E2: (XBoxed_list x ++ unBox_formula A :: A :: XBoxed_list x1 ++ XBoxed_list x2) ++ [Box A0] =
+                  (XBoxed_list x ++ [unBox_formula A]) ++ A :: XBoxed_list x1 ++ XBoxed_list x2 ++ [Box A0]).
+      repeat rewrite <- app_assoc. rewrite <- cons_single. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E2.
+      apply ctr_LI.
+Qed.
+ +
+Lemma ImpR_app_ctr_R : forall s sc A ps,
+  (@ctr_R A s sc) ->
+  (ImpRRule [ps] s) ->
+  ((existsT2 psc, (ImpRRule [psc] sc) * (@ctr_R A ps psc))
+  +
+  (existsT2 B C invps invpsc0 invpsc, (A = Imp B C) * (ImpRRule [invps] ps) * (ImpRRule [invpsc] sc) *
+                                      (@ctr_L B invps invpsc0) * (@ctr_R C invpsc0 invpsc))).
+Proof.
+intros s sc A ps ctr RA. inversion RA. inversion ctr. subst.
+inversion H. subst. apply app2_find_hole in H2. destruct H2. repeat destruct s ; destruct p ; subst.
+- inversion e0. right. exists A0. exists B. exists (Γ0 ++ A0 :: A0 :: Γ1, Δ2 ++ B :: Δ3 ++ B :: Δ4).
+  exists (Γ0 ++ A0 :: Γ1, Δ2 ++ B :: Δ3 ++ B :: Δ4). exists (Γ0 ++ A0 :: Γ1, Δ2 ++ B :: Δ3 ++ Δ4).
+  repeat split. assert (Δ2 ++ B :: Δ3 ++ B :: Δ4 = (Δ2 ++ B :: Δ3) ++ B :: Δ4). rewrite <- app_assoc. reflexivity.
+  rewrite H0. clear H0. assert (Δ2 ++ B :: Δ3 ++ A0 --> B :: Δ4 = (Δ2 ++ B :: Δ3) ++ A0 --> B :: Δ4). rewrite <- app_assoc. reflexivity.
+  rewrite H0. clear H0. apply ImpRRule_I.
+  assert (Γ0 ++ A0 :: A0 :: Γ1 = Γ0 ++ A0 :: [] ++ A0 :: Γ1). reflexivity. rewrite H0. clear H0.
+  assert (Γ0 ++ A0 :: Γ1 = Γ0 ++ A0 :: [] ++ Γ1). reflexivity. rewrite H0. clear H0.
+  apply ctr_LI.
+- destruct x.
+  * simpl in e0. inversion e0. subst. right. exists A0. exists B.
+    exists (Γ0 ++ A0 :: A0 :: Γ1, (Δ2 ++ []) ++ B :: Δ3 ++ B :: Δ4).
+    exists (Γ0 ++ A0 :: Γ1, (Δ2 ++ []) ++ B :: Δ3 ++ B :: Δ4). exists (Γ0 ++ A0 :: Γ1, (Δ2 ++ []) ++ B :: Δ3 ++ Δ4).
+    repeat split. assert ((Δ2 ++ []) ++ B :: Δ3 ++ B :: Δ4 = (Δ2 ++ B :: Δ3) ++ B :: Δ4). repeat rewrite <- app_assoc.
+    reflexivity. rewrite H0. clear H0. assert ((Δ2 ++ []) ++ B :: Δ3 ++ A0 --> B :: Δ4 = (Δ2 ++ B :: Δ3) ++ A0 --> B :: Δ4).
+    rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    apply ImpRRule_I. repeat rewrite <- app_assoc. simpl. apply ImpRRule_I.
+    assert (Γ0 ++ A0 :: A0 :: Γ1 = Γ0 ++ A0 :: [] ++ A0 :: Γ1). reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ A0 :: Γ1 = Γ0 ++ A0 :: [] ++ Γ1). reflexivity. rewrite H0. clear H0.
+    apply ctr_LI.
+  * inversion e0. subst. apply app2_find_hole in H2. destruct H2. repeat destruct s ; destruct p ; subst.
+    + inversion e1. subst. right. exists A0. exists B.
+      exists (Γ0 ++ A0 :: A0 :: Γ1, Δ2 ++ B :: Δ3 ++ B :: Δ4). exists (Γ0 ++ A0 :: Γ1, Δ2 ++ B :: Δ3 ++ B :: Δ4).
+      exists (Γ0 ++ A0 :: Γ1, Δ2 ++ B :: Δ3 ++ Δ4). repeat split.
+      repeat rewrite <- app_assoc. apply ImpRRule_I.
+      assert (Γ0 ++ A0 :: A0 :: Γ1 = Γ0 ++ A0 :: [] ++ A0 :: Γ1). reflexivity. rewrite H0. clear H0.
+      assert (Γ0 ++ A0 :: Γ1 = Γ0 ++ A0 :: [] ++ Γ1). reflexivity. rewrite H0. clear H0.
+      apply ctr_LI.
+    + destruct x0.
+      { simpl in e1. inversion e1. subst. right. exists A0. exists B.
+        exists (Γ0 ++ A0 :: A0 :: Γ1, Δ2 ++ B :: Δ3 ++ B :: Δ1). exists (Γ0 ++ A0 :: Γ1, Δ2 ++ B :: Δ3 ++ B :: Δ1).
+        exists (Γ0 ++ A0 :: Γ1, Δ2 ++ B :: Δ3 ++ Δ1). repeat split.
+        repeat rewrite <- app_assoc. simpl. rewrite app_nil_r. apply ImpRRule_I.
+        assert (Γ0 ++ A0 :: A0 :: Γ1 = Γ0 ++ A0 :: [] ++ A0 :: Γ1). reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ A0 :: Γ1 = Γ0 ++ A0 :: [] ++ Γ1). reflexivity. rewrite H0. clear H0.
+        apply ctr_LI. }
+      { inversion e1. subst. left. exists (Γ0 ++ A0 :: Γ1, Δ2 ++ m0 :: Δ3 ++ x0 ++ B :: Δ1).
+        repeat split. assert (Δ2 ++ m0 :: Δ3 ++ x0 ++ B :: Δ1 = (Δ2 ++ m0 :: Δ3 ++ x0) ++ B :: Δ1).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Δ2 ++ m0 :: Δ3 ++ x0 ++ A0 --> B :: Δ1 = (Δ2 ++ m0 :: Δ3 ++ x0) ++ A0 --> B :: Δ1). repeat rewrite <- app_assoc.
+        simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. apply ctr_RI. }
+    + destruct x0.
+      { simpl in e1. inversion e1. subst. right. exists A0. exists B.
+        exists (Γ0 ++ A0 :: A0 :: Γ1, Δ2 ++ B :: x ++ B :: Δ4). exists (Γ0 ++ A0 :: Γ1, Δ2 ++ B :: x ++ B :: Δ4).
+        exists (Γ0 ++ A0 :: Γ1, Δ2 ++ B :: x ++ Δ4). repeat split.
+        repeat rewrite <- app_assoc. apply ImpRRule_I. repeat rewrite <- app_assoc. apply ImpRRule_I.
+        assert (Γ0 ++ A0 :: A0 :: Γ1 = Γ0 ++ A0 :: [] ++ A0 :: Γ1). reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ A0 :: Γ1 = Γ0 ++ A0 :: [] ++ Γ1). reflexivity. rewrite H0. clear H0.
+        apply ctr_LI. }
+      { inversion e1. subst. left. exists (Γ0 ++ A0 :: Γ1, Δ2 ++ m :: x ++ B :: x0 ++ Δ4).
+        repeat split.
+        assert (Δ2 ++ m :: x ++ B :: x0 ++ Δ4 = (Δ2 ++ m :: x) ++ B :: x0 ++ Δ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Δ2 ++ m :: (x ++ A0 --> B :: x0) ++ Δ4 = (Δ2 ++ m :: x) ++ A0 --> B :: x0 ++ Δ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+        assert ((Δ2 ++ m :: x) ++ B :: x0 ++ m :: Δ4 = Δ2 ++ m :: (x ++ B :: x0) ++ m :: Δ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Δ2 ++ m :: x ++ B :: x0 ++ Δ4 = Δ2 ++ m :: (x ++ B :: x0) ++ Δ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0. apply ctr_RI. }
+- destruct x.
+  + simpl in e0. inversion e0. subst. right. exists A0. exists B.
+    exists (Γ0 ++ A0 :: A0 :: Γ1, Δ0 ++ B :: Δ3 ++ B :: Δ4). exists (Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ3 ++ B :: Δ4).
+    exists (Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ3 ++ Δ4). repeat split.
+    assert (Δ0 ++ B :: Δ3 ++ A0 --> B :: Δ4 = (Δ0 ++ B :: Δ3) ++ A0 --> B :: Δ4). repeat rewrite <- app_assoc. reflexivity. rewrite H0.
+    clear H0. assert (Δ0 ++ B :: Δ3 ++ B :: Δ4 = (Δ0 ++ B :: Δ3) ++ B :: Δ4). rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply ImpRRule_I. repeat rewrite <- app_assoc. simpl. apply ImpRRule_I.
+    assert (Γ0 ++ A0 :: A0 :: Γ1 = Γ0 ++ A0 :: [] ++ A0 :: Γ1). reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ A0 :: Γ1 = Γ0 ++ A0 :: [] ++ Γ1). reflexivity. rewrite H0. clear H0.
+    apply ctr_LI.
+  + inversion e0. subst. left. exists (Γ0 ++ A0 :: Γ1, Δ0 ++ B :: x ++ A :: Δ3 ++ Δ4).
+    repeat split. repeat rewrite <- app_assoc. apply ImpRRule_I.
+    assert (Δ0 ++ B :: x ++ A :: Δ3 ++ A :: Δ4 = (Δ0 ++ B :: x) ++ A :: Δ3 ++ A :: Δ4). repeat rewrite <- app_assoc.
+    reflexivity. rewrite H0. clear H0.
+    assert (Δ0 ++ B :: x ++ A :: Δ3 ++ Δ4 = (Δ0 ++ B :: x) ++ A :: Δ3 ++ Δ4). repeat rewrite <- app_assoc.
+    reflexivity. rewrite H0. clear H0. apply ctr_RI.
+Qed.
+ +
+Lemma ImpL_app_ctr_R : forall s sc A ps1 ps2,
+  (@ctr_R A s sc) ->
+  (ImpLRule [ps1;ps2] s) ->
+  (existsT2 psc1 psc2, (ImpLRule [psc1;psc2] sc) * (@ctr_R A ps1 psc1) * (@ctr_R A ps2 psc2)).
+Proof.
+intros s sc A ps1 ps2 ctr RA. inversion RA. inversion ctr. subst.
+inversion H. subst. apply app2_find_hole in H2. destruct H2. destruct s.
+- destruct s.
+  + destruct p. subst. exists (Γ0 ++ Γ1, Δ2 ++ A0 :: A :: Δ3 ++ Δ4). exists (Γ0 ++ B :: Γ1, Δ2 ++ A :: Δ3 ++ Δ4).
+    split. split.
+    apply ImpLRule_I.
+    assert (E1: Δ2 ++ A0 :: A :: Δ3 ++ A :: Δ4 = (Δ2 ++ [A0]) ++ A :: Δ3 ++ A :: Δ4).
+    repeat rewrite <- app_assoc. rewrite cons_single. reflexivity. rewrite E1.
+    assert (E2: Δ2 ++ A0 :: A :: Δ3 ++ Δ4 = (Δ2 ++ [A0]) ++ A :: Δ3 ++ Δ4).
+    repeat rewrite <- app_assoc. rewrite cons_single. reflexivity. rewrite E2. apply ctr_RI.
+    apply ctr_RI.
+  + destruct p. destruct x.
+    * rewrite app_nil_r in e. rewrite app_nil_l in e0. subst.
+      exists (Γ0 ++ Γ1, Δ2 ++ A0 :: A :: Δ3 ++ Δ4). exists (Γ0 ++ B :: Γ1, Δ2 ++ A :: Δ3 ++ Δ4).
+      split. split.
+      apply ImpLRule_I.
+      assert (E1: Δ2 ++ A0 :: A :: Δ3 ++ A :: Δ4 = (Δ2 ++ [A0]) ++ A :: Δ3 ++ A :: Δ4).
+      repeat rewrite <- app_assoc. rewrite cons_single. reflexivity. rewrite E1.
+      assert (E2: Δ2 ++ A0 :: A :: Δ3 ++ Δ4 = (Δ2 ++ [A0]) ++ A :: Δ3 ++ Δ4).
+      repeat rewrite <- app_assoc. rewrite cons_single. reflexivity. rewrite E2. apply ctr_RI.
+      apply ctr_RI.
+    * inversion e0. subst. apply app2_find_hole in H2. destruct H2. destruct s.
+      { destruct s.
+        - destruct p. subst. exists (Γ0 ++ Γ1, (Δ2 ++ m :: Δ3) ++ A0 :: Δ4).
+          exists (Γ0 ++ B :: Γ1, (Δ2 ++ m :: Δ3) ++ Δ4). split. split.
+          assert (E: Δ2 ++ m :: Δ3 ++ Δ4 = (Δ2 ++ m :: Δ3) ++ Δ4).
+          rewrite <- app_assoc. reflexivity. rewrite E.
+          apply ImpLRule_I.
+          assert (E1: (Δ2 ++ m :: Δ3) ++ A0 :: m :: Δ4 = Δ2 ++ m :: (Δ3 ++ [A0]) ++ m :: Δ4).
+          repeat rewrite <- app_assoc. rewrite cons_single. reflexivity. rewrite E1.
+          assert (E2: (Δ2 ++ m :: Δ3) ++ A0 :: Δ4 = Δ2 ++ m :: (Δ3 ++ [A0]) ++ Δ4).
+          repeat rewrite <- app_assoc. rewrite cons_single. reflexivity. rewrite E2. apply ctr_RI.
+          rewrite <- app_assoc. simpl. apply ctr_RI.
+        - destruct p. subst. destruct x0.
+          + rewrite app_nil_l in e1. rewrite app_nil_r in e0. subst.
+            exists (Γ0 ++ Γ1,(Δ2 ++ m :: Δ3) ++ A0 :: Δ4). exists (Γ0 ++ B :: Γ1, (Δ2 ++ m :: Δ3) ++ Δ4).
+            split. split.
+            assert (E: Δ2 ++ m :: Δ3 ++ Δ4 = (Δ2 ++ m :: Δ3) ++ Δ4).
+            rewrite <- app_assoc. reflexivity. rewrite E.
+            apply ImpLRule_I.
+            assert (E1: (Δ2 ++ m :: Δ3 ++ []) ++ A0 :: m :: Δ4 = Δ2 ++ m :: (Δ3 ++ [A0]) ++ m :: Δ4).
+            rewrite app_nil_r. repeat rewrite <- app_assoc. rewrite cons_single. reflexivity. rewrite E1.
+            assert (E2: (Δ2 ++ m :: Δ3) ++ A0 :: Δ4 = Δ2 ++ m :: (Δ3 ++ [A0]) ++ Δ4).
+            repeat rewrite <- app_assoc. rewrite cons_single. reflexivity. rewrite E2. apply ctr_RI.
+            rewrite <- app_assoc. simpl. apply ctr_RI.
+          + inversion e1. subst. exists (Γ0 ++ Γ1,(Δ2 ++ m0 :: Δ3 ++ x0) ++ A0 :: Δ1).
+            exists (Γ0 ++ B :: Γ1,(Δ2 ++ m0 :: Δ3 ++ x0) ++ Δ1). split. split.
+            assert (E: Δ2 ++ m0 :: Δ3 ++ x0 ++ Δ1 = (Δ2 ++ m0 :: Δ3 ++ x0) ++ Δ1).
+            rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E.
+            apply ImpLRule_I.
+            assert (E1: (Δ2 ++ m0 :: Δ3 ++ m0 :: x0) ++ A0 :: Δ1 = Δ2 ++ m0 :: Δ3 ++ m0 :: x0 ++ A0 :: Δ1).
+            repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E1.
+            assert (E2: (Δ2 ++ m0 :: Δ3 ++ x0) ++ A0 :: Δ1 = Δ2 ++ m0 :: Δ3 ++ x0 ++ A0 :: Δ1).
+            repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E2. apply ctr_RI.
+            rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. apply ctr_RI. }
+      { destruct p. subst. exists (Γ0 ++ Γ1,(Δ2 ++ m :: x) ++ A0 :: x0 ++ Δ4).
+        exists (Γ0 ++ B :: Γ1, (Δ2 ++ m :: x) ++ x0 ++ Δ4). split. split.
+        assert (E: Δ2 ++ m :: (x ++ x0) ++ Δ4 = (Δ2 ++ m :: x) ++ x0 ++ Δ4).
+        rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E.
+        apply ImpLRule_I.
+        assert (E1: (Δ2 ++ m :: x) ++ A0 :: x0 ++ m :: Δ4 = Δ2 ++ m :: (x ++ A0 :: x0) ++ m :: Δ4).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E1.
+        assert (E2: (Δ2 ++ m :: x) ++ A0 :: x0 ++ Δ4 = Δ2 ++ m :: (x ++ A0 :: x0) ++ Δ4).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E2. apply ctr_RI.
+        assert (E1: (Δ2 ++ m :: x) ++ x0 ++ Δ4 = Δ2 ++ m :: (x ++ x0) ++ Δ4).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E1. apply ctr_RI. }
+- destruct p. subst. exists (Γ0 ++ Γ1, Δ0 ++ A0 :: x ++ A :: Δ3 ++ Δ4).
+  exists (Γ0 ++ B :: Γ1, Δ0 ++ x ++ A :: Δ3 ++ Δ4). split. split.
+  rewrite <- app_assoc. apply ImpLRule_I.
+  assert (E1: Δ0 ++ A0 :: x ++ A :: Δ3 ++ A :: Δ4 = (Δ0 ++ A0 :: x) ++ A :: Δ3 ++ A :: Δ4).
+  repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E1.
+  assert (E2: Δ0 ++ A0 :: x ++ A :: Δ3 ++ Δ4 = (Δ0 ++ A0 :: x) ++ A :: Δ3 ++ Δ4).
+  repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E2. apply ctr_RI.
+  rewrite app_assoc. apply ctr_RI.
+Qed.
+ +
+Lemma GLR_app_ctr_R : forall s sc A ps,
+  (@ctr_R A s sc) -> (GLRRule [ps] s) -> (GLRRule [ps] sc).
+Proof.
+intros s sc A ps ctr RA. inversion RA. inversion ctr. rewrite <- H1 in H2.
+inversion H2. apply app2_find_hole in H6. destruct H6. destruct s0.
+  + destruct s0.
+    * destruct p. inversion e0. apply GLRRule_I. assumption. assumption.
+    * destruct p. subst. destruct x.
+      { rewrite app_nil_l in e0. inversion e0. subst. apply GLRRule_I.
+        assumption. assumption. }
+      { inversion e0. subst. apply app2_find_hole in H3. destruct H3. destruct s.
+        - destruct s.
+          + destruct p. inversion e1. apply GLRRule_I. assumption. assumption.
+          + destruct p. subst. destruct x0.
+            * rewrite app_nil_l in e1. inversion e1. subst. apply GLRRule_I. assumption.
+              assumption.
+            * inversion e1. subst. assert (E: Δ2 ++ m0 :: Δ3 ++ x0 ++ Box A0 :: Δ1 = (Δ2 ++ m0 :: Δ3 ++ x0) ++ Box A0 :: Δ1).
+              repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E. apply GLRRule_I. assumption.
+              assumption.
+        - destruct p. subst. destruct x0.
+          * rewrite app_nil_l in e1. inversion e1. subst. apply GLRRule_I. assumption. assumption.
+          * inversion e1. subst. assert (E: Δ2 ++ m :: (x ++ Box A0 :: x0) ++ Δ4 = (Δ2 ++ m :: x) ++ Box A0 :: x0 ++ Δ4).
+            repeat rewrite <- app_assoc. reflexivity. rewrite E. apply GLRRule_I. assumption. assumption. }
+  + destruct p. subst. destruct x.
+    * rewrite app_nil_l in e0. rewrite app_nil_r. inversion e0. subst. apply GLRRule_I. assumption. assumption.
+    * inversion e0. rewrite <- app_assoc. simpl. apply GLRRule_I. assumption. assumption.
+Qed.
+ +
+(* Now we can prove that contractions are height-preserving admissible. *)
+ +
+Theorem GLS_hpadm_ctr_LR : forall (k : nat) s
+        (D0 : GLS_prv s),
+        k = (derrec_height D0) ->
+          (forall sc A, (((@ctr_L A s sc) + (@ctr_R A s sc)) ->
+          existsT2 (D1 : GLS_prv sc),
+          derrec_height D1 <= k)).
+Proof.
+induction k as [n IH] using (well_founded_induction_type lt_wf).
+intros s D0. remember D0 as D0'. destruct D0.
+(* D0 ip a leaf *)
+- intros hei sc A ctr. inversion f.
+(* D0 is ends with an application of rule *)
+- intros hei sc A ctr. destruct ctr as [ctr | ctr].
+{ inversion ctr. assert (DersNil: dersrec GLS_rules (fun _ : Seq => False) []).
+  apply dersrec_nil. inversion g.
+  (* IdP *)
+  * inversion H1. rewrite <- H in H5. inversion H5.
+    apply app2_find_hole in H7. destruct H7. destruct s.
+    + destruct s.
+      { destruct p. inversion e0. subst. pose (IdPRule_I P Γ3 (Γ1 ++ Γ2) Δ0 Δ1). apply IdP in i. simpl in i.
+        pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (Γ3 ++ # P :: Γ1 ++ Γ2, Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl. repeat rewrite dersrec_height_nil.
+        left. reflexivity. reflexivity. }
+      { destruct p. destruct x.
+        - rewrite app_nil_l in e0. inversion e0.
+          subst. pose (IdPRule_I P (Γ3 ++ []) (Γ1 ++ Γ2) Δ0 Δ1). apply IdP in i. simpl in i.
+          pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) ((Γ3 ++ []) ++ # P :: Γ1 ++ Γ2,Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl.
+          repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+        - inversion e0. subst.
+          pose (IdPRule_I P Γ3 (x ++ A :: Γ1 ++ Γ2) Δ0 Δ1). apply IdP in i. simpl in i.
+          assert (E: Γ3 ++ # P :: x ++ A :: Γ1 ++ Γ2 = (Γ3 ++ # P :: x) ++ A :: Γ1 ++ Γ2). repeat rewrite <- app_assoc. reflexivity.
+          rewrite E in i. clear E.
+          pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) ((Γ3 ++ # P :: x) ++ A :: Γ1 ++ Γ2,Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl.
+          repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity. }
+    + destruct p. destruct x.
+      { rewrite app_nil_l in e0. inversion e0. subst.
+        pose (IdPRule_I P Γ0 (Γ1 ++ Γ2) Δ0 Δ1). apply IdP in i. simpl in i.
+        pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (Γ0 ++ # P :: Γ1 ++ Γ2, Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl.
+        repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity. }
+      { inversion e0. subst. apply app2_find_hole in H9. destruct H9. destruct s.
+        - destruct s.
+          + destruct p. inversion e1. subst.
+            pose (IdPRule_I P Γ0 (Γ1 ++ Γ2) Δ0 Δ1). apply IdP in i. simpl in i.
+            pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) (Γ0 ++ # P :: Γ1 ++ Γ2, Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl.
+            repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+          + destruct p. destruct x0.
+            * rewrite app_nil_l in e1. inversion e1. subst.
+              pose (IdPRule_I P Γ0 (Γ1 ++ Γ4) Δ0 Δ1). apply IdP in i. simpl in i.
+              pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+              (ps:=[]) (Γ0 ++ # P :: Γ1 ++ Γ4, Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl.
+              repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+            * inversion e1. subst.
+              pose (IdPRule_I P (Γ0 ++ m0 :: Γ1 ++ x0) Γ4 Δ0 Δ1). apply IdP in i. simpl in i.
+              repeat rewrite <- app_assoc in i. simpl in i. repeat rewrite <- app_assoc in i.
+              pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+              (ps:=[]) (Γ0 ++ m0 :: Γ1 ++ x0 ++ # P :: Γ4,Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl.
+              repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+        - destruct p. destruct x0.
+          + rewrite app_nil_l in e1. inversion e1. subst.
+            pose (IdPRule_I P Γ0 ((x ++ []) ++ Γ2) Δ0 Δ1). apply IdP in i. simpl in i.
+            pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) (Γ0 ++ # P :: (x ++ []) ++ Γ2, Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl.
+            repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+          + inversion e1. subst.
+            pose (IdPRule_I P (Γ0 ++ m :: x) (x0 ++ Γ2) Δ0 Δ1). apply IdP in i. simpl in i.
+            assert (E: (Γ0 ++ m :: x) ++ # P :: x0 ++ Γ2 = Γ0 ++ m :: (x ++ # P :: x0) ++ Γ2). repeat rewrite <- app_assoc. reflexivity.
+            rewrite E in i. clear E.
+            pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) (Γ0 ++ m :: (x ++ # P :: x0) ++ Γ2,Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl.
+            repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity. }
+  (* BotL *)
+  * inversion H1. rewrite <- H in H5. inversion H5.
+    apply app2_find_hole in H7. destruct H7. destruct s.
+    + destruct s.
+      { destruct p. inversion e0. subst. pose (BotLRule_I Γ3 (Γ1 ++ Γ2) Δ). apply BotL in b.
+        pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (Γ3 ++ :: Γ1 ++ Γ2, Δ) b DersNil). exists d0. simpl. repeat rewrite dersrec_height_nil.
+        left. reflexivity. reflexivity. }
+      { destruct p. destruct x.
+        - rewrite app_nil_l in e0. inversion e0.
+          subst. pose (BotLRule_I (Γ3 ++ []) (Γ1 ++ Γ2) Δ). apply BotL in b. simpl in b.
+          pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) ((Γ3 ++ []) ++ :: Γ1 ++ Γ2, Δ) b DersNil). exists d0. simpl.
+          repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+        - inversion e0. subst.
+          pose (BotLRule_I Γ3 (x ++ A :: Γ1 ++ Γ2) Δ). apply BotL in b. simpl in b.
+          assert (E: Γ3 ++ :: x ++ A :: Γ1 ++ Γ2 = (Γ3 ++ :: x) ++ A :: Γ1 ++ Γ2). repeat rewrite <- app_assoc. reflexivity.
+          rewrite E in b. clear E.
+          pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) ((Γ3 ++ :: x) ++ A :: Γ1 ++ Γ2, Δ) b DersNil). exists d0. simpl.
+          repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity. }
+    + destruct p. destruct x.
+      { rewrite app_nil_l in e0. inversion e0. subst.
+        pose (BotLRule_I Γ0 (Γ1 ++ Γ2) Δ). apply BotL in b. simpl in b.
+        pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (Γ0 ++ :: Γ1 ++ Γ2, Δ) b DersNil). exists d0. simpl.
+        repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity. }
+      { inversion e0. subst. apply app2_find_hole in H9. destruct H9. destruct s.
+        - destruct s.
+          + destruct p. inversion e1. subst.
+            pose (BotLRule_I Γ0 (Γ1 ++ Γ2) Δ). apply BotL in b. simpl in b.
+            pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) (Γ0 ++ :: Γ1 ++ Γ2, Δ) b DersNil). exists d0. simpl.
+            repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+          + destruct p. destruct x0.
+            * rewrite app_nil_l in e1. inversion e1. subst.
+              pose (BotLRule_I Γ0 (Γ1 ++ Γ4) Δ). apply BotL in b. simpl in b.
+              pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+              (ps:=[]) (Γ0 ++ :: Γ1 ++ Γ4, Δ) b DersNil). exists d0. simpl.
+              repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+            * inversion e1. subst.
+              pose (BotLRule_I (Γ0 ++ m0 :: Γ1 ++ x0) Γ4 Δ). apply BotL in b. simpl in b.
+              repeat rewrite <- app_assoc in b. simpl in b. repeat rewrite <- app_assoc in b.
+              pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+              (ps:=[]) (Γ0 ++ m0 :: Γ1 ++ x0 ++ :: Γ4, Δ) b DersNil). exists d0. simpl.
+              repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+        - destruct p. destruct x0.
+          + rewrite app_nil_l in e1. inversion e1. subst.
+            pose (BotLRule_I Γ0 ((x ++ []) ++ Γ2) Δ). apply BotL in b. simpl in b.
+            pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) (Γ0 ++ :: (x ++ []) ++ Γ2, Δ) b DersNil). exists d0. simpl.
+            repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+          + inversion e1. subst.
+            pose (BotLRule_I (Γ0 ++ m :: x) (x0 ++ Γ2) Δ). apply BotL in b. simpl in b.
+            assert (E: (Γ0 ++ m :: x) ++ :: x0 ++ Γ2 = Γ0 ++ m :: (x ++ :: x0) ++ Γ2). repeat rewrite <- app_assoc. reflexivity.
+            rewrite E in b. clear E.
+            pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) (Γ0 ++ m :: (x ++ :: x0) ++ Γ2, Δ) b DersNil). exists d0. simpl.
+            repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity. }
+  (* ImpR *)
+  * inversion H1. subst. inversion H5. subst. pose (ImpR_app_ctr_L ctr H1). destruct s. destruct p.
+    apply ImpR in i.
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x]) (Γ0 ++ A :: Γ1 ++ Γ2, Δ0 ++ A0 --> B :: Δ1) i). subst. simpl.
+    remember [(Γ3 ++ A0 :: Γ4, Δ0 ++ B :: Δ1)] as ps'. destruct d. inversion Heqps'.
+    inversion Heqps'. subst. simpl. rewrite dersrec_height_nil. simpl in IH.
+    rewrite dersrec_height_nil in IH. rewrite Nat.max_0_r. rewrite Nat.max_0_r in IH.
+    assert (E: derrec_height d < S (derrec_height d)). auto.
+    assert (E1: derrec_height d = derrec_height d). auto.
+    assert ((ctr_L A (Γ3 ++ A0 :: Γ4, Δ0 ++ B :: Δ1) x) + (ctr_R A (Γ3 ++ A0 :: Γ4, Δ0 ++ B :: Δ1) x)).
+    left. auto.
+    pose (IH (derrec_height d) E (Γ3 ++ A0 :: Γ4, Δ0 ++ B :: Δ1) d E1 x A H).
+    destruct s.
+    pose (dlCons x0 d1). pose (d0 d2). exists d3. simpl. rewrite dersrec_height_nil.
+    rewrite Nat.max_0_r. rewrite <- Nat.succ_le_mono. assumption. reflexivity. reflexivity. reflexivity.
+  (* ImpL *)
+  * inversion H1. subst. inversion H5. subst. pose (ImpL_app_ctr_L ctr H1). destruct s.
+    { repeat destruct s. repeat destruct p. apply ImpL in i.
+      pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[x;x0]) (Γ0 ++ A :: Γ1 ++ Γ2, Δ0 ++ Δ1) i). subst. simpl.
+      remember [(Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1);(Γ3 ++ B :: Γ4, Δ0 ++ Δ1)] as ps'. destruct d.
+      inversion Heqps'. inversion Heqps'. subst.
+      remember [(Γ3 ++ B :: Γ4, Δ0 ++ Δ1)] as ps''. destruct d1. inversion Heqps''.
+      inversion Heqps''. simpl. subst. rewrite dersrec_height_nil. simpl in IH.
+      rewrite dersrec_height_nil in IH. rewrite Nat.max_0_r. rewrite Nat.max_0_r in IH.
+      assert (E1: derrec_height d < S (Init.Nat.max (derrec_height d)(derrec_height d1))).
+      apply Nat.lt_succ_r. apply Nat.le_max_l.
+      assert (E2: derrec_height d = derrec_height d). auto.
+      assert ((ctr_L A (Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1) x) + (ctr_R A (Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1) x)).
+      auto.
+      pose (IH (derrec_height d) E1 (Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1) d E2 x A H).
+      destruct s.
+      assert (E3: derrec_height d1 < S (Init.Nat.max (derrec_height d)(derrec_height d1))).
+      apply Nat.lt_succ_r. apply Nat.le_max_r.
+      assert (E4: derrec_height d1 = derrec_height d1). auto.
+      assert ((ctr_L A (Γ3 ++ B :: Γ4, Δ0 ++ Δ1) x0) + (ctr_R A (Γ3 ++ B :: Γ4, Δ0 ++ Δ1) x0)).
+      auto.
+      pose (IH (derrec_height d1) E3 (Γ3 ++ B :: Γ4, Δ0 ++ Δ1) d1 E4 x0 A H2).
+      destruct s.
+      pose (dlCons x1 (dlCons x2 d2)). pose (d0 d3). exists d4. simpl. rewrite dersrec_height_nil.
+      rewrite Nat.max_0_r. rewrite <- Nat.succ_le_mono. apply Nat.max_le_compat.
+      assumption. assumption. reflexivity. reflexivity. reflexivity. }
+    { simpl. repeat destruct s. repeat destruct p. subst. apply ImpL in i.
+      assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+      pose (@dersrec_derrec2_height (dersrec_height d) _ _ _ _ _ d J30). repeat destruct s.
+      assert (J1: derrec_height x7 = derrec_height x7). reflexivity.
+      pose (ImpR_ImpL_hpinv _ J1). destruct p. clear s. pose (s0 _ _ i1). repeat destruct s.
+      clear s0. destruct p. simpl in IH.
+      assert (J2: derrec_height x9 < S (dersrec_height d)). lia.
+      assert (J3: derrec_height x9 = derrec_height x9). reflexivity.
+      assert (J4: (ctr_L x x1 x5) + (ctr_R x x1 x5)). auto.
+      pose (IH _ J2 _ _ J3 _ _ J4). destruct s.
+      assert (J5: derrec_height x8 = derrec_height x8). reflexivity.
+      pose (ImpR_ImpL_hpinv _ J5). destruct p. clear s. pose (s0 _ _ i0). repeat destruct s.
+      clear s0. destruct p.
+      assert (J6: derrec_height x13 < S (dersrec_height d)). lia.
+      assert (J7: derrec_height x13 = derrec_height x13). reflexivity.
+      assert (J8: (ctr_L x0 x4 x6) + (ctr_R x0 x4 x6)). auto.
+      pose (IH _ J6 _ _ J7 _ _ J8). destruct s. pose (dlCons x14 DersNil). pose (dlCons x11 d0).
+      pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[x5;x6]) (Γ0 ++ x --> x0 :: Γ1 ++ Γ2, Δ0 ++ Δ1) i d1). exists d2. simpl.
+      rewrite dersrec_height_nil. lia. reflexivity. }
+  (* GLR *)
+  * inversion X. rewrite <- H4 in X. pose (GLR_app_ctr_L ctr X). destruct s.
+    { apply GLR in g0. pose (derI (rules:=GLS_rules)
+      (prems:=fun _ : Seq => False) (ps:=[(XBoxed_list ++ [Box A0], [A0])])
+      sc g0). subst. pose (d0 d). exists d1. simpl. reflexivity. }
+    { repeat destruct s. repeat destruct p. apply GLR in g0.
+      remember [(XBoxed_list ++ [Box A0], [A0])] as ps'. destruct d. subst. inversion H4.
+      rewrite Heqps' in H4. inversion H4. subst. simpl. simpl in IH.
+      assert (E1: derrec_height d < S (Init.Nat.max (derrec_height d) (dersrec_height d0))).
+      rewrite dersrec_height_nil. rewrite Nat.max_0_r. apply Nat.lt_succ_r. left. reflexivity.
+      assert (E2: derrec_height d = derrec_height d). auto.
+      assert ((ctr_L (unBox_formula A) (XBoxed_list ++ [Box A0], [A0]) x) +
+      (ctr_R (unBox_formula A) (XBoxed_list ++ [Box A0], [A0]) x)). auto.
+      pose (IH (derrec_height d) E1 ((XBoxed_list ++ [Box A0], [A0])) d E2 x (unBox_formula A) H).
+      destruct s.
+      assert (E3: derrec_height x1 < S (Init.Nat.max (derrec_height d) (dersrec_height d0))).
+      rewrite dersrec_height_nil. rewrite Nat.max_0_r. apply Nat.lt_succ_r. assumption. reflexivity.
+      assert (E4: derrec_height x1 = derrec_height x1). auto.
+      assert ((ctr_L A x x0) + (ctr_R A x x0)). auto.
+      pose (IH (derrec_height x1) E3 x x1 E4 x0 A H0). destruct s.
+      pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[x0]) (Γ0 ++ A :: Γ1 ++ Γ2, Δ) g0). subst. simpl.
+      pose (dlCons x2 d0). pose (d1 d2). exists d3. simpl. rewrite dersrec_height_nil.
+      repeat rewrite Nat.max_0_r. rewrite <- Nat.succ_le_mono.
+      pose (Nat.le_trans (derrec_height x2) (derrec_height x1) (derrec_height d) l0 l).
+      assumption. reflexivity. }}
+{ inversion ctr. assert (DersNil: dersrec GLS_rules (fun _ : Seq => False) []).
+  apply dersrec_nil. inversion g.
+  (* IdP *)
+  * inversion H1. rewrite <- H in H5. inversion H5.
+    apply app2_find_hole in H8. destruct H8. destruct s.
+    + destruct s.
+      { destruct p. inversion e0. subst. pose (IdPRule_I P Γ0 Γ1 Δ3 (Δ1 ++ Δ2)). apply IdP in i. simpl in i.
+        pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (Γ0 ++ # P :: Γ1, Δ3 ++ # P :: Δ1 ++ Δ2) i DersNil). exists d0. simpl. repeat rewrite dersrec_height_nil.
+        left. reflexivity. reflexivity. }
+      { destruct p. destruct x.
+        - rewrite app_nil_l in e0. inversion e0.
+          subst. pose (IdPRule_I P Γ0 Γ1 (Δ3 ++ []) (Δ1 ++ Δ2)). apply IdP in i. simpl in i.
+          pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) (Γ0 ++ # P :: Γ1, (Δ3 ++ []) ++ # P :: Δ1 ++ Δ2) i DersNil). exists d0. simpl.
+          repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+        - inversion e0. subst.
+          pose (IdPRule_I P Γ0 Γ1 Δ3 (x ++ A :: Δ1 ++ Δ2)). apply IdP in i. simpl in i.
+          assert (E: Δ3 ++ # P :: x ++ A :: Δ1 ++ Δ2 = (Δ3 ++ # P :: x) ++ A :: Δ1 ++ Δ2). repeat rewrite <- app_assoc. reflexivity.
+          rewrite E in i. clear E.
+          pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) (Γ0 ++ # P :: Γ1, (Δ3 ++ # P :: x) ++ A :: Δ1 ++ Δ2) i DersNil). exists d0. simpl.
+          repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity. }
+    + destruct p. destruct x.
+      { rewrite app_nil_l in e0. inversion e0. subst.
+        pose (IdPRule_I P Γ0 Γ1 Δ0 (Δ1 ++ Δ2)). apply IdP in i. simpl in i.
+        pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (Γ0 ++ # P :: Γ1, Δ0 ++ # P :: Δ1 ++ Δ2) i DersNil). exists d0. simpl.
+        repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity. }
+      { inversion e0. subst. apply app2_find_hole in H9. destruct H9. destruct s.
+        - destruct s.
+          + destruct p. inversion e1. subst.
+            pose (IdPRule_I P Γ0 Γ1 Δ0 (Δ1 ++ Δ2)). apply IdP in i. simpl in i.
+            pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) (Γ0 ++ # P :: Γ1, Δ0 ++ # P :: Δ1 ++ Δ2) i DersNil). exists d0. simpl.
+            repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+          + destruct p. destruct x0.
+            * rewrite app_nil_l in e1. inversion e1. subst.
+              pose (IdPRule_I P Γ0 Γ1 Δ0 (Δ1 ++ Δ4)). apply IdP in i. simpl in i.
+              pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+              (ps:=[]) (Γ0 ++ # P :: Γ1, Δ0 ++ # P :: Δ1 ++ Δ4) i DersNil). exists d0. simpl.
+              repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+            * inversion e1. subst.
+              pose (IdPRule_I P Γ0 Γ1 (Δ0 ++ m0 :: Δ1 ++ x0) Δ4). apply IdP in i. simpl in i.
+              repeat rewrite <- app_assoc in i. simpl in i. repeat rewrite <- app_assoc in i.
+              pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+              (ps:=[]) (Γ0 ++ # P :: Γ1, Δ0 ++ m0 :: Δ1 ++ x0 ++ # P :: Δ4) i DersNil). exists d0. simpl.
+              repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+        - destruct p. destruct x0.
+          + rewrite app_nil_l in e1. inversion e1. subst.
+            pose (IdPRule_I P Γ0 Γ1 Δ0 ((x ++ []) ++ Δ2)). apply IdP in i. simpl in i.
+            pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) (Γ0 ++ # P :: Γ1, Δ0 ++ # P :: (x ++ []) ++ Δ2) i DersNil). exists d0. simpl.
+            repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+          + inversion e1. subst.
+            pose (IdPRule_I P Γ0 Γ1 (Δ0 ++ m :: x) (x0 ++ Δ2)). apply IdP in i. simpl in i.
+            assert (E: (Δ0 ++ m :: x) ++ # P :: x0 ++ Δ2 = Δ0 ++ m :: (x ++ # P :: x0) ++ Δ2). repeat rewrite <- app_assoc. reflexivity.
+            rewrite E in i. clear E.
+            pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) (Γ0 ++ # P :: Γ1, Δ0 ++ m :: (x ++ # P :: x0) ++ Δ2) i DersNil). exists d0. simpl.
+            repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity. }
+  (* BotL *)
+  * inversion H1. rewrite <- H in H5. inversion H5.
+    pose (BotLRule_I Γ0 Γ1 (Δ0 ++ A :: Δ1 ++ Δ2)). apply BotL in b.
+    pose (derI (rules:=GLS_rules)
+    (prems:=fun _ : Seq => False)
+    (ps:=[]) (Γ0 ++ :: Γ1, Δ0 ++ A :: Δ1 ++ Δ2) b DersNil). subst. exists d0. simpl.
+    repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+  (* ImpR *)
+  * inversion H1. subst. inversion H5. subst. pose (ImpR_app_ctr_R ctr H1). destruct s.
+    { destruct s. destruct p. apply ImpR in i.
+      pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[x]) (Γ0 ++ Γ1, Δ0 ++ A :: Δ1 ++ Δ2) i). subst. simpl.
+      remember [(Γ0 ++ A0 :: Γ1, Δ3 ++ B :: Δ4)] as ps'. destruct d. inversion Heqps'.
+      inversion Heqps'. subst. simpl. rewrite dersrec_height_nil. simpl in IH.
+      rewrite dersrec_height_nil in IH. rewrite Nat.max_0_r. rewrite Nat.max_0_r in IH.
+      assert (E: derrec_height d < S (derrec_height d)). auto.
+      assert (E1: derrec_height d = derrec_height d). auto.
+      assert ((ctr_L A (Γ0 ++ A0 :: Γ1, Δ3 ++ B :: Δ4) x) + (ctr_R A (Γ0 ++ A0 :: Γ1, Δ3 ++ B :: Δ4) x)).
+      auto.
+      pose (IH (derrec_height d) E (Γ0 ++ A0 :: Γ1, Δ3 ++ B :: Δ4) d E1 x A H).
+      destruct s.
+      pose (dlCons x0 d1). pose (d0 d2). exists d3. simpl. rewrite dersrec_height_nil.
+      rewrite Nat.max_0_r. rewrite <- Nat.succ_le_mono. assumption. reflexivity. reflexivity. reflexivity. }
+    { repeat destruct s. repeat destruct p. subst. apply ImpR in i.
+      assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+      pose (dersrec_derrec_height d J30). destruct s.
+      assert (J1: derrec_height x4 = derrec_height x4). reflexivity.
+      pose (ImpR_ImpL_hpinv _ J1). destruct p. clear s0. pose (s _ i0). repeat destruct s0.
+      clear s. simpl in IH.
+      assert (J2: derrec_height x5 < S (dersrec_height d)). lia.
+      assert (J3: derrec_height x5 = derrec_height x5). reflexivity.
+      assert (J4: (ctr_L x x1 x2) + (ctr_R x x1 x2)). auto.
+      pose (IH _ J2 _ _ J3 _ _ J4). destruct s.
+      assert (J5: derrec_height x6 = derrec_height x6). reflexivity.
+      assert (J6: derrec_height x6 < S (dersrec_height d)). lia.
+      assert (J8: (ctr_L x0 x2 x3) + (ctr_R x0 x2 x3)). auto.
+      pose (IH _ J6 _ _ J5 _ _ J8). destruct s. pose (dlCons x7 DersNil).
+      pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[x3]) (Γ0 ++ Γ1, Δ0 ++ x --> x0 :: Δ1 ++ Δ2) i d0). simpl. exists d1. simpl. rewrite dersrec_height_nil.
+      lia. reflexivity. }
+  (* ImpL *)
+  * inversion H1. subst. inversion H5. subst. pose (ImpL_app_ctr_R ctr H1). destruct s.
+    repeat destruct s. repeat destruct p. apply ImpL in i.
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x;x0]) (Γ0 ++ A0 --> B :: Γ1, Δ0 ++ A :: Δ1 ++ Δ2) i). subst. simpl.
+    remember [(Γ0 ++ Γ1, Δ3 ++ A0 :: Δ4);(Γ0 ++ B :: Γ1, Δ3 ++ Δ4)] as ps'. destruct d.
+    inversion Heqps'. inversion Heqps'. subst.
+    remember [(Γ0 ++ B :: Γ1, Δ3 ++ Δ4)] as ps''. destruct d1. inversion Heqps''.
+    inversion Heqps''. simpl. subst. rewrite dersrec_height_nil. simpl in IH.
+    rewrite dersrec_height_nil in IH. rewrite Nat.max_0_r. rewrite Nat.max_0_r in IH.
+    assert (E1: derrec_height d < S (Init.Nat.max (derrec_height d)(derrec_height d1))).
+    apply Nat.lt_succ_r. apply Nat.le_max_l.
+    assert (E2: derrec_height d = derrec_height d). auto.
+    assert ((ctr_L A (Γ0 ++ Γ1, Δ3 ++ A0 :: Δ4) x) + (ctr_R A (Γ0 ++ Γ1, Δ3 ++ A0 :: Δ4) x)).
+    auto.
+    pose (IH (derrec_height d) E1 (Γ0 ++ Γ1, Δ3 ++ A0 :: Δ4) d E2 x A H).
+    destruct s.
+    assert (E3: derrec_height d1 < S (Init.Nat.max (derrec_height d)(derrec_height d1))).
+    apply Nat.lt_succ_r. apply Nat.le_max_r.
+    assert (E4: derrec_height d1 = derrec_height d1). auto.
+    assert ((ctr_L A (Γ0 ++ B :: Γ1, Δ3 ++ Δ4) x0) + (ctr_R A (Γ0 ++ B :: Γ1, Δ3 ++ Δ4) x0)).
+    auto.
+    pose (IH (derrec_height d1) E3 (Γ0 ++ B :: Γ1, Δ3 ++ Δ4) d1 E4 x0 A H0).
+    destruct s.
+    pose (dlCons x1 (dlCons x2 d2)). pose (d0 d3). exists d4. simpl. rewrite dersrec_height_nil.
+    rewrite Nat.max_0_r. rewrite <- Nat.succ_le_mono. apply Nat.max_le_compat.
+    assumption. assumption. reflexivity. reflexivity. reflexivity.
+  (* GLR *)
+  * inversion X. rewrite <- H4 in X. pose (GLR_app_ctr_R ctr X).
+    apply GLR in g0.
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[(XBoxed_list ++ [Box A0], [A0])]) sc g0). subst. simpl. pose (d0 d). exists d1.
+    simpl. rewrite <- Nat.succ_le_mono. left. }
+Qed.
+ +
+Theorem GLS_hpadm_ctr_L : forall (k : nat) s
+        (D0 : GLS_prv s),
+        k = (derrec_height D0) ->
+          (forall sc A, ((@ctr_L A s sc) ->
+          existsT2 (D1 : GLS_prv sc),
+          derrec_height D1 <= k)).
+Proof.
+intros. intros. assert (H1: derrec_height D0 = derrec_height D0). reflexivity.
+assert (H3 : (ctr_L A s sc) + (ctr_R A s sc)). auto.
+pose (@GLS_hpadm_ctr_LR (derrec_height D0) s
+D0 H1 sc A H3). destruct s0. exists x. lia.
+Qed.
+ +
+Theorem GLS_hpadm_ctr_R : forall (k : nat) s
+        (D0 : GLS_prv s),
+        k = (derrec_height D0) ->
+          (forall sc A, ((@ctr_R A s sc) ->
+          existsT2 (D1 : GLS_prv sc),
+          derrec_height D1 <= k)).
+Proof.
+intros. intros. assert (H1: derrec_height D0 = derrec_height D0). reflexivity.
+assert (H3 : (ctr_L A s sc) + (ctr_R A s sc)). auto.
+pose (@GLS_hpadm_ctr_LR (derrec_height D0) s
+D0 H1 sc A H3). destruct s0. exists x. lia.
+Qed.
+ +
+(* We can now prove that contraction of lists is also admissible. *)
+ +
+Theorem GLS_hpadm_list_ctr_L : forall Γ1 (k : nat) Γ0 Γ2 Γ3 Δ
+        (D0 : GLS_prv (Γ0 ++ Γ1 ++ Γ2 ++ Γ1 ++ Γ3,Δ)),
+        k = (derrec_height D0) ->
+          existsT2 (D1 : GLS_prv (Γ0 ++ Γ1 ++ Γ2 ++ Γ3,Δ)),
+          derrec_height D1 <= k.
+Proof.
+induction Γ1.
+- intros. exists D0. rewrite H. auto.
+- intros. assert (H0: derrec_height D0 = derrec_height D0). reflexivity.
+  assert (H1 : ctr_L a (Γ0 ++ (a :: Γ1) ++ Γ2 ++ (a :: Γ1) ++ Γ3, Δ) ((Γ0 ++ [a]) ++ Γ1 ++ Γ2 ++ Γ1 ++ Γ3, Δ)).
+  simpl. assert (Γ0 ++ a :: Γ1 ++ Γ2 ++ a :: Γ1 ++ Γ3 = Γ0 ++ a :: (Γ1 ++ Γ2) ++ a :: (Γ1 ++ Γ3)).
+  repeat rewrite <- app_assoc. reflexivity. rewrite H1.
+  assert ((Γ0 ++ [a]) ++ Γ1 ++ Γ2 ++ Γ1 ++ Γ3 = Γ0 ++ a :: (Γ1 ++ Γ2) ++ Γ1 ++ Γ3). repeat rewrite <- app_assoc.
+  reflexivity. rewrite H2. apply ctr_LI.
+  assert ((ctr_L a (Γ0 ++ (a :: Γ1) ++ Γ2 ++ (a :: Γ1) ++ Γ3, Δ) ((Γ0 ++ [a]) ++ Γ1 ++ Γ2 ++ Γ1 ++ Γ3, Δ)) +
+  (ctr_R a (Γ0 ++ (a :: Γ1) ++ Γ2 ++ (a :: Γ1) ++ Γ3, Δ) ((Γ0 ++ [a]) ++ Γ1 ++ Γ2 ++ Γ1 ++ Γ3, Δ))). auto.
+  pose (@GLS_hpadm_ctr_LR (derrec_height D0) (Γ0 ++ (a :: Γ1) ++ Γ2 ++ (a :: Γ1) ++ Γ3, Δ)
+  D0 H0 ((Γ0 ++ [a]) ++ Γ1 ++ Γ2 ++ Γ1 ++ Γ3, Δ) a H2). destruct s.
+  assert (H3: derrec_height x = derrec_height x). reflexivity.
+  pose (IHΓ1 (derrec_height x) (Γ0 ++ [a]) Γ2 Γ3 Δ x H3). destruct s.
+  assert (Γ0 ++ (a :: Γ1) ++ Γ2 ++ Γ3 = (Γ0 ++ [a]) ++ Γ1 ++ Γ2 ++ Γ3). repeat rewrite <- app_assoc. auto.
+  rewrite H4. exists x0. lia.
+Qed.
+ +
+Theorem GLS_hpadm_list_ctr_R : forall Δ1 (k : nat) Γ Δ0 Δ2 Δ3
+        (D0 : GLS_prv (Γ,Δ0 ++ Δ1 ++ Δ2 ++ Δ1 ++ Δ3)),
+        k = (derrec_height D0) ->
+          existsT2 (D1 : GLS_prv (Γ,Δ0 ++ Δ1 ++ Δ2 ++ Δ3)),
+          derrec_height D1 <= k.
+Proof.
+induction Δ1.
+- intros. exists D0. rewrite H. auto.
+- intros. assert (H0: derrec_height D0 = derrec_height D0). reflexivity.
+  assert (H1 : ctr_R a (Γ, Δ0 ++ (a :: Δ1) ++ Δ2 ++ (a :: Δ1) ++ Δ3) (Γ, (Δ0 ++ [a]) ++ Δ1 ++ Δ2 ++ Δ1 ++ Δ3)).
+  simpl. assert (Δ0 ++ a :: Δ1 ++ Δ2 ++ a :: Δ1 ++ Δ3 = Δ0 ++ a :: (Δ1 ++ Δ2) ++ a :: (Δ1 ++ Δ3)).
+  repeat rewrite <- app_assoc. reflexivity. rewrite H1.
+  assert ((Δ0 ++ [a]) ++ Δ1 ++ Δ2 ++ Δ1 ++ Δ3 = Δ0 ++ a :: (Δ1 ++ Δ2) ++ Δ1 ++ Δ3). repeat rewrite <- app_assoc.
+  reflexivity. rewrite H2. apply ctr_RI.
+  assert ((ctr_L a (Γ, Δ0 ++ (a :: Δ1) ++ Δ2 ++ (a :: Δ1) ++ Δ3) (Γ, (Δ0 ++ [a]) ++ Δ1 ++ Δ2 ++ Δ1 ++ Δ3)) +
+  (ctr_R a (Γ, Δ0 ++ (a :: Δ1) ++ Δ2 ++ (a :: Δ1) ++ Δ3) (Γ, (Δ0 ++ [a]) ++ Δ1 ++ Δ2 ++ Δ1 ++ Δ3))). auto.
+  pose (@GLS_hpadm_ctr_LR (derrec_height D0) (Γ, Δ0 ++ (a :: Δ1) ++ Δ2 ++ (a :: Δ1) ++ Δ3)
+  D0 H0 (Γ, (Δ0 ++ [a]) ++ Δ1 ++ Δ2 ++ Δ1 ++ Δ3) a H2). destruct s.
+  assert (H3: derrec_height x = derrec_height x). reflexivity.
+  pose (IHΔ1 (derrec_height x) Γ (Δ0 ++ [a]) Δ2 Δ3 x H3). destruct s.
+  assert (Δ0 ++ (a :: Δ1) ++ Δ2 ++ Δ3 = (Δ0 ++ [a]) ++ Δ1 ++ Δ2 ++ Δ3). repeat rewrite <- app_assoc. auto.
+  rewrite H4. exists x0. lia.
+Qed.
+ +
+
+
+ +
+ + + diff --git a/GL.GLS.GLS_cut_elim.html b/GL.GLS.GLS_cut_elim.html new file mode 100644 index 0000000..fd60263 --- /dev/null +++ b/GL.GLS.GLS_cut_elim.html @@ -0,0 +1,88 @@ + + + + + + + + + + + + + +
+
+

GL.GLS.GLS_cut_elim

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat.
+Require Import Lia.
+ +
+Require Import GLS_calcs.
+ +
+Require Import GLS_termination_measure.
+Require Import GLS_exch.
+Require Import GLS_ctr.
+Require Import GLS_wkn.
+Require Import GLS_dec.
+Require Import GLS_inv_ImpR_ImpL.
+Require Import GLS_additive_cut.
+ +
+Inductive CutRule : rlsT Seq :=
+  | CutRule_I : forall A Γ0 Γ1 Δ0 Δ1,
+          CutRule [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1) ; (Γ0 ++ A :: Γ1, Δ0 ++ Δ1)]
+                    (Γ0 ++ Γ1, Δ0 ++ Δ1)
+.
+ +
+Inductive GLS_cut_rules : rlsT Seq :=
+  | GLS_woc : forall ps c, GLS_rules ps c -> GLS_cut_rules ps c
+  | iGLS_cut : forall ps c, CutRule ps c -> GLS_cut_rules ps c
+.
+ +
+Definition GLS_cut_prv s := derrec GLS_cut_rules (fun _ => False) s.
+Definition GLS_cut_drv s := derrec GLS_cut_rules (fun _ => True) s.
+ +
+Theorem GLS_cut_elimination : forall s, (GLS_cut_prv s) -> (GLS_prv s).
+Proof.
+intros s D.
+apply derrec_all_rect with
+(Q:= fun x => (GLS_prv x))
+in D ; auto.
+- intros. inversion H.
+- intros ps concl rule ders IH. inversion rule.
+  * subst. apply derI with (ps:=ps) ; auto. apply dersrec_forall. intros. epose (@ForallTD_forall _ _ _ IH c H) ; auto.
+  * subst. inversion H. subst. apply GLS_cut_adm with (A:=A).
+    epose (@ForallTD_forall _ _ _ IH (Γ0 ++ Γ1, Δ0 ++ A :: Δ1)). apply g. apply InT_eq.
+    epose (@ForallTD_forall _ _ _ IH (Γ0 ++ A :: Γ1, Δ0 ++ Δ1)). apply g. apply InT_cons ; apply InT_eq.
+Defined.
+
+
+ +
+ + + diff --git a/GL.GLS.GLS_dec.html b/GL.GLS.GLS_dec.html new file mode 100644 index 0000000..b06d43a --- /dev/null +++ b/GL.GLS.GLS_dec.html @@ -0,0 +1,318 @@ + + + + + + + + + + + + + +
+
+

GL.GLS.GLS_dec

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat.
+Require Import Lia.
+ +
+Require Import GLS_calcs.
+ +
+Set Implicit Arguments.
+ +
+(* In this file we show that the applicability of the rules in GLS is decidable. *)
+ +
+Definition in_top_boxes : forall l A, (In A (top_boxes l)) -> (existsT2 B l1 l2, (A = Box B) * (l = l1 ++ A :: l2)).
+Proof.
+induction l.
+- intros. simpl in H. inversion H.
+- intros. destruct a as [n | | |].
+  * simpl in H. apply IHl in H. destruct H. destruct s. destruct s. destruct p. subst.
+    exists x. exists ([# n] ++ x0). exists x1. auto.
+  * simpl in H. apply IHl in H. destruct H. destruct s. destruct s. destruct p. subst.
+    exists x. exists ([] ++ x0). exists x1. auto.
+  * simpl in H. apply IHl in H. destruct H. destruct s. destruct s. destruct p. subst.
+    exists x. exists ([a1 --> a2] ++ x0). exists x1. auto.
+  * simpl (top_boxes (Box a :: l)) in H. destruct (eq_dec_form (Box a) A).
+    + subst. exists a. exists []. exists l. auto.
+    + subst. assert (H0 : In A (top_boxes l)). inversion H. exfalso. apply n. assumption.
+      assumption. apply IHl in H0. destruct H0. destruct s. destruct s. destruct p.
+      subst. exists x. exists ([Box a] ++ x0). exists x1. auto.
+Qed.
+ +
+Lemma remove_add_rest_gen_ext : forall l (A : MPropF), rest_gen_ext [A] (remove eq_dec_form A l) l.
+Proof.
+induction l.
+- intro A. simpl. apply univ_gen_ext_nil.
+- intro A. pose (IHl A). simpl. destruct (eq_dec_form A a).
+  * subst. apply univ_gen_ext_extra. apply InT_eq.
+    assumption.
+  * apply univ_gen_ext_cons. assumption.
+Qed.
+ +
+Definition dec_prop_var_in : forall s, (existsT2 P, (In (# P) (fst s)) /\ (In (# P) (snd s))) +
+                                      ((existsT2 P, (In (# P) (fst s)) /\ (In (# P) (snd s))) -> False).
+Proof.
+intro. destruct s ; simpl.
+induction l.
+- right. intro. destruct H. destruct a. simpl in H. inversion H.
+- destruct IHl.
+  * destruct s. simpl in a0. destruct a0. left. exists x. simpl. split. auto. assumption.
+  * simpl in *. destruct a as [n | | |].
+    2-4: right ; intro H ; destruct H as (n, H0) ; destruct H0 as (H2 , H3) ; destruct H2 as [H4 | H5] ;
+    [ inversion H4 | apply f ; exists n ; auto].
+    + destruct (In_dec l0 (# n)).
+      { left. exists n ; split ; auto. }
+      { right. intro. destruct H. destruct a. destruct H ; subst.
+        - inversion H ; subst. apply n0. assumption.
+        - apply f. simpl. exists x. firstorder. }
+Defined.
+ +
+Definition dec_is_boxedT : forall (A : MPropF), (is_boxedT A) + ((is_boxedT A) -> False).
+Proof.
+induction A.
+- right. intro. inversion X. inversion H.
+- right. intro. inversion X. inversion H.
+- right. intro. inversion X. inversion H.
+- left. exists A. reflexivity.
+Defined.
+ +
+Definition dec_is_box : forall (A : MPropF), (existsT2 B, A = Box B) + ((existsT2 B, A = Box B ) -> False).
+Proof.
+destruct A.
+- right. intro. destruct H. inversion e.
+- right. intro. destruct H. inversion e.
+- right. intro. destruct H. inversion e.
+- left. exists A. reflexivity.
+Defined.
+ +
+Definition dec_box_in : forall s, (existsT2 (A : MPropF), (In (Box A) (fst s)) /\ (In (Box A) (snd s))) +
+                             ((existsT2 (A : MPropF), (In (Box A) (fst s)) /\ (In (Box A) (snd s))) -> False).
+Proof.
+intro. destruct s.
+induction l.
+- right. intro. destruct H. destruct a. simpl in H. inversion H.
+- destruct IHl.
+  * destruct s. simpl in a0. destruct a0. left. exists x. simpl. split. auto. assumption.
+  * destruct (dec_is_box a).
+    + destruct (In_dec l0 a).
+      { left. destruct s. subst. simpl. exists x. split. auto. assumption. }
+      { right. simpl. intro. destruct H. destruct a0. destruct H.
+        - subst. apply n. assumption.
+        - apply f. simpl. exists x. firstorder. }
+    + right. intro. simpl in H. destruct H. destruct a0. destruct H.
+      { subst. apply f0. exists x. reflexivity. }
+      { apply f. firstorder. }
+Defined.
+ +
+Definition dec_GLS_init_rules : forall (s :Seq) ,
+          ((IdPRule [] s) + (BotLRule [] s)) +
+          (((IdPRule [] s) + (BotLRule [] s)) -> False).
+Proof.
+intro s. destruct s. destruct (dec_prop_var_in (pair l l0)).
+- destruct s. destruct a. left. left. simpl in H. simpl in H0.
+  apply in_splitT in H. destruct H. destruct s. apply in_splitT in H0. destruct H0. destruct s.
+  subst. apply IdPRule_I.
+- destruct (In_dec l (Bot)).
+  + left. apply in_splitT in i. destruct i. destruct s. subst. right. apply BotLRule_I.
+  + right. intro. destruct H.
+    * inversion i. subst. simpl in f. apply f. exists P. split ; apply in_or_app ; right ; apply in_eq.
+    * inversion b. subst. apply n. apply in_or_app. right. apply in_eq.
+Defined.
+ +
+Definition dec_IdP_rule : forall (s :Seq) ,
+          (IdPRule [] s) +
+          ((IdPRule [] s) -> False).
+Proof.
+intro s. destruct s. destruct (dec_prop_var_in (pair l l0)).
+- destruct s. destruct a. left. simpl in H. simpl in H0.
+  apply in_splitT in H. destruct H. destruct s. apply in_splitT in H0. destruct H0. destruct s.
+  subst. apply IdPRule_I.
+- right. intro. destruct H. apply f. exists P. split ; apply in_or_app ; right ; apply in_eq.
+Defined.
+ +
+Definition dec_IdB_rule : forall (s :Seq) ,
+          (IdBRule [] s) +
+          ((IdBRule [] s) -> False).
+Proof.
+intro s. destruct s. destruct (dec_box_in (l, l0)).
+- destruct s. destruct a. left. simpl in H. simpl in H0.
+  apply in_splitT in H. destruct H. destruct s. apply in_splitT in H0. destruct H0. destruct s.
+  subst. apply IdBRule_I.
+- right. intro. destruct H. apply f. exists A. split ; apply in_or_app ; right ; apply in_eq.
+Defined.
+ +
+Definition dec_BotL_rule : forall (s :Seq) ,
+          (BotLRule [] s) +
+          ((BotLRule [] s) -> False).
+Proof.
+intro s. destruct s. destruct (In_dec l (Bot)).
+- left. apply in_splitT in i. destruct i. destruct s. subst. apply BotLRule_I.
+- right. intro. inversion H. apply n. subst. apply in_or_app. right. apply in_eq.
+Defined.
+ +
+Definition dec_init_rules : forall (s :Seq) ,
+          ((IdPRule [] s) + (IdBRule [] s) + (BotLRule [] s)) +
+          (((IdPRule [] s) + (IdBRule [] s) + (BotLRule [] s)) -> False).
+Proof.
+intro s. destruct s. destruct (dec_prop_var_in (pair l l0)).
+- destruct s. destruct a. left. left. left. simpl in H. simpl in H0.
+  apply in_splitT in H. destruct H. destruct s. apply in_splitT in H0. destruct H0. destruct s.
+  subst. apply IdPRule_I.
+- destruct (In_dec l (Bot)).
+  + left. right. apply in_splitT in i. destruct i. destruct s. subst. apply BotLRule_I.
+  + destruct (dec_box_in (l, l0)).
+    * left. left. right. destruct s. destruct a. apply in_splitT in H. destruct H. destruct s.
+      simpl in e. apply in_splitT in H0. destruct H0. destruct s. simpl in e0. subst. apply IdBRule_I.
+    * right. intro. destruct H.
+      { destruct s.
+        - inversion i. subst. simpl in f. apply f. exists P. split ; apply in_or_app ; right ; apply in_eq.
+        - inversion i. subst. apply f0. exists A. split ; apply in_or_app ; right ; apply in_eq. }
+      { inversion b. subst. apply n. apply in_or_app. right. apply in_eq. }
+Defined.
+ +
+Definition dec_is_imp : forall (A : MPropF), (existsT2 B C, A = Imp B C) + ((existsT2 B C, A = Imp B C) -> False).
+Proof.
+destruct A as [n | | |].
+- right. intro. destruct H. destruct s. inversion e.
+- right. intro. destruct H. destruct s. inversion e.
+- left. exists A1. exists A2. reflexivity.
+- right. intro. destruct H. destruct s. inversion e.
+Defined.
+ +
+Definition dec_imp_in : forall (l : list MPropF), (existsT2 A B, In (Imp A B) l) + ((existsT2 A B, In (Imp A B) l) -> False).
+Proof.
+induction l.
+- right. intro. destruct H. destruct s. inversion i.
+- destruct IHl.
+  * repeat destruct s. left. exists x. exists x0. apply in_cons. assumption.
+  * destruct (dec_is_imp a).
+    + repeat destruct s. subst. left. exists x. exists x0. apply in_eq.
+    + right. intro. destruct H. destruct s. inversion i.
+      { subst. apply f0. exists x. exists x0. reflexivity. }
+      { apply f. exists x. exists x0. assumption. }
+Defined.
+ +
+Definition dec_ImpR_rule : forall (concl :Seq),
+          (existsT2 prem, ImpRRule [prem] concl) + ((existsT2 prem, ImpRRule [prem] concl) -> False).
+Proof.
+intros concl. destruct concl. destruct (dec_imp_in l0).
+- left. repeat destruct s. apply in_splitT in i. destruct i. destruct s. subst.
+  exists ([] ++ x :: l, x1 ++ x0 :: x2). assert ((l, x1 ++ x --> x0 :: x2) = ([] ++ l, x1 ++ x --> x0 :: x2)).
+  reflexivity. apply ImpRRule_I.
+- right. intro. destruct H. inversion i. subst. apply f. exists A. exists B. apply in_or_app.
+  right. apply in_eq.
+Defined.
+ +
+Definition dec_ImpL_rule : forall (concl :Seq),
+          (existsT2 prem1 prem2, ImpLRule [prem1 ; prem2] concl) + ((existsT2 prem1 prem2, ImpLRule [prem1 ; prem2] concl) -> False).
+Proof.
+intro concl. destruct concl. destruct (dec_imp_in l).
+- left. repeat destruct s. apply in_splitT in i. destruct i. destruct s. subst.
+  exists (x1 ++ x2, [] ++ x :: l0). exists (x1 ++ x0 :: x2, [] ++ l0).
+  assert ((x1 ++ x --> x0 :: x2, l0) = (x1 ++ x --> x0 :: x2, [] ++ l0)). reflexivity.
+  rewrite H. apply ImpLRule_I.
+- right. intro. destruct H. destruct s. inversion i. subst. apply f. exists A. exists B.
+  apply in_or_app. right. apply in_eq.
+Defined.
+ +
+Definition dec_box_in_list : forall l, (existsT2 (A : MPropF), In (Box A) l) +
+                             ((existsT2 (A : MPropF), In (Box A) l) -> False).
+Proof.
+induction l.
+- simpl. right. intro. destruct H. assumption.
+- destruct (dec_is_box a).
+  * destruct s. subst. left. exists x. apply in_eq.
+  * destruct IHl.
+    + left. destruct s. exists x. apply in_cons. assumption.
+    + right. intro. destruct H. inversion i. subst. apply f. exists x. reflexivity. apply f0.
+      exists x. assumption.
+Defined.
+ +
+Definition dec_GLR_rule : forall (concl :Seq),
+          (existsT2 prem, GLRRule [prem] concl) + ((existsT2 prem, GLRRule [prem] concl) -> False).
+Proof.
+intro concl. destruct concl. destruct (dec_box_in_list l0).
+- left. destruct s. exists ((XBoxed_list (top_boxes l)) ++ [Box x], [x]).
+  apply in_splitT in i. destruct i. destruct s. subst. apply GLRRule_I.
+  + unfold is_Boxed_list. intros. apply in_top_boxes in H. destruct H. destruct s. destruct s.
+    destruct p. exists x2. assumption.
+  + induction l. simpl. apply univ_gen_ext_nil. destruct a.
+    * simpl. apply univ_gen_ext_extra. intro. destruct X. inversion H. assumption.
+    * simpl. apply univ_gen_ext_extra. intro. destruct X. inversion H. assumption.
+    * simpl. apply univ_gen_ext_extra. intro. destruct X. inversion H. assumption.
+    * simpl. apply univ_gen_ext_cons. apply IHl.
+- right. intro. destruct X. inversion g. subst. apply f. exists A. apply in_or_app. right. apply in_eq.
+Defined.
+ +
+Definition dec_GLS_rules : forall (concl :Seq) ,
+          ((existsT2 prems, GLS_rules prems concl) -> False) + (existsT2 prems, GLS_rules prems concl).
+Proof.
+intro concl. destruct (dec_GLS_init_rules concl).
+- right. repeat destruct s.
+  * exists nil. apply IdP. assumption.
+  * exists nil. apply BotL. assumption.
+- destruct (dec_ImpR_rule concl).
+  * right. destruct s. exists [x]. apply ImpR. assumption.
+  * destruct (dec_ImpL_rule concl).
+    + right. repeat destruct s. exists [x; x0]. apply ImpL. assumption.
+    + destruct (dec_GLR_rule concl).
+      { right. repeat destruct s. exists [x]. apply GLR. assumption. }
+      { left. intro. destruct X. inversion g.
+        - inversion H. subst. apply f. auto.
+        - inversion H. subst. apply f. auto.
+        - inversion H. subst. apply f0. exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1). assumption.
+        - inversion H. subst. apply f1. exists (Γ0 ++ Γ1, Δ0 ++ A :: Δ1). exists (Γ0 ++ B :: Γ1, Δ0 ++ Δ1).
+          assumption.
+        - inversion X. subst. apply f2. exists (XBoxed_list ++ [Box A], [A]). assumption. }
+Defined.
+ +
+
+
+ +
+ + + diff --git a/GL.GLS.GLS_der_dec.html b/GL.GLS.GLS_der_dec.html new file mode 100644 index 0000000..370ed20 --- /dev/null +++ b/GL.GLS.GLS_der_dec.html @@ -0,0 +1,1296 @@ + + + + + + + + + + + + + +
+
+

GL.GLS.GLS_der_dec

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat.
+Require Import Lia.
+Require Import Coq.Arith.Compare_dec.
+ +
+Require Import GLS_calcs.
+Require Import GLS_termination_measure.
+Require Import GLS_exch.
+Require Import GLS_ctr.
+Require Import GLS_wkn.
+Require Import GLS_dec.
+Require Import GLS_inv_ImpR_ImpL.
+ +
+Set Implicit Arguments.
+ +
+Lemma forall_elem_list : forall {A : Type} (l : list A) (P : A -> Type),
+    (forall a, (InT a l) -> ((P a) + ((P a) -> False))) ->
+    (existsT2 a, (InT a l) * (P a)) + ((existsT2 a, (InT a l) * (P a)) -> False).
+Proof.
+induction l.
+- intros. right. intros. destruct X0. destruct p. inversion i.
+- intros. pose (X a). assert (InT a (a :: l)). apply InT_eq. apply s in X0. destruct X0.
+  * left. exists a. split. apply InT_eq. assumption.
+  * assert (forall a : A, InT a l -> P a + (P a -> False)).
+    { intros. apply X. apply InT_cons. assumption. }
+    pose (IHl P X0). destruct s0.
+    + left. destruct s0. exists x. split. apply InT_cons. firstorder. firstorder.
+    + right. intro. destruct X1. destruct p. inversion i. subst. firstorder. subst. firstorder.
+Qed.
+ +
+(* The list  premises of a sequent *)
+ +
+Definition proj1_sigT2 {A : Type} (P : A -> Type) (e:sigT P) := match e with
+                                    | existT _ a b => a
+                                    end.
+ +
+Definition proj2_sigT2 {A : Type} (P : A -> Type) (e : sigT P) :=
+  match e return (P (proj1_sigT2 e)) with
+  | existT _ a b => b
+  end.
+ +
+Lemma In_InT : forall (A : MPropF) l, In A l -> InT A l.
+Proof.
+intros. apply in_splitT in H. destruct H. destruct s. subst. apply InT_or_app. right.
+apply InT_eq.
+Qed.
+ +
+Definition In_InT_pair : forall (A : MPropF) (n : nat) l, In (A, n) l -> InT (A, n) l.
+Proof.
+induction l.
+- intro. inversion H.
+- intro. assert ({(A, n) = a} + {(A, n) <> a}). destruct a.
+  destruct (eq_dec_form A m). subst. destruct (Nat.eq_dec n n0). subst. auto.
+  right. intro. apply n1. inversion H0. auto. right. intro. inversion H0.
+  auto. destruct H0. subst. apply InT_eq. apply InT_cons. apply IHl.
+  inversion H. exfalso. auto. assumption.
+Defined.
+ +
+Definition InT_map_iff : forall {A B : Type} (f : A -> B) (l : list A) (y : B),
+       (InT y (map f l) -> (existsT2 x : A, (f x = y) * InT x l)) *
+       ((existsT2 x : A, (f x = y) * InT x l) -> InT y (map f l)).
+Proof.
+induction l.
+- intros. simpl. split. intro. inversion X. intro. destruct X. destruct p. inversion i.
+- simpl. intros. split.
+  * intro. inversion X.
+    + subst. exists a. split ; [ reflexivity | apply InT_eq].
+    + subst. pose (IHl y). destruct p. apply s in X0. destruct X0. destruct p. exists x.
+      split. assumption. apply InT_cons. assumption.
+  * intro. pose (IHl y). destruct p. clear s. pose (proj2_sigT2 X).
+    destruct p. inversion i0. subst. rewrite <- e. rewrite <- H0. apply InT_eq.
+    subst. assert (existsT2 x : A, (f x = y) * InT x l). exists (proj1_sigT2 X).
+    split ; assumption. apply i in X1. apply InT_cons. assumption.
+Defined.
+ +
+Fixpoint top_imps (l : list MPropF) : list MPropF :=
+match l with
+  | nil => nil
+  | h :: t => match h with
+                | Imp A B => (Imp A B) :: top_imps t
+                | _ => top_imps t
+              end
+end.
+ +
+Fixpoint pos_top_imps (l : list MPropF) : (list ((MPropF) * nat)) :=
+match l with
+  | nil => nil
+  | h :: t => match h with
+                | Imp A B => (Imp A B, 1) :: (map (fun y => (fst y, S (snd y))) (pos_top_imps t))
+                | _ => (map (fun y => (fst y, S (snd y))) (pos_top_imps t))
+              end
+end.
+ +
+Lemma le_False_lt : forall n m, ((n <= m) -> False) -> (m < n).
+Proof.
+induction n.
+- intros. exfalso. apply H. apply le_0_n.
+- induction m.
+  * intros. lia.
+  * intros. rewrite <- Nat.succ_lt_mono. apply IHn. intro. apply H. lia.
+Qed.
+ +
+Definition top_boxes_nobox_gen_ext : forall l, nobox_gen_ext (top_boxes l) l.
+Proof.
+induction l.
+- simpl. apply univ_gen_ext_nil.
+- destruct a ; simpl.
+  * apply univ_gen_ext_extra. intro. inversion X. inversion H. assumption.
+  * apply univ_gen_ext_extra. intro. inversion X. inversion H. assumption.
+  * apply univ_gen_ext_extra. intro. inversion X. inversion H. assumption.
+  * apply univ_gen_ext_cons. assumption.
+Defined.
+ +
+Lemma nobox_gen_ext_top_boxes_identity : forall l0 l1, nobox_gen_ext l0 l1 ->
+                                                       is_Boxed_list l0 ->
+                                                       (l0 = top_boxes l1).
+Proof.
+intros l0 l1 X. induction X.
+- intros. reflexivity.
+- intro. simpl. destruct x as [n | | | ].
+  * exfalso. pose (H (# n)). assert (In # n (# n :: l)). apply in_eq. apply e in H0.
+    destruct H0. inversion H0.
+  * exfalso. pose (H ()). assert (In () ( :: l)). apply in_eq. apply e in H0.
+    destruct H0. inversion H0.
+  * exfalso. pose (H (x1 --> x2)). assert (In (x1 --> x2) (x1 --> x2 :: l)). apply in_eq. apply e in H0.
+    destruct H0. inversion H0.
+  * assert (l = top_boxes le). apply IHX. intro. intros. apply H. apply in_cons. assumption.
+    rewrite H0. reflexivity.
+- simpl. destruct x.
+  * apply IHX.
+  * apply IHX.
+  * apply IHX.
+  * exfalso. apply p. exists x. reflexivity.
+Qed.
+ +
+Fixpoint flatten_list {A : Type} (l : list (list A)) : list A :=
+  match l with
+  | [ ] => [ ]
+  | h :: t => h ++ (flatten_list t)
+  end
+.
+ +
+Definition InT_flatten_list_InT_elem {A : Type} : forall (l : list (list A)) b,
+        InT b (flatten_list l) -> (existsT2 bs, (InT b bs) * (InT bs l)).
+Proof.
+induction l.
+- intros. simpl in X. inversion X.
+- intros. simpl in X. apply InT_app_or in X. destruct X.
+  * exists a. split ; [assumption | apply InT_eq].
+  * pose (IHl b). apply s in i. destruct i. destruct p. exists x. split ; [assumption | apply InT_cons ; assumption].
+Defined.
+ +
+Lemma redundant_flatten_list : forall ls (s : Seq), map (fun z : list MPropF * list MPropF => [z;s]) ls =
+flatten_list (map (fun y : list MPropF * list MPropF => [[y;s]]) ls).
+Proof.
+induction ls.
+- intros. simpl. reflexivity.
+- simpl. intros. rewrite IHls. reflexivity.
+Qed.
+ +
+Definition InT_trans_flatten_list {A : Type} : forall (l : list (list A)) bs b,
+        (InT b bs) -> (InT bs l) -> (InT b (flatten_list l)).
+Proof.
+induction l.
+- intros. inversion X0.
+- intros. inversion X0.
+  * subst. simpl. apply InT_or_app. auto.
+  * subst. simpl. apply InT_or_app. right. pose (IHl bs b X X1) ; assumption.
+Defined.
+ +
+(* In this file we prove that each sequent Γ |- Δ has a derivation (not proof) D in
+   GLS of maximal height: all derivations in GLS of this sequent must have an
+   inferior or equal height to that of D.
+
+   This result can be understood as claiming that the proof search defined by GLS
+   terminates. *)

+ +
+(* The next lemma claims that for each sequent s there is a derivation of that sequent. *)
+ +
+Lemma der_s_inhabited : forall s, inhabited (GLS_drv s).
+Proof.
+intros s.
+pose (@dpI Seq GLS_rules (fun _ : Seq => True) s).
+assert (H: (fun _ : Seq => True) s). apply I. apply d in H. apply inhabits. assumption.
+Qed.
+ +
+(* The next definition deals with the property of being a derivation D0 of maximal height
+   for the sequent s. *)

+ +
+Definition is_mhd (s: Seq) (D0 : GLS_drv s): Prop :=
+      forall (D1 : GLS_drv s), derrec_height D1 <= derrec_height D0.
+ +
+(* The next lemma says that given a list and an element, there are only finitely many
+   ways to insert this element in a list. *)

+ +
+Definition list_of_splits : forall (l : list MPropF), existsT2 listSplits,
+                            forall l1 l2, ((l1 ++ l2 = l) <-> In (l1, l2) listSplits).
+Proof.
+induction l.
+- exists [([],[])]. intros. destruct l1. split ; intro. simpl in H. rewrite H. apply in_eq.
+  simpl in H. destruct H. inversion H. reflexivity. inversion H. split ; intro.
+  simpl in H. inversion H. simpl. inversion H. inversion H0. inversion H0.
+- destruct IHl. exists ([([], a :: l)] ++ (map (fun y => (a :: (fst y), snd y)) x)).
+  intros. split ; intro.
+  * apply in_or_app. destruct l1. simpl. left. left. simpl in H. rewrite H.
+    reflexivity. simpl in H. inversion H. subst. right. pose (i l1 l2). destruct i0.
+    assert (l1 ++ l2 = l1 ++ l2). reflexivity. apply H0 in H2.
+    pose (in_map (fun y : list MPropF * list MPropF => (a :: fst y, snd y)) x (l1, l2) H2).
+    simpl in i. assumption.
+  * simpl in H. destruct H. inversion H. simpl. reflexivity. rewrite in_map_iff in H.
+    destruct H. destruct H. inversion H. subst. simpl. pose (i (fst x0) (snd x0)).
+    destruct i0. assert ((fst x0, snd x0) = x0). destruct x0. simpl. reflexivity.
+    rewrite H3 in H2. apply H2 in H0. rewrite H0. reflexivity.
+Defined.
+ +
+Definition listInserts l (A : MPropF) := map (fun y => (fst y) ++ A :: (snd y)) (proj1_sigT2 (list_of_splits l)).
+ +
+(* The next two lemmas make sure that the definition listInserts indeed captures the intended
+   list. *)

+ +
+Lemma listInserts_In : forall l (A: MPropF) l1 l2, ((l1 ++ l2 = l) -> In (l1 ++ A :: l2) (listInserts l A)).
+Proof.
+intros. unfold listInserts. assert (In (l1, l2) (proj1_sigT2 (list_of_splits l))). destruct (list_of_splits l).
+simpl. pose (i l1 l2). apply i0. assumption.
+pose (in_map (fun y : list MPropF * list MPropF => fst y ++ A :: snd y) (proj1_sigT2 (list_of_splits l)) (l1, l2) H0).
+simpl in i. assumption.
+Qed.
+ +
+Lemma In_listInserts : forall l (A: MPropF) l0, In l0 (listInserts l A) ->
+                            (exists l1 l2, prod (l1 ++ l2 = l) (l1 ++ A :: l2 = l0)).
+Proof.
+intros. unfold listInserts in H. destruct (list_of_splits l). simpl in H. rewrite in_map_iff in H.
+destruct H. destruct H. subst. exists (fst x0). exists (snd x0). split. apply i.
+destruct x0. simpl. assumption. reflexivity.
+Qed.
+ +
+(* The definitions below allow you to create the list of all sequents given two lists and a
+   formula to insert in one of them. *)

+ +
+Definition listInsertsR_Seqs (Γ Δ : list MPropF) (A : MPropF) := map (fun y => (y, Δ)) (listInserts Γ A).
+ +
+Definition listInsertsL_Seqs (Γ Δ : list MPropF) (A : MPropF) := map (fun y => (Γ, y)) (listInserts Δ A).
+ +
+(* The next definition allows one to create all sequents *)
+ +
+Definition listInsertsRL_Seqs (Γ Δ : list MPropF) (A B : MPropF) :=
+                  flatten_list (map (fun z => (map (fun y => (z, y)) (listInserts Δ B))) (listInserts Γ A)).
+ +
+(* Now we can prove that a sequent has only finitely many potential premises via the ImpR rules.
+
+   The next definition simply takes a list of formulae l and a sequent s. It outputs a list of sequents.
+   These sequents are generated when there is an implication (Imp A B) encountered in l. With such an
+   implication, the function will stack the list of all insertions of A on the left of s and of B on
+   the right of s (roughly: in fact you need to destroy all such implications on the right to get an ImpRRule
+   premise), and then continues computing on the rest of l. *)

+ +
+Fixpoint remove_nth (n: nat) (A : MPropF) l:=
+    match n with
+      | 0 => l
+      | 1 => match l with
+               | [] => []
+               | B::tl => if (eq_dec_form A B) then tl else B:: tl
+             end
+      | S m => match l with
+                 | [] => []
+                 | B::tl => B::(remove_nth m A tl)
+               end
+      end.
+ +
+Fixpoint nth_split (n : nat) (l : list MPropF) : (list MPropF * list MPropF) :=
+    match n with
+      | 0 => ([], l)
+      | 1 => match l with
+               | [] => ([], [])
+               | B::tl => ([B] , tl)
+             end
+      | S m => match l with
+                 | [] => ([], [])
+                 | B::tl => (B :: (fst (nth_split m tl)), snd (nth_split m tl))
+               end
+      end.
+ +
+Fixpoint prems_Imp_R (l : list ((MPropF) * nat)) (s : Seq) : list Seq :=
+match l with
+  | nil => nil
+  | (C, n) :: t => match n with
+                    | 0 => prems_Imp_R t s
+                    | S m => match C with
+                                | Imp A B => (listInsertsR_Seqs (fst s)
+                                               ((fst (nth_split m (remove_nth (S m) C (snd s)))) ++
+                                               B :: (snd (nth_split m (remove_nth (S m) C (snd s)))))
+                                               A)
+                                             ++ (prems_Imp_R t s)
+                                | _ => prems_Imp_R t s
+                                end
+                   end
+end.
+ +
+Lemma nth_split_length : forall (l0 l1 : list MPropF), (nth_split (length l0) (l0 ++ l1)) = (l0, l1).
+Proof.
+induction l0.
+- intros. simpl. reflexivity.
+- intros. pose (IHl0 l1). simpl (length (a :: l0)). simpl ((a :: l0) ++ l1).
+  simpl. destruct l0.
+  * simpl. reflexivity.
+  * assert (match length (m :: l0) with
+| 0 => ([a], (m :: l0) ++ l1)
+| S _ =>
+    (a :: fst (nth_split (length (m :: l0)) ((m :: l0) ++ l1)),
+    snd (nth_split (length (m :: l0)) ((m :: l0) ++ l1)))
+end = (a :: fst (nth_split (length (m :: l0)) ((m :: l0) ++ l1)),
+    snd (nth_split (length (m :: l0)) ((m :: l0) ++ l1)))). reflexivity. rewrite H.
+clear H. rewrite e. simpl. reflexivity.
+Qed.
+ +
+Lemma nth_split_idL : forall (l0 l1 : list MPropF), l0 = fst (nth_split (length l0) (l0 ++ l1)).
+Proof.
+induction l0.
+- intros. simpl. reflexivity.
+- intros. simpl (length (a :: l0)). pose (IHl0 l1). assert (fst (nth_split (S (length l0)) ((a :: l0) ++ l1)) =
+  a :: fst (nth_split (length l0) (l0 ++ l1))). simpl. destruct l0. simpl. reflexivity.
+  simpl. reflexivity. rewrite H. rewrite <- e. reflexivity.
+Qed.
+ +
+Lemma nth_split_idR : forall (l0 l1 : list MPropF), l1 = snd (nth_split (length l0) (l0 ++ l1)).
+Proof.
+induction l0.
+- intros. simpl. reflexivity.
+- intros. simpl (length (a :: l0)). pose (IHl0 l1). rewrite e. destruct l0.
+  * simpl. reflexivity.
+  * simpl (length (m :: l0)). simpl (S (S (length l0))).
+    simpl (length (m :: l0)) in e. rewrite <- e.
+    assert ((S (S (length l0))) = (length (a :: m :: l0))). simpl. reflexivity.
+    rewrite H. rewrite nth_split_length. simpl. reflexivity.
+Qed.
+ +
+Lemma nth_split_length_id : forall (l0 l1 : list MPropF) n, (length l0 = n) ->
+                                (fst (nth_split n (l0 ++ l1)) = l0 /\
+                                snd (nth_split n (l0 ++ l1)) = l1).
+Proof.
+induction l0.
+- intros. simpl. split. simpl in H. subst. simpl. reflexivity. simpl in H. subst. simpl. reflexivity.
+- intros. simpl in H. subst. split.
+  * assert (J1:length l0 = length l0). reflexivity. pose (@IHl0 l1 (length l0) J1).
+    destruct a0. simpl. destruct l0. simpl. reflexivity. simpl. rewrite <- H.
+    simpl. reflexivity.
+  * assert (J1:length l0 = length l0). reflexivity. pose (@IHl0 l1 (length l0) J1).
+    destruct a0. rewrite <- H0. simpl ((a :: l0) ++ snd (nth_split (length l0) (l0 ++ l1))).
+    assert ((nth_split (S (length l0)) (a :: l0 ++ snd (nth_split (length l0) (l0 ++ l1))) =
+    (a :: l0 ,snd (nth_split (length l0) (l0 ++ l1))))).
+    pose (nth_split_length (a :: l0) (snd (nth_split (length l0) (l0 ++ l1)))). apply e.
+    rewrite H1. simpl. reflexivity.
+Qed.
+ +
+Lemma In_pos_top_imps_0_False : forall l (A : MPropF), In (A, 0) (pos_top_imps l) -> False.
+Proof.
+- induction l.
+  * intros. inversion H.
+  * intros. simpl in H. destruct a.
+    + simpl in H. apply In_InT_pair in H. apply InT_map_iff in H. destruct H.
+      destruct p. destruct x. inversion e.
+    + simpl in H. apply In_InT_pair in H. apply InT_map_iff in H. destruct H.
+      destruct p. destruct x. inversion e.
+    + simpl in H. destruct H. inversion H. apply In_InT_pair in H. apply InT_map_iff in H. destruct H.
+      destruct p. destruct x. inversion e.
+    + simpl in H. apply In_InT_pair in H. apply InT_map_iff in H. destruct H.
+      destruct p. destruct x. inversion e.
+Qed.
+ +
+Lemma In_pos_top_imps_imp : forall l (A : MPropF) n, In (A, n) (pos_top_imps l) -> (existsT2 C D, A = Imp C D).
+Proof.
+induction l ; intros.
+- simpl in H. inversion H.
+- simpl in H. destruct a ; try apply IHl in H. apply In_InT_pair in H. apply InT_map_iff in H. destruct H.
+  destruct p. inversion e. destruct x. subst. apply InT_In in i. apply IHl in i. assumption.
+  apply In_InT_pair in H. apply InT_map_iff in H. destruct H.
+  destruct p. inversion e. destruct x. subst. apply InT_In in i. apply IHl in i. assumption.
+  apply In_InT_pair in H. inversion H. subst. inversion H1. exists a1. exists a2. reflexivity.
+  subst. apply InT_map_iff in H1. destruct H1. destruct p. destruct x. simpl in e. inversion e.
+  subst. apply InT_In in i. apply IHl in i. assumption.
+  apply In_InT_pair in H. apply InT_map_iff in H. destruct H.
+  destruct p. inversion e. destruct x. subst. apply InT_In in i. apply IHl in i. assumption.
+Qed.
+ +
+Lemma In_pos_top_imps_In_l : forall l (A : MPropF) n, In (A, n) (pos_top_imps l) -> In A l.
+Proof.
+induction l.
+- intros. simpl in H. destruct H.
+- intros. simpl in H. destruct a.
+  * apply in_cons. apply In_InT_pair in H. apply InT_map_iff in H. destruct H.
+    destruct p. destruct x. inversion e. subst. apply InT_In in i. apply IHl in i.
+    assumption.
+  * apply in_cons. apply In_InT_pair in H. apply InT_map_iff in H. destruct H.
+    destruct p. destruct x. inversion e. subst. apply InT_In in i. apply IHl in i.
+    assumption.
+  * inversion H.
+    + inversion H0. subst. apply in_eq.
+    + apply in_cons. apply In_InT_pair in H0. apply InT_map_iff in H0. destruct H0.
+      destruct p. destruct x. inversion e. subst. apply InT_In in i. apply IHl in i.
+      assumption.
+  * apply In_InT_pair in H. apply InT_map_iff in H. destruct H.
+    destruct p. destruct x. inversion e. subst. apply InT_In in i. apply IHl in i.
+    apply in_cons. assumption.
+Qed.
+ +
+Lemma effective_remove_nth : forall A l0 l1, ((remove_nth (S (length l0)) A (l0 ++ A :: l1)) = l0 ++ l1).
+Proof.
+induction l0.
+- intros. simpl. destruct (eq_dec_form A A). reflexivity. exfalso. auto.
+- intros. simpl (S (length (a :: l0))). repeat rewrite <- app_assoc. simpl ((a :: l0) ++ A :: l1).
+  pose (IHl0 l1). simpl ((a :: l0) ++ l1). rewrite <- e. simpl. reflexivity.
+Qed.
+ +
+Definition In_pos_top_imps_split_l : forall l (A : MPropF) n, In (A, S n) (pos_top_imps l) ->
+          existsT2 l0 l1, (l = l0 ++ A :: l1) /\
+                          (length l0 = n) /\
+                          (l0 = fst (nth_split n (remove_nth (S n) A l))) /\
+                          (l1 = snd (nth_split n (remove_nth (S n) A l))).
+Proof.
+induction l.
+- intros. simpl. exfalso. simpl in H. destruct H.
+- intros. simpl in H. destruct a as [n0 | | | ].
+  * apply In_InT_pair in H. apply InT_map_iff in H. destruct H as ([m n1] & e & i).
+    simpl in e. inversion e. subst. destruct n. exfalso.
+    apply InT_In in i. apply In_pos_top_imps_0_False in i. assumption.
+    apply InT_In in i. pose (IHl A n i). destruct s as (x & x0 & e2 & e3 & e1 & e0).
+    subst. exists (# n0 :: x). exists x0. repeat split.
+    rewrite effective_remove_nth in e1. rewrite effective_remove_nth in e0.
+    assert (fst (# n0 :: fst (nth_split (S (length x)) (x ++ x0)), snd (nth_split (S (length x)) (x ++ x0))) =
+    # n0 :: fst (nth_split (S (length x)) (x ++ x0))). simpl. reflexivity.
+    assert (S (S (length x)) = S (length (# n0 :: x))). simpl. reflexivity.
+    rewrite H0. assert ((# n0 :: x ++ A :: x0) = ((# n0 :: x) ++ A :: x0)). simpl. reflexivity.
+    rewrite H1. clear H0. clear H1. rewrite effective_remove_nth.
+    pose (nth_split_idL (# n0 :: x) x0). simpl (length (# n0 :: x)) in e2.
+    rewrite <- e2. reflexivity.
+    rewrite effective_remove_nth in e0. rewrite effective_remove_nth in e1.
+    assert (S (S (length x)) = S (length (# n0 :: x))). simpl. reflexivity.
+    rewrite H. assert ((# n0 :: x ++ A :: x0) = ((# n0 :: x) ++ A :: x0)). simpl. reflexivity.
+    rewrite H0. clear H. clear H0. rewrite effective_remove_nth.
+    pose (nth_split_idR (# n0 :: x) x0). simpl (length (# n0 :: x)) in e2.
+    rewrite <- e2. reflexivity.
+  * apply In_InT_pair in H. apply InT_map_iff in H. destruct H as ([m n1] & e & i).
+    simpl in e. inversion e. subst. destruct n.
+    -- exfalso. apply InT_In in i. apply In_pos_top_imps_0_False in i. assumption.
+      -- apply InT_In in i. pose (IHl A n i). destruct s as (x & x0 & e2 & e3 & e1 & e0).
+      subst. exists (Bot :: x). exists x0. repeat split.
+      rewrite effective_remove_nth in e1. rewrite effective_remove_nth in e0.
+      assert (fst (Bot :: fst (nth_split (S (length x)) (x ++ x0)), snd (nth_split (S (length x)) (x ++ x0))) =
+      Bot :: fst (nth_split (S (length x)) (x ++ x0))). simpl. reflexivity.
+    assert (S (S (length x)) = S (length (Bot :: x))). simpl. reflexivity.
+    rewrite H0. assert ((Bot :: x ++ A :: x0) = ((Bot :: x) ++ A :: x0)). simpl. reflexivity.
+    rewrite H1. clear H0. clear H1. rewrite effective_remove_nth.
+    pose (nth_split_idL (Bot :: x) x0). simpl (length (Bot :: x)) in e2.
+    rewrite <- e2. reflexivity.
+    rewrite effective_remove_nth in e0. rewrite effective_remove_nth in e1.
+    assert (S (S (length x)) = S (length (Bot :: x))). simpl. reflexivity.
+    rewrite H. assert ((Bot :: x ++ A :: x0) = ((Bot :: x) ++ A :: x0)). simpl. reflexivity.
+    rewrite H0. clear H. clear H0. rewrite effective_remove_nth.
+    pose (nth_split_idR (Bot :: x) x0). simpl (length (Bot :: x)) in e2.
+    rewrite <- e2. reflexivity.
+  * apply In_InT_pair in H. inversion H.
+    + inversion H1. subst. exists []. exists l. repeat split. simpl.
+      destruct (eq_dec_form (a1 --> a2) (a1 --> a2)). reflexivity. exfalso. auto.
+    + subst. apply InT_map_iff in H1. destruct H1 as ([m n1] & e & i).
+        simpl in e. inversion e. subst. destruct n. exfalso.
+        apply InT_In in i. apply In_pos_top_imps_0_False in i. assumption.
+        apply InT_In in i. pose (IHl A n i). destruct s as (x & x0 & e2 & e3 & e1 & e0).
+        subst. exists (a1 --> a2 :: x). exists x0. repeat split.
+        rewrite effective_remove_nth in e1. rewrite effective_remove_nth in e0.
+        assert (fst (a1 --> a2 :: fst (nth_split (S (length x)) (x ++ x0)), snd (nth_split (S (length x)) (x ++ x0))) =
+        a1 --> a2 :: fst (nth_split (S (length x)) (x ++ x0))). simpl. reflexivity.
+        assert (S (S (length x)) = S (length (a1 --> a2 :: x))). simpl. reflexivity.
+        rewrite H1. assert ((a1 --> a2 :: x ++ A :: x0) = ((a1 --> a2 :: x) ++ A :: x0)). simpl. reflexivity.
+        rewrite H2. clear H2. clear H1. rewrite effective_remove_nth.
+        pose (nth_split_idL (a1 --> a2 :: x) x0). simpl (length (a1 --> a2 :: x)) in e2.
+        rewrite <- e2. reflexivity.
+        rewrite effective_remove_nth in e0. rewrite effective_remove_nth in e1.
+        assert (S (S (length x)) = S (length (a1 --> a2 :: x))). simpl. reflexivity.
+        rewrite H0. assert ((a1 --> a2 :: x ++ A :: x0) = ((a1 --> a2 :: x) ++ A :: x0)). simpl. reflexivity.
+        rewrite H1. clear H0. clear H1. rewrite effective_remove_nth.
+        pose (nth_split_idR (a1 --> a2 :: x) x0). simpl (length (a1 --> a2 :: x)) in e2.
+        rewrite <- e2. reflexivity.
+        * apply In_InT_pair in H. apply InT_map_iff in H. destruct H as ([m n1] & e & i).
+         simpl in e. inversion e. subst. destruct n. exfalso.
+        apply InT_In in i. apply In_pos_top_imps_0_False in i. assumption.
+        apply InT_In in i. pose (IHl A n i). destruct s as (x & x0 & e2 & e3 & e1 & e0).
+        subst. exists (Box a :: x). exists x0. repeat split.
+        rewrite effective_remove_nth in e1. rewrite effective_remove_nth in e0.
+        assert (fst (Box a :: fst (nth_split (S (length x)) (x ++ x0)), snd (nth_split (S (length x)) (x ++ x0))) =
+        Box a :: fst (nth_split (S (length x)) (x ++ x0))). simpl. reflexivity.
+        assert (S (S (length x)) = S (length (Box a :: x))). simpl. reflexivity.
+        rewrite H0. assert ((Box a :: x ++ A :: x0) = ((Box a :: x) ++ A :: x0)). simpl. reflexivity.
+        rewrite H1. clear H0. clear H1. rewrite effective_remove_nth.
+        pose (nth_split_idL (Box a :: x) x0). simpl (length (Box a :: x)) in e2.
+        rewrite <- e2. reflexivity.
+        rewrite effective_remove_nth in e0. rewrite effective_remove_nth in e1.
+        assert (S (S (length x)) = S (length (Box a :: x))). simpl. reflexivity.
+        rewrite H. assert ((Box a :: x ++ A :: x0) = ((Box a :: x) ++ A :: x0)). simpl. reflexivity.
+        rewrite H0. clear H. clear H0. rewrite effective_remove_nth.
+        pose (nth_split_idR (Box a :: x) x0). simpl (length (Box a :: x)) in e2.
+        rewrite <- e2. reflexivity.
+Defined.
+ +
+Lemma In_l_imp_In_pos_top_imps : forall l (A B : MPropF), In (Imp A B) l ->
+                                    existsT2 n, In ((Imp A B), n) (pos_top_imps l).
+Proof.
+induction l.
+- intros. simpl in H. destruct H.
+- intros. apply In_InT in H. inversion H.
+  * subst. exists 1. simpl. left. reflexivity.
+  * destruct a.
+    + subst. apply InT_In in H1. apply IHl in H1. destruct H1. exists (S x). simpl.
+      apply InT_In. apply InT_map_iff. exists (A --> B, x). simpl. split ; auto.
+      apply In_InT_pair. assumption.
+    + subst. apply InT_In in H1. apply IHl in H1. destruct H1. exists (S x). simpl.
+      apply InT_In. apply InT_map_iff. exists (A --> B, x). simpl. split ; auto.
+      apply In_InT_pair. assumption.
+    + subst. apply InT_In in H1. apply IHl in H1. destruct H1. exists (S x). simpl.
+      right. apply InT_In. apply InT_map_iff. exists (A --> B, x). simpl. split ; auto.
+      apply In_InT_pair. assumption.
+    + subst. apply InT_In in H1. apply IHl in H1. destruct H1. exists (S x). simpl.
+      apply InT_In. apply InT_map_iff. exists (A --> B, x). simpl. split ; auto.
+      apply In_InT_pair. assumption.
+Qed.
+ +
+Lemma Good_pos_in_pos_top_imps : forall A B Δ0 Δ1,
+              In (A --> B, S (length Δ0)) (pos_top_imps (Δ0 ++ A --> B :: Δ1)).
+Proof.
+induction Δ0.
+- intros. simpl. auto.
+- intros. destruct a.
+  * simpl. apply InT_In. apply InT_map_iff. exists (A --> B, S (length Δ0)).
+    split. simpl. reflexivity. apply In_InT_pair. apply IHΔ0.
+  * simpl. apply InT_In. apply InT_map_iff. exists (A --> B, S (length Δ0)).
+    split. simpl. reflexivity. apply In_InT_pair. apply IHΔ0.
+  * simpl. right. apply InT_In. apply InT_map_iff. exists (A --> B, S (length Δ0)).
+    split. simpl. reflexivity. apply In_InT_pair. apply IHΔ0.
+  * simpl. apply InT_In. apply InT_map_iff. exists (A --> B, S (length Δ0)).
+    split. simpl. reflexivity. apply In_InT_pair. apply IHΔ0.
+Qed.
+ +
+(* From there we can show that given a specific (Imp A B) on the right of a sequent S,
+   there is only finitely many premises via ImpR applied on this implication. But we
+   need to do it for all implications on the right of this sequent. *)

+ +
+Definition ImpR_help01 : forall prem s l, InT prem (prems_Imp_R l s) ->
+                  (existsT2 n A B Γ0 Γ1 Δ0 Δ1,
+                        (In ((Imp A B), S n) l) /\
+                        (prem = (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)) /\
+                        (Γ0 ++ Γ1 = fst s) /\
+                        (Δ0 = (fst (nth_split n (remove_nth (S n) (Imp A B) (snd s))))) /\
+                        (Δ1 = (snd (nth_split n (remove_nth (S n) (Imp A B) (snd s)))))).
+Proof.
+intros prem s. destruct s. destruct prem. induction l3 ; intros X.
+- simpl in X. inversion X.
+- destruct a as [m n]. destruct m as [m | | | ].
+  * simpl in X. destruct n.
+    + pose (IHl3 X). destruct s as (x & x0 & x1 & x2 & x3 & x4 & x5 & p).
+        decompose record p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. repeat split ; try auto. apply in_cons. tauto.
+    + pose (IHl3 X). destruct s as (x & x0 & x1 & x2 & x3 & x4 & x5 & p). decompose record p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. repeat split ; try tauto. apply in_cons. tauto.
+  * simpl in X. destruct n.
+    + pose (IHl3 X). destruct s as (x & x0 & x1 & x2 & x3 & x4 & x5 & p). decompose record p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. repeat split ; try tauto. apply in_cons. tauto.
+    + pose (IHl3 X). destruct s as (x & x0 & x1 & x2 & x3 & x4 & x5 & p). decompose record p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. repeat split ; try tauto. apply in_cons. tauto.
+  * destruct n.
+    + pose (IHl3 X). destruct s as (x & x0 & x1 & x2 & x3 & x4 & x5 & p). decompose record p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. repeat split ; try tauto. apply in_cons. tauto.
+    + apply InT_app_or in X. destruct X.
+      { simpl (fst (l, l0)) in i. simpl (snd (l, l0)) in i.
+        unfold listInsertsR_Seqs in i. apply InT_map_iff in i. destruct i.
+        destruct p. subst. unfold listInserts in i. apply InT_map_iff in i. destruct i.
+        destruct p. destruct x0. subst. destruct (list_of_splits l). simpl in i. exists n.
+        exists m1. exists m2. exists l4. exists l5. simpl (snd (l, l0)).
+        simpl (fst (l, l0)).
+        exists (fst (nth_split n (remove_nth (S n) (m1 --> m2) l0))).
+        exists (snd (nth_split n (remove_nth (S n) (m1 --> m2) l0))).
+        repeat split ; try auto. apply in_eq. rewrite i0. apply InT_In. assumption. }
+      { pose (IHl3 i). destruct s as (x & x0 & x1 & x2 & x3 & x4 & x5 & p). decompose record p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. repeat split ; try tauto. apply in_cons. tauto. }
+  * simpl in X. destruct n.
+    + pose (IHl3 X). destruct s as (x & x0 & x1 & x2 & x3 & x4 & x5 & p). decompose record p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. repeat split ; try tauto. apply in_cons. tauto.
+    + pose (IHl3 X). destruct s as (x & x0 & x1 & x2 & x3 & x4 & x5 & p). decompose record p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. repeat split ; try tauto. apply in_cons. tauto.
+Defined.
+ +
+Definition ImpR_help1 : forall prem s, InT prem (prems_Imp_R (pos_top_imps (snd s)) s) -> ImpRRule [prem] s.
+Proof.
+intros prem s X. pose (ImpR_help01 _ _ X). destruct s0. destruct s.
+destruct s0. destruct s as (B & Γ0 & Γ1 & Δ0 & Δ1 & i & e2 & e3 & e4 & e5).
+subst. simpl in i, e3. subst.
+simpl (snd (_, _)) in *.
+apply In_pos_top_imps_split_l in i. destruct i. destruct s as (x2 & H1 & H2 & H3 & H4).
+subst.
+rewrite <- H4. rewrite effective_remove_nth. rewrite <- nth_split_idL.
+apply ImpRRule_I.
+Defined.
+ +
+Definition ImpR_help002 : forall Γ0 Γ1 Δ0 Δ1 A B,
+           InT (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) (listInsertsR_Seqs (Γ0 ++ Γ1) (Δ0 ++ B :: Δ1) A).
+Proof.
+intros. unfold listInsertsR_Seqs. apply InT_map_iff. exists (Γ0 ++ A :: Γ1). split.
+reflexivity. unfold listInserts. apply InT_map_iff. exists (Γ0, Γ1). simpl. split.
+reflexivity. destruct (list_of_splits (Γ0 ++ Γ1)). simpl. pose (i Γ0 Γ1).
+apply In_InT_seqs. apply i0. reflexivity.
+Defined.
+ +
+Definition ImpR_help02 : forall Γ0 Γ1 Δ0 Δ1 A B l n,
+                                ImpRRule [(Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)] (Γ0 ++ Γ1, Δ0 ++ (Imp A B) :: Δ1) ->
+                                (length Δ0 = n) ->
+                                (In ((Imp A B), S n) l) ->
+                                InT (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) (prems_Imp_R l (Γ0 ++ Γ1, Δ0 ++ (Imp A B) :: Δ1)).
+Proof.
+induction l ; intros.
+- inversion H1.
+- destruct a. destruct m.
+  * apply In_InT_pair in H1. inversion H1. subst. inversion H3. subst. apply InT_In in H3.
+    assert (J1: length Δ0 = length Δ0). reflexivity.
+    pose (IHl _ H J1 H3). simpl. destruct n0. assumption. assumption.
+  * apply In_InT_pair in H1. inversion H1. subst. inversion H3. subst. apply InT_In in H3.
+    assert (J1: length Δ0 = length Δ0). reflexivity.
+    pose (IHl _ H J1 H3). simpl. destruct n0. assumption. assumption.
+  * apply In_InT_pair in H1. inversion H1.
+    + subst. inversion H3. subst. destruct Δ0.
+      { simpl. pose (ImpR_help002 Γ0 Γ1 [] Δ1 A B). simpl in i. destruct (eq_dec_form (A --> B) (A --> B)).
+        apply InT_or_app. auto. exfalso. auto. }
+      { unfold prems_Imp_R. apply InT_or_app. left.
+        assert ((remove_nth (S (length (m :: Δ0))) (A --> B) (snd (Γ0 ++ Γ1, (m :: Δ0) ++ A --> B :: Δ1))) =
+        (m :: Δ0) ++ Δ1). simpl (snd (Γ0 ++ Γ1, (m :: Δ0) ++ A --> B :: Δ1)).
+        pose (effective_remove_nth (A --> B) (m :: Δ0) Δ1). assumption.
+        rewrite H0.
+        assert (fst (nth_split (length (m :: Δ0)) ((m :: Δ0) ++ Δ1)) = (m :: Δ0) /\
+        snd (nth_split (length (m :: Δ0)) ((m :: Δ0) ++ Δ1)) = Δ1). apply nth_split_length_id.
+        reflexivity. destruct H2. rewrite H2. rewrite H4. apply ImpR_help002. }
+    + subst. assert (J1: (length Δ0) = (length Δ0)). reflexivity. apply InT_In in H3.
+      pose (IHl (length Δ0) H J1 H3). simpl. destruct n0. assumption. apply InT_or_app. auto.
+  * apply In_InT_pair in H1. inversion H1. subst. inversion H3. subst. apply InT_In in H3.
+    assert (J1: length Δ0 = length Δ0). reflexivity.
+    pose (IHl _ H J1 H3). simpl. destruct n0. assumption. assumption.
+Defined.
+ +
+Definition ImpR_help2 : forall prem s, ImpRRule [prem] s -> InT prem (prems_Imp_R (pos_top_imps (snd s)) s).
+Proof.
+intros. inversion H. subst. simpl.
+pose (@ImpR_help02 Γ0 Γ1 Δ0 Δ1 A B (pos_top_imps (Δ0 ++ A --> B :: Δ1)) (length Δ0)). apply i ; try assumption.
+reflexivity. apply Good_pos_in_pos_top_imps.
+Defined.
+ +
+Definition finite_ImpR_premises_of_S : forall (s : Seq), existsT2 listImpRprems,
+              (forall prems, ((ImpRRule prems s) -> (InT prems listImpRprems)) *
+                             ((InT prems listImpRprems) -> (ImpRRule prems s))).
+Proof.
+intro s. destruct s.
+exists (map (fun y => [y]) (prems_Imp_R (pos_top_imps l0) (l,l0))).
+intros. split ; intro.
+- inversion H. subst. apply InT_map_iff.
+  exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1). split. reflexivity.
+  pose (@ImpR_help2 (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1)). simpl in i. apply i.
+  assumption.
+- apply InT_map_iff in H. destruct H. destruct p. subst. apply ImpR_help1. simpl. assumption.
+Defined.
+ +
+(* Then, we turn to the case of the ImpL rule. *)
+ +
+Fixpoint prems_Imp_L (l : list ((MPropF) * nat)) (s : Seq) : list (list Seq) :=
+match l with
+  | nil => nil
+  | (C, n) :: t => match n with
+      | 0 => prems_Imp_L t s
+      | S m => match C with
+           | Imp A B => flatten_list
+                        (map (fun y => map (fun z => [z; y])
+                        (listInsertsL_Seqs ((fst (nth_split m (remove_nth (S m) C (fst s)))) ++
+                        (snd (nth_split m (remove_nth (S m) C (fst s))))) (snd s) A))
+                        [(((fst (nth_split m (remove_nth (S m) C (fst s)))) ++
+                        B :: (snd (nth_split m (remove_nth (S m) C (fst s))))), (snd s))])
+                        ++ (prems_Imp_L t s)
+           | _ => prems_Imp_L t s
+           end
+      end
+end.
+ +
+Definition ImpL_help002 : forall Γ0 Γ1 Δ0 Δ1 A B,
+           InT [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]
+               (flatten_list (map (fun y : list MPropF * list MPropF => map
+               (fun z : list MPropF * list MPropF => [y; z]) [(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)])
+               (listInsertsL_Seqs (Γ0 ++ Γ1) (Δ0 ++ Δ1) A)))
+              .
+Proof.
+intros.
+pose (@InT_trans_flatten_list _ (map (fun y : list MPropF * list MPropF => map
+(fun z : list MPropF * list MPropF => [y; z]) [(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)])
+(listInsertsL_Seqs (Γ0 ++ Γ1) (Δ0 ++ Δ1) A))
+(map (fun z : list MPropF * list MPropF => [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); z])
+[(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]) [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]).
+apply i ; clear i.
+- pose (InT_map_iff (fun z : list MPropF * list MPropF => [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); z]) [(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]
+  [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]).
+  destruct p. clear s. apply i. exists (Γ0 ++ B :: Γ1, Δ0 ++ Δ1). split. reflexivity. apply InT_eq.
+- pose (InT_map_iff (fun y : list MPropF * list MPropF =>
+  map (fun z : list MPropF * list MPropF => [y; z]) [(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)])
+  (listInsertsL_Seqs (Γ0 ++ Γ1) (Δ0 ++ Δ1) A) (map (fun z : list MPropF * list MPropF => [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); z])
+  [(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)])).
+  destruct p. apply i. clear i. clear s. exists (Γ0 ++ Γ1, Δ0 ++ A :: Δ1). split. reflexivity.
+  unfold listInsertsL_Seqs.
+  pose (InT_map_iff (fun y : list MPropF => (Γ0 ++ Γ1, y)) (listInserts (Δ0 ++ Δ1) A) (Γ0 ++ Γ1, Δ0 ++ A :: Δ1)).
+  destruct p. apply i. clear s. clear i. exists (Δ0 ++ A :: Δ1). split. reflexivity.
+  unfold listInserts.
+  pose (InT_map_iff (fun y : list MPropF * list MPropF => fst y ++ A :: snd y)
+  (proj1_sigT2 (list_of_splits (Δ0 ++ Δ1))) (Δ0 ++ A :: Δ1)). destruct p. clear s.
+  apply i. clear i. exists (Δ0,Δ1). simpl. split. reflexivity. destruct (list_of_splits (Δ0 ++ Δ1)).
+  simpl. pose (i Δ0 Δ1). apply In_InT_seqs. rewrite <- i0. reflexivity.
+Defined.
+ +
+Definition ImpL_help02 : forall Γ0 Γ1 Δ0 Δ1 A B l n,
+            ImpLRule [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)] (Γ0 ++ (Imp A B) :: Γ1, Δ0 ++ Δ1) ->
+            (length Γ0 = n) ->
+            (In ((Imp A B), S n) l) ->
+            InT [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)] (prems_Imp_L l (Γ0 ++ (Imp A B) :: Γ1, Δ0 ++ Δ1)).
+Proof.
+induction l ; intros.
+- inversion H1.
+- destruct a. destruct m.
+  * subst. apply In_InT_pair in H1. inversion H1. subst. inversion H2. subst. apply InT_In in H2.
+    assert (J1: length Γ0 = length Γ0). reflexivity.
+    pose (IHl _ H J1 H2). simpl. destruct n0. assumption. assumption.
+  * subst. apply In_InT_pair in H1. inversion H1. subst. inversion H2. subst. apply InT_In in H2.
+    assert (J1: length Γ0 = length Γ0). reflexivity.
+    pose (IHl _ H J1 H2). simpl. destruct n0. assumption. assumption.
+  * apply In_InT_pair in H1. inversion H1.
+    + subst. inversion H3. subst.
+      pose (ImpL_help002 Γ0 Γ1 Δ0 Δ1 A B). simpl in i.
+      apply InT_or_app. left.
+      apply InT_trans_flatten_list with (bs:=(flatten_list
+      (map (fun y : list MPropF * list MPropF => [[y; (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]])
+         (listInsertsL_Seqs (Γ0 ++ Γ1) (Δ0 ++ Δ1) A)))). assumption. apply InT_map_iff.
+      exists (Γ0 ++ B :: Γ1, Δ0 ++ Δ1). split.
+      destruct (eq_dec_form (A --> B) (A --> B)).
+      apply InT_flatten_list_InT_elem in i. destruct i. destruct p.
+      assert ((listInsertsL_Seqs (fst
+      (nth_split (length Γ0) (remove_nth (S (length Γ0)) (A --> B) (fst (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)))) ++
+      snd
+      (nth_split (length Γ0) (remove_nth (S (length Γ0)) (A --> B) (fst (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)))))
+      (snd (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)) A) = (listInsertsL_Seqs (Γ0 ++ Γ1) (Δ0 ++ Δ1) A)).
+      simpl (snd (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+      simpl (fst (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)). repeat rewrite effective_remove_nth.
+      assert (length Γ0 = length Γ0). reflexivity.
+      pose (@nth_split_length_id Γ0 Γ1 (length Γ0) H0). destruct a. rewrite H2. rewrite H4.
+      reflexivity. rewrite H0.
+      apply redundant_flatten_list. exfalso. auto.
+      destruct (eq_dec_form (A --> B) (A --> B)). simpl (snd (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+      simpl (fst (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)). repeat rewrite effective_remove_nth.
+      assert (length Γ0 = length Γ0). reflexivity.
+      pose (@nth_split_length_id Γ0 Γ1 (length Γ0) H0). destruct a. rewrite H2. rewrite H4.
+      apply InT_eq. exfalso. auto.
+    + subst. assert (J1: (length Γ0) = (length Γ0)). reflexivity. apply InT_In in H3.
+      pose (IHl (length Γ0) H J1 H3). simpl. destruct n0. assumption. apply InT_or_app. auto.
+  * subst. apply In_InT_pair in H1. inversion H1. subst. inversion H2. subst. apply InT_In in H2.
+    assert (J1: length Γ0 = length Γ0). reflexivity.
+    pose (IHl _ H J1 H2). simpl. destruct n0. assumption. assumption.
+Defined.
+ +
+Definition ImpL_help2 : forall prem1 prem2 s, ImpLRule [prem1; prem2] s ->
+                      InT [prem1; prem2] (prems_Imp_L (pos_top_imps (fst s)) s).
+Proof.
+intros. inversion H. subst. simpl.
+pose (@ImpL_help02 Γ0 Γ1 Δ0 Δ1 A B (pos_top_imps (Γ0 ++ (Imp A B) :: Γ1)) (length Γ0)). apply i ; try assumption.
+reflexivity. apply Good_pos_in_pos_top_imps.
+Defined.
+ +
+Definition ImpL_help01 : forall prems s l, InT prems (prems_Imp_L l s) ->
+                  (existsT2 n prem1 prem2 A B Γ0 Γ1 Δ0 Δ1,
+                        (prems = [prem1; prem2]) /\
+                        (In ((Imp A B), S n) l) /\
+                        (prem1 = (Γ0 ++ Γ1, Δ0 ++ A :: Δ1)) /\
+                        (prem2 = (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)) /\
+                        (Δ0 ++ Δ1 = snd s) /\
+                        (Γ0 = (fst (nth_split n (remove_nth (S n) (Imp A B) (fst s))))) /\
+                        (Γ1 = (snd (nth_split n (remove_nth (S n) (Imp A B) (fst s)))))).
+Proof.
+intros prems s. destruct s. induction l1 ; intros X.
+- simpl in X. inversion X.
+- simpl (fst (l, l0)). destruct a as [m n]. destruct m as [n0 | | | ].
+  * simpl in X. destruct n.
+    + pose (s := IHl1 X). repeat destruct s. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. exists x6. exists x7.
+      repeat split ; try tauto. apply in_cons. tauto.
+    + pose (s := IHl1 X). repeat destruct s. repeat destruct p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. exists x6. exists x7.
+      repeat split ; try tauto. apply in_cons. tauto.
+  * simpl in X. destruct n.
+    + pose (s := IHl1 X). repeat destruct s. repeat destruct p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. exists x6. exists x7.
+      repeat split ; try tauto. apply in_cons. tauto.
+    + pose (s := IHl1 X). repeat destruct s. repeat destruct p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. exists x6. exists x7.
+      repeat split ; try tauto. apply in_cons. tauto.
+  * destruct n.
+    + pose (s := IHl1 X). repeat destruct s. repeat destruct p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. exists x6. exists x7.
+      repeat split ; try tauto. apply in_cons. tauto.
+    + apply InT_app_or in X. destruct X.
+      { simpl (fst (l, l0)) in i. simpl (snd (l, l0)) in i.
+        apply InT_flatten_list_InT_elem in i. destruct i. destruct p.
+        apply InT_map_iff in i0. destruct i0. destruct p.
+        inversion i0. subst. apply InT_map_iff in i. destruct i.
+        destruct p. unfold listInsertsL_Seqs in i. apply InT_map_iff in i.
+        destruct i. destruct p. subst. unfold listInserts in i. apply InT_map_iff in i. destruct i.
+        destruct p. destruct x. subst. destruct (list_of_splits l0). simpl in i. exists n.
+        simpl (fst (l2, l3)). simpl (snd (l2, l3)).
+        exists (fst (nth_split n (remove_nth (S n) (m1 --> m2) l)) ++
+        snd (nth_split n (remove_nth (S n) (m1 --> m2) l)), l2 ++ m1 :: l3).
+        exists (fst
+          (nth_split n
+             match n with
+             | 0 =>
+                 match l with
+                 | [] => []
+                 | B0 :: tl => if eq_dec_form (m1 --> m2) B0 then tl else B0 :: tl
+                 end
+             | S _ => match l with
+                      | [] => []
+                      | B0 :: tl => B0 :: remove_nth n (m1 --> m2) tl
+                      end
+             end) ++
+        m2
+        :: snd
+             (nth_split n
+                match n with
+                | 0 =>
+                    match l with
+                    | [] => []
+                    | B0 :: tl => if eq_dec_form (m1 --> m2) B0 then tl else B0 :: tl
+                    end
+                | S _ => match l with
+                         | [] => []
+                         | B0 :: tl => B0 :: remove_nth n (m1 --> m2) tl
+                         end
+                end), l0).
+        exists m1. exists m2. exists (fst (nth_split n (remove_nth (S n) (m1 --> m2) l))).
+        exists (snd (nth_split n (remove_nth (S n) (m1 --> m2) l))).
+        exists l2. exists l3. simpl (snd (l, l0)). simpl (fst (l, l0)).
+        repeat split ; try auto. apply in_eq. simpl. assert (l2 ++ l3 = l0). rewrite i1. apply InT_In.
+        assumption. rewrite <- H. reflexivity. rewrite i1. apply InT_In. assumption. subst. inversion H0. }
+      { pose (IHl1 i). repeat destruct s. repeat destruct p. exists x. exists x0. exists x1.
+        exists x2. exists x3. exists x4. exists x5. exists x6. exists x7.
+        repeat split ; try tauto. apply in_cons. tauto. }
+  * simpl in X. destruct n.
+    + pose (IHl1 X). repeat destruct s. repeat destruct p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. exists x6. exists x7.
+      repeat split ; try tauto. apply in_cons. tauto.
+    + pose (IHl1 X). repeat destruct s. repeat destruct p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. exists x6. exists x7.
+      repeat split ; try tauto. apply in_cons. tauto.
+Defined.
+ +
+Definition ImpL_help1 : forall prems s, InT prems (prems_Imp_L (pos_top_imps (fst s)) s) ->
+                                         ImpLRule prems s.
+Proof.
+intros prem s X. pose (s0 := @ImpL_help01 _ _ _ X). destruct s0 as (n&Hn&A&B&Γ0&Γ1&Δ0& Δ1&e1&Heq&i&p). destruct s as (l&l0). simpl in X.
+intuition. subst.
+apply In_pos_top_imps_split_l in i.
+simpl (fst (l, l0)). simpl in H0. subst.
simpl (fst (l, Δ1 ++ e1)) in X.
+destruct i as (l0&l1&Heq1&Heq3&Heq2&Heq4).
+subst.
+simpl (fst (l, Δ1 ++ e1)) in Heq1.
+simpl (fst (l, Δ1 ++ e1)) in Heq2.
+remember (fst (nth_split (length l0) (remove_nth (S (length l0)) (B --> Γ0) l))) as Γ0'.
+remember (snd (nth_split (length l0) (remove_nth (S (length l0)) (B --> Γ0) l))) as Γ1'.
+rewrite Heq1, Heq2.
+apply ImpLRule_I.
+Defined.
+ +
+Definition finite_ImpL_premises_of_S : forall (s : Seq), existsT2 listImpLprems,
+              (forall prems, ((ImpLRule prems s) -> (InT prems listImpLprems)) *
+                             ((InT prems listImpLprems) -> (ImpLRule prems s))).
+Proof.
+intros. destruct s.
+exists (prems_Imp_L (pos_top_imps l) (l,l0)).
+intros. split ; intro.
+- inversion H. subst.
+  pose (@ImpL_help2 (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)). apply i.
+  assumption.
+- pose (@ImpL_help1 prems (l, l0)). apply i. assumption.
+Defined.
+ +
+(* Now let us tackle the GLR rule. *)
+ +
+Fixpoint prems_Box_R (l : list MPropF) (s : Seq) : list (list Seq) :=
+match l with
+  | nil => nil
+  | h :: t => match h with
+              | Box A => [((XBoxed_list (top_boxes (fst s))) ++ [Box A], [A])] :: (prems_Box_R t s)
+              | _ => prems_Box_R t s
+              end
+end.
+ +
Definition GLR_help01 : forall prems s (l : list MPropF), InT prems (prems_Box_R l s) ->
+                  (existsT2 (A : MPropF),
+                        (In (Box A) l) /\
+                        (prems = [(XBoxed_list (top_boxes (fst s)) ++ [Box A], [A])])).
+Proof.
+intros prems s. destruct s. induction l1 ; intros X.
+- simpl in X. inversion X.
+- simpl in X. destruct a.
+  * apply IHl1 in X. destruct X as (x & i & p). subst.
+     exists x. repeat split ; try auto ; try apply in_cons ; try assumption.
+  * apply IHl1 in X. destruct X as (x & i & p). subst.
+     exists x. repeat split ; try auto ; try apply in_cons ; try assumption.
+  * apply IHl1 in X. destruct X as (x & i & p). subst.
+     exists x. repeat split ; try auto ; try apply in_cons ; try assumption.
+  * inversion X.
+    + subst. eexists a. repeat split ; try auto ; try apply in_eq.
+    + apply IHl1 in H0. decompose record H0. subst.
+        exists x. repeat split ; try auto ; try apply in_cons ; try assumption.
+Defined.
+ +
+Definition GLR_help1 : forall prems s, InT prems (prems_Box_R (top_boxes (snd s)) s) ->
+                                         GLRRule prems s.
+Proof.
+intros prems s X. destruct (@GLR_help01 _ _ _ X) as (x&i&Heq). destruct s. simpl in X.
+subst. simpl in i. assert (In (Box x) l0). apply top_boxes_incl_list.
+assumption. apply in_splitT in H. destruct H. repeat destruct s.
+rewrite e. apply GLRRule_I. intro. intros. apply in_top_boxes in H.
+destruct H. repeat destruct s. repeat destruct p. exists x2. assumption.
+simpl. apply top_boxes_nobox_gen_ext.
+Defined.
+ +
+Definition GLR_help02 : forall Γ Δ0 Δ1 A l, GLRRule [(XBoxed_list ++ [Box A], [A])] (Γ, Δ0 ++ Box A :: Δ1) ->
+                                             (is_Boxed_list ) ->
+                                             (nobox_gen_ext Γ) ->
+                                             (In (Box A) l) ->
+                                             InT [(XBoxed_list ++ [Box A], [A])] (prems_Box_R l (Γ, Δ0 ++ Box A :: Δ1)).
+Proof.
+induction l ; intros.
+- inversion H0.
+- simpl. destruct a as [n | | | ].
+  * assert (InT (Box A) (# n :: l)). apply in_splitT in H0. destruct H0. destruct s. rewrite e.
+    apply InT_or_app. right. apply InT_eq. inversion H1. inversion H3. apply InT_In in H3.
+    pose (IHl X H X0 H3). assumption.
+  * assert (InT (Box A) ( :: l)). apply in_splitT in H0. destruct H0. destruct s. rewrite e.
+    apply InT_or_app. right. apply InT_eq. inversion H1. inversion H3. apply InT_In in H3.
+    pose (IHl X H X0 H3). assumption.
+  * assert (InT (Box A) (a1 --> a2 :: l)). apply in_splitT in H0. destruct H0. destruct s. rewrite e.
+    apply InT_or_app. right. apply InT_eq. inversion H1. inversion H3. apply InT_In in H3.
+    pose (IHl X H X0 H3). assumption.
+  * assert (InT (Box A) (Box a :: l)). apply in_splitT in H0. destruct H0. destruct s. rewrite e.
+    apply InT_or_app. right. apply InT_eq. inversion H1.
+    + subst. inversion H3. subst. pose (nobox_gen_ext_top_boxes_identity X0 H). rewrite e.
+      apply InT_eq.
+    + subst. apply InT_In in H3. pose (IHl X H X0 H3). apply InT_cons. assumption.
+Defined.
+ +
+Definition GLR_help2 : forall prem s, GLRRule [prem] s ->
+                      InT [prem] (prems_Box_R (top_boxes (snd s)) s).
+Proof.
+intros. inversion X. subst. simpl.
+pose (@GLR_help02 Γ0 Δ0 Δ1 A (top_boxes (Δ0 ++ Box A :: Δ1))). apply i ; try assumption.
+rewrite top_boxes_distr_app. simpl. apply in_or_app. right. apply in_eq.
+Defined.
+ +
+Definition finite_GLR_premises_of_S : forall (s : Seq), existsT2 listGLRprems,
+              (forall prems, ((GLRRule prems s) -> (InT prems listGLRprems)) *
+                             ((InT prems listGLRprems) -> (GLRRule prems s))).
+Proof.
+intros. destruct s.
+exists (prems_Box_R (top_boxes l0) (l,l0)).
+intros. split ; intro.
+- inversion X. subst.
+  pose (@GLR_help2 (XBoxed_list ++ [Box A], [A]) (l, Δ0 ++ Box A :: Δ1)). apply i.
+  assumption.
+- pose (@GLR_help1 prems (l, l0)). apply g. assumption.
+Defined.
+ +
+(* Obviously, we can obtain the same result for the initial sequents. *)
+ +
+Definition finite_IdP_premises_of_S : forall (s : Seq), existsT2 listIdPprems,
+              (forall prems, ((IdPRule prems s) -> (InT prems listIdPprems)) *
+                             ((InT prems listIdPprems) -> (IdPRule prems s))).
+Proof.
+intros s. destruct (dec_IdP_rule s).
+- exists [[]]. intros. split ; intro.
+  * inversion H. subst. apply InT_eq.
+  * inversion H. subst. assumption. inversion H1.
+- exists []. intros. split ; intro.
+  * inversion H. subst. exfalso. apply f. assumption.
+  * inversion H.
+Defined.
+ +
+Definition finite_IdB_premises_of_S : forall (s : Seq), existsT2 listIdBprems,
+              (forall prems, ((IdBRule prems s) -> (InT prems listIdBprems)) *
+                             ((InT prems listIdBprems) -> (IdBRule prems s))).
+Proof.
+intros s. destruct (dec_IdB_rule s).
+- exists [[]]. intros. split ; intro.
+  * inversion H. subst. apply InT_eq.
+  * inversion H. subst. assumption. inversion H1.
+- exists []. intros. split ; intro.
+  * inversion H. subst. exfalso. apply f. assumption.
+  * inversion H.
+Defined.
+ +
+Definition finite_BotL_premises_of_S : forall (s : Seq), existsT2 listBotLprems,
+              (forall prems, ((BotLRule prems s) -> (InT prems listBotLprems)) *
+                             ((InT prems listBotLprems) -> (BotLRule prems s))).
+Proof.
+intros. destruct (dec_BotL_rule s).
+- exists [[]]. intros. split ; intro.
+  * inversion H. subst. apply InT_eq.
+  * inversion H. subst. assumption. inversion H1.
+- exists []. intros. split ; intro.
+  * inversion H. subst. exfalso. apply f. assumption.
+  * inversion H.
+Defined.
+ +
+(* Now that we have the list of all premises of a sequent via all rules, we can combine
+   them all to obtain the list of all potential premises via the GLS calculus. *)

+ +
+Definition finite_premises_of_S : forall (s : Seq), existsT2 listprems,
+              (forall prems, ((GLS_rules prems s) -> (InT prems listprems)) *
+                             ((InT prems listprems) -> (GLS_rules prems s))).
+Proof.
+intro s.
+destruct (dec_GLS_rules s).
+- exists []. intros. split. intro. exfalso. apply f. exists prems. assumption.
+  intro. inversion H.
+- pose (finite_IdP_premises_of_S s). destruct s1.
+  pose (finite_BotL_premises_of_S s). destruct s1.
+  pose (finite_ImpR_premises_of_S s). destruct s1.
+  pose (finite_ImpL_premises_of_S s). destruct s1.
+  pose (finite_GLR_premises_of_S s). destruct s1.
+  exists (x ++ x0 ++ x1 ++ x2 ++ x3).
+  split.
+  * intro RA. inversion RA.
+    { inversion H. subst. pose (p []). destruct p4. apply InT_or_app. auto. }
+    { inversion H. subst. pose (p0 []). destruct p4. apply InT_or_app. right. apply InT_or_app. auto. }
+    { inversion H. subst. pose (p1 [(Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)]). destruct p4.
+      apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. auto. }
+    { inversion H. subst. pose (p2 [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]).
+      destruct p4. apply InT_or_app. right. apply InT_or_app. right.
+      apply InT_or_app. right. apply InT_or_app. auto. }
+    { inversion X. subst. pose (p3 [(XBoxed_list ++ [Box A], [A])]).
+      destruct p4. apply InT_or_app. right. apply InT_or_app.
+      right. apply InT_or_app. right. apply InT_or_app. right. auto. }
+  * intro. apply InT_app_or in H. destruct H.
+    { apply p in i. apply IdP ; try intro ; try apply f ; try auto ; try assumption. }
+    { apply InT_app_or in i. destruct i.
+      - apply p0 in i. apply BotL ; try intro ; try apply f ; try auto ; try assumption.
+      - apply InT_app_or in i. destruct i.
+        + apply p1 in i. apply ImpR ; try intro ; try apply f ; try auto ; try assumption.
+        + apply InT_app_or in i. destruct i.
+          * apply p2 in i. apply ImpL ; try intro ; try apply f ; try auto ; try assumption.
+          * apply p3 in i. apply GLR ; try intro ; try apply f ; try auto ; try assumption. }
+        Defined.
+ +
+(* The next definitions "flattens" a list of lists of premises to a list of premises.*)
+ +
+Definition list_of_premises (s : Seq) : list Seq :=
+         flatten_list (proj1_sigT2 (finite_premises_of_S s)).
+ +
+Lemma InT_list_of_premises_exists_prems : forall s prem, InT prem (list_of_premises s) ->
+            existsT2 prems, (InT prem prems) * (GLS_rules prems s).
+Proof.
+intros s prem X. unfold list_of_premises in X.
+apply InT_flatten_list_InT_elem in X. destruct X. destruct p.
+exists x. split. auto.
+destruct (finite_premises_of_S s). pose (p x). destruct p0. apply g. assumption.
+Qed.
+ +
+Lemma exists_prems_InT_list_of_premises : forall s prem,
+            (existsT2 prems, (InT prem prems) * (GLS_rules prems s)) ->
+            InT prem (list_of_premises s).
+Proof.
+intros. destruct X. destruct p. unfold list_of_premises. destruct (finite_premises_of_S s).
+pose (p x). destruct p0. apply InT_trans_flatten_list with (bs:=x). assumption. simpl. apply i0.
+assumption.
+Qed.
+ +
+(* Decidability *)
+ +
+Lemma derrec_composition: forall X (rules : list X -> X -> Type) (prems0 prems1 : X -> Prop) (concl : X),
+     (forall leaf : X, prems0 leaf -> (derrec rules prems1 leaf)) ->
+     (derrec rules prems0 concl) ->
+     (derrec rules prems1 concl).
+Proof.
+intros X rules prems0 prems1 concl HypLeaves der. apply derrec_all_rect with
+(Q:= fun x => (derrec rules prems1 x))
+in der.
+- exact der.
+- intros. apply HypLeaves. assumption.
+- intros ps concl0 RA ders IH. apply dersrec_all in IH. apply derI with (ps:=ps) ; assumption.
+Qed.
+ +
+Theorem derrec_leaves_thms : forall (s0 s1 : rel (list MPropF)),
+        (derrec GLS_rules (fun x => (x = s0)) s1) ->
+        (derrec GLS_rules (fun _ => False) s0) ->
+        (derrec GLS_rules (fun _ => False) s1).
+Proof.
+intros s0 s1 leaves pfs.
+pose (@derrec_composition (rel (list MPropF)) GLS_rules (fun x => (x = s0)) (fun _ => False)
+s1). apply d.
+- intros. inversion H. assumption.
+- assumption.
+Qed.
+ +
+Theorem GLS_dec_der : forall s,
+  (derrec GLS_rules (fun _ => False) s) + ((derrec GLS_rules (fun _ => False) s) -> False).
+Proof.
+apply less_thanS_strong_inductionT.
+intros s IH. pose (finite_premises_of_S s). destruct s0.
+destruct (dec_init_rules s).
+- left. destruct s0. destruct s0. 1,3: apply derI with (ps:=[]) ; auto.
+  2,4: apply dlNil. apply IdP ; auto. apply BotL ; auto.
+  inversion i ; subst. apply Id_all_form.
+- assert (forall prems, (InT prems x) -> ((dersrec GLS_rules (fun _ => False) prems) +
+  ((dersrec GLS_rules (fun _ => False) prems) -> False))).
+  { intros. pose (p prems). destruct p0. apply g in H. inversion H.
+    - inversion H0. subst. left ; apply dlNil.
+    - inversion H0. subst. left ; apply dlNil.
+    - inversion H0. subst.
+      assert (J1: (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) << (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1)).
+      apply ImpR_applic_reduces_measure ; auto. destruct (IH _ J1).
+      * left ; apply dlCons ; auto ; apply dlNil.
+      * right. intro. inversion X. subst. auto.
+    - inversion H0. subst.
+      destruct (ImpL_applic_reduces_measure H0). destruct (IH _ l) ; destruct (IH _ l0).
+      * left. apply dlCons ; auto ; apply dlCons ; auto ; apply dlNil.
+      * right. intro. inversion X. subst. inversion X1. subst. auto.
+      * right. intro. inversion X. subst. auto.
+      * right. intro. inversion X. subst. auto.
+    - inversion X. subst.
+      assert (J1: (XBoxed_list ++ [Box A], [A]) << (Γ0, Δ0 ++ Box A :: Δ1)).
+      apply (GLR_applic_reduces_measure X) ; auto. destruct (IH _ J1).
+      * left. apply dlCons ; auto ; apply dlNil.
+      * right. intro. inversion X1. subst. auto. }
+  assert ((existsT2 prems, (InT prems x) * (dersrec GLS_rules (fun _ => False) prems)) +
+  (forall prems, (InT prems x) -> ((dersrec GLS_rules (fun _ => False) prems) -> False))).
+  { assert ((existsT2 prems, (InT prems x) * (dersrec GLS_rules (fun _ => False) prems)) +
+    ((existsT2 prems, (InT prems x) * (dersrec GLS_rules (fun _ => False) prems)) -> False)).
+    { pose (@forall_elem_list _ x (fun y =>
+      dersrec GLS_rules (fun _ : rel (list MPropF) => False) y) X). destruct s0.
+      - left. auto.
+      - right. auto. }
+    destruct X0.
+    - destruct s0. destruct p0. left. exists x0. auto.
+    - right. intros. firstorder. }
+  destruct X0.
+  ++ destruct s0. destruct p0. pose (p x0). destruct p0. apply g in i. left. apply derI with (ps:=x0) ; assumption.
+  ++ pose (dec_init_rules s). repeat destruct s0.
+    * left. apply derI with (ps:=[]) ; [apply IdP ; assumption | apply dlNil].
+    * left. inversion i ; subst. apply Id_all_form.
+    * left. apply derI with (ps:=[]) ; [apply BotL ; assumption | apply dlNil].
+    * right. intro der. inversion der.
+      + inversion H.
+      + subst. inversion X0.
+        { inversion H. subst. apply f. auto. }
+        { inversion H. subst. apply f. auto. }
+        { subst. pose (f0 ps). apply f2. pose (p ps). destruct p0. apply i. assumption.
+          assumption. }
+        { subst. pose (f0 ps). apply f2. pose (p ps). destruct p0. apply i. assumption.
+          assumption. }
+        { subst. pose (f0 ps). apply f2. pose (p ps). destruct p0. apply i. assumption.
+          assumption. }
+Qed.
+ +
+
+
+ +
+ + + diff --git a/GL.GLS.GLS_exch.html b/GL.GLS.GLS_exch.html new file mode 100644 index 0000000..a155d42 --- /dev/null +++ b/GL.GLS.GLS_exch.html @@ -0,0 +1,2278 @@ + + + + + + + + + + + + + +
+
+

GL.GLS.GLS_exch

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat.
+Require Import Lia.
+Require Import Arith.
+ +
+Require Import GLS_calcs.
+ +
+Set Implicit Arguments.
+ +
+(* First, as we want to mimick sequents based on multisets of formulae we need to
+obtain exchange. *)

+ +
+(* Definition of exchange with lists of formulae directly. It is more general and
+makes the proofs easier to handle. *)

+ +
+Inductive list_exch_L : relationT Seq :=
+  | list_exch_LI Γ0 Γ1 Γ2 Γ3 Γ4 Δ : list_exch_L
+      (Γ0 ++ Γ1 ++ Γ2 ++ Γ3 ++ Γ4, Δ) (Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4, Δ).
+ +
+Inductive list_exch_R : relationT Seq :=
+  | list_exch_RI Γ Δ0 Δ1 Δ2 Δ3 Δ4 : list_exch_R
+        (Γ, Δ0 ++ Δ1 ++ Δ2 ++ Δ3 ++ Δ4) (Γ, Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4).
+ +
+(* Some lemmas about In and exchange. *)
+ +
+Lemma InT_list_exch_R : forall l0 l1 l2,
+            (@list_exch_R (l0,l1) (l0,l2)) ->
+            (forall x, (InT x l1 -> InT x l2) * (InT x l2 -> InT x l1)).
+Proof.
+intros l0 l1 l2 exch. inversion exch.
+intro x. split.
+- intro. apply InT_app_or in H2. destruct H2. apply InT_or_app. left. assumption.
+  apply InT_app_or in i. destruct i. apply InT_or_app. right. apply InT_or_app. right.
+  apply InT_or_app. right. apply InT_or_app. left. assumption. apply InT_app_or in i.
+  destruct i. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. left.
+  assumption. apply InT_app_or in i. destruct i. apply InT_or_app. right. apply InT_or_app.
+  left. assumption. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. right.
+  assumption.
+- intro. apply InT_app_or in H2. destruct H2. apply InT_or_app. left. assumption.
+  apply InT_app_or in i. destruct i. apply InT_or_app. right. apply InT_or_app. right.
+  apply InT_or_app. right. apply InT_or_app. left. assumption. apply InT_app_or in i.
+  destruct i. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. left.
+  assumption. apply InT_app_or in i. destruct i. apply InT_or_app. right. apply InT_or_app.
+  left. assumption. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. right.
+  assumption.
+Qed.
+ +
+Lemma InT_list_exch_L : forall l0 l1 l2,
+            (@list_exch_L (l1,l0) (l2,l0)) ->
+            (forall x, (InT x l1 -> InT x l2) * (InT x l2 -> InT x l1)).
+Proof.
+intros l0 l1 l2 exch. inversion exch.
+intro x. split.
+- intro. apply InT_app_or in H2. destruct H2. apply InT_or_app. left. assumption.
+  apply InT_app_or in i. destruct i. apply InT_or_app. right. apply InT_or_app. right.
+  apply InT_or_app. right. apply InT_or_app. left. assumption. apply InT_app_or in i.
+  destruct i. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. left.
+  assumption. apply InT_app_or in i. destruct i. apply InT_or_app. right. apply InT_or_app.
+  left. assumption. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. right.
+  assumption.
+- intro. apply InT_app_or in H2. destruct H2. apply InT_or_app. left. assumption.
+  apply InT_app_or in i. destruct i. apply InT_or_app. right. apply InT_or_app. right.
+  apply InT_or_app. right. apply InT_or_app. left. assumption. apply InT_app_or in i.
+  destruct i. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. left.
+  assumption. apply InT_app_or in i. destruct i. apply InT_or_app. right. apply InT_or_app.
+  left. assumption. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. right.
+  assumption.
+Qed.
+ +
+(* Some useful lemmas about list exchange. *)
+ +
+Lemma list_exch_R_id : forall s, (@list_exch_R s s).
+Proof.
+intros s. destruct s. pose (list_exch_RI l l0
+[] [] [] []). simpl in l1. assert (H: l0 ++ [] = l0).
+apply app_nil_r. rewrite H in l1. assumption.
+Qed.
+ +
+Lemma list_exch_L_id : forall s, (@list_exch_L s s).
+Proof.
+intros s. destruct s. pose (list_exch_LI l
+[] [] [] [] l0). simpl in l1. assert (H: l ++ [] = l).
+apply app_nil_r. rewrite H in l1. assumption.
+Qed.
+ +
+Lemma list_exch_R_same_L: forall s se,
+    (@list_exch_R s se) ->
+    (forall Γ Γe Δ Δe, (s = (Γ , Δ)) ->
+    (se = (Γe , Δe)) ->
+    (Γ = Γe)).
+Proof.
+intros s se exch. induction exch. intros Γ0 Γe Δ Δe E1 E2.
+inversion E1. inversion E2. rewrite H0 in H2. assumption.
+Qed.
+ +
+Lemma list_exch_L_same_R : forall s se,
+    (@list_exch_L s se) ->
+    (forall Γ Γe Δ Δe, (s = (Γ , Δ)) ->
+    (se = (Γe , Δe)) ->
+    (Δ = Δe)).
+Proof.
+intros s se exch. induction exch. intros Γ Γe Δ0 Δe E1 E2.
+inversion E1. inversion E2. rewrite H1 in H3. assumption.
+Qed.
+ +
+Lemma list_exch_R_permL : forall s se,
+    (@list_exch_R s se) ->
+      (forall Γ0 Γ1 Δ C, s = ((Γ0 ++ C :: Γ1), Δ) ->
+      (existsT2 , se = ((Γ0 ++ C :: Γ1), ))).
+Proof.
+intros s se exch. induction exch. intros Γ0 Γ1 Δ C E.
+inversion E. exists (Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4). reflexivity.
+Qed.
+ +
+Lemma list_exch_R_permR : forall s se,
+    (@list_exch_R s se) ->
+      (forall Γ Δ0 Δ1 C, s = (Γ, (Δ0 ++ C :: Δ1)) ->
+      (existsT2 eΔ0 eΔ1, se = (Γ, (eΔ0 ++ C :: eΔ1)))).
+Proof.
+intros s se exch. induction exch. intros Γ0 Δ5 Δ6 C E.
+inversion E. apply partition_1_element in H1. destruct H1.
++ destruct s. destruct s. rewrite e. exists x. exists (x0 ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4).
+  simpl.
+  assert (E1: (x ++ C :: x0) ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4 = x ++ C :: x0 ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4).
+  { symmetry. apply app_assoc with (l:=x) (m:=C :: x0) (n:=Δ3 ++ Δ2 ++ Δ1 ++ Δ4). }
+  rewrite E1. reflexivity.
++ destruct s.
+  * destruct s. destruct s. exists (Δ0 ++ Δ3 ++ Δ2 ++ x). exists (x0 ++ Δ4).
+    rewrite e. assert (E1: Δ0 ++ Δ3 ++ Δ2 ++ (x ++ C :: x0) ++ Δ4 =
+    (Δ0 ++ Δ3 ++ Δ2 ++ x) ++ C :: x0 ++ Δ4).
+    pose (app_assoc x (C :: x0) Δ4). rewrite <- e0. simpl.
+    pose (app_assoc (Δ0 ++ Δ3 ++ Δ2) x (C :: x0 ++ Δ4)).
+    pose (app_assoc (Δ0 ++ Δ3) Δ2 x).
+    pose (app_assoc Δ0 Δ3 Δ2).
+    rewrite <- e3 in e2. rewrite <- e2 in e1.
+    pose (app_assoc Δ0 Δ3 (Δ2 ++ x)). rewrite <- e4 in e1. rewrite <- e1.
+    pose (app_assoc (Δ0 ++ Δ3) Δ2 (x ++ C :: x0 ++ Δ4)).
+    rewrite <- e3 in e5. rewrite <- e5.
+    pose (app_assoc Δ0 Δ3 (Δ2 ++ x ++ C :: x0 ++ Δ4)). rewrite e6. reflexivity.
+    rewrite E1. reflexivity.
+  * destruct s.
+    - destruct s. destruct s. exists (Δ0 ++ Δ3 ++ x). exists (x0 ++ Δ1 ++ Δ4).
+      rewrite e. assert (E1: Δ0 ++ Δ3 ++ (x ++ C :: x0) ++ Δ1 ++ Δ4 =
+      (Δ0 ++ Δ3 ++ x) ++ C :: x0 ++ Δ1 ++ Δ4).
+      pose (app_assoc x (C :: x0) (Δ1 ++ Δ4)). rewrite <- e0. simpl.
+      pose (app_assoc (Δ0 ++ Δ3) x (C :: x0 ++ Δ1 ++ Δ4)).
+      pose (app_assoc Δ0 Δ3 x). rewrite <- e2 in e1. rewrite <- e1.
+      pose (app_assoc Δ0 Δ3 (x ++ C :: x0 ++ Δ1 ++ Δ4)). rewrite <- e3.
+      reflexivity. rewrite E1. reflexivity.
+    - destruct s.
+      { destruct s. destruct s. rewrite e. exists (Δ0 ++ x). exists (x0 ++ Δ2 ++ Δ1 ++ Δ4).
+        assert (E1: Δ0 ++ (x ++ C :: x0) ++ Δ2 ++ Δ1 ++ Δ4 =
+        (Δ0 ++ x) ++ C :: x0 ++ Δ2 ++ Δ1 ++ Δ4).
+        pose (app_assoc x (C :: x0) (Δ2 ++ Δ1 ++ Δ4)). rewrite <- e0. simpl.
+        pose (app_assoc Δ0 x (C :: x0 ++ Δ2 ++ Δ1 ++ Δ4)). rewrite e1.
+        reflexivity. rewrite E1. reflexivity. }
+      { destruct s. destruct s. rewrite e. exists (Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ x).
+        exists x0. assert (E1: Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ x ++ C :: x0 =
+        (Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ x) ++ C :: x0).
+        pose (app_assoc (Δ0 ++ Δ3 ++ Δ2 ++ Δ1) x (C :: x0)).
+        pose (app_assoc (Δ0 ++ Δ3 ++ Δ2) Δ1 x).
+        pose (app_assoc (Δ0 ++ Δ3) Δ2 Δ1).
+        pose (app_assoc Δ0 Δ3 Δ2). rewrite <- e3 in e2. rewrite <- e2 in e1.
+        pose (app_assoc Δ0 Δ3 (Δ2 ++ Δ1)). rewrite <- e4 in e1. rewrite <- e1 in e0.
+        pose (app_assoc (Δ0 ++ Δ3) Δ2 (Δ1 ++ x)). rewrite <- e3 in e5.
+        rewrite <- e5 in e0.
+        pose (app_assoc Δ0 Δ3 (Δ2 ++ Δ1 ++ x)). rewrite <- e6 in e0.
+        rewrite <- e0.
+        pose (app_assoc (Δ0 ++ Δ3 ++ Δ2) Δ1 (x ++ C :: x0)).
+        rewrite <- e2 in e7. rewrite <- e4 in e7. rewrite <- e7.
+        pose (app_assoc (Δ0 ++ Δ3) Δ2 (Δ1 ++ x ++ C :: x0)).
+        rewrite <- e3 in e8. rewrite <- e8.
+        pose (app_assoc Δ0 Δ3 (Δ2 ++ Δ1 ++ x ++ C :: x0)).
+        rewrite e9. reflexivity. rewrite E1. reflexivity. }
+Qed.
+ +
+Lemma list_exch_R_permLR : forall s se,
+    (@list_exch_R s se) ->
+      (forall Γ0 Γ1 Δ0 Δ1 C D, s = ((Γ0 ++ C :: Γ1), (Δ0 ++ D :: Δ1)) ->
+      (existsT2 eΔ0 eΔ1, se = ((Γ0 ++ C :: Γ1), (eΔ0 ++ D :: eΔ1)))).
+Proof.
+intros s se exch. intros Γ0 Γ1 Δ0 Δ1 C D Eq.
+pose (list_exch_R_permL exch). pose (s0 Γ0 Γ1 (Δ0 ++ D :: Δ1) C).
+pose (s1 Eq). destruct s2.
+pose (list_exch_R_permR exch). pose (s2 (Γ0 ++ C :: Γ1) Δ0 Δ1 D).
+pose (s3 Eq). destruct s4. destruct s4. exists x0. exists x1. assumption.
+Qed.
+ +
+Lemma list_exch_L_permL : forall s se,
+    (@list_exch_L s se) ->
+      (forall Γ0 Γ1 Δ C, s = ((Γ0 ++ C :: Γ1), Δ) ->
+      (existsT2 eΓ0 eΓ1, se = ((eΓ0 ++ C :: eΓ1), Δ))).
+Proof.
+intros s se exch. induction exch. intros Γ5 Γ6 Δ0 C E.
+inversion E. apply partition_1_element in H0. destruct H0.
++ destruct s. destruct s. rewrite e. exists x. exists (x0 ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4).
+  simpl.
+  assert (E1: (x ++ C :: x0) ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4 = x ++ C :: x0 ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4).
+  { symmetry. apply app_assoc with (l:=x) (m:=C :: x0) (n:=Γ3 ++ Γ2 ++ Γ1 ++ Γ4). }
+  rewrite E1. reflexivity.
++ destruct s.
+  * destruct s. destruct s. exists (Γ0 ++ Γ3 ++ Γ2 ++ x). exists (x0 ++ Γ4).
+    rewrite e. assert (E1: Γ0 ++ Γ3 ++ Γ2 ++ (x ++ C :: x0) ++ Γ4 =
+    (Γ0 ++ Γ3 ++ Γ2 ++ x) ++ C :: x0 ++ Γ4).
+    pose (app_assoc x (C :: x0) Γ4). rewrite <- e0. simpl.
+    pose (app_assoc (Γ0 ++ Γ3 ++ Γ2) x (C :: x0 ++ Γ4)).
+    pose (app_assoc (Γ0 ++ Γ3) Γ2 x).
+    pose (app_assoc Γ0 Γ3 Γ2).
+    rewrite <- e3 in e2. rewrite <- e2 in e1.
+    pose (app_assoc Γ0 Γ3 (Γ2 ++ x)). rewrite <- e4 in e1. rewrite <- e1.
+    pose (app_assoc (Γ0 ++ Γ3) Γ2 (x ++ C :: x0 ++ Γ4)).
+    rewrite <- e3 in e5. rewrite <- e5.
+    pose (app_assoc Γ0 Γ3 (Γ2 ++ x ++ C :: x0 ++ Γ4)). rewrite e6. reflexivity.
+    rewrite E1. reflexivity.
+  * destruct s.
+    - destruct s. destruct s. exists (Γ0 ++ Γ3 ++ x). exists (x0 ++ Γ1 ++ Γ4).
+      rewrite e. assert (E1: Γ0 ++ Γ3 ++ (x ++ C :: x0) ++ Γ1 ++ Γ4 =
+      (Γ0 ++ Γ3 ++ x) ++ C :: x0 ++ Γ1 ++ Γ4).
+      pose (app_assoc x (C :: x0) (Γ1 ++ Γ4)). rewrite <- e0. simpl.
+      pose (app_assoc (Γ0 ++ Γ3) x (C :: x0 ++ Γ1 ++ Γ4)).
+      pose (app_assoc Γ0 Γ3 x). rewrite <- e2 in e1. rewrite <- e1.
+      pose (app_assoc Γ0 Γ3 (x ++ C :: x0 ++ Γ1 ++ Γ4)). rewrite <- e3.
+      reflexivity. rewrite E1. reflexivity.
+    - destruct s.
+      { destruct s. destruct s. rewrite e. exists (Γ0 ++ x). exists (x0 ++ Γ2 ++ Γ1 ++ Γ4).
+        assert (E1: Γ0 ++ (x ++ C :: x0) ++ Γ2 ++ Γ1 ++ Γ4 =
+        (Γ0 ++ x) ++ C :: x0 ++ Γ2 ++ Γ1 ++ Γ4).
+        pose (app_assoc x (C :: x0) (Γ2 ++ Γ1 ++ Γ4)). rewrite <- e0. simpl.
+        pose (app_assoc Γ0 x (C :: x0 ++ Γ2 ++ Γ1 ++ Γ4)). rewrite e1.
+        reflexivity. rewrite E1. reflexivity. }
+      { destruct s. destruct s. rewrite e. exists (Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ x).
+        exists x0. assert (E1: Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ x ++ C :: x0 =
+        (Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ x) ++ C :: x0).
+        pose (app_assoc (Γ0 ++ Γ3 ++ Γ2 ++ Γ1) x (C :: x0)).
+        pose (app_assoc (Γ0 ++ Γ3 ++ Γ2) Γ1 x).
+        pose (app_assoc (Γ0 ++ Γ3) Γ2 Γ1).
+        pose (app_assoc Γ0 Γ3 Γ2). rewrite <- e3 in e2. rewrite <- e2 in e1.
+        pose (app_assoc Γ0 Γ3 (Γ2 ++ Γ1)). rewrite <- e4 in e1. rewrite <- e1 in e0.
+        pose (app_assoc (Γ0 ++ Γ3) Γ2 (Γ1 ++ x)). rewrite <- e3 in e5.
+        rewrite <- e5 in e0.
+        pose (app_assoc Γ0 Γ3 (Γ2 ++ Γ1 ++ x)). rewrite <- e6 in e0.
+        rewrite <- e0.
+        pose (app_assoc (Γ0 ++ Γ3 ++ Γ2) Γ1 (x ++ C :: x0)).
+        rewrite <- e2 in e7. rewrite <- e4 in e7. rewrite <- e7.
+        pose (app_assoc (Γ0 ++ Γ3) Γ2 (Γ1 ++ x ++ C :: x0)).
+        rewrite <- e3 in e8. rewrite <- e8.
+        pose (app_assoc Γ0 Γ3 (Γ2 ++ Γ1 ++ x ++ C :: x0)).
+        rewrite e9. reflexivity. rewrite E1. reflexivity. }
+Qed.
+ +
+Lemma list_exch_L_permR : forall s se,
+    (@list_exch_L s se) ->
+      (forall Γ Δ0 Δ1 C, s = (Γ, (Δ0 ++ C :: Δ1)) ->
+      (existsT2 , se = (, (Δ0 ++ C :: Δ1)))).
+Proof.
+intros s se exch. induction exch. intros Γ Δ0 Δ1 C E.
+inversion E. exists (Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4). reflexivity.
+Qed.
+ +
+Lemma list_exch_L_permLR : forall s se,
+    (@list_exch_L s se) ->
+      (forall Γ0 Γ1 Δ0 Δ1 C D, s = ((Γ0 ++ C :: Γ1), (Δ0 ++ D :: Δ1)) ->
+      (existsT2 eΓ0 eΓ1, se = ((eΓ0 ++ C :: eΓ1), (Δ0 ++ D :: Δ1)))).
+Proof.
+intros s se exch. intros Γ0 Γ1 Δ0 Δ1 C D Eq.
+pose (list_exch_L_permR exch). pose (s0 (Γ0 ++ C :: Γ1) Δ0 Δ1 D).
+pose (s1 Eq). destruct s2.
+pose (list_exch_L_permL exch). pose (s2 Γ0 Γ1 (Δ0 ++ D :: Δ1) C).
+pose (s3 Eq). destruct s4. destruct s4. exists x0. exists x1. assumption.
+Qed.
+ +
+(* Some lemmas about atomic generalized extensions of lists and exchange. *)
+ +
+Lemma nobox_gen_ext_exch_R : forall Γ Γ' l0 l1 l2,
+    (nobox_gen_ext l0 l1) -> (@list_exch_R (Γ,l1) (Γ,l2)) ->
+    existsT2 l3, (nobox_gen_ext l3 l2) * (list_exch_R (Γ',l0) (Γ',l3)).
+Proof.
+intros Γ Γ' l0. induction l0.
++ intros l1 l2 gen. remember [] as l0. destruct gen.
+  - intro exch. inversion exch. apply app_eq_nil in H1. destruct H1. apply app_eq_nil in H2. destruct H2.
+    apply app_eq_nil in H3. destruct H3. apply app_eq_nil in H4. destruct H4.
+    subst. simpl. exists []. split.
+    * apply univ_gen_ext_nil.
+    * apply list_exch_R_id.
+  - intros exch. exists []. split.
+    * inversion Heql0.
+    * inversion Heql0.
+  - intro exch. subst. exists []. split. apply all_P_univ_gen_ext_nil.
+    intros. pose (InT_list_exch_R exch). pose (p x0). destruct p0. pose (univ_gen_ext_nil_all_P gen).
+    pose (f0 x0). apply i0 in H. inversion H. subst. apply f. assumption. subst. apply f1 in H1.
+    assumption. assumption.
+    apply list_exch_R_id.
++ intros l1 l2 gen. induction gen.
+  - intro exch. inversion exch. destruct Δ0.
+    * rewrite app_nil_l in H. rewrite app_nil_l in H1. rewrite app_nil_l. destruct Δ1.
+      { rewrite app_nil_l in H1. destruct Δ2.
+        + rewrite app_nil_l in H1. destruct Δ3.
+          - rewrite app_nil_l in H1. repeat rewrite app_nil_l in H. destruct Δ4.
+            * simpl. exists []. split. apply univ_gen_ext_nil. apply list_exch_R_id.
+            * inversion H1.
+          - inversion H1.
+        + inversion H1. }
+      { inversion H1. }
+    * inversion H1.
+  - intro exch. inversion exch. destruct Δ0.
+    * rewrite app_nil_l in H. rewrite app_nil_l in H1. rewrite app_nil_l. destruct Δ1.
+      { rewrite app_nil_l in H1. destruct Δ2.
+        + rewrite app_nil_l in H1. destruct Δ3.
+          - rewrite app_nil_l in H1. repeat rewrite app_nil_l in H. destruct Δ4.
+            * inversion H1.
+            * inversion H1. simpl. subst. exists (x :: l).
+              split. apply univ_gen_ext_cons. assumption. apply list_exch_R_id.
+          - repeat rewrite app_nil_l in H. repeat rewrite app_nil_l. simpl. simpl in H. simpl in H1.
+            inversion H1. subst. exists (x :: l). split. apply univ_gen_ext_cons. assumption. apply list_exch_R_id.
+        + rewrite app_nil_l. rewrite app_nil_l in H. inversion H1. subst.
+          pose (univ_gen_ext_splitR _ _ gen). repeat destruct s. repeat destruct p.
+          pose (univ_gen_ext_splitR _ _ u0). repeat destruct s. repeat destruct p. subst.
+          exists (x2 ++ x :: x0 ++ x3). split.
+          - apply univ_gen_ext_cons with (x:=x) in u. pose (univ_gen_ext_combine u u2).
+            pose (univ_gen_ext_combine u1 u3). assumption.
+          - pose (list_exch_RI Γ' [] [] (x :: x0) x2 x3). repeat rewrite app_nil_l in l. assumption. }
+      { inversion H1. subst. pose (univ_gen_ext_splitR _ _ gen). repeat destruct s. repeat destruct p.
+        pose (univ_gen_ext_splitR _ _ u0). repeat destruct s. repeat destruct p. pose (univ_gen_ext_splitR _ _ u2).
+        repeat destruct s. repeat destruct p. subst. exists (x4 ++ x2 ++ (x :: x0) ++ x5).
+        split.
+        - apply univ_gen_ext_cons with (x:=x) in u. pose (univ_gen_ext_combine u u4).
+          pose (univ_gen_ext_combine u1 u5). pose (univ_gen_ext_combine u3 u6). assumption.
+        - pose (list_exch_RI Γ' [] (x :: x0) x2 x4 x5). rewrite app_nil_l in l. assumption. }
+    * inversion H1. subst. pose (univ_gen_ext_splitR _ _ gen).
+      repeat destruct s. repeat destruct p. pose (univ_gen_ext_splitR _ _ u0).
+      repeat destruct s. repeat destruct p. pose (univ_gen_ext_splitR _ _ u2).
+      repeat destruct s. repeat destruct p. pose (univ_gen_ext_splitR _ _ u4).
+      repeat destruct s. repeat destruct p. subst. exists (x :: x0 ++ x6 ++ x4 ++ x2 ++ x7).
+      split.
+      { apply univ_gen_ext_cons with (x:=x) in u. pose (univ_gen_ext_combine u1 u6).
+        pose (univ_gen_ext_combine u3 u7). pose (univ_gen_ext_combine u5 u8).
+        pose (univ_gen_ext_combine u u9). assumption. }
+      { assert (E1: x :: x0 ++ x2 ++ x4 ++ x6 ++ x7 = (x :: x0) ++ x2 ++ x4 ++ x6 ++ x7).
+        reflexivity. rewrite E1.
+        assert (E2: x :: x0 ++ x6 ++ x4 ++ x2 ++ x7 = (x :: x0) ++ x6 ++ x4 ++ x2 ++ x7).
+        reflexivity. rewrite E2. apply list_exch_RI. }
+  - intro exch. inversion exch. destruct Δ0.
+    * rewrite app_nil_l in H. rewrite app_nil_l in H1. rewrite app_nil_l. destruct Δ1.
+      { rewrite app_nil_l in H1. destruct Δ2.
+        + rewrite app_nil_l in H1. destruct Δ3.
+          - rewrite app_nil_l in H1. repeat rewrite app_nil_l in H. destruct Δ4.
+            * inversion H1.
+            * inversion H1. simpl. subst. exists l.
+              split. apply univ_gen_ext_extra. assumption. assumption. apply list_exch_R_id.
+          - repeat rewrite app_nil_l in H. repeat rewrite app_nil_l. simpl. simpl in H. simpl in H1.
+            inversion H1. subst. exists l. split. apply univ_gen_ext_extra. assumption. assumption. apply list_exch_R_id.
+        + rewrite app_nil_l. rewrite app_nil_l in H. inversion H1. subst.
+          pose (univ_gen_ext_splitR _ _ gen). repeat destruct s. repeat destruct p0.
+          pose (univ_gen_ext_splitR _ _ u0). repeat destruct s. repeat destruct p0. subst.
+          exists (x2 ++ x0 ++ x3). split.
+          - apply univ_gen_ext_extra with (x:=x) in u. pose (univ_gen_ext_combine u u2).
+            pose (univ_gen_ext_combine u1 u3). assumption. assumption.
+          - pose (list_exch_RI Γ' [] [] x0 x2 x3). repeat rewrite app_nil_l in l. assumption. }
+      { inversion H1. subst. pose (univ_gen_ext_splitR _ _ gen). repeat destruct s. repeat destruct p0.
+        pose (univ_gen_ext_splitR _ _ u0). repeat destruct s. repeat destruct p0. pose (univ_gen_ext_splitR _ _ u2).
+        repeat destruct s. repeat destruct p0. subst. exists (x4 ++ x2 ++ x0 ++ x5).
+        split.
+        - apply univ_gen_ext_extra with (x:=x) in u. pose (univ_gen_ext_combine u u4).
+          pose (univ_gen_ext_combine u1 u5). pose (univ_gen_ext_combine u3 u6). assumption. assumption.
+        - pose (list_exch_RI Γ' [] x0 x2 x4 x5). rewrite app_nil_l in l. assumption. }
+    * inversion H1. subst. pose (univ_gen_ext_splitR _ _ gen).
+      repeat destruct s. repeat destruct p0. pose (univ_gen_ext_splitR _ _ u0).
+      repeat destruct s. repeat destruct p0. pose (univ_gen_ext_splitR _ _ u2).
+      repeat destruct s. repeat destruct p0. pose (univ_gen_ext_splitR _ _ u4).
+      repeat destruct s. repeat destruct p0. subst. exists (x0 ++ x6 ++ x4 ++ x2 ++ x7).
+      split.
+      { apply univ_gen_ext_extra with (x:=x) in u. pose (univ_gen_ext_combine u1 u6).
+        pose (univ_gen_ext_combine u3 u7). pose (univ_gen_ext_combine u5 u8).
+        pose (univ_gen_ext_combine u u9). assumption. assumption. }
+      { apply list_exch_RI. }
+Qed.
+ +
+Lemma nobox_gen_ext_exch_L : forall Δ Δ' l0 l1 l2,
+    (nobox_gen_ext l0 l1) -> (@list_exch_L (l1,Δ) (l2,Δ)) ->
+    existsT2 l3, (nobox_gen_ext l3 l2) * (list_exch_L (l0,Δ') (l3,Δ')).
+Proof.
+intros Δ Δ' l0. induction l0.
++ intros l1 l2 gen. inversion gen.
+  - intro exch. inversion exch. apply app_eq_nil in H1. destruct H1. apply app_eq_nil in H3. destruct H3.
+    apply app_eq_nil in H4. destruct H4. apply app_eq_nil in H5. destruct H5.
+    subst. simpl. exists []. split.
+    * apply univ_gen_ext_nil.
+    * apply list_exch_L_id.
+  - intros exch. exists []. split.
+    * subst. apply all_P_univ_gen_ext_nil. intros. pose (InT_list_exch_L exch).
+      pose (p x0). destruct p0. apply i0 in H0. inversion H0. subst. apply H.
+      assumption. subst. pose (univ_gen_ext_nil_all_P gen). apply f in H0.
+      assumption. assumption.
+    * apply list_exch_L_id.
++ intros l1 l2 gen. induction gen.
+  - intro exch. inversion exch. destruct Γ0.
+    * rewrite app_nil_l in H0. rewrite app_nil_l in H. rewrite app_nil_l. destruct Γ1.
+      { rewrite app_nil_l in H0. destruct Γ2.
+        + rewrite app_nil_l in H0. destruct Γ3.
+          - rewrite app_nil_l in H0. repeat rewrite app_nil_l in H. destruct Γ4.
+            * simpl. exists []. split. apply univ_gen_ext_nil. apply list_exch_L_id.
+            * inversion H0.
+          - inversion H0.
+        + inversion H0. }
+      { inversion H0. }
+    * inversion H0.
+  - intro exch. inversion exch. destruct Γ0.
+    * rewrite app_nil_l in H. rewrite app_nil_l in H0. rewrite app_nil_l. destruct Γ1.
+      { rewrite app_nil_l in H0. destruct Γ2.
+        + rewrite app_nil_l in H0. destruct Γ3.
+          - rewrite app_nil_l in H0. repeat rewrite app_nil_l in H. destruct Γ4.
+            * inversion H0.
+            * inversion H0. simpl. subst. exists (x :: l).
+              split. apply univ_gen_ext_cons. assumption. apply list_exch_L_id.
+          - repeat rewrite app_nil_l in H. repeat rewrite app_nil_l. simpl. simpl in H. simpl in H0.
+            inversion H0. subst. exists (x :: l). split. apply univ_gen_ext_cons. assumption. apply list_exch_L_id.
+        + rewrite app_nil_l. rewrite app_nil_l in H. inversion H0. subst.
+          pose (univ_gen_ext_splitR _ _ gen). repeat destruct s. repeat destruct p.
+          pose (univ_gen_ext_splitR _ _ u0). repeat destruct s. repeat destruct p. subst.
+          exists (x2 ++ x :: x0 ++ x3). split.
+          - apply univ_gen_ext_cons with (x:=x) in u. pose (univ_gen_ext_combine u u2).
+            pose (univ_gen_ext_combine u1 u3). assumption.
+          - pose (list_exch_LI [] [] (x :: x0) x2 x3 Δ'). repeat rewrite app_nil_l in l. assumption. }
+      { inversion H0. subst. pose (univ_gen_ext_splitR _ _ gen). repeat destruct s. repeat destruct p.
+        pose (univ_gen_ext_splitR _ _ u0). repeat destruct s. repeat destruct p. pose (univ_gen_ext_splitR _ _ u2).
+        repeat destruct s. repeat destruct p. subst. exists (x4 ++ x2 ++ (x :: x0) ++ x5).
+        split.
+        - apply univ_gen_ext_cons with (x:=x) in u. pose (univ_gen_ext_combine u u4).
+          pose (univ_gen_ext_combine u1 u5). pose (univ_gen_ext_combine u3 u6). assumption.
+        - pose (list_exch_LI [] (x :: x0) x2 x4 x5 Δ'). rewrite app_nil_l in l. assumption. }
+    * inversion H0. subst. pose (univ_gen_ext_splitR _ _ gen).
+      repeat destruct s. repeat destruct p. pose (univ_gen_ext_splitR _ _ u0).
+      repeat destruct s. repeat destruct p. pose (univ_gen_ext_splitR _ _ u2).
+      repeat destruct s. repeat destruct p. pose (univ_gen_ext_splitR _ _ u4).
+      repeat destruct s. repeat destruct p. subst. exists (x :: x0 ++ x6 ++ x4 ++ x2 ++ x7).
+      split.
+      { apply univ_gen_ext_cons with (x:=x) in u. pose (univ_gen_ext_combine u1 u6).
+        pose (univ_gen_ext_combine u3 u7). pose (univ_gen_ext_combine u5 u8).
+        pose (univ_gen_ext_combine u u9). assumption. }
+      { assert (E1: x :: x0 ++ x2 ++ x4 ++ x6 ++ x7 = (x :: x0) ++ x2 ++ x4 ++ x6 ++ x7).
+        reflexivity. rewrite E1.
+        assert (E2: x :: x0 ++ x6 ++ x4 ++ x2 ++ x7 = (x :: x0) ++ x6 ++ x4 ++ x2 ++ x7).
+        reflexivity. rewrite E2. apply list_exch_LI. }
+  - intro exch. inversion exch. destruct Γ0.
+    * rewrite app_nil_l in H. rewrite app_nil_l in H0. rewrite app_nil_l. destruct Γ1.
+      { rewrite app_nil_l in H0. destruct Γ2.
+        + rewrite app_nil_l in H0. destruct Γ3.
+          - rewrite app_nil_l in H0. repeat rewrite app_nil_l in H. destruct Γ4.
+            * inversion H0.
+            * inversion H0. simpl. subst. exists l.
+              split. apply univ_gen_ext_extra. assumption. assumption. apply list_exch_L_id.
+          - repeat rewrite app_nil_l in H. repeat rewrite app_nil_l. simpl. simpl in H. simpl in H0.
+            inversion H0. subst. exists l. split. apply univ_gen_ext_extra. assumption. assumption. apply list_exch_L_id.
+        + rewrite app_nil_l. rewrite app_nil_l in H. inversion H0. subst.
+          pose (univ_gen_ext_splitR _ _ gen). repeat destruct s. repeat destruct p0.
+          pose (univ_gen_ext_splitR _ _ u0). repeat destruct s. repeat destruct p0. subst.
+          exists (x2 ++ x0 ++ x3). split.
+          - apply univ_gen_ext_extra with (x:=x) in u. pose (univ_gen_ext_combine u u2).
+            pose (univ_gen_ext_combine u1 u3). assumption. assumption.
+          - pose (list_exch_LI [] [] x0 x2 x3 Δ'). repeat rewrite app_nil_l in l. assumption. }
+      { inversion H0. subst. pose (univ_gen_ext_splitR _ _ gen). repeat destruct s. repeat destruct p0.
+        pose (univ_gen_ext_splitR _ _ u0). repeat destruct s. repeat destruct p0. pose (univ_gen_ext_splitR _ _ u2).
+        repeat destruct s. repeat destruct p0. subst. exists (x4 ++ x2 ++ x0 ++ x5).
+        split.
+        - apply univ_gen_ext_extra with (x:=x) in u. pose (univ_gen_ext_combine u u4).
+          pose (univ_gen_ext_combine u1 u5). pose (univ_gen_ext_combine u3 u6). assumption. assumption.
+        - pose (list_exch_LI [] x0 x2 x4 x5 Δ'). rewrite app_nil_l in l. assumption. }
+    * inversion H0. subst. pose (univ_gen_ext_splitR _ _ gen).
+      repeat destruct s. repeat destruct p0. pose (univ_gen_ext_splitR _ _ u0).
+      repeat destruct s. repeat destruct p0. pose (univ_gen_ext_splitR _ _ u2).
+      repeat destruct s. repeat destruct p0. pose (univ_gen_ext_splitR _ _ u4).
+      repeat destruct s. repeat destruct p0. subst. exists (x0 ++ x6 ++ x4 ++ x2 ++ x7).
+      split.
+      { apply univ_gen_ext_extra with (x:=x) in u. pose (univ_gen_ext_combine u1 u6).
+        pose (univ_gen_ext_combine u3 u7). pose (univ_gen_ext_combine u5 u8).
+        pose (univ_gen_ext_combine u u9). assumption. assumption. }
+      { apply list_exch_LI. }
+Qed.
+ +
+(* Interactions between exchange and rules. *)
+ +
+Lemma list_exch_L_IdP_notapplic : forall s se,
+    (@list_exch_L s se) ->
+    ((IdPRule [] s) -> False) ->
+    ((IdPRule [] se) -> False).
+Proof.
+intros s se exch. induction exch. intros RA RAe. apply RA.
+inversion RAe. symmetry in H. apply partition_1_element in H.
+destruct H.
+- destruct s. destruct s. rewrite e.
+  assert (E: (x ++ # P :: x0) ++ Γ1 ++ Γ2 ++ Γ3 ++ Γ4 =
+  x ++ # P :: x0 ++ Γ1 ++ Γ2 ++ Γ3 ++ Γ4).
+  pose (app_assoc x (# P :: x0) (Γ1 ++ Γ2 ++ Γ3 ++ Γ4)). rewrite <- e0.
+  auto. rewrite E. apply IdPRule_I.
+- destruct s.
+  + destruct s. destruct s. rewrite e.
+    assert (E: Γ0 ++ Γ1 ++ Γ2 ++ (x ++ # P :: x0) ++ Γ4 =
+    Γ0 ++ Γ1 ++ Γ2 ++ x ++ # P :: x0 ++ Γ4).
+    pose (app_assoc x (# P :: x0) Γ4).
+    simpl in e0. rewrite <- e0. reflexivity. rewrite E.
+    assert (E1: Γ0 ++ Γ1 ++ Γ2 ++ x ++ # P :: x0 ++ Γ4 =
+    (Γ0 ++ Γ1 ++ Γ2 ++ x) ++ # P :: x0 ++ Γ4).
+    pose (app_assoc (Γ0 ++ Γ1 ++ Γ2) x (# P :: x0 ++ Γ4)).
+    pose (app_assoc (Γ0 ++ Γ1) Γ2 x).
+    pose (app_assoc Γ0 Γ1 Γ2). rewrite <- e2 in e1. rewrite <- e1 in e0.
+    pose (app_assoc Γ0 Γ1 (Γ2 ++ x)). rewrite <- e3 in e0. rewrite <- e0.
+    pose (app_assoc (Γ0 ++ Γ1) Γ2 (x ++ # P :: x0 ++ Γ4)). rewrite <- e2 in e4.
+    rewrite <- e4.
+    pose (app_assoc Γ0 Γ1 (Γ2 ++ x ++ # P :: x0 ++ Γ4)). rewrite e5. reflexivity.
+    rewrite E1. apply IdPRule_I.
+  + destruct s.
+    * destruct s. destruct s. rewrite e.
+      assert (E: Γ0 ++ Γ1 ++ (x ++ # P :: x0) ++ Γ3 ++ Γ4 =
+      (Γ0 ++ Γ1 ++ x) ++ # P :: x0 ++ Γ3 ++ Γ4).
+      pose (app_assoc x (# P :: x0) (Γ3 ++ Γ4)). rewrite <- e0. simpl.
+      pose (app_assoc (Γ0 ++ Γ1) x (# P :: x0 ++ Γ3 ++ Γ4)).
+      pose (app_assoc Γ0 Γ1 x). rewrite <- e2 in e1. rewrite <- e1.
+      pose (app_assoc Γ0 Γ1 (x ++ # P :: x0 ++ Γ3 ++ Γ4)). rewrite <- e3.
+      reflexivity. rewrite E. apply IdPRule_I.
+    * destruct s.
+      { destruct s. destruct s. rewrite e.
+        assert (E: Γ0 ++ (x ++ # P :: x0) ++ Γ2 ++ Γ3 ++ Γ4 =
+        (Γ0 ++ x) ++ # P :: x0 ++ Γ2 ++ Γ3 ++ Γ4).
+        pose (app_assoc x (# P :: x0) (Γ2 ++ Γ3 ++ Γ4)).
+        rewrite <- e0. simpl.
+        pose (app_assoc Γ0 x (# P :: x0 ++ Γ2 ++ Γ3 ++ Γ4)).
+        rewrite <- e1. reflexivity. rewrite E. apply IdPRule_I. }
+      { destruct s. destruct s. rewrite e.
+        assert (E: Γ0 ++ Γ1 ++ Γ2 ++ Γ3 ++ x ++ # P :: x0 =
+        (Γ0 ++ Γ1 ++ Γ2 ++ Γ3 ++ x) ++ # P :: x0).
+        pose (app_assoc (Γ0 ++ Γ1 ++ Γ2 ++ Γ3) x (# P :: x0)).
+        pose (app_assoc (Γ0 ++ Γ1 ++ Γ2) Γ3 x).
+        pose (app_assoc (Γ0 ++ Γ1) Γ2 Γ3).
+        pose (app_assoc Γ0 Γ1 Γ2).
+        rewrite <- e3 in e2. rewrite <- e2 in e1.
+        pose (app_assoc Γ0 Γ1 (Γ2 ++ Γ3)).
+        rewrite <- e4 in e1. rewrite <- e1 in e0.
+        pose (app_assoc (Γ0 ++ Γ1) Γ2 (Γ3 ++ x)).
+        rewrite <- e3 in e5. rewrite <- e5 in e0.
+        pose (app_assoc Γ0 Γ1 (Γ2 ++ Γ3 ++ x)).
+        rewrite <- e6 in e0. rewrite <- e0.
+        pose (app_assoc (Γ0 ++ Γ1 ++ Γ2) Γ3 (x ++ # P :: x0)).
+        pose (app_assoc (Γ0 ++ Γ1) Γ2 Γ3).
+        rewrite <- e3 in e8. rewrite <- e8 in e7.
+        pose (app_assoc Γ0 Γ1 (Γ2 ++ Γ3)). rewrite <- e9 in e7.
+        rewrite <- e7.
+        pose (app_assoc (Γ0 ++ Γ1) Γ2 (Γ3 ++ x ++ # P :: x0)).
+        rewrite <- e3 in e10. rewrite <- e10.
+        pose (app_assoc Γ0 Γ1 (Γ2 ++ Γ3 ++ x ++ # P :: x0)).
+        rewrite <- e11. reflexivity.
+        rewrite E. apply IdPRule_I. }
+Qed.
+ +
+Lemma list_exch_L_IdB_notapplic : forall s se,
+    (@list_exch_L s se) ->
+    ((IdBRule [] s) -> False) ->
+    ((IdBRule [] se) -> False).
+Proof.
+intros s se exch. induction exch. intros RA RAe. apply RA.
+inversion RAe. symmetry in H. apply partition_1_element in H.
+destruct H.
+- destruct s. destruct s. rewrite e.
+  assert (E: (x ++ Box A :: x0) ++ Γ1 ++ Γ2 ++ Γ3 ++ Γ4 =
+  x ++ Box A :: x0 ++ Γ1 ++ Γ2 ++ Γ3 ++ Γ4).
+  pose (app_assoc x (Box A :: x0) (Γ1 ++ Γ2 ++ Γ3 ++ Γ4)). rewrite <- e0.
+  auto. rewrite E. apply IdBRule_I.
+- destruct s.
+  + destruct s. destruct s. rewrite e.
+    assert (E: Γ0 ++ Γ1 ++ Γ2 ++ (x ++ Box A :: x0) ++ Γ4 =
+    Γ0 ++ Γ1 ++ Γ2 ++ x ++ Box A :: x0 ++ Γ4).
+    pose (app_assoc x (Box A :: x0) Γ4).
+    simpl in e0. rewrite <- e0. reflexivity. rewrite E.
+    assert (E1: Γ0 ++ Γ1 ++ Γ2 ++ x ++ Box A :: x0 ++ Γ4 =
+    (Γ0 ++ Γ1 ++ Γ2 ++ x) ++ Box A :: x0 ++ Γ4).
+    pose (app_assoc (Γ0 ++ Γ1 ++ Γ2) x (Box A :: x0 ++ Γ4)).
+    pose (app_assoc (Γ0 ++ Γ1) Γ2 x).
+    pose (app_assoc Γ0 Γ1 Γ2). rewrite <- e2 in e1. rewrite <- e1 in e0.
+    pose (app_assoc Γ0 Γ1 (Γ2 ++ x)). rewrite <- e3 in e0. rewrite <- e0.
+    pose (app_assoc (Γ0 ++ Γ1) Γ2 (x ++ Box A :: x0 ++ Γ4)). rewrite <- e2 in e4.
+    rewrite <- e4.
+    pose (app_assoc Γ0 Γ1 (Γ2 ++ x ++ Box A :: x0 ++ Γ4)). rewrite e5. reflexivity.
+    rewrite E1. apply IdBRule_I.
+  + destruct s.
+    * destruct s. destruct s. rewrite e.
+      assert (E: Γ0 ++ Γ1 ++ (x ++ Box A :: x0) ++ Γ3 ++ Γ4 =
+      (Γ0 ++ Γ1 ++ x) ++ Box A :: x0 ++ Γ3 ++ Γ4).
+      pose (app_assoc x (Box A :: x0) (Γ3 ++ Γ4)). rewrite <- e0. simpl.
+      pose (app_assoc (Γ0 ++ Γ1) x (Box A :: x0 ++ Γ3 ++ Γ4)).
+      pose (app_assoc Γ0 Γ1 x). rewrite <- e2 in e1. rewrite <- e1.
+      pose (app_assoc Γ0 Γ1 (x ++ Box A :: x0 ++ Γ3 ++ Γ4)). rewrite <- e3.
+      reflexivity. rewrite E. apply IdBRule_I.
+    * destruct s.
+      { destruct s. destruct s. rewrite e.
+        assert (E: Γ0 ++ (x ++ Box A :: x0) ++ Γ2 ++ Γ3 ++ Γ4 =
+        (Γ0 ++ x) ++ Box A :: x0 ++ Γ2 ++ Γ3 ++ Γ4).
+        pose (app_assoc x (Box A :: x0) (Γ2 ++ Γ3 ++ Γ4)).
+        rewrite <- e0. simpl.
+        pose (app_assoc Γ0 x (Box A :: x0 ++ Γ2 ++ Γ3 ++ Γ4)).
+        rewrite <- e1. reflexivity. rewrite E. apply IdBRule_I. }
+      { destruct s. destruct s. rewrite e.
+        assert (E: Γ0 ++ Γ1 ++ Γ2 ++ Γ3 ++ x ++ Box A :: x0 =
+        (Γ0 ++ Γ1 ++ Γ2 ++ Γ3 ++ x) ++ Box A :: x0).
+        pose (app_assoc (Γ0 ++ Γ1 ++ Γ2 ++ Γ3) x (Box A :: x0)).
+        pose (app_assoc (Γ0 ++ Γ1 ++ Γ2) Γ3 x).
+        pose (app_assoc (Γ0 ++ Γ1) Γ2 Γ3).
+        pose (app_assoc Γ0 Γ1 Γ2).
+        rewrite <- e3 in e2. rewrite <- e2 in e1.
+        pose (app_assoc Γ0 Γ1 (Γ2 ++ Γ3)).
+        rewrite <- e4 in e1. rewrite <- e1 in e0.
+        pose (app_assoc (Γ0 ++ Γ1) Γ2 (Γ3 ++ x)).
+        rewrite <- e3 in e5. rewrite <- e5 in e0.
+        pose (app_assoc Γ0 Γ1 (Γ2 ++ Γ3 ++ x)).
+        rewrite <- e6 in e0. rewrite <- e0.
+        pose (app_assoc (Γ0 ++ Γ1 ++ Γ2) Γ3 (x ++ Box A :: x0)).
+        pose (app_assoc (Γ0 ++ Γ1) Γ2 Γ3).
+        rewrite <- e3 in e8. rewrite <- e8 in e7.
+        pose (app_assoc Γ0 Γ1 (Γ2 ++ Γ3)). rewrite <- e9 in e7.
+        rewrite <- e7.
+        pose (app_assoc (Γ0 ++ Γ1) Γ2 (Γ3 ++ x ++ Box A :: x0)).
+        rewrite <- e3 in e10. rewrite <- e10.
+        pose (app_assoc Γ0 Γ1 (Γ2 ++ Γ3 ++ x ++ Box A :: x0)).
+        rewrite <- e11. reflexivity.
+        rewrite E. apply IdBRule_I. }
+Qed.
+ +
+Lemma list_exch_L_BotL_notapplic : forall s se,
+    (@list_exch_L s se) ->
+    ((BotLRule [] s) -> False) ->
+    ((BotLRule [] se) -> False).
+Proof.
+intros s se exch. induction exch. intros RA RAe. apply RA.
+inversion RAe. symmetry in H. apply partition_1_element in H.
+destruct H.
+- destruct s. destruct s. rewrite e.
+  assert (E: (x ++ :: x0) ++ Γ1 ++ Γ2 ++ Γ3 ++ Γ4 =
+  x ++ :: x0 ++ Γ1 ++ Γ2 ++ Γ3 ++ Γ4).
+  pose (app_assoc x ( :: x0) (Γ1 ++ Γ2 ++ Γ3 ++ Γ4)). rewrite <- e0.
+  auto. rewrite E. apply BotLRule_I.
+- destruct s.
+  + destruct s. destruct s. rewrite e.
+    assert (E: Γ0 ++ Γ1 ++ Γ2 ++ (x ++ :: x0) ++ Γ4 =
+    Γ0 ++ Γ1 ++ Γ2 ++ x ++ :: x0 ++ Γ4).
+    pose (app_assoc x ( :: x0) Γ4).
+    simpl in e0. rewrite <- e0. reflexivity. rewrite E.
+    assert (E1: Γ0 ++ Γ1 ++ Γ2 ++ x ++ :: x0 ++ Γ4 =
+    (Γ0 ++ Γ1 ++ Γ2 ++ x) ++ :: x0 ++ Γ4).
+    pose (app_assoc (Γ0 ++ Γ1 ++ Γ2) x ( :: x0 ++ Γ4)).
+    pose (app_assoc (Γ0 ++ Γ1) Γ2 x).
+    pose (app_assoc Γ0 Γ1 Γ2). rewrite <- e2 in e1. rewrite <- e1 in e0.
+    pose (app_assoc Γ0 Γ1 (Γ2 ++ x)). rewrite <- e3 in e0. rewrite <- e0.
+    pose (app_assoc (Γ0 ++ Γ1) Γ2 (x ++ :: x0 ++ Γ4)). rewrite <- e2 in e4.
+    rewrite <- e4.
+    pose (app_assoc Γ0 Γ1 (Γ2 ++ x ++ :: x0 ++ Γ4)). rewrite e5. reflexivity.
+    rewrite E1. apply BotLRule_I.
+  + destruct s.
+    * destruct s. destruct s. rewrite e.
+      assert (E: Γ0 ++ Γ1 ++ (x ++ :: x0) ++ Γ3 ++ Γ4 =
+      (Γ0 ++ Γ1 ++ x) ++ :: x0 ++ Γ3 ++ Γ4).
+      pose (app_assoc x ( :: x0) (Γ3 ++ Γ4)). rewrite <- e0. simpl.
+      pose (app_assoc (Γ0 ++ Γ1) x ( :: x0 ++ Γ3 ++ Γ4)).
+      pose (app_assoc Γ0 Γ1 x). rewrite <- e2 in e1. rewrite <- e1.
+      pose (app_assoc Γ0 Γ1 (x ++ :: x0 ++ Γ3 ++ Γ4)). rewrite <- e3.
+      reflexivity. rewrite E. apply BotLRule_I.
+    * destruct s.
+      { destruct s. destruct s. rewrite e.
+        assert (E: Γ0 ++ (x ++ :: x0) ++ Γ2 ++ Γ3 ++ Γ4 =
+        (Γ0 ++ x) ++ :: x0 ++ Γ2 ++ Γ3 ++ Γ4).
+        pose (app_assoc x ( :: x0) (Γ2 ++ Γ3 ++ Γ4)).
+        rewrite <- e0. simpl.
+        pose (app_assoc Γ0 x ( :: x0 ++ Γ2 ++ Γ3 ++ Γ4)).
+        rewrite <- e1. reflexivity. rewrite E. apply BotLRule_I. }
+      { destruct s. destruct s. rewrite e.
+        assert (E: Γ0 ++ Γ1 ++ Γ2 ++ Γ3 ++ x ++ :: x0 =
+        (Γ0 ++ Γ1 ++ Γ2 ++ Γ3 ++ x) ++ :: x0).
+        pose (app_assoc (Γ0 ++ Γ1 ++ Γ2 ++ Γ3) x ( :: x0)).
+        pose (app_assoc (Γ0 ++ Γ1 ++ Γ2) Γ3 x).
+        pose (app_assoc (Γ0 ++ Γ1) Γ2 Γ3).
+        pose (app_assoc Γ0 Γ1 Γ2).
+        rewrite <- e3 in e2. rewrite <- e2 in e1.
+        pose (app_assoc Γ0 Γ1 (Γ2 ++ Γ3)).
+        rewrite <- e4 in e1. rewrite <- e1 in e0.
+        pose (app_assoc (Γ0 ++ Γ1) Γ2 (Γ3 ++ x)).
+        rewrite <- e3 in e5. rewrite <- e5 in e0.
+        pose (app_assoc Γ0 Γ1 (Γ2 ++ Γ3 ++ x)).
+        rewrite <- e6 in e0. rewrite <- e0.
+        pose (app_assoc (Γ0 ++ Γ1 ++ Γ2) Γ3 (x ++ :: x0)).
+        pose (app_assoc (Γ0 ++ Γ1) Γ2 Γ3).
+        rewrite <- e3 in e8. rewrite <- e8 in e7.
+        pose (app_assoc Γ0 Γ1 (Γ2 ++ Γ3)). rewrite <- e9 in e7.
+        rewrite <- e7.
+        pose (app_assoc (Γ0 ++ Γ1) Γ2 (Γ3 ++ x ++ :: x0)).
+        rewrite <- e3 in e10. rewrite <- e10.
+        pose (app_assoc Γ0 Γ1 (Γ2 ++ Γ3 ++ x ++ :: x0)).
+        rewrite <- e11. reflexivity.
+        rewrite E. apply BotLRule_I. }
+Qed.
+ +
+Lemma list_exch_R_IdP_notapplic : forall s se,
+    (@list_exch_R s se) ->
+    ((IdPRule [] s) -> False) ->
+    ((IdPRule [] se) -> False).
+Proof.
+intros s se exch. induction exch. intros RA RAe. apply RA.
+inversion RAe. symmetry in H1. apply partition_1_element in H1.
+destruct H1.
+- destruct s. destruct s. rewrite e.
+  assert (E: (x ++ # P :: x0) ++ Δ1 ++ Δ2 ++ Δ3 ++ Δ4 =
+  x ++ # P :: x0 ++ Δ1 ++ Δ2 ++ Δ3 ++ Δ4).
+  pose (app_assoc x (# P :: x0) (Δ1 ++ Δ2 ++ Δ3 ++ Δ4)). rewrite <- e0.
+  auto. rewrite E. apply IdPRule_I.
+- destruct s.
+  + destruct s. destruct s. rewrite e.
+    assert (E: Δ0 ++ Δ1 ++ Δ2 ++ (x ++ # P :: x0) ++ Δ4 =
+    Δ0 ++ Δ1 ++ Δ2 ++ x ++ # P :: x0 ++ Δ4).
+    pose (app_assoc x (# P :: x0) Δ4).
+    simpl in e0. rewrite <- e0. reflexivity. rewrite E.
+    assert (E1: Δ0 ++ Δ1 ++ Δ2 ++ x ++ # P :: x0 ++ Δ4 =
+    (Δ0 ++ Δ1 ++ Δ2 ++ x) ++ # P :: x0 ++ Δ4).
+    pose (app_assoc (Δ0 ++ Δ1 ++ Δ2) x (# P :: x0 ++ Δ4)).
+    pose (app_assoc (Δ0 ++ Δ1) Δ2 x).
+    pose (app_assoc Δ0 Δ1 Δ2). rewrite <- e2 in e1. rewrite <- e1 in e0.
+    pose (app_assoc Δ0 Δ1 (Δ2 ++ x)). rewrite <- e3 in e0. rewrite <- e0.
+    pose (app_assoc (Δ0 ++ Δ1) Δ2 (x ++ # P :: x0 ++ Δ4)). rewrite <- e2 in e4.
+    rewrite <- e4.
+    pose (app_assoc Δ0 Δ1 (Δ2 ++ x ++ # P :: x0 ++ Δ4)). rewrite e5. reflexivity.
+    rewrite E1. apply IdPRule_I.
+  + destruct s.
+    * destruct s. destruct s. rewrite e.
+      assert (E: Δ0 ++ Δ1 ++ (x ++ # P :: x0) ++ Δ3 ++ Δ4 =
+      (Δ0 ++ Δ1 ++ x) ++ # P :: x0 ++ Δ3 ++ Δ4).
+      pose (app_assoc x (# P :: x0) (Δ3 ++ Δ4)). rewrite <- e0. simpl.
+      pose (app_assoc (Δ0 ++ Δ1) x (# P :: x0 ++ Δ3 ++ Δ4)).
+      pose (app_assoc Δ0 Δ1 x). rewrite <- e2 in e1. rewrite <- e1.
+      pose (app_assoc Δ0 Δ1 (x ++ # P :: x0 ++ Δ3 ++ Δ4)). rewrite <- e3.
+      reflexivity. rewrite E. apply IdPRule_I.
+    * destruct s.
+      { destruct s. destruct s. rewrite e.
+        assert (E: Δ0 ++ (x ++ # P :: x0) ++ Δ2 ++ Δ3 ++ Δ4 =
+        (Δ0 ++ x) ++ # P :: x0 ++ Δ2 ++ Δ3 ++ Δ4).
+        pose (app_assoc x (# P :: x0) (Δ2 ++ Δ3 ++ Δ4)).
+        rewrite <- e0. simpl.
+        pose (app_assoc Δ0 x (# P :: x0 ++ Δ2 ++ Δ3 ++ Δ4)).
+        rewrite <- e1. reflexivity. rewrite E. apply IdPRule_I. }
+      { destruct s. destruct s. rewrite e.
+        assert (E: Δ0 ++ Δ1 ++ Δ2 ++ Δ3 ++ x ++ # P :: x0 =
+        (Δ0 ++ Δ1 ++ Δ2 ++ Δ3 ++ x) ++ # P :: x0).
+        pose (app_assoc (Δ0 ++ Δ1 ++ Δ2 ++ Δ3) x (# P :: x0)).
+        pose (app_assoc (Δ0 ++ Δ1 ++ Δ2) Δ3 x).
+        pose (app_assoc (Δ0 ++ Δ1) Δ2 Δ3).
+        pose (app_assoc Δ0 Δ1 Δ2).
+        rewrite <- e3 in e2. rewrite <- e2 in e1.
+        pose (app_assoc Δ0 Δ1 (Δ2 ++ Δ3)).
+        rewrite <- e4 in e1. rewrite <- e1 in e0.
+        pose (app_assoc (Δ0 ++ Δ1) Δ2 (Δ3 ++ x)).
+        rewrite <- e3 in e5. rewrite <- e5 in e0.
+        pose (app_assoc Δ0 Δ1 (Δ2 ++ Δ3 ++ x)).
+        rewrite <- e6 in e0. rewrite <- e0.
+        pose (app_assoc (Δ0 ++ Δ1 ++ Δ2) Δ3 (x ++ # P :: x0)).
+        pose (app_assoc (Δ0 ++ Δ1) Δ2 Δ3).
+        rewrite <- e3 in e8. rewrite <- e8 in e7.
+        pose (app_assoc Δ0 Δ1 (Δ2 ++ Δ3)). rewrite <- e9 in e7.
+        rewrite <- e7.
+        pose (app_assoc (Δ0 ++ Δ1) Δ2 (Δ3 ++ x ++ # P :: x0)).
+        rewrite <- e3 in e10. rewrite <- e10.
+        pose (app_assoc Δ0 Δ1 (Δ2 ++ Δ3 ++ x ++ # P :: x0)).
+        rewrite <- e11. reflexivity.
+        rewrite E. apply IdPRule_I. }
+Qed.
+ +
+Lemma list_exch_R_IdB_notapplic : forall s se,
+    (@list_exch_R s se) ->
+    ((IdBRule [] s) -> False) ->
+    ((IdBRule [] se) -> False).
+Proof.
+intros s se exch. induction exch. intros RA RAe. apply RA.
+inversion RAe. symmetry in H1. apply partition_1_element in H1.
+destruct H1.
+- destruct s. destruct s. rewrite e.
+  assert (E: (x ++ Box A :: x0) ++ Δ1 ++ Δ2 ++ Δ3 ++ Δ4 =
+  x ++ Box A :: x0 ++ Δ1 ++ Δ2 ++ Δ3 ++ Δ4).
+  pose (app_assoc x (Box A :: x0) (Δ1 ++ Δ2 ++ Δ3 ++ Δ4)). rewrite <- e0.
+  auto. rewrite E. apply IdBRule_I.
+- destruct s.
+  + destruct s. destruct s. rewrite e.
+    assert (E: Δ0 ++ Δ1 ++ Δ2 ++ (x ++ Box A :: x0) ++ Δ4 =
+    Δ0 ++ Δ1 ++ Δ2 ++ x ++ Box A :: x0 ++ Δ4).
+    pose (app_assoc x (Box A :: x0) Δ4).
+    simpl in e0. rewrite <- e0. reflexivity. rewrite E.
+    assert (E1: Δ0 ++ Δ1 ++ Δ2 ++ x ++ Box A :: x0 ++ Δ4 =
+    (Δ0 ++ Δ1 ++ Δ2 ++ x) ++ Box A :: x0 ++ Δ4).
+    pose (app_assoc (Δ0 ++ Δ1 ++ Δ2) x (Box A :: x0 ++ Δ4)).
+    pose (app_assoc (Δ0 ++ Δ1) Δ2 x).
+    pose (app_assoc Δ0 Δ1 Δ2). rewrite <- e2 in e1. rewrite <- e1 in e0.
+    pose (app_assoc Δ0 Δ1 (Δ2 ++ x)). rewrite <- e3 in e0. rewrite <- e0.
+    pose (app_assoc (Δ0 ++ Δ1) Δ2 (x ++ Box A :: x0 ++ Δ4)). rewrite <- e2 in e4.
+    rewrite <- e4.
+    pose (app_assoc Δ0 Δ1 (Δ2 ++ x ++ Box A :: x0 ++ Δ4)). rewrite e5. reflexivity.
+    rewrite E1. apply IdBRule_I.
+  + destruct s.
+    * destruct s. destruct s. rewrite e.
+      assert (E: Δ0 ++ Δ1 ++ (x ++ Box A :: x0) ++ Δ3 ++ Δ4 =
+      (Δ0 ++ Δ1 ++ x) ++ Box A :: x0 ++ Δ3 ++ Δ4).
+      pose (app_assoc x (Box A :: x0) (Δ3 ++ Δ4)). rewrite <- e0. simpl.
+      pose (app_assoc (Δ0 ++ Δ1) x (Box A :: x0 ++ Δ3 ++ Δ4)).
+      pose (app_assoc Δ0 Δ1 x). rewrite <- e2 in e1. rewrite <- e1.
+      pose (app_assoc Δ0 Δ1 (x ++ Box A :: x0 ++ Δ3 ++ Δ4)). rewrite <- e3.
+      reflexivity. rewrite E. apply IdBRule_I.
+    * destruct s.
+      { destruct s. destruct s. rewrite e.
+        assert (E: Δ0 ++ (x ++ Box A :: x0) ++ Δ2 ++ Δ3 ++ Δ4 =
+        (Δ0 ++ x) ++ Box A :: x0 ++ Δ2 ++ Δ3 ++ Δ4).
+        pose (app_assoc x (Box A :: x0) (Δ2 ++ Δ3 ++ Δ4)).
+        rewrite <- e0. simpl.
+        pose (app_assoc Δ0 x (Box A :: x0 ++ Δ2 ++ Δ3 ++ Δ4)).
+        rewrite <- e1. reflexivity. rewrite E. apply IdBRule_I. }
+      { destruct s. destruct s. rewrite e.
+        assert (E: Δ0 ++ Δ1 ++ Δ2 ++ Δ3 ++ x ++ Box A :: x0 =
+        (Δ0 ++ Δ1 ++ Δ2 ++ Δ3 ++ x) ++ Box A :: x0).
+        pose (app_assoc (Δ0 ++ Δ1 ++ Δ2 ++ Δ3) x (Box A :: x0)).
+        pose (app_assoc (Δ0 ++ Δ1 ++ Δ2) Δ3 x).
+        pose (app_assoc (Δ0 ++ Δ1) Δ2 Δ3).
+        pose (app_assoc Δ0 Δ1 Δ2).
+        rewrite <- e3 in e2. rewrite <- e2 in e1.
+        pose (app_assoc Δ0 Δ1 (Δ2 ++ Δ3)).
+        rewrite <- e4 in e1. rewrite <- e1 in e0.
+        pose (app_assoc (Δ0 ++ Δ1) Δ2 (Δ3 ++ x)).
+        rewrite <- e3 in e5. rewrite <- e5 in e0.
+        pose (app_assoc Δ0 Δ1 (Δ2 ++ Δ3 ++ x)).
+        rewrite <- e6 in e0. rewrite <- e0.
+        pose (app_assoc (Δ0 ++ Δ1 ++ Δ2) Δ3 (x ++ Box A :: x0)).
+        pose (app_assoc (Δ0 ++ Δ1) Δ2 Δ3).
+        rewrite <- e3 in e8. rewrite <- e8 in e7.
+        pose (app_assoc Δ0 Δ1 (Δ2 ++ Δ3)). rewrite <- e9 in e7.
+        rewrite <- e7.
+        pose (app_assoc (Δ0 ++ Δ1) Δ2 (Δ3 ++ x ++ Box A :: x0)).
+        rewrite <- e3 in e10. rewrite <- e10.
+        pose (app_assoc Δ0 Δ1 (Δ2 ++ Δ3 ++ x ++ Box A :: x0)).
+        rewrite <- e11. reflexivity.
+        rewrite E. apply IdBRule_I. }
+Qed.
+ +
+Lemma list_exch_R_BotL_notapplic : forall s se,
+    (@list_exch_R s se) ->
+    ((BotLRule [] s) -> False) ->
+    ((BotLRule [] se) -> False).
+Proof.
+intros s se exch RA RAe. apply RA.
+inversion RAe. destruct s.
+apply list_exch_R_same_L with (Γ:=l) (Γe:=Γ0 ++ :: Γ1) (Δ:=l0) (Δe:=Δ) in exch.
+subst. apply BotLRule_I. reflexivity. symmetry. assumption.
+Qed.
+ +
+(* The following lemmas make sure that if a rule is applied on a sequent s with
+premises ps, then the same rule is applicable on a sequent se which is an exchanged
+version of s, with some premises pse that are such that they are exchanged versions
+of ps. *)

+ +
+Lemma ImpR_app_list_exchL : forall s se ps,
+  (@list_exch_L s se) ->
+  (ImpRRule [ps] s) ->
+  (existsT2 pse,
+    (ImpRRule [pse] se) *
+    (@list_exch_L ps pse)).
+Proof.
+intros s se ps exch. intro RA. inversion RA. inversion exch. subst.
+inversion H. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
+- exists (Γ2 ++ A :: Γ5 ++ Γ4 ++ Γ3 ++ Γ6, Δ0 ++ B :: Δ1). split.
+  apply ImpRRule_I. assert (Γ2 ++ A :: Γ3 ++ Γ4 ++ Γ5 ++ Γ6 = (Γ2 ++ [A]) ++ Γ3 ++ Γ4 ++ Γ5 ++ Γ6).
+  rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+  assert (Γ2 ++ A :: Γ5 ++ Γ4 ++ Γ3 ++ Γ6 = (Γ2 ++ [A]) ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6).
+  rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+- apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+  + exists ((Γ2 ++ Γ5) ++ A :: Γ4 ++ Γ3 ++ Γ6, Δ0 ++ B :: Δ1). split.
+    assert (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6 = (Γ2 ++ Γ5) ++ Γ4 ++ Γ3 ++ Γ6). rewrite app_assoc.
+    reflexivity. rewrite H0. clear H0. apply ImpRRule_I. repeat rewrite <- app_assoc.
+    assert (Γ2 ++ Γ3 ++ A :: Γ4 ++ Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (A :: Γ4) ++ Γ5 ++ Γ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ Γ5 ++ A :: Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ Γ5 ++ (A :: Γ4) ++ Γ3 ++ Γ6).
+    reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+  + apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+    * exists ((Γ2 ++ Γ5 ++ Γ4) ++ A :: Γ3 ++ Γ6, Δ0 ++ B :: Δ1). split.
+      assert (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6 = (Γ2 ++ Γ5 ++ Γ4) ++ Γ3 ++ Γ6). repeat rewrite app_assoc.
+      reflexivity. rewrite H0. clear H0. apply ImpRRule_I. repeat rewrite <- app_assoc.
+      assert (Γ2 ++ Γ3 ++ Γ4 ++ A :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (Γ4 ++ [A]) ++ Γ5 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ Γ5 ++ Γ4 ++ A :: Γ3 ++ Γ6 = Γ2 ++ Γ5 ++ (Γ4 ++ [A]) ++ Γ3 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+    * apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+      { repeat rewrite <- app_assoc. exists (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ A :: Γ6, Δ0 ++ B :: Δ1).
+        split. repeat rewrite app_assoc. apply ImpRRule_I. apply list_exch_LI. }
+      { repeat rewrite <- app_assoc. exists (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ x0 ++ A :: Γ1, Δ0 ++ B :: Δ1).
+        split. repeat rewrite app_assoc. apply ImpRRule_I. apply list_exch_LI. }
+      { repeat rewrite <- app_assoc. exists (Γ2 ++ (x ++ A :: x0) ++ Γ4 ++ Γ3 ++ Γ6, Δ0 ++ B :: Δ1).
+        split. assert (Γ2 ++ (x ++ A :: x0) ++ Γ4 ++ Γ3 ++ Γ6 = (Γ2 ++ x) ++ A :: x0 ++ Γ4 ++ Γ3 ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ x ++ x0 ++ Γ4 ++ Γ3 ++ Γ6 = (Γ2 ++ x) ++ x0 ++ Γ4 ++ Γ3 ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        apply ImpRRule_I.
+        assert (Γ2 ++ Γ3 ++ Γ4 ++ x ++ A :: x0 ++ Γ6 = Γ2 ++ Γ3 ++ Γ4 ++ (x ++ A :: x0) ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply list_exch_LI. }
+    * repeat rewrite <- app_assoc. exists (Γ2 ++ Γ5 ++ (x0 ++ A :: x) ++ Γ3 ++ Γ6, Δ0 ++ B :: Δ1).
+      split. assert (Γ2 ++ Γ5 ++ (x0 ++ A :: x) ++ Γ3 ++ Γ6 = (Γ2 ++ Γ5 ++ x0) ++ A :: x ++ Γ3 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ Γ5 ++ x0 ++ x ++ Γ3 ++ Γ6 = (Γ2 ++ Γ5 ++ x0) ++ x ++ Γ3 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      apply ImpRRule_I.
+      assert (Γ2 ++ Γ3 ++ x0 ++ A :: x ++ Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (x0 ++ A :: x) ++ Γ5 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply list_exch_LI.
+  + repeat rewrite <- app_assoc. exists (Γ2 ++ Γ5 ++ Γ4 ++ (x ++ A :: x0) ++ Γ6, Δ0 ++ B :: Δ1).
+    split. assert (Γ2 ++ Γ5 ++ Γ4 ++ (x ++ A :: x0) ++ Γ6 = (Γ2 ++ Γ5 ++ Γ4 ++ x) ++ A :: x0 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ Γ5 ++ Γ4 ++ x ++ x0 ++ Γ6 = (Γ2 ++ Γ5 ++ Γ4 ++ x) ++ x0 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    apply ImpRRule_I.
+    assert (Γ2 ++ x ++ A :: x0 ++ Γ4 ++ Γ5 ++ Γ6 = Γ2 ++ (x ++ A :: x0) ++ Γ4 ++ Γ5 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply list_exch_LI.
+- repeat rewrite <- app_assoc. exists (Γ0 ++ A :: x ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6, Δ0 ++ B :: Δ1).
+  split. apply ImpRRule_I.
+  assert (Γ0 ++ A :: x ++ Γ3 ++ Γ4 ++ Γ5 ++ Γ6 = (Γ0 ++ A :: x) ++ Γ3 ++ Γ4 ++ Γ5 ++ Γ6).
+  repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+  assert (Γ0 ++ A :: x ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6 = (Γ0 ++ A :: x) ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6).
+  repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+Qed.
+ +
+Lemma ImpL_app_list_exchL : forall s se ps1 ps2,
+  (@list_exch_L s se) ->
+  (ImpLRule [ps1;ps2] s) ->
+  (existsT2 pse1 pse2,
+    (ImpLRule [pse1;pse2] se) *
+    (@list_exch_L ps1 pse1) *
+    (@list_exch_L ps2 pse2)).
+Proof.
+intros s se ps1 ps2 exch. intro RA. inversion RA. inversion exch. subst.
+inversion H. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
+- destruct Γ3 ; destruct Γ4 ; destruct Γ5 ; simpl ; simpl in e0 ; simpl in exch ; subst ; try inversion e0 ; subst.
+  + exists (Γ2 ++ Γ1, Δ0 ++ A :: Δ1). exists (Γ2 ++ B :: Γ1, Δ0 ++ Δ1). split. split ; try assumption.
+    apply list_exch_L_id. apply list_exch_L_id.
+  + exists (Γ2 ++ Γ5 ++ Γ6, Δ0 ++ A :: Δ1). exists (Γ2 ++ B :: Γ5 ++ Γ6, Δ0 ++ Δ1). split. split ; try assumption.
+    apply list_exch_L_id. apply list_exch_L_id.
+  + exists (Γ2 ++ Γ4 ++ Γ6, Δ0 ++ A :: Δ1). exists (Γ2 ++ B :: Γ4 ++ Γ6, Δ0 ++ Δ1). split. split ; try assumption.
+    apply list_exch_L_id. apply list_exch_L_id.
+  + exists (Γ2 ++ (m0 :: Γ5) ++ Γ4 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ2 ++ (m0 :: Γ5) ++ B :: Γ4 ++ Γ6, Δ0 ++ Δ1). split. split.
+    assert (Γ2 ++ (m0 :: Γ5) ++ B :: Γ4 ++ Γ6 = (Γ2 ++ m0 :: Γ5) ++ B :: Γ4 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ m0 :: Γ5 ++ A --> B :: Γ4 ++ Γ6 = (Γ2 ++ m0 :: Γ5) ++ A --> B :: Γ4 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ (m0 :: Γ5) ++ Γ4 ++ Γ6 = (Γ2 ++ m0 :: Γ5) ++ Γ4 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    apply ImpLRule_I.
+    assert (Γ2 ++ Γ4 ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ [] ++ Γ4 ++ (m0 :: Γ5) ++ Γ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ (m0 :: Γ5) ++ Γ4 ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ Γ4 ++ [] ++ Γ6).
+    reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ2 ++ B :: Γ4 ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ [] ++ (B :: Γ4) ++ (m0 :: Γ5) ++ Γ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ (m0 :: Γ5) ++ B :: Γ4 ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ (B :: Γ4) ++ [] ++ Γ6).
+    reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+  + exists (Γ2 ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1). exists (Γ2 ++ B :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split ; try assumption.
+    apply list_exch_L_id. apply list_exch_L_id.
+  + exists (Γ2 ++ (m0 :: Γ5) ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ2 ++ (m0 :: Γ5) ++ B :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+    assert (Γ2 ++ m0 :: Γ5 ++ A --> B :: Γ3 ++ Γ6 = (Γ2 ++ m0 :: Γ5) ++ A --> B :: Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ (m0 :: Γ5) ++ B :: Γ3 ++ Γ6 = (Γ2 ++ m0 :: Γ5) ++ B :: Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ (m0 :: Γ5) ++ Γ3 ++ Γ6 = (Γ2 ++ m0 :: Γ5) ++ Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    apply ImpLRule_I.
+    assert (Γ2 ++ Γ3 ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ [] ++ (m0 :: Γ5) ++ Γ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ (m0 :: Γ5) ++ Γ3 ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ [] ++ Γ3 ++ Γ6).
+    reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ2 ++ B :: Γ3 ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ (B :: Γ3) ++ [] ++ (m0 :: Γ5) ++ Γ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ (m0 :: Γ5) ++ B :: Γ3 ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ [] ++ (B :: Γ3) ++ Γ6).
+    reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+  + exists (Γ2 ++ m0 :: Γ4 ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ2 ++ m0 :: Γ4 ++ B :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+    assert (Γ2 ++ m0 :: Γ4 ++ A --> B :: Γ3 ++ Γ6 = (Γ2 ++ m0 :: Γ4) ++ A --> B :: Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ m0 :: Γ4 ++ B :: Γ3 ++ Γ6 = (Γ2 ++ m0 :: Γ4) ++ B :: Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ m0 :: Γ4 ++ Γ3 ++ Γ6 = (Γ2 ++ m0 :: Γ4) ++ Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+    assert (Γ2 ++ Γ3 ++ m0 :: Γ4 ++ Γ6 = Γ2 ++ Γ3 ++ [] ++ (m0 :: Γ4) ++ Γ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ m0 :: Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (m0 :: Γ4) ++ [] ++ Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ2 ++ B :: Γ3 ++ m0 :: Γ4 ++ Γ6 = Γ2 ++ (B :: Γ3) ++ [] ++ (m0 :: Γ4) ++ Γ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ m0 :: Γ4 ++ B :: Γ3 ++ Γ6 = Γ2 ++ (m0 :: Γ4) ++ [] ++ (B :: Γ3) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+  + exists (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ B :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+    assert (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ A --> B :: Γ3 ++ Γ6 = (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4) ++ A --> B :: Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ B :: Γ3 ++ Γ6 = (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4) ++ B :: Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ Γ3 ++ Γ6 = (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4) ++ Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    apply ImpLRule_I.
+    assert (Γ2 ++ Γ3 ++ m0 :: Γ4 ++ m1 :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (m0 :: Γ4) ++ (m1 :: Γ5) ++ Γ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (m1 :: Γ5) ++ (m0 :: Γ4) ++ Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ2 ++ B :: Γ3 ++ m0 :: Γ4 ++ m1 :: Γ5 ++ Γ6 = Γ2 ++ (B :: Γ3) ++ (m0 :: Γ4) ++ (m1 :: Γ5) ++ Γ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ B :: Γ3 ++ Γ6 = Γ2 ++ (m1 :: Γ5) ++ (m0 :: Γ4) ++ (B :: Γ3) ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+- apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+  + destruct Γ4 ; destruct Γ5 ; simpl ; simpl in e0 ; simpl in exch ; subst ; try inversion e0 ; subst.
+    * rewrite app_assoc. exists ((Γ2 ++ Γ3) ++ Γ1, Δ0 ++ A :: Δ1).
+      exists ((Γ2 ++ Γ3) ++ B :: Γ1, Δ0 ++ Δ1). split. split ; try assumption. apply list_exch_L_id.
+      apply list_exch_L_id.
+    * exists (Γ2 ++ Γ5 ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+      exists (Γ2 ++ B :: Γ5 ++ Γ3 ++ Γ6, Δ0 ++ Δ1). split. split. apply ImpLRule_I.
+      assert ((Γ2 ++ Γ3) ++ Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ [] ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ Γ5 ++ Γ3 ++ Γ6 = Γ2 ++ Γ5 ++ [] ++ Γ3 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+      assert ((Γ2 ++ Γ3) ++ B :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ [] ++ (B :: Γ5) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ B :: Γ5 ++ Γ3 ++ Γ6 = Γ2 ++ (B :: Γ5) ++ [] ++ Γ3 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+    * exists (Γ2 ++ Γ4 ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+      exists (Γ2 ++ B :: Γ4 ++ Γ3 ++ Γ6, Δ0 ++ Δ1). split. split. apply ImpLRule_I.
+      assert ((Γ2 ++ Γ3) ++ Γ4 ++ Γ6 = Γ2 ++ Γ3 ++ [] ++ Γ4 ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ Γ4 ++ [] ++ Γ3 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+      assert ((Γ2 ++ Γ3) ++ B :: Γ4 ++ Γ6 = Γ2 ++ Γ3 ++ [] ++ (B :: Γ4) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ B :: Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (B :: Γ4) ++ [] ++ Γ3 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+    * exists ((Γ2 ++ m0 :: Γ5) ++ Γ4 ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+      exists ((Γ2 ++ m0 :: Γ5) ++ B :: Γ4 ++ Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+      assert (Γ2 ++ m0 :: Γ5 ++ A --> B :: Γ4 ++ Γ3 ++ Γ6 = (Γ2 ++ m0 :: Γ5) ++ A --> B :: Γ4 ++ Γ3 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+      assert ((Γ2 ++ Γ3) ++ Γ4 ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ Γ4 ++ (m0 :: Γ5) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Γ2 ++ m0 :: Γ5) ++ Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ Γ4 ++ Γ3 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+      assert ((Γ2 ++ Γ3) ++ B :: Γ4 ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (B :: Γ4) ++ (m0 :: Γ5) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Γ2 ++ m0 :: Γ5) ++ B :: Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ (B :: Γ4) ++ Γ3 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+  + apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+    * destruct Γ5 ; simpl ; simpl in e0 ; simpl in exch ; subst ; try inversion e0 ; subst.
+      { exists ((Γ2 ++ Γ4 ++ Γ3) ++ Γ1, Δ0 ++ A :: Δ1).
+        exists ((Γ2 ++ Γ4 ++ Γ3) ++ B :: Γ1, Δ0 ++ Δ1). split. split.
+        assert (Γ2 ++ Γ4 ++ Γ3 ++ A --> B :: Γ1 = (Γ2 ++ Γ4 ++ Γ3) ++ A --> B :: Γ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+        assert ((Γ2 ++ Γ3 ++ Γ4) ++ Γ1 = Γ2 ++ Γ3 ++ [] ++ Γ4 ++ Γ1). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert ((Γ2 ++ Γ4 ++ Γ3) ++ Γ1 = Γ2 ++ Γ4 ++ [] ++ Γ3 ++ Γ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+        assert ((Γ2 ++ Γ3 ++ Γ4) ++ B :: Γ1 = Γ2 ++ Γ3 ++ [] ++ Γ4 ++ B :: Γ1). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert ((Γ2 ++ Γ4 ++ Γ3) ++ B :: Γ1 = Γ2 ++ Γ4 ++ [] ++ Γ3 ++ B :: Γ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI. }
+      { exists (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+        exists (Γ2 ++ B :: Γ5 ++ Γ4 ++ Γ3 ++ Γ6, Δ0 ++ Δ1). split. split. apply ImpLRule_I.
+        repeat rewrite <- app_assoc. apply list_exch_LI.
+        assert ((Γ2 ++ Γ3 ++ Γ4) ++ B :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ Γ4 ++ (B :: Γ5) ++ Γ6). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ B :: Γ5 ++ Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (B :: Γ5) ++ Γ4 ++ Γ3 ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI. }
+    * apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+      { exists ((Γ2 ++ Γ5 ++ Γ4 ++ Γ3) ++ Γ1, Δ0 ++ A :: Δ1).
+        exists ((Γ2 ++ Γ5 ++ Γ4 ++ Γ3) ++ B :: Γ1, Δ0 ++ Δ1). split. split.
+        assert (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ A --> B :: Γ1 = (Γ2 ++ Γ5 ++ Γ4 ++ Γ3) ++ A --> B :: Γ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+        repeat rewrite <- app_assoc. apply list_exch_LI. repeat rewrite <- app_assoc. apply list_exch_LI. }
+      { exists ((Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ x0) ++ Γ1, Δ0 ++ A :: Δ1).
+        exists ((Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ x0) ++ B :: Γ1, Δ0 ++ Δ1). split. split.
+        assert (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ x0 ++ A --> B :: Γ1 = (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ x0) ++ A --> B :: Γ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+        repeat rewrite <- app_assoc. apply list_exch_LI. repeat rewrite <- app_assoc. apply list_exch_LI. }
+      { destruct x0.
+        - simpl in e0. subst. rewrite app_nil_r.
+          exists ((Γ2 ++ x ++ Γ4 ++ Γ3) ++ Γ1, Δ0 ++ A :: Δ1).
+          exists ((Γ2 ++ x ++ Γ4 ++ Γ3) ++ B :: Γ1, Δ0 ++ Δ1). split. split.
+          assert (Γ2 ++ x ++ Γ4 ++ Γ3 ++ A --> B :: Γ1 = (Γ2 ++ x ++ Γ4 ++ Γ3) ++ A --> B :: Γ1).
+          repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+          repeat rewrite <- app_assoc. apply list_exch_LI. repeat rewrite <- app_assoc. apply list_exch_LI.
+        - inversion e0. subst.
+          exists ((Γ2 ++ x) ++ x0 ++ Γ4 ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+          exists ((Γ2 ++ x) ++ B :: x0 ++ Γ4 ++ Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+          assert (Γ2 ++ (x ++ A --> B :: x0) ++ Γ4 ++ Γ3 ++ Γ6 = (Γ2 ++ x) ++ A --> B :: x0 ++ Γ4 ++ Γ3 ++ Γ6).
+          repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+          assert ((Γ2 ++ Γ3 ++ Γ4 ++ x) ++ x0 ++ Γ6 = Γ2 ++ Γ3 ++ Γ4 ++ (x ++ x0) ++ Γ6).
+          repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+          assert ((Γ2 ++ x) ++ x0 ++ Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (x ++ x0) ++ Γ4 ++ Γ3 ++ Γ6).
+          repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+          apply list_exch_LI.
+          assert ((Γ2 ++ Γ3 ++ Γ4 ++ x) ++ B :: x0 ++ Γ6 = Γ2 ++ Γ3 ++ Γ4 ++ (x ++ B :: x0) ++ Γ6).
+          repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+          assert ((Γ2 ++ x) ++ B :: x0 ++ Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (x ++ B :: x0) ++ Γ4 ++ Γ3 ++ Γ6).
+          repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+          apply list_exch_LI. }
+    * destruct x ; destruct Γ5 ; simpl ; simpl in e0 ; simpl in exch ; subst ; try inversion e0 ; subst.
+      { rewrite app_nil_r. exists ((Γ2 ++ x0 ++ Γ3) ++ Γ1, Δ0 ++ A :: Δ1).
+        exists ((Γ2 ++ x0 ++ Γ3) ++ B :: Γ1, Δ0 ++ Δ1). split. split.
+        assert (Γ2 ++ x0 ++ Γ3 ++ A --> B :: Γ1 = (Γ2 ++ x0 ++ Γ3) ++ A --> B :: Γ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+        assert ((Γ2 ++ Γ3 ++ x0) ++ Γ1 = Γ2 ++ Γ3 ++ [] ++ x0 ++ Γ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert ((Γ2 ++ x0 ++ Γ3) ++ Γ1 = Γ2 ++ x0 ++ [] ++ Γ3 ++ Γ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+        assert ((Γ2 ++ Γ3 ++ x0) ++ B :: Γ1 = Γ2 ++ Γ3 ++ [] ++ x0 ++ B :: Γ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert ((Γ2 ++ x0 ++ Γ3) ++ B :: Γ1 = Γ2 ++ x0 ++ [] ++ Γ3 ++ B :: Γ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI. }
+      { rewrite app_nil_r. exists (Γ2 ++ Γ5 ++ x0 ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+        exists (Γ2 ++ B :: Γ5 ++ x0 ++ Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+        apply ImpLRule_I. repeat rewrite <- app_assoc. apply list_exch_LI.
+        assert ((Γ2 ++ Γ3 ++ x0) ++ B :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ x0 ++ (B :: Γ5) ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ B :: Γ5 ++ x0 ++ Γ3 ++ Γ6 = Γ2 ++ (B :: Γ5) ++ x0 ++ Γ3 ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI. }
+      { exists ((Γ2 ++ x0) ++ x ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+        exists ((Γ2 ++ x0) ++ B :: x ++ Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+        assert (Γ2 ++ (x0 ++ A --> B :: x) ++ Γ3 ++ Γ6 = (Γ2 ++ x0) ++ A --> B :: x ++ Γ3 ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+        assert ((Γ2 ++ Γ3 ++ x0) ++ x ++ Γ6 = Γ2 ++ Γ3 ++ [] ++ (x0 ++ x) ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert ((Γ2 ++ x0) ++ x ++ Γ3 ++ Γ6 = Γ2 ++ (x0 ++ x) ++ [] ++ Γ3 ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+        assert ((Γ2 ++ Γ3 ++ x0) ++ B :: x ++ Γ6 = Γ2 ++ Γ3 ++ [] ++ (x0 ++ B :: x) ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert ((Γ2 ++ x0) ++ B :: x ++ Γ3 ++ Γ6 = Γ2 ++ (x0 ++ B :: x) ++ [] ++ Γ3 ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI. }
+      { exists ((Γ2 ++ m0 :: Γ5 ++ x0) ++ x ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+        exists ((Γ2 ++ m0 :: Γ5 ++ x0) ++ B :: x ++ Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+        assert (Γ2 ++ m0 :: Γ5 ++ (x0 ++ A --> B :: x) ++ Γ3 ++ Γ6 = (Γ2 ++ m0 :: Γ5 ++ x0) ++ A --> B :: x ++ Γ3 ++ Γ6).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+        assert ((Γ2 ++ Γ3 ++ x0) ++ x ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (x0 ++ x) ++ (m0 :: Γ5) ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert ((Γ2 ++ m0 :: Γ5 ++ x0) ++ x ++ Γ3 ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ (x0 ++ x) ++ Γ3 ++ Γ6).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        apply list_exch_LI.
+        assert ((Γ2 ++ Γ3 ++ x0) ++ B :: x ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (x0 ++ B :: x) ++ (m0 :: Γ5) ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert ((Γ2 ++ m0 :: Γ5 ++ x0) ++ B :: x ++ Γ3 ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ (x0 ++ B :: x) ++ Γ3 ++ Γ6).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        apply list_exch_LI. }
+  + destruct x0 ; destruct Γ4 ; destruct Γ5 ; simpl ; simpl in e0 ; simpl in exch ; subst ; try inversion e0 ; subst.
+    * rewrite app_nil_r. rewrite app_assoc. exists ((Γ2 ++ x) ++ Γ1, Δ0 ++ A :: Δ1).
+      exists ((Γ2 ++ x) ++ B :: Γ1, Δ0 ++ Δ1). split. split ; try assumption. apply list_exch_L_id. apply list_exch_L_id.
+    * rewrite app_nil_r. exists (Γ2 ++ Γ5 ++ x ++ Γ6, Δ0 ++ A :: Δ1).
+      exists (Γ2 ++ B :: Γ5 ++ x ++ Γ6, Δ0 ++ Δ1). split. split. apply ImpLRule_I.
+      assert ((Γ2 ++ x) ++ Γ5 ++ Γ6 = Γ2 ++ x ++ [] ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ Γ5 ++ x ++ Γ6 = Γ2 ++ Γ5 ++ [] ++ x ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+      assert ((Γ2 ++ x) ++ B :: Γ5 ++ Γ6 = Γ2 ++ x ++ [] ++ (B :: Γ5) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ B :: Γ5 ++ x ++ Γ6 = Γ2 ++ (B :: Γ5) ++ [] ++ x ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+    * rewrite app_nil_r. exists (Γ2 ++ Γ4 ++ x ++ Γ6, Δ0 ++ A :: Δ1).
+      exists (Γ2 ++ B :: Γ4 ++ x ++ Γ6, Δ0 ++ Δ1). split. split. apply ImpLRule_I.
+      assert ((Γ2 ++ x) ++ Γ4 ++ Γ6 = Γ2 ++ x ++ [] ++ Γ4 ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ Γ4 ++ x ++ Γ6 = Γ2 ++ Γ4 ++ [] ++ x ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+      assert ((Γ2 ++ x) ++ B :: Γ4 ++ Γ6 = Γ2 ++ x ++ [] ++ (B :: Γ4) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ B :: Γ4 ++ x ++ Γ6 = Γ2 ++ (B :: Γ4) ++ [] ++ x ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+    * rewrite app_nil_r. exists ((Γ2 ++ m0 :: Γ5) ++ Γ4 ++ x ++ Γ6, Δ0 ++ A :: Δ1).
+      exists ((Γ2 ++ m0 :: Γ5) ++ B :: Γ4 ++ x ++ Γ6, Δ0 ++ Δ1). split. split.
+      assert (Γ2 ++ m0 :: Γ5 ++ A --> B :: Γ4 ++ x ++ Γ6 = (Γ2 ++ m0 :: Γ5) ++ A --> B :: Γ4 ++ x ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+      assert ((Γ2 ++ x) ++ Γ4 ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ x ++ Γ4 ++ (m0 :: Γ5) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Γ2 ++ m0 :: Γ5) ++ Γ4 ++ x ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ Γ4 ++ x ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+      assert ((Γ2 ++ x) ++ B :: Γ4 ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ x ++ (B :: Γ4) ++ (m0 :: Γ5) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Γ2 ++ m0 :: Γ5) ++ B :: Γ4 ++ x ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ (B :: Γ4) ++ x ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+    * exists ((Γ2 ++ x) ++ x0 ++ Γ6, Δ0 ++ A :: Δ1).
+      exists ((Γ2 ++ x) ++ B :: x0 ++ Γ6, Δ0 ++ Δ1). split. split.
+      assert (Γ2 ++ (x ++ A --> B :: x0) ++ Γ6 = (Γ2 ++ x) ++ A --> B :: x0 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+      apply list_exch_L_id. apply list_exch_L_id.
+    * exists ((Γ2 ++ m0 :: Γ5 ++ x) ++ x0 ++ Γ6, Δ0 ++ A :: Δ1).
+      exists ((Γ2 ++ m0 :: Γ5 ++ x) ++ B :: x0 ++ Γ6, Δ0 ++ Δ1). split. split.
+      assert (Γ2 ++ m0 :: Γ5 ++ (x ++ A --> B :: x0) ++ Γ6 = (Γ2 ++ m0 :: Γ5 ++ x) ++ A --> B :: x0 ++ Γ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+      assert ((Γ2 ++ x) ++ x0 ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ [] ++ (x ++ x0) ++ (m0 :: Γ5) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Γ2 ++ m0 :: Γ5 ++ x) ++ x0 ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ (x ++ x0) ++ [] ++ Γ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. apply list_exch_LI.
+      assert ((Γ2 ++ x) ++ B :: x0 ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ [] ++ (x ++ B :: x0) ++ (m0 :: Γ5) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Γ2 ++ m0 :: Γ5 ++ x) ++ B :: x0 ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ (x ++ B :: x0) ++ [] ++ Γ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. apply list_exch_LI.
+    * exists ((Γ2 ++ m0 :: Γ4 ++ x) ++ x0 ++ Γ6, Δ0 ++ A :: Δ1).
+      exists ((Γ2 ++ m0 :: Γ4 ++ x) ++ B :: x0 ++ Γ6, Δ0 ++ Δ1). split. split.
+      assert (Γ2 ++ m0 :: Γ4 ++ (x ++ A --> B :: x0) ++ Γ6 = (Γ2 ++ m0 :: Γ4 ++ x) ++ A --> B :: x0 ++ Γ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+      assert ((Γ2 ++ x) ++ x0 ++ m0 :: Γ4 ++ Γ6 = Γ2 ++ [] ++ (x ++ x0) ++ (m0 :: Γ4) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Γ2 ++ m0 :: Γ4 ++ x) ++ x0 ++ Γ6 = Γ2 ++ (m0 :: Γ4) ++ (x ++ x0) ++ [] ++ Γ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. apply list_exch_LI.
+      assert ((Γ2 ++ x) ++ B :: x0 ++ m0 :: Γ4 ++ Γ6 = Γ2 ++ [] ++ (x ++ B :: x0) ++ (m0 :: Γ4) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Γ2 ++ m0 :: Γ4 ++ x) ++ B :: x0 ++ Γ6 = Γ2 ++ (m0 :: Γ4) ++ (x ++ B :: x0) ++ [] ++ Γ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. apply list_exch_LI.
+    * exists ((Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ x) ++ x0 ++ Γ6, Δ0 ++ A :: Δ1).
+      exists ((Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ x) ++ B :: x0 ++ Γ6, Δ0 ++ Δ1). split. split.
+      assert (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ (x ++ A --> B :: x0) ++ Γ6 = (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ x) ++ A --> B :: x0 ++ Γ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. simpl.
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+      assert ((Γ2 ++ x) ++ x0 ++ m0 :: Γ4 ++ m1 :: Γ5 ++ Γ6 = Γ2 ++ (x ++ x0) ++ (m0 :: Γ4) ++ (m1 :: Γ5) ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      assert ((Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ x) ++ x0 ++ Γ6 = Γ2 ++ (m1 :: Γ5) ++ (m0 :: Γ4) ++ (x ++ x0) ++ Γ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. apply list_exch_LI.
+      assert ((Γ2 ++ x) ++ B :: x0 ++ m0 :: Γ4 ++ m1 :: Γ5 ++ Γ6 = Γ2 ++ (x ++ B :: x0) ++ (m0 :: Γ4) ++ (m1 :: Γ5) ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      assert ((Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ x) ++ B :: x0 ++ Γ6 = Γ2 ++ (m1 :: Γ5) ++ (m0 :: Γ4) ++ (x ++ B :: x0) ++ Γ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. apply list_exch_LI.
+- destruct x ; destruct Γ3 ; destruct Γ4 ; destruct Γ5 ; simpl ; simpl in e0 ; simpl in exch ;
+  subst ; try inversion e0 ; subst.
+  * rewrite app_nil_r. exists (Γ0 ++ Γ1, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: Γ1, Δ0 ++ Δ1). split. split ; try assumption.
+    apply list_exch_L_id. apply list_exch_L_id.
+  * rewrite app_nil_r. exists (Γ0 ++ Γ5 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: Γ5 ++ Γ6, Δ0 ++ Δ1). split. split ; try assumption.
+    apply list_exch_L_id. apply list_exch_L_id.
+  * rewrite app_nil_r. exists (Γ0 ++ Γ4 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: Γ4 ++ Γ6, Δ0 ++ Δ1). split. split ; try assumption.
+    apply list_exch_L_id. apply list_exch_L_id.
+  * rewrite app_nil_r. exists ((Γ0 ++ m0 :: Γ5) ++ Γ4 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists ((Γ0 ++ m0 :: Γ5) ++ B :: Γ4 ++ Γ6, Δ0 ++ Δ1). split. split.
+    assert (Γ0 ++ m0 :: Γ5 ++ A --> B :: Γ4 ++ Γ6 = (Γ0 ++ m0 :: Γ5) ++ A --> B :: Γ4 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+    assert (Γ0 ++ Γ4 ++ m0 :: Γ5 ++ Γ6 = Γ0 ++ [] ++ Γ4 ++ (m0 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert ((Γ0 ++ m0 :: Γ5) ++ Γ4 ++ Γ6 = Γ0 ++ (m0 :: Γ5) ++ Γ4 ++ [] ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ0 ++ B :: Γ4 ++ m0 :: Γ5 ++ Γ6 = Γ0 ++ [] ++ (B :: Γ4) ++ (m0 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert ((Γ0 ++ m0 :: Γ5) ++ B :: Γ4 ++ Γ6 = Γ0 ++ (m0 :: Γ5) ++ (B :: Γ4) ++ [] ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+  * rewrite app_nil_r. exists (Γ0 ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split ; try assumption.
+    apply list_exch_L_id. apply list_exch_L_id.
+  * rewrite app_nil_r. exists ((Γ0 ++ m0 :: Γ5) ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists ((Γ0 ++ m0 :: Γ5) ++ B :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+    assert (Γ0 ++ m0 :: Γ5 ++ A --> B :: Γ3 ++ Γ6 = (Γ0 ++ m0 :: Γ5) ++ A --> B :: Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+    assert (Γ0 ++ Γ3 ++ m0 :: Γ5 ++ Γ6 = Γ0 ++ [] ++ Γ3 ++ (m0 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert ((Γ0 ++ m0 :: Γ5) ++ Γ3 ++ Γ6 = Γ0 ++ (m0 :: Γ5) ++ Γ3 ++ [] ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ0 ++ B :: Γ3 ++ m0 :: Γ5 ++ Γ6 = Γ0 ++ [] ++ (B :: Γ3) ++ (m0 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert ((Γ0 ++ m0 :: Γ5) ++ B :: Γ3 ++ Γ6 = Γ0 ++ (m0 :: Γ5) ++ (B :: Γ3) ++ [] ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+  * rewrite app_nil_r. exists ((Γ0 ++ m0 :: Γ4) ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists ((Γ0 ++ m0 :: Γ4) ++ B :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+    assert (Γ0 ++ m0 :: Γ4 ++ A --> B :: Γ3 ++ Γ6 = (Γ0 ++ m0 :: Γ4) ++ A --> B :: Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+    assert ((Γ0 ++ m0 :: Γ4) ++ Γ3 ++ Γ6 = Γ0 ++ (m0 :: Γ4) ++ Γ3 ++ [] ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ Γ3 ++ m0 :: Γ4 ++ Γ6 = Γ0 ++ [] ++ Γ3 ++ (m0 :: Γ4) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+    assert ((Γ0 ++ m0 :: Γ4) ++ B :: Γ3 ++ Γ6 = Γ0 ++ (m0 :: Γ4) ++ (B :: Γ3) ++ [] ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ B :: Γ3 ++ m0 :: Γ4 ++ Γ6 = Γ0 ++ [] ++ (B :: Γ3) ++ (m0 :: Γ4) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+  * rewrite app_nil_r. exists ((Γ0 ++ m1 :: Γ5 ++ m0 :: Γ4) ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists ((Γ0 ++ m1 :: Γ5 ++ m0 :: Γ4) ++ B :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+    assert (Γ0 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ A --> B :: Γ3 ++ Γ6 = (Γ0 ++ m1 :: Γ5 ++ m0 :: Γ4) ++ A --> B :: Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+    assert (Γ0 ++ Γ3 ++ m0 :: Γ4 ++ m1 :: Γ5 ++ Γ6 = Γ0 ++ Γ3 ++ (m0 :: Γ4) ++ (m1 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert ((Γ0 ++ m1 :: Γ5 ++ m0 :: Γ4) ++ Γ3 ++ Γ6 = Γ0 ++ (m1 :: Γ5) ++ (m0 :: Γ4) ++ Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ0 ++ B :: Γ3 ++ m0 :: Γ4 ++ m1 :: Γ5 ++ Γ6 = Γ0 ++ (B :: Γ3) ++ (m0 :: Γ4) ++ (m1 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert ((Γ0 ++ m1 :: Γ5 ++ m0 :: Γ4) ++ B :: Γ3 ++ Γ6 = Γ0 ++ (m1 :: Γ5) ++ (m0 :: Γ4) ++ (B :: Γ3) ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+  * exists (Γ0 ++ x ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: x ++ Γ6, Δ0 ++ Δ1). split. split. repeat rewrite <- app_assoc. apply ImpLRule_I.
+    apply list_exch_L_id. apply list_exch_L_id.
+  * exists (Γ0 ++ x ++ m0 :: Γ5 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: x ++ m0 :: Γ5 ++ Γ6, Δ0 ++ Δ1). split. split. repeat rewrite <- app_assoc. apply ImpLRule_I.
+    apply list_exch_L_id. apply list_exch_L_id.
+  * exists (Γ0 ++ x ++ m0 :: Γ4 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: x ++ m0 :: Γ4 ++ Γ6, Δ0 ++ Δ1). split. split. repeat rewrite <- app_assoc. apply ImpLRule_I.
+    apply list_exch_L_id. apply list_exch_L_id.
+  * exists (Γ0 ++ x ++ m1 :: Γ5 ++ m0 :: Γ4 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: x ++ m1 :: Γ5 ++ m0 :: Γ4 ++ Γ6, Δ0 ++ Δ1). split. split.
+    repeat rewrite <- app_assoc. apply ImpLRule_I.
+    assert (Γ0 ++ x ++ m0 :: Γ4 ++ m1 :: Γ5 ++ Γ6 = (Γ0 ++ x) ++ (m0 :: Γ4) ++ [] ++ (m1 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ x ++ m1 :: Γ5 ++ m0 :: Γ4 ++ Γ6 = (Γ0 ++ x) ++ (m1 :: Γ5) ++ [] ++ (m0 :: Γ4) ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ0 ++ B :: x ++ m0 :: Γ4 ++ m1 :: Γ5 ++ Γ6 = (Γ0 ++ B :: x) ++ (m0 :: Γ4) ++ [] ++ (m1 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ B :: x ++ m1 :: Γ5 ++ m0 :: Γ4 ++ Γ6 = (Γ0 ++ B :: x) ++ (m1 :: Γ5) ++ [] ++ (m0 :: Γ4) ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+  * exists (Γ0 ++ x ++ m0 :: Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: x ++ m0 :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split. repeat rewrite <- app_assoc. apply ImpLRule_I.
+    apply list_exch_L_id. apply list_exch_L_id.
+  * exists (Γ0 ++ x ++ m1 :: Γ5 ++ m0 :: Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: x ++ m1 :: Γ5 ++ m0 :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+    repeat rewrite <- app_assoc. apply ImpLRule_I.
+    assert (Γ0 ++ x ++ m0 :: Γ3 ++ m1 :: Γ5 ++ Γ6 = (Γ0 ++ x) ++ (m0 :: Γ3) ++ [] ++ (m1 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ x ++ m1 :: Γ5 ++ m0 :: Γ3 ++ Γ6 = (Γ0 ++ x) ++ (m1 :: Γ5) ++ [] ++ (m0 :: Γ3) ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ0 ++ B :: x ++ m0 :: Γ3 ++ m1 :: Γ5 ++ Γ6 = (Γ0 ++ B :: x) ++ (m0 :: Γ3) ++ [] ++ (m1 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ B :: x ++ m1 :: Γ5 ++ m0 :: Γ3 ++ Γ6 = (Γ0 ++ B :: x) ++ (m1 :: Γ5) ++ [] ++ (m0 :: Γ3) ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+  * exists (Γ0 ++ x ++ m1 :: Γ4 ++ m0 :: Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: x ++ m1 :: Γ4 ++ m0 :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+    repeat rewrite <- app_assoc. apply ImpLRule_I.
+    assert (Γ0 ++ x ++ m0 :: Γ3 ++ m1 :: Γ4 ++ Γ6 = (Γ0 ++ x) ++ (m0 :: Γ3) ++ [] ++ (m1 :: Γ4) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ x ++ m1 :: Γ4 ++ m0 :: Γ3 ++ Γ6 = (Γ0 ++ x) ++ (m1 :: Γ4) ++ [] ++ (m0 :: Γ3) ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ0 ++ B :: x ++ m0 :: Γ3 ++ m1 :: Γ4 ++ Γ6 = (Γ0 ++ B :: x) ++ (m0 :: Γ3) ++ [] ++ (m1 :: Γ4) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ B :: x ++ m1 :: Γ4 ++ m0 :: Γ3 ++ Γ6 = (Γ0 ++ B :: x) ++ (m1 :: Γ4) ++ [] ++ (m0 :: Γ3) ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+  * exists (Γ0 ++ x ++ m2 :: Γ5 ++ m1 :: Γ4 ++ m0 :: Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: x ++ m2 :: Γ5 ++ m1 :: Γ4 ++ m0 :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+    repeat rewrite <- app_assoc. apply ImpLRule_I.
+    assert (Γ0 ++ x ++ m0 :: Γ3 ++ m1 :: Γ4 ++ m2 :: Γ5 ++ Γ6 = (Γ0 ++ x) ++ (m0 :: Γ3) ++ (m1 :: Γ4) ++ (m2 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ x ++ m2 :: Γ5 ++ m1 :: Γ4 ++ m0 :: Γ3 ++ Γ6 = (Γ0 ++ x) ++ (m2 :: Γ5) ++ (m1 :: Γ4) ++ (m0 :: Γ3) ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ0 ++ B :: x ++ m0 :: Γ3 ++ m1 :: Γ4 ++ m2 :: Γ5 ++ Γ6 = (Γ0 ++ B :: x) ++ (m0 :: Γ3) ++ (m1 :: Γ4) ++ (m2 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ B :: x ++ m2 :: Γ5 ++ m1 :: Γ4 ++ m0 :: Γ3 ++ Γ6 = (Γ0 ++ B :: x) ++ (m2 :: Γ5) ++ (m1 :: Γ4) ++ (m0 :: Γ3) ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+Qed.
+ +
+Lemma GLR_app_list_exchL : forall s se ps,
+  (@list_exch_L s se) ->
+  (GLRRule [ps] s) ->
+  (existsT2 pse,
+    (GLRRule [pse] se) *
+    (@list_exch_L ps pse)).
+Proof.
+intros s se ps exch RA. inversion RA. inversion exch. rewrite <- H1 in H2.
+inversion H2. subst.
+pose (@nobox_gen_ext_exch_L (Δ0 ++ Box A :: Δ1) [A] (Γ1 ++ Γ2 ++ Γ3 ++ Γ4 ++ Γ5) (Γ1 ++ Γ4 ++ Γ3 ++ Γ2 ++ Γ5) X exch).
+destruct s. destruct p. inversion l.
+exists (XBoxed_list (Γ0 ++ Γ8 ++ Γ7 ++ Γ6 ++ Γ9) ++ [Box A], [A]). split.
+- apply GLRRule_I.
+  * unfold is_Boxed_list. intros. apply in_exch_list in H4. subst. apply H0 in H4.
+    assumption.
+  * subst. assumption.
+- repeat rewrite XBox_app_distrib. repeat rewrite <- app_assoc. apply list_exch_LI.
+Qed.
+ +
+Lemma ImpR_app_list_exchR : forall s se ps,
+  (@list_exch_R s se) ->
+  (ImpRRule [ps] s) ->
+  (existsT2 pse,
+    (ImpRRule [pse] se) *
+    (@list_exch_R ps pse)).
+Proof.
+intros s se ps exch. intro RA. inversion RA. inversion exch. subst.
+inversion H. apply app2_find_hole in H2. destruct H2. repeat destruct s ; destruct p ; subst.
+- destruct Δ3 ; destruct Δ4 ; destruct Δ5 ; simpl ; simpl in e0 ; simpl in exch ; subst ; try inversion e0 ; subst.
+  + exists (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ1). split ; try assumption. apply list_exch_R_id.
+  + exists (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ5 ++ Δ6). split ; try assumption. apply list_exch_R_id.
+  + exists (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ4 ++ Δ6). split ; try assumption. apply list_exch_R_id.
+  + exists (Γ0 ++ A :: Γ1, Δ2 ++ (m0 :: Δ5) ++ B :: Δ4 ++ Δ6). split.
+    assert (Δ2 ++ (m0 :: Δ5) ++ B :: Δ4 ++ Δ6 = (Δ2 ++ m0 :: Δ5) ++ B :: Δ4 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Δ2 ++ m0 :: Δ5 ++ A --> B :: Δ4 ++ Δ6 = (Δ2 ++ m0 :: Δ5) ++ A --> B :: Δ4 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    apply ImpRRule_I. assert (Δ2 ++ B :: Δ4 ++ m0 :: Δ5 ++ Δ6 = Δ2 ++ [] ++ (B :: Δ4) ++ (m0 :: Δ5) ++ Δ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Δ2 ++ (m0 :: Δ5) ++ B :: Δ4 ++ Δ6 = Δ2 ++ (m0 :: Δ5) ++ (B :: Δ4) ++ [] ++ Δ6).
+    reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+  + exists (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ3 ++ Δ6). split ; try assumption. apply list_exch_R_id.
+  + exists (Γ0 ++ A :: Γ1, Δ2 ++ (m0 :: Δ5) ++ B :: Δ3 ++ Δ6). split.
+    assert (Δ2 ++ m0 :: Δ5 ++ A --> B :: Δ3 ++ Δ6 = (Δ2 ++ m0 :: Δ5) ++ A --> B :: Δ3 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Δ2 ++ (m0 :: Δ5) ++ B :: Δ3 ++ Δ6 = (Δ2 ++ m0 :: Δ5) ++ B :: Δ3 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    apply ImpRRule_I. assert (Δ2 ++ B :: Δ3 ++ m0 :: Δ5 ++ Δ6 = Δ2 ++ (B :: Δ3) ++ [] ++ (m0 :: Δ5) ++ Δ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Δ2 ++ (m0 :: Δ5) ++ B :: Δ3 ++ Δ6 = Δ2 ++ (m0 :: Δ5) ++ [] ++ (B :: Δ3) ++ Δ6).
+    reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+  + exists (Γ0 ++ A :: Γ1, (Δ2 ++ m0 :: Δ4) ++ B :: Δ3 ++ Δ6). split.
+    assert (Δ2 ++ m0 :: Δ4 ++ A --> B :: Δ3 ++ Δ6 = (Δ2 ++ m0 :: Δ4) ++ A --> B :: Δ3 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+    assert (Δ2 ++ B :: Δ3 ++ m0 :: Δ4 ++ Δ6 = Δ2 ++ (B :: Δ3) ++ [] ++ (m0 :: Δ4) ++ Δ6).
+    reflexivity. rewrite H0. clear H0.
+    assert ((Δ2 ++ m0 :: Δ4) ++ B :: Δ3 ++ Δ6 = Δ2 ++ (m0 :: Δ4) ++ [] ++ (B :: Δ3) ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+  + exists (Γ0 ++ A :: Γ1, (Δ2 ++ m1 :: Δ5 ++ m0 :: Δ4) ++ B :: Δ3 ++ Δ6). split.
+    assert (Δ2 ++ m1 :: Δ5 ++ m0 :: Δ4 ++ A --> B :: Δ3 ++ Δ6 = (Δ2 ++ m1 :: Δ5 ++ m0 :: Δ4) ++ A --> B :: Δ3 ++ Δ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+    assert (Δ2 ++ B :: Δ3 ++ m0 :: Δ4 ++ m1 :: Δ5 ++ Δ6 = Δ2 ++ (B :: Δ3) ++ (m0 :: Δ4) ++ (m1 :: Δ5) ++ Δ6).
+    reflexivity. rewrite H0. clear H0.
+    assert ((Δ2 ++ m1 :: Δ5 ++ m0 :: Δ4) ++ B :: Δ3 ++ Δ6 = Δ2 ++ (m1 :: Δ5) ++ (m0 :: Δ4) ++ (B :: Δ3) ++ Δ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+- apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+  + destruct Δ4 ; destruct Δ5 ; simpl ; simpl in e0 ; simpl in exch ; subst ; try inversion e0 ; subst.
+    * rewrite app_assoc. exists (Γ0 ++ A :: Γ1, (Δ2 ++ Δ3) ++ B :: Δ1). split ; try assumption. apply list_exch_R_id.
+    * exists (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ5 ++ Δ3 ++ Δ6). split. apply ImpRRule_I.
+      assert ((Δ2 ++ Δ3) ++ B :: Δ5 ++ Δ6 = Δ2 ++ Δ3 ++ [] ++ (B :: Δ5) ++ Δ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Δ2 ++ B :: Δ5 ++ Δ3 ++ Δ6 = Δ2 ++ (B :: Δ5) ++ [] ++ Δ3 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+    * exists (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ4 ++ Δ3 ++ Δ6). split. apply ImpRRule_I.
+      assert ((Δ2 ++ Δ3) ++ B :: Δ4 ++ Δ6 = Δ2 ++ Δ3 ++ [] ++ (B :: Δ4) ++ Δ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Δ2 ++ B :: Δ4 ++ Δ3 ++ Δ6 = Δ2 ++ (B :: Δ4) ++ [] ++ Δ3 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+    * exists (Γ0 ++ A :: Γ1, (Δ2 ++ m0 :: Δ5) ++ B :: Δ4 ++ Δ3 ++ Δ6). split.
+      assert (Δ2 ++ m0 :: Δ5 ++ A --> B :: Δ4 ++ Δ3 ++ Δ6 = (Δ2 ++ m0 :: Δ5) ++ A --> B :: Δ4 ++ Δ3 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+      assert ((Δ2 ++ Δ3) ++ B :: Δ4 ++ m0 :: Δ5 ++ Δ6 = Δ2 ++ Δ3 ++ (B :: Δ4) ++ (m0 :: Δ5) ++ Δ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Δ2 ++ m0 :: Δ5) ++ B :: Δ4 ++ Δ3 ++ Δ6 = Δ2 ++ (m0 :: Δ5) ++ (B :: Δ4) ++ Δ3 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+  + apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+    * destruct Δ5 ; simpl ; simpl in e0 ; simpl in exch ; subst ; try inversion e0 ; subst.
+      { exists (Γ0 ++ A :: Γ1, (Δ2 ++ Δ4 ++ Δ3) ++ B :: Δ1). split.
+        assert (Δ2 ++ Δ4 ++ Δ3 ++ A --> B :: Δ1 = (Δ2 ++ Δ4 ++ Δ3) ++ A --> B :: Δ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+        assert ((Δ2 ++ Δ3 ++ Δ4) ++ B :: Δ1 = Δ2 ++ Δ3 ++ [] ++ Δ4 ++ B :: Δ1). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert ((Δ2 ++ Δ4 ++ Δ3) ++ B :: Δ1 = Δ2 ++ Δ4 ++ [] ++ Δ3 ++ B :: Δ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI. }
+      { exists (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ5 ++ Δ4 ++ Δ3 ++ Δ6). split. apply ImpRRule_I.
+        assert ((Δ2 ++ Δ3 ++ Δ4) ++ B :: Δ5 ++ Δ6 = Δ2 ++ Δ3 ++ Δ4 ++ (B :: Δ5) ++ Δ6). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Δ2 ++ B :: Δ5 ++ Δ4 ++ Δ3 ++ Δ6 = Δ2 ++ (B :: Δ5) ++ Δ4 ++ Δ3 ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI. }
+    * apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+      { exists (Γ0 ++ A :: Γ1, (Δ2 ++ Δ5 ++ Δ4 ++ Δ3) ++ B :: Δ1). split.
+        assert (Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ A --> B :: Δ1 = (Δ2 ++ Δ5 ++ Δ4 ++ Δ3) ++ A --> B :: Δ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+        repeat rewrite <- app_assoc. apply list_exch_RI. }
+      { exists (Γ0 ++ A :: Γ1, (Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ x0) ++ B :: Δ1). split.
+        assert (Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ x0 ++ A --> B :: Δ1 = (Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ x0) ++ A --> B :: Δ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+        repeat rewrite <- app_assoc. apply list_exch_RI. }
+      { destruct x0.
+        - simpl in e0. subst. rewrite app_nil_r.
+          exists (Γ0 ++ A :: Γ1, (Δ2 ++ x ++ Δ4 ++ Δ3) ++ B :: Δ1). split.
+          assert (Δ2 ++ x ++ Δ4 ++ Δ3 ++ A --> B :: Δ1 = (Δ2 ++ x ++ Δ4 ++ Δ3) ++ A --> B :: Δ1).
+          repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+          repeat rewrite <- app_assoc. apply list_exch_RI.
+        - inversion e0. subst.
+          exists (Γ0 ++ A :: Γ1, (Δ2 ++ x) ++ B :: x0 ++ Δ4 ++ Δ3 ++ Δ6). split.
+          assert (Δ2 ++ (x ++ A --> B :: x0) ++ Δ4 ++ Δ3 ++ Δ6 = (Δ2 ++ x) ++ A --> B :: x0 ++ Δ4 ++ Δ3 ++ Δ6).
+          repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+          assert ((Δ2 ++ Δ3 ++ Δ4 ++ x) ++ B :: x0 ++ Δ6 = Δ2 ++ Δ3 ++ Δ4 ++ (x ++ B :: x0) ++ Δ6).
+          repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+          assert ((Δ2 ++ x) ++ B :: x0 ++ Δ4 ++ Δ3 ++ Δ6 = Δ2 ++ (x ++ B :: x0) ++ Δ4 ++ Δ3 ++ Δ6).
+          repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+          apply list_exch_RI. }
+    * destruct x ; destruct Δ5 ; simpl ; simpl in e0 ; simpl in exch ; subst ; try inversion e0 ; subst.
+      { rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, (Δ2 ++ x0 ++ Δ3) ++ B :: Δ1). split.
+        assert (Δ2 ++ x0 ++ Δ3 ++ A --> B :: Δ1 = (Δ2 ++ x0 ++ Δ3) ++ A --> B :: Δ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+        assert ((Δ2 ++ Δ3 ++ x0) ++ B :: Δ1 = Δ2 ++ Δ3 ++ [] ++ x0 ++ B :: Δ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert ((Δ2 ++ x0 ++ Δ3) ++ B :: Δ1 = Δ2 ++ x0 ++ [] ++ Δ3 ++ B :: Δ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI. }
+      { rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ5 ++ x0 ++ Δ3 ++ Δ6). split.
+        apply ImpRRule_I.
+        assert ((Δ2 ++ Δ3 ++ x0) ++ B :: Δ5 ++ Δ6 = Δ2 ++ Δ3 ++ x0 ++ (B :: Δ5) ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Δ2 ++ B :: Δ5 ++ x0 ++ Δ3 ++ Δ6 = Δ2 ++ (B :: Δ5) ++ x0 ++ Δ3 ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI. }
+      { exists (Γ0 ++ A :: Γ1, (Δ2 ++ x0) ++ B :: x ++ Δ3 ++ Δ6). split.
+        assert (Δ2 ++ (x0 ++ A --> B :: x) ++ Δ3 ++ Δ6 = (Δ2 ++ x0) ++ A --> B :: x ++ Δ3 ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+        assert ((Δ2 ++ Δ3 ++ x0) ++ B :: x ++ Δ6 = Δ2 ++ Δ3 ++ [] ++ (x0 ++ B :: x) ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert ((Δ2 ++ x0) ++ B :: x ++ Δ3 ++ Δ6 = Δ2 ++ (x0 ++ B :: x) ++ [] ++ Δ3 ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI. }
+      { exists (Γ0 ++ A :: Γ1, (Δ2 ++ m0 :: Δ5 ++ x0) ++ B :: x ++ Δ3 ++ Δ6). split.
+        assert (Δ2 ++ m0 :: Δ5 ++ (x0 ++ A --> B :: x) ++ Δ3 ++ Δ6 = (Δ2 ++ m0 :: Δ5 ++ x0) ++ A --> B :: x ++ Δ3 ++ Δ6).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+        assert ((Δ2 ++ Δ3 ++ x0) ++ B :: x ++ m0 :: Δ5 ++ Δ6 = Δ2 ++ Δ3 ++ (x0 ++ B :: x) ++ (m0 :: Δ5) ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert ((Δ2 ++ m0 :: Δ5 ++ x0) ++ B :: x ++ Δ3 ++ Δ6 = Δ2 ++ (m0 :: Δ5) ++ (x0 ++ B :: x) ++ Δ3 ++ Δ6).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        apply list_exch_RI. }
+  + destruct x0 ; destruct Δ4 ; destruct Δ5 ; simpl ; simpl in e0 ; simpl in exch ; subst ; try inversion e0 ; subst.
+    * rewrite app_nil_r. rewrite app_assoc. exists (Γ0 ++ A :: Γ1, (Δ2 ++ x) ++ B :: Δ1). split ; try assumption. apply list_exch_R_id.
+    * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ5 ++ x ++ Δ6). split. apply ImpRRule_I.
+      assert ((Δ2 ++ x) ++ B :: Δ5 ++ Δ6 = Δ2 ++ x ++ [] ++ (B :: Δ5) ++ Δ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Δ2 ++ B :: Δ5 ++ x ++ Δ6 = Δ2 ++ (B :: Δ5) ++ [] ++ x ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+    * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ4 ++ x ++ Δ6). split. apply ImpRRule_I.
+      assert ((Δ2 ++ x) ++ B :: Δ4 ++ Δ6 = Δ2 ++ x ++ [] ++ (B :: Δ4) ++ Δ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Δ2 ++ B :: Δ4 ++ x ++ Δ6 = Δ2 ++ (B :: Δ4) ++ [] ++ x ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+    * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, (Δ2 ++ m0 :: Δ5) ++ B :: Δ4 ++ x ++ Δ6). split.
+      assert (Δ2 ++ m0 :: Δ5 ++ A --> B :: Δ4 ++ x ++ Δ6 = (Δ2 ++ m0 :: Δ5) ++ A --> B :: Δ4 ++ x ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpRRule_I.
+      assert ((Δ2 ++ x) ++ B :: Δ4 ++ m0 :: Δ5 ++ Δ6 = Δ2 ++ x ++ (B :: Δ4) ++ (m0 :: Δ5) ++ Δ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Δ2 ++ m0 :: Δ5) ++ B :: Δ4 ++ x ++ Δ6 = Δ2 ++ (m0 :: Δ5) ++ (B :: Δ4) ++ x ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+    * exists (Γ0 ++ A :: Γ1, (Δ2 ++ x) ++ B :: x0 ++ Δ6). split.
+      assert (Δ2 ++ (x ++ A --> B :: x0) ++ Δ6 = (Δ2 ++ x) ++ A --> B :: x0 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpRRule_I.
+      apply list_exch_R_id.
+    * exists (Γ0 ++ A :: Γ1, (Δ2 ++ m0 :: Δ5 ++ x) ++ B :: x0 ++ Δ6). split.
+      assert (Δ2 ++ m0 :: Δ5 ++ (x ++ A --> B :: x0) ++ Δ6 = (Δ2 ++ m0 :: Δ5 ++ x) ++ A --> B :: x0 ++ Δ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpRRule_I.
+      assert ((Δ2 ++ x) ++ B :: x0 ++ m0 :: Δ5 ++ Δ6 = Δ2 ++ [] ++ (x ++ B :: x0) ++ (m0 :: Δ5) ++ Δ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Δ2 ++ m0 :: Δ5 ++ x) ++ B :: x0 ++ Δ6 = Δ2 ++ (m0 :: Δ5) ++ (x ++ B :: x0) ++ [] ++ Δ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. apply list_exch_RI.
+    * exists (Γ0 ++ A :: Γ1, (Δ2 ++ m0 :: Δ4 ++ x) ++ B :: x0 ++ Δ6). split.
+      assert (Δ2 ++ m0 :: Δ4 ++ (x ++ A --> B :: x0) ++ Δ6 = (Δ2 ++ m0 :: Δ4 ++ x) ++ A --> B :: x0 ++ Δ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpRRule_I.
+      assert ((Δ2 ++ x) ++ B :: x0 ++ m0 :: Δ4 ++ Δ6 = Δ2 ++ [] ++ (x ++ B :: x0) ++ (m0 :: Δ4) ++ Δ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Δ2 ++ m0 :: Δ4 ++ x) ++ B :: x0 ++ Δ6 = Δ2 ++ (m0 :: Δ4) ++ (x ++ B :: x0) ++ [] ++ Δ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. apply list_exch_RI.
+    * exists (Γ0 ++ A :: Γ1, (Δ2 ++ m1 :: Δ5 ++ m0 :: Δ4 ++ x) ++ B :: x0 ++ Δ6). split.
+      assert (Δ2 ++ m1 :: Δ5 ++ m0 :: Δ4 ++ (x ++ A --> B :: x0) ++ Δ6 = (Δ2 ++ m1 :: Δ5 ++ m0 :: Δ4 ++ x) ++ A --> B :: x0 ++ Δ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. simpl.
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpRRule_I.
+      assert ((Δ2 ++ x) ++ B :: x0 ++ m0 :: Δ4 ++ m1 :: Δ5 ++ Δ6 = Δ2 ++ (x ++ B :: x0) ++ (m0 :: Δ4) ++ (m1 :: Δ5) ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      assert ((Δ2 ++ m1 :: Δ5 ++ m0 :: Δ4 ++ x) ++ B :: x0 ++ Δ6 = Δ2 ++ (m1 :: Δ5) ++ (m0 :: Δ4) ++ (x ++ B :: x0) ++ Δ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. apply list_exch_RI.
+- destruct x ; destruct Δ3 ; destruct Δ4 ; destruct Δ5 ; simpl ; simpl in e0 ; simpl in exch ;
+  subst ; try inversion e0 ; subst.
+  * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1). split ; try assumption.
+    apply list_exch_R_id.
+  * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ5 ++ Δ6). split ; try assumption.
+    apply list_exch_R_id.
+  * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ4 ++ Δ6). split ; try assumption.
+    apply list_exch_R_id.
+  * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, (Δ0 ++ m0 :: Δ5) ++ B :: Δ4 ++ Δ6). split.
+    assert (Δ0 ++ m0 :: Δ5 ++ A --> B :: Δ4 ++ Δ6 = (Δ0 ++ m0 :: Δ5) ++ A --> B :: Δ4 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpRRule_I.
+    assert (Δ0 ++ B :: Δ4 ++ m0 :: Δ5 ++ Δ6 = Δ0 ++ [] ++ (B :: Δ4) ++ (m0 :: Δ5) ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert ((Δ0 ++ m0 :: Δ5) ++ B :: Δ4 ++ Δ6 = Δ0 ++ (m0 :: Δ5) ++ (B :: Δ4) ++ [] ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_RI.
+  * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ3 ++ Δ6). split ; try assumption.
+    apply list_exch_R_id.
+  * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, (Δ0 ++ m0 :: Δ5) ++ B :: Δ3 ++ Δ6). split.
+    assert (Δ0 ++ m0 :: Δ5 ++ A --> B :: Δ3 ++ Δ6 = (Δ0 ++ m0 :: Δ5) ++ A --> B :: Δ3 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpRRule_I.
+    assert (Δ0 ++ B :: Δ3 ++ m0 :: Δ5 ++ Δ6 = Δ0 ++ [] ++ (B :: Δ3) ++ (m0 :: Δ5) ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert ((Δ0 ++ m0 :: Δ5) ++ B :: Δ3 ++ Δ6 = Δ0 ++ (m0 :: Δ5) ++ (B :: Δ3) ++ [] ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_RI.
+  * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, (Δ0 ++ m0 :: Δ4) ++ B :: Δ3 ++ Δ6). split.
+    assert (Δ0 ++ m0 :: Δ4 ++ A --> B :: Δ3 ++ Δ6 = (Δ0 ++ m0 :: Δ4) ++ A --> B :: Δ3 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpRRule_I.
+    assert ((Δ0 ++ m0 :: Δ4) ++ B :: Δ3 ++ Δ6 = Δ0 ++ (m0 :: Δ4) ++ (B :: Δ3) ++ [] ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Δ0 ++ B :: Δ3 ++ m0 :: Δ4 ++ Δ6 = Δ0 ++ [] ++ (B :: Δ3) ++ (m0 :: Δ4) ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_RI.
+  * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, (Δ0 ++ m1 :: Δ5 ++ m0 :: Δ4) ++ B :: Δ3 ++ Δ6). split.
+    assert (Δ0 ++ m1 :: Δ5 ++ m0 :: Δ4 ++ A --> B :: Δ3 ++ Δ6 = (Δ0 ++ m1 :: Δ5 ++ m0 :: Δ4) ++ A --> B :: Δ3 ++ Δ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpRRule_I.
+    assert (Δ0 ++ B :: Δ3 ++ m0 :: Δ4 ++ m1 :: Δ5 ++ Δ6 = Δ0 ++ (B :: Δ3) ++ (m0 :: Δ4) ++ (m1 :: Δ5) ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert ((Δ0 ++ m1 :: Δ5 ++ m0 :: Δ4) ++ B :: Δ3 ++ Δ6 = Δ0 ++ (m1 :: Δ5) ++ (m0 :: Δ4) ++ (B :: Δ3) ++ Δ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_RI.
+  * exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ Δ6). split. repeat rewrite <- app_assoc. apply ImpRRule_I.
+    apply list_exch_R_id.
+  * exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ m0 :: Δ5 ++ Δ6). split. repeat rewrite <- app_assoc. apply ImpRRule_I.
+    apply list_exch_R_id.
+  * exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ m0 :: Δ4 ++ Δ6). split. repeat rewrite <- app_assoc. apply ImpRRule_I.
+    apply list_exch_R_id.
+  * exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ m1 :: Δ5 ++ m0 :: Δ4 ++ Δ6). split.
+    repeat rewrite <- app_assoc. apply ImpRRule_I.
+    assert (Δ0 ++ B :: x ++ m0 :: Δ4 ++ m1 :: Δ5 ++ Δ6 = (Δ0 ++ B :: x) ++ (m0 :: Δ4) ++ [] ++ (m1 :: Δ5) ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Δ0 ++ B :: x ++ m1 :: Δ5 ++ m0 :: Δ4 ++ Δ6 = (Δ0 ++ B :: x) ++ (m1 :: Δ5) ++ [] ++ (m0 :: Δ4) ++ Δ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_RI.
+  * exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ m0 :: Δ3 ++ Δ6). split. repeat rewrite <- app_assoc. apply ImpRRule_I.
+    apply list_exch_R_id.
+  * exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ m1 :: Δ5 ++ m0 :: Δ3 ++ Δ6). split.
+    repeat rewrite <- app_assoc. apply ImpRRule_I.
+    assert (Δ0 ++ B :: x ++ m0 :: Δ3 ++ m1 :: Δ5 ++ Δ6 = (Δ0 ++ B :: x) ++ (m0 :: Δ3) ++ [] ++ (m1 :: Δ5) ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Δ0 ++ B :: x ++ m1 :: Δ5 ++ m0 :: Δ3 ++ Δ6 = (Δ0 ++ B :: x) ++ (m1 :: Δ5) ++ [] ++ (m0 :: Δ3) ++ Δ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_RI.
+  * exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ m1 :: Δ4 ++ m0 :: Δ3 ++ Δ6). split.
+    repeat rewrite <- app_assoc. apply ImpRRule_I.
+    assert (Δ0 ++ B :: x ++ m0 :: Δ3 ++ m1 :: Δ4 ++ Δ6 = (Δ0 ++ B :: x) ++ (m0 :: Δ3) ++ [] ++ (m1 :: Δ4) ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Δ0 ++ B :: x ++ m1 :: Δ4 ++ m0 :: Δ3 ++ Δ6 = (Δ0 ++ B :: x) ++ (m1 :: Δ4) ++ [] ++ (m0 :: Δ3) ++ Δ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_RI.
+  * exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ m2 :: Δ5 ++ m1 :: Δ4 ++ m0 :: Δ3 ++ Δ6). split.
+    repeat rewrite <- app_assoc. apply ImpRRule_I.
+    assert (Δ0 ++ B :: x ++ m0 :: Δ3 ++ m1 :: Δ4 ++ m2 :: Δ5 ++ Δ6 = (Δ0 ++ B :: x) ++ (m0 :: Δ3) ++ (m1 :: Δ4) ++ (m2 :: Δ5) ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Δ0 ++ B :: x ++ m2 :: Δ5 ++ m1 :: Δ4 ++ m0 :: Δ3 ++ Δ6 = (Δ0 ++ B :: x) ++ (m2 :: Δ5) ++ (m1 :: Δ4) ++ (m0 :: Δ3) ++ Δ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_RI.
+Qed.
+ +
+Lemma ImpL_app_list_exchR : forall s se ps1 ps2,
+  (@list_exch_R s se) ->
+  (ImpLRule [ps1;ps2] s) ->
+  (existsT2 pse1 pse2,
+    (ImpLRule [pse1;pse2] se) *
+    (@list_exch_R ps1 pse1) *
+    (@list_exch_R ps2 pse2)).
+Proof.
+intros s se ps1 ps2 exch. intro RA. inversion RA. inversion exch. subst.
+inversion H. apply app2_find_hole in H2. destruct H2. repeat destruct s ; destruct p ; subst.
+- exists (Γ0 ++ Γ1, Δ2 ++ A :: Δ5 ++ Δ4 ++ Δ3 ++ Δ6).
+  exists (Γ0 ++ B :: Γ1, Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6). split. split. apply ImpLRule_I.
+  assert (Δ2 ++ A :: Δ3 ++ Δ4 ++ Δ5 ++ Δ6 = (Δ2 ++ [A]) ++ Δ3 ++ Δ4 ++ Δ5 ++ Δ6).
+  rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+  assert (Δ2 ++ A :: Δ5 ++ Δ4 ++ Δ3 ++ Δ6 = (Δ2 ++ [A]) ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6).
+  rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+  apply list_exch_RI.
+- apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+  + exists (Γ0 ++ Γ1, (Δ2 ++ Δ5) ++ A :: Δ4 ++ Δ3 ++ Δ6).
+    exists (Γ0 ++ B :: Γ1, Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6).
+    split. split.
+    assert (Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6 = (Δ2 ++ Δ5) ++ Δ4 ++ Δ3 ++ Δ6). rewrite app_assoc.
+    reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+    repeat rewrite <- app_assoc.
+    assert (Δ2 ++ Δ3 ++ A :: Δ4 ++ Δ5 ++ Δ6 = Δ2 ++ Δ3 ++ (A :: Δ4) ++ Δ5 ++ Δ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Δ2 ++ Δ5 ++ A :: Δ4 ++ Δ3 ++ Δ6 = Δ2 ++ Δ5 ++ (A :: Δ4) ++ Δ3 ++ Δ6).
+    reflexivity. rewrite H0. clear H0. apply list_exch_RI. apply list_exch_RI.
+  + apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+    * exists (Γ0 ++ Γ1, (Δ2 ++ Δ5 ++ Δ4) ++ A :: Δ3 ++ Δ6).
+      exists (Γ0 ++ B :: Γ1, Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6). split. split.
+      assert (Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6 = (Δ2 ++ Δ5 ++ Δ4) ++ Δ3 ++ Δ6). repeat rewrite app_assoc.
+      reflexivity. rewrite H0. clear H0. apply ImpLRule_I. repeat rewrite <- app_assoc.
+      assert (Δ2 ++ Δ3 ++ Δ4 ++ A :: Δ5 ++ Δ6 = Δ2 ++ Δ3 ++ (Δ4 ++ [A]) ++ Δ5 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      assert (Δ2 ++ Δ5 ++ Δ4 ++ A :: Δ3 ++ Δ6 = Δ2 ++ Δ5 ++ (Δ4 ++ [A]) ++ Δ3 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI. apply list_exch_RI.
+    * apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+      { repeat rewrite <- app_assoc. exists (Γ0 ++ Γ1, Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ A :: Δ6).
+        exists (Γ0 ++ B :: Γ1, Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6).
+        split. split. repeat rewrite app_assoc. apply ImpLRule_I. apply list_exch_RI.
+        apply list_exch_RI. }
+      { repeat rewrite <- app_assoc. exists (Γ0 ++ Γ1, Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ x0 ++ A :: Δ1).
+        exists (Γ0 ++ B :: Γ1, Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ x0 ++ Δ1). split. split. repeat rewrite app_assoc.
+        apply ImpLRule_I. apply list_exch_RI. apply list_exch_RI. }
+      { repeat rewrite <- app_assoc. exists (Γ0 ++ Γ1, Δ2 ++ (x ++ A :: x0) ++ Δ4 ++ Δ3 ++ Δ6).
+        exists (Γ0 ++ B :: Γ1, Δ2 ++ x ++ x0 ++ Δ4 ++ Δ3 ++ Δ6). split. split.
+        assert (Δ2 ++ (x ++ A :: x0) ++ Δ4 ++ Δ3 ++ Δ6 = (Δ2 ++ x) ++ A :: x0 ++ Δ4 ++ Δ3 ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Δ2 ++ x ++ x0 ++ Δ4 ++ Δ3 ++ Δ6 = (Δ2 ++ x) ++ x0 ++ Δ4 ++ Δ3 ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        apply ImpLRule_I.
+        assert (Δ2 ++ Δ3 ++ Δ4 ++ x ++ A :: x0 ++ Δ6 = Δ2 ++ Δ3 ++ Δ4 ++ (x ++ A :: x0) ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply list_exch_RI.
+        assert (Δ2 ++ Δ3 ++ Δ4 ++ x ++ x0 ++ Δ6 = Δ2 ++ Δ3 ++ Δ4 ++ (x ++ x0) ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Δ2 ++ x ++ x0 ++ Δ4 ++ Δ3 ++ Δ6 = Δ2 ++ (x ++ x0) ++ Δ4 ++ Δ3 ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply list_exch_RI. }
+    * repeat rewrite <- app_assoc. exists (Γ0 ++ Γ1, Δ2 ++ Δ5 ++ (x0 ++ A :: x) ++ Δ3 ++ Δ6).
+      exists (Γ0 ++ B :: Γ1, Δ2 ++ Δ5 ++ (x0 ++ x) ++ Δ3 ++ Δ6). split. split.
+      assert (Δ2 ++ Δ5 ++ (x0 ++ A :: x) ++ Δ3 ++ Δ6 = (Δ2 ++ Δ5 ++ x0) ++ A :: x ++ Δ3 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      assert (Δ2 ++ Δ5 ++ x0 ++ x ++ Δ3 ++ Δ6 = (Δ2 ++ Δ5 ++ x0) ++ x ++ Δ3 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      assert (Δ2 ++ Δ5 ++ (x0 ++ x) ++ Δ3 ++ Δ6 = (Δ2 ++ Δ5 ++ x0) ++ x ++ Δ3 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      apply ImpLRule_I.
+      assert (Δ2 ++ Δ3 ++ x0 ++ A :: x ++ Δ5 ++ Δ6 = Δ2 ++ Δ3 ++ (x0 ++ A :: x) ++ Δ5 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply list_exch_RI.
+      assert (Δ2 ++ Δ3 ++ x0 ++ x ++ Δ5 ++ Δ6 = Δ2 ++ Δ3 ++ (x0 ++ x) ++ Δ5 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply list_exch_RI.
+  + repeat rewrite <- app_assoc. exists (Γ0 ++ Γ1, Δ2 ++ Δ5 ++ Δ4 ++ (x ++ A :: x0) ++ Δ6).
+    exists (Γ0 ++ B :: Γ1, Δ2 ++ Δ5 ++ Δ4 ++ (x ++ x0) ++ Δ6). split. split.
+    assert (Δ2 ++ Δ5 ++ Δ4 ++ (x ++ A :: x0) ++ Δ6 = (Δ2 ++ Δ5 ++ Δ4 ++ x) ++ A :: x0 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Δ2 ++ Δ5 ++ Δ4 ++ x ++ x0 ++ Δ6 = (Δ2 ++ Δ5 ++ Δ4 ++ x) ++ x0 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Δ2 ++ Δ5 ++ Δ4 ++ (x ++ x0) ++ Δ6 = (Δ2 ++ Δ5 ++ Δ4 ++ x) ++ x0 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    apply ImpLRule_I.
+    assert (Δ2 ++ x ++ A :: x0 ++ Δ4 ++ Δ5 ++ Δ6 = Δ2 ++ (x ++ A :: x0) ++ Δ4 ++ Δ5 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply list_exch_RI.
+    assert (Δ2 ++ x ++ x0 ++ Δ4 ++ Δ5 ++ Δ6 = Δ2 ++ (x ++ x0) ++ Δ4 ++ Δ5 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply list_exch_RI.
+- repeat rewrite <- app_assoc. exists (Γ0 ++ Γ1, Δ0 ++ A :: x ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6).
+  exists (Γ0 ++ B :: Γ1, Δ0 ++ x ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6). split. split. apply ImpLRule_I.
+  assert (Δ0 ++ A :: x ++ Δ3 ++ Δ4 ++ Δ5 ++ Δ6 = (Δ0 ++ A :: x) ++ Δ3 ++ Δ4 ++ Δ5 ++ Δ6).
+  repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+  assert (Δ0 ++ A :: x ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6 = (Δ0 ++ A :: x) ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6).
+  repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+  assert (Δ0 ++ x ++ Δ3 ++ Δ4 ++ Δ5 ++ Δ6 = (Δ0 ++ x) ++ Δ3 ++ Δ4 ++ Δ5 ++ Δ6).
+  repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+  assert (Δ0 ++ x ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6 = (Δ0 ++ x) ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6).
+  repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+Qed.
+ +
+Lemma GLR_app_list_exchR : forall s se ps,
+  (@list_exch_R s se) ->
+  (GLRRule [ps] s) ->
+  (existsT2 pse,
+    (GLRRule [pse] se) *
+    (@list_exch_R ps pse)).
+Proof.
+intros s se ps exch RA. inversion RA. inversion exch. rewrite <- H1 in H2.
+inversion H2. exists (XBoxed_list ++ [Box A], [A]). split.
+- pose (partition_1_element2 Δ2 Δ3 Δ4 Δ5 Δ6 Δ0 Δ1 (Box A) H6). destruct s0.
+  + repeat destruct s0. repeat destruct p. subst. assert (E : (Δ0 ++ Box A :: x0) ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6 = Δ0 ++ Box A :: (x0 ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6)).
+    repeat rewrite <- app_assoc. reflexivity. rewrite E. apply GLRRule_I.
+    * assumption.
+    * assumption.
+  + destruct s0.
+    * repeat destruct s0. repeat destruct p. subst. assert (E: Δ2 ++ Δ5 ++ Δ4 ++ (x ++ Box A :: x0) ++ Δ6 = (Δ2 ++ Δ5 ++ Δ4 ++ x) ++ Box A :: x0 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite E. apply GLRRule_I.
+      { assumption. }
+      { assumption. }
+    * destruct s0.
+      { repeat destruct s0. repeat destruct p. subst. assert (E: Δ2 ++ Δ5 ++ (x ++ Box A :: x0) ++ Δ3 ++ Δ6 = (Δ2 ++ Δ5 ++ x) ++ Box A :: x0 ++ Δ3 ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite E. apply GLRRule_I.
+        - assumption.
+        - assumption. }
+      { destruct s0.
+        - repeat destruct s0. repeat destruct p. subst. assert (E: Δ2 ++ (x ++ Box A :: x0) ++ Δ4 ++ Δ3 ++ Δ6 = (Δ2 ++ x) ++ Box A :: x0 ++ Δ4 ++ Δ3 ++ Δ6).
+          repeat rewrite <- app_assoc. reflexivity. rewrite E. apply GLRRule_I.
+          + assumption.
+          + assumption.
+        - repeat destruct s0. repeat destruct p. subst. assert (E: Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ x ++ Box A :: Δ1 = (Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ x) ++ Box A :: Δ1).
+          repeat rewrite <- app_assoc. reflexivity. rewrite E. apply GLRRule_I.
+          + assumption.
+          + assumption. }
+- apply list_exch_R_id.
+Qed.
+ +
+(* We can now prove the admissibility of list_exchange on the left. *)
+ +
+Theorem GLS_adm_list_exch_L : forall s,
+        (GLS_prv s) ->
+        (forall se, (@list_exch_L s se) ->
+        (GLS_prv se)).
+Proof.
+intros s D. apply derrec_all_rect with
+(Q:= fun x => forall (se : Seq),
+list_exch_L x se ->
+derrec GLS_rules (fun _ : Seq => False)
+  se)
+in D.
+- exact D.
+- intros concl F. inversion F.
+- intros ps concl rule. induction rule.
+  (* IdP *)
+  * intros ders IH se exch. inversion i. apply derI with (ps:=[]).
+    apply IdP.
+    + assert (Permstose: existsT2 eΓ0 eΓ1, se = (eΓ0 ++ # P :: eΓ1, Δ0 ++ # P :: Δ1)).
+      { pose (list_exch_L_permLR exch). subst. destruct s0 with (Γ0:=Γ0) (Γ1:=Γ1) (Δ0:=Δ0) (Δ1:=Δ1)
+      (C:=# P) (D:=# P). auto. exists x. assumption. }
+      destruct Permstose. repeat destruct s0. subst. apply IdPRule_I.
+    + apply dersrec_all in ders. apply dersrec_all. subst. assumption.
+  (* BotL *)
+  * intros ders IH se exch. apply derI with (ps:=ps).
+    + apply BotL. inversion b. symmetry in H0.
+      assert (Permstose: existsT2 eΓ0 eΓ1, se = ((eΓ0 ++ Bot :: eΓ1), Δ)).
+      { apply list_exch_L_permL with (s:=c) (Γ0:=Γ0) (Γ1:=Γ1) (Δ:=Δ). assumption.
+        assumption. }
+      destruct Permstose. destruct s0. subst. apply BotLRule_I.
+    + apply dersrec_all in ders. apply dersrec_all. assumption.
+  (* ImpR *)
+  * intros ders IH se exch. inversion i. subst. pose (ImpR_app_list_exchL exch i).
+    destruct s0. destruct p. apply derI with (ps:=[x]).
+    + apply ImpR. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion i0.
+      inversion i. apply ForallT_inv in IH. apply ForallT_cons.
+      { apply IH. subst. assumption. }
+      { apply ForallT_nil. }
+  (* ImpL *)
+  * intros ders IH se exch. inversion i. subst. pose (ImpL_app_list_exchL exch i).
+    destruct s0. destruct s0. destruct p. destruct p. apply derI with (ps:=[x;x0]).
+    + apply ImpL. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion i0.
+      inversion i. apply ForallT_cons_inv in IH. destruct IH.
+      apply ForallT_inv in f. apply ForallT_cons.
+      { apply d. subst. assumption. }
+      { apply ForallT_cons. apply f. subst. assumption. apply ForallT_nil. }
+  (* GLR *)
+  * intros ders IH se exch. inversion g. subst. pose (GLR_app_list_exchL exch g).
+    destruct s0. destruct p. apply derI with (ps:=[x]).
+    + apply GLR. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion g0.
+      inversion g. apply ForallT_inv in IH. apply ForallT_cons.
+      { apply IH. subst. assumption. }
+      { apply ForallT_nil. }
+Qed.
+ +
+Theorem GLS_adm_list_exch_R : forall s,
+        (GLS_prv s) ->
+        (forall se, (@list_exch_R s se) ->
+        (GLS_prv se)).
+Proof.
+intros s D. apply derrec_all_rect with
+(Q:= fun x => forall (se : Seq),
+list_exch_R x se ->
+derrec GLS_rules (fun _ : Seq => False)
+  se)
+in D.
+- exact D.
+- intros concl F. inversion F.
+- intros ps concl rule. induction rule.
+  (* IdP *)
+  * intros ders IH se exch. inversion i. apply derI with (ps:=[]).
+    apply IdP.
+    + assert (Permstose: existsT2 eΔ0 eΔ1, se = (Γ0 ++ # P :: Γ1, eΔ0 ++ # P :: eΔ1)).
+      { pose (list_exch_R_permLR exch). subst. destruct s0 with (Γ0:=Γ0) (Γ1:=Γ1) (Δ0:=Δ0) (Δ1:=Δ1)
+      (C:=# P) (D:=# P). auto. exists x. assumption. }
+      destruct Permstose. repeat destruct s0. subst. apply IdPRule_I.
+    + apply dersrec_all in ders. apply dersrec_all. subst. assumption.
+  (* BotL *)
+  * intros ders IH se exch. apply derI with (ps:=ps).
+    + apply BotL. inversion b. symmetry in H0.
+      assert (Permstose: existsT2 , se = ((Γ0 ++ Bot :: Γ1), )).
+      { apply list_exch_R_permL with (s:=c) (Γ0:=Γ0) (Γ1:=Γ1) (Δ:=Δ). assumption.
+        assumption. }
+      destruct Permstose. subst. apply BotLRule_I.
+    + apply dersrec_all in ders. apply dersrec_all. assumption.
+  (* ImpR *)
+  * intros ders IH se exch. inversion i. subst. pose (ImpR_app_list_exchR exch i).
+    destruct s0. destruct p. apply derI with (ps:=[x]).
+    + apply ImpR. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion i0.
+      inversion i. apply ForallT_inv in IH. apply ForallT_cons.
+      { apply IH. subst. assumption. }
+      { apply ForallT_nil. }
+  (* ImpL *)
+  * intros ders IH se exch. inversion i. subst. pose (ImpL_app_list_exchR exch i).
+    destruct s0. destruct s0. destruct p. destruct p. apply derI with (ps:=[x;x0]).
+    + apply ImpL. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion i0.
+      inversion i. apply ForallT_cons_inv in IH. destruct IH.
+      apply ForallT_inv in f. apply ForallT_cons.
+      { apply d. subst. assumption. }
+      { apply ForallT_cons. apply f. subst. assumption. apply ForallT_nil. }
+  (* GLR *)
+  * intros ders IH se exch. inversion g. subst. pose (GLR_app_list_exchR exch g).
+    destruct s0. destruct p. apply derI with (ps:=[x]).
+    + apply GLR. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion g0.
+      inversion g. apply ForallT_inv in IH. apply ForallT_cons.
+      { apply IH. subst. assumption. }
+      { apply ForallT_nil. }
+Qed.
+ +
+(* Now we can turn to the derivability of list_exchange. *)
+ +
+Inductive Closure {X: Type} (F : X -> Type) (P : X -> X -> Type) : X -> Type :=
+  | InitClo : forall x, F x -> Closure F P x
+  | IndClo : forall x y, Closure F P y -> (P y x) -> Closure F P x.
+ +
+Inductive ExcClosure (hyps : Seq -> Type) : Seq -> Type :=
+  | InitLExch : forall x, Closure hyps list_exch_L x -> ExcClosure hyps x
+  | InitRExch : forall x, Closure hyps list_exch_R x -> ExcClosure hyps x
+  | IndLExch : forall x y, ExcClosure hyps x -> list_exch_L x y -> ExcClosure hyps y
+  | IndRExch : forall x y, ExcClosure hyps x -> list_exch_R x y -> ExcClosure hyps y.
+ +
+Theorem GLS_der_list_exch_L : forall hyps s,
+        (derrec GLS_rules hyps s) ->
+        (forall se, (@list_exch_L s se) ->
+        (derrec GLS_rules (ExcClosure hyps) se)).
+Proof.
+intros hyps s D. apply derrec_all_rect with
+(Q:= fun x => forall (se : Seq),
+list_exch_L x se ->
+derrec GLS_rules (ExcClosure hyps) se) in D.
+- exact D.
+- intros concl H1 se exch. apply dpI. apply InitLExch. apply IndClo with (y:=concl).
+  apply InitClo. assumption. assumption.
+- intros ps concl rule. induction rule.
+  (* IdP *)
+  * intros ders IH se exch. inversion i. apply derI with (ps:=[]).
+    apply IdP.
+    + assert (Permstose: existsT2 eΓ0 eΓ1, se = (eΓ0 ++ # P :: eΓ1, Δ0 ++ # P :: Δ1)).
+      { pose (list_exch_L_permLR exch). subst. destruct s0 with (Γ0:=Γ0) (Γ1:=Γ1) (Δ0:=Δ0) (Δ1:=Δ1)
+      (C:=# P) (D:=# P). auto. exists x. assumption. }
+      destruct Permstose. repeat destruct s0. subst. apply IdPRule_I.
+    + apply dersrec_all in ders. apply dersrec_nil.
+  (* BotL *)
+  * intros ders IH se exch. apply derI with (ps:=ps).
+    + apply BotL. inversion b. symmetry in H0.
+      assert (Permstose: existsT2 eΓ0 eΓ1, se = ((eΓ0 ++ Bot :: eΓ1), Δ)).
+      { apply list_exch_L_permL with (s:=c) (Γ0:=Γ0) (Γ1:=Γ1) (Δ:=Δ). assumption.
+        assumption. }
+      destruct Permstose. repeat destruct s0. subst. apply BotLRule_I.
+    + apply dersrec_all in ders. inversion b. apply dersrec_nil.
+  (* ImpR *)
+  * intros ders IH se exch. inversion i. subst. pose (ImpR_app_list_exchL exch i).
+    destruct s0. destruct p. apply derI with (ps:=[x]).
+    + apply ImpR. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion i0.
+      inversion i. apply ForallT_inv in IH. apply ForallT_cons.
+      { apply IH. subst. assumption. }
+      { apply ForallT_nil. }
+  (* ImpL *)
+  * intros ders IH se exch. inversion i. subst. pose (ImpL_app_list_exchL exch i).
+    destruct s0. destruct s0. destruct p. destruct p. apply derI with (ps:=[x;x0]).
+    + apply ImpL. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion i0.
+      inversion i. apply ForallT_cons_inv in IH. destruct IH.
+      apply ForallT_inv in f. apply ForallT_cons.
+      { apply d. subst. assumption. }
+      { apply ForallT_cons. apply f. subst. assumption. apply ForallT_nil. }
+  (* GLR *)
+  * intros ders IH se exch. inversion g. subst. pose (GLR_app_list_exchL exch g).
+    destruct s0. destruct p. apply derI with (ps:=[x]).
+    + apply GLR. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion g0.
+      inversion g. apply ForallT_inv in IH. apply ForallT_cons.
+      { apply IH. subst. assumption. }
+      { apply ForallT_nil. }
+Qed.
+ +
+Theorem GLS_der_list_exch_R : forall hyps s,
+        (derrec GLS_rules hyps s) ->
+        (forall se, (@list_exch_R s se) ->
+        (derrec GLS_rules (ExcClosure hyps) se)).
+Proof.
+intros hyps s D. apply derrec_all_rect with
+(Q:= fun x => forall (se : Seq),
+list_exch_R x se ->
+derrec GLS_rules (ExcClosure hyps) se) in D.
+- exact D.
+- intros concl H1 se exch. apply dpI. apply InitRExch. apply IndClo with (y:=concl).
+  apply InitClo. assumption. assumption.
+- intros ps concl rule. induction rule.
+  (* IdP *)
+  * intros ders IH se exch. inversion i. apply derI with (ps:=[]).
+    apply IdP.
+    + assert (Permstose: existsT2 eΔ0 eΔ1, se = (Γ0 ++ # P :: Γ1, eΔ0 ++ # P :: eΔ1)).
+      { pose (list_exch_R_permLR exch). subst. destruct s0 with (Γ0:=Γ0) (Γ1:=Γ1) (Δ0:=Δ0) (Δ1:=Δ1)
+      (C:=# P) (D:=# P). auto. exists x. assumption. }
+      destruct Permstose. repeat destruct s0. subst. apply IdPRule_I.
+    + apply dersrec_all in ders. apply dersrec_nil.
+  (* BotL *)
+  * intros ders IH se exch. apply derI with (ps:=ps).
+    + apply BotL. inversion b. symmetry in H0.
+      assert (Permstose: existsT2 , se = ((Γ0 ++ Bot :: Γ1), )).
+      { apply list_exch_R_permL with (s:=c) (Γ0:=Γ0) (Γ1:=Γ1) (Δ:=Δ). assumption.
+        assumption. }
+      destruct Permstose. subst. apply BotLRule_I.
+    + apply dersrec_all in ders. inversion b. apply dersrec_nil.
+  (* ImpR *)
+  * intros ders IH se exch. inversion i. subst. pose (ImpR_app_list_exchR exch i).
+    destruct s0. destruct p. apply derI with (ps:=[x]).
+    + apply ImpR. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion i0.
+      inversion i. apply ForallT_inv in IH. apply ForallT_cons.
+      { apply IH. subst. assumption. }
+      { apply ForallT_nil. }
+  (* ImpL *)
+  * intros ders IH se exch. inversion i. subst. pose (ImpL_app_list_exchR exch i).
+    destruct s0. destruct s0. destruct p. destruct p. apply derI with (ps:=[x;x0]).
+    + apply ImpL. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion i0.
+      inversion i. apply ForallT_cons_inv in IH. destruct IH.
+      apply ForallT_inv in f. apply ForallT_cons.
+      { apply d. subst. assumption. }
+      { apply ForallT_cons. apply f. subst. assumption. apply ForallT_nil. }
+  (* GLR *)
+  * intros ders IH se exch. inversion g. subst. pose (GLR_app_list_exchR exch g).
+    destruct s0. destruct p. apply derI with (ps:=[x]).
+    + apply GLR. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion g0.
+      inversion g. apply ForallT_inv in IH. apply ForallT_cons.
+      { apply IH. subst. assumption. }
+      { apply ForallT_nil. }
+Qed.
+ +
+(* In fact, we can prove that exchange is height-preserving admissible. *)
+ +
+Theorem GLS_hpadm_list_exch_R : forall (k : nat) s
+                                  (D0: GLS_prv s),
+        k = (derrec_height D0) ->
+        (forall se, (list_exch_R s se) ->
+        (existsT2 (D1 : GLS_prv se),
+          derrec_height D1 <=k)).
+Proof.
+induction k as [n IH] using (well_founded_induction_type lt_wf).
+intros s0 D0. remember D0 as D0'. destruct D0.
+(* D0 ip a leaf *)
+- inversion f.
+(* D0 is ends with an application of rule *)
+- intros hei se exch. inversion exch.
+  assert (DersNil: dersrec GLS_rules (fun _ : Seq => False) []).
+  apply dersrec_nil. inversion g.
+  (* IdP *)
+  * inversion H1. subst. inversion H5. subst. simpl.
+    assert (In # P (Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4)). assert (In # P (Δ0 ++ Δ1 ++ Δ2 ++ Δ3 ++ Δ4)).
+    rewrite <- H2. apply in_or_app. right. apply in_eq. apply in_app_or in H. apply in_or_app.
+    destruct H. auto. apply in_app_or in H. right. apply in_or_app. destruct H. right. apply in_or_app.
+    right. apply in_or_app. auto. apply in_app_or in H. destruct H. right. apply in_or_app. auto.
+    apply in_app_or in H. destruct H. auto. right. apply in_or_app. right. apply in_or_app. auto.
+    apply in_splitT in H. destruct H. destruct s. rewrite e.
+    assert (IdPRule [] (Γ0 ++ # P :: Γ1, x ++ # P :: x0)). apply IdPRule_I. apply IdP in H.
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[]) (Γ0 ++ # P :: Γ1, x ++ # P :: x0) H DersNil). exists d0. simpl. rewrite dersrec_height_nil.
+    lia. reflexivity.
+  (* BotL *)
+  * inversion H1. subst. inversion H5. subst. simpl.
+    assert (BotLRule [] (Γ0 ++ :: Γ1, Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4)). apply BotLRule_I. apply BotL in H.
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[]) (Γ0 ++ :: Γ1, Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4) H DersNil). exists d0. simpl. rewrite dersrec_height_nil.
+    lia. reflexivity.
+  (* ImpR *)
+  * inversion H1. subst. inversion H5. subst. simpl. simpl in IH.
+    pose (ImpR_app_list_exchR exch H1). destruct s. destruct p.
+    apply ImpR in i. assert (J0: dersrec_height d = dersrec_height d). reflexivity.
+    pose (dersrec_derrec_height d J0). destruct s.
+    assert (E: derrec_height x0 < S (dersrec_height d)). lia.
+    assert (E1: derrec_height x0 = derrec_height x0). auto.
+    pose (IH (derrec_height x0) E (Γ0 ++ A :: Γ1, Δ5 ++ B :: Δ6) x0 E1 x l).
+    destruct s. pose (dlCons x1 DersNil).
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x]) (Γ0 ++ Γ1, Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4) i d0). exists d1. simpl.
+    rewrite dersrec_height_nil. rewrite Nat.max_0_r. lia. reflexivity.
+  (* ImpL *)
+  * inversion H1. subst. inversion H5. subst. simpl. simpl in IH.
+    pose (ImpL_app_list_exchR exch H1). repeat destruct s. repeat destruct p.
+    apply ImpL in i. assert (J0: dersrec_height d = dersrec_height d). reflexivity.
+    pose (dersrec_derrec2_height d J0). repeat destruct s.
+    assert (E: derrec_height x1 < S (dersrec_height d)). lia.
+    assert (E1: derrec_height x1 = derrec_height x1). auto.
+    pose (IH (derrec_height x1) E (Γ0 ++ Γ1, Δ5 ++ A :: Δ6) x1 E1 x l0).
+    destruct s.
+    assert (E2: derrec_height x2 < S (dersrec_height d)). lia.
+    assert (E3: derrec_height x2 = derrec_height x2). auto.
+    pose (IH (derrec_height x2) E2 (Γ0 ++ B :: Γ1, Δ5 ++ Δ6) x2 E3 x0 l).
+    destruct s. pose (dlCons x4 DersNil). pose (dlCons x3 d0).
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x; x0]) (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4) i d1). exists d2. simpl.
+    rewrite dersrec_height_nil. rewrite Nat.max_0_r. lia. reflexivity.
+  (* GLR *)
+  * inversion X. subst. inversion H5. subst. simpl. simpl in IH.
+    pose (GLR_app_list_exchR exch X). destruct s. destruct p.
+    apply GLR in g0. assert (J0: dersrec_height d = dersrec_height d). reflexivity.
+    pose (dersrec_derrec_height d J0). destruct s.
+    assert (E: derrec_height x0 < S (dersrec_height d)). lia.
+    assert (E1: derrec_height x0 = derrec_height x0). auto.
+    pose (IH (derrec_height x0) E (XBoxed_list ++ [Box A], [A]) x0 E1 x l).
+    destruct s. pose (dlCons x1 DersNil).
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x]) (Γ, Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4) g0 d0). exists d1. simpl.
+    rewrite dersrec_height_nil. rewrite Nat.max_0_r. lia. reflexivity.
+Qed.
+ +
+Theorem GLS_hpadm_list_exch_L : forall (k : nat) s
+                                  (D0: GLS_prv s),
+        k = (derrec_height D0) ->
+        (forall se, (list_exch_L s se) ->
+        (existsT2 (D1 : GLS_prv se),
+          derrec_height D1 <=k)).
+Proof.
+induction k as [n IH] using (well_founded_induction_type lt_wf).
+intros s0 D0. remember D0 as D0'. destruct D0.
+(* D0 ip a leaf *)
+- inversion f.
+(* D0 is ends with an application of rule *)
+- intros hei se exch. inversion exch.
+  assert (DersNil: dersrec GLS_rules (fun _ : Seq => False) []).
+  apply dersrec_nil. inversion g.
+  (* IdP *)
+  * inversion H1. subst. inversion H5. subst. simpl.
+    assert (In # P (Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4)). assert (In # P (Γ0 ++ Γ1 ++ Γ2 ++ Γ3 ++ Γ4)).
+    rewrite <- H0. apply in_or_app. right. apply in_eq. apply in_app_or in H. apply in_or_app.
+    destruct H. auto. apply in_app_or in H. right. apply in_or_app. destruct H. right. apply in_or_app.
+    right. apply in_or_app. auto. apply in_app_or in H. destruct H. right. apply in_or_app. auto.
+    apply in_app_or in H. destruct H. auto. right. apply in_or_app. right. apply in_or_app. auto.
+    apply in_splitT in H. destruct H. destruct s. rewrite e.
+    assert (IdPRule [] (x ++ # P :: x0, Δ0 ++ # P :: Δ1)). apply IdPRule_I. apply IdP in H.
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[]) (x ++ # P :: x0, Δ0 ++ # P :: Δ1) H DersNil). exists d0. simpl. rewrite dersrec_height_nil.
+    lia. reflexivity.
+  (* BotL *)
+  * inversion H1. subst. inversion H5. subst. simpl.
+    assert (In () (Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4)). assert (In () (Γ0 ++ Γ1 ++ Γ2 ++ Γ3 ++ Γ4)).
+    rewrite <- H0. apply in_or_app. right. apply in_eq. apply in_app_or in H. apply in_or_app.
+    destruct H. auto. apply in_app_or in H. right. apply in_or_app. destruct H. right. apply in_or_app.
+    right. apply in_or_app. auto. apply in_app_or in H. destruct H. right. apply in_or_app. auto.
+    apply in_app_or in H. destruct H. auto. right. apply in_or_app. right. apply in_or_app. auto.
+    apply in_splitT in H. destruct H. destruct s. rewrite e.
+    assert (BotLRule [] (x ++ :: x0, Δ)). apply BotLRule_I. apply BotL in H.
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[]) (x ++ :: x0, Δ) H DersNil). exists d0. simpl. rewrite dersrec_height_nil.
+    lia. reflexivity.
+  (* ImpR *)
+  * inversion H1. subst. inversion H5. subst. simpl. simpl in IH.
+    pose (ImpR_app_list_exchL exch H1). destruct s. destruct p.
+    apply ImpR in i. assert (J0: dersrec_height d = dersrec_height d). reflexivity.
+    pose (dersrec_derrec_height d J0). destruct s.
+    assert (E: derrec_height x0 < S (dersrec_height d)). lia.
+    assert (E1: derrec_height x0 = derrec_height x0). auto.
+    pose (IH (derrec_height x0) E (Γ5 ++ A :: Γ6, Δ0 ++ B :: Δ1) x0 E1 x l).
+    destruct s. pose (dlCons x1 DersNil).
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x]) (Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4, Δ0 ++ A --> B :: Δ1) i d0). exists d1. simpl.
+    rewrite dersrec_height_nil. rewrite Nat.max_0_r. lia. reflexivity.
+  (* ImpL *)
+  * inversion H1. subst. inversion H5. subst. simpl. simpl in IH.
+    pose (ImpL_app_list_exchL exch H1). repeat destruct s. repeat destruct p.
+    apply ImpL in i. assert (J0: dersrec_height d = dersrec_height d). reflexivity.
+    pose (dersrec_derrec2_height d J0). repeat destruct s.
+    assert (E: derrec_height x1 < S (dersrec_height d)). lia.
+    assert (E1: derrec_height x1 = derrec_height x1). auto.
+    pose (IH (derrec_height x1) E (Γ5 ++ Γ6, Δ0 ++ A :: Δ1) x1 E1 x l0).
+    destruct s.
+    assert (E2: derrec_height x2 < S (dersrec_height d)). lia.
+    assert (E3: derrec_height x2 = derrec_height x2). auto.
+    pose (IH (derrec_height x2) E2 (Γ5 ++ B :: Γ6, Δ0 ++ Δ1) x2 E3 x0 l).
+    destruct s. pose (dlCons x4 DersNil). pose (dlCons x3 d0).
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x; x0]) (Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4, Δ0 ++ Δ1) i d1). exists d2. simpl.
+    rewrite dersrec_height_nil. rewrite Nat.max_0_r. lia. reflexivity.
+  (* GLR *)
+  * inversion X. subst. inversion H5. subst. simpl. simpl in IH.
+    pose (GLR_app_list_exchL exch X). destruct s. destruct p.
+    apply GLR in g0. assert (J0: dersrec_height d = dersrec_height d). reflexivity.
+    pose (dersrec_derrec_height d J0). destruct s.
+    assert (E: derrec_height x0 < S (dersrec_height d)). lia.
+    assert (E1: derrec_height x0 = derrec_height x0). auto.
+    pose (IH (derrec_height x0) E (XBoxed_list ++ [Box A], [A]) x0 E1 x l).
+    destruct s. pose (dlCons x1 DersNil).
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x]) (Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4, Δ0 ++ Box A :: Δ1) g0 d0). exists d1. simpl.
+    rewrite dersrec_height_nil. rewrite Nat.max_0_r. lia. reflexivity.
+Qed.
+ +
+Theorem GLS_adm_list_exch_LR : forall s (D0: GLS_prv s),
+        (forall se, ((list_exch_L s se) -> (GLS_prv se)) *
+                        ((list_exch_R s se) -> (GLS_prv se))).
+Proof.
+intros. assert (J1: derrec_height D0 = derrec_height D0). auto. split ; intro.
+- pose (@GLS_hpadm_list_exch_L (derrec_height D0) s D0 J1 se H). destruct s0 ; auto.
+- pose (@GLS_hpadm_list_exch_R (derrec_height D0) s D0 J1 se H). destruct s0 ; auto.
+Qed.
+ +
+
+
+ +
+ + + diff --git a/GL.GLS.GLS_export.html b/GL.GLS.GLS_export.html new file mode 100644 index 0000000..76a4cc8 --- /dev/null +++ b/GL.GLS.GLS_export.html @@ -0,0 +1,51 @@ + + + + + + + + + + + + + +
+
+

GL.GLS.GLS_export

+ +
+Require Export GLS_calcs.
+Require Export GLS_dec.
+Require Export GLS_exch.
+Require Export GLS_ctr.
+Require Export GLS_wkn.
+Require Export GLS_inv_ImpR_ImpL.
+Require Export DLW_wf_lex.
+Require Export GLS_termination_measure.
+Require Export GLS_der_dec.
+Require Export GLS_additive_cut.
+Require Export GLS_cut_elim.
+
+
+ +
+ + + diff --git a/GL.GLS.GLS_inv_ImpR_ImpL.html b/GL.GLS.GLS_inv_ImpR_ImpL.html new file mode 100644 index 0000000..2ca110d --- /dev/null +++ b/GL.GLS.GLS_inv_ImpR_ImpL.html @@ -0,0 +1,734 @@ + + + + + + + + + + + + + +
+
+

GL.GLS.GLS_inv_ImpR_ImpL

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat Arith.
+Require Import Lia.
+ +
+Require Import GLS_calcs.
+Require Import GLS_exch.
+Require Import GLS_wkn.
+Require Import GLS_dec.
+ +
+Set Implicit Arguments.
+ +
+Lemma remove_rest_gen_ext : forall l A, rest_gen_ext [A] (remove eq_dec_form A l) l.
+Proof.
+induction l ; intros.
+- simpl. apply univ_gen_ext_nil.
+- simpl. destruct (eq_dec_form A a).
+  * subst. apply univ_gen_ext_extra. apply InT_eq. apply IHl.
+  * apply univ_gen_ext_cons. apply IHl.
+Qed.
+ +
+Theorem derrec_height_False_ge_1 : forall s, forall (D : GLS_prv s), 1 <= derrec_height D.
+Proof.
+intros s D.
+induction D.
+- destruct p.
+- simpl. lia.
+Qed.
+ +
+Lemma rest_nobox_gen_ext_trans : forall (A B : MPropF) l0 l1 l2, ((In (Imp A B) l0) -> False) ->
+                                                    (nobox_gen_ext l0 l1) ->
+                                                    (rest_gen_ext [Imp A B] l2 l1) ->
+                                                    (nobox_gen_ext l0 l2).
+Proof.
+intros A B l0 l1 l2 H1 H2. generalize dependent l2.
+induction H2.
+- intros. inversion X. apply univ_gen_ext_nil.
+- intros. inversion X.
+  * subst. apply univ_gen_ext_cons. apply IHuniv_gen_ext. intro. apply H1.
+    apply in_cons. assumption. assumption.
+  * subst. inversion H3. subst. exfalso. apply H1. apply in_eq.
+    inversion H0.
+- intros. inversion X.
+  * subst. apply univ_gen_ext_extra. assumption. apply IHuniv_gen_ext ; assumption.
+  * subst. apply IHuniv_gen_ext ; assumption.
+Qed.
+ +
+Theorem ImpR_ImpL_hpinv : forall (k : nat) concl
+        (D0 : GLS_prv concl),
+        k = (derrec_height D0) ->
+          ((forall prem, ((ImpRRule [prem] concl) ->
+          existsT2 (D1 : GLS_prv prem),
+          derrec_height D1 <= k))) *
+          ((forall prem1 prem2, ((ImpLRule [prem1; prem2] concl) ->
+          existsT2 (D1 : GLS_prv prem1)
+                   (D2 : GLS_prv prem2),
+          (derrec_height D1 <= k) * (derrec_height D2 <= k)))).
+Proof.
+assert (DersNilF: dersrec (GLS_rules) (fun _ : Seq => False) []).
+apply dersrec_nil.
+induction k as [n IH] using (well_founded_induction_type lt_wf).
+intros s D0. remember D0 as D0'. destruct D0.
+(* D0 is a leaf *)
+- destruct f.
+(* D0 is ends with an application of rule *)
+- intros hei. split.
+{ intros prem RA. inversion RA. subst.
+  inversion g ; subst.
+  (* IdP *)
+  * inversion H. subst. assert (InT # P (Γ0 ++ Γ1)).
+    rewrite <- H2. apply InT_or_app. right. apply InT_eq. assert (InT # P (Γ0 ++ A :: Γ1)).
+    apply InT_app_or in H0. destruct H0. apply InT_or_app. auto. apply InT_or_app. right.
+    apply InT_cons. assumption. apply InT_split in H1. destruct H1. destruct s. rewrite e.
+    assert (InT # P (Δ0 ++ B :: Δ1)). assert (InT # P (Δ2 ++ # P :: Δ3)).
+    apply InT_or_app. right. apply InT_eq. rewrite H3 in H1. apply InT_app_or in H1.
+    destruct H1. apply InT_or_app. auto. inversion i. inversion H4. apply InT_or_app. right.
+    apply InT_cons. assumption. apply InT_split in H1. destruct H1. destruct s.
+    rewrite e0. assert (IdPRule [] (x ++ # P :: x0, x1 ++ # P :: x2)).
+    apply IdPRule_I. apply IdP in H1.
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[]) (x ++ # P :: x0, x1 ++ # P :: x2) H1 DersNilF). exists d0.
+    simpl. rewrite dersrec_height_nil. lia. reflexivity.
+  (* BotL *)
+  * inversion H. subst. assert (InT () (Γ0 ++ Γ1)).
+    rewrite <- H2. apply InT_or_app. right. apply InT_eq. assert (InT () (Γ0 ++ A :: Γ1)).
+    apply InT_app_or in H0. destruct H0. apply InT_or_app. auto. apply InT_or_app. right.
+    apply InT_cons. assumption. apply InT_split in H1. destruct H1. destruct s. rewrite e.
+    assert (BotLRule [] (x ++ :: x0, Δ0 ++ B :: Δ1)).
+    apply BotLRule_I. apply BotL in H1.
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[]) (x ++ :: x0, Δ0 ++ B :: Δ1) H1 DersNilF). exists d0.
+    simpl. rewrite dersrec_height_nil. lia. reflexivity.
+  (* ImpR *)
+  * inversion H. subst. apply app2_find_hole in H3. destruct H3. repeat destruct s ; destruct p ; subst.
+    + inversion e0. subst. assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+      pose (@dersrec_derrec_height (dersrec_height d) _ _ _ _ d J30). destruct s.
+      assert (J1: list_exch_L (Γ2 ++ A0 :: Γ3, Δ2 ++ B0 :: Δ3) (A0 :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3)).
+      assert (Γ2 ++ A0 :: Γ3 = [] ++ [] ++ Γ2 ++ [A0] ++ Γ3). reflexivity.
+      rewrite H0. clear H0.
+      assert (A0 :: Γ0 ++ Γ1 = [] ++ [A0] ++ Γ2 ++ [] ++ Γ3). simpl. rewrite H2. reflexivity.
+      rewrite H0. clear H0. apply list_exch_LI.
+      assert (J20: derrec_height x0 = derrec_height x0). reflexivity.
+      pose (GLS_hpadm_list_exch_L x0 J20 J1). destruct s.
+      assert (J2: list_exch_L (A0 :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3) (Γ0 ++ A0 :: Γ1, Δ2 ++ B0 :: Δ3)).
+      assert ((A0 :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3) = ([] ++ [A0] ++ Γ0 ++ [] ++ Γ1, Δ2 ++ B0 :: Δ3)).
+      reflexivity. assert ((Γ0 ++ A0 :: Γ1, Δ2 ++ B0 :: Δ3) = ([] ++ [] ++ Γ0 ++ [A0] ++ Γ1, Δ2 ++ B0 :: Δ3)).
+      reflexivity. rewrite H1. rewrite H0. clear H1. clear H0. apply list_exch_LI.
+      assert (J21: derrec_height x1 = derrec_height x1). reflexivity.
+      pose (GLS_hpadm_list_exch_L x1 J21 J2). destruct s. exists x2.
+      simpl. lia.
+    + destruct x.
+      { simpl in e0. inversion e0. subst. assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+        pose (@dersrec_derrec_height (dersrec_height d) _ _ _ _ d J30). destruct s.
+        assert (J1: list_exch_L (Γ2 ++ A :: Γ3, Δ2 ++ B :: Δ1) (A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ1)).
+        assert (Γ2 ++ A :: Γ3 = [] ++ [] ++ Γ2 ++ [A] ++ Γ3). reflexivity.
+        rewrite H0. clear H0.
+        assert (A :: Γ0 ++ Γ1 = [] ++ [A] ++ Γ2 ++ [] ++ Γ3). simpl. rewrite H2. reflexivity.
+        rewrite H0. clear H0. apply list_exch_LI.
+        assert (J20: derrec_height x = derrec_height x). reflexivity.
+        pose (GLS_hpadm_list_exch_L x J20 J1). destruct s.
+        assert (J2: list_exch_L (A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ1) (Γ0 ++ A :: Γ1, (Δ2 ++ []) ++ B :: Δ1)).
+        assert ((A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ1) = ([] ++ [A] ++ Γ0 ++ [] ++ Γ1, Δ2 ++ B :: Δ1)).
+        reflexivity. assert ((Γ0 ++ A :: Γ1, (Δ2 ++ []) ++ B :: Δ1) = ([] ++ [] ++ Γ0 ++ [A] ++ Γ1, Δ2 ++ B :: Δ1)).
+        rewrite app_nil_r. reflexivity. rewrite H1. rewrite H0. clear H1. clear H0. apply list_exch_LI.
+        assert (J21: derrec_height x0 = derrec_height x0). reflexivity.
+        pose (GLS_hpadm_list_exch_L x0 J21 J2). destruct s. exists x1.
+        simpl. lia. }
+      { inversion e0. subst. assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+        pose (@dersrec_derrec_height (dersrec_height d) _ _ _ _ d J30). destruct s.
+        assert (J1: list_exch_L (Γ2 ++ A0 :: Γ3, Δ2 ++ B0 :: x ++ A --> B :: Δ1) (A0 :: Γ0 ++ Γ1, Δ2 ++ B0 :: x ++ A --> B :: Δ1)).
+        assert (Γ2 ++ A0 :: Γ3 = [] ++ [] ++ Γ2 ++ [A0] ++ Γ3). reflexivity.
+        rewrite H0. clear H0.
+        assert (A0 :: Γ0 ++ Γ1 = [] ++ [A0] ++ Γ2 ++ [] ++ Γ3). simpl. rewrite H2. reflexivity.
+        rewrite H0. clear H0. apply list_exch_LI.
+        assert (J20: derrec_height x0 = derrec_height x0). reflexivity.
+        pose (GLS_hpadm_list_exch_L x0 J20 J1). destruct s. simpl in IH. simpl.
+        assert (J2: derrec_height x1 < S (dersrec_height d)). lia.
+        assert (J3: derrec_height x1 = derrec_height x1). reflexivity.
+        assert (J4: ImpRRule [(A0 :: Γ0 ++ A :: Γ1, Δ2 ++ B0 :: x ++ B :: Δ1)] (A0 :: Γ0 ++ Γ1, Δ2 ++ B0 :: x ++ A --> B :: Δ1)).
+        assert (A0 :: Γ0 ++ A :: Γ1 = (A0 :: Γ0) ++ A :: Γ1). reflexivity. rewrite H0. clear H0.
+        assert (A0 :: Γ0 ++ Γ1 = (A0 :: Γ0) ++ Γ1). reflexivity. rewrite H0. clear H0.
+        assert (Δ2 ++ B0 :: x ++ B :: Δ1 = (Δ2 ++ B0 :: x) ++ B :: Δ1). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Δ2 ++ B0 :: x ++ A --> B :: Δ1 = (Δ2 ++ B0 :: x) ++ A --> B :: Δ1). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+        pose (IH _ J2 _ _ J3). destruct p. pose (s _ J4). clear s0. destruct s1. clear s.
+        assert (existsT2 (x3 : derrec GLS_rules (fun _ : Seq => False)
+        (Γ0 ++ A :: Γ1, (Δ2 ++ A0 --> B0 :: x) ++ B :: Δ1)), derrec_height x3 <= S (dersrec_height d)).
+        assert (ImpRRule [(A0 :: Γ0 ++ A :: Γ1, Δ2 ++ B0 :: x ++ B :: Δ1)] (Γ0 ++ A :: Γ1, (Δ2 ++ A0 --> B0 :: x) ++ B :: Δ1)).
+        assert (A0 :: Γ0 ++ A :: Γ1 = [] ++ A0 :: Γ0 ++ A :: Γ1). reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ A :: Γ1 = [] ++ Γ0 ++ A :: Γ1). reflexivity. rewrite H0. clear H0. repeat rewrite <- app_assoc.
+        apply ImpRRule_I. apply ImpR in H0 ; try intro ; try apply f0 ; try auto ; try assumption.
+        pose (dlCons x2 DersNilF).
+        pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[(A0 :: Γ0 ++ A :: Γ1, Δ2 ++ B0 :: x ++ B :: Δ1)]) (Γ0 ++ A :: Γ1, (Δ2 ++ A0 --> B0 :: x) ++ B :: Δ1) H0 d0).
+        exists d1. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+        destruct X. exists x3. lia. }
+    + destruct x.
+      { simpl in e0. inversion e0. subst. assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+        pose (@dersrec_derrec_height (dersrec_height d) _ _ _ _ d J30). destruct s.
+        assert (J1: list_exch_L (Γ2 ++ A0 :: Γ3, (Δ0 ++ []) ++ B0 :: Δ3) (A0 :: Γ0 ++ Γ1, Δ0 ++ B0 :: Δ3)).
+        rewrite app_nil_r.
+        assert (Γ2 ++ A0 :: Γ3 = [] ++ [] ++ Γ2 ++ [A0] ++ Γ3). reflexivity.
+        rewrite H0. clear H0.
+        assert (A0 :: Γ0 ++ Γ1 = [] ++ [A0] ++ Γ2 ++ [] ++ Γ3). simpl. rewrite H2. reflexivity.
+        rewrite H0. clear H0. apply list_exch_LI.
+        assert (J20: derrec_height x = derrec_height x). reflexivity.
+        pose (GLS_hpadm_list_exch_L x J20 J1). destruct s.
+        assert (J2: list_exch_L (A0 :: Γ0 ++ Γ1, Δ0 ++ B0 :: Δ3) (Γ0 ++ A0 :: Γ1, Δ0 ++ B0 :: Δ3)).
+        assert ((A0 :: Γ0 ++ Γ1, Δ0 ++ B0 :: Δ3) = ([] ++ [A0] ++ Γ0 ++ [] ++ Γ1, Δ0 ++ B0 :: Δ3)).
+        reflexivity. assert ((Γ0 ++ A0 :: Γ1, Δ0 ++ B0 :: Δ3) = ([] ++ [] ++ Γ0 ++ [A0] ++ Γ1, Δ0 ++ B0 :: Δ3)).
+        reflexivity. rewrite H1. rewrite H0. clear H1. clear H0. apply list_exch_LI.
+        assert (J21: derrec_height x0 = derrec_height x0). reflexivity.
+        pose (GLS_hpadm_list_exch_L x0 J21 J2). destruct s. exists x1.
+        simpl. lia. }
+      { inversion e0. subst. assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+        pose (@dersrec_derrec_height (dersrec_height d) _ _ _ _ d J30). destruct s. simpl.
+        assert (J1: list_exch_L (Γ2 ++ A0 :: Γ3, (Δ0 ++ A --> B :: x) ++ B0 :: Δ3) (A0 :: Γ0 ++ Γ1, Δ0 ++ A --> B :: x ++ B0 :: Δ3)).
+        repeat rewrite <- app_assoc.
+        assert (Γ2 ++ A0 :: Γ3 = [] ++ [] ++ Γ2 ++ [A0] ++ Γ3). reflexivity.
+        rewrite H0. clear H0.
+        assert (A0 :: Γ0 ++ Γ1 = [] ++ [A0] ++ Γ2 ++ [] ++ Γ3). simpl. rewrite H2. reflexivity.
+        rewrite H0. clear H0. apply list_exch_LI.
+        assert (J20: derrec_height x0 = derrec_height x0). reflexivity.
+        pose (GLS_hpadm_list_exch_L x0 J20 J1). destruct s. simpl in IH. simpl.
+        assert (J2: derrec_height x1 < S (dersrec_height d)). lia.
+        assert (J3: derrec_height x1 = derrec_height x1). reflexivity.
+        assert (J4: ImpRRule [(A0 :: Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ B0 :: Δ3)] (A0 :: Γ0 ++ Γ1, Δ0 ++ A --> B :: x ++ B0 :: Δ3)).
+        assert (A0 :: Γ0 ++ A :: Γ1 = (A0 :: Γ0) ++ A :: Γ1). reflexivity. rewrite H0. clear H0.
+        assert (A0 :: Γ0 ++ Γ1 = (A0 :: Γ0) ++ Γ1). reflexivity. rewrite H0. clear H0.
+        apply ImpRRule_I.
+        pose (IH _ J2 _ _ J3). destruct p. pose (s _ J4). clear s0. destruct s1. clear s.
+        assert (ImpRRule [(A0 :: Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ B0 :: Δ3)] (Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ A0 --> B0 :: Δ3)).
+        assert (A0 :: Γ0 ++ A :: Γ1 = [] ++ A0 :: Γ0 ++ A :: Γ1). reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ A :: Γ1 = [] ++ Γ0 ++ A :: Γ1). reflexivity. rewrite H0. clear H0. repeat rewrite <- app_assoc.
+        assert (Δ0 ++ B :: x ++ B0 :: Δ3 = (Δ0 ++ B :: x) ++ B0 :: Δ3). rewrite <- app_assoc. reflexivity.
+        rewrite H0. clear H0.
+        assert (Δ0 ++ B :: x ++ A0 --> B0 :: Δ3 = (Δ0 ++ B :: x) ++ A0 --> B0 :: Δ3). rewrite <- app_assoc. reflexivity.
+        rewrite H0. clear H0.
+        apply ImpRRule_I. apply ImpR in H0 ; try intro ; try apply f0 ; try auto ; try assumption.
+        pose (dlCons x2 DersNilF).
+        pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[(A0 :: Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ B0 :: Δ3)]) (Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ A0 --> B0 :: Δ3) H0 d0).
+        exists d1. simpl. rewrite dersrec_height_nil. lia. reflexivity. }
+  (* ImpL *)
+  * inversion H. subst. assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+    pose (@dersrec_derrec2_height (dersrec_height d) _ _ _ _ _ d J30). repeat destruct s. simpl.
+    assert (J1: ImpRRule [(A :: Γ2 ++ B0 :: Γ3, Δ0 ++ B :: Δ1)] (Γ2 ++ B0 :: Γ3, Δ2 ++ Δ3)).
+    rewrite H3. assert (A :: Γ2 ++ B0 :: Γ3 = [] ++ A :: Γ2 ++ B0 :: Γ3). reflexivity.
+    rewrite H0. clear H0. assert (Γ2 ++ B0 :: Γ3 = [] ++ Γ2 ++ B0 :: Γ3). reflexivity.
+    rewrite H0. clear H0. apply ImpRRule_I. simpl in IH.
+    assert (J2: derrec_height x0 < S (dersrec_height d)). lia.
+    assert (J3: derrec_height x0 = derrec_height x0). reflexivity.
+    pose (IH _ J2 _ _ J3). destruct p. clear s0. pose (s _ J1). destruct s0. clear s.
+    assert (J7: list_exch_R (Γ2 ++ Γ3, Δ2 ++ A0 :: Δ3) (Γ2 ++ Γ3, A0 :: Δ0 ++ A --> B :: Δ1)).
+    rewrite <- H3. assert (Δ2 ++ A0 :: Δ3 = [] ++ [] ++ Δ2 ++ [A0] ++ Δ3). reflexivity.
+    rewrite H0. clear H0. assert (A0 :: Δ2 ++ Δ3 = [] ++ [A0] ++ Δ2 ++ [] ++ Δ3). reflexivity.
+    rewrite H0. clear H0. apply list_exch_RI.
+    assert (J8: derrec_height x = derrec_height x). reflexivity.
+    pose (GLS_hpadm_list_exch_R x J8 J7). destruct s.
+    assert (J4: ImpRRule [(A :: Γ2 ++ Γ3, A0 :: Δ0 ++ B :: Δ1)] (Γ2 ++ Γ3, A0 :: Δ0 ++ A --> B :: Δ1)).
+    assert (A :: Γ2 ++ Γ3 = [] ++ A :: Γ2 ++ Γ3). reflexivity.
+    rewrite H0. clear H0. assert ((Γ2 ++ Γ3, A0 :: Δ0 ++ A --> B :: Δ1) = ([] ++ Γ2 ++ Γ3, A0 :: Δ0 ++ A --> B :: Δ1)). reflexivity.
+    rewrite H0. clear H0. assert (A0 :: Δ0 ++ B :: Δ1 = (A0 :: Δ0) ++ B :: Δ1). reflexivity.
+    rewrite H0. clear H0. assert (A0 :: Δ0 ++ A --> B :: Δ1 = (A0 :: Δ0) ++ A --> B :: Δ1). reflexivity.
+    rewrite H0. clear H0. apply ImpRRule_I. simpl in IH.
+    assert (J5: derrec_height x2 < S (dersrec_height d)). lia.
+    assert (J6: derrec_height x2 = derrec_height x2). reflexivity.
+    pose (IH _ J5 _ _ J6). destruct p. clear s0. pose (s _ J4). destruct s0. clear s.
+    assert (ImpLRule [(A :: Γ2 ++ Γ3, A0 :: Δ0 ++ B :: Δ1); (A :: Γ2 ++ B0 :: Γ3, Δ0 ++ B :: Δ1)]
+    (A :: Γ2 ++ A0 --> B0 :: Γ3, Δ0 ++ B :: Δ1)).
+    assert (A :: Γ2 ++ Γ3 = (A :: Γ2) ++ Γ3). reflexivity. rewrite H0. clear H0.
+    assert (A :: Γ2 ++ B0 :: Γ3 = (A :: Γ2) ++ B0 :: Γ3). reflexivity. rewrite H0. clear H0.
+    assert (A :: Γ2 ++ A0 --> B0 :: Γ3 = (A :: Γ2) ++ A0 --> B0 :: Γ3). reflexivity. rewrite H0. clear H0.
+    assert (Δ0 ++ B :: Δ1 = [] ++ Δ0 ++ B :: Δ1). reflexivity. rewrite H0. clear H0.
+    assert (A0 :: [] ++ Δ0 ++ B :: Δ1 = [] ++ A0 :: Δ0 ++ B :: Δ1). reflexivity. rewrite H0. clear H0.
+    apply ImpLRule_I. pose (dlCons x1 DersNilF). pose (dlCons x3 d0).
+    apply ImpL in H0.
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[(A :: Γ2 ++ Γ3, A0 :: Δ0 ++ B :: Δ1); (A :: Γ2 ++ B0 :: Γ3, Δ0 ++ B :: Δ1)])
+    (A :: Γ2 ++ A0 --> B0 :: Γ3, Δ0 ++ B :: Δ1) H0 d1).
+    assert (J40: list_exch_L (A :: Γ2 ++ A0 --> B0 :: Γ3, Δ0 ++ B :: Δ1) (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)).
+    rewrite H2. assert (A :: Γ0 ++ Γ1 = [] ++ [A] ++ Γ0 ++ [] ++ Γ1). reflexivity. rewrite H1. clear H1.
+    assert (Γ0 ++ A :: Γ1 = [] ++ [] ++ Γ0 ++ [A] ++ Γ1). reflexivity. rewrite H1. clear H1.
+    apply list_exch_LI.
+    assert (J41: derrec_height d2 = derrec_height d2). reflexivity.
+    pose (GLS_hpadm_list_exch_L d2 J41 J40). destruct s. exists x4. simpl in J41.
+    simpl in l2. rewrite dersrec_height_nil in l2. lia. reflexivity.
+  (* GLR *)
+  * inversion X. subst.
+    assert (GLRRule [(XBoxed_list ++ [Box A0], [A0])] (Γ0 ++ Γ1, Δ0 ++ Δ1)).
+    assert (In (Box A0) (Δ0 ++ Δ1)).
+    assert (InT (Box A0) (Δ2 ++ Box A0 :: Δ3)). apply InT_or_app. right. apply InT_eq.
+    rewrite H2 in H. apply InT_app_or in H. apply in_or_app. destruct H. apply InT_In in i. auto.
+    inversion i. inversion H0. apply InT_In in H0. auto.
+    apply in_splitT in H. destruct H. destruct s. rewrite e. apply GLRRule_I ; try assumption.
+    simpl. simpl in IH.
+    apply GLR in X1.
+    assert (dersrec_height d = dersrec_height d). reflexivity.
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[(XBoxed_list ++ [Box A0], [A0])]) (Γ0 ++ Γ1, Δ0 ++ Δ1) X1 d).
+    assert (J1: wkn_L A (Γ0 ++ Γ1, Δ0 ++ Δ1) (Γ0 ++ A :: Γ1, Δ0 ++ Δ1)).
+    apply wkn_LI.
+    assert (J2: derrec_height d0 = derrec_height d0). reflexivity.
+    pose (GLS_wkn_L d0 J2 J1). destruct s.
+    assert (J3: wkn_R B (Γ0 ++ A :: Γ1, Δ0 ++ Δ1) (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)).
+    apply wkn_RI.
+    assert (J4: derrec_height x = derrec_height x). reflexivity.
+    pose (GLS_wkn_R x J4 J3). destruct s. exists x0.
+    pose (Nat.le_trans _ _ _ l0 l). simpl in l1. assumption. }
+{ intros prem1 prem2 RA. inversion RA. subst.
+  inversion g ; subst.
+  (* IdP *)
+  * inversion H. subst. assert (InT # P (Γ0 ++ Γ1)). assert (InT # P (Γ2 ++ # P :: Γ3)).
+    apply InT_or_app. right. apply InT_eq. rewrite H2 in H0. apply InT_or_app.
+    apply InT_app_or in H0. destruct H0. auto. inversion i. inversion H1.
+    auto. assert (InT # P (Γ0 ++ B :: Γ1)).
+    apply InT_app_or in H0. apply InT_or_app. destruct H0. auto. right. apply InT_cons.
+    assumption. apply InT_split in H1. destruct H1. destruct s. apply InT_split in H0. destruct H0.
+    destruct s. rewrite e0. rewrite e. assert (In # P (Δ0 ++ A :: Δ1)). assert (In # P (Δ0 ++ Δ1)).
+    rewrite <- H3. apply in_or_app. right. apply in_eq. apply in_app_or in H0. apply in_or_app.
+    destruct H0. auto. right. apply in_cons. assumption. apply in_splitT in H0. destruct H0.
+    destruct s. rewrite e1.
+    assert (IdPRule [] (x1 ++ # P :: x2, x3 ++ # P :: x4)).
+    apply IdPRule_I. apply IdP in H0.
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[]) (x1 ++ # P :: x2, x3 ++ # P :: x4) H0 DersNilF). exists d0.
+    assert (IdPRule [] (x ++ # P :: x0, Δ0 ++ Δ1)). rewrite <- H3.
+    apply IdPRule_I. apply IdP in H1.
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[]) (x ++ # P :: x0, Δ0 ++ Δ1) H1 DersNilF). exists d1.
+    simpl. rewrite dersrec_height_nil. split ; lia. reflexivity.
+  (* BotL *)
+  * inversion H. subst. assert (InT () (Γ0 ++ Γ1)). assert (InT () (Γ2 ++ () :: Γ3)).
+    apply InT_or_app. right. apply InT_eq. rewrite H2 in H0. apply InT_app_or in H0.
+    apply InT_or_app. destruct H0. auto. inversion i. inversion H1. auto. assert (InT () (Γ0 ++ B :: Γ1)).
+    apply InT_app_or in H0. apply InT_or_app. destruct H0. auto. right. apply InT_cons.
+    assumption. apply InT_split in H0. destruct H0. destruct s. apply InT_split in H1. destruct H1.
+    destruct s. rewrite e0. rewrite e.
+    assert (BotLRule [] (x ++ :: x0, Δ0 ++ A :: Δ1)).
+    apply BotLRule_I. apply BotL in H0.
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[]) (x ++ :: x0, Δ0 ++ A :: Δ1) H0 DersNilF). exists d0.
+    assert (BotLRule [] (x1 ++ :: x2, Δ0 ++ Δ1)).
+    apply BotLRule_I. apply BotL in H1.
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[]) (x1 ++ :: x2, Δ0 ++ Δ1) H1 DersNilF). exists d1.
+    simpl. rewrite dersrec_height_nil. split ; lia. reflexivity.
+  (* ImpR *)
+  * inversion H. subst. simpl in IH.
+    assert (J0: (dersrec_height d) = (dersrec_height d)). reflexivity.
+    pose (dersrec_derrec_height d J0). destruct s.
+    apply app2_find_hole in H2. destruct H2. repeat destruct s ; destruct p ; subst.
+    + assert (ImpLRule [(Γ2 ++ A0 :: Γ1, A :: Δ2 ++ B0 :: Δ3) ; (Γ2 ++ A0 :: B :: Γ1, Δ2 ++ B0 :: Δ3)]
+      (Γ2 ++ A0 :: A --> B :: Γ1, Δ2 ++ B0 :: Δ3)). assert (Γ2 ++ A0 :: Γ1 = (Γ2 ++ [A0]) ++ Γ1).
+      rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ A0 :: B :: Γ1 = (Γ2 ++ [A0]) ++ B :: Γ1). rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. assert (Γ2 ++ A0 :: A --> B :: Γ1 = (Γ2 ++ [A0]) ++ A --> B :: Γ1). rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. assert (Δ2 ++ B0 :: Δ3 = [] ++ Δ2 ++ B0 :: Δ3).
+      reflexivity. rewrite H0. clear H0. assert (A :: [] ++ Δ2 ++ B0 :: Δ3 = [] ++ A :: Δ2 ++ B0 :: Δ3).
+      reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+      assert (J1: derrec_height x < S (dersrec_height d)). lia.
+      assert (J2: derrec_height x = derrec_height x). reflexivity.
+      pose (IH (derrec_height x) J1 _ x J2). destruct p. clear s.
+      pose (s0 _ _ H0). repeat destruct s. clear s0. destruct p.
+      assert (ImpRRule [(Γ2 ++ A0 :: Γ1, A :: Δ2 ++ B0 :: Δ3)] (Γ2 ++ Γ1, A :: Δ0 ++ Δ1)).
+      rewrite <- H3. assert (A :: Δ2 ++ B0 :: Δ3 = (A :: Δ2) ++ B0 :: Δ3). reflexivity.
+      rewrite H1. clear H1. assert (A :: Δ2 ++ A0 --> B0 :: Δ3 = (A :: Δ2) ++ A0 --> B0 :: Δ3). reflexivity.
+      rewrite H1. clear H1. apply ImpRRule_I.
+      assert (existsT2 (x3: derrec GLS_rules (fun _ : Seq => False)
+      (Γ2 ++ Γ1, A :: Δ0 ++ Δ1)), derrec_height x3 <= S (dersrec_height d)).
+      apply ImpR in H1.
+      pose (dlCons x1 DersNilF). pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[(Γ2 ++ A0 :: Γ1, A :: Δ2 ++ B0 :: Δ3)]) (Γ2 ++ Γ1, A :: Δ0 ++ Δ1) H1 d0).
+      exists d1. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+      destruct X.
+      assert (J3: derrec_height x3 = derrec_height x3). reflexivity.
+      assert (J4: list_exch_R (Γ2 ++ Γ1, A :: Δ0 ++ Δ1) (Γ2 ++ Γ1, Δ0 ++ A :: Δ1)).
+      assert (A :: Δ0 ++ Δ1 = [] ++ [A] ++ Δ0 ++ [] ++ Δ1). reflexivity. rewrite H2. clear H2.
+      assert (Δ0 ++ A :: Δ1 = [] ++ [] ++ Δ0 ++ [A] ++ Δ1). reflexivity. rewrite H2. clear H2.
+      apply list_exch_RI. pose (GLS_hpadm_list_exch_R x3 J3 J4). destruct s. exists x4.
+      assert (ImpRRule [(Γ2 ++ A0 :: B :: Γ1, Δ2 ++ B0 :: Δ3)] (Γ2 ++ B :: Γ1, Δ0 ++ Δ1)).
+      rewrite <- H3. apply ImpRRule_I.
+      assert (existsT2 (x3: derrec GLS_rules (fun _ : Seq => False)
+      (Γ2 ++ B :: Γ1, Δ0 ++ Δ1)), derrec_height x3 <= S (dersrec_height d)).
+      apply ImpR in H2.
+      pose (dlCons x2 DersNilF). pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[(Γ2 ++ A0 :: B :: Γ1, Δ2 ++ B0 :: Δ3)]) (Γ2 ++ B :: Γ1, Δ0 ++ Δ1) H2 d0).
+      exists d1. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+      destruct X. exists x5. simpl. split. lia. lia.
+    + assert (ImpLRule [(Γ2 ++ A0 :: x0 ++ Γ1, A :: Δ2 ++ B0 :: Δ3) ; (Γ2 ++ A0 :: x0 ++ B :: Γ1, Δ2 ++ B0 :: Δ3)]
+      (Γ2 ++ A0 :: x0 ++ A --> B :: Γ1, Δ2 ++ B0 :: Δ3)). assert (Γ2 ++ A0 :: x0 ++ Γ1 = (Γ2 ++ A0 :: x0) ++ Γ1).
+      rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ A0 :: x0 ++ B :: Γ1 = (Γ2 ++ A0 :: x0) ++ B :: Γ1). rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. assert (Γ2 ++ A0 :: x0 ++ A --> B :: Γ1 = (Γ2 ++ A0 :: x0) ++ A --> B :: Γ1). rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. assert (Δ2 ++ B0 :: Δ3 = [] ++ Δ2 ++ B0 :: Δ3).
+      reflexivity. rewrite H0. clear H0. assert (A :: [] ++ Δ2 ++ B0 :: Δ3 = [] ++ A :: Δ2 ++ B0 :: Δ3).
+      reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+      assert (J1: derrec_height x < S (dersrec_height d)). lia.
+      assert (J2: derrec_height x = derrec_height x). reflexivity.
+      pose (IH (derrec_height x) J1 _ x J2). destruct p. clear s.
+      pose (s0 _ _ H0). repeat destruct s. clear s0. destruct p.
+      assert (ImpRRule [(Γ2 ++ A0 :: x0 ++ Γ1, A :: Δ2 ++ B0 :: Δ3)] ((Γ2 ++ x0) ++ Γ1, A :: Δ0 ++ Δ1)).
+      rewrite <- H3. assert (A :: Δ2 ++ B0 :: Δ3 = (A :: Δ2) ++ B0 :: Δ3). reflexivity.
+      rewrite H1. clear H1. assert (A :: Δ2 ++ A0 --> B0 :: Δ3 = (A :: Δ2) ++ A0 --> B0 :: Δ3). reflexivity.
+      rewrite H1. clear H1. rewrite <- app_assoc. apply ImpRRule_I.
+      assert (existsT2 (x3: derrec GLS_rules (fun _ : Seq => False)
+      ((Γ2 ++ x0) ++ Γ1, A :: Δ0 ++ Δ1)), derrec_height x3 <= S (dersrec_height d)).
+      apply ImpR in H1.
+      pose (dlCons x1 DersNilF). pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[(Γ2 ++ A0 :: x0 ++ Γ1, A :: Δ2 ++ B0 :: Δ3)]) ((Γ2 ++ x0) ++ Γ1, A :: Δ0 ++ Δ1) H1 d0).
+      exists d1. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+      destruct X.
+      assert (J3: derrec_height x3 = derrec_height x3). reflexivity.
+      assert (J4: list_exch_R ((Γ2 ++ x0) ++ Γ1, A :: Δ0 ++ Δ1) ((Γ2 ++ x0) ++ Γ1, Δ0 ++ A :: Δ1)).
+      assert (A :: Δ0 ++ Δ1 = [] ++ [A] ++ Δ0 ++ [] ++ Δ1). reflexivity. rewrite H2. clear H2.
+      assert (Δ0 ++ A :: Δ1 = [] ++ [] ++ Δ0 ++ [A] ++ Δ1). reflexivity. rewrite H2. clear H2.
+      apply list_exch_RI. pose (GLS_hpadm_list_exch_R x3 J3 J4). destruct s. exists x4.
+      assert (ImpRRule [(Γ2 ++ A0 :: x0 ++ B :: Γ1, Δ2 ++ B0 :: Δ3)] ((Γ2 ++ x0) ++ B :: Γ1, Δ0 ++ Δ1)).
+      rewrite <- H3. rewrite <- app_assoc. apply ImpRRule_I.
+      assert (existsT2 (x3: derrec GLS_rules (fun _ : Seq => False)
+      ((Γ2 ++ x0) ++ B :: Γ1, Δ0 ++ Δ1)), derrec_height x3 <= S (dersrec_height d)).
+      apply ImpR in H2.
+      pose (dlCons x2 DersNilF). pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[(Γ2 ++ A0 :: x0 ++ B :: Γ1, Δ2 ++ B0 :: Δ3)]) ((Γ2 ++ x0) ++ B :: Γ1, Δ0 ++ Δ1) H2 d0).
+      exists d1. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+      destruct X. exists x5. simpl. split. lia. lia.
+    + destruct x0.
+      { simpl in e1. subst. assert (ImpLRule [(Γ0 ++ A0 :: Γ1, A :: Δ2 ++ B0 :: Δ3) ; (Γ0 ++ A0 :: B :: Γ1, Δ2 ++ B0 :: Δ3)]
+        ((Γ0 ++ []) ++ A0 :: A --> B :: Γ1, Δ2 ++ B0 :: Δ3)). rewrite app_nil_r. assert (Γ0 ++ A0 :: Γ1 = (Γ0 ++ [A0]) ++ Γ1).
+        rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ A0 :: B :: Γ1 = (Γ0 ++ [A0]) ++ B :: Γ1). rewrite <- app_assoc. reflexivity.
+        rewrite H0. clear H0. assert (Γ0 ++ A0 :: A --> B :: Γ1 = (Γ0 ++ [A0]) ++ A --> B :: Γ1). rewrite <- app_assoc. reflexivity.
+        rewrite H0. clear H0. assert (Δ2 ++ B0 :: Δ3 = [] ++ Δ2 ++ B0 :: Δ3).
+        reflexivity. rewrite H0. clear H0. assert (A :: [] ++ Δ2 ++ B0 :: Δ3 = [] ++ A :: Δ2 ++ B0 :: Δ3).
+        reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+        assert (J1: derrec_height x < S (dersrec_height d)). lia.
+        assert (J2: derrec_height x = derrec_height x). reflexivity.
+        pose (IH (derrec_height x) J1 _ x J2). destruct p. clear s.
+        pose (s0 _ _ H0). repeat destruct s. clear s0. destruct p.
+        assert (ImpRRule [(Γ0 ++ A0 :: Γ1, A :: Δ2 ++ B0 :: Δ3)] (Γ0 ++ Γ1, A :: Δ0 ++ Δ1)).
+        rewrite <- H3. assert (A :: Δ2 ++ B0 :: Δ3 = (A :: Δ2) ++ B0 :: Δ3). reflexivity.
+        rewrite H1. clear H1. assert (A :: Δ2 ++ A0 --> B0 :: Δ3 = (A :: Δ2) ++ A0 --> B0 :: Δ3). reflexivity.
+        rewrite H1. clear H1. apply ImpRRule_I.
+        assert (existsT2 (x3: derrec GLS_rules (fun _ : Seq => False)
+        (Γ0 ++ Γ1, A :: Δ0 ++ Δ1)), derrec_height x3 <= S (dersrec_height d)).
+        apply ImpR in H1.
+        pose (dlCons x0 DersNilF). pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[(Γ0 ++ A0 :: Γ1, A :: Δ2 ++ B0 :: Δ3)]) (Γ0 ++ Γ1, A :: Δ0 ++ Δ1) H1 d0).
+        exists d1. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+        destruct X.
+        assert (J3: derrec_height x2 = derrec_height x2). reflexivity.
+        assert (J4: list_exch_R (Γ0 ++ Γ1, A :: Δ0 ++ Δ1) (Γ0 ++ Γ1, Δ0 ++ A :: Δ1)).
+        assert (A :: Δ0 ++ Δ1 = [] ++ [A] ++ Δ0 ++ [] ++ Δ1). reflexivity. rewrite H2. clear H2.
+        assert (Δ0 ++ A :: Δ1 = [] ++ [] ++ Δ0 ++ [A] ++ Δ1). reflexivity. rewrite H2. clear H2.
+        apply list_exch_RI. pose (GLS_hpadm_list_exch_R x2 J3 J4). destruct s. exists x3.
+        assert (ImpRRule [(Γ0 ++ A0 :: B :: Γ1, Δ2 ++ B0 :: Δ3)] (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)).
+        rewrite <- H3. apply ImpRRule_I.
+        assert (existsT2 (x3: derrec GLS_rules (fun _ : Seq => False)
+        (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)), derrec_height x3 <= S (dersrec_height d)).
+        apply ImpR in H2.
+        pose (dlCons x1 DersNilF). pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[(Γ0 ++ A0 :: B :: Γ1, Δ2 ++ B0 :: Δ3)]) (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) H2 d0).
+        exists d1. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+        destruct X. exists x4. simpl. split. lia. lia. }
+        { inversion e1. subst. assert (ImpLRule [(Γ0 ++ x0 ++ A0 :: Γ3, A :: Δ2 ++ B0 :: Δ3) ; (Γ0 ++ B :: x0 ++ A0 :: Γ3, Δ2 ++ B0 :: Δ3)]
+          ((Γ0 ++ A --> B :: x0) ++ A0 :: Γ3, Δ2 ++ B0 :: Δ3)). rewrite <- app_assoc.
+          assert (Δ2 ++ B0 :: Δ3 = [] ++ Δ2 ++ B0 :: Δ3). reflexivity. rewrite H0. clear H0.
+          assert (A :: [] ++ Δ2 ++ B0 :: Δ3 = [] ++ A :: Δ2 ++ B0 :: Δ3). reflexivity. rewrite H0.
+          clear H0. apply ImpLRule_I.
+          assert (J1: derrec_height x < S (dersrec_height d)). lia.
+          assert (J2: derrec_height x = derrec_height x). reflexivity.
+          pose (IH (derrec_height x) J1 _ x J2). destruct p. clear s.
+          pose (s0 _ _ H0). repeat destruct s. clear s0. destruct p.
+          assert (ImpRRule [(Γ0 ++ x0 ++ A0 :: Γ3, A :: Δ2 ++ B0 :: Δ3)] (Γ0 ++ x0 ++ Γ3, A :: Δ0 ++ Δ1)).
+          rewrite <- H3. assert (A :: Δ2 ++ B0 :: Δ3 = (A :: Δ2) ++ B0 :: Δ3). reflexivity.
+          rewrite H1. clear H1. assert (A :: Δ2 ++ A0 --> B0 :: Δ3 = (A :: Δ2) ++ A0 --> B0 :: Δ3). reflexivity.
+          rewrite H1. clear H1. assert (Γ0 ++ x0 ++ A0 :: Γ3 = (Γ0 ++ x0) ++ A0 :: Γ3). rewrite <- app_assoc.
+          reflexivity. rewrite H1. clear H1. assert (Γ0 ++ x0 ++ Γ3 = (Γ0 ++ x0) ++ Γ3). rewrite <- app_assoc.
+          reflexivity. rewrite H1. clear H1. apply ImpRRule_I.
+          assert (existsT2 (x3: derrec GLS_rules (fun _ : Seq => False)
+          (Γ0 ++ x0 ++ Γ3, A :: Δ0 ++ Δ1)), derrec_height x3 <= S (dersrec_height d)).
+          apply ImpR in H1.
+          pose (dlCons x1 DersNilF). pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[(Γ0 ++ x0 ++ A0 :: Γ3, A :: Δ2 ++ B0 :: Δ3)]) (Γ0 ++ x0 ++ Γ3, A :: Δ0 ++ Δ1) H1 d0).
+          exists d1. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+          destruct X.
+          assert (J3: derrec_height x3 = derrec_height x3). reflexivity.
+          assert (J4: list_exch_R (Γ0 ++ x0 ++ Γ3, A :: Δ0 ++ Δ1) (Γ0 ++ x0 ++ Γ3, Δ0 ++ A :: Δ1)).
+          assert (A :: Δ0 ++ Δ1 = [] ++ [A] ++ Δ0 ++ [] ++ Δ1). reflexivity. rewrite H2. clear H2.
+          assert (Δ0 ++ A :: Δ1 = [] ++ [] ++ Δ0 ++ [A] ++ Δ1). reflexivity. rewrite H2. clear H2.
+          apply list_exch_RI. pose (GLS_hpadm_list_exch_R x3 J3 J4). destruct s. exists x4.
+          assert (ImpRRule [(Γ0 ++ B :: x0 ++ A0 :: Γ3, Δ2 ++ B0 :: Δ3)] (Γ0 ++ B :: x0 ++ Γ3, Δ0 ++ Δ1)).
+          rewrite <- H3. assert (Γ0 ++ B :: x0 ++ A0 :: Γ3 = (Γ0 ++ B :: x0) ++ A0 :: Γ3). rewrite <- app_assoc.
+          reflexivity. rewrite H2. clear H2. assert (Γ0 ++ B :: x0 ++ Γ3 = (Γ0 ++ B :: x0) ++ Γ3). rewrite <- app_assoc.
+          reflexivity. rewrite H2. clear H2. apply ImpRRule_I.
+          assert (existsT2 (x3: derrec GLS_rules (fun _ : Seq => False)
+          (Γ0 ++ B :: x0 ++ Γ3, Δ0 ++ Δ1)), derrec_height x3 <= S (dersrec_height d)).
+          apply ImpR in H2.
+          pose (dlCons x2 DersNilF). pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[(Γ0 ++ B :: x0 ++ A0 :: Γ3, Δ2 ++ B0 :: Δ3)]) (Γ0 ++ B :: x0 ++ Γ3, Δ0 ++ Δ1) H2 d0).
+          exists d1. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+          destruct X. exists x5. simpl. split. lia. lia. }
+  (* ImpL *)
+  * inversion H. subst.
+    apply app2_find_hole in H2. destruct H2. repeat destruct s ; destruct p ; subst.
+    + inversion e0. subst. assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+      pose (@dersrec_derrec2_height (dersrec_height d) _ _ _ _ _ d J30). repeat destruct s.
+      assert (J1: list_exch_R (Γ2 ++ Γ3, Δ2 ++ A0 :: Δ3) (Γ2 ++ Γ3, A0 :: Δ0 ++ Δ1)).
+      assert (Δ2 ++ A0 :: Δ3 = [] ++ [] ++ Δ2 ++ [A0] ++ Δ3). reflexivity.
+      rewrite H0. clear H0.
+      assert (A0 :: Δ0 ++ Δ1 = [] ++ [A0] ++ Δ2 ++ [] ++ Δ3). simpl. rewrite H3. reflexivity.
+      rewrite H0. clear H0. apply list_exch_RI.
+      assert (J20: derrec_height x0 = derrec_height x0). reflexivity.
+      pose (GLS_hpadm_list_exch_R x0 J20 J1). destruct s.
+      assert (J2: list_exch_R (Γ2 ++ Γ3, A0 :: Δ0 ++ Δ1) (Γ2 ++ Γ3, Δ0 ++ A0 :: Δ1)).
+      assert (A0 :: Δ0 ++ Δ1 = [] ++ [A0] ++ Δ0 ++ [] ++ Δ1).
+      reflexivity. assert (Δ0 ++ A0 :: Δ1 = [] ++ [] ++ Δ0 ++ [A0] ++ Δ1).
+      reflexivity. rewrite H1. rewrite H0. clear H1. clear H0. apply list_exch_RI.
+      assert (J21: derrec_height x2 = derrec_height x2). reflexivity.
+      pose (GLS_hpadm_list_exch_R x2 J21 J2). destruct s. exists x3.
+      assert (existsT2 (x4: derrec GLS_rules (fun _ : Seq => False) (Γ2 ++ B0 :: Γ3, Δ0 ++ Δ1)),
+      derrec_height x4 = derrec_height x1). rewrite <- H3. exists x1. reflexivity. destruct X. exists x4. split.
+       simpl. lia. simpl. lia.
+    + destruct x.
+      { simpl in e0. inversion e0. simpl. rewrite app_nil_r. subst.
+        assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+        pose (@dersrec_derrec2_height (dersrec_height d) _ _ _ _ _ d J30). repeat destruct s.
+        assert (J1: list_exch_R (Γ2 ++ Γ1, Δ2 ++ A :: Δ3) (Γ2 ++ Γ1, A :: Δ0 ++ Δ1)).
+        assert (Δ2 ++ A :: Δ3 = [] ++ [] ++ Δ2 ++ [A] ++ Δ3). reflexivity.
+        rewrite H0. clear H0.
+        assert (A :: Δ0 ++ Δ1 = [] ++ [A] ++ Δ2 ++ [] ++ Δ3). simpl. rewrite H3. reflexivity.
+        rewrite H0. clear H0. apply list_exch_RI.
+        assert (J20: derrec_height x = derrec_height x). reflexivity.
+        pose (GLS_hpadm_list_exch_R x J20 J1). destruct s.
+        assert (J2: list_exch_R (Γ2 ++ Γ1, A :: Δ0 ++ Δ1) (Γ2 ++ Γ1, Δ0 ++ A :: Δ1)).
+        assert (A :: Δ0 ++ Δ1 = [] ++ [A] ++ Δ0 ++ [] ++ Δ1).
+        reflexivity. assert (Δ0 ++ A :: Δ1 = [] ++ [] ++ Δ0 ++ [A] ++ Δ1).
+        reflexivity. rewrite H1. rewrite H0. clear H1. clear H0. apply list_exch_RI.
+        assert (J21: derrec_height x1 = derrec_height x1). reflexivity.
+        pose (GLS_hpadm_list_exch_R x1 J21 J2). destruct s. exists x2.
+        assert (existsT2 (x3: derrec GLS_rules (fun _ : Seq => False) (Γ2 ++ B :: Γ1, Δ0 ++ Δ1)),
+        derrec_height x3 = derrec_height x0). rewrite <- H3. exists x0. reflexivity. destruct X. exists x3. split.
+        simpl. lia. simpl. lia. }
+      { inversion e0. subst. assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+        pose (@dersrec_derrec2_height (dersrec_height d) _ _ _ _ _ d J30). repeat destruct s.
+        assert (J1: list_exch_R (Γ2 ++ x ++ A --> B :: Γ1, Δ2 ++ A0 :: Δ3) (Γ2 ++ x ++ A --> B :: Γ1, A0 :: Δ0 ++ Δ1)).
+        assert (Δ2 ++ A0 :: Δ3 = [] ++ [] ++ Δ2 ++ [A0] ++ Δ3). reflexivity.
+        rewrite H0. clear H0.
+        assert (A0 :: Δ0 ++ Δ1 = [] ++ [A0] ++ Δ2 ++ [] ++ Δ3). simpl. rewrite H3. reflexivity.
+        rewrite H0. clear H0. apply list_exch_RI.
+        assert (J20: derrec_height x0 = derrec_height x0). reflexivity.
+        pose (GLS_hpadm_list_exch_R x0 J20 J1). destruct s. simpl in IH. simpl.
+        assert (J2: derrec_height x2 < S (dersrec_height d)). lia.
+        assert (J3: derrec_height x2 = derrec_height x2). reflexivity.
+        assert (J4: ImpLRule [(Γ2 ++ x ++ Γ1, A0 :: Δ0 ++ A :: Δ1); (Γ2 ++ x ++ B :: Γ1, A0 :: Δ0 ++ Δ1)]
+        (Γ2 ++ x ++ A --> B :: Γ1, A0 :: Δ0 ++ Δ1)).
+        assert (A0 :: Δ0 ++ A :: Δ1 = (A0 :: Δ0) ++ A :: Δ1). reflexivity. rewrite H0. clear H0.
+        assert (A0 :: Δ0 ++ Δ1 = (A0 :: Δ0) ++ Δ1). reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ x ++ B :: Γ1 = (Γ2 ++ x) ++ B :: Γ1). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ x ++ A --> B :: Γ1 = (Γ2 ++ x) ++ A --> B :: Γ1). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ x ++ Γ1 = (Γ2 ++ x) ++ Γ1). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+        pose (IH _ J2 _ _ J3). destruct p. pose (s0 _ _ J4). clear s. destruct s1. clear s0. destruct s.
+        destruct p.
+        assert (J5: derrec_height x1 < S (dersrec_height d)). lia.
+        assert (J6: derrec_height x1 = derrec_height x1). reflexivity.
+        assert (J7: ImpLRule [(Γ2 ++ B0 :: x ++ Γ1, Δ0 ++ A :: Δ1); (Γ2 ++ B0 :: x ++ B :: Γ1, Δ0 ++ Δ1)]
+        (Γ2 ++ B0 :: x ++ A --> B :: Γ1, Δ2 ++ Δ3)). rewrite H3.
+        assert (Γ2 ++ B0 :: x ++ Γ1 = (Γ2 ++ B0 :: x) ++ Γ1). rewrite <- app_assoc. reflexivity.
+        rewrite H0. clear H0.
+        assert (Γ2 ++ B0 :: x ++ B :: Γ1 = (Γ2 ++ B0 :: x) ++ B :: Γ1). rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ B0 :: x ++ A --> B :: Γ1 = (Γ2 ++ B0 :: x) ++ A --> B :: Γ1). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+        pose (IH _ J5 _ _ J6). destruct p. pose (s0 _ _ J7). clear s. destruct s1. clear s0. destruct s.
+        destruct p.
+        assert (existsT2 (x7 : derrec GLS_rules (fun _ : Seq => False)
+        ((Γ2 ++ A0 --> B0 :: x) ++ Γ1, Δ0 ++ A :: Δ1)), derrec_height x7 <= S (dersrec_height d)).
+        assert (ImpLRule [(Γ2 ++ x ++ Γ1, A0 :: Δ0 ++ A :: Δ1); (Γ2 ++ B0 :: x ++ Γ1, Δ0 ++ A :: Δ1)]
+        ((Γ2 ++ A0 --> B0 :: x) ++ Γ1, Δ0 ++ A :: Δ1)). rewrite <- app_assoc.
+        assert (A0 :: Δ0 ++ A :: Δ1 = [] ++ A0 :: Δ0 ++ A :: Δ1). reflexivity. rewrite H0. clear H0.
+        assert (Δ0 ++ A :: Δ1 = [] ++ Δ0 ++ A :: Δ1). reflexivity. rewrite H0. clear H0. repeat rewrite <- app_assoc.
+        apply ImpLRule_I. apply ImpL in H0.
+        pose (dlCons x5 DersNilF). pose (dlCons x3 d0).
+        pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[(Γ2 ++ x ++ Γ1, A0 :: Δ0 ++ A :: Δ1); (Γ2 ++ B0 :: x ++ Γ1, Δ0 ++ A :: Δ1)])
+        ((Γ2 ++ A0 --> B0 :: x) ++ Γ1, Δ0 ++ A :: Δ1) H0 d1).
+        exists d2. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+        destruct X. exists x7.
+        assert (existsT2 (x8 : derrec GLS_rules (fun _ : Seq => False)
+        ((Γ2 ++ A0 --> B0 :: x) ++ B :: Γ1, Δ0 ++ Δ1)), derrec_height x8 <= S (dersrec_height d)).
+        assert (ImpLRule [(Γ2 ++ x ++ B :: Γ1, A0 :: Δ0 ++ Δ1); (Γ2 ++ B0 :: x ++ B :: Γ1, Δ0 ++ Δ1)]
+        ((Γ2 ++ A0 --> B0 :: x) ++ B :: Γ1, Δ0 ++ Δ1)). rewrite <- app_assoc.
+        assert (Δ0 ++ Δ1 = [] ++ Δ0 ++ Δ1). reflexivity. rewrite H0. clear H0.
+        assert (A0 :: [] ++ Δ0 ++ Δ1 = [] ++ A0 :: Δ0 ++ Δ1). reflexivity. rewrite H0. clear H0.
+        apply ImpLRule_I. apply ImpL in H0.
+        pose (dlCons x6 DersNilF). pose (dlCons x4 d0).
+        pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[(Γ2 ++ x ++ B :: Γ1, A0 :: Δ0 ++ Δ1); (Γ2 ++ B0 :: x ++ B :: Γ1, Δ0 ++ Δ1)])
+        ((Γ2 ++ A0 --> B0 :: x) ++ B :: Γ1, Δ0 ++ Δ1) H0 d1).
+        exists d2. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+        destruct X. exists x8. split. lia. lia. }
+    + destruct x.
+      { simpl in e0. inversion e0. simpl. subst.
+        assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+        pose (@dersrec_derrec2_height (dersrec_height d) _ _ _ _ _ d J30). repeat destruct s.
+        assert (J1: list_exch_R ((Γ0 ++ []) ++ Γ3, Δ2 ++ A0 :: Δ3) (Γ0 ++ Γ3, A0 :: Δ0 ++ Δ1)).
+        rewrite app_nil_r.
+        assert (Δ2 ++ A0 :: Δ3 = [] ++ [] ++ Δ2 ++ [A0] ++ Δ3). reflexivity.
+        rewrite H0. clear H0.
+        assert (A0 :: Δ0 ++ Δ1 = [] ++ [A0] ++ Δ2 ++ [] ++ Δ3). simpl. rewrite H3. reflexivity.
+        rewrite H0. clear H0. apply list_exch_RI.
+        assert (J20: derrec_height x = derrec_height x). reflexivity.
+        pose (GLS_hpadm_list_exch_R x J20 J1). destruct s.
+        assert (J2: list_exch_R (Γ0 ++ Γ3, A0 :: Δ0 ++ Δ1) (Γ0 ++ Γ3, Δ0 ++ A0 :: Δ1)).
+        assert (A0 :: Δ0 ++ Δ1 = [] ++ [A0] ++ Δ0 ++ [] ++ Δ1).
+        reflexivity. assert (Δ0 ++ A0 :: Δ1 = [] ++ [] ++ Δ0 ++ [A0] ++ Δ1).
+        reflexivity. rewrite H1. rewrite H0. clear H1. clear H0. apply list_exch_RI.
+        assert (J21: derrec_height x1 = derrec_height x1). reflexivity.
+        pose (GLS_hpadm_list_exch_R x1 J21 J2). destruct s. exists x2.
+        assert (existsT2 (x3: derrec GLS_rules (fun _ : Seq => False) (Γ0 ++ B0 :: Γ3, Δ0 ++ Δ1)),
+        derrec_height x3 = derrec_height x0). rewrite <- H3.
+        assert (Γ0 ++ B0 :: Γ3 = (Γ0 ++ []) ++ B0 :: Γ3). rewrite app_nil_r. reflexivity.
+        rewrite H0. exists x0. reflexivity. destruct X. exists x3. split.
+        simpl. lia. simpl. lia. }
+      { inversion e0. subst. assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+        pose (@dersrec_derrec2_height (dersrec_height d) _ _ _ _ _ d J30). repeat destruct s.
+        assert (J1: list_exch_R ((Γ0 ++ A --> B :: x) ++ Γ3, Δ2 ++ A0 :: Δ3) (Γ0 ++ A --> B :: x ++ Γ3, A0 :: Δ0 ++ Δ1)).
+        assert (Δ2 ++ A0 :: Δ3 = [] ++ [] ++ Δ2 ++ [A0] ++ Δ3). reflexivity.
+        rewrite H0. clear H0. rewrite <- app_assoc.
+        assert (A0 :: Δ0 ++ Δ1 = [] ++ [A0] ++ Δ2 ++ [] ++ Δ3). simpl. rewrite H3. reflexivity.
+        rewrite H0. clear H0. apply list_exch_RI.
+        assert (J20: derrec_height x0 = derrec_height x0). reflexivity.
+        pose (GLS_hpadm_list_exch_R x0 J20 J1). destruct s. simpl in IH. simpl.
+        assert (J2: derrec_height x2 < S (dersrec_height d)). lia.
+        assert (J3: derrec_height x2 = derrec_height x2). reflexivity.
+        assert (J4: ImpLRule [(Γ0 ++ x ++ Γ3, A0 :: Δ0 ++ A :: Δ1); (Γ0 ++ B :: x ++ Γ3, A0 :: Δ0 ++ Δ1)]
+        (Γ0 ++ A --> B :: x ++ Γ3, A0 :: Δ0 ++ Δ1)).
+        assert (A0 :: Δ0 ++ A :: Δ1 = (A0 :: Δ0) ++ A :: Δ1). reflexivity. rewrite H0. clear H0.
+        assert (A0 :: Δ0 ++ Δ1 = (A0 :: Δ0) ++ Δ1). reflexivity. rewrite H0. clear H0.
+        apply ImpLRule_I.
+        pose (IH _ J2 _ _ J3). destruct p. pose (s0 _ _ J4). clear s. destruct s1. clear s0. destruct s.
+        destruct p.
+        assert (J5: derrec_height x1 < S (dersrec_height d)). lia.
+        assert (J6: derrec_height x1 = derrec_height x1). reflexivity.
+        assert (J7: ImpLRule [(Γ0 ++ x ++ B0 :: Γ3, Δ0 ++ A :: Δ1); (Γ0 ++ B :: x ++ B0 :: Γ3, Δ0 ++ Δ1)]
+        ((Γ0 ++ A --> B :: x) ++ B0 :: Γ3, Δ2 ++ Δ3)). rewrite H3. rewrite <- app_assoc.
+        apply ImpLRule_I. pose (IH _ J5 _ _ J6). destruct p. pose (s0 _ _ J7). clear s.
+        destruct s1. clear s0. destruct s. destruct p.
+        assert (existsT2 (x7 : derrec GLS_rules (fun _ : Seq => False)
+        (Γ0 ++ x ++ A0 --> B0 :: Γ3, Δ0 ++ A :: Δ1)), derrec_height x7 <= S (dersrec_height d)).
+        assert (ImpLRule [(Γ0 ++ x ++ Γ3, A0 :: Δ0 ++ A :: Δ1); (Γ0 ++ x ++ B0 :: Γ3, Δ0 ++ A :: Δ1)]
+        (Γ0 ++ x ++ A0 --> B0 :: Γ3, Δ0 ++ A :: Δ1)).
+        assert (A0 :: Δ0 ++ A :: Δ1 = [] ++ A0 :: Δ0 ++ A :: Δ1). reflexivity. rewrite H0. clear H0.
+        assert (Δ0 ++ A :: Δ1 = [] ++ Δ0 ++ A :: Δ1). reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ x ++ Γ3 = (Γ0 ++ x) ++ Γ3). rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ x ++ B0 :: Γ3 = (Γ0 ++ x) ++ B0 :: Γ3). rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ x ++ A0 --> B0 :: Γ3 = (Γ0 ++ x) ++ A0 --> B0 :: Γ3). rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        apply ImpLRule_I. apply ImpL in H0.
+        pose (dlCons x5 DersNilF). pose (dlCons x3 d0).
+        pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[(Γ0 ++ x ++ Γ3, A0 :: Δ0 ++ A :: Δ1); (Γ0 ++ x ++ B0 :: Γ3, Δ0 ++ A :: Δ1)])
+        (Γ0 ++ x ++ A0 --> B0 :: Γ3, Δ0 ++ A :: Δ1) H0 d1).
+        exists d2. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+        destruct X. exists x7.
+        assert (existsT2 (x8 : derrec GLS_rules (fun _ : Seq => False)
+        (Γ0 ++ B :: x ++ A0 --> B0 :: Γ3, Δ0 ++ Δ1)), derrec_height x8 <= S (dersrec_height d)).
+        assert (ImpLRule [(Γ0 ++ B :: x ++ Γ3, A0 :: Δ0 ++ Δ1); (Γ0 ++ B :: x ++ B0 :: Γ3, Δ0 ++ Δ1)]
+        (Γ0 ++ B :: x ++ A0 --> B0 :: Γ3, Δ0 ++ Δ1)).
+        assert (Δ0 ++ Δ1 = [] ++ Δ0 ++ Δ1). reflexivity. rewrite H0. clear H0.
+        assert (A0 :: [] ++ Δ0 ++ Δ1 = [] ++ A0 :: Δ0 ++ Δ1). reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ B :: x ++ Γ3 = (Γ0 ++ B :: x) ++ Γ3). rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ B :: x ++ B0 :: Γ3 = (Γ0 ++ B :: x) ++ B0 :: Γ3). rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ B :: x ++ A0 --> B0 :: Γ3 = (Γ0 ++ B :: x) ++ A0 --> B0 :: Γ3). rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        apply ImpLRule_I. apply ImpL in H0.
+        pose (dlCons x6 DersNilF). pose (dlCons x4 d0).
+        pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[(Γ0 ++ B :: x ++ Γ3, A0 :: Δ0 ++ Δ1); (Γ0 ++ B :: x ++ B0 :: Γ3, Δ0 ++ Δ1)])
+        (Γ0 ++ B :: x ++ A0 --> B0 :: Γ3, Δ0 ++ Δ1) H0 d1).
+        exists d2. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+        destruct X. exists x8. split. lia. lia. }
+  (* GLR *)
+  * inversion X. subst. pose (univ_gen_ext_splitR _ _ X0). repeat destruct s. repeat destruct p. subst.
+    assert (J0: dersrec_height d = dersrec_height d). reflexivity.
+    pose (dersrec_derrec_height d J0). destruct s.
+    assert (GLRRule [(XBoxed_list (x ++ x0) ++ [Box A0], [A0])] (Γ0 ++ Γ1, Δ0 ++ Δ1)).
+    rewrite <- H2. apply GLRRule_I ; try assumption. apply univ_gen_ext_combine.
+    assumption. apply univ_gen_ext_not_In_delete with (a:=A --> B). intro.
+    assert (In (A --> B) (x ++ x0)). apply in_or_app. auto. apply H1 in H0. destruct H0.
+    inversion H0. assumption.
+    assert (existsT2 (D : derrec GLS_rules (fun _ : Seq => False) (Γ0 ++ Γ1, Δ0 ++ Δ1)),
+    derrec_height D <= S (dersrec_height d)).
+    apply GLR in X1.
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[(XBoxed_list (x ++ x0) ++ [Box A0], [A0])]) (Γ0 ++ Γ1, Δ0 ++ Δ1) X1 d).
+    exists d0. simpl. lia.
+    destruct X2.
+    assert (J1: derrec_height x2 = derrec_height x2). reflexivity.
+    assert (J2: wkn_L B (Γ0 ++ Γ1, Δ0 ++ Δ1) (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)). apply wkn_LI.
+    pose (GLS_wkn_L x2 J1 J2). destruct s.
+    assert (J3: wkn_R A (Γ0 ++ Γ1, Δ0 ++ Δ1) (Γ0 ++ Γ1, Δ0 ++ A :: Δ1)). apply wkn_RI.
+    pose (GLS_wkn_R x2 J1 J3). destruct s. exists x4. exists x3. simpl.
+    split ; lia. }
+Qed.
+ +
+Theorem ImpR_inv : forall concl prem, (GLS_prv concl) ->
+                                      (ImpRRule [prem] concl) ->
+                                      (GLS_prv prem).
+Proof.
+intros.
+assert (J1: derrec_height X = derrec_height X). reflexivity.
+pose (ImpR_ImpL_hpinv X J1). destruct p. pose (s _ H). destruct s1. assumption.
+Qed.
+ +
+Theorem ImpL_inv : forall concl prem1 prem2, (GLS_prv concl) ->
+                                      (ImpLRule [prem1;prem2] concl) ->
+                                      (GLS_prv prem1) *
+                                      (GLS_prv prem2).
+Proof.
+intros.
+assert (J1: derrec_height X = derrec_height X). reflexivity.
+pose (ImpR_ImpL_hpinv X J1). destruct p. pose (s0 _ _ H). repeat destruct s1. auto.
+Qed.
+
+
+ +
+ + + diff --git a/GL.GLS.GLS_termination_measure.html b/GL.GLS.GLS_termination_measure.html new file mode 100644 index 0000000..2201662 --- /dev/null +++ b/GL.GLS.GLS_termination_measure.html @@ -0,0 +1,864 @@ + + + + + + + + + + + + + +
+
+

GL.GLS.GLS_termination_measure

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat.
+Require Import Lia.
+Require Import Wellfounded.
+ +
+Require Import GLS_calcs.
+Require Import DLW_wf_lex.
+ +
+Set Implicit Arguments.
+ +
+Lemma NoDup_incl_lengthT : forall (l l' : list MPropF), NoDup l -> incl l l' ->
+          {length l < length l'} + {length l = length l'}.
+Proof. intros. apply Compare_dec.le_lt_eq_dec, NoDup_incl_length; assumption. Qed.
+ +
+(* First, let us define a the second part of our measure. This number is simply
+   the number of implication symbols in a sequent.
+
+   To define it, we need to define the number of implications in a formula. *)

+ +
+Fixpoint n_imp_subformF (A : MPropF) : nat :=
+match A with
+ | # P => 0
+ | => 0
+ | Imp B C => 1 + (n_imp_subformF B) + (n_imp_subformF C)
+ | Box B => (n_imp_subformF B)
+end.
+ +
+(* With this definition in hand, we can then straightforwardly define the number
+   of implications in a list of formulae. *)

+ +
+Fixpoint n_imp_subformLF (l : list MPropF) : nat :=
+match l with
+  | [] => 0
+  | h :: t => (n_imp_subformF h) + (n_imp_subformLF t)
+end.
+ +
+(* The the definition we were initially looking for can be reached: *)
+ +
+Definition n_imp_subformS (s : Seq) : nat :=
+    (n_imp_subformLF (fst s)) + (n_imp_subformLF (snd s)).
+ +
+(* It is clear that n_imp_subformS counts the occurrences of implications in a
+   sequent s. As a consequence, if that number is 0 we know for sure that the
+   rules for implication on the left or right cannot be applied upwards on s.
+   This is the meaning of the lemma n_imp_subformS_is_0. 
+
+   But first we need a preliminary lemma which claims that if an implication is
+   in a list, then n_imp_subformLF of that list is higher than one.*)

+ +
+Lemma In_n_imp_subformLF_is_non_0 (l : list MPropF) :
+    forall A B, (In (Imp A B) l) -> (le 1 (n_imp_subformLF l)).
+Proof.
+intros A B Hin. induction l.
+- inversion Hin.
+- inversion Hin.
+  * subst. simpl. rewrite <- Nat.succ_le_mono. apply le_0_n.
+  * pose (IHl H). simpl. destruct l0.
+    + rewrite Nat.add_1_r. rewrite <- Nat.succ_le_mono. apply le_0_n.
+    + rewrite <- plus_n_Sm. rewrite <- Nat.succ_le_mono. apply le_0_n.
+Qed.
+ +
+Theorem n_imp_subformS_is_0 (s : Seq) :
+    (n_imp_subformS s) = 0 -> (existsT2 ps, (ImpRRule ps s) + (ImpLRule ps s)) -> False.
+Proof.
+intros is0 RA. destruct RA. destruct s0.
+- inversion i. subst. unfold n_imp_subformS in is0. simpl in is0.
+  assert (n_imp_subformLF (Δ0 ++ A --> B :: Δ1) = 0). lia.
+  assert (In (A --> B) (Δ0 ++ A --> B :: Δ1)). apply in_or_app. right. apply in_eq.
+  pose (In_n_imp_subformLF_is_non_0 (Δ0 ++ A --> B :: Δ1) A B H0). lia.
+- inversion i. subst.
+  assert (In (A --> B) (Γ0 ++ A --> B :: Γ1)). apply in_or_app. right. apply in_eq.
+  pose (In_n_imp_subformLF_is_non_0 (Γ0 ++ A --> B :: Γ1) A B H). unfold n_imp_subformS in is0.
+  simpl in is0. assert (n_imp_subformLF (Δ0 ++ Δ1) = 0). lia. lia.
+Qed.
+ +
+Lemma n_imp_subformLF_dist_app : forall l1 l2, n_imp_subformLF (l1 ++ l2) =
+                                               plus (n_imp_subformLF l1) (n_imp_subformLF l2).
+Proof.
+induction l1.
+- intros. auto.
+- intros. simpl. rewrite IHl1. lia.
+Qed.
+ +
+(* Second, we intend to define the notion of usable boxed formulae in a sequent. We also
+   prove that if this measure is 0 then no GLR rule can be applied to this sequent.
+
+   In the next definitions our aim is to define the list of all boxed subformulae (not
+   occurrences) of all the formulae in a sequent. *)

+ +
+Fixpoint subform_boxesF (A : MPropF) : list MPropF :=
+match A with
+ | # P => nil
+ | => nil
+ | Imp B C => (subform_boxesF B) ++ (remove_list (subform_boxesF B) (subform_boxesF C))
+ | Box B => (Box B) :: (subform_boxesF B)
+end.
+ +
+Fixpoint subform_boxesLF (l : list MPropF) : list MPropF :=
+match l with
+  | nil => nil
+  | h :: t => (subform_boxesF h) ++ (remove_list (subform_boxesF h) (subform_boxesLF t))
+end.
+ +
+Definition subform_boxesS (s : Seq) : list MPropF :=
+  (subform_boxesLF (fst s)) ++ (remove_list (subform_boxesLF (fst s)) (subform_boxesLF (snd s))).
+ +
+Lemma In_subform_boxesF_box : forall (A B : MPropF), In A (subform_boxesF B) -> is_boxedT A.
+Proof.
+unfold is_boxedT. intros A B. generalize dependent A. induction B ; intros.
+- simpl in H. destruct H.
+- simpl in H. destruct H.
+- simpl in H. apply in_app_or in H. destruct H.
+  * apply IHB1 in H. assumption.
+  * assert (In A (subform_boxesF B2)). apply In_remove_list_In_list in H. assumption.
+    apply IHB2 in H0. assumption.
+- simpl in H. destruct H. exists B. auto. apply IHB in H. assumption.
+Qed.
+ +
+Lemma In_subform_boxesLF_box : forall (A : MPropF) l, In A (subform_boxesLF l) -> is_boxedT A.
+Proof.
+unfold is_boxedT. intros A l. generalize dependent A. induction l ; intros.
+- simpl in H. destruct H.
+- simpl in H. apply in_app_or in H. destruct H. apply In_subform_boxesF_box in H. assumption.
+  apply In_remove_list_In_list in H. apply IHl. assumption.
+Qed.
+ +
+(* Then next lemmas help us reach our goal. *)
+ +
+Fixpoint length_form (a: MPropF) : nat :=
+match a with
+  | # n => 1
+  | => 1
+  | Imp a0 a1 => S (length_form a0 + length_form a1)
+  | Box a0 => S (length_form a0)
+end.
+ +
+Lemma S_le_False : forall (n : nat), S n <= n -> False.
+Proof.
+induction n.
+- intro. inversion H.
+- intro. apply Nat.succ_le_mono in H. apply IHn. assumption.
+Qed.
+ +
+Lemma in_subform_boxesF_smaller_length_form : forall (A B : MPropF), In A (subform_boxesF B) ->
+                (length_form A <= length_form B).
+Proof.
+intros A B. generalize dependent A. induction B; intros .
+- simpl. inversion H.
+- simpl. inversion H.
+- simpl. simpl in H. apply in_app_or in H. destruct H.
+  * apply IHB1 in H. lia.
+  * assert (In A (subform_boxesF B2)). apply In_remove_list_In_list in H. assumption.
+    apply IHB2 in H0. lia.
+- simpl in H. destruct H. subst. auto. apply IHB in H. simpl. apply le_S. assumption.
+Qed.
+ +
+Lemma contradic_subform_boxesF: forall A l, (l = (subform_boxesF A)) -> (In (Box A) l) -> False.
+Proof.
+intros. subst. pose (in_subform_boxesF_smaller_length_form (Box A) A H0).
+inversion l.
+- apply eq_S_F in H1. assumption.
+- simpl in l. apply S_le_False in l. assumption.
+Qed.
+ +
+Lemma NoDup_subform_boxesF : forall A, NoDup (subform_boxesF A).
+Proof.
+induction A.
+- simpl. apply NoDup_nil.
+- simpl. apply NoDup_nil.
+- simpl. apply add_remove_list_preserve_NoDup. apply IHA1. apply IHA2.
+- simpl. apply NoDup_cons. intro. apply contradic_subform_boxesF in H. assumption.
+  reflexivity. apply IHA.
+Qed.
+ +
+Lemma subform_boxesLF_dist_app : forall l1 l2,
+        (subform_boxesLF (l1 ++ l2)) =
+        (subform_boxesLF l1) ++ (remove_list (subform_boxesLF l1) (subform_boxesLF l2)).
+Proof.
+induction l1.
+- intros l2. simpl. reflexivity.
+- intros l2. simpl. rewrite IHl1. repeat rewrite <- app_assoc.
+  assert (E: remove_list (subform_boxesF a) (subform_boxesLF l1 ++
+             remove_list (subform_boxesLF l1) (subform_boxesLF l2)) =
+             remove_list (subform_boxesF a) (subform_boxesLF l1) ++
+             remove_list (subform_boxesF a ++ remove_list (subform_boxesF a)
+             (subform_boxesLF l1)) (subform_boxesLF l2)).
+  { rewrite app_remove_list. rewrite redund_remove_list. rewrite <- remove_list_dist_app. reflexivity. }
+  rewrite E. reflexivity.
+Qed.
+ +
+Lemma NoDup_subform_boxesLF : forall l, NoDup (subform_boxesLF l).
+Proof.
+induction l.
+- intros. simpl. apply NoDup_nil.
+- intros. simpl. apply add_remove_list_preserve_NoDup. apply NoDup_subform_boxesF.
+  apply IHl.
+Qed.
+ +
+Lemma NoDup_subform_boxesS : forall s, NoDup (subform_boxesS s).
+Proof.
+intro s. unfold subform_boxesS. apply add_remove_list_preserve_NoDup ;
+apply NoDup_subform_boxesLF.
+Qed.
+ +
+Lemma univ_gen_ext_incl_subform_boxes : forall l1 l2 P, (univ_gen_ext P l1 l2) ->
+                                          incl (subform_boxesLF l1) (subform_boxesLF l2).
+Proof.
+intros. induction X.
+- unfold incl. intros. auto.
+- unfold incl. intros. simpl in H. simpl. apply in_app_or in H. destruct H.
+  * apply in_or_app. left. assumption.
+  * apply In_remove_list_In_list_not_In_remove_list in H. destruct H.
+    apply in_or_app. right. apply not_removed_remove_list. apply IHX. assumption.
+    assumption.
+- unfold incl. intros. simpl. destruct (In_dec (subform_boxesF x) a).
+  * apply in_or_app. left. assumption.
+  * apply in_or_app. right. apply not_removed_remove_list. apply IHX. assumption.
+    assumption.
+Qed.
+ +
+Lemma XBoxed_list_same_subform_boxes : forall l,
+          incl (subform_boxesLF (XBoxed_list l)) (subform_boxesLF l) /\
+          incl (subform_boxesLF l) (subform_boxesLF (XBoxed_list l)).
+Proof.
+induction l.
+- split.
+  * unfold incl. intros. simpl in H. inversion H.
+  * unfold incl. intros. simpl in H. inversion H.
+- split.
+  * unfold incl. intros. simpl. simpl in H. apply in_app_or in H. destruct H.
+    apply in_or_app. left. destruct a ; simpl in H ; try contradiction.
+    simpl. assumption. simpl. right. assumption. apply In_remove_list_In_list in H.
+    apply in_app_or in H. destruct H. apply in_or_app. left. assumption. apply in_or_app.
+    right. apply In_remove_list_In_list_not_In_remove_list in H. destruct H. destruct IHl.
+    apply H1 in H. apply not_removed_remove_list ; assumption.
+  * destruct IHl. unfold incl. intros. simpl in H1. apply in_app_or in H1. destruct H1.
+    destruct a ; simpl in H1 ; try contradiction. apply in_app_or in H1. destruct H1.
+    simpl. apply in_or_app. left. apply in_or_app. left. assumption. apply
+    In_remove_list_In_list_not_In_remove_list in H1. destruct H1. simpl. apply in_or_app.
+    left. apply in_or_app. right. apply not_removed_remove_list ; assumption. destruct H1.
+    subst. simpl. apply in_or_app. right. apply not_removed_remove_list. apply in_eq.
+    intros. apply contradic_subform_boxesF in H1. assumption. auto. simpl. apply in_or_app.
+    left. assumption. simpl. apply in_or_app. right. rewrite remove_list_dist_app.
+    apply in_or_app. right. apply not_removed_remove_list. apply
+    In_remove_list_In_list_not_In_remove_list in H1. destruct H1. apply H0 in H1.
+    apply not_removed_remove_list ; assumption. intro. apply
+    In_remove_list_In_list_not_In_remove_list in H1. destruct H1. destruct a ; simpl ; try assumption.
+    simpl (unBox_formula (a1 --> a2)) in H2. firstorder. simpl (unBox_formula (Box a)) in H2.
+    apply H3. simpl. right. assumption.
+Qed.
+ +
+Lemma In_incl_subform_boxes : forall l A, In A l ->
+                  (forall B, In B (subform_boxesF A) -> In B (subform_boxesLF l)).
+Proof.
+induction l.
+- intros. inversion H.
+- intros. simpl. inversion H.
+  * subst. apply in_or_app. left. assumption.
+  * pose (IHl A H1). destruct (In_dec (subform_boxesF a) B).
+    + apply in_or_app. left. assumption.
+    + apply in_or_app. right. apply not_removed_remove_list. apply i. assumption.
+      assumption.
+Qed.
+ +
+(* Now we can define the notion of usable boxed formulae: it is a one such that
+   it does not appear as a top formula in the LHS of the sequent. To do so, we need to
+   define the list of such formulae: *)

+ +
+Lemma top_boxes_incl_list : forall l, incl (top_boxes l) l.
+Proof.
+induction l.
+- simpl. unfold incl. intros. inversion H.
+- unfold incl. intros. destruct a.
+  * simpl in H. apply in_cons. apply IHl. assumption.
+  * simpl in H. apply in_cons. apply IHl. assumption.
+  * simpl in H. apply in_cons. apply IHl. assumption.
+  * simpl in H. destruct H.
+    + subst. apply in_eq.
+    + apply in_cons. apply IHl. assumption.
+Qed.
+ +
+Lemma in_top_boxes : forall l A, (In A (top_boxes l)) -> (existsT2 B l1 l2, (A = Box B) * (l = l1 ++ A :: l2)).
+Proof.
+induction l.
+- intros. simpl in H. inversion H.
+- intros. destruct a as [n | | |].
+  * simpl in H. apply IHl in H. destruct H. destruct s. destruct s. destruct p. subst.
+    exists x. exists ([# n] ++ x0). exists x1. auto.
+  * simpl in H. apply IHl in H. destruct H. destruct s. destruct s. destruct p. subst.
+    exists x. exists ([] ++ x0). exists x1. auto.
+  * simpl in H. apply IHl in H. destruct H. destruct s. destruct s. destruct p. subst.
+    exists x. exists ([a1 --> a2] ++ x0). exists x1. auto.
+  * simpl (top_boxes (Box a :: l)) in H. destruct (eq_dec_form (Box a) A).
+    + subst. exists a. exists []. exists l. auto.
+    + subst. assert (H0 : In A (top_boxes l)). inversion H. exfalso. apply n. assumption.
+      assumption. apply IHl in H0. destruct H0. destruct s. destruct s. destruct p.
+      subst. exists x. exists ([Box a] ++ x0). exists x1. auto.
+Qed.
+ +
+Lemma box_preserv_top_boxes : forall l1 l2 l3 A, top_boxes l1 = l2 ++ Box A :: l3 ->
+                                existsT2 l4 l5, l1 = l4 ++ Box A :: l5.
+Proof.
+induction l1.
+- intros. simpl in H. destruct l2 ; inversion H.
+- induction l2.
+  * intros. rewrite app_nil_l in H. destruct a as [n | | |].
+    + pose (IHl1 [] l3 A). simpl in s. apply s in H. destruct H. destruct s0. exists ([# n] ++ x).
+      exists x0. subst. auto.
+    + pose (IHl1 [] l3 A). simpl in s. apply s in H. destruct H. destruct s0. exists ([] ++ x).
+      exists x0. subst. auto.
+    + pose (IHl1 [] l3 A). simpl in s. apply s in H. destruct H. destruct s0. exists ([a1 --> a2] ++ x).
+      exists x0. subst. auto.
+    + inversion H. exists []. exists l1. auto.
+  * intros. destruct a as [n | | |].
+    + simpl in H. pose (IHl1 (a0 :: l2) l3 A). simpl in s. apply s in H. destruct H. destruct s0. exists ([# n] ++ x).
+      exists x0. subst. auto.
+    + simpl in H. pose (IHl1 (a0 :: l2) l3 A). simpl in s. apply s in H. destruct H. destruct s0. exists ([] ++ x).
+      exists x0. subst. auto.
+    + simpl in H. pose (IHl1 (a0 :: l2) l3 A). simpl in s. apply s in H. destruct H. destruct s0. exists ([a1 --> a2] ++ x).
+      exists x0. subst. auto.
+    + inversion H. apply IHl1 in H2. destruct H2. destruct s. subst. exists (Box a :: x). exists x0. auto.
+Qed.
+ +
+Lemma removed_box_exists : forall l1 l2 l3 A,
+    (remove_list (top_boxes l1) (top_boxes (l2 ++ Box A :: l3))) = nil ->
+    (existsT2 l4 l5, l1 = l4 ++ Box A :: l5).
+Proof.
+intros. pose (box_in_top_boxes l2 l3 A). repeat destruct s. rewrite e in H.
+remember (top_boxes l1) as l. apply remove_list_in_nil in H. destruct H.
+destruct s. subst. apply box_preserv_top_boxes in e0. assumption.
+Qed.
+ +
+Lemma is_box_in_top_boxes : forall l A, In A l -> is_boxedT A -> In A (top_boxes l).
+Proof.
+induction l.
+- intros. inversion H.
+- intros. inversion H.
+  * subst. inversion X. subst. simpl. left. reflexivity.
+  * pose (IHl A H0 X). destruct a ; simpl ; try assumption.
+    right. assumption.
+Qed.
+ +
+(* Some more 'macro' lemmas dealing with subform_boxes and top_boxes. *)
+ +
+Lemma RHS_top_box_is_subformLF : forall (s : Seq) (A : MPropF),
+        (In A (top_boxes (snd s))) -> (In A (subform_boxesLF (snd s))).
+Proof.
+intros s A H. apply in_top_boxes in H. destruct H. repeat destruct s0. destruct p. subst. rewrite e0.
+rewrite subform_boxesLF_dist_app. apply in_or_app. pose (In_dec (subform_boxesLF x0) (Box x)).
+destruct s0.
+- left. assumption.
+- right. apply not_removed_remove_list.
+  * simpl. left. reflexivity.
+  * assumption.
+Qed.
+ +
+Lemma RHS_top_box_is_subform : forall s A, (In A (top_boxes (snd s))) -> (In A (subform_boxesS s)).
+Proof.
+intros s A H. unfold subform_boxesS. apply RHS_top_box_is_subformLF in H.
+apply remove_list_is_in with (l2:=subform_boxesLF (fst s)) in H. assumption.
+Qed.
+ +
+(* Finally, we can define the list of usable boxed formulae. The length of that list is
+   the first component of our measure. *)

+ +
+Definition usable_boxes (s : Seq) : list MPropF :=
+   remove_list (top_boxes (fst s)) (subform_boxesS s).
+ +
+(* We can show that our notion of usable box effectively captures what it is intended to:
+   an upper bound on how many GLR rules can be applied to a sequent. To check this, we can
+   show that if the number of usable boxes is effectively 0 then no GLR is applicable. This
+   is the content of the lemma length_usable_boxes_is_0. *)

+ +
+Lemma no_RHS_box_no_GLR (s : Seq) :
+    (top_boxes (snd s)) = nil -> (existsT2 ps, GLRRule ps s) -> False.
+Proof.
+intros isnil RA. destruct RA. inversion g. subst. simpl in isnil.
+rewrite top_boxes_distr_app in isnil. apply app_eq_nil in isnil. destruct isnil.
+simpl in H1. inversion H1.
+Qed.
+ +
+Lemma all_RHS_boxes_are_LHS_boxes_no_GLR (s : Seq) :
+    (IdBRule [] s -> False) -> (* This line makes sure that we do PS: no IdB can happen. *)
+    (remove_list (top_boxes (fst s)) (top_boxes (snd s))) = nil ->
+    (existsT2 ps, GLRRule ps s) -> False.
+Proof.
+intros noId isnil RA. destruct RA. inversion g. subst. simpl in isnil.
+apply noId. apply removed_box_exists in isnil. destruct isnil. destruct s.
+subst. apply IdBRule_I.
+Qed.
+ +
+Lemma no_usable_boxes_all_RHS_are_LHS (s : Seq) :
+    length (usable_boxes s) = 0 -> (remove_list (top_boxes (fst s)) (top_boxes (snd s))) = nil.
+Proof.
+intro is0. remember (usable_boxes s) as l. destruct l.
+- unfold usable_boxes in Heql. symmetry in Heql. rewrite remove_list_is_nil in Heql.
+  rewrite remove_list_is_nil. intros. apply RHS_top_box_is_subform in H. apply Heql. assumption.
+- inversion is0.
+Qed.
+ +
+Theorem length_usable_boxes_is_0 (s : Seq) :
+    length (usable_boxes s) = 0 ->
+    (IdBRule [] s -> False) ->
+    (existsT2 ps, GLRRule ps s) -> False.
+Proof.
+intros H0 H1. pose (no_usable_boxes_all_RHS_are_LHS s H0).
+pose (all_RHS_boxes_are_LHS_boxes_no_GLR H1 e). assumption.
+Qed.
+ +
+Lemma NoDup_usable_boxes : forall s, NoDup (usable_boxes s).
+Proof.
+intro s. unfold usable_boxes. destruct s. simpl. unfold subform_boxesS.
+simpl. pose (NoDup_subform_boxesLF l0). pose (NoDup_subform_boxesLF l).
+pose (add_remove_list_preserve_NoDup _ _ n0 n). apply remove_list_preserv_NoDup.
+assumption.
+Qed.
+ +
+(* We can consequently define our measure on sequents: *)
+ +
+Definition measure (s : Seq) : list nat :=
+  [length (usable_boxes s) ; (n_imp_subformS s)].
+ +
+(* Fourth, we show that the number of usable boxes decreases upwards in the application
+   of a GLR rule. To do so we need to prove some lemmas beforehand. *)

+ +
+Lemma GLR_applic_more_top_boxes : forall prem concl, GLRRule [prem] concl ->
+                                                     (IdBRule [] concl -> False) ->
+                                    incl (top_boxes (fst concl)) (top_boxes (fst prem)).
+Proof.
+intros prem concl RA noIdB. inversion RA. subst. simpl. rewrite top_boxes_distr_app.
+simpl. unfold incl. intros. apply in_or_app. left. assert (In a Γ0). apply in_top_boxes in H.
+destruct H. repeat destruct s. destruct p. subst. apply in_or_app. right. apply in_eq.
+assert (InT a Γ0). apply in_splitT in H1. destruct H1. destruct s. rewrite e.
+apply InT_or_app. right. apply InT_eq. pose (InT_univ_gen_ext H2 X). destruct s.
+exfalso. apply f. apply in_top_boxes in H. destruct H. repeat destruct s.
+destruct p. exists x. assumption. apply top_boxes_incl_list in H.
+pose (list_preserv_XBoxed_list ). pose (InT_In i). apply i0 in i1.
+apply is_box_in_top_boxes. apply i0. apply InT_In. assumption.
+apply H0. apply InT_In. assumption.
+Qed.
+ +
+Lemma GLR_applic_le_subform_boxes : forall prem concl, GLRRule [prem] concl ->
+                                                        (IdBRule [] concl -> False) ->
+                        (length (subform_boxesS prem) <= length (subform_boxesS concl) /\
+                         forall B, (In B (subform_boxesS prem)) -> (In B (subform_boxesS concl))).
+Proof.
+intros prem concl RA noIdB. inversion RA. subst. split.
+- apply NoDup_incl_length.
+  * apply NoDup_subform_boxesS.
+  * intro. intros. unfold subform_boxesS in H. unfold subform_boxesS. simpl. simpl in H.
+    repeat rewrite app_length. repeat rewrite app_length in H. repeat rewrite remove_list_of_nil.
+    repeat rewrite remove_list_of_nil in H. rewrite app_nil_r in H. apply in_app_or in H.
+    destruct H. rewrite subform_boxesLF_dist_app in H. apply in_app_or in H. destruct H.
+    apply in_or_app. left. apply univ_gen_ext_incl_subform_boxes in X. apply X. pose (XBoxed_list_same_subform_boxes ).
+    destruct a0. apply H1. assumption. apply In_remove_list_In_list in H.
+    apply remove_list_is_in. rewrite subform_boxesLF_dist_app. apply remove_list_is_in.
+    simpl. simpl in H. destruct H. left. assumption. right. repeat rewrite remove_list_of_nil in H.
+    apply in_app_or in H. destruct H. apply in_or_app. auto. simpl in H. destruct H.
+    apply remove_list_is_in. apply In_remove_list_In_list in H. rewrite subform_boxesLF_dist_app.
+    apply remove_list_is_in. simpl. right. apply in_or_app. auto.
+- intro. intros. unfold subform_boxesS in H. unfold subform_boxesS. simpl. simpl in H.
+  repeat rewrite app_length. repeat rewrite app_length in H. repeat rewrite remove_list_of_nil.
+  repeat rewrite remove_list_of_nil in H. rewrite app_nil_r in H. apply in_app_or in H.
+  destruct H. rewrite subform_boxesLF_dist_app in H. apply in_app_or in H. destruct H.
+  apply in_or_app. left. apply univ_gen_ext_incl_subform_boxes in X. apply X. pose (XBoxed_list_same_subform_boxes ).
+  destruct a. apply H1. assumption. apply In_remove_list_In_list in H.
+  apply remove_list_is_in. rewrite subform_boxesLF_dist_app. apply remove_list_is_in.
+  simpl. simpl in H. destruct H. left. assumption. right. repeat rewrite remove_list_of_nil in H.
+  apply in_app_or in H. destruct H. apply in_or_app. auto. simpl in H. destruct H.
+  apply remove_list_is_in. apply In_remove_list_In_list in H. rewrite subform_boxesLF_dist_app.
+  apply remove_list_is_in. simpl. right. apply in_or_app. auto.
+Qed.
+ +
+Theorem GLR_applic_less_usable_boxes : forall prem concl, GLRRule [prem] concl ->
+                                                          (IdBRule [] concl -> False) ->
+                                         length (usable_boxes prem) < length (usable_boxes concl).
+Proof.
+intros prem concl RA noIdB. inversion RA. unfold usable_boxes. simpl.
+apply remove_list_incr_decr.
+- apply NoDup_subform_boxesS.
+- apply NoDup_subform_boxesS.
+- exists (Box A). repeat split. simpl. rewrite top_boxes_distr_app. apply in_or_app. right. simpl.
+  left. reflexivity. unfold subform_boxesS. simpl.
+  destruct (In_dec (subform_boxesLF Γ0) (Box A)). apply in_or_app. left. assumption.
+  apply in_or_app. right. apply not_removed_remove_list. rewrite subform_boxesLF_dist_app.
+  destruct (In_dec (subform_boxesLF Δ0) (Box A)). apply in_or_app. left. assumption.
+  apply in_or_app. right. apply not_removed_remove_list. simpl. auto. assumption. assumption.
+  intro. simpl in H2. apply noIdB. subst. pose (in_top_boxes Γ0 (Box A) H2). repeat destruct s.
+  destruct p. subst. apply IdBRule_I.
+- intro A0. pose (@GLR_applic_more_top_boxes prem concl). subst. pose (i RA). pose (i0 noIdB).
+  apply i1.
+- intro A0. subst. pose (GLR_applic_le_subform_boxes RA noIdB). destruct a. apply H1.
+Qed.
+ +
+Theorem ImpR_applic_less_Imp_same_usable_boxes : forall prem concl, ImpRRule [prem] concl ->
+                   prod (sumbool (length (usable_boxes prem) < length(usable_boxes concl))
+                    (length (usable_boxes prem) = length(usable_boxes concl)))
+                   (n_imp_subformS (prem) < n_imp_subformS (concl)).
+Proof.
+intros prem concl RA. inversion RA. subst. split.
+- pose (NoDup_usable_boxes (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)).
+  pose (NoDup_usable_boxes (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1)).
+  apply NoDup_incl_lengthT. assumption. unfold incl. intros. unfold usable_boxes in H. simpl in H.
+  unfold usable_boxes. simpl. apply In_remove_list_In_list_not_In_remove_list in H.
+  destruct H. apply not_removed_remove_list. unfold subform_boxesS. unfold subform_boxesS in H.
+  simpl. simpl in H. apply in_app_or in H. destruct H. rewrite subform_boxesLF_dist_app in H.
+  apply in_app_or in H. destruct H. apply in_or_app. left. rewrite subform_boxesLF_dist_app.
+  apply in_or_app. left. assumption. apply In_remove_list_In_list_not_In_remove_list in H.
+  destruct H. simpl in H. apply in_app_or in H. destruct H. destruct (In_dec (subform_boxesLF (Γ0 ++ Γ1)) a).
+  apply in_or_app. left. assumption. apply in_or_app. right. apply not_removed_remove_list.
+  2: assumption. apply In_incl_subform_boxes with (A:=A --> B). apply in_or_app. right. apply in_eq.
+  simpl. apply in_or_app. left.
+  assumption. apply In_remove_list_In_list_not_In_remove_list in H. destruct H. apply in_or_app. left.
+  rewrite subform_boxesLF_dist_app. apply in_or_app. right. apply not_removed_remove_list. assumption.
+  assumption. apply In_remove_list_In_list_not_In_remove_list in H. destruct H. rewrite subform_boxesLF_dist_app in H.
+  apply in_app_or in H. destruct H. apply in_or_app. right. apply not_removed_remove_list.
+  rewrite subform_boxesLF_dist_app. apply in_or_app. left. assumption. intro.
+  apply H1. rewrite subform_boxesLF_dist_app. apply in_or_app.
+  rewrite subform_boxesLF_dist_app in H2. apply in_app_or in H2.
+  destruct H2. auto. apply In_remove_list_In_list_not_In_remove_list in H2. destruct H2.
+  right. apply not_removed_remove_list. simpl. apply in_or_app. right. apply not_removed_remove_list.
+  assumption. intro. apply H1. rewrite subform_boxesLF_dist_app. apply in_or_app. right.
+  apply not_removed_remove_list. simpl. apply in_or_app. left. assumption. assumption. assumption.
+  apply in_or_app. right. apply not_removed_remove_list. apply In_remove_list_In_list_not_In_remove_list in H.
+  destruct H. simpl in H. apply in_app_or in H. destruct H. apply In_incl_subform_boxes with (A:=A --> B).
+  apply in_or_app. right. apply in_eq. simpl. apply in_or_app. right. apply not_removed_remove_list. assumption.
+  intro. apply H1. rewrite subform_boxesLF_dist_app. apply in_or_app. right. apply not_removed_remove_list.
+  simpl. apply in_or_app. left. assumption. intro. apply H1. rewrite subform_boxesLF_dist_app. apply in_or_app.
+  auto. apply In_remove_list_In_list_not_In_remove_list in H. destruct H.
+  rewrite subform_boxesLF_dist_app.
+  apply in_or_app. right. apply not_removed_remove_list. simpl. apply in_or_app. right.
+  apply not_removed_remove_list. assumption. intro. apply in_app_or in H4. destruct H4.
+  apply H1. rewrite subform_boxesLF_dist_app. apply in_or_app. right. apply not_removed_remove_list.
+  simpl. apply in_or_app. left. assumption. intro. apply H1. rewrite subform_boxesLF_dist_app.
+  apply in_or_app. auto. apply H3. apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4.
+  assumption. assumption. intro. apply H1. rewrite subform_boxesLF_dist_app.
+  apply in_or_app. rewrite subform_boxesLF_dist_app in H2. apply in_app_or in H2.
+  destruct H2. auto. apply In_remove_list_In_list_not_In_remove_list in H2.
+  destruct H2. right. apply not_removed_remove_list. simpl. apply in_or_app. right.
+  apply not_removed_remove_list. assumption. intro. apply H1. rewrite subform_boxesLF_dist_app.
+  apply in_or_app. right. apply not_removed_remove_list. simpl. apply in_or_app. auto.
+  assumption. assumption. intro. apply H0. rewrite top_boxes_distr_app. rewrite top_boxes_distr_app in H1.
+  apply in_app_or in H1. destruct H1. apply in_or_app. auto. apply in_or_app. right.
+  assert (A :: Γ1 = [A] ++ Γ1). auto. rewrite H2. rewrite top_boxes_distr_app. apply in_or_app. right.
+  auto.
+- unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl. lia.
+Qed.
+ +
+Theorem ImpL_applic_less_Imp_same_usable_boxes : forall prem1 prem2 concl, ImpLRule [prem1 ; prem2] concl ->
+                   prod (prod (sumbool (length (usable_boxes prem1) < length(usable_boxes concl))
+                    (length (usable_boxes prem1) = length(usable_boxes concl)))
+                   (n_imp_subformS (prem1) < n_imp_subformS (concl)))
+                   (prod (sumbool (length (usable_boxes prem2) < length(usable_boxes concl))
+                    (length (usable_boxes prem2) = length(usable_boxes concl)))
+                   (n_imp_subformS (prem2) < n_imp_subformS (concl))).
+Proof.
+intros prem1 prem2 concl RA. inversion RA. subst. split.
+- split.
+  * pose (NoDup_usable_boxes (Γ0 ++ Γ1, Δ0 ++ A :: Δ1)).
+    pose (NoDup_usable_boxes (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+    apply NoDup_incl_lengthT. assumption. unfold incl. intros. unfold usable_boxes in H. simpl in H.
+    unfold usable_boxes. simpl. apply In_remove_list_In_list_not_In_remove_list in H.
+    destruct H. apply not_removed_remove_list. unfold subform_boxesS. unfold subform_boxesS in H.
+    simpl. simpl in H. apply in_app_or in H. destruct H. rewrite subform_boxesLF_dist_app in H.
+    apply in_app_or in H. destruct H. apply in_or_app. left. rewrite subform_boxesLF_dist_app.
+    apply in_or_app. auto. apply in_or_app.
+    apply In_remove_list_In_list_not_In_remove_list in H. destruct H. left.
+    rewrite subform_boxesLF_dist_app. apply in_or_app. right.
+    apply not_removed_remove_list. simpl. apply in_or_app.
+    destruct (In_dec (subform_boxesF A ++ remove_list (subform_boxesF A) (subform_boxesF B)) a).
+    auto. right. apply not_removed_remove_list.
+    assumption. assumption. assumption. apply In_remove_list_In_list_not_In_remove_list in H.
+    destruct H. rewrite subform_boxesLF_dist_app in H. apply in_app_or in H. destruct H. apply in_or_app.
+    destruct (In_dec (subform_boxesLF (Γ0 ++ A --> B :: Γ1)) a). auto. right. apply not_removed_remove_list.
+    2: assumption. rewrite subform_boxesLF_dist_app. apply in_or_app. auto.
+    apply in_or_app. apply In_remove_list_In_list_not_In_remove_list in H. destruct H. simpl in H. apply in_app_or in H.
+    destruct H. left. assert (In a (subform_boxesF (A --> B))). simpl. apply in_or_app. auto.
+    apply In_incl_subform_boxes with (A:=A --> B). apply in_or_app. right. apply in_eq. assumption.
+    apply In_remove_list_In_list_not_In_remove_list in H. destruct H.
+    destruct (In_dec (subform_boxesLF (Γ0 ++ A --> B :: Γ1)) a). auto. right.
+    apply not_removed_remove_list. rewrite subform_boxesLF_dist_app. apply in_or_app. right. apply not_removed_remove_list.
+    assumption. assumption. assumption. intro. apply H0. rewrite top_boxes_distr_app in H1. rewrite top_boxes_distr_app.
+    apply in_or_app. apply in_app_or in H1. destruct H1. auto. simpl in H1. auto.
+  * unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl. lia.
+- split.
+  * pose (NoDup_usable_boxes (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)).
+    pose (NoDup_usable_boxes (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+    apply NoDup_incl_lengthT. assumption. unfold incl. intros. unfold usable_boxes in H. simpl in H.
+    unfold usable_boxes. simpl. apply In_remove_list_In_list_not_In_remove_list in H.
+    destruct H. apply not_removed_remove_list. unfold subform_boxesS. unfold subform_boxesS in H.
+    simpl. simpl in H. apply in_app_or in H. destruct H.
+    apply in_or_app. left. rewrite subform_boxesLF_dist_app in H.
+    apply in_app_or in H. destruct H. rewrite subform_boxesLF_dist_app. apply in_or_app. auto.
+    apply In_remove_list_In_list_not_In_remove_list in H. destruct H. simpl in H. apply in_app_or in H.
+    destruct H. simpl. rewrite subform_boxesLF_dist_app. apply in_or_app. right.
+    apply not_removed_remove_list. simpl. apply in_or_app. destruct (In_dec (subform_boxesF A) a).
+    left. apply in_or_app. auto. left.
+    apply in_or_app. right. apply not_removed_remove_list. assumption. assumption. assumption.
+    apply In_remove_list_In_list_not_In_remove_list in H. destruct H. rewrite subform_boxesLF_dist_app.
+    apply in_or_app. right. apply not_removed_remove_list. simpl. destruct (In_dec (subform_boxesF A) a).
+    apply in_or_app. left. apply in_or_app. auto. apply in_or_app. right.
+    apply not_removed_remove_list. assumption. intro. apply in_app_or in H3. destruct H3.
+    apply n1. auto. apply In_remove_list_In_list_not_In_remove_list in H3. destruct H3. auto.
+    assumption. apply In_remove_list_In_list_not_In_remove_list in H. destruct H.
+    destruct (In_dec (subform_boxesLF (Γ0 ++ A --> B :: Γ1)) a). apply in_or_app. auto.
+    apply in_or_app. right. apply not_removed_remove_list. assumption. assumption.
+    intro. apply H0. rewrite top_boxes_distr_app. rewrite top_boxes_distr_app in H1.
+    apply in_app_or in H1. destruct H1. apply in_or_app. auto. simpl in H1.
+    apply in_or_app. right. assert (B :: Γ1 = [B] ++ Γ1). reflexivity. rewrite H2.
+    rewrite top_boxes_distr_app. apply in_or_app. auto.
+  * unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl. lia.
+Qed.
+ +
+(* Now we show that the measure decreases upwards in the rule applications we considered. *)
+ +
+Definition less_thanS (s0 s1 : Seq) : Prop := lex lt (measure s0) (measure s1).
+ +
+Notation "s0 '<<' s1" := (less_thanS s0 s1) (at level 70).
+ +
+Fact less_thanS_inv l m : l << m -> (lex lt (measure l) (measure m)).
+Proof.
+inversion 1; subst ; auto.
+Qed.
+ +
+Theorem less_thanS_wf : well_founded less_thanS.
+Proof.
+unfold less_thanS.
+apply wf_inverse_image. apply lex_wf.
+auto. apply Wf_nat.lt_wf.
+Qed.
+ +
+Fact lex_trans : forall l m n, (lex lt l m) -> (lex lt m n) -> (lex lt l n).
+Proof.
+intros l m n H. revert n. induction H.
+- intros. inversion H0 ; subst. apply lex_skip ; auto. apply lex_cons ; auto. apply lex_length in H ; lia.
+- intros. inversion H1 ; subst. apply lex_cons ; auto. apply lex_length in H5 ; lia.
+  apply lex_cons ; lia.
+Qed.
+ +
+Fact less_thanS_trans l m n : l << m -> m << n -> l << n.
+Proof.
+unfold less_thanS. apply lex_trans.
+Qed.
+ +
+(* Corollary less_thanS_rect (P : (list MPropF * (MPropF)) -> Type)
+(HP : forall s, (forall s1, (less_than lt (measure s1) (seq_list_occ_weight s)) -> P s1) -> P s) s : P s.
+Proof.
+  induction s as  s IHs  using (well_founded_induction_type less_thanS_wf).
+  apply HP; intros; apply IHs. unfold less_thanS ; auto.
+Qed. *)

+ +
+Lemma decT_lt : forall m n, (m < n) + ((m < n) -> False).
+Proof.
+induction m.
+- destruct n. right. intro. inversion H. left. lia.
+- destruct n. right. intro. inversion H. pose (IHm n). destruct s. left. lia. right. intro. apply f. lia.
+Qed.
+ +
+Lemma decT_lex_lt : forall l0 l1, (lex lt l0 l1) + ((lex lt l0 l1) -> False).
+Proof.
+induction l0 ; intros.
+- destruct l1. right ; intro. inversion H ; auto. right ; intro. inversion H ; auto.
+- destruct l1. right ; intro. inversion H ; auto.
+  destruct (IHl0 l1).
+  + pose (lex_length l). destruct (decT_lt a n).
+      * left. apply lex_cons ; auto.
+      * destruct (Nat.eq_dec a n) ; subst.
+        left. apply lex_skip ; auto.
+        right. intro. inversion H ; subst ; auto.
+  + destruct (decT_lt a n).
+      * destruct (Nat.eq_dec (length l0) (length l1)). left. apply lex_cons ; auto.
+        right. intro. inversion H ; auto.
+      * right. intro. inversion H ; auto.
+Qed.
+ +
+Lemma decT_less_than_lt : forall l0 l1, (less_thanS l0 l1) + ((less_thanS l0 l1) -> False).
+Proof.
+intros. destruct l0, l1. unfold less_thanS.
+apply decT_lex_lt.
+Qed.
+ +
+Theorem less_thanS_strong_inductionT:
+forall P : Seq -> Type,
+(forall s0 : Seq, (forall s1 : Seq, ((s1 << s0) -> P s1)) -> P s0) ->
+forall s : Seq, P s.
+Proof.
+  induction s as [ s IHs ] using (well_founded_induction_type less_thanS_wf).
+  apply X; intros; apply IHs. unfold less_thanS ; auto.
+Qed.
+ +
+Theorem GLR_applic_reduces_measure : forall prem concl,
+                GLRRule [prem] concl ->
+                (IdBRule [] concl -> False) ->
+                prem << concl.
+Proof.
+intros. apply lex_cons ; auto.
+apply GLR_applic_less_usable_boxes ; auto.
+Qed.
+ +
+Theorem ImpR_applic_reduces_ub_or_imp : forall prem concl,
+                ImpRRule [prem] concl ->
+                ((length (usable_boxes prem) < length (usable_boxes concl)) +
+                ((length (usable_boxes prem) = length (usable_boxes concl)) *
+                (n_imp_subformS prem < n_imp_subformS concl))).
+Proof.
+intros.
+pose (ImpR_applic_less_Imp_same_usable_boxes H). destruct p ; auto.
+destruct s ; auto.
+Qed.
+ +
+Theorem ImpR_applic_reduces_measure : forall prem concl,
+                ImpRRule [prem] concl ->
+                prem << concl.
+Proof.
+intros. destruct (ImpR_applic_less_Imp_same_usable_boxes H).
+destruct s.
+- apply lex_cons ; auto.
+- unfold less_thanS ; unfold measure ; rewrite e ; apply lex_skip ; auto.
+  apply lex_cons ; auto.
+Qed.
+ +
+Theorem ImpL_applic_reduces_ub_or_imp : forall prem1 prem2 concl,
+                ImpLRule [prem1; prem2] concl ->
+                ((length (usable_boxes prem1) < length (usable_boxes concl)) +
+                ((length (usable_boxes prem1) = length (usable_boxes concl)) *
+                (n_imp_subformS prem1 < n_imp_subformS concl))) *
+                ((length (usable_boxes prem2) < length (usable_boxes concl)) +
+                ((length (usable_boxes prem2) = length (usable_boxes concl)) *
+                (n_imp_subformS prem2 < n_imp_subformS concl))).
+Proof.
+intros.
+pose (ImpL_applic_less_Imp_same_usable_boxes H). destruct p ; auto. destruct p ; auto.
+destruct p0 ; auto. destruct s ; auto. destruct s0 ; auto. destruct s0 ; auto.
+Qed.
+ +
+Theorem ImpL_applic_reduces_measure : forall prem1 prem2 concl,
+                ImpLRule [prem1; prem2] concl ->
+                (prem1 << concl) * (prem2 << concl).
+Proof.
+intros. destruct (ImpL_applic_less_Imp_same_usable_boxes H).
+destruct p, p0. split.
+- destruct s.
+  + apply lex_cons ; auto.
+  + unfold less_thanS ; unfold measure ; rewrite e ; apply lex_skip ; auto.
+    apply lex_cons ; auto.
+- destruct s0.
+  + apply lex_cons ; auto.
+  + unfold less_thanS ; unfold measure ; rewrite e ; apply lex_skip ; auto.
+    apply lex_cons ; auto.
+Qed.
+
+
+ +
+ + + diff --git a/GL.GLS.GLS_wkn.html b/GL.GLS.GLS_wkn.html new file mode 100644 index 0000000..fbacc75 --- /dev/null +++ b/GL.GLS.GLS_wkn.html @@ -0,0 +1,584 @@ + + + + + + + + + + + + + +
+
+

GL.GLS.GLS_wkn

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat.
+Require Import Lia.
+Require Import Arith.
+ +
+Require Import GLS_calcs.
+Require Import GLS_dec.
+ +
+Set Implicit Arguments.
+ +
+(* We define the relations which take care of the notion of weakening. *)
+ +
+Inductive wkn_L (fml : MPropF) : relationT Seq :=
+  | wkn_LI Γ0 Γ1 Δ : wkn_L fml
+        (Γ0 ++ Γ1, Δ) (Γ0 ++ fml :: Γ1, Δ).
+ +
+Inductive wkn_R (fml : MPropF) : relationT Seq :=
+  | wkn_RI Γ Δ0 Δ1 : wkn_R fml
+        (Γ, Δ0 ++ Δ1) (Γ, Δ0 ++ fml :: Δ1).
+ +
+(* Some lemmas on the preservation of inapplicability of BotL through weakening. *)
+ +
+Lemma wkn_R_BotL_notapplic : forall s sw A,
+    (@wkn_R A s sw) ->
+    ((BotLRule [] s) -> False) ->
+    ((BotLRule [] sw) -> False).
+Proof.
+intros s sw A wkn RA RAw. apply RA.
+inversion RAw. destruct s. inversion wkn. subst. inversion H3.
+subst. apply BotLRule_I.
+Qed.
+ +
+(* The following lemmas make sure that if a rule is applied on a sequent s with
+premises ps, then the same rule is applicable on a sequent sw which is a weakened
+version of s, with some premises psw that are such that they are either the same premises
+(in case the weakened formula is weakened in the rule) or weakened versions of ps. *)

+ +
+Lemma ImpR_app_wkn_L : forall s sw A ps,
+  (@wkn_L A s sw) ->
+  (ImpRRule [ps] s) ->
+  (existsT2 psw, (ImpRRule [psw] sw) * (@wkn_L A ps psw)).
+Proof.
+intros s sw A ps wkn RA. inversion RA. inversion wkn. subst.
+inversion H. subst. apply app2_find_hole in H1. destruct H1.
+repeat destruct s ; destruct p ; subst.
+- exists (Γ2 ++ A0 :: A :: Γ3, Δ0 ++ B :: Δ1). repeat split ; try assumption.
+  rewrite cons_single. rewrite cons_single with (v:=A0). rewrite app_assoc. rewrite app_assoc with (l:=Γ2).
+  apply wkn_LI.
+- exists ((Γ2 ++ A :: x) ++ A0 :: Γ1, Δ0 ++ B :: Δ1). split.
+  * assert (Γ2 ++ A :: x ++ Γ1 = (Γ2 ++ A :: x) ++ Γ1). rewrite <- app_assoc. reflexivity.
+    rewrite H0. apply ImpRRule_I ; assumption.
+  * repeat rewrite <- app_assoc. apply wkn_LI.
+- exists (Γ0 ++ A0 :: x ++ A :: Γ3, Δ0 ++ B :: Δ1). split.
+  * repeat rewrite <- app_assoc. apply ImpRRule_I ; assumption.
+  * rewrite cons_single. rewrite cons_single with (v:=A0). rewrite app_assoc. rewrite app_assoc with (l:=Γ0).
+    rewrite app_assoc. rewrite app_assoc with (l:=(Γ0 ++ [A0])). apply wkn_LI.
+Qed.
+ +
+Lemma ImpL_app_wkn_L : forall s sw A ps1 ps2,
+  (@wkn_L A s sw) ->
+  (ImpLRule [ps1;ps2] s) ->
+  (existsT2 psw1 psw2, (ImpLRule [psw1;psw2] sw) *
+                                                  (@wkn_L A ps1 psw1) *
+                                                  (@wkn_L A ps2 psw2)).
+Proof.
+intros s sw A ps1 ps2 wkn RA. inversion RA. inversion wkn. subst.
+inversion H. subst. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
+  - exists (Γ2 ++ A :: Γ1, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ A :: B :: Γ1, Δ0 ++ Δ1).
+    split. split. assert (E1: Γ2 ++ A :: Γ1 = (Γ2 ++ [A]) ++ Γ1). rewrite <- app_assoc.
+    simpl. auto. rewrite E1. assert (E2 : Γ2 ++ A :: B :: Γ1 = (Γ2 ++ [A]) ++ B :: Γ1).
+    rewrite <- app_assoc. simpl. auto. rewrite E2. assert (E3 : Γ2 ++ A :: A0 --> B :: Γ1 = (Γ2 ++ [A]) ++ A0 --> B :: Γ1).
+    rewrite <- app_assoc. simpl. auto. rewrite E3. apply ImpLRule_I.
+    apply wkn_LI. apply wkn_LI.
+  - exists (Γ2 ++ A :: x ++ Γ1, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ A :: x ++ B :: Γ1, Δ0 ++ Δ1).
+    split. split. assert (E1: Γ2 ++ A :: x ++ Γ1 = (Γ2 ++ [A] ++ x) ++ Γ1). rewrite <- app_assoc.
+    simpl. auto. rewrite E1. assert (E2 : Γ2 ++ A :: x ++ B :: Γ1 = (Γ2 ++ [A] ++ x) ++ B :: Γ1).
+    rewrite <- app_assoc. simpl. auto. rewrite E2.
+    assert (E3 : Γ2 ++ A :: x ++ A0 --> B :: Γ1 = (Γ2 ++ [A] ++ x) ++ A0 --> B :: Γ1).
+    rewrite <- app_assoc. simpl. auto. rewrite E3. apply ImpLRule_I.
+    repeat rewrite <- app_assoc. apply wkn_LI. repeat rewrite <- app_assoc. apply wkn_LI.
+  - destruct x ; subst ; repeat rewrite app_nil_r.
+    + simpl in e0. subst. exists (Γ0 ++ A :: Γ1, Δ0 ++ A0 :: Δ1). exists (Γ0 ++ A :: B :: Γ1, Δ0 ++ Δ1) .
+      split. split. assert (E1: Γ0 ++ A :: Γ1 = (Γ0 ++ [A]) ++ Γ1). rewrite <- app_assoc.
+      simpl. auto. rewrite E1. assert (E2 : Γ0 ++ A :: B :: Γ1 = (Γ0 ++ [A]) ++ B :: Γ1).
+      rewrite <- app_assoc. simpl. auto. rewrite E2.
+      assert (E3 : Γ0 ++ A :: A0 --> B :: Γ1 = (Γ0 ++ [A]) ++ A0 --> B :: Γ1).
+      rewrite <- app_assoc. simpl. auto. rewrite E3. apply ImpLRule_I.
+      repeat rewrite <- app_assoc. apply wkn_LI. repeat rewrite <- app_assoc. apply wkn_LI.
+    + inversion e0. subst. exists (Γ0 ++ x ++ A :: Γ3, Δ0 ++ A0 :: Δ1).
+      exists (Γ0 ++ B :: x ++ A :: Γ3, Δ0 ++ Δ1). split. split.
+      repeat rewrite <- app_assoc. apply ImpLRule_I.
+      assert (Γ0 ++ x ++ Γ3 = (Γ0 ++ x) ++ Γ3). rewrite <- app_assoc. reflexivity.
+      rewrite H0. assert (Γ0 ++ x ++ A :: Γ3 = (Γ0 ++ x) ++ A :: Γ3). rewrite <- app_assoc. reflexivity.
+      rewrite H1. apply wkn_LI.
+      assert (Γ0 ++ B :: x ++ Γ3 = (Γ0 ++ B :: x) ++ Γ3). rewrite <- app_assoc. reflexivity.
+      rewrite H0. assert (Γ0 ++ B :: x ++ A :: Γ3 = (Γ0 ++ B :: x) ++ A :: Γ3). rewrite <- app_assoc. reflexivity.
+      rewrite H1. apply wkn_LI.
+Qed.
+ +
+Lemma GLR_app_wkn_L : forall s sw A ps,
+  (@wkn_L A s sw) ->
+  (GLRRule [ps] s) ->
+  ((GLRRule [ps] sw) +
+   (existsT2 psw1 psw2, (GLRRule [psw2] sw) * (@wkn_L (unBox_formula A) ps psw1) * (@wkn_L A psw1 psw2))).
+Proof.
+intros s sw A ps wkn RA. inversion RA. inversion wkn. rewrite <- H1 in H2.
+inversion H2. subst. destruct (dec_is_boxedT A).
+  * right. apply univ_gen_ext_splitR in X. destruct X. destruct s. repeat destruct p.
+    subst. exists (((XBoxed_list x) ++ (unBox_formula A) :: (XBoxed_list x0)) ++ [Box A0], [A0]).
+    exists (XBoxed_list (x ++ A :: x0) ++ [Box A0], [A0]). split. split.
+    + apply GLRRule_I. intro. intros. apply in_app_or in H. destruct H. apply H0. apply in_or_app. auto.
+      inversion H. subst. assumption. apply H0. apply in_or_app. auto. apply univ_gen_ext_combine.
+      assumption. apply univ_gen_ext_cons. assumption.
+    + rewrite XBox_app_distrib. repeat rewrite <- app_assoc. apply wkn_LI.
+    + rewrite XBox_app_distrib. simpl.
+      assert (E1: (XBoxed_list x ++ unBox_formula A :: XBoxed_list x0) ++ [Box A0] =
+      (XBoxed_list x ++ [unBox_formula A]) ++ XBoxed_list x0 ++ [Box A0]). repeat rewrite <- app_assoc.
+      simpl. reflexivity. rewrite E1.
+      assert (E2: (XBoxed_list x ++ unBox_formula A :: A :: XBoxed_list x0) ++ [Box A0] =
+      (XBoxed_list x ++ [unBox_formula A]) ++ A :: XBoxed_list x0 ++ [Box A0]). repeat rewrite <- app_assoc.
+      simpl. reflexivity. rewrite E2.
+      apply wkn_LI.
+  * left. apply GLRRule_I.
+    + assumption.
+    + apply univ_gen_ext_splitR in X. destruct X. destruct s. repeat destruct p.
+      subst. apply univ_gen_ext_combine. assumption. apply univ_gen_ext_extra. assumption.
+      assumption.
+Qed.
+ +
+Lemma ImpR_app_wkn_R : forall s sw A ps,
+  (@wkn_R A s sw) ->
+  (ImpRRule [ps] s) ->
+  ((existsT2 psw, (ImpRRule [psw] sw) * (@wkn_R A ps psw))).
+Proof.
+intros s sw A ps wkn RA. inversion RA. inversion wkn. subst. inversion H.
+subst. apply app2_find_hole in H2. destruct H2. repeat destruct s ; destruct p ; subst.
+  - exists (Γ0 ++ A0 :: Γ1, Δ2 ++ A :: B :: Δ1). split.
+    assert (E1: Δ2 ++ A :: B :: Δ1 = (Δ2 ++ [A]) ++ B :: Δ1). rewrite <- app_assoc.
+    simpl. auto. rewrite E1. assert (E3 : Δ2 ++ A :: A0 --> B :: Δ1 = (Δ2 ++ [A]) ++ A0 --> B :: Δ1).
+    rewrite <- app_assoc. simpl. auto. rewrite E3. apply ImpRRule_I.
+    apply wkn_RI.
+  - exists (Γ0 ++ A0 :: Γ1, Δ2 ++ A :: x ++ B :: Δ1).
+    split. assert (E1: Δ2 ++ A :: x ++ B :: Δ1 = (Δ2 ++ [A] ++ x) ++ B :: Δ1). rewrite <- app_assoc.
+    simpl. auto. rewrite E1. assert (E2 : Δ2 ++ A :: x ++ A0 --> B :: Δ1 = (Δ2 ++ [A] ++ x) ++ A0 --> B :: Δ1).
+    rewrite <- app_assoc. simpl. auto. rewrite E2. apply ImpRRule_I.
+    repeat rewrite <- app_assoc. apply wkn_RI.
+  - destruct x ; subst ; repeat rewrite app_nil_r.
+    + simpl in e0. subst. exists (Γ0 ++ A0 :: Γ1, Δ0 ++ A :: B :: Δ1).
+      split. assert (E1: Δ0 ++ A :: B :: Δ1 = (Δ0 ++ [A]) ++ B :: Δ1). rewrite <- app_assoc.
+      simpl. auto. rewrite E1.
+      assert (E3 : Δ0 ++ A :: A0 --> B :: Δ1 = (Δ0 ++ [A]) ++ A0 --> B :: Δ1).
+      rewrite <- app_assoc. simpl. auto. rewrite E3. apply ImpRRule_I.
+      repeat rewrite <- app_assoc. apply wkn_RI.
+    + inversion e0. subst. exists (Γ0 ++ A0 :: Γ1, Δ0 ++ B :: x ++ A :: Δ3).
+      split. repeat rewrite <- app_assoc. apply ImpRRule_I.
+      assert (Δ0 ++ B :: x ++ Δ3 = (Δ0 ++ B :: x) ++ Δ3). rewrite <- app_assoc. reflexivity.
+      rewrite H0. assert (Δ0 ++ B :: x ++ A :: Δ3 = (Δ0 ++ B :: x) ++ A :: Δ3). rewrite <- app_assoc. reflexivity.
+      rewrite H1. apply wkn_RI.
+Qed.
+ +
+Lemma ImpL_app_wkn_R : forall s sw A ps1 ps2,
+  (@wkn_R A s sw) ->
+  (ImpLRule [ps1;ps2] s) ->
+  (existsT2 psw1 psw2, (ImpLRule [psw1;psw2] sw) * (@wkn_R A ps1 psw1) *
+                                                   (@wkn_R A ps2 psw2)).
+Proof.
+intros s sw A ps1 ps2 wkn RA. inversion RA. inversion wkn. subst.
+inversion H. subst. apply app2_find_hole in H2. destruct H2. repeat destruct s.
+- destruct p. subst. exists (Γ0 ++ Γ1, Δ2 ++ A0 :: A :: Δ3).
+  exists (Γ0 ++ B :: Γ1, Δ2 ++ A :: Δ3). repeat split.
+  assert (E1: Δ2 ++ A0 :: A :: Δ3 = (Δ2 ++ [A0]) ++ A :: Δ3).
+  repeat rewrite <- app_assoc. simpl. reflexivity. rewrite E1.
+  assert (E2: Δ2 ++ A0 :: Δ3 = (Δ2 ++ [A0]) ++ Δ3).
+  repeat rewrite <- app_assoc. simpl. reflexivity. rewrite E2. apply wkn_RI.
+- destruct p. subst. exists (Γ0 ++ Γ1, (Δ2 ++ A :: x) ++ A0 :: Δ1). exists (Γ0 ++ B :: Γ1, (Δ2 ++ A :: x) ++ Δ1).
+  split. split.
+  * assert (E: Δ2 ++ A :: x ++ Δ1 = (Δ2 ++ A :: x) ++ Δ1). rewrite <- app_assoc. simpl. reflexivity.
+    rewrite E. apply ImpLRule_I ; assumption.
+  * repeat rewrite <- app_assoc. simpl. apply wkn_RI.
+  * repeat rewrite <- app_assoc. simpl. apply wkn_RI.
+- destruct p. subst. exists (Γ0 ++ Γ1, Δ0 ++ A0 :: x ++ A :: Δ3).
+  exists (Γ0 ++ B :: Γ1, Δ0 ++ x ++ A :: Δ3). repeat split.
+  * rewrite <- app_assoc. apply ImpLRule_I ; assumption.
+  * assert (E1: Δ0 ++ A0 :: x ++ Δ3 = (Δ0 ++ A0 :: x) ++ Δ3). rewrite <- app_assoc. simpl. reflexivity.
+    rewrite E1.
+    assert (E2: Δ0 ++ A0 :: x ++ A :: Δ3 = (Δ0 ++ A0 :: x) ++ A :: Δ3). rewrite <- app_assoc. simpl. reflexivity.
+    rewrite E2. apply wkn_RI.
+  * rewrite app_assoc with (l:=Δ0). apply wkn_RI.
+Qed.
+ +
+Lemma GLR_app_wkn_R : forall s sw A ps,
+  (@wkn_R A s sw) ->
+  (GLRRule [ps] s) ->
+  (GLRRule [ps] sw).
+Proof.
+intros s sw A ps wkn RA. inversion RA. inversion wkn. rewrite <- H1 in H2.
+inversion H2. apply app2_find_hole in H6. destruct H6. repeat destruct s0.
+- destruct p. subst. assert (Δ2 ++ A :: Box A0 :: Δ1 = (Δ2 ++ [A]) ++ Box A0 :: Δ1).
+  rewrite <- app_assoc. simpl. reflexivity. rewrite H. apply GLRRule_I ; assumption.
+- destruct p. subst. assert (E: Δ2 ++ A :: x ++ Box A0 :: Δ1 = (Δ2 ++ A :: x) ++ Box A0 :: Δ1).
+  repeat rewrite <- app_assoc. simpl. reflexivity. rewrite E.
+  apply GLRRule_I ; assumption.
+- destruct p. subst. destruct x.
+  + rewrite app_nil_r. rewrite app_nil_l in e0. subst. assert (Δ0 ++ A :: Box A0 :: Δ1 = (Δ0 ++ [A]) ++ Box A0 :: Δ1).
+    rewrite <- app_assoc. reflexivity. rewrite H. apply GLRRule_I ; assumption.
+  + inversion e0. subst. rewrite <- app_assoc. simpl. apply GLRRule_I ; assumption.
+Qed.
+ +
+(* Now we can prove that weakening is height-preserving admissible. *)
+ +
+Theorem GLS_wkn_L : forall (k : nat) s
+        (D0 : GLS_prv s),
+        k = (derrec_height D0) ->
+          (forall sw A, ((@wkn_L A s sw) ->
+          existsT2 (D1 : GLS_prv sw),
+          derrec_height D1 <= k)).
+Proof.
+induction k as [n IH] using (well_founded_induction_type lt_wf).
+intros s0 D0. remember D0 as D0'. destruct D0.
+(* D0 is a leaf *)
+- intros hei sw A wkn. inversion f.
+(* D0 ends with an application of rule *)
+- intros hei sw A wkn. inversion wkn. inversion g.
+  (* IdP *)
+  * inversion H1. rewrite <- H in H5. inversion H5. apply app2_find_hole in H7.
+    destruct H7. assert (DersNil: dersrec GLS_rules (fun _ : Seq => False) []).
+    apply dersrec_nil.
+    destruct s.
+    + destruct s.
+      { destruct p. inversion e0. subst. pose (IdPRule_I P (Γ2 ++ [A]) Γ3 Δ0 Δ1). apply IdP in i. rewrite <- app_assoc in i.
+        simpl in i. pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (Γ2 ++ A :: # P :: Γ3, Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl. repeat rewrite dersrec_height_nil.
+        left. reflexivity. reflexivity. }
+      { destruct p. destruct x.
+        - rewrite app_nil_l in e0. inversion e0. subst.
+          pose (IdPRule_I P ((Γ2 ++ []) ++ [A]) Γ3 Δ0 Δ1). apply IdP in i. rewrite <- app_assoc in i. simpl in i.
+          pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) ((Γ2 ++ []) ++ A :: # P :: Γ3, Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl. repeat rewrite dersrec_height_nil.
+          left. reflexivity. reflexivity.
+        - inversion e0. subst.
+          pose (IdPRule_I P Γ2 (x ++ A :: Γ1) Δ0 Δ1). apply IdP in i.
+          assert (E0 : Γ2 ++ # P :: x ++ A :: Γ1 = (Γ2 ++ # P :: x) ++ A :: Γ1). rewrite <- app_assoc. reflexivity.
+          rewrite E0 in i.
+          pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) ((Γ2 ++ # P :: x) ++ A :: Γ1, Δ0 ++ # P :: Δ1) i DersNil).
+          exists d0. simpl. repeat rewrite dersrec_height_nil.
+          left. reflexivity. reflexivity. }
+    + destruct p. subst. pose (IdPRule_I P (Γ0 ++ A :: x) Γ3 Δ0 Δ1). apply IdP in i. rewrite <- app_assoc in i. simpl in i.
+      pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[]) (Γ0 ++ A :: x ++ # P :: Γ3, Δ0 ++ # P :: Δ1) i DersNil).
+      exists d0. simpl. repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+  (* BotL *)
+  * inversion H1. rewrite <- H in H5. inversion H5.
+    assert (DersNil: dersrec GLS_rules (fun _ : Seq => False) []).
+    apply dersrec_nil.
+    apply app2_find_hole in H7. destruct H7. destruct s.
+    + destruct s.
+      { destruct p. inversion e0. subst.
+        pose (BotLRule_I (Γ2 ++ [A]) Γ3 Δ). apply BotL in b. rewrite <- app_assoc in b. simpl in b.
+        pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (Γ2 ++ A :: :: Γ3, Δ) b DersNil). exists d0. simpl. repeat rewrite dersrec_height_nil.
+        left. reflexivity. reflexivity. }
+      { destruct p. destruct x.
+        - rewrite app_nil_l in e0. inversion e0. subst.
+          pose (BotLRule_I ((Γ2 ++ []) ++ [A]) Γ3 Δ). apply BotL in b. rewrite <- app_assoc in b. simpl in b.
+          pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) ((Γ2 ++ []) ++ A :: :: Γ3, Δ) b DersNil). exists d0. simpl. repeat rewrite dersrec_height_nil.
+          left. reflexivity. reflexivity.
+        - inversion e0. subst.
+          pose (BotLRule_I Γ2 (x ++ A :: Γ1) Δ). apply BotL in b.
+          assert (E0: Γ2 ++ :: x ++ A :: Γ1 = (Γ2 ++ :: x) ++ A :: Γ1). rewrite <- app_assoc. reflexivity.
+          rewrite E0 in b.
+          pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) ((Γ2 ++ :: x) ++ A :: Γ1, Δ) b DersNil).
+          exists d0. simpl. repeat rewrite dersrec_height_nil.
+          left. reflexivity. reflexivity. }
+    + destruct p. subst. pose (BotLRule_I (Γ0 ++ A :: x) Γ3 Δ). apply BotL in b.
+      assert (E0 : (Γ0 ++ A :: x) ++ :: Γ3 = Γ0 ++ A :: x ++ :: Γ3).
+      rewrite <- app_assoc. reflexivity. rewrite E0 in b.
+      pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[]) (Γ0 ++ A :: x ++ :: Γ3, Δ) b DersNil). exists d0. simpl.
+      repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+  (* ImpR *)
+  * assert (DersNil: dersrec GLS_rules (fun _ : Seq => False) []).
+    apply dersrec_nil.
+    inversion H1. subst. inversion H5. subst. pose (ImpR_app_wkn_L wkn H1). destruct s.
+    repeat destruct p. remember [(Γ2 ++ A0 :: Γ3, Δ0 ++ B :: Δ1)] as ps'. destruct d.
+    inversion Heqps'. inversion Heqps'. subst.
+    assert (E: derrec_height d < S (derrec_height d)). auto.
+    assert (E1: derrec_height d = derrec_height d). auto. simpl in IH.
+    rewrite dersrec_height_nil in IH. 2: reflexivity. rewrite Nat.max_0_r in IH.
+    pose (IH (derrec_height d) E (Γ2 ++ A0 :: Γ3, Δ0 ++ B :: Δ1) d
+    E1 x A w).
+    destruct s. pose (dlCons x0 d0). apply ImpR in i.
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x]) (Γ0 ++ A :: Γ1, Δ0 ++ A0 --> B :: Δ1) i).
+    pose (d2 d1). exists d3.
+    simpl. repeat rewrite dersrec_height_nil. repeat rewrite Nat.max_0_r.
+    rewrite <- Nat.succ_le_mono. assumption. reflexivity.
+  (* ImpL *)
+  * inversion H1. subst. inversion H5. subst. pose (ImpL_app_wkn_L wkn H1). repeat destruct s.
+    repeat destruct p. apply ImpL in i.
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x;x0]) (Γ0 ++ A :: Γ1, Δ0 ++ Δ1) i). subst. simpl.
+    remember [(Γ2 ++ Γ3, Δ0 ++ A0 :: Δ1); (Γ2 ++ B :: Γ3, Δ0 ++ Δ1)] as ps'. destruct d.
+    inversion Heqps'. inversion Heqps'. subst.
+    remember [(Γ2 ++ B :: Γ3, Δ0 ++ Δ1)] as ps''. destruct d1. inversion Heqps''.
+    inversion Heqps''. simpl. subst. rewrite dersrec_height_nil. simpl in IH.
+    rewrite dersrec_height_nil in IH. rewrite Nat.max_0_r. rewrite Nat.max_0_r in IH.
+    assert (E1: derrec_height d < S (Init.Nat.max (derrec_height d)(derrec_height d1))).
+    apply Nat.lt_succ_r. apply Nat.le_max_l.
+    assert (E2: derrec_height d = derrec_height d). auto.
+    pose (IH (derrec_height d) E1 (Γ2 ++ Γ3, Δ0 ++ A0 :: Δ1) d E2 x A w0).
+    destruct s.
+    assert (E3: derrec_height d1 < S (Init.Nat.max (derrec_height d)(derrec_height d1))).
+    apply Nat.lt_succ_r. apply Nat.le_max_r.
+    assert (E4: derrec_height d1 = derrec_height d1). auto.
+    pose (IH (derrec_height d1) E3 (Γ2 ++ B :: Γ3, Δ0 ++ Δ1) d1 E4 x0 A w).
+    destruct s.
+    pose (dlCons x1 (dlCons x2 d2)). subst. pose (d0 d3). exists d4. simpl. rewrite dersrec_height_nil.
+    rewrite Nat.max_0_r. rewrite <- Nat.succ_le_mono. apply Nat.max_le_compat.
+    assumption. assumption. reflexivity. reflexivity. reflexivity.
+  (* GLR *)
+  * inversion X. rewrite <- H4 in X. subst. pose (GLR_app_wkn_L wkn X). destruct s.
+    { apply GLR in g0. subst. pose (derI (rules:=GLS_rules)
+      (prems:=fun _ : Seq => False) (ps:=[(XBoxed_list ++ [Box A0], [A0])])
+      (Γ0 ++ A :: Γ1, Δ) g0). subst. pose (d0 d). exists d1. simpl. reflexivity. }
+    { repeat destruct s. repeat destruct p. apply GLR in g0.
+      remember [(XBoxed_list ++ [Box A0], [A0])] as ps'. destruct d. inversion Heqps'. subst.
+      inversion Heqps'. subst. simpl. simpl in IH.
+      assert (E1: derrec_height d < S (Init.Nat.max (derrec_height d) (dersrec_height d0))).
+      rewrite dersrec_height_nil. rewrite Nat.max_0_r. apply Nat.lt_succ_r. left. reflexivity.
+      assert (E2: derrec_height d = derrec_height d). auto.
+      pose (IH (derrec_height d) E1 ((XBoxed_list ++ [Box A0], [A0])) d E2 x (unBox_formula A) w0).
+      destruct s.
+      assert (E3: derrec_height x1 < S (Init.Nat.max (derrec_height d) (dersrec_height d0))).
+      rewrite dersrec_height_nil. rewrite Nat.max_0_r. apply Nat.lt_succ_r. assumption. reflexivity.
+      assert (E4: derrec_height x1 = derrec_height x1). auto.
+      pose (IH (derrec_height x1) E3 x x1 E4 x0 A w). destruct s.
+      pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[x0]) (Γ0 ++ A :: Γ1, Δ) g0). subst. simpl.
+      pose (dlCons x2 d0). pose (d1 d2). exists d3. simpl. rewrite dersrec_height_nil.
+      repeat rewrite Nat.max_0_r. rewrite <- Nat.succ_le_mono.
+      pose (Nat.le_trans (derrec_height x2) (derrec_height x1) (derrec_height d) l0 l).
+      assumption. reflexivity. }
+Qed.
+ +
+Theorem GLS_prv_wkn_L : forall s, GLS_prv s ->
+          (forall sw A, (@wkn_L A s sw) -> GLS_prv sw).
+Proof.
+intros.
+assert (J0: derrec_height X = derrec_height X). auto.
+pose (GLS_wkn_L _ J0 H). destruct s0. auto.
+Qed.
+ +
+Theorem GLS_wkn_R : forall (k : nat) s
+        (D0 : GLS_prv s),
+        k = (derrec_height D0) ->
+          (forall sw A, ((@wkn_R A s sw) ->
+          existsT2 (D1 : GLS_prv sw),
+          derrec_height D1 <= k)).
+Proof.
+induction k as [n IH] using (well_founded_induction_type lt_wf).
+intros s0 D0. remember D0 as D0'. destruct D0.
+(* D0 is a leaf *)
+- intros hei sw A wkn. inversion f.
+(* D0 ends with an application of rule *)
+- intros hei sw A wkn. inversion wkn. inversion g.
+  (* IdP *)
+  * inversion H1. rewrite <- H in H5. inversion H5. apply app2_find_hole in H8.
+    destruct H8. assert (DersNil: dersrec GLS_rules (fun _ : Seq => False) []).
+    apply dersrec_nil.
+    repeat destruct s.
+    + destruct p. inversion e0. subst. pose (IdPRule_I P Γ0 Γ1 (Δ2 ++ [A]) Δ3). apply IdP in i. rewrite <- app_assoc in i. simpl in i.
+      pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[]) (Γ0 ++ # P :: Γ1, Δ2 ++ A :: # P :: Δ3) i DersNil). exists d0. simpl. repeat rewrite dersrec_height_nil.
+      left. reflexivity. reflexivity.
+    + destruct p. destruct x.
+      { rewrite app_nil_l in e0. inversion e0. subst.
+        pose (IdPRule_I P Γ0 Γ1 ((Δ2 ++ []) ++ [A]) Δ3). apply IdP in i. rewrite <- app_assoc in i. simpl in i.
+        pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (Γ0 ++ # P :: Γ1, (Δ2 ++ []) ++ A :: # P :: Δ3) i DersNil). exists d0. simpl. repeat rewrite dersrec_height_nil.
+        left. reflexivity. reflexivity. }
+      { inversion e0. subst.
+        pose (IdPRule_I P Γ0 Γ1 Δ2 (x ++ A :: Δ1)). apply IdP in i.
+        assert (E0: Δ2 ++ # P :: x ++ A :: Δ1 = (Δ2 ++ # P :: x) ++ A :: Δ1). rewrite <- app_assoc. reflexivity.
+        rewrite E0 in i.
+        pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (Γ0 ++ # P :: Γ1, (Δ2 ++ # P :: x) ++ A :: Δ1) i DersNil).
+        exists d0. simpl. repeat rewrite dersrec_height_nil.
+        left. reflexivity. reflexivity. }
+    + destruct p. subst. pose (IdPRule_I P Γ0 Γ1 (Δ0 ++ A :: x) Δ3). apply IdP in i. rewrite <- app_assoc in i. simpl in i.
+      pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[]) (Γ0 ++ # P :: Γ1, Δ0 ++ A :: x ++ # P :: Δ3) i DersNil).
+      exists d0. simpl. repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+  (* BotL *)
+  * inversion H1. rewrite <- H in H5. inversion H5.
+    assert (DersNil: dersrec GLS_rules (fun _ : Seq => False) []).
+    apply dersrec_nil.
+    pose (BotLRule_I Γ0 Γ1 (Δ0 ++ A :: Δ1)). apply BotL in b.
+    pose (derI (rules:=GLS_rules)
+    (prems:=fun _ : Seq => False)
+    (ps:=[]) (Γ0 ++ :: Γ1, Δ0 ++ A :: Δ1) b DersNil). subst. exists d0. simpl.
+    repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+  (* ImpR *)
+  * inversion H1. subst. inversion H5. subst. pose (ImpR_app_wkn_R wkn H1). destruct s.
+    destruct p. apply ImpR in i.
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x]) (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) i). subst. simpl.
+    remember [(Γ0 ++ A0 :: Γ1, Δ2 ++ B :: Δ3)] as ps'. destruct d. inversion Heqps'.
+    inversion Heqps'. subst. simpl. rewrite dersrec_height_nil. simpl in IH.
+    rewrite dersrec_height_nil in IH. rewrite Nat.max_0_r. rewrite Nat.max_0_r in IH.
+    assert (E: derrec_height d < S (derrec_height d)). auto.
+    assert (E1: derrec_height d = derrec_height d). auto.
+    pose (IH (derrec_height d) E (Γ0 ++ A0 :: Γ1, Δ2 ++ B :: Δ3) d E1 x A w).
+    destruct s.
+    pose (dlCons x0 d1). pose (d0 d2). exists d3. simpl. rewrite dersrec_height_nil.
+    rewrite Nat.max_0_r. rewrite <- Nat.succ_le_mono. assumption. reflexivity. reflexivity. reflexivity.
+  (* ImpL *)
+  * inversion H1. subst. inversion H5. subst. pose (ImpL_app_wkn_R wkn H1). repeat destruct s.
+    repeat destruct p. apply ImpL in i.
+    pose (derI (rules:=GLS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x;x0]) (Γ0 ++ A0 --> B :: Γ1, Δ0 ++ A :: Δ1) i). subst. simpl.
+    remember [(Γ0 ++ Γ1, Δ2 ++ A0 :: Δ3); (Γ0 ++ B :: Γ1, Δ2 ++ Δ3)] as ps'. destruct d.
+    inversion Heqps'. inversion Heqps'. subst.
+    remember [(Γ0 ++ B :: Γ1, Δ2 ++ Δ3)] as ps''. destruct d1. inversion Heqps''.
+    inversion Heqps''. simpl. subst. rewrite dersrec_height_nil. simpl in IH.
+    rewrite dersrec_height_nil in IH. rewrite Nat.max_0_r. rewrite Nat.max_0_r in IH.
+    assert (E1: derrec_height d < S (Init.Nat.max (derrec_height d)(derrec_height d1))).
+    apply Nat.lt_succ_r. apply Nat.le_max_l.
+    assert (E2: derrec_height d = derrec_height d). auto.
+    pose (IH (derrec_height d) E1 (Γ0 ++ Γ1, Δ2 ++ A0 :: Δ3) d E2 x A w0).
+    destruct s.
+    assert (E3: derrec_height d1 < S (Init.Nat.max (derrec_height d)(derrec_height d1))).
+    apply Nat.lt_succ_r. apply Nat.le_max_r.
+    assert (E4: derrec_height d1 = derrec_height d1). auto.
+    pose (IH (derrec_height d1) E3 (Γ0 ++ B :: Γ1, Δ2 ++ Δ3) d1 E4 x0 A w).
+    destruct s.
+    pose (dlCons x1 (dlCons x2 d2)). subst. pose (d0 d3). exists d4. simpl. rewrite dersrec_height_nil.
+    rewrite Nat.max_0_r. rewrite <- Nat.succ_le_mono. apply Nat.max_le_compat.
+    assumption. assumption. reflexivity. reflexivity. reflexivity.
+  (* GLR *)
+  * inversion X. rewrite <- H4 in X. pose (GLR_app_wkn_R wkn X).
+    apply GLR in g0. pose (derI (rules:=GLS_rules)
+    (prems:=fun _ : Seq => False) (ps:=[(XBoxed_list ++ [Box A0], [A0])])
+    sw g0). subst. pose (d0 d). exists d1. simpl. reflexivity.
+Qed.
+ +
+Theorem GLS_prv_wkn_R : forall s, GLS_prv s ->
+          (forall sw A, (@wkn_R A s sw) -> GLS_prv sw).
+Proof.
+intros.
+assert (J0: derrec_height X = derrec_height X). auto.
+pose (GLS_wkn_R _ J0 H). destruct s0. auto.
+Qed.
+ +
+Theorem GLS_list_wkn_R : forall (k : nat) Γ Δ0 Δ1
+        (D0 : GLS_prv (Γ,Δ0 ++ Δ1)),
+        k = (derrec_height D0) ->
+          (forall l, existsT2 (D1 : GLS_prv (Γ,Δ0 ++ l ++ Δ1)),
+           derrec_height D1 <= k).
+Proof.
+intros. induction l.
+- simpl. exists D0. lia.
+- simpl. destruct IHl.
+  assert (E: derrec_height x = derrec_height x). reflexivity.
+  assert (H0: wkn_R a (Γ, Δ0 ++ l ++ Δ1) (Γ, Δ0 ++ a :: l ++ Δ1)). apply wkn_RI.
+  pose (@GLS_wkn_R (derrec_height x) (Γ, Δ0 ++ l ++ Δ1) x E (Γ, Δ0 ++ a :: l ++ Δ1) a H0).
+  destruct s. exists x0. lia.
+Qed.
+ +
+Theorem GLS_prv_list_wkn_R : forall Γ Δ0 Δ1,
+        GLS_prv (Γ,Δ0 ++ Δ1) -> forall l, GLS_prv (Γ,Δ0 ++ l ++ Δ1).
+Proof.
+intros.
+assert (J0: derrec_height X = derrec_height X). auto.
+pose (@GLS_list_wkn_R _ _ _ _ X J0 l). destruct s. auto.
+Qed.
+ +
+Theorem GLS_list_wkn_L : forall (k : nat) Γ0 Γ1 Δ
+        (D0 : GLS_prv (Γ0 ++ Γ1,Δ)),
+        k = (derrec_height D0) ->
+          (forall l, existsT2 (D1 : GLS_prv (Γ0 ++ l ++ Γ1,Δ)),
+          derrec_height D1 <= k).
+Proof.
+intros. induction l.
+- simpl. exists D0. lia.
+- simpl. destruct IHl.
+  assert (E: derrec_height x = derrec_height x). reflexivity.
+  assert (H0: wkn_L a (Γ0 ++ l ++ Γ1, Δ) (Γ0 ++ a :: l ++ Γ1, Δ)). apply wkn_LI.
+  pose (@GLS_wkn_L (derrec_height x) (Γ0 ++ l ++ Γ1, Δ) x E (Γ0 ++ a :: l ++ Γ1, Δ) a H0).
+  destruct s. exists x0. lia.
+Qed.
+ +
+Theorem GLS_prv_list_wkn_L : forall Γ0 Γ1 Δ,
+        GLS_prv (Γ0 ++ Γ1,Δ) -> forall l, GLS_prv (Γ0 ++ l ++ Γ1,Δ).
+Proof.
+intros.
+assert (J0: derrec_height X = derrec_height X). auto.
+pose (@GLS_list_wkn_L _ _ _ _ X J0 l). destruct s. auto.
+Qed.
+ +
+Theorem GLS_XBoxed_list_wkn_L : forall (k : nat) Γ1 Γ0 Γ2 Δ
+        (D0 : GLS_prv (Γ0 ++ Γ1 ++ Γ2,Δ)),
+        k = (derrec_height D0) ->
+          (existsT2 (D1 : GLS_prv (Γ0 ++ (XBoxed_list Γ1) ++ Γ2,Δ)),
+           derrec_height D1 <= k).
+Proof.
+induction Γ1.
+- intros. simpl. simpl in D0. exists D0. rewrite H. left.
+- intros. simpl. assert (Γ0 ++ (a :: Γ1) ++ Γ2 = (Γ0 ++ [a]) ++ Γ1 ++ Γ2). rewrite <- app_assoc. reflexivity.
+  pose (@IHΓ1 (Γ0 ++ [a]) Γ2 Δ). repeat rewrite <- H0 in s.
+  pose (s D0 H). destruct s0. clear s.
+  assert (wkn_L (unBox_formula a) ((Γ0 ++ [a]) ++ XBoxed_list Γ1 ++ Γ2, Δ) (Γ0 ++ unBox_formula a :: a :: XBoxed_list Γ1 ++ Γ2, Δ)).
+  assert ((Γ0 ++ [a]) ++ XBoxed_list Γ1 ++ Γ2 = Γ0 ++ a :: XBoxed_list Γ1 ++ Γ2). rewrite <- app_assoc. reflexivity. rewrite H1.
+  apply wkn_LI.
+  assert (derrec_height x = derrec_height x). reflexivity.
+  pose (GLS_wkn_L x H2 H1). destruct s. exists x0. lia.
+Qed.
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_And_Or_rules.html b/GL.Interpolation.UIGL_And_Or_rules.html new file mode 100644 index 0000000..d79d96c --- /dev/null +++ b/GL.Interpolation.UIGL_And_Or_rules.html @@ -0,0 +1,261 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_And_Or_rules

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat.
+Require Import Lia.
+ +
+Require Import general_export.
+ +
+Require Import GLS_export.
+ +
+Require Import UIGL_Def_measure.
+Require Import UIGL_Canopy.
+Require Import UIGL_irred_short.
+Require Import UIGL_braga.
+Require Import UIGL_LexSeq.
+Require Import UIGL_nodupseq.
+ +
+  Section list_conj_disj_properties.
+ +
+  Lemma TopR : forall X Y0 Y1, GLS_prv (X, Y0 ++ Top :: Y1).
+  Proof.
+  intros. unfold Top. apply derI with (ps:=[([] ++ :: X, Y0 ++ :: Y1)]).
+  apply ImpR. assert ((X, Y0 ++ --> :: Y1) = ([] ++ X, Y0 ++ --> :: Y1)). auto.
+  rewrite H. apply ImpRRule_I. apply dlCons. 2: apply dlNil. apply derI with (ps:=[]).
+  apply BotL. apply BotLRule_I. apply dlNil.
+  Qed.
+ +
+  Lemma TopL_remove : forall Y X0 X1, GLS_prv (X0 ++ Top :: X1, Y) -> GLS_prv (X0 ++ X1, Y).
+  Proof.
+  intros. assert (Y= [] ++ Y). auto. rewrite H. rewrite H in X. apply GLS_cut_adm with (A:=Top) ; auto.
+  apply TopR.
+  Qed.
+ +
+  Lemma BotR_remove : forall X Y0 Y1, GLS_prv (X, Y0 ++ Bot :: Y1) -> GLS_prv (X, Y0 ++ Y1).
+  Proof.
+  intros. assert (X= [] ++ X). auto. rewrite H. rewrite H in X0. apply GLS_cut_adm with (A:=Bot) ; auto.
+  apply derI with (ps:=[]). 2: apply dlNil. apply BotL. apply BotLRule_I.
+  Qed.
+ +
+  Lemma AndL : forall s A B, GLS_prv (A :: B :: fst s, snd s) -> GLS_prv (And A B :: fst s, snd s).
+  Proof.
+  intros. unfold And. unfold Neg.
+  apply derI with (ps:=[([] ++ fst s, [] ++ (A --> B --> Bot) :: snd s); ([] ++ Bot :: fst s, [] ++ snd s)]).
+  apply ImpL. assert (((A --> B --> Bot) --> Bot :: fst s, snd s) = ([] ++ (A --> B --> Bot) --> Bot :: fst s, snd s)). auto.
+  rewrite H. apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+  apply derI with (ps:=[([] ++ A :: fst s, [] ++ B --> Bot :: snd s)]). apply ImpR. apply ImpRRule_I.
+  apply dlCons. 2: apply dlNil. apply derI with (ps:=[([A] ++ B :: fst s, [] ++ Bot :: snd s)]).
+  assert (([] ++ A :: fst s, [] ++ B --> Bot :: snd s) = ([A] ++ fst s, [] ++ B --> Bot :: snd s)). auto. rewrite H.
+  apply ImpR. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+  assert (J0: derrec_height X = derrec_height X). auto.
+  assert (J1: wkn_R Bot ([A] ++ B :: fst s, [] ++ snd s) ([A] ++ B :: fst s, [] ++ Bot :: snd s)). apply wkn_RI.
+  pose (GLS_wkn_R X J0 J1). destruct s0. auto. apply derI with (ps:=[]). apply BotL. apply BotLRule_I.
+  apply dlNil.
+  Qed.
+ +
+  Lemma AndR : forall s A B, GLS_prv (fst s, A :: snd s) -> GLS_prv (fst s, B :: snd s) -> GLS_prv (fst s, And A B :: snd s).
+  Proof.
+  intros. unfold And. unfold Neg.
+  apply derI with (ps:=[([] ++ A --> B --> :: fst s, [] ++ :: snd s)]).
+  apply ImpR. assert ((fst s, (A --> B --> ) --> :: snd s) = ([] ++ fst s, [] ++ (A --> B --> ) --> :: snd s)). auto.
+  rewrite H. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+  apply derI with (ps:=[([] ++ fst s, [] ++ A :: :: snd s);([] ++ B --> :: fst s, [] ++ :: snd s)]). apply ImpL.
+  apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+  assert (J0: derrec_height X = derrec_height X). auto.
+  assert (J1: wkn_R Bot ([] ++ fst s, [A] ++ snd s) ([] ++ fst s, [A] ++ :: snd s)). apply wkn_RI.
+  pose (GLS_wkn_R X J0 J1). destruct s0. auto.
+  apply derI with (ps:=[([] ++ fst s, [] ++ B :: :: snd s);([] ++ :: fst s, [] ++ :: snd s)]). apply ImpL.
+  apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+  assert (J0: derrec_height X0 = derrec_height X0). auto.
+  assert (J1: wkn_R Bot ([] ++ fst s, [B] ++ snd s) ([] ++ fst s, [B] ++ :: snd s)). apply wkn_RI.
+  pose (GLS_wkn_R X0 J0 J1). destruct s0. auto. apply derI with (ps:=[]). apply BotL. apply BotLRule_I.
+  apply dlNil.
+  Qed.
+ +
+  Lemma list_conj_wkn_L : forall l s A, InT A l -> GLS_prv (A :: fst s, snd s) -> GLS_prv (list_conj l :: fst s, snd s).
+  Proof.
+  induction l.
+  - intros. inversion H.
+  - intros. inversion H ; subst.
+    * simpl. apply AndL.
+      assert (J0: derrec_height X = derrec_height X). auto.
+      assert (J1: wkn_L (list_conj l) (A :: fst s, snd s) (A :: list_conj l :: fst s, snd s)).
+      assert (A :: fst s = [A] ++ fst s). auto. rewrite H0.
+      assert (A :: list_conj l :: fst s = [A] ++ list_conj l :: fst s). auto. rewrite H1. apply wkn_LI.
+      pose (GLS_wkn_L X J0 J1). destruct s0. auto.
+    * simpl. apply IHl in X ; auto.
+      assert (J0: derrec_height X = derrec_height X). auto.
+      assert (J1: wkn_L a (list_conj l :: fst s, snd s) (a :: list_conj l :: fst s, snd s)).
+      assert (a :: list_conj l :: fst s = [] ++ a :: list_conj l :: fst s). auto. rewrite H0.
+      assert ((list_conj l :: fst s,snd s) = ([] ++ list_conj l :: fst s,snd s)). auto. rewrite H2. apply wkn_LI.
+      pose (GLS_wkn_L X J0 J1). destruct s0. apply AndL ; auto.
+  Qed.
+ +
+  Lemma list_conj_R : forall l s, (forall A, InT A l -> GLS_prv (fst s, A :: snd s)) -> GLS_prv (fst s, list_conj l :: snd s).
+  Proof.
+  induction l.
+  - intros. simpl. unfold Top.
+    apply derI with (ps:=[([] ++ :: fst s, [] ++ :: snd s)]).
+    apply ImpR. assert ((fst s, --> :: snd s) = ([] ++ fst s, [] ++ --> :: snd s)). auto.
+    rewrite H. apply ImpRRule_I. apply dlCons. 2: apply dlNil. apply derI with (ps:=[]). apply BotL.
+    apply BotLRule_I. apply dlNil.
+  - intros. simpl. apply AndR.
+    * apply X. apply InT_eq.
+    * simpl. apply IHl. intros. apply X. apply InT_cons ; auto.
+  Qed.
+ +
+  Lemma OrL : forall s A B, GLS_prv (A :: fst s, snd s) -> GLS_prv (B :: fst s, snd s) -> GLS_prv (Or A B :: fst s, snd s).
+  Proof.
+  intros. unfold Or. unfold Neg.
+  apply derI with (ps:=[([] ++ fst s, [] ++ (A --> ) :: snd s); ([] ++ B :: fst s, [] ++ snd s)]).
+  apply ImpL. assert (((A --> ) --> B :: fst s, snd s) = ([] ++ (A --> ) --> B :: fst s, snd s)). auto.
+  rewrite H. apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+  apply derI with (ps:=[([] ++ A :: fst s, [] ++ Bot :: snd s)]). apply ImpR. apply ImpRRule_I.
+  apply dlCons. 2: apply dlNil.
+  assert (J0: derrec_height X = derrec_height X). auto.
+  assert (J1: wkn_R Bot (A :: fst s, [] ++ snd s) (A :: fst s, [] ++ Bot :: snd s)). apply wkn_RI.
+  pose (GLS_wkn_R X J0 J1). destruct s0. auto. auto.
+  Qed.
+ +
+  Lemma OrR : forall s A B, GLS_prv (fst s, A :: B :: snd s) -> GLS_prv (fst s, Or A B :: snd s).
+  Proof.
+  intros. unfold Or. unfold Neg.
+  apply derI with (ps:=[([] ++ (A --> Bot) :: fst s, [] ++ B :: snd s)]).
+  apply ImpR. assert ((fst s, (A --> Bot) --> B :: snd s) = (fst s, [] ++ (A --> Bot) --> B :: snd s)). auto.
+  rewrite H. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+  apply derI with (ps:=[([] ++ fst s, [] ++ A :: B :: snd s);([] ++ :: fst s, [] ++ B :: snd s)]).
+  apply ImpL. apply ImpLRule_I.
+  apply dlCons. 2: apply dlCons. 3: apply dlNil. simpl ; auto.
+  apply derI with (ps:=[]). apply BotL. apply BotLRule_I. apply dlNil.
+  Qed.
+ +
+  Lemma list_disj_L : forall l s, (forall A, InT A l -> GLS_prv (A :: fst s, snd s)) -> GLS_prv (list_disj l :: fst s, snd s).
+  Proof.
+  induction l.
+  - intros. simpl. apply derI with (ps:=[]). apply BotL. assert (( :: fst s, snd s) = ([] ++ :: fst s, snd s)). auto.
+    rewrite H. apply BotLRule_I. apply dlNil.
+  - intros. simpl. apply OrL.
+    * apply X. apply InT_eq.
+    * simpl. apply IHl. intros. apply X. apply InT_cons ; auto.
+  Qed.
+ +
+  Lemma list_disj_wkn_R : forall l s A, InT A l -> GLS_prv (fst s, A :: snd s) -> GLS_prv (fst s, list_disj l :: snd s).
+  Proof.
+  induction l.
+  - intros. inversion H.
+  - intros. inversion H ; subst.
+    * simpl. apply OrR.
+      assert (J0: derrec_height X = derrec_height X). auto.
+      assert (J1: wkn_R (list_disj l) (fst s, A :: snd s) (fst s, A :: list_disj l :: snd s)).
+      assert (A :: snd s = [A] ++ snd s). auto. rewrite H0.
+      assert (A :: list_disj l :: snd s = [A] ++ list_disj l :: snd s). auto. rewrite H1. apply wkn_RI.
+      pose (GLS_wkn_R X J0 J1). destruct s0. auto.
+    * simpl. apply IHl in X ; auto.
+      assert (J0: derrec_height X = derrec_height X). auto.
+      assert (J1: wkn_R a (fst s, list_disj l :: snd s) (fst s, a :: list_disj l :: snd s)).
+      assert (a :: list_disj l :: snd s = [] ++ a :: list_disj l :: snd s). auto. rewrite H0.
+      assert ((fst s, list_disj l :: snd s) = (fst s, [] ++ list_disj l :: snd s)). auto. rewrite H2. apply wkn_RI.
+      pose (GLS_wkn_R X J0 J1). destruct s0. apply OrR ; auto.
+  Qed.
+ +
+  Lemma AndR_inv : forall s A B, GLS_prv (fst s, And A B :: snd s) -> (GLS_prv (fst s, A :: snd s) * GLS_prv (fst s, B :: snd s)).
+  Proof.
+  intros. unfold And in X. unfold Neg in X. apply ImpR_inv with (prem:=((A --> B --> ) :: fst s, :: snd s)) in X.
+  apply ImpL_inv with (prem1:=(fst s, A :: :: snd s)) (prem2:=(B --> :: fst s, :: snd s)) in X. destruct X.
+  apply ImpL_inv with (prem1:=(fst s, B :: :: snd s)) (prem2:=( :: fst s, :: snd s)) in g0. destruct g0.
+  pose (BotR_remove (fst s) [A] (snd s) g). pose (BotR_remove (fst s) [B] (snd s) g0). auto.
+  1-2: epose (ImpLRule_I _ _ [] _ [] _) ; simpl in i ; apply i.
+  epose (ImpRRule_I _ _ [] _ [] _) ; simpl in i ; apply i.
+  Qed.
+ +
+  Lemma AndL_inv : forall s A B, GLS_prv (And A B :: fst s, snd s) -> GLS_prv (A :: B :: fst s, snd s).
+  Proof.
+  intros. unfold And in X. unfold Neg in X.
+  apply ImpL_inv with (prem1:=(fst s, A --> B --> :: snd s)) (prem2:=( :: fst s, snd s)) in X. destruct X.
+  apply ImpR_inv with (prem:=(A :: fst s, B --> :: snd s)) in g.
+  apply ImpR_inv with (prem:=(A :: B :: fst s, :: snd s)) in g.
+  pose (BotR_remove (A :: B :: fst s) [] (snd s) g). simpl in g1. auto.
+  epose (ImpRRule_I _ _ [A] _ [] _) ; simpl in i ; apply i.
+  epose (ImpRRule_I _ _ [] _ [] _) ; simpl in i ; apply i.
+  epose (ImpLRule_I _ _ [] _ [] _) ; simpl in i ; apply i.
+  Qed.
+ +
+  Lemma OrR_inv : forall s A B, GLS_prv (fst s, Or A B :: snd s) -> GLS_prv (fst s, A :: B :: snd s).
+  Proof.
+  intros. unfold Or in X. unfold Neg in X.
+  apply ImpR_inv with (prem:=(A --> :: fst s, B :: snd s)) in X.
+  apply ImpL_inv with (prem1:=(fst s, A :: B :: snd s)) (prem2:=( :: fst s, B :: snd s)) in X. destruct X. auto.
+  epose (ImpLRule_I _ _ [] _ [] _) ; simpl in i ; apply i.
+  epose (ImpRRule_I _ _ [] _ [] _) ; simpl in i ; apply i.
+  Qed.
+ +
+  Lemma OrL_inv : forall s A B, GLS_prv (Or A B :: fst s, snd s) -> (GLS_prv (A :: fst s, snd s) * GLS_prv (B :: fst s, snd s)).
+  Proof.
+  intros. unfold Or in X. unfold Neg in X.
+  apply ImpL_inv with (prem1:=(fst s, A --> :: snd s)) (prem2:=(B :: fst s, snd s)) in X. destruct X. split ; auto.
+  apply ImpR_inv with (prem:=(A :: fst s, :: snd s)) in g.
+  pose (BotR_remove (A :: fst s) [] (snd s) g). simpl in g1 ; auto.
+  epose (ImpRRule_I _ _ [] _ [] _) ; simpl in i ; apply i.
+  epose (ImpLRule_I _ _ [] _ [] _) ; simpl in i ; apply i.
+  Qed.
+ +
+  End list_conj_disj_properties.
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_Canopy.html b/GL.Interpolation.UIGL_Canopy.html new file mode 100644 index 0000000..555d02d --- /dev/null +++ b/GL.Interpolation.UIGL_Canopy.html @@ -0,0 +1,534 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_Canopy

+ +
+  (* Closure of sequents *)
+ +
+  Require Import List.
+  Export ListNotations.
+  Require Import Lia.
+ +
+  Require Import Coq.Init.Wf.
+ +
+  Require Import GLS_export.
+  Require Import UIGL_Def_measure.
+ +
+  Require Import UIGL_irred_short UIGL_irred_high_level.
+ +
+  Require Import general_export.
+ +
+  (* Defining the premises of a sequent via Imp rules. *)
+ +
+  Lemma finite_ImpRules_premises_of_S : forall (s : Seq), existsT2 listImpRulesprems,
+                (forall prems, (((ImpRRule prems s) + (ImpLRule prems s)) -> (InT prems listImpRulesprems)) *
+                               ((InT prems listImpRulesprems) -> ((ImpRRule prems s) + (ImpLRule prems s)))).
+  Proof.
+  intros.
+  pose (finite_ImpR_premises_of_S s). destruct s0.
+  pose (finite_ImpL_premises_of_S s). destruct s0.
+  exists (x ++ x0). intros. split ; intro.
+  - destruct H.
+    + inversion i. subst. apply InT_or_app. left. apply p. apply ImpRRule_I.
+    + inversion i. subst. apply InT_or_app. right. apply p0. apply ImpLRule_I.
+  - apply InT_app_or in H. destruct H.
+    + left. apply p ; auto.
+    + right. apply p0 ; auto.
+  Defined.
+ +
+  Definition inv_prems (s : Seq) := flatten_list (proj1_sigT2 (finite_ImpRules_premises_of_S s)).
+ +
+  (* The number of implication symbols in a sequent gives a measure
+      which has a well-founded order.*)

+ +
+  Definition less_imp (s0 s1 : Seq) := (n_imp_subformS s0) < (n_imp_subformS s1).
+ +
+  Lemma Acc_less_imp : well_founded less_imp.
+  Proof.
+  intros s ; induction on s as IHm with measure (n_imp_subformS s).
+  apply Acc_intro. auto.
+  Defined.
+ +
+  Definition invprem (s0 s1 : Seq) := In s0 (inv_prems s1).
+ +
+  Lemma InT_In_inv_prems : forall s0 s1, (InT s0 (inv_prems s1) -> In s0 (inv_prems s1)) *
+                                                                   (In s0 (inv_prems s1) -> InT s0 (inv_prems s1)).
+  Proof.
+  intros. split ; intros.
+  - apply InT_In ; auto.
+  - unfold inv_prems. unfold inv_prems in H. destruct (finite_ImpRules_premises_of_S s1).
+    simpl. simpl in H. apply In_InT_seqs. auto.
+Qed.
+ +
+  Lemma Acc_invprem : well_founded invprem.
+  Proof.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  apply Acc_intro. intros. apply IHs. unfold invprem in H.
+  apply InT_In_inv_prems in H. unfold inv_prems in H.
+  destruct (finite_ImpRules_premises_of_S s) in H. simpl in H.
+  apply InT_flatten_list_InT_elem in H. destruct H. destruct p0.
+  apply p in i0. destruct i0.
+  inversion i0. subst. inversion i. subst.
+  unfold n_imp_subformS ; simpl. repeat rewrite n_imp_subformLF_dist_app.
+  simpl. lia. subst. inversion H0.
+  inversion i0. subst. inversion i. subst.
+  unfold n_imp_subformS ; simpl. repeat rewrite n_imp_subformLF_dist_app.
+  simpl. lia. subst.
+  inversion H0. subst.
+  unfold n_imp_subformS ; simpl. repeat rewrite n_imp_subformLF_dist_app.
+  simpl. lia. subst. inversion H1.
+  Defined.
+ +
+  (* The closure of a sequent is the list of all sequents which can be
+      reach via chains of backward applications of invertible rules. *)

+ +
+  Definition Canopy := irred Acc_invprem.
+ +
+  (* Critical sequents are sequents on which no invertible (Imp)
+      rule is backward applicable. *)

+ +
+  Definition critical_Seq (s : Seq) := is_Prime ((fst s) ++ (snd s)).
+ +
+  Definition is_Prime_dec : forall l, (is_Prime l) + (is_Prime l -> False).
+  Proof.
+  unfold is_Prime. induction l ; simpl ; auto.
+  left. intros. inversion H. destruct IHl. destruct a as [n | | |].
+  1,2,4: left ; intros ; destruct H ; auto. right. left ; exists n ; auto.
+  left ; exists a ; auto. right. intro.
+  assert (a1 --> a2 = a1 --> a2 \/ In (a1 --> a2) l). left ; auto. apply H in H0.
+  destruct H0. destruct H0. inversion H0. destruct H0. destruct H0 ; inversion H0.
+  inversion H0. right. intros. apply f. intros. apply H. auto.
+  Defined.
+ +
+  Definition critical_Seq_dec (s : Seq) : (critical_Seq s) + (critical_Seq s -> False).
+  Proof.
+  unfold critical_Seq. destruct s ; simpl. apply is_Prime_dec.
+  Defined.
+ +
+  (* We show that all sequents in Canopy are critical. *)
+ +
+  Lemma inv_prems_id_critical : forall s, inv_prems s = [] -> critical_Seq s.
+  Proof.
+  intros. destruct s. unfold critical_Seq. intros A H0. destruct A as [n | | |].
+  right ; left ; exists n ; auto. right ; auto.
+  2: left ; exists A ; auto. exfalso. simpl in H0.
+  apply in_app_or in H0 ; destruct H0.
+  apply in_split in H0. destruct H0. destruct H0. subst.
+  assert (In (x ++ A2 :: x0, l0) (inv_prems (x ++ A1 --> A2 :: x0, l0))).
+  unfold inv_prems. apply InT_In.
+  apply InT_trans_flatten_list with (bs:=[(x ++ x0, [] ++ A1 :: l0);(x ++ A2 :: x0, [] ++ l0)]).
+  apply InT_cons ; apply InT_eq.
+  destruct (finite_ImpRules_premises_of_S (x ++ A1 --> A2 :: x0, l0)).
+  apply p. right. assert ((x ++ A1 --> A2 :: x0, l0) = (x ++ A1 --> A2 :: x0, [] ++ l0)). auto.
+  rewrite H0. apply ImpLRule_I.
+  rewrite H in H0. inversion H0.
+  apply in_split in H0. destruct H0. destruct H0. subst.
+  assert (In (l ++ A1 :: [], x ++ A2 :: x0) (inv_prems (l ++ [] , x ++ A1 --> A2 :: x0))).
+  unfold inv_prems. apply InT_In.
+  apply InT_trans_flatten_list with (bs:=[(l ++ [A1], x ++ A2 :: x0)]). apply InT_eq.
+  destruct (finite_ImpRules_premises_of_S (l ++ [], x ++ A1 --> A2 :: x0)).
+  apply p. left. apply ImpRRule_I. rewrite app_nil_r in H0.
+  rewrite H in H0. inversion H0.
+  Qed.
+ +
+  Lemma Canopy_critical : forall s leaf, InT leaf (Canopy s) -> (critical_Seq leaf).
+  Proof.
+  unfold Canopy.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  intros. remember (inv_prems s) as prems. destruct prems.
+  - symmetry in Heqprems ; pose (irred_nil _ _ Acc_invprem s Heqprems).
+    rewrite e in H. pose (inv_prems_id_critical _ Heqprems). inversion H ; subst ; auto.
+    inversion H1.
+  - assert (J1: inv_prems s <> []%list). rewrite <- Heqprems. intro.
+    inversion H0. pose (irred_not _ _ Acc_invprem s J1). rewrite e in H.
+    pose (InT_In H). apply in_flat_map in i. destruct i. destruct H0.
+    apply In_InT_seqs in H1. apply IHs with (y:=x) ; auto.
+    apply InT_In_inv_prems in H0. unfold inv_prems in H0.
+    destruct (finite_ImpRules_premises_of_S s) in H0. simpl in H0.
+    apply InT_flatten_list_InT_elem in H0. destruct H0. destruct p0.
+    apply p in i0. destruct i0.
+    inversion i0. subst. inversion i. subst.
+    unfold n_imp_subformS ; simpl. repeat rewrite n_imp_subformLF_dist_app.
+    simpl. lia. subst. inversion H2.
+    inversion i0. subst. inversion i. subst.
+    unfold n_imp_subformS ; simpl. repeat rewrite n_imp_subformLF_dist_app.
+    simpl. lia. subst.
+    inversion H2. subst.
+    unfold n_imp_subformS ; simpl. repeat rewrite n_imp_subformLF_dist_app.
+    simpl. lia. subst. inversion H3.
+  Qed.
+ +
+  (* We show the equiprovability between a sequent and its Canopy. *)
+ +
+  Lemma ImpRule_Canopy : forall s prems, ((ImpRRule prems s) + (ImpLRule prems s)) ->
+                (forall prem, InT prem prems -> (forall leaf, InT leaf (Canopy prem) -> InT leaf (Canopy s))).
+  Proof.
+  intros. unfold Canopy. rewrite irred_not. apply In_InT_seqs.
+  apply in_flat_map. exists prem ; split ; auto. 2: apply InT_In ; auto.
+  unfold inv_prems. apply InT_In. apply InT_trans_flatten_list with (bs:=prems) ; auto.
+  destruct (finite_ImpRules_premises_of_S s) ; simpl. apply p ; auto.
+  intro. unfold inv_prems in H2. destruct (finite_ImpRules_premises_of_S s) ; simpl.
+  simpl in H2. apply p in H. assert (InT prem (flatten_list x)).
+  apply InT_trans_flatten_list with (bs:=prems) ; auto. rewrite H2 in H3. inversion H3.
+  Qed.
+ +
+  (* Move the lemma below to a more general location. *)
+ +
+  Lemma InT_flat_map: forall (f : Seq -> list Seq) (l : list Seq) (y : Seq), (InT y (flat_map f l) -> (existsT2 x : Seq, InT x l * InT y (f x))) *
+                                                                                                                ( (existsT2 x : Seq, InT x l * InT y (f x)) -> InT y (flat_map f l)).
+  Proof.
+  intros f. induction l.
+  - intros ; split ; intros. simpl in H. inversion H. simpl. destruct H. destruct p. inversion i.
+  - intros ; simpl ; split ; intros. apply InT_app_or in H. destruct H. exists a ; split ; auto. apply InT_eq.
+    apply IHl in i. destruct i. destruct p. exists x ; split ; auto. apply InT_cons ; auto.
+    apply InT_or_app. destruct H. destruct p. inversion i ; subst ; auto. right.
+    apply IHl. exists x ; split ; auto.
+  Qed.
+ +
+  Lemma fold_Canopy : forall s leaf, InT leaf (Canopy s) ->
+                  (leaf = s) + (existsT2 prem, InT prem (inv_prems s) * InT leaf (Canopy prem)).
+  Proof.
+  intros. remember (finite_ImpRules_premises_of_S s) as J.
+  destruct J. destruct x.
+  - assert (Canopy s = [s]). apply irred_nil. unfold inv_prems. rewrite <- HeqJ.
+    simpl. auto. rewrite H0 in H. inversion H ; subst ; auto. inversion H2.
+  - right. unfold Canopy in H. rewrite irred_not in H. apply InT_flat_map in H. destruct H.
+    destruct p0. exists x0 ; split ; auto. intro. unfold inv_prems in H0. rewrite <- HeqJ in H0.
+    assert (InT l (l :: x)). apply InT_eq. apply p in H1. destruct H1 ; inversion i ; subst ;
+    simpl in H0 ; inversion H0.
+  Qed.
+ +
+  Lemma Canopy_equiprv : forall s,
+    ((forall leaf, InT leaf (Canopy s) -> GLS_prv leaf) -> (GLS_prv s)) *
+    ((GLS_prv s) -> (forall leaf, InT leaf (Canopy s) -> GLS_prv leaf)).
+  Proof.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  intros ; split ; intros.
+  - remember (finite_ImpRules_premises_of_S s) as H.
+    destruct H. destruct x.
+    + assert (Canopy s = [s]). apply irred_nil. unfold inv_prems. rewrite <- HeqH.
+       simpl. auto. rewrite H in X. apply X. apply InT_eq.
+    + assert (J1: InT l (l :: x)). apply InT_eq. apply p in J1. destruct J1 ; unfold GLS_prv ; apply derI with (ps:=l).
+       apply ImpR ; auto. 2: apply ImpL ; auto. all: inversion i ; subst ; apply dlCons. 4: apply dlCons. 2,5: apply dlNil.
+       all: apply IHs. 1,3,5: unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       all: intros ; apply X. apply ImpRule_Canopy with (prems:=[(Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)]) (prem:=(Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)) ; auto.
+       apply InT_eq. apply ImpRule_Canopy with (prems:=[(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)])
+       (prem:=(Γ0 ++ Γ1, Δ0 ++ A :: Δ1)) ; auto. apply InT_eq.
+        apply ImpRule_Canopy with (prems:=[(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)])
+       (prem:=(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)) ; auto. apply InT_cons ; apply InT_eq.
+  - apply fold_Canopy in H. destruct H ; subst ; auto. destruct s0. destruct p.
+    unfold inv_prems in i ; apply InT_flatten_list_InT_elem in i ; destruct i ; destruct p ; destruct (finite_ImpRules_premises_of_S s) ;
+    simpl in i1. apply p in i1. destruct i1 ; inversion i1 ; subst.
+    + inversion i ; subst. 2: inversion H0. apply IHs with (y:=(Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)) ; auto.
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply ImpR_inv with (concl:=(Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1)) ; auto.
+    + inversion i ; subst. apply IHs with (y:=(Γ0 ++ Γ1, Δ0 ++ A :: Δ1)) ; auto.
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply ImpL_inv with (concl:=(Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)) (prem2:= (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)) ; auto.
+       inversion H0 ; subst. 2: inversion H1. apply IHs with (y:=(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)) ; auto.
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply ImpL_inv with (concl:=(Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)) (prem1:= (Γ0 ++ Γ1, Δ0 ++ A :: Δ1)) ; auto.
+  Qed.
+ +
+  Lemma Canopy_equiprv_genL : forall s A,
+    ((forall leaf, InT leaf (Canopy s) -> GLS_prv (A :: fst leaf, snd leaf)) -> (GLS_prv (A :: fst s, snd s))) *
+    ((GLS_prv (A :: fst s, snd s)) -> (forall leaf, InT leaf (Canopy s) -> GLS_prv (A :: fst leaf, snd leaf))).
+  Proof.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  intros ; split ; intros.
+  - remember (finite_ImpRules_premises_of_S s) as H0.
+    destruct H0. destruct x.
+    + assert (Canopy s = [s]). apply irred_nil. unfold inv_prems. rewrite <- HeqH0.
+       simpl. auto. rewrite H in X. apply X. apply InT_eq.
+    + assert (J1: InT l (l :: x)). apply InT_eq. apply p in J1. destruct J1 ; unfold GLS_prv ; inversion i ; subst ; simpl.
+       apply derI with (ps:=[(A :: Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ1)]).
+       apply ImpR ; auto. assert ((A :: Γ0 ++ A0 :: Γ1) = ((A :: Γ0) ++ A0 :: Γ1)). auto. rewrite H.
+       assert (A :: Γ0 ++ Γ1 = (A :: Γ0) ++ Γ1). auto. rewrite H0. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+       2: apply derI with (ps:=[(A :: Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1);(A :: Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]).
+       2: apply ImpL ; auto. 2: assert (A :: Γ0 ++ Γ1 = ((A :: Γ0) ++ Γ1)) ; auto ; rewrite H.
+       2: assert (A :: Γ0 ++ B :: Γ1 = (A :: Γ0) ++ B :: Γ1) ; auto ; rewrite H0. 2: apply ImpLRule_I. 2: apply dlCons.
+       3: apply dlCons. 4: apply dlNil.
+       assert (J2: n_imp_subformS (Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ1) < n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A0 --> B :: Δ1)).
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply IHs with (A:=A) in J2. simpl in J2. destruct J2. apply g. intros. apply X.
+       apply ImpRule_Canopy with (prems:=[(Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ1)]) (prem:=(Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ1)) ; auto.
+       apply InT_eq.
+       assert (J2: n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1) < n_imp_subformS (Γ0 ++ A0 --> B :: Γ1, Δ0 ++ Δ1)).
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply IHs with (A:=A) in J2. simpl in J2. destruct J2. apply g. intros. apply X.
+       apply ImpRule_Canopy with (prems:=[(Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)])
+       (prem:=(Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1)) ; auto. apply InT_eq.
+       assert (J2: n_imp_subformS (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) < n_imp_subformS (Γ0 ++ A0 --> B :: Γ1, Δ0 ++ Δ1)).
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply IHs with (A:=A) in J2. simpl in J2. destruct J2. apply g. intros. apply X.
+       apply ImpRule_Canopy with (prems:=[(Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)])
+       (prem:=(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)) ; auto. apply InT_cons. apply InT_eq.
+  - apply fold_Canopy in H. destruct H ; subst ; auto. destruct s0. destruct p.
+    unfold inv_prems in i ; apply InT_flatten_list_InT_elem in i ; destruct i ; destruct p ; destruct (finite_ImpRules_premises_of_S s) ;
+    simpl in i1. apply p in i1. destruct i1 ; inversion i1 ; subst.
+    + inversion i ; subst. 2: inversion H0. apply IHs with (y:=(Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ1)) ; auto.
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply ImpR_inv with (concl:=(A :: Γ0 ++ Γ1, Δ0 ++ A0 --> B :: Δ1)) ; auto. simpl.
+       assert (A :: Γ0 ++ A0 :: Γ1 = (A :: Γ0) ++ A0 :: Γ1). auto. rewrite H.
+       assert (A :: Γ0 ++ Γ1 = (A :: Γ0) ++ Γ1). auto. rewrite H0. apply ImpRRule_I.
+    + inversion i ; subst. apply IHs with (y:=(Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1)) ; auto.
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply ImpL_inv with (concl:=(A :: Γ0 ++ A0 --> B :: Γ1, Δ0 ++ Δ1)) (prem2:= (A :: Γ0 ++ B :: Γ1, Δ0 ++ Δ1)) ; auto. simpl.
+       assert (A :: Γ0 ++ B :: Γ1 = (A :: Γ0) ++ B :: Γ1). auto. rewrite H.
+       assert (A :: Γ0 ++ Γ1 = (A :: Γ0) ++ Γ1). auto. rewrite H0. apply ImpLRule_I.
+       inversion H0 ; subst. 2: inversion H1. apply IHs with (y:=(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)) ; auto.
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply ImpL_inv with (concl:=(A :: Γ0 ++ A0 --> B :: Γ1, Δ0 ++ Δ1)) (prem1:= (A :: Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1)) ; auto. simpl.
+       assert (A :: Γ0 ++ B :: Γ1 = (A :: Γ0) ++ B :: Γ1). auto. rewrite H.
+       assert (A :: Γ0 ++ Γ1 = (A :: Γ0) ++ Γ1). auto. rewrite H1. apply ImpLRule_I.
+  Qed.
+ +
+  Lemma Canopy_equiprv_genR : forall s A,
+    ((forall leaf, InT leaf (Canopy s) -> GLS_prv (fst leaf, A :: snd leaf)) -> (GLS_prv (fst s, A :: snd s))) *
+    ((GLS_prv (fst s, A :: snd s)) -> (forall leaf, InT leaf (Canopy s) -> GLS_prv (fst leaf, A :: snd leaf))).
+  Proof.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  intros ; split ; intros.
+  - remember (finite_ImpRules_premises_of_S s) as H0.
+    destruct H0. destruct x.
+    + assert (Canopy s = [s]). apply irred_nil. unfold inv_prems. rewrite <- HeqH0.
+       simpl. auto. rewrite H in X. apply X. apply InT_eq.
+    + assert (J1: InT l (l :: x)). apply InT_eq. apply p in J1. destruct J1 ; unfold GLS_prv ; inversion i ; subst ; simpl.
+       apply derI with (ps:=[(Γ0 ++ A0 :: Γ1, A :: Δ0 ++ B :: Δ1)]).
+       apply ImpR ; auto. assert ((A :: Δ0 ++ B :: Δ1) = ((A :: Δ0) ++ B :: Δ1)). auto. rewrite H.
+       assert (A :: Δ0 ++ A0 --> B :: Δ1 = (A :: Δ0) ++ A0 --> B :: Δ1). auto. rewrite H0. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+       2: apply derI with (ps:=[(Γ0 ++ Γ1, A :: Δ0 ++ A0 :: Δ1);(Γ0 ++ B :: Γ1, A :: Δ0 ++ Δ1)]).
+       2: apply ImpL ; auto. 2: assert (A :: Δ0 ++ Δ1 = ((A :: Δ0) ++ Δ1)) ; auto ; rewrite H.
+       2: assert (A :: Δ0 ++ A0 :: Δ1 = (A :: Δ0) ++ A0 :: Δ1) ; auto ; rewrite H0. 2: apply ImpLRule_I. 2: apply dlCons.
+       3: apply dlCons. 4: apply dlNil.
+       assert (J2: n_imp_subformS (Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ1) < n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A0 --> B :: Δ1)).
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply IHs with (A:=A) in J2. simpl in J2. destruct J2. apply g. intros. apply X.
+       apply ImpRule_Canopy with (prems:=[(Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ1)]) (prem:=(Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ1)) ; auto.
+       apply InT_eq.
+       assert (J2: n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1) < n_imp_subformS (Γ0 ++ A0 --> B :: Γ1, Δ0 ++ Δ1)).
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply IHs with (A:=A) in J2. simpl in J2. destruct J2. apply g. intros. apply X.
+       apply ImpRule_Canopy with (prems:=[(Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)])
+       (prem:=(Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1)) ; auto. apply InT_eq.
+       assert (J2: n_imp_subformS (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) < n_imp_subformS (Γ0 ++ A0 --> B :: Γ1, Δ0 ++ Δ1)).
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply IHs with (A:=A) in J2. simpl in J2. destruct J2. apply g. intros. apply X.
+       apply ImpRule_Canopy with (prems:=[(Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)])
+       (prem:=(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)) ; auto. apply InT_cons. apply InT_eq.
+  - apply fold_Canopy in H. destruct H ; subst ; auto. destruct s0. destruct p.
+    unfold inv_prems in i ; apply InT_flatten_list_InT_elem in i ; destruct i ; destruct p ; destruct (finite_ImpRules_premises_of_S s) ;
+    simpl in i1. apply p in i1. destruct i1 ; inversion i1 ; subst.
+    + inversion i ; subst. 2: inversion H0. apply IHs with (y:=(Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ1)) ; auto.
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply ImpR_inv with (concl:=(Γ0 ++ Γ1, A :: Δ0 ++ A0 --> B :: Δ1)) ; auto. simpl.
+       assert (A :: Δ0 ++ B :: Δ1 = (A :: Δ0) ++ B :: Δ1). auto. rewrite H.
+       assert (A :: Δ0 ++ A0 --> B :: Δ1 = (A :: Δ0) ++ A0 --> B :: Δ1). auto. rewrite H0. apply ImpRRule_I.
+    + inversion i ; subst. apply IHs with (y:=(Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1)) ; auto.
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply ImpL_inv with (concl:=(Γ0 ++ A0 --> B :: Γ1, A :: Δ0 ++ Δ1)) (prem2:= (Γ0 ++ B :: Γ1, A :: Δ0 ++ Δ1)) ; auto. simpl.
+       assert (A :: Δ0 ++ A0 :: Δ1 = (A :: Δ0) ++ A0 :: Δ1). auto. rewrite H.
+       assert (A :: Δ0 ++ Δ1 = (A :: Δ0) ++ Δ1). auto. rewrite H0. apply ImpLRule_I.
+       inversion H0 ; subst. 2: inversion H1. apply IHs with (y:=(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)) ; auto.
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply ImpL_inv with (concl:=(Γ0 ++ A0 --> B :: Γ1, A :: Δ0 ++ Δ1)) (prem1:= (Γ0 ++ Γ1, A :: Δ0 ++ A0 :: Δ1)) ; auto. simpl.
+       assert (A :: Δ0 ++ A0 :: Δ1 = (A :: Δ0) ++ A0 :: Δ1). auto. rewrite H.
+       assert (A :: Δ0 ++ Δ1 = (A :: Δ0) ++ Δ1). auto. rewrite H1. apply ImpLRule_I.
+  Qed.
+ +
+  Lemma Canopy_hp_inv_ctx : forall s k scomp (D0 : GLS_prv scomp) X0 Y0,
+        k = (derrec_height D0) ->
+        scomp = (fst s ++ X0, snd s ++ Y0) ->
+        (forall leaf, InT leaf (Canopy s) -> existsT2 (D1: GLS_prv (fst leaf ++ X0, snd leaf ++ Y0)),
+                                                                                derrec_height D1 <= k).
+  Proof.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  intros. apply fold_Canopy in H1. destruct H1.
+  - subst. exists D0 ; auto.
+  - destruct s0 ; destruct p. unfold inv_prems in i. apply InT_flatten_list_InT_elem in i. destruct i.
+    destruct p. destruct (finite_ImpRules_premises_of_S s). simpl in i1. subst.
+    assert (J0: derrec_height D0 = derrec_height D0). auto.
+    pose (ImpR_ImpL_hpinv D0 J0). destruct p0. apply p in i1. destruct i1.
+    + inversion i1 ; subst. simpl in s0.
+       assert (J1: ImpRRule [(Γ0 ++ A :: (Γ1 ++ X0), Δ0 ++ B :: (Δ1 ++ Y0))] ((Γ0 ++ Γ1) ++ X0, (Δ0 ++ A --> B :: Δ1) ++ Y0)).
+       repeat rewrite <- app_assoc ; apply ImpRRule_I. apply s0 in J1. destruct J1. inversion i ; subst.
+       assert (J2: n_imp_subformS (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) < n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1)).
+       unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+       lia.
+       assert (J3: derrec_height x0 = derrec_height x0). auto.
+       assert (J4: (Γ0 ++ A :: Γ1 ++ X0, Δ0 ++ B :: Δ1 ++ Y0) = (fst (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) ++ X0, snd (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) ++ Y0)).
+       simpl ; repeat rewrite <- app_assoc ; auto.
+       pose (IHs _ J2 _ _ x0 X0 Y0 J3 J4 _ i0). destruct s. exists x. apply PeanoNat.Nat.le_trans with (m:=derrec_height x0) ; auto.
+       inversion H0.
+    + inversion i1 ; subst. simpl in s1. clear s0.
+       assert (J1: ImpLRule [(Γ0 ++ Γ1 ++ X0, Δ0 ++ A :: Δ1 ++ Y0); (Γ0 ++ B :: Γ1 ++ X0, Δ0 ++ Δ1 ++ Y0)] ((Γ0 ++ A --> B :: Γ1) ++ X0, (Δ0 ++ Δ1) ++ Y0)).
+       repeat rewrite <- app_assoc ; apply ImpLRule_I. apply s1 in J1. destruct J1. destruct s. destruct p0. inversion i ; subst.
+       assert (J2: n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+       unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+       lia.
+       assert (J3: derrec_height x0 = derrec_height x0). auto.
+       assert (J4: (Γ0 ++ Γ1 ++ X0, Δ0 ++ A :: Δ1 ++ Y0) = (fst (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) ++ X0, snd (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) ++ Y0)).
+       simpl ; repeat rewrite <- app_assoc ; auto.
+       pose (IHs _ J2 _ _ x0 X0 Y0 J3 J4 _ i0). destruct s. exists x. apply PeanoNat.Nat.le_trans with (m:=derrec_height x0) ; auto.
+       inversion H0 ; subst.
+       assert (J2: n_imp_subformS (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+       unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+       lia.
+       assert (J3: derrec_height x2 = derrec_height x2). auto.
+       assert (J4: (Γ0 ++ B :: Γ1 ++ X0, Δ0 ++ Δ1 ++ Y0) = (fst (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) ++ X0, snd (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) ++ Y0)).
+       simpl ; repeat rewrite <- app_assoc ; auto.
+       pose (IHs _ J2 _ _ x2 X0 Y0 J3 J4 _ i0). destruct s. exists x. apply PeanoNat.Nat.le_trans with (m:=derrec_height x2) ; auto.
+       inversion H1.
+  Qed.
+ +
+  Lemma Canopy_neg_var : forall s q, InT (# q) (fst s) -> (forall leaf, InT leaf (Canopy s) -> InT (# q) (fst leaf)).
+  Proof.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  intros. apply fold_Canopy in H0. destruct H0 ; subst ; auto.
+  destruct s0 ; destruct p. unfold inv_prems in i. apply InT_flatten_list_InT_elem in i. destruct i.
+  destruct p. destruct (finite_ImpRules_premises_of_S s). simpl in i1. subst.
+  apply p in i1. destruct i1.
+  - inversion i1 ; subst. inversion i ; subst. 2: inversion H1.
+    assert (J0: n_imp_subformS (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) < n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1)).
+     unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+     lia.
+    apply IHs with (q:= q) (leaf:=leaf) in J0 ; auto. simpl. apply InT_or_app. simpl in H. apply InT_app_or in H ; destruct H ; auto.
+    right ; apply InT_cons ; auto.
+  - inversion i1 ; subst. inversion i ; subst. 2: inversion H1. 3: inversion H2.
+    assert (J0: n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+     unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+     lia.
+    apply IHs with (q:= q) (leaf:=leaf) in J0 ; auto. simpl. apply InT_or_app. simpl in H. apply InT_app_or in H ; destruct H ; auto.
+    inversion i2 ; subst. inversion H0. auto. subst.
+    assert (J0: n_imp_subformS (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+     unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+     lia.
+    apply IHs with (q:= q) (leaf:=leaf) in J0 ; auto. simpl. apply InT_or_app. simpl in H. apply InT_app_or in H ; destruct H ; auto.
+    inversion i2 ; subst. inversion H0. right ; apply InT_cons ; auto.
+  Qed.
+ +
+  Lemma Canopy_pos_var : forall s q, InT (# q) (snd s) -> (forall leaf, InT leaf (Canopy s) -> InT (# q) (snd leaf)).
+  Proof.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  intros. apply fold_Canopy in H0. destruct H0 ; subst ; auto.
+  destruct s0 ; destruct p. unfold inv_prems in i. apply InT_flatten_list_InT_elem in i. destruct i.
+  destruct p. destruct (finite_ImpRules_premises_of_S s). simpl in i1. subst.
+  apply p in i1. destruct i1.
+  - inversion i1 ; subst. inversion i ; subst. 2: inversion H1.
+    assert (J0: n_imp_subformS (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) < n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1)).
+     unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+     lia.
+    apply IHs with (q:= q) (leaf:=leaf) in J0 ; auto. simpl. apply InT_or_app. simpl in H. apply InT_app_or in H ; destruct H ; auto.
+    inversion i2 ; subst. inversion H0. right ; apply InT_cons ; auto.
+  - inversion i1 ; subst. inversion i ; subst. 2: inversion H1. 3: inversion H2.
+    assert (J0: n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+     unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+     lia.
+    apply IHs with (q:= q) (leaf:=leaf) in J0 ; auto. simpl. apply InT_or_app. simpl in H. apply InT_app_or in H ; destruct H ; auto.
+    right ; apply InT_cons ; auto. subst.
+    assert (J0: n_imp_subformS (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+     unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+     lia.
+    apply IHs with (q:= q) (leaf:=leaf) in J0 ; auto.
+  Qed.
+ +
+  Definition Id_InT_Canopy : forall s, InT s (Canopy s) -> Canopy s = [s].
+  Proof.
+  intros. destruct (critical_Seq_dec s).
+  - remember (finite_ImpRules_premises_of_S s) as J.
+    destruct J. destruct x.
+    + apply irred_nil. unfold inv_prems. rewrite <- HeqJ.
+       simpl. auto.
+    + exfalso. assert (J1: InT l (l :: x)). apply InT_eq. apply p in J1. unfold critical_Seq in c.
+       destruct J1 ; inversion i ; subst ; simpl in c.
+       assert (In (A --> B) ((Γ0 ++ Γ1) ++ Δ0 ++ A --> B :: Δ1)). apply in_or_app ; right ; apply in_or_app ; right ; apply in_eq.
+       apply c in H0. destruct H0. destruct H0. inversion H0. destruct H0. destruct H0 ; inversion H0. inversion H0.
+       assert (In (A --> B) ((Γ0 ++ A --> B :: Γ1) ++ Δ0 ++ Δ1)). apply in_or_app ; left ; apply in_or_app ; right ; apply in_eq.
+       apply c in H0. destruct H0. destruct H0. inversion H0. destruct H0. destruct H0 ; inversion H0. inversion H0.
+  - exfalso. apply Canopy_critical in H. auto.
+  Defined.
+ +
+  Lemma critical_Seq_InT_Canopy : forall s, critical_Seq s -> InT s (Canopy s).
+  Proof.
+  intros. remember (finite_ImpRules_premises_of_S s) as J.
+  destruct J. destruct x.
+  + pose irred_nil. unfold Canopy. rewrite e. apply InT_eq. unfold inv_prems. rewrite <- HeqJ.
+     simpl. auto.
+  + exfalso. assert (J1: InT l (l :: x)). apply InT_eq. apply p in J1. unfold critical_Seq in H.
+     destruct J1 ; inversion i ; subst ; simpl in H.
+     assert (In (A --> B) ((Γ0 ++ Γ1) ++ Δ0 ++ A --> B :: Δ1)). apply in_or_app ; right ; apply in_or_app ; right ; apply in_eq.
+     apply H in H0. destruct H0. destruct H0. inversion H0. destruct H0. destruct H0 ; inversion H0. inversion H0.
+     assert (In (A --> B) ((Γ0 ++ A --> B :: Γ1) ++ Δ0 ++ Δ1)). apply in_or_app ; left ; apply in_or_app ; right ; apply in_eq.
+     apply H in H0. destruct H0. destruct H0. inversion H0. destruct H0. destruct H0 ; inversion H0. inversion H0.
+  Qed.
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_Canopy_ImpL.html b/GL.Interpolation.UIGL_Canopy_ImpL.html new file mode 100644 index 0000000..0a48f6b --- /dev/null +++ b/GL.Interpolation.UIGL_Canopy_ImpL.html @@ -0,0 +1,108 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_Canopy_ImpL

+ +
+  Require Import List.
+  Export ListNotations.
+  Require Import PeanoNat.
+  Require Import Lia.
+ +
+  Require Import general_export.
+ +
+  Require Import GLS_export.
+ +
+  Require Import UIGL_Def_measure.
+  Require Import UIGL_Canopy.
+  Require Import UIGL_irred_short.
+  Require Import UIGL_braga.
+  Require Import UIGL_Canopy_ImpR.
+ +
+  Lemma repeat_more_than_one : forall n (A : MPropF), 0 < n -> In A (repeat A n).
+  Proof.
+  induction n ; simpl ; intros ; auto. inversion H.
+  Qed.
+ +
+  (* These two lemmas are crucial. *)
+ +
+  Lemma mult_ImpL_R : forall s0 s1 A B,
+          InT s1 (Canopy (replace (A --> B) B (fst s0), snd s0))->
+          InT s1 (Canopy s0).
+  Proof.
+  intros s0 s1 A B. remember (count_occ eq_dec_form (fst s0) (A --> B)) as n. revert Heqn. generalize dependent B.
+  generalize dependent A. generalize dependent s1. generalize dependent s0. induction n ; simpl ; intros.
+  - symmetry in Heqn. rewrite <- count_occ_not_In in Heqn. rewrite notin_replace in H ; auto. destruct s0 ; auto.
+  - assert (count_occ eq_dec_form (fst s0) (A --> B) > 0). lia. apply count_occ_In in H0. destruct s0. simpl in H0.
+    simpl in H. simpl in Heqn. apply In_InT in H0. apply InT_split in H0. destruct H0. destruct s ; subst.
+    repeat rewrite count_occ_app in Heqn. simpl in Heqn. repeat rewrite replace_app in H.
+    simpl in H. destruct (eq_dec_form (A --> B) (A --> B)). 2: exfalso ; auto.
+    assert (n = count_occ eq_dec_form (x ++ x0) (A --> B)). repeat rewrite count_occ_app ; lia.
+    pose (IHn (x ++ B :: x0, l0) s1 A B). simpl in i.
+    repeat rewrite count_occ_app in i. simpl in i. repeat rewrite replace_app in i.
+    simpl in i. destruct (eq_dec_form B (A --> B)). exfalso. assert (length_form (A --> B) = length_form B). rewrite <- e0 ; auto.
+    simpl in H1 ; lia. destruct (eq_dec_form (A --> B) B). exfalso ; auto. repeat rewrite count_occ_app in H0. pose (i H0 H).
+    apply ImpRule_Canopy with (prems:=[(x ++ x0, A :: l0);(x ++ B :: x0, l0)]) (prem:=(x ++ B :: x0, l0)) ; auto.
+     right. epose (ImpLRule_I _ _ _ _ []). simpl in i1 ; apply i1. apply InT_cons ; apply InT_eq.
+  Qed.
+ +
+  Lemma mult_ImpL_L : forall s0 s1 A B,
+          InT s1 (Canopy (remove eq_dec_form (A --> B) (fst s0), repeat A (count_occ eq_dec_form (fst s0) (A --> B)) ++ (snd s0)))->
+          InT s1 (Canopy s0).
+  Proof.
+  intros s0 s1 A B. remember (count_occ eq_dec_form (fst s0) (A --> B)) as n. revert Heqn. generalize dependent B.
+  generalize dependent A. generalize dependent s1. generalize dependent s0. induction n ; simpl ; intros.
+  - symmetry in Heqn. rewrite <- count_occ_not_In in Heqn. rewrite notin_remove in H ; auto. destruct s0 ; auto.
+  - assert (count_occ eq_dec_form (fst s0) (A --> B) > 0). lia. apply count_occ_In in H0. destruct s0. simpl in H0.
+    simpl in H. simpl in Heqn. apply In_InT in H0. apply InT_split in H0. destruct H0. destruct s ; subst.
+    repeat rewrite count_occ_app in Heqn. simpl in Heqn. repeat rewrite remove_app in H.
+    simpl in H. destruct (eq_dec_form (A --> B) (A --> B)). 2: exfalso ; auto.
+    assert (n = count_occ eq_dec_form (x ++ x0) (A --> B)). repeat rewrite count_occ_app ; lia.
+    pose (IHn (x ++ x0, A :: l0) s1 A B). simpl in i. repeat rewrite count_occ_app in i. repeat rewrite remove_app in i.
+    repeat rewrite count_occ_app in H0. pose (i H0).
+    assert (repeat A n ++ A :: l0 = A :: repeat A n ++ l0). assert (repeat A n ++ A :: l0 = (repeat A n ++ [A]) ++ l0).
+    rewrite <- app_assoc. auto. rewrite H1. rewrite <- repeat_cons. simpl ; auto. rewrite H1 in i0. apply i0 in H.
+    apply ImpRule_Canopy with (prems:=[(x ++ x0, A :: l0);(x ++ B :: x0, l0)]) (prem:=(x ++ x0, A :: l0)) ; auto.
+    right. epose (ImpLRule_I _ _ _ _ []). simpl in i1 ; apply i1. apply InT_eq.
+  Qed.
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_Canopy_ImpR.html b/GL.Interpolation.UIGL_Canopy_ImpR.html new file mode 100644 index 0000000..8909d88 --- /dev/null +++ b/GL.Interpolation.UIGL_Canopy_ImpR.html @@ -0,0 +1,241 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_Canopy_ImpR

+ +
+  Require Import List.
+  Export ListNotations.
+  Require Import PeanoNat.
+  Require Import Lia.
+ +
+  Require Import general_export.
+ +
+  Require Import GLS_export.
+ +
+  Require Import UIGL_Def_measure.
+  Require Import UIGL_Canopy.
+  Require Import UIGL_irred_short.
+  Require Import UIGL_braga.
+ +
+  (* Operation to remove and replace an element in a list. *)
+ +
+  Definition replace (A B : MPropF) (l : list MPropF) : list MPropF :=
+  let subst_form A B C := if (eq_dec_form A C) then B else C in
+  map (subst_form A B) l.
+ +
+  Lemma replace_app : forall l0 l1 A B, replace A B (l0 ++ l1) = replace A B l0 ++ replace A B l1.
+  Proof. intros. apply map_app. Qed.
+ +
+  Lemma in_not_touched_replace : forall (l : list MPropF) [A B C : MPropF], In C l -> C <> A ->
+              In C (replace A B l).
+  Proof.
+  intros. apply in_map_iff. exists C. destruct (eq_dec_form A C) ; subst; tauto.
+  Qed.
+ +
+  Lemma in_replace : forall l A B C, A <> B -> In C (replace A B l) -> (In C l \/ C = B) /\ A <> C.
+  Proof.
+  induction l ; simpl ; intros ; auto. destruct (eq_dec_form A a) ; subst.
+  inversion H0 ; subst. split ; auto. pose (IHl _ _ _ H H1). destruct a0. split ; auto. destruct H2 ; auto.
+  inversion H0 ; subst. split ; auto. pose (IHl _ _ _ H H1). destruct a0 ; split ; auto. destruct H2 ; auto.
+  Qed.
+ +
+  Lemma notin_replace : forall l (A B : MPropF), (In A l -> False) -> replace A B l = l.
+  Proof.
+  induction l ; simpl ; intros ; auto. destruct (eq_dec_form A a) ; subst. destruct H ; auto. rewrite IHl ; auto.
+  Qed.
+ +
+  Lemma univ_gen_ext_count_occ : forall l0 l1 A, univ_gen_ext (fun x : MPropF => x = A) l0 l1 ->
+                count_occ eq_dec_form l0 A <= count_occ eq_dec_form l1 A.
+  Proof.
+  intros. induction X ; simpl ; try lia. all: destruct (eq_dec_form x A) ; try lia.
+  Qed.
+ +
+  Lemma univ_gen_ext_S_count_occ : forall l0 l1 A, (count_occ eq_dec_form l0 A < count_occ eq_dec_form l1 A) ->
+                (univ_gen_ext (fun x : MPropF => x = A) l0 l1) ->
+                existsT2 l2 l3 l4 l5, (l0 = l2 ++ l3) * (l1 = l4 ++ A :: l5) * (univ_gen_ext (fun x : MPropF => x = A) l2 l4) *
+                                              (univ_gen_ext (fun x : MPropF => x = A) l3 l5).
+  Proof.
+  intros. revert H. induction X ; simpl ; intros ; auto ; try lia.
+  - destruct (eq_dec_form x A) ; subst.
+    * assert ((count_occ eq_dec_form l A) < (count_occ eq_dec_form le A)). lia. apply IHX in H0.
+      destruct H0. destruct s. destruct s. destruct s. destruct p. destruct p. destruct p ; subst.
+      exists (A :: x). exists x0. exists (A :: x1). exists x2. simpl. repeat split ; auto.
+      apply univ_gen_ext_cons ; auto.
+    * apply IHX in H. destruct H. destruct s. destruct s. destruct s. destruct p. destruct p. destruct p ; subst.
+      exists (x :: x0). exists x1. exists (x :: x2). exists x3. simpl. repeat split ; auto.
+      apply univ_gen_ext_cons ; auto.
+  - destruct (eq_dec_form x A) ; subst.
+    * exists []. exists l. exists []. exists le. simpl. repeat split ; auto. apply univ_gen_ext_nil.
+    * apply IHX in H. destruct H. destruct s. destruct s. destruct s. destruct p. destruct p. destruct p ; subst.
+      exists x. exists x0. exists (A :: x1). exists x2. simpl. repeat split ; auto.
+      apply univ_gen_ext_extra ; auto.
+  Qed.
+ +
+  Lemma count_occ_n_imp_subformLF : forall l A B, count_occ eq_dec_form l (A --> B) * S (n_imp_subformF A) <= n_imp_subformLF l.
+  Proof.
+  induction l ; simpl ; intros ; auto. destruct (eq_dec_form a (A --> B)) ; subst ; auto.
+  - pose (IHl A B). assert (n_imp_subformF A < n_imp_subformF (A --> B)). simpl. lia. lia.
+  - pose (IHl A B). lia.
+  Qed.
+ +
+  Lemma count_le_n_imp : forall l A B, count_occ eq_dec_form l (A --> B) <= n_imp_subformLF l.
+  Proof.
+  intros. pose (count_occ_n_imp_subformLF l A B). lia.
+  Qed.
+ +
+  Global Opaque eq_dec_form.
+ +
+  Lemma n_imp_subformLF_replace : forall l A B, n_imp_subformLF (replace (A --> B) B l) =
+        (n_imp_subformLF l - ((count_occ eq_dec_form l (A --> B)) * S (n_imp_subformF A))).
+  Proof.
+  intros. remember (count_occ eq_dec_form l (A --> B)) as n. revert Heqn. generalize dependent B.
+  generalize dependent A. generalize dependent l. induction n ; simpl ; intros.
+  - rewrite notin_replace ; try lia. symmetry in Heqn. rewrite <- count_occ_not_In in Heqn ; auto.
+  - assert (count_occ eq_dec_form l (A --> B) > 0). lia. apply count_occ_In in H. apply in_split in H. destruct H.
+    destruct H ; subst. repeat rewrite n_imp_subformLF_dist_app. simpl. repeat rewrite count_occ_app in Heqn.
+    repeat rewrite replace_app. simpl. simpl in Heqn. destruct (eq_dec_form (A --> B) (A --> B)). 2: exfalso ; auto.
+    assert (n = count_occ eq_dec_form (x ++ x0) (A --> B)). repeat rewrite count_occ_app ; lia.
+    apply IHn in H. repeat rewrite replace_app in H. simpl in H. repeat rewrite n_imp_subformLF_dist_app.
+    simpl. repeat rewrite n_imp_subformLF_dist_app in H. simpl in H.
+    assert ((n_imp_subformLF (replace (A --> B) B x) + (n_imp_subformF B + n_imp_subformLF (replace (A --> B) B x0)))%nat =
+    (n_imp_subformF B + ((n_imp_subformLF (replace (A --> B) B x) + n_imp_subformLF (replace (A --> B) B x0))))%nat). lia.
+    rewrite H0. clear H0. rewrite H. simpl.
+    assert ((n_imp_subformLF x + S (n_imp_subformF A + n_imp_subformF B + n_imp_subformLF x0) - S (n_imp_subformF A + n * S (n_imp_subformF A)))%nat =
+    ((n_imp_subformLF x + n_imp_subformF A + n_imp_subformF B + n_imp_subformLF x0) - (n_imp_subformF A + n * S (n_imp_subformF A)))%nat).
+    lia. rewrite H0. clear H0. rewrite Nat.sub_add_distr.
+    assert ((n * S (n_imp_subformF A))%nat <= (n_imp_subformLF x + n_imp_subformLF x0)%nat).
+    assert (n = (count_occ eq_dec_form x (A --> B) + (count_occ eq_dec_form x0 (A --> B)))%nat). lia.
+    rewrite H0. pose (count_occ_n_imp_subformLF (x ++ x0) A B). rewrite n_imp_subformLF_dist_app in l.
+    rewrite count_occ_app in l. lia. lia.
+  Qed.
+ +
+  Lemma univ_gen_ext_more_occ : forall l0 l1 A, univ_gen_ext (fun x : MPropF => x = A) l0 l1 ->
+          (count_occ eq_dec_form l0 A) <= (count_occ eq_dec_form l1 A).
+  Proof.
+  intros. induction X ; simpl ; auto ; subst.
+  - destruct (eq_dec_form x A) ; subst ; lia.
+  - destruct (eq_dec_form A A) ; auto.
+  Qed.
+ +
+  Lemma univ_gen_ext_n_imp_subform : forall l0 l1 A, univ_gen_ext (fun x : MPropF => x = A) l0 l1->
+                 (n_imp_subformLF l1 = (n_imp_subformLF l0 + (n_imp_subformF A * ((count_occ eq_dec_form l1 A) - (count_occ eq_dec_form l0 A))))%nat).
+  Proof.
+  intros. induction X ; simpl ; auto ; subst.
+  - destruct (eq_dec_form x A) ; subst ; lia.
+  - destruct (eq_dec_form A A). 2: exfalso ; auto. rewrite IHX. apply univ_gen_ext_more_occ in X.
+    assert ((S (count_occ eq_dec_form le A) - count_occ eq_dec_form l A)%nat = S ((count_occ eq_dec_form le A) - count_occ eq_dec_form l A)).
+    lia. rewrite H. lia.
+  Qed.
+ +
+  Lemma n_imp_subformS_ImpR_mult : forall x Γ0 Γ1 Δ0 Δ1 A B,
+                              (univ_gen_ext (fun x : MPropF => x = A) (Γ0 ++ A :: Γ1) x) ->
+          ((count_occ eq_dec_form (Δ0 ++ B :: Δ1) (A --> B) + count_occ eq_dec_form (Γ0 ++ A :: Γ1) A)%nat = count_occ eq_dec_form x A) ->
+          (n_imp_subformS (x, replace (A --> B) B (Δ0 ++ B :: Δ1)) < n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1)).
+  Proof.
+  intros. remember (count_occ eq_dec_form (Δ0 ++ B :: Δ1) (A --> B)) as n. revert H. revert Heqn. revert X.
+  generalize dependent B. generalize dependent A. generalize dependent Δ1. generalize dependent Δ0.
+  generalize dependent Γ1. generalize dependent Γ0. generalize dependent x. induction n.
+  - simpl. intros. symmetry in Heqn. rewrite <- count_occ_not_In in Heqn. rewrite notin_replace ; auto.
+    repeat rewrite count_occ_app in H. simpl in H. destruct (eq_dec_form A A). 2: exfalso ; auto.
+    unfold n_imp_subformS ; simpl. repeat rewrite n_imp_subformLF_dist_app ; simpl.
+    assert (n_imp_subformLF x = (n_imp_subformLF Γ0 + n_imp_subformLF Γ1 + n_imp_subformF A)%nat).
+    pose (univ_gen_ext_n_imp_subform _ _ _ X). rewrite e0. repeat rewrite count_occ_app. simpl.
+    destruct (eq_dec_form A A). 2: exfalso ; auto. repeat rewrite n_imp_subformLF_dist_app ; simpl. lia.
+    lia.
+  - intros. repeat rewrite replace_app. simpl. repeat rewrite count_occ_app in H. simpl in H. destruct (eq_dec_form A A). 2: exfalso ; auto.
+    destruct (eq_dec_form (A --> B) B). exfalso. assert (length_form (A --> B) = length_form B).
+    rewrite e0 ; auto. simpl in H0 ; lia. repeat rewrite count_occ_app in Heqn. simpl in Heqn.
+    destruct (eq_dec_form B (A --> B)). exfalso. assert (length_form (A --> B) = length_form B).
+    rewrite <- e0 ; auto. simpl in H0 ; lia.
+    unfold n_imp_subformS ; simpl. repeat rewrite n_imp_subformLF_dist_app ; simpl.
+    assert (n_imp_subformLF x = (n_imp_subformLF Γ0 + n_imp_subformLF Γ1 + (n_imp_subformF A * S (S n)))%nat).
+    pose (univ_gen_ext_n_imp_subform _ _ _ X). rewrite e0. repeat rewrite count_occ_app. simpl.
+    destruct (eq_dec_form A A). 2: exfalso ; auto. repeat rewrite n_imp_subformLF_dist_app ; simpl. lia.
+    rewrite H0.
+    pose (n_imp_subformLF_replace Δ0 A B). rewrite e0. clear e0.
+    pose (n_imp_subformLF_replace Δ1 A B). rewrite e0. clear e0.
+    pose (count_occ_n_imp_subformLF Δ0 A B).
+    pose (count_occ_n_imp_subformLF Δ1 A B). lia.
+Qed.
+ +
+  (* This lemma is crucial. *)
+ +
+  Lemma mult_ImpR : forall s0 s1 A B,
+          InT s1 (Canopy (repeat A (count_occ eq_dec_form (snd s0) (A --> B)) ++ (fst s0), replace (A --> B) B (snd s0))) ->
+          InT s1 (Canopy s0).
+  Proof.
+  intros s0 s1 A B. remember (count_occ eq_dec_form (snd s0) (A --> B)) as n. revert Heqn. generalize dependent B.
+  generalize dependent A. generalize dependent s1. generalize dependent s0. induction n ; simpl ; intros.
+  - symmetry in Heqn. rewrite <- count_occ_not_In in Heqn. rewrite notin_replace in H ; auto. destruct s0 ; auto.
+  - assert (count_occ eq_dec_form (snd s0) (A --> B) > 0). lia. apply count_occ_In in H0. destruct s0. simpl in H0.
+    simpl in H. simpl in Heqn. apply In_InT in H0. apply InT_split in H0. destruct H0. destruct s ; subst.
+    repeat rewrite count_occ_app in Heqn. simpl in Heqn. repeat rewrite replace_app in H.
+    simpl in H. destruct (eq_dec_form (A --> B) (A --> B)). 2: exfalso ; auto.
+    assert (n = count_occ eq_dec_form (x ++ x0) (A --> B)). repeat rewrite count_occ_app ; lia.
+    pose (IHn (A :: l, x ++ B :: x0) s1 A B). simpl in i.
+    repeat rewrite count_occ_app in i. simpl in i. repeat rewrite replace_app in i.
+    simpl in i. destruct (eq_dec_form B (A --> B)). exfalso. assert (length_form (A --> B) = length_form B). rewrite <- e0 ; auto.
+    simpl in H1 ; lia. destruct (eq_dec_form (A --> B) B). exfalso. assert (length_form (A --> B) = length_form B). rewrite e0 ; auto.
+    simpl in H1 ; lia. repeat rewrite count_occ_app in H0. pose (i H0).
+    assert (repeat A n ++ A :: l = A :: repeat A n ++ l). assert (repeat A n ++ A :: l = (repeat A n ++ [A]) ++ l).
+    rewrite <- app_assoc. auto. rewrite H1. rewrite <- repeat_cons. simpl ; auto. rewrite H1 in i0. apply i0 in H.
+    apply ImpRule_Canopy with (prems:=[(A :: l, x ++ B :: x0)]) (prem:=(A :: l, x ++ B :: x0)) ; auto.
+     left. epose (ImpRRule_I _ _ []). simpl in i1 ; apply i1. apply InT_eq.
+  Qed.
+ +
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_Canopy_nodupseq_perm.html b/GL.Interpolation.UIGL_Canopy_nodupseq_perm.html new file mode 100644 index 0000000..2c5c1e3 --- /dev/null +++ b/GL.Interpolation.UIGL_Canopy_nodupseq_perm.html @@ -0,0 +1,405 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_Canopy_nodupseq_perm

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat.
+Require Import Lia.
+ +
+Require Import general_export.
+ +
+Require Import GLS_export.
+ +
+Require Import UIGL_Def_measure.
+Require Import UIGL_Canopy.
+Require Import UIGL_irred_short.
+Require Import UIGL_braga.
+Require Import UIGL_LexSeq.
+Require Import UIGL_PermutationT.
+Require Import UIGL_PermutationTS.
+Require Import UIGL_nodupseq.
+Require Import UIGL_Canopy_ImpR.
+Require Import UIGL_Canopy_ImpL.
+ +
+Lemma nodup_length : forall l0 l1, length (nodup eq_dec_form l0) <= length (nodup eq_dec_form (l1 ++ l0)).
+Proof.
+intros l0 l1. revert l0. induction l1 ; intros ; simpl ; auto.
+destruct (in_dec eq_dec_form a (l1 ++ l0)).
+- apply in_app_or in i. destruct i ; auto.
+- simpl. pose (IHl1 l0). lia.
+Qed.
+ +
+Lemma repeat_n_imp_subformLF: forall (n : nat) A, n_imp_subformLF (repeat A n) = (mult n (n_imp_subformF A)).
+Proof.
+induction n ; simpl ; intros ; auto.
+Qed.
+ +
+Lemma replace_n_imp_subformLF: forall l A B,
+    plus (mult (S (n_imp_subformF A)) (count_occ eq_dec_form l (A --> B))) (n_imp_subformLF (replace (A --> B) B l)) = n_imp_subformLF l.
+Proof.
+induction l ; simpl ; intros ; auto. lia.
+destruct (eq_dec_form a (A --> B)) ; subst ; simpl. destruct (eq_dec_form (A --> B) (A --> B)) ; simpl. pose (IHl A B). lia.
+exfalso ; apply n ; auto. destruct (eq_dec_form (A --> B) a) ; simpl. subst. exfalso ; apply n ; auto.
+pose (IHl A B). lia.
+Qed.
+ +
+Lemma repeat_S : forall n (A: MPropF)A, 0 < n -> (A :: (@repeat MPropF A (Init.Nat.pred n))) = repeat A n.
+Proof.
+induction n ; simpl ; intros ; auto. inversion H.
+Qed.
+ +
+Lemma Permutation_replace_repeat : forall l A B, Permutation (replace A B l) ((repeat B (count_occ eq_dec_form l A)) ++ remove eq_dec_form A l).
+Proof.
+induction l ; intros ; simpl ; auto. destruct (eq_dec_form A a) ; subst. destruct (eq_dec_form a a) ; subst.
+pose (IHl a B). simpl. apply perm_skip ; auto. exfalso ; apply n ; auto.
+destruct (eq_dec_form a A) ; subst ; simpl. exfalso ; apply n ; auto.
+pose (IHl a B). apply Permutation_cons_app ; auto.
+Qed.
+ +
+Lemma Permutation_repeat_extract : forall n l0 l1 l2 A B,
+  (0 < n) ->
+  ((count_occ eq_dec_form l0 A) = n) ->
+  (In A (l1 ++ B :: l2) -> False) ->
+  Permutation (remove eq_dec_form A l0) (l1 ++ l2) ->
+  Permutation (repeat B n ++ remove eq_dec_form A l0) ((repeat B (Init.Nat.pred n)) ++ l1 ++ B :: l2).
+Proof.
+induction n ; simpl ; auto.
+- intros. inversion H.
+- induction l0 ; simpl ; intros ; auto. exfalso ; lia.
+  destruct (eq_dec_form a A) ; subst.
+  + destruct (eq_dec_form A A) ; subst. inversion H0 ; subst.
+     apply perm_trans with (l':=(B :: repeat B (count_occ eq_dec_form l0 A) ++ l1 ++ l2)). apply perm_skip.
+     apply Permutation_app ; auto. pose (@Permutation_middle _ (repeat B (count_occ eq_dec_form l0 A) ++ l1) l2 B).
+     repeat rewrite <- app_assoc in p ; simpl in p. auto.
+     apply perm_trans with (l':=(B :: repeat B n ++ l1 ++ l2)). apply perm_skip.
+     apply Permutation_app ; auto. pose (@Permutation_middle _ (repeat B n ++ l1) l2 B).
+     repeat rewrite <- app_assoc in p ; simpl in p. auto.
+  + destruct (eq_dec_form A a) ; subst. exfalso ; apply n0 ; auto.
+     apply perm_trans with (l':=(B :: repeat B n ++ l1 ++ l2)). apply perm_skip.
+     apply Permutation_app ; auto. pose (@Permutation_middle _ (repeat B n ++ l1) l2 B).
+     repeat rewrite <- app_assoc in p ; simpl in p. auto.
+Qed.
+ +
+Lemma Permutation_remove : forall l0 l1 A, Permutation l0 l1 -> Permutation (remove eq_dec_form A l0) (remove eq_dec_form A l1).
+Proof.
+induction 1 ; simpl ; auto.
+- destruct (eq_dec_form A x) ; subst ; auto.
+- destruct (eq_dec_form A y) ; subst ; auto. destruct (eq_dec_form A x) ; subst ; auto.
+  apply perm_swap.
+- apply (perm_trans IHPermutation1 IHPermutation2).
+Qed.
+ +
+Lemma count_occ_n_imp_subformLF : forall l A, count_occ eq_dec_form l A * n_imp_subformF A <= n_imp_subformLF l.
+Proof.
+induction l ; simpl ; auto.
+intros. destruct (eq_dec_form a A) ; subst ; auto. pose (IHl A). lia.
+pose (IHl A) ; lia.
+Qed.
+ +
+Lemma remove_n_imp_subformLF : forall l A,
+        n_imp_subformLF (remove eq_dec_form A l) = minus (n_imp_subformLF l) (mult (count_occ eq_dec_form l A) (n_imp_subformF A)).
+Proof.
+induction l ; simpl ; auto ; intros.
+destruct (eq_dec_form A a) ; subst ; auto. destruct (eq_dec_form a a) ; subst ; auto.
+assert (n_imp_subformLF (remove eq_dec_form a l) = n_imp_subformLF l - count_occ eq_dec_form l a * n_imp_subformF a).
+apply IHl. destruct (count_occ eq_dec_form l a) ; lia. exfalso ; auto.
+destruct (eq_dec_form a A). exfalso ; auto.
+pose (IHl A). simpl. rewrite e.
+assert (count_occ eq_dec_form l A * n_imp_subformF A <= n_imp_subformLF l). apply count_occ_n_imp_subformLF.
+lia.
+Qed.
+ +
+Lemma remove_n_imp_subformLF_decomp : forall l A,
+        n_imp_subformLF l = plus (n_imp_subformLF (remove eq_dec_form A l)) (mult (count_occ eq_dec_form l A) (n_imp_subformF A)).
+Proof.
+induction l ; simpl ; intros ; auto.
+destruct (eq_dec_form A a) ; subst ; auto. destruct (eq_dec_form a a) ; subst ; auto. pose (IHl a).
+lia. exfalso ; auto. simpl. destruct (eq_dec_form a A). exfalso ; auto. simpl. pose (IHl A). lia.
+Qed.
+ +
+Lemma Permutation_replace : forall l0 l1 A B, Permutation l0 l1 -> Permutation (replace A B l0) (replace A B l1).
+Proof. intros. apply Permutation_map. assumption. Qed.
+ +
+Lemma Canopy_nodupseq_perm_gen : forall s0 s1 leaf1,
+        (existsT2 l0 l1, (PermutationTS s0 (l0 ++ fst s1, l1 ++ snd s1)) * (incl l0 (fst s1)) * (incl l1 (snd s1))) ->
+        (InT leaf1 (Canopy s1)) ->
+        (existsT2 leaf0, InT leaf0 (Canopy s0) * (PermutationTS (nodupseq leaf0) (nodupseq leaf1))).
+Proof.
+  intros s ; induction on s as IH with measure (n_imp_subformS s).
+  intros s1 leaf1 perm InClos. destruct perm. destruct s0. destruct p. destruct p.
+  pose (fold_Canopy _ _ InClos). destruct s0 ; subst ; auto.
+  - exists s. split ; auto. apply Canopy_critical in InClos. apply critical_Seq_InT_Canopy.
+    apply PermutationTS_sym in p. apply (PermutationTS_critic _ _ p). intros A HA ; simpl in HA.
+    apply InClos. apply in_or_app. apply in_app_or in HA ; destruct HA. 1-2: apply in_app_or in H ; destruct H ; auto.
+    split ; apply Permutation_PermutationT ; destruct p ; apply Permutation_PermutationT in p,p0 ; simpl in p,p0 ; unfold nodupseq ; simpl.
+    apply perm_trans with (l':=(nodup eq_dec_form (x ++ fst s1))).
+    apply Permutation_PermutationT ; apply PermutationT_nodupseq ; apply Permutation_PermutationT ; auto.
+    apply (@NoDup_Permutation_bis _ (nodup eq_dec_form (x ++ fst s1)) (nodup eq_dec_form (fst s1))). apply NoDup_nodup.
+    apply nodup_length. intros A HA. apply nodup_In. apply (nodup_In) in HA. apply in_app_or in HA ; destruct HA ; auto.
+    apply perm_trans with (l':=(nodup eq_dec_form (x0 ++ snd s1))).
+    apply Permutation_PermutationT ; apply PermutationT_nodupseq ; apply Permutation_PermutationT ; auto.
+    apply (@NoDup_Permutation_bis _ (nodup eq_dec_form (x0 ++ snd s1)) (nodup eq_dec_form (snd s1))). apply NoDup_nodup.
+    apply nodup_length. intros A HA. apply nodup_In. apply (nodup_In) in HA. apply in_app_or in HA ; destruct HA ; auto.
+  - destruct s0. destruct p0. unfold inv_prems in i1. apply InT_flatten_list_InT_elem in i1. destruct i1.
+    destruct p0. destruct (finite_ImpRules_premises_of_S s1). simpl in i3.
+    apply p0 in i3. destruct i3 ; inversion i3 ; subst.
+    (* x0 is obtained via ImpR. *)
+    + inversion i1 ; subst. 2: inversion H0. simpl in *.
+       assert (InT (A --> B) (snd s)). apply In_InT. destruct p. apply Permutation_PermutationT in p1 ; simpl in p1.
+       apply Permutation_in with (l:=(x0 ++ Δ0 ++ A --> B :: Δ1)). apply Permutation_sym ; auto.
+       apply in_or_app ; right ; apply in_or_app ; right ; simpl ; auto. apply InT_split in H. destruct H. destruct s0.
+       destruct s ; simpl in * ; rewrite e in * ; clear e. inversion p ; simpl in *.
+       destruct (In_dec x0 (A --> B)).
+       * destruct (In_dec (Δ0 ++ Δ1) (A --> B)).
+         -- assert (J1: n_imp_subformS (A :: l, x1 ++ B :: x2) < n_imp_subformS (l, x1 ++ A --> B :: x2)).
+            unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl. lia.
+            pose (IH _ J1 (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) leaf1). simpl in s. destruct s ; simpl ; auto.
+            exists x. clear p0. exists x0. repeat split ; auto ; simpl. apply Permutation_PermutationT.
+            apply perm_trans with (l':=(A :: x ++ Γ0 ++ Γ1)). apply perm_skip. apply Permutation_PermutationT ; auto.
+            pose (Permutation_middle (x ++ Γ0) Γ1 A). repeat rewrite <- app_assoc in p0 ; simpl in p0 ; auto. apply Permutation_PermutationT.
+            apply perm_trans with (l':=(B :: x0 ++ Δ0 ++ Δ1)). apply perm_trans with (l':=(B :: x1 ++ x2)) ; auto.
+            2: apply perm_skip. apply Permutation_sym ; apply Permutation_cons_app ; apply Permutation_refl. apply Permutation_PermutationT in H0.
+            epose (@Permutation_cons_app_inv _ _ (x0 ++ Δ0) Δ1 (A --> B)). repeat rewrite <- app_assoc in p0 ; simpl in p0. apply p0.
+            apply perm_trans with (l':=(x1 ++ A --> B :: x2)) ; auto. apply Permutation_cons_app ; apply Permutation_refl.
+            epose (@Permutation_cons_app _ _ (x0 ++ Δ0) Δ1 B). repeat rewrite <- app_assoc in p0 ; simpl in p0. apply p0 ; apply Permutation_refl.
+            intros C HC. apply in_or_app. apply i0 in HC. simpl. apply in_app_or in HC ; destruct HC ; auto.
+            intros C HC. apply in_or_app ; simpl. pose (i _ HC). apply in_app_or in i6 ; destruct i6 ; auto. inversion H1 ; subst ; auto.
+            apply in_app_or in i5 ; destruct i5 ; auto.
+            destruct p1. exists x4 ; split ; auto. eapply ImpRule_Canopy. left. apply (ImpRRule_I A B [] l x1 x2).
+            simpl. apply InT_eq. auto.
+         -- assert (J1: n_imp_subformS (repeat A (count_occ eq_dec_form (x1 ++ A --> B :: x2) (A --> B)) ++ l, replace (A --> B) B (x1 ++ A --> B :: x2)) < n_imp_subformS (l, x1 ++ A --> B :: x2)).
+            unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl. rewrite repeat_n_imp_subformLF.
+            pose (replace_n_imp_subformLF (x1 ++ A --> B :: x2) A B). repeat rewrite n_imp_subformLF_dist_app in e ; simpl in e. rewrite <- e.
+            assert (0 < count_occ eq_dec_form (x1 ++ A --> B :: x2) (A --> B)). apply count_occ_In. apply in_or_app ; right ; simpl ; auto. lia.
+            pose (IH _ J1 (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) leaf1). simpl in s. destruct s ; simpl ; auto.
+            exists (repeat A (pred (count_occ eq_dec_form (x1 ++ A --> B :: x2) (A --> B))) ++ x). clear p0.
+            exists (repeat B (pred (count_occ eq_dec_form (x1 ++ A --> B :: x2) (A --> B))) ++ (remove eq_dec_form (A --> B) x0)).
+            repeat split ; auto ; simpl. apply Permutation_PermutationT. repeat rewrite <- app_assoc.
+            apply perm_trans with (l':=(repeat A (count_occ eq_dec_form (x1 ++ A --> B :: x2) (A --> B)) ++ x ++ Γ0 ++ Γ1)).
+            apply Permutation_app_head. apply Permutation_PermutationT ; auto.
+            apply perm_trans with (l':=(A :: repeat A (Init.Nat.pred (count_occ eq_dec_form (x1 ++ A --> B :: x2) (A --> B))) ++ x ++ Γ0 ++ Γ1)).
+            assert (A :: repeat A (Init.Nat.pred (count_occ eq_dec_form (x1 ++ A --> B :: x2) (A --> B))) = repeat A (count_occ eq_dec_form (x1 ++ A --> B :: x2) (A --> B))).
+            apply repeat_S ; auto. apply count_occ_In. apply in_or_app ; right ; simpl ; auto.
+            rewrite <- H1. simpl. apply perm_skip. apply Permutation_app_head. apply Permutation_refl.
+            epose (@Permutation_cons_app _ _ (repeat A (Init.Nat.pred (count_occ eq_dec_form (x1 ++ A --> B :: x2) (A --> B))) ++ x ++ Γ0) Γ1 A).
+            repeat rewrite <- app_assoc in p0 ; apply p0 ; clear p0. apply Permutation_refl.
+            apply Permutation_PermutationT. pose (Permutation_replace_repeat (x1 ++ A --> B :: x2) (A --> B) B).
+            apply perm_trans with (l':=(repeat B (count_occ eq_dec_form (x1 ++ A --> B :: x2) (A --> B)) ++ remove eq_dec_form (A --> B) (x1 ++ A --> B :: x2))) ; auto.
+            assert (J20: 0 < count_occ eq_dec_form (x1 ++ A --> B :: x2) (A --> B)). apply count_occ_In. apply in_or_app ; right ; simpl ; auto.
+            assert (J21: (In (A --> B) ((remove eq_dec_form (A --> B) x0 ++ Δ0) ++ B :: Δ1) -> False)).
+            intros. apply in_app_or in H1 ; destruct H1. apply in_app_or in H1 ; destruct H1. apply remove_not_in_anymore in H1 ; auto.
+            apply n ; apply in_or_app ; auto. inversion H1. assert (size B = size (A --> B)). rewrite <- H2 ; auto. simpl in H3 ; lia.
+            apply n ; apply in_or_app ; auto. assert (J43: count_occ eq_dec_form (x1 ++ A --> B :: x2) (A --> B) = count_occ eq_dec_form (x1 ++ A --> B :: x2) (A --> B)) ; auto.
+            pose (Permutation_repeat_extract _ (x1 ++ A --> B :: x2) _ _ (A --> B) B J20 J43 J21).
+            repeat rewrite <- app_assoc ; simpl. repeat rewrite <- app_assoc in p1 ; simpl in p1. apply p1 ; clear p1.
+            assert ((remove eq_dec_form (A --> B) x0 ++ Δ0 ++ Δ1) = (remove eq_dec_form (A --> B) (x0 ++ Δ0 ++ A --> B :: Δ1))).
+            repeat rewrite remove_app. simpl. destruct (eq_dec_form (A --> B) (A --> B)). pose (notin_remove eq_dec_form Δ0).
+            pose (notin_remove eq_dec_form Δ1). rewrite e0. rewrite e1 ; auto. 1-2: intro ; apply n ; apply in_or_app ; auto.
+            exfalso ; apply n0 ; auto. rewrite H1. apply Permutation_remove ; apply Permutation_PermutationT in H0 ; auto.
+            intros C HC. apply in_or_app. apply in_app_or in HC ; destruct HC. right. simpl. apply repeat_spec in H1 ; auto.
+            apply i0 in H1. simpl. apply in_app_or in H1 ; destruct H1 ; auto.
+            intros C HC. apply in_or_app ; simpl. apply in_app_or in HC ; destruct HC. right. apply repeat_spec in H1 ; auto.
+            apply in_remove in H1. destruct H1. pose (i _ H1). apply in_app_or in i5 ; destruct i5 ; auto. inversion H3 ; subst ; auto.
+            exfalso ; auto.
+            destruct p1. exists x4 ; split ; auto. apply (mult_ImpR _ _ A B) ; auto.
+       * assert (J1: n_imp_subformS (A :: l, x1 ++ B :: x2) < n_imp_subformS (l, x1 ++ A --> B :: x2)).
+         unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl. lia.
+         pose (IH _ J1 (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) leaf1). simpl in s. destruct s ; simpl ; auto.
+         exists x. clear p0. exists x0. repeat split ; auto ; simpl. apply Permutation_PermutationT.
+         apply perm_trans with (l':=(A :: x ++ Γ0 ++ Γ1)). apply perm_skip. apply Permutation_PermutationT ; auto.
+         pose (Permutation_middle (x ++ Γ0) Γ1 A). repeat rewrite <- app_assoc in p0 ; simpl in p0 ; auto. apply Permutation_PermutationT.
+         apply perm_trans with (l':=(B :: x0 ++ Δ0 ++ Δ1)). apply perm_trans with (l':=(B :: x1 ++ x2)) ; auto.
+         2: apply perm_skip. apply Permutation_sym ; apply Permutation_cons_app ; apply Permutation_refl. apply Permutation_PermutationT in H0.
+         epose (@Permutation_cons_app_inv _ _ (x0 ++ Δ0) Δ1 (A --> B)). repeat rewrite <- app_assoc in p0 ; simpl in p0. apply p0.
+         apply perm_trans with (l':=(x1 ++ A --> B :: x2)) ; auto. apply Permutation_cons_app ; apply Permutation_refl.
+         epose (@Permutation_cons_app _ _ (x0 ++ Δ0) Δ1 B). repeat rewrite <- app_assoc in p0 ; simpl in p0. apply p0 ; apply Permutation_refl.
+         intros C HC. apply in_or_app. apply i0 in HC. simpl. apply in_app_or in HC ; destruct HC ; auto.
+         intros C HC. apply in_or_app ; simpl. pose (i _ HC). apply in_app_or in i4 ; destruct i4 ; auto. inversion H1 ; subst ; auto.
+         exfalso ; auto.
+         destruct p1. exists x4 ; split ; auto. eapply ImpRule_Canopy. left. apply (ImpRRule_I A B [] l x1 x2).
+         simpl. apply InT_eq. auto.
+    (* x0 is obtained via ImpL. *)
+    + subst. inversion p. simpl in *.
+       assert (InT (A --> B) (fst s)). apply In_InT. apply Permutation_PermutationT in H.
+       apply Permutation_in with (l:=(x ++ Γ0 ++ A --> B :: Γ1)). apply Permutation_sym ; auto.
+       apply in_or_app ; right ; apply in_or_app ; right ; simpl ; auto. apply InT_split in H1. destruct H1. destruct s0.
+       destruct s ; simpl in * ; rewrite e in * ; clear e. inversion i1 ; subst. 2: inversion H2 ; subst ; simpl in *. 3: inversion H3.
+     (* Left premise. *)
+     { destruct (In_dec x (A --> B)).
+       * destruct (In_dec (Γ0 ++ Γ1) (A --> B)).
+         -- assert (J1: n_imp_subformS (x2 ++ x4, A :: l0) < n_imp_subformS (x2 ++ A --> B :: x4, l0)).
+            unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+            pose (IH _ J1 (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) leaf1). simpl in s. destruct s ; simpl ; auto.
+            exists x. clear p0. exists x0. repeat split ; auto ; simpl. 1-2: apply Permutation_PermutationT.
+            pose (@Permutation_app_inv _ x2 x4 (x ++ Γ0) Γ1 (A --> B)). repeat rewrite <- app_assoc in p0.
+            apply p0 ; apply Permutation_PermutationT ; auto.
+            apply perm_trans with (l':=(A :: x0 ++ Δ0 ++ Δ1)). apply perm_skip. apply Permutation_PermutationT ; auto.
+            pose (Permutation_middle (x0 ++ Δ0) Δ1 A). repeat rewrite <- app_assoc in p0 ; simpl in p0 ; auto.
+            intros C HC. apply in_or_app ; simpl. pose (i0 _ HC). apply in_app_or in i6 ; destruct i6 ; auto. inversion H1 ; subst ; auto.
+            apply in_app_or in i5 ; destruct i5 ; auto.
+            intros C HC. apply in_or_app. apply i in HC. simpl. apply in_app_or in HC ; destruct HC ; auto.
+            destruct p1. exists x1 ; split ; auto. eapply ImpRule_Canopy. right. apply (ImpLRule_I A B x2 x4 [] l0).
+            simpl. apply InT_eq. auto.
+         -- assert (J1: n_imp_subformS (remove eq_dec_form (A --> B) (x2 ++ x4), repeat A (count_occ eq_dec_form (x2 ++ A --> B :: x4) (A --> B)) ++ l0) < n_imp_subformS (x2 ++ A --> B :: x4, l0)).
+            unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl. rewrite repeat_n_imp_subformLF.
+            assert (0 < count_occ eq_dec_form (x2 ++ A --> B :: x4) (A --> B)). apply count_occ_In. apply in_or_app ; right ; simpl ; auto.
+            pose (remove_n_imp_subformLF_decomp (x2 ++ A --> B :: x4) (A --> B)). rewrite n_imp_subformLF_dist_app in e ; simpl in e.
+            assert (n_imp_subformLF (remove eq_dec_form (A --> B) (x2 ++ x4)) + (count_occ eq_dec_form (x2 ++ A --> B :: x4) (A --> B) * n_imp_subformF A + n_imp_subformLF l0) <
+            n_imp_subformLF l0 + (n_imp_subformLF x2 + S (n_imp_subformF A + n_imp_subformF B + n_imp_subformLF x4))).
+            rewrite e. repeat rewrite remove_app. simpl. destruct (eq_dec_form (A --> B) (A --> B)). lia. exfalso ; apply n0 ; auto. lia.
+            pose (IH _ J1 (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) leaf1). simpl in s. destruct s ; simpl ; auto.
+            exists (remove eq_dec_form (A --> B) x). clear p0.
+            exists (repeat A (pred (count_occ eq_dec_form (x2 ++ A --> B :: x4) (A --> B))) ++ x0).
+            repeat split ; auto ; simpl. 1-2: apply Permutation_PermutationT.
+            pose (Permutation_remove (x2 ++ x4) (x ++ Γ0 ++ Γ1) (A --> B)).
+            assert (remove eq_dec_form (A --> B) x ++ Γ0 ++ Γ1 = remove eq_dec_form (A --> B) (x ++ Γ0 ++ Γ1)).
+            repeat rewrite remove_app. pose (notin_remove eq_dec_form Γ0). pose (notin_remove eq_dec_form Γ1).
+            rewrite e. rewrite e0 ; auto. 1-2: intro ; apply n ; apply in_or_app ; auto. rewrite H1. apply p0.
+            epose (Permutation_app_inv x2 x4 (x ++ Γ0) Γ1 (A --> B)). repeat rewrite <- app_assoc in p1. apply p1 ; apply Permutation_PermutationT ; auto.
+            apply perm_trans with (l':=((A :: repeat A (Init.Nat.pred (count_occ eq_dec_form (x2 ++ A --> B :: x4) (A --> B))) ++ x0) ++ Δ0 ++ Δ1)).
+            assert (A :: repeat A (Init.Nat.pred (count_occ eq_dec_form (x2 ++ A --> B :: x4) (A --> B))) = repeat A (count_occ eq_dec_form (x2 ++ A --> B :: x4) (A --> B))).
+            remember (count_occ eq_dec_form (x2 ++ A --> B :: x4) (A --> B)) as n' ; destruct n' ; auto ; simpl. exfalso. symmetry in Heqn' ; apply count_occ_not_In in Heqn'.
+            apply Heqn'. apply in_or_app ; simpl ; auto. rewrite <- H1. simpl. apply perm_skip. repeat rewrite <- app_assoc ; simpl.
+            apply Permutation_app_head ; apply Permutation_PermutationT ; auto.
+            epose (@Permutation_cons_app _ ((repeat A (Init.Nat.pred (count_occ eq_dec_form (x2 ++ A --> B :: x4) (A --> B))) ++ x0) ++ Δ0 ++ Δ1)
+            (repeat A (Init.Nat.pred (count_occ eq_dec_form (x2 ++ A --> B :: x4) (A --> B))) ++ x0 ++ Δ0) Δ1 A).
+            simpl ; repeat rewrite <- app_assoc ; simpl in p0 ; repeat rewrite <- app_assoc in p0. apply p0 ; clear p0. apply Permutation_refl.
+            intros C HC. apply in_or_app. apply in_remove in HC. destruct HC. apply i0 in H1. apply in_app_or in H1 ; destruct H1 ; auto.
+            inversion H1 ; [ exfalso ; subst ; apply H2 ; auto | auto].
+            intros C HC. apply in_or_app ; simpl. apply in_app_or in HC ; destruct HC. right. apply repeat_spec in H1 ; auto.
+            pose (i _ H1). apply in_app_or in i5 ; destruct i5 ; auto.
+            destruct p1. exists x1 ; split ; auto. apply (mult_ImpL_L _ _ A B) ; simpl ; auto.
+            assert (remove eq_dec_form (A --> B) (x2 ++ A --> B :: x4) = remove eq_dec_form (A --> B) (x2 ++ x4)).
+            repeat rewrite remove_app. simpl. destruct (eq_dec_form (A --> B) (A --> B)) ; auto. exfalso ; auto. rewrite H1 ; auto.
+       * assert (J1: n_imp_subformS (x2 ++ x4, A :: l0) < n_imp_subformS (x2 ++ A --> B :: x4, l0)).
+         unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl. lia.
+         pose (IH _ J1 (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) leaf1). simpl in s. destruct s ; simpl ; auto.
+        exists x. clear p0. exists x0. repeat split ; auto ; simpl. 1-2: apply Permutation_PermutationT.
+        pose (@Permutation_app_inv _ x2 x4 (x ++ Γ0) Γ1 (A --> B)). repeat rewrite <- app_assoc in p0.
+        apply p0 ; apply Permutation_PermutationT ; auto.
+        apply perm_trans with (l':=(A :: x0 ++ Δ0 ++ Δ1)). apply perm_skip. apply Permutation_PermutationT ; auto.
+        pose (Permutation_middle (x0 ++ Δ0) Δ1 A). repeat rewrite <- app_assoc in p0 ; simpl in p0 ; auto.
+        intros C HC. apply in_or_app ; simpl. pose (i0 _ HC). apply in_app_or in i4 ; destruct i4 ; auto. inversion H1 ; subst ; auto.
+        exfalso ; auto.
+        intros C HC. apply in_or_app. apply i in HC. simpl. apply in_app_or in HC ; destruct HC ; auto.
+        destruct p1. exists x1 ; split ; auto. eapply ImpRule_Canopy. right. apply (ImpLRule_I A B x2 x4 [] l0).
+        simpl. apply InT_eq. auto. }
+     (* Right premise. *)
+     { destruct (In_dec x (A --> B)).
+       * destruct (In_dec (Γ0 ++ Γ1) (A --> B)).
+         -- assert (J1: n_imp_subformS (x2 ++ B :: x4, l0) < n_imp_subformS (x2 ++ A --> B :: x4, l0)).
+            unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+            pose (IH _ J1 (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) leaf1). simpl in s. destruct s ; simpl ; auto.
+            exists x. clear p0. exists x0. repeat split ; auto ; simpl. apply Permutation_PermutationT.
+            pose (@Permutation_app_inv _ x2 x4 (x ++ Γ0) Γ1 (A --> B)). repeat rewrite <- app_assoc in p0.
+            pose (Permutation_elt x2 x4 (x ++ Γ0) Γ1 B). repeat rewrite <- app_assoc in p1. apply p1.
+            apply p0. apply Permutation_PermutationT ; auto.
+            intros C HC. apply in_or_app ; simpl. pose (i0 _ HC). apply in_app_or in i6 ; destruct i6 ; auto. inversion H1 ; subst ; auto.
+            apply in_app_or in i5 ; destruct i5 ; auto.
+            destruct p1. exists x1 ; split ; auto. eapply ImpRule_Canopy. right. apply (ImpLRule_I A B x2 x4 [] l0).
+            simpl. apply InT_cons ; apply InT_eq. auto.
+         -- assert (J1: n_imp_subformS (replace (A --> B) B (x2 ++ A --> B :: x4), l0) < n_imp_subformS (x2 ++ A --> B :: x4, l0)).
+            unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl.
+            pose (replace_n_imp_subformLF (x2 ++ A --> B :: x4) A B). repeat rewrite n_imp_subformLF_dist_app in e. simpl in e.
+            repeat rewrite replace_app. simpl. repeat rewrite replace_app in e. simpl in e. destruct (eq_dec_form (A --> B) (A --> B)).
+            2: exfalso ; auto.
+            assert (0 < count_occ eq_dec_form (x2 ++ A --> B :: x4) (A --> B)). apply count_occ_In. apply in_or_app ; right ; simpl ; auto.
+            lia.
+            pose (IH _ J1 (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) leaf1). simpl in s. destruct s ; simpl ; auto.
+            exists (replace (A --> B) B x). clear p0.
+            exists x0.
+            repeat split ; auto ; simpl. apply Permutation_PermutationT.
+            pose (Permutation_replace (x2 ++ A --> B :: x4) (x ++ Γ0 ++ A --> B :: Γ1) (A --> B) B).
+            assert (replace (A --> B) B x ++ Γ0 ++ B :: Γ1 = replace (A --> B) B (x ++ Γ0 ++ A --> B :: Γ1)).
+            repeat rewrite replace_app. simpl. destruct (eq_dec_form (A --> B) (A --> B)) ; auto. 2: exfalso ; auto.
+            pose (notin_replace Γ0). pose (notin_replace Γ1). rewrite e0. rewrite e1. auto.
+            1-2: intro ; apply n ; apply in_or_app ; auto. rewrite H1. apply p0 ; apply Permutation_PermutationT ; auto.
+            intros C HC. apply in_or_app. apply in_replace in HC. destruct HC. simpl ; destruct H1 ; auto.
+            apply i0 in H1. apply in_app_or in H1 ; destruct H1 ; auto.
+            inversion H1 ; [ exfalso ; subst ; auto | auto]. intro. assert (size (A --> B) = size B). rewrite H1 ; auto. simpl in H3 ; lia.
+            destruct p1. exists x1 ; split ; auto. apply (mult_ImpL_R _ _ A B) ; simpl ; auto.
+       * assert (J1: n_imp_subformS (x2 ++ B :: x4, l0) < n_imp_subformS (x2 ++ A --> B :: x4, l0)).
+         unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl. lia.
+         pose (IH _ J1 (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) leaf1). simpl in s. destruct s ; simpl ; auto.
+        exists x. clear p0. exists x0. repeat split ; auto ; simpl. apply Permutation_PermutationT.
+        pose (@Permutation_app_inv _ x2 x4 (x ++ Γ0) Γ1 (A --> B)). repeat rewrite <- app_assoc in p0.
+        pose (Permutation_elt x2 x4 (x ++ Γ0) Γ1 B). repeat rewrite <- app_assoc in p1. apply p1.
+        apply p0. apply Permutation_PermutationT ; auto.
+        intros C HC. apply in_or_app ; simpl. pose (i0 _ HC). apply in_app_or in i4 ; destruct i4 ; auto. inversion H1 ; subst ; auto.
+        exfalso ; auto.
+        destruct p1. exists x1 ; split ; auto. eapply ImpRule_Canopy. right. apply (ImpLRule_I A B x2 x4 [] l0).
+        simpl. apply InT_cons ; apply InT_eq. auto. }
+Qed.
+ +
+Lemma Canopy_nodupseq_perm : forall s leaf, InT leaf (Canopy (nodupseq s)) ->
+        (existsT2 s0, InT s0 (Canopy s) * (PermutationTS (nodupseq s0) (nodupseq leaf))).
+Proof.
+intros. pose (Canopy_nodupseq_perm_gen s (nodupseq s) leaf). apply s0 ; auto.
+destruct (nodupseq_id s). destruct p. destruct s1. destruct s1. destruct p0. destruct p0.
+exists x0 ; exists x1 ; repeat split ; auto ; simpl.
+- destruct p. destruct p0. apply Permutation_PermutationT in p,p0. simpl in p0.
+  apply Permutation_PermutationT. apply perm_trans with (l':=(x0 ++ fst x)) ; auto.
+  apply Permutation_app_head ; auto.
+- destruct p. destruct p0. apply Permutation_PermutationT in p2,p1. simpl in p2.
+  apply Permutation_PermutationT. apply perm_trans with (l':=(x1 ++ snd x)) ; auto.
+  apply Permutation_app_head ; auto.
+- intros A HA. destruct s ; simpl in *. destruct p. apply i0 in HA. apply Permutation_PermutationT in p.
+  simpl in p. apply Permutation_in with (l:= fst x) ; auto.
+- intros A HA. destruct s ; simpl in *. destruct p. apply i in HA. apply Permutation_PermutationT in p1.
+  simpl in p1. apply Permutation_in with (l:= snd x) ; auto.
+Qed.
+ +
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_Def_measure.html b/GL.Interpolation.UIGL_Def_measure.html new file mode 100644 index 0000000..9e26c6b --- /dev/null +++ b/GL.Interpolation.UIGL_Def_measure.html @@ -0,0 +1,163 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_Def_measure

+ +
+(* Modification of the following file. *)
+ +
+(**************************************************************)
+(*   Copyright Dominique Larchey-Wendling *                 *)
+(*                                                            *)
+(*                             * Affiliation LORIA -- CNRS  *)
+(**************************************************************)
+(*      This file is distributed under the terms of the       *)
+(*         CeCILL v2 FREER SOFTWARE LICENSE AGREEMENT         *)
+(**************************************************************)
+ +
+Require Import List Arith Wellfounded.
+Import ListNotations.
+ +
+Set Implicit Arguments.
+ +
+Section measure_rect.
+ +
+  Variable (X : Type) (m : X -> nat) (P : X -> Type).
+ +
+  Hypothesis F : forall x, (forall y, m y < m x -> P y) -> P x.
+ +
+  Definition measure_rect x : P x.
+  Proof.
+    cut (Acc (fun x y => m x < m y) x); [ revert x | ].
+    + refine (
+        fix loop x Dx := @F x (fun y Dy => loop y _)
+      ).
+      apply (Acc_inv Dx), Dy.
+    + apply wf_inverse_image with (f := m), lt_wf.
+  Qed.
+ +
+End measure_rect.
+ +
+Tactic Notation "induction" "on" hyp(x) "as" ident(IH) "with" "measure" uconstr(f) :=
+  pattern x; revert x; apply measure_rect with (m := fun x => f); intros x IH.
+ +
+Section lex_wf.
+ +
+  Variable (X : Type) (R : X -> X -> Prop) (Rwf : well_founded R).
+ +
+  Reserved Notation "l '<lex' m" (at level 70). (* for lexicographic product *)
+ +
+  Inductive lex : list X -> list X -> Prop :=
+    | lex_skip x l m : l <lex m -> x::l <lex x::m
+    | lex_cons x y l m : length l = length m -> R x y -> x::l <lex y::m
+  where "l <lex m" := (lex l m).
+ +
+  Fact lex_length l m : l <lex m -> length l = length m.
+  Proof. induction 1; simpl; auto. Qed.
+ +
+  Fact lex_cons_inv l m :
+          l <lex m
+       -> match m with
+            | [] => False
+            | y::m =>
+            match l with
+              | [] => False
+              | x::l => x = y /\ lex l m
+                     \/ R x y /\ length l = length m
+            end
+          end.
+  Proof. inversion 1; auto. Qed.
+ +
+  Theorem lex_wf : well_founded lex.
+  Proof.
+    intros m; induction on m as IHm with measure (length m).
+    destruct m as [ | y m ].
+    + constructor; intros l Hl; apply lex_cons_inv in Hl; easy.
+    + revert m IHm.
+      induction y as [ y IHy' ] using (well_founded_induction Rwf).
+      intros m IHm.
+      assert (Acc lex m) as Hm.
+      1: apply IHm; simpl; auto.
+      assert (forall x l, R x y -> length l = length m -> Acc lex (x::l)) as IHy.
+      1: { intros x l Hx Hl; apply IHy'; auto.
+           intros; apply IHm.
+           simpl in *; rewrite <- Hl; auto. }
+      clear IHy' IHm.
+      revert Hm IHy.
+      induction 1 as [ m Hm IHm ]; intros IHy.
+      constructor; intros l Hl; apply lex_cons_inv in Hl.
+      destruct l as [ | x l ]; try tauto.
+      destruct Hl as [ (-> & Hl) | (Hx & Hl) ].
+      * apply IHm; auto.
+        apply lex_length in Hl as ->; auto.
+      * apply IHy; auto.
+  Qed.
+ +
+  Section lex_rect.
+ +
+    Variable (P : list X -> Type) (HP : forall m, (forall l, lex l m -> P l) -> P m).
+ +
+    Corollary lex_rect m : P m.
+    Proof.
+      induction m as [ m IHm ] using (well_founded_induction_type lex_wf).
+      apply HP; intros; apply IHm. auto.
+    Qed.
+ +
+  End lex_rect.
+ +
+End lex_wf.
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_Diam_N_imp_UI.html b/GL.Interpolation.UIGL_Diam_N_imp_UI.html new file mode 100644 index 0000000..175bf6a --- /dev/null +++ b/GL.Interpolation.UIGL_Diam_N_imp_UI.html @@ -0,0 +1,99 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_Diam_N_imp_UI

+ +
+  Require Import List.
+  Export ListNotations.
+  Require Import PeanoNat.
+  Require Import Lia.
+ +
+  Require Import general_export.
+ +
+  Require Import GLS_export.
+ +
+  Require Import UIGL_Def_measure.
+  Require Import UIGL_Canopy.
+  Require Import UIGL_LexSeq.
+  Require Import UIGL_nodupseq.
+  Require Import UIGL_irred_short.
+  Require Import UIGL_braga.
+  Require Import UIGL_UI_prelims.
+  Require Import UIGL_UI_inter.
+  Require Import UIGL_N_imp_UI.
+ +
+  Theorem Diam_rec_UI_imp : forall s p X Y, (is_init s -> False) -> (critical_Seq s) ->
+              GLS_prv (X,
+        Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) -->
+        Diam (UI p (XBoxed_list (top_boxes (fst s)), []%list)) :: Y).
+  Proof.
+  intros.
+  remember (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) as conj1.
+  remember (UI p (XBoxed_list (top_boxes (fst s)), []%list)) as conj2.
+  unfold Diam. unfold Neg.
+  apply derI with (ps:=[((Box (conj1 --> ) --> ) :: X, Box (conj2 --> ) --> :: Y)]).
+  apply ImpR. epose (ImpRRule_I _ _ [] X [] Y). simpl in i. apply i. apply dlCons. 2: apply dlNil.
+  apply derI with (ps:=[(Box (conj2 --> ) :: (Box (conj1 --> ) --> ) :: X, :: Y)]).
+  apply ImpR. epose (ImpRRule_I _ _ [] (Box (conj1 --> ) --> :: X) [] Y). simpl in i. apply i. apply dlCons. 2: apply dlNil.
+  apply derI with (ps:=[([Box (conj2 --> )] ++ X, Box (conj1 --> ) :: :: Y);(Box (conj2 --> ) :: :: X, :: Y)]).
+  apply ImpL. epose (ImpLRule_I _ _ [Box (conj2 --> )] X [] (Bot :: Y)). simpl in i. apply i. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+  2: apply derI with (ps:=[]) ; [apply BotL ; epose (BotLRule_I [Box (conj2 --> )] X _) ; simpl in b ; apply b | apply dlNil].
+  apply derI with (ps:=[(XBoxed_list (Box (conj2 --> ) :: top_boxes X) ++ [Box (conj1 --> )], [conj1 --> ])]).
+  apply GLR. epose (@GLRRule_I _ _ _ []). simpl in g. apply g. 3: apply dlCons. 4: apply dlNil.
+  intro. intros. inversion H1. exists (conj2 --> ) ; rewrite <- H2 ; auto. apply in_top_boxes in H2. destruct H2.
+  destruct s0 ; auto. destruct s0. destruct p0. exists x ; rewrite <- e ; auto.
+  simpl. apply univ_gen_ext_cons. apply top_boxes_nobox_gen_ext. simpl.
+  apply derI with (ps:=[([] ++ conj1 :: conj2 --> :: Box (conj2 --> ) :: XBoxed_list (top_boxes X) ++ [Box (conj1 --> )], [] ++ :: [])]).
+  apply ImpR. apply ImpRRule_I. apply dlCons. 2: apply dlNil. simpl.
+  apply derI with (ps:=[(conj1 :: Box (conj2 --> ) :: XBoxed_list (top_boxes X) ++ [Box (conj1 --> )], [conj2 ; ]);
+  (conj1 :: :: Box (conj2 --> ) :: XBoxed_list (top_boxes X) ++ [Box (conj1 --> )], [])]).
+  apply ImpL. epose (ImpLRule_I _ _ [conj1] _ [] _). simpl in i. apply i. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+  2: apply derI with (ps:=[]) ; [apply BotL ; epose (BotLRule_I [conj1] _ _) ; simpl in b ; apply b | apply dlNil].
+  pose (@GLS_prv_list_wkn_L [conj1] [] [conj2]). simpl in g.
+  pose (@GLS_prv_list_wkn_R (conj1 :: Box (conj2 --> ) :: XBoxed_list (top_boxes X) ++ [Box (conj1 --> )]) [conj2] []). simpl in g0.
+  epose (g0 _ [Bot]). rewrite app_nil_r in g1. apply g1. Unshelve. clear g0.
+  epose (g _ (Box (conj2 --> ) :: XBoxed_list (top_boxes X) ++ [Box (conj1 --> )])).
+  rewrite app_nil_r in g0. apply g0. Unshelve. clear g.
+  apply ImpR_inv with (concl:=([], [conj1 --> conj2])). subst.
+  apply rec_UI_imp ; auto.
+  epose (ImpRRule_I _ _ [] [] [] []). simpl in i. apply i.
+  Qed.
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_Diam_UI_imp_N.html b/GL.Interpolation.UIGL_Diam_UI_imp_N.html new file mode 100644 index 0000000..5945d9c --- /dev/null +++ b/GL.Interpolation.UIGL_Diam_UI_imp_N.html @@ -0,0 +1,724 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_Diam_UI_imp_N

+ +
+  Require Import List.
+  Export ListNotations.
+  Require Import PeanoNat.
+  Require Import Lia.
+ +
+  Require Import general_export.
+ +
+  Require Import GLS_export.
+ +
+  Require Import UIGL_Def_measure.
+  Require Import UIGL_Canopy.
+  Require Import UIGL_irred_short.
+  Require Import UIGL_PermutationT.
+  Require Import UIGL_braga.
+  Require Import UIGL_LexSeq.
+  Require Import UIGL_nodupseq.
+  Require Import UIGL_PermutationTS.
+  Require Import UIGL_And_Or_rules.
+  Require Import UIGL_UI_prelims.
+  Require Import UIGL_UI_inter.
+  Require Import UIGL_Diam_UI_imp_N_prelim.
+ +
+  (* Diam UI implies Diam N.  *)
+ +
+  Theorem UI_Diam_rec_imp : forall s p X Y, (is_init s -> False) -> (critical_Seq s) ->
+              GLS_prv (X,
+        Diam (UI p (XBoxed_list (top_boxes (fst s)), []%list)) -->
+        Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) :: Y).
+  Proof.
+  pose (d:=LexSeq_ind (fun (s:Seq) => forall p X Y, (is_init s -> False) -> (critical_Seq s) ->
+              GLS_prv (X, Diam (UI p (XBoxed_list (top_boxes (fst s)), []%list)) -->
+        Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) :: Y))).
+  apply d. clear d. intros s IH.
+  intros.
+  destruct (empty_seq_dec (XBoxed_list (top_boxes (fst s)), []%list)) as [EE | DE].
+  (* (XBoxed_list (top_boxes (fst s)), *)
+  { inversion EE ; subst ; simpl in *. rewrite H2 in *. assert (GUI p ([],[]) Bot). apply GUI_empty_seq ; auto. apply UI_GUI in H1.
+    rewrite H1 in *. eapply derI with [(Diam :: X , _ :: Y)]. apply ImpR. apply (ImpRRule_I _ _ [] _ []).
+    apply dlCons. 2: apply dlNil. apply DiamL_lim with (top_boxes X).
+    apply is_Boxed_list_top_boxes. apply nobox_gen_ext_top_boxes.
+    apply derI with []. apply BotL ; apply (BotLRule_I []). apply dlNil. }
+  (* (XBoxed_list (top_boxes (fst s)), *)
+  { destruct (critical_Seq_dec (XBoxed_list (top_boxes (fst s)), []%list)).
+  (* The sequent (XBoxed_list (top_boxes (fst s)), *)
+  - assert ((Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))) = [nodupseq (XBoxed_list (top_boxes (fst s)), []%list)]).
+    apply critical_nodupseq in c. apply critical_Seq_InT_Canopy in c. apply Id_InT_Canopy in c ; auto.
+    assert (J50: (Canopy (XBoxed_list (top_boxes (fst s)), []%list)) = [(XBoxed_list (top_boxes (fst s)), []%list)]).
+    apply critical_Seq_InT_Canopy in c. apply Id_InT_Canopy in c ; auto.
+    rewrite H1 ; simpl.
+    destruct (dec_init_rules (XBoxed_list (top_boxes (fst s)), []%list)).
+    (* The sequent (XBoxed_list (top_boxes (fst s)), *)
+    * assert (is_init (XBoxed_list (top_boxes (fst s)), []%list)). auto.
+      assert (is_init (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))). pose (is_init_nodupseq (XBoxed_list (top_boxes (fst s)), []%list)) ; destruct p0 ; auto.
+      assert (J0: GUI p (XBoxed_list (top_boxes (fst s)), []%list) (UI p (XBoxed_list (top_boxes (fst s)), []%list))). apply UI_GUI ; auto.
+      pose (@GUI_inv_critic_init p (XBoxed_list (top_boxes (fst s)), []%list) (UI p (XBoxed_list (top_boxes (fst s)), []%list)) J0 c X0). rewrite <- e.
+      unfold N.
+      destruct (N_pwc p s (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))).
+      simpl. pose (GN_inv_init _ g). rewrite e0. unfold Diam. unfold Neg.
+      apply derI with (ps:=[([] ++ Box (x --> ) --> :: X, [] ++ (Box (And x x --> ) --> ) :: Y)]).
+      assert ((X, (Box (x --> ) --> ) --> (Box (And x x --> ) --> ) :: Y) = ([] ++ X, [] ++ (Box (x --> ) --> ) --> (Box (And x x --> ) --> ) :: Y)).
+      auto. rewrite H2. apply ImpR. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+      apply derI with (ps:=[([] ++ Box (And x x --> ) :: Box (x --> ) --> :: X, [] ++ :: Y)]).
+      apply ImpR. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+      apply derI with (ps:=[([Box (And x x --> )] ++ X, [] ++ Box (x --> ) :: :: Y);([Box (And x x --> )] ++ :: X, [] ++ :: Y)]).
+      apply ImpL. apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+      2: apply derI with (ps:=[]) ; [apply BotL ; apply BotLRule_I | apply dlNil].
+      apply derI with (ps:=[(XBoxed_list (Box (And x x --> ) :: top_boxes X) ++ [Box (x --> )], [x --> ])]).
+      apply GLR. apply GLRRule_I. 3: apply dlCons. 4: apply dlNil.
+      intro. intros. inversion H2. exists (And x x --> ) ; rewrite <- H3 ; auto. apply in_top_boxes in H3. destruct H3.
+      destruct s1 ; auto. destruct s1. destruct p0. exists x0 ; rewrite <- e1 ; auto.
+      simpl. apply univ_gen_ext_cons. apply top_boxes_nobox_gen_ext. simpl.
+      apply derI with (ps:=[([] ++ x :: And x x --> :: Box (And x x --> ) :: XBoxed_list (top_boxes X) ++ [Box (x --> )], [] ++ :: [])]).
+      apply ImpR. apply ImpRRule_I. apply dlCons. 2: apply dlNil. simpl.
+      apply derI with (ps:=[([x] ++ Box (And x x --> ) :: XBoxed_list (top_boxes X) ++ [Box (x --> )], [] ++ And x x :: []);
+      ([x] ++ :: Box (And x x --> ) :: XBoxed_list (top_boxes X) ++ [Box (x --> )], [] ++ [])]).
+      apply ImpL. assert ((x :: And x x --> :: Box (And x x --> ) :: XBoxed_list (top_boxes X) ++ [Box (x --> )], []) =
+      ([x] ++ And x x --> :: Box (And x x --> ) :: XBoxed_list (top_boxes X) ++ [Box (x --> )], [] ++ [])).
+      repeat rewrite <- app_assoc ; auto. rewrite H2. apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+      2: apply derI with (ps:=[]) ; [apply BotL ; apply BotLRule_I | apply dlNil].
+      pose (AndR ([x] ++ Box (And x x --> ) :: XBoxed_list (top_boxes X) ++ [Box (x --> )], []) x x). simpl in g0.
+      simpl. apply g0. clear g0.
+      all: assert ((x :: Box (And x x --> ) :: XBoxed_list (top_boxes X) ++ [Box (x --> )], [x; ]) =
+      ([] ++ x :: Box (And x x --> ) :: XBoxed_list (top_boxes X) ++ [Box (x --> )], [] ++ [x; ])) ;
+      auto ; rewrite H2 ; apply Id_all_form.
+  (* The sequent (XBoxed_list (top_boxes (fst s)), *)
+    * (* Massaging UI. *)
+      assert (J: is_init (XBoxed_list (top_boxes (fst s)), []%list) -> False). auto.
+      assert (J40: is_init (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)) -> False). intro ; apply J ; apply is_init_nodupseq ; auto.
+      assert (J0: GUI p (XBoxed_list (top_boxes (fst s)), []%list) (UI p (XBoxed_list (top_boxes (fst s)), []%list))). apply UI_GUI ; auto.
+      assert (J1: Gimap (GUI p) (GLR_prems (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))) (map (UI p) (GLR_prems (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))). apply Gimap_map. intros.
+      apply UI_GUI ; auto.
+      assert (J2: Gimap (GN p (GUI p) (XBoxed_list (top_boxes (fst s)), []%list))
+      (Canopy (nodupseq (XBoxed_list (top_boxes (fst (XBoxed_list (top_boxes (fst s)), @nil MPropF))), []%list)))
+      (map (N p (XBoxed_list (top_boxes (fst s)), []%list)) (Canopy (nodupseq (XBoxed_list (top_boxes (fst (XBoxed_list (top_boxes (fst s)), @nil MPropF))), []%list))))).
+      simpl. apply Gimap_map. intros. apply (N_spec p (XBoxed_list (top_boxes (fst s)), []%list) x).
+ +
+      pose (@GUI_inv_critic_not_init p (XBoxed_list (top_boxes (fst s)), []%list) _ _ _ J0 c DE J J1 J2). rewrite <- e. clear e. simpl.
+      (*
+      assert (H2 : (GLR_prems (nodupseq (XBoxed_list (top_boxes (fst s)), list))). simpl.
+      destruct x ; auto. assert (InT l (l::x)) by apply InT_eq. apply p0 in H2.
+      inversion H2 ; subst. destruct Δ0 ; inversion H6.
+      }
+      rewrite H2. simpl. *)

+ +
+      (* Naming formulas for brevity. *)
+      remember (And (N p s (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))) Top) as conj.
+      remember (Or (Or (list_disj (map Neg (restr_list_prop p (XBoxed_list (top_boxes (fst s)))))) (Or (Diam (list_conj (map (N p (XBoxed_list (top_boxes (fst s)), []%list)) (Canopy (nodupseq (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s)))), []%list))))))))) as disj.
+ +
+       (* Proof-theoretic work. *)
+       apply derI with (ps:=[([] ++ Diam disj :: X, [] ++ Diam conj :: Y)]). apply ImpR.
+       apply ImpRRule_I.
+       apply dlCons. 2: apply dlNil. unfold Diam.
+       apply derI with (ps:=[([] ++ Box (Neg conj) :: Neg (Box (Neg disj)) :: X, [] ++ Bot :: Y)]).
+       apply ImpR. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+       apply derI with (ps:=[([Box (Neg conj)] ++ X, [] ++ Box (Neg disj) :: :: Y);
+       ([Box (Neg conj)] ++ Bot :: X, [] ++ :: Y)]).
+       apply ImpL. apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+       2: apply derI with (ps:=[]) ; [apply BotL ; apply BotLRule_I | apply dlNil].
+       apply derI with (ps:=[(XBoxed_list (Box (Neg conj) :: top_boxes X) ++ [Box (Neg disj)], [Neg disj])]).
+       apply GLR. apply GLRRule_I.
+       intro A. intros H3. inversion H3 as [H4 | H4]. exists (Neg conj) ; rewrite <- H4 ; auto. apply in_top_boxes in H4. destruct H4.
+       destruct s0 ; auto. destruct s0. destruct p0. exists x ; rewrite <- e ; auto.
+       simpl. apply univ_gen_ext_cons. apply top_boxes_nobox_gen_ext. simpl. apply dlCons. 2: apply dlNil.
+       apply derI with (ps:=[([] ++ disj :: Neg conj :: Box (Neg conj) :: XBoxed_list (top_boxes X) ++ [Box (Neg disj)], [] ++ Bot :: [])]).
+       apply ImpR. assert ((Neg conj :: Box (Neg conj) :: XBoxed_list (top_boxes X) ++ [Box (Neg disj)], [Neg disj]) =
+       ([] ++ Neg conj :: Box (Neg conj) :: XBoxed_list (top_boxes X) ++ [Box (Neg disj)], [] ++ [Neg disj])). auto. rewrite H2.
+       apply ImpRRule_I. apply dlCons. 2: apply dlNil. simpl.
+       apply derI with (ps:=[([disj] ++ Box (Neg conj) :: XBoxed_list (top_boxes X) ++ [Box (Neg disj)], [] ++ conj :: []);
+       ([disj] ++ Bot:: Box (Neg conj) :: XBoxed_list (top_boxes X) ++ [Box (Neg disj)], [] ++ [])]).
+       apply ImpL. assert ((disj :: Neg conj :: Box (Neg conj) :: XBoxed_list (top_boxes X) ++ [Box (Neg disj)], []) =
+       ([disj] ++ Neg conj :: Box (Neg conj) :: XBoxed_list (top_boxes X) ++ [Box (Neg disj)], [] ++ [])).
+       repeat rewrite <- app_asoc ; auto. rewrite H2. apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+       2: apply derI with (ps:=[]) ; [apply BotL ; apply BotLRule_I | apply dlNil]. simpl. rewrite Heqconj.
+       pose (AndR (disj :: Box (Neg (And (N p s (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))) Top)) :: XBoxed_list (top_boxes X) ++ [Box (Neg disj)], []) (N p s (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))) Top).
+       simpl in g. apply g. clear g.
+       2: pose (TopR (disj :: Box (Neg (And (N p s (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))) Top)) :: XBoxed_list (top_boxes X) ++ [Box (Neg disj)]) [] [Bot]) ; simpl in g0 ; auto.
+       pose (@GLS_prv_wkn_R (disj :: Box (Neg (And (N p s (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))) Top)) :: XBoxed_list (top_boxes X) ++ [Box (Neg disj)], [N p s (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))])).
+       apply g with (A:=Bot). clear g. subst.
+      2: epose (wkn_RI Bot _ [N p s (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))] []) ; simpl in w ; apply w.
+ +
+       (* Naming LHS. *)
+       remember (Box (Neg (And (N p s (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))) Top)) :: XBoxed_list (top_boxes X) ++ [Box (Neg (Or (Or (list_disj (map Neg (restr_list_prop p (XBoxed_list (top_boxes (fst s))))))
+       (Or (Diam (list_conj (map (N p (XBoxed_list (top_boxes (fst s)), []%list)) (Canopy (nodupseq (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s)))), []%list))))))))))]) as LHS.
+ +
+      destruct (Compare_dec.lt_dec (length (usable_boxes (nodupseq (XBoxed_list (top_boxes (fst s)), [])))) (length (usable_boxes s))).
+      (* The sequent (XBoxed_list (top_boxes (fst s)), *)
+      + remember (N p (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))) as N_func.
+         (* Massage N on the right. *)
+         unfold N. unfold N in HeqLHS.
+         destruct (N_pwc p s (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))).
+         simpl. simpl in HeqLHS.
+         assert ((forall (x : Seq) (l m : MPropF), (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x l -> (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x m -> l = m)).
+         intros. subst. auto.
+         assert (J11: Gimap (GUI p) (GLR_prems (XBoxed_list (top_boxes (fst s)), []%list)) (map (UI p) (GLR_prems (XBoxed_list (top_boxes (fst s)), []%list)))).
+         apply Gimap_map. intros. apply UI_GUI ; auto.
+         assert (J12: GUI p (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)) (UI p (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))). apply UI_GUI ; auto.
+         apply UI_GUI in J12.
+         pose (GN_inv_noinit_lessub p g J40 l (UI_spec p _)). rewrite <- e. rewrite <- e in HeqLHS. clear e.
+         assert (J00: GUI p (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)) (UI p (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))). apply UI_GUI ; auto.
+         assert (J01: critical_Seq (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))). apply critical_nodupseq in c ; auto.
+         assert (J43: (nodupseq (XBoxed_list (top_boxes (fst s)), @nil MPropF)) <> ([],[])). simpl ; intro. inversion H3.
+         apply nodup_nil in H5. rewrite H5 in DE ; auto.
+         assert (J44: is_init (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)) -> False). intro. apply J. apply is_init_nodupseq ; auto.
+         assert (J45: Gimap (GUI p) (GLR_prems (nodupseq (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))) (map (UI p) (GLR_prems (nodupseq (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))))).
+         apply Gimap_map. intros. apply UI_GUI ; auto.
+         assert (J46: Gimap (GN p (GUI p) (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))
+         (Canopy (nodupseq (XBoxed_list (top_boxes (fst (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))), []%list)))
+         (map (N p (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))) (Canopy (nodupseq (XBoxed_list (top_boxes (fst (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))), []%list))))).
+         simpl. apply Gimap_map. intros. apply (N_spec p (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)) x0).
+         pose (@GUI_inv_critic_not_init p (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)) _ _ _ J00 J01 J43 J44 J45 J46). rewrite <- e. clear e. simpl.
+         (* Deal with the first disjuncts. *)
+         epose (OrL (_,_)). apply g0 ; simpl ; clear g0.
+         apply derI with (ps:=[]) ; [ apply BotL ; apply (BotLRule_I []) | apply dlNil].
+         epose (OrL (_,_)). apply g0 ; simpl ; clear g0.
+         epose (OrR (_,_)). apply g0 ; simpl ; clear g0.
+         epose (@GLS_prv_wkn_R (list_disj (map Neg (restr_list_prop p (XBoxed_list (top_boxes (fst s))))) :: LHS,[Or (list_disj (map Neg (restr_list_prop p (nodup eq_dec_form (XBoxed_list (top_boxes (fst s))))))) (Or
+         (Diam (list_conj (map (N p (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))
+         (Canopy (nodupseq (XBoxed_list (top_boxes (nodup eq_dec_form (XBoxed_list (top_boxes (fst s))))), []%list)))))))])).
+         apply g0 with (A:=Bot) ; simpl ; clear g0. 2: eapply (wkn_RI Bot _ []).
+         eapply (list_disj_L _ (_,_)) ; simpl. intros. apply InT_map_iff in H3. destruct H3. destruct p0. rewrite <- e.
+         epose (OrR (_,_)). apply g0 ; simpl ; clear g0.
+         eapply (list_disj_wkn_R _ (_,_) (Neg x0)) ; simpl. apply InT_map_iff. exists x0 ; split ; auto.
+         apply restr_list_prop_nodup in i ; auto.
+         epose (Id_all_form _ [] _ [] _). simpl in d. apply d.
+         epose (OrL (_,_)). apply g0 ; simpl ; clear g0.
+         apply derI with (ps:=[]) ; [ apply BotL ; apply (BotLRule_I []) | apply dlNil].
+         epose (OrR (_,_)). apply g0 ; simpl ; clear g0.
+         epose (@GLS_prv_wkn_R (Diam (list_conj (map (fun s0 : Seq => proj1_sig
+         (N_pwc p (XBoxed_list (top_boxes (fst s)), []%list) s0))
+         (Canopy (nodupseq (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s)))), []%list))))) :: LHS,[Or (list_disj (map Neg (restr_list_prop p (nodup eq_dec_form (XBoxed_list (top_boxes (fst s))))))) (Or
+         (Diam (list_conj (map (N p (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))
+         (Canopy (nodupseq (XBoxed_list (top_boxes (nodup eq_dec_form (XBoxed_list (top_boxes (fst s))))), []%list)))))))])).
+         apply g0 with (A:=Bot) ; simpl ; clear g0. 2: eapply (wkn_RI Bot _ []).
+         epose (OrR (_,_)). apply g0 ; simpl ; clear g0.
+         epose (@GLS_prv_wkn_R (Diam (list_conj (map (fun s0 : Seq => proj1_sig
+         (N_pwc p (XBoxed_list (top_boxes (fst s)), []%list) s0))
+         (Canopy (nodupseq (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s)))), []%list))))) :: LHS,[(Or
+         (Diam (list_conj (map (N p (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))
+         (Canopy (nodupseq (XBoxed_list (top_boxes (nodup eq_dec_form (XBoxed_list (top_boxes (fst s))))), []%list)))))))])).
+         apply g0 with (A:=list_disj (map Neg (restr_list_prop p (nodup eq_dec_form (XBoxed_list (top_boxes (fst s))))))) ; simpl ; clear g0.
+          2: eapply (wkn_RI (list_disj (map Neg (restr_list_prop p (nodup eq_dec_form (XBoxed_list (top_boxes (fst s))))))) _ []).
+         epose (OrR (_,_)). apply g0 ; simpl ; clear g0.
+         epose (@GLS_prv_wkn_R (Diam (list_conj (map (fun s0 : Seq => proj1_sig
+         (N_pwc p (XBoxed_list (top_boxes (fst s)), []%list) s0))
+         (Canopy (nodupseq (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s)))), []%list))))) :: LHS,[Diam (list_conj (map (N p (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))
+         (Canopy (nodupseq (XBoxed_list (top_boxes (nodup eq_dec_form (XBoxed_list (top_boxes (fst s))))), []%list)))))])).
+         apply g0 with (A:=Bot) ; simpl ; clear g0. 2: eapply (wkn_RI Bot _ []).
+ +
+        (* Naming formulas for brevity. *)
+        remember ((list_conj (map (fun s0 : Seq => proj1_sig (N_pwc p(XBoxed_list (top_boxes (fst s)), []%list) s0))
+        (Canopy (nodupseq (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s)))), []%list)))))) as conj1.
+        remember (list_conj
+         (map (N p (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))
+            (Canopy (nodupseq (XBoxed_list (top_boxes (nodup eq_dec_form (XBoxed_list (top_boxes (fst s))))), []%list))))) as conj2.
+ +
+         (* Proof-theoretic work. *)
+         unfold Diam.
+         apply derI with (ps:=[([] ++ Box (Neg conj2) :: Neg (Box (Neg conj1)) :: LHS, [] ++ Bot :: [])]).
+         apply ImpR. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+         apply derI with (ps:=[([Box (Neg conj2)] ++ LHS, [] ++ Box (Neg conj1) :: :: []);
+         ([Box (Neg conj2)] ++ Bot :: LHS, [] ++ :: [])]).
+         apply ImpL. apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+         2: apply derI with (ps:=[]) ; [apply BotL ; apply BotLRule_I | apply dlNil].
+         apply derI with (ps:=[(XBoxed_list (Box (Neg conj2) :: top_boxes LHS) ++ [Box (Neg conj1)], [Neg conj1])]).
+         apply GLR. apply GLRRule_I.
+         intro. intros. inversion H3. exists (Neg conj2) ; rewrite <- H4 ; auto. apply in_top_boxes in H4. destruct H4.
+         destruct s0 ; auto. destruct s0. destruct p0. exists x0 ; rewrite <- e ; auto.
+         simpl. apply univ_gen_ext_cons. apply top_boxes_nobox_gen_ext. simpl. apply dlCons. 2: apply dlNil.
+         remember (Box (Neg conj2) :: XBoxed_list (top_boxes LHS) ++ [Box (Neg conj1)]) as LHS0.
+         apply derI with (ps:=[([] ++ conj1 :: Neg conj2 :: LHS0, [] ++ Bot :: [])]).
+         apply ImpR. eapply (ImpRRule_I _ _ [] _ []). apply dlCons. 2: apply dlNil. simpl.
+         apply derI with (ps:=[(conj1 :: LHS0, [conj2;]);(conj1 :: Bot :: LHS0, [])]).
+         apply ImpL. eapply (ImpLRule_I _ _ [_] _ []). apply dlCons. 2: apply dlCons. 3: apply dlNil.
+         2: apply derI with (ps:=[]) ; [apply BotL ; eapply (BotLRule_I [_]) | apply dlNil].
+ +
+         (* Deal with the Ns. *)
+         rewrite Heqconj1. rewrite Heqconj2.
+         eapply (list_conj_R _ (_,_)) ; simpl. intros. apply InT_map_iff in H3. destruct H3. destruct p0. rewrite <- e.
+         rewrite <- nodup_top_boxes in i. unfold nodupseq in i ; simpl in i. rewrite nodup_XBoxed_list in i.
+         eapply (list_conj_wkn_L _ (_,_) (N p (XBoxed_list (top_boxes (fst s)), []%list) x0)). apply InT_map_iff. exists x0.
+         destruct ((N_pwc p (XBoxed_list (top_boxes (fst s)), []%list) x0)) ; simpl.
+         split ; auto. subst. pose (@N_spec p (XBoxed_list (top_boxes (fst s)), []%list) x0).
+         eapply (GN_fun0 p _ _ _ _ _ _ g0 g1). simpl.
+ +
+        (* Massage the Ns. *)
+        destruct (dec_init_rules x0).
+        (* The sequents x1 and x0 is initial. *)
+         assert (is_init x0) ; auto.
+         pose (N_spec p (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)) x0).
+         pose (GN_inv_init _ g0). rewrite <- e0 ; auto.
+         epose (TopR _ [] [Bot]). simpl in g1 ; apply g1.
+        (* The sequent x is not initial. *)
+         assert (is_init x0 -> False) ; auto.
+         assert (J20: GUI p x0 (UI p x0)). apply UI_GUI ; auto.
+         pose (Canopy_critical _ _ i).
+         destruct (Compare_dec.lt_dec (length (usable_boxes x0)) (length (usable_boxes (XBoxed_list (top_boxes (fst s)), []%list)))).
+         (* The sequent x has less usable boxes than s. *)
+         pose (N_spec p (XBoxed_list (top_boxes (fst s)), []%list) x0).
+         epose (@GN_inv_noinit_lessub _ _ _ _ _ g0 H3 l0 (UI_spec p _)). rewrite <- e0 ; auto.
+         assert (J60: length (usable_boxes x0) < length (usable_boxes (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))).
+         rewrite <- ub_nodupseq ; auto.
+         pose (N_spec p (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)) x0).
+         epose (@GN_inv_noinit_lessub _ _ _ _ _ g1 H3). rewrite <- e1 ; auto.
+         epose (Id_all_form _ [] _ [] _). simpl in d. apply d. apply UI_GUI ; auto.
+         (* The sequent x does not have less usable boxes than s. *)
+         pose (N_spec p (XBoxed_list (top_boxes (fst s)), []%list) x0).
+         assert (J61: Gimap (GUI p) (GLR_prems (nodupseq x0)) (map (UI p) (GLR_prems (nodupseq x0)))).
+         apply Gimap_map ; auto. intros ; apply UI_GUI ; auto.
+         epose (@GN_inv_noinit_nolessub _ _ _ _ _ g0 H3 n J61). rewrite <- e0 ; auto.
+         assert (J62: (length (usable_boxes x0) < length (usable_boxes (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))) -> False).
+         rewrite <- ub_nodupseq ; auto.
+         pose (N_spec p (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)) x0).
+         epose (@GN_inv_noinit_nolessub _ _ _ _ _ g1 H3 J62 J61). rewrite <- e1 ; auto.
+         epose (Id_all_form _ [] _ [] _). simpl in d. apply d.
+ +
+      (* The sequent (XBoxed_list (top_boxes (fst s)), *)
+      + remember (N p (XBoxed_list (top_boxes (fst s)), []%list)) as N_func.
+         (* Massage N on the right. *)
+         unfold N. unfold N in HeqLHS. destruct (N_pwc p s (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))).
+         simpl. simpl in HeqLHS.
+         assert ((forall (x : Seq) (l m : MPropF), (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x l -> (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x m -> l = m)).
+         intros. subst. auto.
+         assert (J11: Gimap (GUI p) (GLR_prems (nodupseq (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))) (map (UI p) (GLR_prems (nodupseq (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))))).
+         apply Gimap_map. intros. apply UI_GUI ; auto.
+         pose (GN_inv_noinit_nolessub _ g J40 n J11). rewrite <- e. rewrite <- e in HeqLHS. clear e. simpl.
+ +
+        (* (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s)))), *)
+        assert (critical_Seq (nodupseq (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s)))), []%list))).
+        intros A HA ; simpl ; simpl in HA. rewrite app_nil_r in HA. apply nodup_In in HA.
+        pose (In_XBoxed_list _ _ HA). destruct o. left.
+        apply in_top_boxes in H3. destruct H3. destruct s0. destruct s0. destruct p0. exists x0 ; auto.
+        destruct H3. destruct H3. subst. apply c. simpl. rewrite app_nil_r. apply XBoxed_list_In.
+        apply nolessub_In. intro. apply n. rewrite <- ub_nodupseq. auto. auto.
+        pose (i := critical_Seq_InT_Canopy _ H3). apply Id_InT_Canopy in i. rewrite i ; simpl.
+ +
+        (* Treating the disjunction on the right. *)
+        epose (OrR (_,_)). simpl in g0. apply g0 ; clear g0.
+        epose (@GLS_prv_wkn_R (Or (Or (list_disj (map Neg (restr_list_prop p (XBoxed_list (top_boxes (fst s))))))
+        (Or (Diam (And (N_func (nodupseq (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s)))), []%list))) Top)))) :: LHS, [Or (list_disj (map Neg (restr_list_prop p (nodup eq_dec_form (XBoxed_list (top_boxes (fst s))))))) ])).
+        apply g0 with (A:=). clear g0.
+        2: eapply (wkn_RI Bot _ []).
+        epose (OrR (_,_)). simpl in g0. apply g0 ; clear g0.
+        pose (@GLS_prv_wkn_R (Or (Or (list_disj (map Neg (restr_list_prop p (XBoxed_list (top_boxes (fst s))))))
+        (Or (Diam (And (N_func (nodupseq (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s)))), []%list))) Top)))) :: LHS, [list_disj (map Neg (restr_list_prop p (nodup eq_dec_form (XBoxed_list (top_boxes (fst s))))))])).
+        apply g0 with (A:=). clear g0.
+        2: eapply (wkn_RI Bot _ [list_disj (map Neg (restr_list_prop p (nodup eq_dec_form (XBoxed_list (top_boxes (fst s))))))] []).
+ +
+        (* Treating the disjunction on the left. *)
+        epose (OrL (_,_)). simpl in g0. apply g0 ; clear g0.
+        apply derI with (ps:=[]). apply BotL. eapply (BotLRule_I []). apply dlNil.
+        epose (OrL (_,_)). simpl in g0. apply g0 ; clear g0.
+        eapply (list_disj_L _ (_,_)) ; simpl. intros. apply InT_map_iff in H4. destruct H4. destruct p0. rewrite <- e.
+        eapply (list_disj_wkn_R _ (_,_) (Neg x0)) ; simpl. apply InT_map_iff. exists x0 ; split ; auto.
+        apply restr_list_prop_nodup in i0 ; auto.
+        epose (Id_all_form _ [] _ [] _). simpl in d. apply d.
+        epose (OrL (_,_)). apply g0 ; simpl ; clear g0.
+        apply derI with (ps:=[]) ; [ apply BotL ; apply (BotLRule_I []) | apply dlNil].
+ +
+        (* Critical case. *)
+        subst ; simpl. rewrite i. simpl.
+        remember (And (N p (XBoxed_list (top_boxes (fst s)), []%list) (nodupseq (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s)))), []%list))) Top) as conjN.
+        remember [list_disj (map Neg (restr_list_prop p (nodup eq_dec_form (XBoxed_list (top_boxes (fst s))))))] as RHS.
+        remember (Box (Neg (And (Or (Or (list_disj (map Neg (restr_list_prop p (nodup eq_dec_form (XBoxed_list (top_boxes (fst s))))))) )) Top)) :: XBoxed_list (top_boxes X) ++
+        [Box (Neg (Or (Or (list_disj (map Neg (restr_list_prop p (XBoxed_list (top_boxes (fst s)))))) (Or (Diam conjN)))))]) as LHS.
+        unfold Diam.
+        apply derI with (ps:=[([] ++ LHS, [] ++ (Box (Neg conjN)) :: RHS);([] ++ Bot :: LHS, [] ++ RHS)]).
+        apply ImpL. apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+        2: apply derI with (ps:=[]) ; [apply BotL ; apply BotLRule_I | apply dlNil].
+        apply derI with (ps:=[(XBoxed_list (top_boxes LHS) ++ [Box (Neg conjN)], [Neg conjN])]).
+        apply GLR. apply GLRRule_I.
+        intros A HA. rewrite HeqLHS in HA. inversion HA. symmetry in H4. eexists ; rewrite H4 ; auto. apply in_top_boxes in H4. destruct H4.
+        destruct s0 ; auto. destruct s0. destruct p0. exists x0 ; rewrite <- e ; auto.
+        simpl. apply top_boxes_nobox_gen_ext. apply dlCons. 2: apply dlNil.
+        apply derI with (ps:=[([] ++ conjN :: XBoxed_list (top_boxes LHS) ++ [Box (Neg conjN)], [] ++ Bot :: [])]).
+        apply ImpR. assert ((XBoxed_list (top_boxes LHS) ++ [Box (Neg conjN)], [Neg conjN]) =
+        ([] ++ XBoxed_list (top_boxes LHS) ++ [Box (Neg conjN)], [] ++ [Neg conjN])). auto. rewrite H4.
+        apply ImpRRule_I. apply dlCons. 2: apply dlNil. simpl. subst.
+        epose (AndL (_, _)). simpl in g0. apply g0. simpl. clear g0. repeat rewrite top_boxes_distr_app. simpl.
+        repeat rewrite XBox_app_distrib. simpl. repeat rewrite <- app_assoc. simpl.
+        eapply derI with (ps:=[_ ; _]). apply ImpL. epose (ImpLRule_I _ Bot [_ ; _] _ [] [Bot]).
+        simpl in i0. apply i0. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+        2: apply derI with (ps:=[]) ; [apply BotL ; epose (BotLRule_I [_ ; _] _ _) ; simpl in b ; apply b | apply dlNil]. simpl.
+        epose (AndR (_,_)). simpl in g0. apply g0. clear g0. 2: epose (TopR _ [] [Bot]) ; apply g1 ; auto.
+        epose (OrR (_,_)). simpl in g0. apply g0. clear g0.
+ +
+         (* Massaging N on the left. *)
+         unfold N. destruct (N_pwc p (XBoxed_list (top_boxes (fst s)), []%list)
+         (nodupseq (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s)))), []%list))). simpl.
+         assert (J12: Gimap (GUI p) (GLR_prems (nodupseq (nodupseq (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s)))), []%list))))
+         (map (UI p) (GLR_prems (nodupseq (nodupseq (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s)))), []%list)))))).
+         apply Gimap_map. intros. apply UI_GUI ; auto.
+ +
+         assert (J13: length (usable_boxes (nodupseq (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s)))), []%list))) < length (usable_boxes (XBoxed_list (top_boxes (fst s)), []%list)) -> False).
+         subst. intro. apply n. rewrite <- ub_nodupseq. apply ub_stable ; auto. rewrite <- ub_nodupseq in H4 ; auto.
+ +
+         assert (J14: is_init (nodupseq (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s)))), []%list)) -> False).
+         intros. apply J. unfold is_init. right. destruct X0. destruct s0. inversion i0. exfalso. destruct Δ0 ; inversion H6.
+         inversion i0. destruct Δ0 ; inversion H6. inversion b. subst.
+         assert (InT Bot (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s)))))).
+         apply In_InT. rewrite <- nodup_In. rewrite <- H4. apply in_or_app ; right ; apply in_eq.
+         assert (In Bot (XBoxed_list (top_boxes (fst s)))).
+         apply InT_In in H5. apply In_XBoxed_list in H5. destruct H5. exfalso. apply in_top_boxes in H5.
+         destruct H5. destruct s0. destruct s0. destruct p0 ; subst. inversion e. destruct H5.
+         destruct H5. subst. apply nolessub_In in H5 ; auto. apply XBoxed_list_In ; auto.
+         rewrite <- ub_nodupseq in n ; auto. apply In_InT in H6. apply InT_split in H6.
+         destruct H6. destruct s0. rewrite e. apply BotLRule_I.
+ +
+         pose (GN_inv_noinit_nolessub _ g0 J14 J13 J12). rewrite <- e. simpl.
+ +
+         (* Final proof-theoretic work. *)
+         epose (OrL (_,_)). simpl in g1. apply g1 ; clear g1.
+         apply derI with (ps:=[]). apply BotL. epose (BotLRule_I []). simpl in b ; auto. apply dlNil.
+         epose (OrL (_,_)). simpl in g1. apply g1 ; clear g1.
+         epose (@GLS_prv_wkn_R (list_disj (map Neg (restr_list_prop p (nodup eq_dec_form (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s)))))))) :: Top
+         :: Box (Neg (And (Or (Or (list_disj (map Neg (restr_list_prop p (nodup eq_dec_form (XBoxed_list (top_boxes (fst s))))))) )) Top)) :: XBoxed_list (top_boxes (XBoxed_list (top_boxes X))) ++
+         [Neg (Or (Or (list_disj (map Neg (restr_list_prop p (XBoxed_list (top_boxes (fst s)))))) (Or (Diam (And (Or (Or (list_disj (map Neg (restr_list_prop p (nodup eq_dec_form (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s))))))))) )) Top)))));
+         Box (Neg (Or (Or (list_disj (map Neg (restr_list_prop p (XBoxed_list (top_boxes (fst s)))))) (Or (Diam (And (Or (Or (list_disj (map Neg (restr_list_prop p (nodup eq_dec_form (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s))))))))) )) Top))))));
+         Box (Neg (And (Or (Or (list_disj (map Neg (restr_list_prop p (nodup eq_dec_form (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s))))))))) )) Top))], [Or (list_disj (map Neg (restr_list_prop p (nodup eq_dec_form (XBoxed_list (top_boxes (fst s))))))) ; ])).
+         apply g1 with (A:=Bot). clear g1. clear e.
+         epose (OrR (_,[Bot])). simpl in g1. apply g1. clear g1.
+         epose (list_disj_L _ (_,_)). simpl in g1. apply g1. clear g1. intros.
+         epose (list_disj_wkn_R _ (_,_) A). apply g1. clear g1. apply InT_map_iff. apply InT_map_iff in H4. destruct H4.
+         destruct p0. subst. exists x1 ; split ; auto. apply restr_list_prop_nodup.
+         pose (restr_list_prop_nodup (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s))))) x1 p). destruct p0. apply i1 in i0.
+         unfold restr_list_prop. unfold restr_list_prop in i0. apply In_InT. apply InT_In in i0.
+         apply in_remove in i0. destruct i0. apply in_in_remove ; auto. apply In_list_prop_LF in H4.
+         destruct H4. destruct s0. subst. apply In_list_In_list_prop_LF ; auto. apply In_XBoxed_list in i0.
+         destruct i0. exfalso. apply in_top_boxes in H4. destruct H4. destruct s0. destruct s0. destruct p0. inversion e.
+         destruct H4. destruct H4. subst. apply nolessub_In in H4 ; auto. apply XBoxed_list_In ; auto.
+         rewrite <- ub_nodupseq in n ; auto.
+         simpl. clear g1. epose (Id_all_form A [] _ []). simpl in d. apply d.
+         epose (wkn_RI Bot _ []). simpl in w. apply w.
+         apply derI with (ps:=[]). apply BotL. epose (BotLRule_I []). simpl in b. auto. apply dlNil.
+  (* The sequent (XBoxed_list (top_boxes (fst s)), *)
+  - (* First, we massage UI. *)
+    assert ((GLR_prems (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))) = nil).
+    unfold GLR_prems. destruct (finite_GLR_premises_of_S (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))). simpl.
+    destruct x ; auto. assert (InT l (l::x)). apply InT_eq. apply p0 in H1.
+    inversion H1 ; subst. destruct Δ0 ; inversion H5.
+    assert (J0: GUI p (XBoxed_list (top_boxes (fst s)), []%list) (UI p (XBoxed_list (top_boxes (fst s)), []%list))). apply UI_GUI ; auto.
+    assert (J1: Gimap (GUI p) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))) (map (UI p) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))). apply Gimap_map. intros.
+    apply UI_GUI ; auto.
+    pose (@GUI_inv_not_critic p (XBoxed_list (top_boxes (fst s)), []%list) (UI p (XBoxed_list (top_boxes (fst s)), []%list)) _ J0 f J1). rewrite <- e. clear e.
+ +
+    (* Proof theoretic work on the implication and diamonds. *)
+    remember (list_conj (map (UI p) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) as conj1.
+    remember (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) as conj2.
+    apply derI with (ps:=[([] ++ Diam conj1 :: X, [] ++ Diam conj2 :: Y)]). apply ImpR. apply ImpRRule_I.
+    apply dlCons. 2: apply dlNil. unfold Diam.
+    apply derI with (ps:=[([] ++ Box (Neg conj2) :: Neg (Box (Neg conj1)) :: X, [] ++ Bot :: Y)]).
+    apply ImpR. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+    apply derI with (ps:=[([Box (Neg conj2)] ++ X, [] ++ Box (Neg conj1) :: :: Y);
+    ([Box (Neg conj2)] ++ Bot :: X, [] ++ :: Y)]).
+    apply ImpL. apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+    2: apply derI with (ps:=[]) ; [apply BotL ; apply BotLRule_I | apply dlNil].
+    apply derI with (ps:=[(XBoxed_list (Box (Neg conj2) :: top_boxes X) ++ [Box (Neg conj1)], [Neg conj1])]).
+    apply GLR. apply GLRRule_I.
+    intro. intros. inversion H2. exists (Neg conj2) ; rewrite <- H3 ; auto. apply in_top_boxes in H3. destruct H3.
+    destruct s0 ; auto. destruct s0. destruct p0. exists x ; rewrite <- e ; auto.
+    simpl. apply univ_gen_ext_cons. apply top_boxes_nobox_gen_ext. simpl. apply dlCons. 2: apply dlNil.
+    apply derI with (ps:=[([] ++ conj1 :: Neg conj2 :: Box (Neg conj2) :: XBoxed_list (top_boxes X) ++ [Box (Neg conj1)], [] ++ Bot :: [])]).
+    apply ImpR. eapply (ImpRRule_I _ _ [] _ []). apply dlCons. 2: apply dlNil. simpl.
+    apply derI with (ps:=[([conj1] ++ Box (Neg conj2) :: XBoxed_list (top_boxes X) ++ [Box (Neg conj1)], [] ++ conj2 :: []);
+    ([conj1] ++ Bot :: Box (Neg conj2) :: XBoxed_list (top_boxes X) ++ [Box (Neg conj1)], [] ++ [])]).
+    apply ImpL. eapply (ImpLRule_I _ _ [_] _ [] [_]). apply dlCons. 2: apply dlCons. 3: apply dlNil.
+    2: apply derI with (ps:=[]) ; [apply BotL ; apply BotLRule_I | apply dlNil]. simpl.
+ +
+    (* Getting rid of bottom on the right. *)
+    pose (@GLS_prv_wkn_R (conj1 :: Box (Neg conj2) :: XBoxed_list (top_boxes X) ++ [Box (Neg conj1)], [conj2])).
+    apply g with (A:=Bot). subst. clear g.
+    2: assert ([conj2; ] = [conj2] ++ :: []) ; auto. 2: rewrite H2.
+    2: assert ([conj2] = [conj2] ++ []) ; auto. 2: rewrite H3 ; apply wkn_RI.
+ +
+    (* Naming context on the left. *)
+    remember (Box (Neg (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))))
+    :: XBoxed_list (top_boxes X) ++ [Box (Neg (list_conj (map (UI p) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))))]) as LHS.
+ +
+    (* We treat the list of conjunction on the right. *)
+    epose (list_conj_R _ (_,[])). simpl in g. apply g. clear g. intros. apply InT_map_iff in H2. destruct H2. destruct p0. rewrite <- e.
+ +
+    (* We treat the list of conjunction on the left. *)
+    epose (list_conj_wkn_L _ (LHS,_)). simpl in g. apply g with (A:=UI p x). clear g. subst. apply InT_map_iff. exists x ; auto. clear g.
+ +
+    destruct (dec_init_rules x).
+    (* The sequent x is initial. *)
+     assert (is_init x) ; auto.
+     pose (N_spec p s x).
+     pose (GN_inv_init _ g). rewrite <- e0 ; auto.
+     epose (TopR _ [] []). simpl in g0 ; apply g0.
+    (* The sequent x is not initial. *)
+     assert (is_init x -> False) ; auto.
+     assert (J2: GUI p x (UI p x)). apply UI_GUI ; auto.
+     pose (Canopy_critical _ _ i).
+     assert (J3: Gimap (GUI p) (GLR_prems (nodupseq x)) (map (UI p) (GLR_prems (nodupseq x)))).
+     apply Gimap_map. intros. apply UI_GUI ; auto.
+     assert (J4: Gimap (GN p (GUI p) x) (Canopy (nodupseq (XBoxed_list (top_boxes (fst x)), @nil MPropF)))
+     (map (N p x) (Canopy (nodupseq (XBoxed_list (top_boxes (fst x)), @nil MPropF))))).
+     simpl. apply Gimap_map. intros. apply (N_spec p x x0).
+     destruct (empty_seq_dec x) as [EEx | DEx].
+     { subst. assert (GUI p ([],[]) Bot). apply GUI_empty_seq ; auto. apply UI_GUI in H3.
+       rewrite H3 in *. apply derI with []. apply BotL ; apply (BotLRule_I []). apply dlNil. }
+
+      { epose (GUI_inv_critic_not_init _ J2 c DEx H2 J3 J4). rewrite <- e0.
+      destruct (Compare_dec.lt_dec (length (usable_boxes x)) (length (usable_boxes s))).
+      (* The sequent x has less usable boxes than s. *)
+      assert ((forall (x : Seq) (l m : MPropF), (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x l -> (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x m -> l = m)).
+      intros. subst. auto.
+      pose (N_spec p s x).
+      epose (@GN_inv_noinit_lessub _ _ _ _ _ g H2 l (UI_spec p _)). rewrite <- e1 ; auto. rewrite <- e0.
+      epose (Id_all_form _ [] _ [] []). simpl in d ; apply d.
+      (* The sequent x does not have less usable boxes than s. *)
+      assert ((forall (x : Seq) (l m : MPropF), (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x l -> (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x m -> l = m)).
+      intros. subst. auto.
+      pose (N_spec p s x).
+      assert (J5: Gimap (GUI p) (GLR_prems (nodupseq x)) (map (UI p) (GLR_prems (nodupseq x)))).
+      apply Gimap_map ; auto. intros ; apply UI_GUI ; auto.
+      epose (@GN_inv_noinit_nolessub _ _ _ _ _ g H2 n J5). rewrite <- e1 ; auto.
+ +
+       (* Proof-theoretic work. *)
+       epose (OrL (LHS,_)). simpl in g0. apply g0. clear g0.
+       epose (OrR (_,[])). simpl in g0. apply g0. epose (Id_all_form _ [] _ [] _). simpl in d ; apply d.
+       apply g0. clear g0. epose (OrR (_,[])). simpl in g0. apply g0.
+       pose (@GLS_prv_wkn_R (list_disj (map Neg (restr_list_prop p (fst x))) :: LHS, [Or (list_disj (map Neg (restr_list_prop p (fst x)))) (list_disj (map Box (map (UI p) (GLR_prems (nodupseq x)))))])).
+       apply g1 with (A:=list_disj (restr_list_prop p (snd x))). clear g1. apply g0. epose (Id_all_form _ [] _ [] _). simpl in d ; apply d.
+       epose (wkn_RI _ _ []). simpl in w. apply w.
+       apply g0. clear g0. epose (OrR (_,[])). simpl in g0. apply g0.
+       pose (@GLS_prv_wkn_R (list_disj (map Box (map (UI p) (GLR_prems (nodupseq x)))) :: LHS, [Or (list_disj (map Neg (restr_list_prop p (fst x)))) (list_disj (map Box (map (UI p) (GLR_prems (nodupseq x)))))])).
+       apply g1 with (A:=list_disj (restr_list_prop p (snd x))). clear g1. apply g0.
+       pose (@GLS_prv_wkn_R (list_disj (map Box (map (UI p) (GLR_prems (nodupseq x)))) :: LHS, [(list_disj (map Box (map (UI p) (GLR_prems (nodupseq x)))))])).
+       apply g1 with (A:=list_disj (map Neg (restr_list_prop p (fst x)))). clear g1. clear g0.
+       epose (Id_all_form _ [] _ [] _). simpl in d ; apply d.
+       epose (wkn_RI _ _ []). simpl in w. apply w. epose (wkn_RI _ _ []). simpl in w. apply w.
+       clear g0. epose (OrR (_,[])). simpl in g0. apply g0.
+       pose (@GLS_prv_wkn_R (Diam (list_conj (map (N p x) (Canopy (nodupseq (XBoxed_list (top_boxes (fst x)), []%list))))) :: LHS, [Or (list_disj (map Neg (restr_list_prop p (fst x)))) (list_disj (map Box (map (UI p) (GLR_prems (nodupseq x)))))])).
+       apply g1 with (A:=list_disj (restr_list_prop p (snd x))). clear g1. apply g0.
+       pose (@GLS_prv_wkn_R (Diam (list_conj (map (N p x) (Canopy (nodupseq (XBoxed_list (top_boxes (fst x)), []%list))))) :: LHS, [(list_disj (map Box (map (UI p) (GLR_prems (nodupseq x)))))])).
+       apply g1 with (A:=list_disj (map Neg (restr_list_prop p (fst x)))). clear g1. clear g0.
+       2-3: epose (wkn_RI _ _ []) ; simpl in w ; apply w.
+      remember [list_disj (map Box (map (UI p) (GLR_prems (nodupseq x))))] as RHS. unfold Diam.
+      apply derI with (ps:=[([] ++ LHS, [] ++ Box (Neg (list_conj (map (N p x) (Canopy (nodupseq (XBoxed_list (top_boxes (fst x)), []%list)))))) :: RHS);
+      ([] ++ Bot :: LHS, [] ++ RHS)]).
+      apply ImpL. apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+      2: apply derI with (ps:=[]) ; [apply BotL ; apply BotLRule_I | apply dlNil].
+      apply derI with (ps:=[(XBoxed_list (top_boxes LHS) ++ [Box (Neg (list_conj (map (N p x) (Canopy (nodupseq (XBoxed_list (top_boxes (fst x)), []%list))))))], [(Neg (list_conj (map (N p x) (Canopy (nodupseq (XBoxed_list (top_boxes (fst x)), []%list))))))])]).
+      apply GLR. apply GLRRule_I.
+      intro. intros. subst. simpl in H4. repeat rewrite top_boxes_distr_app in H4. simpl in H4.
+      inversion H4. symmetry in H5 ; eexists ; apply H5. apply in_app_or in H5. destruct H5.
+      apply in_top_boxes in H5. destruct H5. destruct s0 ; auto. destruct s0. destruct p0. exists x0 ; rewrite <- e ; auto.
+      simpl in H5. destruct H5. symmetry in H5 ; eexists ; apply H5. inversion H5.
+      simpl. apply top_boxes_nobox_gen_ext. apply dlCons. 2: apply dlNil. subst. simpl.
+      pose (@GLS_prv_list_wkn_L [Neg (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))))] []
+      [Neg (list_conj (map (N p x) (Canopy (nodupseq (XBoxed_list (top_boxes (fst x)), []%list)))))]).
+      simpl in g0.
+ +
+      assert (J20: GLS_prv ([Neg (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))))],
+      [Neg (list_conj (map (N p x) (Canopy (nodupseq (XBoxed_list (top_boxes (fst x)), []%list)))))])).
+      remember (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) as conj1. clear e0.
+      remember (list_conj (map (N p x) (Canopy (nodupseq (XBoxed_list (top_boxes (fst x)), []%list))))) as conj2.
+      apply derI with (ps:=[([conj2;Neg conj1], [Bot])]). apply ImpR. epose (ImpRRule_I _ _ [] _ [] []). simpl in i0. apply i0.
+      apply dlCons. 2: apply dlNil.
+      apply derI with (ps:=[([conj2] , [conj1; ]);([conj2;Bot], [])]). apply ImpL. epose (ImpLRule_I _ _[conj2] [] [] [Bot]). simpl in i0.
+      apply i0. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+      2: apply derI with (ps:=[]) ; [apply BotL ; eapply (BotLRule_I [conj2] [] _) | apply dlNil]. simpl. subst.
+      pose (@GLS_prv_wkn_R ([list_conj (map (N p x) (Canopy (nodupseq (XBoxed_list (top_boxes (fst x)), []%list))))], [list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))])).
+      apply g1 with (A:=Bot). clear g1.
+      2: epose (wkn_RI Bot _ [list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))] []) ; simpl in w ; apply w.
+      epose (list_conj_R _ (_,_)). apply g1 ; clear g1 ; simpl.
+      intros A HA. apply InT_map_iff in HA. destruct HA. destruct p0 ; subst.
+ +
+      assert (PermutationTS (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)) (nodupseq (XBoxed_list (top_boxes (fst x)), []%list))).
+      unfold PermutationTS. split ; simpl. 2: apply permT_nil. apply Permutation_PermutationT.
+      apply NoDup_Permutation. 1-2: apply NoDup_nodup.
+      assert (length (usable_boxes x) < length (usable_boxes (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))) -> False).
+      intro. rewrite <- ub_nodupseq in H4. pose (leq_ub_unif s). lia.
+      assert (forall A, In A (top_boxes (fst s)) <-> In A (top_boxes (fst x))).
+      intros ; split ; intros. apply top_boxes_diam_jump in H5 ; auto.
+      pose (top_boxes_Canopy_noless_ub _ _ i H4). simpl in p0 ; destruct p0. destruct p0.
+      destruct p0. apply i4. rewrite <- nodup_top_boxes. apply nodup_In. auto.
+      pose (leq_ub_unif s). inversion l ; auto ; subst. exfalso. rewrite <- ub_nodupseq in H4.
+      pose (leq_ub_Canopy _ _ i). rewrite <- ub_nodupseq in l0. lia.
+      apply top_boxes_diam_jump ; auto. pose (leq_ub_unif s). inversion l ; auto ; subst. exfalso. rewrite <- ub_nodupseq in H4.
+      pose (leq_ub_Canopy _ _ i). rewrite <- ub_nodupseq in l0. lia.
+      pose (top_boxes_Canopy_noless_ub _ _ i H4). simpl in p0 ; destruct p0. destruct p0.
+      destruct p0. apply i3 in H5. rewrite <- nodup_top_boxes in H5. apply nodup_In in H5. auto.
+      intros. split ; intro ; apply nodup_In ; apply nodup_In in H6.
+      apply In_XBoxed_list in H6. destruct H6. apply list_preserv_XBoxed_list ; apply H5 ; auto.
+      destruct H6. destruct H6 ; subst. apply XBoxed_list_In. apply H5 ; auto.
+      apply In_XBoxed_list in H6. destruct H6. apply list_preserv_XBoxed_list ; apply H5 ; auto.
+      destruct H6. destruct H6 ; subst. apply XBoxed_list_In. apply H5 ; auto.
+      pose (PermutationTS_Canopy _ _ H4 _ i0). destruct s0. destruct p0.
+      epose (list_conj_wkn_L _ (_,_) (N p x x1)). apply g1 ; clear g1 ; simpl.
+      apply InT_map_iff. exists x1 ; split ; auto.
+ +
+      assert (J80: length (usable_boxes s) = length (usable_boxes x)).
+      pose (leq_ub_unif s). pose (leq_ub_Canopy _ _ i). rewrite <- ub_nodupseq in l0. lia.
+ +
+    (* Massage the Ns. *)
+    destruct (dec_init_rules x0).
+    (* The sequents x1 and x0 is initial. *)
+     assert (is_init x0) ; auto.
+     pose (N_spec p s x0).
+     pose (GN_inv_init _ g1). rewrite <- e ; auto.
+     epose (TopR _ [] []). simpl in g2 ; apply g2.
+    (* The sequent x is not initial. *)
+     assert (is_init x0 -> False) ; auto.
+     assert (is_init x1 -> False). intro. apply H5. apply (PermutationTS_is_init _ _ (PermutationTS_sym _ _ p0) X0).
+     assert (J20: GUI p x0 (UI p x0)). apply UI_GUI ; auto.
+     assert (J30: GUI p x1 (UI p x1)). apply UI_GUI ; auto.
+     pose (Canopy_critical _ _ i0).
+     pose (Canopy_critical _ _ i1).
+     destruct (Compare_dec.lt_dec (length (usable_boxes x0)) (length (usable_boxes s))).
+     (* The sequent x has less usable boxes than s. *)
+     pose (N_spec p s x0).
+     epose (@GN_inv_noinit_lessub _ _ _ _ _ g1 H5 l (UI_spec p _)). rewrite <- e ; auto.
+     assert (J40: length (usable_boxes x1) < length (usable_boxes x)). rewrite <- J80 ; auto.
+     assert (incl (usable_boxes x1) (usable_boxes x0)). intros A HA.
+     apply InT_In ; apply In_InT in HA. apply (PermutationTS_usable_boxes _ _ (PermutationTS_sym _ _ p0)) ; auto.
+     pose (NoDup_incl_length (NoDup_usable_boxes x1) H7).
+     assert (incl (usable_boxes x0) (usable_boxes x1)). intros A HA.
+     apply InT_In ; apply In_InT in HA. apply (PermutationTS_usable_boxes _ _ p0) ; auto.
+     pose (NoDup_incl_length (NoDup_usable_boxes x0) H8). lia.
+     pose (N_spec p x x1).
+     epose (@GN_inv_noinit_lessub _ _ _ _ _ g2 H6 J40 (UI_spec p _)). rewrite <- e0 ; auto.
+     apply PermutationTS_UI ; apply PermutationTS_sym ; auto.
+     (* The sequent x does not have less usable boxes than s. *)
+     pose (N_spec p s x0).
+     assert (J41: Gimap (GUI p) (GLR_prems (nodupseq x0)) (map (UI p) (GLR_prems (nodupseq x0)))).
+     apply Gimap_map ; auto. intros ; apply UI_GUI ; auto.
+     epose (@GN_inv_noinit_nolessub _ _ _ _ _ g1 H5 n0 J41). rewrite <- e ; auto.
+     assert (J42: (length (usable_boxes x1) < length (usable_boxes x)) -> False). rewrite <- J80.
+     assert (incl (usable_boxes x1) (usable_boxes x0)). intros A HA.
+     apply InT_In ; apply In_InT in HA. apply (PermutationTS_usable_boxes _ _ (PermutationTS_sym _ _ p0)) ; auto.
+     pose (NoDup_incl_length (NoDup_usable_boxes x1) H7).
+     assert (incl (usable_boxes x0) (usable_boxes x1)). intros A HA.
+     apply InT_In ; apply In_InT in HA. apply (PermutationTS_usable_boxes _ _ p0) ; auto.
+     pose (NoDup_incl_length (NoDup_usable_boxes x0) H8). lia.
+     pose (N_spec p x x1).
+     assert (J43: Gimap (GUI p) (GLR_prems (nodupseq x1)) (map (UI p) (GLR_prems (nodupseq x1)))).
+     apply Gimap_map ; auto. intro ; apply UI_GUI ; auto.
+     epose (@GN_inv_noinit_nolessub _ _ _ _ _ g2 H6 J42 J43). rewrite <- e0 ; auto.
+ +
+       (* Proof-theoretic work. *)
+       epose (OrL (_,_)). simpl in g3. apply g3 ; clear g3.
+       epose (OrR (_,[])). simpl in g3. apply g3 ; clear g3.
+       epose (list_disj_L _ (_,_)). simpl in g3. apply g3 ; clear g3. intros.
+       epose (list_disj_wkn_R _ (_,_) A). apply g3 ; clear g3.
+       apply PermutationTS_restr_list_prop_snd with (s:=x1) ; auto. apply PermutationTS_sym ; auto.
+       simpl. epose (Id_all_form _ [] _ [] _). simpl in d ; apply d.
+       epose (OrL (_,_)). simpl in g3. apply g3 ; clear g3.
+       epose (OrR (_,[])). simpl in g3. apply g3 ; clear g3.
+       pose (@GLS_prv_wkn_R ([list_disj (map Neg (restr_list_prop p (fst x1)))],[Or (list_disj (map Neg (restr_list_prop p (fst x0)))) (list_disj (map Box (map (UI p) (GLR_prems (nodupseq x0)))))])).
+       apply g3 with (A:=list_disj (restr_list_prop p (snd x0))). clear g3.
+       2: epose (wkn_RI _ _ []) ; simpl in w ; apply w.
+       epose (OrR (_,[])). simpl in g3. apply g3 ; clear g3.
+       epose (list_disj_L _ (_,_)). simpl in g3. apply g3 ; clear g3. intros.
+       epose (list_disj_wkn_R _ (_,_) A). apply g3 ; clear g3.
+       apply InT_map_iff. apply InT_map_iff in H7. destruct H7. destruct p1 ; subst.
+       exists x2 ; split ; auto.
+       apply PermutationTS_restr_list_prop_fst with (s:=x1) ; auto. apply PermutationTS_sym ; auto.
+       simpl. epose (Id_all_form _ [] _ [] _). simpl in d ; apply d.
+       epose (OrR (_,[])). simpl in g3. apply g3 ; clear g3.
+       pose (@GLS_prv_wkn_R ([list_disj (map Box (map (UI p) (GLR_prems (nodupseq x1))))],[Or (list_disj (map Neg (restr_list_prop p (fst x0)))) (list_disj (map Box (map (UI p) (GLR_prems (nodupseq x0)))))])).
+       apply g3 with (A:=list_disj (restr_list_prop p (snd x0))). clear g3.
+       2: epose (wkn_RI _ _ []) ; simpl in w ; apply w.
+       epose (OrR (_,[])). simpl in g3. apply g3 ; clear g3.
+       pose (@GLS_prv_wkn_R ([list_disj (map Box (map (UI p) (GLR_prems (nodupseq x1))))],[(list_disj (map Box (map (UI p) (GLR_prems (nodupseq x0)))))])).
+       apply g3 with (A:=list_disj (map Neg (restr_list_prop p (fst x0)))). clear g3.
+       2: epose (wkn_RI _ _ []) ; simpl in w ; apply w.
+       epose (list_disj_L _ (_,_)). simpl in g3. apply g3 ; clear g3. intros.
+       apply InT_map_iff in H7. destruct H7. destruct p1 ; subst.
+       apply InT_map_iff in i2. destruct i2. destruct p1 ; subst.
+       pose (PermutationTS_GLR_prems _ _ (PermutationTS_nodupseq _ _ (PermutationTS_sym _ _ p0)) _ i2).
+       destruct s0. destruct p1.
+       epose (list_disj_wkn_R _ (_,_) (Box (UI p x2))). apply g3 ; clear g3.
+       apply InT_map_iff. exists (UI p x2) ; split ; auto.
+       apply InT_map_iff. exists x2 ; split ; auto. simpl.
+       apply derI with (ps:=[([UI p x3 ; Box (UI p x3) ; Box (UI p x2)], [UI p x2])]).
+       apply GLR. epose (@GLRRule_I _ [Box (UI p x3)] _ [] []). simpl in g3. apply g3 ; clear g3.
+       intros A HA. inversion HA ; subst. eexists ; auto. inversion H7. apply univ_gen_ext_refl.
+       apply dlCons. 2: apply dlNil.
+       pose (PermutationTS_UI _ _ p p1).
+       pose (@GLS_prv_list_wkn_L [UI p x3] [] [UI p x2] g3 [Box (UI p x3); Box (UI p x2)]). simpl in g4.
+       auto.
+ +
+      epose (GLS_prv_list_wkn_L [_] [] _ _). rewrite app_nil_r in g1 ; simpl in g1. apply g1.
+      Unshelve. apply GUI_fun. rewrite app_nil_r ; auto. } }
+  Qed.
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_Diam_UI_imp_N_prelim.html b/GL.Interpolation.UIGL_Diam_UI_imp_N_prelim.html new file mode 100644 index 0000000..4c2908e --- /dev/null +++ b/GL.Interpolation.UIGL_Diam_UI_imp_N_prelim.html @@ -0,0 +1,319 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_Diam_UI_imp_N_prelim

+ +
+  Require Import List.
+  Export ListNotations.
+  Require Import PeanoNat.
+  Require Import Lia.
+ +
+  Require Import general_export.
+ +
+  Require Import GLS_export.
+ +
+  Require Import UIGL_Def_measure.
+  Require Import UIGL_Canopy.
+  Require Import UIGL_irred_short.
+  Require Import UIGL_braga.
+  Require Import UIGL_LexSeq.
+  Require Import UIGL_nodupseq.
+  Require Import UIGL_And_Or_rules.
+  Require Import UIGL_UI_prelims.
+  Require Import UIGL_UI_inter.
+ +
+  (* Preliminary lemmas. *)
+ +
+  Lemma top_boxes_Canopy_noless_ub : forall s0 s1, InT s1 (Canopy s0) ->
+                        (length (usable_boxes s1) < length (usable_boxes s0) -> False) ->
+                        (incl (top_boxes (fst s1)) (top_boxes (fst s0))) * (incl (top_boxes (fst s0)) (top_boxes (fst s1))) *
+                        (incl (subform_boxesS s1) (subform_boxesS s0)) * (incl (subform_boxesS s0) (subform_boxesS s1)).
+  Proof.
+  intro s0. induction on s0 as IH with measure (n_imp_subformS s0).
+  intros. pose (fold_Canopy _ _ H). destruct s ; subst.
+  - assert (Canopy s0 = [s0]). apply Id_InT_Canopy ; auto. rewrite H1 in H. inversion H ; subst.
+    repeat split ; intros a K ; auto. inversion H3.
+  - destruct s. destruct p.
+    assert (n_imp_subformS x < n_imp_subformS s0).
+    unfold inv_prems in i. apply InT_flatten_list_InT_elem in i. destruct i. destruct p.
+    destruct (finite_ImpRules_premises_of_S s0). simpl in i1. apply p in i1. destruct i1.
+    inversion i1 ; subst. inversion i ; subst. 2: inversion H2.
+    unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+    inversion i1 ; subst. inversion i ; subst.
+    unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+    inversion H2 ; subst. 2: inversion H3.
+    unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+    assert ((length (usable_boxes s1) < length (usable_boxes x) -> False)).
+    intro. apply H0. unfold inv_prems in i. apply InT_flatten_list_InT_elem in i. destruct i. destruct p.
+    destruct (finite_ImpRules_premises_of_S s0). simpl in i1. apply p in i1. destruct i1.
+    inversion i1 ; subst. inversion i ; subst. apply ImpR_applic_reduces_ub_or_imp in i1. destruct i1.
+    lia. destruct p0 ; lia. inversion H4.
+    inversion i1 ; subst. inversion i ; subst. apply ImpL_applic_reduces_ub_or_imp in i1. destruct i1. destruct s.
+    lia. destruct p0 ; lia. inversion H4 ; subst. 2: inversion H5. apply ImpL_applic_reduces_ub_or_imp in i1. destruct i1.
+    destruct s0. lia. destruct p0 ; lia.
+    pose (IH _ H1 _ i0 H2).
+    assert ( length (usable_boxes x) < length (usable_boxes s0) -> False).
+    intro. apply H0. destruct p. apply leq_ub_Canopy in i0 ; lia.
+    unfold inv_prems in i. apply InT_flatten_list_InT_elem in i. destruct i. destruct p0.
+    destruct (finite_ImpRules_premises_of_S s0). simpl in i1. apply p0 in i1. destruct i1.
+    + inversion i1 ; subst ; simpl. inversion i ; subst. 2: inversion H5. simpl in p. repeat split.
+       * intros C G. apply p in G. rewrite top_boxes_distr_app ; rewrite top_boxes_distr_app in G.
+         apply in_or_app. apply in_app_or in G ; destruct G ; auto. destruct A ; simpl in H4 ; auto.
+         destruct H4 ; auto. subst. destruct (In_dec (top_boxes (Γ0 ++ Γ1)) (Box A)).
+         rewrite top_boxes_distr_app in i2 ; apply in_app_or in i2 ; auto. exfalso. apply H3.
+         unfold usable_boxes ; simpl. apply remove_list_incr_decr ; auto. 1-2: apply NoDup_subform_boxesS.
+         exists (Box A). repeat split ; auto. rewrite top_boxes_distr_app ; apply in_or_app ; simpl ; auto.
+         unfold subform_boxesS. simpl. apply remove_list_is_in. apply In_incl_subform_boxes with (A:=(Box A --> B)).
+         apply in_or_app ; right ; simpl ; auto. simpl ; auto.
+         intros a G. rewrite top_boxes_distr_app ; rewrite top_boxes_distr_app in G.
+         apply in_or_app. apply in_app_or in G ; destruct G ; auto. right. simpl ; auto.
+         unfold subform_boxesS ; simpl. intros a G. apply in_app_or in G ; destruct G.
+         rewrite subform_boxesLF_dist_app in H4. apply in_app_or in H4 ; destruct H4. apply in_or_app.
+         left ; rewrite subform_boxesLF_dist_app ; apply in_or_app ; auto. apply In_remove_list_In_list_not_In_remove_list in H4.
+         destruct H4. simpl in H4. destruct H4 ; subst. apply remove_list_is_in.
+         rewrite subform_boxesLF_dist_app. apply remove_list_is_in. simpl ; auto.
+         apply in_app_or in H4. destruct H4. apply remove_list_is_in. rewrite subform_boxesLF_dist_app.
+         apply remove_list_is_in. simpl ; right ; apply in_or_app ; left ; apply in_or_app ; auto.
+         apply in_remove in H4. destruct H4. apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4.
+         apply in_or_app ; left ; rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4. apply remove_list_is_in.
+         rewrite subform_boxesLF_dist_app in H4. apply in_app_or in H4 ; destruct H4.
+         rewrite subform_boxesLF_dist_app ; apply in_or_app ; auto. apply In_remove_list_In_list_not_In_remove_list in H4.
+         destruct H4. simpl in H4. apply in_app_or in H4 ; destruct H4.
+         rewrite subform_boxesLF_dist_app. apply remove_list_is_in ; simpl. right. apply in_or_app ; left.
+         apply in_or_app ; right ; apply in_not_touched_remove. apply not_removed_remove_list ; auto.
+         intros. apply H5. rewrite subform_boxesLF_dist_app. apply remove_list_is_in ; simpl. right. apply in_or_app ; auto.
+         intro. subst. apply H5. rewrite subform_boxesLF_dist_app. apply remove_list_is_in ; simpl ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4.
+         rewrite subform_boxesLF_dist_app. apply remove_list_is_in. assert (Box A --> B :: Δ1 = [Box A --> B] ++ Δ1).
+         auto. rewrite H8. rewrite subform_boxesLF_dist_app. apply remove_list_is_in ; auto.
+       * intros C G. apply p. rewrite top_boxes_distr_app ; rewrite top_boxes_distr_app in G.
+         apply in_or_app. apply in_app_or in G ; destruct G ; auto. right. destruct A ; simpl ; auto.
+       * intros C G. apply p in G. unfold subform_boxesS ; unfold subform_boxesS in G ; simpl ; simpl in G.
+         apply in_app_or in G ; destruct G. rewrite subform_boxesLF_dist_app in H4. apply in_app_or in H4 ; destruct H4.
+         apply in_or_app ; left ; rewrite subform_boxesLF_dist_app ; apply in_or_app ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4. simpl in H4. apply in_app_or in H4 ; destruct H4.
+         apply remove_list_is_in. rewrite subform_boxesLF_dist_app ; apply remove_list_is_in. simpl. apply in_or_app ; left ; apply in_or_app ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4.
+         apply in_or_app ; left ; rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4. apply remove_list_is_in.
+         rewrite subform_boxesLF_dist_app in H4. apply in_app_or in H4. destruct H4.
+         rewrite subform_boxesLF_dist_app ; apply in_or_app ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4.
+         rewrite subform_boxesLF_dist_app ; apply remove_list_is_in. simpl in H4. apply in_app_or in H4.
+         destruct H4. simpl. apply in_or_app ; left. apply remove_list_is_in ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4. simpl. apply remove_list_is_in ; auto.
+       * intros C G. apply p. unfold subform_boxesS ; unfold subform_boxesS in G ; simpl ; simpl in G.
+         apply in_app_or in G ; destruct G. apply in_or_app ; left. rewrite subform_boxesLF_dist_app in H4.
+         apply in_app_or in H4 ; destruct H4. rewrite subform_boxesLF_dist_app. apply in_or_app ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4.
+         rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; simpl ; apply remove_list_is_in ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4.
+         rewrite subform_boxesLF_dist_app in H4. apply in_app_or in H4. destruct H4.
+         rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; rewrite subform_boxesLF_dist_app ; apply in_or_app ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4. simpl in H4. apply in_app_or in H4.
+         destruct H4. apply in_app_or in H4. destruct H4. apply in_or_app ; left.
+         rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; apply in_or_app ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4. apply remove_list_is_in.
+         rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; apply in_or_app ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4. apply remove_list_is_in.
+         rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; simpl ; apply remove_list_is_in ; auto.
+    + inversion i1 ; subst ; simpl ; simpl in p. inversion i ; subst ; simpl in p.
+       ++ repeat split.
+       * intros C G. apply p in G. rewrite top_boxes_distr_app ; rewrite top_boxes_distr_app in G.
+         apply in_or_app. apply in_app_or in G ; destruct G ; auto.
+       * intros C G. apply p. rewrite top_boxes_distr_app ; rewrite top_boxes_distr_app in G.
+         apply in_or_app. apply in_app_or in G ; destruct G ; auto.
+       * intros C G. apply p in G. unfold subform_boxesS ; unfold subform_boxesS in G ; simpl ; simpl in G.
+         apply in_app_or in G ; destruct G. rewrite subform_boxesLF_dist_app in H4. apply in_app_or in H4 ; destruct H4.
+         apply in_or_app ; left ; rewrite subform_boxesLF_dist_app ; apply in_or_app ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4.
+         apply in_or_app ; left ; rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; simpl ; apply remove_list_is_in ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4.
+         rewrite subform_boxesLF_dist_app in H4. apply in_app_or in H4. destruct H4.
+         apply remove_list_is_in ; rewrite subform_boxesLF_dist_app ; apply in_or_app ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4. simpl in H4. apply in_app_or in H4 ; destruct H4.
+         apply in_or_app ; left ; rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; simpl ; apply in_or_app ; left ; apply in_or_app ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4.
+         rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; auto.
+       * intros C G. apply p. unfold subform_boxesS ; unfold subform_boxesS in G ; simpl ; simpl in G.
+         apply in_app_or in G ; destruct G. rewrite subform_boxesLF_dist_app in H4.
+         apply in_app_or in H4 ; destruct H4. apply in_or_app ; left. rewrite subform_boxesLF_dist_app. apply in_or_app ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4. simpl in H4. apply in_app_or in H4.
+         destruct H4. apply in_app_or in H4. destruct H4.
+         rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ;
+         apply in_or_app ; auto. apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4.
+         destruct (In_dec (subform_boxesLF (Γ0 ++ Γ1) ++ remove_list (subform_boxesLF (Γ0 ++ Γ1)) (subform_boxesLF (Δ0 ++ A :: Δ1))) C) ; auto.
+         exfalso. apply H3. unfold usable_boxes ; simpl. repeat rewrite top_boxes_distr_app ; simpl.
+         apply remove_list_incr_decr4 ; auto. 1-2: apply NoDup_subform_boxesS. unfold subform_boxesS ; simpl.
+         intros a G. apply in_app_or in G ; destruct G. rewrite subform_boxesLF_dist_app in H7. apply in_app_or in H7 ; destruct H7.
+         apply in_or_app ; left ; rewrite subform_boxesLF_dist_app ; apply in_or_app ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H7. destruct H7. apply in_or_app ; left.
+         rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; apply remove_list_is_in ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H7. destruct H7. rewrite subform_boxesLF_dist_app in H7.
+         apply in_app_or in H7. destruct H7. apply remove_list_is_in ; rewrite subform_boxesLF_dist_app ; apply in_or_app ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H7. destruct H7. simpl in H7.
+         apply in_app_or in H7. destruct H7. apply in_or_app ; left ; rewrite subform_boxesLF_dist_app ; apply remove_list_is_in.
+         simpl. apply in_or_app ; left ; apply in_or_app ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H7. destruct H7.
+         rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; auto.
+         intro. assert (In C (subform_boxesS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1))). unfold subform_boxesS ; simpl. apply in_or_app ; left.
+         apply In_incl_subform_boxes with (A:=A --> B). apply in_or_app ; simpl ; auto. simpl. apply remove_list_is_in ; auto.
+         apply H7 in H8. unfold subform_boxesS in H8 ; simpl in H8. auto.
+         exists C. repeat split. unfold subform_boxesS ; simpl. apply in_or_app ; left.
+         apply In_incl_subform_boxes with (A:=A --> B). apply in_or_app ; simpl ; auto. simpl. apply remove_list_is_in ; auto.
+         intro. apply n. apply in_or_app ; left. apply in_app_or in H7. destruct H7. rewrite subform_boxesLF_dist_app ; apply in_or_app ; left.
+         apply subform_boxesLF_top_boxes. pose (in_top_boxes _ _ H7). destruct s ; destruct s ; destruct s ; destruct p1 ; subst.
+         repeat rewrite top_boxes_distr_app ; simpl. rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; simpl ; auto.
+         rewrite subform_boxesLF_dist_app ; apply remove_list_is_in.
+         apply subform_boxesLF_top_boxes. pose (in_top_boxes _ _ H7). destruct s ; destruct s ; destruct s ; destruct p1 ; subst.
+         repeat rewrite top_boxes_distr_app ; simpl. rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; simpl ; auto.
+         unfold subform_boxesS ; simpl ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4.
+         apply in_or_app ; left. rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4.
+         rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; rewrite subform_boxesLF_dist_app.
+         rewrite subform_boxesLF_dist_app in H4. apply in_app_or in H4. destruct H4. apply in_or_app ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4. apply remove_list_is_in ; apply remove_list_is_in ; auto.
+       ++ inversion H5 ; subst ; simpl in p. 2: inversion H6. repeat split.
+       * intros C G. apply p in G. rewrite top_boxes_distr_app ; rewrite top_boxes_distr_app in G.
+         apply in_or_app. apply in_app_or in G ; destruct G ; auto. simpl. destruct B ; simpl in H4 ; auto.
+         destruct H4 ; subst ; auto. destruct (In_dec (top_boxes (Γ0 ++ Γ1)) (Box B)). rewrite top_boxes_distr_app in i2 ; apply in_app_or in i2 ; auto.
+         exfalso. apply H3. unfold usable_boxes ; simpl. repeat rewrite top_boxes_distr_app ; simpl.
+         apply remove_list_incr_decr ; auto. 1-2: apply NoDup_subform_boxesS.
+         exists (Box B). repeat split. apply in_or_app ; simpl ; auto. unfold subform_boxesS ; simpl.
+         rewrite subform_boxesLF_dist_app ; apply in_or_app ; left ; apply remove_list_is_in ; simpl ; apply in_or_app ; left ; apply remove_list_is_in ; apply in_eq.
+         rewrite top_boxes_distr_app in n ; auto.
+         intros a G. apply in_app_or in G ; apply in_or_app ; simpl ; destruct G ; auto.
+         unfold subform_boxesS ; simpl.
+         intros a G. apply in_app_or in G ; destruct G. rewrite subform_boxesLF_dist_app in H4. apply in_app_or in H4 ; destruct H4.
+         apply in_or_app ; left ; rewrite subform_boxesLF_dist_app ; apply in_or_app ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4. simpl in H4 ; destruct H4 ; subst. apply in_or_app ; left.
+         rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; simpl ; apply in_or_app ; left ; apply remove_list_is_in ; apply in_eq.
+         apply in_app_or in H4 ; destruct H4. apply in_or_app ; left.
+         rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; simpl ; apply in_or_app ; left ; apply remove_list_is_in ; apply in_cons ; auto.
+         apply in_remove in H4. destruct H4.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4. apply in_or_app ; left.
+         rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; apply remove_list_is_in ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4. apply remove_list_is_in ; auto.
+       * intros C G. apply p. rewrite top_boxes_distr_app ; rewrite top_boxes_distr_app in G ; simpl in G.
+         apply in_or_app. apply in_app_or in G ; destruct G ; auto. simpl. destruct B ; auto. right ; apply in_cons ; auto.
+       * intros C G. apply p in G. unfold subform_boxesS ; unfold subform_boxesS in G ; simpl ; simpl in G.
+         apply in_app_or in G ; destruct G. rewrite subform_boxesLF_dist_app in H4. apply in_app_or in H4 ; destruct H4.
+         apply in_or_app ; left ; rewrite subform_boxesLF_dist_app ; apply in_or_app ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4. apply in_or_app ; left. simpl in H4 ; apply in_app_or in H4 ; destruct H4.
+         rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; simpl ; apply in_or_app ; left ; apply remove_list_is_in ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4.
+         rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; simpl ; apply remove_list_is_in ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4. apply remove_list_is_in ; auto.
+       * intros C G. apply p. unfold subform_boxesS ; unfold subform_boxesS in G ; simpl ; simpl in G.
+         apply in_app_or in G ; destruct G. rewrite subform_boxesLF_dist_app in H4. apply in_app_or in H4 ; destruct H4.
+         apply in_or_app ; left ; rewrite subform_boxesLF_dist_app ; apply in_or_app ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4. simpl in H4 ; apply in_app_or in H4 ; destruct H4.
+         apply in_app_or in H4 ; destruct H4. destruct (In_dec (subform_boxesLF (Γ0 ++ B :: Γ1) ++ remove_list (subform_boxesLF (Γ0 ++ B :: Γ1)) (subform_boxesLF (Δ0 ++ Δ1))) C) ; auto.
+ +
+         exfalso. apply H3. unfold usable_boxes ; simpl. repeat rewrite top_boxes_distr_app. simpl (top_boxes (A --> B :: Γ1)).
+         assert (length (remove_list (top_boxes Γ0 ++ top_boxes (B :: Γ1)) (subform_boxesS (Γ0 ++ B :: Γ1, Δ0 ++ Δ1))) <=
+         length (remove_list (top_boxes Γ0 ++ top_boxes Γ1) (subform_boxesS (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)))).
+         destruct B ; simpl ; auto. apply remove_list_incr_decr3 ; auto. intros a G. apply in_or_app ; simpl ; apply in_app_or in G ; destruct G ; auto.
+         assert (length (remove_list (top_boxes Γ0 ++ top_boxes Γ1) (subform_boxesS (Γ0 ++ B :: Γ1, Δ0 ++ Δ1))) <
+         length (remove_list (top_boxes Γ0 ++ top_boxes Γ1) (subform_boxesS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)))).
+         apply remove_list_incr_decr4 ; auto. 1-2: apply NoDup_subform_boxesS.
+         intros a G. unfold subform_boxesS ; simpl ; unfold subform_boxesS in G ; simpl in G. apply in_app_or in G ; destruct G.
+         apply in_or_app ; left. rewrite subform_boxesLF_dist_app in H8 ; apply in_app_or in H8 ; destruct H8.
+         rewrite subform_boxesLF_dist_app ; apply in_or_app ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H8. destruct H8. simpl in H8 ; apply in_app_or in H8 ; destruct H8.
+         rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; simpl ; apply in_or_app ; left ; apply remove_list_is_in ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H8. destruct H8.
+         rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; apply remove_list_is_in ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H8. destruct H8. apply remove_list_is_in ; auto.
+         intro. apply n. apply H8. unfold subform_boxesS ; simpl. apply in_or_app ; left.
+         rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; simpl ; apply in_or_app ; left ; apply in_or_app ; auto.
+         exists (C). repeat split. unfold subform_boxesS ; simpl. apply in_or_app ; left.
+         rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; simpl ; apply in_or_app ; left ; apply in_or_app ; auto.
+         intro. apply n. apply in_or_app ; left. apply subform_boxesLF_top_boxes. assert (In C (top_boxes (Γ0 ++ B :: Γ1))).
+         repeat rewrite top_boxes_distr_app. apply in_or_app ; apply in_app_or in H8 ; destruct H8 ; auto. right. destruct B ; simpl ; auto.
+         pose (in_top_boxes _ _ H9). destruct s ; destruct s ; destruct s ; destruct p1 ; subst. rewrite e0.
+         repeat rewrite top_boxes_distr_app ; simpl. rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; simpl ; auto. auto.
+         lia.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4.
+         apply in_or_app ; left ; rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; apply in_or_app ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4.
+         apply in_or_app ; left ; rewrite subform_boxesLF_dist_app ; apply remove_list_is_in ; apply remove_list_is_in ; auto.
+         apply In_remove_list_In_list_not_In_remove_list in H4. destruct H4. apply remove_list_is_in ; auto.
+  Qed.
+ +
+  Lemma noless_ub_incl_subform_boxesS : forall s,
+              (length (usable_boxes (XBoxed_list (top_boxes (fst s)), []%list)) < length (usable_boxes s) -> False) ->
+              incl (subform_boxesS s) (subform_boxesS (XBoxed_list (top_boxes (fst s)), []%list)).
+  Proof.
+  intros s H. unfold subform_boxesS ; simpl. intros A H0. rewrite remove_list_of_nil. rewrite app_nil_r.
+  apply InT_In. pose (InT_dec (subform_boxesLF (XBoxed_list (top_boxes (fst s)))) A).
+  destruct s0 ; auto. exfalso. apply H. destruct s.
+  simpl. simpl in f. simpl in H0. simpl in H. unfold usable_boxes. simpl. unfold subform_boxesS. simpl.
+  rewrite remove_list_of_nil. rewrite app_nil_r.
+ +
+  assert (length (remove_list (top_boxes l) (subform_boxesLF (XBoxed_list (top_boxes l)))) <
+  length (remove_list (top_boxes l) (subform_boxesLF l ++ remove_list (subform_boxesLF l) (subform_boxesLF l0)))).
+  apply remove_list_incr_decr4 ; simpl. apply NoDup_subform_boxesLF. apply add_remove_list_preserve_NoDup.
+  1-2: apply NoDup_subform_boxesLF.
+  intro. intros. apply in_or_app ; left.
+  pose (XBoxed_list_same_subform_boxes (top_boxes l)). apply a0 in H1. apply In_subform_boxes in H1. destruct H1.
+  destruct H1. apply In_incl_subform_boxes with (A:=x). apply top_boxes_incl_list ; auto. auto.
+  intro. apply f. apply In_InT ; auto.
+  exists A. repeat split ; auto. intro. apply f. apply In_InT. apply In_incl_subform_boxes with (A:=A).
+  apply list_preserv_XBoxed_list ; auto. apply in_top_boxes in H1. destruct H1. destruct s. destruct s.
+  destruct p. subst ; simpl ; auto. intro ; apply f ; apply In_InT ; auto.
+ +
+  assert (length (remove_list (top_boxes (XBoxed_list (top_boxes l))) (subform_boxesLF (XBoxed_list (top_boxes l)))) <=
+  length (remove_list (top_boxes l) (subform_boxesLF (XBoxed_list (top_boxes l))))).
+  apply remove_list_incr_decr3 ; simpl.
+  intro. intros. pose (XBoxed_list_same_subform_boxes (top_boxes l)). apply is_box_in_top_boxes.
+  apply list_preserv_XBoxed_list ; auto. apply in_top_boxes in H2. destruct H2. destruct s. destruct s.
+  destruct p ; subst ; eexists ; auto.
+  lia.
+  Qed.
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_LexSeq.html b/GL.Interpolation.UIGL_LexSeq.html new file mode 100644 index 0000000..ecab28d --- /dev/null +++ b/GL.Interpolation.UIGL_LexSeq.html @@ -0,0 +1,262 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_LexSeq

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat.
+Require Import Lia.
+ +
+Require Import general_export.
+ +
+Require Import GLS_export.
+ +
+Require Import UIGL_Def_measure.
+Require Import UIGL_Canopy.
+Require Import UIGL_irred_short.
+ +
+  Section LogDefinition.
+ +
+  (* Below is the measure which can be used to prove termination of
+      the Fixpoint UI (order used: lexicographic on pairs of natural numbers). *)

+ +
+  Definition measure (s : Seq) := [(length (usable_boxes s)) ; (n_imp_subformS s)].
+ +
+  (* List of all premises through the GLR rule for a sequent s.
+      Note that GLR is not invertible. *)

+ +
+  Definition GLR_prems (s : Seq) := flatten_list (proj1_sigT2 (finite_GLR_premises_of_S s)).
+ +
+  (* Property of being an initial sequent. *)
+ +
+  Definition is_init s : Type := (IdPRule [] s) + (IdBRule [] s) + (BotLRule [] s).
+ +
+  End LogDefinition.
+ +
+  Section LexSeq_ind.
+ +
+  Definition LexSeq := fun s0 s1 => (less_thanS s0 s1).
+ +
+  Lemma wf_LexSeq : well_founded LexSeq.
+  Proof.
+  unfold LexSeq. apply less_thanS_wf.
+  Qed.
+ +
+  Variable (P : Seq -> Type).
+ +
+  Definition LexSeq_ind : (forall s0, (forall s1, LexSeq s1 s0 -> P s1) -> P s0) -> (forall s, P s).
+  Proof.
+  intros. induction s as [ s0 IHs0 ] using (well_founded_induction_type wf_LexSeq).
+  apply X; intros; apply IHs0 ; auto.
+  Defined.
+ +
+  End LexSeq_ind.
+ +
+  Section LexSeq_properties.
+ +
+  Theorem LexSeq_trans : forall x y z, LexSeq x y -> LexSeq y z -> LexSeq x z.
+  Proof.
+  unfold LexSeq. apply less_thanS_trans.
+  Qed.
+ +
+  Lemma inv_prems_LexSeq : forall s0 s1, InT s1 (inv_prems s0) -> LexSeq s1 s0.
+  Proof.
+  intros. unfold inv_prems in H. apply InT_flatten_list_InT_elem in H.
+  destruct H. destruct p. destruct (finite_ImpRules_premises_of_S s0). simpl in i0.
+  apply p in i0. destruct i0 ; inversion i0 ; subst. inversion i ; subst. unfold LexSeq.
+  apply ImpR_applic_reduces_measure ; auto. inversion H0.
+  unfold LexSeq. destruct (ImpL_applic_reduces_measure i0).
+  inversion i ; subst ; auto. inversion H0 ; subst ; auto. inversion H1.
+  Qed.
+ +
+  Lemma GLR_prems_LexSeq : forall s0 s1, (IdBRule [] s0 -> False) ->
+            InT s1 (GLR_prems s0) -> LexSeq s1 s0.
+  Proof.
+  intros s0 s1 H0 H. unfold GLR_prems in H. apply InT_flatten_list_InT_elem in H.
+  destruct H. destruct p. destruct (finite_GLR_premises_of_S s0). simpl in i0.
+  apply p in i0. inversion i0 ; subst. unfold LexSeq. apply GLR_applic_reduces_measure ; auto.
+  inversion i ; subst ; auto. inversion H2.
+  Qed.
+ +
+  Lemma GLR_prems_less_ub : forall s0 s1, (IdBRule [] s0 -> False) ->
+            InT s1 (GLR_prems s0) -> (length (usable_boxes s1) < length (usable_boxes s0)).
+  Proof.
+  intros s0 s1 H0 H. unfold GLR_prems in H. apply InT_flatten_list_InT_elem in H.
+  destruct H. destruct p. destruct (finite_GLR_premises_of_S s0). simpl in i0.
+  apply p in i0. inversion i0 ; subst. apply GLR_applic_less_usable_boxes in i0 ; auto.
+  inversion i ; subst ; auto. inversion H2.
+  Qed.
+ +
+  Lemma top_boxes_XBoxed_list : forall l, incl (top_boxes l) (top_boxes (XBoxed_list (top_boxes l))).
+  Proof.
+  induction l ; intro ; intros ; auto. destruct a ; simpl ; simpl in H ; auto. destruct H. subst.
+  destruct a ; auto. 1-3: apply in_eq. apply in_cons ; apply in_eq. destruct a ; auto. all: apply in_cons ; auto.
+  apply in_cons ; auto.
+  Qed.
+ +
+  Lemma subform_boxesLF_top_boxes : forall l a, In a (subform_boxesLF (top_boxes l)) -> In a (subform_boxesLF l).
+  Proof.
+  induction l ; simpl ; intros ; auto. destruct a ; simpl ; auto. apply remove_list_is_in. auto.
+  simpl in H. destruct H ; auto. right. apply in_app_or in H. apply in_or_app. destruct H ; auto.
+  right. apply in_not_touched_remove. 2: apply In_remove_diff in H ; auto.
+  apply In_remove_In_list in H. apply not_removed_remove_list.
+  apply In_remove_list_In_list in H ; auto. intro. apply remove_list_cont in H ; auto.
+  Qed.
+ +
+  Lemma leq_ub_unif : forall s, (length (usable_boxes (XBoxed_list (top_boxes (fst s)), []))) <= (length (usable_boxes s)).
+  Proof.
+  intros. destruct s. simpl. unfold usable_boxes. simpl.
+  assert (J0: incl (top_boxes l) (top_boxes (XBoxed_list (top_boxes l)))). apply top_boxes_XBoxed_list.
+  pose (remove_list_incr_decr3 (subform_boxesS (XBoxed_list (top_boxes l), []%list)) _ _ J0).
+  assert (J1: NoDup (subform_boxesS (XBoxed_list (top_boxes l), []%list))). apply NoDup_subform_boxesS.
+  assert (J2: NoDup (subform_boxesS (l, l0))). apply NoDup_subform_boxesS.
+  assert (J3: incl (subform_boxesS (XBoxed_list (top_boxes l), []%list)) (subform_boxesS (l, l0))).
+  intro ; intros. unfold subform_boxesS. simpl. unfold subform_boxesS in H. simpl in H.
+  rewrite remove_list_of_nil in H. rewrite app_nil_r in H. apply in_or_app ; left.
+  apply XBoxed_list_same_subform_boxes with (l:=(top_boxes l)) in H.
+  apply subform_boxesLF_top_boxes ; auto.
+  pose (remove_list_incr_decr2 _ _ (top_boxes l) J1 J2 J3). lia.
+  Qed.
+ +
+  Lemma Canopy_nil : forall s0, (inv_prems s0 = []) -> (forall s1, InT s1 (Canopy s0) -> s1 = s0).
+  Proof.
+  intros. assert (Canopy s0 = [s0]). apply irred_nil. unfold inv_prems. unfold inv_prems in H. auto.
+  rewrite H1 in H0. inversion H0. subst. auto. inversion H3.
+  Qed.
+ +
+  Lemma Canopy_LexSeq: forall s0 s1, InT s1 (Canopy s0) -> ((s0 = s1) + (LexSeq s1 s0)).
+  Proof.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  intros. remember (finite_ImpRules_premises_of_S s) as H0. destruct H0. destruct x.
+  - left. assert (Canopy s = [s]). apply irred_nil. unfold inv_prems ; rewrite <- HeqH0 ; auto.
+    rewrite H0 in H. inversion H ; subst ; auto. inversion H2.
+  - apply fold_Canopy in H. destruct H ; auto. right. destruct s0. destruct p0. apply IHs in i0.
+    destruct i0 ; subst ; auto. apply inv_prems_LexSeq in i ; auto. apply inv_prems_LexSeq in i.
+    apply (LexSeq_trans _ _ _ l0 i). unfold inv_prems in i. apply InT_flatten_list_InT_elem in i.
+    destruct i. destruct p0. rewrite <- HeqH0 in i1. simpl in i1. apply p in i1. destruct i1 ; inversion i1 ; subst.
+    inversion i. subst. unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+    inversion H0. inversion i ; subst. unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+    inversion H0 ; subst. unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+    inversion H1.
+  Qed.
+ +
+  Lemma leq_ub_Canopy : forall s0 s1, InT s1 (Canopy s0) ->
+                  (length (usable_boxes s1)) <= (length (usable_boxes s0)).
+  Proof.
+  intros s0 ; induction on s0 as IHs0 with measure (n_imp_subformS s0).
+  intros. remember (finite_ImpRules_premises_of_S s0) as H0.
+  destruct H0. destruct x.
+  - assert (Canopy s0 = [s0]). apply irred_nil. unfold inv_prems. rewrite <- HeqH0.
+    simpl. auto. rewrite H0 in H. inversion H. subst. auto. inversion H2.
+  - apply fold_Canopy in H. destruct H ; auto. subst. auto.
+    destruct s. destruct p0. unfold inv_prems in i. destruct (finite_ImpRules_premises_of_S s0).
+    simpl in i. apply InT_flatten_list_InT_elem in i. destruct i. destruct p1.
+    apply p0 in i1.
+    assert ((length (usable_boxes x0) <= length (usable_boxes s0)) * ((n_imp_subformS x0) < (n_imp_subformS s0))).
+    destruct i1. inversion i1 ; subst. apply ImpR_applic_reduces_ub_or_imp in i1. destruct i1.
+    inversion i ; subst. split ; try lia. unfold n_imp_subformS ; simpl.
+    repeat rewrite n_imp_subformLF_dist_app ; simpl ; repeat rewrite n_imp_subformLF_dist_app. lia.
+    inversion H0. destruct p1. inversion i ; subst. split ; try lia. inversion H0.
+    inversion i1 ; subst. inversion i ; subst. apply ImpL_applic_reduces_ub_or_imp in i1. destruct i1.
+    destruct s. split ; try lia. unfold n_imp_subformS ; simpl.
+    repeat rewrite n_imp_subformLF_dist_app ; simpl ; repeat rewrite n_imp_subformLF_dist_app. lia.
+    destruct p1 ; split ; try lia. inversion H0 ; subst. 2: inversion H1.
+    apply ImpL_applic_reduces_ub_or_imp in i1. destruct i1.
+    destruct s0. split ; try lia. unfold n_imp_subformS ; simpl.
+    repeat rewrite n_imp_subformLF_dist_app ; simpl ; repeat rewrite n_imp_subformLF_dist_app. lia.
+    destruct p1. split ; try lia.
+    destruct H. apply IHs0 in i0 ; lia.
+  Qed.
+ +
+  End LexSeq_properties.
+ +
+  Section empty_seq.
+ +
+  Definition empty_seq_dec : forall (s: Seq), (s = ([],[])) + (s <> ([],[])).
+  Proof.
+  intros. destruct s. destruct l ; destruct l0 ; auto.
+  all: right ; intro H ; inversion H.
+  Defined.
+ +
+  Lemma not_init_empty_seq : is_init ([],[]) -> False.
+  Proof.
+  intro. destruct X. destruct s. 1-2: inversion i ; destruct Γ0 ; inversion H.
+  inversion b ; subst. destruct Γ0 ; inversion H.
+  Qed.
+ +
+  Lemma critical_empty_seq : critical_Seq ([],[]).
+  Proof.
+  intros A HA ; simpl in *. inversion HA.
+  Qed.
+ +
+  End empty_seq.
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_N_imp_UI.html b/GL.Interpolation.UIGL_N_imp_UI.html new file mode 100644 index 0000000..6868c7f --- /dev/null +++ b/GL.Interpolation.UIGL_N_imp_UI.html @@ -0,0 +1,258 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_N_imp_UI

+ +
+  Require Import List.
+  Export ListNotations.
+  Require Import PeanoNat.
+  Require Import Lia.
+ +
+  Require Import general_export.
+ +
+  Require Import GLS_export.
+ +
+  Require Import UIGL_Def_measure.
+  Require Import UIGL_Canopy.
+  Require Import UIGL_irred_short.
+  Require Import UIGL_braga.
+  Require Import UIGL_LexSeq.
+  Require Import UIGL_nodupseq.
+  Require Import UIGL_And_Or_rules.
+  Require Import UIGL_UI_prelims.
+  Require Import UIGL_UI_inter.
+ +
+Theorem gen_rec_UI_imp : forall s sr p X Y,
+              GLS_prv (X, (list_conj (map (N p sr) (Canopy (nodupseq s)))) --> (UI p s) :: Y).
+  Proof.
+  pose (d:=LexSeq_ind (fun (s:Seq) => forall sr p X Y,
+              GLS_prv (X, (list_conj (map (N p sr) (Canopy (nodupseq s)))) --> (UI p s) :: Y))).
+  apply d. clear d. intros s IH.
+  intros.
+  destruct (empty_seq_dec s) as [EE | DE].
+  (* s is the empty sequent. *)
+  { subst ; simpl in *. unfold nodupseq ; simpl.
+    assert ((Canopy ([], [])) = [([], [])]). apply Id_InT_Canopy ; auto.
+    apply critical_Seq_InT_Canopy ; auto. apply critical_empty_seq. rewrite H ; simpl.
+    assert (GUI p ([],[]) Bot). apply GUI_empty_seq ; auto. apply UI_GUI in H0.
+    rewrite H0 in *. pose critical_empty_seq. pose not_init_empty_seq.
+    unfold N. destruct (N_pwc p sr ([], [])). simpl.
+    assert ((forall (x : Seq) (l m : MPropF), (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x l -> (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x m -> l = m)).
+    intros. subst. auto.
+    assert (J11: Gimap (GUI p) (GLR_prems (nodupseq ([],[]))) (map (UI p) (GLR_prems (nodupseq ([],[]))))).
+    apply Gimap_map. intros. apply UI_GUI ; auto.
+    assert (J41: Gimap (GUI p) (GLR_prems (nodupseq (nodupseq ([],[])))) (map (UI p) (GLR_prems (nodupseq (nodupseq ([],[])))))).
+    apply Gimap_map. intros. apply UI_GUI ; auto.
+    destruct (Compare_dec.lt_dec (length (usable_boxes ([],[]))) (length (usable_boxes sr))).
+    + assert (J0: GUI p (nodupseq ([],[])) (UI p (nodupseq ([],[])))). apply UI_GUI ; auto. apply UI_GUI in J0.
+       rewrite ub_nodupseq in l.
+       epose (GN_inv_noinit_lessub p g f l (UI_spec p _)). rewrite <- e. rewrite H0.
+       apply derI with (ps:=[([] ++ (And Bot Top) :: X, [] ++ Bot :: Y)]). apply ImpR. apply ImpRRule_I.
+       apply dlCons. 2: apply dlNil. simpl.
+       pose (AndL (X, Bot :: Y) Bot Top). simpl in g0. apply g0. clear g0.
+       apply derI with []. 2: apply dlNil. apply BotL ; apply (BotLRule_I []).
+    + rewrite ub_nodupseq in n. pose (GN_inv_noinit_nolessub _ g f n J41). rewrite <- e. clear e. simpl.
+        unfold nodupseq in * ; simpl in *. destruct (GLR_prems ([], [])) eqn:E; simpl.
+        { apply derI with (ps:=[([] ++ (And (Or (Or )) Top) :: X, [] ++ Bot :: Y)]). apply ImpR. apply ImpRRule_I.
+          apply dlCons. 2: apply dlNil. simpl.
+          pose (AndL (X, Bot :: Y) (Or (Or )) Top). simpl in g0. apply g0. clear g0.
+          pose (OrL (Top :: X, :: Y)). simpl in g0. apply g0 ; clear g0.
+          apply derI with []. 2: apply dlNil. apply BotL ; apply (BotLRule_I []).
+          pose (OrL (Top :: X, :: Y)). simpl in g0. apply g0 ; clear g0.
+          all: apply derI with [] ; [apply BotL ; apply (BotLRule_I []) | apply dlNil]. }
+        { exfalso. unfold GLR_prems in E. destruct (finite_GLR_premises_of_S ([], [])).
+           simpl in *. destruct x0. simpl in E. inversion E. simpl in E. pose (p0 l0).
+           destruct p1. assert (InT l0 (l0 :: x0)). apply InT_eq. apply g0 in H2. inversion H2.
+           destruct Δ0 ; subst ; inversion H6. } }
+  (* s is not the empty sequent. *)
+  { destruct (critical_Seq_dec s).
+  (* If s is critical. *)
+  - assert ((Canopy (nodupseq s)) = [nodupseq s]). apply Id_InT_Canopy ; auto.
+    apply critical_Seq_InT_Canopy ; auto. apply critical_nodupseq in c ; auto.
+    destruct (dec_init_rules s).
+    (* If s is initial. *)
+    * assert (is_init s). auto.
+      assert (J0: GUI p s (UI p s)). apply UI_GUI ; auto.
+      pose (@GUI_inv_critic_init p s (UI p s) J0 c X0). rewrite <- e. rewrite H. simpl. unfold N.
+      destruct (N_pwc p sr (nodupseq s)).
+      simpl. assert (is_init (nodupseq s)). pose (is_init_nodupseq s) ; destruct p0 ; auto. pose (GN_inv_init _ g).
+      apply derI with (ps:=[([] ++ And x Top :: X, [] ++ Top :: Y)]).
+      apply ImpR. apply ImpRRule_I. apply dlCons. 2: apply dlNil. simpl.
+      epose (TopR _ []). simpl in g0 ; apply g0.
+    (* If s is not initial. *)
+    * rewrite H. simpl. unfold N.
+      destruct (N_pwc p sr (nodupseq s)). simpl.
+      assert (is_init s -> False). auto.
+      assert (J40: is_init (nodupseq s) -> False). intro. apply H0. pose (is_init_nodupseq s) ; destruct p0 ; auto.
+      assert ((forall (x : Seq) (l m : MPropF), (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x l -> (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x m -> l = m)).
+      intros. subst. auto.
+      assert (J11: Gimap (GUI p) (GLR_prems (nodupseq s)) (map (UI p) (GLR_prems (nodupseq s)))).
+      apply Gimap_map. intros. apply UI_GUI ; auto.
+      assert (J41: Gimap (GUI p) (GLR_prems (nodupseq (nodupseq s))) (map (UI p) (GLR_prems (nodupseq (nodupseq s))))).
+      apply Gimap_map. intros. apply UI_GUI ; auto.
+      destruct (Compare_dec.lt_dec (length (usable_boxes s)) (length (usable_boxes sr))).
+      (* If s has less usable boxes than sr. *)
+      + assert (J0: GUI p (nodupseq s) (UI p (nodupseq s))). apply UI_GUI ; auto. apply UI_GUI in J0.
+         rewrite ub_nodupseq in l.
+         epose (GN_inv_noinit_lessub p g J40 l (UI_spec p _)). rewrite <- e.
+         apply derI with (ps:=[([] ++ (And (UI p (nodupseq s)) Top) :: X, [] ++ UI p s :: Y)]). apply ImpR. apply ImpRRule_I.
+         apply dlCons. 2: apply dlNil. simpl.
+         pose (AndL (X, UI p s :: Y) (UI p (nodupseq s)) Top). simpl in g0. apply g0. clear g0.
+         apply UI_nodupseq.
+      (* If s does not have less usable boxes than sr. *)
+      + rewrite ub_nodupseq in n. pose (GN_inv_noinit_nolessub _ g J40 n J41). rewrite <- e. clear e.
+          assert (J0: GUI p s (UI p s)). apply UI_GUI ; auto.
+          assert (J1: Gimap (GUI p) (GLR_prems (nodupseq s)) (map (UI p) (GLR_prems (nodupseq s)))). apply Gimap_map. intros.
+          apply UI_GUI ; auto.
+          assert (J2: Gimap (GN p (GUI p) s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))
+          (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))).
+          simpl. apply Gimap_map. intros. apply (N_spec p s x0).
+          assert (J42: Gimap (GN p (GUI p) s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))
+          (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))).
+          simpl. apply Gimap_map. intros. apply (N_spec p s x0).
+          pose (@GUI_inv_critic_not_init p s _ _ _ J0 c DE H0 J1 J42). rewrite <- e. clear e. simpl.
+          remember (Or (list_disj (restr_list_prop p (nodup eq_dec_form (snd s)))) (Or (list_disj (map Neg (restr_list_prop p (nodup eq_dec_form (fst s))))) (list_disj (map Box (map (UI p) (GLR_prems (nodupseq (nodupseq s)))))))) as disj1.
+          remember (Or (list_disj (restr_list_prop p (snd s))) (Or (list_disj (map Neg (restr_list_prop p (fst s))))
+          (Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq s))))) (Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))))))))
+          as disj2.
+          apply derI with (ps:=[([] ++ (And disj1 Top) :: X, [] ++ disj2 :: Y)]). apply ImpR. apply ImpRRule_I.
+          apply dlCons. 2: apply dlNil. simpl.
+          pose (AndL (X, disj2 :: Y) disj1 Top). simpl in g0. apply g0. clear g0.
+          pose (@GLS_prv_list_wkn_L [disj1] [] [disj2]).
+          pose (@GLS_prv_list_wkn_R (disj1 :: Top :: X) [disj2] []). simpl in g1. simpl in g0.
+          assert (GLS_prv (disj1 :: Top :: X, [disj2])).
+          assert (GLS_prv ([disj1], [disj2])).
+          rewrite Heqdisj2.
+          pose (OrR ([disj1],[])). simpl in g2. apply g2 ; clear g2. subst.
+          epose (OrL (_,_)). simpl in g2. apply g2 ; clear g2.
+          eapply (list_disj_L) with (s:=([],_)). intros. simpl.
+          epose (list_disj_wkn_R _ ([A], _) A). simpl in g2. apply g2 ; clear g2. subst.
+          apply restr_list_prop_nodup ; auto.
+          epose (Id_all_form A [] [] []). simpl in d. apply d.
+          epose (OrL (_,_)). simpl in g2. apply g2 ; clear g2.
+          apply GLS_prv_wkn_R with
+          (s:= ([list_disj (map Neg (restr_list_prop p (nodup eq_dec_form (fst s))))], [Or (list_disj (map Neg (restr_list_prop p (fst s))))
+          (Or (list_disj (map Box (map (UI p) (GLR_prems ( nodupseq s)))))
+          (Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))))))]))
+          (A:=list_disj (restr_list_prop p (snd s))).
+          2: epose (wkn_RI (list_disj (restr_list_prop p (snd s))) _ [] _) ; simpl in w ; apply w.
+          epose (OrR (_,_)). simpl in g2. apply g2 ; clear g2.
+          eapply (list_disj_L) with (s:=([],_)). intros. simpl.
+          epose (list_disj_wkn_R _ ([A], _) A). simpl in g2. apply g2 ; clear g2. subst.
+          apply InT_map_iff. apply InT_map_iff in H2. destruct H2. exists x0.
+          destruct p0 ; split ; auto. apply restr_list_prop_nodup ; auto.
+          epose (Id_all_form A [] [] []). simpl in d. apply d. clear g0. clear g1.
+          apply GLS_prv_wkn_R with
+          (s:= ([list_disj (map Box (map (UI p) (GLR_prems (nodupseq (nodupseq s)))))], [Or (list_disj (map Neg (restr_list_prop p (fst s))))
+          (Or (list_disj (map Box (map (UI p) (GLR_prems ( nodupseq s)))))
+          (Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))))))]))
+          (A:=list_disj (restr_list_prop p (snd s))).
+          2: epose (wkn_RI (list_disj (restr_list_prop p (snd s))) _ [] _) ; simpl in w ; apply w.
+          epose (OrR (_,_)). simpl in g0. apply g0 ; clear g0.
+          apply GLS_prv_wkn_R with
+          (s:= ([list_disj (map Box (map (UI p) (GLR_prems (nodupseq (nodupseq s)))))], [(Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq s)))))
+          (Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))))))]))
+          (A:=list_disj (map Neg (restr_list_prop p (fst s)))).
+          2: epose (wkn_RI (list_disj (map Neg (restr_list_prop p (fst s)))) _ [] _) ; simpl in w ; apply w.
+          epose (OrR (_,_)). simpl in g0. apply g0 ; clear g0.
+          eapply (list_disj_L) with (s:=([],_)). intros. simpl.
+          apply InT_map_iff in H2. destruct H2. destruct p0 ; subst. apply InT_map_iff in i.
+          destruct i. destruct p0 ; subst.
+          apply nodupseq_GLR_prems in i. destruct i. destruct p0. destruct p0. subst.
+          epose (list_disj_wkn_R _ (_,[_]) (Box (UI p x0))). apply g0 ; clear g0. apply InT_map_iff.
+          exists (UI p x0). split ; auto. apply InT_map_iff. exists x0 ; auto.
+          simpl. apply derI with (ps:=[([UI p x1;Box (UI p x1);Box (UI p x0)], [UI p x0])]).
+          apply GLR. epose (@GLRRule_I _ [Box (UI p x1)] _ [] [_]). simpl in g0. apply g0.
+          intros A H3. inversion H3 ; subst. eexists ; auto. inversion H2. apply univ_gen_ext_refl.
+          apply dlCons. 2: apply dlNil. eapply (UI_nodupseq_gen x1 x0 p _ []).
+          unfold nodupseq ; simpl. rewrite e. rewrite e0 ; auto.
+          epose (g0 X0 (Top :: X)). rewrite app_nil_r in g2. apply g2.
+          epose (g1 X0 Y). rewrite app_nil_r in g2. apply g2.
+  (* If s is not critical. *)
+  - assert (J0: GUI p s (UI p s)). apply UI_GUI ; auto.
+    assert (J1: Gimap (GUI p) (Canopy (nodupseq s)) (map (UI p) (Canopy (nodupseq s)))). apply Gimap_map. intros.
+    apply UI_GUI ; auto.
+    pose (@GUI_inv_not_critic p s (UI p s) _ J0 f J1). rewrite <- e.
+    apply derI with (ps:=[(list_conj (map (N p sr) (Canopy (nodupseq s))) :: X, list_conj (map (UI p) (Canopy (nodupseq s))) :: Y)]).
+    apply ImpR. epose (ImpRRule_I _ _ [] _ []). simpl in i. apply i. apply dlCons. 2: apply dlNil.
+    epose (list_conj_R _ (_,_)). simpl in g. apply g. clear g. intros. apply InT_map_iff in H. destruct H.
+    destruct p0 ; subst.
+    epose (list_conj_wkn_L _ (_,_) (N p sr x)). simpl in g. apply g ; clear g.
+    apply InT_map_iff. exists x ; split ; auto.
+    pose (Canopy_LexSeq _ _ i). destruct s0.
+    exfalso. subst. apply Canopy_critical in i. apply critical_nodupseq in i ; auto.
+    assert (J20: LexSeq x s). pose (LexSeq_nodupseq_case s). destruct s0. apply LexSeq_trans with (y:=nodupseq s) ; auto.
+    destruct p0. unfold LexSeq ; unfold less_thanS ; unfold GLS_termination_measure.measure ; inversion l ; subst.
+    rewrite <- e1 in H2. rewrite H2. apply DLW_wf_lex.lex_skip ; auto. rewrite <- e0 ; auto.
+    apply DLW_wf_lex.lex_cons ; auto. rewrite e1 ; auto.
+    pose (IH _ J20 sr p X Y). pose (Canopy_critical _ _ i).
+    assert (Canopy (nodupseq x) = [nodupseq x]). apply Id_InT_Canopy ; auto.
+    apply critical_Seq_InT_Canopy ; auto. rewrite <- critical_nodupseq ; auto.
+    rewrite H in g. simpl in g.
+    epose (ImpRRule_I _ _ [] _ [] _). simpl in i0.
+    pose (@ImpR_inv _ (And (N p sr (nodupseq x)) Top :: X, UI p x :: Y) g i0).
+    epose (TopL_remove _ [] (N p sr x :: X)). simpl in g1. apply g1. clear g1.
+    epose (GLS_cut_adm (And (N p sr x) Top) [] (Top :: N p sr x :: X) [] (UI p x :: Y)).
+    simpl in g1. apply g1 ; clear g1.
+    epose (AndR (_,_)). simpl in g1. apply g1 ; clear g1.
+    epose (Id_all_form (N p sr x) [Top] X []). simpl in d. apply d.
+    epose (TopR _ []). simpl in g1 ; apply g1.
+    pose (@GLS_prv_list_wkn_L [And (N p sr x) Top] X (UI p x :: Y)).
+    simpl in g1. apply g1 with (l:=(Top :: [N p sr x])) ; clear g1.
+    eapply AndL with (s:=(X,_)) ; simpl.
+    eapply AndL_inv with (s:=(_,_)) in g0. simpl in g0.
+    pose (N_nodupseq sr x p (Top :: X) (UI p x :: Y)).
+    epose (GLS_cut_adm (N p sr (nodupseq x)) [] (N p sr x :: Top :: X) [] (UI p x :: Y)).
+    simpl in g2. apply g2 ; clear g2 ; auto.
+    apply GLS_prv_wkn_L with (s:= (N p sr (nodupseq x) :: Top :: X, UI p x :: Y))
+    (A:=N p sr x) ; auto.
+    epose (wkn_LI (N p sr x) [_] _ _) ; simpl in w ; apply w. }
+  Qed.
+ +
+  Theorem rec_UI_imp : forall s p X Y, (is_init s -> False) -> (critical_Seq s) ->
+              GLS_prv (X,
+        (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) -->
+        (UI p (XBoxed_list (top_boxes (fst s)), []%list)) :: Y).
+  Proof.
+  intros. apply gen_rec_UI_imp.
+  Qed.
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_PermutationT.html b/GL.Interpolation.UIGL_PermutationT.html new file mode 100644 index 0000000..2e78d08 --- /dev/null +++ b/GL.Interpolation.UIGL_PermutationT.html @@ -0,0 +1,195 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_PermutationT

+ +
+Require Import List.
+Export ListNotations.
+Require Export Permutation.
+ +
+Require Import GLS_export.
+ +
+Section PermutationT.
+ +
+    Inductive PermutationT : list MPropF -> list MPropF -> Type :=
+      | permT_nil: PermutationT nil nil
+      | permT_skip: forall (x: MPropF) (l l':list MPropF), PermutationT l l' -> PermutationT (cons x l) (cons x l')
+      | permT_swap: forall (x y: MPropF) (l:list MPropF), PermutationT (cons y (cons x l)) (cons x (cons y l))
+      | permT_trans: forall (l l' l'':list MPropF), PermutationT l l' -> PermutationT l' l'' -> PermutationT l l''.
+ +
+Local Hint Constructors PermutationT : core.
+ +
+Theorem PermutationT_refl : forall l, PermutationT l l.
+Proof.
+  induction l; constructor. exact IHl.
+Qed.
+ +
+Theorem PermutationT_sym : forall l l',
PermutationT l l' -> PermutationT l' l.
+Proof.
+  intros l l' Hperm; induction Hperm; auto.
+  apply permT_trans with (l':=l'); assumption.
+Qed.
+ +
+Lemma PermutationT_app_tail : forall l l' tl,
PermutationT l l' -> PermutationT (l++tl) (l'++tl).
+Proof.
+  intros l l' tl Hperm; induction Hperm as [|x l l'|x y l|l l' l'']; simpl; auto.
+  apply PermutationT_refl.
+  eapply permT_trans with (l':=l'++tl); trivial.
+Qed.
+ +
+Lemma PermutationT_app_head : forall l tl tl',
PermutationT tl tl' -> PermutationT (l++tl) (l++tl').
+Proof.
+  intros l tl tl' Hperm; induction l;
+   [trivial | repeat rewrite <- app_comm_cons; constructor; assumption].
+Qed.
+ +
+Theorem PermutationT_app : forall l m l' m',
PermutationT l l' -> PermutationT m m' -> PermutationT (l++m) (l'++m').
+Proof.
+  intros l m l' m' Hpermll' Hpermmm';
+   induction Hpermll' as [|x l l'|x y l|l l' l''];
+    repeat rewrite <- app_comm_cons; auto.
+  - apply permT_trans with (l' := (x :: y :: l ++ m));
+      [idtac | repeat rewrite app_comm_cons; apply PermutationT_app_head]; trivial.
+  - apply permT_trans with (l' := (l' ++ m')); try assumption.
+    apply PermutationT_app_tail; assumption.
+Qed.
+ +
+Lemma PermutationT_cons_append : forall l x,
+  PermutationT (x :: l) (l ++ x :: nil).
+Proof.
+induction l; intros; auto. simpl. apply permT_skip ; apply permT_nil. simpl.
+apply permT_trans with (l':=(a :: x :: l)). apply permT_swap. apply permT_skip ; auto.
+Qed.
+ +
+Theorem PermutationT_app_comm : forall l l',
+  PermutationT (l ++ l') (l' ++ l).
+Proof.
+  induction l as [|x l]; simpl; intro l'.
+  - rewrite app_nil_r; trivial. apply PermutationT_refl.
+  - rewrite app_comm_cons. pose (IHl l').
+    apply permT_trans with (l':= (l' ++ l ++ [x])).
+    simpl. apply permT_trans with (l':= (x :: l' ++ l)).
+    apply permT_skip ; auto. pose (PermutationT_cons_append (l' ++ l) x).
+    rewrite <- app_assoc in p0 ; auto.
+    apply (PermutationT_app l'). apply PermutationT_refl.
+    apply PermutationT_sym , PermutationT_cons_append.
+Qed.
+Local Hint Resolve PermutationT_app_comm : core.
+ +
+Theorem PermutationT_cons_app : forall l l1 l2 a,
+  PermutationT l (l1 ++ l2) -> PermutationT (a :: l) (l1 ++ a :: l2).
+Proof.
+  intros l l1 l2 a H. apply permT_trans with (l':=(a :: (l1 ++ l2))).
+  apply permT_skip ; auto.
+  rewrite app_comm_cons. apply permT_trans with (l':=(a :: (l2 ++ l1))).
+  simpl. apply permT_skip ; auto. pose (PermutationT_app_comm (a :: l2) l1).
+  simpl in p ; auto.
+Qed.
+ +
+Lemma Permutation_vs_elt_invT : forall l l1 l2 (a : MPropF),
Permutation l (l1 ++ a :: l2) -> existsT2 l' l'', l = l' ++ a :: l''.
+Proof.
+  intros l l1 l2 a HP. apply Permutation_sym in HP.
+  assert (In a (l1 ++ a :: l2)). apply in_or_app ; right ; apply in_eq.
+  epose (Permutation_in a HP H). apply In_InT in i. apply InT_split in i.
+  auto.
+Qed.
+ +
+Lemma Permutation_vs_cons_invT : forall l l1 (a : MPropF),
+  Permutation l (a :: l1) -> existsT2 l' l'', l = l' ++ a :: l''.
+Proof.
+  intros l l1 a HP.
+  rewrite <- (app_nil_l (a :: l1)) in HP. apply Permutation_vs_elt_invT in HP. auto.
+Qed.
+ +
+    Theorem Permutation_PermutationT : forall l l', (Permutation l l' -> PermutationT l l') * (PermutationT l l' -> Permutation l l').
+    Proof.
+    intros l l'. split ; intros.
+    - revert H. revert l'. induction l.
+      + intros. destruct l'. apply permT_nil. apply Permutation_nil in H ; inversion H.
+      + intros. pose (Permutation_sym H). apply Permutation_vs_cons_invT in p. destruct p. destruct s. subst.
+         apply Permutation_cons_app_inv in H. apply IHl in H. apply PermutationT_cons_app ; auto.
+    - induction H.
+      + apply perm_nil.
+      + apply perm_skip ; auto.
+      + apply perm_swap ; auto.
+      + apply perm_trans with (l':=l') ; auto.
+    Qed.
+ +
+Theorem PermutationT_ind_T :
forall P : list MPropF -> list MPropF -> Type,
+   P [] [] ->
+   (forall x l l', PermutationT l l' -> P l l' -> P (x :: l) (x :: l')) ->
+   (forall x y l l', PermutationT l l' -> P l l' -> P (y :: x :: l) (x :: y :: l')) ->
+   (forall l l' l'', PermutationT l l' -> P l l' -> PermutationT l' l'' -> P l' l'' -> P l l'') ->
+   forall l l', PermutationT l l' -> P l l'.
+Proof.
+  intros P Hnil Hskip Hswap Htrans.
+  intros l l' ; induction 1 ; auto.
+  - apply Htrans with (x::y::l); auto.
+    + apply Hswap; auto. apply Permutation_PermutationT ; apply Permutation_refl.
+      induction l; auto. apply Hskip ; auto. apply Permutation_PermutationT ; apply Permutation_refl.
+    + apply Permutation_PermutationT ; apply Permutation_refl.
+    + apply Hskip; auto. apply Permutation_PermutationT ; apply Permutation_refl.
+      apply Hskip; auto. apply Permutation_PermutationT ; apply Permutation_refl.
+      induction l; auto. apply Hskip ; auto. apply Permutation_PermutationT ; apply Permutation_refl.
+  - eauto.
+Qed.
+ +
+  End PermutationT.
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_PermutationTS.html b/GL.Interpolation.UIGL_PermutationTS.html new file mode 100644 index 0000000..e7b7281 --- /dev/null +++ b/GL.Interpolation.UIGL_PermutationTS.html @@ -0,0 +1,368 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_PermutationTS

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat Arith.
+Require Import Lia.
+ +
+Require Import general_export.
+ +
+Require Import GLS_export.
+ +
+Require Import UIGL_Def_measure.
+Require Import UIGL_Canopy.
+Require Import UIGL_irred_short.
+Require Import UIGL_PermutationT.
+Require Import UIGL_LexSeq.
+Require Import UIGL_basics.
+ +
+Definition PermutationTS (s sp : Seq) := (PermutationT (fst s) (fst sp)) * (PermutationT (snd s) (snd sp)).
+ +
+Theorem PermutationTS_sym : forall s sp, PermutationTS s sp -> PermutationTS sp s.
+Proof.
+unfold PermutationTS. intros. destruct H. apply Permutation_PermutationT in p.
+apply Permutation_PermutationT in p0. split.
+1-2: apply Permutation_PermutationT ; apply Permutation_sym ; auto.
+Qed.
+ +
+Theorem PermutationT_XBoxed_list : forall l0 l1, PermutationT l0 l1 -> PermutationT (XBoxed_list l0) (XBoxed_list l1).
+Proof.
+induction 1 ; simpl ; intuition.
+- apply Permutation_PermutationT ; apply Permutation_refl.
+- apply Permutation_PermutationT ; repeat apply perm_skip ; apply Permutation_PermutationT ; auto.
+- apply Permutation_PermutationT. epose (Permutation_app_swap_app (_ :: [_]) (_ :: [_])). simpl in p. apply p.
+- apply permT_trans with (l':=(XBoxed_list l')) ; auto.
+Qed.
+ +
+Theorem PermutationT_top_boxes : forall l0 l1, PermutationT l0 l1 -> PermutationT (top_boxes l0) (top_boxes l1).
+Proof.
+induction 1.
+- apply Permutation_PermutationT ; apply Permutation_refl.
+- destruct x ; simpl ; auto. apply Permutation_PermutationT ; repeat apply perm_skip ; apply Permutation_PermutationT ; auto.
+- destruct x ; destruct y ; simpl ; apply Permutation_PermutationT ; try apply Permutation_refl. apply perm_swap.
+- apply permT_trans with (l':=(top_boxes l')) ; auto.
+Qed.
+ +
+Theorem PermutationTS_prv_hpadm : forall s (D: GLS_prv s),
+          forall sp, PermutationTS s sp -> existsT2 (D0: GLS_prv sp), derrec_height D0 <= derrec_height D.
+Proof.
+intros s D. remember (derrec_height D) as n. revert Heqn. revert D. revert s. revert n.
+induction n as [n IH] using (well_founded_induction_type lt_wf).
+intros s0 D0. destruct D0.
+- intros. inversion f.
+- intros hei sp Perm. simpl in hei.
+  inversion g ; subst.
+  + inversion H ; subst.
+     assert (GLS_rules [] sp). apply IdP. destruct sp. destruct Perm. simpl in *. apply Permutation_PermutationT in p, p0.
+     assert (InT (# P) l0). apply In_InT. apply (Permutation_in _ p0). apply in_or_app ; right ; apply in_eq.
+     assert (InT (# P) l). apply In_InT. apply (Permutation_in _ p). apply in_or_app ; right ; apply in_eq.
+     apply InT_split in H0. apply InT_split in H1. destruct H0. destruct s. destruct H1. destruct s. subst ; apply IdPRule_I.
+     pose (dlNil GLS_rules (fun _ : Seq => False)).
+     epose (@derI _ _ (fun _ : Seq => False) _ _ X d0). exists d1. simpl. lia.
+  + inversion H ; subst.
+     assert (GLS_rules [] sp). apply BotL. destruct sp. destruct Perm. simpl in *. apply Permutation_PermutationT in p.
+     assert (InT Bot l). apply In_InT. apply (Permutation_in _ p). apply in_or_app ; right ; apply in_eq.
+     apply InT_split in H0. destruct H0. destruct s. subst ; apply BotLRule_I.
+     pose (dlNil GLS_rules (fun _ : Seq => False)).
+     epose (@derI _ _ (fun _ : Seq => False) _ _ X d0). exists d1. simpl. lia.
+  + inversion H ; subst. destruct sp. destruct Perm. simpl in *. apply Permutation_PermutationT in p0.
+     assert (InT (A --> B) l0). apply In_InT. apply (Permutation_in _ p0). apply in_or_app ; right ; apply in_eq.
+     apply InT_split in H0. destruct H0. destruct s. subst.
+     assert (GLS_rules [(A :: l, x ++ B :: x0)] (l, x ++ A --> B :: x0)). apply ImpR. eapply (ImpRRule_I _ _ []).
+     assert (dersrec_height d = dersrec_height d). auto. pose (dersrec_derrec_height d H0). destruct s ; subst.
+     assert (J0: derrec_height x1 < S (dersrec_height d)). lia.
+     assert (J1: derrec_height x1 = derrec_height x1). auto.
+     assert (J2: PermutationTS (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) (A :: l, x ++ B :: x0)).
+     split ; simpl ; apply Permutation_PermutationT ; apply Permutation_PermutationT in p.
+     apply Permutation_sym. apply Permutation_cons_app ; auto. apply Permutation_sym ; auto.
+     apply Permutation_elt. apply Permutation_app_inv in p0 ; auto.
+     pose (IH _ J0 _ _ J1 _ J2). destruct s. pose (dlCons x2 (dlNil _ _)).
+     epose (@derI _ _ (fun _ : Seq => False) _ _ X d0). exists d1. simpl. lia.
+  + inversion H ; subst. destruct sp. destruct Perm. simpl in *. apply Permutation_PermutationT in p0 , p.
+     assert (InT (A --> B) l). apply In_InT. apply (Permutation_in _ p). apply in_or_app ; right ; apply in_eq.
+     apply InT_split in H0. destruct H0. destruct s. subst.
+     assert (GLS_rules [(x ++ x0, A :: l0);(x ++ B :: x0, l0)] (x ++ A --> B :: x0, l0)). apply ImpL. eapply (ImpLRule_I _ _ x x0 []).
+     assert (dersrec_height d = dersrec_height d). auto. pose (dersrec_derrec2_height d H0). destruct s ; subst. destruct s.
+     assert (J0: derrec_height x1 < S (dersrec_height d)). lia.
+     assert (J1: derrec_height x1 = derrec_height x1). auto.
+     assert (J2: PermutationTS (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) (x ++ x0, A :: l0)).
+     split ; simpl ; apply Permutation_PermutationT.
+     apply Permutation_app_inv in p ; auto.
+     apply Permutation_sym. apply Permutation_cons_app ; auto. apply Permutation_sym ; auto.
+     pose (IH _ J0 _ _ J1 _ J2). destruct s.
+     assert (J3: derrec_height x2 < S (dersrec_height d)). lia.
+     assert (J4: derrec_height x2 = derrec_height x2). auto.
+     assert (J5: PermutationTS (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) (x ++ B :: x0, l0)).
+     split ; simpl ; apply Permutation_PermutationT ; auto.
+     apply Permutation_elt. apply Permutation_app_inv in p ; auto.
+     pose (IH _ J3 _ _ J4 _ J5). destruct s. pose (dlCons x4 (dlNil _ _)). pose (dlCons x3 d0).
+     epose (@derI _ _ (fun _ : Seq => False) _ _ X d1). exists d2. simpl. lia.
+  + inversion X ; subst. destruct sp. destruct Perm. simpl in *. apply Permutation_PermutationT in p0 , p.
+     assert (InT (Box A) l0). apply In_InT. apply (Permutation_in _ p0). apply in_or_app ; right ; apply in_eq.
+     apply InT_split in H0. destruct H0. destruct s. subst.
+     assert (GLS_rules [(XBoxed_list (top_boxes l) ++ [Box A], [A])] (l, x ++ Box A :: x0)). apply GLR. apply GLRRule_I.
+     apply is_Boxed_list_top_boxes. apply nobox_gen_ext_top_boxes.
+     assert (dersrec_height d = dersrec_height d). auto. pose (dersrec_derrec_height d H0). destruct s ; subst.
+     assert (J0: derrec_height x1 < S (dersrec_height d)). lia.
+     assert (J1: derrec_height x1 = derrec_height x1). auto.
+     assert (J2: PermutationTS (XBoxed_list ++ [Box A], [A]) (XBoxed_list (top_boxes l) ++ [Box A], [A])).
+     split ; simpl ; apply Permutation_PermutationT. 2: apply Permutation_refl.
+     apply Permutation_app. 2: apply Permutation_refl.
+     pose (nobox_gen_ext_top_boxes_identity X0 H). rewrite e0. apply Permutation_PermutationT.
+     apply PermutationT_XBoxed_list. apply PermutationT_top_boxes ; apply Permutation_PermutationT ; auto.
+     pose (IH _ J0 _ _ J1 _ J2). destruct s. pose (dlCons x2 (dlNil _ _)).
+     epose (@derI _ _ (fun _ : Seq => False) _ _ X1 d0). exists d1. simpl. lia.
+Qed.
+ +
+Theorem PermutationTS_prv : forall s sp, PermutationTS s sp -> GLS_prv s -> GLS_prv sp.
+Proof.
+intros. destruct (PermutationTS_prv_hpadm _ X _ H) ; auto.
+Qed.
+ +
+Theorem PermutationTS_restr_list_prop_snd : forall s sp p A, PermutationTS s sp -> InT A (restr_list_prop p (snd s)) -> InT A (restr_list_prop p (snd sp)).
+Proof.
+unfold PermutationTS. intros. destruct H. apply Permutation_PermutationT in p0, p1.
+apply InT_In in H0. apply In_InT. unfold restr_list_prop in *. apply in_remove in H0 ; destruct H0.
+apply in_in_remove ; auto. apply In_list_prop_LF_bis in H. destruct H. apply list_prop_LF_In ; auto.
+apply (Permutation_in _ p1 i).
+Qed.
+ +
+Theorem PermutationTS_restr_list_prop_fst : forall s sp p A, PermutationTS s sp -> InT A (restr_list_prop p (fst s)) -> InT A (restr_list_prop p (fst sp)).
+Proof.
+unfold PermutationTS. intros. destruct H. apply Permutation_PermutationT in p0, p1.
+apply InT_In in H0. apply In_InT. unfold restr_list_prop in *. apply in_remove in H0 ; destruct H0.
+apply in_in_remove ; auto. apply In_list_prop_LF_bis in H. destruct H. apply list_prop_LF_In ; auto.
+apply (Permutation_in _ p0 i).
+Qed.
+ +
+Theorem PermutationTS_GLR_prems : forall s sp, PermutationTS s sp ->
+            (forall ps, InT ps (GLR_prems s) -> (existsT2 psp, PermutationTS ps psp * InT psp (GLR_prems sp))).
+Proof.
+intros. unfold GLR_prems in H0. destruct (finite_GLR_premises_of_S s). simpl in H0.
+apply InT_flatten_list_InT_elem in H0. destruct H0. destruct p0. apply p in i0. inversion i0 ; subst.
+destruct sp. destruct H. simpl in *. apply Permutation_PermutationT in p0, p1.
+assert (InT (Box A) l0). apply In_InT. apply (Permutation_in _ p1). apply in_or_app ; right ; apply in_eq.
+apply InT_split in H. destruct H. destruct s. subst.
+exists (XBoxed_list (top_boxes l) ++ [Box A], [A]). inversion i ; subst. 2: inversion H1. split.
+split ; simpl ; apply Permutation_PermutationT. 2: apply Permutation_refl.
+apply Permutation_app. 2: apply Permutation_refl.
+pose (nobox_gen_ext_top_boxes_identity X H0). rewrite e. apply Permutation_PermutationT.
+apply PermutationT_XBoxed_list. apply PermutationT_top_boxes ; apply Permutation_PermutationT ; auto.
+unfold GLR_prems. destruct (finite_GLR_premises_of_S (l, x0 ++ Box A :: x1)). simpl.
+apply InT_trans_flatten_list with (bs:=[(XBoxed_list (top_boxes l) ++ [Box A], [A])]).
+apply InT_eq. apply p2. apply GLRRule_I.
+apply is_Boxed_list_top_boxes. apply nobox_gen_ext_top_boxes.
+Qed.
+ +
+Theorem PermutationTS_is_init : forall s sp, PermutationTS s sp -> (is_init s -> is_init sp).
+Proof.
+unfold PermutationTS. intros. destruct H. apply Permutation_PermutationT in p, p0. destruct s. destruct sp.
+simpl in *. inversion X. inversion H.
+- inversion H0 ; subst.
+  assert (InT (# P) l2). apply In_InT. apply (Permutation_in _ p0). apply in_or_app ; right ; apply in_eq.
+  apply InT_split in H1. destruct H1. destruct s. subst.
+  assert (InT (# P) l1). apply In_InT. apply (Permutation_in _ p). apply in_or_app ; right ; apply in_eq.
+  apply InT_split in H1. destruct H1. destruct s. subst. left. left. apply IdPRule_I.
+- inversion H0 ; subst.
+  assert (InT (Box A) l2). apply In_InT. apply (Permutation_in _ p0). apply in_or_app ; right ; apply in_eq.
+  apply InT_split in H1. destruct H1. destruct s. subst.
+  assert (InT (Box A) l1). apply In_InT. apply (Permutation_in _ p). apply in_or_app ; right ; apply in_eq.
+  apply InT_split in H1. destruct H1. destruct s. subst. left. right. apply IdBRule_I.
+- inversion H ; subst.
+  assert (InT (Bot) l1). apply In_InT. apply (Permutation_in _ p). apply in_or_app ; right ; apply in_eq.
+  apply InT_split in H0. destruct H0. destruct s. subst. right. apply BotLRule_I.
+Qed.
+ +
+Theorem PermutationTS_critic : forall s sp, PermutationTS s sp -> (critical_Seq s -> critical_Seq sp).
+Proof.
+unfold PermutationTS. intros. destruct H. apply Permutation_PermutationT in p, p0. destruct s. destruct sp.
+simpl in *. unfold critical_Seq in * ; simpl in *. intros A HA. apply in_app_or in HA ; destruct HA.
+- assert (InT A l). apply In_InT. apply (Permutation_in _ (Permutation_sym p)) ; auto.
+  apply H0. apply in_or_app ; left ; apply InT_In ; auto.
+- assert (InT A l0). apply In_InT. apply (Permutation_in _ (Permutation_sym p0)) ; auto.
+  apply H0. apply in_or_app ; right ; apply InT_In ; auto.
+Qed.
+ +
+Theorem Permutation_subform_boxesLF : forall l0 l1, Permutation l0 l1 ->
+    (forall A, In A (subform_boxesLF l0) -> In A (subform_boxesLF l1)).
+Proof.
+induction 1 ; simpl ; intuition.
+- apply in_app_or in H0. apply in_or_app. destruct H0 ; auto. right.
+  apply In_remove_list_In_list_not_In_remove_list in H0. destruct H0.
+  apply not_removed_remove_list ; auto.
+- apply in_app_or in H. destruct H ; auto. apply remove_list_is_in. apply in_or_app ; auto.
+  apply In_remove_list_In_list_not_In_remove_list in H. destruct H.
+  apply in_app_or in H. destruct H ; auto. apply in_or_app ; auto.
+  apply In_remove_list_In_list_not_In_remove_list in H. destruct H.
+  apply remove_list_is_in. apply remove_list_is_in ; auto.
+Qed.
+ +
+Theorem PermutationTS_usable_boxes : forall s sp, PermutationTS s sp ->
+    (forall A, InT A (usable_boxes s) -> InT A (usable_boxes sp)).
+Proof.
+unfold PermutationTS. intros. destruct H. apply Permutation_PermutationT in p, p0. destruct s. destruct sp.
+simpl in *. unfold usable_boxes in *. simpl in *. apply InT_In in H0. apply In_InT.
+apply In_remove_list_In_list_not_In_remove_list in H0. destruct H0.
+apply not_removed_remove_list ; auto.
+unfold subform_boxesS in * ; simpl in *. apply in_or_app.
+apply in_app_or in H. destruct H. left.
+apply Permutation_subform_boxesLF with (l0:=l) ; auto.
+right. apply In_remove_list_In_list_not_In_remove_list in H. destruct H.
+apply not_removed_remove_list.
+apply Permutation_subform_boxesLF with (l0:=l0) ; auto.
+intro. apply H1.
+apply Permutation_subform_boxesLF with (l0:=l1) ; auto. apply Permutation_sym ; auto.
+intro. apply H0. pose (in_top_boxes _ _ H1). repeat destruct s.
+destruct p1. clear e0 ; subst. apply is_box_in_top_boxes. 2: eexists ; auto.
+apply top_boxes_incl_list in H1. apply (Permutation_in _ (Permutation_sym p) H1).
+Qed.
+ +
+Theorem PermutationTS_Canopy : forall s sp, PermutationTS s sp ->
+      (forall sc, InT sc (Canopy s) -> existsT2 spc, InT spc (Canopy sp) * PermutationTS sc spc).
+Proof.
+  intros s0 ; induction on s0 as IH with measure (n_imp_subformS s0).
+  intros s1 perm sp InClos.
+  pose (fold_Canopy _ _ InClos). destruct s ; subst ; auto.
+  - exists s1. split ; auto. apply Canopy_critical in InClos. apply critical_Seq_InT_Canopy.
+    apply (PermutationTS_critic _ _ perm) ; auto.
+  - destruct s. destruct p. unfold inv_prems in i. apply InT_flatten_list_InT_elem in i. destruct i.
+    destruct p. destruct (finite_ImpRules_premises_of_S s0). simpl in i1.
+    apply p in i1. destruct i1. inversion i1 ; subst.
+    (* x0 is obtained via ImpR. *)
+    + inversion i ; subst. 2: inversion H0. assert (InT (A --> B) (snd s1)).
+       apply In_InT. apply Permutation_in with (l:=Δ0 ++ A --> B :: Δ1). destruct perm ; simpl in * ; auto.
+       apply Permutation_PermutationT in p1 ; auto. apply in_or_app ; right ; apply in_eq.
+       apply InT_split in H. destruct H. destruct s. subst.
+       assert (J1: n_imp_subformS (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) < n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1)).
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       assert (J2: PermutationTS (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) (A :: fst s1, x ++ B :: x0)).
+       unfold PermutationTS. destruct perm ; simpl in * ; split. apply Permutation_PermutationT. apply Permutation_sym.
+       apply Permutation_cons_app ; apply Permutation_sym ; auto. apply Permutation_PermutationT in p0 ; auto.
+       apply Permutation_PermutationT. apply Permutation_PermutationT in p1. rewrite e in p1.
+       apply Permutation_app_inv in p1. apply Permutation_elt ; auto.
+       pose (IH _ J1 _ J2 _ i0). destruct s. destruct p0. exists x2 ; split ; auto.
+       assert (ImpRRule [(A :: fst s1, x ++ B :: x0)] s1 + ImpLRule [(A :: fst s1, x ++ B :: x0)] s1).
+       left. destruct s1. epose (ImpRRule_I _ _ [] _ _ _). simpl in * ; subst ; simpl in *. apply i3.
+       assert (InT (A :: fst s1, x ++ B :: x0) [(A :: fst s1, x ++ B :: x0)]). apply InT_eq.
+       pose (ImpRule_Canopy _ _ H _ H0). apply i3 ; auto.
+    + inversion i1 ; subst. assert (InT (A --> B) (fst s1)). apply In_InT. apply Permutation_in with (l:=Γ0 ++ A --> B :: Γ1). destruct perm ; simpl in * ; auto.
+       apply Permutation_PermutationT in p0 ; auto. apply in_or_app ; right ; apply in_eq.
+       apply InT_split in H. destruct H. destruct s. inversion i ; subst.
+       (* x is the left premise via ImpL. *)
+       * assert (J1: n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+         unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+         assert (J2: PermutationTS (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) (x0 ++ x2, A :: snd s1)).
+         unfold PermutationTS. destruct perm ; simpl in * ; split.
+         apply Permutation_PermutationT. apply Permutation_PermutationT in p0. rewrite e in p0.
+         apply Permutation_app_inv in p0 ; auto.
+         apply Permutation_PermutationT. apply Permutation_sym.
+         apply Permutation_cons_app ; apply Permutation_sym ; auto. apply Permutation_PermutationT in p1 ; auto.
+         pose (IH _ J1 _ J2 _ i0). destruct s. destruct p0. exists x ; split ; auto.
+         assert (ImpRRule [(x0 ++ x2, A :: snd s1);(x0 ++ B :: x2, snd s1)] s1 + ImpLRule [(x0 ++ x2, A :: snd s1);(x0 ++ B :: x2, snd s1)] s1).
+         right. destruct s1. epose (ImpLRule_I _ _ _ _ [] _). simpl in * ; subst ; simpl in *. apply i3.
+         assert (InT (x0 ++ x2, A :: snd s1) [(x0 ++ x2, A :: snd s1); (x0 ++ B :: x2, snd s1)]). apply InT_eq.
+         pose (ImpRule_Canopy _ _ H _ H0). apply i3 ; auto.
+       (* x is the right premise via ImpL. *)
+       * inversion H0 ; subst. 2: inversion H1.
+         assert (J1: n_imp_subformS (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+         unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+         assert (J2: PermutationTS (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) (x0 ++ B :: x2, snd s1)).
+         unfold PermutationTS. destruct perm ; simpl in * ; split.
+         apply Permutation_PermutationT. apply Permutation_PermutationT in p0. rewrite e in p0.
+         apply Permutation_app_inv in p0 ; auto. apply Permutation_elt ; auto.
+         apply Permutation_PermutationT ; apply Permutation_PermutationT in p1 ; auto.
+         pose (IH _ J1 _ J2 _ i0). destruct s. destruct p0. exists x ; split ; auto.
+         assert (ImpRRule [(x0 ++ x2, A :: snd s1);(x0 ++ B :: x2, snd s1)] s1 + ImpLRule [(x0 ++ x2, A :: snd s1);(x0 ++ B :: x2, snd s1)] s1).
+         right. destruct s1. epose (ImpLRule_I _ _ _ _ [] _). simpl in * ; subst ; simpl in *. apply i3.
+         assert (InT (x0 ++ B :: x2, snd s1) [(x0 ++ x2, A :: snd s1); (x0 ++ B :: x2, snd s1)]). apply InT_cons ; apply InT_eq.
+         pose (ImpRule_Canopy _ _ H _ H1). apply i3 ; auto.
+Qed.
+ +
+Lemma PermutationT_nodupseq : forall l0 l1, PermutationT l0 l1 -> PermutationT (nodup eq_dec_form l0) (nodup eq_dec_form l1).
+Proof.
+intros. apply Permutation_PermutationT. apply Permutation_PermutationT in H.
+revert H. revert l1. revert l0.
+epose (@Permutation_ind_bis _ (fun l0 l1 => Permutation (nodup eq_dec_form l0) (nodup eq_dec_form l1))).
+apply p ; clear p ; intros.
+- simpl. apply perm_nil.
+- simpl. destruct (in_dec eq_dec_form x l). destruct (in_dec eq_dec_form x l') ; auto.
+  exfalso. apply n. apply (Permutation_in _ H) ; auto. destruct (in_dec eq_dec_form x l') ; auto.
+  exfalso. apply n. apply Permutation_sym in H. apply (Permutation_in _ H) ; auto.
+- simpl. destruct (eq_dec_form x y) ; subst ; simpl. destruct (eq_dec_form y y). 2: exfalso ; auto.
+  destruct (in_dec eq_dec_form y l) ; auto. destruct (in_dec eq_dec_form y l') ; auto.
+  exfalso. apply n. apply (Permutation_in _ H) ; auto. destruct (in_dec eq_dec_form y l') ; auto.
+  exfalso. apply n. apply Permutation_sym in H. apply (Permutation_in _ H) ; auto.
+  destruct (in_dec eq_dec_form y l). destruct (in_dec eq_dec_form x l). destruct (eq_dec_form y x).
+  exfalso ; auto. destruct (in_dec eq_dec_form x l'). destruct (in_dec eq_dec_form y l') ; auto.
+  exfalso. apply n1. apply (Permutation_in _ H) ; auto. exfalso. apply n1. apply (Permutation_in _ H) ; auto.
+  destruct (eq_dec_form y x). exfalso ; auto. destruct (in_dec eq_dec_form x l').
+  exfalso. apply n0. apply Permutation_sym in H. apply (Permutation_in _ H) ; auto.
+  destruct (in_dec eq_dec_form y l'). apply perm_skip ; auto. exfalso.
+  apply n3. apply (Permutation_in _ H) ; auto. destruct (in_dec eq_dec_form x l).
+  destruct (eq_dec_form y x). exfalso ; auto. destruct (in_dec eq_dec_form x l').
+  destruct (in_dec eq_dec_form y l') ; auto. exfalso. apply n0. apply Permutation_sym in H. apply (Permutation_in _ H) ; auto.
+  exfalso. apply n2. apply (Permutation_in _ H) ; auto. destruct (eq_dec_form y x).
+  exfalso ; auto. destruct (in_dec eq_dec_form x l'). exfalso. apply n1. apply Permutation_sym in H. apply (Permutation_in _ H) ; auto.
+  destruct (in_dec eq_dec_form y l'). exfalso. apply n0. apply Permutation_sym in H. apply (Permutation_in _ H) ; auto.
+  pose (@Permutation_cons_app _ (x :: nodup eq_dec_form l) [x] (nodup eq_dec_form l') y). simpl in p. apply p.
+  clear p. apply perm_skip ; auto.
+- apply (perm_trans H0 H2) ; auto.
+Qed.
+ +
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_UIDiam_N.html b/GL.Interpolation.UIGL_UIDiam_N.html new file mode 100644 index 0000000..b8d2ec8 --- /dev/null +++ b/GL.Interpolation.UIGL_UIDiam_N.html @@ -0,0 +1,113 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_UIDiam_N

+ +
+  Require Import List.
+  Export ListNotations.
+  Require Import PeanoNat.
+  Require Import Lia.
+ +
+  Require Import general_export.
+ +
+  Require Import GLS_export.
+ +
+  Require Import UIGL_Def_measure.
+  Require Import UIGL_Canopy.
+  Require Import UIGL_irred_short.
+  Require Import UIGL_braga.
+  Require Import UIGL_LexSeq.
+  Require Import UIGL_nodupseq.
+  Require Import UIGL_UI_prelims.
+  Require Import UIGL_UI_inter.
+  Require Import UIGL_Diam_N_imp_UI.
+  Require Import UIGL_Diam_UI_imp_N.
+ +
+    Section UIPDiam.
+ +
+  Theorem Diam_rec_UI : forall s p X Y, (is_init s -> False) -> (critical_Seq s) ->
+              (GLS_prv (X, Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) :: Y) ->
+               GLS_prv (X, Diam (UI p (XBoxed_list (top_boxes (fst s)), []%list)) :: Y) ) *
+
+              (GLS_prv (X, Diam (UI p (XBoxed_list (top_boxes (fst s)), []%list)) :: Y) ->
+               GLS_prv (X, Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) :: Y)).
+  Proof.
+  intros. split ; intros.
+ +
+  pose (Diam_rec_UI_imp _ p X Y H H0).
+  apply ImpR_inv with (prem:=([] ++ Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) :: X,
+  [] ++ Diam (UI p (XBoxed_list (top_boxes (fst s)), []%list)) :: Y)) in g.
+  pose (GLS_cut_adm (Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))))
+  [] X [] (Diam (UI p (XBoxed_list (top_boxes (fst s)), []%list)) :: Y)). simpl in g0. apply g0. clear g0.
+  clear g.
+  assert (wkn_R (Diam (UI p (XBoxed_list (top_boxes (fst s)), []%list))) (X, [Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))))] ++ Y)
+  (X, [Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))))] ++ Diam (UI p (XBoxed_list (top_boxes (fst s)), []%list)) :: Y)).
+  apply wkn_RI.
+  pose (@GLS_prv_wkn_R (X, [Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))))] ++ Y)
+  X0 _ _ H1). auto.
+  simpl in g ; auto.
+  assert ((X, Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) --> Diam (UI p (XBoxed_list (top_boxes (fst s)), []%list)) :: Y) =
+  ([] ++ X, [] ++ Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) --> Diam (UI p (XBoxed_list (top_boxes (fst s)), []%list)) :: Y)).
+  auto. rewrite H1. apply ImpRRule_I.
+ +
+  pose (UI_Diam_rec_imp _ p X Y H H0).
+  apply ImpR_inv with (prem:=([] ++ Diam (UI p (XBoxed_list (top_boxes (fst s)), []%list)) :: X,
+  [] ++ Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) :: Y)) in g.
+  pose (GLS_cut_adm (Diam (UI p (XBoxed_list (top_boxes (fst s)), []%list)))
+  [] X [] (Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) :: Y)). simpl in g0. apply g0. clear g0.
+  clear g.
+  assert (wkn_R (Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))))) (X, [Diam (UI p (XBoxed_list (top_boxes (fst s)), []%list))] ++ Y)
+  (X, [Diam (UI p (XBoxed_list (top_boxes (fst s)), []%list))] ++ Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) :: Y)).
+  apply wkn_RI.
+  pose (@GLS_prv_wkn_R (X, [Diam (UI p (XBoxed_list (top_boxes (fst s)), []%list))] ++ Y)
+  X0 _ _ H1). auto.
+  simpl in g ; auto.
+  assert ((X, Diam (UI p (XBoxed_list (top_boxes (fst s)), []%list)) --> Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) :: Y) =
+  ([] ++ X, [] ++ Diam (UI p (XBoxed_list (top_boxes (fst s)), []%list)) --> Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) :: Y)).
+  auto. rewrite H1. apply ImpRRule_I.
+  Qed.
+ +
+    End UIPDiam.
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_UIOne.html b/GL.Interpolation.UIGL_UIOne.html new file mode 100644 index 0000000..e54ee5d --- /dev/null +++ b/GL.Interpolation.UIGL_UIOne.html @@ -0,0 +1,233 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_UIOne

+ +
+(* First property of uniform interpolation *)
+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat.
+Require Import Lia.
+Require Import String.
+Require Import general_export.
+ +
+Require Import GLS_export.
+ +
+Require Import UIGL_Def_measure.
+Require Import UIGL_Canopy.
+Require Import UIGL_irred_short.
+Require Import UIGL_braga.
+Require Import UIGL_LexSeq.
+Require Import UIGL_nodupseq.
+Require Import UIGL_And_Or_rules.
+Require Import UIGL_UI_prelims.
+ +
+  Section UIPOne.
+ +
+  (* The formula defined by the function UI satisfies all the properties of
+      uniform interpolation. *)

+ +
+  Theorem UI_One : forall s p q, In (Var q) (propvar_subform (UI p (fst s, snd s))) ->
+                                                      ((q <> p) * (In (Var q) (propvar_subform_list (fst s ++ snd s)))).
+  Proof.
+  pose (LexSeq_ind (fun s => forall p q, In (Var q) (propvar_subform (UI p (fst s, snd s))) ->
+                                                      ((q <> p) * (In (Var q) (propvar_subform_list (fst s ++ snd s)))))).
+  apply p. clear p.
+  intros s0 H p q H0. rewrite propvar_subform_list_app.
+  destruct (empty_seq_dec s0).
+  (* s is the empty sequent. *)
+  { subst ; simpl in *. assert (GUI p ([],[]) Bot). apply GUI_empty_seq ; auto. apply UI_GUI in H1.
+    rewrite H1 in *. simpl in H0. inversion H0. }
+  { destruct (critical_Seq_dec s0).
+  (* s0 is a critical sequent *)
+  - destruct (dec_init_rules s0).
+    (* s0 is an initial sequent *)
+    + assert (is_init s0) ; auto.
+       assert (GUI p s0 Top). apply GUI_critic_init ; auto. apply UI_GUI in H1.
+       destruct s0. simpl in H0. rewrite H1 in H0. simpl in H0. inversion H0.
+    (* s0 is not an initial sequent *)
+    + remember (fst s0) as LHS.
+       assert (GUI p s0
+       (Or (list_disj (restr_list_prop p (snd s0)))
+       (Or (list_disj (map Neg (restr_list_prop p (fst s0))))
+       (Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq s0)))))
+       (Diam (list_conj (map (N p s0) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s0)), []%list)))))))))).
+       apply GUI_critic_not_init ; auto. 1-2: apply Gimap_map ; intros. apply UI_GUI ; auto.
+       apply (@N_spec p s0 x). apply UI_GUI in H1. destruct s0. rewrite HeqLHS in H0 ; simpl in H0. rewrite H1 in H0. simpl in H0.
+       repeat rewrite app_nil_r in H0. clear H1. rewrite HeqLHS ; simpl.
+       apply in_app_or in H0. destruct H0.
+ +
+       apply propvar_subform_list_disj in H0.
+       apply propvar_subform_list_restr_list_prop in H0. destruct H0 ; split ; auto. apply in_or_app ; auto.
+ +
+       apply in_app_or in H0 ; destruct H0. apply propvar_subform_list_disj in H0. apply propvar_subform_list_witness in H0.
+       destruct H0. destruct H0. apply in_map_iff in H0. destruct H0. destruct H0 ; subst. simpl in H1.
+       rewrite app_nil_r in H1. unfold restr_list_prop in H2. apply in_remove in H2. destruct H2.
+       pose (In_list_prop_LF _ _ H0). destruct p0. destruct s. subst. simpl in H1. destruct H1. inversion H1. subst.
+       destruct (string_dec q p). exfalso ; apply H2 ; subst ; auto. split ; auto. apply in_or_app ; left.
+       apply list_prop_LF_propvar_subform_list in H0 ; auto. inversion H1.
+ +
+       apply in_app_or in H0 ; destruct H0. apply propvar_subform_list_disj in H0. apply propvar_subform_list_witness in H0.
+       destruct H0. destruct H0. apply in_map_iff in H0. destruct H0. destruct H0 ; subst. simpl in H1.
+       apply in_map_iff in H2. destruct H2. destruct H0 ; subst. assert (In # q (propvar_subform (UI p (fst x, snd x)))).
+       destruct x ; auto. apply H in H0. destruct H0 ; split ; auto.
+       unfold GLR_prems in H2. destruct (finite_GLR_premises_of_S (nodupseq (l, l0))). simpl in H2.
+       apply In_InT_seqs in H2. apply InT_flatten_list_InT_elem in H2. destruct H2. destruct p1.
+       apply p0 in i1. inversion i1 ; subst. inversion i0 ; subst. 2: inversion X0. simpl in i. repeat rewrite propvar_subform_list_app.
+       simpl ; repeat rewrite propvar_subform_list_app.
+       repeat rewrite propvar_subform_list_app in i. apply in_app_or in i ; destruct i. apply in_app_or in H0 ; destruct H0.
+       apply in_or_app ; left. apply propvar_subform_list_XBoxed_list in H0.
+       pose (propvar_subform_list_nobox_gen_ext _ _ X _ H0). apply propvar_subform_list_nodup ; auto.
+       simpl in H0. rewrite app_nil_r in H0.
+       apply in_or_app ; right. apply propvar_subform_list_nodup ; rewrite <- H4 ; repeat rewrite propvar_subform_list_app ;
+       apply in_or_app ; right ; apply in_or_app ; auto. simpl in H0. rewrite app_nil_r in H0.
+       apply in_or_app ; right. apply propvar_subform_list_nodup ; rewrite <- H4 ; repeat rewrite propvar_subform_list_app ;
+       apply in_or_app ; right ; apply in_or_app ; auto.
+       unfold GLR_prems in H2. destruct (finite_GLR_premises_of_S (nodupseq (l, l0))). simpl in H2.
+       apply In_InT_seqs in H2. apply InT_flatten_list_InT_elem in H2. destruct H2. destruct p1.
+       apply p0 in i0. inversion i0 ; subst. inversion i ; subst. 2: inversion X0. apply DLW_wf_lex.lex_cons ; auto.
+       pose (GLR_applic_less_usable_boxes i0). rewrite <- ub_nodupseq in l1. apply l1 ; auto.
+       assert (is_init (l,l0) -> False) ; auto. pose (is_init_nodupseq (l,l0)). destruct p1. intro.
+       assert (is_init (nodupseq (l, l0))) ; auto. unfold is_init ; auto.
+ +
+       apply propvar_subform_list_conj in H0. apply propvar_subform_list_witness in H0.
+       destruct H0. destruct H0. apply in_map_iff in H0. destruct H0. destruct H0 ; subst.
+ +
+       pose (@N_spec p (l,l0) x0). destruct (dec_init_rules x0).
+       (* If x0 is initial. *)
+       assert (is_init x0) ; unfold is_init ; auto. pose (GN_inv_init _ g). rewrite <- e in H1 ; auto. simpl in H1. inversion H1.
+       (* If x0 is not initial. *)
+       destruct (Compare_dec.lt_dec (length (usable_boxes x0)) (length (usable_boxes (l, l0)))).
+       (* If x0 has less usable boxes than (XBoxed_list (top_boxes l), ). *)
+       assert ((forall (x : Seq) (l m : MPropF), (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x l -> (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x m -> l = m)).
+       intros. subst. auto. assert ((is_init x0 -> False)) ; auto.
+       epose (@GN_inv_noinit_lessub _ _ _ _ _ g H3 l1 (UI_spec p x0)). rewrite <- e in H1 ; auto. clear e.
+       assert (In # q (propvar_subform (UI p (fst x0, snd x0)))). destruct x0 ; simpl ; auto.
+       apply H in H4. destruct H4 ; split ; auto.
+       apply propvar_subform_list_Canopy with (A:=# q) in H2 ; auto. simpl in H2. rewrite app_nil_r in H2.
+       apply in_or_app ; left.
+       assert (J30: In # q (propvar_subform_list (XBoxed_list (top_boxes l)))). apply propvar_subform_list_nodup ; auto.
+       apply propvar_subform_list_XBoxed_list in J30. apply propvar_subform_list_top_boxes ; auto.
+       apply DLW_wf_lex.lex_cons ; auto.
+       (* If x0 does not have less usable boxes than (XBoxed_list (top_boxes l), ). *)
+       assert ((forall (x : Seq) (l m : MPropF), (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x l -> (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x m -> l = m)).
+       intros. subst. auto.
+       assert (J1: Gimap (GUI p) (GLR_prems (nodupseq x0)) (map (UI p) (GLR_prems (nodupseq x0)))).
+       apply Gimap_map ; auto. intros ; apply UI_GUI ; auto. assert ((is_init x0 -> False)) ; auto.
+       pose (@GN_inv_noinit_nolessub p _ _ _ _ g H3 n0 J1).
+       rewrite <- e in H1. clear e. clear J1. clear H0. simpl in H1. repeat rewrite app_nil_r in H1. apply in_app_or in H1.
+       destruct H1. apply propvar_subform_list_disj in H0. apply propvar_subform_list_restr_list_prop in H0. destruct H0 ; split ; auto.
+       apply propvar_subform_list_Canopy with (A:=# q) in H2 ; auto. simpl in H2. rewrite app_nil_r in H2.
+       apply in_or_app ; left.
+       assert (J30: In # q (propvar_subform_list (XBoxed_list (top_boxes l)))). apply propvar_subform_list_nodup ; auto.
+       apply propvar_subform_list_XBoxed_list in J30. apply propvar_subform_list_top_boxes ; auto.
+       rewrite propvar_subform_list_app. apply in_or_app ;auto.
+       apply in_app_or in H0. destruct H0. apply propvar_subform_list_disj in H0. apply propvar_subform_list_witness in H0.
+       destruct H0. destruct H0. apply In_InT in H0. apply InT_map_iff in H0. destruct H0. destruct p0 ; subst. simpl in H1.
+       rewrite app_nil_r in H1. unfold restr_list_prop in i. apply InT_In in i. apply in_remove in i. destruct i.
+       pose (In_list_prop_LF _ _ H0). destruct p0. destruct s. subst. simpl in H1. destruct H1. inversion H1. subst.
+       destruct (string_dec q p). exfalso ; apply H4 ; subst ; auto. split ; auto. apply in_or_app ; left.
+       apply list_prop_LF_propvar_subform_list in H0 ; auto. apply propvar_subform_list_Canopy with (A:=# q) in H2 ; auto.
+       simpl in H2. rewrite app_nil_r in H2.
+       assert (J30: In # q (propvar_subform_list (XBoxed_list (top_boxes l)))). apply propvar_subform_list_nodup ; auto.
+       apply propvar_subform_list_XBoxed_list in J30. apply propvar_subform_list_top_boxes ; auto.
+       rewrite propvar_subform_list_app. apply in_or_app ;auto. inversion H1.
+       apply propvar_subform_list_disj in H0. apply propvar_subform_list_witness in H0.
+       destruct H0. destruct H0. apply In_InT in H0. apply InT_map_iff in H0. destruct H0. destruct p0 ; subst. simpl in H1.
+       apply InT_map_iff in i. destruct i. destruct p0 ; subst. assert (In # q (propvar_subform (UI p (fst x, snd x)))).
+       destruct x ; simpl ; auto. apply H in H0. destruct H0 ; split ; auto.
+       unfold GLR_prems in i. destruct (finite_GLR_premises_of_S (nodupseq x0)). simpl in i.
+       apply InT_flatten_list_InT_elem in i. destruct i. destruct p1.
+       apply p0 in i1. inversion i1 ; subst. inversion i ; subst. 2: inversion H4. simpl in i0.
+       repeat rewrite propvar_subform_list_app in i0. simpl in i0. repeat rewrite app_nil_r in i0.
+       apply in_app_or in i0 ; destruct i0. apply in_app_or in H0 ; destruct H0.
+       apply in_or_app ; left. apply propvar_subform_list_XBoxed_list in H0.
+       pose (propvar_subform_list_nobox_gen_ext _ _ X _ H0). rewrite propvar_subform_list_nodup in i0 ; auto.
+       apply propvar_subform_list_Canopy with (A:=# q) in H2 ; auto. simpl in H2. rewrite app_nil_r in H2.
+       assert (J30: In # q (propvar_subform_list (XBoxed_list (top_boxes l)))). apply propvar_subform_list_nodup ; auto.
+       apply propvar_subform_list_XBoxed_list in J30. apply propvar_subform_list_top_boxes ; auto.
+       rewrite propvar_subform_list_app. apply in_or_app ;auto.
+       apply propvar_subform_list_Canopy with (A:=# q) in H2 ; auto. simpl in H2. rewrite app_nil_r in H2.
+       assert (J30: In # q (propvar_subform_list (XBoxed_list (top_boxes l)))). apply propvar_subform_list_nodup ; auto.
+       apply propvar_subform_list_XBoxed_list in J30. apply in_or_app ; left. apply propvar_subform_list_top_boxes ; auto.
+       simpl. repeat rewrite propvar_subform_list_app ; simpl. apply in_or_app ; right. apply propvar_subform_list_nodup ; auto.
+       rewrite <- H6. repeat rewrite propvar_subform_list_app ; simpl. apply in_or_app ; right ; apply in_or_app ; auto.
+       apply propvar_subform_list_Canopy with (A:=# q) in H2 ; auto. simpl in H2. rewrite app_nil_r in H2.
+       assert (J30: In # q (propvar_subform_list (XBoxed_list (top_boxes l)))). apply propvar_subform_list_nodup ; auto.
+       apply propvar_subform_list_XBoxed_list in J30. apply in_or_app ; left. apply propvar_subform_list_top_boxes ; auto.
+       simpl. repeat rewrite propvar_subform_list_app ; simpl. apply in_or_app ; right. apply propvar_subform_list_nodup ; auto.
+       rewrite <- H6. repeat rewrite propvar_subform_list_app ; simpl. apply in_or_app ; right ; apply in_or_app ; auto.
+       apply DLW_wf_lex.lex_cons ; auto. unfold GLR_prems in i. destruct (finite_GLR_premises_of_S (nodupseq x0)). simpl in i.
+       apply InT_flatten_list_InT_elem in i. destruct i. destruct p1.
+       apply p0 in i0. inversion i0 ; subst. inversion i ; subst. 2: inversion H5.
+       pose (GLR_applic_less_usable_boxes i0). rewrite <- ub_nodupseq in l1.
+       apply In_InT_seqs in H2 ; apply leq_ub_Canopy in H2. pose (set_leq_ub_unif (l, l0)). simpl in l1. simpl in l2.
+       assert (length (usable_boxes (XBoxed_list ++ [Box A], [A])) < length (usable_boxes x0)). apply l1 ; auto.
+       pose (is_init_nodupseq x0). destruct p1. intro. assert (is_init (nodupseq x0)) ; auto. unfold is_init ; auto.
+       lia.
+  (* s0 is not a critical sequent *)
+  - assert (GUI p s0 (list_conj (map (UI p) (Canopy (nodupseq s0))))). apply GUI_not_critic ; auto.
+    apply Gimap_map ; intros ; apply UI_GUI ; auto. apply UI_GUI in H1. destruct s0.
+    simpl in H0. rewrite H1 in H0. apply propvar_subform_list_conj in H0.
+    apply propvar_subform_list_witness in H0. destruct H0. destruct H0. apply in_map_iff in H0.
+    destruct H0. destruct H0 ; subst. simpl. assert (In # q (propvar_subform (UI p (fst x0, snd x0)))).
+    destruct x0 ; auto. pose (In_InT_seqs _ _ H3). apply Canopy_LexSeq in i. destruct i ; subst.
+    simpl in H0. exfalso. apply f. apply In_InT_seqs in H3 ; apply Canopy_critical in H3 ; auto.
+    apply critical_nodupseq ; auto.
+    apply H in H0 ; auto. destruct H0 ; split ; auto.
+    apply propvar_subform_list_Canopy with (A:=# q) in H3 ; auto.
+    simpl in H3 ; rewrite propvar_subform_list_app in H3 ; auto.
+    apply in_app_or in H3 ; destruct H3. apply in_or_app ; left. apply propvar_subform_list_nodup ; auto.
+    apply in_or_app ; right. apply propvar_subform_list_nodup ; auto.
+    apply LexSeq_nodupseq ; auto. }
+  Qed.
+ +
+  End UIPOne.
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_UIThree.html b/GL.Interpolation.UIGL_UIThree.html new file mode 100644 index 0000000..5db3be7 --- /dev/null +++ b/GL.Interpolation.UIGL_UIThree.html @@ -0,0 +1,808 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_UIThree

+ +
+(* Uniform interpolation *)
+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat Arith.
+Require Import Lia.
+ +
+Require Import general_export.
+ +
+Require Import GLS_export.
+ +
+Require Import UIGL_Def_measure.
+Require Import UIGL_Canopy.
+Require Import UIGL_irred_short.
+Require Import UIGL_braga.
+Require Import UIGL_LexSeq.
+Require Import UIGL_nodupseq.
+Require Import UIGL_PermutationT.
+Require Import UIGL_PermutationTS.
+Require Import UIGL_And_Or_rules.
+Require Import UIGL_UI_prelims.
+Require Import UIGL_UI_inter.
+Require Import UIGL_UIDiam_N.
+ +
+  Section UIPThree.
+ +
+  Theorem UI_Three : forall s p X0 Y0,
+                                    (In (Var p) (propvar_subform_list (X0 ++ Y0)) -> False) ->
+                                    GLS_prv (fst s ++ X0, snd s ++ Y0) ->
+                                    GLS_prv (X0, (UI p s) :: Y0).
+  Proof.
+  (* Setting up the strong induction on the height of the derivation (PIH) and
+      on the measure of the sequent using LexSeq (SIH). *)

+  intros s p X0 Y0 NotVar D. generalize dependent NotVar. remember (fst s ++ X0, snd s ++ Y0) as scomp.
+  generalize dependent Heqscomp. remember (derrec_height D) as n. generalize dependent Heqn.
+  generalize dependent Y0. generalize dependent X0. generalize dependent D.
+  generalize dependent scomp. generalize dependent s. generalize dependent n.
+  induction n as [n PIH] using (well_founded_induction_type lt_wf).
+  pose (d:=LexSeq_ind (fun (s:Seq) => forall (scomp : list MPropF * list MPropF) (D : GLS_prv scomp) (X0 Y0 : list MPropF),
+                n = derrec_height D ->
+                scomp = (fst s ++ X0, snd s ++ Y0) -> (In # p (propvar_subform_list (X0 ++ Y0)) -> False) -> GLS_prv (X0, UI p s :: Y0))).
+  apply d. clear d. intros k SIH.
+ +
+  (* Now we do the actual proof-theoretical work. *)
+  intros s0 D0. remember D0 as D0'. destruct D0.
+  (* D0 is a leaf *)
+  - inversion f.
+  (* D0 ends with an application of rule *)
+  - intros X0 Y0 hei idseq propvar. destruct (empty_seq_dec k) as [ EE | NE].
+    { subst ; simpl in *.
+       assert (J1: GLS_prv (X0, Y0)). apply derI with ps ; auto. apply GLS_prv_wkn_R with (X0, Y0) (UI p ([], [])) ; auto.
+       apply (wkn_RI _ _ []). }
+    { inversion g ; subst.
+    (* IdP *)
+    * inversion H ; subst.
+      assert (InT (# P) (fst k ++ X0)). rewrite <- H2. apply InT_or_app ; right ; apply InT_eq.
+      apply InT_app_or in H0.
+      assert (InT (# P) (snd k ++ Y0)). rewrite <- H3. apply InT_or_app ; right ; apply InT_eq.
+      apply InT_app_or in H1. destruct H0 ; destruct H1.
+      + assert ((X0, UI p k :: Y0) = (X0, [] ++ UI p k :: Y0)). auto. rewrite H0. apply is_init_UI.
+         left ; left. destruct k. simpl in i ; simpl in i0. apply InT_split in i. destruct i. destruct s ; subst.
+         apply InT_split in i0. destruct i0. destruct s ; subst. apply IdPRule_I.
+      + destruct (critical_Seq_dec k).
+         -- destruct (dec_init_rules k).
+            ** assert (is_init k) ; auto. assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+                pose (@GUI_inv_critic_init p k _ J0 c X). rewrite <- e.
+                assert ((X0, Top :: Y0) = (X0, [] ++ Top :: Y0)). auto. rewrite H0. apply TopR.
+            ** assert ((is_init k) -> False) ; auto. assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+                assert (J1: Gimap (GUI p) (GLR_prems (nodupseq k)) (map (UI p) (GLR_prems (nodupseq k)))). apply Gimap_map. intros.
+                apply UI_GUI ; auto.
+                assert (J2: (Gimap (GN p (GUI p) k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), [])))
+                (map (N p k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), [])))))). apply Gimap_map. intros.
+                apply (N_spec p k x).
+                assert (J40: fst k <> []). intro. rewrite H1 in i ; inversion i.
+                pose (@GUI_inv_critic_not_init p k _ _ _ J0 c NE H0 J1 J2). rewrite <- e.
+                pose (OrR (X0,Y0)). simpl in g0. apply g0.
+                apply (@GLS_adm_list_exch_R (X0,
+                Or (list_disj (map Neg (restr_list_prop p (fst k))))
+                   (Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq k)))))
+                      (Diam
+                         (list_conj
+                            (map (N p k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), []%list)))))))
+                 :: list_disj (restr_list_prop p (snd k)) :: Y0)).
+                2: epose (list_exch_RI _ [] [Or (list_disj (map Neg (restr_list_prop p (fst k)))) (Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq k)))))
+                (Diam (list_conj (map (N p k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), []%list)))))))] [] [list_disj (restr_list_prop p (snd k))] Y0) ; simpl in l ; apply l.
+                pose (OrR (X0,list_disj (restr_list_prop p (snd k)) :: Y0)). simpl in g1. apply g1.
+                assert (J3: InT (Neg # P) (map Neg (restr_list_prop p (fst k)))). unfold restr_list_prop. apply InT_map_iff.
+                exists (# P) ; split ; auto. apply In_InT. apply in_not_touched_remove. apply In_list_In_list_prop_LF ; apply InT_In ; auto.
+                intro. apply propvar. rewrite <- H1. rewrite propvar_subform_list_app. apply in_or_app ; right.
+                apply In_list_In_propvar_subform_list ; apply InT_In ; auto.
+                remember (Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq k))))) (Diam (list_conj
+                       (map (N p k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), []%list))))))
+                 :: list_disj (restr_list_prop p (snd k)) :: Y0) as Y.
+                pose (list_disj_wkn_R (map Neg (restr_list_prop p (fst k))) (X0, Y) (Neg # P) J3). apply g2. simpl.
+                unfold Neg. apply derI with (ps:=[([] ++ # P :: X0, [] ++ :: Y)]). apply ImpR. assert ((X0, # P --> :: Y) = ([] ++ X0, [] ++ # P --> :: Y)).
+                auto. rewrite H1. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+                assert (InT (# P) ([] ++ :: Y)). simpl. apply InT_cons. rewrite HeqY. repeat apply InT_cons ; auto.
+                apply InT_split in H1. destruct H1. destruct s. rewrite e0. apply derI with (ps:=[]). apply IdP. apply IdPRule_I.
+                apply dlNil.
+         -- assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+            assert (J1: Gimap (GUI p) (Canopy (nodupseq k)) (map (UI p) (Canopy (nodupseq k)))). apply Gimap_map. intros.
+            apply UI_GUI ; auto.
+            pose (@GUI_inv_not_critic p k _ _ J0 f J1). rewrite <- e.
+            pose (list_conj_R (map (UI p) (Canopy (nodupseq k))) (X0,Y0)). simpl in g0. apply g0. intros.
+            apply InT_map_iff in H0. destruct H0. destruct p0. subst.
+            assert (LexSeq x k). pose (Canopy_LexSeq _ _ i1). destruct s ; subst ; auto. exfalso.
+            apply f ; apply Canopy_critical in i1 ; auto. apply critical_nodupseq ; auto. apply LexSeq_nodupseq in l ; auto.
+            simpl in SIH.
+            assert (J2: GLS_rules [] (fst x ++ X0, snd x ++ Y0)).
+            apply IdP. assert (InT (# P) (snd x ++ Y0)). apply InT_or_app ; auto. apply InT_split in H1.
+            destruct H1. destruct s. rewrite e0. assert (InT (# P) (fst x ++ X0)). apply InT_or_app ; left.
+            apply Canopy_neg_var with (q:=P) in i1 ; auto. apply In_InT. destruct k ; simpl. apply nodup_In ; simpl in i ; apply InT_In in i ; auto.
+            apply InT_split in H1. destruct H1. destruct s. rewrite e1.
+            apply IdPRule_I. pose (derI _ J2 d).
+            assert (J3: S (dersrec_height d) = derrec_height d0). simpl. lia.
+            assert (J4: (fst x ++ X0, snd x ++ Y0) = (fst x ++ X0, snd x ++ Y0)). auto.
+            pose (SIH _ H0 _ _ _ _ J3 J4 propvar). auto.
+      + destruct (critical_Seq_dec k).
+         -- destruct (dec_init_rules k).
+            ** assert (is_init k) ; auto. assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+                pose (@GUI_inv_critic_init p k _ J0 c X). rewrite <- e.
+                assert ((X0, Top :: Y0) = (X0, [] ++ Top :: Y0)). auto. rewrite H0. apply TopR.
+            ** assert ((is_init k) -> False) ; auto. assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+                assert (J1: Gimap (GUI p) (GLR_prems (nodupseq k)) (map (UI p) (GLR_prems (nodupseq k)))). apply Gimap_map. intros.
+                apply UI_GUI ; auto.
+                assert (J2: (Gimap (GN p (GUI p) k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), [])))
+                (map (N p k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), [])))))). apply Gimap_map. intros.
+                apply (N_spec p k x).
+                pose (@GUI_inv_critic_not_init p k _ _ _ J0 c NE H0 J1 J2). rewrite <- e.
+                pose (OrR (X0,Y0)). simpl in g0. apply g0.
+                assert (J3: InT (# P) (restr_list_prop p (snd k))). unfold restr_list_prop. apply In_InT.
+                apply in_not_touched_remove. apply In_list_In_list_prop_LF ; apply InT_In ; auto.
+                intro. apply propvar. rewrite <- H1. rewrite propvar_subform_list_app. apply in_or_app ; left.
+                apply In_list_In_propvar_subform_list ; apply InT_In ; auto.
+                remember (Or (list_disj (map Neg (restr_list_prop p (fst k)))) (Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq k))))) (Diam
+                (list_conj (map (N p k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), []%list))))))) :: Y0) as Y.
+                pose (list_disj_wkn_R (restr_list_prop p (snd k)) (X0, Y) (# P) J3). apply g1. simpl.
+                apply InT_split in i. destruct i. destruct s. rewrite e0. apply derI with (ps:=[]). apply IdP. 2: apply dlNil.
+                assert ((x ++ # P :: x0, # P :: Y) = (x ++ # P :: x0, [] ++ # P :: Y)). auto. rewrite H1 ; apply IdPRule_I.
+         -- assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+            assert (J1: Gimap (GUI p) (Canopy (nodupseq k)) (map (UI p) (Canopy (nodupseq k)))). apply Gimap_map. intros.
+            apply UI_GUI ; auto.
+            pose (@GUI_inv_not_critic p k _ _ J0 f J1). rewrite <- e.
+            pose (list_conj_R (map (UI p) (Canopy (nodupseq k))) (X0,Y0)). simpl in g0. apply g0. intros.
+            apply InT_map_iff in H0. destruct H0. destruct p0. subst.
+            assert (LexSeq x k). pose (Canopy_LexSeq _ _ i1). destruct s ; subst ; auto. exfalso.
+            apply f ; apply Canopy_critical in i1 ; auto. apply critical_nodupseq ; auto. apply LexSeq_nodupseq in l ; auto. simpl in SIH.
+            assert (J2: GLS_rules [] (fst x ++ X0, snd x ++ Y0)).
+            apply IdP. assert (InT (# P) (fst x ++ X0)). apply InT_or_app ; auto. apply InT_split in H1.
+            destruct H1. destruct s. rewrite e0. assert (InT (# P) (snd x ++ Y0)). apply InT_or_app ; left.
+            apply Canopy_pos_var with (q:=P) in i1 ; auto. auto. apply In_InT. destruct k ; simpl. apply nodup_In ; simpl in i0 ; apply InT_In in i0 ; auto.
+            apply InT_split in H1. destruct H1. destruct s. rewrite e1.
+            apply IdPRule_I. pose (derI _ J2 d).
+            assert (J3: S (dersrec_height d) = derrec_height d0). simpl. lia.
+            assert (J4: (fst x ++ X0, snd x ++ Y0) = (fst x ++ X0, snd x ++ Y0)). auto.
+            pose (SIH _ H0 _ _ _ _ J3 J4 propvar). auto.
+      + apply derI with (ps:=[]). 2: apply dlNil. apply IdP. apply InT_split in i. destruct i. destruct s ; subst.
+         apply InT_split in i0. destruct i0. destruct s ; subst. assert (UI p k :: x1 ++ # P :: x2 = (UI p k :: x1) ++ # P :: x2).
+         auto. rewrite H0. apply IdPRule_I.
+ +
+    (* BotL *)
+    * inversion H ; subst.
+      assert (InT (fst k ++ X0)). rewrite <- H2. apply InT_or_app ; right ; apply InT_eq.
+      apply InT_app_or in H0. destruct H0.
+      + assert ((X0, UI p k :: Y0) = (X0, [] ++ UI p k :: Y0)). auto. rewrite H0. apply is_init_UI.
+         right. destruct k. simpl in i. apply InT_split in i. destruct i. destruct s ; subst. apply BotLRule_I.
+      + apply derI with (ps:=[]). 2: apply dlNil. apply BotL. apply InT_split in i. destruct i. destruct s ; subst.
+         apply BotLRule_I.
+ +
+    (* ImpR *)
+    * destruct (critical_Seq_dec k).
+      (* If critical, then the rule ImpR was applied on a formula in X0 or Y0.
+          So, apply PIH omn the premise and then the rule. *)

+      + inversion H ; subst. assert (J0: dersrec_height d = dersrec_height d) ; auto.
+         apply dersrec_derrec_height in J0. destruct J0.
+         assert (J1: derrec_height x = derrec_height x). auto.
+         assert (J2: list_exch_L (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) (A :: fst k ++ X0, Δ0 ++ B :: Δ1)).
+         assert ((Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) = ([] ++ [] ++ Γ0 ++ [A] ++ Γ1, Δ0 ++ B :: Δ1)). auto.
+         rewrite H0.
+         assert ((A :: fst k ++ X0, Δ0 ++ B :: Δ1) = ([] ++ [A] ++ Γ0 ++ [] ++ Γ1, Δ0 ++ B :: Δ1)).
+         simpl. rewrite H2. auto. rewrite H1. apply list_exch_LI.
+         pose (GLS_hpadm_list_exch_L x J1 J2). destruct s.
+         assert (J3: derrec_height x0 = derrec_height x0). auto.
+         assert (J4: list_exch_L (A :: fst k ++ X0, Δ0 ++ B :: Δ1) (fst k ++ A :: X0, Δ0 ++ B :: Δ1)).
+         assert ((fst k ++ A :: X0, Δ0 ++ B :: Δ1) = ([] ++ [] ++ fst k ++ [A] ++ X0, Δ0 ++ B :: Δ1)). auto.
+         rewrite H0.
+         assert ((A :: fst k ++ X0, Δ0 ++ B :: Δ1) = ([] ++ [A] ++ fst k ++ [] ++ X0, Δ0 ++ B :: Δ1)).
+         auto. rewrite H1. apply list_exch_LI.
+         pose (GLS_hpadm_list_exch_L x0 J3 J4). destruct s. simpl in PIH.
+         apply app2_find_hole in H3. destruct H3.
+         repeat destruct s ; destruct p0 ; subst.
+         assert (J5: derrec_height x1 < S (dersrec_height d)). lia.
+         assert (J6: derrec_height x1 = derrec_height x1). auto.
+         assert (J7: (fst k ++ A :: X0, snd k ++ B :: Δ1) = (fst k ++ A:: X0, snd k ++ B :: Δ1)). auto.
+         assert (J8: (In # p (propvar_subform_list ((A :: X0) ++ B :: Δ1)) -> False)).
+         intro. apply propvar. repeat rewrite propvar_subform_list_app.
+         repeat rewrite propvar_subform_list_app in H0. simpl in H0. simpl.
+         repeat rewrite <- app_assoc in H0.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ;
+         left ; apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ;
+         left ; apply in_or_app ; auto. apply in_or_app ; right ; apply in_or_app ; auto.
+         pose (PIH _ J5 _ _ _ _ _ J6 J7 J8).
+         apply derI with (ps:=[([] ++ A :: X0, [UI p k] ++ B :: Δ1)]). apply ImpR.
+         assert ((X0, UI p k :: A --> B :: Δ1) = ([] ++ X0, [UI p k] ++ A --> B :: Δ1)). auto. rewrite H0.
+         apply ImpRRule_I. apply dlCons ; [ simpl ; auto | apply dlNil].
+         destruct x2 ; simpl in e1 ; subst. rewrite app_nil_r in e0 ; subst.
+         assert (J5: derrec_height x1 < S (dersrec_height d)). lia.
+         assert (J6: derrec_height x1 = derrec_height x1). auto.
+         assert (J7: (fst k ++ A :: X0, snd k ++ B :: Δ1) = (fst k ++ A:: X0, snd k ++ B :: Δ1)). auto.
+         assert (J8: (In # p (propvar_subform_list ((A :: X0) ++ B :: Δ1)) -> False)).
+         intro. apply propvar. repeat rewrite propvar_subform_list_app.
+         repeat rewrite propvar_subform_list_app in H0. simpl in H0. simpl.
+         repeat rewrite <- app_assoc in H0.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ;
+         left ; apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ;
+         left ; apply in_or_app ; auto. apply in_or_app ; right ; apply in_or_app ; auto.
+         pose (PIH _ J5 _ _ _ _ _ J6 J7 J8).
+         apply derI with (ps:=[([] ++ A :: X0, [UI p k] ++ B :: Δ1)]). apply ImpR.
+         assert ((X0, UI p k :: A --> B :: Δ1) = ([] ++ X0, [UI p k] ++ A --> B :: Δ1)). auto. rewrite H0.
+         apply ImpRRule_I. apply dlCons ; [ simpl ; auto | apply dlNil].
+         exfalso. destruct k ; simpl in e0 ; subst. unfold critical_Seq in c ; unfold is_Prime in c ; simpl in c.
+         assert (In m (l1 ++ Δ0 ++ m :: x2)). apply in_or_app ; right ; apply in_or_app ; right ; apply in_eq.
+         apply c in H0. inversion e1 ; subst. destruct H0 ; destruct H0 ; inversion H0 ; inversion H1.
+         assert (J5: derrec_height x1 < S (dersrec_height d)). lia.
+         assert (J6: derrec_height x1 = derrec_height x1). auto.
+         assert (J7: (fst k ++ A :: X0, (snd k ++ x2) ++ B :: Δ1) = (fst k ++ A:: X0, snd k ++ x2 ++ B :: Δ1)).
+         repeat rewrite <- app_assoc. auto.
+         assert (J8: (In # p (propvar_subform_list ((A :: X0) ++ (x2 ++ B :: Δ1))) -> False)).
+         intro. apply propvar. repeat rewrite propvar_subform_list_app.
+         repeat rewrite propvar_subform_list_app in H0. simpl in H0. simpl.
+         repeat rewrite <- app_assoc in H0.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ;
+         right ; apply in_or_app ; left ; apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ;
+         right ; apply in_or_app ; left ; apply in_or_app ; auto.
+         apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+         pose (PIH _ J5 _ _ _ _ _ J6 J7 J8).
+         apply derI with (ps:=[([] ++ A :: X0, (UI p k :: x2) ++ B :: Δ1)]). apply ImpR.
+         assert ((X0, UI p k :: x2 ++ A --> B :: Δ1) = ([] ++ X0, (UI p k :: x2) ++ A --> B :: Δ1)). auto. rewrite H0.
+         apply ImpRRule_I. apply dlCons ; [ simpl ; auto | apply dlNil].
+      (*  If not critical, consider the conjunction that UI p k is. *)
+      + assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+         assert (J1: Gimap (GUI p) (Canopy (nodupseq k)) (map (UI p) (Canopy (nodupseq k)))). apply Gimap_map. intros.
+         apply UI_GUI ; auto.
+         pose (@GUI_inv_not_critic p k (UI p k) (map (UI p) (Canopy (nodupseq k))) J0 f J1). rewrite <- e.
+ +
+         assert (J2: forall s1, InT s1 (Canopy (nodupseq k)) -> GLS_prv (X0, UI p s1 :: Y0)).
+         intros. pose (fold_Canopy _ _ H0). destruct s ; subst.
+         exfalso. apply f. apply Canopy_critical in H0 ; auto. apply critical_nodupseq in H0 ; auto.
+         destruct s. destruct p0. unfold inv_prems in i.
+         apply InT_flatten_list_InT_elem in i. destruct i. destruct p0. simpl in PIH. simpl in SIH.
+         pose (derI _ g d).
+         assert (existsT2 (d1: GLS_prv (fst (nodupseq k) ++ X0, snd (nodupseq k) ++ Y0)), derrec_height d1 <= derrec_height d0).
+         destruct (nodupseq_id k). destruct p0. destruct s. destruct s. destruct p1. destruct p1.
+         pose (PermutationTS_prv_hpadm _ d0 (x2 ++ fst x1 ++ X0, x3 ++ snd x1 ++ Y0)). destruct s.
+         split ; simpl ; apply Permutation_PermutationT. destruct p1.
+         pose (@Permutation_app _ (fst k) X0 (x2 ++ fst x1) X0). rewrite <- app_assoc in p3 ; apply p3 ; auto.
+         apply Permutation_PermutationT ; auto. destruct p1.
+         pose (@Permutation_app _ (snd k) Y0 (x3 ++ snd x1) Y0). rewrite <- app_assoc in p3 ; apply p3 ; auto.
+         apply Permutation_PermutationT ; auto.
+         epose (incl_ctr_R_hpadm _ x3 _ x4). destruct s. intros A HA ; apply in_or_app ; left ; auto.
+         epose (incl_ctr_L_hpadm x2 _ _ x5). destruct s. intros A HA ; apply in_or_app ; left ; auto.
+         pose (PermutationTS_prv_hpadm _ x6 (fst (nodupseq k) ++ X0, snd (nodupseq k) ++ Y0)). destruct s.
+         split ; simpl ; apply Permutation_PermutationT. destruct p0. apply Permutation_app ; auto.
+         unfold nodupseq in p0. apply Permutation_PermutationT ; auto. destruct p0.
+         apply Permutation_app ; auto. unfold nodupseq in p2. apply Permutation_PermutationT ; auto.
+         exists x7. lia. destruct X.
+         assert (J2: derrec_height x1 = derrec_height x1). auto.
+         assert (J3: (fst (nodupseq k) ++ X0, snd (nodupseq k) ++ Y0) = (fst (nodupseq k) ++ X0, snd (nodupseq k) ++ Y0)). auto.
+         pose (Canopy_hp_inv_ctx (nodupseq k) _ _ x1 X0 Y0 J2 J3 _ H0). destruct s.
+         destruct (Compare_dec.lt_dec (derrec_height x2) (S (dersrec_height d))).
+         (* Use PIH. *)
+         pose (fold_Canopy _ _ H0). destruct s ; subst.
+         exfalso. apply f. apply Canopy_critical in H0 ; auto. apply critical_nodupseq in H0 ; auto.
+         destruct s. destruct p0. unfold inv_prems in i2.
+         apply InT_flatten_list_InT_elem in i2. destruct i2. destruct p0.
+         assert (J4: derrec_height x2 = derrec_height x2). auto.
+         assert (J5: (fst s1 ++ X0, snd s1 ++ Y0) = (fst s1 ++ X0, snd s1 ++ Y0)). auto.
+         pose (PIH _ l1 s1 _ x2 X0 Y0 J4 J5). apply g0 ; auto.
+         (* Use SIH. *)
+         assert (derrec_height x2 = S (dersrec_height d)). assert (derrec_height d0 = S (dersrec_height d)). simpl. auto. lia.
+         assert (J4: LexSeq s1 k). pose (Canopy_LexSeq _ _ H0).
+         destruct s ; subst ; auto. exfalso. apply f. apply Canopy_critical in H0 ; apply critical_nodupseq in H0 ; auto.
+         apply LexSeq_nodupseq in l1 ; auto. symmetry in H1.
+         assert (J5: (fst s1 ++ X0, snd s1 ++ Y0) = (fst s1 ++ X0, snd s1 ++ Y0)). auto.
+         pose (SIH _ J4 _ _ _ _ H1 J5 propvar). auto.
+ +
+         assert (J3: (forall A : MPropF, InT A (map (UI p) (Canopy (nodupseq k))) -> GLS_prv (fst (X0, Y0), A :: snd (X0, Y0)))).
+         intros. simpl. apply InT_map_iff in H0. destruct H0. destruct p0 ; subst. apply J2 in i ; auto.
+         pose (list_conj_R _ _ J3). simpl in g0. auto.
+ +
+    (* ImpL *)
+    * destruct (critical_Seq_dec k).
+      (* If critical, then the rule ImpL was applied on a formula in X0 or Y0.
+          So, apply PIH on the premises and then the rule. *)

+      + inversion H ; subst. assert (J0: dersrec_height d = dersrec_height d) ; auto.
+         apply dersrec_derrec2_height in J0. destruct J0. destruct s. simpl in PIH.
+         assert (J1: derrec_height x = derrec_height x). auto.
+         assert (J2: list_exch_R (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) (Γ0 ++ Γ1, A :: snd k ++ Y0)).
+         assert ((Γ0 ++ Γ1, Δ0 ++ A :: Δ1) = (Γ0 ++ Γ1, [] ++ [] ++ Δ0 ++ [A] ++ Δ1)). auto.
+         rewrite H0.
+         assert ((Γ0 ++ Γ1, A :: snd k ++ Y0) = (Γ0 ++ Γ1, [] ++ [A] ++ Δ0 ++ [] ++ Δ1)).
+         simpl. rewrite H3. auto. rewrite H1. apply list_exch_RI.
+         pose (GLS_hpadm_list_exch_R x J1 J2). destruct s.
+         assert (J3: derrec_height x1 = derrec_height x1). auto.
+         assert (J4: list_exch_R (Γ0 ++ Γ1, A :: snd k ++ Y0) (Γ0 ++ Γ1, snd k ++ A :: Y0)).
+         assert ((Γ0 ++ Γ1, snd k ++ A :: Y0) = (Γ0 ++ Γ1, [] ++ [] ++ snd k ++ [A] ++ Y0)). auto.
+         rewrite H0.
+         assert ((Γ0 ++ Γ1, A :: snd k ++ Y0) = (Γ0 ++ Γ1, [] ++ [A] ++ snd k ++ [] ++ Y0)).
+         auto. rewrite H1. apply list_exch_RI.
+         pose (GLS_hpadm_list_exch_R x1 J3 J4). destruct s.
+         apply app2_find_hole in H2. destruct H2.
+         repeat destruct s ; destruct p0 ; subst.
+         assert (J5: derrec_height x2 < S (dersrec_height d)). lia.
+         assert (J6: derrec_height x2 = derrec_height x2). auto.
+         assert (J7: (fst k ++ Γ1, snd k ++ A :: Y0) = (fst k ++ Γ1, snd k ++ A :: Y0)). auto.
+         assert (J8: In # p (propvar_subform_list (Γ1 ++ A :: Y0)) -> False).
+         intro. apply propvar. repeat rewrite propvar_subform_list_app.
+         repeat rewrite propvar_subform_list_app in H0. simpl in H0. simpl.
+         repeat rewrite <- app_assoc.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ;
+         right ; apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; auto. apply in_or_app ; right ; apply in_or_app ;
+         right ; apply in_or_app ; auto.
+         pose (PIH _ J5 _ _ _ _ _ J6 J7 J8).
+         assert (J9: derrec_height x0 < S (dersrec_height d)). lia.
+         assert (J10: derrec_height x0 = derrec_height x0). auto.
+         assert (J11: (fst k ++ B :: Γ1, Δ0 ++ Δ1) = (fst k ++ B :: Γ1, snd k ++ Y0)). rewrite H3 ; auto.
+         assert (J12: In # p (propvar_subform_list ((B :: Γ1) ++ Y0)) -> False).
+         intro. apply propvar. repeat rewrite propvar_subform_list_app.
+         repeat rewrite propvar_subform_list_app in H0. simpl in H0. simpl.
+         repeat rewrite <- app_assoc. repeat rewrite <- app_assoc in H0.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ;
+         right ; apply in_or_app ; auto. apply in_or_app ; right ; apply in_or_app ;
+         right ; apply in_or_app ; auto.
+         pose (PIH _ J9 _ _ _ _ _ J10 J11 J12).
+         apply derI with (ps:=[([] ++ Γ1, [UI p k] ++ A :: Y0);([] ++ B :: Γ1, [UI p k] ++ Y0)]). apply ImpL.
+         assert ((A --> B :: Γ1, UI p k :: Y0) = ([] ++ A --> B :: Γ1, [UI p k] ++ Y0)). auto. rewrite H0.
+         apply ImpLRule_I. apply dlCons. auto. apply dlCons. auto. apply dlNil.
+         destruct x3 ; simpl in e1 ; subst. rewrite app_nil_r in e0 ; subst.
+         assert (J5: derrec_height x2 < S (dersrec_height d)). lia.
+         assert (J6: derrec_height x2 = derrec_height x2). auto.
+         assert (J7: (fst k ++ Γ1, snd k ++ A :: Y0) = (fst k ++ Γ1, snd k ++ A :: Y0)). auto.
+         assert (J8: In # p (propvar_subform_list (Γ1 ++ A :: Y0)) -> False).
+         intro. apply propvar. repeat rewrite propvar_subform_list_app.
+         repeat rewrite propvar_subform_list_app in H0. simpl in H0. simpl.
+         repeat rewrite <- app_assoc.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ;
+         right ; apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; auto. apply in_or_app ; right ; apply in_or_app ;
+         right ; apply in_or_app ; auto.
+         pose (PIH _ J5 _ _ _ _ _ J6 J7 J8).
+         assert (J9: derrec_height x0 < S (dersrec_height d)). lia.
+         assert (J10: derrec_height x0 = derrec_height x0). auto.
+         assert (J11: (fst k ++ B :: Γ1, Δ0 ++ Δ1) = (fst k ++ B :: Γ1, snd k ++ Y0)). rewrite H3 ; auto.
+         assert (J12: In # p (propvar_subform_list ((B :: Γ1) ++ Y0)) -> False).
+         intro. apply propvar. repeat rewrite propvar_subform_list_app.
+         repeat rewrite propvar_subform_list_app in H0. simpl in H0. simpl.
+         repeat rewrite <- app_assoc. repeat rewrite <- app_assoc in H0.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ;
+         right ; apply in_or_app ; auto. apply in_or_app ; right ; apply in_or_app ;
+         right ; apply in_or_app ; auto.
+         pose (PIH _ J9 _ _ _ _ _ J10 J11 J12).
+         apply derI with (ps:=[([] ++ Γ1, [UI p k] ++ A :: Y0);([] ++ B :: Γ1, [UI p k] ++ Y0)]). apply ImpL.
+         assert ((A --> B :: Γ1, UI p k :: Y0) = ([] ++ A --> B :: Γ1, [UI p k] ++ Y0)). auto. rewrite H0.
+         apply ImpLRule_I. apply dlCons. auto. apply dlCons. auto. apply dlNil.
+         exfalso. destruct k ; simpl in e0 ; subst. unfold critical_Seq in c ; unfold is_Prime in c ; simpl in c.
+         assert (In m ((Γ0 ++ m :: x3) ++ l2)). repeat rewrite <- app_assoc. apply in_or_app ; right ; apply in_or_app ; left ; apply in_eq.
+         apply c in H0. inversion e1 ; subst. destruct H0 ; destruct H0 ; inversion H0 ; inversion H1.
+         assert (J5: derrec_height x2 < S (dersrec_height d)). lia.
+         assert (J6: derrec_height x2 = derrec_height x2). auto.
+         assert (J7: ((fst k ++ x3) ++ Γ1, snd k ++ A :: Y0) = (fst k ++ x3 ++ Γ1, snd k ++ A :: Y0)).
+         rewrite <- app_assoc ; auto.
+         assert (J8: In # p (propvar_subform_list ((x3 ++ Γ1) ++ A :: Y0)) -> False).
+         intro. apply propvar. repeat rewrite propvar_subform_list_app.
+         repeat rewrite propvar_subform_list_app in H0. simpl in H0. simpl.
+         repeat rewrite <- app_assoc. repeat rewrite <- app_assoc in H0.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; auto. apply in_app_or in H0 ; destruct H0.
+         apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ; auto.
+         apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+         pose (PIH _ J5 _ _ _ _ _ J6 J7 J8).
+         assert (J9: derrec_height x0 < S (dersrec_height d)). lia.
+         assert (J10: derrec_height x0 = derrec_height x0). auto.
+         assert (J11: ((fst k ++ x3) ++ B :: Γ1, Δ0 ++ Δ1) = (fst k ++ x3 ++ B :: Γ1, snd k ++ Y0)).
+         rewrite H3 ; rewrite <- app_assoc ; auto.
+         assert (J12: In # p (propvar_subform_list ((x3 ++ B :: Γ1) ++ Y0)) -> False).
+         intro. apply propvar. repeat rewrite propvar_subform_list_app.
+         repeat rewrite propvar_subform_list_app in H0. simpl in H0. simpl.
+         repeat rewrite <- app_assoc. repeat rewrite <- app_assoc in H0.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; auto. apply in_or_app ; right ; apply in_or_app ; auto.
+         pose (PIH _ J9 _ _ _ _ _ J10 J11 J12).
+         apply derI with (ps:=[(x3 ++ Γ1, [UI p k] ++ A :: Y0);(x3 ++ B :: Γ1, [UI p k] ++ Y0)]). apply ImpL.
+         assert ((x3 ++ A --> B :: Γ1, UI p k :: Y0) = (x3 ++ A --> B :: Γ1, [UI p k] ++ Y0)). auto. rewrite H0.
+         apply ImpLRule_I. apply dlCons. auto. apply dlCons. auto. apply dlNil.
+      (*  If not critical, consider the conjunction that UI p k is. *)
+      + assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+         assert (J1: Gimap (GUI p) (Canopy (nodupseq k)) (map (UI p) (Canopy (nodupseq k)))). apply Gimap_map. intros.
+         apply UI_GUI ; auto.
+         pose (@GUI_inv_not_critic p k (UI p k) (map (UI p) (Canopy (nodupseq k))) J0 f J1). rewrite <- e.
+ +
+         assert (J2: forall s1, InT s1 (Canopy (nodupseq k)) -> GLS_prv (X0, UI p s1 :: Y0)).
+         intros. pose (fold_Canopy _ _ H0). destruct s ; subst.
+         exfalso. apply f. apply Canopy_critical in H0 ; auto. apply critical_nodupseq in H0 ; auto.
+         destruct s. destruct p0. unfold inv_prems in i.
+         apply InT_flatten_list_InT_elem in i. destruct i. destruct p0. simpl in PIH. simpl in SIH.
+         pose (derI _ g d).
+ +
+         assert (existsT2 (d1: GLS_prv (fst (nodupseq k) ++ X0, snd (nodupseq k) ++ Y0)), derrec_height d1 <= derrec_height d0).
+         destruct (nodupseq_id k). destruct p0. destruct s. destruct s. destruct p1. destruct p1.
+         pose (PermutationTS_prv_hpadm _ d0 (x2 ++ fst x1 ++ X0, x3 ++ snd x1 ++ Y0)). destruct s.
+         split ; simpl ; apply Permutation_PermutationT. destruct p1.
+         pose (@Permutation_app _ (fst k) X0 (x2 ++ fst x1) X0). rewrite <- app_assoc in p3 ; apply p3 ; auto.
+         apply Permutation_PermutationT ; auto. destruct p1.
+         pose (@Permutation_app _ (snd k) Y0 (x3 ++ snd x1) Y0). rewrite <- app_assoc in p3 ; apply p3 ; auto.
+         apply Permutation_PermutationT ; auto.
+         epose (incl_ctr_R_hpadm _ x3 _ x4). destruct s. intros A HA ; apply in_or_app ; left ; auto.
+         epose (incl_ctr_L_hpadm x2 _ _ x5). destruct s. intros A HA ; apply in_or_app ; left ; auto.
+         pose (PermutationTS_prv_hpadm _ x6 (fst (nodupseq k) ++ X0, snd (nodupseq k) ++ Y0)). destruct s.
+         split ; simpl ; apply Permutation_PermutationT. destruct p0. apply Permutation_app ; auto.
+         unfold nodupseq in p0. apply Permutation_PermutationT ; auto. destruct p0.
+         apply Permutation_app ; auto. unfold nodupseq in p2. apply Permutation_PermutationT ; auto.
+         exists x7. lia. destruct X.
+         assert (J2: derrec_height x1 = derrec_height x1). auto.
+         assert (J3: (fst (nodupseq k) ++ X0, snd (nodupseq k) ++ Y0) = (fst (nodupseq k) ++ X0, snd (nodupseq k) ++ Y0)). auto.
+         pose (Canopy_hp_inv_ctx (nodupseq k) _ _ x1 X0 Y0 J2 J3 _ H0). destruct s.
+         destruct (Compare_dec.lt_dec (derrec_height x2) (S (dersrec_height d))).
+         (* Use PIH. *)
+         pose (fold_Canopy _ _ H0). destruct s ; subst.
+         exfalso. apply f. apply Canopy_critical in H0 ; auto. apply critical_nodupseq in H0 ; auto.
+         destruct s. destruct p0. unfold inv_prems in i2.
+         apply InT_flatten_list_InT_elem in i2. destruct i2. destruct p0.
+         assert (J4: derrec_height x2 = derrec_height x2). auto.
+         assert (J5: (fst s1 ++ X0, snd s1 ++ Y0) = (fst s1 ++ X0, snd s1 ++ Y0)). auto.
+         pose (PIH _ l1 s1 _ x2 X0 Y0 J4 J5). apply g0 ; auto.
+         (* Use SIH. *)
+         assert (derrec_height x2 = S (dersrec_height d)). assert (derrec_height d0 = S (dersrec_height d)). simpl. auto. lia.
+         assert (J4: LexSeq s1 k). pose (Canopy_LexSeq _ _ H0).
+         destruct s ; subst ; auto. exfalso. apply f. apply Canopy_critical in H0 ; apply critical_nodupseq in H0 ; auto.
+         apply LexSeq_nodupseq in l1 ; auto. symmetry in H1.
+         assert (J5: (fst s1 ++ X0, snd s1 ++ Y0) = (fst s1 ++ X0, snd s1 ++ Y0)). auto.
+         pose (SIH _ J4 _ _ _ _ H1 J5 propvar). auto.
+ +
+         assert (J3: (forall A : MPropF, InT A (map (UI p) (Canopy (nodupseq k))) -> GLS_prv (fst (X0, Y0), A :: snd (X0, Y0)))).
+         intros. simpl. apply InT_map_iff in H0. destruct H0. destruct p0 ; subst. apply J2 in i ; auto.
+         pose (list_conj_R _ _ J3). simpl in g0. auto.
+ +
+    (* GLR *)
+    * destruct (critical_Seq_dec k).
+      (* If critical. *)
+      + inversion X ; subst. (* Not sure the two lines below are useful. *)
+         assert (J0: dersrec_height d = dersrec_height d) ; auto.
+         apply dersrec_derrec_height in J0. destruct J0. simpl in PIH. simpl in SIH.
+         destruct (dec_init_rules k).
+         (* If initial. *)
+        ** assert (is_init k) ; auto. assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+         pose (@GUI_inv_critic_init p k _ J0 c X2). rewrite <- e0.
+         assert ((X0, Top :: Y0) = (X0, [] ++ Top :: Y0)). auto. rewrite H. apply TopR.
+         (* If not initial. *)
+        ** apply univ_gen_ext_splitR in X1. destruct X1. destruct s. destruct p0. destruct p0.
+         apply app2_find_hole in H2. destruct H2.
+         assert ((is_init k) -> False) ; auto.
+         assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+         assert (J1: Gimap (GUI p) (GLR_prems (nodupseq k)) (map (UI p) (GLR_prems (nodupseq k)))). apply Gimap_map. intros.
+         apply UI_GUI ; auto.
+         assert (J2: (Gimap (GN p (GUI p) k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), [])))
+         (map (N p k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), [])))))). apply Gimap_map. intros.
+         apply (N_spec p k x3).
+         pose (@GUI_inv_critic_not_init p k _ _ _ J0 c NE H J1 J2). rewrite <- e1. clear e1.
+         repeat destruct s ; destruct p0 ; subst.
+         (* If Box A is in Y0. *)
+         -- pose (OrR (X0,Box A :: Δ1)). simpl in g0. apply g0. clear g0.
+            apply GLS_prv_wkn_R with (A:=list_disj (restr_list_prop p (snd k))) (s:=(X0,
+            Or (list_disj (map Neg (restr_list_prop p (fst k))))(Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq k))))) (Diam
+            (list_conj (map (N p k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), []%list)))))))
+            :: Box A :: Δ1)).
+            2: epose (wkn_RI (list_disj (restr_list_prop p (snd k))) _ [] _) ; simpl in w ; apply w.
+            pose (OrR (X0,Box A :: Δ1)). simpl in g0. apply g0. clear g0.
+            apply GLS_prv_wkn_R with (A:=list_disj (map Neg (restr_list_prop p (fst k)))) (s:=(X0,
+            Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq k))))) (Diam
+            (list_conj (map (N p k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), []%list))))))
+            :: Box A :: Δ1)).
+            2: epose (wkn_RI (list_disj (map Neg (restr_list_prop p (fst k)))) _ [] _) ; simpl in w ; apply w.
+            pose (OrR (X0,Box A :: Δ1)). simpl in g0. apply g0. clear g0.
+            apply GLS_prv_wkn_R with (A:=list_disj (map Box (map (UI p) (GLR_prems (nodupseq k))))) (s:=(X0,
+            (Diam (list_conj (map (N p k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), []%list))))))
+            :: Box A :: Δ1)).
+            2: epose (wkn_RI (list_disj (map Box (map (UI p) (GLR_prems (nodupseq k))))) _ [] _) ; simpl in w ; apply w.
+            apply Diam_rec_UI ; auto.
+            assert (J5: derrec_height x < S (dersrec_height d)). lia.
+            assert (J6: derrec_height x = derrec_height x). auto.
+            assert (J7: (XBoxed_list (x0 ++ x1) ++ [Box A], [A]) = (fst (XBoxed_list x0, @nil MPropF) ++ XBoxed_list x1 ++ [Box A], snd (XBoxed_list x0, []) ++ [A])).
+            simpl ; rewrite XBox_app_distrib. repeat rewrite <- app_assoc ; auto.
+            assert (J8: (In # p (propvar_subform_list ((XBoxed_list x1 ++ [Box A]) ++ [A])) -> False)).
+            intro. apply propvar. repeat rewrite propvar_subform_list_app.
+            repeat rewrite propvar_subform_list_app in H0. simpl in H0. repeat rewrite app_nil_r in H0. simpl.
+            repeat rewrite <- app_assoc in H0. apply in_app_or in H0 ; destruct H0.
+            apply in_or_app ; left. apply propvar_subform_list_XBoxed_list in H0.
+            apply propvar_subform_list_nobox_gen_ext with (l0:=x1); auto.
+            apply in_or_app ; right ; apply in_or_app ; left. apply in_app_or in H0 ; destruct H0 ; auto.
+            pose (PIH _ J5 _ _ _ _ _ J6 J7 J8).
+            apply derI with (ps:=[(X0 ++ Box (Neg (UI p (XBoxed_list (top_boxes (fst k)), []%list))) :: [], [] ++ Bot :: Box A :: Δ1)]).
+            apply ImpR. assert ((X0, Diam (UI p (XBoxed_list (top_boxes (fst k)), []%list)) :: Box A :: Δ1) =
+            (X0 ++ [], [] ++ Diam (UI p (XBoxed_list (top_boxes (fst k)), []%list)) :: Box A :: Δ1)). rewrite app_nil_r. auto. rewrite H0.
+            apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+            apply derI with (ps:=[(XBoxed_list (x1 ++ [Box (Neg (UI p (XBoxed_list (top_boxes (fst k)), []%list)))]) ++ [Box A], [A])]).
+            apply GLR. assert (([] ++ :: Box A :: Δ1) = [] ++ Box A :: Δ1). auto. rewrite H0. apply GLRRule_I ; auto.
+            intro. intros. apply in_app_or in H2 ; destruct H2. apply H1 ; apply in_or_app ; auto. exists (Neg (UI p (XBoxed_list (top_boxes (fst k)), []%list))).
+            inversion H2 ; subst ; auto. inversion H3. apply univ_gen_ext_combine ; auto. apply univ_gen_ext_cons. apply univ_gen_ext_nil.
+            apply dlCons. 2: apply dlNil. rewrite XBox_app_distrib. simpl. repeat rewrite <- app_assoc. simpl.
+            apply GLS_prv_wkn_L with (A:=Box (Neg (UI p (XBoxed_list (top_boxes (fst k)), []%list)))) (s:=(XBoxed_list x1 ++
+            [Neg (UI p (XBoxed_list (top_boxes (fst k)), []%list)); Box A], [A])).
+            2: epose (wkn_LI (Box (Neg (UI p (XBoxed_list (top_boxes (fst k)), []%list)))) (XBoxed_list x1 ++ [Neg (UI p (XBoxed_list (top_boxes (fst k)), []%list))]) [Box A] _) ;
+            simpl in w ; repeat rewrite <- app_assoc in w ; simpl in w ; apply w.
+            apply derI with (ps:=[(XBoxed_list x1 ++ [Box A], [] ++ (UI p (XBoxed_list (top_boxes (fst k)), []%list)) :: [A]);
+            (XBoxed_list x1 ++ Bot :: [Box A], [] ++ [A])]). apply ImpL. apply ImpLRule_I. apply dlCons. 2: apply dlCons.
+            3: apply dlNil. 2: apply derI with (ps:=[]) ; [apply BotL ; apply BotLRule_I | apply dlNil].
+            simpl. assert ((top_boxes (fst k)) = x0). symmetry. apply nobox_gen_ext_top_boxes_identity ; auto.
+            intro. intros. apply H1 ; apply in_or_app ; auto. rewrite H0. auto.
+        -- destruct x2 ; simpl in e2 ; subst.
+            (* If Box A is in Y0 (bis). *)
+            +++ rewrite app_nil_r in e1 ; subst.
+                pose (OrR (X0,Box A :: Δ1)). simpl in g0. apply g0. clear g0.
+                apply GLS_prv_wkn_R with (A:=list_disj (restr_list_prop p (snd k))) (s:=(X0,
+                Or (list_disj (map Neg (restr_list_prop p (fst k))))(Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq k))))) (Diam
+                (list_conj (map (N p k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), []%list)))))))
+                :: Box A :: Δ1)).
+                2: epose (wkn_RI (list_disj (restr_list_prop p (snd k))) _ [] _) ; simpl in w ; apply w.
+                pose (OrR (X0,Box A :: Δ1)). simpl in g0. apply g0. clear g0.
+                apply GLS_prv_wkn_R with (A:=list_disj (map Neg (restr_list_prop p (fst k)))) (s:=(X0,
+                Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq k))))) (Diam
+                (list_conj (map (N p k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), []%list))))))
+                :: Box A :: Δ1)).
+                2: epose (wkn_RI (list_disj (map Neg (restr_list_prop p (fst k)))) _ [] _) ; simpl in w ; apply w.
+                pose (OrR (X0,Box A :: Δ1)). simpl in g0. apply g0. clear g0.
+                apply GLS_prv_wkn_R with (A:=list_disj (map Box (map (UI p) (GLR_prems (nodupseq k))))) (s:=(X0,
+                (Diam (list_conj (map (N p k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), []%list))))))
+                :: Box A :: Δ1)).
+                2: epose (wkn_RI (list_disj (map Box (map (UI p) (GLR_prems (nodupseq k))))) _ [] _) ; simpl in w ; apply w.
+                apply Diam_rec_UI ; auto.
+                assert (J5: derrec_height x < S (dersrec_height d)). lia.
+                assert (J6: derrec_height x = derrec_height x). auto.
+                assert (J7: (XBoxed_list (x0 ++ x1) ++ [Box A], [A]) = (fst (XBoxed_list x0, @nil MPropF) ++ XBoxed_list x1 ++ [Box A], snd (XBoxed_list x0, []) ++ [A])).
+                simpl ; rewrite XBox_app_distrib. repeat rewrite <- app_assoc ; auto.
+                assert (J8: (In # p (propvar_subform_list ((XBoxed_list x1 ++ [Box A]) ++ [A])) -> False)).
+                intro. apply propvar. repeat rewrite propvar_subform_list_app.
+                repeat rewrite propvar_subform_list_app in H0. simpl in H0. repeat rewrite app_nil_r in H0. simpl.
+                repeat rewrite <- app_assoc in H0. apply in_app_or in H0 ; destruct H0.
+                apply in_or_app ; left. apply propvar_subform_list_XBoxed_list in H0.
+                apply propvar_subform_list_nobox_gen_ext with (l0:=x1); auto.
+                apply in_or_app ; right ; apply in_or_app ; left. apply in_app_or in H0 ; destruct H0 ; auto.
+                pose (PIH _ J5 _ _ _ _ _ J6 J7 J8).
+                apply derI with (ps:=[(X0 ++ Box (Neg (UI p (XBoxed_list (top_boxes (fst k)), []%list))) :: [], [] ++ Bot :: Box A :: Δ1)]).
+                apply ImpR. assert ((X0, Diam (UI p (XBoxed_list (top_boxes (fst k)), []%list)) :: Box A :: Δ1) =
+                (X0 ++ [], [] ++ Diam (UI p (XBoxed_list (top_boxes (fst k)), []%list)) :: Box A :: Δ1)). rewrite app_nil_r. auto. rewrite H0.
+                apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+                apply derI with (ps:=[(XBoxed_list (x1 ++ [Box (Neg (UI p (XBoxed_list (top_boxes (fst k)), []%list)))]) ++ [Box A], [A])]).
+                apply GLR. assert (([] ++ :: Box A :: Δ1) = [] ++ Box A :: Δ1). auto. rewrite H0. apply GLRRule_I ; auto.
+                intro. intros. apply in_app_or in H2 ; destruct H2. apply H1 ; apply in_or_app ; auto. exists (Neg (UI p (XBoxed_list (top_boxes (fst k)), []%list))).
+                inversion H2 ; subst ; auto. inversion H3. apply univ_gen_ext_combine ; auto. apply univ_gen_ext_cons. apply univ_gen_ext_nil.
+                apply dlCons. 2: apply dlNil. rewrite XBox_app_distrib. simpl. repeat rewrite <- app_assoc. simpl.
+                apply GLS_prv_wkn_L with (A:=Box (Neg (UI p (XBoxed_list (top_boxes (fst k)), []%list)))) (s:=(XBoxed_list x1 ++
+                [Neg (UI p (XBoxed_list (top_boxes (fst k)), []%list)); Box A], [A])).
+                2: epose (wkn_LI (Box (Neg (UI p (XBoxed_list (top_boxes (fst k)), []%list)))) (XBoxed_list x1 ++ [Neg (UI p (XBoxed_list (top_boxes (fst k)), []%list))]) [Box A] _) ;
+                simpl in w ; repeat rewrite <- app_assoc in w ; simpl in w ; apply w.
+                apply derI with (ps:=[(XBoxed_list x1 ++ [Box A], [] ++ (UI p (XBoxed_list (top_boxes (fst k)), []%list)) :: [A]);
+                (XBoxed_list x1 ++ Bot :: [Box A], [] ++ [A])]). apply ImpL. apply ImpLRule_I. apply dlCons. 2: apply dlCons.
+                3: apply dlNil. 2: apply derI with (ps:=[]) ; [apply BotL ; apply BotLRule_I | apply dlNil].
+                simpl. assert ((top_boxes (fst k)) = x0). symmetry. apply nobox_gen_ext_top_boxes_identity ; auto.
+                intro. intros. apply H1 ; apply in_or_app ; auto. rewrite H0. auto.
+           (* If Box A is in (snd k). *)
+           +++ inversion e2 ; subst.
+                assert (J10:derrec_height x = derrec_height x) ; auto.
+                assert (J11: list_exch_L (XBoxed_list (x0 ++ x1) ++ [Box A], [A]) ((XBoxed_list x0 ++ [Box A]) ++ XBoxed_list x1, [A])).
+                assert (XBoxed_list (x0 ++ x1) ++ [Box A] = XBoxed_list x0 ++ [] ++ XBoxed_list x1 ++ [Box A] ++ []). rewrite XBox_app_distrib.
+                repeat rewrite <- app_assoc. auto. rewrite H0.
+                assert ((XBoxed_list x0 ++ [Box A]) ++ XBoxed_list x1 = XBoxed_list x0 ++ [Box A] ++ XBoxed_list x1 ++ [] ++ []).
+                repeat rewrite <- app_assoc. auto. repeat rewrite app_nil_r. auto. rewrite H2. apply list_exch_LI.
+                pose (GLS_hpadm_list_exch_L _ J10 J11). destruct s.
+                pose (incl_hpadm_prv _ ((XBoxed_list (top_boxes (fst (nodupseq k))) ++ [Box A]) ++ XBoxed_list x1, [A]) x3). simpl in s. destruct s.
+                intros B HB. apply in_app_or in HB ; destruct HB. apply in_app_or in H0 ; destruct H0.
+                apply in_or_app ; left. apply in_or_app ; left. destruct (In_XBoxed_list_gen _ _ H0).
+                apply list_preserv_XBoxed_list. apply is_box_in_top_boxes. apply nodup_In.
+                apply (univ_gen_ext_In _ u) ; auto. apply H1. apply in_or_app ; auto. destruct H2. destruct H2 ; subst.
+                apply XBoxed_list_In. apply is_box_in_top_boxes. apply nodup_In. apply (univ_gen_ext_In _ u) ; auto.
+                apply H1. apply in_or_app ; auto. inversion H0 ; subst. apply in_or_app ; left ; apply in_or_app ; auto. inversion H2.
+                apply in_or_app ; auto. intros B HB ; auto.
+                assert (J5: derrec_height x4 < S (dersrec_height d)). lia.
+                assert (J6: derrec_height x4 = derrec_height x4). auto.
+                assert (J7: ((XBoxed_list (top_boxes (nodup eq_dec_form (fst k))) ++ [Box A]) ++ XBoxed_list x1, [A]) = (fst (XBoxed_list (top_boxes (nodup eq_dec_form (fst k))) ++[Box A], [A]) ++ XBoxed_list x1, snd (XBoxed_list x0 ++[Box A], [A]) ++ [])).
+                simpl. repeat rewrite <- app_assoc ; auto.
+                assert (J8: (In # p (propvar_subform_list ((XBoxed_list x1 ++ [])))) -> False).
+                intro. apply propvar. repeat rewrite propvar_subform_list_app.
+                repeat rewrite propvar_subform_list_app in H0. simpl in H0. repeat rewrite app_nil_r in H0. simpl.
+                repeat rewrite <- app_assoc in H0. apply in_or_app ; left. apply propvar_subform_list_XBoxed_list in H0.
+                apply propvar_subform_list_nobox_gen_ext with (l0:=x1); auto.
+                pose (PIH _ J5 _ _ _ _ _ J6 J7 J8).
+                apply GLS_prv_wkn_L with (A:=Box (UI p (XBoxed_list (top_boxes (nodup eq_dec_form (fst k))) ++ [Box A], [A])))
+                (sw:=(XBoxed_list x1 ++ [Box (UI p (XBoxed_list (top_boxes (nodup eq_dec_form (fst k))) ++ [Box A], [A]))] , [UI p (XBoxed_list (top_boxes (nodup eq_dec_form (fst k))) ++ [Box A], [A])])) in g0.
+                2: epose (wkn_LI (Box (UI p (XBoxed_list (top_boxes (nodup eq_dec_form (fst k))) ++ [Box A], [A]))) _ [] _) ; rewrite app_nil_r in w ; simpl in w ; apply w.
+                assert (J20: GLS_rules [(XBoxed_list x1 ++ [Box (UI p (XBoxed_list (top_boxes (nodup eq_dec_form (fst k))) ++ [Box A], [A]))], [UI p (XBoxed_list (top_boxes (nodup eq_dec_form (fst k))) ++ [Box A], [A])])]
+                (X0, Box (UI p (XBoxed_list (top_boxes (nodup eq_dec_form (fst k))) ++ [Box A], [A])) :: Y0)). apply GLR.
+                assert (Box (UI p (XBoxed_list (top_boxes (nodup eq_dec_form (fst k))) ++ [Box A], [A])) :: Y0 = [] ++ Box (UI p (XBoxed_list (top_boxes (nodup eq_dec_form (fst k))) ++ [Box A], [A])) :: Y0).
+                auto. rewrite H0. apply GLRRule_I ;auto. intro. intros. apply H1. apply in_or_app ;auto.
+                pose (dlNil GLS_rules (fun _ : Seq => False)).
+                pose (dlCons g0 d0). pose (derI _ J20 d1).
+                pose (OrR (X0,Y0)). simpl in g1. apply g1. clear g1.
+                apply GLS_prv_wkn_R with (A:=list_disj (restr_list_prop p (snd k))) (s:=(X0,
+                Or (list_disj (map Neg (restr_list_prop p (fst k))))(Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq k))))) (Diam
+                (list_conj (map (N p k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), []%list)))))))
+                :: Y0)).
+                2: epose (wkn_RI (list_disj (restr_list_prop p (snd k))) _ [] _) ; simpl in w ; apply w.
+                pose (OrR (X0,Y0)). simpl in g1. apply g1. clear g1.
+                apply GLS_prv_wkn_R with (A:=list_disj (map Neg (restr_list_prop p (fst k)))) (s:=(X0,
+                Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq k))))) (Diam
+                (list_conj (map (N p k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), []%list))))))
+                :: Y0)).
+                2: epose (wkn_RI (list_disj (map Neg (restr_list_prop p (fst k)))) _ [] _) ; simpl in w ; apply w.
+                pose (OrR (X0,Y0)). simpl in g1. apply g1. clear g1.
+                pose (list_disj_wkn_R (map Box (map (UI p) (GLR_prems (nodupseq k)))) (X0, Diam
+                 (list_conj (map (N p k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), []%list))))) :: Y0)).
+                (* The next UI does not have the correct LHS, which we expect to use x0, to link up with d1. *)
+                apply g1 with (A:=Box (UI p (XBoxed_list (top_boxes (fst (nodupseq k))) ++ [Box A], [A]))) ; clear g1 ; simpl ; auto.
+                apply InT_map_iff.
+                exists (UI p (XBoxed_list (top_boxes (fst (nodupseq k))) ++ [Box A], [A])) ; split ; auto. apply InT_map_iff.
+                exists (XBoxed_list (top_boxes (fst (nodupseq k))) ++ [Box A], [A]) ; split ; auto. unfold GLR_prems.
+                apply InT_trans_flatten_list with (bs:=[(XBoxed_list (top_boxes (fst (nodupseq k))) ++ [Box A], [A])]) ; auto. apply InT_eq.
+                destruct (finite_GLR_premises_of_S (nodupseq k)) ; subst. simpl. apply p0. assert (k = (fst k,Δ0 ++ Box A :: x2)).
+                rewrite <- e1. destruct k ; auto. rewrite H0. unfold nodupseq ; simpl.
+                assert (InT (Box A) (nodup eq_dec_form (Δ0 ++ Box A :: x2))). apply In_InT ; apply nodup_In ; apply in_or_app ; right ; simpl ; auto.
+                apply InT_split in H2 ; destruct H2. destruct s. rewrite e0.
+                apply GLRRule_I ; auto. intro. intros. apply in_top_boxes in H2 ; destruct H2. destruct s ; destruct s. destruct p1.
+                eexists ; subst ; auto. apply nobox_top_boxes.
+                apply GLS_prv_wkn_R with (A:=Diam (list_conj (map (N p k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), []%list))))))
+                (s:=(X0, Box (UI p (XBoxed_list (top_boxes (nodup eq_dec_form (fst k))) ++ [Box A], [A])) :: Y0)) ; auto.
+                assert ((X0, Box (UI p (XBoxed_list (top_boxes (nodup eq_dec_form (fst k))) ++ [Box A], [A])) :: Y0) = (X0, [Box (UI p (XBoxed_list (top_boxes (nodup eq_dec_form (fst k))) ++ [Box A], [A]))] ++ Y0)).
+                repeat rewrite <- app_assoc ; auto. rewrite H0. apply wkn_RI.
+         (* If Box A is in Y0 (ter). *)
+         -- pose (OrR (X0,x2 ++ Box A :: Δ1)). simpl in g0. apply g0. clear g0.
+            apply GLS_prv_wkn_R with (A:=list_disj (restr_list_prop p (snd k))) (s:=(X0,
+            Or (list_disj (map Neg (restr_list_prop p (fst k))))(Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq k))))) (Diam
+            (list_conj (map (N p k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), []%list)))))))
+            :: x2 ++ Box A :: Δ1)).
+            2: epose (wkn_RI (list_disj (restr_list_prop p (snd k))) _ [] _) ; simpl in w ; apply w.
+            pose (OrR (X0,x2 ++ Box A :: Δ1)). simpl in g0. apply g0. clear g0.
+            apply GLS_prv_wkn_R with (A:=list_disj (map Neg (restr_list_prop p (fst k)))) (s:=(X0,
+            Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq k))))) (Diam
+            (list_conj (map (N p k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), []%list))))))
+            :: x2 ++ Box A :: Δ1)).
+            2: epose (wkn_RI (list_disj (map Neg (restr_list_prop p (fst k)))) _ [] _) ; simpl in w ; apply w.
+            pose (OrR (X0,x2 ++ Box A :: Δ1)). simpl in g0. apply g0. clear g0.
+            apply GLS_prv_wkn_R with (A:=list_disj (map Box (map (UI p) (GLR_prems (nodupseq k))))) (s:=(X0,
+            (Diam (list_conj (map (N p k) (Canopy (nodupseq (XBoxed_list (top_boxes (fst k)), []%list))))))
+            :: x2 ++ Box A :: Δ1)).
+            2: epose (wkn_RI (list_disj (map Box (map (UI p) (GLR_prems (nodupseq k))))) _ [] _) ; simpl in w ; apply w.
+            apply Diam_rec_UI ; auto.
+            assert (J5: derrec_height x < S (dersrec_height d)). lia.
+            assert (J6: derrec_height x = derrec_height x). auto.
+            assert (J7: (XBoxed_list (x0 ++ x1) ++ [Box A], [A]) = (fst (XBoxed_list x0, @nil MPropF) ++ XBoxed_list x1 ++ [Box A], snd (XBoxed_list x0, []) ++ [A])).
+            simpl ; rewrite XBox_app_distrib. repeat rewrite <- app_assoc ; auto.
+            assert (J8: (In # p (propvar_subform_list ((XBoxed_list x1 ++ [Box A]) ++ [A])) -> False)).
+            intro. apply propvar. repeat rewrite propvar_subform_list_app.
+            repeat rewrite propvar_subform_list_app in H0. simpl in H0. repeat rewrite app_nil_r in H0. simpl.
+            repeat rewrite <- app_assoc in H0. apply in_app_or in H0 ; destruct H0.
+            apply in_or_app ; left. apply propvar_subform_list_XBoxed_list in H0.
+            apply propvar_subform_list_nobox_gen_ext with (l0:=x1); auto.
+            apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; left. apply in_app_or in H0 ; destruct H0 ; auto.
+            pose (PIH _ J5 _ _ _ _ _ J6 J7 J8).
+            apply derI with (ps:=[(X0 ++ Box (Neg (UI p (XBoxed_list (top_boxes (fst k)), []%list))) :: [], [] ++ Bot :: x2 ++ Box A :: Δ1)]).
+            apply ImpR. assert ((X0, Diam (UI p (XBoxed_list (top_boxes (fst k)), []%list)) :: x2 ++ Box A :: Δ1) =
+            (X0 ++ [], [] ++ Diam (UI p (XBoxed_list (top_boxes (fst k)), []%list)) :: x2 ++ Box A :: Δ1)). rewrite app_nil_r. auto. rewrite H0.
+            apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+            apply derI with (ps:=[(XBoxed_list (x1 ++ [Box (Neg (UI p (XBoxed_list (top_boxes (fst k)), []%list)))]) ++ [Box A], [A])]).
+            apply GLR. assert (([] ++ :: x2 ++ Box A :: Δ1) = ( :: x2) ++ Box A :: Δ1). auto. rewrite H0. apply GLRRule_I ; auto.
+            intro. intros. apply in_app_or in H2 ; destruct H2. apply H1 ; apply in_or_app ; auto. exists (Neg (UI p (XBoxed_list (top_boxes (fst k)), []%list))).
+            inversion H2 ; subst ; auto. inversion H3. apply univ_gen_ext_combine ; auto. apply univ_gen_ext_cons. apply univ_gen_ext_nil.
+            apply dlCons. 2: apply dlNil. rewrite XBox_app_distrib. simpl. repeat rewrite <- app_assoc. simpl.
+            apply GLS_prv_wkn_L with (A:=Box (Neg (UI p (XBoxed_list (top_boxes (fst k)), []%list)))) (s:=(XBoxed_list x1 ++
+            [Neg (UI p (XBoxed_list (top_boxes (fst k)), []%list)); Box A], [A])).
+            2: epose (wkn_LI (Box (Neg (UI p (XBoxed_list (top_boxes (fst k)), []%list)))) (XBoxed_list x1 ++ [Neg (UI p (XBoxed_list (top_boxes (fst k)), []%list))]) [Box A] _) ;
+            simpl in w ; repeat rewrite <- app_assoc in w ; simpl in w ; apply w.
+            apply derI with (ps:=[(XBoxed_list x1 ++ [Box A], [] ++ (UI p (XBoxed_list (top_boxes (fst k)), []%list)) :: [A]);
+            (XBoxed_list x1 ++ Bot :: [Box A], [] ++ [A])]). apply ImpL. apply ImpLRule_I. apply dlCons. 2: apply dlCons.
+            3: apply dlNil. 2: apply derI with (ps:=[]) ; [apply BotL ; apply BotLRule_I | apply dlNil].
+            simpl. assert ((top_boxes (fst k)) = x0). symmetry. apply nobox_gen_ext_top_boxes_identity ; auto.
+            intro. intros. apply H1 ; apply in_or_app ; auto. rewrite H0. auto.
+      (*  If not critical, consider the conjunction that UI p k is. *)
+      + assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+         assert (J1: Gimap (GUI p) (Canopy (nodupseq k)) (map (UI p) (Canopy (nodupseq k)))). apply Gimap_map. intros.
+         apply UI_GUI ; auto.
+         pose (@GUI_inv_not_critic p k (UI p k) (map (UI p) (Canopy (nodupseq k))) J0 f J1). rewrite <- e.
+ +
+         assert (J2: forall s1, InT s1 (Canopy (nodupseq k)) -> GLS_prv (X0, UI p s1 :: Y0)).
+         intros. pose (fold_Canopy _ _ H). destruct s ; subst.
+         exfalso. apply f. apply Canopy_critical in H ; auto. apply critical_nodupseq in H ; auto.
+         destruct s. destruct p0. unfold inv_prems in i.
+         apply InT_flatten_list_InT_elem in i. destruct i. destruct p0. simpl in PIH. simpl in SIH.
+         pose (derI _ g d).
+ +
+         assert (existsT2 (d1: GLS_prv (fst (nodupseq k) ++ X0, snd (nodupseq k) ++ Y0)), derrec_height d1 <= derrec_height d0).
+         destruct (nodupseq_id k). destruct p0. destruct s. destruct s. destruct p1. destruct p1.
+         pose (PermutationTS_prv_hpadm _ d0 (x2 ++ fst x1 ++ X0, x3 ++ snd x1 ++ Y0)). destruct s.
+         split ; simpl ; apply Permutation_PermutationT. destruct p1.
+         pose (@Permutation_app _ (fst k) X0 (x2 ++ fst x1) X0). rewrite <- app_assoc in p3 ; apply p3 ; auto.
+         apply Permutation_PermutationT ; auto. destruct p1.
+         pose (@Permutation_app _ (snd k) Y0 (x3 ++ snd x1) Y0). rewrite <- app_assoc in p3 ; apply p3 ; auto.
+         apply Permutation_PermutationT ; auto.
+         epose (incl_ctr_R_hpadm _ x3 _ x4). destruct s. intros A HA ; apply in_or_app ; left ; auto.
+         epose (incl_ctr_L_hpadm x2 _ _ x5). destruct s. intros A HA ; apply in_or_app ; left ; auto.
+         pose (PermutationTS_prv_hpadm _ x6 (fst (nodupseq k) ++ X0, snd (nodupseq k) ++ Y0)). destruct s.
+         split ; simpl ; apply Permutation_PermutationT. destruct p0. apply Permutation_app ; auto.
+         unfold nodupseq in p0. apply Permutation_PermutationT ; auto. destruct p0.
+         apply Permutation_app ; auto. unfold nodupseq in p2. apply Permutation_PermutationT ; auto.
+         exists x7. lia. destruct X1.
+         assert (J2: derrec_height x1 = derrec_height x1). auto.
+         assert (J3: (fst (nodupseq k) ++ X0, snd (nodupseq k) ++ Y0) = (fst (nodupseq k) ++ X0, snd (nodupseq k) ++ Y0)). auto.
+         pose (Canopy_hp_inv_ctx (nodupseq k) _ _ x1 X0 Y0 J2 J3 _ H). destruct s.
+         destruct (Compare_dec.lt_dec (derrec_height x2) (S (dersrec_height d))).
+         (* Use PIH. *)
+         pose (fold_Canopy _ _ H). destruct s ; subst.
+         exfalso. apply f. apply Canopy_critical in H ; auto. apply critical_nodupseq in H ; auto.
+         destruct s. destruct p0. unfold inv_prems in i2.
+         apply InT_flatten_list_InT_elem in i2. destruct i2. destruct p0.
+         assert (J4: derrec_height x2 = derrec_height x2). auto.
+         assert (J5: (fst s1 ++ X0, snd s1 ++ Y0) = (fst s1 ++ X0, snd s1 ++ Y0)). auto.
+         pose (PIH _ l1 s1 _ x2 X0 Y0 J4 J5). apply g0 ; auto.
+         (* Use SIH. *)
+         assert (derrec_height x2 = S (dersrec_height d)). assert (derrec_height d0 = S (dersrec_height d)). simpl. auto. lia.
+         assert (J4: LexSeq s1 k). pose (Canopy_LexSeq _ _ H).
+         destruct s ; subst ; auto. exfalso. apply f. apply Canopy_critical in H ; apply critical_nodupseq in H ; auto.
+         apply LexSeq_nodupseq in l1 ; auto. symmetry in H0.
+         assert (J5: (fst s1 ++ X0, snd s1 ++ Y0) = (fst s1 ++ X0, snd s1 ++ Y0)). auto.
+         pose (SIH _ J4 _ _ _ _ H0 J5 propvar). auto.
+ +
+         assert (J3: (forall A : MPropF, InT A (map (UI p) (Canopy (nodupseq k))) -> GLS_prv (fst (X0, Y0), A :: snd (X0, Y0)))).
+         intros. simpl. apply InT_map_iff in H. destruct H. destruct p0 ; subst. apply J2 in i ; auto.
+         pose (list_conj_R _ _ J3). simpl in g0. auto. }
+  Qed.
+ +
+  End UIPThree.
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_UITwo.html b/GL.Interpolation.UIGL_UITwo.html new file mode 100644 index 0000000..f47ec38 --- /dev/null +++ b/GL.Interpolation.UIGL_UITwo.html @@ -0,0 +1,256 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_UITwo

+ +
+(* Uniform interpolation *)
+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat.
+Require Import Lia.
+ +
+Require Import general_export.
+ +
+Require Import GLS_export.
+ +
+Require Import UIGL_Def_measure.
+Require Import UIGL_Canopy.
+Require Import UIGL_irred_short.
+Require Import UIGL_braga.
+Require Import UIGL_LexSeq.
+Require Import UIGL_nodupseq.
+Require Import UIGL_And_Or_rules.
+Require Import UIGL_UI_prelims.
+Require Import UIGL_UI_inter.
+ +
+  Section UIPTwo.
+ +
+  Theorem UI_Two : forall (s : Seq), forall p, GLS_prv ((UI p s) :: fst s, snd s).
+  Proof.
+  pose (LexSeq_ind (fun s => forall p, GLS_prv (UI p s :: fst s, snd s))).
+  apply g. clear g. intros.
+  destruct (empty_seq_dec s0).
+  (* s is the empty sequent. *)
+  { subst ; simpl in *. assert (GUI p ([],[]) Bot). apply GUI_empty_seq ; auto. apply UI_GUI in H.
+    rewrite H in *. apply derI with []. apply BotL ; apply (BotLRule_I [] []). apply dlNil. }
+  (* s is not the empty sequent. *)
+  { destruct (critical_Seq_dec s0).
+  (* s0 is a critical sequent *)
+  - destruct (dec_init_rules s0).
+    (* s0 is an initial sequent *)
+    + assert (GLS_prv (fst s0, snd s0)). destruct s0 ; destruct s. destruct s.
+      1,3: apply derI with (ps:=[]) ; try apply dlNil.
+      apply IdP ; auto. apply BotL ; auto. inversion i ; subst. apply Id_all_form.
+      destruct s0. simpl. simpl in X0.
+      assert (J0: derrec_height X0 = derrec_height X0). auto.
+      assert (J1: wkn_L (UI p (l, l0)) (l, l0) (UI p (l, l0) :: l, l0)).
+      assert ((l, l0) = ([] ++ l, l0)). auto. rewrite H.
+      assert ((UI p ([] ++ l, l0) :: l, l0) = ([] ++ UI p ([] ++ l, l0) :: l, l0)). auto. rewrite H0. apply wkn_LI.
+      pose (GLS_wkn_L X0 J0 J1). destruct s0. auto.
+    (* s0 is not an initial sequent *)
+   + assert (P1: GLS_prv (list_disj (map Neg (restr_list_prop p (fst s0))) :: fst s0, snd s0)).
+      apply list_disj_L. intros. apply InT_map_iff in H. destruct H. destruct p0. subst. unfold Neg.
+      apply derI with (ps:=[([] ++ fst s0, [] ++ x :: snd s0);([] ++ :: fst s0, [] ++ snd s0)]).
+      assert ((x --> :: fst s0, snd s0) = ([] ++ x --> :: fst s0, [] ++ snd s0)). auto. rewrite H. apply ImpL. apply ImpLRule_I.
+      apply dlCons. 2: apply dlCons. 3: apply dlNil. unfold restr_list_prop in i.
+      apply InT_In in i. apply In_remove_In_list in i. apply In_list_prop_LF in i. destruct i. apply In_InT in i.
+      apply InT_split in i. destruct i. destruct s1. destruct s. rewrite e. assert ([] ++ x0 ++ x :: x1 = x0 ++ x :: x1). auto.
+      rewrite H. apply Id_all_form. apply derI with (ps:=[]). apply BotL. apply BotLRule_I. apply dlNil.
+ +
+      assert (P2: GLS_prv (list_disj (restr_list_prop p (snd s0)) :: fst s0, snd s0)).
+      apply list_disj_L. intros. unfold restr_list_prop in H. apply InT_In in H. apply In_remove_In_list in H.
+      apply In_list_prop_LF in H. destruct H. apply In_InT in i. apply InT_split in i. destruct i. destruct s1.
+      rewrite e. assert (A :: fst s0 = [] ++ A :: fst s0). auto. rewrite H. apply Id_all_form.
+ +
+      assert (P3: GLS_prv (list_disj (map Box (map (UI p) (GLR_prems (nodupseq s0)))) :: fst s0, snd s0)).
+      apply list_disj_L. intros. apply InT_map_iff in H. destruct H. destruct p0. subst. apply InT_map_iff in i.
+      destruct i. destruct p0 ; subst. unfold GLR_prems in i. destruct (finite_GLR_premises_of_S (nodupseq s0)).
+      simpl in i. apply InT_flatten_list_InT_elem in i. destruct i. destruct p1. apply p0 in i0.
+      inversion i0 ; subst. inversion i ; subst. simpl. remember (UI p (XBoxed_list ++ [Box A], [A])) as Interp.
+      apply derI with (ps:=[(XBoxed_list (Box Interp :: top_boxes (fst s0)) ++ [Box A], [A])]). apply GLR.
+      assert (InT (Box A) (snd s0)).
+      apply In_InT ; apply (nodup_In eq_dec_form) ; rewrite <- H2 ; apply in_or_app ; right ; simpl ; auto.
+      apply InT_split in H. destruct H. destruct s. rewrite e. apply GLRRule_I.
+      intro. intros. inversion H ; simpl. exists Interp ; auto. apply in_top_boxes in H0. destruct H0.
+      destruct s. destruct s. destruct p1 ; subst. eexists ; auto. apply univ_gen_ext_cons.
+      apply nobox_top_boxes. apply dlCons. 2: apply dlNil. simpl.
+      pose (incl_prv (Interp :: Box Interp :: XBoxed_list ++ [Box A], [A])). apply g ; clear g ; simpl ; auto. 1-2: intros B HB ; auto.
+      inversion HB ; simpl ; subst ; auto. inversion HB ; simpl ; subst ; auto. inversion H0 ; simpl ; subst ; auto.
+      apply in_app_or in H3 ; destruct H3. right. right. apply in_or_app ; left. apply In_XBoxed_list_gen in H3.
+      destruct H3. apply list_preserv_XBoxed_list. destruct (is_box_is_in_boxed_list _ H3 H1) ; subst.
+      apply is_box_in_top_boxes ; auto. 2: eexists ; auto. apply (nodup_In eq_dec_form).
+      apply (univ_gen_ext_In _ X0 H3). destruct H3. destruct H3 ; subst. apply XBoxed_list_In.
+      apply is_box_in_top_boxes ; auto. 2: eexists ; auto. apply (nodup_In eq_dec_form).
+      apply (univ_gen_ext_In _ X0 H3). right. right. apply in_or_app ; auto.
+      assert (J2: length (usable_boxes (XBoxed_list ++ [Box A], [A])) < length (usable_boxes s0)).
+      assert (J300: length (usable_boxes (XBoxed_list ++ [Box A], [A])) < length (usable_boxes (nodupseq s0))).
+      apply (GLR_applic_less_usable_boxes i0) ; auto. intro. assert (is_init s0).
+      apply is_init_nodupseq ; unfold is_init ; auto. apply f ; auto.
+      pose (ub_nodupseq s0). lia.
+      assert (J3: LexSeq (XBoxed_list ++ [Box A], [A]) s0).
+      apply DLW_wf_lex.lex_cons ; auto.
+      pose (X (XBoxed_list ++ [Box A], [A]) J3 p). simpl in g. rewrite <- HeqInterp in g.
+      assert (J4: derrec_height g = derrec_height g). auto.
+      assert (J5: wkn_L (Box Interp) (Interp :: XBoxed_list ++ [Box A], [A]) (Interp :: Box Interp :: XBoxed_list ++ [Box A], [A])).
+      assert (Interp :: XBoxed_list ++ [Box A] = [Interp] ++ XBoxed_list ++ [Box A]) ; auto. rewrite H.
+      assert (Interp :: Box Interp :: XBoxed_list ++ [Box A] = [Interp] ++ Box Interp :: XBoxed_list ++ [Box A]) ; auto. rewrite H0.
+      apply wkn_LI. pose (GLS_wkn_L g J4 J5). destruct s. auto. inversion H0.
+ +
+      assert (P4: GLS_prv (Diam (list_conj (map (N p s0) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s0)), []))))) :: fst s0, snd s0)).
+      apply DiamL_lim with (:=top_boxes (fst s0)). apply is_Boxed_list_top_boxes. apply nobox_top_boxes.
+      apply incl_prv with (s0:=(list_conj (map (N p s0) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s0)), []%list))))
+      :: fst ((nodupseq (XBoxed_list (top_boxes (fst s0)), []%list))), []%list)) ; simpl ; auto.
+      intros A HIn ; simpl. destruct HIn ; auto. right. apply nodup_In in H ; auto. intros A HA ; inversion HA.
+      pose (Canopy_nodupseq_equiprv_genL (nodupseq (XBoxed_list (top_boxes (fst s0)), []%list))
+      (list_conj (map (N p s0) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s0)), []%list)))))).
+      apply p0. clear p0. intros.
+      apply list_conj_wkn_L with (A:=N p s0 leaf).
+      apply InT_map_iff. exists leaf ; split ; auto. rewrite <- fixpoint_nodupseq in H ; auto.
+      destruct (dec_init_rules leaf).
+      (* If leaf is initial. *)
+      assert (GLS_prv leaf). destruct leaf. repeat destruct s. 1,3: apply derI with (ps:=[]) ; try apply dlNil.
+      apply IdP ; auto. apply BotL ; auto. inversion i. subst. apply Id_all_form.
+      rewrite <- fixpoint_nodupseq in H ; auto.
+      assert (J0: derrec_height X0 = derrec_height X0). auto.
+      assert (J1:wkn_L (N p s0 leaf) leaf (N p s0 leaf :: fst leaf, snd leaf)).
+      epose (wkn_LI _ [] (fst leaf) (snd leaf)). destruct leaf ; simpl ; simpl in w. apply w.
+      pose (GLS_wkn_L X0 J0 J1). destruct s1. auto.
+      (* If leaf is not initial. *)
+      destruct (Compare_dec.lt_dec (length (usable_boxes leaf)) (length (usable_boxes s0))).
+      (* If leaf has less usable boxes than (XBoxed_list (top_boxes (fst s0)), ). *)
+      unfold N. destruct (N_pwc p s0 leaf).
+      simpl. assert (J0: is_init leaf -> False). auto.
+      assert ((forall (x : Seq) (l m : MPropF), (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x l -> (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x m -> l = m)).
+      intros. subst. auto.
+      epose (@GN_inv_noinit_lessub p _ _ _ _ g J0 l (UI_spec p leaf)). rewrite <- e ; auto. clear e.
+      clear H0. apply X. apply DLW_wf_lex.lex_cons ; auto.
+      (* If leaf does not have less usable boxes than (XBoxed_list (top_boxes (fst s0)), ). *)
+      unfold N. destruct (N_pwc p s0 leaf).
+      simpl. assert (J0: is_init leaf -> False). auto.
+      assert ((forall (x : Seq) (l m : MPropF), (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x l -> (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x m -> l = m)).
+      intros. subst. auto.
+      assert (J1: Gimap (GUI p) (GLR_prems (nodupseq leaf)) (map (UI p) (GLR_prems (nodupseq leaf)))).
+      apply Gimap_map ; auto. intros ; apply UI_GUI ; auto.
+      pose (@GN_inv_noinit_nolessub p _ _ _ _ g J0 n0 J1).
+      rewrite <- e ; auto. clear e. clear J1. clear H0. apply OrL. 2: apply OrL.
+      1-3: apply list_disj_L ; intros. 1-2: unfold restr_list_prop in H0.
+      apply InT_In in H0. apply In_remove_In_list in H0.
+      apply In_list_prop_LF in H0. destruct H0. apply In_InT in i. apply InT_split in i. destruct i. destruct s1.
+      rewrite e. assert (A :: fst leaf = [] ++ A :: fst leaf). auto. rewrite H0. apply Id_all_form.
+      apply InT_map_iff in H0. destruct H0. destruct p0. subst. unfold Neg.
+      apply derI with (ps:=[([] ++ fst leaf, [] ++ x0 :: snd leaf);([] ++ :: fst leaf, [] ++ snd leaf)]).
+      assert ((x0 --> :: fst leaf, snd leaf) = ([] ++ x0 --> :: fst leaf, [] ++ snd leaf)). auto. rewrite H0. apply ImpL. apply ImpLRule_I.
+      apply dlCons. 2: apply dlCons. 3: apply dlNil.
+      apply InT_In in i. apply In_remove_In_list in i. apply In_list_prop_LF in i. destruct i. apply In_InT in i.
+      apply InT_split in i. destruct i. destruct s1. rewrite e. assert ([] ++ x1 ++ x0 :: x2 = x1 ++ x0 :: x2). auto.
+      rewrite H0. apply Id_all_form. apply derI with (ps:=[]). apply BotL. apply BotLRule_I. apply dlNil.
+      apply InT_map_iff in H0. destruct H0. destruct p0. subst. apply InT_map_iff in i. destruct i. destruct p0.
+      subst. unfold GLR_prems in i. destruct (finite_GLR_premises_of_S (nodupseq leaf)).
+      simpl in i. apply InT_flatten_list_InT_elem in i. destruct i. destruct p1. apply p0 in i0.
+      inversion i0 ; subst. inversion i ; subst. simpl. remember (UI p (XBoxed_list ++ [Box A], [A])) as Interp.
+      apply derI with (ps:=[(XBoxed_list (Box Interp :: (top_boxes (fst leaf))) ++ [Box A], [A])]). apply GLR.
+      assert (InT (Box A) (snd leaf)).
+      apply In_InT ; apply (nodup_In eq_dec_form) ; rewrite <- H3 ; apply in_or_app ; right ; simpl ; auto.
+      apply InT_split in H0. destruct H0. destruct s. rewrite e. apply GLRRule_I.
+      intro. intros. inversion H0 ; simpl. exists Interp ; auto. apply in_top_boxes in H1. destruct H1.
+      destruct s. destruct s. destruct p1 ; subst. eexists ; auto. apply univ_gen_ext_cons.
+      apply nobox_top_boxes. apply dlCons. 2: apply dlNil. simpl.
+      pose (incl_prv (Interp :: Box Interp :: XBoxed_list ++ [Box A], [A])). apply g0 ; clear g0 ; simpl ; auto. 1-2: intros B HB ; auto.
+      inversion HB ; simpl ; subst ; auto. inversion HB ; simpl ; subst ; auto. inversion H1 ; simpl ; subst ; auto.
+      apply in_app_or in H4 ; destruct H4. right. right. apply in_or_app ; left. apply In_XBoxed_list_gen in H4.
+      destruct H4. apply list_preserv_XBoxed_list. destruct (is_box_is_in_boxed_list _ H4 H2) ; subst.
+      apply is_box_in_top_boxes ; auto. 2: eexists ; auto. apply (nodup_In eq_dec_form).
+      apply (univ_gen_ext_In _ X0 H4). destruct H4. destruct H4 ; subst. apply XBoxed_list_In.
+      apply is_box_in_top_boxes ; auto. 2: eexists ; auto. apply (nodup_In eq_dec_form).
+      apply (univ_gen_ext_In _ X0 H4). right. right. apply in_or_app ; auto.
+      assert (J2: length (usable_boxes (XBoxed_list ++ [Box A], [A])) < length (usable_boxes leaf)).
+      assert (J300: length (usable_boxes (XBoxed_list ++ [Box A], [A])) < length (usable_boxes (nodupseq leaf))).
+      apply (GLR_applic_less_usable_boxes i0) ; auto. intro. apply J0. apply is_init_nodupseq ; unfold is_init ; auto.
+      pose (ub_nodupseq leaf). lia.
+      assert (J3: LexSeq (XBoxed_list ++ [Box A], [A]) s0).
+      apply DLW_wf_lex.lex_cons ; auto. pose (leq_ub_unif s0). apply leq_ub_Canopy in H.
+      rewrite <- fixpoint_nodupseq in H.
+      assert (J30:length (usable_boxes (XBoxed_list (top_boxes (fst s0)), []%list)) = length (usable_boxes (nodupseq (XBoxed_list (top_boxes (fst s0)), []%list)))).
+      apply ub_nodupseq. lia.
+      pose (X (XBoxed_list ++ [Box A], [A]) J3 p). simpl in g0. rewrite <- HeqInterp in g0.
+      assert (J4: derrec_height g0 = derrec_height g0). auto.
+      assert (J5: wkn_L (Box Interp) (Interp :: XBoxed_list ++ [Box A], [A]) (Interp :: Box Interp :: XBoxed_list ++ [Box A], [A])).
+      assert (Interp :: XBoxed_list ++ [Box A] = [Interp] ++ XBoxed_list ++ [Box A]) ; auto. rewrite H0.
+      assert (Interp :: Box Interp :: XBoxed_list ++ [Box A] = [Interp] ++ Box Interp :: XBoxed_list ++ [Box A]) ; auto. rewrite H1.
+      apply wkn_LI. pose (GLS_wkn_L g0 J4 J5). destruct s. auto. inversion H1.
+      remember (fst s0) as LHS.
+      assert (GUI p s0
+      (Or (list_disj (restr_list_prop p (snd s0)))
+      (Or (list_disj (map Neg (restr_list_prop p (fst s0))))
+      (Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq s0)))))
+      (Diam (list_conj (map (N p s0) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s0)), []%list)))))))))).
+      apply GUI_critic_not_init ; auto. 1-2: apply Gimap_map ; intros. apply UI_GUI ; auto.
+      apply (@N_spec p s0 x). apply (UI_GUI p s0) in H. rewrite H. rewrite HeqLHS in *. repeat apply OrL ; auto.
+  (* s0 is not a critical sequent *)
+  - assert (J0: GUI p s0 (UI p s0)). apply UI_GUI ; auto.
+    assert (J1: Gimap (GUI p) (Canopy (nodupseq s0)) (map (UI p) (Canopy (nodupseq s0)))). apply Gimap_map. intros.
+    apply UI_GUI ; auto.
+    pose (@GUI_inv_not_critic p s0 (UI p s0) (map (UI p) (Canopy (nodupseq s0))) J0 f J1). rewrite <- e.
+    destruct (LexSeq_nodupseq_case s0).
+    + assert (J2: forall s1, InT s1 (Canopy (nodupseq s0)) -> GLS_prv (UI p s1 :: fst s1, snd s1)).
+       intros. apply X. pose (Canopy_LexSeq _ _ H). destruct s ; subst ; auto. apply LexSeq_trans with (y:=nodupseq s0) ; auto.
+       assert (J3 : forall s1 : Seq, InT s1 (Canopy (nodupseq s0)) -> GLS_prv (list_conj (map (UI p) (Canopy (nodupseq s0))) :: fst s1, snd s1)).
+       intros. apply list_conj_wkn_L with (A:=UI p s1) ; auto. apply InT_mapI. exists s1 ; auto.
+       apply Canopy_nodupseq_equiprv_genL ; auto.
+    + destruct p0. assert (J2: forall s1, InT s1 (Canopy (nodupseq s0)) -> GLS_prv (UI p s1 :: fst s1, snd s1)).
+       intros. apply X. pose (Canopy_LexSeq _ _ H). destruct s ; subst ; auto. exfalso.
+       apply f. apply critical_nodupseq. apply Canopy_critical in H ; auto. unfold LexSeq in *.
+       inversion l ; subst. unfold less_thanS. unfold GLS_termination_measure.measure. rewrite <- e1 in *. rewrite H3. apply DLW_wf_lex.lex_skip ; auto.
+       rewrite e0 in *. apply DLW_wf_lex.lex_cons ; auto. inversion H1 ; subst ; auto. inversion H2. apply DLW_wf_lex.lex_cons ; auto. lia.
+       assert (J3 : forall s1 : Seq, InT s1 (Canopy (nodupseq s0)) -> GLS_prv (list_conj (map (UI p) (Canopy (nodupseq s0))) :: fst s1, snd s1)).
+       intros. apply list_conj_wkn_L with (A:=UI p s1) ; auto. apply InT_mapI. exists s1 ; auto.
+       apply Canopy_nodupseq_equiprv_genL ; auto. }
+  Qed.
+ +
+  End UIPTwo.
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_UI_inter.html b/GL.Interpolation.UIGL_UI_inter.html new file mode 100644 index 0000000..f5ff5ba --- /dev/null +++ b/GL.Interpolation.UIGL_UI_inter.html @@ -0,0 +1,631 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_UI_inter

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat.
+Require Import Lia.
+ +
+Require Import general_export.
+ +
+Require Import GLS_export.
+ +
+Require Import UIGL_Def_measure.
+Require Import UIGL_Canopy.
+Require Import UIGL_irred_short.
+Require Import UIGL_braga.
+Require Import UIGL_LexSeq.
+Require Import UIGL_nodupseq.
+Require Import UIGL_PermutationT.
+Require Import UIGL_PermutationTS.
+Require Import UIGL_And_Or_rules.
+Require Import UIGL_UI_prelims.
+ +
+  Theorem PermutationTS_UI : forall s sp p, PermutationTS s sp -> GLS_prv ([UI p s], [UI p sp]).
+  Proof.
+  pose (d:=LexSeq_ind (fun (s:Seq) => forall sp p, PermutationTS s sp -> GLS_prv ([UI p s], [UI p sp]))).
+  apply d. clear d. intros s IH sp p perm.
+  destruct (empty_seq_dec s) as [EE | DE].
+  { subst. assert (J0: GUI p ([],[]) Bot). apply GUI_empty_seq ; auto. apply UI_GUI in J0.
+     rewrite J0 in *. apply derI with []. apply BotL ; apply (BotLRule_I [] []). apply dlNil. }
+  { destruct (critical_Seq_dec s).
+  (* Sequents are critical. *)
+  - pose (PermutationTS_critic _ _ perm c).
+    destruct (dec_init_rules s).
+    (* Sequents are initial. *)
+    * assert (is_init s) ; auto. pose (PermutationTS_is_init _ _ perm X).
+      assert (J0: GUI p sp (UI p sp)). apply UI_GUI ; auto.
+      pose (@GUI_inv_critic_init p sp _ J0 c0 i). rewrite <- e. epose (TopR _ [] []). simpl in g ; apply g.
+    (* Sequents are not initial. *)
+    * assert ((is_init s) -> False) ; auto. assert ((is_init sp) -> False). intro. apply H.
+      pose (PermutationTS_sym _ _ perm). apply (PermutationTS_is_init _ _ p0) ; auto.
+      assert (J0: GUI p s (UI p s)). apply UI_GUI ; auto.
+      assert (J00: GUI p sp (UI p sp)). apply UI_GUI ; auto.
+      assert (J1: Gimap (GUI p) (GLR_prems (nodupseq s)) (map (UI p) (GLR_prems (nodupseq s)))). apply Gimap_map. intros.
+      apply UI_GUI ; auto.
+      assert (J10: Gimap (GUI p) (GLR_prems (nodupseq sp)) (map (UI p) (GLR_prems (nodupseq sp)))). apply Gimap_map. intros.
+      apply UI_GUI ; auto.
+      assert (J2: (Gimap (GN p (GUI p) s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), [])))
+      (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), [])))))). apply Gimap_map. intros.
+      pose (N_spec p s x) ; auto.
+      assert (J20: (Gimap (GN p (GUI p) sp) (Canopy (nodupseq (XBoxed_list (top_boxes (fst sp)), [])))
+      (map (N p sp) (Canopy (nodupseq (XBoxed_list (top_boxes (fst sp)), [])))))). apply Gimap_map. intros.
+      apply (N_spec p sp x).
+      assert (J41: sp <> ([], [])). intro. destruct sp ; destruct s ; inversion H1 ; subst. apply DE. destruct perm. simpl in *.
+      destruct (Permutation_PermutationT l1 []). pose (p3 p0). apply Permutation_sym in p4 ; apply Permutation_nil in p4.
+      destruct (Permutation_PermutationT l2 []). pose (p6 p1). apply Permutation_sym in p7 ; apply Permutation_nil in p7 ; subst ; auto.
+       pose (@GUI_inv_critic_not_init p s _ _ _ J0 c DE H J1 J2). rewrite <- e ; clear e.
+       pose (@GUI_inv_critic_not_init p sp _ _ _ J00 c0 J41 H0 J10 J20). rewrite <- e ; clear e.
+        epose (OrR (_,[])). simpl in g. apply g ; clear g.
+        epose (OrL ([],_)). simpl in g. apply g ; clear g.
+        epose (list_disj_L _ (_,_)). apply g ; clear g. simpl ; intros.
+        pose (PermutationTS_restr_list_prop_snd _ _ _ _ perm H1).
+        epose (list_disj_wkn_R _ ([_],[_]) _ i). simpl in g. apply g ; clear g.
+        epose (Id_all_form _ [] _ []). simpl in d ; apply d.
+        eapply GLS_prv_wkn_R with (s:=([Or (list_disj (map Neg (restr_list_prop p (fst s)))) (Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq s)))))
+       (Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))))))], [Or (list_disj (map Neg (restr_list_prop p (fst sp)))) (Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq sp)))))
+        (Diam (list_conj (map (N p sp) (Canopy (nodupseq (XBoxed_list (top_boxes (fst sp)), []%list)))))))])) (A:=list_disj (restr_list_prop p (snd sp))).
+        2: epose (wkn_RI (list_disj (restr_list_prop p (snd sp))) _ [] _) ; simpl in w ; apply w.
+        epose (OrR (_,[])). simpl in g. apply g ; clear g.
+        epose (OrL ([],_)). simpl in g. apply g ; clear g.
+        epose (list_disj_L _ (_,_)). apply g ; clear g. simpl ; intros.
+        apply InT_map_iff in H1. destruct H1. destruct p0 ; subst.
+        pose (@PermutationTS_restr_list_prop_fst _ _ p x perm i).
+        epose (list_disj_wkn_R _ ([_],[_]) _). simpl in g. apply g ; clear g. apply InT_map_iff. exists x ; split ; auto.
+        epose (Id_all_form _ [] _ []). simpl in d ; apply d.
+        eapply GLS_prv_wkn_R with (s:=([Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq s))))) (Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))))],
+        [(Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq sp)))))
+        (Diam (list_conj (map (N p sp) (Canopy (nodupseq (XBoxed_list (top_boxes (fst sp)), []%list)))))))])) (A:=list_disj (map Neg (restr_list_prop p (fst sp)))).
+        2: epose (wkn_RI (list_disj (map Neg (restr_list_prop p (fst sp)))) _ [] _) ; simpl in w ; apply w.
+        epose (OrR (_,[])). simpl in g. apply g ; clear g.
+        epose (OrL ([],_)). simpl in g. apply g ; clear g.
+        epose (list_disj_L _ (_,_)). apply g ; clear g. simpl ; intros. apply InT_map_iff in H1.
+        destruct H1. destruct p0 ; subst. apply InT_map_iff in i. destruct i. destruct p0 ; subst.
+        destruct (PermutationTS_GLR_prems _ _ (PermutationTS_nodupseq _ _ perm) _ i). destruct p0.
+        epose (list_disj_wkn_R _ ([_],_) (Box (UI p x))). simpl in g. apply g ; clear g.
+        apply InT_map_iff. exists (UI p x). split ; auto. apply InT_map_iff. exists x ; split ; auto.
+        apply derI with (ps:=[([(UI p x0);Box (UI p x0);Box (UI p x)], [UI p x])]). apply GLR.
+        epose (@GLRRule_I _ [Box (UI p x0)] _ []). simpl in g. apply g. intros A HA. inversion HA ; subst.
+        eexists ; auto. inversion H1. apply univ_gen_ext_refl. apply dlCons. 2: apply dlNil.
+        assert (J50: GLS_prv ([UI p x0], [UI p x])).
+        apply IH ; auto. apply GLR_prems_LexSeq in i ; auto. apply LexSeq_nodupseq in i ; auto.
+        intro. assert (is_init (nodupseq s)) ; auto. unfold is_init ; auto. apply H. apply is_init_nodupseq ; auto.
+        epose (GLS_prv_list_wkn_L [UI p x0] [] J50 _). simpl in g ; rewrite app_nil_r in g. apply g.
+        eapply GLS_prv_wkn_R with (s:=([Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))))],
+        [Diam (list_conj (map (N p sp) (Canopy (nodupseq (XBoxed_list (top_boxes (fst sp)), []%list)))))])) (A:=list_disj (map Box (map (UI p) (GLR_prems (nodupseq sp))))).
+        2: epose (wkn_RI (list_disj (map Box (map (UI p) (GLR_prems (nodupseq sp))))) _ [] _) ; simpl in w ; apply w.
+        remember (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) as conjL.
+        remember (list_conj (map (N p sp) (Canopy (nodupseq (XBoxed_list (top_boxes (fst sp)), []%list))))) as conjR.
+        apply derI with (ps:=[([Box (Neg conjR) ; Diam conjL], [Bot])]). apply ImpR. epose (ImpRRule_I _ _ [] [_] [] []). simpl in i ; apply i.
+        apply dlCons. 2: apply dlNil.
+        apply derI with (ps:=[([Box (Neg conjR)], [Box (Neg conjL);]);([Box (Neg conjR); ], [])]).
+        apply ImpL. epose (ImpLRule_I _ _ [_] [] [] [_]). simpl in i. apply i. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+        2: apply derI with (ps:=[]) ; [ apply BotL ; epose (BotLRule_I [_] []) ; simpl in b ; auto | apply dlNil].
+        apply derI with (ps:=[([Neg conjR;Box (Neg conjR);Box (Neg conjL)], [Neg conjL])]). apply GLR.
+        epose (@GLRRule_I _ [Box (Neg conjR)] _ [] [_]). simpl in g ; apply g ; clear g ; auto. intros A HA. inversion HA ; subst.
+        eexists ; auto. inversion H1. apply univ_gen_ext_refl. apply dlCons. 2: apply dlNil.
+        apply derI with (ps:=[([conjL;Neg conjR; Box (Neg conjR); Box (Neg conjL)], [Bot])]). apply ImpR. epose (ImpRRule_I _ _ [] _ [] []). simpl in i ; apply i.
+        apply dlCons. 2: apply dlNil.
+        apply derI with (ps:=[([conjL; Box (Neg conjR); Box (Neg conjL)], [conjR;]);([conjL; Bot; Box (Neg conjR); Box (Neg conjL)], [])]).
+        apply ImpL. epose (ImpLRule_I _ _ [_] _ [] [_]). simpl in i. apply i. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+        2: apply derI with (ps:=[]) ; [ apply BotL ; epose (BotLRule_I [_] _) ; simpl in b ; auto | apply dlNil].
+        remember ([Box (Neg conjR); Box (Neg conjL)]) as LHS0. rewrite HeqconjL. rewrite HeqconjR.
+        epose (list_conj_R _ (_,_)). apply g ; clear g. simpl ; intros. apply InT_map_iff in H1.
+        destruct H1. destruct p0 ; subst.
+        assert (PermutationTS (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)) (nodupseq (XBoxed_list (top_boxes (fst sp)), []%list))).
+        apply PermutationTS_nodupseq. split ; simpl ; auto. apply PermutationT_XBoxed_list. apply PermutationT_top_boxes. destruct perm ; auto.
+        apply PermutationT_refl. apply PermutationTS_sym in H1.
+        pose (PermutationTS_Canopy _ _ H1 _ i). destruct s0. destruct p0.
+        epose (list_conj_wkn_L _ (_,_) (N p s x0)). simpl in g. apply g ; clear g.
+        apply InT_map_iff. exists x0 ; split ; auto.
+ +
+        assert (J100: GLS_prv ([N p s x0], [N p sp x])).
+        { (* Massage the Ns. *)
+          assert ((forall (x : Seq) (l m : MPropF), (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x l -> (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x m -> l = m)).
+          intros. subst. auto.
+          destruct (dec_init_rules x0).
+          (* The sequents x0 and x are initial. *)
+           assert (is_init x0) ; auto. pose (PermutationTS_is_init _ _ (PermutationTS_sym _ _ p0) X).
+           pose (N_spec p sp x).
+           pose (GN_inv_init _ g i1). rewrite <- e.
+           epose (TopR _ [] []). simpl in g0 ; apply g0.
+          (* The sequent x0 and x are not initial. *)
+           assert (is_init x0 -> False) ; auto.
+           assert (is_init x -> False). intro. apply H3. apply (PermutationTS_is_init _ _ p0 X).
+           assert (J200: GUI p x0 (UI p x0)). apply UI_GUI ; auto.
+           assert (J300: GUI p x (UI p x)). apply UI_GUI ; auto.
+           pose (Canopy_critical _ _ i0).
+           pose (Canopy_critical _ _ i).
+           assert (J80: length (usable_boxes s) = length (usable_boxes sp)).
+           assert (incl (usable_boxes s) (usable_boxes sp)). intros A HA. apply InT_In. apply In_InT in HA.
+           apply (PermutationTS_usable_boxes _ _ perm) ; auto.
+           epose (NoDup_incl_length (NoDup_usable_boxes s) H5).
+           assert (incl (usable_boxes sp) (usable_boxes s)). intros A HA. apply InT_In. apply In_InT in HA.
+           apply (PermutationTS_usable_boxes _ _ (PermutationTS_sym _ _ perm)) ; auto.
+           epose (NoDup_incl_length (NoDup_usable_boxes sp) H6). lia.
+           assert (J81: length (usable_boxes x) = length (usable_boxes x0)).
+           assert (incl (usable_boxes x) (usable_boxes x0)). intros A HA. apply InT_In. apply In_InT in HA.
+           apply (PermutationTS_usable_boxes _ _ p0) ; auto.
+           epose (NoDup_incl_length (NoDup_usable_boxes x) H5).
+           assert (incl (usable_boxes x0) (usable_boxes x)). intros A HA. apply InT_In. apply In_InT in HA.
+           apply (PermutationTS_usable_boxes _ _ (PermutationTS_sym _ _ p0)) ; auto.
+           epose (NoDup_incl_length (NoDup_usable_boxes x0) H6). lia.
+           destruct (Compare_dec.lt_dec (length (usable_boxes x0)) (length (usable_boxes s))).
+           (* The sequent x0 has less usable boxes than s. *)
+           pose (N_spec p s x0).
+           epose (@GN_inv_noinit_lessub _ _ _ _ _ g H3 l J200). rewrite <- e ; auto.
+           assert (J500: length (usable_boxes x) < length (usable_boxes sp)). lia.
+           pose (N_spec p sp x).
+           epose (@GN_inv_noinit_lessub _ _ _ _ _ g0 H4 J500 J300). rewrite <- e0 ; auto.
+           apply IH. apply DLW_wf_lex.lex_cons ; auto. apply PermutationTS_sym ; auto.
+           (* The sequent x0 does not have less usable boxes than s. *)
+           pose (N_spec p s x0).
+           assert (J410: Gimap (GUI p) (GLR_prems (nodupseq x0)) (map (UI p) (GLR_prems (nodupseq x0)))).
+           apply Gimap_map ; auto. intros. apply UI_GUI ; auto.
+           epose (@GN_inv_noinit_nolessub _ _ _ _ _ g H3 n J410). rewrite <- e ; auto.
+           assert (J42: (length (usable_boxes x) < length (usable_boxes sp)) -> False). lia.
+           pose (N_spec p sp x).
+           assert (J43: Gimap (GUI p) (GLR_prems (nodupseq x)) (map (UI p) (GLR_prems (nodupseq x)))).
+           apply Gimap_map ; auto. intros. apply UI_GUI ; auto.
+           epose (@GN_inv_noinit_nolessub _ _ _ _ _ g0 H4 J42 J43). rewrite <- e0 ; auto.
+           epose (OrR (_,[])). simpl in g1. apply g1 ; clear g1.
+           epose (OrL ([],_)). simpl in g1. apply g1 ; clear g1.
+           epose (list_disj_L _ (_,_)). apply g1 ; clear g1. simpl ; intros.
+           pose (PermutationTS_restr_list_prop_snd _ _ _ _ (PermutationTS_sym _ _ p0) H5).
+           epose (list_disj_wkn_R _ ([_],[_]) _ i1). simpl in g1. apply g1 ; clear g1.
+           epose (Id_all_form _ [] _ []). simpl in d ; apply d.
+           eapply GLS_prv_wkn_R with (s:=([Or (list_disj (map Neg (restr_list_prop p (fst x0)))) (list_disj (map Box (map (UI p) (GLR_prems (nodupseq x0)))))],
+           [Or (list_disj (map Neg (restr_list_prop p (fst x)))) (list_disj (map Box (map (UI p) (GLR_prems (nodupseq x)))))])) (A:=list_disj (restr_list_prop p (snd x))).
+           2: epose (wkn_RI (list_disj (restr_list_prop p (snd x))) _ [] _) ; simpl in w ; apply w.
+           epose (OrR (_,[])). simpl in g1. apply g1 ; clear g1.
+           epose (OrL ([],_)). simpl in g1. apply g1 ; clear g1.
+           epose (list_disj_L _ (_,_)). apply g1 ; clear g1. simpl ; intros.
+           apply InT_map_iff in H5. destruct H5. destruct p1 ; subst.
+           pose (@PermutationTS_restr_list_prop_fst _ _ p x1 (PermutationTS_sym _ _ p0) i1).
+           epose (list_disj_wkn_R _ ([_],[_]) _). simpl in g1. apply g1 ; clear g1. apply InT_map_iff. exists x1 ; split ; auto.
+           epose (Id_all_form _ [] _ []). simpl in d ; apply d.
+           eapply GLS_prv_wkn_R with (s:=([list_disj (map Box (map (UI p) (GLR_prems (nodupseq x0))))],
+           [list_disj (map Box (map (UI p) (GLR_prems (nodupseq x))))])) (A:=list_disj (map Neg (restr_list_prop p (fst x)))).
+           2: epose (wkn_RI (list_disj (map Neg (restr_list_prop p (fst x)))) _ [] _) ; simpl in w ; apply w.
+            epose (list_disj_L _ (_,_)). apply g1 ; clear g1. simpl ; intros. apply InT_map_iff in H5.
+            destruct H5. destruct p1 ; subst. apply InT_map_iff in i1. destruct i1. destruct p1 ; subst.
+            destruct (PermutationTS_GLR_prems _ _ (PermutationTS_nodupseq _ _ (PermutationTS_sym _ _ p0)) _ i1). destruct p1.
+            epose (list_disj_wkn_R _ ([_],_) (Box (UI p x1))). simpl in g1. apply g1 ; clear g1.
+            apply InT_map_iff. exists (UI p x1). split ; auto. apply InT_map_iff. exists x1 ; split ; auto.
+            apply derI with (ps:=[([(UI p x2);Box (UI p x2);Box (UI p x1)], [UI p x1])]). apply GLR.
+            epose (@GLRRule_I _ [Box (UI p x2)] _ []). simpl in g1. apply g1 ; clear g1. intros A HA. inversion HA ; subst.
+            eexists ; auto. inversion H5. apply univ_gen_ext_refl. apply dlCons. 2: apply dlNil.
+            assert (J50: GLS_prv ([UI p x2], [UI p x1])). apply IH ; auto.
+            pose (leq_ub_unif s). pose (leq_ub_Canopy _ _ i0). apply DLW_wf_lex.lex_cons ; auto.
+            unfold GLR_prems in i1. destruct (finite_GLR_premises_of_S (nodupseq x0)). simpl in i1. apply InT_flatten_list_InT_elem in i1.
+            destruct i1. destruct p3. apply p2 in i3. inversion i3 ; subst. inversion i1 ; subst.
+            assert ((IdBRule []%list (nodupseq x0)) -> False). intro. assert (is_init (nodupseq x0)).
+            destruct x0 ; simpl in H5 ; simpl in H8 ; unfold nodupseq ; simpl ; unfold is_init ; subst ; auto.
+            apply is_init_nodupseq in X0 ; auto. pose (GLR_applic_less_usable_boxes i3 H5).
+            assert (J30:length (usable_boxes (XBoxed_list (top_boxes (fst s)), []%list)) = length (usable_boxes (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))).
+            apply ub_nodupseq. rewrite <- J30 in l0. pose (ub_nodupseq x0). lia. inversion H6.
+            epose (@GLS_prv_list_wkn_L [_] [] _). rewrite app_nil_r in g1 ; simpl in g1. epose (g1 J50 [_;_]). simpl in g2. apply g2. }
+
+        epose (@GLS_prv_list_wkn_R _ _ []). rewrite app_nil_r in g ; simpl in g. pose (g J100 [Bot]). simpl in g0.
+        epose (@GLS_prv_list_wkn_L [_] [] _). rewrite app_nil_r in g1 ; simpl in g1. epose (g1 g0 [_;_]). simpl in g2. apply g2.
+  (* Sequents are not critical. *)
+  - assert (J0: GUI p s (UI p s)). apply UI_GUI ; auto. assert (J00: GUI p sp (UI p sp)). apply UI_GUI ; auto.
+    assert (J1: Gimap (GUI p) (Canopy (nodupseq s)) (map (UI p) (Canopy (nodupseq s)))). apply Gimap_map. intros.
+    apply UI_GUI ; auto.
+    assert (J10: Gimap (GUI p) (Canopy (nodupseq sp)) (map (UI p) (Canopy (nodupseq sp)))). apply Gimap_map. intros.
+    apply UI_GUI ; auto.
+    pose (@GUI_inv_not_critic p s _ _ J0 f J1). rewrite <- e ; clear e.
+    assert (critical_Seq sp -> False). intro. apply f. apply (PermutationTS_critic _ _ (PermutationTS_sym _ _ perm) H).
+    pose (@GUI_inv_not_critic p sp _ _ J00 H J10). rewrite <- e ; clear e.
+    epose (list_conj_R _ (_,_)). simpl in g. apply g ; clear g. intros.
+    apply InT_map_iff in H0. destruct H0. destruct p0. subst.
+    pose (PermutationTS_nodupseq _ _ perm). apply PermutationTS_sym in p0.
+    pose (PermutationTS_Canopy _ _ p0 _ i). destruct s0. destruct p1.
+    epose (list_conj_wkn_L _ (_,_) (UI p x0)). simpl in g. apply g ; clear g.
+    apply InT_map_iff. exists x0 ; split ; auto.
+    assert (LexSeq x0 s). pose (Canopy_LexSeq _ _ i0). destruct s0 ; subst ; auto. exfalso.
+    apply f ; apply Canopy_critical in i0 ; auto. apply critical_nodupseq ; auto. apply LexSeq_nodupseq in l ; auto.
+    apply (IH _ H0 _ p (PermutationTS_sym _ _ p1)). }
+  Qed.
+ +
+  Lemma UI_nodupseq : forall s p X Y, GLS_prv (UI p (nodupseq s) :: X, UI p s :: Y).
+  Proof.
+  pose (d:=LexSeq_ind (fun (s:Seq) => forall p X Y, GLS_prv (UI p (nodupseq s) :: X, UI p s :: Y))).
+  apply d. clear d. intros s IH p X Y.
+  destruct (empty_seq_dec s) as [EE | DE].
+  { subst. unfold nodupseq. simpl. assert (J0: GUI p ([],[]) Bot). apply GUI_empty_seq ; auto. apply UI_GUI in J0.
+     rewrite J0 in *. apply derI with []. apply BotL ; apply (BotLRule_I []). apply dlNil. }
+  { destruct (critical_Seq_dec s).
+  (* Sequents are critical. *)
+  - assert (critical_Seq (nodupseq s)). apply (critical_nodupseq s) ; auto.
+    destruct (dec_init_rules s).
+    (* Sequents are initial. *)
+    * assert (is_init s) ; auto. assert (is_init (nodupseq s)). apply (is_init_nodupseq s) ; auto.
+      assert (J0: GUI p s (UI p s)). apply UI_GUI ; auto.
+      pose (@GUI_inv_critic_init p s _ J0 c X0). rewrite <- e. epose (TopR _ [] _). simpl in g ; apply g.
+    (* Sequents are not initial. *)
+    * assert ((is_init s) -> False) ; auto. assert ((is_init (nodupseq s)) -> False). intro. apply H0.
+      apply (is_init_nodupseq s) ; auto.
+      assert (J0: GUI p s (UI p s)). apply UI_GUI ; auto.
+      assert (J00: GUI p (nodupseq s) (UI p (nodupseq s))). apply UI_GUI ; auto.
+      assert (J1: Gimap (GUI p) (GLR_prems (nodupseq s)) (map (UI p) (GLR_prems (nodupseq s)))). apply Gimap_map. intros.
+      apply UI_GUI ; auto.
+      assert (J10: Gimap (GUI p) (GLR_prems (nodupseq (nodupseq s))) (map (UI p) (GLR_prems (nodupseq (nodupseq s))))). apply Gimap_map. intros.
+      apply UI_GUI ; auto.
+      assert (J2: (Gimap (GN p (GUI p) s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), [])))
+      (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), [])))))). apply Gimap_map. intros.
+      apply (N_spec p s x).
+      assert (J20: (Gimap (GN p (GUI p) (nodupseq s)) (Canopy (nodupseq (XBoxed_list (top_boxes (fst (nodupseq s))), [])))
+      (map (N p (nodupseq s)) (Canopy (nodupseq (XBoxed_list (top_boxes (fst (nodupseq s))), [])))))). apply Gimap_map. intros.
+      apply (N_spec p (nodupseq s) x).
+      assert (J41: (nodupseq s) <> ([],[])). intro. apply DE. destruct s. simpl in *. unfold nodupseq in *. simpl in H2. inversion H2 ; subst.
+      apply nodup_nil in H4 ; rewrite H4 in H5 ; apply nodup_nil in H5 ; subst ; auto.
+       pose (@GUI_inv_critic_not_init p s _ _ _ J0 c DE H0 J1 J2). rewrite <- e ; clear e.
+       pose (@GUI_inv_critic_not_init p (nodupseq s) _ _ _ J00 H J41 H1 J10 J20). rewrite <- e ; clear e.
+       repeat rewrite <- fixpoint_nodupseq.
+        epose (OrR (_,_)). simpl in g. apply g ; clear g.
+        epose (OrL (_,_)). simpl in g. apply g ; clear g.
+        epose (list_disj_L _ (_,_)). apply g ; clear g. simpl ; intros.
+        epose (restr_list_prop_nodup (snd s) A p). apply p0 in H2.
+        epose (list_disj_wkn_R _ (_,_) _ H2). simpl in g. apply g ; clear g.
+        epose (Id_all_form _ [] _ []). simpl in d ; apply d.
+        eapply GLS_prv_wkn_R with (s:=((Or (list_disj (map Neg (restr_list_prop p (fst (nodupseq s))))) (Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq s)))))
+        (Diam (list_conj (map (N p (nodupseq s)) (Canopy (nodupseq (XBoxed_list (top_boxes (fst (nodupseq s))), []%list)))))))) :: X, Or (list_disj (map Neg (restr_list_prop p (fst s))))
+        (Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq s))))) (Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))))) :: Y)) (A:=list_disj (restr_list_prop p (snd s))).
+        2: epose (wkn_RI (list_disj (restr_list_prop p (snd s))) _ [] _) ; simpl in w ; apply w.
+        epose (OrR (_,_)). simpl in g. apply g ; clear g.
+        epose (OrL (_,_)). simpl in g. apply g ; clear g.
+        epose (list_disj_L _ (_,_)). apply g ; clear g. simpl ; intros.
+        apply InT_map_iff in H2. destruct H2. destruct p0 ; subst.
+        epose (restr_list_prop_nodup (fst s) x p). apply p0 in i.
+        epose (list_disj_wkn_R _ (_,_) _). simpl in g. apply g ; clear g. apply InT_map_iff. exists x ; split ; auto.
+        epose (Id_all_form _ [] _ []). simpl in d ; apply d.
+        eapply GLS_prv_wkn_R with (s:=((Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq s))))) (Diam (list_conj (map (N p (nodupseq s)) (Canopy (nodupseq (XBoxed_list (top_boxes (fst (nodupseq s))), []%list))))))) :: X,
+        (Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq s)))))
+        (Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))))) :: Y)) (A:=list_disj (map Neg (restr_list_prop p (fst s)))).
+        2: epose (wkn_RI (list_disj (map Neg (restr_list_prop p (fst s)))) _ [] _) ; simpl in w ; apply w.
+        epose (OrR (_,_)). simpl in g. apply g ; clear g.
+        epose (OrL (_,_)). simpl in g. apply g ; clear g.
+        epose (list_disj_L _ (_,_)). apply g ; clear g. simpl ; intros. apply InT_map_iff in H2.
+        destruct H2. destruct p0 ; subst. apply InT_map_iff in i. destruct i. destruct p0 ; subst.
+        epose (list_disj_wkn_R _ (_,_) (Box (UI p x0))). simpl in g. apply g ; clear g.
+        apply InT_map_iff. exists (UI p x0). split ; auto. apply InT_map_iff. exists x0 ; split ; auto.
+        epose (Id_all_form _ [] _ []). simpl in d ; apply d.
+        eapply GLS_prv_wkn_R with (s:=((Diam (list_conj (map (N p (nodupseq s)) (Canopy (nodupseq (XBoxed_list (top_boxes (fst (nodupseq s))), []%list)))))) :: X,
+        Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) :: Y)) (A:=list_disj (map Box (map (UI p) (GLR_prems (nodupseq s))))).
+        2: epose (wkn_RI (list_disj (map Box (map (UI p) (GLR_prems (nodupseq s))))) _ [] _) ; simpl in w ; apply w.
+        remember (list_conj (map (N p (nodupseq s)) (Canopy (nodupseq (XBoxed_list (top_boxes (fst (nodupseq s))), []%list))))) as conjL.
+        remember (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) as conjR.
+        apply derI with (ps:=[(Box (Neg conjR) :: Diam conjL :: X, Bot :: Y)]). apply ImpR. epose (ImpRRule_I _ _ [] _ [] _). simpl in i ; apply i.
+        apply dlCons. 2: apply dlNil.
+        apply derI with (ps:=[(Box (Neg conjR) :: X, Box (Neg conjL) :: :: Y);(Box (Neg conjR) :: :: X, :: Y)]).
+        apply ImpL. epose (ImpLRule_I _ _ [_] _ [] _). simpl in i. apply i. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+        2: apply derI with (ps:=[]) ; [ apply BotL ; epose (BotLRule_I [_] _) ; simpl in b ; auto | apply dlNil].
+        apply derI with (ps:=[(Neg conjR :: Box (Neg conjR) :: XBoxed_list (top_boxes X) ++ [Box (Neg conjL)], [Neg conjL])]). apply GLR.
+        epose (@GLRRule_I _ (Box (Neg conjR) :: (top_boxes X)) _ [] _). simpl in g ; apply g ; clear g ; auto. intros A HA. inversion HA ; subst.
+        eexists ; auto. apply in_top_boxes in H2. destruct H2. destruct s0. destruct s0. destruct p0 ; subst. eexists ; auto.
+        apply univ_gen_ext_cons. apply nobox_top_boxes. apply dlCons. 2: apply dlNil.
+        apply derI with (ps:=[(conjL :: Neg conjR :: Box (Neg conjR) :: XBoxed_list (top_boxes X) ++ [Box (Neg conjL)], [Bot])]). apply ImpR. epose (ImpRRule_I _ _ [] _ [] []). simpl in i ; apply i.
+        apply dlCons. 2: apply dlNil.
+        apply derI with (ps:=[(conjL :: Box (Neg conjR) :: XBoxed_list (top_boxes X) ++ [Box (Neg conjL)], [conjR;]);(conjL :: Bot :: Box (Neg conjR) :: XBoxed_list (top_boxes X) ++ [Box (Neg conjL)], [])]).
+        apply ImpL. epose (ImpLRule_I _ _ [_] _ [] [_]). simpl in i. apply i. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+        2: apply derI with (ps:=[]) ; [ apply BotL ; epose (BotLRule_I [_] _) ; simpl in b ; auto | apply dlNil].
+        remember (Box (Neg conjR) :: XBoxed_list (top_boxes X) ++ [Box (Neg conjL)]) as LHS0. rewrite HeqconjL. rewrite HeqconjR.
+        epose (list_conj_R _ (_,_)). apply g ; clear g. simpl ; intros. apply InT_map_iff in H2.
+        destruct H2. destruct p0 ; subst.
+        assert (J70: (nodupseq (XBoxed_list (top_boxes (nodup eq_dec_form (fst s))), []%list)) = (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))).
+        unfold nodupseq ; simpl. rewrite <- nodup_top_boxes. rewrite nodup_XBoxed_list ; auto. rewrite J70.
+        epose (list_conj_wkn_L _ (_,_) (N p (nodupseq s) x)). simpl in g. apply g ; clear g.
+        apply InT_map_iff. exists x ; split ; auto.
+ +
+        assert (J100: GLS_prv ([N p (nodupseq s) x], [N p s x])).
+        { (* Massage the Ns. *)
+          assert ((forall (x : Seq) (l m : MPropF), (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x l -> (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x m -> l = m)).
+          intros. subst. auto.
+          destruct (dec_init_rules x).
+          (* The sequent x is initial. *)
+           assert (is_init x) ; auto.
+           pose (N_spec p s x).
+           pose (GN_inv_init _ g). rewrite <- e ; auto.
+           epose (TopR _ [] []). simpl in g0 ; apply g0.
+          (* The sequent x is not initial. *)
+           assert (is_init x -> False) ; auto.
+           assert (J300: GUI p x (UI p x)). apply UI_GUI ; auto.
+           pose (Canopy_critical _ _ i).
+           pose (ub_nodupseq s).
+           destruct (Compare_dec.lt_dec (length (usable_boxes x)) (length (usable_boxes s))).
+           (* The sequent x0 has less usable boxes than s. *)
+           pose (N_spec p s x).
+           epose (@GN_inv_noinit_lessub _ _ _ _ _ g H3 l J300). rewrite <- e0 ; auto.
+           assert (J500: length (usable_boxes x) < length (usable_boxes (nodupseq s))). lia.
+           pose (N_spec p (nodupseq s) x).
+           epose (@GN_inv_noinit_lessub _ _ _ _ _ g0 H3 J500 J300). rewrite <- e1 ; auto.
+           epose (Id_all_form _ [] _ []). simpl in d ; apply d.
+           (* The sequent x does not have less usable boxes than s. *)
+           pose (N_spec p s x).
+           assert (J410: Gimap (GUI p) (GLR_prems (nodupseq x)) (map (UI p) (GLR_prems (nodupseq x)))).
+           apply Gimap_map ; auto. intros ; apply UI_GUI ; auto.
+           epose (@GN_inv_noinit_nolessub _ _ _ _ _ g H3 n J410). rewrite <- e0 ; auto.
+           assert (J42: (length (usable_boxes x) < length (usable_boxes (nodupseq s))) -> False). lia.
+           pose (N_spec p (nodupseq s) x).
+           assert (J43: Gimap (GUI p) (GLR_prems (nodupseq x)) (map (UI p) (GLR_prems (nodupseq x)))).
+           apply Gimap_map ; auto. intros ; apply UI_GUI ; auto.
+           epose (@GN_inv_noinit_nolessub _ _ _ _ _ g0 H3 J42 J43). rewrite <- e1 ; auto.
+           epose (Id_all_form _ [] _ []). simpl in d ; apply d. }
+
+        epose (@GLS_prv_list_wkn_R _ _ _). rewrite app_nil_r in g ; simpl in g. pose (g J100 [Bot]). simpl in g0.
+        epose (@GLS_prv_list_wkn_L [_] _ _). rewrite app_nil_r in g1 ; simpl in g1. epose (g1 g0 _).
+        simpl in g2 ; rewrite app_nil_r in g2. apply g2.
+  (* Sequents are not critical. *)
+  - assert (J0: GUI p s (UI p s)). apply UI_GUI ; auto. assert (J00: GUI p (nodupseq s) (UI p (nodupseq s))). apply UI_GUI ; auto.
+    assert (J1: Gimap (GUI p) (Canopy (nodupseq s)) (map (UI p) (Canopy (nodupseq s)))). apply Gimap_map. intros.
+    apply UI_GUI ; auto.
+    assert (J10: Gimap (GUI p) (Canopy (nodupseq (nodupseq s))) (map (UI p) (Canopy (nodupseq (nodupseq s))))). apply Gimap_map. intros.
+    apply UI_GUI ; auto.
+    pose (@GUI_inv_not_critic p s _ _ J0 f J1). rewrite <- e ; clear e.
+    assert (critical_Seq (nodupseq s) -> False). intro. apply f. apply critical_nodupseq ; auto.
+    pose (@GUI_inv_not_critic p (nodupseq s) _ _ J00 H J10). rewrite <- e ; clear e.
+    rewrite <- fixpoint_nodupseq.
+    epose (Id_all_form _ [] _ []). simpl in d ; apply d. }
+Qed.
+ +
+  Lemma UI_nodupseq_converse : forall s p X Y, GLS_prv (UI p s :: X, UI p (nodupseq s) :: Y).
+  Proof.
+  pose (d:=LexSeq_ind (fun (s:Seq) => forall p X Y, GLS_prv (UI p s :: X, UI p (nodupseq s) :: Y))).
+  apply d. clear d. intros s IH p X Y.
+  destruct (empty_seq_dec s) as [EE | DE].
+  { subst. unfold nodupseq. simpl. assert (J0: GUI p ([],[]) Bot). apply GUI_empty_seq ; auto. apply UI_GUI in J0.
+     rewrite J0 in *. apply derI with []. apply BotL ; apply (BotLRule_I []). apply dlNil. }
+  { destruct (critical_Seq_dec s).
+  (* Sequents are critical. *)
+  - assert (critical_Seq (nodupseq s)). apply (critical_nodupseq s) ; auto.
+    destruct (dec_init_rules s).
+    (* Sequents are initial. *)
+    * assert (is_init s) ; auto. assert (is_init (nodupseq s)). apply (is_init_nodupseq s) ; auto.
+      assert (J0: GUI p (nodupseq s) (UI p (nodupseq s))). apply UI_GUI ; auto.
+      pose (@GUI_inv_critic_init p (nodupseq s) _ J0 H X1). rewrite <- e. epose (TopR _ [] _). simpl in g ; apply g.
+    (* Sequents are not initial. *)
+    * assert ((is_init s) -> False) ; auto. assert ((is_init (nodupseq s)) -> False). intro. apply H0.
+      apply (is_init_nodupseq s) ; auto.
+      assert (J0: GUI p s (UI p s)). apply UI_GUI ; auto.
+      assert (J00: GUI p (nodupseq s) (UI p (nodupseq s))). apply UI_GUI ; auto.
+      assert (J1: Gimap (GUI p) (GLR_prems (nodupseq s)) (map (UI p) (GLR_prems (nodupseq s)))). apply Gimap_map. intros.
+      apply UI_GUI ; auto.
+      assert (J10: Gimap (GUI p) (GLR_prems (nodupseq (nodupseq s))) (map (UI p) (GLR_prems (nodupseq (nodupseq s))))). apply Gimap_map. intros.
+      apply UI_GUI ; auto.
+      assert (J2: (Gimap (GN p (GUI p) s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), [])))
+      (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), [])))))). apply Gimap_map. intros.
+      apply (N_spec p s x).
+      assert (J20: (Gimap (GN p (GUI p) (nodupseq s)) (Canopy (nodupseq (XBoxed_list (top_boxes (fst (nodupseq s))), [])))
+      (map (N p (nodupseq s)) (Canopy (nodupseq (XBoxed_list (top_boxes (fst (nodupseq s))), [])))))). apply Gimap_map. intros.
+      apply (N_spec p (nodupseq s) x).
+      assert (J41: (nodupseq s) <> ([],[])). intro. apply DE. destruct s. simpl in *. unfold nodupseq in *. simpl in H2. inversion H2 ; subst.
+      apply nodup_nil in H4 ; rewrite H4 in H5 ; apply nodup_nil in H5 ; subst ; auto.
+       pose (@GUI_inv_critic_not_init p s _ _ _ J0 c DE H0 J1 J2). rewrite <- e ; clear e.
+       pose (@GUI_inv_critic_not_init p (nodupseq s) _ _ _ J00 H J41 H1 J10 J20). rewrite <- e ; clear e.
+       repeat rewrite <- fixpoint_nodupseq.
+        epose (OrR (_,_)). simpl in g. apply g ; clear g.
+        epose (OrL (_,_)). simpl in g. apply g ; clear g.
+        epose (list_disj_L _ (_,_)). apply g ; clear g. simpl ; intros.
+        epose (restr_list_prop_nodup (snd s) A p). apply p0 in H2.
+        epose (list_disj_wkn_R _ (_,_) _ H2). simpl in g. apply g ; clear g.
+        epose (Id_all_form _ [] _ []). simpl in d ; apply d.
+        eapply GLS_prv_wkn_R with (s:=((Or (list_disj (map Neg (restr_list_prop p (fst s)))) (Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq s)))))
+        (Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))))))) :: X, Or (list_disj (map Neg (restr_list_prop p (fst (nodupseq s)))))
+        (Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq s))))) (Diam (list_conj (map (N p (nodupseq s)) (Canopy (nodupseq (XBoxed_list (top_boxes (fst (nodupseq s))), []%list))))))) :: Y)) (A:=list_disj (restr_list_prop p (snd (nodupseq s)))).
+        2: epose (wkn_RI (list_disj (restr_list_prop p (snd (nodupseq s)))) _ [] _) ; simpl in w ; apply w.
+        epose (OrR (_,_)). simpl in g. apply g ; clear g.
+        epose (OrL (_,_)). simpl in g. apply g ; clear g.
+        epose (list_disj_L _ (_,_)). apply g ; clear g. simpl ; intros.
+        apply InT_map_iff in H2. destruct H2. destruct p0 ; subst.
+        epose (restr_list_prop_nodup (fst s) x p). apply p0 in i.
+        epose (list_disj_wkn_R _ (_,_) _). simpl in g. apply g ; clear g. apply InT_map_iff. exists x ; split ; auto.
+        epose (Id_all_form _ [] _ []). simpl in d ; apply d.
+        eapply GLS_prv_wkn_R with (s:=((Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq s))))) (Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))))) :: X,
+        (Or (list_disj (map Box (map (UI p) (GLR_prems (nodupseq s)))))
+        (Diam (list_conj (map (N p (nodupseq s)) (Canopy (nodupseq (XBoxed_list (top_boxes (fst (nodupseq s))), []%list))))))) :: Y)) (A:=list_disj (map Neg (restr_list_prop p (fst (nodupseq s))))).
+        2: epose (wkn_RI (list_disj (map Neg (restr_list_prop p (fst (nodupseq s))))) _ [] _) ; simpl in w ; apply w.
+        epose (OrR (_,_)). simpl in g. apply g ; clear g.
+        epose (OrL (_,_)). simpl in g. apply g ; clear g.
+        epose (list_disj_L _ (_,_)). apply g ; clear g. simpl ; intros. apply InT_map_iff in H2.
+        destruct H2. destruct p0 ; subst. apply InT_map_iff in i. destruct i. destruct p0 ; subst.
+        epose (list_disj_wkn_R _ (_,_) (Box (UI p x0))). simpl in g. apply g ; clear g.
+        apply InT_map_iff. exists (UI p x0). split ; auto. apply InT_map_iff. exists x0 ; split ; auto.
+        epose (Id_all_form _ [] _ []). simpl in d ; apply d.
+        eapply GLS_prv_wkn_R with (s:=((Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))))) :: X,
+        Diam (list_conj (map (N p (nodupseq s)) (Canopy (nodupseq (XBoxed_list (top_boxes (fst (nodupseq s))), []%list))))) :: Y)) (A:=list_disj (map Box (map (UI p) (GLR_prems (nodupseq s))))).
+        2: epose (wkn_RI (list_disj (map Box (map (UI p) (GLR_prems (nodupseq s))))) _ [] _) ; simpl in w ; apply w.
+        remember (list_conj (map (N p (nodupseq s)) (Canopy (nodupseq (XBoxed_list (top_boxes (fst (nodupseq s))), []%list))))) as conjR.
+        remember (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) as conjL.
+        apply derI with (ps:=[(Box (Neg conjR) :: Diam conjL :: X, Bot :: Y)]). apply ImpR. epose (ImpRRule_I _ _ [] _ [] _). simpl in i ; apply i.
+        apply dlCons. 2: apply dlNil.
+        apply derI with (ps:=[(Box (Neg conjR) :: X, Box (Neg conjL) :: :: Y);(Box (Neg conjR) :: :: X, :: Y)]).
+        apply ImpL. epose (ImpLRule_I _ _ [_] _ [] _). simpl in i. apply i. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+        2: apply derI with (ps:=[]) ; [ apply BotL ; epose (BotLRule_I [_] _) ; simpl in b ; auto | apply dlNil].
+        apply derI with (ps:=[(Neg conjR :: Box (Neg conjR) :: XBoxed_list (top_boxes X) ++ [Box (Neg conjL)], [Neg conjL])]). apply GLR.
+        epose (@GLRRule_I _ (Box (Neg conjR) :: (top_boxes X)) _ [] _). simpl in g ; apply g ; clear g ; auto. intros A HA. inversion HA ; subst.
+        eexists ; auto. apply in_top_boxes in H2. destruct H2. destruct s0. destruct s0. destruct p0 ; subst. eexists ; auto.
+        apply univ_gen_ext_cons. apply nobox_top_boxes. apply dlCons. 2: apply dlNil.
+        apply derI with (ps:=[(conjL :: Neg conjR :: Box (Neg conjR) :: XBoxed_list (top_boxes X) ++ [Box (Neg conjL)], [Bot])]). apply ImpR. epose (ImpRRule_I _ _ [] _ [] []). simpl in i ; apply i.
+        apply dlCons. 2: apply dlNil.
+        apply derI with (ps:=[(conjL :: Box (Neg conjR) :: XBoxed_list (top_boxes X) ++ [Box (Neg conjL)], [conjR;]);(conjL :: Bot :: Box (Neg conjR) :: XBoxed_list (top_boxes X) ++ [Box (Neg conjL)], [])]).
+        apply ImpL. epose (ImpLRule_I _ _ [_] _ [] [_]). simpl in i. apply i. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+        2: apply derI with (ps:=[]) ; [ apply BotL ; epose (BotLRule_I [_] _) ; simpl in b ; auto | apply dlNil].
+        remember (Box (Neg conjR) :: XBoxed_list (top_boxes X) ++ [Box (Neg conjL)]) as LHS0. rewrite HeqconjL. rewrite HeqconjR.
+        epose (list_conj_R _ (_,_)). apply g ; clear g. simpl ; intros. apply InT_map_iff in H2.
+        destruct H2. destruct p0 ; subst.
+        assert (J70: (nodupseq (XBoxed_list (top_boxes (nodup eq_dec_form (fst s))), []%list)) = (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))).
+        unfold nodupseq ; simpl. rewrite <- nodup_top_boxes. rewrite nodup_XBoxed_list ; auto. rewrite <- J70.
+        epose (list_conj_wkn_L _ (_,_) (N p s x)). simpl in g. apply g ; clear g.
+        apply InT_map_iff. exists x ; split ; auto.
+ +
+        assert (J100: GLS_prv ([N p s x], [N p (nodupseq s) x])).
+        { (* Massage the Ns. *)
+          assert ((forall (x : Seq) (l m : MPropF), (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x l -> (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x m -> l = m)).
+          intros. subst. auto.
+          destruct (dec_init_rules x).
+          (* The sequent x is initial. *)
+           assert (is_init x) ; auto.
+           pose (N_spec p (nodupseq s) x).
+           pose (GN_inv_init _ g). rewrite <- e ; auto.
+           epose (TopR _ [] []). simpl in g0 ; apply g0.
+          (* The sequent x is not initial. *)
+           assert (is_init x -> False) ; auto.
+           assert (J300: GUI p x (UI p x)). apply UI_GUI ; auto.
+           pose (Canopy_critical _ _ i).
+           pose (ub_nodupseq s).
+           destruct (Compare_dec.lt_dec (length (usable_boxes x)) (length (usable_boxes s))).
+           (* The sequent x0 has less usable boxes than s. *)
+           pose (N_spec p s x).
+           epose (@GN_inv_noinit_lessub _ _ _ _ _ g H3 l J300). rewrite <- e0 ; auto.
+           assert (J500: length (usable_boxes x) < length (usable_boxes (nodupseq s))). lia.
+           pose (N_spec p (nodupseq s) x).
+           epose (@GN_inv_noinit_lessub _ _ _ _ _ g0 H3 J500 J300). rewrite <- e1 ; auto.
+           epose (Id_all_form _ [] _ []). simpl in d ; apply d.
+           (* The sequent x does not have less usable boxes than s. *)
+           pose (N_spec p s x).
+           assert (J410: Gimap (GUI p) (GLR_prems (nodupseq x)) (map (UI p) (GLR_prems (nodupseq x)))).
+           apply Gimap_map ; auto. intros ; apply UI_GUI ; auto.
+           epose (@GN_inv_noinit_nolessub _ _ _ _ _ g H3 n J410). rewrite <- e0 ; auto.
+           assert (J42: (length (usable_boxes x) < length (usable_boxes (nodupseq s))) -> False). lia.
+           pose (N_spec p (nodupseq s) x).
+           assert (J43: Gimap (GUI p) (GLR_prems (nodupseq x)) (map (UI p) (GLR_prems (nodupseq x)))).
+           apply Gimap_map ; auto. intros ; apply UI_GUI ; auto.
+           epose (@GN_inv_noinit_nolessub _ _ _ _ _ g0 H3 J42 J43). rewrite <- e1 ; auto.
+           epose (Id_all_form _ [] _ []). simpl in d ; apply d. }
+
+        epose (@GLS_prv_list_wkn_R _ _ _). rewrite app_nil_r in g ; simpl in g. pose (g J100 [Bot]). simpl in g0.
+        epose (@GLS_prv_list_wkn_L [_] _ _). rewrite app_nil_r in g1 ; simpl in g1. epose (g1 g0 _).
+        simpl in g2 ; rewrite app_nil_r in g2. apply g2.
+  (* Sequents are not critical. *)
+  - assert (J0: GUI p s (UI p s)). apply UI_GUI ; auto. assert (J00: GUI p (nodupseq s) (UI p (nodupseq s))). apply UI_GUI ; auto.
+    assert (J1: Gimap (GUI p) (Canopy (nodupseq s)) (map (UI p) (Canopy (nodupseq s)))). apply Gimap_map. intros.
+    apply UI_GUI ; auto.
+    assert (J10: Gimap (GUI p) (Canopy (nodupseq (nodupseq s))) (map (UI p) (Canopy (nodupseq (nodupseq s))))). apply Gimap_map. intros.
+    apply UI_GUI ; auto.
+    pose (@GUI_inv_not_critic p s _ _ J0 f J1). rewrite <- e ; clear e.
+    assert (critical_Seq (nodupseq s) -> False). intro. apply f. apply critical_nodupseq ; auto.
+    pose (@GUI_inv_not_critic p (nodupseq s) _ _ J00 H J10). rewrite <- e ; clear e.
+    rewrite <- fixpoint_nodupseq.
+    epose (Id_all_form _ [] _ []). simpl in d ; apply d. }
+  Qed.
+ +
+  Lemma UI_nodupseq_gen : forall s0 s1 p X Y, (nodupseq s0 = nodupseq s1) -> GLS_prv (UI p s0 :: X, UI p s1 :: Y).
+  Proof.
+  intros.
+  pose (UI_nodupseq s1 p X Y).
+  pose (UI_nodupseq_converse s0 p X Y). rewrite H in *.
+  pose (GLS_cut_adm (UI p (nodupseq s1)) [] (UI p s0 :: X) [] (UI p s1 :: Y)). simpl in g1. apply g1 ; auto.
+  eapply GLS_prv_wkn_R with (s:=(UI p s0 :: X, UI p (nodupseq s1) :: Y)) (A:=UI p s1) ; auto.
+  epose (wkn_RI (UI p s1) _ [_] _) ; simpl in w ; apply w.
+  eapply GLS_prv_wkn_L with (s:=(UI p (nodupseq s1) :: X, UI p s1 :: Y)) (A:=UI p s0) ; auto.
+  epose (wkn_LI (UI p s0) [_] _ _) ; simpl in w ; apply w.
+  Qed.
+ +
+  Lemma N_nodupseq : forall s0 s1 p X Y, critical_Seq s1 -> GLS_prv (N p s0 s1 :: X, N p s0 (nodupseq s1) :: Y).
+  Proof.
+  intros s0 s1. revert s0. revert s1.
+  pose (d:=LexSeq_ind (fun (s:Seq) => forall s0 p X Y, critical_Seq s -> GLS_prv (N p s0 s :: X, N p s0 (nodupseq s) :: Y))).
+  apply d. clear d. intros s1 IH s0 p X Y crit.
+  assert ((forall (x : Seq) (l m : MPropF), (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x l -> (fun (s1 : Seq) (A : MPropF) => UI p s1 = A) x m -> l = m)).
+  intros. subst. auto.
+  destruct (dec_init_rules s1).
+  (* The sequent s1 is initial. *)
+   - assert (is_init s1) ; auto. assert (is_init (nodupseq s1)). apply is_init_nodupseq in X0; auto.
+     pose (N_spec p s0 (nodupseq s1)).
+     pose (GN_inv_init _ g). rewrite <- e ; auto.
+     epose (TopR _ [] _). simpl in g0 ; apply g0.
+  (* The sequent s1 is not initial. *)
+   - assert (is_init s1 -> False) ; auto. assert (is_init (nodupseq s1) -> False). intro ; apply H0 ; apply is_init_nodupseq ; auto.
+     assert (J300: GUI p s1 (UI p s1)). apply UI_GUI ; auto.
+     assert (J400: GUI p (nodupseq s1) (UI p (nodupseq s1))). apply UI_GUI ; auto.
+     assert (critical_Seq (nodupseq s1)). apply (critical_nodupseq s1) ; auto.
+     pose (ub_nodupseq s1).
+     destruct (Compare_dec.lt_dec (length (usable_boxes s1)) (length (usable_boxes s0))).
+     (* The sequent x0 has less usable boxes than s. *)
+     * pose (N_spec p s0 s1).
+       epose (@GN_inv_noinit_lessub _ _ _ _ _ g H0 l J300). rewrite <- e0 ; auto.
+       assert (J500: length (usable_boxes (nodupseq s1)) < length (usable_boxes s0)). rewrite <- ub_nodupseq ; auto.
+       pose (N_spec p s0 (nodupseq s1)).
+       epose (@GN_inv_noinit_lessub _ _ _ _ _ g0 H1 J500 J400). rewrite <- e1 ; auto.
+       apply UI_nodupseq_converse.
+     (* The sequent x does not have less usable boxes than s. *)
+     * pose (N_spec p s0 s1).
+       assert (J410: Gimap (GUI p) (GLR_prems (nodupseq s1)) (map (UI p) (GLR_prems (nodupseq s1)))).
+       apply Gimap_map ; auto. intros ; apply UI_GUI ; auto.
+       epose (@GN_inv_noinit_nolessub _ _ _ _ _ g H0 n J410). rewrite <- e0 ; auto.
+       assert (J42: (length (usable_boxes (nodupseq s1)) < length (usable_boxes s0)) -> False). rewrite <- ub_nodupseq ; auto.
+       pose (N_spec p s0 (nodupseq s1)).
+       assert (J43: Gimap (GUI p) (GLR_prems (nodupseq (nodupseq s1))) (map (UI p) (GLR_prems (nodupseq (nodupseq s1))))).
+       apply Gimap_map ; auto. intros ; apply UI_GUI ; auto.
+       epose (@GN_inv_noinit_nolessub _ _ _ _ _ g0 H1 J42 J43). rewrite <- e1 ; auto.
+       repeat rewrite <- fixpoint_nodupseq.
+       epose (OrR (_,_)). simpl in g1. apply g1 ; clear g1.
+       epose (OrL (_,_)). simpl in g1. apply g1 ; clear g1.
+       epose (list_disj_L _ (_,_)). apply g1 ; clear g1. simpl ; intros.
+       epose (restr_list_prop_nodup (snd s1) A p). apply p0 in H3 ; clear p0.
+       epose (list_disj_wkn_R _ (_,_) _ H3). simpl in g1. apply g1 ; clear g1.
+       epose (Id_all_form _ [] _ []). simpl in d ; apply d.
+       eapply GLS_prv_wkn_R with (s:=(Or (list_disj (map Neg (restr_list_prop p (fst s1)))) (list_disj (map Box (map (UI p) (GLR_prems (nodupseq s1))))) :: X,
+       Or (list_disj (map Neg (restr_list_prop p (fst (nodupseq s1))))) (list_disj (map Box (map (UI p) (GLR_prems (nodupseq s1))))) :: Y)) (A:=list_disj (restr_list_prop p (snd (nodupseq s1)))).
+       2: epose (wkn_RI (list_disj (restr_list_prop p (snd (nodupseq s1)))) _ [] _) ; simpl in w ; apply w.
+       epose (OrR (_,_)). simpl in g1. apply g1 ; clear g1.
+       epose (OrL (_,_)). simpl in g1. apply g1 ; clear g1.
+       epose (list_disj_L _ (_,_)). apply g1 ; clear g1. simpl ; intros.
+       apply InT_map_iff in H3. destruct H3. destruct p0 ; subst.
+       epose (restr_list_prop_nodup (fst s1) x p). apply p0 in i ; clear p0.
+       epose (list_disj_wkn_R _ (_,_) _). simpl in g1. apply g1 ; clear g1. apply InT_map_iff. exists x ; split ; auto.
+       epose (Id_all_form _ [] _ []). simpl in d ; apply d.
+       eapply GLS_prv_wkn_R with (s:=(list_disj (map Box (map (UI p) (GLR_prems (nodupseq s1)))) :: X,
+       list_disj (map Box (map (UI p) (GLR_prems (nodupseq s1)))) :: Y)) (A:=list_disj (map Neg (restr_list_prop p (fst (nodupseq s1))))).
+       2: epose (wkn_RI (list_disj (map Neg (restr_list_prop p (fst (nodupseq s1))))) _ [] _) ; simpl in w ; apply w.
+       epose (Id_all_form _ [] _ []). simpl in d ; apply d.
+  Qed.
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_UI_prelims.html b/GL.Interpolation.UIGL_UI_prelims.html new file mode 100644 index 0000000..53d94fe --- /dev/null +++ b/GL.Interpolation.UIGL_UI_prelims.html @@ -0,0 +1,767 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_UI_prelims

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat.
+Require Import Lia.
+Require Import String.
+ +
+Require Import general_export.
+ +
+Require Import GLS_export.
+ +
+Require Import UIGL_Def_measure.
+Require Import UIGL_Canopy.
+Require Import UIGL_irred_short.
+Require Import UIGL_braga.
+Require Import UIGL_LexSeq.
+Require Import UIGL_nodupseq.
+Require Import UIGL_PermutationT.
+Require Import UIGL_PermutationTS.
+Require Import UIGL_And_Or_rules.
+Require Import UIGL_Canopy_nodupseq_perm.
+ +
+  Section Prop_Subform.
+ +
+  (* This is copied from the Craig interpolation file. Make a syntax file for interpolations. *)
+ +
+  Fixpoint propvar_subform (A : MPropF) : list MPropF :=
+  match A with
+    | Var p => (Var p) :: nil
+    | Bot => nil
+    | Imp B C => (propvar_subform B) ++ ( propvar_subform C)
+    | Box B => ( propvar_subform B)
+  end.
+ +
+  Fixpoint propvar_subform_list (l : list MPropF) : list MPropF :=
+  match l with
+    | nil => nil
+    | A :: t => (propvar_subform A) ++ (propvar_subform_list t)
+  end.
+ +
+  (* Lemmas about propvar_subform_list. *)
+ +
+  Lemma propvar_subform_list_app: forall l0 l1,
+        propvar_subform_list (l0 ++ l1) = (propvar_subform_list l0) ++ (propvar_subform_list l1).
+  Proof.
+  induction l0.
+  - simpl. auto.
+  - intros. simpl. rewrite (IHl0). rewrite <- app_assoc ; auto.
+  Qed.
+ +
+  Lemma propvar_subform_list_XBoxed_list : forall l A, In A (propvar_subform_list (XBoxed_list l)) -> In A (propvar_subform_list l).
+  Proof.
+  induction l.
+  - auto.
+  - simpl. intros. apply in_app_or in H. destruct H. apply in_or_app ; left. destruct a ; auto.
+    apply in_app_or in H. destruct H. apply in_or_app ; auto. apply in_or_app ; right ; auto.
+  Qed.
+ +
+  Lemma propvar_subform_list_nobox_gen_ext : forall l0 l1, nobox_gen_ext l0 l1 ->
+            (forall A, In A (propvar_subform_list l0) -> In A (propvar_subform_list l1)).
+  Proof.
+  intros l0 l1 H. induction H ; auto.
+  - simpl ; intros. apply in_or_app. apply in_app_or in H0 ; destruct H0 ; auto.
+  - simpl ; intros. apply in_or_app ; auto.
+  Qed.
+ +
+  Lemma propvar_subform_list_top_boxes : forall l A, In A (propvar_subform_list (top_boxes l)) -> In A (propvar_subform_list l).
+  Proof.
+  induction l ; simpl ; intros ; auto. destruct a ; simpl in H ; auto. 1-2: apply in_or_app ; apply IHl in H ; auto.
+  apply in_or_app ; apply in_app_or in H ; destruct H ; simpl ; auto.
+  Qed.
+ +
+  Lemma propvar_subform_list_conj : forall l A,
+            In A (propvar_subform (list_conj l)) -> In A (propvar_subform_list l).
+  Proof.
+  induction l ; simpl ; intros ; auto. repeat rewrite app_nil_r in H.
+  apply in_app_or in H. apply in_or_app. destruct H ; auto.
+  Qed.
+ +
+  Lemma propvar_subform_list_disj : forall l A,
+            In A (propvar_subform (list_disj l)) -> In A (propvar_subform_list l).
+  Proof.
+  induction l ; simpl ; intros ; auto. repeat rewrite app_nil_r in H.
+  apply in_app_or in H. apply in_or_app. destruct H ; auto.
+  Qed.
+ +
+  Lemma propvar_subform_list_witness : forall l A,
+            In A (propvar_subform_list l) -> (exists B, In B l /\ In A (propvar_subform B)).
+  Proof.
+  induction l ; simpl ; intros ; auto. inversion H. apply in_app_or in H. destruct H.
+  exists a ; auto. apply IHl in H. destruct H. exists x ; firstorder.
+  Qed.
+ +
+  Lemma propvar_subform_list_witnessT : forall l A,
+            InT A (propvar_subform_list l) -> (existsT2 B, (InT B l) * (InT A (propvar_subform B))).
+  Proof.
+  induction l ; simpl ; intros ; auto. inversion H. apply InT_app_or in H. destruct H.
+  exists a ; auto. split ; auto. apply InT_eq. apply IHl in i. destruct i. exists x ; firstorder. apply InT_cons ; auto.
+  Qed.
+ +
+  Lemma propvar_subform_list_Canopy : forall s ir A,
+            In ir (Canopy s) ->
+            In A (propvar_subform_list (fst ir ++ snd ir)) ->
+            In A (propvar_subform_list (fst s ++ snd s)).
+  Proof.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  intros. remember (finite_ImpRules_premises_of_S s) as H1.
+  destruct H1. destruct x.
+  - assert (Canopy s = [s]). apply irred_nil. unfold inv_prems. rewrite <- HeqH1.
+    simpl. auto. rewrite H1 in H. inversion H. subst. auto. inversion H2.
+  - apply In_InT_seqs in H. apply fold_Canopy in H. destruct H ; subst ; auto.
+    destruct s0. destruct p0. unfold inv_prems in i. destruct (finite_ImpRules_premises_of_S s).
+    simpl in i. apply InT_flatten_list_InT_elem in i. destruct i. destruct p1. apply p0 in i1.
+    apply IHs with (y:=x0) in H0. 3: apply InT_In ; auto.
+    destruct i1. inversion i1 ; subst. simpl. inversion i ; subst. 2: inversion H1. simpl in H0.
+    repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
+    repeat rewrite propvar_subform_list_app in H0. repeat rewrite propvar_subform_list_app.
+    simpl in H0. simpl. repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
+    apply in_or_app. apply in_app_or in H0 ; destruct H0 ; auto. right. apply in_or_app.
+    apply in_app_or in H ; destruct H ; auto. right ; apply in_or_app ; right ; apply in_or_app ; auto.
+    apply in_app_or in H ; destruct H ; auto. right. apply in_or_app ; apply in_app_or in H ; destruct H ; auto.
+    right ; apply in_or_app ; right ; auto.
+    inversion i1 ; subst. simpl. inversion i ; subst. simpl in H0.
+    repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
+    repeat rewrite propvar_subform_list_app in H0. repeat rewrite propvar_subform_list_app.
+    simpl in H0. simpl. repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
+    apply in_or_app. apply in_app_or in H0 ; destruct H0 ; auto. right. apply in_or_app.
+    apply in_app_or in H ; destruct H ; auto. right ; apply in_or_app ; right ; apply in_or_app ; auto.
+    apply in_app_or in H ; destruct H ; auto. right. apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+    apply in_app_or in H ; destruct H ; auto. right ; apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+    inversion H1 ; subst. 2: inversion H2. simpl in H0.
+    repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
+    repeat rewrite propvar_subform_list_app in H0. repeat rewrite propvar_subform_list_app.
+    simpl in H0. simpl. repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
+    apply in_or_app. apply in_app_or in H0 ; destruct H0 ; auto. right. apply in_or_app.
+    apply in_app_or in H ; destruct H ; auto. right ; apply in_or_app ; auto.
+    apply in_app_or in H ; destruct H ; auto. right. apply in_or_app ; right ; apply in_or_app ; auto.
+    right ; apply in_or_app ; right ; apply in_or_app ; right ; auto.
+    destruct i1. inversion i1 ; subst. simpl. inversion i ; subst. 2: inversion H1. unfold n_imp_subformS ; simpl.
+    repeat rewrite n_imp_subformLF_dist_app ; simpl ; repeat rewrite n_imp_subformLF_dist_app. lia.
+    inversion i1. subst. inversion i ; subst. unfold n_imp_subformS ; simpl.
+    repeat rewrite n_imp_subformLF_dist_app ; simpl ; repeat rewrite n_imp_subformLF_dist_app. lia.
+    inversion H1. subst. 2: inversion H2. unfold n_imp_subformS ; simpl.
+    repeat rewrite n_imp_subformLF_dist_app ; simpl ; repeat rewrite n_imp_subformLF_dist_app. lia.
+  Qed.
+ +
+  Lemma propvar_subform_list_restr_list_prop : forall l (p q : string), In # q (propvar_subform_list (restr_list_prop p l)) ->
+                        ((q <> p) * (In # q (propvar_subform_list l))).
+  Proof.
+  induction l ; simpl ; intros ; auto. unfold restr_list_prop in H. destruct a as [n | | |]; simpl ; simpl in H ; auto.
+  destruct (eq_dec_form (# p) (# n)) ; subst. apply IHl in H. destruct H ; auto.
+  simpl in H. destruct H ; subst ; auto. split ; auto. rewrite H in n0. destruct (string_dec p q) ; subst; auto.
+  all: apply IHl in H ; destruct H ; auto.
+  all: split ; auto. all: apply in_or_app ; auto.
Qed.
+ +
+  Lemma In_list_prop_LF: forall l A, In A (list_prop_LF l) -> ((existsT2 q, A = # q) * In A l).
+  Proof.
+  induction l ; simpl ; intros ; auto. inversion H. apply In_InT in H. apply InT_app_or in H.
+  destruct H. destruct a as [n | | |]; simpl in i ; inversion i ; subst ; auto. split ; [exists n ; auto | auto]. inversion H0.
+  apply InT_In in i ; apply IHl in i ; auto. destruct i ; split ; auto.
+  Qed.
+ +
+  Lemma list_prop_LF_propvar_subform_list : forall l q, In # q (list_prop_LF l) -> In # q (propvar_subform_list l).
+  Proof.
+  induction l ; simpl ; intros ; auto. apply in_app_or in H ; destruct H ; auto. apply in_or_app ; left. destruct a ; simpl ; simpl in H ; try firstorder.
+  apply in_or_app ; right ; apply IHl in H ; auto.
+  Qed.
+ +
+  Lemma In_list_In_list_prop_LF : forall l P, In # P l -> In # P (list_prop_LF l).
+  Proof.
+  induction l ; simpl ; subst ; auto. intros. destruct H. subst ; simpl ; auto. apply in_or_app; right ; auto.
+  Qed.
+ +
+  Lemma In_list_In_propvar_subform_list : forall l P, In # P l -> In # P (propvar_subform_list l).
+  Proof.
+  induction l ; simpl ; subst ; auto. intros. destruct H. subst ; simpl ; auto. apply in_or_app; right ; auto.
+  Qed.
+ +
+  End Prop_Subform.
+ +
+  Section Diam_help.
+ +
+  Lemma In_subform_boxes:
+  forall (l : list MPropF) (A : MPropF), In A (subform_boxesLF l) -> exists B : MPropF, In A (subform_boxesF B) /\ In B l.
+  Proof.
+  induction l ; simpl ; intros ; auto. inversion H. apply in_app_or in H. destruct H. pose (In_subform_boxesF_box _ _ H).
+  unfold is_boxedT in i. destruct i. subst. exists a ; auto. apply In_remove_list_In_list in H. apply IHl in H. firstorder.
+  Qed.
+ +
+  Lemma nolessub_In : forall s A, (length (usable_boxes (XBoxed_list (top_boxes (fst s)), []%list)) < length (usable_boxes s) -> False) ->
+                                      (In (Box A) (top_boxes (XBoxed_list (top_boxes (fst s))))) -> In (Box A) (top_boxes (fst s)).
+  Proof.
+  intros. apply InT_In. pose (InT_dec (top_boxes (fst s)) (Box A)). destruct s0 ; auto. exfalso. apply H. destruct s.
+  simpl. simpl in f. simpl in H0. simpl in H. unfold usable_boxes. simpl. unfold subform_boxesS. simpl.
+  apply remove_list_incr_decr ; simpl. apply add_remove_list_preserve_NoDup. 2: apply NoDup_nil.
+  apply NoDup_subform_boxesLF. apply add_remove_list_preserve_NoDup. 1-2: apply NoDup_subform_boxesLF.
+  exists (Box A). repeat split ; auto.
+  apply in_or_app ; left. apply XBoxed_list_same_subform_boxes. apply top_boxes_incl_list in H0.
+  apply In_XBoxed_list in H0. destruct H0. apply In_incl_subform_boxes with (A:=Box A) ; auto. exfalso. apply f ; apply In_InT ; auto.
+  simpl ; auto. destruct H0. destruct H0. subst. apply XBoxed_list_same_subform_boxes. apply top_boxes_incl_list in H0.
+  apply In_incl_subform_boxes with (A:=(Box (Box A))) ; simpl ; auto.
+  intro ; apply f ; apply In_InT ; auto. intro. intros. pose (in_top_boxes _ _ H1). destruct s. destruct s.
+  destruct s. destruct p ; subst. rewrite top_boxes_distr_app. simpl. rewrite XBox_app_distrib. simpl.
+  rewrite top_boxes_distr_app. simpl. destruct x ; simpl. 1-3: apply in_or_app ; right ; apply in_eq.
+  apply in_or_app ; right ; apply in_cons ; apply in_eq.
+  intro. intros. apply in_app_or in H1. destruct H1. apply in_or_app. left.
+  pose (XBoxed_list_same_subform_boxes (top_boxes l)). apply a0 in H1. apply In_subform_boxes in H1. destruct H1.
+  destruct H1. apply In_incl_subform_boxes with (A:=x). apply top_boxes_incl_list ; auto. auto.
+  apply remove_list_is_in. rewrite remove_list_of_nil in H1. inversion H1.
Qed.
+ +
+  Lemma remove_list_decr_in: forall [l2 l1 l3 l4: list MPropF], NoDup l4 -> NoDup l3 ->
+    incl l1 l2 -> incl l3 l4 -> length (remove_list l2 l4) < length (remove_list l1 l3) ->
+    (exists A : MPropF, In A l2 /\ (In A l1 -> False)).
+  Proof.
+  induction l2 ; simpl.
+  - intros. destruct l1. simpl. simpl in H3. exfalso. pose (NoDup_incl_length H0 H2). simpl in l. lia.
+    exfalso. pose (H1 m). simpl in i ; apply i ; auto.
+  - intros. destruct (In_dec l2 a).
+    + assert (incl l1 l2). intro. intros. apply H1 in H4. inversion H4 ; subst ; auto.
+       pose (In_remove_list_remove_redund _ l4 _ i). rewrite e in H3.
+       pose (IHl2 _ _ _ H H0 H4 H2 H3). destruct e0. destruct H5. exists x ; split ; auto.
+    + destruct (In_dec l1 a).
+        * destruct (In_dec l4 a).
+          -- destruct (In_dec l3 a).
+            ++ assert (incl (remove eq_dec_form a l1) l2). intro. intros. apply in_remove in H4. destruct H4.
+                 apply H1 in H4. inversion H4 ; subst ; auto. exfalso ; apply H5 ; auto.
+                 assert ((remove_list l1 l3) = (remove_list (remove eq_dec_form a l1) (remove eq_dec_form a l3))).
+                 rewrite <- In_remove_list_remove_redund with (a:=a). rewrite permut_remove_remove_list.
+                 pose (permut_remove_remove_list a (remove eq_dec_form a l1) l3). rewrite <- e.
+                 pose (redund_remove_remove_list a l1 l3). rewrite e0. rewrite permut_remove_remove_list. auto. auto.
+                 assert (J0: NoDup (remove eq_dec_form a l4)). apply remove_preserv_NoDup ; auto.
+                 assert (J1: NoDup (remove eq_dec_form a l3)). apply remove_preserv_NoDup ; auto.
+                 assert (J2: incl (remove eq_dec_form a l3) (remove eq_dec_form a l4)). intro. intros.
+                 apply in_remove in H6. destruct H6. apply in_in_remove ; auto.
+                 rewrite H5 in H3. rewrite permut_remove_remove_list in H3.
+                 pose (IHl2 (remove eq_dec_form a l1) _ _ J0 J1 H4 J2 H3). destruct e. destruct H6.
+                 exists x ; split ; auto. intro. apply H7. apply in_in_remove ; auto. intro ; subst. auto.
+            ++ assert (incl (remove eq_dec_form a l1) l2). intro. intros. apply in_remove in H4. destruct H4.
+                 apply H1 in H4. inversion H4 ; subst ; auto. exfalso ; apply H5 ; auto.
+                 rewrite permut_remove_remove_list in H3.
+                 assert (J0: NoDup (remove eq_dec_form a l4)). apply remove_preserv_NoDup ; auto.
+                 assert (J1: incl l3 (remove eq_dec_form a l4)). intro. intros. apply in_in_remove ; auto.
+                 intro ; subst ; auto.
+                 assert (J:length (remove_list l2 (remove eq_dec_form a l4)) < length (remove_list (remove eq_dec_form a l1) l3)).
+                 assert ((remove_list l1 l3) = (remove_list (remove eq_dec_form a l1) l3)).
+                 pose (redund_remove_remove_list a l1 l3). rewrite notin_remove in e.
+                 symmetry in e. rewrite notin_remove in e. auto.
+                 1-2: intro ; apply In_remove_list_In_list in H5 ; auto. rewrite H5 in H3. auto.
+                 pose (IHl2 (remove eq_dec_form a l1) _ _ J0 H0 H4 J1 J). destruct e. destruct H5.
+                 exists x ; split ; auto. intro. apply H6. apply in_in_remove ; auto. intro ; subst. auto.
+          -- assert (In a l3 -> False). intro. apply n0 ; auto. rewrite permut_remove_remove_list in H3.
+              rewrite notin_remove in H3 ; auto.
+              assert (incl (remove eq_dec_form a l1) l2). intro. intros. apply in_remove in H5. destruct H5.
+              apply H1 in H5. inversion H5 ; subst ; auto. exfalso ; apply H6 ; auto.
+              assert (length (remove_list l2 l4) < length (remove_list (remove eq_dec_form a l1) l3)).
+              pose (redund_remove_remove_list a l1 l3). rewrite notin_remove in e. rewrite e. rewrite notin_remove ; auto.
+              intro. apply In_remove_list_In_list in H6 ; auto. intro. apply In_remove_list_In_list in H6 ; auto.
+              pose (IHl2 (remove eq_dec_form a l1) _ _ H H0 H5 H2 H6). destruct e. destruct H7.
+              exists x ; split ; auto. intro. apply H8. apply in_in_remove ; auto. intro ; subst. auto.
+        * exists a ; split ; auto.
+  Qed.
+ +
+  Lemma less_ub_witness : forall l, length (usable_boxes (XBoxed_list (top_boxes (XBoxed_list (top_boxes l))), []%list)) <
+    length (usable_boxes (XBoxed_list (top_boxes l), []%list)) ->
+    exists A, In (Box A) (top_boxes (XBoxed_list (top_boxes (XBoxed_list (top_boxes l))))) /\
+                  (In (Box A) (top_boxes (XBoxed_list (top_boxes l))) -> False).
+  Proof.
+  intros. unfold usable_boxes in H. simpl in H. unfold subform_boxesS in H. simpl in H.
+  repeat rewrite remove_list_of_nil in H. repeat rewrite app_nil_r in H.
+  apply remove_list_decr_in in H ; auto. destruct H. destruct H.
+  pose (in_top_boxes _ _ H). destruct s. destruct s. destruct s. destruct p. subst. exists x0 ; auto.
+  1-2: apply NoDup_subform_boxesLF.
+  intro. intros. pose (in_top_boxes _ _ H0). destruct s. destruct s. destruct s. destruct p ; subst.
+  apply is_box_in_top_boxes. apply top_boxes_incl_list in H0. apply In_XBoxed_list in H0.
+  destruct H0. apply list_preserv_XBoxed_list. apply is_box_in_top_boxes. 2,4: exists x ; auto.
+  apply list_preserv_XBoxed_list ; auto. destruct H0. destruct H0 ; subst. apply XBoxed_list_In_unfold.
+  exists (Box (Box x)) ; split ; auto. apply is_box_in_top_boxes. 2: exists (Box x) ; auto.
+  apply list_preserv_XBoxed_list ; auto.
+  intro. intros. apply In_subform_boxes in H0. destruct H0. destruct H0. apply In_XBoxed_list in H1.
+  destruct H1. apply In_incl_subform_boxes with (A:=x) ; auto. apply list_preserv_XBoxed_list.
+  apply is_box_in_top_boxes. apply list_preserv_XBoxed_list ; auto. apply in_top_boxes in H1.
+  destruct H1. destruct s. destruct s. destruct p ; subst. exists x0 ; auto.
+  destruct H1. destruct H1 ; subst. apply In_incl_subform_boxes with (A:= x) ; auto.
+  apply XBoxed_list_In_unfold. exists (Box x) ; split ; auto.
+  apply is_box_in_top_boxes. apply list_preserv_XBoxed_list ; auto. exists x ; auto.
+  Qed.
+ +
+  Lemma ub_stable : forall s, length (usable_boxes (XBoxed_list (top_boxes (XBoxed_list (top_boxes (fst s)))), []%list)) <
+     length (usable_boxes (XBoxed_list (top_boxes (fst s)), []%list)) ->
+    length (usable_boxes (XBoxed_list (top_boxes (fst s)), []%list)) < length (usable_boxes s).
+  Proof.
+  intros. unfold usable_boxes. simpl. unfold subform_boxesS. simpl. destruct s. simpl in H. simpl.
+  apply remove_list_incr_decr ; simpl. apply add_remove_list_preserve_NoDup. 2: apply NoDup_nil.
+  apply NoDup_subform_boxesLF. apply add_remove_list_preserve_NoDup. 1-2: apply NoDup_subform_boxesLF.
+  apply less_ub_witness in H. destruct H. destruct H.
+  assert (J0: In (Box (Box (Box x))) (top_boxes l)). apply top_boxes_incl_list in H. apply In_XBoxed_list in H.
+  destruct H. exfalso ; auto. destruct H. destruct H ; subst. apply top_boxes_incl_list in H. apply In_XBoxed_list in H.
+  destruct H. exfalso ; apply H0. apply is_box_in_top_boxes. apply XBoxed_list_In ; auto. unfold is_boxedT ; exists x ; auto.
+  destruct H. destruct H ; subst ; auto.
+  exists (Box (Box x)). repeat split.
+  apply is_box_in_top_boxes. 2: unfold is_boxedT ; eexists ; auto. apply XBoxed_list_In_unfold.
+  exists (Box (Box (Box x))) ; split ; auto. apply in_or_app ; left. apply In_incl_subform_boxes with (A:=Box (Box (Box x))) ; auto.
+  apply top_boxes_incl_list ; auto. simpl ; auto. intro. apply H0. apply is_box_in_top_boxes.
+  2: unfold is_boxedT ; exists x ; auto. apply XBoxed_list_In_unfold. exists (Box (Box x)) ; split ; auto.
+  intro. intros. apply is_box_in_top_boxes. apply list_preserv_XBoxed_list ; auto.
+  apply in_top_boxes in H0. destruct H0. destruct s. destruct s. destruct p ; subst. exists x ; auto.
+  intro. intros. apply in_app_or in H0. destruct H0. apply in_or_app. left.
+  pose (XBoxed_list_same_subform_boxes (top_boxes l)). apply a0 in H0. apply In_subform_boxes in H0. destruct H0.
+  destruct H0. apply In_incl_subform_boxes with (A:=x). apply top_boxes_incl_list ; auto. auto.
+  apply remove_list_is_in. rewrite remove_list_of_nil in H0. inversion H0.
+  Qed.
+ +
+  End Diam_help.
+ +
+  Section logic.
+ +
+  Lemma DiamL_lim : forall A Γ0 Δ, (is_Boxed_list ) ->
+                                                                      (nobox_gen_ext Γ0) ->
+                                                                      (GLS_prv (A :: XBoxed_list , [])) ->
+                                                                      (GLS_prv (Diam A :: Γ0, Δ)).
+  Proof.
+  intros. unfold Diam. unfold Neg.
+  apply derI with (ps:=[([] ++ Γ0, [] ++ Box (A --> ) :: Δ);([] ++ :: Γ0, [] ++ Δ)]).
+  apply ImpL. assert ((Box (A --> ) --> :: Γ0, Δ) = ([] ++ Box (A --> ) --> :: Γ0, [] ++ Δ)). auto.
+  rewrite H0. apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+  2: apply derI with (ps:=[]) ; try apply dlNil ; try apply BotL ; apply BotLRule_I.
+  apply derI with (ps:=[(XBoxed_list ++ [Box (A --> )], [A --> ])]).
+  apply GLR. apply GLRRule_I ; auto. apply dlCons. 2: apply dlNil.
+  apply derI with (ps:=[([] ++ A :: XBoxed_list ++ [Box (A --> )], [] ++ :: [])]).
+  apply ImpR. assert ((XBoxed_list ++ [Box (A --> )], [A --> ]) = ([] ++ XBoxed_list ++ [Box (A --> )], [] ++ A --> :: [])). auto.
+  rewrite H0. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+  assert (J0: derrec_height X0 = derrec_height X0) ; auto.
+  assert (J1: wkn_L (Box (A --> )) (A :: XBoxed_list , []%list) (A :: XBoxed_list ++ [Box (A --> )], []%list)).
+  assert (A :: XBoxed_list = (A :: XBoxed_list ) ++ []). rewrite app_nil_r. auto. rewrite H0.
+  assert (A :: XBoxed_list ++ [Box (A --> )] = (A :: XBoxed_list ) ++ Box (A --> ) :: []). auto. rewrite H1.
+  apply wkn_LI. pose (GLS_wkn_L X0 J0 J1). destruct s.
+  assert (J2: derrec_height x = derrec_height x) ; auto.
+  assert (J3: wkn_R (A :: XBoxed_list ++ [Box (A --> )], []%list) (A :: XBoxed_list ++ [Box (A --> )], [])).
+  assert ((A :: XBoxed_list ++ [Box (A --> )], @nil MPropF) = (A :: XBoxed_list ++ [Box (A --> )], [] ++ [])).
+  rewrite app_nil_r. auto. rewrite H0.
+  assert ((A :: XBoxed_list ++ [Box (A --> )], []) = (A :: XBoxed_list ++ [Box (A --> )], [] ++ :: [])). auto. rewrite H1.
+  apply wkn_RI. pose (GLS_wkn_R x J2 J3). destruct s. simpl. auto.
+  Qed.
+ +
+  Lemma nobox_top_boxes : forall l, nobox_gen_ext (top_boxes l) l.
+  Proof.
+  induction l ; simpl ; auto. apply univ_gen_ext_nil. destruct a.
+  1-3: apply univ_gen_ext_extra ; auto ; intro ; inversion X ; inversion H.
+  apply univ_gen_ext_cons ; auto.
+  Qed.
+ +
+  Lemma top_boxes_nodup : forall l, incl (top_boxes l) (top_boxes (nodup eq_dec_form l)).
+  Proof.
+  induction l ; intro ; intros ; auto. destruct a as [n | | |]; simpl ; simpl in H ; auto ; simpl ; subst.
+  destruct (in_dec eq_dec_form # n l) ; auto. destruct (in_dec eq_dec_form Bot l) ; auto.
+  destruct (in_dec eq_dec_form (a1 --> a2) l) ; auto. destruct (in_dec eq_dec_form (Box a) l) ; simpl ; auto.
+  destruct H ; subst ; auto. apply IHl. apply is_box_in_top_boxes ; auto. exists a ; auto. destruct H ; subst ; auto.
+  Qed.
+ +
+  Lemma subform_boxesLF_nodup : forall l a, In a (subform_boxesLF l) <-> In a (subform_boxesLF (nodup eq_dec_form l)).
+  Proof.
+  induction l ; simpl ; intros ; auto. intuition. split.
+  - destruct a as [n | | |]; simpl ; auto ; intros.
+    destruct (in_dec eq_dec_form # n l) ; apply IHl ; auto. destruct (in_dec eq_dec_form Bot l) ; apply IHl ; auto.
+    destruct (in_dec eq_dec_form (a1 --> a2) l) ; auto. apply in_app_or in H. destruct H.
+    apply IHl. apply In_incl_subform_boxes with (A:=a1 --> a2) ; auto. apply IHl.
+    apply In_remove_list_In_list in H ; auto. apply in_app_or in H. destruct H.
+    simpl. apply in_or_app. left. simpl in H. auto. simpl. apply in_or_app ; right.
+    apply not_removed_remove_list. apply IHl ; auto. apply In_remove_list_In_list in H ; auto.
+    intro. simpl in H. pose (remove_list_cont _ _ H0 _ H). auto.
+    destruct (in_dec eq_dec_form (Box a) l) ; auto. destruct H ; simpl ; auto.
+    apply IHl ; auto. subst. apply In_incl_subform_boxes with (A:=Box a) ; auto. simpl ; auto. apply IHl.
+    apply in_app_or in H ; destruct H. apply In_incl_subform_boxes with (A:=Box a) ; auto. simpl ; auto.
+    apply in_remove in H. destruct H. apply In_remove_list_In_list in H ; auto.
+    destruct H ; subst. simpl ; auto. simpl. right. apply in_or_app ; auto.
+    apply in_app_or in H ; destruct H ; auto. apply in_remove in H. destruct H. right.
+    apply in_not_touched_remove ; auto.
+    apply In_remove_list_In_list_not_In_remove_list in H ; auto. destruct H.
+    apply not_removed_remove_list ; auto.
+    apply IHl ; auto.
+  - destruct a as [n | | |]; simpl ; auto ; intros.
+    destruct (in_dec eq_dec_form # n l) ; apply IHl ; auto. destruct (in_dec eq_dec_form Bot l) ; apply IHl ; auto.
+    destruct (in_dec eq_dec_form (a1 --> a2) l) ; auto. destruct (in_dec eq_dec_form a0 (subform_boxesF a1 ++ remove_list (subform_boxesF a1) (subform_boxesF a2))) ; auto.
+    apply in_or_app ; auto. apply in_or_app ; right.
+    apply not_removed_remove_list ; auto. apply IHl ; auto. simpl in H. apply in_or_app ; apply in_app_or in H ; destruct H ; auto.
+    right. apply In_remove_list_In_list_not_In_remove_list in H ; auto. destruct H.
+    apply not_removed_remove_list ; auto. apply IHl ; auto.
+    destruct (in_dec eq_dec_form (Box a) l) ; auto.
+    destruct (in_dec eq_dec_form a0 (subform_boxesF (Box a))) ; auto. simpl in i0 ; destruct i0 ; auto.
+    right. apply in_or_app ; auto. right. simpl in n. apply in_or_app ; right. apply in_not_touched_remove ; auto.
+    apply not_removed_remove_list ; auto. apply IHl ; auto. simpl in H. destruct H ; auto. right.
+    apply in_or_app ; apply in_app_or in H ; destruct H ; auto.
+    right. apply in_remove in H. destruct H. apply In_remove_list_In_list_not_In_remove_list in H ; auto. destruct H.
+    apply in_not_touched_remove ; auto. apply not_removed_remove_list ; auto. apply IHl ; auto.
+  Qed.
+ +
+  Lemma set_leq_ub_unif : forall s, (length (usable_boxes (nodupseq (XBoxed_list (top_boxes (fst s)), [])))) <= (length (usable_boxes s)).
+  Proof.
+  intros. destruct s. simpl. unfold usable_boxes. simpl.
+  assert (J0: incl (top_boxes l) (top_boxes (XBoxed_list (top_boxes l)))). apply top_boxes_XBoxed_list.
+  assert (J01: incl (top_boxes (XBoxed_list (top_boxes l))) (top_boxes (nodup eq_dec_form (XBoxed_list (top_boxes l))))).
+  intro. intros. apply top_boxes_nodup ; auto.
+  assert (J03: incl (top_boxes l) (top_boxes (nodup eq_dec_form (XBoxed_list (top_boxes l))))).
+  intros a H ; apply J01 ; apply J0 ; auto.
+  pose (remove_list_incr_decr3 (subform_boxesS (nodupseq (XBoxed_list (top_boxes l), []%list))) _ _ J03).
+  assert (J1: NoDup (subform_boxesS (nodupseq (XBoxed_list (top_boxes l), []%list)))). apply NoDup_subform_boxesS.
+  assert (J2: NoDup (subform_boxesS (l, l0))). apply NoDup_subform_boxesS.
+  assert (J3: incl (subform_boxesS (nodupseq (XBoxed_list (top_boxes l), []%list))) (subform_boxesS (l, l0))).
+  intro ; intros. unfold subform_boxesS. simpl. unfold subform_boxesS in H. simpl in H.
+  rewrite remove_list_of_nil in H. rewrite app_nil_r in H. apply in_or_app ; left.
+  assert (J02: In a (subform_boxesLF (XBoxed_list (top_boxes l)))). apply subform_boxesLF_nodup ; auto.
+  apply XBoxed_list_same_subform_boxes with (l:=(top_boxes l)) in J02.
+  apply subform_boxesLF_top_boxes ; auto.
+  pose (remove_list_incr_decr2 _ _ (top_boxes l) J1 J2 J3). lia.
+  Qed.
+ +
+  Lemma is_init_Canopy : forall s, is_init s -> (forall leaf, InT leaf (Canopy s) -> is_init leaf).
+  Proof.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  intros. apply fold_Canopy in H. destruct H ; subst ; auto.
+  destruct s0 ; destruct p. unfold inv_prems in i. apply InT_flatten_list_InT_elem in i. destruct i.
+  destruct p. destruct (finite_ImpRules_premises_of_S s). simpl in i1. subst.
+  apply p in i1. destruct i1.
+  - inversion i1 ; subst. inversion i ; subst. 2: inversion H0.
+    assert (J0: n_imp_subformS (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) < n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1)).
+    unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+    lia. apply IHs with (leaf:=leaf) in J0 ; auto.
+    unfold is_init. destruct X. destruct s.
+    left. left. inversion i2 ; subst. assert (InT (# P) (Γ0 ++ A :: Γ1)). apply InT_or_app.
+    assert (InT (# P) (Γ0 ++ Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
+    destruct H0 ; auto. right ; apply InT_cons ; auto. apply InT_split in H0. destruct H0. destruct s. rewrite e.
+    assert (InT (# P) (Δ0 ++ B :: Δ1)). apply InT_or_app.
+    assert (InT (# P) (Δ0 ++ A --> B :: Δ1)). rewrite <- H1. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
+    destruct H0 ; auto. inversion i3 ; subst. inversion H2. right ; apply InT_cons ; auto. apply InT_split in H0. destruct H0. destruct s.
+    rewrite e0. apply IdPRule_I.
+    left. right. inversion i2 ; subst. assert (InT (Box A0) (Γ0 ++ A :: Γ1)). apply InT_or_app.
+    assert (InT (Box A0) (Γ0 ++ Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
+    destruct H0 ; auto. right ; apply InT_cons ; auto. apply InT_split in H0. destruct H0. destruct s. rewrite e.
+    assert (InT (Box A0) (Δ0 ++ B :: Δ1)). apply InT_or_app.
+    assert (InT (Box A0) (Δ0 ++ A --> B :: Δ1)). rewrite <- H1. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
+    destruct H0 ; auto. inversion i3 ; subst. inversion H2. right ; apply InT_cons ; auto. apply InT_split in H0. destruct H0. destruct s.
+    rewrite e0. apply IdBRule_I.
+    right. inversion b ; subst. assert (InT () (Γ0 ++ A :: Γ1)). apply InT_or_app.
+    assert (InT () (Γ0 ++ Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
+    destruct H0 ; auto. right ; apply InT_cons ; auto. apply InT_split in H0. destruct H0. destruct s. rewrite e. apply BotLRule_I.
+  - inversion i1 ; subst. inversion i ; subst. 2: inversion H0. 3: inversion H1.
+    assert (J0: n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+    unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+    lia. apply IHs with (leaf:=leaf) in J0 ; auto.
+    unfold is_init. destruct X. destruct s.
+    left. left. inversion i2 ; subst. assert (InT (# P) (Γ0 ++ Γ1)). apply InT_or_app.
+    assert (InT (# P) (Γ0 ++ A --> B :: Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
+    destruct H0 ; auto. inversion i3 ; subst. inversion H2. auto. apply InT_split in H0. destruct H0. destruct s. rewrite e.
+    assert (InT (# P) (Δ0 ++ A :: Δ1)). apply InT_or_app.
+    assert (InT (# P) (Δ0 ++ Δ1)). rewrite <- H1. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
+    destruct H0 ; auto. right ; apply InT_cons ; auto. apply InT_split in H0. destruct H0. destruct s.
+    rewrite e0. apply IdPRule_I.
+    left. right. inversion i2 ; subst. assert (InT (Box A0) (Γ0 ++ Γ1)). apply InT_or_app.
+    assert (InT (Box A0) (Γ0 ++ A --> B :: Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
+    destruct H0 ; auto. inversion i3 ; subst. inversion H2. auto. apply InT_split in H0. destruct H0. destruct s. rewrite e.
+    assert (InT (Box A0) (Δ0 ++ A :: Δ1)). apply InT_or_app.
+    assert (InT (Box A0) (Δ0 ++ Δ1)). rewrite <- H1. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
+    destruct H0 ; auto. right ; apply InT_cons ; auto. apply InT_split in H0. destruct H0. destruct s.
+    rewrite e0. apply IdBRule_I.
+    right. inversion b ; subst. assert (InT () (Γ0 ++ Γ1)). apply InT_or_app.
+    assert (InT () (Γ0 ++ A --> B :: Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
+    destruct H0 ; auto. inversion i2 ; subst. inversion H1. auto. apply InT_split in H0. destruct H0. destruct s. rewrite e. apply BotLRule_I.
+    assert (J0: n_imp_subformS (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+    unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+    lia. subst. apply IHs with (leaf:=leaf) in J0 ; auto.
+    unfold is_init. destruct X. destruct s.
+    left. left. inversion i2 ; subst. assert (InT (# P) (Γ0 ++ B :: Γ1)). apply InT_or_app.
+    assert (InT (# P) (Γ0 ++ A --> B :: Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H1.
+    destruct H1 ; auto. inversion i3 ; subst. inversion H3. right ; apply InT_cons ; auto. apply InT_split in H1. destruct H1. destruct s. rewrite e.
+    apply IdPRule_I.
+    left. right. inversion i2 ; subst. assert (InT (Box A0) (Γ0 ++ B :: Γ1)). apply InT_or_app.
+    assert (InT (Box A0) (Γ0 ++ A --> B :: Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H1.
+    destruct H1 ; auto. inversion i3 ; subst. inversion H3. right ; apply InT_cons ; auto. apply InT_split in H1. destruct H1. destruct s. rewrite e.
+    apply IdBRule_I.
+    right. inversion b ; subst. assert (InT () (Γ0 ++ B :: Γ1)). apply InT_or_app.
+    assert (InT () (Γ0 ++ A --> B :: Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H1.
+    destruct H1 ; auto. inversion i2 ; subst. inversion H2. right ; apply InT_cons ; auto. apply InT_split in H1. destruct H1. destruct s. rewrite e. apply BotLRule_I.
+  Qed.
+ +
+  Theorem is_init_UI_equiv_Top : forall s, is_init s -> forall p X Y0 Y1, GLS_prv (X, Y0 ++ Top --> (UI p s) :: Y1).
+  Proof.
+  intros. destruct (critical_Seq_dec s).
+  - assert (J0: GUI p s (UI p s)). apply UI_GUI ; auto.
+    pose (@GUI_inv_critic_init p s (UI p s) J0 c X). rewrite <- e.
+    apply derI with (ps:=[([] ++ Top :: X0, Y0 ++ Top :: Y1)]).
+    apply ImpR. assert ((X0, Y0 ++ Top --> Top :: Y1) = ([] ++ X0, Y0 ++ Top --> Top :: Y1)). auto. rewrite H.
+    apply ImpRRule_I. apply dlCons. 2: apply dlNil. apply TopR.
+  - assert (J0: GUI p s (UI p s)). apply UI_GUI ; auto.
+    assert (J1: Gimap (GUI p) (Canopy (nodupseq s)) (map (UI p) (Canopy (nodupseq s)))). apply Gimap_map. intros.
+    apply UI_GUI ; auto.
+    pose (@GUI_inv_not_critic p s (UI p s) (map (UI p) (Canopy (nodupseq s))) J0 f J1). rewrite <- e.
+    apply derI with (ps:=[([] ++ Top :: X0, Y0 ++ list_conj (map (UI p) (Canopy (nodupseq s))) :: Y1)]).
+    apply ImpR. assert ((X0, Y0 ++ Top --> list_conj (map (UI p) (Canopy (nodupseq s))) :: Y1) = ([] ++ X0, Y0 ++ Top --> list_conj (map (UI p) (Canopy (nodupseq s))) :: Y1)). auto. rewrite H.
+    apply ImpRRule_I. apply dlCons. 2: apply dlNil. simpl.
+    apply GLS_adm_list_exch_R with (s:=(Top :: X0, list_conj (map (UI p) (Canopy (nodupseq s))) :: Y0 ++ Y1)).
+    pose (list_conj_R (map (UI p) (Canopy (nodupseq s))) (Top :: X0, Y0 ++ Y1)). apply g. clear g.
+    intros. simpl. apply InT_map_iff in H. destruct H. destruct p0. subst.
+    assert (J2: GUI p x (UI p x)). apply UI_GUI ; auto.
+    assert (J3: critical_Seq x). apply Canopy_critical in i ; auto.
+    assert (J4: is_init x). apply is_init_Canopy in i ; auto.
+    pose (is_init_nodupseq s). destruct p0. apply i0 ; auto.
+    pose (@GUI_inv_critic_init p x (UI p x) J2 J3 J4). rewrite <- e0.
+    assert ((Top :: X0, Top :: Y0 ++ Y1) = (Top :: X0, [] ++ Top :: Y0 ++ Y1)). auto. rewrite H. apply TopR.
+    assert (list_conj (map (UI p) (Canopy (nodupseq s))) :: Y0 ++ Y1 = [] ++ [list_conj (map (UI p) (Canopy (nodupseq s)))] ++ Y0 ++ [] ++ Y1). auto. rewrite H.
+    assert (Y0 ++ list_conj (map (UI p) (Canopy (nodupseq s))) :: Y1 = [] ++ [] ++ Y0 ++ [list_conj (map (UI p) (Canopy (nodupseq s)))] ++ Y1). auto. rewrite H0.
+    apply list_exch_RI.
+  Qed.
+ +
+  Theorem is_init_UI : forall s, is_init s -> forall p X Y0 Y1, GLS_prv (X, Y0 ++ UI p s :: Y1).
+  Proof.
+  intros. eapply is_init_UI_equiv_Top in X. apply ImpR_inv with (prem:=([] ++ Top :: X0, Y0 ++ UI p s :: Y1)) in X.
+  apply TopL_remove in X. simpl in X ; auto. assert ((X0, Y0 ++ Top --> UI p s :: Y1) = ([] ++ X0, Y0 ++ Top --> UI p s :: Y1)).
+  auto. rewrite H. apply ImpRRule_I.
+  Qed.
+ +
+  End logic.
+ +
+  Section top_boxes_facts.
+ +
+  Theorem top_boxes_diam_jump : forall s, critical_Seq s -> (length (usable_boxes s) = length (usable_boxes (XBoxed_list (top_boxes (fst s)),[]))) ->
+          (forall A, In A (top_boxes (fst s)) <-> In A (top_boxes (XBoxed_list (top_boxes (fst s))))).
+  Proof.
+  intros. split.
+  - intro. apply top_boxes_XBoxed_list ; auto.
+  - intro. pose (in_top_boxes _ _ H1). repeat destruct s0. destruct p. clear e0 ; subst.
+    apply nolessub_In ; auto. lia.
+  Qed.
+ +
+  End top_boxes_facts.
+ +
+  Section nodup_facts.
+ +
+  Theorem list_prop_LF_In: forall l A B, In A l -> In B (list_prop_F A) -> In B (list_prop_LF l).
+  Proof.
+  induction l ; intuition. simpl. apply in_or_app. inversion H ; subst ; auto.
+  right. apply IHl with (A:=A) ; auto.
+  Qed.
+ +
+  Theorem In_propvar_subform: forall l A p, In A l -> In # p (propvar_subform A) -> In # p (propvar_subform_list l).
+  Proof.
+  induction l ; intuition. simpl. apply in_or_app. inversion H ; subst ; auto.
+  right. apply IHl with (A:=A) ; auto.
+  Qed.
+ +
+  Theorem restr_list_prop_nodup : forall l A p,
+      (InT A (restr_list_prop p (nodup eq_dec_form l)) -> InT A (restr_list_prop p l)) *
+      (InT A (restr_list_prop p l) -> InT A (restr_list_prop p (nodup eq_dec_form l))).
+  Proof.
+  induction l ; intros ; simpl ; intuition.
+  - destruct (in_dec eq_dec_form a l) ; auto. apply IHl in H. unfold restr_list_prop. simpl.
+    apply In_InT. apply InT_In in H. apply in_remove in H. destruct H.
+    apply in_not_touched_remove ; auto. apply in_or_app ; right ; auto.
+    unfold restr_list_prop. simpl.
+    apply In_InT. apply InT_In in H. apply in_remove in H. destruct H.
+    apply in_not_touched_remove ; auto. simpl in H. apply in_app_or in H.
+    apply in_or_app ; destruct H ; auto. right.
+    assert (InT A (restr_list_prop p (nodup eq_dec_form l))). apply In_InT.
+    apply in_not_touched_remove ; auto. apply IHl in H1.
+    apply InT_In in H1. apply in_remove in H1. destruct H1. auto.
+  - destruct (in_dec eq_dec_form a l) ; auto. apply IHl. unfold restr_list_prop. simpl.
+    apply In_InT. apply InT_In in H. apply in_remove in H. destruct H.
+    apply in_not_touched_remove ; auto. simpl in H. apply in_app_or in H. destruct H ; auto.
+    apply list_prop_LF_In with (A:=a) ; auto.
+    unfold restr_list_prop. simpl. apply In_InT. apply InT_In in H. apply in_remove in H. destruct H.
+    apply in_not_touched_remove ; auto. simpl in H. apply in_app_or in H. apply in_or_app ; destruct H ; auto.
+    right.
+    assert (InT A (restr_list_prop p l)). apply In_InT.
+    apply in_not_touched_remove ; auto. apply IHl in H1.
+    apply InT_In in H1. apply in_remove in H1. destruct H1. auto.
+  Qed.
+ +
+  Theorem propvar_subform_list_nodup: forall l q,
+  In # q (propvar_subform_list (nodup eq_dec_form l)) <-> In # q (propvar_subform_list l).
+  Proof.
+  induction l ; intuition.
+  - simpl. simpl in H. apply in_or_app. destruct (in_dec eq_dec_form a l).
+    + right ; apply IHl ; auto.
+    + simpl in H. apply in_app_or in H ; destruct H ; auto. right ; apply IHl ; auto.
+  - simpl. simpl in H. apply in_app_or in H. destruct (in_dec eq_dec_form a l).
+    + destruct H. apply In_propvar_subform with (A:=a) ; auto. apply nodup_In ; auto.
+       apply IHl ; auto.
+    + simpl. apply in_or_app. destruct H ; auto. right ; apply IHl ; auto.
+  Qed.
+ +
+  Lemma incl_hpadm_prv : forall s0 s1 (D0: GLS_prv s0), (incl (fst s0) (fst s1)) -> (incl (snd s0) (snd s1)) ->
+    existsT2 (D1: GLS_prv s1), derrec_height D1 <= derrec_height D0.
+  Proof.
+  intros. pose (incl_idS _ _ H H0). destruct s. destruct p. destruct s. destruct s.
+  pose (nodupseq_prv_hpadm_LR _ D0). destruct s.
+  assert (derrec_height x2 = derrec_height x2). auto.
+  apply PermutationTS_sym in p. pose (PermutationTS_prv_hpadm _ x2 _ p).
+  destruct s. destruct x ; simpl in *.
+  assert (derrec_height x3 = derrec_height x3). auto.
+  pose (@GLS_list_wkn_L _ [] l1 _ x3 H2). simpl in s. destruct (s x0).
+  assert (derrec_height x = derrec_height x). auto.
+  pose (@GLS_list_wkn_R _ _ [] l2 x H3). simpl in s2. destruct (s2 x1).
+  apply PermutationTS_sym in p0. pose (PermutationTS_prv_hpadm _ x4 _ p0).
+  destruct s3. pose (nodupseq_prv_hpadm_RL _ x5). destruct s3.
+  exists x6 ; lia.
+  Qed.
+ +
+  Lemma incl_prv : forall s0 s1, (incl (fst s0) (fst s1)) -> (incl (snd s0) (snd s1)) ->
+    (GLS_prv s0) -> (GLS_prv s1).
+  Proof.
+  intros. pose (incl_idS _ _ H H0). destruct s. destruct p. destruct s. destruct s.
+  pose (nodupseq_prv s0). destruct p1. apply g in X. apply PermutationTS_sym in p.
+  pose (PermutationTS_prv _ _ p X). destruct x ; simpl in *.
+  pose (GLS_prv_list_wkn_L [] l). simpl in g2. apply g2 with (l:=x0) in g1.
+  epose (GLS_prv_list_wkn_R []). simpl in g3. apply g3 with (l:=x1) in g1.
+  apply PermutationTS_sym in p0. pose (PermutationTS_prv _ _ p0 g1).
+  apply nodupseq_prv in g4 ; auto.
+  Qed.
+ +
+  Lemma Canopy_nodupseq_equiprv_genR : forall s A,
+    ((forall leaf, InT leaf (Canopy (nodupseq s)) -> GLS_prv (fst leaf, A :: snd leaf)) -> (GLS_prv (fst s, A :: snd s))) *
+    ((GLS_prv (fst s, A :: snd s)) -> (forall leaf, InT leaf (Canopy (nodupseq s)) -> GLS_prv (fst leaf, A :: snd leaf))).
+  Proof.
+  intros. split ; intros.
+  - apply Canopy_equiprv_genR in X. simpl in X.
+    apply incl_prv with (s0:=(nodup eq_dec_form (fst s), A :: nodup eq_dec_form (snd s))) ; simpl ; auto.
+    intros B HB. apply nodup_In in HB ; auto. intros B HB. inversion HB ; simpl ; auto. right. apply nodup_In in H ; auto.
+  - pose (Canopy_equiprv_genR s A). simpl in p. destruct p. clear g. apply Canopy_nodupseq_perm in H.
+    destruct H. destruct p ; subst. pose (g0 X _ i).
+    apply incl_prv with (s0:=((fst x), A :: (snd x))) ; simpl ; auto.
+    intros B HB. apply (nodup_In eq_dec_form) ; apply (nodup_In eq_dec_form) in HB. destruct p.
+    apply Permutation_in with (l:=(nodup eq_dec_form (fst x))) ; auto ; apply Permutation_PermutationT ; destruct x ; destruct leaf ; simpl in * ; auto.
+    intros B HB. apply (nodup_In eq_dec_form) ; apply (nodup_In eq_dec_form) in HB. destruct p.
+    simpl in *. destruct (in_dec eq_dec_form A (snd x)).
+    + destruct (in_dec eq_dec_form A (snd leaf)).
+       apply Permutation_in with (l:=(nodup eq_dec_form (snd x))) ; auto ; apply Permutation_PermutationT ; destruct x ; destruct leaf ; simpl in * ; auto.
+       exfalso. apply n. apply Permutation_PermutationT in p0. apply (nodup_In eq_dec_form).
+       apply Permutation_in with (l:=(nodup eq_dec_form (snd x))) ; auto. apply (nodup_In eq_dec_form) ; auto.
+    + destruct (in_dec eq_dec_form A (snd leaf)).
+       exfalso. apply n. apply Permutation_PermutationT in p0. apply (nodup_In eq_dec_form).
+       apply Permutation_in with (l:=(nodup eq_dec_form (snd leaf))) ; auto. apply Permutation_sym ; auto. apply (nodup_In eq_dec_form) ; auto.
+       simpl ; inversion HB ; auto. right.
+       apply Permutation_in with (l:=(nodup eq_dec_form (snd x))) ; auto ; apply Permutation_PermutationT ; destruct x ; destruct leaf ; simpl in * ; auto.
+  Qed.
+ +
+  Lemma Canopy_nodupseq_equiprv_genL : forall s A,
+    ((forall leaf, InT leaf (Canopy (nodupseq s)) -> GLS_prv (A :: fst leaf, snd leaf)) -> (GLS_prv (A :: fst s, snd s))) *
+    ((GLS_prv (A :: fst s, snd s)) -> (forall leaf, InT leaf (Canopy (nodupseq s)) -> GLS_prv (A :: fst leaf, snd leaf))).
+  Proof.
+  intros. split ; intros.
+  - apply Canopy_equiprv_genL in X. simpl in X.
+    apply incl_prv with (s0:=(A :: nodup eq_dec_form (fst s), nodup eq_dec_form (snd s))) ; simpl ; auto.
+    intros B HB. inversion HB ; simpl ; auto. right. apply nodup_In in H ; auto. intros B HB. apply nodup_In in HB ; auto.
+  - pose (Canopy_equiprv_genL s A). simpl in p. destruct p. clear g. apply Canopy_nodupseq_perm in H.
+    destruct H. destruct p ; subst. pose (g0 X _ i).
+    apply incl_prv with (s0:=(A :: (fst x), (snd x))) ; simpl ; auto.
+    intros B HB. apply (nodup_In eq_dec_form) ; apply (nodup_In eq_dec_form) in HB. destruct p.
+    simpl in *. destruct (in_dec eq_dec_form A (fst x)).
+    + destruct (in_dec eq_dec_form A (fst leaf)).
+       apply Permutation_in with (l:=(nodup eq_dec_form (fst x))) ; auto ; apply Permutation_PermutationT ; destruct x ; destruct leaf ; simpl in * ; auto.
+       exfalso. apply n. apply Permutation_PermutationT in p. apply (nodup_In eq_dec_form).
+       apply Permutation_in with (l:=(nodup eq_dec_form (fst x))) ; auto. apply (nodup_In eq_dec_form) ; auto.
+    + destruct (in_dec eq_dec_form A (fst leaf)).
+       exfalso. apply n. apply Permutation_PermutationT in p. apply (nodup_In eq_dec_form).
+       apply Permutation_in with (l:=(nodup eq_dec_form (fst leaf))) ; auto. apply Permutation_sym ; auto. apply (nodup_In eq_dec_form) ; auto.
+       simpl ; inversion HB ; auto. right.
+       apply Permutation_in with (l:=(nodup eq_dec_form (fst x))) ; auto ; apply Permutation_PermutationT ; destruct x ; destruct leaf ; simpl in * ; auto.
+    + intros B HB. apply (nodup_In eq_dec_form) ; apply (nodup_In eq_dec_form) in HB. destruct p.
+       apply Permutation_in with (l:=(nodup eq_dec_form (snd x))) ; auto ; apply Permutation_PermutationT ; destruct x ; destruct leaf ; simpl in * ; auto.
+  Qed.
+ +
+  End nodup_facts.
+ +
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_basics.html b/GL.Interpolation.UIGL_basics.html new file mode 100644 index 0000000..4c787a1 --- /dev/null +++ b/GL.Interpolation.UIGL_basics.html @@ -0,0 +1,137 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_basics

+ +
+  Require Import List Extraction.
+  Require Import Lia.
+ +
+  Require Import GLS_export.
+ +
+  Section Logic_Abrv.
+ +
+  (* Conjunction of a list of formulas. *)
+ +
+  Fixpoint list_conj (l : list MPropF) : MPropF :=
+  match l with
+   | nil => Top
+   | h :: t => And h (list_conj t)
+  end.
+ +
+  (* Disjunction of a list of formulas. *)
+ +
+  Fixpoint list_disj (l : list MPropF) : MPropF :=
+  match l with
+   | nil => Bot
+   | h :: t => Or h (list_disj t)
+  end.
+ +
+  (* List of propositional variables in a formula. *)
+ +
+  Definition list_prop_F (A : MPropF) : list MPropF :=
+  match A with
+   | # P => [# P]
+   | _ => []
+  end.
+ +
+  (* List of propositional variables in a list of formula. *)
+ +
+  Fixpoint list_prop_LF (l : list MPropF) : list MPropF :=
+  match l with
+   | nil => []
+   | h :: t => (list_prop_F h) ++ (list_prop_LF t)
+  end.
+ +
+  Lemma list_prop_LF_In : forall l A, In A l -> (existsT2 p, A = # p) -> In A (list_prop_LF l).
+  Proof.
+  induction l ; auto. intros. simpl. destruct H0 ; subst. simpl in H. destruct H ; subst.
+  apply in_or_app ; left ; apply in_eq. apply in_or_app ; right. apply IHl ; auto. eexists ; auto.
+  Qed.
+ +
+  Lemma In_list_prop_LF : forall l A, In A (list_prop_LF l) -> In A l.
+  Proof.
+  induction l ; auto. intros. simpl. simpl in H. apply in_app_or in H ; destruct H.
+  left. destruct a ; simpl in H ; subst. destruct H ; auto ; try inversion H.
+  inversion H. 1,2: inversion H. right. apply IHl ; auto.
+  Qed.
+ +
+  Lemma In_list_prop_LF_bis : forall l A, In A (list_prop_LF l) -> ((In A l) * (existsT2 p, A = # p)).
+  Proof.
+  induction l ; auto ; intros. inversion H. simpl in H. split. apply In_list_prop_LF ; auto.
+  apply In_InT in H. apply InT_app_or in H ; destruct H.
+  destruct a ; simpl in i ; inversion i ; subst. eexists ; auto. inversion H0.
+  apply InT_In in i ; apply IHl in i ; destruct i ; auto.
+  Qed.
+ +
+  (* Restricted list of propositional variables. *)
+ +
+  Definition restr_list_prop p (l : list MPropF) := remove eq_dec_form (# p) (list_prop_LF l).
+ +
+  End Logic_Abrv.
+ +
+  Section Random.
+ +
+  Lemma InT_In_Seq: forall (s: Seq) l, (InT s l -> In s l) * (In s l -> InT s l).
+  Proof.
+  intros. split ; intros.
+  - apply InT_In ; auto.
+  - destruct s. apply In_InT_seqs ; auto.
+  Qed.
+ +
+  End Random.
+ +
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_braga.html b/GL.Interpolation.UIGL_braga.html new file mode 100644 index 0000000..8dec0ee --- /dev/null +++ b/GL.Interpolation.UIGL_braga.html @@ -0,0 +1,497 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_braga

+ +
+(**************************************************************)
+(*   Copyright Ian Shillito *                 *)
+(*                                                            *)
+(*                             * Affiliation ANU  *)
+(**************************************************************)
+(*      This file is distributed under the terms of the       *)
+(*         CeCILL v2.1 FREE SOFTWARE LICENSE AGREEMENT        *)
+(**************************************************************)
+ +
+
+ +
+Certification of uniform interpolant function (define below) + +
+ + +
+
+ +
+  Require Import List Extraction.
+  Require Import Lia.
+  Require Import String.
+  Require Import GLS_export.
+ +
+  Require Import UIGL_Def_measure.
+  Require Import UIGL_Canopy.
+  Require Import UIGL_LexSeq.
+  Require Export UIGL_basics.
+  Require Import UIGL_nodupseq.
+ +
+  Import ListNotations.
+ +
+  #[local] Infix "∈" := (@In _) (at level 70, no associativity).
+ +
+  Section imap.
+ +
+  Variables (X Y : Type)
+            (F : X -> Y -> Prop) (* We will instantiate F with GUI (to have mutal recursion). *)
+            (Ffun : forall x l m, F x l -> F x m -> l = m) (*Require that F is a function. *)
+            (D : X -> Prop) (* Domain of F *)
+            (f : forall x, D x -> sig (F x)). (* F is defined on the domain. *)
+ +
+  (* Proceed similarly as Dominique did with flatmap. *)
+ +
+  Inductive Gimap : list X -> list Y -> Prop :=
+    | Gim_nil : Gimap [] []
+    | Gim_cons {x y l m} : F x y
+                         -> Gimap l m
+                         -> Gimap (x::l) (y::m).
+ +
+  Hint Constructors Gimap : core.
+ +
+  Fact Gimap_inv_left l m :
+        Gimap l m
+      -> match l with
+        | [] => [] = m
+        | x::l => exists y m', F x y /\ Gimap l m' /\ m = y :: m'
+        end.
+  Proof. destruct 1; eauto. Qed.
+ +
+  Fact Gimap_inv_sg_left x m : Gimap [x] [m] -> F x m.
+  Proof.
+    intros. apply Gimap_inv_left in H. destruct H. destruct H. destruct H.
+    destruct H0. inversion H1. subst. auto.
+  Qed.
+ +
+  Fact Gimap_app_inv_left l1 l2 m :
+        Gimap (l1++l2) m
+      -> exists m1 m2, Gimap l1 m1 /\ Gimap l2 m2 /\ m = m1++m2.
+  Proof.
+    induction l1 as [ | x l1 IH1 ] in m |- *; simpl.
+    + exists [], m; auto.
+    + intros (y & m' & H1 & (m1 & m2 & H2 & H3 & ->)%IH1 & ->)%Gimap_inv_left.
+      exists (y::m1), m2. repeat split ; auto.
+  Qed.
+ +
+  Fixpoint imap l : (forall x, x l -> D x) -> sig (Gimap l).
+  Proof.
+    refine (match l with
+    | [] => fun _ => exist _ [] Gim_nil
+    | x::l => fun dl => let (y,hy) := f x _ in
+                    let (m,hm) := imap l _ in
+                    exist _ (y::m) (Gim_cons hy hm)
+    end); auto.
+    apply dl ; apply in_eq. intros. apply dl ; apply in_cons ; auto.
+  Defined.
+ +
+  Variables (g : X -> Y) (Hg : forall x, F x (g x)).
+ +
+  Fact Gimap_map l : Gimap l (map g l).
+  Proof. induction l; simpl; now constructor. Qed.
+ +
+  Fact Gimap_fun l0 : forall l1 l2, Gimap l0 l1 -> Gimap l0 l2 -> l1 = l2.
+  Proof. induction l0. intros. apply Gimap_inv_left in H. subst.
+             apply Gimap_inv_left in H0. auto. intros.
+             apply Gimap_inv_left in H. apply Gimap_inv_left in H0.
+             destruct H. destruct H. destruct H. destruct H1. destruct H0.
+             destruct H0. destruct H0. destruct H3. subst. pose (Ffun _ _ _ H H0).
+             rewrite e. pose (IHl0 _ _ H1 H3). rewrite e0. auto. Qed.
+ +
+  End imap.
+ +
+Arguments Gimap {X} {Y} _.
+Arguments imap {X} {Y} _ {D} _ {l}.
+ +
+  Section Gimap_cont.
+ +
+  Variables (X Y : Type)
+            (F : X -> Y -> Prop) (* We will instantiate F with GUI (to have mutal recursion). *)
+            (D : X -> Prop) (* Domain of F *)
+            (f : forall x, D x -> sig (F x)). (* F is defined on the domain. *)
+ +
+  Fact Gimap_fun_rest l0 : forall l1 l2, (forall x, InT x l0 -> forall y0 y1, F x y0 -> F x y1 -> y0 = y1) -> Gimap F l0 l1 -> Gimap F l0 l2 -> l1 = l2.
+  Proof. induction l0. intros l1 l2 Dom H H0. apply Gimap_inv_left in H. subst.
+             apply Gimap_inv_left in H0. auto. intros l1 l2 Dom H H0.
+             apply Gimap_inv_left in H. apply Gimap_inv_left in H0.
+             destruct H. destruct H. destruct H. destruct H1. destruct H0.
+             destruct H0. destruct H0. destruct H3. subst.
+             assert (J0: InT a (a :: l0)). apply InT_eq.
+             pose (Dom _ J0 _ _ H H0). rewrite e.
+             assert (J1: forall x : X, InT x l0 -> forall y0 y1 : Y, F x y0 -> F x y1 -> y0 = y1).
+             intros. apply Dom with (x:=x3) ; auto. apply InT_cons ; auto.
+             pose (IHl0 _ _ J1 H1 H3). rewrite e0. auto. Qed.
+ +
+  End Gimap_cont.
+ +
+  Section GN.
+ +
+  Variables (p : string) (* The variable we exclude from the interpolant. *)
+            (F : Seq -> MPropF -> Prop) (* We will instantiate F with GUI (to have mutal recursion). *)
+            (Ffun : forall x l m, F x l -> F x m -> l = m). (* Require that F is a function. *)
+ +
+  (* First I define the graph of the function N, which is involved in UI. N is total. *)
+ +
+  Unset Elimination Schemes.
+ +
+
+ +
+I proceed as Dominique: Because of nesting, induction principles are too weak, + see below for better ones +
+
+ +
+  Inductive GN : Seq -> Seq -> MPropF -> Prop :=
+    (* If s is initial, send Top. *)
+    | GN_init_seq {s0 s} : is_init s -> GN s0 s Top
+    (* If s is not initial, and has less usable boxes than s0, then call UI. *)
+    | GN_less_ub {s0 s φ} : (is_init s -> False) ->
+                              (length (usable_boxes s) < length (usable_boxes s0)) ->
+                              F s φ ->
+                              GN s0 s φ
+    (* If s is not initial, and does not have less usable boxes than s0, then do an unfolding without recursive call. *)
+    | GN_less {s0 s l} : (is_init s -> False) ->
+                              ((length (usable_boxes s) < length (usable_boxes s0)) -> False) ->
+                              (Gimap F (GLR_prems (nodupseq s)) l) ->
+                              GN s0 s (Or (list_disj (restr_list_prop p (snd s))) (* Disjunction of propositional variables (different from p) on the right. *)
+                                            (Or (list_disj (map Neg (restr_list_prop p (fst s)))) (* Disjunction of propositional variables (different from p) on the left, negated. *)
+                                            (list_disj (map Box l)))).
+ +
+  Set Elimination Schemes.
+ +
+  Fact GN_inv_init0 {s0 s A} : GN s0 s A -> is_init s -> Top = A.
+  Proof. destruct 1 as [ Inits | ? ? ? Inits | ] ; intros; trivial ; exfalso ; auto. Qed.
+ +
+  Fact GN_inv_noinit_lessub0 {s0 s A φ} : GN s0 s A -> (is_init s -> False) ->
+                           (length (usable_boxes s) < length (usable_boxes s0)) ->
+                           F s φ ->
+                           φ = A.
+  Proof. destruct 1 as [ Inits | ? ? ? Inits | ] ; intros; trivial ; auto. 1, 3: exfalso ; auto.
+             apply (Ffun s) ; auto. Defined.
+ +
+  Fact GN_inv_noinit_nolessub0 {s0 s A l} : GN s0 s A -> (is_init s -> False) ->
+                           ((length (usable_boxes s) < length (usable_boxes s0)) -> False) ->
+                           (Gimap F (GLR_prems (nodupseq s)) l) ->
+          (Or (list_disj (restr_list_prop p (snd s))) (Or (list_disj (map Neg (restr_list_prop p (fst s)))) (list_disj (map Box l)))) = A.
+  Proof. destruct 1 as [ Inits | ? ? ? Inits | ] ; intros; trivial ; auto. 1, 2: exfalso ; auto.
+              pose (Gimap_fun _ _ F Ffun _ _ _ H1 H4). rewrite e. auto. Defined.
+ +
+  Hint Constructors Gimap GN : core.
+  Hint Resolve GN_inv_init0 GN_inv_noinit_lessub0 GN_inv_noinit_nolessub0 : core.
+ +
+  Lemma GN_fun : forall s0 s A, GN s0 s A -> (fun s0 s A => forall B, GN s0 s B -> A = B) s0 s A.
+  Proof.
+  intros. inversion H ; subst ; intros; auto.
+  - pose (GN_inv_init0 H0 X) ; auto.
+  - pose (GN_inv_noinit_lessub0 H3 H0 H1 H2) ; auto.
+  - pose (GN_inv_noinit_nolessub0 H3 H0 H1 H2) ; auto.
+  Qed.
+ +
+  Lemma GN_fun0 : forall s0 s A B, GN s0 s A -> GN s0 s B -> A = B.
+  Proof.
+  intros. apply GN_fun with (s0:=s0) (s:=s) ; auto.
+  Qed.
+ +
+  End GN.
+ +
+  Section UI.
+ +
+  (* Second I define the graph of the function UI. *)
+ +
+  Variables (p : string). (* The variable we exclude from the interpolant. *)
+ +
+  Unset Elimination Schemes.
+ +
+
+ +
+Because of nesting, induction principles are too weak, + see below for better ones +
+
+ +
+  Inductive GUI : Seq -> MPropF -> Prop :=
+    | GUI_empty_seq {s} : s = ([],[]) -> (* If s is the empty set, output Bot. *)
+                                      GUI s Bot
+    | GUI_critic_init {s} : critical_Seq s -> (* If critical and initial, output Top. *)
+                                      is_init s ->
+                                      GUI s Top
+    | GUI_not_critic {s l} : ((critical_Seq s) -> False) -> (* If not critical, output conjunction of recursive calls of GUI on Canopy. *)
+                                      (Gimap GUI (Canopy (nodupseq s)) l) ->
+                                      GUI s (list_conj l)
+    | GUI_critic_not_init {s l0 l1} : critical_Seq s -> (* If critical but not initial, store the propositional variables, recursively call on
+                                                                                                               the GLR premises of the sequent, and use GN. *)

+                                           (s <> ([],[])) ->
+                                           (is_init s -> False) ->
+                                           (Gimap GUI (GLR_prems (nodupseq s)) l0) ->
+                                           (Gimap (GN p GUI s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []))) l1) ->
+                                           GUI s (Or (list_disj (restr_list_prop p (snd s)))
+                                                     (Or (list_disj (map Neg (restr_list_prop p (fst s))))
+                                                     (Or (list_disj (map Box l0))
+                                                     (Diam (list_conj l1))))).
+ +
Set Elimination Schemes.
+ +
+  Lemma GUI_fun : forall x l m, GUI x l -> GUI x m -> l = m.
+  Proof.
+  apply (LexSeq_ind (fun x => forall l m, GUI x l -> GUI x m -> l = m)).
+  intros s IH l m H H0. inversion H ; inversion H0 ; subst ; auto ; simpl in *. 1-8: exfalso ; auto.
+  6-9: exfalso ; auto. 1,3: apply not_init_empty_seq ; auto. apply H4 ; apply critical_empty_seq.
+  apply H1 ; apply critical_empty_seq.
+  - assert (J0: (forall x : Seq, InT x (Canopy (nodupseq s)) -> forall y0 y1 : MPropF, GUI x y0 -> GUI x y1 -> y0 = y1)).
+    intros. apply IH with (s1:=x) ; auto. apply LexSeq_nodupseq. destruct (Canopy_LexSeq (nodupseq s) x H3) ; auto.
+    exfalso. apply H1. apply critical_nodupseq. apply Canopy_critical with (s:=nodupseq s) ; subst ; auto.
+    pose (Gimap_fun_rest _ _ GUI (Canopy (nodupseq s)) l0 l1 J0). rewrite e ; auto.
+  - assert (J0: list_disj (map Box l0) = list_disj (map Box l2)).
+    assert (J00: (forall x : Seq, InT x (GLR_prems (nodupseq s)) -> forall y0 y1 : MPropF, GUI x y0 -> GUI x y1 -> y0 = y1)).
+    intros. apply IH with (s1:=x) ; auto. apply LexSeq_nodupseq. apply GLR_prems_LexSeq ; auto.
+    intro. pose (is_init_nodupseq s). apply H3. apply p0. unfold is_init ; auto.
+    pose (Gimap_fun_rest _ _ GUI (GLR_prems (nodupseq s)) l0 l2 J00). rewrite e ; auto.
+    assert (J1: l1 = l3).
+    assert (J10: (forall x : Seq, InT x (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))) -> forall y0 y1 : MPropF, (GN p GUI s) x y0 -> (GN p GUI s) x y1 -> y0 = y1)).
+    intros. inversion H7 ; inversion H13 ; subst ; auto. 1-3: exfalso ; auto.
+    2-4: exfalso ; auto.
+    apply IH with (s1:=x) ; auto. unfold LexSeq. unfold less_thanS. apply DLW_wf_lex.lex_cons ; auto.
+    assert (J100: (forall x0 : Seq, InT x0 (GLR_prems (nodupseq x)) -> forall y0 y1 : MPropF, GUI x0 y0 -> GUI x0 y1 -> y0 = y1)).
+    intros. apply IH with (s1:=x0) ; auto. unfold LexSeq. apply DLW_wf_lex.lex_cons ; auto. apply GLR_prems_less_ub in H17.
+    rewrite <- ub_nodupseq in H17. pose (leq_ub_Canopy _ _ H6). rewrite <- ub_nodupseq in l5.
+    pose (leq_ub_unif s) ; lia. intros. pose (is_init_nodupseq x). apply H14. apply p0. unfold is_init ; left ; auto.
+    pose (Gimap_fun_rest _ _ GUI (GLR_prems (nodupseq x)) l l4 J100). rewrite e ; auto.
+    pose (Gimap_fun_rest _ _ _ _ l1 l3 J10). rewrite e ; auto.
+    rewrite J0. rewrite J1. auto.
+  Qed.
+ +
+  Definition GUI_tot : forall s : Seq, {A : MPropF | GUI s A}.
+  Proof.
+  apply (LexSeq_ind (fun x => existsT A : MPropF, GUI x A)).
+  intros s IH. destruct (empty_seq_dec s).
+  - subst. exists Bot. apply GUI_empty_seq ; auto.
+  - destruct (critical_Seq_dec s).
+    -- destruct (dec_init_rules s).
+      * assert (is_init s) ; auto. exists Top. apply GUI_critic_init ; auto.
+      * assert (is_init s -> False) ; auto.
+        assert ((forall x : Seq, In x (GLR_prems (nodupseq s)) -> {x0 : MPropF | GUI x x0})).
+        intros. apply IH with (s1:=x) ; auto. apply LexSeq_nodupseq. apply GLR_prems_LexSeq ; auto.
+        intro. pose (is_init_nodupseq s). apply f. apply p0. unfold is_init ; auto. apply InT_In_Seq ; auto.
+        epose (@imap _ _ GUI (fun (x : Seq) => In x (GLR_prems (nodupseq s))) H0 (GLR_prems (nodupseq s))). simpl in s0. destruct s0 ; auto.
+        assert (J10: (forall z : Seq, In z (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))) -> existsT A : MPropF, (GN p GUI s) z A)).
+         { intros. destruct (dec_init_rules z).
+         -- exists Top. apply GN_init_seq ; auto.
+         -- destruct (Compare_dec.lt_dec (length (usable_boxes z)) (length (usable_boxes s))).
+             ** destruct (IH z). unfold LexSeq. apply DLW_wf_lex.lex_cons ; auto. exists x0. apply GN_less_ub ; auto.
+             ** assert (J100: (forall x0 : Seq, In x0 (GLR_prems (nodupseq z)) -> existsT A : MPropF, GUI x0 A)).
+                 intros. apply IH with (s1:=x0) ; auto. unfold LexSeq. apply DLW_wf_lex.lex_cons ; auto. apply InT_In_Seq in H2. apply GLR_prems_less_ub in H2.
+                 rewrite <- ub_nodupseq in H2. apply InT_In_Seq in H1. pose (leq_ub_Canopy _ _ H1). rewrite <- ub_nodupseq in l.
+                 pose (leq_ub_unif s) ; lia. intros. pose (is_init_nodupseq z). apply f0. apply p0. unfold is_init ; left ; auto.
+                 epose (@imap _ _ GUI (fun (x : Seq) => In x (GLR_prems (nodupseq z))) J100 (GLR_prems (nodupseq z))). simpl in s0. destruct s0 ; auto.
+                 exists (Or (list_disj (restr_list_prop p (snd z))) (Or (list_disj (map Neg (restr_list_prop p (fst z)))) (list_disj (map Box x0)))).
+                 apply GN_less ; auto. }
+         epose (@imap Seq MPropF (GN p GUI s) (fun (x : Seq) => In x (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))) J10
+         (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list)))). simpl in s0. destruct s0 ; auto.
+         exists (Or (list_disj (restr_list_prop p (snd s))) (Or (list_disj (map Neg (restr_list_prop p (fst s))))
+         (Or (list_disj (map Box x)) (Diam (list_conj x0))))). apply GUI_critic_not_init ; auto.
+    -- assert ((forall x : Seq, In x (Canopy (nodupseq s)) -> {x0 : MPropF | GUI x x0})).
+        intros. apply IH with (s1:=x) ; auto. destruct (Canopy_LexSeq (nodupseq s) x) ; auto.
+        apply InT_In_Seq ; auto. subst. exfalso. apply f. apply critical_nodupseq. apply InT_In_Seq in H ; apply Canopy_critical in H ; auto.
+        apply LexSeq_nodupseq ; auto.
+        epose (@imap _ _ GUI (fun (x : Seq) => In x (Canopy (nodupseq s))) H (Canopy (nodupseq s))). simpl in s0. destruct s0 ; auto.
+        exists (list_conj x). apply GUI_not_critic ; auto.
+Defined.
+ +
+  Fact GUI_inv_empty_seq {s A} : GUI s A -> s = ([],[]) -> Bot = A.
+  Proof. intros. pose (GUI_empty_seq H0). apply (GUI_fun _ _ _ g H). Qed.
+ +
+  Fact GUI_inv_critic_init {s A} : GUI s A -> critical_Seq s -> is_init s -> Top = A.
+  Proof. intros. pose (GUI_critic_init H0 X). apply (GUI_fun _ _ _ g H). Qed.
+ +
+  Fact GUI_inv_not_critic {s A l} : GUI s A -> (critical_Seq s -> False) ->
+                           (Gimap GUI (Canopy (nodupseq s)) l) ->
+                           ((list_conj l) = A).
+  Proof.
+  intros. pose (GUI_not_critic H0 H1). apply (GUI_fun _ _ _ g H).
+  Qed.
+ +
+  Fact GUI_inv_critic_not_init {s A l0 l1} : GUI s A -> critical_Seq s ->
+                           (s <> ([],[])) ->
+                           (is_init s -> False) ->
+                           (Gimap GUI (GLR_prems (nodupseq s)) l0) ->
+                           (Gimap (GN p GUI s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []))) l1) ->
+                           ((Or (list_disj (restr_list_prop p (snd s)))
+                                                     (Or (list_disj (map Neg (restr_list_prop p (fst s))))
+                                                     (Or (list_disj (map Box l0))
+                                                     (Diam (list_conj l1))))) = A).
+  Proof.
+  intros. pose (GUI_critic_not_init H0 H1 H2 H3 H4). apply (GUI_fun _ _ _ g H).
+  Qed.
+ +
+  Let UI_pwc : forall x, sig (GUI x).
+  Proof.
+  apply GUI_tot.
+  Qed.
+ +
+  Definition UI x := proj1_sig (UI_pwc x).
+ +
+  Fact UI_spec x : GUI x (UI x).
+  Proof. apply (proj2_sig _). Qed.
+ +
+  Lemma UI_GUI : forall x A, UI x = A <-> GUI x A.
+  Proof.
+  intros. split ; intro ; subst.
+  apply UI_spec. unfold UI. destruct UI_pwc. simpl.
+  apply GUI_fun with (x:=x) ; auto.
+  Qed.
+ +
+  End UI.
+ +
+  Section N.
+ +
+  Definition N_pwc : forall p s0 s, sig (GN p (GUI p) s0 s).
+  Proof.
+  intros. destruct (dec_init_rules s).
+  - assert (is_init s) ; auto. exists Top. apply GN_init_seq ; auto.
+  - assert (is_init s -> False) ; auto.
+    destruct (Compare_dec.lt_dec (length (usable_boxes s)) (length (usable_boxes s0))).
+    + exists (UI p s). apply GN_less_ub ; auto ; apply UI_GUI ; auto.
+    + assert (J100: (forall x0 : Seq, In x0 (GLR_prems (nodupseq s)) -> existsT A : MPropF, GUI p x0 A)).
+       intros. apply GUI_tot.
+       epose (@imap _ _ (GUI p) (fun (x : Seq) => In x (GLR_prems (nodupseq s))) J100 (GLR_prems (nodupseq s))). simpl in s1. destruct s1 ; auto.
+       exists (Or (list_disj (restr_list_prop p (snd s))) (Or (list_disj (map Neg (restr_list_prop p (fst s)))) (list_disj (map Box x)))).
+       apply GN_less ; auto.
+  Qed.
+ +
+  Variables (p : string). (* Propositional variable we consider. *)
+ +
+  Definition N s0 s := proj1_sig (N_pwc p s0 s).
+ +
+  Fact N_spec s0 s : GN p (GUI p) s0 s (N s0 s).
+  Proof. apply (proj2_sig _). Qed.
+ +
+  Fact GN_inv_init {s0 s A} : GN p (GUI p) s0 s A -> is_init s -> Top = A.
+  Proof. destruct 1 as [ Inits | ? ? ? Inits | ] ; intros; trivial ; exfalso ; auto. Qed.
+ +
+  Fact GN_inv_noinit_lessub {s0 s A φ} : GN p (GUI p) s0 s A -> (is_init s -> False) ->
+                           (length (usable_boxes s) < length (usable_boxes s0)) ->
+                           GUI p s φ ->
+                           φ = A.
+  Proof. destruct 1 as [ Inits | ? ? ? Inits | ] ; intros; trivial ; auto. 1, 3: exfalso ; auto.
+             apply (GUI_fun p s) ; auto. Defined.
+ +
+  Fact GN_inv_noinit_nolessub {s0 s A l} : GN p (GUI p) s0 s A -> (is_init s -> False) ->
+                           ((length (usable_boxes s) < length (usable_boxes s0)) -> False) ->
+                           (Gimap (GUI p) (GLR_prems (nodupseq s)) l) ->
+          (Or (list_disj (restr_list_prop p (snd s))) (Or (list_disj (map Neg (restr_list_prop p (fst s)))) (list_disj (map Box l)))) = A.
+  Proof. destruct 1 as [ Inits | ? ? ? Inits | ] ; intros; trivial ; auto. 1, 2: exfalso ; auto.
+              pose (Gimap_fun _ _ (GUI p) (GUI_fun p) _ _ _ H1 H4). rewrite e. auto. Defined.
+ +
+  Hint Resolve N_spec : core.
+ +
+  End N.
+ +
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_irred_high_level.html b/GL.Interpolation.UIGL_irred_high_level.html new file mode 100644 index 0000000..e4eebaf --- /dev/null +++ b/GL.Interpolation.UIGL_irred_high_level.html @@ -0,0 +1,144 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_irred_high_level

+ +
+(**************************************************************)
+(*   Copyright Dominique Larchey-Wendling *                 *)
+(*                                                            *)
+(*                             * Affiliation LORIA -- CNRS  *)
+(**************************************************************)
+(*      This file is distributed under the terms of the       *)
+(*         CeCILL v2.1 FREE SOFTWARE LICENSE AGREEMENT        *)
+(**************************************************************)
+ +
+Require Import List Relations Utf8.
+ +
+Import ListNotations.
+ +
+#[local] Infix "∈" := (@In _) (at level 70, no associativity).
+ +
+Definition list_is_nil {X} (l : list X) : { l = [] } + { l [] }.
+Proof. now destruct l; [ left | right ]. Qed.
+ +
+Section irred_high_level.
+ +
+  Variables (X : Type)
+            (f : X list X)
+            (f_wf : well_founded (λ u v, u f v))
+            (irred : X list X)
+            (irred_nil : x, f x = [] irred x = [x])
+            (irred_not : x, f x [] irred x = flat_map irred (f x))
+            .
+ +
+  Fact irred_max x y : y irred x f y = [].
+  Proof.
+    induction (f_wf x) as [ x _ IHx ] in y.
+    destruct (list_is_nil (f x)) as [ H | H ].
+    + rewrite irred_nil; auto.
+      now intros [ <- | [] ].
+    + rewrite irred_not, in_flat_map; auto.
+      intros (z & ? & ?); eauto.
+  Qed.
+ +
+  Fact irred_reach x y : y irred x clos_refl_trans _ (λ u v, u f v) y x.
+  Proof.
+    induction (f_wf x) as [ x _ IHx ] in y.
+    destruct (list_is_nil (f x)) as [ H | H ].
+    + rewrite irred_nil; auto.
+      intros [ <- | [] ]; constructor 2.
+    + rewrite irred_not, in_flat_map; auto.
+      intros (z & Hz1 & Hz2).
+      constructor 3 with z; auto.
+      now constructor 1.
+  Qed.
+ +
+  Hint Resolve in_eq : core.
+ +
+  Theorem irred_high_level_spec x y : y irred x f y = [] clos_refl_trans _ (λ u v, u f v) y x.
+  Proof.
+    split.
+    + split.
+      * now apply irred_max with x.
+      * now apply irred_reach.
+    + intros (H1 & H2); revert H2 H1.
+      rewrite clos_rt_rtn1_iff.
+      induction 1 as [ | x z H1 H2 IH2 ]; intros H.
+      * rewrite irred_nil; auto.
+      * rewrite irred_not, in_flat_map.
+        - exists x; auto.
+        - now intros e; rewrite e in H1.
+  Qed.
+ +
+  Section provability.
+ +
+    Variables (P : X Prop)
+              (HP : x, f x [] P x Forall P (f x)).
+ +
+    Theorem irred_provability x : P x Forall P (irred x).
+    Proof.
+      induction (f_wf x) as [ x _ IHx ].
+      destruct (list_is_nil (f x)) as [ H | H ].
+      + rewrite irred_nil; auto.
+        split.
+        * repeat (constructor; auto).
+        * now inversion 1.
+      + rewrite irred_not; auto.
+        rewrite Forall_flat_map, HP; auto.
+        rewrite !Forall_forall.
+        split; firstorder.
+    Qed.
+ +
+  End provability.
+ +
+End irred_high_level.
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_irred_short.html b/GL.Interpolation.UIGL_irred_short.html new file mode 100644 index 0000000..60da2c4 --- /dev/null +++ b/GL.Interpolation.UIGL_irred_short.html @@ -0,0 +1,334 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_irred_short

+ +
+(**************************************************************)
+(*   Copyright Dominique Larchey-Wendling *                 *)
+(*                                                            *)
+(*                             * Affiliation LORIA -- CNRS  *)
+(**************************************************************)
+(*      This file is distributed under the terms of the       *)
+(*         CeCILL v2.1 FREE SOFTWARE LICENSE AGREEMENT        *)
+(**************************************************************)
+ +
+
+ +
+Certification of + +
+ + let rec flatmap f = function + | -> + | x::l -> f x ++ flatmap f l + +
+ + let rec irred f x = + match f x with + | -> x + | _ -> flatmap (irred f) (f x) + +
+ + by extraction. + +
+ + Following a question by Ian Schillito + Also look at the following PR + +
+ + https://github.com/DmxLarchey/Kruskal-Trees/pull/5 + +
+ + +
+
+ +
+(* 
+   This is a standalone file, directly compile with
+
+      coqc irred.v 
+ *)

+ +
+Require Import List Utf8 Extraction.
+Import ListNotations.
+ +
+#[local] Infix "∈" := (@In _) (at level 70, no associativity).
+#[local] Hint Resolve in_eq in_cons : core.
+ +
+Definition list_is_nil {X} (l : list X) : { l = [] } + { l [] }.
+Proof. now destruct l; [ left | right ]. Defined.
+ +
+
+ +
+Directly via Fix_F after cleaning up from Braga using + the domain Dirred := Acc (λ u v, u ∈ f v) directly +
+
+Section flatmap.
+ +
+  Variables (X : Type)
+            (F : X list X Prop)
+            (D : X Prop)
+            (f : x, D x sig (F x)).
+ +
+  Implicit Type (l : list X).
+ +
+  Inductive Gflatmap : list X list X Prop :=
+    | Gfm_nil : Gflatmap [] []
+    | Gfm_cons {x y l m} : F x y
+                          Gflatmap l m
+                          Gflatmap (x::l) (y++m).
+ +
+  Hint Constructors Gflatmap : core.
+ +
+  Fact Gflatmap_inv_left l m :
+        Gflatmap l m
+       match l with
+        | [] => [] = m
+        | x::l => y m', F x y Gflatmap l m' m = y++m'
+        end.
+  Proof. destruct 1; eauto. Qed.
+ +
+  Fact Gflatmap_inv_sg_left x m : Gflatmap [x] m F x m.
+  Proof.
+    intros (y & ? & ? & <-%Gflatmap_inv_left & ->)%Gflatmap_inv_left.
+    now rewrite app_nil_r.
+  Qed.
+ +
+  Fact Gflatmap_app_inv_left l1 l2 m :
+        Gflatmap (l1++l2) m
+       m1 m2, Gflatmap l1 m1 Gflatmap l2 m2 m = m1++m2.
+  Proof.
+    induction l1 as [ | x l1 IH1 ] in m |- *; simpl.
+    + exists [], m; auto.
+    + intros (y & m' & H1 & (m1 & m2 & H2 & H3 & ->)%IH1 & ->)%Gflatmap_inv_left.
+      exists (y++m1), m2; rewrite app_assoc; auto.
+  Qed.
+ +
+  Fixpoint flatmap l : (x, x l D x) sig (Gflatmap l).
+  Proof.
+    refine (match l with
+    | [] => λ _ , exist _ [] Gfm_nil
+    | x::l => λ dl, let (y,hy) := f x _ in
+                    let (m,hm) := flatmap l _ in
+                    exist _ (y++m) (Gfm_cons hy hm)
+    end); auto.
+  Defined.
+ +
+  Variables (g : X list X) (Hg : x, F x (g x)).
+ +
+  Fact Gflatmap_flat_map l : Gflatmap l (flat_map g l).
+  Proof. induction l; simpl; now constructor. Qed.
+ +
+End flatmap.
+ +
+Arguments Gflatmap {X} _.
+Arguments flatmap {X} _ {D} _ {l}.
+ +
+Section irred.
+ +
+  Variables (X : Type) (f : X list X).
+ +
+  Implicit Type l : list X.
+ +
+  Unset Elimination Schemes.
+ +
+
+ +
+Because of nesting, induction principles are too weak, + see below for better ones +
+
+ +
+  Inductive Girred : X list X Prop :=
+    | Girred_nil {x} : f x = []
+                        Girred x [x]
+    | Girred_not {x l} : f x []
+                        Gflatmap Girred (f x) l
+                        Girred x l.
+ +
+  Set Elimination Schemes.
+ +
+  Fact Girred_inv_nil {x l} : Girred x l f x = [] [x] = l.
+  Proof. destruct 1 as [ | ? ? Hx ]; intros; trivial; now destruct Hx. Qed.
+ +
+  Fact Girred_inv_not {x l} : Girred x l f x [] Gflatmap Girred (f x) l.
+  Proof. destruct 1; intros G; trivial; now destruct G. Defined.
+ +
+  Hint Constructors Gflatmap Girred : core.
+  Hint Resolve Girred_inv_nil Girred_inv_not : core.
+ +
+  Section Girred_ind.
+ +
+    Variables (P : list X list X Prop)
+              (Q : X list X Prop)
+
+              (HP0 : P [] [])
+              (HP1 : x y l m, Girred x y Q x y Gflatmap Girred l m P l m P (x::l) (y++m))
+
+              (HQ0 : x, f x = [] Q x [x])
+              (HQ1 : x m, f x [] Gflatmap Girred (f x) m P (f x) m Q x m).
+ +
+    Fixpoint Girred_ind x m (dxm : Girred x m) { struct dxm } : Q x m.
+    Proof.
+      destruct (list_is_nil (f x)) as [ H | H ].
+      + destruct (Girred_inv_nil dxm H); auto.
+      + apply HQ1; auto.
+        generalize (Girred_inv_not dxm H).
+        clear dxm H.
+        induction 1; eauto.
+    Qed.
+ +
+  End Girred_ind.
+ +
+  Lemma Girred_fun : x l, Girred x l (λ x l, m, Girred x m l = m) x l.
+  Proof.
+    (* the property which is proved for (Gflatmap Girred) cannot be guessed by unification *)
+    apply Girred_ind with (P := fun l m1 => m2, Gflatmap Girred l m2 m1 = m2); eauto.
+    + now intros ? ?%Gflatmap_inv_left.
+    + intros ? ? ? ? ? ? ? ? ? (y' & m' & ? & ? & ->)%Gflatmap_inv_left; f_equal; eauto.
+  Qed.
+ +
+
+ +
+We build irred packed with conformity to Girred by Fix_F + induction over Acc (λ u v, u ∈ f v) x directly +
+
+  Let irred_pwc : x (dx : Acc (λ u v, u f v) x), sig (Girred x).
+  Proof.
+    refine (Fix_F _ (λ x irred_pwc,
+      match list_is_nil (f x) with
+      | left Hxf => exist _ [x] _
+      | right Hxf => let (m,hm) := flatmap Girred irred_pwc (λ _ h, h) in
+                     exist _ m _
+      end)); auto.
+  Defined.
+ +
+
+ +
+Now we can instanciate for _ ∈ f _ is well founded + and define irred as a total function +
+
+ +
+  Hypothesis hf : well_founded (λ u v, u f v).
+ +
+  Definition irred x := proj1_sig (irred_pwc x (hf x)).
+ +
+  Fact irred_spec x : Girred x (irred x).
+  Proof. apply (proj2_sig _). Qed.
+ +
+  Hint Resolve irred_spec : core.
+ +
+
+ +
+We conclude with fixpoint equations +
+
+ +
+  Fact irred_nil x : f x = [] irred x = [x].
+  Proof. intros; eapply Girred_fun; eauto. Qed.
+ +
+  Hint Resolve Gflatmap_flat_map : core.
+ +
+  Fact irred_not x : f x [] irred x = flat_map irred (f x).
+  Proof. intros; eapply Girred_fun; eauto. Qed.
+ +
+End irred.
+ +
+Arguments Girred {X}.
+Arguments irred {X f}.
+ +
+
+
+ +
+ + + diff --git a/GL.Interpolation.UIGL_nodupseq.html b/GL.Interpolation.UIGL_nodupseq.html new file mode 100644 index 0000000..4691a07 --- /dev/null +++ b/GL.Interpolation.UIGL_nodupseq.html @@ -0,0 +1,641 @@ + + + + + + + + + + + + + +
+
+

GL.Interpolation.UIGL_nodupseq

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat.
+Require Import Lia.
+ +
+Require Import general_export.
+ +
+Require Import GLS_export.
+ +
+Require Import UIGL_Def_measure.
+Require Import UIGL_Canopy.
+Require Import UIGL_irred_short.
+Require Import UIGL_basics.
+Require Import UIGL_LexSeq.
+Require Import UIGL_PermutationT.
+Require Import UIGL_PermutationTS.
+ +
+  Section nodupseq.
+ +
+  Definition nodupseq (s : Seq) := (nodup eq_dec_form (fst s), nodup eq_dec_form (snd s)).
+ +
+  End nodupseq.
+ +
+  Lemma nodup_app : forall l0 l1 l2, (nodup eq_dec_form l0 = nodup eq_dec_form l1) -> (nodup eq_dec_form (l0 ++ l2) = nodup eq_dec_form (l1 ++ l2)).
+  Proof.
+  induction l0.
+  - simpl ; intros. assert (l1 = []). destruct l1 ; auto. exfalso. simpl in H. destruct (in_dec eq_dec_form m l1).
+    apply (nodup_In eq_dec_form) in i. rewrite <- H in i ; inversion i. inversion H. subst. simpl. auto.
+  - induction l1.
+    + simpl ; intros. destruct (in_dec eq_dec_form a l0) ; simpl in *.
+       assert (l0 = []). apply (nodup_In eq_dec_form) in i. rewrite H in i. inversion i. subst. simpl. inversion i. inversion H.
+    + simpl in * ; intros. destruct (in_dec eq_dec_form a l0) ; simpl in *. destruct (in_dec eq_dec_form a0 l1) ; simpl in *.
+       destruct (in_dec eq_dec_form a (l0 ++ l2)) ; simpl in * ; auto. destruct (in_dec eq_dec_form a0 (l1 ++ l2)) ; simpl in * ; auto.
+       exfalso. apply n. apply in_or_app ; auto. exfalso. apply n. apply in_or_app ; auto.
+       destruct (in_dec eq_dec_form a (l0 ++ l2)). destruct (in_dec eq_dec_form a0 (l1 ++ l2)) ; simpl in * ; auto.
+       apply in_app_or in i1. destruct i1. exfalso ; auto. pose (IHl0 (a0 :: l1) l2). simpl in e.
+       assert (nodup eq_dec_form (l0 ++ l2) = (if in_dec eq_dec_form a0 (l1 ++ l2) then nodup eq_dec_form (l1 ++ l2) else a0 :: nodup eq_dec_form (l1 ++ l2))).
+       apply e. clear e. destruct (in_dec eq_dec_form a0 l1) ; auto. exfalso ; auto. clear e. destruct (in_dec eq_dec_form a0 (l1 ++ l2)).
+       auto. exfalso. apply n0 ; apply in_or_app ; auto. pose (IHl0 (a0 :: l1) l2). simpl in e.
+       assert (nodup eq_dec_form (l0 ++ l2) = (if in_dec eq_dec_form a0 (l1 ++ l2) then nodup eq_dec_form (l1 ++ l2) else a0 :: nodup eq_dec_form (l1 ++ l2))).
+       apply e. clear e. destruct (in_dec eq_dec_form a0 l1) ; auto. exfalso ; auto. clear e. destruct (in_dec eq_dec_form a0 (l1 ++ l2)) ; auto.
+       exfalso ; auto. destruct (in_dec eq_dec_form a0 (l1 ++ l2)) ; simpl in * ; auto. apply in_app_or in i0. destruct i0.
+       exfalso ; auto. exfalso. apply n0. apply in_or_app ; auto. exfalso. apply n0. apply in_or_app ; auto.
+       destruct (in_dec eq_dec_form a0 l1) ; simpl in *. pose (IHl1 l2 H). rewrite e. destruct (in_dec eq_dec_form a0 (l1 ++ l2)) ; auto.
+       exfalso ; apply n0 ; apply in_or_app ; auto. inversion H ; subst.
+       destruct (in_dec eq_dec_form a0 (l0 ++ l2)) ; simpl in *. apply in_app_or in i ; destruct i. exfalso ; auto.
+       destruct (in_dec eq_dec_form a0 (l1 ++ l2)) ; simpl in *. apply in_app_or in i ; destruct i. exfalso ; auto.
+       apply IHl0 ; auto. exfalso ; apply n1 ; apply in_or_app ; auto.
+       destruct (in_dec eq_dec_form a0 (l1 ++ l2)) ; simpl in *. apply in_app_or in i ; destruct i. exfalso ; auto.
+       exfalso ; apply n1 ; apply in_or_app ; auto. rewrite IHl0 with (l1:=l1) ; auto.
+  Qed.
+ +
+  Lemma In_XBoxed_list : forall l A, In A (XBoxed_list (top_boxes l)) -> (In A (top_boxes l) \/ exists B, In B (top_boxes l) /\ B = Box A).
+  Proof.
+  induction l ; intros ; auto. destruct a ; simpl ; simpl in H ; auto.
+  destruct H ; subst. right. exists (Box A) ; auto. destruct H ; subst. left ; auto.
+  apply IHl in H. destruct H. left ; auto. right. firstorder.
+  Qed.
+ +
+  Lemma In_XBoxed_list_gen : forall l A, In A (XBoxed_list l) -> (In A l \/ exists B, In B l /\ B = Box A).
+  Proof.
+  induction l ; intros ; auto. destruct a ; simpl ; simpl in H ; auto.
+  destruct H ; auto. destruct H ; auto. apply IHl in H ; destruct H ; auto. destruct H. destruct H ; subst. right.
+  exists (Box A) ; split ; auto.
+  destruct H ; auto. destruct H ; auto. apply IHl in H ; destruct H ; auto. destruct H. destruct H ; subst. right.
+  exists (Box A) ; split ; auto.
+  destruct H ; auto. destruct H ; auto. apply IHl in H ; destruct H ; auto. destruct H. destruct H ; subst. right.
+  exists (Box A) ; split ; auto.
+  destruct H ; subst ; auto. right. exists (Box A) ; split ; auto. destruct H ; subst ; auto.
+  apply IHl in H. destruct H ; auto. destruct H. destruct H ; subst. right. exists (Box A) ; split ; auto.
+  Qed.
+ +
+  Lemma XBoxed_list_In : forall l A, In (Box A) (top_boxes l) -> In A (XBoxed_list (top_boxes l)).
+  Proof.
+  induction l ; simpl ; intros ; auto. destruct a ; simpl ; simpl in H ; auto. destruct H. inversion H ; subst. auto.
+  apply IHl in H ; auto.
+  Qed.
+ +
+  Lemma XBoxed_list_In_gen : forall l A, In (Box A) l -> In A (XBoxed_list l).
+  Proof.
+  induction l ; simpl ; intros ; auto. destruct a ; simpl ; simpl in H ; auto. 1-3: destruct H ; [inversion H | subst ; auto].
+  destruct H. inversion H ; subst. auto. right. right. apply IHl ; auto.
+  Qed.
+ +
+  Lemma XBoxed_list_In_unfold : forall l A, (exists B, In B (top_boxes l) /\ B = Box A) -> In A (XBoxed_list (top_boxes l)).
+  Proof.
+  induction l ; simpl ; intros ; auto. destruct H. destruct H ; auto.
+  destruct a ; simpl ; simpl in H ; auto. destruct H. destruct H. subst. destruct H.
+  inversion H ; subst ; auto. right. right. apply XBoxed_list_In ; auto.
+  Qed.
+ +
+Theorem critical_nodupseq: forall s, critical_Seq s <-> critical_Seq (nodupseq s).
+Proof.
+intros. split ; intro.
+- intros A HA. destruct s ; simpl in HA. apply H ; simpl. apply in_app_or in HA. apply in_or_app.
+  destruct HA. left ; apply nodup_In in H0 ; auto. right ; apply nodup_In in H0 ; auto.
+- intros A HA. destruct s ; simpl in HA. apply H ; simpl. apply in_app_or in HA. apply in_or_app.
+  destruct HA. left ; apply nodup_In ; auto. right ; apply nodup_In ; auto.
+Qed.
+ +
+Theorem is_init_nodupseq: forall s, (is_init s -> is_init (nodupseq s)) * (is_init (nodupseq s) -> is_init s).
+Proof.
+intros. split ; intro.
+- destruct X. destruct s0.
+  + inversion i ; subst. unfold nodupseq ; simpl. left. left.
+     assert (InT (# P) (nodup eq_dec_form (Γ0 ++ # P :: Γ1))). apply In_InT. apply nodup_In.
+     apply in_or_app ; right ; apply in_eq.
+     assert (InT (# P) (nodup eq_dec_form (Δ0 ++ # P :: Δ1))). apply In_InT. apply nodup_In.
+     apply in_or_app ; right ; apply in_eq.
+     apply InT_split in H. destruct H. destruct s. rewrite e.
+     apply InT_split in H0. destruct H0. destruct s. rewrite e0.
+     apply IdPRule_I.
+  + inversion i ; subst. unfold nodupseq ; simpl. left. right.
+     assert (InT (Box A) (nodup eq_dec_form (Γ0 ++ Box A :: Γ1))). apply In_InT. apply nodup_In.
+     apply in_or_app ; right ; apply in_eq.
+     assert (InT (Box A) (nodup eq_dec_form (Δ0 ++ Box A:: Δ1))). apply In_InT. apply nodup_In.
+     apply in_or_app ; right ; apply in_eq.
+     apply InT_split in H. destruct H. destruct s. rewrite e.
+     apply InT_split in H0. destruct H0. destruct s. rewrite e0.
+     apply IdBRule_I.
+  + inversion b ; subst. unfold nodupseq ; simpl. right.
+     assert (InT Bot (nodup eq_dec_form (Γ0 ++ Bot :: Γ1))). apply In_InT. apply nodup_In.
+     apply in_or_app ; right ; apply in_eq.
+     apply InT_split in H. destruct H. destruct s. rewrite e.
+     apply BotLRule_I.
+- destruct X. destruct s. destruct s0.
+  + inversion i ; subst. left. left.
+     assert (InT (# P) l). apply In_InT. rewrite <- (nodup_In eq_dec_form). rewrite <- H.
+     apply in_or_app ; right ; apply in_eq.
+     assert (InT (# P) l0). apply In_InT. rewrite <- (nodup_In eq_dec_form). rewrite <- H1.
+     apply in_or_app ; right ; apply in_eq.
+     apply InT_split in H0. destruct H0. destruct s. rewrite e.
+     apply InT_split in H2. destruct H2. destruct s. rewrite e0.
+     apply IdPRule_I.
+  + inversion i ; subst. left. right.
+     assert (InT (Box A) l). apply In_InT. rewrite <- (nodup_In eq_dec_form). rewrite <- H.
+     apply in_or_app ; right ; apply in_eq.
+     assert (InT (Box A) l0). apply In_InT. rewrite <- (nodup_In eq_dec_form). rewrite <- H1.
+     apply in_or_app ; right ; apply in_eq.
+     apply InT_split in H0. destruct H0. destruct s. rewrite e.
+     apply InT_split in H2. destruct H2. destruct s. rewrite e0.
+     apply IdBRule_I.
+  + inversion b ; subst. destruct s ; simpl in *. right.
+     assert (InT Bot l). apply In_InT. rewrite <- (nodup_In eq_dec_form). rewrite <- H.
+     apply in_or_app ; right ; apply in_eq.
+     apply InT_split in H0. destruct H0. destruct s. rewrite e.
+     apply BotLRule_I.
+Qed.
+ +
+  Lemma incl_nodup_subform_boxesLF : forall l,
+              (incl (subform_boxesLF l) (subform_boxesLF (nodup eq_dec_form l))) *
+              (incl (subform_boxesLF (nodup eq_dec_form l)) (subform_boxesLF l)).
+  Proof.
+  induction l ; simpl; intuition auto with *.
+  - intros A HA. destruct (in_dec eq_dec_form a l). apply a0. apply in_app_or in HA.
+    destruct HA. apply In_incl_subform_boxes with (A:=a) ; auto. apply In_remove_list_In_list in H ; auto.
+    simpl. apply in_app_or in HA. destruct HA. apply in_or_app ; auto. apply In_remove_list_In_list_not_In_remove_list in H.
+    destruct H. apply in_or_app ; right. apply not_removed_remove_list ; auto.
+  - intros A HA. destruct (in_dec eq_dec_form a l). apply b in HA. apply remove_list_is_in ; auto.
+    simpl in HA. apply in_app_or in HA. destruct HA. apply in_or_app ; auto. apply In_remove_list_In_list_not_In_remove_list in H.
+    destruct H. apply b in H. apply remove_list_is_in ; auto.
+  Qed.
+ +
+  Lemma incl_nodupseq_subform_boxesS : forall s,
+              (incl (subform_boxesS s) (subform_boxesS (nodupseq s))) *
+              (incl (subform_boxesS (nodupseq s)) (subform_boxesS s)).
+  Proof.
+  destruct s. split ; intros A HA ; unfold subform_boxesS in * ; simpl in *.
+  - apply in_app_or in HA ; destruct HA. apply in_or_app ; left.
+    pose (incl_nodup_subform_boxesLF l). destruct p. auto.
+    apply In_remove_list_In_list_not_In_remove_list in H. destruct H.
+    apply remove_list_is_in ; auto. pose (incl_nodup_subform_boxesLF l0). destruct p. auto.
+  - apply in_app_or in HA ; destruct HA. apply in_or_app ; left.
+    pose (incl_nodup_subform_boxesLF l). destruct p. auto.
+    apply In_remove_list_In_list_not_In_remove_list in H. destruct H.
+    apply remove_list_is_in ; auto. pose (incl_nodup_subform_boxesLF l0). destruct p. auto.
+  Qed.
+ +
+  Lemma incl_nodup_top_boxes : forall l,
+              (incl (top_boxes l) (top_boxes (nodup eq_dec_form l))) *
+              (incl (top_boxes (nodup eq_dec_form l)) (top_boxes l)).
+  Proof.
+  induction l ; simpl ; intuition auto with *.
+  - intros A HA. destruct (in_dec eq_dec_form a l). apply a0. destruct a ; auto. inversion HA ; subst ; auto.
+    apply is_box_in_top_boxes ; auto. eexists ; auto.
+    simpl. destruct a ; simpl in * ; auto. destruct HA ; auto.
+  - intros A HA. destruct (in_dec eq_dec_form a l). apply b in HA. destruct a ; auto. apply in_cons ; auto.
+    destruct a ; simpl in * ; auto. destruct HA ; auto.
+  Qed.
+ +
+  Lemma ub_nodupseq : forall s, length (usable_boxes s) = length (usable_boxes (nodupseq s)).
+  Proof.
+  intros. destruct s. unfold usable_boxes ; simpl.
+  assert (J1: NoDup (subform_boxesS (l, l0))). apply NoDup_subform_boxesS.
+  assert (J2: NoDup (subform_boxesS (nodupseq (l, l0)))). apply NoDup_subform_boxesS.
+  assert (J3: incl (subform_boxesS (l, l0)) (subform_boxesS (nodupseq (l, l0)))).
+  apply incl_nodupseq_subform_boxesS.
+  pose (remove_list_incr_decr2 _ _ (top_boxes (nodup eq_dec_form l)) J1 J2 J3).
+  assert (J4: incl (top_boxes (nodup eq_dec_form l)) (top_boxes l)). apply incl_nodup_top_boxes.
+  pose (remove_list_incr_decr3 (subform_boxesS (l, l0)) _ _ J4).
+  assert (J5: incl (subform_boxesS (nodupseq (l, l0))) (subform_boxesS (l, l0))).
+  apply incl_nodupseq_subform_boxesS.
+  pose (remove_list_incr_decr2 _ _ (top_boxes l) J2 J1 J5).
+  assert (J6: incl (top_boxes l) (top_boxes (nodup eq_dec_form l))). apply incl_nodup_top_boxes.
+  pose (remove_list_incr_decr3 (subform_boxesS (nodupseq (l, l0))) _ _ J6).
+  lia.
+  Qed.
+ +
+  Lemma n_imp_subformLF_nodup : forall l, n_imp_subformLF (nodup eq_dec_form l) <= n_imp_subformLF l.
+  Proof.
+  induction l ; simpl ; intuition. destruct (in_dec eq_dec_form a l) ; simpl ; lia.
+  Qed.
+ +
+  Lemma n_imp_subformS_nodupseq : forall s, n_imp_subformS (nodupseq s) <= n_imp_subformS s.
+  Proof.
+  intro s. destruct s. unfold n_imp_subformS ; simpl. pose (n_imp_subformLF_nodup l).
+  pose (n_imp_subformLF_nodup l0). lia.
+  Qed.
+ +
+Theorem LexSeq_nodupseq: forall s0 s1, LexSeq s0 (nodupseq s1) -> LexSeq s0 s1.
+Proof.
+pose (d:=LexSeq_ind (fun x => forall s1, LexSeq x (nodupseq s1) -> LexSeq x s1)).
+apply d. clear d. intros s0 IH s1 H. inversion H ; subst ; intuition.
+- rewrite <- ub_nodupseq in H3. unfold LexSeq. unfold less_thanS. unfold GLS_termination_measure.measure.
+  rewrite H3. apply DLW_wf_lex.lex_skip. apply DLW_wf_lex.lex_cons ; auto. inversion H1 ; subst.
+  inversion H2. apply Nat.lt_le_trans with (m:=n_imp_subformS (nodupseq s1)) ; auto.
+  apply n_imp_subformS_nodupseq.
+- rewrite <- ub_nodupseq in H5. unfold LexSeq. unfold measure.
+  unfold less_thanS. unfold GLS_termination_measure.measure. apply DLW_wf_lex.lex_cons ; auto.
+Qed.
+ +
+Theorem LexSeq_nodupseq_case: forall s, LexSeq (nodupseq s) s +
+  ((n_imp_subformS (nodupseq s) = n_imp_subformS s) * (length (usable_boxes s) = length (usable_boxes (nodupseq s)))).
+Proof.
+intro s. pose (ub_nodupseq s). pose (n_imp_subformS_nodupseq s).
+unfold LexSeq. unfold less_thanS ;unfold GLS_termination_measure.measure. rewrite <- e.
+destruct (Compare_dec.lt_dec (n_imp_subformS (nodupseq s)) (n_imp_subformS s)).
+- left. apply DLW_wf_lex.lex_skip. apply DLW_wf_lex.lex_cons ; auto.
+- right. split ; auto. lia.
+Qed.
+ +
+Theorem fixpoint_nodupseq: forall s, nodupseq s = nodupseq (nodupseq s).
+Proof.
+unfold nodupseq. intros ; simpl.
+assert (nodup eq_dec_form (fst s) = nodup eq_dec_form (nodup eq_dec_form (fst s))).
+symmetry. apply nodup_fixed_point ; auto. apply NoDup_nodup.
+assert (nodup eq_dec_form (snd s) = nodup eq_dec_form (nodup eq_dec_form (snd s))).
+symmetry. apply nodup_fixed_point ; auto. apply NoDup_nodup. rewrite <- H ; rewrite <- H0 ; auto.
+Qed.
+ +
+Theorem nodup_nil : forall (l : list MPropF), l = nil <-> nodup eq_dec_form l = nil.
+Proof.
+induction l ; intuition ; simpl. inversion H1. simpl in H1. destruct (in_dec eq_dec_form a l) ; auto. apply H0 in H1.
+exfalso. rewrite H1 in i ; apply in_nil in i ; auto. inversion H1.
+Qed.
+ +
+Theorem nodup_top_boxes : forall l, nodup eq_dec_form (top_boxes l) = top_boxes (nodup eq_dec_form l).
+Proof.
+induction l ; intuition ; simpl. destruct a as [n | | |]; simpl ; auto.
+destruct (in_dec eq_dec_form # n l) ; auto. destruct (in_dec eq_dec_form l) ; auto.
+destruct (in_dec eq_dec_form (a1 --> a2) l) ; auto.
+destruct (in_dec eq_dec_form (Box a) l) ; destruct (in_dec eq_dec_form (Box a) (top_boxes l)) ; auto.
+exfalso. apply n. apply is_box_in_top_boxes ; auto. eexists ; auto.
+exfalso. apply in_top_boxes in i. destruct i. destruct s. destruct s. destruct p ; subst ; auto.
apply n. inversion e ; subst. apply in_or_app ; right ; apply in_eq.
+simpl ; rewrite IHl ; auto.
+Qed.
+ +
+Theorem nodup_XBoxed_list : forall l, nodup eq_dec_form (XBoxed_list (nodup eq_dec_form l)) = nodup eq_dec_form (XBoxed_list l).
+Proof.
+induction l ; intuition ; simpl. destruct a as [n | | |]; simpl ; auto.
+- destruct (eq_dec_form # n # n). destruct (in_dec eq_dec_form # n l).
+  destruct (in_dec eq_dec_form # n (XBoxed_list l)) ; simpl ; auto. exfalso. apply n0.
+  apply list_preserv_XBoxed_list ; auto. destruct (in_dec eq_dec_form # n) ; auto ; simpl.
+  destruct (eq_dec_form # n # n) ; auto. destruct (in_dec eq_dec_form # n (XBoxed_list (nodup eq_dec_form l))) ; simpl ; auto.
+  exfalso. apply n1. apply In_XBoxed_list_gen in i. destruct i ; auto. exfalso ; auto. destruct H. destruct H ; subst.
+  apply XBoxed_list_In_gen. apply nodup_In ; auto. exfalso ; auto.
+  destruct (eq_dec_form # n # n) ; simpl ; auto. destruct (in_dec eq_dec_form # n (XBoxed_list (nodup eq_dec_form l))) ; simpl ; auto.
+  exfalso. apply In_XBoxed_list_gen in i. destruct i. apply n0. apply nodup_In in H ; auto.
+  destruct H. destruct H ; subst. apply n1. apply XBoxed_list_In_gen. apply nodup_In in H ; auto.
+  rewrite IHl ; auto. destruct (in_dec eq_dec_form # n (XBoxed_list (nodup eq_dec_form l))) ; simpl ; auto.
+  exfalso. apply n1. apply In_XBoxed_list_gen in i. destruct i. apply nodup_In in H. apply list_preserv_XBoxed_list ; auto.
+  destruct H. destruct H ; subst. apply XBoxed_list_In_gen. apply nodup_In in H ; auto.
+  exfalso ; auto. exfalso ; auto.
+- destruct (eq_dec_form Bot Bot). destruct (in_dec eq_dec_form Bot l).
+  destruct (in_dec eq_dec_form Bot (XBoxed_list l)) ; simpl ; auto. exfalso. apply n.
+  apply list_preserv_XBoxed_list ; auto. destruct (in_dec eq_dec_form Bot) ; auto ; simpl.
+  destruct (eq_dec_form Bot Bot) ; auto. destruct (in_dec eq_dec_form Bot (XBoxed_list (nodup eq_dec_form l))) ; simpl ; auto.
+  exfalso. apply n0. apply In_XBoxed_list_gen in i. destruct i ; auto. exfalso ; auto. destruct H. destruct H ; subst.
+  apply XBoxed_list_In_gen. apply nodup_In ; auto. exfalso ; auto.
+  destruct (eq_dec_form Bot Bot) ; simpl ; auto. destruct (in_dec eq_dec_form Bot (XBoxed_list (nodup eq_dec_form l))) ; simpl ; auto.
+  exfalso. apply In_XBoxed_list_gen in i. destruct i. apply n. apply nodup_In in H ; auto.
+  destruct H. destruct H ; subst. apply n0. apply XBoxed_list_In_gen. apply nodup_In in H ; auto.
+  rewrite IHl ; auto. destruct (in_dec eq_dec_form Bot (XBoxed_list (nodup eq_dec_form l))) ; simpl ; auto.
+  exfalso. apply n0. apply In_XBoxed_list_gen in i. destruct i. apply nodup_In in H. apply list_preserv_XBoxed_list ; auto.
+  destruct H. destruct H ; subst. apply XBoxed_list_In_gen. apply nodup_In in H ; auto.
+  exfalso ; auto. exfalso ; auto.
+- destruct (eq_dec_form (a1 --> a2) (a1 --> a2)). destruct (in_dec eq_dec_form (a1 --> a2) l).
+  destruct (in_dec eq_dec_form (a1 --> a2) (XBoxed_list l)) ; simpl ; auto. exfalso. apply n.
+  apply list_preserv_XBoxed_list ; auto. destruct (in_dec eq_dec_form (a1 --> a2)) ; auto ; simpl.
+  destruct (eq_dec_form (a1 --> a2) (a1 --> a2)) ; auto. destruct (in_dec eq_dec_form (a1 --> a2) (XBoxed_list (nodup eq_dec_form l))) ; simpl ; auto.
+  exfalso. apply n0. apply In_XBoxed_list_gen in i. destruct i ; auto. exfalso ; auto. destruct H. destruct H ; subst.
+  apply XBoxed_list_In_gen. apply nodup_In ; auto. exfalso ; auto.
+  destruct (eq_dec_form (a1 --> a2) (a1 --> a2)) ; simpl ; auto. destruct (in_dec eq_dec_form (a1 --> a2) (XBoxed_list (nodup eq_dec_form l))) ; simpl ; auto.
+  exfalso. apply In_XBoxed_list_gen in i. destruct i. apply n. apply nodup_In in H ; auto.
+  destruct H. destruct H ; subst. apply n0. apply XBoxed_list_In_gen. apply nodup_In in H ; auto.
+  rewrite IHl ; auto. destruct (in_dec eq_dec_form (a1 --> a2) (XBoxed_list (nodup eq_dec_form l))) ; simpl ; auto.
+  exfalso. apply n0. apply In_XBoxed_list_gen in i. destruct i. apply nodup_In in H. apply list_preserv_XBoxed_list ; auto.
+  destruct H. destruct H ; subst. apply XBoxed_list_In_gen. apply nodup_In in H ; auto.
+  exfalso ; auto. exfalso ; auto.
+- destruct (in_dec eq_dec_form (Box a)). destruct (eq_dec_form (Box a) a). exfalso.
+  assert (size (Box a) = size a). rewrite e ; auto. destruct a ; simpl in H ; lia.
+  destruct (in_dec eq_dec_form a (XBoxed_list l)) ; simpl ; auto. destruct (in_dec eq_dec_form (Box a) (XBoxed_list l)) ; simpl ; auto.
+  exfalso. apply n0. apply list_preserv_XBoxed_list ; auto. exfalso. apply n0. apply XBoxed_list_In_gen ; auto.
+  destruct (eq_dec_form (Box a) a). assert (size (Box a) = size a). rewrite e ; auto. destruct a ; simpl in H ; lia.
+  destruct (in_dec eq_dec_form a (XBoxed_list l)) ; simpl ; auto. destruct ( eq_dec_form (Box a) a).
+  assert (size (Box a) = size a). rewrite e ; auto. destruct a ; simpl in H ; lia.
+  destruct (in_dec eq_dec_form a (XBoxed_list (nodup eq_dec_form l))).
+  destruct (in_dec eq_dec_form (Box a) (XBoxed_list (nodup eq_dec_form l))) ; simpl ; auto.
+  destruct (in_dec eq_dec_form (Box a) (XBoxed_list l)) ; simpl ; auto. exfalso. apply n2.
+  apply In_XBoxed_list_gen in i1. destruct i1 ; auto. apply list_preserv_XBoxed_list ; apply nodup_In in H ; auto.
+  destruct H. destruct H ; subst. apply XBoxed_list_In_gen. apply nodup_In in H ; auto.
+  destruct (in_dec eq_dec_form (Box a) (XBoxed_list l)) ; simpl ; auto. 2: rewrite IHl ; auto.
+  exfalso. apply n2. apply In_XBoxed_list_gen in i1. destruct i1 ; auto. apply list_preserv_XBoxed_list ; apply nodup_In ; auto.
+  destruct H. destruct H ; subst. apply XBoxed_list_In_gen. apply nodup_In ; auto.
+  exfalso. apply n2. apply In_XBoxed_list_gen in i. destruct i ; auto. apply list_preserv_XBoxed_list ; apply nodup_In ; auto.
+  destruct H. destruct H ; subst. apply XBoxed_list_In_gen. apply nodup_In ; auto.
+  destruct (eq_dec_form (Box a) a). assert (size (Box a) = size a). rewrite e ; auto. destruct a ; simpl in H ; lia.
+  destruct (in_dec eq_dec_form a (XBoxed_list (nodup eq_dec_form l))). exfalso.
+  apply n1. apply In_XBoxed_list_gen in i. destruct i ; auto. apply list_preserv_XBoxed_list ; apply nodup_In in H ; auto.
+  destruct H. destruct H ; subst. apply XBoxed_list_In_gen. apply nodup_In in H ; auto.
+  destruct (in_dec eq_dec_form (Box a) (XBoxed_list (nodup eq_dec_form l))) ; simpl ; auto.
+  destruct (in_dec eq_dec_form (Box a) (XBoxed_list l)) ; simpl ; auto. rewrite IHl ; auto.
+  exfalso. apply n4. apply In_XBoxed_list_gen in i. destruct i ; auto. apply list_preserv_XBoxed_list ; apply nodup_In in H ; auto.
+  destruct H. destruct H ; subst. apply XBoxed_list_In_gen. apply nodup_In in H ; auto.
+  destruct (in_dec eq_dec_form (Box a) (XBoxed_list l)) ; simpl ; auto. 2: rewrite IHl ; auto.
+  exfalso. apply n4. apply In_XBoxed_list_gen in i. destruct i ; auto. apply list_preserv_XBoxed_list ; apply nodup_In ; auto.
+  destruct H. destruct H ; subst. apply XBoxed_list_In_gen. apply nodup_In ; auto.
+Qed.
+ +
+Theorem fixpoint_nodup: forall l, nodup eq_dec_form l = nodup eq_dec_form (nodup eq_dec_form l).
+Proof.
+intros ; simpl. symmetry. apply nodup_fixed_point ; auto. apply NoDup_nodup.
+Qed.
+ +
+Theorem nodupseq_GLR_prems : forall s0 s1, InT s1 (GLR_prems (nodupseq s0)) ->
+        existsT2 s2, (nodup eq_dec_form (fst s1) = nodup eq_dec_form (fst s2)) * (snd s1 = snd s2) * InT s2 (GLR_prems s0).
+Proof.
+intros s0 s1 H. unfold GLR_prems in *. destruct (finite_GLR_premises_of_S (nodupseq s0)) ; simpl in *.
+apply InT_flatten_list_InT_elem in H. destruct H. destruct p0. apply p in i0. inversion i0 ; subst.
+destruct s0 ; simpl in *. unfold nodupseq in * ; subst ; simpl in *. inversion i ; subst. 2: inversion H0. simpl.
+assert (InT (Box A) l0). apply In_InT. apply (nodup_In eq_dec_form). rewrite <- H2. apply in_or_app ; right ; apply in_eq.
+apply InT_split in H. destruct H. destruct s. subst.
+exists (XBoxed_list (top_boxes l) ++ [Box A], [A]). repeat split ; simpl ; auto.
+pose (nobox_gen_ext_top_boxes_identity X). rewrite e ; auto. apply nodup_app.
+rewrite <- nodup_top_boxes. rewrite nodup_XBoxed_list. auto.
+ +
+apply InT_trans_flatten_list with (bs:=[(XBoxed_list (top_boxes l) ++ [Box A], [A])]). apply InT_eq.
+apply (@GLR_help2 (XBoxed_list (top_boxes l) ++ [Box A], [A]) (l, x0 ++ Box A :: x1)).
+apply GLRRule_I. intros B HB. apply in_top_boxes in HB. destruct HB as [x2 [x3 [x4 p1]]].
+destruct p1 ; subst. eexists ; auto. apply top_boxes_nobox_gen_ext.
+Qed.
+ +
+  Theorem incl_ctr_L_hpadm : forall Γ0 Γ1 Δ (D: GLS_prv (Γ0 ++ Γ1, Δ)), incl Γ0 Γ1 ->
+          existsT2 (D0: GLS_prv (Γ1, Δ)), derrec_height D0 <= derrec_height D.
+  Proof.
+  induction Γ0 ; simpl ; intros ; intuition. exists D ; auto.
+  assert (InT a Γ1). apply In_InT. apply H. apply in_eq.
+  apply InT_split in H0. destruct H0. destruct s ; subst.
+  assert (J1: derrec_height D = derrec_height D). auto.
+  assert (J2: ctr_L a (a :: Γ0 ++ x ++ a :: x0, Δ) (a :: Γ0 ++ x ++ x0, Δ)).
+  pose (ctr_LI a [] (Γ0 ++ x) x0). simpl in c ; repeat rewrite <- app_assoc in c ; apply c.
+  pose (GLS_hpadm_ctr_L _ J1 J2). destruct s.
+  assert (J3: derrec_height x1 = derrec_height x1). auto.
+  assert (J4: list_exch_L (a :: Γ0 ++ x ++ x0, Δ) (Γ0 ++ x ++ a :: x0, Δ)).
+  pose (list_exch_LI [] [a] (Γ0 ++ x) [] x0). simpl in l0. repeat rewrite <- app_assoc in l0; auto.
+  pose (GLS_hpadm_list_exch_L x1 J3 J4). destruct s.
+  pose (IHΓ0 (x ++ a :: x0) Δ x2). destruct s.
+  intros A HA. apply H. apply in_cons ; auto.
+  exists x3. lia.
+  Qed.
+ +
+  Theorem incl_ctr_L : forall Γ0 Γ1 Δ, incl Γ0 Γ1 -> GLS_prv (Γ0 ++ Γ1, Δ) -> GLS_prv (Γ1, Δ).
+  Proof.
+  intros. pose (incl_ctr_L_hpadm _ _ _ X H). destruct s ; auto.
+  Qed.
+ +
+  Theorem incl_ctr_R_hpadm : forall Γ Δ0 Δ1 (D: GLS_prv (Γ, Δ0 ++ Δ1)), incl Δ0 Δ1 ->
+        existsT2 (D0: GLS_prv (Γ, Δ1)), derrec_height D0 <= derrec_height D.
+  Proof.
+  intros Γ Δ0. revert Γ. induction Δ0 ; simpl ; intros ; intuition. exists D ; auto.
+  assert (InT a Δ1). apply In_InT. apply H. apply in_eq.
+  apply InT_split in H0. destruct H0. destruct s ; subst.
+  assert (J1: derrec_height D = derrec_height D). auto.
+  assert (J2: ctr_R a (Γ, a :: Δ0 ++ x ++ a :: x0) (Γ, a :: Δ0 ++ x ++ x0)).
+  pose (ctr_RI a Γ [] (Δ0 ++ x) x0). simpl in c ; repeat rewrite <- app_assoc in c ; apply c.
+  pose (GLS_hpadm_ctr_R _ J1 J2). destruct s.
+  assert (J3: derrec_height x1 = derrec_height x1). auto.
+  assert (J4: list_exch_R (Γ, a :: Δ0 ++ x ++ x0) (Γ, Δ0 ++ x ++ a :: x0)).
+  pose (list_exch_RI Γ [] [a] (Δ0 ++ x) [] x0). simpl in l0. repeat rewrite <- app_assoc in l0; auto.
+  pose (GLS_hpadm_list_exch_R x1 J3 J4). destruct s.
+  pose (IHΔ0 Γ (x ++ a :: x0) x2). destruct s.
+  intros A HA. apply H. apply in_cons ; auto.
+  exists x3. lia.
+  Qed.
+ +
+  Theorem incl_ctr_R : forall Γ Δ0 Δ1, incl Δ0 Δ1 -> GLS_prv (Γ, Δ0 ++ Δ1) -> GLS_prv (Γ, Δ1).
+  Proof.
+  intros. pose (incl_ctr_R_hpadm _ _ _ X H). destruct s ; auto.
+  Qed.
+ +
+  Lemma nodup_id: forall l,
+    existsT2 ln, (existsT2 l2, (PermutationT l (l2 ++ ln)) * (incl l2 ln)) *
+                          (PermutationT ln (nodup eq_dec_form l)).
+  Proof.
+  induction l ; simpl ; intros ; intuition.
+  - exists []. split ; auto. 2: apply Permutation_PermutationT ; apply Permutation_refl. exists [].
+    rewrite app_nil_r. split ; auto. apply Permutation_PermutationT ; apply Permutation_refl.
+    intro ; auto.
+  - destruct IHl. destruct p. destruct s. destruct p0. destruct (in_dec eq_dec_form a l) ; simpl ; auto.
+    exists x. split ; auto. exists (a :: x0). simpl. split. apply Permutation_PermutationT. apply perm_skip.
+    apply Permutation_PermutationT ; auto. intros A HA. inversion HA ; subst ; auto.
+    apply Permutation_PermutationT in p0. pose (Permutation_in _ p0 i0). apply in_app_or in i1 ; destruct i1 ; auto.
+    exists (a :: x). split. exists x0. split. apply Permutation_PermutationT. apply Permutation_cons_app. apply Permutation_PermutationT ; auto.
+    intros A HA. apply in_cons ; auto.
+    apply Permutation_PermutationT. apply perm_skip. apply Permutation_PermutationT ; auto.
+  Qed.
+ +
+  Lemma nodupseq_id: forall s,
+    existsT2 sn, (existsT2 LHS RHS, (PermutationTS s (LHS ++ fst sn, RHS ++ snd sn)) * (incl LHS (fst sn)) * (incl RHS (snd sn))) *
+                          (PermutationTS sn (nodupseq s)).
+  Proof.
+  intros. unfold nodupseq in *.
+  destruct (nodup_id (fst s)). destruct p. destruct s0. destruct p0.
+  destruct (nodup_id (snd s)). destruct p1. destruct s0. destruct p2.
+  unfold PermutationTS ; simpl. exists (x, x1) ; simpl. repeat split ; auto.
+  exists x0. exists x2. split ; auto.
+  Qed.
+ +
+Lemma nodupseq_hpadm_prv_LR : forall s (D0: GLS_prv s), existsT2 (D1: GLS_prv (nodupseq s)), derrec_height D1 <= derrec_height D0.
+Proof.
+intros s D0.
+destruct (nodupseq_id s). destruct p. destruct s0. destruct s0. destruct p0. destruct p0.
+pose (PermutationTS_prv_hpadm _ D0 _ p0). destruct s0.
+pose (incl_ctr_L_hpadm x0 (fst x) (x1 ++ snd x) x2 i0). destruct s0.
+pose (incl_ctr_R_hpadm (fst x) x1 (snd x) x3 i). destruct s0. destruct x ; simpl in *.
+pose (PermutationTS_prv_hpadm _ x4 _ p). destruct s0. exists x ; lia.
+Qed.
+ +
+Lemma nodupseq_hpadm_prv_RL : forall s (D0: GLS_prv (nodupseq s)), existsT2 (D1: GLS_prv s), derrec_height D1 <= derrec_height D0.
+Proof.
+intros s D0.
+destruct (nodupseq_id s). destruct p. destruct s0. destruct s0. destruct p0. destruct p0.
+pose (PermutationTS_prv_hpadm _ D0 _ (PermutationTS_sym _ _ p)). destruct s0. destruct x ; simpl in *.
+assert (derrec_height x2 = derrec_height x2). auto.
+pose (@GLS_list_wkn_L _ [] l0 _ x2 H). simpl in s0. destruct (s0 x0).
+assert (derrec_height x = derrec_height x). auto.
+pose (@GLS_list_wkn_R _ _ [] l1 x H0). simpl in s1. destruct (s1 x1).
+apply PermutationTS_sym in p0. pose (PermutationTS_prv_hpadm _ x3 _ p0). destruct s2. exists x4 ; lia.
+Qed.
+ +
+Lemma nodupseq_prv : forall s, ((GLS_prv s) -> (GLS_prv (nodupseq s))) * ((GLS_prv (nodupseq s)) -> (GLS_prv s)).
+Proof.
+intros s. split ; intro.
+- destruct (nodupseq_id s). destruct p. destruct s0. destruct s0. destruct p0. destruct p0.
+  apply (PermutationTS_prv _ _ p). destruct x. pose (incl_ctr_L x0 l). apply g ; auto.
+  pose (incl_ctr_R (x0 ++ l) x1 l0). apply g0 ; auto. simpl in p0. apply (PermutationTS_prv _ _ p0) ; auto.
+- destruct (nodupseq_id s). destruct p. destruct s0. destruct s0. destruct p0. destruct p0. apply PermutationTS_sym in p0.
+  apply (PermutationTS_prv _ _ p0). pose (GLS_prv_list_wkn_L [] (fst x)). simpl in g. apply g.
+  epose (@GLS_prv_list_wkn_R _ [] (snd x)). simpl in g0. apply g0. destruct x ; simpl in *.
+  apply PermutationTS_sym in p. apply (PermutationTS_prv _ _ p) ; auto.
+Qed.
+ +
+Lemma nodupseq_prv_hpadm_LR : forall s (D0: GLS_prv s), existsT2 (D1: GLS_prv (nodupseq s)), derrec_height D1 <= derrec_height D0.
+Proof.
+intros s D0.
+destruct (nodupseq_id s). destruct p. destruct s0. destruct s0. destruct p0. destruct p0.
+pose (PermutationTS_prv_hpadm _ D0 _ p0). destruct s0.
+pose (incl_ctr_L_hpadm _ _ _ x2 i0). destruct s0.
+pose (incl_ctr_R_hpadm _ _ _ x3 i). destruct s0. destruct x.
+pose (PermutationTS_prv_hpadm _ x4 _ p). destruct s0. exists x. lia.
+Qed.
+ +
+Lemma nodupseq_prv_hpadm_RL : forall s (D0: GLS_prv (nodupseq s)), existsT2 (D1: GLS_prv s), derrec_height D1 <= derrec_height D0.
+Proof.
+intros s D0.
+destruct (nodupseq_id s). destruct p. destruct s0. destruct s0. destruct p0. destruct p0. apply PermutationTS_sym in p0.
+pose (PermutationTS_prv_hpadm _ D0 _ (PermutationTS_sym _ _ p)). destruct s0.
+assert (derrec_height x2 = derrec_height x2). auto. destruct x ; simpl in *.
+pose (GLS_list_wkn_L [] l0 x2 H). simpl in s0. destruct (s0 x0).
+assert (derrec_height x = derrec_height x). auto.
+pose (GLS_list_wkn_R [] l1 x H0). simpl in s1. destruct (s1 x1).
+pose (PermutationTS_prv_hpadm _ x3 _ p0). destruct s2. exists x4. lia.
+Qed.
+ +
+Lemma remove_Permutation : forall l a, In a l -> Permutation (nodup eq_dec_form l) (nodup eq_dec_form (a :: remove eq_dec_form a l)).
+  Proof.
+  induction l ; simpl ; intros ; intuition ; subst.
+  - destruct (in_dec eq_dec_form a0 l) ; simpl ; auto. destruct (eq_dec_form a0 a0) ; auto.
+    destruct (in_dec eq_dec_form a0 (remove eq_dec_form a0 l)) ; simpl ; auto. exfalso.
+    apply remove_not_in_anymore in i0 ; auto. apply IHl in i. simpl in i. destruct (in_dec eq_dec_form a0 (remove eq_dec_form a0 l)) ; auto.
+    exfalso ; auto. exfalso ; auto. destruct (eq_dec_form a0 a0) ; subst. 2: exfalso ; auto.
+    destruct (in_dec eq_dec_form a0 (remove eq_dec_form a0 l)) ; simpl ; auto. exfalso.
+    apply remove_not_in_anymore in i ; auto. apply perm_skip.
+    assert ((remove eq_dec_form a0 l) = l). apply notin_remove ; auto. rewrite H ; apply Permutation_refl.
+  - destruct (in_dec eq_dec_form a l) ; simpl ; auto. destruct (eq_dec_form a0 a) ; auto ; subst.
+    destruct (in_dec eq_dec_form a (remove eq_dec_form a l)) ; simpl ; auto. exfalso.
+    apply remove_not_in_anymore in i0 ; auto. apply IHl in i. simpl in i. destruct (in_dec eq_dec_form a (remove eq_dec_form a l)) ; auto.
+    exfalso ; auto. destruct (in_dec eq_dec_form a0 (a :: remove eq_dec_form a0 l)). inversion i0 ;subst.
+    exfalso ; auto. exfalso. apply remove_not_in_anymore in H ; auto. simpl.
+    destruct (in_dec eq_dec_form a (remove eq_dec_form a0 l)) ; simpl ; auto. apply IHl in H0.
+    simpl in H0. destruct (in_dec eq_dec_form a0 (remove eq_dec_form a0 l)) ; auto. exfalso.
+    apply remove_not_in_anymore in i1 ; auto. exfalso. apply n1. apply in_not_touched_remove ; auto.
+    destruct (eq_dec_form a0 a) ; subst. exfalso ; auto. destruct (in_dec eq_dec_form a0 (a :: remove eq_dec_form a0 l)) ; auto.
+    inversion i ; auto. exfalso ; subst ; auto. exfalso. apply remove_not_in_anymore in H ; auto.
+    simpl. destruct (in_dec eq_dec_form a (remove eq_dec_form a0 l)). exfalso.
+    apply n. apply In_remove_In_list in i ; auto.
+    apply Permutation_trans with (l':=(a :: a0 :: nodup eq_dec_form (remove eq_dec_form a0 l))).
+    apply perm_skip. apply IHl in H0. simpl in H0. destruct (in_dec eq_dec_form a0 (remove eq_dec_form a0 l)) ; auto.
+    exfalso. apply remove_not_in_anymore in i ; auto. apply perm_swap.
+  Qed.
+ +
+  Lemma incl_id: forall l0 l1, (incl l0 l1) ->
+    existsT2 l0n, (existsT2 l2, (PermutationT (nodup eq_dec_form l1) (l2 ++ l0n))) *
+                          (PermutationT l0n (nodup eq_dec_form l0)).
+  Proof.
+  induction l0 ; simpl ; intros ; intuition.
+  - exists []. split ; auto. 2: apply Permutation_PermutationT ; apply Permutation_refl.
+    exists (nodup eq_dec_form l1). rewrite app_nil_r. apply Permutation_PermutationT ; apply Permutation_refl.
+  - assert (incl l0 l1). intros A HA. apply H. apply in_cons ; auto. destruct (in_dec eq_dec_form a l0).
+    apply IHl0 in H0 ; auto. assert (incl l0 (remove eq_dec_form a l1)). intros A HA. apply in_not_touched_remove.
+    apply H0 ; auto. intro ; subst ; auto. apply IHl0 in H1. destruct H1. destruct p. destruct s. exists (a::x) ; split.
+    2: apply Permutation_PermutationT ; apply Permutation_PermutationT in p ; apply perm_skip ; auto.
+    exists x0. apply Permutation_PermutationT. apply Permutation_PermutationT in p0.
+    pose (Permutation_middle x0 x a). apply Permutation_trans with (l':=a :: x0 ++ x) ; auto.
+    apply Permutation_trans with (l':=nodup eq_dec_form (a :: remove eq_dec_form a l1)) ; auto.
+    apply remove_Permutation. apply H. apply in_eq.
+    simpl. destruct (in_dec eq_dec_form a (remove eq_dec_form a l1)). exfalso. apply remove_not_in_anymore in i ; auto.
+    apply perm_skip ; auto.
+  Qed.
+ +
+  Lemma incl_idS: forall s0 s1, (incl (fst s0) (fst s1)) -> (incl (snd s0) (snd s1)) ->
+    existsT2 s0n, (existsT2 LHS RHS, (PermutationTS (nodupseq s1) (LHS ++ fst s0n, RHS ++ snd s0n))) *
+                          (PermutationTS s0n (nodupseq s0)).
+  Proof.
+  intros. unfold nodupseq in *.
+  pose (incl_id _ _ H). destruct s. destruct p. destruct s.
+  pose (incl_id _ _ H0). destruct s. destruct p1. destruct s.
+  unfold PermutationTS ; simpl. exists (x, x1) ; simpl. split.
+  - exists x0. exists x2. split ; auto.
+  - split ; auto.
+  Qed.
+ +
+Lemma PermutationTS_nodupseq : forall s0 s1, PermutationTS s0 s1 -> PermutationTS (nodupseq s0) (nodupseq s1).
+Proof.
+intros. split ; destruct H ; apply PermutationT_nodupseq ; auto.
+Qed.
+
+
+ +
+ + + diff --git a/General.List_lemmasT.html b/General.List_lemmasT.html new file mode 100644 index 0000000..db4b3ba --- /dev/null +++ b/General.List_lemmasT.html @@ -0,0 +1,1328 @@ + + + + + + + + + + + + + +
+
+

General.List_lemmasT

+ +
+Require Import List.
+Import ListNotations.
+Require Import PeanoNat.
+Set Implicit Arguments.
+ +
+Require Import existsT.
+Require Import genT gen.
+ +
+Open Scope type_scope.
+ +
+Ltac app_assoc_solve G := rewrite <- (app_assoc G); reflexivity.
+Ltac app_assoc_solve2 G H := rewrite <- (app_assoc G); simpl;
+                             rewrite <- (app_assoc H); reflexivity.
+Ltac eapp_assoc_solve2 G H := erewrite <- (app_assoc G); simpl;
+                             erewrite <- (app_assoc H); reflexivity.
+Ltac app_assoc_hyp G H := rewrite <- (app_assoc G) in H.
+Ltac app_assoc_hyp_inv G H := rewrite <- (app_assoc G) in H; apply app_inv_head in H.
+ +
+Ltac list_assoc_l := repeat (rewrite !app_assoc || rewrite !app_comm_cons).
+Ltac list_assoc_r :=
+  repeat (rewrite <- !app_assoc || rewrite <- !app_comm_cons).
+Ltac list_app_nil := repeat (rewrite !app_nil_l || rewrite !app_nil_r).
+Ltac list_assoc_l_simp := repeat
+  (rewrite !app_assoc || rewrite !app_comm_cons || list_app_nil).
+Ltac list_assoc_r_simp := repeat
+  (rewrite <- !app_assoc || rewrite <- !app_comm_cons || list_app_nil).
+Ltac list_assoc_l_simp' := repeat
+  (rewrite !app_assoc || rewrite !app_comm_cons || rewrite !app_nil_l
+  || rewrite !app_nil_r).
+Ltac list_assoc_r_simp' := repeat
+  (rewrite <- !app_assoc || rewrite <- !app_comm_cons || rewrite !app_nil_l
+  || rewrite !app_nil_r).
+Ltac list_eq_assoc := list_assoc_r ; reflexivity.
+ +
+Lemma if_eq_rev_eq: forall {T} (a b : list T),
+  a = b -> (rev a = rev b).
+Proof. intros. subst. reflexivity. Qed.
+ +
+Lemma if_rev_eq: forall {T} (a b : list T),
+  (rev a = rev b) -> a = b.
+Proof. intros.
+pose (@if_eq_rev_eq T (rev a) (rev b) H).
+rewrite -> !rev_involutive in e.
+exact e.
+Qed.
+ +
+(* rewriting with this won't loop, useful following list_assoc_l *)
+Lemma cons_single A X (v : A) Y: X ++ v :: Y = X ++ [v] ++ Y.
+Proof. simpl. reflexivity. Qed.
+ +
+Lemma partition_2_2 : forall {A : Type} (l1 l2 l3 l4 : list A) a b,
+l1 ++ a :: l2 = l3 ++ b :: l4 ->
+  (exists l5, l1 = l3 ++ b :: l5 /\ l4 = l5 ++ a :: l2) \/
+  (l3 = l1 /\ a = b /\ l2 = l4) \/
+  (exists l5, l3 = l1 ++ a :: l5 /\ l2 = l5 ++ b :: l4).
+Proof.
+  induction l1; intros l2 l3 l4 b c H.
+  - simpl in *. destruct l3.
+    right. left. simpl in *. inversion H.
+    subst. apply conj. reflexivity. apply conj; reflexivity.
+    simpl in H. inversion H as [[H2 H3]].
+    subst. right. right. exists l3. apply conj; reflexivity.
+ +
+  - destruct l3. simpl in *. inversion H as [[H2 H3]].
+    subst. left. exists l1. apply conj; reflexivity.
+    simpl in H. inversion H as [[H2 H3]]. subst.
+    apply IHl1 in H3. destruct H3 as [[l5 [H4 H5]] | [[H4 H5] | [l5 [H4 H5]]]];
+                        subst.
+    + left. exists l5. simpl. apply conj; reflexivity.
+    + right. left. apply conj. reflexivity. assumption.
+    + right. right. exists l5. apply conj; reflexivity.
+Qed.
+ +
+Lemma partition_2_2T : forall {A : Type} (l1 l2 l3 l4 : list A) a b,
+l1 ++ a :: l2 = l3 ++ b :: l4 ->
+  (existsT2 l5, (l1 = l3 ++ b :: l5) * (l4 = l5 ++ a :: l2)) +
+  (((l3 = l1)* (a = b) * (l2 = l4)) +
+  (existsT l5, (l3 = l1 ++ a :: l5) * (l2 = l5 ++ b :: l4))).
+Proof.
+  induction l1; intros l2 l3 l4 b c H.
+  - simpl in *. destruct l3.
+    right. left. simpl in *. inversion H.
+    subst. repeat split.
+    simpl in H. inversion H as [[H2 H3]].
+    subst. right. right. exists l3. repeat split.
+ +
+  - destruct l3. simpl in *. inversion H as [[H2 H3]].
+    subst. left. exists l1. repeat split.
+    simpl in H. inversion H as [[H2 H3]]. subst.
+    apply IHl1 in H3. destruct H3 as [[l5 [H4 H5]] | [[[H4 H5]] | [l5 [H4 H5]]]];
+                        subst.
+    + left. exists l5. simpl. repeat split.
+    + right. left. repeat split.
+    + right. right. exists l5. repeat split.
+Qed.
+ +
+Lemma partition_3_2 : forall {A : Type} (Gam Delt : list A) G' H' Gam1 Delt1 Gam2 Delt2 G H J,
+    G ++ (Gam1, Delt1) :: H ++ (Gam2, Delt2) :: J = G' ++ (Gam, Delt) :: H' ->
+    (exists l, G = G' ++ (Gam,Delt) :: l /\ H' = l ++ (Gam1, Delt1) :: H ++ (Gam2, Delt2) :: J) \/
+    (G' = G /\ Gam1 = Gam /\ Delt1 = Delt /\ H' = H ++ (Gam2, Delt2) :: J) \/
+    (exists l1 l2, G' = G ++ (Gam1, Delt1) :: l1 /\
+                   H = l1 ++ (Gam, Delt) :: l2 /\
+                   H' = l2 ++ (Gam2, Delt2) :: J) \/
+    (G' = G ++ (Gam1,Delt1) :: H /\ Gam2 = Gam /\ Delt2 = Delt /\ J = H' ) \/
+    (exists l, G' = G ++ (Gam1, Delt1) :: H ++ (Gam2, Delt2) :: l /\
+               J = l++ (Gam, Delt) ::H').
+Proof.
+  intros A l1 m1 G' H' l2 m2 l3 m3 G H J.
+  revert G J H l1 m1 G' H' l2 m2 l3 m3.
+  induction G; intros J H l1 m1 G' H' l2 m2 l3 m3 H2.
+  - simpl in *. destruct G'.
+    right. left. simpl in H2. inversion H2.
+    repeat apply conj; reflexivity.
+    simpl in H2. inversion H2 as [[H3 H4]].
+    right. right. edestruct (partition_2_2 _ _ _ _ _ _ H4) as [H0 | [[H0 H5] | H0]].
+    + left. destruct H0 as [l5 [H0' HH]]. subst. exists G', l5.
+      repeat apply conj; try reflexivity.
+    + right. left. subst. inversion H2 as [H3]. apply app_inv_head in H3.
+      inversion H3.
+      repeat apply conj; reflexivity.
+    + right. right. destruct H0 as [l5 [H0' H5]]. exists l5.
+      subst. inversion H2. app_assoc_hyp_inv H H1. simpl in H1.
+      inversion H1.
+      repeat apply conj; reflexivity.
+  - simpl in *. destruct G'. simpl in *. left.
+     inversion H2 as [[H3 H4]].
+     exists G.
+     repeat apply conj; reflexivity.
+     simpl in H2. inversion H2 as [[H3 H4]].
+     apply IHG in H4.
+     destruct H4 as [ [ll [HH1 HH2]] |
+                      [[HH1 [HH2 [HH3]]] |
+                       [ [ll1 [ll2 [HH1 [HH2 HH3]]]] |
+                         [[HH1 [HH2 [HH3 HH4]]] | [ll [HH1 HH2]]]]]]; subst.
+     + left. exists ll.
+       repeat apply conj; reflexivity.
+     + right. left.
+       repeat apply conj; reflexivity.
+     + right. right. left. exists ll1. exists ll2.
+       repeat apply conj; reflexivity.
+     + right. right. right. left.
+       repeat apply conj; reflexivity.
+     + right. right. right. right. exists ll.
+       repeat apply conj; reflexivity.
+ +
+Unshelve.
+all : try assumption.
+Qed.
+ +
+Lemma eq_app_canc1 : forall {A : Type} (l1 l2 l2': list A),
+  (l1 ++ l2 = l1 ++ l2') <-> (l2 = l2').
+Proof. intros. unfold iff. split ; intros.
+  induction l1. simpl in H. exact H.
+  eapply IHl1. simpl in H. inversion H. reflexivity.
+  subst. reflexivity. Qed.
+ +
+Lemma eq_app_canc2 : forall {A : Type} (l1 l1' l2: list A),
+  (l1 ++ l2 = l1' ++ l2) <-> (l1 = l1').
+Proof. intros. unfold iff. split ; intros.
+  apply if_eq_rev_eq in H.
+  rewrite -> !rev_app_distr in H.
+  rewrite -> eq_app_canc1 in H.
+  apply if_rev_eq in H. exact H.
+  subst. reflexivity. Qed.
+ +
+Lemma app_cons_single : forall {A : Type} (l1 l2 : list A) a,
+  l1 ++ a :: l2 = (l1 ++ [a]) ++ l2.
+Proof.
+  induction l1; intros. reflexivity.
+  simpl. rewrite IHl1. reflexivity.
+Qed.
+ +
+Lemma partition_2_3 : forall {A : Type} (l1 l2 l3 l4 : list A) a b,
+    l1 ++ a :: b :: l2 = l3 ++ l4 ->
+    (l3 = l1 /\ l4 = a :: b :: l2) \/
+    (exists l5, l1 = l3 ++ l5 /\ l4 = l5 ++ a :: b :: l2) \/
+    (l3 = l1 ++ [a] /\ l4 = b :: l2) \/
+    (l3 = l1 ++ [a;b] /\ l4 = l2) \/
+    (exists l5, l3 = l1 ++ [a;b] ++ l5 /\ l2 = l5 ++ l4).
+Proof.
+  induction l1; intros *; intros H.
+  - destruct l3. left. auto.
+    right.
+    simpl in *. inversion H as [[H1 H2]]. subst.
+    destruct l3. simpl in *. subst.
+    right. left. auto.
+    simpl in H2. inversion H2 as [[H1 H3]].
+    subst. right. right. right. exists l3. auto.
+ +
+  - simpl in *. destruct l3. right. left.
+    exists (a::l1). auto.
+    simpl in *. inversion H as [[H1 H2]]. subst.
+    apply IHl1 in H2.
+    destruct H2 as [ [H3 H4] | [[l5 [H3 H4]] | [ [H3 H4] | [ [H3 H4] | [l5 [ H4 H5]]]]]];
+      subst.
+    + left. auto.
+    + inversion H as [H2]. app_assoc_hyp_inv l3 H2. subst. right. left.
+      exists l5. auto.
+    + inversion H as [H2]. rewrite <- app_assoc in H2.
+      apply app_inv_head in H2. simpl in H2. inversion H2 as [H3].
+      subst. right. right. left. apply conj; reflexivity.
+    + inversion H as [H2]. app_assoc_hyp_inv l1 H2. simpl in H2.
+      inversion H2 as [H3]. subst. right. right. right. left.
+      apply conj; reflexivity.
+    + subst. right. right. right. right. inversion H as [H2].
+      app_assoc_hyp_inv l1 H2. simpl in *. inversion H2. subst.
+      exists l5. apply conj; reflexivity.
+Qed.
+ +
+Lemma subst_dep : forall (T : Type) (G1 G2 : T) P (P2 : forall (G : T), P G -> nat) (D1 : P G1),
+    G1 = G2 ->
+    exists (D2 : P G2), P2 G1 D1 = P2 G2 D2.
+Proof.
+  intros T G1 G2 P P2 D1 Heq.
+  generalize dependent D1. subst.
+  intros D1. exists D1. reflexivity.
+Qed.
+ +
+Ltac finish_ht_admis_ex1 := simpl; apply le_n_S; assumption.
+Ltac finish_ht_admis_ex2 := simpl; apply le_n_S;
+                            eapply (Nat.le_trans _ _ _ _ _);
+                            assumption.
+Ltac find_trans_solve := match goal with
+               | [ H1 : ?n1 <= ?n2, H2 : ?n2 <= ?n3 |- ?n1 <= ?n3] =>
+                 apply (Nat.le_trans n1 n2 n3 H1 H2) end.
+Ltac finish_ht_admis_ex3 := simpl; apply le_n_S; find_trans_solve.
+Ltac ap_part_2_2 P1 l5 P3 P4 P5 :=
+  apply partition_2_2 in P1;
+  destruct P1 as [ [l5 [P3 P4]] | [ [P3 [P4 P5]] | [l5 [P3 P4]]]].
+ +
+Ltac ap_part_2_3 P5 l5 P55 := apply partition_2_3 in P5;
+    destruct P5 as [ [P5 PP5] | [ [l5 [P5 PP5]]
+ | [[P5 PP5] | [[P5 PP5] | [l5 [P5 PP5]]]]]].
+ +
+Lemma list_rearr1 : forall {A : Type} (a : A) G0 l5 H,
+      (G0 ++ a :: l5 ++ H) =
+           (((G0 ++ [a]) ++ l5) ++ H).
+Proof.
+  intros. rewrite app_cons_single.
+  rewrite app_assoc. reflexivity.
+Qed.
+ +
+Lemma list_rearr2 : forall {A : Type} (a : A) G0 l5 H,
+  ((G0 ++ [a]) ++ l5) ++ H = G0 ++ a :: l5 ++ H.
+Proof. intros. do 2 rewrite <- app_assoc. reflexivity. Qed.
+ +
+Lemma list_rearr4 : forall {T1 T2 T3 : Type} G (A B E : T1) (Delt : list T2)
+                           Gam1 Gam2 (delt : T3) H,
+    G ++ (Gam1 ++ E :: A :: B :: Gam2, Delt, delt) :: H =
+    G ++ ((Gam1 ++ [E]) ++ A :: B :: Gam2, Delt, delt) :: H.
+Proof. intros. rewrite <- app_assoc. reflexivity. Qed.
+ +
+Lemma list_rearr5 : forall {T1 T2 T3 : Type} G (E B : T1)
+                           Gam1 Gam2 (Delt : list T2) (delt : T3) H,
+    G ++ ((Gam1 ++ [E]) ++ B :: Gam2, Delt, delt) :: H =
+    G ++ (Gam1 ++ E :: B :: Gam2, Delt, delt) :: H.
+Proof. intros. rewrite <- app_assoc. reflexivity. Qed.
+ +
+Lemma list_rearr6 : forall {T1 T2 T3 : Type} (E : T1) G l5 Gam3 Gam2
+                           (Delt : list T2) (delt : T3) H,
+    G ++ (Gam3 ++ E :: l5 ++ Gam2, Delt, delt) :: H =
+    G ++ (((Gam3 ++ [E]) ++ l5) ++ Gam2, Delt, delt) :: H.
+Proof. intros. rewrite (app_cons_single Gam3).
+       rewrite (app_assoc _ l5). reflexivity.
+Qed.
+ +
+Lemma list_rearr7 : forall {T1 T2 T3 : Type} G (E : T1) l5 Gam3 Gam2
+                           (Delt : list T2) (delt : T3) H,
+G ++ (((Gam3 ++ [E]) ++ l5) ++ Gam2, Delt, delt) :: H =
+      G ++ (Gam3 ++ E :: l5 ++ Gam2, Delt, delt) :: H.
+Proof. intros. do 2 rewrite <- app_assoc. reflexivity. Qed.
+ +
+Lemma list_rearr8 : forall {T1 T2 T3 : Type} G Gam1 Gam2 (A B : T1)
+                           (Delt : list T2) (delt : T3) H,
G ++ ((Gam1 ++ [A; B]) ++ Gam2, Delt, delt) :: H =
+      G ++ (Gam1 ++ A :: B :: Gam2, Delt, delt) :: H.
+Proof. intros. rewrite <- app_assoc. reflexivity. Qed.
+ +
+Lemma list_rearr9 : forall {T1 T2 T3 : Type} G Gam1 Gam2 (A B : T1)
+                           (Delt : list T2) (delt : T3) H,
+G ++ (Gam1 ++ B :: A :: Gam2, Delt, delt) :: H =
+G ++ (((Gam1 ++ [B]) ++ [A]) ++ Gam2, Delt, delt) :: H.
+Proof. intros. rewrite (app_cons_single _ _ B);
+  rewrite (app_cons_single _ _ A). reflexivity.
+Qed.
+ +
+Lemma list_rearr10 : forall {T1 T2 T3 : Type} G Gam1 Gam4 (A B : T1) l5
+                           (Delt : list T2) (delt : T3) H,
+G ++ ((Gam1 ++ [A; B] ++ l5) ++ Gam4, Delt, delt) :: H =
+       G ++ (Gam1 ++ A :: B :: l5 ++ Gam4, Delt, delt) :: H.
+Proof. intros. rewrite <- app_assoc. reflexivity. Qed.
+ +
+Lemma list_rearr11 : forall {T1 T2 T3 : Type} G Gam1 Gam4 (A B : T1) l5
+                           (Delt : list T2) (delt : T3) H,
+G ++ (Gam1 ++ B :: A :: l5 ++ Gam4, Delt, delt) :: H =
+      G ++ ((((Gam1 ++ [B]) ++ [A]) ++ l5) ++ Gam4, Delt, delt) :: H.
+Proof.
+  intros. rewrite (app_cons_single _ _ B).
+  rewrite (app_cons_single _ _ A).
+  rewrite (app_assoc _ l5). reflexivity.
+Qed.
+ +
+Lemma list_rearr13 : forall {T : Type} a (G l5 H : list T),
+     G ++ a :: l5 ++ H = (G ++ a :: l5) ++ H.
+Proof.
+  intros. rewrite app_comm_cons. rewrite app_assoc.
+  reflexivity. Qed.
+ +
+Lemma list_rearr14 : forall {T : Type} a b (F G H : list T),
+  F ++ a :: (G ++ b :: H) = (F ++ a :: G) ++ b :: H.
+Proof.
+  intros. rewrite app_comm_cons. rewrite app_assoc.
+  reflexivity. Qed.
+ +
+Lemma list_rearr15 : forall {T Xt : Type} (F G H : list T) (X : Xt),
+  (F ++ (G ++ H), X) = ((F ++ G) ++ H, X).
+Proof. intros. rewrite app_assoc. reflexivity. Qed.
+ +
+Lemma list_rearr15_R : forall {T Xt : Type} (F G H : list T) (X : Xt),
+  (X, F ++ (G ++ H)) = (X, (F ++ G) ++ H).
+Proof. intros. rewrite app_assoc. reflexivity. Qed.
+ +
+Lemma list_rearr16' : forall {T : Type} (F G : list T) (a : T),
+  F ++ (a :: G) = (F ++ [a]) ++ G.
+Proof. intros. rewrite <- app_assoc. simpl. reflexivity. Qed.
+ +
+Lemma list_rearr16 : forall {T Xt : Type} (F G : list T) (a : T) (X : Xt),
+  (F ++ (a :: G), X) = ((F ++ [a]) ++ G, X).
+Proof. intros. rewrite <- app_assoc. simpl. reflexivity. Qed.
+ +
+Lemma list_rearr16_R : forall {T Xt : Type} (F G : list T) (a : T) (X : Xt),
+  (X, F ++ (a :: G)) = (X, (F ++ [a]) ++ G).
+Proof. intros. rewrite <- app_assoc. simpl. reflexivity. Qed.
+ +
+Lemma list_rearr17_R : forall {T1 T2 : Type} (Phi : T2) Delt1 (B A : T1) eqr3 U Psi2,
+(Phi, Delt1 ++ B :: A :: eqr3 ++ U :: Psi2) =
+(Phi, (Delt1 ++ B :: A :: eqr3) ++ U :: Psi2).
+Proof. intros. rewrite <- app_assoc. reflexivity. Qed.
+ +
+(* not sure if we ever need this *)
+Lemma list_rearr18 : forall {T : Type} (F G H : list T) (a : T),
+  (F ++ G ++ a :: H) = (F ++ G) ++ a :: H.
+Proof. intros. apply app_assoc. Qed.
+ +
+Lemma list_rearr19 : forall {T : Type} (F G H : list T) (a : T),
+  (F ++ G) ++ a :: H = F ++ (G ++ [a]) ++ H.
+Proof. intros. list_assoc_r. simpl. reflexivity. Qed.
+ +
+Lemma list_rearr20 : forall {T : Type} (F G : list T) (a b : T),
+  F ++ a :: b :: G = F ++ [a ; b] ++ G.
+Proof. intros. list_assoc_r. simpl. reflexivity. Qed.
+ +
+Lemma list_rearr21 : forall {T : Type} (F G : list T) (a b : T),
+  (F ++ [a]) ++ b :: G = F ++ [a ; b] ++ G.
+Proof. intros. list_assoc_r. simpl. reflexivity. Qed.
+ +
+Lemma list_rearr22 : forall {T : Type} (F G : list T) (a b : T),
+  F ++ a :: b :: G = (F ++ [a]) ++ b :: G.
+Proof. intros. list_assoc_r. simpl. reflexivity. Qed.
+ +
+Lemma list_rearr23 : forall {T : Type} (b a : T) (F G : list T),
+  a :: F ++ b :: G = (a :: F) ++ b :: G.
+Proof. intros. list_assoc_r. simpl. reflexivity. Qed.
+ +
+Lemma cons_eq_app: forall (A : Type) (x y z : list A) (a : A),
+  a :: x = y ++ z -> y = [] /\ z = a :: x \/
+  exists (y' : list A), y = a :: y' /\ x = y' ++ z.
+Proof.
+intros.
+destruct y. simpl in H. subst. tauto.
+simpl in H.
+injection H.
+intros. right. subst.
+exists y. tauto.
+Qed.
+ +
+Lemma cons_eq_appT: forall (A : Type) (x y z : list A) (a : A),
+  a :: x = y ++ z -> sum ((y = []) * (z = a :: x))
+  (sigT (fun y' : list A => prod (y = a :: y') (x = y' ++ z))).
+Proof.
+intros.
+destruct y. simpl in H. subst. tauto.
+simpl in H.
+injection H.
+intros. right. subst.
+exists y. tauto.
+Qed.
+ +
+Lemma cons_eq_appT2: forall (A : Type) (x y z : list A) (a : A),
+    a :: x = y ++ z ->
+    ((y = []) * (z = a :: x)) +
+  existsT2 (y' : list A), (y = a :: y') * (x = y' ++ z).
+Proof.
+  intros.
+  destruct y. simpl in H. subst. tauto.
+  simpl in H.
+  injection H.
+  intros. right. subst.
+  exists y. tauto.
+Qed.
+ +
+Definition app_eq_cons (A : Type) (x y z : list A) (a : A) p :=
+  @cons_eq_app A x y z a (eq_sym p).
+ +
+Definition app_eq_consT2 (A : Type) (x y z : list A) (a : A) p :=
+  @cons_eq_appT2 A x y z a (eq_sym p).
+ +
+Lemma app_eq_nilT : forall (A : Type) (l l' : list A),
+    l ++ l' = [] -> (l = []) * (l' = []).
+Proof. destruct l; intros l' H. tauto. discriminate. Qed.
+ +
+Lemma app_eq_app: forall (A : Type) (w x y z : list A),
+  w ++ x = y ++ z -> exists (m : list A),
+    w = y ++ m /\ z = m ++ x \/ y = w ++ m /\ x = m ++ z.
+Proof.
+intro. intro.
+induction w.
+simpl. intros.
+exists y. rewrite H. tauto.
+intros. simpl in H.
+apply cons_eq_app in H.
+destruct H. destruct H. rewrite H. simpl.
+exists (a :: w). rewrite H0. simpl. tauto.
+destruct H. destruct H.
+apply IHw in H0. destruct H0. destruct H0. destruct H0.
+rewrite H. rewrite H0. rewrite H1. simpl.
+exists x1. tauto.
+destruct H0.
+rewrite H. rewrite H0. rewrite H1. simpl.
+exists x1. tauto.
+Qed.
+ +
+Lemma app_eq_appT: forall (A : Type) (w x y z : list A),
+  w ++ x = y ++ z -> sigT (fun m : list A =>
+    sum ((w = y ++ m) * (z = m ++ x)) ((y = w ++ m) * (x = m ++ z))).
+Proof. intro. intro. induction w.
+simpl. intros.
+exists y. rewrite H. tauto.
+intros. simpl in H.
+apply cons_eq_appT in H.
+destruct H. destruct p. subst. simpl.
+exists (a :: w). simpl. tauto.
+destruct s. destruct p.
+apply IHw in e0. destruct e0.
+destruct s ; destruct p ; subst ; simpl ; exists x1 ; tauto.
+Qed.
+ +
+Lemma app_eq_appT2: forall (A : Type) (w x y z : list A),
+  w ++ x = y ++ z -> existsT2 (m : list A),
+    ((w = y ++ m) * (z = m ++ x)) + ((y = w ++ m) * (x = m ++ z)).
+Proof.
+  induction w; intros *; intros H; simpl in *.
+  subst. exists y. right. tauto.
+  apply cons_eq_appT2 in H. destruct H as [[H1 H2]| [l [? H3]]]; subst.
+  exists (a :: w). tauto.
+  eapply IHw in H3. destruct H3 as [l2 [[H3 H4] | [H3 H4]]]; subst.
+  exists l2. tauto.
+  exists l2. tauto.
+Qed.
+ +
+Definition app_eq_consT (A : Type) (x y z : list A) (a : A) p :=
+  @cons_eq_appT A x y z a (eq_sym p).
+ +
+Lemma list_eq_nil: forall (A : Type) (x y : list A) (u : A),
+  x ++ u :: y = [] -> False.
+Proof. intros. apply app_eq_nil in H. cD. discriminate. Qed.
+ +
+Lemma app_eq_unitT2 :
+  forall {A : Type} (x y:list A) (a:A),
+    x ++ y = [a] -> ((x = []) * (y = [a])) + ((x = [a]) * (y = [])).
+Proof.
+  intros *; intros H.
+  destruct x. auto.
+  simpl in *. inversion H. subst. right.
+  rewrite H2. apply app_eq_nilT in H2. destruct H2 as [H2a H2b].
+  subst. auto.
+Qed.
+ +
+Definition nil_eq_list A x y u p := @list_eq_nil A x y u (eq_sym p).
+Definition nil_eq_app A u v p := @app_eq_nil A u v (eq_sym p).
+Definition nil_eq_appT A u v p := @app_eq_nilT A u v (eq_sym p).
+Definition unit_eq_app A x y a p := @app_eq_unit A x y a (eq_sym p).
+Definition unit_eq_appT2 A x y a p := @app_eq_unitT2 A x y a (eq_sym p).
+ +
+Lemma list_eq_single: forall (A : Type) (x y : list A) (u v : A),
+  x ++ u :: y = [v] -> x = [] /\ y = [] /\ u = v.
+Proof. intros. apply app_eq_cons in H. sD. injection H0 as. subst. tauto.
+        apply app_cons_not_nil in H1. contradiction. Qed.
+ +
+Lemma list_eq_singleT: forall (A : Type) (x y : list A) (u v : A),
+  x ++ u :: y = [v] -> prod (x = []) (prod (y = []) (u = v)).
+Proof. intros. apply app_eq_consT in H. sD. injection H0 as. subst. tauto.
+  apply nil_eq_appT in H1. cD. discriminate H2. Qed.
+ +
+Lemma list_eq_singleT_nobrac: forall (A : Type) (x y : list A) (u v : A),
+  x ++ u :: y = [v] -> (x = []) * (y = []) * (u = v).
+Proof. intros. apply app_eq_consT2 in H. sD. injection H0 as. subst. tauto.
+  apply app_cons_not_nil in H1. contradiction. Qed.
+ +
+Definition single_eq_list A x y u v p := @list_eq_single A x y u v (eq_sym p).
+Definition single_eq_listT A x y u v p := @list_eq_singleT A x y u v (eq_sym p).
+Definition single_eq_listT_nobrac A x y u v p := @list_eq_singleT_nobrac A x y u v (eq_sym p).
+ +
+Lemma nnn_app_eq: forall {A : Type} (x : list A), [] ++ [] ++ [] ++ x = x.
+Proof. intros. simpl. reflexivity. Qed.
+ +
+Definition eq_nnn_app {A : Type} (x : list A) := eq_sym (nnn_app_eq x).
+ +
+(* Caitlin added from here for weakening. *)
+ +
+Lemma cons_singleton : forall {A : Type} (l : list A) a,
+    a :: l = [a] ++ l.
+Proof. induction l; intros b; firstorder. Qed.
+ +
+Ltac list_cons_singleton a := repeat rewrite (cons_singleton _ a).
+Ltac tac_cons_singleton_arg a l :=
+    match l with
+    | nil => idtac
+    | _ => rewrite (cons_singleton l a)
+    end.
+ +
+Ltac tac_cons_singleton :=
+  repeat
+  match goal with
+   | [ |- context [?a :: ?l]] => progress (tac_cons_singleton_arg a l)
+  end.
+ +
+(* Caitlin added from here for contraction. *)
+ +
+Ltac rem_nil_goal := repeat rewrite app_nil_l; repeat rewrite app_nil_r.
+Ltac rem_nil_hyp_arg H := repeat rewrite app_nil_l in H; repeat rewrite app_nil_r in H.
+Ltac rem_nil_hyp :=
+  match goal with
+  | [ H : context[ [] ++ ?A ] |- _ ] => progress rem_nil_hyp_arg H
+  | [ H : context[ ?A ++ [] ] |- _ ] => progress rem_nil_hyp_arg H
+  | _ => idtac
+  end.
+ +
+Ltac rem_nil := rem_nil_hyp; rem_nil_goal.
+ +
+Ltac list_assoc_r_single :=
+  list_assoc_r; tac_cons_singleton; rem_nil.
+ +
+Ltac app_bracket_middle_arg l :=
+  repeat match l with
+         | ?l1 ++ ?l2 ++ ?l3 ++ ?l4 => rewrite (app_assoc l2)
+         end.
+ +
+Ltac add_empty_hyp_L l H := rewrite <- (app_nil_l l) in H.
+Ltac add_empty_goal_L l := rewrite <- (app_nil_l l).
+Ltac add_empty_hyp_R l H := rewrite <- (app_nil_r l) in H.
+Ltac add_empty_goal_R l := rewrite <- (app_nil_r l).
+Ltac rem_empty_hyp_L l H := rewrite (app_nil_l l) in H.
+Ltac rem_empty_goal_L l := rewrite (app_nil_l l).
+Ltac rem_empty_hyp_R l H := rewrite (app_nil_r l) in H.
+Ltac rem_empty_goal_R l := rewrite (app_nil_r l).
+ +
+Ltac breakdown :=
+  repeat (
+      repeat (match goal with
+              | [ H : ?A ++ ?B = ?x ++ ?y |- _ ] => apply app_eq_app in H; sE; subst
+              end) ;
+      repeat (match goal with
+              | [H2 : [?a] = ?A ++ ?B |- _ ] => apply unit_eq_app in H2; sE; subst
+              end));
+  repeat try rewrite app_nil_r; repeat try rewrite app_nil_l;
+  repeat (match goal with
+          | [ H3 : context[ ?x ++ [] ] |- _ ] => rewrite (app_nil_r x) in H3
+          end);
+  repeat (match goal with
+          | [ H3 : context[ [] ++ ?x ] |- _ ] => rewrite (app_nil_l x) in H3
+          end).
+ +
+Ltac tac_cons_singleton_arg_hyp H a l :=
+    match l with
+    | nil => idtac
+    | _ => rewrite (cons_singleton l a) in H
+    end.
+ +
+Ltac tac_cons_singleton_hyp H :=
+  repeat
+  match goal with
+  | [ H : context [?a :: ?l] |- _] => progress (tac_cons_singleton_arg_hyp H a nil ||
+                                                tac_cons_singleton_arg_hyp H a l)
+  end.
+ +
+Ltac list_assoc_r_s_arg H :=
+  tac_cons_singleton_hyp H; repeat rewrite <- !app_assoc in H.
+ +
+Ltac list_assoc_r_arg H :=
+  repeat (rewrite <- !app_assoc in H || rewrite <- !app_comm_cons in H).
+Ltac list_assoc_l'_arg H := repeat (rewrite !app_assoc in H || rewrite !app_comm_cons in H).
+Ltac list_assoc_l'_arg_conc H := list_assoc_l; list_assoc_l'_arg H.
+Ltac list_assoc_r_arg_conc H := list_assoc_r; list_assoc_r_arg H.
+ +
+Ltac list_assoc_r_singleton_hyp H :=
+  list_assoc_r_arg H; tac_cons_singleton_hyp H.
+ +
+Ltac list_assoc_r_singleton_hyp2 H :=
+  list_assoc_r_s_arg H.
+ +
+Definition non_empty {A : Type} (l : list A) :=
+  match l with
+  | nil => False
+  | _ => True
+  end.
+ +
+Ltac check_app_head l1 l2 :=
+  match l1 with
+  | l2 ++ ?l3 => idtac
+  | _ => fail
+  end.
+ +
+Ltac check_app_tail l1 l2 :=
+  match l1 with
+  | ?l3 ++ l2 => idtac
+  | _ => fail
+  end.
+ +
+(* Updated *)
+Ltac clear_useless :=
+  repeat match goal with
+         | [H : ?a = ?a |- _] => clear H
+         | [H : [?a] = [?a] |- _] => clear H
+         | [H : ?a :: ?b = ?a :: ?b |- _] => clear H
+         | [H1 : ?a, H2 : ?a |- _] => clear H2
+         | [H1 : [?a] = [?b], H2 : ?c = ?d |- _ ] =>
+           rewrite H2 in H1; match type of H1 with ?d = ?d => clear H1 end
+         | [H1 : [?a] = [?b], H2 : ?c = ?d |- _ ] =>
+           rewrite <- H2 in H1; match type of H1 with ?d = ?d => clear H1 end
+         end.
+ +
+Ltac clear_useless_weak :=
+  repeat match goal with
+         | [H : ?a = ?a |- _] => clear H
+         | [H : [?a] = [?a] |- _] => clear H
+         | [H : ?a :: ?b = ?a :: ?b |- _] => clear H
+         | [H1 : ?a, H2 : ?a |- _] => clear H2
+         end.
+ +
+(*
+Lemma testing_clear_useless : forall (a b c : nat) (l1 l2 l3 : list nat),
+    a::l1 = b::l2 ->
+    b = c ->
+    c = a ->
+    l2 = l2 ->
+    l2 = l2 ->
+    True.
+Proof.  
+  clear_useless.
+Admitted.
+ *)

+ +
+Ltac inv_singleton :=
+    repeat ( match goal with
+       | [ H : ?a :: [] = ?c :: ?d |- _ ] => inversion H; subst
+       | [ H : ?a :: ?b = ?c :: [] |- _ ] => inversion H; subst
+       | [ H : ?a :: ?b = ?c :: ?d |- _ ] => inversion H; subst
+       | [ H : ((?a,?b) = ?c) |- _ ] => inversion H; subst
+       | [ H : ?c = (?a,?b) |- _ ] => inversion H; subst
+             end; clear_useless).
+ +
+Ltac inversion_cons :=
+  repeat match goal with
+         | [ H : ?a :: ?l1 = ?b :: ?l2 |- _] => inversion H; subst; clear_useless
+         end.
+ +
+(* begin git conflict 1 *)
+ +
+Ltac inversion_pair :=
+  repeat (clear_useless; match goal with
+  | [ H : (?a,?b)=(?c,?d) |- _ ] => inversion H; clear H; subst
+  end; clear_useless).
+ +
+Ltac inv_singleton_str :=
+    repeat ( match goal with
+       | [ H : ?a :: [] = ?c :: ?d |- _ ] => inversion H; subst
+       | [ H : ?a :: ?b = ?c :: [] |- _ ] => inversion H; subst
+       | [ H : ?a :: ?b = ?c :: ?d |- _ ] => inversion H; subst
+       | [ H : ((?a,?b) = ?c) |- _ ] => inversion H; subst
+       | [ H : ?c = (?a,?b) |- _ ] => inversion H; subst
+       | [ H : ?C ?a = ?C ?b |- _ ] => inversion H; subst
+             end; clear_useless).
+ +
+Lemma tail_inv_singleton : forall {T : Type} (l1 l2 : list T) a b,
+    l1 ++ [a] = l2 ++ [b] -> (l1 = l2) * (a = b).
+Proof.
+  induction l1; intros l2 c d Heq.
+  simpl in *. destruct l2. simpl in Heq. inversion Heq. firstorder.
+  simpl in Heq. destruct l2. simpl in Heq. inversion Heq.
+  simpl in Heq. inversion Heq.
+  simpl in Heq. destruct l2. simpl in Heq. destruct l1. simpl in Heq. inversion Heq.
+  simpl in Heq. inversion Heq.
+  simpl in Heq. inversion Heq. subst.
+  apply IHl1 in H1. destruct H1 as [IH1 IH2].
+  subst. firstorder.
+Qed.
+ +
+Lemma tail_inv_singleton2 : forall {T : Type} (l1 l2 : list T) a b a' b',
+    l1 ++ [a;a'] = l2 ++ [b;b'] -> (l1 = l2) * (a = b) * (a' = b').
+Proof.
+  induction l1; intros l2 c d a' b' Heq.
+  simpl in *. destruct l2. simpl in Heq. inversion Heq. firstorder.
+  simpl in Heq. destruct l2. simpl in Heq. inversion Heq.
+  simpl in Heq. destruct l2. inversion Heq.
+  simpl in Heq. inversion Heq.
+  destruct l2. simpl in Heq. destruct l1. simpl in Heq. inversion Heq.
+  simpl in Heq. destruct l1; inversion Heq.
+  simpl in Heq. inversion Heq. subst.
+  apply IHl1 in H1. destruct H1 as [[H1 H2] H3].
+  subst. firstorder.
+Qed.
+ +
+Lemma list_insert1 : forall {T : Type} (Gam1 Gam2 Sigm1 Sigm2 : list T) A B,
+    Gam1 ++ [A] ++ Gam2 = Sigm1 ++ Sigm2 ->
+    existsT2 Gam1' Gam2', (Sigm1 ++ [B] ++ Sigm2 = Gam1' ++ [A] ++ Gam2') *
+                      (forall B, InT B Gam1 -> InT B Gam1') *
+                      (forall B, InT B Gam2 -> InT B Gam2').
+Proof.
+  intros *; intros Heq.
+  destruct Sigm2. rewrite app_nil_r.
+  rewrite app_nil_r in Heq. subst.
+  eexists. eexists.
+  split. split. rewrite <- app_assoc. simpl. reflexivity.
+  firstorder.
+  intros C HC. apply InT_appL. assumption.
+  apply partition_2_2T in Heq.
+  sD. subst.
+  eexists (Sigm1 ++ [B] ++ [t] ++ Heq).
+  eexists Gam2. split. split. list_assoc_r. reflexivity. firstorder.
+  apply InT_appE in X. destruct X. apply InT_appL. assumption.
+  apply InT_appR. apply InT_appR.
+  assumption.
+  firstorder.
+  subst.
+  eexists (Gam1 ++ [B]), (Sigm2). split. split.
+  assert (Hyp: t :: Sigm2 = [t] ++ Sigm2). simpl. reflexivity.
+  rewrite Hyp. apply app_assoc.
+  intros C HC. apply InT_appL. assumption.
+  firstorder.
+  subst.
+  list_assoc_r. eexists Gam1, (Heq ++ [B] ++ [t] ++ Sigm2).
+  split. split. reflexivity.
+  firstorder.
+  intros C HC. apply InT_appE in HC.
+  destruct HC. apply InT_appL. assumption.
+  apply InT_appR. apply InT_appR. assumption.
+Qed.
+ +
+  Inductive InT_pair_triple {T1 T2 T3 : Type} (t12 : T1*T2) : list ((list T1) * (list T2) * T3) -> Type :=
+  | InT_pt_hd l a b c t1 t2 : t12 = (t1,t2) -> InT t1 a -> InT t2 b -> InT_pair_triple t12 ((a,b,c) :: l)
+  | InT_pt_tl l a b c : InT_pair_triple t12 l -> InT_pair_triple t12 ((a,b,c) :: l).
+ +
+Lemma InT_pt_I : forall {T1 T2 T3 : Type} L1 (l1 l2 : list T1) (l3 l4 : list T2) (d : T3) A B,
+  InT_pair_triple (A,B) (L1 ++ [(l1 ++ [A] ++ l2, l3 ++ [B] ++ l4, d)]).
+Proof.
+  induction L1; intros. simpl.
+  econstructor. reflexivity.
+  apply InT_appR. econstructor. reflexivity.
+  apply InT_appR. econstructor. reflexivity.
+ +
+  simpl. destruct a as [[a b] c].
+  econstructor 2. apply IHL1.
+Qed.
+ +
+Lemma partition_singleton_app : forall {T : Type} (L1 L2 L3 : list T) A B,
+    L1 ++ [A] = L2 ++ [B] ++ L3 ->
+    ((L3 = []) * (L1 = L2) * (A = B)) +
+    (existsT2 L4, (L3 = L4 ++ [A]) * (L1 = L2 ++ [B] ++ L4)).
+Proof.
+  induction L1; intros L2 L3 A B H.
+  simpl in *. destruct L2. simpl in *. inversion H. firstorder.
+  simpl in *. destruct L2; discriminate.
+  simpl in H. destruct L2. simpl in *. inversion H. subst.
+  right. exists L1. firstorder.
+  simpl in H. inversion H. subst.
+  apply IHL1 in H2. sD. subst. firstorder.
+  subst. right. eexists. split; reflexivity.
+Qed.
+ +
+Lemma InT_mid : forall {T : Type} (l1 l2 : list T) A,
+  InT A (l1 ++ [A] ++ l2).
+Proof.
+  intros. apply InT_appR. apply InT_appL.
+  econstructor. reflexivity.
+Qed.
+ +
+Lemma InT_singleton_mid : forall {T : Type} (l1 l2 l3 l4 : list T) A B,
+    A <> B ->
+    l1 ++ [A] ++ l2 = l3 ++ [B] ++ l4 ->
+    InT A l3 + InT A l4.
+Proof.
+  intros *. intros Hneq Heq.
+  pose proof (InT_mid l1 l2 A) as Hin.
+  rewrite Heq in Hin.
+  apply InT_appE in Hin.
+  destruct Hin. left. assumption.
+  inversion i. subst. contradiction.
+  subst. right. assumption.
+Qed.
+ +
+Lemma list_nil_or_tail_singleton : forall {T : Type} (l : list T),
+    (l = []) + existsT2 l2 a, l = l2 ++ [a].
+Proof.
+  induction l.
+  firstorder.
+  right. destruct IHl. subst. exists nil, a. firstorder.
+  destruct s as [l2' [a' H]].
+  subst. exists (a :: l2'), a'. firstorder.
+Qed.
+ +
+Definition InT_app_or : forall {T : Type} (l1 l2 : list T) A,
+      InT A (l1 ++ l2) -> InT A l1 + InT A l2.
+Proof.
+induction l1. intros. rewrite app_nil_l in X. right. assumption.
+intros. remember ((a :: l1) ++ l2) as l. destruct X.
+subst. inversion Heql. left. apply InT_eq. inversion Heql.
+subst. apply IHl1 in X. destruct X. left. apply InT_cons. assumption.
+right. assumption.
+Defined.
+ +
+Definition InT_or_app : forall {T : Type} (l1 l2 : list T) A,
+       (InT A l1 + InT A l2) -> InT A (l1 ++ l2).
+Proof.
+induction l1. intros. rewrite app_nil_l. destruct X. inversion i.
+assumption.
+intros. destruct X. remember (a:: l1) as l. destruct i.
+inversion Heql. subst. apply InT_eq. inversion Heql. subst.
+simpl. apply InT_cons. apply IHl1. left. assumption.
+simpl. apply InT_cons. apply IHl1. right. assumption.
+Defined.
+ +
+(*
+Lemma partition_LNS_app_mid : forall {T1 T2 : Type} L1 L2 L3 (Gam Sigm Sigm' : list T1) (Delt \u03a0 \u03a0' : list T2) d,
+    L1 ++ (Gam,Delt,d);(Sigm,\u03a0,bac) =
+    L2 ++ (Sigm',\u03a0',fwd) :: L3 ->
+    existsT2 L4, (L3 = L4 ++ (Sigm,\u03a0,bac)) * (L1 ++ (Gam,Delt,d) = L2 ++ (Sigm',\u03a0',fwd) ++ L4).
+Proof.
+  intros *; intros Heq.
+  rewrite app_cons_single in Heq.
+  destruct (list_nil_or_tail_singleont L3) as |[l2 [a Heq2]];
+  subst. eapply tail_inv_singleton in Heq.
+  destruct Heq as H1 H2. inversion H2.
+  exists l2. subst.
+  rewrite (cons_singleton (l2 ++ _)) in Heq.
+  list_assoc_l'_arg Heq.
+  eapply tail_inv_singleton in Heq.
+  destruct Heq as H1 H2. subst. rewrite H1.
+  firstorder.
+Qed.
+*)

+Ltac hd_tl_inv_arg H :=
+    match goal with
+  | [ H : context[?a :: nil] |- _ ] => fail
+  | [ H : context[?a :: ?l] |- _ ] => repeat rewrite (cons_singleton l a) in H
+    end.
+ +
+Ltac list_assoc_r_single_hyp :=
+  match goal with
+  | [ l1 : list ?T, H : ?l1 = ?l2 |- _ ] => list_assoc_r_arg H; tac_cons_singleton_hyp H ; rem_nil_hyp_arg H
+  end.
+ +
+Ltac list_assoc_r_single_arg H :=
+  list_assoc_r_arg H; tac_cons_singleton_hyp H ; rem_nil_hyp_arg H.
+ +
+Lemma app_singleton_inversion : forall {T : Type} (l1 l2 : list T) a b,
+    [a] ++ l1 = [b] ++ l2 -> (a = b) * (l1 = l2).
+Proof. intros *; intros H; inversion H. firstorder. Qed.
+ +
+Lemma app_singleton_tl_inversion : forall {T : Type} (l1 l2 : list T) a b,
+    l1 ++ [a] = l2 ++ [b] -> (a = b) * (l1 = l2).
+Proof.
+  intros T l1 l2 a b H.
+  eapply if_eq_rev_eq in H.
+  do 2 rewrite rev_unit in H.
+  inversion H. apply if_rev_eq in H2.
+  subst. firstorder.
+Qed.
+ +
+Ltac inv_app_hd :=
+  repeat match goal with
+  | [ H : [?a] ++ ?l1 = [?b] ++ ?l2 |- _ ] => apply app_singleton_inversion in H; destruct H as [? H]; try subst a; try subst b
+  | _ => idtac
+         end.
+ +
+Ltac inv_app_tl :=
+  repeat match goal with
+  | [ H : ?l1 ++ [?a] = ?l2 ++ [?b] |- _ ] => apply app_singleton_tl_inversion in H; destruct H as [? H]; try subst a; try subst b
+  | _ => idtac
+         end.
+ +
+Lemma app_hd_inversion : forall {T : Type} (l : list T) a b,
+    [a] = [b] ++ l -> ( (a = b) * (l = []) ).
+Proof.
+  intros *; intros H.
+  inversion H. firstorder.
+Qed.
+ +
+Lemma app_tl_inversion : forall {T : Type} (l : list T) a b,
+    [a] = l ++ [b] -> ( (a = b) * (l = []) ).
+Proof.
+  induction l; intros aa bb H.
+  simpl in *. inversion H. firstorder.
+  simpl in H. inversion H.
+  destruct l; discriminate.
+Qed.
+ +
+Ltac inv_app_hd_arg H :=
+  repeat match type of H with
+  | [?a] ++ ?l1 = [?b] ++ ?l2 => apply app_singleton_inversion in H; let H' := fresh "H" in destruct H as [H' H]; try rewrite H' in *; try rewrite <- H' in *
+  | [?a] = [?b] ++ ?l2 => apply app_hd_inversion in H; let H' := fresh "H" in destruct H as [H' H]; try rewrite H' in *; try rewrite <- H' in *
+  | [?b] ++ ?l2 = [?a] => symmetry in H; apply app_hd_inversion in H; let H' := fresh "H" in destruct H as [H' H]; try rewrite H' in *; try rewrite <- H' in *
+  | _ => idtac
+         end.
+ +
+Ltac inv_app_tl_arg H :=
+  repeat match type of H with
+  | ?l1 ++ [?a] = ?l2 ++ [?b] => apply app_singleton_tl_inversion in H;let H' := fresh "H" in destruct H as [H' H]; try rewrite H' in *; try rewrite <- H' in *
+  | [?a] = ?l2 ++ [?b] => apply app_tl_inversion in H; let H' := fresh "H" in destruct H as [H' H]; try rewrite H' in *; try rewrite <- H' in *
+  | ?l2 ++ [?b] = [?a] => symmetry in H; apply app_tl_inversion in H; let H' := fresh "H" in destruct H as [H' H]; try rewrite H' in *; try rewrite <- H' in *
+  | _ => idtac
+         end.
+ +
+Ltac inv_app_hd_tl_arg H :=
+  list_assoc_r_single_arg H;
+  inv_app_hd_arg H;
+  list_assoc_l'_arg H;
+  inv_app_tl_arg H;
+  list_assoc_r_single_arg H;
+  clear_useless.
+ +
+(* Any equality between lists that have singletons as heads or tails -> destruct into respective smaller equalities. *)
+Ltac inv_app_hd_tl :=
+  repeat match goal with
+  | [ H : ?l1 = ?l2 |- _ ] => inv_app_hd_tl_arg H
+  end.
+ +
+Ltac tac_cons_singleton_eq_hyp :=
+  repeat match goal with
+         | [ l1 : list ?T, H : ?l1 = ?l2 |- _ ] => tac_cons_singleton_hyp H;
+                                                   list_assoc_r_single_arg H
+         end.
+ +
+(* A version of app_eq_appT2_nn to rule out overlap between the two branchs where m =  (hence No Nil mnemonic). *)
+Lemma app_eq_appT2_nn: forall (A : Type) (w x y z : list A),
+  w ++ x = y ++ z -> existsT2 (m : list A),
+    ((w = y ++ m) * (z = m ++ x) * (m <> [])) + ((y = w ++ m) * (x = m ++ z)).
+Proof.
+  induction w; intros *; intros H; simpl in *.
+  subst. exists y. right. tauto.
+  apply cons_eq_appT2 in H. destruct H as [[H1 H2]| [l [? H3]]]; subst.
+  exists (a :: w). left. simpl. split. split ; try auto. intro. inversion H.
+  eapply IHw in H3. destruct H3 as [l2 [[H3 H4] | [H3 H4]]]; subst.
+  exists l2. sD. subst. left. tauto.
+  exists l2. right. tauto.
+Qed.
+ +
+Ltac app_eq_app_dest_arg H :=
+  eapply app_eq_appT2_nn in H; sD; subst.
+ +
+Ltac app_single_eq_dest_arg H :=
+  apply unit_eq_appT2 in H; sD; subst.
+ +
+Lemma app_eq_appT2_single_hdL : forall (A : Type) (x y z : list A) w,
+    [w] ++ x = y ++ z ->
+    (existsT2 m : list A, ((y = [w] ++ m) * (x = m ++ z)))
+       + ((y = []) * (z = [w] ++ x)).
+Proof.
+  intros *.
+  intros H.
+  destruct y. simpl in *. subst.
+  right. firstorder.
+  left. simpl in *. inversion H.
+  subst. exists y. firstorder.
+Qed.
+ +
+Lemma app_eq_appT2_single_hdR : forall (A : Type) (x z w : list A) y,
+    w ++ x = [y] ++ z ->
+    (existsT2 m : list A, (w = [y] ++ m) * (z = m ++ x)) +
+    ( (w = []) * (x = [y] ++ z)).
+Proof.
+  intros *.
+  intros H.
+  symmetry in H.
+  eapply app_eq_appT2_single_hdL.
+  assumption.
+Qed.
+ +
+Lemma app_eq_appT2_single_tlL : forall (A : Type) (x y z : list A) w,
+    x ++ [w] = y ++ z ->
+    (existsT2 m : list A, ((z = m ++ [w]) * (x = y ++ m)))
+       + ((z = []) * (y = x ++ [w])).
+Proof.
+  intros *.
+  intros H.
+  destruct (list_nil_or_tail_singleton z). subst.
rewrite app_nil_r in H. subst.
+  right. firstorder. sD. subst.
+  left. list_assoc_l'_arg H.
+  eapply tail_inv_singleton in H.
+  sD. subst.
+  eexists. firstorder.
+Qed.
+ +
+Lemma app_eq_appT2_single_tlR : forall (A : Type) (x y z : list A) w,
+     y ++ z = x ++ [w] ->
+    (existsT2 m : list A, ((z = m ++ [w]) * (x = y ++ m)))
+       + ((z = []) * (y = x ++ [w])).
+Proof.
+  intros *.
+  intros H.
+  symmetry in H.
+  eapply app_eq_appT2_single_tlL.
+  assumption.
+Qed.
+ +
+(* Where we have a partitioning of lists, split into cases.  *)
+Ltac app_eq_app_dest :=
+  repeat match goal with
+         | [ H : [?a] = ?l1 ++ ?l2 |- _ ] => app_single_eq_dest_arg H
+         | [ H : ?l1 ++ ?l2 = [?a] |- _ ] => symmetry in H; app_single_eq_dest_arg H
+         | [ H : [?a] = [?b] |- _ ] => inversion H
+         | [ H : ?l1 ++ ?l2 = ?l3 ++ ?l4 |- _ ] => app_eq_app_dest_arg H
+         end.
+ +
+Ltac inv_app_hd_tl_full :=
+  inv_app_hd_tl; repeat inversion_pair;
+  tac_cons_singleton_eq_hyp.
+ +
+Ltac app_eq_app_dest2 :=
+  repeat (inv_app_hd_tl_full ; subst ; try match goal with
+         | [ H : [?a] = ?l1 ++ ?l2 |- _ ] => app_single_eq_dest_arg H
+         | [ H : ?l1 ++ ?l2 = [?a] |- _ ] => symmetry in H; app_single_eq_dest_arg H
+         | [ H : [?a] = [?b] |- _ ] => inversion H
+         | [ H : [?a] ++ ?l2 = ?l3 ++ ?l4 |- _ ] => eapply app_eq_appT2_single_hdL in H
+         | [ H : ?l1 ++ ?l2 = [?a] ++ ?l4 |- _ ] => eapply app_eq_appT2_single_hdR in H
+         | [ H : ?l1 ++ ?l2 = ?l3 ++ ?l4 |- _ ] => app_eq_app_dest_arg H
+                                           end).
+ +
+Ltac app_eq_app_dest3_arg_pre H :=
+      (match goal with
+      | H:[?a] = ?l1 ++ ?l2 |- _ => app_single_eq_dest_arg H
+      | H:?l1 ++ ?l2 = [?a] |- _ => symmetry in H; app_single_eq_dest_arg H
+      | H:[?a] = [?b] |- _ => inversion H; clear H
+       end).
+ +
+Ltac app_eq_app_dest3_argL H :=
+      (match goal with
+      | H:[?a] ++ ?l2 = ?l3 ++ ?l4 |- _ => eapply app_eq_appT2_single_hdL in H
+      | H:?l1 ++ ?l2 = [?a] ++ ?l4 |- _ => eapply app_eq_appT2_single_hdR in H
+       end).
+ +
+Ltac app_eq_app_dest3_argR H :=
+      (match goal with
+      | H: ?l2 ++ [?a] = ?l3 ++ ?l4 |- _ => eapply app_eq_appT2_single_tlL in H
+      | H:?l1 ++ ?l2 = ?l4 ++ [?a] |- _ => eapply app_eq_appT2_single_tlR in H
+       end).
+ +
+Ltac app_eq_app_dest3_arg_app H :=
+      (match goal with
+      | H:?l1 ++ ?l2 = ?l3 ++ ?l4 |- _ => app_eq_app_dest_arg H
+       end).
+ +
+Ltac app_eq_app_dest3_arg H :=
+  (progress app_eq_app_dest3_arg_pre H) ||
+  (progress (list_assoc_r_single_arg H; app_eq_app_dest3_argL H)) ||
+  (progress (list_assoc_l'_arg H; app_eq_app_dest3_argR H)) ||
+  (progress (list_assoc_r_single_arg H; app_eq_app_dest3_arg_app H)).
+ +
+Ltac app_eq_app_dest3 :=
+  repeat (inv_app_hd_tl_full ; subst ; match goal with
+  | [l1 : list ?T, H : ?l1 = ?l2 |- _ ] => app_eq_app_dest3_arg H; sD; subst
+          end); try (inv_app_hd_tl_full ; subst).
+ +
+Ltac app_eq_app_dest3' :=
+  repeat ((inv_app_hd_tl_full ; subst ; match goal with
+  | [l1 : list ?T, H : ?l1 = ?l2 |- _ ] => app_eq_app_dest3_arg H; sD; subst
+          end); try (inv_app_hd_tl_full ; subst)).
+ +
+Ltac eapply_refl tac := eapply tac; reflexivity.
+ +
+Ltac assoc_mid_loc L :=
+  repeat match goal with
+         | [ |- context[ ?l1 ++ ?l2 ++ L ++ ?l3 ] ] => rewrite (app_assoc l1)
+         end.
+ +
+Ltac tac_match l1 l2 :=
+  match l1 with
+  | [] => fail
+  | l2 ++ ?s1 => idtac
+  | ?s1 ++ l2 => try rewrite <- (app_nil_r ?L1)
+  | ?s1 ++ l2 ++ ?s2 => try rewrite (app_assoc _ s1)
+  | ?s1 ++ ?s2 => try rewrite (app_assoc _ s1); tac_match s2 l2
+  end.
+ +
+      Ltac tac_match' l1 AA :=
+  match l1 with
+  | [] => fail
+  | AA :: ?s1 => idtac
+  | ?s1 ++ [AA] => try rewrite <- (app_nil_r ?L1)
+  | ?s1 ++ AA :: ?s2 => try rewrite (app_assoc _ s1)
+  | ?s1 ++ ?s2 => try rewrite (app_assoc _ s1); tac_match' s2 AA
+  end.
+ +
+ +
+      Ltac get_last_app H :=
+  match H with
+  | ?H1 ++ ?H2 => get_last_app H2
+  | _ => constr:(H)
+  end.
+ +
+Ltac get_snd_last_app H :=
+  match H with
+  | ?H1 ++ ?H2 ++ ?H3 => get_snd_last_app (H2 ++ H3)
+  | ?H1 ++ ?H2 => constr:(H1)
+  | _ => constr:(H)
+  end.
+ +
+(* end git conflict 1 *)
+ +
+(* begin git conflict 2 *)
+ +
+(* for manipulating lists got by appending shorter lists *)
+Inductive app_split_at X (T : list X) : list X -> list X -> list X -> Type :=
+  | asa_single : app_split_at T T [] []
+  | asa_appL : forall A B C D,
+    app_split_at T A B C -> app_split_at T (A ++ D) B (C ++ D)
+  | asa_appR : forall A B C D,
+    app_split_at T A B C -> app_split_at T (D ++ A) (D ++ B) C
+  .
+ +
+(* to show/solve app_split_at T A ?BC *)
+Ltac solve_asa := apply asa_single ||
+  (apply asa_appL ; solve_asa) ||
+  (apply asa_appR ; solve_asa) .
+ +
+Lemma asa_eq X (T A B C : list X) : app_split_at T A B C -> A = B ++ T ++ C.
+Proof. intro asa. induction asa ; subst.
+rewrite app_nil_r. reflexivity. list_eq_assoc. list_eq_assoc. Qed.
+ +
+(* end git conflict 2 *)
+
+ +
+ + + diff --git a/General.ddT.html b/General.ddT.html new file mode 100644 index 0000000..b31915e --- /dev/null +++ b/General.ddT.html @@ -0,0 +1,915 @@ + + + + + + + + + + + + + +
+
+

General.ddT

+ +
+ +
+(* derrec, derl, etc, other useful stuff *)
+ +
+Require Export List.
+Set Implicit Arguments.
+Export ListNotations.
+ +
+Require Import Coq.Program.Equality. (* for dependent induction/destruction *)
+ +
+Require Import genT gen existsT.
+Require Import PeanoNat.
+ +
+(* note, this doesn't work Type replaced by Prop,
+  although the actual version used allows prems : X -> Prop 
+Reset derrec.
+
+Inductive derrec X (rules : list X -> X -> Prop) :
+  (X -> Type) -> X -> Prop := 
+  | dpI : forall prems concl,
+    prems concl -> derrec rules prems concl
+  | derI : forall ps prems concl,
+    rules ps concl -> dersrec rules prems ps -> derrec rules prems concl 
+with dersrec X (rules : list X -> X -> Prop) :
+  (X -> Type) -> list X -> Prop :=
+  | dlNil : forall prems, dersrec rules prems 
+  | dlCons : forall prems seq seqs, 
+    derrec rules prems seq -> dersrec rules prems seqs ->
+    dersrec rules prems (seq :: seqs)
+    .
+    *)

+ +
+(* definition using Forall, seems equivalent *)
+Inductive aderrec X (rules : list X -> X -> Prop)
+  (prems : X -> Prop) : X -> Prop :=
+  | adpI : forall concl,
+    prems concl -> aderrec rules prems concl
+  | aderI : forall ps concl, rules ps concl ->
+    Forall (aderrec rules prems) ps -> aderrec rules prems concl.
+(* need type version of Forall, to change this to Type *)
+ +
+(* derrec: type of derivation of a sequent ; dersrec: same idea but for
+multiple sequents *)

+ +
+Inductive derrec X (rules : list X -> X -> Type) (prems : X -> Type) :
+  X -> Type :=
+  | dpI : forall concl,
+    prems concl -> derrec rules prems concl
+  | derI : forall ps concl,
+    rules ps concl -> dersrec rules prems ps -> derrec rules prems concl
+with dersrec X (rules : list X -> X -> Type) (prems : X -> Type) :
+  list X -> Type :=
+  | dlNil : dersrec rules prems []
+  | dlCons : forall seq seqs,
+    derrec rules prems seq -> dersrec rules prems seqs ->
+    dersrec rules prems (seq :: seqs)
+    .
+ +
+Scheme derrec_rect_mut := Induction for derrec Sort Type
+with dersrec_rect_mut := Induction for dersrec Sort Type.
+Scheme derrec_rec_mut := Induction for derrec Sort Set
+with dersrec_rec_mut := Induction for dersrec Sort Set.
+Scheme derrec_ind_mut := Induction for derrec Sort Prop
+with dersrec_ind_mut := Induction for dersrec Sort Prop.
+(*
+Check derrec_ind_mut.
+Check dersrec_ind_mut.
+*)

+(* combine the two inductive principles *)
+Definition derrec_dersrec_rect_mut X rules prems P P0 dp der dln dlc :=
+  pair (@derrec_rect_mut X rules prems P P0 dp der dln dlc)
+    (@dersrec_rect_mut X rules prems P P0 dp der dln dlc).
+ +
+Ltac solve_dersrec := repeat (apply dlCons || apply dlNil || assumption).
+ +
+(* this should be a more useful induction principle for derrec *)
+Definition dim_all X rules prems Q :=
+  @derrec_ind_mut X rules prems (fun y => fun _ => Q y)
+  (fun ys => fun _ => Forall Q ys).
+ +
+Definition dim_allT X rules (prems Q : X -> Type) :=
+  @derrec_rect_mut X rules prems (fun y => fun _ => Q y)
+  (fun ys => fun _ => ForallT Q ys).
+ +
+(* this doesn't work
+Check (dim_all _ _ (Forall_nil X Q)).
+*)

+(* here is how to get the tautologies out of dim_all *)
+Definition dim_all3 X rules prems Q h1 h2 :=
+  @dim_all X rules prems Q h1 h2 (Forall_nil Q).
+ +
+Definition fce3 X Q D Ds seq seqs (d : D seq) qs (ds : Ds seqs) qss :=
+  @Forall_cons X Q seq seqs qs qss.
+ +
+Definition dim_all4 X rules prems Q h1 h2 :=
+  @dim_all3 X rules prems Q h1 h2
+  (@fce3 X Q (derrec rules prems) (dersrec rules prems)).
+ +
+Definition dim_all8 X rules prems Q h1 h2 :=
+  @dim_all3 X rules prems Q h1 h2
+  (fun seq seqs _ qs _ qss => @Forall_cons X Q seq seqs qs qss).
+ +
+(* so dim_all4, or dim_all8 better, is the same as derrec_all_ind below *)
+ +
+Lemma derrec_all_ind:
+  forall X (rules : list X -> X -> Type) (prems Q : X -> Prop),
+     (forall concl : X, prems concl -> Q concl) ->
+     (forall (ps : list X) (concl : X),
+      rules ps concl -> dersrec rules prems ps -> Forall Q ps -> Q concl) ->
+     forall y : X, derrec rules prems y -> Q y.
+Proof. intros.
+eapply dim_all. exact H. exact H0.
+apply Forall_nil.
+intros. apply Forall_cons. assumption. assumption.
+assumption. Qed.
+ +
+Lemma derrec_all_indT:
+  forall X (rules : list X -> X -> Type) (prems Q : X -> Type),
+     (forall concl : X, prems concl -> Q concl) ->
+     (forall (ps : list X) (concl : X),
+      rules ps concl -> dersrec rules prems ps -> ForallT Q ps -> Q concl) ->
+     forall y : X, derrec rules prems y -> Q y.
+Proof. intros X rules prems Q. intros H H0.
+eapply dim_allT. exact H. exact H0.
+apply ForallT_nil.
+intros. apply ForallT_cons. assumption. assumption.
+Qed.
+ +
+Lemma derrec_all_rect:
+  forall X (rules : list X -> X -> Type) (prems Q : X -> Type),
+     (forall concl : X, prems concl -> Q concl) ->
+     (forall (ps : list X) (concl : X),
+      rules ps concl -> dersrec rules prems ps -> ForallT Q ps -> Q concl) ->
+     forall y : X, derrec rules prems y -> Q y.
+Proof. intros.
+eapply dim_allT. exact X0. exact X1.
+apply ForallT_nil.
+intros. apply ForallT_cons. assumption. assumption.
+assumption. Qed.
+ +
+Lemma derrec_derrec' X rules prems:
+  (forall c : X, derrec rules (derrec rules prems) c -> derrec rules prems c) *
+  (forall cs, dersrec rules (derrec rules prems) cs -> dersrec rules prems cs).
+Proof. apply derrec_dersrec_rect_mut.
+- intros. assumption.
+- intros. eapply derI ; eassumption.
+- apply dlNil.
+- intros. apply dlCons ; assumption. Qed.
+ +
+Definition derrec_derrec X rules prems := fst (@derrec_derrec' X rules prems).
+Definition dersrec_derrec X rules prems := snd (@derrec_derrec' X rules prems).
+ +
+Inductive derl X (rules : list X -> X -> Type) : list X -> X -> Type :=
+  | asmI : forall p, derl rules [p] p
+  | dtderI : forall pss ps concl, rules ps concl ->
+    dersl rules pss ps -> derl rules pss concl
+with dersl X (rules : list X -> X -> Type) : list X -> list X -> Type :=
+  | dtNil : dersl rules [] []
+  | dtCons : forall ps c pss cs,
+    derl rules ps c -> dersl rules pss cs -> dersl rules (ps ++ pss) (c :: cs)
+  .
+ +
+Scheme derl_ind_mut := Induction for derl Sort Prop
+with dersl_ind_mut := Induction for dersl Sort Prop.
+Scheme derl_rec_mut := Induction for derl Sort Set
+with dersl_rec_mut := Induction for dersl Sort Set.
+Scheme derl_rect_mut := Induction for derl Sort Type
+with dersl_rect_mut := Induction for dersl Sort Type.
+(*
+Check derl_ind_mut.
+Check dersl_ind_mut.
+*)

+Lemma dtCons_eq X rules ps c pss cs psa: derl rules ps (c : X) ->
+  dersl rules pss cs -> psa = ps ++ pss -> dersl rules psa (c :: cs).
+Proof. intros. subst. apply dtCons ; assumption. Qed.
+ +
+Lemma derl_dersl_single X rules ps (c : X) :
+  iffT (dersl rules ps [c]) (derl rules ps c).
+Proof. split.
+intro. inversion X0. inversion X2. subst. rewrite app_nil_r. assumption.
+intro. eapply (dtCons_eq X0 (dtNil _)). rewrite app_nil_r. reflexivity. Qed.
+ +
+(* combine the two inductive principles *)
+Definition derl_dersl_rect_mut X rules P P0 asm dtd dtn dtc :=
+  pair (@derl_rect_mut X rules P P0 asm dtd dtn dtc)
+    (@dersl_rect_mut X rules P P0 asm dtd dtn dtc).
+ +
+Lemma asmsI X rules ps: @dersl X rules ps ps .
+Proof. induction ps. apply dtNil. pose (asmI rules a).
+pose (dtCons d IHps). simpl in d0. exact d0. Qed.
+ +
+Lemma in_derl X rules ps c: rules ps c -> @derl X rules ps c.
+Proof. intro. eapply dtderI. eassumption. apply asmsI. Qed.
+ +
+Definition rsub_derl X rules := rsubI _ _ (@in_derl X rules).
+ +
+Inductive dercl X (rules : list X -> X -> Type) :
+  list X -> X -> Type :=
+  | casmI : forall p, dercl rules [p] p
+  | dtcderI : forall pss ps concl, rules ps concl ->
+    dercsl rules pss ps -> dercl rules (concat pss) concl
+with dercsl X (rules : list X -> X -> Type) :
+  list (list X) -> list X -> Type :=
+  | dtcNil : dercsl rules [] []
+  | dtcCons : forall ps c pss cs, dercl rules ps c ->
+      dercsl rules pss cs -> dercsl rules (ps :: pss) (c :: cs)
+  .
+ +
+Scheme dercl_ind_mut := Induction for dercl Sort Prop
+with dercsl_ind_mut := Induction for dercsl Sort Prop.
+Scheme dercl_rec_mut := Induction for dercl Sort Set
+with dercsl_rec_mut := Induction for dercsl Sort Set.
+Scheme dercl_rect_mut := Induction for dercl Sort Type
+with dercsl_rect_mut := Induction for dercsl Sort Type.
+(*
+Check dercl_ind_mut.
+Check dercsl_ind_mut.
+*)

+(* combine the two inductive principles *)
+Definition dercl_dercsl_rect_mut X rules P P0 asm dtd dtn dtc :=
+  pair (@dercl_rect_mut X rules P P0 asm dtd dtn dtc)
+    (@dercsl_rect_mut X rules P P0 asm dtd dtn dtc).
+ +
+Inductive ccps X f (qs cs : list X) : Type :=
+  | ccpsI : forall pss, f pss cs -> qs = concat pss -> ccps f qs cs.
+ +
+Lemma ccpsD X f qs cs: ccps f qs cs ->
+  {pss : list (list X) & qs = concat pss & f pss cs}.
+Proof. intro cc. destruct cc. subst. exists pss ; tauto. Qed.
+ +
+Definition drl_allT X (rules Q : list X -> X -> Type) R :=
+  @derl_rect_mut X rules (fun ps => fun c => fun _ => Q ps c)
+  (fun pss => fun cs => fun _ => R pss cs).
+ +
+Definition drsl_allT X (rules Q : list X -> X -> Type) R :=
+  @dersl_rect_mut X rules (fun ps => fun c => fun _ => Q ps c)
+  (fun pss => fun cs => fun _ => R pss cs).
+ +
+(* these may be too strong, have a condition that has to hold
+  even if dersl and Forall2T Q hold for different partition of pss *)

+Definition drl_allT' X (rules Q : list X -> X -> Type) :=
+  @derl_rect_mut X rules (fun ps => fun c => fun _ => Q ps c)
+  (fun ps => fun cs => fun _ => ccps (Forall2T Q) ps cs).
+ +
+Definition drsl_allT' X (rules Q : list X -> X -> Type) :=
+  @dersl_rect_mut X rules (fun ps => fun c => fun _ => Q ps c)
+  (fun ps => fun cs => fun _ => ccps (Forall2T Q) ps cs).
+ +
+Definition dcl_allT X (rules Q : list X -> X -> Type) :=
+  @dercl_rect_mut X rules (fun ps => fun c => fun _ => Q ps c)
+  (fun pss => fun cs => fun _ => Forall2T Q pss cs).
+ +
+Definition dcsl_allT X (rules Q : list X -> X -> Type) :=
+  @dercsl_rect_mut X rules (fun ps => fun c => fun _ => Q ps c)
+  (fun pss => fun cs => fun _ => Forall2T Q pss cs).
+ +
+Lemma dercl_all_rect: forall X (rules Q : list X -> X -> Type),
+  (forall p : X, Q [p] p) ->
+  (forall pss qs ps concl, rules ps concl -> dercsl rules pss ps ->
+    Forall2T Q pss ps -> qs = concat pss -> Q qs concl) ->
+  forall ps c, dercl rules ps c -> Q ps c.
+Proof. intros. eapply dcl_allT. exact X0.
+{ intros. eapply X1. eassumption.
+  eassumption. eassumption. reflexivity. }
+apply Forall2T_nil.
+intros. apply Forall2T_cons ; assumption. assumption. Qed.
+ +
+Lemma derscl_all_dercl: forall X (rules : list X -> X -> Type),
+  forall pss cs, dercsl rules pss cs -> Forall2T (dercl rules) pss cs.
+Proof. intros X rules. apply dcsl_allT. apply casmI.
+intros. eapply dtcderI ; eassumption.
+apply Forall2T_nil. intros. apply Forall2T_cons ; assumption. Qed.
+ +
+Lemma all_dercl_derscl: forall X (rules : list X -> X -> Type),
+  forall pss cs, Forall2T (dercl rules) pss cs -> dercsl rules pss cs.
+Proof. induction pss.
+intros. inversion X0. apply dtcNil.
+intros. inversion X0. subst. apply dtcCons. assumption.
+apply IHpss. assumption. Qed.
+ +
+Lemma all_derl_dersl: forall X (rules : list X -> X -> Type),
+  forall pss cs, Forall2T (derl rules) pss cs -> dersl rules (concat pss) cs.
+Proof. induction pss.
+intros. inversion X0. simpl. apply dtNil.
+intros. inversion X0. subst. simpl. apply dtCons. assumption.
+apply IHpss. assumption. Qed.
+ +
+Lemma all_derl_dersl': forall X (rules : list X -> X -> Type),
+  forall qs cs, ccps (Forall2T (derl rules)) qs cs -> dersl rules qs cs.
+Proof. intros. destruct X0. subst. apply all_derl_dersl. exact f. Qed.
+ +
+Lemma dersl_all_derl: forall X (rules : list X -> X -> Type),
+  forall qs cs, dersl rules qs cs ->
+  {pss : list (list X) & qs = concat pss & Forall2T (derl rules) pss cs}.
+Proof. intros X rules. eapply drsl_allT. apply asmI.
+intros. destruct X0. subst. eapply dtderI. apply r. apply d.
+exists []. simpl. reflexivity. apply Forall2T_nil.
+intros. destruct X1. subst. exists (ps :: x). simpl. reflexivity.
+apply Forall2T_cons ; assumption. Qed.
+ +
+Lemma dersl_all_derl': forall X (rules : list X -> X -> Type),
+  forall qs cs, dersl rules qs cs -> ccps (Forall2T (derl rules)) qs cs.
+Proof. intros X rules. eapply drsl_allT'. apply asmI.
+intros. destruct X0. eapply dtderI ; eassumption.
+eapply ccpsI. apply Forall2T_nil. simpl. reflexivity.
+intros. destruct X1. subst. eapply ccpsI.
+apply Forall2T_cons ; eassumption. simpl. reflexivity. Qed.
+ +
+Lemma dercl_derl': forall X (rules : list X -> X -> Type),
+  prod (forall ps c, dercl rules ps c -> derl rules ps c)
+    (forall pss cs, dercsl rules pss cs -> dersl rules (concat pss) cs).
+Proof. intros.
+eapply (dercl_dercsl_rect_mut (rules := rules)
+  (fun ps : list X => fun c => fun _ => derl rules ps c)
+  (fun pss cs => fun _ => dersl rules (concat pss) cs)).
+apply asmI.
+intros. eapply dtderI. eassumption.
+subst. assumption.
+simpl. apply dtNil.
+intros. simpl. apply dtCons ; assumption. Qed.
+ +
+Definition dercl_derl X rules := fst (@dercl_derl' X rules).
+Definition dercsl_dersl X rules := snd (@dercl_derl' X rules).
+ +
+Lemma derl_dercl: forall X (rules : list X -> X -> Type),
+  forall ps c, derl rules ps c -> dercl rules ps c.
+Proof. intros X rules.
+eapply (drl_allT (dercl rules) (ccps (dercsl rules))).
+apply casmI.
+{ intros. destruct X0. subst.
+eapply dtcderI. eassumption. eassumption. }
+{ eapply ccpsI. apply dtcNil. simpl. reflexivity. }
+{ intros. destruct X1. subst.
+eapply ccpsI. eapply dtcCons ; eassumption.
+simpl. reflexivity. } Qed.
+ +
+Lemma derl_all_rect: forall X (rules Q : list X -> X -> Type),
+  (forall p : X, Q [p] p) ->
+  (forall pss qs ps concl, rules ps concl -> dersl rules qs ps ->
+    Forall2T Q pss ps -> qs = concat pss -> Q qs concl) ->
+  forall ps c, derl rules ps c -> Q ps c.
+Proof. intros X rules Q asm dtd.
+eapply (drl_allT Q (ccps (Forall2T Q))).
+exact asm.
+{ intros. destruct X0. subst.
+eapply dtd. eassumption. eassumption. eassumption. reflexivity. }
+{ eapply ccpsI. apply Forall2T_nil. simpl. reflexivity. }
+{ intros. destruct X1. subst.
+eapply ccpsI. eapply Forall2T_cons ; eassumption.
+simpl. reflexivity. } Qed.
+(*
+Check derl_all_rect.  
+Check derl_dercl. 
+Check dercl_derl.
+*)

+(* no convenient way of expressing the corresponding result
+  for dercsl except using sth like allrel *)

+ +
+Lemma derrec_same: forall X rules prems (c c' : X),
+  derrec rules prems c -> c = c' -> derrec rules prems c'.
+Proof. intros. subst. assumption. Qed.
+ +
+(* further detailed versions of derrec_same *)
+Lemma derrec_same_nsL: forall Y X D rules prems G H unk0 d (unk1 unk1' : X),
+  derrec rules prems (G ++ (unk1 : X, unk0 : Y, d : D) :: H) ->
+    unk1 = unk1' -> derrec rules prems (G ++ (unk1', unk0, d) :: H).
+Proof. intros. subst. assumption. Qed.
+ +
+Lemma derrec_same_nsR: forall Y X D rules prems G H unk1 d (unk0 unk0' : X),
+  derrec rules prems (G ++ (unk1 : Y, unk0 : X, d : D) :: H) ->
+    unk0 = unk0' -> derrec rules prems (G ++ (unk1, unk0', d) :: H).
+Proof. intros. subst. assumption. Qed.
+ +
+Lemma dersrec_all: forall X rules prems (cs : list X),
+  iffT (dersrec rules prems cs) (ForallT (derrec rules prems) cs).
+Proof. intros.
+induction cs ; unfold iffT ; apply pair ; intro.
+apply ForallT_nil. apply dlNil.
+inversion X0. apply ForallT_cons. assumption.
+unfold iffT in IHcs. destruct IHcs. tauto.
+inversion X0. subst. apply dlCons. assumption.
+unfold iffT in IHcs. destruct IHcs. tauto.
+Qed.
+ +
+Definition dersrecD_all X rs ps cs := iffT_D1 (@dersrec_all X rs ps cs).
+Definition dersrecI_all X rs ps cs := iffT_D2 (@dersrec_all X rs ps cs).
+ +
+Lemma prems_dersrec X rules prems cs:
+  ForallT prems cs -> @dersrec X rules prems cs.
+Proof. induction cs ; intros. apply dlNil.
+inversion X0. subst. apply dlCons. apply dpI. assumption. tauto. Qed.
+ +
+Lemma dersrec_forall: forall X rules prems (cs : list X),
+  iffT (dersrec rules prems cs) (forall c, InT c cs -> derrec rules prems c).
+Proof. intros. rewrite dersrec_all. rewrite ForallT_forall. reflexivity. Qed.
+ +
+Definition dersrecD_forall X rs ps cs := iffT_D1 (@dersrec_forall X rs ps cs).
+Definition dersrecI_forall X rs ps cs := iffT_D2 (@dersrec_forall X rs ps cs).
+ +
+Lemma dersrec_nil: forall X rules prems, dersrec rules prems ([] : list X).
+Proof. apply dlNil. Qed.
+ +
+(* this is very difficult for such an obvious result,
+  better if we can rewrite based on iffT *)

+Lemma dersrec_app: forall X rules prems cs ds,
+  iffT (dersrec rules prems (cs ++ ds : list X))
+    (prod (dersrec rules prems cs) (dersrec rules prems ds)).
+Proof. intros. eapply iffT_trans. apply dersrec_forall.
+unfold iffT. split ; intros.
+split ; apply dersrecI_forall ; intros ; apply X0.
+apply InT_appL. assumption. apply InT_appR. assumption.
+apply InT_appE in X1. sD.
+eapply dersrecD_forall. 2 : eassumption. assumption.
+eapply dersrecD_forall. 2 : eassumption. assumption. Qed.
+ +
+Definition dersrec_appD X rules prems cs ds :=
+  iffT_D1 (@dersrec_app X rules prems cs ds).
+Definition dersrec_appL X rules prems cs ds da :=
+  fst (@dersrec_appD X rules prems cs ds da).
+Definition dersrec_appR X rules prems cs ds da :=
+  snd (@dersrec_appD X rules prems cs ds da).
+Definition dersrec_appJ X rules prems cs ds :=
+  iffT_D2 (@dersrec_app X rules prems cs ds).
+Definition dersrec_appI X rules prems cs ds :=
+  curry (@dersrec_appJ X rules prems cs ds).
+ +
+Lemma dersrec_single: forall X rules prems c,
+  iffT (dersrec rules prems [c]) (derrec rules prems (c : X)).
+Proof. intros. rewrite dersrec_all. rewrite ForallT_single. reflexivity. Qed.
+ +
+Definition dersrec_singleD X rs ps c := iffT_D1 (@dersrec_single X rs ps c).
+Definition dersrec_singleI X rs ps c := iffT_D2 (@dersrec_single X rs ps c).
+ +
+Lemma dersrec_map_single: forall X Y (f : X -> Y) rules prems c,
+  iffT (dersrec rules prems (map f [c])) (derrec rules prems (f c)).
+Proof. simpl. intros. apply dersrec_single. Qed.
+ +
+Lemma dersrec_map_2: forall X Y (f : X -> Y) rules prems c d,
+  iffT (dersrec rules prems (map f [c ; d]))
+    (derrec rules prems (f c) * derrec rules prems (f d)).
+Proof. intros. rewrite dersrec_all. rewrite ForallT_map_2. reflexivity. Qed.
+ +
+(* try using the induction principle derrec_all_rect *)
+Theorem derrec_trans_imp: forall X rules prems (concl : X),
+  derrec rules (derrec rules prems) concl -> derrec rules prems concl.
+Proof. intros. revert X0.
+eapply derrec_all_rect. tauto.
+intros. eapply derI. exact X0.
+apply dersrecI_all. exact X2. Qed.
+ +
+Lemma derrec_rmono_s: forall W (rulesa rulesb : rlsT W) prems,
+  rsub rulesa rulesb ->
+  (forall concl, derrec rulesa prems concl -> derrec rulesb prems concl) *
+  (forall cs, dersrec rulesa prems cs -> dersrec rulesb prems cs).
+Proof. intros. apply derrec_dersrec_rect_mut ; intros.
+- apply dpI. assumption.
+- eapply derI. unfold rsub in X. apply X. eassumption. assumption.
+- apply dlNil.
+- apply dlCons ; assumption. Qed.
+ +
+Definition derrec_rmono W rulesa rulesb prems concl rs :=
+  fst (@derrec_rmono_s W rulesa rulesb prems rs) concl.
+Definition dersrec_rmono W rulesa rulesb prems rs :=
+  snd (@derrec_rmono_s W rulesa rulesb prems rs).
+ +
+Theorem derl_derrec_trans': forall X rules prems,
+  (forall rps (concl : X), derl rules rps concl ->
+    dersrec rules prems rps -> derrec rules prems concl) *
+  (forall rps cs, dersl rules rps cs ->
+    dersrec rules prems rps -> dersrec rules prems cs).
+Proof. intros.
+apply derl_dersl_rect_mut.
+- intros. inversion X0. assumption.
+- intros. eapply derI. eassumption. tauto.
+- tauto.
+- intros ps c pss cs. intros dc dsdc dscs dspc dspps.
+apply dersrecD_all in dspps. apply dlCons.
++ apply dsdc. apply ForallT_appendD1 in dspps.
+apply dersrecI_all. exact dspps.
++ apply dspc. apply ForallT_appendD2 in dspps.
+apply dersrecI_all. exact dspps. Qed.
+ +
+Definition derl_derrec_trans X rules prems :=
+  fst (@derl_derrec_trans' X rules prems).
+Definition dersl_dersrec_trans X rules prems :=
+  snd (@derl_derrec_trans' X rules prems).
+ +
+Theorem derrec_derl_deriv': forall X rules prems,
+  (forall (concl : X),
+    derrec (derl rules) prems concl -> derrec rules prems concl) *
+  (forall cs, dersrec (derl rules) prems cs -> dersrec rules prems cs).
+Proof. intros.
+apply derrec_dersrec_rect_mut.
+- apply dpI.
+- intros. eapply derl_derrec_trans in r. eassumption. assumption.
+- apply dlNil.
+- intros. apply dlCons ; assumption. Qed.
+ +
+Definition derrec_derl_deriv X rules prems :=
+  fst (@derrec_derl_deriv' X rules prems).
+Definition dersrec_derl_deriv X rules prems :=
+  snd (@derrec_derl_deriv' X rules prems).
+ +
+Definition derl_derrec X rules prems rps (concl : X) drrc prems_cond :=
+  @derl_derrec_trans X rules prems rps (concl : X) drrc
+    (@prems_dersrec X rules prems rps prems_cond).
+ +
+Definition derl_derrec_nil X rules prems (concl : X) drrc :=
+  @derl_derrec_trans X rules prems [] (concl : X) drrc
+    (@dlNil X rules prems).
+ +
+Lemma dersl_dersrec_nil X rules prems (cs : list X):
+  dersl rules [] cs -> dersrec rules prems cs.
+Proof. induction cs ; intros. apply dlNil.
+inversion X0. destruct ps. simpl in H0. subst.
+apply dlCons. apply derl_derrec_nil. assumption. tauto.
+simpl in H0. discriminate H0. Qed.
+ +
+Lemma dersl_cons: forall X rules qs p (ps : list X),
+  dersl rules qs (p :: ps) -> sigT (fun qsa => sigT (fun qsb =>
+    prod (qs = qsa ++ qsb) (prod (derl rules qsa p) (dersl rules qsb ps)))).
+Proof. intros. inversion X0. subst.
+eapply existT. eapply existT. apply pair. reflexivity. tauto. Qed.
+ +
+Lemma dersl_app_eq: forall X rules (psa psb : list X) qs,
+  dersl rules qs (psa ++ psb) -> sigT (fun qsa => sigT (fun qsb =>
+    prod (qs = qsa ++ qsb) (prod (dersl rules qsa psa) (dersl rules qsb psb)))).
+Proof. intro. intro. intro. intro. induction psa. intros.
+apply existT with []. apply existT with qs. simpl. simpl in X0.
+apply pair. trivial.
+apply pair. apply dtNil. apply X0.
+ +
+simpl. intros. apply dersl_cons in X0.
+cD. pose (IHpsa _ X4). cD. subst.
+eapply existT. eapply existT.
+apply pair. apply app_assoc. apply pair.
+apply dtCons. assumption. assumption. assumption.
+Qed.
+ +
+Lemma derl_trans': forall X (rules : list X -> X -> Type),
+  (forall (rps : list X) (concl : X), derl rules rps concl ->
+  forall (pss : list X), dersl rules pss rps -> derl rules pss concl) *
+  (forall (rps : list X) (cs : list X), dersl rules rps cs ->
+  forall (pss : list X), dersl rules pss rps -> dersl rules pss cs).
+Proof. intros.
+apply derl_dersl_rect_mut.
+- intros. inversion_clear X0. inversion_clear X2.
+rewrite app_nil_r. assumption.
+- intros pss ps concl. intros rps dsl dsds pss0 ds0. apply dsds in ds0.
+eapply dtderI. eassumption. assumption.
+- intros. assumption.
+- intros ps c pss cs. intros d dsd dsl dsds pss0 dspps.
+apply dersl_app_eq in dspps. cD. subst. apply dtCons.
+apply dsd. assumption. apply dsds. assumption. Qed.
+ +
+Definition derl_trans X rules pss rps concl d :=
+  fst (@derl_trans' X rules) rps concl d pss.
+Definition dersl_trans X rules pss rps cs ds :=
+  snd (@derl_trans' X rules) rps cs ds pss.
+ +
+(* alternatively, just induction on the list of conclusions *)
+Lemma dersl_trans_alt: forall X (rules : list X -> X -> Type)
+           (cs rps : list X), dersl rules rps cs ->
+         forall (pss : list X), dersl rules pss rps -> dersl rules pss cs.
+Proof. intro. intro. intro.
+induction cs.
+intros. inversion X0. subst. assumption.
+intros. apply dersl_cons in X0. cD. subst.
+apply dersl_app_eq in X1. cD. subst.
+apply dtCons. eapply derl_trans. eassumption. assumption.
+firstorder. Qed.
+ +
+Theorem derl_dersl_deriv': forall X rules,
+  (forall prems (concl : X),
+    derl (derl rules) prems concl -> derl rules prems concl) *
+  (forall prems cs,
+    dersl (derl rules) prems cs -> dersl rules prems cs).
+Proof. intros.
+apply derl_dersl_rect_mut.
+- intro. apply asmI.
+- intros. eapply derl_trans. eassumption. assumption.
+- apply dtNil.
+- intros. apply dtCons. assumption. assumption. Qed.
+ +
+Definition derl_deriv' X rules := fst (@derl_dersl_deriv' X rules).
+Definition dersl_deriv' X rules := snd (@derl_dersl_deriv' X rules).
+Definition derl_deriv X rules := rsubI _ _ (@derl_deriv' X rules).
+Definition dersl_deriv X rules := rsubI _ _ (@dersl_deriv' X rules).
+ +
+Theorem derl_dersl_mono': forall X rulesa rulesb, rsub rulesa rulesb ->
+  (forall prems (concl : X),
+    derl rulesa prems concl -> derl rulesb prems concl) *
+  (forall prems cs,
+    dersl rulesa prems cs -> dersl rulesb prems cs).
+Proof. intros X rulesa rulesb rsab.
+apply derl_dersl_rect_mut.
+- apply asmI.
+- intros. eapply dtderI. unfold rsub in rsab.
+apply rsab. eassumption. assumption.
+- apply dtNil.
+- intros. apply dtCons. assumption. assumption. Qed.
+ +
+Definition derl_mono' X rulesa rulesb rsab :=
+  fst (@derl_dersl_mono' X rulesa rulesb rsab).
+Definition dersl_mono' X rulesa rulesb rsab :=
+  snd (@derl_dersl_mono' X rulesa rulesb rsab).
+ +
+Definition derl_mono X rulesa rulesb rsab :=
+  rsubI _ _ (@derl_mono' X rulesa rulesb rsab).
+Definition dersl_mono X rulesa rulesb rsab :=
+  rsubI _ _ (@dersl_mono' X rulesa rulesb rsab).
+ +
+Lemma derrec_nil_derl_s X rules: (forall concl,
+  derrec rules (@emptyT X) concl -> derl rules [] concl) *
+  (forall cs, dersrec rules (@emptyT X) cs -> dersl rules [] cs).
+Proof.
+apply derrec_dersrec_rect_mut ; intros.
+- inversion p.
+- eapply dtderI ; eassumption.
+- apply dtNil.
+- eapply dtCons_eq. eassumption. eassumption. tauto. Qed.
+ +
+Definition derrec_nil_derl X rules := fst (@derrec_nil_derl_s X rules).
+Definition dersrec_nil_dersl X rules := snd (@derrec_nil_derl_s X rules).
+ +
+Definition derI_rules_mono X rules rulesb prems ps concl rs fuv :=
+  @derI X rulesb prems ps concl (@rsub_imp _ _ rules rulesb rs ps concl fuv).
+(*
+Check derrec_trans_imp.
+Check derl_derrec_trans.
+Check derrec_derl_deriv.
+Check dersl_app_eq.
+Check derl_trans.
+Check dersl_trans.
+Check derl_deriv.
+*)

+ +
+
+ +
+induction for two proof trees +
+
+ +
+Lemma derrec_all_rect2:
+  forall X Y (rulesx : list X -> X -> Type) (rulesy : list Y -> Y -> Type)
+    (premsx : X -> Type) (premsy : Y -> Type) (Q : X -> Y -> Type),
+    (forall px, premsx px -> forall cy, derrec rulesy premsy cy -> Q px cy) ->
+    (forall py, premsy py -> forall cx, derrec rulesx premsx cx -> Q cx py) ->
+    (forall psx cx psy cy, rulesx psx cx -> rulesy psy cy ->
+      dersrec rulesx premsx psx -> dersrec rulesy premsy psy ->
+      ForallT (fun px => Q px cy) psx -> ForallT (Q cx) psy -> Q cx cy) ->
+    forall (conclx : X), derrec rulesx premsx conclx ->
+    forall (concly : Y), derrec rulesy premsy concly ->
+    Q conclx concly.
+Proof. intros until conclx. intro Dx.
+eapply (derrec_all_rect (Q := fun conclx =>
+  forall concly : Y, derrec rulesy premsy concly -> Q conclx concly)).
+intros. apply X0. exact X3. exact X4.
+intros until concly. intro Dy.
+eapply (derrec_all_rect (Q := Q concl)).
+intros. apply X1. exact X6. eapply derI ; eassumption.
+intros. eapply X2. eassumption. eassumption. assumption. assumption.
+eapply ForallT_impl in X5. exact X5.
+intros. simpl. apply X9. eapply derI ; eassumption.
+assumption. assumption. assumption. Qed.
+(*
+Check derrec_all_rect2.
+*)

+(* version with no premises *)
+Definition derrec_all_rect2_nops X Y rulesx rulesy Q :=
+  @derrec_all_rect2 X Y rulesx rulesy emptyT emptyT Q
+  (@emptyT_any' X _) (@emptyT_any' Y _).
+(*
+Check derrec_all_rect2_nops.
+*)

+
+ +
+admissibility +
+
+ +
+Inductive adm X rules ps c : Type :=
+  | admI : (dersrec rules (@emptyT X) ps -> derrec rules (@emptyT X) c) ->
+    adm X rules ps c.
+ +
+Definition admD X rules ps c (a : @adm X rules ps c) :=
+  match a with | admI d => d end.
+Definition admDs X rules p c a d := @admD X rules [p] c a (dersrec_singleI d).
+ +
+Lemma derl_sub_adm X rules ps c : @derl X rules ps c -> adm rules ps c.
+Proof. intro. apply admI. apply derl_derrec_trans. assumption. Qed.
+ +
+Definition rsub_derl_adm X rules := rsubI _ _ (@derl_sub_adm X rules).
+ +
+Definition in_adm X rules ps c r := derl_sub_adm (@in_derl X rules ps c r).
+Definition rsub_adm X rules := rsubI _ _ (@in_adm X rules).
+ +
+Lemma derrec_adm' X rls:
+  (forall c, derrec (adm rls) (@emptyT X) c -> derrec rls (@emptyT X) c) *
+  (forall cs, dersrec (adm rls) (@emptyT X) cs -> dersrec rls (@emptyT X) cs).
+Proof. apply derrec_dersrec_rect_mut ; intros.
+- inversion p.
+- inversion r. apply X1. apply X0.
+- apply dlNil.
+- apply dlCons ; assumption. Qed.
+ +
+Definition derrec_adm X rls := fst (@derrec_adm' X rls).
+Definition dersrec_adm X rls := snd (@derrec_adm' X rls).
+ +
+Lemma adm_adm X rules ps c : @adm X (adm rules) ps c -> adm rules ps c.
+Proof. intros aa. inversion aa. apply admI. intros dps.
+apply derrec_adm. apply X0. eapply dersrec_rmono.
+apply rsubI. apply in_adm. assumption. Qed.
+ +
+Lemma derl_adm_s X rules :
+  (forall ps (c : X), derl (adm rules) ps c -> adm rules ps c) *
+  (forall ps cs, dersl (adm rules) ps cs -> ForallT (adm rules ps) cs).
+Proof. apply derl_dersl_rect_mut ; intros.
+- apply admI. intro. inversion X0. assumption.
+- apply admI. destruct r. intros dpss. apply d0.
+apply dersrecI_forall. intros c icp.
+eapply ForallTD_forall in X0.
+destruct X0. apply d1. apply dpss. apply icp.
+- apply ForallT_nil.
+- apply ForallT_cons. apply admI. inversion X0.
+intro. apply X2. apply dersrec_appL in X3. assumption.
+apply ForallTI_forall. intros x ixcs.
+apply admI. intros dsa.
+eapply ForallTD_forall in X1.
+inversion X1. apply X2. apply dersrec_appR in dsa.
+exact dsa. exact ixcs. Qed.
+ +
+Definition derl_adm X rules := fst (@derl_adm_s X rules).
+Definition dersl_adm X rules := snd (@derl_adm_s X rules).
+ +
+(* also adm (derl rules) = adm rules *)
+ +
+(* plug-in replacement for derl_derrec_trans *)
+Lemma adm_derrec_trans X rules rps concl: @adm X rules rps concl ->
+  dersrec rules (@emptyT X) rps -> derrec rules (@emptyT X) concl.
+Proof. intros a drs. destruct a. apply d. apply drs. Qed.
+ +
+Lemma adm_single_trans X rules prems p c:
+  adm rules prems p -> @adm X rules [p] c -> adm rules prems c.
+Proof. split. destruct X0. inversion X1.
+intro dps. apply X0. right. apply (d dps). left. Qed.
+ +
+Lemma derrec_eq_swap : forall (T : Type) rules prems G H
+    (pf : (G : T) = H),
+    derrec rules prems G ->
+    derrec rules prems H.
+Proof. intros. subst. assumption. Qed.
+ +
+Lemma dersrec_double: forall X rules prems c1 c2,
+  iffT (dersrec rules prems [c1;c2]) ((derrec rules prems (c1 : X)) * (derrec rules prems (c2 : X))).
+Proof.
+  intros. split; intros H.
+  split; (eapply dersrecD_forall; [apply H |]).
+  constructor 1. reflexivity.
+  constructor 2. constructor 1. reflexivity.
+  eapply dersrecI_forall. intros c Hc.
+  inversion Hc as [ | ? ? H2]; subst. apply H.
+  inversion H2 as [ | ? ? H3]; subst. apply H.
+  inversion H3.
+Qed.
+ +
+Definition dersrec_doubleD X rs ps c1 c2 := iffT_D1 (@dersrec_double X rs ps c1 c2).
+
+
+ +
+ + + diff --git a/General.dd_fc.html b/General.dd_fc.html new file mode 100644 index 0000000..fa1a565 --- /dev/null +++ b/General.dd_fc.html @@ -0,0 +1,865 @@ + + + + + + + + + + + + + +
+
+

General.dd_fc

+ +
+ +
+
+ +
+results relating to derivation trees (derrec, dersrec) as data structures, + like Isabelle dertrees, rather than purely as properties of conclusions, + including use of derrec_fc ie without the conclusion as part of the type +
+
+ +
+Require Export List.
+Set Implicit Arguments.
+Export ListNotations.
+ +
+Require Import Coq.Program.Equality. (* for dependent induction/destruction *)
+ +
+Require Import genT gen ddT existsT.
+Require Import PeanoNat.
+Require Import Lia.
+ +
+(* tried to do an inductive property where property Q also involved the 
+proof tree (as well as the endsequent): this created a problem that
+the list of proof trees which are part of the dersrec object are not 
+all of the same type - so one cannot go from 
+ds : dersrec rules prems concls to ForallT (dersrec rules prems ??) ds'
+instead need to define allPder and do the following *)

+ +
+Inductive allPder X (rules : rlsT X) (prems : X -> Type) P :
+  forall concls : list X, dersrec rules prems concls -> Type :=
+  | allPder_Nil : @allPder X rules prems P [] (dlNil rules prems)
+  | allPder_Cons : forall seq seqs d, P seq d -> forall ds,
+    @allPder X rules prems P seqs ds ->
+    @allPder X rules prems P (seq :: seqs) (dlCons d ds)
+  .
+ +
+Lemma allPderD : forall X rules prems Q ps (dpss : dersrec rules prems ps) p,
+  allPder Q dpss -> InT (p : X) ps -> {d : derrec rules prems p & Q p d}.
+Proof. induction ps.
+intros. inversion X1.
+intros dpss p adp inp. inversion adp. subst.
+inversion inp ; subst.
+exists d. assumption.
+clear X0 inp adp. exact (IHps ds p X1 X2). Qed.
+ +
+(* destruct for allPder dlCons *)
+Lemma allPder_dlConsD: forall X rules prems Q seq seqs d ds,
+  @allPder X rules prems Q (seq :: seqs) (dlCons d ds) ->
+    Q seq d * allPder Q ds.
+Proof.
+intros. (* inversion X0 produces existT equalities *)
+(* induction X0 produces trivial subgoal 2, unsolvable subgoal 1 *)
+(* dependent induction X0. OK, but irrelevant IHX0, trivial subgoal *)
+dependent destruction X0.
+split ; assumption. Qed.
+ +
+Definition derrec_rect_mut_all X (rules : rlsT X) prems Q cl1 cl2 :=
+  derrec_rect_mut Q (@allPder X rules prems Q) cl1 cl2
+    (allPder_Nil Q) (@allPder_Cons X rules prems Q).
+(*
+Check derrec_rect_mut_all.
+*)

+Inductive in_dersrec X (rules : rlsT X) prems concl
+  (d : derrec rules prems concl) :
+  forall concls, dersrec rules prems concls -> Type :=
+  | in_dersrec_hd : forall concls ds, in_dersrec d
+    (@dlCons X rules prems concl concls d ds)
+  | in_dersrec_tl : forall concl' d' concls ds, in_dersrec d ds ->
+    in_dersrec d (@dlCons X rules prems concl' concls d' ds)
+  .
+ +
+Inductive is_nextup X (rules : rlsT X) prems (concl : X) (concls : list X)
+  (ds : dersrec rules prems concls) : derrec rules prems concl -> Type :=
+  | is_nextupI : forall rps, is_nextup ds (derI concl rps ds)
+  (* can't make this next line work
+  | is_nextup_nil : is_nextup (dlNil rules prems) (dpI _ _ _ _) 
+  *)

+  .
+ +
+Inductive in_nextup X (rules : rlsT X) prems (concln concl : X)
+  (dn : derrec rules prems concln) (d : derrec rules prems concl) : Type :=
+  | in_nextupI : forall concls (ds : dersrec rules prems concls),
+      is_nextup ds d -> in_dersrec dn ds -> in_nextup dn d
+  .
+ +
+Lemma in_drs_concl_in W rules ps (cn : W) (drs : dersrec rules emptyT ps)
+  (dtn : derrec rules emptyT cn) : in_dersrec dtn drs -> InT cn ps.
+Proof. intro ind. induction ind. apply InT_eq.
+apply InT_cons. assumption. Qed.
+ +
+Lemma in_nextup_concl_in W rules ps (concl cn : W) rpc
+  (drs : dersrec rules emptyT ps) (dtn : derrec rules emptyT cn) :
+  in_nextup dtn (derI concl rpc drs) -> InT cn ps.
+Proof. intro ind. inversion ind. inversion X. subst.
+dependent destruction H2. clear H1 rps0 ind X.
+exact (in_drs_concl_in X0). Qed.
+ +
+Lemma all_in_d_allP: forall X rules prems Q ps (dpss : dersrec rules prems ps),
+  (forall (p : X) (d : derrec rules prems p), in_dersrec d dpss -> Q p d) ->
+  allPder Q dpss.
+Proof. induction dpss. intros. apply allPder_Nil.
+intros. apply allPder_Cons. apply X0. apply in_dersrec_hd.
+apply IHdpss. intros. apply X0. apply in_dersrec_tl. assumption. Qed.
+(* alternative proof, longer, shows need to use dependent inversion 
+Proof. induction ps. intros. dependent inversion dpss. apply allPder_Nil.
+intro. dependent inversion dpss. subst. 
+intros.  apply allPder_Cons. apply X0. apply in_dersrec_hd.
+apply IHps. intros. apply X0. apply in_dersrec_tl. assumption. Qed.
+*)

+ +
+Lemma allP_all_in_d: forall X rules prems Q ps (dpss : dersrec rules prems ps),
+  allPder Q dpss ->
+  forall (p : X) (d : derrec rules prems p), in_dersrec d dpss -> Q p d.
+Proof. induction ps. intro. dependent inversion dpss.
+intros. inversion X1.
+intro. dependent inversion dpss. subst.
+intro. (* inversion X0 gives existT equalities *)
+dependent destruction X0.
+intros. (* inversion X1 gives existT equalities *)
+dependent destruction X1. assumption.
+eapply IHps. eassumption. assumption. Qed.
+ +
+Lemma allPderD_in :
+  forall X rules prems Q ps (dpss : dersrec rules prems ps) p,
+    allPder Q dpss -> InT (p : X) ps ->
+      {d : derrec rules prems p & in_dersrec d dpss & Q p d}.
+Proof. induction ps.
+intros. inversion X1.
+intros dpss p adp inp. dependent destruction adp.
+inversion inp ; subst.
+exists d. apply in_dersrec_hd. assumption.
+pose (IHps ds p adp X0). destruct s. (* cD doesn't work here - why?? *)
+exists x. apply in_dersrec_tl. assumption. assumption. Qed.
+(*
+Check allPderD_in.
+*)

+Fixpoint derrec_height X rules prems concl
+  (der : @derrec X rules prems concl) :=
+  match der with
+    | dpI _ _ _ _ => 0
+    | derI _ _ ds => S (dersrec_height ds)
+  end
+with dersrec_height X rules prems concls
+  (ders : @dersrec X rules prems concls) :=
+  match ders with
+    | dlNil _ _ => 0
+    | dlCons d ds => max (derrec_height d) (dersrec_height ds)
+  end.
+ +
+Fixpoint derrec_size X rules prems concl
+  (der : @derrec X rules prems concl) :=
+  match der with
+    | dpI _ _ _ _ => 0
+    | derI _ _ ds => S (dersrec_size ds)
+  end
+with dersrec_size X rules prems concls
+  (ders : @dersrec X rules prems concls) :=
+  match ders with
+    | dlNil _ _ => 0
+    | dlCons d ds => (derrec_size d) + (dersrec_size ds)
+  end.
+ +
+Definition derrec_concl X rules prems concl
+  (der : @derrec X rules prems concl) :=
+  match der with
+    | dpI _ _ c _ => c
+    | derI c _ _ => c
+  end.
+ +
+Fixpoint dersrec_concls X rules prems concls
+  (ders : @dersrec X rules prems concls) :=
+  match ders with
+    | dlNil _ _ => []
+    | dlCons d ds => derrec_concl d :: dersrec_concls ds
+  end.
+ +
+Definition der_botr_ps X rules prems concl
+  (der : @derrec X rules prems concl) :=
+  match der with
+    | dpI _ _ _ _ => []
+    | @derI _ _ _ ps _ _ _ => ps
+  end.
+ +
+Definition dersrec_hd X rules prems c cs
+  (ders : @dersrec X rules prems (c :: cs)) : derrec rules prems c :=
+  match
+    ders in (dersrec _ _ l) return match l with
+                                   | [] => IDProp
+                                   | c1 :: _ => derrec rules prems c1
+                                   end
+  with
+  | dlNil _ _ => idProp
+  | dlCons d _ => d
+  end.
+ +
+Definition dersrec_tl X rules prems c cs
+  (ders : @dersrec X rules prems (c :: cs)) :=
+  match
+    ders as ders0 in (dersrec _ _ l)
+    return
+      (match l as x return (dersrec rules prems x -> Type) with
+       | [] => fun _ : dersrec rules prems [] => IDProp
+       | c1 :: c0 => fun _ : dersrec rules prems (c1 :: c0) => dersrec rules prems c0
+       end ders0)
+  with
+  | dlNil _ _ => idProp
+  | dlCons _ ds => ds
+  end.
+ +
+Definition dersrec_singleD' X rules prems c
+  (ders : @dersrec X rules prems [c]) := dersrec_hd ders.
+ +
+Definition dersrec_singleI' X rules prems c
+  (d : @derrec X rules prems c) := dlCons d (@dlNil X rules prems).
+ +
+Definition dersrec_single' X rules prems c :=
+  (@dersrec_singleD' X rules prems c, @dersrec_singleI' X rules prems c).
+ +
+(*
+Lemma in_dersrec_single X rs ps c (ds : @dersrec X rs ps c) :
+  in_dersrec (dersrec_singleD ds) ds.
+Proof. dependent destruction ds.  (* dependent induction ds. also seems OK *)
+HOW TO CONTINUE PROOF ?? NB works better for dersrec_singleD'
+*)

+ +
+Lemma botr_ps_der W rules prems c (d : derrec rules prems c) :
+  @dersrec W rules prems (der_botr_ps d).
+Proof. destruct d ; simpl. apply dlNil. apply d. Qed.
+ +
+Lemma in_dersrec_single' X rs ps c (ds : @dersrec X rs ps [c]) :
+  in_dersrec (dersrec_singleD' ds) ds.
+Proof. dependent destruction ds. (* dependent induction ds. also seems OK,
+but dependent inversion gives a type error *)

+unfold dersrec_singleD'. simpl. apply in_dersrec_hd. Qed.
+ +
+(* can't do this, gives The term "ds" has type "dersrec rules prems l"
+  while it is expected to have type "dersrec rules prems ".  
+Fixpoint derrec_nextup X rules prems concl
+  (der : @derrec X rules prems concl) :=
+  match der with 
+    | dpI _ _ _ _ => dlNil rules prems 
+    | derI _ _ ds => ds
+  end.
+*)

+ +
+Lemma dersrec_hd_eq X rs ps c cs
+  (d : @derrec X rs ps c) (ds : @dersrec X rs ps cs) :
+  dersrec_hd (dlCons d ds) = d.
+Proof. simpl. reflexivity. Qed.
+ +
+Lemma dersrec_tl_eq X rs ps c cs
+  (d : @derrec X rs ps c) (ds : @dersrec X rs ps cs) :
+  dersrec_tl (dlCons d ds) = ds.
+Proof. simpl. reflexivity. Qed.
+ +
+Lemma in_drs_drs_hd X rs ps c cs (ds : @dersrec X rs ps (c :: cs)) :
+  in_dersrec (dersrec_hd ds) ds.
+Proof. dependent destruction ds. (* dependent induction ds. also seems OK *)
+simpl. apply in_dersrec_hd. Qed.
+ +
+Lemma dersrec_height_nil : forall X rules prems ps (ds : @dersrec X rules prems ps),
+    ps = [] -> dersrec_height ds = 0.
+Proof.
+induction ds.
+- simpl. reflexivity.
+- intro. inversion H.
+Qed.
+ +
+Lemma dersrec_height_le: forall X rules prems n ps
+  (ds : dersrec rules prems ps),
+  (forall (p : X) (d : derrec rules prems p),
+  in_dersrec d ds -> derrec_height d <= n) -> dersrec_height ds <= n.
+Proof. (* induction ps. 
+intros. inversion ds.  this step seems to do nothing *)

+induction ds.
+intros. simpl. apply le_0_n.
+intros. simpl. apply Nat.max_lub.
+apply H. apply in_dersrec_hd.
+apply IHds. intros. apply H. apply in_dersrec_tl. assumption. Qed.
+ +
+Lemma le_dersrec_height: forall X rules prems n ps
+  (ds : dersrec rules prems ps),
+  forall (p : X) (d : derrec rules prems p),
+  in_dersrec d ds -> n <= derrec_height d -> n <= dersrec_height ds.
+Proof. (* induction ps. 
+intros. inversion ds.  this step seems to do nothing *)

+(* this doesn't work - why ??
+induction ds ; intros ; inversion X0 ; subst ; simpl ; rewrite Nat.max_le_iff.
+left. assumption.
+right.  eapply IHds. 2: eassumption.
+WHAT NOW ???
+*)

+intros. induction X0 ; simpl ; rewrite Nat.max_le_iff ; tauto. Qed.
+ +
+(*
+Fixpoint aderrec_height X 
+  (rules : list X -> X -> Prop) (prems : X -> Prop) concl 
+  (der : @aderrec X rules prems concl) :=
+  match der with 
+    | adpI _ _ _ _ => 0
+    | aderI _ _ _ => 0
+  end.
+  *)

+ +
+Fixpoint derl_height X
+  (rules : list X -> X -> Prop) (prems : list X) (concl : X)
+  (der : @derl X rules prems concl) :=
+  match der with
+    | asmI _ _ => 0
+    | dtderI _ _ ds => S (dersl_height ds)
+  end
+with dersl_height X (rules : list X -> X -> Prop) (prems concls : list X)
+  (ders : @dersl X rules prems concls) :=
+  match ders with
+    | dtNil _ => 0
+    | dtCons d ds => max (derl_height d) (dersl_height ds)
+  end.
+ +
+Lemma der_concl_eq: forall X (rules : rlsT X) prems concl
+  (d : derrec rules prems concl), derrec_concl d = concl.
+Proof. dependent inversion d ; simpl ; reflexivity. Qed.
+ +
+Lemma ders_concls_eq: forall X (rules : rlsT X) prems concls
+  (ds : dersrec rules prems concls), dersrec_concls ds = concls.
+Proof. induction ds ; simpl. reflexivity.
+rewrite -> (der_concl_eq d). rewrite IHds. reflexivity. Qed.
+ +
+
+ +
+der(s)rec_fc(s) - trees without conclusion as part of the type +
+
+ +
+Inductive derrec_fc X rules (prems : X -> Type) : Type :=
+  | fcI : forall concl, derrec rules prems concl -> derrec_fc rules prems.
+ +
+Inductive dersrec_fcs X rules (prems : X -> Type) : Type :=
+  | fcsI : forall concls, dersrec rules prems concls -> dersrec_fcs rules prems.
+ +
+Inductive in_nextup_fc X (rules : rlsT X) prems :
+    relationT (derrec_fc rules prems) :=
+  | in_nextup_fcI : forall concln concl
+    (dn : derrec rules prems concln) (d : derrec rules prems concl),
+    in_nextup dn d -> in_nextup_fc (fcI dn) (fcI d)
+  .
+ +
+Lemma AccT_in_nextup_fc X rules prems dt: AccT (@in_nextup_fc X rules prems) dt.
+Proof. destruct dt. revert d. revert concl.
+eapply derrec_rect_mut_all.
+- intros. apply AccT_intro. intros y iny.
+dependent destruction iny. inversion i. inversion X0.
+- intros * apd. apply AccT_intro. intros y iny.
+dependent destruction iny. inversion i. dependent destruction X0.
+exact (allP_all_in_d apd X1). Qed.
+ +
+Fixpoint dersrec_trees X rules prems concls
+  (ders : @dersrec X rules prems concls) :=
+  match ders with
+    | dlNil _ _ => []
+    | dlCons d ds => fcI d :: dersrec_trees ds
+  end.
+ +
+Definition nextup W rules prems (dt : @derrec_fc W rules prems) :=
+  match dt with
+    | fcI (dpI _ _ _ _) => []
+    | fcI (derI _ _ ds) => dersrec_trees ds
+  end.
+ +
+Definition derrec_fc_concl X rules prems
+  (der : @derrec_fc X rules prems) :=
+  match der with
+    | fcI d => derrec_concl d
+  end.
+ +
+Definition dersrec_fc_concls X rules prems
+  (ders : @dersrec_fcs X rules prems) :=
+  match ders with
+    | fcsI ds => dersrec_concls ds
+  end.
+ +
+(* note, this includes case where the tree is simply a premise *)
+Inductive botRule_fc X rules prems (der : @derrec_fc X rules prems) : rlsT X :=
+  | botRule_fcI : botRule_fc der
+    (map (@derrec_fc_concl _ _ _) (nextup der)) (derrec_fc_concl der).
+ +
+(* this fails, d has type "derrec rules prems x", but x not in scope
+Fixpoint derrec_of_fc X rules prems 
+  (der : @derrec_fc X rules prems) :=
+  match der with 
+    | fcI d => d
+  end.
+  *)

+ +
+(* while we can't get something of type derrec rules prems _
+  from something of type derrec_fc ..., we can get it and then
+  apply any function to it whose result type doesn't involve the conclusion *)

+Definition derrec_fc_size X rules prems
+  (der : @derrec_fc X rules prems) :=
+  match der with
+    | fcI d => derrec_size d
+  end.
+ +
+Definition dersrec_fc_size X rules prems
+  (ders : @dersrec_fcs X rules prems) :=
+  match ders with
+    | fcsI ds => dersrec_size ds
+  end.
+ +
+Definition derrec_fc_height X rules prems
+  (der : @derrec_fc X rules prems) :=
+  match der with
+    | fcI d => derrec_height d
+  end.
+ +
+Definition dersrec_fc_height X rules prems
+  (ders : @dersrec_fcs X rules prems) :=
+  match ders with
+    | fcsI ds => dersrec_height ds
+  end.
+ +
+Lemma der_fc_concl_eq: forall X (rules : rlsT X) prems concl
+  (d : derrec rules prems concl), derrec_fc_concl (fcI d) = concl.
+Proof. simpl. apply der_concl_eq. Qed.
+ +
+Lemma dersrec_trees_concls_eq X rules prems ps (ds : dersrec rules prems ps) :
+  map (@derrec_fc_concl X rules prems) (dersrec_trees ds) = ps.
+Proof. induction ds. simpl. reflexivity.
+simpl. rewrite (der_concl_eq d). rewrite IHds. reflexivity. Qed.
+ +
+Lemma der_botr_ps_eq X rules prems c (dt : derrec rules prems c) :
+  map (@derrec_fc_concl X rules prems) (nextup (fcI dt)) = der_botr_ps dt.
+Proof. destruct dt ; simpl. reflexivity. apply dersrec_trees_concls_eq. Qed.
+ +
+Lemma der_der_fc X rules prems (der : @derrec_fc X rules prems) :
+  derrec rules prems (derrec_fc_concl der).
+Proof. destruct der. simpl. rewrite der_concl_eq. exact d. Qed.
+ +
+Lemma ders_ders_fcs X rules prems (ders : @dersrec_fcs X rules prems) :
+  dersrec rules prems (dersrec_fc_concls ders).
+Proof. destruct ders. simpl. rewrite ders_concls_eq. exact d. Qed.
+ +
+Lemma in_drs_trees: forall X rules prems cs ds c (d : derrec rules prems c),
+  in_dersrec d ds -> InT (fcI d) (@dersrec_trees X rules prems cs ds).
+Proof. intros. induction X0 ; simpl.
+apply InT_eq. apply InT_cons. assumption. Qed.
+ +
+Lemma in_trees_drs: forall X rules prems cs ds c (d : derrec rules prems c),
+  InT (fcI d) (@dersrec_trees X rules prems cs ds) -> in_dersrec d ds.
+Proof. induction cs ; intro ; dependent inversion ds ; simpl ; intros.
+inversion X0.
+(* inversion X0. injection H2. gives existT equality *)
+subst. dependent destruction X0. apply in_dersrec_hd.
+apply in_dersrec_tl. apply IHcs. assumption. Qed.
+ +
+Lemma der_botRule W rules (dt : derrec_fc rules emptyT) :
+  {ps : list W & {c : W & rules ps c & botRule_fc dt ps c}}.
+Proof. destruct dt. destruct d. destruct e.
+exists ps. exists concl. exact r.
+pose botRule_fcI.
+specialize (b W rules emptyT (fcI (derI concl r d))).
+simpl in b. rewrite dersrec_trees_concls_eq in b. exact b. Qed.
+ +
+Lemma botRule_fc_concl W rules prems ps (c : W) (dt : derrec_fc rules prems) :
+  botRule_fc dt ps c -> derrec_fc_concl dt = c.
+Proof. intro br. destruct br. reflexivity. Qed.
+ +
+Lemma botRule_fc_rules W rules ps (c : W) (dt : derrec_fc rules emptyT) :
+  botRule_fc dt ps c -> rules ps c.
+Proof. intro br. destruct br. destruct dt.
+rewrite (der_fc_concl_eq d).
+destruct d. destruct e. simpl.
+rewrite (dersrec_trees_concls_eq d). exact r. Qed.
+ +
+Lemma botRule_fc_drs W rules prems ps (c : W) (dt : derrec_fc rules prems) :
+  botRule_fc dt ps c -> dersrec rules prems ps.
+Proof. intro br. destruct br. destruct dt.
+destruct d. simpl. apply dlNil.
+simpl. rewrite (dersrec_trees_concls_eq d). exact d. Qed.
+ +
+Lemma botRule_fc_ps W rules prems ps (c : W) (dt : derrec_fc rules prems) :
+  botRule_fc dt ps c -> map (@derrec_fc_concl W rules prems) (nextup dt) = ps.
+Proof. intro br. destruct br. destruct dt. reflexivity. Qed.
+ +
+Lemma get_botrule W rules prems (c : W) (dt : derrec rules prems c) :
+  botRule_fc (fcI dt) (der_botr_ps dt) c.
+Proof. rewrite <- der_botr_ps_eq.
+  eapply eq_rect. apply botRule_fcI. apply der_fc_concl_eq. Qed.
+ +
+Definition bot_is_rule W rules (c : W) (dt : derrec rules emptyT c) :=
+  botRule_fc_rules (get_botrule dt).
+ +
+Lemma botRule_fc_prems W rules prems (c : W) (dt : derrec rules prems c) ps c' :
+  botRule_fc (fcI dt) ps c' -> (c = c') * (der_botr_ps dt = ps).
+Proof. intro br. rewrite <- der_botr_ps_eq. rewrite (botRule_fc_ps br).
+split. destruct br. rewrite der_fc_concl_eq. reflexivity. reflexivity. Qed.
+ +
+Lemma in_nextup_eqv W rules prems (concln concl : W)
+  (dtn : derrec rules prems concln) (dt : derrec rules prems concl) :
+  iffT (in_nextup dtn dt) (InT (fcI dtn) (nextup (fcI dt))).
+Proof. apply pair ; intros.
+- destruct X. destruct i. simpl. exact (in_drs_trees i0).
+- simpl in X. destruct dt. inversion X.
+  apply in_trees_drs in X.
+  eapply in_nextupI. apply is_nextupI. exact X. Qed.
+ +
+Definition in_nextup_nu W rules prems concln concl dtn dt :=
+  iffT_D1 (@in_nextup_eqv W rules prems concln concl dtn dt).
+Definition nextup_in_nu W rules prems concln concl dtn dt :=
+  iffT_D2 (@in_nextup_eqv W rules prems concln concl dtn dt).
+ +
+Lemma in_nextup_fc_eqv W rules prems (dtn dt : @derrec_fc W rules prems) :
+  iffT (in_nextup_fc dtn dt) (InT dtn (nextup dt)).
+Proof. apply pair ; intros.
+- destruct X. exact (in_nextup_nu i).
+- destruct dtn. destruct dt. apply in_nextup_fcI. exact (nextup_in_nu _ X).
+Qed.
+ +
+Definition in_nextup_fc_nu W rules prems dtn dt :=
+  iffT_D1 (@in_nextup_fc_eqv W rules prems dtn dt).
+Definition nextup_in_nu_fc W rules prems dtn dt :=
+  iffT_D2 (@in_nextup_fc_eqv W rules prems dtn dt).
+ +
+(* converse to this requires is_nextup (dlNil rules prems) (dpI _ _ _ _) *)
+Lemma is_nextup_ndt W rules prems concls (concl : W)
+  (dts : dersrec rules prems concls)
+  (dt : derrec rules prems concl) :
+  is_nextup dts dt -> nextup (fcI dt) = dersrec_trees dts.
+Proof. unfold nextup. intros. destruct X. reflexivity. Qed.
+ +
+Lemma drs_trees_height W rules prems ps (ds : @dersrec W rules prems ps) dn:
+  InT dn (dersrec_trees ds) -> derrec_fc_height dn <= dersrec_height ds.
+Proof. induction ds ; simpl ; intro inn ; inversion inn.
+subst. simpl. apply PeanoNat.Nat.le_max_l.
+apply (Nat.le_trans _ _ _ (IHds X)). apply PeanoNat.Nat.le_max_r. Qed.
+ +
+Lemma nextup_height W rules prems dt dn: InT dn (nextup dt) ->
+  (@derrec_fc_height W rules prems dn) < derrec_fc_height dt.
+Proof. intro inn. destruct dt. destruct d ; simpl in inn. inversion inn.
+simpl. apply Nat.lt_succ_r, drs_trees_height, inn. Qed.
+ +
+Lemma fcI_inj: forall X rules prems concl (d1 : @derrec X rules prems concl) d2,
+  fcI d1 = fcI d2 -> d1 = d2.
+Proof. intros. (* injection H gives existT equality *)
+  dependent destruction H. reflexivity. Qed.
+ +
+(* this doesn't work - type of Q 
+Goal forall X rules prems Q cs (ds : @dersrec X rules prems cs),
+  allPder Q ds -> Forall2T Q cs (dersrec_trees ds).
+ *)

+ +
+Open Scope type_scope.
+ +
+Lemma dersrecD_forall_in_dersrec : forall (X : Type) (rs : list X -> X -> Type) (ps : X -> Type) (cs : list X) (ds : dersrec rs ps cs) (c : X),
+    InT c cs -> (existsT2 d : derrec rs ps c, in_dersrec d ds).
+Proof.
+  induction ds; intros c Hin.
+  inversion Hin.
+  inversion Hin.
+  + subst. exists d. constructor.
+  + subst. eapply IHds in X0. destruct X0 as [d2 Hin2].
+    exists d2. constructor 2. eapply Hin2.
+Qed.
+ +
+Lemma dersrec_double_verb: forall X rules prems c1 c2 (d : (dersrec rules prems [c1;c2])),
+    existsT2 (d1 : (derrec rules prems (c1 : X))) (d2 : (derrec rules prems (c2 : X))),
+      (in_dersrec d1 d) * (in_dersrec d2 d).
+Proof.
+  intros.
+  assert (InT c1 [c1;c2]) as Hin1. constructor. reflexivity.
+  assert (InT c2 [c1;c2]) as Hin2. constructor 2. constructor. reflexivity.
+  eapply dersrecD_forall_in_dersrec in Hin1.
+  destruct Hin1 as [d1 Hin1]. exists d1.
+  eapply dersrecD_forall_in_dersrec in Hin2.
+  destruct Hin2 as [d2 Hin2]. exists d2.
+  split. apply Hin1. apply Hin2.
+Qed.
+ +
+Definition dp {X : Type} {rules : list X -> X -> Type} {prems : X -> Type}
+  {concl : X} (der : derrec rules prems concl) := @derrec_height X rules prems concl der.
+Lemma dersrec_derrec_height : forall n {X : Type} {rules prems G}
+                                     (D2 : dersrec rules prems [G]),
+    dersrec_height D2 = n ->
+    existsT2 (D1 : derrec rules prems G),
+      @derrec_height X _ _ _ D1 = n.
+Proof.
+  intros *.
+  intros Ht.
+  remember D2 as D2'.
+  remember [G] as GG.
+  destruct D2. discriminate.
+  subst. simpl.
+  inversion HeqGG. subst.
+  exists d.
+  remember [] as l.
+  destruct D2. simpl.
+  rewrite PeanoNat.Nat.max_0_r. reflexivity.
+  discriminate.
+Qed.
+ +
+Lemma dersrec_derrec2_height : forall n {X : Type} {rules prems G1 G2}
+                                     (D2 : dersrec rules prems [G1;G2]),
+    dersrec_height D2 = n ->
+    existsT2 (D1a : derrec rules prems G1) (D1b : derrec rules prems G2),
+     n = max (@derrec_height X _ _ _ D1a) (@derrec_height X _ _ _ D1b).
+Proof.
+  intros *.
+  intros Ht.
+  remember D2 as D2'.
+  remember [G1;G2] as GG.
+  destruct D2. discriminate.
+  destruct seqs. discriminate.
+  destruct seqs. 2 : discriminate.
+  edestruct (@dersrec_derrec_height (@dersrec_height _ _ _ _ D2)_ _ _ _ D2).
+  reflexivity.
+  subst. simpl.
+  inversion HeqGG. subst.
+  exists d. exists x0.
+  rewrite e. reflexivity.
+Qed.
+ +
+Lemma dersrec_derrec_dp : forall n {X : Type} {rules prems G}
+                                     (D2 : dersrec rules prems [G]),
+    dersrec_height D2 = n ->
+    existsT2 (D1 : derrec rules prems G),
+      @dp X _ _ _ D1 = n.
+Proof. eapply dersrec_derrec_height. Qed.
+ +
+Lemma dersrec_derrec2_dp : forall n {X : Type} {rules prems G1 G2}
+                                     (D2 : dersrec rules prems [G1;G2]),
+    dersrec_height D2 = n ->
+    existsT2 (D1a : derrec rules prems G1) (D1b : derrec rules prems G2),
+      n = max (@dp X _ _ _ D1a) (@dp X _ _ _ D1b).
+Proof. eapply dersrec_derrec2_height. Qed.
+ +
+Lemma dersrec_derrec_height_le : forall {T : Type} rules prems ps p
+    (ds : dersrec rules prems ps)
+    (d : derrec rules prems p),
+    in_dersrec d ds ->
+    derrec_height d <= @dersrec_height T _ _ _ ds.
+Proof.
+  intros T rules prems ps p ds d Hin.
+  eapply le_dersrec_height.
+  2 : eapply le_n.
+  assumption.
+Qed.
+ +
+Lemma dp_same : forall {T : Type} {rules prems} (l1 l2 : list T)
+     (D1 : derrec rules prems l1)
+    (Heq : l1 = l2),
+    dp (eq_rect _ (fun l => derrec rules prems l) D1 l2 Heq) = dp D1.
+Proof. induction D1; intros Heq; subst; reflexivity. Qed.
+ +
+Lemma dp_same_fun : forall {T T2 : Type} {rules prems} (l1 l2 : list T) (f : list T -> T2)
+     (D1 : derrec rules prems (f l1))
+    (Heq : l1 = l2),
+    dp (eq_rect _ (fun l => derrec rules prems (f l)) D1 l2 Heq) = dp D1.
+Proof. intros; inversion D1; subst; reflexivity. Qed.
+ +
+Lemma derrec_dp_same :
+  forall {X : Type} rules (prems : X -> Type) G H (D1 : derrec rules prems G),
+    G = H ->
+    existsT2 (D2 : derrec rules prems H), dp D1 = dp D2.
+Proof. intros. subst. exists D1. reflexivity. Qed.
+ +
+Lemma derrec_dp_same2 :
+  forall {X : Type} rules (prems : X -> Type) G (D1 : derrec rules prems G) H,
+    G = H ->
+    existsT2 (D2 : derrec rules prems H), dp D1 = dp D2.
+Proof. intros. subst. exists D1. reflexivity. Qed.
+ +
+Definition get_D {X} rules prems G H D pf :=
+(let (D', HD') := (fun (X : Type) (rules : list X -> X -> Type) (prems : X -> Type)
+  (G H : X) (D1 : derrec rules prems G) (H0 : G = H) =>
+eq_rect_r
+  (fun G0 : X =>
+   forall D2 : derrec rules prems G0,
+   existsT2 D3 : derrec rules prems H, dp D2 = dp D3)
+  (fun D2 : derrec rules prems H =>
+     existT (fun D3 : derrec rules prems H => dp D2 = dp D3) D2 eq_refl) H0 D1)
+              X rules prems
+G H D pf in D').
+ +
+(*
+Parameter (X : Type) (rules : list X -> X -> Type) (prems : X -> Type) 
+  (G H : X) (D : derrec rules prems G) (pf : G = H).
+Compute (get_D rules prems G H D pf).
+*)

+Lemma dp_get_D : forall (X : Type) (rules : list X -> X -> Type) (prems : X -> Type)
+                      (G H : X) (D : derrec rules prems G) (pf : G = H),
+    dp D = dp (get_D D pf).
+Proof. intros. subst. reflexivity. Qed.
+ +
+Definition get_dpD {X : Type} (rules : list X -> X -> Type) (prems : X -> Type) (G H : X)
+  (D : derrec rules prems G) (pf : G = H) :=
EqdepFacts.internal_eq_rew_r_dep
+   (fun (G0 : X) (pf0 : G0 = H) =>
+    forall D0 : derrec rules prems G0, dp D0 = dp (get_D D0 pf0))
+   (fun D0 : derrec rules prems H => eq_refl) pf D.
+ +
+Ltac tfm_dersrec_derrec_dp D2s D2 Hdp HdpD2 Hdp'' Hdp' :=
+  destruct (dersrec_derrec_dp D2s eq_refl) as [D2 HdpD2];
+  match goal with
+  | [ H : dp ?D1 + S (dersrec_height D2s) <= ?m |- _ ] =>
+    assert (dp D1 + (S (dp D2)) <= m) as Hdp'';
+    [rewrite HdpD2; assumption | ];
+    assert (dp D1 + dp D2 <= m - 1) as Hdp';
+    [lia | ]; clear HdpD2 D2s Hdp
+  end.
+ +
+Ltac tfm_dersrec_derrec2_dp D2s D2 Hdp HdpD2 Hdpa'' Hdpb'' Hdpa' Hdpb' HeqD2s Hmax1 Hmax2 :=
+  assert (dersrec_height D2s = dersrec_height D2s) as HeqD2s;
+  [reflexivity |];
+  destruct (dersrec_derrec2_dp D2s HeqD2s) as [D2a [D2b HdpD2]];
+  clear HeqD2s;
+  epose proof (Nat.le_max_r _ _) as Hmax1;
+  epose proof (Nat.le_max_r _ _) as Hmax2;
+  rewrite <- HdpD2 in Hmax1;
+  rewrite <- HdpD2 in Hmax2;
+  match goal with
+  | [ H : dp ?D1 + S (dersrec_height D2s) <= ?m |- _ ] =>
+  assert (dp D1 + (S (dp D2a)) <= m) as Hdpa'';
+  [lia | ];
+  assert (dp D1 + (S (dp D2b)) <= m) as Hdpb'';
+  [lia | ];
+  assert (dp D1 + (dp D2a) <= m - 1) as Hdpa';
+  [lia | ];
+  assert (dp D1 + (dp D2b) <= m - 1) as Hdpb';
+  [lia | ];
+  clear HdpD2 D2s Hdp Hmax1 Hmax2
+  end.
+
+
+ +
+ + + diff --git a/General.existsT.html b/General.existsT.html new file mode 100644 index 0000000..b1bc878 --- /dev/null +++ b/General.existsT.html @@ -0,0 +1,50 @@ + + + + + + + + + + + + + +
+
+

General.existsT

+ +
+Notation "'existsT' x .. y , p" := (sig (fun x => .. (sig (fun y => p)) ..))
+  (at level 200, x binder, right associativity,
+   format "'[' 'existsT' '/ ' x .. y , '/ ' p ']'")
+  : type_scope.
+ +
+Notation "'existsT2' x .. y , p" := (sigT (fun x => .. (sigT (fun y => p)) ..))
+  (at level 200, x binder, right associativity,
+   format "'[' 'existsT2' '/ ' x .. y , '/ ' p ']'")
+  : type_scope.
+
+
+ +
+ + + diff --git a/General.gen.html b/General.gen.html new file mode 100644 index 0000000..ed7ce79 --- /dev/null +++ b/General.gen.html @@ -0,0 +1,398 @@ + + + + + + + + + + + + + +
+
+

General.gen

+ +
+Set Implicit Arguments.
+Require Import List.
+Import ListNotations.
+ +
+Definition rsub U V f g := forall (u : U) (v : V), f u v -> g u v.
+ +
+Lemma rsub_def: forall U V (f g : U -> V -> Type),
+  @rsub U V f g = forall (u : U) (v : V), f u v -> g u v.
+Proof. intros. unfold rsub. reflexivity. Qed.
+ +
+Lemma rsub_trans U V (f g h : U -> V -> Type) :
+  rsub f g -> rsub g h -> rsub f h.
+Proof. unfold rsub. firstorder. Qed.
+ +
+Lemma rsub_id U V (f : U -> V -> Type) : rsub f f.
+Proof. unfold rsub. firstorder. Qed.
+ +
+Definition req U V f g := prod (@rsub U V f g) (rsub g f).
+ +
+Lemma req_refl U V f : @req U V f f.
+Proof. unfold req. split ; apply rsub_id. Qed.
+ +
+Lemma req_sym U V f g : @req U V f g -> @req U V g f.
+Proof. unfold req. tauto. Qed.
+ +
+Lemma req_trans U V f g h : @req U V f g -> @req U V g h -> @req U V f h.
+Proof. unfold req. intros F B. destruct F. destruct B.
+split ; eapply rsub_trans ; eassumption. Qed.
+ +
+Definition rls W := list W -> W -> Prop.
+ +
+(* lemmas which shouldn't be necessary at all! *)
+ +
+Lemma or_false: forall P : Prop, iff (or P False) P. Proof. tauto. Qed.
+Lemma false_or: forall P : Prop, iff (or False P) P. Proof. tauto. Qed.
+Lemma and_true: forall P : Prop, iff (and P True) P. Proof. tauto. Qed.
+Lemma true_and: forall P : Prop, iff (and True P) P. Proof. tauto. Qed.
+ +
+Lemma rappl: forall (A B : Prop), A -> (A -> B) -> B.
+Proof. tauto. Qed.
+ +
+Lemma appl: forall (A B : Prop), (A -> B) -> A -> B.
+Proof. tauto. Qed.
+ +
+Lemma gen_cong: forall T U f g, f = g ->
+  forall x y, x = y -> (f (x : U) : T) = g y.
+Proof. intros. subst. reflexivity. Qed.
+ +
+Lemma fun_cong: forall T U f g, f = g ->
+  forall x, (f (x : U) : T) = g x.
+Proof. intros. subst. reflexivity. Qed.
+ +
+(* similar to Coq.Init.Logic.f_equal *)
+Lemma arg_cong: forall T U f x y, x = y -> (f (x : U) : T) = f y.
+Proof. intros. subst. reflexivity. Qed.
+ +
+Lemma arg_cong_imp: forall U f x y, x = y -> f (x : U) -> f y.
+Proof. intros. subst. assumption. Qed.
+ +
+(* similar to Coq.Init.Logic.eq_rect *)
+Lemma arg_cong_imp': forall U f x y, f (x : U) -> x = y -> f y.
+Proof. intros. subst. assumption. Qed.
+ +
+Lemma arg1_cong_imp: forall U V f x y z, x = y -> f (x : U) (z : V) -> f y z.
+Proof. intros. subst. assumption. Qed.
+ +
+Lemma arg1_cong_imp': forall U V f x y z, f (x : U) (z : V) -> x = y -> f y z.
+Proof. intros. subst. assumption. Qed.
+ +
+(* iffD1, iffD2 for Type *)
+Lemma iffD1: forall x y, (x = y) -> x -> y.
+Proof. intros. subst. assumption. Qed.
+ +
+Lemma iffD2: forall x y, (x = y) -> y -> x.
+Proof. intros. subst. assumption. Qed.
+ +
+(* PiffD1, PiffD2 for Prop *)
+Lemma PiffD1: forall x y, (x <-> y) -> x -> y.
+Proof. intros. rewrite -> H in H0. assumption. Qed.
+ +
+Lemma PiffD2: forall x y, (x <-> y) -> y -> x.
+Proof. intros. rewrite <- H in H0. assumption. Qed.
+ +
+Lemma eq_TrueI: forall (P : Prop), (P -> (P <-> True)).
+intros. unfold iff. apply conj ; intro. apply I. assumption.
+Qed.
+ +
+Definition rsub_imp U V (f g : U -> V -> Type) := iffD1 (@rsub_def U V f g).
+Definition rsubI U V f g := iffD2 (@rsub_def U V f g).
+Definition rsubD U V f g := iffD1 (@rsub_def U V f g).
+ +
+(* and do req_def, reqI, reqD as for rsub *)
+ +
+(* see also eq_refl, eq_trans, eq_sym, eq_ind, eq_ind_r *)
+ +
+Ltac refl_ni :=
+  match goal with
+    | [ |- ?P = ?P ] => reflexivity
+    end.
+ +
+Lemma pair_eqI: forall T U (u v : T) (x y : U),
+  u = v -> x = y -> (u,x) = (v,y).
+Proof. intros. subst. reflexivity. Qed.
+ +
+Ltac rename_last name :=
+  match goal with
+    | [ K : _ |- _ ] => rename K into name
+    end.
+ +
+Ltac clear_one :=
+  match goal with
+    | [ K : _ |- _ ] => clear K
+    end.
+ +
+Ltac cE :=
+  repeat match goal with
+    | [ H : _ /\ _ |- _ ] => inversion_clear H
+    | [ H : ex _ |- _ ] => inversion_clear H
+    | [ H : False |- _ ] => contradiction H
+    end.
+ +
+(* one step of cDv *)
+Ltac cD' :=
+  match goal with
+    | [ H : _ /\ _ |- _ ] => destruct H as [?H ?H]
+    | [ H : prod _ _ |- _ ] => destruct H as [?H ?H]
+    | [ H : ex _ |- _ ] => destruct H as [?H ?H]
+    | [ H : sig _ |- _ ] => destruct H as [?H ?H]
+    | [ H : sigT _ |- _ ] => destruct H as [?H ?H]
+    | [ H : ex2 _ _ |- _ ] => destruct H as [?H ?H ?H]
+    | [ H : sig2 _ _ |- _ ] => destruct H as [?H ?H ?H]
+    | [ H : sigT2 _ _ |- _ ] => destruct H as [?H ?H ?H]
+    | [ H : False |- _ ] => contradiction H
+    end.
+ +
+Ltac cD := repeat cD'.
+ +
+Ltac sE :=
+  repeat match goal with
+    | [ H : _ /\ _ |- _ ] => inversion_clear H
+    | [ H : _ \/ _ |- _ ] => inversion_clear H
+    | [ H : ex _ |- _ ] => inversion_clear H
+    | [ H : False |- _ ] => contradiction H
+    end.
+ +
+Ltac sD' :=
+  match goal with
+    | [ H : _ /\ _ |- _ ] => destruct H as [?H ?H]
+    | [ H : prod _ _ |- _ ] => destruct H as [?H ?H]
+    | [ H : _ \/ _ |- _ ] => destruct H as [?H | ?H]
+    | [ H : sumbool _ _ |- _ ] => destruct H as [?H | ?H]
+    | [ H : sum _ _ |- _ ] => destruct H as [?H | ?H]
+    | [ H : ex _ |- _ ] => destruct H as [?H ?H]
+    | [ H : sig _ |- _ ] => destruct H as [?H ?H]
+    | [ H : sigT _ |- _ ] => destruct H as [?H ?H]
+    | [ H : False |- _ ] => contradiction H
+    end.
+ +
+(* extra stuff used in sD, not in cD *)
+Ltac sDx :=
+  match goal with
+    | [ H : _ \/ _ |- _ ] => destruct H as [?H | ?H]
+    | [ H : sumbool _ _ |- _ ] => destruct H as [?H | ?H]
+    | [ H : sum _ _ |- _ ] => destruct H as [?H | ?H]
+    end.
+ +
+Ltac sD := repeat (cD' || sDx).
+ +
+(* various solutions to dealing with hypothesis forall x, A x -> B x 
+  see emails 8-9 Jan 
+evar (z : list (rel (list (PropF V)) * dir)).
+specialize (H1 z).
+subst z. (* subst. alone doesn't work *)
+
+match type of H1 with
+| ?A -> _ =>
+  assert (I : A); | apply H1 in I
+  end. 
+
+apply (fun G2 G1 => G1 (H1 G2)). 
+
+eassert _ as I*)

+ +
+(* tactics from Lily Chung <ikdc@mit.edu> Tue, 8 Jan 2019
+  https://gist.github.com/ichung/032b849da0c3c5e3987c83f835d111ee *)

+ +
+(* require, when called on a hypothesis H : P -> Q,
+   asserts that P actually holds,
+   and thus that H's type can be replaced with Q *)

+Ltac require H :=
+  match type of H with
+  | forall _ : ?H1, _ =>
+    let x := fresh in
+    let y := x in
+    assert H1 as x; [| specialize (H x); clear y]
+  end.
+ +
+(* erequire H, when called on a hypothesis H : forall x, Q x,
+   specializes H to a new evar to be filled in later *)

+Ltac erequire H :=
+  match type of H with
+  | forall _ : ?H1, _ =>
+    let x := fresh in
+    evar (x : H1); specialize (H x); subst x
+end.
+ +
+(* solution from  Marko Doko <mdoko@mpi-sws.org> Tue, 8 Jan 2019
+  solves question for quantified implication, changed to use Ltac
+
+Tactic Notation "specialize_full" ident(H) :=
+  let foo := fresh in
+  evar (foo : Prop); cut (foo); subst foo; cycle 1;
+  eapply H|try clear H; intro H.
+*)

+ +
+Ltac specialize_full H :=
+  let foo := fresh in
+  evar (foo : Prop); cut (foo); subst foo; cycle 1;
+  [eapply H|try clear H; intro H].
+ +
+Ltac prgt t :=
+  match goal with
+    | [ |- ?P ] => idtac t P
+    end.
+ +
+Lemma in_single: forall (A : Type) (a x : A), In a [x] <-> a = x.
+Proof. intros. unfold iff. split ; intros.
+  apply in_inv in H. sD.
+  subst. reflexivity.
+  apply in_nil in H. contradiction.
+  subst. apply in_eq. Qed.
+ +
+Lemma Forall_cons_inv: forall A (P : A -> Prop) (x : A) (l : list A),
+  Forall P (x :: l) -> P x /\ Forall P l.
+Proof. intros. inversion H. tauto. Qed.
+ +
+Lemma Forall_cons_iff: forall A (P : A -> Prop) (x : A) (l : list A),
+  Forall P (x :: l) <-> P x /\ Forall P l.
+Proof. intros. unfold iff. apply conj ; intro.
+apply Forall_cons_inv. assumption.
+inversion H. apply Forall_cons ; assumption.
+Qed.
+ +
+Lemma Forall_append: forall X P (xs ys: list X),
+  Forall P (xs ++ ys) <-> Forall P xs /\ Forall P ys.
+Proof.
+intros. induction xs. easy.
+simpl. rewrite !Forall_cons_iff. rewrite IHxs. tauto.
+Qed.
+ +
+Lemma Forall_single: forall (A : Type) P x, @Forall A P [x] <-> P x.
+Proof. intros. unfold iff. rewrite Forall_forall.
+  split ; intros.
+  apply H. rewrite in_single. reflexivity.
+  inversion H0. subst. exact H.
+  apply in_nil in H1. contradiction. Qed.
+ +
+Lemma Forall_map_single: forall (A B : Type) P (f : A -> B) x,
+  Forall P (map f [x]) <-> P (f x).
+Proof. simpl. intros. apply Forall_single. Qed.
+ +
+Lemma Forall_map_2: forall (A B : Type) P (f : A -> B) x y,
+  Forall P (map f [x; y]) <-> P (f x) /\ P (f y).
+Proof. intros. rewrite Forall_forall. unfold iff. split.
+  intros. split.
+  pose (H (f x)). apply p. rewrite in_map_iff. exists x. simpl. tauto.
+  pose (H (f y)). apply p. rewrite in_map_iff. exists y. simpl. tauto.
+  intros. rewrite -> in_map_iff in H0. cD. simpl in H3.
+  sD ; subst ; assumption. Qed.
+ +
+Lemma map_cons_ex T U (f : T -> U) ys x : forall ws,
+  map f ws = x :: ys -> {u : T & x = f u &
+    {vs : list _ & ys = map f vs & ws = u :: vs}}.
+Proof. intro. destruct ws ; simpl ; intro. discriminate.
+injection H as . subst. exists t. reflexivity.
+exists ws ; reflexivity. Qed.
+ +
+Lemma map_cons_ex' T U (f : T -> U) ys x : forall ws,
+  map f ws = x :: ys -> {u : T & x = f u &
+    {vs : list _ & map f vs = ys & ws = u :: vs}}.
+Proof. intros ws meq. apply map_cons_ex in meq. cD.
+exists meq. assumption. exists meq1. subst. reflexivity. assumption. Qed.
+ +
+Lemma map_app_ex T U (f : T -> U) ys xs : forall ws,
+  map f ws = xs ++ ys -> {us : _ & map f us = xs &
+    {vs : _ & map f vs = ys & ws = us ++ vs}}.
+Proof. induction xs ; simpl ; intros.
+exists []. simpl. reflexivity.
+simpl. exists ws. subst. reflexivity. reflexivity.
+apply map_cons_ex in H. destruct H. destruct s. subst.
+apply eq_sym in e0. apply IHxs in e0. destruct e0. destruct s. subst.
+exists (x :: x1). simpl. reflexivity. exists x2. reflexivity.
+simpl. reflexivity. Qed.
+ +
+Lemma map_eq_nil T U (f : T -> U) xs : map f xs = [] -> xs = [].
+Proof. intro mx. destruct xs. reflexivity. simpl in mx. discriminate mx. Qed.
+ +
+Ltac name_goal name := refine ?[name].
+ +
+
+
+ +
+ + + diff --git a/General.genT.html b/General.genT.html new file mode 100644 index 0000000..92d169e --- /dev/null +++ b/General.genT.html @@ -0,0 +1,688 @@ + + + + + + + + + + + + + +
+
+

General.genT

+ +
+ +
+(* general purpose stuff, using Type rather than Prop *)
+ +
+Set Implicit Arguments.
+Require Import List.
+Import ListNotations.
+Require Import existsT.
+ +
+Require Export Coq.Classes.CRelationClasses.
+ +
+Require Import gen.
+ +
+Polymorphic Definition rlsT W := list W -> W -> Type.
+ +
+(* how to express the empty set *)
+Inductive emptyT {X : Type} : X -> Type := .
+ +
+Lemma emptyT_any': forall (sty : Type) Q (prem : sty), emptyT prem -> Q prem.
+Proof. intros. induction H. Qed.
+ +
+Lemma emptyT_any: forall (sty : Type) Q (prem : sty), emptyT prem -> Q.
+Proof. intros. induction H. Qed.
+ +
+(* compare 
+  https://coq.inria.fr/stdlib/Coq.Relations.Relation_Definitions.html *)

+Polymorphic Definition relationT (A : Type) := A -> A -> Type.
+Inductive empty_relT {A B : Type} : A -> B -> Type := .
+ +
+Lemma rsub_emptyT {A B} r : @rsub A B empty_relT r.
+Proof. intros u v e. destruct e. Qed.
+ +
+Definition transitiveT W (R : relationT W) :=
+  forall (x y z : W), R x y -> R y z -> R x z.
+ +
+(*
+Definition iffT A B : Type := (A -> B) * (B -> A).
+*)

+Lemma iffT_trans: forall A B C, iffT A B -> iffT B C -> iffT A C.
+Proof. unfold iffT. intros. destruct X. destruct X0. tauto. Qed.
+ +
+Lemma iffT_sym': forall A B, iffT A B -> iffT B A.
+Proof. unfold iffT. intros. destruct X. tauto. Qed.
+ +
+Lemma iffT_refl: forall A, iffT A A.
+Proof. unfold iffT. intros. tauto. Qed.
+ +
+Lemma iffT_D1': forall A B, iffT A B -> A -> B.
+Proof. unfold iffT. intros. tauto. Qed.
+ +
+Lemma iffT_D2': forall A B, iffT B A -> A -> B.
+Proof. unfold iffT. intros. tauto. Qed.
+ +
+(* simpler proof objects *)
+Definition iffT_sym (A B : Type) (X : iffT A B) := let (f, g) := X in (g, f).
+Definition iffT_D1 (A B : Type) (X : iffT A B) a := let (f, _) := X in f a.
+Definition iffT_D2 (A B : Type) (X : iffT A B) b := let (_, g) := X in g b.
+ +
+Lemma prod_mono A A' B B' : (A -> A') -> (B -> B') -> (A * B -> A' * B').
+Proof. intros. destruct X1. tauto. Qed.
+ +
+Lemma iffT_prod A A' B B' : iffT A A' -> iffT B B' -> iffT (A * B) ( A' * B').
+Proof. unfold iffT. intros. destruct X. destruct X0.
+split ; apply prod_mono ; assumption. Qed.
+ +
+(* or defined versions of these
+Definition prod_mono_d A A' B B' aa bb (ab : A * B) :=
+  let (a, b) := ab in (aa a : A', bb b : B').
+
+Definition iffT_prod_d A A' B B' (iaa : iffT A A') (ibb : iffT B B') :=
+  let (af, ab) := iaa in 
+    let (bf, bb) := ibb in (prod_mono af bf, prod_mono ab bb).
+*)

+ +
+Inductive AccT (A : Type) (R : A -> A -> Type) (x : A) : Type :=
+    AccT_intro : (forall y : A, R y x -> AccT R y) -> AccT R x.
+ +
+Definition well_foundedT (A : Type) (R : A -> A -> Type) :=
+  forall a : A, AccT R a.
+ +
+Inductive ForallT (A : Type) (P : A -> Type) : list A -> Type :=
+    ForallT_nil : ForallT P []
+  | ForallT_cons : forall (x : A) (l : list A),
+                  P x -> ForallT P l -> ForallT P (x :: l).
+ +
+Lemma ForallT_inv:
+  forall (A : Type) (P : A -> Type) (a : A) (l : list A),
+  ForallT P (a :: l) -> P a.
+Proof. intros. inversion X. subst. exact X0. Qed.
+ +
+Lemma ForallT_cons_inv:
+  forall (A : Type) (P : A -> Type) (x : A) (l : list A),
+  ForallT P (x :: l) -> P x * ForallT P l.
+Proof. intros. inversion X. subst. split. exact X0. exact X1. Qed.
+ +
+Lemma ForallT_single:
+  forall (A : Type) (P : A -> Type) (x : A), iffT (ForallT P [x]) (P x).
+Proof. intros. unfold iffT. split ; intros.
+  inversion X. subst. exact X0.
+  apply ForallT_cons. exact X. apply ForallT_nil. Qed.
+ +
+Definition ForallT_singleD A P x := iffT_D1 (@ForallT_single A P x).
+Definition ForallT_singleI A P x := iffT_D2 (@ForallT_single A P x).
+ +
+Lemma ForallT_cons_iff:
+  forall (A : Type) (P : A -> Type) (x : A) (l : list A),
+    iffT (ForallT P (x :: l)) (P x * ForallT P l).
+Proof. intros. unfold iffT. split ; intros.
+  apply ForallT_cons_inv. exact X.
+  destruct X. apply ForallT_cons. exact p. exact f. Qed.
+ +
+Lemma ForallT_append:
+  forall (X : Type) (P : X -> Type) (xs ys : list X),
+  iffT (ForallT P (xs ++ ys)) (ForallT P xs * ForallT P ys).
+Proof. intros. unfold iffT.
+  induction xs. simpl. split ; intros. split.
+  apply ForallT_nil. exact X0. destruct X0. exact f0.
+  destruct IHxs. split ; intros.
+  simpl in X0. inversion X0. subst. apply p in X2. destruct X2.
+  split. apply ForallT_cons ; assumption. assumption.
+  simpl. destruct X0. inversion f0. subst.
+  apply ForallT_cons. exact X0. apply f. split ; assumption. Qed.
+ +
+Definition ForallT_appendD A P xs ys := iffT_D1 (@ForallT_append A P xs ys).
+Definition ForallT_appendD1 A P xs ys aa := fst (@ForallT_appendD A P xs ys aa).
+Definition ForallT_appendD2 A P xs ys aa := snd (@ForallT_appendD A P xs ys aa).
+Definition ForallT_appendI' A P xs ys := iffT_D2 (@ForallT_append A P xs ys).
+Definition ForallT_appendI A P xs ys ax ay :=
+  @ForallT_appendI' A P xs ys (pair ax ay).
+ +
+Lemma ForallT_2: forall (A : Type) (P : A -> Type) (x y : A),
+      iffT (ForallT P [x; y]) (P x * P y).
+Proof. intros. unfold iffT. split ; intros.
+inversion X. subst. inversion X1. subst. tauto.
+destruct X. apply ForallT_cons. exact p.
+apply ForallT_cons. exact p0. apply ForallT_nil. Qed.
+ +
+Lemma ForallT_map_2: forall (A B : Type) (P : B -> Type) (f : A -> B) (x y : A),
+      iffT (ForallT P (map f [x; y])) (P (f x) * P (f y)).
+Proof. intros. simpl. apply ForallT_2. Qed.
+ +
+Lemma ForallT_map: forall (A B : Type) (P : B -> Type) (f : A -> B) (x : A),
+      iffT (ForallT P (map f [x])) (P (f x)).
+Proof. intros. simpl. apply ForallT_single. Qed.
+ +
+Lemma ForallT_map_rev: forall (A B : Type) (P : B -> Type) (f : A -> B) (x : A),
+      iffT (P (f x)) (ForallT P (map f [x])).
+Proof. intros. simpl. split; intros HH; apply ForallT_single; tauto. Qed.
+ +
+Definition ForallT_2D A P x y := iffT_D1 (@ForallT_2 A P x y).
+Definition ForallT_D1 A P x y aa := fst (@ForallT_2D A P x y aa).
+Definition ForallT_D2 A P x y aa := snd (@ForallT_2D A P x y aa).
+Definition ForallT_2I' A P x y := iffT_D2 (@ForallT_2 A P x y).
+Definition ForallT_2I A P x y ax ay := @ForallT_2I' A P x y (pair ax ay).
+ +
+Lemma ForallT_impl:
+  forall (A : Type) (P Q : A -> Type),
+  (forall a : A, P a -> Q a) -> forall l : list A, ForallT P l -> ForallT Q l.
+Proof. intros. induction X0. apply ForallT_nil.
+  apply ForallT_cons. apply X. apply p. assumption. Qed.
+ +
+(*
+ForallT_Exists_neg:
+  forall (A : Type) (P : A -> Prop) (l : list A),
+  ForallT (fun x : A => ~ P x) l <-> ~ Exists P l
+ForallT_dec:
+  forall (A : Type) (P : A -> Prop),
+  (forall x : A, {P x} + {~ P x}) ->
+  forall l : list A, {ForallT P l} + {~ ForallT P l}
+ForallT_map_single:
+  forall (A B : Type) (P : B -> Prop) (f : A -> B) (x : A),
+  ForallT P (map f x) <-> P (f x)
+*)

+ +
+Inductive Forall2T (A B : Type) R : list A -> list B -> Type :=
+    Forall2T_nil : Forall2T R [] []
+  | Forall2T_cons : forall (x : A) (y : B) (l : list A) (l' : list B),
+                   R x y -> Forall2T R l l' -> Forall2T R (x :: l) (y :: l')
+  .
+ +
+Theorem Forall2T_app_inv_l : forall A B (R : A -> B -> Type) l1 l2 l',
+  Forall2T R (l1 ++ l2) l' ->
+  sigT2 (fun l1' => Forall2T R l1 l1') (fun l1' => sigT2 (fun l2' =>
+    Forall2T R l2 l2') (fun l2' => l' = l1' ++ l2')).
+Proof. intros until l1. induction l1. simpl.
+intros. exists []. apply Forall2T_nil.
+exists l'. assumption. simpl. reflexivity.
+simpl. intros. inversion_clear X.
+apply IHl1 in X1. destruct X1.
+exists (y :: x). apply Forall2T_cons ; assumption.
+destruct s. subst. simpl. eexists. eassumption. reflexivity. Qed.
+ +
+Theorem Forall2T_app_inv_r : forall A B (R : A -> B -> Type) l1' l2' l,
+  Forall2T R l (l1' ++ l2') ->
+  sigT2 (fun l1 => Forall2T R l1 l1') (fun l1 => sigT2 (fun l2 =>
+    Forall2T R l2 l2') (fun l2 => l = l1 ++ l2)).
+Proof. intros until l1'. induction l1'. simpl.
+intros. exists []. apply Forall2T_nil.
+exists l. assumption. simpl. reflexivity.
+simpl. intros. inversion_clear X.
+apply IHl1' in X1. destruct X1.
+exists (x :: x0). apply Forall2T_cons ; assumption.
+destruct s. subst. simpl. eexists. eassumption. reflexivity. Qed.
+ +
+Theorem Forall2T_app : forall A B (R : A -> B -> Type) l1 l2 l1' l2',
+  Forall2T R l1 l1' -> Forall2T R l2 l2' -> Forall2T R (l1 ++ l2) (l1' ++ l2').
+Proof. intros until l1. induction l1. simpl.
+intros. inversion_clear X. simpl. assumption.
+intros. inversion_clear X. simpl. apply Forall2T_cons. assumption.
+apply IHl1 ; assumption. Qed.
+ +
+(* this isn't usable, because destruct doesn't work for first clause 
+Inductive InT A (a : A) : list A -> Type :=
+  | InT_eq : forall l, @InT A a (a :: l)
+  | InT_cons : forall b l, @InT A a l -> @InT A a (b :: l).
+ *)

+  Ltac cET :=
+  repeat match goal with
+    | [ H : _ /\ _ |- _ ] => inversion_clear H
+    | [ H : ex _ |- _ ] => inversion_clear H
+    | [ H : False |- _ ] => contradiction H
+    | [ H : sig _ |- _ ] => inversion_clear H
+    | [ H : sigT _ |- _ ] => inversion_clear H
+    | [ H : False |- _ ] => contradiction H
+    | [ H : _ * _ |- _ ] => inversion_clear H
+         end.
+ +
+  Ltac cET_nr :=
+  match goal with
+    | [ H : _ /\ _ |- _ ] => inversion_clear H
+    | [ H : ex _ |- _ ] => inversion_clear H
+    | [ H : False |- _ ] => contradiction H
+    | [ H : sig _ |- _ ] => inversion_clear H
+    | [ H : sigT _ |- _ ] => inversion_clear H
+    | [ H : False |- _ ] => contradiction H
+    | [ H : _ * _ |- _ ] => inversion_clear H
+    end.
+ +
+Inductive InT A (a : A) : list A -> Type :=
+  | InT_eq' : forall b l, b = a -> @InT A a (b :: l)
+  | InT_cons : forall b l, @InT A a l -> @InT A a (b :: l).
+ +
+Definition InT_eq: forall A a l, @InT A a (a :: l).
+Proof. intros. apply InT_eq'. reflexivity. Defined.
+ +
+Definition InT_2nd A (a b : A) l := InT_cons a (InT_eq b l).
+ +
+Lemma InT_appL: forall A a X Y, InT (a : A) X -> InT a (X ++ Y).
+Proof. intros. induction X0 ; simpl. subst.
+apply InT_eq. apply InT_cons. assumption. Qed.
+ +
+Lemma InT_appR: forall A a X Y, InT (a : A) Y -> InT a (X ++ Y).
+Proof. intros. induction X ; simpl. assumption.
+apply InT_cons. assumption. Qed.
+ +
+Ltac solve_InT := apply InT_eq ||
+  ((apply InT_cons || (apply InT_appL + apply InT_appR)) ; solve_InT).
+ +
+Lemma InT_appE': forall A a Z, InT (a : A) Z ->
+  forall X Y, Z = X ++ Y -> InT a X + InT a Y.
+Proof. intros *. intro. induction X ; intros.
+destruct X ; simpl in H. subst. right. apply InT_eq.
+injection H. intros. subst. left. apply InT_eq.
+destruct X0 ; simpl in H. subst. right. apply InT_cons. assumption.
+injection H. intros. subst. pose (@eq_refl (list A)). apply IHX in e.
+destruct e. left. apply InT_cons. assumption.
+right. assumption. Qed.
+ +
+Lemma InT_appE: forall A a X Y, InT (a : A) (X ++ Y) -> InT a X + InT a Y.
+Proof. intros. eapply InT_appE'. eassumption. reflexivity. Qed.
+ +
+Lemma InT_nilE': forall A a Z any, InT (a : A) Z -> Z = [] -> any.
+Proof. intros. induction X ; discriminate. Qed.
+ +
+Lemma InT_nilE: forall A a any, InT (a : A) [] -> any.
+Proof. intros. eapply InT_nilE'. eassumption. reflexivity. Qed.
+ +
+Lemma InT_split: forall (A : Type) (x : A) (l : list A),
+  InT x l -> sigT (fun l1 => sigT (fun l2 => l = l1 ++ x :: l2)).
+Proof. intros. induction X.
+exists []. exists l. simpl. subst. reflexivity.
+destruct IHX. destruct s. subst.
+exists (b :: x0). exists x1. simpl. reflexivity. Qed.
+ +
+Lemma InT_inv: forall A a b Y, InT (a : A) (b :: Y) -> (b = a) + InT a Y.
+Proof. intros. inversion X ; subst ; tauto. Qed.
+ +
+Lemma InT_map: forall (A B : Type) (f : A -> B) (l : list A) (x : A),
+  InT x l -> InT (f x) (map f l).
+Proof. intros. induction X.
+subst. simpl. apply InT_eq.
+simpl. apply InT_cons. assumption. Qed.
+ +
+Lemma InT_mapE: forall (A B : Type) (f : A -> B) (l : list A) (y : B),
+       (InT y (map f l)) -> (sigT (fun x => prod (f x = y) (InT x l))).
+Proof. intros.
+induction l. eapply InT_nilE in X. apply X.
+simpl in X. inversion X. subst. exists a.
+split. reflexivity. apply InT_eq.
+subst. apply IHl in X0. cD. exists X0. subst. split. reflexivity.
+apply InT_cons. exact X2. Qed.
+ +
+Definition InT_map_iffT: forall (A B : Type) (f : A -> B) (l : list A) (y : B),
+       iffT (InT y (map f l)) (sigT (fun x => prod (f x = y) (InT x l))).
+Proof. intros. apply pair. apply InT_mapE.
+intro. cD. subst. apply InT_map. exact X1. Defined.
+ +
+Definition InT_mapI A B f l y := iffT_D2 (@InT_map_iffT A B f l y).
+ +
+Lemma InT_concat: forall (A : Type) a (xs : list A) pss,
+     InT a xs -> InT xs pss -> InT a (concat pss).
+Proof. intros. induction X0. subst. simpl. apply InT_appL. assumption.
+simpl. apply InT_appR. assumption. Qed.
+ +
+Lemma Forall2T_ex_l: forall A B (R : A -> B -> Type) xs ys x,
+  Forall2T R xs ys -> InT x xs -> sigT2 (fun y => InT y ys) (fun y => R x y).
+Proof. intros *. intro. induction X.
+intro. eapply InT_nilE in X. eassumption.
+intro. inversion X0 ; subst. eexists. apply InT_eq. assumption.
+apply IHX in X1. destruct X1. eexists. eapply InT_cons. eassumption.
+assumption. Qed.
+ +
+Lemma Forall2T_ex_r: forall A B (R : A -> B -> Type) xs ys x,
+  Forall2T R ys xs -> InT x xs -> sigT2 (fun y => InT y ys) (fun y => R y x).
+Proof. intros *. intro. induction X.
+intro. eapply InT_nilE in X. eassumption.
+intro. inversion X0 ; subst. eexists. apply InT_eq. assumption.
+apply IHX in X1. destruct X1. eexists. eapply InT_cons. eassumption.
+assumption. Qed.
+ +
+Lemma ForallT_forall: forall (A : Type) (P : A -> Type) (l : list A),
+  iffT (ForallT P l) (forall x : A, InT x l -> P x).
+Proof. intros. induction l ; unfold iffT ; split ; intros.
+  eapply InT_nilE in X0. exact X0. apply ForallT_nil.
+  unfold iffT in IHl. destruct IHl. inversion X.
+  inversion X0 ; subst ; firstorder.
+  unfold iffT in IHl. destruct IHl.
+  apply ForallT_cons. apply X. apply InT_eq.
+  apply f. intros. apply X. apply InT_cons. exact X0. Qed.
+ +
+Definition ForallTD_forall A P x := iffT_D1 (@ForallT_forall A P x).
+Definition ForallTI_forall A P x := iffT_D2 (@ForallT_forall A P x).
+ +
+Lemma InT_In: forall A a Y, InT (a : A) Y -> In a Y.
+Proof. intros. induction X. subst. apply in_eq.
+apply in_cons. assumption. Qed.
+ +
+Lemma In_InT: forall A a Y, In (a : A) Y -> ex (fun _ : InT a Y => True).
+Proof. intros. induction Y. apply in_nil in H. contradiction.
+apply in_inv in H. destruct H. subst. exists. apply InT_eq. apply I.
+apply IHY in H. destruct H. exists. apply InT_cons. assumption. apply I. Qed.
+ +
+(* generalise this *)
+Definition anon (p : Type) := ex (fun _ : p => True).
+ +
+Lemma anonI : forall p, p -> anon p.
+Proof. intros. unfold anon. exists. assumption. apply I. Qed.
+ +
+Lemma InT_In': forall A a Y, ex (fun _ : InT (a : A) Y => True) -> In a Y.
+Proof. intros. destruct H. apply InT_In. assumption. Qed.
+(* why can't we do anon p -> p in general, we do it here?
+  note, trying apply InT_In. before destruct H. causes the error below *)

+ +
+(*
+Lemma anonD : forall p, anon p -> p.
+Proof. unfold anon. intros. destruct H.
+Error: Case analysis on sort Type is not allowed for inductive definition ex.
+*)

+Lemma anonD : forall p (q : Prop), (p -> q) -> (anon p -> q).
+Proof. unfold anon. intros. destruct H0. tauto. Qed.
+ +
+Lemma anon_eq: forall P : Prop, anon P <-> P.
+Proof. intros. unfold iff. split. apply anonD. tauto. apply anonI. Qed.
+ +
+Lemma InT_In_eq: forall A a Y, anon (InT (a : A) Y) <-> In a Y.
+Proof. unfold anon. intros. unfold iff. split ; intros.
+apply InT_In'. assumption. apply In_InT. assumption. Qed.
+ +
+Lemma InT_In_eq': forall A a Y, anon (InT (a : A) Y) <-> In a Y.
+Proof. intros. unfold iff. split.
+apply anonD. apply InT_In.
+intro. unfold anon. apply In_InT. assumption. Qed.
+ +
+Lemma anon_prod: forall t u, anon (prod t u) <-> anon t /\ anon u.
+Proof. intros. unfold iff. unfold anon. split ; intros ;
+  cD ; try split ; exists ; tauto. Qed.
+ +
+Lemma anon_sum: forall t u, anon (sum t u) <-> anon t \/ anon u.
+Proof. intros. unfold iff. unfold anon. split ; intros ; sD ;
+  [> left | right | | ] ; exists ; tauto. Qed.
+ +
+(* doubt if converse is valid *)
+Lemma anon_imp: forall t u, anon (t -> u) -> (anon t -> anon u).
+Proof. unfold anon. intros. cD. exists ; tauto. Qed.
+ +
+Lemma anon_iffT: forall t u, anon (iffT t u) -> (anon t <-> anon u).
+Proof. unfold iff. unfold iffT. intros.
+rewrite -> anon_prod in H. destruct H.
+split ; intros ; eapply anon_imp ; eassumption. Qed.
+ +
+Lemma anon_sigT: forall A P, anon (@sigT A P) -> @ex A (fun x => anon (P x)).
+Proof. unfold anon. intros. cD. eexists. eexists. eassumption. apply I. Qed.
+ +
+Lemma anon_forall: forall T P,
+  anon (forall x : T, P x) -> forall x : T, anon (P x).
+Proof. unfold anon. intros. destruct H. exists. apply (x0 x). apply I. Qed.
+ +
+(* example to use the above - to prove in_inv 
+Goal forall (A : Type) (a b : A) l, In b (a :: l) -> a = b \/ In b l.
+Proof.  intros.  pose InT_inv.
+apply anonI in s.
+eapply anon_forall in s.
+eapply anon_forall in s.
+eapply anon_forall in s.
+eapply anon_forall in s.
+eapply anon_imp in s. (* this doesn't work as I'd expect *)
+Undo.
+pose anon_imp.
+pose (a0 (InT ?x0 (?x1 :: ?x2)) (?x1 = ?x0) + InT ?x0 ?x2). (* fails *)
+*)

+ +
+Lemma ForallT_Forall': forall A (P : A -> Prop) (xs : list A),
+  ForallT P xs -> Forall P xs.
+Proof. intros. induction X. apply Forall_nil.
+apply Forall_cons. assumption. assumption. Qed.
+ +
+Lemma ForallT_Forall: forall A P (xs : list A),
+  ForallT P xs -> Forall (fun x => anon (P x)) xs.
+Proof. intros. induction X. apply Forall_nil.
+apply Forall_cons. apply anonI. assumption. assumption. Qed.
+ +
+Lemma Forall_ForallT: forall A P (xs : list A),
+  Forall P xs -> anon (ForallT P xs).
+Proof. intros. induction H. apply anonI. apply ForallT_nil.
+unfold anon in IHForall. cD. apply anonI. (* can't do this before cD *)
+apply ForallT_cons ; assumption. Qed.
+ +
+(* note proof carefully, intros then induction H fails,
+  inversion H too early fails *)

+Lemma Forall_ForallT': forall A P (xs : list A), Forall P xs -> ForallT P xs.
+Proof. intros. induction xs. apply ForallT_nil.
+apply ForallT_cons. inversion H. subst. assumption.
+apply IHxs. inversion H. subst. assumption.
+Qed.
+ +
+Lemma inhabited_anon: forall A, inhabited A <-> anon A.
+Proof. unfold iff. unfold anon. intros. split ; intros.
destruct H. exists ; tauto.
destruct H. apply inhabits. assumption. Qed.
+ +
+Lemma want_left_prod_under_universal : forall (T : Type) (P : T -> Type) (Q1 : T -> Type) (S : Type),
+    (forall y : T, P y -> ((Q1 y) * S)) ->
+    forall y : T, P y -> Q1 y.
+Proof. firstorder. Qed.
+ +
+Lemma want_right_prod_under_universal : forall (T : Type) (P : T -> Type) (Q1 : T -> Type) (S : Type),
+    (forall y : T, P y -> (S * (Q1 y))) ->
+    forall y : T, P y -> Q1 y.
+Proof. firstorder. Qed.
+ +
+Lemma want_right_prod_under_universal' : forall (T : Type) (P : T -> Type) (Q1 S : T -> Type),
+    (forall y : T, P y -> ((S y) * (Q1 y))) ->
+    forall y : T, P y -> Q1 y.
+Proof. firstorder. Qed.
+ +
+Lemma want_prod_under_universal4 : forall (T : Type) (P : T -> Type) (Q1 Q2 Q3 Q4 : T -> Type),
+    (forall y : T, P y -> ((Q1 y) * (Q2 y) * (Q3 y) * (Q4 y))) ->
+    (forall y : T, P y -> Q1 y) *
+    (forall y : T, P y -> Q2 y) *
+    (forall y : T, P y -> Q3 y) *
+    (forall y : T, P y -> Q4 y).
+Proof. firstorder. Qed.
+ +
+Lemma prod_nat_split : forall (P : (nat * nat) -> Type),
+    (forall y : nat * nat, P y) ->
+    (forall n m : nat, P (n,m)).
+Proof. firstorder. Qed.
+ +
+Inductive empty : Type := .
+ +
+Lemma empty_explosion : forall (A : Type), empty -> A.
+Proof. intros A H. inversion H. Qed.
+ +
+Notation "T~ A" := (A -> empty) (at level 60).
+ +
+Lemma False_empty : False -> empty.
+Proof. intros H. inversion H. Qed.
+ +
+Lemma empty_False : empty -> False.
+Proof. intros H. inversion H. Qed.
+ +
+Inductive leT (n : nat) : nat -> Type :=
+  | leT_n : leT n n | leT_S : forall m : nat, leT n m -> leT n (S m).
+ +
+Theorem leT_n_S : forall n m, leT n m -> leT (S n) (S m).
+Proof. intros. induction H. apply leT_n. apply (leT_S IHleT). Qed.
+ +
+Lemma leT_S_n' : forall sn sm, leT sn sm ->
+  forall n m, sn = S n -> sm = S m -> leT n m.
+Proof. intros * ss. induction ss.
+- intros. subst. inversion H0. apply leT_n.
+- destruct m.
++ inversion ss. intros. inversion H0.
++ intros. subst. specialize (IHss _ _ eq_refl eq_refl).
+inversion H0. exact (leT_S IHss). Qed.
+ +
+(* forall n m, leT (S n) (S m) -> leT n m *)
+Definition leT_S_n n m l := @leT_S_n' _ _ l n m eq_refl eq_refl.
+ +
+Lemma leT_trans' l m n: leT m n -> leT l m -> leT l n.
+Proof. intro. induction H ; intro. apply H. exact (leT_S (IHleT H0)). Qed.
+ +
+Definition leT_trans l m n llm lmn := @leT_trans' l m n lmn llm.
+ +
+Lemma leT_0_n n: leT 0 n.
+Proof. induction n. apply leT_n. apply (leT_S IHn). Qed.
+ +
+Lemma leT_plus_r n m : leT m (n + m).
+Proof. induction n ; simpl. apply leT_n. apply (leT_S IHn). Qed.
+ +
+Lemma leT_plus_l n m : leT n (n + m).
+Proof. induction n ; simpl. apply leT_0_n. apply (leT_n_S IHn). Qed.
+ +
+Theorem eq_S_F n : S n = n -> False.
+Proof. intro. induction n ; inversion H. tauto. Qed.
+ +
+Theorem leT_S_F n : leT (S n) n -> False.
+Proof. induction n ; intro. inversion H. apply leT_S_n in H. tauto. Qed.
+ +
+Lemma leT_S_or_eq n m : leT n m -> leT (S n) m + (n = m).
+Proof. intro. induction H. tauto. left. exact (leT_n_S H). Qed.
+ +
+Lemma leT_or_gt n m : leT n m + leT (S m) n.
+Proof. induction n. left. apply leT_0_n.
+destruct IHn. apply leT_S_or_eq in l. destruct l. exact (inl l).
+subst. exact (inr (leT_n _)). exact (inr (leT_S l)). Qed.
+ +
+Lemma leT_ex_plus k n : leT k n -> { m : nat & Nat.add m k = n }.
+Proof. intro lkn. induction lkn. exists 0. simpl. reflexivity.
+cD. subst. exists (S IHlkn). simpl. reflexivity. Qed.
+
+
+ +
+ + + diff --git a/General.gen_seq.html b/General.gen_seq.html new file mode 100644 index 0000000..4f30c17 --- /dev/null +++ b/General.gen_seq.html @@ -0,0 +1,736 @@ + + + + + + + + + + + + + +
+
+

General.gen_seq

+ +
+Require Export List.
+Export ListNotations.
+Set Implicit Arguments.
+ +
+From Coq Require Import ssreflect.
+ +
+(* Add LoadPath "../modal".
+Add LoadPath "../tense-lns". *)

+Require Import gen genT ddT gen_tacs.
+Require Import gstep.
+Require Import List_lemmasT swappedT existsT.
+Require Import Coq.Program.Basics.
+ +
+Inductive rlsmap U W (f : U -> W) (rls : rlsT U) : rlsT W :=
+  | rmI : forall ps c, rls ps c -> rlsmap f rls (map f ps) (f c).
+ +
+Lemma rmI_eq U W (f : U -> W) (rls : rlsT U) ps c mps mc :
+  rls ps c -> mps = map f ps -> mc = f c -> rlsmap f rls mps mc.
+Proof. intros. subst. apply rmI ; assumption. Qed.
+ +
+Inductive relmap U W (f : U -> W) (rel : relationT U) : relationT W :=
+  | rlI : forall p c, rel p c -> relmap f rel (f p) (f c).
+ +
+Lemma rlI_eq U W (f : U -> W) (rel : relationT U) p c mp mc :
+  rel p c -> mp = f p -> mc = f c -> relmap f rel mp mc.
+Proof. intros. subst. apply rlI ; assumption. Qed.
+ +
+
+ +
+seqext, seqrule, extending sequent and rule with left- and right-contexts + in antecedent and consequent +
+
+Definition seqext (W : Type) Gam1 Gam2 Delt1 Delt2 (seq : rel (list W)) :=
+  match seq with | pair U V => pair (Gam1 ++ U ++ Gam2) (Delt1 ++ V ++ Delt2) end.
+ +
+Lemma seqext_seqext: forall V (Gam1 Gam2 Delt1 Delt2 Phi1 Phi2 Psi1 Psi2 : list V) seq,
+  seqext Gam1 Gam2 Delt1 Delt2 (seqext Phi1 Phi2 Psi1 Psi2 seq) =
+  seqext (Gam1 ++ Phi1) (Phi2 ++ Gam2) (Delt1 ++ Psi1) (Psi2 ++ Delt2) seq.
+Proof. intros. unfold seqext. destruct seq.
+rewrite !app_assoc. reflexivity. Qed.
+ +
+Lemma map_seqext_seqext: forall V (Gam1 Gam2 Delt1 Delt2 Phi1 Phi2 Psi1 Psi2 : list V) seqs,
+  map (seqext Gam1 Gam2 Delt1 Delt2) (map (seqext Phi1 Phi2 Psi1 Psi2) seqs) =
+  map (seqext (Gam1 ++ Phi1) (Phi2 ++ Gam2) (Delt1 ++ Psi1) (Psi2 ++ Delt2)) seqs.
+Proof. induction seqs. tauto.
+simpl. rewrite IHseqs. rewrite seqext_seqext. reflexivity. Qed.
+ +
+Inductive seqrule (W : Type) (pr : rlsT (rel (list W))) :
+    rlsT (rel (list W)) :=
+  | Sctxt : forall ps c Phi1 Phi2 Psi1 Psi2, pr ps c ->
+    seqrule pr (map (seqext Phi1 Phi2 Psi1 Psi2) ps) (seqext Phi1 Phi2 Psi1 Psi2 c).
+ +
+Lemma seqext_def : forall (W : Type) Phi1 Phi2 Psi1 Psi2 U V,
+      @seqext W Phi1 Phi2 Psi1 Psi2 (U,V) = (Phi1 ++ U ++ Phi2, Psi1 ++ V ++ Psi2).
+Proof. reflexivity. Qed.
+ +
+Lemma Sctxt_e: forall (W : Type) (pr : rlsT (rel (list W))) ps U V Phi1 Phi2 Psi1 Psi2,
+  pr ps (U, V) ->
+  seqrule pr (map (seqext Phi1 Phi2 Psi1 Psi2) ps) (Phi1 ++ U ++ Phi2, Psi1 ++ V ++ Psi2).
+Proof.
+  intros *. intros H. rewrite <- seqext_def.
+  apply Sctxt. exact H.
+Qed.
+ +
+Lemma Sctxt_eq: forall (W : Type) pr ps mps (ca cs U V Phi1 Phi2 Psi1 Psi2 : list W),
+  pr ps (U, V) -> ca = Phi1 ++ U ++ Phi2 -> cs = Psi1 ++ V ++ Psi2 ->
+  mps = map (seqext Phi1 Phi2 Psi1 Psi2) ps -> seqrule pr mps (ca, cs).
+Proof. intros. subst. apply Sctxt_e. exact X. Qed.
+ +
+Lemma seqrule_id (W : Type) (pr : rlsT (rel (list W))) :
+  forall ps c, pr ps c -> seqrule pr ps c.
+Proof. intros. destruct c as [ca cs].
+apply (Sctxt_eq pr ps ca cs [] [] [] []). assumption.
+simpl. rewrite app_nil_r. reflexivity.
+simpl. rewrite app_nil_r. reflexivity.
+clear X. induction ps. simpl. reflexivity.
+simpl. rewrite <- IHps.
+destruct a. unfold seqext. simpl. rewrite !app_nil_r.
+reflexivity. Qed.
+ +
+Lemma seqrule_seqrule (W : Type) (pr : rlsT (rel (list W))) :
+  rsub (seqrule (seqrule pr)) (seqrule pr).
+Proof. unfold rsub. intros. inversion X. subst. clear X.
+inversion X0. subst. clear X0.
+rewrite seqext_seqext.
+destruct c0 as [ca cs].
+eapply Sctxt_eq. exact X.
+reflexivity. reflexivity.
+clear X. induction ps0. simpl. reflexivity.
+simpl. rewrite IHps0. rewrite seqext_seqext. reflexivity. Qed.
+ +
+Definition seqrule_seqrule' (W : Type) pr :=
+  rsubD (@seqrule_seqrule W pr).
+ +
+Lemma derl_seqrule'' (W : Type) (rules : rlsT (rel (list W))) :
+  forall Phi1 Phi2 Psi1 Psi2, (forall ps c, derl rules ps c ->
+   derl (seqrule rules) (map (seqext Phi1 Phi2 Psi1 Psi2) ps) (seqext Phi1 Phi2 Psi1 Psi2 c)) *
+  (forall ps cs, dersl rules ps cs ->
+    dersl (seqrule rules) (map (seqext Phi1 Phi2 Psi1 Psi2) ps)
+    (map (seqext Phi1 Phi2 Psi1 Psi2)cs)).
+Proof. intros Phi1 Phi2 Psi1 Psi2.
+eapply (derl_dersl_rect_mut (rules := rules)
+  (fun ps c => fun _ => derl (seqrule rules)
+    (map (seqext Phi1 Phi2 Psi1 Psi2) ps) (seqext Phi1 Phi2 Psi1 Psi2 c))
+  (fun ps cs : list _ => fun _ => dersl (seqrule rules)
+    (map (seqext Phi1 Phi2 Psi1 Psi2) ps) (map (seqext Phi1 Phi2 Psi1 Psi2) cs))).
+- simpl. intros. apply asmI.
+- intros. eapply dtderI. apply Sctxt. eassumption. assumption.
+- simpl. apply dtNil.
+- intros. rewrite map_app. simpl. apply dtCons ; assumption. Qed.
+ +
+Definition derl_seqrule' W rules Phi1 Phi2 Psi1 Psi2 :=
+  fst (@derl_seqrule'' W rules Phi1 Phi2 Psi1 Psi2).
+Definition dersl_seqrule' W rules Phi1 Phi2 Psi1 Psi2 :=
+  snd (@derl_seqrule'' W rules Phi1 Phi2 Psi1 Psi2).
+ +
+Lemma derl_seqrule (W : Type) (rules : rlsT (rel (list W))) :
+  rsub (seqrule (derl rules)) (derl (seqrule rules)).
+Proof. unfold rsub. intros. destruct X.
+apply derl_seqrule'. assumption. Qed.
+ +
+Lemma seqrule_derl_seqrule (W : Type) (rules : rlsT (rel (list W))) :
+  rsub (seqrule (derl (seqrule rules))) (derl (seqrule rules)).
+Proof. eapply rsub_trans. apply derl_seqrule.
unfold rsub. intros. eapply derl_mono. 2: eassumption.
apply seqrule_seqrule. Qed.
+ +
+Definition seqrule_derl_seqrule' W rules :=
+  rsubD (@seqrule_derl_seqrule W rules).
+ +
+(* seqrule_s ps c qs d means that d is a sequent extension of c 
+  and that each q in qs is a corresponding sequent extension of the
+  corresponding p in ps *)

+Inductive seqrule_s (W : Type) (ps : list (rel (list W))) (c : rel (list W)) :
+    rlsT (rel (list W)) :=
+  | Sctxt_s : forall Phi1 Phi2 Psi1 Psi2,
+    seqrule_s ps c (map (seqext Phi1 Phi2 Psi1 Psi2) ps) (seqext Phi1 Phi2 Psi1 Psi2 c).
+ +
+Inductive seqrule' (W : Type) (pr : rlsT (rel (list W))) :
+    rlsT (rel (list W)) :=
+  | Sctxt' : forall ps c pse ce,
+    pr ps c -> seqrule_s ps c pse ce -> seqrule' pr pse ce.
+ +
+(* Check, get same as Sctxt but for seqrule' *)
+Lemma Sctxt_alt : forall (W : Type) (pr : rlsT (rel (list W))) ps c Phi1 Phi2 Psi1 Psi2,
+    pr ps c -> seqrule' pr (map (seqext Phi1 Phi2 Psi1 Psi2) ps) (seqext Phi1 Phi2 Psi1 Psi2 c).
+Proof.
+  intros *. intros H.
+  eapply Sctxt'. exact H. apply Sctxt_s.
+Qed.
+ +
+Lemma Sctxt_e': forall (W : Type) (pr : rlsT (rel (list W))) ps U V Phi1 Phi2 Psi1 Psi2,
+  pr ps (U, V) ->
+  seqrule pr (map (seqext Phi1 Phi2 Psi1 Psi2) ps) ((Phi1 ++ U) ++ Phi2, Psi1 ++ V ++ Psi2).
+Proof.
+  intros *. intros H.
+  rewrite <- app_assoc. apply Sctxt_e. exact H.
+Qed.
+ +
+Lemma seqext_defp : forall (W : Type) Phi1 Phi2 Psi1 Psi2 seq,
+      @seqext W Phi1 Phi2 Psi1 Psi2 seq =
+        let (U, V) := seq in (Phi1 ++ U ++ Phi2, Psi1 ++ V ++ Psi2).
+Proof. reflexivity. Qed.
+ +
+Lemma seqrule_same: forall (W : Type) pr ps (c c' : rel (list W)),
+  seqrule pr ps c -> c = c' -> seqrule pr ps c'.
+Proof. intros. subst. assumption. Qed.
+ +
+Lemma seqrule_mono X (rulesa rulesb : rlsT (rel (list X))) :
+  rsub rulesa rulesb -> rsub (seqrule rulesa) (seqrule rulesb).
+Proof. unfold rsub. intros. destruct X1. apply Sctxt. firstorder. Qed.
+ +
+Definition seqrule_mono' X rulesa rulesb rs :=
+  rsubD (@seqrule_mono X rulesa rulesb rs).
+ +
+Lemma Sctxt_nil: forall (W : Type) pr c Gam1 Gam2 Delt1 Delt2, (pr [] c : Type) ->
+  @seqrule W pr [] (seqext Gam1 Gam2 Delt1 Delt2 c).
+Proof.
+  intros *. intros H. eapply Sctxt in H.
+  simpl in H. exact H.
+Qed.
+ +
+Lemma InT_seqextL : forall {W : Type} Gam Delt A,
+    InT A Gam ->
+    existsT2 Phi1 Phi2, @seqext W Phi1 Phi2 Delt [] ([A], []) = (Gam, Delt).
+Proof.
+  induction Gam; intros Delt A Hin.
+  inversion Hin.
+  inversion Hin. subst.
+  repeat eexists. unfold seqext.
+  do 2 rewrite app_nil_r. erewrite app_nil_l.
+     reflexivity.
+  subst. destruct (IHGam Delt _ X) as [H1 [H2 H3]].
+  unfold seqext in *.
+  inversion H3.
+  repeat rewrite app_nil_r.
+  repeat eexists. rewrite app_comm_cons. reflexivity.
+Qed.
+ +
+Lemma InT_seqextR : forall {W : Type} Gam Delt B,
+    InT B Delt ->
+    existsT2 Psi1 Psi2, @seqext W Gam [] Psi1 Psi2 ([], [B]) = (Gam, Delt).
+Proof.
+  induction Delt; intros A Hin.
+  inversion Hin.
+  inversion Hin. subst.
+  repeat eexists. unfold seqext.
+  do 2 rewrite app_nil_r. erewrite app_nil_l.
+     reflexivity.
+  subst. destruct (IHDelt _ X) as [H1 [H2 H3]].
+  unfold seqext in *.
+  inversion H3.
+  repeat rewrite app_nil_r.
+  repeat eexists. rewrite app_comm_cons. reflexivity.
+Qed.
+ +
+Lemma InT_seqext : forall {W : Type} Gam Delt A B,
+    InT A Gam ->
+    InT B Delt ->
+    existsT2 Phi1 Phi2 Psi1 Psi2, @seqext W Phi1 Phi2 Psi1 Psi2 ([A], [B]) = (Gam, Delt).
+Proof.
+  intros *. intros Hin1 Hin2.
+  destruct (@InT_seqextL _ _ Delt _ Hin1) as [H1 [H2 H3]].
+  destruct (@InT_seqextR _ Gam _ _ Hin2) as [J1 [J2 J3]].
+  unfold seqext in *.
+  repeat rewrite app_nil_r in H3.
+  repeat rewrite app_nil_r in J3.
+  inversion H3. inversion J3.
+  subst. repeat eexists.
+Qed.
+ +
+(* fmlsext copied from ../ll/fmlsext.v *)
+Definition fmlsext (W : Type) Gam1 Gam2 (fmls : (list W)) := (Gam1 ++ fmls ++ Gam2).
+ +
+Lemma fmlsext_fmlsext: forall V (Gam1 Gam2 Phi1 Phi2 : list V) seq,
+  fmlsext Gam1 Gam2 (fmlsext Phi1 Phi2 seq) = fmlsext (Gam1 ++ Phi1) (Phi2 ++ Gam2) seq.
+Proof. intros. unfold fmlsext. rewrite !app_assoc. reflexivity. Qed.
+ +
+Lemma map_fmlsext_fmlsext: forall V (Gam1 Gam2 Phi1 Phi2 : list V) seqs,
+  map (fmlsext Gam1 Gam2) (map (fmlsext Phi1 Phi2) seqs) =
+  map (fmlsext (Gam1 ++ Phi1) (Phi2 ++ Gam2)) seqs.
+Proof. induction seqs. tauto.
+simpl. rewrite IHseqs. rewrite fmlsext_fmlsext. reflexivity. Qed.
+ +
+Lemma fmlsext_def : forall (W : Type) Phi1 Phi2 U,
+      @fmlsext W Phi1 Phi2 U = (Phi1 ++ U ++ Phi2).
+Proof. reflexivity. Qed.
+ +
+Definition apfst U V W (f : U -> V) (p : U * W) := let (x, y) := p in (f x, y).
+Definition apsnd U V W (f : U -> V) (p : W * U) := let (x, y) := p in (x, f y).
+ +
+
+ +
+fst_ext_rls - adding left- and right-context + to the antecedent of a sequent rule +
+
+Inductive fst_ext_rls U W rls : rlsT (list U * W) :=
+  | fextI : forall Gam1 Gam2 ps c,
+    rlsmap (apfst (fmlsext Gam1 Gam2)) rls ps c -> fst_ext_rls rls ps c.
+ +
+Inductive snd_ext_rls U W rls : rlsT (U * list W) :=
+  | sextI : forall Gam1 Gam2 ps c,
+    rlsmap (apsnd (fmlsext Gam1 Gam2)) rls ps c -> snd_ext_rls rls ps c.
+ +
+Definition fextI' U W rls Gam1 Gam2 ps c rpc :=
+  @fextI U W rls Gam1 Gam2 _ _ (rmI _ _ ps c rpc).
+ +
+Lemma fextI_eq' U W rls Gam1 Gam2 ps (c : list U * W) mps mc :
+  rls ps c -> mps = map (apfst (fmlsext Gam1 Gam2)) ps ->
+  mc = apfst (fmlsext Gam1 Gam2) c -> fst_ext_rls rls mps mc.
+Proof. intros. subst. apply fextI'. exact X. Qed.
+ +
+Definition fextI_eqc' U W rls Gam1 Gam2 ps (c : list U * W) mc rpc :=
+  @fextI_eq' U W rls Gam1 Gam2 ps (c : list U * W) _ mc rpc eq_refl.
+ +
+Lemma fst_snd_ext W (rls : rlsT (list W * list W)) :
+  req (seqrule rls) (fst_ext_rls (snd_ext_rls rls)).
+Proof. split ; intros ps c.
+- intro sr. destruct sr. eapply fextI. eapply rmI_eq.
+eapply sextI. apply rmI. exact r.
+2: destruct c. 2: simpl. 2: unfold fmlsext. 2: reflexivity.
+clear r. induction ps. reflexivity.
+destruct a. simpl. rewrite - IHps. unfold fmlsext. reflexivity.
+- intro fs. destruct fs. inversion r. clear r. subst.
+destruct X. inversion r. clear r. subst.
+destruct c0. simpl. unfold fmlsext.
+eapply Sctxt_eq. exact X. reflexivity. reflexivity.
+clear X. induction ps0. reflexivity.
+destruct a. simpl. rewrite IHps0. reflexivity. Qed.
+ +
+Lemma snd_fst_ext W (rls : rlsT (list W * list W)) :
+  req (seqrule rls) (snd_ext_rls (fst_ext_rls rls)).
+Proof. split ; intros ps c.
+- intro sr. destruct sr. eapply sextI. eapply rmI_eq.
+eapply fextI. apply rmI. exact r.
+2: destruct c. 2: simpl. 2: unfold fmlsext. 2: reflexivity.
+clear r. induction ps. reflexivity.
+destruct a. simpl. rewrite - IHps. unfold fmlsext. reflexivity.
+- intro fs. destruct fs. inversion r. clear r. subst.
+destruct X. inversion r. clear r. subst.
+destruct c0. simpl. unfold fmlsext.
+eapply Sctxt_eq. exact X. reflexivity. reflexivity.
+clear X. induction ps0. reflexivity.
+destruct a. simpl. rewrite IHps0. reflexivity. Qed.
+ +
+Lemma rm_mono U W (f : U -> W) rlsa rlsb :
+  rsub rlsa rlsb -> rsub (rlsmap f rlsa) (rlsmap f rlsb).
+Proof. intros rab ps c ra.
+destruct ra. pose (rab _ _ r).
+apply rmI. apply r0. Qed.
+ +
+Lemma fer_mono U W (rlsa rlsb : rlsT (list U * W)) :
+  rsub rlsa rlsb -> rsub (fst_ext_rls rlsa) (fst_ext_rls rlsb).
+Proof. intros rab ps c fea.
+destruct fea. destruct r. pose (rab _ _ r).
+eapply fextI. apply rmI. apply r0. Qed.
+ +
+Lemma ser_mono U W (rlsa rlsb : rlsT (U * list W)) :
+  rsub rlsa rlsb -> rsub (snd_ext_rls rlsa) (snd_ext_rls rlsb).
+Proof. intros rab ps c sea.
+destruct sea. destruct r. pose (rab _ _ r).
+eapply sextI. apply rmI. apply r0. Qed.
+ +
+(* derl_fst_ext_rls - similar for seqrule above *)
+Lemma fst_ext_rls_fst_ext_rls (U W : Type) (pr : rlsT (list U * W)) :
+  rsub (fst_ext_rls (fst_ext_rls pr)) (fst_ext_rls pr).
+Proof. unfold rsub. intros. inversion X. subst. clear X.
+inversion X0. subst. clear X0. destruct X. destruct r.
+destruct c. simpl. rewrite fmlsext_fmlsext.
+eapply fextI' in p. simpl in p.
+eapply arg1_cong_imp. 2: exact p. clear p.
+induction ps ; simpl. reflexivity.
+rewrite IHps. destruct a. simpl. rewrite fmlsext_fmlsext. reflexivity. Qed.
+ +
+Definition fst_ext_rls_fst_ext_rls' (U W : Type) pr :=
+  rsubD (@fst_ext_rls_fst_ext_rls U W pr).
+ +
+Lemma derl_fst_ext_rls'' (U W : Type) (rules : rlsT (list U * W)) :
+  forall Phi1 Phi2, (forall ps c, derl rules ps c ->
+   derl (fst_ext_rls rules)
+     (map (apfst (fmlsext Phi1 Phi2)) ps) (apfst (fmlsext Phi1 Phi2) c)) *
+  (forall ps cs, dersl rules ps cs ->
+    dersl (fst_ext_rls rules) (map (apfst (fmlsext Phi1 Phi2)) ps)
+    (map (apfst (fmlsext Phi1 Phi2)) cs)).
+Proof. intros Phi1 Phi2.
+eapply (derl_dersl_rect_mut (rules := rules)
+  (fun ps c => fun _ => derl (fst_ext_rls rules)
+    (map (apfst (fmlsext Phi1 Phi2)) ps) (apfst (fmlsext Phi1 Phi2) c))
+  (fun ps cs : list _ => fun _ => dersl (fst_ext_rls rules)
+    (map (apfst (fmlsext Phi1 Phi2)) ps) (map (apfst (fmlsext Phi1 Phi2)) cs))).
+- simpl. intros. apply asmI.
+- intros. eapply dtderI. eapply fextI. apply rmI. eassumption. assumption.
+- simpl. apply dtNil.
+- intros. rewrite map_app. simpl. apply dtCons ; assumption. Qed.
+ +
+Definition derl_fst_ext_rls' U W rules Phi1 Phi2 :=
+  fst (@derl_fst_ext_rls'' U W rules Phi1 Phi2).
+Definition dersl_fst_ext_rls' U W rules Phi1 Phi2 :=
+  snd (@derl_fst_ext_rls'' U W rules Phi1 Phi2).
+ +
+Lemma derl_fst_ext_rls (U W : Type) (rules : rlsT (list U * W)) :
+  rsub (fst_ext_rls (derl rules)) (derl (fst_ext_rls rules)).
+Proof. unfold rsub. intros. destruct X. destruct r.
+apply derl_fst_ext_rls'. assumption. Qed.
+ +
+Lemma fst_ext_rls_derl_fst_ext_rls (U W : Type) (rules : rlsT (list U * W)) :
+  rsub (fst_ext_rls (derl (fst_ext_rls rules))) (derl (fst_ext_rls rules)).
+Proof. eapply rsub_trans. apply derl_fst_ext_rls.
unfold rsub. intros. eapply derl_mono. 2: eassumption.
apply fst_ext_rls_fst_ext_rls. Qed.
+ +
+Definition fst_ext_rls_derl_fst_ext_rls' U W rules :=
+  rsubD (@fst_ext_rls_derl_fst_ext_rls U W rules).
+ +
+(* simple version of weakening, new stuff added at beginning or end,
+  could do more complicated, but why bother, have exchange *)

+Definition wkL_valid V W rules (cl : list V) cr :=
+  forall Gam1 Gam2, derrec rules (@emptyT _) (fmlsext Gam1 Gam2 cl, cr : W).
+Definition wkL_valid' V W rules seq := @wkL_valid V W rules (fst seq) (snd seq).
+ +
+Definition can_wkL V W rules seq :=
+  derrec rules emptyT seq -> @wkL_valid' V W rules seq.
+ +
+Lemma can_wkL_req V W rlsa rlsb seq : req rlsa rlsb ->
+  @can_wkL V W rlsa seq -> can_wkL rlsb seq.
+Proof. unfold can_wkL. unfold wkL_valid'. unfold wkL_valid.
+intros rab da derb *.
+specialize (da (derrec_rmono (snd rab) derb)).
+exact (derrec_rmono (fst rab) (da Gam1 Gam2)). Qed.
+ +
+Lemma weakeningL: forall V W seq rules, @can_wkL V W (fst_ext_rls rules) seq.
+Proof. unfold can_wkL. intros.
+eapply derrec_all_rect in X. exact X.
+intros. contradiction H.
+intros ps concl ljpc dsps fwk. destruct ljpc. inversion r.
+destruct c0. unfold wkL_valid'. unfold wkL_valid. simpl. subst. clear r.
+intros *. rewrite fmlsext_fmlsext.
+eapply derI. eapply fextI. eapply rmI_eq. apply X0.
+reflexivity. reflexivity.
+apply dersrecI_forall. intros c0 incm.
+apply InT_mapE in incm. cD.
+eapply ForallTD_forall in fwk.
+2: apply InT_map. 2: exact incm1.
+simpl in incm0. destruct incm0. simpl in fwk.
+unfold wkL_valid' in fwk. unfold wkL_valid in fwk. simpl in fwk.
+rewrite - fmlsext_fmlsext. apply fwk. Qed.
+ +
+
+ +
+exchange +
+
+(* properties can exchange adjacent sublists, and resulting sequent
+  is derivable (not conditional on unexchanged version being derivable *)

+Definition can_exchL W Y rules seq :=
+  forall (Gam Gams : list W) (Delt : Y), seq = pair Gam Delt -> swapped Gam Gams ->
+  derrec rules (@emptyT _) (pair Gams Delt).
+ +
+Definition can_exchR W Y rules seq :=
+  forall (Gam : Y) (Delt Delts : list W), seq = pair Gam Delt -> swapped Delt Delts ->
+  derrec rules (@emptyT _) (pair Gam Delts).
+ +
+Inductive sing_empty X : list X -> Type :=
+  | se_empty : sing_empty []
+  | se_single : forall a, sing_empty [a].
+ +
+Lemma sing_empty_app X (xs ys : list X):
+  sing_empty (xs ++ ys) -> sum (xs = []) (ys = []).
+Proof. intro. inversion X0. destruct xs. tauto.
+simpl in H0. discriminate H0.
+destruct xs. tauto.
+injection H0 as. destruct xs. simpl in H0. subst. tauto.
+simpl in H0. discriminate H0. Qed.
+ +
+Lemma sing_empty_app_cons X z (xs ys : list X):
+  sing_empty (xs ++ z :: ys) -> (xs = []) * (ys = []).
+Proof. intro se. inversion se.
+list_eq_ncT. inversion H0. list_eq_ncT. sD. inversion H1. tauto.
+list_eq_ncT. Qed.
+ +
+Inductive fst_rel (A B : Type) (R : relationT A) : relationT (A * B) :=
+  fst_relI : forall x y z, R x y -> @fst_rel A B R (x, z : B) (y, z).
+ +
+Inductive snd_rel (A B : Type) (R : relationT A) : relationT (B * A) :=
+  snd_relI : forall x y z, R x y -> @snd_rel A B R (z : B, x) (z, y).
+ +
+Lemma fext_e: forall (U W : Type) (pr : rlsT (list U * W)) ps cl cr Phi1 Phi2,
+  pr ps (cl, cr) ->
+  fst_ext_rls pr (map (apfst (fmlsext Phi1 Phi2)) ps) (Phi1 ++ cl ++ Phi2, cr).
+Proof. intros * H. rewrite <- fmlsext_def.
+  eapply fextI. eapply rmI_eq. exact H. reflexivity. reflexivity. Qed.
+ +
+Lemma sext_e: forall (U W : Type) (pr : rlsT (U * list W)) ps cl cr Phi1 Phi2,
+  pr ps (cl, cr) ->
+  snd_ext_rls pr (map (apsnd (fmlsext Phi1 Phi2)) ps) (cl, Phi1 ++ cr ++ Phi2).
+Proof. intros * H. rewrite <- fmlsext_def.
+  eapply sextI. eapply rmI_eq. exact H. reflexivity. reflexivity. Qed.
+ +
+Ltac concl_in_app X0 r sea :=
+  pose X0 as r ; apply sea in r ;
+  destruct r ; subst ; rewrite ?app_nil_r ; rewrite ?app_nil_l ;
+  simpl in X0 ; rewrite ?app_nil_r in X0.
+ +
+Ltac fwl_tac mid := eexists ; split ;
+  [> assoc_mid mid ; apply fext_e ; eassumption |
+    apply ForallTI_forall ; intros x inms ; apply InT_mapE in inms ;
+    destruct inms as [x0 p] ; destruct p as [sex int] ;
+    destruct x0 ; simpl in sex ; unfold fmlsext in sex ; destruct sex ;
+    eexists ; split ;
+      [> eapply InT_map ; eassumption |
+      simpl ; unfold fmlsext ; apply fst_relI ; swap_tac ]].
+ +
+Ltac fwr_tac mid := eexists ; split ;
+  [> assoc_mid mid ; apply sext_e ; eassumption |
+    apply ForallTI_forall ; intros x inms ; apply InT_mapE in inms ;
+    destruct inms as [x0 p] ; destruct p as [sex int] ;
+    destruct x0 ; simpl in sex ; unfold fmlsext in sex ; destruct sex ;
+    eexists ; split ;
+      [> eapply InT_map ; eassumption |
+      simpl ; unfold fmlsext ; apply snd_relI ; swap_tac ]].
+ +
+Lemma exchL_std_rule: forall U W (rules : rlsT (list U * W)),
+  (forall ps U S, rules ps (U, S) -> sing_empty U) ->
+  forall ps c, fst_ext_rls rules ps c ->
+    can_trf_rules (fst_rel (@swapped _)) (fst_ext_rls rules) ps c.
+Proof. unfold can_trf_rules.
+intros U W rules se ps c sqr c' fr.
+pose (fun ps xs ys S rps =>
+  sing_empty_app xs ys (se ps (xs ++ ys) S rps)) as sea.
+inversion fr. subst. clear fr.
+inversion sqr. clear sqr. subst.
+inversion X0. destruct c as [pl pr].
+simpl in H1. unfold fmlsext in H1.
+inversion H1. subst. clear H1. clear X0.
+inversion X. subst.
+acacD'T2 ; subst.
+- concl_in_app X1 r sea. + fwl_tac H3. + fwl_tac H1.
+- concl_in_app X1 r sea. concl_in_app X1 r sea.
++ fwl_tac H5. + fwl_tac C.
++ list_eq_nc. destruct e. subst. rewrite ?app_nil_r. rewrite ?app_nil_l.
+simpl in X1. rewrite ?app_nil_r in X1.
+fwl_tac H1.
+- fwl_tac pl.
+- concl_in_app X1 r sea. + fwl_tac H5. + fwl_tac H3.
+- fwl_tac pl.
+- fwl_tac pl.
+- concl_in_app X1 r sea. + fwl_tac H1. + fwl_tac H.
+- concl_in_app X1 r sea. concl_in_app X1 r sea.
++ fwl_tac H3. + fwl_tac B.
++ list_eq_ncT. destruct e. subst. rewrite ?app_nil_r. rewrite ?app_nil_l.
+  simpl in X1 ; rewrite ?app_nil_r in X1.
+fwl_tac H.
+- concl_in_app X1 r sea. concl_in_app X1 r sea. concl_in_app X1 r sea.
++ fwl_tac H5. + fwl_tac C.
++ list_eq_ncT. destruct e. subst. rewrite ?app_nil_r. rewrite ?app_nil_l.
+  simpl in X1 ; rewrite ?app_nil_r in X1.
+fwl_tac B.
++ list_eq_nc. destruct e. list_eq_nc. destruct H1. subst.
+rewrite ?app_nil_r. rewrite ?app_nil_l.
+  simpl in X1 ; rewrite ?app_nil_r in X1.
+fwl_tac H.
+- fwl_tac pl.
+Qed.
+ +
+Lemma exchR_std_rule: forall U W (rules : rlsT (U * list W)),
+  (forall ps U S, rules ps (U, S) -> sing_empty S) ->
+  forall ps c, snd_ext_rls rules ps c ->
+    can_trf_rules (snd_rel (@swapped _)) (snd_ext_rls rules) ps c.
+Proof. unfold can_trf_rules.
+intros U W rules se ps c sqr c' fr.
+pose (fun ps xs ys U rps =>
+  sing_empty_app xs ys (se ps U (xs ++ ys) rps)) as sea.
+inversion fr. subst. clear fr.
+inversion sqr. clear sqr. subst.
+inversion X0. destruct c as [pl pr].
+simpl in H1. unfold fmlsext in H1.
+inversion H1. subst. clear H1. clear X0.
+inversion X. subst.
+acacD'T2 ; subst.
+- concl_in_app X1 r sea. + fwr_tac H3. + fwr_tac H1.
+- concl_in_app X1 r sea. concl_in_app X1 r sea.
++ fwr_tac H5. + fwr_tac C.
++ list_eq_nc. destruct e. subst. rewrite ?app_nil_r. rewrite ?app_nil_l.
+simpl in X1. rewrite ?app_nil_r in X1.
+fwr_tac H1.
+- fwr_tac pr.
+- concl_in_app X1 r sea. + fwr_tac H5. + fwr_tac H3.
+- fwr_tac pr.
+- fwr_tac pr.
+- concl_in_app X1 r sea. + fwr_tac H1. + fwr_tac H.
+- concl_in_app X1 r sea. concl_in_app X1 r sea.
++ fwr_tac H3. + fwr_tac B.
++ list_eq_ncT. destruct e. subst. rewrite ?app_nil_r. rewrite ?app_nil_l.
+  simpl in X1 ; rewrite ?app_nil_r in X1.
+fwr_tac H.
+- concl_in_app X1 r sea. concl_in_app X1 r sea. concl_in_app X1 r sea.
++ fwr_tac H5. + fwr_tac C.
++ list_eq_ncT. destruct e. subst. rewrite ?app_nil_r. rewrite ?app_nil_l.
+  simpl in X1 ; rewrite ?app_nil_r in X1.
+fwr_tac B.
++ list_eq_nc. destruct e. list_eq_nc. destruct H1. subst.
+rewrite ?app_nil_r. rewrite ?app_nil_l.
+  simpl in X1 ; rewrite ?app_nil_r in X1.
+fwr_tac H.
+- fwr_tac pr.
+Qed.
+ +
+Definition rev_pair {U W} (p : U * W) := let (x, y) := p in (y, x).
+ +
+Lemma sext_rev_fext U W (rules : rlsT (U * list W)) ps c :
+  snd_ext_rls rules ps c ->
+  fst_ext_rls (rlsmap rev_pair rules) (map rev_pair ps) (rev_pair c).
+Proof. intro ser. destruct ser. inversion r. destruct c0.
+clear r. subst. simpl.
+eapply fextI. eapply rmI_eq. apply rmI. exact X.
+2: reflexivity.
+clear X. induction ps0. reflexivity.
+simpl. rewrite IHps0. destruct a. reflexivity. Qed.
+ +
+(*
+this is not going to be worthwhile without a bunch more lemmas 
+such as sext_rev_fext above, and more
+
+Lemma exchR_std_rule: forall U W (rules : rlsT (U * list W)),
+  (forall ps U S, rules ps (U, S) -> sing_empty S) ->
+  forall ps c, snd_ext_rls rules ps c ->
+    can_trf_rules (snd_rel (@swapped _)) (snd_ext_rls rules) ps c.
+Proof. intros * se * ser.
+pose (rlsmap rev_pair rules) as rrules.
+pose (@exchL_std_rule _ _ rrules).
+require c0.
+{ intros * rr.  inversion rr. destruct c1. simpl in H1. inversion H1. subst.
+eapply se. subst rrules. exact X. }
+specialize (c0 (map rev_pair ps) (rev_pair c)).
+require c0.  { subst rrules. exact (sext_rev_fext ser). }
+
+destruct ser.
+eapply fextI. inversion r.
+
+*)

+ +
+(* we may also want to refer to rules individually *)
+Inductive Idrule (W : Type) : rlsT (rel (list W)) :=
+  | Idrule_I : forall A, Idrule [] (pair [A] [A]).
+ +
+Lemma sr_Id_alt X (A : X) ant suc: InT A ant -> InT A suc ->
+  seqrule (@Idrule X) [] (ant, suc).
+Proof. intros. apply InT_split in X1.
+apply InT_split in X0. cD. subst.
+eapply Sctxt_eq. apply (Idrule_I A).
+simpl. reflexivity. simpl. reflexivity. simpl. reflexivity. Qed.
+ +
+
+
+ +
+ + + diff --git a/General.gen_tacs.html b/General.gen_tacs.html new file mode 100644 index 0000000..bb7657e --- /dev/null +++ b/General.gen_tacs.html @@ -0,0 +1,275 @@ + + + + + + + + + + + + + +
+
+

General.gen_tacs

+ +
+ +
+Require Export List.
+Set Implicit Arguments.
+Export ListNotations.
+ +
+From Coq Require Import ssreflect.
+ +
+Require Import genT gen.
+Require Import List_lemmasT.
+(*
+Require Import swappedT.
+*)

+ +
+Definition rel (W : Type) : Type := prod W W.
+Definition trf (W : Type) : Type := W -> W.
+ +
+Lemma midI: forall T (a b c d : list T) x,
+  a = c -> b = d -> a ++ x :: b = c ++ x :: d.
+Proof. intros. subst. reflexivity. Qed.
+ +
+Lemma appI: forall T (a b c d : list T),
+  a = b -> c = d -> a ++ c = b ++ d.
+Proof. intros. subst. reflexivity. Qed.
+ +
+Lemma apprI: forall T (a b c : list T),
+  a = b -> a ++ c = b ++ c.
+Proof. intros. subst. reflexivity. Qed.
+ +
+Lemma appl_cong: forall {T} (a b c : list T),
+  (c ++ a = c ++ b) <-> (a = b).
+Proof. intros. unfold iff. apply conj ; intro.
+  induction c. simpl in H. exact H.
+  simpl in H. inversion H. tauto.
+  intros. subst. reflexivity. Qed.
+ +
+Lemma appr_cong: forall {T} (a b c : list T),
+  (a ++ c = b ++ c) <-> (a = b).
+Proof. intros. unfold iff. apply conj ; intro.
+pose (@if_eq_rev_eq T (a ++ c) (b ++ c) H).
+rewrite -> !rev_app_distr in e.
+rewrite -> appl_cong in e.
+apply if_rev_eq in e. exact e.
+subst. reflexivity. Qed.
+ +
+Lemma app_eq_nil_iff: forall {A} (l l' : list A),
+  l ++ l' = [] <-> l = [] /\ l' = [].
+Proof. intros. unfold iff. split ; intros.
+  destruct l ; simpl in H ; [ tauto | discriminate].
+  destruct H. subst. simpl. tauto. Qed.
+ +
+Lemma applI: forall {T} (a b c : list T),
+  a = b -> c ++ a = c ++ b.
+Proof. intros. subst. reflexivity. Qed.
+ +
+Definition app_assoc_cons {A} (x : A) l m xs := app_assoc l m (x :: xs).
+ +
+(* in ssreflect *)
+Ltac list_assoc_l' := repeat (rewrite !app_assoc || rewrite !app_comm_cons).
+Ltac list_assoc_r' :=
+  repeat (rewrite - !app_assoc || rewrite - !app_comm_cons).
+(* tactic to strip off same sublists on lhs or rhs of append sequence *)
+Ltac apps_eq_tac := list_assoc_r' ; rewrite ?eq_app_canc1 ;
+  list_assoc_l' ; rewrite ?eq_app_canc2 ; reflexivity.
+ +
+(* to rearrange a ++ b ++ l ++ d ++ e so that l is central, 
+  ie to give (a ++ b) ++ l ++ (d ++ e),
+  can affect terms not containing l *)

+Ltac assoc_mid l :=
+  list_assoc_r' ;
+  rewrite ?app_comm_cons ;
+  repeat ((rewrite - (app_assoc _ l _) ; fail 1) || rewrite app_assoc) ;
+  rewrite - (app_assoc _ l _).
+ +
+(* to rearrange a ++ b ++ x :: d ++ e so that x is central,
+  ie to give (a ++ b) ++ x :: d ++ e *)

+Ltac assoc_single_mid := list_assoc_r' ; rewrite ?app_assoc_cons.
+ +
+(* as assoc_single_mid, but to specify x *)
+Ltac assoc_single_mid' x := list_assoc_r' ;
+  repeat (rewrite (app_assoc_cons x) || rewrite (list_rearr23 x)).
+ +
+(* test of assoc_mid
+Lemma x : forall T (a b c d e f g : list T) (x y z : T),
+  a ++ x :: b ++ c ++ y :: d ++ e ++ z :: f = g.
+intros.
+assoc_mid b. (* doesn't work *)
+assoc_mid c.
+assoc_mid d. (* doesn't work *)
+assoc_mid e.
+*)

+ +
+Ltac acacE :=
+  repeat match goal with
+    | [ H : _ |- _ ] => apply app_eq_app in H ; sE
+    | [ H : _ |- _ ] => apply cons_eq_app in H ; sE
+    | [ H : _ |- _ ] => apply app_eq_cons in H ; sE
+    end.
+ +
+Ltac acacD :=
+  repeat match goal with
+    | [ H : _ |- _ ] => apply app_eq_app in H ; sD
+    | [ H : _ |- _ ] => apply cons_eq_app in H ; sD
+    | [ H : _ |- _ ] => apply app_eq_cons in H ; sD
+    | [ H : _ :: _ = _ :: _ |- _ ] => injection H as ?H ?H
+    end.
+ +
+Ltac acacD' :=
+  repeat match goal with
+    | [ H : _ ++ _ = _ ++ _ |- _ ] => apply app_eq_app in H ; sD
+    | [ H : _ :: _ = _ ++ _ |- _ ] => apply cons_eq_app in H ; sD
+    | [ H : _ ++ _ = _ :: _ |- _ ] => apply app_eq_cons in H ; sD
+    | [ H : _ :: _ = _ :: _ |- _ ] => injection H as ?H ?H
+    | [ H : (_, _) = (_, _) |- _ ] => injection H as ?H ?H
+    | [ H : _ :: _ = [] |- _ ] => discriminate H
+    | [ H : [] = _ :: _ |- _ ] => discriminate H
+         end.
+ +
+Ltac acacD'T2 :=
+  repeat match goal with
+    | [ H : _ ++ _ = _ ++ _ |- _ ] => apply app_eq_appT2 in H ; sD
+    | [ H : _ :: _ = _ ++ _ |- _ ] => apply cons_eq_appT2 in H ; sD
+    | [ H : _ ++ _ = _ :: _ |- _ ] => apply app_eq_consT2 in H ; sD
+    | [ H : _ :: _ = _ :: _ |- _ ] => injection H as ?H ?H
+    | [ H : (_, _) = (_, _) |- _ ] => injection H as ?H ?H
+    | [ H : _ :: _ = [] |- _ ] => discriminate H
+    | [ H : [] = _ :: _ |- _ ] => discriminate H
+         end.
+ +
+Ltac acacDe' :=
+  match goal with
+    | [ H : _ ++ _ = _ ++ _ |- _ ] => apply app_eq_app in H ; sD
+    | [ H : _ :: _ = _ ++ _ |- _ ] => apply cons_eq_app in H ; sD
+    | [ H : _ ++ _ = _ :: _ |- _ ] => apply app_eq_cons in H ; sD
+    | [ H : _ :: _ = _ :: _ |- _ ] => injection H as ?H ?H
+    | [ H : (_, _) = (_, _) |- _ ] => injection H as ?H ?H
+    | [ H : _ :: _ = [] |- _ ] => discriminate H
+    | [ H : [] = _ :: _ |- _ ] => discriminate H
+    | [ H : _ ++ _ = [] |- _ ] => apply app_eq_nil in H
+    | [ H : [] = _ ++ _ |- _ ] => apply nil_eq_app in H
+    end.
+ +
+Ltac acacDe'T2 :=
+  match goal with
+    | [ H : _ ++ _ = _ ++ _ |- _ ] => apply app_eq_appT2 in H ; sD
+    | [ H : _ :: _ = _ ++ _ |- _ ] => apply cons_eq_appT2 in H ; sD
+    | [ H : _ ++ _ = _ :: _ |- _ ] => apply app_eq_consT2 in H ; sD
+    | [ H : _ :: _ = _ :: _ |- _ ] => injection H as ?H ?H
+    | [ H : (_, _) = (_, _) |- _ ] => injection H as ?H ?H
+    | [ H : _ :: _ = [] |- _ ] => discriminate H
+    | [ H : [] = _ :: _ |- _ ] => discriminate H
+    | [ H : _ ++ _ = [] |- _ ] => apply app_eq_nilT in H
+    | [ H : [] = _ ++ _ |- _ ] => apply nil_eq_appT in H
+  end.
+ +
+Ltac acacDe := repeat (sD' || acacDe').
+Ltac acacDeT2 := repeat (sD' || acacDe'T2).
+ +
+Theorem app_eq_unitT :
+    forall {A : Type } (x y:list A) (a:A),
+      x ++ y = [a] -> (x = [] /\ y = [a]) + (x = [a] /\ y = []).
+Proof.
+  intros *; intros H; destruct x; auto.
+  simpl in H; inversion H as [[H1 H2]]; subst.
+  apply app_eq_nil in H2. destruct H2. subst. auto.
+Qed.
+ +
+Theorem unit_eq_appT :
+    forall {A : Type } (x y:list A) (a:A),
+      [a] = x ++ y -> (x = [] /\ y = [a]) + (x = [a] /\ y = []).
+Proof.
+  intros *; intros H.
+  apply app_eq_unitT. auto.
+Qed.
+ +
+Ltac list_eq_nc :=
+   match goal with
+     | [ H : _ ++ _ :: _ = [] |- _ ] => apply list_eq_nil in H
+     | [ H : [] = _ ++ _ :: _ |- _ ] => apply nil_eq_list in H
+     | [ H : _ ++ _ = [] |- _ ] => apply app_eq_nil in H
+     | [ H : [] = _ ++ _ |- _ ] => apply nil_eq_app in H
+     | [ H : _ ++ _ = [_] |- _ ] => apply app_eq_unit in H
+     | [ H : [_] = _ ++ _ |- _ ] => apply unit_eq_app in H
+     | [ H : _ ++ _ :: _ = [_] |- _ ] => apply list_eq_single in H
+     | [ H : [_] = _ ++ _ :: _ |- _ ] => apply single_eq_list in H
+     | [ H : _ :: _ = [] |- _ ] => discriminate H
+     | [ H : _ :: _ = _ :: _ |- _ ] => injection H as
+     end.
+ +
+(* Type version of list_eq_nc *)
+Ltac list_eq_ncT :=
+   match goal with
+     | [ H : _ ++ _ :: _ = [] |- _ ] => apply list_eq_nil in H
+     | [ H : [] = _ ++ _ :: _ |- _ ] => apply nil_eq_list in H
+     | [ H : _ ++ _ = [] |- _ ] => apply app_eq_nilT in H
+     | [ H : [] = _ ++ _ |- _ ] => apply nil_eq_appT in H
+     | [ H : _ ++ _ = [_] |- _ ] => apply app_eq_unitT in H
+     | [ H : [_] = _ ++ _ |- _ ] => apply unit_eq_appT in H
+     | [ H : _ ++ _ :: _ = [_] |- _ ] => apply list_eq_singleT in H
+     | [ H : [_] = _ ++ _ :: _ |- _ ] => apply single_eq_listT in H
+     | [ H : _ :: _ = [] |- _ ] => discriminate H
+     | [ H : _ :: _ = _ :: _ |- _ ] => injection H as
+     end.
+ +
+Ltac sD_list_eq := repeat (cD' || list_eq_nc || sDx).
+ +
+
+
+ +
+ + + diff --git a/General.general_export.html b/General.general_export.html new file mode 100644 index 0000000..090c24d --- /dev/null +++ b/General.general_export.html @@ -0,0 +1,54 @@ + + + + + + + + + + + + + +
+
+

General.general_export

+ +
+Require Export List_lemmasT.
+Require Export ddT.
+Require Export dd_fc.
+Require Export existsT.
+Require Export gen.
+Require Export genT.
+Require Export gen_seq.
+Require Export gen_tacs.
+Require Export gentree.
+Require Export gstep.
+Require Export rtcT.
+Require Export swappedT.
+Require Export univ_gen_ext.
+Require Export univ_gen_mod.
+
+
+ +
+ + + diff --git a/General.gentree.html b/General.gentree.html new file mode 100644 index 0000000..99c7d0f --- /dev/null +++ b/General.gentree.html @@ -0,0 +1,592 @@ + + + + + + + + + + + + + +
+
+

General.gentree

+ +
+ +
+(* constructions for inductive proofs about derivations,
+  adapted from ~jeremy/isabelle/2005/seqms/gentree.{thy,ML} *)

+ +
+Set Implicit Arguments.
+Require Import Coq.Program.Equality. (* for dependent induction/destruction *)
+Require Import PeanoNat. (* for Nat *)
+ +
+Require Import gen.
+Require Import genT.
+Require Import ddT.
+Require Import dd_fc.
+Require Import rtcT.
+Require Import Lia.
+Require Import gstep.
+ +
+
+ +
+conditions for inductive proofs for a tree +
+
+ +
+Definition gen_step_tr W rules fty P (A : fty) sub
+  (dt : @derrec_fc W rules emptyT) :=
+  (forall A' : fty, sub A' A -> forall d, P A' d) ->
+  (forall dtn, in_nextup_fc dtn dt -> P A dtn) -> P A dt.
+ +
+(* here is the same thing based the conclusion of the tree *)
+Definition gen_step_c W rules fty (P : fty -> W -> Type) A sub c
+  (dt : derrec rules emptyT c) :=
+  (forall A' : fty, sub A' A ->
+    forall c (d : derrec rules emptyT c), P A' c) ->
+  (forall cn (dtn : derrec rules emptyT cn),
+    in_nextup dtn dt -> P A cn) -> P A c.
+ +
+Definition gf2_step_tr W fty (P : fty -> W -> Type) A sub dtsr dts :=
+    ((forall A', sub A' A -> (forall dts, AccT dtsr dts -> P A' dts)) ->
+    (forall dts', dtsr dts' dts -> P A dts') -> P A dts).
+ +
+
+ +
+results linking the conditions for inductive proofs for a tree +
+
+ +
+Lemma gs_gsc W fty rules P A sub (c : W) (dt : derrec rules emptyT c):
+  iffT (@gen_step W fty P A sub (derrec rules emptyT)
+    (map (@derrec_fc_concl _ _ _) (nextup (fcI dt))) c)
+  (@gen_step_c W rules fty P A sub c dt).
+Proof. unfold gen_step. unfold gen_step_c. apply pair ; intros.
+- specialize (X X0). clear X0.
+apply X. clear X.
+apply ForallTI_forall.
+intros x inmn. apply InT_mapE in inmn. cD. subst. split.
++ apply der_der_fc.
++ destruct inmn. apply nextup_in_nu in inmn1.
+simpl. rewrite der_concl_eq. eapply X1 in inmn1. exact inmn1.
++ exact dt.
+- specialize (X X0). clear X0.
+apply X. clear X.
+intros * inn.
+eapply ForallTD_forall in X1. cD. exact X0.
+apply in_nextup_nu in inn. apply InT_mapI.
+exists (fcI dtn). split. simpl. rewrite der_concl_eq. reflexivity.
+exact inn. Qed.
+ +
+Lemma gstr_gf2 W rules fty P A sub (dt : @derrec_fc W rules emptyT) :
+  iffT (@gen_step_tr W rules fty P A sub dt)
+    (@gf2_step_tr _ fty P A sub (@in_nextup_fc _ _ _) dt).
+Proof. unfold gen_step_tr. unfold gf2_step_tr. apply pair ; intros.
+- pose (fun A' saa dts => X0 A' saa dts (AccT_in_nextup_fc dts)) as X0'.
+exact (X X0' X1).
+- revert X1. apply X. intros. apply (X0 A' X1). Qed.
+ +
+Lemma gsc_gstr W rules fty P A sub c dt:
+  iffT (@gen_step_c W rules fty P A sub c dt)
+    (@gen_step_tr W rules fty (fun A' d => P A' (derrec_fc_concl d))
+      (A : fty) sub (fcI dt)).
+Proof. unfold gen_step_tr. unfold gen_step_c. simpl.
+apply pair ; intros.
+- rewrite (der_concl_eq dt). apply X.
++ intros. specialize (X0 A' X2 (fcI d)). simpl in X0.
+rewrite (der_concl_eq d) in X0. exact X0.
++ intros * inn.
+specialize (X1 (fcI dtn)). simpl in X1.
+rewrite (der_concl_eq dtn) in X1. apply X1.
+exact (in_nextup_fcI inn).
+- rewrite (der_concl_eq dt) in X. apply X.
++ intros. apply (X0 A' X2).
+destruct d. simpl. rewrite (der_concl_eq d). exact d.
++ intros dtn inn. destruct dtn.
+simpl. rewrite (der_concl_eq d).
+apply (X1 concl d). dependent destruction inn. exact i. Qed.
+ +
+(* so we have these results linking these various conditions *)
+ +
+
+ +
+lemmas enabling inductive proofs for a tree +
+
+ +
+Lemma gen_step_c_lem W rules fty (P : fty -> W -> Type) A sub : AccT sub A ->
+  (forall A c dt, @gen_step_c W rules fty P A sub c dt) ->
+  forall c (dt : derrec rules emptyT c), P A c.
+Proof. intros acc gs. induction acc.
+eapply derrec_all_rect.
+intros. destruct H.
+unfold gen_step_c in gs.
+intros ps concl rpc drs fps.
+pose (derI _ rpc drs).
+specialize (gs x concl d X).
+apply gs. clear gs a X.
+intros. eapply ForallTD_forall in fps. apply fps.
+exact (in_nextup_concl_in X). Qed.
+ +
+(* this also gives an induction principle for derrec_fc *)
+Lemma gen_step_tr_lem W rules fty P A sub : AccT sub A ->
+  (forall A dt, @gen_step_tr W rules fty P A sub dt) -> forall dt, P A dt.
+Proof. intros acc gs. induction acc.
+unfold gen_step_tr in gs.
+pose (fun dt => gs x dt X) as p.
+intro. destruct dt. revert d. revert concl.
+(* note derrec_all_rect is forall conclusions, we want forall trees *)
+eapply derrec_rect_mut_all.
+- intros. destruct p0.
+- intros * apd. apply p. unfold nextup.
+intros dtn ind. destruct dtn.
+exact (allP_all_in_d apd (in_trees_drs d (in_nextup_fc_nu ind))). Qed.
+ +
+Lemma gf2_step_tr_lem W fty (P : fty -> W -> Type) A sub dtsr :
+  (forall A dts, gf2_step_tr P A sub dtsr dts) ->
+     AccT sub A -> (forall dts, AccT dtsr dts -> P A dts).
+Proof. intros gs acc. induction acc.
+intros dts add. induction add.
+unfold gf2_step_tr in gs. exact (gs _ _ X X0). Qed.
+ +
+
+ +
+conditions for inductive proofs for two trees +
+
+ +
+Definition dt2fun fty U W rlsa rlsb (P : fty -> U -> W -> Type) (A : fty)
+  (da : @derrec_fc U rlsa emptyT) (db : @derrec_fc W rlsb emptyT) :=
+  P A (derrec_fc_concl da) (derrec_fc_concl db).
+ +
+Definition gen_step2_tr U W rulesa rulesb fty P (A : fty) sub
+  (dta : @derrec_fc U rulesa emptyT) (dtb : @derrec_fc W rulesb emptyT) :=
+  (forall A' : fty, sub A' A -> forall da db, P A' da db) ->
+  (forall dtna, in_nextup_fc dtna dta -> P A dtna dtb) ->
+  (forall dtnb, in_nextup_fc dtnb dtb -> P A dta dtnb) -> P A dta dtb.
+ +
+Definition gen_step2_c U W rulesa rulesb fty
+  (P : fty -> U -> W -> Type) (A : fty) sub ca cb
+  (dta : derrec rulesa emptyT ca)
+  (dtb : derrec rulesb emptyT cb) :=
+  (forall A' : fty, sub A' A ->
+    forall ca (dta : derrec rulesa emptyT ca)
+      cb (dtb : derrec rulesb emptyT cb), P A' ca cb) ->
+  (forall cp (dtp : derrec rulesa emptyT cp),
+    in_nextup dtp dta -> P A cp cb) ->
+  (forall cq (dtq : derrec rulesb emptyT cq),
+    in_nextup dtq dtb -> P A ca cq) -> P A ca cb.
+ +
+Definition gf_step2_tr U W fty (P : fty -> U -> W -> Type)
+    A sub gfl gfr dta dtb :=
+  (forall A', sub A' A ->
+    forall a b, AccT gfl a -> AccT gfr b -> P A' a b) ->
+  (forall dtp, gfl dtp dta -> P A dtp dtb) ->
+  (forall dtq, gfr dtq dtb -> P A dta dtq) -> P A dta dtb.
+ +
+Definition sum_step2_tr U W fty (P : fty -> U -> W -> Type)
+    A sub gsl gsr dta dtb :=
+  (forall A', sub A' A -> forall a b, P A' a b) ->
+  (forall dta' dtb', gsl dta' + gsr dtb' < gsl dta + gsr dtb ->
+    P A dta' dtb') -> P A dta dtb.
+ +
+
+ +
+results linking the conditions for intudtive proofs for two trees +
+
+Lemma gs2_gs2c U W rulesa rulesb fty P (A : fty) sub ca cb dta dtb:
+  iffT (@gen_step2 U W fty P A sub
+    (derrec rulesa emptyT) (derrec rulesb emptyT)
+    (der_botr_ps dta) ca (der_botr_ps dtb) cb)
+  (@gen_step2_c U W rulesa rulesb fty P A sub ca cb dta dtb).
+Proof. unfold gen_step2. unfold gen_step2_c.
+  rewrite <- !der_botr_ps_eq. apply pair ; intros.
+- specialize (X X0). clear X0.
+apply (fun fa fb => X fa fb dta dtb) ; clear X ; apply ForallTI_forall ;
+intros x inmn ; apply InT_mapE in inmn ; cD ; subst ; split ;
+try apply der_der_fc.
++ destruct inmn. apply nextup_in_nu in inmn1.
+simpl. rewrite der_concl_eq. eapply X1 in inmn1. exact inmn1.
++ destruct inmn. apply nextup_in_nu in inmn1.
+simpl. rewrite der_concl_eq. eapply X2 in inmn1. exact inmn1.
+- specialize (X X0). clear X0.
+apply X ; clear X ; intros * inn.
++ eapply ForallTD_forall in X1. cD. exact X0.
+apply in_nextup_nu in inn. apply InT_mapI.
+exists (fcI dtp). split. simpl. rewrite der_concl_eq. reflexivity. exact inn.
++ eapply ForallTD_forall in X2. cD. exact X0.
+apply in_nextup_nu in inn. apply InT_mapI.
+exists (fcI dtq). split. simpl. rewrite der_concl_eq. reflexivity. exact inn.
+Qed.
+ +
+(*
+(** results linking the conditions for intudtive proofs for two trees **)
+Lemma gs2_gs2c U W rulesa rulesb fty P (A : fty) sub ca cb dta dtb:
+  iffT (@gen_step2 U W fty P A sub
+    (derrec rulesa emptyT) (derrec rulesb emptyT)
+    (map (@derrec_fc_concl _ _ _) (nextup (fcI dta))) ca
+    (map (@derrec_fc_concl _ _ _) (nextup (fcI dtb))) cb)
+  (@gen_step2_c U W rulesa rulesb fty P A sub ca cb dta dtb).
+Proof. unfold gen_step2.  unfold gen_step2_c. apply pair ; intros.
+- specialize (X X0). clear X0.
+apply (fun fa fb => X fa fb dta dtb) ; clear X ; apply ForallTI_forall ;
+intros x inmn ; apply InT_mapE in inmn ; cD ; subst ;  split ;
+try apply der_der_fc.
++ destruct inmn.  apply nextup_in_nu in inmn1.
+simpl. rewrite der_concl_eq.  eapply X1 in inmn1. exact inmn1.
++ destruct inmn.  apply nextup_in_nu in inmn1.
+simpl. rewrite der_concl_eq.  eapply X2 in inmn1. exact inmn1.
+- specialize (X X0). clear X0.
+apply X ; clear X ; intros * inn.
++ eapply ForallTD_forall in X1. cD. exact X0.
+apply in_nextup_nu in inn.  apply InT_mapI.
+exists (fcI dtp). split. simpl. rewrite der_concl_eq. reflexivity.  exact inn.
++ eapply ForallTD_forall in X2. cD. exact X0.
+apply in_nextup_nu in inn.  apply InT_mapI.
+exists (fcI dtq). split. simpl. rewrite der_concl_eq. reflexivity.  exact inn.
+Qed.
+*)

+ +
+Lemma gs2tr_gf2 U W rulesa rulesb fty P A sub dta dtb :
+  iffT (@gen_step2_tr U W rulesa rulesb fty P A sub dta dtb)
+    (@gf_step2_tr _ _ fty P A sub
+      (@in_nextup_fc _ _ _) (@in_nextup_fc _ _ _) dta dtb).
+Proof. unfold gen_step2_tr. unfold gf_step2_tr. apply pair ; intros.
+- pose (fun A' saa a b =>
+  X0 A' saa a b (AccT_in_nextup_fc a) (AccT_in_nextup_fc b)) as X0'.
+exact (X X0' X1 X2).
+- revert X2. revert X1. apply X. intros. apply (X0 A' X1). Qed.
+ +
+Lemma gs2c_gs2tr U W rulesa rulesb fty P A sub ca cb dta dtb:
+  iffT (@gen_step2_c U W rulesa rulesb fty P A sub ca cb dta dtb)
+  (@gen_step2_tr U W rulesa rulesb fty (dt2fun P) A sub (fcI dta) (fcI dtb)).
+Proof. unfold gen_step2_tr. unfold gen_step2_c. unfold dt2fun. simpl.
+apply pair ; intros.
+- rewrite (der_concl_eq dta). rewrite (der_concl_eq dtb). apply X.
++ intros A' saa ca0 da cb0 db.
+specialize (X0 A' saa (fcI da) (fcI db)). simpl in X0.
+rewrite (der_concl_eq da) in X0. rewrite (der_concl_eq db) in X0. exact X0.
++ intros * inn. specialize (X1 (fcI dtp)). simpl in X1.
+rewrite (der_concl_eq dtp) in X1. rewrite (der_concl_eq dtb) in X1. apply X1.
+exact (in_nextup_fcI inn).
++ intros * inn. specialize (X2 (fcI dtq)). simpl in X2.
+rewrite (der_concl_eq dtq) in X2. rewrite (der_concl_eq dta) in X2. apply X2.
+exact (in_nextup_fcI inn).
+- rewrite (der_concl_eq dta) in X. rewrite (der_concl_eq dtb) in X. apply X.
++ intros A' saa *. apply (X0 A' saa).
+destruct da. simpl. rewrite (der_concl_eq d). exact d.
+destruct db. simpl. rewrite (der_concl_eq d). exact d.
++ intros * inn. destruct dtna.
+simpl. rewrite (der_concl_eq d). apply (X1 concl d).
+dependent destruction inn. exact i.
++ intros * inn. destruct dtnb.
+simpl. rewrite (der_concl_eq d). apply (X2 concl d).
+dependent destruction inn. exact i. Qed.
+ +
+(* so we have these results linking these various conditions *)
+ +
+
+ +
+lemmas enabling inductive proofs for two trees +
+
+ +
+Lemma gen_step2_c_lem U W rulesa rulesb fty P A sub : AccT sub A ->
+  (forall A ca cb dta dtb,
+    @gen_step2_c U W rulesa rulesb fty P A sub ca cb dta dtb) ->
+  forall ca (dta : derrec rulesa emptyT ca) cb (dtb : derrec rulesb emptyT cb),
+    P A ca cb.
+Proof. intros acc gs. induction acc.
+eapply derrec_all_rect2.
+intros. destruct H. intros. destruct H.
+unfold gen_step2_c in gs.
+intros *. intros rx ry drx dry fpx fpy.
+pose (derI _ rx drx) as dx. pose (derI _ ry dry) as dy.
+specialize (gs x cx cy dx dy X).
+apply gs ; clear gs a X ; intros.
++ eapply ForallTD_forall in fpx. apply fpx. exact (in_nextup_concl_in X).
++ eapply ForallTD_forall in fpy. apply fpy. exact (in_nextup_concl_in X).
+Qed.
+ +
+Lemma gen_step2_tr_lem U W rulesa rulesb fty P A sub : AccT sub A ->
+  (forall A dta dtb, @gen_step2_tr U W rulesa rulesb fty P A sub dta dtb) ->
+  forall dta dtb, P A dta dtb.
+Proof. intros acc gs. induction acc.
+unfold gen_step2_tr in gs. pose (fun dta dtb => gs x dta dtb X) as p.
+intro. destruct dta. revert d. revert concl.
+eapply (@derrec_rect_mut_all U rulesa emptyT
+  (fun ca (d : derrec rulesa emptyT ca) => forall dtb, P x (fcI d) dtb)).
+- intros. destruct p0.
+- intros * apd dtb. destruct dtb. revert d0. revert concl0.
+eapply (derrec_rect_mut_all).
++ intros. destruct p0.
++ intros * apdb. apply p. unfold nextup.
+intros dtna inda. destruct dtna.
+exact (allP_all_in_d apd (in_trees_drs d (in_nextup_fc_nu inda)) _).
+intros dtnb indb. destruct dtnb.
+exact (allP_all_in_d apdb (in_trees_drs _ (in_nextup_fc_nu indb))). Qed.
+ +
+Lemma gf_step2_tr_lem U W fty (P : fty -> U -> W -> Type) A sub gra grb :
+  (forall A dta dtb, gf_step2_tr P A sub gra grb dta dtb) -> AccT sub A ->
+    (forall dta, AccT gra dta -> forall dtb, AccT grb dtb -> P A dta dtb).
+Proof. intros gs acc. induction acc.
+unfold gf_step2_tr in gs.
+pose (fun y s dta dtb adg => X y s dta adg dtb) as X'.
+pose (fun dta dtb => gs x dta dtb X').
+intros dta aga. induction aga.
+intros dtb agb. pose agb. induction a1.
+apply p.
+intros dtp gad. apply X0 ; assumption.
+intros dtq gbd. apply (X1 dtq gbd (a1 dtq gbd)).
+Qed.
+ +
+Definition measure {U} f (dtn dt : U) := f dtn < f dt.
+ +
+Lemma AccT_measure' U f n : forall dt : U, f dt < n -> AccT (measure f) dt.
+Proof. induction n.
+- intros. apply Nat.nlt_0_r in H. contradiction H.
+- intros. apply AccT_intro. intros. unfold measure in H0. apply IHn.
+apply Nat.lt_succ_r in H. lia. Qed.
+ +
+Definition AccT_measure U f dt :=
+  @AccT_measure' U f _ dt (Nat.lt_succ_diag_r _).
+ +
+Definition size_step2_tr U W fty rulesa rulesb P (A : fty) sub :=
+    gf_step2_tr P A sub (measure (@derrec_fc_size U rulesa emptyT))
+      (measure (@derrec_fc_size W rulesb emptyT)).
+ +
+Definition height_step2_tr U W fty rulesa rulesb P (A : fty) sub :=
+    gf_step2_tr P A sub (measure (@derrec_fc_height U rulesa emptyT))
+      (measure (@derrec_fc_height W rulesb emptyT)).
+ +
+Lemma size_step2_tr_lem U W fty (rulesa : rlsT U) (rulesb : rlsT W)
+  (P : fty -> derrec_fc rulesa emptyT -> derrec_fc rulesb emptyT -> Type)
+  A sub dta dtb: AccT sub A ->
+  (forall A dta dtb, size_step2_tr P A sub dta dtb) -> P A dta dtb.
+Proof. unfold size_step2_tr. intros acc fgf.
+apply (gf_step2_tr_lem fgf acc) ; apply AccT_measure. Qed.
+ +
+Lemma height_step2_tr_lem U W fty (rulesa : rlsT U) (rulesb : rlsT W)
+  (P : fty -> derrec_fc rulesa emptyT -> derrec_fc rulesb emptyT -> Type)
+  A sub dta dtb: AccT sub A ->
+  (forall A dta dtb, height_step2_tr P A sub dta dtb) -> P A dta dtb.
+Proof. unfold height_step2_tr. intros acc fgf.
+apply (gf_step2_tr_lem fgf acc) ; apply AccT_measure. Qed.
+ +
+Lemma nextup_size W rules prems (d dn : @derrec_fc W rules prems):
+  InT dn (nextup d) -> derrec_fc_size dn < derrec_fc_size d.
+Proof. destruct d. destruct dn.
+unfold derrec_fc_size. unfold nextup.
+destruct d. intro. inversion X.
+intro idt. apply in_trees_drs in idt.
+simpl. clear r. (* otherwise complicates induction *)
+induction idt ; simpl.
++ apply Nat.lt_succ_r. apply Nat.le_add_r.
++ eapply Nat.lt_le_trans. apply IHidt. apply le_n_S. apply Nat.le_add_l. Qed.
+ +
+Lemma nextup_height W rules prems (d dn : @derrec_fc W rules prems):
+  InT dn (nextup d) -> derrec_fc_height dn < derrec_fc_height d.
+Proof. destruct d. destruct dn.
+unfold derrec_fc_height. unfold nextup.
+destruct d. intro. inversion X.
+intro idt. apply in_trees_drs in idt.
+simpl. clear r. (* otherwise complicates induction *)
+induction idt ; simpl.
++ apply Nat.lt_succ_r. apply Nat.le_max_l.
++ eapply Nat.lt_le_trans. apply IHidt. apply le_n_S. apply Nat.le_max_r. Qed.
+ +
+Definition in_nextup_size W rules prems d dn inn :=
+  @nextup_size W rules prems d dn (in_nextup_fc_nu inn).
+Definition in_nextup_height W rules prems d dn inn :=
+  @nextup_height W rules prems d dn (in_nextup_fc_nu inn).
+ +
+Lemma gs2_tr_size U W fty (rulesa : rlsT U) (rulesb : rlsT W)
+  (P : fty -> derrec_fc rulesa emptyT -> derrec_fc rulesb emptyT -> Type)
+  A sub dta dtb:
+  gen_step2_tr P A sub dta dtb -> size_step2_tr P A sub dta dtb.
+Proof. unfold size_step2_tr. unfold gf_step2_tr. unfold gen_step2_tr.
+intros gs2 saa.
+specialize (gs2 (fun A' s a b =>
+  saa A' s a b (AccT_measure _ _) (AccT_measure _ _))).
+clear saa. intros pb aq. apply gs2.
+intros. apply (pb dtna). unfold measure. apply (in_nextup_size X).
+intros. apply (aq dtnb). unfold measure. apply (in_nextup_size X). Qed.
+ +
+Lemma gs2_tr_height U W fty (rulesa : rlsT U) (rulesb : rlsT W)
+  (P : fty -> derrec_fc rulesa emptyT -> derrec_fc rulesb emptyT -> Type)
+  A sub dta dtb:
+  gen_step2_tr P A sub dta dtb -> height_step2_tr P A sub dta dtb.
+Proof. unfold height_step2_tr. unfold gf_step2_tr. unfold gen_step2_tr.
+intros gs2 saa.
+specialize (gs2 (fun A' s a b =>
+  saa A' s a b (AccT_measure _ _) (AccT_measure _ _))).
+clear saa. intros pb aq. apply gs2.
+intros. apply (pb dtna). unfold measure. apply (in_nextup_height X).
+intros. apply (aq dtnb). unfold measure. apply (in_nextup_height X). Qed.
+ +
+Lemma gs2_hs2 (U W fty : Type) rlsl rlsr (P : fty -> U -> W -> Type)
+  A sub cl cr (dl : derrec rlsl emptyT cl) (dr : derrec rlsr emptyT cr)
+  psl psr (brl : botRule_fc (fcI dl) psl cl) (brr : botRule_fc (fcI dr) psr cr):
+  gen_step2 P A sub (derrec rlsl emptyT) (derrec rlsr emptyT) psl cl psr cr ->
+  height_step2_tr (dt2fun P) A sub (fcI dl) (fcI dr).
+Proof. intro gs2. apply gs2_tr_height. apply gs2c_gs2tr. apply gs2_gs2c.
+rewrite (snd (botRule_fc_prems brl)). rewrite (snd (botRule_fc_prems brr)).
+exact gs2. Qed.
+ +
+Definition sumh_step2_tr U W fty (rulesa : rlsT U) (rulesb : rlsT W)
+  (P : fty -> derrec_fc rulesa emptyT -> derrec_fc rulesb emptyT -> Type)
+    A sub :=
+      sum_step2_tr P A sub (@derrec_fc_height _ _ _) (@derrec_fc_height _ _ _).
+ +
+Lemma sum_step2_tr_gf2 U W fty (P : fty -> U -> W -> Type)
+    A sub gsa gsb dta dtb :
+  iffT (sum_step2_tr P A sub gsa gsb dta dtb)
+    (gf2_step_tr (fun fml ab => P fml (fst ab) (snd ab)) A sub
+      (measure (fun ab => Nat.add (gsa (fst ab)) (gsb (snd ab)))) (dta, dtb)).
+Proof. unfold sum_step2_tr. unfold gf2_step_tr.
+unfold iffT. split.
+- intros fsglp sp glpp.
+simpl. apply fsglp.
++ intros A' saa a b.
+apply (sp A' saa (a, b)). apply AccT_measure.
++ intros *. specialize (glpp (dta', dtb')).
+unfold measure in glpp. simpl in glpp. exact glpp.
+- intros sglpp sp glp.
+simpl in sglpp. apply sglpp.
+intros. destruct dts. simpl. apply sp. apply X.
+intros. destruct dts'. simpl. apply glp.
+unfold measure in H. simpl in H. exact H.
+Qed.
+ +
+Definition sum_step2_tr_D_gf2 U W fty P A sub gsa gsb dta dtb :=
+  iffT_D1 (@sum_step2_tr_gf2 U W fty P A sub gsa gsb dta dtb).
+ +
+Lemma sum_step2_tr_lem U W fty (P : fty -> U -> W -> Type)
+    A sub gsa gsb dta dtb : AccT sub A ->
+  (forall A dta dtb, sum_step2_tr P A sub gsa gsb dta dtb) -> P A dta dtb.
+Proof. intros *. intros acc ss.
+pose (fun fty UW => P fty (fst UW) (snd UW)) as Q.
+assert (Q A (dta, dtb)).
+eapply gf2_step_tr_lem.
+intros. apply sum_step2_tr_D_gf2.
+all: cycle 1. exact acc. apply AccT_measure.
+subst Q. simpl in X. exact X.
+destruct dts. apply ss. Qed.
+ +
+Lemma gf2_sum U W fty (P : fty -> U -> W -> Type) A sub gsa gsb dta dtb:
+  gf_step2_tr P A sub (measure gsa) (measure gsb) dta dtb ->
+    sum_step2_tr P A sub gsa gsb dta dtb.
+Proof. unfold sum_step2_tr. unfold gf_step2_tr.
+intros gf2 saa lgss.
+require gf2. intros. exact (saa A' X a b).
+apply gf2 ; intros ; apply lgss ; unfold measure in H; lia. Qed.
+ +
+Lemma sumh_step2_tr_lem U W fty (rulesa : rlsT U) (rulesb : rlsT W)
+  (P : fty -> derrec_fc rulesa emptyT -> derrec_fc rulesb emptyT -> Type)
+  (A : fty) sub dta dtb : AccT sub A ->
+  (forall A dta dtb, sumh_step2_tr P A sub dta dtb) -> P A dta dtb.
+Proof. unfold sumh_step2_tr. apply sum_step2_tr_lem. Qed.
+ +
+Lemma hs2_sumh U W fty rulesa rulesb P A sub dta dtb:
+  @height_step2_tr U W fty rulesa rulesb P A sub dta dtb ->
+  @sumh_step2_tr U W fty rulesa rulesb P A sub dta dtb.
+Proof. unfold height_step2_tr. unfold sumh_step2_tr. apply gf2_sum. Qed.
+ +
+(* TODO
+
+if possible, need to look at gen_step2sr
+gs2_tr_sr
+gs2_sr_tr
+
+val _ = qed_goal_spec_mp "gs2_sr_tr" gentree.thy
+  "valid rls dta --> valid rls dtb --> \
+    \ gen_step2sr P A sub rls (botRule dta, botRule dtb) --> \
+    \ gen_step2_tr (*)

+(* summary of some results for two trees *)
+ +
+
+
+ +
+ + + diff --git a/General.gstep.html b/General.gstep.html new file mode 100644 index 0000000..d507b73 --- /dev/null +++ b/General.gstep.html @@ -0,0 +1,809 @@ + + + + + + + + + + + + + +
+
+

General.gstep

+ +
+ +
+(* constructions for inductive proofs about derivations,
+  part adapted from ~jeremy/isabelle/2005/seqms/gstep.{thy,ML}
+  but can_trf_rules and friends are new *)

+ +
+Set Implicit Arguments.
+ +
+Require Import Init.Wf. (* wfp called Acc, note Acc_intro, Acc_rect,
+  or AccT for Type version *)

+ +
+Require Import Coq.Program.Equality. (* for dependent induction/destruction *)
+Require Import PeanoNat. (* for Nat *)
+ +
+(* Add LoadPath "../tense-lns". *)
+Require Import gen genT.
+Require Import ddT dd_fc.
+Require Import rtcT.
+ +
+(*
+"gen_step ?P ?A ?sub ?derivs (?ps, ?concl) =
+  ((ALL A'. (A', ?A) : ?sub --> Ball ?derivs (?P A')) -->
+  (ALL p:set ?ps. p : ?derivs & ?P ?A p) -->
+  ?concl : ?derivs --> ?P ?A ?concl)"
+  *)

+ +
+Definition gen_step (seq fml : Type) P A (sub : fml -> fml -> Type)
+  derivs ps (concl : seq) :=
+  (forall A', sub A' A -> (forall x, derivs x -> P A' x)) ->
+  ForallT (fun p => prod (derivs p) (P A p)) ps -> derivs concl -> P A concl.
+ +
+Lemma gen_step_sub_mono seq fml P A sub1 sub2 derivs ps c :
+  rsub sub1 sub2 -> gen_step P A sub1 derivs ps c ->
+  @gen_step seq fml P A sub2 derivs ps c.
+Proof. unfold gen_step. intros rs gs saa. apply gs.
+intros A' s1aa. exact (saa A' (rsubD rs _ _ s1aa)). Qed.
+ +
+Lemma gen_step_def: forall (seq fml : Type) P A sub derivs ps (concl : seq),
+  @gen_step seq fml P A sub derivs ps concl =
+  ((forall A', sub A' A -> (forall x, derivs x -> P A' x)) ->
+  ForallT (fun p => prod (derivs p) (P A p)) ps -> derivs concl -> P A concl).
+Proof. intros. unfold gen_step. reflexivity. Qed.
+ +
+Inductive gen_step' (seq fml : Type) P A (sub : fml -> fml -> Type)
+  derivs ps (concl : seq) :=
+  | gsI : ((forall A', sub A' A -> (forall x, derivs x -> P A' x)) ->
+  ForallT (fun p => prod (derivs p) (P A p)) ps -> derivs concl -> P A concl) ->
+  gen_step' P A (sub : fml -> fml -> Type) derivs ps (concl : seq).
+ +
+Lemma gs_gs': forall (seq fml : Type) P A (sub : fml -> fml -> Type)
+  derivs ps (concl : seq),
+  iffT (gen_step P A sub derivs ps concl) (gen_step' P A sub derivs ps concl).
+Proof. intros. unfold gen_step. unfold iffT. split ; intros.
+apply gsI. exact X.
+destruct X. apply p ; assumption. Qed.
+ +
+(*
+"gen_step2 ?P ?A ?sub (?dls, ?drs) ((?psl, ?cl), ?psr, ?cr) =
+  ((ALL A'.
+       (A', ?A) : ?sub --> (ALL dl:?dls. ALL dr:?drs. ?P A' (dl, dr))) -->
+   (ALL pl:set ?psl. pl : ?dls & ?P ?A (pl, ?cr)) -->
+   (ALL pr:set ?psr. pr : ?drs & ?P ?A (?cl, pr)) -->
+   ?cl : ?dls --> ?cr : ?drs --> ?P ?A (?cl, ?cr))"
+*)

+ +
+Definition gen_step2 (seql seqr fml : Type) (P : fml -> seql -> seqr -> Type)
+  A (sub : fml -> fml -> Type) dls drs psl cl psr cr :=
+  (forall A', sub A' A ->
+    forall dl, dls dl -> forall dr, drs dr -> P A' dl dr) ->
+  ForallT (fun pl => prod (dls pl) (P A pl cr)) psl ->
+  ForallT (fun pr => prod (drs pr) (P A cl pr)) psr ->
+  dls cl -> drs cr -> P A cl cr.
+ +
+Lemma gen_step2_sub_mono seql seqr fml P A sub1 sub2 dls drs psl cl psr cr :
+  rsub sub1 sub2 -> gen_step2 P A sub1 dls drs psl cl psr cr ->
+  @gen_step2 seql seqr fml P A sub2 dls drs psl cl psr cr.
+Proof. unfold gen_step2. intros rs gs saa. apply gs.
+intros A' s1aa. exact (saa A' (rsubD rs _ _ s1aa)). Qed.
+ +
+Definition gen_step2_empty seql seqr fml P A sub dls drs psl cl psr cr :=
+  (@gen_step2_sub_mono seql seqr fml P A _ sub dls drs psl cl psr cr)
+  (rsub_emptyT sub).
+ +
+(* generalised version of inductive step proof *)
+Lemma gen_step_lem_psT: forall (sty fty : Type) (P : fty -> sty -> Type)
+  A sub rules prems, AccT sub A ->
+    (forall A ps concl, rules ps concl ->
+      gen_step P A sub (derrec rules prems) ps concl) ->
+    (forall A prem, prems prem -> P A prem) ->
+    (forall seq, derrec rules prems seq -> P A seq).
+Proof. intros *. intros acc gs prs. induction acc.
+intros. eapply derrec_all_rect. apply prs.
+intros. unfold gen_step in gs. eapply gs. exact X1. exact X.
+apply ForallTI_forall. intros. split.
+eapply dersrecD_forall in X2. exact X2. exact X4.
+eapply ForallTD_forall in X3. exact X3. exact X4.
+eapply derI ; eassumption. exact X0. Qed.
+ +
+Lemma gen_step_lem_ps: forall (sty fty : Type) (P : fty -> sty -> Type)
+  A sub rules prems, Acc sub A ->
+    (forall A ps concl, rules ps concl ->
+      gen_step P A sub (derrec rules prems) ps concl) ->
+    (forall A prem, prems prem -> P A prem) ->
+    (forall seq, derrec rules prems seq -> P A seq).
+Proof. intros *. intros acc gs prs. induction acc.
+intros. eapply derrec_all_rect. apply prs.
+intros. unfold gen_step in gs. eapply gs. exact X1. exact X.
+apply ForallTI_forall. intros. split.
+eapply dersrecD_forall in X2. exact X2. exact X4.
+eapply ForallTD_forall in X3. exact X3. exact X4.
+eapply derI ; eassumption. exact X0. Qed.
+ +
+Definition gen_step_lem sty fty P A sub rules acc gs :=
+  @gen_step_lem_ps sty fty P A sub rules (@emptyT sty) acc gs
+  (fun A0 => @emptyT_any' sty (P A0)).
+ +
+Definition gen_step_lemT sty fty P A sub rules acc gs :=
+  @gen_step_lem_psT sty fty P A sub rules (@emptyT sty) acc gs
+  (fun A0 => @emptyT_any' sty (P A0)).
+ +
+(* this one does allow for premises *)
+Lemma gen_step2_lem_ps: forall (stya styb fty : Type) P (A : fty) sub
+  rlsa rlsb (premsa : stya -> Type) (premsb : styb -> Type),
+  Acc sub A -> (forall A psa psb ca cb, rlsa psa ca -> rlsb psb cb ->
+  gen_step2 P A sub (derrec rlsa premsa)
+    (derrec rlsb premsb) psa ca psb cb) ->
(forall A pa, premsa pa -> forall cb, derrec rlsb premsb cb -> P A pa cb) ->
(forall A pb, premsb pb -> forall ca, derrec rlsa premsa ca -> P A ca pb) ->
+  forall seqa, derrec rlsa premsa seqa ->
+  forall seqb, derrec rlsb premsb seqb -> P A seqa seqb.
+Proof. intros *. intros acc gs prsa prsb. induction acc.
+eapply derrec_all_rect2.
+intros. eapply prsa in X0. exact X0. exact X1.
+intros. eapply prsb in X0. exact X0. exact X1.
+intros. unfold gen_step2 in gs. eapply gs. exact X0. exact X1. exact X.
+apply ForallTI_forall. intros. split.
+eapply dersrecD_forall in X2. exact X2. exact X6.
+eapply ForallTD_forall in X4. exact X4. exact X6.
+apply ForallTI_forall. intros. split.
+eapply dersrecD_forall in X3. exact X3. exact X6.
+eapply ForallTD_forall in X5. exact X5. exact X6.
+eapply derI ; eassumption. eapply derI ; eassumption. Qed.
+ +
+Lemma gen_step2_lem_psT: forall (stya styb fty : Type) P (A : fty) sub
+  rlsa rlsb (premsa : stya -> Type) (premsb : styb -> Type),
+  AccT sub A -> (forall A psa psb ca cb, rlsa psa ca -> rlsb psb cb ->
+  gen_step2 P A sub (derrec rlsa premsa)
+    (derrec rlsb premsb) psa ca psb cb) ->
(forall A pa, premsa pa -> forall cb, derrec rlsb premsb cb -> P A pa cb) ->
(forall A pb, premsb pb -> forall ca, derrec rlsa premsa ca -> P A ca pb) ->
+  forall seqa, derrec rlsa premsa seqa ->
+  forall seqb, derrec rlsb premsb seqb -> P A seqa seqb.
+Proof. intros *. intros acc gs prsa prsb. induction acc.
+eapply derrec_all_rect2.
+intros. eapply prsa in X0. exact X0. exact X1.
+intros. eapply prsb in X0. exact X0. exact X1.
+intros. unfold gen_step2 in gs. eapply gs. exact X0. exact X1. exact X.
+apply ForallTI_forall. intros. split.
+eapply dersrecD_forall in X2. exact X2. exact X6.
+eapply ForallTD_forall in X4. exact X4. exact X6.
+apply ForallTI_forall. intros. split.
+eapply dersrecD_forall in X3. exact X3. exact X6.
+eapply ForallTD_forall in X5. exact X5. exact X6.
+eapply derI ; eassumption. eapply derI ; eassumption. Qed.
+ +
+(* this one doesn't allow for premises *)
+Definition gen_step2_lem stya styb fty P A sub rlsa rlsb acc gs :=
+  @gen_step2_lem_ps stya styb fty P A sub rlsa rlsb
+  (@emptyT stya) (@emptyT styb) acc gs
+  (fun _ => @emptyT_any' stya _) (fun _ => @emptyT_any' styb _).
+ +
+Definition gen_step2_lemT stya styb fty P A sub rlsa rlsb acc gs :=
+  @gen_step2_lem_psT stya styb fty P A sub rlsa rlsb
+  (@emptyT stya) (@emptyT styb) acc gs
+  (fun _ => @emptyT_any' stya _) (fun _ => @emptyT_any' styb _).
+ +
+(* simplified versions, forget A, then derive version with A *)
+Definition gen_steps (seq : Type) P derivs ps (concl : seq) :=
+  ForallT (fun p => prod (derivs p) (P p)) ps -> derivs concl -> P concl.
+ +
+Definition gen_step2s (seql seqr : Type) (P : seql -> seqr -> Type)
+  dls drs psl cl psr cr :=
+  ForallT (fun pl => prod (dls pl) (P pl cr)) psl ->
+  ForallT (fun pr => prod (drs pr) (P cl pr)) psr ->
+  dls cl -> drs cr -> P cl cr.
+ +
+(* generalised version of inductive step proof *)
+Lemma gen_steps_lem_ps (sty : Type) (P : sty -> Type) rules prems:
+    (forall ps concl, rules ps concl ->
+      gen_steps P (derrec rules prems) ps concl) ->
+    (forall prem, prems prem -> P prem) ->
+    (forall seq, derrec rules prems seq -> P seq).
+Proof. intros *. intros gs prs.
+intros. eapply derrec_all_rect. apply prs.
+intros. unfold gen_steps in gs. eapply gs. exact X0.
+apply ForallTI_forall. intros. split.
+eapply dersrecD_forall in X1 ; eassumption.
+eapply ForallTD_forall in X2 ; eassumption.
+eapply derI ; eassumption. exact X. Qed.
+ +
+Definition gen_steps_lem sty P rules gs :=
+  @gen_steps_lem_ps sty P rules (@emptyT sty) gs (@emptyT_any' sty P).
+ +
+Lemma gen_step2s_lem_ps: forall (stya styb : Type) P
+  rlsa rlsb (premsa : stya -> Type) (premsb : styb -> Type),
+  (forall psa psb ca cb, rlsa psa ca -> rlsb psb cb ->
+  gen_step2s P (derrec rlsa premsa) (derrec rlsb premsb) psa ca psb cb) ->
(forall pa, premsa pa -> forall cb, derrec rlsb premsb cb -> P pa cb) ->
(forall pb, premsb pb -> forall ca, derrec rlsa premsa ca -> P ca pb) ->
+  forall seqa, derrec rlsa premsa seqa ->
+  forall seqb, derrec rlsb premsb seqb -> P seqa seqb.
+Proof. intros *. intros gs prsa prsb.
+eapply derrec_all_rect2.
+- intros px ppx cy db. eapply prsa in db ; eassumption.
+- intros py ppy cx da. eapply prsb in da ; eassumption.
+- intros *. intros ra rb da db fx fy.
+unfold gen_step2s in gs. eapply gs.
++ exact ra. + exact rb.
++ apply ForallTI_forall. intros x inx. split.
+eapply dersrecD_forall in da ; eassumption.
+eapply ForallTD_forall in fx ; eassumption.
++ apply ForallTI_forall. intros y iny. split.
+eapply dersrecD_forall in db ; eassumption.
+eapply ForallTD_forall in fy ; eassumption.
++ eapply derI ; eassumption.
++ eapply derI ; eassumption. Qed.
+ +
+Definition gen_step2s_lem stya styb P rlsa rlsb gs :=
+  @gen_step2s_lem_ps stya styb P rlsa rlsb
+  (@emptyT stya) (@emptyT styb) gs
+  (@emptyT_any' stya _) (@emptyT_any' styb _).
+ +
+(* proof of version depending on formula A from versions not depending on A,
+  showing this is possible, however, since this is difficult and
+  proving (for example) gen_step2_lem_psT is not much harder
+  than proving gen_step2s_lem_ps, might as welll use gen_step2_lem_psT *)

+Lemma gen_step_lem' sty fty P (A : fty) sub rules:
+  AccT sub A -> (forall A0 ps concl, rules ps concl ->
+    gen_step P A0 sub (derrec rules (emptyT (X:=sty))) ps concl) ->
+    forall seq : sty, derrec rules (emptyT (X:=sty)) seq -> P A seq.
+Proof. intros acc gs. induction acc.
+remember (fun s => (forall y, sub y x ->
+  forall seq, derrec rules (emptyT (X:=sty)) seq -> P y seq) -> P x s) as Q.
+pose (@gen_steps_lem sty Q).
+rewrite HeqQ in q. intros seq ds. eapply q. 2: apply ds.
+all: cycle 1. intros y syx. eapply X. exact syx.
+clear q. intros ps concl rpc.
+eapply gs in rpc. unfold gen_step in rpc.
+unfold gen_steps. intros ft drc sp.
+apply rpc. exact sp. 2: exact drc.
+apply ForallTI_forall. intros x0 inxp.
+eapply ForallTD_forall in ft. 2: apply inxp. cD.
+split. exact ft. apply ft0. exact sp. Qed.
+ +
+(* alternative approach to admissibility, useful for swap in Box rule of K4,
+  where single swap in conclusion requires two swaps in premises,
+  which requires the _rtc;
+  very easily extended to derl rules in def of can_trf_rules
+  (though this doesn't give height preservation),
+  can we extend this to reflexive transitive closure of R ?? *)

+ +
+(* note - although we can't seem to be able to extend this to derl
+  and reflexive transitive closure of R together,
+  we do need reflexive closure of R together with
+  a sort of reflexive closure of the rules, eg
+  where R is that a certain rule can be inverted, 
+  where the rule is that same rule, then we don't want a R step or
+  a single rule application step; 
+  for the K4 rule which allows weakening, where the formula to be
+  inverted is among what is added, then the changed version is
+  derived from the original premise, not from a related premise *)

+ +
+Unset Universe Polymorphism.
+ +
+Definition can_trf_rules (sty : Type) R rules (ps : list sty) (c : sty) :=
+  forall c' : sty, R c c' ->
+  (sigT (fun ps' : list sty => prod (rules ps' c')
+    (ForallT (fun p' => sigT (fun p => prod (InT p ps) (R p p'))) ps'))).
+ +
+Definition can_trf_rules_rc (sty : Type) R rules (ps : list sty) (c : sty) :=
+  forall c' : sty, R c c' ->
+  (sigT (fun ps' : list sty => prod (rules ps' c') (ForallT
+    (fun p' => sigT (fun p => prod (InT p ps) (clos_reflT R p p'))) ps'))).
+ +
+(* can_trf_rules_rc would be a bit pointless if we specified that
+  ps to c is a rule, because then can_trf_rules R would imply
+  can_trf_rules (clos_reflT R) *)

+ +
+Lemma can_trf_rules_imp_rc sty R rules ps c:
+  @can_trf_rules sty R rules ps c -> @can_trf_rules_rc sty R rules ps c.
+Proof. unfold can_trf_rules. unfold can_trf_rules_rc.
+intros. apply X in X0. cD. exists X0. split. assumption.
+apply ForallTI_forall. intros.
+eapply ForallTD_forall in X2. 2: eassumption. cD.
+exists X2. split. assumption.
+apply rT_step. assumption. Qed.
+ +
+Lemma can_trf_rules_mono' sty R rulesa rulesb:
+  rsub rulesa rulesb -> forall ps (c : sty),
+  can_trf_rules R rulesa ps c -> can_trf_rules R rulesb ps c.
+Proof. unfold can_trf_rules.
+intros. apply X0 in X1. clear X0. cD.
+eexists. split. unfold rsub in X. apply X. apply X0. apply X2. Qed.
+ +
+Lemma can_trf_rules_rc_mono' sty R rulesa rulesb:
+  rsub rulesa rulesb -> forall ps (c : sty),
+  can_trf_rules_rc R rulesa ps c -> can_trf_rules_rc R rulesb ps c.
+Proof. unfold can_trf_rules_rc.
+intros. apply X0 in X1. clear X0. cD.
+eexists. split. unfold rsub in X. apply X. apply X0. apply X2. Qed.
+ +
+Definition can_trf_rules_mono sty R rulesa rulesb r :=
+  rsubI _ _ (@can_trf_rules_mono' sty R rulesa rulesb r).
+Definition can_trf_rules_rc_mono sty R rulesa rulesb r :=
+  rsubI _ _ (@can_trf_rules_rc_mono' sty R rulesa rulesb r).
+ +
+(* union of two relations *)
+Polymorphic Inductive runion U V ra rb (ps : U) (c : V) : Type :=
+  | run_l : ra ps c -> @runion U V ra rb ps c
+  | run_r : rb ps c -> @runion U V ra rb ps c.
+ +
+(* union of set of rule sets *)
+Polymorphic Inductive rUnion U V rr (ps : U) (c : V) : Type :=
+  | rUnI : forall r, rr r -> r ps c -> @rUnion U V rr ps c.
+ +
+(* union property for R in can_trf_rules... *)
+Lemma can_trf_rules_un sty R R' rules ps (c : sty):
+  can_trf_rules R rules ps c -> can_trf_rules R' rules ps c ->
+    can_trf_rules (runion R R') rules ps c.
+Proof. unfold can_trf_rules. intros. destruct X1.
+apply X in r. cD. exists r. split. assumption.
+apply ForallTI_forall. intros. eapply ForallTD_forall in r1. cD.
+exists r1. split. assumption. apply run_l. eassumption. assumption.
+apply X0 in r. cD. exists r. split. assumption.
+apply ForallTI_forall. intros. eapply ForallTD_forall in r1. cD.
+exists r1. split. assumption. apply run_r. eassumption. assumption.
+Qed.
+ +
+(* Union property for R in can_trf_rules... *)
+Lemma can_trf_rules_Un sty rr rules ps (c : sty):
+  (forall r, rr r -> can_trf_rules r rules ps c) ->
+    can_trf_rules (rUnion rr) rules ps c.
+Proof. unfold can_trf_rules. intros. destruct X0.
+pose (X r r0 c' r1). cD. exists s. split. assumption.
+apply ForallTI_forall. intros. eapply ForallTD_forall in s1. cD.
+exists s1. split. assumption. eapply rUnI ; eassumption. assumption. Qed.
+ +
+Lemma can_trf_rules_req V R R' rules : req R R' -> forall ps c,
+  @can_trf_rules V R rules ps c -> @can_trf_rules V R' rules ps c.
+Proof. unfold can_trf_rules. unfold req. unfold rsub.
+intros ss ps c fri c' rcc. cD.
+apply ss0 in rcc. apply fri in rcc. cD.
+exists rcc. split. assumption. apply ForallTI_forall. intros.
+eapply ForallTD_forall in rcc1. cD.
+exists rcc1. split. assumption. apply ss. eassumption. assumption. Qed.
+ +
+Lemma der_trf_rc_adm: forall (sty : Type) R rules,
+  (forall ps c, rules ps c -> can_trf_rules_rc R (adm rules) ps c) ->
+  forall concl, derrec rules (@emptyT sty) concl ->
+    forall concl', R concl concl' -> derrec rules (@emptyT sty) concl'.
+Proof. intros *. intro.
+eapply (derrec_all_rect (Q := (fun concl => forall concl' : sty,
+  R concl concl' -> derrec rules (emptyT (X:=sty)) concl'))).
+intros. destruct H.
+intros ps concl rpc dpss fall concl' Rcc.
+apply X in rpc. unfold can_trf_rules_rc in rpc.
+apply rpc in Rcc. cD. clear rpc X.
+(* here, weaker results by using derI or adm_derrec_trans
+  instead of adm_derrec_trans *)

+eapply adm_derrec_trans. exact Rcc0.
+apply dersrecI_forall. intros.
+eapply ForallTD_forall in Rcc1. 2: eassumption. cD.
+inversion Rcc3. subst.
+eapply ForallTD_forall in fall. 2: eassumption.
+apply fall. assumption.
+subst. eapply dersrecD_forall in dpss. exact dpss. assumption. Qed.
+ +
+Lemma der_trf_rc_derl: forall (sty : Type) R rules,
+  (forall ps c, rules ps c -> can_trf_rules_rc R (derl rules) ps c) ->
+  forall concl, derrec rules (@emptyT sty) concl ->
+    forall concl', R concl concl' -> derrec rules (@emptyT sty) concl'.
+Proof. intros sty R rules rtc. apply der_trf_rc_adm.
+intros ps c rpc. apply rtc in rpc.
+eapply can_trf_rules_rc_mono'.
+apply rsub_derl_adm. apply rpc. Qed.
+ +
+Lemma der_trf_rc: forall (sty : Type) R rules,
+  (forall ps c, rules ps c -> can_trf_rules_rc R rules ps c) ->
+  forall concl, derrec rules (@emptyT sty) concl ->
+    forall concl', R concl concl' -> derrec rules (@emptyT sty) concl'.
+Proof. intros sty R rules rtc. apply der_trf_rc_adm.
+intros ps c rpc. apply rtc in rpc.
+eapply can_trf_rules_rc_mono'.
+apply rsub_adm. apply rpc. Qed.
+ +
+Lemma der_trf_derl: forall (sty : Type) R rules,
+  (forall ps c, rules ps c -> can_trf_rules R (derl rules) ps c) ->
+  forall concl, derrec rules (@emptyT sty) concl ->
+    forall concl', R concl concl' -> derrec rules (@emptyT sty) concl'.
+Proof. intros *. intro.
+apply der_trf_rc_derl. intros. apply can_trf_rules_imp_rc.
+exact (X ps c X0). Qed.
+ +
+(* or can do the following *)
+Definition der_trf_derl' sty R rules ct :=
+  @der_trf_rc_derl sty R rules
+    (fun ps c rpc => can_trf_rules_imp_rc (ct ps c rpc)).
+ +
+Lemma can_trf_derl X rules R ps (c : X): can_trf_rules R rules ps c ->
+    can_trf_rules R (derl rules) ps c.
+Proof. unfold can_trf_rules. intros.
+apply X0 in X1. cD. exists X1. split. apply in_derl. assumption.
+assumption. Qed.
+ +
+Lemma der_trf: forall (sty : Type) R rules,
+  (forall ps c, rules ps c -> can_trf_rules R rules ps c) ->
+  forall concl, derrec rules (@emptyT sty) concl ->
+    forall concl', R concl concl' -> derrec rules (@emptyT sty) concl'.
+Proof. intros *. intro rct. apply der_trf_derl.
+intros. apply can_trf_derl. apply rct. assumption. Qed.
+ +
+Definition can_trf_rules_rtc (sty : Type) R rules (ps : list sty) (c : sty) :=
+  forall c' : sty, R c c' ->
+  (sigT (fun ps' : list sty => prod (rules ps' c')
+    (ForallT (fun p' => sigT (fun p => prod (InT p ps)
+      (clos_refl_transT_n1 R p p'))) ps'))).
+ +
+Lemma can_trf_rules_imp_rtc sty R rules ps c:
+  @can_trf_rules sty R rules ps c -> @can_trf_rules_rtc sty R rules ps c.
+Proof. unfold can_trf_rules. unfold can_trf_rules_rtc.
+intros. apply X in X0. cD. exists X0. split. assumption.
+apply ForallTI_forall. intros.
+eapply ForallTD_forall in X2. 2: eassumption. cD.
+exists X2. split. assumption.
+eapply rtn1T_trans. eassumption. apply rtn1T_refl. Qed.
+ +
+Lemma can_trf_rules_rtc_mono' sty R rulesa rulesb ps c:
+  rsub rulesa rulesb -> @can_trf_rules_rtc sty R rulesa ps c ->
+  @can_trf_rules_rtc sty R rulesb ps c.
+Proof. unfold rsub. unfold can_trf_rules_rtc. intros.
+apply X0 in X1. clear X0. cD. exists X1. split. firstorder.
+exact X2. Qed.
+ +
+Definition can_trf_rules_rtc_mono sty R rulesa rulesb r :=
+  rsubI _ _ (@can_trf_rules_rtc_mono' sty R rulesa rulesb r).
+ +
+Lemma trf_rules_rtc: forall (sty : Type) R rules (c : sty),
+  (forall ps' c', clos_refl_transT_n1 R c c' ->
+    rules ps' c' -> can_trf_rules_rtc R rules ps' c') ->
+  forall ps, rules ps c -> can_trf_rules (clos_refl_transT_n1 R) rules ps c.
+Proof. intros. unfold can_trf_rules. intro. intro rtc.
+induction rtc. exists ps. split. assumption.
+apply ForallTI_forall. intros. exists x. split. assumption.
+apply rtn1T_refl.
+cD. eapply X in rtc.
+unfold can_trf_rules_rtc in rtc. apply rtc in r. clear rtc. cD.
+eexists. split. eassumption.
+apply ForallTI_forall. intros.
+eapply ForallTD_forall in r1. 2: eassumption. cD.
+eapply ForallTD_forall in IHrtc1. 2: eassumption. cD.
+eexists. split. eassumption.
+(* now need transitivity of clos_refl_transT_n1 *)
+apply clos_rtn1_rtT in r3.
+apply clos_rtn1_rtT in IHrtc3.
+apply clos_rt_rtn1T.
+eapply rtT_trans ; eassumption. assumption. Qed.
+ +
+(* try to adapt proof of trf_rules_derl to also do _rtc 
+Lemma trf_rules_rtc_derl: forall (sty : Type) R (rules : rlsT sty), 
+  (forall ps c, rules ps c -> can_trf_rules_rtc R (derl rules) ps c) ->
+  (forall ps c, derl rules ps c -> 
+    can_trf_rules (clos_refl_transT_n1 R) (derl rules) ps c).
+NOT ACTUALLY SURE THIS IS VALID
+Check trf_rules_rtc_derl.
+*)

+ +
+Lemma trf_rules_derl: forall (sty : Type) R (rules : rlsT sty),
+  (forall ps c, rules ps c -> can_trf_rules R (derl rules) ps c) ->
+  (forall ps c, derl rules ps c -> can_trf_rules R (derl rules) ps c).
+Proof. intros *. intro rctd.
+eapply derl_all_rect.
+{ intro. unfold can_trf_rules. intros. exists [c'].
+split. apply asmI. apply ForallTI_forall. intros.
+exists p. split. apply InT_eq. inversion X0 ; subst. assumption.
+eapply InT_nilE in X1. eassumption. }
+
+{ intros *. intros rpc drsl fcd qcp.
+apply rctd in rpc. subst. clear rctd.
+unfold can_trf_rules. intros c' Rcc.
+unfold can_trf_rules in rpc. apply rpc in Rcc. cD. clear rpc.
+ +
+assert {cqss : list sty &
+  (dersl rules cqss Rcc * ForallT (fun p' : sty =>
+    {p : sty & InT p (concat pss) * R p p'}) cqss)%type}.
+ +
+{ clear Rcc0. induction Rcc1.
+exists []. simpl. split. apply dtNil. apply ForallT_nil.
+cD.
+eapply Forall2T_ex_r in fcd. 2: eassumption. destruct fcd.
+unfold can_trf_rules in c. eapply c in p1. clear c.
+destruct p1. cD.
+eexists. split. eapply dtCons ; eassumption.
+apply ForallTI_forall. simpl. intros.
+apply InT_appE in X. sD.
+eapply ForallTD_forall in p2. 2: eassumption. cD.
+eexists. split. 2: eassumption.
+eapply InT_concat ; eassumption.
+eapply ForallTD_forall in IHRcc2. 2: eassumption. assumption. }
+
+{ cD. eexists. split. 2: eassumption.
+eapply derl_trans ; eassumption. } } Qed.
+ +
+Lemma der_trf_rtc: forall (sty : Type) R rules,
+  (forall ps c, rules ps c -> can_trf_rules_rtc R rules ps c) ->
+  forall concl, derrec rules (@emptyT sty) concl ->
+    forall concl', clos_refl_transT_n1 R concl concl' ->
+    derrec rules (@emptyT sty) concl'.
+Proof. intros until 1. apply der_trf.
+intros *. apply trf_rules_rtc.
+intros until 1. apply X. Qed.
+ +
+(* how to do this - maybe need to try _rtc variant of trf_rules_derl 
+Lemma der_trf_rtc_derl: forall (sty : Type) R rules, 
+  (forall ps c, rules ps c -> can_trf_rules_rtc R (derl rules) ps c) ->
+  forall concl, derrec rules (@emptyT sty) concl -> 
+    forall concl', clos_refl_transT_n1 R concl concl' ->
+      derrec rules (@emptyT sty) concl'.
+*)

+ +
+Lemma der_trf_ht: forall (sty : Type) R rules,
+  (forall ps c, rules ps c -> can_trf_rules R rules ps c) ->
+  forall concl (D : derrec rules (@emptyT sty) concl),
+    forall concl', R concl concl' ->
+    sigT (fun D' : derrec rules (@emptyT sty) concl' =>
+      derrec_height D' <= derrec_height D).
+Proof. intros *. intros ctr.
+eapply (derrec_rect_mut_all (Q := (fun concl D => forall concl' : sty,
+  R concl concl' -> {D' : derrec rules (emptyT (X:=sty)) concl' &
+  derrec_height D' <= derrec_height D}))).
+intros c p. destruct p.
+intros ps concl rpc dpss apd concl' Rcc.
+pose (ctr ps concl rpc) as ctrr.
+unfold can_trf_rules in ctrr.
+apply ctrr in Rcc. cD. clear ctrr ctr.
+ +
+assert { Ds' : dersrec rules (emptyT (X:=sty)) Rcc &
+  dersrec_height Ds' <= dersrec_height dpss }.
+assert (forall p, InT p Rcc -> { D' : derrec rules (emptyT (X:=sty)) p &
+  derrec_height D' <= dersrec_height dpss }).
+ +
+{ intros.
+eapply ForallTD_forall in Rcc1. 2: eassumption. cD.
+eapply allPderD_in in apd. 2: eassumption. destruct apd. (* cD doesn't work *)
+apply s in Rcc3. cD. clear s.
+eexists. (* shelves a goal *)
+eapply le_dersrec_height. eassumption. eassumption. }
+
+{ clear apd concl' Rcc0 Rcc1 R rpc.
+(* this may be a useful lemma *)
+induction Rcc. eexists. Unshelve. 3: apply dlNil. simpl. apply le_0_n.
+require IHRcc. intros. apply X. apply InT_cons. assumption. cD.
+pose (X a (InT_eq a Rcc)). cD.
+exists (dlCons s IHRcc). simpl. apply Nat.max_lub ; assumption. }
+
+cD. exists (derI concl' Rcc0 X). simpl. apply le_n_S. assumption. Qed.
+ +
+(* this proof gets quite unmanageable, need to use @dersrecI_forall' instead,
+  which is a much simpler proof object 
+Goal forall X rules prems seq seqs f,
+  @dersrecI_forall X rules prems (seq :: seqs) f =
+  @dlCons X rules prems seq seqs (f seq (InT_eq seq seqs))
+    (@dersrecI_forall X rules prems seqs (fun c i => f c (InT_cons seq i))).
+Proof. intros.  
+unfold dersrecI_forall.  unfold dersrec_forall.
+unfold iffT_D2.  unfold prod_rect.  unfold iffT_trans.
+(etc, can do lots of unfolds)
+*)

+ +
+Lemma dlCons_inj: forall X rules prems seq seqs d ds d' ds',
+  @dlCons X rules prems seq seqs d ds = dlCons d' ds' ->
+  prod (d = d') (ds = ds').
+(* shorter proof follows 
+Proof. intros.  injection H. intros. inversion_sigma. 
+unfold eq_rect in H3.  unfold eq_rect in H4. 
+dependent destruction H2.  dependent destruction H1.
+split ; assumption. Defined.
+*)

+Proof. intros. dependent destruction H. tauto. Defined.
+ +
+(* formerly managed to prove these
+Lemma dersrecI_forall_alt_cons: forall X rules prems seq seqs f,
+  @dersrecI_forall X rules prems (seq :: seqs) f =
+  @dlCons X rules prems seq seqs (f seq (InT_eq seq seqs))
+    (@dersrecI_forall X rules prems seqs (fun c i => f c (InT_cons seq i))).
+
+Lemma dersrecI_forall_alt_nil: forall X rules prems f,
+  @dersrecI_forall X rules prems  f = @dlNil X rules prems.
+
+Lemma dlc_drsf: forall X rules prems seq seqs d ds f,
+  @dlCons X rules prems seq seqs d ds = 
+    @dersrecI_forall X rules prems (seq :: seqs) f -> 
+  prod (d = f seq (InT_eq seq seqs)) 
+  (ds = @dersrecI_forall X rules prems seqs (fun c i => f c (InT_cons seq i))).
+*)

+ +
+Lemma existT_inj: forall A P (x : A) px px',
+  existT P x px = existT P x px' -> (px = px').
+Proof. intros. dependent destruction H. tauto. Defined.
+ +
+Lemma existT_inj': forall A P (x x' : A) px px',
+  existT P x px = existT P x' px' -> (x = x').
+Proof. intros. dependent destruction H. tauto. Defined.
+ +
+(* Print Assumptions existT_inj. 
+Fetching opaque proofs from disk for Coq.Logic.EqdepFacts
+Axioms:
+Eqdep.Eq_rect_eq.eq_rect_eq : forall (U : Type) (p : U) 
+                                (Q : U -> Type) (x : Q p) 
+                                (h : p = p), x = eq_rect p Q x p h
+JMeq_eq : forall (A : Type) (x y : A), x ~= y -> x = y
+*)

+ +
+(* soundness proofs *)
+ +
+(* according to some semantics, if each rule preserves validity
+  then a derivation preserves validity *)

+(* note - proof doesn't work using derl instead of dercl *)
+Lemma dercl_soundness W rules valid
+  (rules_sound : forall ps c, rules ps c -> ForallT valid ps -> valid c) :
+  forall ps (c : W), dercl rules ps c -> ForallT valid ps -> valid c.
+Proof.
+apply (@dercl_all_rect _ _ (fun ps c => ForallT valid ps -> valid c)).
+- intros p fvps. exact (ForallT_singleD fvps).
+- intros * rpsc dcsl fvv qseq fvqs. subst.
+eapply rules_sound. exact rpsc.
+clear rpsc dcsl. (* otherwise spoils induction *)
+induction fvv. apply ForallT_nil.
+simpl in fvqs. apply ForallT_appendD in fvqs. destruct fvqs.
+exact (ForallT_cons y (r f) (IHfvv f0)).
+Qed.
+ +
+Lemma derrec_soundness W rules prems valid
+  (rules_sound : forall ps (c : W), rules ps c -> ForallT valid ps -> valid c) :
+  (forall p, prems p -> valid p) -> forall c, derrec rules prems c -> valid c.
+Proof. intro pv. apply (derrec_all_rect pv).
+intros * rps drs. exact (rules_sound ps concl rps). Qed.
+ +
+Unset Universe Polymorphism.
+ +
+(* useful predicates for proving admissibility *)
+(* extend the idea of admissibility to relations *)
+Inductive radm X rules p c : Type :=
+  | radmI : (derrec rules (@emptyT X) p -> derrec rules (@emptyT X) c) ->
+    radm X rules p c.
+ +
+Definition radmD X rules p c (r : @radm X rules p c) :=
+  match r with | radmI d => d end.
+ +
+(* admissibility for a relation *)
+Inductive rel_adm X rules R : Type :=
+  | rel_admI : (forall p c, R p c -> @radm X rules p c) -> rel_adm X rules R.
+ +
+Definition rel_admD X rules R (r : @rel_adm X rules R) :=
+  match r with | rel_admI _ r0 => r0 end.
+ +
+(* similar to rel_adm, but useful for gen_step_lemT *)
+Definition can_rel sty fty rules (R : fty -> sty -> sty -> Type)
+  (fml : fty) (seq : sty) :=
+  forall seq', R fml seq seq' -> derrec rules emptyT seq'.
+ +
+Lemma rel_adm_rtc X rules R :
+  @rel_adm X rules R -> rel_adm rules (clos_refl_transT R).
+Proof. repeat split. destruct X0.
+induction X1. exact (radmD (r x y r0)). tauto. tauto. Qed.
+ +
+(* lemma relating rel_adm to can_rel *)
+Lemma crd_ra sty fty rules (R : fty -> sty -> sty -> Type) fml:
+  iffT (rel_adm rules (R fml))
+  (forall seq, derrec rules emptyT seq -> can_rel rules R fml seq).
+Proof. split.
+- intros ra seq ds seq' rf.
+inversion ra. specialize (X seq seq' rf).
+destruct X. exact (d ds).
+- intro dc. repeat split. intro dp.
+exact (dc p dp c X). Qed.
+ +
+
+
+ +
+ + + diff --git a/General.rtcT.html b/General.rtcT.html new file mode 100644 index 0000000..082c1b5 --- /dev/null +++ b/General.rtcT.html @@ -0,0 +1,154 @@ + + + + + + + + + + + + + +
+
+

General.rtcT

+ +
+ +
+(* Reflexive_Transitive_Closure stuff, using Type rather than Prop *)
+ +
+Set Implicit Arguments.
+Require Import List.
+Import ListNotations.
+ +
+Require Import gen genT.
+ +
+(* compare 
+  https://coq.inria.fr/stdlib/Coq.Relations.Relation_Definitions.html
+  https://coq.inria.fr/stdlib/Coq.Relations.Relation_Operators.html
+  https://coq.inria.fr/stdlib/Coq.Relations.Operators_Properties.html
+  Require Import Coq.Relations.Relation_Definitions.
+  Require Import Coq.Relations.Relation_Operators.
+  Require Import Coq.Relations.Operators_Properties.  
+  *)

+(* this in genT.v in ../lnt/tense-logic-in-Coq 
+Definition relationT (A : Type) := A -> A -> Type.
+*)

+ +
+Definition transitiveT W (R : relationT W) :=
+  forall (x y z : W), R x y -> R y z -> R x z.
+ +
+(* see https://coq.inria.fr/stdlib/Coq.Relations.Relation_Operators.html *)
+Section Reflexive_ClosureT.
+  Variable A : Type.
+  Variable R : relationT A.
+ +
+Inductive clos_reflT (x: A) : A -> Type :=
+  | rT_step (y:A) : R x y -> clos_reflT x y
+  | rT_refl : clos_reflT x x.
+ +
+End Reflexive_ClosureT.
+ +
+Section Reflexive_Transitive_ClosureT.
+  Variable A : Type.
+  Variable R : relationT A.
+ +
+Inductive clos_refl_transT (x:A) : A -> Type :=
+  | rtT_step (y:A) : R x y -> clos_refl_transT x y
+  | rtT_refl : clos_refl_transT x x
+  | rtT_trans (y z:A) :
+        clos_refl_transT x y -> clos_refl_transT y z -> clos_refl_transT x z.
+ +
+(* Alternative definition by transitive extension on the left/right *)
+ +
+Inductive clos_refl_transT_1n (x: A) : A -> Type :=
+  | rt1nT_refl : clos_refl_transT_1n x x
+  | rt1nT_trans (y z:A) :
+       R x y -> clos_refl_transT_1n y z -> clos_refl_transT_1n x z.
+ +
+Inductive clos_refl_transT_n1 (x: A) : A -> Type :=
+  | rtn1T_refl : clos_refl_transT_n1 x x
+  | rtn1T_trans (y z:A) :
+      R y z -> clos_refl_transT_n1 x y -> clos_refl_transT_n1 x z.
+ +
+End Reflexive_Transitive_ClosureT.
+ +
+(* equivalences between above, need to reprove for ...T *)
+Lemma clos_rt1n_rtT : forall A R (x y : A),
+  clos_refl_transT_1n R x y -> clos_refl_transT R x y.
+Proof. intros. induction X. apply rtT_refl.
+eapply rtT_trans. apply rtT_step. eassumption. eassumption. Qed.
+ +
+Lemma clos_rt_rt1nT : forall A R (x y : A),
+  clos_refl_transT R x y -> clos_refl_transT_1n R x y.
+Proof. intros. induction X.
+eapply rt1nT_trans. eassumption. apply rt1nT_refl.
+apply rt1nT_refl.
+clear X1 X2. induction IHX1. assumption.
+apply IHIHX1 in IHX2. eapply rt1nT_trans ; eassumption. Qed.
+ +
+Lemma clos_rtn1_rtT : forall A R (x y : A),
+  clos_refl_transT_n1 R x y -> clos_refl_transT R x y.
+Proof. intros. induction X. apply rtT_refl.
+eapply rtT_trans. eassumption. apply rtT_step. eassumption. Qed.
+ +
+Lemma clos_rt_rtn1T : forall A R (x y : A),
+  clos_refl_transT R x y -> clos_refl_transT_n1 R x y.
+Proof. intros. induction X.
+eapply rtn1T_trans. eassumption. apply rtn1T_refl.
+apply rtn1T_refl.
+clear X1 X2. induction IHX2. assumption.
+eapply rtn1T_trans ; eassumption. Qed.
+ +
+(*
+Lemma clos_rt_rt1n_iffT : forall A R (x y : A),
+  clos_refl_transT R x y <-> clos_refl_transT_1n R x y.
+
+Lemma clos_rt_rtn1_iffT : forall A R (x y : A),
+  clos_refl_transT R x y <-> clos_refl_transT_n1 R x y.
+*)

+ +
+
+
+ +
+ + + diff --git a/General.swappedT.html b/General.swappedT.html new file mode 100644 index 0000000..8c2672a --- /dev/null +++ b/General.swappedT.html @@ -0,0 +1,437 @@ + + + + + + + + + + + + + +
+
+

General.swappedT

+ +
+ +
+(* Add LoadPath "../tense-lns". *)
+ +
+Require Import List.
+Require Import existsT.
+Require Import gen_tacs.
+Require Import gen.
+Require Import List_lemmasT.
+ +
+Set Implicit Arguments.
+Import ListNotations.
+ +
+(* Contains definitions and lemmas for swapped swapped_spec and swapped_gen, all used for contraction. *)
+ +
+Inductive swapped T: list T -> list T -> Type :=
+| swapped_I : forall (X Y A B C D : list T),
+    X = (A ++ B ++ C ++ D) -> Y = (A ++ C ++ B ++ D) -> swapped X Y.
+ +
+Lemma swapped_I': forall T (A B C D : list T),
+  swapped (A ++ B ++ C ++ D) (A ++ C ++ B ++ D).
+Proof. intros. eapply swapped_I ; reflexivity. Qed.
+ +
+Lemma swapped_same: forall T X, swapped X (X : list T).
+Proof. intros. apply (swapped_I [] [] [] X) ; simpl ; reflexivity. Qed.
+ +
+Lemma swapped_L: forall T X Y Z,
+  swapped X (Y : list T) -> swapped (Z ++ X) (Z ++ Y).
+Proof. intros *; intros X0. inversion X0. subst.
+  rewrite !(app_assoc Z). apply swapped_I'. Qed.
+ +
+Lemma swapped_R: forall T X Y Z,
+  swapped X (Y : list T) -> swapped (X ++ Z) (Y ++ Z).
+Proof. intros *; intros X0. destruct X0. subst. rewrite <- !app_assoc. apply swapped_I'. Qed.
+ +
+Lemma swapped_cons: forall T (x : T) Y Z,
+  swapped Y Z -> swapped (x :: Y) (x :: Z).
+Proof.
+  intros *; intros H. destruct H.
+  subst. repeat rewrite app_comm_cons.
+  apply swapped_I'.
+Qed.
+ +
+Definition swapped_single T (x : T) := swapped_cons x (swapped_same []).
+ +
+Lemma swapped_nilLE T Y: @swapped T [] Y -> Y = [].
+Proof. intro sw. inversion sw. subst.
+repeat (list_eq_ncT ; cD ; subst) ;
+simpl ; rewrite ?app_nil_r ; try reflexivity. Qed.
+ +
+Lemma swapped_nilRE T Y: @swapped T Y [] -> Y = [].
+Proof. intro sw. inversion sw. subst.
+repeat (list_eq_ncT ; cD ; subst) ;
+simpl ; rewrite ?app_nil_r ; try reflexivity. Qed.
+ +
+Lemma swapped_singleLE T (x : T) Y: swapped [x] Y -> Y = [x].
+Proof. intro sw. inversion sw. subst.
+acacD'T2 ; subst ; repeat (list_eq_ncT ; cD ; subst) ;
+simpl ; rewrite ?app_nil_r ; try reflexivity. Qed.
+ +
+Lemma swapped_singleRE T (x : T) Y: swapped Y [x] -> Y = [x].
+Proof. intro sw. inversion sw. subst.
+acacD'T2 ; subst ; repeat (list_eq_ncT ; cD ; subst) ;
+simpl ; rewrite ?app_nil_r ; try reflexivity. Qed.
+ +
+Lemma swapped_simple: forall T U V X Y,
+  U = X ++ Y -> V = Y ++ X -> swapped U (V : list T).
+Proof. intros. subst.
+  apply (swapped_I [] X Y []) ; simpl ; rewrite app_nil_r ; reflexivity. Qed.
+ +
+Lemma swapped_simple': forall T X Y, swapped (X ++ Y : list T) (Y ++ X).
+Proof. intros. eapply swapped_simple ; reflexivity. Qed.
+ +
+Lemma swapped_simpleL: forall T X Y Z,
+  Y = Z -> swapped (X ++ Y) (Z ++ X : list T).
+Proof. intros. subst. apply swapped_simple'. Qed.
+ +
+Lemma swapped_simpleR: forall T X Y Z,
+  Y = Z -> swapped (Y ++ X) (X ++ Z : list T).
+Proof. intros. subst. apply swapped_simple'. Qed.
+ +
+Lemma swapped_comm : forall {T} (A B : list T),
+    swapped A B ->
+    swapped B A.
+Proof.
+  intros T A B H.
+  inversion H. subst.
+  eapply swapped_I'.
+Qed.
+ +
+Definition single X (a : X) := [a].
+ +
+Lemma cons_app_single X (a : X) xs : a :: xs = single a ++ xs.
+Proof. unfold single. simpl. reflexivity. Qed.
+ +
+Lemma single_eq X a : [a : X] = single a.
+Proof. unfold single. reflexivity. Qed.
+ +
+(* note some of the complexity of swap_tac involving cons
+  may be avoided by rewriting with cons_app_single and single_eq *)

+ +
+Lemma swapped_Rc2 T A H B C:
+  swapped C (H ++ [A : T]) -> swapped (C ++ B) (H ++ A :: B).
+Proof. intros sw. eapply swapped_R in sw. revert sw.
+rewrite <- app_assoc. simpl. intro. eassumption. Qed.
+ +
+Lemma swapped_Rc1 T A H B C:
+  swapped (H ++ [A : T]) C -> swapped (H ++ A :: B) (C ++ B).
+Proof. intros sw. eapply swapped_R in sw. revert sw.
+rewrite <- app_assoc. simpl. intro. eassumption. Qed.
+ +
+Lemma swapped_ca1 T A H: swapped (A :: H) (H ++ [A : T]).
+Proof. pose (swapped_simple' [A] H). simpl in s. exact s. Qed.
+ +
+Lemma swapped_ca2 T A H: swapped (H ++ [A : T]) (A :: H).
+Proof. pose (swapped_simple' H [A]). simpl in s. exact s. Qed.
+ +
+Lemma swapped_map_ex T U (f : T -> U) xs ys:
+  swapped (map f xs) ys -> sigT2 (swapped xs) (fun zs => ys = map f zs).
+Proof. intro sw. inversion sw. subst. clear sw.
+repeat (match goal with | [ H : _ |- _ ] => eapply map_app_ex in H ; cD end).
+subst. eexists. apply swapped_I'. rewrite !map_app. reflexivity. Qed.
+ +
+Lemma swapped_map T U (f : T -> U) xs ys:
+  swapped xs ys -> swapped (map f xs) (map f ys).
+Proof. intro sw. inversion sw. subst. clear sw.
+rewrite !map_app. apply swapped_I'. Qed.
+ +
+(* Sequences of swaps of length n+1. *)
+Inductive swapped_spec {T} : nat -> list T -> list T -> Type :=
+  swapped_spec_I X Y : swapped X Y -> swapped_spec 0 X Y
+| swapped_spec_step n A B C :
+    swapped_spec n A B -> swapped B C -> swapped_spec (S n) A C.
+ +
+Lemma swapped_spec_refl : forall {T} n (A : list T),
+    swapped_spec n A A.
+Proof.
+  induction n; intros. econstructor. apply swapped_same.
+  econstructor. apply IHn.
+  apply swapped_same.
+Qed.
+ +
+Lemma swapped_app_L : forall {T} n (l A B : list T),
+    swapped_spec n A B ->
+    swapped_spec n (l ++ A) (l ++ B).
+Proof.
+  induction n; intros *; intros Hswap.
+  constructor. apply swapped_L. inversion Hswap. auto.
+  inversion Hswap as [ | ? ? ? ? X X0]. subst.
+  econstructor. eapply IHn. exact X.
+  apply swapped_L. assumption.
+Qed.
+ +
+Lemma swapped_spec_trans : forall {T} n1 n2 (l1 l2 l3 : list T),
+    swapped_spec n1 l1 l2 ->
+    swapped_spec n2 l2 l3 ->
+    existsT2 m, swapped_spec m l1 l3.
+Proof.
+  induction n2; intros *; intros H1 H2.
+  inversion H2. subst. exists (S n1).
+  econstructor. apply H1. assumption.
+  inversion H2 as [ | ? ? ? ? X X0]. subst.
+  eapply IHn2 in H1. destruct H1 as [m H1].
+  exists (S m). econstructor.
+  apply H1. apply X0. apply X.
+Qed.
+ +
+Lemma swapped_spec_trans_exact : forall {T} n1 n2 (l1 l2 l3 : list T),
+    swapped_spec n1 l1 l2 ->
+    swapped_spec n2 l2 l3 ->
+    swapped_spec (S (n1 + n2)) l1 l3.
+Proof.
+  induction n2; intros *; intros H1 H2.
+  inversion H2 as [? ? X | ]. subst. rewrite PeanoNat.Nat.add_0_r.
+  econstructor. apply H1. apply X.
+  inversion H2 as [| ? ? ? ? X X0]. subst.
+  eapply IHn2 in H1. simpl. econstructor.
+  rewrite <- PeanoNat.Nat.add_succ_comm.
+  apply H1. apply X0. assumption.
+Qed.
+ +
+Lemma swapped_spec_comm : forall {T} n (A B : list T),
+    swapped_spec n A B ->
+    swapped_spec n B A.
+Proof.
+  induction n; intros *; intros H.
+  constructor. inversion H as [? ? X | ]. subst.
+  eapply swapped_comm. assumption.
+  inversion H as [ | ? ? ? ? X X0]. subst.
+  eapply swapped_comm in X0.
+  eapply swapped_spec_I in X0.
+  apply IHn in X.
+  apply (@swapped_spec_trans_exact T _ _ _ _ _ X0 X).
+Qed.
+ +
+Lemma swapped_spec_conv : forall {T} n m (A B : list T),
+  n = m ->
+  swapped_spec n A B ->
+  swapped_spec m A B.
+Proof. intros. subst. auto. Qed.
+ +
+Lemma swapped_app_mid_L : forall {T} n (A B C D E : list T),
+    swapped_spec n (A ++ B ++ C ++ D) E ->
+    swapped_spec (S n) (A ++ C ++ B ++ D) E.
+Proof.
+  intros *; intros Hswap.
+  assert (S n = S (0 + n)) as Hass.
+  reflexivity.
+  eapply swapped_spec_conv. symmetry. apply Hass.
+  eapply swapped_spec_trans_exact.
+  constructor. apply swapped_I'.
+  apply Hswap.
+Qed.
+ +
+Lemma swapped_app_mid_R : forall {T} n (A B C D E : list T),
+    swapped_spec n E (A ++ B ++ C ++ D) ->
+    swapped_spec (S n) E (A ++ C ++ B ++ D).
+Proof.
+  intros *; intros H.
+  eapply swapped_spec_comm in H.
+  eapply swapped_spec_comm.
+  eapply swapped_app_mid_L.
+  apply H.
+Qed.
+ +
+Lemma swapped_spec_front_mid : forall {T} n (A B C D : list T),
+    swapped_spec n B (C ++ D) ->
+    existsT2 m, swapped_spec m (A ++ B) (C ++ A ++ D).
+Proof.
+  intros T n A B C D Hswap.
+  eapply swapped_app_L in Hswap.
+  eapply swapped_spec_trans. exact Hswap.
+  rewrite <- app_nil_l.
+  eapply swapped_app_mid_R.
+  apply swapped_spec_refl.
+  Unshelve. apply 0.
+Qed.
+ +
+Lemma swapped__n_mid : forall {T} m (l Gam1 Gam2 Gam1' Gam2' : list T),
+    swapped_spec m (Gam1 ++ Gam2) (Gam1' ++ Gam2') ->
+    existsT2 n, swapped_spec n (Gam1 ++ l ++ Gam2) (Gam1' ++ l ++ Gam2').
+Proof.
+  intros *.
+  intros H. eapply swapped_app_L in H.
+  rewrite <- app_nil_l in H.
+  eexists.
+  replace (Gam1 ++ l ++ Gam2) with (nil ++ Gam1 ++ l ++ Gam2).
+  replace (Gam1' ++ l ++ Gam2') with (nil ++ Gam1' ++ l ++ Gam2').
+  eapply swapped_app_mid_R.
+  eapply swapped_app_mid_L.
+  eapply H. all : reflexivity.
+Qed.
+ +
+(* Sequences of swaps, length implicit. *)
+Inductive swapped_gen {T} Gam Delt :=
+  swapped_gen_I : (existsT2 n, @swapped_spec T n Gam Delt) -> swapped_gen Gam Delt.
+ +
+Lemma swapped_gen_front_mid : forall {T} (A B C D : list T),
+    swapped_gen B (C ++ D) ->
+    swapped_gen (A ++ B) (C ++ A ++ D).
+Proof.
+  intros T A B C D Hswap. inversion Hswap as [Hs].
+  destruct Hs as [n Hs].
+  constructor.
+  eapply swapped_spec_front_mid. exact Hs.
+Qed.
+ +
+Lemma swapped_spec_opp : forall {T} n (A B C : list T),
+    swapped_spec n B C ->
+    swapped A B ->
+    swapped_spec (S n) A C.
+Proof.
+  intros *; intros H1 H2.
+  eapply swapped_spec_I in H2.
+  eapply swapped_spec_trans_exact in H1.
+  2 : eapply H2. auto.
+Qed.
+ +
+Lemma swapped__gen : forall {T} (A B : list T),
+  swapped A B -> swapped_gen A B.
+Proof.
+  intros T A B H. constructor.
+  exists 0. constructor. exact H.
+Qed.
+ +
+Lemma swapped_gen_app_L : forall {T} (l A B : list T),
+    swapped_gen A B ->
+    swapped_gen (l ++ A) (l ++ B).
+Proof.
+  intros T l A B H. inversion H as [H2].
+  destruct H2 as [n H2]. constructor.
+  eapply swapped_app_L in H2. exists n. exact H2.
+Qed.
+ +
+Lemma swapped_gen_refl : forall {T} (A : list T),
+    swapped_gen A A.
+Proof.
+  intros T A. constructor.
+  exists 0. apply swapped_spec_refl.
+Qed.
+ +
+(* tactics to identify swapped lists, where one of swap is single list *)
+ +
+Ltac show_swapped_1 :=
+  list_assoc_r' ;
+  try (eapply arg_cong_imp ; [> list_assoc_l' ; reflexivity | ] ;
+    apply swapped_simpleL ; list_eq_assoc) ;
+  try (eapply arg1_cong_imp ; [> list_assoc_l' ; reflexivity | ] ;
+    apply swapped_simpleR ; list_eq_assoc).
+ +
+Ltac show_swapped_1_ns :=
+  list_assoc_r ; (* not the ssreflext version *)
+  try (eapply arg_cong_imp ; [> list_assoc_l' ; reflexivity | ] ;
+    apply swapped_simpleL ; list_eq_assoc) ;
+  try (eapply arg1_cong_imp ; [> list_assoc_l' ; reflexivity | ] ;
+    apply swapped_simpleR ; list_eq_assoc).
+ +
+(* this should work wherever swap_tac does, but trying to use it in place of
+  swap_tac produces occasional failures - why?? - to investigate *)

+Ltac swap_tac_Rc :=
+  list_assoc_r ; try (apply swapped_same) ;
+    repeat (apply swapped_L || apply swapped_cons) ;
+    list_assoc_l ;
+    repeat (apply swapped_R || apply swapped_Rc1 || apply swapped_Rc2) ;
+    (show_swapped_1 || apply swapped_ca2 || apply swapped_ca1).
+ +
+Ltac swap_tac :=
+  list_assoc_r ; try (apply swapped_same) ;
+    repeat (apply swapped_L || apply swapped_cons) ;
+    list_assoc_l ; repeat (apply swapped_R) ; show_swapped_1.
+ +
+Ltac swap_tac_ns :=
+  list_assoc_r ; try (apply swapped_same) ;
+    repeat (apply swapped_L || apply swapped_cons) ;
+    list_assoc_l ; repeat (apply swapped_R) ; show_swapped_1_ns.
+ +
+Goal forall T A B C D, swapped (A ++ B ++ C ++ D : list T) (D ++ A ++ B ++ C).
+Proof. intros. show_swapped_1. Qed.
+ +
+Goal forall T A B C D, swapped (D ++ A ++ B ++ C) (A ++ B ++ C ++ D : list T).
+Proof. intros. show_swapped_1. Qed.
+ +
+
+
+ +
+ + + diff --git a/General.univ_gen_ext.html b/General.univ_gen_ext.html new file mode 100644 index 0000000..e5df2e3 --- /dev/null +++ b/General.univ_gen_ext.html @@ -0,0 +1,624 @@ + + + + + + + + + + + + + +
+
+

General.univ_gen_ext

+ +
+Require Export List.
+Export ListNotations.
+Set Implicit Arguments.
+ +
+From Coq Require Import ssreflect.
+ +
+Require Import gen.
+Require Import genT.
+Require Import gen_tacs.
+Require Import gen_seq.
+Require Import List_lemmasT.
+Require Import FunctionalExtensionality.
+Require Import Lia.
+ +
+(* The following definition is a generalization of the gen_ext property.
+   As gen_ext, univ_gen_ext gives a precise definition of embedding between
+   lists: l1 is embedded in l2 if all the elements in l1 appear in l2 in the
+   same order as in l1. Some elements might be added in l2, under the condition
+   that these elements satisfy a certain given property P.
+
+   Effectively, univ_gen_ext allows to restrict the weakening of gen_ext_extra to
+   elements of a type A satisfying some property P. *)

+ +
+Inductive univ_gen_ext W (P : W -> Type) : relationT (list W) :=
+  | univ_gen_ext_nil : univ_gen_ext P [] []
+  | univ_gen_ext_cons : forall x l le, univ_gen_ext P l le -> univ_gen_ext P (x :: l) (x :: le)
+  | univ_gen_ext_extra : forall x l le, P x -> univ_gen_ext P l le -> univ_gen_ext P l (x :: le)
+  .
+ +
+(* We can prove some general properties about univ_gen_ext. *)
+ +
+(* univ_gen_ext is a reflexive relation. *)
+ +
+Lemma univ_gen_ext_refl: forall A (l : list A) P, univ_gen_ext P l l.
+Proof.
+induction l.
+- apply univ_gen_ext_nil.
+- intro. apply univ_gen_ext_cons. apply IHl.
+Qed.
+ +
+(* It is also transitive. *)
+ +
+Lemma univ_gen_ext_trans: forall A P (ys zs : list A),
+  univ_gen_ext P ys zs ->
+  forall xs, univ_gen_ext P xs ys -> univ_gen_ext P xs zs.
+Proof. intros until 1. induction X. tauto.
+intros. inversion X0. subst. apply univ_gen_ext_cons. firstorder.
+subst. apply univ_gen_ext_extra. firstorder. apply IHX. assumption.
+intros. firstorder. firstorder. apply univ_gen_ext_extra. firstorder. apply IHX.
+assumption.
+Qed.
+ +
+(* The empty list can be embedded in any other list xs as long as the
+   elements of that list are all satisfying P. *)

+ +
+Lemma all_P_univ_gen_ext_nil: forall A P (xs : list A),
+              (forall x, InT x xs -> P x) -> (univ_gen_ext P [] xs).
+Proof.
+induction xs.
+- intros. apply univ_gen_ext_nil.
+- intros. apply univ_gen_ext_extra. apply X. apply InT_eq'. reflexivity.
+  apply IHxs. intros. apply X. apply InT_cons. assumption.
+Qed.
+ +
+(* Reciprocally, if the empty list is embedded in another list then
+   we know that all the elements of that list are satisfying P. *)

+ +
+Lemma univ_gen_ext_nil_all_P: forall A P (xs : list A),
+              (univ_gen_ext P [] xs) -> (forall x, InT x xs -> P x).
+Proof.
+induction xs.
+- intros. inversion X0.
+- intros. remember (a :: xs) as l0. remember [] as l1. destruct X.
+  * inversion X0.
+  * inversion Heql1.
+  * inversion Heql0. subst. pose (IHxs X). inversion X0.
+    + subst. assumption.
+    + apply p0. assumption.
+Qed.
+ +
+(* The next lemmas state that if a list xs is embedded in a list
+   ys, then xs is also embedded in the list ys appended (on the
+   right or left of it) with a list zs of which all elements are
+   satsfying the property P. *)

+ +
+Lemma univ_gen_ext_appL: forall A P (xs ys zs : list A),
+  univ_gen_ext P xs ys ->
+  (forall z, InT z zs -> P z) ->
+  univ_gen_ext P xs (zs ++ ys).
+Proof.
+induction zs. tauto.
+intros. simpl. apply univ_gen_ext_extra. apply X0. apply InT_eq.
+apply IHzs. assumption. intros. apply X0. apply InT_cons. assumption.
+Qed.
+ +
+Lemma univ_gen_ext_appR: forall A P (xs ys zs : list A),
+  univ_gen_ext P xs ys ->
+  (forall z, InT z zs -> P z) ->
+  univ_gen_ext P xs (ys ++ zs).
+Proof.
+intros. induction X.
+- induction zs.
+  * apply univ_gen_ext_nil.
+  * apply univ_gen_ext_extra. apply X0. apply InT_eq. apply IHzs.
+    intros. apply X0. apply InT_cons. assumption.
+- simpl. apply univ_gen_ext_cons. assumption.
+- simpl. apply univ_gen_ext_extra. assumption. assumption.
+Qed.
+ +
+(* The lemma univ_gen_ext_lem states that if a list x::Z is embedded in
+   a list Y, then x must be appearing in Y, i.e. Y = Y1++x::Y2, and Y2 is
+   is such that Z is embedded in Y2. Note that Y1 is here as it could well
+   be that some elements were added via univ_gen_ext_extra before even
+   treating x. *)

+ +
+Lemma univ_gen_ext_lem: forall A (x : A) P Z Y,
+  univ_gen_ext P (x :: Z) Y -> sigT (fun Y1 => sigT (fun Y2 =>
+    prod (Y = Y1 ++ x :: Y2) (prod (univ_gen_ext P Z Y2)
+      (forall y, InT y Y1 -> P y)))).
+Proof.
+intros A x P Z. induction Y.
+intro. inversion X. intro. inversion X ; subst.
+exists []. exists Y. simpl. split. tauto. split. tauto. intros.
+inversion X1.
+apply IHY in X1. cD. subst.
+exists (a :: X1). exists X2. simpl. split.
+auto. split. assumption. intros. remember (a :: X1) as l. destruct X3.
+- subst. inversion Heql. assumption.
+- apply X5. inversion Heql. subst. assumption.
+Qed.
+ +
+(* The next two lemmas deal with the interaction between univ_gen_ext
+   and append. In essence, they say that if the embedded (resp. embedding)
+   list is of the shape X1++X2, then the embedding list (resp. embedded)
+   is of the shape W1++W2 where W1 embedds (resp. is embedded in) X1 and
+   W2 embedds (resp. is embedded in) X1. *)

+ +
+Lemma univ_gen_ext_splitL: forall A P (Z2 Z1 Y : list A),
+  univ_gen_ext P (Z1 ++ Z2) Y -> sigT (fun Y1 => sigT (fun Y2 =>
+    prod (Y = Y1 ++ Y2) (prod (univ_gen_ext P Z1 Y1) (univ_gen_ext P Z2 Y2)))).
+Proof.
+intros A P Z2. induction Z1 ; simpl.
+- exists []. exists Y. simpl. split. trivial.
+split. apply univ_gen_ext_nil. trivial.
+- intro. intro. apply univ_gen_ext_lem in X. cD. subst.
+apply IHZ1 in X2. cD. subst.
+exists (X ++ a :: X2). exists X1.
+split. rewrite app_comm_cons. rewrite app_assoc. trivial.
+split. apply univ_gen_ext_appL. apply univ_gen_ext_cons. assumption.
+2: assumption. assumption.
+Qed.
+ +
+Lemma univ_gen_ext_splitR: forall A P (Z2 Z1 Y : list A),
+  univ_gen_ext P Y (Z1 ++ Z2) -> sigT (fun Y1 => sigT (fun Y2 =>
+    prod (Y = Y1 ++ Y2) (prod (univ_gen_ext P Y1 Z1) (univ_gen_ext P Y2 Z2)))).
+Proof.
+intros V Z2. induction Z1 ; simpl.
+- exists []. exists Y. simpl. split. trivial.
+  split. apply univ_gen_ext_nil. trivial.
+- intro. intro. inversion X ; subst.
+apply IHZ1 in X0. cD. subst.
+exists (a :: X0). exists X1. simpl. split. trivial.
+split. apply univ_gen_ext_cons. assumption. assumption.
+apply IHZ1 in X1. cD. subst.
+exists X1. exists X2. split. trivial. split. apply univ_gen_ext_extra.
+assumption. assumption. assumption.
+Qed.
+ +
+(* univ_gen_ext_combine claims that if Y1 is embedded in Z1 and Y2 is embedded
+   in Z2, then we can combine the embedded lists in the shape of Y1++Y2 and combine
+   the embedding lists in Z1++Z2 to preserve the relation of embedding between the
+   newly created lists.*)

+ +
+Lemma univ_gen_ext_combine: forall A P (Z2 Z1 Y2 Y1 : list A),
+    univ_gen_ext P Y1 Z1 -> univ_gen_ext P Y2 Z2 -> univ_gen_ext P (Y1 ++ Y2) (Z1 ++ Z2).
+Proof.
+intros A P Z2 Z1 Y2 Y1 gen1 gen2. induction gen1.
+- repeat rewrite app_nil_l. assumption.
+- simpl. apply univ_gen_ext_cons. assumption.
+- simpl. apply univ_gen_ext_extra. assumption. assumption.
+Qed.
+ +
+(* The next lemma states that if a::Y is embedded in a::Z, then we know
+   for sure that Y is embedded in Z. Note that this is not direct as the
+   a in the embedding list could have been added via univ_gen_ext_extra.
+   Effectively, this lemma allows one to remove the identical heads of two
+   lists univ_gen_ext and preserve that relation. *)

+ +
+Lemma univ_gen_ext_same_hd: forall A P (Y Z : list A) (a : A),
+    univ_gen_ext P (a::Y) (a::Z) -> univ_gen_ext P Y Z.
+Proof.
+intros A P Y Z a gen. inversion gen.
+- assumption.
+- subst. assert (H: univ_gen_ext P Y (a :: Y)).
+  apply univ_gen_ext_extra. assumption. apply univ_gen_ext_refl.
+  apply univ_gen_ext_trans with (ys:=(a :: Y)). assumption. assumption.
+Qed.
+ +
+(* The lemma univ_gen_ext_elem_deep considers a list l1 embedded in a
+   list l2 in which an element a appears deeply. Essentially, the lemma
+   makes a case distinction about a: either it has been added by univ_gen_ext_extra
+   (this is the first case of the sum) or it was added by univ_gen_ext_cons
+   in which case it has to appear somewhere in l1. *)

+ +
+Lemma univ_gen_ext_elem_deep {A : Type} : forall P (l1 l2 l3 l4: list A) a,
+          univ_gen_ext P l1 l2 ->
+          (l2 = l3 ++ a :: l4) ->
+            ((univ_gen_ext P l1 (l3 ++ l4) * P a) +
+            sigT (fun l5 => sigT (fun l6 =>
+              (prod (l1 = l5 ++ a :: l6) (prod (univ_gen_ext P l5 l3) (univ_gen_ext P l6 l4)))))).
+Proof.
+intros. subst. rewrite cons_single in X. apply univ_gen_ext_splitR in X.
+destruct X. destruct s. repeat destruct p. subst.
+apply univ_gen_ext_splitR in u0. destruct u0. destruct s. repeat destruct p.
+subst. inversion u0.
+- right. exists x. exists (l ++ x2). split. auto.
+  split. assumption. inversion X. subst. simpl. assumption.
+- left. subst. inversion X0. subst. split. rewrite app_nil_l.
+  apply univ_gen_ext_combine. assumption. assumption. assumption.
+Qed.
+ +
+(* The next lemma states that if a list l1 is embedded in another list,
+   then one can add an element a however deep in the embedding list and
+   keep the relation of embedding, as long as a satisfies P. *)

+ +
+Lemma univ_gen_ext_add_elem_deep {A : Type} : forall P (l1 l2 l3: list A) a,
+    univ_gen_ext P l1 (l2 ++ l3) ->
+    P a -> univ_gen_ext P l1 (l2 ++ a :: l3).
+Proof.
+intros. apply univ_gen_ext_splitR in X. destruct X. destruct s.
+repeat destruct p. subst. apply univ_gen_ext_combine.
+assumption. apply univ_gen_ext_extra. assumption. assumption.
+Qed.
+ +
+(* This last lemma claims that if l0 is embedded in l1 with a property P,
+   then l0 is also embedded in l1 with the property Q. Obviously, all elements
+   which were added in l1 via univ_gen_ext_extra satisfied the property P, and
+   as Q is weaker than P we get that these elements aso satisfy Q. Thus we preserve
+   the embedding relation. *)

+ +
+Lemma univ_gen_ext_Q_weaker_than_P {A : Type} : forall P Q (l0 l1 : list A),
+          (forall a, P a -> Q a) ->
+          (univ_gen_ext P l0 l1) ->
+          (univ_gen_ext Q l0 l1).
+Proof.
+intros. induction X0.
+- apply univ_gen_ext_nil.
+- apply univ_gen_ext_cons. assumption.
+- apply univ_gen_ext_extra. apply X. assumption. assumption.
+Qed.
+ +
+Lemma univ_gen_ext_In {A : Type} : forall (l0 l1 : list A) a P, univ_gen_ext P l0 l1 ->
+                                        In a l0 -> In a l1.
+Proof.
+intros. induction X.
+- subst. inversion H.
+- subst. inversion H. subst. apply in_eq. subst. apply in_cons. apply IHX. assumption.
+- apply in_cons. apply IHX. assumption.
+Qed.
+ +
+Lemma univ_gen_ext_smaller_length : forall {A: Type} (l1 l2 : list A) P,
+                      univ_gen_ext P l1 l2 -> length l1 <= length l2.
+Proof.
+intros. induction X.
+- auto.
+- simpl. apply le_n_S. assumption.
+- simpl. lia.
+Qed.
+ +
+Lemma univ_gen_ext_same_length_id : forall {A: Type} (l1 l2 : list A) P,
+              (length l1 = length l2) -> univ_gen_ext P l1 l2 -> l1 = l2.
+Proof.
+intros A l1 l2 P H X. induction X.
+- firstorder.
+- simpl in H. inversion H. apply IHX in H1. subst. auto.
+- simpl in H. exfalso. pose (univ_gen_ext_smaller_length X). lia.
+Qed.
+ +
+Lemma univ_gen_ext_not_In_delete : forall {A : Type} (l1 l2 : list A) P (a : A),
+            ((In a l1) -> False) -> univ_gen_ext P l1 (a :: l2) -> univ_gen_ext P l1 l2.
+Proof.
+intros. remember (a :: l2) as l3. induction X.
+- inversion Heql3.
+- inversion Heql3. subst. exfalso. apply H. apply in_eq.
+- inversion Heql3. subst. assumption.
+Qed.
+ +
+Lemma InT_univ_gen_ext : forall {A : Type} (l1 l2 : list A) (P : A -> Type) (a : A),
+          (InT a l2) -> (univ_gen_ext P l1 l2) -> ((P a) + (InT a l1)).
+Proof.
+intros. induction X0.
+- inversion X.
+- inversion X. subst. right. apply InT_eq. apply IHX0 in X1. destruct X1. auto.
+  right. apply InT_cons. assumption.
+- inversion X. subst. auto. apply IHX0 in X1. assumption.
+Qed.
+ +
+(* univ_gen_ext simulates gen_ext: *)
+ +
+Definition gen_ext {W : Type} := @univ_gen_ext W (fun x => True).
+ +
+Lemma gen_ext_refl: forall W (l : list W), gen_ext l l.
+Proof. induction l. apply univ_gen_ext_nil. apply univ_gen_ext_cons. exact IHl. Qed.
+ +
+Lemma gen_ext_appL: forall W (xs ys zs : list W),
gen_ext xs ys ->gen_ext xs (zs ++ ys).
+Proof. induction zs. tauto. intros. apply univ_gen_ext_extra. tauto. tauto. Qed.
+ +
+Lemma gen_ext_appR: forall W (xs ys zs : list W),
gen_ext xs ys -> gen_ext xs (ys ++ zs).
+Proof. intros. induction X.
+induction zs. simpl. apply univ_gen_ext_nil. simpl.
+apply univ_gen_ext_extra. apply I. assumption.
+simpl. apply univ_gen_ext_cons. assumption.
+simpl. apply univ_gen_ext_extra. assumption. assumption. Qed.
+ +
+Lemma gen_ext_nil_any: forall W (xs : list W),gen_ext [] xs.
+Proof. induction xs. apply univ_gen_ext_nil. apply univ_gen_ext_extra. tauto. tauto. Qed.
+ +
+Lemma gen_ext_trans: forall W (ys zs : list W),
gen_ext ys zs -> forall xs, gen_ext xs ys -> gen_ext xs zs.
+Proof. intros until 1. induction X. tauto.
+intros. inversion X0. subst. apply univ_gen_ext_cons. firstorder.
+subst. apply univ_gen_ext_extra. firstorder. firstorder.
+intros. apply univ_gen_ext_extra. firstorder. firstorder. Qed.
+ +
+Lemma gen_ext_app: forall W (ys zs : list W),
gen_ext ys zs -> forall us vs, gen_ext us vs -> gen_ext (us ++ ys) (vs ++ zs).
+Proof. intros. induction X0 ; simpl. exact X.
+apply univ_gen_ext_cons. assumption.
+apply univ_gen_ext_extra. assumption. assumption. Qed.
+ +
+Definition gen_ext_sameL W xs ys zs ge :=
+  @gen_ext_app W ys zs ge xs xs (@gen_ext_refl W xs).
+Definition gen_ext_sameR W xs ys zs ge :=
+  @gen_ext_app W xs xs (@gen_ext_refl W xs) ys zs ge.
+ +
+Lemma gen_ext_lem: forall A (x : A) Z Y,
gen_ext (x :: Z) Y -> sigT (fun Y1 => sigT (fun Y2 =>
+    prod (Y = Y1 ++ x :: Y2) (gen_ext Z Y2))).
+Proof. intros A x Z. induction Y.
+intro. inversion X. intro. inversion X ; subst.
+exists []. exists Y. simpl. tauto.
+apply IHY in X0. cD. subst.
+exists (a :: X0). exists X1. simpl. tauto. Qed.
+ +
+Lemma gen_ext_splitL: forall A Z2 Z1 Y,
gen_ext (Z1 ++ Z2 : list A) Y -> sigT (fun Y1 => sigT (fun Y2 =>
+    prod (Y = Y1 ++ Y2) (prod (gen_ext Z1 Y1) (gen_ext Z2 Y2)))).
+Proof. intros A Z2. induction Z1 ; simpl.
+exists []. exists Y. simpl. split. trivial.
+split. apply univ_gen_ext_nil. trivial.
+intro. intro. apply gen_ext_lem in X. cD. subst.
+apply IHZ1 in X2. cD. subst.
+exists (X ++ a :: X2). exists X1.
+split. rewrite app_comm_cons. rewrite app_assoc. trivial.
+split. apply gen_ext_appL. apply univ_gen_ext_cons. assumption. assumption. Qed.
+ +
+Lemma gen_ext_splitR: forall A Z2 Z1 Y,
gen_ext Y (Z1 ++ Z2 : list A) -> sigT (fun Y1 => sigT (fun Y2 =>
+    prod (Y = Y1 ++ Y2) (prod (gen_ext Y1 Z1) (gen_ext Y2 Z2)))).
+Proof. intros A Z2. induction Z1 ; simpl.
+exists []. exists Y. simpl. split. trivial.
+split. apply univ_gen_ext_nil. trivial.
+intro. intro. inversion X ; subst.
+apply IHZ1 in X0. cD. subst.
+exists (a :: X0). exists X1. simpl. split. trivial.
+split. apply univ_gen_ext_cons. assumption. assumption.
+apply IHZ1 in X0. cD. subst.
+exists X0. exists X1. split. trivial.
+split. apply univ_gen_ext_extra. assumption. assumption. assumption. Qed.
+ +
+Lemma gen_ext_combine: forall A (Z2 Z1 Y2 Y1 : list A),
+   gen_ext Y1 Z1 ->gen_ext Y2 Z2 ->gen_ext (Y1 ++ Y2) (Z1 ++ Z2).
+Proof.
+intros A Z2 Z1 Y2 Y1 gen1 gen2. induction gen1.
+- repeat rewrite app_nil_l. assumption.
+- simpl. apply univ_gen_ext_cons. assumption.
+- simpl. apply univ_gen_ext_extra. assumption. assumption.
+Qed.
+ +
+Lemma gen_ext_same_hd: forall A (Y Z : list A) a,
+   gen_ext (a::Y) (a::Z) ->gen_ext Y Z.
+Proof.
+intros A Y Z a gen. inversion gen.
+- assumption.
+- subst. assert (H:gen_ext Y (a :: Y)).
+  apply univ_gen_ext_extra. apply I. apply gen_ext_refl.
+  apply gen_ext_trans with (ys:=(a :: Y)). assumption. assumption.
+Qed.
+ +
+Lemma gen_ext_single: forall A (l : list A), sing_empty l ->
+  forall Y Z le,gen_ext (Z ++ l ++ Y) le -> sigT (fun Ze => sigT (fun Ye =>
+    prod (prod (gen_ext Z Ze) (gen_ext Y Ye)) (le = Ze ++ l ++ Ye))).
+Proof. intros A l es Y. destruct es ; simpl ; intros.
+apply gen_ext_splitL in X. cD. subst. firstorder.
+apply gen_ext_splitL in X. cD.
+apply gen_ext_lem in X3. cD. subst.
+exists (X ++ X3). exists X4.
+split. split. apply gen_ext_appR. assumption. assumption.
+rewrite app_assoc. trivial. Qed.
+ +
+Lemma gen_ext_one': forall A (x : A) (xs l : list A),
+  xs = [x] ->gen_ext xs l -> InT x l.
+Proof. intros. induction X.
+- discriminate H.
+- injection H as . subst. apply InT_eq.
+- apply InT_cons. apply (IHX H). Qed.
+ +
+Definition gen_ext_one A x l := @gen_ext_one' A x [x] l eq_refl.
+(* and note result InT_split *)
+ +
+Lemma InT_gen_ext A x l: InT x l ->gen_ext [x : A] l.
+Proof. intros. apply InT_split in X. cD. subst.
+apply gen_ext_appL. apply univ_gen_ext_cons. apply gen_ext_nil_any. Qed.
+ +
+Lemma gen_ext_InT A (x : A) l m:gen_ext l m -> InT x l -> InT x m.
+Proof. intro ge. induction ge. tauto.
+intro. inversion X ; subst. apply InT_eq.
+apply InT_cons. exact (IHge X0).
+intro. apply InT_cons. exact (IHge X). Qed.
+ +
+Lemma gen_ext_diff' V X r :gen_ext X r -> forall (y : V) Y Z,
+    r = (Y ++ y :: Z) -> InT y X +gen_ext X (Y ++ Z).
+Proof. intro ge. induction ge.
+- intros. list_eq_ncT. contradiction.
+- intros. acacD'T2 ; subst.
++ left. apply InT_eq.
++ erequire IHge. erequire IHge. erequire IHge. require IHge.
+  reflexivity. destruct IHge.
+ * left. apply InT_cons. assumption.
+ * right. simpl. apply univ_gen_ext_cons. assumption.
+- intros. acacD'T2 ; subst.
++ right. simpl. assumption.
++ erequire IHge. erequire IHge. erequire IHge. require IHge.
+  reflexivity. destruct IHge.
+ * left. assumption.
+ * right. simpl. apply univ_gen_ext_extra. apply I. assumption.
+Qed.
+ +
+Definition gen_ext_diff V X y Y Z ge := @gen_ext_diff' V X _ ge y Y Z eq_refl.
+ +
+Lemma gen_ext_delet_hd {A : Type} : forall (l1 l2 l3: list A) (a : A),
+       gen_ext l1 l2 -> (l1 = a :: l3) ->gen_ext l3 l2.
+Proof.
+intros l1 l2 l3 a gen. generalize dependent l3. induction gen.
+- intros l3 E. inversion E.
+- intros l3 E. inversion E. destruct l3.
+  * subst. apply gen_ext_nil_any.
+  * inversion E. subst. apply univ_gen_ext_extra. apply I. assumption.
+- intros l3 E. apply univ_gen_ext_extra. apply I. apply IHgen. assumption.
+Qed.
+ +
+Lemma gen_ext_elem_deep {A : Type} : forall (l1 l2 l3 l4: list A) (a : A),
+         gen_ext l1 l2 ->
+          (l2 = l3 ++ a :: l4) ->
+            ((gen_ext l1 (l3 ++ l4)) +
+            sigT (fun l5 => sigT (fun l6 =>
+              (prod (l1 = l5 ++ a :: l6) (prod (gen_ext l5 l3) (gen_ext l6 l4)))))).
+Proof.
+intros l1 l2 l3 l4 a gen. generalize dependent a. generalize dependent l4.
+generalize dependent l3. induction gen.
+- intros l3 l4 a E. destruct l3. inversion E. inversion E.
+- intros l3 l4 a E. destruct l3.
+  * inversion E. simpl in E. destruct l4.
+    + right. exists []. exists []. split. simpl. destruct l.
+      reflexivity. exfalso. subst. inversion gen. split.
+      apply univ_gen_ext_nil. apply univ_gen_ext_nil.
+    + pose (IHgen [] l4 a0). simpl in s. pose (s H1). destruct s0.
+      { right. exists []. exists l. split. reflexivity. split.
+        apply univ_gen_ext_nil. apply univ_gen_ext_extra. apply I. assumption. }
+      { repeat destruct s0. repeat destruct p. subst. right.
+        exists []. exists (x0 ++ a0 :: x1). split. reflexivity.
+        split. apply univ_gen_ext_nil. destruct x0. simpl. apply univ_gen_ext_cons. assumption.
+        inversion g. }
+  * inversion E. pose (IHgen l3 l4 a H1). destruct s.
+    + left. apply univ_gen_ext_cons. assumption.
+    + repeat destruct s. repeat destruct p. subst. right. exists (a0 :: x0).
+      exists x1. split. reflexivity. split. apply univ_gen_ext_cons. assumption.
+      assumption.
+- intros l3 l4 a E. destruct l3.
+  * simpl in E. inversion E. subst. left. simpl. assumption.
+  * inversion E. pose (IHgen l3 l4 a H1). destruct s.
+    + left. apply univ_gen_ext_extra. apply I. assumption.
+    + repeat destruct s. repeat destruct p0. subst. right.
+      exists x0. exists x1. split. reflexivity. split.
+      apply univ_gen_ext_extra. apply I. assumption. assumption.
+Qed.
+ +
+Lemma gen_ext_add_elem_deep {A : Type} : forall (l1 l2 l3: list A) (a : A),
+   gen_ext l1 (l2 ++ l3) ->gen_ext l1 (l2 ++ a :: l3).
+Proof.
+induction l1.
+- intros. apply gen_ext_nil_any.
+- induction l2.
+  * intros l3 a0 gen. simpl. simpl in gen. apply univ_gen_ext_extra. apply I. assumption.
+  * intros l3 a1 gen. remember ((a0 :: l2) ++ l3) as l4. remember (a :: l1) as l5. destruct gen.
+    + apply gen_ext_nil_any.
+    + inversion Heql4. simpl. subst. apply univ_gen_ext_cons.
+      inversion Heql5. apply IHl1. rewrite <- H1. assumption.
+    + inversion Heql4. subst. simpl. apply univ_gen_ext_extra. apply I.
+      apply IHl2. assumption.
+Qed.
+ +
+Ltac solve_gen_ext :=
+  repeat (apply gen_ext_appR ||
+      apply gen_ext_nil_any || apply gen_ext_refl ||
+      apply gen_ext_sameL || apply gen_ext_appL ||
+      apply univ_gen_ext_cons || apply univ_gen_ext_extra).
+ +
+Ltac solve_univ_gen_ext :=
+  repeat (apply univ_gen_ext_appR || apply univ_gen_ext_refl ||
+      apply univ_gen_ext_appL || apply univ_gen_ext_cons ||
+      apply univ_gen_ext_extra).
+ +
+(* univ_gen_ext simulates rest_gen_ext. The latter allows to restrict
+   the elements you can add to the embedding list to elements of a specific
+   list l. *)

+ +
+Definition rest_gen_ext {W : Type} l := univ_gen_ext (fun x => (@InT W x l)).
+
+
+ +
+ + + diff --git a/General.univ_gen_mod.html b/General.univ_gen_mod.html new file mode 100644 index 0000000..e27f9c1 --- /dev/null +++ b/General.univ_gen_mod.html @@ -0,0 +1,228 @@ + + + + + + + + + + + + + +
+
+

General.univ_gen_mod

+ +
+Require Export List.
+Export ListNotations.
+Set Implicit Arguments.
+ +
+From Coq Require Import ssreflect.
+ +
+Require Import gen.
+Require Import existsT.
+Require Import genT.
+Require Import gen_tacs.
+Require Import gen_seq.
+Require Import List_lemmasT.
+Require Import FunctionalExtensionality.
+Require Import Lia.
+ +
+(* Effectively, univ_gen_mod allows to take a list and modify it by
+    substituting elements (say x) in the initial list by other elements
+    (say y) such that they are satisfying a specific relation (i.e. P x y).  *)

+ +
+Inductive univ_gen_mod W (P : W -> W -> Type) : relationT (list W) :=
+  | univ_gen_mod_nil : univ_gen_mod P [] []
+  | univ_gen_mod_cons : forall x l lm, univ_gen_mod P l lm -> univ_gen_mod P (x :: l) (x :: lm)
+  | univ_gen_mod_modif : forall x y l lm, P x y -> univ_gen_mod P l lm -> univ_gen_mod P (x :: l) (y :: lm)
+  .
+ +
+(* We can prove some general properties about univ_gen_mod. *)
+ +
+(* univ_gen_mod is a reflexive relation. *)
+ +
+Lemma univ_gen_mod_refl: forall A (l : list A) P, univ_gen_mod P l l.
+Proof.
+induction l.
+- apply univ_gen_mod_nil.
+- intro. apply univ_gen_mod_cons. apply IHl.
+Qed.
+ +
+(* The lemma univ_gen_mod_lem states that if a list x::Z is embedded in
+   a list Y, then x must be appearing in Y, i.e. Y = Y1++x::Y2, and Y2 is
+   is such that Z is embedded in Y2. Note that Y1 is here as it could well
+   be that some elements were added via univ_gen_mod_modif before even
+   treating x. *)

+ +
+Lemma univ_gen_mod_lem: forall A (x : A) P Z Y,
+  univ_gen_mod P (x :: Z) Y -> sigT (fun Y1 => sigT (fun y =>
+  prod (P x y + (x = y)) (prod (Y = y :: Y1) (univ_gen_mod P Z Y1)))).
+Proof.
+intros A x P Z. induction Y.
+intro. inversion X. intro. inversion X ; subst. exists Y. exists a. split ; auto.
+exists Y. exists a ; repeat split ; auto.
+Qed.
+ +
+(* The next two lemmas deal with the interaction between univ_gen_mod
+   and append. In essence, they say that if the embedded (resp. embedding)
+   list is of the shape X1++X2, then the embedding list (resp. embedded)
+   is of the shape W1++W2 where W1 embedds (resp. is embedded in) X1 and
+   W2 embedds (resp. is embedded in) X1. *)

+ +
+Lemma univ_gen_mod_splitL: forall A P (Z2 Z1 Y : list A),
+  univ_gen_mod P (Z1 ++ Z2) Y -> sigT (fun Y1 => sigT (fun Y2 =>
+    prod (Y = Y1 ++ Y2) (prod (univ_gen_mod P Z1 Y1) (univ_gen_mod P Z2 Y2)))).
+Proof.
+intros A P Z2. induction Z1 ; simpl.
+- exists []. exists Y. simpl. split. trivial. split. apply univ_gen_mod_nil. trivial.
+- intro. intro. apply univ_gen_mod_lem in X. destruct X. destruct s. repeat destruct p.
+  destruct s ; subst.
+  + apply IHZ1 in u. destruct u. destruct s. repeat destruct p0.
+     exists (x0 :: x1). exists x2. repeat split ; auto. subst ; trivial.
+     apply univ_gen_mod_modif ; auto.
+  + apply IHZ1 in u. destruct u. destruct s. repeat destruct p ; subst.
+     exists (x0 :: x1). exists x2. repeat split ; auto.
+     apply univ_gen_mod_cons ; auto.
+Qed.
+ +
+Lemma univ_gen_mod_splitR: forall A P (Z2 Z1 Y : list A),
+  univ_gen_mod P Y (Z1 ++ Z2) -> sigT (fun Y1 => sigT (fun Y2 =>
+    prod (Y = Y1 ++ Y2) (prod (univ_gen_mod P Y1 Z1) (univ_gen_mod P Y2 Z2)))).
+Proof.
+intros V Z2. induction Z1 ; simpl.
+- exists []. exists Y. simpl. split. trivial. split. apply univ_gen_mod_nil. trivial.
+- intro. intro. inversion X ; subst. apply IHZ1 in X0. cD. subst.
+  exists (a :: X0). exists X1. simpl. split. trivial.
+  split. apply univ_gen_mod_cons. assumption. assumption.
+  apply IHZ1 in X1. cD. subst.
+  exists (x :: X1). exists X2. split. trivial. split. apply univ_gen_mod_modif ; auto.
+  assumption.
+Qed.
+ +
+(* univ_gen_mod_combine claims that if Y1 is embedded in Z1 and Y2 is embedded
+   in Z2, then we can combine the embedded lists in the shape of Y1++Y2 and combine
+   the embedding lists in Z1++Z2 to preserve the relation of embedding between the
+   newly created lists.*)

+ +
+Lemma univ_gen_mod_combine: forall A P (Z2 Z1 Y2 Y1 : list A),
+    univ_gen_mod P Y1 Z1 -> univ_gen_mod P Y2 Z2 -> univ_gen_mod P (Y1 ++ Y2) (Z1 ++ Z2).
+Proof.
+intros A P Z2 Z1 Y2 Y1 gen1 gen2. induction gen1.
+- repeat rewrite app_nil_l. assumption.
+- simpl. apply univ_gen_mod_cons. assumption.
+- simpl. apply univ_gen_mod_modif. assumption. assumption.
+Qed.
+ +
+(* The next lemma states that if a::Y is embedded in a::Z, then we know
+   for sure that Y is embedded in Z. Note that this is not direct as the
+   a in the embedding list could have been added via univ_gen_mod_modif.
+   Effectively, this lemma allows one to remove the identical heads of two
+   lists univ_gen_mod and preserve that relation. *)

+ +
+Lemma univ_gen_mod_same_hd: forall A P (Y Z : list A) (a : A),
+    univ_gen_mod P (a :: Y) (a :: Z) -> univ_gen_mod P Y Z.
+Proof.
+intros A P Y Z a gen. inversion gen ; auto.
+Qed.
+ +
+(* The lemma univ_gen_mod_elem_deep considers a list l1 embedded in a
+   list l2 in which an element a appears deeply. Essentially, the lemma
+   makes a case distinction about a: either it has been added by univ_gen_mod_modif
+   (this is the first case of the sum) or it was added by univ_gen_mod_cons
+   in which case it has to appear somewhere in l1. *)

+ +
+Lemma univ_gen_mod_elem_deep {A : Type} : forall P (l1 l2 l3 l4: list A) a,
+          univ_gen_mod P l1 l2 ->
+          (l2 = l3 ++ a :: l4) ->
+            sigT (fun l5 => sigT (fun l6 => sigT (fun b =>
+              (prod (l1 = l5 ++ b :: l6) (prod (P b a + (a = b)) (prod (univ_gen_mod P l5 l3) (univ_gen_mod P l6 l4))))))).
+Proof.
+intros. subst. rewrite cons_single in X. apply univ_gen_mod_splitR in X.
+destruct X. destruct s. repeat destruct p. subst.
+apply univ_gen_mod_splitR in u0. destruct u0. destruct s. repeat destruct p.
+subst. inversion u0 ; subst.
+- inversion X ; subst. exists x. exists x2. exists a. repeat split ; auto.
+- inversion X0. subst. exists x. exists x2. exists x0. repeat split ; auto.
+Qed.
+ +
+Lemma univ_gen_mod_In {A : Type} : forall (l0 l1 : list A) a P, univ_gen_mod P l0 l1 ->
+                                        InT a l0 -> (InT a l1 + (existsT2 b, InT b l1 * P a b)).
+Proof.
+intros. induction X ; subst.
+- inversion X0.
+- inversion X0 ; subst. left ; apply InT_eq. apply IHX in X1. destruct X1.
+  left ; apply InT_cons ; auto. destruct s ; destruct p. right ; exists x0 ; split ; auto.
+  apply InT_cons ; auto.
+- inversion X0 ; subst. right. exists y ; split ; auto. apply InT_eq. apply IHX in X1. destruct X1.
+  left ; apply InT_cons ; auto. destruct s ; destruct p0. right ; exists x0 ; split ; auto.
+  apply InT_cons ; auto.
+Qed.
+ +
+Lemma univ_gen_mod_smaller_length : forall {A: Type} (l1 l2 : list A) P,
+                      univ_gen_mod P l1 l2 -> length l1 = length l2.
+Proof.
+intros. induction X.
+- auto.
+- simpl. lia.
+- simpl. lia.
+Qed.
+ +
+Lemma InT_univ_gen_mod : forall {A : Type} (l1 l2 : list A) (P : A -> A -> Type) (a : A),
+          (InT a l2) -> (univ_gen_mod P l1 l2) -> ((existsT2 b, InT b l1 * P b a) + (InT a l1)).
+Proof.
+intros. induction X0 ; subst ; simpl.
+- inversion X.
+- inversion X ; subst. right. apply InT_eq. apply IHX0 in X1. destruct X1. destruct s ; destruct p.
+  left. exists x0. split ; auto. apply InT_cons. assumption. right ; apply InT_cons ; auto.
+- inversion X ; subst. left. exists x ; split ; auto. apply InT_eq. apply IHX0 in X1. destruct X1.
+  destruct s ; destruct p0. left ; exists x0 ; split ; auto. apply InT_cons ; auto. right ; apply InT_cons ; auto.
+Qed.
+ +
+
+
+ +
+ + + diff --git a/ISL.Cut.html b/ISL.Cut.html new file mode 100644 index 0000000..601121c --- /dev/null +++ b/ISL.Cut.html @@ -0,0 +1,356 @@ + + + + + + + + + + + + + +
+
+

ISL.Cut

+ +
+Require Import ISL.Formulas ISL.Sequents ISL.Order.
+Require Import ISL.SequentProps .
+ +
+Local Hint Rewrite elements_env_add : order.
+ +
+(* From "A New Calculus for Intuitionistic Strong Löb Logic" *)
+Theorem additive_cut Γ φ ψ :
+  Γ φ -> Γ φ ψ ->
+  Γ ψ.
+Proof.
+remember (weight φ) as w. assert(Hw : weight φ w) by lia. clear Heqw.
+revert φ Hw ψ Γ.
+induction w; intros φ Hw; [pose (weight_pos φ); lia|].
+intros ψ Γ.
+remember (Γ, ψ) as pe.
+replace Γ with pe.1 by now subst.
+replace ψ with pe.2 by now subst. clear Heqpe Γ ψ. revert pe.
+refine (@well_founded_induction _ _ wf_pointed_env_ms_order _ _).
+intros (Γ &ψ). simpl. intro IHW'. assert (IHW := fun Γ0 => fun ψ0 => IHW' (Γ0, ψ0)).
+simpl in IHW. clear IHW'. intros HPφ HPψ.
+Ltac otac Heq := subst; repeat rewrite env_replace in Heq by trivial; repeat rewrite env_add_remove by trivial; order_tac; rewrite Heq; order_tac.
+destruct HPφ; simpl in Hw.
+- now apply contraction.
+- apply ExFalso.
+- apply AndL_rev in HPψ. do 2 apply IHw in HPψ; trivial; try lia; apply weakening; assumption.
+- apply AndL. apply IHW; auto with proof. order_tac.
+- apply OrL_rev in HPψ; apply (IHw φ); [lia| |]; tauto.
+- apply OrL_rev in HPψ; apply (IHw ψ0); [lia| |]; tauto.
+- apply OrL; apply IHW; auto with proof.
+  + otac Heq.
+  + exch 0. eapply (OrL_rev _ φ ψ0). exch 0. exact HPψ.
+  + order_tac.
+  + exch 0. eapply (OrL_rev _ φ ψ0). exch 0. exact HPψ.
+- (* (V) *) (* hard:  *)
+(* START *)
+  remember (Γ (φ ψ0)) as Γ' eqn:HH.
+  assert (Heq: Γ Γ' {[ φ ψ0]}) by ms.
+  assert(Hin : (φ ψ0) Γ')by ms.
+  rw Heq 0. destruct HPψ.
+  + forward. auto with proof.
+  + forward. auto with proof.
+  + apply AndR.
+     * rw (symmetry Heq) 0. apply IHW.
+     -- unfold pointed_env_ms_order. order_tac.
+     -- now apply ImpR.
+     -- peapply HPψ1.
+     * rw (symmetry Heq) 0. apply IHW.
+       -- order_tac.
+       -- apply ImpR. box_tac. peapply HPφ.
+       -- peapply HPψ2.
+  + forward. apply AndL. apply IHW.
+     * unfold pointed_env_ms_order. otac Heq.
+     * apply AndL_rev. backward. rw (symmetry Heq) 0. apply ImpR, HPφ.
+     * backward. peapply HPψ.
+  + apply OrR1, IHW.
+    * rewrite HH, env_add_remove. order_tac.
+    * rw (symmetry Heq) 0. apply ImpR, HPφ.
+    * peapply HPψ.
+  + apply OrR2, IHW.
+    * rewrite HH, env_add_remove. order_tac.
+    * rw (symmetry Heq) 0. apply ImpR, HPφ.
+    * peapply HPψ.
+  + forward. apply ImpR in HPφ.
+       assert(Hin' : (φ0 ψ) ((Γ0 φ0 ψ) {[φ ψ0]}))
+            by (apply in_difference; [discriminate|ms]).
+       assert(HPφ' : (((Γ0 φ0 ψ) {[φ ψ0]}) {[φ0 ψ]} φ0 ψ) (φ ψ0))
+            by (rw (symmetry (difference_singleton _ (φ0 ψ) Hin')) 0; peapply HPφ).
+       assert (HP := (OrL_rev _ φ0 ψ (φ ψ0) HPφ')).
+       apply OrL.
+      * apply IHW.
+        -- rewrite env_replace in Heq by trivial. order_tac. rewrite Heq. order_tac.
+        -- peapply HP.1.
+        -- exch 0. rw (symmetry (difference_singleton _ _ Hin0)) 1. exact HPψ1.
+      * apply IHW.
+        -- rewrite env_replace in Heq by trivial. order_tac. rewrite Heq. order_tac.
+        -- peapply HP.2.
+        -- exch 0. rw (symmetry (difference_singleton _ _ Hin0)) 1. exact HPψ2.
+  + rw (symmetry Heq) 0. apply ImpR, IHW.
+      -- order_tac.
+      -- apply weakening, ImpR, HPφ.
+      -- exch 0. rewrite <- HH. exact HPψ.
+  + case (decide ((Var p φ0) = (φ ψ0))).
+      * intro Heq'; inversion Heq'; subst. clear Heq'.
+         replace ((Γ0 Var p (p ψ0)) {[p ψ0]}) with (Γ0 Var p) by ms.
+         apply (IHw ψ0).
+        -- lia.
+        -- apply contraction. peapply HPφ.
+        -- assumption.
+      * intro Hneq. do 2 forward. exch 0. apply ImpLVar, IHW.
+        -- repeat rewrite env_replace in Heq by trivial. order_tac. rewrite Heq. order_tac.
+        -- apply imp_cut with (φ := Var p). exch 0. do 2 backward.
+            rw (symmetry Heq) 0. apply ImpR, HPφ.
+        -- exch 0; exch 1. rw (symmetry (difference_singleton _ _ Hin1)) 2. exact HPψ.
+  + case (decide (((φ1 φ2) φ3)= (φ ψ0))).
+      * intro Heq'; inversion Heq'; subst. clear Heq'. rw (symmetry Heq) 0.
+         apply (IHw (φ1 φ2 ψ0)).
+        -- simpl in *. lia.
+        -- apply ImpR, ImpR, AndL_rev, HPφ.
+        -- peapply HPψ.
+      * intro Hneq. forward. apply ImpLAnd, IHW.
+        -- rewrite env_replace in Heq by trivial. order_tac. rewrite Heq. order_tac.
+        -- apply ImpLAnd_rev. backward. rw (symmetry Heq) 0. apply ImpR, HPφ.
+        -- exch 0. rw (symmetry (difference_singleton _ _ Hin0)) 1. exact HPψ.
+  + case (decide (((φ1 φ2) φ3)= (φ ψ0))).
+      * intro Heq'; inversion Heq'; subst. clear Heq'. rw (symmetry Heq) 0. apply OrL_rev in HPφ.
+         apply (IHw (φ1 ψ0)).
+        -- simpl in *. lia.
+        -- apply (IHw (φ2 ψ0)).
+           ++ simpl in *; lia.
+           ++ apply ImpR, HPφ.
+           ++ apply weakening, ImpR, HPφ.
+        -- apply (IHw (φ2 ψ0)).
+           ++ simpl in *; lia.
+           ++ apply weakening, ImpR, HPφ.
+           ++ peapply HPψ.
+      * intro Hneq. forward. apply ImpLOr, IHW.
+        -- rewrite env_replace in Heq by trivial. order_tac. rewrite Heq. order_tac.
+        -- apply ImpLOr_rev. backward. rw (symmetry Heq) 0. apply ImpR, HPφ.
+        -- exch 0. exch 1. rw (symmetry (difference_singleton _ _ Hin0)) 2. exact HPψ.
+  + case (decide (((φ1 φ2) φ3) = (φ ψ0))).
+     * intro Heq'. inversion Heq'; subst. clear Heq'. rw (symmetry Heq) 0. apply (IHw ψ0).
+      -- lia.
+      -- apply (IHw(φ1 φ2)).
+        ++ lia.
+        ++ apply (IHw (φ2 ψ0)).
+            ** simpl in *. lia.
+            ** apply ImpR. eapply imp_cut, HPφ.
+            ** peapply HPψ1.
+        ++ exact HPφ.
+    -- peapply HPψ2.
+   * (* (V-d) *)
+       intro Hneq. forward. apply ImpLImp.
+      -- apply ImpR, IHW.
+        ++ otac Heq.
+        ++ exch 0. apply contraction, ImpLImp_dup. backward. rw (symmetry Heq) 0.
+                apply ImpR, HPφ.
+        ++ exch 0. apply ImpR_rev. exch 0. rw (symmetry (difference_singleton _ _ Hin0)) 1.
+                exact HPψ1.
+      -- apply IHW.
+        ++ otac Heq.
+        ++ apply imp_cut with (φ1 φ2). backward. rw (symmetry Heq) 0.
+                apply ImpR, HPφ.
+        ++ exch 0. rw (symmetry (difference_singleton _ _ Hin0)) 1. exact HPψ2.
+  + case (decide (( φ1 φ2) = (φ ψ0))).
+     * intro Heq'. inversion Heq'; subst. clear Heq'. rw (symmetry Heq) 0.
+        assert(Γ = Γ0) by ms. subst Γ0. clear Hin.
+        apply (IHw ( φ1)).
+      -- lia.
+      -- apply BoxR, (IHw(ψ0)).
+        ++ lia.
+        ++ apply open_boxes_R, HPφ.
+        ++ exact HPψ1.
+     -- apply (IHw(ψ0)).
+        ++ lia.
+        ++ exact HPφ.
+        ++ exch 0. apply weakening, HPψ2.
+    * (* (V-f ) *)
+       intro Hneq. forward. apply ImpBox.
+       -- apply IHW.
+        ++ otac Heq. rewrite elements_open_boxes. otac Heq.
+        ++ apply ImpR_rev, open_boxes_R, ImpR.
+                apply ImpLBox_prev with φ1. exch 0. apply weakening.
+                backward. rw (symmetry Heq) 0. apply ImpR, HPφ.
+        ++ exch 0. exch 1. box_tac. apply In_open_boxes in Hin0. simpl in Hin0.
+               rw (symmetry (difference_singleton _ _ Hin0)) 2. exact HPψ1.
+       -- apply IHW.
+        ++ otac Heq.
+        ++ apply ImpLBox_prev with φ1. backward. rw (symmetry Heq) 0.
+                apply ImpR, HPφ.
+        ++ exch 0. rw (symmetry (difference_singleton _ _ Hin0)) 1. exact HPψ2.
+  + subst. rw (symmetry Heq) 0. rewrite open_boxes_add in HPψ. simpl in HPψ.
+      apply BoxR. apply IHW.
+    * otac Heq. rewrite elements_open_boxes. otac Heq.
+    * apply open_boxes_R, weakening, ImpR, HPφ.
+    * exch 0. exact HPψ.
+- apply ImpLVar. eapply IHW; eauto.
+  + otac Heq.
+  + exch 0. apply (imp_cut (Var p)). exch 0; exact HPψ.
+- apply ImpLAnd. eapply IHW; eauto.
+  + otac Heq.
+  + exch 0. apply ImpLAnd_rev. exch 0. exact HPψ.
+- apply ImpLOr. eapply IHW; eauto.
+  + otac Heq.
+  + exch 0. exch 1. apply ImpLOr_rev. exch 0. exact HPψ.
+- apply ImpLImp; [assumption|].
+  apply IHW.
+  + otac Heq.
+  + assumption.
+  + exch 0. eapply ImpLImp_prev. exch 0. exact HPψ.
+- apply ImpBox. trivial. apply IHW.
+  * otac Heq.
+  * assumption.
+  * exch 0. eapply ImpLBox_prev. exch 0. exact HPψ.
+  Require Import Coq.Program.Equality.
+(* (VIII) *)
+- remember (Γ φ) as Γ' eqn:HH.
+  assert (Heq: Γ Γ' {[ φ ]}) by ms.
+  assert(Hin : ( φ) Γ')by ms.
+  rw Heq 0. destruct HPψ.
+  + forward. auto with proof.
+  + forward. auto with proof.
+  + apply AndR.
+     * apply IHW.
+     -- subst. rewrite env_add_remove. otac H.
+     -- rw (symmetry Heq) 0. now apply BoxR.
+     -- peapply HPψ1.
+     * apply IHW.
+       -- otac Heq.
+       -- apply BoxR. box_tac. peapply HPφ. rewrite Heq.
+           rewrite open_boxes_remove; trivial.
+       -- peapply HPψ2.
+  + forward. apply AndL. apply IHW.
+     * otac Heq.
+     * apply AndL_rev. backward. rw (symmetry Heq) 0. apply BoxR, HPφ.
+     * backward. peapply HPψ.
+  + apply OrR1, IHW.
+    * otac Heq.
+    * rw (symmetry Heq) 0. apply BoxR, HPφ.
+    * peapply HPψ.
+  + apply OrR2, IHW.
+    * otac Heq.
+    * rw (symmetry Heq) 0. apply BoxR, HPφ.
+    * peapply HPψ.
+  + forward. apply BoxR in HPφ.
+       assert(Hin' : (φ0 ψ) ((Γ0 φ0 ψ) {[ φ]}))
+            by (apply in_difference; [discriminate|ms]).
+       assert(HPφ' : (((Γ0 φ0 ψ) {[ φ]}) {[φ0 ψ]} φ0 ψ) φ)
+            by (rw (symmetry (difference_singleton _ (φ0 ψ) Hin')) 0; peapply HPφ).
+       assert (HP := (OrL_rev _ φ0 ψ (φ) HPφ')).
+       apply OrL.
+      * apply IHW.
+        -- otac Heq.
+        -- peapply HP.1.
+        -- exch 0. rw (symmetry (difference_singleton _ _ Hin0)) 1. exact HPψ1.
+      * apply IHW.
+        -- otac Heq.
+        -- peapply HP.2.
+        -- exch 0. rw (symmetry (difference_singleton _ _ Hin0)) 1. exact HPψ2.
+  + rw (symmetry Heq) 0. apply ImpR, IHW.
+      -- otac Heq.
+      -- apply weakening, BoxR, HPφ.
+      -- exch 0. rewrite <- HH. exact HPψ.
+  + do 2 forward. exch 0. apply ImpLVar, IHW.
+      * otac Heq.
+      * apply imp_cut with (φ := Var p). exch 0. do 2 backward.
+         rewrite HH. apply BoxR in HPφ. peapply HPφ.
+      * exch 0; exch 1. rw (symmetry (difference_singleton _ _ Hin1)) 2. exact HPψ.
+  + forward. apply ImpLAnd, IHW.
+      * otac Heq.
+      * apply BoxR in HPφ. apply ImpLAnd_rev. backward. rewrite HH. peapply HPφ.
+      * exch 0. rw (symmetry (difference_singleton _ _ Hin0)) 1. exact HPψ.
+  + forward. apply ImpLOr, IHW.
+      * otac Heq.
+      * apply BoxR in HPφ. apply ImpLOr_rev. backward. rewrite HH. peapply HPφ.
+      * exch 0. exch 1. rw (symmetry (difference_singleton _ _ Hin0)) 2. exact HPψ.
+  + forward. apply ImpLImp.
+      -- apply ImpR, IHW.
+        ++ otac Heq.
+        ++ exch 0. apply contraction, ImpLImp_dup. backward. rw (symmetry Heq) 0.
+                apply BoxR, HPφ.
+        ++ exch 0. apply ImpR_rev. exch 0. rw (symmetry (difference_singleton _ _ Hin0)) 1.
+                exact HPψ1.
+      -- apply IHW.
+        ++ otac Heq.
+        ++ apply imp_cut with (φ1 φ2). backward. rw (symmetry Heq) 0.
+                apply BoxR, HPφ.
+        ++ exch 0. rw (symmetry (difference_singleton _ _ Hin0)) 1. exact HPψ2.
+  + (* (VIII-b) *)
+      forward. apply ImpBox.
+     * (* π0 *)
+        apply IHW.
+      -- otac Heq. rewrite elements_open_boxes. otac Heq.
+      -- apply ImpLBox_prev with (φ1 := φ1).
+          exch 0. apply weakening.
+          apply open_boxes_R. backward. rw (symmetry Heq) 0. apply BoxR, HPφ.
+      -- (* π1 *)
+          apply (IHw φ).
+          ++ lia.
+          ++ exch 1; exch 0. apply weakening.
+                  exch 0. apply ImpLBox_prev with (φ1 := φ1). exch 0.
+                  replace ( φ1 φ2) with ( ( φ1 φ2)) by trivial.
+                  rewrite <- (open_boxes_add (Γ0 {[φ]}) ( φ1 φ2)).
+                  assert(Heq0 : (Γ0 {[ φ]} ( φ1 φ2)) Γ)
+                      by (rewrite Heq; now rewrite env_replace).
+                 rw (proper_open_boxes _ _ Heq0) 1. exact HPφ.
+          ++ box_tac. exch 0. apply weakening. exch 0. exch 1.
+                  assert(Hin1 : φ Γ0) by(apply In_open_boxes in Hin0; now simpl).
+                  rw (symmetry (difference_singleton _ _ Hin1)) 2. exact HPψ1.
+     * apply IHW.
+      -- otac Heq.
+      -- apply ImpLBox_prev with (φ1 := φ1). backward.
+          rw (symmetry Heq) 0. apply BoxR, HPφ.
+      -- exch 0. rw (symmetry (difference_singleton _ _ Hin0)) 1. exact HPψ2.
+  + (* (VIII-c) *)
+      subst. rw (symmetry Heq) 0. rewrite open_boxes_add in HPψ. simpl in HPψ.
+      apply BoxR. apply IHW.
+    * otac Heq. rewrite elements_open_boxes. otac Heq.
+    * apply open_boxes_R, weakening, BoxR, HPφ.
+    * apply (IHw φ).
+      -- lia.
+      -- exch 0. apply weakening, HPφ.
+      -- exch 0. apply weakening. exch 0. exact HPψ.
+Qed.
+ +
+(* Multiplicative cut rule *)
+Theorem cut Γ Γ' φ ψ :
+  Γ φ -> Γ' φ ψ ->
+  Γ Γ' ψ.
+Proof.
+intros π1 π2. apply additive_cut with φ.
+- apply generalised_weakeningR, π1.
+- replace (Γ Γ' φ) with (Γ (Γ' φ)) by ms. apply generalised_weakeningL, π2.
+Qed.
+
+
+ +
+ + + diff --git a/ISL.DecisionProcedure.html b/ISL.DecisionProcedure.html new file mode 100644 index 0000000..1ca188c --- /dev/null +++ b/ISL.DecisionProcedure.html @@ -0,0 +1,663 @@ + + + + + + + + + + + + + +
+
+

ISL.DecisionProcedure

+ +
+Require Import ISL.Sequents ISL.SequentProps ISL.Order.
+ +
+Global Instance proper_rm : Proper ((=) ==> (≡ₚ) ==> (≡ₚ)) rm.
+Proof.
+intros x y Heq. subst y.
+induction 1; simpl; trivial.
+- case form_eq_dec; auto with *.
+- case form_eq_dec; auto with * ;
+   case form_eq_dec; auto with *. intros. apply Permutation_swap.
+- now rewrite IHPermutation1.
+Qed.
+ +
+Definition exists_dec {A : Type} (P : A -> bool) (l : list A): {x & (In x l) /\ P x} + {forall x, In x l -> ¬ P x}.
+Proof.
+induction l as [|x l].
+- right. tauto.
+- case_eq (P x); intro Heq.
+  + left. exists x. split; auto with *.
+  + destruct IHl as [(y & Hin & Hy)|Hf].
+    * left. exists y. split; auto with *.
+    * right. simpl. intros z [Hz|Hz]; subst; try rewrite Heq; auto with *.
+Defined.
+ +
+(* This function computes a proof tree of a sequent, if there is one, or produces a proof that there is none *)
+Proposition Proof_tree_dec Γ φ :
+  {_ : list_to_set_disj Γ φ & True} + {forall H : list_to_set_disj Γ φ, False}.
+Proof.
+(* duplicate *)
+Ltac l_tac := repeat rewrite list_to_set_disj_open_boxes;
+    rewrite (proper_Provable _ _ (list_to_set_disj_env_add _ _) _ _ eq_refl)
+|| rewrite (proper_Provable _ _ (equiv_disj_union_compat_r (list_to_set_disj_env_add _ _)) _ _ eq_refl)
+|| rewrite (proper_Provable _ _ (equiv_disj_union_compat_r (equiv_disj_union_compat_r (list_to_set_disj_env_add _ _))) _ _ eq_refl)
+|| rewrite (proper_Provable _ _ (equiv_disj_union_compat_r(equiv_disj_union_compat_r (equiv_disj_union_compat_r (list_to_set_disj_env_add _ _)))) _ _ eq_refl).
+remember (Γ, φ) as pe.
+replace Γ with pe.1 by now inversion Heqpe.
+replace φ with pe.2 by now inversion Heqpe. clear Heqpe Γ φ.
+revert pe.
+refine (@well_founded_induction _ _ wf_pointed_order _ _).
+intros (Γ& φ) Hind; simpl.
+assert(Hind' := λ Γ' φ', Hind(Γ', φ')). simpl in Hind'. clear Hind. rename Hind' into Hind.
+ +
+case (decide ( Γ)); intro Hbot.
+{ left. eexists; trivial. apply elem_of_list_to_set_disj in Hbot. exhibit Hbot 0. apply ExFalso. }
+assert(HAndR : {φ1 & {φ2 & φ = (And φ1 φ2)}} + { φ1 φ2, φ (And φ1 φ2)}) by (destruct φ; eauto).
+destruct HAndR as [(φ1 & φ2 & Heq) | HAndR].
+{ subst.
+  destruct (Hind Γ φ1) as [(Hp1&_) | H1]. order_tac.
+  - destruct (Hind Γ φ2) as [(Hp2&_) | H2]. order_tac.
+    + left. eexists; trivial. apply AndR; assumption.
+    + right. intro Hp. apply AndR_rev in Hp. tauto.
+  - right. intro Hp. apply AndR_rev in Hp. tauto.
+}
+assert(Hvar : {p & φ = Var p & Var p Γ} + { p, φ = Var p -> Var p Γ -> False}). {
+  destruct φ. 2-6: right; auto with *.
+  case (decide (Var v Γ)); intro Hin.
+  - left. exists v; trivial.
+  - right; auto with *. }
+destruct Hvar as [[p Heq Hp]|Hvar].
+{ subst. left. eexists; trivial. apply elem_of_list_to_set_disj in Hp. exhibit Hp 0. apply Atom. }
+assert(HAndL : {ψ1 & {ψ2 & (And ψ1 ψ2) Γ}} + { ψ1 ψ2, (And ψ1 ψ2) Γ -> False}). {
+  pose (fA := (fun θ => match θ with |And _ _ => true | _ => false end)).
+  destruct (exists_dec fA Γ) as [(θ & Hin & ) | Hf].
+  - left. subst fA. destruct θ. 3: { eexists. eexists. apply elem_of_list_In. eauto. }
+    all: auto with *.
+  - right. intros ψ1 ψ2 Hψ. rewrite elem_of_list_In in Hψ. apply Hf in Hψ. subst fA. simpl in Hψ. tauto.
+}
+destruct HAndL as [(ψ1 & ψ2 & Hin)|HAndL].
+{ destruct (Hind (ψ1 :: ψ2 :: rm (And ψ1 ψ2) Γ) φ) as [[Hp' _] | Hf]. order_tac.
+  - left. eexists; trivial. apply elem_of_list_to_set_disj in Hin.
+    exhibit Hin 0.
+    rewrite (proper_Provable _ _ (equiv_disj_union_compat_r (list_to_set_disj_rm _ _)) _ _ eq_refl).
+    apply AndL. peapply Hp'.
+ - right. intro Hf'. apply Hf.
+   rw (symmetry (list_to_set_disj_env_add (ψ2 :: rm (And ψ1 ψ2) Γ) ψ1)) 0.
+   rw (symmetry (list_to_set_disj_env_add (rm (And ψ1 ψ2) Γ) ψ2)) 1.
+   exch 0. apply AndL_rev.
+   rw (symmetry (list_to_set_disj_rm Γ(And ψ1 ψ2))) 1.
+   apply elem_of_list_to_set_disj in Hin.
+   pose (difference_singleton (list_to_set_disj Γ) (And ψ1 ψ2)).
+   peapply Hf'.
+}
+assert(HImpR : {φ1 & {φ2 & φ = (Implies φ1 φ2)}} + { φ1 φ2, φ (Implies φ1 φ2)}) by (destruct φ; eauto).
+destruct HImpR as [(φ1 & φ2 & Heq) | HImpR].
+{ subst.
+  destruct (Hind (φ1 :: Γ) φ2) as [(Hp1&_) | H1]. order_tac.
+  - left. eexists; trivial. apply ImpR. peapply Hp1.
+  - right. intro Hf. apply H1. apply ImpR_rev in Hf. peapply Hf.
+}
+assert(HOrL : {ψ1 & {ψ2 & (Or ψ1 ψ2) Γ}} + { ψ1 ψ2, (Or ψ1 ψ2) Γ -> False}). {
+  pose (fA := (fun θ => match θ with |Or _ _ => true | _ => false end)).
+  destruct (exists_dec fA Γ) as [(θ & Hin & ) | Hf].
+  - left. subst fA. destruct θ. 4: { eexists. eexists. apply elem_of_list_In. eauto. }
+    all: auto with *.
+  - right. intros ψ1 ψ2 Hψ. rewrite elem_of_list_In in Hψ. apply Hf in Hψ. subst fA. simpl in Hψ. tauto.
+}
+destruct HOrL as [(ψ1 & ψ2 & Hin)|HOrL].
+{ apply elem_of_list_to_set_disj in Hin.
+  destruct (Hind (ψ1 :: rm (Or ψ1 ψ2) Γ) φ) as [[Hp1 _] | Hf]. order_tac.
+  - destruct (Hind (ψ2 :: rm (Or ψ1 ψ2) Γ) φ) as [[Hp2 _] | Hf]. order_tac.
+    + left. eexists; trivial. exhibit Hin 0.
+         rewrite (proper_Provable _ _ (equiv_disj_union_compat_r (list_to_set_disj_rm _ _)) _ _ eq_refl).
+         apply OrL. peapply Hp1. peapply Hp2.
+    + right; intro Hf'. assert(Hf'' :list_to_set_disj (rm (Or ψ1 ψ2) Γ) Or ψ1 ψ2 φ). {
+          rw (symmetry (list_to_set_disj_rm Γ(Or ψ1 ψ2))) 1.
+          pose (difference_singleton (list_to_set_disj Γ) (Or ψ1 ψ2)). peapply Hf'.
+         }
+        apply OrL_rev in Hf''. apply Hf. peapply Hf''.
+  - right; intro Hf'. assert(Hf'' :list_to_set_disj (rm (Or ψ1 ψ2) Γ) Or ψ1 ψ2 φ). {
+          rw (symmetry (list_to_set_disj_rm Γ(Or ψ1 ψ2))) 1.
+          pose (difference_singleton (list_to_set_disj Γ) (Or ψ1 ψ2)). peapply Hf'.
+         }
+        apply OrL_rev in Hf''. apply Hf. peapply Hf''.1.
+}
+assert(HImpLVar : {p & {ψ & Var p Γ /\ (Implies (Var p) ψ) Γ}} +
+                                 { p ψ, Var p Γ -> (Implies (Var p) ψ) Γ -> False}). {
+  pose (fIp :=λ p θ, match θ with | Implies (Var q) _ => if decide (p = q) then true else false | _ => false end).
+  pose (fp:= (fun θ => match θ with |Var p => if (exists_dec (fIp p) Γ) then true else false | _ => false end)).
+  destruct (exists_dec fp Γ) as [(θ & Hin & ) | Hf].
+  - left. subst fp. destruct θ. 2-6: auto with *.
+    case exists_dec as [(ψ &Hinψ & Hψ)|] in ; [|auto with *].
+    unfold fIp in Hψ. destruct ψ. 1-4, 6: auto with *.
+    destruct ψ1. 2-6: auto with *. case decide in Hψ; [|auto with *].
+    subst. apply elem_of_list_In in Hinψ, Hin.
+    do 2 eexists. split; eauto.
+  - right. intros p ψ Hp Hψ. rewrite elem_of_list_In in Hp, Hψ. apply Hf in Hp. subst fp fIp.
+    simpl in Hp. case exists_dec as [|Hf'] in Hp. auto with *.
+    apply (Hf' _ Hψ). rewrite decide_True; trivial. auto with *.
+}
+destruct HImpLVar as [[p [ψ [Hinp Hinψ]]]|HImpLVar].
+{ apply elem_of_list_to_set_disj in Hinp.
+  apply elem_of_list_to_set_disj in Hinψ.
+  assert(Hinp' : Var p (list_to_set_disj Γ {[Implies p ψ]} : env))
+    by (apply in_difference; [discriminate| assumption]).
+  destruct (Hind:: rm (Implies (Var p) ψ) Γ) φ) as [[Hp _]|Hf]. order_tac.
+  - left. eexists; trivial. exhibit Hinψ 0.
+     exhibit Hinp' 1. apply ImpLVar.
+     rw (symmetry (difference_singleton (list_to_set_disj Γ {[Implies p ψ]}) (Var p) Hinp')) 1.
+     rw (list_to_set_disj_rm Γ(Implies p ψ)) 1. l_tac. exact Hp.
+  - right. intro Hf'. apply Hf.
+     rw (symmetry (list_to_set_disj_env_add (rm (Implies p ψ) Γ) ψ)) 0.
+     rw (symmetry (list_to_set_disj_rm Γ(Implies p ψ))) 1.
+     exhibit Hinp' 1. apply ImpLVar_rev.
+     rw (symmetry (difference_singleton _ _ Hinp')) 1.
+     rw (symmetry (difference_singleton _ _ Hinψ)) 0.
+     exact Hf'.
+}
+assert(HImpLAnd : {φ1 & {φ2 & {φ3 & (Implies (And φ1 φ2) φ3) Γ}}} +
+                                 { φ1 φ2 φ3, (Implies (And φ1 φ2) φ3) Γ -> False}). {
+    pose (fII := (fun θ => match θ with |Implies (And _ _) _ => true | _ => false end)).
+   destruct (exists_dec fII Γ) as [(θ & Hin & ) | Hf].
+    - left. subst fII. destruct θ. 1-4, 6: auto with *.
+      destruct θ1. 1-2,4-6: auto with *. do 3 eexists; apply elem_of_list_In; eauto.
+    - right. intros ψ1 ψ2 ψ3 Hψ. rewrite elem_of_list_In in Hψ. apply Hf in Hψ. subst fII. simpl in Hψ. tauto.
+}
+destruct HImpLAnd as [(φ1&φ2&φ3&Hin)|HImpLAnd].
+{ apply elem_of_list_to_set_disj in Hin.
+  destruct (Hind (Implies φ1 (Implies φ2 φ3) :: rm (Implies (And φ1 φ2) φ3) Γ) φ) as [[Hp _]|Hf]. order_tac.
+  - left. eexists; trivial. exhibit Hin 0. apply ImpLAnd.
+     rw (list_to_set_disj_rm Γ(Implies (And φ1 φ2) φ3)) 1. l_tac. exact Hp.
+  - right. intro Hf'. apply Hf.
+     rw (symmetry (list_to_set_disj_env_add (rm (Implies (And φ1 φ2) φ3) Γ) (Implies φ1 (Implies φ2 φ3)))) 0.
+     rw (symmetry (list_to_set_disj_rm Γ(Implies (And φ1 φ2) φ3))) 1.
+     apply ImpLAnd_rev.
+     rw (symmetry (difference_singleton _ _ Hin)) 0. exact Hf'.
+}
+assert(HImpLOr : {φ1 & {φ2 & {φ3 & (Implies (Or φ1 φ2) φ3) Γ}}} +
+                                 { φ1 φ2 φ3, (Implies (Or φ1 φ2) φ3) Γ -> False}). {
+    pose (fII := (fun θ => match θ with |Implies (Or _ _) _ => true | _ => false end)).
+   destruct (exists_dec fII Γ) as [(θ & Hin & ) | Hf].
+    - left. subst fII. destruct θ. 1-4, 6: auto with *.
+      destruct θ1. 1-3, 5-6: auto with *. do 3 eexists; apply elem_of_list_In; eauto.
+    - right. intros ψ1 ψ2 ψ3 Hψ. rewrite elem_of_list_In in Hψ. apply Hf in Hψ. subst fII. simpl in Hψ. tauto.
+}
+destruct HImpLOr as [(φ1&φ2&φ3&Hin)|HImpLOr].
+{ apply elem_of_list_to_set_disj in Hin.
+  destruct (Hind (Implies φ2 φ3 :: Implies φ1 φ3 :: rm (Implies (Or φ1 φ2) φ3) Γ) φ) as [[Hp _]|Hf]. order_tac.
+  - left. eexists; trivial. exhibit Hin 0. apply ImpLOr.
+     rw (list_to_set_disj_rm Γ(Implies (Or φ1 φ2) φ3)) 2. do 2 l_tac. exact Hp.
+  - right. intro Hf'. apply Hf.
+     rw (symmetry (list_to_set_disj_env_add ( Implies φ1 φ3 :: rm (Implies (Or φ1 φ2) φ3) Γ) (Implies φ2 φ3))) 0.
+     rw (symmetry (list_to_set_disj_env_add (rm (Implies (Or φ1 φ2) φ3) Γ) (Implies φ1 φ3))) 1.
+     rw (symmetry (list_to_set_disj_rm Γ(Implies (Or φ1 φ2) φ3))) 2.
+     apply ImpLOr_rev.
+     rw (symmetry (difference_singleton _ _ Hin)) 0. exact Hf'.
+}
+(* non invertible right rules *)
+assert(HOrR1 : {φ1 & {φ2 & {Hp : (list_to_set_disj Γ φ1) & φ = (Or φ1 φ2)}}} +
+                       { φ1 φ2, (H : list_to_set_disj Γ φ1), φ = (Or φ1 φ2) -> False}).
+{
+  destruct φ. 4: { destruct (Hind Γ φ1)as [[Hp _]|Hf]. order_tac.
+  - left. do 3 eexists; eauto.
+  - right. intros ? ? Hp Heq. inversion Heq. subst. tauto.
+  }
+  all: right; auto with *.
+}
+destruct HOrR1 as [(φ1 & φ2 & Hp & Heq)| HOrR1].
+{ subst. left. eexists; trivial. apply OrR1, Hp. }
+assert(HOrR2 : {φ1 & {φ2 & {Hp : (list_to_set_disj Γ φ2) & φ = (Or φ1 φ2)}}} +
+                       { φ1 φ2, (H : list_to_set_disj Γ φ2), φ = (Or φ1 φ2) -> False}).
+{
+  destruct φ. 4: { destruct (Hind Γ φ2)as [[Hp _]|Hf]. order_tac.
+  - left. do 3 eexists; eauto.
+  - right. intros ? ? Hp Heq. inversion Heq. subst. tauto.
+  }
+  all: right; auto with *.
+}
+destruct HOrR2 as [(φ1 & φ2 & Hp & Heq)| HOrR2 ].
+{ subst. left. eexists; trivial. apply OrR2, Hp. }
+assert(HBoxR : {φ' & {Hp : ( (list_to_set_disj Γ) φ' φ') & φ = ( φ')}} +
+                       { φ', (H : (list_to_set_disj Γ) φ' φ'), φ = ( φ') -> False}).
+{
+  destruct φ. 6: { destruct (Hind (( φ) :: map open_box Γ) φ)as [[Hp _]|Hf]. order_tac.
+  - left. do 2 eexists; eauto. l_tac. exact Hp.
+  - right. intros ? Hp Heq. inversion Heq. subst. apply Hf.
+     rw (symmetry (list_to_set_disj_env_add (map open_box Γ) ( φ'))) 0.
+     rewrite <- list_to_set_disj_open_boxes. exact Hp.
+  }
+  all: right; auto with *.
+}
+destruct HBoxR as [(φ' & Hp & Heq)| HBoxR ].
+{ left. subst. eexists; trivial. apply BoxR, Hp. }
+assert(Hempty: (Δ : env) φ,((Δ φ) = ) -> False).
+{
+  intros Δ θ Heq. assert (Hm:= multiplicity_empty θ).
+  unfold base.empty in *.
+  rewrite <- Heq, union_mult, singleton_mult_in in Hm by trivial. lia.
+}
+(* non invertible left rules *)
+assert(HImpLImp : Γ2 Γ1, Γ1 ++ Γ2 = Γ -> {φ1 & {φ2 & {φ3 &{H2312 : ((list_to_set_disj (rm (Implies (Implies φ1 φ2) φ3) Γ) (Implies φ2 φ3)) (Implies φ1 φ2))
+                                          & {H3: (list_to_set_disj (rm (Implies (Implies φ1 φ2) φ3) Γ) φ3 φ) & (Implies (Implies φ1 φ2) φ3) Γ2}}}}} +
+    { φ1 φ2 φ3 (_ : (list_to_set_disj (rm (Implies (Implies φ1 φ2) φ3) Γ) (Implies φ2 φ3)) (Implies φ1 φ2))
+                              (_: list_to_set_disj (rm (Implies (Implies φ1 φ2) φ3) Γ) φ3 φ),
+                               Implies (Implies φ1 φ2) φ3 Γ2 False}).
+{
+  induction Γ2 as [|θ Γ2]; intros Γ1 Heq.
+  - right. intros φ1 φ2 φ3 _ _ Hin. inversion Hin.
+  - assert(Heq' : (Γ1 ++ [θ]) ++ Γ2 = Γ) by (subst; auto with *).
+    destruct (IHΓ2 (Γ1 ++ [θ]) Heq') as [(φ1 & φ2 & φ3 & Hp1 & Hp2 & Hin)|Hf].
+   + left. repeat eexists; eauto. now right.
+   + destruct θ.
+        5: destruct θ1.
+        9 : {
+        destruct (Hind (Implies θ1_2 θ2 :: rm (Implies (Implies θ1_1 θ1_2) θ2) Γ) (Implies θ1_1 θ1_2))
+          as [[Hp1 _] | Hf'].
+        - order_tac. rewrite <- Permutation_middle. unfold rm.
+          destruct form_eq_dec; [|tauto]. order_tac.
+        - destruct (Hind (θ2 :: rm (Implies (Implies θ1_1 θ1_2) θ2) Γ) φ) as [[Hp2 _] | Hf''].
+          + order_tac. rewrite <- Permutation_middle. unfold rm.
+               destruct form_eq_dec; [|tauto]. order_tac.
+          + left. repeat eexists; try l_tac; eauto. ms.
+          + right; intros φ1 φ2 φ3 Hp1' Hp2 He; apply elem_of_list_In in He;
+               destruct He as [Heq''| Hin]; [|apply elem_of_list_In in Hin; eapply Hf; eauto].
+               inversion Heq''. subst. apply Hf''. peapply Hp2.
+      - right; intros φ1 φ2 φ3 Hp1 Hp2 He; apply elem_of_list_In in He;
+               destruct He as [Heq''| Hin]; [|apply elem_of_list_In in Hin; eapply Hf; eauto].
+               inversion Heq''. subst. apply Hf'. peapply Hp1.
+        }
+        all: (right; intros φ1 φ2 φ3 Hp1 Hp2 He; apply elem_of_list_In in He; destruct He as [Heq''| Hin];
+     [discriminate|apply elem_of_list_In in Hin; eapply Hf; eauto]).
+}
+destruct (HImpLImp Γ [] (app_nil_l _)) as [(φ1 & φ2 & φ3 & Hp1 & Hp2 & Hin)|HfImpl].
+{ apply elem_of_list_to_set_disj in Hin.
+  left. eexists; trivial. exhibit Hin 0. rw (list_to_set_disj_rm Γ(Implies (Implies φ1 φ2) φ3)) 1.
+  apply ImpLImp; assumption.
+}
+(* ImpBox *)
+assert(HImpLBox : Γ2 Γ1, Γ1 ++ Γ2 = Γ -> {φ1 & {φ2 & {H2312 : ((⊗(list_to_set_disj ((rm (Implies ( φ1) φ2) Γ))) φ1 φ2) φ1)
+                                          & {H3: (list_to_set_disj (rm (Implies ( φ1) φ2) Γ) φ2 φ) & (Implies ( φ1) φ2) Γ2}}}} +
+    { φ1 φ2 (_ : (( (list_to_set_disj ((rm (Implies ( φ1) φ2) Γ))) φ1 φ2) φ1))
+                              (_: list_to_set_disj (rm (Implies ( φ1) φ2) Γ) φ2 φ),
+                               Implies ( φ1) φ2 Γ2 False}).
+{
+  induction Γ2 as [|θ Γ2]; intros Γ1 Heq.
+  - right. intros φ1 φ2 _ _ Hin. inversion Hin.
+  - assert(Heq' : (Γ1 ++ [θ]) ++ Γ2 = Γ) by (subst; auto with *).
+    destruct (IHΓ2 (Γ1 ++ [θ]) Heq') as [(φ1 & φ2 & Hp1 & Hp2 & Hin)|Hf].
+   + left. repeat eexists; eauto. now right.
+   + destruct θ.
+        5: destruct θ1.
+        10 : {
+        destruct (Hind (θ2 :: (θ1) :: map open_box (rm (Implies ( θ1) θ2) Γ)) θ1)
+          as [[Hp1 _] | Hf'].
+        - order_tac. rewrite <- Permutation_middle. unfold rm.
+          destruct form_eq_dec; [|tauto]. order_tac.
+        - destruct (Hind (θ2 :: rm (Implies ( θ1) θ2) Γ) φ) as [[Hp2 _] | Hf''].
+          + order_tac. rewrite <- Permutation_middle. unfold rm.
+              destruct form_eq_dec; [|tauto]. order_tac.
+          + left. repeat eexists; repeat l_tac; eauto. ms.
+          + right; intros φ1 φ2 Hp1' Hp2 He; apply elem_of_list_In in He;
+               destruct He as [Heq''| Hin]; [|apply elem_of_list_In in Hin; eapply Hf; eauto].
+               inversion Heq''. subst. apply Hf''. peapply Hp2.
+      - right; intros φ1 φ2 Hp1 Hp2 He; apply elem_of_list_In in He;
+               destruct He as [Heq''| Hin]; [|apply elem_of_list_In in Hin; eapply Hf; eauto].
+               inversion Heq''. subst. apply Hf'.
+             (erewrite proper_Provable; [| |reflexivity]); [eapply Hp1|].
+             repeat rewrite <- ?list_to_set_disj_env_add, list_to_set_disj_open_boxes. trivial.
+        }
+        all: (right; intros φ1 φ2 Hp1 Hp2 He; apply elem_of_list_In in He; destruct He as [Heq''| Hin];
+     [discriminate|apply elem_of_list_In in Hin; eapply Hf; eauto]).
+}
+destruct (HImpLBox Γ [] (app_nil_l _)) as [(φ1 & φ2 & Hp1 & Hp2 & Hin)|HfImpLBox].
+{ apply elem_of_list_to_set_disj in Hin.
+  left. eexists; trivial. exhibit Hin 0. rw (list_to_set_disj_rm Γ(Implies ( φ1) φ2)) 1.
+  apply ImpBox; assumption.
+}
+clear Hind HImpLImp HImpLBox.
+right.
+Ltac eqt := match goal with | H : (_ ) = list_to_set_disj ?Γ |- _ =>
+  let Heq := fresh "Heq" in assert(Heq := H);
+  assert(Hinφ : φ Γ) by (apply elem_of_list_to_set_disj; setoid_rewrite <- H; ms);
+  apply env_equiv_eq, env_add_inv', symmetry in Heq; rewrite list_to_set_disj_rm in Heq end.
+intro Hp. inversion Hp; subst; try eqt; eauto 2.
+- eapply HAndR; eauto.
+- eapply HImpR; eauto.
+- eapply HImpLVar; eauto. apply elem_of_list_to_set_disj. setoid_rewrite <- H; ms.
+- eapply HfImpl; eauto.
+  + now rw Heq 1.
+  + now rw Heq 1.
+- eapply HfImpLBox; eauto.
+  + now rw (proper_open_boxes _ _ Heq) 2.
+  + now rw Heq 1.
+Defined.
+ +
+(* This function decides whether a sequent is provable *)
+Proposition Provable_dec Γ φ :
+  (exists _ : list_to_set_disj Γ φ, True) + (forall H : list_to_set_disj Γ φ, False).
+Proof.
+remember (Γ, φ) as pe.
+replace Γ with pe.1 by now inversion Heqpe.
+replace φ with pe.2 by now inversion Heqpe. clear Heqpe Γ φ.
+revert pe.
+refine (@well_founded_induction _ _ wf_pointed_order _ _).
+intros (Γ& φ) Hind; simpl.
+assert(Hind' := λ Γ' φ', Hind(Γ', φ')). simpl in Hind'. clear Hind. rename Hind' into Hind.
+ +
+case (decide ( Γ)); intro Hbot.
+{ left. eexists; trivial. apply elem_of_list_to_set_disj in Hbot. exhibit Hbot 0. apply ExFalso. }
+assert(HAndR : {φ1 & {φ2 & φ = (And φ1 φ2)}} + { φ1 φ2, φ (And φ1 φ2)}) by (destruct φ; eauto).
+destruct HAndR as [(φ1 & φ2 & Heq) | HAndR].
+{ subst.
+  destruct (Hind Γ φ1) as [Hp1| H1]. order_tac.
+  - destruct (Hind Γ φ2) as [Hp2| H2]. order_tac.
+    + left. destruct Hp1, Hp2. eexists; trivial. apply AndR; assumption.
+    + right. intro Hp. apply AndR_rev in Hp. tauto.
+  - right. intro Hp. apply AndR_rev in Hp. tauto.
+}
+assert(Hvar : {p & φ = Var p & Var p Γ} + { p, φ = Var p -> Var p Γ -> False}). {
+  destruct φ. 2-6: right; auto with *.
+  case (decide (Var v Γ)); intro Hin.
+  - left. exists v; trivial.
+  - right; auto with *. }
+destruct Hvar as [[p Heq Hp]|Hvar].
+{ subst. left. eexists; trivial. apply elem_of_list_to_set_disj in Hp. exhibit Hp 0. apply Atom. }
+assert(HAndL : {ψ1 & {ψ2 & (And ψ1 ψ2) Γ}} + { ψ1 ψ2, (And ψ1 ψ2) Γ -> False}). {
+  pose (fA := (fun θ => match θ with |And _ _ => true | _ => false end)).
+  destruct (exists_dec fA Γ) as [(θ & Hin & ) | Hf].
+  - left. subst fA. destruct θ. 3: { eexists. eexists. apply elem_of_list_In. eauto. }
+    all: auto with *.
+  - right. intros ψ1 ψ2 Hψ. rewrite elem_of_list_In in Hψ. apply Hf in Hψ. subst fA. simpl in Hψ. tauto.
+}
+destruct HAndL as [(ψ1 & ψ2 & Hin)|HAndL].
+{ destruct (Hind (ψ1 :: ψ2 :: rm (And ψ1 ψ2) Γ) φ) as [Hp' | Hf]. order_tac.
+  - left. destruct Hp' as [Hp' _]. eexists; trivial. apply elem_of_list_to_set_disj in Hin.
+    exhibit Hin 0.
+    rewrite (proper_Provable _ _ (equiv_disj_union_compat_r (list_to_set_disj_rm _ _)) _ _ eq_refl).
+    apply AndL. peapply Hp'.
+ - right. intro Hf'. apply Hf.
+   rw (symmetry (list_to_set_disj_env_add (ψ2 :: rm (And ψ1 ψ2) Γ) ψ1)) 0.
+   rw (symmetry (list_to_set_disj_env_add (rm (And ψ1 ψ2) Γ) ψ2)) 1.
+   exch 0. apply AndL_rev.
+   rw (symmetry (list_to_set_disj_rm Γ(And ψ1 ψ2))) 1.
+   apply elem_of_list_to_set_disj in Hin.
+   pose (difference_singleton (list_to_set_disj Γ) (And ψ1 ψ2)).
+   peapply Hf'.
+}
+assert(HImpR : {φ1 & {φ2 & φ = (Implies φ1 φ2)}} + { φ1 φ2, φ (Implies φ1 φ2)}) by (destruct φ; eauto).
+destruct HImpR as [(φ1 & φ2 & Heq) | HImpR].
+{ subst.
+  destruct (Hind (φ1 :: Γ) φ2) as [Hp1| H1]. order_tac.
+  - left. destruct Hp1 as [Hp1 _]. eexists; trivial. apply ImpR. peapply Hp1.
+  - right. intro Hf. apply H1. apply ImpR_rev in Hf. peapply Hf.
+}
+assert(HOrL : {ψ1 & {ψ2 & (Or ψ1 ψ2) Γ}} + { ψ1 ψ2, (Or ψ1 ψ2) Γ -> False}). {
+  pose (fA := (fun θ => match θ with |Or _ _ => true | _ => false end)).
+  destruct (exists_dec fA Γ) as [(θ & Hin & ) | Hf].
+  - left. subst fA. destruct θ. 4: { eexists. eexists. apply elem_of_list_In. eauto. }
+    all: auto with *.
+  - right. intros ψ1 ψ2 Hψ. rewrite elem_of_list_In in Hψ. apply Hf in Hψ. subst fA. simpl in Hψ. tauto.
+}
+destruct HOrL as [(ψ1 & ψ2 & Hin)|HOrL].
+{ apply elem_of_list_to_set_disj in Hin.
+  destruct (Hind (ψ1 :: rm (Or ψ1 ψ2) Γ) φ) as [Hp1| Hf]. order_tac.
+  - destruct (Hind (ψ2 :: rm (Or ψ1 ψ2) Γ) φ) as [Hp2| Hf]. order_tac.
+    + left. destruct Hp1 as [Hp1 _]. destruct Hp2 as [Hp2 _]. eexists; trivial. exhibit Hin 0.
+         rewrite (proper_Provable _ _ (equiv_disj_union_compat_r (list_to_set_disj_rm _ _)) _ _ eq_refl).
+         apply OrL. peapply Hp1. peapply Hp2.
+    + right; intro Hf'. assert(Hf'' :list_to_set_disj (rm (Or ψ1 ψ2) Γ) Or ψ1 ψ2 φ). {
+          rw (symmetry (list_to_set_disj_rm Γ(Or ψ1 ψ2))) 1.
+          pose (difference_singleton (list_to_set_disj Γ) (Or ψ1 ψ2)). peapply Hf'.
+         }
+        apply OrL_rev in Hf''. apply Hf. peapply Hf''.
+  - right; intro Hf'. assert(Hf'' :list_to_set_disj (rm (Or ψ1 ψ2) Γ) Or ψ1 ψ2 φ). {
+          rw (symmetry (list_to_set_disj_rm Γ(Or ψ1 ψ2))) 1.
+          pose (difference_singleton (list_to_set_disj Γ) (Or ψ1 ψ2)). peapply Hf'.
+         }
+        apply OrL_rev in Hf''. apply Hf. peapply Hf''.1.
+}
+assert(HImpLVar : {p & {ψ & Var p Γ /\ (Implies (Var p) ψ) Γ}} +
+                                 { p ψ, Var p Γ -> (Implies (Var p) ψ) Γ -> False}). {
+  pose (fIp :=λ p θ, match θ with | Implies (Var q) _ => if decide (p = q) then true else false | _ => false end).
+  pose (fp:= (fun θ => match θ with |Var p => if (exists_dec (fIp p) Γ) then true else false | _ => false end)).
+  destruct (exists_dec fp Γ) as [(θ & Hin & ) | Hf].
+  - left. subst fp. destruct θ. 2-6: auto with *.
+    case exists_dec as [(ψ &Hinψ & Hψ)|] in ; [|auto with *].
+    unfold fIp in Hψ. destruct ψ. 1-4, 6: auto with *.
+    destruct ψ1. 2-6: auto with *. case decide in Hψ; [|auto with *].
+    subst. apply elem_of_list_In in Hinψ, Hin.
+    do 2 eexists. split; eauto.
+  - right. intros p ψ Hp Hψ. rewrite elem_of_list_In in Hp, Hψ. apply Hf in Hp. subst fp fIp.
+    simpl in Hp. case exists_dec as [|Hf'] in Hp. auto with *.
+    apply (Hf' _ Hψ). rewrite decide_True; trivial. auto with *.
+}
+destruct HImpLVar as [[p [ψ [Hinp Hinψ]]]|HImpLVar].
+{ apply elem_of_list_to_set_disj in Hinp.
+  apply elem_of_list_to_set_disj in Hinψ.
+  assert(Hinp' : Var p (list_to_set_disj Γ {[Implies p ψ]} : env))
+    by (apply in_difference; [discriminate| assumption]).
+  destruct (Hind:: rm (Implies (Var p) ψ) Γ) φ) as [Hp|Hf]. order_tac.
+  - left. destruct Hp as [Hp _]. eexists; trivial. exhibit Hinψ 0.
+     exhibit Hinp' 1. apply ImpLVar.
+     rw (symmetry (difference_singleton (list_to_set_disj Γ {[Implies p ψ]}) (Var p) Hinp')) 1.
+     rw (list_to_set_disj_rm Γ(Implies p ψ)) 1. l_tac. exact Hp.
+  - right. intro Hf'. apply Hf.
+     rw (symmetry (list_to_set_disj_env_add (rm (Implies p ψ) Γ) ψ)) 0.
+     rw (symmetry (list_to_set_disj_rm Γ(Implies p ψ))) 1.
+     exhibit Hinp' 1. apply ImpLVar_rev.
+     rw (symmetry (difference_singleton _ _ Hinp')) 1.
+     rw (symmetry (difference_singleton _ _ Hinψ)) 0.
+     exact Hf'.
+}
+assert(HImpLAnd : {φ1 & {φ2 & {φ3 & (Implies (And φ1 φ2) φ3) Γ}}} +
+                                 { φ1 φ2 φ3, (Implies (And φ1 φ2) φ3) Γ -> False}). {
+    pose (fII := (fun θ => match θ with |Implies (And _ _) _ => true | _ => false end)).
+   destruct (exists_dec fII Γ) as [(θ & Hin & ) | Hf].
+    - left. subst fII. destruct θ. 1-4, 6: auto with *.
+      destruct θ1. 1-2,4-6: auto with *. do 3 eexists; apply elem_of_list_In; eauto.
+    - right. intros ψ1 ψ2 ψ3 Hψ. rewrite elem_of_list_In in Hψ. apply Hf in Hψ. subst fII. simpl in Hψ. tauto.
+}
+destruct HImpLAnd as [(φ1&φ2&φ3&Hin)|HImpLAnd].
+{ apply elem_of_list_to_set_disj in Hin.
+  destruct (Hind (Implies φ1 (Implies φ2 φ3) :: rm (Implies (And φ1 φ2) φ3) Γ) φ) as [Hp|Hf]. order_tac.
+  - left. destruct Hp as [Hp _]. eexists; trivial. exhibit Hin 0. apply ImpLAnd.
+     rw (list_to_set_disj_rm Γ(Implies (And φ1 φ2) φ3)) 1. l_tac. exact Hp.
+  - right. intro Hf'. apply Hf.
+     rw (symmetry (list_to_set_disj_env_add (rm (Implies (And φ1 φ2) φ3) Γ) (Implies φ1 (Implies φ2 φ3)))) 0.
+     rw (symmetry (list_to_set_disj_rm Γ(Implies (And φ1 φ2) φ3))) 1.
+     apply ImpLAnd_rev.
+     rw (symmetry (difference_singleton _ _ Hin)) 0. exact Hf'.
+}
+assert(HImpLOr : {φ1 & {φ2 & {φ3 & (Implies (Or φ1 φ2) φ3) Γ}}} +
+                                 { φ1 φ2 φ3, (Implies (Or φ1 φ2) φ3) Γ -> False}). {
+    pose (fII := (fun θ => match θ with |Implies (Or _ _) _ => true | _ => false end)).
+   destruct (exists_dec fII Γ) as [(θ & Hin & ) | Hf].
+    - left. subst fII. destruct θ. 1-4, 6: auto with *.
+      destruct θ1. 1-3, 5-6: auto with *. do 3 eexists; apply elem_of_list_In; eauto.
+    - right. intros ψ1 ψ2 ψ3 Hψ. rewrite elem_of_list_In in Hψ. apply Hf in Hψ. subst fII. simpl in Hψ. tauto.
+}
+destruct HImpLOr as [(φ1&φ2&φ3&Hin)|HImpLOr].
+{ apply elem_of_list_to_set_disj in Hin.
+  destruct (Hind (Implies φ2 φ3 :: Implies φ1 φ3 :: rm (Implies (Or φ1 φ2) φ3) Γ) φ) as [Hp|Hf]. order_tac.
+  - left. destruct Hp as [Hp _]. eexists; trivial. exhibit Hin 0. apply ImpLOr.
+     rw (list_to_set_disj_rm Γ(Implies (Or φ1 φ2) φ3)) 2. do 2 l_tac. exact Hp.
+  - right. intro Hf'. apply Hf.
+     rw (symmetry (list_to_set_disj_env_add ( Implies φ1 φ3 :: rm (Implies (Or φ1 φ2) φ3) Γ) (Implies φ2 φ3))) 0.
+     rw (symmetry (list_to_set_disj_env_add (rm (Implies (Or φ1 φ2) φ3) Γ) (Implies φ1 φ3))) 1.
+     rw (symmetry (list_to_set_disj_rm Γ(Implies (Or φ1 φ2) φ3))) 2.
+     apply ImpLOr_rev.
+     rw (symmetry (difference_singleton _ _ Hin)) 0. exact Hf'.
+}
+(* non invertible right rules *)
+assert(HOrR1 : {φ1 & {φ2 & (exists (_ : list_to_set_disj Γ φ1), φ = (Or φ1 φ2))}} +
+                       { φ1 φ2, (H : list_to_set_disj Γ φ1), φ = (Or φ1 φ2) -> False}).
+{
+  destruct φ. 4: { destruct (Hind Γ φ1)as [Hp|Hf]. order_tac.
+  - left. do 2 eexists. destruct Hp as [Hp _]. eexists; eauto.
+  - right. intros ? ? Hp Heq. inversion Heq. subst. tauto.
+  }
+  all: right; auto with *.
+}
+destruct HOrR1 as [(φ1 & φ2 & Hp)| HOrR1].
+{ left. destruct Hp as (Hp & Heq). subst. eexists; trivial. apply OrR1, Hp. }
+assert(HOrR2 : {φ1 & {φ2 & exists (_ : list_to_set_disj Γ φ2), φ = (Or φ1 φ2)}} +
+                       { φ1 φ2, (H : list_to_set_disj Γ φ2), φ = (Or φ1 φ2) -> False}).
+{
+  destruct φ. 4: { destruct (Hind Γ φ2)as [Hp|Hf]. order_tac.
+  - left. do 2 eexists. destruct Hp as [Hp _]; eauto.
+  - right. intros ? ? Hp Heq. inversion Heq. subst. tauto.
+  }
+  all: right; auto with *.
+}
+destruct HOrR2 as [(φ1 & φ2 & Hp)| HOrR2 ].
+{ left. destruct Hp as [Hp Heq]. subst. eexists; trivial. apply OrR2, Hp. }
+assert(HBoxR : {φ' & exists (_ : ( (list_to_set_disj Γ) φ' φ')), φ = ( φ')} +
+                       { φ', (H : (list_to_set_disj Γ) φ' φ'), φ = ( φ') -> False}).
+{
+  destruct φ. 6: { destruct (Hind (( φ) :: map open_box Γ) φ)as [Hp|Hf]. order_tac.
+  - left. eexists. destruct Hp as [Hp _]. eexists; eauto. l_tac. exact Hp.
+  - right. intros ? Hp Heq. inversion Heq. subst. apply Hf.
+     rw (symmetry (list_to_set_disj_env_add (map open_box Γ) ( φ'))) 0.
+     rewrite <- list_to_set_disj_open_boxes. exact Hp.
+  }
+  all: right; auto with *.
+}
+destruct HBoxR as [(φ' & Hp)| HBoxR ].
+{ left. destruct Hp as [Hp Heq]. subst. eexists; trivial. apply BoxR, Hp. }
+assert(Hempty: (Δ : env) φ,((Δ φ) = ) -> False).
+{
+  intros Δ θ Heq. assert (Hm:= multiplicity_empty θ).
+  unfold base.empty in *.
+  rewrite <- Heq, union_mult, singleton_mult_in in Hm by trivial. lia.
+}
+(* non invertible left rules *)
+assert(HImpLImp : Γ2 Γ1, Γ1 ++ Γ2 = Γ -> {φ1 & {φ2 & {φ3 & exists (_ : (list_to_set_disj (rm (Implies (Implies φ1 φ2) φ3) Γ) (Implies φ2 φ3)) (Implies φ1 φ2)),
+                                          exists (_: list_to_set_disj (rm (Implies (Implies φ1 φ2) φ3) Γ) φ3 φ), (Implies (Implies φ1 φ2) φ3) Γ2}}} +
+    { φ1 φ2 φ3 (_ : (list_to_set_disj (rm (Implies (Implies φ1 φ2) φ3) Γ) (Implies φ2 φ3)) (Implies φ1 φ2))
+                              (_: list_to_set_disj (rm (Implies (Implies φ1 φ2) φ3) Γ) φ3 φ),
+                               Implies (Implies φ1 φ2) φ3 Γ2 False}).
+{
+  induction Γ2 as [|θ Γ2]; intros Γ1 Heq.
+  - right. intros φ1 φ2 φ3 _ _ Hin. inversion Hin.
+  - assert(Heq' : (Γ1 ++ [θ]) ++ Γ2 = Γ) by (subst; auto with *).
+    destruct (IHΓ2 (Γ1 ++ [θ]) Heq') as [(φ1 & φ2 & φ3 & Hp)|Hf].
+   + left. do 3 eexists. destruct Hp as ( Hp1 & Hp2 & Hin). do 2 (eexists; eauto). now right.
+   + destruct θ.
+        5: destruct θ1.
+        9 : {
+        destruct (Hind (Implies θ1_2 θ2 :: rm (Implies (Implies θ1_1 θ1_2) θ2) Γ) (Implies θ1_1 θ1_2))
+          as [Hp1| Hf'].
+        - order_tac. rewrite <- Permutation_middle. unfold rm.
+          destruct form_eq_dec; [|tauto]. order_tac.
+        - destruct (Hind (θ2 :: rm (Implies (Implies θ1_1 θ1_2) θ2) Γ) φ) as [Hp2| Hf''].
+          + order_tac. rewrite <- Permutation_middle. unfold rm.
+               destruct form_eq_dec; [|tauto]. order_tac.
+          + left. do 3 eexists. destruct Hp1 as [Hp1 _]. destruct Hp2 as [Hp2 _].
+              eexists; try l_tac; eauto. ms.
+          + right; intros φ1 φ2 φ3 Hp1' Hp2 He; apply elem_of_list_In in He;
+               destruct He as [Heq''| Hin]; [|apply elem_of_list_In in Hin; eapply Hf; eauto].
+               inversion Heq''. subst. apply Hf''. peapply Hp2.
+      - right; intros φ1 φ2 φ3 Hp1 Hp2 He; apply elem_of_list_In in He;
+               destruct He as [Heq''| Hin]; [|apply elem_of_list_In in Hin; eapply Hf; eauto].
+               inversion Heq''. subst. apply Hf'. peapply Hp1.
+        }
+        all: (right; intros φ1 φ2 φ3 Hp1 Hp2 He; apply elem_of_list_In in He; destruct He as [Heq''| Hin];
+     [discriminate|apply elem_of_list_In in Hin; eapply Hf; eauto]).
+}
+destruct (HImpLImp Γ [] (app_nil_l _)) as [(φ1 & φ2 & φ3 & Hp1)|HfImpl].
+{ left. destruct Hp1 as (Hp1 & Hp2 & Hin). eexists; trivial.
+  apply elem_of_list_to_set_disj in Hin. exhibit Hin 0.
+  rw (list_to_set_disj_rm Γ(Implies (Implies φ1 φ2) φ3)) 1.
+  apply ImpLImp; assumption.
+}
+(* ImpBox *)
+assert(HImpLBox : Γ2 Γ1, Γ1 ++ Γ2 = Γ -> {φ1 & {φ2 & exists (_ : (⊗(list_to_set_disj ((rm (Implies ( φ1) φ2) Γ))) φ1 φ2) φ1),
+                                          exists (_ : list_to_set_disj (rm (Implies ( φ1) φ2) Γ) φ2 φ),
+                                          (Implies ( φ1) φ2) Γ2}} +
+    { φ1 φ2 (_ : (( (list_to_set_disj ((rm (Implies ( φ1) φ2) Γ))) φ1 φ2) φ1))
+                              (_: list_to_set_disj (rm (Implies ( φ1) φ2) Γ) φ2 φ),
+                               Implies ( φ1) φ2 Γ2 False}).
+{
+  induction Γ2 as [|θ Γ2]; intros Γ1 Heq.
+  - right. intros φ1 φ2 _ _ Hin. inversion Hin.
+  - assert(Heq' : (Γ1 ++ [θ]) ++ Γ2 = Γ) by (subst; auto with *).
+    destruct (IHΓ2 (Γ1 ++ [θ]) Heq') as [(φ1 & φ2 & Hp1)|Hf].
+   + left. do 2 eexists. destruct Hp1 as (Hp1 & Hp2 & Hin). do 2 (eexists; eauto). now right.
+   + destruct θ.
+        5: destruct θ1.
+        10 : {
+        destruct (Hind (θ2 :: (θ1) :: map open_box (rm (Implies ( θ1) θ2) Γ)) θ1)
+          as [Hp1|Hf'].
+        - order_tac. rewrite <- Permutation_middle. unfold rm.
+          destruct form_eq_dec; [|tauto]. order_tac.
+        - destruct (Hind (θ2 :: rm (Implies ( θ1) θ2) Γ) φ) as [Hp2| Hf''].
+          + order_tac. rewrite <- Permutation_middle. unfold rm.
+              destruct form_eq_dec; [|tauto]. order_tac.
+          + left. do 2 eexists. destruct Hp1 as [Hp1 _]. destruct Hp2 as [Hp2 _].
+               repeat eexists; repeat l_tac; eauto. ms.
+          + right; intros φ1 φ2 Hp1' Hp2 He; apply elem_of_list_In in He;
+               destruct He as [Heq''| Hin]; [|apply elem_of_list_In in Hin; eapply Hf; eauto].
+               inversion Heq''. subst. apply Hf''. peapply Hp2.
+      - right; intros φ1 φ2 Hp1 Hp2 He; apply elem_of_list_In in He;
+               destruct He as [Heq''| Hin]; [|apply elem_of_list_In in Hin; eapply Hf; eauto].
+               inversion Heq''. subst. apply Hf'.
+             (erewrite proper_Provable; [| |reflexivity]); [eapply Hp1|].
+             repeat rewrite <- ?list_to_set_disj_env_add, list_to_set_disj_open_boxes. trivial.
+        }
+        all: (right; intros φ1 φ2 Hp1 Hp2 He; apply elem_of_list_In in He; destruct He as [Heq''| Hin];
+     [discriminate|apply elem_of_list_In in Hin; eapply Hf; eauto]).
+}
+destruct (HImpLBox Γ [] (app_nil_l _)) as [(φ1 & φ2 & Hp1)|HfImpLBox].
+{ left. destruct Hp1 as (Hp1 & Hp2 & Hin). eexists; trivial.
+  apply elem_of_list_to_set_disj in Hin. exhibit Hin 0.
+  rw (list_to_set_disj_rm Γ(Implies ( φ1) φ2)) 1.
+  apply ImpBox; assumption.
+}
+clear Hind HImpLImp HImpLBox.
+right.
+intro Hp. inversion Hp; subst; try eqt; eauto 2.
+- eapply HAndR; eauto.
+- eapply HImpR; eauto.
+- eapply HImpLVar; eauto. apply elem_of_list_to_set_disj. setoid_rewrite <- H; ms.
+- eapply HfImpl; eauto.
+  + now rw Heq 1.
+  + now rw Heq 1.
+- eapply HfImpLBox; eauto.
+  + now rw (proper_open_boxes _ _ Heq) 2.
+  + now rw Heq 1.
+Defined.
+
+
+ +
+ + + diff --git a/ISL.Environments.html b/ISL.Environments.html new file mode 100644 index 0000000..b49a622 --- /dev/null +++ b/ISL.Environments.html @@ -0,0 +1,874 @@ + + + + + + + + + + + + + +
+
+

ISL.Environments

+ +
+
+ +
+

Overview: Environments

+ + +
+ + An environment is a multiset of formulas. We rely on stdpp multisets + mostly for their powerful multiset equivalence tactic. +
+ + Notion of wellfoundedness +
+
+Require Import Coq.Program.Wf.
+ +
+
+ +
+Stdpp implementation of multisets +
+
+Require Export stdpp.gmultiset.
+ +
+
+ +
+Our propositional formulas, including their countability. +
+
+Require Export ISL.Formulas.
+ +
+
+ +
+An environment is defined as a finite multiset of formulas +(in the sense of the stdpp library). +This requires decidable equality and countability of the underlying set. +
+
+Definition env := @gmultiset form form_eq_dec form_count.
+ +
+Global Instance singleton : Singleton form env := gmultiset_singleton.
+Global Instance singletonMS : SingletonMS form env := base.singleton.
+ +
+Global Hint Unfold mult empty singleton union intersection env : mset.
+(* useful notations :
+  { x } : singleton
+      ⊎ : disjoint union
+   \: difference (setminus)
+   { x; y; } union of singletons
+   {[+ x; y; +]} *disjoint* union of singletons
+      ⊂@ : include
+*)

+ +
+Definition empty := : env.
+ +
+Ltac ms :=
+  unfold base.singletonMS, singletonMS, base.empty, gmultiset_empty in *;
+  autounfold with mset in *;
+  autounfold with mset; multiset_solver.
+ +
+Global Instance proper_elem_of : Proper ((=) ==> (≡@{env}) ==> (fun x y => x <-> y)) elem_of.
+Proof. intros Γ Γ' Heq φ φ' Heq'. ms. Qed.
+ +
+Global Instance proper_disj_union : Proper ((≡@{env}) ==> (≡@{env}) ==> (≡@{env})) disj_union.
+Proof. intros Γ Γ' Heq Δ Δ' Heq'. ms. Qed.
+ +
+Global Notation "Γ • φ" := (disj_union Γ (base.singletonMS φ)) (at level 105, φ at level 85, left associativity).
+ +
+Lemma elements_env_add (Γ : env) φ : elements(Γ φ) ≡ₚ φ :: elements Γ.
+Proof.
+rewrite (gmultiset_elements_disj_union Γ).
+setoid_rewrite (gmultiset_elements_singleton φ).
+symmetry. apply Permutation_cons_append.
+Qed.
+ +
+
+ +
+

Multiset utilities

+ +
+
+ +
+Lemma multeq_meq (M N: env) : (forall x, multiplicity x M = multiplicity x N) -> M N.
+  Proof. multiset_solver. Qed.
+ +
+Lemma diff_mult (M N : env) (x : form):
+  multiplicity x (M N) = (multiplicity x M - multiplicity x N)%nat.
+Proof. apply multiplicity_difference. Qed.
+ +
+Lemma union_mult M N (x : form) :
+  multiplicity x (M N) = (multiplicity x M + multiplicity x N)%nat.
+Proof. apply multiplicity_disj_union. Qed.
+ +
+Lemma singleton_mult_in (x y: form): x = y -> multiplicity x {[y]} = 1.
+Proof.
+  intro Heq. rewrite Heq. apply multiplicity_singleton. Qed.
+ +
+Lemma singleton_mult_notin (x y: form): x <> y -> multiplicity x {[y]} = 0.
+Proof. apply multiplicity_singleton_ne. Qed.
+ +
+(* Two useful basic facts about multisets containing (or not) certain elements. *)
+Lemma env_replace {Γ : env} φ {ψ : form}:
+  (ψ Γ) -> (Γ φ) {[ψ]} (Γ {[ψ]} φ).
+Proof.
+intro Hin. apply multeq_meq. intros θ.
+rewrite diff_mult, union_mult, union_mult, diff_mult.
+apply PeanoNat.Nat.add_sub_swap.
+case (decide (θ = ψ)); intro; subst.
+- now rewrite singleton_mult_in.
+- rewrite singleton_mult_notin; trivial. lia.
+Qed.
+ +
+Lemma diff_not_in (Γ : env) φ : φ Γ -> Γ {[φ]} Γ.
+Proof.
+intro Hf. apply multeq_meq. intros ψ.
+rewrite diff_mult. rewrite (elem_of_multiplicity φ Γ) in Hf.
+unfold mult.
+case (decide= ψ)).
+- intro; subst. lia.
+- intro Hneq. setoid_rewrite (multiplicity_singleton_ne ψ φ); trivial. lia.
+  auto.
+Qed.
+ +
+Lemma env_add_remove : (Γ: env) (φ : form), (Γ φ) {[φ]} =Γ.
+Proof. intros; ms. Qed.
+ +
+
+ +
+

Conjunction, disjunction, and implication

+ In the construction of propositional quantifiers, we often want to take the conjunction, disjunction, or implication of a (multi)set of formulas. The following results give some small optimizations of this process, by reducing "obvious" conjunctions such as ⊤ ∧ ϕ, ⊥ ∧ ϕ, etc. +
+
+ +
+Definition irreducible (Γ : env) :=
+  ( p φ, (Var p φ) Γ -> ¬ Var p Γ) /\
+  ¬ Γ /\
+   φ ψ, ¬ (φ ψ) Γ /\ ¬ (φ ψ) Γ.
+ +
+Definition is_double_negation φ ψ := φ = ¬ ¬ ψ.
+Global Instance decidable_is_double_negation φ ψ : Decision (is_double_negation φ ψ) := decide= ¬ ¬ ψ).
+ +
+Definition is_implication φ ψ := exists θ, φ = (θ ψ).
+Global Instance decidable_is_implication φ ψ : Decision (is_implication φ ψ).
+Proof.
+unfold is_implication.
+destruct φ; try solve[right; intros [θ ]; discriminate].
+case (decide (φ2 = ψ)).
+- intro; subst. left. eexists; reflexivity.
+- intro. right; intros [θ ]; inversion . subst. tauto.
+Defined.
+ +
+Definition is_negation φ ψ := φ = ¬ ψ.
+Global Instance decidable_is_negation φ ψ : Decision (is_negation φ ψ) := decide= ¬ ψ).
+ +
+(* Checks "obvious" entailment conditions. If φ ⊢ ψ "obviously" then it returns Lt,
+if ψ ⊢ φ "obviously" then it returns Gt. Eq corresponds to the unknown category, 
+this means that we don't have enough information to determine a possible entailment. *)

+Fixpoint obviously_smaller (φ : form) (ψ : form) :=
+match (φ, ψ) with
+  |(Bot, _) => Lt
+  |(_, Bot) => Gt
+  |(Bot _, _) => Gt
+  |(_, Bot _) => Lt
+  |(φ ψ, ϴ) => match (obviously_smaller φ ϴ, obviously_smaller ψ ϴ) with
+      | (Lt, _) | (_, Lt) => Lt
+      | (Gt, Gt) => Gt
+      | _ => Eq
+      end
+  |(φ ψ, ϴ) => match (obviously_smaller φ ϴ, obviously_smaller ψ ϴ) with
+      | (Gt, _) | (_, Gt) => Gt
+      | (Lt, Lt) => Lt
+      | _ => Eq
+      end
+  |(φ, ψ) => if decide (φ = ψ) then Lt else
+                       if decide (is_double_negation φ ψ) then Gt else
+                       if decide (is_double_negation ψ φ) then Lt else
+                       if decide (is_implication φ ψ) then Gt else
+                       if decide (is_implication ψ φ ) then Lt else
+                       Eq
+end.
+ +
+Definition choose_conj φ ψ :=
+match obviously_smaller φ ψ with
+  | Lt => φ
+  | Gt => ψ
+  | Eq => φ ψ
end.
+ +
+Definition make_conj φ ψ :=
+match ψ with
+  | ψ1 ψ2 =>
+      match obviously_smaller φ ψ1 with
+      | Lt => φ ψ2
+      | Gt => ψ1 ψ2
+      | Eq => φ (ψ1 ψ2)
+      end
+  | ψ1 ψ2 =>
+      if decide (obviously_smaller φ ψ1 = Lt ) then φ
+      else if decide (obviously_smaller φ ψ2 = Lt ) then φ
+      else choose_conj φ (ψ1 ψ2)
+  | ψ1 ψ2 =>
+      if decide (obviously_smaller φ ψ1 = Lt) then choose_conj φ ψ2
+      else choose_conj φ ψ
+  | ψ => match φ with
+      | φ1 φ2 =>
+          if decide (obviously_smaller ψ φ1 = Lt)
+          then choose_conj φ2 ψ
+          else choose_conj φ ψ
+      | _ => choose_conj φ ψ
+       end
+end.
+ +
+Infix "⊼" := make_conj (at level 60).
+ +
+Lemma occurs_in_make_conj v φ ψ : occurs_in v (φ ψ) -> occurs_in v φ \/ occurs_in v ψ.
+Proof.
+generalize ψ.
+induction φ; intro ψ0; destruct ψ0;
+intro H; unfold make_conj in H; unfold choose_conj in H;
+repeat match goal with
+    | H: occurs_in _ (if ?cond then _ else _) |- _ => case decide in H
+    | H: occurs_in _ (match ?x with _ => _ end) |- _ => destruct x
+    | |- _ => simpl; simpl in H; tauto
+end.
+Qed.
+ +
+Definition choose_disj φ ψ :=
+match obviously_smaller φ ψ with
+  | Lt => ψ
+  | Gt => φ
+  | Eq =>match obviously_smaller ψ φ with
+    | Lt => φ
+    | Gt => ψ
+    | Eq => φ ψ
+    end
end.
+ +
+Definition make_disj φ ψ :=
+match ψ with
+  | ψ1 ψ2 =>
+      match obviously_smaller φ ψ1 with
+      | Lt => ψ1 ψ2
+      | Gt => φ ψ2
+      | Eq => φ (ψ1 ψ2)
+      end
+  | ψ1 ψ2 =>
+      if decide (obviously_smaller φ ψ1 = Gt ) then φ
+      else if decide (obviously_smaller φ ψ2 = Gt ) then φ
+      else choose_disj φ (ψ1 ψ2)
+  |_ => choose_disj φ ψ
+end.
+ +
+Infix "⊻" := make_disj (at level 65).
+ +
+Lemma occurs_in_make_disj v φ ψ : occurs_in v (φ ψ) -> occurs_in v φ occurs_in v ψ.
+Proof.
+generalize ψ.
+induction φ; intro ψ0; destruct ψ0;
+intro H; unfold make_disj in H; unfold choose_disj in H;
+repeat match goal with
+    | H: occurs_in _ (if ?cond then _ else _) |- _ => case decide in H
+    | H: occurs_in _ (match ?x with _ => _ end) |- _ => destruct x
+    | |- _ => simpl; simpl in H; tauto
+end.
+Qed.
+ +
+(* "lazy" implication, which produces a potentially simpler, equivalent formula *)
+ +
+(* Same as `simp_ors` but for nested implications. *)
+Fixpoint make_impl φ ψ :=
+match ψ with
+  |(ψ1 ψ2) => make_impl (make_conj φ ψ1) ψ2
+  |_ =>
+     if decide (obviously_smaller φ ψ = Lt) then
+     else if decide (obviously_smaller φ = Lt) then
+     else if decide (obviously_smaller ψ = Gt) then
+     else if decide (obviously_smaller φ = Gt) then ψ
+     else if decide (obviously_smaller ψ = Lt) then ¬φ
+     else if decide (is_negation φ ψ) then ¬φ
+     else if decide (is_negation ψ φ) then ψ
+    else φ ψ
+end.
+ +
+Infix "⇢" := make_impl (at level 66).
+ +
+Lemma occurs_in_make_impl v x y : occurs_in v (x y) -> occurs_in v x occurs_in v y.
+Proof.
+generalize x.
+induction y; intro ψ0;
+intro H; unfold make_impl in H; fold make_impl in H;
+repeat match goal with
+    | H: occurs_in _ (if ?cond then _ else _) |- _ => case decide in H
+    | H: occurs_in _ (match ?x with _ => _ end) |- _ => destruct x
+    | |- _ => simpl; simpl in H; tauto
+end.
+apply IHy2 in H. destruct H as [H|H]; [ apply occurs_in_make_conj in H|]; simpl; tauto.
+Qed.
+ +
+Lemma occurs_in_make_impl2 v x y z: occurs_in v (x (y z)) -> occurs_in v x occurs_in v y occurs_in v z.
+Proof.
+intro H. apply occurs_in_make_impl in H. destruct H as [H|H]; try tauto.
+apply occurs_in_make_impl in H. tauto.
+Qed.
+ +
+
+ +
+To be noted: we remove duplicates first +
+
+Definition conjunction l := foldl make_conj ( ) (nodup form_eq_dec l).
+Notation "⋀" := conjunction.
+ +
+Definition disjunction l := foldl make_disj (nodup form_eq_dec l).
+Notation "⋁" := disjunction.
+ +
+Lemma variables_conjunction x l : occurs_in x ( l) -> exists φ, φ l /\ occurs_in x φ.
+Proof.
+unfold conjunction.
+assert (Hcut : forall ψ, occurs_in x (foldl make_conj ψ (nodup form_eq_dec l))
+  -> occurs_in x ψ \/ ( φ : form, (φ l occurs_in x φ)%type)).
+{
+induction l; simpl.
+- tauto.
+- intros ψ Hocc.
+  case in_dec in Hocc; apply IHl in Hocc; simpl in Hocc;
+  destruct Hocc as [Hx|(φ&Hin&Hx)]; try tauto.
+  + right. exists φ. split; auto with *.
+  + apply occurs_in_make_conj in Hx; destruct Hx as [Hx|Hx]; auto with *.
+      right. exists a. auto with *.
+  + right. exists φ. split; auto with *.
+}
+intro Hocc. apply Hcut in Hocc. simpl in Hocc. tauto.
+Qed.
+ +
+Lemma variables_disjunction x l : occurs_in x ( l) -> exists φ, φ l /\ occurs_in x φ.
+Proof.
+unfold disjunction.
+assert (Hcut : forall ψ, occurs_in x (foldl make_disj ψ (nodup form_eq_dec l))
+  -> occurs_in x ψ \/ ( φ : form, (φ l occurs_in x φ)%type)).
+{
+induction l; simpl.
+- tauto.
+- intros ψ Hocc.
+  case in_dec in Hocc; apply IHl in Hocc; simpl in Hocc;
+  destruct Hocc as [Hx|(φ&Hin&Hx)]; try tauto.
+  + right. exists φ. split; auto with *.
+  + apply occurs_in_make_disj in Hx; destruct Hx as [Hx|Hx]; auto with *.
+      right. exists a. auto with *.
+  + right. exists φ. split; auto with *.
+}
+intro Hocc. apply Hcut in Hocc. simpl in Hocc. tauto.
+Qed.
+ +
+
+ +
+

A dependent version of `map`

+ +
+
+(* a dependent map on lists, with knowledge that we are on that list *)
+(* should work with any set-like type *)
+ +
+Program Fixpoint in_map_aux {A : Type} (Γ : list form) (f : forall φ, (φ Γ) -> A)
Γ' (HΓ' : Γ' Γ) : list A:=
+match Γ' with
+| [] => []
+| a::Γ' => f a _ :: in_map_aux Γ f Γ' _
+end.
+Next Obligation.
+intros. auto with *.
+Qed.
+Next Obligation. auto with *. Qed.
+ +
+Definition in_map {A : Type} (Γ : list form)
+  (f : forall φ, (φ Γ) -> A) : list A :=
+  in_map_aux Γ f Γ (reflexivity _).
+ +
+(* This generalises to any type. decidability of equality over this type is necessary for a result in "Type" *)
+Lemma in_in_map {A : Type} {HD : forall a b : A, Decision (a = b)}
+  Γ (f : forall φ, (φ Γ) -> A) ψ :
+  ψ (in_map Γ f) -> {ψ0 & {Hin | ψ = f ψ0 Hin}}.
+Proof.
+unfold in_map.
+assert(Hcut : forall Γ' (HΓ' : Γ' Γ), ψ in_map_aux Γ f Γ' HΓ'
+   {ψ0 & {Hin : ψ0 Γ | ψ = f ψ0 Hin}}); [|apply Hcut].
+induction Γ'; simpl; intros HΓ' Hin.
+- contradict Hin. auto. now rewrite elem_of_nil.
+- match goal with | H : ψ ?a :: (in_map_aux _ _ _ ?HΓ'') |- _ =>
+  case (decide= a)); [| pose (myHΓ' := HΓ'')] end.
+  + intro Heq; subst. exists a. eexists. reflexivity.
+  + intro Hneq. apply (IHΓ' myHΓ').
+    apply elem_of_cons in Hin. tauto.
+Qed.
+ +
+Local Definition in_subset {Γ : env} {Γ'} (Hi : Γ' elements Γ) {ψ0} (Hin : ψ0 Γ') : ψ0 Γ.
+Proof. apply gmultiset_elem_of_elements,Hi, Hin. Defined.
+ +
+(* converse *)
+(* we require proof irrelevance for the mapped function *)
+Lemma in_map_in {A : Type} {HD : forall a b : A, Decision (a = b)}
+  {Γ} {f : forall φ, (φ Γ) -> A} {ψ0} (Hin : ψ0 Γ):
+  {Hin' | f ψ0 Hin' (in_map Γ f)}.
+Proof.
+unfold in_map.
+assert(Hcut : forall Γ' (HΓ' : Γ' Γ) ψ0 (Hin : In ψ0 Γ'),
+  {Hin' | f ψ0 Hin' in_map_aux Γ f Γ' HΓ'}).
+- induction Γ'; simpl; intros HΓ' ψ' Hin'; [auto with *|].
+  case (decide (ψ' = a)).
+  + intro; subst a. eexists. left.
+  + intro Hneq. assert (Hin'' : In ψ' Γ') by (destruct Hin'; subst; tauto).
+      pose (Hincl := (in_map_aux_obligation_2 Γ (a :: Γ') HΓ' a Γ' eq_refl)).
+      destruct (IHΓ' Hincl ψ' Hin'') as [Hin0 Hprop].
+      eexists. right. apply Hprop.
+- destruct (Hcut Γ (reflexivity Γ) ψ0) as [Hin' Hprop].
+  + auto. now apply elem_of_list_In.
+  + exists Hin'. exact Hprop.
+Qed.
+ +
+Lemma in_map_empty A f : @in_map A [] f = [].
+Proof. auto with *. Qed.
+ +
+Lemma in_map_ext {A} Δ f g:
+  (forall φ H, f φ H = g φ H) -> @in_map A Δ f = in_map Δ g.
+Proof.
+  intros Heq.
+  unfold in_map.
+  assert(forall Γ , in_map_aux Δ f Γ = in_map_aux Δ g Γ ); [|trivial].
+  induction Γ; intro .
+  - trivial.
+  - simpl. now rewrite Heq, IHΓ.
+Qed.
+ +
+Lemma difference_singleton (Δ: env) (φ : form): φ Δ -> Δ ((Δ {[φ]}) φ).
+Proof.
+intro Hin. rewrite (gmultiset_disj_union_difference {[φ]}) at 1. ms.
+now apply gmultiset_singleton_subseteq_l.
+Qed.
+ +
+Lemma env_in_add (Δ : env) ϕ φ: φ (Δ ϕ) <-> φ = ϕ \/ φ Δ.
+Proof.
+rewrite (gmultiset_elem_of_disj_union Δ), gmultiset_elem_of_singleton.
+tauto.
+Qed.
+ +
+Lemma equiv_disj_union_compat_r {Δ Δ' Δ'' : env} : Δ Δ'' -> Δ Δ' Δ'' Δ'.
+Proof. ms. Qed.
+ +
+Lemma env_add_comm (Δ : env) φ ϕ : (Δ φ ϕ) (Δ ϕ φ).
+Proof. ms. Qed.
+ +
+Lemma in_difference (Δ : env) φ ψ : φ ψ -> φ Δ -> φ Δ {[ψ]}.
+Proof.
+intros Hne Hin.
+unfold elem_of, gmultiset_elem_of.
+rewrite (multiplicity_difference Δ {[ψ]} φ).
+assert( HH := multiplicity_singleton_ne φ ψ Hne).
+unfold singletonMS, base.singletonMS in HH.
+unfold base.singleton, Environments.singleton. ms.
+Qed.
+ +
+Global Hint Resolve in_difference : multiset.
+ +
+(* could be used in disj_inv *)
+Lemma env_add_inv (Γ Γ' : env) (φ ψ : form): φ ψ -> ((Γ φ) (Γ' ψ)) -> (Γ' ((Γ {[ψ]}) φ)).
+Proof.
+intros Hneq Heq. rewrite <- env_replace.
+- ms.
+- assert (Γ φ)); [rewrite Heq|]; ms.
+Qed.
+ +
+Lemma env_add_inv' (Γ Γ' : env) (φ : form): (Γ φ) Γ' -> (Γ (Γ' {[φ]})).
+Proof. intro Heq. ms. Qed.
+ +
+Lemma env_equiv_eq (Γ Γ' :env) : Γ = Γ' -> Γ Γ'.
+Proof. intro; subst; trivial. Qed.
+ +
+(* reprove the following principles, proved in stdpp for Prop, but
+   we need them in Type *)

+Lemma gmultiset_choose_or_empty (X : env) : {x | x X} + {X = }.
+Proof.
+  destruct (elements X) as [|x l] eqn:HX; [right|left].
+  - by apply gmultiset_elements_empty_inv.
+  - exists x. rewrite <- (gmultiset_elem_of_elements x X).
+    replace (elements X) with (x :: l). left.
+Qed.
+ +
+(* We need this induction principle in type. *)
+Lemma gmultiset_rec (P : env Type) :
+  P ( x X, P X P ({[+ x +]} X)) X, P X.
+Proof.
+  intros Hemp Hinsert X. induction (gmultiset_wf X) as [X _ IH].
+  destruct (gmultiset_choose_or_empty X) as [[x Hx]| ->]; auto.
+  rewrite (gmultiset_disj_union_difference' x X) by done.
+  apply Hinsert, IH; multiset_solver.
+Qed.
+ +
+Lemma difference_include (θ θ' : form) (Δ : env) :
+  (θ' Δ) ->
+  θ Δ {[θ']} -> θ Δ.
+Proof.
+intros Hin' Hin.
+rewrite gmultiset_disj_union_difference with (X := {[θ']}).
+- apply gmultiset_elem_of_disj_union. tauto.
+- now apply gmultiset_singleton_subseteq_l.
+Qed.
+ +
+Fixpoint rm x l := match l with
+| h :: t => if form_eq_dec x h then t else h :: rm x t
+| [] => []
+end.
+ +
+Lemma in_rm l x y: In x (rm y l) -> In x l.
+Proof.
+induction l; simpl. tauto.
+destruct form_eq_dec. tauto. firstorder.
+Qed.
+ +
+Lemma remove_include (θ θ' : form) (Δ : list form) :
+  (θ' Δ) ->
+  θ rm θ' Δ -> θ Δ.
+Proof. intros Hin' Hin. eapply elem_of_list_In, in_rm, elem_of_list_In, Hin. Qed.
+ +
+(* technical lemma : one can constructively find whether an environment contains
+   an element satisfying a decidable property *)

+Lemma decide_in (P : form -> Prop) (Γ : env) :
+  (forall φ, Decision (P φ)) ->
+  {φ : form| (φ Γ) /\ P φ} + {forall φ, φ Γ -> ¬ P φ}.
+Proof.
+intro HP.
+induction Γ using gmultiset_rec.
+- right. intros φ Hφ; inversion Hφ.
+- destruct IHΓ as [(φ&Hφ) | HF].
+  + left. exists φ. ms.
+  + case (HP x); intro Hx.
+    * left; exists x. ms.
+    * right. intros. ms.
+Qed.
+ +
+Lemma union_difference_L (Γ : env) Δ ϕ: ϕ Γ -> (Γ Δ) {[ϕ]} Γ {[ϕ]} Δ.
+Proof. intro Hin. pose (difference_singleton _ _ Hin). ms. Qed.
+ +
+Lemma union_difference_R (Γ : env) Δ ϕ: ϕ Δ -> (Γ Δ) {[ϕ]} Γ (Δ {[ϕ]}).
+Proof. intro Hin. pose (difference_singleton _ _ Hin). ms. Qed.
+ +
+Global Instance equiv_assoc : @Assoc env equiv disj_union.
+Proof. intros x y z. ms. Qed.
+Global Hint Immediate equiv_assoc : proof.
+ +
+Global Instance proper_difference : Proper ((≡@{env}) ==> eq ==> (≡@{env})) difference.
+Proof. intros Γ Γ' Heq Δ Heq'. ms. Qed.
+ +
+Definition var_not_in_env p (Γ : env):= ( φ0, φ0 Γ -> ¬ occurs_in p φ0).
+ +
+
+ +
+

Tactics

+ +
+
+(* helper tactic split cases given an assumption about belonging to a multiset *)
+ +
+Ltac in_tac :=
+repeat
+match goal with
+| H : ?θ {[?θ1; ?θ2]} |- _ => apply gmultiset_elem_of_union in H; destruct H as [H|H]; try subst
+| H : ?θ (?Δ {[?θ']}) |- _ => apply difference_include in H; trivial
+| H : context [?θ (?d ?θ2)] |- _ =>
+    rewrite (env_in_add d) in H; destruct H as [H|H]; try subst
+| H : context [?θ {[ ?θ2 ]}] |- _ => rewrite gmultiset_elem_of_singleton in H; subst
+end.
+ +
+Definition open_box φ : form := match φ with
+| φ => φ
+| φ => φ
+end.
+ +
+(* inefficient conversion from multisets to lists and back *)
+Definition open_boxes (Γ : env) : env := list_to_set_disj (map open_box (elements Γ)).
+ +
+Global Notation "⊙ φ" := (open_box φ) (at level 75).
+Global Notation "⊗ Γ" := (open_boxes Γ) (at level 75).
+ +
+Global Instance proper_open_boxes : Proper ((≡@{env}) ==> (≡@{env})) open_boxes.
+Proof. intros Γ Heq Δ Heq'. ms. Qed.
+ +
+Lemma open_boxes_empty : open_boxes = .
+Proof. auto. Qed.
+ +
+Lemma open_boxes_disj_union (Γ : env) Δ : (open_boxes (Γ Δ)) = (open_boxes Γ open_boxes Δ).
+Proof.
+unfold open_boxes. rewrite (gmultiset_elements_disj_union Γ Δ).
+rewrite map_app. apply list_to_set_disj_app.
+Qed.
+ +
+Lemma open_boxes_singleton φ : open_boxes {[φ]} = {[ φ]}.
+Proof.
+unfold open_boxes.
+assert (HH := gmultiset_elements_singleton φ).
+unfold elements, base.singletonMS, singletonMS, base.singleton, Environments.singleton in *.
+rewrite HH. simpl. unfold base.singletonMS, disj_union, empty.
+apply gmultiset_disj_union_right_id.
+Qed.
+ +
+Lemma open_boxes_add (Γ : env) φ : (open_boxes (Γ φ)) = (open_boxes Γ open_box φ).
+Proof.
+rewrite open_boxes_disj_union.
+unfold open_boxes. f_equal. apply open_boxes_singleton.
+Qed.
+ +
+Lemma elem_of_open_boxes φ Δ : φ (Δ) -> φ Δ \/ (φ) Δ.
+Proof.
+intro Hin.
+induction Δ as [|θ Δ Hind] using gmultiset_rec.
+- auto with proof.
+- rewrite open_boxes_disj_union in Hin.
+  apply gmultiset_elem_of_disj_union in Hin.
+  destruct Hin as [ | ].
+  + rewrite open_boxes_singleton in . apply gmultiset_elem_of_singleton in .
+      subst φ. destruct θ; ms.
+  + destruct (Hind ); ms.
+Qed.
+ +
+Lemma occurs_in_open_boxes x φ Δ : occurs_in x φ -> φ (Δ) -> exists θ, θ Δ /\ occurs_in x θ.
+Proof.
+intros Hx Hφ. apply elem_of_open_boxes in Hφ. destruct Hφ as [Hφ|Hφ]; eauto.
+Qed.
+ +
+Lemma occurs_in_map_open_box x φ Δ : occurs_in x φ -> φ (map open_box Δ) -> exists θ, θ Δ /\ occurs_in x θ.
+Proof.
+intros Hx Hφ. apply elem_of_list_In, in_map_iff in Hφ.
+destruct Hφ as [ψ [Hφ Hin]]; subst.
+exists ψ. split. now apply elem_of_list_In. destruct ψ; trivial.
+Qed.
+ +
+Global Hint Rewrite open_boxes_disj_union : proof.
+ +
+Lemma open_boxes_remove Γ φ : φ Γ -> (≡@{env}) (⊗ (Γ {[φ]})) ((⊗ Γ) {[⊙ φ]}).
+Proof.
+intro Hin.
pose (difference_singleton Γ φ Hin). rewrite e at 2.
+rewrite open_boxes_add. ms.
+Qed.
+ +
+Definition is_box φ := match φ with
+| _ => true
+| _ => false
+end.
+ +
+Lemma open_boxes_spec Γ φ : φ open_boxes Γ -> {φ Γ is_box φ = false} + {( φ) Γ}.
+Proof.
+unfold open_boxes. intro Hin. apply elem_of_list_to_set_disj in Hin.
+apply elem_of_list_In in Hin. apply in_map_iff in Hin.
+case (decide (( φ) Γ)).
+- right; trivial.
+- intro Hout. left.
+  destruct Hin as (y & Hin & Hy). subst.
+  destruct y; simpl in *; split; trivial;
+  try (apply gmultiset_elem_of_elements,elem_of_list_In; trivial);
+  contradict Hout; apply gmultiset_elem_of_elements,elem_of_list_In; trivial.
+Qed.
+ +
+Lemma is_not_box_open_box φ : is_box φ = false -> (φ) = φ.
+Proof. destruct φ; simpl; intuition. discriminate. Qed.
+ +
+Lemma open_boxes_spec' Γ φ : {φ Γ is_box φ = false} + {( φ) Γ} -> φ open_boxes Γ.
+Proof.
+intros [[Hin Heq] | Hin];
+unfold open_boxes; apply elem_of_list_to_set_disj, elem_of_list_In, in_map_iff.
+- exists φ. apply is_not_box_open_box in Heq. rewrite Heq. split; trivial.
+  now apply elem_of_list_In, gmultiset_elem_of_elements.
+- exists ( φ). simpl. split; trivial. now apply elem_of_list_In, gmultiset_elem_of_elements.
+Qed.
+ +
+Lemma In_open_boxes (Γ : env) (φ : form) : (φ Γ) -> open_box φ open_boxes Γ.
+Proof.
+intro Hin. apply difference_singleton in Hin.
+rewrite Hin, open_boxes_add. auto with *.
+Qed.
+ +
+Global Hint Resolve In_open_boxes : proof.
+Global Hint Unfold open_box : proof.
+Global Hint Rewrite open_boxes_empty : proof.
+Global Hint Rewrite open_boxes_add : proof.
+Global Hint Rewrite open_boxes_remove : proof.
+Global Hint Rewrite open_boxes_singleton : proof.
+ +
+Global Hint Resolve open_boxes_spec' : proof.
+Global Hint Resolve open_boxes_spec : proof.
+ +
+Global Instance Proper_elements : Proper ((≡) ==> (≡ₚ)) ((λ Γ : env, elements Γ)).
+Proof.
+intros Γ Δ Heq; apply AntiSymm_instance_0; apply gmultiset_elements_submseteq; ms.
+Qed.
+ +
+Lemma elements_open_boxes Γ: elements ( Γ) ≡ₚ map open_box (elements Γ).
+Proof.
+unfold open_boxes. remember (elements Γ) as l. clear Γ Heql.
+induction l as [| a l].
+- ms.
+- simpl. setoid_rewrite gmultiset_elements_disj_union.
+  rewrite IHl. setoid_rewrite gmultiset_elements_singleton. trivial.
+Qed.
+ +
+Lemma list_to_set_disj_env_add Δ v: ((list_to_set_disj Δ : env) v : env) list_to_set_disj (v :: Δ).
+Proof. ms. Qed.
+ +
+Lemma list_to_set_disj_rm Δ v: (list_to_set_disj Δ : env) {[v]} list_to_set_disj (rm v Δ).
+Proof.
+induction Δ as [|φ Δ]; simpl; [ms|].
+case form_eq_dec; intro; subst; [ms|].
+simpl. rewrite <- IHΔ. case (decide (v (list_to_set_disj Δ: env))).
+- intro. rewrite union_difference_R by assumption. ms.
+- intro. rewrite diff_not_in by auto with *. rewrite diff_not_in; auto with *.
+Qed.
+ +
+Lemma gmultiset_elements_list_to_set_disj l: gmultiset_elements(list_to_set_disj l) ≡ₚ l.
+Proof.
+induction l as [| x l]; [ms|].
+rewrite Proper_elements; [|symmetry; apply list_to_set_disj_env_add].
+rewrite elements_env_add, IHl. trivial.
+Qed.
+ +
+Lemma list_to_set_disj_open_boxes Δ: (( (list_to_set_disj Δ)) = list_to_set_disj (map open_box Δ)).
+Proof. apply list_to_set_disj_perm, Permutation_map', gmultiset_elements_list_to_set_disj. Qed.
+ +
+(* TODO: move in optimisations *)
+
+ +
+ + + diff --git a/ISL.Formulas.html b/ISL.Formulas.html new file mode 100644 index 0000000..9a2327a --- /dev/null +++ b/ISL.Formulas.html @@ -0,0 +1,238 @@ + + + + + + + + + + + + + +
+
+

ISL.Formulas

+ +
+
+ +
+

Overview: formulas

+ + +
+ +This file defines propositional formulas, the proof that there are countably many, and the definition of the well-founded ordering on the set of formulas, via weight. +
+ + Theory of countability from Iris +
+
+From stdpp Require Import countable strings.
+ +
+Local Open Scope string_scope.
+ +
+
+ +
+

Definitions and notations.

+ +
+
+Definition variable := string.
+ +
+Inductive form : Type :=
+| Var : variable -> form
+| Bot : form
+| And : form -> form -> form
+| Or : form -> form -> form
+| Implies : form -> form -> form
+| Box : form -> form.
+ +
+Fixpoint occurs_in (x : variable) (φ : form) :=
+match φ with
+| Var y => x = y
+| Bot => False
+| And φ ψ => (occurs_in x φ) \/ (occurs_in x ψ)
+| Or φ ψ => (occurs_in x φ) \/ (occurs_in x ψ)
+| Implies φ ψ => (occurs_in x φ) \/ (occurs_in x ψ)
+| Box φ => occurs_in x φ
+
+end.
+ +
+
+ +
+Pretty notations for formulas +
+
+Notation "¬ φ" := (Implies φ Bot) (at level 75, φ at level 75).
+Notation " ⊥ " := Bot.
+Notation " ⊤ " := (Implies Bot Bot).
+Notation " A ∧ B" := (And A B) (at level 80, B at level 80).
+Notation " A ∨ B" := (Or A B) (at level 85, B at level 85).
+Notation " A → B" := (Implies A B) (at level 99, B at level 200).
+Notation "□ φ" := (Box φ) (at level 75, φ at level 75).
+Infix " φ ⇔ ψ " := (And (Implies φ ψ) (Implies ψ φ)) (at level 100).
+Global Instance fomula_bottom : base.Bottom form := Bot.
+ +
+Global Coercion Var : variable >-> form.
+ +
+Global Instance form_top : base.Top form := .
+ +
+
+ +
+Formulas have decidable equality. +
+
+Global Instance string_dec : EqDecision string := string_dec.
+Global Instance form_eq_dec : EqDecision form.
+Proof. solve_decision . Defined.
+ +
+Section CountablyManyFormulas.
+
+ +
+

Countability of the set of formulas

+ We prove that there are countably many formulas by exhibiting an injection + into general trees over nat for countability. +
+
+Local Fixpoint form_to_gen_tree (φ : form) : gen_tree (option string) :=
+match φ with
+| => GenLeaf None
+| Var v => GenLeaf (Some v)
+| φ ψ => GenNode 0 [form_to_gen_tree φ ; form_to_gen_tree ψ]
+| φ ψ => GenNode 1 [form_to_gen_tree φ ; form_to_gen_tree ψ]
+| φ ψ => GenNode 2 [form_to_gen_tree φ ; form_to_gen_tree ψ]
+| φ => GenNode 3 [form_to_gen_tree φ]
+end.
+ +
+Local Fixpoint gen_tree_to_form (t : gen_tree (option string)) : option form :=
+match t with
+| GenLeaf None => Some
+| GenLeaf (Some v) => Some (Var v)
+| GenNode 0 [t1 ; t2] =>
+    gen_tree_to_form t1 ≫= fun φ => gen_tree_to_form t2 ≫= fun ψ =>
+      Some (φ ψ)
+| GenNode 1 [t1 ; t2] =>
+    gen_tree_to_form t1 ≫= fun φ => gen_tree_to_form t2 ≫= fun ψ =>
+      Some (φ ψ)
+| GenNode 2 [t1 ; t2] =>
+    gen_tree_to_form t1 ≫= fun φ => gen_tree_to_form t2 ≫= fun ψ =>
+      Some (φ ψ)
+ | GenNode 3 [t] => gen_tree_to_form t ≫= fun φ => Some (φ)
+| _=> None
+end.
+ +
+Global Instance form_count : Countable form.
+Proof.
+  eapply inj_countable with (f := form_to_gen_tree) (g := gen_tree_to_form).
+  intro φ; induction φ; simpl; trivial; now rewrite IHφ1, IHφ2 || rewrite IHφ.
+Defined.
+ +
+End CountablyManyFormulas.
+ +
+Inductive subform : form -> form -> Prop :=
+| SubEq : φ, subform φ φ
+| SubAnd : φ ψ1 ψ2, (subform φ ψ1 + subform φ ψ2) -> subform φ (ψ1 ψ2)
+| SubOr : φ ψ1 ψ2, (subform φ ψ1 + subform φ ψ2) -> subform φ (ψ1 ψ2)
+| SubImpl : φ ψ1 ψ2, (subform φ ψ1 + subform φ ψ2) -> subform φ (ψ1 ψ2)
+| SubBox : φ ψ, subform φ ψ -> subform φ ( ψ).
+Local Hint Constructors subform : dyckhoff.
+ +
+
+ +
+

Weight

+ + +
+ +We define the weight function on formulas, following (Dyckhoff Negri 2000) +
+
+Fixpoint weight (φ : form) : nat := match φ with
+| => 1
+| Var _ => 1
+| φ ψ => 2 + weight φ + weight ψ
+| φ ψ => 3 + weight φ + weight ψ
+| φ ψ => 1 + weight φ + weight ψ
+| φ => 1 + weight φ
+end.
+ +
+Lemma weight_pos φ : weight φ > 0.
+Proof. induction φ; simpl; lia. Qed.
+ +
+
+ +
+We obtain an induction principle based on weight. +
+
+Definition weight_ind (P : form -> Type) :
(forall ψ, ( φ, (weight φ < weight ψ) -> P φ) -> P ψ) ->
( φ, P φ).
+Proof.
+  intros Hc φ. remember (weight φ) as w.
+  assert(Hw : weight φ w) by now subst. clear Heqw.
+  revert φ Hw. induction w; intros φ Hw.
+  - pose (Hw' := weight_pos φ). auto with *.
+  - destruct φ; simpl in Hw; trivial;
+    apply Hc; intros φ' Hw'; apply IHw; simpl in Hw'; lia.
+Defined.
+ +
+Definition form_order φ ψ := weight φ > weight ψ.
+ +
+Global Instance transitive_form_order : Transitive form_order.
+Proof. unfold form_order. auto with *. Qed.
+ +
+Global Instance irreflexive_form_order : Irreflexive form_order.
+Proof. unfold form_order. intros x y. lia. Qed.
+ +
+Notation "φ ≺f ψ" := (form_order ψ φ) (at level 149).
+
+
+ +
+ + + diff --git a/ISL.Optimizations.html b/ISL.Optimizations.html new file mode 100644 index 0000000..74624f2 --- /dev/null +++ b/ISL.Optimizations.html @@ -0,0 +1,820 @@ + + + + + + + + + + + + + +
+
+

ISL.Optimizations

+ +
+Require Import ISL.Environments ISL.Sequents ISL.SequentProps ISL.Cut.
+Require Import Program Equality.
+ +
+Definition Lindenbaum_Tarski_preorder φ ψ :=
+   φ ψ.
+ +
+Notation "φ ≼ ψ" := (Lindenbaum_Tarski_preorder φ ψ) (at level 150).
+ +
+Corollary weak_cut φ ψ θ:
+  (φ ψ) -> (ψ θ) ->
+  φ θ.
+Proof.
+intros H1 H2.
+eapply additive_cut.
+- apply H1.
+- exch 0. now apply weakening.
+Qed.
+ +
+Lemma top_provable Γ :
Γ .
+Proof.
+  apply ImpR. apply ExFalso.
+Qed.
+ +
+(* Some tactics for the obviously_smaller proofs. *)
+ +
+(* Solve goals involving the equality decision at the end of the match *)
+Ltac eq_clean := match goal with
+| H : (if decide (?f1 = ?f2) then ?t else Eq) = ?t |- _ =>
+    case decide in H;
+    match goal with
+    | e : ?f1 = ?f2 |- _ => rewrite e; apply generalised_axiom
+    | _ => discriminate
+    end
+| H : (if decide (?f1 = ?f2) then Lt else Eq) = Gt |- _ =>
+    case decide in H; discriminate
+| H : matchwith _ => _ end = _ |- _ => destruct φ; try discriminate; eq_clean
+end.
+ +
+(* Solve goals that involve directly using ExFalso *)
+Ltac bot_clean := match goal with
+| [ |- Bot _] => apply ExFalso
+| [ |- _ Bot _ ] => apply ImpR; apply ExFalso
+| _ => idtac
+end.
+ +
+(* Solve induction goals *)
+Ltac induction_auto := match goal with
+| IH : obviously_smaller ?f ?f2 = Lt ?f ?f2 , H : obviously_smaller ?f ?f2 = Lt |- ( ?f) ?f2 =>
+    apply IH; assumption
+| IH : obviously_smaller ?f ?f2 = Gt ?f2 ?f , H : obviously_smaller ?f ?f2 = Gt |- ( ?f2) ?f =>
+    apply IH; assumption
+
+| IH : obviously_smaller ?f _ = Lt ?f _ , H : obviously_smaller ?f _ = Lt |- ?f _ _ =>
+    apply AndL; apply weakening; apply IH; assumption
+| IH : obviously_smaller ?f _ = Lt ?f _ , H : obviously_smaller ?f _ = Lt |- _ ?f _ =>
+    apply AndL; exch 0; apply weakening; apply IH; assumption
+
+| IH : obviously_smaller ?f _ = Gt _ ?f , H : obviously_smaller ?f _ = Gt |- _ ?f _ =>
+    apply OrR1; apply IH; assumption
+| IH : obviously_smaller ?f _ = Gt _ ?f , H : obviously_smaller ?f _ = Gt |- _ _ ?f =>
+    apply OrR2; apply IH; assumption
+| _ => idtac
+end.
+ +
+Lemma double_negation_obviously_smaller φ ψ:
is_double_negation φ ψ -> ψ φ.
+Proof.
+intro H; rewrite H. apply ImpR; auto with proof.
+Qed.
+ +
+Lemma is_implication_obviously_smaller φ ψ:
is_implication φ ψ -> ψ φ.
+Proof.
+unfold is_implication. intro H.
+destruct φ; try (contradict H; intros [θ ]; discriminate).
+case (decide (φ2 = ψ)).
+- intro; subst. apply ImpR, weakening, generalised_axiom.
+- intro Hneq. contradict H; intros [θ ]. inversion . tauto.
+Qed.
+ +
+Lemma obviously_smaller_compatible_LT φ ψ :
+  obviously_smaller φ ψ = Lt -> φ ψ.
+Proof.
+intro H.
+induction φ; destruct ψ;
+repeat (unfold obviously_smaller in H; fold obviously_smaller in H; try discriminate; eq_clean); bot_clean;
+
+repeat match goal with
+  | [ H : obviously_smaller _ (?f _) = Lt |- _ ?f _ ] =>
+      destruct f; simpl in H; try discriminate; bot_clean
+  | |- _ _ ?f =>
+    case_eq (obviously_smaller φ1 f); case_eq (obviously_smaller φ2 f);
+    intros H0 H1;
+    simpl in H; try rewrite H0 in H; try rewrite H1 in H; try discriminate; induction_auto
+  | |- _ _ ?f =>
+    case_eq (obviously_smaller φ1 f); case_eq (obviously_smaller φ2 f);
+    intros H0 H1;
+    simpl in H; rewrite H0 in H; rewrite H1 in H; try discriminate;
+    apply OrL; induction_auto
+  | |- (?f _) _ => destruct f; try eq_clean; discriminate
+end;
+try destruct ψ1; try discriminate; bot_clean;
+simpl in H; try case decide in H; try discriminate; bot_clean;
+try (now apply double_negation_obviously_smaller);
+try case decide in H;
+try (now apply is_implication_obviously_smaller);
+try (inversion e; subst; apply generalised_axiom);
+try solve[destruct φ1; inversion H];
+destruct φ1; repeat case decide in H; try discriminate;
+   try (now apply is_implication_obviously_smaller);
+   try (now apply double_negation_obviously_smaller).
+Qed.
+ +
+Lemma obviously_smaller_compatible_GT φ ψ :
+  obviously_smaller φ ψ = Gt -> ψ φ .
+Proof.
+intro H.
+induction φ; destruct ψ;
+try match goal with H : ?H0 -> _ |- _ => assert(Hw' : H0) by lia; specialize (Hw Hw') end;
+try (unfold obviously_smaller in H; try discriminate; eq_clean); bot_clean;
+repeat match goal with
+  | |- ?f _ _ =>
+    case_eq (obviously_smaller φ1 f); case_eq (obviously_smaller φ2 f); intros H0 H1;
+    simpl in H; rewrite H0 in H; rewrite H1 in H; try discriminate; apply AndR; induction_auto
+  | |- ?f _ _ =>
+    case_eq (obviously_smaller φ1 f); case_eq (obviously_smaller φ2 f); intros H0 H1;
+    simpl in H; rewrite H0 in H; rewrite H1 in H; try discriminate; induction_auto
+  | |- (?f1 _) ?f2 _ =>
+    simpl in H; destruct f1; destruct f2; bot_clean; try eq_clean; discriminate
+  | |- (?f _) _ => destruct f; discriminate
+  | |- ( (?f _)) _ => destruct f; discriminate
+  | |- _ (?f _) => destruct f; bot_clean; discriminate
+end;
+simpl in H;
+try solve[destruct ψ1; try discriminate; eq_clean];
+  destruct φ1; try discriminate; repeat eq_clean;
+  try destruct ψ1;
try (unfold obviously_smaller in H; try discriminate; eq_clean); bot_clean;
repeat case decide in H; try discriminate; bot_clean;
+try (now apply double_negation_obviously_smaller);
+try (now apply is_implication_obviously_smaller);
+try (now apply ImpR, weakening, IHφ2).
+Qed.
+ +
+Lemma and_congruence φ ψ φ' ψ':
+  (φ φ') -> (ψ ψ') -> (φ ψ) φ' ψ'.
+Proof.
+intros Hφ Hψ.
+apply AndL.
+apply AndR.
+- now apply weakening.
+- exch 0. now apply weakening.
+Qed.
+ +
+Lemma choose_conj_equiv_L φ ψ φ' ψ':
+  (φ φ') -> (ψ ψ') -> (φ ψ) choose_conj φ' ψ'.
+Proof.
+intros Hφ Hψ.
+unfold choose_conj.
+case_eq (obviously_smaller φ' ψ'); intro Heq.
+- apply and_congruence; assumption.
+- apply AndL, weakening, Hφ.
+- apply AndL. exch 0. apply weakening, Hψ.
+Qed.
+ +
+Lemma choose_conj_equiv_R φ ψ φ' ψ':
+  (φ' φ) -> (ψ' ψ) -> choose_conj φ' ψ' φ ψ.
+Proof.
+intros Hφ Hψ.
+unfold choose_conj.
+case_eq (obviously_smaller φ' ψ'); intro Heq.
+- now apply and_congruence.
+- apply AndR.
+  + assumption.
+  + eapply weak_cut.
+    * apply obviously_smaller_compatible_LT, Heq.
+    * assumption.
+- apply AndR.
+  + eapply weak_cut.
+    * apply obviously_smaller_compatible_GT, Heq.
+    * assumption.
+  + assumption.
+Qed.
+ +
+Hint Unfold Lindenbaum_Tarski_preorder : proof.
+ +
+Lemma make_conj_equiv_L φ ψ φ' ψ' :
+  (φ φ') -> (ψ ψ') -> (φ ψ) φ' ψ'.
+Proof.
+intros Hφ Hψ.
+unfold make_conj.
+destruct ψ'; try (apply choose_conj_equiv_L; assumption).
+- destruct φ'; try (apply choose_conj_equiv_L; assumption).
+  case decide; intro; try (apply choose_conj_equiv_L; assumption).
+  apply obviously_smaller_compatible_LT in e.
+  apply weak_cut with ((φ φ'1) ψ).
+  + apply AndL; repeat apply AndR. auto with proof.
+      * exch 0. apply weakening; apply weak_cut with v; assumption.
+      * apply generalised_axiom.
+  + apply choose_conj_equiv_L; auto with proof.
+- apply exfalso, AndL. exch 0. apply weakening, Hψ.
+- case_eq (obviously_smaller φ' ψ'1); intro Heq.
+  + apply and_congruence; assumption.
+  + apply and_congruence.
+    * assumption.
+    * apply AndR_rev in Hψ; apply Hψ.
+  + apply AndL. exch 0. apply weakening. assumption.
+- repeat case decide; intros.
+  + apply AndL. now apply weakening.
+  + apply AndL. now apply weakening.
+  + apply choose_conj_equiv_L ; assumption.
+- case (decide (obviously_smaller φ' ψ'1 = Lt)); intro.
+  + apply weak_cut with (φ ψ)).
+     * apply AndR; auto with proof.
+     * apply choose_conj_equiv_L. assumption.
+        apply obviously_smaller_compatible_LT in e.
+        apply contraction, ImpR_rev. apply weak_cut with ψ'1.
+        -- apply weak_cut with φ'; auto with proof.
+        -- apply ImpR. exch 0. apply ImpR_rev, AndL. exch 0. apply weakening, Hψ.
+  + apply choose_conj_equiv_L; assumption.
+- destruct φ'; try (apply choose_conj_equiv_L; assumption).
+  case decide; intro; try (apply choose_conj_equiv_L; assumption).
+  apply weak_cut with (φ φ'1)).
+  + apply AndL, AndR. auto with proof. apply AndR. auto with proof.
+      exch 0. apply weakening. apply weak_cut with ( ψ'). auto with proof.
+      now apply obviously_smaller_compatible_LT.
+  + apply weak_cut with ((φ φ'1) ψ).
+     * apply AndR; auto with proof.
+     * apply choose_conj_equiv_L; auto with proof.
+Qed.
+ +
+Lemma make_conj_equiv_R φ ψ φ' ψ' :
+  (φ' φ) -> (ψ' ψ) -> φ' ψ' φ ψ.
+Proof.
+intros Hφ Hψ.
+unfold make_conj.
+destruct ψ'.
+- destruct φ'; try case decide; intros; apply choose_conj_equiv_R; try assumption.
+  eapply imp_cut; eassumption.
+- destruct φ'; try case decide; intros; apply choose_conj_equiv_R; try assumption.
+   eapply imp_cut; eassumption.
+- case_eq (obviously_smaller φ' ψ'1); intro Heq.
+  + now apply and_congruence.
+  + apply AndR.
+    * apply AndL. now apply weakening.
+    * apply (weak_cut _ ( ψ'1 ψ'2) _).
+      -- apply and_congruence;
+         [now apply obviously_smaller_compatible_LT | apply generalised_axiom].
+      -- assumption.
+  + apply AndR.
+    * apply AndL. apply weakening. eapply weak_cut.
+      -- apply obviously_smaller_compatible_GT; apply Heq.
+      -- assumption.
+    * assumption.
+- repeat case decide; intros.
+  + apply AndR.
+    * assumption.
+    * eapply weak_cut.
+      -- apply obviously_smaller_compatible_LT; eassumption.
+      -- apply OrL_rev in Hψ; apply Hψ.
+  + apply AndR.
+    * assumption.
+    * eapply weak_cut.
+      -- apply obviously_smaller_compatible_LT; eassumption.
+      -- apply OrL_rev in Hψ; apply Hψ.
+  + apply choose_conj_equiv_R; assumption.
+- case decide; intro Heq.
+  + apply choose_conj_equiv_R. assumption. eapply weak_cut; [|exact Hψ]. auto with proof.
+  + apply choose_conj_equiv_R; assumption.
+- destruct φ'; try case decide; intros; apply choose_conj_equiv_R; try assumption.
+  eapply imp_cut; eassumption.
+Qed.
+ +
+Lemma specialised_weakening Γ φ ψ : (φ ψ) -> Γφ ψ.
+Proof.
+intro H.
+apply generalised_weakeningL.
+peapply H.
+Qed.
+ +
+Lemma make_conj_sound_L Γ φ ψ θ : Γφ ψ θ -> Γ φ ψ θ.
+Proof.
+intro H.
+eapply additive_cut.
+- apply specialised_weakening.
+  apply make_conj_equiv_R; apply generalised_axiom.
+- exch 0. now apply weakening.
+Qed.
+ +
+Global Hint Resolve make_conj_sound_L : proof.
+ +
+Lemma make_conj_complete_L Γ φ ψ θ : Γ φ ψ θ -> Γφ ψ θ.
+Proof.
+intro H.
+eapply additive_cut.
+- apply specialised_weakening.
+  apply make_conj_equiv_L; apply generalised_axiom.
+- exch 0. now apply weakening.
+Qed.
+ +
+Lemma make_conj_sound_R Γ φ ψ : Γ φ ψ -> Γ φ ψ.
+Proof.
+intro H.
+eapply additive_cut.
+- apply H.
+- apply make_conj_complete_L, generalised_axiom.
+Qed.
+ +
+Global Hint Resolve make_conj_sound_R : proof.
+ +
+Lemma make_conj_complete_R Γ φ ψ : Γ φ ψ -> Γ φ ψ.
+Proof.
+intro H.
+eapply additive_cut.
+- apply H.
+- apply make_conj_sound_L, generalised_axiom.
+Qed.
+ +
+Lemma or_congruence φ ψ φ' ψ':
+  (φ φ') -> (ψ ψ') -> (φ ψ) φ' ψ'.
+Proof.
+intros Hφ Hψ.
+apply OrL.
+- now apply OrR1.
+- now apply OrR2.
+Qed.
+ +
+Lemma choose_disj_equiv_L φ ψ φ' ψ':
+  (φ φ') -> (ψ ψ') -> (φ ψ) choose_disj φ' ψ'.
+Proof.
+intros Hφ Hψ.
+unfold choose_disj.
+case_eq (obviously_smaller φ' ψ'); intro Heq.
+- case_eq (obviously_smaller ψ' φ'); intro Heq'.
+  + apply or_congruence; assumption.
+  + apply OrL. assumption.
+       eapply weak_cut.
+        * apply Hψ.
+        * apply obviously_smaller_compatible_LT; assumption.
+  + apply OrL; [| assumption].
+       eapply weak_cut.
+        * apply Hφ.
+        * apply obviously_smaller_compatible_GT; assumption.
+- apply OrL.
+  + eapply weak_cut.
+    * apply Hφ.
+    * apply obviously_smaller_compatible_LT; assumption.
+  + assumption.
+- apply OrL.
+  + assumption.
+  + eapply weak_cut.
+    * eapply weak_cut.
+      -- apply Hψ.
+      -- apply obviously_smaller_compatible_GT. apply Heq.
+    * apply generalised_axiom.
+Qed.
+ +
+Lemma choose_disj_equiv_R φ ψ φ' ψ' :
+  (φ' φ) -> (ψ' ψ) -> choose_disj φ' ψ' φ ψ.
+Proof.
+intros Hφ Hψ.
+unfold choose_disj.
+case_eq (obviously_smaller φ' ψ'); intro Heq;
+[| apply OrR2| apply OrR1]; try assumption.
+case_eq (obviously_smaller ψ' φ'); intro Heq';
+[apply or_congruence| apply OrR1| apply OrR2]; try assumption.
+Qed.
+ +
+Lemma make_disj_equiv_L φ ψ φ' ψ' :
+  (φ φ') -> (ψ ψ') -> (φ ψ) φ' ψ'.
+Proof.
+intros Hφ Hψ.
+unfold make_disj.
+destruct ψ'; try (apply choose_disj_equiv_L; assumption).
+- repeat case decide; intros.
+  + apply OrL.
+    * assumption.
+    * eapply weak_cut.
+      -- apply Hψ.
+      -- apply AndL; apply weakening; now apply obviously_smaller_compatible_GT.
+  + apply OrL.
+    * assumption.
+    * eapply weak_cut.
+      -- apply Hψ.
+      -- apply AndL; exch 0. apply weakening; now apply obviously_smaller_compatible_GT.
+  + now apply choose_disj_equiv_L.
+- case_eq (obviously_smaller φ' ψ'1); intro Heq.
+  + now apply or_congruence.
+  + apply OrL.
+    * eapply weak_cut.
+      -- apply Hφ.
+      -- apply OrR1. now apply obviously_smaller_compatible_LT.
+    * assumption.
+  + apply OrL.
+    * now apply OrR1.
+    * eapply weak_cut.
+      -- apply Hψ.
+      -- apply or_congruence; [apply obviously_smaller_compatible_GT; assumption| apply generalised_axiom].
+Qed.
+ +
+Lemma make_disj_equiv_R φ ψ φ' ψ' :
+  (φ' φ) -> (ψ' ψ) -> φ' ψ' φ ψ.
+Proof.
+intros Hφ Hψ.
+unfold make_disj.
+destruct ψ'.
+- now apply choose_disj_equiv_R.
+- now apply choose_disj_equiv_R.
+- repeat case decide; intros.
+  + now apply OrR1.
+  + now apply OrR1.
+  + now apply choose_disj_equiv_R.
+- case_eq (obviously_smaller φ' ψ'1); intro Heq.
+ + now apply or_congruence.
+ + now apply OrR2.
+ + apply OrL.
+   * now apply OrR1.
+   * apply OrL_rev in Hψ.
+     apply OrR2, Hψ.
+- now apply choose_disj_equiv_R.
+- now apply choose_disj_equiv_R.
+Qed.
+ +
+Lemma make_disj_sound_L Γ φ ψ θ : Γφ ψ θ -> Γmake_disj φ ψ θ.
+Proof.
+intro H.
+eapply additive_cut.
+- apply specialised_weakening.
+  apply make_disj_equiv_R; apply generalised_axiom.
+- exch 0. now apply weakening.
+Qed.
+ +
+Global Hint Resolve make_disj_sound_L : proof.
+ +
+Lemma make_disj_complete_L Γ φ ψ θ : Γmake_disj φ ψ θ -> Γφ ψ θ.
+Proof.
+intro H.
+eapply additive_cut.
+- apply specialised_weakening.
+  apply make_disj_equiv_L; apply generalised_axiom.
+- exch 0. now apply weakening.
+Qed.
+ +
+Lemma make_disj_sound_R Γ φ ψ : Γ φ ψ -> Γ make_disj φ ψ.
+Proof.
+intro H.
+eapply additive_cut.
+- apply H.
+- apply make_disj_complete_L, generalised_axiom.
+Qed.
+ +
+Global Hint Resolve make_disj_sound_R : proof.
+ +
+Lemma make_disj_complete_R Γ φ ψ : Γ make_disj φ ψ -> Γ φ ψ.
+Proof.
+intro H.
+eapply additive_cut.
+- apply H.
+- apply make_disj_sound_L, generalised_axiom.
+Qed.
+ +
+
+ +
+

Generalized rules

+ + +
+ +In this section we prove that generalizations of or-left and and-right rules +that take more than two formulas are admissible and invertible in the calculus +G4ip. This is important in the correctness proof of propositional quantifiers +because the propositional quantifiers are defined as large disjunctions / +conjunctions of various individual formulas. + +
+ +

Generalized OrL and its invertibility

+ +
+
+ +
+Lemma disjunction_L Γ Δ θ :
+  ((forall φ, φ Δ -> (Γφ θ)) -> (Γ Δ θ)) *
+  ((Γ Δ θ) -> (forall φ, φ Δ -> (Γφ θ))).
+Proof.
+unfold disjunction.
+assert(Hcut :
+  (forall ψ, (Γψ θ) -> (forall φ, φ Δ -> (Γφ θ)) ->
+    (Γfoldl make_disj ψ (nodup form_eq_dec Δ) θ)) *
+  (forall ψ,((Γfoldl make_disj ψ (nodup form_eq_dec Δ)) θ ->
+    (Γψ θ) * ( φ : form, φ Δ (Γφ) θ)))).
+{
+  induction Δ; simpl; split; intros ψ Hψ.
+  - intro. apply Hψ.
+  - split; trivial. intros φ Hin. contradict Hin. auto with *.
+  - intro Hall. case in_dec; intro; apply (fst IHΔ); auto with *.
+  - case in_dec in Hψ; apply IHΔ in Hψ;
+    destruct Hψ as [Hψ Hind].
+    + split; trivial; intros φ Hin; destruct (decide= a)); auto 2 with *.
+        subst. apply Hind. now apply elem_of_list_In.
+    + apply make_disj_complete_L in Hψ.
+        apply OrL_rev in Hψ as [Hψ Ha].
+        split; trivial; intros φ Hin; destruct (decide= a)); auto with *.
+}
+split; apply Hcut. constructor 2.
+Qed.
+ +
+
+ +
+

Generalized OrR

+ +
+
+ +
+Lemma disjunction_R Γ Δ φ : (φ Δ) -> (Γ φ) -> (Γ Δ).
+Proof.
+intros Hin Hprov. unfold disjunction. revert Hin.
+assert(Hcut : forall θ, ((Γ θ) + (φ Δ)) -> Γ foldl make_disj θ (nodup form_eq_dec Δ)).
+{
+  induction Δ; simpl; intros θ [ | Hin].
+  - assumption.
+  - contradict Hin; auto with *.
+  - case in_dec; intro; apply IHΔ; left; trivial. apply make_disj_sound_R. now apply OrR1.
+  - apply elem_of_cons in Hin.
+    destruct (decide= a)).
+    + subst. case in_dec; intro; apply IHΔ.
+        * right. now apply elem_of_list_In.
+        * left. apply make_disj_sound_R. now apply OrR2.
+    + case in_dec; intro; apply IHΔ; right; tauto.
+}
+intro Hin. apply Hcut; now right.
+Qed.
+ +
+
+ +
+

Generalized invertibility of AndR

+ +
+ +

Generalized AndR

+ +
+
+ +
+Lemma conjunction_R1 Γ Δ : (forall φ, φ Δ -> Γ φ) -> (Γ Δ).
+Proof.
+intro Hprov. unfold conjunction.
+assert(Hcut : forall θ, Γ θ -> Γ foldl make_conj θ (nodup form_eq_dec Δ)).
+{
+  induction Δ; intros θ ; simpl; trivial.
+  case in_dec; intro; auto with *.
+  apply IHΔ.
+  - intros; apply Hprov. now right.
+  - apply make_conj_sound_R, AndR; trivial. apply Hprov. now left.
+}
+apply Hcut. apply ImpR, ExFalso.
+Qed.
+ +
+Lemma conjunction_R2 Γ Δ : (Γ Δ) -> (forall φ, φ Δ -> Γ φ).
+Proof.
unfold conjunction.
+assert(Hcut : forall θ, Γ foldl make_conj θ (nodup form_eq_dec Δ) -> (Γ θ) * (forall φ, φ Δ -> Γ φ)).
+{
+  induction Δ; simpl; intros θ .
+  - split; trivial. intros φ Hin; contradict Hin. auto with *.
+  - case in_dec in ; destruct (IHΔ _ ) as (Hθ' & Hi);
+     try (apply make_conj_complete_R in Hθ'; destruct (AndR_rev Hθ')); split; trivial;
+     intros φ Hin; apply elem_of_cons in Hin;
+     destruct (decide= a)); subst; trivial.
+     + apply Hi. rewrite elem_of_list_In; tauto.
+     + apply (IHΔ _ ). tauto.
+     + apply (IHΔ _ ). tauto.
+}
+apply Hcut.
+Qed.
+ +
+
+ +
+

Generalized AndL

+ +
+
+ +
+Lemma conjunction_L Γ Δ φ θ: (φ Δ) -> (Γφ θ) -> (Γ Δ θ).
+Proof.
+intros Hin Hprov. unfold conjunction. revert Hin.
+assert(Hcut : forall ψ, ((φ Δ) + (Γψ θ)) -> (Γfoldl make_conj ψ (nodup form_eq_dec Δ) θ)).
+{
+  induction Δ; simpl; intros ψ [Hin | Hψ].
+  - contradict Hin; auto with *.
+  - trivial.
+  - case in_dec; intro; apply IHΔ; destruct (decide= a)).
+    + subst. left. now apply elem_of_list_In.
+    + left. auto with *.
+    + subst. right. apply make_conj_sound_L. auto with proof.
+    + left. auto with *.
+  - case in_dec; intro; apply IHΔ; right; trivial.
+     apply make_conj_sound_L. auto with proof.
+}
+intro Hin. apply Hcut. now left.
+Qed.
+ +
+(* TODO move up *)
+
+ +
+

Correctness of optimizations

+ + +
+ +To make the definitions of the propositional quantifiers that we extract from the Coq definition more readable, we introduced functions "make_impl", "make_conj" and "make_disj" in Environments.v which perform obvious simplifications such as reducing φ ∧ ⊥ to ⊥ and φ ∨ ⊥ to φ. The following results show that the definitions of these functions are correct, in the sense that it does not make a difference for provability of a sequent whether one uses the literal conjunction, disjunction, and implication, or its optimized version. +
+
+ +
+(* TODO: suitable name *)
+Lemma tautology_cut {Γ} {φ ψ θ : form} : Γ (φ ψ) θ -> (φ ψ) -> Γ θ.
+Proof.
+intros Hp H.
+apply additive_cut with ψ).
+  + apply ImpR, generalised_weakeningL. peapply H.
+  + apply Hp.
+Qed.
+ +
+Lemma Lindenbaum_Tarski_preorder_Bot φ : φ.
+Proof. apply ExFalso. Qed.
+ +
+Local Hint Resolve Lindenbaum_Tarski_preorder_Bot : proof.
+ +
+Lemma make_impl_sound_L Γ φ ψ θ: Γ•(φ ψ) θ -> Γ•(φ ψ) θ.
+Proof.
+revert φ. induction ψ; intros φ HP; simpl; repeat case decide; intros;
+repeat match goal with
+| H : obviously_smaller _ _ = Lt |- _ => apply obviously_smaller_compatible_LT in H
+| H : obviously_smaller _ _ = Gt |- _ => apply obviously_smaller_compatible_GT in H
+| H : is_negation _ _ |- _ => eapply additive_cut; [| exch 0; apply weakening, HP]; apply ImpR, exfalso; exch 0; auto with proof
+end; trivial; try (solve [eapply imp_cut; eauto]);
+try solve[apply weakening, (tautology_cut HP); trivial; try apply weak_cut with ; auto with proof].
+apply IHψ2.
+apply ImpLAnd in HP.
+apply additive_cut with ((φ ψ1 ψ2) θ).
+- apply weakening, ImpR, HP.
+- apply ImpL; [|auto with proof].
+  apply weakening, ImpR. exch 0. apply ImpL; [|auto with proof].
+  apply weakening, make_conj_complete_L, generalised_axiom.
+Qed.
+ +
+Global Hint Resolve make_impl_sound_L : proof.
+ +
+Lemma make_impl_sound_R Γ φ ψ: Γ (φ ψ) -> Γ φ ψ.
+Proof.
+revert φ. induction ψ; intros φ HP; simpl; repeat case decide; intros;
+repeat match goal with
+| H : obviously_smaller _ _ = Lt |- _ => apply obviously_smaller_compatible_LT in H
+| H : obviously_smaller _ _ = Gt |- _ => apply obviously_smaller_compatible_GT in H
+| H : is_negation _ _ |- _ => rewrite H in *; apply ImpR; eapply additive_cut; [apply ImpR_rev, HP| exch 0; auto with *]
+end; trivial; auto with proof;
+try (solve[peapply (cut Γ φ); auto with proof; eapply TopL_rev; eauto]).
+apply IHψ2, ImpR, make_conj_sound_L, AndL, ImpR_rev, ImpR_rev, HP.
+Qed.
+ +
+Global Hint Resolve make_impl_sound_R : proof.
+ +
+Lemma make_impl_sound_L2 Γ φ1 φ2 ψ θ: Γ•(φ1 (φ2 ψ)) θ -> Γ•(φ1 (φ2 ψ)) θ.
+Proof.
+intro HP. apply make_impl_sound_L in HP.
+apply additive_cut with (φ1 (φ2 ψ)).
+- apply make_impl_sound_L, make_impl_sound_R.
+  apply ImpR. exch 0. apply ImpL.
+  + apply weakening, generalised_axiom.
+  + exch 0. apply weakening, make_impl_sound_L, generalised_axiom.
+- exch 0. apply weakening, HP.
+Qed.
+ +
+Global Hint Resolve make_impl_sound_L2: proof.
+ +
+Lemma make_impl_sound_L2' Γ φ1 φ2 ψ θ: Γ•((φ1 φ2) ψ) θ -> Γ•((φ1 φ2) ψ) θ.
+Proof.
+intro HP. apply make_impl_sound_L.
+apply additive_cut with ((φ1 φ2) ψ); [|exch 0; apply weakening, HP].
+apply ImpR. exch 0. apply ImpL.
+- apply weakening, make_impl_sound_R, generalised_axiom.
+- apply generalised_axiom.
+Qed.
+ +
+Lemma make_impl_complete_L Γ φ ψ θ: Γ•(φ ψ) θ -> Γ•(φ ψ) θ.
+Proof.
+intro HP.
+apply additive_cut with ψ); [|exch 0; apply weakening, HP].
+apply make_impl_sound_R, generalised_axiom.
+Qed.
+ +
+Lemma make_impl_complete_L2 Γ φ1 φ2 ψ θ: Γ•(φ1 (φ2 ψ)) θ -> Γ•(φ1 (φ2 ψ)) θ.
+Proof.
+intro HP. apply make_impl_complete_L in HP.
+apply additive_cut with (φ1 φ2 ψ); [|exch 0; apply weakening, HP].
+apply ImpR. exch 0. apply ImpL.
+- apply weakening, generalised_axiom.
+- exch 0. apply weakening, make_impl_sound_R, generalised_axiom.
+Qed.
+ +
+Lemma make_impl_complete_R Γ φ ψ: Γ φ ψ -> Γ (φ ψ).
+Proof.
+intro HP.
+apply additive_cut with ψ); [apply HP| apply make_impl_sound_L, generalised_axiom ].
+Qed.
+ +
+Lemma OrR_idemp Γ ψ : Γ ψ ψ -> Γ ψ.
+Proof. intro Hp. dependent induction Hp; auto with proof. Qed.
+ +
+Lemma strongness φ : φ φ.
+Proof.
+apply BoxR. box_tac. apply weakening, open_box_L, generalised_axiom.
+Qed.
+
+
+ +
+ + + diff --git a/ISL.Order.html b/ISL.Order.html new file mode 100644 index 0000000..c1b88ff --- /dev/null +++ b/ISL.Order.html @@ -0,0 +1,497 @@ + + + + + + + + + + + + + +
+
+

ISL.Order

+ +
+Require Export ISL.Environments.
+ +
+(* Note 3 or 4 would suffice for IPC ; iSL requires 5 *)
+Definition env_weight (Γ : list form) := list_sum (map (fun x => 5^ weight x) Γ).
+ +
+Lemma env_weight_disj_union Γ Δ : env_weight (Γ ++ Δ) = env_weight Γ + env_weight Δ.
+Proof.
+unfold env_weight. now rewrite map_app, list_sum_app.
+Qed.
+ +
+(* TODO: dirty hack *)
+Local Notation "Δ '•' φ" := (cons φ Δ).
+ +
+Lemma env_weight_add Γ φ : env_weight (Γ φ) = env_weight Γ + (5 ^ weight φ).
+Proof.
+unfold env_weight. simpl. lia.
+Qed.
+ +
+Global Hint Rewrite env_weight_add : order.
+ +
+Definition env_order := ltof (list form) env_weight.
+Infix "≺" := env_order (at level 150).
+ +
+Lemma env_weight_singleton (φ : form) : env_weight [ φ ] = 5 ^ weight φ.
+Proof.
+unfold env_weight, ltof. simpl. lia.
+Qed.
+ +
+Lemma env_order_singleton (φ ψ : form) : weight φ < weight ψ -> [φ ] [ ψ ].
+Proof.
+intro Hw. unfold env_order, ltof. do 2 rewrite env_weight_singleton.
+apply Nat.pow_lt_mono_r. lia. trivial.
+Qed.
+ +
+Definition env_order_refl Δ Δ' := (Δ Δ') \/ Δ ≡ₚ Δ'.
+ +
+Local Notation "Δ ≼ Δ'" := (env_order_refl Δ Δ') (at level 150).
+ +
+Global Instance Proper_env_weight: Proper ((≡ₚ) ==> (=)) env_weight.
+Proof.
+intros Γ Δ Heq. unfold env_weight. now rewrite Heq.
+Qed.
+ +
+Global Instance Proper_env_order_refl_env_weight:
+  Proper ((env_order_refl) ==> le) env_weight.
+Proof.
+intros Γ Δ.
+unfold env_order. intros [Hle | Heq].
+- auto with *.
+- now rewrite Heq.
+Qed.
+ +
+Global Hint Resolve Proper_env_order_refl_env_weight : order.
+ +
+Global Hint Unfold form_order : mset.
+ +
+Global Instance env_order_trans : Transitive env_order.
+Proof. unfold env_order, env_weight, ltof. auto with *. Qed.
+ +
+Definition wf_env_order : well_founded env_order.
+Proof. now apply well_founded_lt_compat with env_weight.
+Defined.
+ +
+(* We introduce a notion of "pointed" environment, which is simply
+ * a pair (Δ, φ), where Δ is an environment and φ is a formula,
+ * not necessarily an element of Δ.  *)

+Definition pointed_env := (list form * form)%type.
+ +
+(* The order on pointed environments is given by considering the
+ * environment order on the sum of Δ and {φ}. *)

(* TODO: modified from G4IP : right-hand side counts twice, to account for the right box rule. Is this working? *)
+Definition pointed_env_order (pe1 : pointed_env) (pe2 : pointed_env) :=
+  env_order (fst pe1 snd pe1 snd pe1) (fst pe2 snd pe2 snd pe2).
+ +
+Lemma wf_pointed_order : well_founded pointed_env_order.
+Proof. apply well_founded_ltof. Qed.
+ +
+Definition pointed_env_ms_order (Γφ Δψ : env * form) :=
+  pointed_env_order (elements Γφ.1, Γφ.2) (elements Δψ.1, Δψ.2).
+ +
+Lemma wf_pointed_env_ms_order : well_founded pointed_env_ms_order.
+Proof. apply well_founded_ltof. Qed.
+ +
+Infix "≺·" := pointed_env_order (at level 150).
+ +
+Lemma env_order_equiv_right_compat {Δ Δ' Δ'' }:
+  Δ' ≡ₚ Δ'' ->
+  (Δ Δ'') ->
+  Δ Δ'.
+Proof.
+unfold equiv, env_order, ltof, env_weight. intro Heq. rewrite Heq. trivial.
+Qed.
+ +
+Lemma env_order_equiv_left_compat {Δ Δ' Δ'' }:
+  Δ ≡ₚ Δ'' ->
+  (Δ'' Δ') ->
+  Δ Δ'.
+Proof. unfold equiv, env_order, ltof, env_weight. intro Heq. rewrite Heq. trivial. Qed.
+ +
+Global Instance Proper_env_order : Proper ((≡ₚ) ==> (≡ₚ) ==> (fun x y => x <-> y)) env_order.
+Proof. intros Δ1 Δ2 H12 Δ3 Δ4 H34; unfold equiv, env_order, ltof, env_weight. rewrite H12, H34. tauto. Qed.
+ +
+Global Instance Proper_env_order_refl : Proper ((≡ₚ) ==> (≡ₚ) ==> (fun x y => x <-> y)) env_order_refl.
+Proof.
+intros Δ1 Δ2 H12 Δ3 Δ4 H34; unfold equiv, env_order, ltof, env_weight, env_order_refl.
+now rewrite H12, H34.
+Qed.
+ +
+Lemma env_order_1 Δ φ1 φ : weight φ1 < weight φ -> Δ φ1 Δ φ.
+Proof.
+intros Hw. unfold env_order, ltof. do 2 rewrite env_weight_add.
+apply Nat.add_lt_mono_l. apply Nat.pow_lt_mono_r. lia. trivial.
+Qed.
+ +
+Local Hint Resolve Nat.pow_lt_mono_r : order.
+ +
+Lemma env_order_compat Δ Δ' φ1 φ : weight φ1 < weight φ -> (Δ' Δ) -> Δ' φ1 Δ φ.
+Proof.
+intros. unfold env_order, ltof. repeat rewrite env_weight_add.
+apply Nat.add_le_lt_mono; auto with *.
+Qed.
+ +
+Global Hint Resolve env_order_compat : order.
+ +
+Lemma env_order_compat' Δ Δ' φ1 φ : weight φ1 weight φ -> (Δ' Δ) -> Δ' φ1 Δ φ.
+Proof.
+intros. unfold env_order, ltof. repeat rewrite env_weight_add.
+apply Nat.add_lt_le_mono; auto with *. now apply Nat.pow_le_mono_r.
+Qed.
+ +
+Lemma env_order_add_compat Δ Δ' φ : (Δ Δ') -> (Δ φ) (Δ' φ).
+Proof.
+unfold env_order, ltof. do 2 rewrite env_weight_add. lia.
+Qed.
+ +
+(* TODO: this is just a special case *)
+Lemma env_order_disj_union_compat_left Δ Δ' Δ'':
+  (Δ Δ'') -> Δ ++ Δ' Δ'' ++ Δ'.
+Proof.
+unfold env_order, ltof. intro. do 2 rewrite env_weight_disj_union. lia.
+Qed.
+ +
+Lemma env_order_disj_union_compat_right Δ Δ' Δ'':
+  (Δ Δ'') -> Δ' ++ Δ Δ' ++ Δ''.
+Proof.
+unfold env_order, ltof. repeat rewrite env_weight_disj_union. lia.
+Qed.
+ +
+Global Hint Resolve env_order_disj_union_compat_right : order.
+ +
+Lemma env_order_disj_union_compat Δ Δ' Δ'' Δ''':
+  (Δ Δ'') -> (Δ' Δ''') -> Δ ++ Δ' Δ'' ++ Δ'''.
+Proof.
+unfold env_order, ltof. repeat rewrite env_weight_disj_union. lia.
+Qed.
+ +
+Lemma env_order_refl_disj_union_compat Δ Δ' Δ'' Δ''':
+  (env_order_refl Δ Δ'') -> (env_order_refl Δ' Δ''') -> env_order_refl (Δ ++ Δ') (Δ'' ++ Δ''').
+Proof.
+unfold env_order_refl, env_order, ltof. repeat rewrite env_weight_disj_union.
+intros [Hlt1 | Heq1] [Hlt2 | Heq2]; try rewrite Heq1; try rewrite Heq2; try lia.
+right. trivial.
+Qed.
+ +
+Global Hint Resolve env_order_refl_disj_union_compat : order.
+ +
+Hint Unfold env_order_refl : order.
+Lemma env_order_disj_union_compat_strong_right Δ Δ' Δ'' Δ''':
+  (Δ Δ'') -> (Δ' Δ''') -> Δ ++ Δ' Δ'' ++ Δ'''.
+Proof.
+intros H1 H2.
+destruct H2 as [Hlt|Heq].
+- unfold env_order, ltof in *. do 2 rewrite env_weight_disj_union. lia.
+- rewrite Heq. now apply env_order_disj_union_compat_left.
+Qed.
+ +
+Lemma env_order_disj_union_compat_strong_left Δ Δ' Δ'' Δ''':
+  (Δ Δ'') -> (Δ' Δ''') -> Δ ++ Δ' Δ'' ++ Δ'''.
+Proof.
+intros H1 H2.
+destruct H1 as [Hlt|Heq].
+- unfold env_order, ltof in *. do 2 rewrite env_weight_disj_union. lia.
+- rewrite Heq. now apply env_order_disj_union_compat_right.
+Qed.
+ +
+Global Hint Resolve env_order_disj_union_compat_strong_left : order.
+Global Hint Rewrite elements_open_boxes : order.
+ +
+Lemma weight_open_box φ : weight ( φ) weight φ.
+Proof. destruct φ; simpl; lia. Qed.
+ +
+Lemma open_boxes_env_order Δ : (map open_box Δ) Δ.
+Proof.
+induction Δ as [|φ Δ].
+- right. trivial.
+- destruct IHΔ as [Hlt | Heq]; simpl.
+  + left. apply env_order_compat'; trivial. apply weight_open_box.
+  + rewrite Heq. auto with order. destruct φ; simpl; try auto with order.
+       left. auto with order.
+Qed.
+ +
+Global Hint Resolve open_boxes_env_order : order.
+ +
+Lemma env_order_0 Δ φ: Δ Δ φ.
+Proof.
+unfold env_order, ltof. rewrite env_weight_add.
+apply Nat.lt_add_pos_r. transitivity (5 ^ 0). simpl. lia. apply Nat.pow_lt_mono_r. lia.
+apply weight_pos.
+Qed.
+ +
+(* TODO: ok? to replace env_order_* ?
+Lemma env_order_l (Δ' Δ: env) φ1 φ: weight φ1 < weight φ -> (Δ' ≺ Δ • φ) -> (Δ' • φ1) ≺ (Δ • φ).
+Proof.
+*)

+ +
+Local Lemma pow5_gt_0 n : 1 5 ^ n.
+Proof. transitivity (5^0). simpl. lia. apply Nat.pow_le_mono_r; lia. Qed.
+ +
+Local Hint Resolve pow5_gt_0: order.
+ +
+Lemma env_order_2 Δ Δ' φ1 φ2 φ: weight φ1 < weight φ -> weight φ2 < weight φ ->
+  (Δ' Δ) -> Δ' φ1 φ2 Δ φ.
+Proof.
+intros Hw1 Hw2 Hor.
+unfold env_order, ltof. repeat rewrite env_weight_add.
+apply Proper_env_order_refl_env_weight in Hor.
+replace (weight φ) with (S (pred (weight φ))) by lia.
+apply Nat.lt_le_pred in Hw1, Hw2.
+simpl. repeat rewrite Nat.add_assoc.
+pose (pow5_gt_0 (Init.Nat.pred (weight φ))).
+rewrite Nat.add_0_r.
+repeat (apply Nat.add_lt_le_mono; [|apply Nat.pow_le_mono_r; lia]).
+pose (pow5_gt_0 (Init.Nat.pred (weight φ))).
+lia.
+Qed.
+ +
+Lemma env_order_3 Δ Δ' φ1 φ2 φ3 φ:
+  weight φ1 < weight φ -> weight φ2 < weight φ -> weight φ3 < weight φ -> (Δ' Δ) ->
+  Δ' φ1 φ2 φ3 Δ φ.
+Proof.
+intros Hw1 Hw2 Hw3 Hor.
+unfold env_order, ltof. repeat rewrite env_weight_add.
+apply Proper_env_order_refl_env_weight in Hor.
+replace (weight φ) with (S (pred (weight φ))) by lia.
+apply Nat.lt_le_pred in Hw1, Hw2.
+simpl. repeat rewrite Nat.add_assoc.
+pose (pow5_gt_0 (Init.Nat.pred (weight φ))).
+rewrite Nat.add_0_r.
+do 3 (apply Nat.add_lt_le_mono; [|apply Nat.pow_le_mono_r; lia]).
+pose (pow5_gt_0 (Init.Nat.pred (weight φ))).
+lia.
+Qed.
+ +
+Lemma env_order_4 Δ Δ' φ1 φ2 φ3 φ4 φ:
+  weight φ1 < weight φ -> weight φ2 < weight φ -> weight φ3 < weight φ -> weight φ4 < weight φ ->
+   (Δ' Δ) -> Δ' φ1 φ2 φ3 φ4 Δ φ.
+Proof.
+intros Hw1 Hw2 Hw3 Hw4 Hor.
+unfold env_order, ltof. repeat rewrite env_weight_add.
+apply Proper_env_order_refl_env_weight in Hor.
+replace (weight φ) with (S (pred (weight φ))) by lia.
+apply Nat.lt_le_pred in Hw1, Hw2.
+simpl. repeat rewrite Nat.add_assoc.
+pose (pow5_gt_0 (Init.Nat.pred (weight φ))).
+rewrite Nat.add_0_r.
+do 4 (apply Nat.add_lt_le_mono; [|apply Nat.pow_le_mono_r; lia]).
+pose (pow5_gt_0 (Init.Nat.pred (weight φ))).
+lia.
+Qed.
+ +
+Lemma env_order_cancel_right Δ Δ' φ: (Δ Δ') -> Δ (Δ' φ).
+Proof. etransitivity; [|apply env_order_0]. assumption. Qed.
+ +
+Lemma env_order_eq_add Δ Δ' φ: (Δ Δ') -> (Δ φ) (Δ' φ).
+Proof. intros[Heq|Hlt]. left. now apply env_order_add_compat. right. ms. Qed.
+ +
+Global Hint Resolve env_order_0 : order.
+Global Hint Resolve env_order_1 : order.
+Global Hint Resolve env_order_2 : order.
+Global Hint Resolve env_order_3 : order.
+Global Hint Resolve env_order_4 : order.
+Global Hint Resolve env_order_add_compat : order.
+Global Hint Resolve env_order_cancel_right : order.
+Global Hint Resolve env_order_eq_add : order.
+Global Hint Extern 1 (?a < ?b) => subst; simpl; lia : order.
+ +
+Ltac get_diff_form g := match g with
+| ?Γ {[]} => φ
+| _ (?Γ {[]}) => φ
+| _ (rm_) => φ
+| ?Γ _ => get_diff_form Γ
+end.
+ +
+Ltac get_diff_env g := match g with
+| ?Γ {[]} => Γ
+| ?Γ _ => get_diff_env Γ
+end.
+ +
+Global Hint Rewrite open_boxes_remove : order.
+ +
+Lemma remove_env_order Δ φ: rm φ Δ Δ.
+Proof.
+induction Δ as [|ψ Δ].
+- simpl. right. auto.
+- simpl. destruct form_eq_dec; auto with order.
+Qed.
+ +
+Global Hint Resolve remove_env_order : order.
+ +
+Lemma remove_In_env_order_refl Δ φ: In φ Δ -> rm φ Δ φ Δ.
+Proof.
+induction Δ as [|ψ Δ].
+- intro Hf; contradict Hf.
+- intros [Heq | Hin].
+  + subst. simpl. destruct form_eq_dec; [|tauto]. auto with order.
+  + specialize (IHΔ Hin). simpl. case form_eq_dec as [Heq | Hneq].
+      * subst. auto with order.
+      * rewrite (Permutation_swap ψ φ (rm φ Δ)). auto with order.
+Qed.
+ +
+Global Hint Resolve remove_In_env_order_refl : order.
+ +
+Lemma env_order_lt_le_trans Γ Γ' Γ'' : (Γ Γ') -> (Γ' Γ'') -> Γ Γ''.
+Proof. intros Hlt [Hlt' | Heq]. transitivity Γ'; auto with order. now rewrite <- Heq. Qed.
+ +
+Lemma env_order_le_lt_trans Γ Γ' Γ'' : (Γ Γ') -> (Γ' Γ'') -> Γ Γ''.
+Proof. intros [Hlt' | Heq] Hlt. transitivity Γ'; auto with order. now rewrite Heq. Qed.
+ +
+Lemma remove_In_env_order Δ φ: In φ Δ -> rm φ Δ Δ.
+Proof.
+intro Hin. apply remove_In_env_order_refl in Hin.
+eapply env_order_lt_le_trans; [|apply Hin]. auto with order.
+Qed.
+ +
+Global Hint Resolve remove_In_env_order : order.
+ +
+Lemma elem_of_list_In_1 {A : Type}: (l : list A) (x : A), x l -> In x l.
+Proof. apply elem_of_list_In. Qed.
+ +
+Global Hint Resolve elem_of_list_In_1 : order.
+ +
+Lemma elements_elem_of {Γ : env} {φ : form} : φ Γ -> elements Γ ≡ₚ φ :: elements (Γ {[φ]}).
+Proof. intro Hin. rewrite <- elements_env_add. apply Proper_elements, difference_singleton, Hin. Qed.
+ +
+Ltac prepare_order :=
+repeat (apply env_order_add_compat);
+unfold pointed_env_order; subst; simpl; repeat rewrite open_boxes_add; try match goal with
+| Δ := _ |- _ => subst Δ; try prepare_order
+| Hin : ?a ?Γ |- context[elements ?Γ] => rewrite (elements_elem_of Hin); try prepare_order
+| H : _ list_to_set_disj _ |- _ => apply elem_of_list_to_set_disj in H; try prepare_order
+| H : ?ψ ?Γ |- ?Γ' ?Γ => let ψ' := (get_diff_form Γ') in
+    apply (env_order_equiv_right_compat (difference_singleton Γ ψ' H)) ||
+    (eapply env_order_lt_le_trans ; [| apply (remove_In_env_order_refl _ ψ'); try apply elem_of_list_In; trivial])
+| H : ?ψ ?Γ |- ?Γ' ?Γ ?φ => let ψ' := (get_diff_form Γ') in
+    apply (env_order_equiv_right_compat (equiv_disj_union_compat_r(difference_singleton Γ ψ' H)))
+| H : ?ψ ?Γ |- ?Γ' ?Γ _ _ => let ψ' := (get_diff_form Γ') in
+apply (env_order_equiv_right_compat (equiv_disj_union_compat_r(equiv_disj_union_compat_r(difference_singleton Γ ψ' H)))) ||
+(eapply env_order_le_lt_trans; [| apply env_order_add_compat;
+eapply env_order_lt_le_trans; [| (apply env_order_eq_add; apply (remove_In_env_order_refl _ ψ'); try apply elem_of_list_In; trivial) ] ] )
+end.
+ +
+(* ad hoc *)
+Lemma openboxes_env_order Δ δ : (map open_box Δ) δ δ Δ δ.
+Proof.
+induction Δ as [|x Δ].
+- simpl. unfold env_order, ltof, env_weight. simpl.
+  repeat rewrite <- plus_n_O. apply Nat.add_lt_mono_l.
+  rewrite plus_n_O at 1. auto with *.
+- apply (@env_order_equiv_right_compat _ _ (Δ δ x)). constructor.
+  simpl.
+  eapply (@env_order_equiv_left_compat _ _ (map open_box Δ δ δ x)).
+  + do 2 (rewrite (Permutation_swap δ ( x)); apply Permutation_skip). trivial.
+  + case x; intros; simpl; try (solve[now apply env_order_add_compat]).
+      transitivity (Δ δ f).
+      * auto with *.
+      * apply env_order_1. simpl. auto.
+Qed.
+ +
+Global Hint Resolve openboxes_env_order : order.
+ +
+Ltac order_tac :=
+try unfold pointed_env_ms_order; prepare_order;
+repeat rewrite elements_env_add;
+simpl; auto 10 with order;
+try (apply env_order_disj_union_compat_right; order_tac).
+
+
+ +
+ + + diff --git a/ISL.PropQuantifiers.html b/ISL.PropQuantifiers.html new file mode 100644 index 0000000..0550ba9 --- /dev/null +++ b/ISL.PropQuantifiers.html @@ -0,0 +1,1209 @@ + + + + + + + + + + + + + +
+
+

ISL.PropQuantifiers

+ +
+Require Import ISL.Sequents.
+Require Import ISL.SequentProps ISL.Order ISL.Optimizations.
+Require Import Coq.Program.Equality. (* for dependent induction *)
+ +
+
+ +
+

Overview: Propositional Quantifiers

+ + +
+ +The main theorem proved in this file was first proved as Theorem 1 in: + +
+ +(Pitts 1992). A. M. Pitts. On an interpretation of second order quantification in first order intuitionistic propositional logic. J. Symb. Log., 57(1):33–52. +It has been further extended to handle iSL + +
+ +It consists of two parts: + +
+ +1) the inductive construction of the propositional quantifiers; + +
+ +2) a proof of its correctness. +
+
+ +
+Section UniformInterpolation.
+ +
+
+ +
+Throughout the construction and proof, we fix a variable p, with respect to + which the propositional quantifier will be computed. +
+
+Variable p : variable.
+ +
+
+ +
+

Definition of propositional quantifiers.

+ +
+
+ +
+Section PropQuantDefinition.
+ +
+
+ +
+We define the formulas Eφ and Aφ associated to any formula φ. This + is an implementation of Pitts' Table 5, together with a (mostly automatic) + proof that the definition terminates +
+
+ +
+Local Notation "Δ '•' φ" := (cons φ Δ).
+ +
+(* solves the obligations of the following programs *)
+Obligation Tactic := intros; order_tac.
+ +
+Notation "□⁻¹ Γ" := (map open_box Γ) (at level 75).
+ +
+
+ +
+First, the implementation of the rules for calculating E. The names of the rules + refer to the table in Pitts' paper. note the use of "lazy" conjunctions, disjunctions and implications +
+
+Program Definition e_rule {Δ : list form } {ϕ : form}
+  (EA0 : pe (Hpe : pe ≺· (Δ, ϕ)), form * form)
+  (θ: form) (Hin : θ Δ) : form :=
+let E Δ H := fst (EA0 (Δ, ϕ) H) in
+let A pe0 H := snd (EA0 pe0 H) in
+let Δ' := rm θ Δ in
+match θ with
+| Bot => (* E0 *)
+| Var q =>
+    if decide (p = q) then (* default *)
+    else q (* E1 modified *)
+(* E2 *)
+| δ₁ δ₂ => E ((Δ'δ₁)•δ₂) _
+(* E3 *)
+| δ₁ δ₂ => E (Δ'δ₁) _ E (Δ' δ₂) _
+| Var q δ =>
+    if decide (Var q Δ) then E (Δ'δ) _ (* E5 modified *)
+    else if decide (p = q) then
+    else q E (Δ'δ) _ (* E4 *)
+(* E6 *)
+| (δ₁ δ₂)→ δ₃ => E (Δ'•(δ₁ (δ₂ δ₃))) _
+(* E7 *)
+| (δ₁ δ₂)→ δ₃ => E (Δ'•(δ₁ δ₃)•(δ₂ δ₃)) _
+(* E8 modified *)
+| ((δ₁ δ₂)→ δ₃) =>
+  (E (Δ'•(δ₂ δ₃) δ₁) _ A (Δ'•(δ₂ δ₃) δ₁, δ₂) _) E (Δ'δ₃) _
+| Bot _ =>
+| φ => □(E ((⁻¹ Δ') φ ) _) (* very redundant ; identical for each box *)
+| (δ1 δ2) => (□(E((⁻¹ Δ') δ2 δ1) _ A((⁻¹ Δ') δ2 δ1, δ1) _)) E(Δ' δ2) _
+end.
+ +
+
+ +
+The implementation of the rules for defining A is separated into two pieces. + Referring to Table 5 in Pitts, the definition a_rule_env handles A1-8 and A10, + and the definition a_rule_form handles A9 and A11-13. +
+
+Program Definition a_rule_env {Δ : list form} {ϕ : form}
+  (EA0 : pe (Hpe : pe ≺· (Δ, ϕ)), form * form)
+  (θ: form) (Hin : θ Δ) : form :=
+let E Δ H := fst (EA0 (Δ, ϕ) H) in
+let A pe0 H := snd (EA0 pe0 H) in
+let Δ' := rm θ Δ in
+match θ with
+| Var q =>
+    if decide (p = q)
+    then
+      if decide (Var p = ϕ) then (* A10 *)
+      else
+    else (* A1 modified : A (Δ', ϕ) can be removed *)
+(* A2 *)
+| δ₁ δ₂ => A ((Δ'δ₁)•δ₂, ϕ) _
+(* A3 *)
+| δ₁ δ₂ =>
+      (E (Δ'δ₁) _ A (Δ'δ₁, ϕ) _)
+   (E (Δ'δ₂) _ A (Δ'δ₂, ϕ) _)
+| Var q δ =>
+    if decide (Var q Δ) then A (Δ'δ, ϕ) _ (* A5 modified *)
+    else if decide (p = q) then
+    else q A (Δ'δ, ϕ) _ (* A4 *)
+(* A6 *)
+| (δ₁ δ₂)→ δ₃ =>
+  A (Δ'•(δ₁ (δ₂ δ₃)), ϕ) _
+(* A7 *)
+| (δ₁ δ₂)→ δ₃ =>
+  A ((Δ'•(δ₁ δ₃))•(δ₂ δ₃), ϕ) _
+(* A8 modified*)
+| ((δ₁ δ₂)→ δ₃) =>
+  (E (Δ'•(δ₂ δ₃) δ₁) _ A (Δ'•(δ₂ δ₃) δ₁, δ₂) _)
+   A (Δ'δ₃, ϕ) _
+| Bot =>
+| Bot _ =>
+| δ =>
+| ((δ1) δ2) => (□(E((⁻¹ Δ')• δ2 δ1) _ A((⁻¹ Δ')• δ2 δ1, δ1) _)) A(Δ' δ2, ϕ) _
+(* using ⊼ here breaks congruence *)
+end.
+ +
+(* make sure that the proof obligations do not depend on EA0 *)
+Obligation Tactic := intros Δ ϕ _ _ _; intros; order_tac.
+Program Definition a_rule_form {Δ : list form} {ϕ : form}
+  (EA0 : pe (Hpe : pe ≺· (Δ, ϕ)), form * form) : form :=
+let E pe0 H := fst (EA0 pe0 H) in
+let A pe0 H := snd (EA0 pe0 H) in
+match ϕ with
+| Var q =>
+    if decide (p = q) (* TODO : change this to p∈Vars(ϕ) *)
+    then
+    else Var q (* A9 *)
+(* A11 *)
+| ϕ₁ ϕ₂ => A (Δ, ϕ₁) _ A (Δ, ϕ₂) _
+(* A12 *)
+| ϕ₁ ϕ₂ => A (Δ, ϕ₁) _ A (Δ, ϕ₂) _
+(* A13 *)
+| ϕ₁ ϕ₂ => E (Δϕ₁, ϕ₂) _ A (Δϕ₁, ϕ₂) _
+    (* TODO would a general right-implication rule be useful efficient? *)
+| Bot =>
+| δ => □((E ((⁻¹ Δ) δ, δ) _) A((⁻¹ Δ) δ, δ) _)
+end.
+ +
+Obligation Tactic := intros; order_tac.
+Program Fixpoint EA (pe : list form * form) {wf pointed_env_order pe} :=
+  let Δ := fst pe in
+  ( (in_map Δ (e_rule EA)),
+    (in_map Δ (a_rule_env EA)) a_rule_form EA).
+Next Obligation. apply wf_pointed_order. Defined.
+ +
+Definition E pe := (EA pe).1.
+Definition A pe := (EA pe).2.
+ +
+Definition Ef (ψ : form) := E ([ψ], ).
+Definition Af (ψ : form) := A ([], ψ).
+ +
+
+ +
+Congruence lemmas: if we apply any of e_rule, a_rule_env, or a_rule_form + to two equal environments, then they give the same results. +
+
+Lemma e_rule_cong Δ ϕ θ (Hin: θ Δ) EA1 EA2:
+  (forall pe Hpe, EA1 pe Hpe = EA2 pe Hpe) ->
+  @e_rule Δ ϕ EA1 θ Hin = @e_rule Δ ϕ EA2 θ Hin.
+Proof.
+  intro Heq.
+  destruct θ; simpl; try (destruct θ1); repeat (destruct decide);
+  f_equal; repeat erewrite Heq; trivial.
+Qed.
+ +
+Lemma e_rule_cong_strong Δ ϕ θ (Hin1 Hin2: θ Δ) EA1 EA2:
+  (forall pe Hpe1 Hpe2, EA1 pe Hpe1 = EA2 pe Hpe2) ->
+  @e_rule Δ ϕ EA1 θ Hin1 = @e_rule Δ ϕ EA2 θ Hin2.
+Proof.
+  intro Heq.
+  destruct θ; simpl; try (destruct θ1); repeat (destruct decide);
+  f_equal; repeat erewrite Heq; trivial.
+Qed.
+ +
+Lemma a_rule_env_cong Δ ϕ θ Hin EA1 EA2:
+  (forall pe Hpe, EA1 pe Hpe = EA2 pe Hpe) ->
+  @a_rule_env Δ ϕ EA1 θ Hin = @a_rule_env Δ ϕ EA2 θ Hin.
+Proof.
+  intro Heq.
+  destruct θ; simpl; trivial; repeat (destruct decide);
+  f_equal; repeat erewrite Heq; trivial;
+  destruct θ1; try (destruct decide); trivial; simpl;
+  repeat erewrite Heq; trivial; (destruct decide); trivial.
+Qed.
+ +
+Lemma a_rule_env_cong_strong Δ ϕ θ Hin1 Hin2 EA1 EA2:
+  (forall pe Hpe1 Hpe2, EA1 pe Hpe1 = EA2 pe Hpe2) ->
+  @a_rule_env Δ ϕ EA1 θ Hin1 = @a_rule_env Δ ϕ EA2 θ Hin2.
+Proof.
+  intro Heq.
+  destruct θ; simpl; trivial; repeat (destruct decide);
+  f_equal; repeat erewrite Heq; trivial;
+  destruct θ1; try (destruct decide); trivial; simpl;
+  repeat erewrite Heq; trivial; (destruct decide); trivial.
+Qed.
+ +
+Lemma a_rule_form_cong Δ ϕ EA1 EA2:
+  (forall pe Hpe, EA1 pe Hpe = EA2 pe Hpe) ->
+  @a_rule_form Δ ϕ EA1 = @a_rule_form Δ ϕ EA2.
+Proof.
+  intro Heq.
+  destruct ϕ; simpl; repeat (destruct decide); trivial;
+  repeat (erewrite Heq; eauto); trivial.
+Qed.
+ +
+Lemma a_rule_form_cong_strong Δ ϕ EA1 EA2:
+  (forall pe Hpe1 Hpe2, EA1 pe Hpe1 = EA2 pe Hpe2) ->
+  @a_rule_form Δ ϕ EA1 = @a_rule_form Δ ϕ EA2.
+Proof.
+  intro Heq.
+  destruct ϕ; simpl; repeat (destruct decide); trivial;
+  repeat (erewrite Heq; eauto); trivial.
+Qed.
+ +
+Lemma EA_eq Δ ϕ:
+  (E (Δ, ϕ) = (in_map Δ (@e_rule Δ ϕ (λ pe _, EA pe)))) /\
+  (A (Δ, ϕ) = ( (in_map Δ (@a_rule_env Δ ϕ (λ pe _, EA pe))))
+       @a_rule_form Δ ϕ (λ pe _, EA pe)).
+Proof.
+simpl. unfold E, A, EA. simpl.
+rewrite -> Wf.Fix_eq.
+- simpl. split; trivial.
+- intros Δ' f g Heq. f_equal; f_equal.
+  + apply in_map_ext. intros. apply e_rule_cong; intros.
+      now rewrite Heq.
+  + f_equal. apply in_map_ext. intros. apply a_rule_env_cong; intros.
+      now rewrite Heq.
+  + apply a_rule_form_cong; intros. now rewrite Heq.
+Qed.
+ +
+Definition E_eq Δ ϕ := proj1 (EA_eq Δ ϕ).
+Definition A_eq Δ ϕ := proj2 (EA_eq Δ ϕ).
+ +
+End PropQuantDefinition.
+ +
+
+ +
+

Correctness

+ +
+
+Section Correctness.
+ +
+
+ +
+This section contains the proof of Proposition 5, the main correctness result, stating that the E- and A-formulas defined above are indeed existential and universal propositional quantified versions of the original formula, respectively. +
+ +

(i) Variables

+ +
+
+Section VariablesCorrect.
+ +
+
+ +
+In this subsection we prove (i), which states that the variable p no longer + occurs in the E- and A-formulas, and that the E- and A-formulas contain no more variables than the original formula. + +
+
+ +
+(* A general tactic for variable occurrences *)
+Ltac vars_tac :=
+intros; subst;
+repeat match goal with
+| HE : context [occurs_in ?x (?E _ _)], H : occurs_in ?x (?E _ _) |- _ =>
+    apply HE in H
+end;
+intuition;
+repeat match goal with | H : exists x, _ |- _ => destruct H end;
+intuition;
+simpl in *; in_tac; try (split; [tauto || auto with *|]); simpl in *;
+try match goal with
+| H : occurs_in _ (?a (?b ?c)) |- _ => apply occurs_in_make_impl2 in H
+| H : occurs_in _ (?a ?b) |- _ => apply occurs_in_make_impl in H
+| H : occurs_in _ (?a ?b) |- _ => apply occurs_in_make_disj in H
+| H : occurs_in _ (?a ?b) |- _ => apply occurs_in_make_conj in H
+|H1 : ?x0 ( ?Δ), H2 : occurs_in ?x ?x0 |- _ =>
+      apply (occurs_in_open_boxes _ _ _ H2) in H1
+|H1 : ?x0 (map open_box ?Δ), H2 : occurs_in ?x ?x0 |- _ =>
+      apply (occurs_in_map_open_box _ _ _ H2) in H1
+end; repeat rewrite elem_of_cons in * ; intuition; subst;
+repeat match goal with | H : exists x, _ |- _ => destruct H end; intuition;
+try multimatch goal with
+| H : ?θ0 ?Δ0 |- context [exists θ, θ ?Δ /\ occurs_in ?x θ] =>
+  solve[try right; exists θ0; split; [eauto using remove_include|simpl; tauto]; eauto] end.
+ +
+
+ +
+

(a)

+ +
+
+ +
+Lemma e_rule_vars Δ (θ : form) (Hin : θ Δ) (ϕ : form)
+  (EA0 : pe (Hpe : pe ≺· (Δ, ϕ)), form * form) x
+  (HEA0 : pe Hpe,
+      (occurs_in x (fst (EA0 pe Hpe)) -> x p θ, θ pe.1 /\ occurs_in x θ) /\
+      (occurs_in x (snd (EA0 pe Hpe)) -> x p (occurs_in x pe.2 \/ θ, θ pe.1 /\ occurs_in x θ))) :
+occurs_in x (e_rule EA0 θ Hin) -> x p θ, θ Δ /\ occurs_in x θ.
+Proof.
+destruct θ; unfold e_rule; simpl; try tauto; try solve [repeat case decide; repeat vars_tac].
+destruct θ1; repeat case decide; repeat vars_tac.
+Qed.
+ +
+
+ +
+

(b)

+ +
+
+ +
+Lemma a_rule_env_vars Δ θ Hin ϕ
+  (EA0 : pe (Hpe : pe ≺· (Δ, ϕ)), form * form) x
+  (HEA0 : pe Hpe,
+      (occurs_in x (fst (EA0 pe Hpe)) -> x p θ, θ pe.1 /\ occurs_in x θ) /\
+      (occurs_in x (snd (EA0 pe Hpe)) -> x p (occurs_in x pe.2 \/ θ, θ pe.1 /\ occurs_in x θ))):
+occurs_in x (a_rule_env EA0 θ Hin) -> x p (occurs_in x ϕ \/ θ, θ Δ /\ occurs_in x θ).
+Proof.
+destruct θ; unfold a_rule_env; simpl; try tauto; try solve [repeat case decide; repeat vars_tac].
+destruct θ1; repeat case decide; repeat vars_tac.
+Qed.
+ +
+Lemma a_rule_form_vars Δ ϕ
+  (EA0 : pe (Hpe : pe ≺· (Δ, ϕ)), form * form) x
+  (HEA0 : pe Hpe,
+      (occurs_in x (fst (EA0 pe Hpe)) -> x p θ, θ pe.1 /\ occurs_in x θ) /\
+      (occurs_in x (snd (EA0 pe Hpe)) -> x p (occurs_in x pe.2 \/ θ, θ pe.1 /\ occurs_in x θ))):
+  occurs_in x (a_rule_form EA0) -> x p (occurs_in x ϕ \/ θ, θ Δ /\ occurs_in x θ).
+Proof.
+destruct ϕ; unfold a_rule_form; simpl; try tauto; try solve [repeat case decide; repeat vars_tac].
+Qed.
+ +
+Proposition EA_vars Δ ϕ x:
+  (occurs_in x (E (Δ, ϕ)) -> x <> p /\ θ, θ Δ /\ occurs_in x θ) /\
+  (occurs_in x (A (Δ, ϕ)) -> x <> p /\ (occurs_in x ϕ \/ ( θ, θ Δ /\ occurs_in x θ))).
+Proof.
+remember (Δ, ϕ) as pe.
+replace Δ with pe.1 by now subst.
+replace ϕ with pe.2 by now subst. clear Heqpe Δ ϕ. revert pe.
+refine (@well_founded_induction _ _ wf_pointed_order _ _).
+intros [Δ ϕ] Hind. simpl.
+rewrite E_eq, A_eq. simpl.
+split.
+(* E *)
+- intros Hocc. apply variables_conjunction in Hocc as (φ&Hin&Hφ).
+  apply in_in_map in Hin as (ψ&Hin&Heq). subst φ.
+  apply e_rule_vars in Hφ.
+  + trivial.
+  + intros; now apply Hind.
+(* A *)
+- intro Hocc. apply occurs_in_make_disj in Hocc as [Hocc|Hocc].
+  (* disjunction *)
+  + apply variables_disjunction in Hocc as (φ&Hin&Hφ).
+      apply in_in_map in Hin as (ψ&Hin&Heq). subst φ.
+      apply a_rule_env_vars in Hφ; trivial.
+  (* pointer rule *)
+  + apply a_rule_form_vars in Hocc.
+    * destruct Hocc as [Hneq [Hocc | Hocc]]; vars_tac.
+    * vars_tac; apply Hind in H; trivial; tauto.
+Qed.
+ +
+End VariablesCorrect.
+ +
+Ltac foldEA := repeat match goal with
+| |- context C [(EA ?pe).1] => fold (E pe)
+| |- context C [(EA ?pe).2] => fold (A pe)
+end.
+ +
+
+ +
+

(ii) Entailment

+ +
+
+Section EntailmentCorrect.
+ +
+
+ +
+In this section we prove (ii), which states that the E- and A-formula are + entailed by the original formula and entail the original formula, + respectively. +
+
+ +
+Hint Extern 5 (?a ?b) => order_tac : proof.
+Opaque make_disj.
+Opaque make_conj.
+ +
+Local Ltac l_tac := repeat rewrite list_to_set_disj_open_boxes;
+    rewrite (proper_Provable _ _ (list_to_set_disj_env_add _ _) _ _ eq_refl)
+|| rewrite (proper_Provable _ _ (equiv_disj_union_compat_r (list_to_set_disj_env_add _ _)) _ _ eq_refl)
+|| rewrite (proper_Provable _ _ (equiv_disj_union_compat_r (equiv_disj_union_compat_r (list_to_set_disj_env_add _ _))) _ _ eq_refl)
+|| rewrite (proper_Provable _ _ (equiv_disj_union_compat_r(equiv_disj_union_compat_r (equiv_disj_union_compat_r (list_to_set_disj_env_add _ _)))) _ _ eq_refl).
+ +
+Lemma a_rule_env_spec (Δ : list form) θ ϕ Hin (EA0 : pe, (pe ≺· (Δ, ϕ)) form * form)
+  (HEA : forall Δ ϕ Hpe, (list_to_set_disj Δ fst (EA0 (Δ, ϕ) Hpe)) * (list_to_set_disj Δ snd(EA0 (Δ, ϕ) Hpe) ϕ)) :
+  (list_to_set_disj Δ a_rule_env EA0 θ Hin ϕ).
+Proof with (auto with proof).
+assert (HE := λ Δ0 ϕ0 Hpe, fst (HEA Δ0 ϕ0 Hpe)).
+assert (HA := λ Δ0 ϕ0 Hpe, snd (HEA Δ0 ϕ0 Hpe)).
+clear HEA.
+assert(Hi : θ list_to_set_disj Δ) by now apply elem_of_list_to_set_disj.
+destruct θ; exhibit Hi 1;
+rewrite (proper_Provable _ _ (equiv_disj_union_compat_r (equiv_disj_union_compat_r (list_to_set_disj_rm _ _))) _ _ eq_refl).
+- simpl; case decide; intro Hp.
+  + subst. case_decide; subst; auto with proof.
+  + exch 0...
+- constructor 2.
+- simpl; exch 0. apply AndL. exch 1; exch 0. do 2 l_tac...
+- apply make_conj_sound_L.
+  exch 0. apply OrL; exch 0.
+  + apply AndL. apply make_impl_sound_L. exch 0. apply make_impl_sound_L.
+      l_tac. apply ImpL...
+  + apply AndL. l_tac. apply make_impl_sound_L. exch 0. apply make_impl_sound_L...
+- destruct θ1.
+  + simpl; case decide; intro Hp.
+    * assert (Hin'' : Var v (list_to_set_disj (rm (v θ2) Δ) : env))
+       by (rewrite <- list_to_set_disj_rm; apply in_difference; try easy; now apply elem_of_list_to_set_disj).
+       exhibit Hin'' 2. exch 0; exch 1. apply ImpLVar. exch 0. backward.
+       rewrite env_add_remove. exch 0. l_tac...
+    * case decide; intro; subst.
+     -- apply ExFalso.
+     -- apply make_conj_sound_L. constructor 4. exch 0. exch 1. exch 0. apply ImpLVar.
+         exch 0. exch 1. l_tac. apply weakening...
+  + constructor 2.
+  + simpl; exch 0. apply ImpLAnd. exch 0. l_tac...
+  + simpl; exch 0. apply ImpLOr. exch 1. l_tac. exch 0. l_tac...
+  + apply make_conj_sound_L. exch 0. apply ImpLImp; exch 0.
+      * apply AndL. exch 0. apply make_impl_sound_L. l_tac.
+         apply ImpR. exch 0. exch 1. l_tac...
+      * apply AndL. exch 0. l_tac. apply weakening, HA.
+  + exch 0. exch 0. simpl. apply AndL. exch 1; exch 0. apply ImpBox.
+      * box_tac. box_tac. exch 0; exch 1; exch 0. apply weakening. exch 1; exch 0.
+         apply make_impl_sound_L. do 2 l_tac. apply ImpL.
+         -- auto with proof.
+         -- apply HA.
+      * exch 1; exch 0. apply weakening. exch 0. l_tac. auto with proof.
+- auto with proof.
+Qed.
+ +
+Proposition entail_correct Δ ϕ : (list_to_set_disj Δ E (Δ, ϕ)) * (list_to_set_disj ΔA (Δ, ϕ) ϕ).
+Proof with (auto with proof).
+remember (Δ, ϕ) as pe.
+replace Δ with pe.1 by now subst.
+replace ϕ with pe.2 by now subst. clear Heqpe Δ ϕ. revert pe.
+refine (@well_founded_induction _ _ wf_pointed_order _ _).
+unfold pointed_env_order.
+intros (Δ, ϕ) Hind. simpl.
+rewrite E_eq, A_eq.
+(* uncurry the induction hypothesis for convenience *)
+assert (HE := fun d f x=> fst (Hind (d, f) x)).
+assert (HA := fun d f x=> snd (Hind (d, f) x)).
+unfold E, A in *; simpl in HE, HA.
+simpl in *. clear Hind.
+split. {
+(* E *)
+apply conjunction_R1. intros φ Hin. apply in_in_map in Hin.
+destruct Hin as (ψ&Hin&Heq). subst.
+assert(Hi : ψ list_to_set_disj Δ) by now apply elem_of_list_to_set_disj.
+destruct ψ; unfold e_rule; exhibit Hi 0; rewrite (proper_Provable _ _ (equiv_disj_union_compat_r (list_to_set_disj_rm _ _)) _ _ eq_refl).
+- case decide; intro; subst; simpl; auto using HE with proof.
+- auto with proof.
+- apply AndL. do 2 l_tac...
+- apply make_disj_sound_R, OrL.
+  + l_tac. apply OrR1, HE. order_tac.
+  + l_tac. apply OrR2, HE. order_tac.
+- destruct ψ1; auto 3 using HE with proof.
+  + case decide; intro Hp.
+    * assert(Hin'' : Var v (list_to_set_disj (rm (v ψ2) Δ) : env))
+          by (rewrite <- list_to_set_disj_rm; apply in_difference; try easy; now apply elem_of_list_to_set_disj).
+          exhibit Hin'' 1. apply ImpLVar. exch 0. backward. rewrite env_add_remove.
+          l_tac. apply HE...
+    * case decide; intro; subst.
+      -- apply ImpR, ExFalso.
+      -- apply make_impl_sound_R, ImpR. exch 0. apply ImpLVar. exch 0.
+          l_tac. apply weakening, HE. order_tac.
+  + apply ImpLAnd. l_tac...
+  + apply ImpLOr. do 2 l_tac...
+  + apply make_impl_sound_R, ImpR, make_impl_sound_L. exch 0. apply ImpLImp.
+      * exch 0. l_tac. apply ImpR. exch 0. l_tac. auto with proof.
+      * exch 0. l_tac. auto with proof.
+  + foldEA. apply make_impl_sound_R, ImpR. exch 0. apply ImpBox.
+         -- box_tac. exch 0; exch 1; exch 0. apply make_impl_sound_L, ImpL.
+            ++ do 2 l_tac. apply weakening, HE. order_tac.
+            ++ do 2 l_tac. apply HA. order_tac.
+         -- exch 0. l_tac. apply weakening, HE. order_tac.
+- apply BoxR. apply weakening. box_tac. l_tac. apply HE. order_tac.
+}
+(* A *)
+apply make_disj_sound_L, OrL.
+- apply disjunction_L. intros φ Hin.
+  apply in_in_map in Hin as (φ' & Heq & Hφ'). subst φ.
+  apply a_rule_env_spec; intros; split ; apply HE || apply HA; order_tac.
+- destruct ϕ; simpl; auto using HE with proof.
+  + case decide; intro; subst; [constructor 2|constructor 1].
+  + apply make_conj_sound_L, AndR; apply AndL; auto using HE with proof.
+  + apply ImpR. exch 0. l_tac. apply make_impl_sound_L, ImpL; auto using HE, HA with proof.
+  + foldEA. apply BoxR. box_tac. exch 0. l_tac. apply make_impl_sound_L, ImpL.
+      * apply weakening, HE. order_tac.
+      * apply HA. order_tac.
+Qed.
+ +
+End EntailmentCorrect.
+ +
+
+ +
+

Uniformity

+ +
+
+Section PropQuantCorrect.
+ +
+Hint Extern 5 (?a ≺· ?b) => order_tac : proof.
+ +
+
+ +
+The proof in this section, which is the most complex part of the argument, + shows that the E- and A-formulas constructed above are indeed their propositionally quantified versions, that is, *any* formula entailed by the original formula and + using only variables from that formula except p is already a consequence of + the E-quantified version, and similarly on the other side for the A-quantifier. + +
+ + E's second argument is mostly irrelevant and is only there for uniform treatment with A +
+
+Lemma E_irr ϕ' Δ ϕ : E (Δ, ϕ) = E (Δ, ϕ').
+Proof.
+remember ((Δ, ϕ) : pointed_env) as pe.
+replace Δ with pe.1 by now subst.
+replace ϕ with pe.2 by now subst. clear Heqpe Δ ϕ.
+  induction pe as [[Γ φ] Hind0] using (well_founded_induction_type wf_pointed_order).
+assert(Hind : Γ0 φ0, ((Γ0, φ0) ≺· (Γ, φ)) E (Γ0, φ0) = E (Γ0, ϕ'))
+  by exact (fun Γ0 φ0 => (Hind0 (Γ0, φ0))).
+unfold E in Hind. simpl in Hind.
+do 2 rewrite E_eq. f_equal. apply in_map_ext.
+intros φ' Hin. unfold e_rule.
+destruct φ'; repeat rewrite (Hind _ φ) by (trivial; order_tac); trivial.
+destruct φ'1; repeat rewrite (Hind _ φ) by (trivial; order_tac); trivial.
+Qed.
+ +
+Lemma E_left {Γ} {θ} {Δ} {φ φ'} (Hin : φ Δ) :
+(Γe_rule (λ pe (_ : pe ≺· (Δ, φ')), EA pe) φ Hin) θ ->
+ΓE (Δ, φ') θ.
+Proof.
+intro Hp. rewrite E_eq.
+destruct (@in_map_in _ _ _ (e_rule (λ pe (_ : pe ≺· (Δ, φ')), EA pe)) _ Hin) as [Hin' Hrule].
+eapply conjunction_L.
+- apply Hrule.
+- exact Hp.
+Qed.
+ +
+Lemma A_right {Γ} {Δ} {φ φ'} (Hin : φ Δ) :
+Γ a_rule_env (λ pe (_ : pe ≺· (Δ, φ')), EA pe) φ Hin ->
+Γ A (Δ, φ').
+Proof. intro Hp. rewrite A_eq.
+destruct (@in_map_in _ _ _ (a_rule_env (λ pe (_ : pe ≺· (Δ, φ')), EA pe)) _ Hin) as [Hin' Hrule].
+eapply make_disj_sound_R, OrR1, disjunction_R.
+- exact Hrule.
+- exact Hp.
+Qed.
+ +
+Proposition pq_correct Γ Δ ϕ:
+  ( φ0, φ0 Γ -> ¬ occurs_in p φ0) ->
+  (Γ list_to_set_disj Δ ϕ) ->
+  (¬ occurs_in p ϕ -> ΓE (Δ, ϕ) ϕ) * (ΓE (Δ, ϕ) A (Δ, ϕ)).
+Proof.
+(* This proof goes by induction on the ordering w.r.t (Γ ⊎Δ, ϕ)
+  instead of on the structure of Γ ⊎Δ ⊢ ϕ, to allow better rules *)

+(* we want to use an E rule *)
+Local Ltac Etac := foldEA; intros; match goal with
+| Hin : ?a list_to_set_disj ?Δ |- _E (?Δ, _) _=>
+    apply (E_left (proj1 (elem_of_list_to_set_disj _ _) Hin)); unfold e_rule end.
+ +
+(* we want to use an A rule defined in a_rule_env *)
+Local Ltac Atac := foldEA; match goal with | Hin : ?a list_to_set_disj ?Δ |- _ A (?Δ, _) =>
+  apply (A_right (proj1 (elem_of_list_to_set_disj _ _) Hin)); unfold a_rule_env end.
+ +
+(* we want to use an A rule defined in a_rule_form *)
+Local Ltac Atac' := foldEA; rewrite A_eq; apply make_disj_sound_R, OrR2; simpl.
+ +
+Local Ltac occ := simpl; tauto ||
+match goal with
+| Hnin : φ0 : form, φ0 ?Γ ¬ occurs_in p φ0 |- _ =>
+
+  let Hin := fresh "Hin" in
+  try (match goal with |Hocc : ?a ?Γ |- _ => let Hocc' := fresh "Hocc" in assert (Hocc' := Hnin _ Hocc); simpl in Hocc';
+  let Hin' := fresh "Hinx" in assert(Hin' := In_open_boxes _ _ Hocc); simpl in *;
+  try rewrite open_boxes_remove in * by trivial end);
+  intro; repeat rewrite env_in_add; repeat rewrite difference_include; simpl;
+  intro Hin; try tauto;
+  try (destruct Hin as [Hin|[Hin|Hin]] ||destruct Hin as [Hin|Hin]);
+  subst; simpl; try tauto;
+  repeat (apply difference_include in Hin; [|assumption]);
+  try (now apply Hnin)
+end.
+ +
+Local Ltac equiv_tac :=
+multimatch goal with
+| Heq' : __ _ |- _ => fail
+| Heq' : _ _ |- _ _ =>
+  try (rewrite <- difference_singleton; trivial);
+  try rewrite Heq';
+  repeat rewrite <- list_to_set_disj_env_add;
+  try rewrite <- list_to_set_disj_rm;
+  try (rewrite union_difference_L by trivial);
+  try (rewrite union_difference_R by trivial);
+  try ms
+end.
+ +
+Local Ltac peapply' th := (erewrite proper_Provable; [| |reflexivity]); [eapply th|equiv_tac].
+ +
+remember (elements Γ++ Δ, ϕ) as pe.
+revert pe Γ Δ ϕ Heqpe.
+refine (@well_founded_induction _ _ wf_pointed_order _ _).
+intros (ΓΔ, ϕ0) Hind Γ Δ ϕ Heq Hnin Hp.
+inversion Heq; subst; clear Heq.
+assert(Hind' := λ Γ0 Δ0 ψ Ho, Hind (elements Γ0 ++ Δ0, ψ) Ho _ _ _ eq_refl).
+clear Hind. rename Hind' into Hind.
+dependent destruction Hp;
+(* try and solve the easy case where the main formula is on the left *)
try match goal with
+| H : (?Γ0?a?b) = Γ list_to_set_disj Δ |- _ => rename H into Heq;
+      pose(Heq' := env_equiv_eq _ _ Heq); apply env_add_inv' in Heq'
+| H : ((?Γ0 ?a) = Γ list_to_set_disj Δ) |- _ => rename H into Heq;
+  assert(Hin : a (Γ list_to_set_disj Δ)) by (rewrite <- Heq; ms);
+  pose(Heq' := env_equiv_eq _ _ Heq); apply env_add_inv' in Heq';
+  try (case (decide (a Γ)); intro Hin0;
+  [split; intros; exhibit Hin0 1|
+   case (decide (a (list_to_set_disj Δ : env))); intro Hin0';
+  [|apply gmultiset_elem_of_disj_union in Hin; exfalso; tauto]])
+end; simpl.
+ +
+(* Atom *)
+- auto 2 with proof.
+- Atac'. case decide; intro; subst; [exfalso; now apply (Hnin _ Hin0)|]; auto with proof.
+- split.
+  + intro Hneq. Etac. rewrite decide_False. auto with proof. trivial.
+  + case (decide (p = p0)).
+    * intro Heqp0. Atac. do 2 rewrite decide_True by (f_equal; trivial). auto with proof.
+    * intro Hneq. Etac. Atac'. do 2 rewrite decide_False by trivial. apply Atom.
+(* ExFalso *)
+- auto 2 with proof.
+- auto 2 with proof.
+- split; Etac; auto with proof.
+(* AndR *)
+- split.
+  + intro Hocc. apply AndR; erewrite E_irr; apply Hind; auto with proof.
+  + Atac'. foldEA. apply make_conj_sound_R, AndR; erewrite E_irr;
+      (eapply Hind; [order_tac | occ | trivial]).
+(* AndL *)
+- exch 0. apply AndL. exch 1; exch 0. peapply Hind; auto with proof. occ. peapply' Hp.
+- exch 0. apply AndL. exch 1; exch 0. peapply Hind; auto with proof. occ. peapply' Hp.
+- split.
+   + Etac. foldEA. apply Hind; auto with proof. peapply' Hp.
+   + Atac. Etac. apply Hind; auto; auto with proof. peapply' Hp.
+(* OrR1 & OrR2 *)
+- split.
+  + intro Hocc. apply OrR1. erewrite E_irr; apply Hind; auto with proof.
+  + rewrite A_eq. apply make_disj_sound_R, OrR2.
+      apply make_disj_sound_R, OrR1; erewrite E_irr.
+      apply Hind; auto with proof.
+- simpl. split.
+  + intro Hocc. apply OrR2. erewrite E_irr; apply Hind; auto with proof.
+  + rewrite A_eq. apply make_disj_sound_R, OrR2.
+       apply make_disj_sound_R, OrR2; erewrite E_irr.
+       apply Hind; auto with proof.
+(* OrL *)
+- exch 0. apply OrL; exch 0.
+ + apply Hind; auto with proof. occ. peapply' Hp1.
+ + apply Hind; auto with proof. occ. peapply' Hp2.
+- exch 0. apply OrL; exch 0.
+  + apply Hind; auto with proof. occ. peapply' Hp1.
+  + apply Hind; auto with proof. occ. peapply' Hp2.
+- split.
+  + Etac. apply make_disj_sound_L, OrL; apply Hind; auto with proof.
+      * peapply' Hp1.
+      * peapply' Hp2.
+  + Atac. apply weakening. apply make_conj_sound_R,AndR, make_impl_sound_R.
+    * apply make_impl_sound_R, ImpR. apply Hind; auto with proof. peapply' Hp1.
+    * apply ImpR. apply Hind; auto with proof. peapply' Hp2.
+(* ImpR *)
+- split.
+  + intro Hocc. apply ImpR. exch 0.
+    erewrite E_irr. apply Hind; auto with proof. occ. peapply Hp.
+  + Atac'. apply weakening, make_impl_sound_R, ImpR, Hind; auto with proof. order_tac.
+      * rewrite <- Permutation_middle. order_tac.
+      * peapply Hp.
+(* ImpLVar *)
+- pose(Heq'' := Heq'); apply env_add_inv' in Heq''.
+  case (decide ((Var p0 φ) Γ)).
+  + intro Hin0.
+    assert (Hocc' := Hnin _ Hin0). simpl in Hocc'.
+    case (decide (Var p0 Γ)); intro Hin1.
+    * (* subcase 1: p0, (p0 → φ) ∈ Γ *)
+      assert (Hin2 : Var p0 Γ {[Var p0 φ]}) by (apply in_difference; trivial; discriminate).
+      clear Hin1.
+      split; [intro Hocc|]; exhibit Hin0 1; exhibit Hin2 2; exch 0; exch 1; apply ImpLVar; exch 1; exch 0;
+      (apply Hind; auto with proof; [occ | peapply' Hp]).
+    * assert(Hin0' : Var p0 (Γ0Var p0•(p0 φ))) by ms. rewrite Heq in Hin0'.
+      case (decide (Var p0 (list_to_set_disj Δ: env))); intro Hp0;
+      [|apply gmultiset_elem_of_disj_union in Hin0'; exfalso; tauto].
+      (* subcase 3: p0 ∈ Δ ; (p0 → φ) ∈ Γ *)
+      clear Heq''.
+      split; try case decide; intros; subst.
+      -- apply contraction. Etac. rewrite decide_False by tauto.
+          exhibit Hin0 2. exch 1. exch 0. apply ImpLVar. exch 0. apply weakening. exch 0.
+         apply Hind; auto with proof. occ. peapply' Hp.
+      -- apply contraction. Etac. rewrite decide_False by tauto.
+          exhibit Hin0 2. exch 1; exch 0. apply ImpLVar. exch 0. apply weakening.
+          exch 0. foldEA. apply Hind; auto with proof. occ. peapply' Hp.
+  + intro.
+    assert(Hin : (Var p0 φ) (Γ0Var p0•(p0 φ))) by ms.
+    rewrite Heq in Hin.
+    case (decide ((Var p0 φ) (list_to_set_disj Δ : env))); intro Hin0;
+    [|apply gmultiset_elem_of_disj_union in Hin; exfalso; tauto].
+    case (decide (Var p0 Γ)); intro Hin1.
+    * (* subcase 2: p0 ∈ Γ ; (p0 → φ) ∈ Δ *)
+      do 2 exhibit Hin1 1.
+      split; [intro Hocc|].
+      -- Etac. case decide; intro Hp0;[|case decide; intro; subst; [auto with *|]].
+         ++ foldEA. apply Hind; auto with proof; [order_tac; order_tac|occ | peapply' Hp].
+         ++ apply make_impl_sound_L, ImpLVar. exch 0. backward. rewrite env_add_remove.
+         apply Hind; auto with proof. peapply' Hp.
+      -- Etac. Atac. case decide; intro Hp0;[|case decide; intro; subst; [auto with *|]].
+        ++ foldEA. apply Hind; auto with proof; [order_tac; order_tac|occ | peapply' Hp].
+        ++ apply make_impl_sound_L, ImpLVar.
+               apply make_conj_sound_R, AndR; auto 2 with proof.
+               exch 0. backward. rewrite env_add_remove.
+               apply Hind; auto with proof. peapply' Hp.
+    * assert(Hin': Var p0 Γ list_to_set_disj Δ) by (rewrite <- Heq; ms).
+       apply gmultiset_elem_of_disj_union in Hin'.
+       case (decide (Var p0 (list_to_set_disj Δ: env))); intro Hin1'; [|exfalso; tauto].
+      (* subcase 4: p0,(p0 → φ) ∈ Δ *)
+      case (decide (p = p0)); intro.
+      -- (* subsubcase p = p0 *)
+        apply elem_of_list_to_set_disj in Hin1'.
+        subst. split; Etac; repeat rewrite decide_True by trivial.
+        ++ clear Heq. apply Hind; auto with proof. peapply' Hp.
+        ++ Atac. repeat rewrite decide_True by trivial. clear Heq.
+                apply Hind; auto with proof. peapply' Hp.
+      -- (* subsubcase p ≠ p0 *)
+         split; [intro Hocc|].
+         ++ apply contraction. Etac. rewrite decide_False by trivial. exch 0.
+                 assert((p0 φ) list_to_set_disj Δ) by ms. Etac.
+                 rewrite decide_True by now apply elem_of_list_to_set_disj.
+                 exch 0. apply weakening. apply Hind; auto with proof. peapply' Hp.
+         ++ apply contraction. Etac. exch 0. assert((p0 φ) list_to_set_disj Δ) by ms.
+                 Etac; Atac. rewrite decide_False by trivial.
+                 do 2 rewrite decide_True by now apply elem_of_list_to_set_disj.
+                 exch 0. apply weakening.
+                 apply Hind; auto with proof. peapply' Hp.
+(* ImpLAnd *)
+- exch 0. apply ImpLAnd. exch 0. apply Hind; auto with proof; [occ|peapply' Hp].
+- exch 0. apply ImpLAnd. exch 0. apply Hind; auto with proof; [occ|peapply' Hp].
+- split; Etac.
+  + apply Hind; auto with proof. peapply' Hp.
+  + Atac. simpl. apply Hind; auto with proof. peapply' Hp.
+(* ImpLOr *)
+- exch 0; apply ImpLOr. exch 1; exch 0. apply Hind; auto with proof. occ. peapply' Hp.
+- exch 0; apply ImpLOr. exch 1; exch 0. apply Hind; [order_tac | occ|peapply' Hp].
+- split; Etac.
+  + apply Hind; auto with proof. peapply' Hp.
+  + Atac. apply Hind; auto with proof. peapply' Hp.
+(* ImpLImp *)
+- (* subcase 1: ((φ1 → φ2) → φ3) ∈ Γ *)
+  assert Var p) by (intro; subst; simpl in *; tauto).
+  exch 0; apply ImpLImp; exch 0.
+  + erewrite E_irr. apply Hind; auto with proof. occ. peapply' Hp1.
+      simpl. apply Hnin in Hin0. simpl in *. tauto.
+  + erewrite E_irr. apply Hind; auto with proof. occ. peapply' Hp2.
+- exch 0; apply ImpLImp; exch 0.
+  + erewrite E_irr. apply Hind; auto with proof. occ. peapply' Hp1.
+       simpl. apply Hnin in Hin0. simpl in Hin0. tauto.
+  + apply Hind; auto with proof. occ. peapply' Hp2.
+- (* subcase 2: ((φ1 → φ2) → φ3) ∈ Δ *)
+  split.
+  + Etac. apply make_impl_sound_L2'. apply ImpLImp.
+    * apply weakening. apply ImpR. foldEA.
+       rewrite (E_irr φ2).
+       apply Hind; auto with proof.
+       -- order_tac. repeat rewrite Permutation_middle. order_tac.
+       -- repeat setoid_rewrite gmultiset_disj_union_assoc.
+           setoid_rewrite gmultiset_disj_union_comm.
+           repeat setoid_rewrite gmultiset_disj_union_assoc. exch 0. apply ImpR_rev.
+           peapply' Hp1.
+    * apply Hind; auto with proof. peapply' Hp2.
+  + Atac. apply make_conj_sound_R, AndR.
+    * apply weakening. apply make_impl_sound_R, ImpR. foldEA.
+       rewrite (E_irr φ2). apply Hind; auto with proof.
+       -- order_tac. repeat rewrite Permutation_middle. order_tac.
+       -- repeat setoid_rewrite gmultiset_disj_union_assoc.
+           setoid_rewrite gmultiset_disj_union_comm.
+           repeat setoid_rewrite gmultiset_disj_union_assoc. exch 0. apply ImpR_rev.
+           peapply' Hp1.
+    * Etac. simpl. apply make_impl_sound_L2', ImpLImp.
+      -- apply weakening. apply ImpR. foldEA.
+       rewrite (E_irr φ2). apply Hind; auto with proof.
+       ++ order_tac. repeat rewrite Permutation_middle. order_tac.
+       ++ repeat setoid_rewrite gmultiset_disj_union_assoc.
+               setoid_rewrite gmultiset_disj_union_comm.
+               repeat setoid_rewrite gmultiset_disj_union_assoc. exch 0. apply ImpR_rev.
+               peapply' Hp1.
+      -- apply Hind; auto with proof. peapply' Hp2.
+- (* ImpBox, external *)
+   destruct (open_boxes_case (list_to_set_disj Δ)) as [[θ ] | Hequiv].
+    + apply contraction. Etac. exch 1; exch 0; apply ImpBox.
+        * box_tac. box_tac. exch 2; exch 1; exch 0. apply weakening. foldEA.
+           erewrite E_irr with (ϕ' := φ1).
+           exch 1; exch 0. apply Hind.
+           -- order_tac. (* cannot handle it. manual proof *)
+               rewrite elements_open_boxes.
+               do 2 apply env_order_cancel_right. apply env_order_4; simpl; try lia. left.
+               apply env_order_disj_union_compat_strong_left; order_tac.
+           -- occ. intro HF. destruct (occurs_in_open_boxes _ _ _ HF Hin1) as (θ0 & Hθ0 & Hinθ).
+               apply (Hnin θ0); ms.
+           -- assert(Hθ' := In_open_boxes _ _ ).
+               assert(Heq'' : Γ0 (Γ {[ φ1 φ2]} list_to_set_disj ((θ) :: rm ( θ) Δ))). {
+               rewrite Heq'. simpl. rewrite union_difference_L by trivial.
+               rewrite (difference_singleton _ _ ).
+               rewrite list_to_set_disj_rm. ms.
+               }
+               clear Heq'. clear .
+              (erewrite proper_Provable; [| |reflexivity]); [eapply Hp1|].
+              rewrite Heq''. rewrite open_boxes_disj_union.
+              repeat rewrite <- ?list_to_set_disj_open_boxes, <- list_to_set_disj_env_add.
+              rewrite open_boxes_add. simpl. ms.
+          -- intro HF. apply (Hnin _ Hin0). simpl. tauto.
+        * exch 0. apply weakening. exch 0. apply Hind; [order_tac | occ|peapply' Hp2| trivial].
+  + assert(Heq'' : ( Γ0) ((Γ {[ φ1 φ2]}) (list_to_set_disj Δ))). {
+       rewrite Heq'. rewrite union_difference_L by trivial.
+       rewrite <- Hequiv, open_boxes_disj_union.
+       rewrite open_boxes_remove by trivial. ms. }
+       exch 0. apply ImpBox.
+      * box_tac. exch 1; exch 0. apply open_box_L.
+         erewrite E_irr with (ϕ' := φ1).
+         apply Hind.
+         -- order_tac. rewrite elements_open_boxes. repeat rewrite Permutation_middle. order_tac.
+         -- occ. intro HF. destruct (occurs_in_open_boxes _ _ _ HF Hin1) as (θ0 & Hθ0 & Hinθ).
+             apply (Hnin θ0); ms.
+         -- peapply' Hp1.
+         -- intro HF. apply (Hnin _ Hin0). simpl. tauto.
+     * exch 0. apply Hind; [order_tac|occ | | trivial].
+        (erewrite proper_Provable; [| |reflexivity]); [eapply Hp2|].
+        rewrite Heq'. rewrite union_difference_L by trivial. ms.
+- destruct (open_boxes_case (list_to_set_disj Δ)) as [[θ ] | Hequiv].
+    + apply contraction. Etac. exch 1; exch 0; apply ImpBox.
+        * box_tac. box_tac. exch 2; exch 1; exch 0. apply weakening. foldEA.
+           erewrite E_irr with (ϕ' := φ1).
+           exch 1; exch 0. apply Hind.
+         -- order_tac.
+             rewrite elements_open_boxes.
+               do 2 apply env_order_cancel_right. apply env_order_4; simpl; try lia. left.
+               apply env_order_disj_union_compat_strong_left; order_tac.
+         -- occ. intro HF. destruct (occurs_in_open_boxes _ _ _ HF Hin1) as (θ0 & Hθ0 & Hinθ).
+             apply (Hnin θ0); ms.
+           -- assert(Hθ' := In_open_boxes _ _ ).
+               assert(Heq'' : Γ0 (Γ {[ φ1 φ2]} list_to_set_disj ((θ) :: rm ( θ) Δ))). {
+               rewrite Heq'. simpl. rewrite union_difference_L by trivial.
+               rewrite (difference_singleton _ _ ).
+               rewrite list_to_set_disj_rm. ms.
+               }
+               clear Heq'. clear .
+              (erewrite proper_Provable; [| |reflexivity]); [eapply Hp1|].
+              rewrite Heq''. rewrite open_boxes_disj_union.
+              repeat rewrite <- ?list_to_set_disj_open_boxes, <- list_to_set_disj_env_add.
+              rewrite open_boxes_add. simpl. ms.
+         -- intro HF. apply (Hnin _ Hin0). simpl. tauto.
+        * exch 0. apply weakening. exch 0. apply Hind ; [order_tac|occ|peapply' Hp2].
+  + erewrite E_irr with (ϕ' := φ1).
+      exch 0. apply ImpBox.
+      * box_tac. exch 1; exch 0. apply open_box_L. apply Hind.
+         -- order_tac. rewrite elements_open_boxes. order_tac.
+         -- occ. intro HF. destruct (occurs_in_open_boxes _ _ _ HF Hin1) as (θ0 & Hθ0 & Hinθ).
+             apply (Hnin θ0); ms.
+         -- assert(Heq'' : ( Γ0) ((Γ {[ φ1 φ2]}) (list_to_set_disj Δ))). {
+                 rewrite Heq'. rewrite union_difference_L by trivial.
+                 rewrite <- Hequiv, open_boxes_disj_union.
+                 rewrite open_boxes_remove by trivial. ms. }
+                 peapply Hp1.
+         -- intro HF. apply (Hnin _ Hin0). simpl. tauto.
+      * erewrite E_irr with (ϕ' := ψ).
+          exch 0. apply Hind. order_tac. occ. clear Hequiv. peapply' Hp2.
+- split; Etac.
+  + foldEA. apply make_impl_sound_L, ImpBox.
+        -- do 2 apply weakening. apply make_impl_sound_R, ImpR.
+            erewrite E_irr with (ϕ' := φ1) by ms.
+            apply Hind.
+             ++ order_tac. rewrite elements_open_boxes.
+                     do 2 apply env_order_cancel_right.
+                     repeat rewrite Permutation_middle.
+                     apply env_order_disj_union_compat_strong_left; order_tac.
+            ++ intros φ0 Hin1 HF. destruct (occurs_in_open_boxes _ _ _ HF Hin1) as (θ0 & Hθ0 & Hinθ).
+                    apply (Hnin θ0); ms.
+            ++ assert(Heq'' : ( Γ0) ((Γ) list_to_set_disj (map open_box (rm ( φ1 φ2) Δ)))). {
+                    rewrite Heq'.
+                    repeat rewrite open_boxes_remove by ms. simpl.
+                    rewrite <- list_to_set_disj_open_boxes, <- list_to_set_disj_rm, open_boxes_disj_union. trivial.
+                    simpl. rewrite union_difference_R by auto with proof. rewrite open_boxes_remove by ms. ms.
+                    }
+                    peapply Hp1.
+        -- apply Hind. order_tac. occ. peapply' Hp2. trivial.
+  + assert(Heq'' : ( Γ0) ((Γ) list_to_set_disj (map open_box (rm ( φ1 φ2) Δ)))). {
+          rewrite Heq'.
+          repeat rewrite open_boxes_remove by ms. simpl.
+          rewrite <- list_to_set_disj_open_boxes, <- list_to_set_disj_rm, open_boxes_disj_union. trivial.
+          simpl. rewrite union_difference_R by auto with proof. rewrite open_boxes_remove by ms. ms.
+        }
+  foldEA. Atac. apply AndR.
+     * apply make_impl_sound_L, ImpBox.
+        -- do 2 apply weakening. apply make_impl_sound_R, ImpR.
+            erewrite E_irr with (ϕ' := φ1).
+            apply Hind.
+             ++ order_tac. rewrite elements_open_boxes.
+                     do 2 apply env_order_cancel_right.
+                     repeat rewrite Permutation_middle.
+                     apply env_order_disj_union_compat_strong_left; order_tac.
+            ++ intros φ0 Hin1 HF. destruct (occurs_in_open_boxes _ _ _ HF Hin1) as (θ0 & Hθ0 & Hinθ).
+                    apply (Hnin θ0); ms.
+            ++ peapply Hp1.
+       -- apply BoxR. box_tac. do 2 apply weakening. apply make_impl_sound_R, ImpR. foldEA.
+           erewrite E_irr with (ϕ' := φ1) by ms.
+           apply Hind.
+             ++ order_tac. rewrite elements_open_boxes.
+                     do 2 apply env_order_cancel_right.
+                     repeat rewrite Permutation_middle.
+                     apply env_order_disj_union_compat_strong_left; order_tac.
+            ++ intros φ0 Hin1 HF. destruct (occurs_in_open_boxes _ _ _ HF Hin1) as (θ0 & Hθ0 & Hinθ).
+                    apply (Hnin θ0); ms.
+            ++ peapply Hp1.
+     * foldEA. apply make_impl_sound_L, ImpBox.
+        -- do 2 apply weakening. apply make_impl_sound_R, ImpR.
+               erewrite E_irr with (ϕ' := φ1).
+               apply Hind.
+             ++ order_tac. rewrite elements_open_boxes.
+                     do 2 apply env_order_cancel_right.
+                     repeat rewrite Permutation_middle.
+                     apply env_order_disj_union_compat_strong_left; order_tac.
+               ++ intros φ0 Hφ0 HF. destruct (occurs_in_open_boxes _ _ _ HF Hφ0) as (θ0 & Hθ0 & Hinθ).
+                     apply (Hnin θ0); ms.
+               ++ peapply Hp1.
+        -- clear Heq''. apply Hind; [order_tac|occ|peapply' Hp2].
+- split.
+  + intro Hocc. destruct (open_boxes_case (list_to_set_disj Δ)) as [[θ ] | Hequiv].
+      * Etac. foldEA. apply BoxR. box_tac. exch 0.
+        erewrite E_irr with (ϕ' := φ); apply Hind.
+        -- order_tac.
+            rewrite elements_open_boxes.
+            repeat rewrite Permutation_middle.
+            apply env_order_disj_union_compat_strong_left. order_tac.
+            apply env_order_2. simpl; lia. simpl; lia.
+            apply env_order_eq_add. left. order_tac.
+        -- intros φ0 Hφ0 HF. apply gmultiset_elem_of_disj_union in Hφ0.
+            destruct Hφ0 as [Hφ0|]; [|ms].
+            destruct (occurs_in_open_boxes _ _ _ HF Hφ0) as (θ0 & Hθ0 & Hinθ). apply (Hnin θ0); ms.
+        -- (erewrite proper_Provable; [| |reflexivity]); [eapply Hp|].
+            rewrite open_boxes_disj_union.
+            rewrite <- list_to_set_disj_env_add.
+            rewrite <- list_to_set_disj_open_boxes, <- list_to_set_disj_rm.
+            rewrite open_boxes_remove by ms.
+            rewrite <- difference_singleton by auto with proof. ms.
+        -- trivial.
+      * apply BoxR. box_tac. exch 0. apply open_box_L.
+         erewrite E_irr with (ϕ' := φ).
+         apply Hind.
+         -- order_tac.
+             rewrite elements_open_boxes.
+            repeat rewrite Permutation_middle.
+            apply env_order_disj_union_compat_strong_left. order_tac.
+            apply env_order_2. simpl; lia. simpl; lia. now right.
+         -- intros φ0 Hφ0 HF. apply gmultiset_elem_of_disj_union in Hφ0.
+            destruct Hφ0 as [Hφ0|]; [|ms].
+            destruct (occurs_in_open_boxes _ _ _ HF Hφ0) as (θ0 & Hθ0 & Hinθ). apply (Hnin θ0); ms.
+         -- (erewrite proper_Provable; [| |reflexivity]); [eapply Hp|].
+              rewrite open_boxes_disj_union, <- Hequiv. ms.
+         -- trivial.
+  + Atac'. foldEA. apply BoxR. box_tac. apply weakening. erewrite E_irr with (ϕ' := φ).
+       apply weakening. apply make_impl_sound_R, ImpR.
+       apply Hind.
+       * order_tac.
+          rewrite elements_open_boxes.
+          repeat rewrite Permutation_middle.
+          order_tac.
+       * intros φ0 Hφ0 HF. destruct (occurs_in_open_boxes _ _ _ HF Hφ0) as (θ0 & Hθ0 & Hinθ).
+          apply (Hnin θ0); ms.
+       * (erewrite proper_Provable; [| |reflexivity]); [eapply Hp|].
+            rewrite open_boxes_disj_union.
+            rewrite <- list_to_set_disj_env_add.
+            rewrite <- list_to_set_disj_open_boxes. ms.
+Qed.
+ +
+End PropQuantCorrect.
+ +
+End Correctness.
+ +
+End UniformInterpolation.
+ +
+
+ +
+

Main uniform interpolation Theorem

+ +
+
+ +
+Open Scope type_scope.
+ +
+Lemma E_of_empty p φ : E p ([], φ) = (Implies Bot Bot).
+Proof.
+  rewrite E_eq. rewrite in_map_empty. now unfold conjunction, nodup, foldl.
+Qed.
+ +
+Definition vars_incl φ l := forall x, occurs_in x φ -> In x l.
+ +
+
+ +
+ The overall correctness result is summarized here. +
+
+ +
+Theorem iSL_uniform_interpolation p V: p V ->
+   φ, vars_incl φ (p :: V) ->
+    (vars_incl (Ef p φ) V)
+  * ({[φ]} (Ef p φ))
+  * ( ψ, vars_incl ψ V -> {[φ]} ψ -> {[Ef p φ]} ψ)
+  * (vars_incl (Af p φ) V)
+  * ({[Af p φ]} φ)
+  * ( θ, vars_incl θ V -> {[θ]} φ -> {[θ]} Af p φ).
+Proof.
+intros Hp φ Hvarsφ; repeat split.
+  + intros x Hx. apply (EA_vars p _ x) in Hx.
+      destruct Hx as [Hneq [θ [ Hocc]]]. apply elem_of_list_singleton in . subst.
+      apply Hvarsφ in Hocc. destruct Hocc; subst; tauto.
+  + replace {[φ]} with (list_to_set_disj [φ] : env). apply entail_correct. simpl. ms.
+  + intros ψ Hψ Hyp. rewrite elem_of_list_In in Hp. unfold Ef. rewrite E_irr with (ϕ' := ψ).
+      * peapply (pq_correct p [φ] ψ).
+         -- intros θ Hin. inversion Hin.
+         -- peapply Hyp.
+         -- intro HF. apply Hψ in HF. tauto.
+  + intros x Hx. apply (EA_vars p φ x) in Hx.
+      destruct Hx as [Hneq [Hin | [θ [ Hocc]]]].
+      * apply Hvarsφ in Hin. destruct Hin; subst; tauto.
+      * inversion .
+  + peapply (entail_correct p []).
+  + intros ψ Hψ Hyp. rewrite elem_of_list_In in Hp.
+      apply (TopL_rev _ ). peapply (pq_correct p {[ψ]} [] φ).
+      * intros φ0 Hφ0. apply gmultiset_elem_of_singleton in Hφ0. subst. auto with *.
+      * peapply Hyp.
+      * now rewrite E_of_empty.
+Qed.
+
+
+ +
+ + + diff --git a/ISL.SequentProps.html b/ISL.SequentProps.html new file mode 100644 index 0000000..7cd49f9 --- /dev/null +++ b/ISL.SequentProps.html @@ -0,0 +1,1019 @@ + + + + + + + + + + + + + +
+
+

ISL.SequentProps

+ +
+Require Import ISL.Sequents.
+ +
+(* Required for dependent induction. *)
+Require Import Coq.Program.Equality.
+ +
+
+ +
+

Overview: admissible rules in G4ip sequent calculus

+ + +
+ +This file contains important properties of the sequent calculus G4ip, defined in +Sequents.v, namely the admissibility of various inversion rules, weakening and +contraction. We draw various consequences from this that are used extensively in +the proof of correctness of propositional quantifiers. The first part of this +file closely follows proof in the paper: + +
+ +(Dyckhoff and Negri 2000). R. Dyckhoff and S. Negri, Admissibility of Structural +Rules for Contraction-Free Systems of Intuitionistic Logic, Journal of Symbolic +Logic (65):4. + +
+ +

Weakening

+ +
+ + We prove the admissibility of the weakening rule. +
+
+ +
+Theorem weakening φ' Γ φ : Γ φ -> Γφ' φ.
+Proof with (auto with proof).
+intro H. revert φ'. induction H; intro φ'; auto with proof; try (exch 0; auto with proof).
+- constructor 4. exch 1; exch 0...
+- constructor 7; exch 0...
+- constructor 8; exch 0...
+- exch 1; constructor 9; exch 1; exch 0...
+- constructor 10; exch 0...
+- constructor 11. exch 1; exch 0...
+- constructor 12; exch 0...
+- apply ImpBox; box_tac.
+  + peapply (IHProvable1 (open_box φ')).
+  + exch 0...
+- apply BoxR. box_tac; exch 0...
+Qed.
+ +
+Global Hint Resolve weakening : proof.
+ +
+Theorem generalised_weakeningL (Γ Γ' : env) φ: Γ φ -> Γ' Γ φ.
+Proof.
+intro Hp.
+induction Γ' as [| x Γ' IHΓ'] using gmultiset_rec.
+- peapply Hp.
+- peapply (weakening x). exact IHΓ'. ms.
+Qed.
+ +
+Theorem generalised_weakeningR (Γ Γ' : env) φ: Γ' φ -> Γ' Γ φ.
+Proof.
+intro Hp.
+induction Γ as [| x Γ IHΓ] using gmultiset_rec.
+- peapply Hp.
+- peapply (weakening x). exact IHΓ. ms.
+Qed.
+ +
+Global Hint Extern 5 (?a <= ?b) => simpl in *; lia : proof.
+ +
+
+ +
+

Inversion rules

+ +
+ + We prove that the following rules are invertible: implication right, and + left, or left, top left (i.e., the appliction of weakening for the formula + top), the four implication left rules, the and right rule and the application of the or right rule with bottom. +
+
+ +
+Lemma ImpR_rev Γ φ ψ :
+  (Γ (φ ψ))
+    -> Γφ ψ.
+Proof with (auto with proof).
+intro Hp. dependent induction Hp; auto with proof; try exch 0.
+- constructor 4. exch 1; exch 0...
+- constructor 7; exch 0...
+- exch 1; constructor 9; exch 1; exch 0...
+- constructor 10; exch 0...
+- constructor 11. exch 1; exch 0...
+- constructor 12; exch 0...
+- constructor 13; box_tac...
+  + exch 1; exch 0...
+  + exch 0. auto with proof.
+Qed.
+ +
+Global Hint Resolve ImpR_rev : proof.
+ +
+Theorem generalised_axiom Γ φ : Γφ φ.
+Proof with (auto with proof).
+remember (weight φ) as w.
+assert(Hle : weight φ w) by lia.
+clear Heqw. revert Γ φ Hle.
+induction w; intros Γ φ Hle.
+- assert (Hφ := weight_pos φ). lia.
+- destruct φ; simpl in Hle...
+  destruct φ1 as [v| | θ1 θ2 | θ1 θ2 | θ1 θ2 | θ].
+  + constructor 8. exch 0...
+  + auto with proof.
+  + apply ImpR, AndL. exch 1; exch 0. apply ImpLAnd.
+    exch 0. apply ImpR_rev. exch 0...
+  + apply ImpR. exch 0. apply ImpLOr.
+    exch 1; exch 0...
+  + apply ImpR. exch 0...
+  + apply ImpR. exch 0. apply ImpBox; box_tac...
+  + apply BoxR; box_tac...
+Qed.
+ +
+Global Hint Resolve generalised_axiom : proof.
+ +
+Lemma open_box_L Γ φ ψ : Γ φ ψ -> Γ φ ψ.
+Proof.
+intro Hp.
+remember (Γφ) as Γ' eqn:HH.
+assert (Heq: Γ Γ' {[ φ ]}) by ms.
+assert(Hin : φ Γ')by ms.
+rw Heq 1. clear Γ HH Heq. revert φ Hin.
+dependent induction Hp generalizing Γ' Hp; intros φ0 Hin.
+- case (decide (φ0 = Var p)).
+  + intro; subst. simpl. auto with proof.
+  + intro. forward. auto with proof.
+- case (decide (φ0 = )).
+  + intro; subst. simpl. auto with proof.
+  + intro. forward. auto with proof.
+- apply AndR; auto.
+- case (decide (φ0 = (φ ψ))).
+  + intro; subst. simpl. apply AndL. peapply Hp.
+  + intro. forward. apply AndL. do 2 backward. peapply (IHHp φ0). ms.
+- apply OrR1; auto.
+- apply OrR2; auto.
+- case (decide (φ0 = (φ ψ))).
+  + intro; subst. simpl. apply OrL.
+      * peapply Hp1.
+      * peapply Hp2.
+  + intro. forward. apply OrL.
+      * backward. peapply (IHHp1 φ0). ms.
+      * backward. peapply (IHHp2 φ0). ms.
+- apply ImpR. backward. apply IHHp. ms.
+- case (decide (φ0 = Var p)).
+  + intro; subst; simpl. forward. apply ImpLVar. peapply Hp.
+  + intro. case (decide (φ0 = (Var p φ))).
+      * intro; subst; simpl. peapply ImpLVar. exact Hp. ms.
+      * intro. do 2 forward. exch 0. apply ImpLVar. exch 0. do 2 backward.
+         apply IHHp. ms.
+- case (decide (φ0 = (φ1 φ2 φ3))).
+  + intro; subst; simpl. apply ImpLAnd. peapply Hp.
+  + intro. forward. apply ImpLAnd. backward. apply IHHp. ms.
+- case (decide (φ0 = (φ1 φ2 φ3))).
+  + intro; subst; simpl. apply ImpLOr. peapply Hp.
+  + intro. forward. apply ImpLOr. exch 0. do 2 backward. apply IHHp. ms.
+- case (decide (φ0 = ((φ1 φ2) φ3))).
+  + intro; subst; simpl. apply ImpLImp. peapply Hp1. peapply Hp2.
+  + intro. forward. apply ImpLImp.
+      * backward. apply IHHp1. ms.
+      * backward. apply IHHp2. ms.
+- case (decide (φ0 = ( φ1 φ2))).
+  + intro; subst; simpl. apply ImpBox.
+      * peapply Hp1; autorewrite with proof; ms.
+      * peapply Hp2; autorewrite with proof.
+  + intro. forward.
+      case (decide (open_box φ0 = φ1)).
+      * intro Heq. repeat rewrite Heq. apply ImpBox; box_tac.
+        -- exch 1; exch 0. apply generalised_axiom.
+        -- backward. rewrite <- Heq. apply IHHp2. auto with *.
+      * intro Hneq. case (decide (open_box φ0 = φ2)).
+          -- intro Heq. subst φ2. apply ImpBox; box_tac.
+              ++ peapply (IHHp1 ( φ0)); [ms|].
+                      autorewrite with proof; [|ms]. repeat rewrite env_replace.
+                     ** ms.
+                     ** auto with proof.
+                     ** apply env_in_add. right. auto with proof; ms.
+              ++ box_tac. backward. apply (IHHp2 φ0). auto with *.
+          -- intro Hneq'. apply ImpBox; repeat box_tac.
+            ++ exch 0. box_tac. backward. backward. apply (IHHp1 ( φ0)).
+                    apply env_in_add. now right.
+            ++ backward. apply IHHp2. apply env_in_add. now right.
+- case (decide (open_box φ0 = φ)).
+  + intro Heq; rewrite Heq. apply generalised_axiom.
+  + intro. backward. apply BoxR. box_tac.
+      case (decide (open_box φ0 = open_box (open_box φ0))).
+      * intro Heq. peapply Hp. autorewrite with proof. rewrite <- Heq. ms. ms.
+      * intro. assert( open_box φ0 open_boxes Γ) by (now apply In_open_boxes).
+        peapply (IHHp (open_box φ0)).
+        -- ms.
+        -- autorewrite with proof. repeat rewrite env_replace; ms. ms.
+Qed.
+ +
+Local Hint Resolve env_in_add : proof.
+ +
+Lemma open_boxes_R (Γ : env) (φ ψ : form): (Γ φ) ψ ((Γ) φ) ψ.
+Proof.
+revert ψ.
+induction Γ using gmultiset_rec; intro ψ.
+- rewrite open_boxes_empty. trivial.
+- intro HP. peapply (open_box_L ( Γ φ) x ψ).
+  + apply ImpR_rev, IHΓ, ImpR. peapply HP.
+  + rewrite open_boxes_disj_union, open_boxes_singleton; ms.
+Qed.
+Lemma AndL_rev Γ φ ψ θ: (Γφ ψ) θ (Γφψ) θ.
+Proof.
+intro Hp.
+remember (Γφ ψ) as Γ' eqn:HH.
+assert (Heq: Γ Γ' {[ φ ψ ]}) by ms.
+assert(Hin : (φ ψ) Γ')by ms.
+rw Heq 2. clear Γ HH Heq. revert φ ψ Hin.
+(* we massaged the goal so that the environment of the derivation on which we do
+   the induction is not composite anymore *)

+induction Hp; intros φ0 ψ0 Hin; try forward.
+(* auto takes care of the right rules easily *)
+- auto with proof.
+- auto with proof.
+- auto with proof.
+(* the main case *)
+- case(decide ((φ ψ) = (φ0 ψ0))); intro Heq0.
+  + inversion Heq0; subst. peapply Hp.
+  + forward. constructor 4. exch 0. backward. backward. apply IHHp. ms.
+(* only left rules remain. Now it's all a matter of putting the right principal
+   formula at the front, apply the rule; and put back the front formula at the back
+   before applying the induction hypothesis *)

+- auto with proof.
+- auto with proof.
+- constructor 7; backward; [apply IHHp1 | apply IHHp2]; ms.
+- constructor 8. backward. apply IHHp. ms.
+- forward. exch 0. constructor 9. exch 0. do 2 backward. apply IHHp. ms.
+- constructor 10. backward. apply IHHp. ms.
+- constructor 11. exch 0. do 2 backward. apply IHHp. ms.
+- constructor 12; backward.
+  + apply IHHp1. ms.
+  + apply IHHp2. ms.
+- constructor 13; repeat box_tac.
+  + exch 0. box_tac.
+      apply In_open_boxes in Hin0. backward. backward. apply open_box_L. exch 0. apply open_box_L. exch 0.
+      apply IHHp1. ms.
+  + backward. apply IHHp2. ms.
+- constructor 14. repeat box_tac.
+  exch 0. apply open_box_L.
+  exch 1; exch 0. apply open_box_L.
+  peapply (IHHp φ0 ψ0).
+  + apply env_in_add. right. apply In_open_boxes in Hin. auto with proof.
+  + autorewrite with proof. simpl. rewrite <- env_replace. ms.
+      apply In_open_boxes in Hin. auto with proof.
+Qed.
+ +
+Lemma OrL_rev Γ φ ψ θ: (Γφ ψ) θ (Γφ θ) * (Γψ θ).
+Proof.
+intro Hp.
+remember (Γφ ψ) as Γ' eqn:HH.
+assert (Heq: Γ Γ' {[ φ ψ ]}) by ms.
+assert(Hin : (φ ψ) Γ')by ms.
+assert(Heq' : ((Γ' {[φ ψ]}φ) θ) * ((Γ' {[φ ψ]}ψ) θ));
+[| split; rw Heq 1; tauto].
+clear Γ HH Heq.
+induction Hp.
+- split; forward; auto with proof.
+- split; forward; auto with proof.
+- split; constructor 3; intuition.
+- split; forward; constructor 4; exch 0; do 2 backward; apply IHHp; ms.
+- split; constructor 5; intuition.
+- split; apply OrR2; intuition.
+- case (decide ((φ0 ψ0) = (φ ψ))); intro Heq0.
+  + inversion Heq0; subst. split; [peapply Hp1| peapply Hp2].
+  + split; forward; constructor 7; backward; (apply IHHp1||apply IHHp2); ms.
+- split; constructor 8; backward; apply IHHp; ms.
+- split; do 2 forward; exch 0; constructor 9; exch 0; do 2 backward; apply IHHp; ms.
+- split; forward; constructor 10; backward; apply IHHp; ms.
+- split; forward; constructor 11; exch 0; do 2 backward; apply IHHp; ms.
+- split; forward; constructor 12; backward; (apply IHHp1 || apply IHHp2); ms.
+- split; forward; assert(Hin' : (φ ψ) ( Γ φ1 φ2))
+  by (apply env_in_add; right; apply env_in_add; right; auto with proof);
+  assert((φ ψ) Γ) by auto with proof;
+  (constructor 13; repeat box_tac; exch 0;
+    [do 2 backward; apply open_box_L; apply IHHp1|exch 0; backward; apply IHHp2];ms).
+- assert (Hin' : (φ ψ) ( Γ φ0)) by (apply env_in_add; right; auto with proof).
+    split; constructor 14; repeat box_tac; backward; apply open_box_L; now apply IHHp.
+Qed.
+ +
+Lemma TopL_rev Γ φ θ: Γ•( φ) θ -> Γ θ.
+Proof.
+remember (Γ•( φ)) as Γ' eqn:HH.
+assert (Heq: Γ Γ' {[ φ ]}) by ms.
+assert(Hin : ( φ) Γ')by ms. clear HH.
+intro Hp. rw Heq 0. clear Γ Heq. induction Hp;
+try forward.
+- auto with proof.
+- auto with proof.
+- auto with proof.
+- constructor 4. exch 0. do 2 backward. apply IHHp. ms.
+- auto with proof.
+- auto with proof.
+- constructor 7; backward; [apply IHHp1 | apply IHHp2]; ms.
+- constructor 8. backward. apply IHHp. ms.
+- forward. exch 0. constructor 9. exch 0. do 2 backward. apply IHHp. ms.
+- constructor 10. backward. apply IHHp. ms.
+- constructor 11. exch 0. do 2 backward. apply IHHp. ms.
+- constructor 12; backward; [apply IHHp1 | apply IHHp2]; ms.
+- constructor 13; box_tac.
+  + exch 0. do 2 backward. apply IHHp1. ms.
+  + backward. apply IHHp2. ms.
+- constructor 14. box_tac. backward. apply IHHp. ms.
+Qed.
+ +
+Local Hint Immediate TopL_rev : proof.
+ +
+Lemma ImpLVar_rev Γ p φ ψ: (ΓVar p•(p φ)) ψ (ΓVar pφ) ψ.
+Proof.
+intro Hp.
+remember (ΓVar p•(p φ)) as Γ' eqn:HH.
+assert (Heq: (ΓVar p) Γ' {[Var p φ]}) by ms.
+assert(Hin : (p φ) Γ')by ms.
+rw Heq 1. clear Γ HH Heq.
+induction Hp; try forward.
+- auto with proof.
+- auto with proof.
+- auto with proof.
+- apply AndL. exch 0. do 2 backward. apply IHHp. ms.
+- auto with proof.
+- auto with proof.
+- apply OrL; backward; apply IHHp1 || apply IHHp2; ms.
+- apply ImpR. backward. apply IHHp. ms.
+- case (decide ((Var p0 φ0) = (Var p φ))); intro Heq0.
+  + inversion Heq0; subst. peapply Hp.
+  + do 2 forward. exch 0. apply ImpLVar. exch 0; do 2 backward. apply IHHp. ms.
+- apply ImpLAnd. backward. apply IHHp. ms.
+- apply ImpLOr. exch 0; do 2 backward. apply IHHp. ms.
+- apply ImpLImp; backward; (apply IHHp1 || apply IHHp2); ms.
+- apply ImpBox; repeat box_tac.
+   + exch 0; do 2 backward. apply open_box_L. apply IHHp1. ms.
+   + backward. apply IHHp2. ms.
+- apply BoxR. repeat box_tac. backward. apply open_box_L. apply IHHp. ms.
+Qed.
+ +
+(* inversion for ImpLImp is only partial *)
+Lemma ImpLImp_prev Γ φ1 φ2 φ3 ψ: (Γ•((φ1 φ2) φ3)) ψ -> (Γφ3) ψ.
+Proof.
+intro Hp.
+remember (Γ •((φ1 φ2) φ3)) as Γ' eqn:HH.
+assert (Heq: Γ Γ' {[ ((φ1 φ2) φ3) ]}) by ms.
+assert(Hin :((φ1 φ2) φ3) Γ')by ms.
+rw Heq 1. clear Γ HH Heq.
+induction Hp; try forward.
+- auto with proof.
+- auto with proof.
+- auto with proof.
+- apply AndL. exch 0; do 2 backward. apply IHHp. ms.
+- auto with proof.
+- auto with proof.
+- apply OrL; backward; [apply IHHp1 | apply IHHp2]; ms.
+- apply ImpR. backward. apply IHHp. ms.
+- forward. exch 0. apply ImpLVar. exch 0. do 2 backward. apply IHHp. ms.
+- apply ImpLAnd. backward. apply IHHp. ms.
+- apply ImpLOr. exch 0. do 2 backward. apply IHHp. ms.
+- case (decide (((φ0 φ4) φ5) = ((φ1 φ2) φ3))); intro Heq0.
+  + inversion Heq0; subst. peapply Hp2.
+  + forward. apply ImpLImp; backward; (apply IHHp1 || apply IHHp2); ms.
+- apply ImpBox; repeat box_tac.
+  + exch 0; do 2 backward. apply open_box_L. apply IHHp1. ms.
+  + backward. apply IHHp2. ms.
+- apply BoxR. repeat box_tac. backward. apply open_box_L. apply IHHp. ms.
+Qed.
+ +
+(* inversion for ImpLbox is only partial too *)
+Lemma ImpLBox_prev Γ φ1 φ2 ψ: (Γ•((φ1) φ2)) ψ -> (Γφ2) ψ.
+Proof.
+intro Hp.
+remember (Γ •((φ1) φ2)) as Γ' eqn:HH.
+assert (Heq: Γ Γ' {[ ((φ1) φ2) ]}) by ms.
+assert(Hin :((φ1) φ2) Γ')by ms.
+rw Heq 1. clear Γ HH Heq.
+induction Hp; try forward.
+- auto with proof.
+- auto with proof.
+- auto with proof.
+- apply AndL. exch 0; do 2 backward. apply IHHp. ms.
+- auto with proof.
+- auto with proof.
+- apply OrL; backward; [apply IHHp1 | apply IHHp2]; ms.
+- apply ImpR. backward. apply IHHp. ms.
+- forward. exch 0. apply ImpLVar. exch 0. do 2 backward. apply IHHp. ms.
+- apply ImpLAnd. backward. apply IHHp. ms.
+- apply ImpLOr. exch 0. do 2 backward. apply IHHp. ms.
+- apply ImpLImp; backward; (apply IHHp1 || apply IHHp2); ms.
+- case (decide((φ0 φ3) = (φ1 φ2))).
+  + intro Heq; inversion Heq; subst. peapply Hp2.
+  + intro Hneq. forward. apply ImpBox; repeat box_tac.
+     * exch 0; do 2 backward. apply open_box_L; apply IHHp1. ms.
+     * backward. apply IHHp2. ms.
+- apply BoxR. repeat box_tac. backward. apply open_box_L. apply IHHp. ms.
+Qed.
+ +
+Lemma ImpLOr_rev Γ φ1 φ2 φ3 ψ: Γ•((φ1 φ2) φ3) ψ -> Γ•(φ1 φ3)•(φ2 φ3) ψ.
+Proof.
+intro Hp.
+remember (Γ •((φ1 φ2) φ3)) as Γ' eqn:HH.
+assert (Heq: Γ Γ' {[ ((φ1 φ2) φ3) ]}) by ms.
+assert(Hin :((φ1 φ2) φ3) Γ')by ms.
+rw Heq 2. clear Γ HH Heq.
+induction Hp; try forward.
+- auto with proof.
+- auto with proof.
+- auto with proof.
+- constructor 4. exch 0; do 2 backward. apply IHHp. ms.
+- auto with proof.
+- auto with proof.
+- constructor 7; backward; [apply IHHp1 | apply IHHp2]; ms.
+- constructor 8. backward. apply IHHp. ms.
+- forward. exch 0. constructor 9. exch 0. do 2 backward. apply IHHp. ms.
+- constructor 10. backward. apply IHHp. ms.
+- case (decide (((φ0 φ4) φ5) = ((φ1 φ2) φ3))); intro Heq0.
+  + inversion Heq0; subst. peapply Hp.
+  + forward. constructor 11; exch 0; do 2 backward; apply IHHp; ms.
+- constructor 12; backward; (apply IHHp1 || apply IHHp2); ms.
+- apply ImpBox; repeat box_tac.
+  + exch 0; do 2 backward. apply IHHp1. ms.
+  + backward. apply IHHp2. ms.
+- apply BoxR. repeat box_tac. backward. apply IHHp. ms.
+Qed.
+ +
+Lemma ImpLAnd_rev Γ φ1 φ2 φ3 ψ: (Γ•(φ1 φ2 φ3)) ψ -> (Γ•(φ1 φ2 φ3)) ψ .
+Proof.
+intro Hp.
+remember (Γ •((φ1 φ2) φ3)) as Γ' eqn:HH.
+assert (Heq: Γ Γ' {[ ((φ1 φ2) φ3) ]}) by ms.
+assert(Hin :((φ1 φ2) φ3) Γ')by ms.
+rw Heq 1. clear Γ HH Heq.
+induction Hp; try forward.
+- auto with proof.
+- auto with proof.
+- auto with proof.
+- constructor 4. exch 0; do 2 backward. apply IHHp. ms.
+- auto with proof.
+- auto with proof.
+- constructor 7; backward; [apply IHHp1 | apply IHHp2]; ms.
+- constructor 8. backward. apply IHHp. ms.
+- forward. exch 0. constructor 9. exch 0. do 2 backward. apply IHHp. ms.
+- case (decide (((φ0 φ4) φ5) = ((φ1 φ2) φ3))); intro Heq0.
+  + inversion Heq0; subst. peapply Hp.
+  + forward. constructor 10. backward. apply IHHp. ms.
+- constructor 11; exch 0; do 2 backward; apply IHHp; ms.
+- constructor 12; backward; (apply IHHp1 || apply IHHp2); ms.
+- apply ImpBox; repeat box_tac.
+  + exch 0; do 2 backward. apply IHHp1. ms.
+  + backward. apply IHHp2. ms.
+- apply BoxR. repeat box_tac. backward. apply IHHp. ms.
+Qed.
+ +
+Global Hint Resolve AndL_rev : proof.
+Global Hint Resolve OrL_rev : proof.
+Global Hint Resolve ImpLVar_rev : proof.
+Global Hint Resolve ImpLOr_rev : proof.
+Global Hint Resolve ImpLAnd_rev : proof.
+Global Hint Resolve ImpLBox_prev : proof.
+ +
+Lemma exfalso Γ φ: Γ -> Γ φ.
+Proof.
+intro Hp. dependent induction Hp; try tauto; auto with proof; tauto.
+Qed.
+ +
+Global Hint Immediate exfalso : proof.
+ +
+Lemma AndR_rev {Γ φ1 φ2} : Γ φ1 φ2 -> (Γ φ1) * (Γ φ2).
+Proof. intro Hp. dependent induction Hp generalizing φ1 φ2 Hp; intuition; auto with proof. Qed.
+ +
+
+ +
+A general inversion rule for disjunction is not admissible. However, inversion holds if one of the formulas is ⊥. +
+
+ +
+Lemma OrR1Bot_rev Γ φ : Γ φ -> Γ φ.
+Proof. intro Hd. dependent induction Hd; auto with proof. Qed.
+Lemma OrR2Bot_rev Γ φ : Γ φ -> Γ φ.
+Proof. intro Hd. dependent induction Hd; auto with proof. Qed.
+ +
+
+ +
+We prove Lemma 4.1 of (Dyckhoff & Negri 2000). This lemma shows that a + weaker version of the ImpL rule of Gentzen's original calculus LJ is still + admissible in G4ip. The proof is simple, but requires the inversion lemmas + proved above. + +
+
+ +
+Lemma weak_ImpL Γ φ ψ θ :Γ φ -> Γψ θ -> Γ•(φ ψ) θ.
+Proof with (auto with proof).
+intro Hp. revert ψ θ. induction Hp; intros ψ0 θ0 Hp'.
+- auto with proof.
+- auto with proof.
+- auto with proof.
+- exch 0; constructor 4; exch 1; exch 0...
+- auto with proof.
+- apply ImpLOr. exch 0...
+- exch 0; constructor 7; exch 0...
+  + apply IHHp1. exch 0. eapply fst, OrL_rev. exch 0. exact Hp'.
+  + apply IHHp2. exch 0. eapply snd, OrL_rev. exch 0. exact Hp'.
+- auto with proof.
+- exch 0; exch 1. constructor 9. exch 1; exch 0...
+- exch 0. apply ImpLAnd. exch 0...
+- exch 0. apply ImpLOr. exch 1; exch 0...
+- exch 0. apply ImpLImp; exch 0... apply IHHp2. exch 0...
+  eapply ImpLImp_prev. exch 0. eassumption.
+- exch 0. apply ImpBox; box_tac.
+  + exch 1; exch 0...
+  + exch 0. apply IHHp2. exch 0. apply ImpLBox_prev with φ1. exch 0. exact Hp'.
+- auto with proof.
+Qed.
+ +
+Global Hint Resolve weak_ImpL : proof.
+ +
+
+ +
+

Contraction

+ + +
+ + The aim of this section is to prove that the contraction rule is admissible in + G4ip. +
+ + An auxiliary definition of **height** of a proof, measured along the leftmost branch. +
+
+Fixpoint height {Γ φ} (Hp : Γ φ) := match Hp with
+| Atom _ _ => 1
+| ExFalso _ _ => 1
+| AndR Γ φ ψ H1 H2 => 1 + height H1 + height H2
+| AndL Γ φ ψ θ H => 1 + height H
+| OrR1 Γ φ ψ H => 1 + height H
+| OrR2 Γ φ ψ H => 1 + height H
+| OrL Γ φ ψ θ H1 H2 => 1 + height H1 + height H2
+| ImpR Γ φ ψ H => 1 + height H
+| ImpLVar Γ p φ ψ H => 1 + height H
+| ImpLAnd Γ φ1 φ2 φ3 ψ H => 1 + height H
+| ImpLOr Γ φ1 φ2 φ3 ψ H => 1 + height H
+| ImpLImp Γ φ1 φ2 φ3 ψ H1 H2 => 1 + height H1 + height H2
+| ImpBox Γ φ1 φ2 ψ H1 H2 => 1 + height H1 + height H2
+| BoxR Γ φ H => 1 + height H
+end.
+ +
+Lemma height_0 {Γ φ} (Hp : Γ φ) : height Hp <> 0.
+Proof. destruct Hp; simpl; lia. Qed.
+ +
+
+ +
+Lemma 4.2 in (Dyckhoff & Negri 2000), showing that a "duplication" in the context of the implication-case of the implication-left rule is admissible. +
+
+ +
+Lemma ImpLImp_dup Γ φ1 φ2 φ3 θ:
+  Γ•((φ1 φ2) φ3) θ ->
+    Γφ1 •(φ2 φ3) •(φ2 φ3) θ.
+Proof.
+intro Hp.
+remember (Γ•((φ1 φ2) φ3)) as Γ0 eqn:Heq0.
+assert(HeqΓ : Γ Γ0 {[((φ1 φ2) φ3)]}) by ms.
+rw HeqΓ 3.
+assert(Hin : ((φ1 φ2) φ3) Γ0) by (subst Γ0; ms).
+clear Γ HeqΓ Heq0.
+(* by induction on the height of the derivation *)
+remember (height Hp) as h.
+assert(Hleh : height Hp h) by lia. clear Heqh.
+revert Γ0 θ Hp Hleh Hin. induction h as [|h]; intros Γ θ Hp Hleh Hin;
+[pose (height_0 Hp); lia|].
+destruct Hp; simpl in Hleh.
+- forward. auto with proof.
+- forward. auto with proof.
+- apply AndR.
+  + apply IHh with Hp1. lia. ms.
+  + apply IHh with Hp2. lia. ms.
+- forward. apply AndL. exch 0. do 2 backward. apply IHh with Hp. lia. ms.
+- apply OrR1. apply IHh with Hp. lia. ms.
+- apply OrR2. apply IHh with Hp. lia. ms.
+- forward. apply OrL; backward.
+  + apply IHh with Hp1. lia. ms.
+  + apply IHh with Hp2. lia. ms.
+- apply ImpR. backward. apply IHh with Hp. lia. ms.
+- do 2 forward. exch 0. apply ImpLVar. exch 0. do 2 backward.
+  apply IHh with Hp. lia. ms.
+- forward. apply ImpLAnd. backward. apply IHh with Hp. lia. ms.
+- forward. apply ImpLOr. exch 0. do 2 backward. apply IHh with Hp. lia. ms.
+- case (decide (((φ0 φ4) φ5) = ((φ1 φ2) φ3))); intro Heq.
+  + inversion Heq; subst.
+    apply weak_ImpL.
+    * exch 0. apply ImpR_rev. peapply Hp1.
+    * do 2 (exch 0; apply weakening). peapply Hp2.
+  + forward. apply ImpLImp; backward.
+    * apply IHh with Hp1. lia. ms.
+    * apply IHh with Hp2. lia. ms.
+- forward. apply ImpBox; repeat box_tac.
+  + exch 0. do 2 backward.
+      exch 1; exch 0. apply open_box_L; exch 0; exch 1.
+      apply IHh with Hp1. lia. ms.
+  + backward. apply IHh with Hp2. lia. ms.
+- apply BoxR. repeat box_tac. backward.
+  exch 1; exch 0; apply open_box_L; exch 0; exch 1.
+  apply IHh with Hp. lia. ms.
+Qed.
+ +
+Lemma ImpBox_dup Γ φ1 φ2 θ:
+  Γ•(φ1 φ2) θ ->
+    Γ φ1 φ1 φ2 θ.
+Proof.
+intro Hp.
+remember (Γ ( φ1 φ2)) as Γ0 eqn:Heq0.
+assert(HeqΓ : Γ Γ0 {[( φ1 φ2)]}) by ms.
+rw HeqΓ 3.
+assert(Hin : ( φ1 φ2) Γ0) by (subst Γ0; ms).
+clear Γ HeqΓ Heq0.
+(* by induction on the height of the derivation *)
+remember (height Hp) as h.
+assert(Hleh : height Hp h) by lia. clear Heqh.
+revert Γ0 θ Hp Hleh Hin. induction h as [|h]; intros Γ θ Hp Hleh Hin;
+[pose (height_0 Hp); lia|].
+destruct Hp; simpl in Hleh.
+- forward. auto with proof.
+- forward. auto with proof.
+- apply AndR.
+  + apply IHh with Hp1. lia. ms.
+  + apply IHh with Hp2. lia. ms.
+- forward. apply AndL. exch 0. do 2 backward. apply IHh with Hp. lia. ms.
+- apply OrR1. apply IHh with Hp. lia. ms.
+- apply OrR2. apply IHh with Hp. lia. ms.
+- forward. apply OrL; backward.
+  + apply IHh with Hp1. lia. ms.
+  + apply IHh with Hp2. lia. ms.
+- apply ImpR. backward. apply IHh with Hp. lia. ms.
+- do 2 forward. exch 0. apply ImpLVar. exch 0. do 2 backward.
+  apply IHh with Hp. lia. ms.
+- forward. apply ImpLAnd. backward. apply IHh with Hp. lia. ms.
+- forward. apply ImpLOr. exch 0. do 2 backward. apply IHh with Hp. lia. ms.
+- forward. apply ImpLImp.
+  + backward. apply IHh with Hp1. lia. ms.
+  + backward. apply IHh with Hp2. lia. ms.
+  (*
+case (decide (((φ0 → φ4) → φ5) = ((φ1 → φ2) → φ3))); intro Heq.
+  + inversion Heq; subst.
+    apply weak_ImpL.
+    * exch 0. apply ImpR_rev. peapply Hp1.
+    * do 2 (exch 0; apply weakening). peapply Hp2.
+  + forward. apply ImpLImp; backward.
+    * apply IHh with Hp1. lia. ms.
+    * apply IHh with Hp2. lia. ms. *)

+- case (decide (( φ0 φ3) = φ1 φ2)); intro Heq.
+  + inversion Heq; subst.
+      exch 0. apply weakening. exch 0. apply weakening. peapply Hp2.
+  + forward. apply ImpBox; repeat box_tac.
+      * exch 0. do 2 backward.
+         replace (φ1) with ( ( φ1)) by trivial.
+         apply open_box_L; exch 0. apply open_box_L; exch 1; exch 0. apply open_box_L.
+         exch 1; exch 0. simpl.
+         apply IHh with Hp1. lia. ms.
+      * backward. apply IHh with Hp2. lia. ms.
+- apply BoxR. repeat box_tac. backward.
+   replace (φ1) with ( ( φ1)) by trivial.
+   apply open_box_L; exch 0. apply open_box_L; exch 1; exch 0. apply open_box_L.
+   exch 1; exch 0. simpl.
+  apply IHh with Hp. lia. ms.
+Qed.
+ +
+(* technical lemma for contraction *)
+Local Lemma p_contr Γ φ θ:
+  (Γφφ) {[φ]} θ ->
+  ((Γφ) θ).
+Proof. intros * Hd; peapply Hd. Qed.
+ +
+Lemma is_box_weight_open_box φ : is_box φ = true -> weight ( φ) = weight φ -1.
+Proof. destruct φ; simpl; lia. Qed.
+ +
+Lemma weight_open_box φ : weight ( φ) weight φ.
+Proof. destruct φ; simpl; lia. Qed.
+ +
+
+ +
+Admissibility of contraction in G4ip. +
+
+Lemma contraction Γ ψ θ : Γψψ θ -> Γψ θ.
+Proof.
+remember (Γψψ) as Γ0 eqn:Heq0.
+assert(HeqΓ : (Γψ) Γ0 {[ψ]}) by ms.
+intro Hp. rw HeqΓ 0.
+assert(Hin : ψ Γ0) by (subst Γ0; ms).
+assert(Hin' : ψ Γ0 {[ψ]}) by(rewrite <- HeqΓ; ms).
+clear Γ HeqΓ Heq0. revert Hp.
+(* by induction on the weight of ψ *)
+remember (weight ψ) as w.
+assert(Hle : weight ψ w) by lia.
+clear Heqw. revert Γ0 ψ θ Hle Hin Hin'.
+induction w; intros Γ ψ θ Hle Hin Hin' Hp; [destruct ψ; simpl in Hle; lia|].
+(* by induction on the height of the premise *)
+remember (height Hp) as h.
+assert(Hleh : height Hp h) by lia. clear Heqh.
+revert Γ θ Hp Hleh Hin Hin'. revert ψ Hle; induction h as [|h]; intros ψ Hle Γ θ Hp Hleh Hin Hin';
+[pose (height_0 Hp); lia|].
+destruct Hp; simpl in Hleh, Hle.
+- case(decide= Var p)).
+  + intro; subst. exhibit Hin' 0. apply Atom.
+  + intro Hneq. forward. apply Atom.
+- case(decide= )).
+  + intro; subst. exhibit Hin' 0. apply ExFalso.
+  + intro. forward. apply ExFalso.
+- apply AndR.
+  + apply (IHh ψ Hle) with Hp1. lia. ms. ms.
+  + apply (IHh ψ Hle) with Hp2. lia. ms. ms.
+- case (decide= (φ ψ0))); intro Heq.
+  + subst. exhibit Hin' 0. apply AndL.
+    apply p_contr. simpl in Hle. apply IHw. lia. ms. rewrite union_difference_R; ms.
+    exch 1. exch 0. apply p_contr. apply IHw. lia. ms. rewrite union_difference_R; ms.
+    exch 1. exch 0. apply AndL_rev. exch 0. exch 1. peapply Hp.
+    rewrite <- (difference_singleton _ _ Hin'). ms.
+  + rewrite union_difference_L in Hin' by ms.
+    forward. apply AndL. exch 0. do 2 backward. apply (IHh ψ Hle) with Hp. lia. ms. ms.
+- apply OrR1. apply (IHh ψ Hle) with Hp. lia. ms. ms.
+- apply OrR2. apply (IHh ψ Hle) with Hp. lia. ms. ms.
+- case (decide= (φ ψ0))); intro Heq.
+  + subst. exhibit Hin' 0.
+    apply OrL.
+    * apply p_contr. simpl in Hle. apply IHw. lia. ms. rewrite union_difference_R; ms.
+      refine (fst (OrL_rev _ φ ψ0 _ _)). exch 0. peapply Hp1.
+      rewrite <- env_replace; ms.
+    * apply p_contr. simpl in Hle. apply IHw. lia. ms. rewrite union_difference_R; ms.
+      refine (snd (OrL_rev _ φ ψ0 _ _)). exch 0. peapply Hp2.
+      rewrite <- env_replace; ms.
+  + rewrite union_difference_L in Hin' by ms.
+    forward. apply OrL; backward.
+    * apply (IHh ψ Hle) with Hp1. lia. ms. ms.
+    * apply (IHh ψ Hle) with Hp2. lia. ms. ms.
+- apply ImpR. backward. apply (IHh ψ Hle) with Hp. lia. ms. ms.
+- case (decide= (p φ))); intro Heq.
+  + subst. exhibit Hin' 0. rewrite union_difference_R in Hin' by ms.
+    assert(Hcut : (((ΓVar p) {[Var p φ]}•(Var p φ)) ψ0)); [|peapply Hcut].
+    forward. exch 0. apply ImpLVar, p_contr.
+    apply IHw. simpl in Hle; lia. ms. rewrite union_difference_L; ms.
+    exch 1. apply ImpLVar_rev. exch 0; exch 1. peapply Hp.
+    rewrite <- env_replace; ms.
+  + rewrite union_difference_L in Hin' by ms.
+      forward. case (decide= Var p)).
+      * intro; subst. forward. exch 0. apply ImpLVar. exch 0.
+         do 2 backward. apply (IHh (Var p) Hle) with Hp. lia. ms. ms.
+      * intro. forward. exch 0. apply ImpLVar; exch 0; do 2 backward.
+         apply (IHh ψ Hle) with Hp. lia. ms. ms.
+- case (decide= (φ1 φ2 φ3))); intro Heq.
+  + subst. exhibit Hin' 0. rewrite union_difference_R in Hin' by ms.
+    apply ImpLAnd. apply p_contr.
+    apply IHw. simpl in *; lia. ms. rewrite union_difference_L; ms.
+    apply ImpLAnd_rev. exch 0. peapply Hp.
+    rewrite <- env_replace; ms.
+  + rewrite union_difference_L in Hin' by ms.
+    forward. apply ImpLAnd. backward. apply (IHh ψ Hle) with Hp. lia. ms. ms.
+- case (decide= (φ1 φ2 φ3))); intro Heq.
+  + subst. exhibit Hin' 0. rewrite union_difference_R in Hin' by ms.
+    apply ImpLOr. apply p_contr.
+    apply IHw. simpl in *; lia. ms. rewrite union_difference_L; ms.
+    exch 1; exch 0. apply p_contr.
+    apply IHw. simpl in *. lia. ms. rewrite union_difference_L; ms.
+    exch 1; exch 0. apply ImpLOr_rev. exch 0. exch 1. peapply Hp.
+    rewrite <- env_replace; ms.
+  + rewrite union_difference_L in Hin' by ms.
+    forward. apply ImpLOr. exch 0. do 2 backward. apply (IHh ψ Hle) with Hp. lia. ms. ms.
+- case (decide= ((φ1 φ2) φ3))); intro Heq.
+  + subst. exhibit Hin' 0. rewrite union_difference_R in Hin' by ms.
+    apply ImpLImp.
+    * apply ImpR.
+      do 3 (exch 0; apply p_contr; apply IHw; [simpl in *; lia|ms|rewrite union_difference_L; ms|exch 1]).
+      exch 1; apply ImpLImp_dup. (* key lemma *)
+      exch 0; exch 1. apply ImpR_rev.
+      peapply Hp1. rewrite <- env_replace; ms.
+    * apply p_contr; apply IHw; [simpl in *; lia|ms|rewrite union_difference_L; ms|].
+      apply (ImpLImp_prev _ φ1 φ2 φ3). exch 0.
+      peapply Hp2. rewrite <- env_replace; ms.
+  + rewrite union_difference_L in Hin' by ms.
+    forward. apply ImpLImp; backward.
+    * apply (IHh ψ Hle) with Hp1. lia. ms. ms.
+    * apply (IHh ψ Hle) with Hp2. lia. ms. ms.
+- case (decide= ( φ1 φ2))); intro Heq.
+  + subst. exhibit Hin' 0.
+    apply ImpBox.
+    * assert (Hr := open_boxes_remove _ _ Hin'). simpl in Hr. box_tac. symmetry in Hr. rw Hr 2.
+        clear Hr.
+        do 3 (exch 0; apply p_contr; apply IHw; [simpl in *; lia|ms|rewrite union_difference_L; ms|exch 1]).
+       exch 0.
+       assert(Heq : ( (Γ ( φ1 φ2)) {[ φ1 φ2]} {[ φ1 φ2]}) ( (Γ {[ φ1 φ2]})))
+       by (autorewrite with proof; simpl; ms).
+       rw Heq 5. clear Heq.
+       apply ImpBox_dup. exch 0; exch 1. peapply Hp1. rewrite open_boxes_remove; [|ms]. simpl.
+       rewrite <- difference_singleton. ms. apply open_boxes_spec'. left. simpl; split; trivial. ms.
+      * apply p_contr; apply IHw; [simpl in *; lia|ms|rewrite union_difference_L; ms|].
+         apply (ImpLBox_prev _ φ1 φ2). exch 0.
+         peapply Hp2. rewrite <- env_replace; ms.
+  + rewrite union_difference_L in Hin' by ms.
+      assert(Hinψ : ψ (Γ {[ψ]})) by ms. apply In_open_boxes in Hinψ.
+      forward. apply ImpBox. box_tac. exch 0; do 2 backward.
+      * rewrite open_boxes_remove in Hinψ by trivial.
+         case_eq (is_box ψ); intro Hψ.
+       -- apply is_box_weight_open_box in Hψ.
+          assert (Hle' : weight(ψ) S w) by lia.
+          apply (IHh ( ψ) Hle') with Hp1. lia. ms. ms.
+      -- apply is_not_box_open_box in Hψ. rewrite Hψ. apply IHh with Hp1.
+          trivial. lia. rewrite <- Hψ. ms. trivial. rewrite <- Hψ. ms.
+      * backward. apply (IHh ψ Hle) with Hp2. lia. ms. ms.
+- assert(Hinψ : ψ (Γ {[ψ]})) by ms. apply In_open_boxes in Hinψ.
+   rewrite open_boxes_remove in Hinψ by trivial.
+  apply BoxR. box_tac. backward. apply IHh with Hp.
+    etransitivity. apply weight_open_box. trivial.
+    lia.
+    ms.
+    ms.
+Qed.
+ +
+Global Hint Resolve contraction : proof.
+ +
+Theorem generalised_contraction (Γ Γ' : env) φ: Γ' Γ' Γ φ -> Γ' Γ φ.
+Proof.
+revert Γ.
+induction Γ' as [| x Γ' IHΓ'] using gmultiset_rec; intros Γ Hp.
+- peapply Hp.
+- peapply (contraction (Γ' Γ) x). peapply (IHΓ' (Γxx)). peapply Hp.
+Qed.
+ +
+
+ +
+

Admissibility of LJ's implication left rule

+ +
+ + We show that the general implication left rule of LJ is admissible in G4ip. + This is Proposition 5.2 in (Dyckhoff Negri 2000). +
+
+ +
+Lemma ImpL Γ φ ψ θ: Γ•(φ ψ) φ -> Γψ θ -> Γ•(φ ψ) θ.
+Proof. intros H1 H2. apply contraction, weak_ImpL; auto with proof. Qed.
+ +
+(* Lemma 5.3 (Dyckhoff Negri 2000) shows that an implication on the left may be
+   weakened. *)

+ +
+Lemma imp_cut φ Γ ψ θ: Γ•(φ ψ) θ -> Γψ θ.
+Proof.
+intro Hp.
+remember (Γ•(φ ψ)) as Γ0 eqn:HH.
+assert (Heq: Γ Γ0 {[(φ ψ)]}) by ms.
+assert(Hin : (φ ψ) Γ0) by ms. clear HH.
+rw Heq 1. clear Heq Γ.
+remember (weight φ) as w.
+assert(Hle : weight φ w) by lia.
+clear Heqw. revert Γ0 φ ψ θ Hle Hin Hp.
+induction w; intros Γ φ ψ θ Hle Hin Hp;
+ [destruct φ; simpl in Hle; lia|].
+induction Hp.
+- forward. auto with proof.
+- forward. auto with proof.
+-apply AndR; intuition.
+- forward; apply AndL. exch 0. do 2 backward. apply IHHp. ms.
+- apply OrR1; intuition.
+- apply OrR2; intuition.
+- forward. apply OrL; backward; [apply IHHp1 | apply IHHp2]; ms.
+- apply ImpR. backward. apply IHHp. ms.
+- case (decide ((p φ0) = (φ ψ))); intro Heq0.
+  + inversion Heq0; subst. peapply Hp.
+  + do 2 forward. exch 0. apply ImpLVar. exch 0. do 2 backward. apply IHHp; ms.
+- case (decide ((φ1 φ2 φ3) = (φ ψ))); intro Heq0.
+  + inversion Heq0; subst.
+    assert(Heq1 : ((Γ•(φ1 φ2 ψ)) {[φ1 φ2 ψ]}) Γ) by ms;
+    rw Heq1 1; clear Heq1. simpl in Hle.
+    peapply (IHw (Γ•(φ2 ψ)) φ2 ψ ψ0); [lia|ms|].
+    peapply (IHw (Γ•(φ1 φ2 ψ)) φ1 (φ2 ψ) ψ0); [lia|ms|trivial].
+  + forward. apply ImpLAnd. backward. apply IHHp. ms.
+- case (decide ((φ1 φ2 φ3) = (φ ψ))); intro Heq0.
+  + inversion Heq0. subst. clear Heq0.
+    apply contraction. simpl in Hle.
+    peapply (IHw (Γψ•(φ1 ψ)) φ1 ψ); [lia|ms|].
+    exch 0.
+    peapply (IHw (Γ•(φ1 ψ)•(φ2 ψ)) φ2 ψ); trivial; [lia|ms].
+  + forward. apply ImpLOr; exch 0; do 2 backward; apply IHHp; ms.
+- case (decide (((φ1 φ2) φ3) = (φ ψ))); intro Heq0.
+  + inversion Heq0. subst. clear Heq0. peapply Hp2.
+  + forward. apply ImpLImp; backward; (apply IHHp1 || apply IHHp2); ms.
+- case (decide((φ1 φ2) = (φ ψ))).
+  + intro Heq. inversion Heq. subst. clear Heq. peapply Hp2.
+  + intro Hneq. forward. apply ImpBox; repeat box_tac.
+      * exch 0. do 2 backward. apply open_box_L. apply IHHp1. ms.
+      * backward. apply IHHp2. ms.
+- apply BoxR. repeat box_tac. backward. apply open_box_L, IHHp.
+  apply env_in_add. right. auto with proof.
+Qed.
+ +
+Global Hint Resolve imp_cut : proof.
+ +
+Lemma open_boxes_case Δ : {φ | ( φ) Δ} + {Δ Δ}.
+Proof.
+unfold open_boxes.
+induction Δ as [|ψ Δ IH] using gmultiset_rec.
+- right. ms.
+- case_eq(is_box ψ); intro Hbox.
+  + left. exists (ψ).
+      destruct ψ; try discriminate Hbox. ms.
+  + destruct IH as [[φ Hφ]| Heq].
+     * left. exists φ. ms.
+     * right. symmetry. etransitivity.
+        -- apply env_equiv_eq, list_to_set_disj_perm, Permutation_map.
+            apply gmultiset_elements_disj_union.
+        -- rewrite map_app, list_to_set_disj_app. rewrite <- Heq. apply env_equiv_eq.
+            f_equal.
+            unfold elements. apply is_not_box_open_box in Hbox. rewrite <- Hbox at 2.
+            transitivity (list_to_set_disj (map open_box (id [ψ])) : env).
+            ++ apply list_to_set_disj_perm, Permutation_map.
+                    apply Permutation_refl', gmultiset_elements_singleton.
+            ++ simpl. ms.
+Qed.
+
+
+ +
+ + + diff --git a/ISL.Sequents.html b/ISL.Sequents.html new file mode 100644 index 0000000..d0e67c6 --- /dev/null +++ b/ISL.Sequents.html @@ -0,0 +1,303 @@ + + + + + + + + + + + + + +
+
+

ISL.Sequents

+ +
+Require Export ISL.Environments.
+ +
+Open Scope stdpp_scope.
+ +
+
+ +
+

Overview: Sequent calculus G4ip

+ +
+ + We implement the sequent calculus G4ip, a contraction-free + refinement of the usual Gentzen sequent calculus LJ for intuitionistic + propositional logic, which was developed by the Soviet school of proof theory + (Vorob'ev 1970) and introduced in the West by (Hudelmaier 1989) and (Dyckhoff + 1990). This calculus is also referred to as "LJT" in the literature, but we this name has also been used in the literature for other, unrelated calculi, so we prefer to use "G4ip" to avoid ambiguity. + +
+ + The calculus G4ip is important because it allows for a terminating proof + search, and in our proof of Pitts' theorem, it therefore lets us perform + well-founded induction on proofs. Technically, this is thanks to the absence of + a contraction rule. The left implication rule is refined into four separate + proof rules. +
+ +

Definition of provability in G4iSL

+ +
+
+Reserved Notation "Γ ⊢ φ" (at level 90).
+Inductive Provable : env -> form -> Type :=
+| Atom : Γ p, Γ (Var p) (Var p)
+| ExFalso : Γ φ, Γ φ
+| AndR : Γ φ ψ,
+    Γ φ -> Γ ψ ->
+      Γ (φ ψ)
+| AndL : Γ φ ψ θ,
+    Γ φ ψ θ ->
+      Γ (φ ψ) θ
+| OrR1 : Γ φ ψ,
+    Γ φ ->
+      Γ (φ ψ)
+| OrR2 : Γ φ ψ,
+    Γ ψ ->
+      Γ (φ ψ)
+| OrL : Γ φ ψ θ,
+    Γ φ θ -> Γ ψ θ ->
+      Γ (φ ψ) θ
+| ImpR : Γ φ ψ,
+    Γ φ ψ ->
+      Γ (φ ψ)
+| ImpLVar : Γ p φ ψ,
+    Γ Var p φ ψ ->
+      Γ Var p (Var p φ) ψ
+| ImpLAnd : Γ φ1 φ2 φ3 ψ,
+    Γ (φ1 (φ2 φ3)) ψ ->
+      Γ ((φ1 φ2) φ3) ψ
+| ImpLOr : Γ φ1 φ2 φ3 ψ,
+    Γ (φ1 φ3) (φ2 φ3) ψ ->
+      Γ ((φ1 φ2) φ3) ψ
+| ImpLImp : Γ φ1 φ2 φ3 ψ,
+    Γ (φ2 φ3) (φ1 φ2) ->Γ φ3 ψ ->
+      Γ ((φ1 φ2) φ3) ψ
+| ImpBox : Γ φ1 φ2 ψ,
+    ( Γ) φ1 φ2 φ1 ->
+    Γ φ2 ψ ->
+      Γ (( φ1) φ2) ψ
+| BoxR : Γ φ, open_boxes Γ φ φ -> Γ φ
+where "Γ ⊢ φ" := (Provable Γ φ).
+ +
+Global Hint Constructors Provable : proof.
+ +
+
+ +
+We show that equivalent multisets prove the same things. +
+
+Global Instance proper_Provable : Proper ((≡@{env}) ==> (=) ==> (=)) Provable.
+Proof. intros Γ Γ' Heq φ φ' Heq'. ms. Qed.
+ +
+
+ +
+We introduce a tactic "peapply" which allows for application of a G4ip rule + even in case the environment needs to be reordered +
+
+Ltac peapply th :=
+  (erewrite proper_Provable; [| |reflexivity]); [eapply th|try ms].
+ +
+
+ +
+

Tactics

+ +
+ + We introduce a few tactics that we will need to prove the admissibility of + the weakening and exchange rules in the proof calculus. +
+ + The tactic "exch" swaps the nth pair of formulas of a sequent, counting from the right. +
+
+ +
+Ltac exch n := match n with
+| O => rewrite (proper_Provable _ _ (env_add_comm _ _ _) _ _ eq_refl)
+| S O => rewrite (proper_Provable _ _ (equiv_disj_union_compat_r (env_add_comm _ _ _)) _ _ eq_refl)
+| S (S O) => rewrite (proper_Provable _ _ (equiv_disj_union_compat_r(equiv_disj_union_compat_r (env_add_comm _ _ _))) _ _ eq_refl)
+| S (S (S O)) => rewrite (proper_Provable _ _ (equiv_disj_union_compat_r(equiv_disj_union_compat_r(equiv_disj_union_compat_r (env_add_comm _ _ _)))) _ _ eq_refl)
+end.
+ +
+
+ +
+The tactic "exhibit" exhibits an element that is in the environment. +
+
+Ltac exhibit Hin n := match n with
+| 0 => rewrite (proper_Provable _ _ (difference_singleton _ _ Hin) _ _ eq_refl)
+| 1 => rewrite (proper_Provable _ _ (equiv_disj_union_compat_r (difference_singleton _ _ Hin)) _ _ eq_refl)
+| 2 => rewrite (proper_Provable _ _ (equiv_disj_union_compat_r (equiv_disj_union_compat_r (difference_singleton _ _ Hin))) _ _ eq_refl)
+| 3 => rewrite (proper_Provable _ _ (equiv_disj_union_compat_r(equiv_disj_union_compat_r (equiv_disj_union_compat_r (difference_singleton _ _ Hin)))) _ _ eq_refl)
+end.
+ +
+
+ +
+The tactic "forward" tries to change a goal of the form : + +
+ +((Γ•φ ∖ {ψ}•…) ⊢ … + +
+ +into + +
+ +((Γ ∖ {ψ}•…•φ) ⊢ … , + +
+ +by first proving that ψ ∈ Γ. +
+
+ +
+Ltac forward := match goal with
+| |- (?Γ) {[]} _ =>
+  let Hin := fresh "Hin" in
+  assert(Hin : ψ Γ) by ms;
+  rewrite (proper_Provable _ _ (env_replace φ Hin) _ _ eq_refl)
+| |- (?Γ) {[]}_ _ =>
+  let Hin := fresh "Hin" in
+  assert(Hin : ψ Γ) by ms;
+  rewrite (proper_Provable _ _ (equiv_disj_union_compat_r (env_replace φ Hin)) _ _ eq_refl);
+  exch 0
+| |- (?Γ) {[]}__ _ =>
+  let Hin := fresh "Hin" in
+  assert(Hin : ψ Γ) by ms;
+  rewrite (proper_Provable _ _ (equiv_disj_union_compat_r(equiv_disj_union_compat_r (env_replace φ Hin))) _ _ eq_refl);
+  exch 1; exch 0
+| |- (?Γ) {[]}___ _ =>
+  let Hin := fresh "Hin" in
+  assert(Hin : ψ Γ) by ms;
+  rewrite (proper_Provable _ _ (equiv_disj_union_compat_r(equiv_disj_union_compat_r(equiv_disj_union_compat_r (env_replace φ Hin)))) _ _ eq_refl);
+  exch 2; exch 1; exch 0
+| |- (?Γ) {[]}____ _ =>
+  let Hin := fresh "Hin" in
+  assert(Hin : ψ Γ) by ms;
+  rewrite (proper_Provable _ _ (equiv_disj_union_compat_r(equiv_disj_union_compat_r(equiv_disj_union_compat_r(equiv_disj_union_compat_r (env_replace φ Hin))))) _ _ eq_refl);
+  exch 3; exch 2; exch 1; exch 0
+end.
+ +
+
+ +
+The tactic "backward" changes a goal of the form : + +
+ +((Γ ∖ {ψ}•…•φ) ⊢ … + +
+ +into + +
+ +((Γ•φ ∖ {ψ}•…) ⊢ …, + +
+ +by first proving that ψ ∈ Γ. + +
+ + +
+
+ +
+Ltac backward := match goal with
+| |- ?Γ {[]} _ =>
+  let Hin := fresh "Hin" in
+  assert(Hin : ψ Γ) by (ms || auto with proof);
+  rewrite (proper_Provable _ _ (symmetry(env_replace _ Hin)) _ _ eq_refl)
+| |- ?Γ {[]}_ _ =>
+  let Hin := fresh "Hin" in
+  assert(Hin : ψ Γ) by (ms || auto with proof); try exch 0;
+  rewrite (proper_Provable _ _ (symmetry(equiv_disj_union_compat_r (env_replace _ Hin))) _ _ eq_refl)
+| |- ?Γ {[]}__ _ =>
+  let Hin := fresh "Hin" in
+  assert(Hin : ψ Γ) by (ms || auto with proof); exch 0; exch 1;
+  rewrite (proper_Provable _ _ (symmetry(equiv_disj_union_compat_r(equiv_disj_union_compat_r (env_replace φ Hin)))) _ _ eq_refl)
+| |- ?Γ {[]}___ _ =>
+  let Hin := fresh "Hin" in
+  assert(Hin : ψ Γ) by (ms || auto with proof); exch 0; exch 1; exch 2;
+  rewrite (proper_Provable _ _ (symmetry(equiv_disj_union_compat_r(equiv_disj_union_compat_r(equiv_disj_union_compat_r (env_replace φ Hin))))) _ _ eq_refl)
+| |- ?Γ {[]}____ _ =>
+  let Hin := fresh "Hin" in
+  assert(Hin : ψ Γ) by (ms || auto with proof); exch 0; exch 1; exch 2; exch 3;
+  rewrite (proper_Provable _ _ (symmetry(equiv_disj_union_compat_r(equiv_disj_union_compat_r(equiv_disj_union_compat_r(equiv_disj_union_compat_r (env_replace φ Hin)))))) _ _ eq_refl)
+end.
+ +
+
+ +
+The tactic "rw" rewrites the environment equivalence Heq under the nth formula in the premise. +
+
+Ltac rw Heq n := match n with
+| 0 => erewrite (proper_Provable _ _ Heq _ _ eq_refl)
+| 1 => erewrite (proper_Provable _ _ (equiv_disj_union_compat_r Heq) _ _ eq_refl)
+| 2 => erewrite (proper_Provable _ _ (equiv_disj_union_compat_r(equiv_disj_union_compat_r Heq)) _ _ eq_refl)
+| 3 => erewrite (proper_Provable _ _ (equiv_disj_union_compat_r(equiv_disj_union_compat_r(equiv_disj_union_compat_r Heq))) _ _ eq_refl)
+| 4 => erewrite (proper_Provable _ _ (equiv_disj_union_compat_r(equiv_disj_union_compat_r(equiv_disj_union_compat_r (equiv_disj_union_compat_r Heq)))) _ _ eq_refl)
+| 5 => erewrite (proper_Provable _ _ (equiv_disj_union_compat_r(equiv_disj_union_compat_r(equiv_disj_union_compat_r(equiv_disj_union_compat_r (equiv_disj_union_compat_r Heq))))) _ _ eq_refl)
+end.
+ +
+Ltac box_tac :=
+       let rec box_tac_aux Δ n := lazymatch Δ with
+  |⊗(?Δ' ) => rewrite (open_boxes_add Δ' φ)
+  |⊗(?Γ {[]}) => match goal with |H: ψ Γ |- _ => rw (open_boxes_remove Γ ψ H) n end
+  | ?Δ' ?φ => box_tac_aux Δ' (S n) end
+  in
+    try match goal with | |- ?Δ _ => box_tac_aux Δ 0 end; simpl.
+
+
+ +
+ + + diff --git a/ISL.Simp.html b/ISL.Simp.html new file mode 100644 index 0000000..6df470b --- /dev/null +++ b/ISL.Simp.html @@ -0,0 +1,856 @@ + + + + + + + + + + + + + +
+
+

ISL.Simp

+ +
+Require Import ISL.Environments ISL.Sequents ISL.SequentProps ISL.Cut ISL.Optimizations.
+ +
+(* Normalises a large disjunctions flattening them to the right. It assumes
+that there are no disjuctions on the left of any of the input formulas, i.e.
+φ and ψ cannot be of the form ((... ∨ ... ) ∨ ...). Since this function is called 
+with the inputs previously simplified (see `simp`) this invariant is assured. *)

+Fixpoint simp_ors φ ψ :=
+match (φ,ψ) with
+  |(φ1 φ2, ψ1 ψ2) => φ1 (ψ1 (simp_ors φ2 ψ2))
+  |(φ1 φ2, ψ) => ψ (φ1 φ2)
+  |(φ, ψ1 ψ2) => φ (ψ1 ψ2)
+  |(φ, ψ) => φ ψ
+end.
+ +
+(* Same as `simp_ors` but for large conjunctions. *)
+Fixpoint simp_ands φ ψ :=
+match (φ,ψ) with
+  |(φ1 φ2, ψ1 ψ2) => φ1 (ψ1 (simp_ands φ2 ψ2))
+  |(φ1 φ2, ψ) => ψ (φ1 φ2)
+  |(φ, ψ1 ψ2) => φ (ψ1 ψ2)
+  |(φ, ψ) => φ ψ
+end.
+ +
+Definition simp_imp φ ψ :=
+  if decide (obviously_smaller φ ψ = Lt) then
+  else if decide (obviously_smaller φ = Lt) then
+  else if decide (obviously_smaller ψ = Gt) then
+  else if decide (obviously_smaller φ = Gt) then ψ
+  else if decide (obviously_smaller ψ = Lt) then ¬φ
+  else φ ψ.
+ +
+(* Same as `simp_ors` but for nested implications. *)
+Fixpoint simp_imps φ ψ :=
+match (φ,ψ) with
+  |(φ1, ψ1 ψ2) => simp_imps (simp_ands φ1 ψ1) ψ2
+  |(φ, ψ) => simp_imp φ ψ
+end.
+Fixpoint simp φ :=
+match φ with
+  | φ ψ => simp_ors (simp φ) (simp ψ)
+  | φ ψ => simp_ands (simp φ) (simp ψ)
+  | φ ψ => simp_imps (simp φ) (simp ψ)
+  | φ => (simp φ)
+  | _ => φ
+end.
+ +
+Lemma or_comm φ ψ: φ ψ ψ φ.
+Proof.
+apply OrL; [apply OrR2 | apply OrR1]; apply generalised_axiom.
+Qed.
+ +
+Lemma or_comm_ctx_L φ ψ ϴ: (φ ψ ϴ) -> ψ φ ϴ.
+Proof.
+intro H.
+eapply weak_cut; [apply or_comm | assumption].
+Qed.
+ +
+Lemma or_comm_ctx_R φ ψ ϴ: (ϴ φ ψ ) -> ϴ ψ φ.
+Proof.
+intro H.
+eapply weak_cut; [apply H | apply or_comm].
+Qed.
+ +
+Lemma or_assoc_R φ ψ ϴ : ((φ ψ) ϴ φ (ψ ϴ)).
+Proof.
+  apply OrL.
+  - apply OrL.
+    + apply OrR1; apply generalised_axiom.
+    + apply OrR2; apply OrR1; apply generalised_axiom.
+  - apply OrR2; apply OrR2; apply generalised_axiom.
+Qed.
+ +
+Lemma or_assoc_L φ ψ ϴ : (φ (ψ ϴ) (φ ψ) ϴ).
+Proof.
+  apply OrL.
+  - apply OrR1; apply OrR1; apply generalised_axiom.
+  - apply OrL.
+    + apply OrR1; apply OrR2; apply generalised_axiom.
+    + apply OrR2; apply generalised_axiom.
+Qed.
+ +
+Lemma or_assoc_ctx_L_R φ ψ ϴ a:
+  (φ (ψ ϴ) a) -> ((φ ψ) ϴ) a.
+Proof.
+intro H.
+eapply weak_cut; [apply or_assoc_R | assumption].
+Qed.
+ +
+Lemma or_assoc_ctx_R_L φ ψ ϴ a:
+  (a (φ ψ) ϴ) ->a φ (ψ ϴ).
+Proof.
+intro H.
+eapply weak_cut; [apply H | apply or_assoc_R].
+Qed.
+ +
+Lemma or_assoc_ctx_R_R φ ψ ϴ a:
+  (a φ (ψ ϴ)) ->a (φ ψ) ϴ.
+Proof.
+intro H.
+eapply weak_cut; [apply H | apply or_assoc_L].
+Qed.
+ +
+Lemma make_disj_comm φ ψ :
+  (φ ψ) (ψ φ).
+Proof.
+apply (weak_cut _ ψ) _).
+- apply make_disj_equiv_R; apply generalised_axiom.
+- apply (weak_cut _ φ) _).
+  + apply or_comm.
+  + apply make_disj_equiv_L; apply generalised_axiom.
+Qed.
+ +
+Lemma make_disj_comm_ctx_R a φ ψ :
+  (a φ ψ) -> a ψ φ.
+Proof.
+intro H.
+eapply weak_cut; [apply H | apply make_disj_comm].
+Qed.
+ +
+Lemma make_disj_comm_ctx_L a φ ψ :
+  (φ ψ a) -> ψ φ a.
+Proof.
+intro H.
+eapply weak_cut; [apply make_disj_comm | apply H].
+Qed.
+ +
+Lemma simp_ors_self_equiv_L φ ψ:
+  (φ ψ) simp_ors φ ψ.
+Proof.
+generalize ψ.
+induction φ;
+intro ψ0;
+destruct ψ0; unfold simp_ors; try (eapply make_disj_equiv_L; apply generalised_axiom);
+try (apply make_disj_comm_ctx_R; apply make_disj_equiv_L; apply generalised_axiom).
+assert (H: φ1 ψ0_1 φ2 ψ0_2 φ1 (ψ0_1 simp_ors φ2 ψ0_2)).
+- apply make_disj_equiv_L.
+  + apply generalised_axiom.
+  + apply make_disj_equiv_L.
+    * apply generalised_axiom.
+    * apply IHφ2.
+- eapply weak_cut.
+  + apply or_assoc_ctx_L_R.
+    apply OrL.
+    * apply OrR1. apply generalised_axiom.
+    * apply OrR2. apply or_comm_ctx_L.
+      apply OrL.
+      -- apply or_assoc_ctx_R_L. apply or_comm_ctx_L.
+        apply or_comm_ctx_L.
+        apply or_comm_ctx_R.
+        apply or_assoc_ctx_R_L.
+        apply OrR1.
+        apply or_comm.
+      -- apply OrR2; apply OrR1; apply generalised_axiom.
+  + assumption.
+Qed.
+ +
+Lemma simp_equiv_or_L φ ψ :
+  (φ simp φ) -> (ψ simp ψ) ->
+  (φ ψ) simp (φ ψ).
+Proof.
+intros Hφ Hψ.
+eapply weak_cut; [apply or_congruence; [apply Hφ | apply Hψ] | apply simp_ors_self_equiv_L].
+Qed.
+ +
+Lemma simp_ors_self_equiv_R φ ψ:
+  simp_ors φ ψ φ ψ.
+Proof.
+generalize ψ.
+induction φ;
+intro ψ0;
+destruct ψ0; unfold simp_ors;
+try (eapply make_disj_equiv_R; apply generalised_axiom);
+try (apply make_disj_comm_ctx_L; apply make_disj_equiv_R; apply generalised_axiom).
+assert (H: φ1 (ψ0_1 simp_ors φ2 ψ0_2) φ1 ψ0_1 φ2 ψ0_2).
+- apply make_disj_equiv_R.
+  + apply generalised_axiom.
+  + apply make_disj_equiv_R.
+    * apply generalised_axiom.
+    * apply IHφ2.
+- apply or_assoc_ctx_R_R.
+  eapply weak_cut.
+  + apply H.
+  + apply OrL.
+    * apply OrR1; apply generalised_axiom.
+    * apply OrR2. apply or_comm_ctx_R. apply or_assoc_ctx_R_R.
+      apply OrL.
+      -- apply OrR1; apply generalised_axiom.
+      -- apply OrR2; apply or_comm.
+Qed.
+ +
+Lemma simp_equiv_or_R φ ψ:
+  (simp φ φ) -> (simp ψ ψ) ->
+  simp (φ ψ) (φ ψ).
+Proof.
+intros Hφ Hψ.
+eapply weak_cut; [ apply simp_ors_self_equiv_R | apply or_congruence; [apply Hφ | apply Hψ]].
+Qed.
+ +
+Lemma simp_equiv_or φ ψ:
+  (φ simp φ) * (simp φ φ) ->
+  (ψ simp ψ) * (simp ψ ψ) ->
+  ((φ ψ) simp (φ ψ)) * (simp (φ ψ) (φ ψ)).
+Proof.
+intros IHφ IHψ.
+split; [ apply simp_equiv_or_L | apply simp_equiv_or_R]; try apply IHφ ; try apply IHψ.
+Qed.
+ +
+Lemma and_comm φ ψ:
+  φ ψ ψ φ.
+Proof.
+apply AndL; apply AndR; [exch 0|]; apply weakening; apply generalised_axiom.
+Qed.
+ +
+Lemma and_comm_ctx_L φ ψ ϴ:
+  (φ ψ ϴ) -> ψ φ ϴ.
+Proof.
+intro H.
+eapply weak_cut; [apply and_comm | assumption].
+Qed.
+ +
+Lemma and_assoc_R φ ψ ϴ :
+  ((φ ψ) ϴ φ (ψ ϴ)).
+Proof.
+  apply AndL; exch 0; apply AndL.
+  apply AndR.
+  - exch 0. apply generalised_axiom.
+  - apply AndR.
+    + apply generalised_axiom.
+    + exch 1. exch 0. apply generalised_axiom.
+Qed.
+ +
+Lemma and_assoc_L φ ψ ϴ :
+  (φ (ψ ϴ) (φ ψ) ϴ).
+Proof.
+  apply AndL; apply AndL.
+  apply AndR.
+  - apply AndR.
+    + exch 1. exch 0. apply generalised_axiom.
+    + exch 0. apply generalised_axiom.
+  - apply generalised_axiom.
+Qed.
+ +
+Lemma and_assoc_ctx_L_R φ ψ ϴ a:
+  (φ (ψ ϴ) a) -> ((φ ψ) ϴ) a.
+Proof.
+intro H.
+eapply weak_cut; [apply and_assoc_R | assumption].
+Qed.
+ +
+Lemma and_assoc_ctx_R_L φ ψ ϴ a:
+  (a (φ ψ) ϴ) -> a φ (ψ ϴ).
+Proof.
+intro H.
+eapply weak_cut; [apply H | apply and_assoc_R].
+Qed.
+ +
+Lemma and_assoc_ctx_R_R φ ψ ϴ a:
+  (a φ (ψ ϴ)) -> a (φ ψ) ϴ.
+Proof.
+intro H.
+eapply weak_cut; [apply H | apply and_assoc_L].
+Qed.
+ +
+Lemma make_conj_comm φ ψ :
+  (φ ψ) (ψ φ).
+Proof.
+apply (weak_cut _ ψ) _).
+- apply make_conj_equiv_R; apply generalised_axiom.
+- apply (weak_cut _ φ) _).
+  + apply and_comm.
+  + apply make_conj_equiv_L; apply generalised_axiom.
+Qed.
+ +
+Lemma make_conj_comm_ctx_R a φ ψ :
+  (a φ ψ) -> a ψ φ.
+Proof.
+intro H.
+eapply weak_cut; [apply H | apply make_conj_comm].
+Qed.
+ +
+Lemma make_conj_comm_ctx_L a φ ψ :
+  (φ ψ a) -> ψ φ a.
+Proof.
+intro H.
+eapply weak_cut; [apply make_conj_comm | apply H].
+Qed.
+ +
+Lemma simp_ands_self_equiv_L φ ψ:
+  (φ ψ) simp_ands φ ψ.
+Proof.
+generalize ψ.
+induction φ;
+intro ψ0; unfold simp_ands;
+destruct ψ0; try (eapply make_conj_equiv_L; apply generalised_axiom);
+try (apply make_conj_comm_ctx_R; apply make_conj_equiv_L; apply generalised_axiom).
+assert (H: φ1 ψ0_1 φ2 ψ0_2 φ1 (ψ0_1 simp_ands φ2 ψ0_2)).
+- apply make_conj_equiv_L.
+  + apply generalised_axiom.
+  + apply make_conj_equiv_L.
+    * apply generalised_axiom.
+    * apply IHφ2.
+- eapply weak_cut.
+  + apply and_assoc_ctx_L_R.
+    do 3 (apply AndL).
+    apply AndR.
+    * exch 2. exch 1. exch 0. apply generalised_axiom.
+    * apply AndR.
+      -- exch 0. apply generalised_axiom.
+      -- apply AndR.
+         ++ exch 1. exch 0. apply generalised_axiom.
+         ++ apply generalised_axiom.
+  + assumption.
+Qed.
+ +
+Lemma simp_ands_self_equiv_R φ ψ:
+  simp_ands φ ψ φ ψ.
+Proof.
+generalize ψ.
+induction φ;
+intro ψ0;
+destruct ψ0;
+try (eapply make_conj_equiv_R; apply generalised_axiom);
+try (apply make_conj_comm_ctx_L; apply make_conj_equiv_R; apply generalised_axiom).
+assert (H: φ1 (ψ0_1 simp_ands φ2 ψ0_2) φ1 ψ0_1 φ2 ψ0_2).
+- apply make_conj_equiv_R.
+  + apply generalised_axiom.
+  + apply make_conj_equiv_R.
+    * apply generalised_axiom.
+    * apply IHφ2.
+- apply and_assoc_ctx_R_R.
+  eapply weak_cut.
+  + apply H.
+  + do 3 (apply AndL).
+    apply AndR.
+    * exch 2. exch 1. exch 0. apply generalised_axiom.
+    * apply AndR.
+      -- exch 0. apply generalised_axiom.
+      -- apply AndR.
+         ++ exch 1. exch 0. apply generalised_axiom.
+         ++ apply generalised_axiom.
+Qed.
+ +
+Lemma simp_equiv_and_L φ ψ :
+  (φ simp φ) -> (ψ simp ψ) -> (φ ψ) simp (φ ψ).
+Proof.
+intros Hφ Hψ.
+eapply weak_cut; [apply and_congruence; [apply Hφ | apply Hψ] | apply simp_ands_self_equiv_L].
+Qed.
+ +
+Lemma simp_equiv_and_R φ ψ :
+  (simp φ φ) -> (simp ψ ψ) -> simp (φ ψ) φ ψ.
+Proof.
+intros Hφ Hψ.
+eapply weak_cut; [apply simp_ands_self_equiv_R | apply and_congruence; [apply Hφ | apply Hψ]].
+Qed.
+ +
+Lemma simp_equiv_and φ ψ:
+  (φ simp φ) * (simp φ φ) ->
+  (ψ simp ψ) * (simp ψ ψ) ->
+  ((φ ψ) simp (φ ψ)) * (simp (φ ψ) (φ ψ)).
+Proof.
+intros IHφ IHψ.
+split; [ apply simp_equiv_and_L | apply simp_equiv_and_R]; try apply IHφ ; try apply IHψ.
+Qed.
+ +
+Lemma simp_imp_self_equiv_L φ ψ:
+  (φ ψ) simp_imp φ ψ.
+Proof.
+unfold simp_imp.
+case decide as [Heq |]; [apply top_provable|].
+case decide as [HφBot |]; [apply top_provable|].
+case decide as [HψTop |]; [apply top_provable|].
+case decide as [HφTop |].
+- apply weak_ImpL.
+  + eapply additive_cut.
+      * apply top_provable.
+      * eapply additive_cut.
+       -- apply obviously_smaller_compatible_GT; apply HφTop.
+       -- apply generalised_axiom.
+  + apply generalised_axiom.
+- case decide as [HψBot |].
+  + apply ImpR. exch 0. apply ImpL.
+      * apply weakening. apply generalised_axiom.
+      * eapply additive_cut with .
+       -- exch 0. apply weakening, obviously_smaller_compatible_LT, HψBot.
+       -- do 2 (exch 0; apply weakening). now apply obviously_smaller_compatible_LT.
+  + apply ImpR. exch 0. apply ImpL.
+      * apply weakening, generalised_axiom.
+      * exch 0. apply weakening, generalised_axiom.
+Qed.
+ +
+Lemma simp_imp_self_equiv_R φ ψ:
+  simp_imp φ ψ φ ψ.
+Proof.
+unfold simp_imp.
+case decide as [Heq |].
+  - apply weakening, ImpR, obviously_smaller_compatible_LT, Heq.
+  - case decide as [HφBot |].
+    + apply weakening.
+      apply ImpR.
+      eapply weak_cut with .
+      * apply obviously_smaller_compatible_LT, HφBot.
+      * apply ExFalso.
+    + case decide as [HψTop |].
+      * apply weakening.
+        apply ImpR.
+        eapply weak_cut.
+        -- apply top_provable.
+        -- apply obviously_smaller_compatible_GT, HψTop.
+      * case decide as [HφTop |].
+        -- apply ImpR. apply weakening, generalised_axiom.
+        -- case decide as [HψBot |].
+           ++ apply ImpR.
+              eapply additive_cut with ψ.
+              ** exch 0. apply weak_ImpL.
+                 --- apply generalised_axiom.
+                 --- apply ExFalso.
+              ** apply generalised_axiom.
+           ++ apply ImpR. exch 0. apply ImpL.
+              ** apply weakening, generalised_axiom.
+              ** exch 0. apply weakening, generalised_axiom.
+Qed.
+ +
+Lemma simp_imps_self_equiv_L φ ψ:
+  (φ ψ) simp_imps φ ψ.
+Proof.
+revert φ; induction ψ; intro φ; unfold simp_imps;
+auto using simp_imp_self_equiv_L.
+fold simp_imps. apply ImpLAnd_rev.
+eapply weak_cut; [| apply IHψ2].
+apply ImpR. exch 0. apply ImpL.
+- apply weakening, simp_ands_self_equiv_R.
+- apply generalised_axiom.
+Qed.
+ +
+Lemma simp_imps_self_equiv_R φ ψ:
+  simp_imps φ ψ (φ ψ).
+Proof.
+revert φ; induction ψ; intro φ; unfold simp_imps;
+auto using simp_imp_self_equiv_R.
+fold simp_imps. apply ImpR, ImpR, AndL_rev, ImpR_rev.
+eapply weak_cut; [apply IHψ2|].
+apply ImpR. exch 0. apply ImpL.
+- apply weakening, simp_ands_self_equiv_L.
+- apply generalised_axiom.
+Qed.
+ +
+Lemma simp_equiv_imp_L φ ψ :
+  (simp φ φ) -> (ψ simp ψ) ->
+  (φ ψ) simp (φ ψ).
+Proof.
+intros HφR HψL.
+simpl.
+eapply weak_cut; [| apply simp_imps_self_equiv_L]. apply ImpR. exch 0.
+apply ImpL.
+- apply weakening. apply HφR.
+- exch 0. apply weakening. apply HψL.
+Qed.
+ +
+Lemma simp_equiv_imp_R φ ψ :
+  (φ simp φ) -> (simp ψ ψ) ->
+  simp (φ ψ) (φ ψ).
+Proof.
+intros HφR HψL.
+simpl.
+eapply weak_cut with (simp φ simp ψ).
+- apply simp_imps_self_equiv_R.
+- apply ImpR. exch 0. apply ImpL.
+  + apply weakening, HφR.
+  + exch 0. apply weakening, HψL.
+Qed.
+ +
+Lemma simp_equiv_imp φ ψ:
+  (φ simp φ) * (simp φ φ) ->
+  (ψ simp ψ) * (simp ψ ψ) ->
+  ((φ ψ) simp (φ ψ)) * (simp (φ ψ) (φ ψ)).
+Proof.
+intros IHφ IHψ.
+split; [ apply simp_equiv_imp_L | apply simp_equiv_imp_R]; try apply IHφ ; try apply IHψ.
+Qed.
+ +
+Lemma box_congr φ ψ:
+  (φ ψ) -> φ ψ.
+Proof.
+intro H.
+apply BoxR.
+box_tac. apply weakening.
+ms.
+Qed.
+ +
+Lemma simp_equiv_box φ:
+  (φ simp φ) * (simp φ φ) ->
+  ( φ (simp φ)) * ( (simp φ) φ).
+Proof.
+intro IHφ.
+split; apply box_congr; apply IHφ.
+Qed.
+ +
+Theorem simp_equiv φ :
+  (φ (simp φ)) * ((simp φ) φ).
+Proof.
+remember (weight φ) as w.
+assert(Hle : weight φ w) by lia.
+clear Heqw. revert φ Hle.
+induction w; intros φ Hle; [destruct φ ; simpl in Hle; lia|];
+destruct φ; simpl; try (split ; apply generalised_axiom);
+[eapply (simp_equiv_and φ1 φ2)|
eapply (simp_equiv_or φ1 φ2)|
eapply (simp_equiv_imp φ1 φ2)|
eapply simp_equiv_box];
apply IHw;
+match goal with
+  | Hle : weight (?connector ?f1 ?f2) S ?w |- weight ?f1 ?w => simpl in Hle; lia
+  | Hle : weight (?connector ?f1 ?f2) S ?w |- weight ?f2 ?w => simpl in Hle; lia
+  | Hle : weight ( ?f1) S ?w |- weight ?f1 ?w => simpl in Hle; lia
+end.
+Qed.
+ +
+Require Import ISL.PropQuantifiers.
+ +
+Definition E_simplified (p: variable) (ψ: form) := simp (E p ([ψ], )).
+Definition A_simplified (p: variable) (ψ: form) := simp (Af p (ψ)).
+ +
+(*
+Lemma bot_vars_incl V: vars_incl ⊥ V.
+Proof.
+  intros x H; unfold In; induction V; auto.
+Qed.
+
+Lemma top_vars_incl V: vars_incl ⊤ V.
+Proof.
+intros x H; unfold In; induction V; simpl in H; tauto | auto.
+Qed.
+
+
+(* Solves simple variable inclusion goals *)
+Ltac vars_incl_tac :=
+repeat match goal with
+| |- vars_incl ⊥ ?V => apply bot_vars_incl
+| |- vars_incl ⊤ ?V => apply top_vars_incl
+
+| H : vars_incl (?connector ?f1 ?f2) ?l |- vars_incl ?f1 ?l * vars_incl ?f2 ?l =>
+        split; intros x H1; apply H; simpl; auto
+| H : vars_incl (?connector ?f1 ?f2) ?l |- vars_incl ?f1 ?l =>
+        intros x H1; apply H; simpl; auto
+| H : vars_incl (?connector ?f1 ?f2) ?l |- vars_incl ?f2 ?l =>
+        intros x H1; apply H; simpl; auto
+
+| H: vars_incl ?f ?l |- vars_incl (_ ?f Bot) ?l =>  unfold vars_incl; simpl; intuition
+| |- (vars_incl ?f1 ?l → vars_incl ?f2 ?l → vars_incl (?connector ?f1 ?f2) ?l) => 
+        unfold vars_incl; simpl; intuition
+| H1: vars_incl ?f1 ?l, H2: vars_incl ?f2 ?l |- vars_incl (?connector ?f1 ?f2) ?l => 
+        unfold vars_incl; simpl; intuition
+
+| |- _ * _  => split; intro| intros
+end.
+
+Lemma or_vars_incl φ ψ V:
+  (vars_incl (Or φ ψ) V -> vars_incl φ V * vars_incl ψ V) *
+  ( vars_incl φ V -> vars_incl ψ V -> vars_incl (Or φ ψ) V).
+Proof. vars_incl_tac. Qed.
+
+
+Lemma vars_incl_choose_disj φ ψ V:
+  vars_incl (Or φ ψ) V -> vars_incl (choose_disj φ ψ) V.
+Proof.
+intros H.
+unfold choose_disj.
+destruct (obviously_smaller φ ψ); vars_incl_tac.
+destruct (obviously_smaller ψ φ); vars_incl_tac. assumption.
+Qed.
+
+Lemma vars_incl_make_disj_equiv_disj φ ψ V:
+  vars_incl (Or φ ψ) V -> vars_incl (φ ⊻ ψ) V.
+Proof.
+intros H.
+unfold make_disj.
+destruct ψ; try (now apply vars_incl_choose_disj);
+repeat case decide; intros; try assumption; vars_incl_tac.
+- now apply vars_incl_choose_disj.
+- apply or_vars_incl in H.  case obviously_smaller; vars_tac; firstorder.
+Qed.
+
+Lemma vars_incl_simp_ors φ ψ V :
+  vars_incl φ V -> vars_incl ψ V -> vars_incl (simp_ors φ ψ) V.
+Proof.
+generalize ψ.
+induction φ; intro ψ0; destruct ψ0; intros Hφ Hψ;
+try ( apply vars_incl_make_disj_equiv_disj; apply or_vars_incl; assumption).
+simpl.
+apply vars_incl_make_disj_equiv_disj.
+apply or_vars_incl.
+- now apply (or_vars_incl _ φ2 _). 
+- apply vars_incl_make_disj_equiv_disj.
+  apply or_vars_incl.
+  + now apply (or_vars_incl _ ψ0_2 _). 
+  +  apply IHφ2.
+    * now apply (or_vars_incl  φ1 _ _). 
+    * now apply (or_vars_incl  ψ0_1 _ _). 
+Qed.
+
+
+Lemma and_vars_incl φ ψ V:
+  (vars_incl (And φ ψ) V -> vars_incl φ V * vars_incl ψ V) *
+  (vars_incl φ V -> vars_incl ψ V -> vars_incl (And φ ψ) V).
+Proof. vars_incl_tac. Qed.
+
+
+Lemma vars_incl_choose_conj φ ψ V:
+  vars_incl (And φ ψ) V -> vars_incl (choose_conj φ ψ) V.
+Proof.
+intros H.
+unfold choose_conj. 
+destruct (obviously_smaller φ ψ); vars_incl_tac; assumption.
+Qed.
+
+
+Lemma vars_incl_make_conj_equiv_conj φ ψ V:
+  vars_incl (And φ ψ) V -> vars_incl (φ ⊼ ψ) V.
+Proof.
+intros H.
+unfold make_conj.
+destruct ψ; try (now apply vars_incl_choose_conj);
+match goal with |- vars_incl match ?a with _ => _ end _ => destruct a end;
+repeat case decide; intros; try discriminate; try assumption; vars_incl_tac;
+try apply vars_incl_choose_conj; apply and_vars_incl;
+vars_incl_tac; apply and_vars_incl in H; vars_tac; vars_incl_tac.
+Qed.
+
+Lemma vars_incl_simp_ands φ ψ V :
+  vars_incl φ V -> vars_incl ψ V -> vars_incl (simp_ands φ ψ) V.
+Proof.
+generalize ψ.
+induction φ; intro ψ0; destruct ψ0; intros Hφ Hψ;
+try (apply vars_incl_make_conj_equiv_conj; apply and_vars_incl; assumption).
+simpl.
+apply vars_incl_make_conj_equiv_conj.
+apply and_vars_incl.
+- vars_incl_tac.
+- apply vars_incl_make_conj_equiv_conj. 
+  apply and_vars_incl.
+  + vars_incl_tac.
+  + apply IHφ2; vars_incl_tac.
+Qed.
+
+Lemma vars_incl_simp_imp φ ψ V :
+  vars_incl φ V -> vars_incl ψ V -> vars_incl (simp_imp φ ψ) V.
+Proof.
+intros Hφ Hψ.
+simpl. unfold simp_imp. 
+case decide as .
+  + vars_incl_tac.
+  + case decide as .
+    * vars_incl_tac.
+    * case decide as .
+      -- vars_incl_tac.
+      -- case decide as .
+         ++ assumption.
+         ++ case decide as ; vars_incl_tac.
+Qed.
+
+Lemma vars_incl_simp_imps φ ψ V :
+  vars_incl φ V -> vars_incl ψ V -> vars_incl (simp_imps φ ψ) V.
+Proof.
+revert φ; induction ψ; intros φ Hφ Hψ; simpl;
+try apply vars_incl_simp_imp; trivial.
+apply IHψ2.
+- apply vars_incl_simp_ands; trivial.
+  intros ? ?; apply Hψ; simpl; tauto.
+-   intros ? ?; apply Hψ; simpl; tauto.
+Qed.
+
+Lemma vars_incl_simp φ V :
+  vars_incl φ V -> vars_incl (simp φ) V.
+Proof.
+intro H.
+induction φ; auto; simpl;
+ apply vars_incl_simp_ands; [apply IHφ1| apply IHφ2]| + apply vars_incl_simp_ors; [apply IHφ1| apply IHφ2]| + apply vars_incl_simp_imps; [apply IHφ1| apply IHφ2] +; vars_incl_tac.
+Qed.
+
+
+Lemma preorder_singleton  φ ψ:
+  {φ} ⊢ ψ -> (φ ≼ ψ).
+Proof.
+intro H.
+assert (H': ∅ • φ ⊢ ψ ) by peapply H.
+apply H'.
+Qed.
+
+Theorem iSL_uniform_interpolation_simp p V: p ∉ V ->
+  ∀ φ, vars_incl φ (p :: V) ->
+  (vars_incl (E_simplified p φ) V)
+  * (φ ≼ E_simplified p φ)
+  * (∀ ψ, vars_incl ψ V -> (φ ≼ ψ) -> E_simplified p φ ≼ ψ)
+  * (vars_incl (A_simplified p φ) V)
+  * (A_simplified p φ ≼ φ)
+  * (∀ θ, vars_incl θ V -> (θ ≼ φ) -> (θ ≼ A_simplified p φ)).
+Proof.
+intros Hp φ Hvarsφ.
+assert (Hislφ : 
+    (vars_incl (Ef p φ) V)
+  * ({φ} ⊢ (Ef p φ))
+  * (∀ ψ, vars_incl ψ V -> {φ} ⊢ ψ -> {Ef p φ} ⊢ ψ)
+  * (vars_incl (Af p φ) V)
+  * ({Af p φ} ⊢ φ)
+  * (∀ θ, vars_incl θ V -> {θ} ⊢ φ -> {θ} ⊢ Af p φ)) by 
+    (apply iSL_uniform_interpolation; apply Hp | apply Hvarsφ).
+repeat split.
+  + intros Hx.
+    eapply vars_incl_simp.
+    apply Hislφ.
+  + eapply weak_cut.
+    * assert (Hef: ({φ} ⊢ Ef p φ)) by apply Hislφ.
+      apply preorder_singleton.
+      apply Hef.
+    * apply (simp_equiv  (Ef p φ)).
+  + intros ψ Hψ Hyp.
+    eapply weak_cut.
+    * apply (simp_equiv  (Ef p φ)).
+    * assert (Hef: ({Ef p φ} ⊢ ψ)) by (apply Hislφ; apply Hψ | peapply Hyp).
+      apply preorder_singleton.
+      apply Hef.
+  + intros Hx.
+    eapply vars_incl_simp.
+    apply Hislφ.
+  + eapply weak_cut.
+    * apply (simp_equiv  (Af p φ)).
+    * apply preorder_singleton.
+      apply Hislφ.
+  + intros ψ Hψ Hyp.
+    eapply weak_cut.
+    * assert (Hef: ({ψ} ⊢ Af p φ)) by (apply Hislφ; apply Hψ | peapply Hyp).
+      apply preorder_singleton.
+      apply Hef.
+    * apply (simp_equiv  (Af p φ)).
+Qed.
+*)

+ +
+Require Import String.
+Local Open Scope string_scope.
+ +
+Example ex1: simp (Implies (Var "a") (And (Var "b") (Var "b" ))) = Implies (Var "a") (Var "b").
+Proof. reflexivity. Qed.
+ +
+Example ex2: simp (Implies (Var "a") (Or (Var "b") (Var "b" ))) = Implies (Var "a") (Var "b").
+Proof. reflexivity. Qed.
+ +
+Example ex3: simp (Implies (Var "a") (Var "a")) = Implies Bot Bot.
+Proof. reflexivity. Qed.
+ +
+Example ex4: simp (Or (Implies (Var "a") (Var "a")) (Implies (Var "a") (Var "a"))) = Implies Bot Bot.
+Proof. reflexivity. Qed.
+ +
+Example ex5: simp (And (Implies (Var "a") (Var "a")) (Implies (Var "a") (Var "a"))) = Implies Bot Bot.
+Proof. reflexivity. Qed.
+ +
+Example ex6: simp (Or (And (Var "a") (Var "b")))= (And (Var "a") (Var "b")).
+Proof. reflexivity. Qed.
+
+
+ +
+ + + diff --git a/K.Interpolation.K_Craig_Interp.html b/K.Interpolation.K_Craig_Interp.html new file mode 100644 index 0000000..d5967ff --- /dev/null +++ b/K.Interpolation.K_Craig_Interp.html @@ -0,0 +1,644 @@ + + + + + + + + + + + + + +
+
+

K.Interpolation.K_Craig_Interp

+ +
+(* It took me a day and a half of work to write the file below
+    (14-15/11/2022). *)

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat Arith.
+Require Import Lia.
+ +
+Require Import KS_export.
+Require Import general_export.
+ +
+Set Implicit Arguments.
+ +
+(* Material to define Craig interpolants. *)
+ +
+Fixpoint propvar_subform (φ : MPropF) : list MPropF :=
+match φ with
+  | Var p => (Var p) :: nil
+  | Bot => nil
+  | Imp ψ χ => (propvar_subform ψ) ++ ( propvar_subform χ)
+  | Box ψ => ( propvar_subform ψ)
+end.
+ +
+Fixpoint propvar_subform_list (l : list MPropF) : list MPropF :=
+match l with
+  | nil => nil
+  | φ :: t => (propvar_subform φ) ++ (propvar_subform_list t)
+end.
+ +
+(* Lemmas about propvar_subform_list. *)
+ +
+Lemma propvar_subform_list_app: forall l0 l1,
+      propvar_subform_list (l0 ++ l1) = (propvar_subform_list l0) ++ (propvar_subform_list l1).
+Proof.
+induction l0.
+- simpl. auto.
+- intros. simpl. rewrite (IHl0). rewrite <- app_assoc ; auto.
+Qed.
+ +
+Lemma propvar_subform_list_unboxed_list : forall l A, In A (propvar_subform_list (unboxed_list l)) -> In A (propvar_subform_list l).
+Proof.
+induction l.
+- auto.
+- simpl. intros. apply in_app_or in H. destruct H. apply in_or_app ; left. destruct a ; auto.
+  apply in_or_app ; auto.
+Qed.
+ +
+Lemma propvar_subform_list_nobox_gen_ext : forall l0 l1, nobox_gen_ext l0 l1 ->
+          (forall A, In A (propvar_subform_list l0) -> In A (propvar_subform_list l1)).
+Proof.
+intros l0 l1 H. induction H ; auto.
+- simpl ; intros. apply in_or_app. apply in_app_or in H0 ; destruct H0 ; auto.
+- simpl ; intros. apply in_or_app ; auto.
+Qed.
+ +
+Lemma InT_var_provar : forall P Γ, InT # P Γ -> InT # P (propvar_subform_list Γ).
+Proof.
+induction Γ ; auto. intro. simpl. inversion H ; subst ; simpl. apply InT_eq.
+apply InT_or_app ; right. auto.
+Qed.
+ +
+(* Craig interpolation theorem. *)
+ +
+Theorem Craig_Interpolation : forall Γ0 Γ1 Δ0 Δ1,
+    KS_prv (Γ0 ++ Γ1, Δ0 ++ Δ1) ->
+    (existsT2 (I : MPropF), (forall p, In (Var p) (propvar_subform I) -> In (Var p) (propvar_subform_list (Γ0 ++ Δ0)) *
+                                                                                                            In (Var p) (propvar_subform_list (Γ1 ++ Δ1))) *
+                                   (KS_prv (Γ0, I :: Δ0)) *
+                                   (KS_prv (I :: Γ1, Δ1))).
+Proof.
+(* Setting the statement right. *)
+intros. remember (Γ0 ++ Γ1, Δ0 ++ Δ1) as s. revert Heqs.
+generalize dependent Γ0. generalize dependent Γ1. generalize dependent Δ0. generalize dependent Δ1.
+remember (derrec_height X) as n. revert Heqn. generalize dependent X. generalize dependent s.
+generalize dependent n.
+(* Using strong induction. *)
+pose ((well_founded_induction_type lt_wf) (fun (x:nat) => forall (s : list MPropF * list MPropF) (X : KS_prv s),
+x = derrec_height X ->
+forall Δ1 Δ0 Γ1 Γ0 : list MPropF,
+s = (Γ0 ++ Γ1, Δ0 ++ Δ1) ->
+existsT2 I : MPropF,
+  (forall p, In # p (propvar_subform I) -> In (Var p) (propvar_subform_list (Γ0 ++ Δ0)) *
+                                                                                                            In (Var p) (propvar_subform_list (Γ1 ++ Δ1))) * KS_prv (Γ0, I :: Δ0) *
+  KS_prv (I :: Γ1, Δ1))).
+apply s. clear s.
+(* Start of the intuitive proof. *)
+unfold KS_prv. intros n IHn s D. subst. remember D as D'. destruct D ; intros.
+(* D0 is a leaf *)
+- inversion f.
+(* D0 ends with an application of rule *)
+- inversion k.
+  (* IdP *)
+  * inversion H1. subst. inversion H5 ; subst. assert (J: InT (# P) (Γ0 ++ Γ1)). rewrite <- H0.
+    apply InT_or_app ; right ; apply InT_eq. apply InT_app_or in J. destruct J.
+    + assert (J: InT (# P) (Δ0 ++ Δ1)). rewrite <- H2.
+       apply InT_or_app ; right ; apply InT_eq. apply InT_app_or in J. destruct J.
+       -- exists (Bot). repeat split. intros. 1,2: inversion H.
+           apply derI with (ps:=[]). 2: apply dersrec_nil. apply IdP.
+           apply InT_split in i. destruct i. destruct s. subst.
+           assert (J: InT # P (Bot :: Δ0)). apply InT_cons. auto.
+           apply InT_split in J. destruct J. destruct s. rewrite e. apply IdPRule_I.
+           apply derI with (ps:=[]). 2: apply dersrec_nil. apply BotL. apply (BotLRule_I []).
+       -- exists (# P). repeat split. intros. 1,2: simpl in H ; destruct H ; auto ; try rewrite <- H. 2, 4: inversion H.
+           1-2: repeat rewrite propvar_subform_list_app ; apply in_or_app. left ; apply InT_In ; apply InT_var_provar ; auto.
+           right ; apply InT_In ; apply InT_var_provar ; auto.
+           apply derI with (ps:=[]). 2: apply dersrec_nil. apply IdP.
+           apply InT_split in i. destruct i. destruct s. subst.
+           assert (J: # P :: Δ0 = [] ++ # P :: Δ0). auto. rewrite J. clear J. apply IdPRule_I.
+           apply derI with (ps:=[]). 2: apply dersrec_nil. apply IdP.
+           apply InT_split in i0. destruct i0. destruct s. subst.
+           assert (J: # P :: Γ1 = [] ++ # P :: Γ1). auto. rewrite J. clear J. apply IdPRule_I.
+    + assert (J: InT (# P) (Δ0 ++ Δ1)). rewrite <- H2.
+       apply InT_or_app ; right ; apply InT_eq. apply InT_app_or in J. destruct J.
+       -- exists (# P --> Bot). repeat split.
+           1,2: simpl in H ; destruct H ; auto ; try rewrite <- H. 2, 4: inversion H.
+           1-2: repeat rewrite propvar_subform_list_app ; apply in_or_app. right ; apply InT_In ; apply InT_var_provar ; auto.
+           left ; apply InT_In ; apply InT_var_provar ; auto.
+           apply derI with (ps:=[([] ++ # P :: Γ0, [] ++ Bot :: Δ0)]). apply ImpR.
+           assert (J: (Γ0, # P --> Bot :: Δ0) = ([] ++ Γ0, [] ++ # P --> Bot :: Δ0)). auto. rewrite J. clear J. apply ImpRRule_I.
+           apply dlCons. 2: apply dlNil. apply derI with (ps:=[]). 2: apply dersrec_nil. apply IdP.
+           assert (J: InT # P ([] ++ Bot :: Δ0)). apply InT_cons. auto. apply InT_split in J. destruct J. destruct s.
+           rewrite e. apply IdPRule_I.
+           apply derI with (ps:=[([] ++ Γ1, [] ++ # P :: Δ1);([] ++ Bot :: Γ1, [] ++ Δ1)]). apply ImpL.
+           assert (J: (# P --> Bot :: Γ1, Δ1) = ([] ++ # P --> Bot :: Γ1, [] ++ Δ1)). auto. rewrite J. clear J. apply ImpLRule_I.
+           apply dlCons. apply derI with (ps:=[]). 2: apply dlNil. apply IdP.
+           assert (J: InT # P ([] ++ Γ1)). simpl ; auto. apply InT_split in J. destruct J. destruct s.
+           rewrite e. apply IdPRule_I. apply dlCons. 2: apply dlNil. apply derI with (ps:=[]). 2: apply dlNil. apply BotL.
+           apply BotLRule_I.
+       -- exists (Bot --> Bot). repeat split. intros. 1,2: inversion H.
+           apply derI with (ps:=[([] ++ Bot :: Γ0, [] ++ Bot :: Δ0)]). apply ImpR.
+           assert ((Γ0, Bot --> Bot :: Δ0) = ([] ++ Γ0, [] ++ Bot --> Bot :: Δ0)). auto. rewrite H. clear H.
+           apply ImpRRule_I. apply dlCons. 2: apply dlNil. apply derI with (ps:=[]). apply BotL.
+           apply BotLRule_I. apply dlNil.
+           apply derI with (ps:=[]). 2: apply dersrec_nil. apply IdP.
+           assert (J: InT # P (Bot --> Bot :: Γ1)). apply InT_cons. auto.
+           apply InT_split in J. destruct J. destruct s. rewrite e.
+           apply InT_split in i0. destruct i0. destruct s. subst. apply IdPRule_I.
+  (* BotL *)
+  * inversion H1. subst. assert (J: InT Bot (Γ0 ++ Γ1)). inversion H5 ; subst.
+    apply InT_or_app ; right ; apply InT_eq. apply InT_app_or in J. destruct J.
+    + exists Bot. repeat split. intros. 1,2: inversion H.
+       apply derI with (ps:=[]). apply BotL. 2: apply dlNil.
+       apply InT_split in i. destruct i. destruct s. subst. apply BotLRule_I.
+       apply derI with (ps:=[]). apply BotL. 2: apply dlNil.
+       assert (J: (Bot :: Γ1, Δ1) = ([] ++ Bot :: Γ1, Δ1)). auto. rewrite J. apply BotLRule_I.
+    + exists (Bot --> Bot). repeat split. intros. 1,2: inversion H.
+       apply derI with (ps:=[([] ++ Bot :: Γ0, [] ++ Bot :: Δ0)]). apply ImpR.
+       assert ((Γ0, Bot --> Bot :: Δ0) = ([] ++ Γ0, [] ++ Bot --> Bot :: Δ0)). auto. rewrite H. clear H.
+       apply ImpRRule_I. apply dlCons. 2: apply dlNil. apply derI with (ps:=[]). apply BotL.
+       apply BotLRule_I. apply dlNil.
+       apply derI with (ps:=[]). apply BotL. 2: apply dlNil.
+       assert (J: InT Bot (Bot --> Bot :: Γ1)). apply InT_cons ; auto.
+       apply InT_split in J. destruct J. destruct s. rewrite e. apply BotLRule_I.
+  (* ImpR *)
+  * inversion H1. subst. inversion H5 ; subst. simpl in IHn.
+    assert (J: dersrec_height d = dersrec_height d). auto. apply dersrec_derrec_height in J.
+    destruct J.
+    assert (J1: derrec_height x = derrec_height x). auto.
+    assert (J3: list_exch_L (Γ2 ++ A :: Γ3, Δ2 ++ B :: Δ3) (A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ3)).
+    rewrite <- H0. assert (Γ2 ++ A :: Γ3 = [] ++ [] ++ Γ2 ++ [A] ++ Γ3). auto. rewrite H.
+    assert (A :: Γ2 ++ Γ3 = [] ++ [A] ++ Γ2 ++ [] ++ Γ3). auto. rewrite H3. apply list_exch_LI.
+    pose (KS_hpadm_list_exch_L _ x _ J3). destruct s.
+    assert (J5: derrec_height x0 = derrec_height x0). auto.
+    assert (J4: list_exch_L (A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ3) (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ3)).
+    assert (Γ0 ++ A :: Γ1 = [] ++ [] ++ Γ0 ++ [A] ++ Γ1). auto. rewrite H.
+    assert (A :: Γ0 ++ Γ1 = [] ++ [A] ++ Γ0 ++ [] ++ Γ1). auto. rewrite H3. apply list_exch_LI.
+    pose (KS_hpadm_list_exch_L _ x0 _ J4). destruct s.
+    assert (J0: derrec_height x1 < S (dersrec_height d)). rewrite <- e. apply PeanoNat.le_lt_n_Sm.
+    apply (Nat.le_trans _ _ _ l0 l).
+    assert (J6: derrec_height x1 = derrec_height x1). auto.
+    pose (IHn _ J0 _ _ J6).
+    apply app2_find_hole in H2. destruct H2. repeat destruct s0 ; destruct p ; subst.
+    + assert (J2: (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ3) = (Γ0 ++ (A :: Γ1), Δ2 ++ (B :: Δ3))). auto.
+        apply s in J2. destruct J2. destruct p. destruct p. exists x3. repeat split ; auto.
+        intros. apply p in H. repeat rewrite propvar_subform_list_app in H. simpl in H.
+        repeat rewrite propvar_subform_list_app. repeat rewrite <- app_assoc in H. simpl. destruct H.
+        apply in_app_or in i. destruct i. apply in_or_app ; auto. apply in_or_app ; auto.
+        apply p in H. repeat rewrite propvar_subform_list_app in H. simpl in H.
+        repeat rewrite propvar_subform_list_app. repeat rewrite <- app_assoc in H. simpl. destruct H.
+        apply in_app_or in i0. destruct i0. apply in_or_app ; right ; apply in_or_app ; left ; apply in_or_app ; auto.
+        apply in_app_or in H. destruct H. apply in_or_app ; auto.
+        apply in_app_or in H. destruct H. apply in_or_app ; right ; apply in_or_app ; left ; apply in_or_app ; auto.
+        apply in_or_app ; right ; apply in_or_app ; auto.
+        apply derI with (ps:=[(x3 :: A :: Γ1, B :: Δ3)]). apply ImpR.
+        assert ((x3 :: Γ1, A --> B :: Δ3) = ([x3] ++ Γ1, [] ++ A --> B :: Δ3)). auto. rewrite H.
+        assert ((x3 :: A :: Γ1, B :: Δ3) = ([x3] ++ A :: Γ1, [] ++ B :: Δ3)). auto. rewrite H2. apply ImpRRule_I.
+        apply dlCons ; auto. apply dlNil.
+    + destruct x2 ; subst.
+        -- simpl in e1. subst. rewrite app_nil_r.
+            assert (J2: (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ3) = (Γ0 ++ (A :: Γ1), Δ2 ++ (B :: Δ3))). auto.
+            apply s in J2. destruct J2. destruct p. destruct p. exists x2. repeat split ; auto.
+            intros. apply p in H. repeat rewrite propvar_subform_list_app in H. simpl in H. repeat rewrite <- app_assoc in H.
+            repeat rewrite propvar_subform_list_app. simpl. destruct H. auto.
+            apply p in H. repeat rewrite propvar_subform_list_app in H. simpl in H. repeat rewrite <- app_assoc in H.
+            repeat rewrite propvar_subform_list_app. simpl. destruct H.
+            apply in_app_or in i0. destruct i0. apply in_or_app ; right ; apply in_or_app ; left ; apply in_or_app ; auto.
+            apply in_app_or in H ; destruct H. apply in_or_app ; auto. apply in_app_or in H ; destruct H.
+            apply in_or_app ; right ; apply in_or_app ; left ; apply in_or_app ; auto.
+            apply in_or_app ; right ; apply in_or_app ; right ; auto.
+            apply derI with (ps:=[(x2 :: A :: Γ1, B :: Δ3)]). apply ImpR.
+            assert ((x2 :: Γ1, A --> B :: Δ3) = ([x2] ++ Γ1, [] ++ A --> B :: Δ3)). auto. rewrite H.
+            assert ((x2 :: A :: Γ1, B :: Δ3) = ([x2] ++ A :: Γ1, [] ++ B :: Δ3)). auto. rewrite H2. apply ImpRRule_I.
+            apply dlCons ; auto. apply dlNil.
+        -- inversion e1. subst.
+            assert (J2: (Γ0 ++ A :: Γ1, Δ2 ++ B :: x2 ++ Δ1) = ((Γ0 ++ [A]) ++ Γ1, (Δ2 ++ B :: x2) ++ Δ1)).
+            repeat rewrite <- app_assoc ; auto.
+            apply s in J2. destruct J2. destruct p. destruct p. exists x3. repeat split ; auto.
+            intros. apply p in H. simpl in H. repeat rewrite <- app_assoc in H ; simpl in H.
+            repeat rewrite propvar_subform_list_app in H. simpl in H. repeat rewrite propvar_subform_list_app in H. simpl in H.
+            destruct H.
+            repeat rewrite propvar_subform_list_app. simpl. repeat rewrite propvar_subform_list_app. simpl.
+            apply in_app_or in i. destruct i. apply in_or_app ; auto. apply in_app_or in H ; destruct H.
+            apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; left ; apply in_or_app ; auto.
+            apply in_app_or in H ; destruct H. apply in_or_app ; right ; apply in_or_app ; auto.
+            apply in_app_or in H ; destruct H. apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; left ; apply in_or_app ; auto.
+            apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+            intros. apply p in H. simpl in H. repeat rewrite <- app_assoc in H ; simpl in H.
+            repeat rewrite propvar_subform_list_app in H. simpl in H. repeat rewrite propvar_subform_list_app in H. simpl in H.
+            destruct H. repeat rewrite propvar_subform_list_app.
+            apply in_app_or in i0. destruct i0. 1-2: apply in_or_app ; auto.
+            apply derI with (ps:=[(Γ0 ++ A :: [], (x3 :: Δ2) ++ B :: x2)]). apply ImpR.
+            assert ((Γ0, x3 :: Δ2 ++ A --> B :: x2) = (Γ0 ++ [], (x3 :: Δ2) ++ A --> B :: x2)). rewrite app_nil_r. auto.
+            rewrite H. apply ImpRRule_I. apply dlCons ; auto. apply dlNil.
+    + assert (J2: (Γ0 ++ A :: Γ1, (Δ0 ++ x2) ++ B :: Δ3) = (Γ0 ++ (A :: Γ1), Δ0 ++ (x2)++ B :: Δ3)). repeat rewrite <- app_assoc. auto.
+        apply s in J2. destruct J2. destruct p. destruct p. exists x3. repeat split ; auto.
+        intros. 1,2: apply p in H ; simpl in H ; repeat rewrite <- app_assoc in H ; simpl in H ;
+        repeat rewrite propvar_subform_list_app in H ; simpl in H ; repeat rewrite propvar_subform_list_app in H ; simpl in H ;
+        destruct H ; repeat rewrite propvar_subform_list_app ; simpl ; repeat rewrite propvar_subform_list_app ; simpl.
+        apply in_app_or in i. destruct i. 1,2: apply in_or_app ; auto.
+        apply in_app_or in i0. destruct i0. apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; left ; apply in_or_app ; auto.
+        apply in_app_or in H ; destruct H. apply in_or_app ; auto. apply in_app_or in H ; destruct H.
+        apply in_or_app ; right ; apply in_or_app ; auto. apply in_app_or in H ; destruct H.
+        apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; left ; apply in_or_app ; auto.
+        apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; right ; auto.
+        apply derI with (ps:=[(x3 :: A :: Γ1, x2 ++ B :: Δ3)]). apply ImpR.
+        assert ((x3 :: Γ1, x2 ++ A --> B :: Δ3) = ([x3] ++ Γ1, x2 ++ A --> B :: Δ3)). auto. rewrite H.
+        assert ((x3 :: A :: Γ1, x2 ++ B :: Δ3) = ([x3] ++ A :: Γ1, x2 ++ B :: Δ3)). auto. rewrite H2. apply ImpRRule_I.
+        apply dlCons ; auto. apply dlNil.
+  (* ImpL *)
+  * inversion H1. subst. inversion H5 ; subst. simpl in IHn.
+    assert (J: dersrec_height d = dersrec_height d). auto. apply dersrec_derrec2_height in J.
+    destruct J. destruct s.
+    assert (J1: derrec_height x = derrec_height x). auto.
+    assert (J3: list_exch_R (Γ2 ++ Γ3, Δ2 ++ A :: Δ3) (Γ2 ++ Γ3, A :: Δ0 ++ Δ1)).
+    rewrite <- H2. assert (Δ2 ++ A :: Δ3 = [] ++ [] ++ Δ2 ++ [A] ++ Δ3). auto. rewrite H.
+    assert (A :: Δ2 ++ Δ3 = [] ++ [A] ++ Δ2 ++ [] ++ Δ3). auto. rewrite H3. apply list_exch_RI.
+    pose (KS_hpadm_list_exch_R _ x _ J3). destruct s.
+    assert (J5: derrec_height x1 = derrec_height x1). auto.
+    assert (J4: list_exch_R (Γ2 ++ Γ3, A :: Δ0 ++ Δ1) (Γ2 ++ Γ3, Δ0 ++ A :: Δ1)).
+    assert (Δ0 ++ A :: Δ1 = [] ++ [] ++ Δ0 ++ [A] ++ Δ1). auto. rewrite H.
+    assert (A :: Δ0 ++ Δ1 = [] ++ [A] ++ Δ0 ++ [] ++ Δ1). auto. rewrite H3. apply list_exch_RI.
+    pose (KS_hpadm_list_exch_R _ x1 _ J4). destruct s.
+    assert (existsT2 (x3 : derrec KS_rules (fun _ : Seq => False) (Γ2 ++ B :: Γ3, Δ0 ++ Δ1)), derrec_height x3 <= dersrec_height d).
+    rewrite <- H2. exists x0 ; auto. rewrite e. apply Nat.le_max_r. destruct X.
+    apply app2_find_hole in H0. destruct H0. repeat destruct s ; destruct p ; subst.
+    + assert (J11: derrec_height x2 < S (dersrec_height d)). rewrite e. apply PeanoNat.le_lt_n_Sm.
+        apply Nat.max_le_iff. left. apply (Nat.le_trans _ _ _ l0 l).
+        assert (J12: derrec_height x2 = derrec_height x2). auto.
+        pose (IHn _ J11 _ _ J12).
+        assert (J2: (Γ2 ++ Γ3, Δ0 ++ A :: Δ1) = (Γ2 ++ Γ3, Δ0 ++ A :: Δ1)). auto.
+        apply s in J2. destruct J2. destruct p. destruct p.
+        assert (J13: derrec_height x3 < S (dersrec_height d)). lia.
+        assert (J14: derrec_height x3 = derrec_height x3). auto.
+        pose (IHn _ J13 _ _ J14).
+        assert (J2: (Γ2 ++ B :: Γ3, Δ0 ++ Δ1) = (Γ2 ++ B :: Γ3, Δ0 ++ Δ1)). auto.
+        apply s0 in J2. destruct J2. destruct p0. destruct p0.
+        exists ((x5 --> (x6 --> Bot)) --> Bot). repeat split.
+        intros. 1,2: simpl in H ; repeat rewrite app_nil_r in H ; repeat rewrite propvar_subform_list_app ; simpl ;
+        repeat rewrite <- app_assoc ; apply in_app_or in H ; destruct H.
+        apply p in H ; repeat rewrite propvar_subform_list_app in H ; simpl in H ; destruct H ; auto.
+        apply p0 in H ; repeat rewrite propvar_subform_list_app in H ; simpl in H ; repeat rewrite <- app_assoc in H ; destruct H ; auto.
+        apply p in H ; repeat rewrite propvar_subform_list_app in H ; simpl in H ; destruct H ; auto.
+        apply in_app_or in i0 ; destruct i0. apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+        apply in_app_or in H ; destruct H. apply in_or_app ; auto.
+        apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; right ; auto.
+        apply p0 in H ; repeat rewrite propvar_subform_list_app in H ; simpl in H ; repeat rewrite <- app_assoc in H ; destruct H ; auto.
+        apply in_app_or in i0 ; destruct i0. apply in_or_app ; right ; apply in_or_app ; auto.
+        apply in_app_or in H ; destruct H. 1,2: apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+        apply derI with (ps:=[([] ++ (x5 --> x6 --> Bot) :: Γ2, [] ++ Bot :: Δ0)]). apply ImpR.
+        assert ((Γ2, (x5 --> x6 --> Bot) --> Bot :: Δ0) = ([] ++ Γ2, [] ++ (x5 --> x6 --> Bot) --> Bot :: Δ0)). auto. rewrite H. apply ImpRRule_I.
+        apply dlCons. 2: apply dlNil.
+        apply derI with (ps:=[([] ++ Γ2, [] ++ x5 :: Bot :: Δ0);([] ++ x6 --> Bot :: Γ2, [] ++ Bot :: Δ0)]). apply ImpL. apply ImpLRule_I.
+        apply dlCons. simpl.
+        assert (J15: derrec_height d1 = derrec_height d1). auto.
+        assert (J16: wkn_R Bot (Γ2, [x5] ++ Δ0) (Γ2, [x5] ++ Bot :: Δ0)). apply wkn_RI. simpl in J16.
+        pose (KS_wkn_R _ _ d1 J15 _ _ J16). destruct s1 ; auto. apply dlCons. 2: apply dlNil.
+        apply derI with (ps:=[([] ++ Γ2, [] ++ x6 :: Bot :: Δ0);([] ++ Bot :: Γ2, [] ++ Bot :: Δ0)]). apply ImpL. apply ImpLRule_I.
+        apply dlCons. simpl.
+        assert (J15: derrec_height d3 = derrec_height d3). auto.
+        assert (J16: wkn_R Bot (Γ2, [x6] ++ Δ0) (Γ2, [x6] ++ Bot :: Δ0)). apply wkn_RI. simpl in J16.
+        pose (KS_wkn_R _ _ d3 J15 _ _ J16). destruct s1 ; auto.
+        apply dlCons. 2: apply dlNil. apply derI with (ps:=[]). apply BotL. apply BotLRule_I. apply dlNil.
+        apply derI with (ps:=[([] ++ A --> B :: Γ3, [] ++ (x5 --> x6 --> Bot) :: Δ1);([] ++ Bot :: A --> B :: Γ3, [] ++ Δ1)]).
+        assert (((x5 --> x6 --> Bot) --> Bot :: A --> B :: Γ3, Δ1) = ([] ++ (x5 --> x6 --> Bot) --> Bot :: A --> B :: Γ3, [] ++ Δ1)). auto.
+        rewrite H. apply ImpL. apply ImpLRule_I. apply dlCons.
+        apply derI with (ps:=[([] ++ x5 :: A --> B :: Γ3, [] ++ x6 --> Bot :: Δ1)]). apply ImpR. apply ImpRRule_I. apply dlCons.
+        apply derI with (ps:=[([x5] ++ Γ3, [] ++ A :: x6 --> Bot :: Δ1);([x5] ++ B :: Γ3, [] ++ x6 --> Bot :: Δ1)]).
+        assert (([] ++ x5 :: A --> B :: Γ3, [] ++ x6 --> Bot :: Δ1) = ([x5] ++ A --> B :: Γ3, [] ++ x6 --> Bot :: Δ1)). auto.
+        rewrite H. apply ImpL. apply ImpLRule_I. apply dlCons. 3: apply dlNil.
+        assert (J15: derrec_height d0 = derrec_height d0). auto. simpl.
+        assert (J16: wkn_R (x6 --> Bot) (x5 :: Γ3, [A]++ Δ1) (x5 :: Γ3, [A] ++ x6 --> Bot :: Δ1)). apply wkn_RI. simpl in J16.
+        pose (KS_wkn_R _ _ d0 J15 _ _ J16). destruct s1 ; auto. apply dlCons. 2: apply dlNil.
+        apply derI with (ps:=[([x5] ++ x6 :: B :: Γ3, [] ++ Bot :: Δ1)]). apply ImpR. apply ImpRRule_I. apply dlCons.
+        assert (J15: derrec_height d2 = derrec_height d2). auto. simpl.
+        assert (J16: wkn_R Bot (x6 :: B :: Γ3, [] ++ Δ1) (x6 :: B :: Γ3, [] ++ Bot :: Δ1)). apply wkn_RI. simpl in J16.
+        pose (KS_wkn_R _ _ d2 J15 _ _ J16). destruct s1.
+        assert (J17: derrec_height x7 = derrec_height x7). auto. simpl.
+        assert (J18: wkn_L x5 ([] ++ x6 :: B :: Γ3, Bot :: Δ1) ([] ++ x5 :: x6 :: B :: Γ3, Bot :: Δ1)). apply wkn_LI. simpl in J18.
+        pose (KS_wkn_L _ _ x7 J17 _ _ J18). destruct s1. auto. apply dlNil. apply dlCons. 2: apply dlNil.
+        apply derI with (ps:=[]). apply BotL. apply BotLRule_I. apply dlNil.
+    + destruct x4.
+      -- simpl. repeat rewrite app_nil_r. simpl in e1. subst.
+          assert (J11: derrec_height x2 < S (dersrec_height d)). rewrite e. apply PeanoNat.le_lt_n_Sm.
+          apply Nat.max_le_iff. left. apply (Nat.le_trans _ _ _ l0 l).
+          assert (J12: derrec_height x2 = derrec_height x2). auto.
+          pose (IHn _ J11 _ _ J12).
+          assert (J2: (Γ2 ++ Γ3, Δ0 ++ A :: Δ1) = (Γ2 ++ Γ3, Δ0 ++ A :: Δ1)). auto.
+          apply s in J2. destruct J2. destruct p. destruct p.
+          assert (J13: derrec_height x3 < S (dersrec_height d)). lia.
+          assert (J14: derrec_height x3 = derrec_height x3). auto.
+          pose (IHn _ J13 _ _ J14).
+          assert (J2: (Γ2 ++ B :: Γ3, Δ0 ++ Δ1) = (Γ2 ++ B :: Γ3, Δ0 ++ Δ1)). auto.
+          apply s0 in J2. destruct J2. destruct p0. destruct p0.
+          exists ((x4 --> (x5 --> Bot)) --> Bot). repeat split.
+          intros. 1,2: simpl in H ; repeat rewrite app_nil_r in H ; repeat rewrite propvar_subform_list_app ; simpl ;
+          repeat rewrite <- app_assoc ; apply in_app_or in H ; destruct H.
+          apply p in H ; repeat rewrite propvar_subform_list_app in H ; simpl in H ; destruct H ; auto.
+          apply p0 in H ; repeat rewrite propvar_subform_list_app in H ; simpl in H ; repeat rewrite <- app_assoc in H ; destruct H ; auto.
+          apply p in H ; repeat rewrite propvar_subform_list_app in H ; simpl in H ; destruct H ; auto.
+          apply in_app_or in i0 ; destruct i0. apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+          apply in_app_or in H ; destruct H. apply in_or_app ; auto.
+          apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; right ; auto.
+          apply p0 in H ; repeat rewrite propvar_subform_list_app in H ; simpl in H ; repeat rewrite <- app_assoc in H ; destruct H ; auto.
+          apply in_app_or in i0 ; destruct i0. apply in_or_app ; right ; apply in_or_app ; auto.
+          apply in_app_or in H ; destruct H. 1,2: apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+          apply derI with (ps:=[([] ++ (x4 --> x5 --> Bot) :: Γ2, [] ++ Bot :: Δ0)]). apply ImpR.
+          assert ((Γ2, (x4 --> x5 --> Bot) --> Bot :: Δ0) = ([] ++ Γ2, [] ++ (x4 --> x5 --> Bot) --> Bot :: Δ0)). auto. rewrite H. apply ImpRRule_I.
+          apply dlCons. 2: apply dlNil.
+          apply derI with (ps:=[([] ++ Γ2, [] ++ x4 :: Bot :: Δ0);([] ++ x5 --> Bot :: Γ2, [] ++ Bot :: Δ0)]). apply ImpL. apply ImpLRule_I.
+          apply dlCons. simpl.
+          assert (J15: derrec_height d1 = derrec_height d1). auto.
+          assert (J16: wkn_R Bot (Γ2, [x4] ++ Δ0) (Γ2, [x4] ++ Bot :: Δ0)). apply wkn_RI. simpl in J16.
+          pose (KS_wkn_R _ _ d1 J15 _ _ J16). destruct s1 ; auto. apply dlCons. 2: apply dlNil.
+          apply derI with (ps:=[([] ++ Γ2, [] ++ x5 :: Bot :: Δ0);([] ++ Bot :: Γ2, [] ++ Bot :: Δ0)]). apply ImpL. apply ImpLRule_I.
+          apply dlCons. simpl.
+          assert (J15: derrec_height d3 = derrec_height d3). auto.
+          assert (J16: wkn_R Bot (Γ2, [x5] ++ Δ0) (Γ2, [x5] ++ Bot :: Δ0)). apply wkn_RI. simpl in J16.
+          pose (KS_wkn_R _ _ d3 J15 _ _ J16). destruct s1 ; auto.
+          apply dlCons. 2: apply dlNil. apply derI with (ps:=[]). apply BotL. apply BotLRule_I. apply dlNil.
+          apply derI with (ps:=[([] ++ A --> B :: Γ3, [] ++ (x4 --> x5 --> Bot) :: Δ1);([] ++ Bot :: A --> B :: Γ3, [] ++ Δ1)]).
+          assert (((x4 --> x5 --> Bot) --> Bot :: A --> B :: Γ3, Δ1) = ([] ++ (x4 --> x5 --> Bot) --> Bot :: A --> B :: Γ3, [] ++ Δ1)). auto.
+          rewrite H. apply ImpL. apply ImpLRule_I. apply dlCons.
+          apply derI with (ps:=[([] ++ x4 :: A --> B :: Γ3, [] ++ x5 --> Bot :: Δ1)]). apply ImpR. apply ImpRRule_I. apply dlCons.
+          apply derI with (ps:=[([x4] ++ Γ3, [] ++ A :: x5 --> Bot :: Δ1);([x4] ++ B :: Γ3, [] ++ x5 --> Bot :: Δ1)]).
+          assert (([] ++ x4 :: A --> B :: Γ3, [] ++ x5 --> Bot :: Δ1) = ([x4] ++ A --> B :: Γ3, [] ++ x5 --> Bot :: Δ1)). auto.
+          rewrite H. apply ImpL. apply ImpLRule_I. apply dlCons. 3: apply dlNil.
+          assert (J15: derrec_height d0 = derrec_height d0). auto. simpl.
+          assert (J16: wkn_R (x5 --> Bot) (x4 :: Γ3, [A]++ Δ1) (x4 :: Γ3, [A] ++ x5 --> Bot :: Δ1)). apply wkn_RI. simpl in J16.
+          pose (KS_wkn_R _ _ d0 J15 _ _ J16). destruct s1 ; auto. apply dlCons. 2: apply dlNil.
+          apply derI with (ps:=[([x4] ++ x5 :: B :: Γ3, [] ++ Bot :: Δ1)]). apply ImpR. apply ImpRRule_I. apply dlCons.
+          assert (J15: derrec_height d2 = derrec_height d2). auto. simpl.
+          assert (J16: wkn_R Bot (x5 :: B :: Γ3, [] ++ Δ1) (x5 :: B :: Γ3, [] ++ Bot :: Δ1)). apply wkn_RI. simpl in J16.
+          pose (KS_wkn_R _ _ d2 J15 _ _ J16). destruct s1.
+          assert (J17: derrec_height x6 = derrec_height x6). auto. simpl.
+          assert (J18: wkn_L x4 ([] ++ x5 :: B :: Γ3, Bot :: Δ1) ([] ++ x4 :: x5 :: B :: Γ3, Bot :: Δ1)). apply wkn_LI. simpl in J18.
+          pose (KS_wkn_L _ _ x6 J17 _ _ J18). destruct s1. auto. apply dlNil. apply dlCons. 2: apply dlNil.
+          apply derI with (ps:=[]). apply BotL. apply BotLRule_I. apply dlNil.
+      -- repeat rewrite <- app_assoc. simpl. simpl in e1. inversion e1. subst.
+          assert (J13: derrec_height x3 < S (dersrec_height d)). lia.
+          assert (J14: derrec_height x3 = derrec_height x3). auto.
+          pose (IHn _ J13 _ _ J14).
+          assert (J2: (Γ2 ++ B :: x4 ++ Γ1, Δ0 ++ Δ1) = ((Γ2 ++ B :: x4) ++ Γ1, Δ0 ++ Δ1)). repeat rewrite <- app_assoc. auto.
+          apply s in J2. destruct J2. destruct p. destruct p.
+          assert (J7: derrec_height x2 = derrec_height x2). auto.
+          assert (J8: list_exch_R (Γ2 ++ x4 ++ Γ1, Δ0 ++ A :: Δ1) (Γ2 ++ x4 ++ Γ1, Δ1 ++ A :: Δ0)).
+          assert (Δ0 ++ A :: Δ1 = [] ++ Δ0 ++ [A] ++ Δ1 ++ []). rewrite app_nil_r. auto. rewrite H.
+          assert (Δ1 ++ A :: Δ0 = [] ++ Δ1 ++ [A] ++ Δ0 ++ []). rewrite app_nil_r. auto. rewrite H0. apply list_exch_RI.
+          pose (KS_hpadm_list_exch_R _ x2 _ J8). destruct s0.
+          assert (J9: derrec_height x6 = derrec_height x6). auto.
+          assert (J10: list_exch_L (Γ2 ++ x4 ++ Γ1, Δ1 ++ A :: Δ0) (Γ1 ++ x4 ++ Γ2, Δ1 ++ A :: Δ0)).
+          assert (Γ2 ++ x4 ++ Γ1 = [] ++ Γ2 ++ x4 ++ Γ1 ++ []). rewrite app_nil_r. auto. rewrite H.
+          assert (Γ1 ++ x4 ++ Γ2 = [] ++ Γ1 ++ x4 ++ Γ2 ++ []). rewrite app_nil_r. auto. rewrite H0. apply list_exch_LI.
+          pose (KS_hpadm_list_exch_L _ x6 _ J10). destruct s0.
+          assert (J11: derrec_height x7 < S (dersrec_height d)). rewrite e. apply PeanoNat.le_lt_n_Sm.
+          apply Nat.max_le_iff. left. pose (Nat.le_trans _ _ _ l0 l). pose (Nat.le_trans _ _ _ l2 l4). apply (Nat.le_trans _ _ _ l3 l5).
+          assert (J12: derrec_height x7 = derrec_height x7). auto.
+          pose (IHn _ J11 _ _ J12).
+          assert (J2: (Γ1 ++ x4 ++ Γ2, Δ1 ++ A :: Δ0) = (Γ1 ++ x4 ++ Γ2, Δ1 ++ A :: Δ0)). auto.
+          apply s0 in J2. destruct J2. destruct p0. destruct p0.
+          exists (x8 --> x5). repeat split.
+          intros. 1,2: simpl in H ; repeat rewrite app_nil_r in H ; repeat rewrite propvar_subform_list_app ; simpl ;
+          repeat rewrite propvar_subform_list_app ; simpl ;repeat rewrite <- app_assoc ; apply in_app_or in H ; destruct H.
+          apply p0 in H ; repeat rewrite propvar_subform_list_app in H ; simpl in H ; repeat rewrite <- app_assoc in H ; destruct H ; auto.
+          apply in_app_or in i0 ; destruct i0. apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+          apply in_app_or in H ; destruct H. apply in_or_app ; auto. apply in_app_or in H ; destruct H.
+          apply in_or_app ; right ; apply in_or_app ; auto. apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+          apply p in H ; repeat rewrite propvar_subform_list_app in H ; simpl in H ; destruct H ; repeat rewrite <- app_assoc in i.
+          apply in_app_or in i ; destruct i. apply in_or_app ; auto. apply in_app_or in H ; destruct H.
+          apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto. apply in_app_or in H ; destruct H.
+          apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+          apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+          apply p0 in H ; repeat rewrite propvar_subform_list_app in H ; simpl in H ; repeat rewrite <- app_assoc in H ; destruct H ; auto.
+          apply p in H ; repeat rewrite propvar_subform_list_app in H ; simpl in H ; destruct H ; auto.
+          apply derI with (ps:=[(Γ2 ++ x8 :: A --> B :: x4, [] ++ x5 :: Δ0)]). apply ImpR.
+          assert ((Γ2 ++ A --> B :: x4, x8 --> x5 :: Δ0) = (Γ2 ++ A --> B :: x4, [] ++ x8 --> x5 :: Δ0)). auto. rewrite H. apply ImpRRule_I.
+          apply dlCons. 2: apply dlNil.
+          apply derI with (ps:=[((Γ2 ++ [x8]) ++ x4, [] ++ A :: x5 :: Δ0);((Γ2 ++ [x8]) ++ B :: x4, [] ++ x5 :: Δ0)]). apply ImpL.
+          assert ((Γ2 ++ x8 :: A --> B :: x4, [] ++ x5 :: Δ0) = ((Γ2 ++ [x8]) ++ A --> B :: x4, [] ++ x5 :: Δ0)). repeat rewrite <- app_assoc. auto.
+          rewrite H. apply ImpLRule_I. apply dlCons. repeat rewrite <- app_assoc. simpl.
+          assert (J15: derrec_height d2 = derrec_height d2). auto.
+          pose (@KS_list_wkn_R (derrec_height d2) (x8 :: x4 ++ Γ2) [A] Δ0). simpl in s1.
+          pose (s1 d2 J15 [x5]). simpl in s2. destruct s2.
+          assert (J16: derrec_height x9 = derrec_height x9). auto.
+          assert (J17: list_exch_L (x8 :: x4 ++ Γ2, A :: x5 :: Δ0) (Γ2 ++ x8 :: x4, A :: x5 :: Δ0)).
+          assert (x8 :: x4 ++ Γ2 = [] ++ (x8 :: x4) ++ [] ++ Γ2 ++ []). rewrite app_nil_r. auto. rewrite H.
+          assert (Γ2 ++ x8 :: x4 = [] ++ Γ2 ++ [] ++ (x8 :: x4) ++ []). rewrite app_nil_r. auto. rewrite H0. apply list_exch_LI.
+          pose (KS_hpadm_list_exch_L _ x9 _ J17). destruct s2. auto.
+          simpl. repeat rewrite <- app_assoc. simpl.
+          assert (J17: derrec_height d1 = derrec_height d1). auto. simpl. apply dlCons. 2: apply dlNil.
+          assert (J18: wkn_L x8 (Γ2 ++ B :: x4, x5 :: Δ0) (Γ2 ++ x8 :: B :: x4, x5 :: Δ0)). apply wkn_LI.
+          pose (KS_wkn_L _ _ d1 J17 _ _ J18). destruct s1. auto.
+          apply derI with (ps:=[([] ++ Γ1, [] ++ x8 :: Δ1);([] ++ x5 :: Γ1, [] ++ Δ1)]).
+          assert ((x8 --> x5 :: Γ1, Δ1) = ([] ++ x8 --> x5 :: Γ1, [] ++ Δ1)). auto. rewrite H. apply ImpL. apply ImpLRule_I.
+          apply dlCons. simpl ; auto. apply dlCons. simpl ; auto. apply dlNil.
+    + assert (J11: derrec_height x2 < S (dersrec_height d)). rewrite e. apply PeanoNat.le_lt_n_Sm.
+        apply Nat.max_le_iff. left. apply (Nat.le_trans _ _ _ l0 l).
+        assert (J12: derrec_height x2 = derrec_height x2). auto.
+        pose (IHn _ J11 _ _ J12).
+        assert (J2: ((Γ0 ++ x4) ++ Γ3, Δ0 ++ A :: Δ1) = (Γ0 ++ x4 ++ Γ3, Δ0 ++ A :: Δ1)). repeat rewrite <- app_assoc. auto.
+        apply s in J2. destruct J2. destruct p. destruct p.
+        assert (J13: derrec_height x3 < S (dersrec_height d)). lia.
+        assert (J14: derrec_height x3 = derrec_height x3). auto.
+        pose (IHn _ J13 _ _ J14).
+        assert (J2: ((Γ0 ++ x4) ++ B :: Γ3, Δ0 ++ Δ1) = (Γ0 ++ x4 ++ B :: Γ3, Δ0 ++ Δ1)). repeat rewrite <- app_assoc. auto.
+        apply s0 in J2. destruct J2. destruct p0. destruct p0.
+        exists ((x5 --> (x6 --> Bot)) --> Bot). repeat split.
+        intros. 1,2: simpl in H ; repeat rewrite app_nil_r in H ; repeat rewrite propvar_subform_list_app ; simpl ;
+        repeat rewrite propvar_subform_list_app ; simpl ;repeat rewrite <- app_assoc ; apply in_app_or in H ; destruct H.
+        apply p in H ; repeat rewrite propvar_subform_list_app in H ; simpl in H ; destruct H ; auto.
+        apply p0 in H ; repeat rewrite propvar_subform_list_app in H ; simpl in H ; repeat rewrite <- app_assoc in H ; destruct H ; auto.
+        apply p in H ; repeat rewrite propvar_subform_list_app in H ; simpl in H ; destruct H ; repeat rewrite <- app_assoc in i0.
+        apply in_app_or in i0 ; destruct i0. apply in_or_app ; auto. apply in_app_or in H ; destruct H.
+        apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto. apply in_app_or in H ; destruct H.
+        apply in_or_app ; right ; apply in_or_app ; auto.
+        apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+        apply p0 in H ; repeat rewrite propvar_subform_list_app in H ; simpl in H ; repeat rewrite <- app_assoc in H ; destruct H ; auto.
+        apply in_app_or in i0 ; destruct i0. apply in_or_app ; auto. apply in_app_or in H ; destruct H.
+        apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto. apply in_app_or in H ; destruct H.
+        apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+        apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+        apply derI with (ps:=[([] ++ (x5 --> x6 --> Bot) :: Γ0, [] ++ Bot :: Δ0)]). apply ImpR.
+        assert ((Γ0, (x5 --> x6 --> Bot) --> Bot :: Δ0) = ([] ++ Γ0, [] ++ (x5 --> x6 --> Bot) --> Bot :: Δ0)). auto. rewrite H. apply ImpRRule_I.
+        apply dlCons. 2: apply dlNil.
+        apply derI with (ps:=[([] ++ Γ0, [] ++ x5 :: Bot :: Δ0);([] ++ x6 --> Bot :: Γ0, [] ++ Bot :: Δ0)]). apply ImpL. apply ImpLRule_I.
+        apply dlCons. simpl.
+        assert (J15: derrec_height d1 = derrec_height d1). auto.
+        assert (J16: wkn_R Bot (Γ0, [x5] ++ Δ0) (Γ0, [x5] ++ Bot :: Δ0)). apply wkn_RI. simpl in J16.
+        pose (KS_wkn_R _ _ d1 J15 _ _ J16). destruct s1 ; auto. apply dlCons. 2: apply dlNil.
+        apply derI with (ps:=[([] ++ Γ0, [] ++ x6 :: Bot :: Δ0);([] ++ Bot :: Γ0, [] ++ Bot :: Δ0)]). apply ImpL. apply ImpLRule_I.
+        apply dlCons. simpl.
+        assert (J15: derrec_height d3 = derrec_height d3). auto.
+        assert (J16: wkn_R Bot (Γ0, [x6] ++ Δ0) (Γ0, [x6] ++ Bot :: Δ0)). apply wkn_RI. simpl in J16.
+        pose (KS_wkn_R _ _ d3 J15 _ _ J16). destruct s1 ; auto.
+        apply dlCons. 2: apply dlNil. apply derI with (ps:=[]). apply BotL. apply BotLRule_I. apply dlNil.
+        apply derI with (ps:=[([] ++ x4 ++ A --> B :: Γ3, [] ++ (x5 --> x6 --> Bot) :: Δ1);([] ++ Bot :: x4 ++ A --> B :: Γ3, [] ++ Δ1)]).
+        assert (((x5 --> x6 --> Bot) --> Bot :: x4 ++ A --> B :: Γ3, Δ1) = ([] ++ (x5 --> x6 --> Bot) --> Bot :: x4 ++ A --> B :: Γ3, [] ++ Δ1)). auto.
+        rewrite H. apply ImpL. apply ImpLRule_I. apply dlCons.
+        apply derI with (ps:=[([] ++ x5 :: x4 ++ A --> B :: Γ3, [] ++ x6 --> Bot :: Δ1)]). apply ImpR. apply ImpRRule_I. apply dlCons.
+        apply derI with (ps:=[((x5 :: x4) ++ Γ3, [] ++ A :: x6 --> Bot :: Δ1);((x5 :: x4) ++ B :: Γ3, [] ++ x6 --> Bot :: Δ1)]).
+        assert (([] ++ x5 :: x4 ++ A --> B :: Γ3, [] ++ x6 --> Bot :: Δ1) = ((x5 :: x4) ++ A --> B :: Γ3, [] ++ x6 --> Bot :: Δ1)). auto.
+        rewrite H. apply ImpL. apply ImpLRule_I. apply dlCons. 3: apply dlNil.
+        assert (J15: derrec_height d0 = derrec_height d0). auto. simpl.
+        assert (J16: wkn_R (x6 --> Bot) (x5 :: x4 ++ Γ3, [A]++ Δ1) (x5 :: x4 ++ Γ3, [A] ++ x6 --> Bot :: Δ1)). apply wkn_RI. simpl in J16.
+        pose (KS_wkn_R _ _ d0 J15 _ _ J16). destruct s1 ; auto. apply dlCons. 2: apply dlNil.
+        apply derI with (ps:=[((x5 :: x4) ++ x6 :: B :: Γ3, [] ++ Bot :: Δ1)]). apply ImpR. apply ImpRRule_I. apply dlCons.
+          assert (J19: derrec_height d2 = derrec_height d2). auto.
+          assert (J20: list_exch_L (x6 :: x4 ++ B :: Γ3, Δ1) (x4 ++ x6 :: B :: Γ3, Δ1)).
+          assert (x6 :: x4 ++ B :: Γ3 = [] ++ [x6] ++ [] ++ x4 ++ (B :: Γ3)). auto. rewrite H.
+          assert (x4 ++ x6 :: B :: Γ3 = [] ++ x4 ++ [] ++ [x6] ++ (B :: Γ3)). auto. rewrite H0. apply list_exch_LI.
+          pose (KS_hpadm_list_exch_L _ d2 _ J20). destruct s1. auto.
+        assert (J15: derrec_height x7 = derrec_height x7). auto. simpl.
+        assert (J16: wkn_R Bot (x4 ++ x6 :: B :: Γ3, [] ++ Δ1) (x4 ++ x6 :: B :: Γ3, [] ++ Bot :: Δ1)). apply wkn_RI. simpl in J16.
+        pose (KS_wkn_R _ _ x7 J15 _ _ J16). destruct s1.
+        assert (J17: derrec_height x8 = derrec_height x8). auto. simpl.
+        assert (J18: wkn_L x5 ([] ++ x4 ++ x6 :: B :: Γ3, Bot :: Δ1) ([] ++ x5 :: x4 ++ x6 :: B :: Γ3, Bot :: Δ1)). apply wkn_LI. simpl in J18.
+        pose (KS_wkn_L _ _ x8 J17 _ _ J18). destruct s1. auto. apply dlNil. apply dlCons. 2: apply dlNil.
+        apply derI with (ps:=[]). apply BotL. apply BotLRule_I. apply dlNil.
+  (* KR *)
+  * inversion X. subst. inversion H5. subst. pose (univ_gen_ext_splitR _ _ X0). destruct s.
+    destruct s. destruct p. subst. destruct p.
+    assert (J: dersrec_height d = dersrec_height d). auto. apply dersrec_derrec_height in J. destruct J.
+    apply app2_find_hole in H1. destruct H1. simpl in IHn. repeat destruct s ; destruct p ; subst.
+    + assert (J1: derrec_height x1 < S (dersrec_height d)). lia.
+       assert (J2: derrec_height x1 = derrec_height x1). auto.
+       assert (J3: (unboxed_list (x ++ x0), [A]) = ((unboxed_list x) ++ (unboxed_list x0), [] ++ [A])).
+       rewrite unbox_app_distrib. repeat rewrite <- app_assoc. auto.
+       pose (IHn _ J1 _ _ J2 _ _ _ _ J3). destruct s. destruct p. destruct p.
+       exists (Box x3). simpl. simpl in p. repeat split.
+       intros. 1,2: simpl in H ; repeat rewrite app_nil_r in H ; repeat rewrite propvar_subform_list_app ; simpl ;
+       repeat rewrite propvar_subform_list_app ; simpl ;repeat rewrite <- app_assoc ;
+       apply p in H ; repeat rewrite propvar_subform_list_app in H ; simpl in H ; repeat rewrite app_nil_r in H ; destruct H.
+       apply propvar_subform_list_unboxed_list in i. apply in_or_app ; left. apply (propvar_subform_list_nobox_gen_ext u) ; auto.
+       repeat rewrite <- app_assoc in i0. apply in_app_or in i0. destruct i0.
+       apply in_or_app ; left. apply propvar_subform_list_unboxed_list in H. apply (propvar_subform_list_nobox_gen_ext u0) ; auto.
+       apply in_or_app ; right ; apply in_or_app ; auto.
+       apply derI with (ps:=[(unboxed_list x, [x3])]). apply KR.
+       assert ((Γ0, Box x3 :: Δ2) = (Γ0, [] ++ Box x3 :: Δ2)). auto. rewrite H. apply KRRule_I ; auto.
+       intro. intros. apply H3. apply in_or_app ; auto. apply dlCons. 2: apply dlNil. auto.
+       apply derI with (ps:=[(unboxed_list (Box x3 :: x0), [A])]). apply KR.
+       assert ((Box x3 :: Γ1, Box A :: Δ3) = (Box x3 :: Γ1, [] ++ Box A :: Δ3)). auto. rewrite H. apply KRRule_I ; auto.
+       intro. intros. inversion H0. exists x3 ; subst ; auto. apply H3. apply in_or_app ; auto.
+       apply univ_gen_ext_cons ; auto. apply dlCons. 2: apply dlNil. simpl. auto.
+    + destruct x2.
+       -- repeat rewrite app_nil_r. simpl in e1. subst. assert (J1: derrec_height x1 < S (dersrec_height d)). lia.
+           assert (J2: derrec_height x1 = derrec_height x1). auto.
+           assert (J3: (unboxed_list (x ++ x0), [A]) = ((unboxed_list x) ++ (unboxed_list x0), [] ++ [A])).
+           rewrite unbox_app_distrib. repeat rewrite <- app_assoc. auto.
+           pose (IHn _ J1 _ _ J2 _ _ _ _ J3). destruct s. destruct p. destruct p.
+           exists (Box x2). simpl. repeat rewrite app_nil_r in p. repeat split.
+           intros. 1,2: simpl in H ; repeat rewrite app_nil_r in H ; repeat rewrite propvar_subform_list_app ; simpl ;
+           repeat rewrite propvar_subform_list_app ; simpl ;repeat rewrite <- app_assoc ;
+           apply p in H ; repeat rewrite propvar_subform_list_app in H ; simpl in H ; repeat rewrite app_nil_r in H ;
+           destruct H ; repeat rewrite <- app_assoc in i0.
+           apply propvar_subform_list_unboxed_list in i. apply in_or_app ; left. apply (propvar_subform_list_nobox_gen_ext u) ; auto.
+           repeat rewrite <- app_assoc in i0. apply in_app_or in i0. destruct i0.
+           apply in_or_app ; left. apply propvar_subform_list_unboxed_list in H. apply (propvar_subform_list_nobox_gen_ext u0) ; auto.
+           apply in_or_app ; right ; apply in_or_app ; auto.
+           apply derI with (ps:=[(unboxed_list x, [x2])]). apply KR.
+           assert ((Γ0, Box x2 :: Δ2) = (Γ0, [] ++ Box x2 :: Δ2)). auto. rewrite H. apply KRRule_I ; auto.
+           intro. intros. apply H3. apply in_or_app ; auto. apply dlCons. 2: apply dlNil. auto.
+           apply derI with (ps:=[(unboxed_list (Box x2 :: x0), [A])]). apply KR.
+           assert ((Box x2 :: Γ1, Box A :: Δ3) = (Box x2 :: Γ1, [] ++ Box A :: Δ3)). auto. rewrite H. apply KRRule_I ; auto.
+           intro. intros. inversion H0. exists x2 ; subst ; auto. apply H3. apply in_or_app ; auto.
+           apply univ_gen_ext_cons ; auto. apply dlCons. 2: apply dlNil. simpl. auto.
+       -- simpl in e1. inversion e1 ; subst.
+              assert (J19: derrec_height x1 = derrec_height x1). auto.
+              assert (J20: list_exch_L (unboxed_list (x ++ x0), [A]) (unboxed_list x0 ++ unboxed_list x, [A])).
+              assert (unboxed_list (x ++ x0) = [] ++ (unboxed_list x) ++ [] ++ (unboxed_list x0) ++ []).
+              rewrite unbox_app_distrib. simpl. rewrite app_nil_r. auto. rewrite H.
+              assert (unboxed_list x0 ++ unboxed_list x = [] ++ (unboxed_list x0) ++ [] ++ (unboxed_list x) ++ []).
+              simpl. rewrite app_nil_r. auto. rewrite H0. apply list_exch_LI.
+               pose (KS_hpadm_list_exch_L _ x1 _ J20). destruct s.
+               assert (J1: derrec_height x3 < S (dersrec_height d)). rewrite <- e. apply PeanoNat.le_lt_n_Sm. auto.
+               assert (J2: derrec_height x3 = derrec_height x3). auto.
+               assert (J3: (unboxed_list x0 ++ unboxed_list x, [A]) = (unboxed_list x0 ++ unboxed_list x, [] ++ [A])).
+               repeat rewrite <- app_assoc. auto.
+               pose (IHn _ J1 _ _ J2 _ _ _ _ J3). destruct s. destruct p. destruct p.
+               exists ((Box x4) --> Bot). simpl. repeat rewrite app_nil_r in p. repeat rewrite app_nil_r. repeat split.
+               intros. 1,2: simpl in H ; repeat rewrite app_nil_r in H ; repeat rewrite propvar_subform_list_app ; simpl ;
+               repeat rewrite propvar_subform_list_app ; simpl ;repeat rewrite <- app_assoc ;
+               apply p in H ; repeat rewrite propvar_subform_list_app in H ; simpl in H ; repeat rewrite app_nil_r in H ;
+               destruct H ; repeat rewrite <- app_assoc in i0. apply in_app_or in i0. destruct i0.
+             apply in_or_app ; left. apply propvar_subform_list_unboxed_list in H. apply (propvar_subform_list_nobox_gen_ext u) ; auto.
+             apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+             apply propvar_subform_list_unboxed_list in i. apply in_or_app ; left.
+             apply (propvar_subform_list_nobox_gen_ext u0) ; auto.
+             apply derI with (ps:=[([] ++ Box x4 :: Γ0, [] ++ Bot :: Δ2 ++ Box A :: x2)]). apply ImpR.
+             assert ((Γ0, Box x4 --> Bot :: Δ2 ++ Box A :: x2) = ([] ++ Γ0, [] ++ Box x4 --> Bot :: Δ2 ++ Box A :: x2)). auto. rewrite H. apply ImpRRule_I.
+             apply dlCons. 2: apply dlNil. simpl.
+             pose (dlCons d0 (dlNil _ _)). apply derI with (concl:=(Box x4 :: Γ0, (Bot :: Δ2) ++ Box A :: x2)) in d2 ; auto.
+             apply KR. assert (x4 :: unboxed_list x = unboxed_list (Box x4 :: x)).
+             simpl. auto. rewrite H. apply KRRule_I ; auto. intro. intros. inversion H0. exists x4 ; subst ; auto.
+             apply H3. apply in_or_app ; auto. apply univ_gen_ext_cons ; auto.
+             apply derI with (ps:=[([] ++ Γ1, [] ++ Box x4 :: Δ1);([] ++ Bot :: Γ1, [] ++ Δ1)]). apply ImpL.
+             assert ((Box x4 --> Bot :: Γ1, Δ1) = ([] ++ Box x4 --> Bot :: Γ1, [] ++ Δ1)). auto. rewrite H. apply ImpLRule_I.
+             apply dlCons. apply derI with (ps:=[(unboxed_list x0, [x4])]). apply KR. apply KRRule_I ; auto.
+             intro. intros. apply H3. apply in_or_app ; auto. apply dlCons.
+             assert (J4: derrec_height d1 = derrec_height d1). auto. 2: apply dlNil. auto.
+             apply dlCons. 2: apply dlNil. apply derI with (ps:=[]). apply BotL. 2: apply dlNil. apply BotLRule_I.
+    + assert (J1: derrec_height x1 < S (dersrec_height d)). lia.
+       assert (J2: derrec_height x1 = derrec_height x1). auto.
+       assert (J3: (unboxed_list (x ++ x0), [A]) = ((unboxed_list x) ++ (unboxed_list x0), [] ++ [A])).
+       rewrite unbox_app_distrib. repeat rewrite <- app_assoc. auto.
+       pose (IHn _ J1 _ _ J2 _ _ _ _ J3). destruct s. destruct p. destruct p.
+       exists (Box x3). simpl. repeat rewrite app_nil_r in p. repeat split.
+       intros. 1,2: simpl in H ; repeat rewrite app_nil_r in H ; repeat rewrite propvar_subform_list_app ; simpl ;
+       repeat rewrite propvar_subform_list_app ; simpl ;repeat rewrite <- app_assoc ;
+       apply p in H ; repeat rewrite propvar_subform_list_app in H ; simpl in H ; repeat rewrite app_nil_r in H ;
+       destruct H ; repeat rewrite <- app_assoc in i0.
+       apply propvar_subform_list_unboxed_list in i. apply in_or_app ; left.
+       apply (propvar_subform_list_nobox_gen_ext u) ; auto.
+       apply in_app_or in i0. destruct i0.
+       apply in_or_app ; left. apply propvar_subform_list_unboxed_list in H. apply (propvar_subform_list_nobox_gen_ext u0) ; auto.
+       apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+       apply derI with (ps:=[(unboxed_list x, [x3])]). apply KR.
+       assert ((Γ0, Box x3 :: Δ0) = (Γ0, [] ++ Box x3 :: Δ0)). auto. rewrite H. apply KRRule_I ; auto.
+       intro. intros. apply H3. apply in_or_app ; auto. apply dlCons. 2: apply dlNil. auto.
+       apply derI with (ps:=[(unboxed_list (Box x3 :: x0), [A])]). apply KR. apply KRRule_I ; auto.
+       intro. intros. inversion H. exists x3 ; subst ; auto. apply H3. apply in_or_app ; auto.
+       apply univ_gen_ext_cons ; auto. apply dlCons. 2: apply dlNil. simpl. auto.
+Qed.
+
+
+ +
+ + + diff --git a/K.Interpolation.UIK_Canopy.html b/K.Interpolation.UIK_Canopy.html new file mode 100644 index 0000000..a51bf96 --- /dev/null +++ b/K.Interpolation.UIK_Canopy.html @@ -0,0 +1,623 @@ + + + + + + + + + + + + + +
+
+

K.Interpolation.UIK_Canopy

+ +
+  (* Canopy of the invertible proof search of sequents *)
+ +
+  Require Import List.
+  Export ListNotations.
+  Require Import Lia.
+ +
+  Require Import Coq.Init.Wf.
+ +
+  Require Import KS_export.
+  Require Import UIK_Def_measure.
+ +
+  Require Import UIK_irred_short UIK_irred_high_level.
+ +
+  Require Import general_export.
+ +
+  (* Defining the premises of a sequent via Imp rules. *)
+ +
+  Lemma finite_ImpRules_premises_of_S : forall (s : Seq), existsT2 listImpRulesprems,
+                (forall prems, (((ImpRRule prems s) + (ImpLRule prems s)) -> (InT prems listImpRulesprems)) *
+                               ((InT prems listImpRulesprems) -> ((ImpRRule prems s) + (ImpLRule prems s)))).
+  Proof.
+  intros.
+  pose (finite_ImpR_premises_of_S s). destruct s0.
+  pose (finite_ImpL_premises_of_S s). destruct s0.
+  exists (x ++ x0). intros. split ; intro.
+  - destruct H.
+    + inversion i. subst. apply InT_or_app. left. apply p. apply ImpRRule_I.
+    + inversion i. subst. apply InT_or_app. right. apply p0. apply ImpLRule_I.
+  - apply InT_app_or in H. destruct H.
+    + left. apply p ; auto.
+    + right. apply p0 ; auto.
+  Defined.
+ +
+  Definition inv_prems (s : Seq) := flatten_list (proj1_sigT2 (finite_ImpRules_premises_of_S s)).
+ +
+  (* The number of implication symbols in a sequent gives a measure
+      which has a well-founded order.*)

+ +
+Fixpoint n_imp_subformF (A : MPropF) : nat :=
+match A with
+ | # P => 0
+ | Bot => 0
+ | Imp B C => 1 + (n_imp_subformF B) + (n_imp_subformF C)
+ | Box B => (n_imp_subformF B)
+end.
+ +
+(* With this definition in hand, we can then straightforwardly define the number
+   of implications in a list of formulae. *)

+ +
+Fixpoint n_imp_subformLF (l : list MPropF) : nat :=
+match l with
+  | [] => 0
+  | h :: t => (n_imp_subformF h) + (n_imp_subformLF t)
+end.
+ +
+(* Then the definition we were initially looking for can be reached: *)
+ +
+Definition n_imp_subformS (s : Seq) : nat :=
+    (n_imp_subformLF (fst s)) + (n_imp_subformLF (snd s)).
+ +
+(* It is clear that n_imp_subformS counts the occurrences of implications in a
+   sequent s. As a consequence, if that number is 0 we know for sure that the
+   rules for implication on the left or right cannot be applied upwards on s.
+   This is the meaning of the lemma n_imp_subformS_is_0. 
+
+   But first we need a preliminary lemma which claims that if an implication is
+   in a list, then n_imp_subformLF of that list is higher than one.*)

+ +
+Lemma In_n_imp_subformLF_is_non_0 (l : list MPropF) :
+    forall A B, (In (Imp A B) l) -> (le 1 (n_imp_subformLF l)).
+Proof.
+intros A B Hin. induction l.
+- inversion Hin.
+- inversion Hin.
+  * subst. simpl. lia.
+  * pose (IHl H). simpl. destruct l0 ; lia.
+Qed.
+ +
+Theorem n_imp_subformS_is_0 (s : Seq) :
+    (n_imp_subformS s) = 0 -> (existsT2 ps, (ImpRRule ps s) + (ImpLRule ps s)) -> False.
+Proof.
+intros is0 RA. destruct RA. destruct s0.
+- inversion i. subst. unfold n_imp_subformS in is0. simpl in is0.
+  assert (n_imp_subformLF (Δ0 ++ A --> B :: Δ1) = 0). lia.
+  assert (In (A --> B) (Δ0 ++ A --> B :: Δ1)). apply in_or_app. right. apply in_eq.
+  pose (In_n_imp_subformLF_is_non_0 (Δ0 ++ A --> B :: Δ1) A B H0). lia.
+- inversion i. subst.
+  assert (In (A --> B) (Γ0 ++ A --> B :: Γ1)). apply in_or_app. right. apply in_eq.
+  pose (In_n_imp_subformLF_is_non_0 (Γ0 ++ A --> B :: Γ1) A B H). unfold n_imp_subformS in is0.
+  simpl in is0. assert (n_imp_subformLF (Δ0 ++ Δ1) = 0). lia. lia.
+Qed.
+ +
+Lemma n_imp_subformLF_dist_app : forall l1 l2, n_imp_subformLF (l1 ++ l2) =
+                                               plus (n_imp_subformLF l1) (n_imp_subformLF l2).
+Proof.
+induction l1.
+- intros. auto.
+- intros. simpl. rewrite IHl1. lia.
+Qed.
+ +
+Lemma n_imp_nobox_gen_ext : forall l1 l2, nobox_gen_ext l1 l2 ->
+                                               (n_imp_subformLF l1 <= n_imp_subformLF l2).
+Proof.
+intros. induction X.
+- simpl. lia.
+- simpl. lia.
+- simpl. lia.
+Qed.
+ +
+Lemma n_imp_unboxed : forall l, (n_imp_subformLF (unboxed_list l) <= n_imp_subformLF l).
+Proof.
+induction l.
+- simpl. lia.
+- simpl. destruct a ; simpl ; lia.
+Qed.
+ +
+  Definition less_imp (s0 s1 : Seq) := (n_imp_subformS s0) < (n_imp_subformS s1).
+ +
+  Lemma Acc_less_imp : well_founded less_imp.
+  Proof.
+  intros s ; induction on s as IHm with measure (n_imp_subformS s).
+  apply Acc_intro. auto.
+  Defined.
+ +
+  Definition invprem (s0 s1 : Seq) := In s0 (inv_prems s1).
+ +
+  Lemma InT_In_inv_prems : forall s0 s1, (InT s0 (inv_prems s1) -> In s0 (inv_prems s1)) *
+                                                                   (In s0 (inv_prems s1) -> InT s0 (inv_prems s1)).
+  Proof.
+  intros. split ; intros.
+  - apply InT_In ; auto.
+  - unfold inv_prems. unfold inv_prems in H. destruct (finite_ImpRules_premises_of_S s1).
+    simpl. simpl in H. apply In_InT_seqs. auto.
+Qed.
+ +
+  Lemma Acc_invprem : well_founded invprem.
+  Proof.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  apply Acc_intro. intros. apply IHs. unfold invprem in H.
+  apply InT_In_inv_prems in H. unfold inv_prems in H.
+  destruct (finite_ImpRules_premises_of_S s) in H. simpl in H.
+  apply InT_flatten_list_InT_elem in H. destruct H. destruct p0.
+  apply p in i0. destruct i0.
+  inversion i0. subst. inversion i. subst.
+  unfold n_imp_subformS ; simpl. repeat rewrite n_imp_subformLF_dist_app.
+  simpl. lia. subst. inversion H0.
+  inversion i0. subst. inversion i. subst.
+  unfold n_imp_subformS ; simpl. repeat rewrite n_imp_subformLF_dist_app.
+  simpl. lia. subst.
+  inversion H0. subst.
+  unfold n_imp_subformS ; simpl. repeat rewrite n_imp_subformLF_dist_app.
+  simpl. lia. subst. inversion H1.
+  Defined.
+ +
+  (* The closure of a sequent is the list of all sequents which can be
+      reach via chains of backward applications of invertible rules. *)

+ +
+  Definition Canopy := irred Acc_invprem.
+ +
+  (* Critical sequents are sequents on which no invertible (Imp)
+      rule is backward applicable. *)

+ +
+  Definition critical_Seq (s : Seq) := is_Prime ((fst s) ++ (snd s)).
+ +
+  Definition is_Prime_dec : forall l, (is_Prime l) + (is_Prime l -> False).
+  Proof.
+  unfold is_Prime. induction l ; simpl ; auto.
+  left. intros. inversion H. destruct IHl. destruct a as [n| | |].
+  1,2,4: left ; intros ; destruct H ; auto. right. left ; exists n ; auto.
+  left ; exists a ; auto. right. intro.
+  assert ((Imp a1 a2 = Imp a1 a2) \/ In (Imp a1 a2) l). left ; auto. apply H in H0.
+  destruct H0. destruct H0. inversion H0. destruct H0. destruct H0 ; inversion H0.
+  inversion H0. right. intros. apply f. intros. apply H. auto.
+  Defined.
+ +
+  Definition critical_Seq_dec (s : Seq) : (critical_Seq s) + (critical_Seq s -> False).
+  Proof.
+  unfold critical_Seq. destruct s ; simpl. apply is_Prime_dec.
+  Defined.
+ +
+  (* We show that all sequents in Canopy are critical. *)
+ +
+  Lemma inv_prems_id_critical : forall s, inv_prems s = [] -> critical_Seq s.
+  Proof.
+  intros. destruct s. unfold critical_Seq. intros A H0. destruct A as [n| | |].
+  right ; left ; exists n ; auto. right ; auto.
+  2: left ; exists A ; auto. exfalso. simpl in H0.
+  apply in_app_or in H0 ; destruct H0.
+  apply in_split in H0. destruct H0. destruct H0. subst.
+  assert (In (x ++ A2 :: x0, l0) (inv_prems (x ++ A1 --> A2 :: x0, l0))).
+  unfold inv_prems. apply InT_In.
+  apply InT_trans_flatten_list with (bs:=[(x ++ x0, [] ++ A1 :: l0);(x ++ A2 :: x0, [] ++ l0)]).
+  apply InT_cons ; apply InT_eq.
+  destruct (finite_ImpRules_premises_of_S (x ++ A1 --> A2 :: x0, l0)).
+  apply p. right. assert ((x ++ A1 --> A2 :: x0, l0) = (x ++ A1 --> A2 :: x0, [] ++ l0)). auto.
+  rewrite H0. apply ImpLRule_I.
+  rewrite H in H0. inversion H0.
+  apply in_split in H0. destruct H0. destruct H0. subst.
+  assert (In (l ++ A1 :: [], x ++ A2 :: x0) (inv_prems (l ++ [] , x ++ A1 --> A2 :: x0))).
+  unfold inv_prems. apply InT_In.
+  apply InT_trans_flatten_list with (bs:=[(l ++ [A1], x ++ A2 :: x0)]). apply InT_eq.
+  destruct (finite_ImpRules_premises_of_S (l ++ [], x ++ A1 --> A2 :: x0)).
+  apply p. left. apply ImpRRule_I. rewrite app_nil_r in H0.
+  rewrite H in H0. inversion H0.
+  Qed.
+ +
+  Lemma Canopy_critical : forall s leaf, InT leaf (Canopy s) -> (critical_Seq leaf).
+  Proof.
+  unfold Canopy.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  intros. remember (inv_prems s) as prems. destruct prems.
+  - symmetry in Heqprems ; pose (irred_nil _ _ Acc_invprem s Heqprems).
+    rewrite e in H. pose (inv_prems_id_critical _ Heqprems). inversion H ; subst ; auto.
+    inversion H1.
+  - assert (J1: inv_prems s <> []%list). rewrite <- Heqprems. intro.
+    inversion H0. pose (irred_not _ _ Acc_invprem s J1). rewrite e in H.
+    pose (InT_In H). apply in_flat_map in i. destruct i. destruct H0.
+    apply In_InT_seqs in H1. apply IHs with (y:=x) ; auto.
+    apply InT_In_inv_prems in H0. unfold inv_prems in H0.
+    destruct (finite_ImpRules_premises_of_S s) in H0. simpl in H0.
+    apply InT_flatten_list_InT_elem in H0. destruct H0. destruct p0.
+    apply p in i0. destruct i0.
+    inversion i0. subst. inversion i. subst.
+    unfold n_imp_subformS ; simpl. repeat rewrite n_imp_subformLF_dist_app.
+    simpl. lia. subst. inversion H2.
+    inversion i0. subst. inversion i. subst.
+    unfold n_imp_subformS ; simpl. repeat rewrite n_imp_subformLF_dist_app.
+    simpl. lia. subst.
+    inversion H2. subst.
+    unfold n_imp_subformS ; simpl. repeat rewrite n_imp_subformLF_dist_app.
+    simpl. lia. subst. inversion H3.
+  Qed.
+ +
+  (* We show the equiprovability between a sequent and its Canopy. *)
+ +
+  Lemma ImpRule_Canopy : forall s prems, ((ImpRRule prems s) + (ImpLRule prems s)) ->
+                (forall prem, InT prem prems -> (forall leaf, InT leaf (Canopy prem) -> InT leaf (Canopy s))).
+  Proof.
+  intros. unfold Canopy. rewrite irred_not. apply In_InT_seqs.
+  apply in_flat_map. exists prem ; split ; auto. 2: apply InT_In ; auto.
+  unfold inv_prems. apply InT_In. apply InT_trans_flatten_list with (bs:=prems) ; auto.
+  destruct (finite_ImpRules_premises_of_S s) ; simpl. apply p ; auto.
+  intro. unfold inv_prems in H2. destruct (finite_ImpRules_premises_of_S s) ; simpl.
+  simpl in H2. apply p in H. assert (InT prem (flatten_list x)).
+  apply InT_trans_flatten_list with (bs:=prems) ; auto. rewrite H2 in H3. inversion H3.
+  Qed.
+ +
+  (* Move the lemma below to a more general location. *)
+ +
+  Lemma InT_flat_map: forall (f : Seq -> list Seq) (l : list Seq) (y : Seq), (InT y (flat_map f l) -> (existsT2 x : Seq, InT x l * InT y (f x))) *
+                                                                                                                ( (existsT2 x : Seq, InT x l * InT y (f x)) -> InT y (flat_map f l)).
+  Proof.
+  intros f. induction l.
+  - intros ; split ; intros. simpl in H. inversion H. simpl. destruct H. destruct p. inversion i.
+  - intros ; simpl ; split ; intros. apply InT_app_or in H. destruct H. exists a ; split ; auto. apply InT_eq.
+    apply IHl in i. destruct i. destruct p. exists x ; split ; auto. apply InT_cons ; auto.
+    apply InT_or_app. destruct H. destruct p. inversion i ; subst ; auto. right.
+    apply IHl. exists x ; split ; auto.
+  Qed.
+ +
+  Lemma fold_Canopy : forall s leaf, InT leaf (Canopy s) ->
+                  (leaf = s) + (existsT2 prem, InT prem (inv_prems s) * InT leaf (Canopy prem)).
+  Proof.
+  intros. remember (finite_ImpRules_premises_of_S s) as J.
+  destruct J. destruct x.
+  - assert (Canopy s = [s]). apply irred_nil. unfold inv_prems. rewrite <- HeqJ.
+    simpl. auto. rewrite H0 in H. inversion H ; subst ; auto. inversion H2.
+  - right. unfold Canopy in H. rewrite irred_not in H. apply InT_flat_map in H. destruct H.
+    destruct p0. exists x0 ; split ; auto. intro. unfold inv_prems in H0. rewrite <- HeqJ in H0.
+    assert (InT l (l :: x)). apply InT_eq. apply p in H1. destruct H1 ; inversion i ; subst ;
+    simpl in H0 ; inversion H0.
+  Qed.
+ +
+  Lemma Canopy_equiprv : forall s,
+    ((forall leaf, InT leaf (Canopy s) -> KS_prv leaf) -> (KS_prv s)) *
+    ((KS_prv s) -> (forall leaf, InT leaf (Canopy s) -> KS_prv leaf)).
+  Proof.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  intros ; split ; intros.
+  - remember (finite_ImpRules_premises_of_S s) as H.
+    destruct H. destruct x.
+    + assert (Canopy s = [s]). apply irred_nil. unfold inv_prems. rewrite <- HeqH.
+       simpl. auto. rewrite H in X. apply X. apply InT_eq.
+    + assert (J1: InT l (l :: x)). apply InT_eq. apply p in J1. destruct J1 ; unfold KS_prv ; apply derI with (ps:=l).
+       apply ImpR ; auto. 2: apply ImpL ; auto. all: inversion i ; subst ; apply dlCons. 4: apply dlCons. 2,5: apply dlNil.
+       all: apply IHs. 1,3,5: unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       all: intros ; apply X. apply ImpRule_Canopy with (prems:=[(Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)]) (prem:=(Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)) ; auto.
+       apply InT_eq. apply ImpRule_Canopy with (prems:=[(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)])
+       (prem:=(Γ0 ++ Γ1, Δ0 ++ A :: Δ1)) ; auto. apply InT_eq.
+        apply ImpRule_Canopy with (prems:=[(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)])
+       (prem:=(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)) ; auto. apply InT_cons ; apply InT_eq.
+  - apply fold_Canopy in H. destruct H ; subst ; auto. destruct s0. destruct p.
+    unfold inv_prems in i ; apply InT_flatten_list_InT_elem in i ; destruct i ; destruct p ; destruct (finite_ImpRules_premises_of_S s) ;
+    simpl in i1. apply p in i1. destruct i1 ; inversion i1 ; subst.
+    + inversion i ; subst. 2: inversion H0. apply IHs with (y:=(Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)) ; auto.
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply ImpR_inv with (concl:=(Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1)) ; auto.
+    + inversion i ; subst. apply IHs with (y:=(Γ0 ++ Γ1, Δ0 ++ A :: Δ1)) ; auto.
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply ImpL_inv with (concl:=(Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)) (prem2:= (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)) ; auto.
+       inversion H0 ; subst. 2: inversion H1. apply IHs with (y:=(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)) ; auto.
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply ImpL_inv with (concl:=(Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)) (prem1:= (Γ0 ++ Γ1, Δ0 ++ A :: Δ1)) ; auto.
+  Qed.
+ +
+  Lemma Canopy_equiprv_genL : forall s A,
+    ((forall leaf, InT leaf (Canopy s) -> KS_prv (A :: fst leaf, snd leaf)) -> (KS_prv (A :: fst s, snd s))) *
+    ((KS_prv (A :: fst s, snd s)) -> (forall leaf, InT leaf (Canopy s) -> KS_prv (A :: fst leaf, snd leaf))).
+  Proof.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  intros ; split ; intros.
+  - remember (finite_ImpRules_premises_of_S s) as H0.
+    destruct H0. destruct x.
+    + assert (Canopy s = [s]). apply irred_nil. unfold inv_prems. rewrite <- HeqH0.
+       simpl. auto. rewrite H in X. apply X. apply InT_eq.
+    + assert (J1: InT l (l :: x)). apply InT_eq. apply p in J1. destruct J1 ; unfold KS_prv ; inversion i ; subst ; simpl.
+       apply derI with (ps:=[(A :: Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ1)]).
+       apply ImpR ; auto. assert ((A :: Γ0 ++ A0 :: Γ1) = ((A :: Γ0) ++ A0 :: Γ1)). auto. rewrite H.
+       assert (A :: Γ0 ++ Γ1 = (A :: Γ0) ++ Γ1). auto. rewrite H0. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+       2: apply derI with (ps:=[(A :: Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1);(A :: Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]).
+       2: apply ImpL ; auto. 2: assert (A :: Γ0 ++ Γ1 = ((A :: Γ0) ++ Γ1)) ; auto ; rewrite H.
+       2: assert (A :: Γ0 ++ B :: Γ1 = (A :: Γ0) ++ B :: Γ1) ; auto ; rewrite H0. 2: apply ImpLRule_I. 2: apply dlCons.
+       3: apply dlCons. 4: apply dlNil.
+       assert (J2: n_imp_subformS (Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ1) < n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A0 --> B :: Δ1)).
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply IHs with (A:=A) in J2. simpl in J2. destruct J2. apply k. intros. apply X.
+       apply ImpRule_Canopy with (prems:=[(Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ1)]) (prem:=(Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ1)) ; auto.
+       apply InT_eq.
+       assert (J2: n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1) < n_imp_subformS (Γ0 ++ A0 --> B :: Γ1, Δ0 ++ Δ1)).
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply IHs with (A:=A) in J2. simpl in J2. destruct J2. apply k. intros. apply X.
+       apply ImpRule_Canopy with (prems:=[(Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)])
+       (prem:=(Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1)) ; auto. apply InT_eq.
+       assert (J2: n_imp_subformS (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) < n_imp_subformS (Γ0 ++ A0 --> B :: Γ1, Δ0 ++ Δ1)).
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply IHs with (A:=A) in J2. simpl in J2. destruct J2. apply k. intros. apply X.
+       apply ImpRule_Canopy with (prems:=[(Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)])
+       (prem:=(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)) ; auto. apply InT_cons. apply InT_eq.
+  - apply fold_Canopy in H. destruct H ; subst ; auto. destruct s0. destruct p.
+    unfold inv_prems in i ; apply InT_flatten_list_InT_elem in i ; destruct i ; destruct p ; destruct (finite_ImpRules_premises_of_S s) ;
+    simpl in i1. apply p in i1. destruct i1 ; inversion i1 ; subst.
+    + inversion i ; subst. 2: inversion H0. apply IHs with (y:=(Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ1)) ; auto.
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply ImpR_inv with (concl:=(A :: Γ0 ++ Γ1, Δ0 ++ A0 --> B :: Δ1)) ; auto. simpl.
+       assert (A :: Γ0 ++ A0 :: Γ1 = (A :: Γ0) ++ A0 :: Γ1). auto. rewrite H.
+       assert (A :: Γ0 ++ Γ1 = (A :: Γ0) ++ Γ1). auto. rewrite H0. apply ImpRRule_I.
+    + inversion i ; subst. apply IHs with (y:=(Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1)) ; auto.
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply ImpL_inv with (concl:=(A :: Γ0 ++ A0 --> B :: Γ1, Δ0 ++ Δ1)) (prem2:= (A :: Γ0 ++ B :: Γ1, Δ0 ++ Δ1)) ; auto. simpl.
+       assert (A :: Γ0 ++ B :: Γ1 = (A :: Γ0) ++ B :: Γ1). auto. rewrite H.
+       assert (A :: Γ0 ++ Γ1 = (A :: Γ0) ++ Γ1). auto. rewrite H0. apply ImpLRule_I.
+       inversion H0 ; subst. 2: inversion H1. apply IHs with (y:=(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)) ; auto.
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply ImpL_inv with (concl:=(A :: Γ0 ++ A0 --> B :: Γ1, Δ0 ++ Δ1)) (prem1:= (A :: Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1)) ; auto. simpl.
+       assert (A :: Γ0 ++ B :: Γ1 = (A :: Γ0) ++ B :: Γ1). auto. rewrite H.
+       assert (A :: Γ0 ++ Γ1 = (A :: Γ0) ++ Γ1). auto. rewrite H1. apply ImpLRule_I.
+  Qed.
+ +
+  Lemma Canopy_equiprv_genR : forall s A,
+    ((forall leaf, InT leaf (Canopy s) -> KS_prv (fst leaf, A :: snd leaf)) -> (KS_prv (fst s, A :: snd s))) *
+    ((KS_prv (fst s, A :: snd s)) -> (forall leaf, InT leaf (Canopy s) -> KS_prv (fst leaf, A :: snd leaf))).
+  Proof.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  intros ; split ; intros.
+  - remember (finite_ImpRules_premises_of_S s) as H0.
+    destruct H0. destruct x.
+    + assert (Canopy s = [s]). apply irred_nil. unfold inv_prems. rewrite <- HeqH0.
+       simpl. auto. rewrite H in X. apply X. apply InT_eq.
+    + assert (J1: InT l (l :: x)). apply InT_eq. apply p in J1. destruct J1 ; unfold KS_prv ; inversion i ; subst ; simpl.
+       apply derI with (ps:=[(Γ0 ++ A0 :: Γ1, A :: Δ0 ++ B :: Δ1)]).
+       apply ImpR ; auto. assert ((A :: Δ0 ++ B :: Δ1) = ((A :: Δ0) ++ B :: Δ1)). auto. rewrite H.
+       assert (A :: Δ0 ++ A0 --> B :: Δ1 = (A :: Δ0) ++ A0 --> B :: Δ1). auto. rewrite H0. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+       2: apply derI with (ps:=[(Γ0 ++ Γ1, A :: Δ0 ++ A0 :: Δ1);(Γ0 ++ B :: Γ1, A :: Δ0 ++ Δ1)]).
+       2: apply ImpL ; auto. 2: assert (A :: Δ0 ++ Δ1 = ((A :: Δ0) ++ Δ1)) ; auto ; rewrite H.
+       2: assert (A :: Δ0 ++ A0 :: Δ1 = (A :: Δ0) ++ A0 :: Δ1) ; auto ; rewrite H0. 2: apply ImpLRule_I. 2: apply dlCons.
+       3: apply dlCons. 4: apply dlNil.
+       assert (J2: n_imp_subformS (Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ1) < n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A0 --> B :: Δ1)).
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply IHs with (A:=A) in J2. simpl in J2. destruct J2. apply k. intros. apply X.
+       apply ImpRule_Canopy with (prems:=[(Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ1)]) (prem:=(Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ1)) ; auto.
+       apply InT_eq.
+       assert (J2: n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1) < n_imp_subformS (Γ0 ++ A0 --> B :: Γ1, Δ0 ++ Δ1)).
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply IHs with (A:=A) in J2. simpl in J2. destruct J2. apply k. intros. apply X.
+       apply ImpRule_Canopy with (prems:=[(Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)])
+       (prem:=(Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1)) ; auto. apply InT_eq.
+       assert (J2: n_imp_subformS (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) < n_imp_subformS (Γ0 ++ A0 --> B :: Γ1, Δ0 ++ Δ1)).
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply IHs with (A:=A) in J2. simpl in J2. destruct J2. apply k. intros. apply X.
+       apply ImpRule_Canopy with (prems:=[(Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)])
+       (prem:=(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)) ; auto. apply InT_cons. apply InT_eq.
+  - apply fold_Canopy in H. destruct H ; subst ; auto. destruct s0. destruct p.
+    unfold inv_prems in i ; apply InT_flatten_list_InT_elem in i ; destruct i ; destruct p ; destruct (finite_ImpRules_premises_of_S s) ;
+    simpl in i1. apply p in i1. destruct i1 ; inversion i1 ; subst.
+    + inversion i ; subst. 2: inversion H0. apply IHs with (y:=(Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ1)) ; auto.
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply ImpR_inv with (concl:=(Γ0 ++ Γ1, A :: Δ0 ++ A0 --> B :: Δ1)) ; auto. simpl.
+       assert (A :: Δ0 ++ B :: Δ1 = (A :: Δ0) ++ B :: Δ1). auto. rewrite H.
+       assert (A :: Δ0 ++ A0 --> B :: Δ1 = (A :: Δ0) ++ A0 --> B :: Δ1). auto. rewrite H0. apply ImpRRule_I.
+    + inversion i ; subst. apply IHs with (y:=(Γ0 ++ Γ1, Δ0 ++ A0 :: Δ1)) ; auto.
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply ImpL_inv with (concl:=(Γ0 ++ A0 --> B :: Γ1, A :: Δ0 ++ Δ1)) (prem2:= (Γ0 ++ B :: Γ1, A :: Δ0 ++ Δ1)) ; auto. simpl.
+       assert (A :: Δ0 ++ A0 :: Δ1 = (A :: Δ0) ++ A0 :: Δ1). auto. rewrite H.
+       assert (A :: Δ0 ++ Δ1 = (A :: Δ0) ++ Δ1). auto. rewrite H0. apply ImpLRule_I.
+       inversion H0 ; subst. 2: inversion H1. apply IHs with (y:=(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)) ; auto.
+       unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+       apply ImpL_inv with (concl:=(Γ0 ++ A0 --> B :: Γ1, A :: Δ0 ++ Δ1)) (prem1:= (Γ0 ++ Γ1, A :: Δ0 ++ A0 :: Δ1)) ; auto. simpl.
+       assert (A :: Δ0 ++ A0 :: Δ1 = (A :: Δ0) ++ A0 :: Δ1). auto. rewrite H.
+       assert (A :: Δ0 ++ Δ1 = (A :: Δ0) ++ Δ1). auto. rewrite H1. apply ImpLRule_I.
+  Qed.
+ +
+  Lemma Canopy_hp_inv_ctx : forall s k scomp (D0 : KS_prv scomp) X0 Y0,
+        k = (derrec_height D0) ->
+        scomp = (fst s ++ X0, snd s ++ Y0) ->
+        (forall leaf, InT leaf (Canopy s) -> existsT2 (D1: KS_prv (fst leaf ++ X0, snd leaf ++ Y0)),
+                                                                                derrec_height D1 <= k).
+  Proof.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  intros. apply fold_Canopy in H1. destruct H1.
+  - subst. exists D0 ; auto.
+  - destruct s0 ; destruct p. unfold inv_prems in i. apply InT_flatten_list_InT_elem in i. destruct i.
+    destruct p. destruct (finite_ImpRules_premises_of_S s). simpl in i1. subst.
+    assert (J0: derrec_height D0 = derrec_height D0). auto.
+    pose (ImpR_ImpL_hpinv _ _ D0 J0). destruct p0. apply p in i1. destruct i1.
+    + inversion i1 ; subst. simpl in s0.
+       assert (J1: ImpRRule [(Γ0 ++ A :: (Γ1 ++ X0), Δ0 ++ B :: (Δ1 ++ Y0))] ((Γ0 ++ Γ1) ++ X0, (Δ0 ++ A --> B :: Δ1) ++ Y0)).
+       repeat rewrite <- app_assoc ; apply ImpRRule_I. apply s0 in J1. destruct J1. inversion i ; subst.
+       assert (J2: n_imp_subformS (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) < n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1)).
+       unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+       lia.
+       assert (J3: derrec_height x0 = derrec_height x0). auto.
+       assert (J4: (Γ0 ++ A :: Γ1 ++ X0, Δ0 ++ B :: Δ1 ++ Y0) = (fst (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) ++ X0, snd (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) ++ Y0)).
+       simpl ; repeat rewrite <- app_assoc ; auto.
+       pose (IHs _ J2 _ _ x0 X0 Y0 J3 J4 _ i0). destruct s. exists x. apply PeanoNat.Nat.le_trans with (m:=derrec_height x0) ; auto.
+       inversion H0.
+    + inversion i1 ; subst. simpl in s1. clear s0.
+       assert (J1: ImpLRule [(Γ0 ++ Γ1 ++ X0, Δ0 ++ A :: Δ1 ++ Y0); (Γ0 ++ B :: Γ1 ++ X0, Δ0 ++ Δ1 ++ Y0)] ((Γ0 ++ A --> B :: Γ1) ++ X0, (Δ0 ++ Δ1) ++ Y0)).
+       repeat rewrite <- app_assoc ; apply ImpLRule_I. apply s1 in J1. destruct J1. destruct s. destruct p0. inversion i ; subst.
+       assert (J2: n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+       unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+       lia.
+       assert (J3: derrec_height x0 = derrec_height x0). auto.
+       assert (J4: (Γ0 ++ Γ1 ++ X0, Δ0 ++ A :: Δ1 ++ Y0) = (fst (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) ++ X0, snd (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) ++ Y0)).
+       simpl ; repeat rewrite <- app_assoc ; auto.
+       pose (IHs _ J2 _ _ x0 X0 Y0 J3 J4 _ i0). destruct s. exists x. apply PeanoNat.Nat.le_trans with (m:=derrec_height x0) ; auto.
+       inversion H0 ; subst.
+       assert (J2: n_imp_subformS (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+       unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+       lia.
+       assert (J3: derrec_height x2 = derrec_height x2). auto.
+       assert (J4: (Γ0 ++ B :: Γ1 ++ X0, Δ0 ++ Δ1 ++ Y0) = (fst (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) ++ X0, snd (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) ++ Y0)).
+       simpl ; repeat rewrite <- app_assoc ; auto.
+       pose (IHs _ J2 _ _ x2 X0 Y0 J3 J4 _ i0). destruct s. exists x. apply PeanoNat.Nat.le_trans with (m:=derrec_height x2) ; auto.
+       inversion H1.
+  Qed.
+ +
+  Lemma Canopy_neg_var : forall s q, InT (# q) (fst s) -> (forall leaf, InT leaf (Canopy s) -> InT (# q) (fst leaf)).
+  Proof.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  intros. apply fold_Canopy in H0. destruct H0 ; subst ; auto.
+  destruct s0 ; destruct p. unfold inv_prems in i. apply InT_flatten_list_InT_elem in i. destruct i.
+  destruct p. destruct (finite_ImpRules_premises_of_S s). simpl in i1. subst.
+  apply p in i1. destruct i1.
+  - inversion i1 ; subst. inversion i ; subst. 2: inversion H1.
+    assert (J0: n_imp_subformS (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) < n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1)).
+     unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+     lia.
+    apply IHs with (q:= q) (leaf:=leaf) in J0 ; auto. simpl. apply InT_or_app. simpl in H. apply InT_app_or in H ; destruct H ; auto.
+    right ; apply InT_cons ; auto.
+  - inversion i1 ; subst. inversion i ; subst. 2: inversion H1. 3: inversion H2.
+    assert (J0: n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+     unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+     lia.
+    apply IHs with (q:= q) (leaf:=leaf) in J0 ; auto. simpl. apply InT_or_app. simpl in H. apply InT_app_or in H ; destruct H ; auto.
+    inversion i2 ; subst. inversion H0. auto. subst.
+    assert (J0: n_imp_subformS (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+     unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+     lia.
+    apply IHs with (q:= q) (leaf:=leaf) in J0 ; auto. simpl. apply InT_or_app. simpl in H. apply InT_app_or in H ; destruct H ; auto.
+    inversion i2 ; subst. inversion H0. right ; apply InT_cons ; auto.
+  Qed.
+ +
+  Lemma Canopy_pos_var : forall s q, InT (# q) (snd s) -> (forall leaf, InT leaf (Canopy s) -> InT (# q) (snd leaf)).
+  Proof.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  intros. apply fold_Canopy in H0. destruct H0 ; subst ; auto.
+  destruct s0 ; destruct p. unfold inv_prems in i. apply InT_flatten_list_InT_elem in i. destruct i.
+  destruct p. destruct (finite_ImpRules_premises_of_S s). simpl in i1. subst.
+  apply p in i1. destruct i1.
+  - inversion i1 ; subst. inversion i ; subst. 2: inversion H1.
+    assert (J0: n_imp_subformS (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) < n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1)).
+     unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+     lia.
+    apply IHs with (q:= q) (leaf:=leaf) in J0 ; auto. simpl. apply InT_or_app. simpl in H. apply InT_app_or in H ; destruct H ; auto.
+    inversion i2 ; subst. inversion H0. right ; apply InT_cons ; auto.
+  - inversion i1 ; subst. inversion i ; subst. 2: inversion H1. 3: inversion H2.
+    assert (J0: n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+     unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+     lia.
+    apply IHs with (q:= q) (leaf:=leaf) in J0 ; auto. simpl. apply InT_or_app. simpl in H. apply InT_app_or in H ; destruct H ; auto.
+    right ; apply InT_cons ; auto. subst.
+    assert (J0: n_imp_subformS (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+     unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+     lia.
+    apply IHs with (q:= q) (leaf:=leaf) in J0 ; auto.
+  Qed.
+ +
+  Lemma Id_InT_Canopy : forall s, InT s (Canopy s) -> Canopy s = [s].
+  Proof.
+  intros. destruct (critical_Seq_dec s).
+  - remember (finite_ImpRules_premises_of_S s) as J.
+    destruct J. destruct x.
+    + apply irred_nil. unfold inv_prems. rewrite <- HeqJ.
+       simpl. auto.
+    + exfalso. assert (J1: InT l (l :: x)). apply InT_eq. apply p in J1. unfold critical_Seq in c.
+       destruct J1 ; inversion i ; subst ; simpl in c.
+       assert (In (A --> B) ((Γ0 ++ Γ1) ++ Δ0 ++ A --> B :: Δ1)). apply in_or_app ; right ; apply in_or_app ; right ; apply in_eq.
+       apply c in H0. destruct H0. destruct H0. inversion H0. destruct H0. destruct H0 ; inversion H0. inversion H0.
+       assert (In (A --> B) ((Γ0 ++ A --> B :: Γ1) ++ Δ0 ++ Δ1)). apply in_or_app ; left ; apply in_or_app ; right ; apply in_eq.
+       apply c in H0. destruct H0. destruct H0. inversion H0. destruct H0. destruct H0 ; inversion H0. inversion H0.
+  - exfalso. apply Canopy_critical in H. auto.
+  Qed.
+ +
+  Lemma critical_Seq_InT_Canopy : forall s, critical_Seq s -> InT s (Canopy s).
+  Proof.
+  intros. remember (finite_ImpRules_premises_of_S s) as J.
+  destruct J. destruct x.
+  + pose irred_nil. unfold Canopy. rewrite e. apply InT_eq. unfold inv_prems. rewrite <- HeqJ.
+     simpl. auto.
+  + exfalso. assert (J1: InT l (l :: x)). apply InT_eq. apply p in J1. unfold critical_Seq in H.
+     destruct J1 ; inversion i ; subst ; simpl in H.
+     assert (In (A --> B) ((Γ0 ++ Γ1) ++ Δ0 ++ A --> B :: Δ1)). apply in_or_app ; right ; apply in_or_app ; right ; apply in_eq.
+     apply H in H0. destruct H0. destruct H0. inversion H0. destruct H0. destruct H0 ; inversion H0. inversion H0.
+     assert (In (A --> B) ((Γ0 ++ A --> B :: Γ1) ++ Δ0 ++ Δ1)). apply in_or_app ; left ; apply in_or_app ; right ; apply in_eq.
+     apply H in H0. destruct H0. destruct H0. inversion H0. destruct H0. destruct H0 ; inversion H0. inversion H0.
+  Qed.
+
+
+ +
+ + + diff --git a/K.Interpolation.UIK_Def_measure.html b/K.Interpolation.UIK_Def_measure.html new file mode 100644 index 0000000..00c0f5e --- /dev/null +++ b/K.Interpolation.UIK_Def_measure.html @@ -0,0 +1,163 @@ + + + + + + + + + + + + + +
+
+

K.Interpolation.UIK_Def_measure

+ +
+(* Modification of the following file. *)
+ +
+(**************************************************************)
+(*   Copyright Dominique Larchey-Wendling *                 *)
+(*                                                            *)
+(*                             * Affiliation LORIA -- CNRS  *)
+(**************************************************************)
+(*      This file is distributed under the terms of the       *)
+(*         CeCILL v2 FREER SOFTWARE LICENSE AGREEMENT         *)
+(**************************************************************)
+ +
+Require Import List Arith Wellfounded.
+Import ListNotations.
+ +
+Set Implicit Arguments.
+ +
+Section measure_rect.
+ +
+  Variable (X : Type) (m : X -> nat) (P : X -> Type).
+ +
+  Hypothesis F : forall x, (forall y, m y < m x -> P y) -> P x.
+ +
+  Definition measure_rect x : P x.
+  Proof.
+    cut (Acc (fun x y => m x < m y) x); [ revert x | ].
+    + refine (
+        fix loop x Dx := @F x (fun y Dy => loop y _)
+      ).
+      apply (Acc_inv Dx), Dy.
+    + apply wf_inverse_image with (f := m), lt_wf.
+  Qed.
+ +
+End measure_rect.
+ +
+Tactic Notation "induction" "on" hyp(x) "as" ident(IH) "with" "measure" uconstr(f) :=
+  pattern x; revert x; apply measure_rect with (m := fun x => f); intros x IH.
+ +
+Section lex_wf.
+ +
+  Variable (X : Type) (R : X -> X -> Prop) (Rwf : well_founded R).
+ +
+  Reserved Notation "l '<lex' m" (at level 70). (* for lexicographic product *)
+ +
+  Inductive lex : list X -> list X -> Prop :=
+    | lex_skip x l m : l <lex m -> x::l <lex x::m
+    | lex_cons x y l m : length l = length m -> R x y -> x::l <lex y::m
+  where "l <lex m" := (lex l m).
+ +
+  Fact lex_length l m : l <lex m -> length l = length m.
+  Proof. induction 1; simpl; auto. Qed.
+ +
+  Fact lex_cons_inv l m :
+          l <lex m
+       -> match m with
+            | [] => False
+            | y::m =>
+            match l with
+              | [] => False
+              | x::l => x = y /\ lex l m
+                     \/ R x y /\ length l = length m
+            end
+          end.
+  Proof. inversion 1; auto. Qed.
+ +
+  Theorem lex_wf : well_founded lex.
+  Proof.
+    intros m; induction on m as IHm with measure (length m).
+    destruct m as [ | y m ].
+    + constructor; intros l Hl; apply lex_cons_inv in Hl; easy.
+    + revert m IHm.
+      induction y as [ y IHy' ] using (well_founded_induction Rwf).
+      intros m IHm.
+      assert (Acc lex m) as Hm.
+      1: apply IHm; simpl; auto.
+      assert (forall x l, R x y -> length l = length m -> Acc lex (x::l)) as IHy.
+      1: { intros x l Hx Hl; apply IHy'; auto.
+           intros; apply IHm.
+           simpl in *; rewrite <- Hl; auto. }
+      clear IHy' IHm.
+      revert Hm IHy.
+      induction 1 as [ m Hm IHm ]; intros IHy.
+      constructor; intros l Hl; apply lex_cons_inv in Hl.
+      destruct l as [ | x l ]; try tauto.
+      destruct Hl as [ (-> & Hl) | (Hx & Hl) ].
+      * apply IHm; auto.
+        apply lex_length in Hl as ->; auto.
+      * apply IHy; auto.
+  Qed.
+ +
+  Section lex_rect.
+ +
+    Variable (P : list X -> Type) (HP : forall m, (forall l, lex l m -> P l) -> P m).
+ +
+    Corollary lex_rect m : P m.
+    Proof.
+      induction m as [ m IHm ] using (well_founded_induction_type lex_wf).
+      apply HP; intros; apply IHm. auto.
+    Qed.
+ +
+  End lex_rect.
+ +
+End lex_wf.
+
+
+ +
+ + + diff --git a/K.Interpolation.UIK_UIOne.html b/K.Interpolation.UIK_UIOne.html new file mode 100644 index 0000000..9d2bbf9 --- /dev/null +++ b/K.Interpolation.UIK_UIOne.html @@ -0,0 +1,166 @@ + + + + + + + + + + + + + +
+
+

K.Interpolation.UIK_UIOne

+ +
+(* First property of uniform interpolation *)
+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat Arith.
+Require Import Lia.
+Require Import String.
+ +
+Require Import general_export.
+ +
+Require Import KS_export.
+ +
+Require Import UIK_Def_measure.
+Require Import UIK_Canopy.
+Require Import UIK_irred_short.
+Require Import UIK_braga.
+Require Import UIK_UI_prelims.
+ +
+  Section UIPOne.
+ +
+  (* The formula defined by the function UI satisfies all the properties of
+      uniform interpolation. *)

+ +
+  Theorem UI_One : forall s p q, In (# q) (propvar_subform (UI p (fst s, snd s))) ->
+                                                      ((q <> p) * (In (# q) (propvar_subform_list (fst s ++ snd s)))).
+  Proof.
+  intro s. remember (measure s) as n. revert Heqn. revert s. revert n.
+  induction n as [n IH] using (well_founded_induction_type lt_wf).
+  intros s Heqn p q H0. rewrite propvar_subform_list_app.
+  destruct (empty_seq_dec s).
+  (* s is the empty sequent. *)
+  { subst ; simpl in *. assert (H : GUI p ([],[]) Bot) by (apply GUI_empty_seq ; auto). apply UI_GUI in H.
+    rewrite H in *. simpl in H0. inversion H0. }
+  (* s is not the empty sequent. *)
+  { destruct (critical_Seq_dec s).
+  (* s is a critical sequent *)
+  - destruct (dec_KS_init_rules s).
+    (* s is an initial sequent *)
+    + assert (is_init s) ; auto.
+       assert (H1 : GUI p s Top) by (apply GUI_critic_init ; auto). apply UI_GUI in H1.
+       destruct s. simpl in H0. rewrite H1 in H0. simpl in H0. inversion H0.
+    (* s is not an initial sequent *)
+    + remember (fst s) as LHS.
+       assert (H1 : GUI p s
+       (Or (list_disj (restr_list_prop p (snd s)))
+       (Or (list_disj (map Neg (restr_list_prop p (fst s))))
+       (Or (list_disj (map Box (map (UI p) (KR_prems s))))
+       (Diam (UI p (unboxed_list (top_boxes (fst s)), []%list))))))).
+       apply GUI_critic_not_init ; auto. apply Gimap_map ; intros. 1-2: apply UI_GUI ; auto.
+       destruct s. simpl in *. apply UI_GUI in H1. simpl in HeqLHS. subst. rewrite H1 in H0. simpl in H0.
+       repeat rewrite app_nil_r in H0. clear H1.
+       apply in_app_or in H0. destruct H0 as [H0 | H0].
+ +
+       apply propvar_subform_list_disj in H0.
+       apply propvar_subform_list_restr_list_prop in H0. destruct H0 ; split ; auto. apply in_or_app ; auto.
+ +
+       apply in_app_or in H0 ; destruct H0 as [H0 | H0]. apply propvar_subform_list_disj in H0. apply propvar_subform_list_witness in H0.
+       destruct H0. destruct H. apply in_map_iff in H. destruct H. destruct H ; subst. simpl in H0.
+       rewrite app_nil_r in H0. unfold restr_list_prop in H1. apply in_remove in H1. destruct H1.
+       pose (In_list_prop_LF _ _ H). destruct p0. destruct s. subst. simpl in H0. destruct H0. inversion H0. subst.
+       destruct (string_dec q p). exfalso ; apply H1 ; subst ; auto. split ; auto. apply in_or_app ; left.
+       apply list_prop_LF_propvar_subform_list in H ; auto. inversion H0.
+ +
+       apply in_app_or in H0 ; destruct H0. apply propvar_subform_list_disj in H. apply propvar_subform_list_witness in H.
+       destruct H. destruct H. apply in_map_iff in H. destruct H. destruct H ; subst. simpl in H0.
+       apply in_map_iff in H1. destruct H1. destruct H ; subst. assert (In # q (propvar_subform (UI p (fst x, snd x)))).
+       destruct x ; auto.
+       unfold KR_prems in H1. destruct (finite_KR_premises_of_S (l, l0)). simpl in H1.
+       apply In_InT_seqs in H1. apply InT_flatten_list_InT_elem in H1. destruct H1. destruct p1.
+       apply p0 in i0. inversion i0 ; subst. inversion i ; subst. 2: inversion X0. simpl in H. repeat rewrite propvar_subform_list_app.
+       simpl ; repeat rewrite propvar_subform_list_app.
+       assert (J0: measure (unboxed_list , [A]) < measure (l, Δ0 ++ Box A :: Δ1)).
+       unfold measure. simpl. repeat rewrite size_LF_dist_app. simpl.
+       pose (size_nobox_gen_ext _ _ X). simpl in l.
+       pose (size_unboxed ). lia.
+       assert (J1: measure (unboxed_list , [A]) = measure (unboxed_list , [A])). auto.
+       pose (IH _ J0 _ J1 _ _ H0). destruct p1. split ; auto. simpl in i1.
+       rewrite propvar_subform_list_app in i1. apply in_app_or in i1. destruct i1.
+       apply in_or_app ; left. apply propvar_subform_list_unboxed_list in H1.
+       pose (propvar_subform_list_nobox_gen_ext _ _ X). simpl in i1. apply i1 ; auto.
+       simpl in H1. rewrite app_nil_r in H1.
+       apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+ +
+       destruct l ; subst ; simpl in *.
+       { assert (GUI p ([],[]) Bot). apply GUI_empty_seq ; auto. apply UI_GUI in H0.
+         rewrite H0 in *. simpl in H. inversion H. }
+       { assert (J0: measure (unboxed_list (top_boxes (m :: l)), []%list) < measure (m :: l, l0)).
+         unfold measure. simpl. destruct m ; simpl.
+         1-4: pose (size_unboxed (top_boxes l)) ; pose (size_top_boxes l) ; lia.
+         assert (J1: measure (unboxed_list (top_boxes (m :: l)), []%list) = measure (unboxed_list (top_boxes (m :: l)), []%list)). auto.
+         pose (IH _ J0 _ J1). simpl in p0. pose (p0 _ _ H). destruct p1. split ; auto. simpl in i. clear p0.
+         rewrite propvar_subform_list_app in i. apply in_app_or in i. destruct i.
+         apply in_or_app ; left. apply propvar_subform_list_unboxed_list in H0.
+         apply in_or_app. destruct m ; simpl in H0 ; auto.
+         1-3: right ; apply propvar_subform_list_top_boxes ; auto. simpl.
+         apply in_app_or in H0 ; destruct H0 ; auto. right. apply propvar_subform_list_top_boxes ; auto.
+         simpl in H0. inversion H0. }
+  (* s is not a critical sequent *)
+  - assert (H1 : GUI p s (list_conj (map (UI p) (Canopy s)))). apply GUI_not_critic ; auto.
+    apply Gimap_map ; intros ; apply UI_GUI ; auto. apply UI_GUI in H1. destruct s.
+    simpl in H0. rewrite H1 in H0. apply propvar_subform_list_conj in H0.
+    apply propvar_subform_list_witness in H0. destruct H0 as [s [H0 H3]].
+    apply in_map_iff in H0.
+    destruct H0 as [x0 H0]. destruct H0 as [H0 Hc]; subst. simpl.
+    assert (H2 : In # q (propvar_subform (UI p (fst x0, snd x0)))) by (destruct x0 ; auto).
+    pose (i := In_InT_seqs _ _ Hc). apply Canopy_measure in i. destruct i ; subst.
+    simpl in *. exfalso. apply f. apply In_InT_seqs in Hc ; apply Canopy_critical in Hc ; auto.
+    assert (measure x0 = measure x0) ; auto.
+    pose (IH _ l1 _ H _ _ H2). destruct p0 ; split ; auto.
+    apply propvar_subform_list_Canopy with (A:=# q) in Hc ; auto.
+    simpl in H3 ; rewrite propvar_subform_list_app in Hc ; auto. }
+  Qed.
+ +
+  End UIPOne.
+
+
+ +
+ + + diff --git a/K.Interpolation.UIK_UIThree.html b/K.Interpolation.UIK_UIThree.html new file mode 100644 index 0000000..4ba853f --- /dev/null +++ b/K.Interpolation.UIK_UIThree.html @@ -0,0 +1,709 @@ + + + + + + + + + + + + + +
+
+

K.Interpolation.UIK_UIThree

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat Arith.
+Require Import Lia.
+ +
+Require Import general_export.
+ +
+Require Import KS_export.
+ +
+Require Import UIK_Def_measure.
+Require Import UIK_Canopy.
+Require Import UIK_irred_short.
+Require Import UIK_braga.
+Require Import UIK_UI_prelims.
+ +
+  Section UIPThree.
+ +
+  Theorem UI_Three : forall s p X0 Y0,
+                                    (In (Var p) (propvar_subform_list (X0 ++ Y0)) -> False) ->
+                                    KS_prv (fst s ++ X0, snd s ++ Y0) ->
+                                    KS_prv (X0, (UI p s) :: Y0).
+  Proof.
+  (* Setting up the strong induction on the height of the derivation (PIH) and
+      on the measure of the sequent using LexSeq (SIH). *)

+  intros s p X0 Y0 NotVar D. generalize dependent NotVar. remember (fst s ++ X0, snd s ++ Y0) as scomp.
+  generalize dependent Heqscomp. remember (derrec_height D) as n. generalize dependent Heqn.
+  generalize dependent Y0. generalize dependent X0. generalize dependent D.
+  generalize dependent scomp. generalize dependent s. generalize dependent n.
+  induction n as [n PIH] using (well_founded_induction_type lt_wf).
+  intro s. remember (measure s) as m. revert Heqm. revert s. revert m.
+  induction m as [m SIH] using (well_founded_induction_type lt_wf).
+  intros k Heqm.
+ +
+  (* Now we do the actual proof-theoretical work. *)
+  intros s0 D0. remember D0 as D0'. destruct D0.
+  (* D0 is a leaf *)
+  - inversion f.
+  (* D0 ends with an application of rule *)
+  - intros X0 Y0 hei idseq propvar. destruct (empty_seq_dec k) as [ EE | NE].
+    { subst ; simpl in *.
+       assert (J1: KS_prv (X0, Y0)). apply derI with ps ; auto.
+       pose (KS_hpadm_wkn_R _ J1 (X0, UI p ([], []) :: Y0) (UI p ([],[]))). destruct s ; auto.
+       apply (wkn_RI _ _ []). }
+    { inversion k0 ; subst.
+    (* IdP *)
+    * inversion H ; subst.
+      assert (InT (# P) (fst k ++ X0)). rewrite <- H2. apply InT_or_app ; right ; apply InT_eq.
+      apply InT_app_or in H0.
+      assert (InT (# P) (snd k ++ Y0)). rewrite <- H3. apply InT_or_app ; right ; apply InT_eq.
+      apply InT_app_or in H1. destruct H0 ; destruct H1.
+      + assert ((X0, UI p k :: Y0) = (X0, [] ++ UI p k :: Y0)). auto. rewrite H0. apply is_init_UI.
+         left. destruct k. simpl in i ; simpl in i0. apply InT_split in i. destruct i. destruct s ; subst.
+         apply InT_split in i0. destruct i0. destruct s ; subst. apply IdPRule_I.
+      + destruct (critical_Seq_dec k).
+         -- destruct (dec_KS_init_rules k).
+            ** assert (is_init k) ; auto. assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+                pose (@GUI_inv_critic_init p k _ J0 c X). rewrite <- e.
+                assert ((X0, Top :: Y0) = (X0, [] ++ Top :: Y0)). auto. rewrite H0. apply TopR.
+            ** assert ((is_init k) -> False) ; auto. assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+                assert (J1: Gimap (GUI p) (KR_prems k) (map (UI p) (KR_prems k))). apply Gimap_map. intros.
+                apply UI_GUI ; auto.
+                assert (k <> ([],[])). intro. rewrite H1 in i. inversion i.
+                assert (J2: GUI p (unboxed_list (top_boxes (fst k)), []) (UI p (unboxed_list (top_boxes (fst k)), []))). apply UI_GUI ; auto.
+                pose (@GUI_inv_critic_not_init p k _ _ _ J0 c H1 H0 J1 J2). rewrite <- e.
+                pose (OrR (X0,Y0)). simpl in k1. apply k1.
+                apply (@KS_adm_list_exch_R (X0,
+                Or (list_disj (map Neg (restr_list_prop p (fst k))))
+                   (Or (list_disj (map Box (map (UI p) (KR_prems k))))
+                      (Diam (UI p (unboxed_list (top_boxes (fst k)), []%list))))
+                 :: list_disj (restr_list_prop p (snd k)) :: Y0)).
+                2: epose (list_exch_RI _ [] [Or (list_disj (map Neg (restr_list_prop p (fst k)))) (Or (list_disj (map Box (map (UI p) (KR_prems k))))
+                (Diam (UI p (unboxed_list (top_boxes (fst k)), []%list))))] [] [list_disj (restr_list_prop p (snd k))] Y0) ; simpl in l ; apply l.
+                pose (OrR (X0,list_disj (restr_list_prop p (snd k)) :: Y0)). simpl in k2. apply k2.
+                assert (J3: InT (Neg # P) (map Neg (restr_list_prop p (fst k)))). unfold restr_list_prop. apply InT_map_iff.
+                exists (# P) ; split ; auto. apply In_InT. apply in_not_touched_remove. apply In_list_In_list_prop_LF ; apply InT_In ; auto.
+                intro. apply propvar. rewrite <- H4. rewrite propvar_subform_list_app. apply in_or_app ; right.
+                apply In_list_In_propvar_subform_list ; apply InT_In ; auto.
+                remember (Or (list_disj (map Box (map (UI p) (KR_prems k)))) (Diam (UI p (unboxed_list (top_boxes (fst k)), []%list)))
+                 :: list_disj (restr_list_prop p (snd k)) :: Y0) as Y.
+                pose (list_disj_wkn_R (map Neg (restr_list_prop p (fst k))) (X0, Y) (Neg # P) J3). apply k3. simpl.
+                unfold Neg. apply derI with (ps:=[([] ++ # P :: X0, [] ++ Bot :: Y)]). apply ImpR. assert ((X0, # P --> Bot :: Y) = ([] ++ X0, [] ++ # P --> Bot :: Y)).
+                auto. rewrite H4. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+                assert (InT (# P) ([] ++ Bot :: Y)). simpl. apply InT_cons. rewrite HeqY. repeat apply InT_cons ; auto.
+                apply InT_split in H4. destruct H4. destruct s. rewrite e0. apply derI with (ps:=[]). apply IdP. apply IdPRule_I.
+                apply dlNil.
+         -- assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+            assert (J1: Gimap (GUI p) (Canopy k) (map (UI p) (Canopy k))). apply Gimap_map. intros.
+            apply UI_GUI ; auto.
+            pose (@GUI_inv_not_critic p k _ _ J0 f J1). rewrite <- e.
+            pose (list_conj_R (map (UI p) (Canopy k)) (X0,Y0)). simpl in k1. apply k1. intros.
+            apply InT_map_iff in H0. destruct H0. destruct p0. subst.
+            assert (measure x < measure k). pose (Canopy_measure _ _ i1). destruct s ; subst ; auto. exfalso.
+            apply f ; apply Canopy_critical in i1 ; auto. simpl in SIH.
+            assert (J2: KS_rules [] (fst x ++ X0, snd x ++ Y0)).
+            apply IdP. assert (InT (# P) (snd x ++ Y0)). apply InT_or_app ; auto. apply InT_split in H1.
+            destruct H1. destruct s. rewrite e0. assert (InT (# P) (fst x ++ X0)). apply InT_or_app ; left.
+            apply Canopy_neg_var with (q:=P) in i1 ; auto. apply InT_split in H1. destruct H1. destruct s. rewrite e1.
+            apply IdPRule_I. pose (derI _ J2 d).
+            assert (J3: S (dersrec_height d) = derrec_height d0). simpl. lia.
+            assert (J4: (fst x ++ X0, snd x ++ Y0) = (fst x ++ X0, snd x ++ Y0)). auto.
+            assert (J5 : measure x = measure x). auto.
+            pose (SIH _ H0 _ J5 _ _ _ _ J3 J4 propvar). auto.
+      + destruct (critical_Seq_dec k).
+         -- destruct (dec_KS_init_rules k).
+            ** assert (is_init k) ; auto. assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+                pose (@GUI_inv_critic_init p k _ J0 c X). rewrite <- e.
+                assert ((X0, Top :: Y0) = (X0, [] ++ Top :: Y0)). auto. rewrite H0. apply TopR.
+            ** assert ((is_init k) -> False) ; auto. assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+                assert (J1: Gimap (GUI p) (KR_prems k) (map (UI p) (KR_prems k))). apply Gimap_map. intros.
+                apply UI_GUI ; auto.
+                assert (J2: GUI p (unboxed_list (top_boxes (fst k)), []) (UI p (unboxed_list (top_boxes (fst k)), []))). apply UI_GUI ; auto.
+                remember (fst k) as LHS. destruct LHS.
+                ++ pose (@GUI_inv_critic_not_init p k _ (UI p (unboxed_list (top_boxes []), [])) _ J0 c NE H0 J1).
+                      simpl in e. rewrite <- HeqLHS in *. apply e in J2. rewrite <- J2. simpl in *.
+                      assert (GUI p ([],[]) Bot). apply GUI_empty_seq ; auto. apply UI_GUI in H1. rewrite H1 in *.
+                      pose (OrR (X0,Y0)). simpl in k1. apply k1.
+                      assert (J3: InT (# P) (restr_list_prop p (snd k))). unfold restr_list_prop. apply In_InT.
+                      apply in_not_touched_remove. apply In_list_In_list_prop_LF ; apply InT_In ; auto.
+                      intro. apply propvar. rewrite <- H4. rewrite propvar_subform_list_app. apply in_or_app ; left.
+                      apply In_list_In_propvar_subform_list ; apply InT_In ; auto.
+                      remember (Or (Or (list_disj (map Box (map (UI p) (KR_prems k)))) (Diam )) :: Y0) as Y.
+                      pose (list_disj_wkn_R (restr_list_prop p (snd k)) (X0, Y) (# P) J3). apply k2. simpl.
+                      apply InT_split in i. destruct i. destruct s. rewrite e0. apply derI with (ps:=[]). apply IdP. 2: apply dlNil.
+                      assert ((x ++ # P :: x0, # P :: Y) = (x ++ # P :: x0, [] ++ # P :: Y)). auto. rewrite H4 ; apply IdPRule_I.
+                ++ assert (J4 : fst k <> []). intro. rewrite H1 in HeqLHS. inversion HeqLHS. rewrite HeqLHS in J2.
+                      pose (@GUI_inv_critic_not_init p k _ _ _ J0 c NE H0 J1 J2). rewrite <- e.
+                      pose (OrR (X0,Y0)). simpl in k1. apply k1.
+                      assert (J3: InT (# P) (restr_list_prop p (snd k))). unfold restr_list_prop. apply In_InT.
+                      apply in_not_touched_remove. apply In_list_In_list_prop_LF ; apply InT_In ; auto.
+                      intro. apply propvar. rewrite <- H1. rewrite propvar_subform_list_app. apply in_or_app ; left.
+                      apply In_list_In_propvar_subform_list ; apply InT_In ; auto.
+                      remember (Or (list_disj (map Neg (restr_list_prop p (fst k)))) (Or (list_disj (map Box (map (UI p) (KR_prems k)))) (Diam
+                      (UI p (unboxed_list (top_boxes (fst k)), []%list)))) :: Y0) as Y.
+                      pose (list_disj_wkn_R (restr_list_prop p (snd k)) (X0, Y) (# P) J3). apply k2. simpl.
+                      apply InT_split in i. destruct i. destruct s. rewrite e0. apply derI with (ps:=[]). apply IdP. 2: apply dlNil.
+                      assert ((x ++ # P :: x0, # P :: Y) = (x ++ # P :: x0, [] ++ # P :: Y)). auto. rewrite H1 ; apply IdPRule_I.
+         -- assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+            assert (J1: Gimap (GUI p) (Canopy k) (map (UI p) (Canopy k))). apply Gimap_map. intros.
+            apply UI_GUI ; auto.
+            pose (@GUI_inv_not_critic p k _ _ J0 f J1). rewrite <- e.
+            pose (list_conj_R (map (UI p) (Canopy k)) (X0,Y0)). simpl in k1. apply k1. intros.
+            apply InT_map_iff in H0. destruct H0. destruct p0. subst.
+            assert (measure x < measure k). pose (Canopy_measure _ _ i1). destruct s ; subst ; auto. exfalso.
+            apply f ; apply Canopy_critical in i1 ; auto. simpl in SIH.
+            assert (J2: KS_rules [] (fst x ++ X0, snd x ++ Y0)).
+            apply IdP. assert (InT (# P) (fst x ++ X0)). apply InT_or_app ; auto. apply InT_split in H1.
+            destruct H1. destruct s. rewrite e0. assert (InT (# P) (snd x ++ Y0)). apply InT_or_app ; left.
+            apply Canopy_pos_var with (q:=P) in i1 ; auto. apply InT_split in H1. destruct H1. destruct s. rewrite e1.
+            apply IdPRule_I. pose (derI _ J2 d).
+            assert (J3: S (dersrec_height d) = derrec_height d0). simpl. lia.
+            assert (J4: (fst x ++ X0, snd x ++ Y0) = (fst x ++ X0, snd x ++ Y0)). auto.
+            assert (J5: measure x = measure x). auto.
+            pose (SIH _ H0 _ J5 _ _ _ _ J3 J4 propvar). auto.
+      + apply derI with (ps:=[]). 2: apply dlNil. apply IdP. apply InT_split in i. destruct i. destruct s ; subst.
+         apply InT_split in i0. destruct i0. destruct s ; subst. assert (UI p k :: x1 ++ # P :: x2 = (UI p k :: x1) ++ # P :: x2).
+         auto. rewrite H0. apply IdPRule_I.
+ +
+    (* BotL *)
+    * inversion H ; subst.
+      assert (InT Bot (fst k ++ X0)). rewrite <- H2. apply InT_or_app ; right ; apply InT_eq.
+      apply InT_app_or in H0. destruct H0.
+      + assert ((X0, UI p k :: Y0) = (X0, [] ++ UI p k :: Y0)). auto. rewrite H0. apply is_init_UI.
+         right. destruct k. simpl in i. apply InT_split in i. destruct i. destruct s ; subst. apply BotLRule_I.
+      + apply derI with (ps:=[]). 2: apply dlNil. apply BotL. apply InT_split in i. destruct i. destruct s ; subst.
+         apply BotLRule_I.
+ +
+    (* ImpR *)
+    * destruct (critical_Seq_dec k).
+      (* If critical, then the rule ImpR was applied on a formula in X0 or Y0.
+          So, apply PIH omn the premise and then the rule. *)

+      + inversion H ; subst. assert (J0: dersrec_height d = dersrec_height d) ; auto.
+         apply dersrec_derrec_height in J0. destruct J0.
+         assert (J1: derrec_height x = derrec_height x). auto.
+         assert (J2: list_exch_L (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) (A :: fst k ++ X0, Δ0 ++ B :: Δ1)).
+         assert ((Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) = ([] ++ [] ++ Γ0 ++ [A] ++ Γ1, Δ0 ++ B :: Δ1)). auto.
+         rewrite H0.
+         assert ((A :: fst k ++ X0, Δ0 ++ B :: Δ1) = ([] ++ [A] ++ Γ0 ++ [] ++ Γ1, Δ0 ++ B :: Δ1)).
+         simpl. rewrite H2. auto. rewrite H1. apply list_exch_LI.
+         pose (KS_hpadm_list_exch_L _ x _ J2). destruct s.
+         assert (J3: derrec_height x0 = derrec_height x0). auto.
+         assert (J4: list_exch_L (A :: fst k ++ X0, Δ0 ++ B :: Δ1) (fst k ++ A :: X0, Δ0 ++ B :: Δ1)).
+         assert ((fst k ++ A :: X0, Δ0 ++ B :: Δ1) = ([] ++ [] ++ fst k ++ [A] ++ X0, Δ0 ++ B :: Δ1)). auto.
+         rewrite H0.
+         assert ((A :: fst k ++ X0, Δ0 ++ B :: Δ1) = ([] ++ [A] ++ fst k ++ [] ++ X0, Δ0 ++ B :: Δ1)).
+         auto. rewrite H1. apply list_exch_LI.
+         pose (KS_hpadm_list_exch_L _ x0 _ J4). destruct s. simpl in PIH.
+         apply app2_find_hole in H3. destruct H3.
+         repeat destruct s ; destruct p0 ; subst.
+         assert (J5: derrec_height x1 < S (dersrec_height d)). rewrite <- e. apply PeanoNat.le_lt_n_Sm.
+         apply (Nat.le_trans _ _ _ l0 l).
+         assert (J6: derrec_height x1 = derrec_height x1). auto.
+         assert (J7: (fst k ++ A :: X0, snd k ++ B :: Δ1) = (fst k ++ A:: X0, snd k ++ B :: Δ1)). auto.
+         assert (J8: (In # p (propvar_subform_list ((A :: X0) ++ B :: Δ1)) -> False)).
+         intro. apply propvar. repeat rewrite propvar_subform_list_app.
+         repeat rewrite propvar_subform_list_app in H0. simpl in H0. simpl.
+         repeat rewrite <- app_assoc in H0.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ;
+         left ; apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ;
+         left ; apply in_or_app ; auto. apply in_or_app ; right ; apply in_or_app ; auto.
+         pose (PIH _ J5 _ _ _ _ _ J6 J7 J8).
+         apply derI with (ps:=[([] ++ A :: X0, [UI p k] ++ B :: Δ1)]). apply ImpR.
+         assert ((X0, UI p k :: A --> B :: Δ1) = ([] ++ X0, [UI p k] ++ A --> B :: Δ1)). auto. rewrite H0.
+         apply ImpRRule_I. apply dlCons ; [ simpl ; auto | apply dlNil].
+         destruct x2 ; simpl in e1 ; subst. rewrite app_nil_r in e0 ; subst.
+         assert (J5: derrec_height x1 < S (dersrec_height d)). rewrite <- e. apply PeanoNat.le_lt_n_Sm.
+         apply (Nat.le_trans _ _ _ l0 l).
+         assert (J6: derrec_height x1 = derrec_height x1). auto.
+         assert (J7: (fst k ++ A :: X0, snd k ++ B :: Δ1) = (fst k ++ A:: X0, snd k ++ B :: Δ1)). auto.
+         assert (J8: (In # p (propvar_subform_list ((A :: X0) ++ B :: Δ1)) -> False)).
+         intro. apply propvar. repeat rewrite propvar_subform_list_app.
+         repeat rewrite propvar_subform_list_app in H0. simpl in H0. simpl.
+         repeat rewrite <- app_assoc in H0.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ;
+         left ; apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ;
+         left ; apply in_or_app ; auto. apply in_or_app ; right ; apply in_or_app ; auto.
+         pose (PIH _ J5 _ _ _ _ _ J6 J7 J8).
+         apply derI with (ps:=[([] ++ A :: X0, [UI p k] ++ B :: Δ1)]). apply ImpR.
+         assert ((X0, UI p k :: A --> B :: Δ1) = ([] ++ X0, [UI p k] ++ A --> B :: Δ1)). auto. rewrite H0.
+         apply ImpRRule_I. apply dlCons ; [ simpl ; auto | apply dlNil].
+         exfalso. destruct k ; simpl in e0 ; subst. unfold critical_Seq in c ; unfold is_Prime in c ; simpl in c.
+         assert (In m (l1 ++ Δ0 ++ m :: x2)). apply in_or_app ; right ; apply in_or_app ; right ; apply in_eq.
+         apply c in H0. inversion e1 ; subst. destruct H0 ; destruct H0 ; inversion H0 ; inversion H1.
+         assert (J5: derrec_height x1 < S (dersrec_height d)). rewrite <- e. apply PeanoNat.le_lt_n_Sm.
+         apply (Nat.le_trans _ _ _ l0 l).
+         assert (J6: derrec_height x1 = derrec_height x1). auto.
+         assert (J7: (fst k ++ A :: X0, (snd k ++ x2) ++ B :: Δ1) = (fst k ++ A:: X0, snd k ++ x2 ++ B :: Δ1)).
+         repeat rewrite <- app_assoc. auto.
+         assert (J8: (In # p (propvar_subform_list ((A :: X0) ++ (x2 ++ B :: Δ1))) -> False)).
+         intro. apply propvar. repeat rewrite propvar_subform_list_app.
+         repeat rewrite propvar_subform_list_app in H0. simpl in H0. simpl.
+         repeat rewrite <- app_assoc in H0.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ;
+         right ; apply in_or_app ; left ; apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ;
+         right ; apply in_or_app ; left ; apply in_or_app ; auto.
+         apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+         pose (PIH _ J5 _ _ _ _ _ J6 J7 J8).
+         apply derI with (ps:=[([] ++ A :: X0, (UI p k :: x2) ++ B :: Δ1)]). apply ImpR.
+         assert ((X0, UI p k :: x2 ++ A --> B :: Δ1) = ([] ++ X0, (UI p k :: x2) ++ A --> B :: Δ1)). auto. rewrite H0.
+         apply ImpRRule_I. apply dlCons ; [ simpl ; auto | apply dlNil].
+      (*  If not critical, consider the conjunction that UI p k is. *)
+      + assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+         assert (J1: Gimap (GUI p) (Canopy k) (map (UI p) (Canopy k))). apply Gimap_map. intros.
+         apply UI_GUI ; auto.
+         pose (@GUI_inv_not_critic p k (UI p k) (map (UI p) (Canopy k)) J0 f J1). rewrite <- e.
+ +
+         assert (J2: forall s1, InT s1 (Canopy k) -> KS_prv (X0, UI p s1 :: Y0)).
+         intros. pose (fold_Canopy _ _ H0). destruct s ; subst.
+         exfalso. apply f. apply Canopy_critical in H0 ; auto. destruct s. destruct p0. unfold inv_prems in i.
+         apply InT_flatten_list_InT_elem in i. destruct i. destruct p0. simpl in PIH. simpl in SIH.
+         pose (derI _ k0 d). assert (J2: derrec_height d0 = derrec_height d0). auto.
+         assert (J3: (fst k ++ X0, snd k ++ Y0) = (fst k ++ X0, snd k ++ Y0)). auto.
+         pose (Canopy_hp_inv_ctx k _ _ d0 X0 Y0 J2 J3 _ H0). destruct s.
+         assert (derrec_height d0 = S (dersrec_height d)). auto. rewrite H1 in l.
+         destruct (lt_decT (derrec_height x1) (S (dersrec_height d))).
+         (* Use PIH. *)
+         pose (fold_Canopy _ _ H0). destruct s ; subst.
+         exfalso. apply f. apply Canopy_critical in H0 ; auto. destruct s. destruct p0. unfold inv_prems in i2.
+         apply InT_flatten_list_InT_elem in i2. destruct i2. destruct p0.
+         assert (J4: derrec_height x1 = derrec_height x1). auto.
+         assert (J5: (fst s1 ++ X0, snd s1 ++ Y0) = (fst s1 ++ X0, snd s1 ++ Y0)). auto.
+         pose (PIH _ l0 s1 _ x1 X0 Y0 J4 J5). apply k1 ; auto.
+         (* Use SIH. *)
+         assert (derrec_height x1 = S (dersrec_height d)). lia.
+         assert (J4: measure s1 < measure k). pose (Canopy_measure _ _ H0).
+         destruct s ; subst ; auto. exfalso. apply f. apply Canopy_critical in H0 ; auto. symmetry in H2.
+         assert (J5: (fst s1 ++ X0, snd s1 ++ Y0) = (fst s1 ++ X0, snd s1 ++ Y0)). auto.
+         assert (J6: measure s1 = measure s1). auto.
+         pose (SIH _ J4 _ J6 _ _ _ _ H2 J5 propvar). auto.
+         assert (J3: (forall A : MPropF, InT A (map (UI p) (Canopy k)) -> KS_prv (fst (X0, Y0), A :: snd (X0, Y0)))).
+         intros. simpl. apply InT_map_iff in H0. destruct H0. destruct p0 ; subst. apply J2 in i ; auto.
+         pose (list_conj_R _ _ J3). simpl in k1. auto.
+ +
+    (* ImpL *)
+    * destruct (critical_Seq_dec k).
+      (* If critical, then the rule ImpL was applied on a formula in X0 or Y0.
+          So, apply PIH on the premises and then the rule. *)

+      + inversion H ; subst. assert (J0: dersrec_height d = dersrec_height d) ; auto.
+         apply dersrec_derrec2_height in J0. destruct J0. destruct s. simpl in PIH.
+         assert (J1: derrec_height x = derrec_height x). auto.
+         assert (J2: list_exch_R (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) (Γ0 ++ Γ1, A :: snd k ++ Y0)).
+         assert ((Γ0 ++ Γ1, Δ0 ++ A :: Δ1) = (Γ0 ++ Γ1, [] ++ [] ++ Δ0 ++ [A] ++ Δ1)). auto.
+         rewrite H0.
+         assert ((Γ0 ++ Γ1, A :: snd k ++ Y0) = (Γ0 ++ Γ1, [] ++ [A] ++ Δ0 ++ [] ++ Δ1)).
+         simpl. rewrite H3. auto. rewrite H1. apply list_exch_RI.
+         pose (KS_hpadm_list_exch_R _ x _ J2). destruct s.
+         assert (J3: derrec_height x1 = derrec_height x1). auto.
+         assert (J4: list_exch_R (Γ0 ++ Γ1, A :: snd k ++ Y0) (Γ0 ++ Γ1, snd k ++ A :: Y0)).
+         assert ((Γ0 ++ Γ1, snd k ++ A :: Y0) = (Γ0 ++ Γ1, [] ++ [] ++ snd k ++ [A] ++ Y0)). auto.
+         rewrite H0.
+         assert ((Γ0 ++ Γ1, A :: snd k ++ Y0) = (Γ0 ++ Γ1, [] ++ [A] ++ snd k ++ [] ++ Y0)).
+         auto. rewrite H1. apply list_exch_RI.
+         pose (KS_hpadm_list_exch_R _ x1 _ J4). destruct s.
+         apply app2_find_hole in H2. destruct H2.
+         repeat destruct s ; destruct p0 ; subst.
+         assert (J5: derrec_height x2 < S (dersrec_height d)). rewrite e. apply PeanoNat.le_lt_n_Sm.
+         apply Nat.max_le_iff. left ; apply (Nat.le_trans _ _ _ l0 l).
+         assert (J6: derrec_height x2 = derrec_height x2). auto.
+         assert (J7: (fst k ++ Γ1, snd k ++ A :: Y0) = (fst k ++ Γ1, snd k ++ A :: Y0)). auto.
+         assert (J8: In # p (propvar_subform_list (Γ1 ++ A :: Y0)) -> False).
+         intro. apply propvar. repeat rewrite propvar_subform_list_app.
+         repeat rewrite propvar_subform_list_app in H0. simpl in H0. simpl.
+         repeat rewrite <- app_assoc.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ;
+         right ; apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; auto. apply in_or_app ; right ; apply in_or_app ;
+         right ; apply in_or_app ; auto.
+         pose (PIH _ J5 _ _ _ _ _ J6 J7 J8).
+         assert (J9: derrec_height x0 < S (dersrec_height d)). lia.
+         assert (J10: derrec_height x0 = derrec_height x0). auto.
+         assert (J11: (fst k ++ B :: Γ1, Δ0 ++ Δ1) = (fst k ++ B :: Γ1, snd k ++ Y0)). rewrite H3 ; auto.
+         assert (J12: In # p (propvar_subform_list ((B :: Γ1) ++ Y0)) -> False).
+         intro. apply propvar. repeat rewrite propvar_subform_list_app.
+         repeat rewrite propvar_subform_list_app in H0. simpl in H0. simpl.
+         repeat rewrite <- app_assoc. repeat rewrite <- app_assoc in H0.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ;
+         right ; apply in_or_app ; auto. apply in_or_app ; right ; apply in_or_app ;
+         right ; apply in_or_app ; auto.
+         pose (PIH _ J9 _ _ _ _ _ J10 J11 J12).
+         apply derI with (ps:=[([] ++ Γ1, [UI p k] ++ A :: Y0);([] ++ B :: Γ1, [UI p k] ++ Y0)]). apply ImpL.
+         assert ((A --> B :: Γ1, UI p k :: Y0) = ([] ++ A --> B :: Γ1, [UI p k] ++ Y0)). auto. rewrite H0.
+         apply ImpLRule_I. apply dlCons. auto. apply dlCons. auto. apply dlNil.
+         destruct x3 ; simpl in e1 ; subst. rewrite app_nil_r in e0 ; subst.
+         assert (J5: derrec_height x2 < S (dersrec_height d)). rewrite e. apply PeanoNat.le_lt_n_Sm.
+         apply Nat.max_le_iff. left ; apply (Nat.le_trans _ _ _ l0 l).
+         assert (J6: derrec_height x2 = derrec_height x2). auto.
+         assert (J7: (fst k ++ Γ1, snd k ++ A :: Y0) = (fst k ++ Γ1, snd k ++ A :: Y0)). auto.
+         assert (J8: In # p (propvar_subform_list (Γ1 ++ A :: Y0)) -> False).
+         intro. apply propvar. repeat rewrite propvar_subform_list_app.
+         repeat rewrite propvar_subform_list_app in H0. simpl in H0. simpl.
+         repeat rewrite <- app_assoc.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ;
+         right ; apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; auto. apply in_or_app ; right ; apply in_or_app ;
+         right ; apply in_or_app ; auto.
+         pose (PIH _ J5 _ _ _ _ _ J6 J7 J8).
+         assert (J9: derrec_height x0 < S (dersrec_height d)). lia.
+         assert (J10: derrec_height x0 = derrec_height x0). auto.
+         assert (J11: (fst k ++ B :: Γ1, Δ0 ++ Δ1) = (fst k ++ B :: Γ1, snd k ++ Y0)). rewrite H3 ; auto.
+         assert (J12: In # p (propvar_subform_list ((B :: Γ1) ++ Y0)) -> False).
+         intro. apply propvar. repeat rewrite propvar_subform_list_app.
+         repeat rewrite propvar_subform_list_app in H0. simpl in H0. simpl.
+         repeat rewrite <- app_assoc. repeat rewrite <- app_assoc in H0.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ;
+         right ; apply in_or_app ; auto. apply in_or_app ; right ; apply in_or_app ;
+         right ; apply in_or_app ; auto.
+         pose (PIH _ J9 _ _ _ _ _ J10 J11 J12).
+         apply derI with (ps:=[([] ++ Γ1, [UI p k] ++ A :: Y0);([] ++ B :: Γ1, [UI p k] ++ Y0)]). apply ImpL.
+         assert ((A --> B :: Γ1, UI p k :: Y0) = ([] ++ A --> B :: Γ1, [UI p k] ++ Y0)). auto. rewrite H0.
+         apply ImpLRule_I. apply dlCons. auto. apply dlCons. auto. apply dlNil.
+         exfalso. destruct k ; simpl in e0 ; subst. unfold critical_Seq in c ; unfold is_Prime in c ; simpl in c.
+         assert (In m ((Γ0 ++ m :: x3) ++ l2)). repeat rewrite <- app_assoc. apply in_or_app ; right ; apply in_or_app ; left ; apply in_eq.
+         apply c in H0. inversion e1 ; subst. destruct H0 ; destruct H0 ; inversion H0 ; inversion H1.
+         assert (J5: derrec_height x2 < S (dersrec_height d)). rewrite e. apply PeanoNat.le_lt_n_Sm.
+         apply Nat.max_le_iff. left ; apply (Nat.le_trans _ _ _ l0 l).
+         assert (J6: derrec_height x2 = derrec_height x2). auto.
+         assert (J7: ((fst k ++ x3) ++ Γ1, snd k ++ A :: Y0) = (fst k ++ x3 ++ Γ1, snd k ++ A :: Y0)).
+         rewrite <- app_assoc ; auto.
+         assert (J8: In # p (propvar_subform_list ((x3 ++ Γ1) ++ A :: Y0)) -> False).
+         intro. apply propvar. repeat rewrite propvar_subform_list_app.
+         repeat rewrite propvar_subform_list_app in H0. simpl in H0. simpl.
+         repeat rewrite <- app_assoc. repeat rewrite <- app_assoc in H0.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; auto. apply in_app_or in H0 ; destruct H0.
+         apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; right ; apply in_or_app ; auto.
+         apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+         pose (PIH _ J5 _ _ _ _ _ J6 J7 J8).
+         assert (J9: derrec_height x0 < S (dersrec_height d)). lia.
+         assert (J10: derrec_height x0 = derrec_height x0). auto.
+         assert (J11: ((fst k ++ x3) ++ B :: Γ1, Δ0 ++ Δ1) = (fst k ++ x3 ++ B :: Γ1, snd k ++ Y0)).
+         rewrite H3 ; rewrite <- app_assoc ; auto.
+         assert (J12: In # p (propvar_subform_list ((x3 ++ B :: Γ1) ++ Y0)) -> False).
+         intro. apply propvar. repeat rewrite propvar_subform_list_app.
+         repeat rewrite propvar_subform_list_app in H0. simpl in H0. simpl.
+         repeat rewrite <- app_assoc. repeat rewrite <- app_assoc in H0.
+         apply in_app_or in H0 ; destruct H0. apply in_or_app ; auto. apply in_or_app ; right ; apply in_or_app ; auto.
+         pose (PIH _ J9 _ _ _ _ _ J10 J11 J12).
+         apply derI with (ps:=[(x3 ++ Γ1, [UI p k] ++ A :: Y0);(x3 ++ B :: Γ1, [UI p k] ++ Y0)]). apply ImpL.
+         assert ((x3 ++ A --> B :: Γ1, UI p k :: Y0) = (x3 ++ A --> B :: Γ1, [UI p k] ++ Y0)). auto. rewrite H0.
+         apply ImpLRule_I. apply dlCons. auto. apply dlCons. auto. apply dlNil.
+      (*  If not critical, consider the conjunction that UI p k is. *)
+      + assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+         assert (J1: Gimap (GUI p) (Canopy k) (map (UI p) (Canopy k))). apply Gimap_map. intros.
+         apply UI_GUI ; auto.
+         pose (@GUI_inv_not_critic p k (UI p k) (map (UI p) (Canopy k)) J0 f J1). rewrite <- e.
+ +
+         assert (J2: forall s1, InT s1 (Canopy k) -> KS_prv (X0, UI p s1 :: Y0)).
+         intros. pose (fold_Canopy _ _ H0). destruct s ; subst.
+         exfalso. apply f. apply Canopy_critical in H0 ; auto. destruct s. destruct p0. unfold inv_prems in i.
+         apply InT_flatten_list_InT_elem in i. destruct i. destruct p0. simpl in PIH. simpl in SIH.
+         pose (derI _ k0 d). assert (J2: derrec_height d0 = derrec_height d0). auto.
+         assert (J3: (fst k ++ X0, snd k ++ Y0) = (fst k ++ X0, snd k ++ Y0)). auto.
+         pose (Canopy_hp_inv_ctx k _ _ d0 X0 Y0 J2 J3 _ H0). destruct s.
+         assert (derrec_height d0 = S (dersrec_height d)). auto. rewrite H1 in l.
+         destruct (lt_decT (derrec_height x1) (S (dersrec_height d))).
+         (* Use PIH. *)
+         pose (fold_Canopy _ _ H0). destruct s ; subst.
+         exfalso. apply f. apply Canopy_critical in H0 ; auto. destruct s. destruct p0. unfold inv_prems in i2.
+         apply InT_flatten_list_InT_elem in i2. destruct i2. destruct p0.
+         assert (J4: derrec_height x1 = derrec_height x1). auto.
+         assert (J5: (fst s1 ++ X0, snd s1 ++ Y0) = (fst s1 ++ X0, snd s1 ++ Y0)). auto.
+         pose (PIH _ l0 s1 _ x1 X0 Y0 J4 J5). apply k1 ; auto.
+         (* Use SIH. *)
+         assert (derrec_height x1 = S (dersrec_height d)). lia.
+         assert (J4: measure s1 < measure k). pose (Canopy_measure _ _ H0).
+         destruct s ; subst ; auto. exfalso. apply f. apply Canopy_critical in H0 ; auto. symmetry in H2.
+         assert (J5: (fst s1 ++ X0, snd s1 ++ Y0) = (fst s1 ++ X0, snd s1 ++ Y0)). auto.
+         assert (J6: measure s1 = measure s1). auto.
+         pose (SIH _ J4 _ J6 _ _ _ _ H2 J5 propvar). auto.
+         assert (J3: (forall A : MPropF, InT A (map (UI p) (Canopy k)) -> KS_prv (fst (X0, Y0), A :: snd (X0, Y0)))).
+         intros. simpl. apply InT_map_iff in H0. destruct H0. destruct p0 ; subst. apply J2 in i ; auto.
+         pose (list_conj_R _ _ J3). simpl in k1. auto.
+ +
+    (* KR *)
+    * destruct (critical_Seq_dec k).
+      (* If critical. *)
+      + inversion X ; subst.
+         assert (J0: dersrec_height d = dersrec_height d) ; auto.
+         apply dersrec_derrec_height in J0. destruct J0. simpl in PIH. simpl in SIH.
+         destruct (dec_KS_init_rules k).
+         (* If initial. *)
+        ** assert (is_init k) ; auto. assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+         pose (@GUI_inv_critic_init p k _ J0 c X2). rewrite <- e0.
+         assert ((X0, Top :: Y0) = (X0, [] ++ Top :: Y0)). auto. rewrite H. apply TopR.
+         (* If not initial. *)
+        ** apply univ_gen_ext_splitR in X1. destruct X1. destruct s. destruct p0. destruct p0.
+           apply app2_find_hole in H2. destruct H2.
+           assert ((is_init k) -> False) ; auto.
+           assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+           assert (J1: Gimap (GUI p) (KR_prems k) (map (UI p) (KR_prems k))). apply Gimap_map. intros.
+           apply UI_GUI ; auto.
+           assert (J2: GUI p (unboxed_list (top_boxes (fst k)), []) (UI p (unboxed_list (top_boxes (fst k)), []))). apply UI_GUI ; auto.
+ +
+           pose (@GUI_inv_critic_not_init p k _ _ _ J0 c NE H J1 J2).
+           rewrite <- e1. clear e1.
+           repeat destruct s ; destruct p0 ; subst.
+           (* If Box A is in Y0. *)
+           -- pose (OrR (X0,Box A :: Δ1)). simpl in k1. apply k1. clear k1.
+              apply KS_hpadm_wkn_R with (A:=list_disj (restr_list_prop p (snd k))) (s:=(X0,
+              Or (list_disj (map Neg (restr_list_prop p (fst k))))(Or (list_disj (map Box (map (UI p) (KR_prems k)))) (Diam
+              (UI p (unboxed_list (top_boxes (fst k)), []%list)))) :: Box A :: Δ1)).
+              2: epose (wkn_RI (list_disj (restr_list_prop p (snd k))) _ [] _) ; simpl in w ; apply w.
+              pose (OrR (X0,Box A :: Δ1)). simpl in k1. apply k1. clear k1.
+              apply KS_hpadm_wkn_R with (A:=list_disj (map Neg (restr_list_prop p (fst k)))) (s:=(X0,
+              Or (list_disj (map Box (map (UI p) (KR_prems k)))) (Diam (UI p (unboxed_list (top_boxes (fst k)), []%list)))
+              :: Box A :: Δ1)).
+              2: epose (wkn_RI (list_disj (map Neg (restr_list_prop p (fst k)))) _ [] _) ; simpl in w ; apply w.
+              pose (OrR (X0,Box A :: Δ1)). simpl in k1. apply k1. clear k1.
+              apply KS_hpadm_wkn_R with (A:=list_disj (map Box (map (UI p) (KR_prems k)))) (s:=(X0,
+              (Diam (UI p (unboxed_list (top_boxes (fst k)), []%list))) :: Box A :: Δ1)).
+              2: epose (wkn_RI (list_disj (map Box (map (UI p) (KR_prems k)))) _ [] _) ; simpl in w ; apply w.
+              assert (J5: derrec_height x < S (dersrec_height d)). lia.
+              assert (J6: derrec_height x = derrec_height x). auto.
+              assert (J7: (unboxed_list (x0 ++ x1), [A]) = (fst (unboxed_list x0, @nil MPropF) ++ unboxed_list x1, snd (unboxed_list x0, []) ++ [A])).
+              simpl ; rewrite unbox_app_distrib. repeat rewrite <- app_assoc ; auto.
+              assert (J8: (In # p (propvar_subform_list ((unboxed_list x1) ++ [A])) -> False)).
+              intro. apply propvar. repeat rewrite propvar_subform_list_app.
+              repeat rewrite propvar_subform_list_app in H0. simpl in H0. repeat rewrite app_nil_r in H0. simpl.
+              repeat rewrite <- app_assoc in H0. apply in_app_or in H0 ; destruct H0.
+              apply in_or_app ; left. apply propvar_subform_list_unboxed_list in H0.
+              apply propvar_subform_list_nobox_gen_ext with (l0:=x1); auto.
+              apply in_or_app ; right ; apply in_or_app ; left. auto.
+              pose (PIH _ J5 _ _ _ _ _ J6 J7 J8).
+              apply derI with (ps:=[(X0 ++ Box (Neg (UI p (unboxed_list (top_boxes (fst k)), []%list))) :: [], [] ++ Bot :: Box A :: Δ1)]).
+              apply ImpR. assert ((X0, Diam (UI p (unboxed_list (top_boxes (fst k)), []%list)) :: Box A :: Δ1) =
+              (X0 ++ [], [] ++ Diam (UI p (unboxed_list (top_boxes (fst k)), []%list)) :: Box A :: Δ1)). rewrite app_nil_r. auto. rewrite H0.
+              apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+              apply derI with (ps:=[(unboxed_list (x1 ++ [Box (Neg (UI p (unboxed_list (top_boxes (fst k)), []%list)))]) , [A])]).
+              apply KR. assert (([] ++ Bot :: Box A :: Δ1) = [Bot] ++ Box A :: Δ1). auto. rewrite H0. apply KRRule_I ; auto.
+              intro. intros. apply in_app_or in H2 ; destruct H2. apply H1 ; apply in_or_app ; auto. exists (Neg (UI p (unboxed_list (top_boxes (fst k)), []%list))).
+              inversion H2 ; subst ; auto. inversion H3. apply univ_gen_ext_combine ; auto. apply univ_gen_ext_cons. apply univ_gen_ext_nil.
+              apply dlCons. 2: apply dlNil. rewrite unbox_app_distrib. simpl. repeat rewrite <- app_assoc. simpl.
+              apply derI with (ps:=[(unboxed_list x1, [] ++ (UI p (unboxed_list (top_boxes (fst k)), []%list)) :: [A]);
+              (unboxed_list x1 ++ Bot :: [], [] ++ [A])]). apply ImpL.
+              pose (ImpLRule_I (UI p (unboxed_list (top_boxes (fst k)), []%list)) Bot (unboxed_list x1) [] [] [A]). simpl ; simpl in i.
+              rewrite app_nil_r in i. auto. apply dlCons. 2: apply dlCons.
+              3: apply dlNil. 2: apply derI with (ps:=[]) ; [apply BotL ; apply BotLRule_I | apply dlNil].
+              simpl. assert ((top_boxes (fst k)) = x0). symmetry. apply nobox_gen_ext_top_boxes_identity ; auto.
+              intro. intros. apply H1 ; apply in_or_app ; auto. rewrite H0. auto.
+          -- destruct x2 ; simpl in e2 ; subst.
+              (* If Box A is in Y0 (bis). *)
+              +++ rewrite app_nil_r in e1 ; subst.
+                  pose (OrR (X0,Box A :: Δ1)). simpl in k1. apply k1. clear k1.
+                  apply KS_hpadm_wkn_R with (A:=list_disj (restr_list_prop p (snd k))) (s:=(X0,
+                  Or (list_disj (map Neg (restr_list_prop p (fst k))))(Or (list_disj (map Box (map (UI p) (KR_prems k)))) (Diam (UI p (unboxed_list (top_boxes (fst k)), []%list))))
+                  :: Box A :: Δ1)).
+                  2: epose (wkn_RI (list_disj (restr_list_prop p (snd k))) _ [] _) ; simpl in w ; apply w.
+                  pose (OrR (X0,Box A :: Δ1)). simpl in k1. apply k1. clear k1.
+                  apply KS_hpadm_wkn_R with (A:=list_disj (map Neg (restr_list_prop p (fst k)))) (s:=(X0,
+                  Or (list_disj (map Box (map (UI p) (KR_prems k)))) (Diam (UI p (unboxed_list (top_boxes (fst k)), []%list)))
+                  :: Box A :: Δ1)).
+                  2: epose (wkn_RI (list_disj (map Neg (restr_list_prop p (fst k)))) _ [] _) ; simpl in w ; apply w.
+                  pose (OrR (X0,Box A :: Δ1)). simpl in k1. apply k1. clear k1.
+                  apply KS_hpadm_wkn_R with (A:=list_disj (map Box (map (UI p) (KR_prems k)))) (s:=(X0,
+                  (Diam (UI p (unboxed_list (top_boxes (fst k)), []%list)))
+                  :: Box A :: Δ1)).
+                  2: epose (wkn_RI (list_disj (map Box (map (UI p) (KR_prems k)))) _ [] _) ; simpl in w ; apply w.
+                  assert (J5: derrec_height x < S (dersrec_height d)). lia.
+                  assert (J6: derrec_height x = derrec_height x). auto.
+                  assert (J7: (unboxed_list (x0 ++ x1), [A]) = (fst (unboxed_list x0, @nil MPropF) ++ unboxed_list x1, snd (unboxed_list x0, []) ++ [A])).
+                  simpl ; rewrite unbox_app_distrib. repeat rewrite <- app_assoc ; auto.
+                  assert (J8: (In # p (propvar_subform_list (unboxed_list x1 ++ [A])) -> False)).
+                  intro. apply propvar. repeat rewrite propvar_subform_list_app.
+                  repeat rewrite propvar_subform_list_app in H0. simpl in H0. repeat rewrite app_nil_r in H0. simpl.
+                  repeat rewrite <- app_assoc in H0. apply in_app_or in H0 ; destruct H0.
+                  apply in_or_app ; left. apply propvar_subform_list_unboxed_list in H0.
+                  apply propvar_subform_list_nobox_gen_ext with (l0:=x1); auto.
+                  apply in_or_app ; right ; apply in_or_app ; left. auto.
+                  pose (PIH _ J5 _ _ _ _ _ J6 J7 J8).
+                  apply derI with (ps:=[(X0 ++ Box (Neg (UI p (unboxed_list (top_boxes (fst k)), []%list))) :: [], [] ++ Bot :: Box A :: Δ1)]).
+                  apply ImpR. assert ((X0, Diam (UI p (unboxed_list (top_boxes (fst k)), []%list)) :: Box A :: Δ1) =
+                  (X0 ++ [], [] ++ Diam (UI p (unboxed_list (top_boxes (fst k)), []%list)) :: Box A :: Δ1)). rewrite app_nil_r. auto. rewrite H0.
+                  apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+                  apply derI with (ps:=[(unboxed_list (x1 ++ [Box (Neg (UI p (unboxed_list (top_boxes (fst k)), []%list)))]), [A])]).
+                  apply KR. assert (([] ++ Bot :: Box A :: Δ1) = [Bot] ++ Box A :: Δ1). auto. rewrite H0. apply KRRule_I ; auto.
+                  intro. intros. apply in_app_or in H2 ; destruct H2. apply H1 ; apply in_or_app ; auto. exists (Neg (UI p (unboxed_list (top_boxes (fst k)), []%list))).
+                  inversion H2 ; subst ; auto. inversion H3. apply univ_gen_ext_combine ; auto. apply univ_gen_ext_cons. apply univ_gen_ext_nil.
+                  apply dlCons. 2: apply dlNil. rewrite unbox_app_distrib. simpl. repeat rewrite <- app_assoc. simpl.
+                  apply derI with (ps:=[(unboxed_list x1, [] ++ (UI p (unboxed_list (top_boxes (fst k)), []%list)) :: [A]);
+                  (unboxed_list x1 ++ Bot :: [], [] ++ [A])]). apply ImpL.
+                  pose (ImpLRule_I (UI p (unboxed_list (top_boxes (fst k)), []%list)) Bot (unboxed_list x1) [] [] [A]). simpl ; simpl in i.
+                  rewrite app_nil_r in i. auto. apply dlCons. 2: apply dlCons.
+                  3: apply dlNil. 2: apply derI with (ps:=[]) ; [apply BotL ; apply BotLRule_I | apply dlNil].
+                  simpl. assert ((top_boxes (fst k)) = x0). symmetry. apply nobox_gen_ext_top_boxes_identity ; auto.
+                  intro. intros. apply H1 ; apply in_or_app ; auto. rewrite H0. auto.
+             (* If Box A is in (snd k). *)
+             +++ inversion e2 ; subst.
+                  assert (J10:derrec_height x = derrec_height x) ; auto.
+                  assert (J5: derrec_height x < S (dersrec_height d)). lia.
+                  assert (J6: derrec_height x = derrec_height x). auto.
+                  assert (J7: (unboxed_list (x0 ++ x1), [A]) = (fst (unboxed_list x0, [A]) ++ unboxed_list x1, snd (unboxed_list x0, [A]) ++ [])).
+                  simpl. rewrite unbox_app_distrib. repeat rewrite <- app_assoc ; auto.
+                  assert (J8: (In # p (propvar_subform_list ((unboxed_list x1 ++ [])))) -> False).
+                  intro. apply propvar. repeat rewrite propvar_subform_list_app.
+                  repeat rewrite propvar_subform_list_app in H0. simpl in H0. repeat rewrite app_nil_r in H0. simpl.
+                  repeat rewrite <- app_assoc in H0. apply in_or_app ; left. apply propvar_subform_list_unboxed_list in H0.
+                  apply propvar_subform_list_nobox_gen_ext with (l0:=x1); auto.
+                  pose (PIH _ J5 _ _ _ _ _ J6 J7 J8).
+                  assert (J20: KS_rules [(unboxed_list x1, [UI p (unboxed_list x0, [A])])]
+                  (X0, Box (UI p (unboxed_list x0, [A])) :: Y0)). apply KR.
+                  assert (Box (UI p (unboxed_list x0, [A])) :: Y0 = [] ++ Box (UI p (unboxed_list x0, [A])) :: Y0).
+                  auto. rewrite H0. apply KRRule_I ;auto. intro. intros. apply H1. apply in_or_app ;auto.
+                  pose (dlNil KS_rules (fun _ : Seq => False)).
+                  pose (dlCons k1 d0). pose (derI _ J20 d1).
+                  pose (OrR (X0,Y0)). simpl in k2. apply k2. clear k2.
+                  apply KS_hpadm_wkn_R with (A:=list_disj (restr_list_prop p (snd k))) (s:=(X0,
+                  Or (list_disj (map Neg (restr_list_prop p (fst k))))(Or (list_disj (map Box (map (UI p) (KR_prems k)))) (Diam (UI p (unboxed_list (top_boxes (fst k)), []%list))))
+                  :: Y0)).
+                  2: epose (wkn_RI (list_disj (restr_list_prop p (snd k))) _ [] _) ; simpl in w ; apply w.
+                  pose (OrR (X0,Y0)). simpl in k2. apply k2. clear k2.
+                  apply KS_hpadm_wkn_R with (A:=list_disj (map Neg (restr_list_prop p (fst k)))) (s:=(X0,
+                  Or (list_disj (map Box (map (UI p) (KR_prems k)))) (Diam (UI p (unboxed_list (top_boxes (fst k)), []%list)))
+                  :: Y0)).
+                  2: epose (wkn_RI (list_disj (map Neg (restr_list_prop p (fst k)))) _ [] _) ; simpl in w ; apply w.
+                  pose (OrR (X0,Y0)). simpl in k2. apply k2. clear k2.
+                  pose (list_disj_wkn_R (map Box (map (UI p) (KR_prems k))) (X0, Diam (UI p (unboxed_list (top_boxes (fst k)), []%list)) :: Y0)).
+                  apply k2 with (A:=Box (UI p (unboxed_list x0, [A]))) ; clear k2 ; simpl ; auto.
+                  apply InT_map_iff. exists (UI p (unboxed_list x0, [A])) ; split ; auto. apply InT_map_iff.
+                  exists (unboxed_list x0, [A]) ; split ; auto. unfold KR_prems.
+                  apply InT_trans_flatten_list with (bs:=[(unboxed_list x0, [A])]) ; auto. apply InT_eq.
+                  destruct (finite_KR_premises_of_S k) ; subst. simpl. apply p0. assert (k = (fst k,Δ0 ++ Box A :: x2)).
+                  rewrite <- e1. destruct k ; auto. rewrite H0. apply KRRule_I ; auto. intro. intros. apply H1 ; apply in_or_app ; auto.
+                  apply KS_hpadm_wkn_R with (A:=Diam (UI p (unboxed_list (top_boxes (fst k)), []%list)))
+                  (s:=(X0, Box (UI p (unboxed_list x0, [A])) :: Y0)) ; auto.
+                  assert ((X0, Box (UI p (unboxed_list x0, [A])) :: Y0) = (X0, [Box (UI p (unboxed_list x0, [A]))] ++ Y0)).
+                  repeat rewrite <- app_assoc ; auto. rewrite H0. apply wkn_RI.
+           (* If Box A is in Y0 (ter). *)
+           -- pose (OrR (X0,x2 ++ Box A :: Δ1)). simpl in k1. apply k1. clear k1.
+              apply KS_hpadm_wkn_R with (A:=list_disj (restr_list_prop p (snd k))) (s:=(X0,
+              Or (list_disj (map Neg (restr_list_prop p (fst k))))(Or (list_disj (map Box (map (UI p) (KR_prems k)))) (Diam
+              (UI p (unboxed_list (top_boxes (fst k)), []%list)))) :: x2 ++ Box A :: Δ1)).
+              2: epose (wkn_RI (list_disj (restr_list_prop p (snd k))) _ [] _) ; simpl in w ; apply w.
+              pose (OrR (X0,x2 ++ Box A :: Δ1)). simpl in k1. apply k1. clear k1.
+              apply KS_hpadm_wkn_R with (A:=list_disj (map Neg (restr_list_prop p (fst k)))) (s:=(X0,
+              Or (list_disj (map Box (map (UI p) (KR_prems k)))) (Diam
+              (UI p (unboxed_list (top_boxes (fst k)), []%list)))
+              :: x2 ++ Box A :: Δ1)).
+              2: epose (wkn_RI (list_disj (map Neg (restr_list_prop p (fst k)))) _ [] _) ; simpl in w ; apply w.
+              pose (OrR (X0,x2 ++ Box A :: Δ1)). simpl in k1. apply k1. clear k1.
+              apply KS_hpadm_wkn_R with (A:=list_disj (map Box (map (UI p) (KR_prems k)))) (s:=(X0,
+              (Diam (UI p (unboxed_list (top_boxes (fst k)), []%list)))
+              :: x2 ++ Box A :: Δ1)).
+              2: epose (wkn_RI (list_disj (map Box (map (UI p) (KR_prems k)))) _ [] _) ; simpl in w ; apply w.
+              assert (J5: derrec_height x < S (dersrec_height d)). lia.
+              assert (J6: derrec_height x = derrec_height x). auto.
+              assert (J7: (unboxed_list (x0 ++ x1), [A]) = (fst (unboxed_list x0, @nil MPropF) ++ unboxed_list x1, snd (unboxed_list x0, []) ++ [A])).
+              simpl ; rewrite unbox_app_distrib. repeat rewrite <- app_assoc ; auto.
+              assert (J8: (In # p (propvar_subform_list ((unboxed_list x1) ++ [A])) -> False)).
+              intro. apply propvar. repeat rewrite propvar_subform_list_app.
+              repeat rewrite propvar_subform_list_app in H0. simpl in H0. repeat rewrite app_nil_r in H0. simpl.
+              repeat rewrite <- app_assoc in H0. apply in_app_or in H0 ; destruct H0.
+              apply in_or_app ; left. apply propvar_subform_list_unboxed_list in H0.
+              apply propvar_subform_list_nobox_gen_ext with (l0:=x1); auto.
+              apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; left. auto.
+              pose (PIH _ J5 _ _ _ _ _ J6 J7 J8).
+              apply derI with (ps:=[(X0 ++ Box (Neg (UI p (unboxed_list (top_boxes (fst k)), []%list))) :: [], [] ++ Bot :: x2 ++ Box A :: Δ1)]).
+              apply ImpR. assert ((X0, Diam (UI p (unboxed_list (top_boxes (fst k)), []%list)) :: x2 ++ Box A :: Δ1) =
+              (X0 ++ [], [] ++ Diam (UI p (unboxed_list (top_boxes (fst k)), []%list)) :: x2 ++ Box A :: Δ1)). rewrite app_nil_r. auto. rewrite H0.
+              apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+              apply derI with (ps:=[(unboxed_list (x1 ++ [Box (Neg (UI p (unboxed_list (top_boxes (fst k)), []%list)))]), [A])]).
+              apply KR. assert (([] ++ Bot :: x2 ++ Box A :: Δ1) = (Bot :: x2) ++ Box A :: Δ1). auto. rewrite H0. apply KRRule_I ; auto.
+              intro. intros. apply in_app_or in H2 ; destruct H2. apply H1 ; apply in_or_app ; auto. exists (Neg (UI p (unboxed_list (top_boxes (fst k)), []%list))).
+              inversion H2 ; subst ; auto. inversion H3. apply univ_gen_ext_combine ; auto. apply univ_gen_ext_cons. apply univ_gen_ext_nil.
+              apply dlCons. 2: apply dlNil. rewrite unbox_app_distrib. simpl. repeat rewrite <- app_assoc. simpl.
+              apply derI with (ps:=[(unboxed_list x1, [] ++ (UI p (unboxed_list (top_boxes (fst k)), []%list)) :: [A]);
+              (unboxed_list x1 ++ Bot :: [], [] ++ [A])]). apply ImpL.
+              pose (ImpLRule_I (UI p (unboxed_list (top_boxes (fst k)), []%list)) Bot (unboxed_list x1) [] [] [A]). simpl ; simpl in i.
+              rewrite app_nil_r in i. auto. apply dlCons. 2: apply dlCons.
+              3: apply dlNil. 2: apply derI with (ps:=[]) ; [apply BotL ; apply BotLRule_I | apply dlNil].
+              simpl. assert ((top_boxes (fst k)) = x0). symmetry. apply nobox_gen_ext_top_boxes_identity ; auto.
+              intro. intros. apply H1 ; apply in_or_app ; auto. rewrite H0. auto.
+      (*  If not critical, consider the conjunction that UI p k is. *)
+      + assert (J0: GUI p k (UI p k)). apply UI_GUI ; auto.
+         assert (J1: Gimap (GUI p) (Canopy k) (map (UI p) (Canopy k))). apply Gimap_map. intros.
+         apply UI_GUI ; auto.
+         pose (@GUI_inv_not_critic p k (UI p k) (map (UI p) (Canopy k)) J0 f J1). rewrite <- e.
+ +
+         assert (J2: forall s1, InT s1 (Canopy k) -> KS_prv (X0, UI p s1 :: Y0)).
+         intros. pose (fold_Canopy _ _ H). destruct s ; subst.
+         exfalso. apply f. apply Canopy_critical in H ; auto. destruct s. destruct p0. unfold inv_prems in i.
+         apply InT_flatten_list_InT_elem in i. destruct i. destruct p0. simpl in PIH. simpl in SIH.
+         pose (derI _ k0 d). assert (J2: derrec_height d0 = derrec_height d0). auto.
+         assert (J3: (fst k ++ X0, snd k ++ Y0) = (fst k ++ X0, snd k ++ Y0)). auto.
+         pose (Canopy_hp_inv_ctx k _ _ d0 X0 Y0 J2 J3 _ H). destruct s.
+         assert (derrec_height d0 = S (dersrec_height d)). auto. rewrite H0 in l.
+         destruct (lt_decT (derrec_height x1) (S (dersrec_height d))).
+         (* Use PIH. *)
+         pose (fold_Canopy _ _ H). destruct s ; subst.
+         exfalso. apply f. apply Canopy_critical in H ; auto. destruct s. destruct p0. unfold inv_prems in i2.
+         apply InT_flatten_list_InT_elem in i2. destruct i2. destruct p0.
+         assert (J4: derrec_height x1 = derrec_height x1). auto.
+         assert (J5: (fst s1 ++ X0, snd s1 ++ Y0) = (fst s1 ++ X0, snd s1 ++ Y0)). auto.
+         pose (PIH _ l0 s1 _ x1 X0 Y0 J4 J5). apply k1 ; auto.
+         (* Use SIH. *)
+         assert (derrec_height x1 = S (dersrec_height d)). lia.
+         assert (J4: measure s1 < measure k). pose (Canopy_measure _ _ H).
+         destruct s ; subst ; auto. exfalso. apply f. apply Canopy_critical in H ; auto. symmetry in H1.
+         assert (J5: (fst s1 ++ X0, snd s1 ++ Y0) = (fst s1 ++ X0, snd s1 ++ Y0)). auto.
+         assert (J6: measure s1 = measure s1). auto.
+         pose (SIH _ J4 _ J6 _ _ _ _ H1 J5 propvar). auto.
+         assert (J3: (forall A : MPropF, InT A (map (UI p) (Canopy k)) -> KS_prv (fst (X0, Y0), A :: snd (X0, Y0)))).
+         intros. simpl. apply InT_map_iff in H. destruct H. destruct p0 ; subst. apply J2 in i ; auto.
+         pose (list_conj_R _ _ J3). simpl in k1. auto. }
+  Qed.
+ +
+  End UIPThree.
+
+
+ +
+ + + diff --git a/K.Interpolation.UIK_UITwo.html b/K.Interpolation.UIK_UITwo.html new file mode 100644 index 0000000..17fa5de --- /dev/null +++ b/K.Interpolation.UIK_UITwo.html @@ -0,0 +1,153 @@ + + + + + + + + + + + + + +
+
+

K.Interpolation.UIK_UITwo

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat Arith.
+Require Import Lia.
+ +
+Require Import general_export.
+ +
+Require Import KS_export.
+ +
+Require Import UIK_Def_measure.
+Require Import UIK_Canopy.
+Require Import UIK_irred_short.
+Require Import UIK_braga.
+Require Import UIK_UI_prelims.
+ +
+  Section UIPTwo.
+ +
+  Theorem UI_Two : forall (s : Seq), forall p, KS_prv ((UI p s) :: fst s, snd s).
+  Proof.
+  intro s. remember (measure s) as n. revert Heqn. revert s. revert n.
+  induction n as [n IH] using (well_founded_induction_type lt_wf).
+  intros.
+  destruct (empty_seq_dec s).
+  (* s is the empty sequent. *)
+  { subst ; simpl in *. assert (GUI p ([],[]) Bot). apply GUI_empty_seq ; auto. apply UI_GUI in H.
+    rewrite H in *. apply derI with []. apply BotL ; apply (BotLRule_I [] []). apply dlNil. }
+  (* s is not the empty sequent. *)
+  { destruct (critical_Seq_dec s).
+  (* s is a critical sequent *)
+  - destruct (dec_KS_init_rules s).
+    (* s is an initial sequent *)
+    + assert (KS_prv (fst s, snd s)). destruct s0. destruct s.
+      1,2: apply derI with (ps:=[]) ; try apply dlNil.
+      apply IdP ; auto. destruct s ; apply BotL ; auto.
+      destruct s. simpl. simpl in X.
+      assert (J0: derrec_height X = derrec_height X). auto.
+      assert (J1: wkn_L (UI p (l, l0)) (l, l0) (UI p (l, l0) :: l, l0)).
+      replace (l, l0) with ([] ++ l, l0) by auto.
+      replace (UI p ([] ++ l, l0) :: l, l0) with ([] ++ UI p ([] ++ l, l0) :: l, l0) by auto.
+      apply wkn_LI.
+      pose (KS_wkn_L _ _ X J0 _ _ J1). destruct s. auto.
+    (* s is not an initial sequent *)
+    + assert (P1: KS_prv (list_disj (map Neg (restr_list_prop p (fst s))) :: fst s, snd s)).
+        apply list_disj_L. intros A H0. apply InT_map_iff in H0. destruct H0. destruct p0. subst. unfold Neg.
+        apply derI with (ps:=[([] ++ fst s, [] ++ x :: snd s);([] ++ Bot :: fst s, [] ++ snd s)]).
+        assert ((x --> Bot :: fst s, snd s) = ([] ++ x --> Bot :: fst s, [] ++ snd s)). auto. rewrite H. apply ImpL. apply ImpLRule_I.
+        apply dlCons. 2: apply dlCons. 3: apply dlNil. unfold restr_list_prop in i.
+        apply InT_In in i. apply In_remove_In_list in i. apply In_list_prop_LF in i. destruct i. apply In_InT in i.
+        apply InT_split in i. destruct i. destruct s1. destruct s. rewrite e. assert ([] ++ x0 ++ x :: x1 = x0 ++ x :: x1). auto.
+        rewrite H. apply Id_all_form. apply derI with (ps:=[]). apply BotL. apply BotLRule_I. apply dlNil.
+ +
+         assert (P2: KS_prv (list_disj (restr_list_prop p (snd s)) :: fst s, snd s)).
+         apply list_disj_L. intros A H0. unfold restr_list_prop in H0. apply InT_In in H0. apply In_remove_In_list in H0.
+         apply In_list_prop_LF in H0. destruct H0 as [s0 i]. apply In_InT in i. apply InT_split in i. destruct i. destruct s1.
+         rewrite e. replace (A :: fst s) with ([] ++ A :: fst s) by auto. apply Id_all_form.
+ +
+         assert (P3: KS_prv (list_disj (map Box (map (UI p) (KR_prems s))) :: fst s, snd s)).
+         apply list_disj_L. intros A H0. apply InT_map_iff in H0. destruct H0. destruct p0. subst. apply InT_map_iff in i.
+         destruct i. destruct p0 ; subst. unfold KR_prems in i. destruct (finite_KR_premises_of_S s).
+         simpl in i. apply InT_flatten_list_InT_elem in i. destruct i. destruct p1. apply p0 in i0.
+         inversion i0 ; subst. inversion i ; subst. simpl. remember (UI p (unboxed_list , [A])) as Interp.
+         apply derI with (ps:=[(unboxed_list (Box Interp :: ), [A])]). apply KR. apply KRRule_I.
+         intro. intros. inversion H0 ; simpl. exists Interp ; auto. apply H ; auto. apply univ_gen_ext_cons ; auto.
+         apply dlCons. 2: apply dlNil. simpl.
+         assert (J0: measure (unboxed_list , [A]) < measure (Γ0, Δ0 ++ Box A :: Δ1)).
+         unfold measure. simpl. repeat rewrite size_LF_dist_app. simpl.
+         pose (size_nobox_gen_ext _ _ X). simpl in l.
+         pose (size_unboxed ). lia.
+         assert (J30: measure (unboxed_list , [A]) = measure (unboxed_list , [A])) ; auto.
+         pose (IH _ J0 _ J30 p). simpl in k. rewrite <- HeqInterp in k. auto. inversion H1.
+ +
+         assert (P4: KS_prv (Diam (UI p (unboxed_list (top_boxes (fst s)), [])) :: fst s, snd s)).
+         { destruct s. destruct l ; subst.
+           - assert (GUI p ([],[]) Bot). apply GUI_empty_seq ; auto. apply UI_GUI in H. simpl in *. rewrite H in *.
+             apply DiamL_lim with (:=[]). intros A HA ; inversion HA. apply univ_gen_ext_nil. apply derI with [].
+             apply BotL. apply (BotLRule_I []). apply dlNil.
+           - apply DiamL_lim with (:=top_boxes (m :: l)). apply is_Boxed_list_top_boxes. apply nobox_top_boxes.
+             assert (J0: measure (unboxed_list (top_boxes (m :: l)), []%list) < measure (m :: l, l0)).
+             unfold measure. simpl. simpl in * ; simpl. subst ; simpl.
+             destruct m ; simpl ; subst ; pose (size_unboxed (top_boxes l)) ; pose (size_top_boxes l) ; lia.
+             assert (J30: measure (unboxed_list (top_boxes (m :: l)), []%list) = measure (unboxed_list (top_boxes (m :: l)), []%list)) ; auto.
+             subst. pose (IH _ J0 _ J30 p). simpl in k. auto. }
+
+         assert (H0: GUI p s
+         (Or (list_disj (restr_list_prop p (snd s)))
+         (Or (list_disj (map Neg (restr_list_prop p (fst s))))
+         (Or (list_disj (map Box (map (UI p) (KR_prems s))))
+         (Diam (UI p (unboxed_list (top_boxes (fst s)), []%list))))))).
+         apply GUI_critic_not_init ; auto. apply Gimap_map ; intros. 1-2: apply UI_GUI ; auto.
+         apply (UI_GUI p s) in H0. rewrite H0. repeat apply OrL ; auto.
+  (* s is not a critical sequent *)
+  - assert (J0: GUI p s (UI p s)). apply UI_GUI ; auto.
+    assert (J1: Gimap (GUI p) (Canopy s) (map (UI p) (Canopy s))). apply Gimap_map. intros.
+    apply UI_GUI ; auto.
+    pose (@GUI_inv_not_critic p s (UI p s) (map (UI p) (Canopy s)) J0 f J1). rewrite <- e.
+    assert (J2: forall s1, InT s1 (Canopy s) -> KS_prv (UI p s1 :: fst s1, snd s1)).
+    intros s1 H0. apply IH with (y:= measure s1) ; auto. pose (Canopy_measure _ _ H0). destruct s0 ; subst ; auto. exfalso.
+    apply f. apply Canopy_critical in H0 ; auto.
+    assert (J3 : forall s1 : Seq, InT s1 (Canopy s) -> KS_prv (list_conj (map (UI p) (Canopy s)) :: fst s1, snd s1)).
+    intros. apply list_conj_wkn_L with (A:=UI p s1) ; auto. apply InT_mapI. exists s1 ; auto.
+    apply Canopy_equiprv_genL ; auto. }
+  Qed.
+ +
+  End UIPTwo.
+
+
+ +
+ + + diff --git a/K.Interpolation.UIK_UI_prelims.html b/K.Interpolation.UIK_UI_prelims.html new file mode 100644 index 0000000..babb6d1 --- /dev/null +++ b/K.Interpolation.UIK_UI_prelims.html @@ -0,0 +1,623 @@ + + + + + + + + + + + + + +
+
+

K.Interpolation.UIK_UI_prelims

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat.
+Require Import Lia.
+Require Import String.
+ +
+Require Import general_export.
+ +
+Require Import KS_export.
+ +
+Require Import UIK_Def_measure.
+Require Import UIK_Canopy.
+Require Import UIK_irred_short.
+Require Import UIK_basics.
+Require Import UIK_braga.
+ +
+  Section Prop_Subform.
+ +
+  (* This is copied from the Craig interpolation file. Make a syntax file for interpolations. *)
+ +
+  Fixpoint propvar_subform (A : MPropF) : list MPropF :=
+  match A with
+    | Var p => (Var p) :: nil
+    | Bot => nil
+    | Imp B C => (propvar_subform B) ++ ( propvar_subform C)
+    | Box B => ( propvar_subform B)
+  end.
+ +
+  Fixpoint propvar_subform_list (l : list MPropF) : list MPropF :=
+  match l with
+    | nil => nil
+    | A :: t => (propvar_subform A) ++ (propvar_subform_list t)
+  end.
+ +
+  (* Lemmas about propvar_subform_list. *)
+ +
+  Lemma propvar_subform_list_app: forall l0 l1,
+        propvar_subform_list (l0 ++ l1) = (propvar_subform_list l0) ++ (propvar_subform_list l1).
+  Proof.
+  induction l0.
+  - simpl. auto.
+  - intros. simpl. rewrite (IHl0). rewrite <- app_assoc ; auto.
+  Qed.
+ +
+  Lemma propvar_subform_list_unboxed_list : forall l A, In A (propvar_subform_list (unboxed_list l)) -> In A (propvar_subform_list l).
+  Proof.
+  induction l.
+  - auto.
+  - simpl. intros. apply in_app_or in H. destruct H. apply in_or_app ; left. destruct a ; auto.
+    apply in_or_app ; auto.
+  Qed.
+ +
+  Lemma propvar_subform_list_nobox_gen_ext : forall l0 l1, nobox_gen_ext l0 l1 ->
+            (forall A, In A (propvar_subform_list l0) -> In A (propvar_subform_list l1)).
+  Proof.
+  intros l0 l1 H. induction H ; auto.
+  - simpl ; intros. apply in_or_app. apply in_app_or in H0 ; destruct H0 ; auto.
+  - simpl ; intros. apply in_or_app ; auto.
+  Qed.
+ +
+  Lemma propvar_subform_list_top_boxes : forall l A, In A (propvar_subform_list (top_boxes l)) -> In A (propvar_subform_list l).
+  Proof.
+  induction l ; simpl ; intros ; auto. destruct a ; simpl in H ; auto. 1-2: apply in_or_app ; apply IHl in H ; auto.
+  apply in_or_app ; apply in_app_or in H ; destruct H ; simpl ; auto.
+  Qed.
+ +
+  Lemma propvar_subform_list_conj : forall l A,
+            In A (propvar_subform (list_conj l)) -> In A (propvar_subform_list l).
+  Proof.
+  induction l ; simpl ; intros ; auto. repeat rewrite app_nil_r in H.
+  apply in_app_or in H. apply in_or_app. destruct H ; auto.
+  Qed.
+ +
+  Lemma propvar_subform_list_disj : forall l A,
+            In A (propvar_subform (list_disj l)) -> In A (propvar_subform_list l).
+  Proof.
+  induction l ; simpl ; intros ; auto. repeat rewrite app_nil_r in H.
+  apply in_app_or in H. apply in_or_app. destruct H ; auto.
+  Qed.
+ +
+  Lemma propvar_subform_list_witness : forall l A,
+            In A (propvar_subform_list l) -> (exists B, In B l /\ In A (propvar_subform B)).
+  Proof.
+  induction l ; simpl ; intros ; auto. inversion H. apply in_app_or in H. destruct H.
+  exists a ; auto. apply IHl in H. destruct H. exists x ; firstorder.
+  Qed.
+ +
+  Lemma propvar_subform_list_witnessT : forall l A,
+            InT A (propvar_subform_list l) -> (existsT2 B, (InT B l) * (InT A (propvar_subform B))).
+  Proof.
+  induction l ; simpl ; intros ; auto. inversion H. apply InT_app_or in H. destruct H.
+  exists a ; auto. split ; auto. apply InT_eq. apply IHl in i. destruct i. exists x ; firstorder. apply InT_cons ; auto.
+  Qed.
+ +
+  Lemma propvar_subform_list_Canopy : forall s ir A,
+            In ir (Canopy s) ->
+            In A (propvar_subform_list (fst ir ++ snd ir)) ->
+            In A (propvar_subform_list (fst s ++ snd s)).
+  Proof.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  intros. remember (finite_ImpRules_premises_of_S s) as H1.
+  destruct H1. destruct x.
+  - assert (Canopy s = [s]). apply irred_nil. unfold inv_prems. rewrite <- HeqH1.
+    simpl. auto. rewrite H1 in H. inversion H. subst. auto. inversion H2.
+  - apply In_InT_seqs in H. apply fold_Canopy in H. destruct H ; subst ; auto.
+    destruct s0. destruct p0. unfold inv_prems in i. destruct (finite_ImpRules_premises_of_S s).
+    simpl in i. apply InT_flatten_list_InT_elem in i. destruct i. destruct p1. apply p0 in i1.
+    apply IHs with (y:=x0) in H0. 3: apply InT_In ; auto.
+    destruct i1. inversion i1 ; subst. simpl. inversion i ; subst. 2: inversion H1. simpl in H0.
+    repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
+    repeat rewrite propvar_subform_list_app in H0. repeat rewrite propvar_subform_list_app.
+    simpl in H0. simpl. repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
+    apply in_or_app. apply in_app_or in H0 ; destruct H0 ; auto. right. apply in_or_app.
+    apply in_app_or in H ; destruct H ; auto. right ; apply in_or_app ; right ; apply in_or_app ; auto.
+    apply in_app_or in H ; destruct H ; auto. right. apply in_or_app ; apply in_app_or in H ; destruct H ; auto.
+    right ; apply in_or_app ; right ; auto.
+    inversion i1 ; subst. simpl. inversion i ; subst. simpl in H0.
+    repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
+    repeat rewrite propvar_subform_list_app in H0. repeat rewrite propvar_subform_list_app.
+    simpl in H0. simpl. repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
+    apply in_or_app. apply in_app_or in H0 ; destruct H0 ; auto. right. apply in_or_app.
+    apply in_app_or in H ; destruct H ; auto. right ; apply in_or_app ; right ; apply in_or_app ; auto.
+    apply in_app_or in H ; destruct H ; auto. right. apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+    apply in_app_or in H ; destruct H ; auto. right ; apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
+    inversion H1 ; subst. 2: inversion H2. simpl in H0.
+    repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
+    repeat rewrite propvar_subform_list_app in H0. repeat rewrite propvar_subform_list_app.
+    simpl in H0. simpl. repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
+    apply in_or_app. apply in_app_or in H0 ; destruct H0 ; auto. right. apply in_or_app.
+    apply in_app_or in H ; destruct H ; auto. right ; apply in_or_app ; auto.
+    apply in_app_or in H ; destruct H ; auto. right. apply in_or_app ; right ; apply in_or_app ; auto.
+    right ; apply in_or_app ; right ; apply in_or_app ; right ; auto.
+    destruct i1. inversion i1 ; subst. simpl. inversion i ; subst. 2: inversion H1. unfold n_imp_subformS ; simpl.
+    repeat rewrite n_imp_subformLF_dist_app ; simpl ; repeat rewrite n_imp_subformLF_dist_app. lia.
+    inversion i1. subst. inversion i ; subst. unfold n_imp_subformS ; simpl.
+    repeat rewrite n_imp_subformLF_dist_app ; simpl ; repeat rewrite n_imp_subformLF_dist_app. lia.
+    inversion H1. subst. 2: inversion H2. unfold n_imp_subformS ; simpl.
+    repeat rewrite n_imp_subformLF_dist_app ; simpl ; repeat rewrite n_imp_subformLF_dist_app. lia.
+  Qed.
+ +
+  Lemma propvar_subform_list_restr_list_prop : forall l p q, In # q (propvar_subform_list (restr_list_prop p l)) ->
+                        ((q <> p) * (In # q (propvar_subform_list l))).
+  Proof.
+  induction l ; simpl ; intros ; auto. unfold restr_list_prop in H. destruct a as [n | | |]; simpl ; simpl in H ; auto.
+  destruct (eq_dec_form (# p) (# n)) ; subst. apply IHl in H. destruct H ; auto.
+  simpl in H. destruct H ; subst ; auto. split ; auto. rewrite H in n0. destruct (string_dec p q) ; subst; auto.
+  all: apply IHl in H ; destruct H ; auto.
+  all: split ; auto. all: apply in_or_app ; auto.
Qed.
+ +
+  Lemma In_list_prop_LF: forall l A, In A (list_prop_LF l) -> ((existsT2 q, A = # q) * In A l).
+  Proof.
+  induction l ; simpl ; intros ; auto. inversion H. apply In_InT in H. apply InT_app_or in H.
+  destruct H. destruct a as [n | | |]; simpl in i ; inversion i ; subst ; auto. split ; [exists n ; auto | auto]. inversion H0.
+  apply InT_In in i ; apply IHl in i ; auto. destruct i ; split ; auto.
+  Qed.
+ +
+  Lemma list_prop_LF_propvar_subform_list : forall l q, In # q (list_prop_LF l) -> In # q (propvar_subform_list l).
+  Proof.
+  induction l ; simpl ; intros ; auto. apply in_app_or in H ; destruct H ; auto. apply in_or_app ; left. destruct a ; simpl ; simpl in H ; try firstorder.
+  apply in_or_app ; right ; apply IHl in H ; auto.
+  Qed.
+ +
+  Lemma In_list_In_list_prop_LF : forall l P, In # P l -> In # P (list_prop_LF l).
+  Proof.
+  induction l ; simpl ; subst ; auto. intros. destruct H. subst ; simpl ; auto. apply in_or_app; right ; auto.
+  Qed.
+ +
+  Lemma In_list_In_propvar_subform_list : forall l P, In # P l -> In # P (propvar_subform_list l).
+  Proof.
+  induction l ; simpl ; subst ; auto. intros. destruct H. subst ; simpl ; auto. apply in_or_app; right ; auto.
+  Qed.
+ +
+  End Prop_Subform.
+ +
+  Section Diam_help.
+ +
+  Lemma In_unboxed_list : forall l A, In A (unboxed_list (top_boxes l)) -> (exists B, In B (top_boxes l) /\ B = Box A).
+  Proof.
+  induction l ; intros ; auto. simpl in H. exfalso ; auto. destruct a ; simpl ; simpl in H ; auto.
+  destruct H ; subst. exists (Box A) ; auto.
+  apply IHl in H. destruct H. firstorder.
+  Qed.
+ +
+  Lemma unboxed_list_In : forall l A, In (Box A) (top_boxes l) -> In A (unboxed_list (top_boxes l)).
+  Proof.
+  induction l ; simpl ; intros ; auto. destruct a ; simpl ; simpl in H ; auto. destruct H. inversion H ; subst. auto.
+  apply IHl in H ; auto.
+  Qed.
+ +
+  Lemma unboxed_list_In_unfold : forall l A, (exists B, In B (top_boxes l) /\ B = Box A) -> In A (unboxed_list (top_boxes l)).
+  Proof.
+  induction l ; simpl ; intros ; auto. destruct H. destruct H ; auto.
+  destruct a ; simpl ; simpl in H ; auto. destruct H. destruct H. subst. destruct H.
+  inversion H ; subst ; auto. right. apply unboxed_list_In ; auto.
+  Qed.
+ +
+  Lemma remove_list_decr_in: forall [l2 l1 l3 l4: list MPropF], NoDup l4 -> NoDup l3 ->
+    incl l1 l2 -> incl l3 l4 -> length (remove_list l2 l4) < length (remove_list l1 l3) ->
+    (exists A : MPropF, In A l2 /\ (In A l1 -> False)).
+  Proof.
+  induction l2 ; simpl.
+  - intros. destruct l1. simpl. simpl in H3. exfalso. pose (NoDup_incl_length H0 H2). simpl in l. lia.
+    exfalso. pose (H1 m). simpl in i ; apply i ; auto.
+  - intros. destruct (In_dec l2 a).
+    + assert (incl l1 l2). intro. intros. apply H1 in H4. inversion H4 ; subst ; auto.
+       pose (In_remove_list_remove_redund _ l4 _ i). rewrite e in H3.
+       pose (IHl2 _ _ _ H H0 H4 H2 H3). destruct e0. destruct H5. exists x ; split ; auto.
+    + destruct (In_dec l1 a).
+        * destruct (In_dec l4 a).
+          -- destruct (In_dec l3 a).
+            ++ assert (incl (remove eq_dec_form a l1) l2). intro. intros. apply in_remove in H4. destruct H4.
+                 apply H1 in H4. inversion H4 ; subst ; auto. exfalso ; apply H5 ; auto.
+                 assert ((remove_list l1 l3) = (remove_list (remove eq_dec_form a l1) (remove eq_dec_form a l3))).
+                 rewrite <- In_remove_list_remove_redund with (a:=a). rewrite permut_remove_remove_list.
+                 pose (permut_remove_remove_list a (remove eq_dec_form a l1) l3). rewrite <- e.
+                 pose (redund_remove_remove_list a l1 l3). rewrite e0. rewrite permut_remove_remove_list. auto. auto.
+                 assert (J0: NoDup (remove eq_dec_form a l4)). apply remove_preserv_NoDup ; auto.
+                 assert (J1: NoDup (remove eq_dec_form a l3)). apply remove_preserv_NoDup ; auto.
+                 assert (J2: incl (remove eq_dec_form a l3) (remove eq_dec_form a l4)). intro. intros.
+                 apply in_remove in H6. destruct H6. apply in_in_remove ; auto.
+                 rewrite H5 in H3. rewrite permut_remove_remove_list in H3.
+                 pose (IHl2 (remove eq_dec_form a l1) _ _ J0 J1 H4 J2 H3). destruct e. destruct H6.
+                 exists x ; split ; auto. intro. apply H7. apply in_in_remove ; auto. intro ; subst. auto.
+            ++ assert (incl (remove eq_dec_form a l1) l2). intro. intros. apply in_remove in H4. destruct H4.
+                 apply H1 in H4. inversion H4 ; subst ; auto. exfalso ; apply H5 ; auto.
+                 rewrite permut_remove_remove_list in H3.
+                 assert (J0: NoDup (remove eq_dec_form a l4)). apply remove_preserv_NoDup ; auto.
+                 assert (J1: incl l3 (remove eq_dec_form a l4)). intro. intros. apply in_in_remove ; auto.
+                 intro ; subst ; auto.
+                 assert (J:length (remove_list l2 (remove eq_dec_form a l4)) < length (remove_list (remove eq_dec_form a l1) l3)).
+                 assert ((remove_list l1 l3) = (remove_list (remove eq_dec_form a l1) l3)).
+                 pose (redund_remove_remove_list a l1 l3). rewrite notin_remove in e.
+                 symmetry in e. rewrite notin_remove in e. auto.
+                 1-2: intro ; apply In_remove_list_In_list in H5 ; auto. rewrite H5 in H3. auto.
+                 pose (IHl2 (remove eq_dec_form a l1) _ _ J0 H0 H4 J1 J). destruct e. destruct H5.
+                 exists x ; split ; auto. intro. apply H6. apply in_in_remove ; auto. intro ; subst. auto.
+          -- assert (In a l3 -> False). intro. apply n0 ; auto. rewrite permut_remove_remove_list in H3.
+              rewrite notin_remove in H3 ; auto.
+              assert (incl (remove eq_dec_form a l1) l2). intro. intros. apply in_remove in H5. destruct H5.
+              apply H1 in H5. inversion H5 ; subst ; auto. exfalso ; apply H6 ; auto.
+              assert (length (remove_list l2 l4) < length (remove_list (remove eq_dec_form a l1) l3)).
+              pose (redund_remove_remove_list a l1 l3). rewrite notin_remove in e. rewrite e. rewrite notin_remove ; auto.
+              intro. apply In_remove_list_In_list in H6 ; auto. intro. apply In_remove_list_In_list in H6 ; auto.
+              pose (IHl2 (remove eq_dec_form a l1) _ _ H H0 H5 H2 H6). destruct e. destruct H7.
+              exists x ; split ; auto. intro. apply H8. apply in_in_remove ; auto. intro ; subst. auto.
+        * exists a ; split ; auto.
+  Qed.
+ +
+  End Diam_help.
+ +
+  Section list_conj_disj_properties.
+ +
+  Lemma AndL : forall s A B, KS_prv (A :: B :: fst s, snd s) -> KS_prv (And A B :: fst s, snd s).
+  Proof.
+  intros. unfold And. unfold Neg.
+  apply derI with (ps:=[([] ++ fst s, [] ++ (A --> B --> Bot) :: snd s); ([] ++ Bot :: fst s, [] ++ snd s)]).
+  apply ImpL. assert (((A --> B --> Bot) --> Bot :: fst s, snd s) = ([] ++ (A --> B --> Bot) --> Bot :: fst s, snd s)). auto.
+  rewrite H. apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+  apply derI with (ps:=[([] ++ A :: fst s, [] ++ B --> Bot :: snd s)]). apply ImpR. apply ImpRRule_I.
+  apply dlCons. 2: apply dlNil. apply derI with (ps:=[([A] ++ B :: fst s, [] ++ Bot :: snd s)]).
+  assert (([] ++ A :: fst s, [] ++ B --> Bot :: snd s) = ([A] ++ fst s, [] ++ B --> Bot :: snd s)). auto. rewrite H.
+  apply ImpR. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+  assert (J0: derrec_height X = derrec_height X). auto.
+  assert (J1: wkn_R Bot ([A] ++ B :: fst s, [] ++ snd s) ([A] ++ B :: fst s, [] ++ Bot :: snd s)). apply wkn_RI.
+  pose (KS_wkn_R _ _ X J0 _ _ J1). destruct s0. auto. apply derI with (ps:=[]). apply BotL. apply BotLRule_I.
+  apply dlNil.
+  Qed.
+ +
+  Lemma AndR : forall s A B, KS_prv (fst s, A :: snd s) -> KS_prv (fst s, B :: snd s) -> KS_prv (fst s, And A B :: snd s).
+  Proof.
+  intros. unfold And. unfold Neg.
+  apply derI with (ps:=[([] ++ A --> B --> Bot :: fst s, [] ++ Bot :: snd s)]).
+  apply ImpR. assert ((fst s, (A --> B --> Bot) --> Bot :: snd s) = ([] ++ fst s, [] ++ (A --> B --> Bot) --> Bot :: snd s)). auto.
+  rewrite H. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+  apply derI with (ps:=[([] ++ fst s, [] ++ A :: Bot :: snd s);([] ++ B --> Bot :: fst s, [] ++ Bot :: snd s)]). apply ImpL.
+  apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+  assert (J0: derrec_height X = derrec_height X). auto.
+  assert (J1: wkn_R Bot ([] ++ fst s, [A] ++ snd s) ([] ++ fst s, [A] ++ Bot :: snd s)). apply wkn_RI.
+  pose (KS_wkn_R _ _ X J0 _ _ J1). destruct s0. auto.
+  apply derI with (ps:=[([] ++ fst s, [] ++ B :: Bot :: snd s);([] ++ Bot :: fst s, [] ++ Bot :: snd s)]). apply ImpL.
+  apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+  assert (J0: derrec_height X0 = derrec_height X0). auto.
+  assert (J1: wkn_R Bot ([] ++ fst s, [B] ++ snd s) ([] ++ fst s, [B] ++ Bot :: snd s)). apply wkn_RI.
+  pose (KS_wkn_R _ _ X0 J0 _ _ J1). destruct s0. auto. apply derI with (ps:=[]). apply BotL. apply BotLRule_I.
+  apply dlNil.
+  Qed.
+ +
+  Lemma list_conj_wkn_L : forall l s A, InT A l -> KS_prv (A :: fst s, snd s) -> KS_prv (list_conj l :: fst s, snd s).
+  Proof.
+  induction l.
+  - intros. inversion H.
+  - intros. inversion H ; subst.
+    * simpl. apply AndL.
+      assert (J0: derrec_height X = derrec_height X). auto.
+      assert (J1: wkn_L (list_conj l) (A :: fst s, snd s) (A :: list_conj l :: fst s, snd s)).
+      assert (A :: fst s = [A] ++ fst s). auto. rewrite H0.
+      assert (A :: list_conj l :: fst s = [A] ++ list_conj l :: fst s). auto. rewrite H1. apply wkn_LI.
+      pose (KS_wkn_L _ _ X J0 _ _ J1). destruct s0. auto.
+    * simpl. apply IHl in X ; auto.
+      assert (J0: derrec_height X = derrec_height X). auto.
+      assert (J1: wkn_L a (list_conj l :: fst s, snd s) (a :: list_conj l :: fst s, snd s)).
+      assert (a :: list_conj l :: fst s = [] ++ a :: list_conj l :: fst s). auto. rewrite H0.
+      assert ((list_conj l :: fst s,snd s) = ([] ++ list_conj l :: fst s,snd s)). auto. rewrite H2. apply wkn_LI.
+      pose (KS_wkn_L _ _ X J0 _ _ J1). destruct s0. apply AndL ; auto.
+  Qed.
+ +
+  Lemma list_conj_R : forall l s, (forall A, InT A l -> KS_prv (fst s, A :: snd s)) -> KS_prv (fst s, list_conj l :: snd s).
+  Proof.
+  induction l.
+  - intros. simpl. unfold Top.
+    apply derI with (ps:=[([] ++ Bot :: fst s, [] ++ Bot :: snd s)]).
+    apply ImpR. assert ((fst s, Bot --> Bot :: snd s) = ([] ++ fst s, [] ++ Bot --> Bot :: snd s)). auto.
+    rewrite H. apply ImpRRule_I. apply dlCons. 2: apply dlNil. apply derI with (ps:=[]). apply BotL.
+    apply BotLRule_I. apply dlNil.
+  - intros. simpl. apply AndR.
+    * apply X. apply InT_eq.
+    * simpl. apply IHl. intros. apply X. apply InT_cons ; auto.
+  Qed.
+ +
+  Lemma OrL : forall s A B, KS_prv (A :: fst s, snd s) -> KS_prv (B :: fst s, snd s) -> KS_prv (Or A B :: fst s, snd s).
+  Proof.
+  intros. unfold Or. unfold Neg.
+  apply derI with (ps:=[([] ++ fst s, [] ++ (A --> Bot) :: snd s); ([] ++ B :: fst s, [] ++ snd s)]).
+  apply ImpL. assert (((A --> Bot) --> B :: fst s, snd s) = ([] ++ (A --> Bot) --> B :: fst s, snd s)). auto.
+  rewrite H. apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+  apply derI with (ps:=[([] ++ A :: fst s, [] ++ Bot :: snd s)]). apply ImpR. apply ImpRRule_I.
+  apply dlCons. 2: apply dlNil.
+  assert (J0: derrec_height X = derrec_height X). auto.
+  assert (J1: wkn_R Bot (A :: fst s, [] ++ snd s) (A :: fst s, [] ++ Bot :: snd s)). apply wkn_RI.
+  pose (KS_wkn_R _ _ X J0 _ _ J1). destruct s0. auto. auto.
+  Qed.
+ +
+  Lemma OrR : forall s A B, KS_prv (fst s, A :: B :: snd s) -> KS_prv (fst s, Or A B :: snd s).
+  Proof.
+  intros. unfold Or. unfold Neg.
+  apply derI with (ps:=[([] ++ (A --> Bot) :: fst s, [] ++ B :: snd s)]).
+  apply ImpR. assert ((fst s, (A --> Bot) --> B :: snd s) = (fst s, [] ++ (A --> Bot) --> B :: snd s)). auto.
+  rewrite H. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+  apply derI with (ps:=[([] ++ fst s, [] ++ A :: B :: snd s);([] ++ Bot :: fst s, [] ++ B :: snd s)]).
+  apply ImpL. apply ImpLRule_I.
+  apply dlCons. 2: apply dlCons. 3: apply dlNil. simpl ; auto.
+  apply derI with (ps:=[]). apply BotL. apply BotLRule_I. apply dlNil.
+  Qed.
+ +
+  Lemma list_disj_L : forall l s, (forall A, InT A l -> KS_prv (A :: fst s, snd s)) -> KS_prv (list_disj l :: fst s, snd s).
+  Proof.
+  induction l.
+  - intros. simpl. apply derI with (ps:=[]). apply BotL. assert ((Bot :: fst s, snd s) = ([] ++ Bot :: fst s, snd s)). auto.
+    rewrite H. apply BotLRule_I. apply dlNil.
+  - intros. simpl. apply OrL.
+    * apply X. apply InT_eq.
+    * simpl. apply IHl. intros. apply X. apply InT_cons ; auto.
+  Qed.
+ +
+  Lemma list_disj_wkn_R : forall l s A, InT A l -> KS_prv (fst s, A :: snd s) -> KS_prv (fst s, list_disj l :: snd s).
+  Proof.
+  induction l.
+  - intros. inversion H.
+  - intros. inversion H ; subst.
+    * simpl. apply OrR.
+      assert (J0: derrec_height X = derrec_height X). auto.
+      assert (J1: wkn_R (list_disj l) (fst s, A :: snd s) (fst s, A :: list_disj l :: snd s)).
+      assert (A :: snd s = [A] ++ snd s). auto. rewrite H0.
+      assert (A :: list_disj l :: snd s = [A] ++ list_disj l :: snd s). auto. rewrite H1. apply wkn_RI.
+      pose (KS_wkn_R _ _ X J0 _ _ J1). destruct s0. auto.
+    * simpl. apply IHl in X ; auto.
+      assert (J0: derrec_height X = derrec_height X). auto.
+      assert (J1: wkn_R a (fst s, list_disj l :: snd s) (fst s, a :: list_disj l :: snd s)).
+      assert (a :: list_disj l :: snd s = [] ++ a :: list_disj l :: snd s). auto. rewrite H0.
+      assert ((fst s, list_disj l :: snd s) = (fst s, [] ++ list_disj l :: snd s)). auto. rewrite H2. apply wkn_RI.
+      pose (KS_wkn_R _ _ X J0 _ _ J1). destruct s0. apply OrR ; auto.
+  Qed.
+ +
+  Lemma DiamL_lim : forall A Γ0 Δ, (is_Boxed_list ) ->
+                                                                      (nobox_gen_ext Γ0) ->
+                                                                      (KS_prv (A :: unboxed_list , [])) ->
+                                                                      (KS_prv (Diam A :: Γ0, Δ)).
+  Proof.
+  intros. unfold Diam. unfold Neg.
+  apply derI with (ps:=[([] ++ Γ0, [] ++ Box (A --> Bot) :: Δ);([] ++ Bot :: Γ0, [] ++ Δ)]).
+  apply ImpL. assert ((Box (A --> Bot) --> Bot :: Γ0, Δ) = ([] ++ Box (A --> Bot) --> Bot :: Γ0, [] ++ Δ)). auto.
+  rewrite H0. apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
+  2: apply derI with (ps:=[]) ; try apply dlNil ; try apply BotL ; apply BotLRule_I.
+  apply derI with (ps:=[(unboxed_list , [A --> Bot])]).
+  apply KR. apply KRRule_I ; auto. apply dlCons. 2: apply dlNil.
+  apply derI with (ps:=[([] ++ A :: unboxed_list , [] ++ Bot :: [])]).
+  apply ImpR. assert ((unboxed_list , [A --> Bot]) = ([] ++ unboxed_list , [] ++ A --> Bot :: [])). auto.
+  rewrite H0. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
+  assert (J0: derrec_height X0 = derrec_height X0) ; auto.
+  assert (J3: wkn_R Bot (A :: unboxed_list , []%list) (A :: unboxed_list , [Bot])).
+  assert ((A :: unboxed_list , @nil MPropF) = (A :: unboxed_list , [] ++ [])).
+  rewrite app_nil_r. auto. rewrite H0.
+  assert ((A :: unboxed_list , [Bot]) = (A :: unboxed_list , [] ++ Bot :: [])). auto. rewrite H1.
+  apply wkn_RI. pose (KS_wkn_R _ _ X0 J0 _ _ J3). destruct s. simpl. auto.
+  Qed.
+ +
+  Lemma nobox_top_boxes : forall l, nobox_gen_ext (top_boxes l) l.
+  Proof.
+  induction l ; simpl ; auto. apply univ_gen_ext_nil. destruct a.
+  1-3: apply univ_gen_ext_extra ; auto ; intro ; inversion X ; inversion H.
+  apply univ_gen_ext_cons ; auto.
+  Qed.
+ +
+  Lemma is_init_Canopy : forall s, is_init s -> (forall leaf, InT leaf (Canopy s) -> is_init leaf).
+  Proof.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  intros. apply fold_Canopy in H. destruct H ; subst ; auto.
+  destruct s0 ; destruct p. unfold inv_prems in i. apply InT_flatten_list_InT_elem in i. destruct i.
+  destruct p. destruct (finite_ImpRules_premises_of_S s). simpl in i1. subst.
+  apply p in i1. destruct i1.
+  - inversion i1 ; subst. inversion i ; subst. 2: inversion H0.
+    assert (J0: n_imp_subformS (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) < n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1)).
+    unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+    lia. apply IHs with (leaf:=leaf) in J0 ; auto.
+    unfold is_init. destruct X.
+    left. inversion i2 ; subst. assert (InT (# P) (Γ0 ++ A :: Γ1)). apply InT_or_app.
+    assert (InT (# P) (Γ0 ++ Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
+    destruct H0 ; auto. right ; apply InT_cons ; auto. apply InT_split in H0. destruct H0. destruct s. rewrite e.
+    assert (InT (# P) (Δ0 ++ B :: Δ1)). apply InT_or_app.
+    assert (InT (# P) (Δ0 ++ A --> B :: Δ1)). rewrite <- H1. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
+    destruct H0 ; auto. inversion i3 ; subst. inversion H2. right ; apply InT_cons ; auto. apply InT_split in H0. destruct H0. destruct s.
+    rewrite e0. apply IdPRule_I.
+    right. inversion b ; subst. assert (InT (Bot) (Γ0 ++ A :: Γ1)). apply InT_or_app.
+    assert (InT (Bot) (Γ0 ++ Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
+    destruct H0 ; auto. right ; apply InT_cons ; auto. apply InT_split in H0. destruct H0. destruct s. rewrite e. apply BotLRule_I.
+  - inversion i1 ; subst. inversion i ; subst. 2: inversion H0. 3: inversion H1.
+    assert (J0: n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+    unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+    lia. apply IHs with (leaf:=leaf) in J0 ; auto.
+    unfold is_init. destruct X.
+    left. inversion i2 ; subst. assert (InT (# P) (Γ0 ++ Γ1)). apply InT_or_app.
+    assert (InT (# P) (Γ0 ++ A --> B :: Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
+    destruct H0 ; auto. inversion i3 ; subst. inversion H2. auto. apply InT_split in H0. destruct H0. destruct s. rewrite e.
+    assert (InT (# P) (Δ0 ++ A :: Δ1)). apply InT_or_app.
+    assert (InT (# P) (Δ0 ++ Δ1)). rewrite <- H1. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
+    destruct H0 ; auto. right ; apply InT_cons ; auto. apply InT_split in H0. destruct H0. destruct s.
+    rewrite e0. apply IdPRule_I.
+    right. inversion b ; subst. assert (InT (Bot) (Γ0 ++ Γ1)). apply InT_or_app.
+    assert (InT (Bot) (Γ0 ++ A --> B :: Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
+    destruct H0 ; auto. inversion i2 ; subst. inversion H1. auto. apply InT_split in H0. destruct H0. destruct s. rewrite e. apply BotLRule_I.
+    assert (J0: n_imp_subformS (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+    unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
+    lia. subst. apply IHs with (leaf:=leaf) in J0 ; auto.
+    unfold is_init. destruct X.
+    left. inversion i2 ; subst. assert (InT (# P) (Γ0 ++ B :: Γ1)). apply InT_or_app.
+    assert (InT (# P) (Γ0 ++ A --> B :: Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H1.
+    destruct H1 ; auto. inversion i3 ; subst. inversion H3. right ; apply InT_cons ; auto. apply InT_split in H1. destruct H1. destruct s. rewrite e.
+    apply IdPRule_I.
+    right. inversion b ; subst. assert (InT (Bot) (Γ0 ++ B :: Γ1)). apply InT_or_app.
+    assert (InT (Bot) (Γ0 ++ A --> B :: Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H1.
+    destruct H1 ; auto. inversion i2 ; subst. inversion H2. right ; apply InT_cons ; auto. apply InT_split in H1. destruct H1. destruct s. rewrite e. apply BotLRule_I.
+  Qed.
+ +
+  Lemma TopR : forall X Y0 Y1, KS_prv (X, Y0 ++ Top :: Y1).
+  Proof.
+  intros. unfold Top. apply derI with (ps:=[([] ++ Bot :: X, Y0 ++ Bot :: Y1)]).
+  apply ImpR. assert ((X, Y0 ++ Bot --> Bot :: Y1) = ([] ++ X, Y0 ++ Bot --> Bot :: Y1)). auto.
+  rewrite H. apply ImpRRule_I. apply dlCons. 2: apply dlNil. apply derI with (ps:=[]).
+  apply BotL. apply BotLRule_I. apply dlNil.
+  Qed.
+ +
+  Lemma TopL_remove : forall Y X0 X1, KS_prv (X0 ++ Top :: X1, Y) -> KS_prv (X0 ++ X1, Y).
+  Proof.
+  intros. assert (Y= [] ++ Y). auto. rewrite H. rewrite H in X. apply KS_cut_adm with (A:=Top) ; auto.
+  apply TopR.
+  Qed.
+ +
+  Theorem is_init_UI_equiv_Top : forall s, is_init s -> forall p X Y0 Y1, KS_prv (X, Y0 ++ Top --> (UI p s) :: Y1).
+  Proof.
+  intros. destruct (critical_Seq_dec s).
+  - assert (J0: GUI p s (UI p s)). apply UI_GUI ; auto.
+    pose (@GUI_inv_critic_init p s (UI p s) J0 c X). rewrite <- e.
+    apply derI with (ps:=[([] ++ Top :: X0, Y0 ++ Top :: Y1)]).
+    apply ImpR. epose (ImpRRule_I _ _ []). simpl in i ; apply i.
+    apply dlCons. 2: apply dlNil. apply TopR.
+  - assert (J0: GUI p s (UI p s)). apply UI_GUI ; auto.
+    assert (J1: Gimap (GUI p) (Canopy s) (map (UI p) (Canopy s))). apply Gimap_map. intros.
+    apply UI_GUI ; auto.
+    pose (@GUI_inv_not_critic p s (UI p s) (map (UI p) (Canopy s)) J0 f J1). rewrite <- e.
+    apply derI with (ps:=[([] ++ Top :: X0, Y0 ++ list_conj (map (UI p) (Canopy s)) :: Y1)]).
+    apply ImpR. epose (ImpRRule_I _ _ []). simpl in i ; apply i. apply dlCons. 2: apply dlNil. simpl.
+    apply KS_adm_list_exch_R with (s:=(Top :: X0, list_conj (map (UI p) (Canopy s)) :: Y0 ++ Y1)).
+    pose (list_conj_R (map (UI p) (Canopy s)) (Top :: X0, Y0 ++ Y1)). apply k. clear k.
+    intros. simpl. apply InT_map_iff in H. destruct H. destruct p0. subst.
+    assert (J2: GUI p x (UI p x)). apply UI_GUI ; auto.
+    assert (J3: critical_Seq x). apply Canopy_critical in i ; auto.
+    assert (J4: is_init x). apply is_init_Canopy in i ; auto.
+    pose (@GUI_inv_critic_init p x (UI p x) J2 J3 J4). rewrite <- e0. epose (TopR _ [] _). simpl in k ; apply k.
+    epose (list_exch_RI _ [] [_] Y0 [] _). simpl in l. apply l.
+  Qed.
+ +
+  Theorem is_init_UI : forall s, is_init s -> forall p X Y0 Y1, KS_prv (X, Y0 ++ UI p s :: Y1).
+  Proof.
+  intros. eapply is_init_UI_equiv_Top in X. apply ImpR_inv with (prem:=([] ++ Top :: X0, Y0 ++ UI p s :: Y1)) in X.
+  apply TopL_remove in X. simpl in X ; auto. assert ((X0, Y0 ++ Top --> UI p s :: Y1) = ([] ++ X0, Y0 ++ Top --> UI p s :: Y1)).
+  auto. rewrite H. apply ImpRRule_I.
+  Qed.
+ +
+  End list_conj_disj_properties.
+ +
+Section Canopy_lems.
+ +
+  Lemma inv_prems_measure : forall s0 s1, InT s1 (inv_prems s0) -> (measure s1 < measure s0).
+  Proof.
+  intros. unfold inv_prems in H. apply InT_flatten_list_InT_elem in H.
+  destruct H. destruct p. destruct (finite_ImpRules_premises_of_S s0). simpl in i0.
+  apply p in i0. destruct i0 ; inversion i0 ; subst. inversion i ; subst. unfold measure ; simpl.
+  repeat rewrite size_LF_dist_app ; simpl ; lia. inversion H0. inversion i ; subst.
+  unfold measure ; simpl ; repeat rewrite size_LF_dist_app ; simpl ; lia.
+  inversion H0 ; subst. unfold measure ; simpl ; repeat rewrite size_LF_dist_app ; simpl ; lia.
+  inversion H1.
+  Qed.
+ +
+  Lemma Canopy_measure: forall s0 s1, InT s1 (Canopy s0) -> ((s0 = s1) + (measure s1 < measure s0)).
+  Proof.
+  intros s ; induction on s as IHs with measure (measure s).
+  intros. remember (finite_ImpRules_premises_of_S s) as H0. destruct H0. destruct x.
+  - left. assert (Canopy s = [s]). apply irred_nil. unfold inv_prems ; rewrite <- HeqH0 ; auto.
+    rewrite H0 in H. inversion H ; subst ; auto. inversion H2.
+  - apply fold_Canopy in H. destruct H ; auto. right. destruct s0. destruct p0. apply IHs in i0.
+    destruct i0 ; subst ; auto. apply inv_prems_measure in i ; auto. apply inv_prems_measure in i. lia.
+    unfold inv_prems in i. apply InT_flatten_list_InT_elem in i.
+    destruct i. destruct p0. rewrite <- HeqH0 in i1. simpl in i1. apply p in i1. destruct i1 ; inversion i1 ; subst.
+    inversion i. subst. unfold measure ; simpl ; repeat rewrite size_LF_dist_app ; simpl ; lia.
+    inversion H0. inversion i ; subst. unfold measure ; simpl ; repeat rewrite size_LF_dist_app ; simpl ; lia.
+    inversion H0 ; subst. unfold measure ; simpl ; repeat rewrite size_LF_dist_app ; simpl ; lia.
+    inversion H1.
+  Qed.
+ +
+End Canopy_lems.
+ +
+
+
+ +
+ + + diff --git a/K.Interpolation.UIK_basics.html b/K.Interpolation.UIK_basics.html new file mode 100644 index 0000000..b3553b8 --- /dev/null +++ b/K.Interpolation.UIK_basics.html @@ -0,0 +1,293 @@ + + + + + + + + + + + + + +
+
+

K.Interpolation.UIK_basics

+ +
+  Require Import List Extraction.
+  Require Import Lia.
+ +
+  Require Import KS_export.
+ +
+Require Import UIK_Def_measure.
+Require Import UIK_Canopy.
+Require Import UIK_irred_short.
+ +
+Section Arithmetic.
+ +
+  Lemma lt_decT : forall m n, (m < n) + ((m < n) -> False).
+  Proof.
+  induction m ; destruct n. 1,3: right ; intro ; lia. left ; lia.
+  destruct (IHm n). left ; lia. right ; intro ; lia.
+  Qed.
+ +
+  End Arithmetic.
+ +
+  Section Logic_Abrv.
+ +
+  (* Conjunction of a list of formulas. *)
+ +
+  Fixpoint list_conj (l : list MPropF) : MPropF :=
+  match l with
+   | nil => Top
+   | h :: t => And h (list_conj t)
+  end.
+ +
+  (* Disjunction of a list of formulas. *)
+ +
+  Fixpoint list_disj (l : list MPropF) : MPropF :=
+  match l with
+   | nil => Bot
+   | h :: t => Or h (list_disj t)
+  end.
+ +
+  (* List of propositional variables in a formula. *)
+ +
+  Definition list_prop_F (A : MPropF) : list MPropF :=
+  match A with
+   | # P => [# P]
+   | _ => []
+  end.
+ +
+  (* List of propositional variables in a list of formula. *)
+ +
+  Fixpoint list_prop_LF (l : list MPropF) : list MPropF :=
+  match l with
+   | nil => []
+   | h :: t => (list_prop_F h) ++ (list_prop_LF t)
+  end.
+ +
+  Lemma list_prop_LF_In : forall l A, In A l -> (existsT2 p, A = # p) -> In A (list_prop_LF l).
+  Proof.
+  induction l ; auto. intros. simpl. destruct H0 ; subst. simpl in H. destruct H ; subst.
+  apply in_or_app ; left ; apply in_eq. apply in_or_app ; right. apply IHl ; auto. eexists ; auto.
+  Qed.
+ +
+  Lemma In_list_prop_LF : forall l A, In A (list_prop_LF l) -> In A l.
+  Proof.
+  induction l ; auto. intros. simpl. simpl in H. apply in_app_or in H ; destruct H.
+  left. destruct a ; simpl in H ; subst. destruct H ; auto ; try inversion H.
+  inversion H. 1,2: inversion H. right. apply IHl ; auto.
+  Qed.
+ +
+  Lemma In_list_prop_LF_bis : forall l A, In A (list_prop_LF l) -> ((In A l) * (existsT2 p, A = # p)).
+  Proof.
+  induction l ; auto ; intros. inversion H. simpl in H. split. apply In_list_prop_LF ; auto.
+  apply In_InT in H. apply InT_app_or in H ; destruct H.
+  destruct a ; simpl in i ; inversion i ; subst. eexists ; auto. inversion H0.
+  apply InT_In in i ; apply IHl in i ; destruct i ; auto.
+  Qed.
+ +
+  (* Restricted list of propositional variables. *)
+ +
+  Definition restr_list_prop p l : list MPropF := remove eq_dec_form (# p) (list_prop_LF l).
+ +
+  (* List of all premises through the KR rule for a sequent s.
+      Note that KR is not invertible. *)

+ +
+  Definition KR_prems (s : Seq) := flatten_list (proj1_sigT2 (finite_KR_premises_of_S s)).
+ +
+  (* Property of being an initial sequent. *)
+ +
+  Definition is_init s : Type := (IdPRule [] s) + (BotLRule [] s).
+ +
+  End Logic_Abrv.
+ +
+  Section Random.
+ +
+  Lemma InT_In_Seq: forall (s: Seq) l, (InT s l -> In s l) * (In s l -> InT s l).
+  Proof.
+  intros. split ; intros.
+  - apply InT_In ; auto.
+  - destruct s. apply In_InT_seqs ; auto.
+  Qed.
+ +
+  Lemma size_LF_nil_unbox_top_box : forall l, l <> nil ->
+      size_LF (unboxed_list (top_boxes l)) < size_LF l.
+  Proof.
+  induction l ; simpl ; auto ; intros.
+  - exfalso ; auto.
+  - destruct l.
+    + destruct a ; simpl ; lia.
+    + assert (m :: l <> []). intro H0 ; inversion H0. apply IHl in H0.
+       destruct a ; destruct m ; simpl in * ; try lia.
+  Qed.
+ +
+  End Random.
+ +
+  Section LtSeq_ind.
+ +
+  Definition LtSeq := fun s0 s1 => (lt (measure s0) (measure s1)).
+ +
+  Lemma wf_LtSeq : well_founded LtSeq.
+  Proof.
+  unfold LtSeq. apply Inverse_Image.wf_inverse_image.
+  apply Wf_nat.lt_wf.
+  Qed.
+ +
+  Variable (P : Seq -> Type).
+ +
+  Definition LtSeq_ind : (forall s0, (forall s1, LtSeq s1 s0 -> P s1) -> P s0) -> (forall s, P s).
+  Proof.
+  intros. induction s as [ s0 IHs0 ] using (well_founded_induction_type wf_LtSeq).
+  apply X; intros; apply IHs0 ; auto.
+  Defined.
+ +
+  End LtSeq_ind.
+ +
+  Section LtSeq_properties.
+ +
+  Theorem LtSeq_trans : forall x y z, LtSeq x y -> LtSeq y z -> LtSeq x z.
+  Proof.
+  unfold LtSeq. intros. lia.
+  Qed.
+ +
+  Lemma inv_prems_LtSeq : forall s0 s1, InT s1 (inv_prems s0) -> LtSeq s1 s0.
+  Proof.
+  intros. unfold inv_prems in H. apply InT_flatten_list_InT_elem in H.
+  destruct H. destruct p. destruct (finite_ImpRules_premises_of_S s0). simpl in i0.
+  apply p in i0. destruct i0 ; inversion i0 ; subst.
+  - inversion i ; subst. unfold LtSeq. unfold measure. simpl. repeat rewrite size_LF_dist_app ; simpl ; lia.
+    inversion H0.
+  - inversion i ; subst. unfold LtSeq. unfold measure. simpl. repeat rewrite size_LF_dist_app ; simpl ; lia.
+    inversion H0 ; subst. unfold LtSeq. unfold measure. simpl. repeat rewrite size_LF_dist_app ; simpl ; lia.
+    inversion H1.
+  Qed.
+ +
+  Lemma KR_prems_LtSeq : forall s0 s1, InT s1 (KR_prems s0) -> LtSeq s1 s0.
+  Proof.
+  intros s0 s1 H. unfold KR_prems in H. apply InT_flatten_list_InT_elem in H.
+  destruct H. destruct p. destruct (finite_KR_premises_of_S s0). simpl in i0.
+  apply p in i0. inversion i0 ; subst. unfold LtSeq.
+  unfold measure. inversion i ; subst. simpl. pose (nobox_gen_ext_top_boxes_identity X H).
+  rewrite e in *. pose (size_unboxed (top_boxes Γ0)). pose (size_top_boxes Γ0).
+  repeat rewrite size_LF_dist_app ; simpl. lia.
+  inversion H1.
+  Qed.
+ +
+  Lemma Canopy_nil : forall s0, (inv_prems s0 = []) -> (forall s1, InT s1 (Canopy s0) -> s1 = s0).
+  Proof.
+  intros. assert (Canopy s0 = [s0]). apply irred_nil. unfold inv_prems. unfold inv_prems in H. auto.
+  rewrite H1 in H0. inversion H0. subst. auto. inversion H3.
+  Qed.
+ +
+  Lemma Canopy_LtSeq: forall s0 s1, InT s1 (Canopy s0) -> ((s0 = s1) + (LtSeq s1 s0)).
+  Proof.
+  intros s ; induction on s as IHs with measure (n_imp_subformS s).
+  intros. remember (finite_ImpRules_premises_of_S s) as H0. destruct H0. destruct x.
+  - left. assert (Canopy s = [s]). apply irred_nil. unfold inv_prems ; rewrite <- HeqH0 ; auto.
+    rewrite H0 in H. inversion H ; subst ; auto. inversion H2.
+  - apply fold_Canopy in H. destruct H ; auto. right. destruct s0. destruct p0. apply IHs in i0.
+    destruct i0 ; subst ; auto. apply inv_prems_LtSeq in i ; auto. apply inv_prems_LtSeq in i.
+    apply (LtSeq_trans _ _ _ l0 i). unfold inv_prems in i. apply InT_flatten_list_InT_elem in i.
+    destruct i. destruct p0. rewrite <- HeqH0 in i1. simpl in i1. apply p in i1. destruct i1 ; inversion i1 ; subst.
+    inversion i. subst. unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+    inversion H0. inversion i ; subst. unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+    inversion H0 ; subst. unfold n_imp_subformS ; simpl ; repeat rewrite n_imp_subformLF_dist_app ; simpl ; lia.
+    inversion H1.
+  Qed.
+ +
+  End LtSeq_properties.
+ +
+  Section empty_seq.
+ +
+  Definition empty_seq_dec : forall (s: Seq), (s = ([],[])) + (s <> ([],[])).
+  Proof.
+  intros. destruct s. destruct l ; destruct l0 ; auto.
+  all: right ; intro H ; inversion H.
+  Defined.
+ +
+  Lemma not_init_empty_set : is_init ([],[]) -> False.
+  Proof.
+  intro. destruct X. inversion i. destruct Γ0 ; inversion H.
+  inversion b ; subst. destruct Γ0 ; inversion H.
+  Qed.
+ +
+  Lemma critical_empty_set : critical_Seq ([],[]).
+  Proof.
+  intros A HA ; simpl in *. inversion HA.
+  Qed.
+ +
+  End empty_seq.
+ +
+
+
+ +
+ + + diff --git a/K.Interpolation.UIK_braga.html b/K.Interpolation.UIK_braga.html new file mode 100644 index 0000000..3974311 --- /dev/null +++ b/K.Interpolation.UIK_braga.html @@ -0,0 +1,335 @@ + + + + + + + + + + + + + +
+
+

K.Interpolation.UIK_braga

+ +
+(**************************************************************)
+(*   Copyright Ian Shillito *                 *)
+(*                                                            *)
+(*                             * Affiliation ANU  *)
+(**************************************************************)
+(*      This file is distributed under the terms of the       *)
+(*         CeCILL v2.1 FREE SOFTWARE LICENSE AGREEMENT        *)
+(**************************************************************)
+ +
+
+ +
+Certification of uniform interpolant function (define below) + +
+ + +
+
+ +
+  Require Import List Extraction.
+  Require Import Lia.
+  Require Import String.
+ +
+  Require Import KS_export.
+ +
+  Require Import UIK_Def_measure.
+  Require Import UIK_Canopy.
+  Require Export UIK_basics.
+ +
+  Import ListNotations.
+ +
+  #[local] Infix "∈" := (@In _) (at level 70, no associativity).
+ +
+  Section imap.
+ +
+  Variables (X Y : Type)
+            (F : X -> Y -> Prop) (* We will instantiate F with GUI (to have mutal recursion). *)
+            (Ffun : forall x l m, F x l -> F x m -> l = m) (*Require that F is a function. *)
+            (D : X -> Prop) (* Domain of F *)
+            (f : forall x, D x -> sig (F x)). (* F is defined on the domain. *)
+ +
+  (* Proceed similarly as Dominique did with flatmap. *)
+ +
+  Inductive Gimap : list X -> list Y -> Prop :=
+    | Gim_nil : Gimap [] []
+    | Gim_cons {x y l m} : F x y
+                         -> Gimap l m
+                         -> Gimap (x::l) (y::m).
+ +
+  Hint Constructors Gimap : core.
+ +
+  Fact Gimap_inv_left l m :
+        Gimap l m
+      -> match l with
+        | [] => [] = m
+        | x::l => exists y m', F x y /\ Gimap l m' /\ m = y :: m'
+        end.
+  Proof. destruct 1; eauto. Qed.
+ +
+  Fact Gimap_inv_sg_left x m : Gimap [x] [m] -> F x m.
+  Proof.
+    intros. apply Gimap_inv_left in H. destruct H. destruct H. destruct H.
+    destruct H0. inversion H1. subst. auto.
+  Qed.
+ +
+  Fact Gimap_app_inv_left l1 l2 m :
+        Gimap (l1++l2) m
+      -> exists m1 m2, Gimap l1 m1 /\ Gimap l2 m2 /\ m = m1++m2.
+  Proof.
+    induction l1 as [ | x l1 IH1 ] in m |- *; simpl.
+    + exists [], m; auto.
+    + intros (y & m' & H1 & (m1 & m2 & H2 & H3 & ->)%IH1 & ->)%Gimap_inv_left.
+      exists (y::m1), m2. repeat split ; auto.
+  Qed.
+ +
+  Fixpoint imap l : (forall x, x l -> D x) -> sig (Gimap l).
+  Proof.
+    refine (match l with
+    | [] => fun _ => exist _ [] Gim_nil
+    | x::l => fun dl => let (y,hy) := f x _ in
+                    let (m,hm) := imap l _ in
+                    exist _ (y::m) (Gim_cons hy hm)
+    end); auto.
+    apply dl ; apply in_eq. intros. apply dl ; apply in_cons ; auto.
+  Defined.
+ +
+  Variables (g : X -> Y) (Hg : forall x, F x (g x)).
+ +
+  Fact Gimap_map l : Gimap l (map g l).
+  Proof. induction l; simpl; now constructor. Qed.
+ +
+  Fact Gimap_fun l0 : forall l1 l2, Gimap l0 l1 -> Gimap l0 l2 -> l1 = l2.
+  Proof. induction l0. intros. apply Gimap_inv_left in H. subst.
+             apply Gimap_inv_left in H0. auto. intros.
+             apply Gimap_inv_left in H. apply Gimap_inv_left in H0.
+             destruct H. destruct H. destruct H. destruct H1. destruct H0.
+             destruct H0. destruct H0. destruct H3. subst. pose (Ffun _ _ _ H H0).
+             rewrite e. pose (IHl0 _ _ H1 H3). rewrite e0. auto. Qed.
+ +
+  End imap.
+ +
+Arguments Gimap {X} {Y} _.
+Arguments imap {X} {Y} _ {D} _ {l}.
+ +
+  Section Gimap_cont.
+ +
+  Variables (X Y : Type)
+            (F : X -> Y -> Prop) (* We will instantiate F with GUI (to have mutal recursion). *)
+            (D : X -> Prop) (* Domain of F *)
+            (f : forall x, D x -> sig (F x)). (* F is defined on the domain. *)
+ +
+  Fact Gimap_fun_rest l0 : forall l1 l2, (forall x, InT x l0 -> forall y0 y1, F x y0 -> F x y1 -> y0 = y1) -> Gimap F l0 l1 -> Gimap F l0 l2 -> l1 = l2.
+  Proof. induction l0. intros l1 l2 Dom H H0. apply Gimap_inv_left in H. subst.
+             apply Gimap_inv_left in H0. auto. intros l1 l2 Dom H H0.
+             apply Gimap_inv_left in H. apply Gimap_inv_left in H0.
+             destruct H. destruct H. destruct H. destruct H1. destruct H0.
+             destruct H0. destruct H0. destruct H3. subst.
+             assert (J0: InT a (a :: l0)). apply InT_eq.
+             pose (Dom _ J0 _ _ H H0). rewrite e.
+             assert (J1: forall x : X, InT x l0 -> forall y0 y1 : Y, F x y0 -> F x y1 -> y0 = y1).
+             intros. apply Dom with (x:=x3) ; auto. apply InT_cons ; auto.
+             pose (IHl0 _ _ J1 H1 H3). rewrite e0. auto. Qed.
+ +
+  End Gimap_cont.
+ +
+  Section UI.
+ +
+  (* I define the graph of the function UI. *)
+ +
+  Variables (p : string). (* The variable we exclude from the interpolant. *)
+ +
+  Unset Elimination Schemes.
+ +
+  Inductive GUI : Seq -> MPropF -> Prop :=
+    | GUI_empty_seq {s} : (s = ([],[])) -> (* If the sequent is empty, output Bot. *)
+                                      GUI s Bot
+    | GUI_critic_init {s} : critical_Seq s -> (* If critical and initial, output Top. *)
+                                      is_init s ->
+                                      GUI s Top
+    | GUI_not_critic {s l} : ((critical_Seq s) -> False) -> (* If not critical, output conjunction of recursive calls of GUI on Canopy. *)
+                                      (Gimap GUI (Canopy s) l) ->
+                                      GUI s (list_conj l)
+    | GUI_critic_not_init {s l A} : critical_Seq s -> (* If critical but not initial, store the propositional variables, recursively call on
+                                                                                                               the KR premises of the sequent, and consider the diamond jump. *)

+                                           (s <> ([],[])) ->
+                                           (is_init s -> False) ->
+                                           (Gimap GUI (KR_prems s) l) ->
+                                           (GUI (unboxed_list (top_boxes (fst s)), []) A) ->
+                                           GUI s (Or (list_disj (restr_list_prop p (snd s)))
+                                                     (Or (list_disj (map Neg (restr_list_prop p (fst s))))
+                                                     (Or (list_disj (map Box l))
+                                                     (Diam A)))).
+ +
Set Elimination Schemes.
+ +
+  Lemma GUI_fun : forall x l m, GUI x l -> GUI x m -> l = m.
+  Proof.
+  apply (LtSeq_ind (fun x => forall l m, GUI x l -> GUI x m -> l = m)).
+  intros s IH l m H H0. subst. inversion H ; inversion H0 ; subst ; auto ; simpl in *. 1-8: exfalso ; auto.
+  6-9: exfalso ; auto. 1,3: apply not_init_empty_set ; auto. apply H4 ; apply critical_empty_set.
+  apply H1 ; apply critical_empty_set.
+  - assert (J0: (forall x : Seq, InT x (Canopy s) -> forall y0 y1 : MPropF, GUI x y0 -> GUI x y1 -> y0 = y1)).
+    intros. apply IH with (s1:=x) ; auto. destruct (Canopy_LtSeq s x H3) ; subst ; auto.
+    exfalso. apply H1. apply Canopy_critical with (s:=x) ; subst ; auto.
+    pose (Gimap_fun_rest _ _ GUI (Canopy s) l0 l1 J0). rewrite e ; auto.
+  - assert (J0: list_disj (map Box l0) = list_disj (map Box l1)).
+    assert (J00: (forall x : Seq, InT x (KR_prems s) -> forall y0 y1 : MPropF, GUI x y0 -> GUI x y1 -> y0 = y1)).
+    intros. apply IH with (s1:=x) ; auto. apply KR_prems_LtSeq ; auto.
+    pose (Gimap_fun_rest _ _ GUI (KR_prems s) l0 l1 J00). rewrite e ; auto.
+    assert (J1: A = A0).
+    { destruct (eq_dec_listsF (fst s) []) ; subst.
+       - rewrite e in * ; simpl in *. inversion H12 ; inversion H5 ; subst ; auto.
+         1-14: exfalso ; auto. 1,3: apply not_init_empty_set ; auto.
+         1-3: pose critical_empty_set ; auto.
+       - apply IH with (s1:=(unboxed_list (top_boxes (fst s)), [])) ; auto.
+         unfold LtSeq. unfold measure ; simpl.
+         pose (size_LF_nil_unbox_top_box _ n). lia. }
+    subst. rewrite J0. auto.
+  Qed.
+ +
+  Definition GUI_tot : forall s : Seq, {A : MPropF | GUI s A}.
+  Proof.
+  apply (LtSeq_ind (fun x => existsT A : MPropF, GUI x A)).
+  intros s IH. destruct (empty_seq_dec s).
+  - subst. exists Bot. apply GUI_empty_seq ; auto.
+  - destruct (critical_Seq_dec s).
+    -- destruct (dec_KS_init_rules s).
+      * assert (is_init s) ; auto. exists Top. apply GUI_critic_init ; auto.
+      * assert (is_init s -> False) ; auto.
+        assert ((forall x : Seq, In x (KR_prems s) -> {x0 : MPropF | GUI x x0})).
+        intros. apply IH with (s1:=x) ; auto. apply KR_prems_LtSeq ; auto. apply InT_In_Seq ; auto.
+        epose (@imap _ _ GUI (fun (x : Seq) => In x (KR_prems s)) H0 (KR_prems s)). simpl in s0. destruct s0 ; auto.
+        destruct (eq_dec_listsF (fst s) []).
+        + exists (Or (list_disj (restr_list_prop p (snd s))) (Or (list_disj (map Neg (restr_list_prop p (fst s))))
+           (Or (list_disj (map Box x)) (Diam Bot)))). apply GUI_critic_not_init ; auto. rewrite e ; simpl.
+           apply GUI_empty_seq ; auto.
+        + assert (J10: existsT A : MPropF, GUI (unboxed_list (top_boxes (fst s)), []%list) A). apply IH.
+           unfold LtSeq. unfold measure. simpl. pose (size_LF_nil_unbox_top_box (fst s) n0). lia. destruct J10.
+           exists (Or (list_disj (restr_list_prop p (snd s))) (Or (list_disj (map Neg (restr_list_prop p (fst s))))
+           (Or (list_disj (map Box x)) (Diam x0)))). apply GUI_critic_not_init ; auto.
+    -- assert ((forall x : Seq, In x (Canopy s) -> {x0 : MPropF | GUI x x0})).
+      intros. apply IH with (s1:=x) ; auto. destruct (Canopy_LtSeq s x) ; auto.
+      apply InT_In_Seq ; auto. subst. exfalso. apply f. apply InT_In_Seq in H ; apply Canopy_critical in H ; auto.
+      epose (@imap _ _ GUI (fun (x : Seq) => In x (Canopy s)) H (Canopy s)). simpl in s0. destruct s0 ; auto.
+      exists (list_conj x). apply GUI_not_critic ; auto.
+  Defined.
+ +
+  Fact GUI_inv_empty_seq {s A} : GUI s A -> s = ([],[]) -> Bot = A.
+  Proof. intros. pose (GUI_empty_seq H0). apply (GUI_fun _ _ _ g H). Qed.
+ +
+  Fact GUI_inv_critic_init {s A} : GUI s A -> critical_Seq s -> is_init s -> Top = A.
+  Proof. intros. pose (GUI_critic_init H0 X). apply (GUI_fun _ _ _ g H). Qed.
+ +
+  Fact GUI_inv_not_critic {s A l} : GUI s A -> (critical_Seq s -> False) ->
+                           (Gimap GUI (Canopy s) l) ->
+                           ((list_conj l) = A).
+  Proof.
+  intros. pose (GUI_not_critic H0 H1). apply (GUI_fun _ _ _ g H).
+  Qed.
+ +
+  Fact GUI_inv_critic_not_init {s A B l0 } : GUI s A -> critical_Seq s ->
+                           (s <> ([],[])) ->
+                           (is_init s -> False) ->
+                           (Gimap GUI (KR_prems s) l0) ->
+                           (GUI (unboxed_list (top_boxes (fst s)), []) B) ->
+                           ((Or (list_disj (restr_list_prop p (snd s)))
+                                                     (Or (list_disj (map Neg (restr_list_prop p (fst s))))
+                                                     (Or (list_disj (map Box l0))
+                                                     (Diam B)))) = A).
+  Proof.
+  intros. pose (GUI_critic_not_init H0 H1 H2 H3 H4). apply (GUI_fun _ _ _ g H).
+  Qed.
+ +
+  Let UI_pwc : forall x, sig (GUI x).
+  Proof.
+  apply GUI_tot.
+  Qed.
+ +
+  Definition UI x := proj1_sig (UI_pwc x).
+ +
+  Fact UI_spec x : GUI x (UI x).
+  Proof. apply (proj2_sig _). Qed.
+ +
+  Lemma UI_GUI : forall x A, UI x = A <-> GUI x A.
+  Proof.
+  intros. split ; intro ; subst.
+  apply UI_spec. unfold UI. destruct UI_pwc. simpl.
+  apply GUI_fun with (x:=x) ; auto.
+  Qed.
+ +
+  End UI.
+ +
+
+
+ +
+ + + diff --git a/K.Interpolation.UIK_irred_high_level.html b/K.Interpolation.UIK_irred_high_level.html new file mode 100644 index 0000000..d961971 --- /dev/null +++ b/K.Interpolation.UIK_irred_high_level.html @@ -0,0 +1,144 @@ + + + + + + + + + + + + + +
+
+

K.Interpolation.UIK_irred_high_level

+ +
+(**************************************************************)
+(*   Copyright Dominique Larchey-Wendling *                 *)
+(*                                                            *)
+(*                             * Affiliation LORIA -- CNRS  *)
+(**************************************************************)
+(*      This file is distributed under the terms of the       *)
+(*         CeCILL v2.1 FREE SOFTWARE LICENSE AGREEMENT        *)
+(**************************************************************)
+ +
+Require Import List Relations Utf8.
+ +
+Import ListNotations.
+ +
+#[local] Infix "∈" := (@In _) (at level 70, no associativity).
+ +
+Definition list_is_nil {X} (l : list X) : { l = [] } + { l [] }.
+Proof. now destruct l; [ left | right ]. Qed.
+ +
+Section irred_high_level.
+ +
+  Variables (X : Type)
+            (f : X list X)
+            (f_wf : well_founded (λ u v, u f v))
+            (irred : X list X)
+            (irred_nil : x, f x = [] irred x = [x])
+            (irred_not : x, f x [] irred x = flat_map irred (f x))
+            .
+ +
+  Fact irred_max x y : y irred x f y = [].
+  Proof.
+    induction (f_wf x) as [ x _ IHx ] in y.
+    destruct (list_is_nil (f x)) as [ H | H ].
+    + rewrite irred_nil; auto.
+      now intros [ <- | [] ].
+    + rewrite irred_not, in_flat_map; auto.
+      intros (z & ? & ?); eauto.
+  Qed.
+ +
+  Fact irred_reach x y : y irred x clos_refl_trans _ (λ u v, u f v) y x.
+  Proof.
+    induction (f_wf x) as [ x _ IHx ] in y.
+    destruct (list_is_nil (f x)) as [ H | H ].
+    + rewrite irred_nil; auto.
+      intros [ <- | [] ]; constructor 2.
+    + rewrite irred_not, in_flat_map; auto.
+      intros (z & Hz1 & Hz2).
+      constructor 3 with z; auto.
+      now constructor 1.
+  Qed.
+ +
+  Hint Resolve in_eq : core.
+ +
+  Theorem irred_high_level_spec x y : y irred x f y = [] clos_refl_trans _ (λ u v, u f v) y x.
+  Proof.
+    split.
+    + split.
+      * now apply irred_max with x.
+      * now apply irred_reach.
+    + intros (H1 & H2); revert H2 H1.
+      rewrite clos_rt_rtn1_iff.
+      induction 1 as [ | x z H1 H2 IH2 ]; intros H.
+      * rewrite irred_nil; auto.
+      * rewrite irred_not, in_flat_map.
+        - exists x; auto.
+        - now intros e; rewrite e in H1.
+  Qed.
+ +
+  Section provability.
+ +
+    Variables (P : X Prop)
+              (HP : x, f x [] P x Forall P (f x)).
+ +
+    Theorem irred_provability x : P x Forall P (irred x).
+    Proof.
+      induction (f_wf x) as [ x _ IHx ].
+      destruct (list_is_nil (f x)) as [ H | H ].
+      + rewrite irred_nil; auto.
+        split.
+        * repeat (constructor; auto).
+        * now inversion 1.
+      + rewrite irred_not; auto.
+        rewrite Forall_flat_map, HP; auto.
+        rewrite !Forall_forall.
+        split; firstorder.
+    Qed.
+ +
+  End provability.
+ +
+End irred_high_level.
+
+
+ +
+ + + diff --git a/K.Interpolation.UIK_irred_short.html b/K.Interpolation.UIK_irred_short.html new file mode 100644 index 0000000..9de8983 --- /dev/null +++ b/K.Interpolation.UIK_irred_short.html @@ -0,0 +1,332 @@ + + + + + + + + + + + + + +
+
+

K.Interpolation.UIK_irred_short

+ +
+(**************************************************************)
+(*   Copyright Dominique Larchey-Wendling *                 *)
+(*                                                            *)
+(*                             * Affiliation LORIA -- CNRS  *)
+(**************************************************************)
+(*      This file is distributed under the terms of the       *)
+(*         CeCILL v2.1 FREE SOFTWARE LICENSE AGREEMENT        *)
+(**************************************************************)
+ +
+
+ +
+Certification of + +
+ + let rec flatmap f = function + | -> + | x::l -> f x ++ flatmap f l + +
+ + let rec irred f x = + match f x with + | -> x + | _ -> flatmap (irred f) (f x) + +
+ + by extraction. + +
+ + Following a question by Ian Schillito + Also look at the following PR + +
+ + https://github.com/DmxLarchey/Kruskal-Trees/pull/5 + +
+ + +
+
+ +
+(* 
+   This is a standalone file, directly compile with
+
+      coqc irred.v 
+ *)

+ +
+Require Import List Utf8 Extraction.
+Import ListNotations.
+ +
+#[local] Infix "∈" := (@In _) (at level 70, no associativity).
+#[local] Hint Resolve in_eq in_cons : core.
+ +
+Definition list_is_nil {X} (l : list X) : { l = [] } + { l [] }.
+Proof. now destruct l; [ left | right ]. Defined.
+ +
+
+ +
+Directly via Fix_F after cleaning up from Braga using + the domain Dirred := Acc (λ u v, u ∈ f v) directly +
+
+Section flatmap.
+ +
+  Variables (X : Type)
+            (F : X list X Prop)
+            (D : X Prop)
+            (f : x, D x sig (F x)).
+ +
+  Implicit Type (l : list X).
+ +
+  Inductive Gflatmap : list X list X Prop :=
+    | Gfm_nil : Gflatmap [] []
+    | Gfm_cons {x y l m} : F x y
+                          Gflatmap l m
+                          Gflatmap (x::l) (y++m).
+ +
+  Hint Constructors Gflatmap : core.
+ +
+  Fact Gflatmap_inv_left l m :
+        Gflatmap l m
+       match l with
+        | [] => [] = m
+        | x::l => y m', F x y Gflatmap l m' m = y++m'
+        end.
+  Proof. destruct 1; eauto. Qed.
+ +
+  Fact Gflatmap_inv_sg_left x m : Gflatmap [x] m F x m.
+  Proof.
+    intros (y & ? & ? & <-%Gflatmap_inv_left & ->)%Gflatmap_inv_left.
+    now rewrite app_nil_r.
+  Qed.
+ +
+  Fact Gflatmap_app_inv_left l1 l2 m :
+        Gflatmap (l1++l2) m
+       m1 m2, Gflatmap l1 m1 Gflatmap l2 m2 m = m1++m2.
+  Proof.
+    induction l1 as [ | x l1 IH1 ] in m |- *; simpl.
+    + exists [], m; auto.
+    + intros (y & m' & H1 & (m1 & m2 & H2 & H3 & ->)%IH1 & ->)%Gflatmap_inv_left.
+      exists (y++m1), m2; rewrite app_assoc; auto.
+  Qed.
+ +
+  Fixpoint flatmap l : (x, x l D x) sig (Gflatmap l).
+  Proof.
+    refine (match l with
+    | [] => λ _ , exist _ [] Gfm_nil
+    | x::l => λ dl, let (y,hy) := f x _ in
+                    let (m,hm) := flatmap l _ in
+                    exist _ (y++m) (Gfm_cons hy hm)
+    end); auto.
+  Defined.
+ +
+  Variables (g : X list X) (Hg : x, F x (g x)).
+ +
+  Fact Gflatmap_flat_map l : Gflatmap l (flat_map g l).
+  Proof. induction l; simpl; now constructor. Qed.
+ +
+End flatmap.
+ +
+Arguments Gflatmap {X} _.
+Arguments flatmap {X} _ {D} _ {l}.
+ +
+Section irred.
+ +
+  Variables (X : Type) (f : X list X).
+ +
+  Implicit Type l : list X.
+ +
+  Unset Elimination Schemes.
+ +
+
+ +
+Because of nesting, induction principles are too weak, + see below for better ones +
+
+ +
+  Inductive Girred : X list X Prop :=
+    | Girred_nil {x} : f x = []
+                        Girred x [x]
+    | Girred_not {x l} : f x []
+                        Gflatmap Girred (f x) l
+                        Girred x l.
+ +
+  Set Elimination Schemes.
+ +
+  Fact Girred_inv_nil {x l} : Girred x l f x = [] [x] = l.
+  Proof. destruct 1 as [ | ? ? Hx ]; intros; trivial; now destruct Hx. Qed.
+ +
+  Fact Girred_inv_not {x l} : Girred x l f x [] Gflatmap Girred (f x) l.
+  Proof. destruct 1; intros G; trivial; now destruct G. Defined.
+ +
+  Hint Constructors Gflatmap Girred : core.
+  Hint Resolve Girred_inv_nil Girred_inv_not : core.
+ +
+  Section Girred_ind.
+ +
+    Variables (P : list X list X Prop)
+              (Q : X list X Prop)
+
+              (HP0 : P [] [])
+              (HP1 : x y l m, Girred x y Q x y Gflatmap Girred l m P l m P (x::l) (y++m))
+
+              (HQ0 : x, f x = [] Q x [x])
+              (HQ1 : x m, f x [] Gflatmap Girred (f x) m P (f x) m Q x m).
+ +
+    Fixpoint Girred_ind x m (dxm : Girred x m) { struct dxm } : Q x m.
+    Proof.
+      destruct (list_is_nil (f x)) as [ H | H ].
+      + destruct (Girred_inv_nil dxm H); auto.
+      + apply HQ1; auto.
+        generalize (Girred_inv_not dxm H).
+        clear dxm H.
+        induction 1; eauto.
+    Qed.
+ +
+  End Girred_ind.
+ +
+  Lemma Girred_fun : x l, Girred x l (λ x l, m, Girred x m l = m) x l.
+  Proof.
+    (* the property which is proved for (Gflatmap Girred) cannot be guessed by unification *)
+    apply Girred_ind with (P := fun l m1 => m2, Gflatmap Girred l m2 m1 = m2); eauto.
+    + now intros ? ?%Gflatmap_inv_left.
+    + intros ? ? ? ? ? ? ? ? ? (y' & m' & ? & ? & ->)%Gflatmap_inv_left; f_equal; eauto.
+  Qed.
+ +
+
+ +
+We build irred packed with conformity to Girred by Fix_F + induction over Acc (λ u v, u ∈ f v) x directly +
+
+  Let irred_pwc : x (dx : Acc (λ u v, u f v) x), sig (Girred x).
+  Proof.
+    refine (Fix_F _ (λ x irred_pwc,
+      match list_is_nil (f x) with
+      | left Hxf => exist _ [x] _
+      | right Hxf => let (m,hm) := flatmap Girred irred_pwc (λ _ h, h) in
+                     exist _ m _
+      end)); auto.
+  Defined.
+ +
+
+ +
+Now we can instanciate for _ ∈ f _ is well founded + and define irred as a total function +
+
+ +
+  Hypothesis hf : well_founded (λ u v, u f v).
+ +
+  Definition irred x := proj1_sig (irred_pwc x (hf x)).
+ +
+  Fact irred_spec x : Girred x (irred x).
+  Proof. apply (proj2_sig _). Qed.
+ +
+  Hint Resolve irred_spec : core.
+ +
+
+ +
+We conclude with fixpoint equations +
+
+ +
+  Fact irred_nil x : f x = [] irred x = [x].
+  Proof. intros; eapply Girred_fun; eauto. Qed.
+ +
+  Hint Resolve Gflatmap_flat_map : core.
+ +
+  Fact irred_not x : f x [] irred x = flat_map irred (f x).
+  Proof. intros; eapply Girred_fun; eauto. Qed.
+ +
+End irred.
+ +
+Arguments Girred {X}.
+Arguments irred {X f}.
+
+
+ +
+ + + diff --git a/K.KS.KS_additive_cut.html b/K.KS.KS_additive_cut.html new file mode 100644 index 0000000..c436e3a --- /dev/null +++ b/K.KS.KS_additive_cut.html @@ -0,0 +1,668 @@ + + + + + + + + + + + + + +
+
+

K.KS.KS_additive_cut

+ +
+Require Import List.
+Export ListNotations.
+Require Import Lia.
+Require Import PeanoNat Arith.
+ +
+Require Import KS_calc.
+Require Import KS_termination_measure.
+Require Import KS_termination.
+Require Import KS_exch.
+Require Import KS_ctr.
+Require Import KS_wkn.
+Require Import KS_dec.
+Require Import KS_inv_ImpR_ImpL.
+ +
+Theorem KS_cut_adm_main : forall n k A s Γ0 Γ1 Δ0 Δ1,
+                      (n = size A) ->
+                      (k = mhd s) ->
+                      (s = (Γ0 ++ Γ1, Δ0 ++ Δ1)) ->
+                      (KS_prv (Γ0 ++ Γ1, Δ0 ++ A :: Δ1)) ->
+                      (KS_prv (Γ0 ++ A :: Γ1, Δ0 ++ Δ1)) ->
+                      (KS_prv s).
+Proof.
+induction n as [n PIH] using (well_founded_induction_type lt_wf).
+induction k as [k SIH] using (well_founded_induction_type lt_wf).
+assert (DersNilF: dersrec KS_rules (fun _ : Seq => False) []).
+apply dersrec_nil.
+assert (DersNilT: dersrec KS_rules (fun _ : Seq => True) []).
+apply dersrec_nil.
+ +
+intros A s Γ0 Γ1 Δ0 Δ1 size MHD E D0 D1. inversion D0. inversion H.
+inversion D1. inversion H0.
+ +
+inversion X ; subst.
+ +
+(* Left rule is IdP *)
+- inversion H1. subst. apply list_split_form in H3. destruct H3.
+  * destruct s.
+    + repeat destruct p. subst. inversion X1.
+    (* Right rule is IdP *)
+    { inversion H. subst. assert (J0 : InT (# P0) (Γ0 ++ # P :: Γ1)). rewrite <- H6. apply InT_or_app.
+      right. apply InT_eq. apply InT_app_or in J0. destruct J0.
+      - apply InT_split in i. destruct i. destruct s. subst. rewrite H2. repeat rewrite <- app_assoc.
+        assert (IdPRule [] (x ++ (# P0 :: x0) ++ Γ1, Δ2 ++ # P0 :: Δ3)). apply IdPRule_I. apply IdP in H0.
+        pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (x ++ (# P0 :: x0) ++ Γ1, Δ2 ++ # P0 :: Δ3) H0 DersNilF). assumption.
+      - inversion i.
+        + inversion H3. subst.
+          assert (IdPRule [] (Γ2 ++ # P0 :: Γ3, Δ2 ++ # P0 :: Δ3)). apply IdPRule_I. apply IdP in H0.
+          pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) (Γ2 ++ # P0 :: Γ3, Δ2 ++ # P0 :: Δ3) H0 DersNilF). assumption.
+        + apply InT_split in H3. destruct H3. destruct s. subst.
+          assert (J0 : InT (# P0) (Γ2 ++ # P :: Γ3)). rewrite H2. apply InT_or_app.
+          right. apply InT_or_app. right. apply InT_eq. apply InT_split in J0. destruct J0. destruct s.
+          rewrite e. assert (IdPRule [] (x1 ++ # P0 :: x2, Δ2 ++ # P0 :: Δ3)).
+          apply IdPRule_I. apply IdP in H0.
+          pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) (x1 ++ # P0 :: x2, Δ2 ++ # P0 :: Δ3) H0 DersNilF). assumption. }
+    (* Right rule is BotL *)
+    { inversion H. subst. assert (J0 : InT (Bot) (Γ0 ++ # P :: Γ1)). rewrite <- H6. apply InT_or_app.
+      right. apply InT_eq. apply InT_app_or in J0. destruct J0.
+      - apply InT_split in i. destruct i. destruct s. subst. rewrite H2. rewrite <- app_assoc.
+        assert (BotLRule [] (x ++ (Bot :: x0) ++ Γ1, Δ0 ++ Δ1)). apply BotLRule_I. apply BotL in H0.
+        pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (x ++ (Bot :: x0) ++ Γ1, Δ0 ++ Δ1) H0 DersNilF). assumption.
+      - inversion i.
+        + inversion H3.
+        + apply InT_split in H3. destruct H3. destruct s. subst. rewrite H2. rewrite app_assoc.
+          assert (BotLRule [] ((Γ0 ++ x) ++ Bot :: x0, Δ0 ++ Δ1)). apply BotLRule_I. apply BotL in H0.
+          pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) ((Γ0 ++ x) ++ Bot :: x0, Δ0 ++ Δ1) H0 DersNilF). assumption. }
+    (* Right rule is ImpR *)
+    { inversion H. subst. assert (InT # P (Γ0 ++ Γ1)). rewrite <- H2. apply InT_or_app.
+      right. apply InT_eq. apply InT_app_or in H0. destruct H0.
+      - apply InT_split in i. destruct i.
+        destruct s. subst. repeat rewrite <- app_assoc in D1. simpl in D1.
+        assert (E0: derrec_height D1 = derrec_height D1). reflexivity.
+        assert (J0 : ctr_L # P (x ++ # P :: x0 ++ # P :: Γ1, Δ0 ++ Δ1)
+        (x ++ # P :: x0 ++ Γ1, Δ0 ++ Δ1)). apply ctr_LI.
+        pose (@KS_hpadm_ctr_L (derrec_height D1) (x ++ # P :: x0 ++ # P :: Γ1, Δ0 ++ Δ1)
+        D1 E0 (x ++ # P :: x0 ++ Γ1, Δ0 ++ Δ1) (# P) J0). destruct s. clear l. rewrite H2.
+        rewrite <- app_assoc. rewrite H7. assumption.
+      - apply InT_split in i. destruct i. destruct s. subst.
+        assert (E0: derrec_height D1 = derrec_height D1). reflexivity.
+        assert (J0 : ctr_L # P (Γ0 ++ # P :: x ++ # P :: x0, Δ0 ++ Δ1)
+        (Γ0 ++ # P :: x ++ x0, Δ0 ++ Δ1)). apply ctr_LI.
+        pose (@KS_hpadm_ctr_L (derrec_height D1) (Γ0 ++ # P :: x ++ # P :: x0, Δ0 ++ Δ1)
+        D1 E0 (Γ0 ++ # P :: x ++ x0, Δ0 ++ Δ1) (# P) J0). destruct s. clear l. rewrite H2.
+        assert (J5 : list_exch_L (Γ0 ++ # P :: x ++ x0, Δ0 ++ Δ1) (Γ0 ++ x ++ # P :: x0, Δ0 ++ Δ1)).
+        assert (Γ0 ++ # P :: x ++ x0 = Γ0 ++ [# P] ++ x ++ [] ++ x0). reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ x ++ # P :: x0 = Γ0 ++ [] ++ x ++ [# P] ++ x0). reflexivity. rewrite H0. clear H0.
+        apply list_exch_LI. pose (KS_adm_list_exch_L _ x1 _ J5). rewrite H7. assumption. }
+    (* Right rule is ImpL *)
+    { inversion H. subst. assert (InT # P (Γ0 ++ Γ1)). rewrite <- H2. apply InT_or_app.
+      right. apply InT_eq. apply InT_app_or in H0. destruct H0.
+      - apply InT_split in i. destruct i.
+        destruct s. subst. repeat rewrite <- app_assoc in D1. simpl in D1.
+        assert (E0: derrec_height D1 = derrec_height D1). reflexivity.
+        assert (J0 : ctr_L # P (x ++ # P :: x0 ++ # P :: Γ1, Δ0 ++ Δ1)
+        (x ++ # P :: x0 ++ Γ1, Δ0 ++ Δ1)). apply ctr_LI.
+        pose (@KS_hpadm_ctr_L (derrec_height D1) (x ++ # P :: x0 ++ # P :: Γ1, Δ0 ++ Δ1)
+        D1 E0 (x ++ # P :: x0 ++ Γ1, Δ0 ++ Δ1) (# P) J0). destruct s. clear l. rewrite H2.
+        rewrite <- app_assoc. rewrite H7. assumption.
+      - apply InT_split in i. destruct i. destruct s. subst.
+        assert (E0: derrec_height D1 = derrec_height D1). reflexivity.
+        assert (J0 : ctr_L # P (Γ0 ++ # P :: x ++ # P :: x0, Δ0 ++ Δ1)
+        (Γ0 ++ # P :: x ++ x0, Δ0 ++ Δ1)). apply ctr_LI.
+        pose (@KS_hpadm_ctr_L (derrec_height D1) (Γ0 ++ # P :: x ++ # P :: x0, Δ0 ++ Δ1)
+        D1 E0 (Γ0 ++ # P :: x ++ x0, Δ0 ++ Δ1) (# P) J0). destruct s. clear l. rewrite H2.
+        assert (J5 : list_exch_L (Γ0 ++ # P :: x ++ x0, Δ0 ++ Δ1) (Γ0 ++ x ++ # P :: x0, Δ0 ++ Δ1)).
+        assert (Γ0 ++ # P :: x ++ x0 = Γ0 ++ [# P] ++ x ++ [] ++ x0). reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ x ++ # P :: x0 = Γ0 ++ [] ++ x ++ [# P] ++ x0). reflexivity. rewrite H0. clear H0.
+        apply list_exch_LI. pose (KS_adm_list_exch_L _ x1 _ J5). rewrite H7. assumption. }
+    (* Right rule is KR *)
+    { inversion X3. subst. assert (InT # P (Γ0 ++ Γ1)). rewrite <- H2. apply InT_or_app.
+      right. apply InT_eq. apply InT_app_or in H. destruct H.
+      - apply InT_split in i. destruct i.
+        destruct s. subst. repeat rewrite <- app_assoc in D1. simpl in D1.
+        assert (E0: derrec_height D1 = derrec_height D1). reflexivity.
+        assert (J0 : ctr_L # P (x ++ # P :: x0 ++ # P :: Γ1, Δ0 ++ Δ1)
+        (x ++ # P :: x0 ++ Γ1, Δ0 ++ Δ1)). apply ctr_LI.
+        pose (@KS_hpadm_ctr_L (derrec_height D1) (x ++ # P :: x0 ++ # P :: Γ1, Δ0 ++ Δ1)
+        D1 E0 (x ++ # P :: x0 ++ Γ1, Δ0 ++ Δ1) (# P) J0). destruct s. clear l. rewrite H2.
+        rewrite <- app_assoc. rewrite H6. assumption.
+      - apply InT_split in i. destruct i. destruct s. subst.
+        assert (E0: derrec_height D1 = derrec_height D1). reflexivity.
+        assert (J0 : ctr_L # P (Γ0 ++ # P :: x ++ # P :: x0, Δ0 ++ Δ1)
+        (Γ0 ++ # P :: x ++ x0, Δ0 ++ Δ1)). apply ctr_LI.
+        pose (@KS_hpadm_ctr_L (derrec_height D1) (Γ0 ++ # P :: x ++ # P :: x0, Δ0 ++ Δ1)
+        D1 E0 (Γ0 ++ # P :: x ++ x0, Δ0 ++ Δ1) (# P) J0). destruct s. clear l. rewrite H2.
+        assert (J5 : list_exch_L (Γ0 ++ # P :: x ++ x0, Δ0 ++ Δ1) (Γ0 ++ x ++ # P :: x0, Δ0 ++ Δ1)).
+        assert (Γ0 ++ # P :: x ++ x0 = Γ0 ++ [# P] ++ x ++ [] ++ x0). reflexivity. rewrite H. clear H.
+        assert (Γ0 ++ x ++ # P :: x0 = Γ0 ++ [] ++ x ++ [# P] ++ x0). reflexivity. rewrite H. clear H.
+        apply list_exch_LI. pose (KS_adm_list_exch_L _ x1 _ J5). rewrite H6. assumption. }
+    + repeat destruct s. repeat destruct p. subst. assert (IdPRule [] (Γ2 ++ # P :: Γ3, (Δ0 ++ x0) ++ # P :: Δ3)).
+      apply IdPRule_I. rewrite <- app_assoc in H. apply IdP in H.
+      pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[]) (Γ2 ++ # P :: Γ3, Δ0 ++ x0 ++ # P :: Δ3) H DersNilF). assumption.
+  * repeat destruct s. repeat destruct p. subst. assert (IdPRule [] (Γ2 ++ # P :: Γ3, Δ2 ++ # P :: x ++ Δ1)).
+    apply IdPRule_I. apply IdP in H. rewrite <- app_assoc.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[]) (Γ2 ++ # P :: Γ3, Δ2 ++ (# P :: x) ++ Δ1) H DersNilF). assumption.
+ +
+(* Left rule is BotL *)
+- inversion H1. subst. assert (BotLRule [] (Γ2 ++ Bot :: Γ3, Δ0 ++ Δ1)).
+  apply BotLRule_I. apply BotL in H.
+  pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+  (ps:=[]) (Γ2 ++ Bot :: Γ3, Δ0 ++ Δ1) H DersNilF).
+  assumption.
+ +
+(* Left rule is ImpR *)
+- inversion H1. subst. apply list_split_form in H3. destruct H3.
+  * destruct s.
+    + repeat destruct p. subst. inversion X1.
+      (* Right rule is IdP *)
+      { inversion H. subst. assert (J0 : InT (# P) (Γ0 ++ (A0 --> B) :: Γ1)). rewrite <- H6. apply InT_or_app.
+        right. apply InT_eq. apply InT_app_or in J0. destruct J0.
+        - apply InT_split in i. destruct i. destruct s. subst. rewrite H2. rewrite <- app_assoc.
+          assert (IdPRule [] (x ++ (# P :: x0) ++ Γ1, Δ2 ++ # P :: Δ3)). apply IdPRule_I. apply IdP in H0.
+          pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) (x ++ (# P :: x0) ++ Γ1, Δ2 ++ # P :: Δ3) H0 DersNilF). assumption.
+        - inversion i.
+          * inversion H3.
+          * apply InT_split in H3. destruct H3. destruct s. subst. rewrite H2. rewrite app_assoc.
+            assert (IdPRule [] ((Γ0 ++ x) ++ # P :: x0, Δ2 ++ # P :: Δ3)). apply IdPRule_I. apply IdP in H0.
+            pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) ((Γ0 ++ x) ++ # P :: x0, Δ2 ++ # P :: Δ3) H0 DersNilF). assumption. }
+      (* Right rule is BotL *)
+      { inversion H. subst. rewrite H2. assert (J0 : InT (Bot) (Γ0 ++ (A0 --> B) :: Γ1)). rewrite <- H6. apply InT_or_app.
+        right. apply InT_eq. apply InT_app_or in J0. destruct J0.
+        - apply InT_split in i. destruct i. destruct s. subst. rewrite <- app_assoc.
+          assert (BotLRule [] (x ++ (Bot :: x0) ++ Γ1, Δ0 ++ Δ1)). apply BotLRule_I. apply BotL in H0.
+          pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) (x ++ (Bot :: x0) ++ Γ1, Δ0 ++ Δ1) H0 DersNilF). assumption.
+        - inversion i.
+          * inversion H3.
+          * apply InT_split in H3. destruct H3. destruct s. subst. rewrite app_assoc.
+            assert (BotLRule [] ((Γ0 ++ x) ++ Bot :: x0, Δ0 ++ Δ1)). apply BotLRule_I. apply BotL in H0.
+            pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) ((Γ0 ++ x) ++ Bot :: x0, Δ0 ++ Δ1) H0 DersNilF). assumption. }
+      (* Right rule is ImpR *)
+      { inversion H. subst. inversion X0. inversion X2. subst. clear X4. clear X6. rewrite <- H7 in D1.
+        assert (J1 : list_exch_L (Γ4 ++ A :: Γ5, Δ2 ++ B0 :: Δ3) (A :: Γ0 ++ A0 --> B :: Γ1, Δ2 ++ B0 :: Δ3)).
+        assert (Γ4 ++ A :: Γ5 = [] ++ [] ++ Γ4 ++ [A] ++ Γ5). reflexivity. rewrite H0. clear H0.
+        assert (A :: Γ0 ++ A0 --> B :: Γ1 = [] ++ [A] ++ Γ4 ++ [] ++ Γ5). rewrite <- H6. reflexivity.
+        rewrite H0. clear H0. apply list_exch_LI. pose (d:=KS_adm_list_exch_L _ X5 _ J1). rewrite H2.
+        assert (ImpRRule [([] ++ A :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3)] ([] ++ Γ0 ++ Γ1, Δ2 ++ A --> B0 :: Δ3)). apply ImpRRule_I.
+        simpl in H0.
+        assert (J3: KS_rules [(A :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3)] (Γ0 ++ Γ1, Δ2 ++ A --> B0 :: Δ3)).
+        apply ImpR ; try intro ; try apply f ; try rewrite <- H7 ; try auto ; try assumption.
+        assert (J31: KS_rules [(A :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3)] (Γ0 ++ Γ1, Δ2 ++ A --> B0 :: Δ3)).
+        apply ImpR ; try assumption.
+        assert (J21: In (A :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3) [(A :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3)]). apply in_eq.
+        pose (RA_mhd_decreases _ _ J3 _ J21). rewrite <- H7 in SIH.
+        assert (J5: size (A0 --> B) = size (A0 --> B)). reflexivity.
+        assert (J6: mhd (A :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3) = mhd (A :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3)). reflexivity.
+        assert (J7 : (A :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3) = ((A :: Γ0) ++ Γ1, [] ++ Δ2 ++ B0 :: Δ3)). reflexivity.
+        pose (d0:=@SIH (mhd (A :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3)) l (A0 --> B) (A :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3)
+        (A :: Γ0) Γ1 [] (Δ2 ++ B0 :: Δ3) J5 J6 J7). simpl in d0.
+        assert (J8 : list_exch_R (Γ0 ++ Γ1, Δ0 ++ A0 --> B :: Δ1) (Γ0 ++ Γ1, A0 --> B :: Δ2 ++ A --> B0 :: Δ3)).
+        assert (Δ0 ++ A0 --> B :: Δ1 = [] ++ [] ++ Δ0 ++ [A0 --> B] ++ Δ1). reflexivity. rewrite H3. clear H3.
+        assert (A0 --> B :: Δ2 ++ A --> B0 :: Δ3 = [] ++ [A0 --> B] ++ Δ0 ++ [] ++ Δ1). rewrite H7.
+        reflexivity. rewrite H3. clear H3. apply list_exch_RI. pose (d1:=KS_adm_list_exch_R _ D0 _ J8).
+        assert (ImpRRule [([] ++ A :: Γ0 ++ Γ1, (A0 --> B :: Δ2) ++ B0 :: Δ3)] ([] ++ Γ0 ++ Γ1, (A0 --> B :: Δ2) ++ A --> B0 :: Δ3)).
+        apply ImpRRule_I. simpl in H3. pose (d2:=ImpR_inv _ _ d1 H3). pose (d3:=d0 d2 d). pose (dlCons d3 DersNilF).
+        apply ImpR in H0 ; try intro ; try apply f ; try rewrite <- H7 ; try auto ; try assumption.
+        pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[(A :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3)]) (Γ0 ++ Γ1, Δ2 ++ A --> B0 :: Δ3) H0 d4). assumption. }
+      (* Right rule is ImpL *)
+      { inversion H. subst. inversion X0. inversion X2. subst. clear X4. inversion X6. subst. clear X7.
+        clear X6. apply list_split_form in H6. destruct H6.
+        - destruct s.
+          * repeat destruct p. inversion e0. subst. rewrite H2.
+            assert (J1 : list_exch_L (Γ2 ++ A0 :: Γ3, Δ0 ++ B :: Δ1) (A0 :: Γ0 ++ Γ1, Δ0 ++ B :: Δ1)).
+            assert (Γ2 ++ A0 :: Γ3 = [] ++ [] ++ Γ2 ++ [A0] ++ Γ3). reflexivity. rewrite H0. clear H0.
+            assert (A0 :: Γ0 ++ Γ1 = [] ++ [A0] ++ Γ2 ++ [] ++ Γ3). rewrite <- H2. reflexivity.
+            rewrite H0. clear H0. apply list_exch_LI. pose (d:=KS_adm_list_exch_L _ X3 _ J1).
+            assert (J2 : list_exch_R (A0 :: Γ0 ++ Γ1, Δ0 ++ B :: Δ1) (A0 :: Γ0 ++ Γ1, B :: Δ2 ++ Δ3)).
+            assert (Δ0 ++ B :: Δ1 = [] ++ [] ++ Δ0 ++ [B] ++ Δ1). reflexivity. rewrite H0. clear H0.
+            assert (B :: Δ2 ++ Δ3 = [] ++ [B] ++ Δ0 ++ [] ++ Δ1). rewrite H7. reflexivity. rewrite H0. clear H0.
+            apply list_exch_RI. pose (d0:=KS_adm_list_exch_R _ d _ J2).
+            assert (J3: size A0 < size (A0 --> B)). simpl. lia.
+            assert (J4: size A0 = size A0). reflexivity.
+            assert (J5: mhd (Γ2 ++ Γ3, B :: Δ2 ++ Δ3) = mhd (Γ2 ++ Γ3, B :: Δ2 ++ Δ3)). reflexivity.
+            assert (J6: (Γ2 ++ Γ3, B :: Δ2 ++ Δ3) = ([] ++ Γ2 ++ Γ3, (B :: Δ2) ++ Δ3)). reflexivity.
+            pose (d1:=PIH _ J3 (mhd (Γ2 ++ Γ3, B :: Δ2 ++ Δ3)) A0 (Γ2 ++ Γ3, B :: Δ2 ++ Δ3) [] (Γ2 ++ Γ3)
+            (B :: Δ2) Δ3 J4 J5 J6). simpl in d1.
+            assert (J7 : wkn_R B (Γ2 ++ Γ3, Δ2 ++ A0 :: Δ3) (Γ2 ++ Γ3, B :: Δ2 ++ A0 :: Δ3)).
+            assert ((Γ2 ++ Γ3, Δ2 ++ A0 :: Δ3) = (Γ2 ++ Γ3, [] ++ Δ2 ++ A0 :: Δ3)). reflexivity. rewrite H0. clear H0.
+            assert ((Γ2 ++ Γ3, B :: Δ2 ++ A0 :: Δ3) = (Γ2 ++ Γ3, [] ++ B :: Δ2 ++ A0 :: Δ3)).
+            reflexivity. rewrite H0. clear H0. apply wkn_RI. rewrite <- H2 in X5.
+            assert (J8 : derrec_height X5 = derrec_height X5).
+            reflexivity. pose (KS_wkn_R _ _ X5 J8 _ _ J7). destruct s. rewrite <- H2 in d0. pose (d2:=d1 x d0).
+            assert (J9: size B < size (A0 --> B)). simpl. lia.
+            assert (J10: size B = size B). reflexivity.
+            assert (J11: mhd (Γ2 ++ Γ3, Δ2 ++ Δ3) = mhd (Γ2 ++ Γ3, Δ2 ++ Δ3)). reflexivity.
+            assert (J12: (Γ2 ++ Γ3, Δ2 ++ Δ3) = (Γ2 ++ Γ3, [] ++ Δ2 ++ Δ3)). reflexivity.
+            pose (d3:=PIH _ J9 (mhd (Γ2 ++ Γ3, Δ2 ++ Δ3)) B (Γ2 ++ Γ3, Δ2 ++ Δ3) Γ2 Γ3
+            [] (Δ2 ++ Δ3) J10 J11 J12). simpl in d3.
+            assert (J30 : list_exch_L (Γ0 ++ B :: Γ1, Δ2 ++ Δ3) (B :: Γ2 ++ Γ3, Δ2 ++ Δ3)).
+            assert (Γ0 ++ B :: Γ1 = [] ++ [] ++ Γ0 ++ [B] ++ Γ1). reflexivity. rewrite H0. clear H0.
+            assert (B :: Γ2 ++ Γ3 = [] ++ [B] ++ Γ0 ++ [] ++ Γ1). rewrite H2. reflexivity.
+            rewrite H0. clear H0. apply list_exch_LI. pose (d4:=KS_adm_list_exch_L _ X4 _ J30).
+            assert (J40 : list_exch_L (B :: Γ2 ++ Γ3, Δ2 ++ Δ3) (Γ2 ++ B :: Γ3, Δ2 ++ Δ3)).
+            assert (Γ2 ++ B :: Γ3 = [] ++ [] ++ Γ2 ++ [B] ++ Γ3). reflexivity. rewrite H0. clear H0.
+            assert (B :: Γ2 ++ Γ3 = [] ++ [B] ++ Γ2 ++ [] ++ Γ3). reflexivity. rewrite H0. clear H0.
+            apply list_exch_LI. pose (d5:=KS_adm_list_exch_L _ d4 _ J40). pose (d3 d2 d5). rewrite <- H2. assumption.
+          * repeat destruct s. repeat destruct p. subst. rewrite H2. repeat rewrite <- app_assoc in X5. repeat rewrite <- app_assoc in X4.
+            simpl in X4. simpl in X5.
+            assert (J1 : list_exch_R (Γ0 ++ x0 ++ A --> B0 :: Γ5, Δ0 ++ A0 --> B :: Δ1) (Γ0 ++ x0 ++ A --> B0 :: Γ5, A0 --> B :: Δ2 ++ Δ3)).
+            assert (Δ0 ++ A0 --> B :: Δ1 = [] ++ [] ++ Δ0 ++ [A0 --> B] ++ Δ1). reflexivity. rewrite H0. clear H0.
+            assert (A0 --> B :: Δ2 ++ Δ3 = [] ++ [A0 --> B] ++ Δ0 ++ [] ++ Δ1). rewrite H7. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+            pose (d:=KS_adm_list_exch_R _ D0 _ J1).
+            assert (ImpLRule [((Γ0 ++ x0) ++ Γ5, Δ2 ++ A :: Δ3); ((Γ0 ++ x0) ++ B0 :: Γ5, Δ2 ++ Δ3)] ((Γ0 ++ x0) ++ A --> B0 :: Γ5, Δ2 ++ Δ3)).
+            apply ImpLRule_I. simpl in H0. repeat rewrite <- app_assoc in H0.
+            assert (J3: KS_rules [(Γ0 ++ x0 ++ Γ5, Δ2 ++ A :: Δ3); (Γ0 ++ x0 ++ B0 :: Γ5, Δ2 ++ Δ3)] (Γ0 ++ x0 ++ A --> B0 :: Γ5, Δ2 ++ Δ3)).
+            apply ImpL ; try intro ; try apply f ; try rewrite <- H7 ; try repeat rewrite <- app_assoc ; try auto ; try assumption.
+            assert (J21: In (Γ0 ++ x0 ++ Γ5, Δ2 ++ A :: Δ3) [(Γ0 ++ x0 ++ Γ5, Δ2 ++ A :: Δ3); (Γ0 ++ x0 ++ B0 :: Γ5, Δ2 ++ Δ3)]). apply in_eq.
+            pose (RA_mhd_decreases _ _ J3 _ J21). rewrite <- H7 in SIH.
+            assert (J5: size (A0 --> B) = size (A0 --> B)). reflexivity.
+            assert (J6: mhd (Γ0 ++ x0 ++ Γ5, Δ2 ++ A :: Δ3) = mhd (Γ0 ++ x0 ++ Γ5, Δ2 ++ A :: Δ3)). reflexivity.
+            assert (J7 : (Γ0 ++ x0 ++ Γ5, Δ2 ++ A :: Δ3) = (Γ0 ++ x0 ++ Γ5, [] ++ Δ2 ++ A :: Δ3)). reflexivity.
+            pose (d0:=@SIH (mhd (Γ0 ++ x0 ++ Γ5, Δ2 ++ A :: Δ3)) l (A0 --> B) (Γ0 ++ x0 ++ Γ5, Δ2 ++ A :: Δ3)
+            Γ0 (x0 ++ Γ5) [] (Δ2 ++ A :: Δ3) J5 J6 J7). simpl in d0.
+            assert (J22: In (Γ0 ++ x0 ++ B0 :: Γ5, Δ2 ++ Δ3) [(Γ0 ++ x0 ++ Γ5, Δ2 ++ A :: Δ3); (Γ0 ++ x0 ++ B0 :: Γ5, Δ2 ++ Δ3)]).
+            apply in_cons. apply in_eq. pose (RA_mhd_decreases _ _ J3 _ J22).
+            assert (J8: size (A0 --> B) = size (A0 --> B)). reflexivity.
+            assert (J9: mhd (Γ0 ++ x0 ++ B0 :: Γ5, Δ2 ++ Δ3) = mhd (Γ0 ++ x0 ++ B0 :: Γ5, Δ2 ++ Δ3)). reflexivity.
+            assert (J10: (Γ0 ++ x0 ++ B0 :: Γ5, Δ2 ++ Δ3) = (Γ0 ++ x0 ++ B0 :: Γ5, [] ++ Δ2 ++ Δ3)). reflexivity.
+            pose (d1:=@SIH (mhd (Γ0 ++ x0 ++ B0 :: Γ5, Δ2 ++ Δ3)) l0 (A0 --> B) (Γ0 ++ x0 ++ B0 :: Γ5, Δ2 ++ Δ3)
+            Γ0 (x0 ++ B0 :: Γ5) [] (Δ2 ++ Δ3) J8 J9 J10). simpl in d1.
+            assert (ImpLRule [((Γ0 ++ x0) ++ Γ5, (A0 --> B :: Δ2) ++ A :: Δ3); ((Γ0 ++ x0) ++ B0 :: Γ5, (A0 --> B :: Δ2) ++ Δ3)] ((Γ0 ++ x0) ++ A --> B0 :: Γ5, (A0 --> B :: Δ2) ++ Δ3)).
+            apply ImpLRule_I. repeat rewrite <- app_assoc in H3. pose (ImpL_inv _ _ _ d H3). destruct p as [d2 d3].
+            pose (d4:=d0 d2 X5). pose (d5:=d1 d3 X4). apply ImpL in H0 ; try intro ; try apply f ; try repeat rewrite <- app_assoc ; try rewrite <- H7 ;
+            try repeat rewrite app_nil_r ; try auto ; try assumption. pose (dlCons d5 DersNilF). pose (dlCons d4 d6).
+            pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[(Γ0 ++ x0 ++ Γ5, Δ2 ++ A :: Δ3); (Γ0 ++ x0 ++ B0 :: Γ5, Δ2 ++ Δ3)]) (Γ0 ++ x0 ++ A --> B0 :: Γ5, Δ2 ++ Δ3) H0 d7).
+            assumption.
+        - repeat destruct s. repeat destruct p. subst. rewrite H2. rewrite <- app_assoc. rewrite <- app_assoc in D0.
+          assert (J1 : list_exch_R (Γ4 ++ (A --> B0 :: x) ++ Γ1, Δ0 ++ A0 --> B :: Δ1) (Γ4 ++ (A --> B0 :: x) ++ Γ1, A0 --> B :: Δ2 ++ Δ3)).
+          assert (Δ0 ++ A0 --> B :: Δ1 = [] ++ [] ++ Δ0 ++ [A0 --> B] ++ Δ1). reflexivity. rewrite H0. clear H0.
+          assert (A0 --> B :: Δ2 ++ Δ3 = [] ++ [A0 --> B] ++ Δ0 ++ [] ++ Δ1). rewrite H7. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+          pose (d:=KS_adm_list_exch_R _ D0 _ J1).
+          assert (ImpLRule [(Γ4 ++ x ++ Γ1, Δ2 ++ A :: Δ3); (Γ4 ++ (B0 :: x) ++ Γ1, Δ2 ++ Δ3)] (Γ4 ++ (A --> B0 :: x) ++ Γ1, Δ2 ++ Δ3)).
+          apply ImpLRule_I. simpl in H0.
+          assert (J3: KS_rules [(Γ4 ++ x ++ Γ1, Δ2 ++ A :: Δ3); (Γ4 ++ B0 :: x ++ Γ1, Δ2 ++ Δ3)] (Γ4 ++ A --> B0 :: x ++ Γ1, Δ2 ++ Δ3)).
+          apply ImpL ; try intro ; try apply f ; try rewrite <- H7 ; try repeat rewrite <- app_assoc ; try auto ; try assumption.
+          assert (J21: In (Γ4 ++ x ++ Γ1, Δ2 ++ A :: Δ3) [(Γ4 ++ x ++ Γ1, Δ2 ++ A :: Δ3); (Γ4 ++ B0 :: x ++ Γ1, Δ2 ++ Δ3)]). apply in_eq.
+          pose (RA_mhd_decreases _ _ J3 _ J21). rewrite <- H7 in SIH. rewrite <- app_assoc in SIH.
+          assert (J5: size (A0 --> B) = size (A0 --> B)). reflexivity.
+          assert (J6: mhd (Γ4 ++ x ++ Γ1, Δ2 ++ A :: Δ3) = mhd (Γ4 ++ x ++ Γ1, Δ2 ++ A :: Δ3)). reflexivity.
+          assert (J7 : (Γ4 ++ x ++ Γ1, Δ2 ++ A :: Δ3) = ((Γ4 ++ x) ++ Γ1, [] ++ Δ2 ++ A :: Δ3)). rewrite <- app_assoc. reflexivity.
+          pose (d0:=@SIH (mhd (Γ4 ++ x ++ Γ1, Δ2 ++ A :: Δ3)) l (A0 --> B) (Γ4 ++ x ++ Γ1, Δ2 ++ A :: Δ3)
+          (Γ4 ++ x) Γ1 [] (Δ2 ++ A :: Δ3) J5 J6 J7). simpl in d0. repeat rewrite <- app_assoc in d0.
+          assert (J22: In (Γ4 ++ B0 :: x ++ Γ1, Δ2 ++ Δ3) [(Γ4 ++ x ++ Γ1, Δ2 ++ A :: Δ3); (Γ4 ++ B0 :: x ++ Γ1, Δ2 ++ Δ3)]).
+          apply in_cons. apply in_eq. pose (RA_mhd_decreases _ _ J3 _ J22).
+          assert (J8: size (A0 --> B) = size (A0 --> B)). reflexivity.
+          assert (J9: mhd (Γ4 ++ B0 :: x ++ Γ1, Δ2 ++ Δ3) = mhd (Γ4 ++ B0 :: x ++ Γ1, Δ2 ++ Δ3)). reflexivity.
+          assert (J10: (Γ4 ++ B0 :: x ++ Γ1, Δ2 ++ Δ3) = ((Γ4 ++ B0 :: x) ++ Γ1, [] ++ Δ2 ++ Δ3)). rewrite <- app_assoc. reflexivity.
+          pose (d1:=@SIH (mhd (Γ4 ++ B0 :: x ++ Γ1, Δ2 ++ Δ3)) l0 (A0 --> B) (Γ4 ++ B0 :: x ++ Γ1, Δ2 ++ Δ3)
+          (Γ4 ++ B0 :: x) Γ1 [] (Δ2 ++ Δ3) J8 J9 J10). simpl in d1.
+          assert (ImpLRule [(Γ4 ++ x ++ Γ1, (A0 --> B :: Δ2) ++ A :: Δ3); (Γ4 ++ (B0 :: x) ++ Γ1, (A0 --> B :: Δ2) ++ Δ3)] (Γ4 ++ (A --> B0 :: x) ++ Γ1, (A0 --> B :: Δ2) ++ Δ3)).
+          apply ImpLRule_I. repeat rewrite <- app_assoc in H3. pose (ImpL_inv _ _ _ d H3). destruct p as [d2 d3].
+          pose (d4:=d0 d2 X5). repeat rewrite <- app_assoc in d1. pose (d5:=d1 d3 X4). apply ImpL in H0 ; try intro ; try apply f ; try repeat rewrite <- app_assoc ; try rewrite <- H7 ;
+          try repeat rewrite app_nil_r ; try auto ; try assumption. pose (dlCons d5 DersNilF). pose (dlCons d4 d6).
+          pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[(Γ4 ++ x ++ Γ1, Δ2 ++ A :: Δ3); (Γ4 ++ B0 :: x ++ Γ1, Δ2 ++ Δ3)]) (Γ4 ++ (A --> B0 :: x) ++ Γ1, Δ2 ++ Δ3) H0 d7).
+          assumption. }
+      (* Right rule is KR *)
+      { inversion X3. subst. rewrite H2.
+        assert (KRRule [(unboxed_list , [A])] (Γ0 ++ Γ1, Δ2 ++ Box A :: Δ3)).
+        apply KRRule_I ; try assumption.
+        apply univ_gen_ext_splitR in X4. destruct X4. destruct s. repeat destruct p. subst.
+        apply univ_gen_ext_combine. assumption. apply univ_gen_ext_not_In_delete in u0. assumption.
+        intro. assert (In (A0 --> B) (x ++ x0)). apply in_or_app. auto. apply H5 in H0. destruct H0.
+        inversion H0. apply KR in X5.
+        pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[(unboxed_list , [A])]) (Γ0 ++ Γ1, Δ2 ++ Box A :: Δ3) X5 X2).
+        assumption. }
+    + repeat destruct s. repeat destruct p. subst.
+      assert (J5 : list_exch_L (Γ0 ++ A :: Γ1, Δ0 ++ x0 ++ A0 --> B :: Δ3) (A :: Γ2 ++ Γ3, Δ0 ++ x0 ++ A0 --> B :: Δ3)).
+      rewrite H2. assert (Γ0 ++ A :: Γ1 = [] ++ [] ++ Γ0 ++ [A] ++ Γ1). reflexivity. rewrite H. clear H.
+      assert (A :: Γ0 ++ Γ1 = [] ++ [A] ++ Γ0 ++ [] ++ Γ1). reflexivity. rewrite H. clear H.
+      apply list_exch_LI. pose (d:=KS_adm_list_exch_L _ D1 _ J5).
+      assert (ImpRRule [((A :: Γ2) ++ A0 :: Γ3, (Δ0 ++ x0) ++ B :: Δ3)] ((A :: Γ2) ++ Γ3, (Δ0 ++ x0) ++ A0 --> B :: Δ3)).
+      apply ImpRRule_I. repeat rewrite <- app_assoc in H. pose (d0:=ImpR_inv _ _ d H).
+      assert (ImpRRule [(Γ2 ++ A0 :: Γ3, (Δ0 ++ x0) ++ B :: Δ3)] (Γ2 ++ Γ3, (Δ0 ++ x0) ++ A0 --> B :: Δ3)).
+      apply ImpRRule_I. repeat rewrite <- app_assoc in H0.
+      assert (KS_rules [(Γ2 ++ A0 :: Γ3, Δ0 ++ x0 ++ B :: Δ3)] (Γ2 ++ Γ3, Δ0 ++ x0 ++ A0 --> B :: Δ3)).
+      apply ImpR ; try intro ; try apply f ; try rewrite <- H2 ; try rewrite <- app_assoc ; try auto ; try assumption.
+      assert (KS_rules [(Γ2 ++ A0 :: Γ3, Δ0 ++ x0 ++ B :: Δ3)] (Γ2 ++ Γ3, Δ0 ++ x0 ++ A0 --> B :: Δ3)).
+      apply ImpR. assumption.
+      assert (J21: In (Γ2 ++ A0 :: Γ3, Δ0 ++ x0 ++ B :: Δ3) [(Γ2 ++ A0 :: Γ3, Δ0 ++ x0 ++ B :: Δ3)]). apply in_eq.
+      pose (RA_mhd_decreases _ _ X3 (Γ2 ++ A0 :: Γ3, Δ0 ++ x0 ++ B :: Δ3) J21).
+      assert (J2 : mhd (Γ2 ++ A0 :: Γ3, Δ0 ++ x0 ++ B :: Δ3) = mhd (Γ2 ++ A0 :: Γ3, Δ0 ++ x0 ++ B :: Δ3)). reflexivity.
+      assert (J3 : size A = size A). reflexivity.
+      assert (J4 : (Γ2 ++ A0 :: Γ3, Δ0 ++ x0 ++ B :: Δ3) = ([] ++ Γ2 ++ A0 :: Γ3, Δ0 ++ x0 ++ B :: Δ3)).
+      repeat rewrite <- app_assoc. reflexivity. rewrite <- H2 in SIH.
+      pose (d1:=@SIH (mhd (Γ2 ++ A0 :: Γ3, Δ0 ++ x0 ++ B :: Δ3)) l A (Γ2 ++ A0 :: Γ3, Δ0 ++ x0 ++ B :: Δ3)
+      [] (Γ2 ++ A0 :: Γ3) Δ0 (x0 ++ B :: Δ3) J3 J2 J4). repeat rewrite <- app_assoc in d1. simpl in d1.
+      inversion X0. subst. clear X6. repeat rewrite <- app_assoc in X5. pose (d2:=d1 X5 d0). pose (dlCons d2 DersNilF).
+      pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[(Γ2 ++ A0 :: Γ3, Δ0 ++ x0 ++ B :: Δ3)]) (Γ2 ++ Γ3, Δ0 ++ x0 ++ A0 --> B :: Δ3) X4 d3). assumption.
+  * repeat destruct s. repeat destruct p. subst. repeat rewrite <- app_assoc. repeat rewrite <- app_assoc in D1.
+    assert (J5 : list_exch_L (Γ0 ++ A :: Γ1, Δ2 ++ (A0 --> B :: x) ++ Δ1) (A :: Γ2 ++ Γ3, Δ2 ++ (A0 --> B :: x) ++ Δ1)).
+    assert (Γ0 ++ A :: Γ1 = [] ++ [] ++ Γ0 ++ [A] ++ Γ1). reflexivity. rewrite H. clear H.
+    assert (A :: Γ2 ++ Γ3 = [] ++ [A] ++ Γ0 ++ [] ++ Γ1). rewrite H2. reflexivity. rewrite H. clear H.
+    apply list_exch_LI. pose (d:=KS_adm_list_exch_L _ D1 _ J5).
+    assert (ImpRRule [((A :: Γ2) ++ A0 :: Γ3, Δ2 ++ B :: x ++ Δ1)] ((A :: Γ2) ++ Γ3, Δ2 ++ (A0 --> B :: x) ++ Δ1)).
+    apply ImpRRule_I. repeat rewrite <- app_assoc in H. pose (d0:=ImpR_inv _ _ d H).
+    assert (ImpRRule [(Γ2 ++ A0 :: Γ3, Δ2 ++ (B :: x) ++ Δ1)] (Γ2 ++ Γ3, Δ2 ++ (A0 --> B :: x) ++ Δ1)).
+    apply ImpRRule_I.
+    assert (KS_rules [(Γ2 ++ A0 :: Γ3, Δ2 ++ (B :: x) ++ Δ1)] (Γ2 ++ Γ3, Δ2 ++ (A0 --> B :: x) ++ Δ1)).
+    apply ImpR ; try intro ; try apply f ; try repeat rewrite <- app_assoc ; try rewrite <- H2 ; try auto ; try assumption.
+    assert (KS_rules [(Γ2 ++ A0 :: Γ3, Δ2 ++ (B :: x) ++ Δ1)] (Γ2 ++ Γ3, Δ2 ++ (A0 --> B :: x) ++ Δ1)).
+    apply ImpR ; try assumption.
+    assert (J21: In (Γ2 ++ A0 :: Γ3, Δ2 ++ (B :: x) ++ Δ1) [(Γ2 ++ A0 :: Γ3, Δ2 ++ (B :: x) ++ Δ1)]). apply in_eq.
+    pose (RA_mhd_decreases _ _ X3 (Γ2 ++ A0 :: Γ3, Δ2 ++ (B :: x) ++ Δ1) J21). rewrite <- H2 in SIH.
+    assert (J2 : mhd (Γ2 ++ A0 :: Γ3, Δ2 ++ (B :: x) ++ Δ1) = mhd (Γ2 ++ A0 :: Γ3, Δ2 ++ (B :: x) ++ Δ1)).
+    repeat rewrite <- app_assoc. reflexivity.
+    assert (J3 : size A = size A). reflexivity.
+    assert (J4 : (Γ2 ++ A0 :: Γ3, Δ2 ++ (B :: x) ++ Δ1) = ([] ++ Γ2 ++ A0 :: Γ3, (Δ2 ++ B :: x) ++ Δ1)).
+    repeat rewrite <- app_assoc. reflexivity. repeat rewrite <- app_assoc in SIH.
+    pose (d1:=@SIH (mhd (Γ2 ++ A0 :: Γ3, Δ2 ++ (B :: x) ++ Δ1)) l A (Γ2 ++ A0 :: Γ3, Δ2 ++ (B :: x) ++ Δ1)
+    [] (Γ2 ++ A0 :: Γ3) (Δ2 ++ (B :: x)) Δ1 J3 J2 J4). simpl in d1. repeat rewrite <- app_assoc in d1.
+    inversion X0. subst. pose (d2:=d1 X5 d0). pose (dlCons d2 DersNilF).
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[(Γ2 ++ A0 :: Γ3, Δ2 ++ (B :: x) ++ Δ1)]) (Γ2 ++ Γ3, Δ2 ++ (A0 --> B :: x) ++ Δ1) X4 d3). assumption.
+ +
+(* Left rule is ImpL *)
+- inversion H1. subst. inversion X0. inversion X4. subst. clear X6. clear X4.
+  assert (J5 : list_exch_L (Γ0 ++ A :: Γ1, Δ0 ++ Δ1) (A :: Γ2 ++ A0 --> B :: Γ3, Δ0 ++ Δ1)).
+  rewrite H2. assert (Γ0 ++ A :: Γ1 = [] ++ [] ++ Γ0 ++ [A] ++ Γ1).
+  reflexivity. rewrite H. clear H.
+  assert (A :: Γ0 ++ Γ1 = [] ++ [A] ++ Γ0 ++ [] ++ Γ1). reflexivity. rewrite H. clear H.
+  apply list_exch_LI. pose (d:=KS_adm_list_exch_L _ D1 _ J5). rewrite H3 in X5.
+  assert (J40 : list_exch_R (Γ2 ++ Γ3, Δ2 ++ A0 :: Δ3) (Γ2 ++ Γ3, A0 :: Δ0 ++ A :: Δ1)).
+  rewrite <- H3. assert (Δ2 ++ A0 :: Δ3 = [] ++ [] ++ Δ2 ++ [A0] ++ Δ3).
+  reflexivity. rewrite H. clear H.
+  assert (A0 :: Δ2 ++ Δ3 = [] ++ [A0] ++ Δ2 ++ [] ++ Δ3). reflexivity. rewrite H. clear H.
+  apply list_exch_RI. pose (d0:=KS_adm_list_exch_R _ X3 _ J40).
+  assert (ImpLRule [(A :: Γ2 ++ Γ3, [] ++ A0 :: Δ0 ++ Δ1); (A :: Γ2 ++ B :: Γ3, [] ++ Δ0 ++ Δ1)] (A :: Γ2 ++ A0 --> B :: Γ3, [] ++ Δ0 ++ Δ1)).
+  assert ((A :: Γ2 ++ A0 --> B :: Γ3, [] ++ Δ0 ++ Δ1) = ((A :: Γ2) ++ A0 --> B :: Γ3, [] ++ Δ0 ++ Δ1)). reflexivity.
+  rewrite H. clear H.
+  assert ((A :: Γ2 ++ Γ3, [] ++ A0 :: Δ0 ++ Δ1) = ((A :: Γ2) ++ Γ3, [] ++ A0 :: Δ0 ++ Δ1)). reflexivity.
+  rewrite H. clear H.
+  assert ((A :: Γ2 ++ B :: Γ3, [] ++ Δ0 ++ Δ1) = ((A :: Γ2) ++ B :: Γ3, [] ++ Δ0 ++ Δ1)). reflexivity.
+  rewrite H. clear H. apply ImpLRule_I. simpl in H. pose (ImpL_inv _ _ _ d H). destruct p as [d1 d2].
+  assert (ImpLRule [(Γ2 ++ Γ3, [] ++ A0 :: Δ0 ++ Δ1); (Γ2 ++ B :: Γ3, [] ++ Δ0 ++ Δ1)] (Γ2 ++ A0 --> B :: Γ3, [] ++ Δ0 ++ Δ1)).
+  apply ImpLRule_I. simpl in H0.
+  assert (KS_rules [(Γ2 ++ Γ3, A0 :: Δ0 ++ Δ1); (Γ2 ++ B :: Γ3, Δ0 ++ Δ1)] (Γ2 ++ A0 --> B :: Γ3, Δ0 ++ Δ1)).
+  apply ImpL ; try intro ; try apply f ; try rewrite <- H2 ; try rewrite <- app_assoc ; try auto ; try assumption.
+  assert (KS_rules [(Γ2 ++ Γ3, A0 :: Δ0 ++ Δ1); (Γ2 ++ B :: Γ3, Δ0 ++ Δ1)] (Γ2 ++ A0 --> B :: Γ3, Δ0 ++ Δ1)).
+  apply ImpL. assumption.
+  assert (J21: In (Γ2 ++ Γ3, A0 :: Δ0 ++ Δ1) [(Γ2 ++ Γ3, A0 :: Δ0 ++ Δ1); (Γ2 ++ B :: Γ3, Δ0 ++ Δ1)]).
+  apply in_eq. pose (RA_mhd_decreases _ _ X4 (Γ2 ++ Γ3, A0 :: Δ0 ++ Δ1) J21).
+  assert (J2 : mhd (Γ2 ++ Γ3, A0 :: Δ0 ++ Δ1) = mhd (Γ2 ++ Γ3, A0 :: Δ0 ++ Δ1)). reflexivity.
+  assert (J3 : size A = size A). reflexivity.
+  assert (J4 : (Γ2 ++ Γ3, A0 :: Δ0 ++ Δ1) = ([] ++ Γ2 ++ Γ3, (A0 :: Δ0) ++ Δ1)).
+  repeat rewrite <- app_assoc. reflexivity. rewrite <- H2 in SIH.
+  pose (d3:=@SIH (mhd (Γ2 ++ Γ3, A0 :: Δ0 ++ Δ1)) l A (Γ2 ++ Γ3, A0 :: Δ0 ++ Δ1)
+  [] (Γ2 ++ Γ3) (A0 :: Δ0) Δ1 J3 J2 J4). repeat rewrite <- app_assoc in d3. simpl in d3.
+  pose (d4:=d3 d0 d1).
+  assert (J31: In (Γ2 ++ B :: Γ3, Δ0 ++ Δ1) [(Γ2 ++ Γ3, A0 :: Δ0 ++ Δ1); (Γ2 ++ B :: Γ3, Δ0 ++ Δ1)]).
+  apply in_cons. apply in_eq. pose (RA_mhd_decreases _ _ X4 (Γ2 ++ B :: Γ3, Δ0 ++ Δ1) J31).
+  assert (J32 : mhd (Γ2 ++ B :: Γ3, Δ0 ++ Δ1) = mhd (Γ2 ++ B :: Γ3, Δ0 ++ Δ1)). reflexivity.
+  assert (J33 : size A = size A). reflexivity.
+  assert (J34 : (Γ2 ++ B :: Γ3, Δ0 ++ Δ1) = ([] ++ Γ2 ++ B :: Γ3, Δ0 ++ Δ1)).
+  repeat rewrite <- app_assoc. reflexivity.
+  pose (d5:=@SIH (mhd (Γ2 ++ B :: Γ3, Δ0 ++ Δ1)) l0 A (Γ2 ++ B :: Γ3, Δ0 ++ Δ1)
+  [] (Γ2 ++ B :: Γ3) Δ0 Δ1 J33 J32 J34). repeat rewrite <- app_assoc in d5. simpl in d5.
+  pose (d6:=d5 X5 d2). pose (dlCons d6 DersNilF). pose (dlCons d4 d7).
+  pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+  (ps:=[(Γ2 ++ Γ3, A0 :: Δ0 ++ Δ1); (Γ2 ++ B :: Γ3, Δ0 ++ Δ1)]) (Γ2 ++ A0 --> B :: Γ3, Δ0 ++ Δ1) X6 d8). assumption.
+ +
+(* Left rule is KR *)
+- inversion X3. subst. apply list_split_form in H2. destruct H2.
+  * destruct s.
+    + repeat destruct p. subst. inversion X1.
+      (* Right rule is IdP *)
+      { inversion H. subst. assert (J0 : InT (# P) (Γ0 ++ Box A0 :: Γ1)). rewrite <- H5. apply InT_or_app.
+        right. apply InT_eq. apply InT_app_or in J0. destruct J0.
+        - apply InT_split in i. destruct i. destruct s. subst. rewrite <- app_assoc.
+          assert (IdPRule [] (x ++ (# P :: x0) ++ Γ1, Δ2 ++ # P :: Δ3)). apply IdPRule_I. apply IdP in H0.
+          pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) (x ++ (# P :: x0) ++ Γ1, Δ2 ++ # P :: Δ3) H0 DersNilF). assumption.
+        - inversion i.
+          * inversion H2.
+          * apply InT_split in H2. destruct H2. destruct s. subst. rewrite app_assoc.
+            assert (IdPRule [] ((Γ0 ++ x) ++ # P :: x0, Δ2 ++ # P :: Δ3)). apply IdPRule_I. apply IdP in H0.
+            pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) ((Γ0 ++ x) ++ # P :: x0, Δ2 ++ # P :: Δ3) H0 DersNilF). assumption. }
+      (* Right rule is BotL *)
+      { inversion H. subst. assert (J0 : InT (Bot) (Γ0 ++ Box A0 :: Γ1)). rewrite <- H5. apply InT_or_app.
+        right. apply InT_eq. apply InT_app_or in J0. destruct J0.
+        - apply InT_split in i. destruct i. destruct s. subst. rewrite <- app_assoc.
+          assert (BotLRule [] (x ++ (Bot :: x0) ++ Γ1, Δ0 ++ Δ1)). apply BotLRule_I. apply BotL in H0.
+          pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) (x ++ (Bot :: x0) ++ Γ1, Δ0 ++ Δ1) H0 DersNilF). assumption.
+        - inversion i.
+          * inversion H2.
+          * apply InT_split in H2. destruct H2. destruct s. subst. rewrite app_assoc.
+            assert (BotLRule [] ((Γ0 ++ x) ++ Bot :: x0, Δ0 ++ Δ1)). apply BotLRule_I. apply BotL in H0.
+            pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) ((Γ0 ++ x) ++ Bot :: x0, Δ0 ++ Δ1) H0 DersNilF). assumption. }
+      (* Right rule is ImpR *)
+      { inversion H. subst. inversion X2. subst. clear X6. rewrite <- H6 in D1.
+        assert (J1 : list_exch_L (Γ2 ++ A :: Γ3, Δ2 ++ B :: Δ3) (A :: Γ0 ++ Box A0 :: Γ1, Δ2 ++ B :: Δ3)).
+        assert (Γ2 ++ A :: Γ3 = [] ++ [] ++ Γ2 ++ [A] ++ Γ3). reflexivity. rewrite H0. clear H0.
+        assert (A :: Γ0 ++ Box A0 :: Γ1 = [] ++ [A] ++ Γ2 ++ [] ++ Γ3). rewrite <- H5. reflexivity.
+        rewrite H0. clear H0. apply list_exch_LI. pose (d:=KS_adm_list_exch_L _ X5 _ J1).
+        assert (ImpRRule [([] ++ A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ3)] ([] ++ Γ0 ++ Γ1, Δ2 ++ A --> B :: Δ3)). apply ImpRRule_I.
+        simpl in H0.
+        assert (J3: KS_rules [(A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ3)] (Γ0 ++ Γ1, Δ2 ++ A --> B :: Δ3)).
+        apply ImpR ; try intro ; try apply f ; try rewrite <- H6 ; try auto ; try assumption.
+        assert (J31: KS_rules [(A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ3)] (Γ0 ++ Γ1, Δ2 ++ A --> B :: Δ3)).
+        apply ImpR ; try assumption.
+        assert (J21: In (A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ3) [(A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ3)]). apply in_eq.
+        pose (RA_mhd_decreases _ _ J3 _ J21). rewrite <- H6 in SIH.
+        assert (J5: size (Box A0) = size (Box A0)). reflexivity.
+        assert (J6: mhd (A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ3) = mhd (A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ3)). reflexivity.
+        assert (J7 : (A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ3) = ((A :: Γ0) ++ Γ1, [] ++ Δ2 ++ B :: Δ3)). reflexivity.
+        pose (d0:=@SIH (mhd (A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ3)) l (Box A0) (A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ3)
+        (A :: Γ0) Γ1 [] (Δ2 ++ B :: Δ3) J5 J6 J7). simpl in d0.
+        assert (J8 : list_exch_R (Γ0 ++ Γ1, Δ0 ++ Box A0 :: Δ1) (Γ0 ++ Γ1, Box A0 :: Δ2 ++ A --> B :: Δ3)).
+        assert (Δ0 ++ Box A0 :: Δ1 = [] ++ [] ++ Δ0 ++ [Box A0] ++ Δ1). reflexivity. rewrite H2. clear H2.
+        assert (Box A0 :: Δ2 ++ A --> B :: Δ3 = [] ++ [Box A0] ++ Δ0 ++ [] ++ Δ1). rewrite H6.
+        reflexivity. rewrite H2. clear H2. apply list_exch_RI. pose (d1:=KS_adm_list_exch_R _ D0 _ J8).
+        assert (ImpRRule [([] ++ A ::Γ0 ++ Γ1, (Box A0 :: Δ2) ++ B :: Δ3)] ([] ++ Γ0 ++ Γ1, (Box A0 :: Δ2) ++ A --> B :: Δ3)).
+        apply ImpRRule_I. simpl in H2. pose (d2:=ImpR_inv _ _ d1 H2). pose (d3:=d0 d2 d). pose (dlCons d3 DersNilF).
+        apply ImpR in H0 ; try intro ; try apply f ; try rewrite <- H7 ; try auto ; try assumption.
+        pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[(A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ3)]) (Γ0 ++ Γ1, Δ2 ++ A --> B :: Δ3) H0 d4). assumption. }
+      (* Right rule is ImpL *)
+      { inversion H. subst. apply list_split_form in H5. destruct H5.
+        - destruct s.
+          + repeat destruct p. inversion e0.
+          + repeat destruct s. repeat destruct p. subst. repeat rewrite <- app_assoc in H. repeat rewrite <- app_assoc in X2.
+            assert (J2: list_exch_R (Γ0 ++ x0 ++ A --> B :: Γ3, Δ0 ++ Box A0 :: Δ1) (Γ0 ++ x0 ++ A --> B :: Γ3, Box A0 :: Δ2 ++ Δ3)).
+            assert (Δ0 ++ Box A0 :: Δ1 = [] ++ [] ++ Δ0 ++ [Box A0] ++ Δ1). reflexivity. rewrite H0. clear H0.
+            assert (Box A0 :: Δ2 ++ Δ3 = [] ++ [Box A0] ++ Δ0 ++ [] ++ Δ1). rewrite H6. reflexivity. rewrite H0. clear H0.
+            apply list_exch_RI. pose (d:=KS_adm_list_exch_R _ D0 _ J2).
+            assert (ImpLRule [((Γ0 ++ x0) ++ Γ3, (Box A0 :: Δ2) ++ A :: Δ3); ((Γ0 ++ x0) ++ B :: Γ3, (Box A0 :: Δ2) ++ Δ3)]
+            ((Γ0 ++ x0) ++ A --> B :: Γ3, (Box A0 :: Δ2) ++ Δ3)). apply ImpLRule_I. simpl in H.
+            repeat rewrite <- app_assoc in H0. pose (ImpL_inv _ _ _ d H0). destruct p as [d0 d1].
+            assert (ImpLRule [((Γ0 ++ x0) ++ Γ3, Δ2 ++ A :: Δ3); ((Γ0 ++ x0) ++ B :: Γ3, Δ2 ++ Δ3)]
+            ((Γ0 ++ x0) ++ A --> B :: Γ3, Δ2 ++ Δ3)). apply ImpLRule_I. repeat rewrite <- app_assoc in H0.
+            repeat rewrite <- app_assoc in H2.
+            assert (J3: KS_rules [(Γ0 ++ x0 ++ Γ3, Δ2 ++ A :: Δ3); (Γ0 ++ x0 ++ B :: Γ3, Δ2 ++ Δ3)]
+            (Γ0 ++ x0 ++ A --> B :: Γ3, Δ2 ++ Δ3)).
+            apply ImpL ; try intro ; try apply f ; try rewrite <- app_assoc ;
+            try rewrite <- H6 ; try auto ; try assumption.
+            assert (J30: KS_rules [(Γ0 ++ x0 ++ Γ3, Δ2 ++ A :: Δ3); (Γ0 ++ x0 ++ B :: Γ3, Δ2 ++ Δ3)]
+            (Γ0 ++ x0 ++ A --> B :: Γ3, Δ2 ++ Δ3)). apply ImpL ; try assumption.
+            assert (J5: In (Γ0 ++ x0 ++ Γ3, Δ2 ++ A :: Δ3) [(Γ0 ++ x0 ++ Γ3, Δ2 ++ A :: Δ3); (Γ0 ++ x0 ++ B :: Γ3, Δ2 ++ Δ3)]).
+            apply in_eq.
+            assert (J9: In (Γ0 ++ x0 ++ B :: Γ3, Δ2 ++ Δ3) [(Γ0 ++ x0 ++ Γ3, Δ2 ++ A :: Δ3); (Γ0 ++ x0 ++ B :: Γ3, Δ2 ++ Δ3)]).
+            apply in_cons. apply in_eq.
+            pose (RA_mhd_decreases _ _ J3 _ J5). pose (RA_mhd_decreases _ _ J3 _ J9). repeat rewrite <- app_assoc in SIH. rewrite <- H6 in SIH.
+            assert (J6: size (Box A0) = size (Box A0)). reflexivity.
+            assert (J7: mhd (Γ0 ++ x0 ++ Γ3, Δ2 ++ A :: Δ3) = mhd (Γ0 ++ x0 ++ Γ3, Δ2 ++ A :: Δ3)). reflexivity.
+            assert (J8: (Γ0 ++ x0 ++ Γ3, Δ2 ++ A :: Δ3) = (Γ0 ++ x0 ++ Γ3, [] ++ Δ2 ++ A :: Δ3)). reflexivity.
+            pose (d2:=@SIH (mhd (Γ0 ++ x0 ++ Γ3, Δ2 ++ A :: Δ3)) l (Box A0) (Γ0 ++ x0 ++ Γ3, Δ2 ++ A :: Δ3)
+            Γ0 (x0 ++ Γ3) [] (Δ2 ++ A :: Δ3) J6 J7 J8). simpl in d2. inversion X2. subst. inversion X6. clear X6.
+            clear X8. subst. pose (d3:=d2 d0 X5).
+            assert (J10: mhd (Γ0 ++ x0 ++ B :: Γ3, Δ2 ++ Δ3) = mhd (Γ0 ++ x0 ++ B :: Γ3, Δ2 ++ Δ3)). reflexivity.
+            assert (J11: (Γ0 ++ x0 ++ B :: Γ3, Δ2 ++ Δ3) = (Γ0 ++ x0 ++ B :: Γ3, [] ++ Δ2 ++ Δ3)). reflexivity.
+            pose (d4:=@SIH (mhd (Γ0 ++ x0 ++ B :: Γ3, Δ2 ++ Δ3)) l0 (Box A0) (Γ0 ++ x0 ++ B :: Γ3, Δ2 ++ Δ3)
+            Γ0 (x0 ++ B :: Γ3) [] (Δ2 ++ Δ3) J6 J10 J11). simpl in d4. pose (d5:=d4 d1 X7).
+            pose (dlCons d5 DersNilF). pose (dlCons d3 d6).
+            pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[(Γ0 ++ x0 ++ Γ3, Δ2 ++ A :: Δ3); (Γ0 ++ x0 ++ B :: Γ3, Δ2 ++ Δ3)]) (Γ0 ++ x0 ++ A --> B :: Γ3, Δ2 ++ Δ3) J30 d7).
+            assumption.
+        - repeat destruct s. repeat destruct p. subst. rewrite <- app_assoc in D0.
+          assert (J2: list_exch_R (Γ2 ++ (A --> B :: x) ++ Γ1, Δ0 ++ Box A0 :: Δ1) (Γ2 ++ (A --> B :: x) ++ Γ1, Box A0 :: Δ2 ++ Δ3)).
+          assert (Δ0 ++ Box A0 :: Δ1 = [] ++ [] ++ Δ0 ++ [Box A0] ++ Δ1). reflexivity. rewrite H0. clear H0.
+          assert (Box A0 :: Δ2 ++ Δ3 = [] ++ [Box A0] ++ Δ0 ++ [] ++ Δ1). rewrite H6. reflexivity. rewrite H0. clear H0.
+          apply list_exch_RI. pose (d:=KS_adm_list_exch_R _ D0 _ J2).
+          assert (ImpLRule [(Γ2 ++ x ++ Γ1, (Box A0 :: Δ2) ++ A :: Δ3); (Γ2 ++ B :: x ++ Γ1, (Box A0 :: Δ2) ++ Δ3)]
+          (Γ2 ++ (A --> B :: x) ++ Γ1, (Box A0 :: Δ2) ++ Δ3)). apply ImpLRule_I. repeat rewrite <- app_assoc in H0.
+          pose (ImpL_inv _ _ _ d H0). destruct p as [d0 d1]. rewrite <- app_assoc.
+          assert (ImpLRule [(Γ2 ++ x ++ Γ1, Δ2 ++ A :: Δ3); (Γ2 ++ B :: x ++ Γ1, Δ2 ++ Δ3)]
+          (Γ2 ++ (A --> B :: x) ++ Γ1, Δ2 ++ Δ3)). apply ImpLRule_I.
+          assert (J3: KS_rules [(Γ2 ++ x ++ Γ1, Δ2 ++ A :: Δ3); (Γ2 ++ B :: x ++ Γ1, Δ2 ++ Δ3)]
+          (Γ2 ++ (A --> B :: x) ++ Γ1, Δ2 ++ Δ3)).
+          apply ImpL ; try intro ; try apply f ; try rewrite <- app_assoc ;
+          try rewrite <- H6 ; try auto ; try assumption.
+          assert (J30: KS_rules [(Γ2 ++ x ++ Γ1, Δ2 ++ A :: Δ3); (Γ2 ++ B :: x ++ Γ1, Δ2 ++ Δ3)]
+          (Γ2 ++ (A --> B :: x) ++ Γ1, Δ2 ++ Δ3)). apply ImpL ; try assumption.
+          assert (J5: In (Γ2 ++ x ++ Γ1, Δ2 ++ A :: Δ3) [(Γ2 ++ x ++ Γ1, Δ2 ++ A :: Δ3); (Γ2 ++ B :: x ++ Γ1, Δ2 ++ Δ3)]).
+          apply in_eq.
+          assert (J9: In (Γ2 ++ B :: x ++ Γ1, Δ2 ++ Δ3) [(Γ2 ++ x ++ Γ1, Δ2 ++ A :: Δ3); (Γ2 ++ B :: x ++ Γ1, Δ2 ++ Δ3)]).
+          apply in_cons. apply in_eq.
+          pose (RA_mhd_decreases _ _ J3 _ J5). pose (RA_mhd_decreases _ _ J3 _ J9). repeat rewrite <- app_assoc in SIH. rewrite <- H6 in SIH.
+          assert (J6: size (Box A0) = size (Box A0)). reflexivity.
+          assert (J7: mhd (Γ2 ++ x ++ Γ1, Δ2 ++ A :: Δ3) = mhd (Γ2 ++ x ++ Γ1, Δ2 ++ A :: Δ3)). reflexivity.
+          assert (J8: (Γ2 ++ x ++ Γ1, Δ2 ++ A :: Δ3) = ((Γ2 ++ x) ++ Γ1, [] ++ Δ2 ++ A :: Δ3)). rewrite <- app_assoc. reflexivity.
+          pose (d2:=@SIH (mhd (Γ2 ++ x ++ Γ1, Δ2 ++ A :: Δ3)) l (Box A0) (Γ2 ++ x ++ Γ1, Δ2 ++ A :: Δ3)
+          (Γ2 ++ x) Γ1 [] (Δ2 ++ A :: Δ3) J6 J7 J8). simpl in d2. inversion X2. subst. inversion X6. clear X6.
+          clear X8. subst. repeat rewrite <- app_assoc in d2. pose (d3:=d2 d0 X5).
+          assert (J10: mhd (Γ2 ++ B :: x ++ Γ1, Δ2 ++ Δ3) = mhd (Γ2 ++ B :: x ++ Γ1, Δ2 ++ Δ3)). reflexivity.
+          assert (J11: (Γ2 ++ B :: x ++ Γ1, Δ2 ++ Δ3) = ((Γ2 ++ B :: x) ++ Γ1, [] ++ Δ2 ++ Δ3)). rewrite <- app_assoc. reflexivity.
+          pose (d4:=@SIH (mhd (Γ2 ++ B :: x ++ Γ1, Δ2 ++ Δ3)) l0 (Box A0) (Γ2 ++ B :: x ++ Γ1, Δ2 ++ Δ3)
+          (Γ2 ++ B :: x) Γ1 [] (Δ2 ++ Δ3) J6 J10 J11). simpl in d4. repeat rewrite <- app_assoc in d4. pose (d5:=d4 d1 X7).
+          pose (dlCons d5 DersNilF). pose (dlCons d3 d6).
+          pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[(Γ2 ++ x ++ Γ1, Δ2 ++ A :: Δ3); (Γ2 ++ B :: x ++ Γ1, Δ2 ++ Δ3)]) (Γ2 ++ (A --> B :: x) ++ Γ1, Δ2 ++ Δ3) J30 d7).
+          assumption. }
+      (* Right rule is KR *)
+      { inversion X5. subst. inversion X0. subst. clear X8. inversion X2. subst. clear X9.
+        pose (univ_gen_ext_splitR _ _ X4). repeat destruct s. repeat destruct p.
+        pose (univ_gen_ext_splitR _ _ X6). repeat destruct s. repeat destruct p. subst. inversion u2.
+        - subst.
+          assert (wkn_R A (unboxed_list (x ++ x0), [] ++ [A0]) (unboxed_list (x ++ x0), [] ++ A :: [A0])).
+          apply wkn_RI. assert (J10: derrec_height X7 = derrec_height X7). reflexivity.
+          pose (KS_wkn_R _ _ _ J10 _ _ H). destruct s. clear J10. clear H. clear l0.
+          rewrite unbox_app_distrib in X8. simpl in X8.
+          assert (J5: list_exch_L (unboxed_list x1 ++ [A0] ++ [] ++ unboxed_list l ++ [], [A])
+          (unboxed_list x1 ++ unboxed_list l ++ [] ++ [A0] ++ [], [A])).
+          apply list_exch_LI.
+          assert (J20: unboxed_list x1 ++ A0 :: unboxed_list l =
+          unboxed_list x1 ++ [A0] ++ [] ++ unboxed_list l ++ []). simpl. rewrite app_nil_r ; auto.
+          rewrite J20 in X8. clear J20.
+          pose (d:=KS_adm_list_exch_L _ X8 _ J5). simpl in d. assert (x1 ++ l = x ++ x0).
+          apply nobox_gen_ext_injective with (l:=(Γ0 ++ Γ1)) ; try assumption.
+          intro. intros. apply H4. apply in_or_app. apply in_app_or in H. destruct H.
+          auto. right. apply in_cons. assumption. apply univ_gen_ext_combine ; assumption.
+          rewrite app_assoc in d. rewrite <- unbox_app_distrib in d.
+          rewrite H in d. clear J5. clear X8.
+          assert (unboxed_list (x ++ x0) = unboxed_list (x ++ x0) ++ []). rewrite app_nil_r.
+          auto. rewrite H0 in x2. clear H0.
+          assert (J6: size A0 < size (Box A0)). simpl. lia.
+          assert (J7: size A0 = size A0). reflexivity.
+          assert (J8: mhd (unboxed_list (x ++ x0), [A]) =
+          mhd (unboxed_list (x ++ x0), [A])). reflexivity.
+          assert (J9: (unboxed_list (x ++ x0) , [A]) =
+          (unboxed_list (x ++ x0) ++ [], [A] ++ [])). rewrite app_nil_r. reflexivity.
+          pose (d0:=@PIH (size A0) J6 (mhd (unboxed_list (x ++ x0), [A]))
+          A0 (unboxed_list (x ++ x0), [A]) (unboxed_list (x ++ x0)) []
+          [A] [] J7 J8 J9). repeat rewrite app_nil_r in d0. simpl in x2. rewrite app_nil_r in x2. pose (d1:=d0 x2 d).
+          assert (KRRule [(unboxed_list (x ++ x0), [A])] (Γ0 ++ Γ1, Δ2 ++ Box A :: Δ3)).
+          apply KRRule_I.
+          assumption. apply univ_gen_ext_combine ; auto.
+          assert (KS_rules [(unboxed_list (x ++ x0), [A])] (Γ0 ++ Γ1, Δ2 ++ Box A :: Δ3)).
+          apply KR. assumption.
+          pose (dlCons d1 DersNilF).
+          pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[(unboxed_list (x ++ x0), [A])]) (Γ0 ++ Γ1, Δ2 ++ Box A :: Δ3) X10 d2). auto.
+        - exfalso. apply H2. exists A0. reflexivity. }
+    + repeat destruct s. repeat destruct p. subst.
+      assert (KRRule [(unboxed_list , [A0])] (Γ0 ++ Γ1, (Δ0 ++ x0) ++ Box A0 :: Δ3)).
+      apply KRRule_I ; try assumption. repeat rewrite <- app_assoc in X5.
+      assert (KS_rules [(unboxed_list , [A0])] (Γ0 ++ Γ1, Δ0 ++ x0 ++ Box A0 :: Δ3)).
+      apply KR. assumption.
+      pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[(unboxed_list , [A0])]) (Γ0 ++ Γ1, Δ0 ++ x0 ++ Box A0 :: Δ3) X6 X0). assumption.
+  * repeat destruct s. repeat destruct p. subst. rewrite <- app_assoc.
+    assert (KRRule [(unboxed_list , [A0])] (Γ0 ++ Γ1, Δ2 ++ (Box A0 :: x) ++ Δ1)).
+    apply KRRule_I ; try assumption.
+    assert (KS_rules [(unboxed_list , [A0])] (Γ0 ++ Γ1, Δ2 ++ (Box A0 :: x) ++ Δ1)).
+    apply KR. assumption.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[(unboxed_list , [A0])]) (Γ0 ++ Γ1, Δ2 ++ (Box A0 :: x) ++ Δ1) X6 X0). assumption.
+Qed.
+ +
+Theorem KS_cut_adm : forall A Γ0 Γ1 Δ0 Δ1,
+                      (KS_prv (Γ0 ++ Γ1, Δ0 ++ A :: Δ1)) ->
+                      (KS_prv (Γ0 ++ A :: Γ1, Δ0 ++ Δ1)) ->
+                      (KS_prv (Γ0 ++ Γ1, Δ0 ++ Δ1)).
+Proof.
+intros.
+assert (J1: size A = size A). reflexivity.
+assert (J2: mhd (Γ0 ++ Γ1, Δ0 ++ Δ1) = mhd (Γ0 ++ Γ1, Δ0 ++ Δ1)). reflexivity.
+assert (J3: (Γ0 ++ Γ1, Δ0 ++ Δ1) = (Γ0 ++ Γ1, Δ0 ++ Δ1)). reflexivity.
+pose (@KS_cut_adm_main (size A) (mhd (Γ0 ++ Γ1, Δ0 ++ Δ1)) A
+(Γ0 ++ Γ1, Δ0 ++ Δ1) Γ0 Γ1 Δ0 Δ1 J1 J2 J3). auto.
+Qed.
+ +
+
+
+ +
+ + + diff --git a/K.KS.KS_calc.html b/K.KS.KS_calc.html new file mode 100644 index 0000000..e9e42b0 --- /dev/null +++ b/K.KS.KS_calc.html @@ -0,0 +1,150 @@ + + + + + + + + + + + + + +
+
+

K.KS.KS_calc

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat.
+ +
+Require Export general_export.
+Require Export Syntax_export.
+ +
+(* We use a macro for sequents *)
+ +
+Definition Seq := (prod (list MPropF) (list MPropF)).
+ +
+(* ---------------------------------------------------------------------------------------------------------------------------------- *)
+ +
+(* Finally, we can define the rules which constitute our calculus. We gather
+   it in caclulus in a definition appearing later. *)

+ +
+Inductive IdPRule : rlsT Seq :=
+  | IdPRule_I : forall P (Γ0 Γ1 Δ0 Δ1 : list MPropF),
+          IdPRule [] (Γ0 ++ # P :: Γ1 , Δ0 ++ # P :: Δ1)
+.
+ +
+Inductive BotLRule : rlsT Seq :=
+  | BotLRule_I : forall Γ0 Γ1 Δ,
+          BotLRule [] (Γ0 ++ Bot :: Γ1 , Δ)
+.
+ +
+Inductive ImpRRule : rlsT Seq :=
+  | ImpRRule_I : forall A B Γ0 Γ1 Δ0 Δ1,
+          ImpRRule [(Γ0 ++ A :: Γ1 , Δ0 ++ B :: Δ1)]
+                    (Γ0 ++ Γ1 , Δ0 ++ (A --> B) :: Δ1).
+ +
+Inductive ImpLRule : rlsT Seq :=
+  | ImpLRule_I : forall A B Γ0 Γ1 Δ0 Δ1,
+          ImpLRule [(Γ0 ++ Γ1 , Δ0 ++ A :: Δ1) ;
+                     (Γ0 ++ B :: Γ1 , Δ0 ++ Δ1)]
+                    (Γ0 ++ (A --> B) :: Γ1 , Δ0 ++ Δ1)
+.
+ +
+Inductive KRRule : rlsT Seq :=
+  | KRRule_I : forall A Γ0 Δ0 Δ1,
+          (is_Boxed_list ) ->
+          (nobox_gen_ext Γ0) ->
+         KRRule [(unboxed_list , [A])] (Γ0 , Δ0 ++ Box A :: Δ1).
+ +
+(* At last we can define our calculus KS. *)
+ +
+Inductive KS_rules : rlsT Seq :=
+  | IdP : forall ps c, IdPRule ps c -> KS_rules ps c
+  | BotL : forall ps c, BotLRule ps c -> KS_rules ps c
+  | ImpR : forall ps c, ImpRRule ps c -> KS_rules ps c
+  | ImpL : forall ps c, ImpLRule ps c -> KS_rules ps c
+  | KR : forall ps c, KRRule ps c -> KS_rules ps c
+.
+ +
+(* We can show that all identities are provable in KS. *)
+ +
+Lemma Id_all_form : forall (A : MPropF) l0 l1 l2 l3,
+          derrec KS_rules (fun _ => False) (l0 ++ A :: l1, l2 ++ A :: l3).
+Proof.
+assert (DersNilF: dersrec KS_rules (fun _ : rel (list (MPropF)) => False) []).
+apply dersrec_nil.
+ +
+induction A as [n| | |].
+- intros. assert (IdPRule [] (l0 ++ # n :: l1, l2 ++ # n :: l3)). apply IdPRule_I. apply IdP in H.
+  pose (derI (rules:=KS_rules) (prems:=fun _ : rel (list (MPropF)) => False) (ps:=[])
+  (l0 ++ # n :: l1, l2 ++ # n :: l3) H DersNilF). assumption.
+- intros. assert (BotLRule [] (l0 ++ Bot :: l1, l2 ++ Bot :: l3)). apply BotLRule_I. apply BotL in H.
+  pose (derI (rules:=KS_rules) (prems:=fun _ : rel (list (MPropF)) => False) (ps:=[])
+  (l0 ++ Bot :: l1, l2 ++ Bot :: l3) H DersNilF). assumption.
+- intros. assert (ImpRRule [(l0 ++ A1 :: A1 --> A2 :: l1, l2 ++ A2 :: l3)] (l0 ++ A1 --> A2 :: l1, l2 ++ A1 --> A2 :: l3)).
+  apply ImpRRule_I. apply ImpR in H.
+  assert (ImpLRule [((l0 ++ [A1]) ++ l1, l2 ++ A1 :: A2 :: l3); ((l0 ++ [A1]) ++ A2 :: l1, l2 ++ A2 :: l3)] ((l0 ++ [A1]) ++ A1 --> A2 :: l1, l2 ++ A2 :: l3)).
+  apply ImpLRule_I. repeat rewrite <- app_assoc in H0. simpl in H0. apply ImpL in H0.
+  pose (IHA1 l0 l1 l2 (A2 :: l3)). pose (IHA2 (l0 ++ [A1]) l1 l2 l3). repeat rewrite <- app_assoc in d0. simpl in d0.
+  pose (dlCons d0 DersNilF). pose (dlCons d d1).
+  pose (derI (rules:=KS_rules) (prems:=fun _ : rel (list (MPropF)) => False) (ps:=[(l0 ++ A1 :: l1, l2 ++ A1 :: A2 :: l3); (l0 ++ A1 :: A2 :: l1, l2 ++ A2 :: l3)])
+  (l0 ++ A1 :: A1 --> A2 :: l1, l2 ++ A2 :: l3) H0 d2). pose (dlCons d3 DersNilF).
+  pose (derI (rules:=KS_rules) (prems:=fun _ : rel (list (MPropF)) => False) (ps:=[(l0 ++ A1 :: A1 --> A2 :: l1, l2 ++ A2 :: l3)])
+  (l0 ++ A1 --> A2 :: l1, l2 ++ A1 --> A2 :: l3) H d4). assumption.
+- intros. assert (KRRule [(unboxed_list (top_boxes (l0 ++ Box A :: l1)), [A])] (l0 ++ Box A :: l1, l2 ++ Box A :: l3)).
+  apply KRRule_I. apply is_Boxed_list_top_boxes. rewrite top_boxes_distr_app. simpl. apply univ_gen_ext_combine.
+  apply nobox_gen_ext_top_boxes. apply univ_gen_ext_cons. apply nobox_gen_ext_top_boxes.
+  rewrite top_boxes_distr_app in X. simpl in X. rewrite unbox_app_distrib in X. simpl in X.
+  repeat rewrite <- app_assoc in X. simpl in X.
+  pose (IHA (unboxed_list (top_boxes l0)) (unboxed_list (top_boxes l1)) [] []).
+  simpl in d. pose (dlCons d DersNilF). apply KR in X.
+  pose (derI (rules:=KS_rules) (prems:=fun _ : rel (list (MPropF)) => False) (ps:=[(unboxed_list (top_boxes l0) ++ A :: unboxed_list (top_boxes l1), [A])])
+  (l0 ++ Box A :: l1, l2 ++ Box A :: l3) X d0). assumption.
+Qed.
+ +
+Definition KS_prv s := derrec KS_rules (fun _ => False) s.
+Definition KS_drv s := derrec KS_rules (fun _ => True) s.
+ +
+
+
+ +
+ + + diff --git a/K.KS.KS_ctr.html b/K.KS.KS_ctr.html new file mode 100644 index 0000000..ad0bfb8 --- /dev/null +++ b/K.KS.KS_ctr.html @@ -0,0 +1,955 @@ + + + + + + + + + + + + + +
+
+

K.KS.KS_ctr

+ +
+Require Import List.
+Export ListNotations.
+Require Import Lia.
+Require Import PeanoNat Arith.
+ +
+Require Import KS_calc.
+Require Import KS_inv_ImpR_ImpL.
+ +
+(* Next are the definitions for contraction of one formula on the left, and
+on the right. Note that while the leftmost occurrence of the formula is kept,
+if we have exchange for our calculus it amounts to the same to keep the rightmost
+formula. *)

+ +
+Inductive ctr_L (fml : MPropF) : relationT Seq :=
+  | ctr_LI Γ0 Γ1 Γ2 Δ : ctr_L fml
+        (Γ0 ++ fml :: Γ1 ++ fml :: Γ2, Δ) (Γ0 ++ fml :: Γ1 ++ Γ2, Δ).
+ +
+Inductive ctr_R (fml : MPropF) : relationT Seq :=
+  | ctr_RI Γ Δ0 Δ1 Δ2 : ctr_R fml
+        (Γ, Δ0 ++ fml :: Δ1 ++ fml :: Δ2) (Γ, Δ0 ++ fml :: Δ1 ++ Δ2).
+ +
+(* The following lemmas make sure that if a rule is applied on a sequent s with
+premises ps, then the same rule is applicable on a sequent sc which is a contracted
+version of s, with some premises psc that are such that they are either the same premises
+(in case the contracted formula was weakened) or contracted versions of ps. *)

+ +
+Lemma ImpR_app_ctr_L : forall s sc A ps,
+  (@ctr_L A s sc) ->
+  (ImpRRule [ps] s) ->
+  (existsT2 psc, (ImpRRule [psc] sc) * (@ctr_L A ps psc)).
+Proof.
+intros s sc A ps ctr RA. inversion RA. inversion ctr. subst.
+inversion H. subst. apply app2_find_hole in H1. destruct H1. destruct s.
+- destruct s.
+  + destruct p. subst. exists (Γ2 ++ A0 :: A :: Γ3 ++ Γ4, Δ0 ++ B :: Δ1).
+    split. apply ImpRRule_I.
+    assert (E1: Γ2 ++ A0 :: A :: Γ3 ++ A :: Γ4 = (Γ2 ++ [A0]) ++ A :: Γ3 ++ A :: Γ4).
+    repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E1.
+    assert (E2: Γ2 ++ A0 :: A :: Γ3 ++ Γ4 = (Γ2 ++ [A0]) ++ A :: Γ3 ++ Γ4).
+    repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E2.
+    apply ctr_LI.
+  + destruct p. subst. destruct x.
+    * simpl in e0. subst. repeat rewrite app_nil_r.
+      exists (Γ2 ++ A0 :: A :: Γ3 ++ Γ4, Δ0 ++ B :: Δ1). split. apply ImpRRule_I.
+      assert (E1: Γ2 ++ A0 :: A :: Γ3 ++ A :: Γ4 = (Γ2 ++ [A0]) ++ A :: Γ3 ++ A :: Γ4).
+      repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E1.
+      assert (E2: Γ2 ++ A0 :: A :: Γ3 ++ Γ4 = (Γ2 ++ [A0]) ++ A :: Γ3 ++ Γ4).
+      repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E2.
+      apply ctr_LI.
+    * inversion e0. subst. apply app2_find_hole in H2. destruct H2. destruct s.
+      { destruct s.
+        - destruct p. subst. exists ((Γ2 ++ m :: Γ3) ++ A0 :: Γ4, Δ0 ++ B :: Δ1).
+          split.
+          assert (E: Γ2 ++ m :: Γ3 ++ Γ4 = (Γ2 ++ m :: Γ3) ++ Γ4).
+          rewrite <- app_assoc. reflexivity. rewrite E. apply ImpRRule_I.
+          assert (E1: (Γ2 ++ m :: Γ3) ++ A0 :: m :: Γ4 = Γ2 ++ m :: (Γ3 ++ [A0]) ++ m :: Γ4).
+          repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E1.
+          assert (E2: (Γ2 ++ m :: Γ3) ++ A0 :: Γ4 = Γ2 ++ m :: (Γ3 ++ [A0]) ++ Γ4).
+          repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E2.
+          apply ctr_LI.
+        - destruct p. subst. destruct x0.
+          + simpl in e1. subst. repeat rewrite app_nil_r.
+            exists ((Γ2 ++ m :: Γ3) ++ A0 :: Γ4, Δ0 ++ B :: Δ1). split.
+            assert (E: Γ2 ++ m :: Γ3 ++ Γ4 = (Γ2 ++ m :: Γ3) ++ Γ4).
+            rewrite <- app_assoc. reflexivity. rewrite E.
+            apply ImpRRule_I.
+            assert (E1: (Γ2 ++ m :: Γ3) ++ A0 :: m :: Γ4 = Γ2 ++ m :: (Γ3 ++ [A0]) ++ m :: Γ4).
+            repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E1.
+            assert (E2: (Γ2 ++ m :: Γ3) ++ A0 :: Γ4 = Γ2 ++ m :: (Γ3 ++ [A0]) ++ Γ4).
+            repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E2.
+            apply ctr_LI.
+          + inversion e1. subst.
+            exists ((Γ2 ++ m0 :: Γ3 ++ x0) ++ A0 :: Γ1, Δ0 ++ B :: Δ1). split.
+            assert (E: Γ2 ++ m0 :: Γ3 ++ x0 ++ Γ1 = (Γ2 ++ m0 :: Γ3 ++ x0) ++ Γ1).
+            repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E.
+            apply ImpRRule_I.
+            repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. apply ctr_LI. }
+      { destruct p. subst. exists ((Γ2 ++ m :: x) ++ A0 :: x0 ++ Γ4,Δ0 ++ B :: Δ1).
+        split. assert (E: Γ2 ++ m :: (x ++ x0) ++ Γ4 = (Γ2 ++ m :: x) ++ x0 ++ Γ4).
+        repeat rewrite <- app_assoc. reflexivity. rewrite E. apply ImpRRule_I.
+        assert (E1: (Γ2 ++ m :: x) ++ A0 :: x0 ++ m :: Γ4 = Γ2 ++ m :: (x ++ A0 :: x0) ++ m :: Γ4).
+        repeat rewrite <- app_assoc. reflexivity. rewrite E1.
+        assert (E2: (Γ2 ++ m :: x) ++ A0 :: x0 ++ Γ4 = Γ2 ++ m :: (x ++ A0 :: x0) ++ Γ4).
+        repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E2.
+        apply ctr_LI. }
+- destruct p. subst. exists (Γ0 ++ A0 :: x ++ A :: Γ3 ++ Γ4, Δ0 ++ B :: Δ1).
+  split. rewrite <- app_assoc. apply ImpRRule_I.
+  assert (E1: Γ0 ++ A0 :: x ++ A :: Γ3 ++ A :: Γ4 = (Γ0 ++ A0 :: x) ++ A :: Γ3 ++ A :: Γ4).
+  repeat rewrite <- app_assoc. reflexivity. rewrite E1.
+  assert (E2: Γ0 ++ A0 :: x ++ A :: Γ3 ++ Γ4 = (Γ0 ++ A0 :: x) ++ A :: Γ3 ++ Γ4).
+  repeat rewrite cons_single. repeat rewrite <- app_assoc. reflexivity. rewrite E2.
+  apply ctr_LI.
+Qed.
+ +
+Lemma ImpL_app_ctr_L : forall s sc A ps1 ps2,
+  (@ctr_L A s sc) ->
+  (ImpLRule [ps1;ps2] s) ->
+  ((existsT2 psc1 psc2, (ImpLRule [psc1;psc2] sc) *
+                       (@ctr_L A ps1 psc1) *
+                       (@ctr_L A ps2 psc2))
+  +
+  (existsT2 B C invps11 invps12 invps21 invps22 invpsc11 invpsc22,
+                       (A = Imp B C) *
+                       (ImpLRule [invps11;invps12] ps1) *
+                       (ImpLRule [invps21;invps22] ps2) *
+                       (@ctr_R B invps11 invpsc11) *
+                       (@ctr_L C invps22 invpsc22) *
+                       (ImpLRule [invpsc11;invpsc22] sc))).
+Proof.
+intros s sc A ps1 ps2 ctr RA. inversion RA. inversion ctr. subst. inversion H.
+subst. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
+- inversion e0. subst. right. exists A0. exists B.
+  exists (Γ2 ++ Γ3 ++ Γ4, Δ0 ++ A0 :: A0 :: Δ1). exists (Γ2 ++ Γ3 ++ B :: Γ4, Δ0 ++ A0 :: Δ1).
+  exists (Γ2 ++ B :: Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ B :: Γ3 ++ B :: Γ4, Δ0 ++ Δ1).
+  exists (Γ2 ++ Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ B :: Γ3 ++ Γ4, Δ0 ++ Δ1). repeat split.
+  assert (Γ2 ++ Γ3 ++ Γ4 = (Γ2 ++ Γ3) ++ Γ4). rewrite <- app_assoc. reflexivity. rewrite H0.
+  clear H0. assert (Γ2 ++ Γ3 ++ B :: Γ4 = (Γ2 ++ Γ3) ++ B :: Γ4). rewrite <- app_assoc. reflexivity.
+  rewrite H0. clear H0. assert (Γ2 ++ Γ3 ++ A0 --> B :: Γ4 = (Γ2 ++ Γ3) ++ A0 --> B :: Γ4). rewrite <- app_assoc.
+  reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+  assert (Γ2 ++ B :: Γ3 ++ Γ4 = (Γ2 ++ B :: Γ3) ++ Γ4). rewrite <- app_assoc. reflexivity. rewrite H0.
+  clear H0. assert (Γ2 ++ B :: Γ3 ++ B :: Γ4 = (Γ2 ++ B :: Γ3) ++ B :: Γ4). rewrite <- app_assoc. reflexivity.
+  rewrite H0. clear H0. assert (Γ2 ++ B :: Γ3 ++ A0 --> B :: Γ4 = (Γ2 ++ B :: Γ3) ++ A0 --> B :: Γ4). rewrite <- app_assoc.
+  reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+  assert (Δ0 ++ A0 :: A0 :: Δ1 = Δ0 ++ A0 :: [] ++ A0 :: Δ1). reflexivity. rewrite H0. clear H0.
+  assert (Δ0 ++ A0 :: Δ1 = Δ0 ++ A0 :: [] ++ Δ1). reflexivity. rewrite H0. clear H0.
+  apply ctr_RI.
+- destruct x.
+  * simpl in e0. inversion e0. subst. right. exists A0. exists B.
+    exists (Γ2 ++ Γ3 ++ Γ4, Δ0 ++ A0 :: A0 :: Δ1). exists (Γ2 ++ Γ3 ++ B :: Γ4, Δ0 ++ A0 :: Δ1).
+    exists (Γ2 ++ B :: Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ B :: Γ3 ++ B :: Γ4, Δ0 ++ Δ1).
+    exists (Γ2 ++ Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ B :: Γ3 ++ Γ4, Δ0 ++ Δ1). repeat split.
+    assert (Γ2 ++ Γ3 ++ Γ4 = (Γ2 ++ Γ3) ++ Γ4). repeat rewrite <- app_assoc. reflexivity. rewrite H0.
+    clear H0. assert (Γ2 ++ Γ3 ++ B :: Γ4 = (Γ2 ++ Γ3) ++ B :: Γ4). rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. assert ((Γ2 ++ []) ++ Γ3 ++ A0 --> B :: Γ4 = (Γ2 ++ Γ3) ++ A0 --> B :: Γ4).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+    assert (Γ2 ++ B :: Γ3 ++ Γ4 = (Γ2 ++ B :: Γ3) ++ Γ4). rewrite <- app_assoc. reflexivity. rewrite H0.
+    clear H0. assert (Γ2 ++ B :: Γ3 ++ B :: Γ4 = (Γ2 ++ B :: Γ3) ++ B :: Γ4). rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. assert ((Γ2 ++ []) ++ B :: Γ3 ++ A0 --> B :: Γ4 = (Γ2 ++ B :: Γ3) ++ A0 --> B :: Γ4).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+    assert (Δ0 ++ A0 :: A0 :: Δ1 = Δ0 ++ A0 :: [] ++ A0 :: Δ1). reflexivity. rewrite H0. clear H0.
+    assert (Δ0 ++ A0 :: Δ1 = Δ0 ++ A0 :: [] ++ Δ1). reflexivity. rewrite H0. clear H0.
+    apply ctr_RI.
+  * inversion e0. subst. apply app2_find_hole in H2. destruct H2. repeat destruct s ; destruct p ; subst.
+    + inversion e1. subst. right. exists A0. exists B.
+      exists (Γ2 ++ Γ3 ++ Γ4, Δ0 ++ A0 :: A0 :: Δ1). exists (Γ2 ++ B :: Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1).
+      exists (Γ2 ++ Γ3 ++ B :: Γ4, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ B :: Γ3 ++ B :: Γ4, Δ0 ++ Δ1).
+      exists (Γ2 ++ Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ B :: Γ3 ++ Γ4, Δ0 ++ Δ1). repeat split.
+      repeat rewrite <- app_assoc. apply ImpLRule_I. repeat rewrite <- app_assoc. apply ImpLRule_I.
+      assert (Δ0 ++ A0 :: A0 :: Δ1 = Δ0 ++ A0 :: [] ++ A0 :: Δ1). reflexivity. rewrite H0. clear H0.
+      assert (Δ0 ++ A0 :: Δ1 = Δ0 ++ A0 :: [] ++ Δ1). reflexivity. rewrite H0. clear H0.
+      apply ctr_RI.
+    + destruct x0.
+      { simpl in e1. inversion e1. subst. right. exists A0. exists B.
+        exists (Γ2 ++ Γ3 ++ Γ1, Δ0 ++ A0 :: A0 :: Δ1). exists (Γ2 ++ B :: Γ3 ++ Γ1, Δ0 ++ A0 :: Δ1).
+        exists (Γ2 ++ Γ3 ++ B :: Γ1, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ B :: Γ3 ++ B :: Γ1, Δ0 ++ Δ1).
+        exists (Γ2 ++ Γ3 ++ Γ1, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ B :: Γ3 ++ Γ1, Δ0 ++ Δ1). repeat split.
+        repeat rewrite <- app_assoc. simpl. rewrite app_nil_r. apply ImpLRule_I. repeat rewrite <- app_assoc.
+        rewrite app_nil_r. apply ImpLRule_I.
+        assert (Δ0 ++ A0 :: A0 :: Δ1 = Δ0 ++ A0 :: [] ++ A0 :: Δ1). reflexivity. rewrite H0. clear H0.
+        assert (Δ0 ++ A0 :: Δ1 = Δ0 ++ A0 :: [] ++ Δ1). reflexivity. rewrite H0. clear H0.
+        apply ctr_RI. }
+      { inversion e1. subst. left. exists (Γ2 ++ m0 :: Γ3 ++ x0 ++ Γ1, Δ0 ++ A0 :: Δ1).
+        exists (Γ2 ++ m0 :: Γ3 ++ x0 ++ B :: Γ1, Δ0 ++ Δ1). repeat split.
+        assert (Γ2 ++ m0 :: Γ3 ++ x0 ++ Γ1 = (Γ2 ++ m0 :: Γ3 ++ x0) ++ Γ1). repeat rewrite <- app_assoc.
+        simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ m0 :: Γ3 ++ x0 ++ A0 --> B :: Γ1 = (Γ2 ++ m0 :: Γ3 ++ x0) ++ A0 --> B :: Γ1). repeat rewrite <- app_assoc.
+        simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ m0 :: Γ3 ++ x0 ++ B :: Γ1 = (Γ2 ++ m0 :: Γ3 ++ x0) ++ B :: Γ1). repeat rewrite <- app_assoc.
+        simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. apply ctr_LI.
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. apply ctr_LI. }
+    + destruct x0.
+      { simpl in e1. inversion e1. subst. right. exists A0. exists B.
+        exists (Γ2 ++ x ++ Γ4, Δ0 ++ A0 :: A0 :: Δ1). exists (Γ2 ++ B :: x ++ Γ4, Δ0 ++ A0 :: Δ1).
+        exists (Γ2 ++ x ++ B :: Γ4, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ B :: x ++ B :: Γ4, Δ0 ++ Δ1).
+        exists (Γ2 ++ x ++ Γ4, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ B :: x ++ Γ4, Δ0 ++ Δ1). repeat split.
+        repeat rewrite <- app_assoc. apply ImpLRule_I. repeat rewrite <- app_assoc. apply ImpLRule_I.
+        assert (Δ0 ++ A0 :: A0 :: Δ1 = Δ0 ++ A0 :: [] ++ A0 :: Δ1). reflexivity. rewrite H0. clear H0.
+        assert (Δ0 ++ A0 :: Δ1 = Δ0 ++ A0 :: [] ++ Δ1). reflexivity. rewrite H0. clear H0.
+        apply ctr_RI. rewrite <- app_assoc. simpl. apply ImpLRule_I. }
+      { inversion e1. subst. left. exists (Γ2 ++ m :: x ++ x0 ++ Γ4, Δ0 ++ A0 :: Δ1).
+        exists (Γ2 ++ m :: x ++ B :: x0 ++ Γ4, Δ0 ++ Δ1). repeat split.
+        assert (Γ2 ++ m :: x ++ x0 ++ Γ4 = (Γ2 ++ m :: x) ++ x0 ++ Γ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ m :: x ++ B :: x0 ++ Γ4 = (Γ2 ++ m :: x) ++ B :: x0 ++ Γ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ m :: (x ++ A0 --> B :: x0) ++ Γ4 = (Γ2 ++ m :: x) ++ A0 --> B :: x0 ++ Γ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+        assert ((Γ2 ++ m :: x) ++ x0 ++ m :: Γ4 = Γ2 ++ m :: (x ++ x0) ++ m :: Γ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ m :: x ++ x0 ++ Γ4 = Γ2 ++ m :: (x ++ x0) ++ Γ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0. apply ctr_LI.
+        assert ((Γ2 ++ m :: x) ++ B :: x0 ++ m :: Γ4 = Γ2 ++ m :: (x ++ B :: x0) ++ m :: Γ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ m :: x ++ B :: x0 ++ Γ4 = Γ2 ++ m :: (x ++ B :: x0) ++ Γ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0. apply ctr_LI. }
+- destruct x.
+  + simpl in e0. inversion e0. subst. right. exists A0. exists B.
+    exists (Γ0 ++ Γ3 ++ Γ4, Δ0 ++ A0 :: A0 :: Δ1). exists (Γ0 ++ Γ3 ++ B :: Γ4, Δ0 ++ A0 :: Δ1).
+    exists (Γ0 ++ B :: Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1). exists (Γ0 ++ B :: Γ3 ++ B :: Γ4, Δ0 ++ Δ1).
+    exists (Γ0 ++ Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1). exists (Γ0 ++ B :: Γ3 ++ Γ4, Δ0 ++ Δ1) . repeat split.
+    assert (Γ0 ++ Γ3 ++ Γ4 = (Γ0 ++ Γ3) ++ Γ4). repeat rewrite <- app_assoc. reflexivity. rewrite H0.
+    clear H0. assert (Γ0 ++ Γ3 ++ B :: Γ4 = (Γ0 ++ Γ3) ++ B :: Γ4). rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. assert (Γ0 ++ Γ3 ++ A0 --> B :: Γ4 = (Γ0 ++ Γ3) ++ A0 --> B :: Γ4).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+    assert (Γ0 ++ B :: Γ3 ++ Γ4 = (Γ0 ++ B :: Γ3) ++ Γ4). rewrite <- app_assoc. reflexivity. rewrite H0.
+    clear H0. assert (Γ0 ++ B :: Γ3 ++ B :: Γ4 = (Γ0 ++ B :: Γ3) ++ B :: Γ4). rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. assert (Γ0 ++ B :: Γ3 ++ A0 --> B :: Γ4 = (Γ0 ++ B :: Γ3) ++ A0 --> B :: Γ4).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+    assert (Δ0 ++ A0 :: A0 :: Δ1 = Δ0 ++ A0 :: [] ++ A0 :: Δ1). reflexivity. rewrite H0. clear H0.
+    assert (Δ0 ++ A0 :: Δ1 = Δ0 ++ A0 :: [] ++ Δ1). reflexivity. rewrite H0. clear H0.
+    apply ctr_RI. repeat rewrite <- app_assoc. simpl. apply ImpLRule_I.
+  + inversion e0. subst. left. exists (Γ0 ++ x ++ A :: Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1).
+    exists (Γ0 ++ B :: x ++ A :: Γ3 ++ Γ4, Δ0 ++ Δ1). repeat split. repeat rewrite <- app_assoc.
+    apply ImpLRule_I.
+    assert (Γ0 ++ x ++ A :: Γ3 ++ A :: Γ4 = (Γ0 ++ x) ++ A :: Γ3 ++ A :: Γ4). repeat rewrite <- app_assoc.
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ x ++ A :: Γ3 ++ Γ4 = (Γ0 ++ x) ++ A :: Γ3 ++ Γ4). repeat rewrite <- app_assoc.
+    reflexivity. rewrite H0. clear H0. apply ctr_LI.
+    assert (Γ0 ++ B :: x ++ A :: Γ3 ++ A :: Γ4 = (Γ0 ++ B :: x) ++ A :: Γ3 ++ A :: Γ4). repeat rewrite <- app_assoc.
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ B :: x ++ A :: Γ3 ++ Γ4 = (Γ0 ++ B :: x) ++ A :: Γ3 ++ Γ4). repeat rewrite <- app_assoc.
+    reflexivity. rewrite H0. clear H0. apply ctr_LI.
+Qed.
+ +
+Lemma KR_app_ctr_L : forall s sc A ps,
+  (@ctr_L A s sc) ->
+  (KRRule [ps] s) ->
+    ((KRRule [ps] sc) +
+     (existsT2 psc, (KRRule [psc] sc) * (@ctr_L (unBox_formula A) ps psc))).
+Proof.
+intros s sc A ps ctr RA. inversion RA. inversion ctr. rewrite <- H1 in H2.
+inversion H2. subst. apply univ_gen_ext_elem_deep with (l3:=Γ1) (l4:=Γ2 ++ A :: Γ3) (a:=A) in X.
+destruct X. 3: reflexivity.
+- destruct p. apply univ_gen_ext_elem_deep with (l3:=Γ1 ++ Γ2) (l4:=Γ3) (a:=A) in u. destruct u. destruct p.
+3: rewrite <- app_assoc. 3: reflexivity.
+  * left. apply KRRule_I.
+    assumption.
+    apply univ_gen_ext_add_elem_deep. rewrite app_assoc. assumption. assumption.
+  * exfalso. apply f. repeat destruct s. repeat destruct p. subst. apply is_box_is_in_boxed_list with (A:=A) in H0 .
+    unfold is_boxedT. destruct H0. exists x1. auto. apply in_or_app. right. apply in_eq.
+- repeat destruct s. repeat destruct p. apply univ_gen_ext_elem_deep with (l3:=Γ2) (l4:=Γ3) (a:=A) in u0.
+  destruct u0. 3: reflexivity.
+  * destruct p. exfalso. subst. apply is_box_is_in_boxed_list with (A:=A) in H0. apply f. unfold is_boxedT.
+    destruct H0. exists x1. auto. apply in_or_app. right. apply in_eq.
+  * repeat destruct s. repeat destruct p. right. subst.
+    exists (unboxed_list (x ++ A :: x1 ++ x2), [A0]). split.
+      { apply KRRule_I.
+        intro. intros. apply H0. apply in_app_or in H. destruct H. apply in_or_app. left. assumption.
+        inversion H. subst. apply in_or_app. right. apply in_eq. apply in_app_or in H1. destruct H1.
+        apply in_or_app. right. apply in_cons. apply in_or_app. left. assumption.
+        apply in_or_app. right. apply in_cons. apply in_or_app. right. apply in_cons.
+        assumption.
+        apply univ_gen_ext_combine. assumption. apply univ_gen_ext_cons. apply univ_gen_ext_combine.
+        assumption. assumption. }
+      { repeat rewrite cons_single. repeat rewrite unbox_app_distrib. simpl. apply ctr_LI. }
+Qed.
+ +
+Lemma ImpR_app_ctr_R : forall s sc A ps,
+  (@ctr_R A s sc) ->
+  (ImpRRule [ps] s) ->
+  ((existsT2 psc, (ImpRRule [psc] sc) * (@ctr_R A ps psc))
+  +
+  (existsT2 B C invps invpsc0 invpsc, (A = Imp B C) * (ImpRRule [invps] ps) * (ImpRRule [invpsc] sc) *
+                                      (@ctr_L B invps invpsc0) * (@ctr_R C invpsc0 invpsc))).
+Proof.
+intros s sc A ps ctr RA. inversion RA. inversion ctr. subst.
+inversion H. subst. apply app2_find_hole in H2. destruct H2. repeat destruct s ; destruct p ; subst.
+- inversion e0. right. exists A0. exists B. exists (Γ0 ++ A0 :: A0 :: Γ1, Δ2 ++ B :: Δ3 ++ B :: Δ4).
+  exists (Γ0 ++ A0 :: Γ1, Δ2 ++ B :: Δ3 ++ B :: Δ4). exists (Γ0 ++ A0 :: Γ1, Δ2 ++ B :: Δ3 ++ Δ4).
+  repeat split. assert (Δ2 ++ B :: Δ3 ++ B :: Δ4 = (Δ2 ++ B :: Δ3) ++ B :: Δ4). rewrite <- app_assoc. reflexivity.
+  rewrite H0. clear H0. assert (Δ2 ++ B :: Δ3 ++ A0 --> B :: Δ4 = (Δ2 ++ B :: Δ3) ++ A0 --> B :: Δ4). rewrite <- app_assoc. reflexivity.
+  rewrite H0. clear H0. apply ImpRRule_I.
+  assert (Γ0 ++ A0 :: A0 :: Γ1 = Γ0 ++ A0 :: [] ++ A0 :: Γ1). reflexivity. rewrite H0. clear H0.
+  assert (Γ0 ++ A0 :: Γ1 = Γ0 ++ A0 :: [] ++ Γ1). reflexivity. rewrite H0. clear H0.
+  apply ctr_LI.
+- destruct x.
+  * simpl in e0. inversion e0. subst. right. exists A0. exists B.
+    exists (Γ0 ++ A0 :: A0 :: Γ1, (Δ2 ++ []) ++ B :: Δ3 ++ B :: Δ4).
+    exists (Γ0 ++ A0 :: Γ1, (Δ2 ++ []) ++ B :: Δ3 ++ B :: Δ4). exists (Γ0 ++ A0 :: Γ1, (Δ2 ++ []) ++ B :: Δ3 ++ Δ4).
+    repeat split. assert ((Δ2 ++ []) ++ B :: Δ3 ++ B :: Δ4 = (Δ2 ++ B :: Δ3) ++ B :: Δ4). repeat rewrite <- app_assoc.
+    reflexivity. rewrite H0. clear H0. assert ((Δ2 ++ []) ++ B :: Δ3 ++ A0 --> B :: Δ4 = (Δ2 ++ B :: Δ3) ++ A0 --> B :: Δ4).
+    rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    apply ImpRRule_I. repeat rewrite <- app_assoc. simpl. apply ImpRRule_I.
+    assert (Γ0 ++ A0 :: A0 :: Γ1 = Γ0 ++ A0 :: [] ++ A0 :: Γ1). reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ A0 :: Γ1 = Γ0 ++ A0 :: [] ++ Γ1). reflexivity. rewrite H0. clear H0.
+    apply ctr_LI.
+  * inversion e0. subst. apply app2_find_hole in H2. destruct H2. repeat destruct s ; destruct p ; subst.
+    + inversion e1. subst. right. exists A0. exists B.
+      exists (Γ0 ++ A0 :: A0 :: Γ1, Δ2 ++ B :: Δ3 ++ B :: Δ4). exists (Γ0 ++ A0 :: Γ1, Δ2 ++ B :: Δ3 ++ B :: Δ4).
+      exists (Γ0 ++ A0 :: Γ1, Δ2 ++ B :: Δ3 ++ Δ4). repeat split.
+      repeat rewrite <- app_assoc. apply ImpRRule_I.
+      assert (Γ0 ++ A0 :: A0 :: Γ1 = Γ0 ++ A0 :: [] ++ A0 :: Γ1). reflexivity. rewrite H0. clear H0.
+      assert (Γ0 ++ A0 :: Γ1 = Γ0 ++ A0 :: [] ++ Γ1). reflexivity. rewrite H0. clear H0.
+      apply ctr_LI.
+    + destruct x0.
+      { simpl in e1. inversion e1. subst. right. exists A0. exists B.
+        exists (Γ0 ++ A0 :: A0 :: Γ1, Δ2 ++ B :: Δ3 ++ B :: Δ1). exists (Γ0 ++ A0 :: Γ1, Δ2 ++ B :: Δ3 ++ B :: Δ1).
+        exists (Γ0 ++ A0 :: Γ1, Δ2 ++ B :: Δ3 ++ Δ1). repeat split.
+        repeat rewrite <- app_assoc. simpl. rewrite app_nil_r. apply ImpRRule_I.
+        assert (Γ0 ++ A0 :: A0 :: Γ1 = Γ0 ++ A0 :: [] ++ A0 :: Γ1). reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ A0 :: Γ1 = Γ0 ++ A0 :: [] ++ Γ1). reflexivity. rewrite H0. clear H0.
+        apply ctr_LI. }
+      { inversion e1. subst. left. exists (Γ0 ++ A0 :: Γ1, Δ2 ++ m0 :: Δ3 ++ x0 ++ B :: Δ1).
+        repeat split. assert (Δ2 ++ m0 :: Δ3 ++ x0 ++ B :: Δ1 = (Δ2 ++ m0 :: Δ3 ++ x0) ++ B :: Δ1).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Δ2 ++ m0 :: Δ3 ++ x0 ++ A0 --> B :: Δ1 = (Δ2 ++ m0 :: Δ3 ++ x0) ++ A0 --> B :: Δ1). repeat rewrite <- app_assoc.
+        simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. apply ctr_RI. }
+    + destruct x0.
+      { simpl in e1. inversion e1. subst. right. exists A0. exists B.
+        exists (Γ0 ++ A0 :: A0 :: Γ1, Δ2 ++ B :: x ++ B :: Δ4). exists (Γ0 ++ A0 :: Γ1, Δ2 ++ B :: x ++ B :: Δ4).
+        exists (Γ0 ++ A0 :: Γ1, Δ2 ++ B :: x ++ Δ4). repeat split.
+        repeat rewrite <- app_assoc. apply ImpRRule_I. repeat rewrite <- app_assoc. apply ImpRRule_I.
+        assert (Γ0 ++ A0 :: A0 :: Γ1 = Γ0 ++ A0 :: [] ++ A0 :: Γ1). reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ A0 :: Γ1 = Γ0 ++ A0 :: [] ++ Γ1). reflexivity. rewrite H0. clear H0.
+        apply ctr_LI. }
+      { inversion e1. subst. left. exists (Γ0 ++ A0 :: Γ1, Δ2 ++ m :: x ++ B :: x0 ++ Δ4).
+        repeat split.
+        assert (Δ2 ++ m :: x ++ B :: x0 ++ Δ4 = (Δ2 ++ m :: x) ++ B :: x0 ++ Δ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Δ2 ++ m :: (x ++ A0 --> B :: x0) ++ Δ4 = (Δ2 ++ m :: x) ++ A0 --> B :: x0 ++ Δ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+        assert ((Δ2 ++ m :: x) ++ B :: x0 ++ m :: Δ4 = Δ2 ++ m :: (x ++ B :: x0) ++ m :: Δ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Δ2 ++ m :: x ++ B :: x0 ++ Δ4 = Δ2 ++ m :: (x ++ B :: x0) ++ Δ4). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0. apply ctr_RI. }
+- destruct x.
+  + simpl in e0. inversion e0. subst. right. exists A0. exists B.
+    exists (Γ0 ++ A0 :: A0 :: Γ1, Δ0 ++ B :: Δ3 ++ B :: Δ4). exists (Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ3 ++ B :: Δ4).
+    exists (Γ0 ++ A0 :: Γ1, Δ0 ++ B :: Δ3 ++ Δ4). repeat split.
+    assert (Δ0 ++ B :: Δ3 ++ A0 --> B :: Δ4 = (Δ0 ++ B :: Δ3) ++ A0 --> B :: Δ4). repeat rewrite <- app_assoc. reflexivity. rewrite H0.
+    clear H0. assert (Δ0 ++ B :: Δ3 ++ B :: Δ4 = (Δ0 ++ B :: Δ3) ++ B :: Δ4). rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply ImpRRule_I. repeat rewrite <- app_assoc. simpl. apply ImpRRule_I.
+    assert (Γ0 ++ A0 :: A0 :: Γ1 = Γ0 ++ A0 :: [] ++ A0 :: Γ1). reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ A0 :: Γ1 = Γ0 ++ A0 :: [] ++ Γ1). reflexivity. rewrite H0. clear H0.
+    apply ctr_LI.
+  + inversion e0. subst. left. exists (Γ0 ++ A0 :: Γ1, Δ0 ++ B :: x ++ A :: Δ3 ++ Δ4).
+    repeat split. repeat rewrite <- app_assoc. apply ImpRRule_I.
+    assert (Δ0 ++ B :: x ++ A :: Δ3 ++ A :: Δ4 = (Δ0 ++ B :: x) ++ A :: Δ3 ++ A :: Δ4). repeat rewrite <- app_assoc.
+    reflexivity. rewrite H0. clear H0.
+    assert (Δ0 ++ B :: x ++ A :: Δ3 ++ Δ4 = (Δ0 ++ B :: x) ++ A :: Δ3 ++ Δ4). repeat rewrite <- app_assoc.
+    reflexivity. rewrite H0. clear H0. apply ctr_RI.
+Qed.
+ +
+Lemma ImpL_app_ctr_R : forall s sc A ps1 ps2,
+  (@ctr_R A s sc) ->
+  (ImpLRule [ps1;ps2] s) ->
+  (existsT2 psc1 psc2, (ImpLRule [psc1;psc2] sc) * (@ctr_R A ps1 psc1) * (@ctr_R A ps2 psc2)).
+Proof.
+intros s sc A ps1 ps2 ctr RA. inversion RA. inversion ctr. subst.
+inversion H. subst. apply app2_find_hole in H2. destruct H2. destruct s.
+- destruct s.
+  + destruct p. subst. exists (Γ0 ++ Γ1, Δ2 ++ A0 :: A :: Δ3 ++ Δ4). exists (Γ0 ++ B :: Γ1, Δ2 ++ A :: Δ3 ++ Δ4).
+    split. split.
+    apply ImpLRule_I.
+    assert (E1: Δ2 ++ A0 :: A :: Δ3 ++ A :: Δ4 = (Δ2 ++ [A0]) ++ A :: Δ3 ++ A :: Δ4).
+    repeat rewrite <- app_assoc. rewrite cons_single. reflexivity. rewrite E1.
+    assert (E2: Δ2 ++ A0 :: A :: Δ3 ++ Δ4 = (Δ2 ++ [A0]) ++ A :: Δ3 ++ Δ4).
+    repeat rewrite <- app_assoc. rewrite cons_single. reflexivity. rewrite E2. apply ctr_RI.
+    apply ctr_RI.
+  + destruct p. destruct x.
+    * rewrite app_nil_r in e. rewrite app_nil_l in e0. subst.
+      exists (Γ0 ++ Γ1, Δ2 ++ A0 :: A :: Δ3 ++ Δ4). exists (Γ0 ++ B :: Γ1, Δ2 ++ A :: Δ3 ++ Δ4).
+      split. split.
+      apply ImpLRule_I.
+      assert (E1: Δ2 ++ A0 :: A :: Δ3 ++ A :: Δ4 = (Δ2 ++ [A0]) ++ A :: Δ3 ++ A :: Δ4).
+      repeat rewrite <- app_assoc. rewrite cons_single. reflexivity. rewrite E1.
+      assert (E2: Δ2 ++ A0 :: A :: Δ3 ++ Δ4 = (Δ2 ++ [A0]) ++ A :: Δ3 ++ Δ4).
+      repeat rewrite <- app_assoc. rewrite cons_single. reflexivity. rewrite E2. apply ctr_RI.
+      apply ctr_RI.
+    * inversion e0. subst. apply app2_find_hole in H2. destruct H2. destruct s.
+      { destruct s.
+        - destruct p. subst. exists (Γ0 ++ Γ1, (Δ2 ++ m :: Δ3) ++ A0 :: Δ4).
+          exists (Γ0 ++ B :: Γ1, (Δ2 ++ m :: Δ3) ++ Δ4). split. split.
+          assert (E: Δ2 ++ m :: Δ3 ++ Δ4 = (Δ2 ++ m :: Δ3) ++ Δ4).
+          rewrite <- app_assoc. reflexivity. rewrite E.
+          apply ImpLRule_I.
+          assert (E1: (Δ2 ++ m :: Δ3) ++ A0 :: m :: Δ4 = Δ2 ++ m :: (Δ3 ++ [A0]) ++ m :: Δ4).
+          repeat rewrite <- app_assoc. rewrite cons_single. reflexivity. rewrite E1.
+          assert (E2: (Δ2 ++ m :: Δ3) ++ A0 :: Δ4 = Δ2 ++ m :: (Δ3 ++ [A0]) ++ Δ4).
+          repeat rewrite <- app_assoc. rewrite cons_single. reflexivity. rewrite E2. apply ctr_RI.
+          rewrite <- app_assoc. simpl. apply ctr_RI.
+        - destruct p. subst. destruct x0.
+          + rewrite app_nil_l in e1. rewrite app_nil_r in e0. subst.
+            exists (Γ0 ++ Γ1,(Δ2 ++ m :: Δ3) ++ A0 :: Δ4). exists (Γ0 ++ B :: Γ1, (Δ2 ++ m :: Δ3) ++ Δ4).
+            split. split.
+            assert (E: Δ2 ++ m :: Δ3 ++ Δ4 = (Δ2 ++ m :: Δ3) ++ Δ4).
+            rewrite <- app_assoc. reflexivity. rewrite E.
+            apply ImpLRule_I.
+            assert (E1: (Δ2 ++ m :: Δ3 ++ []) ++ A0 :: m :: Δ4 = Δ2 ++ m :: (Δ3 ++ [A0]) ++ m :: Δ4).
+            rewrite app_nil_r. repeat rewrite <- app_assoc. rewrite cons_single. reflexivity. rewrite E1.
+            assert (E2: (Δ2 ++ m :: Δ3) ++ A0 :: Δ4 = Δ2 ++ m :: (Δ3 ++ [A0]) ++ Δ4).
+            repeat rewrite <- app_assoc. rewrite cons_single. reflexivity. rewrite E2. apply ctr_RI.
+            rewrite <- app_assoc. simpl. apply ctr_RI.
+          + inversion e1. subst. exists (Γ0 ++ Γ1,(Δ2 ++ m0 :: Δ3 ++ x0) ++ A0 :: Δ1).
+            exists (Γ0 ++ B :: Γ1,(Δ2 ++ m0 :: Δ3 ++ x0) ++ Δ1). split. split.
+            assert (E: Δ2 ++ m0 :: Δ3 ++ x0 ++ Δ1 = (Δ2 ++ m0 :: Δ3 ++ x0) ++ Δ1).
+            rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E.
+            apply ImpLRule_I.
+            assert (E1: (Δ2 ++ m0 :: Δ3 ++ m0 :: x0) ++ A0 :: Δ1 = Δ2 ++ m0 :: Δ3 ++ m0 :: x0 ++ A0 :: Δ1).
+            repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E1.
+            assert (E2: (Δ2 ++ m0 :: Δ3 ++ x0) ++ A0 :: Δ1 = Δ2 ++ m0 :: Δ3 ++ x0 ++ A0 :: Δ1).
+            repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E2. apply ctr_RI.
+            rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. apply ctr_RI. }
+      { destruct p. subst. exists (Γ0 ++ Γ1,(Δ2 ++ m :: x) ++ A0 :: x0 ++ Δ4).
+        exists (Γ0 ++ B :: Γ1, (Δ2 ++ m :: x) ++ x0 ++ Δ4). split. split.
+        assert (E: Δ2 ++ m :: (x ++ x0) ++ Δ4 = (Δ2 ++ m :: x) ++ x0 ++ Δ4).
+        rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E.
+        apply ImpLRule_I.
+        assert (E1: (Δ2 ++ m :: x) ++ A0 :: x0 ++ m :: Δ4 = Δ2 ++ m :: (x ++ A0 :: x0) ++ m :: Δ4).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E1.
+        assert (E2: (Δ2 ++ m :: x) ++ A0 :: x0 ++ Δ4 = Δ2 ++ m :: (x ++ A0 :: x0) ++ Δ4).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E2. apply ctr_RI.
+        assert (E1: (Δ2 ++ m :: x) ++ x0 ++ Δ4 = Δ2 ++ m :: (x ++ x0) ++ Δ4).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E1. apply ctr_RI. }
+- destruct p. subst. exists (Γ0 ++ Γ1, Δ0 ++ A0 :: x ++ A :: Δ3 ++ Δ4).
+  exists (Γ0 ++ B :: Γ1, Δ0 ++ x ++ A :: Δ3 ++ Δ4). split. split.
+  rewrite <- app_assoc. apply ImpLRule_I.
+  assert (E1: Δ0 ++ A0 :: x ++ A :: Δ3 ++ A :: Δ4 = (Δ0 ++ A0 :: x) ++ A :: Δ3 ++ A :: Δ4).
+  repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E1.
+  assert (E2: Δ0 ++ A0 :: x ++ A :: Δ3 ++ Δ4 = (Δ0 ++ A0 :: x) ++ A :: Δ3 ++ Δ4).
+  repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E2. apply ctr_RI.
+  rewrite app_assoc. apply ctr_RI.
+Qed.
+ +
+Lemma KR_app_ctr_R : forall s sc A ps,
+  (@ctr_R A s sc) -> (KRRule [ps] s) -> (KRRule [ps] sc).
+Proof.
+intros s sc A ps ctr RA. inversion RA. inversion ctr. rewrite <- H1 in H2.
+inversion H2. apply app2_find_hole in H6. destruct H6. destruct s0.
+  + destruct s0.
+    * destruct p. inversion e0. apply KRRule_I. assumption. assumption.
+    * destruct p. subst. destruct x.
+      { rewrite app_nil_l in e0. inversion e0. subst. apply KRRule_I.
+        assumption. assumption. }
+      { inversion e0. subst. apply app2_find_hole in H3. destruct H3. destruct s.
+        - destruct s.
+          + destruct p. inversion e1. apply KRRule_I. assumption. assumption.
+          + destruct p. subst. destruct x0.
+            * rewrite app_nil_l in e1. inversion e1. subst. apply KRRule_I. assumption.
+              assumption.
+            * inversion e1. subst. assert (E: Δ2 ++ m0 :: Δ3 ++ x0 ++ Box A0 :: Δ1 = (Δ2 ++ m0 :: Δ3 ++ x0) ++ Box A0 :: Δ1).
+              repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite E. apply KRRule_I. assumption.
+              assumption.
+        - destruct p. subst. destruct x0.
+          * rewrite app_nil_l in e1. inversion e1. subst. apply KRRule_I. assumption. assumption.
+          * inversion e1. subst. assert (E: Δ2 ++ m :: (x ++ Box A0 :: x0) ++ Δ4 = (Δ2 ++ m :: x) ++ Box A0 :: x0 ++ Δ4).
+            repeat rewrite <- app_assoc. reflexivity. rewrite E. apply KRRule_I. assumption. assumption. }
+  + destruct p. subst. destruct x.
+    * rewrite app_nil_l in e0. rewrite app_nil_r. inversion e0. subst. apply KRRule_I. assumption. assumption.
+    * inversion e0. rewrite <- app_assoc. simpl. apply KRRule_I. assumption. assumption.
+Qed.
+ +
+(* Now we can prove that contraction rules are height-preserving admissible. *)
+ +
+Theorem KS_hpadm_ctr_LR0 : forall (k : nat) s
+        (D0 : KS_prv s),
+        k = (derrec_height D0) ->
+          (forall sc A, (((@ctr_L A s sc) + (@ctr_R A s sc)) ->
+          existsT2 (D1 : KS_prv sc),
+          derrec_height D1 <= k)).
+Proof.
+induction k as [n IH] using (well_founded_induction_type lt_wf).
+intros s D0. remember D0 as D0'. destruct D0.
+(* D0 ip a leaf *)
+- intros hei sc A ctr. inversion f.
+(* D0 is ends with an application of rule *)
+- intros hei sc A ctr. destruct ctr as [ctr | ctr].
+{ inversion ctr. assert (DersNil: dersrec KS_rules (fun _ : Seq => False) []).
+  apply dersrec_nil. inversion k.
+  (* IdP *)
+  * inversion H1. rewrite <- H in H5. inversion H5.
+    apply app2_find_hole in H7. destruct H7. destruct s.
+    + destruct s.
+      { destruct p. inversion e0. subst. pose (IdPRule_I P Γ3 (Γ1 ++ Γ2) Δ0 Δ1). apply IdP in i. simpl in i.
+        pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (Γ3 ++ # P :: Γ1 ++ Γ2, Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl. repeat rewrite dersrec_height_nil.
+        left. reflexivity. reflexivity. }
+      { destruct p. destruct x.
+        - rewrite app_nil_l in e0. inversion e0.
+          subst. pose (IdPRule_I P (Γ3 ++ []) (Γ1 ++ Γ2) Δ0 Δ1). apply IdP in i. simpl in i.
+          pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) ((Γ3 ++ []) ++ # P :: Γ1 ++ Γ2,Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl.
+          repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+        - inversion e0. subst.
+          pose (IdPRule_I P Γ3 (x ++ A :: Γ1 ++ Γ2) Δ0 Δ1). apply IdP in i. simpl in i.
+          assert (E: Γ3 ++ # P :: x ++ A :: Γ1 ++ Γ2 = (Γ3 ++ # P :: x) ++ A :: Γ1 ++ Γ2). repeat rewrite <- app_assoc. reflexivity.
+          rewrite E in i. clear E.
+          pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) ((Γ3 ++ # P :: x) ++ A :: Γ1 ++ Γ2,Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl.
+          repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity. }
+    + destruct p. destruct x.
+      { rewrite app_nil_l in e0. inversion e0. subst.
+        pose (IdPRule_I P Γ0 (Γ1 ++ Γ2) Δ0 Δ1). apply IdP in i. simpl in i.
+        pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (Γ0 ++ # P :: Γ1 ++ Γ2, Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl.
+        repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity. }
+      { inversion e0. subst. apply app2_find_hole in H9. destruct H9. destruct s.
+        - destruct s.
+          + destruct p. inversion e1. subst.
+            pose (IdPRule_I P Γ0 (Γ1 ++ Γ2) Δ0 Δ1). apply IdP in i. simpl in i.
+            pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) (Γ0 ++ # P :: Γ1 ++ Γ2, Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl.
+            repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+          + destruct p. destruct x0.
+            * rewrite app_nil_l in e1. inversion e1. subst.
+              pose (IdPRule_I P Γ0 (Γ1 ++ Γ4) Δ0 Δ1). apply IdP in i. simpl in i.
+              pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+              (ps:=[]) (Γ0 ++ # P :: Γ1 ++ Γ4, Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl.
+              repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+            * inversion e1. subst.
+              pose (IdPRule_I P (Γ0 ++ m0 :: Γ1 ++ x0) Γ4 Δ0 Δ1). apply IdP in i. simpl in i.
+              repeat rewrite <- app_assoc in i. simpl in i. repeat rewrite <- app_assoc in i.
+              pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+              (ps:=[]) (Γ0 ++ m0 :: Γ1 ++ x0 ++ # P :: Γ4,Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl.
+              repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+        - destruct p. destruct x0.
+          + rewrite app_nil_l in e1. inversion e1. subst.
+            pose (IdPRule_I P Γ0 ((x ++ []) ++ Γ2) Δ0 Δ1). apply IdP in i. simpl in i.
+            pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) (Γ0 ++ # P :: (x ++ []) ++ Γ2, Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl.
+            repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+          + inversion e1. subst.
+            pose (IdPRule_I P (Γ0 ++ m :: x) (x0 ++ Γ2) Δ0 Δ1). apply IdP in i. simpl in i.
+            assert (E: (Γ0 ++ m :: x) ++ # P :: x0 ++ Γ2 = Γ0 ++ m :: (x ++ # P :: x0) ++ Γ2). repeat rewrite <- app_assoc. reflexivity.
+            rewrite E in i. clear E.
+            pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) (Γ0 ++ m :: (x ++ # P :: x0) ++ Γ2,Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl.
+            repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity. }
+  (* BotL *)
+  * inversion H1. rewrite <- H in H5. inversion H5.
+    apply app2_find_hole in H7. destruct H7. destruct s.
+    + destruct s.
+      { destruct p. inversion e0. subst. pose (BotLRule_I Γ3 (Γ1 ++ Γ2) Δ). apply BotL in b.
+        pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (Γ3 ++ Bot :: Γ1 ++ Γ2, Δ) b DersNil). exists d0. simpl. repeat rewrite dersrec_height_nil.
+        left. reflexivity. reflexivity. }
+      { destruct p. destruct x.
+        - rewrite app_nil_l in e0. inversion e0.
+          subst. pose (BotLRule_I (Γ3 ++ []) (Γ1 ++ Γ2) Δ). apply BotL in b. simpl in b.
+          pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) ((Γ3 ++ []) ++ Bot :: Γ1 ++ Γ2, Δ) b DersNil). exists d0. simpl.
+          repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+        - inversion e0. subst.
+          pose (BotLRule_I Γ3 (x ++ A :: Γ1 ++ Γ2) Δ). apply BotL in b. simpl in b.
+          assert (E: Γ3 ++ Bot :: x ++ A :: Γ1 ++ Γ2 = (Γ3 ++ Bot :: x) ++ A :: Γ1 ++ Γ2). repeat rewrite <- app_assoc. reflexivity.
+          rewrite E in b. clear E.
+          pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) ((Γ3 ++ Bot :: x) ++ A :: Γ1 ++ Γ2, Δ) b DersNil). exists d0. simpl.
+          repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity. }
+    + destruct p. destruct x.
+      { rewrite app_nil_l in e0. inversion e0. subst.
+        pose (BotLRule_I Γ0 (Γ1 ++ Γ2) Δ). apply BotL in b. simpl in b.
+        pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (Γ0 ++ Bot :: Γ1 ++ Γ2, Δ) b DersNil). exists d0. simpl.
+        repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity. }
+      { inversion e0. subst. apply app2_find_hole in H9. destruct H9. destruct s.
+        - destruct s.
+          + destruct p. inversion e1. subst.
+            pose (BotLRule_I Γ0 (Γ1 ++ Γ2) Δ). apply BotL in b. simpl in b.
+            pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) (Γ0 ++ Bot :: Γ1 ++ Γ2, Δ) b DersNil). exists d0. simpl.
+            repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+          + destruct p. destruct x0.
+            * rewrite app_nil_l in e1. inversion e1. subst.
+              pose (BotLRule_I Γ0 (Γ1 ++ Γ4) Δ). apply BotL in b. simpl in b.
+              pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+              (ps:=[]) (Γ0 ++ Bot :: Γ1 ++ Γ4, Δ) b DersNil). exists d0. simpl.
+              repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+            * inversion e1. subst.
+              pose (BotLRule_I (Γ0 ++ m0 :: Γ1 ++ x0) Γ4 Δ). apply BotL in b. simpl in b.
+              repeat rewrite <- app_assoc in b. simpl in b. repeat rewrite <- app_assoc in b.
+              pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+              (ps:=[]) (Γ0 ++ m0 :: Γ1 ++ x0 ++ Bot :: Γ4, Δ) b DersNil). exists d0. simpl.
+              repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+        - destruct p. destruct x0.
+          + rewrite app_nil_l in e1. inversion e1. subst.
+            pose (BotLRule_I Γ0 ((x ++ []) ++ Γ2) Δ). apply BotL in b. simpl in b.
+            pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) (Γ0 ++ Bot :: (x ++ []) ++ Γ2, Δ) b DersNil). exists d0. simpl.
+            repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+          + inversion e1. subst.
+            pose (BotLRule_I (Γ0 ++ m :: x) (x0 ++ Γ2) Δ). apply BotL in b. simpl in b.
+            assert (E: (Γ0 ++ m :: x) ++ Bot :: x0 ++ Γ2 = Γ0 ++ m :: (x ++ Bot :: x0) ++ Γ2). repeat rewrite <- app_assoc. reflexivity.
+            rewrite E in b. clear E.
+            pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) (Γ0 ++ m :: (x ++ Bot :: x0) ++ Γ2, Δ) b DersNil). exists d0. simpl.
+            repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity. }
+  (* ImpR *)
+  * inversion H1. subst. inversion H5. subst. pose (ImpR_app_ctr_L _ _ _ _ ctr H1). destruct s. destruct p.
+    apply ImpR in i.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x]) (Γ0 ++ A :: Γ1 ++ Γ2, Δ0 ++ A0 --> B :: Δ1) i). subst. simpl.
+    remember [(Γ3 ++ A0 :: Γ4, Δ0 ++ B :: Δ1)] as ps'. destruct d. inversion Heqps'.
+    inversion Heqps'. subst. simpl. rewrite dersrec_height_nil. simpl in IH.
+    rewrite dersrec_height_nil in IH. rewrite Nat.max_0_r. rewrite Nat.max_0_r in IH.
+    assert (E: derrec_height d < S (derrec_height d)). auto.
+    assert (E1: derrec_height d = derrec_height d). auto.
+    assert ((ctr_L A (Γ3 ++ A0 :: Γ4, Δ0 ++ B :: Δ1) x) + (ctr_R A (Γ3 ++ A0 :: Γ4, Δ0 ++ B :: Δ1) x)).
+    left. auto.
+    pose (IH (derrec_height d) E (Γ3 ++ A0 :: Γ4, Δ0 ++ B :: Δ1) d E1 x A H).
+    destruct s.
+    pose (dlCons x0 d1). pose (d0 d2). exists d3. simpl. rewrite dersrec_height_nil.
+    rewrite Nat.max_0_r. rewrite <- Nat.succ_le_mono. assumption. reflexivity. reflexivity. reflexivity.
+  (* ImpL *)
+  * inversion H1. subst. inversion H5. subst. pose (ImpL_app_ctr_L _ _ _ _ _ ctr H1). destruct s.
+    { repeat destruct s. repeat destruct p. apply ImpL in i.
+      pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[x;x0]) (Γ0 ++ A :: Γ1 ++ Γ2, Δ0 ++ Δ1) i). subst. simpl.
+      remember [(Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1);(Γ3 ++ B :: Γ4, Δ0 ++ Δ1)] as ps'. destruct d.
+      inversion Heqps'. inversion Heqps'. subst.
+      remember [(Γ3 ++ B :: Γ4, Δ0 ++ Δ1)] as ps''. destruct d1. inversion Heqps''.
+      inversion Heqps''. simpl. subst. rewrite dersrec_height_nil. simpl in IH.
+      rewrite dersrec_height_nil in IH. rewrite Nat.max_0_r. rewrite Nat.max_0_r in IH.
+      assert (E1: derrec_height d < S (Init.Nat.max (derrec_height d)(derrec_height d1))).
+      apply Nat.lt_succ_r. apply Nat.le_max_l.
+      assert (E2: derrec_height d = derrec_height d). auto.
+      assert ((ctr_L A (Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1) x) + (ctr_R A (Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1) x)).
+      auto.
+      pose (IH (derrec_height d) E1 (Γ3 ++ Γ4, Δ0 ++ A0 :: Δ1) d E2 x A H).
+      destruct s.
+      assert (E3: derrec_height d1 < S (Init.Nat.max (derrec_height d)(derrec_height d1))).
+      apply Nat.lt_succ_r. apply Nat.le_max_r.
+      assert (E4: derrec_height d1 = derrec_height d1). auto.
+      assert ((ctr_L A (Γ3 ++ B :: Γ4, Δ0 ++ Δ1) x0) + (ctr_R A (Γ3 ++ B :: Γ4, Δ0 ++ Δ1) x0)).
+      auto.
+      pose (IH (derrec_height d1) E3 (Γ3 ++ B :: Γ4, Δ0 ++ Δ1) d1 E4 x0 A H2).
+      destruct s.
+      pose (dlCons x1 (dlCons x2 d2)). pose (d0 d3). exists d4. simpl. rewrite dersrec_height_nil.
+      rewrite Nat.max_0_r. rewrite <- Nat.succ_le_mono. apply Nat.max_le_compat.
+      assumption. assumption. reflexivity. reflexivity. reflexivity. }
+    { simpl. repeat destruct s. repeat destruct p. subst. apply ImpL in i.
+      assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+      pose (@dersrec_derrec2_height (dersrec_height d) _ _ _ _ _ d J30). repeat destruct s.
+      assert (J1: derrec_height x7 = derrec_height x7). reflexivity.
+      pose (ImpR_ImpL_hpinv _ _ _ J1). destruct p. clear s. pose (s0 _ _ i1). repeat destruct s.
+      clear s0. destruct p. simpl in IH.
+      assert (J2: derrec_height x9 < S (dersrec_height d)). lia.
+      assert (J3: derrec_height x9 = derrec_height x9). reflexivity.
+      assert (J4: (ctr_L x x1 x5) + (ctr_R x x1 x5)). auto.
+      pose (IH _ J2 _ _ J3 _ _ J4). destruct s.
+      assert (J5: derrec_height x8 = derrec_height x8). reflexivity.
+      pose (ImpR_ImpL_hpinv _ _ _ J5). destruct p. clear s. pose (s0 _ _ i0). repeat destruct s.
+      clear s0. destruct p.
+      assert (J6: derrec_height x13 < S (dersrec_height d)). lia.
+      assert (J7: derrec_height x13 = derrec_height x13). reflexivity.
+      assert (J8: (ctr_L x0 x4 x6) + (ctr_R x0 x4 x6)). auto.
+      pose (IH _ J6 _ _ J7 _ _ J8). destruct s. pose (dlCons x14 DersNil). pose (dlCons x11 d0).
+      pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[x5;x6]) (Γ0 ++ x --> x0 :: Γ1 ++ Γ2, Δ0 ++ Δ1) i d1). exists d2. simpl.
+      rewrite dersrec_height_nil. lia. reflexivity. }
+  (* KR *)
+  * inversion X. rewrite <- H4 in X. pose (KR_app_ctr_L _ _ _ _ ctr X). destruct s.
+    { apply KR in k0. pose (derI (rules:=KS_rules)
+      (prems:=fun _ : Seq => False) (ps:=[(unboxed_list , [A0])])
+      sc k0). subst. pose (d0 d). exists d1. simpl. reflexivity. }
+    { repeat destruct s. repeat destruct p. apply KR in k0.
+      remember [(unboxed_list , [A0])] as ps'. destruct d. subst. inversion H4.
+      rewrite Heqps' in H4. inversion H4. subst. simpl. simpl in IH.
+      assert (E1: derrec_height d < S (Init.Nat.max (derrec_height d) (dersrec_height d0))).
+      rewrite dersrec_height_nil. rewrite Nat.max_0_r. apply Nat.lt_succ_r. left. reflexivity.
+      assert (E2: derrec_height d = derrec_height d). auto.
+      assert ((ctr_L (unBox_formula A) (unboxed_list , [A0]) x) +
+      (ctr_R (unBox_formula A) (unboxed_list , [A0]) x)). auto.
+      pose (IH (derrec_height d) E1 ((unboxed_list , [A0])) d E2 x (unBox_formula A) H).
+      destruct s.
+      pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[x]) (Γ0 ++ A :: Γ1 ++ Γ2, Δ) k0). subst. simpl.
+      pose (dlCons x0 d0). pose (d1 d2). exists d3. simpl. rewrite dersrec_height_nil.
+      repeat rewrite Nat.max_0_r. rewrite <- Nat.succ_le_mono. lia. auto. }}
+
+{ inversion ctr. assert (DersNil: dersrec KS_rules (fun _ : Seq => False) []).
+  apply dersrec_nil. inversion k.
+  (* IdP *)
+  * inversion H1. rewrite <- H in H5. inversion H5.
+    apply app2_find_hole in H8. destruct H8. destruct s.
+    + destruct s.
+      { destruct p. inversion e0. subst. pose (IdPRule_I P Γ0 Γ1 Δ3 (Δ1 ++ Δ2)). apply IdP in i. simpl in i.
+        pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (Γ0 ++ # P :: Γ1, Δ3 ++ # P :: Δ1 ++ Δ2) i DersNil). exists d0. simpl. repeat rewrite dersrec_height_nil.
+        left. reflexivity. reflexivity. }
+      { destruct p. destruct x.
+        - rewrite app_nil_l in e0. inversion e0.
+          subst. pose (IdPRule_I P Γ0 Γ1 (Δ3 ++ []) (Δ1 ++ Δ2)). apply IdP in i. simpl in i.
+          pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) (Γ0 ++ # P :: Γ1, (Δ3 ++ []) ++ # P :: Δ1 ++ Δ2) i DersNil). exists d0. simpl.
+          repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+        - inversion e0. subst.
+          pose (IdPRule_I P Γ0 Γ1 Δ3 (x ++ A :: Δ1 ++ Δ2)). apply IdP in i. simpl in i.
+          assert (E: Δ3 ++ # P :: x ++ A :: Δ1 ++ Δ2 = (Δ3 ++ # P :: x) ++ A :: Δ1 ++ Δ2). repeat rewrite <- app_assoc. reflexivity.
+          rewrite E in i. clear E.
+          pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) (Γ0 ++ # P :: Γ1, (Δ3 ++ # P :: x) ++ A :: Δ1 ++ Δ2) i DersNil). exists d0. simpl.
+          repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity. }
+    + destruct p. destruct x.
+      { rewrite app_nil_l in e0. inversion e0. subst.
+        pose (IdPRule_I P Γ0 Γ1 Δ0 (Δ1 ++ Δ2)). apply IdP in i. simpl in i.
+        pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (Γ0 ++ # P :: Γ1, Δ0 ++ # P :: Δ1 ++ Δ2) i DersNil). exists d0. simpl.
+        repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity. }
+      { inversion e0. subst. apply app2_find_hole in H9. destruct H9. destruct s.
+        - destruct s.
+          + destruct p. inversion e1. subst.
+            pose (IdPRule_I P Γ0 Γ1 Δ0 (Δ1 ++ Δ2)). apply IdP in i. simpl in i.
+            pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) (Γ0 ++ # P :: Γ1, Δ0 ++ # P :: Δ1 ++ Δ2) i DersNil). exists d0. simpl.
+            repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+          + destruct p. destruct x0.
+            * rewrite app_nil_l in e1. inversion e1. subst.
+              pose (IdPRule_I P Γ0 Γ1 Δ0 (Δ1 ++ Δ4)). apply IdP in i. simpl in i.
+              pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+              (ps:=[]) (Γ0 ++ # P :: Γ1, Δ0 ++ # P :: Δ1 ++ Δ4) i DersNil). exists d0. simpl.
+              repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+            * inversion e1. subst.
+              pose (IdPRule_I P Γ0 Γ1 (Δ0 ++ m0 :: Δ1 ++ x0) Δ4). apply IdP in i. simpl in i.
+              repeat rewrite <- app_assoc in i. simpl in i. repeat rewrite <- app_assoc in i.
+              pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+              (ps:=[]) (Γ0 ++ # P :: Γ1, Δ0 ++ m0 :: Δ1 ++ x0 ++ # P :: Δ4) i DersNil). exists d0. simpl.
+              repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+        - destruct p. destruct x0.
+          + rewrite app_nil_l in e1. inversion e1. subst.
+            pose (IdPRule_I P Γ0 Γ1 Δ0 ((x ++ []) ++ Δ2)). apply IdP in i. simpl in i.
+            pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) (Γ0 ++ # P :: Γ1, Δ0 ++ # P :: (x ++ []) ++ Δ2) i DersNil). exists d0. simpl.
+            repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+          + inversion e1. subst.
+            pose (IdPRule_I P Γ0 Γ1 (Δ0 ++ m :: x) (x0 ++ Δ2)). apply IdP in i. simpl in i.
+            assert (E: (Δ0 ++ m :: x) ++ # P :: x0 ++ Δ2 = Δ0 ++ m :: (x ++ # P :: x0) ++ Δ2). repeat rewrite <- app_assoc. reflexivity.
+            rewrite E in i. clear E.
+            pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+            (ps:=[]) (Γ0 ++ # P :: Γ1, Δ0 ++ m :: (x ++ # P :: x0) ++ Δ2) i DersNil). exists d0. simpl.
+            repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity. }
+  (* BotL *)
+  * inversion H1. rewrite <- H in H5. inversion H5.
+    pose (BotLRule_I Γ0 Γ1 (Δ0 ++ A :: Δ1 ++ Δ2)). apply BotL in b.
+    pose (derI (rules:=KS_rules)
+    (prems:=fun _ : Seq => False)
+    (ps:=[]) (Γ0 ++ Bot :: Γ1, Δ0 ++ A :: Δ1 ++ Δ2) b DersNil). subst. exists d0. simpl.
+    repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+  (* ImpR *)
+  * inversion H1. subst. inversion H5. subst. pose (ImpR_app_ctr_R _ _ _ _ ctr H1). destruct s.
+    { destruct s. destruct p. apply ImpR in i.
+      pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[x]) (Γ0 ++ Γ1, Δ0 ++ A :: Δ1 ++ Δ2) i). subst. simpl.
+      remember [(Γ0 ++ A0 :: Γ1, Δ3 ++ B :: Δ4)] as ps'. destruct d. inversion Heqps'.
+      inversion Heqps'. subst. simpl. rewrite dersrec_height_nil. simpl in IH.
+      rewrite dersrec_height_nil in IH. rewrite Nat.max_0_r. rewrite Nat.max_0_r in IH.
+      assert (E: derrec_height d < S (derrec_height d)). auto.
+      assert (E1: derrec_height d = derrec_height d). auto.
+      assert ((ctr_L A (Γ0 ++ A0 :: Γ1, Δ3 ++ B :: Δ4) x) + (ctr_R A (Γ0 ++ A0 :: Γ1, Δ3 ++ B :: Δ4) x)).
+      auto.
+      pose (IH (derrec_height d) E (Γ0 ++ A0 :: Γ1, Δ3 ++ B :: Δ4) d E1 x A H).
+      destruct s.
+      pose (dlCons x0 d1). pose (d0 d2). exists d3. simpl. rewrite dersrec_height_nil.
+      rewrite Nat.max_0_r. rewrite <- Nat.succ_le_mono. assumption. reflexivity. reflexivity. reflexivity. }
+    { repeat destruct s. repeat destruct p. subst. apply ImpR in i.
+      assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+      pose (dersrec_derrec_height d J30). destruct s.
+      assert (J1: derrec_height x4 = derrec_height x4). reflexivity.
+      pose (ImpR_ImpL_hpinv _ _ _ J1). destruct p. clear s0. pose (s _ i0). repeat destruct s0.
+      clear s. simpl in IH.
+      assert (J2: derrec_height x5 < S (dersrec_height d)). lia.
+      assert (J3: derrec_height x5 = derrec_height x5). reflexivity.
+      assert (J4: (ctr_L x x1 x2) + (ctr_R x x1 x2)). auto.
+      pose (IH _ J2 _ _ J3 _ _ J4). destruct s.
+      assert (J5: derrec_height x6 = derrec_height x6). reflexivity.
+      assert (J6: derrec_height x6 < S (dersrec_height d)). lia.
+      assert (J8: (ctr_L x0 x2 x3) + (ctr_R x0 x2 x3)). auto.
+      pose (IH _ J6 _ _ J5 _ _ J8). destruct s. pose (dlCons x7 DersNil).
+      pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[x3]) (Γ0 ++ Γ1, Δ0 ++ x --> x0 :: Δ1 ++ Δ2) i d0). simpl. exists d1. simpl. rewrite dersrec_height_nil.
+      lia. reflexivity. }
+  (* ImpL *)
+  * inversion H1. subst. inversion H5. subst. pose (ImpL_app_ctr_R _ _ _ _ _ ctr H1). destruct s.
+    repeat destruct s. repeat destruct p. apply ImpL in i.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x;x0]) (Γ0 ++ A0 --> B :: Γ1, Δ0 ++ A :: Δ1 ++ Δ2) i). subst. simpl.
+    remember [(Γ0 ++ Γ1, Δ3 ++ A0 :: Δ4);(Γ0 ++ B :: Γ1, Δ3 ++ Δ4)] as ps'. destruct d.
+    inversion Heqps'. inversion Heqps'. subst.
+    remember [(Γ0 ++ B :: Γ1, Δ3 ++ Δ4)] as ps''. destruct d1. inversion Heqps''.
+    inversion Heqps''. simpl. subst. rewrite dersrec_height_nil. simpl in IH.
+    rewrite dersrec_height_nil in IH. rewrite Nat.max_0_r. rewrite Nat.max_0_r in IH.
+    assert (E1: derrec_height d < S (Init.Nat.max (derrec_height d)(derrec_height d1))).
+    apply Nat.lt_succ_r. apply Nat.le_max_l.
+    assert (E2: derrec_height d = derrec_height d). auto.
+    assert ((ctr_L A (Γ0 ++ Γ1, Δ3 ++ A0 :: Δ4) x) + (ctr_R A (Γ0 ++ Γ1, Δ3 ++ A0 :: Δ4) x)).
+    auto.
+    pose (IH (derrec_height d) E1 (Γ0 ++ Γ1, Δ3 ++ A0 :: Δ4) d E2 x A H).
+    destruct s.
+    assert (E3: derrec_height d1 < S (Init.Nat.max (derrec_height d)(derrec_height d1))).
+    apply Nat.lt_succ_r. apply Nat.le_max_r.
+    assert (E4: derrec_height d1 = derrec_height d1). auto.
+    assert ((ctr_L A (Γ0 ++ B :: Γ1, Δ3 ++ Δ4) x0) + (ctr_R A (Γ0 ++ B :: Γ1, Δ3 ++ Δ4) x0)).
+    auto.
+    pose (IH (derrec_height d1) E3 (Γ0 ++ B :: Γ1, Δ3 ++ Δ4) d1 E4 x0 A H0).
+    destruct s.
+    pose (dlCons x1 (dlCons x2 d2)). pose (d0 d3). exists d4. simpl. rewrite dersrec_height_nil.
+    rewrite Nat.max_0_r. rewrite <- Nat.succ_le_mono. apply Nat.max_le_compat.
+    assumption. assumption. reflexivity. reflexivity. reflexivity.
+  (* KR *)
+  * inversion X. rewrite <- H4 in X. pose (KR_app_ctr_R _ _ _ _ ctr X).
+    apply KR in k0.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[(unboxed_list , [A0])]) sc k0). subst. simpl. pose (d0 d). exists d1.
+    simpl. rewrite <- Nat.succ_le_mono. left. }
+Qed.
+ +
+Theorem KS_hpadm_ctr_LR : forall s (D0 : KS_prv s),
+          (forall sc A, ((ctr_L A s sc) + (ctr_R A s sc)) ->
+          existsT2 (D1 : KS_prv sc),
+          derrec_height D1 <= derrec_height D0).
+Proof.
+intros.
+assert (J0: derrec_height D0 = derrec_height D0). auto.
+pose (@KS_hpadm_ctr_LR0 (derrec_height D0) _ D0 J0 _ _ H).
+auto.
+Qed.
+ +
+Theorem KS_hpadm_ctr_L : forall (k : nat) s
+        (D0 : KS_prv s),
+        k = (derrec_height D0) ->
+          (forall sc A, ((@ctr_L A s sc) ->
+          existsT2 (D1 : KS_prv sc),
+          derrec_height D1 <= k)).
+Proof.
+intros. intros. assert (H1: derrec_height D0 = derrec_height D0). reflexivity.
+assert (H3 : (ctr_L A s sc) + (ctr_R A s sc)). auto.
+pose (@KS_hpadm_ctr_LR0 (derrec_height D0) s
+D0 H1 sc A H3). destruct s0. exists x. lia.
+Qed.
+ +
+Theorem KS_hpadm_ctr_R : forall (k : nat) s
+        (D0 : KS_prv s),
+        k = (derrec_height D0) ->
+          (forall sc A, ((@ctr_R A s sc) ->
+          existsT2 (D1 : KS_prv sc),
+          derrec_height D1 <= k)).
+Proof.
+intros. intros. assert (H1: derrec_height D0 = derrec_height D0). reflexivity.
+assert (H3 : (ctr_L A s sc) + (ctr_R A s sc)). auto.
+pose (@KS_hpadm_ctr_LR0 (derrec_height D0) s
+D0 H1 sc A H3). destruct s0. exists x. lia.
+Qed.
+ +
+(* We can now prove that contraction of lists is also admissible. *)
+ +
+Theorem KS_hpadm_list_ctr_L : forall Γ1 (k : nat) Γ0 Γ2 Γ3 Δ
+        (D0 : KS_prv (Γ0 ++ Γ1 ++ Γ2 ++ Γ1 ++ Γ3,Δ)),
+        k = (derrec_height D0) ->
+          existsT2 (D1 : KS_prv (Γ0 ++ Γ1 ++ Γ2 ++ Γ3,Δ)),
+          derrec_height D1 <= k.
+Proof.
+induction Γ1.
+- intros. exists D0. rewrite H. auto.
+- intros. assert (H0: derrec_height D0 = derrec_height D0). reflexivity.
+  assert (H1 : ctr_L a (Γ0 ++ (a :: Γ1) ++ Γ2 ++ (a :: Γ1) ++ Γ3, Δ) ((Γ0 ++ [a]) ++ Γ1 ++ Γ2 ++ Γ1 ++ Γ3, Δ)).
+  simpl. assert (Γ0 ++ a :: Γ1 ++ Γ2 ++ a :: Γ1 ++ Γ3 = Γ0 ++ a :: (Γ1 ++ Γ2) ++ a :: (Γ1 ++ Γ3)).
+  repeat rewrite <- app_assoc. reflexivity. rewrite H1.
+  assert ((Γ0 ++ [a]) ++ Γ1 ++ Γ2 ++ Γ1 ++ Γ3 = Γ0 ++ a :: (Γ1 ++ Γ2) ++ Γ1 ++ Γ3). repeat rewrite <- app_assoc.
+  reflexivity. rewrite H2. apply ctr_LI.
+  assert ((ctr_L a (Γ0 ++ (a :: Γ1) ++ Γ2 ++ (a :: Γ1) ++ Γ3, Δ) ((Γ0 ++ [a]) ++ Γ1 ++ Γ2 ++ Γ1 ++ Γ3, Δ)) +
+  (ctr_R a (Γ0 ++ (a :: Γ1) ++ Γ2 ++ (a :: Γ1) ++ Γ3, Δ) ((Γ0 ++ [a]) ++ Γ1 ++ Γ2 ++ Γ1 ++ Γ3, Δ))). auto.
+  pose (@KS_hpadm_ctr_LR0 (derrec_height D0) (Γ0 ++ (a :: Γ1) ++ Γ2 ++ (a :: Γ1) ++ Γ3, Δ)
+  D0 H0 ((Γ0 ++ [a]) ++ Γ1 ++ Γ2 ++ Γ1 ++ Γ3, Δ) a H2). destruct s.
+  assert (H3: derrec_height x = derrec_height x). reflexivity.
+  pose (IHΓ1 (derrec_height x) (Γ0 ++ [a]) Γ2 Γ3 Δ x H3). destruct s.
+  assert (Γ0 ++ (a :: Γ1) ++ Γ2 ++ Γ3 = (Γ0 ++ [a]) ++ Γ1 ++ Γ2 ++ Γ3). repeat rewrite <- app_assoc. auto.
+  rewrite H4. exists x0. lia.
+Qed.
+ +
+Theorem KS_hpadm_list_ctr_R : forall Δ1 (k : nat) Γ Δ0 Δ2 Δ3
+        (D0 : KS_prv (Γ,Δ0 ++ Δ1 ++ Δ2 ++ Δ1 ++ Δ3)),
+        k = (derrec_height D0) ->
+          existsT2 (D1 : KS_prv (Γ,Δ0 ++ Δ1 ++ Δ2 ++ Δ3)),
+          derrec_height D1 <= k.
+Proof.
+induction Δ1.
+- intros. exists D0. rewrite H. auto.
+- intros. assert (H0: derrec_height D0 = derrec_height D0). reflexivity.
+  assert (H1 : ctr_R a (Γ, Δ0 ++ (a :: Δ1) ++ Δ2 ++ (a :: Δ1) ++ Δ3) (Γ, (Δ0 ++ [a]) ++ Δ1 ++ Δ2 ++ Δ1 ++ Δ3)).
+  simpl. assert (Δ0 ++ a :: Δ1 ++ Δ2 ++ a :: Δ1 ++ Δ3 = Δ0 ++ a :: (Δ1 ++ Δ2) ++ a :: (Δ1 ++ Δ3)).
+  repeat rewrite <- app_assoc. reflexivity. rewrite H1.
+  assert ((Δ0 ++ [a]) ++ Δ1 ++ Δ2 ++ Δ1 ++ Δ3 = Δ0 ++ a :: (Δ1 ++ Δ2) ++ Δ1 ++ Δ3). repeat rewrite <- app_assoc.
+  reflexivity. rewrite H2. apply ctr_RI.
+  assert ((ctr_L a (Γ, Δ0 ++ (a :: Δ1) ++ Δ2 ++ (a :: Δ1) ++ Δ3) (Γ, (Δ0 ++ [a]) ++ Δ1 ++ Δ2 ++ Δ1 ++ Δ3)) +
+  (ctr_R a (Γ, Δ0 ++ (a :: Δ1) ++ Δ2 ++ (a :: Δ1) ++ Δ3) (Γ, (Δ0 ++ [a]) ++ Δ1 ++ Δ2 ++ Δ1 ++ Δ3))). auto.
+  pose (@KS_hpadm_ctr_LR0 (derrec_height D0) (Γ, Δ0 ++ (a :: Δ1) ++ Δ2 ++ (a :: Δ1) ++ Δ3)
+  D0 H0 (Γ, (Δ0 ++ [a]) ++ Δ1 ++ Δ2 ++ Δ1 ++ Δ3) a H2). destruct s.
+  assert (H3: derrec_height x = derrec_height x). reflexivity.
+  pose (IHΔ1 (derrec_height x) Γ (Δ0 ++ [a]) Δ2 Δ3 x H3). destruct s.
+  assert (Δ0 ++ (a :: Δ1) ++ Δ2 ++ Δ3 = (Δ0 ++ [a]) ++ Δ1 ++ Δ2 ++ Δ3). repeat rewrite <- app_assoc. auto.
+  rewrite H4. exists x0. lia.
+Qed.
+ +
+
+
+ +
+ + + diff --git a/K.KS.KS_cut_elim.html b/K.KS.KS_cut_elim.html new file mode 100644 index 0000000..d928368 --- /dev/null +++ b/K.KS.KS_cut_elim.html @@ -0,0 +1,87 @@ + + + + + + + + + + + + + +
+
+

K.KS.KS_cut_elim

+ +
+Require Import List.
+Export ListNotations.
+Require Import Lia.
+Require Import PeanoNat.
+ +
+Require Import KS_calc.
+Require Import KS_termination_measure.
+Require Import KS_termination.
+Require Import KS_exch.
+Require Import KS_ctr.
+Require Import KS_wkn.
+Require Import KS_dec.
+Require Import KS_inv_ImpR_ImpL.
+Require Import KS_additive_cut.
+ +
+Inductive CutRule : rlsT Seq :=
+  | CutRule_I : forall A Γ0 Γ1 Δ0 Δ1,
+          CutRule [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1) ; (Γ0 ++ A :: Γ1, Δ0 ++ Δ1)]
+                    (Γ0 ++ Γ1, Δ0 ++ Δ1)
+.
+ +
+Inductive KS_cut_rules : rlsT Seq :=
+  | KS_woc : forall ps c, KS_rules ps c -> KS_cut_rules ps c
+  | KS_cut : forall ps c, CutRule ps c -> KS_cut_rules ps c
+.
+ +
+Definition KS_cut_prv s := derrec KS_cut_rules (fun _ => False) s.
+Definition KS_cut_drv s := derrec KS_cut_rules (fun _ => True) s.
+ +
+Theorem KS_cut_elimination : forall s, (KS_cut_prv s) -> (KS_prv s).
+Proof.
+intros s D.
+apply derrec_all_rect with
+(Q:= fun x => (KS_prv x))
+in D ; auto.
+- intros. inversion H.
+- intros ps concl rule ders IH. inversion rule.
+  * subst. apply derI with (ps:=ps) ; auto. apply dersrec_forall. intros. pose (ForallTD_forall IH H) ; auto.
+  * subst. inversion H. subst. apply KS_cut_adm with (A:=A).
+    pose (ForallTD_forall IH). apply k ; apply InT_eq.
+    pose (ForallTD_forall IH). apply k ; apply InT_cons ; apply InT_eq.
+Defined.
+
+
+ +
+ + + diff --git a/K.KS.KS_dec.html b/K.KS.KS_dec.html new file mode 100644 index 0000000..abb9de7 --- /dev/null +++ b/K.KS.KS_dec.html @@ -0,0 +1,296 @@ + + + + + + + + + + + + + +
+
+

K.KS.KS_dec

+ +
+Require Import List.
+Export ListNotations.
+Require Import Lia.
+Require Import PeanoNat.
+ +
+Require Import KS_calc.
+ +
+(* In this file we show that the applicability of the rules in KS is decidable. *)
+ +
+Lemma top_boxes_incl_list : forall l, incl (top_boxes l) l.
+Proof.
+induction l.
+- simpl. unfold incl. intros. inversion H.
+- unfold incl. intros. destruct a.
+  * simpl in H. apply in_cons. apply IHl. assumption.
+  * simpl in H. apply in_cons. apply IHl. assumption.
+  * simpl in H. apply in_cons. apply IHl. assumption.
+  * simpl in H. destruct H.
+    + subst. apply in_eq.
+    + apply in_cons. apply IHl. assumption.
+Qed.
+ +
+Definition in_top_boxes : forall l A, (In A (top_boxes l)) -> (existsT2 B l1 l2, (A = Box B) * (l = l1 ++ A :: l2)).
+Proof.
+induction l.
+- intros. simpl in H. inversion H.
+- intros. destruct a as [n| | |].
+  * simpl in H. apply IHl in H. destruct H. destruct s. destruct s. destruct p. subst.
+    exists x. exists ([# n] ++ x0). exists x1. auto.
+  * simpl in H. apply IHl in H. destruct H. destruct s. destruct s. destruct p. subst.
+    exists x. exists ([Bot] ++ x0). exists x1. auto.
+  * simpl in H. apply IHl in H. destruct H. destruct s. destruct s. destruct p. subst.
+    exists x. exists ([a1 --> a2] ++ x0). exists x1. auto.
+  * simpl (top_boxes (Box a :: l)) in H. destruct (eq_dec_form (Box a) A).
+    + subst. exists a. exists []. exists l. auto.
+    + subst. assert (H0 : In A (top_boxes l)). inversion H. exfalso. apply n. assumption.
+      assumption. apply IHl in H0. destruct H0. destruct s. destruct s. destruct p.
+      subst. exists x. exists ([Box a] ++ x0). exists x1. auto.
+Defined.
+ +
+Definition dec_is_PropVar : forall (A : MPropF), (existsT2 P, A = # P) + ((existsT2 P, A = # P) -> False).
+Proof.
+induction A as [n| | |].
+- left. exists n. reflexivity.
+- right. intro. inversion H. inversion H0.
+- right. intro. inversion H. inversion H0.
+- right. intro. inversion H. inversion H0.
+Defined.
+ +
+Definition dec_prop_var_in : forall s, (existsT2 P, (In (# P) (fst s)) /\ (In (# P) (snd s))) +
+                                      ((existsT2 P, (In (# P) (fst s)) /\ (In (# P) (snd s))) -> False).
+Proof.
+intro. destruct s.
+induction l.
+- right. intro. destruct H. destruct a. simpl in H. inversion H.
+- destruct IHl.
+  * destruct s. simpl in a0. destruct a0. left. exists x. simpl. split. auto. assumption.
+  * destruct (dec_is_PropVar a) ; simpl.
+    + destruct (In_dec l0 a).
+      { left. subst. destruct s. exists x. simpl. split. auto. subst. assumption. }
+      { right. simpl. intro. destruct H. destruct a0. destruct H.
+        - subst. apply n. assumption.
+        - apply f. simpl. exists x. firstorder. }
+    + right. intro. simpl in H. destruct H. destruct a0. destruct H.
+      { subst. apply f0. exists x. reflexivity. }
+      { apply f. firstorder. }
+Defined.
+ +
+Definition dec_is_boxedT : forall (A : MPropF), (is_boxedT A) + ((is_boxedT A) -> False).
+Proof.
+induction A.
+- right. intro. inversion X. inversion H.
+- right. intro. inversion X. inversion H.
+- right. intro. inversion X. inversion H.
+- left. exists A. reflexivity.
+Defined.
+ +
+Definition dec_is_box : forall (A : MPropF), (existsT2 B, A = Box B) + ((existsT2 B, A = Box B ) -> False).
+Proof.
+destruct A.
+- right. intro. destruct H. inversion e.
+- right. intro. destruct H. inversion e.
+- right. intro. destruct H. inversion e.
+- left. exists A. reflexivity.
+Defined.
+ +
+Definition dec_box_in : forall s, (existsT2 (A : MPropF), (In (Box A) (fst s)) /\ (In (Box A) (snd s))) +
+                             ((existsT2 (A : MPropF), (In (Box A) (fst s)) /\ (In (Box A) (snd s))) -> False).
+Proof.
+intro. destruct s.
+induction l.
+- right. intro. destruct H. destruct a. simpl in H. inversion H.
+- destruct IHl.
+  * destruct s. simpl in a0. destruct a0. left. exists x. simpl. split. auto. assumption.
+  * destruct (dec_is_box a).
+    + destruct (In_dec l0 a).
+      { left. destruct s. subst. simpl. exists x. split. auto. assumption. }
+      { right. simpl. intro. destruct H. destruct a0. destruct H.
+        - subst. apply n. assumption.
+        - apply f. simpl. exists x. firstorder. }
+    + right. intro. simpl in H. destruct H. destruct a0. destruct H.
+      { subst. apply f0. exists x. reflexivity. }
+      { apply f. firstorder. }
+Defined.
+ +
+Definition dec_KS_init_rules : forall (s :Seq) ,
+          ((IdPRule [] s) + (BotLRule [] s)) +
+          (((IdPRule [] s) + (BotLRule [] s)) -> False).
+Proof.
+intro s. destruct s. destruct (dec_prop_var_in (pair l l0)).
+- destruct s. destruct a. left. left. simpl in H. simpl in H0.
+  apply in_splitT in H. destruct H. destruct s. apply in_splitT in H0. destruct H0. destruct s.
+  subst. apply IdPRule_I.
+- destruct (In_dec l (Bot)).
+  + left. apply in_splitT in i. destruct i. destruct s. subst. right. apply BotLRule_I.
+  + right. intro. destruct H.
+    * inversion i. subst. simpl in f. apply f. exists P. split ; apply in_or_app ; right ; apply in_eq.
+    * inversion b. subst. apply n. apply in_or_app. right. apply in_eq.
+Defined.
+ +
+Definition dec_IdP_rule : forall (s :Seq) ,
+          (IdPRule [] s) +
+          ((IdPRule [] s) -> False).
+Proof.
+intro s. destruct s. destruct (dec_prop_var_in (pair l l0)).
+- destruct s. destruct a. left. simpl in H. simpl in H0.
+  apply in_splitT in H. destruct H. destruct s. apply in_splitT in H0. destruct H0. destruct s.
+  subst. apply IdPRule_I.
+- right. intro. destruct H. apply f. exists P. split ; apply in_or_app ; right ; apply in_eq.
+Defined.
+ +
+Definition dec_BotL_rule : forall (s :Seq) ,
+          (BotLRule [] s) +
+          ((BotLRule [] s) -> False).
+Proof.
+intro s. destruct s. destruct (In_dec l (Bot)).
+- left. apply in_splitT in i. destruct i. destruct s. subst. apply BotLRule_I.
+- right. intro. inversion H. apply n. subst. apply in_or_app. right. apply in_eq.
+Defined.
+ +
+Definition dec_is_imp : forall (A : MPropF), (existsT2 B C, A = Imp B C) + ((existsT2 B C, A = Imp B C) -> False).
+Proof.
+destruct A as [n| | |].
+- right. intro. destruct H. destruct s. inversion e.
+- right. intro. destruct H. destruct s. inversion e.
+- left. exists A1. exists A2. reflexivity.
+- right. intro. destruct H. destruct s. inversion e.
+Defined.
+ +
+Definition dec_imp_in : forall (l : list MPropF), (existsT2 A B, In (Imp A B) l) + ((existsT2 A B, In (Imp A B) l) -> False).
+Proof.
+induction l.
+- right. intro. destruct H. destruct s. inversion i.
+- destruct IHl.
+  * repeat destruct s. left. exists x. exists x0. apply in_cons. assumption.
+  * destruct (dec_is_imp a).
+    + repeat destruct s. subst. left. exists x. exists x0. apply in_eq.
+    + right. intro. destruct H. destruct s. inversion i.
+      { subst. apply f0. exists x. exists x0. reflexivity. }
+      { apply f. exists x. exists x0. assumption. }
+Defined.
+ +
+Definition dec_ImpR_rule : forall (concl :Seq),
+          (existsT2 prem, ImpRRule [prem] concl) + ((existsT2 prem, ImpRRule [prem] concl) -> False).
+Proof.
+intros concl. destruct concl. destruct (dec_imp_in l0).
+- left. repeat destruct s. apply in_splitT in i. destruct i. destruct s. subst.
+  exists ([] ++ x :: l, x1 ++ x0 :: x2). assert ((l, x1 ++ x --> x0 :: x2) = ([] ++ l, x1 ++ x --> x0 :: x2)).
+  reflexivity. apply ImpRRule_I.
+- right. intro. destruct H. inversion i. subst. apply f. exists A. exists B. apply in_or_app.
+  right. apply in_eq.
+Defined.
+ +
+Definition dec_ImpL_rule : forall (concl :Seq),
+          (existsT2 prem1 prem2, ImpLRule [prem1 ; prem2] concl) + ((existsT2 prem1 prem2, ImpLRule [prem1 ; prem2] concl) -> False).
+Proof.
+intro concl. destruct concl. destruct (dec_imp_in l).
+- left. repeat destruct s. apply in_splitT in i. destruct i. destruct s. subst.
+  exists (x1 ++ x2, [] ++ x :: l0). exists (x1 ++ x0 :: x2, [] ++ l0).
+  assert ((x1 ++ x --> x0 :: x2, l0) = (x1 ++ x --> x0 :: x2, [] ++ l0)). reflexivity.
+  rewrite H. apply ImpLRule_I.
+- right. intro. destruct H. destruct s. inversion i. subst. apply f. exists A. exists B.
+  apply in_or_app. right. apply in_eq.
+Defined.
+ +
+Definition dec_box_in_list : forall l, (existsT2 (A : MPropF), In (Box A) l) +
+                             ((existsT2 (A : MPropF), In (Box A) l) -> False).
+Proof.
+induction l.
+- simpl. right. intro. destruct H. assumption.
+- destruct (dec_is_box a).
+  * destruct s. subst. left. exists x. apply in_eq.
+  * destruct IHl.
+    + left. destruct s. exists x. apply in_cons. assumption.
+    + right. intro. destruct H. inversion i. subst. apply f. exists x. reflexivity. apply f0.
+      exists x. assumption.
+Defined.
+ +
+Definition dec_KR_rule : forall (concl :Seq),
+          (existsT2 prem, KRRule [prem] concl) + ((existsT2 prem, KRRule [prem] concl) -> False).
+Proof.
+intro concl. destruct concl. destruct (dec_box_in_list l0).
+- left. destruct s. exists ((unboxed_list (top_boxes l)), [x]).
+  apply in_splitT in i. destruct i. destruct s. subst. apply KRRule_I.
+  + unfold is_Boxed_list. intros. apply in_top_boxes in H. destruct H. destruct s. destruct s.
+    destruct p. exists x2. assumption.
+  + induction l. simpl. apply univ_gen_ext_nil. destruct a.
+    * simpl. apply univ_gen_ext_extra. intro. destruct X. inversion H. assumption.
+    * simpl. apply univ_gen_ext_extra. intro. destruct X. inversion H. assumption.
+    * simpl. apply univ_gen_ext_extra. intro. destruct X. inversion H. assumption.
+    * simpl. apply univ_gen_ext_cons. apply IHl.
+- right. intro. destruct X. inversion k. subst. apply f. exists A. apply in_or_app. right. apply in_eq.
+Defined.
+ +
+Definition dec_KS_rules : forall (concl :Seq) ,
+          ((existsT2 prems, KS_rules prems concl) -> False) + (existsT2 prems, KS_rules prems concl).
+Proof.
+intro concl. destruct (dec_KS_init_rules concl).
+- right. repeat destruct s.
+  * exists nil. apply IdP. assumption.
+  * exists nil. apply BotL. assumption.
+- destruct (dec_ImpR_rule concl).
+  * right. destruct s. exists [x]. apply ImpR. assumption.
+  * destruct (dec_ImpL_rule concl).
+    + right. repeat destruct s. exists [x; x0]. apply ImpL. assumption.
+    + destruct (dec_KR_rule concl).
+      { right. repeat destruct s. exists [x]. apply KR. assumption. }
+      { left. intro. destruct X. inversion k.
+        - inversion H. subst. apply f. auto.
+        - inversion H. subst. apply f. auto.
+        - inversion H. subst. apply f0. exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1). assumption.
+        - inversion H. subst. apply f1. exists (Γ0 ++ Γ1, Δ0 ++ A :: Δ1). exists (Γ0 ++ B :: Γ1, Δ0 ++ Δ1).
+          assumption.
+        - inversion X. subst. apply f2. exists (unboxed_list , [A]). assumption. }
+Defined.
+ +
+
+
+ +
+ + + diff --git a/K.KS.KS_exch.html b/K.KS.KS_exch.html new file mode 100644 index 0000000..8968b66 --- /dev/null +++ b/K.KS.KS_exch.html @@ -0,0 +1,495 @@ + + + + + + + + + + + + + +
+
+

K.KS.KS_exch

+ +
+Require Import List.
+Export ListNotations.
+Require Import Lia.
+Require Import PeanoNat Arith.
+ +
+Require Import KS_calc.
+Require Export KS_exch_prelims.
+Require Export KS_exch_ImpR.
+Require Export KS_exch_ImpL.
+Require Export KS_exch_KR.
+ +
+(* We can now prove the admissibility of list_exchange on the left. *)
+ +
+Theorem KS_adm_list_exch_L : forall s,
+        (KS_prv s) ->
+        (forall se, (@list_exch_L s se) ->
+        (KS_prv se)).
+Proof.
+intros s D. apply derrec_all_rect with
+(Q:= fun x => forall (se : Seq),
+list_exch_L x se ->
+derrec KS_rules (fun _ : Seq => False)
+  se)
+in D.
+- exact D.
+- intros concl F. inversion F.
+- intros ps concl rule. induction rule.
+  (* IdP *)
+  * intros ders IH se exch. inversion i. apply derI with (ps:=[]).
+    apply IdP.
+    + assert (Permstose: existsT2 eΓ0 eΓ1, se = (eΓ0 ++ # P :: eΓ1, Δ0 ++ # P :: Δ1)).
+      { pose (list_exch_L_permLR _ _ exch). subst. destruct s0 with (Γ0:=Γ0) (Γ1:=Γ1) (Δ0:=Δ0) (Δ1:=Δ1)
+      (C:=# P) (D:=# P). auto. exists x. assumption. }
+      destruct Permstose. repeat destruct s0. subst. apply IdPRule_I.
+    + apply dersrec_all in ders. apply dersrec_all. subst. assumption.
+  (* BotL *)
+  * intros ders IH se exch. apply derI with (ps:=ps).
+    + apply BotL. inversion b. symmetry in H0.
+      assert (Permstose: existsT2 eΓ0 eΓ1, se = ((eΓ0 ++ Bot :: eΓ1), Δ)).
+      { apply list_exch_L_permL with (s:=c) (Γ0:=Γ0) (Γ1:=Γ1) (Δ:=Δ). assumption.
+        assumption. }
+      destruct Permstose. destruct s0. subst. apply BotLRule_I.
+    + apply dersrec_all in ders. apply dersrec_all. assumption.
+  (* ImpR *)
+  * intros ders IH se exch. inversion i. subst. pose (ImpR_app_list_exchL _ _ _ exch i).
+    destruct s0. destruct p. apply derI with (ps:=[x]).
+    + apply ImpR. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion i0.
+      inversion i. apply ForallT_inv in IH. apply ForallT_cons.
+      { apply IH. subst. assumption. }
+      { apply ForallT_nil. }
+  (* ImpL *)
+  * intros ders IH se exch. inversion i. subst. pose (ImpL_app_list_exchL _ _ _ _ exch i).
+    destruct s0. destruct s0. destruct p. destruct p. apply derI with (ps:=[x;x0]).
+    + apply ImpL. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion i0.
+      inversion i. apply ForallT_cons_inv in IH. destruct IH.
+      apply ForallT_inv in f. apply ForallT_cons.
+      { apply d. subst. assumption. }
+      { apply ForallT_cons. apply f. subst. assumption. apply ForallT_nil. }
+  (* KR *)
+  * intros ders IH se exch. inversion k. subst. pose (KR_app_list_exchL _ _ _ exch k).
+    destruct s0. destruct p. apply derI with (ps:=[x]).
+    + apply KR. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion k0.
+      inversion k. apply ForallT_inv in IH. apply ForallT_cons.
+      { apply IH. subst. assumption. }
+      { apply ForallT_nil. }
+Qed.
+ +
+Theorem KS_adm_list_exch_R : forall s,
+        (KS_prv s) ->
+        (forall se, (@list_exch_R s se) ->
+        (KS_prv se)).
+Proof.
+intros s D. apply derrec_all_rect with
+(Q:= fun x => forall (se : Seq),
+list_exch_R x se ->
+derrec KS_rules (fun _ : Seq => False)
+  se)
+in D.
+- exact D.
+- intros concl F. inversion F.
+- intros ps concl rule. induction rule.
+  (* IdP *)
+  * intros ders IH se exch. inversion i. apply derI with (ps:=[]).
+    apply IdP.
+    + assert (Permstose: existsT2 eΔ0 eΔ1, se = (Γ0 ++ # P :: Γ1, eΔ0 ++ # P :: eΔ1)).
+      { pose (list_exch_R_permLR _ _ exch). subst. destruct s0 with (Γ0:=Γ0) (Γ1:=Γ1) (Δ0:=Δ0) (Δ1:=Δ1)
+      (C:=# P) (D:=# P). auto. exists x. assumption. }
+      destruct Permstose. repeat destruct s0. subst. apply IdPRule_I.
+    + apply dersrec_all in ders. apply dersrec_all. subst. assumption.
+  (* BotL *)
+  * intros ders IH se exch. apply derI with (ps:=ps).
+    + apply BotL. inversion b. symmetry in H0.
+      assert (Permstose: existsT2 , se = ((Γ0 ++ Bot :: Γ1), )).
+      { apply list_exch_R_permL with (s:=c) (Γ0:=Γ0) (Γ1:=Γ1) (Δ:=Δ). assumption.
+        assumption. }
+      destruct Permstose. subst. apply BotLRule_I.
+    + apply dersrec_all in ders. apply dersrec_all. assumption.
+  (* ImpR *)
+  * intros ders IH se exch. inversion i. subst. pose (ImpR_app_list_exchR _ _ _ exch i).
+    destruct s0. destruct p. apply derI with (ps:=[x]).
+    + apply ImpR. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion i0.
+      inversion i. apply ForallT_inv in IH. apply ForallT_cons.
+      { apply IH. subst. assumption. }
+      { apply ForallT_nil. }
+  (* ImpL *)
+  * intros ders IH se exch. inversion i. subst. pose (ImpL_app_list_exchR _ _ _ _ exch i).
+    destruct s0. destruct s0. destruct p. destruct p. apply derI with (ps:=[x;x0]).
+    + apply ImpL. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion i0.
+      inversion i. apply ForallT_cons_inv in IH. destruct IH.
+      apply ForallT_inv in f. apply ForallT_cons.
+      { apply d. subst. assumption. }
+      { apply ForallT_cons. apply f. subst. assumption. apply ForallT_nil. }
+  (* KR *)
+  * intros ders IH se exch. inversion k. subst. pose (KR_app_list_exchR _ _ _ exch k).
+    destruct s0. destruct p. apply derI with (ps:=[x]).
+    + apply KR. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion k0.
+      inversion k. apply ForallT_inv in IH. apply ForallT_cons.
+      { apply IH. subst. assumption. }
+      { apply ForallT_nil. }
+Qed.
+ +
+(* Now we can turn to the derivability of list_exchange. *)
+ +
+Inductive Closure {X: Type} (F : X -> Type) (P : X -> X -> Type) : X -> Type :=
+  | InitClo : forall x, F x -> Closure F P x
+  | IndClo : forall x y, Closure F P y -> (P y x) -> Closure F P x.
+ +
+Inductive ExcClosure (hyps : Seq -> Type) : Seq -> Type :=
+  | InitLExch : forall x, Closure hyps list_exch_L x -> ExcClosure hyps x
+  | InitRExch : forall x, Closure hyps list_exch_R x -> ExcClosure hyps x
+  | IndLExch : forall x y, ExcClosure hyps x -> list_exch_L x y -> ExcClosure hyps y
+  | IndRExch : forall x y, ExcClosure hyps x -> list_exch_R x y -> ExcClosure hyps y.
+ +
+Theorem KS_der_list_exch_L : forall hyps s,
+        (derrec KS_rules hyps s) ->
+        (forall se, (@list_exch_L s se) ->
+        (derrec KS_rules (ExcClosure hyps) se)).
+Proof.
+intros hyps s D. apply derrec_all_rect with
+(Q:= fun x => forall (se : Seq),
+list_exch_L x se ->
+derrec KS_rules (ExcClosure hyps) se) in D.
+- exact D.
+- intros concl H1 se exch. apply dpI. apply InitLExch. apply IndClo with (y:=concl).
+  apply InitClo. assumption. assumption.
+- intros ps concl rule. induction rule.
+  (* IdP *)
+  * intros ders IH se exch. inversion i. apply derI with (ps:=[]).
+    apply IdP.
+    + assert (Permstose: existsT2 eΓ0 eΓ1, se = (eΓ0 ++ # P :: eΓ1, Δ0 ++ # P :: Δ1)).
+      { pose (list_exch_L_permLR _ _ exch). subst. destruct s0 with (Γ0:=Γ0) (Γ1:=Γ1) (Δ0:=Δ0) (Δ1:=Δ1)
+      (C:=# P) (D:=# P). auto. exists x. assumption. }
+      destruct Permstose. repeat destruct s0. subst. apply IdPRule_I.
+    + apply dersrec_all in ders. apply dersrec_nil.
+  (* BotL *)
+  * intros ders IH se exch. apply derI with (ps:=ps).
+    + apply BotL. inversion b. symmetry in H0.
+      assert (Permstose: existsT2 eΓ0 eΓ1, se = ((eΓ0 ++ Bot :: eΓ1), Δ)).
+      { apply list_exch_L_permL with (s:=c) (Γ0:=Γ0) (Γ1:=Γ1) (Δ:=Δ). assumption.
+        assumption. }
+      destruct Permstose. repeat destruct s0. subst. apply BotLRule_I.
+    + apply dersrec_all in ders. inversion b. apply dersrec_nil.
+  (* ImpR *)
+  * intros ders IH se exch. inversion i. subst. pose (ImpR_app_list_exchL _ _ _ exch i).
+    destruct s0. destruct p. apply derI with (ps:=[x]).
+    + apply ImpR. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion i0.
+      inversion i. apply ForallT_inv in IH. apply ForallT_cons.
+      { apply IH. subst. assumption. }
+      { apply ForallT_nil. }
+  (* ImpL *)
+  * intros ders IH se exch. inversion i. subst. pose (ImpL_app_list_exchL _ _ _ _ exch i).
+    destruct s0. destruct s0. destruct p. destruct p. apply derI with (ps:=[x;x0]).
+    + apply ImpL. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion i0.
+      inversion i. apply ForallT_cons_inv in IH. destruct IH.
+      apply ForallT_inv in f. apply ForallT_cons.
+      { apply d. subst. assumption. }
+      { apply ForallT_cons. apply f. subst. assumption. apply ForallT_nil. }
+  (* KR *)
+  * intros ders IH se exch. inversion k. subst. pose (KR_app_list_exchL _ _ _ exch k).
+    destruct s0. destruct p. apply derI with (ps:=[x]).
+    + apply KR. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion k0.
+      inversion k. apply ForallT_inv in IH. apply ForallT_cons.
+      { apply IH. subst. assumption. }
+      { apply ForallT_nil. }
+Qed.
+ +
+Theorem KS_der_list_exch_R : forall hyps s,
+        (derrec KS_rules hyps s) ->
+        (forall se, (@list_exch_R s se) ->
+        (derrec KS_rules (ExcClosure hyps) se)).
+Proof.
+intros hyps s D. apply derrec_all_rect with
+(Q:= fun x => forall (se : Seq),
+list_exch_R x se ->
+derrec KS_rules (ExcClosure hyps) se) in D.
+- exact D.
+- intros concl H1 se exch. apply dpI. apply InitRExch. apply IndClo with (y:=concl).
+  apply InitClo. assumption. assumption.
+- intros ps concl rule. induction rule.
+  (* IdP *)
+  * intros ders IH se exch. inversion i. apply derI with (ps:=[]).
+    apply IdP.
+    + assert (Permstose: existsT2 eΔ0 eΔ1, se = (Γ0 ++ # P :: Γ1, eΔ0 ++ # P :: eΔ1)).
+      { pose (list_exch_R_permLR _ _ exch). subst. destruct s0 with (Γ0:=Γ0) (Γ1:=Γ1) (Δ0:=Δ0) (Δ1:=Δ1)
+      (C:=# P) (D:=# P). auto. exists x. assumption. }
+      destruct Permstose. repeat destruct s0. subst. apply IdPRule_I.
+    + apply dersrec_all in ders. apply dersrec_nil.
+  (* BotL *)
+  * intros ders IH se exch. apply derI with (ps:=ps).
+    + apply BotL. inversion b. symmetry in H0.
+      assert (Permstose: existsT2 , se = ((Γ0 ++ Bot :: Γ1), )).
+      { apply list_exch_R_permL with (s:=c) (Γ0:=Γ0) (Γ1:=Γ1) (Δ:=Δ). assumption.
+        assumption. }
+      destruct Permstose. subst. apply BotLRule_I.
+    + apply dersrec_all in ders. inversion b. apply dersrec_nil.
+  (* ImpR *)
+  * intros ders IH se exch. inversion i. subst. pose (ImpR_app_list_exchR _ _ _ exch i).
+    destruct s0. destruct p. apply derI with (ps:=[x]).
+    + apply ImpR. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion i0.
+      inversion i. apply ForallT_inv in IH. apply ForallT_cons.
+      { apply IH. subst. assumption. }
+      { apply ForallT_nil. }
+  (* ImpL *)
+  * intros ders IH se exch. inversion i. subst. pose (ImpL_app_list_exchR _ _ _ _ exch i).
+    destruct s0. destruct s0. destruct p. destruct p. apply derI with (ps:=[x;x0]).
+    + apply ImpL. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion i0.
+      inversion i. apply ForallT_cons_inv in IH. destruct IH.
+      apply ForallT_inv in f. apply ForallT_cons.
+      { apply d. subst. assumption. }
+      { apply ForallT_cons. apply f. subst. assumption. apply ForallT_nil. }
+  (* KR *)
+  * intros ders IH se exch. inversion k. subst. pose (KR_app_list_exchR _ _ _ exch k).
+    destruct s0. destruct p. apply derI with (ps:=[x]).
+    + apply KR. assumption.
+    + apply dersrec_all. apply dersrec_all in ders. inversion k0.
+      inversion k. apply ForallT_inv in IH. apply ForallT_cons.
+      { apply IH. subst. assumption. }
+      { apply ForallT_nil. }
+Qed.
+ +
+(* In fact, we can prove that exchange is height-preserving admissible. *)
+ +
+Theorem KS_hpadm_list_exch_R0 : forall (k : nat) s
+                                  (D0: KS_prv s),
+        k = (derrec_height D0) ->
+        (forall se, (list_exch_R s se) ->
+        (existsT2 (D1 : KS_prv se),
+          derrec_height D1 <=k)).
+Proof.
+induction k as [n IH] using (well_founded_induction_type lt_wf).
+(* Now we do the actual proof-theoretical work. *)
+intros s0 D0. remember D0 as D0'. destruct D0.
+(* D0 ip a leaf *)
+- inversion f.
+(* D0 is ends with an application of rule *)
+- intros hei se exch. inversion exch.
+  assert (DersNil: dersrec KS_rules (fun _ : Seq => False) []).
+  apply dersrec_nil. inversion k.
+  (* IdP *)
+  * inversion H1. subst. inversion H5. subst. simpl.
+    assert (In # P (Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4)). assert (In # P (Δ0 ++ Δ1 ++ Δ2 ++ Δ3 ++ Δ4)).
+    rewrite <- H2. apply in_or_app. right. apply in_eq. apply in_app_or in H. apply in_or_app.
+    destruct H. auto. apply in_app_or in H. right. apply in_or_app. destruct H. right. apply in_or_app.
+    right. apply in_or_app. auto. apply in_app_or in H. destruct H. right. apply in_or_app. auto.
+    apply in_app_or in H. destruct H. auto. right. apply in_or_app. right. apply in_or_app. auto.
+    apply in_splitT in H. destruct H. destruct s. rewrite e.
+    assert (IdPRule [] (Γ0 ++ # P :: Γ1, x ++ # P :: x0)). apply IdPRule_I. apply IdP in H.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[]) (Γ0 ++ # P :: Γ1, x ++ # P :: x0) H DersNil). exists d0. simpl. rewrite dersrec_height_nil.
+    lia. reflexivity.
+  (* BotL *)
+  * inversion H1. subst. inversion H5. subst. simpl.
+    assert (BotLRule [] (Γ0 ++ Bot :: Γ1, Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4)). apply BotLRule_I. apply BotL in H.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[]) (Γ0 ++ Bot :: Γ1, Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4) H DersNil). exists d0. simpl. rewrite dersrec_height_nil.
+    lia. reflexivity.
+  (* ImpR *)
+  * inversion H1. subst. inversion H5. subst. simpl. simpl in IH.
+    pose (ImpR_app_list_exchR _ _ _ exch H1). destruct s. destruct p.
+    apply ImpR in i. assert (J0: dersrec_height d = dersrec_height d). reflexivity.
+    pose (dersrec_derrec_height d J0). destruct s.
+    assert (E: derrec_height x0 < S (dersrec_height d)). lia.
+    assert (E1: derrec_height x0 = derrec_height x0). auto.
+    pose (IH (derrec_height x0) E (Γ0 ++ A :: Γ1, Δ5 ++ B :: Δ6) x0 E1 x l).
+    destruct s. pose (dlCons x1 DersNil).
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x]) (Γ0 ++ Γ1, Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4) i d0). exists d1. simpl.
+    rewrite dersrec_height_nil. rewrite Nat.max_0_r. lia. reflexivity.
+  (* ImpL *)
+  * inversion H1. subst. inversion H5. subst. simpl. simpl in IH.
+    pose (ImpL_app_list_exchR _ _ _ _ exch H1). repeat destruct s. repeat destruct p.
+    apply ImpL in i. assert (J0: dersrec_height d = dersrec_height d). reflexivity.
+    pose (dersrec_derrec2_height d J0). repeat destruct s.
+    assert (E: derrec_height x1 < S (dersrec_height d)). lia.
+    assert (E1: derrec_height x1 = derrec_height x1). auto.
+    pose (IH (derrec_height x1) E (Γ0 ++ Γ1, Δ5 ++ A :: Δ6) x1 E1 x l0).
+    destruct s.
+    assert (E2: derrec_height x2 < S (dersrec_height d)). lia.
+    assert (E3: derrec_height x2 = derrec_height x2). auto.
+    pose (IH (derrec_height x2) E2 (Γ0 ++ B :: Γ1, Δ5 ++ Δ6) x2 E3 x0 l).
+    destruct s. pose (dlCons x4 DersNil). pose (dlCons x3 d0).
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x; x0]) (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4) i d1). exists d2. simpl.
+    rewrite dersrec_height_nil. rewrite Nat.max_0_r. lia. reflexivity.
+  (* KR *)
+  * inversion X. subst. inversion H5. subst. simpl. simpl in IH.
+    pose (KR_app_list_exchR _ _ _ exch X). destruct s. destruct p.
+    apply KR in k0. assert (J0: dersrec_height d = dersrec_height d). reflexivity.
+    pose (dersrec_derrec_height d J0). destruct s.
+    assert (E: derrec_height x0 < S (dersrec_height d)). lia.
+    assert (E1: derrec_height x0 = derrec_height x0). auto.
+    pose (IH (derrec_height x0) E (unboxed_list , [A]) x0 E1 x l).
+    destruct s. pose (dlCons x1 DersNil).
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x]) (Γ, Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4) k0 d0). exists d1. simpl.
+    rewrite dersrec_height_nil. rewrite Nat.max_0_r. lia. reflexivity.
+Qed.
+ +
+Theorem KS_hpadm_list_exch_L0 : forall (k : nat) s
+                                  (D0: KS_prv s),
+        k = (derrec_height D0) ->
+        (forall se, (list_exch_L s se) ->
+        (existsT2 (D1 : KS_prv se),
+          derrec_height D1 <=k)).
+Proof.
+induction k as [n IH] using (well_founded_induction_type lt_wf).
+intros s0 D0. remember D0 as D0'. destruct D0.
+(* D0 ip a leaf *)
+- inversion f.
+(* D0 is ends with an application of rule *)
+- intros hei se exch. inversion exch.
+  assert (DersNil: dersrec KS_rules (fun _ : Seq => False) []).
+  apply dersrec_nil. inversion k.
+  (* IdP *)
+  * inversion H1. subst. inversion H5. subst. simpl.
+    assert (In # P (Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4)). assert (In # P (Γ0 ++ Γ1 ++ Γ2 ++ Γ3 ++ Γ4)).
+    rewrite <- H0. apply in_or_app. right. apply in_eq. apply in_app_or in H. apply in_or_app.
+    destruct H. auto. apply in_app_or in H. right. apply in_or_app. destruct H. right. apply in_or_app.
+    right. apply in_or_app. auto. apply in_app_or in H. destruct H. right. apply in_or_app. auto.
+    apply in_app_or in H. destruct H. auto. right. apply in_or_app. right. apply in_or_app. auto.
+    apply in_splitT in H. destruct H. destruct s. rewrite e.
+    assert (IdPRule [] (x ++ # P :: x0, Δ0 ++ # P :: Δ1)). apply IdPRule_I. apply IdP in H.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[]) (x ++ # P :: x0, Δ0 ++ # P :: Δ1) H DersNil). exists d0. simpl. rewrite dersrec_height_nil.
+    lia. reflexivity.
+  (* BotL *)
+  * inversion H1. subst. inversion H5. subst. simpl.
+    assert (In (Bot) (Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4)). assert (In (Bot) (Γ0 ++ Γ1 ++ Γ2 ++ Γ3 ++ Γ4)).
+    rewrite <- H0. apply in_or_app. right. apply in_eq. apply in_app_or in H. apply in_or_app.
+    destruct H. auto. apply in_app_or in H. right. apply in_or_app. destruct H. right. apply in_or_app.
+    right. apply in_or_app. auto. apply in_app_or in H. destruct H. right. apply in_or_app. auto.
+    apply in_app_or in H. destruct H. auto. right. apply in_or_app. right. apply in_or_app. auto.
+    apply in_splitT in H. destruct H. destruct s. rewrite e.
+    assert (BotLRule [] (x ++ Bot :: x0, Δ)). apply BotLRule_I. apply BotL in H.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[]) (x ++ Bot :: x0, Δ) H DersNil). exists d0. simpl. rewrite dersrec_height_nil.
+    lia. reflexivity.
+  (* ImpR *)
+  * inversion H1. subst. inversion H5. subst. simpl. simpl in IH.
+    pose (ImpR_app_list_exchL _ _ _ exch H1). destruct s. destruct p.
+    apply ImpR in i. assert (J0: dersrec_height d = dersrec_height d). reflexivity.
+    pose (dersrec_derrec_height d J0). destruct s.
+    assert (E: derrec_height x0 < S (dersrec_height d)). lia.
+    assert (E1: derrec_height x0 = derrec_height x0). auto.
+    pose (IH (derrec_height x0) E (Γ5 ++ A :: Γ6, Δ0 ++ B :: Δ1) x0 E1 x l).
+    destruct s. pose (dlCons x1 DersNil).
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x]) (Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4, Δ0 ++ A --> B :: Δ1) i d0). exists d1. simpl.
+    rewrite dersrec_height_nil. rewrite Nat.max_0_r. lia. reflexivity.
+  (* ImpL *)
+  * inversion H1. subst. inversion H5. subst. simpl. simpl in IH.
+    pose (ImpL_app_list_exchL _ _ _ _ exch H1). repeat destruct s. repeat destruct p.
+    apply ImpL in i. assert (J0: dersrec_height d = dersrec_height d). reflexivity.
+    pose (dersrec_derrec2_height d J0). repeat destruct s.
+    assert (E: derrec_height x1 < S (dersrec_height d)). lia.
+    assert (E1: derrec_height x1 = derrec_height x1). auto.
+    pose (IH (derrec_height x1) E (Γ5 ++ Γ6, Δ0 ++ A :: Δ1) x1 E1 x l0).
+    destruct s.
+    assert (E2: derrec_height x2 < S (dersrec_height d)). lia.
+    assert (E3: derrec_height x2 = derrec_height x2). auto.
+    pose (IH (derrec_height x2) E2 (Γ5 ++ B :: Γ6, Δ0 ++ Δ1) x2 E3 x0 l).
+    destruct s. pose (dlCons x4 DersNil). pose (dlCons x3 d0).
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x; x0]) (Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4, Δ0 ++ Δ1) i d1). exists d2. simpl.
+    rewrite dersrec_height_nil. rewrite Nat.max_0_r. lia. reflexivity.
+  (* KR *)
+  * inversion X. subst. inversion H5. subst. simpl. simpl in IH.
+    pose (KR_app_list_exchL _ _ _ exch X). destruct s. destruct p.
+    apply KR in k0. assert (J0: dersrec_height d = dersrec_height d). reflexivity.
+    pose (dersrec_derrec_height d J0). destruct s.
+    assert (E: derrec_height x0 < S (dersrec_height d)). lia.
+    assert (E1: derrec_height x0 = derrec_height x0). auto.
+    pose (IH (derrec_height x0) E (unboxed_list , [A]) x0 E1 x l).
+    destruct s. pose (dlCons x1 DersNil).
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x]) (Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4, Δ0 ++ Box A :: Δ1) k0 d0). exists d1. simpl.
+    rewrite dersrec_height_nil. rewrite Nat.max_0_r. lia. reflexivity.
+Qed.
+ +
+Theorem KS_hpadm_list_exch_L : forall s (D0: KS_prv s),
+        (forall se, (list_exch_L s se) ->
+        (existsT2 (D1 : KS_prv se),
+          derrec_height D1 <= derrec_height D0)).
+Proof.
+intros.
+pose (@KS_hpadm_list_exch_L0 (derrec_height D0) _ D0).
+apply s0 ; auto.
+Qed.
+ +
+Theorem KS_hpadm_list_exch_R : forall s (D0: KS_prv s),
+        (forall se, (list_exch_R s se) ->
+        (existsT2 (D1 : KS_prv se),
+          derrec_height D1 <= derrec_height D0)).
+Proof.
+intros.
+pose (@KS_hpadm_list_exch_R0 (derrec_height D0) _ D0).
+apply s0 ; auto.
+Qed.
+ +
+Theorem KS_adm_list_exch_LR : forall s (D0: KS_prv s),
+        (forall se, ((list_exch_L s se) -> (KS_prv se)) *
+                        ((list_exch_R s se) -> (KS_prv se))).
+Proof.
+intros. assert (J1: derrec_height D0 = derrec_height D0). auto. split ; intro.
+- pose (@KS_hpadm_list_exch_L0 (derrec_height D0) s D0 J1 se H). destruct s0 ; auto.
+- pose (@KS_hpadm_list_exch_R0 (derrec_height D0) s D0 J1 se H). destruct s0 ; auto.
+Qed.
+ +
+
+
+ +
+ + + diff --git a/K.KS.KS_exch_ImpL.html b/K.KS.KS_exch_ImpL.html new file mode 100644 index 0000000..d5231da --- /dev/null +++ b/K.KS.KS_exch_ImpL.html @@ -0,0 +1,589 @@ + + + + + + + + + + + + + +
+
+

K.KS.KS_exch_ImpL

+ +
+Require Import List.
+Export ListNotations.
+Require Import Lia.
+Require Import PeanoNat.
+ +
+Require Import KS_calc.
+Require Import KS_exch_prelims.
+ +
+Lemma ImpL_app_list_exchL : forall s se ps1 ps2,
+  (@list_exch_L s se) ->
+  (ImpLRule [ps1;ps2] s) ->
+  (existsT2 pse1 pse2,
+    (ImpLRule [pse1;pse2] se) *
+    (@list_exch_L ps1 pse1) *
+    (@list_exch_L ps2 pse2)).
+Proof.
+intros s se ps1 ps2 exch. intro RA. inversion RA. inversion exch. subst.
+inversion H. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
+- destruct Γ3 ; destruct Γ4 ; destruct Γ5 ; simpl ; simpl in e0 ; simpl in exch ; subst ; try inversion e0 ; subst.
+  + exists (Γ2 ++ Γ1, Δ0 ++ A :: Δ1). exists (Γ2 ++ B :: Γ1, Δ0 ++ Δ1). split. split ; try assumption.
+    apply list_exch_L_id. apply list_exch_L_id.
+  + exists (Γ2 ++ Γ5 ++ Γ6, Δ0 ++ A :: Δ1). exists (Γ2 ++ B :: Γ5 ++ Γ6, Δ0 ++ Δ1). split. split ; try assumption.
+    apply list_exch_L_id. apply list_exch_L_id.
+  + exists (Γ2 ++ Γ4 ++ Γ6, Δ0 ++ A :: Δ1). exists (Γ2 ++ B :: Γ4 ++ Γ6, Δ0 ++ Δ1). split. split ; try assumption.
+    apply list_exch_L_id. apply list_exch_L_id.
+  + exists (Γ2 ++ (m0 :: Γ5) ++ Γ4 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ2 ++ (m0 :: Γ5) ++ B :: Γ4 ++ Γ6, Δ0 ++ Δ1). split. split.
+    assert (Γ2 ++ (m0 :: Γ5) ++ B :: Γ4 ++ Γ6 = (Γ2 ++ m0 :: Γ5) ++ B :: Γ4 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ m0 :: Γ5 ++ A --> B :: Γ4 ++ Γ6 = (Γ2 ++ m0 :: Γ5) ++ A --> B :: Γ4 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ (m0 :: Γ5) ++ Γ4 ++ Γ6 = (Γ2 ++ m0 :: Γ5) ++ Γ4 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    apply ImpLRule_I.
+    assert (Γ2 ++ Γ4 ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ [] ++ Γ4 ++ (m0 :: Γ5) ++ Γ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ (m0 :: Γ5) ++ Γ4 ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ Γ4 ++ [] ++ Γ6).
+    reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ2 ++ B :: Γ4 ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ [] ++ (B :: Γ4) ++ (m0 :: Γ5) ++ Γ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ (m0 :: Γ5) ++ B :: Γ4 ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ (B :: Γ4) ++ [] ++ Γ6).
+    reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+  + exists (Γ2 ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1). exists (Γ2 ++ B :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split ; try assumption.
+    apply list_exch_L_id. apply list_exch_L_id.
+  + exists (Γ2 ++ (m0 :: Γ5) ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ2 ++ (m0 :: Γ5) ++ B :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+    assert (Γ2 ++ m0 :: Γ5 ++ A --> B :: Γ3 ++ Γ6 = (Γ2 ++ m0 :: Γ5) ++ A --> B :: Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ (m0 :: Γ5) ++ B :: Γ3 ++ Γ6 = (Γ2 ++ m0 :: Γ5) ++ B :: Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ (m0 :: Γ5) ++ Γ3 ++ Γ6 = (Γ2 ++ m0 :: Γ5) ++ Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    apply ImpLRule_I.
+    assert (Γ2 ++ Γ3 ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ [] ++ (m0 :: Γ5) ++ Γ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ (m0 :: Γ5) ++ Γ3 ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ [] ++ Γ3 ++ Γ6).
+    reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ2 ++ B :: Γ3 ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ (B :: Γ3) ++ [] ++ (m0 :: Γ5) ++ Γ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ (m0 :: Γ5) ++ B :: Γ3 ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ [] ++ (B :: Γ3) ++ Γ6).
+    reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+  + exists (Γ2 ++ m0 :: Γ4 ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ2 ++ m0 :: Γ4 ++ B :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+    assert (Γ2 ++ m0 :: Γ4 ++ A --> B :: Γ3 ++ Γ6 = (Γ2 ++ m0 :: Γ4) ++ A --> B :: Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ m0 :: Γ4 ++ B :: Γ3 ++ Γ6 = (Γ2 ++ m0 :: Γ4) ++ B :: Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ m0 :: Γ4 ++ Γ3 ++ Γ6 = (Γ2 ++ m0 :: Γ4) ++ Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+    assert (Γ2 ++ Γ3 ++ m0 :: Γ4 ++ Γ6 = Γ2 ++ Γ3 ++ [] ++ (m0 :: Γ4) ++ Γ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ m0 :: Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (m0 :: Γ4) ++ [] ++ Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ2 ++ B :: Γ3 ++ m0 :: Γ4 ++ Γ6 = Γ2 ++ (B :: Γ3) ++ [] ++ (m0 :: Γ4) ++ Γ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ m0 :: Γ4 ++ B :: Γ3 ++ Γ6 = Γ2 ++ (m0 :: Γ4) ++ [] ++ (B :: Γ3) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+  + exists (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ B :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+    assert (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ A --> B :: Γ3 ++ Γ6 = (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4) ++ A --> B :: Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ B :: Γ3 ++ Γ6 = (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4) ++ B :: Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ Γ3 ++ Γ6 = (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4) ++ Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    apply ImpLRule_I.
+    assert (Γ2 ++ Γ3 ++ m0 :: Γ4 ++ m1 :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (m0 :: Γ4) ++ (m1 :: Γ5) ++ Γ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (m1 :: Γ5) ++ (m0 :: Γ4) ++ Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ2 ++ B :: Γ3 ++ m0 :: Γ4 ++ m1 :: Γ5 ++ Γ6 = Γ2 ++ (B :: Γ3) ++ (m0 :: Γ4) ++ (m1 :: Γ5) ++ Γ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ B :: Γ3 ++ Γ6 = Γ2 ++ (m1 :: Γ5) ++ (m0 :: Γ4) ++ (B :: Γ3) ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+- apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+  + destruct Γ4 ; destruct Γ5 ; simpl ; simpl in e0 ; simpl in exch ; subst ; try inversion e0 ; subst.
+    * rewrite app_assoc. exists ((Γ2 ++ Γ3) ++ Γ1, Δ0 ++ A :: Δ1).
+      exists ((Γ2 ++ Γ3) ++ B :: Γ1, Δ0 ++ Δ1). split. split ; try assumption. apply list_exch_L_id.
+      apply list_exch_L_id.
+    * exists (Γ2 ++ Γ5 ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+      exists (Γ2 ++ B :: Γ5 ++ Γ3 ++ Γ6, Δ0 ++ Δ1). split. split. apply ImpLRule_I.
+      assert ((Γ2 ++ Γ3) ++ Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ [] ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ Γ5 ++ Γ3 ++ Γ6 = Γ2 ++ Γ5 ++ [] ++ Γ3 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+      assert ((Γ2 ++ Γ3) ++ B :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ [] ++ (B :: Γ5) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ B :: Γ5 ++ Γ3 ++ Γ6 = Γ2 ++ (B :: Γ5) ++ [] ++ Γ3 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+    * exists (Γ2 ++ Γ4 ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+      exists (Γ2 ++ B :: Γ4 ++ Γ3 ++ Γ6, Δ0 ++ Δ1). split. split. apply ImpLRule_I.
+      assert ((Γ2 ++ Γ3) ++ Γ4 ++ Γ6 = Γ2 ++ Γ3 ++ [] ++ Γ4 ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ Γ4 ++ [] ++ Γ3 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+      assert ((Γ2 ++ Γ3) ++ B :: Γ4 ++ Γ6 = Γ2 ++ Γ3 ++ [] ++ (B :: Γ4) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ B :: Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (B :: Γ4) ++ [] ++ Γ3 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+    * exists ((Γ2 ++ m0 :: Γ5) ++ Γ4 ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+      exists ((Γ2 ++ m0 :: Γ5) ++ B :: Γ4 ++ Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+      assert (Γ2 ++ m0 :: Γ5 ++ A --> B :: Γ4 ++ Γ3 ++ Γ6 = (Γ2 ++ m0 :: Γ5) ++ A --> B :: Γ4 ++ Γ3 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+      assert ((Γ2 ++ Γ3) ++ Γ4 ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ Γ4 ++ (m0 :: Γ5) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Γ2 ++ m0 :: Γ5) ++ Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ Γ4 ++ Γ3 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+      assert ((Γ2 ++ Γ3) ++ B :: Γ4 ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (B :: Γ4) ++ (m0 :: Γ5) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Γ2 ++ m0 :: Γ5) ++ B :: Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ (B :: Γ4) ++ Γ3 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+  + apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+    * destruct Γ5 ; simpl ; simpl in e0 ; simpl in exch ; subst ; try inversion e0 ; subst.
+      { exists ((Γ2 ++ Γ4 ++ Γ3) ++ Γ1, Δ0 ++ A :: Δ1).
+        exists ((Γ2 ++ Γ4 ++ Γ3) ++ B :: Γ1, Δ0 ++ Δ1). split. split.
+        assert (Γ2 ++ Γ4 ++ Γ3 ++ A --> B :: Γ1 = (Γ2 ++ Γ4 ++ Γ3) ++ A --> B :: Γ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+        assert ((Γ2 ++ Γ3 ++ Γ4) ++ Γ1 = Γ2 ++ Γ3 ++ [] ++ Γ4 ++ Γ1). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert ((Γ2 ++ Γ4 ++ Γ3) ++ Γ1 = Γ2 ++ Γ4 ++ [] ++ Γ3 ++ Γ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+        assert ((Γ2 ++ Γ3 ++ Γ4) ++ B :: Γ1 = Γ2 ++ Γ3 ++ [] ++ Γ4 ++ B :: Γ1). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert ((Γ2 ++ Γ4 ++ Γ3) ++ B :: Γ1 = Γ2 ++ Γ4 ++ [] ++ Γ3 ++ B :: Γ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI. }
+      { exists (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+        exists (Γ2 ++ B :: Γ5 ++ Γ4 ++ Γ3 ++ Γ6, Δ0 ++ Δ1). split. split. apply ImpLRule_I.
+        repeat rewrite <- app_assoc. apply list_exch_LI.
+        assert ((Γ2 ++ Γ3 ++ Γ4) ++ B :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ Γ4 ++ (B :: Γ5) ++ Γ6). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ B :: Γ5 ++ Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (B :: Γ5) ++ Γ4 ++ Γ3 ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI. }
+    * apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+      { exists ((Γ2 ++ Γ5 ++ Γ4 ++ Γ3) ++ Γ1, Δ0 ++ A :: Δ1).
+        exists ((Γ2 ++ Γ5 ++ Γ4 ++ Γ3) ++ B :: Γ1, Δ0 ++ Δ1). split. split.
+        assert (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ A --> B :: Γ1 = (Γ2 ++ Γ5 ++ Γ4 ++ Γ3) ++ A --> B :: Γ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+        repeat rewrite <- app_assoc. apply list_exch_LI. repeat rewrite <- app_assoc. apply list_exch_LI. }
+      { exists ((Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ x0) ++ Γ1, Δ0 ++ A :: Δ1).
+        exists ((Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ x0) ++ B :: Γ1, Δ0 ++ Δ1). split. split.
+        assert (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ x0 ++ A --> B :: Γ1 = (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ x0) ++ A --> B :: Γ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+        repeat rewrite <- app_assoc. apply list_exch_LI. repeat rewrite <- app_assoc. apply list_exch_LI. }
+      { destruct x0.
+        - simpl in e0. subst. rewrite app_nil_r.
+          exists ((Γ2 ++ x ++ Γ4 ++ Γ3) ++ Γ1, Δ0 ++ A :: Δ1).
+          exists ((Γ2 ++ x ++ Γ4 ++ Γ3) ++ B :: Γ1, Δ0 ++ Δ1). split. split.
+          assert (Γ2 ++ x ++ Γ4 ++ Γ3 ++ A --> B :: Γ1 = (Γ2 ++ x ++ Γ4 ++ Γ3) ++ A --> B :: Γ1).
+          repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+          repeat rewrite <- app_assoc. apply list_exch_LI. repeat rewrite <- app_assoc. apply list_exch_LI.
+        - inversion e0. subst.
+          exists ((Γ2 ++ x) ++ x0 ++ Γ4 ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+          exists ((Γ2 ++ x) ++ B :: x0 ++ Γ4 ++ Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+          assert (Γ2 ++ (x ++ A --> B :: x0) ++ Γ4 ++ Γ3 ++ Γ6 = (Γ2 ++ x) ++ A --> B :: x0 ++ Γ4 ++ Γ3 ++ Γ6).
+          repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+          assert ((Γ2 ++ Γ3 ++ Γ4 ++ x) ++ x0 ++ Γ6 = Γ2 ++ Γ3 ++ Γ4 ++ (x ++ x0) ++ Γ6).
+          repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+          assert ((Γ2 ++ x) ++ x0 ++ Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (x ++ x0) ++ Γ4 ++ Γ3 ++ Γ6).
+          repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+          apply list_exch_LI.
+          assert ((Γ2 ++ Γ3 ++ Γ4 ++ x) ++ B :: x0 ++ Γ6 = Γ2 ++ Γ3 ++ Γ4 ++ (x ++ B :: x0) ++ Γ6).
+          repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+          assert ((Γ2 ++ x) ++ B :: x0 ++ Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (x ++ B :: x0) ++ Γ4 ++ Γ3 ++ Γ6).
+          repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+          apply list_exch_LI. }
+    * destruct x ; destruct Γ5 ; simpl ; simpl in e0 ; simpl in exch ; subst ; try inversion e0 ; subst.
+      { rewrite app_nil_r. exists ((Γ2 ++ x0 ++ Γ3) ++ Γ1, Δ0 ++ A :: Δ1).
+        exists ((Γ2 ++ x0 ++ Γ3) ++ B :: Γ1, Δ0 ++ Δ1). split. split.
+        assert (Γ2 ++ x0 ++ Γ3 ++ A --> B :: Γ1 = (Γ2 ++ x0 ++ Γ3) ++ A --> B :: Γ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+        assert ((Γ2 ++ Γ3 ++ x0) ++ Γ1 = Γ2 ++ Γ3 ++ [] ++ x0 ++ Γ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert ((Γ2 ++ x0 ++ Γ3) ++ Γ1 = Γ2 ++ x0 ++ [] ++ Γ3 ++ Γ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+        assert ((Γ2 ++ Γ3 ++ x0) ++ B :: Γ1 = Γ2 ++ Γ3 ++ [] ++ x0 ++ B :: Γ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert ((Γ2 ++ x0 ++ Γ3) ++ B :: Γ1 = Γ2 ++ x0 ++ [] ++ Γ3 ++ B :: Γ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI. }
+      { rewrite app_nil_r. exists (Γ2 ++ Γ5 ++ x0 ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+        exists (Γ2 ++ B :: Γ5 ++ x0 ++ Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+        apply ImpLRule_I. repeat rewrite <- app_assoc. apply list_exch_LI.
+        assert ((Γ2 ++ Γ3 ++ x0) ++ B :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ x0 ++ (B :: Γ5) ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ B :: Γ5 ++ x0 ++ Γ3 ++ Γ6 = Γ2 ++ (B :: Γ5) ++ x0 ++ Γ3 ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI. }
+      { exists ((Γ2 ++ x0) ++ x ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+        exists ((Γ2 ++ x0) ++ B :: x ++ Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+        assert (Γ2 ++ (x0 ++ A --> B :: x) ++ Γ3 ++ Γ6 = (Γ2 ++ x0) ++ A --> B :: x ++ Γ3 ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+        assert ((Γ2 ++ Γ3 ++ x0) ++ x ++ Γ6 = Γ2 ++ Γ3 ++ [] ++ (x0 ++ x) ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert ((Γ2 ++ x0) ++ x ++ Γ3 ++ Γ6 = Γ2 ++ (x0 ++ x) ++ [] ++ Γ3 ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+        assert ((Γ2 ++ Γ3 ++ x0) ++ B :: x ++ Γ6 = Γ2 ++ Γ3 ++ [] ++ (x0 ++ B :: x) ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert ((Γ2 ++ x0) ++ B :: x ++ Γ3 ++ Γ6 = Γ2 ++ (x0 ++ B :: x) ++ [] ++ Γ3 ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI. }
+      { exists ((Γ2 ++ m0 :: Γ5 ++ x0) ++ x ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+        exists ((Γ2 ++ m0 :: Γ5 ++ x0) ++ B :: x ++ Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+        assert (Γ2 ++ m0 :: Γ5 ++ (x0 ++ A --> B :: x) ++ Γ3 ++ Γ6 = (Γ2 ++ m0 :: Γ5 ++ x0) ++ A --> B :: x ++ Γ3 ++ Γ6).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+        assert ((Γ2 ++ Γ3 ++ x0) ++ x ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (x0 ++ x) ++ (m0 :: Γ5) ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert ((Γ2 ++ m0 :: Γ5 ++ x0) ++ x ++ Γ3 ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ (x0 ++ x) ++ Γ3 ++ Γ6).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        apply list_exch_LI.
+        assert ((Γ2 ++ Γ3 ++ x0) ++ B :: x ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (x0 ++ B :: x) ++ (m0 :: Γ5) ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert ((Γ2 ++ m0 :: Γ5 ++ x0) ++ B :: x ++ Γ3 ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ (x0 ++ B :: x) ++ Γ3 ++ Γ6).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        apply list_exch_LI. }
+  + destruct x0 ; destruct Γ4 ; destruct Γ5 ; simpl ; simpl in e0 ; simpl in exch ; subst ; try inversion e0 ; subst.
+    * rewrite app_nil_r. rewrite app_assoc. exists ((Γ2 ++ x) ++ Γ1, Δ0 ++ A :: Δ1).
+      exists ((Γ2 ++ x) ++ B :: Γ1, Δ0 ++ Δ1). split. split ; try assumption. apply list_exch_L_id. apply list_exch_L_id.
+    * rewrite app_nil_r. exists (Γ2 ++ Γ5 ++ x ++ Γ6, Δ0 ++ A :: Δ1).
+      exists (Γ2 ++ B :: Γ5 ++ x ++ Γ6, Δ0 ++ Δ1). split. split. apply ImpLRule_I.
+      assert ((Γ2 ++ x) ++ Γ5 ++ Γ6 = Γ2 ++ x ++ [] ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ Γ5 ++ x ++ Γ6 = Γ2 ++ Γ5 ++ [] ++ x ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+      assert ((Γ2 ++ x) ++ B :: Γ5 ++ Γ6 = Γ2 ++ x ++ [] ++ (B :: Γ5) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ B :: Γ5 ++ x ++ Γ6 = Γ2 ++ (B :: Γ5) ++ [] ++ x ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+    * rewrite app_nil_r. exists (Γ2 ++ Γ4 ++ x ++ Γ6, Δ0 ++ A :: Δ1).
+      exists (Γ2 ++ B :: Γ4 ++ x ++ Γ6, Δ0 ++ Δ1). split. split. apply ImpLRule_I.
+      assert ((Γ2 ++ x) ++ Γ4 ++ Γ6 = Γ2 ++ x ++ [] ++ Γ4 ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ Γ4 ++ x ++ Γ6 = Γ2 ++ Γ4 ++ [] ++ x ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+      assert ((Γ2 ++ x) ++ B :: Γ4 ++ Γ6 = Γ2 ++ x ++ [] ++ (B :: Γ4) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ B :: Γ4 ++ x ++ Γ6 = Γ2 ++ (B :: Γ4) ++ [] ++ x ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+    * rewrite app_nil_r. exists ((Γ2 ++ m0 :: Γ5) ++ Γ4 ++ x ++ Γ6, Δ0 ++ A :: Δ1).
+      exists ((Γ2 ++ m0 :: Γ5) ++ B :: Γ4 ++ x ++ Γ6, Δ0 ++ Δ1). split. split.
+      assert (Γ2 ++ m0 :: Γ5 ++ A --> B :: Γ4 ++ x ++ Γ6 = (Γ2 ++ m0 :: Γ5) ++ A --> B :: Γ4 ++ x ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+      assert ((Γ2 ++ x) ++ Γ4 ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ x ++ Γ4 ++ (m0 :: Γ5) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Γ2 ++ m0 :: Γ5) ++ Γ4 ++ x ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ Γ4 ++ x ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+      assert ((Γ2 ++ x) ++ B :: Γ4 ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ x ++ (B :: Γ4) ++ (m0 :: Γ5) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Γ2 ++ m0 :: Γ5) ++ B :: Γ4 ++ x ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ (B :: Γ4) ++ x ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+    * exists ((Γ2 ++ x) ++ x0 ++ Γ6, Δ0 ++ A :: Δ1).
+      exists ((Γ2 ++ x) ++ B :: x0 ++ Γ6, Δ0 ++ Δ1). split. split.
+      assert (Γ2 ++ (x ++ A --> B :: x0) ++ Γ6 = (Γ2 ++ x) ++ A --> B :: x0 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+      apply list_exch_L_id. apply list_exch_L_id.
+    * exists ((Γ2 ++ m0 :: Γ5 ++ x) ++ x0 ++ Γ6, Δ0 ++ A :: Δ1).
+      exists ((Γ2 ++ m0 :: Γ5 ++ x) ++ B :: x0 ++ Γ6, Δ0 ++ Δ1). split. split.
+      assert (Γ2 ++ m0 :: Γ5 ++ (x ++ A --> B :: x0) ++ Γ6 = (Γ2 ++ m0 :: Γ5 ++ x) ++ A --> B :: x0 ++ Γ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+      assert ((Γ2 ++ x) ++ x0 ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ [] ++ (x ++ x0) ++ (m0 :: Γ5) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Γ2 ++ m0 :: Γ5 ++ x) ++ x0 ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ (x ++ x0) ++ [] ++ Γ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. apply list_exch_LI.
+      assert ((Γ2 ++ x) ++ B :: x0 ++ m0 :: Γ5 ++ Γ6 = Γ2 ++ [] ++ (x ++ B :: x0) ++ (m0 :: Γ5) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Γ2 ++ m0 :: Γ5 ++ x) ++ B :: x0 ++ Γ6 = Γ2 ++ (m0 :: Γ5) ++ (x ++ B :: x0) ++ [] ++ Γ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. apply list_exch_LI.
+    * exists ((Γ2 ++ m0 :: Γ4 ++ x) ++ x0 ++ Γ6, Δ0 ++ A :: Δ1).
+      exists ((Γ2 ++ m0 :: Γ4 ++ x) ++ B :: x0 ++ Γ6, Δ0 ++ Δ1). split. split.
+      assert (Γ2 ++ m0 :: Γ4 ++ (x ++ A --> B :: x0) ++ Γ6 = (Γ2 ++ m0 :: Γ4 ++ x) ++ A --> B :: x0 ++ Γ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+      assert ((Γ2 ++ x) ++ x0 ++ m0 :: Γ4 ++ Γ6 = Γ2 ++ [] ++ (x ++ x0) ++ (m0 :: Γ4) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Γ2 ++ m0 :: Γ4 ++ x) ++ x0 ++ Γ6 = Γ2 ++ (m0 :: Γ4) ++ (x ++ x0) ++ [] ++ Γ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. apply list_exch_LI.
+      assert ((Γ2 ++ x) ++ B :: x0 ++ m0 :: Γ4 ++ Γ6 = Γ2 ++ [] ++ (x ++ B :: x0) ++ (m0 :: Γ4) ++ Γ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Γ2 ++ m0 :: Γ4 ++ x) ++ B :: x0 ++ Γ6 = Γ2 ++ (m0 :: Γ4) ++ (x ++ B :: x0) ++ [] ++ Γ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. apply list_exch_LI.
+    * exists ((Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ x) ++ x0 ++ Γ6, Δ0 ++ A :: Δ1).
+      exists ((Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ x) ++ B :: x0 ++ Γ6, Δ0 ++ Δ1). split. split.
+      assert (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ (x ++ A --> B :: x0) ++ Γ6 = (Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ x) ++ A --> B :: x0 ++ Γ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. simpl.
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+      assert ((Γ2 ++ x) ++ x0 ++ m0 :: Γ4 ++ m1 :: Γ5 ++ Γ6 = Γ2 ++ (x ++ x0) ++ (m0 :: Γ4) ++ (m1 :: Γ5) ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      assert ((Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ x) ++ x0 ++ Γ6 = Γ2 ++ (m1 :: Γ5) ++ (m0 :: Γ4) ++ (x ++ x0) ++ Γ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. apply list_exch_LI.
+      assert ((Γ2 ++ x) ++ B :: x0 ++ m0 :: Γ4 ++ m1 :: Γ5 ++ Γ6 = Γ2 ++ (x ++ B :: x0) ++ (m0 :: Γ4) ++ (m1 :: Γ5) ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      assert ((Γ2 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ x) ++ B :: x0 ++ Γ6 = Γ2 ++ (m1 :: Γ5) ++ (m0 :: Γ4) ++ (x ++ B :: x0) ++ Γ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. apply list_exch_LI.
+- destruct x ; destruct Γ3 ; destruct Γ4 ; destruct Γ5 ; simpl ; simpl in e0 ; simpl in exch ;
+  subst ; try inversion e0 ; subst.
+  * rewrite app_nil_r. exists (Γ0 ++ Γ1, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: Γ1, Δ0 ++ Δ1). split. split ; try assumption.
+    apply list_exch_L_id. apply list_exch_L_id.
+  * rewrite app_nil_r. exists (Γ0 ++ Γ5 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: Γ5 ++ Γ6, Δ0 ++ Δ1). split. split ; try assumption.
+    apply list_exch_L_id. apply list_exch_L_id.
+  * rewrite app_nil_r. exists (Γ0 ++ Γ4 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: Γ4 ++ Γ6, Δ0 ++ Δ1). split. split ; try assumption.
+    apply list_exch_L_id. apply list_exch_L_id.
+  * rewrite app_nil_r. exists ((Γ0 ++ m0 :: Γ5) ++ Γ4 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists ((Γ0 ++ m0 :: Γ5) ++ B :: Γ4 ++ Γ6, Δ0 ++ Δ1). split. split.
+    assert (Γ0 ++ m0 :: Γ5 ++ A --> B :: Γ4 ++ Γ6 = (Γ0 ++ m0 :: Γ5) ++ A --> B :: Γ4 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+    assert (Γ0 ++ Γ4 ++ m0 :: Γ5 ++ Γ6 = Γ0 ++ [] ++ Γ4 ++ (m0 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert ((Γ0 ++ m0 :: Γ5) ++ Γ4 ++ Γ6 = Γ0 ++ (m0 :: Γ5) ++ Γ4 ++ [] ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ0 ++ B :: Γ4 ++ m0 :: Γ5 ++ Γ6 = Γ0 ++ [] ++ (B :: Γ4) ++ (m0 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert ((Γ0 ++ m0 :: Γ5) ++ B :: Γ4 ++ Γ6 = Γ0 ++ (m0 :: Γ5) ++ (B :: Γ4) ++ [] ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+  * rewrite app_nil_r. exists (Γ0 ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split ; try assumption.
+    apply list_exch_L_id. apply list_exch_L_id.
+  * rewrite app_nil_r. exists ((Γ0 ++ m0 :: Γ5) ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists ((Γ0 ++ m0 :: Γ5) ++ B :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+    assert (Γ0 ++ m0 :: Γ5 ++ A --> B :: Γ3 ++ Γ6 = (Γ0 ++ m0 :: Γ5) ++ A --> B :: Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+    assert (Γ0 ++ Γ3 ++ m0 :: Γ5 ++ Γ6 = Γ0 ++ [] ++ Γ3 ++ (m0 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert ((Γ0 ++ m0 :: Γ5) ++ Γ3 ++ Γ6 = Γ0 ++ (m0 :: Γ5) ++ Γ3 ++ [] ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ0 ++ B :: Γ3 ++ m0 :: Γ5 ++ Γ6 = Γ0 ++ [] ++ (B :: Γ3) ++ (m0 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert ((Γ0 ++ m0 :: Γ5) ++ B :: Γ3 ++ Γ6 = Γ0 ++ (m0 :: Γ5) ++ (B :: Γ3) ++ [] ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+  * rewrite app_nil_r. exists ((Γ0 ++ m0 :: Γ4) ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists ((Γ0 ++ m0 :: Γ4) ++ B :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+    assert (Γ0 ++ m0 :: Γ4 ++ A --> B :: Γ3 ++ Γ6 = (Γ0 ++ m0 :: Γ4) ++ A --> B :: Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+    assert ((Γ0 ++ m0 :: Γ4) ++ Γ3 ++ Γ6 = Γ0 ++ (m0 :: Γ4) ++ Γ3 ++ [] ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ Γ3 ++ m0 :: Γ4 ++ Γ6 = Γ0 ++ [] ++ Γ3 ++ (m0 :: Γ4) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+    assert ((Γ0 ++ m0 :: Γ4) ++ B :: Γ3 ++ Γ6 = Γ0 ++ (m0 :: Γ4) ++ (B :: Γ3) ++ [] ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ B :: Γ3 ++ m0 :: Γ4 ++ Γ6 = Γ0 ++ [] ++ (B :: Γ3) ++ (m0 :: Γ4) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+  * rewrite app_nil_r. exists ((Γ0 ++ m1 :: Γ5 ++ m0 :: Γ4) ++ Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists ((Γ0 ++ m1 :: Γ5 ++ m0 :: Γ4) ++ B :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+    assert (Γ0 ++ m1 :: Γ5 ++ m0 :: Γ4 ++ A --> B :: Γ3 ++ Γ6 = (Γ0 ++ m1 :: Γ5 ++ m0 :: Γ4) ++ A --> B :: Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpLRule_I.
+    assert (Γ0 ++ Γ3 ++ m0 :: Γ4 ++ m1 :: Γ5 ++ Γ6 = Γ0 ++ Γ3 ++ (m0 :: Γ4) ++ (m1 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert ((Γ0 ++ m1 :: Γ5 ++ m0 :: Γ4) ++ Γ3 ++ Γ6 = Γ0 ++ (m1 :: Γ5) ++ (m0 :: Γ4) ++ Γ3 ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ0 ++ B :: Γ3 ++ m0 :: Γ4 ++ m1 :: Γ5 ++ Γ6 = Γ0 ++ (B :: Γ3) ++ (m0 :: Γ4) ++ (m1 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert ((Γ0 ++ m1 :: Γ5 ++ m0 :: Γ4) ++ B :: Γ3 ++ Γ6 = Γ0 ++ (m1 :: Γ5) ++ (m0 :: Γ4) ++ (B :: Γ3) ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+  * exists (Γ0 ++ x ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: x ++ Γ6, Δ0 ++ Δ1). split. split. repeat rewrite <- app_assoc. apply ImpLRule_I.
+    apply list_exch_L_id. apply list_exch_L_id.
+  * exists (Γ0 ++ x ++ m0 :: Γ5 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: x ++ m0 :: Γ5 ++ Γ6, Δ0 ++ Δ1). split. split. repeat rewrite <- app_assoc. apply ImpLRule_I.
+    apply list_exch_L_id. apply list_exch_L_id.
+  * exists (Γ0 ++ x ++ m0 :: Γ4 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: x ++ m0 :: Γ4 ++ Γ6, Δ0 ++ Δ1). split. split. repeat rewrite <- app_assoc. apply ImpLRule_I.
+    apply list_exch_L_id. apply list_exch_L_id.
+  * exists (Γ0 ++ x ++ m1 :: Γ5 ++ m0 :: Γ4 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: x ++ m1 :: Γ5 ++ m0 :: Γ4 ++ Γ6, Δ0 ++ Δ1). split. split.
+    repeat rewrite <- app_assoc. apply ImpLRule_I.
+    assert (Γ0 ++ x ++ m0 :: Γ4 ++ m1 :: Γ5 ++ Γ6 = (Γ0 ++ x) ++ (m0 :: Γ4) ++ [] ++ (m1 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ x ++ m1 :: Γ5 ++ m0 :: Γ4 ++ Γ6 = (Γ0 ++ x) ++ (m1 :: Γ5) ++ [] ++ (m0 :: Γ4) ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ0 ++ B :: x ++ m0 :: Γ4 ++ m1 :: Γ5 ++ Γ6 = (Γ0 ++ B :: x) ++ (m0 :: Γ4) ++ [] ++ (m1 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ B :: x ++ m1 :: Γ5 ++ m0 :: Γ4 ++ Γ6 = (Γ0 ++ B :: x) ++ (m1 :: Γ5) ++ [] ++ (m0 :: Γ4) ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+  * exists (Γ0 ++ x ++ m0 :: Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: x ++ m0 :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split. repeat rewrite <- app_assoc. apply ImpLRule_I.
+    apply list_exch_L_id. apply list_exch_L_id.
+  * exists (Γ0 ++ x ++ m1 :: Γ5 ++ m0 :: Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: x ++ m1 :: Γ5 ++ m0 :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+    repeat rewrite <- app_assoc. apply ImpLRule_I.
+    assert (Γ0 ++ x ++ m0 :: Γ3 ++ m1 :: Γ5 ++ Γ6 = (Γ0 ++ x) ++ (m0 :: Γ3) ++ [] ++ (m1 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ x ++ m1 :: Γ5 ++ m0 :: Γ3 ++ Γ6 = (Γ0 ++ x) ++ (m1 :: Γ5) ++ [] ++ (m0 :: Γ3) ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ0 ++ B :: x ++ m0 :: Γ3 ++ m1 :: Γ5 ++ Γ6 = (Γ0 ++ B :: x) ++ (m0 :: Γ3) ++ [] ++ (m1 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ B :: x ++ m1 :: Γ5 ++ m0 :: Γ3 ++ Γ6 = (Γ0 ++ B :: x) ++ (m1 :: Γ5) ++ [] ++ (m0 :: Γ3) ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+  * exists (Γ0 ++ x ++ m1 :: Γ4 ++ m0 :: Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: x ++ m1 :: Γ4 ++ m0 :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+    repeat rewrite <- app_assoc. apply ImpLRule_I.
+    assert (Γ0 ++ x ++ m0 :: Γ3 ++ m1 :: Γ4 ++ Γ6 = (Γ0 ++ x) ++ (m0 :: Γ3) ++ [] ++ (m1 :: Γ4) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ x ++ m1 :: Γ4 ++ m0 :: Γ3 ++ Γ6 = (Γ0 ++ x) ++ (m1 :: Γ4) ++ [] ++ (m0 :: Γ3) ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ0 ++ B :: x ++ m0 :: Γ3 ++ m1 :: Γ4 ++ Γ6 = (Γ0 ++ B :: x) ++ (m0 :: Γ3) ++ [] ++ (m1 :: Γ4) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ B :: x ++ m1 :: Γ4 ++ m0 :: Γ3 ++ Γ6 = (Γ0 ++ B :: x) ++ (m1 :: Γ4) ++ [] ++ (m0 :: Γ3) ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+  * exists (Γ0 ++ x ++ m2 :: Γ5 ++ m1 :: Γ4 ++ m0 :: Γ3 ++ Γ6, Δ0 ++ A :: Δ1).
+    exists (Γ0 ++ B :: x ++ m2 :: Γ5 ++ m1 :: Γ4 ++ m0 :: Γ3 ++ Γ6, Δ0 ++ Δ1). split. split.
+    repeat rewrite <- app_assoc. apply ImpLRule_I.
+    assert (Γ0 ++ x ++ m0 :: Γ3 ++ m1 :: Γ4 ++ m2 :: Γ5 ++ Γ6 = (Γ0 ++ x) ++ (m0 :: Γ3) ++ (m1 :: Γ4) ++ (m2 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ x ++ m2 :: Γ5 ++ m1 :: Γ4 ++ m0 :: Γ3 ++ Γ6 = (Γ0 ++ x) ++ (m2 :: Γ5) ++ (m1 :: Γ4) ++ (m0 :: Γ3) ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+    assert (Γ0 ++ B :: x ++ m0 :: Γ3 ++ m1 :: Γ4 ++ m2 :: Γ5 ++ Γ6 = (Γ0 ++ B :: x) ++ (m0 :: Γ3) ++ (m1 :: Γ4) ++ (m2 :: Γ5) ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ0 ++ B :: x ++ m2 :: Γ5 ++ m1 :: Γ4 ++ m0 :: Γ3 ++ Γ6 = (Γ0 ++ B :: x) ++ (m2 :: Γ5) ++ (m1 :: Γ4) ++ (m0 :: Γ3) ++ Γ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_LI.
+Qed.
+ +
+Lemma ImpL_app_list_exchR : forall s se ps1 ps2,
+  (@list_exch_R s se) ->
+  (ImpLRule [ps1;ps2] s) ->
+  (existsT2 pse1 pse2,
+    (ImpLRule [pse1;pse2] se) *
+    (@list_exch_R ps1 pse1) *
+    (@list_exch_R ps2 pse2)).
+Proof.
+intros s se ps1 ps2 exch. intro RA. inversion RA. inversion exch. subst.
+inversion H. apply app2_find_hole in H2. destruct H2. repeat destruct s ; destruct p ; subst.
+- exists (Γ0 ++ Γ1, Δ2 ++ A :: Δ5 ++ Δ4 ++ Δ3 ++ Δ6).
+  exists (Γ0 ++ B :: Γ1, Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6). split. split. apply ImpLRule_I.
+  assert (Δ2 ++ A :: Δ3 ++ Δ4 ++ Δ5 ++ Δ6 = (Δ2 ++ [A]) ++ Δ3 ++ Δ4 ++ Δ5 ++ Δ6).
+  rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+  assert (Δ2 ++ A :: Δ5 ++ Δ4 ++ Δ3 ++ Δ6 = (Δ2 ++ [A]) ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6).
+  rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+  apply list_exch_RI.
+- apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+  + exists (Γ0 ++ Γ1, (Δ2 ++ Δ5) ++ A :: Δ4 ++ Δ3 ++ Δ6).
+    exists (Γ0 ++ B :: Γ1, Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6).
+    split. split.
+    assert (Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6 = (Δ2 ++ Δ5) ++ Δ4 ++ Δ3 ++ Δ6). rewrite app_assoc.
+    reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+    repeat rewrite <- app_assoc.
+    assert (Δ2 ++ Δ3 ++ A :: Δ4 ++ Δ5 ++ Δ6 = Δ2 ++ Δ3 ++ (A :: Δ4) ++ Δ5 ++ Δ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Δ2 ++ Δ5 ++ A :: Δ4 ++ Δ3 ++ Δ6 = Δ2 ++ Δ5 ++ (A :: Δ4) ++ Δ3 ++ Δ6).
+    reflexivity. rewrite H0. clear H0. apply list_exch_RI. apply list_exch_RI.
+  + apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+    * exists (Γ0 ++ Γ1, (Δ2 ++ Δ5 ++ Δ4) ++ A :: Δ3 ++ Δ6).
+      exists (Γ0 ++ B :: Γ1, Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6). split. split.
+      assert (Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6 = (Δ2 ++ Δ5 ++ Δ4) ++ Δ3 ++ Δ6). repeat rewrite app_assoc.
+      reflexivity. rewrite H0. clear H0. apply ImpLRule_I. repeat rewrite <- app_assoc.
+      assert (Δ2 ++ Δ3 ++ Δ4 ++ A :: Δ5 ++ Δ6 = Δ2 ++ Δ3 ++ (Δ4 ++ [A]) ++ Δ5 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      assert (Δ2 ++ Δ5 ++ Δ4 ++ A :: Δ3 ++ Δ6 = Δ2 ++ Δ5 ++ (Δ4 ++ [A]) ++ Δ3 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI. apply list_exch_RI.
+    * apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+      { repeat rewrite <- app_assoc. exists (Γ0 ++ Γ1, Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ A :: Δ6).
+        exists (Γ0 ++ B :: Γ1, Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6).
+        split. split. repeat rewrite app_assoc. apply ImpLRule_I. apply list_exch_RI.
+        apply list_exch_RI. }
+      { repeat rewrite <- app_assoc. exists (Γ0 ++ Γ1, Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ x0 ++ A :: Δ1).
+        exists (Γ0 ++ B :: Γ1, Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ x0 ++ Δ1). split. split. repeat rewrite app_assoc.
+        apply ImpLRule_I. apply list_exch_RI. apply list_exch_RI. }
+      { repeat rewrite <- app_assoc. exists (Γ0 ++ Γ1, Δ2 ++ (x ++ A :: x0) ++ Δ4 ++ Δ3 ++ Δ6).
+        exists (Γ0 ++ B :: Γ1, Δ2 ++ x ++ x0 ++ Δ4 ++ Δ3 ++ Δ6). split. split.
+        assert (Δ2 ++ (x ++ A :: x0) ++ Δ4 ++ Δ3 ++ Δ6 = (Δ2 ++ x) ++ A :: x0 ++ Δ4 ++ Δ3 ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Δ2 ++ x ++ x0 ++ Δ4 ++ Δ3 ++ Δ6 = (Δ2 ++ x) ++ x0 ++ Δ4 ++ Δ3 ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        apply ImpLRule_I.
+        assert (Δ2 ++ Δ3 ++ Δ4 ++ x ++ A :: x0 ++ Δ6 = Δ2 ++ Δ3 ++ Δ4 ++ (x ++ A :: x0) ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply list_exch_RI.
+        assert (Δ2 ++ Δ3 ++ Δ4 ++ x ++ x0 ++ Δ6 = Δ2 ++ Δ3 ++ Δ4 ++ (x ++ x0) ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Δ2 ++ x ++ x0 ++ Δ4 ++ Δ3 ++ Δ6 = Δ2 ++ (x ++ x0) ++ Δ4 ++ Δ3 ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply list_exch_RI. }
+    * repeat rewrite <- app_assoc. exists (Γ0 ++ Γ1, Δ2 ++ Δ5 ++ (x0 ++ A :: x) ++ Δ3 ++ Δ6).
+      exists (Γ0 ++ B :: Γ1, Δ2 ++ Δ5 ++ (x0 ++ x) ++ Δ3 ++ Δ6). split. split.
+      assert (Δ2 ++ Δ5 ++ (x0 ++ A :: x) ++ Δ3 ++ Δ6 = (Δ2 ++ Δ5 ++ x0) ++ A :: x ++ Δ3 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      assert (Δ2 ++ Δ5 ++ x0 ++ x ++ Δ3 ++ Δ6 = (Δ2 ++ Δ5 ++ x0) ++ x ++ Δ3 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      assert (Δ2 ++ Δ5 ++ (x0 ++ x) ++ Δ3 ++ Δ6 = (Δ2 ++ Δ5 ++ x0) ++ x ++ Δ3 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      apply ImpLRule_I.
+      assert (Δ2 ++ Δ3 ++ x0 ++ A :: x ++ Δ5 ++ Δ6 = Δ2 ++ Δ3 ++ (x0 ++ A :: x) ++ Δ5 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply list_exch_RI.
+      assert (Δ2 ++ Δ3 ++ x0 ++ x ++ Δ5 ++ Δ6 = Δ2 ++ Δ3 ++ (x0 ++ x) ++ Δ5 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply list_exch_RI.
+  + repeat rewrite <- app_assoc. exists (Γ0 ++ Γ1, Δ2 ++ Δ5 ++ Δ4 ++ (x ++ A :: x0) ++ Δ6).
+    exists (Γ0 ++ B :: Γ1, Δ2 ++ Δ5 ++ Δ4 ++ (x ++ x0) ++ Δ6). split. split.
+    assert (Δ2 ++ Δ5 ++ Δ4 ++ (x ++ A :: x0) ++ Δ6 = (Δ2 ++ Δ5 ++ Δ4 ++ x) ++ A :: x0 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Δ2 ++ Δ5 ++ Δ4 ++ x ++ x0 ++ Δ6 = (Δ2 ++ Δ5 ++ Δ4 ++ x) ++ x0 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Δ2 ++ Δ5 ++ Δ4 ++ (x ++ x0) ++ Δ6 = (Δ2 ++ Δ5 ++ Δ4 ++ x) ++ x0 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    apply ImpLRule_I.
+    assert (Δ2 ++ x ++ A :: x0 ++ Δ4 ++ Δ5 ++ Δ6 = Δ2 ++ (x ++ A :: x0) ++ Δ4 ++ Δ5 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply list_exch_RI.
+    assert (Δ2 ++ x ++ x0 ++ Δ4 ++ Δ5 ++ Δ6 = Δ2 ++ (x ++ x0) ++ Δ4 ++ Δ5 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply list_exch_RI.
+- repeat rewrite <- app_assoc. exists (Γ0 ++ Γ1, Δ0 ++ A :: x ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6).
+  exists (Γ0 ++ B :: Γ1, Δ0 ++ x ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6). split. split. apply ImpLRule_I.
+  assert (Δ0 ++ A :: x ++ Δ3 ++ Δ4 ++ Δ5 ++ Δ6 = (Δ0 ++ A :: x) ++ Δ3 ++ Δ4 ++ Δ5 ++ Δ6).
+  repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+  assert (Δ0 ++ A :: x ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6 = (Δ0 ++ A :: x) ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6).
+  repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+  assert (Δ0 ++ x ++ Δ3 ++ Δ4 ++ Δ5 ++ Δ6 = (Δ0 ++ x) ++ Δ3 ++ Δ4 ++ Δ5 ++ Δ6).
+  repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+  assert (Δ0 ++ x ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6 = (Δ0 ++ x) ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6).
+  repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+Qed.
+
+
+ +
+ + + diff --git a/K.KS.KS_exch_ImpR.html b/K.KS.KS_exch_ImpR.html new file mode 100644 index 0000000..aa2d605 --- /dev/null +++ b/K.KS.KS_exch_ImpR.html @@ -0,0 +1,385 @@ + + + + + + + + + + + + + +
+
+

K.KS.KS_exch_ImpR

+ +
+Require Import List.
+Export ListNotations.
+Require Import Lia.
+Require Import PeanoNat.
+ +
+Require Import KS_calc.
+Require Import KS_exch_prelims.
+ +
+(* The following lemmas make sure that if a rule is applied on a sequent s with
+premises ps, then the same rule is applicable on a sequent se which is an exchanged
+version of s, with some premises pse that are such that they are exchanged versions
+of ps. *)

+ +
+Lemma ImpR_app_list_exchL : forall s se ps,
+  (@list_exch_L s se) ->
+  (ImpRRule [ps] s) ->
+  (existsT2 pse,
+    (ImpRRule [pse] se) *
+    (@list_exch_L ps pse)).
+Proof.
+intros s se ps exch. intro RA. inversion RA. inversion exch. subst.
+inversion H. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
+- exists (Γ2 ++ A :: Γ5 ++ Γ4 ++ Γ3 ++ Γ6, Δ0 ++ B :: Δ1). split.
+  apply ImpRRule_I. assert (Γ2 ++ A :: Γ3 ++ Γ4 ++ Γ5 ++ Γ6 = (Γ2 ++ [A]) ++ Γ3 ++ Γ4 ++ Γ5 ++ Γ6).
+  rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+  assert (Γ2 ++ A :: Γ5 ++ Γ4 ++ Γ3 ++ Γ6 = (Γ2 ++ [A]) ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6).
+  rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+- apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+  + exists ((Γ2 ++ Γ5) ++ A :: Γ4 ++ Γ3 ++ Γ6, Δ0 ++ B :: Δ1). split.
+    assert (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6 = (Γ2 ++ Γ5) ++ Γ4 ++ Γ3 ++ Γ6). rewrite app_assoc.
+    reflexivity. rewrite H0. clear H0. apply ImpRRule_I. repeat rewrite <- app_assoc.
+    assert (Γ2 ++ Γ3 ++ A :: Γ4 ++ Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (A :: Γ4) ++ Γ5 ++ Γ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ Γ5 ++ A :: Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ Γ5 ++ (A :: Γ4) ++ Γ3 ++ Γ6).
+    reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+  + apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+    * exists ((Γ2 ++ Γ5 ++ Γ4) ++ A :: Γ3 ++ Γ6, Δ0 ++ B :: Δ1). split.
+      assert (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6 = (Γ2 ++ Γ5 ++ Γ4) ++ Γ3 ++ Γ6). repeat rewrite app_assoc.
+      reflexivity. rewrite H0. clear H0. apply ImpRRule_I. repeat rewrite <- app_assoc.
+      assert (Γ2 ++ Γ3 ++ Γ4 ++ A :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (Γ4 ++ [A]) ++ Γ5 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ Γ5 ++ Γ4 ++ A :: Γ3 ++ Γ6 = Γ2 ++ Γ5 ++ (Γ4 ++ [A]) ++ Γ3 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+    * apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+      { repeat rewrite <- app_assoc. exists (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ A :: Γ6, Δ0 ++ B :: Δ1).
+        split. repeat rewrite app_assoc. apply ImpRRule_I. apply list_exch_LI. }
+      { repeat rewrite <- app_assoc. exists (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ x0 ++ A :: Γ1, Δ0 ++ B :: Δ1).
+        split. repeat rewrite app_assoc. apply ImpRRule_I. apply list_exch_LI. }
+      { repeat rewrite <- app_assoc. exists (Γ2 ++ (x ++ A :: x0) ++ Γ4 ++ Γ3 ++ Γ6, Δ0 ++ B :: Δ1).
+        split. assert (Γ2 ++ (x ++ A :: x0) ++ Γ4 ++ Γ3 ++ Γ6 = (Γ2 ++ x) ++ A :: x0 ++ Γ4 ++ Γ3 ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ x ++ x0 ++ Γ4 ++ Γ3 ++ Γ6 = (Γ2 ++ x) ++ x0 ++ Γ4 ++ Γ3 ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        apply ImpRRule_I.
+        assert (Γ2 ++ Γ3 ++ Γ4 ++ x ++ A :: x0 ++ Γ6 = Γ2 ++ Γ3 ++ Γ4 ++ (x ++ A :: x0) ++ Γ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply list_exch_LI. }
+    * repeat rewrite <- app_assoc. exists (Γ2 ++ Γ5 ++ (x0 ++ A :: x) ++ Γ3 ++ Γ6, Δ0 ++ B :: Δ1).
+      split. assert (Γ2 ++ Γ5 ++ (x0 ++ A :: x) ++ Γ3 ++ Γ6 = (Γ2 ++ Γ5 ++ x0) ++ A :: x ++ Γ3 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ Γ5 ++ x0 ++ x ++ Γ3 ++ Γ6 = (Γ2 ++ Γ5 ++ x0) ++ x ++ Γ3 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      apply ImpRRule_I.
+      assert (Γ2 ++ Γ3 ++ x0 ++ A :: x ++ Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (x0 ++ A :: x) ++ Γ5 ++ Γ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply list_exch_LI.
+  + repeat rewrite <- app_assoc. exists (Γ2 ++ Γ5 ++ Γ4 ++ (x ++ A :: x0) ++ Γ6, Δ0 ++ B :: Δ1).
+    split. assert (Γ2 ++ Γ5 ++ Γ4 ++ (x ++ A :: x0) ++ Γ6 = (Γ2 ++ Γ5 ++ Γ4 ++ x) ++ A :: x0 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Γ2 ++ Γ5 ++ Γ4 ++ x ++ x0 ++ Γ6 = (Γ2 ++ Γ5 ++ Γ4 ++ x) ++ x0 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    apply ImpRRule_I.
+    assert (Γ2 ++ x ++ A :: x0 ++ Γ4 ++ Γ5 ++ Γ6 = Γ2 ++ (x ++ A :: x0) ++ Γ4 ++ Γ5 ++ Γ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply list_exch_LI.
+- repeat rewrite <- app_assoc. exists (Γ0 ++ A :: x ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6, Δ0 ++ B :: Δ1).
+  split. apply ImpRRule_I.
+  assert (Γ0 ++ A :: x ++ Γ3 ++ Γ4 ++ Γ5 ++ Γ6 = (Γ0 ++ A :: x) ++ Γ3 ++ Γ4 ++ Γ5 ++ Γ6).
+  repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+  assert (Γ0 ++ A :: x ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6 = (Γ0 ++ A :: x) ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6).
+  repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_LI.
+Qed.
+ +
+Lemma ImpR_app_list_exchR : forall s se ps,
+  (@list_exch_R s se) ->
+  (ImpRRule [ps] s) ->
+  (existsT2 pse,
+    (ImpRRule [pse] se) *
+    (@list_exch_R ps pse)).
+Proof.
+intros s se ps exch. intro RA. inversion RA. inversion exch. subst.
+inversion H. apply app2_find_hole in H2. destruct H2. repeat destruct s ; destruct p ; subst.
+- destruct Δ3 ; destruct Δ4 ; destruct Δ5 ; simpl ; simpl in e0 ; simpl in exch ; subst ; try inversion e0 ; subst.
+  + exists (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ1). split ; try assumption. apply list_exch_R_id.
+  + exists (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ5 ++ Δ6). split ; try assumption. apply list_exch_R_id.
+  + exists (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ4 ++ Δ6). split ; try assumption. apply list_exch_R_id.
+  + exists (Γ0 ++ A :: Γ1, Δ2 ++ (m0 :: Δ5) ++ B :: Δ4 ++ Δ6). split.
+    assert (Δ2 ++ (m0 :: Δ5) ++ B :: Δ4 ++ Δ6 = (Δ2 ++ m0 :: Δ5) ++ B :: Δ4 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Δ2 ++ m0 :: Δ5 ++ A --> B :: Δ4 ++ Δ6 = (Δ2 ++ m0 :: Δ5) ++ A --> B :: Δ4 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    apply ImpRRule_I. assert (Δ2 ++ B :: Δ4 ++ m0 :: Δ5 ++ Δ6 = Δ2 ++ [] ++ (B :: Δ4) ++ (m0 :: Δ5) ++ Δ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Δ2 ++ (m0 :: Δ5) ++ B :: Δ4 ++ Δ6 = Δ2 ++ (m0 :: Δ5) ++ (B :: Δ4) ++ [] ++ Δ6).
+    reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+  + exists (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ3 ++ Δ6). split ; try assumption. apply list_exch_R_id.
+  + exists (Γ0 ++ A :: Γ1, Δ2 ++ (m0 :: Δ5) ++ B :: Δ3 ++ Δ6). split.
+    assert (Δ2 ++ m0 :: Δ5 ++ A --> B :: Δ3 ++ Δ6 = (Δ2 ++ m0 :: Δ5) ++ A --> B :: Δ3 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Δ2 ++ (m0 :: Δ5) ++ B :: Δ3 ++ Δ6 = (Δ2 ++ m0 :: Δ5) ++ B :: Δ3 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    apply ImpRRule_I. assert (Δ2 ++ B :: Δ3 ++ m0 :: Δ5 ++ Δ6 = Δ2 ++ (B :: Δ3) ++ [] ++ (m0 :: Δ5) ++ Δ6).
+    reflexivity. rewrite H0. clear H0.
+    assert (Δ2 ++ (m0 :: Δ5) ++ B :: Δ3 ++ Δ6 = Δ2 ++ (m0 :: Δ5) ++ [] ++ (B :: Δ3) ++ Δ6).
+    reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+  + exists (Γ0 ++ A :: Γ1, (Δ2 ++ m0 :: Δ4) ++ B :: Δ3 ++ Δ6). split.
+    assert (Δ2 ++ m0 :: Δ4 ++ A --> B :: Δ3 ++ Δ6 = (Δ2 ++ m0 :: Δ4) ++ A --> B :: Δ3 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+    assert (Δ2 ++ B :: Δ3 ++ m0 :: Δ4 ++ Δ6 = Δ2 ++ (B :: Δ3) ++ [] ++ (m0 :: Δ4) ++ Δ6).
+    reflexivity. rewrite H0. clear H0.
+    assert ((Δ2 ++ m0 :: Δ4) ++ B :: Δ3 ++ Δ6 = Δ2 ++ (m0 :: Δ4) ++ [] ++ (B :: Δ3) ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+  + exists (Γ0 ++ A :: Γ1, (Δ2 ++ m1 :: Δ5 ++ m0 :: Δ4) ++ B :: Δ3 ++ Δ6). split.
+    assert (Δ2 ++ m1 :: Δ5 ++ m0 :: Δ4 ++ A --> B :: Δ3 ++ Δ6 = (Δ2 ++ m1 :: Δ5 ++ m0 :: Δ4) ++ A --> B :: Δ3 ++ Δ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+    assert (Δ2 ++ B :: Δ3 ++ m0 :: Δ4 ++ m1 :: Δ5 ++ Δ6 = Δ2 ++ (B :: Δ3) ++ (m0 :: Δ4) ++ (m1 :: Δ5) ++ Δ6).
+    reflexivity. rewrite H0. clear H0.
+    assert ((Δ2 ++ m1 :: Δ5 ++ m0 :: Δ4) ++ B :: Δ3 ++ Δ6 = Δ2 ++ (m1 :: Δ5) ++ (m0 :: Δ4) ++ (B :: Δ3) ++ Δ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+- apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+  + destruct Δ4 ; destruct Δ5 ; simpl ; simpl in e0 ; simpl in exch ; subst ; try inversion e0 ; subst.
+    * rewrite app_assoc. exists (Γ0 ++ A :: Γ1, (Δ2 ++ Δ3) ++ B :: Δ1). split ; try assumption. apply list_exch_R_id.
+    * exists (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ5 ++ Δ3 ++ Δ6). split. apply ImpRRule_I.
+      assert ((Δ2 ++ Δ3) ++ B :: Δ5 ++ Δ6 = Δ2 ++ Δ3 ++ [] ++ (B :: Δ5) ++ Δ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Δ2 ++ B :: Δ5 ++ Δ3 ++ Δ6 = Δ2 ++ (B :: Δ5) ++ [] ++ Δ3 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+    * exists (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ4 ++ Δ3 ++ Δ6). split. apply ImpRRule_I.
+      assert ((Δ2 ++ Δ3) ++ B :: Δ4 ++ Δ6 = Δ2 ++ Δ3 ++ [] ++ (B :: Δ4) ++ Δ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Δ2 ++ B :: Δ4 ++ Δ3 ++ Δ6 = Δ2 ++ (B :: Δ4) ++ [] ++ Δ3 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+    * exists (Γ0 ++ A :: Γ1, (Δ2 ++ m0 :: Δ5) ++ B :: Δ4 ++ Δ3 ++ Δ6). split.
+      assert (Δ2 ++ m0 :: Δ5 ++ A --> B :: Δ4 ++ Δ3 ++ Δ6 = (Δ2 ++ m0 :: Δ5) ++ A --> B :: Δ4 ++ Δ3 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+      assert ((Δ2 ++ Δ3) ++ B :: Δ4 ++ m0 :: Δ5 ++ Δ6 = Δ2 ++ Δ3 ++ (B :: Δ4) ++ (m0 :: Δ5) ++ Δ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Δ2 ++ m0 :: Δ5) ++ B :: Δ4 ++ Δ3 ++ Δ6 = Δ2 ++ (m0 :: Δ5) ++ (B :: Δ4) ++ Δ3 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+  + apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+    * destruct Δ5 ; simpl ; simpl in e0 ; simpl in exch ; subst ; try inversion e0 ; subst.
+      { exists (Γ0 ++ A :: Γ1, (Δ2 ++ Δ4 ++ Δ3) ++ B :: Δ1). split.
+        assert (Δ2 ++ Δ4 ++ Δ3 ++ A --> B :: Δ1 = (Δ2 ++ Δ4 ++ Δ3) ++ A --> B :: Δ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+        assert ((Δ2 ++ Δ3 ++ Δ4) ++ B :: Δ1 = Δ2 ++ Δ3 ++ [] ++ Δ4 ++ B :: Δ1). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert ((Δ2 ++ Δ4 ++ Δ3) ++ B :: Δ1 = Δ2 ++ Δ4 ++ [] ++ Δ3 ++ B :: Δ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI. }
+      { exists (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ5 ++ Δ4 ++ Δ3 ++ Δ6). split. apply ImpRRule_I.
+        assert ((Δ2 ++ Δ3 ++ Δ4) ++ B :: Δ5 ++ Δ6 = Δ2 ++ Δ3 ++ Δ4 ++ (B :: Δ5) ++ Δ6). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Δ2 ++ B :: Δ5 ++ Δ4 ++ Δ3 ++ Δ6 = Δ2 ++ (B :: Δ5) ++ Δ4 ++ Δ3 ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI. }
+    * apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+      { exists (Γ0 ++ A :: Γ1, (Δ2 ++ Δ5 ++ Δ4 ++ Δ3) ++ B :: Δ1). split.
+        assert (Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ A --> B :: Δ1 = (Δ2 ++ Δ5 ++ Δ4 ++ Δ3) ++ A --> B :: Δ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+        repeat rewrite <- app_assoc. apply list_exch_RI. }
+      { exists (Γ0 ++ A :: Γ1, (Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ x0) ++ B :: Δ1). split.
+        assert (Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ x0 ++ A --> B :: Δ1 = (Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ x0) ++ A --> B :: Δ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+        repeat rewrite <- app_assoc. apply list_exch_RI. }
+      { destruct x0.
+        - simpl in e0. subst. rewrite app_nil_r.
+          exists (Γ0 ++ A :: Γ1, (Δ2 ++ x ++ Δ4 ++ Δ3) ++ B :: Δ1). split.
+          assert (Δ2 ++ x ++ Δ4 ++ Δ3 ++ A --> B :: Δ1 = (Δ2 ++ x ++ Δ4 ++ Δ3) ++ A --> B :: Δ1).
+          repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+          repeat rewrite <- app_assoc. apply list_exch_RI.
+        - inversion e0. subst.
+          exists (Γ0 ++ A :: Γ1, (Δ2 ++ x) ++ B :: x0 ++ Δ4 ++ Δ3 ++ Δ6). split.
+          assert (Δ2 ++ (x ++ A --> B :: x0) ++ Δ4 ++ Δ3 ++ Δ6 = (Δ2 ++ x) ++ A --> B :: x0 ++ Δ4 ++ Δ3 ++ Δ6).
+          repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+          assert ((Δ2 ++ Δ3 ++ Δ4 ++ x) ++ B :: x0 ++ Δ6 = Δ2 ++ Δ3 ++ Δ4 ++ (x ++ B :: x0) ++ Δ6).
+          repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+          assert ((Δ2 ++ x) ++ B :: x0 ++ Δ4 ++ Δ3 ++ Δ6 = Δ2 ++ (x ++ B :: x0) ++ Δ4 ++ Δ3 ++ Δ6).
+          repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+          apply list_exch_RI. }
+    * destruct x ; destruct Δ5 ; simpl ; simpl in e0 ; simpl in exch ; subst ; try inversion e0 ; subst.
+      { rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, (Δ2 ++ x0 ++ Δ3) ++ B :: Δ1). split.
+        assert (Δ2 ++ x0 ++ Δ3 ++ A --> B :: Δ1 = (Δ2 ++ x0 ++ Δ3) ++ A --> B :: Δ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+        assert ((Δ2 ++ Δ3 ++ x0) ++ B :: Δ1 = Δ2 ++ Δ3 ++ [] ++ x0 ++ B :: Δ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert ((Δ2 ++ x0 ++ Δ3) ++ B :: Δ1 = Δ2 ++ x0 ++ [] ++ Δ3 ++ B :: Δ1).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI. }
+      { rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ5 ++ x0 ++ Δ3 ++ Δ6). split.
+        apply ImpRRule_I.
+        assert ((Δ2 ++ Δ3 ++ x0) ++ B :: Δ5 ++ Δ6 = Δ2 ++ Δ3 ++ x0 ++ (B :: Δ5) ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Δ2 ++ B :: Δ5 ++ x0 ++ Δ3 ++ Δ6 = Δ2 ++ (B :: Δ5) ++ x0 ++ Δ3 ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI. }
+      { exists (Γ0 ++ A :: Γ1, (Δ2 ++ x0) ++ B :: x ++ Δ3 ++ Δ6). split.
+        assert (Δ2 ++ (x0 ++ A --> B :: x) ++ Δ3 ++ Δ6 = (Δ2 ++ x0) ++ A --> B :: x ++ Δ3 ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+        assert ((Δ2 ++ Δ3 ++ x0) ++ B :: x ++ Δ6 = Δ2 ++ Δ3 ++ [] ++ (x0 ++ B :: x) ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert ((Δ2 ++ x0) ++ B :: x ++ Δ3 ++ Δ6 = Δ2 ++ (x0 ++ B :: x) ++ [] ++ Δ3 ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI. }
+      { exists (Γ0 ++ A :: Γ1, (Δ2 ++ m0 :: Δ5 ++ x0) ++ B :: x ++ Δ3 ++ Δ6). split.
+        assert (Δ2 ++ m0 :: Δ5 ++ (x0 ++ A --> B :: x) ++ Δ3 ++ Δ6 = (Δ2 ++ m0 :: Δ5 ++ x0) ++ A --> B :: x ++ Δ3 ++ Δ6).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+        assert ((Δ2 ++ Δ3 ++ x0) ++ B :: x ++ m0 :: Δ5 ++ Δ6 = Δ2 ++ Δ3 ++ (x0 ++ B :: x) ++ (m0 :: Δ5) ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert ((Δ2 ++ m0 :: Δ5 ++ x0) ++ B :: x ++ Δ3 ++ Δ6 = Δ2 ++ (m0 :: Δ5) ++ (x0 ++ B :: x) ++ Δ3 ++ Δ6).
+        repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        apply list_exch_RI. }
+  + destruct x0 ; destruct Δ4 ; destruct Δ5 ; simpl ; simpl in e0 ; simpl in exch ; subst ; try inversion e0 ; subst.
+    * rewrite app_nil_r. rewrite app_assoc. exists (Γ0 ++ A :: Γ1, (Δ2 ++ x) ++ B :: Δ1). split ; try assumption. apply list_exch_R_id.
+    * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ5 ++ x ++ Δ6). split. apply ImpRRule_I.
+      assert ((Δ2 ++ x) ++ B :: Δ5 ++ Δ6 = Δ2 ++ x ++ [] ++ (B :: Δ5) ++ Δ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Δ2 ++ B :: Δ5 ++ x ++ Δ6 = Δ2 ++ (B :: Δ5) ++ [] ++ x ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+    * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, Δ2 ++ B :: Δ4 ++ x ++ Δ6). split. apply ImpRRule_I.
+      assert ((Δ2 ++ x) ++ B :: Δ4 ++ Δ6 = Δ2 ++ x ++ [] ++ (B :: Δ4) ++ Δ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert (Δ2 ++ B :: Δ4 ++ x ++ Δ6 = Δ2 ++ (B :: Δ4) ++ [] ++ x ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+    * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, (Δ2 ++ m0 :: Δ5) ++ B :: Δ4 ++ x ++ Δ6). split.
+      assert (Δ2 ++ m0 :: Δ5 ++ A --> B :: Δ4 ++ x ++ Δ6 = (Δ2 ++ m0 :: Δ5) ++ A --> B :: Δ4 ++ x ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpRRule_I.
+      assert ((Δ2 ++ x) ++ B :: Δ4 ++ m0 :: Δ5 ++ Δ6 = Δ2 ++ x ++ (B :: Δ4) ++ (m0 :: Δ5) ++ Δ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Δ2 ++ m0 :: Δ5) ++ B :: Δ4 ++ x ++ Δ6 = Δ2 ++ (m0 :: Δ5) ++ (B :: Δ4) ++ x ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0. apply list_exch_RI.
+    * exists (Γ0 ++ A :: Γ1, (Δ2 ++ x) ++ B :: x0 ++ Δ6). split.
+      assert (Δ2 ++ (x ++ A --> B :: x0) ++ Δ6 = (Δ2 ++ x) ++ A --> B :: x0 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpRRule_I.
+      apply list_exch_R_id.
+    * exists (Γ0 ++ A :: Γ1, (Δ2 ++ m0 :: Δ5 ++ x) ++ B :: x0 ++ Δ6). split.
+      assert (Δ2 ++ m0 :: Δ5 ++ (x ++ A --> B :: x0) ++ Δ6 = (Δ2 ++ m0 :: Δ5 ++ x) ++ A --> B :: x0 ++ Δ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpRRule_I.
+      assert ((Δ2 ++ x) ++ B :: x0 ++ m0 :: Δ5 ++ Δ6 = Δ2 ++ [] ++ (x ++ B :: x0) ++ (m0 :: Δ5) ++ Δ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Δ2 ++ m0 :: Δ5 ++ x) ++ B :: x0 ++ Δ6 = Δ2 ++ (m0 :: Δ5) ++ (x ++ B :: x0) ++ [] ++ Δ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. apply list_exch_RI.
+    * exists (Γ0 ++ A :: Γ1, (Δ2 ++ m0 :: Δ4 ++ x) ++ B :: x0 ++ Δ6). split.
+      assert (Δ2 ++ m0 :: Δ4 ++ (x ++ A --> B :: x0) ++ Δ6 = (Δ2 ++ m0 :: Δ4 ++ x) ++ A --> B :: x0 ++ Δ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpRRule_I.
+      assert ((Δ2 ++ x) ++ B :: x0 ++ m0 :: Δ4 ++ Δ6 = Δ2 ++ [] ++ (x ++ B :: x0) ++ (m0 :: Δ4) ++ Δ6). repeat rewrite <- app_assoc.
+      reflexivity. rewrite H0. clear H0.
+      assert ((Δ2 ++ m0 :: Δ4 ++ x) ++ B :: x0 ++ Δ6 = Δ2 ++ (m0 :: Δ4) ++ (x ++ B :: x0) ++ [] ++ Δ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. apply list_exch_RI.
+    * exists (Γ0 ++ A :: Γ1, (Δ2 ++ m1 :: Δ5 ++ m0 :: Δ4 ++ x) ++ B :: x0 ++ Δ6). split.
+      assert (Δ2 ++ m1 :: Δ5 ++ m0 :: Δ4 ++ (x ++ A --> B :: x0) ++ Δ6 = (Δ2 ++ m1 :: Δ5 ++ m0 :: Δ4 ++ x) ++ A --> B :: x0 ++ Δ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. simpl.
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpRRule_I.
+      assert ((Δ2 ++ x) ++ B :: x0 ++ m0 :: Δ4 ++ m1 :: Δ5 ++ Δ6 = Δ2 ++ (x ++ B :: x0) ++ (m0 :: Δ4) ++ (m1 :: Δ5) ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      assert ((Δ2 ++ m1 :: Δ5 ++ m0 :: Δ4 ++ x) ++ B :: x0 ++ Δ6 = Δ2 ++ (m1 :: Δ5) ++ (m0 :: Δ4) ++ (x ++ B :: x0) ++ Δ6).
+      repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. apply list_exch_RI.
+- destruct x ; destruct Δ3 ; destruct Δ4 ; destruct Δ5 ; simpl ; simpl in e0 ; simpl in exch ;
+  subst ; try inversion e0 ; subst.
+  * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1). split ; try assumption.
+    apply list_exch_R_id.
+  * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ5 ++ Δ6). split ; try assumption.
+    apply list_exch_R_id.
+  * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ4 ++ Δ6). split ; try assumption.
+    apply list_exch_R_id.
+  * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, (Δ0 ++ m0 :: Δ5) ++ B :: Δ4 ++ Δ6). split.
+    assert (Δ0 ++ m0 :: Δ5 ++ A --> B :: Δ4 ++ Δ6 = (Δ0 ++ m0 :: Δ5) ++ A --> B :: Δ4 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpRRule_I.
+    assert (Δ0 ++ B :: Δ4 ++ m0 :: Δ5 ++ Δ6 = Δ0 ++ [] ++ (B :: Δ4) ++ (m0 :: Δ5) ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert ((Δ0 ++ m0 :: Δ5) ++ B :: Δ4 ++ Δ6 = Δ0 ++ (m0 :: Δ5) ++ (B :: Δ4) ++ [] ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_RI.
+  * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ3 ++ Δ6). split ; try assumption.
+    apply list_exch_R_id.
+  * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, (Δ0 ++ m0 :: Δ5) ++ B :: Δ3 ++ Δ6). split.
+    assert (Δ0 ++ m0 :: Δ5 ++ A --> B :: Δ3 ++ Δ6 = (Δ0 ++ m0 :: Δ5) ++ A --> B :: Δ3 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpRRule_I.
+    assert (Δ0 ++ B :: Δ3 ++ m0 :: Δ5 ++ Δ6 = Δ0 ++ [] ++ (B :: Δ3) ++ (m0 :: Δ5) ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert ((Δ0 ++ m0 :: Δ5) ++ B :: Δ3 ++ Δ6 = Δ0 ++ (m0 :: Δ5) ++ (B :: Δ3) ++ [] ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_RI.
+  * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, (Δ0 ++ m0 :: Δ4) ++ B :: Δ3 ++ Δ6). split.
+    assert (Δ0 ++ m0 :: Δ4 ++ A --> B :: Δ3 ++ Δ6 = (Δ0 ++ m0 :: Δ4) ++ A --> B :: Δ3 ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpRRule_I.
+    assert ((Δ0 ++ m0 :: Δ4) ++ B :: Δ3 ++ Δ6 = Δ0 ++ (m0 :: Δ4) ++ (B :: Δ3) ++ [] ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Δ0 ++ B :: Δ3 ++ m0 :: Δ4 ++ Δ6 = Δ0 ++ [] ++ (B :: Δ3) ++ (m0 :: Δ4) ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_RI.
+  * rewrite app_nil_r. exists (Γ0 ++ A :: Γ1, (Δ0 ++ m1 :: Δ5 ++ m0 :: Δ4) ++ B :: Δ3 ++ Δ6). split.
+    assert (Δ0 ++ m1 :: Δ5 ++ m0 :: Δ4 ++ A --> B :: Δ3 ++ Δ6 = (Δ0 ++ m1 :: Δ5 ++ m0 :: Δ4) ++ A --> B :: Δ3 ++ Δ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity. rewrite H0. apply ImpRRule_I.
+    assert (Δ0 ++ B :: Δ3 ++ m0 :: Δ4 ++ m1 :: Δ5 ++ Δ6 = Δ0 ++ (B :: Δ3) ++ (m0 :: Δ4) ++ (m1 :: Δ5) ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert ((Δ0 ++ m1 :: Δ5 ++ m0 :: Δ4) ++ B :: Δ3 ++ Δ6 = Δ0 ++ (m1 :: Δ5) ++ (m0 :: Δ4) ++ (B :: Δ3) ++ Δ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_RI.
+  * exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ Δ6). split. repeat rewrite <- app_assoc. apply ImpRRule_I.
+    apply list_exch_R_id.
+  * exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ m0 :: Δ5 ++ Δ6). split. repeat rewrite <- app_assoc. apply ImpRRule_I.
+    apply list_exch_R_id.
+  * exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ m0 :: Δ4 ++ Δ6). split. repeat rewrite <- app_assoc. apply ImpRRule_I.
+    apply list_exch_R_id.
+  * exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ m1 :: Δ5 ++ m0 :: Δ4 ++ Δ6). split.
+    repeat rewrite <- app_assoc. apply ImpRRule_I.
+    assert (Δ0 ++ B :: x ++ m0 :: Δ4 ++ m1 :: Δ5 ++ Δ6 = (Δ0 ++ B :: x) ++ (m0 :: Δ4) ++ [] ++ (m1 :: Δ5) ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Δ0 ++ B :: x ++ m1 :: Δ5 ++ m0 :: Δ4 ++ Δ6 = (Δ0 ++ B :: x) ++ (m1 :: Δ5) ++ [] ++ (m0 :: Δ4) ++ Δ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_RI.
+  * exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ m0 :: Δ3 ++ Δ6). split. repeat rewrite <- app_assoc. apply ImpRRule_I.
+    apply list_exch_R_id.
+  * exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ m1 :: Δ5 ++ m0 :: Δ3 ++ Δ6). split.
+    repeat rewrite <- app_assoc. apply ImpRRule_I.
+    assert (Δ0 ++ B :: x ++ m0 :: Δ3 ++ m1 :: Δ5 ++ Δ6 = (Δ0 ++ B :: x) ++ (m0 :: Δ3) ++ [] ++ (m1 :: Δ5) ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Δ0 ++ B :: x ++ m1 :: Δ5 ++ m0 :: Δ3 ++ Δ6 = (Δ0 ++ B :: x) ++ (m1 :: Δ5) ++ [] ++ (m0 :: Δ3) ++ Δ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_RI.
+  * exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ m1 :: Δ4 ++ m0 :: Δ3 ++ Δ6). split.
+    repeat rewrite <- app_assoc. apply ImpRRule_I.
+    assert (Δ0 ++ B :: x ++ m0 :: Δ3 ++ m1 :: Δ4 ++ Δ6 = (Δ0 ++ B :: x) ++ (m0 :: Δ3) ++ [] ++ (m1 :: Δ4) ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Δ0 ++ B :: x ++ m1 :: Δ4 ++ m0 :: Δ3 ++ Δ6 = (Δ0 ++ B :: x) ++ (m1 :: Δ4) ++ [] ++ (m0 :: Δ3) ++ Δ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_RI.
+  * exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ m2 :: Δ5 ++ m1 :: Δ4 ++ m0 :: Δ3 ++ Δ6). split.
+    repeat rewrite <- app_assoc. apply ImpRRule_I.
+    assert (Δ0 ++ B :: x ++ m0 :: Δ3 ++ m1 :: Δ4 ++ m2 :: Δ5 ++ Δ6 = (Δ0 ++ B :: x) ++ (m0 :: Δ3) ++ (m1 :: Δ4) ++ (m2 :: Δ5) ++ Δ6).
+    repeat rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+    assert (Δ0 ++ B :: x ++ m2 :: Δ5 ++ m1 :: Δ4 ++ m0 :: Δ3 ++ Δ6 = (Δ0 ++ B :: x) ++ (m2 :: Δ5) ++ (m1 :: Δ4) ++ (m0 :: Δ3) ++ Δ6).
+    repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. reflexivity.
+    rewrite H0. clear H0. apply list_exch_RI.
+Qed.
+
+
+ +
+ + + diff --git a/K.KS.KS_exch_KR.html b/K.KS.KS_exch_KR.html new file mode 100644 index 0000000..dcff216 --- /dev/null +++ b/K.KS.KS_exch_KR.html @@ -0,0 +1,111 @@ + + + + + + + + + + + + + +
+
+

K.KS.KS_exch_KR

+ +
+Require Import List.
+Export ListNotations.
+Require Import Lia.
+Require Import PeanoNat.
+ +
+Require Import KS_calc.
+Require Import KS_exch_prelims.
+ +
+(* The following lemmas make sure that if a rule is applied on a sequent s with
+premises ps, then the same rule is applicable on a sequent se which is an exchanged
+version of s, with some premises pse that are such that they are exchanged versions
+of ps. *)

+ +
+Lemma KR_app_list_exchL : forall s se ps,
+  (@list_exch_L s se) ->
+  (KRRule [ps] s) ->
+  (existsT2 pse,
+    (KRRule [pse] se) *
+    (@list_exch_L ps pse)).
+Proof.
+intros s se ps exch RA. inversion RA. inversion exch. rewrite <- H1 in H2.
+inversion H2. subst.
+pose (@nobox_gen_ext_exch_L (Δ0 ++ Box A :: Δ1) [A] (Γ1 ++ Γ2 ++ Γ3 ++ Γ4 ++ Γ5) (Γ1 ++ Γ4 ++ Γ3 ++ Γ2 ++ Γ5) X exch).
+destruct s. destruct p. inversion l.
+exists (unboxed_list (Γ0 ++ Γ8 ++ Γ7 ++ Γ6 ++ Γ9), [A]). split.
+- apply KRRule_I.
+  * unfold is_Boxed_list. intros. apply in_exch_list in H4. subst. apply H0 in H4.
+    assumption.
+  * subst. assumption.
+- repeat rewrite unbox_app_distrib. repeat rewrite <- app_assoc. apply list_exch_LI.
+Qed.
+ +
+Lemma KR_app_list_exchR : forall s se ps,
+  (@list_exch_R s se) ->
+  (KRRule [ps] s) ->
+  (existsT2 pse,
+    (KRRule [pse] se) *
+    (@list_exch_R ps pse)).
+Proof.
+intros s se ps exch RA. inversion RA. inversion exch. rewrite <- H1 in H2.
+inversion H2. exists (unboxed_list , [A]). split.
+- pose (partition_1_element2 Δ2 Δ3 Δ4 Δ5 Δ6 Δ0 Δ1 (Box A) H6). destruct s0.
+  + repeat destruct s0. repeat destruct p. subst. assert (E : (Δ0 ++ Box A :: x0) ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6 = Δ0 ++ Box A :: (x0 ++ Δ5 ++ Δ4 ++ Δ3 ++ Δ6)).
+    repeat rewrite <- app_assoc. reflexivity. rewrite E. apply KRRule_I.
+    * assumption.
+    * assumption.
+  + destruct s0.
+    * repeat destruct s0. repeat destruct p. subst. assert (E: Δ2 ++ Δ5 ++ Δ4 ++ (x ++ Box A :: x0) ++ Δ6 = (Δ2 ++ Δ5 ++ Δ4 ++ x) ++ Box A :: x0 ++ Δ6).
+      repeat rewrite <- app_assoc. reflexivity. rewrite E. apply KRRule_I.
+      { assumption. }
+      { assumption. }
+    * destruct s0.
+      { repeat destruct s0. repeat destruct p. subst. assert (E: Δ2 ++ Δ5 ++ (x ++ Box A :: x0) ++ Δ3 ++ Δ6 = (Δ2 ++ Δ5 ++ x) ++ Box A :: x0 ++ Δ3 ++ Δ6).
+        repeat rewrite <- app_assoc. reflexivity. rewrite E. apply KRRule_I.
+        - assumption.
+        - assumption. }
+      { destruct s0.
+        - repeat destruct s0. repeat destruct p. subst. assert (E: Δ2 ++ (x ++ Box A :: x0) ++ Δ4 ++ Δ3 ++ Δ6 = (Δ2 ++ x) ++ Box A :: x0 ++ Δ4 ++ Δ3 ++ Δ6).
+          repeat rewrite <- app_assoc. reflexivity. rewrite E. apply KRRule_I.
+          + assumption.
+          + assumption.
+        - repeat destruct s0. repeat destruct p. subst. assert (E: Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ x ++ Box A :: Δ1 = (Δ2 ++ Δ5 ++ Δ4 ++ Δ3 ++ x) ++ Box A :: Δ1).
+          repeat rewrite <- app_assoc. reflexivity. rewrite E. apply KRRule_I.
+          + assumption.
+          + assumption. }
+- apply list_exch_R_id.
+Qed.
+
+
+ +
+ + + diff --git a/K.KS.KS_exch_prelims.html b/K.KS.KS_exch_prelims.html new file mode 100644 index 0000000..8413b5d --- /dev/null +++ b/K.KS.KS_exch_prelims.html @@ -0,0 +1,538 @@ + + + + + + + + + + + + + +
+
+

K.KS.KS_exch_prelims

+ +
+Require Import List.
+Export ListNotations.
+Require Import Lia.
+Require Import PeanoNat.
+ +
+Require Import KS_calc.
+ +
+(* First, as we want to mimic sequents based on multisets of formulae we need to
+obtain exchange. *)

+ +
+(* Definition of exchange with lists of formulae directly. It is more general and
+makes the proofs about exchange easier to handle. *)

+ +
+Inductive list_exch_L : relationT Seq :=
+  | list_exch_LI Γ0 Γ1 Γ2 Γ3 Γ4 Δ : list_exch_L
+      (Γ0 ++ Γ1 ++ Γ2 ++ Γ3 ++ Γ4, Δ) (Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4, Δ).
+ +
+Inductive list_exch_R : relationT Seq :=
+  | list_exch_RI Γ Δ0 Δ1 Δ2 Δ3 Δ4 : list_exch_R
+        (Γ, Δ0 ++ Δ1 ++ Δ2 ++ Δ3 ++ Δ4) (Γ, Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4).
+ +
+(* Some lemmas about In and exchange. *)
+ +
+Lemma InT_list_exch_R : forall l0 l1 l2,
+            (@list_exch_R (l0,l1) (l0,l2)) ->
+            (forall x, (InT x l1 -> InT x l2) * (InT x l2 -> InT x l1)).
+Proof.
+intros l0 l1 l2 exch. inversion exch.
+intro x. split.
+- intro. apply InT_app_or in H2. destruct H2. apply InT_or_app. left. assumption.
+  apply InT_app_or in i. destruct i. apply InT_or_app. right. apply InT_or_app. right.
+  apply InT_or_app. right. apply InT_or_app. left. assumption. apply InT_app_or in i.
+  destruct i. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. left.
+  assumption. apply InT_app_or in i. destruct i. apply InT_or_app. right. apply InT_or_app.
+  left. assumption. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. right.
+  assumption.
+- intro. apply InT_app_or in H2. destruct H2. apply InT_or_app. left. assumption.
+  apply InT_app_or in i. destruct i. apply InT_or_app. right. apply InT_or_app. right.
+  apply InT_or_app. right. apply InT_or_app. left. assumption. apply InT_app_or in i.
+  destruct i. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. left.
+  assumption. apply InT_app_or in i. destruct i. apply InT_or_app. right. apply InT_or_app.
+  left. assumption. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. right.
+  assumption.
+Qed.
+ +
+Lemma InT_list_exch_L : forall l0 l1 l2,
+            (@list_exch_L (l1,l0) (l2,l0)) ->
+            (forall x, (InT x l1 -> InT x l2) * (InT x l2 -> InT x l1)).
+Proof.
+intros l0 l1 l2 exch. inversion exch.
+intro x. split.
+- intro. apply InT_app_or in H2. destruct H2. apply InT_or_app. left. assumption.
+  apply InT_app_or in i. destruct i. apply InT_or_app. right. apply InT_or_app. right.
+  apply InT_or_app. right. apply InT_or_app. left. assumption. apply InT_app_or in i.
+  destruct i. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. left.
+  assumption. apply InT_app_or in i. destruct i. apply InT_or_app. right. apply InT_or_app.
+  left. assumption. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. right.
+  assumption.
+- intro. apply InT_app_or in H2. destruct H2. apply InT_or_app. left. assumption.
+  apply InT_app_or in i. destruct i. apply InT_or_app. right. apply InT_or_app. right.
+  apply InT_or_app. right. apply InT_or_app. left. assumption. apply InT_app_or in i.
+  destruct i. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. left.
+  assumption. apply InT_app_or in i. destruct i. apply InT_or_app. right. apply InT_or_app.
+  left. assumption. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. right.
+  assumption.
+Qed.
+ +
+(* Some useful lemmas about list exchange. *)
+ +
+Lemma list_exch_R_id : forall s, (@list_exch_R s s).
+Proof.
+intros s. destruct s. pose (list_exch_RI l l0
+[] [] [] []). simpl in l1. assert (H: l0 ++ [] = l0).
+apply app_nil_r. rewrite H in l1. assumption.
+Qed.
+ +
+Lemma list_exch_L_id : forall s, (@list_exch_L s s).
+Proof.
+intros s. destruct s. pose (list_exch_LI l
+[] [] [] [] l0). simpl in l1. assert (H: l ++ [] = l).
+apply app_nil_r. rewrite H in l1. assumption.
+Qed.
+ +
+Lemma list_exch_R_same_L: forall s se,
+    (@list_exch_R s se) ->
+    (forall Γ Γe Δ Δe, (s = (Γ , Δ)) ->
+    (se = (Γe , Δe)) ->
+    (Γ = Γe)).
+Proof.
+intros s se exch. induction exch. intros Γ0 Γe Δ Δe E1 E2.
+inversion E1. inversion E2. rewrite H0 in H2. assumption.
+Qed.
+ +
+Lemma list_exch_L_same_R : forall s se,
+    (@list_exch_L s se) ->
+    (forall Γ Γe Δ Δe, (s = (Γ , Δ)) ->
+    (se = (Γe , Δe)) ->
+    (Δ = Δe)).
+Proof.
+intros s se exch. induction exch. intros Γ Γe Δ0 Δe E1 E2.
+inversion E1. inversion E2. rewrite H1 in H3. assumption.
+Qed.
+ +
+Lemma list_exch_R_permL : forall s se,
+    (@list_exch_R s se) ->
+      (forall Γ0 Γ1 Δ C, s = ((Γ0 ++ C :: Γ1), Δ) ->
+      (existsT2 , se = ((Γ0 ++ C :: Γ1), ))).
+Proof.
+intros s se exch. induction exch. intros Γ0 Γ1 Δ C E.
+inversion E. exists (Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4). reflexivity.
+Qed.
+ +
+Lemma list_exch_R_permR : forall s se,
+    (@list_exch_R s se) ->
+      (forall Γ Δ0 Δ1 C, s = (Γ, (Δ0 ++ C :: Δ1)) ->
+      (existsT2 eΔ0 eΔ1, se = (Γ, (eΔ0 ++ C :: eΔ1)))).
+Proof.
+intros s se exch. induction exch. intros Γ0 Δ5 Δ6 C E.
+inversion E. apply partition_1_element in H1. destruct H1.
++ destruct s. destruct s. rewrite e. exists x. exists (x0 ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4).
+  simpl.
+  assert (E1: (x ++ C :: x0) ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4 = x ++ C :: x0 ++ Δ3 ++ Δ2 ++ Δ1 ++ Δ4).
+  { symmetry. apply app_assoc with (l:=x) (m:=C :: x0) (n:=Δ3 ++ Δ2 ++ Δ1 ++ Δ4). }
+  rewrite E1. reflexivity.
++ destruct s.
+  * destruct s. destruct s. exists (Δ0 ++ Δ3 ++ Δ2 ++ x). exists (x0 ++ Δ4).
+    rewrite e. assert (E1: Δ0 ++ Δ3 ++ Δ2 ++ (x ++ C :: x0) ++ Δ4 =
+    (Δ0 ++ Δ3 ++ Δ2 ++ x) ++ C :: x0 ++ Δ4).
+    pose (app_assoc x (C :: x0) Δ4). rewrite <- e0. simpl.
+    pose (app_assoc (Δ0 ++ Δ3 ++ Δ2) x (C :: x0 ++ Δ4)).
+    pose (app_assoc (Δ0 ++ Δ3) Δ2 x).
+    pose (app_assoc Δ0 Δ3 Δ2).
+    rewrite <- e3 in e2. rewrite <- e2 in e1.
+    pose (app_assoc Δ0 Δ3 (Δ2 ++ x)). rewrite <- e4 in e1. rewrite <- e1.
+    pose (app_assoc (Δ0 ++ Δ3) Δ2 (x ++ C :: x0 ++ Δ4)).
+    rewrite <- e3 in e5. rewrite <- e5.
+    pose (app_assoc Δ0 Δ3 (Δ2 ++ x ++ C :: x0 ++ Δ4)). rewrite e6. reflexivity.
+    rewrite E1. reflexivity.
+  * destruct s.
+    - destruct s. destruct s. exists (Δ0 ++ Δ3 ++ x). exists (x0 ++ Δ1 ++ Δ4).
+      rewrite e. assert (E1: Δ0 ++ Δ3 ++ (x ++ C :: x0) ++ Δ1 ++ Δ4 =
+      (Δ0 ++ Δ3 ++ x) ++ C :: x0 ++ Δ1 ++ Δ4).
+      pose (app_assoc x (C :: x0) (Δ1 ++ Δ4)). rewrite <- e0. simpl.
+      pose (app_assoc (Δ0 ++ Δ3) x (C :: x0 ++ Δ1 ++ Δ4)).
+      pose (app_assoc Δ0 Δ3 x). rewrite <- e2 in e1. rewrite <- e1.
+      pose (app_assoc Δ0 Δ3 (x ++ C :: x0 ++ Δ1 ++ Δ4)). rewrite <- e3.
+      reflexivity. rewrite E1. reflexivity.
+    - destruct s.
+      { destruct s. destruct s. rewrite e. exists (Δ0 ++ x). exists (x0 ++ Δ2 ++ Δ1 ++ Δ4).
+        assert (E1: Δ0 ++ (x ++ C :: x0) ++ Δ2 ++ Δ1 ++ Δ4 =
+        (Δ0 ++ x) ++ C :: x0 ++ Δ2 ++ Δ1 ++ Δ4).
+        pose (app_assoc x (C :: x0) (Δ2 ++ Δ1 ++ Δ4)). rewrite <- e0. simpl.
+        pose (app_assoc Δ0 x (C :: x0 ++ Δ2 ++ Δ1 ++ Δ4)). rewrite e1.
+        reflexivity. rewrite E1. reflexivity. }
+      { destruct s. destruct s. rewrite e. exists (Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ x).
+        exists x0. assert (E1: Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ x ++ C :: x0 =
+        (Δ0 ++ Δ3 ++ Δ2 ++ Δ1 ++ x) ++ C :: x0).
+        pose (app_assoc (Δ0 ++ Δ3 ++ Δ2 ++ Δ1) x (C :: x0)).
+        pose (app_assoc (Δ0 ++ Δ3 ++ Δ2) Δ1 x).
+        pose (app_assoc (Δ0 ++ Δ3) Δ2 Δ1).
+        pose (app_assoc Δ0 Δ3 Δ2). rewrite <- e3 in e2. rewrite <- e2 in e1.
+        pose (app_assoc Δ0 Δ3 (Δ2 ++ Δ1)). rewrite <- e4 in e1. rewrite <- e1 in e0.
+        pose (app_assoc (Δ0 ++ Δ3) Δ2 (Δ1 ++ x)). rewrite <- e3 in e5.
+        rewrite <- e5 in e0.
+        pose (app_assoc Δ0 Δ3 (Δ2 ++ Δ1 ++ x)). rewrite <- e6 in e0.
+        rewrite <- e0.
+        pose (app_assoc (Δ0 ++ Δ3 ++ Δ2) Δ1 (x ++ C :: x0)).
+        rewrite <- e2 in e7. rewrite <- e4 in e7. rewrite <- e7.
+        pose (app_assoc (Δ0 ++ Δ3) Δ2 (Δ1 ++ x ++ C :: x0)).
+        rewrite <- e3 in e8. rewrite <- e8.
+        pose (app_assoc Δ0 Δ3 (Δ2 ++ Δ1 ++ x ++ C :: x0)).
+        rewrite e9. reflexivity. rewrite E1. reflexivity. }
+Qed.
+ +
+Lemma list_exch_R_permLR : forall s se,
+    (@list_exch_R s se) ->
+      (forall Γ0 Γ1 Δ0 Δ1 C D, s = ((Γ0 ++ C :: Γ1), (Δ0 ++ D :: Δ1)) ->
+      (existsT2 eΔ0 eΔ1, se = ((Γ0 ++ C :: Γ1), (eΔ0 ++ D :: eΔ1)))).
+Proof.
+intros s se exch. intros Γ0 Γ1 Δ0 Δ1 C D Eq.
+pose (list_exch_R_permL _ _ exch). pose (s0 Γ0 Γ1 (Δ0 ++ D :: Δ1) C).
+pose (s1 Eq). destruct s2.
+pose (list_exch_R_permR _ _ exch). pose (s2 (Γ0 ++ C :: Γ1) Δ0 Δ1 D).
+pose (s3 Eq). destruct s4. destruct s4. exists x0. exists x1. assumption.
+Qed.
+ +
+Lemma list_exch_L_permL : forall s se,
+    (@list_exch_L s se) ->
+      (forall Γ0 Γ1 Δ C, s = ((Γ0 ++ C :: Γ1), Δ) ->
+      (existsT2 eΓ0 eΓ1, se = ((eΓ0 ++ C :: eΓ1), Δ))).
+Proof.
+intros s se exch. induction exch. intros Γ5 Γ6 Δ0 C E.
+inversion E. apply partition_1_element in H0. destruct H0.
++ destruct s. destruct s. rewrite e. exists x. exists (x0 ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4).
+  simpl.
+  assert (E1: (x ++ C :: x0) ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4 = x ++ C :: x0 ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4).
+  { symmetry. apply app_assoc with (l:=x) (m:=C :: x0) (n:=Γ3 ++ Γ2 ++ Γ1 ++ Γ4). }
+  rewrite E1. reflexivity.
++ destruct s.
+  * destruct s. destruct s. exists (Γ0 ++ Γ3 ++ Γ2 ++ x). exists (x0 ++ Γ4).
+    rewrite e. assert (E1: Γ0 ++ Γ3 ++ Γ2 ++ (x ++ C :: x0) ++ Γ4 =
+    (Γ0 ++ Γ3 ++ Γ2 ++ x) ++ C :: x0 ++ Γ4).
+    pose (app_assoc x (C :: x0) Γ4). rewrite <- e0. simpl.
+    pose (app_assoc (Γ0 ++ Γ3 ++ Γ2) x (C :: x0 ++ Γ4)).
+    pose (app_assoc (Γ0 ++ Γ3) Γ2 x).
+    pose (app_assoc Γ0 Γ3 Γ2).
+    rewrite <- e3 in e2. rewrite <- e2 in e1.
+    pose (app_assoc Γ0 Γ3 (Γ2 ++ x)). rewrite <- e4 in e1. rewrite <- e1.
+    pose (app_assoc (Γ0 ++ Γ3) Γ2 (x ++ C :: x0 ++ Γ4)).
+    rewrite <- e3 in e5. rewrite <- e5.
+    pose (app_assoc Γ0 Γ3 (Γ2 ++ x ++ C :: x0 ++ Γ4)). rewrite e6. reflexivity.
+    rewrite E1. reflexivity.
+  * destruct s.
+    - destruct s. destruct s. exists (Γ0 ++ Γ3 ++ x). exists (x0 ++ Γ1 ++ Γ4).
+      rewrite e. assert (E1: Γ0 ++ Γ3 ++ (x ++ C :: x0) ++ Γ1 ++ Γ4 =
+      (Γ0 ++ Γ3 ++ x) ++ C :: x0 ++ Γ1 ++ Γ4).
+      pose (app_assoc x (C :: x0) (Γ1 ++ Γ4)). rewrite <- e0. simpl.
+      pose (app_assoc (Γ0 ++ Γ3) x (C :: x0 ++ Γ1 ++ Γ4)).
+      pose (app_assoc Γ0 Γ3 x). rewrite <- e2 in e1. rewrite <- e1.
+      pose (app_assoc Γ0 Γ3 (x ++ C :: x0 ++ Γ1 ++ Γ4)). rewrite <- e3.
+      reflexivity. rewrite E1. reflexivity.
+    - destruct s.
+      { destruct s. destruct s. rewrite e. exists (Γ0 ++ x). exists (x0 ++ Γ2 ++ Γ1 ++ Γ4).
+        assert (E1: Γ0 ++ (x ++ C :: x0) ++ Γ2 ++ Γ1 ++ Γ4 =
+        (Γ0 ++ x) ++ C :: x0 ++ Γ2 ++ Γ1 ++ Γ4).
+        pose (app_assoc x (C :: x0) (Γ2 ++ Γ1 ++ Γ4)). rewrite <- e0. simpl.
+        pose (app_assoc Γ0 x (C :: x0 ++ Γ2 ++ Γ1 ++ Γ4)). rewrite e1.
+        reflexivity. rewrite E1. reflexivity. }
+      { destruct s. destruct s. rewrite e. exists (Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ x).
+        exists x0. assert (E1: Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ x ++ C :: x0 =
+        (Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ x) ++ C :: x0).
+        pose (app_assoc (Γ0 ++ Γ3 ++ Γ2 ++ Γ1) x (C :: x0)).
+        pose (app_assoc (Γ0 ++ Γ3 ++ Γ2) Γ1 x).
+        pose (app_assoc (Γ0 ++ Γ3) Γ2 Γ1).
+        pose (app_assoc Γ0 Γ3 Γ2). rewrite <- e3 in e2. rewrite <- e2 in e1.
+        pose (app_assoc Γ0 Γ3 (Γ2 ++ Γ1)). rewrite <- e4 in e1. rewrite <- e1 in e0.
+        pose (app_assoc (Γ0 ++ Γ3) Γ2 (Γ1 ++ x)). rewrite <- e3 in e5.
+        rewrite <- e5 in e0.
+        pose (app_assoc Γ0 Γ3 (Γ2 ++ Γ1 ++ x)). rewrite <- e6 in e0.
+        rewrite <- e0.
+        pose (app_assoc (Γ0 ++ Γ3 ++ Γ2) Γ1 (x ++ C :: x0)).
+        rewrite <- e2 in e7. rewrite <- e4 in e7. rewrite <- e7.
+        pose (app_assoc (Γ0 ++ Γ3) Γ2 (Γ1 ++ x ++ C :: x0)).
+        rewrite <- e3 in e8. rewrite <- e8.
+        pose (app_assoc Γ0 Γ3 (Γ2 ++ Γ1 ++ x ++ C :: x0)).
+        rewrite e9. reflexivity. rewrite E1. reflexivity. }
+Qed.
+ +
+Lemma list_exch_L_permR : forall s se,
+    (@list_exch_L s se) ->
+      (forall Γ Δ0 Δ1 C, s = (Γ, (Δ0 ++ C :: Δ1)) ->
+      (existsT2 , se = (, (Δ0 ++ C :: Δ1)))).
+Proof.
+intros s se exch. induction exch. intros Γ Δ0 Δ1 C E.
+inversion E. exists (Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4). reflexivity.
+Qed.
+ +
+Lemma list_exch_L_permLR : forall s se,
+    (@list_exch_L s se) ->
+      (forall Γ0 Γ1 Δ0 Δ1 C D, s = ((Γ0 ++ C :: Γ1), (Δ0 ++ D :: Δ1)) ->
+      (existsT2 eΓ0 eΓ1, se = ((eΓ0 ++ C :: eΓ1), (Δ0 ++ D :: Δ1)))).
+Proof.
+intros s se exch. intros Γ0 Γ1 Δ0 Δ1 C D Eq.
+pose (list_exch_L_permR _ _ exch). pose (s0 (Γ0 ++ C :: Γ1) Δ0 Δ1 D).
+pose (s1 Eq). destruct s2.
+pose (list_exch_L_permL _ _ exch). pose (s2 Γ0 Γ1 (Δ0 ++ D :: Δ1) C).
+pose (s3 Eq). destruct s4. destruct s4. exists x0. exists x1. assumption.
+Qed.
+ +
+(* Some lemmas about nobox_gen_ext and exchange. *)
+ +
+Lemma nobox_gen_ext_exch_R : forall Γ Γ' l0 l1 l2,
+    (nobox_gen_ext l0 l1) -> (@list_exch_R (Γ,l1) (Γ,l2)) ->
+    existsT2 l3, (nobox_gen_ext l3 l2) * (list_exch_R (Γ',l0) (Γ',l3)).
+Proof.
+intros Γ Γ' l0. induction l0.
++ intros l1 l2 gen. remember [] as l0. destruct gen.
+  - intro exch. inversion exch. apply app_eq_nil in H1. destruct H1. apply app_eq_nil in H2. destruct H2.
+    apply app_eq_nil in H3. destruct H3. apply app_eq_nil in H4. destruct H4.
+    subst. simpl. exists []. split.
+    * apply univ_gen_ext_nil.
+    * apply list_exch_R_id.
+  - intros exch. exists []. split.
+    * inversion Heql0.
+    * inversion Heql0.
+  - intro exch. subst. exists []. split. apply all_P_univ_gen_ext_nil.
+    intros. pose (InT_list_exch_R _ _ _ exch). pose (p x0). destruct p0. pose (univ_gen_ext_nil_all_P gen).
+    pose (f0 x0). apply i0 in H. inversion H. subst. apply f. assumption. subst. apply f1 in H1.
+    assumption. assumption.
+    apply list_exch_R_id.
++ intros l1 l2 gen. induction gen.
+  - intro exch. inversion exch. destruct Δ0.
+    * rewrite app_nil_l in H. rewrite app_nil_l in H1. rewrite app_nil_l. destruct Δ1.
+      { rewrite app_nil_l in H1. destruct Δ2.
+        + rewrite app_nil_l in H1. destruct Δ3.
+          - rewrite app_nil_l in H1. repeat rewrite app_nil_l in H. destruct Δ4.
+            * simpl. exists []. split. apply univ_gen_ext_nil. apply list_exch_R_id.
+            * inversion H1.
+          - inversion H1.
+        + inversion H1. }
+      { inversion H1. }
+    * inversion H1.
+  - intro exch. inversion exch. destruct Δ0.
+    * rewrite app_nil_l in H. rewrite app_nil_l in H1. rewrite app_nil_l. destruct Δ1.
+      { rewrite app_nil_l in H1. destruct Δ2.
+        + rewrite app_nil_l in H1. destruct Δ3.
+          - rewrite app_nil_l in H1. repeat rewrite app_nil_l in H. destruct Δ4.
+            * inversion H1.
+            * inversion H1. simpl. subst. exists (x :: l).
+              split. apply univ_gen_ext_cons. assumption. apply list_exch_R_id.
+          - repeat rewrite app_nil_l in H. repeat rewrite app_nil_l. simpl. simpl in H. simpl in H1.
+            inversion H1. subst. exists (x :: l). split. apply univ_gen_ext_cons. assumption. apply list_exch_R_id.
+        + rewrite app_nil_l. rewrite app_nil_l in H. inversion H1. subst.
+          pose (univ_gen_ext_splitR _ _ gen). repeat destruct s. repeat destruct p.
+          pose (univ_gen_ext_splitR _ _ u0). repeat destruct s. repeat destruct p. subst.
+          exists (x2 ++ x :: x0 ++ x3). split.
+          - apply univ_gen_ext_cons with (x:=x) in u. pose (univ_gen_ext_combine u u2).
+            pose (univ_gen_ext_combine u1 u3). assumption.
+          - pose (list_exch_RI Γ' [] [] (x :: x0) x2 x3). repeat rewrite app_nil_l in l. assumption. }
+      { inversion H1. subst. pose (univ_gen_ext_splitR _ _ gen). repeat destruct s. repeat destruct p.
+        pose (univ_gen_ext_splitR _ _ u0). repeat destruct s. repeat destruct p. pose (univ_gen_ext_splitR _ _ u2).
+        repeat destruct s. repeat destruct p. subst. exists (x4 ++ x2 ++ (x :: x0) ++ x5).
+        split.
+        - apply univ_gen_ext_cons with (x:=x) in u. pose (univ_gen_ext_combine u u4).
+          pose (univ_gen_ext_combine u1 u5). pose (univ_gen_ext_combine u3 u6). assumption.
+        - pose (list_exch_RI Γ' [] (x :: x0) x2 x4 x5). rewrite app_nil_l in l. assumption. }
+    * inversion H1. subst. pose (univ_gen_ext_splitR _ _ gen).
+      repeat destruct s. repeat destruct p. pose (univ_gen_ext_splitR _ _ u0).
+      repeat destruct s. repeat destruct p. pose (univ_gen_ext_splitR _ _ u2).
+      repeat destruct s. repeat destruct p. pose (univ_gen_ext_splitR _ _ u4).
+      repeat destruct s. repeat destruct p. subst. exists (x :: x0 ++ x6 ++ x4 ++ x2 ++ x7).
+      split.
+      { apply univ_gen_ext_cons with (x:=x) in u. pose (univ_gen_ext_combine u1 u6).
+        pose (univ_gen_ext_combine u3 u7). pose (univ_gen_ext_combine u5 u8).
+        pose (univ_gen_ext_combine u u9). assumption. }
+      { assert (E1: x :: x0 ++ x2 ++ x4 ++ x6 ++ x7 = (x :: x0) ++ x2 ++ x4 ++ x6 ++ x7).
+        reflexivity. rewrite E1.
+        assert (E2: x :: x0 ++ x6 ++ x4 ++ x2 ++ x7 = (x :: x0) ++ x6 ++ x4 ++ x2 ++ x7).
+        reflexivity. rewrite E2. apply list_exch_RI. }
+  - intro exch. inversion exch. destruct Δ0.
+    * rewrite app_nil_l in H. rewrite app_nil_l in H1. rewrite app_nil_l. destruct Δ1.
+      { rewrite app_nil_l in H1. destruct Δ2.
+        + rewrite app_nil_l in H1. destruct Δ3.
+          - rewrite app_nil_l in H1. repeat rewrite app_nil_l in H. destruct Δ4.
+            * inversion H1.
+            * inversion H1. simpl. subst. exists l.
+              split. apply univ_gen_ext_extra. assumption. assumption. apply list_exch_R_id.
+          - repeat rewrite app_nil_l in H. repeat rewrite app_nil_l. simpl. simpl in H. simpl in H1.
+            inversion H1. subst. exists l. split. apply univ_gen_ext_extra. assumption. assumption. apply list_exch_R_id.
+        + rewrite app_nil_l. rewrite app_nil_l in H. inversion H1. subst.
+          pose (univ_gen_ext_splitR _ _ gen). repeat destruct s. repeat destruct p0.
+          pose (univ_gen_ext_splitR _ _ u0). repeat destruct s. repeat destruct p0. subst.
+          exists (x2 ++ x0 ++ x3). split.
+          - apply univ_gen_ext_extra with (x:=x) in u. pose (univ_gen_ext_combine u u2).
+            pose (univ_gen_ext_combine u1 u3). assumption. assumption.
+          - pose (list_exch_RI Γ' [] [] x0 x2 x3). repeat rewrite app_nil_l in l. assumption. }
+      { inversion H1. subst. pose (univ_gen_ext_splitR _ _ gen). repeat destruct s. repeat destruct p0.
+        pose (univ_gen_ext_splitR _ _ u0). repeat destruct s. repeat destruct p0. pose (univ_gen_ext_splitR _ _ u2).
+        repeat destruct s. repeat destruct p0. subst. exists (x4 ++ x2 ++ x0 ++ x5).
+        split.
+        - apply univ_gen_ext_extra with (x:=x) in u. pose (univ_gen_ext_combine u u4).
+          pose (univ_gen_ext_combine u1 u5). pose (univ_gen_ext_combine u3 u6). assumption. assumption.
+        - pose (list_exch_RI Γ' [] x0 x2 x4 x5). rewrite app_nil_l in l. assumption. }
+    * inversion H1. subst. pose (univ_gen_ext_splitR _ _ gen).
+      repeat destruct s. repeat destruct p0. pose (univ_gen_ext_splitR _ _ u0).
+      repeat destruct s. repeat destruct p0. pose (univ_gen_ext_splitR _ _ u2).
+      repeat destruct s. repeat destruct p0. pose (univ_gen_ext_splitR _ _ u4).
+      repeat destruct s. repeat destruct p0. subst. exists (x0 ++ x6 ++ x4 ++ x2 ++ x7).
+      split.
+      { apply univ_gen_ext_extra with (x:=x) in u. pose (univ_gen_ext_combine u1 u6).
+        pose (univ_gen_ext_combine u3 u7). pose (univ_gen_ext_combine u5 u8).
+        pose (univ_gen_ext_combine u u9). assumption. assumption. }
+      { apply list_exch_RI. }
+Qed.
+ +
+Lemma nobox_gen_ext_exch_L : forall Δ Δ' l0 l1 l2,
+    (nobox_gen_ext l0 l1) -> (@list_exch_L (l1,Δ) (l2,Δ)) ->
+    existsT2 l3, (nobox_gen_ext l3 l2) * (list_exch_L (l0,Δ') (l3,Δ')).
+Proof.
+intros Δ Δ' l0. induction l0.
++ intros l1 l2 gen. inversion gen.
+  - intro exch. inversion exch. apply app_eq_nil in H1. destruct H1. apply app_eq_nil in H3. destruct H3.
+    apply app_eq_nil in H4. destruct H4. apply app_eq_nil in H5. destruct H5.
+    subst. simpl. exists []. split.
+    * apply univ_gen_ext_nil.
+    * apply list_exch_L_id.
+  - intros exch. exists []. split.
+    * subst. apply all_P_univ_gen_ext_nil. intros. pose (InT_list_exch_L _ _ _ exch).
+      pose (p x0). destruct p0. apply i0 in H0. inversion H0. subst. apply H.
+      assumption. subst. pose (univ_gen_ext_nil_all_P gen). apply f in H0.
+      assumption. assumption.
+    * apply list_exch_L_id.
++ intros l1 l2 gen. induction gen.
+  - intro exch. inversion exch. destruct Γ0.
+    * rewrite app_nil_l in H0. rewrite app_nil_l in H. rewrite app_nil_l. destruct Γ1.
+      { rewrite app_nil_l in H0. destruct Γ2.
+        + rewrite app_nil_l in H0. destruct Γ3.
+          - rewrite app_nil_l in H0. repeat rewrite app_nil_l in H. destruct Γ4.
+            * simpl. exists []. split. apply univ_gen_ext_nil. apply list_exch_L_id.
+            * inversion H0.
+          - inversion H0.
+        + inversion H0. }
+      { inversion H0. }
+    * inversion H0.
+  - intro exch. inversion exch. destruct Γ0.
+    * rewrite app_nil_l in H. rewrite app_nil_l in H0. rewrite app_nil_l. destruct Γ1.
+      { rewrite app_nil_l in H0. destruct Γ2.
+        + rewrite app_nil_l in H0. destruct Γ3.
+          - rewrite app_nil_l in H0. repeat rewrite app_nil_l in H. destruct Γ4.
+            * inversion H0.
+            * inversion H0. simpl. subst. exists (x :: l).
+              split. apply univ_gen_ext_cons. assumption. apply list_exch_L_id.
+          - repeat rewrite app_nil_l in H. repeat rewrite app_nil_l. simpl. simpl in H. simpl in H0.
+            inversion H0. subst. exists (x :: l). split. apply univ_gen_ext_cons. assumption. apply list_exch_L_id.
+        + rewrite app_nil_l. rewrite app_nil_l in H. inversion H0. subst.
+          pose (univ_gen_ext_splitR _ _ gen). repeat destruct s. repeat destruct p.
+          pose (univ_gen_ext_splitR _ _ u0). repeat destruct s. repeat destruct p. subst.
+          exists (x2 ++ x :: x0 ++ x3). split.
+          - apply univ_gen_ext_cons with (x:=x) in u. pose (univ_gen_ext_combine u u2).
+            pose (univ_gen_ext_combine u1 u3). assumption.
+          - pose (list_exch_LI [] [] (x :: x0) x2 x3 Δ'). repeat rewrite app_nil_l in l. assumption. }
+      { inversion H0. subst. pose (univ_gen_ext_splitR _ _ gen). repeat destruct s. repeat destruct p.
+        pose (univ_gen_ext_splitR _ _ u0). repeat destruct s. repeat destruct p. pose (univ_gen_ext_splitR _ _ u2).
+        repeat destruct s. repeat destruct p. subst. exists (x4 ++ x2 ++ (x :: x0) ++ x5).
+        split.
+        - apply univ_gen_ext_cons with (x:=x) in u. pose (univ_gen_ext_combine u u4).
+          pose (univ_gen_ext_combine u1 u5). pose (univ_gen_ext_combine u3 u6). assumption.
+        - pose (list_exch_LI [] (x :: x0) x2 x4 x5 Δ'). rewrite app_nil_l in l. assumption. }
+    * inversion H0. subst. pose (univ_gen_ext_splitR _ _ gen).
+      repeat destruct s. repeat destruct p. pose (univ_gen_ext_splitR _ _ u0).
+      repeat destruct s. repeat destruct p. pose (univ_gen_ext_splitR _ _ u2).
+      repeat destruct s. repeat destruct p. pose (univ_gen_ext_splitR _ _ u4).
+      repeat destruct s. repeat destruct p. subst. exists (x :: x0 ++ x6 ++ x4 ++ x2 ++ x7).
+      split.
+      { apply univ_gen_ext_cons with (x:=x) in u. pose (univ_gen_ext_combine u1 u6).
+        pose (univ_gen_ext_combine u3 u7). pose (univ_gen_ext_combine u5 u8).
+        pose (univ_gen_ext_combine u u9). assumption. }
+      { assert (E1: x :: x0 ++ x2 ++ x4 ++ x6 ++ x7 = (x :: x0) ++ x2 ++ x4 ++ x6 ++ x7).
+        reflexivity. rewrite E1.
+        assert (E2: x :: x0 ++ x6 ++ x4 ++ x2 ++ x7 = (x :: x0) ++ x6 ++ x4 ++ x2 ++ x7).
+        reflexivity. rewrite E2. apply list_exch_LI. }
+  - intro exch. inversion exch. destruct Γ0.
+    * rewrite app_nil_l in H. rewrite app_nil_l in H0. rewrite app_nil_l. destruct Γ1.
+      { rewrite app_nil_l in H0. destruct Γ2.
+        + rewrite app_nil_l in H0. destruct Γ3.
+          - rewrite app_nil_l in H0. repeat rewrite app_nil_l in H. destruct Γ4.
+            * inversion H0.
+            * inversion H0. simpl. subst. exists l.
+              split. apply univ_gen_ext_extra. assumption. assumption. apply list_exch_L_id.
+          - repeat rewrite app_nil_l in H. repeat rewrite app_nil_l. simpl. simpl in H. simpl in H0.
+            inversion H0. subst. exists l. split. apply univ_gen_ext_extra. assumption. assumption. apply list_exch_L_id.
+        + rewrite app_nil_l. rewrite app_nil_l in H. inversion H0. subst.
+          pose (univ_gen_ext_splitR _ _ gen). repeat destruct s. repeat destruct p0.
+          pose (univ_gen_ext_splitR _ _ u0). repeat destruct s. repeat destruct p0. subst.
+          exists (x2 ++ x0 ++ x3). split.
+          - apply univ_gen_ext_extra with (x:=x) in u. pose (univ_gen_ext_combine u u2).
+            pose (univ_gen_ext_combine u1 u3). assumption. assumption.
+          - pose (list_exch_LI [] [] x0 x2 x3 Δ'). repeat rewrite app_nil_l in l. assumption. }
+      { inversion H0. subst. pose (univ_gen_ext_splitR _ _ gen). repeat destruct s. repeat destruct p0.
+        pose (univ_gen_ext_splitR _ _ u0). repeat destruct s. repeat destruct p0. pose (univ_gen_ext_splitR _ _ u2).
+        repeat destruct s. repeat destruct p0. subst. exists (x4 ++ x2 ++ x0 ++ x5).
+        split.
+        - apply univ_gen_ext_extra with (x:=x) in u. pose (univ_gen_ext_combine u u4).
+          pose (univ_gen_ext_combine u1 u5). pose (univ_gen_ext_combine u3 u6). assumption. assumption.
+        - pose (list_exch_LI [] x0 x2 x4 x5 Δ'). rewrite app_nil_l in l. assumption. }
+    * inversion H0. subst. pose (univ_gen_ext_splitR _ _ gen).
+      repeat destruct s. repeat destruct p0. pose (univ_gen_ext_splitR _ _ u0).
+      repeat destruct s. repeat destruct p0. pose (univ_gen_ext_splitR _ _ u2).
+      repeat destruct s. repeat destruct p0. pose (univ_gen_ext_splitR _ _ u4).
+      repeat destruct s. repeat destruct p0. subst. exists (x0 ++ x6 ++ x4 ++ x2 ++ x7).
+      split.
+      { apply univ_gen_ext_extra with (x:=x) in u. pose (univ_gen_ext_combine u1 u6).
+        pose (univ_gen_ext_combine u3 u7). pose (univ_gen_ext_combine u5 u8).
+        pose (univ_gen_ext_combine u u9). assumption. assumption. }
+      { apply list_exch_LI. }
+Qed.
+
+
+ +
+ + + diff --git a/K.KS.KS_export.html b/K.KS.KS_export.html new file mode 100644 index 0000000..41349f6 --- /dev/null +++ b/K.KS.KS_export.html @@ -0,0 +1,50 @@ + + + + + + + + + + + + + +
+
+

K.KS.KS_export

+ +
+Require Export KS_calc.
+Require Export KS_dec.
+Require Export KS_exch.
+Require Export KS_ctr.
+Require Export KS_wkn.
+Require Export KS_inv_ImpR_ImpL.
+Require Export KS_termination_measure.
+Require Export KS_termination.
+Require Export KS_additive_cut.
+Require Export KS_cut_elim.
+
+
+ +
+ + + diff --git a/K.KS.KS_inv_ImpR_ImpL.html b/K.KS.KS_inv_ImpR_ImpL.html new file mode 100644 index 0000000..3ff2cb1 --- /dev/null +++ b/K.KS.KS_inv_ImpR_ImpL.html @@ -0,0 +1,734 @@ + + + + + + + + + + + + + +
+
+

K.KS.KS_inv_ImpR_ImpL

+ +
+Require Import List.
+Export ListNotations.
+Require Import Lia.
+Require Import PeanoNat Arith.
+ +
+Require Import KS_calc.
+Require Import KS_exch.
+Require Import KS_wkn.
+Require Import KS_dec.
+ +
+Lemma remove_rest_gen_ext : forall l A, rest_gen_ext [A] (remove eq_dec_form A l) l.
+Proof.
+induction l ; intros.
+- simpl. apply univ_gen_ext_nil.
+- simpl. destruct (eq_dec_form A a).
+  * subst. apply univ_gen_ext_extra. apply InT_eq. apply IHl.
+  * apply univ_gen_ext_cons. apply IHl.
+Qed.
+ +
+Theorem derrec_height_False_ge_1 : forall s, forall (D : KS_prv s), 1 <= derrec_height D.
+Proof.
+intros s D.
+induction D.
+- destruct p.
+- simpl. lia.
+Qed.
+ +
+Lemma rest_nobox_gen_ext_trans : forall (A B : MPropF) l0 l1 l2, ((In (Imp A B) l0) -> False) ->
+                                                    (nobox_gen_ext l0 l1) ->
+                                                    (rest_gen_ext [Imp A B] l2 l1) ->
+                                                    (nobox_gen_ext l0 l2).
+Proof.
+intros A B l0 l1 l2 H1 H2. generalize dependent l2.
+induction H2.
+- intros. inversion X. apply univ_gen_ext_nil.
+- intros. inversion X.
+  * subst. apply univ_gen_ext_cons. apply IHuniv_gen_ext. intro. apply H1.
+    apply in_cons. assumption. assumption.
+  * subst. inversion H3. subst. exfalso. apply H1. apply in_eq.
+    inversion H0.
+- intros. inversion X.
+  * subst. apply univ_gen_ext_extra. assumption. apply IHuniv_gen_ext ; assumption.
+  * subst. apply IHuniv_gen_ext ; assumption.
+Qed.
+ +
+(* We prove the height-preserving invertibility of ImpR and ImpL below. *)
+ +
+Theorem ImpR_ImpL_hpinv : forall (k : nat) concl
+        (D0 : KS_prv concl),
+        k = (derrec_height D0) ->
+          ((forall prem, ((ImpRRule [prem] concl) ->
+          existsT2 (D1 : KS_prv prem),
+          derrec_height D1 <= k))) *
+          ((forall prem1 prem2, ((ImpLRule [prem1; prem2] concl) ->
+          existsT2 (D1 : KS_prv prem1)
+                   (D2 : KS_prv prem2),
+          (derrec_height D1 <= k) * (derrec_height D2 <= k)))).
+Proof.
+assert (DersNilF: dersrec (KS_rules) (fun _ : Seq => False) []).
+apply dersrec_nil.
+induction k as [n IH] using (well_founded_induction_type lt_wf).
+intros s D0. remember D0 as D0'. destruct D0.
+(* D0 is a leaf *)
+- destruct f.
+(* D0 is ends with an application of rule *)
+- intros hei. split.
+{ intros prem RA. inversion RA. subst.
+  inversion k ; subst.
+  (* IdP *)
+  * inversion H. subst. assert (InT # P (Γ0 ++ Γ1)).
+    rewrite <- H2. apply InT_or_app. right. apply InT_eq. assert (InT # P (Γ0 ++ A :: Γ1)).
+    apply InT_app_or in H0. destruct H0. apply InT_or_app. auto. apply InT_or_app. right.
+    apply InT_cons. assumption. apply InT_split in H1. destruct H1. destruct s. rewrite e.
+    assert (InT # P (Δ0 ++ B :: Δ1)). assert (InT # P (Δ2 ++ # P :: Δ3)).
+    apply InT_or_app. right. apply InT_eq. rewrite H3 in H1. apply InT_app_or in H1.
+    destruct H1. apply InT_or_app. auto. inversion i. inversion H4. apply InT_or_app. right.
+    apply InT_cons. assumption. apply InT_split in H1. destruct H1. destruct s.
+    rewrite e0. assert (IdPRule [] (x ++ # P :: x0, x1 ++ # P :: x2)).
+    apply IdPRule_I. apply IdP in H1.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[]) (x ++ # P :: x0, x1 ++ # P :: x2) H1 DersNilF). exists d0.
+    simpl. rewrite dersrec_height_nil. lia. reflexivity.
+  (* BotL *)
+  * inversion H. subst. assert (InT (Bot) (Γ0 ++ Γ1)).
+    rewrite <- H2. apply InT_or_app. right. apply InT_eq. assert (InT (Bot) (Γ0 ++ A :: Γ1)).
+    apply InT_app_or in H0. destruct H0. apply InT_or_app. auto. apply InT_or_app. right.
+    apply InT_cons. assumption. apply InT_split in H1. destruct H1. destruct s. rewrite e.
+    assert (BotLRule [] (x ++ Bot :: x0, Δ0 ++ B :: Δ1)).
+    apply BotLRule_I. apply BotL in H1.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[]) (x ++ Bot :: x0, Δ0 ++ B :: Δ1) H1 DersNilF). exists d0.
+    simpl. rewrite dersrec_height_nil. lia. reflexivity.
+  (* ImpR *)
+  * inversion H. subst. apply app2_find_hole in H3. destruct H3. repeat destruct s ; destruct p ; subst.
+    + inversion e0. subst. assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+      pose (@dersrec_derrec_height (dersrec_height d) _ _ _ _ d J30). destruct s.
+      assert (J1: list_exch_L (Γ2 ++ A0 :: Γ3, Δ2 ++ B0 :: Δ3) (A0 :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3)).
+      assert (Γ2 ++ A0 :: Γ3 = [] ++ [] ++ Γ2 ++ [A0] ++ Γ3). reflexivity.
+      rewrite H0. clear H0.
+      assert (A0 :: Γ0 ++ Γ1 = [] ++ [A0] ++ Γ2 ++ [] ++ Γ3). simpl. rewrite H2. reflexivity.
+      rewrite H0. clear H0. apply list_exch_LI.
+      assert (J20: derrec_height x0 = derrec_height x0). reflexivity.
+      pose (KS_hpadm_list_exch_L0 _ _ x0 J20 _ J1). destruct s.
+      assert (J2: list_exch_L (A0 :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3) (Γ0 ++ A0 :: Γ1, Δ2 ++ B0 :: Δ3)).
+      assert ((A0 :: Γ0 ++ Γ1, Δ2 ++ B0 :: Δ3) = ([] ++ [A0] ++ Γ0 ++ [] ++ Γ1, Δ2 ++ B0 :: Δ3)).
+      reflexivity. assert ((Γ0 ++ A0 :: Γ1, Δ2 ++ B0 :: Δ3) = ([] ++ [] ++ Γ0 ++ [A0] ++ Γ1, Δ2 ++ B0 :: Δ3)).
+      reflexivity. rewrite H1. rewrite H0. clear H1. clear H0. apply list_exch_LI.
+      assert (J21: derrec_height x1 = derrec_height x1). reflexivity.
+      pose (KS_hpadm_list_exch_L0 _ _ x1 J21 _ J2). destruct s. exists x2.
+      simpl. lia.
+    + destruct x.
+      { simpl in e0. inversion e0. subst. assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+        pose (@dersrec_derrec_height (dersrec_height d) _ _ _ _ d J30). destruct s.
+        assert (J1: list_exch_L (Γ2 ++ A :: Γ3, Δ2 ++ B :: Δ1) (A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ1)).
+        assert (Γ2 ++ A :: Γ3 = [] ++ [] ++ Γ2 ++ [A] ++ Γ3). reflexivity.
+        rewrite H0. clear H0.
+        assert (A :: Γ0 ++ Γ1 = [] ++ [A] ++ Γ2 ++ [] ++ Γ3). simpl. rewrite H2. reflexivity.
+        rewrite H0. clear H0. apply list_exch_LI.
+        assert (J20: derrec_height x = derrec_height x). reflexivity.
+        pose (KS_hpadm_list_exch_L0 _ _ x J20 _ J1). destruct s.
+        assert (J2: list_exch_L (A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ1) (Γ0 ++ A :: Γ1, (Δ2 ++ []) ++ B :: Δ1)).
+        assert ((A :: Γ0 ++ Γ1, Δ2 ++ B :: Δ1) = ([] ++ [A] ++ Γ0 ++ [] ++ Γ1, Δ2 ++ B :: Δ1)).
+        reflexivity. assert ((Γ0 ++ A :: Γ1, (Δ2 ++ []) ++ B :: Δ1) = ([] ++ [] ++ Γ0 ++ [A] ++ Γ1, Δ2 ++ B :: Δ1)).
+        rewrite app_nil_r. reflexivity. rewrite H1. rewrite H0. clear H1. clear H0. apply list_exch_LI.
+        assert (J21: derrec_height x0 = derrec_height x0). reflexivity.
+        pose (KS_hpadm_list_exch_L0 _ _ x0 J21 _ J2). destruct s. exists x1.
+        simpl. lia. }
+      { inversion e0. subst. assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+        pose (@dersrec_derrec_height (dersrec_height d) _ _ _ _ d J30). destruct s.
+        assert (J1: list_exch_L (Γ2 ++ A0 :: Γ3, Δ2 ++ B0 :: x ++ A --> B :: Δ1) (A0 :: Γ0 ++ Γ1, Δ2 ++ B0 :: x ++ A --> B :: Δ1)).
+        assert (Γ2 ++ A0 :: Γ3 = [] ++ [] ++ Γ2 ++ [A0] ++ Γ3). reflexivity.
+        rewrite H0. clear H0.
+        assert (A0 :: Γ0 ++ Γ1 = [] ++ [A0] ++ Γ2 ++ [] ++ Γ3). simpl. rewrite H2. reflexivity.
+        rewrite H0. clear H0. apply list_exch_LI.
+        assert (J20: derrec_height x0 = derrec_height x0). reflexivity.
+        pose (KS_hpadm_list_exch_L0 _ _ x0 J20 _ J1). destruct s. simpl in IH. simpl.
+        assert (J2: derrec_height x1 < S (dersrec_height d)). lia.
+        assert (J3: derrec_height x1 = derrec_height x1). reflexivity.
+        assert (J4: ImpRRule [(A0 :: Γ0 ++ A :: Γ1, Δ2 ++ B0 :: x ++ B :: Δ1)] (A0 :: Γ0 ++ Γ1, Δ2 ++ B0 :: x ++ A --> B :: Δ1)).
+        assert (A0 :: Γ0 ++ A :: Γ1 = (A0 :: Γ0) ++ A :: Γ1). reflexivity. rewrite H0. clear H0.
+        assert (A0 :: Γ0 ++ Γ1 = (A0 :: Γ0) ++ Γ1). reflexivity. rewrite H0. clear H0.
+        assert (Δ2 ++ B0 :: x ++ B :: Δ1 = (Δ2 ++ B0 :: x) ++ B :: Δ1). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Δ2 ++ B0 :: x ++ A --> B :: Δ1 = (Δ2 ++ B0 :: x) ++ A --> B :: Δ1). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0. apply ImpRRule_I.
+        pose (IH _ J2 _ _ J3). destruct p. pose (s _ J4). clear s0. destruct s1. clear s.
+        assert (existsT2 (x3 : derrec KS_rules (fun _ : Seq => False)
+        (Γ0 ++ A :: Γ1, (Δ2 ++ A0 --> B0 :: x) ++ B :: Δ1)), derrec_height x3 <= S (dersrec_height d)).
+        assert (ImpRRule [(A0 :: Γ0 ++ A :: Γ1, Δ2 ++ B0 :: x ++ B :: Δ1)] (Γ0 ++ A :: Γ1, (Δ2 ++ A0 --> B0 :: x) ++ B :: Δ1)).
+        assert (A0 :: Γ0 ++ A :: Γ1 = [] ++ A0 :: Γ0 ++ A :: Γ1). reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ A :: Γ1 = [] ++ Γ0 ++ A :: Γ1). reflexivity. rewrite H0. clear H0. repeat rewrite <- app_assoc.
+        apply ImpRRule_I. apply ImpR in H0 ; try intro ; try apply f0 ; try auto ; try assumption.
+        pose (dlCons x2 DersNilF).
+        pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[(A0 :: Γ0 ++ A :: Γ1, Δ2 ++ B0 :: x ++ B :: Δ1)]) (Γ0 ++ A :: Γ1, (Δ2 ++ A0 --> B0 :: x) ++ B :: Δ1) H0 d0).
+        exists d1. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+        destruct X. exists x3. lia. }
+    + destruct x.
+      { simpl in e0. inversion e0. subst. assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+        pose (@dersrec_derrec_height (dersrec_height d) _ _ _ _ d J30). destruct s.
+        assert (J1: list_exch_L (Γ2 ++ A0 :: Γ3, (Δ0 ++ []) ++ B0 :: Δ3) (A0 :: Γ0 ++ Γ1, Δ0 ++ B0 :: Δ3)).
+        rewrite app_nil_r.
+        assert (Γ2 ++ A0 :: Γ3 = [] ++ [] ++ Γ2 ++ [A0] ++ Γ3). reflexivity.
+        rewrite H0. clear H0.
+        assert (A0 :: Γ0 ++ Γ1 = [] ++ [A0] ++ Γ2 ++ [] ++ Γ3). simpl. rewrite H2. reflexivity.
+        rewrite H0. clear H0. apply list_exch_LI.
+        assert (J20: derrec_height x = derrec_height x). reflexivity.
+        pose (KS_hpadm_list_exch_L0 _ _ x J20 _ J1). destruct s.
+        assert (J2: list_exch_L (A0 :: Γ0 ++ Γ1, Δ0 ++ B0 :: Δ3) (Γ0 ++ A0 :: Γ1, Δ0 ++ B0 :: Δ3)).
+        assert ((A0 :: Γ0 ++ Γ1, Δ0 ++ B0 :: Δ3) = ([] ++ [A0] ++ Γ0 ++ [] ++ Γ1, Δ0 ++ B0 :: Δ3)).
+        reflexivity. assert ((Γ0 ++ A0 :: Γ1, Δ0 ++ B0 :: Δ3) = ([] ++ [] ++ Γ0 ++ [A0] ++ Γ1, Δ0 ++ B0 :: Δ3)).
+        reflexivity. rewrite H1. rewrite H0. clear H1. clear H0. apply list_exch_LI.
+        assert (J21: derrec_height x0 = derrec_height x0). reflexivity.
+        pose (KS_hpadm_list_exch_L0 _ _ x0 J21 _ J2). destruct s. exists x1.
+        simpl. lia. }
+      { inversion e0. subst. assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+        pose (@dersrec_derrec_height (dersrec_height d) _ _ _ _ d J30). destruct s. simpl.
+        assert (J1: list_exch_L (Γ2 ++ A0 :: Γ3, (Δ0 ++ A --> B :: x) ++ B0 :: Δ3) (A0 :: Γ0 ++ Γ1, Δ0 ++ A --> B :: x ++ B0 :: Δ3)).
+        repeat rewrite <- app_assoc.
+        assert (Γ2 ++ A0 :: Γ3 = [] ++ [] ++ Γ2 ++ [A0] ++ Γ3). reflexivity.
+        rewrite H0. clear H0.
+        assert (A0 :: Γ0 ++ Γ1 = [] ++ [A0] ++ Γ2 ++ [] ++ Γ3). simpl. rewrite H2. reflexivity.
+        rewrite H0. clear H0. apply list_exch_LI.
+        assert (J20: derrec_height x0 = derrec_height x0). reflexivity.
+        pose (KS_hpadm_list_exch_L0 _ _ x0 J20 _ J1). destruct s. simpl in IH. simpl.
+        assert (J2: derrec_height x1 < S (dersrec_height d)). lia.
+        assert (J3: derrec_height x1 = derrec_height x1). reflexivity.
+        assert (J4: ImpRRule [(A0 :: Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ B0 :: Δ3)] (A0 :: Γ0 ++ Γ1, Δ0 ++ A --> B :: x ++ B0 :: Δ3)).
+        assert (A0 :: Γ0 ++ A :: Γ1 = (A0 :: Γ0) ++ A :: Γ1). reflexivity. rewrite H0. clear H0.
+        assert (A0 :: Γ0 ++ Γ1 = (A0 :: Γ0) ++ Γ1). reflexivity. rewrite H0. clear H0.
+        apply ImpRRule_I.
+        pose (IH _ J2 _ _ J3). destruct p. pose (s _ J4). clear s0. destruct s1. clear s.
+        assert (ImpRRule [(A0 :: Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ B0 :: Δ3)] (Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ A0 --> B0 :: Δ3)).
+        assert (A0 :: Γ0 ++ A :: Γ1 = [] ++ A0 :: Γ0 ++ A :: Γ1). reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ A :: Γ1 = [] ++ Γ0 ++ A :: Γ1). reflexivity. rewrite H0. clear H0. repeat rewrite <- app_assoc.
+        assert (Δ0 ++ B :: x ++ B0 :: Δ3 = (Δ0 ++ B :: x) ++ B0 :: Δ3). rewrite <- app_assoc. reflexivity.
+        rewrite H0. clear H0.
+        assert (Δ0 ++ B :: x ++ A0 --> B0 :: Δ3 = (Δ0 ++ B :: x) ++ A0 --> B0 :: Δ3). rewrite <- app_assoc. reflexivity.
+        rewrite H0. clear H0.
+        apply ImpRRule_I. apply ImpR in H0 ; try intro ; try apply f0 ; try auto ; try assumption.
+        pose (dlCons x2 DersNilF).
+        pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[(A0 :: Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ B0 :: Δ3)]) (Γ0 ++ A :: Γ1, Δ0 ++ B :: x ++ A0 --> B0 :: Δ3) H0 d0).
+        exists d1. simpl. rewrite dersrec_height_nil. lia. reflexivity. }
+  (* ImpL *)
+  * inversion H. subst. assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+    pose (@dersrec_derrec2_height (dersrec_height d) _ _ _ _ _ d J30). repeat destruct s. simpl.
+    assert (J1: ImpRRule [(A :: Γ2 ++ B0 :: Γ3, Δ0 ++ B :: Δ1)] (Γ2 ++ B0 :: Γ3, Δ2 ++ Δ3)).
+    rewrite H3. assert (A :: Γ2 ++ B0 :: Γ3 = [] ++ A :: Γ2 ++ B0 :: Γ3). reflexivity.
+    rewrite H0. clear H0. assert (Γ2 ++ B0 :: Γ3 = [] ++ Γ2 ++ B0 :: Γ3). reflexivity.
+    rewrite H0. clear H0. apply ImpRRule_I. simpl in IH.
+    assert (J2: derrec_height x0 < S (dersrec_height d)). lia.
+    assert (J3: derrec_height x0 = derrec_height x0). reflexivity.
+    pose (IH _ J2 _ _ J3). destruct p. clear s0. pose (s _ J1). destruct s0. clear s.
+    assert (J7: list_exch_R (Γ2 ++ Γ3, Δ2 ++ A0 :: Δ3) (Γ2 ++ Γ3, A0 :: Δ0 ++ A --> B :: Δ1)).
+    rewrite <- H3. assert (Δ2 ++ A0 :: Δ3 = [] ++ [] ++ Δ2 ++ [A0] ++ Δ3). reflexivity.
+    rewrite H0. clear H0. assert (A0 :: Δ2 ++ Δ3 = [] ++ [A0] ++ Δ2 ++ [] ++ Δ3). reflexivity.
+    rewrite H0. clear H0. apply list_exch_RI.
+    assert (J8: derrec_height x = derrec_height x). reflexivity.
+    pose (KS_hpadm_list_exch_R0 _ _ x J8 _ J7). destruct s.
+    assert (J4: ImpRRule [(A :: Γ2 ++ Γ3, A0 :: Δ0 ++ B :: Δ1)] (Γ2 ++ Γ3, A0 :: Δ0 ++ A --> B :: Δ1)).
+    assert (A :: Γ2 ++ Γ3 = [] ++ A :: Γ2 ++ Γ3). reflexivity.
+    rewrite H0. clear H0. assert ((Γ2 ++ Γ3, A0 :: Δ0 ++ A --> B :: Δ1) = ([] ++ Γ2 ++ Γ3, A0 :: Δ0 ++ A --> B :: Δ1)). reflexivity.
+    rewrite H0. clear H0. assert (A0 :: Δ0 ++ B :: Δ1 = (A0 :: Δ0) ++ B :: Δ1). reflexivity.
+    rewrite H0. clear H0. assert (A0 :: Δ0 ++ A --> B :: Δ1 = (A0 :: Δ0) ++ A --> B :: Δ1). reflexivity.
+    rewrite H0. clear H0. apply ImpRRule_I. simpl in IH.
+    assert (J5: derrec_height x2 < S (dersrec_height d)). lia.
+    assert (J6: derrec_height x2 = derrec_height x2). reflexivity.
+    pose (IH _ J5 _ _ J6). destruct p. clear s0. pose (s _ J4). destruct s0. clear s.
+    assert (ImpLRule [(A :: Γ2 ++ Γ3, A0 :: Δ0 ++ B :: Δ1); (A :: Γ2 ++ B0 :: Γ3, Δ0 ++ B :: Δ1)]
+    (A :: Γ2 ++ A0 --> B0 :: Γ3, Δ0 ++ B :: Δ1)).
+    assert (A :: Γ2 ++ Γ3 = (A :: Γ2) ++ Γ3). reflexivity. rewrite H0. clear H0.
+    assert (A :: Γ2 ++ B0 :: Γ3 = (A :: Γ2) ++ B0 :: Γ3). reflexivity. rewrite H0. clear H0.
+    assert (A :: Γ2 ++ A0 --> B0 :: Γ3 = (A :: Γ2) ++ A0 --> B0 :: Γ3). reflexivity. rewrite H0. clear H0.
+    assert (Δ0 ++ B :: Δ1 = [] ++ Δ0 ++ B :: Δ1). reflexivity. rewrite H0. clear H0.
+    assert (A0 :: [] ++ Δ0 ++ B :: Δ1 = [] ++ A0 :: Δ0 ++ B :: Δ1). reflexivity. rewrite H0. clear H0.
+    apply ImpLRule_I. pose (dlCons x1 DersNilF). pose (dlCons x3 d0).
+    apply ImpL in H0.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[(A :: Γ2 ++ Γ3, A0 :: Δ0 ++ B :: Δ1); (A :: Γ2 ++ B0 :: Γ3, Δ0 ++ B :: Δ1)])
+    (A :: Γ2 ++ A0 --> B0 :: Γ3, Δ0 ++ B :: Δ1) H0 d1).
+    assert (J40: list_exch_L (A :: Γ2 ++ A0 --> B0 :: Γ3, Δ0 ++ B :: Δ1) (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)).
+    rewrite H2. assert (A :: Γ0 ++ Γ1 = [] ++ [A] ++ Γ0 ++ [] ++ Γ1). reflexivity. rewrite H1. clear H1.
+    assert (Γ0 ++ A :: Γ1 = [] ++ [] ++ Γ0 ++ [A] ++ Γ1). reflexivity. rewrite H1. clear H1.
+    apply list_exch_LI.
+    assert (J41: derrec_height d2 = derrec_height d2). reflexivity.
+    pose (KS_hpadm_list_exch_L0 _ _ d2 J41 _ J40). destruct s. exists x4. simpl in J41.
+    simpl in l2. rewrite dersrec_height_nil in l2. lia. reflexivity.
+  (* KR *)
+  * inversion X. subst.
+    assert (KRRule [(unboxed_list , [A0])] (Γ0 ++ Γ1, Δ0 ++ Δ1)).
+    assert (In (Box A0) (Δ0 ++ Δ1)).
+    assert (InT (Box A0) (Δ2 ++ Box A0 :: Δ3)). apply InT_or_app. right. apply InT_eq.
+    rewrite H2 in H. apply InT_app_or in H. apply in_or_app. destruct H. apply InT_In in i. auto.
+    inversion i. inversion H0. apply InT_In in H0. auto.
+    apply in_splitT in H. destruct H. destruct s. rewrite e. apply KRRule_I ; try assumption.
+    simpl. simpl in IH.
+    apply KR in X1.
+    assert (dersrec_height d = dersrec_height d). reflexivity.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[(unboxed_list , [A0])]) (Γ0 ++ Γ1, Δ0 ++ Δ1) X1 d).
+    assert (J1: wkn_L A (Γ0 ++ Γ1, Δ0 ++ Δ1) (Γ0 ++ A :: Γ1, Δ0 ++ Δ1)).
+    apply wkn_LI.
+    assert (J2: derrec_height d0 = derrec_height d0). reflexivity.
+    pose (KS_wkn_L _ _ d0 J2 _ _ J1). destruct s.
+    assert (J3: wkn_R B (Γ0 ++ A :: Γ1, Δ0 ++ Δ1) (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)).
+    apply wkn_RI.
+    assert (J4: derrec_height x = derrec_height x). reflexivity.
+    pose (KS_wkn_R _ _ x J4 _ _ J3). destruct s. exists x0.
+    pose (Nat.le_trans _ _ _ l0 l). simpl in l1. assumption. }
+{ intros prem1 prem2 RA. inversion RA. subst.
+  inversion k ; subst.
+  (* IdP *)
+  * inversion H. subst. assert (InT # P (Γ0 ++ Γ1)). assert (InT # P (Γ2 ++ # P :: Γ3)).
+    apply InT_or_app. right. apply InT_eq. rewrite H2 in H0. apply InT_or_app.
+    apply InT_app_or in H0. destruct H0. auto. inversion i. inversion H1.
+    auto. assert (InT # P (Γ0 ++ B :: Γ1)).
+    apply InT_app_or in H0. apply InT_or_app. destruct H0. auto. right. apply InT_cons.
+    assumption. apply InT_split in H1. destruct H1. destruct s. apply InT_split in H0. destruct H0.
+    destruct s. rewrite e0. rewrite e. assert (In # P (Δ0 ++ A :: Δ1)). assert (In # P (Δ0 ++ Δ1)).
+    rewrite <- H3. apply in_or_app. right. apply in_eq. apply in_app_or in H0. apply in_or_app.
+    destruct H0. auto. right. apply in_cons. assumption. apply in_splitT in H0. destruct H0.
+    destruct s. rewrite e1.
+    assert (IdPRule [] (x1 ++ # P :: x2, x3 ++ # P :: x4)).
+    apply IdPRule_I. apply IdP in H0.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[]) (x1 ++ # P :: x2, x3 ++ # P :: x4) H0 DersNilF). exists d0.
+    assert (IdPRule [] (x ++ # P :: x0, Δ0 ++ Δ1)). rewrite <- H3.
+    apply IdPRule_I. apply IdP in H1.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[]) (x ++ # P :: x0, Δ0 ++ Δ1) H1 DersNilF). exists d1.
+    simpl. rewrite dersrec_height_nil. split ; lia. reflexivity.
+  (* BotL *)
+  * inversion H. subst. assert (InT (Bot) (Γ0 ++ Γ1)). assert (InT (Bot) (Γ2 ++ (Bot) :: Γ3)).
+    apply InT_or_app. right. apply InT_eq. rewrite H2 in H0. apply InT_app_or in H0.
+    apply InT_or_app. destruct H0. auto. inversion i. inversion H1. auto. assert (InT (Bot) (Γ0 ++ B :: Γ1)).
+    apply InT_app_or in H0. apply InT_or_app. destruct H0. auto. right. apply InT_cons.
+    assumption. apply InT_split in H0. destruct H0. destruct s. apply InT_split in H1. destruct H1.
+    destruct s. rewrite e0. rewrite e.
+    assert (BotLRule [] (x ++ Bot :: x0, Δ0 ++ A :: Δ1)).
+    apply BotLRule_I. apply BotL in H0.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[]) (x ++ Bot :: x0, Δ0 ++ A :: Δ1) H0 DersNilF). exists d0.
+    assert (BotLRule [] (x1 ++ Bot :: x2, Δ0 ++ Δ1)).
+    apply BotLRule_I. apply BotL in H1.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[]) (x1 ++ Bot :: x2, Δ0 ++ Δ1) H1 DersNilF). exists d1.
+    simpl. rewrite dersrec_height_nil. split ; lia. reflexivity.
+  (* ImpR *)
+  * inversion H. subst. simpl in IH.
+    assert (J0: (dersrec_height d) = (dersrec_height d)). reflexivity.
+    pose (dersrec_derrec_height d J0). destruct s.
+    apply app2_find_hole in H2. destruct H2. repeat destruct s ; destruct p ; subst.
+    + assert (ImpLRule [(Γ2 ++ A0 :: Γ1, A :: Δ2 ++ B0 :: Δ3) ; (Γ2 ++ A0 :: B :: Γ1, Δ2 ++ B0 :: Δ3)]
+      (Γ2 ++ A0 :: A --> B :: Γ1, Δ2 ++ B0 :: Δ3)). assert (Γ2 ++ A0 :: Γ1 = (Γ2 ++ [A0]) ++ Γ1).
+      rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ A0 :: B :: Γ1 = (Γ2 ++ [A0]) ++ B :: Γ1). rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. assert (Γ2 ++ A0 :: A --> B :: Γ1 = (Γ2 ++ [A0]) ++ A --> B :: Γ1). rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. assert (Δ2 ++ B0 :: Δ3 = [] ++ Δ2 ++ B0 :: Δ3).
+      reflexivity. rewrite H0. clear H0. assert (A :: [] ++ Δ2 ++ B0 :: Δ3 = [] ++ A :: Δ2 ++ B0 :: Δ3).
+      reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+      assert (J1: derrec_height x < S (dersrec_height d)). lia.
+      assert (J2: derrec_height x = derrec_height x). reflexivity.
+      pose (IH (derrec_height x) J1 _ x J2). destruct p. clear s.
+      pose (s0 _ _ H0). repeat destruct s. clear s0. destruct p.
+      assert (ImpRRule [(Γ2 ++ A0 :: Γ1, A :: Δ2 ++ B0 :: Δ3)] (Γ2 ++ Γ1, A :: Δ0 ++ Δ1)).
+      rewrite <- H3. assert (A :: Δ2 ++ B0 :: Δ3 = (A :: Δ2) ++ B0 :: Δ3). reflexivity.
+      rewrite H1. clear H1. assert (A :: Δ2 ++ A0 --> B0 :: Δ3 = (A :: Δ2) ++ A0 --> B0 :: Δ3). reflexivity.
+      rewrite H1. clear H1. apply ImpRRule_I.
+      assert (existsT2 (x3: derrec KS_rules (fun _ : Seq => False)
+      (Γ2 ++ Γ1, A :: Δ0 ++ Δ1)), derrec_height x3 <= S (dersrec_height d)).
+      apply ImpR in H1.
+      pose (dlCons x1 DersNilF). pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[(Γ2 ++ A0 :: Γ1, A :: Δ2 ++ B0 :: Δ3)]) (Γ2 ++ Γ1, A :: Δ0 ++ Δ1) H1 d0).
+      exists d1. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+      destruct X.
+      assert (J3: derrec_height x3 = derrec_height x3). reflexivity.
+      assert (J4: list_exch_R (Γ2 ++ Γ1, A :: Δ0 ++ Δ1) (Γ2 ++ Γ1, Δ0 ++ A :: Δ1)).
+      assert (A :: Δ0 ++ Δ1 = [] ++ [A] ++ Δ0 ++ [] ++ Δ1). reflexivity. rewrite H2. clear H2.
+      assert (Δ0 ++ A :: Δ1 = [] ++ [] ++ Δ0 ++ [A] ++ Δ1). reflexivity. rewrite H2. clear H2.
+      apply list_exch_RI. pose (KS_hpadm_list_exch_R0 _ _ x3 J3 _ J4). destruct s. exists x4.
+      assert (ImpRRule [(Γ2 ++ A0 :: B :: Γ1, Δ2 ++ B0 :: Δ3)] (Γ2 ++ B :: Γ1, Δ0 ++ Δ1)).
+      rewrite <- H3. apply ImpRRule_I.
+      assert (existsT2 (x3: derrec KS_rules (fun _ : Seq => False)
+      (Γ2 ++ B :: Γ1, Δ0 ++ Δ1)), derrec_height x3 <= S (dersrec_height d)).
+      apply ImpR in H2.
+      pose (dlCons x2 DersNilF). pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[(Γ2 ++ A0 :: B :: Γ1, Δ2 ++ B0 :: Δ3)]) (Γ2 ++ B :: Γ1, Δ0 ++ Δ1) H2 d0).
+      exists d1. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+      destruct X. exists x5. simpl. split. lia. lia.
+    + assert (ImpLRule [(Γ2 ++ A0 :: x0 ++ Γ1, A :: Δ2 ++ B0 :: Δ3) ; (Γ2 ++ A0 :: x0 ++ B :: Γ1, Δ2 ++ B0 :: Δ3)]
+      (Γ2 ++ A0 :: x0 ++ A --> B :: Γ1, Δ2 ++ B0 :: Δ3)). assert (Γ2 ++ A0 :: x0 ++ Γ1 = (Γ2 ++ A0 :: x0) ++ Γ1).
+      rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+      assert (Γ2 ++ A0 :: x0 ++ B :: Γ1 = (Γ2 ++ A0 :: x0) ++ B :: Γ1). rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. assert (Γ2 ++ A0 :: x0 ++ A --> B :: Γ1 = (Γ2 ++ A0 :: x0) ++ A --> B :: Γ1). rewrite <- app_assoc. reflexivity.
+      rewrite H0. clear H0. assert (Δ2 ++ B0 :: Δ3 = [] ++ Δ2 ++ B0 :: Δ3).
+      reflexivity. rewrite H0. clear H0. assert (A :: [] ++ Δ2 ++ B0 :: Δ3 = [] ++ A :: Δ2 ++ B0 :: Δ3).
+      reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+      assert (J1: derrec_height x < S (dersrec_height d)). lia.
+      assert (J2: derrec_height x = derrec_height x). reflexivity.
+      pose (IH (derrec_height x) J1 _ x J2). destruct p. clear s.
+      pose (s0 _ _ H0). repeat destruct s. clear s0. destruct p.
+      assert (ImpRRule [(Γ2 ++ A0 :: x0 ++ Γ1, A :: Δ2 ++ B0 :: Δ3)] ((Γ2 ++ x0) ++ Γ1, A :: Δ0 ++ Δ1)).
+      rewrite <- H3. assert (A :: Δ2 ++ B0 :: Δ3 = (A :: Δ2) ++ B0 :: Δ3). reflexivity.
+      rewrite H1. clear H1. assert (A :: Δ2 ++ A0 --> B0 :: Δ3 = (A :: Δ2) ++ A0 --> B0 :: Δ3). reflexivity.
+      rewrite H1. clear H1. rewrite <- app_assoc. apply ImpRRule_I.
+      assert (existsT2 (x3: derrec KS_rules (fun _ : Seq => False)
+      ((Γ2 ++ x0) ++ Γ1, A :: Δ0 ++ Δ1)), derrec_height x3 <= S (dersrec_height d)).
+      apply ImpR in H1.
+      pose (dlCons x1 DersNilF). pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[(Γ2 ++ A0 :: x0 ++ Γ1, A :: Δ2 ++ B0 :: Δ3)]) ((Γ2 ++ x0) ++ Γ1, A :: Δ0 ++ Δ1) H1 d0).
+      exists d1. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+      destruct X.
+      assert (J3: derrec_height x3 = derrec_height x3). reflexivity.
+      assert (J4: list_exch_R ((Γ2 ++ x0) ++ Γ1, A :: Δ0 ++ Δ1) ((Γ2 ++ x0) ++ Γ1, Δ0 ++ A :: Δ1)).
+      assert (A :: Δ0 ++ Δ1 = [] ++ [A] ++ Δ0 ++ [] ++ Δ1). reflexivity. rewrite H2. clear H2.
+      assert (Δ0 ++ A :: Δ1 = [] ++ [] ++ Δ0 ++ [A] ++ Δ1). reflexivity. rewrite H2. clear H2.
+      apply list_exch_RI. pose (KS_hpadm_list_exch_R0 _ _ x3 J3 _ J4). destruct s. exists x4.
+      assert (ImpRRule [(Γ2 ++ A0 :: x0 ++ B :: Γ1, Δ2 ++ B0 :: Δ3)] ((Γ2 ++ x0) ++ B :: Γ1, Δ0 ++ Δ1)).
+      rewrite <- H3. rewrite <- app_assoc. apply ImpRRule_I.
+      assert (existsT2 (x3: derrec KS_rules (fun _ : Seq => False)
+      ((Γ2 ++ x0) ++ B :: Γ1, Δ0 ++ Δ1)), derrec_height x3 <= S (dersrec_height d)).
+      apply ImpR in H2.
+      pose (dlCons x2 DersNilF). pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[(Γ2 ++ A0 :: x0 ++ B :: Γ1, Δ2 ++ B0 :: Δ3)]) ((Γ2 ++ x0) ++ B :: Γ1, Δ0 ++ Δ1) H2 d0).
+      exists d1. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+      destruct X. exists x5. simpl. split. lia. lia.
+    + destruct x0.
+      { simpl in e1. subst. assert (ImpLRule [(Γ0 ++ A0 :: Γ1, A :: Δ2 ++ B0 :: Δ3) ; (Γ0 ++ A0 :: B :: Γ1, Δ2 ++ B0 :: Δ3)]
+        ((Γ0 ++ []) ++ A0 :: A --> B :: Γ1, Δ2 ++ B0 :: Δ3)). rewrite app_nil_r. assert (Γ0 ++ A0 :: Γ1 = (Γ0 ++ [A0]) ++ Γ1).
+        rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ A0 :: B :: Γ1 = (Γ0 ++ [A0]) ++ B :: Γ1). rewrite <- app_assoc. reflexivity.
+        rewrite H0. clear H0. assert (Γ0 ++ A0 :: A --> B :: Γ1 = (Γ0 ++ [A0]) ++ A --> B :: Γ1). rewrite <- app_assoc. reflexivity.
+        rewrite H0. clear H0. assert (Δ2 ++ B0 :: Δ3 = [] ++ Δ2 ++ B0 :: Δ3).
+        reflexivity. rewrite H0. clear H0. assert (A :: [] ++ Δ2 ++ B0 :: Δ3 = [] ++ A :: Δ2 ++ B0 :: Δ3).
+        reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+        assert (J1: derrec_height x < S (dersrec_height d)). lia.
+        assert (J2: derrec_height x = derrec_height x). reflexivity.
+        pose (IH (derrec_height x) J1 _ x J2). destruct p. clear s.
+        pose (s0 _ _ H0). repeat destruct s. clear s0. destruct p.
+        assert (ImpRRule [(Γ0 ++ A0 :: Γ1, A :: Δ2 ++ B0 :: Δ3)] (Γ0 ++ Γ1, A :: Δ0 ++ Δ1)).
+        rewrite <- H3. assert (A :: Δ2 ++ B0 :: Δ3 = (A :: Δ2) ++ B0 :: Δ3). reflexivity.
+        rewrite H1. clear H1. assert (A :: Δ2 ++ A0 --> B0 :: Δ3 = (A :: Δ2) ++ A0 --> B0 :: Δ3). reflexivity.
+        rewrite H1. clear H1. apply ImpRRule_I.
+        assert (existsT2 (x3: derrec KS_rules (fun _ : Seq => False)
+        (Γ0 ++ Γ1, A :: Δ0 ++ Δ1)), derrec_height x3 <= S (dersrec_height d)).
+        apply ImpR in H1.
+        pose (dlCons x0 DersNilF). pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[(Γ0 ++ A0 :: Γ1, A :: Δ2 ++ B0 :: Δ3)]) (Γ0 ++ Γ1, A :: Δ0 ++ Δ1) H1 d0).
+        exists d1. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+        destruct X.
+        assert (J3: derrec_height x2 = derrec_height x2). reflexivity.
+        assert (J4: list_exch_R (Γ0 ++ Γ1, A :: Δ0 ++ Δ1) (Γ0 ++ Γ1, Δ0 ++ A :: Δ1)).
+        assert (A :: Δ0 ++ Δ1 = [] ++ [A] ++ Δ0 ++ [] ++ Δ1). reflexivity. rewrite H2. clear H2.
+        assert (Δ0 ++ A :: Δ1 = [] ++ [] ++ Δ0 ++ [A] ++ Δ1). reflexivity. rewrite H2. clear H2.
+        apply list_exch_RI. pose (KS_hpadm_list_exch_R0 _ _ x2 J3 _ J4). destruct s. exists x3.
+        assert (ImpRRule [(Γ0 ++ A0 :: B :: Γ1, Δ2 ++ B0 :: Δ3)] (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)).
+        rewrite <- H3. apply ImpRRule_I.
+        assert (existsT2 (x3: derrec KS_rules (fun _ : Seq => False)
+        (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)), derrec_height x3 <= S (dersrec_height d)).
+        apply ImpR in H2.
+        pose (dlCons x1 DersNilF). pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[(Γ0 ++ A0 :: B :: Γ1, Δ2 ++ B0 :: Δ3)]) (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) H2 d0).
+        exists d1. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+        destruct X. exists x4. simpl. split. lia. lia. }
+        { inversion e1. subst. assert (ImpLRule [(Γ0 ++ x0 ++ A0 :: Γ3, A :: Δ2 ++ B0 :: Δ3) ; (Γ0 ++ B :: x0 ++ A0 :: Γ3, Δ2 ++ B0 :: Δ3)]
+          ((Γ0 ++ A --> B :: x0) ++ A0 :: Γ3, Δ2 ++ B0 :: Δ3)). rewrite <- app_assoc.
+          assert (Δ2 ++ B0 :: Δ3 = [] ++ Δ2 ++ B0 :: Δ3). reflexivity. rewrite H0. clear H0.
+          assert (A :: [] ++ Δ2 ++ B0 :: Δ3 = [] ++ A :: Δ2 ++ B0 :: Δ3). reflexivity. rewrite H0.
+          clear H0. apply ImpLRule_I.
+          assert (J1: derrec_height x < S (dersrec_height d)). lia.
+          assert (J2: derrec_height x = derrec_height x). reflexivity.
+          pose (IH (derrec_height x) J1 _ x J2). destruct p. clear s.
+          pose (s0 _ _ H0). repeat destruct s. clear s0. destruct p.
+          assert (ImpRRule [(Γ0 ++ x0 ++ A0 :: Γ3, A :: Δ2 ++ B0 :: Δ3)] (Γ0 ++ x0 ++ Γ3, A :: Δ0 ++ Δ1)).
+          rewrite <- H3. assert (A :: Δ2 ++ B0 :: Δ3 = (A :: Δ2) ++ B0 :: Δ3). reflexivity.
+          rewrite H1. clear H1. assert (A :: Δ2 ++ A0 --> B0 :: Δ3 = (A :: Δ2) ++ A0 --> B0 :: Δ3). reflexivity.
+          rewrite H1. clear H1. assert (Γ0 ++ x0 ++ A0 :: Γ3 = (Γ0 ++ x0) ++ A0 :: Γ3). rewrite <- app_assoc.
+          reflexivity. rewrite H1. clear H1. assert (Γ0 ++ x0 ++ Γ3 = (Γ0 ++ x0) ++ Γ3). rewrite <- app_assoc.
+          reflexivity. rewrite H1. clear H1. apply ImpRRule_I.
+          assert (existsT2 (x3: derrec KS_rules (fun _ : Seq => False)
+          (Γ0 ++ x0 ++ Γ3, A :: Δ0 ++ Δ1)), derrec_height x3 <= S (dersrec_height d)).
+          apply ImpR in H1.
+          pose (dlCons x1 DersNilF). pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[(Γ0 ++ x0 ++ A0 :: Γ3, A :: Δ2 ++ B0 :: Δ3)]) (Γ0 ++ x0 ++ Γ3, A :: Δ0 ++ Δ1) H1 d0).
+          exists d1. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+          destruct X.
+          assert (J3: derrec_height x3 = derrec_height x3). reflexivity.
+          assert (J4: list_exch_R (Γ0 ++ x0 ++ Γ3, A :: Δ0 ++ Δ1) (Γ0 ++ x0 ++ Γ3, Δ0 ++ A :: Δ1)).
+          assert (A :: Δ0 ++ Δ1 = [] ++ [A] ++ Δ0 ++ [] ++ Δ1). reflexivity. rewrite H2. clear H2.
+          assert (Δ0 ++ A :: Δ1 = [] ++ [] ++ Δ0 ++ [A] ++ Δ1). reflexivity. rewrite H2. clear H2.
+          apply list_exch_RI. pose (KS_hpadm_list_exch_R0 _ _ x3 J3 _ J4). destruct s. exists x4.
+          assert (ImpRRule [(Γ0 ++ B :: x0 ++ A0 :: Γ3, Δ2 ++ B0 :: Δ3)] (Γ0 ++ B :: x0 ++ Γ3, Δ0 ++ Δ1)).
+          rewrite <- H3. assert (Γ0 ++ B :: x0 ++ A0 :: Γ3 = (Γ0 ++ B :: x0) ++ A0 :: Γ3). rewrite <- app_assoc.
+          reflexivity. rewrite H2. clear H2. assert (Γ0 ++ B :: x0 ++ Γ3 = (Γ0 ++ B :: x0) ++ Γ3). rewrite <- app_assoc.
+          reflexivity. rewrite H2. clear H2. apply ImpRRule_I.
+          assert (existsT2 (x3: derrec KS_rules (fun _ : Seq => False)
+          (Γ0 ++ B :: x0 ++ Γ3, Δ0 ++ Δ1)), derrec_height x3 <= S (dersrec_height d)).
+          apply ImpR in H2.
+          pose (dlCons x2 DersNilF). pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[(Γ0 ++ B :: x0 ++ A0 :: Γ3, Δ2 ++ B0 :: Δ3)]) (Γ0 ++ B :: x0 ++ Γ3, Δ0 ++ Δ1) H2 d0).
+          exists d1. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+          destruct X. exists x5. simpl. split. lia. lia. }
+  (* ImpL *)
+  * inversion H. subst.
+    apply app2_find_hole in H2. destruct H2. repeat destruct s ; destruct p ; subst.
+    + inversion e0. subst. assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+      pose (@dersrec_derrec2_height (dersrec_height d) _ _ _ _ _ d J30). repeat destruct s.
+      assert (J1: list_exch_R (Γ2 ++ Γ3, Δ2 ++ A0 :: Δ3) (Γ2 ++ Γ3, A0 :: Δ0 ++ Δ1)).
+      assert (Δ2 ++ A0 :: Δ3 = [] ++ [] ++ Δ2 ++ [A0] ++ Δ3). reflexivity.
+      rewrite H0. clear H0.
+      assert (A0 :: Δ0 ++ Δ1 = [] ++ [A0] ++ Δ2 ++ [] ++ Δ3). simpl. rewrite H3. reflexivity.
+      rewrite H0. clear H0. apply list_exch_RI.
+      assert (J20: derrec_height x0 = derrec_height x0). reflexivity.
+      pose (KS_hpadm_list_exch_R0 _ _ x0 J20 _ J1). destruct s.
+      assert (J2: list_exch_R (Γ2 ++ Γ3, A0 :: Δ0 ++ Δ1) (Γ2 ++ Γ3, Δ0 ++ A0 :: Δ1)).
+      assert (A0 :: Δ0 ++ Δ1 = [] ++ [A0] ++ Δ0 ++ [] ++ Δ1).
+      reflexivity. assert (Δ0 ++ A0 :: Δ1 = [] ++ [] ++ Δ0 ++ [A0] ++ Δ1).
+      reflexivity. rewrite H1. rewrite H0. clear H1. clear H0. apply list_exch_RI.
+      assert (J21: derrec_height x2 = derrec_height x2). reflexivity.
+      pose (KS_hpadm_list_exch_R0 _ _ x2 J21 _ J2). destruct s. exists x3.
+      assert (existsT2 (x4: derrec KS_rules (fun _ : Seq => False) (Γ2 ++ B0 :: Γ3, Δ0 ++ Δ1)),
+      derrec_height x4 = derrec_height x1). rewrite <- H3. exists x1. reflexivity. destruct X. exists x4. split.
+       simpl. lia. simpl. lia.
+    + destruct x.
+      { simpl in e0. inversion e0. simpl. rewrite app_nil_r. subst.
+        assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+        pose (@dersrec_derrec2_height (dersrec_height d) _ _ _ _ _ d J30). repeat destruct s.
+        assert (J1: list_exch_R (Γ2 ++ Γ1, Δ2 ++ A :: Δ3) (Γ2 ++ Γ1, A :: Δ0 ++ Δ1)).
+        assert (Δ2 ++ A :: Δ3 = [] ++ [] ++ Δ2 ++ [A] ++ Δ3). reflexivity.
+        rewrite H0. clear H0.
+        assert (A :: Δ0 ++ Δ1 = [] ++ [A] ++ Δ2 ++ [] ++ Δ3). simpl. rewrite H3. reflexivity.
+        rewrite H0. clear H0. apply list_exch_RI.
+        assert (J20: derrec_height x = derrec_height x). reflexivity.
+        pose (KS_hpadm_list_exch_R0 _ _ x J20 _ J1). destruct s.
+        assert (J2: list_exch_R (Γ2 ++ Γ1, A :: Δ0 ++ Δ1) (Γ2 ++ Γ1, Δ0 ++ A :: Δ1)).
+        assert (A :: Δ0 ++ Δ1 = [] ++ [A] ++ Δ0 ++ [] ++ Δ1).
+        reflexivity. assert (Δ0 ++ A :: Δ1 = [] ++ [] ++ Δ0 ++ [A] ++ Δ1).
+        reflexivity. rewrite H1. rewrite H0. clear H1. clear H0. apply list_exch_RI.
+        assert (J21: derrec_height x1 = derrec_height x1). reflexivity.
+        pose (KS_hpadm_list_exch_R0 _ _ x1 J21 _ J2). destruct s. exists x2.
+        assert (existsT2 (x3: derrec KS_rules (fun _ : Seq => False) (Γ2 ++ B :: Γ1, Δ0 ++ Δ1)),
+        derrec_height x3 = derrec_height x0). rewrite <- H3. exists x0. reflexivity. destruct X. exists x3. split.
+        simpl. lia. simpl. lia. }
+      { inversion e0. subst. assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+        pose (@dersrec_derrec2_height (dersrec_height d) _ _ _ _ _ d J30). repeat destruct s.
+        assert (J1: list_exch_R (Γ2 ++ x ++ A --> B :: Γ1, Δ2 ++ A0 :: Δ3) (Γ2 ++ x ++ A --> B :: Γ1, A0 :: Δ0 ++ Δ1)).
+        assert (Δ2 ++ A0 :: Δ3 = [] ++ [] ++ Δ2 ++ [A0] ++ Δ3). reflexivity.
+        rewrite H0. clear H0.
+        assert (A0 :: Δ0 ++ Δ1 = [] ++ [A0] ++ Δ2 ++ [] ++ Δ3). simpl. rewrite H3. reflexivity.
+        rewrite H0. clear H0. apply list_exch_RI.
+        assert (J20: derrec_height x0 = derrec_height x0). reflexivity.
+        pose (KS_hpadm_list_exch_R0 _ _ x0 J20 _ J1). destruct s. simpl in IH. simpl.
+        assert (J2: derrec_height x2 < S (dersrec_height d)). lia.
+        assert (J3: derrec_height x2 = derrec_height x2). reflexivity.
+        assert (J4: ImpLRule [(Γ2 ++ x ++ Γ1, A0 :: Δ0 ++ A :: Δ1); (Γ2 ++ x ++ B :: Γ1, A0 :: Δ0 ++ Δ1)]
+        (Γ2 ++ x ++ A --> B :: Γ1, A0 :: Δ0 ++ Δ1)).
+        assert (A0 :: Δ0 ++ A :: Δ1 = (A0 :: Δ0) ++ A :: Δ1). reflexivity. rewrite H0. clear H0.
+        assert (A0 :: Δ0 ++ Δ1 = (A0 :: Δ0) ++ Δ1). reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ x ++ B :: Γ1 = (Γ2 ++ x) ++ B :: Γ1). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ x ++ A --> B :: Γ1 = (Γ2 ++ x) ++ A --> B :: Γ1). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ x ++ Γ1 = (Γ2 ++ x) ++ Γ1). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+        pose (IH _ J2 _ _ J3). destruct p. pose (s0 _ _ J4). clear s. destruct s1. clear s0. destruct s.
+        destruct p.
+        assert (J5: derrec_height x1 < S (dersrec_height d)). lia.
+        assert (J6: derrec_height x1 = derrec_height x1). reflexivity.
+        assert (J7: ImpLRule [(Γ2 ++ B0 :: x ++ Γ1, Δ0 ++ A :: Δ1); (Γ2 ++ B0 :: x ++ B :: Γ1, Δ0 ++ Δ1)]
+        (Γ2 ++ B0 :: x ++ A --> B :: Γ1, Δ2 ++ Δ3)). rewrite H3.
+        assert (Γ2 ++ B0 :: x ++ Γ1 = (Γ2 ++ B0 :: x) ++ Γ1). rewrite <- app_assoc. reflexivity.
+        rewrite H0. clear H0.
+        assert (Γ2 ++ B0 :: x ++ B :: Γ1 = (Γ2 ++ B0 :: x) ++ B :: Γ1). rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0.
+        assert (Γ2 ++ B0 :: x ++ A --> B :: Γ1 = (Γ2 ++ B0 :: x) ++ A --> B :: Γ1). repeat rewrite <- app_assoc.
+        reflexivity. rewrite H0. clear H0. apply ImpLRule_I.
+        pose (IH _ J5 _ _ J6). destruct p. pose (s0 _ _ J7). clear s. destruct s1. clear s0. destruct s.
+        destruct p.
+        assert (existsT2 (x7 : derrec KS_rules (fun _ : Seq => False)
+        ((Γ2 ++ A0 --> B0 :: x) ++ Γ1, Δ0 ++ A :: Δ1)), derrec_height x7 <= S (dersrec_height d)).
+        assert (ImpLRule [(Γ2 ++ x ++ Γ1, A0 :: Δ0 ++ A :: Δ1); (Γ2 ++ B0 :: x ++ Γ1, Δ0 ++ A :: Δ1)]
+        ((Γ2 ++ A0 --> B0 :: x) ++ Γ1, Δ0 ++ A :: Δ1)). rewrite <- app_assoc.
+        assert (A0 :: Δ0 ++ A :: Δ1 = [] ++ A0 :: Δ0 ++ A :: Δ1). reflexivity. rewrite H0. clear H0.
+        assert (Δ0 ++ A :: Δ1 = [] ++ Δ0 ++ A :: Δ1). reflexivity. rewrite H0. clear H0. repeat rewrite <- app_assoc.
+        apply ImpLRule_I. apply ImpL in H0.
+        pose (dlCons x5 DersNilF). pose (dlCons x3 d0).
+        pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[(Γ2 ++ x ++ Γ1, A0 :: Δ0 ++ A :: Δ1); (Γ2 ++ B0 :: x ++ Γ1, Δ0 ++ A :: Δ1)])
+        ((Γ2 ++ A0 --> B0 :: x) ++ Γ1, Δ0 ++ A :: Δ1) H0 d1).
+        exists d2. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+        destruct X. exists x7.
+        assert (existsT2 (x8 : derrec KS_rules (fun _ : Seq => False)
+        ((Γ2 ++ A0 --> B0 :: x) ++ B :: Γ1, Δ0 ++ Δ1)), derrec_height x8 <= S (dersrec_height d)).
+        assert (ImpLRule [(Γ2 ++ x ++ B :: Γ1, A0 :: Δ0 ++ Δ1); (Γ2 ++ B0 :: x ++ B :: Γ1, Δ0 ++ Δ1)]
+        ((Γ2 ++ A0 --> B0 :: x) ++ B :: Γ1, Δ0 ++ Δ1)). rewrite <- app_assoc.
+        assert (Δ0 ++ Δ1 = [] ++ Δ0 ++ Δ1). reflexivity. rewrite H0. clear H0.
+        assert (A0 :: [] ++ Δ0 ++ Δ1 = [] ++ A0 :: Δ0 ++ Δ1). reflexivity. rewrite H0. clear H0.
+        apply ImpLRule_I. apply ImpL in H0.
+        pose (dlCons x6 DersNilF). pose (dlCons x4 d0).
+        pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[(Γ2 ++ x ++ B :: Γ1, A0 :: Δ0 ++ Δ1); (Γ2 ++ B0 :: x ++ B :: Γ1, Δ0 ++ Δ1)])
+        ((Γ2 ++ A0 --> B0 :: x) ++ B :: Γ1, Δ0 ++ Δ1) H0 d1).
+        exists d2. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+        destruct X. exists x8. split. lia. lia. }
+    + destruct x.
+      { simpl in e0. inversion e0. simpl. subst.
+        assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+        pose (@dersrec_derrec2_height (dersrec_height d) _ _ _ _ _ d J30). repeat destruct s.
+        assert (J1: list_exch_R ((Γ0 ++ []) ++ Γ3, Δ2 ++ A0 :: Δ3) (Γ0 ++ Γ3, A0 :: Δ0 ++ Δ1)).
+        rewrite app_nil_r.
+        assert (Δ2 ++ A0 :: Δ3 = [] ++ [] ++ Δ2 ++ [A0] ++ Δ3). reflexivity.
+        rewrite H0. clear H0.
+        assert (A0 :: Δ0 ++ Δ1 = [] ++ [A0] ++ Δ2 ++ [] ++ Δ3). simpl. rewrite H3. reflexivity.
+        rewrite H0. clear H0. apply list_exch_RI.
+        assert (J20: derrec_height x = derrec_height x). reflexivity.
+        pose (KS_hpadm_list_exch_R0 _ _ x J20 _ J1). destruct s.
+        assert (J2: list_exch_R (Γ0 ++ Γ3, A0 :: Δ0 ++ Δ1) (Γ0 ++ Γ3, Δ0 ++ A0 :: Δ1)).
+        assert (A0 :: Δ0 ++ Δ1 = [] ++ [A0] ++ Δ0 ++ [] ++ Δ1).
+        reflexivity. assert (Δ0 ++ A0 :: Δ1 = [] ++ [] ++ Δ0 ++ [A0] ++ Δ1).
+        reflexivity. rewrite H1. rewrite H0. clear H1. clear H0. apply list_exch_RI.
+        assert (J21: derrec_height x1 = derrec_height x1). reflexivity.
+        pose (KS_hpadm_list_exch_R0 _ _ x1 J21 _ J2). destruct s. exists x2.
+        assert (existsT2 (x3: derrec KS_rules (fun _ : Seq => False) (Γ0 ++ B0 :: Γ3, Δ0 ++ Δ1)),
+        derrec_height x3 = derrec_height x0). rewrite <- H3.
+        assert (Γ0 ++ B0 :: Γ3 = (Γ0 ++ []) ++ B0 :: Γ3). rewrite app_nil_r. reflexivity.
+        rewrite H0. exists x0. reflexivity. destruct X. exists x3. split.
+        simpl. lia. simpl. lia. }
+      { inversion e0. subst. assert (J30: dersrec_height d = dersrec_height d). reflexivity.
+        pose (@dersrec_derrec2_height (dersrec_height d) _ _ _ _ _ d J30). repeat destruct s.
+        assert (J1: list_exch_R ((Γ0 ++ A --> B :: x) ++ Γ3, Δ2 ++ A0 :: Δ3) (Γ0 ++ A --> B :: x ++ Γ3, A0 :: Δ0 ++ Δ1)).
+        assert (Δ2 ++ A0 :: Δ3 = [] ++ [] ++ Δ2 ++ [A0] ++ Δ3). reflexivity.
+        rewrite H0. clear H0. rewrite <- app_assoc.
+        assert (A0 :: Δ0 ++ Δ1 = [] ++ [A0] ++ Δ2 ++ [] ++ Δ3). simpl. rewrite H3. reflexivity.
+        rewrite H0. clear H0. apply list_exch_RI.
+        assert (J20: derrec_height x0 = derrec_height x0). reflexivity.
+        pose (KS_hpadm_list_exch_R0 _ _ x0 J20 _ J1). destruct s. simpl in IH. simpl.
+        assert (J2: derrec_height x2 < S (dersrec_height d)). lia.
+        assert (J3: derrec_height x2 = derrec_height x2). reflexivity.
+        assert (J4: ImpLRule [(Γ0 ++ x ++ Γ3, A0 :: Δ0 ++ A :: Δ1); (Γ0 ++ B :: x ++ Γ3, A0 :: Δ0 ++ Δ1)]
+        (Γ0 ++ A --> B :: x ++ Γ3, A0 :: Δ0 ++ Δ1)).
+        assert (A0 :: Δ0 ++ A :: Δ1 = (A0 :: Δ0) ++ A :: Δ1). reflexivity. rewrite H0. clear H0.
+        assert (A0 :: Δ0 ++ Δ1 = (A0 :: Δ0) ++ Δ1). reflexivity. rewrite H0. clear H0.
+        apply ImpLRule_I.
+        pose (IH _ J2 _ _ J3). destruct p. pose (s0 _ _ J4). clear s. destruct s1. clear s0. destruct s.
+        destruct p.
+        assert (J5: derrec_height x1 < S (dersrec_height d)). lia.
+        assert (J6: derrec_height x1 = derrec_height x1). reflexivity.
+        assert (J7: ImpLRule [(Γ0 ++ x ++ B0 :: Γ3, Δ0 ++ A :: Δ1); (Γ0 ++ B :: x ++ B0 :: Γ3, Δ0 ++ Δ1)]
+        ((Γ0 ++ A --> B :: x) ++ B0 :: Γ3, Δ2 ++ Δ3)). rewrite H3. rewrite <- app_assoc.
+        apply ImpLRule_I. pose (IH _ J5 _ _ J6). destruct p. pose (s0 _ _ J7). clear s.
+        destruct s1. clear s0. destruct s. destruct p.
+        assert (existsT2 (x7 : derrec KS_rules (fun _ : Seq => False)
+        (Γ0 ++ x ++ A0 --> B0 :: Γ3, Δ0 ++ A :: Δ1)), derrec_height x7 <= S (dersrec_height d)).
+        assert (ImpLRule [(Γ0 ++ x ++ Γ3, A0 :: Δ0 ++ A :: Δ1); (Γ0 ++ x ++ B0 :: Γ3, Δ0 ++ A :: Δ1)]
+        (Γ0 ++ x ++ A0 --> B0 :: Γ3, Δ0 ++ A :: Δ1)).
+        assert (A0 :: Δ0 ++ A :: Δ1 = [] ++ A0 :: Δ0 ++ A :: Δ1). reflexivity. rewrite H0. clear H0.
+        assert (Δ0 ++ A :: Δ1 = [] ++ Δ0 ++ A :: Δ1). reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ x ++ Γ3 = (Γ0 ++ x) ++ Γ3). rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ x ++ B0 :: Γ3 = (Γ0 ++ x) ++ B0 :: Γ3). rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ x ++ A0 --> B0 :: Γ3 = (Γ0 ++ x) ++ A0 --> B0 :: Γ3). rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        apply ImpLRule_I. apply ImpL in H0.
+        pose (dlCons x5 DersNilF). pose (dlCons x3 d0).
+        pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[(Γ0 ++ x ++ Γ3, A0 :: Δ0 ++ A :: Δ1); (Γ0 ++ x ++ B0 :: Γ3, Δ0 ++ A :: Δ1)])
+        (Γ0 ++ x ++ A0 --> B0 :: Γ3, Δ0 ++ A :: Δ1) H0 d1).
+        exists d2. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+        destruct X. exists x7.
+        assert (existsT2 (x8 : derrec KS_rules (fun _ : Seq => False)
+        (Γ0 ++ B :: x ++ A0 --> B0 :: Γ3, Δ0 ++ Δ1)), derrec_height x8 <= S (dersrec_height d)).
+        assert (ImpLRule [(Γ0 ++ B :: x ++ Γ3, A0 :: Δ0 ++ Δ1); (Γ0 ++ B :: x ++ B0 :: Γ3, Δ0 ++ Δ1)]
+        (Γ0 ++ B :: x ++ A0 --> B0 :: Γ3, Δ0 ++ Δ1)).
+        assert (Δ0 ++ Δ1 = [] ++ Δ0 ++ Δ1). reflexivity. rewrite H0. clear H0.
+        assert (A0 :: [] ++ Δ0 ++ Δ1 = [] ++ A0 :: Δ0 ++ Δ1). reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ B :: x ++ Γ3 = (Γ0 ++ B :: x) ++ Γ3). rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ B :: x ++ B0 :: Γ3 = (Γ0 ++ B :: x) ++ B0 :: Γ3). rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        assert (Γ0 ++ B :: x ++ A0 --> B0 :: Γ3 = (Γ0 ++ B :: x) ++ A0 --> B0 :: Γ3). rewrite <- app_assoc. reflexivity. rewrite H0. clear H0.
+        apply ImpLRule_I. apply ImpL in H0.
+        pose (dlCons x6 DersNilF). pose (dlCons x4 d0).
+        pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[(Γ0 ++ B :: x ++ Γ3, A0 :: Δ0 ++ Δ1); (Γ0 ++ B :: x ++ B0 :: Γ3, Δ0 ++ Δ1)])
+        (Γ0 ++ B :: x ++ A0 --> B0 :: Γ3, Δ0 ++ Δ1) H0 d1).
+        exists d2. simpl. rewrite dersrec_height_nil. lia. reflexivity.
+        destruct X. exists x8. split. lia. lia. }
+  (* KR *)
+  * inversion X. subst. pose (univ_gen_ext_splitR _ _ X0). repeat destruct s. repeat destruct p. subst.
+    assert (J0: dersrec_height d = dersrec_height d). reflexivity.
+    pose (dersrec_derrec_height d J0). destruct s.
+    assert (KRRule [(unboxed_list (x ++ x0), [A0])] (Γ0 ++ Γ1, Δ0 ++ Δ1)).
+    rewrite <- H2. apply KRRule_I ; try assumption. apply univ_gen_ext_combine.
+    assumption. apply univ_gen_ext_not_In_delete with (a:=A --> B). intro.
+    assert (In (A --> B) (x ++ x0)). apply in_or_app. auto. apply H1 in H0. destruct H0.
+    inversion H0. assumption.
+    assert (existsT2 (D : derrec KS_rules (fun _ : Seq => False) (Γ0 ++ Γ1, Δ0 ++ Δ1)),
+    derrec_height D <= S (dersrec_height d)).
+    apply KR in X1.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[(unboxed_list (x ++ x0), [A0])]) (Γ0 ++ Γ1, Δ0 ++ Δ1) X1 d).
+    exists d0. simpl. lia.
+    destruct X2.
+    assert (J1: derrec_height x2 = derrec_height x2). reflexivity.
+    assert (J2: wkn_L B (Γ0 ++ Γ1, Δ0 ++ Δ1) (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)). apply wkn_LI.
+    pose (KS_wkn_L _ _ x2 J1 _ _ J2). destruct s.
+    assert (J3: wkn_R A (Γ0 ++ Γ1, Δ0 ++ Δ1) (Γ0 ++ Γ1, Δ0 ++ A :: Δ1)). apply wkn_RI.
+    pose (KS_wkn_R _ _ x2 J1 _ _ J3). destruct s. exists x4. exists x3. simpl.
+    split ; lia. }
+Qed.
+ +
+Theorem ImpR_inv : forall concl prem, (KS_prv concl) ->
+                                      (ImpRRule [prem] concl) ->
+                                      (KS_prv prem).
+Proof.
+intros.
+assert (J1: derrec_height X = derrec_height X). reflexivity.
+pose (ImpR_ImpL_hpinv _ _ X J1). destruct p. pose (s _ H). destruct s1. assumption.
+Qed.
+ +
+Theorem ImpL_inv : forall concl prem1 prem2, (KS_prv concl) ->
+                                      (ImpLRule [prem1;prem2] concl) ->
+                                      (KS_prv prem1) *
+                                      (KS_prv prem2).
+Proof.
+intros.
+assert (J1: derrec_height X = derrec_height X). reflexivity.
+pose (ImpR_ImpL_hpinv _ _ X J1). destruct p. pose (s0 _ _ H). repeat destruct s1. auto.
+Qed.
+
+
+ +
+ + + diff --git a/K.KS.KS_termination.html b/K.KS.KS_termination.html new file mode 100644 index 0000000..58cc2dc --- /dev/null +++ b/K.KS.KS_termination.html @@ -0,0 +1,579 @@ + + + + + + + + + + + + + +
+
+

K.KS.KS_termination

+ +
+Require Import List.
+Export ListNotations.
+Require Import Lia.
+Require Import PeanoNat Arith.
+ +
+Require Import KS_calc.
+Require Import KS_dec.
+Require Import KS_termination_measure.
+Require Export KS_termination_prelims.
+Require Export KS_termination_init.
+Require Export KS_termination_ImpR.
+Require Export KS_termination_ImpL.
+Require Export KS_termination_KR.
+ +
+(* Now that we have the list of all premises of a sequent via all rules, we can combine
+   them all to obtain the list of all potential premises via the KS calculus. *)

+ +
+Lemma finite_premises_of_S : forall (s : Seq), existsT2 listprems,
+              (forall prems, ((KS_rules prems s) -> (InT prems listprems)) *
+                             ((InT prems listprems) -> (KS_rules prems s))).
+Proof.
+intro s.
+destruct (dec_KS_rules s).
+- exists []. intros. split. intro. exfalso. apply f. exists prems. assumption.
+  intro. inversion H.
+- pose (finite_IdP_premises_of_S s). destruct s1.
+  pose (finite_BotL_premises_of_S s). destruct s1.
+  pose (finite_ImpR_premises_of_S s). destruct s1.
+  pose (finite_ImpL_premises_of_S s). destruct s1.
+  pose (finite_KR_premises_of_S s). destruct s1.
+  exists (x ++ x0 ++ x1 ++ x2 ++ x3).
+  split.
+  * intro RA. inversion RA.
+    { inversion H. subst. pose (p []). destruct p4. apply InT_or_app. auto. }
+    { inversion H. subst. pose (p0 []). destruct p4. apply InT_or_app. right. apply InT_or_app. auto. }
+    { inversion H. subst. pose (p1 [(Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)]). destruct p4.
+      apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. left. auto. }
+    { inversion H. subst. pose (p2 [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]).
+      destruct p4. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. right.
+      apply InT_or_app. left. auto. }
+    { inversion X. subst. pose (p3 [(unboxed_list , [A])]).
+      destruct p4. apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app.
+      right. apply InT_or_app. auto. }
+  * intro. apply InT_app_or in H. destruct H.
+    { apply p in i. apply IdP ; try intro ; try apply f ; try auto ; try assumption. }
+    { apply InT_app_or in i. destruct i.
+      - apply p0 in i. apply BotL ; try intro ; try apply f ; try auto ; try assumption.
+      - apply InT_app_or in i. destruct i.
+        + apply p1 in i. apply ImpR ; try intro ; try apply f ; try auto ; try assumption.
+        + apply InT_app_or in i. destruct i.
+          * apply p2 in i. apply ImpL ; try intro ; try apply f ; try auto ; try assumption.
+          * apply p3 in i. apply KR ; try intro ; try apply f ; try auto ; try assumption. }
+Qed.
+ +
+(* The next definitions "flattens" a list of lists of premises to a list of premises.*)
+ +
+Definition list_of_premises (s : Seq) : list Seq :=
+         flatten_list (proj1_sigT2 (finite_premises_of_S s)).
+ +
+Lemma InT_list_of_premises_exists_prems : forall s prem, InT prem (list_of_premises s) ->
+            existsT2 prems, (InT prem prems) * (KS_rules prems s).
+Proof.
+intros s prem X. unfold list_of_premises in X.
+apply InT_flatten_list_InT_elem in X. destruct X. destruct p.
+exists x. split. auto.
+destruct (finite_premises_of_S s). pose (p x). destruct p0. apply k. assumption.
+Qed.
+ +
+Lemma exists_prems_InT_list_of_premises : forall s prem,
+            (existsT2 prems, (InT prem prems) * (KS_rules prems s)) ->
+            InT prem (list_of_premises s).
+Proof.
+intros. destruct X. destruct p. unfold list_of_premises. destruct (finite_premises_of_S s).
+pose (p x). destruct p0. apply InT_trans_flatten_list with (bs:=x). assumption. simpl. apply i0.
+assumption.
+Qed.
+ +
+Lemma find_the_max_mhd : forall concl l
+      (Prem_mhd : forall prems : list Seq, KS_rules prems concl ->
+                  forall prem : Seq, InT prem prems ->
+                  existsT2 Dprem : derrec KS_rules (fun _ : Seq => True) prem,
+                  is_mhd Dprem)
+      (H1 : forall prem : Seq, InT prem l -> InT prem (list_of_premises concl))
+      (H2 : forall (prem : Seq) (J : InT prem l), InT prem (proj1_sigT2
+            (InT_list_of_premises_exists_prems concl _ (H1 prem J))))
+      (H3 : forall (prem : Seq) (J : InT prem l), KS_rules (proj1_sigT2
+            (InT_list_of_premises_exists_prems concl _ (H1 prem J))) concl)
+      (NotNil: l <> nil),
+
+existsT2 prem, existsT2 (J0: InT prem l), forall prem' (J1: InT prem' l),
+       (derrec_height (proj1_sigT2 (Prem_mhd
+        (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 prem' J1)))
+        (H3 prem' J1)
+        prem'
+        (H2 prem' J1))))
+       <=
+       (derrec_height (proj1_sigT2 (Prem_mhd
+        (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 prem J0)))
+        (H3 prem J0)
+        prem
+        (H2 prem J0)))).
+Proof.
+induction l ; intros.
+- exfalso. apply NotNil. reflexivity.
+- clear NotNil. destruct l as [ | r l].
+  * exists a. assert (InT a [a]). apply InT_eq. exists H. intros. inversion J1. subst.
+    destruct (Prem_mhd (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 prem' H))) (H3 prem' H) prem' (H2 prem' H)).
+    destruct (Prem_mhd (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 prem' J1))) (H3 prem' J1) prem' (H2 prem' J1)).
+    simpl. auto. inversion H4.
+  * assert (H1' : forall prem : Seq, InT prem (r :: l) -> InT prem (list_of_premises concl)).
+    { intros. apply H1. apply InT_cons. assumption. }
+    assert (Prem_mhd' : forall prems : list Seq, KS_rules prems concl -> forall prem : Seq,
+                        InT prem prems -> existsT2 Dprem : derrec KS_rules (fun _ : Seq => True)
+                        prem, is_mhd Dprem).
+    { intros. apply Prem_mhd with (prems:= prems) ; try assumption. }
+    assert (H2' : forall (prem : Seq) (J : InT prem (r :: l)), InT prem (proj1_sigT2
+                  (InT_list_of_premises_exists_prems concl _ (H1' prem J)))).
+    { intros. assert (InT prem (a :: r :: l)). apply InT_cons. assumption. pose (H2 _ H).
+      destruct (InT_list_of_premises_exists_prems concl _ (H1' prem J)).
+      simpl. destruct p. assumption. }
+    assert (H3' : forall (prem : Seq) (J : InT prem (r :: l)), KS_rules
+                (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1' prem J))) concl).
+    { intros. destruct (InT_list_of_premises_exists_prems concl _ (H1' prem J)). simpl. destruct p.
+      assumption. }
+    assert (r :: l <> []). intro. inversion H.
+    pose (IHl Prem_mhd' H1' H2' H3' H). destruct s. destruct s.
+    (* I have a max in r :: l: so I simply need to compare it with a. *)
+    assert (J2: InT a (a :: r :: l)). apply InT_eq.
+    assert (J3: InT x (a :: r :: l)). apply InT_cons. assumption.
+    (* The next assert decides on le between mhd of a and mhd of x. *)
+    pose (le_dec
+      (derrec_height (proj1_sigT2 (Prem_mhd (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 a J2)))
+      (H3 a J2) a (H2 a J2))))
+      (derrec_height
+       (proj1_sigT2
+          (Prem_mhd' (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1' x x0)))
+             (H3' x x0) x (H2' x x0))))).
+    destruct s.
+    + exists x. exists J3. intros. inversion J1. subst.
+      destruct (Prem_mhd (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 prem' J1)))
+      (H3 prem' J1) prem' (H2 prem' J1)). simpl.
+      destruct (Prem_mhd (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 prem' J2)))
+      (H3 prem' J2) prem' (H2 prem' J2)). simpl in l1. unfold is_mhd in i0.
+      pose (i0 x1).
+      destruct (Prem_mhd (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 x J3))) (H3 x J3) x (H2 x J3)).
+      simpl.
+      destruct (Prem_mhd' (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1' x x0)))
+      (H3' x x0) x (H2' x x0)). simpl in l1.
+      unfold is_mhd in i1. pose (i1 x4). lia.
+      destruct (Prem_mhd' (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1' x x0)))
+      (H3' x x0) x (H2' x x0)). simpl in l0.
+      destruct (Prem_mhd (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 x J3))) (H3 x J3) x (H2 x J3)).
+      simpl.
+      destruct (Prem_mhd (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 prem' J1)))). simpl.
+      assert (derrec_height
+     (proj1_sigT2
+        (Prem_mhd' (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1' prem' H4)))
+           (H3' prem' H4) prem' (H2' prem' H4))) <= derrec_height x1).
+      apply (l0 prem' H4). subst.
+      unfold is_mhd in i0. pose (i0 x1).
+      destruct (Prem_mhd' (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1' prem' H4)))
+           (H3' prem' H4) prem' (H2' prem' H4)). simpl in H6. unfold is_mhd in i2. pose (i2 x3). lia.
+    + exists a. exists J2. intros.
+      inversion J1.
+      { subst. destruct (Prem_mhd (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 prem' J1)))
+        (H3 prem' J1) prem' (H2 prem' J1)). simpl.
+        destruct (Prem_mhd (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 prem' J2)))
+        (H3 prem' J2) prem' (H2 prem' J2)).
+        simpl. unfold is_mhd in i0. pose (i0 x1). lia. }
+      { subst.
+        destruct (Prem_mhd (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 a J2))) (H3 a J2) a (H2 a J2)).
+        simpl.
+        destruct (Prem_mhd (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 prem' J1)))
+        (H3 prem' J1) prem' (H2 prem' J1)). simpl.
+        destruct (Prem_mhd' (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1' x x0)))
+             (H3' x x0) x (H2' x x0)). simpl in l0.
+        assert (derrec_height
+       (proj1_sigT2
+          (Prem_mhd' (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1' prem' H4)))
+             (H3' prem' H4) prem' (H2' prem' H4))) <= derrec_height x3). apply l0.
+       destruct (Prem_mhd' (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1' prem' H4)))
+             (H3' prem' H4) prem' (H2' prem' H4)). simpl in H0. unfold is_mhd in i2.
+       pose (i2 x2). simpl in *. lia. }
+Qed.
+ +
+Lemma term_IH_help : forall concl,
+     (existsT2 prems, (KS_rules prems concl) * (prems <> [])) ->
+     (forall prems, KS_rules prems concl -> (forall prem, InT prem prems -> (existsT2 Dprem, @is_mhd prem Dprem)))
+      ->
+     (existsT2 Maxprems Maxprem DMaxprem, (KS_rules Maxprems concl) * (@is_mhd Maxprem DMaxprem) * (InT Maxprem Maxprems) *
+        (forall prems prem (Dprem : KS_drv prem), KS_rules prems concl -> InT prem prems ->
+            derrec_height Dprem <= derrec_height DMaxprem)).
+Proof.
+intros concl FAH Prem_mhd.
+pose (list_of_premises concl).
+assert (H1: forall prem, InT prem l -> InT prem (list_of_premises concl)).
+intros. auto.
+assert (H2: forall prem (J: InT prem l), InT prem (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 prem J)))).
+intros. destruct (InT_list_of_premises_exists_prems concl _ (H1 prem J)). destruct p. auto.
+assert (H3: forall prem (J: InT prem l),
+KS_rules (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 prem J))) concl).
+intros. destruct (InT_list_of_premises_exists_prems concl _ (H1 prem J)). destruct p. auto.
+assert (H4: forall prem (J: InT prem l), is_mhd (proj1_sigT2 (Prem_mhd
+        (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 prem J)))
+        (H3 prem J)
+        prem
+        (H2 prem J)))).
+intros. intro. destruct (Prem_mhd (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 prem J)))
+(H3 prem J) prem (H2 prem J)). auto.
+assert (l <> []). intro. destruct FAH. destruct p. destruct k.
+- inversion i. subst. auto.
+- inversion b. subst. auto.
+- inversion i. subst. pose (@exists_prems_InT_list_of_premises (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1) (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)).
+  assert (InT (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) (list_of_premises (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1))). apply i0.
+  exists [(Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)]. split. apply InT_eq. apply ImpR ; assumption.
+  assert (InT (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) l). auto. rewrite H in H5. inversion H5.
+- inversion i. subst. pose (@exists_prems_InT_list_of_premises (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1) (Γ0 ++ Γ1, Δ0 ++ A :: Δ1)).
+  assert (InT (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) (list_of_premises (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1))). apply i0.
+  exists [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]. split. apply InT_eq. apply ImpL ; assumption.
+  assert (InT (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) l). auto. rewrite H in H5. inversion H5.
+- inversion k. subst. pose (@exists_prems_InT_list_of_premises (Γ0, Δ0 ++ Box A :: Δ1) (unboxed_list , [A])).
+  assert (InT (unboxed_list , [A]) (list_of_premises (Γ0, Δ0 ++ Box A :: Δ1))). apply i.
+  exists [(unboxed_list , [A])]. split. apply InT_eq. apply KR ; assumption.
+  assert (InT (unboxed_list , [A]) l). auto. rewrite H in H6. inversion H6.
+ +
+- pose (find_the_max_mhd _ _ Prem_mhd H1 H2 H3 H).
+  destruct s. destruct s. exists (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 x x0))).
+  exists x. exists (proj1_sigT2 (Prem_mhd (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 x x0)))
+  (H3 x x0) x (H2 x x0))). repeat split ; try apply H3 ; try apply H4 ; try apply H2.
+  intros prems prem Dprem RA IsPrem.
+  assert (J3: InT prem l).
+  pose (@exists_prems_InT_list_of_premises concl prem). apply i. exists prems. auto.
+  assert (E1: derrec_height Dprem <= derrec_height (proj1_sigT2 (Prem_mhd (proj1_sigT2
+  (InT_list_of_premises_exists_prems concl _ (H1 prem J3))) (H3 prem J3) prem (H2 prem J3)))).
+  destruct (Prem_mhd (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 prem J3)))
+  (H3 prem J3) prem (H2 prem J3)). auto.
+  assert (E2: derrec_height (proj1_sigT2 (Prem_mhd (proj1_sigT2 (InT_list_of_premises_exists_prems concl
+  _ (H1 prem J3))) (H3 prem J3) prem (H2 prem J3))) <=
+  derrec_height (proj1_sigT2 (Prem_mhd (proj1_sigT2 (InT_list_of_premises_exists_prems concl _ (H1 x x0)))
+  (H3 x x0) x (H2 x x0)))). apply l0. lia.
+Qed.
+ +
+Lemma in_drs_concl_in_allT W rules prems ps (cn : W) (drs : dersrec rules prems ps)
+  (dtn : derrec rules prems cn) : in_dersrec dtn drs -> InT cn ps.
+Proof.
+intro ind. induction ind. apply InT_eq.
+apply InT_cons. assumption.
+Qed.
+ +
+Lemma dec_non_nil_prems: forall (concl : Seq), ((existsT2 prems, (KS_rules prems concl) * (prems <> []))) +
+                                       ((existsT2 prems, (KS_rules prems concl) * (prems <> [])) -> False).
+Proof.
+intros. destruct (dec_KR_rule concl).
+  + destruct s. left. exists [x]. split. apply KR in k ; auto. intro. inversion H.
+  + destruct (dec_ImpR_rule concl).
+    * destruct s. left. exists [x]. split. apply ImpR in i. assumption. intro. inversion H.
+    * destruct (dec_ImpL_rule concl).
+      { destruct s. destruct s. left. exists [x; x0]. split. apply ImpL in i. assumption.
+        intro. inversion H. }
+      { right. intro. destruct X. destruct p. inversion k.
+        - subst. inversion H. auto.
+        - subst. inversion H. auto.
+        - subst. inversion H. subst. apply f0. exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1). assumption.
+        - subst. inversion H. subst. apply f1. exists (Γ0 ++ Γ1, Δ0 ++ A :: Δ1).
+          exists (Γ0 ++ B :: Γ1, Δ0 ++ Δ1). assumption.
+        - subst. inversion X. subst. apply f. exists (unboxed_list , [A]). assumption. }
+Qed.
+ +
+(* The next theorem claims that every sequent s has a derivation DMax of maximal height. *)
+ +
+Theorem KS_termin_base : forall n s, (n = measure s) ->
+   existsT2 (DMax : KS_drv s), (@is_mhd s DMax).
+Proof.
+induction n as [n IH] using (well_founded_induction_type lt_wf).
+assert (dersrecnil: dersrec KS_rules (fun _ => True) nil).
+apply dersrec_nil.
+intros. pose (dec_KS_rules s). destruct s0.
+- assert (forall ps : list Seq, KS_rules ps s -> False).
+  intros. apply f. exists ps. assumption. pose (@no_KS_rule_applic s H0).
+  pose (dpI KS_rules (fun _ : Seq => True) s I).
+  exists d. unfold is_mhd. intros. simpl. pose (e D1). rewrite e0. auto.
+- assert (forall prems, KS_rules prems s -> (forall prem, InT prem prems ->
+  (existsT2 Dprem, @is_mhd prem Dprem))).
+  { simpl. intros prems X prem X0. inversion X.
+    - inversion H0. subst. exfalso. inversion X0.
+    - inversion H0. subst. exfalso. inversion X0.
+    - inversion H0. subst. inversion X0. 2: inversion H1. subst.
+      assert (J0: measure (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) < measure (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1)).
+      unfold measure. simpl.
+      repeat rewrite size_LF_dist_app. simpl. lia.
+      pose (IH (measure (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)) J0 (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)).
+      apply s. reflexivity.
+    - inversion H0. subst. inversion X0 ; subst.
+     + assert (J0: measure (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) < measure (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+        unfold measure. simpl. repeat rewrite size_LF_dist_app. simpl. lia.
+        pose (IH (measure (Γ0 ++ Γ1, Δ0 ++ A :: Δ1)) J0 (Γ0 ++ Γ1, Δ0 ++ A :: Δ1)).
+        apply s. reflexivity.
+     + inversion H1. subst.
+        assert (J0: measure (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) < measure (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+        unfold measure. simpl. repeat rewrite size_LF_dist_app. simpl. lia.
+        pose (IH (measure (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)) J0 (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)).
+        apply s. reflexivity. inversion H2.
+    - inversion X1. subst. inversion X0. 2: inversion H0. subst.
+      assert (J0: measure (unboxed_list , [A]) < measure (Γ0, Δ0 ++ Box A :: Δ1)).
+      unfold measure. simpl. repeat rewrite size_LF_dist_app. simpl.
+      pose (size_nobox_gen_ext _ _ X2). pose (size_unboxed ). lia.
+      pose (IH (measure (unboxed_list , [A])) J0 (unboxed_list , [A])).
+      apply s. reflexivity. }
+    destruct (dec_non_nil_prems s).
+    + pose (@term_IH_help s s1 X). repeat destruct s2. destruct p. destruct p. destruct p.
+      inversion k.
+      (* Use PIH and SIH here, depending on the rule applied *)
+      * inversion H0. subst. inversion i.
+      * inversion H0. subst. inversion i.
+      * subst. inversion H0. subst. assert (E: x0 = (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)).
+        inversion i. auto. inversion H1. subst.
+        pose (dlCons x1 dersrecnil).
+        pose (@derI _ _ (fun _ : Seq => True) [(Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)] (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1) k d).
+        exists d0. unfold is_mhd. intros. simpl. rewrite dersrec_height_nil with (ds:=dersrecnil). rewrite Nat.max_0_r.
+        destruct D1.
+        { simpl. lia. }
+        { simpl.
+          assert (forall p (d : derrec KS_rules (fun _ : Seq => True) p),
+          in_dersrec d d1 -> derrec_height d <= (derrec_height x1)). intros.
+          pose (@in_drs_concl_in_allT _ _ _ _ _ _ _ X0). subst. pose (l ps p d2 k0 i1). assumption.
+          pose (dersrec_height_le H). lia. }
+        { reflexivity. }
+      * subst. inversion H0. subst. inversion i.
+        { subst. pose (dpI KS_rules (fun _ : Seq => True) (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) I).
+          pose (dlCons d dersrecnil). pose (dlCons x1 d0).
+          pose (@derI _ _ (fun _ : Seq => True) [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]
+          (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1) k d1).
+          exists d2. unfold is_mhd. intros. simpl. rewrite dersrec_height_nil with (ds:=dersrecnil). rewrite Nat.max_0_r.
+          destruct D1.
+          { simpl. lia. }
+          { simpl.
+            assert (forall p (d : derrec KS_rules (fun _ : Seq => True) p),
+            in_dersrec d d3 -> derrec_height d <= (derrec_height x1)). intros.
+            pose (@in_drs_concl_in_allT _ _ _ _ _ _ _ X0). subst. pose (l ps p d4 k0 i1). assumption.
+            pose (dersrec_height_le H). lia. }
+          { reflexivity. } }
+        { inversion H1. subst. pose (dpI KS_rules (fun _ : Seq => True) (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) I).
+          pose (dlCons x1 dersrecnil). pose (dlCons d d0).
+          pose (@derI _ _ (fun _ : Seq => True) [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]
+          (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1) k d1).
+          exists d2. unfold is_mhd. intros. simpl. rewrite dersrec_height_nil with (ds:=dersrecnil). rewrite Nat.max_0_r.
+          destruct D1.
+          { simpl. lia. }
+          { simpl.
+            assert (forall p (d : derrec KS_rules (fun _ : Seq => True) p),
+            in_dersrec d d3 -> derrec_height d <= (derrec_height x1)). intros.
+            pose (@in_drs_concl_in_allT _ _ _ _ _ _ _ X0). subst. pose (l ps p d4 k0 i1). assumption.
+            pose (dersrec_height_le H). lia. }
+          { reflexivity. }
+          inversion H4. }
+      * subst. inversion X0. subst. assert (E: x0 = (unboxed_list , [A])).
+        inversion i. subst. auto. inversion H1. subst.
+        pose (dlCons x1 dersrecnil).
+        pose (@derI _ _ (fun _ : Seq => True) [(unboxed_list , [A])] (Γ0, Δ0 ++ Box A :: Δ1) k d).
+        exists d0. unfold is_mhd. intros. simpl. rewrite dersrec_height_nil with (ds:=dersrecnil). rewrite Nat.max_0_r.
+        destruct D1.
+        { simpl. lia. }
+        { simpl.
+          assert (forall p (d : derrec KS_rules (fun _ : Seq => True) p),
+          in_dersrec d d1 -> derrec_height d <= (derrec_height x1)). intros.
+          pose (@in_drs_concl_in_allT _ _ _ _ _ _ _ X2). subst. pose (l ps p d2 k0 i1). assumption.
+          pose (dersrec_height_le H0). lia. }
+        { reflexivity. }
+    + destruct s0. inversion k.
+      * inversion H0. subst. pose (@derI _ _ (fun _ : Seq => True) [] (Γ0 ++ # P :: Γ1, Δ0 ++ # P :: Δ1) k dersrecnil).
+        exists d. unfold is_mhd. intros. simpl. rewrite dersrec_height_nil with (ds:=dersrecnil).
+        destruct D1.
+        { simpl. lia. }
+        { simpl. destruct k0.
+          - inversion i. subst. rewrite dersrec_height_nil with (ds:=d0). lia. reflexivity.
+          - inversion b. subst. rewrite dersrec_height_nil with (ds:=d0). lia. reflexivity.
+          - inversion i. subst. exfalso. apply f. exists [(Γ2 ++ A :: Γ3, Δ2 ++ B :: Δ3)]. split.
+            apply ImpR in i. assumption. intro. inversion H.
+          - inversion i. subst. exfalso. apply f. exists [(Γ2 ++ Γ3, Δ2 ++ A :: Δ3); (Γ2 ++ B :: Γ3, Δ2 ++ Δ3)]. split.
+            apply ImpL in i. assumption. intro. inversion H.
+          - inversion k0. subst. exfalso. apply f. exists [(unboxed_list , [A])]. split.
+            apply KR in k0. assumption. intro. inversion H1. }
+        { reflexivity. }
+      * inversion H0. subst. pose (@derI _ _ (fun _ : Seq => True) [] (Γ0 ++ Bot :: Γ1, Δ) k dersrecnil).
+        exists d. unfold is_mhd. intros. simpl. rewrite dersrec_height_nil with (ds:=dersrecnil).
+        destruct D1.
+        { simpl. lia. }
+        { simpl. destruct k0.
+          - inversion i. subst. rewrite dersrec_height_nil with (ds:=d0). lia. reflexivity.
+          - inversion b. subst. rewrite dersrec_height_nil with (ds:=d0). lia. reflexivity.
+          - inversion i. subst. exfalso. apply f. exists [(Γ2 ++ A :: Γ3, Δ0 ++ B :: Δ1)]. split.
+            apply ImpR in i. assumption. intro. inversion H.
+          - inversion i. subst. exfalso. apply f. exists [(Γ2 ++ Γ3, Δ0 ++ A :: Δ1); (Γ2 ++ B :: Γ3, Δ0 ++ Δ1)]. split.
+            apply ImpL in i. assumption. intro. inversion H.
+          - inversion k0. subst. exfalso. apply f. exists [(unboxed_list , [A])]. split.
+            apply KR in k0. assumption. intro. inversion H1. }
+        { reflexivity. }
+      * inversion H0. subst. exfalso. apply f. exists [(Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)]. split. assumption. intro.
+        inversion H.
+      * inversion H0. subst. exfalso. apply f. exists [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]. split. assumption. intro.
+        inversion H.
+      * inversion X0. subst. exfalso. apply f. exists [(unboxed_list , [A])]. split. assumption. intro.
+        inversion H.
+Qed.
+ +
+Theorem KS_termin : forall s, existsT2 (DMax : KS_drv s), (@is_mhd s DMax).
+Proof.
+intro s. pose (@KS_termin_base (measure s)). apply s0 ; reflexivity.
+Qed.
+ +
+Theorem KS_termin1 : forall (s : Seq), exists (DMax : KS_drv s), (is_mhd DMax).
+Proof.
+intro s.
+assert (J1: measure s = measure s). reflexivity.
+pose (@KS_termin_base (measure s) s J1).
+destruct s0. exists x. assumption.
+Qed.
+ +
+Theorem KS_termin2 : forall s, exists (DMax : KS_drv s), (is_mhd DMax).
+Proof.
+intro s.
+assert (J1: measure s = measure s). reflexivity.
+pose (@KS_termin_base (measure s) s J1 ).
+destruct s0. exists x. assumption.
+Qed.
+ +
+Theorem KS_termin3 : forall (s : Seq), existsT2 (DMax : KS_drv s), (is_mhd DMax).
+Proof.
+intro s. pose (@KS_termin_base (measure s)). apply s0 ; reflexivity.
+Qed.
+ +
+(* Now we can prove that the maximal height of derivations (mhd) for sequents
+   decreases upwards in the applicability of the proofs. In other words, if a sequent s is the
+   conclusion of an instance of a rule R of KS with premises in ps, then for any element s0 of
+   ps we have that (mhd s0) < (mhd s).
+
+   To do so we first define mhd.*)

+ +
+Definition mhd (s: Seq) : nat := derrec_height (proj1_sigT2 (KS_termin s)).
+ +
+Lemma KS_termin_der_is_mhd : forall s, (@is_mhd s (proj1_sigT2 (@KS_termin s))).
+Proof.
+intro s. destruct KS_termin. auto.
+Qed.
+ +
+Theorem RA_mhd_decreases : forall prems concl, (KS_rules prems concl) ->
+                             (forall prem, (In prem prems) -> (mhd prem) < (mhd concl)).
+Proof.
+intros. inversion X.
+- inversion H0. subst. inversion H.
+- inversion H0. subst. inversion H.
+- inversion H0. subst. inversion H.
+  * subst. apply le_False_lt. intro.
+    pose (d:= proj1_sigT2 (KS_termin (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1))).
+    pose (d0:=proj1_sigT2 (KS_termin (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1))).
+    assert (dersrecnil: dersrec KS_rules (fun _ => True) nil).
+    apply dersrec_nil. pose (dlCons d0 dersrecnil).
+    pose (@derI _ _ (fun _ : Seq => True) [(Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)] (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1) X d1).
+    assert (E1: derrec_height d0 = mhd (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)).
+    unfold mhd. auto.
+    assert (E2: derrec_height d = mhd (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1)).
+    unfold mhd. auto.
+    assert (@is_mhd (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1) d). apply KS_termin_der_is_mhd.
+    unfold is_mhd in H2. pose (H2 d2). simpl in l. rewrite dersrec_height_nil in l. rewrite Nat.max_0_r in l.
+    lia. reflexivity.
+  * inversion H1.
+- inversion H0. subst. inversion H.
+    * subst. apply le_False_lt. intro.
+      pose (d:=proj1_sigT2 (KS_termin (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1))).
+      pose (d0:=proj1_sigT2 (KS_termin (Γ0 ++ Γ1, Δ0 ++ A :: Δ1))).
+      assert (dersrecnil: dersrec KS_rules (fun _ => True) nil).
+      apply dersrec_nil.
+      pose (dpI KS_rules (fun _ : Seq => True) (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) I).
+      pose (dlCons d1 dersrecnil). pose (dlCons d0 d2).
+      pose (@derI _ _ (fun _ : Seq => True) [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]
+      (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1) X d3).
+      assert (E1: derrec_height d0 = mhd (Γ0 ++ Γ1, Δ0 ++ A :: Δ1)).
+      unfold mhd. auto.
+      assert (E2: derrec_height d = mhd (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+      unfold mhd. auto.
+      assert (@is_mhd (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1) d). apply KS_termin_der_is_mhd.
+      unfold is_mhd in H2. pose (H2 d4). simpl in l. rewrite dersrec_height_nil in l. rewrite Nat.max_0_r in l.
+      lia. reflexivity.
+    * inversion H1. subst. apply le_False_lt. intro.
+      pose (d:=proj1_sigT2 (KS_termin (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1))).
+      pose (d0:=proj1_sigT2 (KS_termin (Γ0 ++ B :: Γ1, Δ0 ++ Δ1))).
+      assert (dersrecnil: dersrec KS_rules (fun _ => True) nil).
+      apply dersrec_nil.
+      pose (dpI KS_rules (fun _ : Seq => True) (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) I).
+      pose (dlCons d0 dersrecnil). pose (dlCons d1 d2).
+      pose (@derI _ _ (fun _ : Seq => True) [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]
+      (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1) X d3).
+      assert (E1: derrec_height d0 = mhd (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)).
+      unfold mhd. auto.
+      assert (E2: derrec_height d = mhd (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+      unfold mhd. auto.
+      assert (@is_mhd (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1) d). apply KS_termin_der_is_mhd.
+      unfold is_mhd in H3. pose (H3 d4). simpl in l. rewrite dersrec_height_nil in l. rewrite Nat.max_0_r in l.
+      simpl in l. lia. reflexivity. inversion H2.
+- inversion X0. subst. inversion H.
+  * subst. apply le_False_lt. intro.
+    pose (d:=proj1_sigT2 (KS_termin (Γ0, Δ0 ++ Box A :: Δ1))).
+    pose (d0:=proj1_sigT2 (KS_termin (unboxed_list , [A]))).
+    assert (dersrecnil: dersrec KS_rules (fun _ => True) nil).
+    apply dersrec_nil. pose (dlCons d0 dersrecnil).
+    pose (@derI _ _ (fun _ : Seq => True) [(unboxed_list , [A])] (Γ0, Δ0 ++ Box A :: Δ1) X d1).
+    assert (E1: derrec_height d0 = mhd (unboxed_list , [A])).
+    unfold mhd. auto.
+    assert (E2: derrec_height d = mhd (Γ0, Δ0 ++ Box A :: Δ1)).
+    unfold mhd. auto.
+    assert (@is_mhd (Γ0, Δ0 ++ Box A :: Δ1) d). apply KS_termin_der_is_mhd.
+    unfold is_mhd in H1. pose (H1 d2). simpl in l. rewrite dersrec_height_nil in l. rewrite Nat.max_0_r in l.
+    lia. reflexivity.
+  * inversion H0.
+Qed.
+ +
+
+
+ +
+ + + diff --git a/K.KS.KS_termination_ImpL.html b/K.KS.KS_termination_ImpL.html new file mode 100644 index 0000000..c9f2b05 --- /dev/null +++ b/K.KS.KS_termination_ImpL.html @@ -0,0 +1,286 @@ + + + + + + + + + + + + + +
+
+

K.KS.KS_termination_ImpL

+ +
+Require Import List.
+Export ListNotations.
+Require Import Lia.
+Require Import PeanoNat.
+ +
+Require Import KS_calc.
+Require Import KS_dec.
+Require Import KS_termination_measure.
+Require Import KS_termination_prelims.
+Require Import KS_termination_ImpR.
+ +
+(* Then, we turn to the case of the ImpL rule. *)
+ +
+Fixpoint prems_Imp_L (l : list ((MPropF) * nat)) (s : Seq) : list (list Seq) :=
+match l with
+  | nil => nil
+  | (C, n) :: t => match n with
+      | 0 => prems_Imp_L t s
+      | S m => match C with
+           | Imp A B => flatten_list
+                        (map (fun y => map (fun z => [z; y])
+                        (listInsertsL_Seqs ((fst (nth_split m (remove_nth (S m) C (fst s)))) ++
+                        (snd (nth_split m (remove_nth (S m) C (fst s))))) (snd s) A))
+                        [(((fst (nth_split m (remove_nth (S m) C (fst s)))) ++
+                        B :: (snd (nth_split m (remove_nth (S m) C (fst s))))), (snd s))])
+                        ++ (prems_Imp_L t s)
+           | _ => prems_Imp_L t s
+           end
+      end
+end.
+ +
+Definition ImpL_help002 : forall Γ0 Γ1 Δ0 Δ1 A B,
+           InT [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]
+               (flatten_list (map (fun y : list MPropF * list MPropF => map
+               (fun z : list MPropF * list MPropF => [y; z]) [(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)])
+               (listInsertsL_Seqs (Γ0 ++ Γ1) (Δ0 ++ Δ1) A)))
+              .
+Proof.
+intros.
+pose (@InT_trans_flatten_list _ (map (fun y : list MPropF * list MPropF => map
+(fun z : list MPropF * list MPropF => [y; z]) [(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)])
+(listInsertsL_Seqs (Γ0 ++ Γ1) (Δ0 ++ Δ1) A))
+(map (fun z : list MPropF * list MPropF => [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); z])
+[(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]) [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]).
+apply i ; clear i.
+- pose (InT_map_iff (fun z : list MPropF * list MPropF => [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); z]) [(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]
+  [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]).
+  destruct p. clear s. apply i. exists (Γ0 ++ B :: Γ1, Δ0 ++ Δ1). split. reflexivity. apply InT_eq.
+- pose (InT_map_iff (fun y : list MPropF * list MPropF =>
+  map (fun z : list MPropF * list MPropF => [y; z]) [(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)])
+  (listInsertsL_Seqs (Γ0 ++ Γ1) (Δ0 ++ Δ1) A) (map (fun z : list MPropF * list MPropF => [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); z])
+  [(Γ0 ++ B :: Γ1, Δ0 ++ Δ1)])).
+  destruct p. apply i. clear i. clear s. exists (Γ0 ++ Γ1, Δ0 ++ A :: Δ1). split. reflexivity.
+  unfold listInsertsL_Seqs.
+  pose (InT_map_iff (fun y : list MPropF => (Γ0 ++ Γ1, y)) (listInserts (Δ0 ++ Δ1) A) (Γ0 ++ Γ1, Δ0 ++ A :: Δ1)).
+  destruct p. apply i. clear s. clear i. exists (Δ0 ++ A :: Δ1). split. reflexivity.
+  unfold listInserts.
+  pose (InT_map_iff (fun y : list MPropF * list MPropF => fst y ++ A :: snd y)
+  (proj1_sigT2 (list_of_splits (Δ0 ++ Δ1))) (Δ0 ++ A :: Δ1)). destruct p. clear s.
+  apply i. clear i. exists (Δ0,Δ1). simpl. split. reflexivity. destruct (list_of_splits (Δ0 ++ Δ1)).
+  simpl. pose (i Δ0 Δ1). apply In_InT_seqs. rewrite <- i0. reflexivity.
+Defined.
+ +
+Definition ImpL_help02 : forall Γ0 Γ1 Δ0 Δ1 A B l n,
+            ImpLRule [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)] (Γ0 ++ (Imp A B) :: Γ1, Δ0 ++ Δ1) ->
+            (length Γ0 = n) ->
+            (In ((Imp A B), S n) l) ->
+            InT [(Γ0 ++ Γ1, Δ0 ++ A :: Δ1); (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)] (prems_Imp_L l (Γ0 ++ (Imp A B) :: Γ1, Δ0 ++ Δ1)).
+Proof.
+induction l ; intros.
+- inversion H1.
+- destruct a. destruct m.
+  * subst. apply In_InT_pair in H1. inversion H1. subst. inversion H2. subst. apply InT_In in H2.
+    assert (J1: length Γ0 = length Γ0). reflexivity.
+    pose (IHl _ H J1 H2). simpl. destruct n0. assumption. assumption.
+  * subst. apply In_InT_pair in H1. inversion H1. subst. inversion H2. subst. apply InT_In in H2.
+    assert (J1: length Γ0 = length Γ0). reflexivity.
+    pose (IHl _ H J1 H2). simpl. destruct n0. assumption. assumption.
+  * apply In_InT_pair in H1. inversion H1.
+    + subst. inversion H3. subst.
+      pose (ImpL_help002 Γ0 Γ1 Δ0 Δ1 A B). simpl in i.
+      apply InT_or_app. left.
+      apply InT_trans_flatten_list with (bs:=(flatten_list
+      (map (fun y : list MPropF * list MPropF => [[y; (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)]])
+         (listInsertsL_Seqs (Γ0 ++ Γ1) (Δ0 ++ Δ1) A)))). assumption. apply InT_map_iff.
+      exists (Γ0 ++ B :: Γ1, Δ0 ++ Δ1). split.
+      destruct (eq_dec_form (A --> B) (A --> B)).
+      apply InT_flatten_list_InT_elem in i. destruct i. destruct p.
+      assert ((listInsertsL_Seqs (fst
+      (nth_split (length Γ0) (remove_nth (S (length Γ0)) (A --> B) (fst (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)))) ++
+      snd
+      (nth_split (length Γ0) (remove_nth (S (length Γ0)) (A --> B) (fst (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)))))
+      (snd (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)) A) = (listInsertsL_Seqs (Γ0 ++ Γ1) (Δ0 ++ Δ1) A)).
+      simpl (snd (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+      simpl (fst (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)). repeat rewrite effective_remove_nth.
+      assert (length Γ0 = length Γ0). reflexivity.
+      pose (@nth_split_length_id Γ0 Γ1 (length Γ0) H0). destruct a. rewrite H2. rewrite H4.
+      reflexivity. rewrite H0.
+      apply redundant_flatten_list. exfalso. auto.
+      destruct (eq_dec_form (A --> B) (A --> B)). simpl (snd (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
+      simpl (fst (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)). repeat rewrite effective_remove_nth.
+      assert (length Γ0 = length Γ0). reflexivity.
+      pose (@nth_split_length_id Γ0 Γ1 (length Γ0) H0). destruct a. rewrite H2. rewrite H4.
+      apply InT_eq. exfalso. auto.
+    + subst. assert (J1: (length Γ0) = (length Γ0)). reflexivity. apply InT_In in H3.
+      pose (IHl (length Γ0) H J1 H3). simpl. destruct n0. assumption. apply InT_or_app. auto.
+  * subst. apply In_InT_pair in H1. inversion H1. subst. inversion H2. subst. apply InT_In in H2.
+    assert (J1: length Γ0 = length Γ0). reflexivity.
+    pose (IHl _ H J1 H2). simpl. destruct n0. assumption. assumption.
+Defined.
+ +
+Definition ImpL_help2 : forall prem1 prem2 s, ImpLRule [prem1; prem2] s ->
+                      InT [prem1; prem2] (prems_Imp_L (pos_top_imps (fst s)) s).
+Proof.
+intros. inversion H. subst. simpl.
+pose (@ImpL_help02 Γ0 Γ1 Δ0 Δ1 A B (pos_top_imps (Γ0 ++ (Imp A B) :: Γ1)) (length Γ0)). apply i ; try assumption.
+reflexivity. apply Good_pos_in_pos_top_imps.
+Defined.
+ +
+Definition ImpL_help01 : forall prems s l, InT prems (prems_Imp_L l s) ->
+                  (existsT2 n prem1 prem2 A B Γ0 Γ1 Δ0 Δ1,
+                        (prems = [prem1; prem2]) /\
+                        (In ((Imp A B), S n) l) /\
+                        (prem1 = (Γ0 ++ Γ1, Δ0 ++ A :: Δ1)) /\
+                        (prem2 = (Γ0 ++ B :: Γ1, Δ0 ++ Δ1)) /\
+                        (Δ0 ++ Δ1 = snd s) /\
+                        (Γ0 = (fst (nth_split n (remove_nth (S n) (Imp A B) (fst s))))) /\
+                        (Γ1 = (snd (nth_split n (remove_nth (S n) (Imp A B) (fst s)))))).
+Proof.
+intros prems s. destruct s. induction l1 ; intros X.
+- simpl in X. inversion X.
+- simpl (fst (l, l0)). destruct a as [m n]. destruct m as [n0| | |].
+  * simpl in X. destruct n.
+    + pose (s := IHl1 X). repeat destruct s. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. exists x6. exists x7.
+      repeat split ; try tauto. apply in_cons. tauto.
+    + pose (s := IHl1 X). repeat destruct s. repeat destruct p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. exists x6. exists x7.
+      repeat split ; try tauto. apply in_cons. tauto.
+  * simpl in X. destruct n.
+    + pose (s := IHl1 X). repeat destruct s. repeat destruct p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. exists x6. exists x7.
+      repeat split ; try tauto. apply in_cons. tauto.
+    + pose (s := IHl1 X). repeat destruct s. repeat destruct p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. exists x6. exists x7.
+      repeat split ; try tauto. apply in_cons. tauto.
+  * destruct n.
+    + pose (s := IHl1 X). repeat destruct s. repeat destruct p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. exists x6. exists x7.
+      repeat split ; try tauto. apply in_cons. tauto.
+    + apply InT_app_or in X. destruct X.
+      { simpl (fst (l, l0)) in i. simpl (snd (l, l0)) in i.
+        apply InT_flatten_list_InT_elem in i. destruct i. destruct p.
+        apply InT_map_iff in i0. destruct i0. destruct p.
+        inversion i0. subst. apply InT_map_iff in i. destruct i.
+        destruct p. unfold listInsertsL_Seqs in i. apply InT_map_iff in i.
+        destruct i. destruct p. subst. unfold listInserts in i. apply InT_map_iff in i. destruct i.
+        destruct p. destruct x. subst. destruct (list_of_splits l0). simpl in i. exists n.
+        simpl (fst (l2, l3)). simpl (snd (l2, l3)).
+        exists (fst (nth_split n (remove_nth (S n) (m1 --> m2) l)) ++
+        snd (nth_split n (remove_nth (S n) (m1 --> m2) l)), l2 ++ m1 :: l3).
+        exists (fst
+          (nth_split n
+             match n with
+             | 0 =>
+                 match l with
+                 | [] => []
+                 | B0 :: tl => if eq_dec_form (m1 --> m2) B0 then tl else B0 :: tl
+                 end
+             | S _ => match l with
+                      | [] => []
+                      | B0 :: tl => B0 :: remove_nth n (m1 --> m2) tl
+                      end
+             end) ++
+        m2
+        :: snd
+             (nth_split n
+                match n with
+                | 0 =>
+                    match l with
+                    | [] => []
+                    | B0 :: tl => if eq_dec_form (m1 --> m2) B0 then tl else B0 :: tl
+                    end
+                | S _ => match l with
+                         | [] => []
+                         | B0 :: tl => B0 :: remove_nth n (m1 --> m2) tl
+                         end
+                end), l0).
+        exists m1. exists m2. exists (fst (nth_split n (remove_nth (S n) (m1 --> m2) l))).
+        exists (snd (nth_split n (remove_nth (S n) (m1 --> m2) l))).
+        exists l2. exists l3. simpl (snd (l, l0)). simpl (fst (l, l0)).
+        repeat split ; try auto. apply in_eq. simpl. assert (l2 ++ l3 = l0). rewrite i1. apply InT_In.
+        assumption. rewrite <- H. reflexivity. rewrite i1. apply InT_In. assumption. subst. inversion H0. }
+      { pose (IHl1 i). repeat destruct s. repeat destruct p. exists x. exists x0. exists x1.
+        exists x2. exists x3. exists x4. exists x5. exists x6. exists x7.
+        repeat split ; try tauto. apply in_cons. tauto. }
+  * simpl in X. destruct n.
+    + pose (IHl1 X). repeat destruct s. repeat destruct p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. exists x6. exists x7.
+      repeat split ; try tauto. apply in_cons. tauto.
+    + pose (IHl1 X). repeat destruct s. repeat destruct p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. exists x6. exists x7.
+      repeat split ; try tauto. apply in_cons. tauto.
+Defined.
+ +
+Definition ImpL_help1 : forall prems s, InT prems (prems_Imp_L (pos_top_imps (fst s)) s) ->
+                                         ImpLRule prems s.
+Proof.
+intros prem s X. pose (s0 := @ImpL_help01 _ _ _ X). destruct s0 as (n&Hn&A&B&Γ0&Γ1&Δ0& Δ1&e1&Heq&i&p). destruct s as (l&l0). simpl in X.
+intuition. subst.
+apply In_pos_top_imps_split_l in i.
+simpl (fst (l, l0)). simpl in H0. subst.
simpl (fst (l, Δ1 ++ e1)) in X.
+destruct i as (l0&l1&Heq1 & Hlen & Heq2 & Heq3).
+subst.
+simpl (fst (l, Δ1 ++ e1)) in Heq1.
+simpl (fst (l, Δ1 ++ e1)) in Heq2.
+remember (fst (nth_split (length l0) (remove_nth (S (length l0)) (B --> Γ0) l))) as Γ0'.
+remember (snd (nth_split (length l0) (remove_nth (S (length l0)) (B --> Γ0) l))) as Γ1'.
+rewrite Heq1, Heq2.
+apply ImpLRule_I.
+Defined.
+ +
+Definition finite_ImpL_premises_of_S : forall (s : Seq), existsT2 listImpLprems,
+              (forall prems, ((ImpLRule prems s) -> (InT prems listImpLprems)) *
+                             ((InT prems listImpLprems) -> (ImpLRule prems s))).
+Proof.
+intros. destruct s.
+exists (prems_Imp_L (pos_top_imps l) (l,l0)).
+intros. split ; intro.
+- inversion H. subst.
+  pose (@ImpL_help2 (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)). apply i.
+  assumption.
+- pose (@ImpL_help1 prems (l, l0)). apply i. assumption.
+Defined.
+ +
+
+
+ +
+ + + diff --git a/K.KS.KS_termination_ImpR.html b/K.KS.KS_termination_ImpR.html new file mode 100644 index 0000000..50994ff --- /dev/null +++ b/K.KS.KS_termination_ImpR.html @@ -0,0 +1,392 @@ + + + + + + + + + + + + + +
+
+

K.KS.KS_termination_ImpR

+ +
+Require Import List.
+Export ListNotations.
+Require Import Lia.
+Require Import PeanoNat.
+ +
+Require Import KS_calc.
+Require Import KS_dec.
+Require Import KS_termination_measure.
+Require Import KS_termination_prelims.
+ +
+(* Now we can prove that a sequent has only finitely many potential premises via the ImpR rules.
+
+   The next definition simply takes a list of formulae l and a sequent s. It outputs a list of sequents.
+   These sequents are generated when there is an implication (Imp A B) encountered in l. With such an
+   implication, the function will stack the list of all insertions of A on the left of s and of B on
+   the right of s (roughly: in fact you need to destroy all such implications on the right to get an ImpRRule
+   premise), and then continues computing on the rest of l. *)

+ +
+Fixpoint prems_Imp_R (l : list ((MPropF) * nat)) (s : Seq) : list Seq :=
+match l with
+  | nil => nil
+  | (C, n) :: t => match n with
+                    | 0 => prems_Imp_R t s
+                    | S m => match C with
+                                | Imp A B => (listInsertsR_Seqs (fst s)
+                                               ((fst (nth_split m (remove_nth (S m) C (snd s)))) ++
+                                               B :: (snd (nth_split m (remove_nth (S m) C (snd s)))))
+                                               A)
+                                             ++ (prems_Imp_R t s)
+                                | _ => prems_Imp_R t s
+                                end
+                   end
+end.
+ +
+Lemma In_pos_top_imps_0_False : forall l (A : MPropF), In (A, 0) (pos_top_imps l) -> False.
+Proof.
+- induction l.
+  * intros. inversion H.
+  * intros. simpl in H. destruct a.
+    + simpl in H. apply In_InT_pair in H. apply InT_map_iff in H. destruct H.
+      destruct p. destruct x. inversion e.
+    + simpl in H. apply In_InT_pair in H. apply InT_map_iff in H. destruct H.
+      destruct p. destruct x. inversion e.
+    + simpl in H. destruct H. inversion H. apply In_InT_pair in H. apply InT_map_iff in H. destruct H.
+      destruct p. destruct x. inversion e.
+    + simpl in H. apply In_InT_pair in H. apply InT_map_iff in H. destruct H.
+      destruct p. destruct x. inversion e.
+Qed.
+ +
+Lemma In_pos_top_imps_imp : forall l (A : MPropF) n, In (A, n) (pos_top_imps l) -> (existsT2 C D, A = Imp C D).
+Proof.
+induction l ; intros.
+- simpl in H. inversion H.
+- simpl in H. destruct a ; try apply IHl in H. apply In_InT_pair in H. apply InT_map_iff in H. destruct H.
+  destruct p. inversion e. destruct x. subst. apply InT_In in i. apply IHl in i. assumption.
+  apply In_InT_pair in H. apply InT_map_iff in H. destruct H.
+  destruct p. inversion e. destruct x. subst. apply InT_In in i. apply IHl in i. assumption.
+  apply In_InT_pair in H. inversion H. subst. inversion H1. exists a1. exists a2. reflexivity.
+  subst. apply InT_map_iff in H1. destruct H1. destruct p. destruct x. simpl in e. inversion e.
+  subst. apply InT_In in i. apply IHl in i. assumption.
+  apply In_InT_pair in H. apply InT_map_iff in H. destruct H.
+  destruct p. inversion e. destruct x. subst. apply InT_In in i. apply IHl in i. assumption.
+Qed.
+ +
+Lemma In_pos_top_imps_In_l : forall l (A : MPropF) n, In (A, n) (pos_top_imps l) -> In A l.
+Proof.
+induction l.
+- intros. simpl in H. destruct H.
+- intros. simpl in H. destruct a.
+  * apply in_cons. apply In_InT_pair in H. apply InT_map_iff in H. destruct H.
+    destruct p. destruct x. inversion e. subst. apply InT_In in i. apply IHl in i.
+    assumption.
+  * apply in_cons. apply In_InT_pair in H. apply InT_map_iff in H. destruct H.
+    destruct p. destruct x. inversion e. subst. apply InT_In in i. apply IHl in i.
+    assumption.
+  * inversion H.
+    + inversion H0. subst. apply in_eq.
+    + apply in_cons. apply In_InT_pair in H0. apply InT_map_iff in H0. destruct H0.
+      destruct p. destruct x. inversion e. subst. apply InT_In in i. apply IHl in i.
+      assumption.
+  * apply In_InT_pair in H. apply InT_map_iff in H. destruct H.
+    destruct p. destruct x. inversion e. subst. apply InT_In in i. apply IHl in i.
+    apply in_cons. assumption.
+Qed.
+ +
+Definition In_pos_top_imps_split_l : forall l (A : MPropF) n, In (A, S n) (pos_top_imps l) ->
+          existsT2 l0 l1, (l = l0 ++ A :: l1) /\
+                          (length l0 = n) /\
+                          (l0 = fst (nth_split n (remove_nth (S n) A l))) /\
+                          (l1 = snd (nth_split n (remove_nth (S n) A l))).
+Proof.
+induction l.
+- intros. simpl. exfalso. simpl in H. destruct H.
+- intros. simpl in H. destruct a as [n0| | |].
+  * apply In_InT_pair in H. apply InT_map_iff in H. destruct H as ([m n1] & e & i).
+    simpl in e. inversion e. subst. destruct n. exfalso.
+    apply InT_In in i. apply In_pos_top_imps_0_False in i. assumption.
+    apply InT_In in i. pose (IHl A n i). destruct s as (x & x0 & e2 & e3 & e1 & e0).
+    subst. exists (# n0 :: x). exists x0. repeat split.
+    rewrite effective_remove_nth in e1. rewrite effective_remove_nth in e0.
+    assert (fst (# n0 :: fst (nth_split (S (length x)) (x ++ x0)), snd (nth_split (S (length x)) (x ++ x0))) =
+    # n0 :: fst (nth_split (S (length x)) (x ++ x0))). simpl. reflexivity.
+    assert (S (S (length x)) = S (length (# n0 :: x))). simpl. reflexivity.
+    rewrite H0. assert ((# n0 :: x ++ A :: x0) = ((# n0 :: x) ++ A :: x0)). simpl. reflexivity.
+    rewrite H1. clear H0. clear H1. rewrite effective_remove_nth.
+    pose (nth_split_idL (# n0 :: x) x0). simpl (length (# n0 :: x)) in e2.
+    rewrite <- e2. reflexivity.
+    rewrite effective_remove_nth in e0. rewrite effective_remove_nth in e1.
+    assert (S (S (length x)) = S (length (# n0 :: x))). simpl. reflexivity.
+    rewrite H. assert ((# n0 :: x ++ A :: x0) = ((# n0 :: x) ++ A :: x0)). simpl. reflexivity.
+    rewrite H0. clear H. clear H0. rewrite effective_remove_nth.
+    pose (nth_split_idR (# n0 :: x) x0). simpl (length (# n0 :: x)) in e2.
+    rewrite <- e2. reflexivity.
+  * apply In_InT_pair in H. apply InT_map_iff in H. destruct H as ([m n1] & e & i).
+    simpl in e. inversion e. subst. destruct n.
+    -- exfalso. apply InT_In in i. apply In_pos_top_imps_0_False in i. assumption.
+      -- apply InT_In in i. pose (IHl A n i). destruct s as (x & x0 & e2 & e3 & e1 & e0).
+      subst. exists (Bot :: x). exists x0. repeat split.
+      rewrite effective_remove_nth in e1. rewrite effective_remove_nth in e0.
+      assert (fst (Bot :: fst (nth_split (S (length x)) (x ++ x0)), snd (nth_split (S (length x)) (x ++ x0))) =
+      Bot :: fst (nth_split (S (length x)) (x ++ x0))). simpl. reflexivity.
+    assert (S (S (length x)) = S (length (Bot :: x))). simpl. reflexivity.
+    rewrite H0. assert ((Bot :: x ++ A :: x0) = ((Bot :: x) ++ A :: x0)). simpl. reflexivity.
+    rewrite H1. clear H0. clear H1. rewrite effective_remove_nth.
+    pose (nth_split_idL (Bot :: x) x0). simpl (length (Bot :: x)) in e2.
+    rewrite <- e2. reflexivity.
+    rewrite effective_remove_nth in e0. rewrite effective_remove_nth in e1.
+    assert (S (S (length x)) = S (length (Bot :: x))). simpl. reflexivity.
+    rewrite H. assert ((Bot :: x ++ A :: x0) = ((Bot :: x) ++ A :: x0)). simpl. reflexivity.
+    rewrite H0. clear H. clear H0. rewrite effective_remove_nth.
+    pose (nth_split_idR (Bot :: x) x0). simpl (length (Bot :: x)) in e2.
+    rewrite <- e2. reflexivity.
+  * apply In_InT_pair in H. inversion H.
+    + inversion H1. subst. exists []. exists l. repeat split. simpl.
+      destruct (eq_dec_form (a1 --> a2) (a1 --> a2)). reflexivity. exfalso. auto.
+    + subst. apply InT_map_iff in H1. destruct H1 as ([m n1] & e & i).
+        simpl in e. inversion e. subst. destruct n. exfalso.
+        apply InT_In in i. apply In_pos_top_imps_0_False in i. assumption.
+        apply InT_In in i. pose (IHl A n i). destruct s as (x & x0 & e2 & e3 & e1 & e0).
+        subst. exists (a1 --> a2 :: x). exists x0. repeat split.
+        rewrite effective_remove_nth in e1. rewrite effective_remove_nth in e0.
+        assert (fst (a1 --> a2 :: fst (nth_split (S (length x)) (x ++ x0)), snd (nth_split (S (length x)) (x ++ x0))) =
+        a1 --> a2 :: fst (nth_split (S (length x)) (x ++ x0))). simpl. reflexivity.
+        assert (S (S (length x)) = S (length (a1 --> a2 :: x))). simpl. reflexivity.
+        rewrite H1. assert ((a1 --> a2 :: x ++ A :: x0) = ((a1 --> a2 :: x) ++ A :: x0)). simpl. reflexivity.
+        rewrite H2. clear H2. clear H1. rewrite effective_remove_nth.
+        pose (nth_split_idL (a1 --> a2 :: x) x0). simpl (length (a1 --> a2 :: x)) in e2.
+        rewrite <- e2. reflexivity.
+        rewrite effective_remove_nth in e0. rewrite effective_remove_nth in e1.
+        assert (S (S (length x)) = S (length (a1 --> a2 :: x))). simpl. reflexivity.
+        rewrite H0. assert ((a1 --> a2 :: x ++ A :: x0) = ((a1 --> a2 :: x) ++ A :: x0)). simpl. reflexivity.
+        rewrite H1. clear H0. clear H1. rewrite effective_remove_nth.
+        pose (nth_split_idR (a1 --> a2 :: x) x0). simpl (length (a1 --> a2 :: x)) in e2.
+        rewrite <- e2. reflexivity.
+        * apply In_InT_pair in H. apply InT_map_iff in H. destruct H as ([m n1] & e & i).
+         simpl in e. inversion e. subst. destruct n. exfalso.
+        apply InT_In in i. apply In_pos_top_imps_0_False in i. assumption.
+        apply InT_In in i. pose (IHl A n i). destruct s as (x & x0 & e2 & e3 & e1 & e0).
+        subst. exists (Box a :: x). exists x0. repeat split.
+        rewrite effective_remove_nth in e1. rewrite effective_remove_nth in e0.
+        assert (fst (Box a :: fst (nth_split (S (length x)) (x ++ x0)), snd (nth_split (S (length x)) (x ++ x0))) =
+        Box a :: fst (nth_split (S (length x)) (x ++ x0))). simpl. reflexivity.
+        assert (S (S (length x)) = S (length (Box a :: x))). simpl. reflexivity.
+        rewrite H0. assert ((Box a :: x ++ A :: x0) = ((Box a :: x) ++ A :: x0)). simpl. reflexivity.
+        rewrite H1. clear H0. clear H1. rewrite effective_remove_nth.
+        pose (nth_split_idL (Box a :: x) x0). simpl (length (Box a :: x)) in e2.
+        rewrite <- e2. reflexivity.
+        rewrite effective_remove_nth in e0. rewrite effective_remove_nth in e1.
+        assert (S (S (length x)) = S (length (Box a :: x))). simpl. reflexivity.
+        rewrite H. assert ((Box a :: x ++ A :: x0) = ((Box a :: x) ++ A :: x0)). simpl. reflexivity.
+        rewrite H0. clear H. clear H0. rewrite effective_remove_nth.
+        pose (nth_split_idR (Box a :: x) x0). simpl (length (Box a :: x)) in e2.
+        rewrite <- e2. reflexivity.
+Defined.
+ +
+Lemma In_l_imp_In_pos_top_imps : forall l (A B : MPropF), In (Imp A B) l ->
+                                    existsT2 n, In ((Imp A B), n) (pos_top_imps l).
+Proof.
+induction l.
+- intros. simpl in H. destruct H.
+- intros. apply In_InT in H. inversion H.
+  * subst. exists 1. simpl. left. reflexivity.
+  * destruct a.
+    + subst. apply InT_In in H1. apply IHl in H1. destruct H1. exists (S x). simpl.
+      apply InT_In. apply InT_map_iff. exists (A --> B, x). simpl. split ; auto.
+      apply In_InT_pair. assumption.
+    + subst. apply InT_In in H1. apply IHl in H1. destruct H1. exists (S x). simpl.
+      apply InT_In. apply InT_map_iff. exists (A --> B, x). simpl. split ; auto.
+      apply In_InT_pair. assumption.
+    + subst. apply InT_In in H1. apply IHl in H1. destruct H1. exists (S x). simpl.
+      right. apply InT_In. apply InT_map_iff. exists (A --> B, x). simpl. split ; auto.
+      apply In_InT_pair. assumption.
+    + subst. apply InT_In in H1. apply IHl in H1. destruct H1. exists (S x). simpl.
+      apply InT_In. apply InT_map_iff. exists (A --> B, x). simpl. split ; auto.
+      apply In_InT_pair. assumption.
+Qed.
+ +
+Lemma Good_pos_in_pos_top_imps : forall A B Δ0 Δ1,
+              In (A --> B, S (length Δ0)) (pos_top_imps (Δ0 ++ A --> B :: Δ1)).
+Proof.
+induction Δ0.
+- intros. simpl. auto.
+- intros. destruct a.
+  * simpl. apply InT_In. apply InT_map_iff. exists (A --> B, S (length Δ0)).
+    split. simpl. reflexivity. apply In_InT_pair. apply IHΔ0.
+  * simpl. apply InT_In. apply InT_map_iff. exists (A --> B, S (length Δ0)).
+    split. simpl. reflexivity. apply In_InT_pair. apply IHΔ0.
+  * simpl. right. apply InT_In. apply InT_map_iff. exists (A --> B, S (length Δ0)).
+    split. simpl. reflexivity. apply In_InT_pair. apply IHΔ0.
+  * simpl. apply InT_In. apply InT_map_iff. exists (A --> B, S (length Δ0)).
+    split. simpl. reflexivity. apply In_InT_pair. apply IHΔ0.
+Qed.
+ +
+(* From there we can show that given a specific (Imp A B) on the right of a sequent S,
+   there is only finitely many premises via ImpR applied on this implication. But we
+   need to do it for all implications on the right of this sequent. *)

+ +
+Definition ImpR_help01 : forall prem s l, InT prem (prems_Imp_R l s) ->
+                  (existsT2 n A B Γ0 Γ1 Δ0 Δ1,
+                        (In ((Imp A B), S n) l) /\
+                        (prem = (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)) /\
+                        (Γ0 ++ Γ1 = fst s) /\
+                        (Δ0 = (fst (nth_split n (remove_nth (S n) (Imp A B) (snd s))))) /\
+                        (Δ1 = (snd (nth_split n (remove_nth (S n) (Imp A B) (snd s)))))).
+Proof.
+intros prem s. destruct s. destruct prem. induction l3 ; intros X.
+- simpl in X. inversion X.
+- destruct a as [m n]. destruct m as [n0| | |].
+  * simpl in X. destruct n.
+    + pose (IHl3 X). destruct s as (x & x0 & x1 & x2 & x3 & x4 & x5 & p).
+        decompose record p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. repeat split ; try auto. apply in_cons. tauto.
+    + pose (IHl3 X). destruct s as (x & x0 & x1 & x2 & x3 & x4 & x5 & p). decompose record p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. repeat split ; try tauto. apply in_cons. tauto.
+  * simpl in X. destruct n.
+    + pose (IHl3 X). destruct s as (x & x0 & x1 & x2 & x3 & x4 & x5 & p). decompose record p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. repeat split ; try tauto. apply in_cons. tauto.
+    + pose (IHl3 X). destruct s as (x & x0 & x1 & x2 & x3 & x4 & x5 & p). decompose record p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. repeat split ; try tauto. apply in_cons. tauto.
+  * destruct n.
+    + pose (IHl3 X). destruct s as (x & x0 & x1 & x2 & x3 & x4 & x5 & p). decompose record p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. repeat split ; try tauto. apply in_cons. tauto.
+    + apply InT_app_or in X. destruct X.
+      { simpl (fst (l, l0)) in i. simpl (snd (l, l0)) in i.
+        unfold listInsertsR_Seqs in i. apply InT_map_iff in i. destruct i.
+        destruct p. subst. unfold listInserts in i. apply InT_map_iff in i. destruct i.
+        destruct p. destruct x0. subst. destruct (list_of_splits l). simpl in i. exists n.
+        exists m1. exists m2. exists l4. exists l5. simpl (snd (l, l0)).
+        simpl (fst (l, l0)).
+        exists (fst (nth_split n (remove_nth (S n) (m1 --> m2) l0))).
+        exists (snd (nth_split n (remove_nth (S n) (m1 --> m2) l0))).
+        repeat split ; try auto. apply in_eq. rewrite i0. apply InT_In. assumption. }
+      { pose (IHl3 i). destruct s as (x & x0 & x1 & x2 & x3 & x4 & x5 & p). decompose record p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. repeat split ; try tauto. apply in_cons. tauto. }
+  * simpl in X. destruct n.
+    + pose (IHl3 X). destruct s as (x & x0 & x1 & x2 & x3 & x4 & x5 & p). decompose record p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. repeat split ; try tauto. apply in_cons. tauto.
+    + pose (IHl3 X). destruct s as (x & x0 & x1 & x2 & x3 & x4 & x5 & p). decompose record p. exists x. exists x0. exists x1.
+      exists x2. exists x3. exists x4. exists x5. repeat split ; try tauto. apply in_cons. tauto.
+Defined.
+ +
+Definition ImpR_help1 : forall prem s, InT prem (prems_Imp_R (pos_top_imps (snd s)) s) -> ImpRRule [prem] s.
+Proof.
+intros prem s X. pose (ImpR_help01 _ _ _ X). destruct s0. destruct s.
+destruct s0. destruct s as (B & Γ0 & Γ1 & Δ0 & Δ1 & i & e2 & e3 & e4 & e5).
+subst. simpl in i, e3. subst.
+simpl (snd (_, _)) in *.
+apply In_pos_top_imps_split_l in i. destruct i. destruct s as (x2 & H1 & H2 & H3 & H4).
+subst.
+rewrite <- H4. rewrite effective_remove_nth. rewrite <- nth_split_idL.
+apply ImpRRule_I.
+Defined.
+ +
+Definition ImpR_help002 : forall Γ0 Γ1 Δ0 Δ1 A B,
+           InT (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) (listInsertsR_Seqs (Γ0 ++ Γ1) (Δ0 ++ B :: Δ1) A).
+Proof.
+intros. unfold listInsertsR_Seqs. apply InT_map_iff. exists (Γ0 ++ A :: Γ1). split.
+reflexivity. unfold listInserts. apply InT_map_iff. exists (Γ0, Γ1). simpl. split.
+reflexivity. destruct (list_of_splits (Γ0 ++ Γ1)). simpl. pose (i Γ0 Γ1).
+apply In_InT_seqs. apply i0. reflexivity.
+Defined.
+ +
+Definition ImpR_help02 : forall Γ0 Γ1 Δ0 Δ1 A B l n,
+                                ImpRRule [(Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1)] (Γ0 ++ Γ1, Δ0 ++ (Imp A B) :: Δ1) ->
+                                (length Δ0 = n) ->
+                                (In ((Imp A B), S n) l) ->
+                                InT (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) (prems_Imp_R l (Γ0 ++ Γ1, Δ0 ++ (Imp A B) :: Δ1)).
+Proof.
+induction l ; intros.
+- inversion H1.
+- destruct a. destruct m.
+  * apply In_InT_pair in H1. inversion H1. subst. inversion H3. subst. apply InT_In in H3.
+    assert (J1: length Δ0 = length Δ0). reflexivity.
+    pose (IHl _ H J1 H3). simpl. destruct n0. assumption. assumption.
+  * apply In_InT_pair in H1. inversion H1. subst. inversion H3. subst. apply InT_In in H3.
+    assert (J1: length Δ0 = length Δ0). reflexivity.
+    pose (IHl _ H J1 H3). simpl. destruct n0. assumption. assumption.
+  * apply In_InT_pair in H1. inversion H1.
+    + subst. inversion H3. subst. destruct Δ0.
+      { simpl. pose (ImpR_help002 Γ0 Γ1 [] Δ1 A B). simpl in i. destruct (eq_dec_form (A --> B) (A --> B)).
+        apply InT_or_app. auto. exfalso. auto. }
+      { unfold prems_Imp_R. apply InT_or_app. left.
+        assert ((remove_nth (S (length (m :: Δ0))) (A --> B) (snd (Γ0 ++ Γ1, (m :: Δ0) ++ A --> B :: Δ1))) =
+        (m :: Δ0) ++ Δ1). simpl (snd (Γ0 ++ Γ1, (m :: Δ0) ++ A --> B :: Δ1)).
+        pose (effective_remove_nth (A --> B) (m :: Δ0) Δ1). assumption.
+        rewrite H0.
+        assert (fst (nth_split (length (m :: Δ0)) ((m :: Δ0) ++ Δ1)) = (m :: Δ0) /\
+        snd (nth_split (length (m :: Δ0)) ((m :: Δ0) ++ Δ1)) = Δ1). apply nth_split_length_id.
+        reflexivity. destruct H2. rewrite H2. rewrite H4. apply ImpR_help002. }
+    + subst. assert (J1: (length Δ0) = (length Δ0)). reflexivity. apply InT_In in H3.
+      pose (IHl (length Δ0) H J1 H3). simpl. destruct n0. assumption. apply InT_or_app. auto.
+  * apply In_InT_pair in H1. inversion H1. subst. inversion H3. subst. apply InT_In in H3.
+    assert (J1: length Δ0 = length Δ0). reflexivity.
+    pose (IHl _ H J1 H3). simpl. destruct n0. assumption. assumption.
+Defined.
+ +
+Definition ImpR_help2 : forall prem s, ImpRRule [prem] s -> InT prem (prems_Imp_R (pos_top_imps (snd s)) s).
+Proof.
+intros. inversion H. subst. simpl.
+pose (@ImpR_help02 Γ0 Γ1 Δ0 Δ1 A B (pos_top_imps (Δ0 ++ A --> B :: Δ1)) (length Δ0)). apply i ; try assumption.
+reflexivity. apply Good_pos_in_pos_top_imps.
+Defined.
+ +
+Definition finite_ImpR_premises_of_S : forall (s : Seq), existsT2 listImpRprems,
+              (forall prems, ((ImpRRule prems s) -> (InT prems listImpRprems)) *
+                             ((InT prems listImpRprems) -> (ImpRRule prems s))).
+Proof.
+intro s. destruct s.
+exists (map (fun y => [y]) (prems_Imp_R (pos_top_imps l0) (l,l0))).
+intros. split ; intro.
+- inversion H. subst. apply InT_map_iff.
+  exists (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1). split. reflexivity.
+  pose (@ImpR_help2 (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1)). simpl in i. apply i.
+  assumption.
+- apply InT_map_iff in H. destruct H. destruct p. subst. apply ImpR_help1. simpl. assumption.
+Defined.
+
+
+ +
+ + + diff --git a/K.KS.KS_termination_KR.html b/K.KS.KS_termination_KR.html new file mode 100644 index 0000000..e27d632 --- /dev/null +++ b/K.KS.KS_termination_KR.html @@ -0,0 +1,146 @@ + + + + + + + + + + + + + +
+
+

K.KS.KS_termination_KR

+ +
+Require Import List.
+Export ListNotations.
+Require Import Lia.
+Require Import PeanoNat.
+ +
+Require Import KS_calc.
+Require Import KS_dec.
+Require Import KS_termination_measure.
+Require Import KS_termination_prelims.
+ +
+(* Now let us tackle the KR rule. *)
+ +
+Fixpoint prems_Box_R (l : list MPropF) (s : Seq) : list (list Seq) :=
+match l with
+  | nil => nil
+  | h :: t => match h with
+              | Box A => [((unboxed_list (top_boxes (fst s))), [A])] :: (prems_Box_R t s)
+              | _ => prems_Box_R t s
+              end
+end.
+ +
Definition KR_help01 : forall prems s (l : list MPropF), InT prems (prems_Box_R l s) ->
+                  (existsT2 (A : MPropF),
+                        (In (Box A) l) /\
+                        (prems = [(unboxed_list (top_boxes (fst s)) , [A])])).
+Proof.
+intros prems s. destruct s. induction l1 ; intros X.
+- simpl in X. inversion X.
+- simpl in X. destruct a.
+  * apply IHl1 in X. destruct X as [x p]. repeat destruct p. subst.
+     exists x. repeat split ; try auto ; try apply in_cons ; try assumption.
+  * apply IHl1 in X. destruct X as [x p]. repeat destruct p. subst.
+    exists x. repeat split ; try auto ; try apply in_cons ; try assumption.
+  * apply IHl1 in X. destruct X as [x p]. repeat destruct p. subst.
+    exists x. repeat split ; try auto ; try apply in_cons ; try assumption.
+  * inversion X.
+    + subst. exists a. repeat split ; try auto ; try apply in_eq.
+    + apply IHl1 in H0. destruct H0 as [x p]. repeat destruct p. subst.
+      exists x. repeat split ; try auto ; try apply in_cons ; try assumption.
+Defined.
+ +
+Definition KR_help1 : forall prems s, InT prems (prems_Box_R (top_boxes (snd s)) s) ->
+                                         KRRule prems s.
+Proof.
+intros prems s X. destruct (@KR_help01 _ _ _ X) as (x&Hi&Heq).
+repeat destruct s0. destruct s. simpl in X.
+repeat destruct p. subst. simpl in *. assert (In (Box x) l0). apply top_boxes_incl_list.
+assumption. apply in_splitT in H. destruct H. repeat destruct s.
+rewrite e. apply KRRule_I. intro. intros. apply in_top_boxes in H.
+destruct H. repeat destruct s. repeat destruct p. exists x2. assumption.
+simpl. apply top_boxes_nobox_gen_ext.
+Defined.
+ +
+Definition KR_help02 : forall Γ Δ0 Δ1 A l, KRRule [(unboxed_list , [A])] (Γ, Δ0 ++ Box A :: Δ1) ->
+                                             (is_Boxed_list ) ->
+                                             (nobox_gen_ext Γ) ->
+                                             (In (Box A) l) ->
+                                             InT [(unboxed_list , [A])] (prems_Box_R l (Γ, Δ0 ++ Box A :: Δ1)).
+Proof.
+induction l ; intros.
+- inversion H0.
+- simpl. destruct a as [n| | |].
+  * assert (InT (Box A) (# n :: l)). apply in_splitT in H0. destruct H0. destruct s. rewrite e.
+    apply InT_or_app. right. apply InT_eq. inversion H1. inversion H3. apply InT_In in H3.
+    pose (IHl X H X0 H3). assumption.
+  * assert (InT (Box A) (Bot :: l)). apply in_splitT in H0. destruct H0. destruct s. rewrite e.
+    apply InT_or_app. right. apply InT_eq. inversion H1. inversion H3. apply InT_In in H3.
+    pose (IHl X H X0 H3). assumption.
+  * assert (InT (Box A) (a1 --> a2 :: l)). apply in_splitT in H0. destruct H0. destruct s. rewrite e.
+    apply InT_or_app. right. apply InT_eq. inversion H1. inversion H3. apply InT_In in H3.
+    pose (IHl X H X0 H3). assumption.
+  * assert (InT (Box A) (Box a :: l)). apply in_splitT in H0. destruct H0. destruct s. rewrite e.
+    apply InT_or_app. right. apply InT_eq. inversion H1.
+    + subst. inversion H3. subst. pose (nobox_gen_ext_top_boxes_identity X0 H). rewrite e.
+      apply InT_eq.
+    + subst. apply InT_In in H3. pose (IHl X H X0 H3). apply InT_cons. assumption.
+Defined.
+ +
+Definition KR_help2 : forall prem s, KRRule [prem] s ->
+                      InT [prem] (prems_Box_R (top_boxes (snd s)) s).
+Proof.
+intros. inversion X. subst. simpl.
+pose (@KR_help02 Γ0 Δ0 Δ1 A (top_boxes (Δ0 ++ Box A :: Δ1))). apply i ; try assumption.
+rewrite top_boxes_distr_app. simpl. apply in_or_app. right. apply in_eq.
+Defined.
+ +
+Definition finite_KR_premises_of_S : forall (s : Seq), existsT2 listKRprems,
+              (forall prems, ((KRRule prems s) -> (InT prems listKRprems)) *
+                             ((InT prems listKRprems) -> (KRRule prems s))).
+Proof.
+intros. destruct s.
+exists (prems_Box_R (top_boxes l0) (l,l0)).
+intros. split ; intro.
+- inversion X. subst.
+  pose (@KR_help2 (unboxed_list , [A]) (l, Δ0 ++ Box A :: Δ1)). apply i.
+  assumption.
+- pose (@KR_help1 prems (l, l0)). apply k. assumption.
+Defined.
+
+
+ +
+ + + diff --git a/K.KS.KS_termination_init.html b/K.KS.KS_termination_init.html new file mode 100644 index 0000000..d5e56db --- /dev/null +++ b/K.KS.KS_termination_init.html @@ -0,0 +1,81 @@ + + + + + + + + + + + + + +
+
+

K.KS.KS_termination_init

+ +
+Require Import List.
+Export ListNotations.
+Require Import Lia.
+Require Import PeanoNat.
+ +
+Require Import KS_calc.
+Require Import KS_dec.
+Require Import KS_termination_measure.
+Require Import KS_termination_prelims.
+ +
+(* Obviously, we can obtain the same result for initial sequents. *)
+ +
+Lemma finite_IdP_premises_of_S : forall (s : Seq), existsT2 listIdPprems,
+              (forall prems, ((IdPRule prems s) -> (InT prems listIdPprems)) *
+                             ((InT prems listIdPprems) -> (IdPRule prems s))).
+Proof.
+intros s. destruct (dec_IdP_rule s).
+- exists [[]]. intros. split ; intro.
+  * inversion H. subst. apply InT_eq.
+  * inversion H. subst. assumption. inversion H1.
+- exists []. intros. split ; intro.
+  * inversion H. subst. exfalso. apply f. assumption.
+  * inversion H.
+Qed.
+ +
+Lemma finite_BotL_premises_of_S : forall (s : Seq), existsT2 listBotLprems,
+              (forall prems, ((BotLRule prems s) -> (InT prems listBotLprems)) *
+                             ((InT prems listBotLprems) -> (BotLRule prems s))).
+Proof.
+intros. destruct (dec_BotL_rule s).
+- exists [[]]. intros. split ; intro.
+  * inversion H. subst. apply InT_eq.
+  * inversion H. subst. assumption. inversion H1.
+- exists []. intros. split ; intro.
+  * inversion H. subst. exfalso. apply f. assumption.
+  * inversion H.
+Qed.
+
+
+ +
+ + + diff --git a/K.KS.KS_termination_measure.html b/K.KS.KS_termination_measure.html new file mode 100644 index 0000000..d10462f --- /dev/null +++ b/K.KS.KS_termination_measure.html @@ -0,0 +1,171 @@ + + + + + + + + + + + + + +
+
+

K.KS.KS_termination_measure

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat.
+Require Import Lia.
+ +
+Require Import KS_calc.
+ +
+Lemma NoDup_incl_lengthT : forall (l l' : list MPropF), NoDup l -> incl l l' ->
+          {length l < length l'} + {length l = length l'}.
+Proof. intros. apply Compare_dec.le_lt_eq_dec, NoDup_incl_length; assumption. Qed.
+ +
+(* Then the definition we were initially looking for can be reached: *)
+ +
+Definition measure (s : Seq) : nat :=
+    (size_LF (fst s)) + (size_LF (snd s)).
+ +
+(* It is clear that measure counts the occurrences of implications in a
+   sequent s. As a consequence, if that number is 0 we know for sure that the
+   rules for implication on the left or right cannot be applied upwards on s.
+   This is the meaning of the lemma measure_is_0. 
+
+   But first we need a preliminary lemma which claims that if an implication is
+   in a list, then size_LF of that list is higher than one.*)

+ +
+Lemma In_Imp_size_LF_is_non_0 (l : list MPropF) :
+    forall A B, (In (Imp A B) l) -> (le 1 (size_LF l)).
+Proof.
+intros A B Hin. induction l.
+- inversion Hin.
+- inversion Hin.
+  * subst. simpl. rewrite <- Nat.succ_le_mono. apply le_0_n.
+  * pose (IHl H). simpl. destruct l0.
+    + rewrite Nat.add_1_r. rewrite <- Nat.succ_le_mono. apply le_0_n.
+    + rewrite <- plus_n_Sm. rewrite <- Nat.succ_le_mono. apply le_0_n.
+Qed.
+ +
+Theorem term_meas_is_0 (s : Seq) :
+    (measure s) = 0 -> (existsT2 ps, (ImpRRule ps s) + (ImpLRule ps s)) -> False.
+Proof.
+intros is0 RA. destruct RA. destruct s0.
+- inversion i. subst. unfold measure in is0. simpl in is0.
+  assert (size_LF (Δ0 ++ A --> B :: Δ1) = 0). lia.
+  assert (In (A --> B) (Δ0 ++ A --> B :: Δ1)). apply in_or_app. right. apply in_eq.
+  pose (In_Imp_size_LF_is_non_0 (Δ0 ++ A --> B :: Δ1) A B H0). lia.
+- inversion i. subst.
+  assert (In (A --> B) (Γ0 ++ A --> B :: Γ1)). apply in_or_app. right. apply in_eq.
+  pose (In_Imp_size_LF_is_non_0 (Γ0 ++ A --> B :: Γ1) A B H). unfold measure in is0.
+  simpl in is0. assert (size_LF (Δ0 ++ Δ1) = 0). lia. lia.
+Qed.
+ +
+Lemma size_LF_dist_app : forall l1 l2, size_LF (l1 ++ l2) =
+                                               plus (size_LF l1) (size_LF l2).
+Proof.
+induction l1.
+- intros. auto.
+- intros. simpl. rewrite IHl1. lia.
+Qed.
+ +
+Lemma size_nobox_gen_ext : forall l1 l2, nobox_gen_ext l1 l2 ->
+                                               (size_LF l1 <= size_LF l2).
+Proof.
+intros. induction X.
+- simpl. lia.
+- simpl. lia.
+- simpl. lia.
+Qed.
+ +
+Lemma size_unboxed : forall l, (size_LF (unboxed_list l) <= size_LF l).
+Proof.
+induction l.
+- simpl. lia.
+- simpl. destruct a ; simpl ; lia.
+Qed.
+ +
+Lemma size_top_boxes : forall l, (size_LF (top_boxes l) <= size_LF l).
+Proof.
+induction l.
+- simpl. lia.
+- simpl. destruct a ; simpl ; lia.
+Qed.
+ +
+(* We prove some lemmas about these notions. *)
+ +
+Lemma In_Box_size_LF_is_non_0 (l : list MPropF) :
+    forall A, (In (Box A) l) -> (le 1 (size_LF l)).
+Proof.
+intros A Hin. induction l.
+- inversion Hin.
+- inversion Hin.
+  * subst. simpl. rewrite <- Nat.succ_le_mono. apply le_0_n.
+  * pose (IHl H). simpl. destruct l0.
+    + rewrite Nat.add_1_r. rewrite <- Nat.succ_le_mono. apply le_0_n.
+    + rewrite <- plus_n_Sm. rewrite <- Nat.succ_le_mono. apply le_0_n.
+Qed.
+ +
+Theorem measure_is_0 (s : Seq) :
+    (measure s) = 0 -> (existsT2 ps, (KRRule ps s)) -> False.
+Proof.
+intros is0 RA. destruct RA. inversion k. subst. unfold measure in is0.
+simpl in is0.
+assert (size_LF (Δ0 ++ Box A :: Δ1) = 0). lia.
+assert (In (Box A) (Δ0 ++ Box A :: Δ1)). apply in_or_app. right. apply in_eq.
+pose (In_Box_size_LF_is_non_0 (Δ0 ++ Box A :: Δ1) A H1). lia.
+Qed.
+ +
+(* Third, we need to prove that if no KS rule is applicable to a sequent s,
+   then its derivations have a height equal to 0. *)

+ +
+Theorem no_KS_rule_applic : forall s, (forall ps, (KS_rules ps s) -> False) ->
+                                 forall (D : KS_drv s), derrec_height D = 0.
+Proof.
+intros s noRA D. induction D.
+- auto.
+- exfalso. apply noRA with (ps:=ps). assumption.
+Qed.
+
+
+ +
+ + + diff --git a/K.KS.KS_termination_prelims.html b/K.KS.KS_termination_prelims.html new file mode 100644 index 0000000..66af4d9 --- /dev/null +++ b/K.KS.KS_termination_prelims.html @@ -0,0 +1,411 @@ + + + + + + + + + + + + + +
+
+

K.KS.KS_termination_prelims

+ +
+Require Import List.
+Export ListNotations.
+Require Import Lia.
+Require Import PeanoNat.
+ +
+Require Import KS_calc.
+Require Import KS_dec.
+Require Import KS_termination_measure.
+ +
+Set Implicit Arguments.
+ +
+(* In this file we prove that each sequent Γ |- Δ has a derivation (not proof) D in
+   KS of maximal height: all derivations in KS of this sequent must have an
+   inferior or equal height to that of D.
+
+   This result can be understood as claiming that the proof search defined by KS
+   terminates. *)

+ +
+Definition proj1_sigT2 {A : Type} (P : A -> Type) (e:sigT P) := match e with
+                                    | existT _ a b => a
+                                    end.
+ +
+Definition proj2_sigT2 {A : Type} (P : A -> Type) (e : sigT P) :=
+  match e return (P (proj1_sigT2 e)) with
+  | existT _ a b => b
+  end.
+ +
+Lemma In_InT : forall (A : MPropF) l, In A l -> InT A l.
+Proof.
+intros. apply in_splitT in H. destruct H. destruct s. subst. apply InT_or_app. right.
+apply InT_eq.
+Qed.
+ +
+Definition In_InT_pair : forall (A : MPropF) (n : nat) l, In (A, n) l -> InT (A, n) l.
+Proof.
+induction l.
+- intro. inversion H.
+- intro. assert ({(A, n) = a} + {(A, n) <> a}). destruct a.
+  destruct (eq_dec_form A m). subst. destruct (Nat.eq_dec n n0). subst. auto.
+  right. intro. apply n1. inversion H0. auto. right. intro. inversion H0.
+  auto. destruct H0. subst. apply InT_eq. apply InT_cons. apply IHl.
+  inversion H. exfalso. auto. assumption.
+Defined.
+ +
+Lemma dec_le : forall n m, (n <= m) + ((n <= m) -> False).
+Proof.
+induction n.
+- intro m. left. apply le_0_n.
+- intro m. pose (IHn m). destruct s.
+  * destruct (Nat.eq_dec n m). subst. right. intro. lia. left. lia.
+  * right. intro. apply f. lia.
+Qed.
+ +
+Definition InT_map_iff : forall {A B : Type} (f : A -> B) (l : list A) (y : B),
+       (InT y (map f l) -> (existsT2 x : A, (f x = y) * InT x l)) *
+       ((existsT2 x : A, (f x = y) * InT x l) -> InT y (map f l)).
+Proof.
+induction l.
+- intros. simpl. split. intro. inversion X. intro. destruct X. destruct p. inversion i.
+- simpl. intros. split.
+  * intro. inversion X.
+    + subst. exists a. split ; [ reflexivity | apply InT_eq].
+    + subst. pose (IHl y). destruct p. apply s in X0. destruct X0. destruct p. exists x.
+      split. assumption. apply InT_cons. assumption.
+  * intro. pose (IHl y). destruct p. clear s. pose (proj2_sigT2 X).
+    destruct p. inversion i0. subst. rewrite <- e. rewrite <- H0. apply InT_eq.
+    subst. assert (existsT2 x : A, (f x = y) * InT x l). exists (proj1_sigT2 X).
+    split ; assumption. apply i in X1. apply InT_cons. assumption.
+Defined.
+ +
+Fixpoint top_imps (l : list MPropF) : list MPropF :=
+match l with
+  | nil => nil
+  | h :: t => match h with
+                | Imp A B => (Imp A B) :: top_imps t
+                | _ => top_imps t
+              end
+end.
+ +
+Fixpoint pos_top_imps (l : list MPropF) : (list ((MPropF) * nat)) :=
+match l with
+  | nil => nil
+  | h :: t => match h with
+                | Imp A B => (Imp A B, 1) :: (map (fun y => (fst y, S (snd y))) (pos_top_imps t))
+                | _ => (map (fun y => (fst y, S (snd y))) (pos_top_imps t))
+              end
+end.
+ +
+Lemma le_False_lt : forall n m, ((n <= m) -> False) -> (m < n).
+Proof.
+induction n.
+- intros. exfalso. apply H. apply le_0_n.
+- induction m.
+  * intros. lia.
+  * intros. rewrite <- Nat.succ_lt_mono. apply IHn. intro. apply H.
+    rewrite <- Nat.succ_le_mono. assumption.
+Qed.
+ +
+Definition top_boxes_nobox_gen_ext : forall l, nobox_gen_ext (top_boxes l) l.
+Proof.
+induction l.
+- simpl. apply univ_gen_ext_nil.
+- destruct a ; simpl.
+  * apply univ_gen_ext_extra. intro. inversion X. inversion H. assumption.
+  * apply univ_gen_ext_extra. intro. inversion X. inversion H. assumption.
+  * apply univ_gen_ext_extra. intro. inversion X. inversion H. assumption.
+  * apply univ_gen_ext_cons. assumption.
+Defined.
+ +
+Lemma nobox_gen_ext_top_boxes_identity : forall l0 l1, nobox_gen_ext l0 l1 ->
+                                                       is_Boxed_list l0 ->
+                                                       (l0 = top_boxes l1).
+Proof.
+intros l0 l1 X. induction X.
+- intros. reflexivity.
+- intro. simpl. destruct x as [n | | | ].
+  * exfalso. pose (H (# n)). assert (In # n (# n :: l)). apply in_eq. apply e in H0.
+    destruct H0. inversion H0.
+  * exfalso. pose (H (Bot)). assert (In (Bot) (Bot :: l)). apply in_eq. apply e in H0.
+    destruct H0. inversion H0.
+  * exfalso. pose (H (x1 --> x2)). assert (In (x1 --> x2) (x1 --> x2 :: l)). apply in_eq. apply e in H0.
+    destruct H0. inversion H0.
+  * assert (l = top_boxes le). apply IHX. intro. intros. apply H. apply in_cons. assumption.
+    rewrite H0. reflexivity.
+- simpl. destruct x.
+  * apply IHX.
+  * apply IHX.
+  * apply IHX.
+  * exfalso. apply p. exists x. reflexivity.
+Qed.
+ +
+Fixpoint flatten_list {A : Type} (l : list (list A)) : list A :=
+  match l with
+  | [ ] => [ ]
+  | h :: t => h ++ (flatten_list t)
+  end
+.
+ +
+Definition InT_flatten_list_InT_elem {A : Type} : forall (l : list (list A)) b,
+        InT b (flatten_list l) -> (existsT2 bs, (InT b bs) * (InT bs l)).
+Proof.
+induction l.
+- intros. simpl in X. inversion X.
+- intros. simpl in X. apply InT_app_or in X. destruct X.
+  * exists a. split ; [assumption | apply InT_eq].
+  * pose (IHl b). apply s in i. destruct i. destruct p. exists x. split ; [assumption | apply InT_cons ; assumption].
+Defined.
+ +
+Lemma redundant_flatten_list : forall ls (s : Seq), map (fun z : list MPropF * list MPropF => [z;s]) ls =
+flatten_list (map (fun y : list MPropF * list MPropF => [[y;s]]) ls).
+Proof.
+induction ls.
+- intros. simpl. reflexivity.
+- simpl. intros. rewrite IHls. reflexivity.
+Qed.
+ +
+Definition InT_trans_flatten_list {A : Type} : forall (l : list (list A)) bs b,
+        (InT b bs) -> (InT bs l) -> (InT b (flatten_list l)).
+Proof.
+induction l.
+- intros. inversion X0.
+- intros. inversion X0.
+  * subst. simpl. apply InT_or_app. auto.
+  * subst. simpl. apply InT_or_app. right. pose (IHl bs b X X1) ; assumption.
+Defined.
+ +
+(* The next lemma claims that for each sequent s there is a derivation of that sequent. *)
+ +
+Lemma der_s_inhabited : forall s, inhabited (KS_drv s).
+Proof.
+intros s.
+pose (@dpI Seq KS_rules (fun _ : Seq => True) s).
+assert (H: (fun _ : Seq => True) s). apply I. apply d in H. apply inhabits. assumption.
+Qed.
+ +
+(* The next definition deals with the property of being a derivation D0 of maximal height
+   for the sequent s. *)

+ +
+Definition is_mhd (s: Seq) (D0 : KS_drv s): Prop :=
+      forall (D1 : KS_drv s), derrec_height D1 <= derrec_height D0.
+ +
+(* The next lemma says that given a list and an element, there are only finitely many
+   ways to insert this element in a list. *)

+ +
+Definition list_of_splits : forall (l : list MPropF), existsT2 listSplits,
+                            forall l1 l2, ((l1 ++ l2 = l) <-> In (l1, l2) listSplits).
+Proof.
+induction l.
+- exists [([],[])]. intros. destruct l1. split ; intro. simpl in H. rewrite H. apply in_eq.
+  simpl in H. destruct H. inversion H. reflexivity. inversion H. split ; intro.
+  simpl in H. inversion H. simpl. inversion H. inversion H0. inversion H0.
+- destruct IHl. exists ([([], a :: l)] ++ (map (fun y => (a :: (fst y), snd y)) x)).
+  intros. split ; intro.
+  * apply in_or_app. destruct l1. simpl. left. left. simpl in H. rewrite H.
+    reflexivity. simpl in H. inversion H. subst. right. pose (i l1 l2). destruct i0.
+    assert (l1 ++ l2 = l1 ++ l2). reflexivity. apply H0 in H2.
+    pose (in_map (fun y : list MPropF * list MPropF => (a :: fst y, snd y)) x (l1, l2) H2).
+    simpl in i. assumption.
+  * simpl in H. destruct H. inversion H. simpl. reflexivity. rewrite in_map_iff in H.
+    destruct H. destruct H. inversion H. subst. simpl. pose (i (fst x0) (snd x0)).
+    destruct i0. assert ((fst x0, snd x0) = x0). destruct x0. simpl. reflexivity.
+    rewrite H3 in H2. apply H2 in H0. rewrite H0. reflexivity.
+Defined.
+ +
+Definition listInserts l (A : MPropF) := map (fun y => (fst y) ++ A :: (snd y)) (proj1_sigT2 (list_of_splits l)).
+ +
+(* The next two lemmas make sure that the definition listInserts indeed captures the intended
+   list. *)

+ +
+Lemma listInserts_In : forall l (A: MPropF) l1 l2, ((l1 ++ l2 = l) -> In (l1 ++ A :: l2) (listInserts l A)).
+Proof.
+intros. unfold listInserts. assert (In (l1, l2) (proj1_sigT2 (list_of_splits l))). destruct (list_of_splits l).
+simpl. pose (i l1 l2). apply i0. assumption.
+pose (in_map (fun y : list MPropF * list MPropF => fst y ++ A :: snd y) (proj1_sigT2 (list_of_splits l)) (l1, l2) H0).
+simpl in i. assumption.
+Qed.
+ +
+Lemma In_listInserts : forall l (A: MPropF) l0, In l0 (listInserts l A) ->
+                            (exists l1 l2, prod (l1 ++ l2 = l) (l1 ++ A :: l2 = l0)).
+Proof.
+intros. unfold listInserts in H. destruct (list_of_splits l). simpl in H. rewrite in_map_iff in H.
+destruct H. destruct H. subst. exists (fst x0). exists (snd x0). split. apply i.
+destruct x0. simpl. assumption. reflexivity.
+Qed.
+ +
+(* The definitions below allow you to create the list of all sequents given two lists and a
+   formula to insert in one of them. *)

+ +
+Definition listInsertsR_Seqs (Γ Δ : list MPropF) (A : MPropF) := map (fun y => (y, Δ)) (listInserts Γ A).
+ +
+Definition listInsertsL_Seqs (Γ Δ : list MPropF) (A : MPropF) := map (fun y => (Γ, y)) (listInserts Δ A).
+ +
+(* The next definition allows one to create all sequents *)
+ +
+Definition listInsertsRL_Seqs (Γ Δ : list MPropF) (A B : MPropF) :=
+                  flatten_list (map (fun z => (map (fun y => (z, y)) (listInserts Δ B))) (listInserts Γ A)).
+ +
+(* Some useful functions *)
+ +
+Fixpoint remove_nth (n: nat) (A : MPropF) l:=
+    match n with
+      | 0 => l
+      | 1 => match l with
+               | [] => []
+               | B::tl => if (eq_dec_form A B) then tl else B:: tl
+             end
+      | S m => match l with
+                 | [] => []
+                 | B::tl => B::(remove_nth m A tl)
+               end
+      end.
+ +
+Fixpoint nth_split (n : nat) (l : list MPropF) : (list MPropF * list MPropF) :=
+    match n with
+      | 0 => ([], l)
+      | 1 => match l with
+               | [] => ([], [])
+               | B::tl => ([B] , tl)
+             end
+      | S m => match l with
+                 | [] => ([], [])
+                 | B::tl => (B :: (fst (nth_split m tl)), snd (nth_split m tl))
+               end
+      end.
+ +
+Lemma nth_split_length : forall (l0 l1 : list MPropF), (nth_split (length l0) (l0 ++ l1)) = (l0, l1).
+Proof.
+induction l0.
+- intros. simpl. reflexivity.
+- intros. pose (IHl0 l1). simpl (length (a :: l0)). simpl ((a :: l0) ++ l1).
+  simpl. destruct l0.
+  * simpl. reflexivity.
+  * assert (match length (m :: l0) with
+| 0 => ([a], (m :: l0) ++ l1)
+| S _ =>
+    (a :: fst (nth_split (length (m :: l0)) ((m :: l0) ++ l1)),
+    snd (nth_split (length (m :: l0)) ((m :: l0) ++ l1)))
+end = (a :: fst (nth_split (length (m :: l0)) ((m :: l0) ++ l1)),
+    snd (nth_split (length (m :: l0)) ((m :: l0) ++ l1)))). reflexivity. rewrite H.
+clear H. rewrite e. simpl. reflexivity.
+Qed.
+ +
+Lemma nth_split_idL : forall (l0 l1 : list MPropF), l0 = fst (nth_split (length l0) (l0 ++ l1)).
+Proof.
+induction l0.
+- intros. simpl. reflexivity.
+- intros. simpl (length (a :: l0)). pose (IHl0 l1). assert (fst (nth_split (S (length l0)) ((a :: l0) ++ l1)) =
+  a :: fst (nth_split (length l0) (l0 ++ l1))). simpl. destruct l0. simpl. reflexivity.
+  simpl. reflexivity. rewrite H. rewrite <- e. reflexivity.
+Qed.
+ +
+Lemma nth_split_idR : forall (l0 l1 : list MPropF), l1 = snd (nth_split (length l0) (l0 ++ l1)).
+Proof.
+induction l0.
+- intros. simpl. reflexivity.
+- intros. simpl (length (a :: l0)). pose (IHl0 l1). rewrite e. destruct l0.
+  * simpl. reflexivity.
+  * simpl (length (m :: l0)). simpl (S (S (length l0))).
+    simpl (length (m :: l0)) in e. rewrite <- e.
+    assert ((S (S (length l0))) = (length (a :: m :: l0))). simpl. reflexivity.
+    rewrite H. rewrite nth_split_length. simpl. reflexivity.
+Qed.
+ +
+Lemma nth_split_length_id : forall (l0 l1 : list MPropF) n, (length l0 = n) ->
+                                (fst (nth_split n (l0 ++ l1)) = l0 /\
+                                snd (nth_split n (l0 ++ l1)) = l1).
+Proof.
+induction l0.
+- intros. simpl. split. simpl in H. subst. simpl. reflexivity. simpl in H. subst. simpl. reflexivity.
+- intros. simpl in H. subst. split.
+  * assert (J1:length l0 = length l0). reflexivity. pose (@IHl0 l1 (length l0) J1).
+    destruct a0. simpl. destruct l0. simpl. reflexivity. simpl. rewrite <- H.
+    simpl. reflexivity.
+  * assert (J1:length l0 = length l0). reflexivity. pose (@IHl0 l1 (length l0) J1).
+    destruct a0. rewrite <- H0. simpl ((a :: l0) ++ snd (nth_split (length l0) (l0 ++ l1))).
+    assert ((nth_split (S (length l0)) (a :: l0 ++ snd (nth_split (length l0) (l0 ++ l1))) =
+    (a :: l0 ,snd (nth_split (length l0) (l0 ++ l1))))).
+    pose (nth_split_length (a :: l0) (snd (nth_split (length l0) (l0 ++ l1)))). apply e.
+    rewrite H1. simpl. reflexivity.
+Qed.
+ +
+Lemma effective_remove_nth : forall A l0 l1, ((remove_nth (S (length l0)) A (l0 ++ A :: l1)) = l0 ++ l1).
+Proof.
+induction l0.
+- intros. simpl. destruct (eq_dec_form A A). reflexivity. exfalso. auto.
+- intros. simpl (S (length (a :: l0))). repeat rewrite <- app_assoc. simpl ((a :: l0) ++ A :: l1).
+  pose (IHl0 l1). simpl ((a :: l0) ++ l1). rewrite <- e. simpl. reflexivity.
+Qed.
+ +
+
+
+ +
+ + + diff --git a/K.KS.KS_wkn.html b/K.KS.KS_wkn.html new file mode 100644 index 0000000..c1187b0 --- /dev/null +++ b/K.KS.KS_wkn.html @@ -0,0 +1,518 @@ + + + + + + + + + + + + + +
+
+

K.KS.KS_wkn

+ +
+Require Import List.
+Export ListNotations.
+Require Import Lia.
+Require Import PeanoNat.
+Require Import Arith.
+ +
+Require Import KS_calc.
+Require Import KS_dec.
+ +
+(* We define the relations which take care of the notion of weakening. *)
+ +
+Inductive wkn_L (fml : MPropF) : relationT Seq :=
+  | wkn_LI Γ0 Γ1 Δ : wkn_L fml
+        (Γ0 ++ Γ1, Δ) (Γ0 ++ fml :: Γ1, Δ).
+ +
+Inductive wkn_R (fml : MPropF) : relationT Seq :=
+  | wkn_RI Γ Δ0 Δ1 : wkn_R fml
+        (Γ, Δ0 ++ Δ1) (Γ, Δ0 ++ fml :: Δ1).
+ +
+(* The following lemmas make sure that if a rule is applied on a sequent s with
+premises ps, then the same rule is applicable on a sequent sw which is a weakened
+version of s, with some premises psw that are such that they are either the same premises
+(in case the weakened formula is weakened in the rule) or weakened versions of ps. *)

+ +
+Lemma ImpR_app_wkn_L : forall s sw A ps,
+  (@wkn_L A s sw) ->
+  (ImpRRule [ps] s) ->
+  (existsT2 psw, (ImpRRule [psw] sw) * (@wkn_L A ps psw)).
+Proof.
+intros s sw A ps wkn RA. inversion RA. inversion wkn. subst.
+inversion H. subst. apply app2_find_hole in H1. destruct H1.
+repeat destruct s ; destruct p ; subst.
+- exists (Γ2 ++ A0 :: A :: Γ3, Δ0 ++ B :: Δ1). repeat split ; try assumption.
+  rewrite cons_single. rewrite cons_single with (v:=A0). rewrite app_assoc. rewrite app_assoc with (l:=Γ2).
+  apply wkn_LI.
+- exists ((Γ2 ++ A :: x) ++ A0 :: Γ1, Δ0 ++ B :: Δ1). split.
+  * assert (Γ2 ++ A :: x ++ Γ1 = (Γ2 ++ A :: x) ++ Γ1). rewrite <- app_assoc. reflexivity.
+    rewrite H0. apply ImpRRule_I ; assumption.
+  * repeat rewrite <- app_assoc. apply wkn_LI.
+- exists (Γ0 ++ A0 :: x ++ A :: Γ3, Δ0 ++ B :: Δ1). split.
+  * repeat rewrite <- app_assoc. apply ImpRRule_I ; assumption.
+  * rewrite cons_single. rewrite cons_single with (v:=A0). rewrite app_assoc. rewrite app_assoc with (l:=Γ0).
+    rewrite app_assoc. rewrite app_assoc with (l:=(Γ0 ++ [A0])). apply wkn_LI.
+Qed.
+ +
+Lemma ImpL_app_wkn_L : forall s sw A ps1 ps2,
+  (@wkn_L A s sw) ->
+  (ImpLRule [ps1;ps2] s) ->
+  (existsT2 psw1 psw2, (ImpLRule [psw1;psw2] sw) *
+                                                  (@wkn_L A ps1 psw1) *
+                                                  (@wkn_L A ps2 psw2)).
+Proof.
+intros s sw A ps1 ps2 wkn RA. inversion RA. inversion wkn. subst.
+inversion H. subst. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
+  - exists (Γ2 ++ A :: Γ1, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ A :: B :: Γ1, Δ0 ++ Δ1).
+    split. split. assert (E1: Γ2 ++ A :: Γ1 = (Γ2 ++ [A]) ++ Γ1). rewrite <- app_assoc.
+    simpl. auto. rewrite E1. assert (E2 : Γ2 ++ A :: B :: Γ1 = (Γ2 ++ [A]) ++ B :: Γ1).
+    rewrite <- app_assoc. simpl. auto. rewrite E2. assert (E3 : Γ2 ++ A :: A0 --> B :: Γ1 = (Γ2 ++ [A]) ++ A0 --> B :: Γ1).
+    rewrite <- app_assoc. simpl. auto. rewrite E3. apply ImpLRule_I.
+    apply wkn_LI. apply wkn_LI.
+  - exists (Γ2 ++ A :: x ++ Γ1, Δ0 ++ A0 :: Δ1). exists (Γ2 ++ A :: x ++ B :: Γ1, Δ0 ++ Δ1).
+    split. split. assert (E1: Γ2 ++ A :: x ++ Γ1 = (Γ2 ++ [A] ++ x) ++ Γ1). rewrite <- app_assoc.
+    simpl. auto. rewrite E1. assert (E2 : Γ2 ++ A :: x ++ B :: Γ1 = (Γ2 ++ [A] ++ x) ++ B :: Γ1).
+    rewrite <- app_assoc. simpl. auto. rewrite E2.
+    assert (E3 : Γ2 ++ A :: x ++ A0 --> B :: Γ1 = (Γ2 ++ [A] ++ x) ++ A0 --> B :: Γ1).
+    rewrite <- app_assoc. simpl. auto. rewrite E3. apply ImpLRule_I.
+    repeat rewrite <- app_assoc. apply wkn_LI. repeat rewrite <- app_assoc. apply wkn_LI.
+  - destruct x ; subst ; repeat rewrite app_nil_r.
+    + simpl in e0. subst. exists (Γ0 ++ A :: Γ1, Δ0 ++ A0 :: Δ1). exists (Γ0 ++ A :: B :: Γ1, Δ0 ++ Δ1) .
+      split. split. assert (E1: Γ0 ++ A :: Γ1 = (Γ0 ++ [A]) ++ Γ1). rewrite <- app_assoc.
+      simpl. auto. rewrite E1. assert (E2 : Γ0 ++ A :: B :: Γ1 = (Γ0 ++ [A]) ++ B :: Γ1).
+      rewrite <- app_assoc. simpl. auto. rewrite E2.
+      assert (E3 : Γ0 ++ A :: A0 --> B :: Γ1 = (Γ0 ++ [A]) ++ A0 --> B :: Γ1).
+      rewrite <- app_assoc. simpl. auto. rewrite E3. apply ImpLRule_I.
+      repeat rewrite <- app_assoc. apply wkn_LI. repeat rewrite <- app_assoc. apply wkn_LI.
+    + inversion e0. subst. exists (Γ0 ++ x ++ A :: Γ3, Δ0 ++ A0 :: Δ1).
+      exists (Γ0 ++ B :: x ++ A :: Γ3, Δ0 ++ Δ1). split. split.
+      repeat rewrite <- app_assoc. apply ImpLRule_I.
+      assert (Γ0 ++ x ++ Γ3 = (Γ0 ++ x) ++ Γ3). rewrite <- app_assoc. reflexivity.
+      rewrite H0. assert (Γ0 ++ x ++ A :: Γ3 = (Γ0 ++ x) ++ A :: Γ3). rewrite <- app_assoc. reflexivity.
+      rewrite H1. apply wkn_LI.
+      assert (Γ0 ++ B :: x ++ Γ3 = (Γ0 ++ B :: x) ++ Γ3). rewrite <- app_assoc. reflexivity.
+      rewrite H0. assert (Γ0 ++ B :: x ++ A :: Γ3 = (Γ0 ++ B :: x) ++ A :: Γ3). rewrite <- app_assoc. reflexivity.
+      rewrite H1. apply wkn_LI.
+Qed.
+ +
+Lemma KR_app_wkn_L : forall s sw A ps,
+  (@wkn_L A s sw) ->
+  (KRRule [ps] s) ->
+  ((KRRule [ps] sw) +
+   (existsT2 psw, (KRRule [psw] sw) * (@wkn_L (unBox_formula A) ps psw))).
+Proof.
+intros s sw A ps wkn RA. inversion RA. inversion wkn. rewrite <- H1 in H2.
+inversion H2. subst. destruct (dec_is_boxedT A).
+  * right. apply univ_gen_ext_splitR in X. destruct X. destruct s. repeat destruct p.
+    subst. exists (unboxed_list (x ++ A :: x0), [A0]). split.
+    + apply KRRule_I. intro. intros. apply in_app_or in H. destruct H. apply H0. apply in_or_app. auto.
+      inversion H. subst. assumption. apply H0. apply in_or_app. auto. apply univ_gen_ext_combine.
+      assumption. apply univ_gen_ext_cons. assumption.
+    + repeat rewrite unbox_app_distrib. simpl. apply wkn_LI.
+  * left. apply KRRule_I.
+    + assumption.
+    + apply univ_gen_ext_splitR in X. destruct X. destruct s. repeat destruct p.
+      subst. apply univ_gen_ext_combine. assumption. apply univ_gen_ext_extra. assumption.
+      assumption.
+Qed.
+ +
+Lemma ImpR_app_wkn_R : forall s sw A ps,
+  (@wkn_R A s sw) ->
+  (ImpRRule [ps] s) ->
+  ((existsT2 psw, (ImpRRule [psw] sw) * (@wkn_R A ps psw))).
+Proof.
+intros s sw A ps wkn RA. inversion RA. inversion wkn. subst. inversion H.
+subst. apply app2_find_hole in H2. destruct H2. repeat destruct s ; destruct p ; subst.
+  - exists (Γ0 ++ A0 :: Γ1, Δ2 ++ A :: B :: Δ1). split.
+    assert (E1: Δ2 ++ A :: B :: Δ1 = (Δ2 ++ [A]) ++ B :: Δ1). rewrite <- app_assoc.
+    simpl. auto. rewrite E1. assert (E3 : Δ2 ++ A :: A0 --> B :: Δ1 = (Δ2 ++ [A]) ++ A0 --> B :: Δ1).
+    rewrite <- app_assoc. simpl. auto. rewrite E3. apply ImpRRule_I.
+    apply wkn_RI.
+  - exists (Γ0 ++ A0 :: Γ1, Δ2 ++ A :: x ++ B :: Δ1).
+    split. assert (E1: Δ2 ++ A :: x ++ B :: Δ1 = (Δ2 ++ [A] ++ x) ++ B :: Δ1). rewrite <- app_assoc.
+    simpl. auto. rewrite E1. assert (E2 : Δ2 ++ A :: x ++ A0 --> B :: Δ1 = (Δ2 ++ [A] ++ x) ++ A0 --> B :: Δ1).
+    rewrite <- app_assoc. simpl. auto. rewrite E2. apply ImpRRule_I.
+    repeat rewrite <- app_assoc. apply wkn_RI.
+  - destruct x ; subst ; repeat rewrite app_nil_r.
+    + simpl in e0. subst. exists (Γ0 ++ A0 :: Γ1, Δ0 ++ A :: B :: Δ1).
+      split. assert (E1: Δ0 ++ A :: B :: Δ1 = (Δ0 ++ [A]) ++ B :: Δ1). rewrite <- app_assoc.
+      simpl. auto. rewrite E1.
+      assert (E3 : Δ0 ++ A :: A0 --> B :: Δ1 = (Δ0 ++ [A]) ++ A0 --> B :: Δ1).
+      rewrite <- app_assoc. simpl. auto. rewrite E3. apply ImpRRule_I.
+      repeat rewrite <- app_assoc. apply wkn_RI.
+    + inversion e0. subst. exists (Γ0 ++ A0 :: Γ1, Δ0 ++ B :: x ++ A :: Δ3).
+      split. repeat rewrite <- app_assoc. apply ImpRRule_I.
+      assert (Δ0 ++ B :: x ++ Δ3 = (Δ0 ++ B :: x) ++ Δ3). rewrite <- app_assoc. reflexivity.
+      rewrite H0. assert (Δ0 ++ B :: x ++ A :: Δ3 = (Δ0 ++ B :: x) ++ A :: Δ3). rewrite <- app_assoc. reflexivity.
+      rewrite H1. apply wkn_RI.
+Qed.
+ +
+Lemma ImpL_app_wkn_R : forall s sw A ps1 ps2,
+  (@wkn_R A s sw) ->
+  (ImpLRule [ps1;ps2] s) ->
+  (existsT2 psw1 psw2, (ImpLRule [psw1;psw2] sw) * (@wkn_R A ps1 psw1) *
+                                                   (@wkn_R A ps2 psw2)).
+Proof.
+intros s sw A ps1 ps2 wkn RA. inversion RA. inversion wkn. subst.
+inversion H. subst. apply app2_find_hole in H2. destruct H2. repeat destruct s.
+- destruct p. subst. exists (Γ0 ++ Γ1, Δ2 ++ A0 :: A :: Δ3).
+  exists (Γ0 ++ B :: Γ1, Δ2 ++ A :: Δ3). repeat split.
+  assert (E1: Δ2 ++ A0 :: A :: Δ3 = (Δ2 ++ [A0]) ++ A :: Δ3).
+  repeat rewrite <- app_assoc. simpl. reflexivity. rewrite E1.
+  assert (E2: Δ2 ++ A0 :: Δ3 = (Δ2 ++ [A0]) ++ Δ3).
+  repeat rewrite <- app_assoc. simpl. reflexivity. rewrite E2. apply wkn_RI.
+- destruct p. subst. exists (Γ0 ++ Γ1, (Δ2 ++ A :: x) ++ A0 :: Δ1). exists (Γ0 ++ B :: Γ1, (Δ2 ++ A :: x) ++ Δ1).
+  split. split.
+  * assert (E: Δ2 ++ A :: x ++ Δ1 = (Δ2 ++ A :: x) ++ Δ1). rewrite <- app_assoc. simpl. reflexivity.
+    rewrite E. apply ImpLRule_I ; assumption.
+  * repeat rewrite <- app_assoc. simpl. apply wkn_RI.
+  * repeat rewrite <- app_assoc. simpl. apply wkn_RI.
+- destruct p. subst. exists (Γ0 ++ Γ1, Δ0 ++ A0 :: x ++ A :: Δ3).
+  exists (Γ0 ++ B :: Γ1, Δ0 ++ x ++ A :: Δ3). repeat split.
+  * rewrite <- app_assoc. apply ImpLRule_I ; assumption.
+  * assert (E1: Δ0 ++ A0 :: x ++ Δ3 = (Δ0 ++ A0 :: x) ++ Δ3). rewrite <- app_assoc. simpl. reflexivity.
+    rewrite E1.
+    assert (E2: Δ0 ++ A0 :: x ++ A :: Δ3 = (Δ0 ++ A0 :: x) ++ A :: Δ3). rewrite <- app_assoc. simpl. reflexivity.
+    rewrite E2. apply wkn_RI.
+  * rewrite app_assoc with (l:=Δ0). apply wkn_RI.
+Qed.
+ +
+Lemma KR_app_wkn_R : forall s sw A ps,
+  (@wkn_R A s sw) ->
+  (KRRule [ps] s) ->
+  (KRRule [ps] sw).
+Proof.
+intros s sw A ps wkn RA. inversion RA. inversion wkn. rewrite <- H1 in H2.
+inversion H2. apply app2_find_hole in H6. destruct H6. repeat destruct s0.
+- destruct p. subst. assert (Δ2 ++ A :: Box A0 :: Δ1 = (Δ2 ++ [A]) ++ Box A0 :: Δ1).
+  rewrite <- app_assoc. simpl. reflexivity. rewrite H. apply KRRule_I ; assumption.
+- destruct p. subst. assert (E: Δ2 ++ A :: x ++ Box A0 :: Δ1 = (Δ2 ++ A :: x) ++ Box A0 :: Δ1).
+  repeat rewrite <- app_assoc. simpl. reflexivity. rewrite E.
+  apply KRRule_I ; assumption.
+- destruct p. subst. destruct x.
+  + rewrite app_nil_r. rewrite app_nil_l in e0. subst. assert (Δ0 ++ A :: Box A0 :: Δ1 = (Δ0 ++ [A]) ++ Box A0 :: Δ1).
+    rewrite <- app_assoc. reflexivity. rewrite H. apply KRRule_I ; assumption.
+  + inversion e0. subst. rewrite <- app_assoc. simpl. apply KRRule_I ; assumption.
+Qed.
+ +
+(* Now we can prove that weakening is height-preserving admissible. *)
+ +
+Theorem KS_wkn_L : forall (k : nat) s
+        (D0 : KS_prv s),
+        k = (derrec_height D0) ->
+          (forall sw A, ((@wkn_L A s sw) ->
+          existsT2 (D1 : KS_prv sw),
+          derrec_height D1 <= k)).
+Proof.
+induction k as [n IH] using (well_founded_induction_type lt_wf).
+intros s0 D0. remember D0 as D0'. destruct D0.
+(* D0 is a leaf *)
+- intros hei sw A wkn. inversion f.
+(* D0 ends with an application of rule *)
+- intros hei sw A wkn. inversion wkn. inversion k.
+  (* IdP *)
+  * inversion H1. rewrite <- H in H5. inversion H5. apply app2_find_hole in H7.
+    destruct H7. assert (DersNil: dersrec KS_rules (fun _ : Seq => False) []).
+    apply dersrec_nil.
+    destruct s.
+    + destruct s.
+      { destruct p. inversion e0. subst. pose (IdPRule_I P (Γ2 ++ [A]) Γ3 Δ0 Δ1). apply IdP in i. rewrite <- app_assoc in i.
+        simpl in i. pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (Γ2 ++ A :: # P :: Γ3, Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl. repeat rewrite dersrec_height_nil.
+        left. reflexivity. reflexivity. }
+      { destruct p. destruct x.
+        - rewrite app_nil_l in e0. inversion e0. subst.
+          pose (IdPRule_I P ((Γ2 ++ []) ++ [A]) Γ3 Δ0 Δ1). apply IdP in i. rewrite <- app_assoc in i. simpl in i.
+          pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) ((Γ2 ++ []) ++ A :: # P :: Γ3, Δ0 ++ # P :: Δ1) i DersNil). exists d0. simpl. repeat rewrite dersrec_height_nil.
+          left. reflexivity. reflexivity.
+        - inversion e0. subst.
+          pose (IdPRule_I P Γ2 (x ++ A :: Γ1) Δ0 Δ1). apply IdP in i.
+          assert (E0 : Γ2 ++ # P :: x ++ A :: Γ1 = (Γ2 ++ # P :: x) ++ A :: Γ1). rewrite <- app_assoc. reflexivity.
+          rewrite E0 in i.
+          pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) ((Γ2 ++ # P :: x) ++ A :: Γ1, Δ0 ++ # P :: Δ1) i DersNil).
+          exists d0. simpl. repeat rewrite dersrec_height_nil.
+          left. reflexivity. reflexivity. }
+    + destruct p. subst. pose (IdPRule_I P (Γ0 ++ A :: x) Γ3 Δ0 Δ1). apply IdP in i. rewrite <- app_assoc in i. simpl in i.
+      pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[]) (Γ0 ++ A :: x ++ # P :: Γ3, Δ0 ++ # P :: Δ1) i DersNil).
+      exists d0. simpl. repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+  (* BotL *)
+  * inversion H1. rewrite <- H in H5. inversion H5.
+    assert (DersNil: dersrec KS_rules (fun _ : Seq => False) []).
+    apply dersrec_nil.
+    apply app2_find_hole in H7. destruct H7. destruct s.
+    + destruct s.
+      { destruct p. inversion e0. subst.
+        pose (BotLRule_I (Γ2 ++ [A]) Γ3 Δ). apply BotL in b. rewrite <- app_assoc in b. simpl in b.
+        pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (Γ2 ++ A :: Bot :: Γ3, Δ) b DersNil). exists d0. simpl. repeat rewrite dersrec_height_nil.
+        left. reflexivity. reflexivity. }
+      { destruct p. destruct x.
+        - rewrite app_nil_l in e0. inversion e0. subst.
+          pose (BotLRule_I ((Γ2 ++ []) ++ [A]) Γ3 Δ). apply BotL in b. rewrite <- app_assoc in b. simpl in b.
+          pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) ((Γ2 ++ []) ++ A :: Bot :: Γ3, Δ) b DersNil). exists d0. simpl. repeat rewrite dersrec_height_nil.
+          left. reflexivity. reflexivity.
+        - inversion e0. subst.
+          pose (BotLRule_I Γ2 (x ++ A :: Γ1) Δ). apply BotL in b.
+          assert (E0: Γ2 ++ Bot :: x ++ A :: Γ1 = (Γ2 ++ Bot :: x) ++ A :: Γ1). rewrite <- app_assoc. reflexivity.
+          rewrite E0 in b.
+          pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+          (ps:=[]) ((Γ2 ++ Bot :: x) ++ A :: Γ1, Δ) b DersNil).
+          exists d0. simpl. repeat rewrite dersrec_height_nil.
+          left. reflexivity. reflexivity. }
+    + destruct p. subst. pose (BotLRule_I (Γ0 ++ A :: x) Γ3 Δ). apply BotL in b.
+      assert (E0 : (Γ0 ++ A :: x) ++ Bot :: Γ3 = Γ0 ++ A :: x ++ Bot :: Γ3).
+      rewrite <- app_assoc. reflexivity. rewrite E0 in b.
+      pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[]) (Γ0 ++ A :: x ++ Bot :: Γ3, Δ) b DersNil). exists d0. simpl.
+      repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+  (* ImpR *)
+  * assert (DersNil: dersrec KS_rules (fun _ : Seq => False) []).
+    apply dersrec_nil.
+    inversion H1. subst. inversion H5. subst. pose (ImpR_app_wkn_L _ _ _ _ wkn H1). destruct s.
+    repeat destruct p. remember [(Γ2 ++ A0 :: Γ3, Δ0 ++ B :: Δ1)] as ps'. destruct d.
+    inversion Heqps'. inversion Heqps'. subst.
+    assert (E: derrec_height d < S (derrec_height d)). auto.
+    assert (E1: derrec_height d = derrec_height d). auto. simpl in IH.
+    rewrite dersrec_height_nil in IH. 2: reflexivity. rewrite Nat.max_0_r in IH.
+    pose (IH (derrec_height d) E (Γ2 ++ A0 :: Γ3, Δ0 ++ B :: Δ1) d
+    E1 x A w).
+    destruct s. pose (dlCons x0 d0). apply ImpR in i.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x]) (Γ0 ++ A :: Γ1, Δ0 ++ A0 --> B :: Δ1) i).
+    pose (d2 d1). exists d3.
+    simpl. repeat rewrite dersrec_height_nil. repeat rewrite Nat.max_0_r.
+    rewrite <- Nat.succ_le_mono. assumption. reflexivity.
+  (* ImpL *)
+  * inversion H1. subst. inversion H5. subst. pose (ImpL_app_wkn_L _ _ _ _ _ wkn H1). repeat destruct s.
+    repeat destruct p. apply ImpL in i.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x;x0]) (Γ0 ++ A :: Γ1, Δ0 ++ Δ1) i). subst. simpl.
+    remember [(Γ2 ++ Γ3, Δ0 ++ A0 :: Δ1); (Γ2 ++ B :: Γ3, Δ0 ++ Δ1)] as ps'. destruct d.
+    inversion Heqps'. inversion Heqps'. subst.
+    remember [(Γ2 ++ B :: Γ3, Δ0 ++ Δ1)] as ps''. destruct d1. inversion Heqps''.
+    inversion Heqps''. simpl. subst. rewrite dersrec_height_nil. simpl in IH.
+    rewrite dersrec_height_nil in IH. rewrite Nat.max_0_r. rewrite Nat.max_0_r in IH.
+    assert (E1: derrec_height d < S (Init.Nat.max (derrec_height d)(derrec_height d1))).
+    apply Nat.lt_succ_r. apply Nat.le_max_l.
+    assert (E2: derrec_height d = derrec_height d). auto.
+    pose (IH (derrec_height d) E1 (Γ2 ++ Γ3, Δ0 ++ A0 :: Δ1) d E2 x A w0).
+    destruct s.
+    assert (E3: derrec_height d1 < S (Init.Nat.max (derrec_height d)(derrec_height d1))).
+    apply Nat.lt_succ_r. apply Nat.le_max_r.
+    assert (E4: derrec_height d1 = derrec_height d1). auto.
+    pose (IH (derrec_height d1) E3 (Γ2 ++ B :: Γ3, Δ0 ++ Δ1) d1 E4 x0 A w).
+    destruct s.
+    pose (dlCons x1 (dlCons x2 d2)). subst. pose (d0 d3). exists d4. simpl. rewrite dersrec_height_nil.
+    rewrite Nat.max_0_r. rewrite <- Nat.succ_le_mono. apply Nat.max_le_compat.
+    assumption. assumption. reflexivity. reflexivity. reflexivity.
+  (* KR *)
+  * inversion X. rewrite <- H4 in X. subst. pose (KR_app_wkn_L _ _ _ _ wkn X). destruct s.
+    { apply KR in k0. subst. pose (derI (rules:=KS_rules)
+      (prems:=fun _ : Seq => False) (ps:=[(unboxed_list , [A0])])
+      (Γ0 ++ A :: Γ1, Δ) k0). subst. pose (d0 d). exists d1. simpl. reflexivity. }
+    { repeat destruct s. repeat destruct p. apply KR in k0.
+      remember [(unboxed_list , [A0])] as ps'. destruct d. inversion Heqps'. subst.
+      inversion Heqps'. subst. simpl. simpl in IH.
+      assert (E1: derrec_height d < S (Init.Nat.max (derrec_height d) (dersrec_height d0))).
+      rewrite dersrec_height_nil. rewrite Nat.max_0_r. apply Nat.lt_succ_r. left. reflexivity.
+      assert (E2: derrec_height d = derrec_height d). auto.
+      pose (IH (derrec_height d) E1 ((unboxed_list , [A0])) d E2 x (unBox_formula A) w).
+      destruct s. pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[x]) (Γ0 ++ A :: Γ1, Δ) k0). subst. simpl.
+      pose (dlCons x0 d0). pose (d1 d2). exists d3. simpl. rewrite dersrec_height_nil.
+      repeat rewrite Nat.max_0_r. rewrite <- Nat.succ_le_mono. lia. auto. }
+Qed.
+ +
+Theorem KS_hpadm_wkn_L : forall s (D0 : KS_prv s),
+          (forall sw A, ((@wkn_L A s sw) ->
+          existsT2 (D1 : KS_prv sw),
+          derrec_height D1 <= derrec_height D0)).
+Proof.
+intros.
+assert (J0 : derrec_height D0 = derrec_height D0). auto.
+pose (KS_wkn_L _ _ D0 J0 _ _ H). auto.
+Qed.
+ +
+Theorem KS_wkn_R : forall (k : nat) s
+        (D0 : KS_prv s),
+        k = (derrec_height D0) ->
+          (forall sw A, ((@wkn_R A s sw) ->
+          existsT2 (D1 : KS_prv sw),
+          derrec_height D1 <= k)).
+Proof.
+induction k as [n IH] using (well_founded_induction_type lt_wf).
+intros s0 D0. remember D0 as D0'. destruct D0.
+(* D0 is a leaf *)
+- intros hei sw A wkn. inversion f.
+(* D0 ends with an application of rule *)
+- intros hei sw A wkn. inversion wkn. inversion k.
+  (* IdP *)
+  * inversion H1. rewrite <- H in H5. inversion H5. apply app2_find_hole in H8.
+    destruct H8. assert (DersNil: dersrec KS_rules (fun _ : Seq => False) []).
+    apply dersrec_nil.
+    repeat destruct s.
+    + destruct p. inversion e0. subst. pose (IdPRule_I P Γ0 Γ1 (Δ2 ++ [A]) Δ3). apply IdP in i. rewrite <- app_assoc in i. simpl in i.
+      pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[]) (Γ0 ++ # P :: Γ1, Δ2 ++ A :: # P :: Δ3) i DersNil). exists d0. simpl. repeat rewrite dersrec_height_nil.
+      left. reflexivity. reflexivity.
+    + destruct p. destruct x.
+      { rewrite app_nil_l in e0. inversion e0. subst.
+        pose (IdPRule_I P Γ0 Γ1 ((Δ2 ++ []) ++ [A]) Δ3). apply IdP in i. rewrite <- app_assoc in i. simpl in i.
+        pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (Γ0 ++ # P :: Γ1, (Δ2 ++ []) ++ A :: # P :: Δ3) i DersNil). exists d0. simpl. repeat rewrite dersrec_height_nil.
+        left. reflexivity. reflexivity. }
+      { inversion e0. subst.
+        pose (IdPRule_I P Γ0 Γ1 Δ2 (x ++ A :: Δ1)). apply IdP in i.
+        assert (E0: Δ2 ++ # P :: x ++ A :: Δ1 = (Δ2 ++ # P :: x) ++ A :: Δ1). rewrite <- app_assoc. reflexivity.
+        rewrite E0 in i.
+        pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+        (ps:=[]) (Γ0 ++ # P :: Γ1, (Δ2 ++ # P :: x) ++ A :: Δ1) i DersNil).
+        exists d0. simpl. repeat rewrite dersrec_height_nil.
+        left. reflexivity. reflexivity. }
+    + destruct p. subst. pose (IdPRule_I P Γ0 Γ1 (Δ0 ++ A :: x) Δ3). apply IdP in i. rewrite <- app_assoc in i. simpl in i.
+      pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+      (ps:=[]) (Γ0 ++ # P :: Γ1, Δ0 ++ A :: x ++ # P :: Δ3) i DersNil).
+      exists d0. simpl. repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+  (* BotL *)
+  * inversion H1. rewrite <- H in H5. inversion H5.
+    assert (DersNil: dersrec KS_rules (fun _ : Seq => False) []).
+    apply dersrec_nil.
+    pose (BotLRule_I Γ0 Γ1 (Δ0 ++ A :: Δ1)). apply BotL in b.
+    pose (derI (rules:=KS_rules)
+    (prems:=fun _ : Seq => False)
+    (ps:=[]) (Γ0 ++ Bot :: Γ1, Δ0 ++ A :: Δ1) b DersNil). subst. exists d0. simpl.
+    repeat rewrite dersrec_height_nil. left. reflexivity. reflexivity.
+  (* ImpR *)
+  * inversion H1. subst. inversion H5. subst. pose (ImpR_app_wkn_R _ _ _ _ wkn H1). destruct s.
+    destruct p. apply ImpR in i.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x]) (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) i). subst. simpl.
+    remember [(Γ0 ++ A0 :: Γ1, Δ2 ++ B :: Δ3)] as ps'. destruct d. inversion Heqps'.
+    inversion Heqps'. subst. simpl. rewrite dersrec_height_nil. simpl in IH.
+    rewrite dersrec_height_nil in IH. rewrite Nat.max_0_r. rewrite Nat.max_0_r in IH.
+    assert (E: derrec_height d < S (derrec_height d)). auto.
+    assert (E1: derrec_height d = derrec_height d). auto.
+    pose (IH (derrec_height d) E (Γ0 ++ A0 :: Γ1, Δ2 ++ B :: Δ3) d E1 x A w).
+    destruct s.
+    pose (dlCons x0 d1). pose (d0 d2). exists d3. simpl. rewrite dersrec_height_nil.
+    rewrite Nat.max_0_r. rewrite <- Nat.succ_le_mono. assumption. reflexivity. reflexivity. reflexivity.
+  (* ImpL *)
+  * inversion H1. subst. inversion H5. subst. pose (ImpL_app_wkn_R _ _ _ _ _ wkn H1). repeat destruct s.
+    repeat destruct p. apply ImpL in i.
+    pose (derI (rules:=KS_rules) (prems:=fun _ : Seq => False)
+    (ps:=[x;x0]) (Γ0 ++ A0 --> B :: Γ1, Δ0 ++ A :: Δ1) i). subst. simpl.
+    remember [(Γ0 ++ Γ1, Δ2 ++ A0 :: Δ3); (Γ0 ++ B :: Γ1, Δ2 ++ Δ3)] as ps'. destruct d.
+    inversion Heqps'. inversion Heqps'. subst.
+    remember [(Γ0 ++ B :: Γ1, Δ2 ++ Δ3)] as ps''. destruct d1. inversion Heqps''.
+    inversion Heqps''. simpl. subst. rewrite dersrec_height_nil. simpl in IH.
+    rewrite dersrec_height_nil in IH. rewrite Nat.max_0_r. rewrite Nat.max_0_r in IH.
+    assert (E1: derrec_height d < S (Init.Nat.max (derrec_height d)(derrec_height d1))).
+    apply Nat.lt_succ_r. apply Nat.le_max_l.
+    assert (E2: derrec_height d = derrec_height d). auto.
+    pose (IH (derrec_height d) E1 (Γ0 ++ Γ1, Δ2 ++ A0 :: Δ3) d E2 x A w0).
+    destruct s.
+    assert (E3: derrec_height d1 < S (Init.Nat.max (derrec_height d)(derrec_height d1))).
+    apply Nat.lt_succ_r. apply Nat.le_max_r.
+    assert (E4: derrec_height d1 = derrec_height d1). auto.
+    pose (IH (derrec_height d1) E3 (Γ0 ++ B :: Γ1, Δ2 ++ Δ3) d1 E4 x0 A w).
+    destruct s.
+    pose (dlCons x1 (dlCons x2 d2)). subst. pose (d0 d3). exists d4. simpl. rewrite dersrec_height_nil.
+    rewrite Nat.max_0_r. rewrite <- Nat.succ_le_mono. apply Nat.max_le_compat.
+    assumption. assumption. reflexivity. reflexivity. reflexivity.
+  (* KR *)
+  * inversion X. rewrite <- H4 in X. pose (KR_app_wkn_R _ _ _ _ wkn X).
+    apply KR in k0. pose (derI (rules:=KS_rules)
+    (prems:=fun _ : Seq => False) (ps:=[(unboxed_list , [A0])])
+    sw k0). subst. pose (d0 d). exists d1. simpl. reflexivity.
+Qed.
+ +
+Theorem KS_hpadm_wkn_R : forall s (D0 : KS_prv s),
+          (forall sw A, ((@wkn_R A s sw) ->
+          existsT2 (D1 : KS_prv sw),
+          derrec_height D1 <= derrec_height D0)).
+Proof.
+intros.
+assert (J0 : derrec_height D0 = derrec_height D0). auto.
+pose (KS_wkn_R _ _ D0 J0 _ _ H). auto.
+Qed.
+ +
+Theorem KS_list_wkn_R : forall (k : nat) Γ Δ0 Δ1
+        (D0 : KS_prv (Γ,Δ0 ++ Δ1)),
+        k = (derrec_height D0) ->
+          (forall l, existsT2 (D1 : KS_prv (Γ,Δ0 ++ l ++ Δ1)),
+           derrec_height D1 <= k).
+Proof.
+intros. induction l.
+- simpl. exists D0. lia.
+- simpl. destruct IHl.
+  assert (E: derrec_height x = derrec_height x). reflexivity.
+  assert (H0: wkn_R a (Γ, Δ0 ++ l ++ Δ1) (Γ, Δ0 ++ a :: l ++ Δ1)). apply wkn_RI.
+  pose (@KS_wkn_R (derrec_height x) (Γ, Δ0 ++ l ++ Δ1) x E (Γ, Δ0 ++ a :: l ++ Δ1) a H0).
+  destruct s. exists x0. lia.
+Qed.
+ +
+Theorem KS_list_wkn_L : forall (k : nat) Γ0 Γ1 Δ
+        (D0 : KS_prv (Γ0 ++ Γ1,Δ)),
+        k = (derrec_height D0) ->
+          (forall l, existsT2 (D1 : KS_prv (Γ0 ++ l ++ Γ1,Δ)),
+          derrec_height D1 <= k).
+Proof.
+intros. induction l.
+- simpl. exists D0. lia.
+- simpl. destruct IHl.
+  assert (E: derrec_height x = derrec_height x). reflexivity.
+  assert (H0: wkn_L a (Γ0 ++ l ++ Γ1, Δ) (Γ0 ++ a :: l ++ Γ1, Δ)). apply wkn_LI.
+  pose (@KS_wkn_L (derrec_height x) (Γ0 ++ l ++ Γ1, Δ) x E (Γ0 ++ a :: l ++ Γ1, Δ) a H0).
+  destruct s. exists x0. lia.
+Qed.
+
+
+ +
+ + + diff --git a/Syntax.CML_Syntax.html b/Syntax.CML_Syntax.html new file mode 100644 index 0000000..1beb6d2 --- /dev/null +++ b/Syntax.CML_Syntax.html @@ -0,0 +1,277 @@ + + + + + + + + + + + + + +
+
+

Syntax.CML_Syntax

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat String.
+ +
+Require Import general_export.
+ +
+Set Implicit Arguments.
+ +
+(* Definitions Language *)
+ +
+(* First, let us define the propositional formulas we use here. *)
+ +
+Inductive MPropF : Type :=
+ | Var : string -> MPropF
+ | Bot : MPropF
+ | Imp : MPropF -> MPropF -> MPropF
+ | Box : MPropF -> MPropF
+.
+ +
+Notation "# p" := (Var p) (at level 1).
+Notation "A --> B" := (Imp A B) (at level 16, right associativity).
+Notation "⊥" := Bot (at level 0).
+Notation "¬ A" := (A --> ) (at level 42).
+ +
+  Definition Top := (Bot --> Bot).
+  Definition Neg (A : MPropF) := A --> Bot.
+  Definition And (A B : MPropF) := Neg (A --> Neg B).
+  Definition Or (A B : MPropF) := (Neg A) --> B.
+  Definition Diam (A : MPropF) := Neg (Box (Neg A)).
+ +
+Fixpoint subformlist (φ : MPropF) : list MPropF :=match φ with
+| Var p => (Var p) :: nil | Bot => Bot :: nil
+| Imp ψ χ => (Imp ψ χ) ::
+(subformlist ψ) ++ (subformlist χ) | Box ψ => (Box ψ) :: (subformlist ψ)end.
+ +
+Lemma eq_dec_form : forall x y : MPropF, {x = y} + {x <> y}.
+Proof.
+repeat decide equality.
+Defined.
+ +
+Global Opaque eq_dec_form.
+ +
+Fixpoint size (φ : MPropF) : nat :=
+match φ with
+| Var p => 1| Bot => 1
+| Imp ψ χ => 1 + (size ψ) + (size χ) | Box ψ => 1 + (size ψ)
+end.
+ +
+Fixpoint size_LF (l : list MPropF) : nat :=
+match l with
+  | [] => 0
+  | h :: t => (size h) + (size_LF t)
+end.
+ +
+Fixpoint subst (σ : string -> MPropF) (φ : MPropF) : MPropF :=
+match φ with
+| Var p => (σ p)
+| Bot => Bot
+| Imp ψ χ => Imp (subst σ ψ) (subst σ χ)| Box ψ => Box (subst σ ψ)
+end.
+ +
+Definition is_atomicT A : Type :=
+                  (exists p, A = # p) + (A = Bot).
+ +
+(* Order all this *)
+ +
+Definition is_boxedT (A : MPropF) : Type :=
+                  exists (B : MPropF), A = Box B.
+ +
+Definition is_Boxed_list (Γ : list (MPropF)) : Prop :=
+    forall (A : MPropF), (In A Γ) -> (exists (B : MPropF), A = Box B).
+ +
+Definition is_Prime (Γ : list MPropF) : Prop :=
+    forall (A : MPropF), (In A Γ) ->
+    (exists (B : MPropF), A = Box B) \/ (exists P, A = # P) \/ (A = Bot).
+ +
+(* With these properties we can define restrictions of univ_gen_ext on
+   formulae. *)

+ +
+Definition nobox_gen_ext := univ_gen_ext (fun x => (is_boxedT x) -> False).
+ +
+(* A lemmas about nobox_gen_ext. *)
+ +
+Lemma nobox_gen_ext_injective : forall (l0 l1 l : list (MPropF)), (is_Boxed_list l0) -> (is_Boxed_list l1) ->
+                                (nobox_gen_ext l0 l) -> (nobox_gen_ext l1 l) -> l1 = l0.
+Proof.
+intros l0 l1 l Hl0 Hl1 gen. generalize dependent l1.
+induction gen.
+- intros. inversion X. reflexivity.
+- intros. inversion X.
+  * subst. assert (l0 = l). apply IHgen. intro. intros. apply Hl0. apply in_cons. assumption.
+    intro. intros. apply Hl1. apply in_cons. assumption. assumption. rewrite H. reflexivity.
+  * subst. exfalso. apply H1. apply Hl0. apply in_eq.
+- intros. apply IHgen. intro. intros. apply Hl0. assumption.
+  intro. intros. apply Hl1. assumption. inversion X.
+  subst. exfalso. apply p. apply Hl1. apply in_eq. subst. assumption.
+Qed.
+ +
+(* The next definitions help to define the combination of a list of boxed
+   formulae and the unboxing of all the formulae in that list. *)

+ +
+Definition unBox_formula (A : MPropF) : MPropF :=
+  match A with
+              | # P => # P
+              | Bot => Bot
+              | A --> B => A --> B
+              | Box A => A
+              end
+.
+ +
+Fixpoint unboxed_list (Γ : list (MPropF)) : list (MPropF):=
+  match Γ with
+  | [ ] => [ ]
+  | h :: t => (unBox_formula h :: unboxed_list t)
+  end
+.
+ +
+Fixpoint top_boxes (l : list (MPropF)) : list (MPropF) :=
+match l with
+  | nil => nil
+  | h :: t => match h with
+                | Box A => (Box A) :: top_boxes t
+                | _ => top_boxes t
+              end
+end.
+ +
+(* Now that we have defined these, we can prove some properties about them. *)
+ +
+Lemma unbox_app_distrib :
+  forall (l1 l2: list (MPropF)), unboxed_list (l1 ++ l2) = (unboxed_list l1) ++ (unboxed_list l2).
+Proof.
+induction l1.
+- intro l2. rewrite app_nil_l with (l:=l2). simpl. reflexivity.
+- intro l2. simpl. rewrite IHl1. reflexivity.
+Qed.
+ +
+Lemma subl_of_boxl_is_boxl {V : Set}:
+  forall (l1 l2: list (MPropF)), (incl l1 l2) -> (is_Boxed_list l2) -> (is_Boxed_list l1).
+Proof.
+intros. unfold is_Boxed_list. intros. apply H in H1. apply H0 in H1.
+destruct H1. exists x. assumption.
+Qed.
+ +
+Lemma tl_of_boxl_is_boxl {V : Set}:
+  forall (h : MPropF) (t l : list (MPropF)) (H: l = h :: t),
+         (is_Boxed_list l) -> (is_Boxed_list t).
+Proof.
+intros. unfold is_Boxed_list. intros. assert (Hyp: In A l).
+rewrite H. simpl. right. apply H1. apply H0 in Hyp. destruct Hyp.
+exists x. assumption.
+Qed.
+ +
+Lemma is_box_is_in_boxed_list : forall l (A : MPropF), In A l -> is_Boxed_list l -> (exists B, Box B = A).
+Proof.
+induction l.
+- intros. inversion H.
+- intros. inversion H.
+  + subst. unfold is_Boxed_list in H0. pose (H0 A).
+    apply e in H. destruct H. exists x. symmetry. assumption.
+  + apply IHl. assumption. unfold is_Boxed_list. intros. unfold is_Boxed_list in H0.
+    pose (H0 A0). apply e. apply in_cons. assumption.
+Qed.
+ +
+Lemma top_boxes_distr_app : forall (l1 l2 : list (MPropF)),
+      top_boxes (l1 ++ l2) = (top_boxes l1) ++ (top_boxes l2).
+Proof.
+induction l1.
+- intro l2. rewrite app_nil_l. simpl. reflexivity.
+- intro l2. simpl. destruct a ; try apply IHl1.
+  simpl. rewrite IHl1. reflexivity.
+Qed.
+ +
+Lemma box_in_top_boxes : forall l1 l2 A, existsT2 l3 l4, top_boxes (l1 ++ Box A :: l2) = l3 ++ Box A :: l4.
+Proof.
+intros. exists (top_boxes l1). exists (top_boxes l2). rewrite top_boxes_distr_app. auto.
+Qed.
+ +
+Lemma is_Boxed_list_top_boxes : forall l, is_Boxed_list (top_boxes l).
+Proof.
+intros. induction l.
+- simpl. intro. intros. inversion H.
+- intro. destruct a.
+  + simpl. intros. apply IHl in H. assumption.
+  + simpl. intros. apply IHl in H. assumption.
+  + simpl. intros. apply IHl in H. assumption.
+  + simpl. intros. destruct H.
+    * exists a. auto.
+    * apply IHl. assumption.
+Qed.
+ +
+Lemma nobox_gen_ext_top_boxes : forall l, nobox_gen_ext (top_boxes l) l.
+Proof.
+induction l.
+- simpl. apply univ_gen_ext_refl.
+- destruct a.
+  * simpl. apply univ_gen_ext_extra. intros. inversion X. inversion H. assumption.
+  * simpl. apply univ_gen_ext_extra. intros. inversion X. inversion H. assumption.
+  * simpl. apply univ_gen_ext_extra. intros. inversion X. inversion H. assumption.
+  * simpl. apply univ_gen_ext_cons. assumption.
+Qed.
+ +
+
+
+ +
+ + + diff --git a/Syntax.Syntax_export.html b/Syntax.Syntax_export.html new file mode 100644 index 0000000..5908bd1 --- /dev/null +++ b/Syntax.Syntax_export.html @@ -0,0 +1,43 @@ + + + + + + + + + + + + + +
+
+

Syntax.Syntax_export

+ +
+Require Export CML_Syntax.
+Require Export list_lems.
+Require Export remove_list_lems.
+
+
+ +
+ + + diff --git a/Syntax.list_lems.html b/Syntax.list_lems.html new file mode 100644 index 0000000..75e8d20 --- /dev/null +++ b/Syntax.list_lems.html @@ -0,0 +1,340 @@ + + + + + + + + + + + + + +
+
+

Syntax.list_lems

+ +
+Require Import List.
+Export ListNotations.
+ +
+Require Import genT.
+Require Import gen_tacs.
+Require Import List_lemmasT.
+Require Import existsT.
+ +
+Require Import CML_Syntax.
+ +
+(* Some useful lemmas about lists. *)
+ +
+Lemma in_exch_list : forall {A : Type} (l0 l1 l2 l3 l4 : list A) (a : A),
+  In a (l0 ++ l1 ++ l2 ++ l3 ++ l4) -> In a (l0 ++ l3 ++ l2 ++ l1 ++ l4).
+Proof.
+intros A l0 l1 l2 l3 l4 a H.
+apply in_app_or in H. destruct H. apply in_or_app. left. assumption.
+apply in_app_or in H. destruct H. apply in_or_app. right. apply in_or_app. right.
+apply in_or_app. right. apply in_or_app. left. assumption.
+apply in_app_or in H. destruct H. apply in_or_app. right. apply in_or_app. right.
+apply in_or_app. left. assumption.
+apply in_app_or in H. destruct H. apply in_or_app. right. apply in_or_app. left.
+assumption.
+apply in_or_app. right. apply in_or_app. right. apply in_or_app. right.
+apply in_or_app. right. assumption.
+Qed.
+ +
+Lemma InT_exch_list : forall {A : Type} (l0 l1 l2 l3 l4 : list A) (a : A),
+  InT a (l0 ++ l1 ++ l2 ++ l3 ++ l4) -> InT a (l0 ++ l3 ++ l2 ++ l1 ++ l4).
+Proof.
+intros A l0 l1 l2 l3 l4 a H.
+apply InT_app_or in H. destruct H. apply InT_or_app. left. assumption.
+apply InT_app_or in i. destruct i. apply InT_or_app. right. apply InT_or_app. right.
+apply InT_or_app. right. apply InT_or_app. left. assumption.
+apply InT_app_or in i. destruct i. apply InT_or_app. right. apply InT_or_app. right.
+apply InT_or_app. left. assumption.
+apply InT_app_or in i. destruct i. apply InT_or_app. right. apply InT_or_app. left.
+assumption.
+apply InT_or_app. right. apply InT_or_app. right. apply InT_or_app. right.
+apply InT_or_app. right. assumption.
+Qed.
+ +
+Lemma partition_1_element : forall {A : Type} (l1 l2 l3 l4 l5 l6 l7 : list A) a,
+l1 ++ l2 ++ l3 ++ l4 ++ l5 = l6 ++ a :: l7 ->
+  (existsT2 l8 l9, l1 = l8 ++ a :: l9) +
+  ((existsT2 l8 l9, l2 = l8 ++ a :: l9) +
+  ((existsT2 l8 l9, l3 = l8 ++ a :: l9) +
+  ((existsT2 l8 l9, l4 = l8 ++ a :: l9) +
+  ((existsT2 l8 l9, l5 = l8 ++ a :: l9))))).
+Proof.
+intros A l1. induction l1.
+- simpl. induction l2.
+  * simpl. induction l3.
+    + simpl. induction l4.
+      { simpl. intros. right. right. right. right. exists l6. exists l7.
+        assumption. }
+      { intros. destruct l6. simpl in H. right. right. right. left. exists []. simpl.
+        inversion H. exists l4. reflexivity.
+        inversion H. apply IHl4 in H2. destruct H2. destruct s. destruct s. exfalso.
+        apply app_cons_not_nil in e. assumption.
+        destruct s. destruct s. destruct s. exfalso.
+        apply app_cons_not_nil in e. assumption.
+        destruct s. destruct s. destruct s. exfalso.
+        apply app_cons_not_nil in e. assumption.
+        destruct s. destruct s. destruct s. right. right. right.
+        left. exists (a1 :: x). exists x0. simpl. rewrite e. reflexivity.
+        destruct s. destruct s. right. right. right. right. exists x. exists x0.
+        assumption. }
+    + intros l4 l5 l6 l7 a0 E. destruct l6.
+      { inversion E. right. right. left. exists []. exists l3. simpl. reflexivity. }
+      { inversion E. apply IHl3 in H1. destruct H1.
+        destruct s. destruct s. exfalso.
+        apply app_cons_not_nil in e. assumption.
+        destruct s. destruct s. destruct s. exfalso.
+        apply app_cons_not_nil in e. assumption.
+        destruct s. destruct s. destruct s. right. right. left. exists (a1 :: x).
+        exists x0. rewrite e. simpl. reflexivity.
+        right. right. right. assumption. }
+  * intros l3 l4 l5 l6 l7 a0 E. destruct l6. inversion E.
+    { inversion E. right. left. exists []. exists l2. simpl. reflexivity. }
+    { inversion E. apply IHl2 in H1. destruct H1.
+      destruct s. destruct s. exfalso.
+      apply app_cons_not_nil in e. assumption.
+      destruct s. destruct s. destruct s. right. left. exists (a1 :: x). exists x0.
+      rewrite e. simpl. reflexivity.
+      right. right. assumption. }
+- intros l2 l3 l4 l5 l6 l7 a0 E. destruct l6.
+  { inversion E. left. exists []. exists l1. auto. }
+  { inversion E. apply IHl1 in H1. destruct H1.
+    destruct s. destruct s. left. exists (a1 :: x). exists x0. rewrite e. auto.
+    right. assumption. }
+Qed.
+ +
+Lemma partition_1_element2 : forall {A : Type} (l1 l2 l3 l4 l5 l6 l7 : list A) a,
+l1 ++ l2 ++ l3 ++ l4 ++ l5 = l6 ++ a :: l7 ->
+  ((existsT2 l8 l9, (l1 = l8 ++ a :: l9) * (l9 ++ l2 ++ l3 ++ l4 ++ l5 = l7) * (l8 = l6)) +
+  ((existsT2 l8 l9, (l2 = l8 ++ a :: l9) * (l9 ++ l3 ++ l4 ++ l5 = l7) * (l1 ++ l8 = l6)) +
+  ((existsT2 l8 l9, (l3 = l8 ++ a :: l9) * (l9 ++ l4 ++ l5 = l7) * (l1 ++ l2 ++ l8 = l6)) +
+  ((existsT2 l8 l9, (l4 = l8 ++ a :: l9) * (l9 ++ l5 = l7) * (l1 ++ l2 ++ l3 ++ l8 = l6)) +
+  ((existsT2 l8 l9, (l5 = l8 ++ a :: l9) * (l9 = l7) * (l1 ++ l2 ++ l3 ++ l4 ++ l8 = l6))))))).
+Proof.
+intros A l1. induction l1.
+- simpl. induction l2.
+  * simpl. induction l3.
+    + simpl. induction l4.
+      { simpl. intros. right. right. right. right. exists l6. exists l7.
+        split. split. assumption. reflexivity. reflexivity. }
+      { intros. destruct l6. simpl in H. right. right. right. left. exists []. simpl.
+        inversion H. exists l4. split. split. reflexivity. reflexivity. reflexivity.
+        inversion H. apply IHl4 in H2. destruct H2. destruct s. destruct s. exfalso.
+        repeat destruct p. apply app_cons_not_nil in e0. assumption.
+        destruct s. destruct s. destruct s. exfalso.
+        repeat destruct p. apply app_cons_not_nil in e0. assumption.
+        destruct s. destruct s. destruct s. exfalso.
+        repeat destruct p. apply app_cons_not_nil in e0. assumption.
+        destruct s. destruct s. destruct s. right. right. right.
+        left. exists (a1 :: x). exists x0. simpl. repeat destruct p. rewrite e0.
+        split. split. reflexivity. assumption. subst. reflexivity.
+        destruct s. destruct s. right. right. right. right. exists x. exists x0.
+        split. split. repeat destruct p. assumption. repeat destruct p. subst. reflexivity.
+        repeat destruct p. subst. reflexivity. }
+    + intros l4 l5 l6 l7 a0 E. destruct l6.
+      { inversion E. right. right. left. exists []. exists l3. simpl. split. split. reflexivity. reflexivity. reflexivity. }
+      { inversion E. apply IHl3 in H1. destruct H1.
+        destruct s. destruct s. exfalso.
+        repeat destruct p. apply app_cons_not_nil in e0. assumption.
+        destruct s. destruct s. destruct s. exfalso.
+        repeat destruct p. apply app_cons_not_nil in e0. assumption.
+        destruct s. destruct s. destruct s. right. right. left. exists (a1 :: x).
+        exists x0. repeat destruct p. rewrite e0. simpl. split. split. reflexivity. assumption. subst. reflexivity.
+        right. right. right. destruct s. left. repeat destruct s. exists x. exists x0. repeat destruct p.
+        split. split. assumption. assumption. simpl. subst. reflexivity.
+        repeat destruct s. right. exists x. exists x0. repeat destruct p. split. split. assumption. assumption. subst. reflexivity. }
+  * intros l3 l4 l5 l6 l7 a0 E. destruct l6. inversion E.
+    { inversion E. right. left. exists []. exists l2. simpl. split. split. reflexivity. reflexivity. reflexivity. }
+    { inversion E. apply IHl2 in H1. destruct H1.
+      destruct s. destruct s. exfalso.
+      repeat destruct p. apply app_cons_not_nil in e0. assumption.
+      destruct s. destruct s. destruct s. right. left. exists (a1 :: x). exists x0.
+      repeat destruct p. rewrite e. simpl. subst. split. split. reflexivity. reflexivity. reflexivity.
+      right. right. destruct s. repeat destruct s. repeat destruct p. left. exists x. exists x0. subst. split. split. reflexivity.
+      reflexivity. reflexivity.
+      destruct s. repeat destruct s. repeat destruct p. subst. right. left. exists x. exists x0. subst. split. split. reflexivity.
+      reflexivity. reflexivity.
+      repeat destruct s. repeat destruct p. right. right. exists x. exists x0. subst. split. split. reflexivity.
+      reflexivity. reflexivity. }
+- intros l2 l3 l4 l5 l6 l7 a0 E. destruct l6.
+  { inversion E. left. exists []. exists l1. auto. }
+  { inversion E. apply IHl1 in H1. destruct H1.
+    destruct s. destruct s. left. exists (a1 :: x). exists x0. repeat destruct p. rewrite e0. split.
+    split. subst. reflexivity. subst. reflexivity. subst. reflexivity.
+    destruct s.
+    repeat destruct s. right. left. exists x. exists x0. repeat destruct p. subst. split. split. subst. reflexivity.
+    reflexivity. reflexivity.
+    destruct s.
+    repeat destruct s. right. right. left. exists x. exists x0. repeat destruct p. subst. split. split. subst. reflexivity.
+    reflexivity. reflexivity.
+    destruct s.
+    repeat destruct s. right. right. right. left. exists x. exists x0. repeat destruct p. subst. split. split. subst. reflexivity.
+    reflexivity. reflexivity.
+    destruct s.
+    repeat destruct s. right. right. right. right. exists x. exists x0. repeat destruct p. subst. split. split. subst. reflexivity.
+    reflexivity. reflexivity. }
+Qed.
+ +
+Lemma add_1_element_split_lists : forall {A : Type} (l1 l2 l3 l4 : list A) a,
+    l1 ++ l2 = l3 ++ l4 -> ((l1 = l3) * (l2 = l4)) +
+    (existsT2 l5 l6, ((l5 ++ a :: l6 ++ l2 = l3 ++ a :: l4) * (l5 ++ l6 = l1) * (l6 ++ l2 = l4) * (l5 = l3)) +
+                     ((l1 ++ l5 ++ a :: l6 = l3 ++ a :: l4) * (l5 ++ l6 = l2) * (l1 ++ l5 = l3) * (l6 = l4))).
+Proof.
+intros A l1. induction l1.
+- intros. rewrite app_nil_l in H. destruct l3.
+  + left. rewrite app_nil_l in H. split. reflexivity. assumption.
+  + right. exists (a0 :: l3). exists l4. right. split. split. split.
+    rewrite app_nil_l. reflexivity. symmetry. assumption. rewrite app_nil_l.
+    reflexivity. reflexivity.
+- destruct l3.
+  + intros. right. exists []. exists (a :: l1). left. split. split. split.
+    repeat rewrite app_nil_l. rewrite H. reflexivity. rewrite app_nil_l. reflexivity.
+    rewrite app_nil_l in H. assumption. reflexivity.
+  + intros. inversion H. apply IHl1 with (a:=a1) in H2. destruct H2.
+    * destruct p. subst. left. split. reflexivity. reflexivity.
+    * destruct s. destruct s. destruct s.
+      { repeat destruct p. subst. right. exists (a0 :: l3). exists x0.
+        left. split. split. split. reflexivity. reflexivity. reflexivity.
+        reflexivity. }
+      { repeat destruct p. subst. right. exists x. exists l4. right. split. split. split.
+        repeat rewrite app_assoc. reflexivity. reflexivity. reflexivity. reflexivity. }
+Qed.
+ +
+Lemma app2_find_hole {A : Type} : forall (l1 l2 l3 l4 : list A),
+              l1 ++ l2 = l3 ++ l4 ->
+              (existsT2 l5,
+                ((l3 = l1) * (l4 = l2)) +
+                ((l3 = l1 ++ l5) * (l2 = l5 ++ l4)) +
+                ((l1 = l3 ++ l5) * (l4 = l5 ++ l2))).
+Proof.
+induction l1.
+- intros. exists l3. left. right. split. reflexivity. assumption.
+- intros l2 l3 l4 E. destruct l3.
+  * rewrite app_nil_l in E. exists (a :: l1). right. split. reflexivity.
+    symmetry. assumption.
+  * inversion E. apply IHl1 in H1. destruct H1. destruct s.
+    + destruct s.
+      { destruct p. subst. exists []. left. left. auto. }
+      { destruct p. subst. exists x. left. right. auto. }
+    + destruct p. subst. exists x. right. auto.
+Qed.
+ +
+Theorem in_splitT : forall x (l:list MPropF), In x l -> existsT2 l1 l2, l = l1++x::l2.
+Proof.
+intros x l. induction l.
+- intro. inversion H.
+- intro. destruct (eq_dec_form x a).
+  * subst. exists nil. exists l. auto.
+  * assert (In x l). inversion H. subst. exfalso. apply n. reflexivity. assumption.
+    apply IHl in H0. destruct H0. destruct s. subst. exists ([a] ++ x0). exists x1.
+    auto.
+Defined.
+ +
+Lemma InT_dec : forall l (a : MPropF) , (InT a l) + ((InT a l) -> False).
+Proof.
+induction l.
+- intro. right. intro. inversion H.
+- intro a0. pose (IHl a0). destruct s.
+  * left. apply InT_cons. assumption.
+  * destruct (eq_dec_form a a0).
+    + subst. left. apply InT_eq.
+    + right. intro. inversion H.
+      { apply n. assumption. }
+      { apply f. assumption. }
+Qed.
+ +
+Definition eq_dec_listsF : forall (l0 l1 : list MPropF), {l0 = l1} + {l0 <> l1}.
+Proof.
+apply list_eq_dec. apply eq_dec_form.
+Defined.
+ +
+Definition eq_dec_seqs : forall (s0 s1 : rel (list MPropF)), {s0 = s1} + {s0 <> s1}.
+Proof.
+intros. destruct s0. destruct s1. destruct (eq_dec_listsF l l1) ; destruct (eq_dec_listsF l0 l2).
+- subst. left. reflexivity.
+- subst. right. intro. inversion H. auto.
+- subst. right. intro. inversion H. auto.
+- subst. right. intro. inversion H. auto.
+Defined.
+ +
+Definition seqs_in_splitT : forall (x : rel (list MPropF)) l,
+       In x l -> existsT2 l1 l2, l = l1 ++ x :: l2.
+Proof.
+intros x l. induction l.
+- intro. inversion H.
+- intro. destruct (eq_dec_seqs x a).
+  * subst. exists nil. exists l. auto.
+  * assert (In x l). inversion H. subst. exfalso. apply n. reflexivity. assumption.
+    apply IHl in H0. destruct H0. destruct s. subst. exists ([a] ++ x0). exists x1.
+    auto.
+Defined.
+ +
+Definition In_InT_seqs : forall (seq : rel (list MPropF)) seqs, In seq seqs -> InT seq seqs.
+Proof.
+intros seq seqs. induction seqs.
+- intro. inversion H.
+- intro. apply seqs_in_splitT in H. destruct H. destruct s. rewrite e. apply InT_or_app.
+  right. apply InT_eq.
+Defined.
+ +
+Lemma list_split_form : forall (A B : MPropF) l0 l1 l2 l3, (l0 ++ A :: l1 = l2 ++ B :: l3) ->
+                          ((A = B) * (l0 = l2) * (l1 = l3)) +
+                          (existsT2 l4 l5, (l0 = l4 ++ l5) * (l5 ++ A :: l1 = l3) * (l2 ++ [B] = l4)) +
+                          (existsT2 l4 l5, (l1 = l4 ++ l5) * (l0 ++ A :: l4 = l2) * (B :: l3 = l5)).
+Proof.
+intros A B l0. generalize dependent A. generalize dependent B. induction l0.
+- intros. simpl in H. destruct l2.
+  * simpl in H. left. left. inversion H. auto.
+  * simpl. inversion H. subst. right. exists l2. exists (B :: l3). auto.
+- simpl. simpl in IHl0. intros. destruct l2.
+  * left. right. simpl. exists [B]. exists l0. simpl. inversion H. subst. auto.
+  * inversion H. subst. pose (@IHl0 B A l1 l2 l3 H2). repeat destruct s.
+    + repeat destruct p. subst. left. left. auto.
+    + repeat destruct p. subst. left. right. exists ((m :: l2) ++ [B]). exists x0.
+      auto.
+    + repeat destruct p. subst. right. exists x. exists (B :: l3). auto.
+Qed.
+
+
+ +
+ + + diff --git a/Syntax.remove_list_lems.html b/Syntax.remove_list_lems.html new file mode 100644 index 0000000..eed635b --- /dev/null +++ b/Syntax.remove_list_lems.html @@ -0,0 +1,688 @@ + + + + + + + + + + + + + +
+
+

Syntax.remove_list_lems

+ +
+Require Import List.
+Export ListNotations.
+Require Import PeanoNat.
+Require Import Lia.
+ +
+Require Import existsT.
+ +
+Require Import CML_Syntax.
+ +
+Definition In_dec l (a : MPropF) := in_dec eq_dec_form a l.
+ +
+(* Let us prove some lemmas about remove. *)
+ +
+Lemma in_not_touched_remove : forall l1 (a0 a1 : MPropF),
+        In a0 l1 -> a0 <> a1 -> In a0 (remove eq_dec_form a1 l1).
+Proof.
+induction l1.
+- intros. inversion H.
+- intros. simpl. destruct (eq_dec_form a1 a).
+  * subst. apply IHl1. inversion H. exfalso. apply H0. auto. assumption. assumption.
+  * inversion H. subst. apply in_eq. apply in_cons. apply IHl1. assumption. assumption.
+Qed.
+ +
+Lemma remove_dist_app {A : Type} (eq_dec : forall x y : A, {x = y} + {x <> y}) :
+        forall (a : A) l1 l2, (@remove A eq_dec a (l1 ++ l2)) =
+                              (@remove A eq_dec a l1) ++ (@remove A eq_dec a l2).
+Proof.
+intros a l1. induction l1.
+- intro l2. rewrite app_nil_l. simpl. reflexivity.
+- intro l2. simpl. destruct (eq_dec a a0).
+  * apply IHl1.
+  * simpl. rewrite IHl1. reflexivity.
+Qed.
+ +
+Lemma remove_not_in_anymore : forall l (A : MPropF),
+          (In A (remove eq_dec_form A l)) -> False.
+Proof.
+induction l.
+- intros. simpl in H. inversion H.
+- intros. simpl in H. destruct (eq_dec_form A a). subst. apply IHl in H. assumption.
+  inversion H. apply n. symmetry. assumption. apply IHl in H0. assumption.
+Qed.
+ +
+Lemma in_remove_in_init : forall l A B,
+    In A (remove eq_dec_form B l) -> In A l.
+Proof.
+induction l.
+- intros. simpl. inversion H.
+- intros. destruct (eq_dec_form A a). subst. apply in_eq. apply in_cons.
+  pose (IHl A B). apply i. simpl in H. destruct (eq_dec_form B a).
+  * subst. assumption.
+  * inversion H. exfalso. apply n. symmetry. assumption. assumption.
+Qed.
+ +
+Lemma remove_preserv_NoDup : forall l (A : MPropF), NoDup l -> NoDup (remove eq_dec_form A l).
+Proof.
+induction l.
+- intros. simpl. apply NoDup_nil.
+- intros. simpl. destruct (eq_dec_form A a).
+  * subst. apply IHl. inversion H. assumption.
+  * apply NoDup_cons. intro. apply in_remove_in_init in H0. inversion H. apply H3. assumption.
+    apply IHl. inversion H. assumption.
+Qed.
+ +
+Lemma NoDup_destr_split : forall l1 l2 (A : MPropF), NoDup (l1 ++ A :: l2) -> NoDup (l1 ++ l2).
+Proof.
+induction l1.
+- intros. rewrite app_nil_l. rewrite app_nil_l in H. inversion H. assumption.
+- intros. simpl. apply NoDup_cons. intro. inversion H. subst. apply H3. apply in_app_or in H0.
+  destruct H0. apply in_or_app. left. assumption. apply in_or_app. right. apply in_cons.
+  assumption. simpl in H. inversion H. subst. apply IHl1 with (A:=A). assumption.
+Qed.
+ +
+Lemma remove_le_length : forall l (A : MPropF), length (remove eq_dec_form A l) <= length l.
+Proof.
+induction l.
+- intros. simpl. reflexivity.
+- intros. simpl. destruct (eq_dec_form A a).
+  * subst. apply le_S. apply IHl.
+  * simpl. apply le_n_S. apply IHl.
+Qed.
+ +
+Lemma remove_In_smaller_length : forall l (A : MPropF),
+                                 In A l -> length (remove eq_dec_form A l) < length l.
+Proof.
+induction l.
+- intros. inversion H.
+- intros. simpl. destruct (eq_dec_form A a).
+  * subst. unfold lt. apply le_n_S. apply remove_le_length.
+  * simpl. rewrite <- Nat.succ_lt_mono. apply IHl. inversion H. subst. exfalso. apply n. auto.
+    assumption.
+Qed.
+ +
+Lemma double_remove {A : Type} (eq_dec : forall x y : A, {x = y} + {x <> y}) :
+      forall a l, (@remove A eq_dec a (@remove A eq_dec a l)) = (@remove A eq_dec a l).
+Proof.
+intros a l. induction l.
+- simpl. reflexivity.
+- simpl. destruct (eq_dec a a0).
+  * subst. apply IHl.
+  * simpl. destruct (eq_dec a a0).
+    + exfalso. apply n. assumption.
+    + rewrite IHl. reflexivity.
+Qed.
+ +
+Lemma permut_remove {A : Type} (eq_dec : forall x y : A, {x = y} + {x <> y}) :
+      forall a0 a1 l, (@remove A eq_dec a0 (@remove A eq_dec a1 l)) =
+                      (@remove A eq_dec a1 (@remove A eq_dec a0 l)).
+Proof.
+intros a0 a1 l. induction l.
+- simpl. reflexivity.
+- simpl. destruct (eq_dec a1 a).
+  * subst. simpl. destruct (eq_dec a0 a).
+    + subst. reflexivity.
+    + simpl. destruct (eq_dec a a). apply IHl. exfalso. apply n0. reflexivity.
+  * simpl. destruct (eq_dec a0 a).
+    + subst. assumption.
+    + simpl. destruct (eq_dec a1 a). exfalso. apply n. assumption.
+      rewrite IHl. reflexivity.
+Qed.
+ +
+Lemma In_remove_diff : forall l (A B : MPropF), In A (remove eq_dec_form B l) -> A <> B.
+Proof.
+induction l ; intros.
+- intro. simpl in H. assumption.
+- simpl in H. destruct (eq_dec_form B a).
+  * subst. apply IHl. assumption.
+  * inversion H.
+    + subst. intro. apply n. symmetry. assumption.
+    + apply IHl. assumption.
+Qed.
+ +
+(* Now we define remove_list and prove some lemmas about it. *)
+ +
+Fixpoint remove_list (l1 l2: list (MPropF)) : list (MPropF) :=
+match l1 with
+  | [] => l2
+  | h1 :: t1 => remove eq_dec_form h1 (remove_list t1 l2)
+end.
+ +
+Lemma remove_list_of_nil : forall (l : list (MPropF)), remove_list l nil = nil.
+Proof.
+induction l.
+- simpl. reflexivity.
+- simpl. rewrite IHl. simpl. reflexivity.
+Qed.
+ +
+Lemma app_remove_list : forall (l1 l2 l3 : list (MPropF)),
+        remove_list (l1 ++ l2) l3 = remove_list l1 (remove_list l2 l3).
+Proof.
+induction l1.
+- simpl. firstorder.
+- induction l2.
+  * intro l3. rewrite app_nil_r. simpl. reflexivity.
+  * intro l3. simpl. pose (IHl1 (a0 :: l2) l3). simpl in e.
+    rewrite e. reflexivity.
+Qed.
+ +
+Lemma remove_list_preserv_NoDup : forall l1 l2, NoDup l2 -> NoDup (remove_list l1 l2).
+Proof.
+induction l1.
+- intros. simpl. assumption.
+- intros. simpl. apply IHl1 in H. apply remove_preserv_NoDup with (A:=a) in H.
+  assumption.
+Qed.
+ +
+Lemma remove_list_cont : forall l1 A, In A l1 -> (forall l2, In A (remove_list l1 l2) -> False).
+Proof.
+induction l1.
+- intros. inversion H.
+- intros. inversion H.
+  * subst. simpl in H0. apply remove_not_in_anymore in H0. assumption.
+  * simpl in H0. pose (IHl1 A H1 l2). apply f. apply in_remove_in_init with (B:= a). assumption.
+Qed.
+ +
+Lemma remove_list_dist_app : forall (l1 l2 l3 : list (MPropF)),
+        remove_list l1 (l2 ++ l3) = (remove_list l1 l2) ++ (remove_list l1 l3).
+Proof.
+induction l1.
+- intros. simpl. reflexivity.
+- simpl. intros. rewrite IHl1. simpl. rewrite remove_dist_app. reflexivity.
+Qed.
+ +
+Lemma permut_remove_remove_list : forall a (l1 l2 : list (MPropF)),
+      remove eq_dec_form a (remove_list l1 l2) =
+      remove_list l1 (remove eq_dec_form a l2).
+Proof.
+intros a l1. generalize dependent a. induction l1 ; simpl.
+- reflexivity.
+- intros. rewrite permut_remove. rewrite IHl1. reflexivity.
+Qed.
+ +
+Lemma swap_remove_list : forall (l1 l2 l3 : list (MPropF)),
+      remove_list (l1 ++ l2) l3 = remove_list (l2 ++ l1) l3.
+Proof.
+induction l1.
+- intros. rewrite app_nil_l. rewrite app_nil_r. reflexivity.
+- induction l2.
+  * rewrite app_nil_l. rewrite app_nil_r. reflexivity.
+  * intro l3. simpl. rewrite IHl1. simpl. rewrite permut_remove.
+    rewrite <- IHl2. simpl. rewrite IHl1. reflexivity.
+Qed.
+ +
+Lemma redund_remove_remove_list : forall a (l1 l2 : list (MPropF)),
+      remove eq_dec_form a (remove_list (remove eq_dec_form a l1) l2) =
+      remove eq_dec_form a (remove_list l1 l2).
+Proof.
+intro a. induction l1.
+- intro l2. simpl. reflexivity.
+- intro l2. simpl. destruct (eq_dec_form a a0).
+  * rewrite IHl1. subst. rewrite double_remove. reflexivity.
+  * simpl. rewrite permut_remove. rewrite IHl1. apply permut_remove.
+Qed.
+ +
+Lemma redund_remove : forall (l1 l2 l3 : list (MPropF)) a,
+      remove eq_dec_form a (remove_list l1 (remove_list (remove eq_dec_form a l2) l3)) =
+      remove eq_dec_form a (remove_list l1 (remove_list l2 l3)).
+Proof.
+intros. repeat rewrite <- app_remove_list. rewrite swap_remove_list.
+rewrite app_remove_list. rewrite redund_remove_remove_list. rewrite <- app_remove_list.
+rewrite swap_remove_list. reflexivity.
+Qed.
+ +
+Lemma redund_remove_list : forall (l1 l2 l3 : list (MPropF)),
+      remove_list l1 (remove_list (remove_list l1 l2) l3) = remove_list l1 (remove_list l2 l3).
+Proof.
+induction l1 ; intros ; simpl.
+- reflexivity.
+- rewrite redund_remove. rewrite IHl1. reflexivity.
+Qed.
+ +
+Lemma remove_list_in_single : forall l1 a, (In a l1) -> remove_list l1 [a] = nil.
+Proof.
+induction l1.
+- intros. inversion H.
+- intros. inversion H.
+  * subst. simpl. rewrite permut_remove_remove_list. simpl. destruct (eq_dec_form a0 a0).
+    apply remove_list_of_nil. exfalso. apply n. reflexivity.
+  * apply IHl1 in H0. simpl. rewrite H0. simpl. reflexivity.
+Qed.
+ +
+Lemma not_removed_remove_list : forall l2 l1 A, In A l2 -> (In A l1 -> False) -> In A (remove_list l1 l2).
+Proof.
+induction l2.
+- intros. inversion H.
+- induction l1.
+  * intros. simpl. assumption.
+  * intros. simpl. pose (in_not_touched_remove (remove_list l1 (a :: l2))). pose (i A).
+    pose (i0 a0). apply i1. apply IHl1. assumption. intro. apply H0. apply in_cons. assumption.
+    clear i1. clear i0. clear i. destruct (eq_dec_form A a0). intro. apply H0. subst. apply in_eq.
+    assumption.
+Qed.
+ +
+Lemma add_remove_list_preserve_NoDup : forall (l1 l2 : list (MPropF)),
+            NoDup l1 -> NoDup l2 -> NoDup (l1 ++ (remove_list l1 l2)).
+Proof.
+induction l1.
+- intros. rewrite app_nil_l. simpl. assumption.
+- intros. simpl. apply NoDup_cons.
+  * intro. apply in_app_or in H1. destruct H1. inversion H. apply H4. assumption.
+    apply remove_not_in_anymore in H1. assumption.
+  * rewrite permut_remove_remove_list. apply IHl1. inversion H. assumption.
+    apply remove_preserv_NoDup. assumption.
+Qed.
+ +
+Lemma remove_list_is_in : forall l1 l2 A, In A l1 -> In A (l2 ++ (remove_list l2 l1)).
+Proof.
+intros. pose (In_dec l2 A). destruct s.
+- apply in_or_app. left. assumption.
+- apply in_or_app. right. apply not_removed_remove_list ; assumption.
+Qed.
+ +
+Lemma In_remove_same : forall l1 l2 (A : MPropF), In A l1 ->
+                remove_list l1 (A :: l2) = remove_list l1 l2.
+Proof.
+induction l1.
+- intros. inversion H.
+- intros. inversion H.
+  * subst. simpl. rewrite permut_remove_remove_list. simpl. destruct (eq_dec_form A A).
+    rewrite permut_remove_remove_list. reflexivity. exfalso. apply n. reflexivity.
+  * simpl. pose (IHl1 l2 A H0). rewrite e. reflexivity.
+Qed.
+ +
+Lemma In_remove_length_same : forall l1 l2 (A : MPropF), In A l1 ->
+                length (remove_list l1 (A :: l2)) = length (remove_list l1 l2).
+Proof.
+intros. rewrite In_remove_same. reflexivity. assumption.
+Qed.
+ +
+Lemma length_le_remove_list : forall (l1 l2 : list (MPropF)), length (remove_list l1 l2) <= length l2.
+Proof.
+induction l1.
+- intros. auto.
+- intros. simpl. rewrite permut_remove_remove_list. pose (IHl1 (remove eq_dec_form a l2)).
+  apply Nat.le_trans with (m:=length (remove eq_dec_form a l2)). assumption.
+  apply remove_le_length.
+Qed.
+ +
+Lemma remove_list_singl_id_or_nil : forall l (A : MPropF), remove_list l [A] = nil \/ remove_list l [A] = [A].
+Proof.
+induction l.
+- intros. right. auto.
+- intros. pose (IHl A). destruct o. left. simpl. rewrite H. auto.
+  simpl. rewrite H. destruct (eq_dec_form A a).
+  * subst. left. simpl. destruct (eq_dec_form a a). reflexivity. exfalso. apply n.
+    reflexivity.
+  * right. simpl. destruct (eq_dec_form a A). exfalso. apply n. symmetry. assumption.
+    reflexivity.
+Qed.
+ +
+Lemma remove_list_non_empty_inter_smaller_length : forall l2 l1 (A : MPropF),
+                                 In A l1 -> In A l2 -> length (remove_list l1 l2) < length l2.
+Proof.
+induction l2.
+- intros. inversion H0.
+- intros. simpl. destruct (eq_dec_form A a).
+  * subst. rewrite In_remove_length_same. 2: assumption. unfold lt. apply le_n_S.
+    apply length_le_remove_list.
+  * inversion H0.
+    + exfalso. apply n. symmetry. assumption.
+    + assert (a :: l2 = [a] ++ l2). auto. rewrite H2. rewrite remove_list_dist_app.
+      rewrite app_length. pose (remove_list_singl_id_or_nil l1 a). destruct o.
+      rewrite H3. simpl. apply Nat.lt_lt_succ_r. apply IHl2 with (A:=A) ; assumption.
+      rewrite H3. simpl. rewrite <- Nat.succ_lt_mono. apply IHl2 with (A:=A) ; assumption.
+Qed.
+ +
+Lemma remove_list_delete_head : forall l1 l2 l3 A, remove_list (l1 ++ A :: l2) (A :: l3) = remove_list (l1 ++ A :: l2) l3.
+Proof.
+induction l1 ; intros ; simpl.
+- rewrite permut_remove_remove_list. simpl. destruct (eq_dec_form A A). symmetry. apply permut_remove_remove_list.
+  exfalso. apply n. reflexivity.
+- rewrite IHl1. reflexivity.
+Qed.
+ +
+Lemma remove_list_delete_head_In : forall l1 l2 A, In A l1 -> remove_list l1 (A :: l2) = remove_list l1 l2.
+Proof.
+intros. pose (In_split A l1 H). destruct e. destruct H0. subst. apply remove_list_delete_head.
+Qed.
+ +
+Lemma remove_list_in_nil : forall l1 l2 l3 A,
+        remove_list l1 (l2 ++ A :: l3) = nil ->
+        (existsT2 l4 l5, l1 = l4 ++ A :: l5).
+Proof.
+induction l1.
+- intros. simpl in H. destruct l2 ; inversion H.
+- induction l2.
+  * intros. simpl in H. rewrite permut_remove_remove_list in H. simpl in H. destruct (eq_dec_form a A).
+    + subst. exists []. exists l1. auto.
+    + pose (IHl1 [] (remove eq_dec_form a l3)). simpl in s. apply s in H. destruct H. destruct s0.
+      exists ([a] ++ x). exists x0. subst. auto.
+  * intros. simpl in H. rewrite permut_remove_remove_list in H. simpl in H. destruct (eq_dec_form a a0).
+    + subst. pose (IHl2 l3 A). apply s. rewrite <- permut_remove_remove_list in H. simpl. assumption.
+    + pose (IHl1 [] (remove eq_dec_form a (l2 ++ A :: l3)) a0). pose (s H). repeat destruct s0.
+      subst. apply IHl2 with (l3:= l3). simpl. rewrite permut_remove_remove_list.
+      rewrite remove_list_delete_head in H. assumption.
+Qed.
+ +
+Lemma remove_list_is_nil : forall l1 l2, (remove_list l1 l2 = nil <-> (forall A, (In A l2) -> (In A l1))).
+Proof.
+induction l1.
+- intro l2. split.
+  * intros. simpl in H. rewrite <- H. assumption.
+  * intros. simpl. destruct l2.
+    + reflexivity.
+    + exfalso. pose (H m). assert (In m (m :: l2)). apply in_eq. apply i in H0. inversion H0.
+- induction l2.
+  * split.
+    + intros. inversion H0.
+    + intros. apply remove_list_of_nil.
+  * split.
+    + intros. simpl in H. rewrite permut_remove_remove_list in H. simpl in H. destruct (eq_dec_form a a0).
+      subst. inversion H0. subst. apply in_eq. rewrite <- permut_remove_remove_list in H. simpl in IHl2.
+      rewrite IHl2 in H. apply H in H1. destruct H1. subst. apply in_eq. apply in_cons. assumption.
+      inversion H0. subst. apply in_cons. pose (remove_list_in_nil l1 [] (remove eq_dec_form a l2) A).
+      simpl in s. apply s in H. destruct H. destruct s0. subst. apply in_or_app. right. apply in_eq.
+      apply IHl2. 2: assumption. simpl. rewrite permut_remove_remove_list.
+      pose (app_eq_nil (remove_list l1 [a0]) (remove_list l1 (remove eq_dec_form a l2))). simpl in a1.
+      assert (H2: remove_list l1 [a0] ++ remove_list l1 (remove eq_dec_form a l2) = []).
+      rewrite <- remove_list_dist_app. simpl. assumption. apply a1 in H2. destruct H2. assumption.
+    + intros. simpl. rewrite permut_remove_remove_list. simpl. destruct (eq_dec_form a a0).
+      { subst. rewrite <- permut_remove_remove_list. simpl in IHl2. rewrite IHl2. intros.
+        pose (H A). apply i. apply in_cons. assumption. }
+      { assert (H1: (forall A : MPropF, In A l2 -> In A (a :: l1))). intros. apply H.
+        apply in_cons. assumption. apply IHl2 in H1.
+        assert (H2: a0 :: remove eq_dec_form a l2 = [a0] ++ remove eq_dec_form a l2). auto.
+        rewrite H2. rewrite remove_list_dist_app. clear H2. rewrite <- permut_remove_remove_list.
+        simpl in H1. rewrite H1. rewrite app_nil_r. apply remove_list_in_single. pose (H a0).
+        assert (H3: In a0 (a0 :: l2)). apply in_eq. apply i in H3. inversion H3. exfalso. apply n.
+        assumption. assumption. }
+Qed.
+ +
+Lemma remove_delete_origin : forall l1 l2 (A B : MPropF), (A <> B) ->
+            length (remove eq_dec_form A (l1 ++ B :: l2)) = S (length (remove eq_dec_form A (l1 ++ l2))).
+Proof.
+induction l1.
+- intros. repeat rewrite app_nil_l. simpl. destruct (eq_dec_form A B). exfalso. apply H. assumption.
+  simpl. reflexivity.
+- intros. simpl. destruct (eq_dec_form A a).
+  * apply IHl1. assumption.
+  * simpl. apply eq_S. apply IHl1. assumption.
+Qed.
+ +
+Lemma keep_list_delete_head_not_origin : forall l1 l2 l3 A, ((In A l1) -> False) ->
+                length (remove_list l1 (l2 ++ A :: l3)) = S (length (remove_list l1 (l2 ++ l3))).
+Proof.
+induction l1.
+- intros. simpl. rewrite app_length. simpl. rewrite app_length. auto.
+- intros. simpl. repeat rewrite remove_list_dist_app. assert (In A l1 -> False).
+  intro. apply H. apply in_cons. assumption. assert (A :: l3 = [A] ++ l3).
+  auto. rewrite H1. rewrite remove_list_dist_app. pose (remove_list_singl_id_or_nil l1 A).
+  destruct o. exfalso. rewrite remove_list_is_nil in H2. apply H0. apply H2.
+  apply in_eq. rewrite H2. apply remove_delete_origin. intro. apply H. subst. apply in_eq.
+Qed.
+ +
+Lemma keep_list_delete_head_not_In : forall l1 l2 A, ((In A l1) -> False) ->
+                length (remove_list l1 (A :: l2)) = S (length (remove_list l1 l2)).
+Proof.
+intros. pose (@keep_list_delete_head_not_origin l1 [] l2 A H). repeat rewrite app_nil_l in e.
+assumption.
+Qed.
+ +
+Lemma In_remove_In_list : forall (A B : MPropF) l, In A (remove eq_dec_form B l) -> In A l.
+Proof.
+induction l ; intros.
+- simpl in H. destruct H.
+- simpl in H. destruct (eq_dec_form B a).
+  * subst. apply in_cons. apply IHl. assumption.
+  * inversion H.
+    + subst. apply in_eq.
+    + apply in_cons. apply IHl. assumption.
+Qed.
+ +
+Lemma In_remove_list_In_list : forall (A : MPropF) l1 l2, In A (remove_list l1 l2) -> In A l2.
+Proof.
+intro A. induction l1 ; intros.
+- simpl in H. assumption.
+- simpl in H. apply In_remove_In_list in H. apply IHl1. assumption.
+Qed.
+ +
+Lemma In_remove_list_In_list_not_In_remove_list : forall (A : MPropF) l1 l2,
+            In A (remove_list l1 l2) -> (In A l2 /\ ((In A l1) -> False)).
+Proof.
+intro A. induction l1 ; intros.
+- simpl in H. split. assumption. intro. inversion H0.
+- simpl in H. split. apply In_remove_In_list in H. apply IHl1. assumption. intro.
+  inversion H0.
+  * subst. apply remove_not_in_anymore in H. assumption.
+  * apply In_remove_In_list in H. apply IHl1 in H. destruct H. apply H2. assumption.
+Qed.
+ +
+Lemma remove_list_incr_decr3 : forall (l3 l2 l1 : list (MPropF)),
+              (incl l1 l2) ->
+              length (remove_list l2 l3) <= length (remove_list l1 l3).
+Proof.
+induction l3 ; intros.
+- repeat rewrite remove_list_of_nil. auto.
+- destruct (In_dec l2 a).
+  + rewrite remove_list_delete_head_In. 2: assumption. destruct (In_dec l1 a).
+    * rewrite remove_list_delete_head_In. 2: assumption. apply IHl3 ; auto.
+    * rewrite keep_list_delete_head_not_In. 2: assumption. apply Nat.le_le_succ_r.
+      apply IHl3. assumption.
+  + repeat rewrite keep_list_delete_head_not_In. apply le_n_S. apply IHl3 ; auto.
+    intro. apply n. apply H. assumption. assumption.
+Qed.
+ +
+Lemma remove_list_incr_decr1 : forall (l3 l1 l2: list (MPropF)),
+              (exists A, In A l2 /\ In A l3 /\ (In A l1 -> False)) ->
+              (incl l1 l2) ->
+              length (remove_list l2 l3) < length (remove_list l1 l3).
+Proof.
+induction l3.
+- intros. destruct H. destruct H. destruct H1. exfalso. inversion H1.
+- intros. destruct H. destruct H. destruct H1. destruct (eq_dec_form a x).
+  * subst. rewrite remove_list_delete_head_In. 2: assumption.
+    rewrite keep_list_delete_head_not_In. 2: assumption. unfold lt.
+    apply le_n_S. apply remove_list_incr_decr3. assumption.
+  * inversion H1. exfalso. apply n ; assumption.
+    assert (H4: exists A : MPropF, In A l2 /\ In A l3 /\ (In A l1 -> False)).
+    exists x. auto. apply IHl3 in H4. 2 : assumption. unfold lt.
+    destruct (In_dec l2 a).
+    + rewrite remove_list_delete_head_In. 2: assumption. destruct (In_dec l1 a).
+      { rewrite remove_list_delete_head_In. 2: assumption. apply H4. }
+      { rewrite keep_list_delete_head_not_In. 2: assumption. apply le_n_S.
+        unfold lt in H4. apply Nat.lt_le_incl. assumption. }
+    + rewrite keep_list_delete_head_not_In. 2: assumption. rewrite keep_list_delete_head_not_In.
+      unfold lt in H4. apply le_n_S. assumption. intro. apply n0. apply H0. assumption.
+Qed.
+ +
+Lemma remove_list_incr_decr2 : forall (l4 l3 l1 : list (MPropF)),
+              (NoDup l4) ->
+              (NoDup l3) ->
+              (incl l4 l3) ->
+              length (remove_list l1 l4) <= length (remove_list l1 l3).
+Proof.
+induction l4.
+- intros. rewrite remove_list_of_nil. simpl. apply le_0_n.
+- intros. destruct (In_dec l1 a).
+  * rewrite remove_list_delete_head_In. 2: assumption. apply IHl4 ; try assumption.
+    inversion H. assumption. unfold incl. intros. apply H1. apply in_cons. assumption.
+  * rewrite keep_list_delete_head_not_In. 2: assumption. assert (H2: In a l3). apply H1.
+    apply in_eq. pose (in_split a l3 H2). repeat destruct e. destruct H3. rewrite H3.
+    rewrite keep_list_delete_head_not_origin. 2: assumption. apply le_n_S. apply IHl4.
+    inversion H. assumption. subst. apply NoDup_destr_split with (A:=a). assumption.
+    inversion H. unfold incl. intros. subst. assert (H9 : In a0 (a :: l4)). apply in_cons.
+    assumption. pose (H1 a0 H9). apply in_app_or in i. destruct i. apply in_or_app. left.
+    assumption. inversion H3. subst. exfalso. apply H6. assumption. apply in_or_app. right.
+    assumption.
+Qed.
+ +
+Lemma remove_list_incr_decr4 : forall (l4 l3 l1: list (MPropF)),
+              (NoDup l4) ->
+              (NoDup l3) ->
+              (incl l4 l3) ->
+              ((incl l3 l4) -> False) ->
+              (exists A, (In A l3) /\ ((In A l1) -> False) /\ ((In A l4) -> False)) ->
+              length (remove_list l1 l4) < length (remove_list l1 l3).
+Proof.
+induction l4.
+- intros. rewrite remove_list_of_nil. simpl. destruct H3. destruct H3. destruct H4. pose (In_split x l3 H3).
+  destruct e. destruct H6. subst. rewrite keep_list_delete_head_not_origin. 2: assumption.
+  apply Nat.lt_0_succ.
+- intros. destruct (In_dec l1 a).
+  * rewrite remove_list_delete_head_In. 2: assumption. apply IHl4 ; try assumption.
+    inversion H. assumption. unfold incl. intros. apply H1. apply in_cons. assumption.
+    intro. apply H2. unfold incl. intros. apply in_cons. apply H4. assumption. destruct H3.
+    destruct H3. destruct H4. exists x. repeat split ; try assumption. intro. apply H5.
+    apply in_cons. assumption.
+  * rewrite keep_list_delete_head_not_In. 2: assumption. assert (In a l3). apply H1.
+    apply in_eq. pose (In_split a l3 H4). destruct e. destruct H5. subst.
+    rewrite keep_list_delete_head_not_origin. 2 : assumption. rewrite <- Nat.succ_lt_mono.
+    apply IHl4. inversion H. assumption. apply NoDup_destr_split with (A:=a). assumption.
+    unfold incl. intros. pose (H1 a0). assert (In a0 (a :: l4)). apply in_cons. assumption.
+    apply i in H6. apply in_app_or in H6. destruct H6. apply in_or_app. left. assumption.
+    inversion H6. subst. inversion H. exfalso. apply H9. assumption. apply in_or_app. right.
+    assumption. intro. apply H2. unfold incl. intros. apply in_app_or in H6. destruct H6.
+    apply in_cons. apply H5. apply in_or_app. left. assumption. inversion H6. subst. apply in_eq.
+    apply in_cons. apply H5. apply in_or_app. right. assumption.
+    destruct H3. destruct H3. destruct H5. exists x1. repeat split ; try assumption.
+    apply in_app_or in H3. destruct H3. apply in_or_app. left. assumption. inversion H3.
+    subst. exfalso. apply H6. apply in_eq. apply in_or_app. right. assumption.
+    intro. apply H6. apply in_cons. assumption.
+Qed.
+ +
+Lemma remove_list_incr_decr : forall (l1 l2 l3 l4 : list (MPropF)),
+              (NoDup l4) ->
+              (NoDup l3) ->
+              (exists A, In A l2 /\ In A l3 /\ (In A l1 -> False)) ->
+              (incl l1 l2) ->
+              (incl l4 l3) ->
+              length (remove_list l2 l4) < length (remove_list l1 l3).
+Proof.
+intros. unfold lt.
+pose (remove_list_incr_decr2 _ _ l1 H H0 H3).
+repeat destruct H1. destruct H4. destruct (In_dec l4 x).
+- assert (H6: (exists A, In A l2 /\ In A l4 /\ (In A l1 -> False))).
+  exists x. repeat split ; assumption. pose (@remove_list_incr_decr1 l4 l1 l2 H6 H2).
+  unfold lt in l0. apply Nat.le_trans with (m:=length (remove_list l1 l4)) ; assumption.
+- assert ((incl l3 l4) -> False). intros. apply n. apply H6. assumption.
+  assert ((exists A, (In A l3) /\ ((In A l1) -> False) /\ ((In A l4) -> False))). exists x. auto.
+  pose (@remove_list_incr_decr3 l4 l2 l1 H2). pose (@remove_list_incr_decr4 l4 l3 l1 H H0 H3 H6 H7).
+  unfold lt in l5. apply le_n_S in l0.
+  apply Nat.le_trans with (m:=S (length (remove_list l1 l4))) ; assumption.
+Qed.
+ +
+Lemma In_remove_list_remove_redund : forall l1 l2 a, In a l1 ->
+                remove eq_dec_form a (remove_list l1 l2) = remove_list l1 l2.
+Proof.
+induction l1.
+- intros. inversion H.
+- intros. simpl. inversion H.
+  * subst. rewrite double_remove. reflexivity.
+  * pose (IHl1 l2 a0 H0). rewrite permut_remove. rewrite e. reflexivity.
+Qed.
+ +
+Lemma In_matters_remove_list : forall l1 l2, (incl l1 l2 /\ incl l2 l1) -> (forall l0,
+                                    remove_list l1 l0 = remove_list l2 l0).
+Proof.
+induction l1.
+- intros. destruct H. destruct l2. auto. unfold incl in H0. pose (H0 m). assert (In m (m :: l2)).
+  apply in_eq. apply i in H1. inversion H1.
+- intros. destruct H. simpl. pose (H a). assert (In a (a :: l1)). apply in_eq. apply i in H1.
+  apply in_split in H1. destruct H1. destruct H1. subst. destruct (In_dec l1 a).
+  * rewrite In_remove_list_remove_redund. 2: assumption. apply IHl1. split. intro. intro.
+    apply H. apply in_cons. assumption. intro. intro. apply H0 in H1. inversion H1. subst.
+    assumption. assumption.
+  * rewrite swap_remove_list. simpl. rewrite <- redund_remove_remove_list with (l1:=(x0 ++ x)).
+    pose (IHl1 (remove eq_dec_form a (x0 ++ x))). rewrite e.
+    auto. split. intro. intro. apply in_not_touched_remove. assert (In a0 (a :: l1)). apply in_cons.
+    assumption. apply H in H2. apply in_app_or in H2. destruct H2. apply in_or_app. right. assumption.
+    inversion H2. subst. exfalso. apply n. assumption. apply in_or_app. left. assumption.
+    intro. subst. apply n. assumption. intro. intro. pose (In_remove_diff (x0 ++ x) _ _ H1).
+    pose (In_remove_In_list a0 a (x0 ++ x) H1). assert (In a0 (x ++ a :: x0)). apply in_app_or in i0.
+    destruct i0. apply in_or_app. right. apply in_cons. assumption. apply in_or_app. left. assumption.
+    apply H0 in H2. inversion H2. exfalso. apply n0. symmetry. assumption. assumption.
+Qed.
+
+
+ +
+ + + diff --git a/UIML_extraction.UIML_extraction.html b/UIML_extraction.UIML_extraction.html new file mode 100644 index 0000000..59ef27f --- /dev/null +++ b/UIML_extraction.UIML_extraction.html @@ -0,0 +1,94 @@ + + + + + + + + + + + + + +
+
+

UIML_extraction.UIML_extraction

+ +
+Require Import GL.Interpolation.UIGL_braga.
+Require Import GLS_export.
+Require Import ExtrOcamlBasic ExtrOcamlString.
+ +
+Require Import K.Interpolation.UIK_braga.
+Require Import KS_export.
+Require Import ISL.PropQuantifiers ISL.DecisionProcedure.
+ +
+Require Import ISL.Simp.
+ +
+Fixpoint MPropF_of_form (f : Formulas.form) : MPropF :=
+match f with
+| Formulas.Var n => Var n
+| Formulas.Bot => Bot
+| Formulas.Implies f1 f2 => Imp (MPropF_of_form f1) (MPropF_of_form f2)
+| Formulas.And f1 f2 => Imp (Imp (MPropF_of_form f1) (Imp (MPropF_of_form f2) Bot)) Bot
+| Formulas.Or f1 f2 => Imp (Imp (MPropF_of_form f1) Bot) (MPropF_of_form f2)
+| Formulas.Box f => Box (MPropF_of_form f)
+end.
+ +
+Fixpoint form_of_MPropF (f : MPropF) : Formulas.form :=
+match f with
+| Var n => Formulas.Var n
+| Bot => Formulas.Bot
+| Imp f1 f2 => Formulas.Implies (form_of_MPropF f1) (form_of_MPropF f2)
+| Box f => Formulas.Box (form_of_MPropF f)
+end.
+ +
+Definition gl_UI p s := form_of_MPropF (proj1_sig (GL.Interpolation.UIGL_braga.GUI_tot p ([],[MPropF_of_form s]))).
+Definition k_UI p s := form_of_MPropF(proj1_sig (K.Interpolation.UIK_braga.GUI_tot p ([],[MPropF_of_form s]))).
+ +
+Definition isl_E v f := Ef v f.
+Definition isl_A v f := Af v f.
+ +
+Definition isl_simp f := simp f.
+ +
+Definition isl_simplified_E v f := E_simplified v f.
+Definition isl_simplified_A v f := A_simplified v f.
+ +
+Set Extraction Output Directory "extraction".
+ +
+Separate Extraction Provable_dec gl_UI k_UI isl_E isl_A isl_simplified_E isl_simplified_A Formulas.weight isl_simp.
+ +
+
+
+ +
+ + + diff --git a/config.js b/config.js new file mode 100644 index 0000000..72be613 --- /dev/null +++ b/config.js @@ -0,0 +1,72 @@ +var coqdocjs = coqdocjs || {}; + +coqdocjs.repl = { + "forall": "∀", + "exists": "∃", + "~": "¬", + "/\\": "∧", + "\\/": "∨", + "->": "→", + "<-": "←", + "<->": "↔", + "=>": "⇒", + "<>": "≠", + "<=": "≤", + ">=": "≥", + "el": "∈", + "nel": "∉", + "<<=": "⊆", + "|-": "⊢", + ">>": "»", + "<<": "⊆", + "++": "⧺", + "===": "≡", + "=/=": "≢", + "=~=": "≅", + "==>": "⟹", + "lhd": "⊲", + "rhd": "⊳", + "nat": "ℕ", + "alpha": "α", + "beta": "β", + "gamma": "γ", + "delta": "δ", + "epsilon": "ε", + "eta": "η", + "iota": "ι", + "kappa": "κ", + "lambda": "λ", + "mu": "μ", + "nu": "ν", + "omega": "ω", + "phi": "ϕ", + "pi": "π", + "psi": "ψ", + "rho": "ρ", + "sigma": "σ", + "tau": "τ", + "theta": "θ", + "xi": "ξ", + "zeta": "ζ", + "Delta": "Δ", + "Gamma": "Γ", + "Pi": "Π", + "Sigma": "Σ", + "Omega": "Ω", + "Xi": "Ξ" +}; + +coqdocjs.subscr = { + "0" : "₀", + "1" : "₁", + "2" : "₂", + "3" : "₃", + "4" : "₄", + "5" : "₅", + "6" : "₆", + "7" : "₇", + "8" : "₈", + "9" : "₉", +}; + +coqdocjs.replInText = ["==>","<=>", "=>", "->", "<-", ":="]; diff --git a/coqdoc.css b/coqdoc.css new file mode 100644 index 0000000..7753021 --- /dev/null +++ b/coqdoc.css @@ -0,0 +1,244 @@ +body { + font-family: Times New Roman, serif; + font-size: 1.5em; + color: #2D2D2D +} + +td { + padding: 0 10px; +} + +td.ms { + font-family: 'Courier New', monospace; +} + +a { + text-decoration: none; + border-radius: 3px; + padding-left: 3px; + padding-right: 3px; + margin-left: -3px; + margin-right: -3px; + color: inherit; + font-weight: bold; +} + +#main .code a, +#main .inlinecode a, +#toc a { + font-weight: inherit; +} + +a[href]:hover, +[clickable]:hover { + background-color: rgba(0, 0, 0, 0.1); + cursor: pointer; +} + +h, +h1, +h2, +h3, +h4, +h5 { + line-height: 1; + color: black; + text-rendering: optimizeLegibility; + font-weight: normal; + text-align: left; +} + +div+br { + display: none; +} + +div:empty { + display: none; +} + +#main h1 { + font-size: 2em; +} + +#main h2 { + font-size: 1.667rem; +} + +#main h3 { + font-size: 1.333em; +} + +#main h4, +#main h5, +#main h6 { + font-size: 1em; +} + +#toc h2 { + padding-bottom: 0; +} + +#main .doc { + margin: 0; + text-align: justify; +} + +.inlinecode, +.code, +#main pre { + font-family: monospace; +} + +.code>br:first-child { + display: none; +} + +.doc+.code { + margin-top: 0.5em; +} + +.block { + display: block; + margin-top: 5px; + margin-bottom: 5px; + padding: 10px; + text-align: center; +} + +.block img { + margin: 15px; +} + +table.infrule { + border: 0px; + margin-left: 50px; + margin-top: 10px; + margin-bottom: 10px; +} + +td.infrule { + font-family: "Droid Sans Mono", "DejaVu Sans Mono", monospace; + text-align: center; + padding: 0; + line-height: 1; +} + +tr.infrulemiddle hr { + margin: 1px 0 1px 0; +} + +.infrulenamecol { + color: rgb(60%, 60%, 60%); + padding-left: 1em; + padding-bottom: 0.1em +} + +.id[type="constructor"], +.id[type="projection"], +.id[type="method"], +.id[title="constructor"], +.id[title="projection"], +.id[title="method"] { + color: #A30E16; +} + +.id[type="var"], +.id[type="variable"], +.id[title="var"], +.id[title="variable"] { + color: inherit; +} + +.id[type="definition"], +.id[type="record"], +.id[type="class"], +.id[type="instance"], +.id[type="inductive"], +.id[type="library"], +.id[title="definition"], +.id[title="record"], +.id[title="class"], +.id[title="instance"], +.id[title="inductive"], +.id[title="library"] { + color: #A6650F; +} + +.id[type="lemma"], +.id[title="lemma"] { + color: #188B0C; +} + +.id[type="keyword"], +.id[type="notation"], +.id[type="abbreviation"], +.id[title="keyword"], +.id[title="notation"], +.id[title="abbreviation"] { + color: #2874AE; +} + +.comment { + color: #808080; +} + +/* TOC */ + +#toc h2 { + letter-spacing: 0; + font-size: 1.333em; +} + +/* Index */ + +#index { + margin: 0; + padding: 0; + width: 100%; +} + +#index #frontispiece { + margin: 1em auto; + padding: 1em; + width: 60%; +} + +.booktitle { + font-size: 140% +} + +.authors { + font-size: 90%; + line-height: 115%; +} + +.moreauthors { + font-size: 60% +} + +#index #entrance { + text-align: center; +} + +#index #entrance .spacer { + margin: 0 30px 0 30px; +} + +ul.doclist { + margin-top: 0em; + margin-bottom: 0em; +} + +#toc>* { + clear: both; +} + +#toc>a { + display: block; + float: left; + margin-top: 1em; +} + +#toc a h2 { + display: inline; +} diff --git a/coqdocjs.css b/coqdocjs.css new file mode 100644 index 0000000..d94bb58 --- /dev/null +++ b/coqdocjs.css @@ -0,0 +1,249 @@ +/* replace unicode */ + +.id[repl] .hidden { + font-size: 0; +} + +.id[repl]:before{ + content: attr(repl); +} + +/* folding proofs */ + +@keyframes show-proof { + 0% { + max-height: 1.2em; + opacity: 1; + } + 99% { + max-height: 1000em; + } + 100%{ + } +} + +@keyframes hide-proof { + from { + visibility: visible; + max-height: 10em; + opacity: 1; + } + to { + max-height: 1.2em; + } +} + +.proof { + cursor: pointer; +} +.proof * { + cursor: pointer; +} + +.proof { + overflow: hidden; + position: relative; + transition: opacity 1s; + display: inline-block; +} + +.proof[show="false"] { + max-height: 1.2em; + visibility: visible; + opacity: 0.3; +} + +.proof[show="false"][animate] { + animation-name: hide-proof; + animation-duration: 0.25s; +} + +.proof[show=true] { + animation-name: show-proof; + animation-duration: 10s; +} + +.proof[show="false"]:before { + position: absolute; + visibility: visible; + width: 100%; + height: 100%; + display: block; + opacity: 0; + content: "M"; +} +.proof[show="false"]:hover:before { + content: ""; +} + +.proof[show="false"] + br + br { + display: none; +} + +.proof[show="false"]:hover { + visibility: visible; + opacity: 0.5; +} + +#toggle-proofs[proof-status="no-proofs"] { + display: none; +} + +#toggle-proofs[proof-status="some-hidden"]:before { + content: "Show Proofs"; +} + +#toggle-proofs[proof-status="all-shown"]:before { + content: "Hide Proofs"; +} + + +/* page layout */ + +html, body { + height: 100%; + margin:0; + padding:0; +} + +@media only screen { /* no div with internal scrolling to allow printing of whole content */ + body { + display: flex; + flex-direction: column + } + + #content { + flex: 1; + overflow: auto; + display: flex; + flex-direction: column; + } +} + +#content:focus { + outline: none; /* prevent glow in OS X */ +} + +#main { + display: block; + padding: 16px; + padding-top: 1em; + padding-bottom: 2em; + margin-left: auto; + margin-right: auto; + max-width: 60em; + flex: 1 0 auto; +} + +.libtitle { + display: none; +} + +/* header */ +#header { + width:100%; + padding: 0; + margin: 0; + display: flex; + align-items: center; + background-color: rgb(21,57,105); + color: white; + font-weight: bold; + overflow: hidden; +} + + +.button { + cursor: pointer; +} + +#header * { + text-decoration: none; + vertical-align: middle; + margin-left: 15px; + margin-right: 15px; +} + +#header > .right, #header > .left { + display: flex; + flex: 1; + align-items: center; +} +#header > .left { + text-align: left; +} +#header > .right { + flex-direction: row-reverse; +} + +#header a, #header .button { + color: white; + box-sizing: border-box; +} + +#header a { + border-radius: 0; + padding: 0.2em; +} + +#header .button { + background-color: rgb(63, 103, 156); + border-radius: 1em; + padding-left: 0.5em; + padding-right: 0.5em; + margin: 0.2em; +} + +#header a:hover, #header .button:hover { + background-color: rgb(181, 213, 255); + color: black; +} + +#header h1 { padding: 0; + margin: 0;} + +/* footer */ +#footer { + text-align: center; + opacity: 0.5; + font-size: 75%; +} + +/* hyperlinks */ + +@keyframes highlight { + 50%{ + background-color: black; + } +} + +:target * { + animation-name: highlight; + animation-duration: 1s; +} + +a[name]:empty { + float: right; +} + +/* Proviola */ + +div.code { + width: auto; + float: none; +} + +div.goal { + position: fixed; + left: 75%; + width: 25%; + top: 3em; +} + +div.doc { + clear: both; +} + +span.command:hover { + background-color: inherit; +} diff --git a/coqdocjs.js b/coqdocjs.js new file mode 100644 index 0000000..10dc0bb --- /dev/null +++ b/coqdocjs.js @@ -0,0 +1,189 @@ +var coqdocjs = coqdocjs || {}; +(function(){ + +function replace(s){ + var m; + if (m = s.match(/^(.+)'/)) { + return replace(m[1])+"'"; + } else if (m = s.match(/^([A-Za-z]+)_?(\d+)$/)) { + return replace(m[1])+m[2].replace(/\d/g, function(d){ + if (coqdocjs.subscr.hasOwnProperty(d)) { + return coqdocjs.subscr[d]; + } else { + return d; + } + }); + } else if (coqdocjs.repl.hasOwnProperty(s)){ + return coqdocjs.repl[s] + } else { + return s; + } +} + +function toArray(nl){ + return Array.prototype.slice.call(nl); +} + +function replInTextNodes() { + coqdocjs.replInText.forEach(function(toReplace){ + toArray(document.getElementsByClassName("code")).concat(toArray(document.getElementsByClassName("inlinecode"))).forEach(function(elem){ + toArray(elem.childNodes).forEach(function(node){ + if (node.nodeType != Node.TEXT_NODE) return; + var fragments = node.textContent.split(toReplace); + node.textContent = fragments[fragments.length-1]; + for (var k = 0; k < fragments.length - 1; ++k) { + node.parentNode.insertBefore(document.createTextNode(fragments[k]),node); + var replacement = document.createElement("span"); + replacement.appendChild(document.createTextNode(toReplace)); + replacement.setAttribute("class", "id"); + replacement.setAttribute("type", "keyword"); + node.parentNode.insertBefore(replacement, node); + } + }); + }); + }); +} + +function replNodes() { + toArray(document.getElementsByClassName("id")).forEach(function(node){ + if (["var", "variable", "keyword", "notation", "definition", "inductive"].indexOf(node.getAttribute("type"))>=0){ + var text = node.textContent; + var replText = replace(text); + if(text != replText) { + node.setAttribute("repl", replText); + node.setAttribute("title", text); + var hidden = document.createElement("span"); + hidden.setAttribute("class", "hidden"); + while (node.firstChild) { + hidden.appendChild(node.firstChild); + } + node.appendChild(hidden); + } + } + }); +} + +function isVernacStart(l, t){ + t = t.trim(); + for(var s of l){ + if (t == s || t.startsWith(s+" ") || t.startsWith(s+".")){ + return true; + } + } + return false; +} + +function isProofStart(n){ + return isVernacStart(["Proof"], n.textContent) || + (isVernacStart(["Next"], n.textContent) && isVernacStart(["Obligation"], n.nextSibling.nextSibling.textContent)); +} + +function isProofEnd(s){ + return isVernacStart(["Qed", "Admitted", "Defined", "Abort"], s); +} + +function proofStatus(){ + var proofs = toArray(document.getElementsByClassName("proof")); + if(proofs.length) { + for(var proof of proofs) { + if (proof.getAttribute("show") === "false") { + return "some-hidden"; + } + } + return "all-shown"; + } + else { + return "no-proofs"; + } +} + +function updateView(){ + document.getElementById("toggle-proofs").setAttribute("proof-status", proofStatus()); +} + +function foldProofs() { + var hasCommands = true; + var nodes = document.getElementsByClassName("command"); + if(nodes.length == 0) { + hasCommands = false; + console.log("no command tags found") + nodes = document.getElementsByClassName("id"); + } + toArray(nodes).forEach(function(node){ + if(isProofStart(node)) { + var proof = document.createElement("span"); + proof.setAttribute("class", "proof"); + + node.parentNode.insertBefore(proof, node); + if(proof.previousSibling.nodeType === Node.TEXT_NODE) + proof.appendChild(proof.previousSibling); + while(node && !isProofEnd(node.textContent)) { + proof.appendChild(node); + node = proof.nextSibling; + } + if (proof.nextSibling) proof.appendChild(proof.nextSibling); // the Qed + if (!hasCommands && proof.nextSibling) proof.appendChild(proof.nextSibling); // the dot after the Qed + + proof.addEventListener("click", function(proof){return function(e){ + if (e.target.parentNode.tagName.toLowerCase() === "a") + return; + proof.setAttribute("show", proof.getAttribute("show") === "true" ? "false" : "true"); + proof.setAttribute("animate", ""); + updateView(); + };}(proof)); + proof.setAttribute("show", "false"); + } + }); +} + +function toggleProofs(){ + var someProofsHidden = proofStatus() === "some-hidden"; + toArray(document.getElementsByClassName("proof")).forEach(function(proof){ + proof.setAttribute("show", someProofsHidden); + proof.setAttribute("animate", ""); + }); + updateView(); +} + +function repairDom(){ + // pull whitespace out of command + toArray(document.getElementsByClassName("command")).forEach(function(node){ + while(node.firstChild && node.firstChild.textContent.trim() == ""){ + console.log("try move"); + node.parentNode.insertBefore(node.firstChild, node); + } + }); + toArray(document.getElementsByClassName("id")).forEach(function(node){ + node.setAttribute("type", node.getAttribute("title")); + }); + toArray(document.getElementsByClassName("idref")).forEach(function(ref){ + toArray(ref.childNodes).forEach(function(child){ + if (["var", "variable"].indexOf(child.getAttribute("type")) > -1) + ref.removeAttribute("href"); + }); + }); + +} + +function fixTitle(){ + var url = "/" + window.location.pathname; + var basename = url.substring(url.lastIndexOf('/')+1, url.lastIndexOf('.')); + if (basename === "toc") {document.title = "Table of Contents";} + else if (basename === "indexpage") {document.title = "Index";} + else {document.title = basename;} +} + +function postprocess(){ + repairDom(); + replInTextNodes() + replNodes(); + foldProofs(); + document.getElementById("toggle-proofs").addEventListener("click", toggleProofs); + updateView(); +} + +fixTitle(); +document.addEventListener('DOMContentLoaded', postprocess); + +coqdocjs.toggleProofs = toggleProofs; +})(); diff --git a/demo.html b/demo.html new file mode 100644 index 0000000..c94d08f --- /dev/null +++ b/demo.html @@ -0,0 +1,139 @@ + + + + + + + + + + Uniform interpolant calculator + + + + + +
+
+ +

Enter a formula below and choose a logic and interpolant to compute.

+ + + + +

+
Result:

+
+ + Usage instructions. + We support four logics: +
    +
  • intuitionistic logic (IL),
  • +
  • Gödel-Löb logic (GL),
  • +
  • basic modal logic (K), and +
  • intuitionistic Strong Löb logic (iSL).
  • +
+ You may use the following symbols: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
->implication
¬~negation
&conjunction (and)
|disjunction (or)
[]necessity (box)
<>possibility (diamond)
Tverum
F, #falsum
ppropositional variable to be quantified
q, r, … other propositional variables (in [a-z][a-z A-Z 0-9]*)
+

The quantifiers are always with respect to the variable p.

+

+ Disclaimer: + This page is only for the purpose of easy demonstration of the formally verified implementation in Coq (more information on this implementation can be found by clicking the links above). The + parsing library and the OCaml to JS compiler that were used + for building this page are not verified formally. + The functions have not yet been optimized; high run-time may occur even on small examples. +

+ + + +
+
+ + + diff --git a/index.html b/index.html new file mode 100644 index 0000000..3a32d47 --- /dev/null +++ b/index.html @@ -0,0 +1,10 @@ + + + + Index Page + + + + + + diff --git a/indexpage.html b/indexpage.html new file mode 100644 index 0000000..583179e --- /dev/null +++ b/indexpage.html @@ -0,0 +1,6674 @@ + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Global IndexABCDEFGHIJKLMNOPQRSTUVWXYZ_other(2915 entries)
Notation IndexABCDEFGHIJKLMNOPQRSTUVWXYZ_other(42 entries)
Variable IndexABCDEFGHIJKLMNOPQRSTUVWXYZ_other(114 entries)
Library IndexABCDEFGHIJKLMNOPQRSTUVWXYZ_other(97 entries)
Lemma IndexABCDEFGHIJKLMNOPQRSTUVWXYZ_other(1372 entries)
Constructor IndexABCDEFGHIJKLMNOPQRSTUVWXYZ_other(190 entries)
Inductive IndexABCDEFGHIJKLMNOPQRSTUVWXYZ_other(102 entries)
Section IndexABCDEFGHIJKLMNOPQRSTUVWXYZ_other(66 entries)
Instance IndexABCDEFGHIJKLMNOPQRSTUVWXYZ_other(25 entries)
Definition IndexABCDEFGHIJKLMNOPQRSTUVWXYZ_other(907 entries)
+
+

Global Index

+

A

+A [definition, in ISL.PropQuantifiers]
+AccT [inductive, in General.genT]
+AccT_in_nextup_fc [lemma, in General.dd_fc]
+AccT_measure [definition, in General.gentree]
+AccT_measure' [lemma, in General.gentree]
+AccT_sind [definition, in General.genT]
+AccT_rec [definition, in General.genT]
+AccT_ind [definition, in General.genT]
+AccT_rect [definition, in General.genT]
+AccT_intro [constructor, in General.genT]
+Acc_invprem [lemma, in GL.Interpolation.UIGL_Canopy]
+Acc_less_imp [lemma, in GL.Interpolation.UIGL_Canopy]
+Acc_invprem [lemma, in K.Interpolation.UIK_Canopy]
+Acc_less_imp [lemma, in K.Interpolation.UIK_Canopy]
+additive_cut [lemma, in ISL.Cut]
+add_remove_list_preserve_NoDup [lemma, in Syntax.remove_list_lems]
+add_1_element_split_lists [lemma, in Syntax.list_lems]
+aderI [constructor, in General.ddT]
+aderrec [inductive, in General.ddT]
+aderrec_sind [definition, in General.ddT]
+aderrec_ind [definition, in General.ddT]
+adm [inductive, in General.ddT]
+admD [definition, in General.ddT]
+admDs [definition, in General.ddT]
+admI [constructor, in General.ddT]
+adm_single_trans [lemma, in General.ddT]
+adm_derrec_trans [lemma, in General.ddT]
+adm_adm [lemma, in General.ddT]
+adm_sind [definition, in General.ddT]
+adm_rec [definition, in General.ddT]
+adm_ind [definition, in General.ddT]
+adm_rect [definition, in General.ddT]
+adpI [constructor, in General.ddT]
+Af [definition, in ISL.PropQuantifiers]
+allPder [inductive, in General.dd_fc]
+allPderD [lemma, in General.dd_fc]
+allPderD_in [lemma, in General.dd_fc]
+allPder_dlConsD [lemma, in General.dd_fc]
+allPder_sind [definition, in General.dd_fc]
+allPder_rec [definition, in General.dd_fc]
+allPder_ind [definition, in General.dd_fc]
+allPder_rect [definition, in General.dd_fc]
+allPder_Cons [constructor, in General.dd_fc]
+allPder_Nil [constructor, in General.dd_fc]
+allP_all_in_d [lemma, in General.dd_fc]
+all_P_univ_gen_ext_nil [lemma, in General.univ_gen_ext]
+all_in_d_allP [lemma, in General.dd_fc]
+all_derl_dersl' [lemma, in General.ddT]
+all_derl_dersl [lemma, in General.ddT]
+all_dercl_derscl [lemma, in General.ddT]
+all_RHS_boxes_are_LHS_boxes_no_GLR [lemma, in GL.GLS.GLS_termination_measure]
+And [definition, in Syntax.CML_Syntax]
+And [constructor, in ISL.Formulas]
+AndL [constructor, in ISL.Sequents]
+AndL [lemma, in K.Interpolation.UIK_UI_prelims]
+AndL [lemma, in GL.Interpolation.UIGL_And_Or_rules]
+AndL_inv [lemma, in GL.Interpolation.UIGL_And_Or_rules]
+AndL_rev [lemma, in ISL.SequentProps]
+AndR [constructor, in ISL.Sequents]
+AndR [lemma, in K.Interpolation.UIK_UI_prelims]
+AndR [lemma, in GL.Interpolation.UIGL_And_Or_rules]
+AndR_inv [lemma, in GL.Interpolation.UIGL_And_Or_rules]
+AndR_rev [lemma, in ISL.SequentProps]
+and_assoc_ctx_R_R [lemma, in ISL.Simp]
+and_assoc_ctx_R_L [lemma, in ISL.Simp]
+and_assoc_ctx_L_R [lemma, in ISL.Simp]
+and_assoc_L [lemma, in ISL.Simp]
+and_assoc_R [lemma, in ISL.Simp]
+and_comm_ctx_L [lemma, in ISL.Simp]
+and_comm [lemma, in ISL.Simp]
+and_true [lemma, in General.gen]
+and_congruence [lemma, in ISL.Optimizations]
+anon [definition, in General.genT]
+anonD [lemma, in General.genT]
+anonI [lemma, in General.genT]
+anon_forall [lemma, in General.genT]
+anon_sigT [lemma, in General.genT]
+anon_iffT [lemma, in General.genT]
+anon_imp [lemma, in General.genT]
+anon_sum [lemma, in General.genT]
+anon_prod [lemma, in General.genT]
+anon_eq [lemma, in General.genT]
+apfst [definition, in General.gen_seq]
+appI [lemma, in General.gen_tacs]
+appl [lemma, in General.gen]
+applI [lemma, in General.gen_tacs]
+appl_cong [lemma, in General.gen_tacs]
+apprI [lemma, in General.gen_tacs]
+appr_cong [lemma, in General.gen_tacs]
+app_remove_list [lemma, in Syntax.remove_list_lems]
+app_split_at_sind [definition, in General.List_lemmasT]
+app_split_at_rec [definition, in General.List_lemmasT]
+app_split_at_ind [definition, in General.List_lemmasT]
+app_split_at_rect [definition, in General.List_lemmasT]
+app_split_at [inductive, in General.List_lemmasT]
+app_eq_appT2_single_tlR [lemma, in General.List_lemmasT]
+app_eq_appT2_single_tlL [lemma, in General.List_lemmasT]
+app_eq_appT2_single_hdR [lemma, in General.List_lemmasT]
+app_eq_appT2_single_hdL [lemma, in General.List_lemmasT]
+app_eq_appT2_nn [lemma, in General.List_lemmasT]
+app_tl_inversion [lemma, in General.List_lemmasT]
+app_hd_inversion [lemma, in General.List_lemmasT]
+app_singleton_tl_inversion [lemma, in General.List_lemmasT]
+app_singleton_inversion [lemma, in General.List_lemmasT]
+app_eq_unitT2 [lemma, in General.List_lemmasT]
+app_eq_consT [definition, in General.List_lemmasT]
+app_eq_appT2 [lemma, in General.List_lemmasT]
+app_eq_appT [lemma, in General.List_lemmasT]
+app_eq_app [lemma, in General.List_lemmasT]
+app_eq_nilT [lemma, in General.List_lemmasT]
+app_eq_consT2 [definition, in General.List_lemmasT]
+app_eq_cons [definition, in General.List_lemmasT]
+app_cons_single [lemma, in General.List_lemmasT]
+app_eq_unitT [lemma, in General.gen_tacs]
+app_assoc_cons [definition, in General.gen_tacs]
+app_eq_nil_iff [lemma, in General.gen_tacs]
+app2_find_hole [lemma, in Syntax.list_lems]
+apsnd [definition, in General.gen_seq]
+arg_cong_imp' [lemma, in General.gen]
+arg_cong_imp [lemma, in General.gen]
+arg_cong [lemma, in General.gen]
+arg1_cong_imp' [lemma, in General.gen]
+arg1_cong_imp [lemma, in General.gen]
+Arithmetic [section, in K.Interpolation.UIK_basics]
+asa_eq [lemma, in General.List_lemmasT]
+asa_appR [constructor, in General.List_lemmasT]
+asa_appL [constructor, in General.List_lemmasT]
+asa_single [constructor, in General.List_lemmasT]
+asmI [constructor, in General.ddT]
+asmsI [lemma, in General.ddT]
+Atom [constructor, in ISL.Sequents]
+A_simplified [definition, in ISL.Simp]
+A_right [lemma, in ISL.PropQuantifiers]
+a_rule_env_spec [lemma, in ISL.PropQuantifiers]
+a_rule_form_vars [lemma, in ISL.PropQuantifiers]
+a_rule_env_vars [lemma, in ISL.PropQuantifiers]
+A_eq [definition, in ISL.PropQuantifiers]
+a_rule_form_cong_strong [lemma, in ISL.PropQuantifiers]
+a_rule_form_cong [lemma, in ISL.PropQuantifiers]
+a_rule_env_cong_strong [lemma, in ISL.PropQuantifiers]
+a_rule_env_cong [lemma, in ISL.PropQuantifiers]
+a_rule_form [definition, in ISL.PropQuantifiers]
+a_rule_env [definition, in ISL.PropQuantifiers]
+

B

+Bot [constructor, in Syntax.CML_Syntax]
+Bot [constructor, in ISL.Formulas]
+BotL [constructor, in GL.GLS.GLS_calcs]
+BotL [constructor, in K.KS.KS_calc]
+BotLRule [inductive, in GL.GLS.GLS_calcs]
+BotLRule [inductive, in K.KS.KS_calc]
+BotLRule_sind [definition, in GL.GLS.GLS_calcs]
+BotLRule_rec [definition, in GL.GLS.GLS_calcs]
+BotLRule_ind [definition, in GL.GLS.GLS_calcs]
+BotLRule_rect [definition, in GL.GLS.GLS_calcs]
+BotLRule_I [constructor, in GL.GLS.GLS_calcs]
+BotLRule_sind [definition, in K.KS.KS_calc]
+BotLRule_rec [definition, in K.KS.KS_calc]
+BotLRule_ind [definition, in K.KS.KS_calc]
+BotLRule_rect [definition, in K.KS.KS_calc]
+BotLRule_I [constructor, in K.KS.KS_calc]
+botRule_fc_prems [lemma, in General.dd_fc]
+botRule_fc_ps [lemma, in General.dd_fc]
+botRule_fc_drs [lemma, in General.dd_fc]
+botRule_fc_rules [lemma, in General.dd_fc]
+botRule_fc_concl [lemma, in General.dd_fc]
+botRule_fc_sind [definition, in General.dd_fc]
+botRule_fc_rec [definition, in General.dd_fc]
+botRule_fc_ind [definition, in General.dd_fc]
+botRule_fc_rect [definition, in General.dd_fc]
+botRule_fcI [constructor, in General.dd_fc]
+botRule_fc [inductive, in General.dd_fc]
+BotR_remove [lemma, in GL.Interpolation.UIGL_And_Or_rules]
+botr_ps_der [lemma, in General.dd_fc]
+bot_is_rule [definition, in General.dd_fc]
+Box [constructor, in Syntax.CML_Syntax]
+Box [constructor, in ISL.Formulas]
+BoxR [constructor, in ISL.Sequents]
+box_congr [lemma, in ISL.Simp]
+box_in_top_boxes [lemma, in Syntax.CML_Syntax]
+box_preserv_top_boxes [lemma, in GL.GLS.GLS_termination_measure]
+

C

+Canopy [definition, in GL.Interpolation.UIGL_Canopy]
+Canopy [definition, in K.Interpolation.UIK_Canopy]
+Canopy_nodupseq_perm [lemma, in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+Canopy_nodupseq_perm_gen [lemma, in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+Canopy_measure [lemma, in K.Interpolation.UIK_UI_prelims]
+Canopy_lems [section, in K.Interpolation.UIK_UI_prelims]
+Canopy_LtSeq [lemma, in K.Interpolation.UIK_basics]
+Canopy_nil [lemma, in K.Interpolation.UIK_basics]
+Canopy_pos_var [lemma, in GL.Interpolation.UIGL_Canopy]
+Canopy_neg_var [lemma, in GL.Interpolation.UIGL_Canopy]
+Canopy_hp_inv_ctx [lemma, in GL.Interpolation.UIGL_Canopy]
+Canopy_equiprv_genR [lemma, in GL.Interpolation.UIGL_Canopy]
+Canopy_equiprv_genL [lemma, in GL.Interpolation.UIGL_Canopy]
+Canopy_equiprv [lemma, in GL.Interpolation.UIGL_Canopy]
+Canopy_critical [lemma, in GL.Interpolation.UIGL_Canopy]
+Canopy_nodupseq_equiprv_genL [lemma, in GL.Interpolation.UIGL_UI_prelims]
+Canopy_nodupseq_equiprv_genR [lemma, in GL.Interpolation.UIGL_UI_prelims]
+Canopy_LexSeq [lemma, in GL.Interpolation.UIGL_LexSeq]
+Canopy_nil [lemma, in GL.Interpolation.UIGL_LexSeq]
+Canopy_pos_var [lemma, in K.Interpolation.UIK_Canopy]
+Canopy_neg_var [lemma, in K.Interpolation.UIK_Canopy]
+Canopy_hp_inv_ctx [lemma, in K.Interpolation.UIK_Canopy]
+Canopy_equiprv_genR [lemma, in K.Interpolation.UIK_Canopy]
+Canopy_equiprv_genL [lemma, in K.Interpolation.UIK_Canopy]
+Canopy_equiprv [lemma, in K.Interpolation.UIK_Canopy]
+Canopy_critical [lemma, in K.Interpolation.UIK_Canopy]
+can_exchR [definition, in General.gen_seq]
+can_exchL [definition, in General.gen_seq]
+can_wkL_req [lemma, in General.gen_seq]
+can_wkL [definition, in General.gen_seq]
+can_rel [definition, in General.gstep]
+can_trf_rules_rtc_mono [definition, in General.gstep]
+can_trf_rules_rtc_mono' [lemma, in General.gstep]
+can_trf_rules_imp_rtc [lemma, in General.gstep]
+can_trf_rules_rtc [definition, in General.gstep]
+can_trf_derl [lemma, in General.gstep]
+can_trf_rules_req [lemma, in General.gstep]
+can_trf_rules_Un [lemma, in General.gstep]
+can_trf_rules_un [lemma, in General.gstep]
+can_trf_rules_rc_mono [definition, in General.gstep]
+can_trf_rules_mono [definition, in General.gstep]
+can_trf_rules_rc_mono' [lemma, in General.gstep]
+can_trf_rules_mono' [lemma, in General.gstep]
+can_trf_rules_imp_rc [lemma, in General.gstep]
+can_trf_rules_rc [definition, in General.gstep]
+can_trf_rules [definition, in General.gstep]
+casmI [constructor, in General.ddT]
+ccps [inductive, in General.ddT]
+ccpsD [lemma, in General.ddT]
+ccpsI [constructor, in General.ddT]
+ccps_sind [definition, in General.ddT]
+ccps_rec [definition, in General.ddT]
+ccps_ind [definition, in General.ddT]
+ccps_rect [definition, in General.ddT]
+choose_disj [definition, in ISL.Environments]
+choose_conj [definition, in ISL.Environments]
+choose_disj_equiv_R [lemma, in ISL.Optimizations]
+choose_disj_equiv_L [lemma, in ISL.Optimizations]
+choose_conj_equiv_R [lemma, in ISL.Optimizations]
+choose_conj_equiv_L [lemma, in ISL.Optimizations]
+Closure [inductive, in GL.GLS.GLS_exch]
+Closure [inductive, in K.KS.KS_exch]
+Closure_sind [definition, in GL.GLS.GLS_exch]
+Closure_rec [definition, in GL.GLS.GLS_exch]
+Closure_ind [definition, in GL.GLS.GLS_exch]
+Closure_rect [definition, in GL.GLS.GLS_exch]
+Closure_sind [definition, in K.KS.KS_exch]
+Closure_rec [definition, in K.KS.KS_exch]
+Closure_ind [definition, in K.KS.KS_exch]
+Closure_rect [definition, in K.KS.KS_exch]
+clos_rt_rtn1T [lemma, in General.rtcT]
+clos_rtn1_rtT [lemma, in General.rtcT]
+clos_rt_rt1nT [lemma, in General.rtcT]
+clos_rt1n_rtT [lemma, in General.rtcT]
+clos_refl_transT_n1_sind [definition, in General.rtcT]
+clos_refl_transT_n1_rec [definition, in General.rtcT]
+clos_refl_transT_n1_ind [definition, in General.rtcT]
+clos_refl_transT_n1_rect [definition, in General.rtcT]
+clos_refl_transT_n1 [inductive, in General.rtcT]
+clos_refl_transT_1n_sind [definition, in General.rtcT]
+clos_refl_transT_1n_rec [definition, in General.rtcT]
+clos_refl_transT_1n_ind [definition, in General.rtcT]
+clos_refl_transT_1n_rect [definition, in General.rtcT]
+clos_refl_transT_1n [inductive, in General.rtcT]
+clos_refl_transT_sind [definition, in General.rtcT]
+clos_refl_transT_rec [definition, in General.rtcT]
+clos_refl_transT_ind [definition, in General.rtcT]
+clos_refl_transT_rect [definition, in General.rtcT]
+clos_refl_transT [inductive, in General.rtcT]
+clos_reflT_sind [definition, in General.rtcT]
+clos_reflT_rec [definition, in General.rtcT]
+clos_reflT_ind [definition, in General.rtcT]
+clos_reflT_rect [definition, in General.rtcT]
+clos_reflT [inductive, in General.rtcT]
+CML_Syntax [library]
+conjunction [definition, in ISL.Environments]
+conjunction_L [lemma, in ISL.Optimizations]
+conjunction_R2 [lemma, in ISL.Optimizations]
+conjunction_R1 [lemma, in ISL.Optimizations]
+cons_singleton [lemma, in General.List_lemmasT]
+cons_eq_appT2 [lemma, in General.List_lemmasT]
+cons_eq_appT [lemma, in General.List_lemmasT]
+cons_eq_app [lemma, in General.List_lemmasT]
+cons_single [lemma, in General.List_lemmasT]
+cons_app_single [lemma, in General.swappedT]
+contraction [lemma, in ISL.SequentProps]
+contradic_subform_boxesF [lemma, in GL.GLS.GLS_termination_measure]
+CountablyManyFormulas [section, in ISL.Formulas]
+count_occ_n_imp_subformLF [lemma, in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+count_le_n_imp [lemma, in GL.Interpolation.UIGL_Canopy_ImpR]
+count_occ_n_imp_subformLF [lemma, in GL.Interpolation.UIGL_Canopy_ImpR]
+Craig_Interpolation [lemma, in K.Interpolation.K_Craig_Interp]
+crd_ra [lemma, in General.gstep]
+critical_empty_set [lemma, in K.Interpolation.UIK_basics]
+critical_nodupseq [lemma, in GL.Interpolation.UIGL_nodupseq]
+critical_Seq_InT_Canopy [lemma, in GL.Interpolation.UIGL_Canopy]
+critical_Seq_dec [definition, in GL.Interpolation.UIGL_Canopy]
+critical_Seq [definition, in GL.Interpolation.UIGL_Canopy]
+critical_empty_seq [lemma, in GL.Interpolation.UIGL_LexSeq]
+critical_Seq_InT_Canopy [lemma, in K.Interpolation.UIK_Canopy]
+critical_Seq_dec [definition, in K.Interpolation.UIK_Canopy]
+critical_Seq [definition, in K.Interpolation.UIK_Canopy]
+ctr_R_sind [definition, in K.KS.KS_ctr]
+ctr_R_rec [definition, in K.KS.KS_ctr]
+ctr_R_ind [definition, in K.KS.KS_ctr]
+ctr_R_rect [definition, in K.KS.KS_ctr]
+ctr_RI [constructor, in K.KS.KS_ctr]
+ctr_R [inductive, in K.KS.KS_ctr]
+ctr_L_sind [definition, in K.KS.KS_ctr]
+ctr_L_rec [definition, in K.KS.KS_ctr]
+ctr_L_ind [definition, in K.KS.KS_ctr]
+ctr_L_rect [definition, in K.KS.KS_ctr]
+ctr_LI [constructor, in K.KS.KS_ctr]
+ctr_L [inductive, in K.KS.KS_ctr]
+ctr_R_BotL_notapplic [lemma, in GL.GLS.GLS_ctr]
+ctr_R_IdB_notapplic [lemma, in GL.GLS.GLS_ctr]
+ctr_R_IdP_notapplic [lemma, in GL.GLS.GLS_ctr]
+ctr_L_BotL_notapplic [lemma, in GL.GLS.GLS_ctr]
+ctr_L_IdB_notapplic [lemma, in GL.GLS.GLS_ctr]
+ctr_L_IdP_notapplic [lemma, in GL.GLS.GLS_ctr]
+ctr_R_sind [definition, in GL.GLS.GLS_ctr]
+ctr_R_rec [definition, in GL.GLS.GLS_ctr]
+ctr_R_ind [definition, in GL.GLS.GLS_ctr]
+ctr_R_rect [definition, in GL.GLS.GLS_ctr]
+ctr_RI [constructor, in GL.GLS.GLS_ctr]
+ctr_R [inductive, in GL.GLS.GLS_ctr]
+ctr_L_sind [definition, in GL.GLS.GLS_ctr]
+ctr_L_rec [definition, in GL.GLS.GLS_ctr]
+ctr_L_ind [definition, in GL.GLS.GLS_ctr]
+ctr_L_rect [definition, in GL.GLS.GLS_ctr]
+ctr_LI [constructor, in GL.GLS.GLS_ctr]
+ctr_L [inductive, in GL.GLS.GLS_ctr]
+cut [lemma, in ISL.Cut]
+Cut [library]
+CutRule [inductive, in GL.GLS.GLS_cut_elim]
+CutRule [inductive, in K.KS.KS_cut_elim]
+CutRule_sind [definition, in GL.GLS.GLS_cut_elim]
+CutRule_rec [definition, in GL.GLS.GLS_cut_elim]
+CutRule_ind [definition, in GL.GLS.GLS_cut_elim]
+CutRule_rect [definition, in GL.GLS.GLS_cut_elim]
+CutRule_I [constructor, in GL.GLS.GLS_cut_elim]
+CutRule_sind [definition, in K.KS.KS_cut_elim]
+CutRule_rec [definition, in K.KS.KS_cut_elim]
+CutRule_ind [definition, in K.KS.KS_cut_elim]
+CutRule_rect [definition, in K.KS.KS_cut_elim]
+CutRule_I [constructor, in K.KS.KS_cut_elim]
+

D

+dcl_allT [definition, in General.ddT]
+dcsl_allT [definition, in General.ddT]
+ddT [library]
+dd_fc [library]
+decidable_is_negation [instance, in ISL.Environments]
+decidable_is_implication [instance, in ISL.Environments]
+decidable_is_double_negation [instance, in ISL.Environments]
+decide_in [lemma, in ISL.Environments]
+DecisionProcedure [library]
+decT_less_than_lt [lemma, in GL.GLS.GLS_termination_measure]
+decT_lex_lt [lemma, in GL.GLS.GLS_termination_measure]
+decT_lt [lemma, in GL.GLS.GLS_termination_measure]
+dec_non_nil_prems [lemma, in K.KS.KS_termination]
+dec_le [lemma, in K.KS.KS_termination_prelims]
+dec_GLS_rules [definition, in GL.GLS.GLS_dec]
+dec_GLR_rule [definition, in GL.GLS.GLS_dec]
+dec_box_in_list [definition, in GL.GLS.GLS_dec]
+dec_ImpL_rule [definition, in GL.GLS.GLS_dec]
+dec_ImpR_rule [definition, in GL.GLS.GLS_dec]
+dec_imp_in [definition, in GL.GLS.GLS_dec]
+dec_is_imp [definition, in GL.GLS.GLS_dec]
+dec_init_rules [definition, in GL.GLS.GLS_dec]
+dec_BotL_rule [definition, in GL.GLS.GLS_dec]
+dec_IdB_rule [definition, in GL.GLS.GLS_dec]
+dec_IdP_rule [definition, in GL.GLS.GLS_dec]
+dec_GLS_init_rules [definition, in GL.GLS.GLS_dec]
+dec_box_in [definition, in GL.GLS.GLS_dec]
+dec_is_box [definition, in GL.GLS.GLS_dec]
+dec_is_boxedT [definition, in GL.GLS.GLS_dec]
+dec_prop_var_in [definition, in GL.GLS.GLS_dec]
+dec_KS_rules [definition, in K.KS.KS_dec]
+dec_KR_rule [definition, in K.KS.KS_dec]
+dec_box_in_list [definition, in K.KS.KS_dec]
+dec_ImpL_rule [definition, in K.KS.KS_dec]
+dec_ImpR_rule [definition, in K.KS.KS_dec]
+dec_imp_in [definition, in K.KS.KS_dec]
+dec_is_imp [definition, in K.KS.KS_dec]
+dec_BotL_rule [definition, in K.KS.KS_dec]
+dec_IdP_rule [definition, in K.KS.KS_dec]
+dec_KS_init_rules [definition, in K.KS.KS_dec]
+dec_box_in [definition, in K.KS.KS_dec]
+dec_is_box [definition, in K.KS.KS_dec]
+dec_is_boxedT [definition, in K.KS.KS_dec]
+dec_prop_var_in [definition, in K.KS.KS_dec]
+dec_is_PropVar [definition, in K.KS.KS_dec]
+dercl [inductive, in General.ddT]
+dercl_soundness [lemma, in General.gstep]
+dercl_derl [definition, in General.ddT]
+dercl_derl' [lemma, in General.ddT]
+dercl_all_rect [lemma, in General.ddT]
+dercl_dercsl_rect_mut [definition, in General.ddT]
+dercl_rect_mut [definition, in General.ddT]
+dercl_rec_mut [definition, in General.ddT]
+dercl_ind_mut [definition, in General.ddT]
+dercl_sind [definition, in General.ddT]
+dercl_rec [definition, in General.ddT]
+dercl_ind [definition, in General.ddT]
+dercl_rect [definition, in General.ddT]
+dercsl [inductive, in General.ddT]
+dercsl_dersl [definition, in General.ddT]
+dercsl_rect_mut [definition, in General.ddT]
+dercsl_rec_mut [definition, in General.ddT]
+dercsl_ind_mut [definition, in General.ddT]
+dercsl_sind [definition, in General.ddT]
+dercsl_rec [definition, in General.ddT]
+dercsl_ind [definition, in General.ddT]
+dercsl_rect [definition, in General.ddT]
+derI [constructor, in General.ddT]
+derI_rules_mono [definition, in General.ddT]
+derl [inductive, in General.ddT]
+derl_fst_ext_rls [lemma, in General.gen_seq]
+derl_fst_ext_rls' [definition, in General.gen_seq]
+derl_fst_ext_rls'' [lemma, in General.gen_seq]
+derl_seqrule [lemma, in General.gen_seq]
+derl_seqrule' [definition, in General.gen_seq]
+derl_seqrule'' [lemma, in General.gen_seq]
+derl_height [definition, in General.dd_fc]
+derl_adm [definition, in General.ddT]
+derl_adm_s [lemma, in General.ddT]
+derl_sub_adm [lemma, in General.ddT]
+derl_mono [definition, in General.ddT]
+derl_mono' [definition, in General.ddT]
+derl_dersl_mono' [lemma, in General.ddT]
+derl_deriv [definition, in General.ddT]
+derl_deriv' [definition, in General.ddT]
+derl_dersl_deriv' [lemma, in General.ddT]
+derl_trans [definition, in General.ddT]
+derl_trans' [lemma, in General.ddT]
+derl_derrec_nil [definition, in General.ddT]
+derl_derrec [definition, in General.ddT]
+derl_derrec_trans [definition, in General.ddT]
+derl_derrec_trans' [lemma, in General.ddT]
+derl_all_rect [lemma, in General.ddT]
+derl_dercl [lemma, in General.ddT]
+derl_dersl_rect_mut [definition, in General.ddT]
+derl_dersl_single [lemma, in General.ddT]
+derl_rect_mut [definition, in General.ddT]
+derl_rec_mut [definition, in General.ddT]
+derl_ind_mut [definition, in General.ddT]
+derl_sind [definition, in General.ddT]
+derl_rec [definition, in General.ddT]
+derl_ind [definition, in General.ddT]
+derl_rect [definition, in General.ddT]
+derrec [inductive, in General.ddT]
+derrec_leaves_thms [lemma, in GL.GLS.GLS_der_dec]
+derrec_composition [lemma, in GL.GLS.GLS_der_dec]
+derrec_soundness [lemma, in General.gstep]
+derrec_dp_same2 [lemma, in General.dd_fc]
+derrec_dp_same [lemma, in General.dd_fc]
+derrec_fc_height [definition, in General.dd_fc]
+derrec_fc_size [definition, in General.dd_fc]
+derrec_fc_concl [definition, in General.dd_fc]
+derrec_fc_sind [definition, in General.dd_fc]
+derrec_fc_rec [definition, in General.dd_fc]
+derrec_fc_ind [definition, in General.dd_fc]
+derrec_fc_rect [definition, in General.dd_fc]
+derrec_fc [inductive, in General.dd_fc]
+derrec_concl [definition, in General.dd_fc]
+derrec_size [definition, in General.dd_fc]
+derrec_height [definition, in General.dd_fc]
+derrec_rect_mut_all [definition, in General.dd_fc]
+derrec_eq_swap [lemma, in General.ddT]
+derrec_adm [definition, in General.ddT]
+derrec_adm' [lemma, in General.ddT]
+derrec_all_rect2_nops [definition, in General.ddT]
+derrec_all_rect2 [lemma, in General.ddT]
+derrec_nil_derl [definition, in General.ddT]
+derrec_nil_derl_s [lemma, in General.ddT]
+derrec_derl_deriv [definition, in General.ddT]
+derrec_derl_deriv' [lemma, in General.ddT]
+derrec_rmono [definition, in General.ddT]
+derrec_rmono_s [lemma, in General.ddT]
+derrec_trans_imp [lemma, in General.ddT]
+derrec_same_nsR [lemma, in General.ddT]
+derrec_same_nsL [lemma, in General.ddT]
+derrec_same [lemma, in General.ddT]
+derrec_derrec [definition, in General.ddT]
+derrec_derrec' [lemma, in General.ddT]
+derrec_all_rect [lemma, in General.ddT]
+derrec_all_indT [lemma, in General.ddT]
+derrec_all_ind [lemma, in General.ddT]
+derrec_dersrec_rect_mut [definition, in General.ddT]
+derrec_ind_mut [definition, in General.ddT]
+derrec_rec_mut [definition, in General.ddT]
+derrec_rect_mut [definition, in General.ddT]
+derrec_sind [definition, in General.ddT]
+derrec_rec [definition, in General.ddT]
+derrec_ind [definition, in General.ddT]
+derrec_rect [definition, in General.ddT]
+derrec_height_False_ge_1 [lemma, in GL.GLS.GLS_inv_ImpR_ImpL]
+derrec_height_False_ge_1 [lemma, in K.KS.KS_inv_ImpR_ImpL]
+derscl_all_dercl [lemma, in General.ddT]
+dersl [inductive, in General.ddT]
+dersl_fst_ext_rls' [definition, in General.gen_seq]
+dersl_seqrule' [definition, in General.gen_seq]
+dersl_height [definition, in General.dd_fc]
+dersl_adm [definition, in General.ddT]
+dersl_mono [definition, in General.ddT]
+dersl_mono' [definition, in General.ddT]
+dersl_deriv [definition, in General.ddT]
+dersl_deriv' [definition, in General.ddT]
+dersl_trans_alt [lemma, in General.ddT]
+dersl_trans [definition, in General.ddT]
+dersl_app_eq [lemma, in General.ddT]
+dersl_cons [lemma, in General.ddT]
+dersl_dersrec_nil [lemma, in General.ddT]
+dersl_dersrec_trans [definition, in General.ddT]
+dersl_all_derl' [lemma, in General.ddT]
+dersl_all_derl [lemma, in General.ddT]
+dersl_rect_mut [definition, in General.ddT]
+dersl_rec_mut [definition, in General.ddT]
+dersl_ind_mut [definition, in General.ddT]
+dersl_sind [definition, in General.ddT]
+dersl_rec [definition, in General.ddT]
+dersl_ind [definition, in General.ddT]
+dersl_rect [definition, in General.ddT]
+dersrec [inductive, in General.ddT]
+dersrecD_forall_in_dersrec [lemma, in General.dd_fc]
+dersrecD_forall [definition, in General.ddT]
+dersrecD_all [definition, in General.ddT]
+dersrecI_forall [definition, in General.ddT]
+dersrecI_all [definition, in General.ddT]
+dersrec_derrec_height_le [lemma, in General.dd_fc]
+dersrec_derrec2_dp [lemma, in General.dd_fc]
+dersrec_derrec_dp [lemma, in General.dd_fc]
+dersrec_derrec2_height [lemma, in General.dd_fc]
+dersrec_derrec_height [lemma, in General.dd_fc]
+dersrec_double_verb [lemma, in General.dd_fc]
+dersrec_trees_concls_eq [lemma, in General.dd_fc]
+dersrec_fc_height [definition, in General.dd_fc]
+dersrec_fc_size [definition, in General.dd_fc]
+dersrec_fc_concls [definition, in General.dd_fc]
+dersrec_trees [definition, in General.dd_fc]
+dersrec_fcs_sind [definition, in General.dd_fc]
+dersrec_fcs_rec [definition, in General.dd_fc]
+dersrec_fcs_ind [definition, in General.dd_fc]
+dersrec_fcs_rect [definition, in General.dd_fc]
+dersrec_fcs [inductive, in General.dd_fc]
+dersrec_height_le [lemma, in General.dd_fc]
+dersrec_height_nil [lemma, in General.dd_fc]
+dersrec_tl_eq [lemma, in General.dd_fc]
+dersrec_hd_eq [lemma, in General.dd_fc]
+dersrec_single' [definition, in General.dd_fc]
+dersrec_singleI' [definition, in General.dd_fc]
+dersrec_singleD' [definition, in General.dd_fc]
+dersrec_tl [definition, in General.dd_fc]
+dersrec_hd [definition, in General.dd_fc]
+dersrec_concls [definition, in General.dd_fc]
+dersrec_size [definition, in General.dd_fc]
+dersrec_height [definition, in General.dd_fc]
+dersrec_doubleD [definition, in General.ddT]
+dersrec_double [lemma, in General.ddT]
+dersrec_adm [definition, in General.ddT]
+dersrec_nil_dersl [definition, in General.ddT]
+dersrec_derl_deriv [definition, in General.ddT]
+dersrec_rmono [definition, in General.ddT]
+dersrec_map_2 [lemma, in General.ddT]
+dersrec_map_single [lemma, in General.ddT]
+dersrec_singleI [definition, in General.ddT]
+dersrec_singleD [definition, in General.ddT]
+dersrec_single [lemma, in General.ddT]
+dersrec_appI [definition, in General.ddT]
+dersrec_appJ [definition, in General.ddT]
+dersrec_appR [definition, in General.ddT]
+dersrec_appL [definition, in General.ddT]
+dersrec_appD [definition, in General.ddT]
+dersrec_app [lemma, in General.ddT]
+dersrec_nil [lemma, in General.ddT]
+dersrec_forall [lemma, in General.ddT]
+dersrec_all [lemma, in General.ddT]
+dersrec_derrec [definition, in General.ddT]
+dersrec_ind_mut [definition, in General.ddT]
+dersrec_rec_mut [definition, in General.ddT]
+dersrec_rect_mut [definition, in General.ddT]
+dersrec_sind [definition, in General.ddT]
+dersrec_rec [definition, in General.ddT]
+dersrec_ind [definition, in General.ddT]
+dersrec_rect [definition, in General.ddT]
+ders_ders_fcs [lemma, in General.dd_fc]
+ders_concls_eq [lemma, in General.dd_fc]
+der_s_inhabited [lemma, in GL.GLS.GLS_der_dec]
+der_s_inhabited [lemma, in K.KS.KS_termination_prelims]
+der_trf_ht [lemma, in General.gstep]
+der_trf_rtc [lemma, in General.gstep]
+der_trf [lemma, in General.gstep]
+der_trf_derl' [definition, in General.gstep]
+der_trf_derl [lemma, in General.gstep]
+der_trf_rc [lemma, in General.gstep]
+der_trf_rc_derl [lemma, in General.gstep]
+der_trf_rc_adm [lemma, in General.gstep]
+der_botRule [lemma, in General.dd_fc]
+der_der_fc [lemma, in General.dd_fc]
+der_botr_ps_eq [lemma, in General.dd_fc]
+der_fc_concl_eq [lemma, in General.dd_fc]
+der_concl_eq [lemma, in General.dd_fc]
+der_botr_ps [definition, in General.dd_fc]
+Diam [definition, in Syntax.CML_Syntax]
+DiamL_lim [lemma, in K.Interpolation.UIK_UI_prelims]
+DiamL_lim [lemma, in GL.Interpolation.UIGL_UI_prelims]
+Diam_help [section, in K.Interpolation.UIK_UI_prelims]
+Diam_rec_UI_imp [lemma, in GL.Interpolation.UIGL_Diam_N_imp_UI]
+Diam_help [section, in GL.Interpolation.UIGL_UI_prelims]
+Diam_rec_UI [lemma, in GL.Interpolation.UIGL_UIDiam_N]
+difference_include [lemma, in ISL.Environments]
+difference_singleton [lemma, in ISL.Environments]
+diff_not_in [lemma, in ISL.Environments]
+diff_mult [lemma, in ISL.Environments]
+dim_all8 [definition, in General.ddT]
+dim_all4 [definition, in General.ddT]
+dim_all3 [definition, in General.ddT]
+dim_allT [definition, in General.ddT]
+dim_all [definition, in General.ddT]
+disjunction [definition, in ISL.Environments]
+disjunction_R [lemma, in ISL.Optimizations]
+disjunction_L [lemma, in ISL.Optimizations]
+dlCons [constructor, in General.ddT]
+dlCons_inj [lemma, in General.gstep]
+dlNil [constructor, in General.ddT]
+DLW_wf_lex [library]
+double_remove [lemma, in Syntax.remove_list_lems]
+double_negation_obviously_smaller [lemma, in ISL.Optimizations]
+dp [definition, in General.dd_fc]
+dpI [constructor, in General.ddT]
+dp_get_D [lemma, in General.dd_fc]
+dp_same_fun [lemma, in General.dd_fc]
+dp_same [lemma, in General.dd_fc]
+drl_allT' [definition, in General.ddT]
+drl_allT [definition, in General.ddT]
+drsl_allT' [definition, in General.ddT]
+drsl_allT [definition, in General.ddT]
+drs_trees_height [lemma, in General.dd_fc]
+dtcCons [constructor, in General.ddT]
+dtcderI [constructor, in General.ddT]
+dtcNil [constructor, in General.ddT]
+dtCons [constructor, in General.ddT]
+dtCons_eq [lemma, in General.ddT]
+dtderI [constructor, in General.ddT]
+dtNil [constructor, in General.ddT]
+dt2fun [definition, in General.gentree]
+

E

+E [definition, in ISL.PropQuantifiers]
+EA [definition, in ISL.PropQuantifiers]
+EA_vars [lemma, in ISL.PropQuantifiers]
+EA_eq [lemma, in ISL.PropQuantifiers]
+Ef [definition, in ISL.PropQuantifiers]
+effective_remove_nth [lemma, in GL.GLS.GLS_der_dec]
+effective_remove_nth [lemma, in K.KS.KS_termination_prelims]
+elements_elem_of [lemma, in ISL.Order]
+elements_open_boxes [lemma, in ISL.Environments]
+elements_env_add [lemma, in ISL.Environments]
+elem_of_list_In_1 [lemma, in ISL.Order]
+elem_of_open_boxes [lemma, in ISL.Environments]
+empty [inductive, in General.genT]
+empty [definition, in ISL.Environments]
+emptyT [inductive, in General.genT]
+emptyT_any [lemma, in General.genT]
+emptyT_any' [lemma, in General.genT]
+emptyT_sind [definition, in General.genT]
+emptyT_rec [definition, in General.genT]
+emptyT_ind [definition, in General.genT]
+emptyT_rect [definition, in General.genT]
+empty_seq_dec [definition, in K.Interpolation.UIK_basics]
+empty_seq [section, in K.Interpolation.UIK_basics]
+empty_seq_dec [definition, in GL.Interpolation.UIGL_LexSeq]
+empty_seq [section, in GL.Interpolation.UIGL_LexSeq]
+empty_False [lemma, in General.genT]
+empty_explosion [lemma, in General.genT]
+empty_sind [definition, in General.genT]
+empty_rec [definition, in General.genT]
+empty_ind [definition, in General.genT]
+empty_rect [definition, in General.genT]
+empty_relT_sind [definition, in General.genT]
+empty_relT_rec [definition, in General.genT]
+empty_relT_ind [definition, in General.genT]
+empty_relT_rect [definition, in General.genT]
+empty_relT [inductive, in General.genT]
+entail_correct [lemma, in ISL.PropQuantifiers]
+env [definition, in ISL.Environments]
+Environments [library]
+env_order_le_lt_trans [lemma, in ISL.Order]
+env_order_lt_le_trans [lemma, in ISL.Order]
+env_order_eq_add [lemma, in ISL.Order]
+env_order_cancel_right [lemma, in ISL.Order]
+env_order_4 [lemma, in ISL.Order]
+env_order_3 [lemma, in ISL.Order]
+env_order_2 [lemma, in ISL.Order]
+env_order_0 [lemma, in ISL.Order]
+env_order_disj_union_compat_strong_left [lemma, in ISL.Order]
+env_order_disj_union_compat_strong_right [lemma, in ISL.Order]
+env_order_refl_disj_union_compat [lemma, in ISL.Order]
+env_order_disj_union_compat [lemma, in ISL.Order]
+env_order_disj_union_compat_right [lemma, in ISL.Order]
+env_order_disj_union_compat_left [lemma, in ISL.Order]
+env_order_add_compat [lemma, in ISL.Order]
+env_order_compat' [lemma, in ISL.Order]
+env_order_compat [lemma, in ISL.Order]
+env_order_1 [lemma, in ISL.Order]
+env_order_equiv_left_compat [lemma, in ISL.Order]
+env_order_equiv_right_compat [lemma, in ISL.Order]
+env_order_trans [instance, in ISL.Order]
+env_order_refl [definition, in ISL.Order]
+env_order_singleton [lemma, in ISL.Order]
+env_weight_singleton [lemma, in ISL.Order]
+env_order [definition, in ISL.Order]
+env_weight_add [lemma, in ISL.Order]
+env_weight_disj_union [lemma, in ISL.Order]
+env_weight [definition, in ISL.Order]
+env_equiv_eq [lemma, in ISL.Environments]
+env_add_inv' [lemma, in ISL.Environments]
+env_add_inv [lemma, in ISL.Environments]
+env_add_comm [lemma, in ISL.Environments]
+env_in_add [lemma, in ISL.Environments]
+env_add_remove [lemma, in ISL.Environments]
+env_replace [lemma, in ISL.Environments]
+equiv_assoc [instance, in ISL.Environments]
+equiv_disj_union_compat_r [lemma, in ISL.Environments]
+eq_dec_form [lemma, in Syntax.CML_Syntax]
+eq_TrueI [lemma, in General.gen]
+eq_nnn_app [definition, in General.List_lemmasT]
+eq_app_canc2 [lemma, in General.List_lemmasT]
+eq_app_canc1 [lemma, in General.List_lemmasT]
+eq_dec_seqs [definition, in Syntax.list_lems]
+eq_dec_listsF [definition, in Syntax.list_lems]
+eq_S_F [lemma, in General.genT]
+ExcClosure [inductive, in GL.GLS.GLS_exch]
+ExcClosure [inductive, in K.KS.KS_exch]
+ExcClosure_sind [definition, in GL.GLS.GLS_exch]
+ExcClosure_rec [definition, in GL.GLS.GLS_exch]
+ExcClosure_ind [definition, in GL.GLS.GLS_exch]
+ExcClosure_rect [definition, in GL.GLS.GLS_exch]
+ExcClosure_sind [definition, in K.KS.KS_exch]
+ExcClosure_rec [definition, in K.KS.KS_exch]
+ExcClosure_ind [definition, in K.KS.KS_exch]
+ExcClosure_rect [definition, in K.KS.KS_exch]
+exchL_std_rule [lemma, in General.gen_seq]
+exchR_std_rule [lemma, in General.gen_seq]
+ExFalso [constructor, in ISL.Sequents]
+exfalso [lemma, in ISL.SequentProps]
+existsT [library]
+exists_prems_InT_list_of_premises [lemma, in K.KS.KS_termination]
+exists_prems_InT_list_of_premises [lemma, in GL.GLS.GLS_der_dec]
+exists_dec [definition, in ISL.DecisionProcedure]
+existT_inj' [lemma, in General.gstep]
+existT_inj [lemma, in General.gstep]
+ex1 [definition, in ISL.Simp]
+ex2 [definition, in ISL.Simp]
+ex3 [definition, in ISL.Simp]
+ex4 [definition, in ISL.Simp]
+ex5 [definition, in ISL.Simp]
+ex6 [definition, in ISL.Simp]
+E_simplified [definition, in ISL.Simp]
+E_of_empty [lemma, in ISL.PropQuantifiers]
+E_left [lemma, in ISL.PropQuantifiers]
+E_irr [lemma, in ISL.PropQuantifiers]
+e_rule_vars [lemma, in ISL.PropQuantifiers]
+E_eq [definition, in ISL.PropQuantifiers]
+e_rule_cong_strong [lemma, in ISL.PropQuantifiers]
+e_rule_cong [lemma, in ISL.PropQuantifiers]
+e_rule [definition, in ISL.PropQuantifiers]
+

F

+false_or [lemma, in General.gen]
+False_empty [lemma, in General.genT]
+fce3 [definition, in General.ddT]
+fcI [constructor, in General.dd_fc]
+fcI_inj [lemma, in General.dd_fc]
+fcsI [constructor, in General.dd_fc]
+fer_mono [lemma, in General.gen_seq]
+fextI [constructor, in General.gen_seq]
+fextI_eqc' [definition, in General.gen_seq]
+fextI_eq' [lemma, in General.gen_seq]
+fextI' [definition, in General.gen_seq]
+fext_e [lemma, in General.gen_seq]
+find_the_max_mhd [lemma, in K.KS.KS_termination]
+finite_premises_of_S [lemma, in K.KS.KS_termination]
+finite_premises_of_S [definition, in GL.GLS.GLS_der_dec]
+finite_BotL_premises_of_S [definition, in GL.GLS.GLS_der_dec]
+finite_IdB_premises_of_S [definition, in GL.GLS.GLS_der_dec]
+finite_IdP_premises_of_S [definition, in GL.GLS.GLS_der_dec]
+finite_GLR_premises_of_S [definition, in GL.GLS.GLS_der_dec]
+finite_ImpL_premises_of_S [definition, in GL.GLS.GLS_der_dec]
+finite_ImpR_premises_of_S [definition, in GL.GLS.GLS_der_dec]
+finite_KR_premises_of_S [definition, in K.KS.KS_termination_KR]
+finite_ImpL_premises_of_S [definition, in K.KS.KS_termination_ImpL]
+finite_ImpRules_premises_of_S [lemma, in GL.Interpolation.UIGL_Canopy]
+finite_ImpR_premises_of_S [definition, in K.KS.KS_termination_ImpR]
+finite_BotL_premises_of_S [lemma, in K.KS.KS_termination_init]
+finite_IdP_premises_of_S [lemma, in K.KS.KS_termination_init]
+finite_ImpRules_premises_of_S [lemma, in K.Interpolation.UIK_Canopy]
+fixpoint_nodup [lemma, in GL.Interpolation.UIGL_nodupseq]
+fixpoint_nodupseq [lemma, in GL.Interpolation.UIGL_nodupseq]
+flatmap [definition, in K.Interpolation.UIK_irred_short]
+flatmap [section, in K.Interpolation.UIK_irred_short]
+flatmap [definition, in GL.Interpolation.UIGL_irred_short]
+flatmap [section, in GL.Interpolation.UIGL_irred_short]
+flatmap.D [variable, in K.Interpolation.UIK_irred_short]
+flatmap.D [variable, in GL.Interpolation.UIGL_irred_short]
+flatmap.f [variable, in K.Interpolation.UIK_irred_short]
+flatmap.F [variable, in K.Interpolation.UIK_irred_short]
+flatmap.f [variable, in GL.Interpolation.UIGL_irred_short]
+flatmap.F [variable, in GL.Interpolation.UIGL_irred_short]
+flatmap.g [variable, in K.Interpolation.UIK_irred_short]
+flatmap.g [variable, in GL.Interpolation.UIGL_irred_short]
+flatmap.Hg [variable, in K.Interpolation.UIK_irred_short]
+flatmap.Hg [variable, in GL.Interpolation.UIGL_irred_short]
+flatmap.X [variable, in K.Interpolation.UIK_irred_short]
+flatmap.X [variable, in GL.Interpolation.UIGL_irred_short]
+flatten_list [definition, in GL.GLS.GLS_der_dec]
+flatten_list [definition, in K.KS.KS_termination_prelims]
+fmlsext [definition, in General.gen_seq]
+fmlsext_def [lemma, in General.gen_seq]
+fmlsext_fmlsext [lemma, in General.gen_seq]
+fold_Canopy [lemma, in GL.Interpolation.UIGL_Canopy]
+fold_Canopy [lemma, in K.Interpolation.UIK_Canopy]
+fomula_bottom [instance, in ISL.Formulas]
+ForallT [inductive, in General.genT]
+ForallTD_forall [definition, in General.genT]
+ForallTI_forall [definition, in General.genT]
+ForallT_Forall [lemma, in General.genT]
+ForallT_Forall' [lemma, in General.genT]
+ForallT_forall [lemma, in General.genT]
+ForallT_impl [lemma, in General.genT]
+ForallT_2I [definition, in General.genT]
+ForallT_2I' [definition, in General.genT]
+ForallT_D2 [definition, in General.genT]
+ForallT_D1 [definition, in General.genT]
+ForallT_2D [definition, in General.genT]
+ForallT_map_rev [lemma, in General.genT]
+ForallT_map [lemma, in General.genT]
+ForallT_map_2 [lemma, in General.genT]
+ForallT_2 [lemma, in General.genT]
+ForallT_appendI [definition, in General.genT]
+ForallT_appendI' [definition, in General.genT]
+ForallT_appendD2 [definition, in General.genT]
+ForallT_appendD1 [definition, in General.genT]
+ForallT_appendD [definition, in General.genT]
+ForallT_append [lemma, in General.genT]
+ForallT_cons_iff [lemma, in General.genT]
+ForallT_singleI [definition, in General.genT]
+ForallT_singleD [definition, in General.genT]
+ForallT_single [lemma, in General.genT]
+ForallT_cons_inv [lemma, in General.genT]
+ForallT_inv [lemma, in General.genT]
+ForallT_sind [definition, in General.genT]
+ForallT_rec [definition, in General.genT]
+ForallT_ind [definition, in General.genT]
+ForallT_rect [definition, in General.genT]
+ForallT_cons [constructor, in General.genT]
+ForallT_nil [constructor, in General.genT]
+forall_elem_list [lemma, in GL.GLS.GLS_der_dec]
+Forall_map_2 [lemma, in General.gen]
+Forall_map_single [lemma, in General.gen]
+Forall_single [lemma, in General.gen]
+Forall_append [lemma, in General.gen]
+Forall_cons_iff [lemma, in General.gen]
+Forall_cons_inv [lemma, in General.gen]
+Forall_ForallT' [lemma, in General.genT]
+Forall_ForallT [lemma, in General.genT]
+Forall2T [inductive, in General.genT]
+Forall2T_ex_r [lemma, in General.genT]
+Forall2T_ex_l [lemma, in General.genT]
+Forall2T_app [lemma, in General.genT]
+Forall2T_app_inv_r [lemma, in General.genT]
+Forall2T_app_inv_l [lemma, in General.genT]
+Forall2T_sind [definition, in General.genT]
+Forall2T_rec [definition, in General.genT]
+Forall2T_ind [definition, in General.genT]
+Forall2T_rect [definition, in General.genT]
+Forall2T_cons [constructor, in General.genT]
+Forall2T_nil [constructor, in General.genT]
+form [inductive, in ISL.Formulas]
+Formulas [library]
+form_of_MPropF [definition, in UIML_extraction.UIML_extraction]
+form_order [definition, in ISL.Formulas]
+form_count [instance, in ISL.Formulas]
+form_to_gen_tree [definition, in ISL.Formulas]
+form_eq_dec [instance, in ISL.Formulas]
+form_top [instance, in ISL.Formulas]
+form_sind [definition, in ISL.Formulas]
+form_rec [definition, in ISL.Formulas]
+form_ind [definition, in ISL.Formulas]
+form_rect [definition, in ISL.Formulas]
+fst_rel_sind [definition, in General.gen_seq]
+fst_rel_rec [definition, in General.gen_seq]
+fst_rel_ind [definition, in General.gen_seq]
+fst_rel_rect [definition, in General.gen_seq]
+fst_relI [constructor, in General.gen_seq]
+fst_rel [inductive, in General.gen_seq]
+fst_ext_rls_derl_fst_ext_rls' [definition, in General.gen_seq]
+fst_ext_rls_derl_fst_ext_rls [lemma, in General.gen_seq]
+fst_ext_rls_fst_ext_rls' [definition, in General.gen_seq]
+fst_ext_rls_fst_ext_rls [lemma, in General.gen_seq]
+fst_snd_ext [lemma, in General.gen_seq]
+fst_ext_rls_sind [definition, in General.gen_seq]
+fst_ext_rls_rec [definition, in General.gen_seq]
+fst_ext_rls_ind [definition, in General.gen_seq]
+fst_ext_rls_rect [definition, in General.gen_seq]
+fst_ext_rls [inductive, in General.gen_seq]
+fun_cong [lemma, in General.gen]
+

G

+gen [library]
+generalised_contraction [lemma, in ISL.SequentProps]
+generalised_axiom [lemma, in ISL.SequentProps]
+generalised_weakeningR [lemma, in ISL.SequentProps]
+generalised_weakeningL [lemma, in ISL.SequentProps]
+general_export [library]
+genT [library]
+gentree [library]
+gen_step_lem' [lemma, in General.gstep]
+gen_step2s_lem [definition, in General.gstep]
+gen_step2s_lem_ps [lemma, in General.gstep]
+gen_steps_lem [definition, in General.gstep]
+gen_steps_lem_ps [lemma, in General.gstep]
+gen_step2s [definition, in General.gstep]
+gen_steps [definition, in General.gstep]
+gen_step2_lemT [definition, in General.gstep]
+gen_step2_lem [definition, in General.gstep]
+gen_step2_lem_psT [lemma, in General.gstep]
+gen_step2_lem_ps [lemma, in General.gstep]
+gen_step_lemT [definition, in General.gstep]
+gen_step_lem [definition, in General.gstep]
+gen_step_lem_ps [lemma, in General.gstep]
+gen_step_lem_psT [lemma, in General.gstep]
+gen_step2_empty [definition, in General.gstep]
+gen_step2_sub_mono [lemma, in General.gstep]
+gen_step2 [definition, in General.gstep]
+gen_step'_sind [definition, in General.gstep]
+gen_step'_rec [definition, in General.gstep]
+gen_step'_ind [definition, in General.gstep]
+gen_step'_rect [definition, in General.gstep]
+gen_step' [inductive, in General.gstep]
+gen_step_def [lemma, in General.gstep]
+gen_step_sub_mono [lemma, in General.gstep]
+gen_step [definition, in General.gstep]
+gen_ext_add_elem_deep [lemma, in General.univ_gen_ext]
+gen_ext_elem_deep [lemma, in General.univ_gen_ext]
+gen_ext_delet_hd [lemma, in General.univ_gen_ext]
+gen_ext_diff [definition, in General.univ_gen_ext]
+gen_ext_diff' [lemma, in General.univ_gen_ext]
+gen_ext_InT [lemma, in General.univ_gen_ext]
+gen_ext_one [definition, in General.univ_gen_ext]
+gen_ext_one' [lemma, in General.univ_gen_ext]
+gen_ext_single [lemma, in General.univ_gen_ext]
+gen_ext_same_hd [lemma, in General.univ_gen_ext]
+gen_ext_combine [lemma, in General.univ_gen_ext]
+gen_ext_splitR [lemma, in General.univ_gen_ext]
+gen_ext_splitL [lemma, in General.univ_gen_ext]
+gen_ext_lem [lemma, in General.univ_gen_ext]
+gen_ext_sameR [definition, in General.univ_gen_ext]
+gen_ext_sameL [definition, in General.univ_gen_ext]
+gen_ext_app [lemma, in General.univ_gen_ext]
+gen_ext_trans [lemma, in General.univ_gen_ext]
+gen_ext_nil_any [lemma, in General.univ_gen_ext]
+gen_ext_appR [lemma, in General.univ_gen_ext]
+gen_ext_appL [lemma, in General.univ_gen_ext]
+gen_ext_refl [lemma, in General.univ_gen_ext]
+gen_ext [definition, in General.univ_gen_ext]
+gen_step2_tr_lem [lemma, in General.gentree]
+gen_step2_c_lem [lemma, in General.gentree]
+gen_step2_c [definition, in General.gentree]
+gen_step2_tr [definition, in General.gentree]
+gen_step_tr_lem [lemma, in General.gentree]
+gen_step_c_lem [lemma, in General.gentree]
+gen_step_c [definition, in General.gentree]
+gen_step_tr [definition, in General.gentree]
+gen_cong [lemma, in General.gen]
+gen_rec_UI_imp [lemma, in GL.Interpolation.UIGL_N_imp_UI]
+gen_tree_to_form [definition, in ISL.Formulas]
+gen_tacs [library]
+gen_seq [library]
+get_dpD [definition, in General.dd_fc]
+get_D [definition, in General.dd_fc]
+get_botrule [lemma, in General.dd_fc]
+Gflatmap [inductive, in K.Interpolation.UIK_irred_short]
+Gflatmap [inductive, in GL.Interpolation.UIGL_irred_short]
+Gflatmap_flat_map [lemma, in K.Interpolation.UIK_irred_short]
+Gflatmap_app_inv_left [lemma, in K.Interpolation.UIK_irred_short]
+Gflatmap_inv_sg_left [lemma, in K.Interpolation.UIK_irred_short]
+Gflatmap_inv_left [lemma, in K.Interpolation.UIK_irred_short]
+Gflatmap_sind [definition, in K.Interpolation.UIK_irred_short]
+Gflatmap_ind [definition, in K.Interpolation.UIK_irred_short]
+Gflatmap_flat_map [lemma, in GL.Interpolation.UIGL_irred_short]
+Gflatmap_app_inv_left [lemma, in GL.Interpolation.UIGL_irred_short]
+Gflatmap_inv_sg_left [lemma, in GL.Interpolation.UIGL_irred_short]
+Gflatmap_inv_left [lemma, in GL.Interpolation.UIGL_irred_short]
+Gflatmap_sind [definition, in GL.Interpolation.UIGL_irred_short]
+Gflatmap_ind [definition, in GL.Interpolation.UIGL_irred_short]
+Gfm_cons [constructor, in K.Interpolation.UIK_irred_short]
+Gfm_nil [constructor, in K.Interpolation.UIK_irred_short]
+Gfm_cons [constructor, in GL.Interpolation.UIGL_irred_short]
+Gfm_nil [constructor, in GL.Interpolation.UIGL_irred_short]
+gf_step2_tr_lem [lemma, in General.gentree]
+gf_step2_tr [definition, in General.gentree]
+gf2_sum [lemma, in General.gentree]
+gf2_step_tr_lem [lemma, in General.gentree]
+gf2_step_tr [definition, in General.gentree]
+Gimap [inductive, in K.Interpolation.UIK_braga]
+Gimap [inductive, in GL.Interpolation.UIGL_braga]
+Gimap_fun_rest [lemma, in K.Interpolation.UIK_braga]
+Gimap_cont.f [variable, in K.Interpolation.UIK_braga]
+Gimap_cont.D [variable, in K.Interpolation.UIK_braga]
+Gimap_cont.F [variable, in K.Interpolation.UIK_braga]
+Gimap_cont.Y [variable, in K.Interpolation.UIK_braga]
+Gimap_cont.X [variable, in K.Interpolation.UIK_braga]
+Gimap_cont [section, in K.Interpolation.UIK_braga]
+Gimap_fun [lemma, in K.Interpolation.UIK_braga]
+Gimap_map [lemma, in K.Interpolation.UIK_braga]
+Gimap_app_inv_left [lemma, in K.Interpolation.UIK_braga]
+Gimap_inv_sg_left [lemma, in K.Interpolation.UIK_braga]
+Gimap_inv_left [lemma, in K.Interpolation.UIK_braga]
+Gimap_sind [definition, in K.Interpolation.UIK_braga]
+Gimap_ind [definition, in K.Interpolation.UIK_braga]
+Gimap_fun_rest [lemma, in GL.Interpolation.UIGL_braga]
+Gimap_cont.f [variable, in GL.Interpolation.UIGL_braga]
+Gimap_cont.D [variable, in GL.Interpolation.UIGL_braga]
+Gimap_cont.F [variable, in GL.Interpolation.UIGL_braga]
+Gimap_cont.Y [variable, in GL.Interpolation.UIGL_braga]
+Gimap_cont.X [variable, in GL.Interpolation.UIGL_braga]
+Gimap_cont [section, in GL.Interpolation.UIGL_braga]
+Gimap_fun [lemma, in GL.Interpolation.UIGL_braga]
+Gimap_map [lemma, in GL.Interpolation.UIGL_braga]
+Gimap_app_inv_left [lemma, in GL.Interpolation.UIGL_braga]
+Gimap_inv_sg_left [lemma, in GL.Interpolation.UIGL_braga]
+Gimap_inv_left [lemma, in GL.Interpolation.UIGL_braga]
+Gimap_sind [definition, in GL.Interpolation.UIGL_braga]
+Gimap_ind [definition, in GL.Interpolation.UIGL_braga]
+Gim_cons [constructor, in K.Interpolation.UIK_braga]
+Gim_nil [constructor, in K.Interpolation.UIK_braga]
+Gim_cons [constructor, in GL.Interpolation.UIGL_braga]
+Gim_nil [constructor, in GL.Interpolation.UIGL_braga]
+Girred [inductive, in K.Interpolation.UIK_irred_short]
+Girred [inductive, in GL.Interpolation.UIGL_irred_short]
+Girred_fun [lemma, in K.Interpolation.UIK_irred_short]
+Girred_ind [definition, in K.Interpolation.UIK_irred_short]
+Girred_inv_not [lemma, in K.Interpolation.UIK_irred_short]
+Girred_inv_nil [lemma, in K.Interpolation.UIK_irred_short]
+Girred_not [constructor, in K.Interpolation.UIK_irred_short]
+Girred_nil [constructor, in K.Interpolation.UIK_irred_short]
+Girred_fun [lemma, in GL.Interpolation.UIGL_irred_short]
+Girred_ind [definition, in GL.Interpolation.UIGL_irred_short]
+Girred_inv_not [lemma, in GL.Interpolation.UIGL_irred_short]
+Girred_inv_nil [lemma, in GL.Interpolation.UIGL_irred_short]
+Girred_not [constructor, in GL.Interpolation.UIGL_irred_short]
+Girred_nil [constructor, in GL.Interpolation.UIGL_irred_short]
+GLR [constructor, in GL.GLS.GLS_calcs]
+GLRRule [inductive, in GL.GLS.GLS_calcs]
+GLRRule_sind [definition, in GL.GLS.GLS_calcs]
+GLRRule_rec [definition, in GL.GLS.GLS_calcs]
+GLRRule_ind [definition, in GL.GLS.GLS_calcs]
+GLRRule_rect [definition, in GL.GLS.GLS_calcs]
+GLRRule_I [constructor, in GL.GLS.GLS_calcs]
+GLR_help2 [definition, in GL.GLS.GLS_der_dec]
+GLR_help02 [definition, in GL.GLS.GLS_der_dec]
+GLR_help1 [definition, in GL.GLS.GLS_der_dec]
+GLR_help01 [definition, in GL.GLS.GLS_der_dec]
+GLR_app_wkn_R [lemma, in GL.GLS.GLS_wkn]
+GLR_app_wkn_L [lemma, in GL.GLS.GLS_wkn]
+GLR_applic_reduces_measure [lemma, in GL.GLS.GLS_termination_measure]
+GLR_applic_less_usable_boxes [lemma, in GL.GLS.GLS_termination_measure]
+GLR_applic_le_subform_boxes [lemma, in GL.GLS.GLS_termination_measure]
+GLR_applic_more_top_boxes [lemma, in GL.GLS.GLS_termination_measure]
+GLR_app_list_exchR [lemma, in GL.GLS.GLS_exch]
+GLR_app_list_exchL [lemma, in GL.GLS.GLS_exch]
+GLR_prems_less_ub [lemma, in GL.Interpolation.UIGL_LexSeq]
+GLR_prems_LexSeq [lemma, in GL.Interpolation.UIGL_LexSeq]
+GLR_prems [definition, in GL.Interpolation.UIGL_LexSeq]
+GLR_app_ctr_R [lemma, in GL.GLS.GLS_ctr]
+GLR_app_ctr_L [lemma, in GL.GLS.GLS_ctr]
+GLS_cut_adm [lemma, in GL.GLS.GLS_additive_cut]
+GLS_cut_adm_main [lemma, in GL.GLS.GLS_additive_cut]
+GLS_dec_der [lemma, in GL.GLS.GLS_der_dec]
+GLS_drv [definition, in GL.GLS.GLS_calcs]
+GLS_prv [definition, in GL.GLS.GLS_calcs]
+GLS_rules_sind [definition, in GL.GLS.GLS_calcs]
+GLS_rules_rec [definition, in GL.GLS.GLS_calcs]
+GLS_rules_ind [definition, in GL.GLS.GLS_calcs]
+GLS_rules_rect [definition, in GL.GLS.GLS_calcs]
+GLS_rules [inductive, in GL.GLS.GLS_calcs]
+GLS_XBoxed_list_wkn_L [lemma, in GL.GLS.GLS_wkn]
+GLS_prv_list_wkn_L [lemma, in GL.GLS.GLS_wkn]
+GLS_list_wkn_L [lemma, in GL.GLS.GLS_wkn]
+GLS_prv_list_wkn_R [lemma, in GL.GLS.GLS_wkn]
+GLS_list_wkn_R [lemma, in GL.GLS.GLS_wkn]
+GLS_prv_wkn_R [lemma, in GL.GLS.GLS_wkn]
+GLS_wkn_R [lemma, in GL.GLS.GLS_wkn]
+GLS_prv_wkn_L [lemma, in GL.GLS.GLS_wkn]
+GLS_wkn_L [lemma, in GL.GLS.GLS_wkn]
+GLS_cut_elimination [lemma, in GL.GLS.GLS_cut_elim]
+GLS_cut_drv [definition, in GL.GLS.GLS_cut_elim]
+GLS_cut_prv [definition, in GL.GLS.GLS_cut_elim]
+GLS_cut_rules_sind [definition, in GL.GLS.GLS_cut_elim]
+GLS_cut_rules_rec [definition, in GL.GLS.GLS_cut_elim]
+GLS_cut_rules_ind [definition, in GL.GLS.GLS_cut_elim]
+GLS_cut_rules_rect [definition, in GL.GLS.GLS_cut_elim]
+GLS_woc [constructor, in GL.GLS.GLS_cut_elim]
+GLS_cut_rules [inductive, in GL.GLS.GLS_cut_elim]
+GLS_adm_list_exch_LR [lemma, in GL.GLS.GLS_exch]
+GLS_hpadm_list_exch_L [lemma, in GL.GLS.GLS_exch]
+GLS_hpadm_list_exch_R [lemma, in GL.GLS.GLS_exch]
+GLS_der_list_exch_R [lemma, in GL.GLS.GLS_exch]
+GLS_der_list_exch_L [lemma, in GL.GLS.GLS_exch]
+GLS_adm_list_exch_R [lemma, in GL.GLS.GLS_exch]
+GLS_adm_list_exch_L [lemma, in GL.GLS.GLS_exch]
+GLS_hpadm_list_ctr_R [lemma, in GL.GLS.GLS_ctr]
+GLS_hpadm_list_ctr_L [lemma, in GL.GLS.GLS_ctr]
+GLS_hpadm_ctr_R [lemma, in GL.GLS.GLS_ctr]
+GLS_hpadm_ctr_L [lemma, in GL.GLS.GLS_ctr]
+GLS_hpadm_ctr_LR [lemma, in GL.GLS.GLS_ctr]
+GLS_wkn [library]
+GLS_dec [library]
+GLS_cut_elim [library]
+GLS_calcs [library]
+GLS_ctr [library]
+GLS_export [library]
+GLS_inv_ImpR_ImpL [library]
+GLS_exch [library]
+GLS_additive_cut [library]
+GLS_der_dec [library]
+GLS_termination_measure [library]
+gl_UI [definition, in UIML_extraction.UIML_extraction]
+gmultiset_elements_list_to_set_disj [lemma, in ISL.Environments]
+gmultiset_rec [lemma, in ISL.Environments]
+gmultiset_choose_or_empty [lemma, in ISL.Environments]
+GN [inductive, in GL.Interpolation.UIGL_braga]
+GN [section, in GL.Interpolation.UIGL_braga]
+GN_inv_noinit_nolessub [lemma, in GL.Interpolation.UIGL_braga]
+GN_inv_noinit_lessub [lemma, in GL.Interpolation.UIGL_braga]
+GN_inv_init [lemma, in GL.Interpolation.UIGL_braga]
+GN_fun0 [lemma, in GL.Interpolation.UIGL_braga]
+GN_fun [lemma, in GL.Interpolation.UIGL_braga]
+GN_inv_noinit_nolessub0 [lemma, in GL.Interpolation.UIGL_braga]
+GN_inv_noinit_lessub0 [lemma, in GL.Interpolation.UIGL_braga]
+GN_inv_init0 [lemma, in GL.Interpolation.UIGL_braga]
+GN_less [constructor, in GL.Interpolation.UIGL_braga]
+GN_less_ub [constructor, in GL.Interpolation.UIGL_braga]
+GN_init_seq [constructor, in GL.Interpolation.UIGL_braga]
+GN.F [variable, in GL.Interpolation.UIGL_braga]
+GN.Ffun [variable, in GL.Interpolation.UIGL_braga]
+GN.p [variable, in GL.Interpolation.UIGL_braga]
+Good_pos_in_pos_top_imps [lemma, in GL.GLS.GLS_der_dec]
+Good_pos_in_pos_top_imps [lemma, in K.KS.KS_termination_ImpR]
+gsc_gstr [lemma, in General.gentree]
+gsI [constructor, in General.gstep]
+gstep [library]
+gstr_gf2 [lemma, in General.gentree]
+gs_gs' [lemma, in General.gstep]
+gs_gsc [lemma, in General.gentree]
+gs2c_gs2tr [lemma, in General.gentree]
+gs2tr_gf2 [lemma, in General.gentree]
+gs2_hs2 [lemma, in General.gentree]
+gs2_tr_height [lemma, in General.gentree]
+gs2_tr_size [lemma, in General.gentree]
+gs2_gs2c [lemma, in General.gentree]
+GUI [inductive, in K.Interpolation.UIK_braga]
+GUI [inductive, in GL.Interpolation.UIGL_braga]
+GUI_inv_critic_not_init [lemma, in K.Interpolation.UIK_braga]
+GUI_inv_not_critic [lemma, in K.Interpolation.UIK_braga]
+GUI_inv_critic_init [lemma, in K.Interpolation.UIK_braga]
+GUI_inv_empty_seq [lemma, in K.Interpolation.UIK_braga]
+GUI_tot [definition, in K.Interpolation.UIK_braga]
+GUI_fun [lemma, in K.Interpolation.UIK_braga]
+GUI_critic_not_init [constructor, in K.Interpolation.UIK_braga]
+GUI_not_critic [constructor, in K.Interpolation.UIK_braga]
+GUI_critic_init [constructor, in K.Interpolation.UIK_braga]
+GUI_empty_seq [constructor, in K.Interpolation.UIK_braga]
+GUI_inv_critic_not_init [lemma, in GL.Interpolation.UIGL_braga]
+GUI_inv_not_critic [lemma, in GL.Interpolation.UIGL_braga]
+GUI_inv_critic_init [lemma, in GL.Interpolation.UIGL_braga]
+GUI_inv_empty_seq [lemma, in GL.Interpolation.UIGL_braga]
+GUI_tot [definition, in GL.Interpolation.UIGL_braga]
+GUI_fun [lemma, in GL.Interpolation.UIGL_braga]
+GUI_critic_not_init [constructor, in GL.Interpolation.UIGL_braga]
+GUI_not_critic [constructor, in GL.Interpolation.UIGL_braga]
+GUI_critic_init [constructor, in GL.Interpolation.UIGL_braga]
+GUI_empty_seq [constructor, in GL.Interpolation.UIGL_braga]
+

H

+height [definition, in ISL.SequentProps]
+height_0 [lemma, in ISL.SequentProps]
+height_step2_tr_lem [lemma, in General.gentree]
+height_step2_tr [definition, in General.gentree]
+hs2_sumh [lemma, in General.gentree]
+

I

+IdBRule [inductive, in GL.GLS.GLS_calcs]
+IdBRule_sind [definition, in GL.GLS.GLS_calcs]
+IdBRule_rec [definition, in GL.GLS.GLS_calcs]
+IdBRule_ind [definition, in GL.GLS.GLS_calcs]
+IdBRule_rect [definition, in GL.GLS.GLS_calcs]
+IdBRule_I [constructor, in GL.GLS.GLS_calcs]
+IdP [constructor, in GL.GLS.GLS_calcs]
+IdP [constructor, in K.KS.KS_calc]
+IdPRule [inductive, in GL.GLS.GLS_calcs]
+IdPRule [inductive, in K.KS.KS_calc]
+IdPRule_sind [definition, in GL.GLS.GLS_calcs]
+IdPRule_rec [definition, in GL.GLS.GLS_calcs]
+IdPRule_ind [definition, in GL.GLS.GLS_calcs]
+IdPRule_rect [definition, in GL.GLS.GLS_calcs]
+IdPRule_I [constructor, in GL.GLS.GLS_calcs]
+IdPRule_sind [definition, in K.KS.KS_calc]
+IdPRule_rec [definition, in K.KS.KS_calc]
+IdPRule_ind [definition, in K.KS.KS_calc]
+IdPRule_rect [definition, in K.KS.KS_calc]
+IdPRule_I [constructor, in K.KS.KS_calc]
+Idrule [inductive, in General.gen_seq]
+Idrule_sind [definition, in General.gen_seq]
+Idrule_rec [definition, in General.gen_seq]
+Idrule_ind [definition, in General.gen_seq]
+Idrule_rect [definition, in General.gen_seq]
+Idrule_I [constructor, in General.gen_seq]
+Id_all_form [lemma, in GL.GLS.GLS_calcs]
+Id_InT_Canopy [definition, in GL.Interpolation.UIGL_Canopy]
+Id_all_form [lemma, in K.KS.KS_calc]
+Id_InT_Canopy [lemma, in K.Interpolation.UIK_Canopy]
+iffD1 [lemma, in General.gen]
+iffD2 [lemma, in General.gen]
+iffT_prod [lemma, in General.genT]
+iffT_D2 [definition, in General.genT]
+iffT_D1 [definition, in General.genT]
+iffT_sym [definition, in General.genT]
+iffT_D2' [lemma, in General.genT]
+iffT_D1' [lemma, in General.genT]
+iffT_refl [lemma, in General.genT]
+iffT_sym' [lemma, in General.genT]
+iffT_trans [lemma, in General.genT]
+if_rev_eq [lemma, in General.List_lemmasT]
+if_eq_rev_eq [lemma, in General.List_lemmasT]
+iGLS_cut [constructor, in GL.GLS.GLS_cut_elim]
+imap [definition, in K.Interpolation.UIK_braga]
+imap [section, in K.Interpolation.UIK_braga]
+imap [definition, in GL.Interpolation.UIGL_braga]
+imap [section, in GL.Interpolation.UIGL_braga]
+imap.D [variable, in K.Interpolation.UIK_braga]
+imap.D [variable, in GL.Interpolation.UIGL_braga]
+imap.f [variable, in K.Interpolation.UIK_braga]
+imap.F [variable, in K.Interpolation.UIK_braga]
+imap.f [variable, in GL.Interpolation.UIGL_braga]
+imap.F [variable, in GL.Interpolation.UIGL_braga]
+imap.Ffun [variable, in K.Interpolation.UIK_braga]
+imap.Ffun [variable, in GL.Interpolation.UIGL_braga]
+imap.g [variable, in K.Interpolation.UIK_braga]
+imap.g [variable, in GL.Interpolation.UIGL_braga]
+imap.Hg [variable, in K.Interpolation.UIK_braga]
+imap.Hg [variable, in GL.Interpolation.UIGL_braga]
+imap.X [variable, in K.Interpolation.UIK_braga]
+imap.X [variable, in GL.Interpolation.UIGL_braga]
+imap.Y [variable, in K.Interpolation.UIK_braga]
+imap.Y [variable, in GL.Interpolation.UIGL_braga]
+Imp [constructor, in Syntax.CML_Syntax]
+ImpBox [constructor, in ISL.Sequents]
+ImpBox_dup [lemma, in ISL.SequentProps]
+ImpL [constructor, in GL.GLS.GLS_calcs]
+ImpL [lemma, in ISL.SequentProps]
+ImpL [constructor, in K.KS.KS_calc]
+ImpLAnd [constructor, in ISL.Sequents]
+ImpLAnd_rev [lemma, in ISL.SequentProps]
+ImpLBox_prev [lemma, in ISL.SequentProps]
+Implies [constructor, in ISL.Formulas]
+ImpLImp [constructor, in ISL.Sequents]
+ImpLImp_dup [lemma, in ISL.SequentProps]
+ImpLImp_prev [lemma, in ISL.SequentProps]
+ImpLOr [constructor, in ISL.Sequents]
+ImpLOr_rev [lemma, in ISL.SequentProps]
+ImpLRule [inductive, in GL.GLS.GLS_calcs]
+ImpLRule [inductive, in K.KS.KS_calc]
+ImpLRule_sind [definition, in GL.GLS.GLS_calcs]
+ImpLRule_rec [definition, in GL.GLS.GLS_calcs]
+ImpLRule_ind [definition, in GL.GLS.GLS_calcs]
+ImpLRule_rect [definition, in GL.GLS.GLS_calcs]
+ImpLRule_I [constructor, in GL.GLS.GLS_calcs]
+ImpLRule_sind [definition, in K.KS.KS_calc]
+ImpLRule_rec [definition, in K.KS.KS_calc]
+ImpLRule_ind [definition, in K.KS.KS_calc]
+ImpLRule_rect [definition, in K.KS.KS_calc]
+ImpLRule_I [constructor, in K.KS.KS_calc]
+ImpLVar [constructor, in ISL.Sequents]
+ImpLVar_rev [lemma, in ISL.SequentProps]
+ImpL_app_ctr_R [lemma, in K.KS.KS_ctr]
+ImpL_app_ctr_L [lemma, in K.KS.KS_ctr]
+ImpL_app_wkn_R [lemma, in K.KS.KS_wkn]
+ImpL_app_wkn_L [lemma, in K.KS.KS_wkn]
+ImpL_help1 [definition, in GL.GLS.GLS_der_dec]
+ImpL_help01 [definition, in GL.GLS.GLS_der_dec]
+ImpL_help2 [definition, in GL.GLS.GLS_der_dec]
+ImpL_help02 [definition, in GL.GLS.GLS_der_dec]
+ImpL_help002 [definition, in GL.GLS.GLS_der_dec]
+ImpL_app_wkn_R [lemma, in GL.GLS.GLS_wkn]
+ImpL_app_wkn_L [lemma, in GL.GLS.GLS_wkn]
+ImpL_help1 [definition, in K.KS.KS_termination_ImpL]
+ImpL_help01 [definition, in K.KS.KS_termination_ImpL]
+ImpL_help2 [definition, in K.KS.KS_termination_ImpL]
+ImpL_help02 [definition, in K.KS.KS_termination_ImpL]
+ImpL_help002 [definition, in K.KS.KS_termination_ImpL]
+ImpL_app_list_exchR [lemma, in K.KS.KS_exch_ImpL]
+ImpL_app_list_exchL [lemma, in K.KS.KS_exch_ImpL]
+ImpL_applic_reduces_measure [lemma, in GL.GLS.GLS_termination_measure]
+ImpL_applic_reduces_ub_or_imp [lemma, in GL.GLS.GLS_termination_measure]
+ImpL_applic_less_Imp_same_usable_boxes [lemma, in GL.GLS.GLS_termination_measure]
+ImpL_inv [lemma, in GL.GLS.GLS_inv_ImpR_ImpL]
+ImpL_app_list_exchR [lemma, in GL.GLS.GLS_exch]
+ImpL_app_list_exchL [lemma, in GL.GLS.GLS_exch]
+ImpL_app_ctr_R [lemma, in GL.GLS.GLS_ctr]
+ImpL_app_ctr_L [lemma, in GL.GLS.GLS_ctr]
+ImpL_inv [lemma, in K.KS.KS_inv_ImpR_ImpL]
+ImpR [constructor, in ISL.Sequents]
+ImpR [constructor, in GL.GLS.GLS_calcs]
+ImpR [constructor, in K.KS.KS_calc]
+ImpRRule [inductive, in GL.GLS.GLS_calcs]
+ImpRRule [inductive, in K.KS.KS_calc]
+ImpRRule_sind [definition, in GL.GLS.GLS_calcs]
+ImpRRule_rec [definition, in GL.GLS.GLS_calcs]
+ImpRRule_ind [definition, in GL.GLS.GLS_calcs]
+ImpRRule_rect [definition, in GL.GLS.GLS_calcs]
+ImpRRule_I [constructor, in GL.GLS.GLS_calcs]
+ImpRRule_sind [definition, in K.KS.KS_calc]
+ImpRRule_rec [definition, in K.KS.KS_calc]
+ImpRRule_ind [definition, in K.KS.KS_calc]
+ImpRRule_rect [definition, in K.KS.KS_calc]
+ImpRRule_I [constructor, in K.KS.KS_calc]
+ImpRule_Canopy [lemma, in GL.Interpolation.UIGL_Canopy]
+ImpRule_Canopy [lemma, in K.Interpolation.UIK_Canopy]
+ImpR_app_ctr_R [lemma, in K.KS.KS_ctr]
+ImpR_app_ctr_L [lemma, in K.KS.KS_ctr]
+ImpR_app_wkn_R [lemma, in K.KS.KS_wkn]
+ImpR_app_wkn_L [lemma, in K.KS.KS_wkn]
+ImpR_help2 [definition, in GL.GLS.GLS_der_dec]
+ImpR_help02 [definition, in GL.GLS.GLS_der_dec]
+ImpR_help002 [definition, in GL.GLS.GLS_der_dec]
+ImpR_help1 [definition, in GL.GLS.GLS_der_dec]
+ImpR_help01 [definition, in GL.GLS.GLS_der_dec]
+ImpR_rev [lemma, in ISL.SequentProps]
+ImpR_app_wkn_R [lemma, in GL.GLS.GLS_wkn]
+ImpR_app_wkn_L [lemma, in GL.GLS.GLS_wkn]
+ImpR_applic_reduces_measure [lemma, in GL.GLS.GLS_termination_measure]
+ImpR_applic_reduces_ub_or_imp [lemma, in GL.GLS.GLS_termination_measure]
+ImpR_applic_less_Imp_same_usable_boxes [lemma, in GL.GLS.GLS_termination_measure]
+ImpR_inv [lemma, in GL.GLS.GLS_inv_ImpR_ImpL]
+ImpR_ImpL_hpinv [lemma, in GL.GLS.GLS_inv_ImpR_ImpL]
+ImpR_app_list_exchR [lemma, in GL.GLS.GLS_exch]
+ImpR_app_list_exchL [lemma, in GL.GLS.GLS_exch]
+ImpR_app_ctr_R [lemma, in GL.GLS.GLS_ctr]
+ImpR_app_ctr_L [lemma, in GL.GLS.GLS_ctr]
+ImpR_help2 [definition, in K.KS.KS_termination_ImpR]
+ImpR_help02 [definition, in K.KS.KS_termination_ImpR]
+ImpR_help002 [definition, in K.KS.KS_termination_ImpR]
+ImpR_help1 [definition, in K.KS.KS_termination_ImpR]
+ImpR_help01 [definition, in K.KS.KS_termination_ImpR]
+ImpR_inv [lemma, in K.KS.KS_inv_ImpR_ImpL]
+ImpR_ImpL_hpinv [lemma, in K.KS.KS_inv_ImpR_ImpL]
+ImpR_app_list_exchR [lemma, in K.KS.KS_exch_ImpR]
+ImpR_app_list_exchL [lemma, in K.KS.KS_exch_ImpR]
+imp_cut [lemma, in ISL.SequentProps]
+incl_idS [lemma, in GL.Interpolation.UIGL_nodupseq]
+incl_id [lemma, in GL.Interpolation.UIGL_nodupseq]
+incl_ctr_R [lemma, in GL.Interpolation.UIGL_nodupseq]
+incl_ctr_R_hpadm [lemma, in GL.Interpolation.UIGL_nodupseq]
+incl_ctr_L [lemma, in GL.Interpolation.UIGL_nodupseq]
+incl_ctr_L_hpadm [lemma, in GL.Interpolation.UIGL_nodupseq]
+incl_nodup_top_boxes [lemma, in GL.Interpolation.UIGL_nodupseq]
+incl_nodupseq_subform_boxesS [lemma, in GL.Interpolation.UIGL_nodupseq]
+incl_nodup_subform_boxesLF [lemma, in GL.Interpolation.UIGL_nodupseq]
+incl_prv [lemma, in GL.Interpolation.UIGL_UI_prelims]
+incl_hpadm_prv [lemma, in GL.Interpolation.UIGL_UI_prelims]
+IndClo [constructor, in GL.GLS.GLS_exch]
+IndClo [constructor, in K.KS.KS_exch]
+IndLExch [constructor, in GL.GLS.GLS_exch]
+IndLExch [constructor, in K.KS.KS_exch]
+IndRExch [constructor, in GL.GLS.GLS_exch]
+IndRExch [constructor, in K.KS.KS_exch]
+inhabited_anon [lemma, in General.genT]
+InitClo [constructor, in GL.GLS.GLS_exch]
+InitClo [constructor, in K.KS.KS_exch]
+InitLExch [constructor, in GL.GLS.GLS_exch]
+InitLExch [constructor, in K.KS.KS_exch]
+InitRExch [constructor, in GL.GLS.GLS_exch]
+InitRExch [constructor, in K.KS.KS_exch]
+InT [inductive, in General.genT]
+InT_seqext [lemma, in General.gen_seq]
+InT_seqextR [lemma, in General.gen_seq]
+InT_seqextL [lemma, in General.gen_seq]
+InT_list_of_premises_exists_prems [lemma, in K.KS.KS_termination]
+InT_In_Seq [lemma, in K.Interpolation.UIK_basics]
+InT_list_of_premises_exists_prems [lemma, in GL.GLS.GLS_der_dec]
+InT_trans_flatten_list [definition, in GL.GLS.GLS_der_dec]
+InT_flatten_list_InT_elem [definition, in GL.GLS.GLS_der_dec]
+InT_map_iff [definition, in GL.GLS.GLS_der_dec]
+InT_trans_flatten_list [definition, in K.KS.KS_termination_prelims]
+InT_flatten_list_InT_elem [definition, in K.KS.KS_termination_prelims]
+InT_map_iff [definition, in K.KS.KS_termination_prelims]
+InT_univ_gen_mod [lemma, in General.univ_gen_mod]
+InT_In_Seq [lemma, in GL.Interpolation.UIGL_basics]
+InT_gen_ext [lemma, in General.univ_gen_ext]
+InT_univ_gen_ext [lemma, in General.univ_gen_ext]
+InT_var_provar [lemma, in K.Interpolation.K_Craig_Interp]
+InT_list_exch_L [lemma, in K.KS.KS_exch_prelims]
+InT_list_exch_R [lemma, in K.KS.KS_exch_prelims]
+InT_flat_map [lemma, in GL.Interpolation.UIGL_Canopy]
+InT_In_inv_prems [lemma, in GL.Interpolation.UIGL_Canopy]
+InT_list_exch_L [lemma, in GL.GLS.GLS_exch]
+InT_list_exch_R [lemma, in GL.GLS.GLS_exch]
+InT_or_app [definition, in General.List_lemmasT]
+InT_app_or [definition, in General.List_lemmasT]
+InT_singleton_mid [lemma, in General.List_lemmasT]
+InT_mid [lemma, in General.List_lemmasT]
+InT_pt_I [lemma, in General.List_lemmasT]
+InT_pair_triple_sind [definition, in General.List_lemmasT]
+InT_pair_triple_rec [definition, in General.List_lemmasT]
+InT_pair_triple_ind [definition, in General.List_lemmasT]
+InT_pair_triple_rect [definition, in General.List_lemmasT]
+InT_pt_tl [constructor, in General.List_lemmasT]
+InT_pt_hd [constructor, in General.List_lemmasT]
+InT_pair_triple [inductive, in General.List_lemmasT]
+InT_dec [lemma, in Syntax.list_lems]
+InT_exch_list [lemma, in Syntax.list_lems]
+InT_In_eq' [lemma, in General.genT]
+InT_In_eq [lemma, in General.genT]
+InT_In' [lemma, in General.genT]
+InT_In [lemma, in General.genT]
+InT_concat [lemma, in General.genT]
+InT_mapI [definition, in General.genT]
+InT_map_iffT [definition, in General.genT]
+InT_mapE [lemma, in General.genT]
+InT_map [lemma, in General.genT]
+InT_inv [lemma, in General.genT]
+InT_split [lemma, in General.genT]
+InT_nilE [lemma, in General.genT]
+InT_nilE' [lemma, in General.genT]
+InT_appE [lemma, in General.genT]
+InT_appE' [lemma, in General.genT]
+InT_appR [lemma, in General.genT]
+InT_appL [lemma, in General.genT]
+InT_2nd [definition, in General.genT]
+InT_eq [definition, in General.genT]
+InT_sind [definition, in General.genT]
+InT_rec [definition, in General.genT]
+InT_ind [definition, in General.genT]
+InT_rect [definition, in General.genT]
+InT_cons [constructor, in General.genT]
+InT_eq' [constructor, in General.genT]
+InT_flat_map [lemma, in K.Interpolation.UIK_Canopy]
+InT_In_inv_prems [lemma, in K.Interpolation.UIK_Canopy]
+invprem [definition, in GL.Interpolation.UIGL_Canopy]
+invprem [definition, in K.Interpolation.UIK_Canopy]
+inv_prems_measure [lemma, in K.Interpolation.UIK_UI_prelims]
+inv_prems_LtSeq [lemma, in K.Interpolation.UIK_basics]
+inv_prems_id_critical [lemma, in GL.Interpolation.UIGL_Canopy]
+inv_prems [definition, in GL.Interpolation.UIGL_Canopy]
+inv_prems_LexSeq [lemma, in GL.Interpolation.UIGL_LexSeq]
+inv_prems_id_critical [lemma, in K.Interpolation.UIK_Canopy]
+inv_prems [definition, in K.Interpolation.UIK_Canopy]
+in_drs_concl_in_allT [lemma, in K.KS.KS_termination]
+In_unboxed_list [lemma, in K.Interpolation.UIK_UI_prelims]
+In_list_In_propvar_subform_list [lemma, in K.Interpolation.UIK_UI_prelims]
+In_list_In_list_prop_LF [lemma, in K.Interpolation.UIK_UI_prelims]
+In_list_prop_LF [lemma, in K.Interpolation.UIK_UI_prelims]
+In_list_prop_LF_bis [lemma, in K.Interpolation.UIK_basics]
+In_list_prop_LF [lemma, in K.Interpolation.UIK_basics]
+In_l_imp_In_pos_top_imps [lemma, in GL.GLS.GLS_der_dec]
+In_pos_top_imps_split_l [definition, in GL.GLS.GLS_der_dec]
+In_pos_top_imps_In_l [lemma, in GL.GLS.GLS_der_dec]
+In_pos_top_imps_imp [lemma, in GL.GLS.GLS_der_dec]
+In_pos_top_imps_0_False [lemma, in GL.GLS.GLS_der_dec]
+In_listInserts [lemma, in GL.GLS.GLS_der_dec]
+In_InT_pair [definition, in GL.GLS.GLS_der_dec]
+In_InT [lemma, in GL.GLS.GLS_der_dec]
+in_replace [lemma, in GL.Interpolation.UIGL_Canopy_ImpR]
+in_not_touched_replace [lemma, in GL.Interpolation.UIGL_Canopy_ImpR]
+In_listInserts [lemma, in K.KS.KS_termination_prelims]
+In_InT_pair [definition, in K.KS.KS_termination_prelims]
+In_InT [lemma, in K.KS.KS_termination_prelims]
+In_list_prop_LF_bis [lemma, in GL.Interpolation.UIGL_basics]
+In_list_prop_LF [lemma, in GL.Interpolation.UIGL_basics]
+in_nextup_fc_nu [definition, in General.dd_fc]
+in_nextup_fc_eqv [lemma, in General.dd_fc]
+in_nextup_nu [definition, in General.dd_fc]
+in_nextup_eqv [lemma, in General.dd_fc]
+in_trees_drs [lemma, in General.dd_fc]
+in_drs_trees [lemma, in General.dd_fc]
+in_nextup_fc_sind [definition, in General.dd_fc]
+in_nextup_fc_rec [definition, in General.dd_fc]
+in_nextup_fc_ind [definition, in General.dd_fc]
+in_nextup_fc_rect [definition, in General.dd_fc]
+in_nextup_fcI [constructor, in General.dd_fc]
+in_nextup_fc [inductive, in General.dd_fc]
+in_drs_drs_hd [lemma, in General.dd_fc]
+in_dersrec_single' [lemma, in General.dd_fc]
+in_nextup_concl_in [lemma, in General.dd_fc]
+in_drs_concl_in [lemma, in General.dd_fc]
+in_nextup_sind [definition, in General.dd_fc]
+in_nextup_rec [definition, in General.dd_fc]
+in_nextup_ind [definition, in General.dd_fc]
+in_nextup_rect [definition, in General.dd_fc]
+in_nextupI [constructor, in General.dd_fc]
+in_nextup [inductive, in General.dd_fc]
+in_dersrec_sind [definition, in General.dd_fc]
+in_dersrec_rec [definition, in General.dd_fc]
+in_dersrec_ind [definition, in General.dd_fc]
+in_dersrec_rect [definition, in General.dd_fc]
+in_dersrec_tl [constructor, in General.dd_fc]
+in_dersrec_hd [constructor, in General.dd_fc]
+in_dersrec [inductive, in General.dd_fc]
+in_nextup_height [definition, in General.gentree]
+in_nextup_size [definition, in General.gentree]
+In_XBoxed_list_gen [lemma, in GL.Interpolation.UIGL_nodupseq]
+In_XBoxed_list [lemma, in GL.Interpolation.UIGL_nodupseq]
+in_adm [definition, in General.ddT]
+in_derl [lemma, in General.ddT]
+in_single [lemma, in General.gen]
+In_matters_remove_list [lemma, in Syntax.remove_list_lems]
+In_remove_list_remove_redund [lemma, in Syntax.remove_list_lems]
+In_remove_list_In_list_not_In_remove_list [lemma, in Syntax.remove_list_lems]
+In_remove_list_In_list [lemma, in Syntax.remove_list_lems]
+In_remove_In_list [lemma, in Syntax.remove_list_lems]
+In_remove_length_same [lemma, in Syntax.remove_list_lems]
+In_remove_same [lemma, in Syntax.remove_list_lems]
+In_remove_diff [lemma, in Syntax.remove_list_lems]
+in_remove_in_init [lemma, in Syntax.remove_list_lems]
+in_not_touched_remove [lemma, in Syntax.remove_list_lems]
+In_dec [definition, in Syntax.remove_list_lems]
+in_top_boxes [lemma, in GL.GLS.GLS_termination_measure]
+In_incl_subform_boxes [lemma, in GL.GLS.GLS_termination_measure]
+in_subform_boxesF_smaller_length_form [lemma, in GL.GLS.GLS_termination_measure]
+In_subform_boxesLF_box [lemma, in GL.GLS.GLS_termination_measure]
+In_subform_boxesF_box [lemma, in GL.GLS.GLS_termination_measure]
+In_n_imp_subformLF_is_non_0 [lemma, in GL.GLS.GLS_termination_measure]
+In_propvar_subform [lemma, in GL.Interpolation.UIGL_UI_prelims]
+In_subform_boxes [lemma, in GL.Interpolation.UIGL_UI_prelims]
+In_list_In_propvar_subform_list [lemma, in GL.Interpolation.UIGL_UI_prelims]
+In_list_In_list_prop_LF [lemma, in GL.Interpolation.UIGL_UI_prelims]
+In_list_prop_LF [lemma, in GL.Interpolation.UIGL_UI_prelims]
+In_l_imp_In_pos_top_imps [lemma, in K.KS.KS_termination_ImpR]
+In_pos_top_imps_split_l [definition, in K.KS.KS_termination_ImpR]
+In_pos_top_imps_In_l [lemma, in K.KS.KS_termination_ImpR]
+In_pos_top_imps_imp [lemma, in K.KS.KS_termination_ImpR]
+In_pos_top_imps_0_False [lemma, in K.KS.KS_termination_ImpR]
+in_top_boxes [definition, in GL.GLS.GLS_dec]
+In_InT_seqs [definition, in Syntax.list_lems]
+in_splitT [lemma, in Syntax.list_lems]
+in_exch_list [lemma, in Syntax.list_lems]
+In_InT [lemma, in General.genT]
+in_top_boxes [definition, in K.KS.KS_dec]
+In_open_boxes [lemma, in ISL.Environments]
+in_rm [lemma, in ISL.Environments]
+in_difference [lemma, in ISL.Environments]
+in_map_ext [lemma, in ISL.Environments]
+in_map_empty [lemma, in ISL.Environments]
+in_map_in [lemma, in ISL.Environments]
+in_subset [definition, in ISL.Environments]
+in_in_map [lemma, in ISL.Environments]
+in_map [definition, in ISL.Environments]
+in_map_aux [definition, in ISL.Environments]
+In_n_imp_subformLF_is_non_0 [lemma, in K.Interpolation.UIK_Canopy]
+In_Box_size_LF_is_non_0 [lemma, in K.KS.KS_termination_measure]
+In_Imp_size_LF_is_non_0 [lemma, in K.KS.KS_termination_measure]
+irred [definition, in K.Interpolation.UIK_irred_short]
+irred [section, in K.Interpolation.UIK_irred_short]
+irred [definition, in GL.Interpolation.UIGL_irred_short]
+irred [section, in GL.Interpolation.UIGL_irred_short]
+irreducible [definition, in ISL.Environments]
+irred_provability [lemma, in K.Interpolation.UIK_irred_high_level]
+irred_high_level.provability.HP [variable, in K.Interpolation.UIK_irred_high_level]
+irred_high_level.provability.P [variable, in K.Interpolation.UIK_irred_high_level]
+irred_high_level.provability [section, in K.Interpolation.UIK_irred_high_level]
+irred_high_level_spec [lemma, in K.Interpolation.UIK_irred_high_level]
+irred_reach [lemma, in K.Interpolation.UIK_irred_high_level]
+irred_max [lemma, in K.Interpolation.UIK_irred_high_level]
+irred_high_level.irred_not [variable, in K.Interpolation.UIK_irred_high_level]
+irred_high_level.irred_nil [variable, in K.Interpolation.UIK_irred_high_level]
+irred_high_level.irred [variable, in K.Interpolation.UIK_irred_high_level]
+irred_high_level.f_wf [variable, in K.Interpolation.UIK_irred_high_level]
+irred_high_level.f [variable, in K.Interpolation.UIK_irred_high_level]
+irred_high_level.X [variable, in K.Interpolation.UIK_irred_high_level]
+irred_high_level [section, in K.Interpolation.UIK_irred_high_level]
+irred_not [lemma, in K.Interpolation.UIK_irred_short]
+irred_nil [lemma, in K.Interpolation.UIK_irred_short]
+irred_spec [lemma, in K.Interpolation.UIK_irred_short]
+irred_provability [lemma, in GL.Interpolation.UIGL_irred_high_level]
+irred_high_level.provability.HP [variable, in GL.Interpolation.UIGL_irred_high_level]
+irred_high_level.provability.P [variable, in GL.Interpolation.UIGL_irred_high_level]
+irred_high_level.provability [section, in GL.Interpolation.UIGL_irred_high_level]
+irred_high_level_spec [lemma, in GL.Interpolation.UIGL_irred_high_level]
+irred_reach [lemma, in GL.Interpolation.UIGL_irred_high_level]
+irred_max [lemma, in GL.Interpolation.UIGL_irred_high_level]
+irred_high_level.irred_not [variable, in GL.Interpolation.UIGL_irred_high_level]
+irred_high_level.irred_nil [variable, in GL.Interpolation.UIGL_irred_high_level]
+irred_high_level.irred [variable, in GL.Interpolation.UIGL_irred_high_level]
+irred_high_level.f_wf [variable, in GL.Interpolation.UIGL_irred_high_level]
+irred_high_level.f [variable, in GL.Interpolation.UIGL_irred_high_level]
+irred_high_level.X [variable, in GL.Interpolation.UIGL_irred_high_level]
+irred_high_level [section, in GL.Interpolation.UIGL_irred_high_level]
+irred_not [lemma, in GL.Interpolation.UIGL_irred_short]
+irred_nil [lemma, in GL.Interpolation.UIGL_irred_short]
+irred_spec [lemma, in GL.Interpolation.UIGL_irred_short]
+irred.f [variable, in K.Interpolation.UIK_irred_short]
+irred.f [variable, in GL.Interpolation.UIGL_irred_short]
+irred.Girred_ind.HQ1 [variable, in K.Interpolation.UIK_irred_short]
+irred.Girred_ind.HQ0 [variable, in K.Interpolation.UIK_irred_short]
+irred.Girred_ind.HP1 [variable, in K.Interpolation.UIK_irred_short]
+irred.Girred_ind.HP0 [variable, in K.Interpolation.UIK_irred_short]
+irred.Girred_ind.Q [variable, in K.Interpolation.UIK_irred_short]
+irred.Girred_ind.P [variable, in K.Interpolation.UIK_irred_short]
+irred.Girred_ind [section, in K.Interpolation.UIK_irred_short]
+irred.Girred_ind.HQ1 [variable, in GL.Interpolation.UIGL_irred_short]
+irred.Girred_ind.HQ0 [variable, in GL.Interpolation.UIGL_irred_short]
+irred.Girred_ind.HP1 [variable, in GL.Interpolation.UIGL_irred_short]
+irred.Girred_ind.HP0 [variable, in GL.Interpolation.UIGL_irred_short]
+irred.Girred_ind.Q [variable, in GL.Interpolation.UIGL_irred_short]
+irred.Girred_ind.P [variable, in GL.Interpolation.UIGL_irred_short]
+irred.Girred_ind [section, in GL.Interpolation.UIGL_irred_short]
+irred.hf [variable, in K.Interpolation.UIK_irred_short]
+irred.hf [variable, in GL.Interpolation.UIGL_irred_short]
+irred.irred_pwc [variable, in K.Interpolation.UIK_irred_short]
+irred.irred_pwc [variable, in GL.Interpolation.UIGL_irred_short]
+irred.X [variable, in K.Interpolation.UIK_irred_short]
+irred.X [variable, in GL.Interpolation.UIGL_irred_short]
+irreflexive_form_order [instance, in ISL.Formulas]
+isl_simplified_A [definition, in UIML_extraction.UIML_extraction]
+isl_simplified_E [definition, in UIML_extraction.UIML_extraction]
+isl_simp [definition, in UIML_extraction.UIML_extraction]
+isl_A [definition, in UIML_extraction.UIML_extraction]
+isl_E [definition, in UIML_extraction.UIML_extraction]
+iSL_uniform_interpolation [lemma, in ISL.PropQuantifiers]
+is_init_UI [lemma, in K.Interpolation.UIK_UI_prelims]
+is_init_UI_equiv_Top [lemma, in K.Interpolation.UIK_UI_prelims]
+is_init_Canopy [lemma, in K.Interpolation.UIK_UI_prelims]
+is_init [definition, in K.Interpolation.UIK_basics]
+is_mhd [definition, in GL.GLS.GLS_der_dec]
+is_mhd [definition, in K.KS.KS_termination_prelims]
+is_box_weight_open_box [lemma, in ISL.SequentProps]
+is_Boxed_list_top_boxes [lemma, in Syntax.CML_Syntax]
+is_box_is_in_boxed_list [lemma, in Syntax.CML_Syntax]
+is_Prime [definition, in Syntax.CML_Syntax]
+is_Boxed_list [definition, in Syntax.CML_Syntax]
+is_boxedT [definition, in Syntax.CML_Syntax]
+is_atomicT [definition, in Syntax.CML_Syntax]
+is_nextup_ndt [lemma, in General.dd_fc]
+is_nextup_sind [definition, in General.dd_fc]
+is_nextup_rec [definition, in General.dd_fc]
+is_nextup_ind [definition, in General.dd_fc]
+is_nextup_rect [definition, in General.dd_fc]
+is_nextupI [constructor, in General.dd_fc]
+is_nextup [inductive, in General.dd_fc]
+is_init_nodupseq [lemma, in GL.Interpolation.UIGL_nodupseq]
+is_Prime_dec [definition, in GL.Interpolation.UIGL_Canopy]
+is_box_in_top_boxes [lemma, in GL.GLS.GLS_termination_measure]
+is_init_UI [lemma, in GL.Interpolation.UIGL_UI_prelims]
+is_init_UI_equiv_Top [lemma, in GL.Interpolation.UIGL_UI_prelims]
+is_init_Canopy [lemma, in GL.Interpolation.UIGL_UI_prelims]
+is_init [definition, in GL.Interpolation.UIGL_LexSeq]
+is_not_box_open_box [lemma, in ISL.Environments]
+is_box [definition, in ISL.Environments]
+is_negation [definition, in ISL.Environments]
+is_implication [definition, in ISL.Environments]
+is_double_negation [definition, in ISL.Environments]
+is_implication_obviously_smaller [lemma, in ISL.Optimizations]
+is_Prime_dec [definition, in K.Interpolation.UIK_Canopy]
+

K

+keep_list_delete_head_not_In [lemma, in Syntax.remove_list_lems]
+keep_list_delete_head_not_origin [lemma, in Syntax.remove_list_lems]
+KR [constructor, in K.KS.KS_calc]
+KRRule [inductive, in K.KS.KS_calc]
+KRRule_sind [definition, in K.KS.KS_calc]
+KRRule_rec [definition, in K.KS.KS_calc]
+KRRule_ind [definition, in K.KS.KS_calc]
+KRRule_rect [definition, in K.KS.KS_calc]
+KRRule_I [constructor, in K.KS.KS_calc]
+KR_app_ctr_R [lemma, in K.KS.KS_ctr]
+KR_app_ctr_L [lemma, in K.KS.KS_ctr]
+KR_app_wkn_R [lemma, in K.KS.KS_wkn]
+KR_app_wkn_L [lemma, in K.KS.KS_wkn]
+KR_prems_LtSeq [lemma, in K.Interpolation.UIK_basics]
+KR_prems [definition, in K.Interpolation.UIK_basics]
+KR_help2 [definition, in K.KS.KS_termination_KR]
+KR_help02 [definition, in K.KS.KS_termination_KR]
+KR_help1 [definition, in K.KS.KS_termination_KR]
+KR_help01 [definition, in K.KS.KS_termination_KR]
+KR_app_list_exchR [lemma, in K.KS.KS_exch_KR]
+KR_app_list_exchL [lemma, in K.KS.KS_exch_KR]
+KS_hpadm_list_ctr_R [lemma, in K.KS.KS_ctr]
+KS_hpadm_list_ctr_L [lemma, in K.KS.KS_ctr]
+KS_hpadm_ctr_R [lemma, in K.KS.KS_ctr]
+KS_hpadm_ctr_L [lemma, in K.KS.KS_ctr]
+KS_hpadm_ctr_LR [lemma, in K.KS.KS_ctr]
+KS_hpadm_ctr_LR0 [lemma, in K.KS.KS_ctr]
+KS_list_wkn_L [lemma, in K.KS.KS_wkn]
+KS_list_wkn_R [lemma, in K.KS.KS_wkn]
+KS_hpadm_wkn_R [lemma, in K.KS.KS_wkn]
+KS_wkn_R [lemma, in K.KS.KS_wkn]
+KS_hpadm_wkn_L [lemma, in K.KS.KS_wkn]
+KS_wkn_L [lemma, in K.KS.KS_wkn]
+KS_termin_der_is_mhd [lemma, in K.KS.KS_termination]
+KS_termin3 [lemma, in K.KS.KS_termination]
+KS_termin2 [lemma, in K.KS.KS_termination]
+KS_termin1 [lemma, in K.KS.KS_termination]
+KS_termin [lemma, in K.KS.KS_termination]
+KS_termin_base [lemma, in K.KS.KS_termination]
+KS_cut_elimination [lemma, in K.KS.KS_cut_elim]
+KS_cut_drv [definition, in K.KS.KS_cut_elim]
+KS_cut_prv [definition, in K.KS.KS_cut_elim]
+KS_cut_rules_sind [definition, in K.KS.KS_cut_elim]
+KS_cut_rules_rec [definition, in K.KS.KS_cut_elim]
+KS_cut_rules_ind [definition, in K.KS.KS_cut_elim]
+KS_cut_rules_rect [definition, in K.KS.KS_cut_elim]
+KS_cut [constructor, in K.KS.KS_cut_elim]
+KS_woc [constructor, in K.KS.KS_cut_elim]
+KS_cut_rules [inductive, in K.KS.KS_cut_elim]
+KS_cut_adm [lemma, in K.KS.KS_additive_cut]
+KS_cut_adm_main [lemma, in K.KS.KS_additive_cut]
+KS_drv [definition, in K.KS.KS_calc]
+KS_prv [definition, in K.KS.KS_calc]
+KS_rules_sind [definition, in K.KS.KS_calc]
+KS_rules_rec [definition, in K.KS.KS_calc]
+KS_rules_ind [definition, in K.KS.KS_calc]
+KS_rules_rect [definition, in K.KS.KS_calc]
+KS_rules [inductive, in K.KS.KS_calc]
+KS_adm_list_exch_LR [lemma, in K.KS.KS_exch]
+KS_hpadm_list_exch_R [lemma, in K.KS.KS_exch]
+KS_hpadm_list_exch_L [lemma, in K.KS.KS_exch]
+KS_hpadm_list_exch_L0 [lemma, in K.KS.KS_exch]
+KS_hpadm_list_exch_R0 [lemma, in K.KS.KS_exch]
+KS_der_list_exch_R [lemma, in K.KS.KS_exch]
+KS_der_list_exch_L [lemma, in K.KS.KS_exch]
+KS_adm_list_exch_R [lemma, in K.KS.KS_exch]
+KS_adm_list_exch_L [lemma, in K.KS.KS_exch]
+KS_exch_KR [library]
+KS_inv_ImpR_ImpL [library]
+KS_termination_measure [library]
+KS_dec [library]
+KS_termination_ImpR [library]
+KS_exch_ImpR [library]
+KS_ctr [library]
+KS_termination_init [library]
+KS_exch [library]
+KS_calc [library]
+KS_export [library]
+KS_termination [library]
+KS_additive_cut [library]
+KS_exch_ImpL [library]
+KS_cut_elim [library]
+KS_exch_prelims [library]
+KS_termination_ImpL [library]
+KS_wkn [library]
+KS_termination_KR [library]
+KS_termination_prelims [library]
+k_UI [definition, in UIML_extraction.UIML_extraction]
+K_Craig_Interp [library]
+

L

+length_le_remove_list [lemma, in Syntax.remove_list_lems]
+length_usable_boxes_is_0 [lemma, in GL.GLS.GLS_termination_measure]
+length_form [definition, in GL.GLS.GLS_termination_measure]
+leq_ub_Canopy [lemma, in GL.Interpolation.UIGL_LexSeq]
+leq_ub_unif [lemma, in GL.Interpolation.UIGL_LexSeq]
+less_imp [definition, in GL.Interpolation.UIGL_Canopy]
+less_thanS_strong_inductionT [lemma, in GL.GLS.GLS_termination_measure]
+less_thanS_trans [lemma, in GL.GLS.GLS_termination_measure]
+less_thanS_wf [lemma, in GL.GLS.GLS_termination_measure]
+less_thanS_inv [lemma, in GL.GLS.GLS_termination_measure]
+less_thanS [definition, in GL.GLS.GLS_termination_measure]
+less_ub_witness [lemma, in GL.Interpolation.UIGL_UI_prelims]
+less_imp [definition, in K.Interpolation.UIK_Canopy]
+leT [inductive, in General.genT]
+leT_ex_plus [lemma, in General.genT]
+leT_or_gt [lemma, in General.genT]
+leT_S_or_eq [lemma, in General.genT]
+leT_S_F [lemma, in General.genT]
+leT_plus_l [lemma, in General.genT]
+leT_plus_r [lemma, in General.genT]
+leT_0_n [lemma, in General.genT]
+leT_trans [definition, in General.genT]
+leT_trans' [lemma, in General.genT]
+leT_S_n [definition, in General.genT]
+leT_S_n' [lemma, in General.genT]
+leT_n_S [lemma, in General.genT]
+leT_sind [definition, in General.genT]
+leT_rec [definition, in General.genT]
+leT_ind [definition, in General.genT]
+leT_rect [definition, in General.genT]
+leT_S [constructor, in General.genT]
+leT_n [constructor, in General.genT]
+lex [inductive, in K.Interpolation.UIK_Def_measure]
+lex [inductive, in GL.GLS.DLW_wf_lex]
+lex [inductive, in GL.Interpolation.UIGL_Def_measure]
+LexSeq [definition, in GL.Interpolation.UIGL_LexSeq]
+LexSeq_nodupseq_case [lemma, in GL.Interpolation.UIGL_nodupseq]
+LexSeq_nodupseq [lemma, in GL.Interpolation.UIGL_nodupseq]
+LexSeq_trans [lemma, in GL.Interpolation.UIGL_LexSeq]
+LexSeq_properties [section, in GL.Interpolation.UIGL_LexSeq]
+LexSeq_ind [definition, in GL.Interpolation.UIGL_LexSeq]
+LexSeq_ind.P [variable, in GL.Interpolation.UIGL_LexSeq]
+LexSeq_ind [section, in GL.Interpolation.UIGL_LexSeq]
+lex_rect [lemma, in K.Interpolation.UIK_Def_measure]
+lex_wf.lex_rect.HP [variable, in K.Interpolation.UIK_Def_measure]
+lex_wf.lex_rect.P [variable, in K.Interpolation.UIK_Def_measure]
+lex_wf.lex_rect [section, in K.Interpolation.UIK_Def_measure]
+lex_wf [lemma, in K.Interpolation.UIK_Def_measure]
+lex_cons_inv [lemma, in K.Interpolation.UIK_Def_measure]
+lex_length [lemma, in K.Interpolation.UIK_Def_measure]
+_ <lex _ [notation, in K.Interpolation.UIK_Def_measure]
+lex_sind [definition, in K.Interpolation.UIK_Def_measure]
+lex_ind [definition, in K.Interpolation.UIK_Def_measure]
+lex_cons [constructor, in K.Interpolation.UIK_Def_measure]
+lex_skip [constructor, in K.Interpolation.UIK_Def_measure]
+lex_wf.Rwf [variable, in K.Interpolation.UIK_Def_measure]
+lex_wf.R [variable, in K.Interpolation.UIK_Def_measure]
+lex_wf.X [variable, in K.Interpolation.UIK_Def_measure]
+lex_wf [section, in K.Interpolation.UIK_Def_measure]
+lex_trans [lemma, in GL.GLS.GLS_termination_measure]
+lex_wf [lemma, in GL.GLS.DLW_wf_lex]
+lex_cons_inv [lemma, in GL.GLS.DLW_wf_lex]
+lex_length [lemma, in GL.GLS.DLW_wf_lex]
+_ <lex _ [notation, in GL.GLS.DLW_wf_lex]
+lex_sind [definition, in GL.GLS.DLW_wf_lex]
+lex_ind [definition, in GL.GLS.DLW_wf_lex]
+lex_cons [constructor, in GL.GLS.DLW_wf_lex]
+lex_skip [constructor, in GL.GLS.DLW_wf_lex]
+lex_wf.Rwf [variable, in GL.GLS.DLW_wf_lex]
+lex_wf.R [variable, in GL.GLS.DLW_wf_lex]
+lex_wf.X [variable, in GL.GLS.DLW_wf_lex]
+lex_wf [section, in GL.GLS.DLW_wf_lex]
+lex_rect [lemma, in GL.Interpolation.UIGL_Def_measure]
+lex_wf.lex_rect.HP [variable, in GL.Interpolation.UIGL_Def_measure]
+lex_wf.lex_rect.P [variable, in GL.Interpolation.UIGL_Def_measure]
+lex_wf.lex_rect [section, in GL.Interpolation.UIGL_Def_measure]
+lex_wf [lemma, in GL.Interpolation.UIGL_Def_measure]
+lex_cons_inv [lemma, in GL.Interpolation.UIGL_Def_measure]
+lex_length [lemma, in GL.Interpolation.UIGL_Def_measure]
+_ <lex _ [notation, in GL.Interpolation.UIGL_Def_measure]
+lex_sind [definition, in GL.Interpolation.UIGL_Def_measure]
+lex_ind [definition, in GL.Interpolation.UIGL_Def_measure]
+lex_cons [constructor, in GL.Interpolation.UIGL_Def_measure]
+lex_skip [constructor, in GL.Interpolation.UIGL_Def_measure]
+lex_wf.Rwf [variable, in GL.Interpolation.UIGL_Def_measure]
+lex_wf.R [variable, in GL.Interpolation.UIGL_Def_measure]
+lex_wf.X [variable, in GL.Interpolation.UIGL_Def_measure]
+lex_wf [section, in GL.Interpolation.UIGL_Def_measure]
+le_False_lt [lemma, in GL.GLS.GLS_der_dec]
+le_False_lt [lemma, in K.KS.KS_termination_prelims]
+le_dersrec_height [lemma, in General.dd_fc]
+Lindenbaum_Tarski_preorder_Bot [lemma, in ISL.Optimizations]
+Lindenbaum_Tarski_preorder [definition, in ISL.Optimizations]
+listInserts [definition, in GL.GLS.GLS_der_dec]
+listInserts [definition, in K.KS.KS_termination_prelims]
+listInsertsL_Seqs [definition, in GL.GLS.GLS_der_dec]
+listInsertsL_Seqs [definition, in K.KS.KS_termination_prelims]
+listInsertsRL_Seqs [definition, in GL.GLS.GLS_der_dec]
+listInsertsRL_Seqs [definition, in K.KS.KS_termination_prelims]
+listInsertsR_Seqs [definition, in GL.GLS.GLS_der_dec]
+listInsertsR_Seqs [definition, in K.KS.KS_termination_prelims]
+listInserts_In [lemma, in GL.GLS.GLS_der_dec]
+listInserts_In [lemma, in K.KS.KS_termination_prelims]
+list_is_nil [definition, in K.Interpolation.UIK_irred_high_level]
+list_of_premises [definition, in K.KS.KS_termination]
+list_disj_wkn_R [lemma, in K.Interpolation.UIK_UI_prelims]
+list_disj_L [lemma, in K.Interpolation.UIK_UI_prelims]
+list_conj_R [lemma, in K.Interpolation.UIK_UI_prelims]
+list_conj_wkn_L [lemma, in K.Interpolation.UIK_UI_prelims]
+list_conj_disj_properties [section, in K.Interpolation.UIK_UI_prelims]
+list_prop_LF_propvar_subform_list [lemma, in K.Interpolation.UIK_UI_prelims]
+list_prop_LF_In [lemma, in K.Interpolation.UIK_basics]
+list_prop_LF [definition, in K.Interpolation.UIK_basics]
+list_prop_F [definition, in K.Interpolation.UIK_basics]
+list_disj [definition, in K.Interpolation.UIK_basics]
+list_conj [definition, in K.Interpolation.UIK_basics]
+list_of_premises [definition, in GL.GLS.GLS_der_dec]
+list_of_splits [definition, in GL.GLS.GLS_der_dec]
+list_of_splits [definition, in K.KS.KS_termination_prelims]
+list_prop_LF_In [lemma, in GL.Interpolation.UIGL_basics]
+list_prop_LF [definition, in GL.Interpolation.UIGL_basics]
+list_prop_F [definition, in GL.Interpolation.UIGL_basics]
+list_disj [definition, in GL.Interpolation.UIGL_basics]
+list_conj [definition, in GL.Interpolation.UIGL_basics]
+list_disj_wkn_R [lemma, in GL.Interpolation.UIGL_And_Or_rules]
+list_disj_L [lemma, in GL.Interpolation.UIGL_And_Or_rules]
+list_conj_R [lemma, in GL.Interpolation.UIGL_And_Or_rules]
+list_conj_wkn_L [lemma, in GL.Interpolation.UIGL_And_Or_rules]
+list_conj_disj_properties [section, in GL.Interpolation.UIGL_And_Or_rules]
+list_preserv_XBoxed_list [lemma, in GL.GLS.GLS_calcs]
+list_exch_L_permLR [lemma, in K.KS.KS_exch_prelims]
+list_exch_L_permR [lemma, in K.KS.KS_exch_prelims]
+list_exch_L_permL [lemma, in K.KS.KS_exch_prelims]
+list_exch_R_permLR [lemma, in K.KS.KS_exch_prelims]
+list_exch_R_permR [lemma, in K.KS.KS_exch_prelims]
+list_exch_R_permL [lemma, in K.KS.KS_exch_prelims]
+list_exch_L_same_R [lemma, in K.KS.KS_exch_prelims]
+list_exch_R_same_L [lemma, in K.KS.KS_exch_prelims]
+list_exch_L_id [lemma, in K.KS.KS_exch_prelims]
+list_exch_R_id [lemma, in K.KS.KS_exch_prelims]
+list_exch_R_sind [definition, in K.KS.KS_exch_prelims]
+list_exch_R_rec [definition, in K.KS.KS_exch_prelims]
+list_exch_R_ind [definition, in K.KS.KS_exch_prelims]
+list_exch_R_rect [definition, in K.KS.KS_exch_prelims]
+list_exch_RI [constructor, in K.KS.KS_exch_prelims]
+list_exch_R [inductive, in K.KS.KS_exch_prelims]
+list_exch_L_sind [definition, in K.KS.KS_exch_prelims]
+list_exch_L_rec [definition, in K.KS.KS_exch_prelims]
+list_exch_L_ind [definition, in K.KS.KS_exch_prelims]
+list_exch_L_rect [definition, in K.KS.KS_exch_prelims]
+list_exch_LI [constructor, in K.KS.KS_exch_prelims]
+list_exch_L [inductive, in K.KS.KS_exch_prelims]
+list_prop_LF_In [lemma, in GL.Interpolation.UIGL_UI_prelims]
+list_prop_LF_propvar_subform_list [lemma, in GL.Interpolation.UIGL_UI_prelims]
+list_exch_R_BotL_notapplic [lemma, in GL.GLS.GLS_exch]
+list_exch_R_IdB_notapplic [lemma, in GL.GLS.GLS_exch]
+list_exch_R_IdP_notapplic [lemma, in GL.GLS.GLS_exch]
+list_exch_L_BotL_notapplic [lemma, in GL.GLS.GLS_exch]
+list_exch_L_IdB_notapplic [lemma, in GL.GLS.GLS_exch]
+list_exch_L_IdP_notapplic [lemma, in GL.GLS.GLS_exch]
+list_exch_L_permLR [lemma, in GL.GLS.GLS_exch]
+list_exch_L_permR [lemma, in GL.GLS.GLS_exch]
+list_exch_L_permL [lemma, in GL.GLS.GLS_exch]
+list_exch_R_permLR [lemma, in GL.GLS.GLS_exch]
+list_exch_R_permR [lemma, in GL.GLS.GLS_exch]
+list_exch_R_permL [lemma, in GL.GLS.GLS_exch]
+list_exch_L_same_R [lemma, in GL.GLS.GLS_exch]
+list_exch_R_same_L [lemma, in GL.GLS.GLS_exch]
+list_exch_L_id [lemma, in GL.GLS.GLS_exch]
+list_exch_R_id [lemma, in GL.GLS.GLS_exch]
+list_exch_R_sind [definition, in GL.GLS.GLS_exch]
+list_exch_R_rec [definition, in GL.GLS.GLS_exch]
+list_exch_R_ind [definition, in GL.GLS.GLS_exch]
+list_exch_R_rect [definition, in GL.GLS.GLS_exch]
+list_exch_RI [constructor, in GL.GLS.GLS_exch]
+list_exch_R [inductive, in GL.GLS.GLS_exch]
+list_exch_L_sind [definition, in GL.GLS.GLS_exch]
+list_exch_L_rec [definition, in GL.GLS.GLS_exch]
+list_exch_L_ind [definition, in GL.GLS.GLS_exch]
+list_exch_L_rect [definition, in GL.GLS.GLS_exch]
+list_exch_LI [constructor, in GL.GLS.GLS_exch]
+list_exch_L [inductive, in GL.GLS.GLS_exch]
+list_is_nil [definition, in K.Interpolation.UIK_irred_short]
+list_nil_or_tail_singleton [lemma, in General.List_lemmasT]
+list_insert1 [lemma, in General.List_lemmasT]
+list_eq_singleT_nobrac [lemma, in General.List_lemmasT]
+list_eq_singleT [lemma, in General.List_lemmasT]
+list_eq_single [lemma, in General.List_lemmasT]
+list_eq_nil [lemma, in General.List_lemmasT]
+list_rearr23 [lemma, in General.List_lemmasT]
+list_rearr22 [lemma, in General.List_lemmasT]
+list_rearr21 [lemma, in General.List_lemmasT]
+list_rearr20 [lemma, in General.List_lemmasT]
+list_rearr19 [lemma, in General.List_lemmasT]
+list_rearr18 [lemma, in General.List_lemmasT]
+list_rearr17_R [lemma, in General.List_lemmasT]
+list_rearr16_R [lemma, in General.List_lemmasT]
+list_rearr16 [lemma, in General.List_lemmasT]
+list_rearr16' [lemma, in General.List_lemmasT]
+list_rearr15_R [lemma, in General.List_lemmasT]
+list_rearr15 [lemma, in General.List_lemmasT]
+list_rearr14 [lemma, in General.List_lemmasT]
+list_rearr13 [lemma, in General.List_lemmasT]
+list_rearr11 [lemma, in General.List_lemmasT]
+list_rearr10 [lemma, in General.List_lemmasT]
+list_rearr9 [lemma, in General.List_lemmasT]
+list_rearr8 [lemma, in General.List_lemmasT]
+list_rearr7 [lemma, in General.List_lemmasT]
+list_rearr6 [lemma, in General.List_lemmasT]
+list_rearr5 [lemma, in General.List_lemmasT]
+list_rearr4 [lemma, in General.List_lemmasT]
+list_rearr2 [lemma, in General.List_lemmasT]
+list_rearr1 [lemma, in General.List_lemmasT]
+list_is_nil [definition, in GL.Interpolation.UIGL_irred_high_level]
+list_split_form [lemma, in Syntax.list_lems]
+list_to_set_disj_open_boxes [lemma, in ISL.Environments]
+list_to_set_disj_rm [lemma, in ISL.Environments]
+list_to_set_disj_env_add [lemma, in ISL.Environments]
+list_is_nil [definition, in GL.Interpolation.UIGL_irred_short]
+List_lemmasT [library]
+list_lems [library]
+LogDefinition [section, in GL.Interpolation.UIGL_LexSeq]
+logic [section, in GL.Interpolation.UIGL_UI_prelims]
+Logic_Abrv [section, in K.Interpolation.UIK_basics]
+Logic_Abrv [section, in GL.Interpolation.UIGL_basics]
+LtSeq [definition, in K.Interpolation.UIK_basics]
+LtSeq_trans [lemma, in K.Interpolation.UIK_basics]
+LtSeq_properties [section, in K.Interpolation.UIK_basics]
+LtSeq_ind [definition, in K.Interpolation.UIK_basics]
+LtSeq_ind.P [variable, in K.Interpolation.UIK_basics]
+LtSeq_ind [section, in K.Interpolation.UIK_basics]
+lt_decT [lemma, in K.Interpolation.UIK_basics]
+

M

+make_conj_comm_ctx_L [lemma, in ISL.Simp]
+make_conj_comm_ctx_R [lemma, in ISL.Simp]
+make_conj_comm [lemma, in ISL.Simp]
+make_disj_comm_ctx_L [lemma, in ISL.Simp]
+make_disj_comm_ctx_R [lemma, in ISL.Simp]
+make_disj_comm [lemma, in ISL.Simp]
+make_impl [definition, in ISL.Environments]
+make_disj [definition, in ISL.Environments]
+make_conj [definition, in ISL.Environments]
+make_impl_complete_R [lemma, in ISL.Optimizations]
+make_impl_complete_L2 [lemma, in ISL.Optimizations]
+make_impl_complete_L [lemma, in ISL.Optimizations]
+make_impl_sound_L2' [lemma, in ISL.Optimizations]
+make_impl_sound_L2 [lemma, in ISL.Optimizations]
+make_impl_sound_R [lemma, in ISL.Optimizations]
+make_impl_sound_L [lemma, in ISL.Optimizations]
+make_disj_complete_R [lemma, in ISL.Optimizations]
+make_disj_sound_R [lemma, in ISL.Optimizations]
+make_disj_complete_L [lemma, in ISL.Optimizations]
+make_disj_sound_L [lemma, in ISL.Optimizations]
+make_disj_equiv_R [lemma, in ISL.Optimizations]
+make_disj_equiv_L [lemma, in ISL.Optimizations]
+make_conj_complete_R [lemma, in ISL.Optimizations]
+make_conj_sound_R [lemma, in ISL.Optimizations]
+make_conj_complete_L [lemma, in ISL.Optimizations]
+make_conj_sound_L [lemma, in ISL.Optimizations]
+make_conj_equiv_R [lemma, in ISL.Optimizations]
+make_conj_equiv_L [lemma, in ISL.Optimizations]
+map_fmlsext_fmlsext [lemma, in General.gen_seq]
+map_seqext_seqext [lemma, in General.gen_seq]
+map_eq_nil [lemma, in General.gen]
+map_app_ex [lemma, in General.gen]
+map_cons_ex' [lemma, in General.gen]
+map_cons_ex [lemma, in General.gen]
+measure [definition, in General.gentree]
+measure [definition, in GL.GLS.GLS_termination_measure]
+measure [definition, in GL.Interpolation.UIGL_LexSeq]
+measure [definition, in K.KS.KS_termination_measure]
+measure_rect [definition, in K.Interpolation.UIK_Def_measure]
+measure_rect.F [variable, in K.Interpolation.UIK_Def_measure]
+measure_rect.P [variable, in K.Interpolation.UIK_Def_measure]
+measure_rect.m [variable, in K.Interpolation.UIK_Def_measure]
+measure_rect.X [variable, in K.Interpolation.UIK_Def_measure]
+measure_rect [section, in K.Interpolation.UIK_Def_measure]
+measure_rect [definition, in GL.GLS.DLW_wf_lex]
+measure_rect.F [variable, in GL.GLS.DLW_wf_lex]
+measure_rect.P [variable, in GL.GLS.DLW_wf_lex]
+measure_rect.m [variable, in GL.GLS.DLW_wf_lex]
+measure_rect.X [variable, in GL.GLS.DLW_wf_lex]
+measure_rect [section, in GL.GLS.DLW_wf_lex]
+measure_rect [definition, in GL.Interpolation.UIGL_Def_measure]
+measure_rect.F [variable, in GL.Interpolation.UIGL_Def_measure]
+measure_rect.P [variable, in GL.Interpolation.UIGL_Def_measure]
+measure_rect.m [variable, in GL.Interpolation.UIGL_Def_measure]
+measure_rect.X [variable, in GL.Interpolation.UIGL_Def_measure]
+measure_rect [section, in GL.Interpolation.UIGL_Def_measure]
+measure_is_0 [lemma, in K.KS.KS_termination_measure]
+mhd [definition, in K.KS.KS_termination]
+midI [lemma, in General.gen_tacs]
+MPropF [inductive, in Syntax.CML_Syntax]
+MPropF_sind [definition, in Syntax.CML_Syntax]
+MPropF_rec [definition, in Syntax.CML_Syntax]
+MPropF_ind [definition, in Syntax.CML_Syntax]
+MPropF_rect [definition, in Syntax.CML_Syntax]
+MPropF_of_form [definition, in UIML_extraction.UIML_extraction]
+multeq_meq [lemma, in ISL.Environments]
+mult_ImpR [lemma, in GL.Interpolation.UIGL_Canopy_ImpR]
+mult_ImpL_L [lemma, in GL.Interpolation.UIGL_Canopy_ImpL]
+mult_ImpL_R [lemma, in GL.Interpolation.UIGL_Canopy_ImpL]
+

N

+N [definition, in GL.Interpolation.UIGL_braga]
+N [section, in GL.Interpolation.UIGL_braga]
+Neg [definition, in Syntax.CML_Syntax]
+nextup [definition, in General.dd_fc]
+nextup_height [lemma, in General.dd_fc]
+nextup_in_nu_fc [definition, in General.dd_fc]
+nextup_in_nu [definition, in General.dd_fc]
+nextup_height [lemma, in General.gentree]
+nextup_size [lemma, in General.gentree]
+nil_eq_appT [definition, in General.List_lemmasT]
+nil_eq_app [definition, in General.List_lemmasT]
+nil_eq_list [definition, in General.List_lemmasT]
+nnn_app_eq [lemma, in General.List_lemmasT]
+nobox_top_boxes [lemma, in K.Interpolation.UIK_UI_prelims]
+nobox_gen_ext_top_boxes_identity [lemma, in GL.GLS.GLS_der_dec]
+nobox_gen_ext_top_boxes_identity [lemma, in K.KS.KS_termination_prelims]
+nobox_gen_ext_top_boxes [lemma, in Syntax.CML_Syntax]
+nobox_gen_ext_injective [lemma, in Syntax.CML_Syntax]
+nobox_gen_ext [definition, in Syntax.CML_Syntax]
+nobox_gen_ext_exch_L [lemma, in K.KS.KS_exch_prelims]
+nobox_gen_ext_exch_R [lemma, in K.KS.KS_exch_prelims]
+nobox_top_boxes [lemma, in GL.Interpolation.UIGL_UI_prelims]
+nobox_gen_ext_exch_L [lemma, in GL.GLS.GLS_exch]
+nobox_gen_ext_exch_R [lemma, in GL.GLS.GLS_exch]
+nodupseq [definition, in GL.Interpolation.UIGL_nodupseq]
+nodupseq [section, in GL.Interpolation.UIGL_nodupseq]
+nodupseq_prv_hpadm_RL [lemma, in GL.Interpolation.UIGL_nodupseq]
+nodupseq_prv_hpadm_LR [lemma, in GL.Interpolation.UIGL_nodupseq]
+nodupseq_prv [lemma, in GL.Interpolation.UIGL_nodupseq]
+nodupseq_hpadm_prv_RL [lemma, in GL.Interpolation.UIGL_nodupseq]
+nodupseq_hpadm_prv_LR [lemma, in GL.Interpolation.UIGL_nodupseq]
+nodupseq_id [lemma, in GL.Interpolation.UIGL_nodupseq]
+nodupseq_GLR_prems [lemma, in GL.Interpolation.UIGL_nodupseq]
+nodup_length [lemma, in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+nodup_id [lemma, in GL.Interpolation.UIGL_nodupseq]
+nodup_XBoxed_list [lemma, in GL.Interpolation.UIGL_nodupseq]
+nodup_top_boxes [lemma, in GL.Interpolation.UIGL_nodupseq]
+nodup_nil [lemma, in GL.Interpolation.UIGL_nodupseq]
+nodup_app [lemma, in GL.Interpolation.UIGL_nodupseq]
+NoDup_destr_split [lemma, in Syntax.remove_list_lems]
+NoDup_usable_boxes [lemma, in GL.GLS.GLS_termination_measure]
+NoDup_subform_boxesS [lemma, in GL.GLS.GLS_termination_measure]
+NoDup_subform_boxesLF [lemma, in GL.GLS.GLS_termination_measure]
+NoDup_subform_boxesF [lemma, in GL.GLS.GLS_termination_measure]
+NoDup_incl_lengthT [lemma, in GL.GLS.GLS_termination_measure]
+nodup_facts [section, in GL.Interpolation.UIGL_UI_prelims]
+NoDup_incl_lengthT [lemma, in K.KS.KS_termination_measure]
+nolessub_In [lemma, in GL.Interpolation.UIGL_UI_prelims]
+noless_ub_incl_subform_boxesS [lemma, in GL.Interpolation.UIGL_Diam_UI_imp_N_prelim]
+non_empty [definition, in General.List_lemmasT]
+notin_replace [lemma, in GL.Interpolation.UIGL_Canopy_ImpR]
+not_init_empty_set [lemma, in K.Interpolation.UIK_basics]
+not_removed_remove_list [lemma, in Syntax.remove_list_lems]
+not_init_empty_seq [lemma, in GL.Interpolation.UIGL_LexSeq]
+no_usable_boxes_all_RHS_are_LHS [lemma, in GL.GLS.GLS_termination_measure]
+no_RHS_box_no_GLR [lemma, in GL.GLS.GLS_termination_measure]
+no_KS_rule_applic [lemma, in K.KS.KS_termination_measure]
+nth_split_length_id [lemma, in GL.GLS.GLS_der_dec]
+nth_split_idR [lemma, in GL.GLS.GLS_der_dec]
+nth_split_idL [lemma, in GL.GLS.GLS_der_dec]
+nth_split_length [lemma, in GL.GLS.GLS_der_dec]
+nth_split [definition, in GL.GLS.GLS_der_dec]
+nth_split_length_id [lemma, in K.KS.KS_termination_prelims]
+nth_split_idR [lemma, in K.KS.KS_termination_prelims]
+nth_split_idL [lemma, in K.KS.KS_termination_prelims]
+nth_split_length [lemma, in K.KS.KS_termination_prelims]
+nth_split [definition, in K.KS.KS_termination_prelims]
+N_spec [lemma, in GL.Interpolation.UIGL_braga]
+N_pwc [definition, in GL.Interpolation.UIGL_braga]
+n_imp_subformS_ImpR_mult [lemma, in GL.Interpolation.UIGL_Canopy_ImpR]
+n_imp_subformLF_replace [lemma, in GL.Interpolation.UIGL_Canopy_ImpR]
+n_imp_subformS_nodupseq [lemma, in GL.Interpolation.UIGL_nodupseq]
+n_imp_subformLF_nodup [lemma, in GL.Interpolation.UIGL_nodupseq]
+n_imp_subformLF_dist_app [lemma, in GL.GLS.GLS_termination_measure]
+n_imp_subformS_is_0 [lemma, in GL.GLS.GLS_termination_measure]
+n_imp_subformS [definition, in GL.GLS.GLS_termination_measure]
+n_imp_subformLF [definition, in GL.GLS.GLS_termination_measure]
+n_imp_subformF [definition, in GL.GLS.GLS_termination_measure]
+N_nodupseq [lemma, in GL.Interpolation.UIGL_UI_inter]
+n_imp_unboxed [lemma, in K.Interpolation.UIK_Canopy]
+n_imp_nobox_gen_ext [lemma, in K.Interpolation.UIK_Canopy]
+n_imp_subformLF_dist_app [lemma, in K.Interpolation.UIK_Canopy]
+n_imp_subformS_is_0 [lemma, in K.Interpolation.UIK_Canopy]
+n_imp_subformS [definition, in K.Interpolation.UIK_Canopy]
+n_imp_subformLF [definition, in K.Interpolation.UIK_Canopy]
+n_imp_subformF [definition, in K.Interpolation.UIK_Canopy]
+N.p [variable, in GL.Interpolation.UIGL_braga]
+

O

+obviously_smaller [definition, in ISL.Environments]
+obviously_smaller_compatible_GT [lemma, in ISL.Optimizations]
+obviously_smaller_compatible_LT [lemma, in ISL.Optimizations]
+occurs_in_map_open_box [lemma, in ISL.Environments]
+occurs_in_open_boxes [lemma, in ISL.Environments]
+occurs_in_make_impl2 [lemma, in ISL.Environments]
+occurs_in_make_impl [lemma, in ISL.Environments]
+occurs_in_make_disj [lemma, in ISL.Environments]
+occurs_in_make_conj [lemma, in ISL.Environments]
+occurs_in [definition, in ISL.Formulas]
+openboxes_env_order [lemma, in ISL.Order]
+open_boxes_case [lemma, in ISL.SequentProps]
+open_boxes_R [lemma, in ISL.SequentProps]
+open_box_L [lemma, in ISL.SequentProps]
+open_boxes_env_order [lemma, in ISL.Order]
+open_boxes_spec' [lemma, in ISL.Environments]
+open_boxes_spec [lemma, in ISL.Environments]
+open_boxes_remove [lemma, in ISL.Environments]
+open_boxes_add [lemma, in ISL.Environments]
+open_boxes_singleton [lemma, in ISL.Environments]
+open_boxes_disj_union [lemma, in ISL.Environments]
+open_boxes_empty [lemma, in ISL.Environments]
+open_boxes [definition, in ISL.Environments]
+open_box [definition, in ISL.Environments]
+Optimizations [library]
+Or [definition, in Syntax.CML_Syntax]
+Or [constructor, in ISL.Formulas]
+Order [library]
+OrL [constructor, in ISL.Sequents]
+OrL [lemma, in K.Interpolation.UIK_UI_prelims]
+OrL [lemma, in GL.Interpolation.UIGL_And_Or_rules]
+OrL_inv [lemma, in GL.Interpolation.UIGL_And_Or_rules]
+OrL_rev [lemma, in ISL.SequentProps]
+OrR [lemma, in K.Interpolation.UIK_UI_prelims]
+OrR [lemma, in GL.Interpolation.UIGL_And_Or_rules]
+OrR_inv [lemma, in GL.Interpolation.UIGL_And_Or_rules]
+OrR_idemp [lemma, in ISL.Optimizations]
+OrR1 [constructor, in ISL.Sequents]
+OrR1Bot_rev [lemma, in ISL.SequentProps]
+OrR2 [constructor, in ISL.Sequents]
+OrR2Bot_rev [lemma, in ISL.SequentProps]
+or_assoc_ctx_R_R [lemma, in ISL.Simp]
+or_assoc_ctx_R_L [lemma, in ISL.Simp]
+or_assoc_ctx_L_R [lemma, in ISL.Simp]
+or_assoc_L [lemma, in ISL.Simp]
+or_assoc_R [lemma, in ISL.Simp]
+or_comm_ctx_R [lemma, in ISL.Simp]
+or_comm_ctx_L [lemma, in ISL.Simp]
+or_comm [lemma, in ISL.Simp]
+or_false [lemma, in General.gen]
+or_congruence [lemma, in ISL.Optimizations]
+

P

+pair_eqI [lemma, in General.gen]
+partition_singleton_app [lemma, in General.List_lemmasT]
+partition_2_3 [lemma, in General.List_lemmasT]
+partition_3_2 [lemma, in General.List_lemmasT]
+partition_2_2T [lemma, in General.List_lemmasT]
+partition_2_2 [lemma, in General.List_lemmasT]
+partition_1_element2 [lemma, in Syntax.list_lems]
+partition_1_element [lemma, in Syntax.list_lems]
+permT_trans [constructor, in GL.Interpolation.UIGL_PermutationT]
+permT_swap [constructor, in GL.Interpolation.UIGL_PermutationT]
+permT_skip [constructor, in GL.Interpolation.UIGL_PermutationT]
+permT_nil [constructor, in GL.Interpolation.UIGL_PermutationT]
+PermutationT [inductive, in GL.Interpolation.UIGL_PermutationT]
+PermutationT [section, in GL.Interpolation.UIGL_PermutationT]
+PermutationTS [definition, in GL.Interpolation.UIGL_PermutationTS]
+PermutationTS_nodupseq [lemma, in GL.Interpolation.UIGL_nodupseq]
+PermutationTS_Canopy [lemma, in GL.Interpolation.UIGL_PermutationTS]
+PermutationTS_usable_boxes [lemma, in GL.Interpolation.UIGL_PermutationTS]
+PermutationTS_critic [lemma, in GL.Interpolation.UIGL_PermutationTS]
+PermutationTS_is_init [lemma, in GL.Interpolation.UIGL_PermutationTS]
+PermutationTS_GLR_prems [lemma, in GL.Interpolation.UIGL_PermutationTS]
+PermutationTS_restr_list_prop_fst [lemma, in GL.Interpolation.UIGL_PermutationTS]
+PermutationTS_restr_list_prop_snd [lemma, in GL.Interpolation.UIGL_PermutationTS]
+PermutationTS_prv [lemma, in GL.Interpolation.UIGL_PermutationTS]
+PermutationTS_prv_hpadm [lemma, in GL.Interpolation.UIGL_PermutationTS]
+PermutationTS_sym [lemma, in GL.Interpolation.UIGL_PermutationTS]
+PermutationTS_UI [lemma, in GL.Interpolation.UIGL_UI_inter]
+PermutationT_ind_T [lemma, in GL.Interpolation.UIGL_PermutationT]
+PermutationT_cons_app [lemma, in GL.Interpolation.UIGL_PermutationT]
+PermutationT_app_comm [lemma, in GL.Interpolation.UIGL_PermutationT]
+PermutationT_cons_append [lemma, in GL.Interpolation.UIGL_PermutationT]
+PermutationT_app [lemma, in GL.Interpolation.UIGL_PermutationT]
+PermutationT_app_head [lemma, in GL.Interpolation.UIGL_PermutationT]
+PermutationT_app_tail [lemma, in GL.Interpolation.UIGL_PermutationT]
+PermutationT_sym [lemma, in GL.Interpolation.UIGL_PermutationT]
+PermutationT_refl [lemma, in GL.Interpolation.UIGL_PermutationT]
+PermutationT_sind [definition, in GL.Interpolation.UIGL_PermutationT]
+PermutationT_rec [definition, in GL.Interpolation.UIGL_PermutationT]
+PermutationT_ind [definition, in GL.Interpolation.UIGL_PermutationT]
+PermutationT_rect [definition, in GL.Interpolation.UIGL_PermutationT]
+PermutationT_nodupseq [lemma, in GL.Interpolation.UIGL_PermutationTS]
+PermutationT_top_boxes [lemma, in GL.Interpolation.UIGL_PermutationTS]
+PermutationT_XBoxed_list [lemma, in GL.Interpolation.UIGL_PermutationTS]
+Permutation_replace [lemma, in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+Permutation_remove [lemma, in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+Permutation_repeat_extract [lemma, in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+Permutation_replace_repeat [lemma, in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+Permutation_PermutationT [lemma, in GL.Interpolation.UIGL_PermutationT]
+Permutation_vs_cons_invT [lemma, in GL.Interpolation.UIGL_PermutationT]
+Permutation_vs_elt_invT [lemma, in GL.Interpolation.UIGL_PermutationT]
+Permutation_subform_boxesLF [lemma, in GL.Interpolation.UIGL_PermutationTS]
+permut_remove_remove_list [lemma, in Syntax.remove_list_lems]
+permut_remove [lemma, in Syntax.remove_list_lems]
+PiffD1 [lemma, in General.gen]
+PiffD2 [lemma, in General.gen]
+pointed_env_ms_order [definition, in ISL.Order]
+pointed_env_order [definition, in ISL.Order]
+pointed_env [definition, in ISL.Order]
+pos_top_imps [definition, in GL.GLS.GLS_der_dec]
+pos_top_imps [definition, in K.KS.KS_termination_prelims]
+pow5_gt_0 [lemma, in ISL.Order]
+pq_correct [lemma, in ISL.PropQuantifiers]
+prems_Box_R [definition, in GL.GLS.GLS_der_dec]
+prems_Imp_L [definition, in GL.GLS.GLS_der_dec]
+prems_Imp_R [definition, in GL.GLS.GLS_der_dec]
+prems_Box_R [definition, in K.KS.KS_termination_KR]
+prems_dersrec [lemma, in General.ddT]
+prems_Imp_L [definition, in K.KS.KS_termination_ImpL]
+prems_Imp_R [definition, in K.KS.KS_termination_ImpR]
+prod_nat_split [lemma, in General.genT]
+prod_mono [lemma, in General.genT]
+proj1_sigT2 [definition, in GL.GLS.GLS_der_dec]
+proj1_sigT2 [definition, in K.KS.KS_termination_prelims]
+proj2_sigT2 [definition, in GL.GLS.GLS_der_dec]
+proj2_sigT2 [definition, in K.KS.KS_termination_prelims]
+Proof_tree_dec [lemma, in ISL.DecisionProcedure]
+proper_Provable [instance, in ISL.Sequents]
+Proper_env_order_refl [instance, in ISL.Order]
+Proper_env_order [instance, in ISL.Order]
+Proper_env_order_refl_env_weight [instance, in ISL.Order]
+Proper_env_weight [instance, in ISL.Order]
+Proper_elements [instance, in ISL.Environments]
+proper_open_boxes [instance, in ISL.Environments]
+proper_difference [instance, in ISL.Environments]
+proper_disj_union [instance, in ISL.Environments]
+proper_elem_of [instance, in ISL.Environments]
+proper_rm [instance, in ISL.DecisionProcedure]
+PropQuantifiers [library]
+propvar_subform_list_restr_list_prop [lemma, in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list_Canopy [lemma, in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list_witnessT [lemma, in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list_witness [lemma, in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list_disj [lemma, in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list_conj [lemma, in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list_top_boxes [lemma, in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list_nobox_gen_ext [lemma, in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list_unboxed_list [lemma, in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list_app [lemma, in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list [definition, in K.Interpolation.UIK_UI_prelims]
+propvar_subform [definition, in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list_nobox_gen_ext [lemma, in K.Interpolation.K_Craig_Interp]
+propvar_subform_list_unboxed_list [lemma, in K.Interpolation.K_Craig_Interp]
+propvar_subform_list_app [lemma, in K.Interpolation.K_Craig_Interp]
+propvar_subform_list [definition, in K.Interpolation.K_Craig_Interp]
+propvar_subform [definition, in K.Interpolation.K_Craig_Interp]
+propvar_subform_list_nodup [lemma, in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform_list_restr_list_prop [lemma, in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform_list_Canopy [lemma, in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform_list_witnessT [lemma, in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform_list_witness [lemma, in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform_list_disj [lemma, in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform_list_conj [lemma, in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform_list_top_boxes [lemma, in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform_list_nobox_gen_ext [lemma, in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform_list_XBoxed_list [lemma, in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform_list_app [lemma, in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform_list [definition, in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform [definition, in GL.Interpolation.UIGL_UI_prelims]
+Prop_Subform [section, in K.Interpolation.UIK_UI_prelims]
+Prop_Subform [section, in GL.Interpolation.UIGL_UI_prelims]
+Provable [inductive, in ISL.Sequents]
+Provable_sind [definition, in ISL.Sequents]
+Provable_rec [definition, in ISL.Sequents]
+Provable_ind [definition, in ISL.Sequents]
+Provable_rect [definition, in ISL.Sequents]
+Provable_dec [lemma, in ISL.DecisionProcedure]
+p_contr [lemma, in ISL.SequentProps]
+

R

+radm [inductive, in General.gstep]
+radmD [definition, in General.gstep]
+radmI [constructor, in General.gstep]
+radm_sind [definition, in General.gstep]
+radm_rec [definition, in General.gstep]
+radm_ind [definition, in General.gstep]
+radm_rect [definition, in General.gstep]
+Random [section, in K.Interpolation.UIK_basics]
+Random [section, in GL.Interpolation.UIGL_basics]
+rappl [lemma, in General.gen]
+RA_mhd_decreases [lemma, in K.KS.KS_termination]
+rec_UI_imp [lemma, in GL.Interpolation.UIGL_N_imp_UI]
+redundant_flatten_list [lemma, in GL.GLS.GLS_der_dec]
+redundant_flatten_list [lemma, in K.KS.KS_termination_prelims]
+redund_remove_list [lemma, in Syntax.remove_list_lems]
+redund_remove [lemma, in Syntax.remove_list_lems]
+redund_remove_remove_list [lemma, in Syntax.remove_list_lems]
+Reflexive_Transitive_ClosureT.R [variable, in General.rtcT]
+Reflexive_Transitive_ClosureT.A [variable, in General.rtcT]
+Reflexive_Transitive_ClosureT [section, in General.rtcT]
+Reflexive_ClosureT.R [variable, in General.rtcT]
+Reflexive_ClosureT.A [variable, in General.rtcT]
+Reflexive_ClosureT [section, in General.rtcT]
+rel [definition, in General.gen_tacs]
+relationT [definition, in General.genT]
+relmap [inductive, in General.gen_seq]
+relmap_sind [definition, in General.gen_seq]
+relmap_rec [definition, in General.gen_seq]
+relmap_ind [definition, in General.gen_seq]
+relmap_rect [definition, in General.gen_seq]
+rel_adm_rtc [lemma, in General.gstep]
+rel_admD [definition, in General.gstep]
+rel_adm_sind [definition, in General.gstep]
+rel_adm_rec [definition, in General.gstep]
+rel_adm_ind [definition, in General.gstep]
+rel_adm_rect [definition, in General.gstep]
+rel_admI [constructor, in General.gstep]
+rel_adm [inductive, in General.gstep]
+removed_box_exists [lemma, in GL.GLS.GLS_termination_measure]
+remove_n_imp_subformLF_decomp [lemma, in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+remove_n_imp_subformLF [lemma, in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+remove_list_decr_in [lemma, in K.Interpolation.UIK_UI_prelims]
+remove_nth [definition, in GL.GLS.GLS_der_dec]
+remove_nth [definition, in K.KS.KS_termination_prelims]
+remove_Permutation [lemma, in GL.Interpolation.UIGL_nodupseq]
+remove_list_incr_decr [lemma, in Syntax.remove_list_lems]
+remove_list_incr_decr4 [lemma, in Syntax.remove_list_lems]
+remove_list_incr_decr2 [lemma, in Syntax.remove_list_lems]
+remove_list_incr_decr1 [lemma, in Syntax.remove_list_lems]
+remove_list_incr_decr3 [lemma, in Syntax.remove_list_lems]
+remove_delete_origin [lemma, in Syntax.remove_list_lems]
+remove_list_is_nil [lemma, in Syntax.remove_list_lems]
+remove_list_in_nil [lemma, in Syntax.remove_list_lems]
+remove_list_delete_head_In [lemma, in Syntax.remove_list_lems]
+remove_list_delete_head [lemma, in Syntax.remove_list_lems]
+remove_list_non_empty_inter_smaller_length [lemma, in Syntax.remove_list_lems]
+remove_list_singl_id_or_nil [lemma, in Syntax.remove_list_lems]
+remove_list_is_in [lemma, in Syntax.remove_list_lems]
+remove_list_in_single [lemma, in Syntax.remove_list_lems]
+remove_list_dist_app [lemma, in Syntax.remove_list_lems]
+remove_list_cont [lemma, in Syntax.remove_list_lems]
+remove_list_preserv_NoDup [lemma, in Syntax.remove_list_lems]
+remove_list_of_nil [lemma, in Syntax.remove_list_lems]
+remove_list [definition, in Syntax.remove_list_lems]
+remove_In_smaller_length [lemma, in Syntax.remove_list_lems]
+remove_le_length [lemma, in Syntax.remove_list_lems]
+remove_preserv_NoDup [lemma, in Syntax.remove_list_lems]
+remove_not_in_anymore [lemma, in Syntax.remove_list_lems]
+remove_dist_app [lemma, in Syntax.remove_list_lems]
+remove_rest_gen_ext [lemma, in GL.GLS.GLS_inv_ImpR_ImpL]
+remove_list_decr_in [lemma, in GL.Interpolation.UIGL_UI_prelims]
+remove_In_env_order [lemma, in ISL.Order]
+remove_In_env_order_refl [lemma, in ISL.Order]
+remove_env_order [lemma, in ISL.Order]
+remove_add_rest_gen_ext [lemma, in GL.GLS.GLS_dec]
+remove_include [lemma, in ISL.Environments]
+remove_rest_gen_ext [lemma, in K.KS.KS_inv_ImpR_ImpL]
+remove_list_lems [library]
+repeat_S [lemma, in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+repeat_n_imp_subformLF [lemma, in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+repeat_more_than_one [lemma, in GL.Interpolation.UIGL_Canopy_ImpL]
+replace [definition, in GL.Interpolation.UIGL_Canopy_ImpR]
+replace_n_imp_subformLF [lemma, in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+replace_app [lemma, in GL.Interpolation.UIGL_Canopy_ImpR]
+req [definition, in General.gen]
+req_trans [lemma, in General.gen]
+req_sym [lemma, in General.gen]
+req_refl [lemma, in General.gen]
+restr_list_prop [definition, in K.Interpolation.UIK_basics]
+restr_list_prop [definition, in GL.Interpolation.UIGL_basics]
+restr_list_prop_nodup [lemma, in GL.Interpolation.UIGL_UI_prelims]
+rest_gen_ext [definition, in General.univ_gen_ext]
+rest_nobox_gen_ext_trans [lemma, in GL.GLS.GLS_inv_ImpR_ImpL]
+rest_nobox_gen_ext_trans [lemma, in K.KS.KS_inv_ImpR_ImpL]
+rev_pair [definition, in General.gen_seq]
+RHS_top_box_is_subform [lemma, in GL.GLS.GLS_termination_measure]
+RHS_top_box_is_subformLF [lemma, in GL.GLS.GLS_termination_measure]
+rlI [constructor, in General.gen_seq]
+rlI_eq [lemma, in General.gen_seq]
+rls [definition, in General.gen]
+rlsmap [inductive, in General.gen_seq]
+rlsmap_sind [definition, in General.gen_seq]
+rlsmap_rec [definition, in General.gen_seq]
+rlsmap_ind [definition, in General.gen_seq]
+rlsmap_rect [definition, in General.gen_seq]
+rlsT [definition, in General.genT]
+rm [definition, in ISL.Environments]
+rmI [constructor, in General.gen_seq]
+rmI_eq [lemma, in General.gen_seq]
+rm_mono [lemma, in General.gen_seq]
+rsub [definition, in General.gen]
+rsubD [definition, in General.gen]
+rsubI [definition, in General.gen]
+rsub_adm [definition, in General.ddT]
+rsub_derl_adm [definition, in General.ddT]
+rsub_derl [definition, in General.ddT]
+rsub_imp [definition, in General.gen]
+rsub_id [lemma, in General.gen]
+rsub_trans [lemma, in General.gen]
+rsub_def [lemma, in General.gen]
+rsub_emptyT [lemma, in General.genT]
+rtcT [library]
+rtn1T_trans [constructor, in General.rtcT]
+rtn1T_refl [constructor, in General.rtcT]
+rtT_trans [constructor, in General.rtcT]
+rtT_refl [constructor, in General.rtcT]
+rtT_step [constructor, in General.rtcT]
+rT_refl [constructor, in General.rtcT]
+rT_step [constructor, in General.rtcT]
+rt1nT_trans [constructor, in General.rtcT]
+rt1nT_refl [constructor, in General.rtcT]
+rUnI [constructor, in General.gstep]
+rUnion [inductive, in General.gstep]
+runion [inductive, in General.gstep]
+rUnion_sind [definition, in General.gstep]
+rUnion_rec [definition, in General.gstep]
+rUnion_ind [definition, in General.gstep]
+rUnion_rect [definition, in General.gstep]
+runion_sind [definition, in General.gstep]
+runion_rec [definition, in General.gstep]
+runion_ind [definition, in General.gstep]
+runion_rect [definition, in General.gstep]
+run_r [constructor, in General.gstep]
+run_l [constructor, in General.gstep]
+

S

+Sctxt [constructor, in General.gen_seq]
+Sctxt_nil [lemma, in General.gen_seq]
+Sctxt_e' [lemma, in General.gen_seq]
+Sctxt_alt [lemma, in General.gen_seq]
+Sctxt_s [constructor, in General.gen_seq]
+Sctxt_eq [lemma, in General.gen_seq]
+Sctxt_e [lemma, in General.gen_seq]
+Sctxt' [constructor, in General.gen_seq]
+Seq [definition, in GL.GLS.GLS_calcs]
+Seq [definition, in K.KS.KS_calc]
+seqext [definition, in General.gen_seq]
+seqext_defp [lemma, in General.gen_seq]
+seqext_def [lemma, in General.gen_seq]
+seqext_seqext [lemma, in General.gen_seq]
+seqrule [inductive, in General.gen_seq]
+seqrule_mono' [definition, in General.gen_seq]
+seqrule_mono [lemma, in General.gen_seq]
+seqrule_same [lemma, in General.gen_seq]
+seqrule_s_sind [definition, in General.gen_seq]
+seqrule_s_rec [definition, in General.gen_seq]
+seqrule_s_ind [definition, in General.gen_seq]
+seqrule_s_rect [definition, in General.gen_seq]
+seqrule_s [inductive, in General.gen_seq]
+seqrule_derl_seqrule' [definition, in General.gen_seq]
+seqrule_derl_seqrule [lemma, in General.gen_seq]
+seqrule_seqrule' [definition, in General.gen_seq]
+seqrule_seqrule [lemma, in General.gen_seq]
+seqrule_id [lemma, in General.gen_seq]
+seqrule_sind [definition, in General.gen_seq]
+seqrule_rec [definition, in General.gen_seq]
+seqrule_ind [definition, in General.gen_seq]
+seqrule_rect [definition, in General.gen_seq]
+seqrule' [inductive, in General.gen_seq]
+seqrule'_sind [definition, in General.gen_seq]
+seqrule'_rec [definition, in General.gen_seq]
+seqrule'_ind [definition, in General.gen_seq]
+seqrule'_rect [definition, in General.gen_seq]
+seqs_in_splitT [definition, in Syntax.list_lems]
+SequentProps [library]
+Sequents [library]
+ser_mono [lemma, in General.gen_seq]
+set_leq_ub_unif [lemma, in GL.Interpolation.UIGL_UI_prelims]
+sextI [constructor, in General.gen_seq]
+sext_rev_fext [lemma, in General.gen_seq]
+sext_e [lemma, in General.gen_seq]
+se_single [constructor, in General.gen_seq]
+se_empty [constructor, in General.gen_seq]
+simp [definition, in ISL.Simp]
+Simp [library]
+simp_equiv [lemma, in ISL.Simp]
+simp_equiv_box [lemma, in ISL.Simp]
+simp_equiv_imp [lemma, in ISL.Simp]
+simp_equiv_imp_R [lemma, in ISL.Simp]
+simp_equiv_imp_L [lemma, in ISL.Simp]
+simp_imps_self_equiv_R [lemma, in ISL.Simp]
+simp_imps_self_equiv_L [lemma, in ISL.Simp]
+simp_imp_self_equiv_R [lemma, in ISL.Simp]
+simp_imp_self_equiv_L [lemma, in ISL.Simp]
+simp_equiv_and [lemma, in ISL.Simp]
+simp_equiv_and_R [lemma, in ISL.Simp]
+simp_equiv_and_L [lemma, in ISL.Simp]
+simp_ands_self_equiv_R [lemma, in ISL.Simp]
+simp_ands_self_equiv_L [lemma, in ISL.Simp]
+simp_equiv_or [lemma, in ISL.Simp]
+simp_equiv_or_R [lemma, in ISL.Simp]
+simp_ors_self_equiv_R [lemma, in ISL.Simp]
+simp_equiv_or_L [lemma, in ISL.Simp]
+simp_ors_self_equiv_L [lemma, in ISL.Simp]
+simp_imps [definition, in ISL.Simp]
+simp_imp [definition, in ISL.Simp]
+simp_ands [definition, in ISL.Simp]
+simp_ors [definition, in ISL.Simp]
+single [definition, in General.swappedT]
+singleton [instance, in ISL.Environments]
+singletonMS [instance, in ISL.Environments]
+singleton_mult_notin [lemma, in ISL.Environments]
+singleton_mult_in [lemma, in ISL.Environments]
+single_eq_listT_nobrac [definition, in General.List_lemmasT]
+single_eq_listT [definition, in General.List_lemmasT]
+single_eq_list [definition, in General.List_lemmasT]
+single_eq [lemma, in General.swappedT]
+sing_empty_app_cons [lemma, in General.gen_seq]
+sing_empty_app [lemma, in General.gen_seq]
+sing_empty_sind [definition, in General.gen_seq]
+sing_empty_rec [definition, in General.gen_seq]
+sing_empty_ind [definition, in General.gen_seq]
+sing_empty_rect [definition, in General.gen_seq]
+sing_empty [inductive, in General.gen_seq]
+size [definition, in Syntax.CML_Syntax]
+size_LF_nil_unbox_top_box [lemma, in K.Interpolation.UIK_basics]
+size_LF [definition, in Syntax.CML_Syntax]
+size_step2_tr_lem [lemma, in General.gentree]
+size_step2_tr [definition, in General.gentree]
+size_top_boxes [lemma, in K.KS.KS_termination_measure]
+size_unboxed [lemma, in K.KS.KS_termination_measure]
+size_nobox_gen_ext [lemma, in K.KS.KS_termination_measure]
+size_LF_dist_app [lemma, in K.KS.KS_termination_measure]
+snd_rel_sind [definition, in General.gen_seq]
+snd_rel_rec [definition, in General.gen_seq]
+snd_rel_ind [definition, in General.gen_seq]
+snd_rel_rect [definition, in General.gen_seq]
+snd_relI [constructor, in General.gen_seq]
+snd_rel [inductive, in General.gen_seq]
+snd_fst_ext [lemma, in General.gen_seq]
+snd_ext_rls_sind [definition, in General.gen_seq]
+snd_ext_rls_rec [definition, in General.gen_seq]
+snd_ext_rls_ind [definition, in General.gen_seq]
+snd_ext_rls_rect [definition, in General.gen_seq]
+snd_ext_rls [inductive, in General.gen_seq]
+specialised_weakening [lemma, in ISL.Optimizations]
+sr_Id_alt [lemma, in General.gen_seq]
+string_dec [instance, in ISL.Formulas]
+strongness [lemma, in ISL.Optimizations]
+SubAnd [constructor, in ISL.Formulas]
+SubBox [constructor, in ISL.Formulas]
+SubEq [constructor, in ISL.Formulas]
+subform [inductive, in ISL.Formulas]
+subformlist [definition, in Syntax.CML_Syntax]
+subform_boxesLF_dist_app [lemma, in GL.GLS.GLS_termination_measure]
+subform_boxesS [definition, in GL.GLS.GLS_termination_measure]
+subform_boxesLF [definition, in GL.GLS.GLS_termination_measure]
+subform_boxesF [definition, in GL.GLS.GLS_termination_measure]
+subform_boxesLF_nodup [lemma, in GL.Interpolation.UIGL_UI_prelims]
+subform_boxesLF_top_boxes [lemma, in GL.Interpolation.UIGL_LexSeq]
+subform_sind [definition, in ISL.Formulas]
+subform_ind [definition, in ISL.Formulas]
+SubImpl [constructor, in ISL.Formulas]
+subl_of_boxl_is_boxl [lemma, in Syntax.CML_Syntax]
+SubOr [constructor, in ISL.Formulas]
+subst [definition, in Syntax.CML_Syntax]
+subst_dep [lemma, in General.List_lemmasT]
+sumh_step2_tr_lem [lemma, in General.gentree]
+sumh_step2_tr [definition, in General.gentree]
+sum_step2_tr_lem [lemma, in General.gentree]
+sum_step2_tr_D_gf2 [definition, in General.gentree]
+sum_step2_tr_gf2 [lemma, in General.gentree]
+sum_step2_tr [definition, in General.gentree]
+swapped [inductive, in General.swappedT]
+swappedT [library]
+swapped_gen_refl [lemma, in General.swappedT]
+swapped_gen_app_L [lemma, in General.swappedT]
+swapped__gen [lemma, in General.swappedT]
+swapped_spec_opp [lemma, in General.swappedT]
+swapped_gen_front_mid [lemma, in General.swappedT]
+swapped_gen_sind [definition, in General.swappedT]
+swapped_gen_rec [definition, in General.swappedT]
+swapped_gen_ind [definition, in General.swappedT]
+swapped_gen_rect [definition, in General.swappedT]
+swapped_gen_I [constructor, in General.swappedT]
+swapped_gen [inductive, in General.swappedT]
+swapped__n_mid [lemma, in General.swappedT]
+swapped_spec_front_mid [lemma, in General.swappedT]
+swapped_app_mid_R [lemma, in General.swappedT]
+swapped_app_mid_L [lemma, in General.swappedT]
+swapped_spec_conv [lemma, in General.swappedT]
+swapped_spec_comm [lemma, in General.swappedT]
+swapped_spec_trans_exact [lemma, in General.swappedT]
+swapped_spec_trans [lemma, in General.swappedT]
+swapped_app_L [lemma, in General.swappedT]
+swapped_spec_refl [lemma, in General.swappedT]
+swapped_spec_sind [definition, in General.swappedT]
+swapped_spec_rec [definition, in General.swappedT]
+swapped_spec_ind [definition, in General.swappedT]
+swapped_spec_rect [definition, in General.swappedT]
+swapped_spec_step [constructor, in General.swappedT]
+swapped_spec_I [constructor, in General.swappedT]
+swapped_spec [inductive, in General.swappedT]
+swapped_map [lemma, in General.swappedT]
+swapped_map_ex [lemma, in General.swappedT]
+swapped_ca2 [lemma, in General.swappedT]
+swapped_ca1 [lemma, in General.swappedT]
+swapped_Rc1 [lemma, in General.swappedT]
+swapped_Rc2 [lemma, in General.swappedT]
+swapped_comm [lemma, in General.swappedT]
+swapped_simpleR [lemma, in General.swappedT]
+swapped_simpleL [lemma, in General.swappedT]
+swapped_simple' [lemma, in General.swappedT]
+swapped_simple [lemma, in General.swappedT]
+swapped_singleRE [lemma, in General.swappedT]
+swapped_singleLE [lemma, in General.swappedT]
+swapped_nilRE [lemma, in General.swappedT]
+swapped_nilLE [lemma, in General.swappedT]
+swapped_single [definition, in General.swappedT]
+swapped_cons [lemma, in General.swappedT]
+swapped_R [lemma, in General.swappedT]
+swapped_L [lemma, in General.swappedT]
+swapped_same [lemma, in General.swappedT]
+swapped_I' [lemma, in General.swappedT]
+swapped_sind [definition, in General.swappedT]
+swapped_rec [definition, in General.swappedT]
+swapped_ind [definition, in General.swappedT]
+swapped_rect [definition, in General.swappedT]
+swapped_I [constructor, in General.swappedT]
+swap_remove_list [lemma, in Syntax.remove_list_lems]
+Syntax_export [library]
+S_le_False [lemma, in GL.GLS.GLS_termination_measure]
+

T

+tail_inv_singleton2 [lemma, in General.List_lemmasT]
+tail_inv_singleton [lemma, in General.List_lemmasT]
+tautology_cut [lemma, in ISL.Optimizations]
+term_IH_help [lemma, in K.KS.KS_termination]
+term_meas_is_0 [lemma, in K.KS.KS_termination_measure]
+tl_of_boxl_is_boxl [lemma, in Syntax.CML_Syntax]
+Top [definition, in Syntax.CML_Syntax]
+TopL_remove [lemma, in K.Interpolation.UIK_UI_prelims]
+TopL_remove [lemma, in GL.Interpolation.UIGL_And_Or_rules]
+TopL_rev [lemma, in ISL.SequentProps]
+TopR [lemma, in K.Interpolation.UIK_UI_prelims]
+TopR [lemma, in GL.Interpolation.UIGL_And_Or_rules]
+top_boxes_Canopy_noless_ub [lemma, in GL.Interpolation.UIGL_Diam_UI_imp_N_prelim]
+top_boxes_nobox_gen_ext [definition, in GL.GLS.GLS_der_dec]
+top_imps [definition, in GL.GLS.GLS_der_dec]
+top_boxes_nobox_gen_ext [definition, in K.KS.KS_termination_prelims]
+top_imps [definition, in K.KS.KS_termination_prelims]
+top_boxes_distr_app [lemma, in Syntax.CML_Syntax]
+top_boxes [definition, in Syntax.CML_Syntax]
+top_boxes_incl_list [lemma, in GL.GLS.GLS_termination_measure]
+top_boxes_diam_jump [lemma, in GL.Interpolation.UIGL_UI_prelims]
+top_boxes_facts [section, in GL.Interpolation.UIGL_UI_prelims]
+top_boxes_nodup [lemma, in GL.Interpolation.UIGL_UI_prelims]
+top_boxes_XBoxed_list [lemma, in GL.Interpolation.UIGL_LexSeq]
+top_boxes_incl_list [lemma, in K.KS.KS_dec]
+top_provable [lemma, in ISL.Optimizations]
+transitiveT [definition, in General.rtcT]
+transitiveT [definition, in General.genT]
+transitive_form_order [instance, in ISL.Formulas]
+trf [definition, in General.gen_tacs]
+trf_rules_derl [lemma, in General.gstep]
+trf_rules_rtc [lemma, in General.gstep]
+true_and [lemma, in General.gen]
+

U

+ub_nodupseq [lemma, in GL.Interpolation.UIGL_nodupseq]
+ub_stable [lemma, in GL.Interpolation.UIGL_UI_prelims]
+UI [definition, in K.Interpolation.UIK_braga]
+UI [section, in K.Interpolation.UIK_braga]
+UI [definition, in GL.Interpolation.UIGL_braga]
+UI [section, in GL.Interpolation.UIGL_braga]
+UIGL_And_Or_rules [library]
+UIGL_Diam_UI_imp_N_prelim [library]
+UIGL_irred_short [library]
+UIGL_Canopy_nodupseq_perm [library]
+UIGL_Canopy_ImpL [library]
+UIGL_irred_high_level [library]
+UIGL_UIDiam_N [library]
+UIGL_Diam_N_imp_UI [library]
+UIGL_UIOne [library]
+UIGL_braga [library]
+UIGL_Diam_UI_imp_N [library]
+UIGL_Canopy [library]
+UIGL_Canopy_ImpR [library]
+UIGL_UIThree [library]
+UIGL_nodupseq [library]
+UIGL_basics [library]
+UIGL_UITwo [library]
+UIGL_PermutationT [library]
+UIGL_UI_inter [library]
+UIGL_PermutationTS [library]
+UIGL_UI_prelims [library]
+UIGL_Def_measure [library]
+UIGL_LexSeq [library]
+UIGL_N_imp_UI [library]
+UIK_irred_high_level [library]
+UIK_irred_short [library]
+UIK_UIOne [library]
+UIK_UI_prelims [library]
+UIK_Canopy [library]
+UIK_UITwo [library]
+UIK_basics [library]
+UIK_UIThree [library]
+UIK_braga [library]
+UIK_Def_measure [library]
+UIML_extraction [library]
+UIPDiam [section, in GL.Interpolation.UIGL_UIDiam_N]
+UIPOne [section, in K.Interpolation.UIK_UIOne]
+UIPOne [section, in GL.Interpolation.UIGL_UIOne]
+UIPThree [section, in K.Interpolation.UIK_UIThree]
+UIPThree [section, in GL.Interpolation.UIGL_UIThree]
+UIPTwo [section, in K.Interpolation.UIK_UITwo]
+UIPTwo [section, in GL.Interpolation.UIGL_UITwo]
+UI_One [lemma, in K.Interpolation.UIK_UIOne]
+UI_GUI [lemma, in K.Interpolation.UIK_braga]
+UI_spec [lemma, in K.Interpolation.UIK_braga]
+UI_GUI [lemma, in GL.Interpolation.UIGL_braga]
+UI_spec [lemma, in GL.Interpolation.UIGL_braga]
+UI_Diam_rec_imp [lemma, in GL.Interpolation.UIGL_Diam_UI_imp_N]
+UI_Two [lemma, in K.Interpolation.UIK_UITwo]
+UI_Three [lemma, in K.Interpolation.UIK_UIThree]
+UI_Two [lemma, in GL.Interpolation.UIGL_UITwo]
+UI_nodupseq_gen [lemma, in GL.Interpolation.UIGL_UI_inter]
+UI_nodupseq_converse [lemma, in GL.Interpolation.UIGL_UI_inter]
+UI_nodupseq [lemma, in GL.Interpolation.UIGL_UI_inter]
+UI_Three [lemma, in GL.Interpolation.UIGL_UIThree]
+UI_One [lemma, in GL.Interpolation.UIGL_UIOne]
+UI.p [variable, in K.Interpolation.UIK_braga]
+UI.p [variable, in GL.Interpolation.UIGL_braga]
+UI.UI_pwc [variable, in K.Interpolation.UIK_braga]
+UI.UI_pwc [variable, in GL.Interpolation.UIGL_braga]
+unboxed_list_In_unfold [lemma, in K.Interpolation.UIK_UI_prelims]
+unboxed_list_In [lemma, in K.Interpolation.UIK_UI_prelims]
+unboxed_list [definition, in Syntax.CML_Syntax]
+unbox_app_distrib [lemma, in Syntax.CML_Syntax]
+unBox_formula [definition, in Syntax.CML_Syntax]
+UniformInterpolation [section, in ISL.PropQuantifiers]
+UniformInterpolation.Correctness [section, in ISL.PropQuantifiers]
+UniformInterpolation.Correctness.EntailmentCorrect [section, in ISL.PropQuantifiers]
+UniformInterpolation.Correctness.PropQuantCorrect [section, in ISL.PropQuantifiers]
+UniformInterpolation.Correctness.VariablesCorrect [section, in ISL.PropQuantifiers]
+UniformInterpolation.p [variable, in ISL.PropQuantifiers]
+UniformInterpolation.PropQuantDefinition [section, in ISL.PropQuantifiers]
+_ • _ [notation, in ISL.PropQuantifiers]
+□⁻¹ _ [notation, in ISL.PropQuantifiers]
+union_difference_R [lemma, in ISL.Environments]
+union_difference_L [lemma, in ISL.Environments]
+union_mult [lemma, in ISL.Environments]
+unit_eq_appT2 [definition, in General.List_lemmasT]
+unit_eq_app [definition, in General.List_lemmasT]
+unit_eq_appT [lemma, in General.gen_tacs]
+univ_gen_ext_n_imp_subform [lemma, in GL.Interpolation.UIGL_Canopy_ImpR]
+univ_gen_ext_more_occ [lemma, in GL.Interpolation.UIGL_Canopy_ImpR]
+univ_gen_ext_S_count_occ [lemma, in GL.Interpolation.UIGL_Canopy_ImpR]
+univ_gen_ext_count_occ [lemma, in GL.Interpolation.UIGL_Canopy_ImpR]
+univ_gen_mod_smaller_length [lemma, in General.univ_gen_mod]
+univ_gen_mod_In [lemma, in General.univ_gen_mod]
+univ_gen_mod_elem_deep [lemma, in General.univ_gen_mod]
+univ_gen_mod_same_hd [lemma, in General.univ_gen_mod]
+univ_gen_mod_combine [lemma, in General.univ_gen_mod]
+univ_gen_mod_splitR [lemma, in General.univ_gen_mod]
+univ_gen_mod_splitL [lemma, in General.univ_gen_mod]
+univ_gen_mod_lem [lemma, in General.univ_gen_mod]
+univ_gen_mod_refl [lemma, in General.univ_gen_mod]
+univ_gen_mod_sind [definition, in General.univ_gen_mod]
+univ_gen_mod_rec [definition, in General.univ_gen_mod]
+univ_gen_mod_ind [definition, in General.univ_gen_mod]
+univ_gen_mod_rect [definition, in General.univ_gen_mod]
+univ_gen_mod_modif [constructor, in General.univ_gen_mod]
+univ_gen_mod_cons [constructor, in General.univ_gen_mod]
+univ_gen_mod_nil [constructor, in General.univ_gen_mod]
+univ_gen_mod [inductive, in General.univ_gen_mod]
+univ_gen_ext_not_In_delete [lemma, in General.univ_gen_ext]
+univ_gen_ext_same_length_id [lemma, in General.univ_gen_ext]
+univ_gen_ext_smaller_length [lemma, in General.univ_gen_ext]
+univ_gen_ext_In [lemma, in General.univ_gen_ext]
+univ_gen_ext_Q_weaker_than_P [lemma, in General.univ_gen_ext]
+univ_gen_ext_add_elem_deep [lemma, in General.univ_gen_ext]
+univ_gen_ext_elem_deep [lemma, in General.univ_gen_ext]
+univ_gen_ext_same_hd [lemma, in General.univ_gen_ext]
+univ_gen_ext_combine [lemma, in General.univ_gen_ext]
+univ_gen_ext_splitR [lemma, in General.univ_gen_ext]
+univ_gen_ext_splitL [lemma, in General.univ_gen_ext]
+univ_gen_ext_lem [lemma, in General.univ_gen_ext]
+univ_gen_ext_appR [lemma, in General.univ_gen_ext]
+univ_gen_ext_appL [lemma, in General.univ_gen_ext]
+univ_gen_ext_nil_all_P [lemma, in General.univ_gen_ext]
+univ_gen_ext_trans [lemma, in General.univ_gen_ext]
+univ_gen_ext_refl [lemma, in General.univ_gen_ext]
+univ_gen_ext_sind [definition, in General.univ_gen_ext]
+univ_gen_ext_rec [definition, in General.univ_gen_ext]
+univ_gen_ext_ind [definition, in General.univ_gen_ext]
+univ_gen_ext_rect [definition, in General.univ_gen_ext]
+univ_gen_ext_extra [constructor, in General.univ_gen_ext]
+univ_gen_ext_cons [constructor, in General.univ_gen_ext]
+univ_gen_ext_nil [constructor, in General.univ_gen_ext]
+univ_gen_ext [inductive, in General.univ_gen_ext]
+univ_gen_ext_incl_subform_boxes [lemma, in GL.GLS.GLS_termination_measure]
+univ_gen_ext [library]
+univ_gen_mod [library]
+Unnamed_thm0 [definition, in General.swappedT]
+Unnamed_thm [definition, in General.swappedT]
+usable_boxes [definition, in GL.GLS.GLS_termination_measure]
+

V

+Var [constructor, in Syntax.CML_Syntax]
+Var [constructor, in ISL.Formulas]
+variable [definition, in ISL.Formulas]
+variables_disjunction [lemma, in ISL.Environments]
+variables_conjunction [lemma, in ISL.Environments]
+vars_incl [definition, in ISL.PropQuantifiers]
+var_not_in_env [definition, in ISL.Environments]
+

W

+want_prod_under_universal4 [lemma, in General.genT]
+want_right_prod_under_universal' [lemma, in General.genT]
+want_right_prod_under_universal [lemma, in General.genT]
+want_left_prod_under_universal [lemma, in General.genT]
+weakening [lemma, in ISL.SequentProps]
+weakeningL [lemma, in General.gen_seq]
+weak_ImpL [lemma, in ISL.SequentProps]
+weak_cut [lemma, in ISL.Optimizations]
+weight [definition, in ISL.Formulas]
+weight_open_box [lemma, in ISL.SequentProps]
+weight_open_box [lemma, in ISL.Order]
+weight_ind [definition, in ISL.Formulas]
+weight_pos [lemma, in ISL.Formulas]
+well_foundedT [definition, in General.genT]
+wf_LtSeq [lemma, in K.Interpolation.UIK_basics]
+wf_pointed_env_ms_order [lemma, in ISL.Order]
+wf_pointed_order [lemma, in ISL.Order]
+wf_env_order [definition, in ISL.Order]
+wf_LexSeq [lemma, in GL.Interpolation.UIGL_LexSeq]
+wkL_valid' [definition, in General.gen_seq]
+wkL_valid [definition, in General.gen_seq]
+wkn_R_sind [definition, in K.KS.KS_wkn]
+wkn_R_rec [definition, in K.KS.KS_wkn]
+wkn_R_ind [definition, in K.KS.KS_wkn]
+wkn_R_rect [definition, in K.KS.KS_wkn]
+wkn_RI [constructor, in K.KS.KS_wkn]
+wkn_R [inductive, in K.KS.KS_wkn]
+wkn_L_sind [definition, in K.KS.KS_wkn]
+wkn_L_rec [definition, in K.KS.KS_wkn]
+wkn_L_ind [definition, in K.KS.KS_wkn]
+wkn_L_rect [definition, in K.KS.KS_wkn]
+wkn_LI [constructor, in K.KS.KS_wkn]
+wkn_L [inductive, in K.KS.KS_wkn]
+wkn_R_BotL_notapplic [lemma, in GL.GLS.GLS_wkn]
+wkn_R_sind [definition, in GL.GLS.GLS_wkn]
+wkn_R_rec [definition, in GL.GLS.GLS_wkn]
+wkn_R_ind [definition, in GL.GLS.GLS_wkn]
+wkn_R_rect [definition, in GL.GLS.GLS_wkn]
+wkn_RI [constructor, in GL.GLS.GLS_wkn]
+wkn_R [inductive, in GL.GLS.GLS_wkn]
+wkn_L_sind [definition, in GL.GLS.GLS_wkn]
+wkn_L_rec [definition, in GL.GLS.GLS_wkn]
+wkn_L_ind [definition, in GL.GLS.GLS_wkn]
+wkn_L_rect [definition, in GL.GLS.GLS_wkn]
+wkn_LI [constructor, in GL.GLS.GLS_wkn]
+wkn_L [inductive, in GL.GLS.GLS_wkn]
+

X

+XBoxed_list [definition, in GL.GLS.GLS_calcs]
+XBoxed_list_In_unfold [lemma, in GL.Interpolation.UIGL_nodupseq]
+XBoxed_list_In_gen [lemma, in GL.Interpolation.UIGL_nodupseq]
+XBoxed_list_In [lemma, in GL.Interpolation.UIGL_nodupseq]
+XBoxed_list_same_subform_boxes [lemma, in GL.GLS.GLS_termination_measure]
+XBox_app_distrib [lemma, in GL.GLS.GLS_calcs]
+

other

+existsT2 _ .. _ , _ (type_scope) [notation, in General.existsT]
+existsT _ .. _ , _ (type_scope) [notation, in General.existsT]
+_ ∈ _ [notation, in K.Interpolation.UIK_irred_high_level]
+_ ∈ _ [notation, in K.Interpolation.UIK_braga]
+_ ⊢ _ [notation, in ISL.Sequents]
+_ ∈ _ [notation, in GL.Interpolation.UIGL_braga]
+_ --> _ [notation, in Syntax.CML_Syntax]
+_ << _ [notation, in GL.GLS.GLS_termination_measure]
+_ ≺· _ [notation, in ISL.Order]
+_ ≼ _ [notation, in ISL.Order]
+_ ≺ _ [notation, in ISL.Order]
+_ • _ [notation, in ISL.Order]
+_ ∈ _ [notation, in K.Interpolation.UIK_irred_short]
+_ ∈ _ [notation, in GL.Interpolation.UIGL_irred_high_level]
+_ ⇢ _ [notation, in ISL.Environments]
+_ ⊻ _ [notation, in ISL.Environments]
+_ ⊼ _ [notation, in ISL.Environments]
+_ • _ [notation, in ISL.Environments]
+_ ≼ _ [notation, in ISL.Optimizations]
+_ ∈ _ [notation, in GL.Interpolation.UIGL_irred_short]
+_ ≺f _ [notation, in ISL.Formulas]
+_ _ ⇔ _ _ [notation, in ISL.Formulas]
+_ → _ [notation, in ISL.Formulas]
+_ ∨ _ [notation, in ISL.Formulas]
+_ ∧ _ [notation, in ISL.Formulas]
+T~ _ [notation, in General.genT]
+# _ [notation, in Syntax.CML_Syntax]
+¬ _ [notation, in Syntax.CML_Syntax]
+¬ _ [notation, in ISL.Formulas]
+⊗ _ [notation, in ISL.Environments]
+⊙ _ [notation, in ISL.Environments]
+ [notation, in ISL.Formulas]
+ [notation, in Syntax.CML_Syntax]
+ [notation, in ISL.Formulas]
+ [notation, in ISL.Environments]
+ [notation, in ISL.Environments]
+□ _ [notation, in ISL.Formulas]
+


+

Notation Index

+

L

+_ <lex _ [in K.Interpolation.UIK_Def_measure]
+_ <lex _ [in GL.GLS.DLW_wf_lex]
+_ <lex _ [in GL.Interpolation.UIGL_Def_measure]
+

U

+_ • _ [in ISL.PropQuantifiers]
+□⁻¹ _ [in ISL.PropQuantifiers]
+

other

+existsT2 _ .. _ , _ (type_scope) [in General.existsT]
+existsT _ .. _ , _ (type_scope) [in General.existsT]
+_ ∈ _ [in K.Interpolation.UIK_irred_high_level]
+_ ∈ _ [in K.Interpolation.UIK_braga]
+_ ⊢ _ [in ISL.Sequents]
+_ ∈ _ [in GL.Interpolation.UIGL_braga]
+_ --> _ [in Syntax.CML_Syntax]
+_ << _ [in GL.GLS.GLS_termination_measure]
+_ ≺· _ [in ISL.Order]
+_ ≼ _ [in ISL.Order]
+_ ≺ _ [in ISL.Order]
+_ • _ [in ISL.Order]
+_ ∈ _ [in K.Interpolation.UIK_irred_short]
+_ ∈ _ [in GL.Interpolation.UIGL_irred_high_level]
+_ ⇢ _ [in ISL.Environments]
+_ ⊻ _ [in ISL.Environments]
+_ ⊼ _ [in ISL.Environments]
+_ • _ [in ISL.Environments]
+_ ≼ _ [in ISL.Optimizations]
+_ ∈ _ [in GL.Interpolation.UIGL_irred_short]
+_ ≺f _ [in ISL.Formulas]
+_ _ ⇔ _ _ [in ISL.Formulas]
+_ → _ [in ISL.Formulas]
+_ ∨ _ [in ISL.Formulas]
+_ ∧ _ [in ISL.Formulas]
+T~ _ [in General.genT]
+# _ [in Syntax.CML_Syntax]
+¬ _ [in Syntax.CML_Syntax]
+¬ _ [in ISL.Formulas]
+⊗ _ [in ISL.Environments]
+⊙ _ [in ISL.Environments]
+ [in ISL.Formulas]
+ [in Syntax.CML_Syntax]
+ [in ISL.Formulas]
+ [in ISL.Environments]
+ [in ISL.Environments]
+□ _ [in ISL.Formulas]
+


+

Variable Index

+

F

+flatmap.D [in K.Interpolation.UIK_irred_short]
+flatmap.D [in GL.Interpolation.UIGL_irred_short]
+flatmap.f [in K.Interpolation.UIK_irred_short]
+flatmap.F [in K.Interpolation.UIK_irred_short]
+flatmap.f [in GL.Interpolation.UIGL_irred_short]
+flatmap.F [in GL.Interpolation.UIGL_irred_short]
+flatmap.g [in K.Interpolation.UIK_irred_short]
+flatmap.g [in GL.Interpolation.UIGL_irred_short]
+flatmap.Hg [in K.Interpolation.UIK_irred_short]
+flatmap.Hg [in GL.Interpolation.UIGL_irred_short]
+flatmap.X [in K.Interpolation.UIK_irred_short]
+flatmap.X [in GL.Interpolation.UIGL_irred_short]
+

G

+Gimap_cont.f [in K.Interpolation.UIK_braga]
+Gimap_cont.D [in K.Interpolation.UIK_braga]
+Gimap_cont.F [in K.Interpolation.UIK_braga]
+Gimap_cont.Y [in K.Interpolation.UIK_braga]
+Gimap_cont.X [in K.Interpolation.UIK_braga]
+Gimap_cont.f [in GL.Interpolation.UIGL_braga]
+Gimap_cont.D [in GL.Interpolation.UIGL_braga]
+Gimap_cont.F [in GL.Interpolation.UIGL_braga]
+Gimap_cont.Y [in GL.Interpolation.UIGL_braga]
+Gimap_cont.X [in GL.Interpolation.UIGL_braga]
+GN.F [in GL.Interpolation.UIGL_braga]
+GN.Ffun [in GL.Interpolation.UIGL_braga]
+GN.p [in GL.Interpolation.UIGL_braga]
+

I

+imap.D [in K.Interpolation.UIK_braga]
+imap.D [in GL.Interpolation.UIGL_braga]
+imap.f [in K.Interpolation.UIK_braga]
+imap.F [in K.Interpolation.UIK_braga]
+imap.f [in GL.Interpolation.UIGL_braga]
+imap.F [in GL.Interpolation.UIGL_braga]
+imap.Ffun [in K.Interpolation.UIK_braga]
+imap.Ffun [in GL.Interpolation.UIGL_braga]
+imap.g [in K.Interpolation.UIK_braga]
+imap.g [in GL.Interpolation.UIGL_braga]
+imap.Hg [in K.Interpolation.UIK_braga]
+imap.Hg [in GL.Interpolation.UIGL_braga]
+imap.X [in K.Interpolation.UIK_braga]
+imap.X [in GL.Interpolation.UIGL_braga]
+imap.Y [in K.Interpolation.UIK_braga]
+imap.Y [in GL.Interpolation.UIGL_braga]
+irred_high_level.provability.HP [in K.Interpolation.UIK_irred_high_level]
+irred_high_level.provability.P [in K.Interpolation.UIK_irred_high_level]
+irred_high_level.irred_not [in K.Interpolation.UIK_irred_high_level]
+irred_high_level.irred_nil [in K.Interpolation.UIK_irred_high_level]
+irred_high_level.irred [in K.Interpolation.UIK_irred_high_level]
+irred_high_level.f_wf [in K.Interpolation.UIK_irred_high_level]
+irred_high_level.f [in K.Interpolation.UIK_irred_high_level]
+irred_high_level.X [in K.Interpolation.UIK_irred_high_level]
+irred_high_level.provability.HP [in GL.Interpolation.UIGL_irred_high_level]
+irred_high_level.provability.P [in GL.Interpolation.UIGL_irred_high_level]
+irred_high_level.irred_not [in GL.Interpolation.UIGL_irred_high_level]
+irred_high_level.irred_nil [in GL.Interpolation.UIGL_irred_high_level]
+irred_high_level.irred [in GL.Interpolation.UIGL_irred_high_level]
+irred_high_level.f_wf [in GL.Interpolation.UIGL_irred_high_level]
+irred_high_level.f [in GL.Interpolation.UIGL_irred_high_level]
+irred_high_level.X [in GL.Interpolation.UIGL_irred_high_level]
+irred.f [in K.Interpolation.UIK_irred_short]
+irred.f [in GL.Interpolation.UIGL_irred_short]
+irred.Girred_ind.HQ1 [in K.Interpolation.UIK_irred_short]
+irred.Girred_ind.HQ0 [in K.Interpolation.UIK_irred_short]
+irred.Girred_ind.HP1 [in K.Interpolation.UIK_irred_short]
+irred.Girred_ind.HP0 [in K.Interpolation.UIK_irred_short]
+irred.Girred_ind.Q [in K.Interpolation.UIK_irred_short]
+irred.Girred_ind.P [in K.Interpolation.UIK_irred_short]
+irred.Girred_ind.HQ1 [in GL.Interpolation.UIGL_irred_short]
+irred.Girred_ind.HQ0 [in GL.Interpolation.UIGL_irred_short]
+irred.Girred_ind.HP1 [in GL.Interpolation.UIGL_irred_short]
+irred.Girred_ind.HP0 [in GL.Interpolation.UIGL_irred_short]
+irred.Girred_ind.Q [in GL.Interpolation.UIGL_irred_short]
+irred.Girred_ind.P [in GL.Interpolation.UIGL_irred_short]
+irred.hf [in K.Interpolation.UIK_irred_short]
+irred.hf [in GL.Interpolation.UIGL_irred_short]
+irred.irred_pwc [in K.Interpolation.UIK_irred_short]
+irred.irred_pwc [in GL.Interpolation.UIGL_irred_short]
+irred.X [in K.Interpolation.UIK_irred_short]
+irred.X [in GL.Interpolation.UIGL_irred_short]
+

L

+LexSeq_ind.P [in GL.Interpolation.UIGL_LexSeq]
+lex_wf.lex_rect.HP [in K.Interpolation.UIK_Def_measure]
+lex_wf.lex_rect.P [in K.Interpolation.UIK_Def_measure]
+lex_wf.Rwf [in K.Interpolation.UIK_Def_measure]
+lex_wf.R [in K.Interpolation.UIK_Def_measure]
+lex_wf.X [in K.Interpolation.UIK_Def_measure]
+lex_wf.Rwf [in GL.GLS.DLW_wf_lex]
+lex_wf.R [in GL.GLS.DLW_wf_lex]
+lex_wf.X [in GL.GLS.DLW_wf_lex]
+lex_wf.lex_rect.HP [in GL.Interpolation.UIGL_Def_measure]
+lex_wf.lex_rect.P [in GL.Interpolation.UIGL_Def_measure]
+lex_wf.Rwf [in GL.Interpolation.UIGL_Def_measure]
+lex_wf.R [in GL.Interpolation.UIGL_Def_measure]
+lex_wf.X [in GL.Interpolation.UIGL_Def_measure]
+LtSeq_ind.P [in K.Interpolation.UIK_basics]
+

M

+measure_rect.F [in K.Interpolation.UIK_Def_measure]
+measure_rect.P [in K.Interpolation.UIK_Def_measure]
+measure_rect.m [in K.Interpolation.UIK_Def_measure]
+measure_rect.X [in K.Interpolation.UIK_Def_measure]
+measure_rect.F [in GL.GLS.DLW_wf_lex]
+measure_rect.P [in GL.GLS.DLW_wf_lex]
+measure_rect.m [in GL.GLS.DLW_wf_lex]
+measure_rect.X [in GL.GLS.DLW_wf_lex]
+measure_rect.F [in GL.Interpolation.UIGL_Def_measure]
+measure_rect.P [in GL.Interpolation.UIGL_Def_measure]
+measure_rect.m [in GL.Interpolation.UIGL_Def_measure]
+measure_rect.X [in GL.Interpolation.UIGL_Def_measure]
+

N

+N.p [in GL.Interpolation.UIGL_braga]
+

R

+Reflexive_Transitive_ClosureT.R [in General.rtcT]
+Reflexive_Transitive_ClosureT.A [in General.rtcT]
+Reflexive_ClosureT.R [in General.rtcT]
+Reflexive_ClosureT.A [in General.rtcT]
+

U

+UI.p [in K.Interpolation.UIK_braga]
+UI.p [in GL.Interpolation.UIGL_braga]
+UI.UI_pwc [in K.Interpolation.UIK_braga]
+UI.UI_pwc [in GL.Interpolation.UIGL_braga]
+UniformInterpolation.p [in ISL.PropQuantifiers]
+


+

Library Index

+

C

+CML_Syntax
+Cut
+

D

+ddT
+dd_fc
+DecisionProcedure
+DLW_wf_lex
+

E

+Environments
+existsT
+

F

+Formulas
+

G

+gen
+general_export
+genT
+gentree
+gen_tacs
+gen_seq
+GLS_wkn
+GLS_dec
+GLS_cut_elim
+GLS_calcs
+GLS_ctr
+GLS_export
+GLS_inv_ImpR_ImpL
+GLS_exch
+GLS_additive_cut
+GLS_der_dec
+GLS_termination_measure
+gstep
+

K

+KS_exch_KR
+KS_inv_ImpR_ImpL
+KS_termination_measure
+KS_dec
+KS_termination_ImpR
+KS_exch_ImpR
+KS_ctr
+KS_termination_init
+KS_exch
+KS_calc
+KS_export
+KS_termination
+KS_additive_cut
+KS_exch_ImpL
+KS_cut_elim
+KS_exch_prelims
+KS_termination_ImpL
+KS_wkn
+KS_termination_KR
+KS_termination_prelims
+K_Craig_Interp
+

L

+List_lemmasT
+list_lems
+

O

+Optimizations
+Order
+

P

+PropQuantifiers
+

R

+remove_list_lems
+rtcT
+

S

+SequentProps
+Sequents
+Simp
+swappedT
+Syntax_export
+

U

+UIGL_And_Or_rules
+UIGL_Diam_UI_imp_N_prelim
+UIGL_irred_short
+UIGL_Canopy_nodupseq_perm
+UIGL_Canopy_ImpL
+UIGL_irred_high_level
+UIGL_UIDiam_N
+UIGL_Diam_N_imp_UI
+UIGL_UIOne
+UIGL_braga
+UIGL_Diam_UI_imp_N
+UIGL_Canopy
+UIGL_Canopy_ImpR
+UIGL_UIThree
+UIGL_nodupseq
+UIGL_basics
+UIGL_UITwo
+UIGL_PermutationT
+UIGL_UI_inter
+UIGL_PermutationTS
+UIGL_UI_prelims
+UIGL_Def_measure
+UIGL_LexSeq
+UIGL_N_imp_UI
+UIK_irred_high_level
+UIK_irred_short
+UIK_UIOne
+UIK_UI_prelims
+UIK_Canopy
+UIK_UITwo
+UIK_basics
+UIK_UIThree
+UIK_braga
+UIK_Def_measure
+UIML_extraction
+univ_gen_ext
+univ_gen_mod
+


+

Lemma Index

+

A

+AccT_in_nextup_fc [in General.dd_fc]
+AccT_measure' [in General.gentree]
+Acc_invprem [in GL.Interpolation.UIGL_Canopy]
+Acc_less_imp [in GL.Interpolation.UIGL_Canopy]
+Acc_invprem [in K.Interpolation.UIK_Canopy]
+Acc_less_imp [in K.Interpolation.UIK_Canopy]
+additive_cut [in ISL.Cut]
+add_remove_list_preserve_NoDup [in Syntax.remove_list_lems]
+add_1_element_split_lists [in Syntax.list_lems]
+adm_single_trans [in General.ddT]
+adm_derrec_trans [in General.ddT]
+adm_adm [in General.ddT]
+allPderD [in General.dd_fc]
+allPderD_in [in General.dd_fc]
+allPder_dlConsD [in General.dd_fc]
+allP_all_in_d [in General.dd_fc]
+all_P_univ_gen_ext_nil [in General.univ_gen_ext]
+all_in_d_allP [in General.dd_fc]
+all_derl_dersl' [in General.ddT]
+all_derl_dersl [in General.ddT]
+all_dercl_derscl [in General.ddT]
+all_RHS_boxes_are_LHS_boxes_no_GLR [in GL.GLS.GLS_termination_measure]
+AndL [in K.Interpolation.UIK_UI_prelims]
+AndL [in GL.Interpolation.UIGL_And_Or_rules]
+AndL_inv [in GL.Interpolation.UIGL_And_Or_rules]
+AndL_rev [in ISL.SequentProps]
+AndR [in K.Interpolation.UIK_UI_prelims]
+AndR [in GL.Interpolation.UIGL_And_Or_rules]
+AndR_inv [in GL.Interpolation.UIGL_And_Or_rules]
+AndR_rev [in ISL.SequentProps]
+and_assoc_ctx_R_R [in ISL.Simp]
+and_assoc_ctx_R_L [in ISL.Simp]
+and_assoc_ctx_L_R [in ISL.Simp]
+and_assoc_L [in ISL.Simp]
+and_assoc_R [in ISL.Simp]
+and_comm_ctx_L [in ISL.Simp]
+and_comm [in ISL.Simp]
+and_true [in General.gen]
+and_congruence [in ISL.Optimizations]
+anonD [in General.genT]
+anonI [in General.genT]
+anon_forall [in General.genT]
+anon_sigT [in General.genT]
+anon_iffT [in General.genT]
+anon_imp [in General.genT]
+anon_sum [in General.genT]
+anon_prod [in General.genT]
+anon_eq [in General.genT]
+appI [in General.gen_tacs]
+appl [in General.gen]
+applI [in General.gen_tacs]
+appl_cong [in General.gen_tacs]
+apprI [in General.gen_tacs]
+appr_cong [in General.gen_tacs]
+app_remove_list [in Syntax.remove_list_lems]
+app_eq_appT2_single_tlR [in General.List_lemmasT]
+app_eq_appT2_single_tlL [in General.List_lemmasT]
+app_eq_appT2_single_hdR [in General.List_lemmasT]
+app_eq_appT2_single_hdL [in General.List_lemmasT]
+app_eq_appT2_nn [in General.List_lemmasT]
+app_tl_inversion [in General.List_lemmasT]
+app_hd_inversion [in General.List_lemmasT]
+app_singleton_tl_inversion [in General.List_lemmasT]
+app_singleton_inversion [in General.List_lemmasT]
+app_eq_unitT2 [in General.List_lemmasT]
+app_eq_appT2 [in General.List_lemmasT]
+app_eq_appT [in General.List_lemmasT]
+app_eq_app [in General.List_lemmasT]
+app_eq_nilT [in General.List_lemmasT]
+app_cons_single [in General.List_lemmasT]
+app_eq_unitT [in General.gen_tacs]
+app_eq_nil_iff [in General.gen_tacs]
+app2_find_hole [in Syntax.list_lems]
+arg_cong_imp' [in General.gen]
+arg_cong_imp [in General.gen]
+arg_cong [in General.gen]
+arg1_cong_imp' [in General.gen]
+arg1_cong_imp [in General.gen]
+asa_eq [in General.List_lemmasT]
+asmsI [in General.ddT]
+A_right [in ISL.PropQuantifiers]
+a_rule_env_spec [in ISL.PropQuantifiers]
+a_rule_form_vars [in ISL.PropQuantifiers]
+a_rule_env_vars [in ISL.PropQuantifiers]
+a_rule_form_cong_strong [in ISL.PropQuantifiers]
+a_rule_form_cong [in ISL.PropQuantifiers]
+a_rule_env_cong_strong [in ISL.PropQuantifiers]
+a_rule_env_cong [in ISL.PropQuantifiers]
+

B

+botRule_fc_prems [in General.dd_fc]
+botRule_fc_ps [in General.dd_fc]
+botRule_fc_drs [in General.dd_fc]
+botRule_fc_rules [in General.dd_fc]
+botRule_fc_concl [in General.dd_fc]
+BotR_remove [in GL.Interpolation.UIGL_And_Or_rules]
+botr_ps_der [in General.dd_fc]
+box_congr [in ISL.Simp]
+box_in_top_boxes [in Syntax.CML_Syntax]
+box_preserv_top_boxes [in GL.GLS.GLS_termination_measure]
+

C

+Canopy_nodupseq_perm [in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+Canopy_nodupseq_perm_gen [in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+Canopy_measure [in K.Interpolation.UIK_UI_prelims]
+Canopy_LtSeq [in K.Interpolation.UIK_basics]
+Canopy_nil [in K.Interpolation.UIK_basics]
+Canopy_pos_var [in GL.Interpolation.UIGL_Canopy]
+Canopy_neg_var [in GL.Interpolation.UIGL_Canopy]
+Canopy_hp_inv_ctx [in GL.Interpolation.UIGL_Canopy]
+Canopy_equiprv_genR [in GL.Interpolation.UIGL_Canopy]
+Canopy_equiprv_genL [in GL.Interpolation.UIGL_Canopy]
+Canopy_equiprv [in GL.Interpolation.UIGL_Canopy]
+Canopy_critical [in GL.Interpolation.UIGL_Canopy]
+Canopy_nodupseq_equiprv_genL [in GL.Interpolation.UIGL_UI_prelims]
+Canopy_nodupseq_equiprv_genR [in GL.Interpolation.UIGL_UI_prelims]
+Canopy_LexSeq [in GL.Interpolation.UIGL_LexSeq]
+Canopy_nil [in GL.Interpolation.UIGL_LexSeq]
+Canopy_pos_var [in K.Interpolation.UIK_Canopy]
+Canopy_neg_var [in K.Interpolation.UIK_Canopy]
+Canopy_hp_inv_ctx [in K.Interpolation.UIK_Canopy]
+Canopy_equiprv_genR [in K.Interpolation.UIK_Canopy]
+Canopy_equiprv_genL [in K.Interpolation.UIK_Canopy]
+Canopy_equiprv [in K.Interpolation.UIK_Canopy]
+Canopy_critical [in K.Interpolation.UIK_Canopy]
+can_wkL_req [in General.gen_seq]
+can_trf_rules_rtc_mono' [in General.gstep]
+can_trf_rules_imp_rtc [in General.gstep]
+can_trf_derl [in General.gstep]
+can_trf_rules_req [in General.gstep]
+can_trf_rules_Un [in General.gstep]
+can_trf_rules_un [in General.gstep]
+can_trf_rules_rc_mono' [in General.gstep]
+can_trf_rules_mono' [in General.gstep]
+can_trf_rules_imp_rc [in General.gstep]
+ccpsD [in General.ddT]
+choose_disj_equiv_R [in ISL.Optimizations]
+choose_disj_equiv_L [in ISL.Optimizations]
+choose_conj_equiv_R [in ISL.Optimizations]
+choose_conj_equiv_L [in ISL.Optimizations]
+clos_rt_rtn1T [in General.rtcT]
+clos_rtn1_rtT [in General.rtcT]
+clos_rt_rt1nT [in General.rtcT]
+clos_rt1n_rtT [in General.rtcT]
+conjunction_L [in ISL.Optimizations]
+conjunction_R2 [in ISL.Optimizations]
+conjunction_R1 [in ISL.Optimizations]
+cons_singleton [in General.List_lemmasT]
+cons_eq_appT2 [in General.List_lemmasT]
+cons_eq_appT [in General.List_lemmasT]
+cons_eq_app [in General.List_lemmasT]
+cons_single [in General.List_lemmasT]
+cons_app_single [in General.swappedT]
+contraction [in ISL.SequentProps]
+contradic_subform_boxesF [in GL.GLS.GLS_termination_measure]
+count_occ_n_imp_subformLF [in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+count_le_n_imp [in GL.Interpolation.UIGL_Canopy_ImpR]
+count_occ_n_imp_subformLF [in GL.Interpolation.UIGL_Canopy_ImpR]
+Craig_Interpolation [in K.Interpolation.K_Craig_Interp]
+crd_ra [in General.gstep]
+critical_empty_set [in K.Interpolation.UIK_basics]
+critical_nodupseq [in GL.Interpolation.UIGL_nodupseq]
+critical_Seq_InT_Canopy [in GL.Interpolation.UIGL_Canopy]
+critical_empty_seq [in GL.Interpolation.UIGL_LexSeq]
+critical_Seq_InT_Canopy [in K.Interpolation.UIK_Canopy]
+ctr_R_BotL_notapplic [in GL.GLS.GLS_ctr]
+ctr_R_IdB_notapplic [in GL.GLS.GLS_ctr]
+ctr_R_IdP_notapplic [in GL.GLS.GLS_ctr]
+ctr_L_BotL_notapplic [in GL.GLS.GLS_ctr]
+ctr_L_IdB_notapplic [in GL.GLS.GLS_ctr]
+ctr_L_IdP_notapplic [in GL.GLS.GLS_ctr]
+cut [in ISL.Cut]
+

D

+decide_in [in ISL.Environments]
+decT_less_than_lt [in GL.GLS.GLS_termination_measure]
+decT_lex_lt [in GL.GLS.GLS_termination_measure]
+decT_lt [in GL.GLS.GLS_termination_measure]
+dec_non_nil_prems [in K.KS.KS_termination]
+dec_le [in K.KS.KS_termination_prelims]
+dercl_soundness [in General.gstep]
+dercl_derl' [in General.ddT]
+dercl_all_rect [in General.ddT]
+derl_fst_ext_rls [in General.gen_seq]
+derl_fst_ext_rls'' [in General.gen_seq]
+derl_seqrule [in General.gen_seq]
+derl_seqrule'' [in General.gen_seq]
+derl_adm_s [in General.ddT]
+derl_sub_adm [in General.ddT]
+derl_dersl_mono' [in General.ddT]
+derl_dersl_deriv' [in General.ddT]
+derl_trans' [in General.ddT]
+derl_derrec_trans' [in General.ddT]
+derl_all_rect [in General.ddT]
+derl_dercl [in General.ddT]
+derl_dersl_single [in General.ddT]
+derrec_leaves_thms [in GL.GLS.GLS_der_dec]
+derrec_composition [in GL.GLS.GLS_der_dec]
+derrec_soundness [in General.gstep]
+derrec_dp_same2 [in General.dd_fc]
+derrec_dp_same [in General.dd_fc]
+derrec_eq_swap [in General.ddT]
+derrec_adm' [in General.ddT]
+derrec_all_rect2 [in General.ddT]
+derrec_nil_derl_s [in General.ddT]
+derrec_derl_deriv' [in General.ddT]
+derrec_rmono_s [in General.ddT]
+derrec_trans_imp [in General.ddT]
+derrec_same_nsR [in General.ddT]
+derrec_same_nsL [in General.ddT]
+derrec_same [in General.ddT]
+derrec_derrec' [in General.ddT]
+derrec_all_rect [in General.ddT]
+derrec_all_indT [in General.ddT]
+derrec_all_ind [in General.ddT]
+derrec_height_False_ge_1 [in GL.GLS.GLS_inv_ImpR_ImpL]
+derrec_height_False_ge_1 [in K.KS.KS_inv_ImpR_ImpL]
+derscl_all_dercl [in General.ddT]
+dersl_trans_alt [in General.ddT]
+dersl_app_eq [in General.ddT]
+dersl_cons [in General.ddT]
+dersl_dersrec_nil [in General.ddT]
+dersl_all_derl' [in General.ddT]
+dersl_all_derl [in General.ddT]
+dersrecD_forall_in_dersrec [in General.dd_fc]
+dersrec_derrec_height_le [in General.dd_fc]
+dersrec_derrec2_dp [in General.dd_fc]
+dersrec_derrec_dp [in General.dd_fc]
+dersrec_derrec2_height [in General.dd_fc]
+dersrec_derrec_height [in General.dd_fc]
+dersrec_double_verb [in General.dd_fc]
+dersrec_trees_concls_eq [in General.dd_fc]
+dersrec_height_le [in General.dd_fc]
+dersrec_height_nil [in General.dd_fc]
+dersrec_tl_eq [in General.dd_fc]
+dersrec_hd_eq [in General.dd_fc]
+dersrec_double [in General.ddT]
+dersrec_map_2 [in General.ddT]
+dersrec_map_single [in General.ddT]
+dersrec_single [in General.ddT]
+dersrec_app [in General.ddT]
+dersrec_nil [in General.ddT]
+dersrec_forall [in General.ddT]
+dersrec_all [in General.ddT]
+ders_ders_fcs [in General.dd_fc]
+ders_concls_eq [in General.dd_fc]
+der_s_inhabited [in GL.GLS.GLS_der_dec]
+der_s_inhabited [in K.KS.KS_termination_prelims]
+der_trf_ht [in General.gstep]
+der_trf_rtc [in General.gstep]
+der_trf [in General.gstep]
+der_trf_derl [in General.gstep]
+der_trf_rc [in General.gstep]
+der_trf_rc_derl [in General.gstep]
+der_trf_rc_adm [in General.gstep]
+der_botRule [in General.dd_fc]
+der_der_fc [in General.dd_fc]
+der_botr_ps_eq [in General.dd_fc]
+der_fc_concl_eq [in General.dd_fc]
+der_concl_eq [in General.dd_fc]
+DiamL_lim [in K.Interpolation.UIK_UI_prelims]
+DiamL_lim [in GL.Interpolation.UIGL_UI_prelims]
+Diam_rec_UI_imp [in GL.Interpolation.UIGL_Diam_N_imp_UI]
+Diam_rec_UI [in GL.Interpolation.UIGL_UIDiam_N]
+difference_include [in ISL.Environments]
+difference_singleton [in ISL.Environments]
+diff_not_in [in ISL.Environments]
+diff_mult [in ISL.Environments]
+disjunction_R [in ISL.Optimizations]
+disjunction_L [in ISL.Optimizations]
+dlCons_inj [in General.gstep]
+double_remove [in Syntax.remove_list_lems]
+double_negation_obviously_smaller [in ISL.Optimizations]
+dp_get_D [in General.dd_fc]
+dp_same_fun [in General.dd_fc]
+dp_same [in General.dd_fc]
+drs_trees_height [in General.dd_fc]
+dtCons_eq [in General.ddT]
+

E

+EA_vars [in ISL.PropQuantifiers]
+EA_eq [in ISL.PropQuantifiers]
+effective_remove_nth [in GL.GLS.GLS_der_dec]
+effective_remove_nth [in K.KS.KS_termination_prelims]
+elements_elem_of [in ISL.Order]
+elements_open_boxes [in ISL.Environments]
+elements_env_add [in ISL.Environments]
+elem_of_list_In_1 [in ISL.Order]
+elem_of_open_boxes [in ISL.Environments]
+emptyT_any [in General.genT]
+emptyT_any' [in General.genT]
+empty_False [in General.genT]
+empty_explosion [in General.genT]
+entail_correct [in ISL.PropQuantifiers]
+env_order_le_lt_trans [in ISL.Order]
+env_order_lt_le_trans [in ISL.Order]
+env_order_eq_add [in ISL.Order]
+env_order_cancel_right [in ISL.Order]
+env_order_4 [in ISL.Order]
+env_order_3 [in ISL.Order]
+env_order_2 [in ISL.Order]
+env_order_0 [in ISL.Order]
+env_order_disj_union_compat_strong_left [in ISL.Order]
+env_order_disj_union_compat_strong_right [in ISL.Order]
+env_order_refl_disj_union_compat [in ISL.Order]
+env_order_disj_union_compat [in ISL.Order]
+env_order_disj_union_compat_right [in ISL.Order]
+env_order_disj_union_compat_left [in ISL.Order]
+env_order_add_compat [in ISL.Order]
+env_order_compat' [in ISL.Order]
+env_order_compat [in ISL.Order]
+env_order_1 [in ISL.Order]
+env_order_equiv_left_compat [in ISL.Order]
+env_order_equiv_right_compat [in ISL.Order]
+env_order_singleton [in ISL.Order]
+env_weight_singleton [in ISL.Order]
+env_weight_add [in ISL.Order]
+env_weight_disj_union [in ISL.Order]
+env_equiv_eq [in ISL.Environments]
+env_add_inv' [in ISL.Environments]
+env_add_inv [in ISL.Environments]
+env_add_comm [in ISL.Environments]
+env_in_add [in ISL.Environments]
+env_add_remove [in ISL.Environments]
+env_replace [in ISL.Environments]
+equiv_disj_union_compat_r [in ISL.Environments]
+eq_dec_form [in Syntax.CML_Syntax]
+eq_TrueI [in General.gen]
+eq_app_canc2 [in General.List_lemmasT]
+eq_app_canc1 [in General.List_lemmasT]
+eq_S_F [in General.genT]
+exchL_std_rule [in General.gen_seq]
+exchR_std_rule [in General.gen_seq]
+exfalso [in ISL.SequentProps]
+exists_prems_InT_list_of_premises [in K.KS.KS_termination]
+exists_prems_InT_list_of_premises [in GL.GLS.GLS_der_dec]
+existT_inj' [in General.gstep]
+existT_inj [in General.gstep]
+E_of_empty [in ISL.PropQuantifiers]
+E_left [in ISL.PropQuantifiers]
+E_irr [in ISL.PropQuantifiers]
+e_rule_vars [in ISL.PropQuantifiers]
+e_rule_cong_strong [in ISL.PropQuantifiers]
+e_rule_cong [in ISL.PropQuantifiers]
+

F

+false_or [in General.gen]
+False_empty [in General.genT]
+fcI_inj [in General.dd_fc]
+fer_mono [in General.gen_seq]
+fextI_eq' [in General.gen_seq]
+fext_e [in General.gen_seq]
+find_the_max_mhd [in K.KS.KS_termination]
+finite_premises_of_S [in K.KS.KS_termination]
+finite_ImpRules_premises_of_S [in GL.Interpolation.UIGL_Canopy]
+finite_BotL_premises_of_S [in K.KS.KS_termination_init]
+finite_IdP_premises_of_S [in K.KS.KS_termination_init]
+finite_ImpRules_premises_of_S [in K.Interpolation.UIK_Canopy]
+fixpoint_nodup [in GL.Interpolation.UIGL_nodupseq]
+fixpoint_nodupseq [in GL.Interpolation.UIGL_nodupseq]
+fmlsext_def [in General.gen_seq]
+fmlsext_fmlsext [in General.gen_seq]
+fold_Canopy [in GL.Interpolation.UIGL_Canopy]
+fold_Canopy [in K.Interpolation.UIK_Canopy]
+ForallT_Forall [in General.genT]
+ForallT_Forall' [in General.genT]
+ForallT_forall [in General.genT]
+ForallT_impl [in General.genT]
+ForallT_map_rev [in General.genT]
+ForallT_map [in General.genT]
+ForallT_map_2 [in General.genT]
+ForallT_2 [in General.genT]
+ForallT_append [in General.genT]
+ForallT_cons_iff [in General.genT]
+ForallT_single [in General.genT]
+ForallT_cons_inv [in General.genT]
+ForallT_inv [in General.genT]
+forall_elem_list [in GL.GLS.GLS_der_dec]
+Forall_map_2 [in General.gen]
+Forall_map_single [in General.gen]
+Forall_single [in General.gen]
+Forall_append [in General.gen]
+Forall_cons_iff [in General.gen]
+Forall_cons_inv [in General.gen]
+Forall_ForallT' [in General.genT]
+Forall_ForallT [in General.genT]
+Forall2T_ex_r [in General.genT]
+Forall2T_ex_l [in General.genT]
+Forall2T_app [in General.genT]
+Forall2T_app_inv_r [in General.genT]
+Forall2T_app_inv_l [in General.genT]
+fst_ext_rls_derl_fst_ext_rls [in General.gen_seq]
+fst_ext_rls_fst_ext_rls [in General.gen_seq]
+fst_snd_ext [in General.gen_seq]
+fun_cong [in General.gen]
+

G

+generalised_contraction [in ISL.SequentProps]
+generalised_axiom [in ISL.SequentProps]
+generalised_weakeningR [in ISL.SequentProps]
+generalised_weakeningL [in ISL.SequentProps]
+gen_step_lem' [in General.gstep]
+gen_step2s_lem_ps [in General.gstep]
+gen_steps_lem_ps [in General.gstep]
+gen_step2_lem_psT [in General.gstep]
+gen_step2_lem_ps [in General.gstep]
+gen_step_lem_ps [in General.gstep]
+gen_step_lem_psT [in General.gstep]
+gen_step2_sub_mono [in General.gstep]
+gen_step_def [in General.gstep]
+gen_step_sub_mono [in General.gstep]
+gen_ext_add_elem_deep [in General.univ_gen_ext]
+gen_ext_elem_deep [in General.univ_gen_ext]
+gen_ext_delet_hd [in General.univ_gen_ext]
+gen_ext_diff' [in General.univ_gen_ext]
+gen_ext_InT [in General.univ_gen_ext]
+gen_ext_one' [in General.univ_gen_ext]
+gen_ext_single [in General.univ_gen_ext]
+gen_ext_same_hd [in General.univ_gen_ext]
+gen_ext_combine [in General.univ_gen_ext]
+gen_ext_splitR [in General.univ_gen_ext]
+gen_ext_splitL [in General.univ_gen_ext]
+gen_ext_lem [in General.univ_gen_ext]
+gen_ext_app [in General.univ_gen_ext]
+gen_ext_trans [in General.univ_gen_ext]
+gen_ext_nil_any [in General.univ_gen_ext]
+gen_ext_appR [in General.univ_gen_ext]
+gen_ext_appL [in General.univ_gen_ext]
+gen_ext_refl [in General.univ_gen_ext]
+gen_step2_tr_lem [in General.gentree]
+gen_step2_c_lem [in General.gentree]
+gen_step_tr_lem [in General.gentree]
+gen_step_c_lem [in General.gentree]
+gen_cong [in General.gen]
+gen_rec_UI_imp [in GL.Interpolation.UIGL_N_imp_UI]
+get_botrule [in General.dd_fc]
+Gflatmap_flat_map [in K.Interpolation.UIK_irred_short]
+Gflatmap_app_inv_left [in K.Interpolation.UIK_irred_short]
+Gflatmap_inv_sg_left [in K.Interpolation.UIK_irred_short]
+Gflatmap_inv_left [in K.Interpolation.UIK_irred_short]
+Gflatmap_flat_map [in GL.Interpolation.UIGL_irred_short]
+Gflatmap_app_inv_left [in GL.Interpolation.UIGL_irred_short]
+Gflatmap_inv_sg_left [in GL.Interpolation.UIGL_irred_short]
+Gflatmap_inv_left [in GL.Interpolation.UIGL_irred_short]
+gf_step2_tr_lem [in General.gentree]
+gf2_sum [in General.gentree]
+gf2_step_tr_lem [in General.gentree]
+Gimap_fun_rest [in K.Interpolation.UIK_braga]
+Gimap_fun [in K.Interpolation.UIK_braga]
+Gimap_map [in K.Interpolation.UIK_braga]
+Gimap_app_inv_left [in K.Interpolation.UIK_braga]
+Gimap_inv_sg_left [in K.Interpolation.UIK_braga]
+Gimap_inv_left [in K.Interpolation.UIK_braga]
+Gimap_fun_rest [in GL.Interpolation.UIGL_braga]
+Gimap_fun [in GL.Interpolation.UIGL_braga]
+Gimap_map [in GL.Interpolation.UIGL_braga]
+Gimap_app_inv_left [in GL.Interpolation.UIGL_braga]
+Gimap_inv_sg_left [in GL.Interpolation.UIGL_braga]
+Gimap_inv_left [in GL.Interpolation.UIGL_braga]
+Girred_fun [in K.Interpolation.UIK_irred_short]
+Girred_inv_not [in K.Interpolation.UIK_irred_short]
+Girred_inv_nil [in K.Interpolation.UIK_irred_short]
+Girred_fun [in GL.Interpolation.UIGL_irred_short]
+Girred_inv_not [in GL.Interpolation.UIGL_irred_short]
+Girred_inv_nil [in GL.Interpolation.UIGL_irred_short]
+GLR_app_wkn_R [in GL.GLS.GLS_wkn]
+GLR_app_wkn_L [in GL.GLS.GLS_wkn]
+GLR_applic_reduces_measure [in GL.GLS.GLS_termination_measure]
+GLR_applic_less_usable_boxes [in GL.GLS.GLS_termination_measure]
+GLR_applic_le_subform_boxes [in GL.GLS.GLS_termination_measure]
+GLR_applic_more_top_boxes [in GL.GLS.GLS_termination_measure]
+GLR_app_list_exchR [in GL.GLS.GLS_exch]
+GLR_app_list_exchL [in GL.GLS.GLS_exch]
+GLR_prems_less_ub [in GL.Interpolation.UIGL_LexSeq]
+GLR_prems_LexSeq [in GL.Interpolation.UIGL_LexSeq]
+GLR_app_ctr_R [in GL.GLS.GLS_ctr]
+GLR_app_ctr_L [in GL.GLS.GLS_ctr]
+GLS_cut_adm [in GL.GLS.GLS_additive_cut]
+GLS_cut_adm_main [in GL.GLS.GLS_additive_cut]
+GLS_dec_der [in GL.GLS.GLS_der_dec]
+GLS_XBoxed_list_wkn_L [in GL.GLS.GLS_wkn]
+GLS_prv_list_wkn_L [in GL.GLS.GLS_wkn]
+GLS_list_wkn_L [in GL.GLS.GLS_wkn]
+GLS_prv_list_wkn_R [in GL.GLS.GLS_wkn]
+GLS_list_wkn_R [in GL.GLS.GLS_wkn]
+GLS_prv_wkn_R [in GL.GLS.GLS_wkn]
+GLS_wkn_R [in GL.GLS.GLS_wkn]
+GLS_prv_wkn_L [in GL.GLS.GLS_wkn]
+GLS_wkn_L [in GL.GLS.GLS_wkn]
+GLS_cut_elimination [in GL.GLS.GLS_cut_elim]
+GLS_adm_list_exch_LR [in GL.GLS.GLS_exch]
+GLS_hpadm_list_exch_L [in GL.GLS.GLS_exch]
+GLS_hpadm_list_exch_R [in GL.GLS.GLS_exch]
+GLS_der_list_exch_R [in GL.GLS.GLS_exch]
+GLS_der_list_exch_L [in GL.GLS.GLS_exch]
+GLS_adm_list_exch_R [in GL.GLS.GLS_exch]
+GLS_adm_list_exch_L [in GL.GLS.GLS_exch]
+GLS_hpadm_list_ctr_R [in GL.GLS.GLS_ctr]
+GLS_hpadm_list_ctr_L [in GL.GLS.GLS_ctr]
+GLS_hpadm_ctr_R [in GL.GLS.GLS_ctr]
+GLS_hpadm_ctr_L [in GL.GLS.GLS_ctr]
+GLS_hpadm_ctr_LR [in GL.GLS.GLS_ctr]
+gmultiset_elements_list_to_set_disj [in ISL.Environments]
+gmultiset_rec [in ISL.Environments]
+gmultiset_choose_or_empty [in ISL.Environments]
+GN_inv_noinit_nolessub [in GL.Interpolation.UIGL_braga]
+GN_inv_noinit_lessub [in GL.Interpolation.UIGL_braga]
+GN_inv_init [in GL.Interpolation.UIGL_braga]
+GN_fun0 [in GL.Interpolation.UIGL_braga]
+GN_fun [in GL.Interpolation.UIGL_braga]
+GN_inv_noinit_nolessub0 [in GL.Interpolation.UIGL_braga]
+GN_inv_noinit_lessub0 [in GL.Interpolation.UIGL_braga]
+GN_inv_init0 [in GL.Interpolation.UIGL_braga]
+Good_pos_in_pos_top_imps [in GL.GLS.GLS_der_dec]
+Good_pos_in_pos_top_imps [in K.KS.KS_termination_ImpR]
+gsc_gstr [in General.gentree]
+gstr_gf2 [in General.gentree]
+gs_gs' [in General.gstep]
+gs_gsc [in General.gentree]
+gs2c_gs2tr [in General.gentree]
+gs2tr_gf2 [in General.gentree]
+gs2_hs2 [in General.gentree]
+gs2_tr_height [in General.gentree]
+gs2_tr_size [in General.gentree]
+gs2_gs2c [in General.gentree]
+GUI_inv_critic_not_init [in K.Interpolation.UIK_braga]
+GUI_inv_not_critic [in K.Interpolation.UIK_braga]
+GUI_inv_critic_init [in K.Interpolation.UIK_braga]
+GUI_inv_empty_seq [in K.Interpolation.UIK_braga]
+GUI_fun [in K.Interpolation.UIK_braga]
+GUI_inv_critic_not_init [in GL.Interpolation.UIGL_braga]
+GUI_inv_not_critic [in GL.Interpolation.UIGL_braga]
+GUI_inv_critic_init [in GL.Interpolation.UIGL_braga]
+GUI_inv_empty_seq [in GL.Interpolation.UIGL_braga]
+GUI_fun [in GL.Interpolation.UIGL_braga]
+

H

+height_0 [in ISL.SequentProps]
+height_step2_tr_lem [in General.gentree]
+hs2_sumh [in General.gentree]
+

I

+Id_all_form [in GL.GLS.GLS_calcs]
+Id_all_form [in K.KS.KS_calc]
+Id_InT_Canopy [in K.Interpolation.UIK_Canopy]
+iffD1 [in General.gen]
+iffD2 [in General.gen]
+iffT_prod [in General.genT]
+iffT_D2' [in General.genT]
+iffT_D1' [in General.genT]
+iffT_refl [in General.genT]
+iffT_sym' [in General.genT]
+iffT_trans [in General.genT]
+if_rev_eq [in General.List_lemmasT]
+if_eq_rev_eq [in General.List_lemmasT]
+ImpBox_dup [in ISL.SequentProps]
+ImpL [in ISL.SequentProps]
+ImpLAnd_rev [in ISL.SequentProps]
+ImpLBox_prev [in ISL.SequentProps]
+ImpLImp_dup [in ISL.SequentProps]
+ImpLImp_prev [in ISL.SequentProps]
+ImpLOr_rev [in ISL.SequentProps]
+ImpLVar_rev [in ISL.SequentProps]
+ImpL_app_ctr_R [in K.KS.KS_ctr]
+ImpL_app_ctr_L [in K.KS.KS_ctr]
+ImpL_app_wkn_R [in K.KS.KS_wkn]
+ImpL_app_wkn_L [in K.KS.KS_wkn]
+ImpL_app_wkn_R [in GL.GLS.GLS_wkn]
+ImpL_app_wkn_L [in GL.GLS.GLS_wkn]
+ImpL_app_list_exchR [in K.KS.KS_exch_ImpL]
+ImpL_app_list_exchL [in K.KS.KS_exch_ImpL]
+ImpL_applic_reduces_measure [in GL.GLS.GLS_termination_measure]
+ImpL_applic_reduces_ub_or_imp [in GL.GLS.GLS_termination_measure]
+ImpL_applic_less_Imp_same_usable_boxes [in GL.GLS.GLS_termination_measure]
+ImpL_inv [in GL.GLS.GLS_inv_ImpR_ImpL]
+ImpL_app_list_exchR [in GL.GLS.GLS_exch]
+ImpL_app_list_exchL [in GL.GLS.GLS_exch]
+ImpL_app_ctr_R [in GL.GLS.GLS_ctr]
+ImpL_app_ctr_L [in GL.GLS.GLS_ctr]
+ImpL_inv [in K.KS.KS_inv_ImpR_ImpL]
+ImpRule_Canopy [in GL.Interpolation.UIGL_Canopy]
+ImpRule_Canopy [in K.Interpolation.UIK_Canopy]
+ImpR_app_ctr_R [in K.KS.KS_ctr]
+ImpR_app_ctr_L [in K.KS.KS_ctr]
+ImpR_app_wkn_R [in K.KS.KS_wkn]
+ImpR_app_wkn_L [in K.KS.KS_wkn]
+ImpR_rev [in ISL.SequentProps]
+ImpR_app_wkn_R [in GL.GLS.GLS_wkn]
+ImpR_app_wkn_L [in GL.GLS.GLS_wkn]
+ImpR_applic_reduces_measure [in GL.GLS.GLS_termination_measure]
+ImpR_applic_reduces_ub_or_imp [in GL.GLS.GLS_termination_measure]
+ImpR_applic_less_Imp_same_usable_boxes [in GL.GLS.GLS_termination_measure]
+ImpR_inv [in GL.GLS.GLS_inv_ImpR_ImpL]
+ImpR_ImpL_hpinv [in GL.GLS.GLS_inv_ImpR_ImpL]
+ImpR_app_list_exchR [in GL.GLS.GLS_exch]
+ImpR_app_list_exchL [in GL.GLS.GLS_exch]
+ImpR_app_ctr_R [in GL.GLS.GLS_ctr]
+ImpR_app_ctr_L [in GL.GLS.GLS_ctr]
+ImpR_inv [in K.KS.KS_inv_ImpR_ImpL]
+ImpR_ImpL_hpinv [in K.KS.KS_inv_ImpR_ImpL]
+ImpR_app_list_exchR [in K.KS.KS_exch_ImpR]
+ImpR_app_list_exchL [in K.KS.KS_exch_ImpR]
+imp_cut [in ISL.SequentProps]
+incl_idS [in GL.Interpolation.UIGL_nodupseq]
+incl_id [in GL.Interpolation.UIGL_nodupseq]
+incl_ctr_R [in GL.Interpolation.UIGL_nodupseq]
+incl_ctr_R_hpadm [in GL.Interpolation.UIGL_nodupseq]
+incl_ctr_L [in GL.Interpolation.UIGL_nodupseq]
+incl_ctr_L_hpadm [in GL.Interpolation.UIGL_nodupseq]
+incl_nodup_top_boxes [in GL.Interpolation.UIGL_nodupseq]
+incl_nodupseq_subform_boxesS [in GL.Interpolation.UIGL_nodupseq]
+incl_nodup_subform_boxesLF [in GL.Interpolation.UIGL_nodupseq]
+incl_prv [in GL.Interpolation.UIGL_UI_prelims]
+incl_hpadm_prv [in GL.Interpolation.UIGL_UI_prelims]
+inhabited_anon [in General.genT]
+InT_seqext [in General.gen_seq]
+InT_seqextR [in General.gen_seq]
+InT_seqextL [in General.gen_seq]
+InT_list_of_premises_exists_prems [in K.KS.KS_termination]
+InT_In_Seq [in K.Interpolation.UIK_basics]
+InT_list_of_premises_exists_prems [in GL.GLS.GLS_der_dec]
+InT_univ_gen_mod [in General.univ_gen_mod]
+InT_In_Seq [in GL.Interpolation.UIGL_basics]
+InT_gen_ext [in General.univ_gen_ext]
+InT_univ_gen_ext [in General.univ_gen_ext]
+InT_var_provar [in K.Interpolation.K_Craig_Interp]
+InT_list_exch_L [in K.KS.KS_exch_prelims]
+InT_list_exch_R [in K.KS.KS_exch_prelims]
+InT_flat_map [in GL.Interpolation.UIGL_Canopy]
+InT_In_inv_prems [in GL.Interpolation.UIGL_Canopy]
+InT_list_exch_L [in GL.GLS.GLS_exch]
+InT_list_exch_R [in GL.GLS.GLS_exch]
+InT_singleton_mid [in General.List_lemmasT]
+InT_mid [in General.List_lemmasT]
+InT_pt_I [in General.List_lemmasT]
+InT_dec [in Syntax.list_lems]
+InT_exch_list [in Syntax.list_lems]
+InT_In_eq' [in General.genT]
+InT_In_eq [in General.genT]
+InT_In' [in General.genT]
+InT_In [in General.genT]
+InT_concat [in General.genT]
+InT_mapE [in General.genT]
+InT_map [in General.genT]
+InT_inv [in General.genT]
+InT_split [in General.genT]
+InT_nilE [in General.genT]
+InT_nilE' [in General.genT]
+InT_appE [in General.genT]
+InT_appE' [in General.genT]
+InT_appR [in General.genT]
+InT_appL [in General.genT]
+InT_flat_map [in K.Interpolation.UIK_Canopy]
+InT_In_inv_prems [in K.Interpolation.UIK_Canopy]
+inv_prems_measure [in K.Interpolation.UIK_UI_prelims]
+inv_prems_LtSeq [in K.Interpolation.UIK_basics]
+inv_prems_id_critical [in GL.Interpolation.UIGL_Canopy]
+inv_prems_LexSeq [in GL.Interpolation.UIGL_LexSeq]
+inv_prems_id_critical [in K.Interpolation.UIK_Canopy]
+in_drs_concl_in_allT [in K.KS.KS_termination]
+In_unboxed_list [in K.Interpolation.UIK_UI_prelims]
+In_list_In_propvar_subform_list [in K.Interpolation.UIK_UI_prelims]
+In_list_In_list_prop_LF [in K.Interpolation.UIK_UI_prelims]
+In_list_prop_LF [in K.Interpolation.UIK_UI_prelims]
+In_list_prop_LF_bis [in K.Interpolation.UIK_basics]
+In_list_prop_LF [in K.Interpolation.UIK_basics]
+In_l_imp_In_pos_top_imps [in GL.GLS.GLS_der_dec]
+In_pos_top_imps_In_l [in GL.GLS.GLS_der_dec]
+In_pos_top_imps_imp [in GL.GLS.GLS_der_dec]
+In_pos_top_imps_0_False [in GL.GLS.GLS_der_dec]
+In_listInserts [in GL.GLS.GLS_der_dec]
+In_InT [in GL.GLS.GLS_der_dec]
+in_replace [in GL.Interpolation.UIGL_Canopy_ImpR]
+in_not_touched_replace [in GL.Interpolation.UIGL_Canopy_ImpR]
+In_listInserts [in K.KS.KS_termination_prelims]
+In_InT [in K.KS.KS_termination_prelims]
+In_list_prop_LF_bis [in GL.Interpolation.UIGL_basics]
+In_list_prop_LF [in GL.Interpolation.UIGL_basics]
+in_nextup_fc_eqv [in General.dd_fc]
+in_nextup_eqv [in General.dd_fc]
+in_trees_drs [in General.dd_fc]
+in_drs_trees [in General.dd_fc]
+in_drs_drs_hd [in General.dd_fc]
+in_dersrec_single' [in General.dd_fc]
+in_nextup_concl_in [in General.dd_fc]
+in_drs_concl_in [in General.dd_fc]
+In_XBoxed_list_gen [in GL.Interpolation.UIGL_nodupseq]
+In_XBoxed_list [in GL.Interpolation.UIGL_nodupseq]
+in_derl [in General.ddT]
+in_single [in General.gen]
+In_matters_remove_list [in Syntax.remove_list_lems]
+In_remove_list_remove_redund [in Syntax.remove_list_lems]
+In_remove_list_In_list_not_In_remove_list [in Syntax.remove_list_lems]
+In_remove_list_In_list [in Syntax.remove_list_lems]
+In_remove_In_list [in Syntax.remove_list_lems]
+In_remove_length_same [in Syntax.remove_list_lems]
+In_remove_same [in Syntax.remove_list_lems]
+In_remove_diff [in Syntax.remove_list_lems]
+in_remove_in_init [in Syntax.remove_list_lems]
+in_not_touched_remove [in Syntax.remove_list_lems]
+in_top_boxes [in GL.GLS.GLS_termination_measure]
+In_incl_subform_boxes [in GL.GLS.GLS_termination_measure]
+in_subform_boxesF_smaller_length_form [in GL.GLS.GLS_termination_measure]
+In_subform_boxesLF_box [in GL.GLS.GLS_termination_measure]
+In_subform_boxesF_box [in GL.GLS.GLS_termination_measure]
+In_n_imp_subformLF_is_non_0 [in GL.GLS.GLS_termination_measure]
+In_propvar_subform [in GL.Interpolation.UIGL_UI_prelims]
+In_subform_boxes [in GL.Interpolation.UIGL_UI_prelims]
+In_list_In_propvar_subform_list [in GL.Interpolation.UIGL_UI_prelims]
+In_list_In_list_prop_LF [in GL.Interpolation.UIGL_UI_prelims]
+In_list_prop_LF [in GL.Interpolation.UIGL_UI_prelims]
+In_l_imp_In_pos_top_imps [in K.KS.KS_termination_ImpR]
+In_pos_top_imps_In_l [in K.KS.KS_termination_ImpR]
+In_pos_top_imps_imp [in K.KS.KS_termination_ImpR]
+In_pos_top_imps_0_False [in K.KS.KS_termination_ImpR]
+in_splitT [in Syntax.list_lems]
+in_exch_list [in Syntax.list_lems]
+In_InT [in General.genT]
+In_open_boxes [in ISL.Environments]
+in_rm [in ISL.Environments]
+in_difference [in ISL.Environments]
+in_map_ext [in ISL.Environments]
+in_map_empty [in ISL.Environments]
+in_map_in [in ISL.Environments]
+in_in_map [in ISL.Environments]
+In_n_imp_subformLF_is_non_0 [in K.Interpolation.UIK_Canopy]
+In_Box_size_LF_is_non_0 [in K.KS.KS_termination_measure]
+In_Imp_size_LF_is_non_0 [in K.KS.KS_termination_measure]
+irred_provability [in K.Interpolation.UIK_irred_high_level]
+irred_high_level_spec [in K.Interpolation.UIK_irred_high_level]
+irred_reach [in K.Interpolation.UIK_irred_high_level]
+irred_max [in K.Interpolation.UIK_irred_high_level]
+irred_not [in K.Interpolation.UIK_irred_short]
+irred_nil [in K.Interpolation.UIK_irred_short]
+irred_spec [in K.Interpolation.UIK_irred_short]
+irred_provability [in GL.Interpolation.UIGL_irred_high_level]
+irred_high_level_spec [in GL.Interpolation.UIGL_irred_high_level]
+irred_reach [in GL.Interpolation.UIGL_irred_high_level]
+irred_max [in GL.Interpolation.UIGL_irred_high_level]
+irred_not [in GL.Interpolation.UIGL_irred_short]
+irred_nil [in GL.Interpolation.UIGL_irred_short]
+irred_spec [in GL.Interpolation.UIGL_irred_short]
+iSL_uniform_interpolation [in ISL.PropQuantifiers]
+is_init_UI [in K.Interpolation.UIK_UI_prelims]
+is_init_UI_equiv_Top [in K.Interpolation.UIK_UI_prelims]
+is_init_Canopy [in K.Interpolation.UIK_UI_prelims]
+is_box_weight_open_box [in ISL.SequentProps]
+is_Boxed_list_top_boxes [in Syntax.CML_Syntax]
+is_box_is_in_boxed_list [in Syntax.CML_Syntax]
+is_nextup_ndt [in General.dd_fc]
+is_init_nodupseq [in GL.Interpolation.UIGL_nodupseq]
+is_box_in_top_boxes [in GL.GLS.GLS_termination_measure]
+is_init_UI [in GL.Interpolation.UIGL_UI_prelims]
+is_init_UI_equiv_Top [in GL.Interpolation.UIGL_UI_prelims]
+is_init_Canopy [in GL.Interpolation.UIGL_UI_prelims]
+is_not_box_open_box [in ISL.Environments]
+is_implication_obviously_smaller [in ISL.Optimizations]
+

K

+keep_list_delete_head_not_In [in Syntax.remove_list_lems]
+keep_list_delete_head_not_origin [in Syntax.remove_list_lems]
+KR_app_ctr_R [in K.KS.KS_ctr]
+KR_app_ctr_L [in K.KS.KS_ctr]
+KR_app_wkn_R [in K.KS.KS_wkn]
+KR_app_wkn_L [in K.KS.KS_wkn]
+KR_prems_LtSeq [in K.Interpolation.UIK_basics]
+KR_app_list_exchR [in K.KS.KS_exch_KR]
+KR_app_list_exchL [in K.KS.KS_exch_KR]
+KS_hpadm_list_ctr_R [in K.KS.KS_ctr]
+KS_hpadm_list_ctr_L [in K.KS.KS_ctr]
+KS_hpadm_ctr_R [in K.KS.KS_ctr]
+KS_hpadm_ctr_L [in K.KS.KS_ctr]
+KS_hpadm_ctr_LR [in K.KS.KS_ctr]
+KS_hpadm_ctr_LR0 [in K.KS.KS_ctr]
+KS_list_wkn_L [in K.KS.KS_wkn]
+KS_list_wkn_R [in K.KS.KS_wkn]
+KS_hpadm_wkn_R [in K.KS.KS_wkn]
+KS_wkn_R [in K.KS.KS_wkn]
+KS_hpadm_wkn_L [in K.KS.KS_wkn]
+KS_wkn_L [in K.KS.KS_wkn]
+KS_termin_der_is_mhd [in K.KS.KS_termination]
+KS_termin3 [in K.KS.KS_termination]
+KS_termin2 [in K.KS.KS_termination]
+KS_termin1 [in K.KS.KS_termination]
+KS_termin [in K.KS.KS_termination]
+KS_termin_base [in K.KS.KS_termination]
+KS_cut_elimination [in K.KS.KS_cut_elim]
+KS_cut_adm [in K.KS.KS_additive_cut]
+KS_cut_adm_main [in K.KS.KS_additive_cut]
+KS_adm_list_exch_LR [in K.KS.KS_exch]
+KS_hpadm_list_exch_R [in K.KS.KS_exch]
+KS_hpadm_list_exch_L [in K.KS.KS_exch]
+KS_hpadm_list_exch_L0 [in K.KS.KS_exch]
+KS_hpadm_list_exch_R0 [in K.KS.KS_exch]
+KS_der_list_exch_R [in K.KS.KS_exch]
+KS_der_list_exch_L [in K.KS.KS_exch]
+KS_adm_list_exch_R [in K.KS.KS_exch]
+KS_adm_list_exch_L [in K.KS.KS_exch]
+

L

+length_le_remove_list [in Syntax.remove_list_lems]
+length_usable_boxes_is_0 [in GL.GLS.GLS_termination_measure]
+leq_ub_Canopy [in GL.Interpolation.UIGL_LexSeq]
+leq_ub_unif [in GL.Interpolation.UIGL_LexSeq]
+less_thanS_strong_inductionT [in GL.GLS.GLS_termination_measure]
+less_thanS_trans [in GL.GLS.GLS_termination_measure]
+less_thanS_wf [in GL.GLS.GLS_termination_measure]
+less_thanS_inv [in GL.GLS.GLS_termination_measure]
+less_ub_witness [in GL.Interpolation.UIGL_UI_prelims]
+leT_ex_plus [in General.genT]
+leT_or_gt [in General.genT]
+leT_S_or_eq [in General.genT]
+leT_S_F [in General.genT]
+leT_plus_l [in General.genT]
+leT_plus_r [in General.genT]
+leT_0_n [in General.genT]
+leT_trans' [in General.genT]
+leT_S_n' [in General.genT]
+leT_n_S [in General.genT]
+LexSeq_nodupseq_case [in GL.Interpolation.UIGL_nodupseq]
+LexSeq_nodupseq [in GL.Interpolation.UIGL_nodupseq]
+LexSeq_trans [in GL.Interpolation.UIGL_LexSeq]
+lex_rect [in K.Interpolation.UIK_Def_measure]
+lex_wf [in K.Interpolation.UIK_Def_measure]
+lex_cons_inv [in K.Interpolation.UIK_Def_measure]
+lex_length [in K.Interpolation.UIK_Def_measure]
+lex_trans [in GL.GLS.GLS_termination_measure]
+lex_wf [in GL.GLS.DLW_wf_lex]
+lex_cons_inv [in GL.GLS.DLW_wf_lex]
+lex_length [in GL.GLS.DLW_wf_lex]
+lex_rect [in GL.Interpolation.UIGL_Def_measure]
+lex_wf [in GL.Interpolation.UIGL_Def_measure]
+lex_cons_inv [in GL.Interpolation.UIGL_Def_measure]
+lex_length [in GL.Interpolation.UIGL_Def_measure]
+le_False_lt [in GL.GLS.GLS_der_dec]
+le_False_lt [in K.KS.KS_termination_prelims]
+le_dersrec_height [in General.dd_fc]
+Lindenbaum_Tarski_preorder_Bot [in ISL.Optimizations]
+listInserts_In [in GL.GLS.GLS_der_dec]
+listInserts_In [in K.KS.KS_termination_prelims]
+list_disj_wkn_R [in K.Interpolation.UIK_UI_prelims]
+list_disj_L [in K.Interpolation.UIK_UI_prelims]
+list_conj_R [in K.Interpolation.UIK_UI_prelims]
+list_conj_wkn_L [in K.Interpolation.UIK_UI_prelims]
+list_prop_LF_propvar_subform_list [in K.Interpolation.UIK_UI_prelims]
+list_prop_LF_In [in K.Interpolation.UIK_basics]
+list_prop_LF_In [in GL.Interpolation.UIGL_basics]
+list_disj_wkn_R [in GL.Interpolation.UIGL_And_Or_rules]
+list_disj_L [in GL.Interpolation.UIGL_And_Or_rules]
+list_conj_R [in GL.Interpolation.UIGL_And_Or_rules]
+list_conj_wkn_L [in GL.Interpolation.UIGL_And_Or_rules]
+list_preserv_XBoxed_list [in GL.GLS.GLS_calcs]
+list_exch_L_permLR [in K.KS.KS_exch_prelims]
+list_exch_L_permR [in K.KS.KS_exch_prelims]
+list_exch_L_permL [in K.KS.KS_exch_prelims]
+list_exch_R_permLR [in K.KS.KS_exch_prelims]
+list_exch_R_permR [in K.KS.KS_exch_prelims]
+list_exch_R_permL [in K.KS.KS_exch_prelims]
+list_exch_L_same_R [in K.KS.KS_exch_prelims]
+list_exch_R_same_L [in K.KS.KS_exch_prelims]
+list_exch_L_id [in K.KS.KS_exch_prelims]
+list_exch_R_id [in K.KS.KS_exch_prelims]
+list_prop_LF_In [in GL.Interpolation.UIGL_UI_prelims]
+list_prop_LF_propvar_subform_list [in GL.Interpolation.UIGL_UI_prelims]
+list_exch_R_BotL_notapplic [in GL.GLS.GLS_exch]
+list_exch_R_IdB_notapplic [in GL.GLS.GLS_exch]
+list_exch_R_IdP_notapplic [in GL.GLS.GLS_exch]
+list_exch_L_BotL_notapplic [in GL.GLS.GLS_exch]
+list_exch_L_IdB_notapplic [in GL.GLS.GLS_exch]
+list_exch_L_IdP_notapplic [in GL.GLS.GLS_exch]
+list_exch_L_permLR [in GL.GLS.GLS_exch]
+list_exch_L_permR [in GL.GLS.GLS_exch]
+list_exch_L_permL [in GL.GLS.GLS_exch]
+list_exch_R_permLR [in GL.GLS.GLS_exch]
+list_exch_R_permR [in GL.GLS.GLS_exch]
+list_exch_R_permL [in GL.GLS.GLS_exch]
+list_exch_L_same_R [in GL.GLS.GLS_exch]
+list_exch_R_same_L [in GL.GLS.GLS_exch]
+list_exch_L_id [in GL.GLS.GLS_exch]
+list_exch_R_id [in GL.GLS.GLS_exch]
+list_nil_or_tail_singleton [in General.List_lemmasT]
+list_insert1 [in General.List_lemmasT]
+list_eq_singleT_nobrac [in General.List_lemmasT]
+list_eq_singleT [in General.List_lemmasT]
+list_eq_single [in General.List_lemmasT]
+list_eq_nil [in General.List_lemmasT]
+list_rearr23 [in General.List_lemmasT]
+list_rearr22 [in General.List_lemmasT]
+list_rearr21 [in General.List_lemmasT]
+list_rearr20 [in General.List_lemmasT]
+list_rearr19 [in General.List_lemmasT]
+list_rearr18 [in General.List_lemmasT]
+list_rearr17_R [in General.List_lemmasT]
+list_rearr16_R [in General.List_lemmasT]
+list_rearr16 [in General.List_lemmasT]
+list_rearr16' [in General.List_lemmasT]
+list_rearr15_R [in General.List_lemmasT]
+list_rearr15 [in General.List_lemmasT]
+list_rearr14 [in General.List_lemmasT]
+list_rearr13 [in General.List_lemmasT]
+list_rearr11 [in General.List_lemmasT]
+list_rearr10 [in General.List_lemmasT]
+list_rearr9 [in General.List_lemmasT]
+list_rearr8 [in General.List_lemmasT]
+list_rearr7 [in General.List_lemmasT]
+list_rearr6 [in General.List_lemmasT]
+list_rearr5 [in General.List_lemmasT]
+list_rearr4 [in General.List_lemmasT]
+list_rearr2 [in General.List_lemmasT]
+list_rearr1 [in General.List_lemmasT]
+list_split_form [in Syntax.list_lems]
+list_to_set_disj_open_boxes [in ISL.Environments]
+list_to_set_disj_rm [in ISL.Environments]
+list_to_set_disj_env_add [in ISL.Environments]
+LtSeq_trans [in K.Interpolation.UIK_basics]
+lt_decT [in K.Interpolation.UIK_basics]
+

M

+make_conj_comm_ctx_L [in ISL.Simp]
+make_conj_comm_ctx_R [in ISL.Simp]
+make_conj_comm [in ISL.Simp]
+make_disj_comm_ctx_L [in ISL.Simp]
+make_disj_comm_ctx_R [in ISL.Simp]
+make_disj_comm [in ISL.Simp]
+make_impl_complete_R [in ISL.Optimizations]
+make_impl_complete_L2 [in ISL.Optimizations]
+make_impl_complete_L [in ISL.Optimizations]
+make_impl_sound_L2' [in ISL.Optimizations]
+make_impl_sound_L2 [in ISL.Optimizations]
+make_impl_sound_R [in ISL.Optimizations]
+make_impl_sound_L [in ISL.Optimizations]
+make_disj_complete_R [in ISL.Optimizations]
+make_disj_sound_R [in ISL.Optimizations]
+make_disj_complete_L [in ISL.Optimizations]
+make_disj_sound_L [in ISL.Optimizations]
+make_disj_equiv_R [in ISL.Optimizations]
+make_disj_equiv_L [in ISL.Optimizations]
+make_conj_complete_R [in ISL.Optimizations]
+make_conj_sound_R [in ISL.Optimizations]
+make_conj_complete_L [in ISL.Optimizations]
+make_conj_sound_L [in ISL.Optimizations]
+make_conj_equiv_R [in ISL.Optimizations]
+make_conj_equiv_L [in ISL.Optimizations]
+map_fmlsext_fmlsext [in General.gen_seq]
+map_seqext_seqext [in General.gen_seq]
+map_eq_nil [in General.gen]
+map_app_ex [in General.gen]
+map_cons_ex' [in General.gen]
+map_cons_ex [in General.gen]
+measure_is_0 [in K.KS.KS_termination_measure]
+midI [in General.gen_tacs]
+multeq_meq [in ISL.Environments]
+mult_ImpR [in GL.Interpolation.UIGL_Canopy_ImpR]
+mult_ImpL_L [in GL.Interpolation.UIGL_Canopy_ImpL]
+mult_ImpL_R [in GL.Interpolation.UIGL_Canopy_ImpL]
+

N

+nextup_height [in General.dd_fc]
+nextup_height [in General.gentree]
+nextup_size [in General.gentree]
+nnn_app_eq [in General.List_lemmasT]
+nobox_top_boxes [in K.Interpolation.UIK_UI_prelims]
+nobox_gen_ext_top_boxes_identity [in GL.GLS.GLS_der_dec]
+nobox_gen_ext_top_boxes_identity [in K.KS.KS_termination_prelims]
+nobox_gen_ext_top_boxes [in Syntax.CML_Syntax]
+nobox_gen_ext_injective [in Syntax.CML_Syntax]
+nobox_gen_ext_exch_L [in K.KS.KS_exch_prelims]
+nobox_gen_ext_exch_R [in K.KS.KS_exch_prelims]
+nobox_top_boxes [in GL.Interpolation.UIGL_UI_prelims]
+nobox_gen_ext_exch_L [in GL.GLS.GLS_exch]
+nobox_gen_ext_exch_R [in GL.GLS.GLS_exch]
+nodupseq_prv_hpadm_RL [in GL.Interpolation.UIGL_nodupseq]
+nodupseq_prv_hpadm_LR [in GL.Interpolation.UIGL_nodupseq]
+nodupseq_prv [in GL.Interpolation.UIGL_nodupseq]
+nodupseq_hpadm_prv_RL [in GL.Interpolation.UIGL_nodupseq]
+nodupseq_hpadm_prv_LR [in GL.Interpolation.UIGL_nodupseq]
+nodupseq_id [in GL.Interpolation.UIGL_nodupseq]
+nodupseq_GLR_prems [in GL.Interpolation.UIGL_nodupseq]
+nodup_length [in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+nodup_id [in GL.Interpolation.UIGL_nodupseq]
+nodup_XBoxed_list [in GL.Interpolation.UIGL_nodupseq]
+nodup_top_boxes [in GL.Interpolation.UIGL_nodupseq]
+nodup_nil [in GL.Interpolation.UIGL_nodupseq]
+nodup_app [in GL.Interpolation.UIGL_nodupseq]
+NoDup_destr_split [in Syntax.remove_list_lems]
+NoDup_usable_boxes [in GL.GLS.GLS_termination_measure]
+NoDup_subform_boxesS [in GL.GLS.GLS_termination_measure]
+NoDup_subform_boxesLF [in GL.GLS.GLS_termination_measure]
+NoDup_subform_boxesF [in GL.GLS.GLS_termination_measure]
+NoDup_incl_lengthT [in GL.GLS.GLS_termination_measure]
+NoDup_incl_lengthT [in K.KS.KS_termination_measure]
+nolessub_In [in GL.Interpolation.UIGL_UI_prelims]
+noless_ub_incl_subform_boxesS [in GL.Interpolation.UIGL_Diam_UI_imp_N_prelim]
+notin_replace [in GL.Interpolation.UIGL_Canopy_ImpR]
+not_init_empty_set [in K.Interpolation.UIK_basics]
+not_removed_remove_list [in Syntax.remove_list_lems]
+not_init_empty_seq [in GL.Interpolation.UIGL_LexSeq]
+no_usable_boxes_all_RHS_are_LHS [in GL.GLS.GLS_termination_measure]
+no_RHS_box_no_GLR [in GL.GLS.GLS_termination_measure]
+no_KS_rule_applic [in K.KS.KS_termination_measure]
+nth_split_length_id [in GL.GLS.GLS_der_dec]
+nth_split_idR [in GL.GLS.GLS_der_dec]
+nth_split_idL [in GL.GLS.GLS_der_dec]
+nth_split_length [in GL.GLS.GLS_der_dec]
+nth_split_length_id [in K.KS.KS_termination_prelims]
+nth_split_idR [in K.KS.KS_termination_prelims]
+nth_split_idL [in K.KS.KS_termination_prelims]
+nth_split_length [in K.KS.KS_termination_prelims]
+N_spec [in GL.Interpolation.UIGL_braga]
+n_imp_subformS_ImpR_mult [in GL.Interpolation.UIGL_Canopy_ImpR]
+n_imp_subformLF_replace [in GL.Interpolation.UIGL_Canopy_ImpR]
+n_imp_subformS_nodupseq [in GL.Interpolation.UIGL_nodupseq]
+n_imp_subformLF_nodup [in GL.Interpolation.UIGL_nodupseq]
+n_imp_subformLF_dist_app [in GL.GLS.GLS_termination_measure]
+n_imp_subformS_is_0 [in GL.GLS.GLS_termination_measure]
+N_nodupseq [in GL.Interpolation.UIGL_UI_inter]
+n_imp_unboxed [in K.Interpolation.UIK_Canopy]
+n_imp_nobox_gen_ext [in K.Interpolation.UIK_Canopy]
+n_imp_subformLF_dist_app [in K.Interpolation.UIK_Canopy]
+n_imp_subformS_is_0 [in K.Interpolation.UIK_Canopy]
+

O

+obviously_smaller_compatible_GT [in ISL.Optimizations]
+obviously_smaller_compatible_LT [in ISL.Optimizations]
+occurs_in_map_open_box [in ISL.Environments]
+occurs_in_open_boxes [in ISL.Environments]
+occurs_in_make_impl2 [in ISL.Environments]
+occurs_in_make_impl [in ISL.Environments]
+occurs_in_make_disj [in ISL.Environments]
+occurs_in_make_conj [in ISL.Environments]
+openboxes_env_order [in ISL.Order]
+open_boxes_case [in ISL.SequentProps]
+open_boxes_R [in ISL.SequentProps]
+open_box_L [in ISL.SequentProps]
+open_boxes_env_order [in ISL.Order]
+open_boxes_spec' [in ISL.Environments]
+open_boxes_spec [in ISL.Environments]
+open_boxes_remove [in ISL.Environments]
+open_boxes_add [in ISL.Environments]
+open_boxes_singleton [in ISL.Environments]
+open_boxes_disj_union [in ISL.Environments]
+open_boxes_empty [in ISL.Environments]
+OrL [in K.Interpolation.UIK_UI_prelims]
+OrL [in GL.Interpolation.UIGL_And_Or_rules]
+OrL_inv [in GL.Interpolation.UIGL_And_Or_rules]
+OrL_rev [in ISL.SequentProps]
+OrR [in K.Interpolation.UIK_UI_prelims]
+OrR [in GL.Interpolation.UIGL_And_Or_rules]
+OrR_inv [in GL.Interpolation.UIGL_And_Or_rules]
+OrR_idemp [in ISL.Optimizations]
+OrR1Bot_rev [in ISL.SequentProps]
+OrR2Bot_rev [in ISL.SequentProps]
+or_assoc_ctx_R_R [in ISL.Simp]
+or_assoc_ctx_R_L [in ISL.Simp]
+or_assoc_ctx_L_R [in ISL.Simp]
+or_assoc_L [in ISL.Simp]
+or_assoc_R [in ISL.Simp]
+or_comm_ctx_R [in ISL.Simp]
+or_comm_ctx_L [in ISL.Simp]
+or_comm [in ISL.Simp]
+or_false [in General.gen]
+or_congruence [in ISL.Optimizations]
+

P

+pair_eqI [in General.gen]
+partition_singleton_app [in General.List_lemmasT]
+partition_2_3 [in General.List_lemmasT]
+partition_3_2 [in General.List_lemmasT]
+partition_2_2T [in General.List_lemmasT]
+partition_2_2 [in General.List_lemmasT]
+partition_1_element2 [in Syntax.list_lems]
+partition_1_element [in Syntax.list_lems]
+PermutationTS_nodupseq [in GL.Interpolation.UIGL_nodupseq]
+PermutationTS_Canopy [in GL.Interpolation.UIGL_PermutationTS]
+PermutationTS_usable_boxes [in GL.Interpolation.UIGL_PermutationTS]
+PermutationTS_critic [in GL.Interpolation.UIGL_PermutationTS]
+PermutationTS_is_init [in GL.Interpolation.UIGL_PermutationTS]
+PermutationTS_GLR_prems [in GL.Interpolation.UIGL_PermutationTS]
+PermutationTS_restr_list_prop_fst [in GL.Interpolation.UIGL_PermutationTS]
+PermutationTS_restr_list_prop_snd [in GL.Interpolation.UIGL_PermutationTS]
+PermutationTS_prv [in GL.Interpolation.UIGL_PermutationTS]
+PermutationTS_prv_hpadm [in GL.Interpolation.UIGL_PermutationTS]
+PermutationTS_sym [in GL.Interpolation.UIGL_PermutationTS]
+PermutationTS_UI [in GL.Interpolation.UIGL_UI_inter]
+PermutationT_ind_T [in GL.Interpolation.UIGL_PermutationT]
+PermutationT_cons_app [in GL.Interpolation.UIGL_PermutationT]
+PermutationT_app_comm [in GL.Interpolation.UIGL_PermutationT]
+PermutationT_cons_append [in GL.Interpolation.UIGL_PermutationT]
+PermutationT_app [in GL.Interpolation.UIGL_PermutationT]
+PermutationT_app_head [in GL.Interpolation.UIGL_PermutationT]
+PermutationT_app_tail [in GL.Interpolation.UIGL_PermutationT]
+PermutationT_sym [in GL.Interpolation.UIGL_PermutationT]
+PermutationT_refl [in GL.Interpolation.UIGL_PermutationT]
+PermutationT_nodupseq [in GL.Interpolation.UIGL_PermutationTS]
+PermutationT_top_boxes [in GL.Interpolation.UIGL_PermutationTS]
+PermutationT_XBoxed_list [in GL.Interpolation.UIGL_PermutationTS]
+Permutation_replace [in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+Permutation_remove [in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+Permutation_repeat_extract [in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+Permutation_replace_repeat [in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+Permutation_PermutationT [in GL.Interpolation.UIGL_PermutationT]
+Permutation_vs_cons_invT [in GL.Interpolation.UIGL_PermutationT]
+Permutation_vs_elt_invT [in GL.Interpolation.UIGL_PermutationT]
+Permutation_subform_boxesLF [in GL.Interpolation.UIGL_PermutationTS]
+permut_remove_remove_list [in Syntax.remove_list_lems]
+permut_remove [in Syntax.remove_list_lems]
+PiffD1 [in General.gen]
+PiffD2 [in General.gen]
+pow5_gt_0 [in ISL.Order]
+pq_correct [in ISL.PropQuantifiers]
+prems_dersrec [in General.ddT]
+prod_nat_split [in General.genT]
+prod_mono [in General.genT]
+Proof_tree_dec [in ISL.DecisionProcedure]
+propvar_subform_list_restr_list_prop [in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list_Canopy [in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list_witnessT [in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list_witness [in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list_disj [in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list_conj [in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list_top_boxes [in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list_nobox_gen_ext [in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list_unboxed_list [in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list_app [in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list_nobox_gen_ext [in K.Interpolation.K_Craig_Interp]
+propvar_subform_list_unboxed_list [in K.Interpolation.K_Craig_Interp]
+propvar_subform_list_app [in K.Interpolation.K_Craig_Interp]
+propvar_subform_list_nodup [in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform_list_restr_list_prop [in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform_list_Canopy [in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform_list_witnessT [in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform_list_witness [in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform_list_disj [in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform_list_conj [in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform_list_top_boxes [in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform_list_nobox_gen_ext [in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform_list_XBoxed_list [in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform_list_app [in GL.Interpolation.UIGL_UI_prelims]
+Provable_dec [in ISL.DecisionProcedure]
+p_contr [in ISL.SequentProps]
+

R

+rappl [in General.gen]
+RA_mhd_decreases [in K.KS.KS_termination]
+rec_UI_imp [in GL.Interpolation.UIGL_N_imp_UI]
+redundant_flatten_list [in GL.GLS.GLS_der_dec]
+redundant_flatten_list [in K.KS.KS_termination_prelims]
+redund_remove_list [in Syntax.remove_list_lems]
+redund_remove [in Syntax.remove_list_lems]
+redund_remove_remove_list [in Syntax.remove_list_lems]
+rel_adm_rtc [in General.gstep]
+removed_box_exists [in GL.GLS.GLS_termination_measure]
+remove_n_imp_subformLF_decomp [in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+remove_n_imp_subformLF [in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+remove_list_decr_in [in K.Interpolation.UIK_UI_prelims]
+remove_Permutation [in GL.Interpolation.UIGL_nodupseq]
+remove_list_incr_decr [in Syntax.remove_list_lems]
+remove_list_incr_decr4 [in Syntax.remove_list_lems]
+remove_list_incr_decr2 [in Syntax.remove_list_lems]
+remove_list_incr_decr1 [in Syntax.remove_list_lems]
+remove_list_incr_decr3 [in Syntax.remove_list_lems]
+remove_delete_origin [in Syntax.remove_list_lems]
+remove_list_is_nil [in Syntax.remove_list_lems]
+remove_list_in_nil [in Syntax.remove_list_lems]
+remove_list_delete_head_In [in Syntax.remove_list_lems]
+remove_list_delete_head [in Syntax.remove_list_lems]
+remove_list_non_empty_inter_smaller_length [in Syntax.remove_list_lems]
+remove_list_singl_id_or_nil [in Syntax.remove_list_lems]
+remove_list_is_in [in Syntax.remove_list_lems]
+remove_list_in_single [in Syntax.remove_list_lems]
+remove_list_dist_app [in Syntax.remove_list_lems]
+remove_list_cont [in Syntax.remove_list_lems]
+remove_list_preserv_NoDup [in Syntax.remove_list_lems]
+remove_list_of_nil [in Syntax.remove_list_lems]
+remove_In_smaller_length [in Syntax.remove_list_lems]
+remove_le_length [in Syntax.remove_list_lems]
+remove_preserv_NoDup [in Syntax.remove_list_lems]
+remove_not_in_anymore [in Syntax.remove_list_lems]
+remove_dist_app [in Syntax.remove_list_lems]
+remove_rest_gen_ext [in GL.GLS.GLS_inv_ImpR_ImpL]
+remove_list_decr_in [in GL.Interpolation.UIGL_UI_prelims]
+remove_In_env_order [in ISL.Order]
+remove_In_env_order_refl [in ISL.Order]
+remove_env_order [in ISL.Order]
+remove_add_rest_gen_ext [in GL.GLS.GLS_dec]
+remove_include [in ISL.Environments]
+remove_rest_gen_ext [in K.KS.KS_inv_ImpR_ImpL]
+repeat_S [in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+repeat_n_imp_subformLF [in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+repeat_more_than_one [in GL.Interpolation.UIGL_Canopy_ImpL]
+replace_n_imp_subformLF [in GL.Interpolation.UIGL_Canopy_nodupseq_perm]
+replace_app [in GL.Interpolation.UIGL_Canopy_ImpR]
+req_trans [in General.gen]
+req_sym [in General.gen]
+req_refl [in General.gen]
+restr_list_prop_nodup [in GL.Interpolation.UIGL_UI_prelims]
+rest_nobox_gen_ext_trans [in GL.GLS.GLS_inv_ImpR_ImpL]
+rest_nobox_gen_ext_trans [in K.KS.KS_inv_ImpR_ImpL]
+RHS_top_box_is_subform [in GL.GLS.GLS_termination_measure]
+RHS_top_box_is_subformLF [in GL.GLS.GLS_termination_measure]
+rlI_eq [in General.gen_seq]
+rmI_eq [in General.gen_seq]
+rm_mono [in General.gen_seq]
+rsub_id [in General.gen]
+rsub_trans [in General.gen]
+rsub_def [in General.gen]
+rsub_emptyT [in General.genT]
+

S

+Sctxt_nil [in General.gen_seq]
+Sctxt_e' [in General.gen_seq]
+Sctxt_alt [in General.gen_seq]
+Sctxt_eq [in General.gen_seq]
+Sctxt_e [in General.gen_seq]
+seqext_defp [in General.gen_seq]
+seqext_def [in General.gen_seq]
+seqext_seqext [in General.gen_seq]
+seqrule_mono [in General.gen_seq]
+seqrule_same [in General.gen_seq]
+seqrule_derl_seqrule [in General.gen_seq]
+seqrule_seqrule [in General.gen_seq]
+seqrule_id [in General.gen_seq]
+ser_mono [in General.gen_seq]
+set_leq_ub_unif [in GL.Interpolation.UIGL_UI_prelims]
+sext_rev_fext [in General.gen_seq]
+sext_e [in General.gen_seq]
+simp_equiv [in ISL.Simp]
+simp_equiv_box [in ISL.Simp]
+simp_equiv_imp [in ISL.Simp]
+simp_equiv_imp_R [in ISL.Simp]
+simp_equiv_imp_L [in ISL.Simp]
+simp_imps_self_equiv_R [in ISL.Simp]
+simp_imps_self_equiv_L [in ISL.Simp]
+simp_imp_self_equiv_R [in ISL.Simp]
+simp_imp_self_equiv_L [in ISL.Simp]
+simp_equiv_and [in ISL.Simp]
+simp_equiv_and_R [in ISL.Simp]
+simp_equiv_and_L [in ISL.Simp]
+simp_ands_self_equiv_R [in ISL.Simp]
+simp_ands_self_equiv_L [in ISL.Simp]
+simp_equiv_or [in ISL.Simp]
+simp_equiv_or_R [in ISL.Simp]
+simp_ors_self_equiv_R [in ISL.Simp]
+simp_equiv_or_L [in ISL.Simp]
+simp_ors_self_equiv_L [in ISL.Simp]
+singleton_mult_notin [in ISL.Environments]
+singleton_mult_in [in ISL.Environments]
+single_eq [in General.swappedT]
+sing_empty_app_cons [in General.gen_seq]
+sing_empty_app [in General.gen_seq]
+size_LF_nil_unbox_top_box [in K.Interpolation.UIK_basics]
+size_step2_tr_lem [in General.gentree]
+size_top_boxes [in K.KS.KS_termination_measure]
+size_unboxed [in K.KS.KS_termination_measure]
+size_nobox_gen_ext [in K.KS.KS_termination_measure]
+size_LF_dist_app [in K.KS.KS_termination_measure]
+snd_fst_ext [in General.gen_seq]
+specialised_weakening [in ISL.Optimizations]
+sr_Id_alt [in General.gen_seq]
+strongness [in ISL.Optimizations]
+subform_boxesLF_dist_app [in GL.GLS.GLS_termination_measure]
+subform_boxesLF_nodup [in GL.Interpolation.UIGL_UI_prelims]
+subform_boxesLF_top_boxes [in GL.Interpolation.UIGL_LexSeq]
+subl_of_boxl_is_boxl [in Syntax.CML_Syntax]
+subst_dep [in General.List_lemmasT]
+sumh_step2_tr_lem [in General.gentree]
+sum_step2_tr_lem [in General.gentree]
+sum_step2_tr_gf2 [in General.gentree]
+swapped_gen_refl [in General.swappedT]
+swapped_gen_app_L [in General.swappedT]
+swapped__gen [in General.swappedT]
+swapped_spec_opp [in General.swappedT]
+swapped_gen_front_mid [in General.swappedT]
+swapped__n_mid [in General.swappedT]
+swapped_spec_front_mid [in General.swappedT]
+swapped_app_mid_R [in General.swappedT]
+swapped_app_mid_L [in General.swappedT]
+swapped_spec_conv [in General.swappedT]
+swapped_spec_comm [in General.swappedT]
+swapped_spec_trans_exact [in General.swappedT]
+swapped_spec_trans [in General.swappedT]
+swapped_app_L [in General.swappedT]
+swapped_spec_refl [in General.swappedT]
+swapped_map [in General.swappedT]
+swapped_map_ex [in General.swappedT]
+swapped_ca2 [in General.swappedT]
+swapped_ca1 [in General.swappedT]
+swapped_Rc1 [in General.swappedT]
+swapped_Rc2 [in General.swappedT]
+swapped_comm [in General.swappedT]
+swapped_simpleR [in General.swappedT]
+swapped_simpleL [in General.swappedT]
+swapped_simple' [in General.swappedT]
+swapped_simple [in General.swappedT]
+swapped_singleRE [in General.swappedT]
+swapped_singleLE [in General.swappedT]
+swapped_nilRE [in General.swappedT]
+swapped_nilLE [in General.swappedT]
+swapped_cons [in General.swappedT]
+swapped_R [in General.swappedT]
+swapped_L [in General.swappedT]
+swapped_same [in General.swappedT]
+swapped_I' [in General.swappedT]
+swap_remove_list [in Syntax.remove_list_lems]
+S_le_False [in GL.GLS.GLS_termination_measure]
+

T

+tail_inv_singleton2 [in General.List_lemmasT]
+tail_inv_singleton [in General.List_lemmasT]
+tautology_cut [in ISL.Optimizations]
+term_IH_help [in K.KS.KS_termination]
+term_meas_is_0 [in K.KS.KS_termination_measure]
+tl_of_boxl_is_boxl [in Syntax.CML_Syntax]
+TopL_remove [in K.Interpolation.UIK_UI_prelims]
+TopL_remove [in GL.Interpolation.UIGL_And_Or_rules]
+TopL_rev [in ISL.SequentProps]
+TopR [in K.Interpolation.UIK_UI_prelims]
+TopR [in GL.Interpolation.UIGL_And_Or_rules]
+top_boxes_Canopy_noless_ub [in GL.Interpolation.UIGL_Diam_UI_imp_N_prelim]
+top_boxes_distr_app [in Syntax.CML_Syntax]
+top_boxes_incl_list [in GL.GLS.GLS_termination_measure]
+top_boxes_diam_jump [in GL.Interpolation.UIGL_UI_prelims]
+top_boxes_nodup [in GL.Interpolation.UIGL_UI_prelims]
+top_boxes_XBoxed_list [in GL.Interpolation.UIGL_LexSeq]
+top_boxes_incl_list [in K.KS.KS_dec]
+top_provable [in ISL.Optimizations]
+trf_rules_derl [in General.gstep]
+trf_rules_rtc [in General.gstep]
+true_and [in General.gen]
+

U

+ub_nodupseq [in GL.Interpolation.UIGL_nodupseq]
+ub_stable [in GL.Interpolation.UIGL_UI_prelims]
+UI_One [in K.Interpolation.UIK_UIOne]
+UI_GUI [in K.Interpolation.UIK_braga]
+UI_spec [in K.Interpolation.UIK_braga]
+UI_GUI [in GL.Interpolation.UIGL_braga]
+UI_spec [in GL.Interpolation.UIGL_braga]
+UI_Diam_rec_imp [in GL.Interpolation.UIGL_Diam_UI_imp_N]
+UI_Two [in K.Interpolation.UIK_UITwo]
+UI_Three [in K.Interpolation.UIK_UIThree]
+UI_Two [in GL.Interpolation.UIGL_UITwo]
+UI_nodupseq_gen [in GL.Interpolation.UIGL_UI_inter]
+UI_nodupseq_converse [in GL.Interpolation.UIGL_UI_inter]
+UI_nodupseq [in GL.Interpolation.UIGL_UI_inter]
+UI_Three [in GL.Interpolation.UIGL_UIThree]
+UI_One [in GL.Interpolation.UIGL_UIOne]
+unboxed_list_In_unfold [in K.Interpolation.UIK_UI_prelims]
+unboxed_list_In [in K.Interpolation.UIK_UI_prelims]
+unbox_app_distrib [in Syntax.CML_Syntax]
+union_difference_R [in ISL.Environments]
+union_difference_L [in ISL.Environments]
+union_mult [in ISL.Environments]
+unit_eq_appT [in General.gen_tacs]
+univ_gen_ext_n_imp_subform [in GL.Interpolation.UIGL_Canopy_ImpR]
+univ_gen_ext_more_occ [in GL.Interpolation.UIGL_Canopy_ImpR]
+univ_gen_ext_S_count_occ [in GL.Interpolation.UIGL_Canopy_ImpR]
+univ_gen_ext_count_occ [in GL.Interpolation.UIGL_Canopy_ImpR]
+univ_gen_mod_smaller_length [in General.univ_gen_mod]
+univ_gen_mod_In [in General.univ_gen_mod]
+univ_gen_mod_elem_deep [in General.univ_gen_mod]
+univ_gen_mod_same_hd [in General.univ_gen_mod]
+univ_gen_mod_combine [in General.univ_gen_mod]
+univ_gen_mod_splitR [in General.univ_gen_mod]
+univ_gen_mod_splitL [in General.univ_gen_mod]
+univ_gen_mod_lem [in General.univ_gen_mod]
+univ_gen_mod_refl [in General.univ_gen_mod]
+univ_gen_ext_not_In_delete [in General.univ_gen_ext]
+univ_gen_ext_same_length_id [in General.univ_gen_ext]
+univ_gen_ext_smaller_length [in General.univ_gen_ext]
+univ_gen_ext_In [in General.univ_gen_ext]
+univ_gen_ext_Q_weaker_than_P [in General.univ_gen_ext]
+univ_gen_ext_add_elem_deep [in General.univ_gen_ext]
+univ_gen_ext_elem_deep [in General.univ_gen_ext]
+univ_gen_ext_same_hd [in General.univ_gen_ext]
+univ_gen_ext_combine [in General.univ_gen_ext]
+univ_gen_ext_splitR [in General.univ_gen_ext]
+univ_gen_ext_splitL [in General.univ_gen_ext]
+univ_gen_ext_lem [in General.univ_gen_ext]
+univ_gen_ext_appR [in General.univ_gen_ext]
+univ_gen_ext_appL [in General.univ_gen_ext]
+univ_gen_ext_nil_all_P [in General.univ_gen_ext]
+univ_gen_ext_trans [in General.univ_gen_ext]
+univ_gen_ext_refl [in General.univ_gen_ext]
+univ_gen_ext_incl_subform_boxes [in GL.GLS.GLS_termination_measure]
+

V

+variables_disjunction [in ISL.Environments]
+variables_conjunction [in ISL.Environments]
+

W

+want_prod_under_universal4 [in General.genT]
+want_right_prod_under_universal' [in General.genT]
+want_right_prod_under_universal [in General.genT]
+want_left_prod_under_universal [in General.genT]
+weakening [in ISL.SequentProps]
+weakeningL [in General.gen_seq]
+weak_ImpL [in ISL.SequentProps]
+weak_cut [in ISL.Optimizations]
+weight_open_box [in ISL.SequentProps]
+weight_open_box [in ISL.Order]
+weight_pos [in ISL.Formulas]
+wf_LtSeq [in K.Interpolation.UIK_basics]
+wf_pointed_env_ms_order [in ISL.Order]
+wf_pointed_order [in ISL.Order]
+wf_LexSeq [in GL.Interpolation.UIGL_LexSeq]
+wkn_R_BotL_notapplic [in GL.GLS.GLS_wkn]
+

X

+XBoxed_list_In_unfold [in GL.Interpolation.UIGL_nodupseq]
+XBoxed_list_In_gen [in GL.Interpolation.UIGL_nodupseq]
+XBoxed_list_In [in GL.Interpolation.UIGL_nodupseq]
+XBoxed_list_same_subform_boxes [in GL.GLS.GLS_termination_measure]
+XBox_app_distrib [in GL.GLS.GLS_calcs]
+


+

Constructor Index

+

A

+AccT_intro [in General.genT]
+aderI [in General.ddT]
+admI [in General.ddT]
+adpI [in General.ddT]
+allPder_Cons [in General.dd_fc]
+allPder_Nil [in General.dd_fc]
+And [in ISL.Formulas]
+AndL [in ISL.Sequents]
+AndR [in ISL.Sequents]
+asa_appR [in General.List_lemmasT]
+asa_appL [in General.List_lemmasT]
+asa_single [in General.List_lemmasT]
+asmI [in General.ddT]
+Atom [in ISL.Sequents]
+

B

+Bot [in Syntax.CML_Syntax]
+Bot [in ISL.Formulas]
+BotL [in GL.GLS.GLS_calcs]
+BotL [in K.KS.KS_calc]
+BotLRule_I [in GL.GLS.GLS_calcs]
+BotLRule_I [in K.KS.KS_calc]
+botRule_fcI [in General.dd_fc]
+Box [in Syntax.CML_Syntax]
+Box [in ISL.Formulas]
+BoxR [in ISL.Sequents]
+

C

+casmI [in General.ddT]
+ccpsI [in General.ddT]
+ctr_RI [in K.KS.KS_ctr]
+ctr_LI [in K.KS.KS_ctr]
+ctr_RI [in GL.GLS.GLS_ctr]
+ctr_LI [in GL.GLS.GLS_ctr]
+CutRule_I [in GL.GLS.GLS_cut_elim]
+CutRule_I [in K.KS.KS_cut_elim]
+

D

+derI [in General.ddT]
+dlCons [in General.ddT]
+dlNil [in General.ddT]
+dpI [in General.ddT]
+dtcCons [in General.ddT]
+dtcderI [in General.ddT]
+dtcNil [in General.ddT]
+dtCons [in General.ddT]
+dtderI [in General.ddT]
+dtNil [in General.ddT]
+

E

+ExFalso [in ISL.Sequents]
+

F

+fcI [in General.dd_fc]
+fcsI [in General.dd_fc]
+fextI [in General.gen_seq]
+ForallT_cons [in General.genT]
+ForallT_nil [in General.genT]
+Forall2T_cons [in General.genT]
+Forall2T_nil [in General.genT]
+fst_relI [in General.gen_seq]
+

G

+Gfm_cons [in K.Interpolation.UIK_irred_short]
+Gfm_nil [in K.Interpolation.UIK_irred_short]
+Gfm_cons [in GL.Interpolation.UIGL_irred_short]
+Gfm_nil [in GL.Interpolation.UIGL_irred_short]
+Gim_cons [in K.Interpolation.UIK_braga]
+Gim_nil [in K.Interpolation.UIK_braga]
+Gim_cons [in GL.Interpolation.UIGL_braga]
+Gim_nil [in GL.Interpolation.UIGL_braga]
+Girred_not [in K.Interpolation.UIK_irred_short]
+Girred_nil [in K.Interpolation.UIK_irred_short]
+Girred_not [in GL.Interpolation.UIGL_irred_short]
+Girred_nil [in GL.Interpolation.UIGL_irred_short]
+GLR [in GL.GLS.GLS_calcs]
+GLRRule_I [in GL.GLS.GLS_calcs]
+GLS_woc [in GL.GLS.GLS_cut_elim]
+GN_less [in GL.Interpolation.UIGL_braga]
+GN_less_ub [in GL.Interpolation.UIGL_braga]
+GN_init_seq [in GL.Interpolation.UIGL_braga]
+gsI [in General.gstep]
+GUI_critic_not_init [in K.Interpolation.UIK_braga]
+GUI_not_critic [in K.Interpolation.UIK_braga]
+GUI_critic_init [in K.Interpolation.UIK_braga]
+GUI_empty_seq [in K.Interpolation.UIK_braga]
+GUI_critic_not_init [in GL.Interpolation.UIGL_braga]
+GUI_not_critic [in GL.Interpolation.UIGL_braga]
+GUI_critic_init [in GL.Interpolation.UIGL_braga]
+GUI_empty_seq [in GL.Interpolation.UIGL_braga]
+

I

+IdBRule_I [in GL.GLS.GLS_calcs]
+IdP [in GL.GLS.GLS_calcs]
+IdP [in K.KS.KS_calc]
+IdPRule_I [in GL.GLS.GLS_calcs]
+IdPRule_I [in K.KS.KS_calc]
+Idrule_I [in General.gen_seq]
+iGLS_cut [in GL.GLS.GLS_cut_elim]
+Imp [in Syntax.CML_Syntax]
+ImpBox [in ISL.Sequents]
+ImpL [in GL.GLS.GLS_calcs]
+ImpL [in K.KS.KS_calc]
+ImpLAnd [in ISL.Sequents]
+Implies [in ISL.Formulas]
+ImpLImp [in ISL.Sequents]
+ImpLOr [in ISL.Sequents]
+ImpLRule_I [in GL.GLS.GLS_calcs]
+ImpLRule_I [in K.KS.KS_calc]
+ImpLVar [in ISL.Sequents]
+ImpR [in ISL.Sequents]
+ImpR [in GL.GLS.GLS_calcs]
+ImpR [in K.KS.KS_calc]
+ImpRRule_I [in GL.GLS.GLS_calcs]
+ImpRRule_I [in K.KS.KS_calc]
+IndClo [in GL.GLS.GLS_exch]
+IndClo [in K.KS.KS_exch]
+IndLExch [in GL.GLS.GLS_exch]
+IndLExch [in K.KS.KS_exch]
+IndRExch [in GL.GLS.GLS_exch]
+IndRExch [in K.KS.KS_exch]
+InitClo [in GL.GLS.GLS_exch]
+InitClo [in K.KS.KS_exch]
+InitLExch [in GL.GLS.GLS_exch]
+InitLExch [in K.KS.KS_exch]
+InitRExch [in GL.GLS.GLS_exch]
+InitRExch [in K.KS.KS_exch]
+InT_pt_tl [in General.List_lemmasT]
+InT_pt_hd [in General.List_lemmasT]
+InT_cons [in General.genT]
+InT_eq' [in General.genT]
+in_nextup_fcI [in General.dd_fc]
+in_nextupI [in General.dd_fc]
+in_dersrec_tl [in General.dd_fc]
+in_dersrec_hd [in General.dd_fc]
+is_nextupI [in General.dd_fc]
+

K

+KR [in K.KS.KS_calc]
+KRRule_I [in K.KS.KS_calc]
+KS_cut [in K.KS.KS_cut_elim]
+KS_woc [in K.KS.KS_cut_elim]
+

L

+leT_S [in General.genT]
+leT_n [in General.genT]
+lex_cons [in K.Interpolation.UIK_Def_measure]
+lex_skip [in K.Interpolation.UIK_Def_measure]
+lex_cons [in GL.GLS.DLW_wf_lex]
+lex_skip [in GL.GLS.DLW_wf_lex]
+lex_cons [in GL.Interpolation.UIGL_Def_measure]
+lex_skip [in GL.Interpolation.UIGL_Def_measure]
+list_exch_RI [in K.KS.KS_exch_prelims]
+list_exch_LI [in K.KS.KS_exch_prelims]
+list_exch_RI [in GL.GLS.GLS_exch]
+list_exch_LI [in GL.GLS.GLS_exch]
+

O

+Or [in ISL.Formulas]
+OrL [in ISL.Sequents]
+OrR1 [in ISL.Sequents]
+OrR2 [in ISL.Sequents]
+

P

+permT_trans [in GL.Interpolation.UIGL_PermutationT]
+permT_swap [in GL.Interpolation.UIGL_PermutationT]
+permT_skip [in GL.Interpolation.UIGL_PermutationT]
+permT_nil [in GL.Interpolation.UIGL_PermutationT]
+

R

+radmI [in General.gstep]
+rel_admI [in General.gstep]
+rlI [in General.gen_seq]
+rmI [in General.gen_seq]
+rtn1T_trans [in General.rtcT]
+rtn1T_refl [in General.rtcT]
+rtT_trans [in General.rtcT]
+rtT_refl [in General.rtcT]
+rtT_step [in General.rtcT]
+rT_refl [in General.rtcT]
+rT_step [in General.rtcT]
+rt1nT_trans [in General.rtcT]
+rt1nT_refl [in General.rtcT]
+rUnI [in General.gstep]
+run_r [in General.gstep]
+run_l [in General.gstep]
+

S

+Sctxt [in General.gen_seq]
+Sctxt_s [in General.gen_seq]
+Sctxt' [in General.gen_seq]
+sextI [in General.gen_seq]
+se_single [in General.gen_seq]
+se_empty [in General.gen_seq]
+snd_relI [in General.gen_seq]
+SubAnd [in ISL.Formulas]
+SubBox [in ISL.Formulas]
+SubEq [in ISL.Formulas]
+SubImpl [in ISL.Formulas]
+SubOr [in ISL.Formulas]
+swapped_gen_I [in General.swappedT]
+swapped_spec_step [in General.swappedT]
+swapped_spec_I [in General.swappedT]
+swapped_I [in General.swappedT]
+

U

+univ_gen_mod_modif [in General.univ_gen_mod]
+univ_gen_mod_cons [in General.univ_gen_mod]
+univ_gen_mod_nil [in General.univ_gen_mod]
+univ_gen_ext_extra [in General.univ_gen_ext]
+univ_gen_ext_cons [in General.univ_gen_ext]
+univ_gen_ext_nil [in General.univ_gen_ext]
+

V

+Var [in Syntax.CML_Syntax]
+Var [in ISL.Formulas]
+

W

+wkn_RI [in K.KS.KS_wkn]
+wkn_LI [in K.KS.KS_wkn]
+wkn_RI [in GL.GLS.GLS_wkn]
+wkn_LI [in GL.GLS.GLS_wkn]
+


+

Inductive Index

+

A

+AccT [in General.genT]
+aderrec [in General.ddT]
+adm [in General.ddT]
+allPder [in General.dd_fc]
+app_split_at [in General.List_lemmasT]
+

B

+BotLRule [in GL.GLS.GLS_calcs]
+BotLRule [in K.KS.KS_calc]
+botRule_fc [in General.dd_fc]
+

C

+ccps [in General.ddT]
+Closure [in GL.GLS.GLS_exch]
+Closure [in K.KS.KS_exch]
+clos_refl_transT_n1 [in General.rtcT]
+clos_refl_transT_1n [in General.rtcT]
+clos_refl_transT [in General.rtcT]
+clos_reflT [in General.rtcT]
+ctr_R [in K.KS.KS_ctr]
+ctr_L [in K.KS.KS_ctr]
+ctr_R [in GL.GLS.GLS_ctr]
+ctr_L [in GL.GLS.GLS_ctr]
+CutRule [in GL.GLS.GLS_cut_elim]
+CutRule [in K.KS.KS_cut_elim]
+

D

+dercl [in General.ddT]
+dercsl [in General.ddT]
+derl [in General.ddT]
+derrec [in General.ddT]
+derrec_fc [in General.dd_fc]
+dersl [in General.ddT]
+dersrec [in General.ddT]
+dersrec_fcs [in General.dd_fc]
+

E

+empty [in General.genT]
+emptyT [in General.genT]
+empty_relT [in General.genT]
+ExcClosure [in GL.GLS.GLS_exch]
+ExcClosure [in K.KS.KS_exch]
+

F

+ForallT [in General.genT]
+Forall2T [in General.genT]
+form [in ISL.Formulas]
+fst_rel [in General.gen_seq]
+fst_ext_rls [in General.gen_seq]
+

G

+gen_step' [in General.gstep]
+Gflatmap [in K.Interpolation.UIK_irred_short]
+Gflatmap [in GL.Interpolation.UIGL_irred_short]
+Gimap [in K.Interpolation.UIK_braga]
+Gimap [in GL.Interpolation.UIGL_braga]
+Girred [in K.Interpolation.UIK_irred_short]
+Girred [in GL.Interpolation.UIGL_irred_short]
+GLRRule [in GL.GLS.GLS_calcs]
+GLS_rules [in GL.GLS.GLS_calcs]
+GLS_cut_rules [in GL.GLS.GLS_cut_elim]
+GN [in GL.Interpolation.UIGL_braga]
+GUI [in K.Interpolation.UIK_braga]
+GUI [in GL.Interpolation.UIGL_braga]
+

I

+IdBRule [in GL.GLS.GLS_calcs]
+IdPRule [in GL.GLS.GLS_calcs]
+IdPRule [in K.KS.KS_calc]
+Idrule [in General.gen_seq]
+ImpLRule [in GL.GLS.GLS_calcs]
+ImpLRule [in K.KS.KS_calc]
+ImpRRule [in GL.GLS.GLS_calcs]
+ImpRRule [in K.KS.KS_calc]
+InT [in General.genT]
+InT_pair_triple [in General.List_lemmasT]
+in_nextup_fc [in General.dd_fc]
+in_nextup [in General.dd_fc]
+in_dersrec [in General.dd_fc]
+is_nextup [in General.dd_fc]
+

K

+KRRule [in K.KS.KS_calc]
+KS_cut_rules [in K.KS.KS_cut_elim]
+KS_rules [in K.KS.KS_calc]
+

L

+leT [in General.genT]
+lex [in K.Interpolation.UIK_Def_measure]
+lex [in GL.GLS.DLW_wf_lex]
+lex [in GL.Interpolation.UIGL_Def_measure]
+list_exch_R [in K.KS.KS_exch_prelims]
+list_exch_L [in K.KS.KS_exch_prelims]
+list_exch_R [in GL.GLS.GLS_exch]
+list_exch_L [in GL.GLS.GLS_exch]
+

M

+MPropF [in Syntax.CML_Syntax]
+

P

+PermutationT [in GL.Interpolation.UIGL_PermutationT]
+Provable [in ISL.Sequents]
+

R

+radm [in General.gstep]
+relmap [in General.gen_seq]
+rel_adm [in General.gstep]
+rlsmap [in General.gen_seq]
+rUnion [in General.gstep]
+runion [in General.gstep]
+

S

+seqrule [in General.gen_seq]
+seqrule_s [in General.gen_seq]
+seqrule' [in General.gen_seq]
+sing_empty [in General.gen_seq]
+snd_rel [in General.gen_seq]
+snd_ext_rls [in General.gen_seq]
+subform [in ISL.Formulas]
+swapped [in General.swappedT]
+swapped_gen [in General.swappedT]
+swapped_spec [in General.swappedT]
+

U

+univ_gen_mod [in General.univ_gen_mod]
+univ_gen_ext [in General.univ_gen_ext]
+

W

+wkn_R [in K.KS.KS_wkn]
+wkn_L [in K.KS.KS_wkn]
+wkn_R [in GL.GLS.GLS_wkn]
+wkn_L [in GL.GLS.GLS_wkn]
+


+

Section Index

+

A

+Arithmetic [in K.Interpolation.UIK_basics]
+

C

+Canopy_lems [in K.Interpolation.UIK_UI_prelims]
+CountablyManyFormulas [in ISL.Formulas]
+

D

+Diam_help [in K.Interpolation.UIK_UI_prelims]
+Diam_help [in GL.Interpolation.UIGL_UI_prelims]
+

E

+empty_seq [in K.Interpolation.UIK_basics]
+empty_seq [in GL.Interpolation.UIGL_LexSeq]
+

F

+flatmap [in K.Interpolation.UIK_irred_short]
+flatmap [in GL.Interpolation.UIGL_irred_short]
+

G

+Gimap_cont [in K.Interpolation.UIK_braga]
+Gimap_cont [in GL.Interpolation.UIGL_braga]
+GN [in GL.Interpolation.UIGL_braga]
+

I

+imap [in K.Interpolation.UIK_braga]
+imap [in GL.Interpolation.UIGL_braga]
+irred [in K.Interpolation.UIK_irred_short]
+irred [in GL.Interpolation.UIGL_irred_short]
+irred_high_level.provability [in K.Interpolation.UIK_irred_high_level]
+irred_high_level [in K.Interpolation.UIK_irred_high_level]
+irred_high_level.provability [in GL.Interpolation.UIGL_irred_high_level]
+irred_high_level [in GL.Interpolation.UIGL_irred_high_level]
+irred.Girred_ind [in K.Interpolation.UIK_irred_short]
+irred.Girred_ind [in GL.Interpolation.UIGL_irred_short]
+

L

+LexSeq_properties [in GL.Interpolation.UIGL_LexSeq]
+LexSeq_ind [in GL.Interpolation.UIGL_LexSeq]
+lex_wf.lex_rect [in K.Interpolation.UIK_Def_measure]
+lex_wf [in K.Interpolation.UIK_Def_measure]
+lex_wf [in GL.GLS.DLW_wf_lex]
+lex_wf.lex_rect [in GL.Interpolation.UIGL_Def_measure]
+lex_wf [in GL.Interpolation.UIGL_Def_measure]
+list_conj_disj_properties [in K.Interpolation.UIK_UI_prelims]
+list_conj_disj_properties [in GL.Interpolation.UIGL_And_Or_rules]
+LogDefinition [in GL.Interpolation.UIGL_LexSeq]
+logic [in GL.Interpolation.UIGL_UI_prelims]
+Logic_Abrv [in K.Interpolation.UIK_basics]
+Logic_Abrv [in GL.Interpolation.UIGL_basics]
+LtSeq_properties [in K.Interpolation.UIK_basics]
+LtSeq_ind [in K.Interpolation.UIK_basics]
+

M

+measure_rect [in K.Interpolation.UIK_Def_measure]
+measure_rect [in GL.GLS.DLW_wf_lex]
+measure_rect [in GL.Interpolation.UIGL_Def_measure]
+

N

+N [in GL.Interpolation.UIGL_braga]
+nodupseq [in GL.Interpolation.UIGL_nodupseq]
+nodup_facts [in GL.Interpolation.UIGL_UI_prelims]
+

P

+PermutationT [in GL.Interpolation.UIGL_PermutationT]
+Prop_Subform [in K.Interpolation.UIK_UI_prelims]
+Prop_Subform [in GL.Interpolation.UIGL_UI_prelims]
+

R

+Random [in K.Interpolation.UIK_basics]
+Random [in GL.Interpolation.UIGL_basics]
+Reflexive_Transitive_ClosureT [in General.rtcT]
+Reflexive_ClosureT [in General.rtcT]
+

T

+top_boxes_facts [in GL.Interpolation.UIGL_UI_prelims]
+

U

+UI [in K.Interpolation.UIK_braga]
+UI [in GL.Interpolation.UIGL_braga]
+UIPDiam [in GL.Interpolation.UIGL_UIDiam_N]
+UIPOne [in K.Interpolation.UIK_UIOne]
+UIPOne [in GL.Interpolation.UIGL_UIOne]
+UIPThree [in K.Interpolation.UIK_UIThree]
+UIPThree [in GL.Interpolation.UIGL_UIThree]
+UIPTwo [in K.Interpolation.UIK_UITwo]
+UIPTwo [in GL.Interpolation.UIGL_UITwo]
+UniformInterpolation [in ISL.PropQuantifiers]
+UniformInterpolation.Correctness [in ISL.PropQuantifiers]
+UniformInterpolation.Correctness.EntailmentCorrect [in ISL.PropQuantifiers]
+UniformInterpolation.Correctness.PropQuantCorrect [in ISL.PropQuantifiers]
+UniformInterpolation.Correctness.VariablesCorrect [in ISL.PropQuantifiers]
+UniformInterpolation.PropQuantDefinition [in ISL.PropQuantifiers]
+


+

Instance Index

+

D

+decidable_is_negation [in ISL.Environments]
+decidable_is_implication [in ISL.Environments]
+decidable_is_double_negation [in ISL.Environments]
+

E

+env_order_trans [in ISL.Order]
+equiv_assoc [in ISL.Environments]
+

F

+fomula_bottom [in ISL.Formulas]
+form_count [in ISL.Formulas]
+form_eq_dec [in ISL.Formulas]
+form_top [in ISL.Formulas]
+

I

+irreflexive_form_order [in ISL.Formulas]
+

P

+proper_Provable [in ISL.Sequents]
+Proper_env_order_refl [in ISL.Order]
+Proper_env_order [in ISL.Order]
+Proper_env_order_refl_env_weight [in ISL.Order]
+Proper_env_weight [in ISL.Order]
+Proper_elements [in ISL.Environments]
+proper_open_boxes [in ISL.Environments]
+proper_difference [in ISL.Environments]
+proper_disj_union [in ISL.Environments]
+proper_elem_of [in ISL.Environments]
+proper_rm [in ISL.DecisionProcedure]
+

S

+singleton [in ISL.Environments]
+singletonMS [in ISL.Environments]
+string_dec [in ISL.Formulas]
+

T

+transitive_form_order [in ISL.Formulas]
+


+

Definition Index

+

A

+A [in ISL.PropQuantifiers]
+AccT_measure [in General.gentree]
+AccT_sind [in General.genT]
+AccT_rec [in General.genT]
+AccT_ind [in General.genT]
+AccT_rect [in General.genT]
+aderrec_sind [in General.ddT]
+aderrec_ind [in General.ddT]
+admD [in General.ddT]
+admDs [in General.ddT]
+adm_sind [in General.ddT]
+adm_rec [in General.ddT]
+adm_ind [in General.ddT]
+adm_rect [in General.ddT]
+Af [in ISL.PropQuantifiers]
+allPder_sind [in General.dd_fc]
+allPder_rec [in General.dd_fc]
+allPder_ind [in General.dd_fc]
+allPder_rect [in General.dd_fc]
+And [in Syntax.CML_Syntax]
+anon [in General.genT]
+apfst [in General.gen_seq]
+app_split_at_sind [in General.List_lemmasT]
+app_split_at_rec [in General.List_lemmasT]
+app_split_at_ind [in General.List_lemmasT]
+app_split_at_rect [in General.List_lemmasT]
+app_eq_consT [in General.List_lemmasT]
+app_eq_consT2 [in General.List_lemmasT]
+app_eq_cons [in General.List_lemmasT]
+app_assoc_cons [in General.gen_tacs]
+apsnd [in General.gen_seq]
+A_simplified [in ISL.Simp]
+A_eq [in ISL.PropQuantifiers]
+a_rule_form [in ISL.PropQuantifiers]
+a_rule_env [in ISL.PropQuantifiers]
+

B

+BotLRule_sind [in GL.GLS.GLS_calcs]
+BotLRule_rec [in GL.GLS.GLS_calcs]
+BotLRule_ind [in GL.GLS.GLS_calcs]
+BotLRule_rect [in GL.GLS.GLS_calcs]
+BotLRule_sind [in K.KS.KS_calc]
+BotLRule_rec [in K.KS.KS_calc]
+BotLRule_ind [in K.KS.KS_calc]
+BotLRule_rect [in K.KS.KS_calc]
+botRule_fc_sind [in General.dd_fc]
+botRule_fc_rec [in General.dd_fc]
+botRule_fc_ind [in General.dd_fc]
+botRule_fc_rect [in General.dd_fc]
+bot_is_rule [in General.dd_fc]
+

C

+Canopy [in GL.Interpolation.UIGL_Canopy]
+Canopy [in K.Interpolation.UIK_Canopy]
+can_exchR [in General.gen_seq]
+can_exchL [in General.gen_seq]
+can_wkL [in General.gen_seq]
+can_rel [in General.gstep]
+can_trf_rules_rtc_mono [in General.gstep]
+can_trf_rules_rtc [in General.gstep]
+can_trf_rules_rc_mono [in General.gstep]
+can_trf_rules_mono [in General.gstep]
+can_trf_rules_rc [in General.gstep]
+can_trf_rules [in General.gstep]
+ccps_sind [in General.ddT]
+ccps_rec [in General.ddT]
+ccps_ind [in General.ddT]
+ccps_rect [in General.ddT]
+choose_disj [in ISL.Environments]
+choose_conj [in ISL.Environments]
+Closure_sind [in GL.GLS.GLS_exch]
+Closure_rec [in GL.GLS.GLS_exch]
+Closure_ind [in GL.GLS.GLS_exch]
+Closure_rect [in GL.GLS.GLS_exch]
+Closure_sind [in K.KS.KS_exch]
+Closure_rec [in K.KS.KS_exch]
+Closure_ind [in K.KS.KS_exch]
+Closure_rect [in K.KS.KS_exch]
+clos_refl_transT_n1_sind [in General.rtcT]
+clos_refl_transT_n1_rec [in General.rtcT]
+clos_refl_transT_n1_ind [in General.rtcT]
+clos_refl_transT_n1_rect [in General.rtcT]
+clos_refl_transT_1n_sind [in General.rtcT]
+clos_refl_transT_1n_rec [in General.rtcT]
+clos_refl_transT_1n_ind [in General.rtcT]
+clos_refl_transT_1n_rect [in General.rtcT]
+clos_refl_transT_sind [in General.rtcT]
+clos_refl_transT_rec [in General.rtcT]
+clos_refl_transT_ind [in General.rtcT]
+clos_refl_transT_rect [in General.rtcT]
+clos_reflT_sind [in General.rtcT]
+clos_reflT_rec [in General.rtcT]
+clos_reflT_ind [in General.rtcT]
+clos_reflT_rect [in General.rtcT]
+conjunction [in ISL.Environments]
+critical_Seq_dec [in GL.Interpolation.UIGL_Canopy]
+critical_Seq [in GL.Interpolation.UIGL_Canopy]
+critical_Seq_dec [in K.Interpolation.UIK_Canopy]
+critical_Seq [in K.Interpolation.UIK_Canopy]
+ctr_R_sind [in K.KS.KS_ctr]
+ctr_R_rec [in K.KS.KS_ctr]
+ctr_R_ind [in K.KS.KS_ctr]
+ctr_R_rect [in K.KS.KS_ctr]
+ctr_L_sind [in K.KS.KS_ctr]
+ctr_L_rec [in K.KS.KS_ctr]
+ctr_L_ind [in K.KS.KS_ctr]
+ctr_L_rect [in K.KS.KS_ctr]
+ctr_R_sind [in GL.GLS.GLS_ctr]
+ctr_R_rec [in GL.GLS.GLS_ctr]
+ctr_R_ind [in GL.GLS.GLS_ctr]
+ctr_R_rect [in GL.GLS.GLS_ctr]
+ctr_L_sind [in GL.GLS.GLS_ctr]
+ctr_L_rec [in GL.GLS.GLS_ctr]
+ctr_L_ind [in GL.GLS.GLS_ctr]
+ctr_L_rect [in GL.GLS.GLS_ctr]
+CutRule_sind [in GL.GLS.GLS_cut_elim]
+CutRule_rec [in GL.GLS.GLS_cut_elim]
+CutRule_ind [in GL.GLS.GLS_cut_elim]
+CutRule_rect [in GL.GLS.GLS_cut_elim]
+CutRule_sind [in K.KS.KS_cut_elim]
+CutRule_rec [in K.KS.KS_cut_elim]
+CutRule_ind [in K.KS.KS_cut_elim]
+CutRule_rect [in K.KS.KS_cut_elim]
+

D

+dcl_allT [in General.ddT]
+dcsl_allT [in General.ddT]
+dec_GLS_rules [in GL.GLS.GLS_dec]
+dec_GLR_rule [in GL.GLS.GLS_dec]
+dec_box_in_list [in GL.GLS.GLS_dec]
+dec_ImpL_rule [in GL.GLS.GLS_dec]
+dec_ImpR_rule [in GL.GLS.GLS_dec]
+dec_imp_in [in GL.GLS.GLS_dec]
+dec_is_imp [in GL.GLS.GLS_dec]
+dec_init_rules [in GL.GLS.GLS_dec]
+dec_BotL_rule [in GL.GLS.GLS_dec]
+dec_IdB_rule [in GL.GLS.GLS_dec]
+dec_IdP_rule [in GL.GLS.GLS_dec]
+dec_GLS_init_rules [in GL.GLS.GLS_dec]
+dec_box_in [in GL.GLS.GLS_dec]
+dec_is_box [in GL.GLS.GLS_dec]
+dec_is_boxedT [in GL.GLS.GLS_dec]
+dec_prop_var_in [in GL.GLS.GLS_dec]
+dec_KS_rules [in K.KS.KS_dec]
+dec_KR_rule [in K.KS.KS_dec]
+dec_box_in_list [in K.KS.KS_dec]
+dec_ImpL_rule [in K.KS.KS_dec]
+dec_ImpR_rule [in K.KS.KS_dec]
+dec_imp_in [in K.KS.KS_dec]
+dec_is_imp [in K.KS.KS_dec]
+dec_BotL_rule [in K.KS.KS_dec]
+dec_IdP_rule [in K.KS.KS_dec]
+dec_KS_init_rules [in K.KS.KS_dec]
+dec_box_in [in K.KS.KS_dec]
+dec_is_box [in K.KS.KS_dec]
+dec_is_boxedT [in K.KS.KS_dec]
+dec_prop_var_in [in K.KS.KS_dec]
+dec_is_PropVar [in K.KS.KS_dec]
+dercl_derl [in General.ddT]
+dercl_dercsl_rect_mut [in General.ddT]
+dercl_rect_mut [in General.ddT]
+dercl_rec_mut [in General.ddT]
+dercl_ind_mut [in General.ddT]
+dercl_sind [in General.ddT]
+dercl_rec [in General.ddT]
+dercl_ind [in General.ddT]
+dercl_rect [in General.ddT]
+dercsl_dersl [in General.ddT]
+dercsl_rect_mut [in General.ddT]
+dercsl_rec_mut [in General.ddT]
+dercsl_ind_mut [in General.ddT]
+dercsl_sind [in General.ddT]
+dercsl_rec [in General.ddT]
+dercsl_ind [in General.ddT]
+dercsl_rect [in General.ddT]
+derI_rules_mono [in General.ddT]
+derl_fst_ext_rls' [in General.gen_seq]
+derl_seqrule' [in General.gen_seq]
+derl_height [in General.dd_fc]
+derl_adm [in General.ddT]
+derl_mono [in General.ddT]
+derl_mono' [in General.ddT]
+derl_deriv [in General.ddT]
+derl_deriv' [in General.ddT]
+derl_trans [in General.ddT]
+derl_derrec_nil [in General.ddT]
+derl_derrec [in General.ddT]
+derl_derrec_trans [in General.ddT]
+derl_dersl_rect_mut [in General.ddT]
+derl_rect_mut [in General.ddT]
+derl_rec_mut [in General.ddT]
+derl_ind_mut [in General.ddT]
+derl_sind [in General.ddT]
+derl_rec [in General.ddT]
+derl_ind [in General.ddT]
+derl_rect [in General.ddT]
+derrec_fc_height [in General.dd_fc]
+derrec_fc_size [in General.dd_fc]
+derrec_fc_concl [in General.dd_fc]
+derrec_fc_sind [in General.dd_fc]
+derrec_fc_rec [in General.dd_fc]
+derrec_fc_ind [in General.dd_fc]
+derrec_fc_rect [in General.dd_fc]
+derrec_concl [in General.dd_fc]
+derrec_size [in General.dd_fc]
+derrec_height [in General.dd_fc]
+derrec_rect_mut_all [in General.dd_fc]
+derrec_adm [in General.ddT]
+derrec_all_rect2_nops [in General.ddT]
+derrec_nil_derl [in General.ddT]
+derrec_derl_deriv [in General.ddT]
+derrec_rmono [in General.ddT]
+derrec_derrec [in General.ddT]
+derrec_dersrec_rect_mut [in General.ddT]
+derrec_ind_mut [in General.ddT]
+derrec_rec_mut [in General.ddT]
+derrec_rect_mut [in General.ddT]
+derrec_sind [in General.ddT]
+derrec_rec [in General.ddT]
+derrec_ind [in General.ddT]
+derrec_rect [in General.ddT]
+dersl_fst_ext_rls' [in General.gen_seq]
+dersl_seqrule' [in General.gen_seq]
+dersl_height [in General.dd_fc]
+dersl_adm [in General.ddT]
+dersl_mono [in General.ddT]
+dersl_mono' [in General.ddT]
+dersl_deriv [in General.ddT]
+dersl_deriv' [in General.ddT]
+dersl_trans [in General.ddT]
+dersl_dersrec_trans [in General.ddT]
+dersl_rect_mut [in General.ddT]
+dersl_rec_mut [in General.ddT]
+dersl_ind_mut [in General.ddT]
+dersl_sind [in General.ddT]
+dersl_rec [in General.ddT]
+dersl_ind [in General.ddT]
+dersl_rect [in General.ddT]
+dersrecD_forall [in General.ddT]
+dersrecD_all [in General.ddT]
+dersrecI_forall [in General.ddT]
+dersrecI_all [in General.ddT]
+dersrec_fc_height [in General.dd_fc]
+dersrec_fc_size [in General.dd_fc]
+dersrec_fc_concls [in General.dd_fc]
+dersrec_trees [in General.dd_fc]
+dersrec_fcs_sind [in General.dd_fc]
+dersrec_fcs_rec [in General.dd_fc]
+dersrec_fcs_ind [in General.dd_fc]
+dersrec_fcs_rect [in General.dd_fc]
+dersrec_single' [in General.dd_fc]
+dersrec_singleI' [in General.dd_fc]
+dersrec_singleD' [in General.dd_fc]
+dersrec_tl [in General.dd_fc]
+dersrec_hd [in General.dd_fc]
+dersrec_concls [in General.dd_fc]
+dersrec_size [in General.dd_fc]
+dersrec_height [in General.dd_fc]
+dersrec_doubleD [in General.ddT]
+dersrec_adm [in General.ddT]
+dersrec_nil_dersl [in General.ddT]
+dersrec_derl_deriv [in General.ddT]
+dersrec_rmono [in General.ddT]
+dersrec_singleI [in General.ddT]
+dersrec_singleD [in General.ddT]
+dersrec_appI [in General.ddT]
+dersrec_appJ [in General.ddT]
+dersrec_appR [in General.ddT]
+dersrec_appL [in General.ddT]
+dersrec_appD [in General.ddT]
+dersrec_derrec [in General.ddT]
+dersrec_ind_mut [in General.ddT]
+dersrec_rec_mut [in General.ddT]
+dersrec_rect_mut [in General.ddT]
+dersrec_sind [in General.ddT]
+dersrec_rec [in General.ddT]
+dersrec_ind [in General.ddT]
+dersrec_rect [in General.ddT]
+der_trf_derl' [in General.gstep]
+der_botr_ps [in General.dd_fc]
+Diam [in Syntax.CML_Syntax]
+dim_all8 [in General.ddT]
+dim_all4 [in General.ddT]
+dim_all3 [in General.ddT]
+dim_allT [in General.ddT]
+dim_all [in General.ddT]
+disjunction [in ISL.Environments]
+dp [in General.dd_fc]
+drl_allT' [in General.ddT]
+drl_allT [in General.ddT]
+drsl_allT' [in General.ddT]
+drsl_allT [in General.ddT]
+dt2fun [in General.gentree]
+

E

+E [in ISL.PropQuantifiers]
+EA [in ISL.PropQuantifiers]
+Ef [in ISL.PropQuantifiers]
+empty [in ISL.Environments]
+emptyT_sind [in General.genT]
+emptyT_rec [in General.genT]
+emptyT_ind [in General.genT]
+emptyT_rect [in General.genT]
+empty_seq_dec [in K.Interpolation.UIK_basics]
+empty_seq_dec [in GL.Interpolation.UIGL_LexSeq]
+empty_sind [in General.genT]
+empty_rec [in General.genT]
+empty_ind [in General.genT]
+empty_rect [in General.genT]
+empty_relT_sind [in General.genT]
+empty_relT_rec [in General.genT]
+empty_relT_ind [in General.genT]
+empty_relT_rect [in General.genT]
+env [in ISL.Environments]
+env_order_refl [in ISL.Order]
+env_order [in ISL.Order]
+env_weight [in ISL.Order]
+eq_nnn_app [in General.List_lemmasT]
+eq_dec_seqs [in Syntax.list_lems]
+eq_dec_listsF [in Syntax.list_lems]
+ExcClosure_sind [in GL.GLS.GLS_exch]
+ExcClosure_rec [in GL.GLS.GLS_exch]
+ExcClosure_ind [in GL.GLS.GLS_exch]
+ExcClosure_rect [in GL.GLS.GLS_exch]
+ExcClosure_sind [in K.KS.KS_exch]
+ExcClosure_rec [in K.KS.KS_exch]
+ExcClosure_ind [in K.KS.KS_exch]
+ExcClosure_rect [in K.KS.KS_exch]
+exists_dec [in ISL.DecisionProcedure]
+ex1 [in ISL.Simp]
+ex2 [in ISL.Simp]
+ex3 [in ISL.Simp]
+ex4 [in ISL.Simp]
+ex5 [in ISL.Simp]
+ex6 [in ISL.Simp]
+E_simplified [in ISL.Simp]
+E_eq [in ISL.PropQuantifiers]
+e_rule [in ISL.PropQuantifiers]
+

F

+fce3 [in General.ddT]
+fextI_eqc' [in General.gen_seq]
+fextI' [in General.gen_seq]
+finite_premises_of_S [in GL.GLS.GLS_der_dec]
+finite_BotL_premises_of_S [in GL.GLS.GLS_der_dec]
+finite_IdB_premises_of_S [in GL.GLS.GLS_der_dec]
+finite_IdP_premises_of_S [in GL.GLS.GLS_der_dec]
+finite_GLR_premises_of_S [in GL.GLS.GLS_der_dec]
+finite_ImpL_premises_of_S [in GL.GLS.GLS_der_dec]
+finite_ImpR_premises_of_S [in GL.GLS.GLS_der_dec]
+finite_KR_premises_of_S [in K.KS.KS_termination_KR]
+finite_ImpL_premises_of_S [in K.KS.KS_termination_ImpL]
+finite_ImpR_premises_of_S [in K.KS.KS_termination_ImpR]
+flatmap [in K.Interpolation.UIK_irred_short]
+flatmap [in GL.Interpolation.UIGL_irred_short]
+flatten_list [in GL.GLS.GLS_der_dec]
+flatten_list [in K.KS.KS_termination_prelims]
+fmlsext [in General.gen_seq]
+ForallTD_forall [in General.genT]
+ForallTI_forall [in General.genT]
+ForallT_2I [in General.genT]
+ForallT_2I' [in General.genT]
+ForallT_D2 [in General.genT]
+ForallT_D1 [in General.genT]
+ForallT_2D [in General.genT]
+ForallT_appendI [in General.genT]
+ForallT_appendI' [in General.genT]
+ForallT_appendD2 [in General.genT]
+ForallT_appendD1 [in General.genT]
+ForallT_appendD [in General.genT]
+ForallT_singleI [in General.genT]
+ForallT_singleD [in General.genT]
+ForallT_sind [in General.genT]
+ForallT_rec [in General.genT]
+ForallT_ind [in General.genT]
+ForallT_rect [in General.genT]
+Forall2T_sind [in General.genT]
+Forall2T_rec [in General.genT]
+Forall2T_ind [in General.genT]
+Forall2T_rect [in General.genT]
+form_of_MPropF [in UIML_extraction.UIML_extraction]
+form_order [in ISL.Formulas]
+form_to_gen_tree [in ISL.Formulas]
+form_sind [in ISL.Formulas]
+form_rec [in ISL.Formulas]
+form_ind [in ISL.Formulas]
+form_rect [in ISL.Formulas]
+fst_rel_sind [in General.gen_seq]
+fst_rel_rec [in General.gen_seq]
+fst_rel_ind [in General.gen_seq]
+fst_rel_rect [in General.gen_seq]
+fst_ext_rls_derl_fst_ext_rls' [in General.gen_seq]
+fst_ext_rls_fst_ext_rls' [in General.gen_seq]
+fst_ext_rls_sind [in General.gen_seq]
+fst_ext_rls_rec [in General.gen_seq]
+fst_ext_rls_ind [in General.gen_seq]
+fst_ext_rls_rect [in General.gen_seq]
+

G

+gen_step2s_lem [in General.gstep]
+gen_steps_lem [in General.gstep]
+gen_step2s [in General.gstep]
+gen_steps [in General.gstep]
+gen_step2_lemT [in General.gstep]
+gen_step2_lem [in General.gstep]
+gen_step_lemT [in General.gstep]
+gen_step_lem [in General.gstep]
+gen_step2_empty [in General.gstep]
+gen_step2 [in General.gstep]
+gen_step'_sind [in General.gstep]
+gen_step'_rec [in General.gstep]
+gen_step'_ind [in General.gstep]
+gen_step'_rect [in General.gstep]
+gen_step [in General.gstep]
+gen_ext_diff [in General.univ_gen_ext]
+gen_ext_one [in General.univ_gen_ext]
+gen_ext_sameR [in General.univ_gen_ext]
+gen_ext_sameL [in General.univ_gen_ext]
+gen_ext [in General.univ_gen_ext]
+gen_step2_c [in General.gentree]
+gen_step2_tr [in General.gentree]
+gen_step_c [in General.gentree]
+gen_step_tr [in General.gentree]
+gen_tree_to_form [in ISL.Formulas]
+get_dpD [in General.dd_fc]
+get_D [in General.dd_fc]
+Gflatmap_sind [in K.Interpolation.UIK_irred_short]
+Gflatmap_ind [in K.Interpolation.UIK_irred_short]
+Gflatmap_sind [in GL.Interpolation.UIGL_irred_short]
+Gflatmap_ind [in GL.Interpolation.UIGL_irred_short]
+gf_step2_tr [in General.gentree]
+gf2_step_tr [in General.gentree]
+Gimap_sind [in K.Interpolation.UIK_braga]
+Gimap_ind [in K.Interpolation.UIK_braga]
+Gimap_sind [in GL.Interpolation.UIGL_braga]
+Gimap_ind [in GL.Interpolation.UIGL_braga]
+Girred_ind [in K.Interpolation.UIK_irred_short]
+Girred_ind [in GL.Interpolation.UIGL_irred_short]
+GLRRule_sind [in GL.GLS.GLS_calcs]
+GLRRule_rec [in GL.GLS.GLS_calcs]
+GLRRule_ind [in GL.GLS.GLS_calcs]
+GLRRule_rect [in GL.GLS.GLS_calcs]
+GLR_help2 [in GL.GLS.GLS_der_dec]
+GLR_help02 [in GL.GLS.GLS_der_dec]
+GLR_help1 [in GL.GLS.GLS_der_dec]
+GLR_help01 [in GL.GLS.GLS_der_dec]
+GLR_prems [in GL.Interpolation.UIGL_LexSeq]
+GLS_drv [in GL.GLS.GLS_calcs]
+GLS_prv [in GL.GLS.GLS_calcs]
+GLS_rules_sind [in GL.GLS.GLS_calcs]
+GLS_rules_rec [in GL.GLS.GLS_calcs]
+GLS_rules_ind [in GL.GLS.GLS_calcs]
+GLS_rules_rect [in GL.GLS.GLS_calcs]
+GLS_cut_drv [in GL.GLS.GLS_cut_elim]
+GLS_cut_prv [in GL.GLS.GLS_cut_elim]
+GLS_cut_rules_sind [in GL.GLS.GLS_cut_elim]
+GLS_cut_rules_rec [in GL.GLS.GLS_cut_elim]
+GLS_cut_rules_ind [in GL.GLS.GLS_cut_elim]
+GLS_cut_rules_rect [in GL.GLS.GLS_cut_elim]
+gl_UI [in UIML_extraction.UIML_extraction]
+GUI_tot [in K.Interpolation.UIK_braga]
+GUI_tot [in GL.Interpolation.UIGL_braga]
+

H

+height [in ISL.SequentProps]
+height_step2_tr [in General.gentree]
+

I

+IdBRule_sind [in GL.GLS.GLS_calcs]
+IdBRule_rec [in GL.GLS.GLS_calcs]
+IdBRule_ind [in GL.GLS.GLS_calcs]
+IdBRule_rect [in GL.GLS.GLS_calcs]
+IdPRule_sind [in GL.GLS.GLS_calcs]
+IdPRule_rec [in GL.GLS.GLS_calcs]
+IdPRule_ind [in GL.GLS.GLS_calcs]
+IdPRule_rect [in GL.GLS.GLS_calcs]
+IdPRule_sind [in K.KS.KS_calc]
+IdPRule_rec [in K.KS.KS_calc]
+IdPRule_ind [in K.KS.KS_calc]
+IdPRule_rect [in K.KS.KS_calc]
+Idrule_sind [in General.gen_seq]
+Idrule_rec [in General.gen_seq]
+Idrule_ind [in General.gen_seq]
+Idrule_rect [in General.gen_seq]
+Id_InT_Canopy [in GL.Interpolation.UIGL_Canopy]
+iffT_D2 [in General.genT]
+iffT_D1 [in General.genT]
+iffT_sym [in General.genT]
+imap [in K.Interpolation.UIK_braga]
+imap [in GL.Interpolation.UIGL_braga]
+ImpLRule_sind [in GL.GLS.GLS_calcs]
+ImpLRule_rec [in GL.GLS.GLS_calcs]
+ImpLRule_ind [in GL.GLS.GLS_calcs]
+ImpLRule_rect [in GL.GLS.GLS_calcs]
+ImpLRule_sind [in K.KS.KS_calc]
+ImpLRule_rec [in K.KS.KS_calc]
+ImpLRule_ind [in K.KS.KS_calc]
+ImpLRule_rect [in K.KS.KS_calc]
+ImpL_help1 [in GL.GLS.GLS_der_dec]
+ImpL_help01 [in GL.GLS.GLS_der_dec]
+ImpL_help2 [in GL.GLS.GLS_der_dec]
+ImpL_help02 [in GL.GLS.GLS_der_dec]
+ImpL_help002 [in GL.GLS.GLS_der_dec]
+ImpL_help1 [in K.KS.KS_termination_ImpL]
+ImpL_help01 [in K.KS.KS_termination_ImpL]
+ImpL_help2 [in K.KS.KS_termination_ImpL]
+ImpL_help02 [in K.KS.KS_termination_ImpL]
+ImpL_help002 [in K.KS.KS_termination_ImpL]
+ImpRRule_sind [in GL.GLS.GLS_calcs]
+ImpRRule_rec [in GL.GLS.GLS_calcs]
+ImpRRule_ind [in GL.GLS.GLS_calcs]
+ImpRRule_rect [in GL.GLS.GLS_calcs]
+ImpRRule_sind [in K.KS.KS_calc]
+ImpRRule_rec [in K.KS.KS_calc]
+ImpRRule_ind [in K.KS.KS_calc]
+ImpRRule_rect [in K.KS.KS_calc]
+ImpR_help2 [in GL.GLS.GLS_der_dec]
+ImpR_help02 [in GL.GLS.GLS_der_dec]
+ImpR_help002 [in GL.GLS.GLS_der_dec]
+ImpR_help1 [in GL.GLS.GLS_der_dec]
+ImpR_help01 [in GL.GLS.GLS_der_dec]
+ImpR_help2 [in K.KS.KS_termination_ImpR]
+ImpR_help02 [in K.KS.KS_termination_ImpR]
+ImpR_help002 [in K.KS.KS_termination_ImpR]
+ImpR_help1 [in K.KS.KS_termination_ImpR]
+ImpR_help01 [in K.KS.KS_termination_ImpR]
+InT_trans_flatten_list [in GL.GLS.GLS_der_dec]
+InT_flatten_list_InT_elem [in GL.GLS.GLS_der_dec]
+InT_map_iff [in GL.GLS.GLS_der_dec]
+InT_trans_flatten_list [in K.KS.KS_termination_prelims]
+InT_flatten_list_InT_elem [in K.KS.KS_termination_prelims]
+InT_map_iff [in K.KS.KS_termination_prelims]
+InT_or_app [in General.List_lemmasT]
+InT_app_or [in General.List_lemmasT]
+InT_pair_triple_sind [in General.List_lemmasT]
+InT_pair_triple_rec [in General.List_lemmasT]
+InT_pair_triple_ind [in General.List_lemmasT]
+InT_pair_triple_rect [in General.List_lemmasT]
+InT_mapI [in General.genT]
+InT_map_iffT [in General.genT]
+InT_2nd [in General.genT]
+InT_eq [in General.genT]
+InT_sind [in General.genT]
+InT_rec [in General.genT]
+InT_ind [in General.genT]
+InT_rect [in General.genT]
+invprem [in GL.Interpolation.UIGL_Canopy]
+invprem [in K.Interpolation.UIK_Canopy]
+inv_prems [in GL.Interpolation.UIGL_Canopy]
+inv_prems [in K.Interpolation.UIK_Canopy]
+In_pos_top_imps_split_l [in GL.GLS.GLS_der_dec]
+In_InT_pair [in GL.GLS.GLS_der_dec]
+In_InT_pair [in K.KS.KS_termination_prelims]
+in_nextup_fc_nu [in General.dd_fc]
+in_nextup_nu [in General.dd_fc]
+in_nextup_fc_sind [in General.dd_fc]
+in_nextup_fc_rec [in General.dd_fc]
+in_nextup_fc_ind [in General.dd_fc]
+in_nextup_fc_rect [in General.dd_fc]
+in_nextup_sind [in General.dd_fc]
+in_nextup_rec [in General.dd_fc]
+in_nextup_ind [in General.dd_fc]
+in_nextup_rect [in General.dd_fc]
+in_dersrec_sind [in General.dd_fc]
+in_dersrec_rec [in General.dd_fc]
+in_dersrec_ind [in General.dd_fc]
+in_dersrec_rect [in General.dd_fc]
+in_nextup_height [in General.gentree]
+in_nextup_size [in General.gentree]
+in_adm [in General.ddT]
+In_dec [in Syntax.remove_list_lems]
+In_pos_top_imps_split_l [in K.KS.KS_termination_ImpR]
+in_top_boxes [in GL.GLS.GLS_dec]
+In_InT_seqs [in Syntax.list_lems]
+in_top_boxes [in K.KS.KS_dec]
+in_subset [in ISL.Environments]
+in_map [in ISL.Environments]
+in_map_aux [in ISL.Environments]
+irred [in K.Interpolation.UIK_irred_short]
+irred [in GL.Interpolation.UIGL_irred_short]
+irreducible [in ISL.Environments]
+isl_simplified_A [in UIML_extraction.UIML_extraction]
+isl_simplified_E [in UIML_extraction.UIML_extraction]
+isl_simp [in UIML_extraction.UIML_extraction]
+isl_A [in UIML_extraction.UIML_extraction]
+isl_E [in UIML_extraction.UIML_extraction]
+is_init [in K.Interpolation.UIK_basics]
+is_mhd [in GL.GLS.GLS_der_dec]
+is_mhd [in K.KS.KS_termination_prelims]
+is_Prime [in Syntax.CML_Syntax]
+is_Boxed_list [in Syntax.CML_Syntax]
+is_boxedT [in Syntax.CML_Syntax]
+is_atomicT [in Syntax.CML_Syntax]
+is_nextup_sind [in General.dd_fc]
+is_nextup_rec [in General.dd_fc]
+is_nextup_ind [in General.dd_fc]
+is_nextup_rect [in General.dd_fc]
+is_Prime_dec [in GL.Interpolation.UIGL_Canopy]
+is_init [in GL.Interpolation.UIGL_LexSeq]
+is_box [in ISL.Environments]
+is_negation [in ISL.Environments]
+is_implication [in ISL.Environments]
+is_double_negation [in ISL.Environments]
+is_Prime_dec [in K.Interpolation.UIK_Canopy]
+

K

+KRRule_sind [in K.KS.KS_calc]
+KRRule_rec [in K.KS.KS_calc]
+KRRule_ind [in K.KS.KS_calc]
+KRRule_rect [in K.KS.KS_calc]
+KR_prems [in K.Interpolation.UIK_basics]
+KR_help2 [in K.KS.KS_termination_KR]
+KR_help02 [in K.KS.KS_termination_KR]
+KR_help1 [in K.KS.KS_termination_KR]
+KR_help01 [in K.KS.KS_termination_KR]
+KS_cut_drv [in K.KS.KS_cut_elim]
+KS_cut_prv [in K.KS.KS_cut_elim]
+KS_cut_rules_sind [in K.KS.KS_cut_elim]
+KS_cut_rules_rec [in K.KS.KS_cut_elim]
+KS_cut_rules_ind [in K.KS.KS_cut_elim]
+KS_cut_rules_rect [in K.KS.KS_cut_elim]
+KS_drv [in K.KS.KS_calc]
+KS_prv [in K.KS.KS_calc]
+KS_rules_sind [in K.KS.KS_calc]
+KS_rules_rec [in K.KS.KS_calc]
+KS_rules_ind [in K.KS.KS_calc]
+KS_rules_rect [in K.KS.KS_calc]
+k_UI [in UIML_extraction.UIML_extraction]
+

L

+length_form [in GL.GLS.GLS_termination_measure]
+less_imp [in GL.Interpolation.UIGL_Canopy]
+less_thanS [in GL.GLS.GLS_termination_measure]
+less_imp [in K.Interpolation.UIK_Canopy]
+leT_trans [in General.genT]
+leT_S_n [in General.genT]
+leT_sind [in General.genT]
+leT_rec [in General.genT]
+leT_ind [in General.genT]
+leT_rect [in General.genT]
+LexSeq [in GL.Interpolation.UIGL_LexSeq]
+LexSeq_ind [in GL.Interpolation.UIGL_LexSeq]
+lex_sind [in K.Interpolation.UIK_Def_measure]
+lex_ind [in K.Interpolation.UIK_Def_measure]
+lex_sind [in GL.GLS.DLW_wf_lex]
+lex_ind [in GL.GLS.DLW_wf_lex]
+lex_sind [in GL.Interpolation.UIGL_Def_measure]
+lex_ind [in GL.Interpolation.UIGL_Def_measure]
+Lindenbaum_Tarski_preorder [in ISL.Optimizations]
+listInserts [in GL.GLS.GLS_der_dec]
+listInserts [in K.KS.KS_termination_prelims]
+listInsertsL_Seqs [in GL.GLS.GLS_der_dec]
+listInsertsL_Seqs [in K.KS.KS_termination_prelims]
+listInsertsRL_Seqs [in GL.GLS.GLS_der_dec]
+listInsertsRL_Seqs [in K.KS.KS_termination_prelims]
+listInsertsR_Seqs [in GL.GLS.GLS_der_dec]
+listInsertsR_Seqs [in K.KS.KS_termination_prelims]
+list_is_nil [in K.Interpolation.UIK_irred_high_level]
+list_of_premises [in K.KS.KS_termination]
+list_prop_LF [in K.Interpolation.UIK_basics]
+list_prop_F [in K.Interpolation.UIK_basics]
+list_disj [in K.Interpolation.UIK_basics]
+list_conj [in K.Interpolation.UIK_basics]
+list_of_premises [in GL.GLS.GLS_der_dec]
+list_of_splits [in GL.GLS.GLS_der_dec]
+list_of_splits [in K.KS.KS_termination_prelims]
+list_prop_LF [in GL.Interpolation.UIGL_basics]
+list_prop_F [in GL.Interpolation.UIGL_basics]
+list_disj [in GL.Interpolation.UIGL_basics]
+list_conj [in GL.Interpolation.UIGL_basics]
+list_exch_R_sind [in K.KS.KS_exch_prelims]
+list_exch_R_rec [in K.KS.KS_exch_prelims]
+list_exch_R_ind [in K.KS.KS_exch_prelims]
+list_exch_R_rect [in K.KS.KS_exch_prelims]
+list_exch_L_sind [in K.KS.KS_exch_prelims]
+list_exch_L_rec [in K.KS.KS_exch_prelims]
+list_exch_L_ind [in K.KS.KS_exch_prelims]
+list_exch_L_rect [in K.KS.KS_exch_prelims]
+list_exch_R_sind [in GL.GLS.GLS_exch]
+list_exch_R_rec [in GL.GLS.GLS_exch]
+list_exch_R_ind [in GL.GLS.GLS_exch]
+list_exch_R_rect [in GL.GLS.GLS_exch]
+list_exch_L_sind [in GL.GLS.GLS_exch]
+list_exch_L_rec [in GL.GLS.GLS_exch]
+list_exch_L_ind [in GL.GLS.GLS_exch]
+list_exch_L_rect [in GL.GLS.GLS_exch]
+list_is_nil [in K.Interpolation.UIK_irred_short]
+list_is_nil [in GL.Interpolation.UIGL_irred_high_level]
+list_is_nil [in GL.Interpolation.UIGL_irred_short]
+LtSeq [in K.Interpolation.UIK_basics]
+LtSeq_ind [in K.Interpolation.UIK_basics]
+

M

+make_impl [in ISL.Environments]
+make_disj [in ISL.Environments]
+make_conj [in ISL.Environments]
+measure [in General.gentree]
+measure [in GL.GLS.GLS_termination_measure]
+measure [in GL.Interpolation.UIGL_LexSeq]
+measure [in K.KS.KS_termination_measure]
+measure_rect [in K.Interpolation.UIK_Def_measure]
+measure_rect [in GL.GLS.DLW_wf_lex]
+measure_rect [in GL.Interpolation.UIGL_Def_measure]
+mhd [in K.KS.KS_termination]
+MPropF_sind [in Syntax.CML_Syntax]
+MPropF_rec [in Syntax.CML_Syntax]
+MPropF_ind [in Syntax.CML_Syntax]
+MPropF_rect [in Syntax.CML_Syntax]
+MPropF_of_form [in UIML_extraction.UIML_extraction]
+

N

+N [in GL.Interpolation.UIGL_braga]
+Neg [in Syntax.CML_Syntax]
+nextup [in General.dd_fc]
+nextup_in_nu_fc [in General.dd_fc]
+nextup_in_nu [in General.dd_fc]
+nil_eq_appT [in General.List_lemmasT]
+nil_eq_app [in General.List_lemmasT]
+nil_eq_list [in General.List_lemmasT]
+nobox_gen_ext [in Syntax.CML_Syntax]
+nodupseq [in GL.Interpolation.UIGL_nodupseq]
+non_empty [in General.List_lemmasT]
+nth_split [in GL.GLS.GLS_der_dec]
+nth_split [in K.KS.KS_termination_prelims]
+N_pwc [in GL.Interpolation.UIGL_braga]
+n_imp_subformS [in GL.GLS.GLS_termination_measure]
+n_imp_subformLF [in GL.GLS.GLS_termination_measure]
+n_imp_subformF [in GL.GLS.GLS_termination_measure]
+n_imp_subformS [in K.Interpolation.UIK_Canopy]
+n_imp_subformLF [in K.Interpolation.UIK_Canopy]
+n_imp_subformF [in K.Interpolation.UIK_Canopy]
+

O

+obviously_smaller [in ISL.Environments]
+occurs_in [in ISL.Formulas]
+open_boxes [in ISL.Environments]
+open_box [in ISL.Environments]
+Or [in Syntax.CML_Syntax]
+

P

+PermutationTS [in GL.Interpolation.UIGL_PermutationTS]
+PermutationT_sind [in GL.Interpolation.UIGL_PermutationT]
+PermutationT_rec [in GL.Interpolation.UIGL_PermutationT]
+PermutationT_ind [in GL.Interpolation.UIGL_PermutationT]
+PermutationT_rect [in GL.Interpolation.UIGL_PermutationT]
+pointed_env_ms_order [in ISL.Order]
+pointed_env_order [in ISL.Order]
+pointed_env [in ISL.Order]
+pos_top_imps [in GL.GLS.GLS_der_dec]
+pos_top_imps [in K.KS.KS_termination_prelims]
+prems_Box_R [in GL.GLS.GLS_der_dec]
+prems_Imp_L [in GL.GLS.GLS_der_dec]
+prems_Imp_R [in GL.GLS.GLS_der_dec]
+prems_Box_R [in K.KS.KS_termination_KR]
+prems_Imp_L [in K.KS.KS_termination_ImpL]
+prems_Imp_R [in K.KS.KS_termination_ImpR]
+proj1_sigT2 [in GL.GLS.GLS_der_dec]
+proj1_sigT2 [in K.KS.KS_termination_prelims]
+proj2_sigT2 [in GL.GLS.GLS_der_dec]
+proj2_sigT2 [in K.KS.KS_termination_prelims]
+propvar_subform_list [in K.Interpolation.UIK_UI_prelims]
+propvar_subform [in K.Interpolation.UIK_UI_prelims]
+propvar_subform_list [in K.Interpolation.K_Craig_Interp]
+propvar_subform [in K.Interpolation.K_Craig_Interp]
+propvar_subform_list [in GL.Interpolation.UIGL_UI_prelims]
+propvar_subform [in GL.Interpolation.UIGL_UI_prelims]
+Provable_sind [in ISL.Sequents]
+Provable_rec [in ISL.Sequents]
+Provable_ind [in ISL.Sequents]
+Provable_rect [in ISL.Sequents]
+

R

+radmD [in General.gstep]
+radm_sind [in General.gstep]
+radm_rec [in General.gstep]
+radm_ind [in General.gstep]
+radm_rect [in General.gstep]
+rel [in General.gen_tacs]
+relationT [in General.genT]
+relmap_sind [in General.gen_seq]
+relmap_rec [in General.gen_seq]
+relmap_ind [in General.gen_seq]
+relmap_rect [in General.gen_seq]
+rel_admD [in General.gstep]
+rel_adm_sind [in General.gstep]
+rel_adm_rec [in General.gstep]
+rel_adm_ind [in General.gstep]
+rel_adm_rect [in General.gstep]
+remove_nth [in GL.GLS.GLS_der_dec]
+remove_nth [in K.KS.KS_termination_prelims]
+remove_list [in Syntax.remove_list_lems]
+replace [in GL.Interpolation.UIGL_Canopy_ImpR]
+req [in General.gen]
+restr_list_prop [in K.Interpolation.UIK_basics]
+restr_list_prop [in GL.Interpolation.UIGL_basics]
+rest_gen_ext [in General.univ_gen_ext]
+rev_pair [in General.gen_seq]
+rls [in General.gen]
+rlsmap_sind [in General.gen_seq]
+rlsmap_rec [in General.gen_seq]
+rlsmap_ind [in General.gen_seq]
+rlsmap_rect [in General.gen_seq]
+rlsT [in General.genT]
+rm [in ISL.Environments]
+rsub [in General.gen]
+rsubD [in General.gen]
+rsubI [in General.gen]
+rsub_adm [in General.ddT]
+rsub_derl_adm [in General.ddT]
+rsub_derl [in General.ddT]
+rsub_imp [in General.gen]
+rUnion_sind [in General.gstep]
+rUnion_rec [in General.gstep]
+rUnion_ind [in General.gstep]
+rUnion_rect [in General.gstep]
+runion_sind [in General.gstep]
+runion_rec [in General.gstep]
+runion_ind [in General.gstep]
+runion_rect [in General.gstep]
+

S

+Seq [in GL.GLS.GLS_calcs]
+Seq [in K.KS.KS_calc]
+seqext [in General.gen_seq]
+seqrule_mono' [in General.gen_seq]
+seqrule_s_sind [in General.gen_seq]
+seqrule_s_rec [in General.gen_seq]
+seqrule_s_ind [in General.gen_seq]
+seqrule_s_rect [in General.gen_seq]
+seqrule_derl_seqrule' [in General.gen_seq]
+seqrule_seqrule' [in General.gen_seq]
+seqrule_sind [in General.gen_seq]
+seqrule_rec [in General.gen_seq]
+seqrule_ind [in General.gen_seq]
+seqrule_rect [in General.gen_seq]
+seqrule'_sind [in General.gen_seq]
+seqrule'_rec [in General.gen_seq]
+seqrule'_ind [in General.gen_seq]
+seqrule'_rect [in General.gen_seq]
+seqs_in_splitT [in Syntax.list_lems]
+simp [in ISL.Simp]
+simp_imps [in ISL.Simp]
+simp_imp [in ISL.Simp]
+simp_ands [in ISL.Simp]
+simp_ors [in ISL.Simp]
+single [in General.swappedT]
+single_eq_listT_nobrac [in General.List_lemmasT]
+single_eq_listT [in General.List_lemmasT]
+single_eq_list [in General.List_lemmasT]
+sing_empty_sind [in General.gen_seq]
+sing_empty_rec [in General.gen_seq]
+sing_empty_ind [in General.gen_seq]
+sing_empty_rect [in General.gen_seq]
+size [in Syntax.CML_Syntax]
+size_LF [in Syntax.CML_Syntax]
+size_step2_tr [in General.gentree]
+snd_rel_sind [in General.gen_seq]
+snd_rel_rec [in General.gen_seq]
+snd_rel_ind [in General.gen_seq]
+snd_rel_rect [in General.gen_seq]
+snd_ext_rls_sind [in General.gen_seq]
+snd_ext_rls_rec [in General.gen_seq]
+snd_ext_rls_ind [in General.gen_seq]
+snd_ext_rls_rect [in General.gen_seq]
+subformlist [in Syntax.CML_Syntax]
+subform_boxesS [in GL.GLS.GLS_termination_measure]
+subform_boxesLF [in GL.GLS.GLS_termination_measure]
+subform_boxesF [in GL.GLS.GLS_termination_measure]
+subform_sind [in ISL.Formulas]
+subform_ind [in ISL.Formulas]
+subst [in Syntax.CML_Syntax]
+sumh_step2_tr [in General.gentree]
+sum_step2_tr_D_gf2 [in General.gentree]
+sum_step2_tr [in General.gentree]
+swapped_gen_sind [in General.swappedT]
+swapped_gen_rec [in General.swappedT]
+swapped_gen_ind [in General.swappedT]
+swapped_gen_rect [in General.swappedT]
+swapped_spec_sind [in General.swappedT]
+swapped_spec_rec [in General.swappedT]
+swapped_spec_ind [in General.swappedT]
+swapped_spec_rect [in General.swappedT]
+swapped_single [in General.swappedT]
+swapped_sind [in General.swappedT]
+swapped_rec [in General.swappedT]
+swapped_ind [in General.swappedT]
+swapped_rect [in General.swappedT]
+

T

+Top [in Syntax.CML_Syntax]
+top_boxes_nobox_gen_ext [in GL.GLS.GLS_der_dec]
+top_imps [in GL.GLS.GLS_der_dec]
+top_boxes_nobox_gen_ext [in K.KS.KS_termination_prelims]
+top_imps [in K.KS.KS_termination_prelims]
+top_boxes [in Syntax.CML_Syntax]
+transitiveT [in General.rtcT]
+transitiveT [in General.genT]
+trf [in General.gen_tacs]
+

U

+UI [in K.Interpolation.UIK_braga]
+UI [in GL.Interpolation.UIGL_braga]
+unboxed_list [in Syntax.CML_Syntax]
+unBox_formula [in Syntax.CML_Syntax]
+unit_eq_appT2 [in General.List_lemmasT]
+unit_eq_app [in General.List_lemmasT]
+univ_gen_mod_sind [in General.univ_gen_mod]
+univ_gen_mod_rec [in General.univ_gen_mod]
+univ_gen_mod_ind [in General.univ_gen_mod]
+univ_gen_mod_rect [in General.univ_gen_mod]
+univ_gen_ext_sind [in General.univ_gen_ext]
+univ_gen_ext_rec [in General.univ_gen_ext]
+univ_gen_ext_ind [in General.univ_gen_ext]
+univ_gen_ext_rect [in General.univ_gen_ext]
+Unnamed_thm0 [in General.swappedT]
+Unnamed_thm [in General.swappedT]
+usable_boxes [in GL.GLS.GLS_termination_measure]
+

V

+variable [in ISL.Formulas]
+vars_incl [in ISL.PropQuantifiers]
+var_not_in_env [in ISL.Environments]
+

W

+weight [in ISL.Formulas]
+weight_ind [in ISL.Formulas]
+well_foundedT [in General.genT]
+wf_env_order [in ISL.Order]
+wkL_valid' [in General.gen_seq]
+wkL_valid [in General.gen_seq]
+wkn_R_sind [in K.KS.KS_wkn]
+wkn_R_rec [in K.KS.KS_wkn]
+wkn_R_ind [in K.KS.KS_wkn]
+wkn_R_rect [in K.KS.KS_wkn]
+wkn_L_sind [in K.KS.KS_wkn]
+wkn_L_rec [in K.KS.KS_wkn]
+wkn_L_ind [in K.KS.KS_wkn]
+wkn_L_rect [in K.KS.KS_wkn]
+wkn_R_sind [in GL.GLS.GLS_wkn]
+wkn_R_rec [in GL.GLS.GLS_wkn]
+wkn_R_ind [in GL.GLS.GLS_wkn]
+wkn_R_rect [in GL.GLS.GLS_wkn]
+wkn_L_sind [in GL.GLS.GLS_wkn]
+wkn_L_rec [in GL.GLS.GLS_wkn]
+wkn_L_ind [in GL.GLS.GLS_wkn]
+wkn_L_rect [in GL.GLS.GLS_wkn]
+

X

+XBoxed_list [in GL.GLS.GLS_calcs]
+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Global IndexABCDEFGHIJKLMNOPQRSTUVWXYZ_other(2915 entries)
Notation IndexABCDEFGHIJKLMNOPQRSTUVWXYZ_other(42 entries)
Variable IndexABCDEFGHIJKLMNOPQRSTUVWXYZ_other(114 entries)
Library IndexABCDEFGHIJKLMNOPQRSTUVWXYZ_other(97 entries)
Lemma IndexABCDEFGHIJKLMNOPQRSTUVWXYZ_other(1372 entries)
Constructor IndexABCDEFGHIJKLMNOPQRSTUVWXYZ_other(190 entries)
Inductive IndexABCDEFGHIJKLMNOPQRSTUVWXYZ_other(102 entries)
Section IndexABCDEFGHIJKLMNOPQRSTUVWXYZ_other(66 entries)
Instance IndexABCDEFGHIJKLMNOPQRSTUVWXYZ_other(25 entries)
Definition IndexABCDEFGHIJKLMNOPQRSTUVWXYZ_other(907 entries)
+
+ +
+ + + diff --git a/toc.html b/toc.html new file mode 100644 index 0000000..711fbea --- /dev/null +++ b/toc.html @@ -0,0 +1,500 @@ + + + + + + + + + + + + + +
+
+
+ +

General

+ + +

Syntax for K and GL

+ + +

The calculus KS and its properties

+ + + +

Uniform interpolation for K

+ + + +

The calculus GLS and its properties

+ + +

Uniform interpolation for GL

+ + +

ISL.Environments

+ +

ISL.Formulas

+ +

ISL.Order

+

ISL.PropQuantifiers

+ +

ISL.SequentProps

+ +

ISL.Sequents

+ + +

Extraction file

+
+
+ +
+ + + diff --git a/uiml_demo.bc.js b/uiml_demo.bc.js new file mode 100644 index 0000000..f68397e --- /dev/null +++ b/uiml_demo.bc.js @@ -0,0 +1,33245 @@ +//# 1 ".uiml_demo.eobjs/jsoo/uiml_demo.bc.runtime.js" +// Generated by js_of_ocaml +//# buildInfo:effects=false, kind=unknown, use-js-string=true, version=5.8.2 +//# 3 ".uiml_demo.eobjs/jsoo/uiml_demo.bc.runtime.js" + +//# 7 ".uiml_demo.eobjs/jsoo/uiml_demo.bc.runtime.js" +(function + (Object){ + typeof globalThis !== "object" + && + (this + ? get() + : (Object.defineProperty + (Object.prototype, "_T_", {configurable: true, get: get}), + _T_)); + function get(){ + var global = this || self; + global.globalThis = global; + delete Object.prototype._T_; + } + } + (Object)); +(function(globalThis){ + "use strict"; + function caml_subarray_to_jsbytes(a, i, len){ + var f = String.fromCharCode; + if(i == 0 && len <= 4096 && len == a.length) return f.apply(null, a); + var s = ""; + for(; 0 < len; i += 1024, len -= 1024) + s += f.apply(null, a.slice(i, i + Math.min(len, 1024))); + return s; + } + function caml_string_of_jsbytes(x){return x;} + function caml_string_of_array(a){ + return caml_string_of_jsbytes(caml_subarray_to_jsbytes(a, 0, a.length)); + } + function caml_ba_get_1(ba, i0){return ba.get(ba.offset(i0));} + function BigStringReader(bs, i){this.s = bs; this.i = i;} + BigStringReader.prototype = + {read8u: function(){return caml_ba_get_1(this.s, this.i++);}, + read8s: function(){return caml_ba_get_1(this.s, this.i++) << 24 >> 24;}, + read16u: + function(){ + var s = this.s, i = this.i; + this.i = i + 2; + return caml_ba_get_1(s, i) << 8 | caml_ba_get_1(s, i + 1); + }, + read16s: + function(){ + var s = this.s, i = this.i; + this.i = i + 2; + return caml_ba_get_1(s, i) << 24 >> 16 | caml_ba_get_1(s, i + 1); + }, + read32u: + function(){ + var s = this.s, i = this.i; + this.i = i + 4; + return (caml_ba_get_1(s, i) << 24 | caml_ba_get_1(s, i + 1) << 16 + | caml_ba_get_1(s, i + 2) << 8 + | caml_ba_get_1(s, i + 3)) + >>> 0; + }, + read32s: + function(){ + var s = this.s, i = this.i; + this.i = i + 4; + return caml_ba_get_1(s, i) << 24 | caml_ba_get_1(s, i + 1) << 16 + | caml_ba_get_1(s, i + 2) << 8 + | caml_ba_get_1(s, i + 3); + }, + readstr: + function(len){ + var i = this.i, arr = new Array(len); + for(var j = 0; j < len; j++) arr[j] = caml_ba_get_1(this.s, i + j); + this.i = i + len; + return caml_string_of_array(arr); + }, + readuint8array: + function(len){ + var i = this.i, offset = this.offset(i); + this.i = i + len; + return this.s.data.subarray(offset, offset + len); + }}; + function caml_str_repeat(n, s){ + if(n == 0) return ""; + if(s.repeat) return s.repeat(n); + var r = "", l = 0; + for(;;){ + if(n & 1) r += s; + n >>= 1; + if(n == 0) return r; + s += s; + l++; + if(l == 9) s.slice(0, 1); + } + } + function caml_convert_string_to_bytes(s){ + if(s.t == 2) + s.c += caml_str_repeat(s.l - s.c.length, "\0"); + else + s.c = caml_subarray_to_jsbytes(s.c, 0, s.c.length); + s.t = 0; + } + function jsoo_is_ascii(s){ + if(s.length < 24){ + for(var i = 0; i < s.length; i++) if(s.charCodeAt(i) > 127) return false; + return true; + } + else + return ! /[^\x00-\x7f]/.test(s); + } + function caml_utf16_of_utf8(s){ + for(var b = "", t = "", c, c1, c2, v, i = 0, l = s.length; i < l; i++){ + c1 = s.charCodeAt(i); + if(c1 < 0x80){ + for(var j = i + 1; j < l && (c1 = s.charCodeAt(j)) < 0x80; j++) ; + if(j - i > 512){ + t.substr(0, 1); + b += t; + t = ""; + b += s.slice(i, j); + } + else + t += s.slice(i, j); + if(j == l) break; + i = j; + } + v = 1; + if(++i < l && ((c2 = s.charCodeAt(i)) & - 64) == 128){ + c = c2 + (c1 << 6); + if(c1 < 0xe0){ + v = c - 0x3080; + if(v < 0x80) v = 1; + } + else{ + v = 2; + if(++i < l && ((c2 = s.charCodeAt(i)) & - 64) == 128){ + c = c2 + (c << 6); + if(c1 < 0xf0){ + v = c - 0xe2080; + if(v < 0x800 || v >= 0xd7ff && v < 0xe000) v = 2; + } + else{ + v = 3; + if(++i < l && ((c2 = s.charCodeAt(i)) & - 64) == 128 && c1 < 0xf5){ + v = c2 - 0x3c82080 + (c << 6); + if(v < 0x10000 || v > 0x10ffff) v = 3; + } + } + } + } + } + if(v < 4){ + i -= v; + t += "\ufffd"; + } + else if(v > 0xffff) + t += String.fromCharCode(0xd7c0 + (v >> 10), 0xdc00 + (v & 0x3FF)); + else + t += String.fromCharCode(v); + if(t.length > 1024){t.substr(0, 1); b += t; t = "";} + } + return b + t; + } + function MlBytes(tag, contents, length){ + this.t = tag; + this.c = contents; + this.l = length; + } + MlBytes.prototype.toString = + function(){ + switch(this.t){ + case 9: + return this.c; + default: caml_convert_string_to_bytes(this); + case 0: + if(jsoo_is_ascii(this.c)){this.t = 9; return this.c;} this.t = 8; + case 8: + return this.c; + } + }; + MlBytes.prototype.toUtf16 = + function(){ + var r = this.toString(); + if(this.t == 9) return r; + return caml_utf16_of_utf8(r); + }; + MlBytes.prototype.slice = + function(){ + var content = this.t == 4 ? this.c.slice() : this.c; + return new MlBytes(this.t, content, this.l); + }; + function caml_utf8_of_utf16(s){ + for(var b = "", t = b, c, d, i = 0, l = s.length; i < l; i++){ + c = s.charCodeAt(i); + if(c < 0x80){ + for(var j = i + 1; j < l && (c = s.charCodeAt(j)) < 0x80; j++) ; + if(j - i > 512){ + t.substr(0, 1); + b += t; + t = ""; + b += s.slice(i, j); + } + else + t += s.slice(i, j); + if(j == l) break; + i = j; + } + if(c < 0x800){ + t += String.fromCharCode(0xc0 | c >> 6); + t += String.fromCharCode(0x80 | c & 0x3f); + } + else if(c < 0xd800 || c >= 0xdfff) + t += + String.fromCharCode + (0xe0 | c >> 12, 0x80 | c >> 6 & 0x3f, 0x80 | c & 0x3f); + else if + (c >= 0xdbff || i + 1 == l || (d = s.charCodeAt(i + 1)) < 0xdc00 + || d > 0xdfff) + t += "\xef\xbf\xbd"; + else{ + i++; + c = (c << 10) + d - 0x35fdc00; + t += + String.fromCharCode + (0xf0 | c >> 18, + 0x80 | c >> 12 & 0x3f, + 0x80 | c >> 6 & 0x3f, + 0x80 | c & 0x3f); + } + if(t.length > 1024){t.substr(0, 1); b += t; t = "";} + } + return b + t; + } + function caml_string_of_jsstring(s){ + return jsoo_is_ascii(s) + ? caml_string_of_jsbytes(s) + : caml_string_of_jsbytes(caml_utf8_of_utf16(s)); + } + var + unix_error = + ["E2BIG", + "EACCES", + "EAGAIN", + "EBADF", + "EBUSY", + "ECHILD", + "EDEADLK", + "EDOM", + "EEXIST", + "EFAULT", + "EFBIG", + "EINTR", + "EINVAL", + "EIO", + "EISDIR", + "EMFILE", + "EMLINK", + "ENAMETOOLONG", + "ENFILE", + "ENODEV", + "ENOENT", + "ENOEXEC", + "ENOLCK", + "ENOMEM", + "ENOSPC", + "ENOSYS", + "ENOTDIR", + "ENOTEMPTY", + "ENOTTY", + "ENXIO", + "EPERM", + "EPIPE", + "ERANGE", + "EROFS", + "ESPIPE", + "ESRCH", + "EXDEV", + "EWOULDBLOCK", + "EINPROGRESS", + "EALREADY", + "ENOTSOCK", + "EDESTADDRREQ", + "EMSGSIZE", + "EPROTOTYPE", + "ENOPROTOOPT", + "EPROTONOSUPPORT", + "ESOCKTNOSUPPORT", + "EOPNOTSUPP", + "EPFNOSUPPORT", + "EAFNOSUPPORT", + "EADDRINUSE", + "EADDRNOTAVAIL", + "ENETDOWN", + "ENETUNREACH", + "ENETRESET", + "ECONNABORTED", + "ECONNRESET", + "ENOBUFS", + "EISCONN", + "ENOTCONN", + "ESHUTDOWN", + "ETOOMANYREFS", + "ETIMEDOUT", + "ECONNREFUSED", + "EHOSTDOWN", + "EHOSTUNREACH", + "ELOOP", + "EOVERFLOW"]; + function make_unix_err_args(code, syscall, path, errno){ + var variant = unix_error.indexOf(code); + if(variant < 0){if(errno == null) errno = - 9999; variant = [0, errno];} + var + args = + [variant, + caml_string_of_jsstring(syscall || ""), + caml_string_of_jsstring(path || "")]; + return args; + } + var caml_named_values = {}; + function caml_named_value(nm){return caml_named_values[nm];} + function jsoo_sys_getenv(n){ + var process = globalThis.process; + if(process && process.env && process.env[n] != undefined) + return process.env[n]; + if(globalThis.jsoo_static_env && globalThis.jsoo_static_env[n]) + return globalThis.jsoo_static_env[n]; + } + var caml_record_backtrace_flag = 0; + (function(){ + var r = jsoo_sys_getenv("OCAMLRUNPARAM"); + if(r !== undefined){ + var l = r.split(","); + for(var i = 0; i < l.length; i++) + if(l[i] == "b"){ + caml_record_backtrace_flag = 1; + break; + } + else if(l[i].startsWith("b=")) + caml_record_backtrace_flag = + l[i].slice(2); + else + continue; + } + } + ()); + var caml_global_data = [0]; + function caml_exn_with_js_backtrace(exn, force){ + if(! exn.js_error || force || exn[0] == 248) + exn.js_error = new globalThis.Error("Js exception containing backtrace"); + return exn; + } + function caml_maybe_attach_backtrace(exn, force){ + return caml_record_backtrace_flag + ? caml_exn_with_js_backtrace(exn, force) + : exn; + } + function caml_raise_with_args(tag, args){ + throw caml_maybe_attach_backtrace([0, tag].concat(args)); + } + function caml_is_ml_bytes(s){return s instanceof MlBytes;} + function caml_is_ml_string(s){ + return typeof s === "string" && ! /[^\x00-\xff]/.test(s); + } + function caml_bytes_of_array(a){ + if(! (a instanceof Uint8Array)) a = new Uint8Array(a); + return new MlBytes(4, a, a.length); + } + function caml_bytes_of_jsbytes(s){return new MlBytes(0, s, s.length);} + function caml_jsbytes_of_string(x){return x;} + function caml_bytes_of_string(s){ + return caml_bytes_of_jsbytes(caml_jsbytes_of_string(s)); + } + function caml_raise_with_arg(tag, arg){ + throw caml_maybe_attach_backtrace([0, tag, arg]); + } + function caml_raise_with_string(tag, msg){ + caml_raise_with_arg(tag, caml_string_of_jsbytes(msg)); + } + function caml_raise_sys_error(msg){ + caml_raise_with_string(caml_global_data.Sys_error, msg); + } + function caml_raise_no_such_file(name){ + caml_raise_sys_error(name + ": No such file or directory"); + } + function caml_convert_bytes_to_array(s){ + var a = new Uint8Array(s.l), b = s.c, l = b.length, i = 0; + for(; i < l; i++) a[i] = b.charCodeAt(i); + for(l = s.l; i < l; i++) a[i] = 0; + s.c = a; + s.t = 4; + return a; + } + function caml_uint8_array_of_bytes(s){ + if(s.t != 4) caml_convert_bytes_to_array(s); + return s.c; + } + function caml_invalid_argument(msg){ + caml_raise_with_string(caml_global_data.Invalid_argument, msg); + } + function caml_create_bytes(len){ + if(len < 0) caml_invalid_argument("Bytes.create"); + return new MlBytes(len ? 2 : 9, "", len); + } + function caml_ml_bytes_length(s){return s.l;} + function caml_blit_bytes(s1, i1, s2, i2, len){ + if(len == 0) return 0; + if(i2 == 0 && (len >= s2.l || s2.t == 2 && len >= s2.c.length)){ + s2.c = + s1.t == 4 + ? caml_subarray_to_jsbytes(s1.c, i1, len) + : i1 == 0 && s1.c.length == len ? s1.c : s1.c.substr(i1, len); + s2.t = s2.c.length == s2.l ? 0 : 2; + } + else if(s2.t == 2 && i2 == s2.c.length){ + s2.c += + s1.t == 4 + ? caml_subarray_to_jsbytes(s1.c, i1, len) + : i1 == 0 && s1.c.length == len ? s1.c : s1.c.substr(i1, len); + s2.t = s2.c.length == s2.l ? 0 : 2; + } + else{ + if(s2.t != 4) caml_convert_bytes_to_array(s2); + var c1 = s1.c, c2 = s2.c; + if(s1.t == 4) + if(i2 <= i1) + for(var i = 0; i < len; i++) c2[i2 + i] = c1[i1 + i]; + else + for(var i = len - 1; i >= 0; i--) c2[i2 + i] = c1[i1 + i]; + else{ + var l = Math.min(len, c1.length - i1); + for(var i = 0; i < l; i++) c2[i2 + i] = c1.charCodeAt(i1 + i); + for(; i < len; i++) c2[i2 + i] = 0; + } + } + return 0; + } + function MlFile(){} + function MlFakeFile(content){this.data = content;} + MlFakeFile.prototype = new MlFile(); + MlFakeFile.prototype.constructor = MlFakeFile; + MlFakeFile.prototype.truncate = + function(len){ + var old = this.data; + this.data = caml_create_bytes(len | 0); + caml_blit_bytes(old, 0, this.data, 0, len); + }; + MlFakeFile.prototype.length = + function(){return caml_ml_bytes_length(this.data);}; + MlFakeFile.prototype.write = + function(offset, buf, pos, len){ + var clen = this.length(); + if(offset + len >= clen){ + var new_str = caml_create_bytes(offset + len), old_data = this.data; + this.data = new_str; + caml_blit_bytes(old_data, 0, this.data, 0, clen); + } + caml_blit_bytes(caml_bytes_of_array(buf), pos, this.data, offset, len); + return 0; + }; + MlFakeFile.prototype.read = + function(offset, buf, pos, len){ + var clen = this.length(); + if(offset + len >= clen) len = clen - offset; + if(len){ + var data = caml_create_bytes(len | 0); + caml_blit_bytes(this.data, offset, data, 0, len); + buf.set(caml_uint8_array_of_bytes(data), pos); + } + return len; + }; + function MlFakeFd(name, file, flags){ + this.file = file; + this.name = name; + this.flags = flags; + } + MlFakeFd.prototype.err_closed = + function(){ + caml_raise_sys_error(this.name + ": file descriptor already closed"); + }; + MlFakeFd.prototype.length = + function(){if(this.file) return this.file.length(); this.err_closed();}; + MlFakeFd.prototype.write = + function(offset, buf, pos, len){ + if(this.file) return this.file.write(offset, buf, pos, len); + this.err_closed(); + }; + MlFakeFd.prototype.read = + function(offset, buf, pos, len){ + if(this.file) return this.file.read(offset, buf, pos, len); + this.err_closed(); + }; + MlFakeFd.prototype.close = function(){this.file = undefined;}; + function MlFakeDevice(root, f){ + this.content = {}; + this.root = root; + this.lookupFun = f; + } + MlFakeDevice.prototype.nm = function(name){return this.root + name;}; + MlFakeDevice.prototype.create_dir_if_needed = + function(name){ + var comp = name.split("/"), res = ""; + for(var i = 0; i < comp.length - 1; i++){ + res += comp[i] + "/"; + if(this.content[res]) continue; + this.content[res] = Symbol("directory"); + } + }; + MlFakeDevice.prototype.slash = + function(name){return /\/$/.test(name) ? name : name + "/";}; + MlFakeDevice.prototype.lookup = + function(name){ + if(! this.content[name] && this.lookupFun){ + var + res = + this.lookupFun + (caml_string_of_jsbytes(this.root), caml_string_of_jsbytes(name)); + if(res !== 0){ + this.create_dir_if_needed(name); + this.content[name] = new MlFakeFile(caml_bytes_of_string(res[1])); + } + } + }; + MlFakeDevice.prototype.exists = + function(name){ + if(name == "") return 1; + var name_slash = this.slash(name); + if(this.content[name_slash]) return 1; + this.lookup(name); + return this.content[name] ? 1 : 0; + }; + MlFakeDevice.prototype.isFile = + function(name){return this.exists(name) && ! this.is_dir(name) ? 1 : 0;}; + MlFakeDevice.prototype.mkdir = + function(name, mode, raise_unix){ + var unix_error = raise_unix && caml_named_value("Unix.Unix_error"); + if(this.exists(name)) + if(unix_error) + caml_raise_with_args + (unix_error, make_unix_err_args("EEXIST", "mkdir", this.nm(name))); + else + caml_raise_sys_error(name + ": File exists"); + var parent = /^(.*)\/[^/]+/.exec(name); + parent = parent && parent[1] || ""; + if(! this.exists(parent)) + if(unix_error) + caml_raise_with_args + (unix_error, make_unix_err_args("ENOENT", "mkdir", this.nm(parent))); + else + caml_raise_sys_error(parent + ": No such file or directory"); + if(! this.is_dir(parent)) + if(unix_error) + caml_raise_with_args + (unix_error, make_unix_err_args("ENOTDIR", "mkdir", this.nm(parent))); + else + caml_raise_sys_error(parent + ": Not a directory"); + this.create_dir_if_needed(this.slash(name)); + }; + MlFakeDevice.prototype.rmdir = + function(name, raise_unix){ + var + unix_error = raise_unix && caml_named_value("Unix.Unix_error"), + name_slash = name == "" ? "" : this.slash(name), + r = new RegExp("^" + name_slash + "([^/]+)"); + if(! this.exists(name)) + if(unix_error) + caml_raise_with_args + (unix_error, make_unix_err_args("ENOENT", "rmdir", this.nm(name))); + else + caml_raise_sys_error(name + ": No such file or directory"); + if(! this.is_dir(name)) + if(unix_error) + caml_raise_with_args + (unix_error, make_unix_err_args("ENOTDIR", "rmdir", this.nm(name))); + else + caml_raise_sys_error(name + ": Not a directory"); + for(var n in this.content) + if(n.match(r)) + if(unix_error) + caml_raise_with_args + (unix_error, make_unix_err_args("ENOTEMPTY", "rmdir", this.nm(name))); + else + caml_raise_sys_error(this.nm(name) + ": Directory not empty"); + delete this.content[name_slash]; + }; + MlFakeDevice.prototype.readdir = + function(name){ + var name_slash = name == "" ? "" : this.slash(name); + if(! this.exists(name)) + caml_raise_sys_error(name + ": No such file or directory"); + if(! this.is_dir(name)) caml_raise_sys_error(name + ": Not a directory"); + var r = new RegExp("^" + name_slash + "([^/]+)"), seen = {}, a = []; + for(var n in this.content){ + var m = n.match(r); + if(m && ! seen[m[1]]){seen[m[1]] = true; a.push(m[1]);} + } + return a; + }; + MlFakeDevice.prototype.opendir = + function(name, raise_unix){ + var + unix_error = raise_unix && caml_named_value("Unix.Unix_error"), + a = this.readdir(name), + c = false, + i = 0; + return {readSync: + function(){ + if(c) + if(unix_error) + caml_raise_with_args + (unix_error, + make_unix_err_args("EBADF", "closedir", this.nm(name))); + else + caml_raise_sys_error(name + ": closedir failed"); + if(i == a.length) return null; + var entry = a[i]; + i++; + return {name: entry}; + }, + closeSync: + function(){ + if(c) + if(unix_error) + caml_raise_with_args + (unix_error, + make_unix_err_args("EBADF", "closedir", this.nm(name))); + else + caml_raise_sys_error(name + ": closedir failed"); + c = true; + a = []; + }}; + }; + MlFakeDevice.prototype.is_dir = + function(name){ + if(name == "") return true; + var name_slash = this.slash(name); + return this.content[name_slash] ? 1 : 0; + }; + MlFakeDevice.prototype.unlink = + function(name){ + var ok = this.content[name] ? true : false; + delete this.content[name]; + return ok; + }; + MlFakeDevice.prototype.open = + function(name, f){ + var file; + if(f.rdonly && f.wronly) + caml_raise_sys_error + (this.nm(name) + + " : flags Open_rdonly and Open_wronly are not compatible"); + if(f.text && f.binary) + caml_raise_sys_error + (this.nm(name) + + " : flags Open_text and Open_binary are not compatible"); + this.lookup(name); + if(this.content[name]){ + if(this.is_dir(name)) + caml_raise_sys_error(this.nm(name) + " : is a directory"); + if(f.create && f.excl) + caml_raise_sys_error(this.nm(name) + " : file already exists"); + file = this.content[name]; + if(f.truncate) file.truncate(); + } + else if(f.create){ + this.create_dir_if_needed(name); + this.content[name] = new MlFakeFile(caml_create_bytes(0)); + file = this.content[name]; + } + else + caml_raise_no_such_file(this.nm(name)); + return new MlFakeFd(this.nm(name), file, f); + }; + MlFakeDevice.prototype.open = + function(name, f){ + var file; + if(f.rdonly && f.wronly) + caml_raise_sys_error + (this.nm(name) + + " : flags Open_rdonly and Open_wronly are not compatible"); + if(f.text && f.binary) + caml_raise_sys_error + (this.nm(name) + + " : flags Open_text and Open_binary are not compatible"); + this.lookup(name); + if(this.content[name]){ + if(this.is_dir(name)) + caml_raise_sys_error(this.nm(name) + " : is a directory"); + if(f.create && f.excl) + caml_raise_sys_error(this.nm(name) + " : file already exists"); + file = this.content[name]; + if(f.truncate) file.truncate(); + } + else if(f.create){ + this.create_dir_if_needed(name); + this.content[name] = new MlFakeFile(caml_create_bytes(0)); + file = this.content[name]; + } + else + caml_raise_no_such_file(this.nm(name)); + return new MlFakeFd(this.nm(name), file, f); + }; + MlFakeDevice.prototype.register = + function(name, content){ + var file; + if(this.content[name]) + caml_raise_sys_error(this.nm(name) + " : file already exists"); + if(caml_is_ml_bytes(content)) file = new MlFakeFile(content); + if(caml_is_ml_string(content)) + file = new MlFakeFile(caml_bytes_of_string(content)); + else if(content instanceof Array) + file = new MlFakeFile(caml_bytes_of_array(content)); + else if(typeof content === "string") + file = new MlFakeFile(caml_bytes_of_jsbytes(content)); + else if(content.toString){ + var + bytes = + caml_bytes_of_string(caml_string_of_jsstring(content.toString())); + file = new MlFakeFile(bytes); + } + if(file){ + this.create_dir_if_needed(name); + this.content[name] = file; + } + else + caml_raise_sys_error + (this.nm(name) + " : registering file with invalid content type"); + }; + MlFakeDevice.prototype.constructor = MlFakeDevice; + function MlFakeFd_out(fd, flags){ + MlFakeFile.call(this, caml_create_bytes(0)); + this.log = function(s){return 0;}; + if(fd == 1 && typeof console.log == "function") + this.log = console.log; + else if(fd == 2 && typeof console.error == "function") + this.log = console.error; + else if(typeof console.log == "function") this.log = console.log; + this.flags = flags; + } + MlFakeFd_out.prototype.length = function(){return 0;}; + MlFakeFd_out.prototype.write = + function(offset, buf, pos, len){ + if(this.log){ + if + (len > 0 && pos >= 0 && pos + len <= buf.length + && buf[pos + len - 1] == 10) + len--; + var src = caml_create_bytes(len); + caml_blit_bytes(caml_bytes_of_array(buf), pos, src, 0, len); + this.log(src.toUtf16()); + return 0; + } + caml_raise_sys_error(this.fd + ": file descriptor already closed"); + }; + MlFakeFd_out.prototype.read = + function(offset, buf, pos, len){ + caml_raise_sys_error(this.fd + ": file descriptor is write only"); + }; + MlFakeFd_out.prototype.close = function(){this.log = undefined;}; + var caml_int64_offset = Math.pow(2, - 24); + function caml_raise_constant(tag){throw tag;} + function caml_raise_zero_divide(){ + caml_raise_constant(caml_global_data.Division_by_zero); + } + function MlInt64(lo, mi, hi){ + this.lo = lo & 0xffffff; + this.mi = mi & 0xffffff; + this.hi = hi & 0xffff; + } + MlInt64.prototype.caml_custom = "_j"; + MlInt64.prototype.copy = + function(){return new MlInt64(this.lo, this.mi, this.hi);}; + MlInt64.prototype.ucompare = + function(x){ + if(this.hi > x.hi) return 1; + if(this.hi < x.hi) return - 1; + if(this.mi > x.mi) return 1; + if(this.mi < x.mi) return - 1; + if(this.lo > x.lo) return 1; + if(this.lo < x.lo) return - 1; + return 0; + }; + MlInt64.prototype.compare = + function(x){ + var hi = this.hi << 16, xhi = x.hi << 16; + if(hi > xhi) return 1; + if(hi < xhi) return - 1; + if(this.mi > x.mi) return 1; + if(this.mi < x.mi) return - 1; + if(this.lo > x.lo) return 1; + if(this.lo < x.lo) return - 1; + return 0; + }; + MlInt64.prototype.neg = + function(){ + var + lo = - this.lo, + mi = - this.mi + (lo >> 24), + hi = - this.hi + (mi >> 24); + return new MlInt64(lo, mi, hi); + }; + MlInt64.prototype.add = + function(x){ + var + lo = this.lo + x.lo, + mi = this.mi + x.mi + (lo >> 24), + hi = this.hi + x.hi + (mi >> 24); + return new MlInt64(lo, mi, hi); + }; + MlInt64.prototype.sub = + function(x){ + var + lo = this.lo - x.lo, + mi = this.mi - x.mi + (lo >> 24), + hi = this.hi - x.hi + (mi >> 24); + return new MlInt64(lo, mi, hi); + }; + MlInt64.prototype.mul = + function(x){ + var + lo = this.lo * x.lo, + mi = (lo * caml_int64_offset | 0) + this.mi * x.lo + this.lo * x.mi, + hi = + (mi * caml_int64_offset | 0) + this.hi * x.lo + this.mi * x.mi + + this.lo * x.hi; + return new MlInt64(lo, mi, hi); + }; + MlInt64.prototype.isZero = + function(){return (this.lo | this.mi | this.hi) == 0;}; + MlInt64.prototype.isNeg = function(){return this.hi << 16 < 0;}; + MlInt64.prototype.and = + function(x){ + return new MlInt64(this.lo & x.lo, this.mi & x.mi, this.hi & x.hi); + }; + MlInt64.prototype.or = + function(x){ + return new MlInt64(this.lo | x.lo, this.mi | x.mi, this.hi | x.hi); + }; + MlInt64.prototype.xor = + function(x){ + return new MlInt64(this.lo ^ x.lo, this.mi ^ x.mi, this.hi ^ x.hi); + }; + MlInt64.prototype.shift_left = + function(s){ + s = s & 63; + if(s == 0) return this; + if(s < 24) + return new + MlInt64 + (this.lo << s, + this.mi << s | this.lo >> 24 - s, + this.hi << s | this.mi >> 24 - s); + if(s < 48) + return new + MlInt64 + (0, this.lo << s - 24, this.mi << s - 24 | this.lo >> 48 - s); + return new MlInt64(0, 0, this.lo << s - 48); + }; + MlInt64.prototype.shift_right_unsigned = + function(s){ + s = s & 63; + if(s == 0) return this; + if(s < 24) + return new + MlInt64 + (this.lo >> s | this.mi << 24 - s, + this.mi >> s | this.hi << 24 - s, + this.hi >> s); + if(s < 48) + return new + MlInt64 + (this.mi >> s - 24 | this.hi << 48 - s, this.hi >> s - 24, 0); + return new MlInt64(this.hi >> s - 48, 0, 0); + }; + MlInt64.prototype.shift_right = + function(s){ + s = s & 63; + if(s == 0) return this; + var h = this.hi << 16 >> 16; + if(s < 24) + return new + MlInt64 + (this.lo >> s | this.mi << 24 - s, + this.mi >> s | h << 24 - s, + this.hi << 16 >> s >>> 16); + var sign = this.hi << 16 >> 31; + if(s < 48) + return new + MlInt64 + (this.mi >> s - 24 | this.hi << 48 - s, + this.hi << 16 >> s - 24 >> 16, + sign & 0xffff); + return new MlInt64(this.hi << 16 >> s - 32, sign, sign); + }; + MlInt64.prototype.lsl1 = + function(){ + this.hi = this.hi << 1 | this.mi >> 23; + this.mi = (this.mi << 1 | this.lo >> 23) & 0xffffff; + this.lo = this.lo << 1 & 0xffffff; + }; + MlInt64.prototype.lsr1 = + function(){ + this.lo = (this.lo >>> 1 | this.mi << 23) & 0xffffff; + this.mi = (this.mi >>> 1 | this.hi << 23) & 0xffffff; + this.hi = this.hi >>> 1; + }; + MlInt64.prototype.udivmod = + function(x){ + var + offset = 0, + modulus = this.copy(), + divisor = x.copy(), + quotient = new MlInt64(0, 0, 0); + while(modulus.ucompare(divisor) > 0){offset++; divisor.lsl1();} + while(offset >= 0){ + offset--; + quotient.lsl1(); + if(modulus.ucompare(divisor) >= 0){ + quotient.lo++; + modulus = modulus.sub(divisor); + } + divisor.lsr1(); + } + return {quotient: quotient, modulus: modulus}; + }; + MlInt64.prototype.div = + function(y){ + var x = this; + if(y.isZero()) caml_raise_zero_divide(); + var sign = x.hi ^ y.hi; + if(x.hi & 0x8000) x = x.neg(); + if(y.hi & 0x8000) y = y.neg(); + var q = x.udivmod(y).quotient; + if(sign & 0x8000) q = q.neg(); + return q; + }; + MlInt64.prototype.mod = + function(y){ + var x = this; + if(y.isZero()) caml_raise_zero_divide(); + var sign = x.hi; + if(x.hi & 0x8000) x = x.neg(); + if(y.hi & 0x8000) y = y.neg(); + var r = x.udivmod(y).modulus; + if(sign & 0x8000) r = r.neg(); + return r; + }; + MlInt64.prototype.toInt = function(){return this.lo | this.mi << 24;}; + MlInt64.prototype.toFloat = + function(){ + return (this.hi << 16) * Math.pow(2, 32) + this.mi * Math.pow(2, 24) + + this.lo; + }; + MlInt64.prototype.toArray = + function(){ + return [this.hi >> 8, + this.hi & 0xff, + this.mi >> 16, + this.mi >> 8 & 0xff, + this.mi & 0xff, + this.lo >> 16, + this.lo >> 8 & 0xff, + this.lo & 0xff]; + }; + MlInt64.prototype.lo32 = + function(){return this.lo | (this.mi & 0xff) << 24;}; + MlInt64.prototype.hi32 = + function(){return this.mi >>> 8 & 0xffff | this.hi << 16;}; + function MlMutex(){this.locked = false;} + function MlNat(x){ + this.data = new Int32Array(x); + this.length = this.data.length + 2; + } + MlNat.prototype.caml_custom = "_nat"; + function caml_ml_string_length(s){return s.length;} + function caml_string_unsafe_get(s, i){return s.charCodeAt(i);} + function caml_uint8_array_of_string(s){ + var l = caml_ml_string_length(s), a = new Uint8Array(l), i = 0; + for(; i < l; i++) a[i] = caml_string_unsafe_get(s, i); + return a; + } + function caml_bytes_bound_error(){ + caml_invalid_argument("index out of bounds"); + } + function caml_bytes_unsafe_set(s, i, c){ + c &= 0xff; + if(s.t != 4){ + if(i == s.c.length){ + s.c += String.fromCharCode(c); + if(i + 1 == s.l) s.t = 0; + return 0; + } + caml_convert_bytes_to_array(s); + } + s.c[i] = c; + return 0; + } + function caml_bytes_set(s, i, c){ + if(i >>> 0 >= s.l) caml_bytes_bound_error(); + return caml_bytes_unsafe_set(s, i, c); + } + function MlNodeFd(fd, flags){ + this.fs = require("fs"); + this.fd = fd; + this.flags = flags; + } + MlNodeFd.prototype = new MlFile(); + MlNodeFd.prototype.constructor = MlNodeFd; + MlNodeFd.prototype.truncate = + function(len){ + try{this.fs.ftruncateSync(this.fd, len | 0);} + catch(err){caml_raise_sys_error(err.toString());} + }; + MlNodeFd.prototype.length = + function(){ + try{return this.fs.fstatSync(this.fd).size;} + catch(err){caml_raise_sys_error(err.toString());} + }; + MlNodeFd.prototype.write = + function(offset, buf, buf_offset, len){ + try{ + if(this.flags.isCharacterDevice) + this.fs.writeSync(this.fd, buf, buf_offset, len); + else + this.fs.writeSync(this.fd, buf, buf_offset, len, offset); + } + catch(err){caml_raise_sys_error(err.toString());} + return 0; + }; + MlNodeFd.prototype.read = + function(offset, a, buf_offset, len){ + try{ + if(this.flags.isCharacterDevice) + var read = this.fs.readSync(this.fd, a, buf_offset, len); + else + var read = this.fs.readSync(this.fd, a, buf_offset, len, offset); + return read; + } + catch(err){caml_raise_sys_error(err.toString());} + }; + MlNodeFd.prototype.close = + function(){ + try{this.fs.closeSync(this.fd); return 0;} + catch(err){caml_raise_sys_error(err.toString());} + }; + function MlNodeDevice(root){this.fs = require("fs"); this.root = root;} + MlNodeDevice.prototype.nm = function(name){return this.root + name;}; + MlNodeDevice.prototype.exists = + function(name){ + try{return this.fs.existsSync(this.nm(name)) ? 1 : 0;} + catch(err){return 0;} + }; + MlNodeDevice.prototype.isFile = + function(name){ + try{return this.fs.statSync(this.nm(name)).isFile() ? 1 : 0;} + catch(err){caml_raise_sys_error(err.toString());} + }; + MlNodeDevice.prototype.mkdir = + function(name, mode, raise_unix){ + try{this.fs.mkdirSync(this.nm(name), {mode: mode}); return 0;} + catch(err){this.raise_nodejs_error(err, raise_unix);} + }; + MlNodeDevice.prototype.rmdir = + function(name, raise_unix){ + try{this.fs.rmdirSync(this.nm(name)); return 0;} + catch(err){this.raise_nodejs_error(err, raise_unix);} + }; + MlNodeDevice.prototype.readdir = + function(name, raise_unix){ + try{return this.fs.readdirSync(this.nm(name));} + catch(err){this.raise_nodejs_error(err, raise_unix);} + }; + MlNodeDevice.prototype.is_dir = + function(name){ + try{return this.fs.statSync(this.nm(name)).isDirectory() ? 1 : 0;} + catch(err){caml_raise_sys_error(err.toString());} + }; + MlNodeDevice.prototype.unlink = + function(name, raise_unix){ + try{ + var b = this.fs.existsSync(this.nm(name)) ? 1 : 0; + this.fs.unlinkSync(this.nm(name)); + return b; + } + catch(err){this.raise_nodejs_error(err, raise_unix);} + }; + MlNodeDevice.prototype.open = + function(name, f, raise_unix){ + var consts = require("constants"), res = 0; + for(var key in f) + switch(key){ + case "rdonly": + res |= consts.O_RDONLY; break; + case "wronly": + res |= consts.O_WRONLY; break; + case "append": + res |= consts.O_WRONLY | consts.O_APPEND; break; + case "create": + res |= consts.O_CREAT; break; + case "truncate": + res |= consts.O_TRUNC; break; + case "excl": + res |= consts.O_EXCL; break; + case "binary": + res |= consts.O_BINARY; break; + case "text": + res |= consts.O_TEXT; break; + case "nonblock": + res |= consts.O_NONBLOCK; break; + } + try{ + var + fd = this.fs.openSync(this.nm(name), res), + isCharacterDevice = + this.fs.lstatSync(this.nm(name)).isCharacterDevice(); + f.isCharacterDevice = isCharacterDevice; + return new MlNodeFd(fd, f); + } + catch(err){this.raise_nodejs_error(err, raise_unix);} + }; + MlNodeDevice.prototype.rename = + function(o, n, raise_unix){ + try{this.fs.renameSync(this.nm(o), this.nm(n));} + catch(err){this.raise_nodejs_error(err, raise_unix);} + }; + MlNodeDevice.prototype.stat = + function(name, raise_unix){ + try{ + var js_stats = this.fs.statSync(this.nm(name)); + return this.stats_from_js(js_stats); + } + catch(err){this.raise_nodejs_error(err, raise_unix);} + }; + MlNodeDevice.prototype.lstat = + function(name, raise_unix){ + try{ + var js_stats = this.fs.lstatSync(this.nm(name)); + return this.stats_from_js(js_stats); + } + catch(err){this.raise_nodejs_error(err, raise_unix);} + }; + MlNodeDevice.prototype.symlink = + function(to_dir, target, path, raise_unix){ + try{ + this.fs.symlinkSync + (this.nm(target), this.nm(path), to_dir ? "dir" : "file"); + return 0; + } + catch(err){this.raise_nodejs_error(err, raise_unix);} + }; + MlNodeDevice.prototype.readlink = + function(name, raise_unix){ + try{ + var link = this.fs.readlinkSync(this.nm(name), "utf8"); + return caml_string_of_jsstring(link); + } + catch(err){this.raise_nodejs_error(err, raise_unix);} + }; + MlNodeDevice.prototype.opendir = + function(name, raise_unix){ + try{return this.fs.opendirSync(this.nm(name));} + catch(err){this.raise_nodejs_error(err, raise_unix);} + }; + MlNodeDevice.prototype.raise_nodejs_error = + function(err, raise_unix){ + var unix_error = caml_named_value("Unix.Unix_error"); + if(raise_unix && unix_error){ + var + args = make_unix_err_args(err.code, err.syscall, err.path, err.errno); + caml_raise_with_args(unix_error, args); + } + else + caml_raise_sys_error(err.toString()); + }; + MlNodeDevice.prototype.stats_from_js = + function(js_stats){ + var file_kind; + if(js_stats.isFile()) + file_kind = 0; + else if(js_stats.isDirectory()) + file_kind = 1; + else if(js_stats.isCharacterDevice()) + file_kind = 2; + else if(js_stats.isBlockDevice()) + file_kind = 3; + else if(js_stats.isSymbolicLink()) + file_kind = 4; + else if(js_stats.isFIFO()) + file_kind = 5; + else if(js_stats.isSocket()) file_kind = 6; + return [0, + js_stats.dev, + js_stats.ino, + file_kind, + js_stats.mode, + js_stats.nlink, + js_stats.uid, + js_stats.gid, + js_stats.rdev, + js_stats.size, + js_stats.atimeMs, + js_stats.mtimeMs, + js_stats.ctimeMs]; + }; + MlNodeDevice.prototype.constructor = MlNodeDevice; + var MlObjectTable; + if(typeof globalThis.Map === "undefined") + MlObjectTable = + function(){ + function NaiveLookup(objs){this.objs = objs;} + NaiveLookup.prototype.get = + function(v){ + for(var i = 0; i < this.objs.length; i++) + if(this.objs[i] === v) return i; + }; + NaiveLookup.prototype.set = function(){}; + return function(){ + this.objs = []; + this.lookup = new NaiveLookup(this.objs);}; + } + (); + else + MlObjectTable = + function(){this.objs = []; this.lookup = new globalThis.Map();}; + MlObjectTable.prototype.store = + function(v){this.lookup.set(v, this.objs.length); this.objs.push(v);}; + MlObjectTable.prototype.recall = + function(v){ + var i = this.lookup.get(v); + return i === undefined ? undefined : this.objs.length - i; + }; + function MlStringReader(s, i){ + this.s = caml_jsbytes_of_string(s); + this.i = i; + } + MlStringReader.prototype = + {read8u: function(){return this.s.charCodeAt(this.i++);}, + read8s: function(){return this.s.charCodeAt(this.i++) << 24 >> 24;}, + read16u: + function(){ + var s = this.s, i = this.i; + this.i = i + 2; + return s.charCodeAt(i) << 8 | s.charCodeAt(i + 1); + }, + read16s: + function(){ + var s = this.s, i = this.i; + this.i = i + 2; + return s.charCodeAt(i) << 24 >> 16 | s.charCodeAt(i + 1); + }, + read32u: + function(){ + var s = this.s, i = this.i; + this.i = i + 4; + return (s.charCodeAt(i) << 24 | s.charCodeAt(i + 1) << 16 + | s.charCodeAt(i + 2) << 8 + | s.charCodeAt(i + 3)) + >>> 0; + }, + read32s: + function(){ + var s = this.s, i = this.i; + this.i = i + 4; + return s.charCodeAt(i) << 24 | s.charCodeAt(i + 1) << 16 + | s.charCodeAt(i + 2) << 8 + | s.charCodeAt(i + 3); + }, + readstr: + function(len){ + var i = this.i; + this.i = i + len; + return caml_string_of_jsbytes(this.s.substring(i, i + len)); + }, + readuint8array: + function(len){ + var b = new Uint8Array(len), s = this.s, i = this.i; + for(var j = 0; j < len; j++) b[j] = s.charCodeAt(i + j); + this.i = i + len; + return b; + }}; + function caml_int64_create_lo_hi(lo, hi){ + return new + MlInt64 + (lo & 0xffffff, + lo >>> 24 & 0xff | (hi & 0xffff) << 8, + hi >>> 16 & 0xffff); + } + function caml_int64_hi32(v){return v.hi32();} + function caml_int64_lo32(v){return v.lo32();} + function caml_array_bound_error(){ + caml_invalid_argument("index out of bounds"); + } + var caml_ba_custom_name = "_bigarr02"; + function Ml_Bigarray(kind, layout, dims, buffer){ + this.kind = kind; + this.layout = layout; + this.dims = dims; + this.data = buffer; + } + Ml_Bigarray.prototype.caml_custom = caml_ba_custom_name; + Ml_Bigarray.prototype.offset = + function(arg){ + var ofs = 0; + if(typeof arg === "number") arg = [arg]; + if(! (arg instanceof Array)) + caml_invalid_argument("bigarray.js: invalid offset"); + if(this.dims.length != arg.length) + caml_invalid_argument("Bigarray.get/set: bad number of dimensions"); + if(this.layout == 0) + for(var i = 0; i < this.dims.length; i++){ + if(arg[i] < 0 || arg[i] >= this.dims[i]) caml_array_bound_error(); + ofs = ofs * this.dims[i] + arg[i]; + } + else + for(var i = this.dims.length - 1; i >= 0; i--){ + if(arg[i] < 1 || arg[i] > this.dims[i]) caml_array_bound_error(); + ofs = ofs * this.dims[i] + (arg[i] - 1); + } + return ofs; + }; + Ml_Bigarray.prototype.get = + function(ofs){ + switch(this.kind){ + case 7: + var l = this.data[ofs * 2 + 0], h = this.data[ofs * 2 + 1]; + return caml_int64_create_lo_hi(l, h); + case 10: + case 11: + var r = this.data[ofs * 2 + 0], i = this.data[ofs * 2 + 1]; + return [254, r, i]; + default: return this.data[ofs]; + } + }; + Ml_Bigarray.prototype.set = + function(ofs, v){ + switch(this.kind){ + case 7: + this.data[ofs * 2 + 0] = caml_int64_lo32(v); + this.data[ofs * 2 + 1] = caml_int64_hi32(v); + break; + case 10: + case 11: + this.data[ofs * 2 + 0] = v[1]; this.data[ofs * 2 + 1] = v[2]; break; + default: this.data[ofs] = v; break; + } + return 0; + }; + Ml_Bigarray.prototype.fill = + function(v){ + switch(this.kind){ + case 7: + var a = caml_int64_lo32(v), b = caml_int64_hi32(v); + if(a == b) + this.data.fill(a); + else + for(var i = 0; i < this.data.length; i++) + this.data[i] = i % 2 == 0 ? a : b; + break; + case 10: + case 11: + var im = v[1], re = v[2]; + if(im == re) + this.data.fill(im); + else + for(var i = 0; i < this.data.length; i++) + this.data[i] = i % 2 == 0 ? im : re; + break; + default: this.data.fill(v); break; + } + }; + Ml_Bigarray.prototype.compare = + function(b, total){ + if(this.layout != b.layout || this.kind != b.kind){ + var k1 = this.kind | this.layout << 8, k2 = b.kind | b.layout << 8; + return k2 - k1; + } + if(this.dims.length != b.dims.length) + return b.dims.length - this.dims.length; + for(var i = 0; i < this.dims.length; i++) + if(this.dims[i] != b.dims[i]) return this.dims[i] < b.dims[i] ? - 1 : 1; + switch(this.kind){ + case 0: + case 1: + case 10: + case 11: + var x, y; + for(var i = 0; i < this.data.length; i++){ + x = this.data[i]; + y = b.data[i]; + if(x < y) return - 1; + if(x > y) return 1; + if(x != y){ + if(! total) return NaN; + if(x == x) return 1; + if(y == y) return - 1; + } + } + break; + case 7: + for(var i = 0; i < this.data.length; i += 2){ + if(this.data[i + 1] < b.data[i + 1]) return - 1; + if(this.data[i + 1] > b.data[i + 1]) return 1; + if(this.data[i] >>> 0 < b.data[i] >>> 0) return - 1; + if(this.data[i] >>> 0 > b.data[i] >>> 0) return 1; + } + break; + case 2: + case 3: + case 4: + case 5: + case 6: + case 8: + case 9: + case 12: + for(var i = 0; i < this.data.length; i++){ + if(this.data[i] < b.data[i]) return - 1; + if(this.data[i] > b.data[i]) return 1; + } + break; + } + return 0; + }; + function Ml_Bigarray_c_1_1(kind, layout, dims, buffer){ + this.kind = kind; + this.layout = layout; + this.dims = dims; + this.data = buffer; + } + Ml_Bigarray_c_1_1.prototype = new Ml_Bigarray(); + Ml_Bigarray_c_1_1.prototype.offset = + function(arg){ + if(typeof arg !== "number") + if(arg instanceof Array && arg.length == 1) + arg = arg[0]; + else + caml_invalid_argument("Ml_Bigarray_c_1_1.offset"); + if(arg < 0 || arg >= this.dims[0]) caml_array_bound_error(); + return arg; + }; + Ml_Bigarray_c_1_1.prototype.get = function(ofs){return this.data[ofs];}; + Ml_Bigarray_c_1_1.prototype.set = + function(ofs, v){this.data[ofs] = v; return 0;}; + Ml_Bigarray_c_1_1.prototype.fill = + function(v){this.data.fill(v); return 0;}; + function UInt8ArrayReader(s, i){this.s = s; this.i = i;} + UInt8ArrayReader.prototype = + {read8u: function(){return this.s[this.i++];}, + read8s: function(){return this.s[this.i++] << 24 >> 24;}, + read16u: + function(){ + var s = this.s, i = this.i; + this.i = i + 2; + return s[i] << 8 | s[i + 1]; + }, + read16s: + function(){ + var s = this.s, i = this.i; + this.i = i + 2; + return s[i] << 24 >> 16 | s[i + 1]; + }, + read32u: + function(){ + var s = this.s, i = this.i; + this.i = i + 4; + return (s[i] << 24 | s[i + 1] << 16 | s[i + 2] << 8 | s[i + 3]) >>> 0; + }, + read32s: + function(){ + var s = this.s, i = this.i; + this.i = i + 4; + return s[i] << 24 | s[i + 1] << 16 | s[i + 2] << 8 | s[i + 3]; + }, + readstr: + function(len){ + var i = this.i; + this.i = i + len; + return caml_string_of_array(this.s.subarray(i, i + len)); + }, + readuint8array: + function(len){ + var i = this.i; + this.i = i + len; + return this.s.subarray(i, i + len); + }}; + function incr_nat(nat, ofs, len, carry_in){ + var carry = carry_in; + for(var i = 0; i < len; i++){ + var x = (nat.data[ofs + i] >>> 0) + carry; + nat.data[ofs + i] = x | 0; + if(x == x >>> 0){carry = 0; break;} else carry = 1; + } + return carry; + } + function add_nat(nat1, ofs1, len1, nat2, ofs2, len2, carry_in){ + var carry = carry_in; + for(var i = 0; i < len2; i++){ + var + x = (nat1.data[ofs1 + i] >>> 0) + (nat2.data[ofs2 + i] >>> 0) + carry; + nat1.data[ofs1 + i] = x; + if(x == x >>> 0) carry = 0; else carry = 1; + } + return incr_nat(nat1, ofs1 + len2, len1 - len2, carry); + } + function caml_ba_get_size(dims){ + var n_dims = dims.length, size = 1; + for(var i = 0; i < n_dims; i++){ + if(dims[i] < 0) + caml_invalid_argument("Bigarray.create: negative dimension"); + size = size * dims[i]; + } + return size; + } + function caml_ba_get_size_per_element(kind){ + switch(kind){case 7:case 10:case 11: return 2;default: return 1; + } + } + function caml_ba_create_unsafe(kind, layout, dims, data){ + var size_per_element = caml_ba_get_size_per_element(kind); + if(caml_ba_get_size(dims) * size_per_element != data.length) + caml_invalid_argument("length doesn't match dims"); + if(layout == 0 && dims.length == 1 && size_per_element == 1) + return new Ml_Bigarray_c_1_1(kind, layout, dims, data); + return new Ml_Bigarray(kind, layout, dims, data); + } + function bigstring_of_array_buffer(ab){ + var ta = new Uint8Array(ab); + return caml_ba_create_unsafe(12, 0, [ta.length], ta); + } + function bigstring_of_typed_array(ba){ + var + ta = + new + Uint8Array + (ba.buffer, ba.byteOffset, ba.length * ba.BYTES_PER_ELEMENT); + return caml_ba_create_unsafe(12, 0, [ta.length], ta); + } + function bigstring_to_array_buffer(bs){return bs.data.buffer;} + function bigstring_to_typed_array(bs){return bs.data;} + function caml_bigstring_blit_string_to_ba(str1, pos1, ba2, pos2, len){ + if(12 != ba2.kind) + caml_invalid_argument("caml_bigstring_blit_string_to_ba: kind mismatch"); + if(len == 0) return 0; + var ofs2 = ba2.offset(pos2); + if(pos1 + len > caml_ml_string_length(str1)) caml_array_bound_error(); + if(ofs2 + len > ba2.data.length) caml_array_bound_error(); + var slice = caml_uint8_array_of_string(str1).slice(pos1, pos1 + len); + ba2.data.set(slice, ofs2); + return 0; + } + function bigstringaf_blit_from_bytes(src, src_off, dst, dst_off, len){ + return caml_bigstring_blit_string_to_ba(src, src_off, dst, dst_off, len); + } + function caml_bigstring_blit_ba_to_ba(ba1, pos1, ba2, pos2, len){ + if(12 != ba1.kind) + caml_invalid_argument("caml_bigstring_blit_ba_to_ba: kind mismatch"); + if(12 != ba2.kind) + caml_invalid_argument("caml_bigstring_blit_ba_to_ba: kind mismatch"); + if(len == 0) return 0; + var ofs1 = ba1.offset(pos1), ofs2 = ba2.offset(pos2); + if(ofs1 + len > ba1.data.length) caml_array_bound_error(); + if(ofs2 + len > ba2.data.length) caml_array_bound_error(); + var slice = ba1.data.subarray(ofs1, ofs1 + len); + ba2.data.set(slice, pos2); + return 0; + } + function bigstringaf_blit_to_bigstring(src, src_off, dst, dst_off, len){return caml_bigstring_blit_ba_to_ba(src, src_off, dst, dst_off, len); + } + function caml_bigstring_blit_ba_to_bytes(ba1, pos1, bytes2, pos2, len){ + if(12 != ba1.kind) + caml_invalid_argument("caml_bigstring_blit_string_to_ba: kind mismatch"); + if(len == 0) return 0; + var ofs1 = ba1.offset(pos1); + if(ofs1 + len > ba1.data.length) caml_array_bound_error(); + if(pos2 + len > caml_ml_bytes_length(bytes2)) caml_array_bound_error(); + var slice = ba1.data.slice(ofs1, ofs1 + len); + caml_blit_bytes(caml_bytes_of_array(slice), 0, bytes2, pos2, len); + return 0; + } + function bigstringaf_blit_to_bytes(src, src_off, dst, dst_off, len){ + return caml_bigstring_blit_ba_to_bytes(src, src_off, dst, dst_off, len); + } + function bigstringaf_memchr(ba, ba_off, chr, len){ + for(var i = 0; i < len; i++) + if(caml_ba_get_1(ba, ba_off + i) == chr) return ba_off + i; + return - 1; + } + function caml_int_compare(a, b){ + if(a < b) return - 1; + if(a == b) return 0; + return 1; + } + function bigstringaf_memcmp_bigstring(ba1, ba1_off, ba2, ba2_off, len){ + for(var i = 0; i < len; i++){ + var + c = + caml_int_compare + (caml_ba_get_1(ba1, ba1_off + i), caml_ba_get_1(ba2, ba2_off + i)); + if(c != 0) return c; + } + return 0; + } + function bigstringaf_memcmp_string(ba, ba_off, str, str_off, len){ + for(var i = 0; i < len; i++){ + var + c = + caml_int_compare + (caml_ba_get_1(ba, ba_off + i), + caml_string_unsafe_get(str, str_off + i)); + if(c != 0) return c; + } + return 0; + } + function blit_nat(nat1, ofs1, nat2, ofs2, len){ + for(var i = 0; i < len; i++) nat1.data[ofs1 + i] = nat2.data[ofs2 + i]; + return 0; + } + var + caml_MD5Transform = + function(){ + function add(x, y){return x + y | 0;} + function xx(q, a, b, x, s, t){ + a = add(add(a, q), add(x, t)); + return add(a << s | a >>> 32 - s, b); + } + function ff(a, b, c, d, x, s, t){ + return xx(b & c | ~ b & d, a, b, x, s, t); + } + function gg(a, b, c, d, x, s, t){ + return xx(b & d | c & ~ d, a, b, x, s, t); + } + function hh(a, b, c, d, x, s, t){return xx(b ^ c ^ d, a, b, x, s, t);} + function ii(a, b, c, d, x, s, t){ + return xx(c ^ (b | ~ d), a, b, x, s, t); + } + return function(w, buffer){ + var a = w[0], b = w[1], c = w[2], d = w[3]; + a = ff(a, b, c, d, buffer[0], 7, 0xD76AA478); + d = ff(d, a, b, c, buffer[1], 12, 0xE8C7B756); + c = ff(c, d, a, b, buffer[2], 17, 0x242070DB); + b = ff(b, c, d, a, buffer[3], 22, 0xC1BDCEEE); + a = ff(a, b, c, d, buffer[4], 7, 0xF57C0FAF); + d = ff(d, a, b, c, buffer[5], 12, 0x4787C62A); + c = ff(c, d, a, b, buffer[6], 17, 0xA8304613); + b = ff(b, c, d, a, buffer[7], 22, 0xFD469501); + a = ff(a, b, c, d, buffer[8], 7, 0x698098D8); + d = ff(d, a, b, c, buffer[9], 12, 0x8B44F7AF); + c = ff(c, d, a, b, buffer[10], 17, 0xFFFF5BB1); + b = ff(b, c, d, a, buffer[11], 22, 0x895CD7BE); + a = ff(a, b, c, d, buffer[12], 7, 0x6B901122); + d = ff(d, a, b, c, buffer[13], 12, 0xFD987193); + c = ff(c, d, a, b, buffer[14], 17, 0xA679438E); + b = ff(b, c, d, a, buffer[15], 22, 0x49B40821); + a = gg(a, b, c, d, buffer[1], 5, 0xF61E2562); + d = gg(d, a, b, c, buffer[6], 9, 0xC040B340); + c = gg(c, d, a, b, buffer[11], 14, 0x265E5A51); + b = gg(b, c, d, a, buffer[0], 20, 0xE9B6C7AA); + a = gg(a, b, c, d, buffer[5], 5, 0xD62F105D); + d = gg(d, a, b, c, buffer[10], 9, 0x02441453); + c = gg(c, d, a, b, buffer[15], 14, 0xD8A1E681); + b = gg(b, c, d, a, buffer[4], 20, 0xE7D3FBC8); + a = gg(a, b, c, d, buffer[9], 5, 0x21E1CDE6); + d = gg(d, a, b, c, buffer[14], 9, 0xC33707D6); + c = gg(c, d, a, b, buffer[3], 14, 0xF4D50D87); + b = gg(b, c, d, a, buffer[8], 20, 0x455A14ED); + a = gg(a, b, c, d, buffer[13], 5, 0xA9E3E905); + d = gg(d, a, b, c, buffer[2], 9, 0xFCEFA3F8); + c = gg(c, d, a, b, buffer[7], 14, 0x676F02D9); + b = gg(b, c, d, a, buffer[12], 20, 0x8D2A4C8A); + a = hh(a, b, c, d, buffer[5], 4, 0xFFFA3942); + d = hh(d, a, b, c, buffer[8], 11, 0x8771F681); + c = hh(c, d, a, b, buffer[11], 16, 0x6D9D6122); + b = hh(b, c, d, a, buffer[14], 23, 0xFDE5380C); + a = hh(a, b, c, d, buffer[1], 4, 0xA4BEEA44); + d = hh(d, a, b, c, buffer[4], 11, 0x4BDECFA9); + c = hh(c, d, a, b, buffer[7], 16, 0xF6BB4B60); + b = hh(b, c, d, a, buffer[10], 23, 0xBEBFBC70); + a = hh(a, b, c, d, buffer[13], 4, 0x289B7EC6); + d = hh(d, a, b, c, buffer[0], 11, 0xEAA127FA); + c = hh(c, d, a, b, buffer[3], 16, 0xD4EF3085); + b = hh(b, c, d, a, buffer[6], 23, 0x04881D05); + a = hh(a, b, c, d, buffer[9], 4, 0xD9D4D039); + d = hh(d, a, b, c, buffer[12], 11, 0xE6DB99E5); + c = hh(c, d, a, b, buffer[15], 16, 0x1FA27CF8); + b = hh(b, c, d, a, buffer[2], 23, 0xC4AC5665); + a = ii(a, b, c, d, buffer[0], 6, 0xF4292244); + d = ii(d, a, b, c, buffer[7], 10, 0x432AFF97); + c = ii(c, d, a, b, buffer[14], 15, 0xAB9423A7); + b = ii(b, c, d, a, buffer[5], 21, 0xFC93A039); + a = ii(a, b, c, d, buffer[12], 6, 0x655B59C3); + d = ii(d, a, b, c, buffer[3], 10, 0x8F0CCC92); + c = ii(c, d, a, b, buffer[10], 15, 0xFFEFF47D); + b = ii(b, c, d, a, buffer[1], 21, 0x85845DD1); + a = ii(a, b, c, d, buffer[8], 6, 0x6FA87E4F); + d = ii(d, a, b, c, buffer[15], 10, 0xFE2CE6E0); + c = ii(c, d, a, b, buffer[6], 15, 0xA3014314); + b = ii(b, c, d, a, buffer[13], 21, 0x4E0811A1); + a = ii(a, b, c, d, buffer[4], 6, 0xF7537E82); + d = ii(d, a, b, c, buffer[11], 10, 0xBD3AF235); + c = ii(c, d, a, b, buffer[2], 15, 0x2AD7D2BB); + b = ii(b, c, d, a, buffer[9], 21, 0xEB86D391); + w[0] = add(a, w[0]); + w[1] = add(b, w[1]); + w[2] = add(c, w[2]); + w[3] = add(d, w[3]);}; + } + (); + function caml_MD5Final(ctx){ + var in_buf = ctx.len & 0x3f; + ctx.b8[in_buf] = 0x80; + in_buf++; + if(in_buf > 56){ + for(var j = in_buf; j < 64; j++) ctx.b8[j] = 0; + caml_MD5Transform(ctx.w, ctx.b32); + for(var j = 0; j < 56; j++) ctx.b8[j] = 0; + } + else + for(var j = in_buf; j < 56; j++) ctx.b8[j] = 0; + ctx.b32[14] = ctx.len << 3; + ctx.b32[15] = ctx.len >> 29 & 0x1FFFFFFF; + caml_MD5Transform(ctx.w, ctx.b32); + var t = new Uint8Array(16); + for(var i = 0; i < 4; i++) + for(var j = 0; j < 4; j++) t[i * 4 + j] = ctx.w[i] >> 8 * j & 0xFF; + return t; + } + function caml_MD5Init(){ + var + buffer = new ArrayBuffer(64), + b32 = new Uint32Array(buffer), + b8 = new Uint8Array(buffer); + return {len: 0, + w: + new Uint32Array([0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476]), + b32: b32, + b8: b8}; + } + function caml_MD5Update(ctx, input, input_len){ + var in_buf = ctx.len & 0x3f, input_pos = 0; + ctx.len += input_len; + if(in_buf){ + var missing = 64 - in_buf; + if(input_len < missing){ + ctx.b8.set(input.subarray(0, input_len), in_buf); + return; + } + ctx.b8.set(input.subarray(0, missing), in_buf); + caml_MD5Transform(ctx.w, ctx.b32); + input_len -= missing; + input_pos += missing; + } + while(input_len >= 64){ + ctx.b8.set(input.subarray(input_pos, input_pos + 64), 0); + caml_MD5Transform(ctx.w, ctx.b32); + input_len -= 64; + input_pos += 64; + } + if(input_len) + ctx.b8.set(input.subarray(input_pos, input_pos + input_len), 0); + } + function caml_acosh_float(x){return Math.acosh(x);} + function caml_call_gen(f, args){ + var + n = f.l >= 0 ? f.l : f.l = f.length, + argsLen = args.length, + d = n - argsLen; + if(d == 0) + return f.apply(null, args); + else if(d < 0){ + var g = f.apply(null, args.slice(0, n)); + if(typeof g !== "function") return g; + return caml_call_gen(g, args.slice(n)); + } + else{ + switch(d){ + case 1: + { + var + g = + function(x){ + var nargs = new Array(argsLen + 1); + for(var i = 0; i < argsLen; i++) nargs[i] = args[i]; + nargs[argsLen] = x; + return f.apply(null, nargs); + }; + break; + } + case 2: + { + var + g = + function(x, y){ + var nargs = new Array(argsLen + 2); + for(var i = 0; i < argsLen; i++) nargs[i] = args[i]; + nargs[argsLen] = x; + nargs[argsLen + 1] = y; + return f.apply(null, nargs); + }; + break; + } + default: + var + g = + function(){ + var + extra_args = arguments.length == 0 ? 1 : arguments.length, + nargs = new Array(args.length + extra_args); + for(var i = 0; i < args.length; i++) nargs[i] = args[i]; + for(var i = 0; i < arguments.length; i++) + nargs[args.length + i] = arguments[i]; + return caml_call_gen(f, nargs); + }; + } + g.l = d; + return g; + } + } + function caml_alloc_dummy_infix(){ + return function f(x){return caml_call_gen(f.fun, [x]);}; + } + function caml_alloc_stack(hv, hx, hf){return 0;} + var + caml_argv = + function(){ + var process = globalThis.process, main = "a.out", args = []; + if(process && process.argv && process.argv.length > 1){ + var argv = process.argv; + main = argv[1]; + args = argv.slice(2); + } + var p = caml_string_of_jsstring(main), args2 = [0, p]; + for(var i = 0; i < args.length; i++) + args2.push(caml_string_of_jsstring(args[i])); + return args2; + } + (); + function caml_array_append(a1, a2){ + var l1 = a1.length, l2 = a2.length, l = l1 + l2 - 1, a = new Array(l); + a[0] = 0; + var i = 1, j = 1; + for(; i < l1; i++) a[i] = a1[i]; + for(; i < l; i++, j++) a[i] = a2[j]; + return a; + } + function caml_array_blit(a1, i1, a2, i2, len){ + if(i2 <= i1) + for(var j = 1; j <= len; j++) a2[i2 + j] = a1[i1 + j]; + else + for(var j = len; j >= 1; j--) a2[i2 + j] = a1[i1 + j]; + return 0; + } + function caml_array_concat(l){ + var a = [0]; + while(l !== 0){ + var b = l[1]; + for(var i = 1; i < b.length; i++) a.push(b[i]); + l = l[2]; + } + return a; + } + function caml_array_fill(array, ofs, len, v){ + for(var i = 0; i < len; i++) array[ofs + i + 1] = v; + return 0; + } + function caml_array_get(array, index){ + if(index < 0 || index >= array.length - 1) caml_array_bound_error(); + return array[index + 1]; + } + function caml_array_of_bytes(x){return caml_uint8_array_of_bytes(x);} + function caml_array_of_string(x){return caml_uint8_array_of_string(x);} + function caml_array_set(array, index, newval){ + if(index < 0 || index >= array.length - 1) caml_array_bound_error(); + array[index + 1] = newval; + return 0; + } + function caml_array_sub(a, i, len){ + var a2 = new Array(len + 1); + a2[0] = 0; + for(var i2 = 1, i1 = i + 1; i2 <= len; i2++, i1++) a2[i2] = a[i1]; + return a2; + } + function caml_asinh_float(x){return Math.asinh(x);} + function caml_atanh_float(x){return Math.atanh(x);} + function caml_atomic_cas(ref, o, n){ + if(ref[1] === o){ref[1] = n; return 1;} + return 0; + } + function caml_atomic_exchange(ref, v){ + var r = ref[1]; + ref[1] = v; + return r; + } + function caml_atomic_fetch_add(ref, i){ + var old = ref[1]; + ref[1] += i; + return old; + } + function caml_atomic_load(ref){return ref[1];} + function caml_atomic_make_contended(a){return [0, a];} + function caml_ba_blit(src, dst){ + if(dst.dims.length != src.dims.length) + caml_invalid_argument("Bigarray.blit: dimension mismatch"); + for(var i = 0; i < dst.dims.length; i++) + if(dst.dims[i] != src.dims[i]) + caml_invalid_argument("Bigarray.blit: dimension mismatch"); + dst.data.set(src.data); + return 0; + } + function caml_ba_change_layout(ba, layout){ + if(ba.layout == layout) return ba; + var new_dims = []; + for(var i = 0; i < ba.dims.length; i++) + new_dims[i] = ba.dims[ba.dims.length - i - 1]; + return caml_ba_create_unsafe(ba.kind, layout, new_dims, ba.data); + } + function caml_ba_compare(a, b, total){return a.compare(b, total);} + function caml_ba_create_buffer(kind, size){ + var view; + switch(kind){ + case 0: + view = Float32Array; break; + case 1: + view = Float64Array; break; + case 2: + view = Int8Array; break; + case 3: + view = Uint8Array; break; + case 4: + view = Int16Array; break; + case 5: + view = Uint16Array; break; + case 6: + view = Int32Array; break; + case 7: + view = Int32Array; break; + case 8: + view = Int32Array; break; + case 9: + view = Int32Array; break; + case 10: + view = Float32Array; break; + case 11: + view = Float64Array; break; + case 12: + view = Uint8Array; break; + } + if(! view) caml_invalid_argument("Bigarray.create: unsupported kind"); + var data = new view(size * caml_ba_get_size_per_element(kind)); + return data; + } + function caml_js_from_array(a){return a.slice(1);} + function caml_ba_create(kind, layout, dims_ml){ + var + dims = caml_js_from_array(dims_ml), + data = caml_ba_create_buffer(kind, caml_ba_get_size(dims)); + return caml_ba_create_unsafe(kind, layout, dims, data); + } + function caml_ba_create_from(data1, data2, jstyp, kind, layout, dims){ + if(data2 || caml_ba_get_size_per_element(kind) == 2) + caml_invalid_argument + ("caml_ba_create_from: use return caml_ba_create_unsafe"); + return caml_ba_create_unsafe(kind, layout, dims, data1); + } + function caml_int32_float_of_bits(x){ + var int32a = new Int32Array(1); + int32a[0] = x; + var float32a = new Float32Array(int32a.buffer); + return float32a[0]; + } + function caml_int64_of_bytes(a){ + return new + MlInt64 + (a[7] << 0 | a[6] << 8 | a[5] << 16, + a[4] << 0 | a[3] << 8 | a[2] << 16, + a[1] << 0 | a[0] << 8); + } + function caml_int64_float_of_bits(x){ + var lo = x.lo, mi = x.mi, hi = x.hi, exp = (hi & 0x7fff) >> 4; + if(exp == 2047) + return (lo | mi | hi & 0xf) == 0 + ? hi & 0x8000 ? - Infinity : Infinity + : NaN; + var k = Math.pow(2, - 24), res = (lo * k + mi) * k + (hi & 0xf); + if(exp > 0){ + res += 16; + res *= Math.pow(2, exp - 1027); + } + else + res *= Math.pow(2, - 1026); + if(hi & 0x8000) res = - res; + return res; + } + function caml_failwith(msg){ + if(! caml_global_data.Failure) + caml_global_data.Failure = [248, caml_string_of_jsbytes("Failure"), - 3]; + caml_raise_with_string(caml_global_data.Failure, msg); + } + function caml_ba_deserialize(reader, sz, name){ + var num_dims = reader.read32s(); + if(num_dims < 0 || num_dims > 16) + caml_failwith("input_value: wrong number of bigarray dimensions"); + var + tag = reader.read32s(), + kind = tag & 0xff, + layout = tag >> 8 & 1, + dims = []; + if(name == "_bigarr02") + for(var i = 0; i < num_dims; i++){ + var size_dim = reader.read16u(); + if(size_dim == 0xffff){ + var size_dim_hi = reader.read32u(), size_dim_lo = reader.read32u(); + if(size_dim_hi != 0) + caml_failwith("input_value: bigarray dimension overflow in 32bit"); + size_dim = size_dim_lo; + } + dims.push(size_dim); + } + else + for(var i = 0; i < num_dims; i++) dims.push(reader.read32u()); + var + size = caml_ba_get_size(dims), + data = caml_ba_create_buffer(kind, size), + ba = caml_ba_create_unsafe(kind, layout, dims, data); + switch(kind){ + case 2: + for(var i = 0; i < size; i++) data[i] = reader.read8s(); break; + case 3: + case 12: + for(var i = 0; i < size; i++) data[i] = reader.read8u(); break; + case 4: + for(var i = 0; i < size; i++) data[i] = reader.read16s(); break; + case 5: + for(var i = 0; i < size; i++) data[i] = reader.read16u(); break; + case 6: + for(var i = 0; i < size; i++) data[i] = reader.read32s(); break; + case 8: + case 9: + var sixty = reader.read8u(); + if(sixty) + caml_failwith + ("input_value: cannot read bigarray with 64-bit OCaml ints"); + for(var i = 0; i < size; i++) data[i] = reader.read32s(); + break; + case 7: + var t = new Array(8); + for(var i = 0; i < size; i++){ + for(var j = 0; j < 8; j++) t[j] = reader.read8u(); + var int64 = caml_int64_of_bytes(t); + ba.set(i, int64); + } + break; + case 1: + var t = new Array(8); + for(var i = 0; i < size; i++){ + for(var j = 0; j < 8; j++) t[j] = reader.read8u(); + var f = caml_int64_float_of_bits(caml_int64_of_bytes(t)); + ba.set(i, f); + } + break; + case 0: + for(var i = 0; i < size; i++){ + var f = caml_int32_float_of_bits(reader.read32s()); + ba.set(i, f); + } + break; + case 10: + for(var i = 0; i < size; i++){ + var + re = caml_int32_float_of_bits(reader.read32s()), + im = caml_int32_float_of_bits(reader.read32s()); + ba.set(i, [254, re, im]); + } + break; + case 11: + var t = new Array(8); + for(var i = 0; i < size; i++){ + for(var j = 0; j < 8; j++) t[j] = reader.read8u(); + var re = caml_int64_float_of_bits(caml_int64_of_bytes(t)); + for(var j = 0; j < 8; j++) t[j] = reader.read8u(); + var im = caml_int64_float_of_bits(caml_int64_of_bytes(t)); + ba.set(i, [254, re, im]); + } + break; + } + sz[0] = (4 + num_dims) * 4; + return caml_ba_create_unsafe(kind, layout, dims, data); + } + function caml_ba_dim(ba, i){ + if(i < 0 || i >= ba.dims.length) caml_invalid_argument("Bigarray.dim"); + return ba.dims[i]; + } + function caml_ba_dim_1(ba){return caml_ba_dim(ba, 0);} + function caml_ba_dim_2(ba){return caml_ba_dim(ba, 1);} + function caml_ba_dim_3(ba){return caml_ba_dim(ba, 2);} + function caml_ba_fill(ba, v){ba.fill(v); return 0;} + function caml_ba_kind_of_typed_array(ta){ + var kind; + if(ta instanceof Float32Array) + kind = 0; + else if(ta instanceof Float64Array) + kind = 1; + else if(ta instanceof Int8Array) + kind = 2; + else if(ta instanceof Uint8Array) + kind = 3; + else if(ta instanceof Uint8ClampedArray) + kind = 3; + else if(ta instanceof Int16Array) + kind = 4; + else if(ta instanceof Uint16Array) + kind = 5; + else if(ta instanceof Int32Array) + kind = 6; + else if(ta instanceof Uint32Array) + kind = 6; + else + caml_invalid_argument("caml_ba_kind_of_typed_array: unsupported kind"); + return kind; + } + function caml_ba_from_typed_array(ta){ + var + kind = caml_ba_kind_of_typed_array(ta), + ta = + ta instanceof Uint32Array + ? new Int32Array(ta.buffer, ta.byteOffset, ta.length) + : ta; + return caml_ba_create_unsafe(kind, 0, [ta.length], ta); + } + function caml_ba_get_2(ba, i0, i1){return ba.get(ba.offset([i0, i1]));} + function caml_ba_get_3(ba, i0, i1, i2){ + return ba.get(ba.offset([i0, i1, i2])); + } + function caml_ba_get_generic(ba, i){ + var ofs = ba.offset(caml_js_from_array(i)); + return ba.get(ofs); + } + function caml_mul(a, b){return Math.imul(a, b);} + function caml_hash_mix_int(h, d){ + d = caml_mul(d, 0xcc9e2d51 | 0); + d = d << 15 | d >>> 32 - 15; + d = caml_mul(d, 0x1b873593); + h ^= d; + h = h << 13 | h >>> 32 - 13; + return (h + (h << 2) | 0) + (0xe6546b64 | 0) | 0; + } + var log2_ok = Math.log2 && Math.log2(1.1235582092889474E+307) == 1020; + function jsoo_floor_log2(x){ + if(log2_ok) return Math.floor(Math.log2(x)); + var i = 0; + if(x == 0) return - Infinity; + if(x >= 1) while(x >= 2){x /= 2; i++;} else while(x < 1){x *= 2; i--;} + return i; + } + function caml_int64_create_lo_mi_hi(lo, mi, hi){return new MlInt64(lo, mi, hi); + } + function caml_int64_bits_of_float(x){ + if(! isFinite(x)){ + if(isNaN(x)) return caml_int64_create_lo_mi_hi(1, 0, 0x7ff0); + return x > 0 + ? caml_int64_create_lo_mi_hi(0, 0, 0x7ff0) + : caml_int64_create_lo_mi_hi(0, 0, 0xfff0); + } + var sign = x == 0 && 1 / x == - Infinity ? 0x8000 : x >= 0 ? 0 : 0x8000; + if(sign) x = - x; + var exp = jsoo_floor_log2(x) + 1023; + if(exp <= 0){ + exp = 0; + x /= Math.pow(2, - 1026); + } + else{ + x /= Math.pow(2, exp - 1027); + if(x < 16){x *= 2; exp -= 1;} + if(exp == 0) x /= 2; + } + var k = Math.pow(2, 24), r3 = x | 0; + x = (x - r3) * k; + var r2 = x | 0; + x = (x - r2) * k; + var r1 = x | 0; + r3 = r3 & 0xf | sign | exp << 4; + return caml_int64_create_lo_mi_hi(r1, r2, r3); + } + function caml_hash_mix_int64(h, v){ + h = caml_hash_mix_int(h, caml_int64_lo32(v)); + h = caml_hash_mix_int(h, caml_int64_hi32(v)); + return h; + } + function caml_hash_mix_float(h, v0){ + return caml_hash_mix_int64(h, caml_int64_bits_of_float(v0)); + } + function caml_ba_hash(ba){ + var num_elts = caml_ba_get_size(ba.dims), h = 0; + switch(ba.kind){ + case 2: + case 3: + case 12: + if(num_elts > 256) num_elts = 256; + var w = 0, i = 0; + for(i = 0; i + 4 <= ba.data.length; i += 4){ + w = + ba.data[i + 0] | ba.data[i + 1] << 8 | ba.data[i + 2] << 16 + | ba.data[i + 3] << 24; + h = caml_hash_mix_int(h, w); + } + w = 0; + switch(num_elts & 3){ + case 3: + w = ba.data[i + 2] << 16; + case 2: + w |= ba.data[i + 1] << 8; + case 1: + w |= ba.data[i + 0]; h = caml_hash_mix_int(h, w); + } + break; + case 4: + case 5: + if(num_elts > 128) num_elts = 128; + var w = 0, i = 0; + for(i = 0; i + 2 <= ba.data.length; i += 2){ + w = ba.data[i + 0] | ba.data[i + 1] << 16; + h = caml_hash_mix_int(h, w); + } + if((num_elts & 1) != 0) h = caml_hash_mix_int(h, ba.data[i]); + break; + case 6: + if(num_elts > 64) num_elts = 64; + for(var i = 0; i < num_elts; i++) h = caml_hash_mix_int(h, ba.data[i]); + break; + case 8: + case 9: + if(num_elts > 64) num_elts = 64; + for(var i = 0; i < num_elts; i++) h = caml_hash_mix_int(h, ba.data[i]); + break; + case 7: + if(num_elts > 32) num_elts = 32; + num_elts *= 2; + for(var i = 0; i < num_elts; i++) h = caml_hash_mix_int(h, ba.data[i]); + break; + case 10: + num_elts *= 2; + case 0: + if(num_elts > 64) num_elts = 64; + for(var i = 0; i < num_elts; i++) + h = caml_hash_mix_float(h, ba.data[i]); + break; + case 11: + num_elts *= 2; + case 1: + if(num_elts > 32) num_elts = 32; + for(var i = 0; i < num_elts; i++) + h = caml_hash_mix_float(h, ba.data[i]); + break; + } + return h; + } + function caml_ba_init(){return 0;} + function caml_ba_kind(ba){return ba.kind;} + function caml_ba_layout(ba){return ba.layout;} + function caml_ba_map_file(vfd, kind, layout, shared, dims, pos){caml_failwith("caml_ba_map_file not implemented"); + } + function caml_ba_map_file_bytecode(argv, argn){ + return caml_ba_map_file + (argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); + } + function caml_ba_num_dims(ba){return ba.dims.length;} + function caml_ba_reshape(ba, vind){ + vind = caml_js_from_array(vind); + var new_dim = [], num_dims = vind.length; + if(num_dims < 0 || num_dims > 16) + caml_invalid_argument("Bigarray.reshape: bad number of dimensions"); + var num_elts = 1; + for(var i = 0; i < num_dims; i++){ + new_dim[i] = vind[i]; + if(new_dim[i] < 0) + caml_invalid_argument("Bigarray.reshape: negative dimension"); + num_elts = num_elts * new_dim[i]; + } + var size = caml_ba_get_size(ba.dims); + if(num_elts != size) + caml_invalid_argument("Bigarray.reshape: size mismatch"); + return caml_ba_create_unsafe(ba.kind, ba.layout, new_dim, ba.data); + } + function caml_int32_bits_of_float(x){ + var float32a = new Float32Array(1); + float32a[0] = x; + var int32a = new Int32Array(float32a.buffer); + return int32a[0] | 0; + } + function caml_int64_to_bytes(x){return x.toArray();} + function caml_ba_serialize(writer, ba, sz){ + writer.write(32, ba.dims.length); + writer.write(32, ba.kind | ba.layout << 8); + if(ba.caml_custom == "_bigarr02") + for(var i = 0; i < ba.dims.length; i++) + if(ba.dims[i] < 0xffff) + writer.write(16, ba.dims[i]); + else{ + writer.write(16, 0xffff); + writer.write(32, 0); + writer.write(32, ba.dims[i]); + } + else + for(var i = 0; i < ba.dims.length; i++) writer.write(32, ba.dims[i]); + switch(ba.kind){ + case 2: + case 3: + case 12: + for(var i = 0; i < ba.data.length; i++) writer.write(8, ba.data[i]); + break; + case 4: + case 5: + for(var i = 0; i < ba.data.length; i++) writer.write(16, ba.data[i]); + break; + case 6: + for(var i = 0; i < ba.data.length; i++) writer.write(32, ba.data[i]); + break; + case 8: + case 9: + writer.write(8, 0); + for(var i = 0; i < ba.data.length; i++) writer.write(32, ba.data[i]); + break; + case 7: + for(var i = 0; i < ba.data.length / 2; i++){ + var b = caml_int64_to_bytes(ba.get(i)); + for(var j = 0; j < 8; j++) writer.write(8, b[j]); + } + break; + case 1: + for(var i = 0; i < ba.data.length; i++){ + var b = caml_int64_to_bytes(caml_int64_bits_of_float(ba.get(i))); + for(var j = 0; j < 8; j++) writer.write(8, b[j]); + } + break; + case 0: + for(var i = 0; i < ba.data.length; i++){ + var b = caml_int32_bits_of_float(ba.get(i)); + writer.write(32, b); + } + break; + case 10: + for(var i = 0; i < ba.data.length / 2; i++){ + var j = ba.get(i); + writer.write(32, caml_int32_bits_of_float(j[1])); + writer.write(32, caml_int32_bits_of_float(j[2])); + } + break; + case 11: + for(var i = 0; i < ba.data.length / 2; i++){ + var + complex = ba.get(i), + b = caml_int64_to_bytes(caml_int64_bits_of_float(complex[1])); + for(var j = 0; j < 8; j++) writer.write(8, b[j]); + var b = caml_int64_to_bytes(caml_int64_bits_of_float(complex[2])); + for(var j = 0; j < 8; j++) writer.write(8, b[j]); + } + break; + } + sz[0] = (4 + ba.dims.length) * 4; + sz[1] = (4 + ba.dims.length) * 8; + } + function caml_ba_set_1(ba, i0, v){ba.set(ba.offset(i0), v); return 0;} + function caml_ba_set_2(ba, i0, i1, v){ + ba.set(ba.offset([i0, i1]), v); + return 0; + } + function caml_ba_set_3(ba, i0, i1, i2, v){ + ba.set(ba.offset([i0, i1, i2]), v); + return 0; + } + function caml_ba_set_generic(ba, i, v){ + ba.set(ba.offset(caml_js_from_array(i)), v); + return 0; + } + function caml_ba_slice(ba, vind){ + vind = caml_js_from_array(vind); + var num_inds = vind.length, index = [], sub_dims = [], ofs; + if(num_inds > ba.dims.length) + caml_invalid_argument("Bigarray.slice: too many indices"); + if(ba.layout == 0){ + for(var i = 0; i < num_inds; i++) index[i] = vind[i]; + for(; i < ba.dims.length; i++) index[i] = 0; + sub_dims = ba.dims.slice(num_inds); + } + else{ + for(var i = 0; i < num_inds; i++) + index[ba.dims.length - num_inds + i] = vind[i]; + for(var i = 0; i < ba.dims.length - num_inds; i++) index[i] = 1; + sub_dims = ba.dims.slice(0, ba.dims.length - num_inds); + } + ofs = ba.offset(index); + var + size = caml_ba_get_size(sub_dims), + size_per_element = caml_ba_get_size_per_element(ba.kind), + new_data = + ba.data.subarray + (ofs * size_per_element, (ofs + size) * size_per_element); + return caml_ba_create_unsafe(ba.kind, ba.layout, sub_dims, new_data); + } + function caml_ba_sub(ba, ofs, len){ + var changed_dim, mul = 1; + if(ba.layout == 0){ + for(var i = 1; i < ba.dims.length; i++) mul = mul * ba.dims[i]; + changed_dim = 0; + } + else{ + for(var i = 0; i < ba.dims.length - 1; i++) mul = mul * ba.dims[i]; + changed_dim = ba.dims.length - 1; + ofs = ofs - 1; + } + if(ofs < 0 || len < 0 || ofs + len > ba.dims[changed_dim]) + caml_invalid_argument("Bigarray.sub: bad sub-array"); + var new_dims = []; + for(var i = 0; i < ba.dims.length; i++) new_dims[i] = ba.dims[i]; + new_dims[changed_dim] = len; + mul *= caml_ba_get_size_per_element(ba.kind); + var new_data = ba.data.subarray(ofs * mul, (ofs + len) * mul); + return caml_ba_create_unsafe(ba.kind, ba.layout, new_dims, new_data); + } + function caml_ba_to_typed_array(ba){return ba.data;} + function caml_ba_uint8_get16(ba, i0){ + var ofs = ba.offset(i0); + if(ofs + 1 >= ba.data.length) caml_array_bound_error(); + var b1 = ba.get(ofs), b2 = ba.get(ofs + 1); + return b1 | b2 << 8; + } + function caml_ba_uint8_get32(ba, i0){ + var ofs = ba.offset(i0); + if(ofs + 3 >= ba.data.length) caml_array_bound_error(); + var + b1 = ba.get(ofs + 0), + b2 = ba.get(ofs + 1), + b3 = ba.get(ofs + 2), + b4 = ba.get(ofs + 3); + return b1 << 0 | b2 << 8 | b3 << 16 | b4 << 24; + } + function caml_ba_uint8_get64(ba, i0){ + var ofs = ba.offset(i0); + if(ofs + 7 >= ba.data.length) caml_array_bound_error(); + var + b1 = ba.get(ofs + 0), + b2 = ba.get(ofs + 1), + b3 = ba.get(ofs + 2), + b4 = ba.get(ofs + 3), + b5 = ba.get(ofs + 4), + b6 = ba.get(ofs + 5), + b7 = ba.get(ofs + 6), + b8 = ba.get(ofs + 7); + return caml_int64_of_bytes([b8, b7, b6, b5, b4, b3, b2, b1]); + } + function caml_ba_uint8_set16(ba, i0, v){ + var ofs = ba.offset(i0); + if(ofs + 1 >= ba.data.length) caml_array_bound_error(); + ba.set(ofs + 0, v & 0xff); + ba.set(ofs + 1, v >>> 8 & 0xff); + return 0; + } + function caml_ba_uint8_set32(ba, i0, v){ + var ofs = ba.offset(i0); + if(ofs + 3 >= ba.data.length) caml_array_bound_error(); + ba.set(ofs + 0, v & 0xff); + ba.set(ofs + 1, v >>> 8 & 0xff); + ba.set(ofs + 2, v >>> 16 & 0xff); + ba.set(ofs + 3, v >>> 24 & 0xff); + return 0; + } + function caml_ba_uint8_set64(ba, i0, v){ + var ofs = ba.offset(i0); + if(ofs + 7 >= ba.data.length) caml_array_bound_error(); + var v = caml_int64_to_bytes(v); + for(var i = 0; i < 8; i++) ba.set(ofs + i, v[7 - i]); + return 0; + } + function caml_backtrace_status(_unit){ + return caml_record_backtrace_flag ? 1 : 0; + } + function caml_bigstring_blit_bytes_to_ba(str1, pos1, ba2, pos2, len){ + if(12 != ba2.kind) + caml_invalid_argument("caml_bigstring_blit_string_to_ba: kind mismatch"); + if(len == 0) return 0; + var ofs2 = ba2.offset(pos2); + if(pos1 + len > caml_ml_bytes_length(str1)) caml_array_bound_error(); + if(ofs2 + len > ba2.data.length) caml_array_bound_error(); + var slice = caml_uint8_array_of_bytes(str1).slice(pos1, pos1 + len); + ba2.data.set(slice, ofs2); + return 0; + } + function caml_bigstring_memcmp(s1, pos1, s2, pos2, len){ + for(var i = 0; i < len; i++){ + var a = caml_ba_get_1(s1, pos1 + i), b = caml_ba_get_1(s2, pos2 + i); + if(a < b) return - 1; + if(a > b) return 1; + } + return 0; + } + function caml_blit_string(a, b, c, d, e){ + caml_blit_bytes(caml_bytes_of_string(a), b, c, d, e); + return 0; + } + function caml_bswap16(x){return (x & 0x00FF) << 8 | (x & 0xFF00) >> 8;} + function caml_jsstring_of_string(s){ + if(jsoo_is_ascii(s)) return s; + return caml_utf16_of_utf8(s); + } + function caml_build_symbols(symb){ + var r = {}; + if(symb) + for(var i = 1; i < symb.length; i++) + r[caml_jsstring_of_string(symb[i][1])] = symb[i][2]; + return r; + } + function caml_bytes_compare(s1, s2){ + s1.t & 6 && caml_convert_string_to_bytes(s1); + s2.t & 6 && caml_convert_string_to_bytes(s2); + return s1.c < s2.c ? - 1 : s1.c > s2.c ? 1 : 0; + } + function caml_bytes_equal(s1, s2){ + if(s1 === s2) return 1; + s1.t & 6 && caml_convert_string_to_bytes(s1); + s2.t & 6 && caml_convert_string_to_bytes(s2); + return s1.c == s2.c ? 1 : 0; + } + function caml_bytes_unsafe_get(s, i){ + switch(s.t & 6){ + default: if(i >= s.c.length) return 0; + case 0: + return s.c.charCodeAt(i); + case 4: + return s.c[i]; + } + } + function caml_bytes_get(s, i){ + if(i >>> 0 >= s.l) caml_bytes_bound_error(); + return caml_bytes_unsafe_get(s, i); + } + function caml_bytes_get16(s, i){ + if(i >>> 0 >= s.l - 1) caml_bytes_bound_error(); + var + b1 = caml_bytes_unsafe_get(s, i), + b2 = caml_bytes_unsafe_get(s, i + 1); + return b2 << 8 | b1; + } + function caml_bytes_get32(s, i){ + if(i >>> 0 >= s.l - 3) caml_bytes_bound_error(); + var + b1 = caml_bytes_unsafe_get(s, i), + b2 = caml_bytes_unsafe_get(s, i + 1), + b3 = caml_bytes_unsafe_get(s, i + 2), + b4 = caml_bytes_unsafe_get(s, i + 3); + return b4 << 24 | b3 << 16 | b2 << 8 | b1; + } + function caml_bytes_get64(s, i){ + if(i >>> 0 >= s.l - 7) caml_bytes_bound_error(); + var a = new Array(8); + for(var j = 0; j < 8; j++) a[7 - j] = caml_bytes_unsafe_get(s, i + j); + return caml_int64_of_bytes(a); + } + function caml_bytes_lessequal(s1, s2){ + s1.t & 6 && caml_convert_string_to_bytes(s1); + s2.t & 6 && caml_convert_string_to_bytes(s2); + return s1.c <= s2.c ? 1 : 0; + } + function caml_bytes_greaterequal(s1, s2){return caml_bytes_lessequal(s2, s1); + } + function caml_bytes_lessthan(s1, s2){ + s1.t & 6 && caml_convert_string_to_bytes(s1); + s2.t & 6 && caml_convert_string_to_bytes(s2); + return s1.c < s2.c ? 1 : 0; + } + function caml_bytes_greaterthan(s1, s2){return caml_bytes_lessthan(s2, s1); + } + function caml_bytes_notequal(s1, s2){return 1 - caml_bytes_equal(s1, s2);} + function caml_bytes_of_utf16_jsstring(s){ + var tag = 9; + if(! jsoo_is_ascii(s)) tag = 8, s = caml_utf8_of_utf16(s); + return new MlBytes(tag, s, s.length); + } + function caml_bytes_set16(s, i, i16){ + if(i >>> 0 >= s.l - 1) caml_bytes_bound_error(); + var b2 = 0xFF & i16 >> 8, b1 = 0xFF & i16; + caml_bytes_unsafe_set(s, i + 0, b1); + caml_bytes_unsafe_set(s, i + 1, b2); + return 0; + } + function caml_bytes_set32(s, i, i32){ + if(i >>> 0 >= s.l - 3) caml_bytes_bound_error(); + var + b4 = 0xFF & i32 >> 24, + b3 = 0xFF & i32 >> 16, + b2 = 0xFF & i32 >> 8, + b1 = 0xFF & i32; + caml_bytes_unsafe_set(s, i + 0, b1); + caml_bytes_unsafe_set(s, i + 1, b2); + caml_bytes_unsafe_set(s, i + 2, b3); + caml_bytes_unsafe_set(s, i + 3, b4); + return 0; + } + function caml_bytes_set64(s, i, i64){ + if(i >>> 0 >= s.l - 7) caml_bytes_bound_error(); + var a = caml_int64_to_bytes(i64); + for(var j = 0; j < 8; j++) caml_bytes_unsafe_set(s, i + 7 - j, a[j]); + return 0; + } + var caml_callback = caml_call_gen; + function caml_cbrt_float(x){return Math.cbrt(x);} + var caml_ml_channels = new Array(); + function caml_ml_channel_get(id){return caml_ml_channels[id];} + function caml_channel_descriptor(chanid){ + var chan = caml_ml_channel_get(chanid); + return chan.fd; + } + function caml_check_bound(array, index){ + if(index >>> 0 >= array.length - 1) caml_array_bound_error(); + return array; + } + function caml_classify_float(x){ + if(isFinite(x)){ + if(Math.abs(x) >= 2.2250738585072014e-308) return 0; + if(x != 0) return 1; + return 2; + } + return isNaN(x) ? 4 : 3; + } + function caml_is_continuation_tag(t){return 0;} + function caml_int32_unmarshal(reader, size){size[0] = 4; return reader.read32s(); + } + function caml_nativeint_unmarshal(reader, size){ + switch(reader.read8u()){ + case 1: + size[0] = 4; return reader.read32s(); + case 2: + caml_failwith("input_value: native integer value too large"); + default: caml_failwith("input_value: ill-formed native integer"); + } + } + function caml_int64_unmarshal(reader, size){ + var t = new Array(8); + for(var j = 0; j < 8; j++) t[j] = reader.read8u(); + size[0] = 8; + return caml_int64_of_bytes(t); + } + function caml_int64_marshal(writer, v, sizes){ + var b = caml_int64_to_bytes(v); + for(var i = 0; i < 8; i++) writer.write(8, b[i]); + sizes[0] = 8; + sizes[1] = 8; + } + function caml_int64_compare(x, y, total){return x.compare(y);} + function caml_int64_hash(v){return v.lo32() ^ v.hi32();} + var + caml_custom_ops = + {"_j": + {deserialize: caml_int64_unmarshal, + serialize: caml_int64_marshal, + fixed_length: 8, + compare: caml_int64_compare, + hash: caml_int64_hash}, + "_i": {deserialize: caml_int32_unmarshal, fixed_length: 4}, + "_n": {deserialize: caml_nativeint_unmarshal, fixed_length: 4}, + "_bigarray": + {deserialize: + function(reader, sz){ + return caml_ba_deserialize(reader, sz, "_bigarray"); + }, + serialize: caml_ba_serialize, + compare: caml_ba_compare, + hash: caml_ba_hash}, + "_bigarr02": + {deserialize: + function(reader, sz){ + return caml_ba_deserialize(reader, sz, "_bigarr02"); + }, + serialize: caml_ba_serialize, + compare: caml_ba_compare, + hash: caml_ba_hash}}; + function caml_compare_val_get_custom(a){ + return caml_custom_ops[a.caml_custom] + && caml_custom_ops[a.caml_custom].compare; + } + function caml_compare_val_number_custom(num, custom, swap, total){ + var comp = caml_compare_val_get_custom(custom); + if(comp){ + var x = swap > 0 ? comp(custom, num, total) : comp(num, custom, total); + if(total && x != x) return swap; + if(+ x != + x) return + x; + if((x | 0) != 0) return x | 0; + } + return swap; + } + function caml_compare_val_tag(a){ + if(typeof a === "number") + return 1000; + else if(caml_is_ml_bytes(a)) + return 252; + else if(caml_is_ml_string(a)) + return 1252; + else if(a instanceof Array && a[0] === a[0] >>> 0 && a[0] <= 255){var tag = a[0] | 0; return tag == 254 ? 0 : tag;} + else if(a instanceof String) + return 12520; + else if(typeof a == "string") + return 12520; + else if(a instanceof Number) + return 1000; + else if(a && a.caml_custom) + return 1255; + else if(a && a.compare) + return 1256; + else if(typeof a == "function") + return 1247; + else if(typeof a == "symbol") return 1251; + return 1001; + } + function caml_string_compare(s1, s2){ + return s1 < s2 ? - 1 : s1 > s2 ? 1 : 0; + } + function caml_compare_val(a, b, total){ + var stack = []; + for(;;){ + if(! (total && a === b)){ + var tag_a = caml_compare_val_tag(a); + if(tag_a == 250){a = a[1]; continue;} + var tag_b = caml_compare_val_tag(b); + if(tag_b == 250){b = b[1]; continue;} + if(tag_a !== tag_b){ + if(tag_a == 1000){ + if(tag_b == 1255) + return caml_compare_val_number_custom(a, b, - 1, total); + return - 1; + } + if(tag_b == 1000){ + if(tag_a == 1255) + return caml_compare_val_number_custom(b, a, 1, total); + return 1; + } + return tag_a < tag_b ? - 1 : 1; + } + switch(tag_a){ + case 247: + caml_invalid_argument("compare: functional value"); break; + case 248: + var x = caml_int_compare(a[2], b[2]); if(x != 0) return x | 0; break; + case 249: + caml_invalid_argument("compare: functional value"); break; + case 250: + caml_invalid_argument("equal: got Forward_tag, should not happen"); + break; + case 251: + caml_invalid_argument("equal: abstract value"); break; + case 252: + if(a !== b){ + var x = caml_bytes_compare(a, b); + if(x != 0) return x | 0; + } + break; + case 253: + caml_invalid_argument("equal: got Double_tag, should not happen"); + break; + case 254: + caml_invalid_argument + ("equal: got Double_array_tag, should not happen"); + break; + case 255: + caml_invalid_argument("equal: got Custom_tag, should not happen"); + break; + case 1247: + caml_invalid_argument("compare: functional value"); break; + case 1255: + var comp = caml_compare_val_get_custom(a); + if(comp != caml_compare_val_get_custom(b)) + return a.caml_custom < b.caml_custom ? - 1 : 1; + if(! comp) caml_invalid_argument("compare: abstract value"); + var x = comp(a, b, total); + if(x != x) return total ? - 1 : x; + if(x !== (x | 0)) return - 1; + if(x != 0) return x | 0; + break; + case 1256: + var x = a.compare(b, total); + if(x != x) return total ? - 1 : x; + if(x !== (x | 0)) return - 1; + if(x != 0) return x | 0; + break; + case 1000: + a = + a; + b = + b; + if(a < b) return - 1; + if(a > b) return 1; + if(a != b){ + if(! total) return NaN; + if(a == a) return 1; + if(b == b) return - 1; + } + break; + case 1001: + if(a < b) return - 1; + if(a > b) return 1; + if(a != b){ + if(! total) return NaN; + if(a == a) return 1; + if(b == b) return - 1; + } + break; + case 1251: + if(a !== b){if(! total) return NaN; return 1;} break; + case 1252: + var a = caml_jsbytes_of_string(a), b = caml_jsbytes_of_string(b); + if(a !== b){if(a < b) return - 1; if(a > b) return 1;} + break; + case 12520: + var a = a.toString(), b = b.toString(); + if(a !== b){if(a < b) return - 1; if(a > b) return 1;} + break; + case 246: + case 254: + default: + if(caml_is_continuation_tag(tag_a)){ + caml_invalid_argument("compare: continuation value"); + break; + } + if(a.length != b.length) return a.length < b.length ? - 1 : 1; + if(a.length > 1) stack.push(a, b, 1); + break; + } + } + if(stack.length == 0) return 0; + var i = stack.pop(); + b = stack.pop(); + a = stack.pop(); + if(i + 1 < a.length) stack.push(a, b, i + 1); + a = a[i]; + b = b[i]; + } + } + function caml_compare(a, b){return caml_compare_val(a, b, true);} + function caml_continuation_use_noexc(cont){ + var stack = cont[1]; + cont[1] = 0; + return stack; + } + function caml_continuation_use_and_update_handler_noexc + (cont, hval, hexn, heff){ + var stack = caml_continuation_use_noexc(cont); + stack[3] = [0, hval, hexn, heff]; + return stack; + } + function caml_convert_raw_backtrace(){return [0];} + function caml_convert_raw_backtrace_slot(){ + caml_failwith("caml_convert_raw_backtrace_slot"); + } + function caml_copysign_float(x, y){ + if(y == 0) y = 1 / y; + x = Math.abs(x); + return y < 0 ? - x : x; + } + function caml_cosh_float(x){return Math.cosh(x);} + function fs_node_supported(){ + return typeof globalThis.process !== "undefined" + && typeof globalThis.process.versions !== "undefined" + && typeof globalThis.process.versions.node !== "undefined"; + } + function make_path_is_absolute(){ + function posix(path){ + if(path.charAt(0) === "/") return ["", path.substring(1)]; + return; + } + function win32(path){ + var + splitDeviceRe = + /^([a-zA-Z]:|[\\/]{2}[^\\/]+[\\/]+[^\\/]+)?([\\/])?([\s\S]*?)$/, + result = splitDeviceRe.exec(path), + device = result[1] || "", + isUnc = Boolean(device && device.charAt(1) !== ":"); + if(Boolean(result[2] || isUnc)){ + var root = result[1] || "", sep = result[2] || ""; + return [root, path.substring(root.length + sep.length)]; + } + return; + } + return fs_node_supported() && globalThis.process + && globalThis.process.platform + ? globalThis.process.platform === "win32" ? win32 : posix + : posix; + } + var path_is_absolute = make_path_is_absolute(); + function caml_trailing_slash(name){ + return name.slice(- 1) !== "/" ? name + "/" : name; + } + if(fs_node_supported() && globalThis.process && globalThis.process.cwd) + var caml_current_dir = globalThis.process.cwd().replace(/\\/g, "/"); + else + var caml_current_dir = "/static"; + caml_current_dir = caml_trailing_slash(caml_current_dir); + function caml_make_path(name){ + name = caml_jsstring_of_string(name); + if(! path_is_absolute(name)) name = caml_current_dir + name; + var + comp0 = path_is_absolute(name), + comp = comp0[1].split("/"), + ncomp = []; + for(var i = 0; i < comp.length; i++) + switch(comp[i]){ + case "..": + if(ncomp.length > 1) ncomp.pop(); break; + case ".": break; + case "": break; + default: ncomp.push(comp[i]); break; + } + ncomp.unshift(comp0[0]); + ncomp.orig = name; + return ncomp; + } + function caml_get_root(path){ + var x = path_is_absolute(path); + if(! x) return; + return x[0] + "/"; + } + var + caml_root = + caml_get_root(caml_current_dir) + || caml_failwith("unable to compute caml_root"), + jsoo_mount_point = []; + if(fs_node_supported()) + jsoo_mount_point.push + ({path: caml_root, device: new MlNodeDevice(caml_root)}); + else + jsoo_mount_point.push + ({path: caml_root, device: new MlFakeDevice(caml_root)}); + jsoo_mount_point.push + ({path: "/static/", device: new MlFakeDevice("/static/")}); + function resolve_fs_device(name){ + var + path = caml_make_path(name), + name = path.join("/"), + name_slash = caml_trailing_slash(name), + res; + for(var i = 0; i < jsoo_mount_point.length; i++){ + var m = jsoo_mount_point[i]; + if + (name_slash.search(m.path) == 0 + && (! res || res.path.length < m.path.length)) + res = + {path: m.path, + device: m.device, + rest: name.substring(m.path.length, name.length)}; + } + if(! res && fs_node_supported()){ + var root = caml_get_root(name); + if(root && root.match(/^[a-zA-Z]:\/$/)){ + var m = {path: root, device: new MlNodeDevice(root)}; + jsoo_mount_point.push(m); + res = + {path: m.path, + device: m.device, + rest: name.substring(m.path.length, name.length)}; + } + } + if(res) return res; + caml_raise_sys_error("no device found for " + name_slash); + } + function caml_create_file(name, content){ + var root = resolve_fs_device(name); + if(! root.device.register) caml_failwith("cannot register file"); + root.device.register(root.rest, content); + return 0; + } + function caml_create_string(len){caml_invalid_argument("String.create");} + var caml_custom_event_index = 0, caml_decompress_input = null; + function caml_div(x, y){ + if(y == 0) caml_raise_zero_divide(); + return x / y | 0; + } + var caml_domain_dls = [0]; + function caml_domain_dls_get(unit){return caml_domain_dls;} + function caml_domain_dls_set(a){caml_domain_dls = a;} + var caml_domain_id = 0; + function caml_ml_mutex_unlock(t){t.locked = false; return 0;} + var caml_domain_latest_idx = 1; + function caml_domain_spawn(f, mutex){ + var id = caml_domain_latest_idx++, old = caml_domain_id; + caml_domain_id = id; + var res = caml_callback(f, [0]); + caml_domain_id = old; + caml_ml_mutex_unlock(mutex); + return id; + } + var caml_ephe_data_offset = 2, caml_ephe_key_offset = 3; + function caml_ephe_unset_data(x){ + if(globalThis.FinalizationRegistry && globalThis.WeakRef) + if(x[1] instanceof globalThis.FinalizationRegistry) + for(var j = caml_ephe_key_offset; j < x.length; j++){ + var key = x[j]; + if(key instanceof globalThis.WeakRef){ + key = key.deref(); + if(key) x[1].unregister(key); + } + } + x[caml_ephe_data_offset] = undefined; + return 0; + } + function caml_ephe_set_data(x, data){ + if(globalThis.FinalizationRegistry && globalThis.WeakRef) + if(! (x[1] instanceof globalThis.FinalizationRegistry)){ + x[1] = + new + globalThis.FinalizationRegistry + (function(){caml_ephe_unset_data(x);}); + for(var j = caml_ephe_key_offset; j < x.length; j++){ + var key = x[j]; + if(key instanceof globalThis.WeakRef){ + key = key.deref(); + if(key) x[1].register(key, undefined, key); + } + } + } + x[caml_ephe_data_offset] = data; + return 0; + } + function caml_ephe_blit_data(src, dst){ + var n = src[caml_ephe_data_offset]; + if(n === undefined) + caml_ephe_unset_data(dst); + else + caml_ephe_set_data(dst, n); + return 0; + } + function caml_ephe_blit_key(a1, i1, a2, i2, len){ + caml_array_blit + (a1, + caml_ephe_key_offset + i1 - 1, + a2, + caml_ephe_key_offset + i2 - 1, + len); + return 0; + } + function caml_ephe_check_data(x){ + return x[caml_ephe_data_offset] === undefined ? 0 : 1; + } + function caml_ephe_check_key(x, i){ + var weak = x[caml_ephe_key_offset + i]; + if(globalThis.WeakRef && weak instanceof globalThis.WeakRef) + weak = weak.deref(); + return weak === undefined ? 0 : 1; + } + function caml_weak_create(n){ + if(n < 0) caml_invalid_argument("Weak.create"); + var x = [251, "caml_ephe_list_head"]; + x.length = caml_ephe_key_offset + n; + return x; + } + function caml_ephe_create(n){var x = caml_weak_create(n); return x;} + function caml_ephe_get_data(x){ + return x[caml_ephe_data_offset] === undefined + ? 0 + : [0, x[caml_ephe_data_offset]]; + } + function caml_obj_dup(x){ + var l = x.length, a = new Array(l); + for(var i = 0; i < l; i++) a[i] = x[i]; + return a; + } + function caml_ephe_get_data_copy(x){ + return x[caml_ephe_data_offset] === undefined + ? 0 + : [0, caml_obj_dup(x[caml_ephe_data_offset])]; + } + function caml_ephe_get_key(x, i){ + if(i < 0 || caml_ephe_key_offset + i >= x.length) + caml_invalid_argument("Weak.get_key"); + var weak = x[caml_ephe_key_offset + i]; + if(globalThis.WeakRef && weak instanceof globalThis.WeakRef) + weak = weak.deref(); + return weak === undefined ? 0 : [0, weak]; + } + function caml_ephe_get_key_copy(x, i){ + if(i < 0 || caml_ephe_key_offset + i >= x.length) + caml_invalid_argument("Weak.get_copy"); + var y = caml_ephe_get_key(x, i); + if(y === 0) return y; + var z = y[1]; + if(z instanceof Array) return [0, caml_obj_dup(z)]; + return y; + } + function caml_ephe_set_key(x, i, v){ + if(i < 0 || caml_ephe_key_offset + i >= x.length) + caml_invalid_argument("Weak.set"); + if(v instanceof Object && globalThis.WeakRef){ + if(x[1].register) x[1].register(v, undefined, v); + x[caml_ephe_key_offset + i] = new globalThis.WeakRef(v); + } + else + x[caml_ephe_key_offset + i] = v; + return 0; + } + function caml_ephe_unset_key(x, i){ + if(i < 0 || caml_ephe_key_offset + i >= x.length) + caml_invalid_argument("Weak.set"); + if + (globalThis.WeakRef + && x[caml_ephe_key_offset + i] instanceof globalThis.WeakRef + && x[1].unregister){ + var old = x[caml_ephe_key_offset + i].deref(); + if(old !== undefined){ + var count = 0; + for(var j = caml_ephe_key_offset; j < x.length; j++){ + var key = x[j]; + if(key instanceof globalThis.WeakRef){ + key = key.deref(); + if(key === old) count++; + } + } + if(count == 1) x[1].unregister(old); + } + } + x[caml_ephe_key_offset + i] = undefined; + return 0; + } + function caml_equal(x, y){return + (caml_compare_val(x, y, false) == 0);} + function caml_erf_float(x){ + var + a1 = 0.254829592, + a2 = - 0.284496736, + a3 = 1.421413741, + a4 = - 1.453152027, + a5 = 1.061405429, + p = 0.3275911, + sign = 1; + if(x < 0) sign = - 1; + x = Math.abs(x); + var + t = 1.0 / (1.0 + p * x), + y = + 1.0 + - + ((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t + * Math.exp(- (x * x)); + return sign * y; + } + function caml_erfc_float(x){return 1 - caml_erf_float(x);} + function caml_eventlog_pause(unit){return 0;} + function caml_eventlog_resume(unit){return 0;} + var caml_executable_name = caml_argv[1]; + function caml_exp2_float(x){return Math.pow(2, x);} + function caml_expm1_float(x){return Math.expm1(x);} + function caml_is_special_exception(exn){ + switch(exn[2]){case - 8:case - 11:case - 12: return 1;default: return 0; + } + } + function caml_format_exception(exn){ + var r = ""; + if(exn[0] == 0){ + r += exn[1][1]; + if + (exn.length == 3 && exn[2][0] == 0 && caml_is_special_exception(exn[1])) + var bucket = exn[2], start = 1; + else + var start = 2, bucket = exn; + r += "("; + for(var i = start; i < bucket.length; i++){ + if(i > start) r += ", "; + var v = bucket[i]; + if(typeof v == "number") + r += v.toString(); + else if(v instanceof MlBytes) + r += '"' + v.toString() + '"'; + else if(typeof v == "string") + r += '"' + v.toString() + '"'; + else + r += "_"; + } + r += ")"; + } + else if(exn[0] == 248) r += exn[1]; + return r; + } + function caml_fatal_uncaught_exception(err){ + if(err instanceof Array && (err[0] == 0 || err[0] == 248)){ + var handler = caml_named_value("Printexc.handle_uncaught_exception"); + if(handler) + caml_callback(handler, [err, false]); + else{ + var + msg = caml_format_exception(err), + at_exit = caml_named_value("Pervasives.do_at_exit"); + if(at_exit) caml_callback(at_exit, [0]); + console.error("Fatal error: exception " + msg); + if(err.js_error) throw err.js_error; + } + } + else + throw err; + } + function caml_fill_bytes(s, i, l, c){ + if(l > 0) + if(i == 0 && (l >= s.l || s.t == 2 && l >= s.c.length)) + if(c == 0){ + s.c = ""; + s.t = 2; + } + else{ + s.c = caml_str_repeat(l, String.fromCharCode(c)); + s.t = l == s.l ? 0 : 2; + } + else{ + if(s.t != 4) caml_convert_bytes_to_array(s); + for(l += i; i < l; i++) s.c[i] = c; + } + return 0; + } + function caml_final_register(){return 0;} + var all_finalizers = new globalThis.Set(); + function caml_final_register_called_without_value(cb, a){ + if(globalThis.FinalizationRegistry && a instanceof Object){ + var + x = + new + globalThis.FinalizationRegistry + (function(x){all_finalizers.delete(x); cb(0); return;}); + x.register(a, x); + all_finalizers.add(x); + } + return 0; + } + function caml_final_release(){return 0;} + function caml_finish_formatting(f, rawbuffer){ + if(f.uppercase) rawbuffer = rawbuffer.toUpperCase(); + var len = rawbuffer.length; + if(f.signedconv && (f.sign < 0 || f.signstyle != "-")) len++; + if(f.alternate){if(f.base == 8) len += 1; if(f.base == 16) len += 2;} + var buffer = ""; + if(f.justify == "+" && f.filler == " ") + for(var i = len; i < f.width; i++) buffer += " "; + if(f.signedconv) + if(f.sign < 0) + buffer += "-"; + else if(f.signstyle != "-") buffer += f.signstyle; + if(f.alternate && f.base == 8) buffer += "0"; + if(f.alternate && f.base == 16) buffer += f.uppercase ? "0X" : "0x"; + if(f.justify == "+" && f.filler == "0") + for(var i = len; i < f.width; i++) buffer += "0"; + buffer += rawbuffer; + if(f.justify == "-") for(var i = len; i < f.width; i++) buffer += " "; + return caml_string_of_jsbytes(buffer); + } + function caml_float_compare(x, y){ + if(x === y) return 0; + if(x < y) return - 1; + if(x > y) return 1; + if(x === x) return 1; + if(y === y) return - 1; + return 0; + } + function caml_float_of_bytes(a){ + return caml_int64_float_of_bits(caml_int64_of_bytes(a)); + } + function caml_float_of_string(s){ + var res; + s = caml_jsbytes_of_string(s); + res = + s; + if(s.length > 0 && res === res) return res; + s = s.replace(/_/g, ""); + res = + s; + if(s.length > 0 && res === res || /^[+-]?nan$/i.test(s)) return res; + var m = /^ *([+-]?)0x([0-9a-f]+)\.?([0-9a-f]*)(p([+-]?[0-9]+))?/i.exec(s); + if(m){ + var + m3 = m[3].replace(/0+$/, ""), + mantissa = parseInt(m[1] + m[2] + m3, 16), + exponent = (m[5] | 0) - 4 * m3.length; + res = mantissa * Math.pow(2, exponent); + return res; + } + if(/^\+?inf(inity)?$/i.test(s)) return Infinity; + if(/^-inf(inity)?$/i.test(s)) return - Infinity; + caml_failwith("float_of_string"); + } + function caml_floatarray_blit(a1, i1, a2, i2, len){ + if(i2 <= i1) + for(var j = 1; j <= len; j++) a2[i2 + j] = a1[i1 + j]; + else + for(var j = len; j >= 1; j--) a2[i2 + j] = a1[i1 + j]; + return 0; + } + function caml_floatarray_create(len){ + if(len < 0) caml_array_bound_error(); + var len = len + 1 | 0, b = new Array(len); + b[0] = 254; + for(var i = 1; i < len; i++) b[i] = 0; + return b; + } + function caml_fma_float(x, y, z){ + var + SPLIT = Math.pow(2, 27) + 1, + MIN_VALUE = Math.pow(2, - 1022), + EPSILON = Math.pow(2, - 52), + C = 416, + A = Math.pow(2, + C), + B = Math.pow(2, - C); + function multiply(a, b){ + var + at = SPLIT * a, + ahi = at - (at - a), + alo = a - ahi, + bt = SPLIT * b, + bhi = bt - (bt - b), + blo = b - bhi, + p = a * b, + e = ahi * bhi - p + ahi * blo + alo * bhi + alo * blo; + return {p: p, e: e}; + } + function add(a, b){ + var s = a + b, v = s - a, e = a - (s - v) + (b - v); + return {s: s, e: e}; + } + function adjust(x, y){ + return x !== 0 && y !== 0 && SPLIT * x - (SPLIT * x - x) === x + ? x * (1 + (x < 0 ? - 1 : + 1) * (y < 0 ? - 1 : + 1) * EPSILON) + : x; + } + if + (x === 0 || x !== x || x === + (1 / 0) || x === - (1 / 0) || y === 0 + || y !== y + || y === + (1 / 0) + || y === - (1 / 0)) + return x * y + z; + if(z === 0) return x * y; + if(z !== z || z === + (1 / 0) || z === - (1 / 0)) return z; + var scale = 1; + while(Math.abs(x) > A){scale *= A; x *= B;} + while(Math.abs(y) > A){scale *= A; y *= B;} + if(scale === 1 / 0) return x * y * scale; + while(Math.abs(x) < B){scale *= B; x *= A;} + while(Math.abs(y) < B){scale *= B; y *= A;} + if(scale === 0) return z; + var xs = x, ys = y, zs = z / scale; + if(Math.abs(zs) > Math.abs(xs * ys) * 4 / EPSILON) return z; + if(Math.abs(zs) < Math.abs(xs * ys) * EPSILON / 4 * EPSILON / 4) + zs = (z < 0 ? - 1 : + 1) * MIN_VALUE; + var + xy = multiply(xs, ys), + s = add(xy.p, zs), + u = add(xy.e, s.e), + i = add(s.s, u.s), + f = i.s + adjust(i.e, u.e); + if(f === 0) return f; + var fs = f * scale; + if(Math.abs(fs) > MIN_VALUE) return fs; + return fs + adjust(f - fs / scale, i.e) * scale; + } + function caml_parse_format(fmt){ + fmt = caml_jsbytes_of_string(fmt); + var len = fmt.length; + if(len > 31) caml_invalid_argument("format_int: format too long"); + var + f = + {justify: "+", + signstyle: "-", + filler: " ", + alternate: false, + base: 0, + signedconv: false, + width: 0, + uppercase: false, + sign: 1, + prec: - 1, + conv: "f"}; + for(var i = 0; i < len; i++){ + var c = fmt.charAt(i); + switch(c){ + case "-": + f.justify = "-"; break; + case "+": + case " ": + f.signstyle = c; break; + case "0": + f.filler = "0"; break; + case "#": + f.alternate = true; break; + case "1": + case "2": + case "3": + case "4": + case "5": + case "6": + case "7": + case "8": + case "9": + f.width = 0; + while(c = fmt.charCodeAt(i) - 48, c >= 0 && c <= 9){f.width = f.width * 10 + c; i++;} + i--; + break; + case ".": + f.prec = 0; + i++; + while(c = fmt.charCodeAt(i) - 48, c >= 0 && c <= 9){f.prec = f.prec * 10 + c; i++;} + i--; + case "d": + case "i": + f.signedconv = true; + case "u": + f.base = 10; break; + case "x": + f.base = 16; break; + case "X": + f.base = 16; f.uppercase = true; break; + case "o": + f.base = 8; break; + case "e": + case "f": + case "g": + f.signedconv = true; f.conv = c; break; + case "E": + case "F": + case "G": + f.signedconv = true; + f.uppercase = true; + f.conv = c.toLowerCase(); + break; + } + } + return f; + } + function caml_format_float(fmt, x){ + function toFixed(x, dp){ + if(Math.abs(x) < 1.0) + return x.toFixed(dp); + else{ + var e = parseInt(x.toString().split("+")[1]); + if(e > 20){ + e -= 20; + x /= Math.pow(10, e); + x += new Array(e + 1).join("0"); + if(dp > 0) x = x + "." + new Array(dp + 1).join("0"); + return x; + } + else + return x.toFixed(dp); + } + } + var s, f = caml_parse_format(fmt), prec = f.prec < 0 ? 6 : f.prec; + if(x < 0 || x == 0 && 1 / x == - Infinity){f.sign = - 1; x = - x;} + if(isNaN(x)){ + s = "nan"; + f.filler = " "; + } + else if(! isFinite(x)){ + s = "inf"; + f.filler = " "; + } + else + switch(f.conv){ + case "e": + var s = x.toExponential(prec), i = s.length; + if(s.charAt(i - 3) == "e") + s = s.slice(0, i - 1) + "0" + s.slice(i - 1); + break; + case "f": + s = toFixed(x, prec); break; + case "g": + prec = prec ? prec : 1; + s = x.toExponential(prec - 1); + var j = s.indexOf("e"), exp = + s.slice(j + 1); + if(exp < - 4 || x >= 1e21 || x.toFixed(0).length > prec){ + var i = j - 1; + while(s.charAt(i) == "0") i--; + if(s.charAt(i) == ".") i--; + s = s.slice(0, i + 1) + s.slice(j); + i = s.length; + if(s.charAt(i - 3) == "e") + s = s.slice(0, i - 1) + "0" + s.slice(i - 1); + break; + } + else{ + var p = prec; + if(exp < 0){ + p -= exp + 1; + s = x.toFixed(p); + } + else + while(s = x.toFixed(p), s.length > prec + 1) p--; + if(p){ + var i = s.length - 1; + while(s.charAt(i) == "0") i--; + if(s.charAt(i) == ".") i--; + s = s.slice(0, i + 1); + } + } + break; + } + return caml_finish_formatting(f, s); + } + function caml_format_int(fmt, i){ + if(caml_jsbytes_of_string(fmt) == "%d") + return caml_string_of_jsbytes("" + i); + var f = caml_parse_format(fmt); + if(i < 0) if(f.signedconv){f.sign = - 1; i = - i;} else i >>>= 0; + var s = i.toString(f.base); + if(f.prec >= 0){ + f.filler = " "; + var n = f.prec - s.length; + if(n > 0) s = caml_str_repeat(n, "0") + s; + } + return caml_finish_formatting(f, s); + } + var caml_oo_last_id = 0; + function caml_fresh_oo_id(){return caml_oo_last_id++;} + function caml_frexp_float(x){ + if(x == 0 || ! isFinite(x)) return [0, x, 0]; + var neg = x < 0; + if(neg) x = - x; + var exp = Math.max(- 1023, jsoo_floor_log2(x) + 1); + x *= Math.pow(2, - exp); + while(x < 0.5){x *= 2; exp--;} + while(x >= 1){x *= 0.5; exp++;} + if(neg) x = - x; + return [0, x, exp]; + } + function jsoo_create_file(name, content){ + var + name = caml_string_of_jsbytes(name), + content = caml_string_of_jsbytes(content); + return caml_create_file(name, content); + } + function caml_fs_init(){ + var tmp = globalThis.caml_fs_tmp; + if(tmp) + for(var i = 0; i < tmp.length; i++) + jsoo_create_file(tmp[i].name, tmp[i].content); + globalThis.jsoo_create_file = jsoo_create_file; + globalThis.caml_fs_tmp = []; + return 0; + } + function caml_gc_compaction(){return 0;} + function caml_gc_counters(){return [254, 0, 0, 0];} + function caml_gc_full_major(unit){ + if(typeof globalThis.gc == "function") globalThis.gc(); + return 0; + } + function caml_gc_get(){return [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];} + function caml_gc_huge_fallback_count(unit){return 0;} + function caml_gc_major(unit){ + if(typeof globalThis.gc == "function") globalThis.gc(); + return 0; + } + function caml_gc_major_slice(work){return 0;} + function caml_gc_minor(unit){ + if(typeof globalThis.gc == "function") globalThis.gc(true); + return 0; + } + function caml_gc_minor_words(unit){return 0;} + function caml_gc_quick_stat(){ + return [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + } + function caml_gc_set(_control){return 0;} + function caml_gc_stat(){return caml_gc_quick_stat();} + function caml_get_continuation_callstack(){return [0];} + function caml_get_current_callstack(){return [0];} + function caml_get_exception_backtrace(){return 0;} + function caml_get_exception_raw_backtrace(){return [0];} + function caml_get_global_data(){return caml_global_data;} + function caml_get_major_bucket(n){return 0;} + function caml_get_major_credit(n){return 0;} + function caml_get_minor_free(unit){return 0;} + var caml_method_cache = []; + function caml_get_public_method(obj, tag, cacheid){ + var meths = obj[1], ofs = caml_method_cache[cacheid]; + if(ofs === undefined) + for(var i = caml_method_cache.length; i < cacheid; i++) + caml_method_cache[i] = 0; + else if(meths[ofs] === tag) return meths[ofs - 1]; + var li = 3, hi = meths[1] * 2 + 1, mi; + while(li < hi){ + mi = li + hi >> 1 | 1; + if(tag < meths[mi + 1]) hi = mi - 2; else li = mi; + } + caml_method_cache[cacheid] = li + 1; + return tag == meths[li + 1] ? meths[li] : 0; + } + function caml_gr_arc_aux(ctx, cx, cy, ry, rx, a1, a2){ + while(a1 > a2) a2 += 360; + a1 /= 180; + a2 /= 180; + var + rot = 0, + xPos, + yPos, + xPos_prev, + yPos_prev, + space = 2, + num = (a2 - a1) * Math.PI * ((rx + ry) / 2) / space | 0, + delta = (a2 - a1) * Math.PI / num, + i = a1 * Math.PI; + for(var j = 0; j <= num; j++){ + xPos = + cx - rx * Math.sin(i) * Math.sin(rot * Math.PI) + + ry * Math.cos(i) * Math.cos(rot * Math.PI); + xPos = xPos.toFixed(2); + yPos = + cy + ry * Math.cos(i) * Math.sin(rot * Math.PI) + + rx * Math.sin(i) * Math.cos(rot * Math.PI); + yPos = yPos.toFixed(2); + if(j == 0) + ctx.moveTo(xPos, yPos); + else if(xPos_prev != xPos || yPos_prev != yPos) ctx.lineTo(xPos, yPos); + xPos_prev = xPos; + yPos_prev = yPos; + i -= delta; + } + return 0; + } + var caml_gr_state; + function caml_gr_state_get(){ + if(caml_gr_state) return caml_gr_state; + throw caml_maybe_attach_backtrace + ([0, + caml_named_value("Graphics.Graphic_failure"), + caml_string_of_jsbytes("Not initialized")]); + } + function caml_gr_blit_image(im, x, y){ + var + s = caml_gr_state_get(), + im2 = + s.context.getImageData + (x, s.height - im.height - y, im.width, im.height); + for(var i = 0; i < im2.data.length; i += 4){ + im.data[i] = im2.data[i]; + im.data[i + 1] = im2.data[i + 1]; + im.data[i + 2] = im2.data[i + 2]; + im.data[i + 3] = im2.data[i + 3]; + } + return 0; + } + function caml_gr_clear_graph(){ + var s = caml_gr_state_get(); + s.canvas.width = s.width; + s.canvas.height = s.height; + return 0; + } + function caml_gr_close_graph(){ + var s = caml_gr_state_get(); + s.canvas.width = 0; + s.canvas.height = 0; + return 0; + } + function caml_gr_close_subwindow(a){ + caml_failwith("caml_gr_close_subwindow not Implemented"); + } + function caml_gr_create_image(x, y){ + var s = caml_gr_state_get(); + return s.context.createImageData(x, y); + } + function caml_gr_current_x(){var s = caml_gr_state_get(); return s.x;} + function caml_gr_current_y(){var s = caml_gr_state_get(); return s.y;} + function caml_gr_display_mode(){ + caml_failwith("caml_gr_display_mode not Implemented"); + } + function caml_gr_doc_of_state(state){ + if(state.canvas.ownerDocument) return state.canvas.ownerDocument; + } + function caml_gr_draw_arc(x, y, rx, ry, a1, a2){ + var s = caml_gr_state_get(); + s.context.beginPath(); + caml_gr_arc_aux(s.context, x, s.height - y, rx, ry, a1, a2); + s.context.stroke(); + return 0; + } + function caml_gr_draw_str(str){ + var s = caml_gr_state_get(), m = s.context.measureText(str), dx = m.width; + s.context.fillText(str, s.x, s.height - s.y); + s.x += dx | 0; + return 0; + } + function caml_gr_draw_char(c){ + caml_gr_draw_str(String.fromCharCode(c)); + return 0; + } + function caml_gr_draw_image(im, x, y){ + var s = caml_gr_state_get(); + if(! im.image){ + var canvas = document.createElement("canvas"); + canvas.width = s.width; + canvas.height = s.height; + canvas.getContext("2d").putImageData(im, 0, 0); + var image = new globalThis.Image(); + image.onload = + function(){ + s.context.drawImage(image, x, s.height - im.height - y); + im.image = image; + }; + image.src = canvas.toDataURL("image/png"); + } + else + s.context.drawImage(im.image, x, s.height - im.height - y); + return 0; + } + function caml_gr_draw_rect(x, y, w, h){ + var s = caml_gr_state_get(); + s.context.strokeRect(x, s.height - y, w, - h); + return 0; + } + function caml_gr_draw_string(str){ + caml_gr_draw_str(caml_jsstring_of_string(str)); + return 0; + } + function caml_gr_dump_image(im){ + var data = [0]; + for(var i = 0; i < im.height; i++){ + data[i + 1] = [0]; + for(var j = 0; j < im.width; j++){ + var + o = i * (im.width * 4) + j * 4, + r = im.data[o + 0], + g = im.data[o + 1], + b = im.data[o + 2]; + data[i + 1][j + 1] = (r << 16) + (g << 8) + b; + } + } + return data; + } + function caml_gr_fill_arc(x, y, rx, ry, a1, a2){ + var s = caml_gr_state_get(); + s.context.beginPath(); + caml_gr_arc_aux(s.context, x, s.height - y, rx, ry, a1, a2); + s.context.fill(); + return 0; + } + function caml_gr_fill_poly(ar){ + var s = caml_gr_state_get(); + s.context.beginPath(); + s.context.moveTo(ar[1][1], s.height - ar[1][2]); + for(var i = 2; i < ar.length; i++) + s.context.lineTo(ar[i][1], s.height - ar[i][2]); + s.context.lineTo(ar[1][1], s.height - ar[1][2]); + s.context.fill(); + return 0; + } + function caml_gr_fill_rect(x, y, w, h){ + var s = caml_gr_state_get(); + s.context.fillRect(x, s.height - y, w, - h); + return 0; + } + function caml_gr_lineto(x, y){ + var s = caml_gr_state_get(); + s.context.beginPath(); + s.context.moveTo(s.x, s.height - s.y); + s.context.lineTo(x, s.height - y); + s.context.stroke(); + s.x = x; + s.y = y; + return 0; + } + function caml_gr_make_image(arr){ + var + s = caml_gr_state_get(), + h = arr.length - 1, + w = arr[1].length - 1, + im = s.context.createImageData(w, h); + for(var i = 0; i < h; i++) + for(var j = 0; j < w; j++){ + var c = arr[i + 1][j + 1], o = i * (w * 4) + j * 4; + if(c == - 1){ + im.data[o + 0] = 0; + im.data[o + 1] = 0; + im.data[o + 2] = 0; + im.data[o + 3] = 0; + } + else{ + im.data[o + 0] = c >> 16 & 0xff; + im.data[o + 1] = c >> 8 & 0xff; + im.data[o + 2] = c >> 0 & 0Xff; + im.data[o + 3] = 0xff; + } + } + return im; + } + function caml_gr_moveto(x, y){ + var s = caml_gr_state_get(); + s.x = x; + s.y = y; + return 0; + } + function caml_gr_set_window_title(name){ + var s = caml_gr_state_get(); + s.title = name; + var jsname = caml_jsstring_of_string(name); + if(s.set_title) s.set_title(jsname); + return 0; + } + function caml_gr_set_line_width(w){ + var s = caml_gr_state_get(); + s.line_width = w; + s.context.lineWidth = w; + return 0; + } + function caml_gr_set_text_size(size){ + var s = caml_gr_state_get(); + s.text_size = size; + s.context.font = s.text_size + "px " + caml_jsstring_of_string(s.font); + return 0; + } + function caml_gr_set_font(f){ + var s = caml_gr_state_get(); + s.font = f; + s.context.font = s.text_size + "px " + caml_jsstring_of_string(s.font); + return 0; + } + function caml_gr_set_color(color){ + var s = caml_gr_state_get(); + function convert(number){ + var str = "" + number.toString(16); + while(str.length < 2) str = "0" + str; + return str; + } + var r = color >> 16 & 0xff, g = color >> 8 & 0xff, b = color >> 0 & 0xff; + s.color = color; + var c_str = "#" + convert(r) + convert(g) + convert(b); + s.context.fillStyle = c_str; + s.context.strokeStyle = c_str; + return 0; + } + function caml_gr_resize_window(w, h){ + var s = caml_gr_state_get(); + s.width = w; + s.height = h; + s.canvas.width = w; + s.canvas.height = h; + return 0; + } + function caml_gr_state_init(){ + caml_gr_moveto(caml_gr_state.x, caml_gr_state.y); + caml_gr_resize_window(caml_gr_state.width, caml_gr_state.height); + caml_gr_set_line_width(caml_gr_state.line_width); + caml_gr_set_text_size(caml_gr_state.text_size); + caml_gr_set_font(caml_gr_state.font); + caml_gr_set_color(caml_gr_state.color); + caml_gr_set_window_title(caml_gr_state.title); + caml_gr_state.context.textBaseline = "bottom"; + } + function caml_gr_state_set(ctx){ + caml_gr_state = ctx; + caml_gr_state_init(); + return 0; + } + function caml_gr_state_create(canvas, w, h){ + var context = canvas.getContext("2d"); + return {context: context, + canvas: canvas, + x: 0, + y: 0, + width: w, + height: h, + line_width: 1, + font: caml_string_of_jsbytes("fixed"), + text_size: 26, + color: 0x000000, + title: caml_string_of_jsbytes("")}; + } + function caml_gr_open_graph(info){ + var info = caml_jsstring_of_string(info); + function get(name){ + var res = info.match("(^|,) *" + name + " *= *([a-zA-Z0-9_]+) *(,|$)"); + if(res) return res[2]; + } + var specs = []; + if(! (info == "")) specs.push(info); + var target = get("target"); + if(! target) target = ""; + var status = get("status"); + if(! status) specs.push("status=1"); + var w = get("width"); + w = w ? parseInt(w) : 200; + specs.push("width=" + w); + var h = get("height"); + h = h ? parseInt(h) : 200; + specs.push("height=" + h); + var win = globalThis.open("about:blank", target, specs.join(",")); + if(! win) caml_failwith("Graphics.open_graph: cannot open the window"); + var doc = win.document, canvas = doc.createElement("canvas"); + canvas.width = w; + canvas.height = h; + var ctx = caml_gr_state_create(canvas, w, h); + ctx.set_title = function(title){doc.title = title;}; + caml_gr_state_set(ctx); + var body = doc.body; + body.style.margin = "0px"; + body.appendChild(canvas); + return 0; + } + function caml_gr_open_subwindow(a, b, c, d){ + caml_failwith("caml_gr_open_subwindow not Implemented"); + } + function caml_gr_plot(x, y){ + var + s = caml_gr_state_get(), + im = s.context.createImageData(1, 1), + d = im.data, + color = s.color; + d[0] = color >> 16 & 0xff; + d[1] = color >> 8 & 0xff, d[2] = color >> 0 & 0xff; + d[3] = 0xFF; + s.x = x; + s.y = y; + s.context.putImageData(im, x, s.height - y); + return 0; + } + function caml_gr_point_color(x, y){ + var + s = caml_gr_state_get(), + im = s.context.getImageData(x, s.height - y, 1, 1), + d = im.data; + return (d[0] << 16) + (d[1] << 8) + d[2]; + } + function caml_gr_remember_mode(){ + caml_failwith("caml_gr_remember_mode not Implemented"); + } + function caml_gr_sigio_handler(){return 0;} + function caml_gr_sigio_signal(){return 0;} + function caml_gr_size_x(){var s = caml_gr_state_get(); return s.width;} + function caml_gr_size_y(){var s = caml_gr_state_get(); return s.height;} + function caml_gr_synchronize(){ + caml_failwith("caml_gr_synchronize not Implemented"); + } + function caml_gr_text_size(txt){ + var + s = caml_gr_state_get(), + w = s.context.measureText(caml_jsstring_of_string(txt)).width; + return [0, w, s.text_size]; + } + function caml_gr_wait_event(_evl){ + caml_failwith + ("caml_gr_wait_event not Implemented: use Graphics_js instead"); + } + function caml_gr_window_id(a){ + caml_failwith("caml_gr_window_id not Implemented"); + } + function caml_greaterequal(x, y){ + return + (caml_compare_val(x, y, false) >= 0); + } + function caml_greaterthan(x, y){ + return + (caml_compare_val(x, y, false) > 0); + } + function caml_hash_mix_jsbytes(h, s){ + var len = s.length, i, w; + for(i = 0; i + 4 <= len; i += 4){ + w = + s.charCodeAt(i) | s.charCodeAt(i + 1) << 8 | s.charCodeAt(i + 2) << 16 + | s.charCodeAt(i + 3) << 24; + h = caml_hash_mix_int(h, w); + } + w = 0; + switch(len & 3){ + case 3: + w = s.charCodeAt(i + 2) << 16; + case 2: + w |= s.charCodeAt(i + 1) << 8; + case 1: + w |= s.charCodeAt(i); h = caml_hash_mix_int(h, w); + } + h ^= len; + return h; + } + function caml_hash_mix_string(h, v){ + return caml_hash_mix_jsbytes(h, caml_jsbytes_of_string(v)); + } + function caml_hash_mix_bytes_arr(h, s){ + var len = s.length, i, w; + for(i = 0; i + 4 <= len; i += 4){ + w = s[i] | s[i + 1] << 8 | s[i + 2] << 16 | s[i + 3] << 24; + h = caml_hash_mix_int(h, w); + } + w = 0; + switch(len & 3){ + case 3: + w = s[i + 2] << 16; + case 2: + w |= s[i + 1] << 8; + case 1: + w |= s[i]; h = caml_hash_mix_int(h, w); + } + h ^= len; + return h; + } + function caml_ml_bytes_content(s){ + switch(s.t & 6){ + default: caml_convert_string_to_bytes(s); + case 0: + return s.c; + case 4: + return s.c; + } + } + function caml_hash_mix_bytes(h, v){ + var content = caml_ml_bytes_content(v); + return typeof content === "string" + ? caml_hash_mix_jsbytes(h, content) + : caml_hash_mix_bytes_arr(h, content); + } + function caml_hash_mix_final(h){ + h ^= h >>> 16; + h = caml_mul(h, 0x85ebca6b | 0); + h ^= h >>> 13; + h = caml_mul(h, 0xc2b2ae35 | 0); + h ^= h >>> 16; + return h; + } + function caml_hash(count, limit, seed, obj){ + var queue, rd, wr, sz, num, h, v, i, len; + sz = limit; + if(sz < 0 || sz > 256) sz = 256; + num = count; + h = seed; + queue = [obj]; + rd = 0; + wr = 1; + while(rd < wr && num > 0){ + v = queue[rd++]; + if(v && v.caml_custom){ + if + (caml_custom_ops[v.caml_custom] && caml_custom_ops[v.caml_custom].hash){ + var hh = caml_custom_ops[v.caml_custom].hash(v); + h = caml_hash_mix_int(h, hh); + num--; + } + } + else if(v instanceof Array && v[0] === (v[0] | 0)) + switch(v[0]){ + case 248: + h = caml_hash_mix_int(h, v[2]); num--; break; + case 250: + queue[--rd] = v[1]; break; + default: + if(caml_is_continuation_tag(v[0])) break; + var tag = v.length - 1 << 10 | v[0]; + h = caml_hash_mix_int(h, tag); + for(i = 1, len = v.length; i < len; i++){if(wr >= sz) break; queue[wr++] = v[i]; + } + break; + } + else if(caml_is_ml_bytes(v)){ + h = caml_hash_mix_bytes(h, v); + num--; + } + else if(caml_is_ml_string(v)){ + h = caml_hash_mix_string(h, v); + num--; + } + else if(typeof v === "string"){ + h = caml_hash_mix_jsbytes(h, v); + num--; + } + else if(v === (v | 0)){ + h = caml_hash_mix_int(h, v + v + 1); + num--; + } + else if(typeof v === "number"){h = caml_hash_mix_float(h, v); num--;} + } + h = caml_hash_mix_final(h); + return h & 0x3FFFFFFF; + } + function caml_hash_mix_bigstring(h, bs){ + return caml_hash_mix_bytes_arr(h, bs.data); + } + function num_digits_nat(nat, ofs, len){ + for(var i = len - 1; i >= 0; i--) if(nat.data[ofs + i] != 0) return i + 1; + return 1; + } + function caml_hash_nat(x){ + var len = num_digits_nat(x, 0, x.data.length), h = 0; + for(var i = 0; i < len; i++) h = caml_hash_mix_int(h, x.data[i]); + return h; + } + function caml_hexstring_of_float(x, prec, style){ + if(! isFinite(x)){ + if(isNaN(x)) return caml_string_of_jsstring("nan"); + return caml_string_of_jsstring(x > 0 ? "infinity" : "-infinity"); + } + var sign = x == 0 && 1 / x == - Infinity ? 1 : x >= 0 ? 0 : 1; + if(sign) x = - x; + var exp = 0; + if(x == 0) + ; + else if(x < 1) + while(x < 1 && exp > - 1022){x *= 2; exp--;} + else + while(x >= 2){x /= 2; exp++;} + var exp_sign = exp < 0 ? "" : "+", sign_str = ""; + if(sign) + sign_str = "-"; + else + switch(style){ + case 43: + sign_str = "+"; break; + case 32: + sign_str = " "; break; + default: break; + } + if(prec >= 0 && prec < 13){ + var cst = Math.pow(2, prec * 4); + x = Math.round(x * cst) / cst; + } + var x_str = x.toString(16); + if(prec >= 0){ + var idx = x_str.indexOf("."); + if(idx < 0) + x_str += "." + caml_str_repeat(prec, "0"); + else{ + var size = idx + 1 + prec; + if(x_str.length < size) + x_str += caml_str_repeat(size - x_str.length, "0"); + else + x_str = x_str.substr(0, size); + } + } + return caml_string_of_jsstring + (sign_str + "0x" + x_str + "p" + exp_sign + exp.toString(10)); + } + function caml_hypot_float(x, y){return Math.hypot(x, y);} + var caml_marshal_header_size = 20; + function caml_refill(chan){ + if(chan.refill != null){ + var str = chan.refill(), str_a = caml_uint8_array_of_string(str); + if(str_a.length == 0) + chan.refill = null; + else{ + if(chan.buffer.length < chan.buffer_max + str_a.length){ + var b = new Uint8Array(chan.buffer_max + str_a.length); + b.set(chan.buffer); + chan.buffer = b; + } + chan.buffer.set(str_a, chan.buffer_max); + chan.offset += str_a.length; + chan.buffer_max += str_a.length; + } + } + else{ + var + nread = + chan.file.read + (chan.offset, + chan.buffer, + chan.buffer_max, + chan.buffer.length - chan.buffer_max); + chan.offset += nread; + chan.buffer_max += nread; + } + } + function caml_raise_end_of_file(){ + caml_raise_constant(caml_global_data.End_of_file); + } + function caml_marshal_data_size(s, ofs){ + var r = new UInt8ArrayReader(caml_uint8_array_of_bytes(s), ofs); + function readvlq(overflow){ + var c = r.read8u(), n = c & 0x7F; + while((c & 0x80) != 0){ + c = r.read8u(); + var n7 = n << 7; + if(n != n7 >> 7) overflow[0] = true; + n = n7 | c & 0x7F; + } + return n; + } + switch(r.read32u()){ + case 0x8495A6BE: + var header_len = 20, data_len = r.read32u(); break; + case 0x8495A6BD: + var + header_len = r.read8u() & 0x3F, + overflow = [false], + data_len = readvlq(overflow); + if(overflow[0]) + caml_failwith + ("Marshal.data_size: object too large to be read back on this platform"); + break; + case 0x8495A6BF: + default: caml_failwith("Marshal.data_size: bad object"); break; + } + return header_len - caml_marshal_header_size + data_len; + } + function caml_input_value_from_reader(reader, ofs){ + function readvlq(overflow){ + var c = reader.read8u(), n = c & 0x7F; + while((c & 0x80) != 0){ + c = reader.read8u(); + var n7 = n << 7; + if(n != n7 >> 7) overflow[0] = true; + n = n7 | c & 0x7F; + } + return n; + } + var magic = reader.read32u(); + switch(magic){ + case 0x8495A6BE: + var + header_len = 20, + compressed = 0, + data_len = reader.read32u(), + uncompressed_data_len = data_len, + num_objects = reader.read32u(), + _size_32 = reader.read32u(), + _size_64 = reader.read32u(); + break; + case 0x8495A6BD: + var + header_len = reader.read8u() & 0x3F, + compressed = 1, + overflow = [false], + data_len = readvlq(overflow), + uncompressed_data_len = readvlq(overflow), + num_objects = readvlq(overflow), + _size_32 = readvlq(overflow), + _size_64 = readvlq(overflow); + if(overflow[0]) + caml_failwith + ("caml_input_value_from_reader: object too large to be read back on this platform"); + break; + case 0x8495A6BF: + caml_failwith + ("caml_input_value_from_reader: object too large to be read back on a 32-bit platform"); + break; + default: + caml_failwith("caml_input_value_from_reader: bad object"); break; + } + var + stack = [], + intern_obj_table = num_objects > 0 ? [] : null, + obj_counter = 0; + function intern_rec(reader){ + var code = reader.read8u(); + if(code >= 0x40) + if(code >= 0x80){ + var tag = code & 0xF, size = code >> 4 & 0x7, v = [tag]; + if(size == 0) return v; + if(intern_obj_table) intern_obj_table[obj_counter++] = v; + stack.push(v, size); + return v; + } + else + return code & 0x3F; + else if(code >= 0x20){ + var len = code & 0x1F, v = reader.readstr(len); + if(intern_obj_table) intern_obj_table[obj_counter++] = v; + return v; + } + else + switch(code){ + case 0x00: + return reader.read8s(); + case 0x01: + return reader.read16s(); + case 0x02: + return reader.read32s(); + case 0x03: + caml_failwith("input_value: integer too large"); break; + case 0x04: + var offset = reader.read8u(); + if(compressed == 0) offset = obj_counter - offset; + return intern_obj_table[offset]; + case 0x05: + var offset = reader.read16u(); + if(compressed == 0) offset = obj_counter - offset; + return intern_obj_table[offset]; + case 0x06: + var offset = reader.read32u(); + if(compressed == 0) offset = obj_counter - offset; + return intern_obj_table[offset]; + case 0x08: + var + header = reader.read32u(), + tag = header & 0xFF, + size = header >> 10, + v = [tag]; + if(size == 0) return v; + if(intern_obj_table) intern_obj_table[obj_counter++] = v; + stack.push(v, size); + return v; + case 0x13: + caml_failwith("input_value: data block too large"); break; + case 0x09: + var len = reader.read8u(), v = reader.readstr(len); + if(intern_obj_table) intern_obj_table[obj_counter++] = v; + return v; + case 0x0A: + var len = reader.read32u(), v = reader.readstr(len); + if(intern_obj_table) intern_obj_table[obj_counter++] = v; + return v; + case 0x0C: + var t = new Array(8); + for(var i = 0; i < 8; i++) t[7 - i] = reader.read8u(); + var v = caml_float_of_bytes(t); + if(intern_obj_table) intern_obj_table[obj_counter++] = v; + return v; + case 0x0B: + var t = new Array(8); + for(var i = 0; i < 8; i++) t[i] = reader.read8u(); + var v = caml_float_of_bytes(t); + if(intern_obj_table) intern_obj_table[obj_counter++] = v; + return v; + case 0x0E: + var len = reader.read8u(), v = new Array(len + 1); + v[0] = 254; + var t = new Array(8); + if(intern_obj_table) intern_obj_table[obj_counter++] = v; + for(var i = 1; i <= len; i++){ + for(var j = 0; j < 8; j++) t[7 - j] = reader.read8u(); + v[i] = caml_float_of_bytes(t); + } + return v; + case 0x0D: + var len = reader.read8u(), v = new Array(len + 1); + v[0] = 254; + var t = new Array(8); + if(intern_obj_table) intern_obj_table[obj_counter++] = v; + for(var i = 1; i <= len; i++){ + for(var j = 0; j < 8; j++) t[j] = reader.read8u(); + v[i] = caml_float_of_bytes(t); + } + return v; + case 0x07: + var len = reader.read32u(), v = new Array(len + 1); + v[0] = 254; + if(intern_obj_table) intern_obj_table[obj_counter++] = v; + var t = new Array(8); + for(var i = 1; i <= len; i++){ + for(var j = 0; j < 8; j++) t[7 - j] = reader.read8u(); + v[i] = caml_float_of_bytes(t); + } + return v; + case 0x0F: + var len = reader.read32u(), v = new Array(len + 1); + v[0] = 254; + var t = new Array(8); + for(var i = 1; i <= len; i++){ + for(var j = 0; j < 8; j++) t[j] = reader.read8u(); + v[i] = caml_float_of_bytes(t); + } + return v; + case 0x10: + case 0x11: + caml_failwith("input_value: code pointer"); break; + case 0x12: + case 0x18: + case 0x19: + var c, s = ""; + while((c = reader.read8u()) != 0) s += String.fromCharCode(c); + var ops = caml_custom_ops[s], expected_size; + if(! ops) + caml_failwith("input_value: unknown custom block identifier"); + switch(code){ + case 0x12: break; + case 0x19: + if(! ops.fixed_length) + caml_failwith("input_value: expected a fixed-size custom block"); + expected_size = ops.fixed_length; + break; + case 0x18: + expected_size = reader.read32u(); + reader.read32s(); + reader.read32s(); + break; + } + var + old_pos = reader.i, + size = [0], + v = ops.deserialize(reader, size); + if(expected_size != undefined) + if(expected_size != size[0]) + caml_failwith + ("input_value: incorrect length of serialized custom block"); + if(intern_obj_table) intern_obj_table[obj_counter++] = v; + return v; + default: caml_failwith("input_value: ill-formed message"); + } + } + if(compressed) + if(caml_decompress_input) + var + data = reader.readuint8array(data_len), + res = new Uint8Array(uncompressed_data_len), + res = caml_decompress_input(data, res), + reader = new UInt8ArrayReader(res, 0); + else + caml_failwith("input_value: compressed object, cannot decompress"); + var res = intern_rec(reader); + while(stack.length > 0){ + var size = stack.pop(), v = stack.pop(), d = v.length; + if(d < size) stack.push(v, size); + v[d] = intern_rec(reader); + } + if(typeof ofs != "number") ofs[0] = reader.i; + return res; + } + function caml_string_of_bytes(s){ + s.t & 6 && caml_convert_string_to_bytes(s); + return caml_string_of_jsbytes(s.c); + } + function caml_input_value_from_bytes(s, ofs){ + var + reader = + new + MlStringReader + (caml_string_of_bytes(s), typeof ofs == "number" ? ofs : ofs[0]); + return caml_input_value_from_reader(reader, ofs); + } + function caml_input_value(chanid){ + var + chan = caml_ml_channel_get(chanid), + header = new Uint8Array(caml_marshal_header_size); + function block(buffer, offset, n){ + var r = 0; + while(r < n){ + if(chan.buffer_curr >= chan.buffer_max){ + chan.buffer_curr = 0; + chan.buffer_max = 0; + caml_refill(chan); + } + if(chan.buffer_curr >= chan.buffer_max) break; + buffer[offset + r] = chan.buffer[chan.buffer_curr]; + chan.buffer_curr++; + r++; + } + return r; + } + var r = block(header, 0, caml_marshal_header_size); + if(r == 0) + caml_raise_end_of_file(); + else if(r < caml_marshal_header_size) + caml_failwith("input_value: truncated object"); + var + len = caml_marshal_data_size(caml_bytes_of_array(header), 0), + buf = new Uint8Array(len + caml_marshal_header_size); + buf.set(header, 0); + var r = block(buf, caml_marshal_header_size, len); + if(r < len) + caml_failwith("input_value: truncated object " + r + " " + len); + var + offset = [0], + res = caml_input_value_from_bytes(caml_bytes_of_array(buf), offset); + chan.offset = chan.offset + offset[0]; + return res; + } + function caml_input_value_from_string(s, ofs){ + var reader = new MlStringReader(s, typeof ofs == "number" ? ofs : ofs[0]); + return caml_input_value_from_reader(reader, ofs); + } + function caml_input_value_to_outside_heap(c){return caml_input_value(c);} + function caml_install_signal_handler(){return 0;} + function caml_int32_bswap(x){ + return (x & 0x000000FF) << 24 | (x & 0x0000FF00) << 8 + | (x & 0x00FF0000) >>> 8 + | (x & 0xFF000000) >>> 24; + } + function caml_int64_add(x, y){return x.add(y);} + function caml_int64_and(x, y){return x.and(y);} + function caml_int64_bswap(x){ + var y = caml_int64_to_bytes(x); + return caml_int64_of_bytes + ([y[7], y[6], y[5], y[4], y[3], y[2], y[1], y[0]]); + } + function caml_int64_div(x, y){return x.div(y);} + function caml_int64_is_zero(x){return + x.isZero();} + function caml_int64_of_int32(x){ + return new MlInt64(x & 0xffffff, x >> 24 & 0xffffff, x >> 31 & 0xffff); + } + function caml_int64_to_int32(x){return x.toInt();} + function caml_int64_is_negative(x){return + x.isNeg();} + function caml_int64_neg(x){return x.neg();} + function caml_int64_format(fmt, x){ + var f = caml_parse_format(fmt); + if(f.signedconv && caml_int64_is_negative(x)){f.sign = - 1; x = caml_int64_neg(x);} + var + buffer = "", + wbase = caml_int64_of_int32(f.base), + cvtbl = "0123456789abcdef"; + do{ + var p = x.udivmod(wbase); + x = p.quotient; + buffer = cvtbl.charAt(caml_int64_to_int32(p.modulus)) + buffer; + } + while + (! caml_int64_is_zero(x)); + if(f.prec >= 0){ + f.filler = " "; + var n = f.prec - buffer.length; + if(n > 0) buffer = caml_str_repeat(n, "0") + buffer; + } + return caml_finish_formatting(f, buffer); + } + function caml_int64_mod(x, y){return x.mod(y);} + function caml_int64_mul(x, y){return x.mul(y);} + function caml_int64_of_float(x){ + if(x < 0) x = Math.ceil(x); + return new + MlInt64 + (x & 0xffffff, + Math.floor(x * caml_int64_offset) & 0xffffff, + Math.floor(x * caml_int64_offset * caml_int64_offset) & 0xffff); + } + function caml_int64_ult(x, y){return x.ucompare(y) < 0;} + function caml_parse_sign_and_base(s){ + var i = 0, len = caml_ml_string_length(s), base = 10, sign = 1; + if(len > 0) + switch(caml_string_unsafe_get(s, i)){ + case 45: + i++; sign = - 1; break; + case 43: + i++; sign = 1; break; + } + if(i + 1 < len && caml_string_unsafe_get(s, i) == 48) + switch(caml_string_unsafe_get(s, i + 1)){ + case 120: + case 88: + base = 16; i += 2; break; + case 111: + case 79: + base = 8; i += 2; break; + case 98: + case 66: + base = 2; i += 2; break; + case 117: + case 85: + i += 2; break; + } + return [i, sign, base]; + } + function caml_parse_digit(c){ + if(c >= 48 && c <= 57) return c - 48; + if(c >= 65 && c <= 90) return c - 55; + if(c >= 97 && c <= 122) return c - 87; + return - 1; + } + function caml_int64_of_string(s){ + var + r = caml_parse_sign_and_base(s), + i = r[0], + sign = r[1], + base = r[2], + base64 = caml_int64_of_int32(base), + threshold = + new MlInt64(0xffffff, 0xfffffff, 0xffff).udivmod(base64).quotient, + c = caml_string_unsafe_get(s, i), + d = caml_parse_digit(c); + if(d < 0 || d >= base) caml_failwith("int_of_string"); + var res = caml_int64_of_int32(d); + for(;;){ + i++; + c = caml_string_unsafe_get(s, i); + if(c == 95) continue; + d = caml_parse_digit(c); + if(d < 0 || d >= base) break; + if(caml_int64_ult(threshold, res)) caml_failwith("int_of_string"); + d = caml_int64_of_int32(d); + res = caml_int64_add(caml_int64_mul(base64, res), d); + if(caml_int64_ult(res, d)) caml_failwith("int_of_string"); + } + if(i != caml_ml_string_length(s)) caml_failwith("int_of_string"); + if(base == 10 && caml_int64_ult(new MlInt64(0, 0, 0x8000), res)) + caml_failwith("int_of_string"); + if(sign < 0) res = caml_int64_neg(res); + return res; + } + function caml_int64_or(x, y){return x.or(y);} + function caml_int64_shift_left(x, s){return x.shift_left(s);} + function caml_int64_shift_right(x, s){return x.shift_right(s);} + function caml_int64_shift_right_unsigned(x, s){return x.shift_right_unsigned(s); + } + function caml_int64_sub(x, y){return x.sub(y);} + function caml_int64_to_float(x){return x.toFloat();} + function caml_int64_xor(x, y){return x.xor(y);} + function caml_int_of_string(s){ + var + r = caml_parse_sign_and_base(s), + i = r[0], + sign = r[1], + base = r[2], + len = caml_ml_string_length(s), + threshold = - 1 >>> 0, + c = i < len ? caml_string_unsafe_get(s, i) : 0, + d = caml_parse_digit(c); + if(d < 0 || d >= base) caml_failwith("int_of_string"); + var res = d; + for(i++; i < len; i++){ + c = caml_string_unsafe_get(s, i); + if(c == 95) continue; + d = caml_parse_digit(c); + if(d < 0 || d >= base) break; + res = base * res + d; + if(res > threshold) caml_failwith("int_of_string"); + } + if(i != len) caml_failwith("int_of_string"); + res = sign * res; + if(base == 10 && (res | 0) != res) caml_failwith("int_of_string"); + return res | 0; + } + function caml_is_js(){return 1;} + function caml_is_printable(c){return + (c > 31 && c < 127);} + function caml_js_call(f, o, args){ + return f.apply(o, caml_js_from_array(args)); + } + function caml_js_delete(o, f){delete o[f]; return 0;} + function caml_js_equals(x, y){return + (x == y);} + function caml_js_error_of_exception(exn){ + if(exn.js_error) return exn.js_error; + return null; + } + function caml_js_error_option_of_exception(exn){ + if(exn.js_error) return [0, exn.js_error]; + return 0; + } + function caml_js_eval_string(s){return eval(caml_jsstring_of_string(s));} + function caml_js_expr(s){ + console.error("caml_js_expr: fallback to runtime evaluation\n"); + return eval(caml_jsstring_of_string(s)); + } + function caml_js_from_bool(x){return ! ! x;} + function caml_js_from_float(x){return x;} + function caml_js_from_string(s){return caml_jsstring_of_string(s);} + function caml_js_fun_call(f, a){ + switch(a.length){ + case 1: + return f(); + case 2: + return f(a[1]); + case 3: + return f(a[1], a[2]); + case 4: + return f(a[1], a[2], a[3]); + case 5: + return f(a[1], a[2], a[3], a[4]); + case 6: + return f(a[1], a[2], a[3], a[4], a[5]); + case 7: + return f(a[1], a[2], a[3], a[4], a[5], a[6]); + case 8: + return f(a[1], a[2], a[3], a[4], a[5], a[6], a[7]); + } + return f.apply(null, caml_js_from_array(a)); + } + function caml_js_function_arity(f){return f.l >= 0 ? f.l : f.l = f.length;} + function caml_js_get(o, f){return o[f];} + function caml_js_get_console(){ + var + c = console, + m = + ["log", + "debug", + "info", + "warn", + "error", + "assert", + "dir", + "dirxml", + "trace", + "group", + "groupCollapsed", + "groupEnd", + "time", + "timeEnd"]; + function f(){} + for(var i = 0; i < m.length; i++) if(! c[m[i]]) c[m[i]] = f; + return c; + } + function caml_js_html_entities(s){ + var entity = /^&#?[0-9a-zA-Z]+;$/; + if(s.match(entity)){ + var str, temp = document.createElement("p"); + temp.innerHTML = s; + str = temp.textContent || temp.innerText; + temp = null; + return str; + } + else + caml_failwith("Invalid entity " + s); + } + var caml_js_regexps = {amp: /&/g, lt: / 0){ + var args = new Array(len); + for(var i = 0; i < len; i++) args[i] = arguments[i]; + } + else + args = [undefined]; + var res = caml_callback(f, args); + return res instanceof Function ? caml_js_wrap_callback(res) : res;}; + } + function caml_js_wrap_callback_arguments(f){ + return function(){ + var len = arguments.length, args = new Array(len); + for(var i = 0; i < len; i++) args[i] = arguments[i]; + return caml_callback(f, [args]);}; + } + function caml_js_wrap_callback_strict(arity, f){ + return function(){ + var + n = arguments.length, + args = new Array(arity), + len = Math.min(arguments.length, arity); + for(var i = 0; i < len; i++) args[i] = arguments[i]; + return caml_callback(f, args);}; + } + function caml_js_wrap_callback_unsafe(f){ + return function(){ + var len = caml_js_function_arity(f), args = new Array(len); + for(var i = 0; i < len; i++) args[i] = arguments[i]; + return caml_callback(f, args);}; + } + function caml_js_wrap_meth_callback(f){ + return function(){ + var len = arguments.length, args = new Array(len + 1); + args[0] = this; + for(var i = 0; i < len; i++) args[i + 1] = arguments[i]; + var res = caml_callback(f, args); + return res instanceof Function ? caml_js_wrap_callback(res) : res;}; + } + function caml_js_wrap_meth_callback_arguments(f){ + return function(){ + var len = arguments.length, args = new Array(len); + for(var i = 0; i < len; i++) args[i] = arguments[i]; + return caml_callback(f, [this, args]);}; + } + function caml_js_wrap_meth_callback_strict(arity, f){ + return function(){ + var args = new Array(arity + 1), len = Math.min(arguments.length, arity); + args[0] = this; + for(var i = 0; i < len; i++) args[i + 1] = arguments[i]; + return caml_callback(f, args);}; + } + function caml_js_wrap_meth_callback_unsafe(f){ + return function(){ + var len = caml_js_function_arity(f) - 1, args = new Array(len + 1); + args[0] = this; + for(var i = 0; i < len; i++) args[i + 1] = arguments[i]; + return caml_callback(f, args);}; + } + function caml_jsoo_flags_effects(unit){return 0;} + function caml_jsoo_flags_use_js_string(unit){return 1;} + function caml_lazy_make_forward(v){return [250, v];} + function caml_obj_tag(x){ + if(x instanceof Array && x[0] == x[0] >>> 0) + return x[0]; + else if(caml_is_ml_bytes(x)) + return 252; + else if(caml_is_ml_string(x)) + return 252; + else if(x instanceof Function || typeof x == "function") + return 247; + else if(x && x.caml_custom) return 255; else return 1000; + } + function caml_lazy_read_result(o){ + return caml_obj_tag(o) == 250 ? o[1] : o; + } + function caml_obj_update_tag(b, o, n){ + if(b[0] == o){b[0] = n; return 1;} + return 0; + } + function caml_lazy_reset_to_lazy(o){ + caml_obj_update_tag(o, 244, 246); + return 0; + } + function caml_lazy_update_to_forcing(o){ + return o instanceof Array && o[0] == o[0] >>> 0 + && caml_obj_update_tag(o, 246, 244) + ? 0 + : 1; + } + function caml_lazy_update_to_forward(o){ + caml_obj_update_tag(o, 244, 250); + return 0; + } + function caml_ldexp_float(x, exp){ + exp |= 0; + if(exp > 1023){ + exp -= 1023; + x *= Math.pow(2, 1023); + if(exp > 1023){exp -= 1023; x *= Math.pow(2, 1023);} + } + if(exp < - 1023){exp += 1023; x *= Math.pow(2, - 1023);} + x *= Math.pow(2, exp); + return x; + } + function caml_lessequal(x, y){ + return + (caml_compare_val(x, y, false) <= 0); + } + function caml_lessthan(x, y){return + (caml_compare_val(x, y, false) < 0);} + function caml_lex_array(s){ + s = caml_jsbytes_of_string(s); + var l = s.length / 2, a = new Array(l); + for(var i = 0; i < l; i++) + a[i] = (s.charCodeAt(2 * i) | s.charCodeAt(2 * i + 1) << 8) << 16 >> 16; + return a; + } + function caml_lex_engine(tbl, start_state, lexbuf){ + var + lex_buffer = 2, + lex_buffer_len = 3, + lex_start_pos = 5, + lex_curr_pos = 6, + lex_last_pos = 7, + lex_last_action = 8, + lex_eof_reached = 9, + lex_base = 1, + lex_backtrk = 2, + lex_default = 3, + lex_trans = 4, + lex_check = 5; + if(! tbl.lex_default){ + tbl.lex_base = caml_lex_array(tbl[lex_base]); + tbl.lex_backtrk = caml_lex_array(tbl[lex_backtrk]); + tbl.lex_check = caml_lex_array(tbl[lex_check]); + tbl.lex_trans = caml_lex_array(tbl[lex_trans]); + tbl.lex_default = caml_lex_array(tbl[lex_default]); + } + var + c, + state = start_state, + buffer = caml_uint8_array_of_bytes(lexbuf[lex_buffer]); + if(state >= 0){ + lexbuf[lex_last_pos] = lexbuf[lex_start_pos] = lexbuf[lex_curr_pos]; + lexbuf[lex_last_action] = - 1; + } + else + state = - state - 1; + for(;;){ + var base = tbl.lex_base[state]; + if(base < 0) return - base - 1; + var backtrk = tbl.lex_backtrk[state]; + if(backtrk >= 0){ + lexbuf[lex_last_pos] = lexbuf[lex_curr_pos]; + lexbuf[lex_last_action] = backtrk; + } + if(lexbuf[lex_curr_pos] >= lexbuf[lex_buffer_len]) + if(lexbuf[lex_eof_reached] == 0) return - state - 1; else c = 256; + else{c = buffer[lexbuf[lex_curr_pos]]; lexbuf[lex_curr_pos]++;} + if(tbl.lex_check[base + c] == state) + state = tbl.lex_trans[base + c]; + else + state = tbl.lex_default[state]; + if(state < 0){ + lexbuf[lex_curr_pos] = lexbuf[lex_last_pos]; + if(lexbuf[lex_last_action] == - 1) + caml_failwith("lexing: empty token"); + else + return lexbuf[lex_last_action]; + } + else if(c == 256) lexbuf[lex_eof_reached] = 0; + } + } + function caml_list_mount_point(){ + var prev = 0; + for(var i = 0; i < jsoo_mount_point.length; i++){ + var old = prev; + prev = [0, caml_string_of_jsbytes(jsoo_mount_point[i].path), old]; + } + return prev; + } + function caml_list_of_js_array(a){ + var l = 0; + for(var i = a.length - 1; i >= 0; i--){var e = a[i]; l = [0, e, l];} + return l; + } + function caml_list_to_js_array(l){ + var a = []; + for(; l !== 0; l = l[2]) a.push(l[1]); + return a; + } + function caml_log10_float(x){return Math.log10(x);} + function caml_log1p_float(x){return Math.log1p(x);} + function caml_log2_float(x){return Math.log2(x);} + function caml_new_string(s){return caml_string_of_jsbytes(s);} + function caml_lxm_next(v){ + function shift_l(x, k){return caml_int64_shift_left(x, k);} + function shift_r(x, k){return caml_int64_shift_right_unsigned(x, k);} + function or(a, b){return caml_int64_or(a, b);} + function xor(a, b){return caml_int64_xor(a, b);} + function add(a, b){return caml_int64_add(a, b);} + function mul(a, b){return caml_int64_mul(a, b);} + function rotl(x, k){return or(shift_l(x, k), shift_r(x, 64 - k));} + function get(a, i){return caml_ba_get_1(a, i);} + function set(a, i, x){return caml_ba_set_1(a, i, x);} + var + M = caml_int64_of_string(caml_new_string("0xd1342543de82ef95")), + daba = caml_int64_of_string(caml_new_string("0xdaba0b6eb09322e3")), + z, + q0, + q1, + st = v, + a = get(st, 0), + s = get(st, 1), + x0 = get(st, 2), + x1 = get(st, 3); + z = add(s, x0); + z = mul(xor(z, shift_r(z, 32)), daba); + z = mul(xor(z, shift_r(z, 32)), daba); + z = xor(z, shift_r(z, 32)); + set(st, 1, add(mul(s, M), a)); + var q0 = x0, q1 = x1; + q1 = xor(q1, q0); + q0 = rotl(q0, 24); + q0 = xor(xor(q0, q1), shift_l(q1, 16)); + q1 = rotl(q1, 37); + set(st, 2, q0); + set(st, 3, q1); + return z; + } + function caml_make_float_vect(len){ + if(len < 0) caml_array_bound_error(); + var len = len + 1 | 0, b = new Array(len); + b[0] = 254; + for(var i = 1; i < len; i++) b[i] = 0; + return b; + } + function caml_make_vect(len, init){ + if(len < 0) caml_array_bound_error(); + var len = len + 1 | 0, b = new Array(len); + b[0] = 0; + for(var i = 1; i < len; i++) b[i] = init; + return b; + } + var + caml_marshal_constants = + {PREFIX_SMALL_BLOCK: 0x80, + PREFIX_SMALL_INT: 0x40, + PREFIX_SMALL_STRING: 0x20, + CODE_INT8: 0x00, + CODE_INT16: 0x01, + CODE_INT32: 0x02, + CODE_INT64: 0x03, + CODE_SHARED8: 0x04, + CODE_SHARED16: 0x05, + CODE_SHARED32: 0x06, + CODE_BLOCK32: 0x08, + CODE_BLOCK64: 0x13, + CODE_STRING8: 0x09, + CODE_STRING32: 0x0A, + CODE_DOUBLE_BIG: 0x0B, + CODE_DOUBLE_LITTLE: 0x0C, + CODE_DOUBLE_ARRAY8_BIG: 0x0D, + CODE_DOUBLE_ARRAY8_LITTLE: 0x0E, + CODE_DOUBLE_ARRAY32_BIG: 0x0F, + CODE_DOUBLE_ARRAY32_LITTLE: 0x07, + CODE_CODEPOINTER: 0x10, + CODE_INFIXPOINTER: 0x11, + CODE_CUSTOM: 0x12, + CODE_CUSTOM_LEN: 0x18, + CODE_CUSTOM_FIXED: 0x19}; + function caml_maybe_print_stats(unit){return 0;} + function caml_md5_bytes(s, ofs, len){ + var ctx = caml_MD5Init(), a = caml_uint8_array_of_bytes(s); + caml_MD5Update(ctx, a.subarray(ofs, ofs + len), len); + return caml_string_of_array(caml_MD5Final(ctx)); + } + function caml_ml_input_block(chanid, ba, i, l){ + var + chan = caml_ml_channel_get(chanid), + n = l, + avail = chan.buffer_max - chan.buffer_curr; + if(l <= avail){ + ba.set(chan.buffer.subarray(chan.buffer_curr, chan.buffer_curr + l), i); + chan.buffer_curr += l; + } + else if(avail > 0){ + ba.set + (chan.buffer.subarray(chan.buffer_curr, chan.buffer_curr + avail), i); + chan.buffer_curr += avail; + n = avail; + } + else{ + chan.buffer_curr = 0; + chan.buffer_max = 0; + caml_refill(chan); + var avail = chan.buffer_max - chan.buffer_curr; + if(n > avail) n = avail; + ba.set(chan.buffer.subarray(chan.buffer_curr, chan.buffer_curr + n), i); + chan.buffer_curr += n; + } + return n | 0; + } + function caml_md5_chan(chanid, toread){ + var ctx = caml_MD5Init(), buffer = new Uint8Array(4096); + if(toread < 0) + while(true){ + var read = caml_ml_input_block(chanid, buffer, 0, buffer.length); + if(read == 0) break; + caml_MD5Update(ctx, buffer.subarray(0, read), read); + } + else + while(toread > 0){ + var + read = + caml_ml_input_block + (chanid, buffer, 0, toread > buffer.length ? buffer.length : toread); + if(read == 0) caml_raise_end_of_file(); + caml_MD5Update(ctx, buffer.subarray(0, read), read); + toread -= read; + } + return caml_string_of_array(caml_MD5Final(ctx)); + } + function caml_md5_string(s, ofs, len){ + return caml_md5_bytes(caml_bytes_of_string(s), ofs, len); + } + function caml_memprof_discard(t){return 0;} + function caml_memprof_set(_control){return 0;} + function caml_memprof_start(rate, stack_size, tracker){return 0;} + function caml_memprof_stop(unit){return 0;} + function caml_ml_channel_redirect(captured, into){ + var + to_restore = caml_ml_channel_get(captured), + new_ = caml_ml_channel_get(into); + caml_ml_channels[captured] = new_; + return to_restore; + } + function caml_ml_channel_restore(captured, to_restore){caml_ml_channels[captured] = to_restore; return 0; + } + function caml_ml_channel_size(chanid){ + var chan = caml_ml_channel_get(chanid); + return chan.file.length(); + } + function caml_ml_channel_size_64(chanid){ + var chan = caml_ml_channel_get(chanid); + return caml_int64_of_float(chan.file.length()); + } + var caml_sys_fds = new Array(3); + function caml_sys_close(fd){ + var file = caml_sys_fds[fd]; + if(file) file.close(); + delete caml_sys_fds[fd]; + return 0; + } + function caml_ml_flush(chanid){ + var chan = caml_ml_channel_get(chanid); + if(! chan.opened) caml_raise_sys_error("Cannot flush a closed channel"); + if(! chan.buffer || chan.buffer_curr == 0) return 0; + if(chan.output) + chan.output(caml_subarray_to_jsbytes(chan.buffer, 0, chan.buffer_curr)); + else + chan.file.write(chan.offset, chan.buffer, 0, chan.buffer_curr); + chan.offset += chan.buffer_curr; + chan.buffer_curr = 0; + return 0; + } + function caml_ml_close_channel(chanid){ + var chan = caml_ml_channel_get(chanid); + if(chan.opened){ + chan.opened = false; + caml_sys_close(chan.fd); + chan.fd = - 1; + chan.buffer = new Uint8Array(0); + chan.buffer_curr = 0; + chan.buffer_max = 0; + } + return 0; + } + function caml_ml_condition_broadcast(t){return 0;} + function caml_ml_condition_new(unit){return {condition: 1};} + function caml_ml_condition_signal(t){return 0;} + function caml_ml_condition_wait(t, mutext){return 0;} + function caml_ml_debug_info_status(){return 0;} + function caml_ml_domain_cpu_relax(unit){return 0;} + function caml_ml_domain_id(unit){return caml_domain_id;} + function caml_ml_domain_set_name(_name){return 0;} + var caml_ml_domain_unique_token_ = [0]; + function caml_ml_domain_unique_token(unit){return caml_ml_domain_unique_token_; + } + var caml_runtime_warnings = 0; + function caml_ml_enable_runtime_warnings(bool){caml_runtime_warnings = bool; return 0; + } + function caml_ml_input(chanid, b, i, l){ + var ba = caml_uint8_array_of_bytes(b); + return caml_ml_input_block(chanid, ba, i, l); + } + function caml_ml_input_bigarray(chanid, b, i, l){ + var ba = caml_ba_to_typed_array(b); + return caml_ml_input_block(chanid, ba, i, l); + } + function caml_ml_input_char(chanid){ + var chan = caml_ml_channel_get(chanid); + if(chan.buffer_curr >= chan.buffer_max){ + chan.buffer_curr = 0; + chan.buffer_max = 0; + caml_refill(chan); + } + if(chan.buffer_curr >= chan.buffer_max) caml_raise_end_of_file(); + var res = chan.buffer[chan.buffer_curr]; + chan.buffer_curr++; + return res; + } + function caml_ml_input_int(chanid){ + var chan = caml_ml_channel_get(chanid), res = 0; + for(var i = 0; i < 4; i++) + res = (res << 8) + caml_ml_input_char(chanid) | 0; + return res | 0; + } + function caml_ml_input_scan_line(chanid){ + var chan = caml_ml_channel_get(chanid), p = chan.buffer_curr; + do + if(p >= chan.buffer_max){ + if(chan.buffer_curr > 0){ + chan.buffer.set(chan.buffer.subarray(chan.buffer_curr), 0); + p -= chan.buffer_curr; + chan.buffer_max -= chan.buffer_curr; + chan.buffer_curr = 0; + } + if(chan.buffer_max >= chan.buffer.length) return - chan.buffer_max | 0; + var prev_max = chan.buffer_max; + caml_refill(chan); + if(prev_max == chan.buffer_max) return - chan.buffer_max | 0; + } + while + (chan.buffer[p++] != 10); + return p - chan.buffer_curr | 0; + } + function caml_ml_is_buffered(chanid){ + return caml_ml_channel_get(chanid).buffered ? 1 : 0; + } + function caml_ml_mutex_lock(t){ + if(t.locked) + caml_failwith("Mutex.lock: mutex already locked. Cannot wait."); + else + t.locked = true; + return 0; + } + function caml_ml_mutex_new(unit){return new MlMutex();} + function caml_ml_mutex_try_lock(t){ + if(! t.locked){t.locked = true; return 1;} + return 0; + } + function caml_sys_open_for_node(fd, flags){ + if(flags.name) + try{ + var fs = require("fs"), fd2 = fs.openSync(flags.name, "rs"); + return new MlNodeFd(fd2, flags); + } + catch(e){} + return new MlNodeFd(fd, flags); + } + function caml_sys_open_internal(file, idx){ + if(idx == undefined) idx = caml_sys_fds.length; + caml_sys_fds[idx] = file; + return idx | 0; + } + function caml_sys_open(name, flags, _perms){ + var f = {}; + while(flags){ + switch(flags[1]){ + case 0: + f.rdonly = 1; break; + case 1: + f.wronly = 1; break; + case 2: + f.append = 1; break; + case 3: + f.create = 1; break; + case 4: + f.truncate = 1; break; + case 5: + f.excl = 1; break; + case 6: + f.binary = 1; break; + case 7: + f.text = 1; break; + case 8: + f.nonblock = 1; break; + } + flags = flags[2]; + } + if(f.rdonly && f.wronly) + caml_raise_sys_error + (caml_jsbytes_of_string(name) + + " : flags Open_rdonly and Open_wronly are not compatible"); + if(f.text && f.binary) + caml_raise_sys_error + (caml_jsbytes_of_string(name) + + " : flags Open_text and Open_binary are not compatible"); + var root = resolve_fs_device(name), file = root.device.open(root.rest, f); + return caml_sys_open_internal(file, undefined); + } + (function(){ + function file(fd, flags){ + return fs_node_supported() + ? caml_sys_open_for_node(fd, flags) + : new MlFakeFd_out(fd, flags); + } + caml_sys_open_internal + (file(0, {rdonly: 1, altname: "/dev/stdin", isCharacterDevice: true}), + 0); + caml_sys_open_internal + (file(1, {buffered: 2, wronly: 1, isCharacterDevice: true}), 1); + caml_sys_open_internal + (file(2, {buffered: 2, wronly: 1, isCharacterDevice: true}), 2); + } + ()); + function caml_ml_open_descriptor_in(fd){ + var file = caml_sys_fds[fd]; + if(file.flags.wronly) caml_raise_sys_error("fd " + fd + " is writeonly"); + var + refill = null, + channel = + {file: file, + offset: file.flags.append ? file.length() : 0, + fd: fd, + opened: true, + out: false, + buffer_curr: 0, + buffer_max: 0, + buffer: new Uint8Array(65536), + refill: refill}; + caml_ml_channels[channel.fd] = channel; + return channel.fd; + } + function caml_ml_open_descriptor_out(fd){ + var file = caml_sys_fds[fd]; + if(file.flags.rdonly) caml_raise_sys_error("fd " + fd + " is readonly"); + var + buffered = file.flags.buffered !== undefined ? file.flags.buffered : 1, + channel = + {file: file, + offset: file.flags.append ? file.length() : 0, + fd: fd, + opened: true, + out: true, + buffer_curr: 0, + buffer: new Uint8Array(65536), + buffered: buffered}; + caml_ml_channels[channel.fd] = channel; + return channel.fd; + } + function caml_ml_out_channels_list(){ + var l = 0; + for(var c = 0; c < caml_ml_channels.length; c++) + if + (caml_ml_channels[c] && caml_ml_channels[c].opened + && caml_ml_channels[c].out) + l = [0, caml_ml_channels[c].fd, l]; + return l; + } + function caml_ml_output_ta(chanid, buffer, offset, len){ + var chan = caml_ml_channel_get(chanid); + if(! chan.opened) + caml_raise_sys_error("Cannot output to a closed channel"); + buffer = buffer.subarray(offset, offset + len); + if(chan.buffer_curr + buffer.length > chan.buffer.length){ + var b = new Uint8Array(chan.buffer_curr + buffer.length); + b.set(chan.buffer); + chan.buffer = b; + } + switch(chan.buffered){ + case 0: + chan.buffer.set(buffer, chan.buffer_curr); + chan.buffer_curr += buffer.length; + caml_ml_flush(chanid); + break; + case 1: + chan.buffer.set(buffer, chan.buffer_curr); + chan.buffer_curr += buffer.length; + if(chan.buffer_curr >= chan.buffer.length) caml_ml_flush(chanid); + break; + case 2: + var id = buffer.lastIndexOf(10); + if(id < 0){ + chan.buffer.set(buffer, chan.buffer_curr); + chan.buffer_curr += buffer.length; + if(chan.buffer_curr >= chan.buffer.length) caml_ml_flush(chanid); + } + else{ + chan.buffer.set(buffer.subarray(0, id + 1), chan.buffer_curr); + chan.buffer_curr += id + 1; + caml_ml_flush(chanid); + chan.buffer.set(buffer.subarray(id + 1), chan.buffer_curr); + chan.buffer_curr += buffer.length - id - 1; + } + break; + } + return 0; + } + function caml_ml_output_bytes(chanid, buffer, offset, len){ + var buffer = caml_uint8_array_of_bytes(buffer); + return caml_ml_output_ta(chanid, buffer, offset, len); + } + function caml_ml_output(chanid, buffer, offset, len){ + return caml_ml_output_bytes + (chanid, caml_bytes_of_string(buffer), offset, len); + } + function caml_ml_output_bigarray(chanid, buffer, offset, len){ + var buffer = caml_ba_to_typed_array(buffer); + return caml_ml_output_ta(chanid, buffer, offset, len); + } + function caml_ml_output_char(chanid, c){ + var s = caml_string_of_jsbytes(String.fromCharCode(c)); + caml_ml_output(chanid, s, 0, 1); + return 0; + } + function caml_ml_output_int(chanid, i){ + var + arr = [i >> 24 & 0xFF, i >> 16 & 0xFF, i >> 8 & 0xFF, i & 0xFF], + s = caml_string_of_array(arr); + caml_ml_output(chanid, s, 0, 4); + return 0; + } + function caml_pos_in(chanid){ + var chan = caml_ml_channel_get(chanid); + return chan.offset - (chan.buffer_max - chan.buffer_curr) | 0; + } + function caml_ml_pos_in(chanid){return caml_pos_in(chanid);} + function caml_ml_pos_in_64(chanid){ + return caml_int64_of_float(caml_pos_in(chanid)); + } + function caml_pos_out(chanid){ + var chan = caml_ml_channel_get(chanid); + return chan.offset + chan.buffer_curr; + } + function caml_ml_pos_out(chanid){return caml_pos_out(chanid);} + function caml_ml_pos_out_64(chanid){ + return caml_int64_of_float(caml_pos_out(chanid)); + } + function caml_ml_runtime_events_pause(){return 0;} + function caml_ml_runtime_events_resume(){return 0;} + function caml_ml_runtime_events_start(){return 0;} + function caml_ml_runtime_warnings_enabled(_unit){return caml_runtime_warnings; + } + function caml_seek_in(chanid, pos){ + var chan = caml_ml_channel_get(chanid); + if(chan.refill != null) caml_raise_sys_error("Illegal seek"); + if + (pos >= chan.offset - chan.buffer_max && pos <= chan.offset + && chan.file.flags.binary) + chan.buffer_curr = chan.buffer_max - (chan.offset - pos); + else{chan.offset = pos; chan.buffer_curr = 0; chan.buffer_max = 0;} + return 0; + } + function caml_ml_seek_in(chanid, pos){return caml_seek_in(chanid, pos);} + function caml_ml_seek_in_64(chanid, pos){ + var pos = caml_int64_to_float(pos); + return caml_seek_in(chanid, pos); + } + function caml_seek_out(chanid, pos){ + caml_ml_flush(chanid); + var chan = caml_ml_channel_get(chanid); + chan.offset = pos; + return 0; + } + function caml_ml_seek_out(chanid, pos){return caml_seek_out(chanid, pos);} + function caml_ml_seek_out_64(chanid, pos){ + var pos = caml_int64_to_float(pos); + return caml_seek_out(chanid, pos); + } + function caml_ml_set_binary_mode(chanid, mode){ + var chan = caml_ml_channel_get(chanid); + chan.file.flags.text = ! mode; + chan.file.flags.binary = mode; + return 0; + } + function caml_ml_set_buffered(chanid, v){ + caml_ml_channel_get(chanid).buffered = v; + if(! v) caml_ml_flush(chanid); + return 0; + } + function caml_ml_set_channel_name(chanid, name){ + var chan = caml_ml_channel_get(chanid); + chan.name = name; + return 0; + } + function caml_ml_set_channel_output(chanid, f){ + var chan = caml_ml_channel_get(chanid); + chan.output = function(s){f(s);}; + return 0; + } + function caml_ml_set_channel_refill(chanid, f){ + caml_ml_channel_get(chanid).refill = f; + return 0; + } + function caml_mod(x, y){if(y == 0) caml_raise_zero_divide(); return x % y;} + function caml_modf_float(x){ + if(isFinite(x)){ + var neg = 1 / x < 0; + x = Math.abs(x); + var i = Math.floor(x), f = x - i; + if(neg){i = - i; f = - f;} + return [0, f, i]; + } + if(isNaN(x)) return [0, NaN, NaN]; + return [0, 1 / x, x]; + } + function caml_mount_autoload(name, f){ + var + path = caml_make_path(name), + name = caml_trailing_slash(path.join("/")); + jsoo_mount_point.push({path: name, device: new MlFakeDevice(name, f)}); + return 0; + } + function caml_lex_run_mem(s, i, mem, curr_pos){ + for(;;){ + var dst = s.charCodeAt(i); + i++; + if(dst == 0xff) return; + var src = s.charCodeAt(i); + i++; + if(src == 0xff) + mem[dst + 1] = curr_pos; + else + mem[dst + 1] = mem[src + 1]; + } + } + function caml_lex_run_tag(s, i, mem){ + for(;;){ + var dst = s.charCodeAt(i); + i++; + if(dst == 0xff) return; + var src = s.charCodeAt(i); + i++; + if(src == 0xff) mem[dst + 1] = - 1; else mem[dst + 1] = mem[src + 1]; + } + } + function caml_new_lex_engine(tbl, start_state, lexbuf){ + var + lex_buffer = 2, + lex_buffer_len = 3, + lex_start_pos = 5, + lex_curr_pos = 6, + lex_last_pos = 7, + lex_last_action = 8, + lex_eof_reached = 9, + lex_mem = 10, + lex_base = 1, + lex_backtrk = 2, + lex_default = 3, + lex_trans = 4, + lex_check = 5, + lex_base_code = 6, + lex_backtrk_code = 7, + lex_default_code = 8, + lex_trans_code = 9, + lex_check_code = 10, + lex_code = 11; + if(! tbl.lex_default){ + tbl.lex_base = caml_lex_array(tbl[lex_base]); + tbl.lex_backtrk = caml_lex_array(tbl[lex_backtrk]); + tbl.lex_check = caml_lex_array(tbl[lex_check]); + tbl.lex_trans = caml_lex_array(tbl[lex_trans]); + tbl.lex_default = caml_lex_array(tbl[lex_default]); + } + if(! tbl.lex_default_code){ + tbl.lex_base_code = caml_lex_array(tbl[lex_base_code]); + tbl.lex_backtrk_code = caml_lex_array(tbl[lex_backtrk_code]); + tbl.lex_check_code = caml_lex_array(tbl[lex_check_code]); + tbl.lex_trans_code = caml_lex_array(tbl[lex_trans_code]); + tbl.lex_default_code = caml_lex_array(tbl[lex_default_code]); + } + if(tbl.lex_code == null) + tbl.lex_code = caml_jsbytes_of_string(tbl[lex_code]); + var + c, + state = start_state, + buffer = caml_uint8_array_of_bytes(lexbuf[lex_buffer]); + if(state >= 0){ + lexbuf[lex_last_pos] = lexbuf[lex_start_pos] = lexbuf[lex_curr_pos]; + lexbuf[lex_last_action] = - 1; + } + else + state = - state - 1; + for(;;){ + var base = tbl.lex_base[state]; + if(base < 0){ + var pc_off = tbl.lex_base_code[state]; + caml_lex_run_tag(tbl.lex_code, pc_off, lexbuf[lex_mem]); + return - base - 1; + } + var backtrk = tbl.lex_backtrk[state]; + if(backtrk >= 0){ + var pc_off = tbl.lex_backtrk_code[state]; + caml_lex_run_tag(tbl.lex_code, pc_off, lexbuf[lex_mem]); + lexbuf[lex_last_pos] = lexbuf[lex_curr_pos]; + lexbuf[lex_last_action] = backtrk; + } + if(lexbuf[lex_curr_pos] >= lexbuf[lex_buffer_len]) + if(lexbuf[lex_eof_reached] == 0) return - state - 1; else c = 256; + else{c = buffer[lexbuf[lex_curr_pos]]; lexbuf[lex_curr_pos]++;} + var pstate = state; + if(tbl.lex_check[base + c] == state) + state = tbl.lex_trans[base + c]; + else + state = tbl.lex_default[state]; + if(state < 0){ + lexbuf[lex_curr_pos] = lexbuf[lex_last_pos]; + if(lexbuf[lex_last_action] == - 1) + caml_failwith("lexing: empty token"); + else + return lexbuf[lex_last_action]; + } + else{ + var base_code = tbl.lex_base_code[pstate], pc_off; + if(tbl.lex_check_code[base_code + c] == pstate) + pc_off = tbl.lex_trans_code[base_code + c]; + else + pc_off = tbl.lex_default_code[pstate]; + if(pc_off > 0) + caml_lex_run_mem + (tbl.lex_code, pc_off, lexbuf[lex_mem], lexbuf[lex_curr_pos]); + if(c == 256) lexbuf[lex_eof_reached] = 0; + } + } + } + function caml_nextafter_float(x, y){ + if(isNaN(x) || isNaN(y)) return NaN; + if(x == y) return y; + if(x == 0) return y < 0 ? - Math.pow(2, - 1074) : Math.pow(2, - 1074); + var bits = caml_int64_bits_of_float(x), one = caml_int64_of_int32(1); + if(x < y == x > 0) + bits = caml_int64_add(bits, one); + else + bits = caml_int64_sub(bits, one); + return caml_int64_float_of_bits(bits); + } + function caml_notequal(x, y){ + return + (caml_compare_val(x, y, false) != 0); + } + function caml_obj_add_offset(v, offset){ + caml_failwith("Obj.add_offset is not supported"); + } + function caml_obj_block(tag, size){ + var o = new Array(size + 1); + o[0] = tag; + for(var i = 1; i <= size; i++) o[i] = 0; + return o; + } + function caml_obj_compare_and_swap(x, i, old, n){ + if(x[i + 1] == old){x[i + 1] = n; return 1;} + return 0; + } + function caml_obj_is_block(x){return + (x instanceof Array);} + function caml_obj_is_shared(x){return 1;} + function caml_obj_make_forward(b, v){b[0] = 250; b[1] = v; return 0;} + function caml_obj_raw_field(o, i){return o[i + 1];} + function caml_obj_reachable_words(o){return 0;} + function caml_obj_set_raw_field(o, i, v){return o[i + 1] = v;} + function caml_obj_set_tag(x, tag){x[0] = tag; return 0;} + function caml_obj_truncate(x, s){ + if(s <= 0 || s + 1 > x.length) caml_invalid_argument("Obj.truncate"); + if(x.length != s + 1) x.length = s + 1; + return 0; + } + function caml_obj_with_tag(tag, x){ + var l = x.length, a = new Array(l); + a[0] = tag; + for(var i = 1; i < l; i++) a[i] = x[i]; + return a; + } + function caml_ojs_new_arr(c, a){ + switch(a.length){ + case 0: + return new c; + case 1: + return new c(a[0]); + case 2: + return new c(a[0], a[1]); + case 3: + return new c(a[0], a[1], a[2]); + case 4: + return new c(a[0], a[1], a[2], a[3]); + case 5: + return new c(a[0], a[1], a[2], a[3], a[4]); + case 6: + return new c(a[0], a[1], a[2], a[3], a[4], a[5]); + case 7: + return new c(a[0], a[1], a[2], a[3], a[4], a[5], a[6]); + } + function F(){return c.apply(this, a);} + F.prototype = c.prototype; + return new F; + } + var + caml_output_val = + function(){ + function Writer(){this.chunk = [];} + Writer.prototype = + {chunk_idx: 20, + block_len: 0, + obj_counter: 0, + size_32: 0, + size_64: 0, + write: + function(size, value){ + for(var i = size - 8; i >= 0; i -= 8) + this.chunk[this.chunk_idx++] = value >> i & 0xFF; + }, + write_at: + function(pos, size, value){ + var pos = pos; + for(var i = size - 8; i >= 0; i -= 8) + this.chunk[pos++] = value >> i & 0xFF; + }, + write_code: + function(size, code, value){ + this.chunk[this.chunk_idx++] = code; + for(var i = size - 8; i >= 0; i -= 8) + this.chunk[this.chunk_idx++] = value >> i & 0xFF; + }, + write_shared: + function(offset){ + if(offset < 1 << 8) + this.write_code(8, 0x04, offset); + else if(offset < 1 << 16) + this.write_code(16, 0x05, offset); + else + this.write_code(32, 0x06, offset); + }, + pos: function(){return this.chunk_idx;}, + finalize: + function(){ + this.block_len = this.chunk_idx - 20; + this.chunk_idx = 0; + this.write(32, 0x8495A6BE); + this.write(32, this.block_len); + this.write(32, this.obj_counter); + this.write(32, this.size_32); + this.write(32, this.size_64); + return this.chunk; + }}; + return function(v, flags){ + flags = caml_list_to_js_array(flags); + var + no_sharing = flags.indexOf(0) !== - 1, + closures = flags.indexOf(1) !== - 1; + if(closures) + console.warn + ("in caml_output_val: flag Marshal.Closures is not supported."); + var + writer = new Writer(), + stack = [], + intern_obj_table = no_sharing ? null : new MlObjectTable(); + function memo(v){ + if(no_sharing) return false; + var existing_offset = intern_obj_table.recall(v); + if(existing_offset){ + writer.write_shared(existing_offset); + return true; + } + else{intern_obj_table.store(v); return false;} + } + function extern_rec(v){ + if(v.caml_custom){ + if(memo(v)) return; + var + name = v.caml_custom, + ops = caml_custom_ops[name], + sz_32_64 = [0, 0]; + if(! ops.serialize) + caml_invalid_argument("output_value: abstract value (Custom)"); + if(ops.fixed_length == undefined){ + writer.write(8, 0x18); + for(var i = 0; i < name.length; i++) + writer.write(8, name.charCodeAt(i)); + writer.write(8, 0); + var header_pos = writer.pos(); + for(var i = 0; i < 12; i++) writer.write(8, 0); + ops.serialize(writer, v, sz_32_64); + writer.write_at(header_pos, 32, sz_32_64[0]); + writer.write_at(header_pos + 4, 32, 0); + writer.write_at(header_pos + 8, 32, sz_32_64[1]); + } + else{ + writer.write(8, 0x19); + for(var i = 0; i < name.length; i++) + writer.write(8, name.charCodeAt(i)); + writer.write(8, 0); + var old_pos = writer.pos(); + ops.serialize(writer, v, sz_32_64); + if(ops.fixed_length != writer.pos() - old_pos) + caml_failwith + ("output_value: incorrect fixed sizes specified by " + name); + } + writer.size_32 += 2 + (sz_32_64[0] + 3 >> 2); + writer.size_64 += 2 + (sz_32_64[1] + 7 >> 3); + } + else if(v instanceof Array && v[0] === (v[0] | 0)){ + if(v[0] == 251) + caml_failwith("output_value: abstract value (Abstract)"); + if(caml_is_continuation_tag(v[0])) + caml_invalid_argument("output_value: continuation value"); + if(v.length > 1 && memo(v)) return; + if(v[0] < 16 && v.length - 1 < 8) + writer.write(8, 0x80 + v[0] + (v.length - 1 << 4)); + else + writer.write_code(32, 0x08, v.length - 1 << 10 | v[0]); + writer.size_32 += v.length; + writer.size_64 += v.length; + if(v.length > 1) stack.push(v, 1); + } + else if(caml_is_ml_bytes(v)){ + if(! caml_is_ml_bytes(caml_string_of_jsbytes(""))) + caml_failwith + ("output_value: [Bytes.t] cannot safely be marshaled with [--enable use-js-string]"); + if(memo(v)) return; + var len = caml_ml_bytes_length(v); + if(len < 0x20) + writer.write(8, 0x20 + len); + else if(len < 0x100) + writer.write_code(8, 0x09, len); + else + writer.write_code(32, 0x0A, len); + for(var i = 0; i < len; i++) + writer.write(8, caml_bytes_unsafe_get(v, i)); + writer.size_32 += 1 + ((len + 4) / 4 | 0); + writer.size_64 += 1 + ((len + 8) / 8 | 0); + } + else if(caml_is_ml_string(v)){ + if(memo(v)) return; + var len = caml_ml_string_length(v); + if(len < 0x20) + writer.write(8, 0x20 + len); + else if(len < 0x100) + writer.write_code(8, 0x09, len); + else + writer.write_code(32, 0x0A, len); + for(var i = 0; i < len; i++) + writer.write(8, caml_string_unsafe_get(v, i)); + writer.size_32 += 1 + ((len + 4) / 4 | 0); + writer.size_64 += 1 + ((len + 8) / 8 | 0); + } + else if(v != (v | 0)){ + var type_of_v = typeof v; + if(type_of_v != "number") + caml_failwith("output_value: abstract value (" + type_of_v + ")"); + if(memo(v)) return; + var t = caml_int64_to_bytes(caml_int64_bits_of_float(v)); + writer.write(8, 0x0C); + for(var i = 0; i < 8; i++) writer.write(8, t[7 - i]); + writer.size_32 += 3; + writer.size_64 += 2; + } + else if(v >= 0 && v < 0x40) + writer.write(8, 0X40 + v); + else if(v >= - (1 << 7) && v < 1 << 7) + writer.write_code(8, 0x00, v); + else if(v >= - (1 << 15) && v < 1 << 15) + writer.write_code(16, 0x01, v); + else + writer.write_code(32, 0x02, v); + } + extern_rec(v); + while(stack.length > 0){ + var i = stack.pop(), v = stack.pop(); + if(i + 1 < v.length) stack.push(v, i + 1); + extern_rec(v[i]); + } + if(intern_obj_table) + writer.obj_counter = intern_obj_table.objs.length; + writer.finalize(); + return writer.chunk;}; + } + (); + function caml_output_value_to_string(v, flags){ + return caml_string_of_array(caml_output_val(v, flags)); + } + function caml_output_value(chanid, v, flags){ + var s = caml_output_value_to_string(v, flags); + caml_ml_output(chanid, s, 0, caml_ml_string_length(s)); + return 0; + } + function caml_output_value_to_buffer(s, ofs, len, v, flags){ + var t = caml_output_val(v, flags); + if(t.length > len) caml_failwith("Marshal.to_buffer: buffer overflow"); + caml_blit_bytes(t, 0, s, ofs, t.length); + return 0; + } + function caml_output_value_to_bytes(v, flags){ + return caml_bytes_of_array(caml_output_val(v, flags)); + } + var caml_parser_trace = 0; + function caml_parse_engine(tables, env, cmd, arg){ + var + ERRCODE = 256, + loop = 6, + testshift = 7, + shift = 8, + shift_recover = 9, + reduce = 10, + READ_TOKEN = 0, + RAISE_PARSE_ERROR = 1, + GROW_STACKS_1 = 2, + GROW_STACKS_2 = 3, + COMPUTE_SEMANTIC_ACTION = 4, + CALL_ERROR_FUNCTION = 5, + env_s_stack = 1, + env_v_stack = 2, + env_symb_start_stack = 3, + env_symb_end_stack = 4, + env_stacksize = 5, + env_stackbase = 6, + env_curr_char = 7, + env_lval = 8, + env_symb_start = 9, + env_symb_end = 10, + env_asp = 11, + env_rule_len = 12, + env_rule_number = 13, + env_sp = 14, + env_state = 15, + env_errflag = 16, + tbl_transl_const = 2, + tbl_transl_block = 3, + tbl_lhs = 4, + tbl_len = 5, + tbl_defred = 6, + tbl_dgoto = 7, + tbl_sindex = 8, + tbl_rindex = 9, + tbl_gindex = 10, + tbl_tablesize = 11, + tbl_table = 12, + tbl_check = 13, + tbl_names_const = 15, + tbl_names_block = 16; + function log(x){ + var s = caml_string_of_jsbytes(x + "\n"); + caml_ml_output(2, s, 0, caml_ml_string_length(s)); + } + function token_name(names, number){ + var str = caml_jsstring_of_string(names); + if(str[0] == "\x00") return ""; + return str.split("\x00")[number]; + } + function print_token(state, tok){ + var token, kind; + if(tok instanceof Array){ + token = token_name(tables[tbl_names_block], tok[0]); + if(typeof tok[1] == "number") + kind = "" + tok[1]; + else if(typeof tok[1] == "string") + kind = tok[1]; + else if(tok[1] instanceof MlBytes) + kind = caml_jsbytes_of_string(tok[1]); + else + kind = "_"; + log("State " + state + ": read token " + token + "(" + kind + ")"); + } + else{ + token = token_name(tables[tbl_names_const], tok); + log("State " + state + ": read token " + token); + } + } + if(! tables.dgoto){ + tables.defred = caml_lex_array(tables[tbl_defred]); + tables.sindex = caml_lex_array(tables[tbl_sindex]); + tables.check = caml_lex_array(tables[tbl_check]); + tables.rindex = caml_lex_array(tables[tbl_rindex]); + tables.table = caml_lex_array(tables[tbl_table]); + tables.len = caml_lex_array(tables[tbl_len]); + tables.lhs = caml_lex_array(tables[tbl_lhs]); + tables.gindex = caml_lex_array(tables[tbl_gindex]); + tables.dgoto = caml_lex_array(tables[tbl_dgoto]); + } + var + res = 0, + n, + n1, + n2, + state1, + sp = env[env_sp], + state = env[env_state], + errflag = env[env_errflag]; + exit: + for(;;) + next: + switch(cmd){ + case 0: + state = 0; errflag = 0; + case 6: + n = tables.defred[state]; + if(n != 0){cmd = reduce; break;} + if(env[env_curr_char] >= 0){cmd = testshift; break;} + res = READ_TOKEN; + break exit; + case 1: + if(arg instanceof Array){ + env[env_curr_char] = tables[tbl_transl_block][arg[0] + 1]; + env[env_lval] = arg[1]; + } + else{ + env[env_curr_char] = tables[tbl_transl_const][arg + 1]; + env[env_lval] = 0; + } + if(caml_parser_trace) print_token(state, arg); + case 7: + n1 = tables.sindex[state]; + n2 = n1 + env[env_curr_char]; + if + (n1 != 0 && n2 >= 0 && n2 <= tables[tbl_tablesize] + && tables.check[n2] == env[env_curr_char]){cmd = shift; break;} + n1 = tables.rindex[state]; + n2 = n1 + env[env_curr_char]; + if + (n1 != 0 && n2 >= 0 && n2 <= tables[tbl_tablesize] + && tables.check[n2] == env[env_curr_char]){ + n = tables.table[n2]; + cmd = reduce; + break; + } + if(errflag <= 0){res = CALL_ERROR_FUNCTION; break exit;} + case 5: + if(errflag < 3){ + errflag = 3; + for(;;){ + state1 = env[env_s_stack][sp + 1]; + n1 = tables.sindex[state1]; + n2 = n1 + ERRCODE; + if + (n1 != 0 && n2 >= 0 && n2 <= tables[tbl_tablesize] + && tables.check[n2] == ERRCODE){ + if(caml_parser_trace) log("Recovering in state " + state1); + cmd = shift_recover; + break next; + } + else{ + if(caml_parser_trace) log("Discarding state " + state1); + if(sp <= env[env_stackbase]){ + if(caml_parser_trace) log("No more states to discard"); + return RAISE_PARSE_ERROR; + } + sp--; + } + } + } + else{ + if(env[env_curr_char] == 0) return RAISE_PARSE_ERROR; + if(caml_parser_trace) log("Discarding last token read"); + env[env_curr_char] = - 1; + cmd = loop; + break; + } + case 8: + env[env_curr_char] = - 1; if(errflag > 0) errflag--; + case 9: + if(caml_parser_trace) + log("State " + state + ": shift to state " + tables.table[n2]); + state = tables.table[n2]; + sp++; + if(sp >= env[env_stacksize]){res = GROW_STACKS_1; break exit;} + case 2: + env[env_s_stack][sp + 1] = state; + env[env_v_stack][sp + 1] = env[env_lval]; + env[env_symb_start_stack][sp + 1] = env[env_symb_start]; + env[env_symb_end_stack][sp + 1] = env[env_symb_end]; + cmd = loop; + break; + case 10: + if(caml_parser_trace) log("State " + state + ": reduce by rule " + n); + var m = tables.len[n]; + env[env_asp] = sp; + env[env_rule_number] = n; + env[env_rule_len] = m; + sp = sp - m + 1; + m = tables.lhs[n]; + state1 = env[env_s_stack][sp]; + n1 = tables.gindex[m]; + n2 = n1 + state1; + if + (n1 != 0 && n2 >= 0 && n2 <= tables[tbl_tablesize] + && tables.check[n2] == state1) + state = tables.table[n2]; + else + state = tables.dgoto[m]; + if(sp >= env[env_stacksize]){res = GROW_STACKS_2; break exit;} + case 3: + res = COMPUTE_SEMANTIC_ACTION; break exit; + case 4: + env[env_s_stack][sp + 1] = state; + env[env_v_stack][sp + 1] = arg; + var asp = env[env_asp]; + env[env_symb_end_stack][sp + 1] = env[env_symb_end_stack][asp + 1]; + if(sp > asp) + env[env_symb_start_stack][sp + 1] = env[env_symb_end_stack][asp + 1]; + cmd = loop; + break; + default: return RAISE_PARSE_ERROR; + } + env[env_sp] = sp; + env[env_state] = state; + env[env_errflag] = errflag; + return res; + } + function caml_pure_js_expr(s){ + console.error("caml_pure_js_expr: fallback to runtime evaluation\n"); + return eval(caml_jsstring_of_string(s)); + } + function caml_raise_not_a_dir(name){ + caml_raise_sys_error(name + ": Not a directory"); + } + function caml_raise_not_found(){ + caml_raise_constant(caml_global_data.Not_found); + } + function caml_raw_backtrace_length(){return 0;} + function caml_raw_backtrace_next_slot(){return 0;} + function caml_raw_backtrace_slot(){ + caml_invalid_argument + ("Printexc.get_raw_backtrace_slot: index out of bounds"); + } + function caml_read_file_content(name){ + var + name = typeof name == "string" ? caml_string_of_jsbytes(name) : name, + root = resolve_fs_device(name); + if(root.device.exists(root.rest)){ + var + file = root.device.open(root.rest, {rdonly: 1}), + len = file.length(), + buf = new Uint8Array(len); + file.read(0, buf, 0, len); + return caml_string_of_array(buf); + } + caml_raise_no_such_file(caml_jsbytes_of_string(name)); + } + function caml_recommended_domain_count(unit){return 1;} + function caml_record_backtrace(b){ + caml_record_backtrace_flag = b; + return 0; + } + function caml_register_channel_for_spacetime(_channel){return 0;} + function caml_register_global(n, v, name_opt){ + if(name_opt){ + var name = name_opt; + if(globalThis.toplevelReloc) + n = caml_callback(globalThis.toplevelReloc, [name]); + else if(caml_global_data.symbols){ + if(! caml_global_data.symidx) + caml_global_data.symidx = caml_build_symbols(caml_global_data.symbols); + var nid = caml_global_data.symidx[name]; + if(nid >= 0) + n = nid; + else + caml_failwith("caml_register_global: cannot locate " + name); + } + } + caml_global_data[n + 1] = v; + if(name_opt) caml_global_data[name_opt] = v; + } + function caml_register_named_value(nm, v){ + caml_named_values[caml_jsbytes_of_string(nm)] = v; + return 0; + } + function caml_restore_raw_backtrace(exn, bt){return 0;} + function caml_round_float(x){ + if(x >= 0){ + var y = Math.floor(x); + return x - y >= 0.5 ? y + 1 : y; + } + else{var y = Math.ceil(x); return y - x >= 0.5 ? y - 1 : y;} + } + function caml_runtime_events_create_cursor(target){return {};} + function caml_runtime_events_free_cursor(cursor){return 0;} + function caml_runtime_events_read_poll(cursor, callbacks, num){return 0;} + function caml_runtime_events_user_register + (event_name, event_tag, event_type){ + caml_custom_event_index += 1; + return [0, caml_custom_event_index, event_name, event_type, event_tag]; + } + function caml_runtime_events_user_resolve(){return 0;} + function caml_runtime_events_user_write(event, event_content){return 0;} + function caml_runtime_parameters(_unit){return caml_string_of_jsbytes("");} + function caml_runtime_variant(_unit){return caml_string_of_jsbytes("");} + function caml_set_oo_id(b){b[2] = caml_oo_last_id++; return b;} + function caml_set_parser_trace(bool){ + var oldflag = caml_parser_trace; + caml_parser_trace = bool; + return oldflag; + } + function caml_set_static_env(k, v){ + if(! globalThis.jsoo_static_env) globalThis.jsoo_static_env = {}; + globalThis.jsoo_static_env[k] = v; + return 0; + } + function caml_signbit_float(x){if(x == 0) x = 1 / x; return x < 0 ? 1 : 0;} + function caml_sinh_float(x){return Math.sinh(x);} + function caml_spacetime_enabled(_unit){return 0;} + function caml_spacetime_only_works_for_native_code(){ + caml_failwith("Spacetime profiling only works for native code"); + } + function caml_str_initialize(unit){return 0;} + function caml_string_bound_error(){ + caml_invalid_argument("index out of bounds"); + } + function caml_string_concat(a, b){return a + b;} + function caml_string_equal(s1, s2){if(s1 === s2) return 1; return 0;} + function caml_string_get(s, i){ + if(i >>> 0 >= caml_ml_string_length(s)) caml_string_bound_error(); + return caml_string_unsafe_get(s, i); + } + function caml_string_get16(s, i){ + if(i >>> 0 >= caml_ml_string_length(s) - 1) caml_string_bound_error(); + var + b1 = caml_string_unsafe_get(s, i), + b2 = caml_string_unsafe_get(s, i + 1); + return b2 << 8 | b1; + } + function caml_string_get32(s, i){ + if(i >>> 0 >= caml_ml_string_length(s) - 3) caml_string_bound_error(); + var + b1 = caml_string_unsafe_get(s, i), + b2 = caml_string_unsafe_get(s, i + 1), + b3 = caml_string_unsafe_get(s, i + 2), + b4 = caml_string_unsafe_get(s, i + 3); + return b4 << 24 | b3 << 16 | b2 << 8 | b1; + } + function caml_string_get64(s, i){ + if(i >>> 0 >= caml_ml_string_length(s) - 7) caml_string_bound_error(); + var a = new Array(8); + for(var j = 0; j < 8; j++) a[7 - j] = caml_string_unsafe_get(s, i + j); + return caml_int64_of_bytes(a); + } + function caml_string_lessequal(s1, s2){return s1 <= s2 ? 1 : 0;} + function caml_string_greaterequal(s1, s2){return caml_string_lessequal(s2, s1); + } + function caml_string_lessthan(s1, s2){return s1 < s2 ? 1 : 0;} + function caml_string_greaterthan(s1, s2){return caml_string_lessthan(s2, s1); + } + function caml_string_hash(h, v){ + var h = caml_hash_mix_string(h, v), h = caml_hash_mix_final(h); + return h & 0x3FFFFFFF; + } + function caml_string_notequal(s1, s2){ + return 1 - caml_string_equal(s1, s2); + } + function caml_string_set(s, i, c){caml_failwith("caml_string_set");} + function caml_string_set16(s, i, i16){caml_failwith("caml_string_set16");} + function caml_string_set32(s, i, i32){caml_failwith("caml_string_set32");} + function caml_string_set64(s, i, i64){caml_failwith("caml_string_set64");} + function caml_string_unsafe_set(s, i, c){ + caml_failwith("caml_string_unsafe_set"); + } + function caml_sys_argv(a){return caml_argv;} + function caml_sys_chdir(dir){ + var root = resolve_fs_device(dir); + if(root.device.exists(root.rest)){ + if(root.rest) + caml_current_dir = caml_trailing_slash(root.path + root.rest); + else + caml_current_dir = root.path; + return 0; + } + else + caml_raise_no_such_file(caml_jsbytes_of_string(dir)); + } + function caml_sys_const_backend_type(){ + return [0, caml_string_of_jsbytes("js_of_ocaml")]; + } + function caml_sys_const_big_endian(){return 0;} + function caml_sys_const_int_size(){return 32;} + function caml_sys_const_max_wosize(){return 0x7FFFFFFF / 4 | 0;} + function caml_sys_const_naked_pointers_checked(_unit){return 0;} + var + os_type = + globalThis.process && globalThis.process.platform + && globalThis.process.platform == "win32" + ? "Cygwin" + : "Unix"; + function caml_sys_const_ostype_cygwin(){return os_type == "Cygwin" ? 1 : 0; + } + function caml_sys_const_ostype_unix(){return os_type == "Unix" ? 1 : 0;} + function caml_sys_const_ostype_win32(){return os_type == "Win32" ? 1 : 0;} + function caml_sys_const_word_size(){return 32;} + function caml_sys_executable_name(a){return caml_executable_name;} + function caml_sys_exit(code){ + if(globalThis.quit) globalThis.quit(code); + if(globalThis.process && globalThis.process.exit) + globalThis.process.exit(code); + caml_invalid_argument("Function 'exit' not implemented"); + } + function caml_sys_file_exists(name){ + var root = resolve_fs_device(name); + return root.device.exists(root.rest); + } + function caml_sys_get_argv(a){return [0, caml_argv[1], caml_argv];} + function caml_sys_get_config(){ + return [0, caml_string_of_jsbytes(os_type), 32, 0]; + } + function caml_sys_getcwd(){ + return caml_string_of_jsbytes(caml_current_dir); + } + function caml_sys_getenv(name){ + var r = jsoo_sys_getenv(caml_jsstring_of_string(name)); + if(r === undefined) caml_raise_not_found(); + return caml_string_of_jsstring(r); + } + function caml_sys_is_directory(name){ + var root = resolve_fs_device(name), a = root.device.is_dir(root.rest); + return a ? 1 : 0; + } + function caml_sys_is_regular_file(name){ + var root = resolve_fs_device(name); + return root.device.isFile(root.rest); + } + function caml_sys_isatty(_chan){return 0;} + function caml_sys_mkdir(name, perm){ + var root = resolve_fs_device(name); + root.device.mkdir(root.rest, perm); + return 0; + } + function caml_sys_modify_argv(arg){caml_argv = arg; return 0;} + function caml_sys_random_seed(){ + if(globalThis.crypto) + if(globalThis.crypto.getRandomValues){ + var a = globalThis.crypto.getRandomValues(new Int32Array(4)); + return [0, a[0], a[1], a[2], a[3]]; + } + else if(globalThis.crypto.randomBytes){ + var a = new Int32Array(globalThis.crypto.randomBytes(16).buffer); + return [0, a[0], a[1], a[2], a[3]]; + } + var now = new Date().getTime(), x = now ^ 0xffffffff * Math.random(); + return [0, x]; + } + function caml_sys_read_directory(name){ + var + root = resolve_fs_device(name), + a = root.device.readdir(root.rest), + l = new Array(a.length + 1); + l[0] = 0; + for(var i = 0; i < a.length; i++) l[i + 1] = caml_string_of_jsbytes(a[i]); + return l; + } + function caml_sys_remove(name){ + var root = resolve_fs_device(name), ok = root.device.unlink(root.rest); + if(ok == 0) caml_raise_no_such_file(caml_jsbytes_of_string(name)); + return 0; + } + function caml_sys_rename(o, n){ + var o_root = resolve_fs_device(o), n_root = resolve_fs_device(n); + if(o_root.device != n_root.device) + caml_failwith("caml_sys_rename: cannot move file between two filesystem"); + if(! o_root.device.rename) + caml_failwith("caml_sys_rename: no implemented"); + o_root.device.rename(o_root.rest, n_root.rest); + } + function caml_sys_rmdir(name){ + var root = resolve_fs_device(name); + root.device.rmdir(root.rest); + return 0; + } + function caml_sys_system_command(cmd){ + var cmd = caml_jsstring_of_string(cmd); + if(typeof require != "undefined"){ + var child_process = require("child_process"); + if(child_process && child_process.execSync) + try{child_process.execSync(cmd, {stdio: "inherit"}); return 0;} + catch(e){return 1;} + } + else + return 127; + } + var caml_initial_time = new Date().getTime() * 0.001; + function caml_sys_time(){ + var now = new Date().getTime(); + return now * 0.001 - caml_initial_time; + } + function caml_sys_time_include_children(b){return caml_sys_time();} + function caml_sys_unsafe_getenv(name){return caml_sys_getenv(name);} + function caml_tanh_float(x){return Math.tanh(x);} + function caml_to_js_string(s){return caml_jsstring_of_string(s);} + function caml_trampoline(res){ + var c = 1; + while(res && res.joo_tramp){ + res = res.joo_tramp.apply(null, res.joo_args); + c++; + } + return res; + } + function caml_trampoline_return(f, args){return {joo_tramp: f, joo_args: args}; + } + function caml_trunc_float(x){return Math.trunc(x);} + function caml_unix_cleanup(){} + function caml_unix_closedir(dir_handle){ + try{dir_handle.pointer.closeSync();} + catch(e){ + var unix_error = caml_named_value("Unix.Unix_error"); + caml_raise_with_args + (unix_error, make_unix_err_args("EBADF", "closedir", dir_handle.path)); + } + } + function caml_unix_filedescr_of_fd(x){return x;} + function caml_unix_findclose(dir_handle){return caml_unix_closedir(dir_handle); + } + function caml_unix_opendir(path){ + var root = resolve_fs_device(path); + if(! root.device.opendir) + caml_failwith("caml_unix_opendir: not implemented"); + var dir_handle = root.device.opendir(root.rest, true); + return {pointer: dir_handle, path: path}; + } + function caml_unix_readdir(dir_handle){ + var entry; + try{entry = dir_handle.pointer.readSync();} + catch(e){ + var unix_error = caml_named_value("Unix.Unix_error"); + caml_raise_with_args + (unix_error, make_unix_err_args("EBADF", "readdir", dir_handle.path)); + } + if(entry === null) + caml_raise_end_of_file(); + else + return caml_string_of_jsstring(entry.name); + } + function caml_unix_findfirst(path){ + var path_js = caml_jsstring_of_string(path); + path_js = path_js.replace(/(^|[\\\/])\*\.\*$/, ""); + path = caml_string_of_jsstring(path_js); + var + dir_handle = caml_unix_opendir(path), + first_entry = caml_unix_readdir(dir_handle); + return [0, first_entry, dir_handle]; + } + function caml_unix_findnext(dir_handle){return caml_unix_readdir(dir_handle); + } + function caml_unix_getpwuid(unit){caml_raise_not_found();} + function caml_unix_gettimeofday(){return new Date().getTime() / 1000;} + function caml_unix_getuid(unit){ + if(globalThis.process && globalThis.process.getuid) + return globalThis.process.getuid(); + caml_raise_not_found(); + } + function caml_unix_gmtime(t){ + var + d = new Date(t * 1000), + d_num = d.getTime(), + januaryfirst = new Date(Date.UTC(d.getUTCFullYear(), 0, 1)).getTime(), + doy = Math.floor((d_num - januaryfirst) / 86400000); + return [0, + d.getUTCSeconds(), + d.getUTCMinutes(), + d.getUTCHours(), + d.getUTCDate(), + d.getUTCMonth(), + d.getUTCFullYear() - 1900, + d.getUTCDay(), + doy, + false | 0]; + } + function caml_unix_has_symlink(unit){return fs_node_supported() ? 1 : 0;} + function caml_unix_inet_addr_of_string(){return 0;} + function caml_unix_isatty(fileDescriptor){ + if(fs_node_supported()){ + var tty = require("tty"); + return tty.isatty(fileDescriptor) ? 1 : 0; + } + else + return 0; + } + function caml_unix_localtime(t){ + var + d = new Date(t * 1000), + d_num = d.getTime(), + januaryfirst = new Date(d.getFullYear(), 0, 1).getTime(), + doy = Math.floor((d_num - januaryfirst) / 86400000), + jan = new Date(d.getFullYear(), 0, 1), + jul = new Date(d.getFullYear(), 6, 1), + stdTimezoneOffset = + Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset()); + return [0, + d.getSeconds(), + d.getMinutes(), + d.getHours(), + d.getDate(), + d.getMonth(), + d.getFullYear() - 1900, + d.getDay(), + doy, + d.getTimezoneOffset() < stdTimezoneOffset | 0]; + } + function caml_unix_lstat(name){ + var root = resolve_fs_device(name); + if(! root.device.lstat) caml_failwith("caml_unix_lstat: not implemented"); + return root.device.lstat(root.rest, true); + } + function caml_unix_lstat_64(name){ + var r = caml_unix_lstat(name); + r[9] = caml_int64_of_int32(r[9]); + return r; + } + function caml_unix_mkdir(name, perm){ + var root = resolve_fs_device(name); + if(! root.device.mkdir) caml_failwith("caml_unix_mkdir: not implemented"); + return root.device.mkdir(root.rest, perm, true); + } + function caml_unix_mktime(tm){ + var + d = new Date(tm[6] + 1900, tm[5], tm[4], tm[3], tm[2], tm[1]).getTime(), + t = Math.floor(d / 1000), + tm2 = caml_unix_localtime(t); + return [0, t, tm2]; + } + function caml_unix_readlink(name){ + var root = resolve_fs_device(name); + if(! root.device.readlink) + caml_failwith("caml_unix_readlink: not implemented"); + return root.device.readlink(root.rest, true); + } + function caml_unix_rewinddir(dir_handle){ + caml_unix_closedir(dir_handle); + var new_dir_handle = caml_unix_opendir(dir_handle.path); + dir_handle.pointer = new_dir_handle.pointer; + return 0; + } + function caml_unix_rmdir(name){ + var root = resolve_fs_device(name); + if(! root.device.rmdir) caml_failwith("caml_unix_rmdir: not implemented"); + return root.device.rmdir(root.rest, true); + } + function caml_unix_startup(){} + function caml_unix_stat(name){ + var root = resolve_fs_device(name); + if(! root.device.stat) caml_failwith("caml_unix_stat: not implemented"); + return root.device.stat(root.rest, true); + } + function caml_unix_stat_64(name){ + var r = caml_unix_stat(name); + r[9] = caml_int64_of_int32(r[9]); + return r; + } + function caml_unix_symlink(to_dir, src, dst){ + var src_root = resolve_fs_device(src), dst_root = resolve_fs_device(dst); + if(src_root.device != dst_root.device) + caml_failwith + ("caml_unix_symlink: cannot symlink between two filesystems"); + if(! src_root.device.symlink) + caml_failwith("caml_unix_symlink: not implemented"); + return src_root.device.symlink(to_dir, src_root.rest, dst_root.rest, true); + } + function caml_unix_time(){return Math.floor(caml_unix_gettimeofday());} + function caml_unix_unlink(name){ + var root = resolve_fs_device(name); + if(! root.device.unlink) + caml_failwith("caml_unix_unlink: not implemented"); + return root.device.unlink(root.rest, true); + } + function caml_unmount(name){ + var + path = caml_make_path(name), + name = caml_trailing_slash(path.join("/")), + idx = - 1; + for(var i = 0; i < jsoo_mount_point.length; i++) + if(jsoo_mount_point[i].path == name) idx = i; + if(idx > - 1) jsoo_mount_point.splice(idx, 1); + return 0; + } + function caml_update_dummy(x, y){ + if(y.fun){x.fun = y.fun; return 0;} + if(typeof y === "function"){x.fun = y; return 0;} + var i = y.length; + while(i--) x[i] = y[i]; + return 0; + } + function caml_weak_set(x, i, v){ + if(v == 0) caml_ephe_unset_key(x, i); else caml_ephe_set_key(x, i, v[1]); + return 0; + } + function caml_wrap_exception(e){ + { + if(e instanceof Array) return e; + var exn; + if + (globalThis.RangeError && e instanceof globalThis.RangeError + && e.message + && e.message.match(/maximum call stack/i)) + exn = caml_global_data.Stack_overflow; + else if + (globalThis.InternalError && e instanceof globalThis.InternalError + && e.message + && e.message.match(/too much recursion/i)) + exn = caml_global_data.Stack_overflow; + else if(e instanceof globalThis.Error && caml_named_value("jsError")) + exn = [0, caml_named_value("jsError"), e]; + else + exn = [0, caml_global_data.Failure, caml_string_of_jsstring(String(e))]; + if(e instanceof globalThis.Error) exn.js_error = e; + return exn; + } + } + function caml_xmlhttprequest_create(unit){ + if(typeof globalThis.XMLHttpRequest !== "undefined") + try{return new globalThis.XMLHttpRequest;}catch(e){} + if(typeof globalThis.activeXObject !== "undefined"){ + try{return new globalThis.activeXObject("Msxml2.XMLHTTP");}catch(e){} + try{return new globalThis.activeXObject("Msxml3.XMLHTTP");}catch(e){} + try{return new globalThis.activeXObject("Microsoft.XMLHTTP");}catch(e){} + } + caml_failwith("Cannot create a XMLHttpRequest"); + } + function compare_digits_nat(nat1, ofs1, nat2, ofs2){ + if(nat1.data[ofs1] > nat2.data[ofs2]) return 1; + if(nat1.data[ofs1] < nat2.data[ofs2]) return - 1; + return 0; + } + function compare_nat(nat1, ofs1, len1, nat2, ofs2, len2){ + var + a = num_digits_nat(nat1, ofs1, len1), + b = num_digits_nat(nat2, ofs2, len2); + if(a > b) return 1; + if(a < b) return - 1; + for(var i = len1 - 1; i >= 0; i--){ + if(nat1.data[ofs1 + i] >>> 0 > nat2.data[ofs2 + i] >>> 0) return 1; + if(nat1.data[ofs1 + i] >>> 0 < nat2.data[ofs2 + i] >>> 0) return - 1; + } + return 0; + } + function compare_nat_real(nat1, nat2){ + return compare_nat(nat1, 0, nat1.data.length, nat2, 0, nat2.data.length); + } + function complement_nat(nat, ofs, len){ + for(var i = 0; i < len; i++) + nat.data[ofs + i] = (- 1 >>> 0) - (nat.data[ofs + i] >>> 0); + } + function create_nat(size){ + var arr = new MlNat(size); + for(var i = 0; i < size; i++) arr.data[i] = - 1; + return arr; + } + function decr_nat(nat, ofs, len, carry_in){ + var borrow = carry_in == 1 ? 0 : 1; + for(var i = 0; i < len; i++){ + var x = (nat.data[ofs + i] >>> 0) - borrow; + nat.data[ofs + i] = x; + if(x >= 0){borrow = 0; break;} else borrow = 1; + } + return borrow == 1 ? 0 : 1; + } + function deserialize_nat(reader, sz){ + var len = reader.read32s(), nat = new MlNat(len); + for(var i = 0; i < len; i++) nat.data[i] = reader.read32s(); + sz[0] = len * 4; + return nat; + } + function div_helper(a, b, c){ + var + x = a * 65536 + (b >>> 16), + y = Math.floor(x / c) * 65536, + z = x % c * 65536, + w = z + (b & 0x0000FFFF); + return [y + Math.floor(w / c), w % c]; + } + function div_digit_nat(natq, ofsq, natr, ofsr, nat1, ofs1, len, nat2, ofs2){ + var rem = nat1.data[ofs1 + len - 1] >>> 0; + for(var i = len - 2; i >= 0; i--){ + var + x = div_helper(rem, nat1.data[ofs1 + i] >>> 0, nat2.data[ofs2] >>> 0); + natq.data[ofsq + i] = x[0]; + rem = x[1]; + } + natr.data[ofsr] = rem; + return 0; + } + function num_leading_zero_bits_in_digit(nat, ofs){ + var a = nat.data[ofs], b = 0; + if(a & 0xFFFF0000){b += 16; a >>>= 16;} + if(a & 0xFF00){b += 8; a >>>= 8;} + if(a & 0xF0){b += 4; a >>>= 4;} + if(a & 12){b += 2; a >>>= 2;} + if(a & 2){b += 1; a >>>= 1;} + if(a & 1) b += 1; + return 32 - b; + } + function shift_left_nat(nat1, ofs1, len1, nat2, ofs2, nbits){ + if(nbits == 0){nat2.data[ofs2] = 0; return 0;} + var wrap = 0; + for(var i = 0; i < len1; i++){ + var a = nat1.data[ofs1 + i] >>> 0; + nat1.data[ofs1 + i] = a << nbits | wrap; + wrap = a >>> 32 - nbits; + } + nat2.data[ofs2] = wrap; + return 0; + } + function shift_right_nat(nat1, ofs1, len1, nat2, ofs2, nbits){ + if(nbits == 0){nat2.data[ofs2] = 0; return 0;} + var wrap = 0; + for(var i = len1 - 1; i >= 0; i--){ + var a = nat1.data[ofs1 + i] >>> 0; + nat1.data[ofs1 + i] = a >>> nbits | wrap; + wrap = a << 32 - nbits; + } + nat2.data[ofs2] = wrap; + return 0; + } + function set_to_zero_nat(nat, ofs, len){ + for(var i = 0; i < len; i++) nat.data[ofs + i] = 0; + return 0; + } + function nat_of_array(l){return new MlNat(l);} + function mult_digit_nat(nat1, ofs1, len1, nat2, ofs2, len2, nat3, ofs3){ + var carry = 0, a = nat3.data[ofs3] >>> 0; + for(var i = 0; i < len2; i++){ + var + x1 = + (nat1.data[ofs1 + i] >>> 0) + + (nat2.data[ofs2 + i] >>> 0) * (a & 0x0000FFFF) + + carry, + x2 = (nat2.data[ofs2 + i] >>> 0) * (a >>> 16); + carry = Math.floor(x2 / 65536); + var x3 = x1 + x2 % 65536 * 65536; + nat1.data[ofs1 + i] = x3; + carry += Math.floor(x3 / 4294967296); + } + return len2 < len1 && carry + ? add_nat + (nat1, ofs1 + len2, len1 - len2, nat_of_array([carry]), 0, 1, 0) + : carry; + } + function sub_nat(nat1, ofs1, len1, nat2, ofs2, len2, carry_in){ + var borrow = carry_in == 1 ? 0 : 1; + for(var i = 0; i < len2; i++){ + var + x = (nat1.data[ofs1 + i] >>> 0) - (nat2.data[ofs2 + i] >>> 0) - borrow; + nat1.data[ofs1 + i] = x; + if(x >= 0) borrow = 0; else borrow = 1; + } + return decr_nat(nat1, ofs1 + len2, len1 - len2, borrow == 1 ? 0 : 1); + } + function div_nat(nat1, ofs1, len1, nat2, ofs2, len2){ + if(len2 == 1){ + div_digit_nat(nat1, ofs1 + 1, nat1, ofs1, nat1, ofs1, len1, nat2, ofs2); + return 0; + } + var s = num_leading_zero_bits_in_digit(nat2, ofs2 + len2 - 1); + shift_left_nat(nat2, ofs2, len2, nat_of_array([0]), 0, s); + shift_left_nat(nat1, ofs1, len1, nat_of_array([0]), 0, s); + var d = (nat2.data[ofs2 + len2 - 1] >>> 0) + 1, a = create_nat(len2 + 1); + for(var i = len1 - 1; i >= len2; i--){ + var + quo = + d == 4294967296 + ? nat1.data[ofs1 + i] >>> 0 + : div_helper + (nat1.data[ofs1 + i] >>> 0, nat1.data[ofs1 + i - 1] >>> 0, d) + [0]; + set_to_zero_nat(a, 0, len2 + 1); + mult_digit_nat(a, 0, len2 + 1, nat2, ofs2, len2, nat_of_array([quo]), 0); + sub_nat(nat1, ofs1 + i - len2, len2 + 1, a, 0, len2 + 1, 1); + while + (nat1.data[ofs1 + i] != 0 + || compare_nat(nat1, ofs1 + i - len2, len2, nat2, ofs2, len2) >= 0){ + quo = quo + 1; + sub_nat(nat1, ofs1 + i - len2, len2 + 1, nat2, ofs2, len2, 1); + } + nat1.data[ofs1 + i] = quo; + } + shift_right_nat(nat1, ofs1, len2, nat_of_array([0]), 0, s); + shift_right_nat(nat2, ofs2, len2, nat_of_array([0]), 0, s); + return 0; + } + function serialize_nat(writer, nat, sz){ + var len = nat.data.length; + writer.write(32, len); + for(var i = 0; i < len; i++) writer.write(32, nat.data[i]); + sz[0] = len * 4; + sz[1] = len * 8; + } + function initialize_nat(){ + caml_custom_ops["_nat"] = + {deserialize: deserialize_nat, + serialize: serialize_nat, + hash: caml_hash_nat}; + } + function is_digit_int(nat, ofs){if(nat.data[ofs] >= 0) return 1; return 0;} + function is_digit_odd(nat, ofs){if(nat.data[ofs] & 1) return 1; return 0;} + function is_digit_zero(nat, ofs){ + if(nat.data[ofs] == 0) return 1; + return 0; + } + function jsoo_create_file_extern(name, content){ + if(globalThis.jsoo_create_file) + globalThis.jsoo_create_file(name, content); + else{ + if(! globalThis.caml_fs_tmp) globalThis.caml_fs_tmp = []; + globalThis.caml_fs_tmp.push({name: name, content: content}); + } + return 0; + } + function jsoo_effect_not_supported(){ + caml_failwith("Effect handlers are not supported"); + } + function land_digit_nat(nat1, ofs1, nat2, ofs2){nat1.data[ofs1] &= nat2.data[ofs2]; return 0; + } + function length_nat(x){return x.data.length;} + function lor_digit_nat(nat1, ofs1, nat2, ofs2){nat1.data[ofs1] |= nat2.data[ofs2]; return 0; + } + function lxor_digit_nat(nat1, ofs1, nat2, ofs2){nat1.data[ofs1] ^= nat2.data[ofs2]; return 0; + } + function mult_nat(nat1, ofs1, len1, nat2, ofs2, len2, nat3, ofs3, len3){ + var carry = 0; + for(var i = 0; i < len3; i++) + carry += + mult_digit_nat + (nat1, ofs1 + i, len1 - i, nat2, ofs2, len2, nat3, ofs3 + i); + return carry; + } + function nth_digit_nat(nat, ofs){return nat.data[ofs];} + function nth_digit_nat_native(nat, ofs){return nat.data[ofs];} + var + re_match = + function(){ + var + re_word_letters = + [0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xFF, + 0x03, + 0xFE, + 0xFF, + 0xFF, + 0x87, + 0xFE, + 0xFF, + 0xFF, + 0x07, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xFF, + 0xFF, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0x7F, + 0xFF], + opcodes = + {CHAR: 0, + CHARNORM: 1, + STRING: 2, + STRINGNORM: 3, + CHARCLASS: 4, + BOL: 5, + EOL: 6, + WORDBOUNDARY: 7, + BEGGROUP: 8, + ENDGROUP: 9, + REFGROUP: 10, + ACCEPT: 11, + SIMPLEOPT: 12, + SIMPLESTAR: 13, + SIMPLEPLUS: 14, + GOTO: 15, + PUSHBACK: 16, + SETMARK: 17, + CHECKPROGRESS: 18}; + function is_word_letter(c){ + return re_word_letters[c >> 3] >> (c & 7) & 1; + } + function in_bitset(s, i){ + return caml_string_get(s, i >> 3) >> (i & 7) & 1; + } + function re_match_impl(re, s, pos, partial){ + var + prog = caml_js_from_array(re[1]), + cpool = caml_js_from_array(re[2]), + normtable = caml_jsbytes_of_string(re[3]), + numgroups = re[4] | 0, + numregisters = re[5] | 0, + startchars = re[6] | 0, + s = caml_uint8_array_of_string(s), + pc = 0, + quit = false, + stack = [], + groups = new Array(numgroups), + re_register = new Array(numregisters); + for(var i = 0; i < groups.length; i++) + groups[i] = {start: - 1, end: - 1}; + groups[0].start = pos; + function backtrack(){ + while(stack.length){ + var item = stack.pop(); + if(item.undo) + item.undo.obj[item.undo.prop] = item.undo.value; + else if(item.pos){pc = item.pos.pc; pos = item.pos.txt; return;} + } + quit = true; + } + function push(item){stack.push(item);} + function accept(){ + groups[0].end = pos; + var result = new Array(1 + groups.length * 2); + result[0] = 0; + for(var i = 0; i < groups.length; i++){ + var g = groups[i]; + if(g.start < 0 || g.end < 0) g.start = g.end = - 1; + result[2 * i + 1] = g.start; + result[2 * i + 1 + 1] = g.end; + } + return result; + } + function prefix_match(){ + if(partial) return accept(); else backtrack(); + } + while(! quit){ + var + op = prog[pc] & 0xff, + sarg = prog[pc] >> 8, + uarg = sarg & 0xff, + c = s[pos], + group; + pc++; + switch(op){ + case opcodes.CHAR: + if(pos === s.length){prefix_match(); break;} + if(c === uarg) pos++; else backtrack(); + break; + case opcodes.CHARNORM: + if(pos === s.length){prefix_match(); break;} + if(normtable.charCodeAt(c) === uarg) pos++; else backtrack(); + break; + case opcodes.STRING: + for + (var arg = caml_jsbytes_of_string(cpool[uarg]), i = 0; + i < arg.length; + i++){ + if(pos === s.length){prefix_match(); break;} + if(c === arg.charCodeAt(i)) + c = s[++pos]; + else{backtrack(); break;} + } + break; + case opcodes.STRINGNORM: + for + (var arg = caml_jsbytes_of_string(cpool[uarg]), i = 0; + i < arg.length; + i++){ + if(pos === s.length){prefix_match(); break;} + if(normtable.charCodeAt(c) === arg.charCodeAt(i)) + c = s[++pos]; + else{backtrack(); break;} + } + break; + case opcodes.CHARCLASS: + if(pos === s.length){prefix_match(); break;} + if(in_bitset(cpool[uarg], c)) pos++; else backtrack(); + break; + case opcodes.BOL: + if(pos > 0 && s[pos - 1] != 10) backtrack(); break; + case opcodes.EOL: + if(pos < s.length && s[pos] != 10) backtrack(); break; + case opcodes.WORDBOUNDARY: + if(pos == 0){ + if(pos === s.length){prefix_match(); break;} + if(is_word_letter(s[0])) break; + backtrack(); + } + else if(pos === s.length){ + if(is_word_letter(s[pos - 1])) break; + backtrack(); + } + else{ + if(is_word_letter(s[pos - 1]) != is_word_letter(s[pos])) break; + backtrack(); + } + break; + case opcodes.BEGGROUP: + group = groups[uarg]; + push({undo: {obj: group, prop: "start", value: group.start}}); + group.start = pos; + break; + case opcodes.ENDGROUP: + group = groups[uarg]; + push({undo: {obj: group, prop: "end", value: group.end}}); + group.end = pos; + break; + case opcodes.REFGROUP: + group = groups[uarg]; + if(group.start < 0 || group.end < 0){backtrack(); break;} + for(var i = group.start; i < group.end; i++){ + if(pos === s.length){prefix_match(); break;} + if(s[i] != s[pos]){backtrack(); break;} + pos++; + } + break; + case opcodes.SIMPLEOPT: + if(in_bitset(cpool[uarg], c)) pos++; break; + case opcodes.SIMPLESTAR: + while(in_bitset(cpool[uarg], c)) c = s[++pos]; break; + case opcodes.SIMPLEPLUS: + if(pos === s.length){prefix_match(); break;} + if(in_bitset(cpool[uarg], c)) + do c = s[++pos];while(in_bitset(cpool[uarg], c)); + else + backtrack(); + break; + case opcodes.ACCEPT: return accept(); + case opcodes.GOTO: + pc = pc + sarg; break; + case opcodes.PUSHBACK: + push({pos: {pc: pc + sarg, txt: pos}}); break; + case opcodes.SETMARK: + push + ({undo: {obj: re_register, prop: uarg, value: re_register[uarg]}}); + re_register[uarg] = pos; + break; + case opcodes.CHECKPROGRESS: + if(re_register[uarg] === pos) backtrack(); break; + default: throw new Error("Invalid bytecode"); + } + } + return 0; + } + return re_match_impl; + } + (); + function re_partial_match(re, s, pos){ + if(pos < 0 || pos > caml_ml_string_length(s)) + caml_invalid_argument("Str.partial_match"); + var res = re_match(re, s, pos, 1); + return res ? res : [0]; + } + function re_replacement_text(repl, groups, orig){ + var + repl = caml_jsbytes_of_string(repl), + len = repl.length, + orig = caml_jsbytes_of_string(orig), + res = "", + n = 0, + cur, + start, + end, + c; + while(n < len){ + cur = repl.charAt(n++); + if(cur != "\\") + res += cur; + else{ + if(n == len) caml_failwith("Str.replace: illegal backslash sequence"); + cur = repl.charAt(n++); + switch(cur){ + case "\\": + res += cur; break; + case "0": + case "1": + case "2": + case "3": + case "4": + case "5": + case "6": + case "7": + case "8": + case "9": + c = + cur; + if(c * 2 >= groups.length - 1) + caml_failwith("Str.replace: reference to unmatched group"); + start = caml_array_get(groups, c * 2); + end = caml_array_get(groups, c * 2 + 1); + if(start == - 1) + caml_failwith("Str.replace: reference to unmatched group"); + res += orig.slice(start, end); + break; + default: res += "\\" + cur; + } + } + } + return caml_string_of_jsbytes(res); + } + function re_search_backward(re, s, pos){ + if(pos < 0 || pos > caml_ml_string_length(s)) + caml_invalid_argument("Str.search_backward"); + while(pos >= 0){ + var res = re_match(re, s, pos, 0); + if(res) return res; + pos--; + } + return [0]; + } + function re_search_forward(re, s, pos){ + if(pos < 0 || pos > caml_ml_string_length(s)) + caml_invalid_argument("Str.search_forward"); + while(pos <= caml_ml_string_length(s)){ + var res = re_match(re, s, pos, 0); + if(res) return res; + pos++; + } + return [0]; + } + function re_string_match(re, s, pos){ + if(pos < 0 || pos > caml_ml_string_length(s)) + caml_invalid_argument("Str.string_match"); + var res = re_match(re, s, pos, 0); + return res ? res : [0]; + } + function set_digit_nat(nat, ofs, digit){nat.data[ofs] = digit; return 0;} + function set_digit_nat_native(nat, ofs, digit){nat.data[ofs] = digit; return 0; + } + function square_nat(nat1, ofs1, len1, nat2, ofs2, len2){ + var carry = 0; + carry += add_nat(nat1, ofs1, len1, nat1, ofs1, len1, 0); + carry += mult_nat(nat1, ofs1, len1, nat2, ofs2, len2, nat2, ofs2, len2); + return carry; + } + function caml_setup_uncaught_exception_handler(){ + var process = globalThis.process; + if(process && process.on) + process.on + ("uncaughtException", + function(err, origin){ + caml_fatal_uncaught_exception(err); + process.exit(2); + }); + else if(globalThis.addEventListener) + globalThis.addEventListener + ("error", + function(event){ + if(event.error) caml_fatal_uncaught_exception(event.error); + }); + } + caml_setup_uncaught_exception_handler(); + globalThis.jsoo_runtime = + {bigstringaf_memchr: bigstringaf_memchr, + bigstringaf_memcmp_string: bigstringaf_memcmp_string, + bigstringaf_memcmp_bigstring: bigstringaf_memcmp_bigstring, + bigstringaf_blit_from_bytes: bigstringaf_blit_from_bytes, + bigstringaf_blit_to_bigstring: bigstringaf_blit_to_bigstring, + bigstringaf_blit_to_bytes: bigstringaf_blit_to_bytes, + caml_runtime_events_read_poll: caml_runtime_events_read_poll, + caml_runtime_events_free_cursor: caml_runtime_events_free_cursor, + caml_runtime_events_create_cursor: caml_runtime_events_create_cursor, + caml_ml_runtime_events_resume: caml_ml_runtime_events_resume, + caml_ml_runtime_events_pause: caml_ml_runtime_events_pause, + caml_ml_runtime_events_start: caml_ml_runtime_events_start, + caml_runtime_events_user_resolve: caml_runtime_events_user_resolve, + caml_runtime_events_user_write: caml_runtime_events_user_write, + caml_runtime_events_user_register: caml_runtime_events_user_register, + caml_custom_event_index: caml_custom_event_index, + caml_decompress_input: caml_decompress_input, + jsoo_effect_not_supported: jsoo_effect_not_supported, + caml_ml_condition_signal: caml_ml_condition_signal, + caml_ml_condition_broadcast: caml_ml_condition_broadcast, + caml_ml_condition_wait: caml_ml_condition_wait, + caml_ml_condition_new: caml_ml_condition_new, + caml_get_continuation_callstack: caml_get_continuation_callstack, + caml_continuation_use_and_update_handler_noexc: + caml_continuation_use_and_update_handler_noexc, + caml_continuation_use_noexc: caml_continuation_use_noexc, + caml_alloc_stack: caml_alloc_stack, + caml_ml_mutex_unlock: caml_ml_mutex_unlock, + caml_ml_mutex_try_lock: caml_ml_mutex_try_lock, + caml_ml_mutex_lock: caml_ml_mutex_lock, + caml_ml_mutex_new: caml_ml_mutex_new, + MlMutex: MlMutex, + caml_lxm_next: caml_lxm_next, + caml_ml_domain_cpu_relax: caml_ml_domain_cpu_relax, + caml_ml_domain_id: caml_ml_domain_id, + caml_domain_spawn: caml_domain_spawn, + caml_domain_id: caml_domain_id, + caml_recommended_domain_count: caml_recommended_domain_count, + caml_ml_domain_set_name: caml_ml_domain_set_name, + caml_ml_domain_unique_token: caml_ml_domain_unique_token, + caml_atomic_make_contended: caml_atomic_make_contended, + caml_atomic_exchange: caml_atomic_exchange, + caml_atomic_fetch_add: caml_atomic_fetch_add, + caml_atomic_cas: caml_atomic_cas, + caml_atomic_load: caml_atomic_load, + caml_domain_dls_get: caml_domain_dls_get, + caml_domain_dls_set: caml_domain_dls_set, + caml_domain_dls: caml_domain_dls, + caml_ephe_check_data: caml_ephe_check_data, + caml_ephe_unset_data: caml_ephe_unset_data, + caml_ephe_set_data: caml_ephe_set_data, + caml_ephe_get_data_copy: caml_ephe_get_data_copy, + caml_ephe_get_data: caml_ephe_get_data, + caml_ephe_blit_data: caml_ephe_blit_data, + caml_ephe_blit_key: caml_ephe_blit_key, + caml_ephe_check_key: caml_ephe_check_key, + caml_ephe_get_key_copy: caml_ephe_get_key_copy, + caml_ephe_get_key: caml_ephe_get_key, + caml_weak_set: caml_weak_set, + caml_weak_create: caml_weak_create, + caml_ephe_create: caml_ephe_create, + caml_ephe_unset_key: caml_ephe_unset_key, + caml_ephe_set_key: caml_ephe_set_key, + caml_ephe_data_offset: caml_ephe_data_offset, + caml_ephe_key_offset: caml_ephe_key_offset, + caml_unix_inet_addr_of_string: caml_unix_inet_addr_of_string, + caml_unix_findclose: caml_unix_findclose, + caml_unix_findnext: caml_unix_findnext, + caml_unix_findfirst: caml_unix_findfirst, + caml_unix_rewinddir: caml_unix_rewinddir, + caml_unix_closedir: caml_unix_closedir, + caml_unix_readdir: caml_unix_readdir, + caml_unix_opendir: caml_unix_opendir, + caml_unix_has_symlink: caml_unix_has_symlink, + caml_unix_getpwuid: caml_unix_getpwuid, + caml_unix_getuid: caml_unix_getuid, + caml_unix_unlink: caml_unix_unlink, + caml_unix_readlink: caml_unix_readlink, + caml_unix_symlink: caml_unix_symlink, + caml_unix_rmdir: caml_unix_rmdir, + caml_unix_mkdir: caml_unix_mkdir, + caml_unix_lstat_64: caml_unix_lstat_64, + caml_unix_lstat: caml_unix_lstat, + caml_unix_stat_64: caml_unix_stat_64, + caml_unix_stat: caml_unix_stat, + make_unix_err_args: make_unix_err_args, + caml_unix_isatty: caml_unix_isatty, + caml_unix_filedescr_of_fd: caml_unix_filedescr_of_fd, + caml_unix_cleanup: caml_unix_cleanup, + caml_unix_startup: caml_unix_startup, + caml_unix_mktime: caml_unix_mktime, + caml_unix_localtime: caml_unix_localtime, + caml_unix_gmtime: caml_unix_gmtime, + caml_unix_time: caml_unix_time, + caml_unix_gettimeofday: caml_unix_gettimeofday, + caml_str_initialize: caml_str_initialize, + re_replacement_text: re_replacement_text, + re_partial_match: re_partial_match, + re_string_match: re_string_match, + re_search_backward: re_search_backward, + re_search_forward: re_search_forward, + re_match: re_match, + caml_sys_is_regular_file: caml_sys_is_regular_file, + caml_spacetime_only_works_for_native_code: + caml_spacetime_only_works_for_native_code, + caml_register_channel_for_spacetime: caml_register_channel_for_spacetime, + caml_sys_const_naked_pointers_checked: + caml_sys_const_naked_pointers_checked, + caml_spacetime_enabled: caml_spacetime_enabled, + caml_ml_runtime_warnings_enabled: caml_ml_runtime_warnings_enabled, + caml_ml_enable_runtime_warnings: caml_ml_enable_runtime_warnings, + caml_runtime_warnings: caml_runtime_warnings, + caml_install_signal_handler: caml_install_signal_handler, + caml_runtime_parameters: caml_runtime_parameters, + caml_runtime_variant: caml_runtime_variant, + caml_sys_isatty: caml_sys_isatty, + caml_sys_get_config: caml_sys_get_config, + os_type: os_type, + caml_sys_const_backend_type: caml_sys_const_backend_type, + caml_sys_const_ostype_cygwin: caml_sys_const_ostype_cygwin, + caml_sys_const_ostype_win32: caml_sys_const_ostype_win32, + caml_sys_const_ostype_unix: caml_sys_const_ostype_unix, + caml_sys_const_max_wosize: caml_sys_const_max_wosize, + caml_sys_const_int_size: caml_sys_const_int_size, + caml_sys_const_word_size: caml_sys_const_word_size, + caml_sys_const_big_endian: caml_sys_const_big_endian, + caml_sys_random_seed: caml_sys_random_seed, + caml_sys_time_include_children: caml_sys_time_include_children, + caml_sys_time: caml_sys_time, + caml_sys_system_command: caml_sys_system_command, + caml_sys_executable_name: caml_sys_executable_name, + caml_sys_modify_argv: caml_sys_modify_argv, + caml_sys_argv: caml_sys_argv, + caml_sys_get_argv: caml_sys_get_argv, + caml_executable_name: caml_executable_name, + caml_argv: caml_argv, + caml_sys_unsafe_getenv: caml_sys_unsafe_getenv, + caml_sys_getenv: caml_sys_getenv, + jsoo_sys_getenv: jsoo_sys_getenv, + caml_set_static_env: caml_set_static_env, + caml_fatal_uncaught_exception: caml_fatal_uncaught_exception, + caml_format_exception: caml_format_exception, + caml_is_special_exception: caml_is_special_exception, + caml_sys_exit: caml_sys_exit, + caml_raise_sys_error: caml_raise_sys_error, + caml_maybe_print_stats: caml_maybe_print_stats, + caml_is_printable: caml_is_printable, + caml_get_global_data: caml_get_global_data, + caml_register_global: caml_register_global, + caml_build_symbols: caml_build_symbols, + caml_global_data: caml_global_data, + caml_named_value: caml_named_value, + caml_register_named_value: caml_register_named_value, + caml_named_values: caml_named_values, + caml_call_gen: caml_call_gen, + caml_set_parser_trace: caml_set_parser_trace, + caml_parse_engine: caml_parse_engine, + caml_parser_trace: caml_parser_trace, + caml_is_continuation_tag: caml_is_continuation_tag, + caml_lazy_read_result: caml_lazy_read_result, + caml_lazy_reset_to_lazy: caml_lazy_reset_to_lazy, + caml_lazy_update_to_forward: caml_lazy_update_to_forward, + caml_lazy_update_to_forcing: caml_lazy_update_to_forcing, + caml_obj_update_tag: caml_obj_update_tag, + caml_obj_add_offset: caml_obj_add_offset, + caml_obj_reachable_words: caml_obj_reachable_words, + caml_obj_set_raw_field: caml_obj_set_raw_field, + caml_obj_raw_field: caml_obj_raw_field, + caml_fresh_oo_id: caml_fresh_oo_id, + caml_set_oo_id: caml_set_oo_id, + caml_oo_last_id: caml_oo_last_id, + caml_get_public_method: caml_get_public_method, + caml_lazy_make_forward: caml_lazy_make_forward, + caml_obj_is_shared: caml_obj_is_shared, + caml_obj_compare_and_swap: caml_obj_compare_and_swap, + caml_obj_make_forward: caml_obj_make_forward, + caml_obj_truncate: caml_obj_truncate, + caml_obj_dup: caml_obj_dup, + caml_obj_with_tag: caml_obj_with_tag, + caml_obj_block: caml_obj_block, + caml_obj_set_tag: caml_obj_set_tag, + caml_obj_tag: caml_obj_tag, + caml_obj_is_block: caml_obj_is_block, + caml_alloc_dummy_infix: caml_alloc_dummy_infix, + caml_update_dummy: caml_update_dummy, + deserialize_nat: deserialize_nat, + serialize_nat: serialize_nat, + lxor_digit_nat: lxor_digit_nat, + lor_digit_nat: lor_digit_nat, + land_digit_nat: land_digit_nat, + compare_nat_real: compare_nat_real, + compare_nat: compare_nat, + compare_digits_nat: compare_digits_nat, + shift_right_nat: shift_right_nat, + div_nat: div_nat, + div_digit_nat: div_digit_nat, + div_helper: div_helper, + shift_left_nat: shift_left_nat, + square_nat: square_nat, + mult_nat: mult_nat, + mult_digit_nat: mult_digit_nat, + sub_nat: sub_nat, + decr_nat: decr_nat, + complement_nat: complement_nat, + add_nat: add_nat, + incr_nat: incr_nat, + is_digit_odd: is_digit_odd, + is_digit_zero: is_digit_zero, + is_digit_int: is_digit_int, + num_leading_zero_bits_in_digit: num_leading_zero_bits_in_digit, + num_digits_nat: num_digits_nat, + nth_digit_nat_native: nth_digit_nat_native, + set_digit_nat_native: set_digit_nat_native, + nth_digit_nat: nth_digit_nat, + set_digit_nat: set_digit_nat, + blit_nat: blit_nat, + set_to_zero_nat: set_to_zero_nat, + create_nat: create_nat, + nat_of_array: nat_of_array, + length_nat: length_nat, + caml_hash_nat: caml_hash_nat, + MlNat: MlNat, + initialize_nat: initialize_nat, + caml_array_of_bytes: caml_array_of_bytes, + caml_array_of_string: caml_array_of_string, + caml_js_to_string: caml_js_to_string, + caml_to_js_string: caml_to_js_string, + caml_js_from_string: caml_js_from_string, + caml_new_string: caml_new_string, + caml_js_to_byte_string: caml_js_to_byte_string, + caml_is_ml_string: caml_is_ml_string, + caml_ml_bytes_content: caml_ml_bytes_content, + caml_is_ml_bytes: caml_is_ml_bytes, + caml_bytes_of_jsbytes: caml_bytes_of_jsbytes, + caml_string_of_jsstring: caml_string_of_jsstring, + caml_jsstring_of_string: caml_jsstring_of_string, + caml_jsbytes_of_string: caml_jsbytes_of_string, + caml_string_of_jsbytes: caml_string_of_jsbytes, + caml_bytes_of_string: caml_bytes_of_string, + caml_string_of_bytes: caml_string_of_bytes, + caml_string_lessthan: caml_string_lessthan, + caml_string_lessequal: caml_string_lessequal, + caml_string_equal: caml_string_equal, + caml_string_compare: caml_string_compare, + caml_ml_string_length: caml_ml_string_length, + caml_string_unsafe_set: caml_string_unsafe_set, + caml_string_unsafe_get: caml_string_unsafe_get, + caml_string_concat: caml_string_concat, + caml_ml_bytes_length: caml_ml_bytes_length, + caml_blit_string: caml_blit_string, + caml_blit_bytes: caml_blit_bytes, + caml_fill_bytes: caml_fill_bytes, + caml_bytes_greaterthan: caml_bytes_greaterthan, + caml_string_greaterthan: caml_string_greaterthan, + caml_bytes_greaterequal: caml_bytes_greaterequal, + caml_string_greaterequal: caml_string_greaterequal, + caml_bytes_lessthan: caml_bytes_lessthan, + caml_bytes_lessequal: caml_bytes_lessequal, + caml_bytes_notequal: caml_bytes_notequal, + caml_string_notequal: caml_string_notequal, + caml_bytes_equal: caml_bytes_equal, + caml_bytes_compare: caml_bytes_compare, + caml_bytes_of_array: caml_bytes_of_array, + caml_string_of_array: caml_string_of_array, + caml_create_bytes: caml_create_bytes, + caml_create_string: caml_create_string, + caml_uint8_array_of_string: caml_uint8_array_of_string, + caml_uint8_array_of_bytes: caml_uint8_array_of_bytes, + caml_convert_bytes_to_array: caml_convert_bytes_to_array, + caml_convert_string_to_bytes: caml_convert_string_to_bytes, + MlBytes: MlBytes, + caml_bytes_of_utf16_jsstring: caml_bytes_of_utf16_jsstring, + caml_bytes_set: caml_bytes_set, + caml_string_set64: caml_string_set64, + caml_bytes_set64: caml_bytes_set64, + caml_string_set32: caml_string_set32, + caml_bytes_set32: caml_bytes_set32, + caml_string_set16: caml_string_set16, + caml_bytes_set16: caml_bytes_set16, + caml_string_set: caml_string_set, + caml_bytes_get: caml_bytes_get, + caml_bytes_get64: caml_bytes_get64, + caml_string_get64: caml_string_get64, + caml_bytes_get32: caml_bytes_get32, + caml_string_get32: caml_string_get32, + caml_bytes_get16: caml_bytes_get16, + caml_string_get16: caml_string_get16, + caml_string_get: caml_string_get, + caml_bytes_bound_error: caml_bytes_bound_error, + caml_string_bound_error: caml_string_bound_error, + caml_bytes_unsafe_set: caml_bytes_unsafe_set, + caml_bytes_unsafe_get: caml_bytes_unsafe_get, + jsoo_is_ascii: jsoo_is_ascii, + caml_utf16_of_utf8: caml_utf16_of_utf8, + caml_utf8_of_utf16: caml_utf8_of_utf16, + caml_subarray_to_jsbytes: caml_subarray_to_jsbytes, + caml_str_repeat: caml_str_repeat, + caml_md5_bytes: caml_md5_bytes, + caml_MD5Final: caml_MD5Final, + caml_MD5Update: caml_MD5Update, + caml_MD5Init: caml_MD5Init, + caml_MD5Transform: caml_MD5Transform, + caml_md5_string: caml_md5_string, + caml_md5_chan: caml_md5_chan, + caml_output_value_to_buffer: caml_output_value_to_buffer, + caml_output_value_to_bytes: caml_output_value_to_bytes, + caml_output_value_to_string: caml_output_value_to_string, + caml_output_val: caml_output_val, + MlObjectTable: MlObjectTable, + caml_marshal_data_size: caml_marshal_data_size, + caml_marshal_header_size: caml_marshal_header_size, + caml_input_value_from_reader: caml_input_value_from_reader, + caml_custom_ops: caml_custom_ops, + caml_nativeint_unmarshal: caml_nativeint_unmarshal, + caml_int32_unmarshal: caml_int32_unmarshal, + caml_int64_marshal: caml_int64_marshal, + caml_int64_unmarshal: caml_int64_unmarshal, + caml_input_value_from_bytes: caml_input_value_from_bytes, + caml_input_value_from_string: caml_input_value_from_string, + caml_float_of_bytes: caml_float_of_bytes, + BigStringReader: BigStringReader, + MlStringReader: MlStringReader, + UInt8ArrayReader: UInt8ArrayReader, + caml_marshal_constants: caml_marshal_constants, + caml_new_lex_engine: caml_new_lex_engine, + caml_lex_engine: caml_lex_engine, + caml_lex_array: caml_lex_array, + caml_js_error_of_exception: caml_js_error_of_exception, + caml_xmlhttprequest_create: caml_xmlhttprequest_create, + caml_js_get_console: caml_js_get_console, + caml_js_html_entities: caml_js_html_entities, + caml_js_html_escape: caml_js_html_escape, + caml_js_on_ie: caml_js_on_ie, + caml_js_object: caml_js_object, + caml_pure_js_expr: caml_pure_js_expr, + caml_js_expr: caml_js_expr, + caml_js_eval_string: caml_js_eval_string, + caml_js_strict_equals: caml_js_strict_equals, + caml_js_equals: caml_js_equals, + caml_js_function_arity: caml_js_function_arity, + caml_js_wrap_meth_callback_unsafe: caml_js_wrap_meth_callback_unsafe, + caml_js_wrap_meth_callback_strict: caml_js_wrap_meth_callback_strict, + caml_js_wrap_meth_callback_arguments: + caml_js_wrap_meth_callback_arguments, + caml_js_wrap_meth_callback: caml_js_wrap_meth_callback, + caml_js_wrap_callback_unsafe: caml_js_wrap_callback_unsafe, + caml_js_wrap_callback_strict: caml_js_wrap_callback_strict, + caml_js_wrap_callback_arguments: caml_js_wrap_callback_arguments, + caml_js_wrap_callback: caml_js_wrap_callback, + caml_ojs_new_arr: caml_ojs_new_arr, + caml_js_new: caml_js_new, + caml_js_meth_call: caml_js_meth_call, + caml_js_fun_call: caml_js_fun_call, + caml_js_call: caml_js_call, + caml_js_var: caml_js_var, + caml_list_to_js_array: caml_list_to_js_array, + caml_list_of_js_array: caml_list_of_js_array, + caml_js_to_array: caml_js_to_array, + caml_js_from_array: caml_js_from_array, + caml_js_to_int32: caml_js_to_int32, + caml_js_to_float: caml_js_to_float, + caml_js_from_float: caml_js_from_float, + caml_js_to_bool: caml_js_to_bool, + caml_js_from_bool: caml_js_from_bool, + caml_js_error_option_of_exception: caml_js_error_option_of_exception, + caml_exn_with_js_backtrace: caml_exn_with_js_backtrace, + caml_maybe_attach_backtrace: caml_maybe_attach_backtrace, + caml_wrap_exception: caml_wrap_exception, + caml_jsoo_flags_effects: caml_jsoo_flags_effects, + caml_jsoo_flags_use_js_string: caml_jsoo_flags_use_js_string, + caml_is_js: caml_is_js, + caml_callback: caml_callback, + caml_trampoline_return: caml_trampoline_return, + caml_trampoline: caml_trampoline, + caml_js_typeof: caml_js_typeof, + caml_js_instanceof: caml_js_instanceof, + caml_js_delete: caml_js_delete, + caml_js_get: caml_js_get, + caml_js_set: caml_js_set, + caml_js_pure_expr: caml_js_pure_expr, + caml_ml_set_buffered: caml_ml_set_buffered, + caml_ml_is_buffered: caml_ml_is_buffered, + caml_ml_output_int: caml_ml_output_int, + caml_ml_pos_out_64: caml_ml_pos_out_64, + caml_ml_pos_out: caml_ml_pos_out, + caml_pos_out: caml_pos_out, + caml_ml_seek_out_64: caml_ml_seek_out_64, + caml_ml_seek_out: caml_ml_seek_out, + caml_seek_out: caml_seek_out, + caml_output_value: caml_output_value, + caml_ml_output_char: caml_ml_output_char, + caml_ml_output: caml_ml_output, + caml_ml_output_bigarray: caml_ml_output_bigarray, + caml_ml_output_bytes: caml_ml_output_bytes, + caml_ml_output_ta: caml_ml_output_ta, + caml_ml_flush: caml_ml_flush, + caml_ml_input_scan_line: caml_ml_input_scan_line, + caml_ml_pos_in_64: caml_ml_pos_in_64, + caml_ml_pos_in: caml_ml_pos_in, + caml_pos_in: caml_pos_in, + caml_ml_seek_in_64: caml_ml_seek_in_64, + caml_ml_seek_in: caml_ml_seek_in, + caml_seek_in: caml_seek_in, + caml_ml_input_int: caml_ml_input_int, + caml_ml_input_char: caml_ml_input_char, + caml_input_value_to_outside_heap: caml_input_value_to_outside_heap, + caml_input_value: caml_input_value, + caml_ml_input_block: caml_ml_input_block, + caml_ml_input_bigarray: caml_ml_input_bigarray, + caml_ml_input: caml_ml_input, + caml_refill: caml_refill, + caml_ml_set_channel_refill: caml_ml_set_channel_refill, + caml_ml_set_channel_output: caml_ml_set_channel_output, + caml_ml_channel_size_64: caml_ml_channel_size_64, + caml_ml_channel_size: caml_ml_channel_size, + caml_ml_close_channel: caml_ml_close_channel, + caml_ml_set_binary_mode: caml_ml_set_binary_mode, + caml_channel_descriptor: caml_channel_descriptor, + caml_ml_open_descriptor_in: caml_ml_open_descriptor_in, + caml_ml_open_descriptor_out: caml_ml_open_descriptor_out, + caml_ml_out_channels_list: caml_ml_out_channels_list, + caml_ml_channel_get: caml_ml_channel_get, + caml_ml_channel_restore: caml_ml_channel_restore, + caml_ml_channel_redirect: caml_ml_channel_redirect, + caml_ml_channels: caml_ml_channels, + caml_ml_set_channel_name: caml_ml_set_channel_name, + caml_sys_open: caml_sys_open, + caml_sys_close: caml_sys_close, + caml_sys_fds: caml_sys_fds, + caml_int64_bswap: caml_int64_bswap, + caml_int32_bswap: caml_int32_bswap, + caml_bswap16: caml_bswap16, + caml_mod: caml_mod, + caml_div: caml_div, + caml_mul: caml_mul, + caml_int_of_string: caml_int_of_string, + caml_parse_digit: caml_parse_digit, + caml_parse_sign_and_base: caml_parse_sign_and_base, + caml_format_int: caml_format_int, + caml_int64_hash: caml_int64_hash, + caml_int64_to_bytes: caml_int64_to_bytes, + caml_int64_of_bytes: caml_int64_of_bytes, + caml_int64_hi32: caml_int64_hi32, + caml_int64_lo32: caml_int64_lo32, + caml_int64_create_lo_hi: caml_int64_create_lo_hi, + caml_int64_create_lo_mi_hi: caml_int64_create_lo_mi_hi, + caml_int64_of_string: caml_int64_of_string, + caml_int64_format: caml_int64_format, + caml_int64_of_float: caml_int64_of_float, + caml_int64_to_float: caml_int64_to_float, + caml_int64_to_int32: caml_int64_to_int32, + caml_int64_of_int32: caml_int64_of_int32, + caml_int64_mod: caml_int64_mod, + caml_int64_div: caml_int64_div, + caml_int64_shift_right: caml_int64_shift_right, + caml_int64_shift_right_unsigned: caml_int64_shift_right_unsigned, + caml_int64_shift_left: caml_int64_shift_left, + caml_int64_xor: caml_int64_xor, + caml_int64_or: caml_int64_or, + caml_int64_and: caml_int64_and, + caml_int64_is_negative: caml_int64_is_negative, + caml_int64_is_zero: caml_int64_is_zero, + caml_int64_mul: caml_int64_mul, + caml_int64_sub: caml_int64_sub, + caml_int64_add: caml_int64_add, + caml_int64_neg: caml_int64_neg, + caml_int64_compare: caml_int64_compare, + caml_int64_ult: caml_int64_ult, + MlInt64: MlInt64, + caml_int64_offset: caml_int64_offset, + caml_float_of_string: caml_float_of_string, + caml_format_float: caml_format_float, + caml_fma_float: caml_fma_float, + caml_erfc_float: caml_erfc_float, + caml_erf_float: caml_erf_float, + caml_cbrt_float: caml_cbrt_float, + caml_round_float: caml_round_float, + caml_atanh_float: caml_atanh_float, + caml_tanh_float: caml_tanh_float, + caml_asinh_float: caml_asinh_float, + caml_sinh_float: caml_sinh_float, + caml_acosh_float: caml_acosh_float, + caml_cosh_float: caml_cosh_float, + caml_log10_float: caml_log10_float, + caml_hypot_float: caml_hypot_float, + caml_log2_float: caml_log2_float, + caml_log1p_float: caml_log1p_float, + caml_exp2_float: caml_exp2_float, + caml_expm1_float: caml_expm1_float, + caml_signbit_float: caml_signbit_float, + caml_copysign_float: caml_copysign_float, + caml_float_compare: caml_float_compare, + caml_frexp_float: caml_frexp_float, + caml_ldexp_float: caml_ldexp_float, + caml_modf_float: caml_modf_float, + caml_classify_float: caml_classify_float, + caml_int32_float_of_bits: caml_int32_float_of_bits, + caml_trunc_float: caml_trunc_float, + caml_nextafter_float: caml_nextafter_float, + caml_int64_float_of_bits: caml_int64_float_of_bits, + caml_hexstring_of_float: caml_hexstring_of_float, + caml_int32_bits_of_float: caml_int32_bits_of_float, + caml_int64_bits_of_float: caml_int64_bits_of_float, + jsoo_floor_log2: jsoo_floor_log2, + caml_string_hash: caml_string_hash, + caml_hash: caml_hash, + caml_hash_mix_string: caml_hash_mix_string, + caml_hash_mix_bytes: caml_hash_mix_bytes, + caml_hash_mix_bytes_arr: caml_hash_mix_bytes_arr, + caml_hash_mix_jsbytes: caml_hash_mix_jsbytes, + caml_hash_mix_int64: caml_hash_mix_int64, + caml_hash_mix_float: caml_hash_mix_float, + caml_hash_mix_final: caml_hash_mix_final, + caml_hash_mix_int: caml_hash_mix_int, + caml_gr_close_subwindow: caml_gr_close_subwindow, + caml_gr_open_subwindow: caml_gr_open_subwindow, + caml_gr_window_id: caml_gr_window_id, + caml_gr_display_mode: caml_gr_display_mode, + caml_gr_remember_mode: caml_gr_remember_mode, + caml_gr_synchronize: caml_gr_synchronize, + caml_gr_wait_event: caml_gr_wait_event, + caml_gr_sigio_signal: caml_gr_sigio_signal, + caml_gr_sigio_handler: caml_gr_sigio_handler, + caml_gr_blit_image: caml_gr_blit_image, + caml_gr_create_image: caml_gr_create_image, + caml_gr_draw_image: caml_gr_draw_image, + caml_gr_dump_image: caml_gr_dump_image, + caml_gr_make_image: caml_gr_make_image, + caml_gr_text_size: caml_gr_text_size, + caml_gr_set_text_size: caml_gr_set_text_size, + caml_gr_set_font: caml_gr_set_font, + caml_gr_draw_string: caml_gr_draw_string, + caml_gr_draw_char: caml_gr_draw_char, + caml_gr_draw_str: caml_gr_draw_str, + caml_gr_fill_arc: caml_gr_fill_arc, + caml_gr_fill_poly: caml_gr_fill_poly, + caml_gr_fill_rect: caml_gr_fill_rect, + caml_gr_set_line_width: caml_gr_set_line_width, + caml_gr_draw_arc: caml_gr_draw_arc, + caml_gr_arc_aux: caml_gr_arc_aux, + caml_gr_draw_rect: caml_gr_draw_rect, + caml_gr_lineto: caml_gr_lineto, + caml_gr_current_y: caml_gr_current_y, + caml_gr_current_x: caml_gr_current_x, + caml_gr_moveto: caml_gr_moveto, + caml_gr_point_color: caml_gr_point_color, + caml_gr_plot: caml_gr_plot, + caml_gr_set_color: caml_gr_set_color, + caml_gr_size_y: caml_gr_size_y, + caml_gr_size_x: caml_gr_size_x, + caml_gr_clear_graph: caml_gr_clear_graph, + caml_gr_resize_window: caml_gr_resize_window, + caml_gr_set_window_title: caml_gr_set_window_title, + caml_gr_close_graph: caml_gr_close_graph, + caml_gr_doc_of_state: caml_gr_doc_of_state, + caml_gr_state_create: caml_gr_state_create, + caml_gr_state_init: caml_gr_state_init, + caml_gr_open_graph: caml_gr_open_graph, + caml_gr_state_set: caml_gr_state_set, + caml_gr_state_get: caml_gr_state_get, + caml_gr_state: caml_gr_state, + caml_get_major_credit: caml_get_major_credit, + caml_get_major_bucket: caml_get_major_bucket, + caml_get_minor_free: caml_get_minor_free, + caml_gc_minor_words: caml_gc_minor_words, + caml_gc_major_slice: caml_gc_major_slice, + caml_gc_huge_fallback_count: caml_gc_huge_fallback_count, + caml_eventlog_pause: caml_eventlog_pause, + caml_eventlog_resume: caml_eventlog_resume, + caml_memprof_discard: caml_memprof_discard, + caml_memprof_stop: caml_memprof_stop, + caml_memprof_start: caml_memprof_start, + caml_final_release: caml_final_release, + caml_final_register_called_without_value: + caml_final_register_called_without_value, + caml_final_register: caml_final_register, + caml_memprof_set: caml_memprof_set, + caml_gc_get: caml_gc_get, + caml_gc_set: caml_gc_set, + caml_gc_stat: caml_gc_stat, + caml_gc_quick_stat: caml_gc_quick_stat, + caml_gc_counters: caml_gc_counters, + caml_gc_compaction: caml_gc_compaction, + caml_gc_full_major: caml_gc_full_major, + caml_gc_major: caml_gc_major, + caml_gc_minor: caml_gc_minor, + caml_sys_open_for_node: caml_sys_open_for_node, + MlNodeFd: MlNodeFd, + MlNodeDevice: MlNodeDevice, + fs_node_supported: fs_node_supported, + MlFakeFd: MlFakeFd, + MlFakeFd_out: MlFakeFd_out, + MlFakeFile: MlFakeFile, + MlFakeDevice: MlFakeDevice, + caml_read_file_content: caml_read_file_content, + jsoo_create_file: jsoo_create_file, + caml_create_file: caml_create_file, + caml_fs_init: caml_fs_init, + jsoo_create_file_extern: jsoo_create_file_extern, + caml_ba_map_file_bytecode: caml_ba_map_file_bytecode, + caml_ba_map_file: caml_ba_map_file, + caml_sys_rmdir: caml_sys_rmdir, + caml_sys_mkdir: caml_sys_mkdir, + caml_sys_rename: caml_sys_rename, + caml_sys_is_directory: caml_sys_is_directory, + caml_sys_remove: caml_sys_remove, + caml_sys_read_directory: caml_sys_read_directory, + caml_sys_file_exists: caml_sys_file_exists, + caml_raise_not_a_dir: caml_raise_not_a_dir, + caml_raise_no_such_file: caml_raise_no_such_file, + caml_sys_chdir: caml_sys_chdir, + caml_sys_getcwd: caml_sys_getcwd, + caml_unmount: caml_unmount, + caml_mount_autoload: caml_mount_autoload, + resolve_fs_device: resolve_fs_device, + caml_list_mount_point: caml_list_mount_point, + jsoo_mount_point: jsoo_mount_point, + caml_make_path: caml_make_path, + path_is_absolute: path_is_absolute, + MlFile: MlFile, + caml_root: caml_root, + caml_get_root: caml_get_root, + caml_current_dir: caml_current_dir, + caml_trailing_slash: caml_trailing_slash, + caml_finish_formatting: caml_finish_formatting, + caml_parse_format: caml_parse_format, + caml_array_bound_error: caml_array_bound_error, + caml_raise_not_found: caml_raise_not_found, + caml_raise_zero_divide: caml_raise_zero_divide, + caml_raise_end_of_file: caml_raise_end_of_file, + caml_invalid_argument: caml_invalid_argument, + caml_failwith: caml_failwith, + caml_raise_with_string: caml_raise_with_string, + caml_raise_with_args: caml_raise_with_args, + caml_raise_with_arg: caml_raise_with_arg, + caml_raise_constant: caml_raise_constant, + caml_lessthan: caml_lessthan, + caml_lessequal: caml_lessequal, + caml_greaterthan: caml_greaterthan, + caml_greaterequal: caml_greaterequal, + caml_notequal: caml_notequal, + caml_equal: caml_equal, + caml_int_compare: caml_int_compare, + caml_compare: caml_compare, + caml_compare_val: caml_compare_val, + caml_compare_val_number_custom: caml_compare_val_number_custom, + caml_compare_val_get_custom: caml_compare_val_get_custom, + caml_compare_val_tag: caml_compare_val_tag, + caml_bigstring_blit_ba_to_bytes: caml_bigstring_blit_ba_to_bytes, + caml_bigstring_blit_bytes_to_ba: caml_bigstring_blit_bytes_to_ba, + caml_bigstring_blit_string_to_ba: caml_bigstring_blit_string_to_ba, + caml_bigstring_blit_ba_to_ba: caml_bigstring_blit_ba_to_ba, + caml_bigstring_memcmp: caml_bigstring_memcmp, + bigstring_of_typed_array: bigstring_of_typed_array, + bigstring_of_array_buffer: bigstring_of_array_buffer, + bigstring_to_typed_array: bigstring_to_typed_array, + bigstring_to_array_buffer: bigstring_to_array_buffer, + caml_hash_mix_bigstring: caml_hash_mix_bigstring, + caml_ba_from_typed_array: caml_ba_from_typed_array, + caml_ba_kind_of_typed_array: caml_ba_kind_of_typed_array, + caml_ba_to_typed_array: caml_ba_to_typed_array, + caml_ba_hash: caml_ba_hash, + caml_ba_create_from: caml_ba_create_from, + caml_ba_deserialize: caml_ba_deserialize, + caml_ba_serialize: caml_ba_serialize, + caml_ba_reshape: caml_ba_reshape, + caml_ba_slice: caml_ba_slice, + caml_ba_sub: caml_ba_sub, + caml_ba_blit: caml_ba_blit, + caml_ba_fill: caml_ba_fill, + caml_ba_set_3: caml_ba_set_3, + caml_ba_set_2: caml_ba_set_2, + caml_ba_set_1: caml_ba_set_1, + caml_ba_uint8_set64: caml_ba_uint8_set64, + caml_ba_uint8_set32: caml_ba_uint8_set32, + caml_ba_uint8_set16: caml_ba_uint8_set16, + caml_ba_set_generic: caml_ba_set_generic, + caml_ba_get_3: caml_ba_get_3, + caml_ba_get_2: caml_ba_get_2, + caml_ba_get_1: caml_ba_get_1, + caml_ba_uint8_get64: caml_ba_uint8_get64, + caml_ba_uint8_get32: caml_ba_uint8_get32, + caml_ba_uint8_get16: caml_ba_uint8_get16, + caml_ba_get_generic: caml_ba_get_generic, + caml_ba_dim_3: caml_ba_dim_3, + caml_ba_dim_2: caml_ba_dim_2, + caml_ba_dim_1: caml_ba_dim_1, + caml_ba_dim: caml_ba_dim, + caml_ba_num_dims: caml_ba_num_dims, + caml_ba_layout: caml_ba_layout, + caml_ba_kind: caml_ba_kind, + caml_ba_change_layout: caml_ba_change_layout, + caml_ba_create: caml_ba_create, + caml_ba_create_unsafe: caml_ba_create_unsafe, + caml_ba_compare: caml_ba_compare, + Ml_Bigarray_c_1_1: Ml_Bigarray_c_1_1, + Ml_Bigarray: Ml_Bigarray, + caml_ba_custom_name: caml_ba_custom_name, + caml_ba_create_buffer: caml_ba_create_buffer, + caml_ba_get_size_per_element: caml_ba_get_size_per_element, + caml_ba_get_size: caml_ba_get_size, + caml_ba_init: caml_ba_init, + caml_convert_raw_backtrace_slot: caml_convert_raw_backtrace_slot, + caml_get_current_callstack: caml_get_current_callstack, + caml_restore_raw_backtrace: caml_restore_raw_backtrace, + caml_raw_backtrace_slot: caml_raw_backtrace_slot, + caml_raw_backtrace_next_slot: caml_raw_backtrace_next_slot, + caml_raw_backtrace_length: caml_raw_backtrace_length, + caml_convert_raw_backtrace: caml_convert_raw_backtrace, + caml_record_backtrace: caml_record_backtrace, + caml_get_exception_raw_backtrace: caml_get_exception_raw_backtrace, + caml_get_exception_backtrace: caml_get_exception_backtrace, + caml_backtrace_status: caml_backtrace_status, + caml_ml_debug_info_status: caml_ml_debug_info_status, + caml_record_backtrace_flag: caml_record_backtrace_flag, + caml_floatarray_create: caml_floatarray_create, + caml_make_float_vect: caml_make_float_vect, + caml_make_vect: caml_make_vect, + caml_check_bound: caml_check_bound, + caml_array_fill: caml_array_fill, + caml_array_get: caml_array_get, + caml_array_set: caml_array_set, + caml_floatarray_blit: caml_floatarray_blit, + caml_array_blit: caml_array_blit, + caml_array_concat: caml_array_concat, + caml_array_append: caml_array_append, + caml_array_sub: caml_array_sub}; + var + cst_Assert_failure = "Assert_failure", + cst_Division_by_zero = "Division_by_zero", + cst_End_of_file = "End_of_file", + cst_Failure = "Failure", + cst_Invalid_argument = "Invalid_argument", + cst_Match_failure = "Match_failure", + cst_Not_found = "Not_found", + cst_Out_of_memory = "Out_of_memory", + cst_Stack_overflow = "Stack_overflow", + cst_Sys_blocked_io = "Sys_blocked_io", + cst_Sys_error = "Sys_error", + cst_Undefined_recursive_module = "Undefined_recursive_module"; + caml_fs_init(); + caml_register_global(0, [248, cst_Out_of_memory, -1], cst_Out_of_memory); + caml_register_global(1, [248, cst_Sys_error, -2], cst_Sys_error); + caml_register_global(2, [248, cst_Failure, -3], cst_Failure); + caml_register_global + (3, [248, cst_Invalid_argument, -4], cst_Invalid_argument); + caml_register_global(4, [248, cst_End_of_file, -5], cst_End_of_file); + caml_register_global + (5, [248, cst_Division_by_zero, -6], cst_Division_by_zero); + caml_register_global(6, [248, cst_Not_found, -7], cst_Not_found); + caml_register_global(7, [248, cst_Match_failure, -8], cst_Match_failure); + caml_register_global(8, [248, cst_Stack_overflow, -9], cst_Stack_overflow); + caml_register_global(9, [248, cst_Sys_blocked_io, -10], cst_Sys_blocked_io); + caml_register_global + (10, [248, cst_Assert_failure, -11], cst_Assert_failure); + caml_register_global + (11, + [248, cst_Undefined_recursive_module, -12], + cst_Undefined_recursive_module); + return; + } + (globalThis)); + + +(function(a){"use strict";var +au="UIML__UIGL_basics",cD="Stdlib__Obj",cC="UIML__UIK_Canopy",dp=163,cA=169,cB=129,at="Stdlib__Map",as=146,dn="UIML__UIGL_LexSeq",ar="Stdlib__Format",cz="Q",dm="Js_of_ocaml__EventSource",dl="Stdlib__Bytes",aq="End_of_file",bD=148,dk="Out_of_memory",ap="Angstrom__Buffering",cy="UIML__List_lemmasT",dj="Failure",di="Stdlib__Printf",bB="Stdlib",bC="UIML__PeanoNat",cx=136,ao="Dune__exe__Uiml_demo",an=177,cw="Stdlib__Callback",bA="Stdlib__Filename",cv="Stdlib__Hashtbl",am="UIML__UIML_extraction",dh=170,cu=147,al="Stdlib__Option",bz=176,dg="Stdlib__ListLabels",ct="CamlinternalAtomic",df="UIML__PropQuantifiers",by=132,cq="Js_of_ocaml__IntersectionObserver",cr="Stdlib__MoreLabels",cs=125,de="UIML__KS_termination_ImpR",bx="Js_of_ocaml",dd="UIML__Base",cp="Js_of_ocaml__Jstable",dc="Match_failure",co="Js_of_ocaml__File",cn=156,db=109,cl=154,cm=175,bw="Stdlib__Int64",ak="UIML__Specif",ai="UIML__GLS_der_dec",aj="UIML__KS_termination_KR",bv="Angstrom__Exported_state",ag="Js_of_ocaml__Dom_svg",ah="UIML__KS_calc",bu=139,da="Stdlib__Digest",af=161,bt="UIML__UIGL_nodupseq",ae="Sys_error",bs=107,c$="Stdlib__Nativeint",c_="Stdlib__Stack",ad="CamlinternalFormat",br="Stdlib__Genlex",ck="UIML__Formulas",ac="Stdlib__Pervasives",cj="Stdlib__Printexc",ab="Js_of_ocaml__WebSockets",ci="Js_of_ocaml__Form",c9="UIML__UIK_basics",bq="Undefined_recursive_module",aa="Js_of_ocaml__ResizeObserver",bn="CamlinternalFormatBasics",bo="Js_of_ocaml__WebGL",bp="UIML__KS_termination_ImpL",bm="Stdlib__Queue",$="Jsoo_runtime",ch="Division_by_zero",bl="CamlinternalMod",bk="Big_int_Z",bj="UIML__Datatypes",bi=114,cg=158,bh="Stdlib__Parsing",ce="Stdlib__Weak",cf=119,c8="UIML__KS_dec",_=110,bg=113,cd=101,Y="Stdlib__StdLabels",Z=128,c6="Js_of_ocaml__Typed_array",c7="UIML__KS_termination_prelims",be="Stdlib__Bigarray",bf="Stdlib__List",cc="Angstrom__",bd="UIML__List0",X=155,bc="Js_of_ocaml__MutationObserver",cb=100,c5="UIML__Nat",W="UIML__GLS_calcs",bb=111,ca="UIML__UIK_braga",ba="UIML__List",V=102,a$="Js_of_ocaml__Json",b$=171,c4="Stdlib__Atomic",b_="UIML__String",a_=135,a9="Exenum_internals__Exen",a8="Stdlib__Set",a7=123,b9="Js_of_ocaml__Import",c3="Exenum_internals__ExtArray",b8=150,b7="Exenum_internals__Shuffle",U="Stdlib__Seq",S="Dune__exe__Printer",T="UIML",Q="UIML__GLS_termination_measure",R="Z",a6=127,a5="Sys_blocked_io",a4="Stdlib__Uchar",P="CamlinternalOO",O="Stdlib__Stream",N="Js_of_ocaml__Firebug",b6=172,b5="UIML__Environments",L="Stdlib__Gc",M="UIML__Simp",c1="Stdlib__Random",c2="UIML__GenT",J=116,K="UIML__UIGL_Canopy",a3="Js_of_ocaml__PerformanceObserver",b4="Stdlib__Either",c0="Js_of_ocaml__Intl",I="UIML__CML_Syntax",cY="Stdlib__Array",cZ=137,a2="Assert_failure",G=159,H="Stdlib__Lazy",cW="Js_of_ocaml__Lib_version",cX="Jsoo_runtime__",b3="UIML__UIGL_braga",a0="Stdlib__BytesLabels",a1=131,F="UIML__List_lems",aX="Stdlib__Marshal",aY=152,aZ=134,cV="Js_of_ocaml__CSS",cU=122,E=160,b2="UIML__Numbers",aW="Js_of_ocaml__Url",b1="Not_found",cT="Jsoo_runtime__Runtime_version",D=121,cS="Stdlib__String",B="Exenum_internals__Convenience",C=168,aV=173,cR="Js_of_ocaml__Geolocation",aU=124,A="Invalid_argument",aT=141,aS=120,cQ="Js_of_ocaml__Dom_html",aR="Js_of_ocaml__Js",aQ="UIML__Compare_dec",z="UIML__Gen_tacs",cP=166,y="Std_exit",b0="UIML__GLS_dec",x="UIML__DecisionProcedure",w="Stdlib__StringLabels",bZ=133,aP="Exenum_internals",v=157,bY="Js_of_ocaml__Regexp",u=112,cO="Stdlib__Complex",t=140,aO=118,cN="Stdlib__Sys",bW="CamlinternalLazy",bX="Exenum",s="Stdlib__Scanf",q="Dune__exe__Modal_expressions_parser",r=174,bV=167,aN="Js_of_ocaml__Worker",aM="Stdlib__Char",cM=144,aL="Stdlib__Int32",cL="UIML__Order",cK="UIML__Remove_list_lems",cJ="Stdlib__Unit",aK=151,bU=126,aJ="Stack_overflow",bT="Stdlib__ArrayLabels",p=108,aI="Stdlib__Arg",bS="Js_of_ocaml__",aH="Js_of_ocaml__Dom_events",aF="Angstrom",aG=153,n="Angstrom__More",o="Stdlib__Bool",m="Js_of_ocaml__Dom",bR=165,bQ="Zarith_version",bP="Exenum_internals__Parts",bO="Dune__exe",l="Stdlib__Int",bN="Angstrom__Input",k="Stdlib__Oo",bM="Stdlib__Ephemeron",i=130,j=138,aE=145,cI="UIML__Ascii",cH=164,bL="Exenum_internals__Tester",h=106,cG=178,bK="Stdlib__Fun",g=117,aD="Stdlib__Lexing",bJ="UIML__Univ_gen_ext",bI="UIML__UIGL_irred_short",aC="UIML__UIK_irred_short",bH="Stdlib__Result",cF=149,f="Js_of_ocaml__XmlHttpRequest",aB=162,aA="Bigstringaf",bG="Stdlib__Buffer",az="Dune__exe__Stringconversion",e=103,ay=115,d=142,ax="Stdlib__Float",bF=105,aw=143,cE="Angstrom__Parser",av=104,bE="Js_of_ocaml__Sys_js",c=a.jsoo_runtime,b=c.caml_get_global_data();b.prim_count=722;b.symbols=[0,[0,bQ,af],[0,R,aB],[0,bq,11],[0,bJ,p],[0,am,b8],[0,aC,as],[0,ca,cF],[0,c9,bD],[0,cC,cu],[0,bt,cM],[0,bI,t],[0,b3,aE],[0,au,aw],[0,dn,d],[0,K,aT],[0,b_,bi],[0,ak,aU],[0,M,bu],[0,cK,bU],[0,df,j],[0,bC,Z],[0,cL,cZ],[0,b2,aO],[0,c5,bg],[0,F,cs],[0,cy,a7],[0,bd,g],[0,ba,J],[0,c7,bZ],[0,aj,cx],[0,de,aZ],[0,bp,a_],[0,c8,by],[0,ah,a1],[0,z,cU],[0,c2,D],[0,Q,i],[0,ai,cB],[0,b0,a6],[0,W,aS],[0,ck,ay],[0,b5,cf],[0,x,aK],[0,bj,bb],[0,aQ,u],[0,I,_],[0,dd,db],[0,cI,aY],[0,T,bs],[0,ae,10],[0,a5,9],[0,ce,56],[0,cJ,28],[0,a4,22],[0,cN,23],[0,w,70],[0,cS,27],[0,O,44],[0,Y,72],[0,c_,40],[0,a8,38],[0,U,16],[0,s,58],[0,bH,19],[0,c1,54],[0,bm,41],[0,di,47],[0,cj,50],[0,ac,15],[0,bh,37],[0,al,17],[0,k,61],[0,cD,30],[0,c$,35],[0,cr,71],[0,aX,29],[0,at,39],[0,dg,68],[0,bf,24],[0,aD,36],[0,H,43],[0,bw,34],[0,aL,33],[0,l,25],[0,cv,55],[0,br,63],[0,L,52],[0,bK,51],[0,ar,57],[0,ax,32],[0,bA,65],[0,bM,64],[0,b4,18],[0,da,53],[0,cO,66],[0,aM,21],[0,cw,59],[0,a0,69],[0,dl,26],[0,bG,45],[0,o,20],[0,be,73],[0,c4,49],[0,bT,67],[0,cY,31],[0,aI,48],[0,bB,14],[0,y,cG],[0,aJ,8],[0,cz,dp],[0,dk,7],[0,b1,6],[0,dc,5],[0,cT,75],[0,cX,74],[0,$,76],[0,f,85],[0,aN,86],[0,ab,87],[0,bo,88],[0,aW,90],[0,c6,81],[0,bE,92],[0,aa,93],[0,bY,89],[0,a3,94],[0,bc,95],[0,cW,91],[0,cp,96],[0,a$,97],[0,aR,79],[0,c0,bF],[0,cq,av],[0,b9,78],[0,cR,e],[0,ci,84],[0,N,V],[0,co,82],[0,dm,cd],[0,ag,cb],[0,cQ,83],[0,aH,99],[0,m,80],[0,cV,98],[0,bS,77],[0,bx,h],[0,A,4],[0,dj,3],[0,bL,b$],[0,b7,C],[0,bP,cA],[0,c3,bV],[0,a9,dh],[0,B,cP],[0,aP,bR],[0,bX,b6],[0,aq,2],[0,ao,an],[0,az,r],[0,S,bz],[0,q,cm],[0,bO,aV],[0,ch,1],[0,P,60],[0,bl,62],[0,bW,42],[0,bn,12],[0,ad,46],[0,ct,13],[0,aA,aG],[0,bk,cH],[0,a2,0],[0,cE,cg],[0,n,X],[0,bN,v],[0,bv,cn],[0,ap,G],[0,cc,cl],[0,aF,E]];var +dq=[2,S],dr=[2,ao],ds=[2,dm],dt=[2,c0],du=[2,a$],dv=[2,a0],dw=[2,Y],dx=[2,ce],dy=[2,ae],dz=[2,cI],dA=[2,aQ],dB=[2,x],dC=[2,Q],dD=[2,bp],dE=[2,aj],dF=[2,cL],dG=[2,df],dH=[2,M],dI=[0,0,[2,b3],aE,0,1],dJ=[2,au],dK=[2,ca],dL=[2,bQ],dM=[0,0,[2,R],aB,0,1];b.sections=[0,[0,179,[0,[0,[0,[0,[0,[0,[0,0,[2,aF],E,0,1],[2,cc],cl,[0,0,[2,ap],G,0,1],2],[2,bv],cn,[0,[0,0,[2,bN],v,0,1],[2,n],X,[0,0,[2,cE],cg,0,1],2],3],[2,a2],0,[0,[0,[0,0,[2,bk],cH,0,1],[2,aA],aG,0,2],[2,ct],13,[0,0,[2,ad],46,0,1],3],4],[2,bn],12,[0,[0,0,[2,bW],42,[0,[0,0,[2,bl],62,0,1],[2,P],60,0,2],3],[2,ch],1,[0,[0,[0,[0,0,[2,bO],aV,0,1],[2,q],cm,[0,[0,0,dq,bz,0,1],[2,az],r,[0,0,dr,an,0,1],2],3],[2,aq],2,[0,0,[2,bX],b6,0,1],4],[2,aP],bR,[0,[0,0,[2,B],cP,[0,0,[2,a9],dh,0,1],2],[2,c3],bV,[0,[0,0,[2,bP],cA,0,1],[2,b7],C,[0,0,[2,bL],b$,0,1],2],3],5],6],7],[2,dj],3,[0,[0,[0,[0,[0,0,[2,A],4,[0,0,[2,bx],h,0,1],2],[2,bS],77,[0,0,[2,cV],98,0,1],3],[2,m],80,[0,[0,[0,0,[2,aH],99,0,1],[2,cQ],83,[0,0,[2,ag],cb,[0,0,ds,cd,0,1],2],3],[2,co],82,[0,[0,0,[2,N],V,0,1],[2,ci],84,[0,0,[2,cR],e,0,1],2],4],5],[2,b9],78,[0,[0,[0,[0,0,[2,cq],av,[0,0,dt,bF,0,1],2],[2,aR],79,[0,[0,0,du,97,0,1],[2,cp],96,0,2],3],[2,cW],91,[0,[0,0,[2,bc],95,0,1],[2,a3],94,0,2],4],[2,bY],89,[0,[0,0,[2,aa],93,0,1],[2,bE],92,0,2],5],6],[2,c6],81,[0,[0,[0,[0,[0,0,[2,aW],90,0,1],[2,bo],88,0,2],[2,ab],87,0,3],[2,aN],86,[0,0,[2,f],85,0,1],4],[2,$],76,[0,[0,0,[2,cX],74,[0,0,[2,cT],75,0,1],2],[2,dc],5,[0,[0,0,[2,b1],6,0,1],[2,dk],7,[0,[0,0,[2,cz],dp,0,1],[2,aJ],8,[0,0,[2,y],cG,0,1],2],3],4],5],7],8],[2,bB],14,[0,[0,[0,[0,[0,[0,0,[2,aI],48,0,1],[2,cY],31,[0,[0,0,[2,bT],67,0,1],[2,c4],49,[0,0,[2,be],73,0,1],2],3],[2,o],20,[0,[0,[0,0,[2,bG],45,0,1],[2,dl],26,[0,[0,0,dv,69,0,1],[2,cw],59,0,2],3],[2,aM],21,[0,[0,0,[2,cO],66,0,1],[2,da],53,0,2],4],5],[2,b4],18,[0,[0,[0,0,[2,bM],64,[0,0,[2,bA],65,0,1],2],[2,ax],32,[0,0,[2,ar],57,0,1],3],[2,bK],51,[0,[0,0,[2,L],52,[0,0,[2,br],63,0,1],2],[2,cv],55,[0,0,[2,l],25,0,1],3],4],6],[2,aL],33,[0,[0,[0,0,[2,bw],34,[0,[0,0,[2,H],43,0,1],[2,aD],36,0,2],3],[2,bf],24,[0,[0,0,[2,dg],68,0,1],[2,at],39,0,2],4],[2,aX],29,[0,[0,[0,[0,0,[2,cr],71,0,1],[2,c$],35,0,2],[2,cD],30,[0,0,[2,k],61,0,1],3],[2,al],17,[0,0,[2,bh],37,0,1],4],5],7],[2,ac],15,[0,[0,[0,[0,[0,[0,0,[2,cj],50,0,1],[2,di],47,0,2],[2,bm],41,[0,[0,0,[2,c1],54,0,1],[2,bH],19,[0,0,[2,s],58,0,1],2],3],[2,U],16,[0,[0,0,[2,a8],38,0,1],[2,c_],40,[0,[0,[0,0,dw,72,0,1],[2,O],44,0,2],[2,cS],27,[0,0,[2,w],70,0,1],3],4],5],[2,cN],23,[0,[0,[0,0,[2,a4],22,[0,0,[2,cJ],28,[0,0,dx,56,0,1],2],3],[2,a5],9,[0,[0,[0,0,dy,10,0,1],[2,T],bs,[0,0,dz,aY,0,1],2],[2,dd],db,[0,0,[2,I],_,[0,0,dA,u,0,1],2],3],4],[2,bj],bb,[0,[0,[0,[0,0,dB,aK,0,1],[2,b5],cf,0,2],[2,ck],ay,0,3],[2,W],aS,[0,0,[2,b0],a6,[0,0,[2,ai],cB,[0,0,dC,i,0,1],2],3],4],5],6],[2,c2],D,[0,[0,[0,[0,0,[2,z],cU,0,1],[2,ah],a1,[0,[0,0,[2,c8],by,[0,0,dD,a_,0,1],2],[2,de],aZ,[0,[0,0,dE,cx,0,1],[2,c7],bZ,0,2],3],4],[2,ba],J,[0,0,[2,bd],g,[0,0,[2,cy],a7,[0,0,[2,F],cs,0,1],2],3],5],[2,c5],bg,[0,[0,[0,[0,0,[2,b2],aO,[0,0,dF,cZ,0,1],2],[2,bC],Z,[0,[0,0,dG,j,0,1],[2,cK],bU,[0,0,dH,bu,0,1],2],3],[2,ak],aU,[0,[0,0,[2,b_],bi,0,1],[2,K],aT,[0,0,[2,dn],d,[0,0,dJ,aw,dI,2],3],4],5],[2,bI],t,[0,[0,[0,0,[2,bt],cM,0,1],[2,cC],cu,[0,0,[2,c9],bD,[0,0,dK,cF,0,1],2],3],[2,aC],as,[0,[0,0,[2,am],b8,0,1],[2,bJ],p,[0,0,[2,bq],11,[0,dM,dL,af,0,2],3],4],5],6],7],8],9],10]],0,c.caml_list_of_js_array(["BigStringReader","MlBytes","MlFakeDevice","MlFakeFd","MlFakeFd_out","MlFakeFile","MlFile","MlInt64","MlMutex","MlNat","MlNodeDevice","MlNodeFd","MlObjectTable","MlStringReader","Ml_Bigarray","Ml_Bigarray_c_1_1","UInt8ArrayReader","add_nat","bigstring_of_array_buffer","bigstring_of_typed_array","bigstring_to_array_buffer","bigstring_to_typed_array","bigstringaf_blit_from_bytes","bigstringaf_blit_to_bigstring","bigstringaf_blit_to_bytes","bigstringaf_memchr","bigstringaf_memcmp_bigstring","bigstringaf_memcmp_string","blit_nat","caml_MD5Final","caml_MD5Init","caml_MD5Transform","caml_MD5Update","caml_acosh_float","caml_alloc_dummy_infix","caml_alloc_stack","caml_argv","caml_array_append","caml_array_blit","caml_array_bound_error","caml_array_concat","caml_array_fill","caml_array_get","caml_array_of_bytes","caml_array_of_string","caml_array_set","caml_array_sub","caml_asinh_float","caml_atanh_float","caml_atomic_cas","caml_atomic_exchange","caml_atomic_fetch_add","caml_atomic_load","caml_atomic_make_contended","caml_ba_blit","caml_ba_change_layout","caml_ba_compare","caml_ba_create","caml_ba_create_buffer","caml_ba_create_from","caml_ba_create_unsafe","caml_ba_custom_name","caml_ba_deserialize","caml_ba_dim","caml_ba_dim_1","caml_ba_dim_2","caml_ba_dim_3","caml_ba_fill","caml_ba_from_typed_array","caml_ba_get_1","caml_ba_get_2","caml_ba_get_3","caml_ba_get_generic","caml_ba_get_size","caml_ba_get_size_per_element","caml_ba_hash","caml_ba_init","caml_ba_kind","caml_ba_kind_of_typed_array","caml_ba_layout","caml_ba_map_file","caml_ba_map_file_bytecode","caml_ba_num_dims","caml_ba_reshape","caml_ba_serialize","caml_ba_set_1","caml_ba_set_2","caml_ba_set_3","caml_ba_set_generic","caml_ba_slice","caml_ba_sub","caml_ba_to_typed_array","caml_ba_uint8_get16","caml_ba_uint8_get32","caml_ba_uint8_get64","caml_ba_uint8_set16","caml_ba_uint8_set32","caml_ba_uint8_set64","caml_backtrace_status","caml_bigstring_blit_ba_to_ba","caml_bigstring_blit_ba_to_bytes","caml_bigstring_blit_bytes_to_ba","caml_bigstring_blit_string_to_ba","caml_bigstring_memcmp","caml_blit_bytes","caml_blit_string","caml_bswap16","caml_build_symbols","caml_bytes_bound_error","caml_bytes_compare","caml_bytes_equal","caml_bytes_get","caml_bytes_get16","caml_bytes_get32","caml_bytes_get64","caml_bytes_greaterequal","caml_bytes_greaterthan","caml_bytes_lessequal","caml_bytes_lessthan","caml_bytes_notequal","caml_bytes_of_array","caml_bytes_of_jsbytes","caml_bytes_of_string","caml_bytes_of_utf16_jsstring","caml_bytes_set","caml_bytes_set16","caml_bytes_set32","caml_bytes_set64","caml_bytes_unsafe_get","caml_bytes_unsafe_set","caml_call_gen","caml_callback","caml_cbrt_float","caml_channel_descriptor","caml_check_bound","caml_classify_float","caml_compare","caml_compare_val","caml_compare_val_get_custom","caml_compare_val_number_custom","caml_compare_val_tag","caml_continuation_use_and_update_handler_noexc","caml_continuation_use_noexc","caml_convert_bytes_to_array","caml_convert_raw_backtrace","caml_convert_raw_backtrace_slot","caml_convert_string_to_bytes","caml_copysign_float","caml_cosh_float","caml_create_bytes","caml_create_file","caml_create_string","caml_current_dir","caml_custom_event_index","caml_custom_ops","caml_decompress_input","caml_div","caml_domain_dls","caml_domain_dls_get","caml_domain_dls_set","caml_domain_id","caml_domain_spawn","caml_ephe_blit_data","caml_ephe_blit_key","caml_ephe_check_data","caml_ephe_check_key","caml_ephe_create","caml_ephe_data_offset","caml_ephe_get_data","caml_ephe_get_data_copy","caml_ephe_get_key","caml_ephe_get_key_copy","caml_ephe_key_offset","caml_ephe_set_data","caml_ephe_set_key","caml_ephe_unset_data","caml_ephe_unset_key","caml_equal","caml_erf_float","caml_erfc_float","caml_eventlog_pause","caml_eventlog_resume","caml_executable_name","caml_exn_with_js_backtrace","caml_exp2_float","caml_expm1_float","caml_failwith","caml_fatal_uncaught_exception","caml_fill_bytes","caml_final_register","caml_final_register_called_without_value","caml_final_release","caml_finish_formatting","caml_float_compare","caml_float_of_bytes","caml_float_of_string","caml_floatarray_blit","caml_floatarray_create","caml_fma_float","caml_format_exception","caml_format_float","caml_format_int","caml_fresh_oo_id","caml_frexp_float","caml_fs_init","caml_gc_compaction","caml_gc_counters","caml_gc_full_major","caml_gc_get","caml_gc_huge_fallback_count","caml_gc_major","caml_gc_major_slice","caml_gc_minor","caml_gc_minor_words","caml_gc_quick_stat","caml_gc_set","caml_gc_stat","caml_get_continuation_callstack","caml_get_current_callstack","caml_get_exception_backtrace","caml_get_exception_raw_backtrace","caml_get_global_data","caml_get_major_bucket","caml_get_major_credit","caml_get_minor_free","caml_get_public_method","caml_get_root","caml_global_data","caml_gr_arc_aux","caml_gr_blit_image","caml_gr_clear_graph","caml_gr_close_graph","caml_gr_close_subwindow","caml_gr_create_image","caml_gr_current_x","caml_gr_current_y","caml_gr_display_mode","caml_gr_doc_of_state","caml_gr_draw_arc","caml_gr_draw_char","caml_gr_draw_image","caml_gr_draw_rect","caml_gr_draw_str","caml_gr_draw_string","caml_gr_dump_image","caml_gr_fill_arc","caml_gr_fill_poly","caml_gr_fill_rect","caml_gr_lineto","caml_gr_make_image","caml_gr_moveto","caml_gr_open_graph","caml_gr_open_subwindow","caml_gr_plot","caml_gr_point_color","caml_gr_remember_mode","caml_gr_resize_window","caml_gr_set_color","caml_gr_set_font","caml_gr_set_line_width","caml_gr_set_text_size","caml_gr_set_window_title","caml_gr_sigio_handler","caml_gr_sigio_signal","caml_gr_size_x","caml_gr_size_y","caml_gr_state","caml_gr_state_create","caml_gr_state_get","caml_gr_state_init","caml_gr_state_set","caml_gr_synchronize","caml_gr_text_size","caml_gr_wait_event","caml_gr_window_id","caml_greaterequal","caml_greaterthan","caml_hash","caml_hash_mix_bigstring","caml_hash_mix_bytes","caml_hash_mix_bytes_arr","caml_hash_mix_final","caml_hash_mix_float","caml_hash_mix_int","caml_hash_mix_int64","caml_hash_mix_jsbytes","caml_hash_mix_string","caml_hash_nat","caml_hexstring_of_float","caml_hypot_float","caml_input_value","caml_input_value_from_bytes","caml_input_value_from_reader","caml_input_value_from_string","caml_input_value_to_outside_heap","caml_install_signal_handler","caml_int32_bits_of_float","caml_int32_bswap","caml_int32_float_of_bits","caml_int32_unmarshal","caml_int64_add","caml_int64_and","caml_int64_bits_of_float","caml_int64_bswap","caml_int64_compare","caml_int64_create_lo_hi","caml_int64_create_lo_mi_hi","caml_int64_div","caml_int64_float_of_bits","caml_int64_format","caml_int64_hash","caml_int64_hi32","caml_int64_is_negative","caml_int64_is_zero","caml_int64_lo32","caml_int64_marshal","caml_int64_mod","caml_int64_mul","caml_int64_neg","caml_int64_of_bytes","caml_int64_of_float","caml_int64_of_int32","caml_int64_of_string","caml_int64_offset","caml_int64_or","caml_int64_shift_left","caml_int64_shift_right","caml_int64_shift_right_unsigned","caml_int64_sub","caml_int64_to_bytes","caml_int64_to_float","caml_int64_to_int32","caml_int64_ult","caml_int64_unmarshal","caml_int64_xor","caml_int_compare","caml_int_of_string","caml_invalid_argument","caml_is_continuation_tag","caml_is_js","caml_is_ml_bytes","caml_is_ml_string","caml_is_printable","caml_is_special_exception","caml_js_call","caml_js_delete","caml_js_equals","caml_js_error_of_exception","caml_js_error_option_of_exception","caml_js_eval_string","caml_js_expr","caml_js_from_array","caml_js_from_bool","caml_js_from_float","caml_js_from_string","caml_js_fun_call","caml_js_function_arity","caml_js_get","caml_js_get_console","caml_js_html_entities","caml_js_html_escape","caml_js_instanceof","caml_js_meth_call","caml_js_new","caml_js_object","caml_js_on_ie","caml_js_pure_expr","caml_js_set","caml_js_strict_equals","caml_js_to_array","caml_js_to_bool","caml_js_to_byte_string","caml_js_to_float","caml_js_to_int32","caml_js_to_string","caml_js_typeof","caml_js_var","caml_js_wrap_callback","caml_js_wrap_callback_arguments","caml_js_wrap_callback_strict","caml_js_wrap_callback_unsafe","caml_js_wrap_meth_callback","caml_js_wrap_meth_callback_arguments","caml_js_wrap_meth_callback_strict","caml_js_wrap_meth_callback_unsafe","caml_jsbytes_of_string","caml_jsoo_flags_effects","caml_jsoo_flags_use_js_string","caml_jsstring_of_string","caml_lazy_make_forward","caml_lazy_read_result","caml_lazy_reset_to_lazy","caml_lazy_update_to_forcing","caml_lazy_update_to_forward","caml_ldexp_float","caml_lessequal","caml_lessthan","caml_lex_array","caml_lex_engine","caml_list_mount_point","caml_list_of_js_array","caml_list_to_js_array","caml_log10_float","caml_log1p_float","caml_log2_float","caml_lxm_next","caml_make_float_vect","caml_make_path","caml_make_vect","caml_marshal_constants","caml_marshal_data_size","caml_marshal_header_size","caml_maybe_attach_backtrace","caml_maybe_print_stats","caml_md5_bytes","caml_md5_chan","caml_md5_string","caml_memprof_discard","caml_memprof_set","caml_memprof_start","caml_memprof_stop","caml_ml_bytes_content","caml_ml_bytes_length","caml_ml_channel_get","caml_ml_channel_redirect","caml_ml_channel_restore","caml_ml_channel_size","caml_ml_channel_size_64","caml_ml_channels","caml_ml_close_channel","caml_ml_condition_broadcast","caml_ml_condition_new","caml_ml_condition_signal","caml_ml_condition_wait","caml_ml_debug_info_status","caml_ml_domain_cpu_relax","caml_ml_domain_id","caml_ml_domain_set_name","caml_ml_domain_unique_token","caml_ml_enable_runtime_warnings","caml_ml_flush","caml_ml_input","caml_ml_input_bigarray","caml_ml_input_block","caml_ml_input_char","caml_ml_input_int","caml_ml_input_scan_line","caml_ml_is_buffered","caml_ml_mutex_lock","caml_ml_mutex_new","caml_ml_mutex_try_lock","caml_ml_mutex_unlock","caml_ml_open_descriptor_in","caml_ml_open_descriptor_out","caml_ml_out_channels_list","caml_ml_output","caml_ml_output_bigarray","caml_ml_output_bytes","caml_ml_output_char","caml_ml_output_int","caml_ml_output_ta","caml_ml_pos_in","caml_ml_pos_in_64","caml_ml_pos_out","caml_ml_pos_out_64","caml_ml_runtime_events_pause","caml_ml_runtime_events_resume","caml_ml_runtime_events_start","caml_ml_runtime_warnings_enabled","caml_ml_seek_in","caml_ml_seek_in_64","caml_ml_seek_out","caml_ml_seek_out_64","caml_ml_set_binary_mode","caml_ml_set_buffered","caml_ml_set_channel_name","caml_ml_set_channel_output","caml_ml_set_channel_refill","caml_ml_string_length","caml_mod","caml_modf_float","caml_mount_autoload","caml_mul","caml_named_value","caml_named_values","caml_nativeint_unmarshal","caml_new_lex_engine","caml_new_string","caml_nextafter_float","caml_notequal","caml_obj_add_offset","caml_obj_block","caml_obj_compare_and_swap","caml_obj_dup","caml_obj_is_block","caml_obj_is_shared","caml_obj_make_forward","caml_obj_raw_field","caml_obj_reachable_words","caml_obj_set_raw_field","caml_obj_set_tag","caml_obj_tag","caml_obj_truncate","caml_obj_update_tag","caml_obj_with_tag","caml_ojs_new_arr","caml_oo_last_id","caml_output_val","caml_output_value","caml_output_value_to_buffer","caml_output_value_to_bytes","caml_output_value_to_string","caml_parse_digit","caml_parse_engine","caml_parse_format","caml_parse_sign_and_base","caml_parser_trace","caml_pos_in","caml_pos_out","caml_pure_js_expr","caml_raise_constant","caml_raise_end_of_file","caml_raise_no_such_file","caml_raise_not_a_dir","caml_raise_not_found","caml_raise_sys_error","caml_raise_with_arg","caml_raise_with_args","caml_raise_with_string","caml_raise_zero_divide","caml_raw_backtrace_length","caml_raw_backtrace_next_slot","caml_raw_backtrace_slot","caml_read_file_content","caml_recommended_domain_count","caml_record_backtrace","caml_record_backtrace_flag","caml_refill","caml_register_channel_for_spacetime","caml_register_global","caml_register_named_value","caml_restore_raw_backtrace","caml_root","caml_round_float","caml_runtime_events_create_cursor","caml_runtime_events_free_cursor","caml_runtime_events_read_poll","caml_runtime_events_user_register","caml_runtime_events_user_resolve","caml_runtime_events_user_write","caml_runtime_parameters","caml_runtime_variant","caml_runtime_warnings","caml_seek_in","caml_seek_out","caml_set_oo_id","caml_set_parser_trace","caml_set_static_env","caml_signbit_float","caml_sinh_float","caml_spacetime_enabled","caml_spacetime_only_works_for_native_code","caml_str_initialize","caml_str_repeat","caml_string_bound_error","caml_string_compare","caml_string_concat","caml_string_equal","caml_string_get","caml_string_get16","caml_string_get32","caml_string_get64","caml_string_greaterequal","caml_string_greaterthan","caml_string_hash","caml_string_lessequal","caml_string_lessthan","caml_string_notequal","caml_string_of_array","caml_string_of_bytes","caml_string_of_jsbytes","caml_string_of_jsstring","caml_string_set","caml_string_set16","caml_string_set32","caml_string_set64","caml_string_unsafe_get","caml_string_unsafe_set","caml_subarray_to_jsbytes","caml_sys_argv","caml_sys_chdir","caml_sys_close","caml_sys_const_backend_type","caml_sys_const_big_endian","caml_sys_const_int_size","caml_sys_const_max_wosize","caml_sys_const_naked_pointers_checked","caml_sys_const_ostype_cygwin","caml_sys_const_ostype_unix","caml_sys_const_ostype_win32","caml_sys_const_word_size","caml_sys_executable_name","caml_sys_exit","caml_sys_fds","caml_sys_file_exists","caml_sys_get_argv","caml_sys_get_config","caml_sys_getcwd","caml_sys_getenv","caml_sys_is_directory","caml_sys_is_regular_file","caml_sys_isatty","caml_sys_mkdir","caml_sys_modify_argv","caml_sys_open","caml_sys_open_for_node","caml_sys_random_seed","caml_sys_read_directory","caml_sys_remove","caml_sys_rename","caml_sys_rmdir","caml_sys_system_command","caml_sys_time","caml_sys_time_include_children","caml_sys_unsafe_getenv","caml_tanh_float","caml_to_js_string","caml_trailing_slash","caml_trampoline","caml_trampoline_return","caml_trunc_float","caml_uint8_array_of_bytes","caml_uint8_array_of_string","caml_unix_cleanup","caml_unix_closedir","caml_unix_filedescr_of_fd","caml_unix_findclose","caml_unix_findfirst","caml_unix_findnext","caml_unix_getpwuid","caml_unix_gettimeofday","caml_unix_getuid","caml_unix_gmtime","caml_unix_has_symlink","caml_unix_inet_addr_of_string","caml_unix_isatty","caml_unix_localtime","caml_unix_lstat","caml_unix_lstat_64","caml_unix_mkdir","caml_unix_mktime","caml_unix_opendir","caml_unix_readdir","caml_unix_readlink","caml_unix_rewinddir","caml_unix_rmdir","caml_unix_startup","caml_unix_stat","caml_unix_stat_64","caml_unix_symlink","caml_unix_time","caml_unix_unlink","caml_unmount","caml_update_dummy","caml_utf16_of_utf8","caml_utf8_of_utf16","caml_weak_create","caml_weak_set","caml_wrap_exception","caml_xmlhttprequest_create","compare_digits_nat","compare_nat","compare_nat_real","complement_nat","create_nat","decr_nat","deserialize_nat","div_digit_nat","div_helper","div_nat","fs_node_supported","incr_nat","initialize_nat","is_digit_int","is_digit_odd","is_digit_zero","jsoo_create_file","jsoo_create_file_extern","jsoo_effect_not_supported","jsoo_floor_log2","jsoo_is_ascii","jsoo_mount_point","jsoo_sys_getenv","land_digit_nat","length_nat","lor_digit_nat","lxor_digit_nat","make_unix_err_args","mult_digit_nat","mult_nat","nat_of_array","nth_digit_nat","nth_digit_nat_native","num_digits_nat","num_leading_zero_bits_in_digit","os_type","path_is_absolute","re_match","re_partial_match","re_replacement_text","re_search_backward","re_search_forward","re_string_match","resolve_fs_device","serialize_nat","set_digit_nat","set_digit_nat_native","set_to_zero_nat","shift_left_nat","shift_right_nat","square_nat","sub_nat"]),0];return}(globalThis)); +//# 1 "../.js/default/stdlib/stdlib.cma.js" +// Generated by js_of_ocaml +//# 3 "../.js/default/stdlib/stdlib.cma.js" + +//# 5 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function erase_rel(param){ + if(typeof param === "number") return 0; + switch(param[0]){ + case 0: + var rest = param[1]; return [0, erase_rel(rest)]; + case 1: + var rest$0 = param[1]; return [1, erase_rel(rest$0)]; + case 2: + var rest$1 = param[1]; return [2, erase_rel(rest$1)]; + case 3: + var rest$2 = param[1]; return [3, erase_rel(rest$2)]; + case 4: + var rest$3 = param[1]; return [4, erase_rel(rest$3)]; + case 5: + var rest$4 = param[1]; return [5, erase_rel(rest$4)]; + case 6: + var rest$5 = param[1]; return [6, erase_rel(rest$5)]; + case 7: + var rest$6 = param[1]; return [7, erase_rel(rest$6)]; + case 8: + var rest$7 = param[2], ty = param[1]; + return [8, ty, erase_rel(rest$7)]; + case 9: + var rest$8 = param[3], ty1 = param[1]; + return [9, ty1, ty1, erase_rel(rest$8)]; + case 10: + var rest$9 = param[1]; return [10, erase_rel(rest$9)]; + case 11: + var rest$10 = param[1]; return [11, erase_rel(rest$10)]; + case 12: + var rest$11 = param[1]; return [12, erase_rel(rest$11)]; + case 13: + var rest$12 = param[1]; return [13, erase_rel(rest$12)]; + default: var rest$13 = param[1]; return [14, erase_rel(rest$13)]; + } + } + function concat_fmtty(fmtty1, fmtty2){ + if(typeof fmtty1 === "number") return fmtty2; + switch(fmtty1[0]){ + case 0: + var rest = fmtty1[1]; return [0, concat_fmtty(rest, fmtty2)]; + case 1: + var rest$0 = fmtty1[1]; return [1, concat_fmtty(rest$0, fmtty2)]; + case 2: + var rest$1 = fmtty1[1]; return [2, concat_fmtty(rest$1, fmtty2)]; + case 3: + var rest$2 = fmtty1[1]; return [3, concat_fmtty(rest$2, fmtty2)]; + case 4: + var rest$3 = fmtty1[1]; return [4, concat_fmtty(rest$3, fmtty2)]; + case 5: + var rest$4 = fmtty1[1]; return [5, concat_fmtty(rest$4, fmtty2)]; + case 6: + var rest$5 = fmtty1[1]; return [6, concat_fmtty(rest$5, fmtty2)]; + case 7: + var rest$6 = fmtty1[1]; return [7, concat_fmtty(rest$6, fmtty2)]; + case 8: + var rest$7 = fmtty1[2], ty = fmtty1[1]; + return [8, ty, concat_fmtty(rest$7, fmtty2)]; + case 9: + var rest$8 = fmtty1[3], ty2 = fmtty1[2], ty1 = fmtty1[1]; + return [9, ty1, ty2, concat_fmtty(rest$8, fmtty2)]; + case 10: + var rest$9 = fmtty1[1]; return [10, concat_fmtty(rest$9, fmtty2)]; + case 11: + var rest$10 = fmtty1[1]; return [11, concat_fmtty(rest$10, fmtty2)]; + case 12: + var rest$11 = fmtty1[1]; return [12, concat_fmtty(rest$11, fmtty2)]; + case 13: + var rest$12 = fmtty1[1]; return [13, concat_fmtty(rest$12, fmtty2)]; + default: + var rest$13 = fmtty1[1]; return [14, concat_fmtty(rest$13, fmtty2)]; + } + } + function concat_fmt(fmt1, fmt2){ + if(typeof fmt1 === "number") return fmt2; + switch(fmt1[0]){ + case 0: + var rest = fmt1[1]; return [0, concat_fmt(rest, fmt2)]; + case 1: + var rest$0 = fmt1[1]; return [1, concat_fmt(rest$0, fmt2)]; + case 2: + var rest$1 = fmt1[2], pad = fmt1[1]; + return [2, pad, concat_fmt(rest$1, fmt2)]; + case 3: + var rest$2 = fmt1[2], pad$0 = fmt1[1]; + return [3, pad$0, concat_fmt(rest$2, fmt2)]; + case 4: + var rest$3 = fmt1[4], prec = fmt1[3], pad$1 = fmt1[2], iconv = fmt1[1]; + return [4, iconv, pad$1, prec, concat_fmt(rest$3, fmt2)]; + case 5: + var + rest$4 = fmt1[4], + prec$0 = fmt1[3], + pad$2 = fmt1[2], + iconv$0 = fmt1[1]; + return [5, iconv$0, pad$2, prec$0, concat_fmt(rest$4, fmt2)]; + case 6: + var + rest$5 = fmt1[4], + prec$1 = fmt1[3], + pad$3 = fmt1[2], + iconv$1 = fmt1[1]; + return [6, iconv$1, pad$3, prec$1, concat_fmt(rest$5, fmt2)]; + case 7: + var + rest$6 = fmt1[4], + prec$2 = fmt1[3], + pad$4 = fmt1[2], + iconv$2 = fmt1[1]; + return [7, iconv$2, pad$4, prec$2, concat_fmt(rest$6, fmt2)]; + case 8: + var + rest$7 = fmt1[4], + prec$3 = fmt1[3], + pad$5 = fmt1[2], + fconv = fmt1[1]; + return [8, fconv, pad$5, prec$3, concat_fmt(rest$7, fmt2)]; + case 9: + var rest$8 = fmt1[2], pad$6 = fmt1[1]; + return [9, pad$6, concat_fmt(rest$8, fmt2)]; + case 10: + var rest$9 = fmt1[1]; return [10, concat_fmt(rest$9, fmt2)]; + case 11: + var rest$10 = fmt1[2], str = fmt1[1]; + return [11, str, concat_fmt(rest$10, fmt2)]; + case 12: + var rest$11 = fmt1[2], chr = fmt1[1]; + return [12, chr, concat_fmt(rest$11, fmt2)]; + case 13: + var rest$12 = fmt1[3], fmtty = fmt1[2], pad$7 = fmt1[1]; + return [13, pad$7, fmtty, concat_fmt(rest$12, fmt2)]; + case 14: + var rest$13 = fmt1[3], fmtty$0 = fmt1[2], pad$8 = fmt1[1]; + return [14, pad$8, fmtty$0, concat_fmt(rest$13, fmt2)]; + case 15: + var rest$14 = fmt1[1]; return [15, concat_fmt(rest$14, fmt2)]; + case 16: + var rest$15 = fmt1[1]; return [16, concat_fmt(rest$15, fmt2)]; + case 17: + var rest$16 = fmt1[2], fmting_lit = fmt1[1]; + return [17, fmting_lit, concat_fmt(rest$16, fmt2)]; + case 18: + var rest$17 = fmt1[2], fmting_gen = fmt1[1]; + return [18, fmting_gen, concat_fmt(rest$17, fmt2)]; + case 19: + var rest$18 = fmt1[1]; return [19, concat_fmt(rest$18, fmt2)]; + case 20: + var rest$19 = fmt1[3], char_set = fmt1[2], width_opt = fmt1[1]; + return [20, width_opt, char_set, concat_fmt(rest$19, fmt2)]; + case 21: + var rest$20 = fmt1[2], counter = fmt1[1]; + return [21, counter, concat_fmt(rest$20, fmt2)]; + case 22: + var rest$21 = fmt1[1]; return [22, concat_fmt(rest$21, fmt2)]; + case 23: + var rest$22 = fmt1[2], ign = fmt1[1]; + return [23, ign, concat_fmt(rest$22, fmt2)]; + default: + var rest$23 = fmt1[3], f = fmt1[2], arity = fmt1[1]; + return [24, arity, f, concat_fmt(rest$23, fmt2)]; + } + } + var CamlinternalFormatBasics = [0, concat_fmtty, erase_rel, concat_fmt]; + runtime.caml_register_global + (0, CamlinternalFormatBasics, "CamlinternalFormatBasics"); + return; + } + (globalThis)); + +//# 179 "../.js/default/stdlib/stdlib.cma.js" +(function(globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function make(v){return [0, v];} + function get(r){return r[1];} + function set(r, v){r[1] = v; return 0;} + function exchange(r, v){var cur = r[1]; r[1] = v; return cur;} + function compare_and_set(r, seen, v){ + var cur = r[1]; + return cur === seen ? (r[1] = v, 1) : 0; + } + function fetch_and_add(r, n){ + var cur = r[1]; + r[1] = cur + n | 0; + return cur; + } + function incr(r){fetch_and_add(r, 1); return 0;} + function decr(r){fetch_and_add(r, -1); return 0;} + var + CamlinternalAtomic = + [0, + make, + get, + set, + exchange, + compare_and_set, + fetch_and_add, + incr, + decr]; + runtime.caml_register_global(0, CamlinternalAtomic, "CamlinternalAtomic"); + return; + } + (globalThis)); + +//# 215 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst_false$0 = "false", + cst_true$0 = "true", + caml_create_bytes = runtime.caml_create_bytes, + caml_float_of_string = runtime.caml_float_of_string, + caml_int64_float_of_bits = runtime.caml_int64_float_of_bits, + caml_int_of_string = runtime.caml_int_of_string, + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace, + caml_ml_bytes_length = runtime.caml_ml_bytes_length, + caml_ml_channel_size = runtime.caml_ml_channel_size, + caml_ml_channel_size_64 = runtime.caml_ml_channel_size_64, + caml_ml_close_channel = runtime.caml_ml_close_channel, + caml_ml_flush = runtime.caml_ml_flush, + caml_ml_input = runtime.caml_ml_input, + caml_ml_input_char = runtime.caml_ml_input_char, + caml_ml_open_descriptor_in = runtime.caml_ml_open_descriptor_in, + caml_ml_open_descriptor_out = runtime.caml_ml_open_descriptor_out, + caml_ml_output = runtime.caml_ml_output, + caml_ml_output_bytes = runtime.caml_ml_output_bytes, + caml_ml_output_char = runtime.caml_ml_output_char, + caml_ml_set_binary_mode = runtime.caml_ml_set_binary_mode, + caml_ml_set_channel_name = runtime.caml_ml_set_channel_name, + caml_ml_string_length = runtime.caml_ml_string_length, + caml_string_concat = runtime.caml_string_concat, + caml_string_of_bytes = runtime.caml_string_of_bytes, + caml_sys_open = runtime.caml_sys_open, + caml_wrap_exception = runtime.caml_wrap_exception; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + var + global_data = runtime.caml_get_global_data(), + CamlinternalAtomic = global_data.CamlinternalAtomic, + CamlinternalFormatBasics = global_data.CamlinternalFormatBasics, + Invalid_argument = global_data.Invalid_argument, + Failure = global_data.Failure, + Match_failure = global_data.Match_failure, + Assert_failure = global_data.Assert_failure, + Not_found = global_data.Not_found, + Out_of_memory = global_data.Out_of_memory, + Stack_overflow = global_data.Stack_overflow, + Sys_error = global_data.Sys_error, + End_of_file = global_data.End_of_file, + Division_by_zero = global_data.Division_by_zero, + Sys_blocked_io = global_data.Sys_blocked_io, + Undefined_recursive_module = global_data.Undefined_recursive_module; + function failwith(s){ + throw caml_maybe_attach_backtrace([0, Failure, s], 1); + } + function invalid_arg(s){ + throw caml_maybe_attach_backtrace([0, Invalid_argument, s], 1); + } + var Exit = [248, "Stdlib.Exit", runtime.caml_fresh_oo_id(0)]; + function min(x, y){return runtime.caml_lessequal(x, y) ? x : y;} + function max(x, y){return runtime.caml_greaterequal(x, y) ? x : y;} + function abs(x){return 0 <= x ? x : - x | 0;} + function lnot(x){return x ^ -1;} + var + infinity = + caml_int64_float_of_bits + (runtime.caml_int64_create_lo_mi_hi(0, 0, 32752)), + neg_infinity = + caml_int64_float_of_bits + (runtime.caml_int64_create_lo_mi_hi(0, 0, 65520)), + nan = + caml_int64_float_of_bits + (runtime.caml_int64_create_lo_mi_hi(1, 0, 32752)), + max_float = + caml_int64_float_of_bits + (runtime.caml_int64_create_lo_mi_hi(16777215, 16777215, 32751)), + min_float = + caml_int64_float_of_bits(runtime.caml_int64_create_lo_mi_hi(0, 0, 16)), + epsilon_float = + caml_int64_float_of_bits + (runtime.caml_int64_create_lo_mi_hi(0, 0, 15536)), + symbol_concat = caml_string_concat, + cst_char_of_int = "char_of_int", + cst_true = cst_true$0, + cst_false = cst_false$0, + cst_bool_of_string = "bool_of_string", + _a_ = [0, 1], + _b_ = [0, 0]; + function char_of_int(n){ + if(0 <= n && 255 >= n) return n; + return invalid_arg(cst_char_of_int); + } + function string_of_bool(b){return b ? cst_true : cst_false;} + function bool_of_string(param){ + return param !== cst_false$0 + ? param !== cst_true$0 ? invalid_arg(cst_bool_of_string) : 1 + : 0; + } + function bool_of_string_opt(param){ + return param !== cst_false$0 ? param !== cst_true$0 ? 0 : _a_ : _b_; + } + function string_of_int(n){return "" + n;} + function int_of_string_opt(s){ + try{var _u_ = [0, caml_int_of_string(s)]; return _u_;} + catch(_v_){ + var _t_ = caml_wrap_exception(_v_); + if(_t_[1] === Failure) return 0; + throw caml_maybe_attach_backtrace(_t_, 0); + } + } + function valid_float_lexem(s1){ + var l = caml_ml_string_length(s1), i = 0; + for(;;){ + if(l <= i) return s1 + "."; + var match = runtime.caml_string_get(s1, i); + a: + { + if(48 <= match){if(58 > match) break a;} else if(45 === match) break a; + return s1; + } + var i$0 = i + 1 | 0; + i = i$0; + } + } + function string_of_float(f){ + return valid_float_lexem(runtime.caml_format_float("%.12g", f)); + } + function float_of_string_opt(s){ + try{var _r_ = [0, caml_float_of_string(s)]; return _r_;} + catch(_s_){ + var _q_ = caml_wrap_exception(_s_); + if(_q_[1] === Failure) return 0; + throw caml_maybe_attach_backtrace(_q_, 0); + } + } + function symbol(l1, l2){ + if(! l1) return l2; + var tl = l1[2], hd = l1[1]; + return [0, hd, symbol(tl, l2)]; + } + var + stdin = caml_ml_open_descriptor_in(0), + stdout = caml_ml_open_descriptor_out(1), + stderr = caml_ml_open_descriptor_out(2), + _c_ = [0, 1, [0, 3, [0, 4, [0, 7, 0]]]], + _d_ = [0, 1, [0, 3, [0, 4, [0, 6, 0]]]], + cst_output = "output", + cst_output_substring = "output_substring", + _e_ = [0, 0, [0, 7, 0]], + _f_ = [0, 0, [0, 6, 0]], + cst_input = "input", + cst_really_input = "really_input"; + function open_out_gen(mode, perm, name){ + var c = caml_ml_open_descriptor_out(caml_sys_open(name, mode, perm)); + caml_ml_set_channel_name(c, name); + return c; + } + function open_out(name){return open_out_gen(_c_, 438, name);} + function open_out_bin(name){return open_out_gen(_d_, 438, name);} + function flush_all(param){ + var param$0 = runtime.caml_ml_out_channels_list(0); + for(;;){ + if(! param$0) return 0; + var l = param$0[2], a = param$0[1]; + try{caml_ml_flush(a);} + catch(_p_){ + var _o_ = caml_wrap_exception(_p_); + if(_o_[1] !== Sys_error) throw caml_maybe_attach_backtrace(_o_, 0); + } + param$0 = l; + } + } + function output_bytes(oc, s){ + return caml_ml_output_bytes(oc, s, 0, caml_ml_bytes_length(s)); + } + function output_string(oc, s){ + return caml_ml_output(oc, s, 0, caml_ml_string_length(s)); + } + function output(oc, s, ofs, len){ + if(0 <= ofs && 0 <= len && (caml_ml_bytes_length(s) - len | 0) >= ofs) + return caml_ml_output_bytes(oc, s, ofs, len); + return invalid_arg(cst_output); + } + function output_substring(oc, s, ofs, len){ + if(0 <= ofs && 0 <= len && (caml_ml_string_length(s) - len | 0) >= ofs) + return caml_ml_output(oc, s, ofs, len); + return invalid_arg(cst_output_substring); + } + function output_value(chan, v){ + return runtime.caml_output_value(chan, v, 0); + } + function close_out(oc){ + caml_ml_flush(oc); + return caml_ml_close_channel(oc); + } + function close_out_noerr(oc){ + try{caml_ml_flush(oc);}catch(_n_){} + try{var _l_ = caml_ml_close_channel(oc); return _l_;}catch(_m_){return 0;} + } + function open_in_gen(mode, perm, name){ + var c = caml_ml_open_descriptor_in(caml_sys_open(name, mode, perm)); + caml_ml_set_channel_name(c, name); + return c; + } + function open_in(name){return open_in_gen(_e_, 0, name);} + function open_in_bin(name){return open_in_gen(_f_, 0, name);} + function input(ic, s, ofs, len){ + if(0 <= ofs && 0 <= len && (caml_ml_bytes_length(s) - len | 0) >= ofs) + return caml_ml_input(ic, s, ofs, len); + return invalid_arg(cst_input); + } + function unsafe_really_input(ic, s, ofs, len){ + var ofs$0 = ofs, len$0 = len; + for(;;){ + if(0 >= len$0) return 0; + var r = caml_ml_input(ic, s, ofs$0, len$0); + if(0 === r) throw caml_maybe_attach_backtrace(End_of_file, 1); + var len$1 = len$0 - r | 0, ofs$1 = ofs$0 + r | 0; + ofs$0 = ofs$1; + len$0 = len$1; + } + } + function really_input(ic, s, ofs, len){ + if(0 <= ofs && 0 <= len && (caml_ml_bytes_length(s) - len | 0) >= ofs) + return unsafe_really_input(ic, s, ofs, len); + return invalid_arg(cst_really_input); + } + function really_input_string(ic, len){ + var s = caml_create_bytes(len); + really_input(ic, s, 0, len); + return caml_string_of_bytes(s); + } + function input_line(chan){ + function build_result(buf, pos, param){ + var pos$0 = pos, param$0 = param; + for(;;){ + if(! param$0) return buf; + var tl = param$0[2], hd = param$0[1], len = caml_ml_bytes_length(hd); + runtime.caml_blit_bytes(hd, 0, buf, pos$0 - len | 0, len); + var pos$1 = pos$0 - len | 0; + pos$0 = pos$1; + param$0 = tl; + } + } + var accu = 0, len = 0; + for(;;){ + var n = runtime.caml_ml_input_scan_line(chan); + if(0 === n){ + if(! accu) throw caml_maybe_attach_backtrace(End_of_file, 1); + var _k_ = build_result(caml_create_bytes(len), len, accu); + } + else{ + if(0 >= n){ + var beg = caml_create_bytes(- n | 0); + caml_ml_input(chan, beg, 0, - n | 0); + var len$1 = len - n | 0, accu$0 = [0, beg, accu]; + accu = accu$0; + len = len$1; + continue; + } + var res = caml_create_bytes(n - 1 | 0); + caml_ml_input(chan, res, 0, n - 1 | 0); + caml_ml_input_char(chan); + if(accu) + var + len$0 = (len + n | 0) - 1 | 0, + _k_ = build_result(caml_create_bytes(len$0), len$0, [0, res, accu]); + else + var _k_ = res; + } + return caml_string_of_bytes(_k_); + } + } + function close_in_noerr(ic){ + try{var _i_ = caml_ml_close_channel(ic); return _i_;}catch(_j_){return 0;} + } + function print_char(c){return caml_ml_output_char(stdout, c);} + function print_string(s){return output_string(stdout, s);} + function print_bytes(s){return output_bytes(stdout, s);} + function print_int(i){return output_string(stdout, "" + i);} + function print_float(f){return output_string(stdout, string_of_float(f));} + function print_endline(s){ + output_string(stdout, s); + caml_ml_output_char(stdout, 10); + return caml_ml_flush(stdout); + } + function print_newline(param){ + caml_ml_output_char(stdout, 10); + return caml_ml_flush(stdout); + } + function prerr_char(c){return caml_ml_output_char(stderr, c);} + function prerr_string(s){return output_string(stderr, s);} + function prerr_bytes(s){return output_bytes(stderr, s);} + function prerr_int(i){return output_string(stderr, "" + i);} + function prerr_float(f){return output_string(stderr, string_of_float(f));} + function prerr_endline(s){ + output_string(stderr, s); + caml_ml_output_char(stderr, 10); + return caml_ml_flush(stderr); + } + function prerr_newline(param){ + caml_ml_output_char(stderr, 10); + return caml_ml_flush(stderr); + } + function read_line(param){caml_ml_flush(stdout); return input_line(stdin);} + function read_int(param){return caml_int_of_string(read_line(0));} + function read_int_opt(param){return int_of_string_opt(read_line(0));} + function read_float(param){return caml_float_of_string(read_line(0));} + function read_float_opt(param){return float_of_string_opt(read_line(0));} + function string_of_format(param){var str = param[2]; return str;} + function symbol$0(param, _h_){ + var + str2 = _h_[2], + fmt2 = _h_[1], + str1 = param[2], + fmt1 = param[1], + s2 = "%," + str2; + return [0, caml_call2(CamlinternalFormatBasics[3], fmt1, fmt2), str1 + s2]; + } + var exit_function = caml_call1(CamlinternalAtomic[1], flush_all); + function at_exit(f){ + for(;;){ + var + f_yet_to_run = caml_call1(CamlinternalAtomic[1], 1), + old_exit = caml_call1(CamlinternalAtomic[2], exit_function); + let f_yet_to_run$0 = f_yet_to_run, old_exit$0 = old_exit; + var + new_exit = + function(param){ + if(caml_call3(CamlinternalAtomic[5], f_yet_to_run$0, 1, 0)) + caml_call1(f, 0); + return caml_call1(old_exit$0, 0); + }, + success = + caml_call3(CamlinternalAtomic[5], exit_function, old_exit, new_exit), + _g_ = 1 - success; + if(! _g_) return _g_; + } + } + function do_at_exit(param){ + return caml_call1(caml_call1(CamlinternalAtomic[2], exit_function), 0); + } + function exit(retcode){ + do_at_exit(0); + return runtime.caml_sys_exit(retcode); + } + runtime.caml_register_named_value("Pervasives.do_at_exit", do_at_exit); + var + Stdlib = + [0, + invalid_arg, + failwith, + Exit, + Match_failure, + Assert_failure, + Invalid_argument, + Failure, + Not_found, + Out_of_memory, + Stack_overflow, + Sys_error, + End_of_file, + Division_by_zero, + Sys_blocked_io, + Undefined_recursive_module, + min, + max, + abs, + 2147483647, + -2147483648, + lnot, + infinity, + neg_infinity, + nan, + max_float, + min_float, + epsilon_float, + symbol_concat, + char_of_int, + string_of_bool, + bool_of_string_opt, + bool_of_string, + string_of_int, + int_of_string_opt, + string_of_float, + float_of_string_opt, + symbol, + stdin, + stdout, + stderr, + print_char, + print_string, + print_bytes, + print_int, + print_float, + print_endline, + print_newline, + prerr_char, + prerr_string, + prerr_bytes, + prerr_int, + prerr_float, + prerr_endline, + prerr_newline, + read_line, + read_int_opt, + read_int, + read_float_opt, + read_float, + open_out, + open_out_bin, + open_out_gen, + caml_ml_flush, + flush_all, + caml_ml_output_char, + output_string, + output_bytes, + output, + output_substring, + caml_ml_output_char, + runtime.caml_ml_output_int, + output_value, + runtime.caml_ml_seek_out, + runtime.caml_ml_pos_out, + caml_ml_channel_size, + close_out, + close_out_noerr, + caml_ml_set_binary_mode, + open_in, + open_in_bin, + open_in_gen, + caml_ml_input_char, + input_line, + input, + really_input, + really_input_string, + caml_ml_input_char, + runtime.caml_ml_input_int, + runtime.caml_input_value, + runtime.caml_ml_seek_in, + runtime.caml_ml_pos_in, + caml_ml_channel_size, + caml_ml_close_channel, + close_in_noerr, + caml_ml_set_binary_mode, + [0, + runtime.caml_ml_seek_out_64, + runtime.caml_ml_pos_out_64, + caml_ml_channel_size_64, + runtime.caml_ml_seek_in_64, + runtime.caml_ml_pos_in_64, + caml_ml_channel_size_64], + string_of_format, + symbol$0, + exit, + at_exit, + valid_float_lexem, + unsafe_really_input, + do_at_exit]; + runtime.caml_register_global(46, Stdlib, "Stdlib"); + return; + } + (globalThis)); + +//# 884 "../.js/default/stdlib/stdlib.cma.js" +(function(globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function empty(param){return 0;} + function return$0(x, param){return [0, x, empty];} + function cons(x, next, param){return [0, x, next];} + function append(seq1, seq2, param){ + var match = caml_call1(seq1, 0); + if(! match) return caml_call1(seq2, 0); + var next = match[2], x = match[1]; + return [0, x, function(_g_){return append(next, seq2, _g_);}]; + } + function map(f, seq, param){ + var match = caml_call1(seq, 0); + if(! match) return 0; + var next = match[2], x = match[1]; + return [0, caml_call1(f, x), function(_f_){return map(f, next, _f_);}]; + } + function filter_map(f, seq, param){ + var seq$0 = seq; + for(;;){ + var match = caml_call1(seq$0, 0); + if(! match) return 0; + var next = match[2], x = match[1], match$0 = caml_call1(f, x); + if(match$0){ + var y = match$0[1]; + return [0, y, function(_e_){return filter_map(f, next, _e_);}]; + } + seq$0 = next; + } + } + function filter(f, seq, param){ + var seq$0 = seq; + for(;;){ + var match = caml_call1(seq$0, 0); + if(! match) return 0; + var next = match[2], x = match[1]; + if(caml_call1(f, x)) + return [0, x, function(_d_){return filter(f, next, _d_);}]; + seq$0 = next; + } + } + function concat(seq, param){ + var match = caml_call1(seq, 0); + if(! match) return 0; + var next = match[2], x = match[1]; + return append(x, function(_c_){return concat(next, _c_);}, 0); + } + function flat_map(f, seq, param){ + var match = caml_call1(seq, 0); + if(! match) return 0; + var next = match[2], x = match[1]; + return append + (caml_call1(f, x), + function(_b_){return flat_map(f, next, _b_);}, + 0); + } + function fold_left(f, acc, seq){ + var acc$0 = acc, seq$0 = seq; + for(;;){ + var match = caml_call1(seq$0, 0); + if(! match) return acc$0; + var next = match[2], x = match[1], acc$1 = caml_call2(f, acc$0, x); + acc$0 = acc$1; + seq$0 = next; + } + } + function iter(f, seq){ + var seq$0 = seq; + for(;;){ + var match = caml_call1(seq$0, 0); + if(! match) return 0; + var next = match[2], x = match[1]; + caml_call1(f, x); + seq$0 = next; + } + } + function unfold(f, u, param){ + var match = caml_call1(f, u); + if(! match) return 0; + var match$0 = match[1], u$0 = match$0[2], x = match$0[1]; + return [0, x, function(_a_){return unfold(f, u$0, _a_);}]; + } + var + Stdlib_Seq = + [0, + empty, + return$0, + cons, + append, + map, + filter, + filter_map, + concat, + flat_map, + flat_map, + fold_left, + iter, + unfold]; + runtime.caml_register_global(0, Stdlib_Seq, "Stdlib__Seq"); + return; + } + (globalThis)); + +//# 1363 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + caml_bytes_unsafe_set = runtime.caml_bytes_unsafe_set, + caml_create_bytes = runtime.caml_create_bytes, + caml_string_of_bytes = runtime.caml_string_of_bytes; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + var + global_data = runtime.caml_get_global_data(), + cst = "\\\\", + cst$0 = "\\'", + Stdlib = global_data.Stdlib, + cst_Char_chr = "Char.chr", + cst_b = "\\b", + cst_t = "\\t", + cst_n = "\\n", + cst_r = "\\r"; + function chr(n){ + if(0 <= n && 255 >= n) return n; + return caml_call1(Stdlib[1], cst_Char_chr); + } + function escaped(c){ + a: + { + if(40 <= c){ + if(92 === c) return cst; + if(127 > c) break a; + } + else{ + if(32 <= c){if(39 <= c) return cst$0; break a;} + if(14 > c) + switch(c){ + case 8: + return cst_b; + case 9: + return cst_t; + case 10: + return cst_n; + case 13: + return cst_r; + } + } + var s = caml_create_bytes(4); + caml_bytes_unsafe_set(s, 0, 92); + caml_bytes_unsafe_set(s, 1, 48 + (c / 100 | 0) | 0); + caml_bytes_unsafe_set(s, 2, 48 + ((c / 10 | 0) % 10 | 0) | 0); + caml_bytes_unsafe_set(s, 3, 48 + (c % 10 | 0) | 0); + return caml_string_of_bytes(s); + } + var s$0 = caml_create_bytes(1); + caml_bytes_unsafe_set(s$0, 0, c); + return caml_string_of_bytes(s$0); + } + function lowercase(c){ + var _b_ = c - 192 | 0; + a: + { + if(30 < _b_ >>> 0){ + if(25 < _b_ + 127 >>> 0) break a; + } + else if(23 === _b_) break a; + return c + 32 | 0; + } + return c; + } + function uppercase(c){ + var _a_ = c - 224 | 0; + a: + { + if(30 < _a_ >>> 0){ + if(25 < _a_ + 127 >>> 0) break a; + } + else if(23 === _a_) break a; + return c - 32 | 0; + } + return c; + } + function lowercase_ascii(c){return 25 < c - 65 >>> 0 ? c : c + 32 | 0;} + function uppercase_ascii(c){return 25 < c - 97 >>> 0 ? c : c - 32 | 0;} + function compare(c1, c2){return c1 - c2 | 0;} + function equal(c1, c2){return 0 === (c1 - c2 | 0) ? 1 : 0;} + var + Stdlib_Char = + [0, + chr, + escaped, + lowercase, + uppercase, + lowercase_ascii, + uppercase_ascii, + compare, + equal]; + runtime.caml_register_global(8, Stdlib_Char, "Stdlib__Char"); + return; + } + (globalThis)); + +//# 1468 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + caml_format_int = runtime.caml_format_int; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + var + global_data = runtime.caml_get_global_data(), + err_no_pred = "U+0000 has no predecessor", + err_no_succ = "U+10FFFF has no successor", + Stdlib = global_data.Stdlib, + cst_is_not_an_Unicode_scalar_v = " is not an Unicode scalar value", + cst_is_not_a_latin1_character = " is not a latin1 character", + cst_U = "U+", + lo_bound = 55295, + hi_bound = 57344; + function succ(u){ + return u === 55295 + ? hi_bound + : u === 1114111 ? caml_call1(Stdlib[1], err_no_succ) : u + 1 | 0; + } + function pred(u){ + return u === 57344 + ? lo_bound + : u === 0 ? caml_call1(Stdlib[1], err_no_pred) : u - 1 | 0; + } + function is_valid(i){ + var _j_ = 0 <= i ? 1 : 0, _k_ = _j_ ? i <= 55295 ? 1 : 0 : _j_; + if(_k_) + var _l_ = _k_; + else + var _m_ = 57344 <= i ? 1 : 0, _l_ = _m_ ? i <= 1114111 ? 1 : 0 : _m_; + return _l_; + } + function of_int(i){ + if(is_valid(i)) return i; + var + _i_ = + caml_call2 + (Stdlib[28], caml_format_int("%X", i), cst_is_not_an_Unicode_scalar_v); + return caml_call1(Stdlib[1], _i_); + } + function is_char(u){return u < 256 ? 1 : 0;} + function of_char(c){return c;} + function to_char(u){ + if(255 >= u) return u; + var + _g_ = + caml_call2 + (Stdlib[28], + caml_format_int("%04X", u), + cst_is_not_a_latin1_character), + _h_ = caml_call2(Stdlib[28], cst_U, _g_); + return caml_call1(Stdlib[1], _h_); + } + function unsafe_to_char(_f_){return _f_;} + function equal(_e_, _d_){return _e_ === _d_ ? 1 : 0;} + var compare = runtime.caml_int_compare; + function hash(_c_){return _c_;} + var + Stdlib_Uchar = + [0, + 0, + 1114111, + 65279, + 65533, + succ, + pred, + is_valid, + of_int, + function(_b_){return _b_;}, + function(_a_){return _a_;}, + is_char, + of_char, + to_char, + unsafe_to_char, + equal, + compare, + hash]; + runtime.caml_register_global(8, Stdlib_Uchar, "Stdlib__Uchar"); + return; + } + (globalThis)); + +//# 1564 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace, + caml_wrap_exception = runtime.caml_wrap_exception, + global_data = runtime.caml_get_global_data(), + ocaml_version = "4.13.1", + Stdlib = global_data.Stdlib, + executable_name = runtime.caml_sys_executable_name(0), + os_type = runtime.caml_sys_get_config(0)[1], + backend_type = [0, "js_of_ocaml"], + unix = runtime.caml_sys_const_ostype_unix(0), + win32 = runtime.caml_sys_const_ostype_win32(0), + cygwin = runtime.caml_sys_const_ostype_cygwin(0), + max_array_length = runtime.caml_sys_const_max_wosize(0), + max_floatarray_length = max_array_length / 2 | 0, + max_string_length = (4 * max_array_length | 0) - 1 | 0; + function getenv_opt(s){ + try{var _d_ = [0, runtime.caml_sys_getenv(s)]; return _d_;} + catch(_e_){ + var _c_ = caml_wrap_exception(_e_); + if(_c_ === Stdlib[8]) return 0; + throw caml_maybe_attach_backtrace(_c_, 0); + } + } + var interactive = [0, 0]; + function set_signal(sig_num, sig_beh){return 0;} + var Break = [248, "Stdlib.Sys.Break", runtime.caml_fresh_oo_id(0)]; + function catch_break(on){return on ? 0 : 0;} + function Make(_b_, _a_){return [0, 1];} + var + Immediate64 = [0, Make], + Stdlib_Sys = + [0, + executable_name, + getenv_opt, + interactive, + os_type, + backend_type, + unix, + win32, + cygwin, + 32, + 32, + 0, + max_string_length, + max_array_length, + max_floatarray_length, + set_signal, + -1, + -2, + -3, + -4, + -5, + -6, + -7, + -8, + -9, + -10, + -11, + -12, + -13, + -14, + -15, + -16, + -17, + -18, + -19, + -20, + -21, + -22, + -23, + -24, + -25, + -26, + -27, + -28, + Break, + catch_break, + ocaml_version, + runtime.caml_ml_enable_runtime_warnings, + runtime.caml_ml_runtime_warnings_enabled, + Immediate64]; + runtime.caml_register_global(3, Stdlib_Sys, "Stdlib__Sys"); + return; + } + (globalThis)); + +//# 1656 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst_List_nth$1 = "List.nth", + caml_compare = runtime.caml_compare, + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + var + global_data = runtime.caml_get_global_data(), + Stdlib = global_data.Stdlib, + Stdlib_Seq = global_data.Stdlib__Seq, + Stdlib_Sys = global_data.Stdlib__Sys, + cst_hd = "hd", + cst_tl = "tl", + cst_nth = "nth", + cst_List_nth = cst_List_nth$1, + cst_List_nth$0 = cst_List_nth$1; + function length(l$0){ + var len = 0, param = l$0; + for(;;){ + if(! param) return len; + var l = param[2], len$0 = len + 1 | 0; + len = len$0; + param = l; + } + } + function cons(a, l){return [0, a, l];} + function hd(param){ + if(! param) return caml_call1(Stdlib[2], cst_hd); + var a = param[1]; + return a; + } + function tl(param){ + if(! param) return caml_call1(Stdlib[2], cst_tl); + var l = param[2]; + return l; + } + function nth(l, n){ + if(0 > n) return caml_call1(Stdlib[1], cst_List_nth); + var l$0 = l, n$0 = n; + for(;;){ + if(! l$0) return caml_call1(Stdlib[2], cst_nth); + var l$1 = l$0[2], a = l$0[1]; + if(0 === n$0) return a; + var n$1 = n$0 - 1 | 0; + l$0 = l$1; + n$0 = n$1; + } + } + function nth_opt(l, n){ + if(0 > n) return caml_call1(Stdlib[1], cst_List_nth$0); + var l$0 = l, n$0 = n; + for(;;){ + if(! l$0) return 0; + var l$1 = l$0[2], a = l$0[1]; + if(0 === n$0) return [0, a]; + var n$1 = n$0 - 1 | 0; + l$0 = l$1; + n$0 = n$1; + } + } + var append = Stdlib[37]; + function rev_append(l1, l2){ + var l1$0 = l1, l2$0 = l2; + for(;;){ + if(! l1$0) return l2$0; + var l1$1 = l1$0[2], a = l1$0[1], l2$1 = [0, a, l2$0]; + l1$0 = l1$1; + l2$0 = l2$1; + } + } + function rev(l){return rev_append(l, 0);} + function init_aux(i, n, f){ + if(n <= i) return 0; + var r = caml_call1(f, i); + return [0, r, init_aux(i + 1 | 0, n, f)]; + } + var + cst_List_map2 = "List.map2", + cst_List_iter2 = "List.iter2", + cst_List_fold_left2 = "List.fold_left2", + cst_List_fold_right2 = "List.fold_right2", + cst_List_for_all2 = "List.for_all2", + cst_List_exists2 = "List.exists2", + _b_ = [0, 0, 0], + cst_List_combine = "List.combine", + cst_List_rev_map2 = "List.rev_map2", + cst_List_init = "List.init", + rev_init_threshold = typeof Stdlib_Sys[5] === "number" ? 10000 : 50; + function init(len, f){ + if(0 > len) return caml_call1(Stdlib[1], cst_List_init); + if(rev_init_threshold >= len) return init_aux(0, len, f); + var acc = 0, i = 0; + for(;;){ + if(len <= i) return rev(acc); + var i$0 = i + 1 | 0, acc$0 = [0, caml_call1(f, i), acc]; + acc = acc$0; + i = i$0; + } + } + function flatten(param){ + if(! param) return 0; + var r = param[2], l = param[1], _H_ = flatten(r); + return caml_call2(Stdlib[37], l, _H_); + } + function map(f, param){ + if(! param) return 0; + var l = param[2], a = param[1], r = caml_call1(f, a); + return [0, r, map(f, l)]; + } + function _a_(i, f, param){ + if(! param) return 0; + var l = param[2], a = param[1], r = caml_call2(f, i, a); + return [0, r, _a_(i + 1 | 0, f, l)]; + } + function mapi(f, l){return _a_(0, f, l);} + function rev_map(f, l){ + var accu = 0, param = l; + for(;;){ + if(! param) return accu; + var l$0 = param[2], a = param[1], accu$0 = [0, caml_call1(f, a), accu]; + accu = accu$0; + param = l$0; + } + } + function iter(f, param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + var l = param$0[2], a = param$0[1]; + caml_call1(f, a); + param$0 = l; + } + } + function iteri(f, l$0){ + var i = 0, param = l$0; + for(;;){ + if(! param) return 0; + var l = param[2], a = param[1]; + caml_call2(f, i, a); + var i$0 = i + 1 | 0; + i = i$0; + param = l; + } + } + function fold_left(f, accu, l){ + var accu$0 = accu, l$0 = l; + for(;;){ + if(! l$0) return accu$0; + var l$1 = l$0[2], a = l$0[1], accu$1 = caml_call2(f, accu$0, a); + accu$0 = accu$1; + l$0 = l$1; + } + } + function fold_right(f, l, accu){ + if(! l) return accu; + var l$0 = l[2], a = l[1]; + return caml_call2(f, a, fold_right(f, l$0, accu)); + } + function map2(f, l1, l2){ + if(l1){ + if(l2){ + var + l2$0 = l2[2], + a2 = l2[1], + l1$0 = l1[2], + a1 = l1[1], + r = caml_call2(f, a1, a2); + return [0, r, map2(f, l1$0, l2$0)]; + } + } + else if(! l2) return 0; + return caml_call1(Stdlib[1], cst_List_map2); + } + function rev_map2(f, l1, l2){ + var accu = 0, l1$0 = l1, l2$0 = l2; + for(;;){ + if(l1$0){ + if(l2$0){ + var + l2$1 = l2$0[2], + a2 = l2$0[1], + l1$1 = l1$0[2], + a1 = l1$0[1], + accu$0 = [0, caml_call2(f, a1, a2), accu]; + accu = accu$0; + l1$0 = l1$1; + l2$0 = l2$1; + continue; + } + } + else if(! l2$0) return accu; + return caml_call1(Stdlib[1], cst_List_rev_map2); + } + } + function iter2(f, l1, l2){ + var l1$0 = l1, l2$0 = l2; + for(;;){ + if(l1$0){ + if(l2$0){ + var l2$1 = l2$0[2], a2 = l2$0[1], l1$1 = l1$0[2], a1 = l1$0[1]; + caml_call2(f, a1, a2); + l1$0 = l1$1; + l2$0 = l2$1; + continue; + } + } + else if(! l2$0) return 0; + return caml_call1(Stdlib[1], cst_List_iter2); + } + } + function fold_left2(f, accu, l1, l2){ + var accu$0 = accu, l1$0 = l1, l2$0 = l2; + for(;;){ + if(l1$0){ + if(l2$0){ + var + l2$1 = l2$0[2], + a2 = l2$0[1], + l1$1 = l1$0[2], + a1 = l1$0[1], + accu$1 = caml_call3(f, accu$0, a1, a2); + accu$0 = accu$1; + l1$0 = l1$1; + l2$0 = l2$1; + continue; + } + } + else if(! l2$0) return accu$0; + return caml_call1(Stdlib[1], cst_List_fold_left2); + } + } + function fold_right2(f, l1, l2, accu){ + if(l1){ + if(l2){ + var l2$0 = l2[2], a2 = l2[1], l1$0 = l1[2], a1 = l1[1]; + return caml_call3(f, a1, a2, fold_right2(f, l1$0, l2$0, accu)); + } + } + else if(! l2) return accu; + return caml_call1(Stdlib[1], cst_List_fold_right2); + } + function for_all(p, param){ + var param$0 = param; + for(;;){ + if(! param$0) return 1; + var l = param$0[2], a = param$0[1], _G_ = caml_call1(p, a); + if(! _G_) return _G_; + param$0 = l; + } + } + function exists(p, param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + var l = param$0[2], a = param$0[1], _F_ = caml_call1(p, a); + if(_F_) return _F_; + param$0 = l; + } + } + function for_all2(p, l1, l2){ + var l1$0 = l1, l2$0 = l2; + for(;;){ + if(l1$0){ + if(l2$0){ + var + l2$1 = l2$0[2], + a2 = l2$0[1], + l1$1 = l1$0[2], + a1 = l1$0[1], + _E_ = caml_call2(p, a1, a2); + if(! _E_) return _E_; + l1$0 = l1$1; + l2$0 = l2$1; + continue; + } + } + else if(! l2$0) return 1; + return caml_call1(Stdlib[1], cst_List_for_all2); + } + } + function exists2(p, l1, l2){ + var l1$0 = l1, l2$0 = l2; + for(;;){ + if(l1$0){ + if(l2$0){ + var + l2$1 = l2$0[2], + a2 = l2$0[1], + l1$1 = l1$0[2], + a1 = l1$0[1], + _D_ = caml_call2(p, a1, a2); + if(_D_) return _D_; + l1$0 = l1$1; + l2$0 = l2$1; + continue; + } + } + else if(! l2$0) return 0; + return caml_call1(Stdlib[1], cst_List_exists2); + } + } + function mem(x, param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + var + l = param$0[2], + a = param$0[1], + _C_ = 0 === caml_compare(a, x) ? 1 : 0; + if(_C_) return _C_; + param$0 = l; + } + } + function memq(x, param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + var l = param$0[2], a = param$0[1], _B_ = a === x ? 1 : 0; + if(_B_) return _B_; + param$0 = l; + } + } + function assoc(x, param){ + var param$0 = param; + for(;;){ + if(! param$0) throw caml_maybe_attach_backtrace(Stdlib[8], 1); + var l = param$0[2], match = param$0[1], b = match[2], a = match[1]; + if(0 === caml_compare(a, x)) return b; + param$0 = l; + } + } + function assoc_opt(x, param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + var l = param$0[2], match = param$0[1], b = match[2], a = match[1]; + if(0 === caml_compare(a, x)) return [0, b]; + param$0 = l; + } + } + function assq(x, param){ + var param$0 = param; + for(;;){ + if(! param$0) throw caml_maybe_attach_backtrace(Stdlib[8], 1); + var l = param$0[2], match = param$0[1], b = match[2], a = match[1]; + if(a === x) return b; + param$0 = l; + } + } + function assq_opt(x, param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + var l = param$0[2], match = param$0[1], b = match[2], a = match[1]; + if(a === x) return [0, b]; + param$0 = l; + } + } + function mem_assoc(x, param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + var + l = param$0[2], + a = param$0[1][1], + _A_ = 0 === caml_compare(a, x) ? 1 : 0; + if(_A_) return _A_; + param$0 = l; + } + } + function mem_assq(x, param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + var l = param$0[2], a = param$0[1][1], _z_ = a === x ? 1 : 0; + if(_z_) return _z_; + param$0 = l; + } + } + function remove_assoc(x, param){ + if(! param) return 0; + var l = param[2], pair = param[1], a = pair[1]; + return 0 === caml_compare(a, x) ? l : [0, pair, remove_assoc(x, l)]; + } + function remove_assq(x, param){ + if(! param) return 0; + var l = param[2], pair = param[1], a = pair[1]; + return a === x ? l : [0, pair, remove_assq(x, l)]; + } + function find(p, param){ + var param$0 = param; + for(;;){ + if(! param$0) throw caml_maybe_attach_backtrace(Stdlib[8], 1); + var l = param$0[2], x = param$0[1]; + if(caml_call1(p, x)) return x; + param$0 = l; + } + } + function find_opt(p, param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + var l = param$0[2], x = param$0[1]; + if(caml_call1(p, x)) return [0, x]; + param$0 = l; + } + } + function find_map(f, param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + var l = param$0[2], x = param$0[1], result = caml_call1(f, x); + if(result) return result; + param$0 = l; + } + } + function find_all(p){ + var accu = 0; + return function(param$0){ + var accu$0 = accu, param = param$0; + for(;;){ + if(! param) return rev(accu$0); + var l = param[2], x = param[1]; + if(caml_call1(p, x)){ + var accu$1 = [0, x, accu$0]; + accu$0 = accu$1; + param = l; + } + else + param = l; + }}; + } + function filteri(p, l){ + var i = 0, acc = 0, param = l; + for(;;){ + if(! param) return rev(acc); + var + l$0 = param[2], + x = param[1], + acc$0 = caml_call2(p, i, x) ? [0, x, acc] : acc, + i$0 = i + 1 | 0; + i = i$0; + acc = acc$0; + param = l$0; + } + } + function filter_map(f){ + var accu = 0; + return function(param$0){ + var accu$0 = accu, param = param$0; + for(;;){ + if(! param) return rev(accu$0); + var l = param[2], x = param[1], match = caml_call1(f, x); + if(match){ + var v = match[1], accu$1 = [0, v, accu$0]; + accu$0 = accu$1; + param = l; + } + else + param = l; + }}; + } + function concat_map(f, l){ + var acc = 0, param = l; + for(;;){ + if(! param) return rev(acc); + var + l$0 = param[2], + x = param[1], + xs = caml_call1(f, x), + acc$0 = rev_append(xs, acc); + acc = acc$0; + param = l$0; + } + } + function fold_left_map(f, accu, l){ + var accu$0 = accu, l_accu = 0, param = l; + for(;;){ + if(! param) return [0, accu$0, rev(l_accu)]; + var + l$0 = param[2], + x = param[1], + match = caml_call2(f, accu$0, x), + x$0 = match[2], + accu$1 = match[1], + l_accu$0 = [0, x$0, l_accu]; + accu$0 = accu$1; + l_accu = l_accu$0; + param = l$0; + } + } + function partition(p, l){ + var yes = 0, no = 0, param = l; + for(;;){ + if(! param){var _y_ = rev(no); return [0, rev(yes), _y_];} + var l$0 = param[2], x = param[1]; + if(caml_call1(p, x)){ + var yes$0 = [0, x, yes]; + yes = yes$0; + param = l$0; + } + else{var no$0 = [0, x, no]; no = no$0; param = l$0;} + } + } + function partition_map(p, l){ + var left = 0, right = 0, param = l; + for(;;){ + if(! param){var _x_ = rev(right); return [0, rev(left), _x_];} + var l$0 = param[2], x = param[1], match = caml_call1(p, x); + if(0 === match[0]){ + var v = match[1], left$0 = [0, v, left]; + left = left$0; + param = l$0; + } + else{ + var v$0 = match[1], right$0 = [0, v$0, right]; + right = right$0; + param = l$0; + } + } + } + function split(param){ + if(! param) return _b_; + var + l = param[2], + match = param[1], + y = match[2], + x = match[1], + match$0 = split(l), + ry = match$0[2], + rx = match$0[1]; + return [0, [0, x, rx], [0, y, ry]]; + } + function combine(l1, l2){ + if(l1){ + if(l2){ + var l2$0 = l2[2], a2 = l2[1], l1$0 = l1[2], a1 = l1[1]; + return [0, [0, a1, a2], combine(l1$0, l2$0)]; + } + } + else if(! l2) return 0; + return caml_call1(Stdlib[1], cst_List_combine); + } + function merge(cmp, l1, l2){ + if(! l1) return l2; + if(! l2) return l1; + var t2 = l2[2], h2 = l2[1], t1 = l1[2], h1 = l1[1]; + return 0 < caml_call2(cmp, h1, h2) + ? [0, h2, merge(cmp, l1, t2)] + : [0, h1, merge(cmp, t1, l2)]; + } + function stable_sort(cmp, l){ + function sort(n, l){ + if(2 === n){ + if(l){ + var match = l[2]; + if(match){ + var + tl = match[2], + x2 = match[1], + x1 = l[1], + s = + 0 < caml_call2(cmp, x1, x2) + ? [0, x2, [0, x1, 0]] + : [0, x1, [0, x2, 0]]; + return [0, s, tl]; + } + } + } + else if(3 === n && l){ + var _w_ = l[2]; + if(_w_){ + var match$2 = _w_[2]; + if(match$2){ + var + tl$1 = match$2[2], + x3 = match$2[1], + x2$0 = _w_[1], + x1$0 = l[1], + s$0 = + 0 < caml_call2(cmp, x1$0, x2$0) + ? 0 + < caml_call2(cmp, x1$0, x3) + ? 0 + < caml_call2(cmp, x2$0, x3) + ? [0, x3, [0, x2$0, [0, x1$0, 0]]] + : [0, x2$0, [0, x3, [0, x1$0, 0]]] + : [0, x2$0, [0, x1$0, [0, x3, 0]]] + : 0 + < caml_call2(cmp, x2$0, x3) + ? 0 + < caml_call2(cmp, x1$0, x3) + ? [0, x3, [0, x1$0, [0, x2$0, 0]]] + : [0, x1$0, [0, x3, [0, x2$0, 0]]] + : [0, x1$0, [0, x2$0, [0, x3, 0]]]; + return [0, s$0, tl$1]; + } + } + } + var + n1 = n >> 1, + n2 = n - n1 | 0, + match$0 = rev_sort(n1, l), + l2$0 = match$0[2], + s1 = match$0[1], + match$1 = rev_sort(n2, l2$0), + tl$0 = match$1[2], + s2 = match$1[1], + l1 = s1, + l2 = s2, + accu = 0; + for(;;){ + if(l1){ + if(l2){ + var t2 = l2[2], h2 = l2[1], t1 = l1[2], h1 = l1[1]; + if(0 < caml_call2(cmp, h1, h2)){ + var accu$0 = [0, h1, accu]; + l1 = t1; + accu = accu$0; + continue; + } + var accu$1 = [0, h2, accu]; + l2 = t2; + accu = accu$1; + continue; + } + var _v_ = rev_append(l1, accu); + } + else + var _v_ = rev_append(l2, accu); + return [0, _v_, tl$0]; + } + } + function rev_sort(n, l){ + if(2 === n){ + if(l){ + var match = l[2]; + if(match){ + var + tl = match[2], + x2 = match[1], + x1 = l[1], + s = + 0 < caml_call2(cmp, x1, x2) + ? [0, x1, [0, x2, 0]] + : [0, x2, [0, x1, 0]]; + return [0, s, tl]; + } + } + } + else if(3 === n && l){ + var _u_ = l[2]; + if(_u_){ + var match$2 = _u_[2]; + if(match$2){ + var + tl$1 = match$2[2], + x3 = match$2[1], + x2$0 = _u_[1], + x1$0 = l[1], + s$0 = + 0 < caml_call2(cmp, x1$0, x2$0) + ? 0 + < caml_call2(cmp, x2$0, x3) + ? [0, x1$0, [0, x2$0, [0, x3, 0]]] + : 0 + < caml_call2(cmp, x1$0, x3) + ? [0, x1$0, [0, x3, [0, x2$0, 0]]] + : [0, x3, [0, x1$0, [0, x2$0, 0]]] + : 0 + < caml_call2(cmp, x1$0, x3) + ? [0, x2$0, [0, x1$0, [0, x3, 0]]] + : 0 + < caml_call2(cmp, x2$0, x3) + ? [0, x2$0, [0, x3, [0, x1$0, 0]]] + : [0, x3, [0, x2$0, [0, x1$0, 0]]]; + return [0, s$0, tl$1]; + } + } + } + var + n1 = n >> 1, + n2 = n - n1 | 0, + match$0 = sort(n1, l), + l2$0 = match$0[2], + s1 = match$0[1], + match$1 = sort(n2, l2$0), + tl$0 = match$1[2], + s2 = match$1[1], + l1 = s1, + l2 = s2, + accu = 0; + for(;;){ + if(l1){ + if(l2){ + var t2 = l2[2], h2 = l2[1], t1 = l1[2], h1 = l1[1]; + if(0 < caml_call2(cmp, h1, h2)){ + var accu$0 = [0, h2, accu]; + l2 = t2; + accu = accu$0; + continue; + } + var accu$1 = [0, h1, accu]; + l1 = t1; + accu = accu$1; + continue; + } + var _t_ = rev_append(l1, accu); + } + else + var _t_ = rev_append(l2, accu); + return [0, _t_, tl$0]; + } + } + var len = length(l); + return 2 <= len ? sort(len, l)[1] : l; + } + function sort_uniq(cmp, l){ + function sort(n, l){ + if(2 === n){ + if(l){ + var match = l[2]; + if(match){ + var + tl = match[2], + x2 = match[1], + x1 = l[1], + c$0 = caml_call2(cmp, x1, x2), + s = + 0 === c$0 + ? [0, x1, 0] + : 0 <= c$0 ? [0, x2, [0, x1, 0]] : [0, x1, [0, x2, 0]]; + return [0, s, tl]; + } + } + } + else if(3 === n && l){ + var _n_ = l[2]; + if(_n_){ + var match$2 = _n_[2]; + if(match$2){ + var + tl$1 = match$2[2], + x3 = match$2[1], + x2$0 = _n_[1], + x1$0 = l[1], + c$1 = caml_call2(cmp, x1$0, x2$0); + if(0 === c$1) + var + c$2 = caml_call2(cmp, x2$0, x3), + _o_ = + 0 === c$2 + ? [0, x2$0, 0] + : 0 <= c$2 ? [0, x3, [0, x2$0, 0]] : [0, x2$0, [0, x3, 0]], + s$0 = _o_; + else if(0 <= c$1){ + var c$3 = caml_call2(cmp, x1$0, x3); + if(0 === c$3) + var _p_ = [0, x2$0, [0, x1$0, 0]]; + else if(0 <= c$3) + var + c$4 = caml_call2(cmp, x2$0, x3), + _q_ = + 0 === c$4 + ? [0, x2$0, [0, x1$0, 0]] + : 0 + <= c$4 + ? [0, x3, [0, x2$0, [0, x1$0, 0]]] + : [0, x2$0, [0, x3, [0, x1$0, 0]]], + _p_ = _q_; + else + var _p_ = [0, x2$0, [0, x1$0, [0, x3, 0]]]; + var s$0 = _p_; + } + else{ + var c$5 = caml_call2(cmp, x2$0, x3); + if(0 === c$5) + var _r_ = [0, x1$0, [0, x2$0, 0]]; + else if(0 <= c$5) + var + c$6 = caml_call2(cmp, x1$0, x3), + _s_ = + 0 === c$6 + ? [0, x1$0, [0, x2$0, 0]] + : 0 + <= c$6 + ? [0, x3, [0, x1$0, [0, x2$0, 0]]] + : [0, x1$0, [0, x3, [0, x2$0, 0]]], + _r_ = _s_; + else + var _r_ = [0, x1$0, [0, x2$0, [0, x3, 0]]]; + var s$0 = _r_; + } + return [0, s$0, tl$1]; + } + } + } + var + n1 = n >> 1, + n2 = n - n1 | 0, + match$0 = rev_sort(n1, l), + l2$0 = match$0[2], + s1 = match$0[1], + match$1 = rev_sort(n2, l2$0), + tl$0 = match$1[2], + s2 = match$1[1], + l1 = s1, + l2 = s2, + accu = 0; + for(;;){ + if(l1){ + if(l2){ + var + t2 = l2[2], + h2 = l2[1], + t1 = l1[2], + h1 = l1[1], + c = caml_call2(cmp, h1, h2); + if(0 === c){ + var accu$0 = [0, h1, accu]; + l1 = t1; + l2 = t2; + accu = accu$0; + continue; + } + if(0 < c){ + var accu$1 = [0, h1, accu]; + l1 = t1; + accu = accu$1; + continue; + } + var accu$2 = [0, h2, accu]; + l2 = t2; + accu = accu$2; + continue; + } + var _m_ = rev_append(l1, accu); + } + else + var _m_ = rev_append(l2, accu); + return [0, _m_, tl$0]; + } + } + function rev_sort(n, l){ + if(2 === n){ + if(l){ + var match = l[2]; + if(match){ + var + tl = match[2], + x2 = match[1], + x1 = l[1], + c$0 = caml_call2(cmp, x1, x2), + s = + 0 === c$0 + ? [0, x1, 0] + : 0 < c$0 ? [0, x1, [0, x2, 0]] : [0, x2, [0, x1, 0]]; + return [0, s, tl]; + } + } + } + else if(3 === n && l){ + var _g_ = l[2]; + if(_g_){ + var match$2 = _g_[2]; + if(match$2){ + var + tl$1 = match$2[2], + x3 = match$2[1], + x2$0 = _g_[1], + x1$0 = l[1], + c$1 = caml_call2(cmp, x1$0, x2$0); + if(0 === c$1) + var + c$2 = caml_call2(cmp, x2$0, x3), + _h_ = + 0 === c$2 + ? [0, x2$0, 0] + : 0 < c$2 ? [0, x2$0, [0, x3, 0]] : [0, x3, [0, x2$0, 0]], + s$0 = _h_; + else if(0 < c$1){ + var c$3 = caml_call2(cmp, x2$0, x3); + if(0 === c$3) + var _i_ = [0, x1$0, [0, x2$0, 0]]; + else if(0 < c$3) + var _i_ = [0, x1$0, [0, x2$0, [0, x3, 0]]]; + else + var + c$4 = caml_call2(cmp, x1$0, x3), + _j_ = + 0 === c$4 + ? [0, x1$0, [0, x2$0, 0]] + : 0 + < c$4 + ? [0, x1$0, [0, x3, [0, x2$0, 0]]] + : [0, x3, [0, x1$0, [0, x2$0, 0]]], + _i_ = _j_; + var s$0 = _i_; + } + else{ + var c$5 = caml_call2(cmp, x1$0, x3); + if(0 === c$5) + var _k_ = [0, x2$0, [0, x1$0, 0]]; + else if(0 < c$5) + var _k_ = [0, x2$0, [0, x1$0, [0, x3, 0]]]; + else + var + c$6 = caml_call2(cmp, x2$0, x3), + _l_ = + 0 === c$6 + ? [0, x2$0, [0, x1$0, 0]] + : 0 + < c$6 + ? [0, x2$0, [0, x3, [0, x1$0, 0]]] + : [0, x3, [0, x2$0, [0, x1$0, 0]]], + _k_ = _l_; + var s$0 = _k_; + } + return [0, s$0, tl$1]; + } + } + } + var + n1 = n >> 1, + n2 = n - n1 | 0, + match$0 = sort(n1, l), + l2$0 = match$0[2], + s1 = match$0[1], + match$1 = sort(n2, l2$0), + tl$0 = match$1[2], + s2 = match$1[1], + l1 = s1, + l2 = s2, + accu = 0; + for(;;){ + if(l1){ + if(l2){ + var + t2 = l2[2], + h2 = l2[1], + t1 = l1[2], + h1 = l1[1], + c = caml_call2(cmp, h1, h2); + if(0 === c){ + var accu$0 = [0, h1, accu]; + l1 = t1; + l2 = t2; + accu = accu$0; + continue; + } + if(0 <= c){ + var accu$1 = [0, h2, accu]; + l2 = t2; + accu = accu$1; + continue; + } + var accu$2 = [0, h1, accu]; + l1 = t1; + accu = accu$2; + continue; + } + var _f_ = rev_append(l1, accu); + } + else + var _f_ = rev_append(l2, accu); + return [0, _f_, tl$0]; + } + } + var len = length(l); + return 2 <= len ? sort(len, l)[1] : l; + } + function compare_lengths(l1, l2){ + var l1$0 = l1, l2$0 = l2; + for(;;){ + if(! l1$0) return l2$0 ? -1 : 0; + if(! l2$0) return 1; + var l2$1 = l2$0[2], l1$1 = l1$0[2]; + l1$0 = l1$1; + l2$0 = l2$1; + } + } + function compare_length_with(l, n){ + var l$0 = l, n$0 = n; + for(;;){ + if(! l$0) return 0 === n$0 ? 0 : 0 < n$0 ? -1 : 1; + var l$1 = l$0[2]; + if(0 >= n$0) return 1; + var n$1 = n$0 - 1 | 0; + l$0 = l$1; + n$0 = n$1; + } + } + function equal(eq, l1, l2){ + var l1$0 = l1, l2$0 = l2; + for(;;){ + if(l1$0){ + if(l2$0){ + var + l2$1 = l2$0[2], + a2 = l2$0[1], + l1$1 = l1$0[2], + a1 = l1$0[1], + _e_ = caml_call2(eq, a1, a2); + if(! _e_) return _e_; + l1$0 = l1$1; + l2$0 = l2$1; + continue; + } + } + else if(! l2$0) return 1; + return 0; + } + } + function compare(cmp, l1, l2){ + var l1$0 = l1, l2$0 = l2; + for(;;){ + if(! l1$0) return l2$0 ? -1 : 0; + var l1$1 = l1$0[2], a1 = l1$0[1]; + if(! l2$0) return 1; + var l2$1 = l2$0[2], a2 = l2$0[1], c = caml_call2(cmp, a1, a2); + if(0 !== c) return c; + l1$0 = l1$1; + l2$0 = l2$1; + } + } + function to_seq(l){ + function aux(l, param){ + if(! l) return 0; + var tail = l[2], x = l[1]; + return [0, x, function(_d_){return aux(tail, _d_);}]; + } + return function(_c_){return aux(l, _c_);}; + } + function of_seq(seq){ + function direct(depth, seq){ + if(0 === depth) + return rev + (caml_call3 + (Stdlib_Seq[11], + function(acc, x){return [0, x, acc];}, + 0, + seq)); + var match = caml_call1(seq, 0); + if(! match) return 0; + var next = match[2], x = match[1]; + return [0, x, direct(depth - 1 | 0, next)]; + } + return direct(500, seq); + } + var + Stdlib_List = + [0, + length, + compare_lengths, + compare_length_with, + cons, + hd, + tl, + nth, + nth_opt, + rev, + init, + append, + rev_append, + flatten, + flatten, + equal, + compare, + iter, + iteri, + map, + mapi, + rev_map, + filter_map, + concat_map, + fold_left_map, + fold_left, + fold_right, + iter2, + map2, + rev_map2, + fold_left2, + fold_right2, + for_all, + exists, + for_all2, + exists2, + mem, + memq, + find, + find_opt, + find_map, + find_all, + find_all, + filteri, + partition, + partition_map, + assoc, + assoc_opt, + assq, + assq_opt, + mem_assoc, + mem_assq, + remove_assoc, + remove_assq, + split, + combine, + stable_sort, + stable_sort, + stable_sort, + sort_uniq, + merge, + to_seq, + of_seq]; + runtime.caml_register_global(18, Stdlib_List, "Stdlib__List"); + return; + } + (globalThis)); + +//# 2793 "../.js/default/stdlib/stdlib.cma.js" +(function(globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function abs(x){return 0 <= x ? x : - x | 0;} + function lognot(x){return x ^ -1;} + function equal(_b_, _a_){return _b_ === _a_ ? 1 : 0;} + var compare = runtime.caml_int_compare; + function min(x, y){return x <= y ? x : y;} + function max(x, y){return y <= x ? x : y;} + function to_string(x){return "" + x;} + var + Stdlib_Int = + [0, + 0, + 1, + -1, + abs, + 2147483647, + -2147483648, + lognot, + equal, + compare, + min, + max, + to_string]; + runtime.caml_register_global(1, Stdlib_Int, "Stdlib__Int"); + return; + } + (globalThis)); + +//# 2825 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + caml_blit_bytes = runtime.caml_blit_bytes, + caml_bswap16 = runtime.caml_bswap16, + caml_bytes_get = runtime.caml_bytes_get, + caml_bytes_get16 = runtime.caml_bytes_get16, + caml_bytes_get32 = runtime.caml_bytes_get32, + caml_bytes_get64 = runtime.caml_bytes_get64, + caml_bytes_of_string = runtime.caml_bytes_of_string, + caml_bytes_set = runtime.caml_bytes_set, + caml_bytes_set16 = runtime.caml_bytes_set16, + caml_bytes_set32 = runtime.caml_bytes_set32, + caml_bytes_set64 = runtime.caml_bytes_set64, + caml_bytes_unsafe_get = runtime.caml_bytes_unsafe_get, + caml_bytes_unsafe_set = runtime.caml_bytes_unsafe_set, + caml_create_bytes = runtime.caml_create_bytes, + caml_fill_bytes = runtime.caml_fill_bytes, + caml_int32_bswap = runtime.caml_int32_bswap, + caml_int64_bswap = runtime.caml_int64_bswap, + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace, + caml_ml_bytes_length = runtime.caml_ml_bytes_length, + caml_string_of_bytes = runtime.caml_string_of_bytes, + caml_wrap_exception = runtime.caml_wrap_exception; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + var + global_data = runtime.caml_get_global_data(), + Stdlib = global_data.Stdlib, + Stdlib_Sys = global_data.Stdlib__Sys, + Stdlib_Int = global_data.Stdlib__Int, + Stdlib_Seq = global_data.Stdlib__Seq, + Stdlib_Char = global_data.Stdlib__Char; + function make(n, c){ + var s = caml_create_bytes(n); + caml_fill_bytes(s, 0, n, c); + return s; + } + function init(n, f){ + var s = caml_create_bytes(n), _ad_ = n - 1 | 0, _ac_ = 0; + if(_ad_ >= 0){ + var i = _ac_; + for(;;){ + caml_bytes_unsafe_set(s, i, caml_call1(f, i)); + var _ae_ = i + 1 | 0; + if(_ad_ === i) break; + i = _ae_; + } + } + return s; + } + var + empty = caml_create_bytes(0), + cst_String_sub_Bytes_sub = "String.sub / Bytes.sub", + cst_Bytes_extend = "Bytes.extend", + cst_String_fill_Bytes_fill = "String.fill / Bytes.fill", + cst_Bytes_blit = "Bytes.blit", + cst_String_blit_Bytes_blit_str = "String.blit / Bytes.blit_string", + cst_Bytes_concat = "Bytes.concat", + cst_String_index_from_Bytes_in = "String.index_from / Bytes.index_from", + cst_String_index_from_opt_Byte = + "String.index_from_opt / Bytes.index_from_opt", + cst_String_rindex_from_Bytes_r = "String.rindex_from / Bytes.rindex_from", + cst_String_rindex_from_opt_Byt = + "String.rindex_from_opt / Bytes.rindex_from_opt", + cst_String_contains_from_Bytes = + "String.contains_from / Bytes.contains_from", + cst_String_rcontains_from_Byte = + "String.rcontains_from / Bytes.rcontains_from"; + function copy(s){ + var len = caml_ml_bytes_length(s), r = caml_create_bytes(len); + caml_blit_bytes(s, 0, r, 0, len); + return r; + } + function to_string(b){return caml_string_of_bytes(copy(b));} + function of_string(s){return copy(caml_bytes_of_string(s));} + function sub(s, ofs, len){ + if(0 <= ofs && 0 <= len && (caml_ml_bytes_length(s) - len | 0) >= ofs){ + var r = caml_create_bytes(len); + caml_blit_bytes(s, ofs, r, 0, len); + return r; + } + return caml_call1(Stdlib[1], cst_String_sub_Bytes_sub); + } + function sub_string(b, ofs, len){ + return caml_string_of_bytes(sub(b, ofs, len)); + } + function symbol(a, b){ + var c = a + b | 0, _ab_ = b < 0 ? 1 : 0, match = c < 0 ? 1 : 0; + a: + { + if(a < 0){if(_ab_ && ! match) break a;} else if(! _ab_ && match) break a; + return c; + } + return caml_call1(Stdlib[1], cst_Bytes_extend); + } + function extend(s, left, right){ + var + len = symbol(symbol(caml_ml_bytes_length(s), left), right), + r = caml_create_bytes(len); + if(0 <= left) + var dstoff = left, srcoff = 0; + else + var dstoff = 0, srcoff = - left | 0; + var + cpylen = + caml_call2 + (Stdlib_Int[10], + caml_ml_bytes_length(s) - srcoff | 0, + len - dstoff | 0); + if(0 < cpylen) caml_blit_bytes(s, srcoff, r, dstoff, cpylen); + return r; + } + function fill(s, ofs, len, c){ + if(0 <= ofs && 0 <= len && (caml_ml_bytes_length(s) - len | 0) >= ofs) + return caml_fill_bytes(s, ofs, len, c); + return caml_call1(Stdlib[1], cst_String_fill_Bytes_fill); + } + function blit(s1, ofs1, s2, ofs2, len){ + if + (0 <= len + && + 0 <= ofs1 + && + (caml_ml_bytes_length(s1) - len | 0) >= ofs1 + && 0 <= ofs2 && (caml_ml_bytes_length(s2) - len | 0) >= ofs2) + return caml_blit_bytes(s1, ofs1, s2, ofs2, len); + return caml_call1(Stdlib[1], cst_Bytes_blit); + } + function blit_string(s1, ofs1, s2, ofs2, len){ + if + (0 <= len + && + 0 <= ofs1 + && + (runtime.caml_ml_string_length(s1) - len | 0) >= ofs1 + && 0 <= ofs2 && (caml_ml_bytes_length(s2) - len | 0) >= ofs2) + return runtime.caml_blit_string(s1, ofs1, s2, ofs2, len); + return caml_call1(Stdlib[1], cst_String_blit_Bytes_blit_str); + } + function iter(f, a){ + var _$_ = caml_ml_bytes_length(a) - 1 | 0, ___ = 0; + if(_$_ >= 0){ + var i = ___; + for(;;){ + caml_call1(f, caml_bytes_unsafe_get(a, i)); + var _aa_ = i + 1 | 0; + if(_$_ === i) break; + i = _aa_; + } + } + return 0; + } + function iteri(f, a){ + var _Y_ = caml_ml_bytes_length(a) - 1 | 0, _X_ = 0; + if(_Y_ >= 0){ + var i = _X_; + for(;;){ + caml_call2(f, i, caml_bytes_unsafe_get(a, i)); + var _Z_ = i + 1 | 0; + if(_Y_ === i) break; + i = _Z_; + } + } + return 0; + } + function concat(sep, l){ + if(! l) return empty; + var seplen = caml_ml_bytes_length(sep); + a: + { + b: + { + var acc = 0, param = l, pos$1 = 0; + for(;;){ + if(! param) break; + var hd = param[1]; + if(! param[2]) break b; + var + tl = param[2], + x = (caml_ml_bytes_length(hd) + seplen | 0) + acc | 0, + acc$0 = acc <= x ? x : caml_call1(Stdlib[1], cst_Bytes_concat); + acc = acc$0; + param = tl; + } + var _W_ = acc; + break a; + } + var _W_ = caml_ml_bytes_length(hd) + acc | 0; + } + var dst = caml_create_bytes(_W_), pos = pos$1, param$0 = l; + for(;;){ + if(! param$0) return dst; + var hd$0 = param$0[1]; + if(! param$0[2]){ + caml_blit_bytes(hd$0, 0, dst, pos, caml_ml_bytes_length(hd$0)); + return dst; + } + var tl$0 = param$0[2]; + caml_blit_bytes(hd$0, 0, dst, pos, caml_ml_bytes_length(hd$0)); + caml_blit_bytes + (sep, 0, dst, pos + caml_ml_bytes_length(hd$0) | 0, seplen); + var pos$0 = (pos + caml_ml_bytes_length(hd$0) | 0) + seplen | 0; + pos = pos$0; + param$0 = tl$0; + } + } + function cat(s1, s2){ + var + l1 = caml_ml_bytes_length(s1), + l2 = caml_ml_bytes_length(s2), + r = caml_create_bytes(l1 + l2 | 0); + caml_blit_bytes(s1, 0, r, 0, l1); + caml_blit_bytes(s2, 0, r, l1, l2); + return r; + } + function is_space(param){ + var _V_ = param - 9 | 0; + a: + { + if(4 < _V_ >>> 0){if(23 !== _V_) break a;} else if(2 === _V_) break a; + return 1; + } + return 0; + } + function trim(s){ + var len = caml_ml_bytes_length(s), i = [0, 0]; + for(;;){ + if(i[1] >= len) break; + if(! is_space(caml_bytes_unsafe_get(s, i[1]))) break; + i[1]++; + } + var j = [0, len - 1 | 0]; + for(;;){ + if(i[1] <= j[1] && is_space(caml_bytes_unsafe_get(s, j[1]))){j[1]--; continue;} + return i[1] <= j[1] ? sub(s, i[1], (j[1] - i[1] | 0) + 1 | 0) : empty; + } + } + function escaped(s){ + var n = [0, 0], _O_ = caml_ml_bytes_length(s) - 1 | 0, _N_ = 0; + if(_O_ >= 0){ + var i$0 = _N_; + for(;;){ + var match = caml_bytes_unsafe_get(s, i$0); + a: + { + b: + { + c: + { + if(32 <= match){ + var _S_ = match - 34 | 0; + if(58 < _S_ >>> 0){ + if(93 <= _S_) break c; + } + else if(56 < _S_ - 1 >>> 0) break b; + var _T_ = 1; + break a; + } + if(11 <= match){ + if(13 === match) break b; + } + else if(8 <= match) break b; + } + var _T_ = 4; + break a; + } + var _T_ = 2; + } + n[1] = n[1] + _T_ | 0; + var _U_ = i$0 + 1 | 0; + if(_O_ === i$0) break; + i$0 = _U_; + } + } + if(n[1] === caml_ml_bytes_length(s)) return copy(s); + var s$0 = caml_create_bytes(n[1]); + n[1] = 0; + var _Q_ = caml_ml_bytes_length(s) - 1 | 0, _P_ = 0; + if(_Q_ >= 0){ + var i = _P_; + for(;;){ + var c = caml_bytes_unsafe_get(s, i); + a: + { + b: + { + c: + { + if(35 <= c){ + if(92 !== c){if(127 <= c) break c; break b;} + } + else{ + if(32 > c){ + if(14 <= c) break c; + switch(c){ + case 8: + caml_bytes_unsafe_set(s$0, n[1], 92); + n[1]++; + caml_bytes_unsafe_set(s$0, n[1], 98); + break a; + case 9: + caml_bytes_unsafe_set(s$0, n[1], 92); + n[1]++; + caml_bytes_unsafe_set(s$0, n[1], 116); + break a; + case 10: + caml_bytes_unsafe_set(s$0, n[1], 92); + n[1]++; + caml_bytes_unsafe_set(s$0, n[1], 110); + break a; + case 13: + caml_bytes_unsafe_set(s$0, n[1], 92); + n[1]++; + caml_bytes_unsafe_set(s$0, n[1], 114); + break a; + default: break c; + } + } + if(34 > c) break b; + } + caml_bytes_unsafe_set(s$0, n[1], 92); + n[1]++; + caml_bytes_unsafe_set(s$0, n[1], c); + break a; + } + caml_bytes_unsafe_set(s$0, n[1], 92); + n[1]++; + caml_bytes_unsafe_set(s$0, n[1], 48 + (c / 100 | 0) | 0); + n[1]++; + caml_bytes_unsafe_set(s$0, n[1], 48 + ((c / 10 | 0) % 10 | 0) | 0); + n[1]++; + caml_bytes_unsafe_set(s$0, n[1], 48 + (c % 10 | 0) | 0); + break a; + } + caml_bytes_unsafe_set(s$0, n[1], c); + } + n[1]++; + var _R_ = i + 1 | 0; + if(_Q_ === i) break; + i = _R_; + } + } + return s$0; + } + function map(f, s){ + var l = caml_ml_bytes_length(s); + if(0 === l) return s; + var r = caml_create_bytes(l), _L_ = l - 1 | 0, _K_ = 0; + if(_L_ >= 0){ + var i = _K_; + for(;;){ + caml_bytes_unsafe_set(r, i, caml_call1(f, caml_bytes_unsafe_get(s, i))); + var _M_ = i + 1 | 0; + if(_L_ === i) break; + i = _M_; + } + } + return r; + } + function mapi(f, s){ + var l = caml_ml_bytes_length(s); + if(0 === l) return s; + var r = caml_create_bytes(l), _I_ = l - 1 | 0, _H_ = 0; + if(_I_ >= 0){ + var i = _H_; + for(;;){ + caml_bytes_unsafe_set + (r, i, caml_call2(f, i, caml_bytes_unsafe_get(s, i))); + var _J_ = i + 1 | 0; + if(_I_ === i) break; + i = _J_; + } + } + return r; + } + function fold_left(f, x, a){ + var r = [0, x], _F_ = caml_ml_bytes_length(a) - 1 | 0, _E_ = 0; + if(_F_ >= 0){ + var i = _E_; + for(;;){ + r[1] = caml_call2(f, r[1], caml_bytes_unsafe_get(a, i)); + var _G_ = i + 1 | 0; + if(_F_ === i) break; + i = _G_; + } + } + return r[1]; + } + function fold_right(f, a, x){ + var r = [0, x], _C_ = caml_ml_bytes_length(a) - 1 | 0; + if(_C_ >= 0){ + var i = _C_; + for(;;){ + r[1] = caml_call2(f, caml_bytes_unsafe_get(a, i), r[1]); + var _D_ = i - 1 | 0; + if(0 === i) break; + i = _D_; + } + } + return r[1]; + } + function exists(p, s){ + var n = caml_ml_bytes_length(s), i = 0; + for(;;){ + if(i === n) return 0; + if(caml_call1(p, caml_bytes_unsafe_get(s, i))) return 1; + var i$0 = i + 1 | 0; + i = i$0; + } + } + function for_all(p, s){ + var n = caml_ml_bytes_length(s), i = 0; + for(;;){ + if(i === n) return 1; + if(! caml_call1(p, caml_bytes_unsafe_get(s, i))) return 0; + var i$0 = i + 1 | 0; + i = i$0; + } + } + function uppercase_ascii(s){return map(Stdlib_Char[6], s);} + function lowercase_ascii(s){return map(Stdlib_Char[5], s);} + function apply1(f, s){ + if(0 === caml_ml_bytes_length(s)) return s; + var r = copy(s); + caml_bytes_unsafe_set(r, 0, caml_call1(f, caml_bytes_unsafe_get(s, 0))); + return r; + } + function capitalize_ascii(s){return apply1(Stdlib_Char[6], s);} + function uncapitalize_ascii(s){return apply1(Stdlib_Char[5], s);} + function starts_with(prefix, s){ + var + len_s = caml_ml_bytes_length(s), + len_pre = caml_ml_bytes_length(prefix), + _B_ = len_pre <= len_s ? 1 : 0; + if(! _B_) return _B_; + var i = 0; + for(;;){ + if(i === len_pre) return 1; + if(caml_bytes_unsafe_get(s, i) !== caml_bytes_unsafe_get(prefix, i)) + return 0; + var i$0 = i + 1 | 0; + i = i$0; + } + } + function ends_with(suffix, s){ + var + len_s = caml_ml_bytes_length(s), + len_suf = caml_ml_bytes_length(suffix), + diff = len_s - len_suf | 0, + _A_ = 0 <= diff ? 1 : 0; + if(! _A_) return _A_; + var i = 0; + for(;;){ + if(i === len_suf) return 1; + if + (caml_bytes_unsafe_get(s, diff + i | 0) + !== caml_bytes_unsafe_get(suffix, i)) + return 0; + var i$0 = i + 1 | 0; + i = i$0; + } + } + function index_rec(s, lim, i, c){ + var i$0 = i; + for(;;){ + if(lim <= i$0) throw caml_maybe_attach_backtrace(Stdlib[8], 1); + if(caml_bytes_unsafe_get(s, i$0) === c) return i$0; + var i$1 = i$0 + 1 | 0; + i$0 = i$1; + } + } + function index(s, c){return index_rec(s, caml_ml_bytes_length(s), 0, c);} + function index_rec_opt(s, lim, i, c){ + var i$0 = i; + for(;;){ + if(lim <= i$0) return 0; + if(caml_bytes_unsafe_get(s, i$0) === c) return [0, i$0]; + var i$1 = i$0 + 1 | 0; + i$0 = i$1; + } + } + function index_opt(s, c){ + return index_rec_opt(s, caml_ml_bytes_length(s), 0, c); + } + function index_from(s, i, c){ + var l = caml_ml_bytes_length(s); + if(0 <= i && l >= i) return index_rec(s, l, i, c); + return caml_call1(Stdlib[1], cst_String_index_from_Bytes_in); + } + function index_from_opt(s, i, c){ + var l = caml_ml_bytes_length(s); + if(0 <= i && l >= i) return index_rec_opt(s, l, i, c); + return caml_call1(Stdlib[1], cst_String_index_from_opt_Byte); + } + function rindex_rec(s, i, c){ + var i$0 = i; + for(;;){ + if(0 > i$0) throw caml_maybe_attach_backtrace(Stdlib[8], 1); + if(caml_bytes_unsafe_get(s, i$0) === c) return i$0; + var i$1 = i$0 - 1 | 0; + i$0 = i$1; + } + } + function rindex(s, c){ + return rindex_rec(s, caml_ml_bytes_length(s) - 1 | 0, c); + } + function rindex_from(s, i, c){ + if(-1 <= i && caml_ml_bytes_length(s) > i) return rindex_rec(s, i, c); + return caml_call1(Stdlib[1], cst_String_rindex_from_Bytes_r); + } + function rindex_rec_opt(s, i, c){ + var i$0 = i; + for(;;){ + if(0 > i$0) return 0; + if(caml_bytes_unsafe_get(s, i$0) === c) return [0, i$0]; + var i$1 = i$0 - 1 | 0; + i$0 = i$1; + } + } + function rindex_opt(s, c){ + return rindex_rec_opt(s, caml_ml_bytes_length(s) - 1 | 0, c); + } + function rindex_from_opt(s, i, c){ + if(-1 <= i && caml_ml_bytes_length(s) > i) return rindex_rec_opt(s, i, c); + return caml_call1(Stdlib[1], cst_String_rindex_from_opt_Byt); + } + function contains_from(s, i, c){ + var l = caml_ml_bytes_length(s); + if(0 <= i && l >= i) + try{index_rec(s, l, i, c); var _y_ = 1; return _y_;} + catch(_z_){ + var _x_ = caml_wrap_exception(_z_); + if(_x_ === Stdlib[8]) return 0; + throw caml_maybe_attach_backtrace(_x_, 0); + } + return caml_call1(Stdlib[1], cst_String_contains_from_Bytes); + } + function contains(s, c){return contains_from(s, 0, c);} + function rcontains_from(s, i, c){ + if(0 <= i && caml_ml_bytes_length(s) > i) + try{rindex_rec(s, i, c); var _v_ = 1; return _v_;} + catch(_w_){ + var _u_ = caml_wrap_exception(_w_); + if(_u_ === Stdlib[8]) return 0; + throw caml_maybe_attach_backtrace(_u_, 0); + } + return caml_call1(Stdlib[1], cst_String_rcontains_from_Byte); + } + var + compare = runtime.caml_bytes_compare, + cst_Bytes_of_seq_cannot_grow_b = "Bytes.of_seq: cannot grow bytes"; + function split_on_char(sep, s){ + var + r = [0, 0], + j = [0, caml_ml_bytes_length(s)], + _q_ = caml_ml_bytes_length(s) - 1 | 0; + if(_q_ >= 0){ + var i = _q_; + for(;;){ + if(caml_bytes_unsafe_get(s, i) === sep){ + var _s_ = r[1]; + r[1] = [0, sub(s, i + 1 | 0, (j[1] - i | 0) - 1 | 0), _s_]; + j[1] = i; + } + var _t_ = i - 1 | 0; + if(0 === i) break; + i = _t_; + } + } + var _r_ = r[1]; + return [0, sub(s, 0, j[1]), _r_]; + } + function uppercase(s){return map(Stdlib_Char[4], s);} + function lowercase(s){return map(Stdlib_Char[3], s);} + function capitalize(s){return apply1(Stdlib_Char[4], s);} + function uncapitalize(s){return apply1(Stdlib_Char[3], s);} + function to_seq(s){ + function aux(i, param){ + if(i === caml_ml_bytes_length(s)) return 0; + var x = caml_bytes_get(s, i), _o_ = i + 1 | 0; + return [0, x, function(_p_){return aux(_o_, _p_);}]; + } + var _m_ = 0; + return function(_n_){return aux(_m_, _n_);}; + } + function to_seqi(s){ + function aux(i, param){ + if(i === caml_ml_bytes_length(s)) return 0; + var x = caml_bytes_get(s, i), _k_ = i + 1 | 0; + return [0, [0, i, x], function(_l_){return aux(_k_, _l_);}]; + } + var _i_ = 0; + return function(_j_){return aux(_i_, _j_);}; + } + function of_seq(i){ + var n = [0, 0], buf = [0, make(256, 0)]; + caml_call2 + (Stdlib_Seq[12], + function(c){ + if(n[1] === caml_ml_bytes_length(buf[1])){ + var + new_len = + caml_call2 + (Stdlib_Int[10], + 2 * caml_ml_bytes_length(buf[1]) | 0, + Stdlib_Sys[12]); + if(caml_ml_bytes_length(buf[1]) === new_len) + caml_call1(Stdlib[2], cst_Bytes_of_seq_cannot_grow_b); + var new_buf = make(new_len, 0); + blit(buf[1], 0, new_buf, 0, n[1]); + buf[1] = new_buf; + } + caml_bytes_set(buf[1], n[1], c); + n[1]++; + return 0; + }, + i); + return sub(buf[1], 0, n[1]); + } + function get_int8(b, i){ + var _g_ = Stdlib_Sys[10] - 8 | 0, _h_ = Stdlib_Sys[10] - 8 | 0; + return caml_bytes_get(b, i) << _h_ >> _g_; + } + function get_uint16_le(b, i){ + return Stdlib_Sys[11] + ? caml_bswap16(caml_bytes_get16(b, i)) + : caml_bytes_get16(b, i); + } + function get_uint16_be(b, i){ + return Stdlib_Sys[11] + ? caml_bytes_get16(b, i) + : caml_bswap16(caml_bytes_get16(b, i)); + } + function get_int16_ne(b, i){ + var _e_ = Stdlib_Sys[10] - 16 | 0, _f_ = Stdlib_Sys[10] - 16 | 0; + return caml_bytes_get16(b, i) << _f_ >> _e_; + } + function get_int16_le(b, i){ + var _c_ = Stdlib_Sys[10] - 16 | 0, _d_ = Stdlib_Sys[10] - 16 | 0; + return get_uint16_le(b, i) << _d_ >> _c_; + } + function get_int16_be(b, i){ + var _a_ = Stdlib_Sys[10] - 16 | 0, _b_ = Stdlib_Sys[10] - 16 | 0; + return get_uint16_be(b, i) << _b_ >> _a_; + } + function get_int32_le(b, i){ + return Stdlib_Sys[11] + ? caml_int32_bswap(caml_bytes_get32(b, i)) + : caml_bytes_get32(b, i); + } + function get_int32_be(b, i){ + return Stdlib_Sys[11] + ? caml_bytes_get32(b, i) + : caml_int32_bswap(caml_bytes_get32(b, i)); + } + function get_int64_le(b, i){ + return Stdlib_Sys[11] + ? caml_int64_bswap(caml_bytes_get64(b, i)) + : caml_bytes_get64(b, i); + } + function get_int64_be(b, i){ + return Stdlib_Sys[11] + ? caml_bytes_get64(b, i) + : caml_int64_bswap(caml_bytes_get64(b, i)); + } + function set_int16_le(b, i, x){ + return Stdlib_Sys[11] + ? caml_bytes_set16(b, i, caml_bswap16(x)) + : caml_bytes_set16(b, i, x); + } + function set_int16_be(b, i, x){ + return Stdlib_Sys[11] + ? caml_bytes_set16(b, i, x) + : caml_bytes_set16(b, i, caml_bswap16(x)); + } + function set_int32_le(b, i, x){ + return Stdlib_Sys[11] + ? caml_bytes_set32(b, i, caml_int32_bswap(x)) + : caml_bytes_set32(b, i, x); + } + function set_int32_be(b, i, x){ + return Stdlib_Sys[11] + ? caml_bytes_set32(b, i, x) + : caml_bytes_set32(b, i, caml_int32_bswap(x)); + } + function set_int64_le(b, i, x){ + return Stdlib_Sys[11] + ? caml_bytes_set64(b, i, caml_int64_bswap(x)) + : caml_bytes_set64(b, i, x); + } + function set_int64_be(b, i, x){ + return Stdlib_Sys[11] + ? caml_bytes_set64(b, i, x) + : caml_bytes_set64(b, i, caml_int64_bswap(x)); + } + var + set_uint8 = caml_bytes_set, + set_uint16_ne = caml_bytes_set16, + Stdlib_Bytes = + [0, + make, + init, + empty, + copy, + of_string, + to_string, + sub, + sub_string, + extend, + fill, + blit, + blit_string, + concat, + cat, + iter, + iteri, + map, + mapi, + fold_left, + fold_right, + for_all, + exists, + trim, + escaped, + index, + index_opt, + rindex, + rindex_opt, + index_from, + index_from_opt, + rindex_from, + rindex_from_opt, + contains, + contains_from, + rcontains_from, + uppercase, + lowercase, + capitalize, + uncapitalize, + uppercase_ascii, + lowercase_ascii, + capitalize_ascii, + uncapitalize_ascii, + compare, + runtime.caml_bytes_equal, + starts_with, + ends_with, + caml_string_of_bytes, + caml_bytes_of_string, + split_on_char, + to_seq, + to_seqi, + of_seq, + caml_bytes_get, + get_int8, + caml_bytes_get16, + get_uint16_be, + get_uint16_le, + get_int16_ne, + get_int16_be, + get_int16_le, + caml_bytes_get32, + get_int32_be, + get_int32_le, + caml_bytes_get64, + get_int64_be, + get_int64_le, + set_uint8, + caml_bytes_set, + set_uint16_ne, + set_int16_be, + set_int16_le, + caml_bytes_set16, + set_int16_be, + set_int16_le, + caml_bytes_set32, + set_int32_be, + set_int32_le, + caml_bytes_set64, + set_int64_be, + set_int64_le]; + runtime.caml_register_global(18, Stdlib_Bytes, "Stdlib__Bytes"); + return; + } + (globalThis)); + +//# 3624 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst$0 = "", + caml_blit_string = runtime.caml_blit_string, + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace, + caml_ml_string_length = runtime.caml_ml_string_length, + caml_string_equal = runtime.caml_string_equal, + caml_string_unsafe_get = runtime.caml_string_unsafe_get, + caml_wrap_exception = runtime.caml_wrap_exception; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + var + global_data = runtime.caml_get_global_data(), + cst = cst$0, + empty = cst$0, + Stdlib = global_data.Stdlib, + Stdlib_Bytes = global_data.Stdlib__Bytes, + bts = Stdlib_Bytes[48], + bos = Stdlib_Bytes[49]; + function make(n, c){ + return caml_call1(bts, caml_call2(Stdlib_Bytes[1], n, c)); + } + function init(n, f){ + return caml_call1(bts, caml_call2(Stdlib_Bytes[2], n, f)); + } + function copy(s){ + var _Y_ = caml_call1(bos, s); + return caml_call1(bts, caml_call1(Stdlib_Bytes[4], _Y_)); + } + var of_bytes = Stdlib_Bytes[6], to_bytes = Stdlib_Bytes[5]; + function sub(s, ofs, len){ + var _X_ = caml_call1(bos, s); + return caml_call1(bts, caml_call3(Stdlib_Bytes[7], _X_, ofs, len)); + } + var + fill = Stdlib_Bytes[10], + blit = Stdlib_Bytes[12], + cst_String_concat = "String.concat"; + function concat(sep, l){ + if(! l) return cst; + var seplen = caml_ml_string_length(sep); + a: + { + b: + { + var acc = 0, param = l, pos$1 = 0; + for(;;){ + if(! param) break; + var hd = param[1]; + if(! param[2]) break b; + var + tl = param[2], + x = (caml_ml_string_length(hd) + seplen | 0) + acc | 0, + acc$0 = acc <= x ? x : caml_call1(Stdlib[1], cst_String_concat); + acc = acc$0; + param = tl; + } + var _W_ = acc; + break a; + } + var _W_ = caml_ml_string_length(hd) + acc | 0; + } + var dst = runtime.caml_create_bytes(_W_), pos = pos$1, param$0 = l; + for(;;){ + if(param$0){ + var hd$0 = param$0[1]; + if(param$0[2]){ + var tl$0 = param$0[2]; + caml_blit_string(hd$0, 0, dst, pos, caml_ml_string_length(hd$0)); + caml_blit_string + (sep, 0, dst, pos + caml_ml_string_length(hd$0) | 0, seplen); + var pos$0 = (pos + caml_ml_string_length(hd$0) | 0) + seplen | 0; + pos = pos$0; + param$0 = tl$0; + continue; + } + caml_blit_string(hd$0, 0, dst, pos, caml_ml_string_length(hd$0)); + } + return caml_call1(bts, dst); + } + } + var + cat = Stdlib[28], + cst_String_index_from_Bytes_in = "String.index_from / Bytes.index_from", + cst_String_index_from_opt_Byte = + "String.index_from_opt / Bytes.index_from_opt", + cst_String_rindex_from_Bytes_r = "String.rindex_from / Bytes.rindex_from", + cst_String_rindex_from_opt_Byt = + "String.rindex_from_opt / Bytes.rindex_from_opt", + cst_String_contains_from_Bytes = + "String.contains_from / Bytes.contains_from", + cst_String_rcontains_from_Byte = + "String.rcontains_from / Bytes.rcontains_from"; + function iter(f, s){ + var _U_ = caml_ml_string_length(s) - 1 | 0, _T_ = 0; + if(_U_ >= 0){ + var i = _T_; + for(;;){ + caml_call1(f, caml_string_unsafe_get(s, i)); + var _V_ = i + 1 | 0; + if(_U_ === i) break; + i = _V_; + } + } + return 0; + } + function iteri(f, s){ + var _R_ = caml_ml_string_length(s) - 1 | 0, _Q_ = 0; + if(_R_ >= 0){ + var i = _Q_; + for(;;){ + caml_call2(f, i, caml_string_unsafe_get(s, i)); + var _S_ = i + 1 | 0; + if(_R_ === i) break; + i = _S_; + } + } + return 0; + } + function map(f, s){ + var _P_ = caml_call1(bos, s); + return caml_call1(bts, caml_call2(Stdlib_Bytes[17], f, _P_)); + } + function mapi(f, s){ + var _O_ = caml_call1(bos, s); + return caml_call1(bts, caml_call2(Stdlib_Bytes[18], f, _O_)); + } + function fold_right(f, x, a){ + var _N_ = caml_call1(bos, x); + return caml_call3(Stdlib_Bytes[20], f, _N_, a); + } + function fold_left(f, a, x){ + var _M_ = caml_call1(bos, x); + return caml_call3(Stdlib_Bytes[19], f, a, _M_); + } + function exists(f, s){ + var _L_ = caml_call1(bos, s); + return caml_call2(Stdlib_Bytes[22], f, _L_); + } + function for_all(f, s){ + var _K_ = caml_call1(bos, s); + return caml_call2(Stdlib_Bytes[21], f, _K_); + } + function is_space(param){ + var _J_ = param - 9 | 0; + a: + { + if(4 < _J_ >>> 0){if(23 !== _J_) break a;} else if(2 === _J_) break a; + return 1; + } + return 0; + } + function trim(s){ + if(s == cst$0) return s; + if + (! + is_space(caml_string_unsafe_get(s, 0)) + && + ! + is_space(caml_string_unsafe_get(s, caml_ml_string_length(s) - 1 | 0))) + return s; + var _I_ = caml_call1(bos, s); + return caml_call1(bts, caml_call1(Stdlib_Bytes[23], _I_)); + } + function escaped(s){ + var n = caml_ml_string_length(s), i = 0; + for(;;){ + if(n <= i) return s; + var _G_ = caml_string_unsafe_get(s, i) - 32 | 0; + a: + { + if(59 < _G_ >>> 0){ + if(33 < _G_ - 61 >>> 0) break a; + } + else if(2 === _G_) break a; + var i$0 = i + 1 | 0; + i = i$0; + continue; + } + var _H_ = caml_call1(bos, s); + return caml_call1(bts, caml_call1(Stdlib_Bytes[24], _H_)); + } + } + function index_rec(s, lim, i, c){ + var i$0 = i; + for(;;){ + if(lim <= i$0) throw caml_maybe_attach_backtrace(Stdlib[8], 1); + if(caml_string_unsafe_get(s, i$0) === c) return i$0; + var i$1 = i$0 + 1 | 0; + i$0 = i$1; + } + } + function index(s, c){return index_rec(s, caml_ml_string_length(s), 0, c);} + function index_rec_opt(s, lim, i, c){ + var i$0 = i; + for(;;){ + if(lim <= i$0) return 0; + if(caml_string_unsafe_get(s, i$0) === c) return [0, i$0]; + var i$1 = i$0 + 1 | 0; + i$0 = i$1; + } + } + function index_opt(s, c){ + return index_rec_opt(s, caml_ml_string_length(s), 0, c); + } + function index_from(s, i, c){ + var l = caml_ml_string_length(s); + if(0 <= i && l >= i) return index_rec(s, l, i, c); + return caml_call1(Stdlib[1], cst_String_index_from_Bytes_in); + } + function index_from_opt(s, i, c){ + var l = caml_ml_string_length(s); + if(0 <= i && l >= i) return index_rec_opt(s, l, i, c); + return caml_call1(Stdlib[1], cst_String_index_from_opt_Byte); + } + function rindex_rec(s, i, c){ + var i$0 = i; + for(;;){ + if(0 > i$0) throw caml_maybe_attach_backtrace(Stdlib[8], 1); + if(caml_string_unsafe_get(s, i$0) === c) return i$0; + var i$1 = i$0 - 1 | 0; + i$0 = i$1; + } + } + function rindex(s, c){ + return rindex_rec(s, caml_ml_string_length(s) - 1 | 0, c); + } + function rindex_from(s, i, c){ + if(-1 <= i && caml_ml_string_length(s) > i) return rindex_rec(s, i, c); + return caml_call1(Stdlib[1], cst_String_rindex_from_Bytes_r); + } + function rindex_rec_opt(s, i, c){ + var i$0 = i; + for(;;){ + if(0 > i$0) return 0; + if(caml_string_unsafe_get(s, i$0) === c) return [0, i$0]; + var i$1 = i$0 - 1 | 0; + i$0 = i$1; + } + } + function rindex_opt(s, c){ + return rindex_rec_opt(s, caml_ml_string_length(s) - 1 | 0, c); + } + function rindex_from_opt(s, i, c){ + if(-1 <= i && caml_ml_string_length(s) > i) + return rindex_rec_opt(s, i, c); + return caml_call1(Stdlib[1], cst_String_rindex_from_opt_Byt); + } + function contains_from(s, i, c){ + var l = caml_ml_string_length(s); + if(0 <= i && l >= i) + try{index_rec(s, l, i, c); var _E_ = 1; return _E_;} + catch(_F_){ + var _D_ = caml_wrap_exception(_F_); + if(_D_ === Stdlib[8]) return 0; + throw caml_maybe_attach_backtrace(_D_, 0); + } + return caml_call1(Stdlib[1], cst_String_contains_from_Bytes); + } + function contains(s, c){return contains_from(s, 0, c);} + function rcontains_from(s, i, c){ + if(0 <= i && caml_ml_string_length(s) > i) + try{rindex_rec(s, i, c); var _B_ = 1; return _B_;} + catch(_C_){ + var _A_ = caml_wrap_exception(_C_); + if(_A_ === Stdlib[8]) return 0; + throw caml_maybe_attach_backtrace(_A_, 0); + } + return caml_call1(Stdlib[1], cst_String_rcontains_from_Byte); + } + function uppercase_ascii(s){ + var _z_ = caml_call1(bos, s); + return caml_call1(bts, caml_call1(Stdlib_Bytes[40], _z_)); + } + function lowercase_ascii(s){ + var _y_ = caml_call1(bos, s); + return caml_call1(bts, caml_call1(Stdlib_Bytes[41], _y_)); + } + function capitalize_ascii(s){ + var _x_ = caml_call1(bos, s); + return caml_call1(bts, caml_call1(Stdlib_Bytes[42], _x_)); + } + function uncapitalize_ascii(s){ + var _w_ = caml_call1(bos, s); + return caml_call1(bts, caml_call1(Stdlib_Bytes[43], _w_)); + } + function starts_with(prefix, s){ + var + len_s = caml_ml_string_length(s), + len_pre = caml_ml_string_length(prefix), + _v_ = len_pre <= len_s ? 1 : 0; + if(! _v_) return _v_; + var i = 0; + for(;;){ + if(i === len_pre) return 1; + if(caml_string_unsafe_get(s, i) !== caml_string_unsafe_get(prefix, i)) + return 0; + var i$0 = i + 1 | 0; + i = i$0; + } + } + function ends_with(suffix, s){ + var + len_s = caml_ml_string_length(s), + len_suf = caml_ml_string_length(suffix), + diff = len_s - len_suf | 0, + _u_ = 0 <= diff ? 1 : 0; + if(! _u_) return _u_; + var i = 0; + for(;;){ + if(i === len_suf) return 1; + if + (caml_string_unsafe_get(s, diff + i | 0) + !== caml_string_unsafe_get(suffix, i)) + return 0; + var i$0 = i + 1 | 0; + i = i$0; + } + } + function split_on_char(sep, s){ + var + r = [0, 0], + j = [0, caml_ml_string_length(s)], + _q_ = caml_ml_string_length(s) - 1 | 0; + if(_q_ >= 0){ + var i = _q_; + for(;;){ + if(caml_string_unsafe_get(s, i) === sep){ + var _s_ = r[1]; + r[1] = [0, sub(s, i + 1 | 0, (j[1] - i | 0) - 1 | 0), _s_]; + j[1] = i; + } + var _t_ = i - 1 | 0; + if(0 === i) break; + i = _t_; + } + } + var _r_ = r[1]; + return [0, sub(s, 0, j[1]), _r_]; + } + function uppercase(s){ + var _p_ = caml_call1(bos, s); + return caml_call1(bts, caml_call1(Stdlib_Bytes[36], _p_)); + } + function lowercase(s){ + var _o_ = caml_call1(bos, s); + return caml_call1(bts, caml_call1(Stdlib_Bytes[37], _o_)); + } + function capitalize(s){ + var _n_ = caml_call1(bos, s); + return caml_call1(bts, caml_call1(Stdlib_Bytes[38], _n_)); + } + function uncapitalize(s){ + var _m_ = caml_call1(bos, s); + return caml_call1(bts, caml_call1(Stdlib_Bytes[39], _m_)); + } + var compare = runtime.caml_string_compare; + function to_seq(s){ + var _l_ = caml_call1(bos, s); + return caml_call1(Stdlib_Bytes[51], _l_); + } + function to_seqi(s){ + var _k_ = caml_call1(bos, s); + return caml_call1(Stdlib_Bytes[52], _k_); + } + function of_seq(g){ + return caml_call1(bts, caml_call1(Stdlib_Bytes[53], g)); + } + function get_int8(s, i){ + var _j_ = caml_call1(bos, s); + return caml_call2(Stdlib_Bytes[55], _j_, i); + } + function get_uint16_le(s, i){ + var _i_ = caml_call1(bos, s); + return caml_call2(Stdlib_Bytes[58], _i_, i); + } + function get_uint16_be(s, i){ + var _h_ = caml_call1(bos, s); + return caml_call2(Stdlib_Bytes[57], _h_, i); + } + function get_int16_ne(s, i){ + var _g_ = caml_call1(bos, s); + return caml_call2(Stdlib_Bytes[59], _g_, i); + } + function get_int16_le(s, i){ + var _f_ = caml_call1(bos, s); + return caml_call2(Stdlib_Bytes[61], _f_, i); + } + function get_int16_be(s, i){ + var _e_ = caml_call1(bos, s); + return caml_call2(Stdlib_Bytes[60], _e_, i); + } + function get_int32_le(s, i){ + var _d_ = caml_call1(bos, s); + return caml_call2(Stdlib_Bytes[64], _d_, i); + } + function get_int32_be(s, i){ + var _c_ = caml_call1(bos, s); + return caml_call2(Stdlib_Bytes[63], _c_, i); + } + function get_int64_le(s, i){ + var _b_ = caml_call1(bos, s); + return caml_call2(Stdlib_Bytes[67], _b_, i); + } + function get_int64_be(s, i){ + var _a_ = caml_call1(bos, s); + return caml_call2(Stdlib_Bytes[66], _a_, i); + } + var + Stdlib_String = + [0, + make, + init, + empty, + of_bytes, + to_bytes, + concat, + cat, + caml_string_equal, + compare, + starts_with, + ends_with, + contains_from, + rcontains_from, + contains, + sub, + split_on_char, + map, + mapi, + fold_left, + fold_right, + for_all, + exists, + trim, + escaped, + uppercase_ascii, + lowercase_ascii, + capitalize_ascii, + uncapitalize_ascii, + iter, + iteri, + index_from, + index_from_opt, + rindex_from, + rindex_from_opt, + index, + index_opt, + rindex, + rindex_opt, + to_seq, + to_seqi, + of_seq, + blit, + copy, + fill, + uppercase, + lowercase, + capitalize, + uncapitalize, + runtime.caml_string_get, + get_int8, + runtime.caml_string_get16, + get_uint16_be, + get_uint16_le, + get_int16_ne, + get_int16_be, + get_int16_le, + runtime.caml_string_get32, + get_int32_be, + get_int32_le, + runtime.caml_string_get64, + get_int64_be, + get_int64_le]; + runtime.caml_register_global(12, Stdlib_String, "Stdlib__String"); + return; + } + (globalThis)); + +//# 4133 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst_Marshal_from_bytes$1 = "Marshal.from_bytes", + caml_marshal_data_size = runtime.caml_marshal_data_size, + caml_ml_bytes_length = runtime.caml_ml_bytes_length; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + var + global_data = runtime.caml_get_global_data(), + Stdlib_Bytes = global_data.Stdlib__Bytes, + Stdlib = global_data.Stdlib, + cst_Marshal_to_buffer_substrin = + "Marshal.to_buffer: substring out of bounds"; + function to_buffer(buff, ofs, len, v, flags){ + if(0 <= ofs && 0 <= len && (caml_ml_bytes_length(buff) - len | 0) >= ofs) + return runtime.caml_output_value_to_buffer(buff, ofs, len, v, flags); + return caml_call1(Stdlib[1], cst_Marshal_to_buffer_substrin); + } + var + cst_Marshal_data_size = "Marshal.data_size", + cst_Marshal_from_bytes = cst_Marshal_from_bytes$1, + cst_Marshal_from_bytes$0 = cst_Marshal_from_bytes$1; + function data_size(buff, ofs){ + if(0 <= ofs && (caml_ml_bytes_length(buff) - 20 | 0) >= ofs) + return caml_marshal_data_size(buff, ofs); + return caml_call1(Stdlib[1], cst_Marshal_data_size); + } + function total_size(buff, ofs){return 20 + data_size(buff, ofs) | 0;} + function from_bytes(buff, ofs){ + if(0 <= ofs && (caml_ml_bytes_length(buff) - 20 | 0) >= ofs){ + var len = caml_marshal_data_size(buff, ofs); + return (caml_ml_bytes_length(buff) - (20 + len | 0) | 0) < ofs + ? caml_call1(Stdlib[1], cst_Marshal_from_bytes$0) + : runtime.caml_input_value_from_bytes(buff, ofs); + } + return caml_call1(Stdlib[1], cst_Marshal_from_bytes); + } + function from_string(buff, ofs){ + return from_bytes(caml_call1(Stdlib_Bytes[49], buff), ofs); + } + var + Stdlib_Marshal = + [0, + runtime.caml_output_value, + to_buffer, + runtime.caml_input_value, + from_bytes, + from_string, + 20, + data_size, + total_size]; + runtime.caml_register_global(6, Stdlib_Marshal, "Stdlib__Marshal"); + return; + } + (globalThis)); + +//# 4197 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst_Obj_extension_constructor$1 = "Obj.extension_constructor", + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace, + caml_obj_tag = runtime.caml_obj_tag; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + var + global_data = runtime.caml_get_global_data(), + Stdlib = global_data.Stdlib, + Assert_failure = global_data.Assert_failure, + Stdlib_Sys = global_data.Stdlib__Sys, + Stdlib_Marshal = global_data.Stdlib__Marshal; + function is_block(a){return 1 - (typeof a === "number" ? 1 : 0);} + var + double_field = runtime.caml_array_get, + set_double_field = runtime.caml_array_set; + function marshal(obj){return runtime.caml_output_value_to_bytes(obj, 0);} + function unmarshal(str, pos){ + var _i_ = pos + caml_call2(Stdlib_Marshal[8], str, pos) | 0; + return [0, caml_call2(Stdlib_Marshal[4], str, pos), _i_]; + } + var + custom_tag = 255, + _a_ = [0, "obj.ml", 100, 4], + cst_Obj_extension_constructor = cst_Obj_extension_constructor$1, + cst_Obj_extension_constructor$0 = cst_Obj_extension_constructor$1; + function info(obj){ + if(caml_obj_tag(obj) !== 247) + throw caml_maybe_attach_backtrace([0, Assert_failure, _a_], 1); + var + info = runtime.caml_obj_raw_field(obj, 1), + arity = 64 === Stdlib_Sys[9] ? info >> 56 : info >> 24, + start_env = info << 8 >>> 9 | 0; + return [0, arity, start_env]; + } + function of_val(x){ + a: + { + if(is_block(x) && caml_obj_tag(x) !== 248 && 1 <= x.length - 1){var slot = x[1]; break a;} + var slot = x; + } + a: + { + if(is_block(slot) && caml_obj_tag(slot) === 248){var name = slot[1]; break a;} + var name = caml_call1(Stdlib[1], cst_Obj_extension_constructor$0); + } + return caml_obj_tag(name) === 252 + ? slot + : caml_call1(Stdlib[1], cst_Obj_extension_constructor); + } + function name(slot){return slot[1];} + function id(slot){return slot[2];} + var + Extension_constructor = [0, of_val, name, id], + extension_constructor = Extension_constructor[1], + extension_name = Extension_constructor[2], + extension_id = Extension_constructor[3], + max_ephe_length = Stdlib_Sys[13] - 2 | 0, + cst_Obj_Ephemeron_create = "Obj.Ephemeron.create", + cst_Obj_Ephemeron_get_key = "Obj.Ephemeron.get_key", + cst_Obj_Ephemeron_get_key_copy = "Obj.Ephemeron.get_key_copy", + cst_Obj_Ephemeron_set_key = "Obj.Ephemeron.set_key", + cst_Obj_Ephemeron_unset_key = "Obj.Ephemeron.unset_key", + cst_Obj_Ephemeron_check_key = "Obj.Ephemeron.check_key", + cst_Obj_Ephemeron_blit_key = "Obj.Ephemeron.blit_key"; + function create(l){ + var _g_ = 0 <= l ? 1 : 0, _h_ = _g_ ? l <= max_ephe_length ? 1 : 0 : _g_; + if(1 - _h_) caml_call1(Stdlib[1], cst_Obj_Ephemeron_create); + return runtime.caml_ephe_create(l); + } + function length(x){return x.length - 3 | 0;} + function raise_if_invalid_offset(e, o, msg){ + var + _d_ = 0 <= o ? 1 : 0, + _e_ = _d_ ? o < length(e) ? 1 : 0 : _d_, + _f_ = 1 - _e_; + return _f_ ? caml_call1(Stdlib[1], msg) : _f_; + } + function get_key(e, o){ + raise_if_invalid_offset(e, o, cst_Obj_Ephemeron_get_key); + return runtime.caml_ephe_get_key(e, o); + } + function get_key_copy(e, o){ + raise_if_invalid_offset(e, o, cst_Obj_Ephemeron_get_key_copy); + return runtime.caml_ephe_get_key_copy(e, o); + } + function set_key(e, o, x){ + raise_if_invalid_offset(e, o, cst_Obj_Ephemeron_set_key); + return runtime.caml_ephe_set_key(e, o, x); + } + function unset_key(e, o){ + raise_if_invalid_offset(e, o, cst_Obj_Ephemeron_unset_key); + return runtime.caml_ephe_unset_key(e, o); + } + function check_key(e, o){ + raise_if_invalid_offset(e, o, cst_Obj_Ephemeron_check_key); + return runtime.caml_ephe_check_key(e, o); + } + function blit_key(e1, o1, e2, o2, l){ + if + (0 <= l + && + 0 <= o1 + && (length(e1) - l | 0) >= o1 && 0 <= o2 && (length(e2) - l | 0) >= o2){ + var + _b_ = 0 !== l ? 1 : 0, + _c_ = _b_ ? runtime.caml_ephe_blit_key(e1, o1, e2, o2, l) : _b_; + return _c_; + } + return caml_call1(Stdlib[1], cst_Obj_Ephemeron_blit_key); + } + var + Stdlib_Obj = + [0, + is_block, + double_field, + set_double_field, + 0, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 251, + 252, + 253, + 254, + custom_tag, + custom_tag, + 1000, + 1001, + 1002, + [0, info], + Extension_constructor, + extension_constructor, + extension_name, + extension_id, + marshal, + unmarshal, + [0, + create, + length, + get_key, + get_key_copy, + set_key, + unset_key, + check_key, + blit_key, + runtime.caml_ephe_get_data, + runtime.caml_ephe_get_data_copy, + runtime.caml_ephe_set_data, + runtime.caml_ephe_unset_data, + runtime.caml_ephe_check_data, + runtime.caml_ephe_blit_data, + max_ephe_length]]; + runtime.caml_register_global(14, Stdlib_Obj, "Stdlib__Obj"); + return; + } + (globalThis)); + +//# 4373 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + caml_array_sub = runtime.caml_array_sub, + caml_check_bound = runtime.caml_check_bound, + caml_make_vect = runtime.caml_make_vect, + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace, + caml_wrap_exception = runtime.caml_wrap_exception; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + var + global_data = runtime.caml_get_global_data(), + Stdlib_Seq = global_data.Stdlib__Seq, + Assert_failure = global_data.Assert_failure, + Stdlib = global_data.Stdlib, + make_float = runtime.caml_make_float_vect, + Floatarray = [0], + cst_Array_init = "Array.init", + cst_Array_sub = "Array.sub", + cst_Array_fill = "Array.fill", + cst_Array_blit = "Array.blit", + cst_Array_iter2_arrays_must_ha = + "Array.iter2: arrays must have the same length", + cst_Array_map2_arrays_must_hav = + "Array.map2: arrays must have the same length", + cst_Array_for_all2 = "Array.for_all2", + cst_Array_exists2 = "Array.exists2", + cst_Array_combine = "Array.combine"; + function init(l, f){ + if(0 === l) return [0]; + if(0 > l) return caml_call1(Stdlib[1], cst_Array_init); + var res = caml_make_vect(l, caml_call1(f, 0)), _aq_ = l - 1 | 0, _ap_ = 1; + if(_aq_ >= 1){ + var i = _ap_; + for(;;){ + res[1 + i] = caml_call1(f, i); + var _ar_ = i + 1 | 0; + if(_aq_ === i) break; + i = _ar_; + } + } + return res; + } + function make_matrix(sx, sy, init){ + var res = caml_make_vect(sx, [0]), _an_ = sx - 1 | 0, _am_ = 0; + if(_an_ >= 0){ + var x = _am_; + for(;;){ + res[1 + x] = caml_make_vect(sy, init); + var _ao_ = x + 1 | 0; + if(_an_ === x) break; + x = _ao_; + } + } + return res; + } + function copy(a){ + var l = a.length - 1; + return 0 === l ? [0] : caml_array_sub(a, 0, l); + } + function append(a1, a2){ + var l1 = a1.length - 1; + return 0 === l1 + ? copy(a2) + : 0 + === a2.length - 1 + ? caml_array_sub(a1, 0, l1) + : runtime.caml_array_append(a1, a2); + } + function sub(a, ofs, len){ + if(0 <= ofs && 0 <= len && (a.length - 1 - len | 0) >= ofs) + return caml_array_sub(a, ofs, len); + return caml_call1(Stdlib[1], cst_Array_sub); + } + function fill(a, ofs, len, v){ + if(0 <= ofs && 0 <= len && (a.length - 1 - len | 0) >= ofs) + return runtime.caml_array_fill(a, ofs, len, v); + return caml_call1(Stdlib[1], cst_Array_fill); + } + function blit(a1, ofs1, a2, ofs2, len){ + if + (0 <= len + && + 0 <= ofs1 + && + (a1.length - 1 - len | 0) >= ofs1 + && 0 <= ofs2 && (a2.length - 1 - len | 0) >= ofs2) + return runtime.caml_array_blit(a1, ofs1, a2, ofs2, len); + return caml_call1(Stdlib[1], cst_Array_blit); + } + function iter(f, a){ + var _ak_ = a.length - 2 | 0, _aj_ = 0; + if(_ak_ >= 0){ + var i = _aj_; + for(;;){ + caml_call1(f, a[1 + i]); + var _al_ = i + 1 | 0; + if(_ak_ === i) break; + i = _al_; + } + } + return 0; + } + function iter2(f, a, b){ + if(a.length - 1 !== b.length - 1) + return caml_call1(Stdlib[1], cst_Array_iter2_arrays_must_ha); + var _ah_ = a.length - 2 | 0, _ag_ = 0; + if(_ah_ >= 0){ + var i = _ag_; + for(;;){ + caml_call2(f, a[1 + i], b[1 + i]); + var _ai_ = i + 1 | 0; + if(_ah_ === i) break; + i = _ai_; + } + } + return 0; + } + function map(f, a){ + var l = a.length - 1; + if(0 === l) return [0]; + var + r = caml_make_vect(l, caml_call1(f, a[1])), + _ae_ = l - 1 | 0, + _ad_ = 1; + if(_ae_ >= 1){ + var i = _ad_; + for(;;){ + r[1 + i] = caml_call1(f, a[1 + i]); + var _af_ = i + 1 | 0; + if(_ae_ === i) break; + i = _af_; + } + } + return r; + } + function map2(f, a, b){ + var la = a.length - 1, lb = b.length - 1; + if(la !== lb) + return caml_call1(Stdlib[1], cst_Array_map2_arrays_must_hav); + if(0 === la) return [0]; + var + r = caml_make_vect(la, caml_call2(f, a[1], b[1])), + _ab_ = la - 1 | 0, + _aa_ = 1; + if(_ab_ >= 1){ + var i = _aa_; + for(;;){ + r[1 + i] = caml_call2(f, a[1 + i], b[1 + i]); + var _ac_ = i + 1 | 0; + if(_ab_ === i) break; + i = _ac_; + } + } + return r; + } + function iteri(f, a){ + var ___ = a.length - 2 | 0, _Z_ = 0; + if(___ >= 0){ + var i = _Z_; + for(;;){ + caml_call2(f, i, a[1 + i]); + var _$_ = i + 1 | 0; + if(___ === i) break; + i = _$_; + } + } + return 0; + } + function mapi(f, a){ + var l = a.length - 1; + if(0 === l) return [0]; + var + r = caml_make_vect(l, caml_call2(f, 0, a[1])), + _X_ = l - 1 | 0, + _W_ = 1; + if(_X_ >= 1){ + var i = _W_; + for(;;){ + r[1 + i] = caml_call2(f, i, a[1 + i]); + var _Y_ = i + 1 | 0; + if(_X_ === i) break; + i = _Y_; + } + } + return r; + } + function to_list(a){ + var i$1 = a.length - 2 | 0, i = i$1, res = 0; + for(;;){ + if(0 > i) return res; + var res$0 = [0, a[1 + i], res], i$0 = i - 1 | 0; + i = i$0; + res = res$0; + } + } + function list_length(accu, param){ + var accu$0 = accu, param$0 = param; + for(;;){ + if(! param$0) return accu$0; + var t = param$0[2], accu$1 = accu$0 + 1 | 0; + accu$0 = accu$1; + param$0 = t; + } + } + function of_list(l){ + if(! l) return [0]; + var + tl = l[2], + hd = l[1], + a = caml_make_vect(list_length(0, l), hd), + i = 1, + param = tl; + for(;;){ + if(! param) return a; + var tl$0 = param[2], hd$0 = param[1]; + a[1 + i] = hd$0; + var i$0 = i + 1 | 0; + i = i$0; + param = tl$0; + } + } + function fold_left(f, x, a){ + var r = [0, x], _U_ = a.length - 2 | 0, _T_ = 0; + if(_U_ >= 0){ + var i = _T_; + for(;;){ + r[1] = caml_call2(f, r[1], a[1 + i]); + var _V_ = i + 1 | 0; + if(_U_ === i) break; + i = _V_; + } + } + return r[1]; + } + function fold_left_map(f, acc, input_array){ + var len = input_array.length - 1; + if(0 === len) return [0, acc, [0]]; + var + match = caml_call2(f, acc, input_array[1]), + elt = match[2], + acc$0 = match[1], + output_array = caml_make_vect(len, elt), + acc$1 = [0, acc$0], + _R_ = len - 1 | 0, + _Q_ = 1; + if(_R_ >= 1){ + var i = _Q_; + for(;;){ + var + match$0 = caml_call2(f, acc$1[1], input_array[1 + i]), + elt$0 = match$0[2], + acc$2 = match$0[1]; + acc$1[1] = acc$2; + output_array[1 + i] = elt$0; + var _S_ = i + 1 | 0; + if(_R_ === i) break; + i = _S_; + } + } + return [0, acc$1[1], output_array]; + } + function fold_right(f, a, x){ + var r = [0, x], _O_ = a.length - 2 | 0; + if(_O_ >= 0){ + var i = _O_; + for(;;){ + r[1] = caml_call2(f, a[1 + i], r[1]); + var _P_ = i - 1 | 0; + if(0 === i) break; + i = _P_; + } + } + return r[1]; + } + function exists(p, a){ + var n = a.length - 1, i = 0; + for(;;){ + if(i === n) return 0; + if(caml_call1(p, a[1 + i])) return 1; + var i$0 = i + 1 | 0; + i = i$0; + } + } + function for_all(p, a){ + var n = a.length - 1, i = 0; + for(;;){ + if(i === n) return 1; + if(! caml_call1(p, a[1 + i])) return 0; + var i$0 = i + 1 | 0; + i = i$0; + } + } + function for_all2(p, l1, l2){ + var n1 = l1.length - 1, n2 = l2.length - 1; + if(n1 !== n2) return caml_call1(Stdlib[1], cst_Array_for_all2); + var i = 0; + for(;;){ + if(i === n1) return 1; + if(! caml_call2(p, l1[1 + i], l2[1 + i])) return 0; + var i$0 = i + 1 | 0; + i = i$0; + } + } + function exists2(p, l1, l2){ + var n1 = l1.length - 1, n2 = l2.length - 1; + if(n1 !== n2) return caml_call1(Stdlib[1], cst_Array_exists2); + var i = 0; + for(;;){ + if(i === n1) return 0; + if(caml_call2(p, l1[1 + i], l2[1 + i])) return 1; + var i$0 = i + 1 | 0; + i = i$0; + } + } + function mem(x, a){ + var n = a.length - 1, i = 0; + for(;;){ + if(i === n) return 0; + if(0 === runtime.caml_compare(a[1 + i], x)) return 1; + var i$0 = i + 1 | 0; + i = i$0; + } + } + function memq(x, a){ + var n = a.length - 1, i = 0; + for(;;){ + if(i === n) return 0; + if(x === a[1 + i]) return 1; + var i$0 = i + 1 | 0; + i = i$0; + } + } + function find_opt(p, a){ + var n = a.length - 1, i = 0; + for(;;){ + if(i === n) return 0; + var x = a[1 + i]; + if(caml_call1(p, x)) return [0, x]; + var i$0 = i + 1 | 0; + i = i$0; + } + } + function find_map(f, a){ + var n = a.length - 1, i = 0; + for(;;){ + if(i === n) return 0; + var r = caml_call1(f, a[1 + i]); + if(r) return r; + var i$0 = i + 1 | 0; + i = i$0; + } + } + function split(x){ + if(runtime.caml_equal(x, [0])) return [0, [0], [0]]; + var + match = x[1], + b0 = match[2], + a0 = match[1], + n = x.length - 1, + a = caml_make_vect(n, a0), + b = caml_make_vect(n, b0), + _M_ = n - 1 | 0, + _L_ = 1; + if(_M_ >= 1){ + var i = _L_; + for(;;){ + var match$0 = x[1 + i], bi = match$0[2], ai = match$0[1]; + a[1 + i] = ai; + b[1 + i] = bi; + var _N_ = i + 1 | 0; + if(_M_ === i) break; + i = _N_; + } + } + return [0, a, b]; + } + function combine(a, b){ + var na = a.length - 1, nb = b.length - 1; + if(na !== nb) caml_call1(Stdlib[1], cst_Array_combine); + if(0 === na) return [0]; + var x = caml_make_vect(na, [0, a[1], b[1]]), _J_ = na - 1 | 0, _I_ = 1; + if(_J_ >= 1){ + var i = _I_; + for(;;){ + x[1 + i] = [0, a[1 + i], b[1 + i]]; + var _K_ = i + 1 | 0; + if(_J_ === i) break; + i = _K_; + } + } + return x; + } + var + Bottom = [248, "Stdlib.Array.Bottom", runtime.caml_fresh_oo_id(0)], + _a_ = [0, "array.ml", 322, 4]; + function sort(cmp, a){ + function maxson(l, i){ + var i31 = ((i + i | 0) + i | 0) + 1 | 0, x = [0, i31]; + if((i31 + 2 | 0) < l){ + var _B_ = i31 + 1 | 0, _C_ = caml_check_bound(a, _B_)[1 + _B_]; + if(caml_call2(cmp, caml_check_bound(a, i31)[1 + i31], _C_) < 0) + x[1] = i31 + 1 | 0; + var + _D_ = i31 + 2 | 0, + _E_ = caml_check_bound(a, _D_)[1 + _D_], + _F_ = x[1]; + if(caml_call2(cmp, caml_check_bound(a, _F_)[1 + _F_], _E_) < 0) + x[1] = i31 + 2 | 0; + return x[1]; + } + if((i31 + 1 | 0) < l){ + var _G_ = i31 + 1 | 0, _H_ = caml_check_bound(a, _G_)[1 + _G_]; + if(0 > caml_call2(cmp, caml_check_bound(a, i31)[1 + i31], _H_)) + return i31 + 1 | 0; + } + if(i31 < l) return i31; + throw caml_maybe_attach_backtrace([0, Bottom, i], 1); + } + var l = a.length - 1, _v_ = ((l + 1 | 0) / 3 | 0) - 1 | 0; + if(_v_ >= 0){ + var i$6 = _v_; + for(;;){ + var e$1 = caml_check_bound(a, i$6)[1 + i$6]; + try{ + var i = i$6; + for(;;){ + var j = maxson(l, i); + if(0 >= caml_call2(cmp, caml_check_bound(a, j)[1 + j], e$1)) break; + var _s_ = caml_check_bound(a, j)[1 + j]; + caml_check_bound(a, i)[1 + i] = _s_; + i = j; + } + caml_check_bound(a, i)[1 + i] = e$1; + } + catch(exn$0){ + var exn = caml_wrap_exception(exn$0); + if(exn[1] !== Bottom) throw caml_maybe_attach_backtrace(exn, 0); + var i$0 = exn[2]; + caml_check_bound(a, i$0)[1 + i$0] = e$1; + } + var _A_ = i$6 - 1 | 0; + if(0 === i$6) break; + i$6 = _A_; + } + } + var _w_ = l - 1 | 0; + if(_w_ >= 2){ + var i$4 = _w_; + for(;;){ + var e$0 = caml_check_bound(a, i$4)[1 + i$4]; + a[1 + i$4] = caml_check_bound(a, 0)[1]; + var i$5 = 0; + try{ + var i$1 = i$5; + for(;;){ + var j$0 = maxson(i$4, i$1), _t_ = caml_check_bound(a, j$0)[1 + j$0]; + caml_check_bound(a, i$1)[1 + i$1] = _t_; + i$1 = j$0; + } + } + catch(exn){ + var exn$0 = caml_wrap_exception(exn); + if(exn$0[1] !== Bottom) throw caml_maybe_attach_backtrace(exn$0, 0); + var i$2 = exn$0[2]; + a: + { + b: + { + var i$3 = i$2; + for(;;){ + var father = (i$3 - 1 | 0) / 3 | 0; + if(i$3 === father) + throw caml_maybe_attach_backtrace([0, Assert_failure, _a_], 1); + if + (0 <= caml_call2(cmp, caml_check_bound(a, father)[1 + father], e$0)) + break; + var _u_ = caml_check_bound(a, father)[1 + father]; + caml_check_bound(a, i$3)[1 + i$3] = _u_; + if(0 >= father) break b; + i$3 = father; + } + caml_check_bound(a, i$3)[1 + i$3] = e$0; + break a; + } + caml_check_bound(a, 0)[1] = e$0; + } + var _z_ = i$4 - 1 | 0; + if(2 === i$4) break; + i$4 = _z_; + } + } + } + var _x_ = 1 < l ? 1 : 0; + if(_x_){ + var e = caml_check_bound(a, 1)[2]; + a[2] = caml_check_bound(a, 0)[1]; + a[1] = e; + var _y_ = 0; + } + else + var _y_ = _x_; + return _y_; + } + function stable_sort(cmp, a){ + function merge(src1ofs, src1len, src2, src2ofs, src2len, dst, dstofs){ + var + src1r = src1ofs + src1len | 0, + src2r = src2ofs + src2len | 0, + s2$1 = caml_check_bound(src2, src2ofs)[1 + src2ofs], + s1$1 = caml_check_bound(a, src1ofs)[1 + src1ofs], + i1 = src1ofs, + s1 = s1$1, + i2 = src2ofs, + s2 = s2$1, + d = dstofs; + for(;;) + if(0 < caml_call2(cmp, s1, s2)){ + caml_check_bound(dst, d)[1 + d] = s2; + var i2$0 = i2 + 1 | 0; + if(i2$0 >= src2r) return blit(a, i1, dst, d + 1 | 0, src1r - i1 | 0); + var d$0 = d + 1 | 0, s2$0 = caml_check_bound(src2, i2$0)[1 + i2$0]; + i2 = i2$0; + s2 = s2$0; + d = d$0; + } + else{ + caml_check_bound(dst, d)[1 + d] = s1; + var i1$0 = i1 + 1 | 0; + if(i1$0 >= src1r) + return blit(src2, i2, dst, d + 1 | 0, src2r - i2 | 0); + var d$1 = d + 1 | 0, s1$0 = caml_check_bound(a, i1$0)[1 + i1$0]; + i1 = i1$0; + s1 = s1$0; + d = d$1; + } + } + function isortto(srcofs, dst, dstofs, len){ + var _k_ = len - 1 | 0, _j_ = 0; + if(_k_ >= 0){ + var i = _j_; + for(;;){ + var + _l_ = srcofs + i | 0, + e = caml_check_bound(a, _l_)[1 + _l_], + j = [0, (dstofs + i | 0) - 1 | 0]; + for(;;){ + if(dstofs > j[1]) break; + var _m_ = j[1]; + if(0 >= caml_call2(cmp, caml_check_bound(dst, _m_)[1 + _m_], e)) + break; + var + _n_ = j[1], + _o_ = caml_check_bound(dst, _n_)[1 + _n_], + _p_ = j[1] + 1 | 0; + caml_check_bound(dst, _p_)[1 + _p_] = _o_; + j[1]--; + } + var _q_ = j[1] + 1 | 0; + caml_check_bound(dst, _q_)[1 + _q_] = e; + var _r_ = i + 1 | 0; + if(_k_ === i) break; + i = _r_; + } + } + return 0; + } + function sortto(srcofs, dst, dstofs, len){ + if(len <= 5) return isortto(srcofs, dst, dstofs, len); + var l1 = len / 2 | 0, l2 = len - l1 | 0; + sortto(srcofs + l1 | 0, dst, dstofs + l1 | 0, l2); + sortto(srcofs, a, srcofs + l2 | 0, l1); + return merge(srcofs + l2 | 0, l1, dst, dstofs + l1 | 0, l2, dst, dstofs); + } + var l = a.length - 1; + if(l <= 5) return isortto(0, a, 0, l); + var + l1 = l / 2 | 0, + l2 = l - l1 | 0, + t = caml_make_vect(l2, caml_check_bound(a, 0)[1]); + sortto(l1, t, 0, l2); + sortto(0, a, l2, l1); + return merge(l2, l1, t, 0, l2, a, 0); + } + function to_seq(a){ + function aux(i, param){ + if(i >= a.length - 1) return 0; + var x = a[1 + i], _h_ = i + 1 | 0; + return [0, x, function(_i_){return aux(_h_, _i_);}]; + } + var _f_ = 0; + return function(_g_){return aux(_f_, _g_);}; + } + function to_seqi(a){ + function aux(i, param){ + if(i >= a.length - 1) return 0; + var x = a[1 + i], _d_ = i + 1 | 0; + return [0, [0, i, x], function(_e_){return aux(_d_, _e_);}]; + } + var _b_ = 0; + return function(_c_){return aux(_b_, _c_);}; + } + function of_seq(i$2){ + var + l = + caml_call3 + (Stdlib_Seq[11], function(acc, x){return [0, x, acc];}, 0, i$2); + if(! l) return [0]; + var + tl = l[2], + hd = l[1], + len = list_length(0, l), + a = caml_make_vect(len, hd), + i$1 = len - 2 | 0, + i = i$1, + param = tl; + for(;;){ + if(! param) return a; + var tl$0 = param[2], hd$0 = param[1]; + a[1 + i] = hd$0; + var i$0 = i - 1 | 0; + i = i$0; + param = tl$0; + } + } + var + Stdlib_Array = + [0, + make_float, + init, + make_matrix, + make_matrix, + append, + runtime.caml_array_concat, + sub, + copy, + fill, + blit, + to_list, + of_list, + iter, + iteri, + map, + mapi, + fold_left, + fold_left_map, + fold_right, + iter2, + map2, + for_all, + exists, + for_all2, + exists2, + mem, + memq, + find_opt, + find_map, + split, + combine, + sort, + stable_sort, + stable_sort, + to_seq, + to_seqi, + of_seq, + Floatarray]; + runtime.caml_register_global(14, Stdlib_Array, "Stdlib__Array"); + return; + } + (globalThis)); + +//# 5812 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + caml_greaterequal = runtime.caml_greaterequal, + caml_int_compare = runtime.caml_int_compare, + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace, + caml_mul = runtime.caml_mul, + caml_wrap_exception = runtime.caml_wrap_exception, + global_data = runtime.caml_get_global_data(), + Stdlib = global_data.Stdlib, + Stdlib_Sys = global_data.Stdlib__Sys, + Assert_failure = global_data.Assert_failure, + zero = 0, + one = 1; + function succ(n){return n + 1 | 0;} + function pred(n){return n - 1 | 0;} + function abs(n){return caml_greaterequal(n, 0) ? n : - n | 0;} + function lognot(n){return n ^ -1;} + var + _a_ = Stdlib_Sys[9], + _b_ = [0, "int32.ml", 69, 6], + minus_one = -1, + min_int = -2147483648, + max_int = 2147483647; + if(32 === _a_) + var + max_int$0 = Stdlib[19], + unsigned_to_int = + function(n){ + if(0 >= caml_int_compare(0, n) && 0 >= caml_int_compare(n, max_int$0)) + return [0, n]; + return 0; + }; + else{ + if(64 !== _a_) + throw caml_maybe_attach_backtrace([0, Assert_failure, _b_], 1); + var unsigned_to_int = function(n){return [0, n & -1];}; + } + function to_string(n){return runtime.caml_format_int("%d", n);} + function of_string_opt(s){ + try{var _d_ = [0, runtime.caml_int_of_string(s)]; return _d_;} + catch(_e_){ + var _c_ = caml_wrap_exception(_e_); + if(_c_[1] === Stdlib[7]) return 0; + throw caml_maybe_attach_backtrace(_c_, 0); + } + } + var compare = caml_int_compare; + function equal(x, y){return 0 === caml_int_compare(x, y) ? 1 : 0;} + function unsigned_compare(n, m){ + var y = m + 2147483648 | 0, x = n + 2147483648 | 0; + return caml_int_compare(x, y); + } + function min(x, y){return runtime.caml_lessequal(x, y) ? x : y;} + function max(x, y){return caml_greaterequal(x, y) ? x : y;} + function unsigned_div(n, d){ + if(runtime.caml_lessthan(d, 0)) + return 0 <= unsigned_compare(n, d) ? one : zero; + var q = runtime.caml_div(n >>> 1 | 0, d) << 1, r = n - caml_mul(q, d) | 0; + return 0 <= unsigned_compare(r, d) ? q + 1 | 0 : q; + } + function unsigned_rem(n, d){ + return n - caml_mul(unsigned_div(n, d), d) | 0; + } + var + Stdlib_Int32 = + [0, + zero, + one, + minus_one, + unsigned_div, + unsigned_rem, + succ, + pred, + abs, + max_int, + min_int, + lognot, + unsigned_to_int, + of_string_opt, + to_string, + compare, + unsigned_compare, + equal, + min, + max]; + runtime.caml_register_global(14, Stdlib_Int32, "Stdlib__Int32"); + return; + } + (globalThis)); + +//# 5907 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + caml_greaterequal = runtime.caml_greaterequal, + caml_int64_add = runtime.caml_int64_add, + caml_int64_compare = runtime.caml_int64_compare, + caml_int64_mul = runtime.caml_int64_mul, + caml_int64_sub = runtime.caml_int64_sub, + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace, + caml_wrap_exception = runtime.caml_wrap_exception, + global_data = runtime.caml_get_global_data(), + _a_ = runtime.caml_int64_create_lo_mi_hi(1, 0, 0), + zero = runtime.caml_int64_create_lo_mi_hi(0, 0, 0), + one = runtime.caml_int64_create_lo_mi_hi(1, 0, 0), + minus_one = runtime.caml_int64_create_lo_mi_hi(16777215, 16777215, 65535), + min_int = runtime.caml_int64_create_lo_mi_hi(0, 0, 32768), + max_int = runtime.caml_int64_create_lo_mi_hi(16777215, 16777215, 32767), + Stdlib = global_data.Stdlib, + _b_ = runtime.caml_int64_create_lo_mi_hi(1, 0, 0), + _c_ = runtime.caml_int64_create_lo_mi_hi(0, 0, 0), + _d_ = runtime.caml_int64_create_lo_mi_hi(16777215, 16777215, 65535); + function succ(n){return caml_int64_add(n, _a_);} + function pred(n){return caml_int64_sub(n, _b_);} + function abs(n){ + return caml_greaterequal(n, _c_) ? n : runtime.caml_int64_neg(n); + } + function lognot(n){return runtime.caml_int64_xor(n, _d_);} + var max_int$0 = runtime.caml_int64_of_int32(Stdlib[19]); + function unsigned_to_int(n){ + if + (0 >= caml_int64_compare(zero, n) + && 0 >= caml_int64_compare(n, max_int$0)) + return [0, runtime.caml_int64_to_int32(n)]; + return 0; + } + function to_string(n){return runtime.caml_int64_format("%d", n);} + function of_string_opt(s){ + try{var _f_ = [0, runtime.caml_int64_of_string(s)]; return _f_;} + catch(_g_){ + var _e_ = caml_wrap_exception(_g_); + if(_e_[1] === Stdlib[7]) return 0; + throw caml_maybe_attach_backtrace(_e_, 0); + } + } + function compare(x, y){return caml_int64_compare(x, y);} + function equal(x, y){return 0 === caml_int64_compare(x, y) ? 1 : 0;} + function unsigned_compare(n, m){ + var y = caml_int64_sub(m, min_int), x = caml_int64_sub(n, min_int); + return caml_int64_compare(x, y); + } + function min(x, y){return runtime.caml_lessequal(x, y) ? x : y;} + function max(x, y){return caml_greaterequal(x, y) ? x : y;} + function unsigned_div(n, d){ + if(runtime.caml_lessthan(d, zero)) + return 0 <= unsigned_compare(n, d) ? one : zero; + var + q = + runtime.caml_int64_shift_left + (runtime.caml_int64_div + (runtime.caml_int64_shift_right_unsigned(n, 1), d), + 1), + r = caml_int64_sub(n, caml_int64_mul(q, d)); + return 0 <= unsigned_compare(r, d) ? caml_int64_add(q, _a_) : q; + } + function unsigned_rem(n, d){ + return caml_int64_sub(n, caml_int64_mul(unsigned_div(n, d), d)); + } + var + Stdlib_Int64 = + [0, + zero, + one, + minus_one, + unsigned_div, + unsigned_rem, + succ, + pred, + abs, + max_int, + min_int, + lognot, + unsigned_to_int, + of_string_opt, + to_string, + compare, + unsigned_compare, + equal, + min, + max]; + runtime.caml_register_global(11, Stdlib_Int64, "Stdlib__Int64"); + return; + } + (globalThis)); + +//# 7383 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst_Map_bal$3 = "Map.bal", + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + var + global_data = runtime.caml_get_global_data(), + Stdlib = global_data.Stdlib, + Assert_failure = global_data.Assert_failure, + Stdlib_Seq = global_data.Stdlib__Seq, + cst_Map_bal = cst_Map_bal$3, + cst_Map_bal$0 = cst_Map_bal$3, + cst_Map_bal$1 = cst_Map_bal$3, + cst_Map_bal$2 = cst_Map_bal$3, + cst_Map_remove_min_elt = "Map.remove_min_elt", + _a_ = [0, 0, 0, 0], + _b_ = [0, "map.ml", 400, 10], + _c_ = [0, 0, 0], + Stdlib_Map = + [0, + function(Ord){ + function height(param){ + if(! param) return 0; + var h = param[5]; + return h; + } + function create(l, x, d, r){ + var + hl = height(l), + hr = height(r), + _K_ = hr <= hl ? hl + 1 | 0 : hr + 1 | 0; + return [0, l, x, d, r, _K_]; + } + function singleton(x, d){return [0, 0, x, d, 0, 1];} + function bal(l, x, d, r){ + if(l) var h = l[5], hl = h; else var hl = 0; + if(r) var h$0 = r[5], hr = h$0; else var hr = 0; + if((hr + 2 | 0) < hl){ + if(! l) return caml_call1(Stdlib[1], cst_Map_bal$0); + var lr = l[4], ld = l[3], lv = l[2], ll = l[1], _F_ = height(lr); + if(_F_ <= height(ll)) + return create(ll, lv, ld, create(lr, x, d, r)); + if(! lr) return caml_call1(Stdlib[1], cst_Map_bal); + var + lrr = lr[4], + lrd = lr[3], + lrv = lr[2], + lrl = lr[1], + _G_ = create(lrr, x, d, r); + return create(create(ll, lv, ld, lrl), lrv, lrd, _G_); + } + if((hl + 2 | 0) >= hr){ + var _J_ = hr <= hl ? hl + 1 | 0 : hr + 1 | 0; + return [0, l, x, d, r, _J_]; + } + if(! r) return caml_call1(Stdlib[1], cst_Map_bal$2); + var rr = r[4], rd = r[3], rv = r[2], rl = r[1], _H_ = height(rl); + if(_H_ <= height(rr)) return create(create(l, x, d, rl), rv, rd, rr); + if(! rl) return caml_call1(Stdlib[1], cst_Map_bal$1); + var + rlr = rl[4], + rld = rl[3], + rlv = rl[2], + rll = rl[1], + _I_ = create(rlr, rv, rd, rr); + return create(create(l, x, d, rll), rlv, rld, _I_); + } + var empty = 0; + function is_empty(param){return param ? 0 : 1;} + function add(x, data, m){ + if(! m) return [0, 0, x, data, 0, 1]; + var + h = m[5], + r = m[4], + d = m[3], + v = m[2], + l = m[1], + c = caml_call2(Ord[1], x, v); + if(0 === c) return d === data ? m : [0, l, x, data, r, h]; + if(0 <= c){ + var rr = add(x, data, r); + return r === rr ? m : bal(l, v, d, rr); + } + var ll = add(x, data, l); + return l === ll ? m : bal(ll, v, d, r); + } + function find(x, param){ + var param$0 = param; + for(;;){ + if(! param$0) throw caml_maybe_attach_backtrace(Stdlib[8], 1); + var + r = param$0[4], + d = param$0[3], + v = param$0[2], + l = param$0[1], + c = caml_call2(Ord[1], x, v); + if(0 === c) return d; + var r$0 = 0 <= c ? r : l; + param$0 = r$0; + } + } + function find_first(f, param$0){ + var param$1 = param$0; + for(;;){ + if(! param$1) throw caml_maybe_attach_backtrace(Stdlib[8], 1); + var + r$0 = param$1[4], + d0$1 = param$1[3], + v0$1 = param$1[2], + l$0 = param$1[1]; + if(caml_call1(f, v0$1)){ + var v0 = v0$1, d0 = d0$1, param = l$0; + for(;;){ + if(! param) return [0, v0, d0]; + var r = param[4], d0$0 = param[3], v0$0 = param[2], l = param[1]; + if(caml_call1(f, v0$0)){ + v0 = v0$0; + d0 = d0$0; + param = l; + } + else + param = r; + } + } + else + param$1 = r$0; + } + } + function find_first_opt(f, param$0){ + var param$1 = param$0; + for(;;){ + if(! param$1) return 0; + var + r$0 = param$1[4], + d0$1 = param$1[3], + v0$1 = param$1[2], + l$0 = param$1[1]; + if(caml_call1(f, v0$1)){ + var v0 = v0$1, d0 = d0$1, param = l$0; + for(;;){ + if(! param) return [0, [0, v0, d0]]; + var r = param[4], d0$0 = param[3], v0$0 = param[2], l = param[1]; + if(caml_call1(f, v0$0)){ + v0 = v0$0; + d0 = d0$0; + param = l; + } + else + param = r; + } + } + else + param$1 = r$0; + } + } + function find_last(f, param$0){ + var param$1 = param$0; + for(;;){ + if(! param$1) throw caml_maybe_attach_backtrace(Stdlib[8], 1); + var + r$0 = param$1[4], + d0$1 = param$1[3], + v0$1 = param$1[2], + l$0 = param$1[1]; + if(caml_call1(f, v0$1)){ + var v0 = v0$1, d0 = d0$1, param = r$0; + for(;;){ + if(! param) return [0, v0, d0]; + var r = param[4], d0$0 = param[3], v0$0 = param[2], l = param[1]; + if(caml_call1(f, v0$0)){ + v0 = v0$0; + d0 = d0$0; + param = r; + } + else + param = l; + } + } + else + param$1 = l$0; + } + } + function find_last_opt(f, param$0){ + var param$1 = param$0; + for(;;){ + if(! param$1) return 0; + var + r$0 = param$1[4], + d0$1 = param$1[3], + v0$1 = param$1[2], + l$0 = param$1[1]; + if(caml_call1(f, v0$1)){ + var v0 = v0$1, d0 = d0$1, param = r$0; + for(;;){ + if(! param) return [0, [0, v0, d0]]; + var r = param[4], d0$0 = param[3], v0$0 = param[2], l = param[1]; + if(caml_call1(f, v0$0)){ + v0 = v0$0; + d0 = d0$0; + param = r; + } + else + param = l; + } + } + else + param$1 = l$0; + } + } + function find_opt(x, param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + var + r = param$0[4], + d = param$0[3], + v = param$0[2], + l = param$0[1], + c = caml_call2(Ord[1], x, v); + if(0 === c) return [0, d]; + var r$0 = 0 <= c ? r : l; + param$0 = r$0; + } + } + function mem(x, param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + var + r = param$0[4], + v = param$0[2], + l = param$0[1], + c = caml_call2(Ord[1], x, v), + _E_ = 0 === c ? 1 : 0; + if(_E_) return _E_; + var r$0 = 0 <= c ? r : l; + param$0 = r$0; + } + } + function min_binding(param){ + var param$0 = param; + for(;;){ + if(! param$0) throw caml_maybe_attach_backtrace(Stdlib[8], 1); + var l = param$0[1]; + if(! l){var d = param$0[3], v = param$0[2]; return [0, v, d];} + param$0 = l; + } + } + function min_binding_opt(param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + var l = param$0[1]; + if(! l){var d = param$0[3], v = param$0[2]; return [0, [0, v, d]];} + param$0 = l; + } + } + function max_binding(param){ + var param$0 = param; + for(;;){ + if(! param$0) throw caml_maybe_attach_backtrace(Stdlib[8], 1); + if(! param$0[4]){ + var d = param$0[3], v = param$0[2]; + return [0, v, d]; + } + var r = param$0[4]; + param$0 = r; + } + } + function max_binding_opt(param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + if(! param$0[4]){ + var d = param$0[3], v = param$0[2]; + return [0, [0, v, d]]; + } + var r = param$0[4]; + param$0 = r; + } + } + function remove_min_binding(param){ + if(! param) return caml_call1(Stdlib[1], cst_Map_remove_min_elt); + var l = param[1]; + if(l){ + var r = param[4], d = param[3], v = param[2]; + return bal(remove_min_binding(l), v, d, r); + } + var r$0 = param[4]; + return r$0; + } + function _d_(t1, t2){ + if(! t1) return t2; + if(! t2) return t1; + var match = min_binding(t2), d = match[2], x = match[1]; + return bal(t1, x, d, remove_min_binding(t2)); + } + function remove(x, m){ + if(! m) return 0; + var + r = m[4], + d = m[3], + v = m[2], + l = m[1], + c = caml_call2(Ord[1], x, v); + if(0 === c) return _d_(l, r); + if(0 <= c){ + var rr = remove(x, r); + return r === rr ? m : bal(l, v, d, rr); + } + var ll = remove(x, l); + return l === ll ? m : bal(ll, v, d, r); + } + function update(x, f, m){ + if(! m){ + var match$0 = caml_call1(f, 0); + if(! match$0) return 0; + var data$0 = match$0[1]; + return [0, 0, x, data$0, 0, 1]; + } + var + h = m[5], + r = m[4], + d = m[3], + v = m[2], + l = m[1], + c = caml_call2(Ord[1], x, v); + if(0 === c){ + var match = caml_call1(f, [0, d]); + if(! match) return _d_(l, r); + var data = match[1]; + return d === data ? m : [0, l, x, data, r, h]; + } + if(0 <= c){ + var rr = update(x, f, r); + return r === rr ? m : bal(l, v, d, rr); + } + var ll = update(x, f, l); + return l === ll ? m : bal(ll, v, d, r); + } + function iter(f, param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + var r = param$0[4], d = param$0[3], v = param$0[2], l = param$0[1]; + iter(f, l); + caml_call2(f, v, d); + param$0 = r; + } + } + function map(f, param){ + if(! param) return 0; + var + h = param[5], + r = param[4], + d = param[3], + v = param[2], + l = param[1], + l$0 = map(f, l), + d$0 = caml_call1(f, d), + r$0 = map(f, r); + return [0, l$0, v, d$0, r$0, h]; + } + function mapi(f, param){ + if(! param) return 0; + var + h = param[5], + r = param[4], + d = param[3], + v = param[2], + l = param[1], + l$0 = mapi(f, l), + d$0 = caml_call2(f, v, d), + r$0 = mapi(f, r); + return [0, l$0, v, d$0, r$0, h]; + } + function fold(f, m, accu){ + var m$0 = m, accu$0 = accu; + for(;;){ + if(! m$0) return accu$0; + var + r = m$0[4], + d = m$0[3], + v = m$0[2], + l = m$0[1], + accu$1 = caml_call3(f, v, d, fold(f, l, accu$0)); + m$0 = r; + accu$0 = accu$1; + } + } + function for_all(p, param){ + var param$0 = param; + for(;;){ + if(! param$0) return 1; + var + r = param$0[4], + d = param$0[3], + v = param$0[2], + l = param$0[1], + _B_ = caml_call2(p, v, d); + if(_B_){ + var _C_ = for_all(p, l); + if(_C_){param$0 = r; continue;} + var _D_ = _C_; + } + else + var _D_ = _B_; + return _D_; + } + } + function exists(p, param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + var + r = param$0[4], + d = param$0[3], + v = param$0[2], + l = param$0[1], + _y_ = caml_call2(p, v, d); + if(_y_) + var _z_ = _y_; + else{ + var _A_ = exists(p, l); + if(! _A_){param$0 = r; continue;} + var _z_ = _A_; + } + return _z_; + } + } + function add_min_binding(k, x, param){ + if(! param) return singleton(k, x); + var r = param[4], d = param[3], v = param[2], l = param[1]; + return bal(add_min_binding(k, x, l), v, d, r); + } + function add_max_binding(k, x, param){ + if(! param) return singleton(k, x); + var r = param[4], d = param[3], v = param[2], l = param[1]; + return bal(l, v, d, add_max_binding(k, x, r)); + } + function join(l, v, d, r){ + if(! l) return add_min_binding(v, d, r); + if(! r) return add_max_binding(v, d, l); + var + rh = r[5], + rr = r[4], + rd = r[3], + rv = r[2], + rl = r[1], + lh = l[5], + lr = l[4], + ld = l[3], + lv = l[2], + ll = l[1]; + return (rh + 2 | 0) < lh + ? bal(ll, lv, ld, join(lr, v, d, r)) + : (lh + + 2 + | 0) + < rh + ? bal(join(l, v, d, rl), rv, rd, rr) + : create(l, v, d, r); + } + function concat(t1, t2){ + if(! t1) return t2; + if(! t2) return t1; + var match = min_binding(t2), d = match[2], x = match[1]; + return join(t1, x, d, remove_min_binding(t2)); + } + function concat_or_join(t1, v, d, t2){ + if(! d) return concat(t1, t2); + var d$0 = d[1]; + return join(t1, v, d$0, t2); + } + function split(x, param){ + if(! param) return _a_; + var + r = param[4], + d = param[3], + v = param[2], + l = param[1], + c = caml_call2(Ord[1], x, v); + if(0 === c) return [0, l, [0, d], r]; + if(0 <= c){ + var + match = split(x, r), + rr = match[3], + pres = match[2], + lr = match[1]; + return [0, join(l, v, d, lr), pres, rr]; + } + var + match$0 = split(x, l), + rl = match$0[3], + pres$0 = match$0[2], + ll = match$0[1]; + return [0, ll, pres$0, join(rl, v, d, r)]; + } + function merge(f, s1, s2){ + if(s1){ + var h1 = s1[5], r1 = s1[4], d1 = s1[3], v1 = s1[2], l1 = s1[1]; + if(height(s2) <= h1){ + var + match = split(v1, s2), + r2 = match[3], + d2 = match[2], + l2 = match[1], + _u_ = merge(f, r1, r2), + _v_ = caml_call3(f, v1, [0, d1], d2); + return concat_or_join(merge(f, l1, l2), v1, _v_, _u_); + } + } + else if(! s2) return 0; + if(! s2) + throw caml_maybe_attach_backtrace([0, Assert_failure, _b_], 1); + var + r2$0 = s2[4], + d2$0 = s2[3], + v2 = s2[2], + l2$0 = s2[1], + match$0 = split(v2, s1), + r1$0 = match$0[3], + d1$0 = match$0[2], + l1$0 = match$0[1], + _w_ = merge(f, r1$0, r2$0), + _x_ = caml_call3(f, v2, d1$0, [0, d2$0]); + return concat_or_join(merge(f, l1$0, l2$0), v2, _x_, _w_); + } + function union(f, s1, s2){ + if(s1){ + if(s2){ + var + h2 = s2[5], + r2 = s2[4], + d2 = s2[3], + v2 = s2[2], + l2 = s2[1], + h1 = s1[5], + r1 = s1[4], + d1 = s1[3], + v1 = s1[2], + l1 = s1[1]; + if(h2 <= h1){ + var + match = split(v1, s2), + r2$0 = match[3], + d2$0 = match[2], + l2$0 = match[1], + l = union(f, l1, l2$0), + r = union(f, r1, r2$0); + if(! d2$0) return join(l, v1, d1, r); + var d2$1 = d2$0[1]; + return concat_or_join(l, v1, caml_call3(f, v1, d1, d2$1), r); + } + var + match$0 = split(v2, s1), + r1$0 = match$0[3], + d1$0 = match$0[2], + l1$0 = match$0[1], + l$0 = union(f, l1$0, l2), + r$0 = union(f, r1$0, r2); + if(! d1$0) return join(l$0, v2, d2, r$0); + var d1$1 = d1$0[1]; + return concat_or_join(l$0, v2, caml_call3(f, v2, d1$1, d2), r$0); + } + var s = s1; + } + else + var s = s2; + return s; + } + function filter(p, m){ + if(! m) return 0; + var + r = m[4], + d = m[3], + v = m[2], + l = m[1], + l$0 = filter(p, l), + pvd = caml_call2(p, v, d), + r$0 = filter(p, r); + if(! pvd) return concat(l$0, r$0); + if(l === l$0 && r === r$0) return m; + return join(l$0, v, d, r$0); + } + function filter_map(f, param){ + if(! param) return 0; + var + r = param[4], + d = param[3], + v = param[2], + l = param[1], + l$0 = filter_map(f, l), + fvd = caml_call2(f, v, d), + r$0 = filter_map(f, r); + if(! fvd) return concat(l$0, r$0); + var d$0 = fvd[1]; + return join(l$0, v, d$0, r$0); + } + function partition(p, param){ + if(! param) return _c_; + var + r = param[4], + d = param[3], + v = param[2], + l = param[1], + match = partition(p, l), + lf = match[2], + lt = match[1], + pvd = caml_call2(p, v, d), + match$0 = partition(p, r), + rf = match$0[2], + rt = match$0[1]; + if(pvd){ + var _s_ = concat(lf, rf); + return [0, join(lt, v, d, rt), _s_]; + } + var _t_ = join(lf, v, d, rf); + return [0, concat(lt, rt), _t_]; + } + function cons_enum(m, e){ + var m$0 = m, e$0 = e; + for(;;){ + if(! m$0) return e$0; + var + r = m$0[4], + d = m$0[3], + v = m$0[2], + l = m$0[1], + e$1 = [0, v, d, r, e$0]; + m$0 = l; + e$0 = e$1; + } + } + function compare(cmp, m1, m2){ + var + e2$2 = cons_enum(m2, 0), + e1$2 = cons_enum(m1, 0), + e1 = e1$2, + e2 = e2$2; + for(;;){ + if(! e1) return e2 ? -1 : 0; + if(! e2) return 1; + var + e2$0 = e2[4], + r2 = e2[3], + d2 = e2[2], + v2 = e2[1], + e1$0 = e1[4], + r1 = e1[3], + d1 = e1[2], + v1 = e1[1], + c = caml_call2(Ord[1], v1, v2); + if(0 !== c) return c; + var c$0 = caml_call2(cmp, d1, d2); + if(0 !== c$0) return c$0; + var e2$1 = cons_enum(r2, e2$0), e1$1 = cons_enum(r1, e1$0); + e1 = e1$1; + e2 = e2$1; + } + } + function equal(cmp, m1, m2){ + var + e2$2 = cons_enum(m2, 0), + e1$2 = cons_enum(m1, 0), + e1 = e1$2, + e2 = e2$2; + for(;;){ + if(! e1) return e2 ? 0 : 1; + if(! e2) return 0; + var + e2$0 = e2[4], + r2 = e2[3], + d2 = e2[2], + v2 = e2[1], + e1$0 = e1[4], + r1 = e1[3], + d1 = e1[2], + v1 = e1[1], + _p_ = 0 === caml_call2(Ord[1], v1, v2) ? 1 : 0; + if(_p_){ + var _q_ = caml_call2(cmp, d1, d2); + if(_q_){ + var e2$1 = cons_enum(r2, e2$0), e1$1 = cons_enum(r1, e1$0); + e1 = e1$1; + e2 = e2$1; + continue; + } + var _r_ = _q_; + } + else + var _r_ = _p_; + return _r_; + } + } + function cardinal(param){ + if(! param) return 0; + var r = param[4], l = param[1], _o_ = cardinal(r); + return (cardinal(l) + 1 | 0) + _o_ | 0; + } + function bindings_aux(accu, param){ + var accu$0 = accu, param$0 = param; + for(;;){ + if(! param$0) return accu$0; + var + r = param$0[4], + d = param$0[3], + v = param$0[2], + l = param$0[1], + accu$1 = [0, [0, v, d], bindings_aux(accu$0, r)]; + accu$0 = accu$1; + param$0 = l; + } + } + function bindings(s){return bindings_aux(0, s);} + function add_seq(i, m){ + return caml_call3 + (Stdlib_Seq[11], + function(m, param){ + var v = param[2], k = param[1]; + return add(k, v, m); + }, + m, + i); + } + function of_seq(i){return add_seq(i, empty);} + function seq_of_enum(c, param){ + if(! c) return 0; + var + rest = c[4], + t = c[3], + v = c[2], + k = c[1], + _m_ = cons_enum(t, rest); + return [0, [0, k, v], function(_n_){return seq_of_enum(_m_, _n_);}]; + } + function to_seq(m){ + var _k_ = cons_enum(m, 0); + return function(_l_){return seq_of_enum(_k_, _l_);}; + } + function snoc_enum(s, e){ + var s$0 = s, e$0 = e; + for(;;){ + if(! s$0) return e$0; + var + r = s$0[4], + d = s$0[3], + v = s$0[2], + l = s$0[1], + e$1 = [0, v, d, l, e$0]; + s$0 = r; + e$0 = e$1; + } + } + function rev_seq_of_enum(c, param){ + if(! c) return 0; + var + rest = c[4], + t = c[3], + v = c[2], + k = c[1], + _i_ = snoc_enum(t, rest); + return [0, + [0, k, v], + function(_j_){return rev_seq_of_enum(_i_, _j_);}]; + } + function to_rev_seq(c){ + var _g_ = snoc_enum(c, 0); + return function(_h_){return rev_seq_of_enum(_g_, _h_);}; + } + function to_seq_from(low, m){ + a: + { + b: + { + var m$0 = m, c = 0; + for(;;){ + if(! m$0) break; + var + r = m$0[4], + d = m$0[3], + v = m$0[2], + l = m$0[1], + n = caml_call2(Ord[1], v, low); + if(0 === n) break b; + if(0 <= n){ + var c$0 = [0, v, d, r, c]; + m$0 = l; + c = c$0; + } + else + m$0 = r; + } + var _e_ = c; + break a; + } + var _e_ = [0, v, d, r, c]; + } + return function(_f_){return seq_of_enum(_e_, _f_);}; + } + return [0, + empty, + is_empty, + mem, + add, + update, + singleton, + remove, + merge, + union, + compare, + equal, + iter, + fold, + for_all, + exists, + filter, + filter_map, + partition, + cardinal, + bindings, + min_binding, + min_binding_opt, + max_binding, + max_binding_opt, + min_binding, + min_binding_opt, + split, + find, + find_opt, + find_first, + find_first_opt, + find_last, + find_last_opt, + map, + mapi, + to_seq, + to_rev_seq, + to_seq_from, + add_seq, + of_seq]; + }]; + runtime.caml_register_global(11, Stdlib_Map, "Stdlib__Map"); + return; + } + (globalThis)); + +//# 8497 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace, + caml_obj_make_forward = runtime.caml_obj_make_forward, + caml_obj_tag = runtime.caml_obj_tag, + caml_wrap_exception = runtime.caml_wrap_exception; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + var + global_data = runtime.caml_get_global_data(), + Stdlib_Obj = global_data.Stdlib__Obj, + Undefined = + [248, "CamlinternalLazy.Undefined", runtime.caml_fresh_oo_id(0)]; + function raise_undefined(param){ + throw caml_maybe_attach_backtrace(Undefined, 1); + } + function force_lazy_block(blk){ + var closure = blk[1]; + blk[1] = raise_undefined; + try{ + var result = caml_call1(closure, 0); + caml_obj_make_forward(blk, result); + return result; + } + catch(e$0){ + var e = caml_wrap_exception(e$0); + blk[1] = function(param){throw caml_maybe_attach_backtrace(e, 0);}; + throw caml_maybe_attach_backtrace(e, 0); + } + } + function force_val_lazy_block(blk){ + var closure = blk[1]; + blk[1] = raise_undefined; + var result = caml_call1(closure, 0); + caml_obj_make_forward(blk, result); + return result; + } + function force(lzv){ + var t = caml_obj_tag(lzv); + return t === Stdlib_Obj[10] + ? lzv[1] + : t !== Stdlib_Obj[6] ? lzv : force_lazy_block(lzv); + } + function force_val(lzv){ + var t = caml_obj_tag(lzv); + return t === Stdlib_Obj[10] + ? lzv[1] + : t !== Stdlib_Obj[6] ? lzv : force_val_lazy_block(lzv); + } + var + CamlinternalLazy = + [0, Undefined, force_lazy_block, force_val_lazy_block, force, force_val]; + runtime.caml_register_global(2, CamlinternalLazy, "CamlinternalLazy"); + return; + } + (globalThis)); + +//# 9012 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst_buffer_ml = "buffer.ml", + caml_blit_string = runtime.caml_blit_string, + caml_bswap16 = runtime.caml_bswap16, + caml_bytes_unsafe_get = runtime.caml_bytes_unsafe_get, + caml_bytes_unsafe_set = runtime.caml_bytes_unsafe_set, + caml_create_bytes = runtime.caml_create_bytes, + caml_int32_bswap = runtime.caml_int32_bswap, + caml_int64_bswap = runtime.caml_int64_bswap, + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace, + caml_ml_bytes_length = runtime.caml_ml_bytes_length, + caml_ml_string_length = runtime.caml_ml_string_length, + caml_string_get = runtime.caml_string_get; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + function caml_call4(f, a0, a1, a2, a3){ + return (f.l >= 0 ? f.l : f.l = f.length) == 4 + ? f(a0, a1, a2, a3) + : runtime.caml_call_gen(f, [a0, a1, a2, a3]); + } + function caml_call5(f, a0, a1, a2, a3, a4){ + return (f.l >= 0 ? f.l : f.l = f.length) == 5 + ? f(a0, a1, a2, a3, a4) + : runtime.caml_call_gen(f, [a0, a1, a2, a3, a4]); + } + var + undef = undefined, + global_data = runtime.caml_get_global_data(), + Stdlib_Sys = global_data.Stdlib__Sys, + Stdlib_Seq = global_data.Stdlib__Seq, + Stdlib = global_data.Stdlib, + Stdlib_String = global_data.Stdlib__String, + Assert_failure = global_data.Assert_failure, + Stdlib_Bytes = global_data.Stdlib__Bytes, + Stdlib_Uchar = global_data.Stdlib__Uchar, + cst_Buffer_sub = "Buffer.sub", + cst_Buffer_blit = "Buffer.blit", + cst_Buffer_nth = "Buffer.nth", + _a_ = [0, cst_buffer_ml, 94, 2], + _b_ = [0, cst_buffer_ml, 93, 2], + cst_Buffer_add_cannot_grow_buf = "Buffer.add: cannot grow buffer", + _c_ = [0, cst_buffer_ml, 171, 8], + _d_ = [0, cst_buffer_ml, 138, 19], + _e_ = [0, cst_buffer_ml, 192, 8], + _f_ = [0, cst_buffer_ml, 174, 19], + _g_ = [0, cst_buffer_ml, 213, 8], + _h_ = [0, cst_buffer_ml, 195, 19], + cst_Buffer_add_substring_add_s = "Buffer.add_substring/add_subbytes", + _i_ = [0, cst_buffer_ml, 263, 2], + cst_Buffer_add_channel = "Buffer.add_channel", + _j_ = [0, cst_buffer_ml, 282, 9], + cst_Buffer_truncate = "Buffer.truncate"; + function create(n){ + var + n$0 = 1 <= n ? n : 1, + n$1 = Stdlib_Sys[12] < n$0 ? Stdlib_Sys[12] : n$0, + s = caml_create_bytes(n$1); + return [0, s, 0, n$1, s]; + } + function contents(b){return caml_call3(Stdlib_Bytes[8], b[1], 0, b[2]);} + function to_bytes(b){return caml_call3(Stdlib_Bytes[7], b[1], 0, b[2]);} + function sub(b, ofs, len){ + if(0 <= ofs && 0 <= len && (b[2] - len | 0) >= ofs) + return caml_call3(Stdlib_Bytes[8], b[1], ofs, len); + return caml_call1(Stdlib[1], cst_Buffer_sub); + } + function blit(src, srcoff, dst, dstoff, len){ + if + (0 <= len + && + 0 <= srcoff + && + (src[2] - len | 0) >= srcoff + && 0 <= dstoff && (caml_ml_bytes_length(dst) - len | 0) >= dstoff) + return runtime.caml_blit_bytes(src[1], srcoff, dst, dstoff, len); + return caml_call1(Stdlib[1], cst_Buffer_blit); + } + function nth(b, ofs){ + if(0 <= ofs && b[2] > ofs) return caml_bytes_unsafe_get(b[1], ofs); + return caml_call1(Stdlib[1], cst_Buffer_nth); + } + function length(b){return b[2];} + function clear(b){b[2] = 0; return 0;} + function reset(b){ + b[2] = 0; + b[1] = b[4]; + b[3] = caml_ml_bytes_length(b[1]); + return 0; + } + function resize(b, more){ + var old_pos = b[2], old_len = b[3], new_len = [0, old_len]; + for(;;){ + if(new_len[1] >= (old_pos + more | 0)) break; + new_len[1] = 2 * new_len[1] | 0; + } + if(Stdlib_Sys[12] < new_len[1]) + if((old_pos + more | 0) <= Stdlib_Sys[12]) + new_len[1] = Stdlib_Sys[12]; + else + caml_call1(Stdlib[2], cst_Buffer_add_cannot_grow_buf); + var new_buffer = caml_create_bytes(new_len[1]); + caml_call5(Stdlib_Bytes[11], b[1], 0, new_buffer, 0, b[2]); + b[1] = new_buffer; + b[3] = new_len[1]; + if((b[2] + more | 0) > b[3]) + throw caml_maybe_attach_backtrace([0, Assert_failure, _b_], 1); + if((old_pos + more | 0) <= b[3]) return; + throw caml_maybe_attach_backtrace([0, Assert_failure, _a_], 1); + } + function add_char(b, c){ + var pos = b[2]; + if(b[3] <= pos) resize(b, 1); + caml_bytes_unsafe_set(b[1], pos, c); + b[2] = pos + 1 | 0; + return 0; + } + function add_utf_8_uchar(b, u){ + var u$0 = caml_call1(Stdlib_Uchar[10], u); + if(0 > u$0) + throw caml_maybe_attach_backtrace([0, Assert_failure, _d_], 1); + if(127 >= u$0) return add_char(b, u$0); + if(2047 >= u$0){ + var pos$1 = b[2]; + if(b[3] < (pos$1 + 2 | 0)) resize(b, 2); + caml_bytes_unsafe_set(b[1], pos$1, 192 | u$0 >>> 6 | 0); + caml_bytes_unsafe_set(b[1], pos$1 + 1 | 0, 128 | u$0 & 63); + b[2] = pos$1 + 2 | 0; + return 0; + } + if(65535 < u$0){ + if(1114111 < u$0) + throw caml_maybe_attach_backtrace([0, Assert_failure, _c_], 1); + var pos = b[2]; + if(b[3] < (pos + 4 | 0)) resize(b, 4); + caml_bytes_unsafe_set(b[1], pos, 240 | u$0 >>> 18 | 0); + caml_bytes_unsafe_set(b[1], pos + 1 | 0, 128 | (u$0 >>> 12 | 0) & 63); + caml_bytes_unsafe_set(b[1], pos + 2 | 0, 128 | (u$0 >>> 6 | 0) & 63); + caml_bytes_unsafe_set(b[1], pos + 3 | 0, 128 | u$0 & 63); + b[2] = pos + 4 | 0; + return 0; + } + var pos$0 = b[2]; + if(b[3] < (pos$0 + 3 | 0)) resize(b, 3); + caml_bytes_unsafe_set(b[1], pos$0, 224 | u$0 >>> 12 | 0); + caml_bytes_unsafe_set(b[1], pos$0 + 1 | 0, 128 | (u$0 >>> 6 | 0) & 63); + caml_bytes_unsafe_set(b[1], pos$0 + 2 | 0, 128 | u$0 & 63); + b[2] = pos$0 + 3 | 0; + return 0; + } + function add_utf_16be_uchar(b, u){ + var u$0 = caml_call1(Stdlib_Uchar[10], u); + if(0 > u$0) + throw caml_maybe_attach_backtrace([0, Assert_failure, _f_], 1); + if(65535 < u$0){ + if(1114111 < u$0) + throw caml_maybe_attach_backtrace([0, Assert_failure, _e_], 1); + var + u$1 = u$0 - 65536 | 0, + hi = 55296 | u$1 >>> 10 | 0, + lo = 56320 | u$1 & 1023, + pos = b[2]; + if(b[3] < (pos + 4 | 0)) resize(b, 4); + caml_bytes_unsafe_set(b[1], pos, hi >>> 8 | 0); + caml_bytes_unsafe_set(b[1], pos + 1 | 0, hi & 255); + caml_bytes_unsafe_set(b[1], pos + 2 | 0, lo >>> 8 | 0); + caml_bytes_unsafe_set(b[1], pos + 3 | 0, lo & 255); + b[2] = pos + 4 | 0; + return 0; + } + var pos$0 = b[2]; + if(b[3] < (pos$0 + 2 | 0)) resize(b, 2); + caml_bytes_unsafe_set(b[1], pos$0, u$0 >>> 8 | 0); + caml_bytes_unsafe_set(b[1], pos$0 + 1 | 0, u$0 & 255); + b[2] = pos$0 + 2 | 0; + return 0; + } + function add_utf_16le_uchar(b, u){ + var u$0 = caml_call1(Stdlib_Uchar[10], u); + if(0 > u$0) + throw caml_maybe_attach_backtrace([0, Assert_failure, _h_], 1); + if(65535 < u$0){ + if(1114111 < u$0) + throw caml_maybe_attach_backtrace([0, Assert_failure, _g_], 1); + var + u$1 = u$0 - 65536 | 0, + hi = 55296 | u$1 >>> 10 | 0, + lo = 56320 | u$1 & 1023, + pos = b[2]; + if(b[3] < (pos + 4 | 0)) resize(b, 4); + caml_bytes_unsafe_set(b[1], pos, hi & 255); + caml_bytes_unsafe_set(b[1], pos + 1 | 0, hi >>> 8 | 0); + caml_bytes_unsafe_set(b[1], pos + 2 | 0, lo & 255); + caml_bytes_unsafe_set(b[1], pos + 3 | 0, lo >>> 8 | 0); + b[2] = pos + 4 | 0; + return 0; + } + var pos$0 = b[2]; + if(b[3] < (pos$0 + 2 | 0)) resize(b, 2); + caml_bytes_unsafe_set(b[1], pos$0, u$0 & 255); + caml_bytes_unsafe_set(b[1], pos$0 + 1 | 0, u$0 >>> 8 | 0); + b[2] = pos$0 + 2 | 0; + return 0; + } + function add_substring(b, s, offset, len){ + var _z_ = offset < 0 ? 1 : 0; + if(_z_) + var _A_ = _z_; + else + var + _B_ = len < 0 ? 1 : 0, + _A_ = _B_ || ((caml_ml_string_length(s) - len | 0) < offset ? 1 : 0); + if(_A_) caml_call1(Stdlib[1], cst_Buffer_add_substring_add_s); + var new_position = b[2] + len | 0; + if(b[3] < new_position) resize(b, len); + caml_blit_string(s, offset, b[1], b[2], len); + b[2] = new_position; + return 0; + } + function add_subbytes(b, s, offset, len){ + return add_substring(b, caml_call1(Stdlib_Bytes[48], s), offset, len); + } + function add_string(b, s){ + var len = caml_ml_string_length(s), new_position = b[2] + len | 0; + if(b[3] < new_position) resize(b, len); + caml_blit_string(s, 0, b[1], b[2], len); + b[2] = new_position; + return 0; + } + function add_bytes(b, s){ + return add_string(b, caml_call1(Stdlib_Bytes[48], s)); + } + function add_buffer(b, bs){return add_subbytes(b, bs[1], 0, bs[2]);} + function add_channel(b, ic, to_read$1){ + var + _x_ = to_read$1 < 0 ? 1 : 0, + _y_ = _x_ || (Stdlib_Sys[12] < to_read$1 ? 1 : 0); + if(_y_) caml_call1(Stdlib[1], cst_Buffer_add_channel); + if(b[3] < (b[2] + to_read$1 | 0)) resize(b, to_read$1); + var + ofs$1 = b[2], + buf = b[1], + already_read = 0, + ofs = ofs$1, + to_read = to_read$1; + for(;;){ + if(0 !== to_read){ + var r = caml_call4(Stdlib[84], ic, buf, ofs, to_read); + if(0 !== r){ + var + already_read$0 = already_read + r | 0, + ofs$0 = ofs + r | 0, + to_read$0 = to_read - r | 0; + already_read = already_read$0; + ofs = ofs$0; + to_read = to_read$0; + continue; + } + } + if((b[2] + already_read | 0) > b[3]) + throw caml_maybe_attach_backtrace([0, Assert_failure, _i_], 1); + b[2] = b[2] + already_read | 0; + if(already_read < to_read$1) + throw caml_maybe_attach_backtrace(Stdlib[12], 1); + return 0; + } + } + function output_buffer(oc, b){ + return caml_call4(Stdlib[68], oc, b[1], 0, b[2]); + } + function add_substitute(b, f, s){ + var lim$1 = caml_ml_string_length(s), previous = 32, i$4 = 0; + for(;;){ + if(i$4 >= lim$1){ + var _w_ = 92 === previous ? 1 : 0; + return _w_ ? add_char(b, previous) : _w_; + } + var previous$0 = caml_string_get(s, i$4); + if(36 === previous$0) + if(92 === previous){ + add_char(b, previous$0); + var i$5 = i$4 + 1 | 0; + previous = 32; + i$4 = i$5; + } + else{ + var start$0 = i$4 + 1 | 0; + if(lim$1 <= start$0) throw caml_maybe_attach_backtrace(Stdlib[8], 1); + var opening = caml_string_get(s, start$0); + a: + { + if(40 !== opening && 123 !== opening){ + var start = start$0 + 1 | 0, lim$0 = caml_ml_string_length(s); + b: + { + c: + { + d: + { + var i$2 = start; + for(;;){ + if(lim$0 <= i$2) break c; + var match = caml_string_get(s, i$2); + if(91 <= match){ + if(97 <= match){ + if(123 <= match) break d; + } + else if(95 !== match) break d; + } + else + if(58 <= match){ + if(65 > match) break; + } + else if(48 > match) break d; + var i$3 = i$2 + 1 | 0; + i$2 = i$3; + } + } + var stop$0 = i$2; + break b; + } + var stop$0 = lim$0; + } + var + match$0 = + [0, + caml_call3(Stdlib_String[15], s, start$0, stop$0 - start$0 | 0), + stop$0]; + break a; + } + var new_start = start$0 + 1 | 0, k$2 = 0; + if(40 === opening) + var closing = 41; + else{ + if(123 !== opening) + throw caml_maybe_attach_backtrace([0, Assert_failure, _j_], 1); + var closing = 125; + } + var lim = caml_ml_string_length(s), k = k$2, stop = new_start; + for(;;){ + if(lim <= stop) throw caml_maybe_attach_backtrace(Stdlib[8], 1); + if(caml_string_get(s, stop) === opening){ + var i = stop + 1 | 0, k$0 = k + 1 | 0; + k = k$0; + stop = i; + } + else if(caml_string_get(s, stop) === closing){ + if(0 === k) break; + var i$0 = stop + 1 | 0, k$1 = k - 1 | 0; + k = k$1; + stop = i$0; + } + else{var i$1 = stop + 1 | 0; stop = i$1;} + } + var + match$0 = + [0, + caml_call3 + (Stdlib_String[15], s, new_start, (stop - start$0 | 0) - 1 | 0), + stop + 1 | 0]; + } + var next_i = match$0[2], ident = match$0[1]; + add_string(b, caml_call1(f, ident)); + previous = 32; + i$4 = next_i; + } + else if(92 === previous){ + add_char(b, 92); + add_char(b, previous$0); + var i$6 = i$4 + 1 | 0; + previous = 32; + i$4 = i$6; + } + else if(92 === previous$0){ + var i$7 = i$4 + 1 | 0; + previous = previous$0; + i$4 = i$7; + } + else{ + add_char(b, previous$0); + var i$8 = i$4 + 1 | 0; + previous = previous$0; + i$4 = i$8; + } + } + } + function truncate(b, len){ + if(0 <= len && b[2] >= len){b[2] = len; return 0;} + return caml_call1(Stdlib[1], cst_Buffer_truncate); + } + function to_seq(b){ + function aux(i, param){ + if(b[2] <= i) return 0; + var x = caml_bytes_unsafe_get(b[1], i), _u_ = i + 1 | 0; + return [0, x, function(_v_){return aux(_u_, _v_);}]; + } + var _s_ = 0; + return function(_t_){return aux(_s_, _t_);}; + } + function to_seqi(b){ + function aux(i, param){ + if(b[2] <= i) return 0; + var x = caml_bytes_unsafe_get(b[1], i), _q_ = i + 1 | 0; + return [0, [0, i, x], function(_r_){return aux(_q_, _r_);}]; + } + var _o_ = 0; + return function(_p_){return aux(_o_, _p_);}; + } + function add_seq(b, seq){ + return caml_call2 + (Stdlib_Seq[12], function(_n_){return add_char(b, _n_);}, seq); + } + function of_seq(i){var b = create(32); add_seq(b, i); return b;} + function add_int8(b, x){ + var new_position = b[2] + 1 | 0; + if(b[3] < new_position) resize(b, 1); + caml_bytes_unsafe_set(b[1], b[2], x); + b[2] = new_position; + return 0; + } + function add_int16_ne(b, x){ + var new_position = b[2] + 2 | 0; + if(b[3] < new_position) resize(b, 2); + runtime.caml_bytes_set16(b[1], b[2], x); + b[2] = new_position; + return 0; + } + function add_int32_ne(b, x){ + var new_position = b[2] + 4 | 0; + if(b[3] < new_position) resize(b, 4); + runtime.caml_bytes_set32(b[1], b[2], x); + b[2] = new_position; + return 0; + } + function add_int64_ne(b, x){ + var new_position = b[2] + 8 | 0; + if(b[3] < new_position) resize(b, 8); + runtime.caml_bytes_set64(b[1], b[2], x); + b[2] = new_position; + return 0; + } + function add_int16_le(b, x){ + var _m_ = Stdlib_Sys[11] ? caml_bswap16(x) : x; + return add_int16_ne(b, _m_); + } + function add_int16_be(b, x){ + var x$0 = Stdlib_Sys[11] ? x : caml_bswap16(x); + return add_int16_ne(b, x$0); + } + function add_int32_le(b, x){ + var _l_ = Stdlib_Sys[11] ? caml_int32_bswap(x) : x; + return add_int32_ne(b, _l_); + } + function add_int32_be(b, x){ + var x$0 = Stdlib_Sys[11] ? x : caml_int32_bswap(x); + return add_int32_ne(b, x$0); + } + function add_int64_le(b, x){ + var _k_ = Stdlib_Sys[11] ? caml_int64_bswap(x) : x; + return add_int64_ne(b, _k_); + } + function add_int64_be(b, x){ + var x$0 = Stdlib_Sys[11] ? x : caml_int64_bswap(x); + return add_int64_ne(b, x$0); + } + var + Stdlib_Buffer = + [0, + create, + contents, + to_bytes, + sub, + blit, + nth, + length, + clear, + reset, + output_buffer, + truncate, + add_char, + add_utf_8_uchar, + add_utf_16le_uchar, + add_utf_16be_uchar, + add_string, + add_bytes, + add_substring, + add_subbytes, + add_substitute, + add_buffer, + add_channel, + to_seq, + to_seqi, + add_seq, + of_seq, + add_int8, + add_int8, + add_int16_ne, + add_int16_be, + add_int16_le, + add_int16_ne, + add_int16_be, + add_int16_le, + add_int32_ne, + add_int32_be, + add_int32_le, + add_int64_ne, + add_int64_be, + add_int64_le]; + runtime.caml_register_global(24, Stdlib_Buffer, "Stdlib__Buffer"); + return; + } + (globalThis)); + +//# 9543 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst$43 = "", + cst_and = " and ", + cst_Li$3 = "%Li", + cst_i$3 = "%i", + cst_li$3 = "%li", + cst_ni$3 = "%ni", + cst_u$0 = "%u", + cst$42 = "' '", + cst$41 = "'#'", + cst$39 = "'*'", + cst$40 = "'+'", + cst$44 = ", ", + cst_0$3 = "0", + cst_at_character_number = ": at character number ", + cst$38 = "@[", + cst$37 = "@{", + cst_bad_input_format_type_mism = + "bad input: format type mismatch between ", + cst_bad_input_format_type_mism$0 = + "bad input: format type mismatch between %S and %S", + cst_camlinternalFormat_ml = "camlinternalFormat.ml", + cst_invalid_format = "invalid format ", + cst_precision$3 = "precision", + caml_blit_string = runtime.caml_blit_string, + caml_bytes_set = runtime.caml_bytes_set, + caml_create_bytes = runtime.caml_create_bytes, + caml_format_float = runtime.caml_format_float, + caml_format_int = runtime.caml_format_int, + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace, + caml_ml_string_length = runtime.caml_ml_string_length, + caml_notequal = runtime.caml_notequal, + caml_string_get = runtime.caml_string_get, + caml_string_unsafe_get = runtime.caml_string_unsafe_get, + caml_trampoline = runtime.caml_trampoline, + caml_trampoline_return = runtime.caml_trampoline_return, + caml_wrap_exception = runtime.caml_wrap_exception; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + function caml_call4(f, a0, a1, a2, a3){ + return (f.l >= 0 ? f.l : f.l = f.length) == 4 + ? f(a0, a1, a2, a3) + : runtime.caml_call_gen(f, [a0, a1, a2, a3]); + } + function caml_call5(f, a0, a1, a2, a3, a4){ + return (f.l >= 0 ? f.l : f.l = f.length) == 5 + ? f(a0, a1, a2, a3, a4) + : runtime.caml_call_gen(f, [a0, a1, a2, a3, a4]); + } + var + undef = undefined, + global_data = runtime.caml_get_global_data(), + cst$9 = "%{", + cst$10 = "%}", + cst$11 = "%(", + cst$12 = "%)", + cst$13 = "%?", + cst$18 = cst$37, + cst$19 = cst$38, + cst$20 = cst$37, + cst$21 = cst$38, + cst$22 = cst$37, + cst$23 = cst$38, + cst$26 = cst$39, + cst$24 = "'-'", + cst$25 = cst$39, + cst$27 = cst$40, + cst$28 = cst$41, + cst$29 = cst$42, + cst$30 = cst$40, + cst$31 = "'_'", + sub_format = [0, 0, cst$43], + formatting_lit = [0, "@;", 1, 0], + cst$35 = cst$41, + cst$32 = cst$40, + cst$33 = cst$40, + cst$34 = cst$42, + cst$36 = cst$40, + cst_unexpected_end_of_format = "unexpected end of format", + cst$17 = ".", + cst$14 = "%!", + cst$15 = cst$37, + cst$16 = cst$38, + cst$8 = "%%", + cst$0 = "@]", + cst$1 = "@}", + cst$2 = "@?", + cst$3 = "@\n", + cst$4 = "@.", + cst$5 = "@@", + cst$6 = "@%", + cst$7 = "@", + cst = ".*", + Assert_failure = global_data.Assert_failure, + CamlinternalFormatBasics = global_data.CamlinternalFormatBasics, + Stdlib = global_data.Stdlib, + Stdlib_Buffer = global_data.Stdlib__Buffer, + Stdlib_String = global_data.Stdlib__String, + Stdlib_Sys = global_data.Stdlib__Sys, + Stdlib_Char = global_data.Stdlib__Char, + Stdlib_Bytes = global_data.Stdlib__Bytes, + Stdlib_Int = global_data.Stdlib__Int, + _a_ = [0, 0, 0], + cst_c = "%c", + cst_s = "%s", + cst_i = cst_i$3, + cst_li = cst_li$3, + cst_ni = cst_ni$3, + cst_Li = cst_Li$3, + cst_f = "%f", + cst_B = "%B", + cst_a = "%a", + cst_t = "%t", + cst_r = "%r", + cst_r$0 = "%_r", + cst_0c = "0c", + _b_ = [0, cst_camlinternalFormat_ml, 850, 23], + _c_ = [0, cst_camlinternalFormat_ml, 837, 26], + _d_ = [0, cst_camlinternalFormat_ml, 847, 28], + _e_ = [0, cst_camlinternalFormat_ml, 815, 21], + _f_ = [0, cst_camlinternalFormat_ml, 819, 21], + _g_ = [0, cst_camlinternalFormat_ml, 823, 19], + _h_ = [0, cst_camlinternalFormat_ml, 827, 22], + _i_ = [0, cst_camlinternalFormat_ml, 832, 30], + _j_ = [0, cst_camlinternalFormat_ml, 851, 23], + _k_ = [0, cst_camlinternalFormat_ml, 836, 26], + _l_ = [0, cst_camlinternalFormat_ml, 846, 28], + _m_ = [0, cst_camlinternalFormat_ml, 814, 21], + _n_ = [0, cst_camlinternalFormat_ml, 818, 21], + _o_ = [0, cst_camlinternalFormat_ml, 822, 19], + _p_ = [0, cst_camlinternalFormat_ml, 826, 22], + _q_ = [0, cst_camlinternalFormat_ml, 831, 30]; + function create_char_set(param){return caml_call2(Stdlib_Bytes[1], 32, 0);} + function add_in_char_set(char_set, c){ + var + str_ind = c >>> 3 | 0, + mask = 1 << (c & 7), + _cU_ = runtime.caml_bytes_get(char_set, str_ind) | mask; + return caml_bytes_set(char_set, str_ind, caml_call1(Stdlib[29], _cU_)); + } + function freeze_char_set(char_set){ + return caml_call1(Stdlib_Bytes[6], char_set); + } + function rev_char_set(char_set){ + var char_set$0 = create_char_set(0), i = 0; + for(;;){ + var _cS_ = caml_string_get(char_set, i) ^ 255; + caml_bytes_set(char_set$0, i, caml_call1(Stdlib[29], _cS_)); + var _cT_ = i + 1 | 0; + if(31 === i) return caml_call1(Stdlib_Bytes[48], char_set$0); + i = _cT_; + } + } + function is_in_char_set(char_set, c){ + var str_ind = c >>> 3 | 0, mask = 1 << (c & 7); + return 0 !== (caml_string_get(char_set, str_ind) & mask) ? 1 : 0; + } + function pad_of_pad_opt(pad_opt){ + if(! pad_opt) return 0; + var width = pad_opt[1]; + return [0, 1, width]; + } + function param_format_of_ignored_format(ign, fmt){ + if(typeof ign === "number") + switch(ign){ + case 0: + return [0, [0, fmt]]; + case 1: + return [0, [1, fmt]]; + case 2: + return [0, [19, fmt]]; + default: return [0, [22, fmt]]; + } + switch(ign[0]){ + case 0: + var pad_opt = ign[1]; return [0, [2, pad_of_pad_opt(pad_opt), fmt]]; + case 1: + var pad_opt$0 = ign[1]; + return [0, [3, pad_of_pad_opt(pad_opt$0), fmt]]; + case 2: + var pad_opt$1 = ign[2], iconv = ign[1]; + return [0, [4, iconv, pad_of_pad_opt(pad_opt$1), 0, fmt]]; + case 3: + var pad_opt$2 = ign[2], iconv$0 = ign[1]; + return [0, [5, iconv$0, pad_of_pad_opt(pad_opt$2), 0, fmt]]; + case 4: + var pad_opt$3 = ign[2], iconv$1 = ign[1]; + return [0, [6, iconv$1, pad_of_pad_opt(pad_opt$3), 0, fmt]]; + case 5: + var pad_opt$4 = ign[2], iconv$2 = ign[1]; + return [0, [7, iconv$2, pad_of_pad_opt(pad_opt$4), 0, fmt]]; + case 6: + var prec_opt = ign[2], pad_opt$5 = ign[1]; + if(prec_opt) + var ndec = prec_opt[1], _cR_ = [0, ndec]; + else + var _cR_ = 0; + return [0, [8, _a_, pad_of_pad_opt(pad_opt$5), _cR_, fmt]]; + case 7: + var pad_opt$6 = ign[1]; + return [0, [9, pad_of_pad_opt(pad_opt$6), fmt]]; + case 8: + var fmtty = ign[2], pad_opt$7 = ign[1]; + return [0, [13, pad_opt$7, fmtty, fmt]]; + case 9: + var fmtty$0 = ign[2], pad_opt$8 = ign[1]; + return [0, [14, pad_opt$8, fmtty$0, fmt]]; + case 10: + var char_set = ign[2], width_opt = ign[1]; + return [0, [20, width_opt, char_set, fmt]]; + default: var counter = ign[1]; return [0, [21, counter, fmt]]; + } + } + function default_float_precision(fconv){return 5 === fconv[2] ? 12 : -6;} + function buffer_create(init_size){ + return [0, 0, caml_create_bytes(init_size)]; + } + function buffer_check_size(buf, overhead){ + var + len = runtime.caml_ml_bytes_length(buf[2]), + min_len = buf[1] + overhead | 0; + if(len < min_len){ + var + new_len = caml_call2(Stdlib_Int[11], len * 2 | 0, min_len), + new_str = caml_create_bytes(new_len); + caml_call5(Stdlib_Bytes[11], buf[2], 0, new_str, 0, len); + buf[2] = new_str; + } + return; + } + function buffer_add_char(buf, c){ + buffer_check_size(buf, 1); + caml_bytes_set(buf[2], buf[1], c); + buf[1] = buf[1] + 1 | 0; + return; + } + function buffer_add_string(buf, s){ + var str_len = caml_ml_string_length(s); + buffer_check_size(buf, str_len); + caml_call5(Stdlib_String[42], s, 0, buf[2], buf[1], str_len); + buf[1] = buf[1] + str_len | 0; + return; + } + function buffer_contents(buf){ + return caml_call3(Stdlib_Bytes[8], buf[2], 0, buf[1]); + } + function char_of_iconv(iconv){ + switch(iconv){ + case 6: + case 7: + return 120; + case 8: + case 9: + return 88; + case 10: + case 11: + return 111; + case 12: + case 15: + return 117; + case 0: + case 1: + case 2: + case 13: + return 100; + default: return 105; + } + } + function char_of_fconv(opt, fconv){ + if(opt) var sth = opt[1], cF = sth; else var cF = 70; + switch(fconv[2]){ + case 0: + return 102; + case 1: + return 101; + case 2: + return 69; + case 3: + return 103; + case 4: + return 71; + case 5: + return cF; + case 6: + return 104; + case 7: + return 72; + default: return 70; + } + } + function bprint_padty(buf, padty){ + switch(padty){ + case 0: + return buffer_add_char(buf, 45); + case 1: + return; + default: return buffer_add_char(buf, 48); + } + } + function bprint_ignored_flag(buf, ign_flag){ + return ign_flag ? buffer_add_char(buf, 95) : ign_flag; + } + function bprint_pad_opt(buf, pad_opt){ + if(! pad_opt) return; + var width = pad_opt[1]; + return buffer_add_string(buf, caml_call1(Stdlib_Int[12], width)); + } + function bprint_padding(buf, pad){ + if(typeof pad === "number") return; + if(0 === pad[0]){ + var n = pad[2], padty = pad[1]; + bprint_padty(buf, padty); + return buffer_add_string(buf, caml_call1(Stdlib_Int[12], n)); + } + var padty$0 = pad[1]; + bprint_padty(buf, padty$0); + return buffer_add_char(buf, 42); + } + function bprint_precision(buf, prec){ + if(typeof prec !== "number"){ + var n = prec[1]; + buffer_add_char(buf, 46); + return buffer_add_string(buf, caml_call1(Stdlib_Int[12], n)); + } + if(prec) return buffer_add_string(buf, cst); + return; + } + function bprint_iconv_flag(buf, iconv){ + switch(iconv){ + case 1: + case 4: + return buffer_add_char(buf, 43); + case 2: + case 5: + return buffer_add_char(buf, 32); + case 7: + case 9: + case 11: + case 13: + case 14: + case 15: + return buffer_add_char(buf, 35); + default: return; + } + } + function bprint_altint_fmt(buf, ign_flag, iconv, pad, prec, c){ + buffer_add_char(buf, 37); + bprint_ignored_flag(buf, ign_flag); + bprint_iconv_flag(buf, iconv); + bprint_padding(buf, pad); + bprint_precision(buf, prec); + buffer_add_char(buf, c); + return buffer_add_char(buf, char_of_iconv(iconv)); + } + function bprint_fconv_flag(buf, fconv){ + switch(fconv[1]){ + case 0: break; + case 1: + buffer_add_char(buf, 43); break; + default: buffer_add_char(buf, 32); + } + if(8 <= fconv[2]) return buffer_add_char(buf, 35); + return; + } + function string_of_formatting_lit(formatting_lit){ + if(typeof formatting_lit === "number") + switch(formatting_lit){ + case 0: + return cst$0; + case 1: + return cst$1; + case 2: + return cst$2; + case 3: + return cst$3; + case 4: + return cst$4; + case 5: + return cst$5; + default: return cst$6; + } + switch(formatting_lit[0]){ + case 0: + var str = formatting_lit[1]; return str; + case 1: + var str$0 = formatting_lit[1]; return str$0; + default: + var c = formatting_lit[1], _cQ_ = caml_call2(Stdlib_String[1], 1, c); + return caml_call2(Stdlib[28], cst$7, _cQ_); + } + } + function bprint_char_literal(buf, chr){ + return 37 === chr + ? buffer_add_string(buf, cst$8) + : buffer_add_char(buf, chr); + } + function bprint_string_literal(buf, str){ + var _cO_ = caml_ml_string_length(str) - 1 | 0, _cN_ = 0; + if(_cO_ >= 0){ + var i = _cN_; + for(;;){ + bprint_char_literal(buf, caml_string_get(str, i)); + var _cP_ = i + 1 | 0; + if(_cO_ === i) break; + i = _cP_; + } + } + return; + } + function bprint_fmtty(buf, fmtty){ + var fmtty$0 = fmtty; + for(;;){ + if(typeof fmtty$0 === "number") return; + switch(fmtty$0[0]){ + case 0: + var fmtty$1 = fmtty$0[1]; + buffer_add_string(buf, cst_c); + fmtty$0 = fmtty$1; + break; + case 1: + var fmtty$2 = fmtty$0[1]; + buffer_add_string(buf, cst_s); + fmtty$0 = fmtty$2; + break; + case 2: + var fmtty$3 = fmtty$0[1]; + buffer_add_string(buf, cst_i); + fmtty$0 = fmtty$3; + break; + case 3: + var fmtty$4 = fmtty$0[1]; + buffer_add_string(buf, cst_li); + fmtty$0 = fmtty$4; + break; + case 4: + var fmtty$5 = fmtty$0[1]; + buffer_add_string(buf, cst_ni); + fmtty$0 = fmtty$5; + break; + case 5: + var fmtty$6 = fmtty$0[1]; + buffer_add_string(buf, cst_Li); + fmtty$0 = fmtty$6; + break; + case 6: + var fmtty$7 = fmtty$0[1]; + buffer_add_string(buf, cst_f); + fmtty$0 = fmtty$7; + break; + case 7: + var fmtty$8 = fmtty$0[1]; + buffer_add_string(buf, cst_B); + fmtty$0 = fmtty$8; + break; + case 8: + var fmtty$9 = fmtty$0[2], sub_fmtty = fmtty$0[1]; + buffer_add_string(buf, cst$9); + bprint_fmtty(buf, sub_fmtty); + buffer_add_string(buf, cst$10); + fmtty$0 = fmtty$9; + break; + case 9: + var fmtty$10 = fmtty$0[3], sub_fmtty$0 = fmtty$0[1]; + buffer_add_string(buf, cst$11); + bprint_fmtty(buf, sub_fmtty$0); + buffer_add_string(buf, cst$12); + fmtty$0 = fmtty$10; + break; + case 10: + var fmtty$11 = fmtty$0[1]; + buffer_add_string(buf, cst_a); + fmtty$0 = fmtty$11; + break; + case 11: + var fmtty$12 = fmtty$0[1]; + buffer_add_string(buf, cst_t); + fmtty$0 = fmtty$12; + break; + case 12: + var fmtty$13 = fmtty$0[1]; + buffer_add_string(buf, cst$13); + fmtty$0 = fmtty$13; + break; + case 13: + var fmtty$14 = fmtty$0[1]; + buffer_add_string(buf, cst_r); + fmtty$0 = fmtty$14; + break; + default: + var fmtty$15 = fmtty$0[1]; + buffer_add_string(buf, cst_r$0); + fmtty$0 = fmtty$15; + } + } + } + function int_of_custom_arity(param){ + if(! param) return 0; + var x = param[1]; + return 1 + int_of_custom_arity(x) | 0; + } + function string_of_fmt(fmt){ + var buf = buffer_create(16); + function fmtiter(fmt, ign_flag){ + var fmt$0 = fmt, ign_flag$0 = ign_flag; + for(;;){ + if(typeof fmt$0 === "number") return; + switch(fmt$0[0]){ + case 0: + var rest = fmt$0[1]; + buffer_add_char(buf, 37); + bprint_ignored_flag(buf, ign_flag$0); + buffer_add_char(buf, 99); + fmt$0 = rest; + ign_flag$0 = 0; + break; + case 1: + var rest$0 = fmt$0[1]; + buffer_add_char(buf, 37); + bprint_ignored_flag(buf, ign_flag$0); + buffer_add_char(buf, 67); + fmt$0 = rest$0; + ign_flag$0 = 0; + break; + case 2: + var rest$1 = fmt$0[2], pad = fmt$0[1]; + buffer_add_char(buf, 37); + bprint_ignored_flag(buf, ign_flag$0); + bprint_padding(buf, pad); + buffer_add_char(buf, 115); + fmt$0 = rest$1; + ign_flag$0 = 0; + break; + case 3: + var rest$2 = fmt$0[2], pad$0 = fmt$0[1]; + buffer_add_char(buf, 37); + bprint_ignored_flag(buf, ign_flag$0); + bprint_padding(buf, pad$0); + buffer_add_char(buf, 83); + fmt$0 = rest$2; + ign_flag$0 = 0; + break; + case 4: + var + rest$3 = fmt$0[4], + prec = fmt$0[3], + pad$1 = fmt$0[2], + iconv = fmt$0[1]; + buffer_add_char(buf, 37); + bprint_ignored_flag(buf, ign_flag$0); + bprint_iconv_flag(buf, iconv); + bprint_padding(buf, pad$1); + bprint_precision(buf, prec); + buffer_add_char(buf, char_of_iconv(iconv)); + fmt$0 = rest$3; + ign_flag$0 = 0; + break; + case 5: + var + rest$4 = fmt$0[4], + prec$0 = fmt$0[3], + pad$2 = fmt$0[2], + iconv$0 = fmt$0[1]; + bprint_altint_fmt(buf, ign_flag$0, iconv$0, pad$2, prec$0, 108); + fmt$0 = rest$4; + ign_flag$0 = 0; + break; + case 6: + var + rest$5 = fmt$0[4], + prec$1 = fmt$0[3], + pad$3 = fmt$0[2], + iconv$1 = fmt$0[1]; + bprint_altint_fmt(buf, ign_flag$0, iconv$1, pad$3, prec$1, 110); + fmt$0 = rest$5; + ign_flag$0 = 0; + break; + case 7: + var + rest$6 = fmt$0[4], + prec$2 = fmt$0[3], + pad$4 = fmt$0[2], + iconv$2 = fmt$0[1]; + bprint_altint_fmt(buf, ign_flag$0, iconv$2, pad$4, prec$2, 76); + fmt$0 = rest$6; + ign_flag$0 = 0; + break; + case 8: + var + rest$7 = fmt$0[4], + prec$3 = fmt$0[3], + pad$5 = fmt$0[2], + fconv = fmt$0[1]; + buffer_add_char(buf, 37); + bprint_ignored_flag(buf, ign_flag$0); + bprint_fconv_flag(buf, fconv); + bprint_padding(buf, pad$5); + bprint_precision(buf, prec$3); + buffer_add_char(buf, char_of_fconv(0, fconv)); + fmt$0 = rest$7; + ign_flag$0 = 0; + break; + case 9: + var rest$8 = fmt$0[2], pad$6 = fmt$0[1]; + buffer_add_char(buf, 37); + bprint_ignored_flag(buf, ign_flag$0); + bprint_padding(buf, pad$6); + buffer_add_char(buf, 66); + fmt$0 = rest$8; + ign_flag$0 = 0; + break; + case 10: + var rest$9 = fmt$0[1]; + buffer_add_string(buf, cst$14); + fmt$0 = rest$9; + break; + case 11: + var rest$10 = fmt$0[2], str = fmt$0[1]; + bprint_string_literal(buf, str); + fmt$0 = rest$10; + break; + case 12: + var rest$11 = fmt$0[2], chr = fmt$0[1]; + bprint_char_literal(buf, chr); + fmt$0 = rest$11; + break; + case 13: + var rest$12 = fmt$0[3], fmtty = fmt$0[2], pad_opt = fmt$0[1]; + buffer_add_char(buf, 37); + bprint_ignored_flag(buf, ign_flag$0); + bprint_pad_opt(buf, pad_opt); + buffer_add_char(buf, 123); + bprint_fmtty(buf, fmtty); + buffer_add_char(buf, 37); + buffer_add_char(buf, 125); + fmt$0 = rest$12; + ign_flag$0 = 0; + break; + case 14: + var rest$13 = fmt$0[3], fmtty$0 = fmt$0[2], pad_opt$0 = fmt$0[1]; + buffer_add_char(buf, 37); + bprint_ignored_flag(buf, ign_flag$0); + bprint_pad_opt(buf, pad_opt$0); + buffer_add_char(buf, 40); + bprint_fmtty(buf, fmtty$0); + buffer_add_char(buf, 37); + buffer_add_char(buf, 41); + fmt$0 = rest$13; + ign_flag$0 = 0; + break; + case 15: + var rest$14 = fmt$0[1]; + buffer_add_char(buf, 37); + bprint_ignored_flag(buf, ign_flag$0); + buffer_add_char(buf, 97); + fmt$0 = rest$14; + ign_flag$0 = 0; + break; + case 16: + var rest$15 = fmt$0[1]; + buffer_add_char(buf, 37); + bprint_ignored_flag(buf, ign_flag$0); + buffer_add_char(buf, 116); + fmt$0 = rest$15; + ign_flag$0 = 0; + break; + case 17: + var rest$16 = fmt$0[2], fmting_lit = fmt$0[1]; + bprint_string_literal(buf, string_of_formatting_lit(fmting_lit)); + fmt$0 = rest$16; + break; + case 18: + var rest$17 = fmt$0[2], fmting_gen = fmt$0[1]; + if(0 === fmting_gen[0]){ + var str$0 = fmting_gen[1][2]; + buffer_add_string(buf, cst$15); + buffer_add_string(buf, str$0); + } + else{ + var str$1 = fmting_gen[1][2]; + buffer_add_string(buf, cst$16); + buffer_add_string(buf, str$1); + } + fmt$0 = rest$17; + break; + case 19: + var rest$18 = fmt$0[1]; + buffer_add_char(buf, 37); + bprint_ignored_flag(buf, ign_flag$0); + buffer_add_char(buf, 114); + fmt$0 = rest$18; + ign_flag$0 = 0; + break; + case 20: + var rest$19 = fmt$0[3], char_set = fmt$0[2], width_opt = fmt$0[1]; + buffer_add_char(buf, 37); + bprint_ignored_flag(buf, ign_flag$0); + bprint_pad_opt(buf, width_opt); + var + print_char = + function(buf, i){ + var c = caml_call1(Stdlib[29], i); + return 37 === c + ? (buffer_add_char(buf, 37), buffer_add_char(buf, 37)) + : 64 + === c + ? (buffer_add_char(buf, 37), buffer_add_char(buf, 64)) + : buffer_add_char(buf, c); + }; + buffer_add_char(buf, 91); + var + set = + is_in_char_set(char_set, 0) + ? (buffer_add_char(buf, 94), rev_char_set(char_set)) + : char_set; + let set$0 = set; + var + is_alone = + function(c){ + var + after = caml_call1(Stdlib_Char[1], c + 1 | 0), + before = caml_call1(Stdlib_Char[1], c - 1 | 0), + _cJ_ = is_in_char_set(set$0, c); + if(_cJ_) + var + _cK_ = is_in_char_set(set$0, before), + _cL_ = _cK_ ? is_in_char_set(set$0, after) : _cK_, + _cM_ = 1 - _cL_; + else + var _cM_ = _cJ_; + return _cM_; + }; + if(is_alone(93)) buffer_add_char(buf, 93); + a: + b: + { + c: + { + d: + { + var i = 1; + for(;;){ + if(i >= 256) break; + if(is_in_char_set(set, caml_call1(Stdlib[29], i))){ + var switcher = caml_call1(Stdlib[29], i) - 45 | 0; + if(48 < switcher >>> 0){ + if(210 <= switcher) break d; + } + else if(46 < switcher - 1 >>> 0){ + var i$2 = i + 1 | 0; + i = i$2; + continue; + } + var i$1 = i + 1 | 0; + if(is_in_char_set(set, caml_call1(Stdlib[29], i$1))){ + var switcher$0 = caml_call1(Stdlib[29], i$1) - 45 | 0; + if(48 < switcher$0 >>> 0){ + if(210 <= switcher$0) break c; + } + else if + (46 < switcher$0 - 1 >>> 0 + && ! is_in_char_set(set, caml_call1(Stdlib[29], i$1 + 1 | 0))){ + print_char(buf, i$1 - 1 | 0); + var i$5 = i$1 + 1 | 0; + i = i$5; + continue; + } + if(is_in_char_set(set, caml_call1(Stdlib[29], i$1 + 1 | 0))){ + var j = i$1 + 2 | 0, i$3 = i$1 - 1 | 0, j$0 = j; + for(;;){ + if(256 === j$0) break; + if(! is_in_char_set(set, caml_call1(Stdlib[29], j$0))) break; + var j$1 = j$0 + 1 | 0; + j$0 = j$1; + } + print_char(buf, i$3); + print_char(buf, 45); + print_char(buf, j$0 - 1 | 0); + if(j$0 >= 256) break b; + var i$7 = j$0 + 1 | 0; + i = i$7; + } + else{ + print_char(buf, i$1 - 1 | 0); + print_char(buf, i$1); + var i$4 = i$1 + 2 | 0; + i = i$4; + } + } + else{ + print_char(buf, i$1 - 1 | 0); + var i$6 = i$1 + 1 | 0; + i = i$6; + } + } + else{var i$0 = i + 1 | 0; i = i$0;} + } + break a; + } + print_char(buf, 255); + break a; + } + print_char(buf, 254); + print_char(buf, 255); + break a; + } + if(is_alone(45)) buffer_add_char(buf, 45); + buffer_add_char(buf, 93); + fmt$0 = rest$19; + ign_flag$0 = 0; + break; + case 21: + var rest$20 = fmt$0[2], counter = fmt$0[1]; + buffer_add_char(buf, 37); + bprint_ignored_flag(buf, ign_flag$0); + switch(counter){ + case 0: + var _cF_ = 108; break; + case 1: + var _cF_ = 110; break; + default: var _cF_ = 78; + } + buffer_add_char(buf, _cF_); + fmt$0 = rest$20; + ign_flag$0 = 0; + break; + case 22: + var rest$21 = fmt$0[1]; + buffer_add_char(buf, 37); + bprint_ignored_flag(buf, ign_flag$0); + bprint_string_literal(buf, cst_0c); + fmt$0 = rest$21; + ign_flag$0 = 0; + break; + case 23: + var + rest$22 = fmt$0[2], + ign = fmt$0[1], + fmt$1 = param_format_of_ignored_format(ign, rest$22)[1]; + fmt$0 = fmt$1; + ign_flag$0 = 1; + break; + default: + var + rest$23 = fmt$0[3], + arity = fmt$0[1], + _cH_ = int_of_custom_arity(arity), + _cG_ = 1; + if(_cH_ >= 1){ + var i$8 = _cG_; + for(;;){ + buffer_add_char(buf, 37); + bprint_ignored_flag(buf, ign_flag$0); + buffer_add_char(buf, 63); + var _cI_ = i$8 + 1 | 0; + if(_cH_ === i$8) break; + i$8 = _cI_; + } + } + fmt$0 = rest$23; + ign_flag$0 = 0; + } + } + } + fmtiter(fmt, 0); + return buffer_contents(buf); + } + function symm(param){ + if(typeof param === "number") return 0; + switch(param[0]){ + case 0: + var rest = param[1]; return [0, symm(rest)]; + case 1: + var rest$0 = param[1]; return [1, symm(rest$0)]; + case 2: + var rest$1 = param[1]; return [2, symm(rest$1)]; + case 3: + var rest$2 = param[1]; return [3, symm(rest$2)]; + case 4: + var rest$3 = param[1]; return [4, symm(rest$3)]; + case 5: + var rest$4 = param[1]; return [5, symm(rest$4)]; + case 6: + var rest$5 = param[1]; return [6, symm(rest$5)]; + case 7: + var rest$6 = param[1]; return [7, symm(rest$6)]; + case 8: + var rest$7 = param[2], ty = param[1]; return [8, ty, symm(rest$7)]; + case 9: + var rest$8 = param[3], ty2 = param[2], ty1 = param[1]; + return [9, ty2, ty1, symm(rest$8)]; + case 10: + var rest$9 = param[1]; return [10, symm(rest$9)]; + case 11: + var rest$10 = param[1]; return [11, symm(rest$10)]; + case 12: + var rest$11 = param[1]; return [12, symm(rest$11)]; + case 13: + var rest$12 = param[1]; return [13, symm(rest$12)]; + default: var rest$13 = param[1]; return [14, symm(rest$13)]; + } + } + function fmtty_rel_det(param){ + if(typeof param === "number") + return [0, + function(param){return;}, + function(param){return;}, + function(param){return;}, + function(param){return;}]; + switch(param[0]){ + case 0: + var + rest = param[1], + match = fmtty_rel_det(rest), + de = match[4], + ed = match[3], + af = match[2], + fa = match[1]; + return [0, + function(param){fa(0); return;}, + function(param){af(0); return;}, + ed, + de]; + case 1: + var + rest$0 = param[1], + match$0 = fmtty_rel_det(rest$0), + de$0 = match$0[4], + ed$0 = match$0[3], + af$0 = match$0[2], + fa$0 = match$0[1]; + return [0, + function(param){fa$0(0); return;}, + function(param){af$0(0); return;}, + ed$0, + de$0]; + case 2: + var + rest$1 = param[1], + match$1 = fmtty_rel_det(rest$1), + de$1 = match$1[4], + ed$1 = match$1[3], + af$1 = match$1[2], + fa$1 = match$1[1]; + return [0, + function(param){fa$1(0); return;}, + function(param){af$1(0); return;}, + ed$1, + de$1]; + case 3: + var + rest$2 = param[1], + match$2 = fmtty_rel_det(rest$2), + de$2 = match$2[4], + ed$2 = match$2[3], + af$2 = match$2[2], + fa$2 = match$2[1]; + return [0, + function(param){fa$2(0); return;}, + function(param){af$2(0); return;}, + ed$2, + de$2]; + case 4: + var + rest$3 = param[1], + match$3 = fmtty_rel_det(rest$3), + de$3 = match$3[4], + ed$3 = match$3[3], + af$3 = match$3[2], + fa$3 = match$3[1]; + return [0, + function(param){fa$3(0); return;}, + function(param){af$3(0); return;}, + ed$3, + de$3]; + case 5: + var + rest$4 = param[1], + match$4 = fmtty_rel_det(rest$4), + de$4 = match$4[4], + ed$4 = match$4[3], + af$4 = match$4[2], + fa$4 = match$4[1]; + return [0, + function(param){fa$4(0); return;}, + function(param){af$4(0); return;}, + ed$4, + de$4]; + case 6: + var + rest$5 = param[1], + match$5 = fmtty_rel_det(rest$5), + de$5 = match$5[4], + ed$5 = match$5[3], + af$5 = match$5[2], + fa$5 = match$5[1]; + return [0, + function(param){fa$5(0); return;}, + function(param){af$5(0); return;}, + ed$5, + de$5]; + case 7: + var + rest$6 = param[1], + match$6 = fmtty_rel_det(rest$6), + de$6 = match$6[4], + ed$6 = match$6[3], + af$6 = match$6[2], + fa$6 = match$6[1]; + return [0, + function(param){fa$6(0); return;}, + function(param){af$6(0); return;}, + ed$6, + de$6]; + case 8: + var + rest$7 = param[2], + match$7 = fmtty_rel_det(rest$7), + de$7 = match$7[4], + ed$7 = match$7[3], + af$7 = match$7[2], + fa$7 = match$7[1]; + return [0, + function(param){fa$7(0); return;}, + function(param){af$7(0); return;}, + ed$7, + de$7]; + case 9: + var + rest$8 = param[3], + ty2 = param[2], + ty1 = param[1], + match$8 = fmtty_rel_det(rest$8), + de$8 = match$8[4], + ed$8 = match$8[3], + af$8 = match$8[2], + fa$8 = match$8[1], + ty = trans(symm(ty1), ty2), + match$9 = fmtty_rel_det(ty), + jd = match$9[4], + dj = match$9[3], + ga = match$9[2], + ag = match$9[1]; + return [0, + function(param){fa$8(0); ag(0); return;}, + function(param){ga(0); af$8(0); return;}, + function(param){ed$8(0); dj(0); return;}, + function(param){jd(0); de$8(0); return;}]; + case 10: + var + rest$9 = param[1], + match$10 = fmtty_rel_det(rest$9), + de$9 = match$10[4], + ed$9 = match$10[3], + af$9 = match$10[2], + fa$9 = match$10[1]; + return [0, + function(param){fa$9(0); return;}, + function(param){af$9(0); return;}, + ed$9, + de$9]; + case 11: + var + rest$10 = param[1], + match$11 = fmtty_rel_det(rest$10), + de$10 = match$11[4], + ed$10 = match$11[3], + af$10 = match$11[2], + fa$10 = match$11[1]; + return [0, + function(param){fa$10(0); return;}, + function(param){af$10(0); return;}, + ed$10, + de$10]; + case 12: + var + rest$11 = param[1], + match$12 = fmtty_rel_det(rest$11), + de$11 = match$12[4], + ed$11 = match$12[3], + af$11 = match$12[2], + fa$11 = match$12[1]; + return [0, + function(param){fa$11(0); return;}, + function(param){af$11(0); return;}, + ed$11, + de$11]; + case 13: + var + rest$12 = param[1], + match$13 = fmtty_rel_det(rest$12), + de$12 = match$13[4], + ed$12 = match$13[3], + af$12 = match$13[2], + fa$12 = match$13[1]; + return [0, + function(param){fa$12(0); return;}, + function(param){af$12(0); return;}, + function(param){ed$12(0); return;}, + function(param){de$12(0); return;}]; + default: + var + rest$13 = param[1], + match$14 = fmtty_rel_det(rest$13), + de$13 = match$14[4], + ed$13 = match$14[3], + af$13 = match$14[2], + fa$13 = match$14[1]; + return [0, + function(param){fa$13(0); return;}, + function(param){af$13(0); return;}, + function(param){ed$13(0); return;}, + function(param){de$13(0); return;}]; + } + } + function trans(ty1, ty2){ + a: + { + b: + { + c: + { + d: + { + e: + { + f: + { + g: + { + if(typeof ty1 !== "number"){ + switch(ty1[0]){ + case 0: + var rest1 = ty1[1]; + if(typeof ty2 !== "number") + switch(ty2[0]){ + case 0: + var rest2 = ty2[1]; return [0, trans(rest1, rest2)]; + case 8: + break f; + case 9: + break g; + case 10: + break a; + case 11: + break b; + case 12: + break c; + case 13: + break d; + case 14: + break e; + } + break; + case 1: + var rest1$0 = ty1[1]; + if(typeof ty2 !== "number") + switch(ty2[0]){ + case 1: + var rest2$0 = ty2[1]; return [1, trans(rest1$0, rest2$0)]; + case 8: + break f; + case 9: + break g; + case 10: + break a; + case 11: + break b; + case 12: + break c; + case 13: + break d; + case 14: + break e; + } + break; + case 2: + var rest1$1 = ty1[1]; + if(typeof ty2 !== "number") + switch(ty2[0]){ + case 2: + var rest2$1 = ty2[1]; return [2, trans(rest1$1, rest2$1)]; + case 8: + break f; + case 9: + break g; + case 10: + break a; + case 11: + break b; + case 12: + break c; + case 13: + break d; + case 14: + break e; + } + break; + case 3: + var rest1$2 = ty1[1]; + if(typeof ty2 !== "number") + switch(ty2[0]){ + case 3: + var rest2$2 = ty2[1]; return [3, trans(rest1$2, rest2$2)]; + case 8: + break f; + case 9: + break g; + case 10: + break a; + case 11: + break b; + case 12: + break c; + case 13: + break d; + case 14: + break e; + } + break; + case 4: + var rest1$3 = ty1[1]; + if(typeof ty2 !== "number") + switch(ty2[0]){ + case 4: + var rest2$3 = ty2[1]; return [4, trans(rest1$3, rest2$3)]; + case 8: + break f; + case 9: + break g; + case 10: + break a; + case 11: + break b; + case 12: + break c; + case 13: + break d; + case 14: + break e; + } + break; + case 5: + var rest1$4 = ty1[1]; + if(typeof ty2 !== "number") + switch(ty2[0]){ + case 5: + var rest2$4 = ty2[1]; return [5, trans(rest1$4, rest2$4)]; + case 8: + break f; + case 9: + break g; + case 10: + break a; + case 11: + break b; + case 12: + break c; + case 13: + break d; + case 14: + break e; + } + break; + case 6: + var rest1$5 = ty1[1]; + if(typeof ty2 !== "number") + switch(ty2[0]){ + case 6: + var rest2$5 = ty2[1]; return [6, trans(rest1$5, rest2$5)]; + case 8: + break f; + case 9: + break g; + case 10: + break a; + case 11: + break b; + case 12: + break c; + case 13: + break d; + case 14: + break e; + } + break; + case 7: + var rest1$6 = ty1[1]; + if(typeof ty2 !== "number") + switch(ty2[0]){ + case 7: + var rest2$6 = ty2[1]; return [7, trans(rest1$6, rest2$6)]; + case 8: + break f; + case 9: + break g; + case 10: + break a; + case 11: + break b; + case 12: + break c; + case 13: + break d; + case 14: + break e; + } + break; + case 8: + var rest1$7 = ty1[2], ty1$0 = ty1[1]; + if(typeof ty2 !== "number") + switch(ty2[0]){ + case 8: + var + rest2$7 = ty2[2], + ty2$0 = ty2[1], + _cE_ = trans(rest1$7, rest2$7); + return [8, trans(ty1$0, ty2$0), _cE_]; + case 10: + break a; + case 11: + break b; + case 12: + break c; + case 13: + break d; + case 14: + break e; + } + throw caml_maybe_attach_backtrace([0, Assert_failure, _k_], 1); + case 9: + var rest1$8 = ty1[3], ty12 = ty1[2], ty11 = ty1[1]; + if(typeof ty2 !== "number") + switch(ty2[0]){ + case 8: + break f; + case 9: + var + rest2$8 = ty2[3], + ty22 = ty2[2], + ty21 = ty2[1], + ty = trans(symm(ty12), ty21), + match = fmtty_rel_det(ty), + f4 = match[4], + f2 = match[2]; + f2(0); + f4(0); + return [9, ty11, ty22, trans(rest1$8, rest2$8)]; + case 10: + break a; + case 11: + break b; + case 12: + break c; + case 13: + break d; + case 14: + break e; + } + throw caml_maybe_attach_backtrace([0, Assert_failure, _l_], 1); + case 10: + var rest1$9 = ty1[1]; + if(typeof ty2 !== "number" && 10 === ty2[0]){ + var rest2$9 = ty2[1]; + return [10, trans(rest1$9, rest2$9)]; + } + throw caml_maybe_attach_backtrace([0, Assert_failure, _m_], 1); + case 11: + var rest1$10 = ty1[1]; + if(typeof ty2 !== "number") + switch(ty2[0]){ + case 10: + break a; + case 11: + var rest2$10 = ty2[1]; + return [11, trans(rest1$10, rest2$10)]; + } + throw caml_maybe_attach_backtrace([0, Assert_failure, _n_], 1); + case 12: + var rest1$11 = ty1[1]; + if(typeof ty2 !== "number") + switch(ty2[0]){ + case 10: + break a; + case 11: + break b; + case 12: + var rest2$11 = ty2[1]; + return [12, trans(rest1$11, rest2$11)]; + } + throw caml_maybe_attach_backtrace([0, Assert_failure, _o_], 1); + case 13: + var rest1$12 = ty1[1]; + if(typeof ty2 !== "number") + switch(ty2[0]){ + case 10: + break a; + case 11: + break b; + case 12: + break c; + case 13: + var rest2$12 = ty2[1]; + return [13, trans(rest1$12, rest2$12)]; + } + throw caml_maybe_attach_backtrace([0, Assert_failure, _p_], 1); + default: + var rest1$13 = ty1[1]; + if(typeof ty2 !== "number") + switch(ty2[0]){ + case 10: + break a; + case 11: + break b; + case 12: + break c; + case 13: + break d; + case 14: + var rest2$13 = ty2[1]; + return [14, trans(rest1$13, rest2$13)]; + } + throw caml_maybe_attach_backtrace([0, Assert_failure, _q_], 1); + } + throw caml_maybe_attach_backtrace([0, Assert_failure, _j_], 1); + } + if(typeof ty2 === "number") return 0; + switch(ty2[0]){ + case 10: + break a; + case 11: + break b; + case 12: + break c; + case 13: + break d; + case 14: + break e; + case 8: + break f; + case 9: break; + default: + throw caml_maybe_attach_backtrace([0, Assert_failure, _b_], 1); + } + } + throw caml_maybe_attach_backtrace([0, Assert_failure, _d_], 1); + } + throw caml_maybe_attach_backtrace([0, Assert_failure, _c_], 1); + } + throw caml_maybe_attach_backtrace([0, Assert_failure, _i_], 1); + } + throw caml_maybe_attach_backtrace([0, Assert_failure, _h_], 1); + } + throw caml_maybe_attach_backtrace([0, Assert_failure, _g_], 1); + } + throw caml_maybe_attach_backtrace([0, Assert_failure, _f_], 1); + } + throw caml_maybe_attach_backtrace([0, Assert_failure, _e_], 1); + } + function fmtty_of_fmt(fmtty){ + var fmtty$0 = fmtty; + for(;;){ + if(typeof fmtty$0 === "number") return 0; + switch(fmtty$0[0]){ + case 0: + var rest = fmtty$0[1]; return [0, fmtty_of_fmt(rest)]; + case 1: + var rest$0 = fmtty$0[1]; return [0, fmtty_of_fmt(rest$0)]; + case 2: + var rest$1 = fmtty$0[2], pad = fmtty$0[1]; + return fmtty_of_padding_fmtty(pad, [1, fmtty_of_fmt(rest$1)]); + case 3: + var rest$2 = fmtty$0[2], pad$0 = fmtty$0[1]; + return fmtty_of_padding_fmtty(pad$0, [1, fmtty_of_fmt(rest$2)]); + case 4: + var + rest$3 = fmtty$0[4], + prec = fmtty$0[3], + pad$1 = fmtty$0[2], + ty_rest = fmtty_of_fmt(rest$3), + prec_ty = fmtty_of_precision_fmtty(prec, [2, ty_rest]); + return fmtty_of_padding_fmtty(pad$1, prec_ty); + case 5: + var + rest$4 = fmtty$0[4], + prec$0 = fmtty$0[3], + pad$2 = fmtty$0[2], + ty_rest$0 = fmtty_of_fmt(rest$4), + prec_ty$0 = fmtty_of_precision_fmtty(prec$0, [3, ty_rest$0]); + return fmtty_of_padding_fmtty(pad$2, prec_ty$0); + case 6: + var + rest$5 = fmtty$0[4], + prec$1 = fmtty$0[3], + pad$3 = fmtty$0[2], + ty_rest$1 = fmtty_of_fmt(rest$5), + prec_ty$1 = fmtty_of_precision_fmtty(prec$1, [4, ty_rest$1]); + return fmtty_of_padding_fmtty(pad$3, prec_ty$1); + case 7: + var + rest$6 = fmtty$0[4], + prec$2 = fmtty$0[3], + pad$4 = fmtty$0[2], + ty_rest$2 = fmtty_of_fmt(rest$6), + prec_ty$2 = fmtty_of_precision_fmtty(prec$2, [5, ty_rest$2]); + return fmtty_of_padding_fmtty(pad$4, prec_ty$2); + case 8: + var + rest$7 = fmtty$0[4], + prec$3 = fmtty$0[3], + pad$5 = fmtty$0[2], + ty_rest$3 = fmtty_of_fmt(rest$7), + prec_ty$3 = fmtty_of_precision_fmtty(prec$3, [6, ty_rest$3]); + return fmtty_of_padding_fmtty(pad$5, prec_ty$3); + case 9: + var rest$8 = fmtty$0[2], pad$6 = fmtty$0[1]; + return fmtty_of_padding_fmtty(pad$6, [7, fmtty_of_fmt(rest$8)]); + case 10: + var fmtty$1 = fmtty$0[1]; fmtty$0 = fmtty$1; break; + case 11: + var fmtty$2 = fmtty$0[2]; fmtty$0 = fmtty$2; break; + case 12: + var fmtty$3 = fmtty$0[2]; fmtty$0 = fmtty$3; break; + case 13: + var rest$9 = fmtty$0[3], ty = fmtty$0[2]; + return [8, ty, fmtty_of_fmt(rest$9)]; + case 14: + var rest$10 = fmtty$0[3], ty$0 = fmtty$0[2]; + return [9, ty$0, ty$0, fmtty_of_fmt(rest$10)]; + case 15: + var rest$11 = fmtty$0[1]; return [10, fmtty_of_fmt(rest$11)]; + case 16: + var rest$12 = fmtty$0[1]; return [11, fmtty_of_fmt(rest$12)]; + case 17: + var fmtty$4 = fmtty$0[2]; fmtty$0 = fmtty$4; break; + case 18: + var + rest$13 = fmtty$0[2], + formatting_gen = fmtty$0[1], + _cB_ = fmtty_of_fmt(rest$13); + if(0 === formatting_gen[0]) + var fmt = formatting_gen[1][1], _cC_ = fmtty_of_fmt(fmt); + else + var fmt$0 = formatting_gen[1][1], _cC_ = fmtty_of_fmt(fmt$0); + return caml_call2(CamlinternalFormatBasics[1], _cC_, _cB_); + case 19: + var rest$14 = fmtty$0[1]; return [13, fmtty_of_fmt(rest$14)]; + case 20: + var rest$15 = fmtty$0[3]; return [1, fmtty_of_fmt(rest$15)]; + case 21: + var rest$16 = fmtty$0[2]; return [2, fmtty_of_fmt(rest$16)]; + case 22: + var rest$17 = fmtty$0[1]; return [0, fmtty_of_fmt(rest$17)]; + case 23: + var fmtty$5 = fmtty$0[2], ign = fmtty$0[1]; + if(typeof ign === "number") + switch(ign){ + case 0: + fmtty$0 = fmtty$5; break; + case 1: + fmtty$0 = fmtty$5; break; + case 2: + return [14, fmtty_of_fmt(fmtty$5)]; + default: fmtty$0 = fmtty$5; + } + else + switch(ign[0]){ + case 0: + fmtty$0 = fmtty$5; break; + case 1: + fmtty$0 = fmtty$5; break; + case 2: + fmtty$0 = fmtty$5; break; + case 3: + fmtty$0 = fmtty$5; break; + case 4: + fmtty$0 = fmtty$5; break; + case 5: + fmtty$0 = fmtty$5; break; + case 6: + fmtty$0 = fmtty$5; break; + case 7: + fmtty$0 = fmtty$5; break; + case 8: + fmtty$0 = fmtty$5; break; + case 9: + var fmtty$6 = ign[2], _cD_ = fmtty_of_fmt(fmtty$5); + return caml_call2(CamlinternalFormatBasics[1], fmtty$6, _cD_); + case 10: + fmtty$0 = fmtty$5; break; + default: fmtty$0 = fmtty$5; + } + break; + default: + var rest$18 = fmtty$0[3], arity = fmtty$0[1]; + return fmtty_of_custom(arity, fmtty_of_fmt(rest$18)); + } + } + } + function fmtty_of_custom(arity, fmtty){ + if(! arity) return fmtty; + var arity$0 = arity[1]; + return [12, fmtty_of_custom(arity$0, fmtty)]; + } + function fmtty_of_padding_fmtty(pad, fmtty){ + return typeof pad === "number" ? fmtty : 0 === pad[0] ? fmtty : [2, fmtty]; + } + function fmtty_of_precision_fmtty(prec, fmtty){ + return typeof prec === "number" ? prec ? [2, fmtty] : fmtty : fmtty; + } + var + Type_mismatch = + [248, "CamlinternalFormat.Type_mismatch", runtime.caml_fresh_oo_id(0)], + cst_d = "%d", + cst_d$0 = "%+d", + cst_d$1 = "% d", + cst_i$0 = cst_i$3, + cst_i$1 = "%+i", + cst_i$2 = "% i", + cst_x = "%x", + cst_x$0 = "%#x", + cst_X = "%X", + cst_X$0 = "%#X", + cst_o = "%o", + cst_o$0 = "%#o", + cst_u = cst_u$0, + cst_Ld = "%Ld", + cst_Ld$0 = "%+Ld", + cst_Ld$1 = "% Ld", + cst_Li$0 = cst_Li$3, + cst_Li$1 = "%+Li", + cst_Li$2 = "% Li", + cst_Lx = "%Lx", + cst_Lx$0 = "%#Lx", + cst_LX = "%LX", + cst_LX$0 = "%#LX", + cst_Lo = "%Lo", + cst_Lo$0 = "%#Lo", + cst_Lu = "%Lu", + cst_ld = "%ld", + cst_ld$0 = "%+ld", + cst_ld$1 = "% ld", + cst_li$0 = cst_li$3, + cst_li$1 = "%+li", + cst_li$2 = "% li", + cst_lx = "%lx", + cst_lx$0 = "%#lx", + cst_lX = "%lX", + cst_lX$0 = "%#lX", + cst_lo = "%lo", + cst_lo$0 = "%#lo", + cst_lu = "%lu", + cst_nd = "%nd", + cst_nd$0 = "%+nd", + cst_nd$1 = "% nd", + cst_ni$0 = cst_ni$3, + cst_ni$1 = "%+ni", + cst_ni$2 = "% ni", + cst_nx = "%nx", + cst_nx$0 = "%#nx", + cst_nX = "%nX", + cst_nX$0 = "%#nX", + cst_no = "%no", + cst_no$0 = "%#no", + cst_nu = "%nu", + _r_ = [0, 103], + cst_neg_infinity = "neg_infinity", + cst_infinity = "infinity", + cst_nan = "nan", + _s_ = [0, cst_camlinternalFormat_ml, 1558, 4], + cst_Printf_bad_conversion = "Printf: bad conversion %[", + _t_ = [0, cst_camlinternalFormat_ml, 1626, 39], + _u_ = [0, cst_camlinternalFormat_ml, 1649, 31], + _v_ = [0, cst_camlinternalFormat_ml, 1650, 31], + cst_Printf_bad_conversion$0 = "Printf: bad conversion %_", + _w_ = [0, cst_camlinternalFormat_ml, 1830, 8], + _x_ = [0, 0, 4], + _y_ = + [0, + [11, "invalid box description ", [3, 0, 0]], + "invalid box description %S"], + _z_ = + [0, + [11, + cst_invalid_format, + [3, + 0, + [11, cst_at_character_number, [4, 0, 0, 0, [11, cst$44, [2, 0, 0]]]]]], + "invalid format %S: at character number %d, %s"], + cst_non_zero_widths_are_unsupp = + "non-zero widths are unsupported for %c conversions", + _A_ = + [0, + [11, + cst_invalid_format, + [3, + 0, + [11, + cst_at_character_number, + [4, 0, 0, 0, [11, ", '", [0, [11, "' without ", [2, 0, 0]]]]]]]], + "invalid format %S: at character number %d, '%c' without %s"], + _B_ = + [0, + [11, + cst_invalid_format, + [3, + 0, + [11, + cst_at_character_number, + [4, 0, 0, 0, [11, cst$44, [2, 0, [11, " expected, read ", [1, 0]]]]]]]], + "invalid format %S: at character number %d, %s expected, read %C"], + _C_ = + [0, + [11, + cst_invalid_format, + [3, + 0, + [11, + cst_at_character_number, + [4, 0, 0, 0, [11, ", duplicate flag ", [1, 0]]]]]], + "invalid format %S: at character number %d, duplicate flag %C"], + cst_padding = "padding", + _D_ = [0, 1, 0], + cst_0 = cst_0$3, + _E_ = [0, 0], + cst_precision = cst_precision$3, + _F_ = [1, 0], + _G_ = [1, 1], + cst_precision$0 = cst_precision$3, + _H_ = [1, 1], + cst_precision$1 = cst_precision$3, + cst_0$0 = cst_0$3, + _I_ = [1, 1], + cst_0$1 = cst_0$3, + cst_0$2 = "'0'", + _J_ = + [0, + [11, + cst_invalid_format, + [3, + 0, + [11, + cst_at_character_number, + [4, + 0, + 0, + 0, + [11, ', invalid conversion "', [12, 37, [0, [12, 34, 0]]]]]]]], + 'invalid format %S: at character number %d, invalid conversion "%%%c"'], + _K_ = [0, 0], + cst_padding$0 = "`padding'", + _L_ = [0, 0], + cst_precision$2 = "`precision'", + _M_ = + [0, + [11, + cst_invalid_format, + [3, + 0, + [11, + cst_at_character_number, + [4, + 0, + 0, + 0, + [11, + ", flag ", + [1, + [11, + " is only allowed after the '", + [12, 37, [11, "', before padding and precision", 0]]]]]]]]], + "invalid format %S: at character number %d, flag %C is only allowed after the '%%', before padding and precision"], + _N_ = [0, [12, 64, 0]], + _O_ = [0, "@ ", 1, 0], + _P_ = [0, "@,", 0, 0], + _Q_ = [2, 60], + _R_ = + [0, + [11, + cst_invalid_format, + [3, + 0, + [11, + ": '", + [12, + 37, + [11, + "' alone is not accepted in character sets, use ", + [12, + 37, + [12, + 37, + [11, " instead at position ", [4, 0, 0, 0, [12, 46, 0]]]]]]]]]], + "invalid format %S: '%%' alone is not accepted in character sets, use %%%% instead at position %d."], + _S_ = + [0, + [11, + cst_invalid_format, + [3, + 0, + [11, + ": integer ", + [4, 0, 0, 0, [11, " is greater than the limit ", [4, 0, 0, 0, 0]]]]]], + "invalid format %S: integer %d is greater than the limit %d"], + _T_ = [0, cst_camlinternalFormat_ml, 2837, 11], + cst_digit = "digit", + _U_ = + [0, + [11, + cst_invalid_format, + [3, + 0, + [11, + ': unclosed sub-format, expected "', + [12, 37, [0, [11, '" at character number ', [4, 0, 0, 0, 0]]]]]]], + 'invalid format %S: unclosed sub-format, expected "%%%c" at character number %d'], + cst_character = "character ')'", + cst_character$0 = "character '}'", + _V_ = [0, cst_camlinternalFormat_ml, 2899, 34], + _W_ = [0, cst_camlinternalFormat_ml, 2935, 28], + _X_ = [0, cst_camlinternalFormat_ml, 2957, 11], + _Y_ = + [0, + [11, + cst_invalid_format, + [3, + 0, + [11, + cst_at_character_number, + [4, + 0, + 0, + 0, + [11, + cst$44, + [2, + 0, + [11, + " is incompatible with '", + [0, [11, "' in sub-format ", [3, 0, 0]]]]]]]]]], + "invalid format %S: at character number %d, %s is incompatible with '%c' in sub-format %S"], + _Z_ = + [0, + [11, cst_bad_input_format_type_mism, [3, 0, [11, cst_and, [3, 0, 0]]]], + cst_bad_input_format_type_mism$0], + ___ = + [0, + [11, cst_bad_input_format_type_mism, [3, 0, [11, cst_and, [3, 0, 0]]]], + cst_bad_input_format_type_mism$0]; + function type_padding(pad, fmtty){ + if(typeof pad === "number") return [0, 0, fmtty]; + if(0 === pad[0]){ + var w = pad[2], padty = pad[1]; + return [0, [0, padty, w], fmtty]; + } + if(typeof fmtty !== "number" && 2 === fmtty[0]){ + var rest = fmtty[1], padty$0 = pad[1]; + return [0, [1, padty$0], rest]; + } + throw caml_maybe_attach_backtrace(Type_mismatch, 1); + } + function type_padprec(pad, prec, fmtty){ + var match = type_padding(pad, fmtty); + if(typeof prec !== "number"){ + var rest$1 = match[2], pad$2 = match[1], p = prec[1]; + return [0, pad$2, [0, p], rest$1]; + } + if(! prec){ + var rest$0 = match[2], pad$1 = match[1]; + return [0, pad$1, 0, rest$0]; + } + var match$0 = match[2]; + if(typeof match$0 !== "number" && 2 === match$0[0]){ + var rest = match$0[1], pad$0 = match[1]; + return [0, pad$0, 1, rest]; + } + throw caml_maybe_attach_backtrace(Type_mismatch, 1); + } + function type_format(fmt, fmtty){ + var _cA_ = type_format_gen(fmt, fmtty); + if(typeof _cA_[2] !== "number") + throw caml_maybe_attach_backtrace(Type_mismatch, 1); + var fmt$0 = _cA_[1]; + return fmt$0; + } + function type_format_gen(fmt, fmtty0){ + if(typeof fmt === "number") return [0, 0, fmtty0]; + switch(fmt[0]){ + case 0: + if(typeof fmtty0 !== "number" && 0 === fmtty0[0]){ + var + fmtty_rest = fmtty0[1], + fmt_rest = fmt[1], + match = type_format_gen(fmt_rest, fmtty_rest), + fmtty = match[2], + fmt$0 = match[1]; + return [0, [0, fmt$0], fmtty]; + } + break; + case 1: + if(typeof fmtty0 !== "number" && 0 === fmtty0[0]){ + var + fmtty_rest$0 = fmtty0[1], + fmt_rest$0 = fmt[1], + match$0 = type_format_gen(fmt_rest$0, fmtty_rest$0), + fmtty$0 = match$0[2], + fmt$1 = match$0[1]; + return [0, [1, fmt$1], fmtty$0]; + } + break; + case 2: + var + fmt_rest$1 = fmt[2], + pad = fmt[1], + match$1 = type_padding(pad, fmtty0), + pad$0 = match$1[1], + match$2 = match$1[2]; + if(typeof match$2 !== "number" && 1 === match$2[0]){ + var + fmtty_rest$1 = match$2[1], + match$3 = type_format_gen(fmt_rest$1, fmtty_rest$1), + fmtty$1 = match$3[2], + fmt$2 = match$3[1]; + return [0, [2, pad$0, fmt$2], fmtty$1]; + } + throw caml_maybe_attach_backtrace(Type_mismatch, 1); + case 3: + var + fmt_rest$2 = fmt[2], + pad$1 = fmt[1], + match$4 = type_padding(pad$1, fmtty0), + pad$2 = match$4[1], + match$5 = match$4[2]; + if(typeof match$5 !== "number" && 1 === match$5[0]){ + var + fmtty_rest$2 = match$5[1], + match$6 = type_format_gen(fmt_rest$2, fmtty_rest$2), + fmtty$2 = match$6[2], + fmt$3 = match$6[1]; + return [0, [3, pad$2, fmt$3], fmtty$2]; + } + throw caml_maybe_attach_backtrace(Type_mismatch, 1); + case 4: + var + fmt_rest$3 = fmt[4], + prec = fmt[3], + pad$3 = fmt[2], + iconv = fmt[1], + match$7 = type_padprec(pad$3, prec, fmtty0), + pad$4 = match$7[1], + match$8 = match$7[3]; + if(typeof match$8 !== "number" && 2 === match$8[0]){ + var + fmtty_rest$3 = match$8[1], + prec$0 = match$7[2], + match$9 = type_format_gen(fmt_rest$3, fmtty_rest$3), + fmtty$3 = match$9[2], + fmt$4 = match$9[1]; + return [0, [4, iconv, pad$4, prec$0, fmt$4], fmtty$3]; + } + throw caml_maybe_attach_backtrace(Type_mismatch, 1); + case 5: + var + fmt_rest$4 = fmt[4], + prec$1 = fmt[3], + pad$5 = fmt[2], + iconv$0 = fmt[1], + match$10 = type_padprec(pad$5, prec$1, fmtty0), + pad$6 = match$10[1], + match$11 = match$10[3]; + if(typeof match$11 !== "number" && 3 === match$11[0]){ + var + fmtty_rest$4 = match$11[1], + prec$2 = match$10[2], + match$12 = type_format_gen(fmt_rest$4, fmtty_rest$4), + fmtty$4 = match$12[2], + fmt$5 = match$12[1]; + return [0, [5, iconv$0, pad$6, prec$2, fmt$5], fmtty$4]; + } + throw caml_maybe_attach_backtrace(Type_mismatch, 1); + case 6: + var + fmt_rest$5 = fmt[4], + prec$3 = fmt[3], + pad$7 = fmt[2], + iconv$1 = fmt[1], + match$13 = type_padprec(pad$7, prec$3, fmtty0), + pad$8 = match$13[1], + match$14 = match$13[3]; + if(typeof match$14 !== "number" && 4 === match$14[0]){ + var + fmtty_rest$5 = match$14[1], + prec$4 = match$13[2], + match$15 = type_format_gen(fmt_rest$5, fmtty_rest$5), + fmtty$5 = match$15[2], + fmt$6 = match$15[1]; + return [0, [6, iconv$1, pad$8, prec$4, fmt$6], fmtty$5]; + } + throw caml_maybe_attach_backtrace(Type_mismatch, 1); + case 7: + var + fmt_rest$6 = fmt[4], + prec$5 = fmt[3], + pad$9 = fmt[2], + iconv$2 = fmt[1], + match$16 = type_padprec(pad$9, prec$5, fmtty0), + pad$10 = match$16[1], + match$17 = match$16[3]; + if(typeof match$17 !== "number" && 5 === match$17[0]){ + var + fmtty_rest$6 = match$17[1], + prec$6 = match$16[2], + match$18 = type_format_gen(fmt_rest$6, fmtty_rest$6), + fmtty$6 = match$18[2], + fmt$7 = match$18[1]; + return [0, [7, iconv$2, pad$10, prec$6, fmt$7], fmtty$6]; + } + throw caml_maybe_attach_backtrace(Type_mismatch, 1); + case 8: + var + fmt_rest$7 = fmt[4], + prec$7 = fmt[3], + pad$11 = fmt[2], + fconv = fmt[1], + match$19 = type_padprec(pad$11, prec$7, fmtty0), + pad$12 = match$19[1], + match$20 = match$19[3]; + if(typeof match$20 !== "number" && 6 === match$20[0]){ + var + fmtty_rest$7 = match$20[1], + prec$8 = match$19[2], + match$21 = type_format_gen(fmt_rest$7, fmtty_rest$7), + fmtty$7 = match$21[2], + fmt$8 = match$21[1]; + return [0, [8, fconv, pad$12, prec$8, fmt$8], fmtty$7]; + } + throw caml_maybe_attach_backtrace(Type_mismatch, 1); + case 9: + var + fmt_rest$8 = fmt[2], + pad$13 = fmt[1], + match$22 = type_padding(pad$13, fmtty0), + pad$14 = match$22[1], + match$23 = match$22[2]; + if(typeof match$23 !== "number" && 7 === match$23[0]){ + var + fmtty_rest$8 = match$23[1], + match$24 = type_format_gen(fmt_rest$8, fmtty_rest$8), + fmtty$8 = match$24[2], + fmt$9 = match$24[1]; + return [0, [9, pad$14, fmt$9], fmtty$8]; + } + throw caml_maybe_attach_backtrace(Type_mismatch, 1); + case 10: + var + fmt_rest$9 = fmt[1], + match$25 = type_format_gen(fmt_rest$9, fmtty0), + fmtty$9 = match$25[2], + fmt$10 = match$25[1]; + return [0, [10, fmt$10], fmtty$9]; + case 11: + var + fmt_rest$10 = fmt[2], + str = fmt[1], + match$26 = type_format_gen(fmt_rest$10, fmtty0), + fmtty$10 = match$26[2], + fmt$11 = match$26[1]; + return [0, [11, str, fmt$11], fmtty$10]; + case 12: + var + fmt_rest$11 = fmt[2], + chr = fmt[1], + match$27 = type_format_gen(fmt_rest$11, fmtty0), + fmtty$11 = match$27[2], + fmt$12 = match$27[1]; + return [0, [12, chr, fmt$12], fmtty$11]; + case 13: + if(typeof fmtty0 !== "number" && 8 === fmtty0[0]){ + var + fmtty_rest$9 = fmtty0[2], + sub_fmtty = fmtty0[1], + fmt_rest$12 = fmt[3], + sub_fmtty$0 = fmt[2], + pad_opt = fmt[1]; + if(caml_notequal([0, sub_fmtty$0], [0, sub_fmtty])) + throw caml_maybe_attach_backtrace(Type_mismatch, 1); + var + match$28 = type_format_gen(fmt_rest$12, fmtty_rest$9), + fmtty$12 = match$28[2], + fmt$13 = match$28[1]; + return [0, [13, pad_opt, sub_fmtty, fmt$13], fmtty$12]; + } + break; + case 14: + if(typeof fmtty0 !== "number" && 9 === fmtty0[0]){ + var + fmtty_rest$10 = fmtty0[3], + sub_fmtty1 = fmtty0[1], + fmt_rest$13 = fmt[3], + sub_fmtty$1 = fmt[2], + pad_opt$0 = fmt[1], + _cy_ = [0, caml_call1(CamlinternalFormatBasics[2], sub_fmtty1)]; + if + (caml_notequal + ([0, caml_call1(CamlinternalFormatBasics[2], sub_fmtty$1)], _cy_)) + throw caml_maybe_attach_backtrace(Type_mismatch, 1); + var + match$29 = + type_format_gen + (fmt_rest$13, + caml_call1(CamlinternalFormatBasics[2], fmtty_rest$10)), + fmtty$13 = match$29[2], + fmt$14 = match$29[1]; + return [0, [14, pad_opt$0, sub_fmtty1, fmt$14], fmtty$13]; + } + break; + case 15: + if(typeof fmtty0 !== "number" && 10 === fmtty0[0]){ + var + fmtty_rest$11 = fmtty0[1], + fmt_rest$14 = fmt[1], + match$30 = type_format_gen(fmt_rest$14, fmtty_rest$11), + fmtty$14 = match$30[2], + fmt$15 = match$30[1]; + return [0, [15, fmt$15], fmtty$14]; + } + break; + case 16: + if(typeof fmtty0 !== "number" && 11 === fmtty0[0]){ + var + fmtty_rest$12 = fmtty0[1], + fmt_rest$15 = fmt[1], + match$31 = type_format_gen(fmt_rest$15, fmtty_rest$12), + fmtty$15 = match$31[2], + fmt$16 = match$31[1]; + return [0, [16, fmt$16], fmtty$15]; + } + break; + case 17: + var + fmt_rest$16 = fmt[2], + formatting_lit = fmt[1], + match$32 = type_format_gen(fmt_rest$16, fmtty0), + fmtty$16 = match$32[2], + fmt$17 = match$32[1]; + return [0, [17, formatting_lit, fmt$17], fmtty$16]; + case 18: + var fmt_rest$17 = fmt[2], formatting_gen = fmt[1]; + if(0 === formatting_gen[0]){ + var + match$36 = formatting_gen[1], + str$0 = match$36[2], + fmt1 = match$36[1], + match$37 = type_format_gen(fmt1, fmtty0), + fmtty2 = match$37[2], + fmt2 = match$37[1], + match$38 = type_format_gen(fmt_rest$17, fmtty2), + fmtty3 = match$38[2], + fmt3 = match$38[1]; + return [0, [18, [0, [0, fmt2, str$0]], fmt3], fmtty3]; + } + var + match$39 = formatting_gen[1], + str$1 = match$39[2], + fmt1$0 = match$39[1], + match$40 = type_format_gen(fmt1$0, fmtty0), + fmtty2$0 = match$40[2], + fmt2$0 = match$40[1], + match$41 = type_format_gen(fmt_rest$17, fmtty2$0), + fmtty3$0 = match$41[2], + fmt3$0 = match$41[1]; + return [0, [18, [1, [0, fmt2$0, str$1]], fmt3$0], fmtty3$0]; + case 19: + if(typeof fmtty0 !== "number" && 13 === fmtty0[0]){ + var + fmtty_rest$13 = fmtty0[1], + fmt_rest$18 = fmt[1], + match$33 = type_format_gen(fmt_rest$18, fmtty_rest$13), + fmtty$17 = match$33[2], + fmt$18 = match$33[1]; + return [0, [19, fmt$18], fmtty$17]; + } + break; + case 20: + if(typeof fmtty0 !== "number" && 1 === fmtty0[0]){ + var + fmtty_rest$14 = fmtty0[1], + fmt_rest$19 = fmt[3], + char_set = fmt[2], + width_opt = fmt[1], + match$34 = type_format_gen(fmt_rest$19, fmtty_rest$14), + fmtty$18 = match$34[2], + fmt$19 = match$34[1]; + return [0, [20, width_opt, char_set, fmt$19], fmtty$18]; + } + break; + case 21: + if(typeof fmtty0 !== "number" && 2 === fmtty0[0]){ + var + fmtty_rest$15 = fmtty0[1], + fmt_rest$20 = fmt[2], + counter = fmt[1], + match$35 = type_format_gen(fmt_rest$20, fmtty_rest$15), + fmtty$19 = match$35[2], + fmt$20 = match$35[1]; + return [0, [21, counter, fmt$20], fmtty$19]; + } + break; + case 23: + var rest = fmt[2], ign = fmt[1]; + if(typeof ign !== "number") + switch(ign[0]){ + case 0: + return type_ignored_param_one(ign, rest, fmtty0); + case 1: + return type_ignored_param_one(ign, rest, fmtty0); + case 2: + return type_ignored_param_one(ign, rest, fmtty0); + case 3: + return type_ignored_param_one(ign, rest, fmtty0); + case 4: + return type_ignored_param_one(ign, rest, fmtty0); + case 5: + return type_ignored_param_one(ign, rest, fmtty0); + case 6: + return type_ignored_param_one(ign, rest, fmtty0); + case 7: + return type_ignored_param_one(ign, rest, fmtty0); + case 8: + var sub_fmtty$2 = ign[2], pad_opt$1 = ign[1]; + return type_ignored_param_one + ([8, pad_opt$1, sub_fmtty$2], rest, fmtty0); + case 9: + var + sub_fmtty$3 = ign[2], + pad_opt$2 = ign[1], + _cz_ = type_ignored_format_substituti(sub_fmtty$3, rest, fmtty0), + match$43 = _cz_[2], + fmtty$21 = match$43[2], + fmt$22 = match$43[1], + sub_fmtty$4 = _cz_[1]; + return [0, [23, [9, pad_opt$2, sub_fmtty$4], fmt$22], fmtty$21]; + case 10: + return type_ignored_param_one(ign, rest, fmtty0); + default: return type_ignored_param_one(ign, rest, fmtty0); + } + switch(ign){ + case 0: + return type_ignored_param_one(ign, rest, fmtty0); + case 1: + return type_ignored_param_one(ign, rest, fmtty0); + case 2: + if(typeof fmtty0 !== "number" && 14 === fmtty0[0]){ + var + fmtty_rest$16 = fmtty0[1], + match$42 = type_format_gen(rest, fmtty_rest$16), + fmtty$20 = match$42[2], + fmt$21 = match$42[1]; + return [0, [23, 2, fmt$21], fmtty$20]; + } + throw caml_maybe_attach_backtrace(Type_mismatch, 1); + default: return type_ignored_param_one(ign, rest, fmtty0); + } + } + throw caml_maybe_attach_backtrace(Type_mismatch, 1); + } + function type_ignored_param_one(ign, fmt, fmtty){ + var + match = type_format_gen(fmt, fmtty), + fmtty$0 = match[2], + fmt$0 = match[1]; + return [0, [23, ign, fmt$0], fmtty$0]; + } + function type_ignored_format_substituti(sub_fmtty, fmt, fmtty){ + if(typeof sub_fmtty === "number") + return [0, 0, type_format_gen(fmt, fmtty)]; + switch(sub_fmtty[0]){ + case 0: + if(typeof fmtty !== "number" && 0 === fmtty[0]){ + var + fmtty_rest = fmtty[1], + sub_fmtty_rest = sub_fmtty[1], + match = + type_ignored_format_substituti(sub_fmtty_rest, fmt, fmtty_rest), + fmt$0 = match[2], + sub_fmtty_rest$0 = match[1]; + return [0, [0, sub_fmtty_rest$0], fmt$0]; + } + break; + case 1: + if(typeof fmtty !== "number" && 1 === fmtty[0]){ + var + fmtty_rest$0 = fmtty[1], + sub_fmtty_rest$1 = sub_fmtty[1], + match$0 = + type_ignored_format_substituti(sub_fmtty_rest$1, fmt, fmtty_rest$0), + fmt$1 = match$0[2], + sub_fmtty_rest$2 = match$0[1]; + return [0, [1, sub_fmtty_rest$2], fmt$1]; + } + break; + case 2: + if(typeof fmtty !== "number" && 2 === fmtty[0]){ + var + fmtty_rest$1 = fmtty[1], + sub_fmtty_rest$3 = sub_fmtty[1], + match$1 = + type_ignored_format_substituti(sub_fmtty_rest$3, fmt, fmtty_rest$1), + fmt$2 = match$1[2], + sub_fmtty_rest$4 = match$1[1]; + return [0, [2, sub_fmtty_rest$4], fmt$2]; + } + break; + case 3: + if(typeof fmtty !== "number" && 3 === fmtty[0]){ + var + fmtty_rest$2 = fmtty[1], + sub_fmtty_rest$5 = sub_fmtty[1], + match$2 = + type_ignored_format_substituti(sub_fmtty_rest$5, fmt, fmtty_rest$2), + fmt$3 = match$2[2], + sub_fmtty_rest$6 = match$2[1]; + return [0, [3, sub_fmtty_rest$6], fmt$3]; + } + break; + case 4: + if(typeof fmtty !== "number" && 4 === fmtty[0]){ + var + fmtty_rest$3 = fmtty[1], + sub_fmtty_rest$7 = sub_fmtty[1], + match$3 = + type_ignored_format_substituti(sub_fmtty_rest$7, fmt, fmtty_rest$3), + fmt$4 = match$3[2], + sub_fmtty_rest$8 = match$3[1]; + return [0, [4, sub_fmtty_rest$8], fmt$4]; + } + break; + case 5: + if(typeof fmtty !== "number" && 5 === fmtty[0]){ + var + fmtty_rest$4 = fmtty[1], + sub_fmtty_rest$9 = sub_fmtty[1], + match$4 = + type_ignored_format_substituti(sub_fmtty_rest$9, fmt, fmtty_rest$4), + fmt$5 = match$4[2], + sub_fmtty_rest$10 = match$4[1]; + return [0, [5, sub_fmtty_rest$10], fmt$5]; + } + break; + case 6: + if(typeof fmtty !== "number" && 6 === fmtty[0]){ + var + fmtty_rest$5 = fmtty[1], + sub_fmtty_rest$11 = sub_fmtty[1], + match$5 = + type_ignored_format_substituti + (sub_fmtty_rest$11, fmt, fmtty_rest$5), + fmt$6 = match$5[2], + sub_fmtty_rest$12 = match$5[1]; + return [0, [6, sub_fmtty_rest$12], fmt$6]; + } + break; + case 7: + if(typeof fmtty !== "number" && 7 === fmtty[0]){ + var + fmtty_rest$6 = fmtty[1], + sub_fmtty_rest$13 = sub_fmtty[1], + match$6 = + type_ignored_format_substituti + (sub_fmtty_rest$13, fmt, fmtty_rest$6), + fmt$7 = match$6[2], + sub_fmtty_rest$14 = match$6[1]; + return [0, [7, sub_fmtty_rest$14], fmt$7]; + } + break; + case 8: + if(typeof fmtty !== "number" && 8 === fmtty[0]){ + var + fmtty_rest$7 = fmtty[2], + sub2_fmtty = fmtty[1], + sub_fmtty_rest$15 = sub_fmtty[2], + sub2_fmtty$0 = sub_fmtty[1]; + if(caml_notequal([0, sub2_fmtty$0], [0, sub2_fmtty])) + throw caml_maybe_attach_backtrace(Type_mismatch, 1); + var + match$7 = + type_ignored_format_substituti + (sub_fmtty_rest$15, fmt, fmtty_rest$7), + fmt$8 = match$7[2], + sub_fmtty_rest$16 = match$7[1]; + return [0, [8, sub2_fmtty, sub_fmtty_rest$16], fmt$8]; + } + break; + case 9: + if(typeof fmtty !== "number" && 9 === fmtty[0]){ + var + fmtty_rest$8 = fmtty[3], + sub2_fmtty$1 = fmtty[2], + sub1_fmtty = fmtty[1], + sub_fmtty_rest$17 = sub_fmtty[3], + sub2_fmtty$2 = sub_fmtty[2], + sub1_fmtty$0 = sub_fmtty[1], + _cw_ = [0, caml_call1(CamlinternalFormatBasics[2], sub1_fmtty)]; + if + (caml_notequal + ([0, caml_call1(CamlinternalFormatBasics[2], sub1_fmtty$0)], _cw_)) + throw caml_maybe_attach_backtrace(Type_mismatch, 1); + var _cx_ = [0, caml_call1(CamlinternalFormatBasics[2], sub2_fmtty$1)]; + if + (caml_notequal + ([0, caml_call1(CamlinternalFormatBasics[2], sub2_fmtty$2)], _cx_)) + throw caml_maybe_attach_backtrace(Type_mismatch, 1); + var + sub_fmtty$0 = trans(symm(sub1_fmtty), sub2_fmtty$1), + match$8 = fmtty_rel_det(sub_fmtty$0), + f4 = match$8[4], + f2 = match$8[2]; + f2(0); + f4(0); + var + match$9 = + type_ignored_format_substituti + (caml_call1(CamlinternalFormatBasics[2], sub_fmtty_rest$17), + fmt, + fmtty_rest$8), + fmt$9 = match$9[2], + sub_fmtty_rest$18 = match$9[1]; + return [0, + [9, sub1_fmtty, sub2_fmtty$1, symm(sub_fmtty_rest$18)], + fmt$9]; + } + break; + case 10: + if(typeof fmtty !== "number" && 10 === fmtty[0]){ + var + fmtty_rest$9 = fmtty[1], + sub_fmtty_rest$19 = sub_fmtty[1], + match$10 = + type_ignored_format_substituti + (sub_fmtty_rest$19, fmt, fmtty_rest$9), + fmt$10 = match$10[2], + sub_fmtty_rest$20 = match$10[1]; + return [0, [10, sub_fmtty_rest$20], fmt$10]; + } + break; + case 11: + if(typeof fmtty !== "number" && 11 === fmtty[0]){ + var + fmtty_rest$10 = fmtty[1], + sub_fmtty_rest$21 = sub_fmtty[1], + match$11 = + type_ignored_format_substituti + (sub_fmtty_rest$21, fmt, fmtty_rest$10), + fmt$11 = match$11[2], + sub_fmtty_rest$22 = match$11[1]; + return [0, [11, sub_fmtty_rest$22], fmt$11]; + } + break; + case 13: + if(typeof fmtty !== "number" && 13 === fmtty[0]){ + var + fmtty_rest$11 = fmtty[1], + sub_fmtty_rest$23 = sub_fmtty[1], + match$12 = + type_ignored_format_substituti + (sub_fmtty_rest$23, fmt, fmtty_rest$11), + fmt$12 = match$12[2], + sub_fmtty_rest$24 = match$12[1]; + return [0, [13, sub_fmtty_rest$24], fmt$12]; + } + break; + case 14: + if(typeof fmtty !== "number" && 14 === fmtty[0]){ + var + fmtty_rest$12 = fmtty[1], + sub_fmtty_rest$25 = sub_fmtty[1], + match$13 = + type_ignored_format_substituti + (sub_fmtty_rest$25, fmt, fmtty_rest$12), + fmt$13 = match$13[2], + sub_fmtty_rest$26 = match$13[1]; + return [0, [14, sub_fmtty_rest$26], fmt$13]; + } + break; + } + throw caml_maybe_attach_backtrace(Type_mismatch, 1); + } + function recast(fmt, fmtty){ + var _cv_ = symm(fmtty); + return type_format(fmt, caml_call1(CamlinternalFormatBasics[2], _cv_)); + } + function fix_padding(padty, width, str){ + var + len = caml_ml_string_length(str), + padty$0 = 0 <= width ? padty : 0, + width$0 = caml_call1(Stdlib[18], width); + if(width$0 <= len) return str; + var + _cu_ = 2 === padty$0 ? 48 : 32, + res = caml_call2(Stdlib_Bytes[1], width$0, _cu_); + switch(padty$0){ + case 0: + caml_call5(Stdlib_String[42], str, 0, res, 0, len); break; + case 1: + caml_call5(Stdlib_String[42], str, 0, res, width$0 - len | 0, len); + break; + default: + a: + if(0 < len){ + if + (43 !== caml_string_get(str, 0) + && 45 !== caml_string_get(str, 0) && 32 !== caml_string_get(str, 0)) + break a; + caml_bytes_set(res, 0, caml_string_get(str, 0)); + caml_call5 + (Stdlib_String[42], + str, + 1, + res, + (width$0 - len | 0) + 1 | 0, + len - 1 | 0); + break; + } + a: + if(1 < len && 48 === caml_string_get(str, 0)){ + if(120 !== caml_string_get(str, 1) && 88 !== caml_string_get(str, 1)) + break a; + caml_bytes_set(res, 1, caml_string_get(str, 1)); + caml_call5 + (Stdlib_String[42], + str, + 2, + res, + (width$0 - len | 0) + 2 | 0, + len - 2 | 0); + break; + } + caml_call5(Stdlib_String[42], str, 0, res, width$0 - len | 0, len); + } + return caml_call1(Stdlib_Bytes[48], res); + } + function fix_int_precision(prec, str){ + var + prec$0 = caml_call1(Stdlib[18], prec), + len = caml_ml_string_length(str), + c = caml_string_get(str, 0); + a: + { + b: + { + if(58 > c){ + if(32 !== c){ + if(43 > c) break a; + switch(c - 43 | 0){ + case 5: + c: + if(len < (prec$0 + 2 | 0) && 1 < len){ + if + (120 !== caml_string_get(str, 1) + && 88 !== caml_string_get(str, 1)) + break c; + var res$1 = caml_call2(Stdlib_Bytes[1], prec$0 + 2 | 0, 48); + caml_bytes_set(res$1, 1, caml_string_get(str, 1)); + caml_call5 + (Stdlib_String[42], + str, + 2, + res$1, + (prec$0 - len | 0) + 4 | 0, + len - 2 | 0); + return caml_call1(Stdlib_Bytes[48], res$1); + } + break b; + case 0: + case 2: break; + case 1: + case 3: + case 4: + break a; + default: break b; + } + } + if(len >= (prec$0 + 1 | 0)) break a; + var res$0 = caml_call2(Stdlib_Bytes[1], prec$0 + 1 | 0, 48); + caml_bytes_set(res$0, 0, c); + caml_call5 + (Stdlib_String[42], + str, + 1, + res$0, + (prec$0 - len | 0) + 2 | 0, + len - 1 | 0); + return caml_call1(Stdlib_Bytes[48], res$0); + } + if(71 <= c){if(5 < c - 97 >>> 0) break a;} else if(65 > c) break a; + } + if(len < prec$0){ + var res = caml_call2(Stdlib_Bytes[1], prec$0, 48); + caml_call5(Stdlib_String[42], str, 0, res, prec$0 - len | 0, len); + return caml_call1(Stdlib_Bytes[48], res); + } + } + return str; + } + function string_to_caml_string(str){ + var + str$0 = caml_call1(Stdlib_String[24], str), + l = caml_ml_string_length(str$0), + res = caml_call2(Stdlib_Bytes[1], l + 2 | 0, 34); + caml_blit_string(str$0, 0, res, 1, l); + return caml_call1(Stdlib_Bytes[48], res); + } + function format_of_fconv(fconv, prec){ + var + prec$0 = caml_call1(Stdlib[18], prec), + symb = char_of_fconv(_r_, fconv), + buf = buffer_create(16); + buffer_add_char(buf, 37); + bprint_fconv_flag(buf, fconv); + buffer_add_char(buf, 46); + buffer_add_string(buf, caml_call1(Stdlib_Int[12], prec$0)); + buffer_add_char(buf, symb); + return buffer_contents(buf); + } + function transform_int_alt(iconv, s){ + if(13 > iconv) return s; + var n = [0, 0], _cp_ = caml_ml_string_length(s) - 1 | 0, _co_ = 0; + if(_cp_ >= 0){ + var i$0 = _co_; + for(;;){ + if(9 >= caml_string_unsafe_get(s, i$0) - 48 >>> 0) n[1]++; + var _ct_ = i$0 + 1 | 0; + if(_cp_ === i$0) break; + i$0 = _ct_; + } + } + var + digits = n[1], + buf = + caml_create_bytes + (caml_ml_string_length(s) + ((digits - 1 | 0) / 3 | 0) | 0), + pos = [0, 0]; + function put(c){caml_bytes_set(buf, pos[1], c); pos[1]++; return;} + var + left = [0, ((digits - 1 | 0) % 3 | 0) + 1 | 0], + _cr_ = caml_ml_string_length(s) - 1 | 0, + _cq_ = 0; + if(_cr_ >= 0){ + var i = _cq_; + for(;;){ + var c = caml_string_unsafe_get(s, i); + if(9 < c - 48 >>> 0) + put(c); + else{if(0 === left[1]){put(95); left[1] = 3;} left[1]--; put(c);} + var _cs_ = i + 1 | 0; + if(_cr_ === i) break; + i = _cs_; + } + } + return caml_call1(Stdlib_Bytes[48], buf); + } + function convert_int(iconv, n){ + switch(iconv){ + case 1: + var _cn_ = cst_d$0; break; + case 2: + var _cn_ = cst_d$1; break; + case 4: + var _cn_ = cst_i$1; break; + case 5: + var _cn_ = cst_i$2; break; + case 6: + var _cn_ = cst_x; break; + case 7: + var _cn_ = cst_x$0; break; + case 8: + var _cn_ = cst_X; break; + case 9: + var _cn_ = cst_X$0; break; + case 10: + var _cn_ = cst_o; break; + case 11: + var _cn_ = cst_o$0; break; + case 0: + case 13: + var _cn_ = cst_d; break; + case 3: + case 14: + var _cn_ = cst_i$0; break; + default: var _cn_ = cst_u; + } + return transform_int_alt(iconv, caml_format_int(_cn_, n)); + } + function convert_int32(iconv, n){ + switch(iconv){ + case 1: + var _cm_ = cst_ld$0; break; + case 2: + var _cm_ = cst_ld$1; break; + case 4: + var _cm_ = cst_li$1; break; + case 5: + var _cm_ = cst_li$2; break; + case 6: + var _cm_ = cst_lx; break; + case 7: + var _cm_ = cst_lx$0; break; + case 8: + var _cm_ = cst_lX; break; + case 9: + var _cm_ = cst_lX$0; break; + case 10: + var _cm_ = cst_lo; break; + case 11: + var _cm_ = cst_lo$0; break; + case 0: + case 13: + var _cm_ = cst_ld; break; + case 3: + case 14: + var _cm_ = cst_li$0; break; + default: var _cm_ = cst_lu; + } + return transform_int_alt(iconv, caml_format_int(_cm_, n)); + } + function convert_nativeint(iconv, n){ + switch(iconv){ + case 1: + var _cl_ = cst_nd$0; break; + case 2: + var _cl_ = cst_nd$1; break; + case 4: + var _cl_ = cst_ni$1; break; + case 5: + var _cl_ = cst_ni$2; break; + case 6: + var _cl_ = cst_nx; break; + case 7: + var _cl_ = cst_nx$0; break; + case 8: + var _cl_ = cst_nX; break; + case 9: + var _cl_ = cst_nX$0; break; + case 10: + var _cl_ = cst_no; break; + case 11: + var _cl_ = cst_no$0; break; + case 0: + case 13: + var _cl_ = cst_nd; break; + case 3: + case 14: + var _cl_ = cst_ni$0; break; + default: var _cl_ = cst_nu; + } + return transform_int_alt(iconv, caml_format_int(_cl_, n)); + } + function convert_int64(iconv, n){ + switch(iconv){ + case 1: + var _ck_ = cst_Ld$0; break; + case 2: + var _ck_ = cst_Ld$1; break; + case 4: + var _ck_ = cst_Li$1; break; + case 5: + var _ck_ = cst_Li$2; break; + case 6: + var _ck_ = cst_Lx; break; + case 7: + var _ck_ = cst_Lx$0; break; + case 8: + var _ck_ = cst_LX; break; + case 9: + var _ck_ = cst_LX$0; break; + case 10: + var _ck_ = cst_Lo; break; + case 11: + var _ck_ = cst_Lo$0; break; + case 0: + case 13: + var _ck_ = cst_Ld; break; + case 3: + case 14: + var _ck_ = cst_Li$0; break; + default: var _ck_ = cst_Lu; + } + return transform_int_alt(iconv, runtime.caml_int64_format(_ck_, n)); + } + function convert_float(fconv, prec, x){ + function hex(param){ + switch(fconv[1]){ + case 0: + var sign = 45; break; + case 1: + var sign = 43; break; + default: var sign = 32; + } + return runtime.caml_hexstring_of_float(x, prec, sign); + } + function caml_special_val(str){ + var match = runtime.caml_classify_float(x); + return 3 === match + ? x < 0. ? cst_neg_infinity : cst_infinity + : 4 <= match ? cst_nan : str; + } + switch(fconv[2]){ + case 5: + var + str = caml_format_float(format_of_fconv(fconv, prec), x), + len = caml_ml_string_length(str), + i = 0; + for(;;){ + if(i === len) + var _ch_ = 0; + else{ + var _cg_ = caml_string_get(str, i) - 46 | 0; + a: + { + if(23 < _cg_ >>> 0){ + if(55 === _cg_) break a; + } + else if(21 < _cg_ - 1 >>> 0) break a; + var i$0 = i + 1 | 0; + i = i$0; + continue; + } + var _ch_ = 1; + } + var _ci_ = _ch_ ? str : caml_call2(Stdlib[28], str, cst$17); + return caml_special_val(_ci_); + } + case 6: + return hex(0); + case 7: + var _cj_ = hex(0); return caml_call1(Stdlib_String[25], _cj_); + case 8: + return caml_special_val(hex(0)); + default: return caml_format_float(format_of_fconv(fconv, prec), x); + } + } + function string_of_fmtty(fmtty){ + var buf = buffer_create(16); + bprint_fmtty(buf, fmtty); + return buffer_contents(buf); + } + function make_printf$0(counter, k, acc, fmt){ + var k$0 = k, acc$0 = acc, fmt$0 = fmt; + for(;;){ + if(typeof fmt$0 === "number") return caml_call1(k$0, acc$0); + switch(fmt$0[0]){ + case 0: + var rest = fmt$0[1]; + return function(c){ + var new_acc = [5, acc$0, c]; + return make_printf(k$0, new_acc, rest);}; + case 1: + var rest$0 = fmt$0[1]; + return function(c){ + var + str = caml_call1(Stdlib_Char[2], c), + l = caml_ml_string_length(str), + res = caml_call2(Stdlib_Bytes[1], l + 2 | 0, 39); + caml_blit_string(str, 0, res, 1, l); + var new_acc = [4, acc$0, caml_call1(Stdlib_Bytes[48], res)]; + return make_printf(k$0, new_acc, rest$0);}; + case 2: + var rest$1 = fmt$0[2], pad = fmt$0[1]; + return make_padding + (k$0, acc$0, rest$1, pad, function(str){return str;}); + case 3: + var rest$2 = fmt$0[2], pad$0 = fmt$0[1]; + return make_padding(k$0, acc$0, rest$2, pad$0, string_to_caml_string); + case 4: + var + rest$3 = fmt$0[4], + prec = fmt$0[3], + pad$1 = fmt$0[2], + iconv = fmt$0[1]; + return make_int_padding_precision + (k$0, acc$0, rest$3, pad$1, prec, convert_int, iconv); + case 5: + var + rest$4 = fmt$0[4], + prec$0 = fmt$0[3], + pad$2 = fmt$0[2], + iconv$0 = fmt$0[1]; + return make_int_padding_precision + (k$0, acc$0, rest$4, pad$2, prec$0, convert_int32, iconv$0); + case 6: + var + rest$5 = fmt$0[4], + prec$1 = fmt$0[3], + pad$3 = fmt$0[2], + iconv$1 = fmt$0[1]; + return make_int_padding_precision + (k$0, + acc$0, + rest$5, + pad$3, + prec$1, + convert_nativeint, + iconv$1); + case 7: + var + rest$6 = fmt$0[4], + prec$2 = fmt$0[3], + pad$4 = fmt$0[2], + iconv$2 = fmt$0[1]; + return make_int_padding_precision + (k$0, acc$0, rest$6, pad$4, prec$2, convert_int64, iconv$2); + case 8: + var + rest$7 = fmt$0[4], + prec$3 = fmt$0[3], + pad$5 = fmt$0[2], + fconv = fmt$0[1]; + if(typeof pad$5 === "number"){ + if(typeof prec$3 === "number") + return prec$3 + ? function + (p, x){ + var str = convert_float(fconv, p, x); + return make_printf(k$0, [4, acc$0, str], rest$7); + } + : function + (x){ + var + str = + convert_float(fconv, default_float_precision(fconv), x); + return make_printf(k$0, [4, acc$0, str], rest$7); + }; + var p = prec$3[1]; + return function(x){ + var str = convert_float(fconv, p, x); + return make_printf(k$0, [4, acc$0, str], rest$7);}; + } + if(0 === pad$5[0]){ + var w = pad$5[2], padty = pad$5[1]; + if(typeof prec$3 === "number") + return prec$3 + ? function + (p, x){ + var str = fix_padding(padty, w, convert_float(fconv, p, x)); + return make_printf(k$0, [4, acc$0, str], rest$7); + } + : function + (x){ + var + str = + convert_float(fconv, default_float_precision(fconv), x), + str$0 = fix_padding(padty, w, str); + return make_printf(k$0, [4, acc$0, str$0], rest$7); + }; + var p$0 = prec$3[1]; + return function(x){ + var str = fix_padding(padty, w, convert_float(fconv, p$0, x)); + return make_printf(k$0, [4, acc$0, str], rest$7);}; + } + var padty$0 = pad$5[1]; + if(typeof prec$3 === "number") + return prec$3 + ? function + (w, p, x){ + var + str = fix_padding(padty$0, w, convert_float(fconv, p, x)); + return make_printf(k$0, [4, acc$0, str], rest$7); + } + : function + (w, x){ + var + str = + convert_float(fconv, default_float_precision(fconv), x), + str$0 = fix_padding(padty$0, w, str); + return make_printf(k$0, [4, acc$0, str$0], rest$7); + }; + var p$1 = prec$3[1]; + return function(w, x){ + var str = fix_padding(padty$0, w, convert_float(fconv, p$1, x)); + return make_printf(k$0, [4, acc$0, str], rest$7);}; + case 9: + var rest$8 = fmt$0[2], pad$6 = fmt$0[1]; + return make_padding(k$0, acc$0, rest$8, pad$6, Stdlib[30]); + case 10: + var rest$9 = fmt$0[1], acc$1 = [7, acc$0]; + acc$0 = acc$1; + fmt$0 = rest$9; + break; + case 11: + var rest$10 = fmt$0[2], str = fmt$0[1], acc$2 = [2, acc$0, str]; + acc$0 = acc$2; + fmt$0 = rest$10; + break; + case 12: + var rest$11 = fmt$0[2], chr = fmt$0[1], acc$3 = [3, acc$0, chr]; + acc$0 = acc$3; + fmt$0 = rest$11; + break; + case 13: + var + rest$12 = fmt$0[3], + sub_fmtty = fmt$0[2], + ty = string_of_fmtty(sub_fmtty); + return function(str){ + return make_printf(k$0, [4, acc$0, ty], rest$12);}; + case 14: + var rest$13 = fmt$0[3], fmtty = fmt$0[2]; + return function(param){ + var fmt = param[1], _cf_ = recast(fmt, fmtty); + return make_printf + (k$0, + acc$0, + caml_call2(CamlinternalFormatBasics[3], _cf_, rest$13));}; + case 15: + var rest$14 = fmt$0[1]; + return function(f, x){ + return make_printf + (k$0, + [6, acc$0, function(o){return caml_call2(f, o, x);}], + rest$14);}; + case 16: + var rest$15 = fmt$0[1]; + return function(f){return make_printf(k$0, [6, acc$0, f], rest$15);}; + case 17: + var + rest$16 = fmt$0[2], + fmting_lit = fmt$0[1], + acc$4 = [0, acc$0, fmting_lit]; + acc$0 = acc$4; + fmt$0 = rest$16; + break; + case 18: + var _cd_ = fmt$0[1]; + if(0 === _cd_[0]){ + var rest$17 = fmt$0[2], fmt$1 = _cd_[1][1]; + let acc = acc$0, k = k$0, rest = rest$17; + var + k$1 = + function(kacc){return make_printf(k, [1, acc, [0, kacc]], rest);}; + k$0 = k$1; + acc$0 = 0; + fmt$0 = fmt$1; + } + else{ + var rest$18 = fmt$0[2], fmt$2 = _cd_[1][1]; + let acc = acc$0, k = k$0, rest = rest$18; + var + k$2 = + function(kacc){return make_printf(k, [1, acc, [1, kacc]], rest);}; + k$0 = k$2; + acc$0 = 0; + fmt$0 = fmt$2; + } + break; + case 19: + throw caml_maybe_attach_backtrace([0, Assert_failure, _s_], 1); + case 20: + var + rest$19 = fmt$0[3], + new_acc = [8, acc$0, cst_Printf_bad_conversion]; + return function(param){return make_printf(k$0, new_acc, rest$19);}; + case 21: + var rest$20 = fmt$0[2]; + return function(n){ + var new_acc = [4, acc$0, caml_format_int(cst_u$0, n)]; + return make_printf(k$0, new_acc, rest$20);}; + case 22: + var rest$21 = fmt$0[1]; + return function(c){ + var new_acc = [5, acc$0, c]; + return make_printf(k$0, new_acc, rest$21);}; + case 23: + var rest$22 = fmt$0[2], ign = fmt$0[1]; + if(counter >= 50) + return caml_trampoline_return + (make_ignored_param$0, [0, k$0, acc$0, ign, rest$22]); + var counter$1 = counter + 1 | 0; + return make_ignored_param$0(counter$1, k$0, acc$0, ign, rest$22); + default: + var + rest$23 = fmt$0[3], + f = fmt$0[2], + arity = fmt$0[1], + _ce_ = caml_call1(f, 0); + if(counter >= 50) + return caml_trampoline_return + (make_custom$0, [0, k$0, acc$0, rest$23, arity, _ce_]); + var counter$0 = counter + 1 | 0; + return make_custom$0(counter$0, k$0, acc$0, rest$23, arity, _ce_); + } + } + } + function make_printf(k, acc, fmt){ + return caml_trampoline(make_printf$0(0, k, acc, fmt)); + } + function make_ignored_param$0(counter, k, acc, ign, fmt){ + if(typeof ign === "number") + switch(ign){ + case 0: + if(counter >= 50) + return caml_trampoline_return(make_invalid_arg, [0, k, acc, fmt]); + var counter$0 = counter + 1 | 0; + return make_invalid_arg(counter$0, k, acc, fmt); + case 1: + if(counter >= 50) + return caml_trampoline_return(make_invalid_arg, [0, k, acc, fmt]); + var counter$1 = counter + 1 | 0; + return make_invalid_arg(counter$1, k, acc, fmt); + case 2: + throw caml_maybe_attach_backtrace([0, Assert_failure, _t_], 1); + default: + if(counter >= 50) + return caml_trampoline_return(make_invalid_arg, [0, k, acc, fmt]); + var counter$2 = counter + 1 | 0; + return make_invalid_arg(counter$2, k, acc, fmt); + } + switch(ign[0]){ + case 0: + if(counter >= 50) + return caml_trampoline_return(make_invalid_arg, [0, k, acc, fmt]); + var counter$3 = counter + 1 | 0; + return make_invalid_arg(counter$3, k, acc, fmt); + case 1: + if(counter >= 50) + return caml_trampoline_return(make_invalid_arg, [0, k, acc, fmt]); + var counter$4 = counter + 1 | 0; + return make_invalid_arg(counter$4, k, acc, fmt); + case 2: + if(counter >= 50) + return caml_trampoline_return(make_invalid_arg, [0, k, acc, fmt]); + var counter$5 = counter + 1 | 0; + return make_invalid_arg(counter$5, k, acc, fmt); + case 3: + if(counter >= 50) + return caml_trampoline_return(make_invalid_arg, [0, k, acc, fmt]); + var counter$6 = counter + 1 | 0; + return make_invalid_arg(counter$6, k, acc, fmt); + case 4: + if(counter >= 50) + return caml_trampoline_return(make_invalid_arg, [0, k, acc, fmt]); + var counter$7 = counter + 1 | 0; + return make_invalid_arg(counter$7, k, acc, fmt); + case 5: + if(counter >= 50) + return caml_trampoline_return(make_invalid_arg, [0, k, acc, fmt]); + var counter$8 = counter + 1 | 0; + return make_invalid_arg(counter$8, k, acc, fmt); + case 6: + if(counter >= 50) + return caml_trampoline_return(make_invalid_arg, [0, k, acc, fmt]); + var counter$9 = counter + 1 | 0; + return make_invalid_arg(counter$9, k, acc, fmt); + case 7: + if(counter >= 50) + return caml_trampoline_return(make_invalid_arg, [0, k, acc, fmt]); + var counter$10 = counter + 1 | 0; + return make_invalid_arg(counter$10, k, acc, fmt); + case 8: + if(counter >= 50) + return caml_trampoline_return(make_invalid_arg, [0, k, acc, fmt]); + var counter$11 = counter + 1 | 0; + return make_invalid_arg(counter$11, k, acc, fmt); + case 9: + var fmtty = ign[2]; + if(counter >= 50) + return caml_trampoline_return + (make_from_fmtty$0, [0, k, acc, fmtty, fmt]); + var counter$14 = counter + 1 | 0; + return make_from_fmtty$0(counter$14, k, acc, fmtty, fmt); + case 10: + if(counter >= 50) + return caml_trampoline_return(make_invalid_arg, [0, k, acc, fmt]); + var counter$12 = counter + 1 | 0; + return make_invalid_arg(counter$12, k, acc, fmt); + default: + if(counter >= 50) + return caml_trampoline_return(make_invalid_arg, [0, k, acc, fmt]); + var counter$13 = counter + 1 | 0; + return make_invalid_arg(counter$13, k, acc, fmt); + } + } + function make_ignored_param(k, acc, ign, fmt){ + return caml_trampoline(make_ignored_param$0(0, k, acc, ign, fmt)); + } + function make_from_fmtty$0(counter, k, acc, fmtty, fmt){ + if(typeof fmtty !== "number") + switch(fmtty[0]){ + case 0: + var rest = fmtty[1]; + return function(param){return make_from_fmtty(k, acc, rest, fmt);}; + case 1: + var rest$0 = fmtty[1]; + return function(param){return make_from_fmtty(k, acc, rest$0, fmt);}; + case 2: + var rest$1 = fmtty[1]; + return function(param){return make_from_fmtty(k, acc, rest$1, fmt);}; + case 3: + var rest$2 = fmtty[1]; + return function(param){return make_from_fmtty(k, acc, rest$2, fmt);}; + case 4: + var rest$3 = fmtty[1]; + return function(param){return make_from_fmtty(k, acc, rest$3, fmt);}; + case 5: + var rest$4 = fmtty[1]; + return function(param){return make_from_fmtty(k, acc, rest$4, fmt);}; + case 6: + var rest$5 = fmtty[1]; + return function(param){return make_from_fmtty(k, acc, rest$5, fmt);}; + case 7: + var rest$6 = fmtty[1]; + return function(param){return make_from_fmtty(k, acc, rest$6, fmt);}; + case 8: + var rest$7 = fmtty[2]; + return function(param){return make_from_fmtty(k, acc, rest$7, fmt);}; + case 9: + var + rest$8 = fmtty[3], + ty2 = fmtty[2], + ty1 = fmtty[1], + ty = trans(symm(ty1), ty2); + return function(param){ + return make_from_fmtty + (k, + acc, + caml_call2(CamlinternalFormatBasics[1], ty, rest$8), + fmt);}; + case 10: + var rest$9 = fmtty[1]; + return function(param, _cc_){ + return make_from_fmtty(k, acc, rest$9, fmt);}; + case 11: + var rest$10 = fmtty[1]; + return function(param){return make_from_fmtty(k, acc, rest$10, fmt);}; + case 12: + var rest$11 = fmtty[1]; + return function(param){return make_from_fmtty(k, acc, rest$11, fmt);}; + case 13: + throw caml_maybe_attach_backtrace([0, Assert_failure, _u_], 1); + default: + throw caml_maybe_attach_backtrace([0, Assert_failure, _v_], 1); + } + if(counter >= 50) + return caml_trampoline_return(make_invalid_arg, [0, k, acc, fmt]); + var counter$0 = counter + 1 | 0; + return make_invalid_arg(counter$0, k, acc, fmt); + } + function make_from_fmtty(k, acc, fmtty, fmt){ + return caml_trampoline(make_from_fmtty$0(0, k, acc, fmtty, fmt)); + } + function make_invalid_arg(counter, k, acc, fmt){ + var _cb_ = [8, acc, cst_Printf_bad_conversion$0]; + if(counter >= 50) + return caml_trampoline_return(make_printf$0, [0, k, _cb_, fmt]); + var counter$0 = counter + 1 | 0; + return make_printf$0(counter$0, k, _cb_, fmt); + } + function make_padding(k, acc, fmt, pad, trans){ + if(typeof pad === "number") + return function(x){ + var new_acc = [4, acc, caml_call1(trans, x)]; + return make_printf(k, new_acc, fmt);}; + if(0 === pad[0]){ + var width = pad[2], padty = pad[1]; + return function(x){ + var new_acc = [4, acc, fix_padding(padty, width, caml_call1(trans, x))]; + return make_printf(k, new_acc, fmt);}; + } + var padty$0 = pad[1]; + return function(w, x){ + var new_acc = [4, acc, fix_padding(padty$0, w, caml_call1(trans, x))]; + return make_printf(k, new_acc, fmt);}; + } + function make_int_padding_precision(k, acc, fmt, pad, prec, trans, iconv){ + if(typeof pad === "number"){ + if(typeof prec === "number") + return prec + ? function + (p, x){ + var str = fix_int_precision(p, caml_call2(trans, iconv, x)); + return make_printf(k, [4, acc, str], fmt); + } + : function + (x){ + var str = caml_call2(trans, iconv, x); + return make_printf(k, [4, acc, str], fmt); + }; + var p = prec[1]; + return function(x){ + var str = fix_int_precision(p, caml_call2(trans, iconv, x)); + return make_printf(k, [4, acc, str], fmt);}; + } + if(0 === pad[0]){ + var w = pad[2], padty = pad[1]; + if(typeof prec === "number") + return prec + ? function + (p, x){ + var + str = + fix_padding + (padty, + w, + fix_int_precision(p, caml_call2(trans, iconv, x))); + return make_printf(k, [4, acc, str], fmt); + } + : function + (x){ + var str = fix_padding(padty, w, caml_call2(trans, iconv, x)); + return make_printf(k, [4, acc, str], fmt); + }; + var p$0 = prec[1]; + return function(x){ + var + str = + fix_padding + (padty, w, fix_int_precision(p$0, caml_call2(trans, iconv, x))); + return make_printf(k, [4, acc, str], fmt);}; + } + var padty$0 = pad[1]; + if(typeof prec === "number") + return prec + ? function + (w, p, x){ + var + str = + fix_padding + (padty$0, + w, + fix_int_precision(p, caml_call2(trans, iconv, x))); + return make_printf(k, [4, acc, str], fmt); + } + : function + (w, x){ + var str = fix_padding(padty$0, w, caml_call2(trans, iconv, x)); + return make_printf(k, [4, acc, str], fmt); + }; + var p$1 = prec[1]; + return function(w, x){ + var + str = + fix_padding + (padty$0, w, fix_int_precision(p$1, caml_call2(trans, iconv, x))); + return make_printf(k, [4, acc, str], fmt);}; + } + function make_custom$0(counter, k, acc, rest, arity, f){ + if(arity){ + var arity$0 = arity[1]; + return function(x){ + return make_custom(k, acc, rest, arity$0, caml_call1(f, x));}; + } + var _ca_ = [4, acc, f]; + if(counter >= 50) + return caml_trampoline_return(make_printf$0, [0, k, _ca_, rest]); + var counter$0 = counter + 1 | 0; + return make_printf$0(counter$0, k, _ca_, rest); + } + function make_custom(k, acc, rest, arity, f){ + return caml_trampoline(make_custom$0(0, k, acc, rest, arity, f)); + } + function make_iprintf$0(counter, k, o, fmt){ + var k$0 = k, fmt$0 = fmt; + for(;;){ + if(typeof fmt$0 === "number") return caml_call1(k$0, o); + switch(fmt$0[0]){ + case 0: + var rest = fmt$0[1], x = make_iprintf(k$0, o, rest); + return function(_b$_){return x;}; + case 1: + var rest$0 = fmt$0[1], x$0 = make_iprintf(k$0, o, rest$0); + return function(_b__){return x$0;}; + case 2: + var _bM_ = fmt$0[1]; + if(typeof _bM_ === "number"){ + var rest$1 = fmt$0[2], x$1 = make_iprintf(k$0, o, rest$1); + return function(_b9_){return x$1;}; + } + if(0 === _bM_[0]){ + var rest$2 = fmt$0[2], x$2 = make_iprintf(k$0, o, rest$2); + return function(_b8_){return x$2;}; + } + var + rest$3 = fmt$0[2], + x$3 = make_iprintf(k$0, o, rest$3), + x$4 = function(_b7_){return x$3;}; + return function(_b6_){return x$4;}; + case 3: + var _bN_ = fmt$0[1]; + if(typeof _bN_ === "number"){ + var rest$4 = fmt$0[2], x$5 = make_iprintf(k$0, o, rest$4); + return function(_b5_){return x$5;}; + } + if(0 === _bN_[0]){ + var rest$5 = fmt$0[2], x$6 = make_iprintf(k$0, o, rest$5); + return function(_b4_){return x$6;}; + } + var + rest$6 = fmt$0[2], + x$7 = make_iprintf(k$0, o, rest$6), + x$8 = function(_b3_){return x$7;}; + return function(_b2_){return x$8;}; + case 4: + var rest$7 = fmt$0[4], prec = fmt$0[3], pad = fmt$0[2]; + return fn_of_padding_precision(k$0, o, rest$7, pad, prec); + case 5: + var rest$8 = fmt$0[4], prec$0 = fmt$0[3], pad$0 = fmt$0[2]; + return fn_of_padding_precision(k$0, o, rest$8, pad$0, prec$0); + case 6: + var rest$9 = fmt$0[4], prec$1 = fmt$0[3], pad$1 = fmt$0[2]; + return fn_of_padding_precision(k$0, o, rest$9, pad$1, prec$1); + case 7: + var rest$10 = fmt$0[4], prec$2 = fmt$0[3], pad$2 = fmt$0[2]; + return fn_of_padding_precision(k$0, o, rest$10, pad$2, prec$2); + case 8: + var rest$11 = fmt$0[4], prec$3 = fmt$0[3], pad$3 = fmt$0[2]; + return fn_of_padding_precision(k$0, o, rest$11, pad$3, prec$3); + case 9: + var _bO_ = fmt$0[1]; + if(typeof _bO_ === "number"){ + var rest$12 = fmt$0[2], x$9 = make_iprintf(k$0, o, rest$12); + return function(_b1_){return x$9;}; + } + if(0 === _bO_[0]){ + var rest$13 = fmt$0[2], x$10 = make_iprintf(k$0, o, rest$13); + return function(_b0_){return x$10;}; + } + var + rest$14 = fmt$0[2], + x$11 = make_iprintf(k$0, o, rest$14), + x$12 = function(_bZ_){return x$11;}; + return function(_bY_){return x$12;}; + case 10: + var rest$15 = fmt$0[1]; fmt$0 = rest$15; break; + case 11: + var rest$16 = fmt$0[2]; fmt$0 = rest$16; break; + case 12: + var rest$17 = fmt$0[2]; fmt$0 = rest$17; break; + case 13: + var rest$18 = fmt$0[3], x$13 = make_iprintf(k$0, o, rest$18); + return function(_bX_){return x$13;}; + case 14: + var rest$19 = fmt$0[3], fmtty = fmt$0[2]; + return function(param){ + var fmt = param[1], _bW_ = recast(fmt, fmtty); + return make_iprintf + (k$0, + o, + caml_call2(CamlinternalFormatBasics[3], _bW_, rest$19));}; + case 15: + var + rest$20 = fmt$0[1], + x$14 = make_iprintf(k$0, o, rest$20), + x$15 = function(_bV_){return x$14;}; + return function(_bU_){return x$15;}; + case 16: + var rest$21 = fmt$0[1], x$16 = make_iprintf(k$0, o, rest$21); + return function(_bT_){return x$16;}; + case 17: + var rest$22 = fmt$0[2]; fmt$0 = rest$22; break; + case 18: + var _bP_ = fmt$0[1]; + if(0 === _bP_[0]){ + var rest$23 = fmt$0[2], fmt$1 = _bP_[1][1]; + let k = k$0, rest = rest$23; + var k$1 = function(koc){return make_iprintf(k, koc, rest);}; + k$0 = k$1; + fmt$0 = fmt$1; + } + else{ + var rest$24 = fmt$0[2], fmt$2 = _bP_[1][1]; + let k = k$0, rest = rest$24; + var k$2 = function(koc){return make_iprintf(k, koc, rest);}; + k$0 = k$2; + fmt$0 = fmt$2; + } + break; + case 19: + throw caml_maybe_attach_backtrace([0, Assert_failure, _w_], 1); + case 20: + var rest$25 = fmt$0[3], x$17 = make_iprintf(k$0, o, rest$25); + return function(_bS_){return x$17;}; + case 21: + var rest$26 = fmt$0[2], x$18 = make_iprintf(k$0, o, rest$26); + return function(_bR_){return x$18;}; + case 22: + var rest$27 = fmt$0[1], x$19 = make_iprintf(k$0, o, rest$27); + return function(_bQ_){return x$19;}; + case 23: + var rest$28 = fmt$0[2], ign = fmt$0[1]; + return make_ignored_param + (function(param){return caml_call1(k$0, o);}, 0, ign, rest$28); + default: + var rest$29 = fmt$0[3], arity = fmt$0[1]; + if(counter >= 50) + return caml_trampoline_return + (fn_of_custom_arity$0, [0, k$0, o, rest$29, arity]); + var counter$0 = counter + 1 | 0; + return fn_of_custom_arity$0(counter$0, k$0, o, rest$29, arity); + } + } + } + function make_iprintf(k, o, fmt){ + return caml_trampoline(make_iprintf$0(0, k, o, fmt)); + } + function fn_of_padding_precision(k, o, fmt, pad, prec){ + if(typeof pad === "number"){ + if(typeof prec !== "number"){ + var x$2 = make_iprintf(k, o, fmt); + return function(_bL_){return x$2;}; + } + if(prec){ + var x = make_iprintf(k, o, fmt), x$0 = function(_bK_){return x;}; + return function(_bJ_){return x$0;}; + } + var x$1 = make_iprintf(k, o, fmt); + return function(_bI_){return x$1;}; + } + if(0 === pad[0]){ + if(typeof prec !== "number"){ + var x$6 = make_iprintf(k, o, fmt); + return function(_bH_){return x$6;}; + } + if(prec){ + var x$3 = make_iprintf(k, o, fmt), x$4 = function(_bG_){return x$3;}; + return function(_bF_){return x$4;}; + } + var x$5 = make_iprintf(k, o, fmt); + return function(_bE_){return x$5;}; + } + if(typeof prec !== "number"){ + var x$12 = make_iprintf(k, o, fmt), x$13 = function(_bD_){return x$12;}; + return function(_bC_){return x$13;}; + } + if(prec){ + var + x$7 = make_iprintf(k, o, fmt), + x$8 = function(_bB_){return x$7;}, + x$9 = function(_bA_){return x$8;}; + return function(_bz_){return x$9;}; + } + var x$10 = make_iprintf(k, o, fmt); + function x$11(_by_){return x$10;} + return function(_bx_){return x$11;}; + } + function fn_of_custom_arity$0(counter, k, o, fmt, param){ + if(param){ + var arity = param[1], x = fn_of_custom_arity(k, o, fmt, arity); + return function(_bw_){return x;}; + } + if(counter >= 50) + return caml_trampoline_return(make_iprintf$0, [0, k, o, fmt]); + var counter$0 = counter + 1 | 0; + return make_iprintf$0(counter$0, k, o, fmt); + } + function fn_of_custom_arity(k, o, fmt, param){ + return caml_trampoline(fn_of_custom_arity$0(0, k, o, fmt, param)); + } + function output_acc(o, acc){ + var acc$0 = acc; + for(;;){ + if(typeof acc$0 === "number") return 0; + switch(acc$0[0]){ + case 0: + var + fmting_lit = acc$0[2], + p = acc$0[1], + s = string_of_formatting_lit(fmting_lit); + output_acc(o, p); + return caml_call2(Stdlib[66], o, s); + case 1: + var match = acc$0[2], p$0 = acc$0[1]; + if(0 === match[0]){ + var acc$1 = match[1]; + output_acc(o, p$0); + caml_call2(Stdlib[66], o, cst$18); + acc$0 = acc$1; + } + else{ + var acc$2 = match[1]; + output_acc(o, p$0); + caml_call2(Stdlib[66], o, cst$19); + acc$0 = acc$2; + } + break; + case 6: + var f = acc$0[2], p$3 = acc$0[1]; + output_acc(o, p$3); + return caml_call1(f, o); + case 7: + var p$4 = acc$0[1]; + output_acc(o, p$4); + return caml_call1(Stdlib[63], o); + case 8: + var msg = acc$0[2], p$5 = acc$0[1]; + output_acc(o, p$5); + return caml_call1(Stdlib[1], msg); + case 2: + case 4: + var s$0 = acc$0[2], p$1 = acc$0[1]; + output_acc(o, p$1); + return caml_call2(Stdlib[66], o, s$0); + default: + var c = acc$0[2], p$2 = acc$0[1]; + output_acc(o, p$2); + return caml_call2(Stdlib[65], o, c); + } + } + } + function bufput_acc(b, acc){ + var acc$0 = acc; + for(;;){ + if(typeof acc$0 === "number") return 0; + switch(acc$0[0]){ + case 0: + var + fmting_lit = acc$0[2], + p = acc$0[1], + s = string_of_formatting_lit(fmting_lit); + bufput_acc(b, p); + return caml_call2(Stdlib_Buffer[16], b, s); + case 1: + var match = acc$0[2], p$0 = acc$0[1]; + if(0 === match[0]){ + var acc$1 = match[1]; + bufput_acc(b, p$0); + caml_call2(Stdlib_Buffer[16], b, cst$20); + acc$0 = acc$1; + } + else{ + var acc$2 = match[1]; + bufput_acc(b, p$0); + caml_call2(Stdlib_Buffer[16], b, cst$21); + acc$0 = acc$2; + } + break; + case 6: + var f = acc$0[2], p$3 = acc$0[1]; + bufput_acc(b, p$3); + return caml_call1(f, b); + case 7: + var acc$3 = acc$0[1]; acc$0 = acc$3; break; + case 8: + var msg = acc$0[2], p$4 = acc$0[1]; + bufput_acc(b, p$4); + return caml_call1(Stdlib[1], msg); + case 2: + case 4: + var s$0 = acc$0[2], p$1 = acc$0[1]; + bufput_acc(b, p$1); + return caml_call2(Stdlib_Buffer[16], b, s$0); + default: + var c = acc$0[2], p$2 = acc$0[1]; + bufput_acc(b, p$2); + return caml_call2(Stdlib_Buffer[12], b, c); + } + } + } + function strput_acc(b, acc){ + var acc$0 = acc; + for(;;){ + if(typeof acc$0 === "number") return 0; + switch(acc$0[0]){ + case 0: + var + fmting_lit = acc$0[2], + p = acc$0[1], + s = string_of_formatting_lit(fmting_lit); + strput_acc(b, p); + return caml_call2(Stdlib_Buffer[16], b, s); + case 1: + var match = acc$0[2], p$0 = acc$0[1]; + if(0 === match[0]){ + var acc$1 = match[1]; + strput_acc(b, p$0); + caml_call2(Stdlib_Buffer[16], b, cst$22); + acc$0 = acc$1; + } + else{ + var acc$2 = match[1]; + strput_acc(b, p$0); + caml_call2(Stdlib_Buffer[16], b, cst$23); + acc$0 = acc$2; + } + break; + case 6: + var f = acc$0[2], p$3 = acc$0[1]; + strput_acc(b, p$3); + var _bv_ = caml_call1(f, 0); + return caml_call2(Stdlib_Buffer[16], b, _bv_); + case 7: + var acc$3 = acc$0[1]; acc$0 = acc$3; break; + case 8: + var msg = acc$0[2], p$4 = acc$0[1]; + strput_acc(b, p$4); + return caml_call1(Stdlib[1], msg); + case 2: + case 4: + var s$0 = acc$0[2], p$1 = acc$0[1]; + strput_acc(b, p$1); + return caml_call2(Stdlib_Buffer[16], b, s$0); + default: + var c = acc$0[2], p$2 = acc$0[1]; + strput_acc(b, p$2); + return caml_call2(Stdlib_Buffer[12], b, c); + } + } + } + function failwith_message(param){ + var fmt = param[1], buf = caml_call1(Stdlib_Buffer[1], 256); + function k(acc){ + strput_acc(buf, acc); + var _bu_ = caml_call1(Stdlib_Buffer[2], buf); + return caml_call1(Stdlib[2], _bu_); + } + return make_printf(k, 0, fmt); + } + function open_box_of_string(str){ + if(str == cst$43) return _x_; + var len = caml_ml_string_length(str); + function invalid_box(param){ + return caml_call1(failwith_message(_y_), str); + } + function parse_spaces(i){ + var i$0 = i; + for(;;){ + if(i$0 === len) return i$0; + var match = caml_string_get(str, i$0); + if(9 !== match && 32 !== match) return i$0; + var i$1 = i$0 + 1 | 0; + i$0 = i$1; + } + } + var wstart = parse_spaces(0); + a: + b: + { + var wend = wstart; + for(;;){ + if(wend === len) break b; + if(25 < caml_string_get(str, wend) - 97 >>> 0) break; + var j = wend + 1 | 0; + wend = j; + } + break a; + } + var + box_name = caml_call3(Stdlib_String[15], str, wstart, wend - wstart | 0), + nstart = parse_spaces(wend); + a: + b: + { + var nend = nstart; + for(;;){ + if(nend === len) break b; + var match = caml_string_get(str, nend); + if(48 <= match){if(58 <= match) break;} else if(45 !== match) break; + var j$0 = nend + 1 | 0; + nend = j$0; + } + break a; + } + if(nstart === nend) + var indent = 0; + else + try{ + var + _bs_ = + runtime.caml_int_of_string + (caml_call3(Stdlib_String[15], str, nstart, nend - nstart | 0)), + indent = _bs_; + } + catch(_bt_){ + var _br_ = caml_wrap_exception(_bt_); + if(_br_[1] !== Stdlib[7]) throw caml_maybe_attach_backtrace(_br_, 0); + var indent = invalid_box(0); + } + var exp_end = parse_spaces(nend); + if(exp_end !== len) invalid_box(0); + a: + { + if(box_name !== cst$43 && box_name !== "b"){ + if(box_name === "h"){var box_type = 0; break a;} + if(box_name === "hov"){var box_type = 3; break a;} + if(box_name === "hv"){var box_type = 2; break a;} + if(box_name !== "v"){var box_type = invalid_box(0); break a;} + var box_type = 1; + break a; + } + var box_type = 4; + } + return [0, indent, box_type]; + } + function make_padding_fmt_ebb(pad, fmt){ + if(typeof pad === "number") return [0, 0, fmt]; + if(0 === pad[0]){var w = pad[2], s = pad[1]; return [0, [0, s, w], fmt];} + var s$0 = pad[1]; + return [0, [1, s$0], fmt]; + } + function make_padprec_fmt_ebb(pad, prec, fmt){ + if(typeof prec === "number") + var match = prec ? [0, 1] : [0, 0]; + else + var p = prec[1], match = [0, [0, p]]; + var prec$0 = match[1]; + if(typeof pad === "number") return [0, 0, prec$0, fmt]; + if(0 === pad[0]){ + var w = pad[2], s = pad[1]; + return [0, [0, s, w], prec$0, fmt]; + } + var s$0 = pad[1]; + return [0, [1, s$0], prec$0, fmt]; + } + function fmt_ebb_of_string(legacy_behavior, str){ + if(legacy_behavior) + var flag = legacy_behavior[1], legacy_behavior$0 = flag; + else + var legacy_behavior$0 = 1; + function invalid_format_message(str_ind, msg){ + return caml_call3(failwith_message(_z_), str, str_ind, msg); + } + function invalid_format_without(str_ind, c, s){ + return caml_call4(failwith_message(_A_), str, str_ind, c, s); + } + function expected_character(str_ind, expected, read){ + return caml_call4(failwith_message(_B_), str, str_ind, expected, read); + } + function parse(lit_start, end_ind){ + a: + { + var str_ind = lit_start; + for(;;){ + if(str_ind === end_ind) return add_literal(lit_start, str_ind, 0); + var match = caml_string_get(str, str_ind); + if(37 === match) break; + if(64 === match) break a; + var str_ind$1 = str_ind + 1 | 0; + str_ind = str_ind$1; + } + var str_ind$2 = str_ind + 1 | 0; + if(str_ind$2 === end_ind) + invalid_format_message(end_ind, cst_unexpected_end_of_format); + var + match$1 = + 95 === caml_string_get(str, str_ind$2) + ? parse_flags(str_ind, str_ind$2 + 1 | 0, end_ind, 1) + : parse_flags(str_ind, str_ind$2, end_ind, 0), + fmt_rest = match$1[1]; + return add_literal(lit_start, str_ind, fmt_rest); + } + var str_ind$0 = str_ind + 1 | 0; + a: + if(str_ind$0 === end_ind) + var match$0 = _N_; + else{ + var c = caml_string_get(str, str_ind$0); + if(65 <= c){ + if(94 <= c){ + var switcher = c - 123 | 0; + if(2 >= switcher >>> 0) + switch(switcher){ + case 0: + var match$0 = parse_tag(1, str_ind$0 + 1 | 0, end_ind); break a; + case 1: break; + default: + var + fmt_rest$2 = parse(str_ind$0 + 1 | 0, end_ind)[1], + match$0 = [0, [17, 1, fmt_rest$2]]; + break a; + } + } + else if(91 <= c) + switch(c - 91 | 0){ + case 0: + var match$0 = parse_tag(0, str_ind$0 + 1 | 0, end_ind); break a; + case 1: break; + default: + var + fmt_rest$3 = parse(str_ind$0 + 1 | 0, end_ind)[1], + match$0 = [0, [17, 0, fmt_rest$3]]; + break a; + } + } + else{ + if(10 === c){ + var + fmt_rest$4 = parse(str_ind$0 + 1 | 0, end_ind)[1], + match$0 = [0, [17, 3, fmt_rest$4]]; + break a; + } + if(32 <= c) + switch(c - 32 | 0){ + case 0: + var + fmt_rest$5 = parse(str_ind$0 + 1 | 0, end_ind)[1], + match$0 = [0, [17, _O_, fmt_rest$5]]; + break a; + case 5: + if + ((str_ind$0 + 1 | 0) < end_ind + && 37 === caml_string_get(str, str_ind$0 + 1 | 0)){ + var + fmt_rest$6 = parse(str_ind$0 + 2 | 0, end_ind)[1], + match$0 = [0, [17, 6, fmt_rest$6]]; + break a; + } + var + fmt_rest$7 = parse(str_ind$0, end_ind)[1], + match$0 = [0, [12, 64, fmt_rest$7]]; + break a; + case 12: + var + fmt_rest$8 = parse(str_ind$0 + 1 | 0, end_ind)[1], + match$0 = [0, [17, _P_, fmt_rest$8]]; + break a; + case 14: + var + fmt_rest$9 = parse(str_ind$0 + 1 | 0, end_ind)[1], + match$0 = [0, [17, 4, fmt_rest$9]]; + break a; + case 27: + var str_ind$3 = str_ind$0 + 1 | 0; + b: + try{ + var + _bg_ = str_ind$3 === end_ind ? 1 : 0, + _bh_ = _bg_ || (60 !== caml_string_get(str, str_ind$3) ? 1 : 0); + if(_bh_) throw caml_maybe_attach_backtrace(Stdlib[8], 1); + var + str_ind_1 = parse_spaces(str_ind$3 + 1 | 0, end_ind), + match$2 = caml_string_get(str, str_ind_1); + c: + { + if(48 <= match$2){ + if(58 > match$2) break c; + } + else if(45 === match$2) break c; + throw caml_maybe_attach_backtrace(Stdlib[8], 1); + } + var + match$3 = parse_integer(str_ind_1, end_ind), + width = match$3[2], + str_ind_2 = match$3[1], + str_ind_3 = parse_spaces(str_ind_2, end_ind), + switcher$0 = caml_string_get(str, str_ind_3) - 45 | 0; + if(12 < switcher$0 >>> 0){ + if(17 === switcher$0){ + var + s = + caml_call3 + (Stdlib_String[15], + str, + str_ind$3 - 2 | 0, + (str_ind_3 - str_ind$3 | 0) + 3 | 0), + _bi_ = [0, s, width, 0], + _bj_ = str_ind_3 + 1 | 0, + formatting_lit$0 = _bi_, + next_ind = _bj_; + break b; + } + } + else if(1 < switcher$0 - 1 >>> 0){ + var + match$4 = parse_integer(str_ind_3, end_ind), + offset = match$4[2], + str_ind_4 = match$4[1], + str_ind_5 = parse_spaces(str_ind_4, end_ind); + if(62 !== caml_string_get(str, str_ind_5)) + throw caml_maybe_attach_backtrace(Stdlib[8], 1); + var + s$0 = + caml_call3 + (Stdlib_String[15], + str, + str_ind$3 - 2 | 0, + (str_ind_5 - str_ind$3 | 0) + 3 | 0), + _bk_ = [0, s$0, width, offset], + _bl_ = str_ind_5 + 1 | 0, + formatting_lit$0 = _bk_, + next_ind = _bl_; + break b; + } + throw caml_maybe_attach_backtrace(Stdlib[8], 1); + } + catch(_bq_){ + var _bf_ = caml_wrap_exception(_bq_); + if(_bf_ !== Stdlib[8] && _bf_[1] !== Stdlib[7]) + throw caml_maybe_attach_backtrace(_bf_, 0); + var formatting_lit$0 = formatting_lit, next_ind = str_ind$3; + } + var + fmt_rest$12 = parse(next_ind, end_ind)[1], + match$0 = [0, [17, formatting_lit$0, fmt_rest$12]]; + break a; + case 28: + var str_ind$4 = str_ind$0 + 1 | 0; + try{ + var + str_ind_1$0 = parse_spaces(str_ind$4, end_ind), + match$6 = caml_string_get(str, str_ind_1$0); + b: + { + c: + { + if(48 <= match$6){ + if(58 > match$6) break c; + } + else if(45 === match$6) break c; + var _bo_ = 0; + break b; + } + var + match$7 = parse_integer(str_ind_1$0, end_ind), + size = match$7[2], + str_ind_2$0 = match$7[1], + str_ind_3$0 = parse_spaces(str_ind_2$0, end_ind); + if(62 !== caml_string_get(str, str_ind_3$0)) + throw caml_maybe_attach_backtrace(Stdlib[8], 1); + var + s$1 = + caml_call3 + (Stdlib_String[15], + str, + str_ind$4 - 2 | 0, + (str_ind_3$0 - str_ind$4 | 0) + 3 | 0), + _bo_ = [0, [0, str_ind_3$0 + 1 | 0, [1, s$1, size]]]; + } + var _bn_ = _bo_; + } + catch(_bp_){ + var _bm_ = caml_wrap_exception(_bp_); + if(_bm_ !== Stdlib[8] && _bm_[1] !== Stdlib[7]) + throw caml_maybe_attach_backtrace(_bm_, 0); + var _bn_ = 0; + } + if(_bn_) + var + match$5 = _bn_[1], + formatting_lit$1 = match$5[2], + next_ind$0 = match$5[1], + fmt_rest$13 = parse(next_ind$0, end_ind)[1], + _be_ = [0, [17, formatting_lit$1, fmt_rest$13]]; + else + var + fmt_rest$14 = parse(str_ind$4, end_ind)[1], + _be_ = [0, [17, _Q_, fmt_rest$14]]; + var match$0 = _be_; + break a; + case 31: + var + fmt_rest$10 = parse(str_ind$0 + 1 | 0, end_ind)[1], + match$0 = [0, [17, 2, fmt_rest$10]]; + break a; + case 32: + var + fmt_rest$11 = parse(str_ind$0 + 1 | 0, end_ind)[1], + match$0 = [0, [17, 5, fmt_rest$11]]; + break a; + } + } + var + fmt_rest$1 = parse(str_ind$0 + 1 | 0, end_ind)[1], + match$0 = [0, [17, [2, c], fmt_rest$1]]; + } + var fmt_rest$0 = match$0[1]; + return add_literal(lit_start, str_ind, fmt_rest$0); + } + function parse_flags(pct_ind, str_ind, end_ind, ign){ + var + zero = [0, 0], + minus = [0, 0], + plus = [0, 0], + space = [0, 0], + hash = [0, 0]; + function set_flag(str_ind, flag){ + var _bb_ = flag[1], _bc_ = _bb_ ? 1 - legacy_behavior$0 : _bb_; + if(_bc_){ + var _bd_ = caml_string_get(str, str_ind); + caml_call3(failwith_message(_C_), str, str_ind, _bd_); + } + flag[1] = 1; + return; + } + a: + b: + { + var str_ind$0 = str_ind; + c: + for(;;){ + if(str_ind$0 === end_ind) + invalid_format_message(end_ind, cst_unexpected_end_of_format); + var switcher = caml_string_get(str, str_ind$0) - 32 | 0; + if(16 < switcher >>> 0) break b; + switch(switcher){ + case 0: + set_flag(str_ind$0, space); + var str_ind$1 = str_ind$0 + 1 | 0; + str_ind$0 = str_ind$1; + break; + case 3: + set_flag(str_ind$0, hash); + var str_ind$2 = str_ind$0 + 1 | 0; + str_ind$0 = str_ind$2; + break; + case 11: + set_flag(str_ind$0, plus); + var str_ind$3 = str_ind$0 + 1 | 0; + str_ind$0 = str_ind$3; + break; + case 13: + set_flag(str_ind$0, minus); + var str_ind$4 = str_ind$0 + 1 | 0; + str_ind$0 = str_ind$4; + break; + case 16: + set_flag(str_ind$0, zero); + var str_ind$5 = str_ind$0 + 1 | 0; + str_ind$0 = str_ind$5; + break; + default: break c; + } + } + break a; + } + var + space$0 = space[1], + hash$0 = hash[1], + plus$0 = plus[1], + minus$0 = minus[1], + zero$0 = zero[1]; + if(str_ind$0 === end_ind) + invalid_format_message(end_ind, cst_unexpected_end_of_format); + var + padty = + zero$0 + ? minus$0 + ? legacy_behavior$0 + ? 0 + : incompatible_flag(pct_ind, str_ind$0, 45, cst_0) + : 2 + : minus$0 ? 0 : 1, + match = caml_string_get(str, str_ind$0); + if(48 <= match){ + if(58 > match){ + var + match$0 = parse_positive(str_ind$0, end_ind, 0), + width = match$0[2], + new_ind = match$0[1]; + return parse_after_padding + (pct_ind, + new_ind, + end_ind, + minus$0, + plus$0, + hash$0, + space$0, + ign, + [0, padty, width]); + } + } + else if(42 === match) + return parse_after_padding + (pct_ind, + str_ind$0 + 1 | 0, + end_ind, + minus$0, + plus$0, + hash$0, + space$0, + ign, + [1, padty]); + switch(padty){ + case 0: + if(1 - legacy_behavior$0) + invalid_format_without(str_ind$0 - 1 | 0, 45, cst_padding); + return parse_after_padding + (pct_ind, + str_ind$0, + end_ind, + minus$0, + plus$0, + hash$0, + space$0, + ign, + 0); + case 1: + return parse_after_padding + (pct_ind, + str_ind$0, + end_ind, + minus$0, + plus$0, + hash$0, + space$0, + ign, + 0); + default: + return parse_after_padding + (pct_ind, + str_ind$0, + end_ind, + minus$0, + plus$0, + hash$0, + space$0, + ign, + _D_); + } + } + function parse_after_padding + (pct_ind, str_ind, end_ind, minus, plus, hash, space, ign, pad){ + if(str_ind === end_ind) + invalid_format_message(end_ind, cst_unexpected_end_of_format); + var symb = caml_string_get(str, str_ind); + if(46 !== symb) + return parse_conversion + (pct_ind, + str_ind + 1 | 0, + end_ind, + plus, + hash, + space, + ign, + pad, + 0, + pad, + symb); + var str_ind$0 = str_ind + 1 | 0; + if(str_ind$0 === end_ind) + invalid_format_message(end_ind, cst_unexpected_end_of_format); + function parse_literal(minus, str_ind){ + var + match = parse_positive(str_ind, end_ind, 0), + prec = match[2], + new_ind = match[1]; + return parse_after_precision + (pct_ind, + new_ind, + end_ind, + minus, + plus, + hash, + space, + ign, + pad, + [0, prec]); + } + var symb$0 = caml_string_get(str, str_ind$0); + if(48 <= symb$0){ + if(58 > symb$0) return parse_literal(minus, str_ind$0); + } + else if(42 <= symb$0) + switch(symb$0 - 42 | 0){ + case 0: + return parse_after_precision + (pct_ind, + str_ind$0 + 1 | 0, + end_ind, + minus, + plus, + hash, + space, + ign, + pad, + 1); + case 1: + case 3: + if(legacy_behavior$0){ + var + _ba_ = str_ind$0 + 1 | 0, + minus$0 = minus || (45 === symb$0 ? 1 : 0); + return parse_literal(minus$0, _ba_); + } + break; + } + return legacy_behavior$0 + ? parse_after_precision + (pct_ind, + str_ind$0, + end_ind, + minus, + plus, + hash, + space, + ign, + pad, + _E_) + : invalid_format_without(str_ind$0 - 1 | 0, 46, cst_precision); + } + function parse_after_precision + (pct_ind, str_ind, end_ind, minus, plus, hash, space, ign, pad, prec){ + if(str_ind === end_ind) + invalid_format_message(end_ind, cst_unexpected_end_of_format); + function parse_conv(padprec){ + return parse_conversion + (pct_ind, + str_ind + 1 | 0, + end_ind, + plus, + hash, + space, + ign, + pad, + prec, + padprec, + caml_string_get(str, str_ind)); + } + if(typeof pad !== "number") return parse_conv(pad); + if(typeof prec === "number" && ! prec) return parse_conv(0); + if(minus){ + if(typeof prec === "number") return parse_conv(_F_); + var n = prec[1]; + return parse_conv([0, 0, n]); + } + if(typeof prec === "number") return parse_conv(_G_); + var n$0 = prec[1]; + return parse_conv([0, 1, n$0]); + } + function parse_conversion + (pct_ind, + str_ind, + end_ind, + plus, + hash, + space, + ign, + pad, + prec, + padprec, + symb){ + var + plus_used = [0, 0], + hash_used = [0, 0], + space_used = [0, 0], + ign_used = [0, 0], + pad_used = [0, 0], + prec_used = [0, 0]; + function get_plus(param){plus_used[1] = 1; return plus;} + function get_hash(param){hash_used[1] = 1; return hash;} + function get_space(param){space_used[1] = 1; return space;} + function get_ign(param){ign_used[1] = 1; return ign;} + function get_pad(param){pad_used[1] = 1; return pad;} + function get_prec(param){prec_used[1] = 1; return prec;} + function get_padprec(param){pad_used[1] = 1; return padprec;} + function get_int_pad(param){ + var pad = get_pad(0), match = get_prec(0); + if(typeof match === "number" && ! match) return pad; + if(typeof pad === "number") return 0; + if(0 !== pad[0]) + return 2 <= pad[1] + ? legacy_behavior$0 + ? _H_ + : incompatible_flag(pct_ind, str_ind, 48, cst_precision$1) + : pad; + if(2 > pad[1]) return pad; + var n = pad[2]; + return legacy_behavior$0 + ? [0, 1, n] + : incompatible_flag(pct_ind, str_ind, 48, cst_precision$0); + } + function check_no_0(symb, pad){ + if(typeof pad === "number") return pad; + if(0 !== pad[0]) + return 2 <= pad[1] + ? legacy_behavior$0 + ? _I_ + : incompatible_flag(pct_ind, str_ind, symb, cst_0$1) + : pad; + if(2 > pad[1]) return pad; + var width = pad[2]; + return legacy_behavior$0 + ? [0, 1, width] + : incompatible_flag(pct_ind, str_ind, symb, cst_0$0); + } + function opt_of_pad(c, pad){ + if(typeof pad === "number") return 0; + if(0 === pad[0]) + switch(pad[1]){ + case 0: + var width = pad[2]; + return legacy_behavior$0 + ? [0, width] + : incompatible_flag(pct_ind, str_ind, c, cst$24); + case 1: + var width$0 = pad[2]; return [0, width$0]; + default: + var width$1 = pad[2]; + return legacy_behavior$0 + ? [0, width$1] + : incompatible_flag(pct_ind, str_ind, c, cst_0$2); + } + return incompatible_flag(pct_ind, str_ind, c, cst$25); + } + function get_pad_opt(c){return opt_of_pad(c, get_pad(0));} + function get_padprec_opt(c){return opt_of_pad(c, get_padprec(0));} + a: + { + if(124 > symb) + switch(symb){ + case 33: + var + fmt_rest$5 = parse(str_ind, end_ind)[1], + fmt_result = [0, [10, fmt_rest$5]]; + break a; + case 40: + var + sub_end = search_subformat_end(str_ind, end_ind, 41), + fmt_rest$7 = parse(sub_end + 2 | 0, end_ind)[1], + sub_fmt = parse(str_ind, sub_end)[1], + sub_fmtty = fmtty_of_fmt(sub_fmt); + if(get_ign(0)) + var + ignored$2 = [9, get_pad_opt(95), sub_fmtty], + _aJ_ = [0, [23, ignored$2, fmt_rest$7]]; + else + var _aJ_ = [0, [14, get_pad_opt(40), sub_fmtty, fmt_rest$7]]; + var fmt_result = _aJ_; + break a; + case 44: + var fmt_result = parse(str_ind, end_ind); break a; + case 67: + var + fmt_rest$10 = parse(str_ind, end_ind)[1], + _aL_ = + get_ign(0) ? [0, [23, 1, fmt_rest$10]] : [0, [1, fmt_rest$10]], + fmt_result = _aL_; + break a; + case 78: + var fmt_rest$14 = parse(str_ind, end_ind)[1], counter$0 = 2; + if(get_ign(0)) + var + ignored$6 = [11, counter$0], + _aR_ = [0, [23, ignored$6, fmt_rest$14]]; + else + var _aR_ = [0, [21, counter$0, fmt_rest$14]]; + var fmt_result = _aR_; + break a; + case 83: + var + pad$6 = check_no_0(symb, get_padprec(0)), + fmt_rest$15 = parse(str_ind, end_ind)[1]; + if(get_ign(0)) + var + ignored$7 = [1, get_padprec_opt(95)], + _aS_ = [0, [23, ignored$7, fmt_rest$15]]; + else + var + match$5 = make_padding_fmt_ebb(pad$6, fmt_rest$15), + fmt_rest$16 = match$5[2], + pad$7 = match$5[1], + _aS_ = [0, [3, pad$7, fmt_rest$16]]; + var fmt_result = _aS_; + break a; + case 91: + if(str_ind === end_ind) + invalid_format_message(end_ind, cst_unexpected_end_of_format); + var + char_set = create_char_set(0), + add_range = + function(c$0, c){ + if(c >= c$0){ + var i = c$0; + for(;;){ + add_in_char_set(char_set, caml_call1(Stdlib[29], i)); + var _a$_ = i + 1 | 0; + if(c === i) break; + i = _a$_; + } + } + return; + }, + fail_single_percent = + function(str_ind){ + return caml_call2(failwith_message(_R_), str, str_ind); + }, + parse_char_set_content = + function(counter, str_ind, end_ind){ + var str_ind$0 = str_ind; + for(;;){ + if(str_ind$0 === end_ind) + invalid_format_message(end_ind, cst_unexpected_end_of_format); + var c = caml_string_get(str, str_ind$0); + if(45 !== c){ + if(93 === c) return str_ind$0 + 1 | 0; + var _a__ = str_ind$0 + 1 | 0; + if(counter >= 50) + return caml_trampoline_return + (parse_char_set_after_char$0, [0, _a__, end_ind, c]); + var counter$0 = counter + 1 | 0; + return parse_char_set_after_char$0 + (counter$0, _a__, end_ind, c); + } + add_in_char_set(char_set, 45); + var str_ind$1 = str_ind$0 + 1 | 0; + str_ind$0 = str_ind$1; + } + }, + parse_char_set_after_char$0 = + function(counter, str_ind, end_ind, c){ + var str_ind$0 = str_ind, c$0 = c; + for(;;){ + if(str_ind$0 === end_ind) + invalid_format_message(end_ind, cst_unexpected_end_of_format); + var c$1 = caml_string_get(str, str_ind$0); + a: + { + if(46 <= c$1){ + if(64 !== c$1){ + if(93 !== c$1) break a; + add_in_char_set(char_set, c$0); + return str_ind$0 + 1 | 0; + } + } + else if(37 !== c$1){ + if(45 > c$1) break a; + var str_ind$2 = str_ind$0 + 1 | 0; + if(str_ind$2 === end_ind) + invalid_format_message + (end_ind, cst_unexpected_end_of_format); + var c$2 = caml_string_get(str, str_ind$2); + if(37 === c$2){ + if((str_ind$2 + 1 | 0) === end_ind) + invalid_format_message + (end_ind, cst_unexpected_end_of_format); + var c$3 = caml_string_get(str, str_ind$2 + 1 | 0); + if(37 !== c$3 && 64 !== c$3) + return fail_single_percent(str_ind$2); + add_range(c$0, c$3); + var _a8_ = str_ind$2 + 2 | 0; + if(counter >= 50) + return caml_trampoline_return + (parse_char_set_content, [0, _a8_, end_ind]); + var counter$1 = counter + 1 | 0; + return parse_char_set_content(counter$1, _a8_, end_ind); + } + if(93 === c$2){ + add_in_char_set(char_set, c$0); + add_in_char_set(char_set, 45); + return str_ind$2 + 1 | 0; + } + add_range(c$0, c$2); + var _a9_ = str_ind$2 + 1 | 0; + if(counter >= 50) + return caml_trampoline_return + (parse_char_set_content, [0, _a9_, end_ind]); + var counter$0 = counter + 1 | 0; + return parse_char_set_content(counter$0, _a9_, end_ind); + } + if(37 === c$0){ + add_in_char_set(char_set, c$1); + var _a7_ = str_ind$0 + 1 | 0; + if(counter >= 50) + return caml_trampoline_return + (parse_char_set_content, [0, _a7_, end_ind]); + var counter$2 = counter + 1 | 0; + return parse_char_set_content(counter$2, _a7_, end_ind); + } + } + if(37 === c$0) fail_single_percent(str_ind$0); + add_in_char_set(char_set, c$0); + var str_ind$1 = str_ind$0 + 1 | 0; + str_ind$0 = str_ind$1; + c$0 = c$1; + } + }, + parse_char_set_after_char = + function(str_ind, end_ind, c){ + return caml_trampoline + (parse_char_set_after_char$0(0, str_ind, end_ind, c)); + }; + if(str_ind === end_ind) + invalid_format_message(end_ind, cst_unexpected_end_of_format); + if(94 === caml_string_get(str, str_ind)) + var + str_ind$0 = str_ind + 1 | 0, + reverse = 1, + str_ind$1 = str_ind$0; + else + var reverse = 0, str_ind$1 = str_ind; + if(str_ind$1 === end_ind) + invalid_format_message(end_ind, cst_unexpected_end_of_format); + var + c = caml_string_get(str, str_ind$1), + next_ind = parse_char_set_after_char(str_ind$1 + 1 | 0, end_ind, c), + char_set$0 = freeze_char_set(char_set), + char_set$1 = reverse ? rev_char_set(char_set$0) : char_set$0, + fmt_rest$19 = parse(next_ind, end_ind)[1]; + if(get_ign(0)) + var + ignored$9 = [10, get_pad_opt(95), char_set$1], + _aX_ = [0, [23, ignored$9, fmt_rest$19]]; + else + var _aX_ = [0, [20, get_pad_opt(91), char_set$1, fmt_rest$19]]; + var fmt_result = _aX_; + break a; + case 97: + var + fmt_rest$20 = parse(str_ind, end_ind)[1], + fmt_result = [0, [15, fmt_rest$20]]; + break a; + case 99: + var + char_format = + function(fmt_rest){ + return get_ign(0) ? [0, [23, 0, fmt_rest]] : [0, [0, fmt_rest]]; + }, + fmt_rest$21 = parse(str_ind, end_ind)[1], + match$7 = get_pad_opt(99); + if(match$7){ + if(0 === match$7[1]) + var + _aY_ = + get_ign(0) ? [0, [23, 3, fmt_rest$21]] : [0, [22, fmt_rest$21]], + _aZ_ = _aY_; + else + var + _aZ_ = + legacy_behavior$0 + ? char_format(fmt_rest$21) + : invalid_format_message + (str_ind, cst_non_zero_widths_are_unsupp); + var _a0_ = _aZ_; + } + else + var _a0_ = char_format(fmt_rest$21); + var fmt_result = _a0_; + break a; + case 114: + var + fmt_rest$22 = parse(str_ind, end_ind)[1], + _a1_ = + get_ign(0) ? [0, [23, 2, fmt_rest$22]] : [0, [19, fmt_rest$22]], + fmt_result = _a1_; + break a; + case 115: + var + pad$9 = check_no_0(symb, get_padprec(0)), + fmt_rest$23 = parse(str_ind, end_ind)[1]; + if(get_ign(0)) + var + ignored$10 = [0, get_padprec_opt(95)], + _a2_ = [0, [23, ignored$10, fmt_rest$23]]; + else + var + match$8 = make_padding_fmt_ebb(pad$9, fmt_rest$23), + fmt_rest$24 = match$8[2], + pad$10 = match$8[1], + _a2_ = [0, [2, pad$10, fmt_rest$24]]; + var fmt_result = _a2_; + break a; + case 116: + var + fmt_rest$25 = parse(str_ind, end_ind)[1], + fmt_result = [0, [16, fmt_rest$25]]; + break a; + case 123: + var + sub_end$0 = search_subformat_end(str_ind, end_ind, 125), + sub_fmt$0 = parse(str_ind, sub_end$0)[1], + fmt_rest$26 = parse(sub_end$0 + 2 | 0, end_ind)[1], + sub_fmtty$0 = fmtty_of_fmt(sub_fmt$0); + if(get_ign(0)) + var + ignored$11 = [8, get_pad_opt(95), sub_fmtty$0], + _a3_ = [0, [23, ignored$11, fmt_rest$26]]; + else + var _a3_ = [0, [13, get_pad_opt(123), sub_fmtty$0, fmt_rest$26]]; + var fmt_result = _a3_; + break a; + case 66: + case 98: + var + pad$3 = check_no_0(symb, get_padprec(0)), + fmt_rest$8 = parse(str_ind, end_ind)[1]; + if(get_ign(0)) + var + ignored$3 = [7, get_padprec_opt(95)], + _aK_ = [0, [23, ignored$3, fmt_rest$8]]; + else + var + match$3 = make_padding_fmt_ebb(pad$3, fmt_rest$8), + fmt_rest$9 = match$3[2], + pad$4 = match$3[1], + _aK_ = [0, [9, pad$4, fmt_rest$9]]; + var fmt_result = _aK_; + break a; + case 37: + case 64: + var + fmt_rest$6 = parse(str_ind, end_ind)[1], + fmt_result = [0, [12, symb, fmt_rest$6]]; + break a; + case 76: + case 108: + case 110: + if(str_ind !== end_ind){ + var symb$0 = caml_string_get(str, str_ind), _a4_ = symb$0 - 88 | 0; + b: + { + if(32 >= _a4_ >>> 0) + switch(_a4_){ + case 0: + case 12: + case 17: + case 23: + case 29: + case 32: + var _aQ_ = 1; break b; + } + var _aQ_ = 0; + } + if(_aQ_) break; + } + var fmt_rest$13 = parse(str_ind, end_ind)[1]; + b: + { + if(108 <= symb){ + if(111 > symb) + switch(symb - 108 | 0){ + case 0: + var counter = 0; break b; + case 1: break; + default: var counter = 1; break b; + } + } + else if(76 === symb){var counter = 2; break b;} + throw caml_maybe_attach_backtrace([0, Assert_failure, _V_], 1); + } + if(get_ign(0)) + var + ignored$5 = [11, counter], + _aP_ = [0, [23, ignored$5, fmt_rest$13]]; + else + var _aP_ = [0, [21, counter, fmt_rest$13]]; + var fmt_result = _aP_; + break a; + case 32: + case 35: + case 43: + case 45: + case 95: + var + fmt_result = caml_call3(failwith_message(_M_), str, pct_ind, symb); + break a; + case 88: + case 100: + case 105: + case 111: + case 117: + case 120: + var + _aT_ = get_space(0), + _aU_ = get_hash(0), + iconv$2 = + compute_int_conv(pct_ind, str_ind, get_plus(0), _aU_, _aT_, symb), + fmt_rest$17 = parse(str_ind, end_ind)[1]; + if(get_ign(0)) + var + ignored$8 = [2, iconv$2, get_pad_opt(95)], + _aV_ = [0, [23, ignored$8, fmt_rest$17]]; + else + var + _aW_ = get_prec(0), + match$6 = make_padprec_fmt_ebb(get_int_pad(0), _aW_, fmt_rest$17), + fmt_rest$18 = match$6[3], + prec$4 = match$6[2], + pad$8 = match$6[1], + _aV_ = [0, [4, iconv$2, pad$8, prec$4, fmt_rest$18]]; + var fmt_result = _aV_; + break a; + case 69: + case 70: + case 71: + case 72: + case 101: + case 102: + case 103: + case 104: + var + space$1 = get_space(0), + hash$1 = get_hash(0), + plus$2 = get_plus(0), + flag = + plus$2 + ? space$1 + ? legacy_behavior$0 + ? 1 + : incompatible_flag(pct_ind, str_ind, 32, cst$36) + : 1 + : space$1 ? 2 : 0; + b: + { + c: + if(73 <= symb){ + var switcher = symb - 101 | 0; + if(3 >= switcher >>> 0){ + switch(switcher){ + case 0: + var _a5_ = 1; break; + case 1: + var _a5_ = 0; break; + case 2: + var _a5_ = 3; break; + default: var _a5_ = 6; + } + var kind = _a5_; + break b; + } + } + else if(69 <= symb){ + switch(symb - 69 | 0){ + case 0: + var _a6_ = 2; break; + case 1: + break c; + case 2: + var _a6_ = 4; break; + default: var _a6_ = 7; + } + var kind = _a6_; + break b; + } + if(hash$1){ + if(70 === symb){var kind = 8; break b;} + } + else if(70 === symb){var kind = 5; break b;} + throw caml_maybe_attach_backtrace([0, Assert_failure, _X_], 1); + } + var + fconv = [0, flag, kind], + fmt_rest$11 = parse(str_ind, end_ind)[1]; + if(get_ign(0)){ + var match = get_prec(0); + if(typeof match === "number") + var + _aM_ = + match ? incompatible_flag(pct_ind, str_ind, 95, cst$26) : 0; + else + var ndec = match[1], _aM_ = [0, ndec]; + var + ignored$4 = [6, get_pad_opt(95), _aM_], + _aN_ = [0, [23, ignored$4, fmt_rest$11]]; + } + else + var + _aO_ = get_prec(0), + match$4 = make_padprec_fmt_ebb(get_pad(0), _aO_, fmt_rest$11), + fmt_rest$12 = match$4[3], + prec$3 = match$4[2], + pad$5 = match$4[1], + _aN_ = [0, [8, fconv, pad$5, prec$3, fmt_rest$12]]; + var fmt_result = _aN_; + break a; + } + b: + if(108 <= symb){ + if(111 > symb){ + switch(symb - 108 | 0){ + case 0: + var + _at_ = caml_string_get(str, str_ind), + _au_ = get_space(0), + _av_ = get_hash(0), + iconv = + compute_int_conv + (pct_ind, str_ind + 1 | 0, get_plus(0), _av_, _au_, _at_), + fmt_rest = parse(str_ind + 1 | 0, end_ind)[1]; + if(get_ign(0)) + var + ignored = [3, iconv, get_pad_opt(95)], + _aw_ = [0, [23, ignored, fmt_rest]]; + else + var + _ay_ = get_prec(0), + match$0 = make_padprec_fmt_ebb(get_int_pad(0), _ay_, fmt_rest), + fmt_rest$0 = match$0[3], + prec$0 = match$0[2], + pad$0 = match$0[1], + _aw_ = [0, [5, iconv, pad$0, prec$0, fmt_rest$0]]; + var _ax_ = _aw_; + break; + case 1: + break b; + default: + var + _az_ = caml_string_get(str, str_ind), + _aA_ = get_space(0), + _aB_ = get_hash(0), + iconv$0 = + compute_int_conv + (pct_ind, str_ind + 1 | 0, get_plus(0), _aB_, _aA_, _az_), + fmt_rest$1 = parse(str_ind + 1 | 0, end_ind)[1]; + if(get_ign(0)) + var + ignored$0 = [4, iconv$0, get_pad_opt(95)], + _aC_ = [0, [23, ignored$0, fmt_rest$1]]; + else + var + _aD_ = get_prec(0), + match$1 = make_padprec_fmt_ebb(get_int_pad(0), _aD_, fmt_rest$1), + fmt_rest$2 = match$1[3], + prec$1 = match$1[2], + pad$1 = match$1[1], + _aC_ = [0, [6, iconv$0, pad$1, prec$1, fmt_rest$2]]; + var _ax_ = _aC_; + } + var fmt_result = _ax_; + break a; + } + } + else if(76 === symb){ + var + _aE_ = caml_string_get(str, str_ind), + _aF_ = get_space(0), + _aG_ = get_hash(0), + iconv$1 = + compute_int_conv + (pct_ind, str_ind + 1 | 0, get_plus(0), _aG_, _aF_, _aE_), + fmt_rest$3 = parse(str_ind + 1 | 0, end_ind)[1]; + if(get_ign(0)) + var + ignored$1 = [5, iconv$1, get_pad_opt(95)], + _aH_ = [0, [23, ignored$1, fmt_rest$3]]; + else + var + _aI_ = get_prec(0), + match$2 = make_padprec_fmt_ebb(get_int_pad(0), _aI_, fmt_rest$3), + fmt_rest$4 = match$2[3], + prec$2 = match$2[2], + pad$2 = match$2[1], + _aH_ = [0, [7, iconv$1, pad$2, prec$2, fmt_rest$4]]; + var fmt_result = _aH_; + break a; + } + var + fmt_result = + caml_call3(failwith_message(_J_), str, str_ind - 1 | 0, symb); + } + if(1 - legacy_behavior$0){ + var _ak_ = 1 - plus_used[1], plus$0 = _ak_ ? plus : _ak_; + if(plus$0) incompatible_flag(pct_ind, str_ind, symb, cst$27); + var _al_ = 1 - hash_used[1], hash$0 = _al_ ? hash : _al_; + if(hash$0) incompatible_flag(pct_ind, str_ind, symb, cst$28); + var _am_ = 1 - space_used[1], space$0 = _am_ ? space : _am_; + if(space$0) incompatible_flag(pct_ind, str_ind, symb, cst$29); + var + _an_ = 1 - pad_used[1], + _ao_ = _an_ ? caml_notequal([0, pad], _K_) : _an_; + if(_ao_) incompatible_flag(pct_ind, str_ind, symb, cst_padding$0); + var + _ap_ = 1 - prec_used[1], + _aq_ = _ap_ ? caml_notequal([0, prec], _L_) : _ap_; + if(_aq_){ + var _ar_ = ign ? 95 : symb; + incompatible_flag(pct_ind, str_ind, _ar_, cst_precision$2); + } + var plus$1 = ign ? plus : ign; + if(plus$1) incompatible_flag(pct_ind, str_ind, 95, cst$30); + } + var _as_ = 1 - ign_used[1], ign$0 = _as_ ? ign : _as_; + a: + if(ign$0){ + b: + { + if(38 <= symb){ + if(44 !== symb && 64 !== symb) break b; + } + else if(33 !== symb && 37 > symb) break b; + if(legacy_behavior$0) break a; + } + incompatible_flag(pct_ind, str_ind, symb, cst$31); + } + return fmt_result; + } + function parse_tag(is_open_tag, str_ind, end_ind){ + try{ + if(str_ind === end_ind) throw caml_maybe_attach_backtrace(Stdlib[8], 1); + if(60 !== caml_string_get(str, str_ind)) + throw caml_maybe_attach_backtrace(Stdlib[8], 1); + var ind = caml_call3(Stdlib_String[31], str, str_ind + 1 | 0, 62); + if(end_ind <= ind) throw caml_maybe_attach_backtrace(Stdlib[8], 1); + var + sub_str = + caml_call3 + (Stdlib_String[15], str, str_ind, (ind - str_ind | 0) + 1 | 0), + fmt_rest$0 = parse(ind + 1 | 0, end_ind)[1], + sub_fmt = parse(str_ind, ind + 1 | 0)[1], + sub_format$0 = [0, sub_fmt, sub_str], + formatting$0 = is_open_tag ? [0, sub_format$0] : [1, sub_format$0], + _ai_ = [0, [18, formatting$0, fmt_rest$0]]; + return _ai_; + } + catch(_aj_){ + var _ah_ = caml_wrap_exception(_aj_); + if(_ah_ !== Stdlib[8]) throw caml_maybe_attach_backtrace(_ah_, 0); + var + fmt_rest = parse(str_ind, end_ind)[1], + formatting = is_open_tag ? [0, sub_format] : [1, sub_format]; + return [0, [18, formatting, fmt_rest]]; + } + } + function parse_spaces(str_ind, end_ind){ + var str_ind$0 = str_ind; + for(;;){ + if(str_ind$0 === end_ind) + invalid_format_message(end_ind, cst_unexpected_end_of_format); + if(32 !== caml_string_get(str, str_ind$0)) return str_ind$0; + var str_ind$1 = str_ind$0 + 1 | 0; + str_ind$0 = str_ind$1; + } + } + function parse_positive(str_ind, end_ind, acc){ + var str_ind$0 = str_ind, acc$0 = acc; + for(;;){ + if(str_ind$0 === end_ind) + invalid_format_message(end_ind, cst_unexpected_end_of_format); + var c = caml_string_get(str, str_ind$0); + if(9 < c - 48 >>> 0) return [0, str_ind$0, acc$0]; + var new_acc = (acc$0 * 10 | 0) + (c - 48 | 0) | 0; + if(Stdlib_Sys[12] < new_acc){ + var _ag_ = Stdlib_Sys[12]; + return caml_call3(failwith_message(_S_), str, new_acc, _ag_); + } + var str_ind$1 = str_ind$0 + 1 | 0; + str_ind$0 = str_ind$1; + acc$0 = new_acc; + } + } + function parse_integer(str_ind, end_ind){ + if(str_ind === end_ind) + invalid_format_message(end_ind, cst_unexpected_end_of_format); + var match = caml_string_get(str, str_ind); + if(48 <= match){ + if(58 > match) return parse_positive(str_ind, end_ind, 0); + } + else if(45 === match){ + if((str_ind + 1 | 0) === end_ind) + invalid_format_message(end_ind, cst_unexpected_end_of_format); + var c = caml_string_get(str, str_ind + 1 | 0); + if(9 < c - 48 >>> 0) + return expected_character(str_ind + 1 | 0, cst_digit, c); + var + match$0 = parse_positive(str_ind + 1 | 0, end_ind, 0), + n = match$0[2], + next_ind = match$0[1]; + return [0, next_ind, - n | 0]; + } + throw caml_maybe_attach_backtrace([0, Assert_failure, _T_], 1); + } + function add_literal(lit_start, str_ind, fmt){ + var size = str_ind - lit_start | 0; + return 0 === size + ? [0, fmt] + : 1 + === size + ? [0, [12, caml_string_get(str, lit_start), fmt]] + : [0, + [11, + caml_call3(Stdlib_String[15], str, lit_start, size), + fmt]]; + } + function search_subformat_end(str_ind, end_ind, c){ + var str_ind$0 = str_ind; + for(;;){ + if(str_ind$0 === end_ind) + caml_call3(failwith_message(_U_), str, c, end_ind); + if(37 === caml_string_get(str, str_ind$0)){ + if((str_ind$0 + 1 | 0) === end_ind) + invalid_format_message(end_ind, cst_unexpected_end_of_format); + if(caml_string_get(str, str_ind$0 + 1 | 0) === c) return str_ind$0; + var match = caml_string_get(str, str_ind$0 + 1 | 0); + if(95 <= match){ + if(123 <= match){ + if(126 > match) + switch(match - 123 | 0){ + case 0: + var + sub_end = search_subformat_end(str_ind$0 + 2 | 0, end_ind, 125), + str_ind$2 = sub_end + 2 | 0; + str_ind$0 = str_ind$2; + continue; + case 1: break; + default: + return expected_character(str_ind$0 + 1 | 0, cst_character, 125); + } + } + else if(96 > match){ + if((str_ind$0 + 2 | 0) === end_ind) + invalid_format_message(end_ind, cst_unexpected_end_of_format); + var match$0 = caml_string_get(str, str_ind$0 + 2 | 0); + if(40 === match$0){ + var + sub_end$0 = search_subformat_end(str_ind$0 + 3 | 0, end_ind, 41), + str_ind$3 = sub_end$0 + 2 | 0; + str_ind$0 = str_ind$3; + continue; + } + if(123 === match$0){ + var + sub_end$1 = search_subformat_end(str_ind$0 + 3 | 0, end_ind, 125), + str_ind$4 = sub_end$1 + 2 | 0; + str_ind$0 = str_ind$4; + continue; + } + var str_ind$5 = str_ind$0 + 3 | 0; + str_ind$0 = str_ind$5; + continue; + } + } + else{ + if(40 === match){ + var + sub_end$2 = search_subformat_end(str_ind$0 + 2 | 0, end_ind, 41), + str_ind$6 = sub_end$2 + 2 | 0; + str_ind$0 = str_ind$6; + continue; + } + if(41 === match) + return expected_character(str_ind$0 + 1 | 0, cst_character$0, 41); + } + var str_ind$1 = str_ind$0 + 2 | 0; + str_ind$0 = str_ind$1; + } + else{var str_ind$7 = str_ind$0 + 1 | 0; str_ind$0 = str_ind$7;} + } + } + function compute_int_conv(pct_ind, str_ind, plus, hash, space, symb){ + var plus$0 = plus, hash$0 = hash, space$0 = space; + for(;;){ + a: + { + if(plus$0){ + if(! hash$0){ + if(space$0) break a; + if(100 === symb) return 1; + if(105 === symb) return 4; + break a; + } + } + else{ + if(! hash$0){ + if(space$0){ + if(100 === symb) return 2; + if(105 === symb) return 5; + break a; + } + var switcher$1 = symb - 88 | 0; + if(32 < switcher$1 >>> 0) break a; + switch(switcher$1){ + case 0: + return 8; + case 12: + return 0; + case 17: + return 3; + case 23: + return 10; + case 29: + return 12; + case 32: + return 6; + default: break a; + } + } + if(! space$0){ + var switcher$0 = symb - 88 | 0; + if(32 >= switcher$0 >>> 0) + switch(switcher$0){ + case 0: + return 9; + case 12: + return 13; + case 17: + return 14; + case 23: + return 11; + case 29: + return 15; + case 32: + return 7; + } + } + } + var switcher = symb - 88 | 0; + if(32 >= switcher >>> 0) + switch(switcher){ + case 0: + if(legacy_behavior$0) return 9; break; + case 23: + if(legacy_behavior$0) return 11; break; + case 32: + if(legacy_behavior$0) return 7; break; + case 12: + case 17: + case 29: + if(! legacy_behavior$0) + return incompatible_flag(pct_ind, str_ind, symb, cst$35); + hash$0 = 0; + continue; + } + } + if(plus$0) + if(space$0){ + if(! legacy_behavior$0) + return incompatible_flag(pct_ind, str_ind, 32, cst$32); + space$0 = 0; + } + else{ + if(! legacy_behavior$0) + return incompatible_flag(pct_ind, str_ind, symb, cst$33); + plus$0 = 0; + } + else{ + if(! space$0) + throw caml_maybe_attach_backtrace([0, Assert_failure, _W_], 1); + if(! legacy_behavior$0) + return incompatible_flag(pct_ind, str_ind, symb, cst$34); + space$0 = 0; + } + } + } + function incompatible_flag(pct_ind, str_ind, symb, option){ + var + subfmt = + caml_call3(Stdlib_String[15], str, pct_ind, str_ind - pct_ind | 0); + return caml_call5 + (failwith_message(_Y_), str, pct_ind, option, symb, subfmt); + } + return parse(0, caml_ml_string_length(str)); + } + function format_of_string_fmtty(str, fmtty){ + var fmt = fmt_ebb_of_string(0, str)[1]; + try{var _ae_ = [0, type_format(fmt, fmtty), str]; return _ae_;} + catch(_af_){ + var _ac_ = caml_wrap_exception(_af_); + if(_ac_ !== Type_mismatch) throw caml_maybe_attach_backtrace(_ac_, 0); + var _ad_ = string_of_fmtty(fmtty); + return caml_call2(failwith_message(_Z_), str, _ad_); + } + } + function format_of_string_format(str, param){ + var + str$0 = param[2], + fmt = param[1], + fmt$0 = fmt_ebb_of_string(0, str)[1]; + try{ + var _aa_ = [0, type_format(fmt$0, fmtty_of_fmt(fmt)), str]; + return _aa_; + } + catch(_ab_){ + var _$_ = caml_wrap_exception(_ab_); + if(_$_ === Type_mismatch) + return caml_call2(failwith_message(___), str, str$0); + throw caml_maybe_attach_backtrace(_$_, 0); + } + } + var + CamlinternalFormat = + [0, + is_in_char_set, + rev_char_set, + create_char_set, + add_in_char_set, + freeze_char_set, + param_format_of_ignored_format, + make_printf, + make_iprintf, + output_acc, + bufput_acc, + strput_acc, + type_format, + fmt_ebb_of_string, + format_of_string_fmtty, + format_of_string_format, + char_of_iconv, + string_of_formatting_lit, + string_of_fmtty, + string_of_fmt, + open_box_of_string, + symm, + trans, + recast]; + runtime.caml_register_global(197, CamlinternalFormat, "CamlinternalFormat"); + return; + } + (globalThis)); + +//# 14846 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + var + global_data = runtime.caml_get_global_data(), + Stdlib_Buffer = global_data.Stdlib__Buffer, + CamlinternalFormat = global_data.CamlinternalFormat, + Stdlib = global_data.Stdlib; + function kfprintf(k, o, param){ + var fmt = param[1]; + return caml_call3 + (CamlinternalFormat[7], + function(acc){ + caml_call2(CamlinternalFormat[9], o, acc); + return caml_call1(k, o); + }, + 0, + fmt); + } + function kbprintf(k, b, param){ + var fmt = param[1]; + return caml_call3 + (CamlinternalFormat[7], + function(acc){ + caml_call2(CamlinternalFormat[10], b, acc); + return caml_call1(k, b); + }, + 0, + fmt); + } + function ikfprintf(k, oc, param){ + var fmt = param[1]; + return caml_call3(CamlinternalFormat[8], k, oc, fmt); + } + function fprintf(oc, fmt){ + return kfprintf(function(_d_){return 0;}, oc, fmt); + } + function bprintf(b, fmt){ + return kbprintf(function(_c_){return 0;}, b, fmt); + } + function ifprintf(oc, fmt){ + return ikfprintf(function(_b_){return 0;}, oc, fmt); + } + function ibprintf(b, fmt){ + return ikfprintf(function(_a_){return 0;}, b, fmt); + } + function printf(fmt){return fprintf(Stdlib[39], fmt);} + function eprintf(fmt){return fprintf(Stdlib[40], fmt);} + function ksprintf(k, param){ + var fmt = param[1]; + function k$0(acc){ + var buf = caml_call1(Stdlib_Buffer[1], 64); + caml_call2(CamlinternalFormat[11], buf, acc); + return caml_call1(k, caml_call1(Stdlib_Buffer[2], buf)); + } + return caml_call3(CamlinternalFormat[7], k$0, 0, fmt); + } + function sprintf(fmt){return ksprintf(function(s){return s;}, fmt);} + var + Stdlib_Printf = + [0, + fprintf, + printf, + eprintf, + sprintf, + bprintf, + ifprintf, + ibprintf, + kfprintf, + ikfprintf, + ksprintf, + kbprintf, + ikfprintf, + ksprintf]; + runtime.caml_register_global(3, Stdlib_Printf, "Stdlib__Printf"); + return; + } + (globalThis)); + +//# 15656 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + global_data = runtime.caml_get_global_data(), + CamlinternalAtomic = global_data.CamlinternalAtomic, + make = CamlinternalAtomic[1], + get = CamlinternalAtomic[2], + set = CamlinternalAtomic[3], + exchange = CamlinternalAtomic[4], + compare_and_set = CamlinternalAtomic[5], + fetch_and_add = CamlinternalAtomic[6], + incr = CamlinternalAtomic[7], + decr = CamlinternalAtomic[8], + Stdlib_Atomic = + [0, + make, + get, + set, + exchange, + compare_and_set, + fetch_and_add, + incr, + decr]; + runtime.caml_register_global(1, Stdlib_Atomic, "Stdlib__Atomic"); + return; + } + (globalThis)); + +//# 15688 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst$4 = "", + cst_s = "%s\n", + cst_Program_not_linked_with_g_$0 = + "(Program not linked with -g, cannot print stack backtrace)\n", + cst_characters = ", characters ", + cst_Fatal_error_exception = "Fatal error: exception ", + cst_Fatal_error_exception_s = "Fatal error: exception %s\n", + cst_Uncaught_exception = "Uncaught exception: ", + cst_Uncaught_exception_s = "Uncaught exception: %s\n", + caml_check_bound = runtime.caml_check_bound, + caml_get_exception_raw_backtra = runtime.caml_get_exception_raw_backtrace, + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace, + caml_obj_tag = runtime.caml_obj_tag, + caml_wrap_exception = runtime.caml_wrap_exception; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + function caml_call6(f, a0, a1, a2, a3, a4, a5){ + return (f.l >= 0 ? f.l : f.l = f.length) == 6 + ? f(a0, a1, a2, a3, a4, a5) + : runtime.caml_call_gen(f, [a0, a1, a2, a3, a4, a5]); + } + function caml_call8(f, a0, a1, a2, a3, a4, a5, a6, a7){ + return (f.l >= 0 ? f.l : f.l = f.length) == 8 + ? f(a0, a1, a2, a3, a4, a5, a6, a7) + : runtime.caml_call_gen(f, [a0, a1, a2, a3, a4, a5, a6, a7]); + } + var + global_data = runtime.caml_get_global_data(), + cst$0 = cst$4, + cst$3 = cst$4, + partial = [4, 0, 0, 0, [12, 45, [4, 0, 0, 0, 0]]], + cst$1 = cst$4, + cst$2 = cst$4, + cst = "_", + locfmt = + [0, + [11, + 'File "', + [2, + 0, + [11, + '", line ', + [4, + 0, + 0, + 0, + [11, + cst_characters, + [4, 0, 0, 0, [12, 45, [4, 0, 0, 0, [11, ": ", [2, 0, 0]]]]]]]]]], + 'File "%s", line %d, characters %d-%d: %s'], + Stdlib_Printf = global_data.Stdlib__Printf, + Stdlib_Atomic = global_data.Stdlib__Atomic, + Stdlib = global_data.Stdlib, + Stdlib_Buffer = global_data.Stdlib__Buffer, + Stdlib_Obj = global_data.Stdlib__Obj, + printers = caml_call1(Stdlib_Atomic[1], 0), + _a_ = [0, [3, 0, 0], "%S"], + _b_ = [0, [4, 0, 0, 0, 0], "%d"], + _c_ = [0, [11, ", ", [2, 0, [2, 0, 0]]], ", %s%s"], + _d_ = [0, [12, 40, [2, 0, [2, 0, [12, 41, 0]]]], "(%s%s)"], + _e_ = [0, [12, 40, [2, 0, [12, 41, 0]]], "(%s)"], + cst_Out_of_memory = "Out of memory", + cst_Stack_overflow = "Stack overflow", + cst_Pattern_matching_failed = "Pattern matching failed", + cst_Assertion_failed = "Assertion failed", + cst_Undefined_recursive_module = "Undefined recursive module", + _f_ = + [0, + [11, cst_Uncaught_exception, [2, 0, [12, 10, 0]]], + cst_Uncaught_exception_s], + _g_ = + [0, + [11, cst_Uncaught_exception, [2, 0, [12, 10, 0]]], + cst_Uncaught_exception_s], + cst_Raised_at = "Raised at", + cst_Re_raised_at = "Re-raised at", + cst_Raised_by_primitive_operat = "Raised by primitive operation at", + cst_Called_from = "Called from", + cst_inlined = " (inlined)", + _h_ = + [0, + [2, + 0, + [12, + 32, + [2, + 0, + [11, + ' in file "', + [2, + 0, + [12, + 34, + [2, + 0, + [11, ", line ", [4, 0, 0, 0, [11, cst_characters, partial]]]]]]]]]], + '%s %s in file "%s"%s, line %d, characters %d-%d'], + _i_ = [0, [2, 0, [11, " unknown location", 0]], "%s unknown location"], + _j_ = [0, [2, 0, [12, 10, 0]], cst_s], + _k_ = + [0, + [11, cst_Program_not_linked_with_g_$0, 0], + cst_Program_not_linked_with_g_$0], + _l_ = [0, [2, 0, [12, 10, 0]], cst_s], + cst_Program_not_linked_with_g_ = cst_Program_not_linked_with_g_$0; + function field(x, i){ + var f = x[1 + i]; + if(! caml_call1(Stdlib_Obj[1], f)) + return caml_call2(Stdlib_Printf[4], _b_, f); + var _ag_ = Stdlib_Obj[13]; + if(caml_obj_tag(f) === _ag_) return caml_call2(Stdlib_Printf[4], _a_, f); + var _ah_ = Stdlib_Obj[14]; + return caml_obj_tag(f) === _ah_ ? caml_call1(Stdlib[35], f) : cst; + } + function other_fields(x, i){ + if(x.length - 1 <= i) return cst$0; + var _ae_ = other_fields(x, i + 1 | 0), _af_ = field(x, i); + return caml_call3(Stdlib_Printf[4], _c_, _af_, _ae_); + } + function use_printers(x){ + var param = caml_call1(Stdlib_Atomic[2], printers); + for(;;){ + if(! param) return 0; + var tl = param[2], hd = param[1]; + a: + { + try{var val = caml_call1(hd, x);}catch(_ad_){break a;} + if(val){var s = val[1]; return [0, s];} + } + param = tl; + } + } + function to_string_default(x){ + if(x === Stdlib[9]) return cst_Out_of_memory; + if(x === Stdlib[10]) return cst_Stack_overflow; + if(x[1] === Stdlib[4]){ + var + match$0 = x[2], + char$0 = match$0[3], + line = match$0[2], + file = match$0[1]; + return caml_call6 + (Stdlib_Printf[4], + locfmt, + file, + line, + char$0, + char$0 + 5 | 0, + cst_Pattern_matching_failed); + } + if(x[1] === Stdlib[5]){ + var + match$1 = x[2], + char$1 = match$1[3], + line$0 = match$1[2], + file$0 = match$1[1]; + return caml_call6 + (Stdlib_Printf[4], + locfmt, + file$0, + line$0, + char$1, + char$1 + 6 | 0, + cst_Assertion_failed); + } + if(x[1] === Stdlib[15]){ + var + match$2 = x[2], + char$2 = match$2[3], + line$1 = match$2[2], + file$1 = match$2[1]; + return caml_call6 + (Stdlib_Printf[4], + locfmt, + file$1, + line$1, + char$2, + char$2 + 6 | 0, + cst_Undefined_recursive_module); + } + if(0 !== caml_obj_tag(x)) return x[1]; + var constructor = x[1][1], match = x.length - 1; + if(2 < match >>> 0) + var + _$_ = other_fields(x, 2), + _aa_ = field(x, 1), + _ac_ = caml_call3(Stdlib_Printf[4], _d_, _aa_, _$_); + else + switch(match){ + case 0: + var _ac_ = cst$1; break; + case 1: + var _ac_ = cst$2; break; + default: + var + _ab_ = field(x, 1), + _ac_ = caml_call2(Stdlib_Printf[4], _e_, _ab_); + } + return caml_call2(Stdlib[28], constructor, _ac_); + } + function to_string(e){ + var match = use_printers(e); + if(! match) return to_string_default(e); + var s = match[1]; + return s; + } + function print(fct, arg){ + try{var ___ = caml_call1(fct, arg); return ___;} + catch(x$0){ + var x = caml_wrap_exception(x$0), _Z_ = to_string(x); + caml_call2(Stdlib_Printf[3], _f_, _Z_); + caml_call1(Stdlib[63], Stdlib[40]); + throw caml_maybe_attach_backtrace(x, 0); + } + } + function catch$0(fct, arg){ + try{var _Y_ = caml_call1(fct, arg); return _Y_;} + catch(x$0){ + var x = caml_wrap_exception(x$0); + caml_call1(Stdlib[63], Stdlib[39]); + var _X_ = to_string(x); + caml_call2(Stdlib_Printf[3], _g_, _X_); + return caml_call1(Stdlib[99], 2); + } + } + function raw_backtrace_entries(bt){return bt;} + function convert_raw_backtrace(bt){ + return [0, runtime.caml_convert_raw_backtrace(bt)]; + } + function format_backtrace_slot(pos, slot){ + function info(is_raise){ + return is_raise + ? 0 === pos ? cst_Raised_at : cst_Re_raised_at + : 0 === pos ? cst_Raised_by_primitive_operat : cst_Called_from; + } + if(0 === slot[0]){ + var + _P_ = slot[5], + _Q_ = slot[4], + _R_ = slot[3], + _S_ = slot[6] ? cst_inlined : cst$3, + _T_ = slot[2], + _U_ = slot[7], + _V_ = info(slot[1]); + return [0, + caml_call8 + (Stdlib_Printf[4], _h_, _V_, _U_, _T_, _S_, _R_, _Q_, _P_)]; + } + if(slot[1]) return 0; + var _W_ = info(0); + return [0, caml_call2(Stdlib_Printf[4], _i_, _W_)]; + } + function print_raw_backtrace(outchan, raw_backtrace){ + var backtrace = convert_raw_backtrace(raw_backtrace); + if(! backtrace) return caml_call2(Stdlib_Printf[1], outchan, _k_); + var a = backtrace[1], _N_ = a.length - 2 | 0, _M_ = 0; + if(_N_ >= 0){ + var i = _M_; + for(;;){ + var match = format_backtrace_slot(i, caml_check_bound(a, i)[1 + i]); + if(match){ + var str = match[1]; + caml_call3(Stdlib_Printf[1], outchan, _j_, str); + } + var _O_ = i + 1 | 0; + if(_N_ === i) break; + i = _O_; + } + } + return 0; + } + function print_backtrace(outchan){ + return print_raw_backtrace(outchan, caml_get_exception_raw_backtra(0)); + } + function raw_backtrace_to_string(raw_backtrace){ + var backtrace = convert_raw_backtrace(raw_backtrace); + if(! backtrace) return cst_Program_not_linked_with_g_; + var + a = backtrace[1], + b = caml_call1(Stdlib_Buffer[1], 1024), + _K_ = a.length - 2 | 0, + _J_ = 0; + if(_K_ >= 0){ + var i = _J_; + for(;;){ + var match = format_backtrace_slot(i, caml_check_bound(a, i)[1 + i]); + if(match){ + var str = match[1]; + caml_call3(Stdlib_Printf[5], b, _l_, str); + } + var _L_ = i + 1 | 0; + if(_K_ === i) break; + i = _L_; + } + } + return caml_call1(Stdlib_Buffer[2], b); + } + function backtrace_slot_is_raise(param){ + return 0 === param[0] ? param[1] : param[1]; + } + function backtrace_slot_is_inline(param){return 0 === param[0] ? param[6] : 0; + } + function backtrace_slot_location(param){ + return 0 === param[0] + ? [0, [0, param[2], param[3], param[4], param[5]]] + : 0; + } + function backtrace_slot_defname(param){ + if(0 === param[0] && param[7] !== cst$4) return [0, param[7]]; + return 0; + } + function backtrace_slots(raw_backtrace){ + var match = convert_raw_backtrace(raw_backtrace); + if(! match) return 0; + var backtrace = match[1], i$1 = backtrace.length - 2 | 0, i = i$1; + for(;;){ + if(-1 === i) + var _I_ = 0; + else{ + var _H_ = 0 === caml_check_bound(backtrace, i)[1 + i][0] ? 1 : 0; + if(! _H_){var i$0 = i - 1 | 0; i = i$0; continue;} + var _I_ = _H_; + } + return _I_ ? [0, backtrace] : 0; + } + } + function backtrace_slots_of_raw_entry(entry){return backtrace_slots([0, entry]); + } + function raw_backtrace_length(bt){return bt.length - 1;} + function get_backtrace(param){ + return raw_backtrace_to_string(caml_get_exception_raw_backtra(0)); + } + function register_printer(fn){ + for(;;){ + var + old_printers = caml_call1(Stdlib_Atomic[2], printers), + new_printers = [0, fn, old_printers], + success = + caml_call3(Stdlib_Atomic[5], printers, old_printers, new_printers), + _G_ = 1 - success; + if(! _G_) return _G_; + } + } + function exn_slot(x){return 0 === caml_obj_tag(x) ? x[1] : x;} + function exn_slot_id(x){var slot = exn_slot(x); return slot[2];} + function exn_slot_name(x){var slot = exn_slot(x); return slot[1];} + var + errors = + [0, + cst$4, + "(Cannot print locations:\n bytecode executable program file not found)", + "(Cannot print locations:\n bytecode executable program file appears to be corrupt)", + "(Cannot print locations:\n bytecode executable program file has wrong magic number)", + "(Cannot print locations:\n bytecode executable program file cannot be opened;\n -- too many open files. Try running with OCAMLRUNPARAM=b=2)"].slice + (), + _m_ = + [0, + [11, cst_Fatal_error_exception, [2, 0, [12, 10, 0]]], + cst_Fatal_error_exception_s]; + function default_uncaught_exception_han(exn, raw_backtrace){ + var _D_ = to_string(exn); + caml_call2(Stdlib_Printf[3], _m_, _D_); + print_raw_backtrace(Stdlib[40], raw_backtrace); + var status = runtime.caml_ml_debug_info_status(0); + if(status < 0){ + var + _E_ = caml_call1(Stdlib[18], status), + _F_ = caml_check_bound(errors, _E_)[1 + _E_]; + caml_call1(Stdlib[53], _F_); + } + return caml_call1(Stdlib[63], Stdlib[40]); + } + var uncaught_exception_handler = [0, default_uncaught_exception_han]; + function set_uncaught_exception_handler(fn){ + uncaught_exception_handler[1] = fn; + return 0; + } + var + empty_backtrace = [0], + cst_Fatal_error_out_of_memory_ = + "Fatal error: out of memory in uncaught exception handler", + _n_ = + [0, + [11, cst_Fatal_error_exception, [2, 0, [12, 10, 0]]], + cst_Fatal_error_exception_s], + _o_ = + [0, + [11, + "Fatal error in uncaught exception handler: exception ", + [2, 0, [12, 10, 0]]], + "Fatal error in uncaught exception handler: exception %s\n"]; + function handle_uncaught_exception(exn$0, debugger_in_use){ + try{ + try{ + var + raw_backtrace = + debugger_in_use ? empty_backtrace : caml_get_exception_raw_backtra(0); + try{caml_call1(Stdlib[103], 0);}catch(_C_){} + try{ + var + _y_ = caml_call2(uncaught_exception_handler[1], exn$0, raw_backtrace), + _x_ = _y_; + } + catch(exn$1){ + var + exn = caml_wrap_exception(exn$1), + raw_backtrace$0 = caml_get_exception_raw_backtra(0), + _v_ = to_string(exn$0); + caml_call2(Stdlib_Printf[3], _n_, _v_); + print_raw_backtrace(Stdlib[40], raw_backtrace); + var _w_ = to_string(exn); + caml_call2(Stdlib_Printf[3], _o_, _w_); + print_raw_backtrace(Stdlib[40], raw_backtrace$0); + var _x_ = caml_call1(Stdlib[63], Stdlib[40]); + } + var _z_ = _x_; + } + catch(_B_){ + var _u_ = caml_wrap_exception(_B_); + if(_u_ !== Stdlib[9]) throw caml_maybe_attach_backtrace(_u_, 0); + var _z_ = caml_call1(Stdlib[53], cst_Fatal_error_out_of_memory_); + } + return _z_; + } + catch(_A_){return 0;} + } + runtime.caml_register_named_value + ("Printexc.handle_uncaught_exception", handle_uncaught_exception); + var + Stdlib_Printexc = + [0, + to_string, + to_string_default, + print, + catch$0, + print_backtrace, + get_backtrace, + runtime.caml_record_backtrace, + runtime.caml_backtrace_status, + register_printer, + use_printers, + raw_backtrace_entries, + function(_t_){return caml_get_exception_raw_backtra(_t_);}, + print_raw_backtrace, + raw_backtrace_to_string, + default_uncaught_exception_han, + set_uncaught_exception_handler, + backtrace_slots, + backtrace_slots_of_raw_entry, + [0, + backtrace_slot_is_raise, + backtrace_slot_is_inline, + backtrace_slot_location, + backtrace_slot_defname, + format_backtrace_slot], + raw_backtrace_length, + function(_s_, _r_){return runtime.caml_raw_backtrace_slot(_s_, _r_);}, + function(_q_){return runtime.caml_convert_raw_backtrace_slot(_q_);}, + function(_p_){return runtime.caml_raw_backtrace_next_slot(_p_);}, + exn_slot_id, + exn_slot_name]; + runtime.caml_register_global(42, Stdlib_Printexc, "Stdlib__Printexc"); + return; + } + (globalThis)); + +//# 21391 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + caml_register_named_value = runtime.caml_register_named_value, + global_data = runtime.caml_get_global_data(), + Stdlib_Obj = global_data.Stdlib__Obj, + register = caml_register_named_value; + function register_exception(name, exn){ + var + _a_ = Stdlib_Obj[8], + slot = runtime.caml_obj_tag(exn) === _a_ ? exn : exn[1]; + return caml_register_named_value(name, slot); + } + var Stdlib_Callback = [0, register, register_exception]; + runtime.caml_register_global(1, Stdlib_Callback, "Stdlib__Callback"); + return; + } + (globalThis)); + +//# 21414 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst_camlinternalOO_ml = "camlinternalOO.ml", + caml_check_bound = runtime.caml_check_bound, + caml_div = runtime.caml_div, + caml_get_public_method = runtime.caml_get_public_method, + caml_make_vect = runtime.caml_make_vect, + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace, + caml_obj_block = runtime.caml_obj_block, + caml_set_oo_id = runtime.caml_set_oo_id, + caml_string_compare = runtime.caml_string_compare, + caml_wrap_exception = runtime.caml_wrap_exception; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + function caml_call5(f, a0, a1, a2, a3, a4){ + return (f.l >= 0 ? f.l : f.l = f.length) == 5 + ? f(a0, a1, a2, a3, a4) + : runtime.caml_call_gen(f, [a0, a1, a2, a3, a4]); + } + var + global_data = runtime.caml_get_global_data(), + Assert_failure = global_data.Assert_failure, + Stdlib_Sys = global_data.Stdlib__Sys, + Stdlib_Obj = global_data.Stdlib__Obj, + Stdlib = global_data.Stdlib, + Stdlib_Array = global_data.Stdlib__Array, + Stdlib_List = global_data.Stdlib__List, + Stdlib_Map = global_data.Stdlib__Map; + function copy(o){var o$0 = o.slice(); return caml_set_oo_id(o$0);} + var params = [0, 1, 1, 1, 3, 16]; + function public_method_label(s){ + var + accu = [0, 0], + _al_ = runtime.caml_ml_string_length(s) - 1 | 0, + _ak_ = 0; + if(_al_ >= 0){ + var i = _ak_; + for(;;){ + var _am_ = runtime.caml_string_get(s, i); + accu[1] = (223 * accu[1] | 0) + _am_ | 0; + var _an_ = i + 1 | 0; + if(_al_ === i) break; + i = _an_; + } + } + accu[1] = accu[1] & 2147483647; + var tag = 1073741823 < accu[1] ? accu[1] + 2147483648 | 0 : accu[1]; + return tag; + } + var + compare = caml_string_compare, + Vars = caml_call1(Stdlib_Map[1], [0, compare]), + compare$0 = caml_string_compare, + Meths = caml_call1(Stdlib_Map[1], [0, compare$0]), + compare$1 = runtime.caml_int_compare, + Labs = caml_call1(Stdlib_Map[1], [0, compare$1]), + dummy_table = [0, 0, [0, 0], Meths[1], Labs[1], 0, 0, Vars[1], 0], + table_count = [0, 0], + dummy_met = caml_obj_block(0, 0), + initial_object_size = 2; + function fit_size(n){ + return 2 < n ? fit_size((n + 1 | 0) / 2 | 0) * 2 | 0 : n; + } + function new_table(pub_labels){ + table_count[1]++; + var + len = pub_labels.length - 1, + methods = caml_make_vect((len * 2 | 0) + 2 | 0, dummy_met); + caml_check_bound(methods, 0)[1] = len; + var + _ad_ = Stdlib_Sys[9], + _ae_ = (runtime.caml_mul(fit_size(len), _ad_) / 8 | 0) - 1 | 0; + caml_check_bound(methods, 1)[2] = _ae_; + var _ag_ = len - 1 | 0, _af_ = 0; + if(_ag_ >= 0){ + var i = _af_; + for(;;){ + var + _ai_ = (i * 2 | 0) + 3 | 0, + _ah_ = caml_check_bound(pub_labels, i)[1 + i]; + caml_check_bound(methods, _ai_)[1 + _ai_] = _ah_; + var _aj_ = i + 1 | 0; + if(_ag_ === i) break; + i = _aj_; + } + } + return [0, + initial_object_size, + methods, + Meths[1], + Labs[1], + 0, + 0, + Vars[1], + 0]; + } + function resize(array, new_size){ + var old_size = array[2].length - 1, _ab_ = old_size < new_size ? 1 : 0; + if(_ab_){ + var new_buck = caml_make_vect(new_size, dummy_met); + caml_call5(Stdlib_Array[10], array[2], 0, new_buck, 0, old_size); + array[2] = new_buck; + var _ac_ = 0; + } + else + var _ac_ = _ab_; + return _ac_; + } + var + method_count = [0, 0], + inst_var_count = [0, 0], + _a_ = [0, cst_camlinternalOO_ml, 281, 50], + _b_ = [0, cst_camlinternalOO_ml, 409, 13], + _c_ = [0, cst_camlinternalOO_ml, 412, 13], + _d_ = [0, cst_camlinternalOO_ml, 415, 13], + _e_ = [0, cst_camlinternalOO_ml, 418, 13], + _f_ = [0, cst_camlinternalOO_ml, 421, 13], + _g_ = [0, cst_camlinternalOO_ml, 439, 17]; + function new_method(table){ + var index = table[2].length - 1; + resize(table, index + 1 | 0); + return index; + } + function get_method_label(table, name){ + try{var _$_ = caml_call2(Meths[28], name, table[3]); return _$_;} + catch(_aa_){ + var ___ = caml_wrap_exception(_aa_); + if(___ !== Stdlib[8]) throw caml_maybe_attach_backtrace(___, 0); + var label = new_method(table); + table[3] = caml_call3(Meths[4], name, label, table[3]); + table[4] = caml_call3(Labs[4], label, 1, table[4]); + return label; + } + } + function get_method_labels(table, names){ + return caml_call2 + (Stdlib_Array[15], + function(_Z_){return get_method_label(table, _Z_);}, + names); + } + function set_method(table, label, element){ + method_count[1]++; + return caml_call2(Labs[28], label, table[4]) + ? (resize + (table, label + 1 | 0), + caml_check_bound(table[2], label)[1 + label] = element, + 0) + : (table[6] = [0, [0, label, element], table[6]], 0); + } + function get_method(table, label){ + try{var _X_ = caml_call2(Stdlib_List[46], label, table[6]); return _X_;} + catch(_Y_){ + var _W_ = caml_wrap_exception(_Y_); + if(_W_ === Stdlib[8]) + return caml_check_bound(table[2], label)[1 + label]; + throw caml_maybe_attach_backtrace(_W_, 0); + } + } + function to_list(arr){ + return 0 === arr ? 0 : caml_call1(Stdlib_Array[11], arr); + } + function narrow(table, vars, virt_meths, concr_meths){ + var + vars$0 = to_list(vars), + virt_meths$0 = to_list(virt_meths), + concr_meths$0 = to_list(concr_meths), + virt_meth_labs = + caml_call2 + (Stdlib_List[19], + function(_V_){return get_method_label(table, _V_);}, + virt_meths$0), + concr_meth_labs = + caml_call2 + (Stdlib_List[19], + function(_U_){return get_method_label(table, _U_);}, + concr_meths$0); + table[5] = + [0, + [0, table[3], table[4], table[6], table[7], virt_meth_labs, vars$0], + table[5]]; + table[7] = + caml_call3 + (Vars[13], + function(lab, info, tvars){ + return caml_call2(Stdlib_List[36], lab, vars$0) + ? caml_call3(Vars[4], lab, info, tvars) + : tvars; + }, + table[7], + Vars[1]); + var by_name = [0, Meths[1]], by_label = [0, Labs[1]]; + caml_call3 + (Stdlib_List[27], + function(met, label){ + by_name[1] = caml_call3(Meths[4], met, label, by_name[1]); + var _P_ = by_label[1]; + try{var _S_ = caml_call2(Labs[28], label, table[4]), _R_ = _S_;} + catch(_T_){ + var _Q_ = caml_wrap_exception(_T_); + if(_Q_ !== Stdlib[8]) throw caml_maybe_attach_backtrace(_Q_, 0); + var _R_ = 1; + } + by_label[1] = caml_call3(Labs[4], label, _R_, _P_); + return 0; + }, + concr_meths$0, + concr_meth_labs); + caml_call3 + (Stdlib_List[27], + function(met, label){ + by_name[1] = caml_call3(Meths[4], met, label, by_name[1]); + by_label[1] = caml_call3(Labs[4], label, 0, by_label[1]); + return 0; + }, + virt_meths$0, + virt_meth_labs); + table[3] = by_name[1]; + table[4] = by_label[1]; + table[6] = + caml_call3 + (Stdlib_List[26], + function(met, hm){ + var lab = met[1]; + return caml_call2(Stdlib_List[36], lab, virt_meth_labs) + ? hm + : [0, met, hm]; + }, + table[6], + 0); + return 0; + } + function widen(table){ + var + match = caml_call1(Stdlib_List[5], table[5]), + vars = match[6], + virt_meths = match[5], + saved_vars = match[4], + saved_hidden_meths = match[3], + by_label = match[2], + by_name = match[1]; + table[5] = caml_call1(Stdlib_List[6], table[5]); + table[7] = + caml_call3 + (Stdlib_List[25], + function(s, v){ + var _O_ = caml_call2(Vars[28], v, table[7]); + return caml_call3(Vars[4], v, _O_, s); + }, + saved_vars, + vars); + table[3] = by_name; + table[4] = by_label; + table[6] = + caml_call3 + (Stdlib_List[26], + function(met, hm){ + var lab = met[1]; + return caml_call2(Stdlib_List[36], lab, virt_meths) + ? hm + : [0, met, hm]; + }, + table[6], + saved_hidden_meths); + return 0; + } + function new_variable(table, name){ + try{var _M_ = caml_call2(Vars[28], name, table[7]); return _M_;} + catch(_N_){ + var _L_ = caml_wrap_exception(_N_); + if(_L_ !== Stdlib[8]) throw caml_maybe_attach_backtrace(_L_, 0); + var index = table[1]; + table[1] = index + 1 | 0; + if(name !== "") table[7] = caml_call3(Vars[4], name, index, table[7]); + return index; + } + } + function to_array(arr){return runtime.caml_equal(arr, 0) ? [0] : arr;} + function new_methods_variables(table, meths, vals){ + var + meths$0 = to_array(meths), + nmeths = meths$0.length - 1, + nvals = vals.length - 1, + res = caml_make_vect(nmeths + nvals | 0, 0), + _D_ = nmeths - 1 | 0, + _C_ = 0; + if(_D_ >= 0){ + var i$0 = _C_; + for(;;){ + var + _J_ = get_method_label(table, caml_check_bound(meths$0, i$0)[1 + i$0]); + caml_check_bound(res, i$0)[1 + i$0] = _J_; + var _K_ = i$0 + 1 | 0; + if(_D_ === i$0) break; + i$0 = _K_; + } + } + var _F_ = nvals - 1 | 0, _E_ = 0; + if(_F_ >= 0){ + var i = _E_; + for(;;){ + var + _H_ = i + nmeths | 0, + _G_ = new_variable(table, caml_check_bound(vals, i)[1 + i]); + caml_check_bound(res, _H_)[1 + _H_] = _G_; + var _I_ = i + 1 | 0; + if(_F_ === i) break; + i = _I_; + } + } + return res; + } + function get_variable(table, name){ + try{var _A_ = caml_call2(Vars[28], name, table[7]); return _A_;} + catch(_B_){ + var _z_ = caml_wrap_exception(_B_); + if(_z_ === Stdlib[8]) + throw caml_maybe_attach_backtrace([0, Assert_failure, _a_], 1); + throw caml_maybe_attach_backtrace(_z_, 0); + } + } + function get_variables(table, names){ + return caml_call2 + (Stdlib_Array[15], + function(_y_){return get_variable(table, _y_);}, + names); + } + function add_initializer(table, f){table[8] = [0, f, table[8]]; return 0;} + function create_table(public_methods){ + if(0 === public_methods) return new_table([0]); + var + tags = caml_call2(Stdlib_Array[15], public_method_label, public_methods), + table = new_table(tags); + caml_call2 + (Stdlib_Array[14], + function(i, met){ + var lab = (i * 2 | 0) + 2 | 0; + table[3] = caml_call3(Meths[4], met, lab, table[3]); + table[4] = caml_call3(Labs[4], lab, 1, table[4]); + return 0; + }, + public_methods); + return table; + } + function init_class(table){ + inst_var_count[1] = (inst_var_count[1] + table[1] | 0) - 1 | 0; + table[8] = caml_call1(Stdlib_List[9], table[8]); + var _x_ = Stdlib_Sys[9]; + return resize + (table, + 3 + caml_div(caml_check_bound(table[2], 1)[2] * 16 | 0, _x_) | 0); + } + function inherits(cla, vals, virt_meths, concr_meths, param, top){ + var env = param[4], super$0 = param[2]; + narrow(cla, vals, virt_meths, concr_meths); + var init = top ? caml_call2(super$0, cla, env) : caml_call1(super$0, cla); + widen(cla); + var + _s_ = to_array(concr_meths), + _t_ = + [0, + caml_call2 + (Stdlib_Array[15], + function(nm){return get_method(cla, get_method_label(cla, nm));}, + _s_), + 0], + _u_ = to_array(vals), + _v_ = + [0, + [0, init], + [0, + caml_call2 + (Stdlib_Array[15], + function(_w_){return get_variable(cla, _w_);}, + _u_), + _t_]]; + return caml_call1(Stdlib_Array[6], _v_); + } + function make_class(pub_meths, class_init){ + var + table = create_table(pub_meths), + env_init = caml_call1(class_init, table); + init_class(table); + return [0, caml_call1(env_init, 0), class_init, env_init, 0]; + } + function make_class_store(pub_meths, class_init, init_table){ + var + table = create_table(pub_meths), + env_init = caml_call1(class_init, table); + init_class(table); + init_table[2] = class_init; + init_table[1] = env_init; + return 0; + } + function dummy_class(loc){ + function undef(param){ + throw caml_maybe_attach_backtrace([0, Stdlib[15], loc], 1); + } + return [0, undef, undef, undef, 0]; + } + function create_object(table){ + var obj = caml_obj_block(Stdlib_Obj[8], table[1]); + obj[1] = table[2]; + return caml_set_oo_id(obj); + } + function create_object_opt(obj_0, table){ + if(obj_0) return obj_0; + var obj = caml_obj_block(Stdlib_Obj[8], table[1]); + obj[1] = table[2]; + return caml_set_oo_id(obj); + } + function iter_f(obj, param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + var l = param$0[2], f = param$0[1]; + caml_call1(f, obj); + param$0 = l; + } + } + function run_initializers(obj, table){ + var inits = table[8], _r_ = 0 !== inits ? 1 : 0; + return _r_ ? iter_f(obj, inits) : _r_; + } + function run_initializers_opt(obj_0, obj, table){ + if(obj_0) return obj; + var inits = table[8]; + if(0 !== inits) iter_f(obj, inits); + return obj; + } + function create_object_and_run_initiali(obj_0, table){ + if(obj_0) return obj_0; + var obj = create_object(table); + run_initializers(obj, table); + return obj; + } + function get_data(param){ + if(param) return param[2]; + throw caml_maybe_attach_backtrace([0, Assert_failure, _e_], 1); + } + function build_path(n, keys, tables){ + var res = [0, 0, 0, 0], r = [0, res], _o_ = 0; + if(n >= 0){ + var i = _o_; + for(;;){ + var _p_ = r[1]; + r[1] = [0, caml_check_bound(keys, i)[1 + i], _p_, 0]; + var _q_ = i + 1 | 0; + if(n === i) break; + i = _q_; + } + } + var v = r[1]; + if(! tables) + throw caml_maybe_attach_backtrace([0, Assert_failure, _b_], 1); + tables[2] = v; + return res; + } + function lookup_tables(root, keys){ + var root_data = get_data(root); + if(! root_data) return build_path(keys.length - 2 | 0, keys, root); + var i$1 = keys.length - 2 | 0, i = i$1, tables$0 = root_data; + for(;;){ + if(0 > i) return tables$0; + var key = caml_check_bound(keys, i)[1 + i], tables$1 = tables$0; + for(;;){ + if(! tables$1) + throw caml_maybe_attach_backtrace([0, Assert_failure, _d_], 1); + if(tables$1[1] === key) break; + if(! tables$1) + throw caml_maybe_attach_backtrace([0, Assert_failure, _f_], 1); + var tables = tables$1[3]; + if(! tables){ + var next = [0, key, 0, 0]; + if(! tables$1) + throw caml_maybe_attach_backtrace([0, Assert_failure, _c_], 1); + tables$1[3] = next; + return build_path(i - 1 | 0, keys, next); + } + tables$1 = tables; + } + var tables_data = get_data(tables$1); + if(! tables_data) + throw caml_maybe_attach_backtrace([0, Assert_failure, _g_], 1); + var i$0 = i - 1 | 0; + i = i$0; + tables$0 = tables_data; + } + } + function new_cache(table){ + var n = new_method(table); + a: + { + if(0 !== (n % 2 | 0)){ + var _n_ = Stdlib_Sys[9]; + if + ((2 + caml_div(caml_check_bound(table[2], 1)[2] * 16 | 0, _n_) | 0) + >= n){ + var n$0 = new_method(table); + break a; + } + } + var n$0 = n; + } + caml_check_bound(table[2], n$0)[1 + n$0] = 0; + return n$0; + } + function set_methods(table, methods){ + var len = methods.length - 1, i = [0, 0]; + for(;;){ + if(i[1] >= len) return 0; + var + _h_ = i[1], + label = caml_check_bound(methods, _h_)[1 + _h_], + next = + function(param){ + i[1]++; + var _m_ = i[1]; + return caml_check_bound(methods, _m_)[1 + _m_]; + }, + clo = next(0); + if(typeof clo === "number") + switch(clo){ + case 0: + var x = next(0); + let x$20 = x; + var clo$0 = function(obj){return x$20;}; + break; + case 1: + var n = next(0); + let n$38 = n; + var clo$0 = function(obj){return obj[1 + n$38];}; + break; + case 2: + var e = next(0), n$0 = next(0); + let e$10 = e, n$37 = n$0; + var clo$0 = function(obj){return obj[1 + e$10][1 + n$37];}; + break; + case 3: + var n$1 = next(0); + let n$36 = n$1; + var clo$0 = function(obj){return caml_call1(obj[1][1 + n$36], obj);}; + break; + case 4: + var n$2 = next(0); + let n$35 = n$2; + var clo$0 = function(obj, x){obj[1 + n$35] = x; return 0;}; + break; + case 5: + var f = next(0), x$0 = next(0); + let f$20 = f, x$19 = x$0; + var clo$0 = function(obj){return caml_call1(f$20, x$19);}; + break; + case 6: + var f$0 = next(0), n$3 = next(0); + let f$19 = f$0, n$34 = n$3; + var clo$0 = function(obj){return caml_call1(f$19, obj[1 + n$34]);}; + break; + case 7: + var f$1 = next(0), e$0 = next(0), n$4 = next(0); + let f$18 = f$1, e$9 = e$0, n$33 = n$4; + var + clo$0 = + function(obj){return caml_call1(f$18, obj[1 + e$9][1 + n$33]);}; + break; + case 8: + var f$2 = next(0), n$5 = next(0); + let f$17 = f$2, n$32 = n$5; + var + clo$0 = + function(obj){ + return caml_call1(f$17, caml_call1(obj[1][1 + n$32], obj)); + }; + break; + case 9: + var f$3 = next(0), x$1 = next(0), y = next(0); + let f$16 = f$3, x$18 = x$1, y$0 = y; + var clo$0 = function(obj){return caml_call2(f$16, x$18, y$0);}; + break; + case 10: + var f$4 = next(0), x$2 = next(0), n$6 = next(0); + let f$15 = f$4, x$17 = x$2, n$31 = n$6; + var + clo$0 = function(obj){return caml_call2(f$15, x$17, obj[1 + n$31]);}; + break; + case 11: + var f$5 = next(0), x$3 = next(0), e$1 = next(0), n$7 = next(0); + let f$14 = f$5, x$16 = x$3, e$8 = e$1, n$30 = n$7; + var + clo$0 = + function(obj){ + return caml_call2(f$14, x$16, obj[1 + e$8][1 + n$30]); + }; + break; + case 12: + var f$6 = next(0), x$4 = next(0), n$8 = next(0); + let f$13 = f$6, x$15 = x$4, n$29 = n$8; + var + clo$0 = + function(obj){ + return caml_call2(f$13, x$15, caml_call1(obj[1][1 + n$29], obj)); + }; + break; + case 13: + var f$7 = next(0), n$9 = next(0), x$5 = next(0); + let f$12 = f$7, n$28 = n$9, x$14 = x$5; + var + clo$0 = function(obj){return caml_call2(f$12, obj[1 + n$28], x$14);}; + break; + case 14: + var f$8 = next(0), e$2 = next(0), n$10 = next(0), x$6 = next(0); + let f$11 = f$8, e$7 = e$2, n$27 = n$10, x$13 = x$6; + var + clo$0 = + function(obj){ + return caml_call2(f$11, obj[1 + e$7][1 + n$27], x$13); + }; + break; + case 15: + var f$9 = next(0), n$11 = next(0), x$7 = next(0); + let f$10 = f$9, n$26 = n$11, x$12 = x$7; + var + clo$0 = + function(obj){ + return caml_call2(f$10, caml_call1(obj[1][1 + n$26], obj), x$12); + }; + break; + case 16: + var n$12 = next(0), x$8 = next(0); + let n$25 = n$12, x$11 = x$8; + var + clo$0 = + function(obj){return caml_call2(obj[1][1 + n$25], obj, x$11);}; + break; + case 17: + var n$13 = next(0), m = next(0); + let n$24 = n$13, m$12 = m; + var + clo$0 = + function(obj){ + return caml_call2(obj[1][1 + n$24], obj, obj[1 + m$12]); + }; + break; + case 18: + var n$14 = next(0), e$3 = next(0), m$0 = next(0); + let n$23 = n$14, e$6 = e$3, m$11 = m$0; + var + clo$0 = + function(obj){ + return caml_call2(obj[1][1 + n$23], obj, obj[1 + e$6][1 + m$11]); + }; + break; + case 19: + var n$15 = next(0), m$1 = next(0); + let n$22 = n$15, m$10 = m$1; + var + clo$0 = + function(obj){ + var _l_ = caml_call1(obj[1][1 + m$10], obj); + return caml_call2(obj[1][1 + n$22], obj, _l_); + }; + break; + case 20: + var m$2 = next(0), x$9 = next(0); + new_cache(table); + let m$9 = m$2, x$10 = x$9; + var + clo$0 = + function(obj){ + return caml_call1(caml_get_public_method(x$10, m$9, 0), x$10); + }; + break; + case 21: + var m$3 = next(0), n$16 = next(0); + new_cache(table); + let m$8 = m$3, n$21 = n$16; + var + clo$0 = + function(obj){ + var _k_ = obj[1 + n$21]; + return caml_call1(caml_get_public_method(_k_, m$8, 0), _k_); + }; + break; + case 22: + var m$4 = next(0), e$4 = next(0), n$17 = next(0); + new_cache(table); + let m$7 = m$4, e$5 = e$4, n$20 = n$17; + var + clo$0 = + function(obj){ + var _j_ = obj[1 + e$5][1 + n$20]; + return caml_call1(caml_get_public_method(_j_, m$7, 0), _j_); + }; + break; + default: + var m$5 = next(0), n$18 = next(0); + new_cache(table); + let m$6 = m$5, n$19 = n$18; + var + clo$0 = + function(obj){ + var _i_ = caml_call1(obj[1][1 + n$19], obj); + return caml_call1(caml_get_public_method(_i_, m$6, 0), _i_); + }; + } + else + var clo$0 = clo; + set_method(table, label, clo$0); + i[1]++; + } + } + function stats(param){ + return [0, table_count[1], method_count[1], inst_var_count[1]]; + } + var + CamlinternalOO = + [0, + public_method_label, + new_method, + new_variable, + new_methods_variables, + get_variable, + get_variables, + get_method_label, + get_method_labels, + get_method, + set_method, + set_methods, + narrow, + widen, + add_initializer, + dummy_table, + create_table, + init_class, + inherits, + make_class, + make_class_store, + dummy_class, + copy, + create_object, + create_object_opt, + run_initializers, + run_initializers_opt, + create_object_and_run_initiali, + lookup_tables, + params, + stats]; + runtime.caml_register_global(17, CamlinternalOO, "CamlinternalOO"); + return; + } + (globalThis)); + +//# 25359 "../.js/default/stdlib/stdlib.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst_Bigarray_Array3_of_array_n$1 = + "Bigarray.Array3.of_array: non-cubic data", + caml_ba_change_layout = runtime.caml_ba_change_layout, + caml_ba_create = runtime.caml_ba_create, + caml_ba_dim_1 = runtime.caml_ba_dim_1, + caml_ba_dim_2 = runtime.caml_ba_dim_2, + caml_ba_kind = runtime.caml_ba_kind, + caml_ba_num_dims = runtime.caml_ba_num_dims, + caml_ba_reshape = runtime.caml_ba_reshape, + caml_ba_set_1 = runtime.caml_ba_set_1, + caml_ba_set_2 = runtime.caml_ba_set_2, + caml_ba_set_3 = runtime.caml_ba_set_3, + caml_ba_set_generic = runtime.caml_ba_set_generic, + caml_ba_slice = runtime.caml_ba_slice, + caml_check_bound = runtime.caml_check_bound, + caml_make_vect = runtime.caml_make_vect, + caml_mul = runtime.caml_mul; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + var + undef = undefined, + global_data = runtime.caml_get_global_data(), + Stdlib = global_data.Stdlib, + Stdlib_Array = global_data.Stdlib__Array, + Stdlib_Sys = global_data.Stdlib__Sys; + function kind_size_in_bytes(param){ + switch(param){ + case 0: + return 4; + case 1: + return 8; + case 2: + return 1; + case 3: + return 1; + case 4: + return 2; + case 5: + return 2; + case 6: + return 4; + case 7: + return 8; + case 8: + return Stdlib_Sys[9] / 8 | 0; + case 9: + return Stdlib_Sys[9] / 8 | 0; + case 10: + return 8; + case 11: + return 16; + default: return 1; + } + } + var + cst_Bigarray_Array2_of_array_n = + "Bigarray.Array2.of_array: non-rectangular data", + cst_Bigarray_Array3_of_array_n = cst_Bigarray_Array3_of_array_n$1, + cst_Bigarray_Array3_of_array_n$0 = cst_Bigarray_Array3_of_array_n$1, + cst_Bigarray_array0_of_genarra = "Bigarray.array0_of_genarray", + cst_Bigarray_array1_of_genarra = "Bigarray.array1_of_genarray", + cst_Bigarray_array2_of_genarra = "Bigarray.array2_of_genarray", + cst_Bigarray_array3_of_genarra = "Bigarray.array3_of_genarray"; + function cloop(arr, idx, f, col, max){ + if(col === idx.length - 1){ + caml_ba_set_generic(arr, idx, caml_call1(f, idx)); + return; + } + var _am_ = caml_check_bound(max, col)[1 + col] - 1 | 0, _al_ = 0; + if(_am_ >= 0){ + var j = _al_; + for(;;){ + caml_check_bound(idx, col)[1 + col] = j; + cloop(arr, idx, f, col + 1 | 0, max); + var _an_ = j + 1 | 0; + if(_am_ === j) break; + j = _an_; + } + } + return; + } + function floop(arr, idx, f, col, max){ + if(0 > col){caml_ba_set_generic(arr, idx, caml_call1(f, idx)); return;} + var _aj_ = caml_check_bound(max, col)[1 + col], _ai_ = 1; + if(_aj_ >= 1){ + var j = _ai_; + for(;;){ + caml_check_bound(idx, col)[1 + col] = j; + floop(arr, idx, f, col - 1 | 0, max); + var _ak_ = j + 1 | 0; + if(_aj_ === j) break; + j = _ak_; + } + } + return; + } + function init(kind, layout, dims, f){ + var arr = caml_ba_create(kind, layout, dims), match = dims.length - 1; + return 0 === match + ? arr + : layout + ? (floop + (arr, caml_make_vect(match, 1), f, match - 1 | 0, dims), + arr) + : (cloop(arr, caml_make_vect(match, 0), f, 0, dims), arr); + } + function dims(a){ + var + n = caml_ba_num_dims(a), + d = caml_make_vect(n, 0), + _af_ = n - 1 | 0, + _ae_ = 0; + if(_af_ >= 0){ + var i = _ae_; + for(;;){ + var _ag_ = runtime.caml_ba_dim(a, i); + caml_check_bound(d, i)[1 + i] = _ag_; + var _ah_ = i + 1 | 0; + if(_af_ === i) break; + i = _ah_; + } + } + return d; + } + function size_in_bytes(arr){ + var + _ac_ = dims(arr), + _ad_ = caml_call3(Stdlib_Array[17], caml_mul, 1, _ac_); + return caml_mul(kind_size_in_bytes(caml_ba_kind(arr)), _ad_); + } + function create(kind, layout){return caml_ba_create(kind, layout, [0]);} + function get(arr){return runtime.caml_ba_get_generic(arr, [0]);} + function set(arr){ + var _aa_ = [0]; + return function(_ab_){return caml_ba_set_generic(arr, _aa_, _ab_);}; + } + function size_in_bytes$0(arr){ + return kind_size_in_bytes(caml_ba_kind(arr)); + } + function of_value(kind, layout, v){ + var a = create(kind, layout); + set(a)(v); + return a; + } + function create$0(kind, layout, dim){ + return caml_ba_create(kind, layout, [0, dim]); + } + function size_in_bytes$1(arr){ + var _$_ = caml_ba_dim_1(arr); + return caml_mul(kind_size_in_bytes(caml_ba_kind(arr)), _$_); + } + function slice(a, n){ + return runtime.caml_ba_layout(a) + ? caml_ba_slice(a, [0, n]) + : caml_ba_slice(a, [0, n]); + } + function init$0(kind, layout, dim, f){ + var arr = create$0(kind, layout, dim); + if(layout){ + var _Z_ = 1; + if(dim >= 1){ + var i$0 = _Z_; + for(;;){ + caml_ba_set_1(arr, i$0, caml_call1(f, i$0)); + var ___ = i$0 + 1 | 0; + if(dim === i$0) break; + i$0 = ___; + } + } + return arr; + } + var _X_ = dim - 1 | 0, _W_ = 0; + if(_X_ >= 0){ + var i = _W_; + for(;;){ + caml_ba_set_1(arr, i, caml_call1(f, i)); + var _Y_ = i + 1 | 0; + if(_X_ === i) break; + i = _Y_; + } + } + return arr; + } + function of_array(kind, layout, data){ + var + ba = create$0(kind, layout, data.length - 1), + ofs = layout ? 1 : 0, + _U_ = data.length - 2 | 0, + _T_ = 0; + if(_U_ >= 0){ + var i = _T_; + for(;;){ + caml_ba_set_1(ba, i + ofs | 0, caml_check_bound(data, i)[1 + i]); + var _V_ = i + 1 | 0; + if(_U_ === i) break; + i = _V_; + } + } + return ba; + } + function create$1(kind, layout, dim1, dim2){ + return caml_ba_create(kind, layout, [0, dim1, dim2]); + } + function size_in_bytes$2(arr){ + var _R_ = caml_ba_dim_2(arr), _S_ = caml_ba_dim_1(arr); + return caml_mul(caml_mul(kind_size_in_bytes(caml_ba_kind(arr)), _S_), _R_); + } + function slice_left(a, n){return caml_ba_slice(a, [0, n]);} + function slice_right(a, n){return caml_ba_slice(a, [0, n]);} + function init$1(kind, layout, dim1, dim2, f){ + var arr = create$1(kind, layout, dim1, dim2); + if(layout){ + var _N_ = 1; + if(dim2 >= 1){ + var j$0 = _N_; + for(;;){ + var _O_ = 1; + if(dim1 >= 1){ + var i$0 = _O_; + for(;;){ + caml_ba_set_2(arr, i$0, j$0, caml_call2(f, i$0, j$0)); + var _Q_ = i$0 + 1 | 0; + if(dim1 === i$0) break; + i$0 = _Q_; + } + } + var _P_ = j$0 + 1 | 0; + if(dim2 === j$0) break; + j$0 = _P_; + } + } + return arr; + } + var _I_ = dim1 - 1 | 0, _H_ = 0; + if(_I_ >= 0){ + var i = _H_; + for(;;){ + var _K_ = dim2 - 1 | 0, _J_ = 0; + if(_K_ >= 0){ + var j = _J_; + for(;;){ + caml_ba_set_2(arr, i, j, caml_call2(f, i, j)); + var _M_ = j + 1 | 0; + if(_K_ === j) break; + j = _M_; + } + } + var _L_ = i + 1 | 0; + if(_I_ === i) break; + i = _L_; + } + } + return arr; + } + function of_array$0(kind, layout, data){ + var + dim1 = data.length - 1, + dim2 = 0 === dim1 ? 0 : caml_check_bound(data, 0)[1].length - 1, + ba = create$1(kind, layout, dim1, dim2), + ofs = layout ? 1 : 0, + _C_ = dim1 - 1 | 0, + _B_ = 0; + if(_C_ >= 0){ + var i = _B_; + for(;;){ + var row = caml_check_bound(data, i)[1 + i]; + if(row.length - 1 !== dim2) + caml_call1(Stdlib[1], cst_Bigarray_Array2_of_array_n); + var _E_ = dim2 - 1 | 0, _D_ = 0; + if(_E_ >= 0){ + var j = _D_; + for(;;){ + caml_ba_set_2 + (ba, i + ofs | 0, j + ofs | 0, caml_check_bound(row, j)[1 + j]); + var _G_ = j + 1 | 0; + if(_E_ === j) break; + j = _G_; + } + } + var _F_ = i + 1 | 0; + if(_C_ === i) break; + i = _F_; + } + } + return ba; + } + function create$2(kind, layout, dim1, dim2, dim3){ + return caml_ba_create(kind, layout, [0, dim1, dim2, dim3]); + } + function size_in_bytes$3(arr){ + var + _y_ = runtime.caml_ba_dim_3(arr), + _z_ = caml_ba_dim_2(arr), + _A_ = caml_ba_dim_1(arr); + return caml_mul + (caml_mul + (caml_mul(kind_size_in_bytes(caml_ba_kind(arr)), _A_), _z_), + _y_); + } + function slice_left_1(a, n, m){return caml_ba_slice(a, [0, n, m]);} + function slice_right_1(a, n, m){return caml_ba_slice(a, [0, n, m]);} + function slice_left_2(a, n){return caml_ba_slice(a, [0, n]);} + function slice_right_2(a, n){return caml_ba_slice(a, [0, n]);} + function init$2(kind, layout, dim1, dim2, dim3, f){ + var arr = create$2(kind, layout, dim1, dim2, dim3); + if(layout){ + var _s_ = 1; + if(dim3 >= 1){ + var k$0 = _s_; + for(;;){ + var _t_ = 1; + if(dim2 >= 1){ + var j$0 = _t_; + for(;;){ + var _v_ = 1; + if(dim1 >= 1){ + var i$0 = _v_; + for(;;){ + caml_ba_set_3(arr, i$0, j$0, k$0, caml_call3(f, i$0, j$0, k$0)); + var _x_ = i$0 + 1 | 0; + if(dim1 === i$0) break; + i$0 = _x_; + } + } + var _w_ = j$0 + 1 | 0; + if(dim2 === j$0) break; + j$0 = _w_; + } + } + var _u_ = k$0 + 1 | 0; + if(dim3 === k$0) break; + k$0 = _u_; + } + } + return arr; + } + var _k_ = dim1 - 1 | 0, _j_ = 0; + if(_k_ >= 0){ + var i = _j_; + for(;;){ + var _m_ = dim2 - 1 | 0, _l_ = 0; + if(_m_ >= 0){ + var j = _l_; + for(;;){ + var _p_ = dim3 - 1 | 0, _o_ = 0; + if(_p_ >= 0){ + var k = _o_; + for(;;){ + caml_ba_set_3(arr, i, j, k, caml_call3(f, i, j, k)); + var _r_ = k + 1 | 0; + if(_p_ === k) break; + k = _r_; + } + } + var _q_ = j + 1 | 0; + if(_m_ === j) break; + j = _q_; + } + } + var _n_ = i + 1 | 0; + if(_k_ === i) break; + i = _n_; + } + } + return arr; + } + function of_array$1(kind, layout, data){ + var + dim1 = data.length - 1, + dim2 = 0 === dim1 ? 0 : caml_check_bound(data, 0)[1].length - 1, + dim3 = + 0 === dim2 + ? 0 + : caml_check_bound(caml_check_bound(data, 0)[1], 0)[1].length - 1, + ba = create$2(kind, layout, dim1, dim2, dim3), + ofs = layout ? 1 : 0, + _b_ = dim1 - 1 | 0, + _a_ = 0; + if(_b_ >= 0){ + var i = _a_; + for(;;){ + var row = caml_check_bound(data, i)[1 + i]; + if(row.length - 1 !== dim2) + caml_call1(Stdlib[1], cst_Bigarray_Array3_of_array_n); + var _d_ = dim2 - 1 | 0, _c_ = 0; + if(_d_ >= 0){ + var j = _c_; + for(;;){ + var col = caml_check_bound(row, j)[1 + j]; + if(col.length - 1 !== dim3) + caml_call1(Stdlib[1], cst_Bigarray_Array3_of_array_n$0); + var _g_ = dim3 - 1 | 0, _f_ = 0; + if(_g_ >= 0){ + var k = _f_; + for(;;){ + caml_ba_set_3 + (ba, + i + ofs | 0, + j + ofs | 0, + k + ofs | 0, + caml_check_bound(col, k)[1 + k]); + var _i_ = k + 1 | 0; + if(_g_ === k) break; + k = _i_; + } + } + var _h_ = j + 1 | 0; + if(_d_ === j) break; + j = _h_; + } + } + var _e_ = i + 1 | 0; + if(_b_ === i) break; + i = _e_; + } + } + return ba; + } + function array0_of_genarray(a){ + return 0 === caml_ba_num_dims(a) + ? a + : caml_call1(Stdlib[1], cst_Bigarray_array0_of_genarra); + } + function array1_of_genarray(a){ + return 1 === caml_ba_num_dims(a) + ? a + : caml_call1(Stdlib[1], cst_Bigarray_array1_of_genarra); + } + function array2_of_genarray(a){ + return 2 === caml_ba_num_dims(a) + ? a + : caml_call1(Stdlib[1], cst_Bigarray_array2_of_genarra); + } + function array3_of_genarray(a){ + return 3 === caml_ba_num_dims(a) + ? a + : caml_call1(Stdlib[1], cst_Bigarray_array3_of_genarra); + } + function reshape_0(a){return caml_ba_reshape(a, [0]);} + function reshape_1(a, dim1){return caml_ba_reshape(a, [0, dim1]);} + function reshape_2(a, dim1, dim2){ + return caml_ba_reshape(a, [0, dim1, dim2]); + } + function reshape_3(a, dim1, dim2, dim3){ + return caml_ba_reshape(a, [0, dim1, dim2, dim3]); + } + var + Stdlib_Bigarray = + [0, + 0, + 1, + 10, + 11, + 2, + 3, + 4, + 5, + 8, + 6, + 7, + 9, + 12, + kind_size_in_bytes, + 0, + 1, + [0, init, dims, size_in_bytes], + [0, + create, + of_value, + caml_ba_change_layout, + size_in_bytes$0, + get, + set, + of_value], + [0, + create$0, + init$0, + caml_ba_change_layout, + size_in_bytes$1, + slice, + of_array], + [0, + create$1, + init$1, + caml_ba_change_layout, + size_in_bytes$2, + slice_left, + slice_right, + of_array$0], + [0, + create$2, + init$2, + caml_ba_change_layout, + size_in_bytes$3, + slice_left_1, + slice_right_1, + slice_left_2, + slice_right_2, + of_array$1], + array0_of_genarray, + array1_of_genarray, + array2_of_genarray, + array3_of_genarray, + caml_ba_reshape, + reshape_0, + reshape_1, + reshape_2, + reshape_3]; + runtime.caml_register_global(10, Stdlib_Bigarray, "Stdlib__Bigarray"); + return; + } + (globalThis)); + + +//# 1 "../.js/default/js_of_ocaml-compiler.runtime/jsoo_runtime.cma.js" +// Generated by js_of_ocaml +//# 3 "../.js/default/js_of_ocaml-compiler.runtime/jsoo_runtime.cma.js" + +//# 18 "../.js/default/js_of_ocaml-compiler.runtime/jsoo_runtime.cma.js" +(function(globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + s = "5.8.2", + git_version = "", + Jsoo_runtime_Runtime_version = [0, s, git_version]; + runtime.caml_register_global + (2, Jsoo_runtime_Runtime_version, "Jsoo_runtime__Runtime_version"); + return; + } + (globalThis)); + +//# 33 "../.js/default/js_of_ocaml-compiler.runtime/jsoo_runtime.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + var + global_data = runtime.caml_get_global_data(), + Jsoo_runtime_Runtime_version = global_data.Jsoo_runtime__Runtime_version, + Stdlib_Callback = global_data.Stdlib__Callback, + Js = [0], + Config = [0], + version = Jsoo_runtime_Runtime_version[1], + git_version = Jsoo_runtime_Runtime_version[2], + Sys = [0, Config, version, git_version], + Exn = [248, "Jsoo_runtime.Error.Exn", runtime.caml_fresh_oo_id(0)]; + caml_call2(Stdlib_Callback[2], "jsError", [0, Exn, [0]]); + function raise(exn){throw exn;} + var + Error = + [0, + raise, + runtime.caml_exn_with_js_backtrace, + runtime.caml_js_error_option_of_exception, + Exn], + For_compatibility_only = [0], + Bigstring = [0], + Typed_array = [0, Bigstring], + Int64 = [0], + Jsoo_runtime = + [0, Js, Sys, Error, For_compatibility_only, Typed_array, Int64]; + runtime.caml_register_global(5, Jsoo_runtime, "Jsoo_runtime"); + return; + } + (globalThis)); + + +//# 1 "../.js/default/js_of_ocaml/js_of_ocaml.cma.js" +// Generated by js_of_ocaml +//# 3 "../.js/default/js_of_ocaml/js_of_ocaml.cma.js" + +//# 19 "../.js/default/js_of_ocaml/js_of_ocaml.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + global_data = runtime.caml_get_global_data(), + Stdlib_String = global_data.Stdlib__String, + Stdlib_Char = global_data.Stdlib__Char, + Poly = [0]; + function max(x, y){return y <= x ? x : y;} + function min(x, y){return x <= y ? x : y;} + var + Int_replace_polymorphic_compar = [0, max, min], + make = Stdlib_String[1], + init = Stdlib_String[2], + empty = Stdlib_String[3], + of_bytes = Stdlib_String[4], + to_bytes = Stdlib_String[5], + concat = Stdlib_String[6], + cat = Stdlib_String[7], + compare = Stdlib_String[9], + starts_with = Stdlib_String[10], + ends_with = Stdlib_String[11], + contains_from = Stdlib_String[12], + rcontains_from = Stdlib_String[13], + contains = Stdlib_String[14], + sub = Stdlib_String[15], + split_on_char = Stdlib_String[16], + map = Stdlib_String[17], + mapi = Stdlib_String[18], + fold_left = Stdlib_String[19], + fold_right = Stdlib_String[20], + for_all = Stdlib_String[21], + exists = Stdlib_String[22], + trim = Stdlib_String[23], + escaped = Stdlib_String[24], + uppercase_ascii = Stdlib_String[25], + lowercase_ascii = Stdlib_String[26], + capitalize_ascii = Stdlib_String[27], + uncapitalize_ascii = Stdlib_String[28], + iter = Stdlib_String[29], + iteri = Stdlib_String[30], + index_from = Stdlib_String[31], + index_from_opt = Stdlib_String[32], + rindex_from = Stdlib_String[33], + rindex_from_opt = Stdlib_String[34], + index = Stdlib_String[35], + index_opt = Stdlib_String[36], + rindex = Stdlib_String[37], + rindex_opt = Stdlib_String[38], + to_seq = Stdlib_String[39], + to_seqi = Stdlib_String[40], + of_seq = Stdlib_String[41], + blit = Stdlib_String[42], + copy = Stdlib_String[43], + fill = Stdlib_String[44], + uppercase = Stdlib_String[45], + lowercase = Stdlib_String[46], + capitalize = Stdlib_String[47], + uncapitalize = Stdlib_String[48], + get_uint8 = Stdlib_String[49], + get_int8 = Stdlib_String[50], + get_uint16_ne = Stdlib_String[51], + get_uint16_be = Stdlib_String[52], + get_uint16_le = Stdlib_String[53], + get_int16_ne = Stdlib_String[54], + get_int16_be = Stdlib_String[55], + get_int16_le = Stdlib_String[56], + get_int32_ne = Stdlib_String[57], + get_int32_be = Stdlib_String[58], + get_int32_le = Stdlib_String[59], + get_int64_ne = Stdlib_String[60], + get_int64_be = Stdlib_String[61], + get_int64_le = Stdlib_String[62], + equal = runtime.caml_string_equal, + String = + [0, + make, + init, + empty, + of_bytes, + to_bytes, + concat, + cat, + compare, + starts_with, + ends_with, + contains_from, + rcontains_from, + contains, + sub, + split_on_char, + map, + mapi, + fold_left, + fold_right, + for_all, + exists, + trim, + escaped, + uppercase_ascii, + lowercase_ascii, + capitalize_ascii, + uncapitalize_ascii, + iter, + iteri, + index_from, + index_from_opt, + rindex_from, + rindex_from_opt, + index, + index_opt, + rindex, + rindex_opt, + to_seq, + to_seqi, + of_seq, + blit, + copy, + fill, + uppercase, + lowercase, + capitalize, + uncapitalize, + get_uint8, + get_int8, + get_uint16_ne, + get_uint16_be, + get_uint16_le, + get_int16_ne, + get_int16_be, + get_int16_le, + get_int32_ne, + get_int32_be, + get_int32_le, + get_int64_ne, + get_int64_be, + get_int64_le, + equal], + chr = Stdlib_Char[1], + escaped$0 = Stdlib_Char[2], + lowercase$0 = Stdlib_Char[3], + uppercase$0 = Stdlib_Char[4], + lowercase_ascii$0 = Stdlib_Char[5], + uppercase_ascii$0 = Stdlib_Char[6], + compare$0 = Stdlib_Char[7]; + function equal$0(x, y){return x === y ? 1 : 0;} + var + Char = + [0, + chr, + escaped$0, + lowercase$0, + uppercase$0, + lowercase_ascii$0, + uppercase_ascii$0, + compare$0, + equal$0], + max$0 = Int_replace_polymorphic_compar[1], + min$0 = Int_replace_polymorphic_compar[2], + Js_of_ocaml_Import = + [0, Poly, Int_replace_polymorphic_compar, String, Char, max$0, min$0]; + runtime.caml_register_global(2, Js_of_ocaml_Import, "Js_of_ocaml__Import"); + return; + } + (globalThis)); + +//# 188 "../.js/default/js_of_ocaml/js_of_ocaml.cma.js" +(function + (globalThis){ + "use strict"; + var + jsoo_exports = typeof module === "object" && module.exports || globalThis, + runtime = globalThis.jsoo_runtime, + cst_parseFloat$0 = "parseFloat", + cst_parseInt$0 = "parseInt", + caml_js_get = runtime.caml_js_get, + caml_js_set = runtime.caml_js_set, + caml_js_wrap_callback = runtime.caml_js_wrap_callback, + caml_string_of_jsstring = runtime.caml_string_of_jsstring; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + var + global_data = runtime.caml_get_global_data(), + Js_of_ocaml_Import = global_data.Js_of_ocaml__Import, + Stdlib = global_data.Stdlib, + Jsoo_runtime = global_data.Jsoo_runtime, + Stdlib_Printexc = global_data.Stdlib__Printexc, + global = globalThis, + Unsafe = [0, global], + null$0 = null, + undefined$0 = undefined; + function return$0(_p_){return _p_;} + function map(x, f){return x == null$0 ? null$0 : caml_call1(f, x);} + function bind(x, f){return x == null$0 ? null$0 : caml_call1(f, x);} + function test(x){return 1 - (x == null$0 ? 1 : 0);} + function iter(x, f){ + var _o_ = 1 - (x == null$0 ? 1 : 0); + return _o_ ? caml_call1(f, x) : _o_; + } + function case$0(x, f, g){ + return x == null$0 ? caml_call1(f, 0) : caml_call1(g, x); + } + function get(x, f){return x == null$0 ? caml_call1(f, 0) : x;} + function option(x){if(! x) return null$0; var x$0 = x[1]; return x$0;} + function to_option(x){return x == null$0 ? 0 : [0, x];} + var + Opt = + [0, + null$0, + return$0, + map, + bind, + test, + iter, + case$0, + get, + option, + to_option]; + function return$1(_n_){return _n_;} + function map$0(x, f){ + return x === undefined$0 ? undefined$0 : caml_call1(f, x); + } + function bind$0(x, f){ + return x === undefined$0 ? undefined$0 : caml_call1(f, x); + } + function test$0(x){return 1 - (x === undefined$0 ? 1 : 0);} + function iter$0(x, f){ + var _m_ = 1 - (x === undefined$0 ? 1 : 0); + return _m_ ? caml_call1(f, x) : _m_; + } + function case$1(x, f, g){ + return x === undefined$0 ? caml_call1(f, 0) : caml_call1(g, x); + } + function get$0(x, f){return x === undefined$0 ? caml_call1(f, 0) : x;} + function option$0(x){ + if(! x) return undefined$0; + var x$0 = x[1]; + return x$0; + } + function to_option$0(x){return x === undefined$0 ? 0 : [0, x];} + var + Optdef = + [0, + undefined$0, + return$1, + map$0, + bind$0, + test$0, + iter$0, + case$1, + get$0, + option$0, + to_option$0]; + function coerce(x, f, g){ + var _l_ = caml_call1(f, x); + return caml_call2(Opt[8], _l_, function(param){return caml_call1(g, x);}); + } + function coerce_opt(x, f, g){ + var _k_ = caml_call2(Opt[4], x, f); + return caml_call2(Opt[8], _k_, function(param){return caml_call1(g, x);}); + } + var + true$0 = true, + false$0 = false, + nfc = "NFC", + nfd = "NFD", + nfkc = "NFKC", + nfkd = "NFKD", + t0 = Unsafe[1], + string_constr = t0.String, + t1 = Unsafe[1], + regExp = t1.RegExp, + t2 = Unsafe[1], + object_constructor = t2.Object; + function object_keys(t3){return object_constructor.keys(t3);} + var + t5 = Unsafe[1], + array_constructor = t5.Array, + array_get = caml_js_get, + array_set = caml_js_set; + function array_map(f, t7){ + var + cb = + caml_js_wrap_callback + (function(x, idx, param){return caml_call1(f, x);}); + return t7.map(cb); + } + function array_mapi(f, t7){ + var + cb = + caml_js_wrap_callback + (function(x, idx, param){return caml_call2(f, idx, x);}); + return t7.map(cb); + } + function str_array(_j_){return _j_;} + function match_result(_i_){return _i_;} + var + t8 = Unsafe[1], + date_constr = t8.Date, + t9 = Unsafe[1], + math = t9.Math, + t10 = Unsafe[1], + error_constr = t10.Error, + include = Jsoo_runtime[3], + raise = include[1], + exn_with_js_backtrace = include[2], + of_exn = include[3], + Error = include[4]; + function name(t11){return caml_string_of_jsstring(t11.name);} + function message(t12){return caml_string_of_jsstring(t12.message);} + function stack(t13){ + var _h_ = caml_call2(Opt[3], t13.stack, caml_string_of_jsstring); + return caml_call1(Opt[10], _h_); + } + function to_string(t14){return caml_string_of_jsstring(t14.toString());} + function raise_js_error(e){return caml_call1(raise, e);} + function string_of_error(e){return to_string(e);} + var + t15 = Unsafe[1], + JSON = t15.JSON, + cst_parseInt = cst_parseInt$0, + cst_parseFloat = cst_parseFloat$0; + function decodeURI(s){var t16 = Unsafe[1]; return t16.decodeURI(s);} + function decodeURIComponent(s){ + var t17 = Unsafe[1]; + return t17.decodeURIComponent(s); + } + function encodeURI(s){var t18 = Unsafe[1]; return t18.encodeURI(s);} + function encodeURIComponent(s){ + var t19 = Unsafe[1]; + return t19.encodeURIComponent(s); + } + function escape(s){var t20 = Unsafe[1]; return t20.escape(s);} + function unescape(s){var t21 = Unsafe[1]; return t21.unescape(s);} + function isNaN(i){var t22 = Unsafe[1]; return t22.isNaN(i) | 0;} + function parseInt(s){ + var t23 = Unsafe[1], s$0 = t23.parseInt(s); + return isNaN(s$0) ? caml_call1(Stdlib[2], cst_parseInt) : s$0; + } + function parseFloat(s){ + var t24 = Unsafe[1], s$0 = t24.parseFloat(s); + return isNaN(s$0) ? caml_call1(Stdlib[2], cst_parseFloat) : s$0; + } + caml_call1 + (Stdlib_Printexc[9], + function(param){ + if(param[1] !== Error) return 0; + var e = param[2]; + return [0, to_string(e)]; + }); + caml_call1 + (Stdlib_Printexc[9], + function(t25){ + return t25 instanceof array_constructor + ? 0 + : [0, caml_string_of_jsstring(t25.toString())]; + }); + var cst_function = "function"; + function export_js(field, x){ + var _f_ = caml_string_of_jsstring(typeof x); + a: + { + if + (caml_call2(Js_of_ocaml_Import[3][62], _f_, cst_function) + && 0 < x.length){ + var _g_ = caml_js_wrap_callback(x); + break a; + } + var _g_ = x; + } + return jsoo_exports[field] = _g_; + } + function export$0(field, x){ + return export_js(runtime.caml_jsstring_of_string(field), x); + } + function export_all(obj){ + var + keys = object_constructor.keys(obj), + t26 = + caml_js_wrap_callback + (function(key, param, _e_){return export_js(key, obj[key]);}); + return keys.forEach(t26); + } + var + Js_of_ocaml_Js = + [0, + null$0, + function(_d_){return _d_;}, + undefined$0, + function(_c_){return _c_;}, + Opt, + Optdef, + true$0, + false$0, + nfd, + nfc, + nfkd, + nfkc, + string_constr, + regExp, + regExp, + regExp, + object_keys, + array_constructor, + array_constructor, + array_get, + array_set, + array_map, + array_mapi, + str_array, + match_result, + date_constr, + date_constr, + date_constr, + date_constr, + date_constr, + date_constr, + date_constr, + date_constr, + date_constr, + math, + error_constr, + [0, + to_string, + name, + message, + stack, + raise, + exn_with_js_backtrace, + of_exn, + Error, + function(_b_){return _b_;}, + function(_a_){return _a_;}], + JSON, + decodeURI, + decodeURIComponent, + encodeURI, + encodeURIComponent, + escape, + unescape, + isNaN, + parseInt, + parseFloat, + coerce, + coerce_opt, + export$0, + export_all, + Unsafe, + string_of_error, + raise_js_error, + exn_with_js_backtrace, + runtime.caml_js_error_of_exception, + Error]; + runtime.caml_register_global(43, Js_of_ocaml_Js, "Js_of_ocaml__Js"); + return; + } + (globalThis)); + + +//# 1 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +// Generated by js_of_ocaml +//# 3 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" + +//# 24 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function(globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function decide(decision){return decision;} + function decide_rel(relDecision){return relDecision;} + function top(top0){return top0;} + function bottom(bottom0){return bottom0;} + var UIML_Base = [0, decide, decide_rel, top, bottom]; + runtime.caml_register_global(0, UIML_Base, "UIML__Base"); + return; + } + (globalThis)); + +//# 38 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function(globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime, coq_Top = [1, 0, 0]; + function coq_Neg(a){return [1, a, 0];} + function coq_And(a, b){return coq_Neg([1, a, coq_Neg(b)]);} + function coq_Or(a, b){return [1, coq_Neg(a), b];} + function coq_Diam(a){return coq_Neg([2, coq_Neg(a)]);} + function eq_dec_form(m, x0){ + var m$0 = m, x0$0 = x0; + for(;;){ + if(typeof m$0 === "number") return typeof x0$0 === "number" ? 1 : 0; + switch(m$0[0]){ + case 0: + var s = m$0[1]; + if(typeof x0$0 !== "number" && 0 === x0$0[0]){ + var + s0 = x0$0[1], + f = + function(s1, x1){ + if(! s1) return x1 ? 0 : 1; + var s2 = s1[2], a = s1[1]; + if(! x1) return 0; + var s3 = x1[2], a0 = x1[1]; + function h$0(i){return 0 !== (a & 1 << i) ? 1 : 0;} + var + b6 = h$0(7), + b5 = h$0(6), + b4 = h$0(5), + b3 = h$0(4), + b2 = h$0(3), + b1 = h$0(2), + b0 = h$0(1), + b = h$0(0); + function f$0(b7, b8, b9, b10, b11, b12, b13, b14){ + return b + ? b7 + ? b0 + ? b8 + ? b1 + ? b9 + ? b2 + ? b10 + ? b3 + ? b11 + ? b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b11 + ? 0 + : b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b10 + ? 0 + : b3 + ? b11 + ? b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b11 + ? 0 + : b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b9 + ? 0 + : b2 + ? b10 + ? b3 + ? b11 + ? b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b11 + ? 0 + : b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b10 + ? 0 + : b3 + ? b11 + ? b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b11 + ? 0 + : b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b8 + ? 0 + : b1 + ? b9 + ? b2 + ? b10 + ? b3 + ? b11 + ? b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b11 + ? 0 + : b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b10 + ? 0 + : b3 + ? b11 + ? b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b11 + ? 0 + : b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b9 + ? 0 + : b2 + ? b10 + ? b3 + ? b11 + ? b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b11 + ? 0 + : b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b10 + ? 0 + : b3 + ? b11 + ? b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b11 + ? 0 + : b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b7 + ? 0 + : b0 + ? b8 + ? b1 + ? b9 + ? b2 + ? b10 + ? b3 + ? b11 + ? b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b11 + ? 0 + : b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b10 + ? 0 + : b3 + ? b11 + ? b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b11 + ? 0 + : b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b9 + ? 0 + : b2 + ? b10 + ? b3 + ? b11 + ? b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b11 + ? 0 + : b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b10 + ? 0 + : b3 + ? b11 + ? b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b11 + ? 0 + : b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b8 + ? 0 + : b1 + ? b9 + ? b2 + ? b10 + ? b3 + ? b11 + ? b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b11 + ? 0 + : b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b10 + ? 0 + : b3 + ? b11 + ? b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b11 + ? 0 + : b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b9 + ? 0 + : b2 + ? b10 + ? b3 + ? b11 + ? b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b11 + ? 0 + : b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b10 + ? 0 + : b3 + ? b11 + ? b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b11 + ? 0 + : b4 + ? b12 + ? b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) + : 0 + : b12 + ? 0 + : b5 + ? b13 ? b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3) : 0 + : b13 ? 0 : b6 ? b14 ? f(s2, s3) : 0 : b14 ? 0 : f(s2, s3); + } + function h(i){return 0 !== (a0 & 1 << i) ? 1 : 0;} + var + _b_ = h(7), + _c_ = h(6), + _d_ = h(5), + _e_ = h(4), + _f_ = h(3), + _g_ = h(2), + _h_ = h(1); + return f$0(h(0), _h_, _g_, _f_, _e_, _d_, _c_, _b_); + }; + return f(s, s0); + } + return 0; + case 1: + var m1 = m$0[2], m0 = m$0[1]; + if(typeof x0$0 !== "number" && 1 === x0$0[0]){ + var m3 = x0$0[2], m2 = x0$0[1]; + if(! eq_dec_form(m0, m2)) return 0; + m$0 = m1; + x0$0 = m3; + break; + } + return 0; + default: + var m0$0 = m$0[1]; + if(typeof x0$0 !== "number" && 2 === x0$0[0]){ + var m1$0 = x0$0[1]; + m$0 = m0$0; + x0$0 = m1$0; + break; + } + return 0; + } + } + } + function unBox_formula(x){ + if(typeof x !== "number" && 2 === x[0]){var a0 = x[1]; return a0;} + return x; + } + function unboxed_list(param){ + if(! param) return 0; + var t = param[2], h = param[1], _a_ = unboxed_list(t); + return [0, unBox_formula(h), _a_]; + } + function top_boxes(param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + var t = param$0[2], h = param$0[1]; + if(typeof h !== "number" && 2 === h[0]){ + var a = h[1]; + return [0, [2, a], top_boxes(t)]; + } + param$0 = t; + } + } + var + UIML_CML_Syntax = + [0, + coq_Top, + coq_Neg, + coq_And, + coq_Or, + coq_Diam, + eq_dec_form, + unBox_formula, + unboxed_list, + top_boxes]; + runtime.caml_register_global(1, UIML_CML_Syntax, "UIML__CML_Syntax"); + return; + } + (globalThis)); + +//# 655 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function(globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function fst(param){var x = param[1]; return x;} + function snd(param){var y = param[2]; return y;} + function length(param){ + if(! param) return 0; + var l = param[2]; + return [0, length(l)]; + } + function app(l, m){ + if(! l) return m; + var l1 = l[2], a = l[1]; + return [0, a, app(l1, m)]; + } + var UIML_Datatypes = [0, fst, snd, length, app]; + runtime.caml_register_global(0, UIML_Datatypes, "UIML__Datatypes"); + return; + } + (globalThis)); + +//# 677 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function(globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function le_lt_dec(n, m){ + var n$0 = n, m$0 = m; + for(;;){ + if(! n$0) return 1; + var n0 = n$0[1]; + if(! m$0) return 0; + var n1 = m$0[1]; + n$0 = n0; + m$0 = n1; + } + } + function lt_dec(n, m){return le_lt_dec([0, n], m);} + var UIML_Compare_dec = [0, le_lt_dec, le_lt_dec, le_lt_dec, lt_dec]; + runtime.caml_register_global(0, UIML_Compare_dec, "UIML__Compare_dec"); + return; + } + (globalThis)); + +//# 699 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function(globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function add(n, m){if(! n) return m; var p = n[1]; return [0, add(p, m)];} + var UIML_Nat = [0, add]; + runtime.caml_register_global(0, UIML_Nat, "UIML__Nat"); + return; + } + (globalThis)); + +//# 710 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function(globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function string_dec(s, x){ + var s$0 = s, x$0 = x; + for(;;){ + if(! s$0) return x$0 ? 0 : 1; + var s0 = s$0[2], a = s$0[1]; + if(! x$0) return 0; + var s1 = x$0[2], a0 = x$0[1]; + if(! runtime.caml_equal(a, a0)) return 0; + s$0 = s0; + x$0 = s1; + } + } + var UIML_String = [0, string_dec]; + runtime.caml_register_global(0, UIML_String, "UIML__String"); + return; + } + (globalThis)); + +//# 733 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + var + global_data = runtime.caml_get_global_data(), + form_top = [3, 0, 0], + UIML_Base = global_data.UIML__Base, + UIML_Nat = global_data.UIML__Nat, + UIML_String = global_data.UIML__String, + string_dec = UIML_String[1], + _a_ = [0, 0], + _b_ = [0, [0, 0]], + _c_ = [0, [0, [0, 0]]], + _d_ = [0, 0], + _e_ = [0, 0]; + function form_eq_dec(f, x0){ + var f$0 = f, x0$0 = x0; + for(;;){ + if(typeof f$0 === "number") return typeof x0$0 === "number" ? 1 : 0; + switch(f$0[0]){ + case 0: + var v = f$0[1]; + if(typeof x0$0 !== "number" && 0 === x0$0[0]){ + var v0 = x0$0[1]; + return caml_call3(UIML_Base[2], string_dec, v, v0); + } + return 0; + case 1: + var f1 = f$0[2], f0 = f$0[1]; + if(typeof x0$0 !== "number" && 1 === x0$0[0]){ + var f3 = x0$0[2], f2 = x0$0[1]; + if(! form_eq_dec(f0, f2)) return 0; + f$0 = f1; + x0$0 = f3; + break; + } + return 0; + case 2: + var f1$0 = f$0[2], f0$0 = f$0[1]; + if(typeof x0$0 !== "number" && 2 === x0$0[0]){ + var f3$0 = x0$0[2], f2$0 = x0$0[1]; + if(! form_eq_dec(f0$0, f2$0)) return 0; + f$0 = f1$0; + x0$0 = f3$0; + break; + } + return 0; + case 3: + var f1$1 = f$0[2], f0$1 = f$0[1]; + if(typeof x0$0 !== "number" && 3 === x0$0[0]){ + var f3$1 = x0$0[2], f2$1 = x0$0[1]; + if(! form_eq_dec(f0$1, f2$1)) return 0; + f$0 = f1$1; + x0$0 = f3$1; + break; + } + return 0; + default: + var f0$2 = f$0[1]; + if(typeof x0$0 !== "number" && 4 === x0$0[0]){ + var f1$2 = x0$0[1]; + f$0 = f0$2; + x0$0 = f1$2; + break; + } + return 0; + } + } + } + function weight(param){ + if(typeof param !== "number") + switch(param[0]){ + case 1: + var + UU03c8 = param[2], + UU03c6_0 = param[1], + _f_ = weight(UU03c8), + _g_ = weight(UU03c6_0), + _h_ = caml_call2(UIML_Nat[1], _b_, _g_); + return caml_call2(UIML_Nat[1], _h_, _f_); + case 2: + var + UU03c8$0 = param[2], + UU03c6_0$0 = param[1], + _i_ = weight(UU03c8$0), + _j_ = weight(UU03c6_0$0), + _k_ = caml_call2(UIML_Nat[1], _c_, _j_); + return caml_call2(UIML_Nat[1], _k_, _i_); + case 3: + var + UU03c8$1 = param[2], + UU03c6_0$1 = param[1], + _l_ = weight(UU03c8$1), + _m_ = weight(UU03c6_0$1), + _n_ = caml_call2(UIML_Nat[1], _d_, _m_); + return caml_call2(UIML_Nat[1], _n_, _l_); + case 4: + var UU03c6_0$2 = param[1], _o_ = weight(UU03c6_0$2); + return caml_call2(UIML_Nat[1], _e_, _o_); + } + return _a_; + } + var UIML_Formulas = [0, 0, form_top, string_dec, form_eq_dec, weight]; + runtime.caml_register_global(9, UIML_Formulas, "UIML__Formulas"); + return; + } + (globalThis)); + +//# 853 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function(globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function in_dec(h, a, param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + var l0 = param$0[2], y = param$0[1], s = caml_call2(h, y, a); + if(s) return 1; + param$0 = l0; + } + } + function remove(eq_dec, x, param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + var tl = param$0[2], y = param$0[1]; + if(! caml_call2(eq_dec, x, y)) return [0, y, remove(eq_dec, x, tl)]; + param$0 = tl; + } + } + function list_eq_dec(eq_dec, l$0, l){ + var l$2 = l$0, l$1 = l; + for(;;){ + if(! l$2) return l$1 ? 0 : 1; + var l0 = l$2[2], y = l$2[1]; + if(! l$1) return 0; + var l1 = l$1[2], a = l$1[1]; + if(! caml_call2(eq_dec, y, a)) return 0; + l$2 = l0; + l$1 = l1; + } + } + function map(f, param){ + if(! param) return 0; + var t = param[2], a = param[1], _a_ = map(f, t); + return [0, caml_call1(f, a), _a_]; + } + function nodup(decA, param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + var xs = param$0[2], x = param$0[1]; + if(! in_dec(decA, x, xs)) return [0, x, nodup(decA, xs)]; + param$0 = xs; + } + } + var UIML_List = [0, in_dec, remove, list_eq_dec, map, nodup]; + runtime.caml_register_global(0, UIML_List, "UIML__List"); + return; + } + (globalThis)); + +//# 918 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_Base = global_data.UIML__Base; + function foldl(f, a, param){ + var a$0 = a, param$0 = param; + for(;;){ + if(! param$0) return a$0; + var l0 = param$0[2], x = param$0[1], a$1 = caml_call2(f, a$0, x); + a$0 = a$1; + param$0 = l0; + } + } + function elem_of_list_dec(dec, x, param){ + var param$0 = param; + for(;;){ + if(! param$0) return 0; + var + l0 = param$0[2], + y = param$0[1], + _a_ = caml_call3(UIML_Base[2], dec, x, y); + if(caml_call1(UIML_Base[1], _a_)) return 1; + param$0 = l0; + } + } + var UIML_List0 = [0, foldl, elem_of_list_dec]; + runtime.caml_register_global(1, UIML_List0, "UIML__List0"); + return; + } + (globalThis)); + +//# 968 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function(globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function comparison_eq_dec(x, y){ + switch(x){ + case 0: + return y ? 0 : 1; + case 1: + return 1 === y ? 1 : 0; + default: return 2 <= y ? 1 : 0; + } + } + var UIML_Numbers = [0, comparison_eq_dec]; + runtime.caml_register_global(0, UIML_Numbers, "UIML__Numbers"); + return; + } + (globalThis)); + +//# 988 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_Formulas = global_data.UIML__Formulas, + UIML_Base = global_data.UIML__Base, + UIML_Numbers = global_data.UIML__Numbers, + UIML_List = global_data.UIML__List, + UIML_List0 = global_data.UIML__List0, + _a_ = [3, 0, 0], + _b_ = [3, 0, 0], + _c_ = [3, 0, 0], + _d_ = [3, 0, 0], + _e_ = [3, 0, 0], + _f_ = [3, 0, 0]; + function symbol(param){return symbol;} + function decidable_is_implication(UU03c6, UU03c8){ + if(typeof UU03c6 !== "number" && 3 === UU03c6[0]){ + var + f = UU03c6[2], + _aE_ = caml_call3(UIML_Base[2], UIML_Formulas[4], f, UU03c8); + return caml_call1(UIML_Base[1], _aE_); + } + return 0; + } + function decidable_is_negation(UU03c6, UU03c8){ + var + _aD_ = caml_call3(UIML_Base[2], UIML_Formulas[4], UU03c6, [3, UU03c8, 0]); + return caml_call1(UIML_Base[1], _aD_); + } + function obviously_smaller(UU03c6, UU03c8){ + if(typeof UU03c6 === "number") return 1; + switch(UU03c6[0]){ + case 0: + if(typeof UU03c8 === "number") return 2; + if(3 === UU03c8[0]){ + var f = UU03c8[1]; + if(typeof f === "number") return 1; + var _M_ = caml_call3(UIML_Base[2], UIML_Formulas[4], UU03c6, UU03c8); + if(caml_call1(UIML_Base[1], _M_)) return 1; + var _N_ = decidable_is_negation(UU03c6, [3, UU03c8, 0]); + if(caml_call1(UIML_Base[1], _N_)) return 2; + var _O_ = decidable_is_negation(UU03c8, [3, UU03c6, 0]); + if(caml_call1(UIML_Base[1], _O_)) return 1; + var _P_ = decidable_is_implication(UU03c6, UU03c8); + if(caml_call1(UIML_Base[1], _P_)) return 2; + var _Q_ = decidable_is_implication(UU03c8, UU03c6); + return caml_call1(UIML_Base[1], _Q_) ? 1 : 0; + } + var _H_ = caml_call3(UIML_Base[2], UIML_Formulas[4], UU03c6, UU03c8); + if(caml_call1(UIML_Base[1], _H_)) return 1; + var _I_ = decidable_is_negation(UU03c6, [3, UU03c8, 0]); + if(caml_call1(UIML_Base[1], _I_)) return 2; + var _J_ = decidable_is_negation(UU03c8, [3, UU03c6, 0]); + if(caml_call1(UIML_Base[1], _J_)) return 1; + var _K_ = decidable_is_implication(UU03c6, UU03c8); + if(caml_call1(UIML_Base[1], _K_)) return 2; + var _L_ = decidable_is_implication(UU03c8, UU03c6); + return caml_call1(UIML_Base[1], _L_) ? 1 : 0; + case 1: + var UU03c8_0 = UU03c6[2], UU03c6_0 = UU03c6[1]; + if(typeof UU03c8 === "number") return 2; + if(3 !== UU03c8[0]){ + var + c = obviously_smaller(UU03c6_0, UU03c8), + c0 = obviously_smaller(UU03c8_0, UU03c8); + switch(c){ + case 0: + return 1 === c0 ? 1 : 0; + case 1: + return 1; + default: return c0; + } + } + var f$0 = UU03c8[1]; + if(typeof f$0 === "number") return 1; + var + c$0 = obviously_smaller(UU03c6_0, UU03c8), + c0$0 = obviously_smaller(UU03c8_0, UU03c8); + switch(c$0){ + case 0: + return 1 === c0$0 ? 1 : 0; + case 1: + return 1; + default: return c0$0; + } + case 2: + var UU03c8_0$0 = UU03c6[2], UU03c6_0$0 = UU03c6[1]; + if(typeof UU03c8 === "number") return 2; + if(3 !== UU03c8[0]){ + var + c$1 = obviously_smaller(UU03c6_0$0, UU03c8), + c0$1 = obviously_smaller(UU03c8_0$0, UU03c8); + switch(c$1){ + case 0: + return 2 <= c0$1 ? 2 : 0; + case 1: + return c0$1; + default: return 2; + } + } + var f$1 = UU03c8[1]; + if(typeof f$1 === "number") return 1; + var + c$2 = obviously_smaller(UU03c6_0$0, UU03c8), + c0$2 = obviously_smaller(UU03c8_0$0, UU03c8); + switch(c$2){ + case 0: + return 2 <= c0$2 ? 2 : 0; + case 1: + return c0$2; + default: return 2; + } + case 3: + var f$2 = UU03c6[1]; + if(typeof f$2 === "number") return 2; + switch(f$2[0]){ + case 0: + if(typeof UU03c8 === "number") return 2; + if(3 === UU03c8[0]){ + var f1 = UU03c8[1]; + if(typeof f1 === "number") return 1; + var + _W_ = caml_call3(UIML_Base[2], UIML_Formulas[4], UU03c6, UU03c8); + if(caml_call1(UIML_Base[1], _W_)) return 1; + var _X_ = decidable_is_negation(UU03c6, [3, UU03c8, 0]); + if(caml_call1(UIML_Base[1], _X_)) return 2; + var _Y_ = decidable_is_negation(UU03c8, [3, UU03c6, 0]); + if(caml_call1(UIML_Base[1], _Y_)) return 1; + var _Z_ = decidable_is_implication(UU03c6, UU03c8); + if(caml_call1(UIML_Base[1], _Z_)) return 2; + var ___ = decidable_is_implication(UU03c8, UU03c6); + return caml_call1(UIML_Base[1], ___) ? 1 : 0; + } + var + _R_ = caml_call3(UIML_Base[2], UIML_Formulas[4], UU03c6, UU03c8); + if(caml_call1(UIML_Base[1], _R_)) return 1; + var _S_ = decidable_is_negation(UU03c6, [3, UU03c8, 0]); + if(caml_call1(UIML_Base[1], _S_)) return 2; + var _T_ = decidable_is_negation(UU03c8, [3, UU03c6, 0]); + if(caml_call1(UIML_Base[1], _T_)) return 1; + var _U_ = decidable_is_implication(UU03c6, UU03c8); + if(caml_call1(UIML_Base[1], _U_)) return 2; + var _V_ = decidable_is_implication(UU03c8, UU03c6); + return caml_call1(UIML_Base[1], _V_) ? 1 : 0; + case 4: + if(typeof UU03c8 === "number") return 2; + if(3 === UU03c8[0]){ + var f2 = UU03c8[1]; + if(typeof f2 === "number") return 1; + var + _ao_ = caml_call3(UIML_Base[2], UIML_Formulas[4], UU03c6, UU03c8); + if(caml_call1(UIML_Base[1], _ao_)) return 1; + var _ap_ = decidable_is_negation(UU03c6, [3, UU03c8, 0]); + if(caml_call1(UIML_Base[1], _ap_)) return 2; + var _aq_ = decidable_is_negation(UU03c8, [3, UU03c6, 0]); + if(caml_call1(UIML_Base[1], _aq_)) return 1; + var _ar_ = decidable_is_implication(UU03c6, UU03c8); + if(caml_call1(UIML_Base[1], _ar_)) return 2; + var _as_ = decidable_is_implication(UU03c8, UU03c6); + return caml_call1(UIML_Base[1], _as_) ? 1 : 0; + } + var + _aj_ = caml_call3(UIML_Base[2], UIML_Formulas[4], UU03c6, UU03c8); + if(caml_call1(UIML_Base[1], _aj_)) return 1; + var _ak_ = decidable_is_negation(UU03c6, [3, UU03c8, 0]); + if(caml_call1(UIML_Base[1], _ak_)) return 2; + var _al_ = decidable_is_negation(UU03c8, [3, UU03c6, 0]); + if(caml_call1(UIML_Base[1], _al_)) return 1; + var _am_ = decidable_is_implication(UU03c6, UU03c8); + if(caml_call1(UIML_Base[1], _am_)) return 2; + var _an_ = decidable_is_implication(UU03c8, UU03c6); + return caml_call1(UIML_Base[1], _an_) ? 1 : 0; + default: + if(typeof UU03c8 === "number") return 2; + if(3 === UU03c8[0]){ + var f3 = UU03c8[1]; + if(typeof f3 === "number") return 1; + var + _ae_ = caml_call3(UIML_Base[2], UIML_Formulas[4], UU03c6, UU03c8); + if(caml_call1(UIML_Base[1], _ae_)) return 1; + var _af_ = decidable_is_negation(UU03c6, [3, UU03c8, 0]); + if(caml_call1(UIML_Base[1], _af_)) return 2; + var _ag_ = decidable_is_negation(UU03c8, [3, UU03c6, 0]); + if(caml_call1(UIML_Base[1], _ag_)) return 1; + var _ah_ = decidable_is_implication(UU03c6, UU03c8); + if(caml_call1(UIML_Base[1], _ah_)) return 2; + var _ai_ = decidable_is_implication(UU03c8, UU03c6); + return caml_call1(UIML_Base[1], _ai_) ? 1 : 0; + } + var + _$_ = caml_call3(UIML_Base[2], UIML_Formulas[4], UU03c6, UU03c8); + if(caml_call1(UIML_Base[1], _$_)) return 1; + var _aa_ = decidable_is_negation(UU03c6, [3, UU03c8, 0]); + if(caml_call1(UIML_Base[1], _aa_)) return 2; + var _ab_ = decidable_is_negation(UU03c8, [3, UU03c6, 0]); + if(caml_call1(UIML_Base[1], _ab_)) return 1; + var _ac_ = decidable_is_implication(UU03c6, UU03c8); + if(caml_call1(UIML_Base[1], _ac_)) return 2; + var _ad_ = decidable_is_implication(UU03c8, UU03c6); + return caml_call1(UIML_Base[1], _ad_) ? 1 : 0; + } + default: + if(typeof UU03c8 === "number") return 2; + if(3 === UU03c8[0]){ + var f0 = UU03c8[1]; + if(typeof f0 === "number") return 1; + var _ay_ = caml_call3(UIML_Base[2], UIML_Formulas[4], UU03c6, UU03c8); + if(caml_call1(UIML_Base[1], _ay_)) return 1; + var _az_ = decidable_is_negation(UU03c6, [3, UU03c8, 0]); + if(caml_call1(UIML_Base[1], _az_)) return 2; + var _aA_ = decidable_is_negation(UU03c8, [3, UU03c6, 0]); + if(caml_call1(UIML_Base[1], _aA_)) return 1; + var _aB_ = decidable_is_implication(UU03c6, UU03c8); + if(caml_call1(UIML_Base[1], _aB_)) return 2; + var _aC_ = decidable_is_implication(UU03c8, UU03c6); + return caml_call1(UIML_Base[1], _aC_) ? 1 : 0; + } + var _at_ = caml_call3(UIML_Base[2], UIML_Formulas[4], UU03c6, UU03c8); + if(caml_call1(UIML_Base[1], _at_)) return 1; + var _au_ = decidable_is_negation(UU03c6, [3, UU03c8, 0]); + if(caml_call1(UIML_Base[1], _au_)) return 2; + var _av_ = decidable_is_negation(UU03c8, [3, UU03c6, 0]); + if(caml_call1(UIML_Base[1], _av_)) return 1; + var _aw_ = decidable_is_implication(UU03c6, UU03c8); + if(caml_call1(UIML_Base[1], _aw_)) return 2; + var _ax_ = decidable_is_implication(UU03c8, UU03c6); + return caml_call1(UIML_Base[1], _ax_) ? 1 : 0; + } + } + function choose_conj(UU03c6, UU03c8){ + switch(obviously_smaller(UU03c6, UU03c8)){ + case 0: + return [1, UU03c6, UU03c8]; + case 1: + return UU03c6; + default: return UU03c8; + } + } + function make_conj(UU03c6, UU03c8){ + if(typeof UU03c8 !== "number") + switch(UU03c8[0]){ + case 1: + var UU03c8_2 = UU03c8[2], UU03c8_1 = UU03c8[1]; + switch(obviously_smaller(UU03c6, UU03c8_1)){ + case 0: + return [1, UU03c6, [1, UU03c8_1, UU03c8_2]]; + case 1: + return [1, UU03c6, UU03c8_2]; + default: return [1, UU03c8_1, UU03c8_2]; + } + case 2: + var + UU03c8_2$0 = UU03c8[2], + UU03c8_1$0 = UU03c8[1], + _B_ = obviously_smaller(UU03c6, UU03c8_1$0), + _C_ = caml_call3(UIML_Base[2], UIML_Numbers[1], _B_, 1); + if(caml_call1(UIML_Base[1], _C_)) return UU03c6; + var + _D_ = obviously_smaller(UU03c6, UU03c8_2$0), + _E_ = caml_call3(UIML_Base[2], UIML_Numbers[1], _D_, 1); + return caml_call1(UIML_Base[1], _E_) + ? UU03c6 + : choose_conj(UU03c6, [2, UU03c8_1$0, UU03c8_2$0]); + case 3: + var + UU03c8_2$1 = UU03c8[2], + UU03c8_1$1 = UU03c8[1], + _F_ = obviously_smaller(UU03c6, UU03c8_1$1), + _G_ = caml_call3(UIML_Base[2], UIML_Numbers[1], _F_, 1); + return caml_call1(UIML_Base[1], _G_) + ? choose_conj(UU03c6, UU03c8_2$1) + : choose_conj(UU03c6, UU03c8); + } + if(typeof UU03c6 !== "number" && 3 === UU03c6[0]){ + var + UU03c6_2 = UU03c6[2], + UU03c6_1 = UU03c6[1], + _z_ = obviously_smaller(UU03c8, UU03c6_1), + _A_ = caml_call3(UIML_Base[2], UIML_Numbers[1], _z_, 1); + return caml_call1(UIML_Base[1], _A_) + ? choose_conj(UU03c6_2, UU03c8) + : choose_conj(UU03c6, UU03c8); + } + return choose_conj(UU03c6, UU03c8); + } + function choose_disj(UU03c6, UU03c8){ + switch(obviously_smaller(UU03c6, UU03c8)){ + case 0: + switch(obviously_smaller(UU03c8, UU03c6)){ + case 0: + return [2, UU03c6, UU03c8]; + case 1: + return UU03c6; + default: return UU03c8; + } + case 1: + return UU03c8; + default: return UU03c6; + } + } + function make_disj(UU03c6, UU03c8){ + if(typeof UU03c8 !== "number") + switch(UU03c8[0]){ + case 1: + var + UU03c8_2 = UU03c8[2], + UU03c8_1 = UU03c8[1], + _v_ = obviously_smaller(UU03c6, UU03c8_1), + _w_ = caml_call3(UIML_Base[2], UIML_Numbers[1], _v_, 2); + if(caml_call1(UIML_Base[1], _w_)) return UU03c6; + var + _x_ = obviously_smaller(UU03c6, UU03c8_2), + _y_ = caml_call3(UIML_Base[2], UIML_Numbers[1], _x_, 2); + return caml_call1(UIML_Base[1], _y_) + ? UU03c6 + : choose_disj(UU03c6, [1, UU03c8_1, UU03c8_2]); + case 2: + var UU03c8_2$0 = UU03c8[2], UU03c8_1$0 = UU03c8[1]; + switch(obviously_smaller(UU03c6, UU03c8_1$0)){ + case 0: + return [2, UU03c6, [2, UU03c8_1$0, UU03c8_2$0]]; + case 1: + return [2, UU03c8_1$0, UU03c8_2$0]; + default: return [2, UU03c6, UU03c8_2$0]; + } + } + return choose_disj(UU03c6, UU03c8); + } + function make_impl(UU03c6, UU03c8){ + var UU03c6$0 = UU03c6, UU03c8$0 = UU03c8; + for(;;){ + if(typeof UU03c8$0 !== "number" && 3 === UU03c8$0[0]){ + var + UU03c8_2 = UU03c8$0[2], + UU03c8_1 = UU03c8$0[1], + UU03c6$1 = make_conj(UU03c6$0, UU03c8_1); + UU03c6$0 = UU03c6$1; + UU03c8$0 = UU03c8_2; + continue; + } + var + _j_ = obviously_smaller(UU03c6$0, UU03c8$0), + _k_ = caml_call3(UIML_Base[2], UIML_Numbers[1], _j_, 1); + if(caml_call1(UIML_Base[1], _k_)) return _a_; + var + _l_ = obviously_smaller(UU03c6$0, 0), + _m_ = caml_call3(UIML_Base[2], UIML_Numbers[1], _l_, 1); + if(caml_call1(UIML_Base[1], _m_)) return _b_; + var + _n_ = obviously_smaller(UU03c8$0, _c_), + _o_ = caml_call3(UIML_Base[2], UIML_Numbers[1], _n_, 2); + if(caml_call1(UIML_Base[1], _o_)) return _d_; + var + _p_ = obviously_smaller(UU03c6$0, _e_), + _q_ = caml_call3(UIML_Base[2], UIML_Numbers[1], _p_, 2); + if(caml_call1(UIML_Base[1], _q_)) return UU03c8$0; + var + _r_ = obviously_smaller(UU03c8$0, 0), + _s_ = caml_call3(UIML_Base[2], UIML_Numbers[1], _r_, 1); + if(caml_call1(UIML_Base[1], _s_)) return [3, UU03c6$0, 0]; + var _t_ = decidable_is_negation(UU03c6$0, UU03c8$0); + if(caml_call1(UIML_Base[1], _t_)) return [3, UU03c6$0, 0]; + var _u_ = decidable_is_negation(UU03c8$0, UU03c6$0); + return caml_call1(UIML_Base[1], _u_) ? UU03c8$0 : [3, UU03c6$0, UU03c8$0]; + } + } + function conjunction(l){ + var _i_ = caml_call2(UIML_List[5], UIML_Formulas[4], l); + return caml_call3(UIML_List0[1], make_conj, _f_, _i_); + } + function disjunction(l){ + var _h_ = caml_call2(UIML_List[5], UIML_Formulas[4], l); + return caml_call3(UIML_List0[1], make_disj, 0, _h_); + } + function in_map_aux(UU0393, f, param){ + if(! param) return 0; + var + UU0393_0 = param[2], + a = param[1], + _g_ = in_map_aux(UU0393, f, UU0393_0); + return [0, caml_call2(f, a, symbol), _g_]; + } + function in_map(UU0393, f){return in_map_aux(UU0393, f, UU0393);} + function rm(x, param){ + if(! param) return 0; + var t = param[2], h = param[1]; + return caml_call2(UIML_Formulas[4], x, h) ? t : [0, h, rm(x, t)]; + } + function open_box(UU03c6){ + if(typeof UU03c6 !== "number" && 4 === UU03c6[0]){var UU03c6_0 = UU03c6[1]; return UU03c6_0;} + return UU03c6; + } + var + UIML_Environments = + [0, + decidable_is_implication, + decidable_is_negation, + obviously_smaller, + choose_conj, + make_conj, + choose_disj, + make_disj, + make_impl, + conjunction, + disjunction, + in_map_aux, + in_map, + rm, + open_box]; + runtime.caml_register_global(11, UIML_Environments, "UIML__Environments"); + return; + } + (globalThis)); + +//# 1422 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_CML_Syntax = global_data.UIML__CML_Syntax; + function coq_XBoxed_list(param){ + if(! param) return 0; + var t = param[2], h = param[1], _a_ = [0, h, coq_XBoxed_list(t)]; + return [0, caml_call1(UIML_CML_Syntax[7], h), _a_]; + } + var UIML_GLS_calcs = [0, coq_XBoxed_list]; + runtime.caml_register_global(1, UIML_GLS_calcs, "UIML__GLS_calcs"); + return; + } + (globalThis)); + +//# 1446 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function(globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function coq_InT_eq(a, l){return [0, a, l];} + var UIML_GenT = [0, coq_InT_eq]; + runtime.caml_register_global(0, UIML_GenT, "UIML__GenT"); + return; + } + (globalThis)); + +//# 1467 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace; + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_GenT = global_data.UIML__GenT, + UIML_Datatypes = global_data.UIML__Datatypes, + Assert_failure = global_data.Assert_failure, + _a_ = [0, "extraction/List_lemmasT.ml", 28, 20]; + function coq_InT_app_or(l, l2, a, x){ + if(! l) return [1, x]; + var l0 = l[2], y = l[1]; + if(0 === x[0]) return [0, caml_call2(UIML_GenT[1], y, l0)]; + var i = x[3], x0 = coq_InT_app_or(l0, l2, a, i); + if(0 === x0[0]){var i0 = x0[1]; return [0, [1, y, l0, i0]];} + var i0$0 = x0[1]; + return [1, i0$0]; + } + function coq_InT_or_app(l, l2, a, x){ + if(! l){ + if(0 === x[0]) + throw caml_maybe_attach_backtrace([0, Assert_failure, _a_], 1); + var i$1 = x[1]; + return i$1; + } + var l0 = l[2], y = l[1]; + if(0 !== x[0]){ + var i$0 = x[1], _d_ = coq_InT_or_app(l0, l2, a, [1, i$0]); + return [1, y, caml_call2(UIML_Datatypes[4], l0, l2), _d_]; + } + var i = x[1]; + if(0 === i[0]){ + var + app0 = + function(l1, m){ + if(! l1) return m; + var l3 = l1[2], a0 = l1[1]; + return [0, a0, app0(l3, m)]; + }, + _b_ = app0(l0, l2); + return caml_call2(UIML_GenT[1], y, _b_); + } + var i0 = i[3], _c_ = coq_InT_or_app(l0, l2, a, [0, i0]); + return [1, y, caml_call2(UIML_Datatypes[4], l0, l2), _c_]; + } + var UIML_List_lemmasT = [0, coq_InT_app_or, coq_InT_or_app]; + runtime.caml_register_global(4, UIML_List_lemmasT, "UIML__List_lemmasT"); + return; + } + (globalThis)); + +//# 1537 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst_extraction_list_lems_ml = "extraction/list_lems.ml", + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call4(f, a0, a1, a2, a3){ + return (f.l >= 0 ? f.l : f.l = f.length) == 4 + ? f(a0, a1, a2, a3) + : runtime.caml_call_gen(f, [a0, a1, a2, a3]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_CML_Syntax = global_data.UIML__CML_Syntax, + UIML_Datatypes = global_data.UIML__Datatypes, + Assert_failure = global_data.Assert_failure, + UIML_GenT = global_data.UIML__GenT, + UIML_List_lemmasT = global_data.UIML__List_lemmasT, + UIML_List = global_data.UIML__List, + _a_ = [0, cst_extraction_list_lems_ml, 17, 8]; + function symbol(param){return symbol;} + function in_splitT(x, param){ + if(! param) + throw caml_maybe_attach_backtrace([0, Assert_failure, _a_], 1); + var l0 = param[2], y = param[1], s = caml_call2(UIML_CML_Syntax[6], x, y); + if(s) return [0, 0, [0, l0, symbol]]; + var h0 = in_splitT(x, l0), s0 = h0[2], x0 = h0[1], x1 = s0[1]; + return [0, caml_call2(UIML_Datatypes[4], [0, y, 0], x0), [0, x1, symbol]]; + } + var + eq_dec_listsF = caml_call1(UIML_List[3], UIML_CML_Syntax[6]), + _b_ = [0, cst_extraction_list_lems_ml, 44, 8], + _c_ = [0, cst_extraction_list_lems_ml, 59, 8]; + function eq_dec_seqs(s0, s1){ + var + l0 = s0[2], + l = s0[1], + l2 = s1[2], + l1 = s1[1], + s = caml_call2(eq_dec_listsF, l, l1); + return s ? caml_call2(eq_dec_listsF, l0, l2) : 0; + } + function seqs_in_splitT(x, param){ + if(! param) + throw caml_maybe_attach_backtrace([0, Assert_failure, _b_], 1); + var l0 = param[2], y = param[1], s = eq_dec_seqs(x, y); + if(s) return [0, 0, [0, l0, symbol]]; + var h0 = seqs_in_splitT(x, l0), s0 = h0[2], x0 = h0[1], x1 = s0[1]; + return [0, caml_call2(UIML_Datatypes[4], [0, y, 0], x0), [0, x1, symbol]]; + } + function coq_In_InT_seqs(seq, param){ + if(! param) + throw caml_maybe_attach_backtrace([0, Assert_failure, _c_], 1); + var + l = param[2], + y = param[1], + h = seqs_in_splitT(seq, [0, y, l]), + s = h[2], + x = h[1], + x0 = s[1], + _d_ = [1, caml_call2(UIML_GenT[1], seq, x0)]; + return caml_call4(UIML_List_lemmasT[2], x, [0, seq, x0], seq, _d_); + } + var + UIML_List_lems = + [0, + in_splitT, + eq_dec_listsF, + eq_dec_seqs, + seqs_in_splitT, + coq_In_InT_seqs]; + runtime.caml_register_global(9, UIML_List_lems, "UIML__List_lems"); + return; + } + (globalThis)); + +//# 1626 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_CML_Syntax = global_data.UIML__CML_Syntax, + UIML_List = global_data.UIML__List; + function coq_In_dec(l, a){ + return caml_call3(UIML_List[1], UIML_CML_Syntax[6], a, l); + } + function remove_list(l1, l2){ + if(! l1) return l2; + var t1 = l1[2], h1 = l1[1], _a_ = remove_list(t1, l2); + return caml_call3(UIML_List[2], UIML_CML_Syntax[6], h1, _a_); + } + var UIML_Remove_list_lems = [0, coq_In_dec, remove_list]; + runtime.caml_register_global + (2, UIML_Remove_list_lems, "UIML__Remove_list_lems"); + return; + } + (globalThis)); + +//# 1656 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_List_lems = global_data.UIML__List_lems, + UIML_Remove_list_lems = global_data.UIML__Remove_list_lems, + UIML_Datatypes = global_data.UIML__Datatypes; + function symbol(param){return symbol;} + function dec_prop_var_in(param){ + var l0 = param[2], l = param[1]; + function f(param){ + if(! param) return [1, symbol]; + var l2 = param[2], y = param[1], match = f(l2); + if(0 === match[0]){ + var s0 = match[1], x = s0[1]; + return [0, [0, x, symbol]]; + } + if(typeof y !== "number" && 0 === y[0]){ + var + s0$0 = y[1], + s1 = caml_call2(UIML_Remove_list_lems[1], l0, [0, s0$0]); + return s1 ? [0, [0, s0$0, symbol]] : [1, symbol]; + } + return [1, symbol]; + } + return f(l); + } + function dec_is_box(param){ + if(typeof param !== "number" && 2 === param[0]){var m = param[1]; return [0, [0, m, symbol]];} + return [1, symbol]; + } + function dec_box_in(param){ + var l0 = param[2], l = param[1]; + function f(param){ + if(! param) return [1, symbol]; + var l2 = param[2], y = param[1], match = f(l2); + if(0 === match[0]){ + var s0 = match[1], x = s0[1]; + return [0, [0, x, symbol]]; + } + var s0$0 = dec_is_box(y); + if(0 !== s0$0[0]) return [1, symbol]; + var s1 = s0$0[1], s2 = caml_call2(UIML_Remove_list_lems[1], l0, y); + if(! s2) return [1, symbol]; + var x$0 = s1[1]; + return [0, [0, x$0, symbol]]; + } + return f(l); + } + function dec_init_rules(param){ + var l0 = param[2], l = param[1], s0 = dec_prop_var_in([0, l, l0]); + if(0 === s0[0]){ + var + s1 = s0[1], + x = s1[1], + h = caml_call2(UIML_List_lems[1], [0, x], l), + s2 = h[2], + x0 = h[1], + x1 = s2[1], + h0 = caml_call2(UIML_List_lems[1], [0, x], l0), + s3 = h0[2], + x2 = h0[1], + x3 = s3[1]; + return [0, [0, [0, [0, x, x0, x1, x2, x3]]]]; + } + var s1$0 = caml_call2(UIML_Remove_list_lems[1], l, 0); + if(s1$0){ + var + i = caml_call2(UIML_List_lems[1], 0, l), + s2$0 = i[2], + x$0 = i[1], + x0$0 = s2$0[1]; + return [0, [1, [0, x$0, x0$0, l0]]]; + } + var s2$1 = dec_box_in([0, l, l0]); + if(0 !== s2$1[0]) return [1, symbol]; + var + s3$0 = s2$1[1], + x$1 = s3$0[1], + _a_ = caml_call1(UIML_Datatypes[1], [0, l, l0]), + h$0 = caml_call2(UIML_List_lems[1], [2, x$1], _a_), + s4 = h$0[2], + x0$1 = h$0[1], + x1$0 = s4[1], + _b_ = caml_call1(UIML_Datatypes[2], [0, l, l0]), + h0$0 = caml_call2(UIML_List_lems[1], [2, x$1], _b_), + s5 = h0$0[2], + x2$0 = h0$0[1], + x3$0 = s5[1]; + return [0, [0, [1, [0, x$1, x0$1, x1$0, x2$0, x3$0]]]]; + } + var + UIML_GLS_dec = + [0, dec_prop_var_in, dec_is_box, dec_box_in, dec_init_rules]; + runtime.caml_register_global(3, UIML_GLS_dec, "UIML__GLS_dec"); + return; + } + (globalThis)); + +//# 1768 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function(globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function eq_dec(n, m){ + var n$0 = n, m$0 = m; + for(;;){ + if(! n$0) return m$0 ? 0 : 1; + var n0 = n$0[1]; + if(! m$0) return 0; + var n1 = m$0[1]; + n$0 = n0; + m$0 = n1; + } + } + var Nat = [0, eq_dec], UIML_PeanoNat = [0, Nat]; + runtime.caml_register_global(0, UIML_PeanoNat, "UIML__PeanoNat"); + return; + } + (globalThis)); + +//# 1790 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst_extraction_GLS_der_dec_ml = "extraction/GLS_der_dec.ml", + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call4(f, a0, a1, a2, a3){ + return (f.l >= 0 ? f.l : f.l = f.length) == 4 + ? f(a0, a1, a2, a3) + : runtime.caml_call_gen(f, [a0, a1, a2, a3]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_CML_Syntax = global_data.UIML__CML_Syntax, + UIML_PeanoNat = global_data.UIML__PeanoNat, + UIML_GenT = global_data.UIML__GenT, + Assert_failure = global_data.Assert_failure, + UIML_List = global_data.UIML__List, + UIML_Datatypes = global_data.UIML__Datatypes, + UIML_List_lemmasT = global_data.UIML__List_lemmasT, + UIML_GLS_calcs = global_data.UIML__GLS_calcs, + UIML_List_lems = global_data.UIML__List_lems, + _a_ = [0, cst_extraction_GLS_der_dec_ml, 29, 8], + _b_ = [0, cst_extraction_GLS_der_dec_ml, 46, 4], + _c_ = [0, cst_extraction_GLS_der_dec_ml, 45, 23], + _d_ = [0, 0], + _e_ = [0, cst_extraction_GLS_der_dec_ml, 105, 10], + _f_ = [0, cst_extraction_GLS_der_dec_ml, 122, 10], + _g_ = [0, [0, 0, 0], 0], + _h_ = [0, 0, 0], + _i_ = [0, 0, 0], + _j_ = [0, cst_extraction_GLS_der_dec_ml, 238, 15], + _k_ = [0, 0], + _l_ = [0, cst_extraction_GLS_der_dec_ml, 230, 18], + _m_ = [0, cst_extraction_GLS_der_dec_ml, 218, 10], + _n_ = [0, cst_extraction_GLS_der_dec_ml, 254, 12], + _o_ = [0, cst_extraction_GLS_der_dec_ml, 522, 28], + _p_ = [0, cst_extraction_GLS_der_dec_ml, 428, 18], + _q_ = [0, cst_extraction_GLS_der_dec_ml, 407, 10], + _r_ = [0, cst_extraction_GLS_der_dec_ml, 931, 28], + _s_ = [0, cst_extraction_GLS_der_dec_ml, 839, 23], + _t_ = [0, cst_extraction_GLS_der_dec_ml, 665, 10], + _u_ = [0, cst_extraction_GLS_der_dec_ml, 1200, 40], + _v_ = [0, cst_extraction_GLS_der_dec_ml, 955, 12], + _w_ = [0, cst_extraction_GLS_der_dec_ml, 1291, 10], + _x_ = [0, cst_extraction_GLS_der_dec_ml, 1361, 28], + _y_ = [0, cst_extraction_GLS_der_dec_ml, 1325, 10]; + function symbol(param){return symbol;} + function proj1_sigT2(param){var a = param[1]; return a;} + function proj2_sigT2(param){var b = param[2]; return b;} + function coq_In_InT_pair(a, n, param){ + if(! param) + throw caml_maybe_attach_backtrace([0, Assert_failure, _a_], 1); + var + l0 = param[2], + y = param[1], + n0 = y[2], + m = y[1], + s = caml_call2(UIML_CML_Syntax[6], a, m), + h0 = s ? caml_call2(UIML_PeanoNat[1][1], n, n0) : 0; + return h0 + ? caml_call2(UIML_GenT[1], [0, a, n], l0) + : [1, y, l0, coq_In_InT_pair(a, n, l0)]; + } + function coq_InT_map_iff(f, param){ + if(! param) + return function(param){ + return [0, + function(param){ + throw caml_maybe_attach_backtrace([0, Assert_failure, _c_], 1); + }, + function(param){ + throw caml_maybe_attach_backtrace([0, Assert_failure, _b_], 1); + }];}; + var l0 = param[2], y = param[1], iHl = coq_InT_map_iff(f, l0); + return function(y0){ + return [0, + function(x){ + if(0 === x[0]) + return [0, y, [0, symbol, caml_call2(UIML_GenT[1], y, l0)]]; + var + x0 = x[3], + p = iHl(y0), + s = p[1], + x1 = caml_call1(s, x0), + p0 = x1[2], + x2 = x1[1], + i = p0[2]; + return [0, x2, [0, symbol, [1, y, l0, i]]]; + }, + function(x){ + var p = iHl(y0), i = p[2], p0 = x[2], i0 = p0[2]; + if(0 === i0[0]){ + var + _gF_ = caml_call2(UIML_List[4], f, l0), + _gG_ = caml_call1(f, y); + return caml_call2(UIML_GenT[1], _gG_, _gF_); + } + var + x0 = i0[3], + a = x[1], + x1 = [0, a, [0, symbol, x0]], + x2 = caml_call1(i, x1), + _gH_ = caml_call2(UIML_List[4], f, l0); + return [1, caml_call1(f, y), _gH_, x2]; + }];}; + } + function pos_top_imps(param){ + if(! param) return 0; + var t = param[2], h = param[1]; + if(typeof h !== "number" && 1 === h[0]){ + var b = h[2], a = h[1], _gC_ = pos_top_imps(t); + return [0, + [0, [1, a, b], _d_], + caml_call2 + (UIML_List[4], + function(y){ + var _gE_ = [0, caml_call1(UIML_Datatypes[2], y)]; + return [0, caml_call1(UIML_Datatypes[1], y), _gE_]; + }, + _gC_)]; + } + var _gB_ = pos_top_imps(t); + return caml_call2 + (UIML_List[4], + function(y){ + var _gD_ = [0, caml_call1(UIML_Datatypes[2], y)]; + return [0, caml_call1(UIML_Datatypes[1], y), _gD_]; + }, + _gB_); + } + function top_boxes_nobox_gen_ext(param){ + if(! param) return 0; + var l0 = param[2], y = param[1]; + if(typeof y !== "number" && 2 === y[0]){ + var m = y[1], _gA_ = top_boxes_nobox_gen_ext(l0); + return [0, [2, m], caml_call1(UIML_CML_Syntax[9], l0), l0, _gA_]; + } + var _gz_ = top_boxes_nobox_gen_ext(l0); + return [1, y, caml_call1(UIML_CML_Syntax[9], l0), l0, symbol, _gz_]; + } + function flatten_list(param){ + if(! param) return 0; + var t = param[2], h = param[1], _gy_ = flatten_list(t); + return caml_call2(UIML_Datatypes[4], h, _gy_); + } + function coq_InT_flatten_list_InT_elem(l, b, x){ + if(! l) throw caml_maybe_attach_backtrace([0, Assert_failure, _e_], 1); + var + l0 = l[2], + y = l[1], + _gx_ = flatten_list(l0), + x0 = caml_call4(UIML_List_lemmasT[1], y, _gx_, b, x); + if(0 === x0[0]){ + var i = x0[1]; + return [0, y, [0, i, caml_call2(UIML_GenT[1], y, l0)]]; + } + var + i$0 = x0[1], + i0 = coq_InT_flatten_list_InT_elem(l0, b, i$0), + p = i0[2], + x1 = i0[1], + i2 = p[2], + i1 = p[1]; + return [0, x1, [0, i1, [1, y, l0, i2]]]; + } + function coq_InT_trans_flatten_list(l, bs, b, x, x0){ + if(! l) throw caml_maybe_attach_backtrace([0, Assert_failure, _f_], 1); + var l0 = l[2], y = l[1]; + if(0 === x0[0]){ + var _gu_ = flatten_list(l0); + return caml_call4(UIML_List_lemmasT[2], bs, _gu_, b, [0, x]); + } + var + x1 = x0[3], + _gv_ = [1, coq_InT_trans_flatten_list(l0, bs, b, x, x1)], + _gw_ = flatten_list(l0); + return caml_call4(UIML_List_lemmasT[2], y, _gw_, b, _gv_); + } + function list_of_splits(param){ + if(! param) return [0, _g_, symbol]; + var + l0 = param[2], + y = param[1], + x = list_of_splits(l0)[1], + _gs_ = + caml_call2 + (UIML_List[4], + function(y0){ + var _gt_ = caml_call1(UIML_Datatypes[2], y0); + return [0, [0, y, caml_call1(UIML_Datatypes[1], y0)], _gt_]; + }, + x); + return [0, + caml_call2(UIML_Datatypes[4], [0, [0, 0, [0, y, l0]], 0], _gs_), + symbol]; + } + function listInserts(l, a){ + var a$0 = list_of_splits(l)[1]; + return caml_call2 + (UIML_List[4], + function(y){ + var + _gq_ = [0, a, caml_call1(UIML_Datatypes[2], y)], + _gr_ = caml_call1(UIML_Datatypes[1], y); + return caml_call2(UIML_Datatypes[4], _gr_, _gq_); + }, + a$0); + } + function listInsertsR_Seqs(UU0393, UU0394, a){ + var _gp_ = listInserts(UU0393, a); + return caml_call2(UIML_List[4], function(y){return [0, y, UU0394];}, _gp_); + } + function listInsertsL_Seqs(UU0393, UU0394, a){ + var _go_ = listInserts(UU0394, a); + return caml_call2(UIML_List[4], function(y){return [0, UU0393, y];}, _go_); + } + function remove_nth(n, a, l){ + if(! n) return l; + var m = n[1]; + if(m){ + if(! l) return 0; + var tl = l[2], b = l[1]; + return [0, b, remove_nth(m, a, tl)]; + } + if(! l) return 0; + var tl$0 = l[2], b$0 = l[1]; + return caml_call2(UIML_CML_Syntax[6], a, b$0) ? tl$0 : [0, b$0, tl$0]; + } + function nth_split(n, l){ + if(! n) return [0, 0, l]; + var m = n[1]; + if(m){ + if(! l) return _h_; + var + tl = l[2], + b = l[1], + _gl_ = nth_split(m, tl), + _gm_ = caml_call1(UIML_Datatypes[2], _gl_), + _gn_ = nth_split(m, tl); + return [0, [0, b, caml_call1(UIML_Datatypes[1], _gn_)], _gm_]; + } + if(! l) return _i_; + var tl$0 = l[2], b$0 = l[1]; + return [0, [0, b$0, 0], tl$0]; + } + function prems_Imp_R(l, s){ + var l$0 = l; + for(;;){ + if(! l$0) return 0; + var t = l$0[2], p = l$0[1], n = p[2], c = p[1]; + if(n){ + var m = n[1]; + if(typeof c !== "number" && 1 === c[0]){ + var + b = c[2], + a = c[1], + _ge_ = prems_Imp_R(t, s), + _gf_ = + nth_split + (m, remove_nth([0, m], c, caml_call1(UIML_Datatypes[2], s))), + _gg_ = [0, b, caml_call1(UIML_Datatypes[2], _gf_)], + _gh_ = + nth_split + (m, remove_nth([0, m], c, caml_call1(UIML_Datatypes[2], s))), + _gi_ = caml_call1(UIML_Datatypes[1], _gh_), + _gj_ = caml_call2(UIML_Datatypes[4], _gi_, _gg_), + _gk_ = listInsertsR_Seqs(caml_call1(UIML_Datatypes[1], s), _gj_, a); + return caml_call2(UIML_Datatypes[4], _gk_, _ge_); + } + l$0 = t; + } + else + l$0 = t; + } + } + function coq_In_pos_top_imps_split_l(l, a, n){ + if(! l) throw caml_maybe_attach_backtrace([0, Assert_failure, _m_], 1); + var l0 = l[2], y = l[1]; + if(typeof y !== "number" && 1 === y[0]){ + var + m0 = y[2], + m = y[1], + _gc_ = pos_top_imps(l0), + h = + coq_In_InT_pair + (a, + [0, n], + [0, + [0, [1, m, m0], _k_], + caml_call2 + (UIML_List[4], + function(y0){ + var _gd_ = [0, caml_call1(UIML_Datatypes[2], y0)]; + return [0, caml_call1(UIML_Datatypes[1], y0), _gd_]; + }, + _gc_)]); + if(0 === h[0]) return [0, 0, [0, l0, symbol]]; + if(! n) throw caml_maybe_attach_backtrace([0, Assert_failure, _l_], 1); + var + n0$0 = n[1], + s$0 = coq_In_pos_top_imps_split_l(l0, a, n0$0), + s0$0 = s$0[2], + x = s$0[1], + x0$0 = s0$0[1]; + return [0, [0, [1, m, m0], x], [0, x0$0, symbol]]; + } + if(! n) throw caml_maybe_attach_backtrace([0, Assert_failure, _j_], 1); + var + n0 = n[1], + s = coq_In_pos_top_imps_split_l(l0, a, n0), + s0 = s[2], + x0 = s[1], + x1 = s0[1]; + return [0, [0, y, x0], [0, x1, symbol]]; + } + function coq_ImpR_help01(prem, s, l3){ + var l0 = s[2], l = s[1]; + function f(l1, x){ + if(! l1) throw caml_maybe_attach_backtrace([0, Assert_failure, _n_], 1); + var l2 = l1[2], y = l1[1], n = y[2], m = y[1]; + if(typeof m !== "number" && 1 === m[0]){ + var m1 = m[2], m0 = m[1]; + if(! n){ + var + s0$1 = f(l2, x), + s1$1 = s0$1[2], + x0$1 = s0$1[1], + s2$1 = s1$1[2], + x1$2 = s1$1[1], + s3$1 = s2$1[2], + x2$2 = s2$1[1], + s4$1 = s3$1[2], + x3$2 = s3$1[1], + s5$1 = s4$1[2], + x4$2 = s4$1[1], + s6$1 = s5$1[2], + x5$1 = s5$1[1], + x6$1 = s6$1[1]; + return [0, + x0$1, + [0, + x1$2, + [0, x2$2, [0, x3$2, [0, x4$2, [0, x5$1, [0, x6$1, symbol]]]]]]]; + } + var + n0 = n[1], + prems_Imp_R0 = + function(l4, s0){ + var l4$0 = l4; + for(;;){ + if(! l4$0) return 0; + var l4$1 = l4$0[2], p = l4$0[1], n1 = p[2], c = p[1]; + if(n1){ + var m2 = n1[1]; + if(typeof c !== "number" && 1 === c[0]){ + var + b = c[2], + a = c[1], + _f7_ = prems_Imp_R0(l4$1, s0), + _f8_ = + nth_split + (m2, + remove_nth([0, m2], c, caml_call1(UIML_Datatypes[2], s0))), + _f9_ = [0, b, caml_call1(UIML_Datatypes[2], _f8_)], + _f__ = + nth_split + (m2, + remove_nth([0, m2], c, caml_call1(UIML_Datatypes[2], s0))), + _f$_ = caml_call1(UIML_Datatypes[1], _f__), + _ga_ = caml_call2(UIML_Datatypes[4], _f$_, _f9_), + _gb_ = + listInsertsR_Seqs(caml_call1(UIML_Datatypes[1], s0), _ga_, a); + return caml_call2(UIML_Datatypes[4], _gb_, _f7_); + } + l4$0 = l4$1; + } + else + l4$0 = l4$1; + } + }, + _fR_ = prems_Imp_R0(l2, [0, l, l0]), + _fS_ = + nth_split + (n0, + remove_nth + ([0, n0], [1, m0, m1], caml_call1(UIML_Datatypes[2], [0, l, l0]))), + _fT_ = [0, m1, caml_call1(UIML_Datatypes[2], _fS_)], + _fU_ = + nth_split + (n0, + remove_nth + ([0, n0], [1, m0, m1], caml_call1(UIML_Datatypes[2], [0, l, l0]))), + _fV_ = caml_call1(UIML_Datatypes[1], _fU_), + _fW_ = caml_call2(UIML_Datatypes[4], _fV_, _fT_), + _fX_ = + listInsertsR_Seqs + (caml_call1(UIML_Datatypes[1], [0, l, l0]), _fW_, m0), + x0$0 = caml_call4(UIML_List_lemmasT[1], _fX_, _fR_, prem, x); + if(0 === x0$0[0]){ + var + i = x0$0[1], + l4 = listInserts(l, m0), + f0 = + function(y0){ + var + _f3_ = nth_split(n0, remove_nth([0, n0], [1, m0, m1], l0)), + _f4_ = [0, m1, caml_call1(UIML_Datatypes[2], _f3_)], + _f5_ = nth_split(n0, remove_nth([0, n0], [1, m0, m1], l0)), + _f6_ = caml_call1(UIML_Datatypes[1], _f5_); + return [0, y0, caml_call2(UIML_Datatypes[4], _f6_, _f4_)]; + }, + x1$0 = coq_InT_map_iff(f0, l4)(prem)[1], + i0 = caml_call1(x1$0, i), + p = i0[2], + x2$0 = i0[1], + i1 = p[2], + l4$1 = list_of_splits(l)[1], + f0$0 = + function(y0){ + var + _f1_ = [0, m0, caml_call1(UIML_Datatypes[2], y0)], + _f2_ = caml_call1(UIML_Datatypes[1], y0); + return caml_call2(UIML_Datatypes[4], _f2_, _f1_); + }, + x3$0 = coq_InT_map_iff(f0$0, l4$1)(x2$0)[1], + i2 = caml_call1(x3$0, i1), + x4$0 = i2[1], + l5 = x4$0[2], + l4$0 = x4$0[1], + _fY_ = nth_split(n0, remove_nth([0, n0], [1, m0, m1], l0)), + _fZ_ = [0, caml_call1(UIML_Datatypes[2], _fY_), symbol], + _f0_ = nth_split(n0, remove_nth([0, n0], [1, m0, m1], l0)); + return [0, + n0, + [0, + m0, + [0, + m1, + [0, + l4$0, + [0, l5, [0, caml_call1(UIML_Datatypes[1], _f0_), _fZ_]]]]]]; + } + var + i$0 = x0$0[1], + s0$0 = f(l2, i$0), + s1$0 = s0$0[2], + x1$1 = s0$0[1], + s2$0 = s1$0[2], + x2$1 = s1$0[1], + s3$0 = s2$0[2], + x3$1 = s2$0[1], + s4$0 = s3$0[2], + x4$1 = s3$0[1], + s5$0 = s4$0[2], + x5$0 = s4$0[1], + s6$0 = s5$0[2], + x6$0 = s5$0[1], + x7 = s6$0[1]; + return [0, + x1$1, + [0, + x2$1, + [0, x3$1, [0, x4$1, [0, x5$0, [0, x6$0, [0, x7, symbol]]]]]]]; + } + var + s0 = f(l2, x), + s1 = s0[2], + x0 = s0[1], + s2 = s1[2], + x1 = s1[1], + s3 = s2[2], + x2 = s2[1], + s4 = s3[2], + x3 = s3[1], + s5 = s4[2], + x4 = s4[1], + s6 = s5[2], + x5 = s5[1], + x6 = s6[1]; + return [0, + x0, + [0, x1, [0, x2, [0, x3, [0, x4, [0, x5, [0, x6, symbol]]]]]]]; + } + return function(_fQ_){return f(l3, _fQ_);}; + } + function coq_ImpR_help1(prem, s, x){ + var + s0 = + coq_ImpR_help01 + (prem, s, pos_top_imps(caml_call1(UIML_Datatypes[2], s))) + (x), + s1 = s0[2], + x0 = s0[1], + l = s[2], + s2 = s1[2], + x1 = s1[1], + s3 = s2[2], + x2 = s2[1], + s4 = s3[2], + x3 = s3[1], + x4 = s4[1], + i = coq_In_pos_top_imps_split_l(l, [1, x1, x2], x0), + s5 = i[2], + x5 = i[1], + x6 = s5[1]; + return [0, x1, x2, x3, x4, x5, x6]; + } + function coq_ImpR_help002(UU0393_0, UU0393_1, UU0394_0, UU0394_1, a, b){ + function f(y){ + return [0, y, caml_call2(UIML_Datatypes[4], UU0394_0, [0, b, UU0394_1])]; + } + var + l = listInserts(caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), a), + _fM_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, b, UU0394_1]), + y = [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), _fM_], + x = coq_InT_map_iff(f, l)(y)[2]; + function f0(y0){ + var + _fO_ = [0, a, caml_call1(UIML_Datatypes[2], y0)], + _fP_ = caml_call1(UIML_Datatypes[1], y0); + return caml_call2(UIML_Datatypes[4], _fP_, _fO_); + } + var + l0 = list_of_splits(caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1))[1], + y0 = caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), + x0 = coq_InT_map_iff(f0, l0)(y0)[2], + s = list_of_splits(caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1)), + x1 = s[1], + _fN_ = + [0, + symbol, + caml_call1 + (x0, + [0, + [0, UU0393_0, UU0393_1], + [0, + symbol, + caml_call2(UIML_List_lems[5], [0, UU0393_0, UU0393_1], x1)]])]; + return caml_call1 + (x, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), + _fN_]); + } + function coq_ImpR_help02 + (UU0393_0, UU0393_1, UU0394_0, UU0394_1, a, b, l, n, x){ + var l$0 = l, n$0 = n; + for(;;){ + if(! l$0) throw caml_maybe_attach_backtrace([0, Assert_failure, _q_], 1); + var l0 = l$0[2], y = l$0[1], n0 = y[2], m = y[1]; + if(typeof m !== "number" && 1 === m[0]){ + var + m1 = m[2], + m0 = m[1], + h1$0 = + coq_In_InT_pair([1, a, b], [0, n$0], [0, [0, [1, m0, m1], n0], l0]); + if(0 === h1$0[0]){ + if(UU0394_0){ + var + l1 = UU0394_0[2], + m2 = UU0394_0[1], + _e4_ = + [0, + coq_ImpR_help002(UU0393_0, UU0393_1, [0, m2, l1], UU0394_1, a, b)], + _e5_ = caml_call2(UIML_Datatypes[4], [0, m2, l1], [0, b, UU0394_1]), + prems_Imp_R0 = + function(l2, s){ + var l2$0 = l2; + for(;;){ + if(! l2$0) return 0; + var l2$1 = l2$0[2], p = l2$0[1], n1 = p[2], c = p[1]; + if(n1){ + var m3 = n1[1]; + if(typeof c !== "number" && 1 === c[0]){ + var + b0 = c[2], + a0 = c[1], + _fF_ = prems_Imp_R0(l2$1, s), + _fG_ = + nth_split + (m3, + remove_nth([0, m3], c, caml_call1(UIML_Datatypes[2], s))), + _fH_ = [0, b0, caml_call1(UIML_Datatypes[2], _fG_)], + _fI_ = + nth_split + (m3, + remove_nth([0, m3], c, caml_call1(UIML_Datatypes[2], s))), + _fJ_ = caml_call1(UIML_Datatypes[1], _fI_), + _fK_ = caml_call2(UIML_Datatypes[4], _fJ_, _fH_), + _fL_ = + listInsertsR_Seqs + (caml_call1(UIML_Datatypes[1], s), _fK_, a0); + return caml_call2(UIML_Datatypes[4], _fL_, _fF_); + } + l2$0 = l2$1; + } + else + l2$0 = l2$1; + } + }, + _e6_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), + _e5_], + _e7_ = + caml_call2 + (UIML_Datatypes[4], [0, m2, l1], [0, [1, a, b], UU0394_1]), + _e8_ = + prems_Imp_R0 + (l0, [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _e7_]), + _e9_ = + caml_call2 + (UIML_Datatypes[4], [0, m2, l1], [0, [1, a, b], UU0394_1]), + _e__ = [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _e9_], + _e$_ = caml_call1(UIML_Datatypes[2], _e__), + _fa_ = + remove_nth + ([0, caml_call1(UIML_Datatypes[3], [0, m2, l1])], [1, a, b], _e$_), + _fb_ = nth_split(caml_call1(UIML_Datatypes[3], [0, m2, l1]), _fa_), + _fc_ = [0, b, caml_call1(UIML_Datatypes[2], _fb_)], + _fd_ = + caml_call2 + (UIML_Datatypes[4], [0, m2, l1], [0, [1, a, b], UU0394_1]), + _fe_ = [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _fd_], + _ff_ = caml_call1(UIML_Datatypes[2], _fe_), + _fg_ = + remove_nth + ([0, caml_call1(UIML_Datatypes[3], [0, m2, l1])], [1, a, b], _ff_), + _fh_ = nth_split(caml_call1(UIML_Datatypes[3], [0, m2, l1]), _fg_), + _fi_ = caml_call1(UIML_Datatypes[1], _fh_), + _fj_ = caml_call2(UIML_Datatypes[4], _fi_, _fc_), + _fk_ = + caml_call2 + (UIML_Datatypes[4], [0, m2, l1], [0, [1, a, b], UU0394_1]), + _fl_ = [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _fk_], + _fm_ = + listInsertsR_Seqs(caml_call1(UIML_Datatypes[1], _fl_), _fj_, a); + return caml_call4(UIML_List_lemmasT[2], _fm_, _e8_, _e6_, _e4_); + } + var + i = coq_ImpR_help002(UU0393_0, UU0393_1, 0, UU0394_1, a, b), + s = caml_call2(UIML_CML_Syntax[6], [1, a, b], [1, a, b]); + if(! s) throw caml_maybe_attach_backtrace([0, Assert_failure, _p_], 1); + var + _fn_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), + [0, b, UU0394_1]], + _fo_ = + prems_Imp_R + (l0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), + [0, [1, a, b], UU0394_1]]), + _fp_ = + listInsertsR_Seqs + (caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), + [0, b, UU0394_1], + a); + return caml_call4(UIML_List_lemmasT[2], _fp_, _fo_, _fn_, [0, i]); + } + var + i$0 = + coq_ImpR_help02 + (UU0393_0, + UU0393_1, + UU0394_0, + UU0394_1, + a, + b, + l0, + caml_call1(UIML_Datatypes[3], UU0394_0), + x); + if(! n0) return i$0; + var + n1 = n0[1], + _fr_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, b, UU0394_1]), + _fs_ = + [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), _fr_], + _ft_ = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, [1, a, b], UU0394_1]), + _fq_ = [1, i$0], + _fu_ = + prems_Imp_R + (l0, [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _ft_]); + if(n1){ + var + match = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, [1, a, b], UU0394_1]); + if(match) + var + tl = match[2], + b0 = match[1], + _fv_ = [0, b0, remove_nth(n1, [1, m0, m1], tl)]; + else + var _fv_ = 0; + var _fw_ = _fv_; + } + else{ + var + match$2 = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, [1, a, b], UU0394_1]); + if(match$2) + var + tl$4 = match$2[2], + b0$2 = match$2[1], + tl$5 = + caml_call2(UIML_CML_Syntax[6], [1, m0, m1], b0$2) + ? tl$4 + : [0, b0$2, tl$4], + tl$6 = tl$5; + else + var tl$6 = 0; + var _fw_ = tl$6; + } + var + _fx_ = nth_split(n1, _fw_), + _fy_ = [0, m1, caml_call1(UIML_Datatypes[2], _fx_)]; + if(n1){ + var + match$0 = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, [1, a, b], UU0394_1]); + if(match$0) + var + tl$0 = match$0[2], + b0$0 = match$0[1], + _fz_ = [0, b0$0, remove_nth(n1, [1, m0, m1], tl$0)]; + else + var _fz_ = 0; + var _fA_ = _fz_; + } + else{ + var + match$1 = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, [1, a, b], UU0394_1]); + if(match$1) + var + tl$1 = match$1[2], + b0$1 = match$1[1], + tl$2 = + caml_call2(UIML_CML_Syntax[6], [1, m0, m1], b0$1) + ? tl$1 + : [0, b0$1, tl$1], + tl$3 = tl$2; + else + var tl$3 = 0; + var _fA_ = tl$3; + } + var + _fB_ = nth_split(n1, _fA_), + _fC_ = caml_call1(UIML_Datatypes[1], _fB_), + _fD_ = caml_call2(UIML_Datatypes[4], _fC_, _fy_), + _fE_ = + listInsertsR_Seqs + (caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _fD_, m0); + return caml_call4(UIML_List_lemmasT[2], _fE_, _fu_, _fs_, _fq_); + } + var h1 = coq_In_InT_pair([1, a, b], [0, n$0], [0, [0, m, n0], l0]); + if(0 === h1[0]) + throw caml_maybe_attach_backtrace([0, Assert_failure, _o_], 1); + var n$1 = caml_call1(UIML_Datatypes[3], UU0394_0); + l$0 = l0; + n$0 = n$1; + } + } + function coq_ImpR_help2(param, _e2_, x){ + var + UU0394_1 = x[6], + UU0394_0 = x[5], + UU0393_1 = x[4], + UU0393_0 = x[3], + b = x[2], + a = x[1], + _e3_ = caml_call1(UIML_Datatypes[3], UU0394_0); + return coq_ImpR_help02 + (UU0393_0, + UU0393_1, + UU0394_0, + UU0394_1, + a, + b, + pos_top_imps + (caml_call2 + (UIML_Datatypes[4], UU0394_0, [0, [1, a, b], UU0394_1])), + _e3_, + x); + } + function finite_ImpR_premises_of_S(param){ + var + l0 = param[2], + l = param[1], + _eT_ = prems_Imp_R(pos_top_imps(l0), [0, l, l0]); + return [0, + caml_call2(UIML_List[4], function(y){return [0, y, 0];}, _eT_), + function(prems){ + return [0, + function(h){ + var + UU0394_1 = h[6], + UU0394_0 = h[5], + UU0393_1 = h[4], + UU0393_0 = h[3], + b = h[2], + a = h[1]; + function f(y){return [0, y, 0];} + var + _eU_ = + caml_call2 + (UIML_Datatypes[4], UU0394_0, [0, [1, a, b], UU0394_1]), + _eV_ = + [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _eU_], + l1 = + prems_Imp_R + (pos_top_imps + (caml_call2 + (UIML_Datatypes[4], UU0394_0, [0, [1, a, b], UU0394_1])), + _eV_), + _eW_ = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, b, UU0394_1]), + y = + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), + _eW_], + 0], + x = coq_InT_map_iff(f, l1)(y)[2], + _eX_ = + caml_call2 + (UIML_Datatypes[4], UU0394_0, [0, [1, a, b], UU0394_1]), + _eY_ = + [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _eX_], + _eZ_ = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, b, UU0394_1]), + _e0_ = + [0, + symbol, + coq_ImpR_help2 + ([0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), + _eZ_], + _eY_, + h)], + _e1_ = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, b, UU0394_1]); + return caml_call1 + (x, + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), + _e1_], + _e0_]); + }, + function(h){ + var l1 = prems_Imp_R(pos_top_imps(l0), [0, l, l0]); + function f(y){return [0, y, 0];} + var + x = coq_InT_map_iff(f, l1)(prems)[1], + h0 = caml_call1(x, h), + p = h0[2], + x0 = h0[1], + i = p[2]; + return coq_ImpR_help1(x0, [0, l, l0], i); + }]; + }]; + } + function prems_Imp_L(l, s){ + var l$0 = l; + for(;;){ + if(! l$0) return 0; + var t = l$0[2], p = l$0[1], n = p[2], c = p[1]; + if(n){ + var m = n[1]; + if(typeof c !== "number" && 1 === c[0]){ + var + b = c[2], + a = c[1], + _eF_ = prems_Imp_L(t, s), + _eG_ = caml_call1(UIML_Datatypes[2], s), + _eH_ = + nth_split + (m, remove_nth([0, m], c, caml_call1(UIML_Datatypes[1], s))), + _eI_ = [0, b, caml_call1(UIML_Datatypes[2], _eH_)], + _eJ_ = + nth_split + (m, remove_nth([0, m], c, caml_call1(UIML_Datatypes[1], s))), + _eK_ = caml_call1(UIML_Datatypes[1], _eJ_), + _eL_ = [0, [0, caml_call2(UIML_Datatypes[4], _eK_, _eI_), _eG_], 0], + _eM_ = + flatten_list + (caml_call2 + (UIML_List[4], + function(y){ + var + _eN_ = caml_call1(UIML_Datatypes[2], s), + _eO_ = + nth_split + (m, remove_nth([0, m], c, caml_call1(UIML_Datatypes[1], s))), + _eP_ = caml_call1(UIML_Datatypes[2], _eO_), + _eQ_ = + nth_split + (m, remove_nth([0, m], c, caml_call1(UIML_Datatypes[1], s))), + _eR_ = caml_call1(UIML_Datatypes[1], _eQ_), + _eS_ = + listInsertsL_Seqs + (caml_call2(UIML_Datatypes[4], _eR_, _eP_), _eN_, a); + return caml_call2 + (UIML_List[4], function(z){return [0, z, [0, y, 0]];}, _eS_); + }, + _eL_)); + return caml_call2(UIML_Datatypes[4], _eM_, _eF_); + } + l$0 = t; + } + else + l$0 = t; + } + } + function coq_ImpL_help002(UU0393_0, UU0393_1, UU0394_0, UU0394_1, a, b){ + var + _d4_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _d5_ = + [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), _d4_], + 0], + _d6_ = + caml_call2 + (UIML_List[4], + function(z){ + var + _eE_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]); + return [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _eE_], + [0, z, 0]]; + }, + _d5_), + _d7_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + p = + coq_InT_map_iff + (function(y){ + var + _eC_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _eD_ = + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), + _eC_], + 0]; + return caml_call2 + (UIML_List[4], function(z){return [0, y, [0, z, 0]];}, _eD_); + }, + listInsertsL_Seqs + (caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _d7_, a)) + (_d6_), + i = p[2], + _d8_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]), + _d9_ = [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _d8_], + p0 = + coq_InT_map_iff + (function(y){ + return [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), y]; + }, + listInserts(caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), a)) + (_d9_), + i0 = p0[2], + _d__ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]), + a$0 = + list_of_splits(caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1))[1], + p1 = + coq_InT_map_iff + (function(y){ + var + _eA_ = [0, a, caml_call1(UIML_Datatypes[2], y)], + _eB_ = caml_call1(UIML_Datatypes[1], y); + return caml_call2(UIML_Datatypes[4], _eB_, _eA_); + }, + a$0) + (_d__), + i1 = p1[2], + s = list_of_splits(caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1)), + x = s[1], + _d$_ = + [0, + symbol, + caml_call1 + (i1, + [0, + [0, UU0394_0, UU0394_1], + [0, + symbol, + caml_call2(UIML_List_lems[5], [0, UU0394_0, UU0394_1], x)]])], + _ea_ = + [0, + symbol, + caml_call1 + (i0, + [0, caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]), _d$_])], + _eb_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]), + _ec_ = + caml_call1 + (i, + [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _eb_], + _ea_]), + _ed_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _ee_ = + [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), _ed_], + 0], + _ef_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]), + _eg_ = + [0, [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _ef_], _ee_], + _eh_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + p$0 = + coq_InT_map_iff + (function(z){ + var + _ez_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]); + return [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _ez_], + [0, z, 0]]; + }, + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), + _eh_], + 0]) + (_eg_), + i$0 = p$0[2], + _ei_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _ej_ = + [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), _ei_], + _ek_ = [0, symbol, caml_call2(UIML_GenT[1], _ej_, 0)], + _el_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _em_ = + caml_call1 + (i$0, + [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), _el_], + _ek_]), + _en_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _eo_ = + [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), _en_], + 0], + _ep_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]), + _eq_ = + [0, [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _ep_], _eo_], + _er_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _es_ = + [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), _er_], + 0], + _et_ = + caml_call2 + (UIML_List[4], + function(z){ + var + _ey_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]); + return [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _ey_], + [0, z, 0]]; + }, + _es_), + _eu_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _ev_ = + listInsertsL_Seqs + (caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _eu_, a); + return coq_InT_trans_flatten_list + (caml_call2 + (UIML_List[4], + function(y){ + var + _ew_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _ex_ = + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), + _ew_], + 0]; + return caml_call2 + (UIML_List[4], function(z){return [0, y, [0, z, 0]];}, _ex_); + }, + _ev_), + _et_, + _eq_, + _em_, + _ec_); + } + function coq_ImpL_help02 + (UU0393_0, UU0393_1, UU0394_0, UU0394_1, a, b, l, n, x){ + var l$0 = l, n$0 = n; + for(;;){ + if(! l$0) throw caml_maybe_attach_backtrace([0, Assert_failure, _t_], 1); + var l0 = l$0[2], y = l$0[1], n0 = y[2], m = y[1]; + if(typeof m !== "number" && 1 === m[0]){ + var + m1 = m[2], + m0 = m[1], + h1$0 = + coq_In_InT_pair([1, a, b], [0, n$0], [0, [0, [1, m0, m1], n0], l0]); + if(0 === h1$0[0]){ + var + i = coq_ImpL_help002(UU0393_0, UU0393_1, UU0394_0, UU0394_1, a, b), + f = + function(y0){ + var + _dO_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _dP_ = + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _dO_], + _dQ_ = caml_call1(UIML_Datatypes[2], _dP_), + _dR_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _dS_ = + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _dR_], + _dT_ = caml_call1(UIML_Datatypes[1], _dS_), + _dU_ = + remove_nth + ([0, caml_call1(UIML_Datatypes[3], UU0393_0)], [1, a, b], _dT_), + _dV_ = nth_split(caml_call1(UIML_Datatypes[3], UU0393_0), _dU_), + _dW_ = caml_call1(UIML_Datatypes[2], _dV_), + _dX_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _dY_ = + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _dX_], + _dZ_ = caml_call1(UIML_Datatypes[1], _dY_), + _d0_ = + remove_nth + ([0, caml_call1(UIML_Datatypes[3], UU0393_0)], [1, a, b], _dZ_), + _d1_ = nth_split(caml_call1(UIML_Datatypes[3], UU0393_0), _d0_), + _d2_ = caml_call1(UIML_Datatypes[1], _d1_), + _d3_ = + listInsertsL_Seqs + (caml_call2(UIML_Datatypes[4], _d2_, _dW_), _dQ_, a); + return caml_call2 + (UIML_List[4], + function(z){return [0, z, [0, y0, 0]];}, + _d3_); + }, + _bv_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _bw_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _bv_], + _bx_ = caml_call1(UIML_Datatypes[2], _bw_), + _by_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _bz_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _by_], + _bA_ = caml_call1(UIML_Datatypes[1], _bz_), + _bB_ = + remove_nth + ([0, caml_call1(UIML_Datatypes[3], UU0393_0)], [1, a, b], _bA_), + _bC_ = nth_split(caml_call1(UIML_Datatypes[3], UU0393_0), _bB_), + _bD_ = [0, b, caml_call1(UIML_Datatypes[2], _bC_)], + _bE_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _bF_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _bE_], + _bG_ = caml_call1(UIML_Datatypes[1], _bF_), + _bH_ = + remove_nth + ([0, caml_call1(UIML_Datatypes[3], UU0393_0)], [1, a, b], _bG_), + _bI_ = nth_split(caml_call1(UIML_Datatypes[3], UU0393_0), _bH_), + _bJ_ = caml_call1(UIML_Datatypes[1], _bI_), + l1 = [0, [0, caml_call2(UIML_Datatypes[4], _bJ_, _bD_), _bx_], 0], + _bK_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _bL_ = + listInsertsL_Seqs + (caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _bK_, a), + y0 = + flatten_list + (caml_call2 + (UIML_List[4], + function(y0){ + var _dN_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1); + return [0, + [0, + y0, + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), + _dN_], + 0]], + 0]; + }, + _bL_)), + x0 = coq_InT_map_iff(f, l1)(y0)[2], + s = caml_call2(UIML_CML_Syntax[6], [1, a, b], [1, a, b]); + if(! s) throw caml_maybe_attach_backtrace([0, Assert_failure, _s_], 1); + var + _bM_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _bN_ = + [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), _bM_], + _bO_ = [0, symbol, caml_call2(UIML_GenT[1], _bN_, 0)], + _bP_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _bQ_ = + caml_call1 + (x0, + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), + _bP_], + _bO_]), + _bR_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _bS_ = + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), + _bR_], + 0], + _bT_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]), + _bU_ = + [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _bT_], + _bS_], + _bV_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _bW_ = + listInsertsL_Seqs + (caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _bV_, a), + _bX_ = + flatten_list + (caml_call2 + (UIML_List[4], + function(y0){ + var _dM_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1); + return [0, + [0, + y0, + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), + _dM_], + 0]], + 0]; + }, + _bW_)), + _bY_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _bZ_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _bY_], + _b0_ = caml_call1(UIML_Datatypes[2], _bZ_), + _b1_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _b2_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _b1_], + _b3_ = caml_call1(UIML_Datatypes[1], _b2_), + _b4_ = + remove_nth + ([0, caml_call1(UIML_Datatypes[3], UU0393_0)], [1, a, b], _b3_), + _b5_ = nth_split(caml_call1(UIML_Datatypes[3], UU0393_0), _b4_), + _b6_ = [0, b, caml_call1(UIML_Datatypes[2], _b5_)], + _b7_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _b8_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _b7_], + _b9_ = caml_call1(UIML_Datatypes[1], _b8_), + _b__ = + remove_nth + ([0, caml_call1(UIML_Datatypes[3], UU0393_0)], [1, a, b], _b9_), + _b$_ = nth_split(caml_call1(UIML_Datatypes[3], UU0393_0), _b__), + _ca_ = caml_call1(UIML_Datatypes[1], _b$_), + _cb_ = [0, [0, caml_call2(UIML_Datatypes[4], _ca_, _b6_), _b0_], 0], + _cc_ = + [0, + coq_InT_trans_flatten_list + (caml_call2 + (UIML_List[4], + function(y0){ + var + _dw_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _dx_ = + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _dw_], + _dy_ = caml_call1(UIML_Datatypes[2], _dx_), + _dz_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _dA_ = + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _dz_], + _dB_ = caml_call1(UIML_Datatypes[1], _dA_), + _dC_ = + remove_nth + ([0, caml_call1(UIML_Datatypes[3], UU0393_0)], + [1, a, b], + _dB_), + _dD_ = + nth_split(caml_call1(UIML_Datatypes[3], UU0393_0), _dC_), + _dE_ = caml_call1(UIML_Datatypes[2], _dD_), + _dF_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _dG_ = + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _dF_], + _dH_ = caml_call1(UIML_Datatypes[1], _dG_), + _dI_ = + remove_nth + ([0, caml_call1(UIML_Datatypes[3], UU0393_0)], + [1, a, b], + _dH_), + _dJ_ = + nth_split(caml_call1(UIML_Datatypes[3], UU0393_0), _dI_), + _dK_ = caml_call1(UIML_Datatypes[1], _dJ_), + _dL_ = + listInsertsL_Seqs + (caml_call2(UIML_Datatypes[4], _dK_, _dE_), _dy_, a); + return caml_call2 + (UIML_List[4], + function(z){return [0, z, [0, y0, 0]];}, + _dL_); + }, + _cb_), + _bX_, + _bU_, + i, + _bQ_)], + _cd_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _ce_ = + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), + _cd_], + 0], + _cf_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]), + prems_Imp_L0 = + function(l1, s){ + var l1$0 = l1; + for(;;){ + if(! l1$0) return 0; + var l1$1 = l1$0[2], p = l1$0[1], n1 = p[2], c = p[1]; + if(n1){ + var m2 = n1[1]; + if(typeof c !== "number" && 1 === c[0]){ + var + b0 = c[2], + a0 = c[1], + _di_ = prems_Imp_L0(l1$1, s), + _dj_ = caml_call1(UIML_Datatypes[2], s), + _dk_ = + nth_split + (m2, + remove_nth([0, m2], c, caml_call1(UIML_Datatypes[1], s))), + _dl_ = [0, b0, caml_call1(UIML_Datatypes[2], _dk_)], + _dm_ = + nth_split + (m2, + remove_nth([0, m2], c, caml_call1(UIML_Datatypes[1], s))), + _dn_ = caml_call1(UIML_Datatypes[1], _dm_), + _do_ = + [0, [0, caml_call2(UIML_Datatypes[4], _dn_, _dl_), _dj_], 0], + _dp_ = + flatten_list + (caml_call2 + (UIML_List[4], + function(y0){ + var + _dq_ = caml_call1(UIML_Datatypes[2], s), + _dr_ = + nth_split + (m2, + remove_nth([0, m2], c, caml_call1(UIML_Datatypes[1], s))), + _ds_ = caml_call1(UIML_Datatypes[2], _dr_), + _dt_ = + nth_split + (m2, + remove_nth([0, m2], c, caml_call1(UIML_Datatypes[1], s))), + _du_ = caml_call1(UIML_Datatypes[1], _dt_), + _dv_ = + listInsertsL_Seqs + (caml_call2(UIML_Datatypes[4], _du_, _ds_), _dq_, a0); + return caml_call2 + (UIML_List[4], + function(z){return [0, z, [0, y0, 0]];}, + _dv_); + }, + _do_)); + return caml_call2(UIML_Datatypes[4], _dp_, _di_); + } + l1$0 = l1$1; + } + else + l1$0 = l1$1; + } + }, + _cg_ = + [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _cf_], + _ce_], + _ch_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _ci_ = + prems_Imp_L0 + (l0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _ch_]), + _cj_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _ck_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _cj_], + _cl_ = caml_call1(UIML_Datatypes[2], _ck_), + _cm_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _cn_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _cm_], + _co_ = caml_call1(UIML_Datatypes[1], _cn_), + _cp_ = + remove_nth + ([0, caml_call1(UIML_Datatypes[3], UU0393_0)], [1, a, b], _co_), + _cq_ = nth_split(caml_call1(UIML_Datatypes[3], UU0393_0), _cp_), + _cr_ = [0, b, caml_call1(UIML_Datatypes[2], _cq_)], + _cs_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _ct_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _cs_], + _cu_ = caml_call1(UIML_Datatypes[1], _ct_), + _cv_ = + remove_nth + ([0, caml_call1(UIML_Datatypes[3], UU0393_0)], [1, a, b], _cu_), + _cw_ = nth_split(caml_call1(UIML_Datatypes[3], UU0393_0), _cv_), + _cx_ = caml_call1(UIML_Datatypes[1], _cw_), + _cy_ = [0, [0, caml_call2(UIML_Datatypes[4], _cx_, _cr_), _cl_], 0], + _cz_ = + flatten_list + (caml_call2 + (UIML_List[4], + function(y0){ + var + _c4_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _c5_ = + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _c4_], + _c6_ = caml_call1(UIML_Datatypes[2], _c5_), + _c7_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _c8_ = + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _c7_], + _c9_ = caml_call1(UIML_Datatypes[1], _c8_), + _c__ = + remove_nth + ([0, caml_call1(UIML_Datatypes[3], UU0393_0)], + [1, a, b], + _c9_), + _c$_ = + nth_split(caml_call1(UIML_Datatypes[3], UU0393_0), _c__), + _da_ = caml_call1(UIML_Datatypes[2], _c$_), + _db_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _dc_ = + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _db_], + _dd_ = caml_call1(UIML_Datatypes[1], _dc_), + _de_ = + remove_nth + ([0, caml_call1(UIML_Datatypes[3], UU0393_0)], + [1, a, b], + _dd_), + _df_ = + nth_split(caml_call1(UIML_Datatypes[3], UU0393_0), _de_), + _dg_ = caml_call1(UIML_Datatypes[1], _df_), + _dh_ = + listInsertsL_Seqs + (caml_call2(UIML_Datatypes[4], _dg_, _da_), _c6_, a); + return caml_call2 + (UIML_List[4], + function(z){return [0, z, [0, y0, 0]];}, + _dh_); + }, + _cy_)); + return caml_call4(UIML_List_lemmasT[2], _cz_, _ci_, _cg_, _cc_); + } + var + i$0 = + coq_ImpL_help02 + (UU0393_0, + UU0393_1, + UU0394_0, + UU0394_1, + a, + b, + l0, + caml_call1(UIML_Datatypes[3], UU0393_0), + x); + if(! n0) return i$0; + var + n1 = n0[1], + _cB_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _cC_ = + [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), _cB_], + 0], + _cD_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]), + _cE_ = + [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _cD_], + _cC_], + _cF_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _cG_ = + prems_Imp_L + (l0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _cF_]), + _cA_ = [1, i$0], + _cH_ = 0, + _cI_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1); + if(n1){ + var + match = + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]); + if(match) + var + tl = match[2], + b0 = match[1], + _cJ_ = [0, b0, remove_nth(n1, [1, m0, m1], tl)]; + else + var _cJ_ = 0; + var _cK_ = _cJ_; + } + else{ + var + match$2 = + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]); + if(match$2) + var + tl$4 = match$2[2], + b0$2 = match$2[1], + tl$5 = + caml_call2(UIML_CML_Syntax[6], [1, m0, m1], b0$2) + ? tl$4 + : [0, b0$2, tl$4], + tl$6 = tl$5; + else + var tl$6 = 0; + var _cK_ = tl$6; + } + var + _cL_ = nth_split(n1, _cK_), + _cM_ = caml_call1(UIML_Datatypes[2], _cL_); + if(n1){ + var + match$0 = + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]); + if(match$0) + var + tl$0 = match$0[2], + b0$0 = match$0[1], + _cN_ = [0, b0$0, remove_nth(n1, [1, m0, m1], tl$0)]; + else + var _cN_ = 0; + var _cO_ = _cN_; + } + else{ + var + match$1 = + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]); + if(match$1) + var + tl$1 = match$1[2], + b0$1 = match$1[1], + tl$2 = + caml_call2(UIML_CML_Syntax[6], [1, m0, m1], b0$1) + ? tl$1 + : [0, b0$1, tl$1], + tl$3 = tl$2; + else + var tl$3 = 0; + var _cO_ = tl$3; + } + var + _cP_ = nth_split(n1, _cO_), + _cQ_ = caml_call1(UIML_Datatypes[1], _cP_), + _cR_ = + listInsertsL_Seqs + (caml_call2(UIML_Datatypes[4], _cQ_, _cM_), _cI_, m0), + _cS_ = + caml_call2 + (UIML_List[4], + function(z){ + var + _cU_ = 0, + _cV_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1); + if(n1){ + var + match = + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]); + if(match) + var + tl = match[2], + b0 = match[1], + _cW_ = [0, b0, remove_nth(n1, [1, m0, m1], tl)]; + else + var _cW_ = 0; + var _cX_ = _cW_; + } + else{ + var + match$2 = + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]); + if(match$2) + var + tl$4 = match$2[2], + b0$2 = match$2[1], + tl$5 = + caml_call2(UIML_CML_Syntax[6], [1, m0, m1], b0$2) + ? tl$4 + : [0, b0$2, tl$4], + tl$6 = tl$5; + else + var tl$6 = 0; + var _cX_ = tl$6; + } + var + _cY_ = nth_split(n1, _cX_), + _cZ_ = [0, m1, caml_call1(UIML_Datatypes[2], _cY_)]; + if(n1){ + var + match$0 = + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]); + if(match$0) + var + tl$0 = match$0[2], + b0$0 = match$0[1], + _c0_ = [0, b0$0, remove_nth(n1, [1, m0, m1], tl$0)]; + else + var _c0_ = 0; + var _c1_ = _c0_; + } + else{ + var + match$1 = + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]); + if(match$1) + var + tl$1 = match$1[2], + b0$1 = match$1[1], + tl$2 = + caml_call2(UIML_CML_Syntax[6], [1, m0, m1], b0$1) + ? tl$1 + : [0, b0$1, tl$1], + tl$3 = tl$2; + else + var tl$3 = 0; + var _c1_ = tl$3; + } + var + _c2_ = nth_split(n1, _c1_), + _c3_ = caml_call1(UIML_Datatypes[1], _c2_); + return [0, + z, + [0, + [0, caml_call2(UIML_Datatypes[4], _c3_, _cZ_), _cV_], + _cU_]]; + }, + _cR_), + _cT_ = caml_call2(UIML_Datatypes[4], _cS_, _cH_); + return caml_call4(UIML_List_lemmasT[2], _cT_, _cG_, _cE_, _cA_); + } + var + h1 = + coq_In_InT_pair + ([1, a, b], + [0, caml_call1(UIML_Datatypes[3], UU0393_0)], + [0, [0, m, n0], l0]); + if(0 === h1[0]) + throw caml_maybe_attach_backtrace([0, Assert_failure, _r_], 1); + var n$1 = caml_call1(UIML_Datatypes[3], UU0393_0); + l$0 = l0; + n$0 = n$1; + } + } + function coq_ImpL_help2(param, _bt_, _bs_, x){ + var + UU0394_1 = x[6], + UU0394_0 = x[5], + UU0393_1 = x[4], + UU0393_0 = x[3], + b = x[2], + a = x[1], + _bu_ = caml_call1(UIML_Datatypes[3], UU0393_0); + return coq_ImpL_help02 + (UU0393_0, + UU0393_1, + UU0394_0, + UU0394_1, + a, + b, + pos_top_imps + (caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1])), + _bu_, + x); + } + function coq_ImpL_help01(prems, s, l1){ + var l0 = s[2], l = s[1]; + function f(l2, x){ + if(! l2) throw caml_maybe_attach_backtrace([0, Assert_failure, _v_], 1); + var l3 = l2[2], y = l2[1], n = y[2], m = y[1]; + if(typeof m !== "number" && 1 === m[0]){ + var m1 = m[2], m0 = m[1]; + if(! n){ + var + s0$1 = f(l3, x), + s1$1 = s0$1[2], + x0$1 = s0$1[1], + s2$1 = s1$1[2], + x1$2 = s1$1[1], + s3$1 = s2$1[2], + x2$2 = s2$1[1], + s4$1 = s3$1[2], + x3$2 = s3$1[1], + s5$1 = s4$1[2], + x4$2 = s4$1[1], + s6$1 = s5$1[2], + x5$2 = s5$1[1], + s7$1 = s6$1[2], + x6$2 = s6$1[1], + s8$1 = s7$1[2], + x7$2 = s7$1[1], + x8$2 = s8$1[1]; + return [0, + x0$1, + [0, + x1$2, + [0, + x2$2, + [0, + x3$2, + [0, + x4$2, + [0, x5$2, [0, x6$2, [0, x7$2, [0, x8$2, symbol]]]]]]]]]; + } + var + n0 = n[1], + prems_Imp_L0 = + function(l4, s0){ + var l4$0 = l4; + for(;;){ + if(! l4$0) return 0; + var l4$1 = l4$0[2], p = l4$0[1], n1 = p[2], c = p[1]; + if(n1){ + var m2 = n1[1]; + if(typeof c !== "number" && 1 === c[0]){ + var + b = c[2], + a = c[1], + _be_ = prems_Imp_L0(l4$1, s0), + _bf_ = caml_call1(UIML_Datatypes[2], s0), + _bg_ = + nth_split + (m2, + remove_nth([0, m2], c, caml_call1(UIML_Datatypes[1], s0))), + _bh_ = [0, b, caml_call1(UIML_Datatypes[2], _bg_)], + _bi_ = + nth_split + (m2, + remove_nth([0, m2], c, caml_call1(UIML_Datatypes[1], s0))), + _bj_ = caml_call1(UIML_Datatypes[1], _bi_), + _bk_ = + [0, [0, caml_call2(UIML_Datatypes[4], _bj_, _bh_), _bf_], 0], + _bl_ = + flatten_list + (caml_call2 + (UIML_List[4], + function(y0){ + var + _bm_ = caml_call1(UIML_Datatypes[2], s0), + _bn_ = + nth_split + (m2, + remove_nth([0, m2], c, caml_call1(UIML_Datatypes[1], s0))), + _bo_ = caml_call1(UIML_Datatypes[2], _bn_), + _bp_ = + nth_split + (m2, + remove_nth([0, m2], c, caml_call1(UIML_Datatypes[1], s0))), + _bq_ = caml_call1(UIML_Datatypes[1], _bp_), + _br_ = + listInsertsL_Seqs + (caml_call2(UIML_Datatypes[4], _bq_, _bo_), _bm_, a); + return caml_call2 + (UIML_List[4], + function(z){return [0, z, [0, y0, 0]];}, + _br_); + }, + _bk_)); + return caml_call2(UIML_Datatypes[4], _bl_, _be_); + } + l4$0 = l4$1; + } + else + l4$0 = l4$1; + } + }, + _ac_ = prems_Imp_L0(l3, [0, l, l0]), + _ad_ = caml_call1(UIML_Datatypes[2], [0, l, l0]), + _ae_ = + nth_split + (n0, + remove_nth + ([0, n0], [1, m0, m1], caml_call1(UIML_Datatypes[1], [0, l, l0]))), + _af_ = [0, m1, caml_call1(UIML_Datatypes[2], _ae_)], + _ag_ = + nth_split + (n0, + remove_nth + ([0, n0], [1, m0, m1], caml_call1(UIML_Datatypes[1], [0, l, l0]))), + _ah_ = caml_call1(UIML_Datatypes[1], _ag_), + _ai_ = [0, [0, caml_call2(UIML_Datatypes[4], _ah_, _af_), _ad_], 0], + _aj_ = + flatten_list + (caml_call2 + (UIML_List[4], + function(y0){ + var + _a__ = caml_call1(UIML_Datatypes[2], [0, l, l0]), + _a$_ = + nth_split + (n0, + remove_nth + ([0, n0], + [1, m0, m1], + caml_call1(UIML_Datatypes[1], [0, l, l0]))), + _ba_ = caml_call1(UIML_Datatypes[2], _a$_), + _bb_ = + nth_split + (n0, + remove_nth + ([0, n0], + [1, m0, m1], + caml_call1(UIML_Datatypes[1], [0, l, l0]))), + _bc_ = caml_call1(UIML_Datatypes[1], _bb_), + _bd_ = + listInsertsL_Seqs + (caml_call2(UIML_Datatypes[4], _bc_, _ba_), _a__, m0); + return caml_call2 + (UIML_List[4], + function(z){return [0, z, [0, y0, 0]];}, + _bd_); + }, + _ai_)), + x0$0 = caml_call4(UIML_List_lemmasT[1], _aj_, _ac_, prems, x); + if(0 !== x0$0[0]){ + var + i$0 = x0$0[1], + s0$0 = f(l3, i$0), + s1$0 = s0$0[2], + x1$1 = s0$0[1], + s2$0 = s1$0[2], + x2$1 = s1$0[1], + s3$0 = s2$0[2], + x3$1 = s2$0[1], + s4$0 = s3$0[2], + x4$1 = s3$0[1], + s5$0 = s4$0[2], + x5$1 = s4$0[1], + s6$0 = s5$0[2], + x6$1 = s5$0[1], + s7$0 = s6$0[2], + x7$1 = s6$0[1], + s8$0 = s7$0[2], + x8$1 = s7$0[1], + x9 = s8$0[1]; + return [0, + x1$1, + [0, + x2$1, + [0, + x3$1, + [0, + x4$1, + [0, x5$1, [0, x6$1, [0, x7$1, [0, x8$1, [0, x9, symbol]]]]]]]]]; + } + var + i = x0$0[1], + _ak_ = nth_split(n0, remove_nth([0, n0], [1, m0, m1], l)), + _al_ = [0, m1, caml_call1(UIML_Datatypes[2], _ak_)], + _am_ = nth_split(n0, remove_nth([0, n0], [1, m0, m1], l)), + _an_ = caml_call1(UIML_Datatypes[1], _am_), + _ao_ = [0, [0, caml_call2(UIML_Datatypes[4], _an_, _al_), l0], 0], + i0 = + coq_InT_flatten_list_InT_elem + (caml_call2 + (UIML_List[4], + function(y0){ + var + _a5_ = nth_split(n0, remove_nth([0, n0], [1, m0, m1], l)), + _a6_ = caml_call1(UIML_Datatypes[2], _a5_), + _a7_ = nth_split(n0, remove_nth([0, n0], [1, m0, m1], l)), + _a8_ = caml_call1(UIML_Datatypes[1], _a7_), + _a9_ = + listInsertsL_Seqs + (caml_call2(UIML_Datatypes[4], _a8_, _a6_), l0, m0); + return caml_call2 + (UIML_List[4], + function(z){return [0, z, [0, y0, 0]];}, + _a9_); + }, + _ao_), + prems, + i), + p = i0[2], + x1$0 = i0[1], + i2 = p[2], + i1 = p[1], + _ap_ = nth_split(n0, remove_nth([0, n0], [1, m0, m1], l)), + _aq_ = [0, m1, caml_call1(UIML_Datatypes[2], _ap_)], + _ar_ = nth_split(n0, remove_nth([0, n0], [1, m0, m1], l)), + _as_ = caml_call1(UIML_Datatypes[1], _ar_), + l4 = [0, [0, caml_call2(UIML_Datatypes[4], _as_, _aq_), l0], 0], + f0 = + function(y0){ + var + _a0_ = nth_split(n0, remove_nth([0, n0], [1, m0, m1], l)), + _a1_ = caml_call1(UIML_Datatypes[2], _a0_), + _a2_ = nth_split(n0, remove_nth([0, n0], [1, m0, m1], l)), + _a3_ = caml_call1(UIML_Datatypes[1], _a2_), + _a4_ = + listInsertsL_Seqs + (caml_call2(UIML_Datatypes[4], _a3_, _a1_), l0, m0); + return caml_call2 + (UIML_List[4], + function(z){return [0, z, [0, y0, 0]];}, + _a4_); + }, + x2$0 = coq_InT_map_iff(f0, l4)(x1$0)[1], + i3 = caml_call1(x2$0, i2), + p0 = i3[2], + i4 = p0[2]; + if(0 !== i4[0]) + throw caml_maybe_attach_backtrace([0, Assert_failure, _u_], 1); + var + _at_ = nth_split(n0, remove_nth([0, n0], [1, m0, m1], l)), + _au_ = caml_call1(UIML_Datatypes[2], _at_), + _av_ = nth_split(n0, remove_nth([0, n0], [1, m0, m1], l)), + _aw_ = caml_call1(UIML_Datatypes[1], _av_), + l4$0 = + listInsertsL_Seqs(caml_call2(UIML_Datatypes[4], _aw_, _au_), l0, m0), + f0$0 = + function(z){ + var _aT_ = 0; + if(n0) + if(l) + var + tl = l[2], + b = l[1], + _aU_ = [0, b, remove_nth(n0, [1, m0, m1], tl)]; + else + var _aU_ = 0; + else if(l) + var + tl$3 = l[2], + b$2 = l[1], + tl$4 = + caml_call2(UIML_CML_Syntax[6], [1, m0, m1], b$2) + ? tl$3 + : [0, b$2, tl$3], + _aU_ = tl$4; + else + var _aU_ = 0; + var + _aV_ = nth_split(n0, _aU_), + _aW_ = [0, m1, caml_call1(UIML_Datatypes[2], _aV_)]; + if(n0) + if(l) + var + tl$0 = l[2], + b$0 = l[1], + _aX_ = [0, b$0, remove_nth(n0, [1, m0, m1], tl$0)]; + else + var _aX_ = 0; + else if(l) + var + tl$1 = l[2], + b$1 = l[1], + tl$2 = + caml_call2(UIML_CML_Syntax[6], [1, m0, m1], b$1) + ? tl$1 + : [0, b$1, tl$1], + _aX_ = tl$2; + else + var _aX_ = 0; + var + _aY_ = nth_split(n0, _aX_), + _aZ_ = caml_call1(UIML_Datatypes[1], _aY_); + return [0, + z, + [0, + [0, caml_call2(UIML_Datatypes[4], _aZ_, _aW_), l0], + _aT_]]; + }, + x3$0 = coq_InT_map_iff(f0$0, l4$0)(prems)[1], + i5 = caml_call1(x3$0, i1), + p1 = i5[2], + x4$0 = i5[1], + i6 = p1[2], + l4$1 = listInserts(l0, m0), + f0$1 = + function(y0){ + var + _aP_ = nth_split(n0, remove_nth([0, n0], [1, m0, m1], l)), + _aQ_ = caml_call1(UIML_Datatypes[2], _aP_), + _aR_ = nth_split(n0, remove_nth([0, n0], [1, m0, m1], l)), + _aS_ = caml_call1(UIML_Datatypes[1], _aR_); + return [0, caml_call2(UIML_Datatypes[4], _aS_, _aQ_), y0]; + }, + x5$0 = coq_InT_map_iff(f0$1, l4$1)(x4$0)[1], + i7 = caml_call1(x5$0, i6), + p2 = i7[2], + x6$0 = i7[1], + i8 = p2[2], + l4$3 = list_of_splits(l0)[1], + f0$2 = + function(y0){ + var + _aN_ = [0, m0, caml_call1(UIML_Datatypes[2], y0)], + _aO_ = caml_call1(UIML_Datatypes[1], y0); + return caml_call2(UIML_Datatypes[4], _aO_, _aN_); + }, + x7$0 = coq_InT_map_iff(f0$2, l4$3)(x6$0)[1], + i9 = caml_call1(x7$0, i8), + x8$0 = i9[1], + l5 = x8$0[2], + l4$2 = x8$0[1], + _ax_ = nth_split(n0, remove_nth([0, n0], [1, m0, m1], l)), + _ay_ = + [0, caml_call1(UIML_Datatypes[2], _ax_), [0, l4$2, [0, l5, symbol]]], + _az_ = nth_split(n0, remove_nth([0, n0], [1, m0, m1], l)), + _aA_ = [0, m0, [0, m1, [0, caml_call1(UIML_Datatypes[1], _az_), _ay_]]]; + if(n0) + if(l) + var + tl = l[2], + b0 = l[1], + _aB_ = [0, b0, remove_nth(n0, [1, m0, m1], tl)]; + else + var _aB_ = 0; + else if(l) + var + tl$3 = l[2], + b0$2 = l[1], + tl$4 = + caml_call2(UIML_CML_Syntax[6], [1, m0, m1], b0$2) + ? tl$3 + : [0, b0$2, tl$3], + _aB_ = tl$4; + else + var _aB_ = 0; + var + _aC_ = nth_split(n0, _aB_), + _aD_ = [0, m1, caml_call1(UIML_Datatypes[2], _aC_)]; + if(n0) + if(l) + var + tl$0 = l[2], + b0$0 = l[1], + _aE_ = [0, b0$0, remove_nth(n0, [1, m0, m1], tl$0)]; + else + var _aE_ = 0; + else if(l) + var + tl$1 = l[2], + b0$1 = l[1], + tl$2 = + caml_call2(UIML_CML_Syntax[6], [1, m0, m1], b0$1) + ? tl$1 + : [0, b0$1, tl$1], + _aE_ = tl$2; + else + var _aE_ = 0; + var + _aF_ = nth_split(n0, _aE_), + _aG_ = caml_call1(UIML_Datatypes[1], _aF_), + _aH_ = [0, [0, caml_call2(UIML_Datatypes[4], _aG_, _aD_), l0], _aA_], + _aI_ = caml_call2(UIML_Datatypes[4], l4$2, [0, m0, l5]), + _aJ_ = nth_split(n0, remove_nth([0, n0], [1, m0, m1], l)), + _aK_ = caml_call1(UIML_Datatypes[2], _aJ_), + _aL_ = nth_split(n0, remove_nth([0, n0], [1, m0, m1], l)), + _aM_ = caml_call1(UIML_Datatypes[1], _aL_); + return [0, + n0, + [0, [0, caml_call2(UIML_Datatypes[4], _aM_, _aK_), _aI_], _aH_]]; + } + var + s0 = f(l3, x), + s1 = s0[2], + x0 = s0[1], + s2 = s1[2], + x1 = s1[1], + s3 = s2[2], + x2 = s2[1], + s4 = s3[2], + x3 = s3[1], + s5 = s4[2], + x4 = s4[1], + s6 = s5[2], + x5 = s5[1], + s7 = s6[2], + x6 = s6[1], + s8 = s7[2], + x7 = s7[1], + x8 = s8[1]; + return [0, + x0, + [0, + x1, + [0, + x2, + [0, x3, [0, x4, [0, x5, [0, x6, [0, x7, [0, x8, symbol]]]]]]]]]; + } + return function(_ab_){return f(l1, _ab_);}; + } + function coq_ImpL_help1(prem, s, x){ + var + s0 = + coq_ImpL_help01 + (prem, s, pos_top_imps(caml_call1(UIML_Datatypes[1], s))) + (x), + s1 = s0[2], + x0 = s0[1], + s2 = s1[2], + s3 = s2[2], + s4 = s3[2], + x1 = s3[1], + s5 = s4[2], + x2 = s4[1], + s6 = s5[2], + s7 = s6[2], + s8 = s7[2], + x3 = s7[1], + x4 = s8[1], + l0 = s[2], + l = s[1], + i = + coq_In_pos_top_imps_split_l + (caml_call1(UIML_Datatypes[1], [0, l, l0]), [1, x1, x2], x0), + x5 = i[1], + _Z_ = remove_nth([0, caml_call1(UIML_Datatypes[3], x5)], [1, x1, x2], l), + ___ = nth_split(caml_call1(UIML_Datatypes[3], x5), _Z_), + UU0393_0 = caml_call1(UIML_Datatypes[1], ___), + _$_ = remove_nth([0, caml_call1(UIML_Datatypes[3], x5)], [1, x1, x2], l), + _aa_ = nth_split(caml_call1(UIML_Datatypes[3], x5), _$_), + UU0393_1 = caml_call1(UIML_Datatypes[2], _aa_); + return [0, x1, x2, UU0393_0, UU0393_1, x3, x4]; + } + function finite_ImpL_premises_of_S(param){ + var l0 = param[2], l = param[1]; + return [0, + prems_Imp_L(pos_top_imps(l), [0, l, l0]), + function(prems){ + return [0, + function(h){ + var + UU0394_1 = h[6], + UU0394_0 = h[5], + UU0393_1 = h[4], + UU0393_0 = h[3], + b = h[2], + a = h[1], + _U_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _V_ = + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _U_], + _W_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _X_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), + _W_], + _Y_ = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]); + return coq_ImpL_help2 + ([0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _Y_], + _X_, + _V_, + h); + }, + function(h){return coq_ImpL_help1(prems, [0, l, l0], h);}]; + }]; + } + function prems_Box_R(l, s){ + var l$0 = l; + for(;;){ + if(! l$0) return 0; + var t = l$0[2], h = l$0[1]; + if(typeof h !== "number" && 2 === h[0]){ + var + a = h[1], + _Q_ = prems_Box_R(t, s), + _R_ = caml_call1(UIML_Datatypes[1], s), + _S_ = caml_call1(UIML_CML_Syntax[9], _R_), + _T_ = caml_call1(UIML_GLS_calcs[1], _S_); + return [0, + [0, + [0, + caml_call2(UIML_Datatypes[4], _T_, [0, [2, a], 0]), + [0, a, 0]], + 0], + _Q_]; + } + l$0 = t; + } + } + function coq_GLR_help01(prems, s, l1, x){ + if(! l1) throw caml_maybe_attach_backtrace([0, Assert_failure, _w_], 1); + var l = l1[2], y = l1[1]; + if(typeof y !== "number" && 2 === y[0]){ + var m = y[1]; + if(0 === x[0]) return [0, m, symbol]; + var x0$0 = x[3], h0 = coq_GLR_help01(prems, s, l, x0$0), x1$0 = h0[1]; + return [0, x1$0, symbol]; + } + var x0 = coq_GLR_help01(prems, s, l, x), x1 = x0[1]; + return [0, x1, symbol]; + } + function coq_GLR_help1(prems, s, x){ + var + _M_ = caml_call1(UIML_Datatypes[2], s), + s0 = coq_GLR_help01(prems, s, caml_call1(UIML_CML_Syntax[9], _M_), x), + x0 = s0[1], + l0 = s[2], + l = s[1], + h = caml_call2(UIML_List_lems[1], [2, x0], l0), + s1 = h[2], + x1 = h[1], + x2 = s1[1], + _N_ = top_boxes_nobox_gen_ext(l), + _O_ = [0, l, caml_call2(UIML_Datatypes[4], x1, [0, [2, x0], x2])], + _P_ = caml_call1(UIML_Datatypes[1], _O_); + return [0, x0, caml_call1(UIML_CML_Syntax[9], _P_), l, x1, x2, _N_]; + } + function coq_GLR_help02(UU0393, UU0394_0, UU0394_1, b_UU0393, a, l, x, x0){ + var l$0 = l; + for(;;){ + if(! l$0) throw caml_maybe_attach_backtrace([0, Assert_failure, _y_], 1); + var l0 = l$0[2], y = l$0[1]; + if(typeof y !== "number" && 2 === y[0]){ + var + m = y[1], + h0$0 = caml_call2(UIML_List_lems[1], [2, a], [0, [2, m], l0]), + s$0 = h0$0[2], + x1 = h0$0[1], + x2$0 = s$0[1], + _E_ = [1, caml_call2(UIML_GenT[1], [2, a], x2$0)], + h1$0 = + caml_call4(UIML_List_lemmasT[2], x1, [0, [2, a], x2$0], [2, a], _E_); + if(0 === h1$0[0]){ + var + _F_ = + prems_Box_R + (l0, + [0, + UU0393, + caml_call2(UIML_Datatypes[4], UU0394_0, [0, [2, a], UU0394_1])]), + _G_ = caml_call1(UIML_CML_Syntax[9], UU0393), + _H_ = caml_call1(UIML_GLS_calcs[1], _G_), + _I_ = + [0, + [0, caml_call2(UIML_Datatypes[4], _H_, [0, [2, a], 0]), [0, a, 0]], + 0]; + return caml_call2(UIML_GenT[1], _I_, _F_); + } + var + i = coq_GLR_help02(UU0393, UU0394_0, UU0394_1, b_UU0393, a, l0, x, x0), + _J_ = + prems_Box_R + (l0, + [0, + UU0393, + caml_call2(UIML_Datatypes[4], UU0394_0, [0, [2, a], UU0394_1])]), + _K_ = caml_call1(UIML_CML_Syntax[9], UU0393), + _L_ = caml_call1(UIML_GLS_calcs[1], _K_); + return [1, + [0, + [0, + caml_call2(UIML_Datatypes[4], _L_, [0, [2, m], 0]), + [0, m, 0]], + 0], + _J_, + i]; + } + var + h0 = caml_call2(UIML_List_lems[1], [2, a], [0, y, l0]), + s = h0[2], + x2 = h0[1], + x3 = s[1], + _D_ = [1, caml_call2(UIML_GenT[1], [2, a], x3)], + h1 = caml_call4(UIML_List_lemmasT[2], x2, [0, [2, a], x3], [2, a], _D_); + if(0 === h1[0]) + throw caml_maybe_attach_backtrace([0, Assert_failure, _x_], 1); + l$0 = l0; + } + } + function coq_GLR_help2(param, _B_, x){ + var + x0 = x[6], + UU0394_1 = x[5], + UU0394_0 = x[4], + UU0393_0 = x[3], + b_UU0393 = x[2], + a = x[1], + _C_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, [2, a], UU0394_1]); + return coq_GLR_help02 + (UU0393_0, + UU0394_0, + UU0394_1, + b_UU0393, + a, + caml_call1(UIML_CML_Syntax[9], _C_), + x, + x0); + } + function finite_GLR_premises_of_S(param){ + var l0 = param[2], l = param[1]; + return [0, + prems_Box_R(caml_call1(UIML_CML_Syntax[9], l0), [0, l, l0]), + function(prems){ + return [0, + function(x){ + var + UU0394_1 = x[5], + UU0394_0 = x[4], + b_UU0393 = x[2], + a = x[1], + _z_ = + [0, + l, + caml_call2 + (UIML_Datatypes[4], UU0394_0, [0, [2, a], UU0394_1])], + _A_ = caml_call1(UIML_GLS_calcs[1], b_UU0393); + return coq_GLR_help2 + ([0, + caml_call2(UIML_Datatypes[4], _A_, [0, [2, a], 0]), + [0, a, 0]], + _z_, + x); + }, + function(h){return coq_GLR_help1(prems, [0, l, l0], h);}]; + }]; + } + var + UIML_GLS_der_dec = + [0, + proj1_sigT2, + proj2_sigT2, + coq_In_InT_pair, + coq_InT_map_iff, + pos_top_imps, + top_boxes_nobox_gen_ext, + flatten_list, + coq_InT_flatten_list_InT_elem, + coq_InT_trans_flatten_list, + list_of_splits, + listInserts, + listInsertsR_Seqs, + listInsertsL_Seqs, + remove_nth, + nth_split, + prems_Imp_R, + coq_In_pos_top_imps_split_l, + coq_ImpR_help01, + coq_ImpR_help1, + coq_ImpR_help002, + coq_ImpR_help02, + coq_ImpR_help2, + finite_ImpR_premises_of_S, + prems_Imp_L, + coq_ImpL_help002, + coq_ImpL_help02, + coq_ImpL_help2, + coq_ImpL_help01, + coq_ImpL_help1, + finite_ImpL_premises_of_S, + prems_Box_R, + coq_GLR_help01, + coq_GLR_help1, + coq_GLR_help02, + coq_GLR_help2, + finite_GLR_premises_of_S]; + runtime.caml_register_global(34, UIML_GLS_der_dec, "UIML__GLS_der_dec"); + return; + } + (globalThis)); + +//# 4215 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_Remove_list_lems = global_data.UIML__Remove_list_lems, + UIML_Datatypes = global_data.UIML__Datatypes, + UIML_CML_Syntax = global_data.UIML__CML_Syntax; + function subform_boxesF(param){ + if(typeof param !== "number") + switch(param[0]){ + case 1: + var + c = param[2], + b = param[1], + _l_ = subform_boxesF(c), + _m_ = subform_boxesF(b), + _n_ = caml_call2(UIML_Remove_list_lems[2], _m_, _l_), + _o_ = subform_boxesF(b); + return caml_call2(UIML_Datatypes[4], _o_, _n_); + case 2: + var b$0 = param[1]; return [0, [2, b$0], subform_boxesF(b$0)]; + } + return 0; + } + function subform_boxesLF(param){ + if(! param) return 0; + var + t = param[2], + h = param[1], + _h_ = subform_boxesLF(t), + _i_ = subform_boxesF(h), + _j_ = caml_call2(UIML_Remove_list_lems[2], _i_, _h_), + _k_ = subform_boxesF(h); + return caml_call2(UIML_Datatypes[4], _k_, _j_); + } + function subform_boxesS(s){ + var + _d_ = subform_boxesLF(caml_call1(UIML_Datatypes[2], s)), + _e_ = subform_boxesLF(caml_call1(UIML_Datatypes[1], s)), + _f_ = caml_call2(UIML_Remove_list_lems[2], _e_, _d_), + _g_ = subform_boxesLF(caml_call1(UIML_Datatypes[1], s)); + return caml_call2(UIML_Datatypes[4], _g_, _f_); + } + function usable_boxes(s){ + var + _a_ = subform_boxesS(s), + _b_ = caml_call1(UIML_Datatypes[1], s), + _c_ = caml_call1(UIML_CML_Syntax[9], _b_); + return caml_call2(UIML_Remove_list_lems[2], _c_, _a_); + } + var + UIML_GLS_termination_measure = + [0, subform_boxesF, subform_boxesLF, subform_boxesS, usable_boxes]; + runtime.caml_register_global + (3, UIML_GLS_termination_measure, "UIML__GLS_termination_measure"); + return; + } + (globalThis)); + +//# 4297 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_List_lems = global_data.UIML__List_lems, + UIML_Remove_list_lems = global_data.UIML__Remove_list_lems; + function symbol(param){return symbol;} + function dec_is_PropVar(param){ + if(typeof param !== "number" && 0 === param[0]){var s = param[1]; return [0, [0, s, symbol]];} + return [1, symbol]; + } + function dec_prop_var_in(param){ + var l0 = param[2], l = param[1]; + function f(param){ + if(! param) return [1, symbol]; + var l2 = param[2], y = param[1], match = f(l2); + if(0 === match[0]){ + var s0 = match[1], x = s0[1]; + return [0, [0, x, symbol]]; + } + var s0$0 = dec_is_PropVar(y); + if(0 !== s0$0[0]) return [1, symbol]; + var s1 = s0$0[1], s2 = caml_call2(UIML_Remove_list_lems[1], l0, y); + if(! s2) return [1, symbol]; + var x$0 = s1[1]; + return [0, [0, x$0, symbol]]; + } + return f(l); + } + function dec_KS_init_rules(param){ + var l0 = param[2], l = param[1], s0 = dec_prop_var_in([0, l, l0]); + if(0 === s0[0]){ + var + s1 = s0[1], + x = s1[1], + h = caml_call2(UIML_List_lems[1], [0, x], l), + s2 = h[2], + x0 = h[1], + x1 = s2[1], + h0 = caml_call2(UIML_List_lems[1], [0, x], l0), + s3 = h0[2], + x2 = h0[1], + x3 = s3[1]; + return [0, [0, [0, x, x0, x1, x2, x3]]]; + } + var s1$0 = caml_call2(UIML_Remove_list_lems[1], l, 0); + if(! s1$0) return [1, symbol]; + var + i = caml_call2(UIML_List_lems[1], 0, l), + s2$0 = i[2], + x$0 = i[1], + x0$0 = s2$0[1]; + return [0, [1, [0, x$0, x0$0, l0]]]; + } + var UIML_KS_dec = [0, dec_is_PropVar, dec_prop_var_in, dec_KS_init_rules]; + runtime.caml_register_global(2, UIML_KS_dec, "UIML__KS_dec"); + return; + } + (globalThis)); + +//# 4366 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst_extraction_KS_termination_ = "extraction/KS_termination_prelims.ml", + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call4(f, a0, a1, a2, a3){ + return (f.l >= 0 ? f.l : f.l = f.length) == 4 + ? f(a0, a1, a2, a3) + : runtime.caml_call_gen(f, [a0, a1, a2, a3]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_CML_Syntax = global_data.UIML__CML_Syntax, + UIML_PeanoNat = global_data.UIML__PeanoNat, + UIML_GenT = global_data.UIML__GenT, + Assert_failure = global_data.Assert_failure, + UIML_List = global_data.UIML__List, + UIML_Datatypes = global_data.UIML__Datatypes, + UIML_List_lemmasT = global_data.UIML__List_lemmasT, + _a_ = [0, cst_extraction_KS_termination_, 27, 8], + _b_ = [0, cst_extraction_KS_termination_, 44, 4], + _c_ = [0, cst_extraction_KS_termination_, 43, 23], + _d_ = [0, 0], + _e_ = [0, cst_extraction_KS_termination_, 103, 10], + _f_ = [0, cst_extraction_KS_termination_, 120, 10], + _g_ = [0, [0, 0, 0], 0], + _h_ = [0, 0, 0], + _i_ = [0, 0, 0]; + function symbol(param){return symbol;} + function proj1_sigT2(param){var a = param[1]; return a;} + function proj2_sigT2(param){var b = param[2]; return b;} + function coq_In_InT_pair(a, n, param){ + if(! param) + throw caml_maybe_attach_backtrace([0, Assert_failure, _a_], 1); + var + l0 = param[2], + y = param[1], + n0 = y[2], + m = y[1], + s = caml_call2(UIML_CML_Syntax[6], a, m), + h0 = s ? caml_call2(UIML_PeanoNat[1][1], n, n0) : 0; + return h0 + ? caml_call2(UIML_GenT[1], [0, a, n], l0) + : [1, y, l0, coq_In_InT_pair(a, n, l0)]; + } + function coq_InT_map_iff(f, param){ + if(! param) + return function(param){ + return [0, + function(param){ + throw caml_maybe_attach_backtrace([0, Assert_failure, _c_], 1); + }, + function(param){ + throw caml_maybe_attach_backtrace([0, Assert_failure, _b_], 1); + }];}; + var l0 = param[2], y = param[1], iHl = coq_InT_map_iff(f, l0); + return function(y0){ + return [0, + function(x){ + if(0 === x[0]) + return [0, y, [0, symbol, caml_call2(UIML_GenT[1], y, l0)]]; + var + x0 = x[3], + p = iHl(y0), + s = p[1], + x1 = caml_call1(s, x0), + p0 = x1[2], + x2 = x1[1], + i = p0[2]; + return [0, x2, [0, symbol, [1, y, l0, i]]]; + }, + function(x){ + var p = iHl(y0), i = p[2], p0 = x[2], i0 = p0[2]; + if(0 === i0[0]){ + var + _D_ = caml_call2(UIML_List[4], f, l0), + _E_ = caml_call1(f, y); + return caml_call2(UIML_GenT[1], _E_, _D_); + } + var + x0 = i0[3], + a = x[1], + x1 = [0, a, [0, symbol, x0]], + x2 = caml_call1(i, x1), + _F_ = caml_call2(UIML_List[4], f, l0); + return [1, caml_call1(f, y), _F_, x2]; + }];}; + } + function pos_top_imps(param){ + if(! param) return 0; + var t = param[2], h = param[1]; + if(typeof h !== "number" && 1 === h[0]){ + var b = h[2], a = h[1], _A_ = pos_top_imps(t); + return [0, + [0, [1, a, b], _d_], + caml_call2 + (UIML_List[4], + function(y){ + var _C_ = [0, caml_call1(UIML_Datatypes[2], y)]; + return [0, caml_call1(UIML_Datatypes[1], y), _C_]; + }, + _A_)]; + } + var _z_ = pos_top_imps(t); + return caml_call2 + (UIML_List[4], + function(y){ + var _B_ = [0, caml_call1(UIML_Datatypes[2], y)]; + return [0, caml_call1(UIML_Datatypes[1], y), _B_]; + }, + _z_); + } + function top_boxes_nobox_gen_ext(param){ + if(! param) return 0; + var l0 = param[2], y = param[1]; + if(typeof y !== "number" && 2 === y[0]){ + var m = y[1], _y_ = top_boxes_nobox_gen_ext(l0); + return [0, [2, m], caml_call1(UIML_CML_Syntax[9], l0), l0, _y_]; + } + var _x_ = top_boxes_nobox_gen_ext(l0); + return [1, y, caml_call1(UIML_CML_Syntax[9], l0), l0, symbol, _x_]; + } + function flatten_list(param){ + if(! param) return 0; + var t = param[2], h = param[1], _w_ = flatten_list(t); + return caml_call2(UIML_Datatypes[4], h, _w_); + } + function coq_InT_flatten_list_InT_elem(l, b, x){ + if(! l) throw caml_maybe_attach_backtrace([0, Assert_failure, _e_], 1); + var + l0 = l[2], + y = l[1], + _v_ = flatten_list(l0), + x0 = caml_call4(UIML_List_lemmasT[1], y, _v_, b, x); + if(0 === x0[0]){ + var i = x0[1]; + return [0, y, [0, i, caml_call2(UIML_GenT[1], y, l0)]]; + } + var + i$0 = x0[1], + i0 = coq_InT_flatten_list_InT_elem(l0, b, i$0), + p = i0[2], + x1 = i0[1], + i2 = p[2], + i1 = p[1]; + return [0, x1, [0, i1, [1, y, l0, i2]]]; + } + function coq_InT_trans_flatten_list(l, bs, b, x, x0){ + if(! l) throw caml_maybe_attach_backtrace([0, Assert_failure, _f_], 1); + var l0 = l[2], y = l[1]; + if(0 === x0[0]){ + var _s_ = flatten_list(l0); + return caml_call4(UIML_List_lemmasT[2], bs, _s_, b, [0, x]); + } + var + x1 = x0[3], + _t_ = [1, coq_InT_trans_flatten_list(l0, bs, b, x, x1)], + _u_ = flatten_list(l0); + return caml_call4(UIML_List_lemmasT[2], y, _u_, b, _t_); + } + function list_of_splits(param){ + if(! param) return [0, _g_, symbol]; + var + l0 = param[2], + y = param[1], + x = list_of_splits(l0)[1], + _q_ = + caml_call2 + (UIML_List[4], + function(y0){ + var _r_ = caml_call1(UIML_Datatypes[2], y0); + return [0, [0, y, caml_call1(UIML_Datatypes[1], y0)], _r_]; + }, + x); + return [0, + caml_call2(UIML_Datatypes[4], [0, [0, 0, [0, y, l0]], 0], _q_), + symbol]; + } + function listInserts(l, a){ + var a$0 = list_of_splits(l)[1]; + return caml_call2 + (UIML_List[4], + function(y){ + var + _o_ = [0, a, caml_call1(UIML_Datatypes[2], y)], + _p_ = caml_call1(UIML_Datatypes[1], y); + return caml_call2(UIML_Datatypes[4], _p_, _o_); + }, + a$0); + } + function listInsertsR_Seqs(UU0393, UU0394, a){ + var _n_ = listInserts(UU0393, a); + return caml_call2(UIML_List[4], function(y){return [0, y, UU0394];}, _n_); + } + function listInsertsL_Seqs(UU0393, UU0394, a){ + var _m_ = listInserts(UU0394, a); + return caml_call2(UIML_List[4], function(y){return [0, UU0393, y];}, _m_); + } + function remove_nth(n, a, l){ + if(! n) return l; + var m = n[1]; + if(m){ + if(! l) return 0; + var tl = l[2], b = l[1]; + return [0, b, remove_nth(m, a, tl)]; + } + if(! l) return 0; + var tl$0 = l[2], b$0 = l[1]; + return caml_call2(UIML_CML_Syntax[6], a, b$0) ? tl$0 : [0, b$0, tl$0]; + } + function nth_split(n, l){ + if(! n) return [0, 0, l]; + var m = n[1]; + if(m){ + if(! l) return _h_; + var + tl = l[2], + b = l[1], + _j_ = nth_split(m, tl), + _k_ = caml_call1(UIML_Datatypes[2], _j_), + _l_ = nth_split(m, tl); + return [0, [0, b, caml_call1(UIML_Datatypes[1], _l_)], _k_]; + } + if(! l) return _i_; + var tl$0 = l[2], b$0 = l[1]; + return [0, [0, b$0, 0], tl$0]; + } + var + UIML_KS_termination_prelims = + [0, + proj1_sigT2, + proj2_sigT2, + coq_In_InT_pair, + coq_InT_map_iff, + pos_top_imps, + top_boxes_nobox_gen_ext, + flatten_list, + coq_InT_flatten_list_InT_elem, + coq_InT_trans_flatten_list, + list_of_splits, + listInserts, + listInsertsR_Seqs, + listInsertsL_Seqs, + remove_nth, + nth_split]; + runtime.caml_register_global + (16, UIML_KS_termination_prelims, "UIML__KS_termination_prelims"); + return; + } + (globalThis)); + +//# 4631 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst_extraction_KS_termination_ = "extraction/KS_termination_ImpR.ml", + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + function caml_call4(f, a0, a1, a2, a3){ + return (f.l >= 0 ? f.l : f.l = f.length) == 4 + ? f(a0, a1, a2, a3) + : runtime.caml_call_gen(f, [a0, a1, a2, a3]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_Datatypes = global_data.UIML__Datatypes, + UIML_KS_termination_prelims = global_data.UIML__KS_termination_prelims, + UIML_List = global_data.UIML__List, + Assert_failure = global_data.Assert_failure, + UIML_List_lemmasT = global_data.UIML__List_lemmasT, + UIML_CML_Syntax = global_data.UIML__CML_Syntax, + UIML_List_lems = global_data.UIML__List_lems, + _a_ = [0, cst_extraction_KS_termination_, 59, 15], + _b_ = [0, 0], + _c_ = [0, cst_extraction_KS_termination_, 51, 18], + _d_ = [0, cst_extraction_KS_termination_, 39, 10], + _e_ = [0, cst_extraction_KS_termination_, 75, 12], + _f_ = [0, cst_extraction_KS_termination_, 343, 28], + _g_ = [0, cst_extraction_KS_termination_, 249, 18], + _h_ = [0, cst_extraction_KS_termination_, 228, 10]; + function symbol(param){return symbol;} + function prems_Imp_R(l, s){ + var l$0 = l; + for(;;){ + if(! l$0) return 0; + var t = l$0[2], p = l$0[1], n = p[2], c = p[1]; + if(n){ + var m = n[1]; + if(typeof c !== "number" && 1 === c[0]){ + var + b = c[2], + a = c[1], + _bm_ = prems_Imp_R(t, s), + _bn_ = caml_call1(UIML_Datatypes[2], s), + _bo_ = caml_call3(UIML_KS_termination_prelims[14], [0, m], c, _bn_), + _bp_ = caml_call2(UIML_KS_termination_prelims[15], m, _bo_), + _bq_ = [0, b, caml_call1(UIML_Datatypes[2], _bp_)], + _br_ = caml_call1(UIML_Datatypes[2], s), + _bs_ = caml_call3(UIML_KS_termination_prelims[14], [0, m], c, _br_), + _bt_ = caml_call2(UIML_KS_termination_prelims[15], m, _bs_), + _bu_ = caml_call1(UIML_Datatypes[1], _bt_), + _bv_ = caml_call2(UIML_Datatypes[4], _bu_, _bq_), + _bw_ = caml_call1(UIML_Datatypes[1], s), + _bx_ = caml_call3(UIML_KS_termination_prelims[12], _bw_, _bv_, a); + return caml_call2(UIML_Datatypes[4], _bx_, _bm_); + } + l$0 = t; + } + else + l$0 = t; + } + } + function coq_In_pos_top_imps_split_l(l, a, n){ + if(! l) throw caml_maybe_attach_backtrace([0, Assert_failure, _d_], 1); + var l0 = l[2], y = l[1]; + if(typeof y !== "number" && 1 === y[0]){ + var + m0 = y[2], + m = y[1], + _bj_ = caml_call1(UIML_KS_termination_prelims[5], l0), + _bk_ = + [0, + [0, [1, m, m0], _b_], + caml_call2 + (UIML_List[4], + function(y0){ + var _bl_ = [0, caml_call1(UIML_Datatypes[2], y0)]; + return [0, caml_call1(UIML_Datatypes[1], y0), _bl_]; + }, + _bj_)], + h = caml_call3(UIML_KS_termination_prelims[3], a, [0, n], _bk_); + if(0 === h[0]) return [0, 0, [0, l0, symbol]]; + if(! n) throw caml_maybe_attach_backtrace([0, Assert_failure, _c_], 1); + var + n0$0 = n[1], + s$0 = coq_In_pos_top_imps_split_l(l0, a, n0$0), + s0$0 = s$0[2], + x = s$0[1], + x0$0 = s0$0[1]; + return [0, [0, [1, m, m0], x], [0, x0$0, symbol]]; + } + if(! n) throw caml_maybe_attach_backtrace([0, Assert_failure, _a_], 1); + var + n0 = n[1], + s = coq_In_pos_top_imps_split_l(l0, a, n0), + s0 = s[2], + x0 = s[1], + x1 = s0[1]; + return [0, [0, y, x0], [0, x1, symbol]]; + } + function coq_ImpR_help01(prem, s, l3){ + var l0 = s[2], l = s[1]; + function f(l1, x){ + if(! l1) throw caml_maybe_attach_backtrace([0, Assert_failure, _e_], 1); + var l2 = l1[2], y = l1[1], n = y[2], m = y[1]; + if(typeof m !== "number" && 1 === m[0]){ + var m1 = m[2], m0 = m[1]; + if(! n){ + var + s0$1 = f(l2, x), + s1$1 = s0$1[2], + x0$1 = s0$1[1], + s2$1 = s1$1[2], + x1$2 = s1$1[1], + s3$1 = s2$1[2], + x2$2 = s2$1[1], + s4$1 = s3$1[2], + x3$2 = s3$1[1], + s5$1 = s4$1[2], + x4$2 = s4$1[1], + s6$1 = s5$1[2], + x5$1 = s5$1[1], + x6$1 = s6$1[1]; + return [0, + x0$1, + [0, + x1$2, + [0, x2$2, [0, x3$2, [0, x4$2, [0, x5$1, [0, x6$1, symbol]]]]]]]; + } + var + n0 = n[1], + prems_Imp_R0 = + function(l4, s0){ + var l4$0 = l4; + for(;;){ + if(! l4$0) return 0; + var l4$1 = l4$0[2], p = l4$0[1], n1 = p[2], c = p[1]; + if(n1){ + var m2 = n1[1]; + if(typeof c !== "number" && 1 === c[0]){ + var + b = c[2], + a = c[1], + _a9_ = prems_Imp_R0(l4$1, s0), + _a__ = caml_call1(UIML_Datatypes[2], s0), + _a$_ = + caml_call3(UIML_KS_termination_prelims[14], [0, m2], c, _a__), + _ba_ = caml_call2(UIML_KS_termination_prelims[15], m2, _a$_), + _bb_ = [0, b, caml_call1(UIML_Datatypes[2], _ba_)], + _bc_ = caml_call1(UIML_Datatypes[2], s0), + _bd_ = + caml_call3(UIML_KS_termination_prelims[14], [0, m2], c, _bc_), + _be_ = caml_call2(UIML_KS_termination_prelims[15], m2, _bd_), + _bf_ = caml_call1(UIML_Datatypes[1], _be_), + _bg_ = caml_call2(UIML_Datatypes[4], _bf_, _bb_), + _bh_ = caml_call1(UIML_Datatypes[1], s0), + _bi_ = + caml_call3(UIML_KS_termination_prelims[12], _bh_, _bg_, a); + return caml_call2(UIML_Datatypes[4], _bi_, _a9_); + } + l4$0 = l4$1; + } + else + l4$0 = l4$1; + } + }, + _aJ_ = prems_Imp_R0(l2, [0, l, l0]), + _aK_ = caml_call1(UIML_Datatypes[2], [0, l, l0]), + _aL_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], _aK_), + _aM_ = caml_call2(UIML_KS_termination_prelims[15], n0, _aL_), + _aN_ = [0, m1, caml_call1(UIML_Datatypes[2], _aM_)], + _aO_ = caml_call1(UIML_Datatypes[2], [0, l, l0]), + _aP_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], _aO_), + _aQ_ = caml_call2(UIML_KS_termination_prelims[15], n0, _aP_), + _aR_ = caml_call1(UIML_Datatypes[1], _aQ_), + _aS_ = caml_call2(UIML_Datatypes[4], _aR_, _aN_), + _aT_ = caml_call1(UIML_Datatypes[1], [0, l, l0]), + _aU_ = caml_call3(UIML_KS_termination_prelims[12], _aT_, _aS_, m0), + x0$0 = caml_call4(UIML_List_lemmasT[1], _aU_, _aJ_, prem, x); + if(0 === x0$0[0]){ + var + i = x0$0[1], + l4 = caml_call2(UIML_KS_termination_prelims[11], l, m0), + f0 = + function(y0){ + var + _a3_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], l0), + _a4_ = caml_call2(UIML_KS_termination_prelims[15], n0, _a3_), + _a5_ = [0, m1, caml_call1(UIML_Datatypes[2], _a4_)], + _a6_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], l0), + _a7_ = caml_call2(UIML_KS_termination_prelims[15], n0, _a6_), + _a8_ = caml_call1(UIML_Datatypes[1], _a7_); + return [0, y0, caml_call2(UIML_Datatypes[4], _a8_, _a5_)]; + }, + x1$0 = caml_call3(UIML_KS_termination_prelims[4], f0, l4, prem)[1], + i0 = caml_call1(x1$0, i), + p = i0[2], + x2$0 = i0[1], + i1 = p[2], + _aV_ = caml_call1(UIML_KS_termination_prelims[10], l), + l4$0 = caml_call1(UIML_KS_termination_prelims[1], _aV_), + f0$0 = + function(y0){ + var + _a1_ = [0, m0, caml_call1(UIML_Datatypes[2], y0)], + _a2_ = caml_call1(UIML_Datatypes[1], y0); + return caml_call2(UIML_Datatypes[4], _a2_, _a1_); + }, + x3$0 = caml_call3(UIML_KS_termination_prelims[4], f0$0, l4$0, x2$0)[1], + i2 = caml_call1(x3$0, i1), + x4$0 = i2[1], + l5 = x4$0[2], + l4$1 = x4$0[1], + _aW_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], l0), + _aX_ = caml_call2(UIML_KS_termination_prelims[15], n0, _aW_), + _aY_ = [0, caml_call1(UIML_Datatypes[2], _aX_), symbol], + _aZ_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], l0), + _a0_ = caml_call2(UIML_KS_termination_prelims[15], n0, _aZ_); + return [0, + n0, + [0, + m0, + [0, + m1, + [0, + l4$1, + [0, l5, [0, caml_call1(UIML_Datatypes[1], _a0_), _aY_]]]]]]; + } + var + i$0 = x0$0[1], + s0$0 = f(l2, i$0), + s1$0 = s0$0[2], + x1$1 = s0$0[1], + s2$0 = s1$0[2], + x2$1 = s1$0[1], + s3$0 = s2$0[2], + x3$1 = s2$0[1], + s4$0 = s3$0[2], + x4$1 = s3$0[1], + s5$0 = s4$0[2], + x5$0 = s4$0[1], + s6$0 = s5$0[2], + x6$0 = s5$0[1], + x7 = s6$0[1]; + return [0, + x1$1, + [0, + x2$1, + [0, x3$1, [0, x4$1, [0, x5$0, [0, x6$0, [0, x7, symbol]]]]]]]; + } + var + s0 = f(l2, x), + s1 = s0[2], + x0 = s0[1], + s2 = s1[2], + x1 = s1[1], + s3 = s2[2], + x2 = s2[1], + s4 = s3[2], + x3 = s3[1], + s5 = s4[2], + x4 = s4[1], + s6 = s5[2], + x5 = s5[1], + x6 = s6[1]; + return [0, + x0, + [0, x1, [0, x2, [0, x3, [0, x4, [0, x5, [0, x6, symbol]]]]]]]; + } + return function(_aI_){return f(l3, _aI_);}; + } + function coq_ImpR_help1(prem, s, x){ + var + _aH_ = caml_call1(UIML_Datatypes[2], s), + s0 = + coq_ImpR_help01 + (prem, s, caml_call1(UIML_KS_termination_prelims[5], _aH_)) + (x), + s1 = s0[2], + x0 = s0[1], + l = s[2], + s2 = s1[2], + x1 = s1[1], + s3 = s2[2], + x2 = s2[1], + s4 = s3[2], + x3 = s3[1], + x4 = s4[1], + i = coq_In_pos_top_imps_split_l(l, [1, x1, x2], x0), + s5 = i[2], + x5 = i[1], + x6 = s5[1]; + return [0, x1, x2, x3, x4, x5, x6]; + } + function coq_ImpR_help002(UU0393_0, UU0393_1, UU0394_0, UU0394_1, a, b){ + function f(y){ + return [0, y, caml_call2(UIML_Datatypes[4], UU0394_0, [0, b, UU0394_1])]; + } + var + _az_ = caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), + l = caml_call2(UIML_KS_termination_prelims[11], _az_, a), + _aA_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, b, UU0394_1]), + y = [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), _aA_], + x = caml_call3(UIML_KS_termination_prelims[4], f, l, y)[2]; + function f0(y0){ + var + _aF_ = [0, a, caml_call1(UIML_Datatypes[2], y0)], + _aG_ = caml_call1(UIML_Datatypes[1], y0); + return caml_call2(UIML_Datatypes[4], _aG_, _aF_); + } + var + _aB_ = caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), + _aC_ = caml_call1(UIML_KS_termination_prelims[10], _aB_), + l0 = caml_call1(UIML_KS_termination_prelims[1], _aC_), + y0 = caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), + x0 = caml_call3(UIML_KS_termination_prelims[4], f0, l0, y0)[2], + _aD_ = caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), + s = caml_call1(UIML_KS_termination_prelims[10], _aD_), + x1 = s[1], + _aE_ = + [0, + symbol, + caml_call1 + (x0, + [0, + [0, UU0393_0, UU0393_1], + [0, + symbol, + caml_call2(UIML_List_lems[5], [0, UU0393_0, UU0393_1], x1)]])]; + return caml_call1 + (x, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), + _aE_]); + } + function coq_ImpR_help02 + (UU0393_0, UU0393_1, UU0394_0, UU0394_1, a, b, l, n, x){ + var l$0 = l, n$0 = n; + for(;;){ + if(! l$0) throw caml_maybe_attach_backtrace([0, Assert_failure, _h_], 1); + var l0 = l$0[2], y = l$0[1], n0 = y[2], m = y[1]; + if(typeof m !== "number" && 1 === m[0]){ + var + m1 = m[2], + m0 = m[1], + h1$0 = + caml_call3 + (UIML_KS_termination_prelims[3], + [1, a, b], + [0, n$0], + [0, [0, [1, m0, m1], n0], l0]); + if(0 === h1$0[0]){ + if(UU0394_0){ + var + l1 = UU0394_0[2], + m2 = UU0394_0[1], + _v_ = + [0, + coq_ImpR_help002(UU0393_0, UU0393_1, [0, m2, l1], UU0394_1, a, b)], + _w_ = caml_call2(UIML_Datatypes[4], [0, m2, l1], [0, b, UU0394_1]), + prems_Imp_R0 = + function(l2, s){ + var l2$0 = l2; + for(;;){ + if(! l2$0) return 0; + var l2$1 = l2$0[2], p = l2$0[1], n1 = p[2], c = p[1]; + if(n1){ + var m3 = n1[1]; + if(typeof c !== "number" && 1 === c[0]){ + var + b0 = c[2], + a0 = c[1], + _an_ = prems_Imp_R0(l2$1, s), + _ao_ = caml_call1(UIML_Datatypes[2], s), + _ap_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, m3], c, _ao_), + _aq_ = caml_call2(UIML_KS_termination_prelims[15], m3, _ap_), + _ar_ = [0, b0, caml_call1(UIML_Datatypes[2], _aq_)], + _as_ = caml_call1(UIML_Datatypes[2], s), + _at_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, m3], c, _as_), + _au_ = caml_call2(UIML_KS_termination_prelims[15], m3, _at_), + _av_ = caml_call1(UIML_Datatypes[1], _au_), + _aw_ = caml_call2(UIML_Datatypes[4], _av_, _ar_), + _ax_ = caml_call1(UIML_Datatypes[1], s), + _ay_ = + caml_call3(UIML_KS_termination_prelims[12], _ax_, _aw_, a0); + return caml_call2(UIML_Datatypes[4], _ay_, _an_); + } + l2$0 = l2$1; + } + else + l2$0 = l2$1; + } + }, + _x_ = + [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), _w_], + _y_ = + caml_call2 + (UIML_Datatypes[4], [0, m2, l1], [0, [1, a, b], UU0394_1]), + _z_ = + prems_Imp_R0 + (l0, [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _y_]), + _A_ = + caml_call2 + (UIML_Datatypes[4], [0, m2, l1], [0, [1, a, b], UU0394_1]), + _B_ = [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _A_], + _C_ = caml_call1(UIML_Datatypes[2], _B_), + _D_ = [0, caml_call1(UIML_Datatypes[3], [0, m2, l1])], + _E_ = + caml_call3(UIML_KS_termination_prelims[14], _D_, [1, a, b], _C_), + _F_ = caml_call1(UIML_Datatypes[3], [0, m2, l1]), + _G_ = caml_call2(UIML_KS_termination_prelims[15], _F_, _E_), + _H_ = [0, b, caml_call1(UIML_Datatypes[2], _G_)], + _I_ = + caml_call2 + (UIML_Datatypes[4], [0, m2, l1], [0, [1, a, b], UU0394_1]), + _J_ = [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _I_], + _K_ = caml_call1(UIML_Datatypes[2], _J_), + _L_ = [0, caml_call1(UIML_Datatypes[3], [0, m2, l1])], + _M_ = + caml_call3(UIML_KS_termination_prelims[14], _L_, [1, a, b], _K_), + _N_ = caml_call1(UIML_Datatypes[3], [0, m2, l1]), + _O_ = caml_call2(UIML_KS_termination_prelims[15], _N_, _M_), + _P_ = caml_call1(UIML_Datatypes[1], _O_), + _Q_ = caml_call2(UIML_Datatypes[4], _P_, _H_), + _R_ = + caml_call2 + (UIML_Datatypes[4], [0, m2, l1], [0, [1, a, b], UU0394_1]), + _S_ = [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _R_], + _T_ = caml_call1(UIML_Datatypes[1], _S_), + _U_ = caml_call3(UIML_KS_termination_prelims[12], _T_, _Q_, a); + return caml_call4(UIML_List_lemmasT[2], _U_, _z_, _x_, _v_); + } + var + i = coq_ImpR_help002(UU0393_0, UU0393_1, 0, UU0394_1, a, b), + s = caml_call2(UIML_CML_Syntax[6], [1, a, b], [1, a, b]); + if(! s) throw caml_maybe_attach_backtrace([0, Assert_failure, _g_], 1); + var + _V_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), + [0, b, UU0394_1]], + _W_ = + prems_Imp_R + (l0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), + [0, [1, a, b], UU0394_1]]), + _X_ = caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), + _Y_ = + caml_call3 + (UIML_KS_termination_prelims[12], _X_, [0, b, UU0394_1], a); + return caml_call4(UIML_List_lemmasT[2], _Y_, _W_, _V_, [0, i]); + } + var + i$0 = + coq_ImpR_help02 + (UU0393_0, + UU0393_1, + UU0394_0, + UU0394_1, + a, + b, + l0, + caml_call1(UIML_Datatypes[3], UU0394_0), + x); + if(! n0) return i$0; + var + n1 = n0[1], + ___ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, b, UU0394_1]), + _$_ = + [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), ___], + _aa_ = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, [1, a, b], UU0394_1]), + _Z_ = [1, i$0], + _ab_ = + prems_Imp_R + (l0, [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _aa_]); + if(n1){ + var + match = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, [1, a, b], UU0394_1]); + if(match) + var + tl = match[2], + b0 = match[1], + _ac_ = + [0, + b0, + caml_call3(UIML_KS_termination_prelims[14], n1, [1, m0, m1], tl)]; + else + var _ac_ = 0; + var _ad_ = _ac_; + } + else{ + var + match$2 = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, [1, a, b], UU0394_1]); + if(match$2) + var + tl$4 = match$2[2], + b0$2 = match$2[1], + tl$5 = + caml_call2(UIML_CML_Syntax[6], [1, m0, m1], b0$2) + ? tl$4 + : [0, b0$2, tl$4], + tl$6 = tl$5; + else + var tl$6 = 0; + var _ad_ = tl$6; + } + var + _ae_ = caml_call2(UIML_KS_termination_prelims[15], n1, _ad_), + _af_ = [0, m1, caml_call1(UIML_Datatypes[2], _ae_)]; + if(n1){ + var + match$0 = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, [1, a, b], UU0394_1]); + if(match$0) + var + tl$0 = match$0[2], + b0$0 = match$0[1], + _ag_ = + [0, + b0$0, + caml_call3(UIML_KS_termination_prelims[14], n1, [1, m0, m1], tl$0)]; + else + var _ag_ = 0; + var _ah_ = _ag_; + } + else{ + var + match$1 = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, [1, a, b], UU0394_1]); + if(match$1) + var + tl$1 = match$1[2], + b0$1 = match$1[1], + tl$2 = + caml_call2(UIML_CML_Syntax[6], [1, m0, m1], b0$1) + ? tl$1 + : [0, b0$1, tl$1], + tl$3 = tl$2; + else + var tl$3 = 0; + var _ah_ = tl$3; + } + var + _ai_ = caml_call2(UIML_KS_termination_prelims[15], n1, _ah_), + _aj_ = caml_call1(UIML_Datatypes[1], _ai_), + _ak_ = caml_call2(UIML_Datatypes[4], _aj_, _af_), + _al_ = caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), + _am_ = caml_call3(UIML_KS_termination_prelims[12], _al_, _ak_, m0); + return caml_call4(UIML_List_lemmasT[2], _am_, _ab_, _$_, _Z_); + } + var + h1 = + caml_call3 + (UIML_KS_termination_prelims[3], + [1, a, b], + [0, n$0], + [0, [0, m, n0], l0]); + if(0 === h1[0]) + throw caml_maybe_attach_backtrace([0, Assert_failure, _f_], 1); + var n$1 = caml_call1(UIML_Datatypes[3], UU0394_0); + l$0 = l0; + n$0 = n$1; + } + } + function coq_ImpR_help2(param, _s_, x){ + var + UU0394_1 = x[6], + UU0394_0 = x[5], + UU0393_1 = x[4], + UU0393_0 = x[3], + b = x[2], + a = x[1], + _t_ = caml_call1(UIML_Datatypes[3], UU0394_0), + _u_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, [1, a, b], UU0394_1]); + return coq_ImpR_help02 + (UU0393_0, + UU0393_1, + UU0394_0, + UU0394_1, + a, + b, + caml_call1(UIML_KS_termination_prelims[5], _u_), + _t_, + x); + } + function finite_ImpR_premises_of_S(param){ + var + l0 = param[2], + l = param[1], + _i_ = + prems_Imp_R(caml_call1(UIML_KS_termination_prelims[5], l0), [0, l, l0]); + return [0, + caml_call2(UIML_List[4], function(y){return [0, y, 0];}, _i_), + function(prems){ + return [0, + function(h){ + var + UU0394_1 = h[6], + UU0394_0 = h[5], + UU0393_1 = h[4], + UU0393_0 = h[3], + b = h[2], + a = h[1]; + function f(y){return [0, y, 0];} + var + _j_ = + caml_call2 + (UIML_Datatypes[4], UU0394_0, [0, [1, a, b], UU0394_1]), + _k_ = + [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _j_], + _l_ = + caml_call2 + (UIML_Datatypes[4], UU0394_0, [0, [1, a, b], UU0394_1]), + l1 = + prems_Imp_R + (caml_call1(UIML_KS_termination_prelims[5], _l_), _k_), + _m_ = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, b, UU0394_1]), + y = + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), + _m_], + 0], + x = caml_call3(UIML_KS_termination_prelims[4], f, l1, y)[2], + _n_ = + caml_call2 + (UIML_Datatypes[4], UU0394_0, [0, [1, a, b], UU0394_1]), + _o_ = + [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _n_], + _p_ = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, b, UU0394_1]), + _q_ = + [0, + symbol, + coq_ImpR_help2 + ([0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), + _p_], + _o_, + h)], + _r_ = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, b, UU0394_1]); + return caml_call1 + (x, + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), + _r_], + _q_]); + }, + function(h){ + var + l1 = + prems_Imp_R + (caml_call1(UIML_KS_termination_prelims[5], l0), [0, l, l0]); + function f(y){return [0, y, 0];} + var + x = + caml_call3(UIML_KS_termination_prelims[4], f, l1, prems)[1], + h0 = caml_call1(x, h), + p = h0[2], + x0 = h0[1], + i = p[2]; + return coq_ImpR_help1(x0, [0, l, l0], i); + }]; + }]; + } + var + UIML_KS_termination_ImpR = + [0, + prems_Imp_R, + coq_In_pos_top_imps_split_l, + coq_ImpR_help01, + coq_ImpR_help1, + coq_ImpR_help002, + coq_ImpR_help02, + coq_ImpR_help2, + finite_ImpR_premises_of_S]; + runtime.caml_register_global + (15, UIML_KS_termination_ImpR, "UIML__KS_termination_ImpR"); + return; + } + (globalThis)); + +//# 5352 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst_extraction_KS_termination_ = "extraction/KS_termination_ImpL.ml", + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + function caml_call4(f, a0, a1, a2, a3){ + return (f.l >= 0 ? f.l : f.l = f.length) == 4 + ? f(a0, a1, a2, a3) + : runtime.caml_call_gen(f, [a0, a1, a2, a3]); + } + function caml_call5(f, a0, a1, a2, a3, a4){ + return (f.l >= 0 ? f.l : f.l = f.length) == 5 + ? f(a0, a1, a2, a3, a4) + : runtime.caml_call_gen(f, [a0, a1, a2, a3, a4]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_Datatypes = global_data.UIML__Datatypes, + UIML_KS_termination_prelims = global_data.UIML__KS_termination_prelims, + UIML_List = global_data.UIML__List, + UIML_CML_Syntax = global_data.UIML__CML_Syntax, + UIML_GenT = global_data.UIML__GenT, + Assert_failure = global_data.Assert_failure, + UIML_List_lemmasT = global_data.UIML__List_lemmasT, + UIML_KS_termination_ImpR = global_data.UIML__KS_termination_ImpR, + UIML_List_lems = global_data.UIML__List_lems, + _a_ = [0, cst_extraction_KS_termination_, 378, 28], + _b_ = [0, cst_extraction_KS_termination_, 286, 23], + _c_ = [0, cst_extraction_KS_termination_, 112, 10], + _d_ = [0, cst_extraction_KS_termination_, 647, 40], + _e_ = [0, cst_extraction_KS_termination_, 402, 12]; + function symbol(param){return symbol;} + function prems_Imp_L(l, s){ + var l$0 = l; + for(;;){ + if(! l$0) return 0; + var t = l$0[2], p = l$0[1], n = p[2], c = p[1]; + if(n){ + var m = n[1]; + if(typeof c !== "number" && 1 === c[0]){ + var + b = c[2], + a = c[1], + _fE_ = prems_Imp_L(t, s), + _fF_ = caml_call1(UIML_Datatypes[2], s), + _fG_ = caml_call1(UIML_Datatypes[1], s), + _fH_ = caml_call3(UIML_KS_termination_prelims[14], [0, m], c, _fG_), + _fI_ = caml_call2(UIML_KS_termination_prelims[15], m, _fH_), + _fJ_ = [0, b, caml_call1(UIML_Datatypes[2], _fI_)], + _fK_ = caml_call1(UIML_Datatypes[1], s), + _fL_ = caml_call3(UIML_KS_termination_prelims[14], [0, m], c, _fK_), + _fM_ = caml_call2(UIML_KS_termination_prelims[15], m, _fL_), + _fN_ = caml_call1(UIML_Datatypes[1], _fM_), + _fO_ = [0, [0, caml_call2(UIML_Datatypes[4], _fN_, _fJ_), _fF_], 0], + _fP_ = + caml_call2 + (UIML_List[4], + function(y){ + var + _fR_ = caml_call1(UIML_Datatypes[2], s), + _fS_ = caml_call1(UIML_Datatypes[1], s), + _fT_ = + caml_call3(UIML_KS_termination_prelims[14], [0, m], c, _fS_), + _fU_ = caml_call2(UIML_KS_termination_prelims[15], m, _fT_), + _fV_ = caml_call1(UIML_Datatypes[2], _fU_), + _fW_ = caml_call1(UIML_Datatypes[1], s), + _fX_ = + caml_call3(UIML_KS_termination_prelims[14], [0, m], c, _fW_), + _fY_ = caml_call2(UIML_KS_termination_prelims[15], m, _fX_), + _fZ_ = caml_call1(UIML_Datatypes[1], _fY_), + _f0_ = caml_call2(UIML_Datatypes[4], _fZ_, _fV_), + _f1_ = + caml_call3(UIML_KS_termination_prelims[13], _f0_, _fR_, a); + return caml_call2 + (UIML_List[4], function(z){return [0, z, [0, y, 0]];}, _f1_); + }, + _fO_), + _fQ_ = caml_call1(UIML_KS_termination_prelims[7], _fP_); + return caml_call2(UIML_Datatypes[4], _fQ_, _fE_); + } + l$0 = t; + } + else + l$0 = t; + } + } + function coq_ImpL_help002(UU0393_0, UU0393_1, UU0394_0, UU0394_1, a, b){ + var + _eS_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _eT_ = + [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), _eS_], + 0], + _eU_ = + caml_call2 + (UIML_List[4], + function(z){ + var + _fD_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]); + return [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _fD_], + [0, z, 0]]; + }, + _eT_), + _eV_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _eW_ = caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), + _eX_ = caml_call3(UIML_KS_termination_prelims[13], _eW_, _eV_, a), + p = + caml_call3 + (UIML_KS_termination_prelims[4], + function(y){ + var + _fB_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _fC_ = + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), + _fB_], + 0]; + return caml_call2 + (UIML_List[4], function(z){return [0, y, [0, z, 0]];}, _fC_); + }, + _eX_, + _eU_), + i = p[2], + _eY_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]), + _eZ_ = [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _eY_], + _e0_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _e1_ = caml_call2(UIML_KS_termination_prelims[11], _e0_, a), + p0 = + caml_call3 + (UIML_KS_termination_prelims[4], + function(y){ + return [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), y]; + }, + _e1_, + _eZ_), + i0 = p0[2], + _e2_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]), + _e3_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _e4_ = caml_call1(UIML_KS_termination_prelims[10], _e3_), + _e5_ = caml_call1(UIML_KS_termination_prelims[1], _e4_), + p1 = + caml_call3 + (UIML_KS_termination_prelims[4], + function(y){ + var + _fz_ = [0, a, caml_call1(UIML_Datatypes[2], y)], + _fA_ = caml_call1(UIML_Datatypes[1], y); + return caml_call2(UIML_Datatypes[4], _fA_, _fz_); + }, + _e5_, + _e2_), + i1 = p1[2], + _e6_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + s = caml_call1(UIML_KS_termination_prelims[10], _e6_), + x = s[1], + _e7_ = + [0, + symbol, + caml_call1 + (i1, + [0, + [0, UU0394_0, UU0394_1], + [0, + symbol, + caml_call2(UIML_List_lems[5], [0, UU0394_0, UU0394_1], x)]])], + _e8_ = + [0, + symbol, + caml_call1 + (i0, + [0, caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]), _e7_])], + _e9_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]), + _e__ = + caml_call1 + (i, + [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _e9_], + _e8_]), + _e$_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _fa_ = + [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), _e$_], + 0], + _fb_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]), + _fc_ = + [0, [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _fb_], _fa_], + _fd_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _fe_ = + [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), _fd_], + 0], + p$0 = + caml_call3 + (UIML_KS_termination_prelims[4], + function(z){ + var + _fy_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]); + return [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _fy_], + [0, z, 0]]; + }, + _fe_, + _fc_), + i$0 = p$0[2], + _ff_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _fg_ = + [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), _ff_], + _fh_ = [0, symbol, caml_call2(UIML_GenT[1], _fg_, 0)], + _fi_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _fj_ = + caml_call1 + (i$0, + [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), _fi_], + _fh_]), + _fk_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _fl_ = + [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), _fk_], + 0], + _fm_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]), + _fn_ = + [0, [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _fm_], _fl_], + _fo_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _fp_ = + [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), _fo_], + 0], + _fq_ = + caml_call2 + (UIML_List[4], + function(z){ + var + _fx_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]); + return [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _fx_], + [0, z, 0]]; + }, + _fp_), + _fr_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _fs_ = caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), + _ft_ = caml_call3(UIML_KS_termination_prelims[13], _fs_, _fr_, a), + _fu_ = + caml_call2 + (UIML_List[4], + function(y){ + var + _fv_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _fw_ = + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), + _fv_], + 0]; + return caml_call2 + (UIML_List[4], function(z){return [0, y, [0, z, 0]];}, _fw_); + }, + _ft_); + return caml_call5 + (UIML_KS_termination_prelims[9], _fu_, _fq_, _fn_, _fj_, _e__); + } + function coq_ImpL_help02 + (UU0393_0, UU0393_1, UU0394_0, UU0394_1, a, b, l, n, x){ + var l$0 = l, n$0 = n; + for(;;){ + if(! l$0) throw caml_maybe_attach_backtrace([0, Assert_failure, _c_], 1); + var l0 = l$0[2], y = l$0[1], n0 = y[2], m = y[1]; + if(typeof m !== "number" && 1 === m[0]){ + var + m1 = m[2], + m0 = m[1], + h1$0 = + caml_call3 + (UIML_KS_termination_prelims[3], + [1, a, b], + [0, n$0], + [0, [0, [1, m0, m1], n0], l0]); + if(0 === h1$0[0]){ + var + i = coq_ImpL_help002(UU0393_0, UU0393_1, UU0394_0, UU0394_1, a, b), + f = + function(y0){ + var + _ex_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _ey_ = + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _ex_], + _ez_ = caml_call1(UIML_Datatypes[2], _ey_), + _eA_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _eB_ = + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _eA_], + _eC_ = caml_call1(UIML_Datatypes[1], _eB_), + _eD_ = [0, caml_call1(UIML_Datatypes[3], UU0393_0)], + _eE_ = + caml_call3 + (UIML_KS_termination_prelims[14], _eD_, [1, a, b], _eC_), + _eF_ = caml_call1(UIML_Datatypes[3], UU0393_0), + _eG_ = caml_call2(UIML_KS_termination_prelims[15], _eF_, _eE_), + _eH_ = caml_call1(UIML_Datatypes[2], _eG_), + _eI_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _eJ_ = + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _eI_], + _eK_ = caml_call1(UIML_Datatypes[1], _eJ_), + _eL_ = [0, caml_call1(UIML_Datatypes[3], UU0393_0)], + _eM_ = + caml_call3 + (UIML_KS_termination_prelims[14], _eL_, [1, a, b], _eK_), + _eN_ = caml_call1(UIML_Datatypes[3], UU0393_0), + _eO_ = caml_call2(UIML_KS_termination_prelims[15], _eN_, _eM_), + _eP_ = caml_call1(UIML_Datatypes[1], _eO_), + _eQ_ = caml_call2(UIML_Datatypes[4], _eP_, _eH_), + _eR_ = caml_call3(UIML_KS_termination_prelims[13], _eQ_, _ez_, a); + return caml_call2 + (UIML_List[4], + function(z){return [0, z, [0, y0, 0]];}, + _eR_); + }, + _bD_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _bE_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _bD_], + _bF_ = caml_call1(UIML_Datatypes[2], _bE_), + _bG_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _bH_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _bG_], + _bI_ = caml_call1(UIML_Datatypes[1], _bH_), + _bJ_ = [0, caml_call1(UIML_Datatypes[3], UU0393_0)], + _bK_ = + caml_call3(UIML_KS_termination_prelims[14], _bJ_, [1, a, b], _bI_), + _bL_ = caml_call1(UIML_Datatypes[3], UU0393_0), + _bM_ = caml_call2(UIML_KS_termination_prelims[15], _bL_, _bK_), + _bN_ = [0, b, caml_call1(UIML_Datatypes[2], _bM_)], + _bO_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _bP_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _bO_], + _bQ_ = caml_call1(UIML_Datatypes[1], _bP_), + _bR_ = [0, caml_call1(UIML_Datatypes[3], UU0393_0)], + _bS_ = + caml_call3(UIML_KS_termination_prelims[14], _bR_, [1, a, b], _bQ_), + _bT_ = caml_call1(UIML_Datatypes[3], UU0393_0), + _bU_ = caml_call2(UIML_KS_termination_prelims[15], _bT_, _bS_), + _bV_ = caml_call1(UIML_Datatypes[1], _bU_), + l1 = [0, [0, caml_call2(UIML_Datatypes[4], _bV_, _bN_), _bF_], 0], + _bW_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _bX_ = caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), + _bY_ = caml_call3(UIML_KS_termination_prelims[13], _bX_, _bW_, a), + _bZ_ = + caml_call2 + (UIML_List[4], + function(y0){ + var _ew_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1); + return [0, + [0, + y0, + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), + _ew_], + 0]], + 0]; + }, + _bY_), + y0 = caml_call1(UIML_KS_termination_prelims[7], _bZ_), + x0 = caml_call3(UIML_KS_termination_prelims[4], f, l1, y0)[2], + s = caml_call2(UIML_CML_Syntax[6], [1, a, b], [1, a, b]); + if(! s) throw caml_maybe_attach_backtrace([0, Assert_failure, _b_], 1); + var + _b0_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _b1_ = + [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), _b0_], + _b2_ = [0, symbol, caml_call2(UIML_GenT[1], _b1_, 0)], + _b3_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _b4_ = + caml_call1 + (x0, + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), + _b3_], + _b2_]), + _b5_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _b6_ = + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), + _b5_], + 0], + _b7_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]), + _b8_ = + [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _b7_], + _b6_], + _b9_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _b__ = caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), + _b$_ = caml_call3(UIML_KS_termination_prelims[13], _b__, _b9_, a), + _ca_ = + caml_call2 + (UIML_List[4], + function(y0){ + var _ev_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1); + return [0, + [0, + y0, + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), + _ev_], + 0]], + 0]; + }, + _b$_), + _cb_ = caml_call1(UIML_KS_termination_prelims[7], _ca_), + _cc_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _cd_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _cc_], + _ce_ = caml_call1(UIML_Datatypes[2], _cd_), + _cf_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _cg_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _cf_], + _ch_ = caml_call1(UIML_Datatypes[1], _cg_), + _ci_ = [0, caml_call1(UIML_Datatypes[3], UU0393_0)], + _cj_ = + caml_call3(UIML_KS_termination_prelims[14], _ci_, [1, a, b], _ch_), + _ck_ = caml_call1(UIML_Datatypes[3], UU0393_0), + _cl_ = caml_call2(UIML_KS_termination_prelims[15], _ck_, _cj_), + _cm_ = [0, b, caml_call1(UIML_Datatypes[2], _cl_)], + _cn_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _co_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _cn_], + _cp_ = caml_call1(UIML_Datatypes[1], _co_), + _cq_ = [0, caml_call1(UIML_Datatypes[3], UU0393_0)], + _cr_ = + caml_call3(UIML_KS_termination_prelims[14], _cq_, [1, a, b], _cp_), + _cs_ = caml_call1(UIML_Datatypes[3], UU0393_0), + _ct_ = caml_call2(UIML_KS_termination_prelims[15], _cs_, _cr_), + _cu_ = caml_call1(UIML_Datatypes[1], _ct_), + _cv_ = [0, [0, caml_call2(UIML_Datatypes[4], _cu_, _cm_), _ce_], 0], + _cw_ = + caml_call2 + (UIML_List[4], + function(y0){ + var + _ea_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _eb_ = + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _ea_], + _ec_ = caml_call1(UIML_Datatypes[2], _eb_), + _ed_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _ee_ = + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _ed_], + _ef_ = caml_call1(UIML_Datatypes[1], _ee_), + _eg_ = [0, caml_call1(UIML_Datatypes[3], UU0393_0)], + _eh_ = + caml_call3 + (UIML_KS_termination_prelims[14], _eg_, [1, a, b], _ef_), + _ei_ = caml_call1(UIML_Datatypes[3], UU0393_0), + _ej_ = caml_call2(UIML_KS_termination_prelims[15], _ei_, _eh_), + _ek_ = caml_call1(UIML_Datatypes[2], _ej_), + _el_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _em_ = + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _el_], + _en_ = caml_call1(UIML_Datatypes[1], _em_), + _eo_ = [0, caml_call1(UIML_Datatypes[3], UU0393_0)], + _ep_ = + caml_call3 + (UIML_KS_termination_prelims[14], _eo_, [1, a, b], _en_), + _eq_ = caml_call1(UIML_Datatypes[3], UU0393_0), + _er_ = caml_call2(UIML_KS_termination_prelims[15], _eq_, _ep_), + _es_ = caml_call1(UIML_Datatypes[1], _er_), + _et_ = caml_call2(UIML_Datatypes[4], _es_, _ek_), + _eu_ = + caml_call3(UIML_KS_termination_prelims[13], _et_, _ec_, a); + return caml_call2 + (UIML_List[4], + function(z){return [0, z, [0, y0, 0]];}, + _eu_); + }, + _cv_), + _cx_ = + [0, + caml_call5 + (UIML_KS_termination_prelims[9], _cw_, _cb_, _b8_, i, _b4_)], + _cy_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _cz_ = + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), + _cy_], + 0], + _cA_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]), + prems_Imp_L0 = + function(l1, s){ + var l1$0 = l1; + for(;;){ + if(! l1$0) return 0; + var l1$1 = l1$0[2], p = l1$0[1], n1 = p[2], c = p[1]; + if(n1){ + var m2 = n1[1]; + if(typeof c !== "number" && 1 === c[0]){ + var + b0 = c[2], + a0 = c[1], + _dO_ = prems_Imp_L0(l1$1, s), + _dP_ = caml_call1(UIML_Datatypes[2], s), + _dQ_ = caml_call1(UIML_Datatypes[1], s), + _dR_ = + caml_call3(UIML_KS_termination_prelims[14], [0, m2], c, _dQ_), + _dS_ = caml_call2(UIML_KS_termination_prelims[15], m2, _dR_), + _dT_ = [0, b0, caml_call1(UIML_Datatypes[2], _dS_)], + _dU_ = caml_call1(UIML_Datatypes[1], s), + _dV_ = + caml_call3(UIML_KS_termination_prelims[14], [0, m2], c, _dU_), + _dW_ = caml_call2(UIML_KS_termination_prelims[15], m2, _dV_), + _dX_ = caml_call1(UIML_Datatypes[1], _dW_), + _dY_ = + [0, [0, caml_call2(UIML_Datatypes[4], _dX_, _dT_), _dP_], 0], + _dZ_ = + caml_call2 + (UIML_List[4], + function(y0){ + var + _d1_ = caml_call1(UIML_Datatypes[2], s), + _d2_ = caml_call1(UIML_Datatypes[1], s), + _d3_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, m2], c, _d2_), + _d4_ = caml_call2(UIML_KS_termination_prelims[15], m2, _d3_), + _d5_ = caml_call1(UIML_Datatypes[2], _d4_), + _d6_ = caml_call1(UIML_Datatypes[1], s), + _d7_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, m2], c, _d6_), + _d8_ = caml_call2(UIML_KS_termination_prelims[15], m2, _d7_), + _d9_ = caml_call1(UIML_Datatypes[1], _d8_), + _d__ = caml_call2(UIML_Datatypes[4], _d9_, _d5_), + _d$_ = + caml_call3(UIML_KS_termination_prelims[13], _d__, _d1_, a0); + return caml_call2 + (UIML_List[4], + function(z){return [0, z, [0, y0, 0]];}, + _d$_); + }, + _dY_), + _d0_ = caml_call1(UIML_KS_termination_prelims[7], _dZ_); + return caml_call2(UIML_Datatypes[4], _d0_, _dO_); + } + l1$0 = l1$1; + } + else + l1$0 = l1$1; + } + }, + _cB_ = + [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _cA_], + _cz_], + _cC_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _cD_ = + prems_Imp_L0 + (l0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _cC_]), + _cE_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _cF_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _cE_], + _cG_ = caml_call1(UIML_Datatypes[2], _cF_), + _cH_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _cI_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _cH_], + _cJ_ = caml_call1(UIML_Datatypes[1], _cI_), + _cK_ = [0, caml_call1(UIML_Datatypes[3], UU0393_0)], + _cL_ = + caml_call3(UIML_KS_termination_prelims[14], _cK_, [1, a, b], _cJ_), + _cM_ = caml_call1(UIML_Datatypes[3], UU0393_0), + _cN_ = caml_call2(UIML_KS_termination_prelims[15], _cM_, _cL_), + _cO_ = [0, b, caml_call1(UIML_Datatypes[2], _cN_)], + _cP_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _cQ_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _cP_], + _cR_ = caml_call1(UIML_Datatypes[1], _cQ_), + _cS_ = [0, caml_call1(UIML_Datatypes[3], UU0393_0)], + _cT_ = + caml_call3(UIML_KS_termination_prelims[14], _cS_, [1, a, b], _cR_), + _cU_ = caml_call1(UIML_Datatypes[3], UU0393_0), + _cV_ = caml_call2(UIML_KS_termination_prelims[15], _cU_, _cT_), + _cW_ = caml_call1(UIML_Datatypes[1], _cV_), + _cX_ = [0, [0, caml_call2(UIML_Datatypes[4], _cW_, _cO_), _cG_], 0], + _cY_ = + caml_call2 + (UIML_List[4], + function(y0){ + var + _dt_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _du_ = + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _dt_], + _dv_ = caml_call1(UIML_Datatypes[2], _du_), + _dw_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _dx_ = + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _dw_], + _dy_ = caml_call1(UIML_Datatypes[1], _dx_), + _dz_ = [0, caml_call1(UIML_Datatypes[3], UU0393_0)], + _dA_ = + caml_call3 + (UIML_KS_termination_prelims[14], _dz_, [1, a, b], _dy_), + _dB_ = caml_call1(UIML_Datatypes[3], UU0393_0), + _dC_ = caml_call2(UIML_KS_termination_prelims[15], _dB_, _dA_), + _dD_ = caml_call1(UIML_Datatypes[2], _dC_), + _dE_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _dF_ = + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _dE_], + _dG_ = caml_call1(UIML_Datatypes[1], _dF_), + _dH_ = [0, caml_call1(UIML_Datatypes[3], UU0393_0)], + _dI_ = + caml_call3 + (UIML_KS_termination_prelims[14], _dH_, [1, a, b], _dG_), + _dJ_ = caml_call1(UIML_Datatypes[3], UU0393_0), + _dK_ = caml_call2(UIML_KS_termination_prelims[15], _dJ_, _dI_), + _dL_ = caml_call1(UIML_Datatypes[1], _dK_), + _dM_ = caml_call2(UIML_Datatypes[4], _dL_, _dD_), + _dN_ = + caml_call3(UIML_KS_termination_prelims[13], _dM_, _dv_, a); + return caml_call2 + (UIML_List[4], + function(z){return [0, z, [0, y0, 0]];}, + _dN_); + }, + _cX_), + _cZ_ = caml_call1(UIML_KS_termination_prelims[7], _cY_); + return caml_call4(UIML_List_lemmasT[2], _cZ_, _cD_, _cB_, _cx_); + } + var + i$0 = + coq_ImpL_help02 + (UU0393_0, + UU0393_1, + UU0394_0, + UU0394_1, + a, + b, + l0, + caml_call1(UIML_Datatypes[3], UU0393_0), + x); + if(! n0) return i$0; + var + n1 = n0[1], + _c1_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _c2_ = + [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), _c1_], + 0], + _c3_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]), + _c4_ = + [0, + [0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _c3_], + _c2_], + _c5_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _c6_ = + prems_Imp_L + (l0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _c5_]), + _c0_ = [1, i$0], + _c7_ = 0, + _c8_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1); + if(n1){ + var + match = + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]); + if(match) + var + tl = match[2], + b0 = match[1], + _c9_ = + [0, + b0, + caml_call3(UIML_KS_termination_prelims[14], n1, [1, m0, m1], tl)]; + else + var _c9_ = 0; + var _c__ = _c9_; + } + else{ + var + match$2 = + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]); + if(match$2) + var + tl$4 = match$2[2], + b0$2 = match$2[1], + tl$5 = + caml_call2(UIML_CML_Syntax[6], [1, m0, m1], b0$2) + ? tl$4 + : [0, b0$2, tl$4], + tl$6 = tl$5; + else + var tl$6 = 0; + var _c__ = tl$6; + } + var + _c$_ = caml_call2(UIML_KS_termination_prelims[15], n1, _c__), + _da_ = caml_call1(UIML_Datatypes[2], _c$_); + if(n1){ + var + match$0 = + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]); + if(match$0) + var + tl$0 = match$0[2], + b0$0 = match$0[1], + _db_ = + [0, + b0$0, + caml_call3(UIML_KS_termination_prelims[14], n1, [1, m0, m1], tl$0)]; + else + var _db_ = 0; + var _dc_ = _db_; + } + else{ + var + match$1 = + caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]); + if(match$1) + var + tl$1 = match$1[2], + b0$1 = match$1[1], + tl$2 = + caml_call2(UIML_CML_Syntax[6], [1, m0, m1], b0$1) + ? tl$1 + : [0, b0$1, tl$1], + tl$3 = tl$2; + else + var tl$3 = 0; + var _dc_ = tl$3; + } + var + _dd_ = caml_call2(UIML_KS_termination_prelims[15], n1, _dc_), + _de_ = caml_call1(UIML_Datatypes[1], _dd_), + _df_ = caml_call2(UIML_Datatypes[4], _de_, _da_), + _dg_ = caml_call3(UIML_KS_termination_prelims[13], _df_, _c8_, m0), + _dh_ = + caml_call2 + (UIML_List[4], + function(z){ + var + _dj_ = 0, + _dk_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1); + if(n1){ + var + match = + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]); + if(match) + var + tl = match[2], + b0 = match[1], + _dl_ = + [0, + b0, + caml_call3 + (UIML_KS_termination_prelims[14], n1, [1, m0, m1], tl)]; + else + var _dl_ = 0; + var _dm_ = _dl_; + } + else{ + var + match$2 = + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]); + if(match$2) + var + tl$4 = match$2[2], + b0$2 = match$2[1], + tl$5 = + caml_call2(UIML_CML_Syntax[6], [1, m0, m1], b0$2) + ? tl$4 + : [0, b0$2, tl$4], + tl$6 = tl$5; + else + var tl$6 = 0; + var _dm_ = tl$6; + } + var + _dn_ = caml_call2(UIML_KS_termination_prelims[15], n1, _dm_), + _do_ = [0, m1, caml_call1(UIML_Datatypes[2], _dn_)]; + if(n1){ + var + match$0 = + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]); + if(match$0) + var + tl$0 = match$0[2], + b0$0 = match$0[1], + _dp_ = + [0, + b0$0, + caml_call3 + (UIML_KS_termination_prelims[14], n1, [1, m0, m1], tl$0)]; + else + var _dp_ = 0; + var _dq_ = _dp_; + } + else{ + var + match$1 = + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]); + if(match$1) + var + tl$1 = match$1[2], + b0$1 = match$1[1], + tl$2 = + caml_call2(UIML_CML_Syntax[6], [1, m0, m1], b0$1) + ? tl$1 + : [0, b0$1, tl$1], + tl$3 = tl$2; + else + var tl$3 = 0; + var _dq_ = tl$3; + } + var + _dr_ = caml_call2(UIML_KS_termination_prelims[15], n1, _dq_), + _ds_ = caml_call1(UIML_Datatypes[1], _dr_); + return [0, + z, + [0, + [0, caml_call2(UIML_Datatypes[4], _ds_, _do_), _dk_], + _dj_]]; + }, + _dg_), + _di_ = caml_call2(UIML_Datatypes[4], _dh_, _c7_); + return caml_call4(UIML_List_lemmasT[2], _di_, _c6_, _c4_, _c0_); + } + var + _bC_ = [0, caml_call1(UIML_Datatypes[3], UU0393_0)], + h1 = + caml_call3 + (UIML_KS_termination_prelims[3], + [1, a, b], + _bC_, + [0, [0, m, n0], l0]); + if(0 === h1[0]) + throw caml_maybe_attach_backtrace([0, Assert_failure, _a_], 1); + var n$1 = caml_call1(UIML_Datatypes[3], UU0393_0); + l$0 = l0; + n$0 = n$1; + } + } + function coq_ImpL_help2(param, _bz_, _by_, x){ + var + UU0394_1 = x[6], + UU0394_0 = x[5], + UU0393_1 = x[4], + UU0393_0 = x[3], + b = x[2], + a = x[1], + _bA_ = caml_call1(UIML_Datatypes[3], UU0393_0), + _bB_ = caml_call2(UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]); + return coq_ImpL_help02 + (UU0393_0, + UU0393_1, + UU0394_0, + UU0394_1, + a, + b, + caml_call1(UIML_KS_termination_prelims[5], _bB_), + _bA_, + x); + } + function coq_ImpL_help01(prems, s, l1){ + var l0 = s[2], l = s[1]; + function f(l2, x){ + if(! l2) throw caml_maybe_attach_backtrace([0, Assert_failure, _e_], 1); + var l3 = l2[2], y = l2[1], n = y[2], m = y[1]; + if(typeof m !== "number" && 1 === m[0]){ + var m1 = m[2], m0 = m[1]; + if(! n){ + var + s0$1 = f(l3, x), + s1$1 = s0$1[2], + x0$1 = s0$1[1], + s2$1 = s1$1[2], + x1$2 = s1$1[1], + s3$1 = s2$1[2], + x2$2 = s2$1[1], + s4$1 = s3$1[2], + x3$2 = s3$1[1], + s5$1 = s4$1[2], + x4$2 = s4$1[1], + s6$1 = s5$1[2], + x5$2 = s5$1[1], + s7$1 = s6$1[2], + x6$2 = s6$1[1], + s8$1 = s7$1[2], + x7$2 = s7$1[1], + x8$2 = s8$1[1]; + return [0, + x0$1, + [0, + x1$2, + [0, + x2$2, + [0, + x3$2, + [0, + x4$2, + [0, x5$2, [0, x6$2, [0, x7$2, [0, x8$2, symbol]]]]]]]]]; + } + var + n0 = n[1], + prems_Imp_L0 = + function(l4, s0){ + var l4$0 = l4; + for(;;){ + if(! l4$0) return 0; + var l4$1 = l4$0[2], p = l4$0[1], n1 = p[2], c = p[1]; + if(n1){ + var m2 = n1[1]; + if(typeof c !== "number" && 1 === c[0]){ + var + b = c[2], + a = c[1], + _ba_ = prems_Imp_L0(l4$1, s0), + _bb_ = caml_call1(UIML_Datatypes[2], s0), + _bc_ = caml_call1(UIML_Datatypes[1], s0), + _bd_ = + caml_call3(UIML_KS_termination_prelims[14], [0, m2], c, _bc_), + _be_ = caml_call2(UIML_KS_termination_prelims[15], m2, _bd_), + _bf_ = [0, b, caml_call1(UIML_Datatypes[2], _be_)], + _bg_ = caml_call1(UIML_Datatypes[1], s0), + _bh_ = + caml_call3(UIML_KS_termination_prelims[14], [0, m2], c, _bg_), + _bi_ = caml_call2(UIML_KS_termination_prelims[15], m2, _bh_), + _bj_ = caml_call1(UIML_Datatypes[1], _bi_), + _bk_ = + [0, [0, caml_call2(UIML_Datatypes[4], _bj_, _bf_), _bb_], 0], + _bl_ = + caml_call2 + (UIML_List[4], + function(y0){ + var + _bn_ = caml_call1(UIML_Datatypes[2], s0), + _bo_ = caml_call1(UIML_Datatypes[1], s0), + _bp_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, m2], c, _bo_), + _bq_ = caml_call2(UIML_KS_termination_prelims[15], m2, _bp_), + _br_ = caml_call1(UIML_Datatypes[2], _bq_), + _bs_ = caml_call1(UIML_Datatypes[1], s0), + _bt_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, m2], c, _bs_), + _bu_ = caml_call2(UIML_KS_termination_prelims[15], m2, _bt_), + _bv_ = caml_call1(UIML_Datatypes[1], _bu_), + _bw_ = caml_call2(UIML_Datatypes[4], _bv_, _br_), + _bx_ = + caml_call3(UIML_KS_termination_prelims[13], _bw_, _bn_, a); + return caml_call2 + (UIML_List[4], + function(z){return [0, z, [0, y0, 0]];}, + _bx_); + }, + _bk_), + _bm_ = caml_call1(UIML_KS_termination_prelims[7], _bl_); + return caml_call2(UIML_Datatypes[4], _bm_, _ba_); + } + l4$0 = l4$1; + } + else + l4$0 = l4$1; + } + }, + _v_ = prems_Imp_L0(l3, [0, l, l0]), + _w_ = caml_call1(UIML_Datatypes[2], [0, l, l0]), + _x_ = caml_call1(UIML_Datatypes[1], [0, l, l0]), + _y_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], _x_), + _z_ = caml_call2(UIML_KS_termination_prelims[15], n0, _y_), + _A_ = [0, m1, caml_call1(UIML_Datatypes[2], _z_)], + _B_ = caml_call1(UIML_Datatypes[1], [0, l, l0]), + _C_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], _B_), + _D_ = caml_call2(UIML_KS_termination_prelims[15], n0, _C_), + _E_ = caml_call1(UIML_Datatypes[1], _D_), + _F_ = [0, [0, caml_call2(UIML_Datatypes[4], _E_, _A_), _w_], 0], + _G_ = + caml_call2 + (UIML_List[4], + function(y0){ + var + _a1_ = caml_call1(UIML_Datatypes[2], [0, l, l0]), + _a2_ = caml_call1(UIML_Datatypes[1], [0, l, l0]), + _a3_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], _a2_), + _a4_ = caml_call2(UIML_KS_termination_prelims[15], n0, _a3_), + _a5_ = caml_call1(UIML_Datatypes[2], _a4_), + _a6_ = caml_call1(UIML_Datatypes[1], [0, l, l0]), + _a7_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], _a6_), + _a8_ = caml_call2(UIML_KS_termination_prelims[15], n0, _a7_), + _a9_ = caml_call1(UIML_Datatypes[1], _a8_), + _a__ = caml_call2(UIML_Datatypes[4], _a9_, _a5_), + _a$_ = + caml_call3(UIML_KS_termination_prelims[13], _a__, _a1_, m0); + return caml_call2 + (UIML_List[4], + function(z){return [0, z, [0, y0, 0]];}, + _a$_); + }, + _F_), + _H_ = caml_call1(UIML_KS_termination_prelims[7], _G_), + x0$0 = caml_call4(UIML_List_lemmasT[1], _H_, _v_, prems, x); + if(0 !== x0$0[0]){ + var + i$0 = x0$0[1], + s0$0 = f(l3, i$0), + s1$0 = s0$0[2], + x1$1 = s0$0[1], + s2$0 = s1$0[2], + x2$1 = s1$0[1], + s3$0 = s2$0[2], + x3$1 = s2$0[1], + s4$0 = s3$0[2], + x4$1 = s3$0[1], + s5$0 = s4$0[2], + x5$1 = s4$0[1], + s6$0 = s5$0[2], + x6$1 = s5$0[1], + s7$0 = s6$0[2], + x7$1 = s6$0[1], + s8$0 = s7$0[2], + x8$1 = s7$0[1], + x9 = s8$0[1]; + return [0, + x1$1, + [0, + x2$1, + [0, + x3$1, + [0, + x4$1, + [0, x5$1, [0, x6$1, [0, x7$1, [0, x8$1, [0, x9, symbol]]]]]]]]]; + } + var + i = x0$0[1], + _I_ = + caml_call3(UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], l), + _J_ = caml_call2(UIML_KS_termination_prelims[15], n0, _I_), + _K_ = [0, m1, caml_call1(UIML_Datatypes[2], _J_)], + _L_ = + caml_call3(UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], l), + _M_ = caml_call2(UIML_KS_termination_prelims[15], n0, _L_), + _N_ = caml_call1(UIML_Datatypes[1], _M_), + _O_ = [0, [0, caml_call2(UIML_Datatypes[4], _N_, _K_), l0], 0], + _P_ = + caml_call2 + (UIML_List[4], + function(y0){ + var + _aT_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], l), + _aU_ = caml_call2(UIML_KS_termination_prelims[15], n0, _aT_), + _aV_ = caml_call1(UIML_Datatypes[2], _aU_), + _aW_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], l), + _aX_ = caml_call2(UIML_KS_termination_prelims[15], n0, _aW_), + _aY_ = caml_call1(UIML_Datatypes[1], _aX_), + _aZ_ = caml_call2(UIML_Datatypes[4], _aY_, _aV_), + _a0_ = caml_call3(UIML_KS_termination_prelims[13], _aZ_, l0, m0); + return caml_call2 + (UIML_List[4], + function(z){return [0, z, [0, y0, 0]];}, + _a0_); + }, + _O_), + i0 = caml_call3(UIML_KS_termination_prelims[8], _P_, prems, i), + p = i0[2], + x1$0 = i0[1], + i2 = p[2], + i1 = p[1], + _Q_ = + caml_call3(UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], l), + _R_ = caml_call2(UIML_KS_termination_prelims[15], n0, _Q_), + _S_ = [0, m1, caml_call1(UIML_Datatypes[2], _R_)], + _T_ = + caml_call3(UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], l), + _U_ = caml_call2(UIML_KS_termination_prelims[15], n0, _T_), + _V_ = caml_call1(UIML_Datatypes[1], _U_), + l4 = [0, [0, caml_call2(UIML_Datatypes[4], _V_, _S_), l0], 0], + f0 = + function(y0){ + var + _aL_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], l), + _aM_ = caml_call2(UIML_KS_termination_prelims[15], n0, _aL_), + _aN_ = caml_call1(UIML_Datatypes[2], _aM_), + _aO_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], l), + _aP_ = caml_call2(UIML_KS_termination_prelims[15], n0, _aO_), + _aQ_ = caml_call1(UIML_Datatypes[1], _aP_), + _aR_ = caml_call2(UIML_Datatypes[4], _aQ_, _aN_), + _aS_ = caml_call3(UIML_KS_termination_prelims[13], _aR_, l0, m0); + return caml_call2 + (UIML_List[4], + function(z){return [0, z, [0, y0, 0]];}, + _aS_); + }, + x2$0 = caml_call3(UIML_KS_termination_prelims[4], f0, l4, x1$0)[1], + i3 = caml_call1(x2$0, i2), + p0 = i3[2], + i4 = p0[2]; + if(0 !== i4[0]) + throw caml_maybe_attach_backtrace([0, Assert_failure, _d_], 1); + var + _W_ = + caml_call3(UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], l), + _X_ = caml_call2(UIML_KS_termination_prelims[15], n0, _W_), + _Y_ = caml_call1(UIML_Datatypes[2], _X_), + _Z_ = + caml_call3(UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], l), + ___ = caml_call2(UIML_KS_termination_prelims[15], n0, _Z_), + _$_ = caml_call1(UIML_Datatypes[1], ___), + _aa_ = caml_call2(UIML_Datatypes[4], _$_, _Y_), + l4$0 = caml_call3(UIML_KS_termination_prelims[13], _aa_, l0, m0), + f0$0 = + function(z){ + var _aE_ = 0; + if(n0) + if(l) + var + tl = l[2], + b = l[1], + _aF_ = + [0, + b, + caml_call3 + (UIML_KS_termination_prelims[14], n0, [1, m0, m1], tl)]; + else + var _aF_ = 0; + else if(l) + var + tl$3 = l[2], + b$2 = l[1], + tl$4 = + caml_call2(UIML_CML_Syntax[6], [1, m0, m1], b$2) + ? tl$3 + : [0, b$2, tl$3], + _aF_ = tl$4; + else + var _aF_ = 0; + var + _aG_ = caml_call2(UIML_KS_termination_prelims[15], n0, _aF_), + _aH_ = [0, m1, caml_call1(UIML_Datatypes[2], _aG_)]; + if(n0) + if(l) + var + tl$0 = l[2], + b$0 = l[1], + _aI_ = + [0, + b$0, + caml_call3 + (UIML_KS_termination_prelims[14], n0, [1, m0, m1], tl$0)]; + else + var _aI_ = 0; + else if(l) + var + tl$1 = l[2], + b$1 = l[1], + tl$2 = + caml_call2(UIML_CML_Syntax[6], [1, m0, m1], b$1) + ? tl$1 + : [0, b$1, tl$1], + _aI_ = tl$2; + else + var _aI_ = 0; + var + _aJ_ = caml_call2(UIML_KS_termination_prelims[15], n0, _aI_), + _aK_ = caml_call1(UIML_Datatypes[1], _aJ_); + return [0, + z, + [0, + [0, caml_call2(UIML_Datatypes[4], _aK_, _aH_), l0], + _aE_]]; + }, + x3$0 = caml_call3(UIML_KS_termination_prelims[4], f0$0, l4$0, prems)[1], + i5 = caml_call1(x3$0, i1), + p1 = i5[2], + x4$0 = i5[1], + i6 = p1[2], + l4$1 = caml_call2(UIML_KS_termination_prelims[11], l0, m0), + f0$1 = + function(y0){ + var + _ay_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], l), + _az_ = caml_call2(UIML_KS_termination_prelims[15], n0, _ay_), + _aA_ = caml_call1(UIML_Datatypes[2], _az_), + _aB_ = + caml_call3 + (UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], l), + _aC_ = caml_call2(UIML_KS_termination_prelims[15], n0, _aB_), + _aD_ = caml_call1(UIML_Datatypes[1], _aC_); + return [0, caml_call2(UIML_Datatypes[4], _aD_, _aA_), y0]; + }, + x5$0 = caml_call3(UIML_KS_termination_prelims[4], f0$1, l4$1, x4$0)[1], + i7 = caml_call1(x5$0, i6), + p2 = i7[2], + x6$0 = i7[1], + i8 = p2[2], + _ab_ = caml_call1(UIML_KS_termination_prelims[10], l0), + l4$2 = caml_call1(UIML_KS_termination_prelims[1], _ab_), + f0$2 = + function(y0){ + var + _aw_ = [0, m0, caml_call1(UIML_Datatypes[2], y0)], + _ax_ = caml_call1(UIML_Datatypes[1], y0); + return caml_call2(UIML_Datatypes[4], _ax_, _aw_); + }, + x7$0 = caml_call3(UIML_KS_termination_prelims[4], f0$2, l4$2, x6$0)[1], + i9 = caml_call1(x7$0, i8), + x8$0 = i9[1], + l5 = x8$0[2], + l4$3 = x8$0[1], + _ac_ = + caml_call3(UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], l), + _ad_ = caml_call2(UIML_KS_termination_prelims[15], n0, _ac_), + _ae_ = + [0, caml_call1(UIML_Datatypes[2], _ad_), [0, l4$3, [0, l5, symbol]]], + _af_ = + caml_call3(UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], l), + _ag_ = caml_call2(UIML_KS_termination_prelims[15], n0, _af_), + _ah_ = [0, m0, [0, m1, [0, caml_call1(UIML_Datatypes[1], _ag_), _ae_]]]; + if(n0) + if(l) + var + tl = l[2], + b0 = l[1], + _ai_ = + [0, + b0, + caml_call3(UIML_KS_termination_prelims[14], n0, [1, m0, m1], tl)]; + else + var _ai_ = 0; + else if(l) + var + tl$3 = l[2], + b0$2 = l[1], + tl$4 = + caml_call2(UIML_CML_Syntax[6], [1, m0, m1], b0$2) + ? tl$3 + : [0, b0$2, tl$3], + _ai_ = tl$4; + else + var _ai_ = 0; + var + _aj_ = caml_call2(UIML_KS_termination_prelims[15], n0, _ai_), + _ak_ = [0, m1, caml_call1(UIML_Datatypes[2], _aj_)]; + if(n0) + if(l) + var + tl$0 = l[2], + b0$0 = l[1], + _al_ = + [0, + b0$0, + caml_call3(UIML_KS_termination_prelims[14], n0, [1, m0, m1], tl$0)]; + else + var _al_ = 0; + else if(l) + var + tl$1 = l[2], + b0$1 = l[1], + tl$2 = + caml_call2(UIML_CML_Syntax[6], [1, m0, m1], b0$1) + ? tl$1 + : [0, b0$1, tl$1], + _al_ = tl$2; + else + var _al_ = 0; + var + _am_ = caml_call2(UIML_KS_termination_prelims[15], n0, _al_), + _an_ = caml_call1(UIML_Datatypes[1], _am_), + _ao_ = [0, [0, caml_call2(UIML_Datatypes[4], _an_, _ak_), l0], _ah_], + _ap_ = caml_call2(UIML_Datatypes[4], l4$3, [0, m0, l5]), + _aq_ = + caml_call3(UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], l), + _ar_ = caml_call2(UIML_KS_termination_prelims[15], n0, _aq_), + _as_ = caml_call1(UIML_Datatypes[2], _ar_), + _at_ = + caml_call3(UIML_KS_termination_prelims[14], [0, n0], [1, m0, m1], l), + _au_ = caml_call2(UIML_KS_termination_prelims[15], n0, _at_), + _av_ = caml_call1(UIML_Datatypes[1], _au_); + return [0, + n0, + [0, [0, caml_call2(UIML_Datatypes[4], _av_, _as_), _ap_], _ao_]]; + } + var + s0 = f(l3, x), + s1 = s0[2], + x0 = s0[1], + s2 = s1[2], + x1 = s1[1], + s3 = s2[2], + x2 = s2[1], + s4 = s3[2], + x3 = s3[1], + s5 = s4[2], + x4 = s4[1], + s6 = s5[2], + x5 = s5[1], + s7 = s6[2], + x6 = s6[1], + s8 = s7[2], + x7 = s7[1], + x8 = s8[1]; + return [0, + x0, + [0, + x1, + [0, + x2, + [0, x3, [0, x4, [0, x5, [0, x6, [0, x7, [0, x8, symbol]]]]]]]]]; + } + return function(_u_){return f(l1, _u_);}; + } + function coq_ImpL_help1(prem, s, x){ + var + _k_ = caml_call1(UIML_Datatypes[1], s), + s0 = + coq_ImpL_help01 + (prem, s, caml_call1(UIML_KS_termination_prelims[5], _k_)) + (x), + s1 = s0[2], + x0 = s0[1], + s2 = s1[2], + s3 = s2[2], + s4 = s3[2], + x1 = s3[1], + s5 = s4[2], + x2 = s4[1], + s6 = s5[2], + s7 = s6[2], + s8 = s7[2], + x3 = s7[1], + x4 = s8[1], + l0 = s[2], + l = s[1], + _l_ = caml_call1(UIML_Datatypes[1], [0, l, l0]), + i = caml_call3(UIML_KS_termination_ImpR[2], _l_, [1, x1, x2], x0), + x5 = i[1], + _m_ = [0, caml_call1(UIML_Datatypes[3], x5)], + _n_ = caml_call3(UIML_KS_termination_prelims[14], _m_, [1, x1, x2], l), + _o_ = caml_call1(UIML_Datatypes[3], x5), + _p_ = caml_call2(UIML_KS_termination_prelims[15], _o_, _n_), + UU0393_0 = caml_call1(UIML_Datatypes[1], _p_), + _q_ = [0, caml_call1(UIML_Datatypes[3], x5)], + _r_ = caml_call3(UIML_KS_termination_prelims[14], _q_, [1, x1, x2], l), + _s_ = caml_call1(UIML_Datatypes[3], x5), + _t_ = caml_call2(UIML_KS_termination_prelims[15], _s_, _r_), + UU0393_1 = caml_call1(UIML_Datatypes[2], _t_); + return [0, x1, x2, UU0393_0, UU0393_1, x3, x4]; + } + function finite_ImpL_premises_of_S(param){ + var l0 = param[2], l = param[1]; + return [0, + prems_Imp_L + (caml_call1(UIML_KS_termination_prelims[5], l), [0, l, l0]), + function(prems){ + return [0, + function(h){ + var + UU0394_1 = h[6], + UU0394_0 = h[5], + UU0393_1 = h[4], + UU0393_0 = h[3], + b = h[2], + a = h[1], + _f_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _g_ = + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0, [0, [1, a, b], UU0393_1]), + _f_], + _h_ = caml_call2(UIML_Datatypes[4], UU0394_0, UU0394_1), + _i_ = + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, b, UU0393_1]), + _h_], + _j_ = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, a, UU0394_1]); + return coq_ImpL_help2 + ([0, caml_call2(UIML_Datatypes[4], UU0393_0, UU0393_1), _j_], + _i_, + _g_, + h); + }, + function(h){return coq_ImpL_help1(prems, [0, l, l0], h);}]; + }]; + } + var + UIML_KS_termination_ImpL = + [0, + prems_Imp_L, + coq_ImpL_help002, + coq_ImpL_help02, + coq_ImpL_help2, + coq_ImpL_help01, + coq_ImpL_help1, + finite_ImpL_premises_of_S]; + runtime.caml_register_global + (14, UIML_KS_termination_ImpL, "UIML__KS_termination_ImpL"); + return; + } + (globalThis)); + +//# 6842 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst_extraction_KS_termination_ = "extraction/KS_termination_KR.ml", + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call4(f, a0, a1, a2, a3){ + return (f.l >= 0 ? f.l : f.l = f.length) == 4 + ? f(a0, a1, a2, a3) + : runtime.caml_call_gen(f, [a0, a1, a2, a3]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_Datatypes = global_data.UIML__Datatypes, + UIML_CML_Syntax = global_data.UIML__CML_Syntax, + Assert_failure = global_data.Assert_failure, + UIML_List_lems = global_data.UIML__List_lems, + UIML_GenT = global_data.UIML__GenT, + UIML_List_lemmasT = global_data.UIML__List_lemmasT, + UIML_KS_termination_prelims = global_data.UIML__KS_termination_prelims, + _a_ = [0, cst_extraction_KS_termination_, 31, 10], + _b_ = [0, cst_extraction_KS_termination_, 96, 28], + _c_ = [0, cst_extraction_KS_termination_, 64, 10]; + function symbol(param){return symbol;} + function prems_Box_R(l, s){ + var l$0 = l; + for(;;){ + if(! l$0) return 0; + var t = l$0[2], h = l$0[1]; + if(typeof h !== "number" && 2 === h[0]){ + var + a = h[1], + _p_ = prems_Box_R(t, s), + _q_ = caml_call1(UIML_Datatypes[1], s), + _r_ = caml_call1(UIML_CML_Syntax[9], _q_); + return [0, + [0, [0, caml_call1(UIML_CML_Syntax[8], _r_), [0, a, 0]], 0], + _p_]; + } + l$0 = t; + } + } + function coq_KR_help01(prems, s, l1, x){ + if(! l1) throw caml_maybe_attach_backtrace([0, Assert_failure, _a_], 1); + var l = l1[2], y = l1[1]; + if(typeof y !== "number" && 2 === y[0]){ + var m = y[1]; + if(0 === x[0]) return [0, m, symbol]; + var x0$0 = x[3], h0 = coq_KR_help01(prems, s, l, x0$0), x1$0 = h0[1]; + return [0, x1$0, symbol]; + } + var x0 = coq_KR_help01(prems, s, l, x), x1 = x0[1]; + return [0, x1, symbol]; + } + function coq_KR_help1(prems, s, x){ + var + _n_ = caml_call1(UIML_Datatypes[2], s), + s0 = coq_KR_help01(prems, s, caml_call1(UIML_CML_Syntax[9], _n_), x), + x0 = s0[1], + l0 = s[2], + l = s[1], + h = caml_call2(UIML_List_lems[1], [2, x0], l0), + s1 = h[2], + x1 = h[1], + x2 = s1[1], + _o_ = caml_call1(UIML_KS_termination_prelims[6], l); + return [0, x0, caml_call1(UIML_CML_Syntax[9], l), l, x1, x2, _o_]; + } + function coq_KR_help02(UU0393, UU0394_0, UU0394_1, b_UU0393, a, l, x, x0){ + var l$0 = l; + for(;;){ + if(! l$0) throw caml_maybe_attach_backtrace([0, Assert_failure, _c_], 1); + var l0 = l$0[2], y = l$0[1]; + if(typeof y !== "number" && 2 === y[0]){ + var + m = y[1], + h0$0 = caml_call2(UIML_List_lems[1], [2, a], [0, [2, m], l0]), + s$0 = h0$0[2], + x1 = h0$0[1], + x2$0 = s$0[1], + _h_ = [1, caml_call2(UIML_GenT[1], [2, a], x2$0)], + h1$0 = + caml_call4(UIML_List_lemmasT[2], x1, [0, [2, a], x2$0], [2, a], _h_); + if(0 === h1$0[0]){ + var + _i_ = + prems_Box_R + (l0, + [0, + UU0393, + caml_call2(UIML_Datatypes[4], UU0394_0, [0, [2, a], UU0394_1])]), + _j_ = caml_call1(UIML_CML_Syntax[9], UU0393), + _k_ = [0, [0, caml_call1(UIML_CML_Syntax[8], _j_), [0, a, 0]], 0]; + return caml_call2(UIML_GenT[1], _k_, _i_); + } + var + i = coq_KR_help02(UU0393, UU0394_0, UU0394_1, b_UU0393, a, l0, x, x0), + _l_ = + prems_Box_R + (l0, + [0, + UU0393, + caml_call2(UIML_Datatypes[4], UU0394_0, [0, [2, a], UU0394_1])]), + _m_ = caml_call1(UIML_CML_Syntax[9], UU0393); + return [1, + [0, [0, caml_call1(UIML_CML_Syntax[8], _m_), [0, m, 0]], 0], + _l_, + i]; + } + var + h0 = caml_call2(UIML_List_lems[1], [2, a], [0, y, l0]), + s = h0[2], + x2 = h0[1], + x3 = s[1], + _g_ = [1, caml_call2(UIML_GenT[1], [2, a], x3)], + h1 = caml_call4(UIML_List_lemmasT[2], x2, [0, [2, a], x3], [2, a], _g_); + if(0 === h1[0]) + throw caml_maybe_attach_backtrace([0, Assert_failure, _b_], 1); + l$0 = l0; + } + } + function coq_KR_help2(param, _e_, x){ + var + x0 = x[6], + UU0394_1 = x[5], + UU0394_0 = x[4], + UU0393_0 = x[3], + b_UU0393 = x[2], + a = x[1], + _f_ = caml_call2(UIML_Datatypes[4], UU0394_0, [0, [2, a], UU0394_1]); + return coq_KR_help02 + (UU0393_0, + UU0394_0, + UU0394_1, + b_UU0393, + a, + caml_call1(UIML_CML_Syntax[9], _f_), + x, + x0); + } + function finite_KR_premises_of_S(param){ + var l0 = param[2], l = param[1]; + return [0, + prems_Box_R(caml_call1(UIML_CML_Syntax[9], l0), [0, l, l0]), + function(prems){ + return [0, + function(x){ + var + UU0394_1 = x[5], + UU0394_0 = x[4], + b_UU0393 = x[2], + a = x[1], + _d_ = + [0, + l, + caml_call2 + (UIML_Datatypes[4], UU0394_0, [0, [2, a], UU0394_1])]; + return coq_KR_help2 + ([0, caml_call1(UIML_CML_Syntax[8], b_UU0393), [0, a, 0]], + _d_, + x); + }, + function(h){return coq_KR_help1(prems, [0, l, l0], h);}]; + }]; + } + var + UIML_KS_termination_KR = + [0, + prems_Box_R, + coq_KR_help01, + coq_KR_help1, + coq_KR_help02, + coq_KR_help2, + finite_KR_premises_of_S]; + runtime.caml_register_global + (10, UIML_KS_termination_KR, "UIML__KS_termination_KR"); + return; + } + (globalThis)); + +//# 7044 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_Datatypes = global_data.UIML__Datatypes, + UIML_Environments = global_data.UIML__Environments, + UIML_Formulas = global_data.UIML__Formulas, + UIML_Base = global_data.UIML__Base, + UIML_List = global_data.UIML__List, + UIML_List0 = global_data.UIML__List0, + _a_ = [3, 0, 0], + _b_ = [3, 0, 0], + _c_ = [3, 0, 0], + _d_ = [3, 0, 0]; + function symbol(param){return symbol;} + function e_rule(p, UU0394, UU03d5, eA0, UU03b8){ + function e(UU0394_0){ + var _ai_ = caml_call2(eA0, [0, UU0394_0, UU03d5], symbol); + return caml_call1(UIML_Datatypes[1], _ai_); + } + function a(pe0){ + var _ah_ = caml_call2(eA0, pe0, symbol); + return caml_call1(UIML_Datatypes[2], _ah_); + } + var UU0394$0 = caml_call2(UIML_Environments[13], UU03b8, UU0394); + if(typeof UU03b8 === "number") return 0; + switch(UU03b8[0]){ + case 0: + var + q = UU03b8[1], + _U_ = caml_call3(UIML_Base[2], UIML_Formulas[3], p, q); + return caml_call1(UIML_Base[1], _U_) ? _a_ : [0, q]; + case 1: + var UU03b4_UU2082 = UU03b8[2], UU03b4_UU2081 = UU03b8[1]; + return e([0, UU03b4_UU2082, [0, UU03b4_UU2081, UU0394$0]]); + case 2: + var + UU03b4_UU2082$0 = UU03b8[2], + UU03b4_UU2081$0 = UU03b8[1], + _V_ = e([0, UU03b4_UU2082$0, UU0394$0]), + _W_ = e([0, UU03b4_UU2081$0, UU0394$0]); + return caml_call2(UIML_Environments[7], _W_, _V_); + case 3: + var UU03b4_2 = UU03b8[2], f = UU03b8[1]; + if(typeof f === "number") return _b_; + switch(f[0]){ + case 0: + var + q$0 = f[1], + _X_ = caml_call1(UIML_List0[2], UIML_Formulas[4]), + _Y_ = caml_call3(UIML_Base[2], _X_, [0, q$0], UU0394); + if(caml_call1(UIML_Base[1], _Y_)) return e([0, UU03b4_2, UU0394$0]); + var _Z_ = caml_call3(UIML_Base[2], UIML_Formulas[3], p, q$0); + if(caml_call1(UIML_Base[1], _Z_)) return _c_; + var ___ = e([0, UU03b4_2, UU0394$0]); + return caml_call2(UIML_Environments[8], [0, q$0], ___); + case 1: + var UU03b4_UU2082$1 = f[2], UU03b4_UU2081$1 = f[1]; + return e + ([0, + [3, UU03b4_UU2081$1, [3, UU03b4_UU2082$1, UU03b4_2]], + UU0394$0]); + case 2: + var UU03b4_UU2082$2 = f[2], UU03b4_UU2081$2 = f[1]; + return e + ([0, + [3, UU03b4_UU2082$2, UU03b4_2], + [0, [3, UU03b4_UU2081$2, UU03b4_2], UU0394$0]]); + case 3: + var + UU03b4_UU2082$3 = f[2], + UU03b4_UU2081$3 = f[1], + _$_ = e([0, UU03b4_2, UU0394$0]), + _aa_ = + a + ([0, + [0, + UU03b4_UU2081$3, + [0, [3, UU03b4_UU2082$3, UU03b4_2], UU0394$0]], + UU03b4_UU2082$3]), + _ab_ = + e + ([0, + UU03b4_UU2081$3, + [0, [3, UU03b4_UU2082$3, UU03b4_2], UU0394$0]]), + _ac_ = caml_call2(UIML_Environments[8], _ab_, _aa_); + return caml_call2(UIML_Environments[8], _ac_, _$_); + default: + var + UU03b4_1 = f[1], + _ad_ = e([0, UU03b4_2, UU0394$0]), + _ae_ = + a + ([0, + [0, + [4, UU03b4_1], + [0, + UU03b4_2, + caml_call2(UIML_List[4], UIML_Environments[14], UU0394$0)]], + UU03b4_1]), + _af_ = + e + ([0, + [4, UU03b4_1], + [0, + UU03b4_2, + caml_call2(UIML_List[4], UIML_Environments[14], UU0394$0)]]), + _ag_ = [4, caml_call2(UIML_Environments[8], _af_, _ae_)]; + return caml_call2(UIML_Environments[8], _ag_, _ad_); + } + default: + var UU03c6 = UU03b8[1]; + return [4, + e + ([0, + UU03c6, + caml_call2(UIML_List[4], UIML_Environments[14], UU0394$0)])]; + } + } + function a_rule_env(p, UU0394, UU03d5, eA0, UU03b8){ + function e(UU0394_0){ + var _T_ = caml_call2(eA0, [0, UU0394_0, UU03d5], symbol); + return caml_call1(UIML_Datatypes[1], _T_); + } + function a(pe0){ + var _S_ = caml_call2(eA0, pe0, symbol); + return caml_call1(UIML_Datatypes[2], _S_); + } + var UU0394$0 = caml_call2(UIML_Environments[13], UU03b8, UU0394); + if(typeof UU03b8 !== "number") + switch(UU03b8[0]){ + case 0: + var + q = UU03b8[1], + _z_ = caml_call3(UIML_Base[2], UIML_Formulas[3], p, q); + if(! caml_call1(UIML_Base[1], _z_)) return 0; + var _A_ = caml_call3(UIML_Base[2], UIML_Formulas[4], [0, p], UU03d5); + return caml_call1(UIML_Base[1], _A_) ? _d_ : 0; + case 1: + var UU03b4_UU2082 = UU03b8[2], UU03b4_UU2081 = UU03b8[1]; + return a + ([0, [0, UU03b4_UU2082, [0, UU03b4_UU2081, UU0394$0]], UU03d5]); + case 2: + var + UU03b4_UU2082$0 = UU03b8[2], + UU03b4_UU2081$0 = UU03b8[1], + _B_ = a([0, [0, UU03b4_UU2082$0, UU0394$0], UU03d5]), + _C_ = e([0, UU03b4_UU2082$0, UU0394$0]), + _D_ = caml_call2(UIML_Environments[8], _C_, _B_), + _E_ = a([0, [0, UU03b4_UU2081$0, UU0394$0], UU03d5]), + _F_ = e([0, UU03b4_UU2081$0, UU0394$0]), + _G_ = caml_call2(UIML_Environments[8], _F_, _E_); + return caml_call2(UIML_Environments[5], _G_, _D_); + case 3: + var UU03b4_2 = UU03b8[2], f = UU03b8[1]; + if(typeof f === "number") return 0; + switch(f[0]){ + case 0: + var + q$0 = f[1], + _H_ = caml_call1(UIML_List0[2], UIML_Formulas[4]), + _I_ = caml_call3(UIML_Base[2], _H_, [0, q$0], UU0394); + if(caml_call1(UIML_Base[1], _I_)) + return a([0, [0, UU03b4_2, UU0394$0], UU03d5]); + var _J_ = caml_call3(UIML_Base[2], UIML_Formulas[3], p, q$0); + if(caml_call1(UIML_Base[1], _J_)) return 0; + var _K_ = a([0, [0, UU03b4_2, UU0394$0], UU03d5]); + return caml_call2(UIML_Environments[5], [0, q$0], _K_); + case 1: + var UU03b4_UU2082$1 = f[2], UU03b4_UU2081$1 = f[1]; + return a + ([0, + [0, + [3, UU03b4_UU2081$1, [3, UU03b4_UU2082$1, UU03b4_2]], + UU0394$0], + UU03d5]); + case 2: + var UU03b4_UU2082$2 = f[2], UU03b4_UU2081$2 = f[1]; + return a + ([0, + [0, + [3, UU03b4_UU2082$2, UU03b4_2], + [0, [3, UU03b4_UU2081$2, UU03b4_2], UU0394$0]], + UU03d5]); + case 3: + var + UU03b4_UU2082$3 = f[2], + UU03b4_UU2081$3 = f[1], + _L_ = a([0, [0, UU03b4_2, UU0394$0], UU03d5]), + _M_ = + a + ([0, + [0, + UU03b4_UU2081$3, + [0, [3, UU03b4_UU2082$3, UU03b4_2], UU0394$0]], + UU03b4_UU2082$3]), + _N_ = + e + ([0, + UU03b4_UU2081$3, + [0, [3, UU03b4_UU2082$3, UU03b4_2], UU0394$0]]), + _O_ = caml_call2(UIML_Environments[8], _N_, _M_); + return caml_call2(UIML_Environments[5], _O_, _L_); + default: + var + UU03b4_1 = f[1], + _P_ = a([0, [0, UU03b4_2, UU0394$0], UU03d5]), + _Q_ = + a + ([0, + [0, + [4, UU03b4_1], + [0, + UU03b4_2, + caml_call2(UIML_List[4], UIML_Environments[14], UU0394$0)]], + UU03b4_1]), + _R_ = + e + ([0, + [4, UU03b4_1], + [0, + UU03b4_2, + caml_call2(UIML_List[4], UIML_Environments[14], UU0394$0)]]); + return [1, [4, caml_call2(UIML_Environments[8], _R_, _Q_)], _P_]; + } + } + return 0; + } + function a_rule_form(p, UU0394, UU03d5, eA0){ + function e(pe0){ + var _y_ = caml_call2(eA0, pe0, symbol); + return caml_call1(UIML_Datatypes[1], _y_); + } + function a(pe0){ + var _x_ = caml_call2(eA0, pe0, symbol); + return caml_call1(UIML_Datatypes[2], _x_); + } + if(typeof UU03d5 === "number") return 0; + switch(UU03d5[0]){ + case 0: + var + q = UU03d5[1], + _o_ = caml_call3(UIML_Base[2], UIML_Formulas[3], p, q); + return caml_call1(UIML_Base[1], _o_) ? 0 : [0, q]; + case 1: + var + UU03d5_UU2082 = UU03d5[2], + UU03d5_UU2081 = UU03d5[1], + _p_ = a([0, UU0394, UU03d5_UU2082]), + _q_ = a([0, UU0394, UU03d5_UU2081]); + return caml_call2(UIML_Environments[5], _q_, _p_); + case 2: + var + UU03d5_UU2082$0 = UU03d5[2], + UU03d5_UU2081$0 = UU03d5[1], + _r_ = a([0, UU0394, UU03d5_UU2082$0]), + _s_ = a([0, UU0394, UU03d5_UU2081$0]); + return caml_call2(UIML_Environments[7], _s_, _r_); + case 3: + var + UU03d5_UU2082$1 = UU03d5[2], + UU03d5_UU2081$1 = UU03d5[1], + _t_ = a([0, [0, UU03d5_UU2081$1, UU0394], UU03d5_UU2082$1]), + _u_ = e([0, [0, UU03d5_UU2081$1, UU0394], UU03d5_UU2082$1]); + return caml_call2(UIML_Environments[8], _u_, _t_); + default: + var + UU03b4 = UU03d5[1], + _v_ = + a + ([0, + [0, + [4, UU03b4], + caml_call2(UIML_List[4], UIML_Environments[14], UU0394)], + UU03b4]), + _w_ = + e + ([0, + [0, + [4, UU03b4], + caml_call2(UIML_List[4], UIML_Environments[14], UU0394)], + UU03b4]); + return [4, caml_call2(UIML_Environments[8], _w_, _v_)]; + } + } + function coq_EA(p, x){ + var + UU0394 = caml_call1(UIML_Datatypes[1], x), + _g_ = caml_call1(UIML_Datatypes[2], x), + _h_ = + a_rule_form + (p, + caml_call1(UIML_Datatypes[1], x), + _g_, + function(pe, param){return coq_EA(p, pe);}), + _i_ = + caml_call2 + (UIML_Environments[12], + UU0394, + function(x0, param){ + var _n_ = caml_call1(UIML_Datatypes[2], x); + return a_rule_env + (p, + caml_call1(UIML_Datatypes[1], x), + _n_, + function(pe, param){return coq_EA(p, pe);}, + x0); + }), + _j_ = caml_call1(UIML_Environments[10], _i_), + _k_ = caml_call2(UIML_Environments[7], _j_, _h_), + _l_ = + caml_call2 + (UIML_Environments[12], + UU0394, + function(x0, param){ + var _m_ = caml_call1(UIML_Datatypes[2], x); + return e_rule + (p, + caml_call1(UIML_Datatypes[1], x), + _m_, + function(pe, param){return coq_EA(p, pe);}, + x0); + }); + return [0, caml_call1(UIML_Environments[9], _l_), _k_]; + } + function coq_E(p, pe){ + var _f_ = coq_EA(p, pe); + return caml_call1(UIML_Datatypes[1], _f_); + } + function coq_A(p, pe){ + var _e_ = coq_EA(p, pe); + return caml_call1(UIML_Datatypes[2], _e_); + } + function coq_Ef(p, UU03c8){return coq_E(p, [0, [0, UU03c8, 0], 0]);} + function coq_Af(p, UU03c8){return coq_A(p, [0, 0, UU03c8]);} + var + UIML_PropQuantifiers = + [0, + e_rule, + a_rule_env, + a_rule_form, + coq_EA, + coq_E, + coq_A, + coq_Ef, + coq_Af]; + runtime.caml_register_global + (10, UIML_PropQuantifiers, "UIML__PropQuantifiers"); + return; + } + (globalThis)); + +//# 7415 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_Environments = global_data.UIML__Environments, + UIML_PropQuantifiers = global_data.UIML__PropQuantifiers, + UIML_Formulas = global_data.UIML__Formulas, + UIML_Base = global_data.UIML__Base, + UIML_Numbers = global_data.UIML__Numbers; + function simp_ors(UU03c6, UU03c8){ + if(typeof UU03c6 !== "number" && 2 === UU03c6[0]){ + var UU03c6_2 = UU03c6[2], UU03c6_1 = UU03c6[1]; + if(typeof UU03c8 !== "number" && 2 === UU03c8[0]){ + var + UU03c8_2$0 = UU03c8[2], + UU03c8_1$0 = UU03c8[1], + _u_ = simp_ors(UU03c6_2, UU03c8_2$0), + _v_ = caml_call2(UIML_Environments[7], UU03c8_1$0, _u_); + return caml_call2(UIML_Environments[7], UU03c6_1, _v_); + } + return caml_call2(UIML_Environments[7], UU03c8, [2, UU03c6_1, UU03c6_2]); + } + if(typeof UU03c8 !== "number" && 2 === UU03c8[0]){ + var UU03c8_2 = UU03c8[2], UU03c8_1 = UU03c8[1]; + return caml_call2(UIML_Environments[7], UU03c6, [2, UU03c8_1, UU03c8_2]); + } + return caml_call2(UIML_Environments[7], UU03c6, UU03c8); + } + function simp_ands(UU03c6, UU03c8){ + if(typeof UU03c6 !== "number" && 1 === UU03c6[0]){ + var UU03c6_2 = UU03c6[2], UU03c6_1 = UU03c6[1]; + if(typeof UU03c8 !== "number" && 1 === UU03c8[0]){ + var + UU03c8_2$0 = UU03c8[2], + UU03c8_1$0 = UU03c8[1], + _s_ = simp_ands(UU03c6_2, UU03c8_2$0), + _t_ = caml_call2(UIML_Environments[5], UU03c8_1$0, _s_); + return caml_call2(UIML_Environments[5], UU03c6_1, _t_); + } + return caml_call2(UIML_Environments[5], UU03c8, [1, UU03c6_1, UU03c6_2]); + } + if(typeof UU03c8 !== "number" && 1 === UU03c8[0]){ + var UU03c8_2 = UU03c8[2], UU03c8_1 = UU03c8[1]; + return caml_call2(UIML_Environments[5], UU03c6, [1, UU03c8_1, UU03c8_2]); + } + return caml_call2(UIML_Environments[5], UU03c6, UU03c8); + } + function simp_imp(UU03c6, UU03c8){ + var + _e_ = caml_call2(UIML_Environments[3], UU03c6, UU03c8), + _f_ = caml_call3(UIML_Base[2], UIML_Numbers[1], _e_, 1); + if(caml_call1(UIML_Base[1], _f_)) + return caml_call1(UIML_Base[3], UIML_Formulas[2]); + var + _g_ = caml_call1(UIML_Base[4], UIML_Formulas[1]), + _h_ = caml_call2(UIML_Environments[3], UU03c6, _g_), + _i_ = caml_call3(UIML_Base[2], UIML_Numbers[1], _h_, 1); + if(caml_call1(UIML_Base[1], _i_)) + return caml_call1(UIML_Base[3], UIML_Formulas[2]); + var + _j_ = caml_call1(UIML_Base[3], UIML_Formulas[2]), + _k_ = caml_call2(UIML_Environments[3], UU03c8, _j_), + _l_ = caml_call3(UIML_Base[2], UIML_Numbers[1], _k_, 2); + if(caml_call1(UIML_Base[1], _l_)) + return caml_call1(UIML_Base[3], UIML_Formulas[2]); + var + _m_ = caml_call1(UIML_Base[3], UIML_Formulas[2]), + _n_ = caml_call2(UIML_Environments[3], UU03c6, _m_), + _o_ = caml_call3(UIML_Base[2], UIML_Numbers[1], _n_, 2); + if(caml_call1(UIML_Base[1], _o_)) return UU03c8; + var + _p_ = caml_call1(UIML_Base[4], UIML_Formulas[1]), + _q_ = caml_call2(UIML_Environments[3], UU03c8, _p_), + _r_ = caml_call3(UIML_Base[2], UIML_Numbers[1], _q_, 1); + return caml_call1(UIML_Base[1], _r_) + ? [3, UU03c6, 0] + : [3, UU03c6, UU03c8]; + } + function simp_imps(UU03c6, UU03c8){ + var UU03c6$0 = UU03c6, UU03c8$0 = UU03c8; + for(;;){ + if(typeof UU03c8$0 !== "number" && 3 === UU03c8$0[0]){ + var + UU03c8_2 = UU03c8$0[2], + UU03c8_1 = UU03c8$0[1], + UU03c6$1 = simp_ands(UU03c6$0, UU03c8_1); + UU03c6$0 = UU03c6$1; + UU03c8$0 = UU03c8_2; + continue; + } + return simp_imp(UU03c6$0, UU03c8$0); + } + } + function simp(UU03c6){ + if(typeof UU03c6 !== "number") + switch(UU03c6[0]){ + case 1: + var UU03c8 = UU03c6[2], UU03c6_0 = UU03c6[1], _b_ = simp(UU03c8); + return simp_ands(simp(UU03c6_0), _b_); + case 2: + var + UU03c8$0 = UU03c6[2], + UU03c6_0$0 = UU03c6[1], + _c_ = simp(UU03c8$0); + return simp_ors(simp(UU03c6_0$0), _c_); + case 3: + var + UU03c8$1 = UU03c6[2], + UU03c6_0$1 = UU03c6[1], + _d_ = simp(UU03c8$1); + return simp_imps(simp(UU03c6_0$1), _d_); + case 4: + var UU03c6_0$2 = UU03c6[1]; return [4, simp(UU03c6_0$2)]; + } + return UU03c6; + } + function coq_E_simplified(p, UU03c8){ + var _a_ = [0, [0, UU03c8, 0], caml_call1(UIML_Base[4], UIML_Formulas[1])]; + return simp(caml_call2(UIML_PropQuantifiers[5], p, _a_)); + } + function coq_A_simplified(p, UU03c8){ + return simp(caml_call2(UIML_PropQuantifiers[8], p, UU03c8)); + } + var + UIML_Simp = + [0, + simp_ors, + simp_ands, + simp_imp, + simp_imps, + simp, + coq_E_simplified, + coq_A_simplified]; + runtime.caml_register_global(5, UIML_Simp, "UIML__Simp"); + return; + } + (globalThis)); + +//# 7572 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_Datatypes = global_data.UIML__Datatypes; + function symbol(param){return symbol;} + function list_is_nil(param){return param ? 0 : 1;} + function flatmap(f, param){ + if(! param) return 0; + var + l0 = param[2], + x = param[1], + _a_ = flatmap(f, l0), + _b_ = caml_call2(f, x, symbol); + return caml_call2(UIML_Datatypes[4], _b_, _a_); + } + function irred(f, x){ + return list_is_nil(caml_call1(f, x)) + ? [0, x, 0] + : flatmap + (function(y, param){return irred(f, y);}, caml_call1(f, x)); + } + var UIML_UIGL_irred_short = [0, list_is_nil, flatmap, irred]; + runtime.caml_register_global + (1, UIML_UIGL_irred_short, "UIML__UIGL_irred_short"); + return; + } + (globalThis)); + +//# 7615 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call4(f, a0, a1, a2, a3){ + return (f.l >= 0 ? f.l : f.l = f.length) == 4 + ? f(a0, a1, a2, a3) + : runtime.caml_call_gen(f, [a0, a1, a2, a3]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_Datatypes = global_data.UIML__Datatypes, + UIML_GLS_der_dec = global_data.UIML__GLS_der_dec, + UIML_List_lemmasT = global_data.UIML__List_lemmasT, + UIML_UIGL_irred_short = global_data.UIML__UIGL_irred_short; + function symbol(param){return symbol;} + function finite_ImpRules_premises_of_S(s){ + var + s0 = caml_call1(UIML_GLS_der_dec[23], s), + p = s0[2], + x = s0[1], + s1 = caml_call1(UIML_GLS_der_dec[30], s), + p0 = s1[2], + x0 = s1[1]; + return [0, + caml_call2(UIML_Datatypes[4], x, x0), + function(prems){ + return [0, + function(h){ + if(0 === h[0]){ + var + i = h[1], + UU0394_1 = i[6], + UU0394_0 = i[5], + UU0393_1 = i[4], + UU0393_0 = i[3], + b = i[2], + a = i[1], + _c_ = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, b, UU0394_1]), + prems0 = + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), + _c_], + 0], + x1 = caml_call1(p, prems0)[1], + _d_ = + [0, + caml_call1 + (x1, [0, a, b, UU0393_0, UU0393_1, UU0394_0, UU0394_1])], + _e_ = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, b, UU0394_1]), + _f_ = + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), + _e_], + 0]; + return caml_call4(UIML_List_lemmasT[2], x, x0, _f_, _d_); + } + var + i$0 = h[1], + UU0394_1$0 = i$0[6], + UU0394_0$0 = i$0[5], + UU0393_1$0 = i$0[4], + UU0393_0$0 = i$0[3], + b$0 = i$0[2], + a$0 = i$0[1], + _g_ = caml_call2(UIML_Datatypes[4], UU0394_0$0, UU0394_1$0), + _h_ = + [0, + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0$0, [0, b$0, UU0393_1$0]), + _g_], + 0], + _i_ = + caml_call2 + (UIML_Datatypes[4], UU0394_0$0, [0, a$0, UU0394_1$0]), + prems0$0 = + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0$0, UU0393_1$0), + _i_], + _h_], + x1$0 = caml_call1(p0, prems0$0)[1], + _j_ = + [1, + caml_call1 + (x1$0, + [0, + a$0, + b$0, + UU0393_0$0, + UU0393_1$0, + UU0394_0$0, + UU0394_1$0])], + _k_ = caml_call2(UIML_Datatypes[4], UU0394_0$0, UU0394_1$0), + _l_ = + [0, + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0$0, [0, b$0, UU0393_1$0]), + _k_], + 0], + _m_ = + caml_call2 + (UIML_Datatypes[4], UU0394_0$0, [0, a$0, UU0394_1$0]), + _n_ = + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0$0, UU0393_1$0), + _m_], + _l_]; + return caml_call4(UIML_List_lemmasT[2], x, x0, _n_, _j_); + }, + function(h){ + var h0 = caml_call4(UIML_List_lemmasT[1], x, x0, prems, h); + if(0 === h0[0]){ + var i = h0[1], x1 = caml_call1(p, prems)[2]; + return [0, caml_call1(x1, i)]; + } + var i$0 = h0[1], x1$0 = caml_call1(p0, prems)[2]; + return [1, caml_call1(x1$0, i$0)]; + }]; + }]; + } + function inv_prems(s){ + var + _a_ = finite_ImpRules_premises_of_S(s), + _b_ = caml_call1(UIML_GLS_der_dec[1], _a_); + return caml_call1(UIML_GLS_der_dec[7], _b_); + } + var coq_Canopy = caml_call1(UIML_UIGL_irred_short[3], inv_prems); + function is_Prime_dec(param){ + if(! param) return [0, symbol]; + var l0 = param[2], y = param[1]; + if(0 !== is_Prime_dec(l0)[0]) return [1, symbol]; + if(typeof y !== "number" && 1 === y[0]) return [1, symbol]; + return [0, symbol]; + } + function critical_Seq_dec(param){ + var l0 = param[2], l = param[1]; + return is_Prime_dec(caml_call2(UIML_Datatypes[4], l, l0)); + } + var + UIML_UIGL_Canopy = + [0, + finite_ImpRules_premises_of_S, + inv_prems, + coq_Canopy, + is_Prime_dec, + critical_Seq_dec]; + runtime.caml_register_global(4, UIML_UIGL_Canopy, "UIML__UIGL_Canopy"); + return; + } + (globalThis)); + +//# 7786 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_GLS_der_dec = global_data.UIML__GLS_der_dec; + function symbol(param){return symbol;} + function coq_GLR_prems(s){ + var + _a_ = caml_call1(UIML_GLS_der_dec[36], s), + _b_ = caml_call1(UIML_GLS_der_dec[1], _a_); + return caml_call1(UIML_GLS_der_dec[7], _b_); + } + function coq_LexSeq_ind(x, s){ + return caml_call2 + (x, s, function(s1, param){return coq_LexSeq_ind(x, s1);}); + } + function empty_seq_dec(param){ + var l0 = param[2], l = param[1]; + return l ? [1, symbol] : l0 ? [1, symbol] : [0, symbol]; + } + var UIML_UIGL_LexSeq = [0, coq_GLR_prems, coq_LexSeq_ind, empty_seq_dec]; + runtime.caml_register_global(1, UIML_UIGL_LexSeq, "UIML__UIGL_LexSeq"); + return; + } + (globalThis)); + +//# 7826 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_CML_Syntax = global_data.UIML__CML_Syntax, + UIML_Datatypes = global_data.UIML__Datatypes, + UIML_List = global_data.UIML__List; + function list_conj(param){ + if(! param) return UIML_CML_Syntax[1]; + var t = param[2], h = param[1], _e_ = list_conj(t); + return caml_call2(UIML_CML_Syntax[3], h, _e_); + } + function list_disj(param){ + if(! param) return 0; + var t = param[2], h = param[1], _d_ = list_disj(t); + return caml_call2(UIML_CML_Syntax[4], h, _d_); + } + function list_prop_F(param){ + if(typeof param !== "number" && 0 === param[0]){var p = param[1]; return [0, [0, p], 0];} + return 0; + } + function list_prop_LF(param){ + if(! param) return 0; + var + t = param[2], + h = param[1], + _b_ = list_prop_LF(t), + _c_ = list_prop_F(h); + return caml_call2(UIML_Datatypes[4], _c_, _b_); + } + function restr_list_prop(p, l){ + var _a_ = list_prop_LF(l); + return caml_call3(UIML_List[2], UIML_CML_Syntax[6], [0, p], _a_); + } + var + UIML_UIGL_basics = + [0, list_conj, list_disj, list_prop_F, list_prop_LF, restr_list_prop]; + runtime.caml_register_global(3, UIML_UIGL_basics, "UIML__UIGL_basics"); + return; + } + (globalThis)); + +//# 7882 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_Datatypes = global_data.UIML__Datatypes, + UIML_CML_Syntax = global_data.UIML__CML_Syntax, + UIML_List = global_data.UIML__List; + function nodupseq(s){ + var + _a_ = caml_call1(UIML_Datatypes[2], s), + _b_ = caml_call2(UIML_List[5], UIML_CML_Syntax[6], _a_), + _c_ = caml_call1(UIML_Datatypes[1], s); + return [0, caml_call2(UIML_List[5], UIML_CML_Syntax[6], _c_), _b_]; + } + var UIML_UIGL_nodupseq = [0, nodupseq]; + runtime.caml_register_global(3, UIML_UIGL_nodupseq, "UIML__UIGL_nodupseq"); + return; + } + (globalThis)); + +//# 7916 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_UIGL_nodupseq = global_data.UIML__UIGL_nodupseq, + UIML_UIGL_Canopy = global_data.UIML__UIGL_Canopy, + UIML_Datatypes = global_data.UIML__Datatypes, + UIML_CML_Syntax = global_data.UIML__CML_Syntax, + UIML_GLS_calcs = global_data.UIML__GLS_calcs, + UIML_UIGL_LexSeq = global_data.UIML__UIGL_LexSeq, + UIML_GLS_dec = global_data.UIML__GLS_dec, + UIML_GLS_termination_measure = global_data.UIML__GLS_termination_measure, + UIML_Compare_dec = global_data.UIML__Compare_dec, + UIML_List = global_data.UIML__List, + UIML_UIGL_basics = global_data.UIML__UIGL_basics; + function symbol(param){return symbol;} + function imap(f, param){ + if(! param) return 0; + var l0 = param[2], x = param[1], _I_ = imap(f, l0); + return [0, caml_call2(f, x, symbol), _I_]; + } + function coq_GUI_tot(p){ + return caml_call1 + (UIML_UIGL_LexSeq[2], + function(s, iH){ + var s0 = caml_call1(UIML_UIGL_LexSeq[3], s); + if(0 === s0[0]) return 0; + var s1 = caml_call1(UIML_UIGL_Canopy[5], s); + if(0 !== s1[0]){ + var + _s_ = caml_call1(UIML_UIGL_nodupseq[1], s), + s3 = + imap + (function(x, param){return caml_call2(iH, x, symbol);}, + caml_call1(UIML_UIGL_Canopy[3], _s_)); + return caml_call1(UIML_UIGL_basics[1], s3); + } + var s2 = caml_call1(UIML_GLS_dec[4], s); + if(0 === s2[0]) return UIML_CML_Syntax[1]; + var + _a_ = caml_call1(UIML_UIGL_nodupseq[1], s), + s4 = + imap + (function(x, param){return caml_call2(iH, x, symbol);}, + caml_call1(UIML_UIGL_LexSeq[1], _a_)), + _b_ = caml_call1(UIML_Datatypes[1], s), + _c_ = caml_call1(UIML_CML_Syntax[9], _b_), + _d_ = [0, caml_call1(UIML_GLS_calcs[1], _c_), 0], + _e_ = caml_call1(UIML_UIGL_nodupseq[1], _d_), + s6 = + imap + (function(z, param){ + var s5 = caml_call1(UIML_GLS_dec[4], z); + if(0 === s5[0]) return UIML_CML_Syntax[1]; + var + _t_ = caml_call1(UIML_GLS_termination_measure[4], s), + _u_ = caml_call1(UIML_Datatypes[3], _t_), + _v_ = caml_call1(UIML_GLS_termination_measure[4], z), + _w_ = caml_call1(UIML_Datatypes[3], _v_), + s6 = caml_call2(UIML_Compare_dec[4], _w_, _u_); + if(s6) return caml_call2(iH, z, symbol); + var + _x_ = caml_call1(UIML_UIGL_nodupseq[1], z), + s8 = + imap + (function(x0, param){return caml_call2(iH, x0, symbol);}, + caml_call1(UIML_UIGL_LexSeq[1], _x_)), + _y_ = + caml_call2(UIML_List[4], function(x){return [2, x];}, s8), + _z_ = caml_call1(UIML_UIGL_basics[2], _y_), + _A_ = caml_call1(UIML_Datatypes[1], z), + _B_ = caml_call2(UIML_UIGL_basics[5], p, _A_), + _C_ = caml_call2(UIML_List[4], UIML_CML_Syntax[2], _B_), + _D_ = caml_call1(UIML_UIGL_basics[2], _C_), + _E_ = caml_call2(UIML_CML_Syntax[4], _D_, _z_), + _F_ = caml_call1(UIML_Datatypes[2], z), + _G_ = caml_call2(UIML_UIGL_basics[5], p, _F_), + _H_ = caml_call1(UIML_UIGL_basics[2], _G_); + return caml_call2(UIML_CML_Syntax[4], _H_, _E_); + }, + caml_call1(UIML_UIGL_Canopy[3], _e_)), + _f_ = caml_call1(UIML_UIGL_basics[1], s6), + _g_ = caml_call1(UIML_CML_Syntax[5], _f_), + _h_ = caml_call2(UIML_List[4], function(x){return [2, x];}, s4), + _i_ = caml_call1(UIML_UIGL_basics[2], _h_), + _j_ = caml_call2(UIML_CML_Syntax[4], _i_, _g_), + _k_ = caml_call1(UIML_Datatypes[1], s), + _l_ = caml_call2(UIML_UIGL_basics[5], p, _k_), + _m_ = caml_call2(UIML_List[4], UIML_CML_Syntax[2], _l_), + _n_ = caml_call1(UIML_UIGL_basics[2], _m_), + _o_ = caml_call2(UIML_CML_Syntax[4], _n_, _j_), + _p_ = caml_call1(UIML_Datatypes[2], s), + _q_ = caml_call2(UIML_UIGL_basics[5], p, _p_), + _r_ = caml_call1(UIML_UIGL_basics[2], _q_); + return caml_call2(UIML_CML_Syntax[4], _r_, _o_); + }); + } + var UIML_UIGL_braga = [0, imap, coq_GUI_tot]; + runtime.caml_register_global(11, UIML_UIGL_braga, "UIML__UIGL_braga"); + return; + } + (globalThis)); + +//# 8033 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_Datatypes = global_data.UIML__Datatypes; + function symbol(param){return symbol;} + function list_is_nil(param){return param ? 0 : 1;} + function flatmap(f, param){ + if(! param) return 0; + var + l0 = param[2], + x = param[1], + _a_ = flatmap(f, l0), + _b_ = caml_call2(f, x, symbol); + return caml_call2(UIML_Datatypes[4], _b_, _a_); + } + function irred(f, x){ + return list_is_nil(caml_call1(f, x)) + ? [0, x, 0] + : flatmap + (function(y, param){return irred(f, y);}, caml_call1(f, x)); + } + var UIML_UIK_irred_short = [0, list_is_nil, flatmap, irred]; + runtime.caml_register_global + (1, UIML_UIK_irred_short, "UIML__UIK_irred_short"); + return; + } + (globalThis)); + +//# 8076 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call4(f, a0, a1, a2, a3){ + return (f.l >= 0 ? f.l : f.l = f.length) == 4 + ? f(a0, a1, a2, a3) + : runtime.caml_call_gen(f, [a0, a1, a2, a3]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_Datatypes = global_data.UIML__Datatypes, + UIML_KS_termination_prelims = global_data.UIML__KS_termination_prelims, + UIML_List_lemmasT = global_data.UIML__List_lemmasT, + UIML_KS_termination_ImpR = global_data.UIML__KS_termination_ImpR, + UIML_KS_termination_ImpL = global_data.UIML__KS_termination_ImpL, + UIML_UIK_irred_short = global_data.UIML__UIK_irred_short; + function symbol(param){return symbol;} + function finite_ImpRules_premises_of_S(s){ + var + s0 = caml_call1(UIML_KS_termination_ImpR[8], s), + p = s0[2], + x = s0[1], + s1 = caml_call1(UIML_KS_termination_ImpL[7], s), + p0 = s1[2], + x0 = s1[1]; + return [0, + caml_call2(UIML_Datatypes[4], x, x0), + function(prems){ + return [0, + function(h){ + if(0 === h[0]){ + var + i = h[1], + UU0394_1 = i[6], + UU0394_0 = i[5], + UU0393_1 = i[4], + UU0393_0 = i[3], + b = i[2], + a = i[1], + _c_ = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, b, UU0394_1]), + prems0 = + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), + _c_], + 0], + x1 = caml_call1(p, prems0)[1], + _d_ = + [0, + caml_call1 + (x1, [0, a, b, UU0393_0, UU0393_1, UU0394_0, UU0394_1])], + _e_ = + caml_call2(UIML_Datatypes[4], UU0394_0, [0, b, UU0394_1]), + _f_ = + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0, [0, a, UU0393_1]), + _e_], + 0]; + return caml_call4(UIML_List_lemmasT[2], x, x0, _f_, _d_); + } + var + i$0 = h[1], + UU0394_1$0 = i$0[6], + UU0394_0$0 = i$0[5], + UU0393_1$0 = i$0[4], + UU0393_0$0 = i$0[3], + b$0 = i$0[2], + a$0 = i$0[1], + _g_ = caml_call2(UIML_Datatypes[4], UU0394_0$0, UU0394_1$0), + _h_ = + [0, + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0$0, [0, b$0, UU0393_1$0]), + _g_], + 0], + _i_ = + caml_call2 + (UIML_Datatypes[4], UU0394_0$0, [0, a$0, UU0394_1$0]), + prems0$0 = + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0$0, UU0393_1$0), + _i_], + _h_], + x1$0 = caml_call1(p0, prems0$0)[1], + _j_ = + [1, + caml_call1 + (x1$0, + [0, + a$0, + b$0, + UU0393_0$0, + UU0393_1$0, + UU0394_0$0, + UU0394_1$0])], + _k_ = caml_call2(UIML_Datatypes[4], UU0394_0$0, UU0394_1$0), + _l_ = + [0, + [0, + caml_call2 + (UIML_Datatypes[4], UU0393_0$0, [0, b$0, UU0393_1$0]), + _k_], + 0], + _m_ = + caml_call2 + (UIML_Datatypes[4], UU0394_0$0, [0, a$0, UU0394_1$0]), + _n_ = + [0, + [0, + caml_call2(UIML_Datatypes[4], UU0393_0$0, UU0393_1$0), + _m_], + _l_]; + return caml_call4(UIML_List_lemmasT[2], x, x0, _n_, _j_); + }, + function(h){ + var h0 = caml_call4(UIML_List_lemmasT[1], x, x0, prems, h); + if(0 === h0[0]){ + var i = h0[1], x1 = caml_call1(p, prems)[2]; + return [0, caml_call1(x1, i)]; + } + var i$0 = h0[1], x1$0 = caml_call1(p0, prems)[2]; + return [1, caml_call1(x1$0, i$0)]; + }]; + }]; + } + function inv_prems(s){ + var + _a_ = finite_ImpRules_premises_of_S(s), + _b_ = caml_call1(UIML_KS_termination_prelims[1], _a_); + return caml_call1(UIML_KS_termination_prelims[7], _b_); + } + var coq_Canopy = caml_call1(UIML_UIK_irred_short[3], inv_prems); + function is_Prime_dec(param){ + if(! param) return [0, symbol]; + var l0 = param[2], y = param[1]; + if(0 !== is_Prime_dec(l0)[0]) return [1, symbol]; + if(typeof y !== "number" && 1 === y[0]) return [1, symbol]; + return [0, symbol]; + } + function critical_Seq_dec(param){ + var l0 = param[2], l = param[1]; + return is_Prime_dec(caml_call2(UIML_Datatypes[4], l, l0)); + } + var + UIML_UIK_Canopy = + [0, + finite_ImpRules_premises_of_S, + inv_prems, + coq_Canopy, + is_Prime_dec, + critical_Seq_dec]; + runtime.caml_register_global(6, UIML_UIK_Canopy, "UIML__UIK_Canopy"); + return; + } + (globalThis)); + +//# 8249 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_CML_Syntax = global_data.UIML__CML_Syntax, + UIML_Datatypes = global_data.UIML__Datatypes, + UIML_KS_termination_KR = global_data.UIML__KS_termination_KR, + UIML_KS_termination_prelims = global_data.UIML__KS_termination_prelims, + UIML_List = global_data.UIML__List; + function symbol(param){return symbol;} + function list_conj(param){ + if(! param) return UIML_CML_Syntax[1]; + var t = param[2], h = param[1], _g_ = list_conj(t); + return caml_call2(UIML_CML_Syntax[3], h, _g_); + } + function list_disj(param){ + if(! param) return 0; + var t = param[2], h = param[1], _f_ = list_disj(t); + return caml_call2(UIML_CML_Syntax[4], h, _f_); + } + function list_prop_F(param){ + if(typeof param !== "number" && 0 === param[0]){var p = param[1]; return [0, [0, p], 0];} + return 0; + } + function list_prop_LF(param){ + if(! param) return 0; + var + t = param[2], + h = param[1], + _d_ = list_prop_LF(t), + _e_ = list_prop_F(h); + return caml_call2(UIML_Datatypes[4], _e_, _d_); + } + function restr_list_prop(p, l){ + var _c_ = list_prop_LF(l); + return caml_call3(UIML_List[2], UIML_CML_Syntax[6], [0, p], _c_); + } + function coq_KR_prems(s){ + var + _a_ = caml_call1(UIML_KS_termination_KR[6], s), + _b_ = caml_call1(UIML_KS_termination_prelims[1], _a_); + return caml_call1(UIML_KS_termination_prelims[7], _b_); + } + function coq_LtSeq_ind(x, s){ + return caml_call2(x, s, function(s1, param){return coq_LtSeq_ind(x, s1);}); + } + function empty_seq_dec(param){ + var l0 = param[2], l = param[1]; + return l ? [1, symbol] : l0 ? [1, symbol] : [0, symbol]; + } + var + UIML_UIK_basics = + [0, + list_conj, + list_disj, + list_prop_F, + list_prop_LF, + restr_list_prop, + coq_KR_prems, + coq_LtSeq_ind, + empty_seq_dec]; + runtime.caml_register_global(5, UIML_UIK_basics, "UIML__UIK_basics"); + return; + } + (globalThis)); + +//# 8334 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_UIK_Canopy = global_data.UIML__UIK_Canopy, + UIML_UIK_basics = global_data.UIML__UIK_basics, + UIML_KS_dec = global_data.UIML__KS_dec, + UIML_CML_Syntax = global_data.UIML__CML_Syntax, + UIML_Datatypes = global_data.UIML__Datatypes, + UIML_List_lems = global_data.UIML__List_lems, + UIML_List = global_data.UIML__List; + function symbol(param){return symbol;} + function imap(f, param){ + if(! param) return 0; + var l0 = param[2], x = param[1], _B_ = imap(f, l0); + return [0, caml_call2(f, x, symbol), _B_]; + } + function coq_GUI_tot(p){ + return caml_call1 + (UIML_UIK_basics[7], + function(s, iH){ + var s0 = caml_call1(UIML_UIK_basics[8], s); + if(0 === s0[0]) return 0; + var s1 = caml_call1(UIML_UIK_Canopy[5], s); + if(0 !== s1[0]){ + var + s3 = + imap + (function(x, param){return caml_call2(iH, x, symbol);}, + caml_call1(UIML_UIK_Canopy[3], s)); + return caml_call1(UIML_UIK_basics[1], s3); + } + var s2 = caml_call1(UIML_KS_dec[3], s); + if(0 === s2[0]) return UIML_CML_Syntax[1]; + var + s4 = + imap + (function(x, param){return caml_call2(iH, x, symbol);}, + caml_call1(UIML_UIK_basics[6], s)), + _a_ = caml_call1(UIML_Datatypes[1], s), + s5 = caml_call2(UIML_List_lems[2], _a_, 0); + if(s5){ + var + _b_ = caml_call1(UIML_CML_Syntax[5], 0), + _c_ = + caml_call2(UIML_List[4], function(x){return [2, x];}, s4), + _d_ = caml_call1(UIML_UIK_basics[2], _c_), + _e_ = caml_call2(UIML_CML_Syntax[4], _d_, _b_), + _f_ = caml_call1(UIML_Datatypes[1], s), + _g_ = caml_call2(UIML_UIK_basics[5], p, _f_), + _h_ = caml_call2(UIML_List[4], UIML_CML_Syntax[2], _g_), + _i_ = caml_call1(UIML_UIK_basics[2], _h_), + _j_ = caml_call2(UIML_CML_Syntax[4], _i_, _e_), + _k_ = caml_call1(UIML_Datatypes[2], s), + _l_ = caml_call2(UIML_UIK_basics[5], p, _k_), + _m_ = caml_call1(UIML_UIK_basics[2], _l_); + return caml_call2(UIML_CML_Syntax[4], _m_, _j_); + } + var + _n_ = caml_call1(UIML_Datatypes[1], s), + _o_ = caml_call1(UIML_CML_Syntax[9], _n_), + j10 = + caml_call2 + (iH, [0, caml_call1(UIML_CML_Syntax[8], _o_), 0], symbol), + _p_ = caml_call1(UIML_CML_Syntax[5], j10), + _q_ = caml_call2(UIML_List[4], function(x){return [2, x];}, s4), + _r_ = caml_call1(UIML_UIK_basics[2], _q_), + _s_ = caml_call2(UIML_CML_Syntax[4], _r_, _p_), + _t_ = caml_call1(UIML_Datatypes[1], s), + _u_ = caml_call2(UIML_UIK_basics[5], p, _t_), + _v_ = caml_call2(UIML_List[4], UIML_CML_Syntax[2], _u_), + _w_ = caml_call1(UIML_UIK_basics[2], _v_), + _x_ = caml_call2(UIML_CML_Syntax[4], _w_, _s_), + _y_ = caml_call1(UIML_Datatypes[2], s), + _z_ = caml_call2(UIML_UIK_basics[5], p, _y_), + _A_ = caml_call1(UIML_UIK_basics[2], _z_); + return caml_call2(UIML_CML_Syntax[4], _A_, _x_); + }); + } + var UIML_UIK_braga = [0, imap, coq_GUI_tot]; + runtime.caml_register_global(7, UIML_UIK_braga, "UIML__UIK_braga"); + return; + } + (globalThis)); + +//# 8433 "../extraction/.UIML.objs/jsoo/default/UIML.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + var + global_data = runtime.caml_get_global_data(), + UIML_UIK_braga = global_data.UIML__UIK_braga, + UIML_UIGL_braga = global_data.UIML__UIGL_braga, + UIML_PropQuantifiers = global_data.UIML__PropQuantifiers, + UIML_Simp = global_data.UIML__Simp; + function coq_MPropF_of_form(param){ + if(typeof param === "number") return 0; + switch(param[0]){ + case 0: + var n = param[1]; return [0, n]; + case 1: + var f2 = param[2], f1 = param[1], _d_ = [1, coq_MPropF_of_form(f2), 0]; + return [1, [1, coq_MPropF_of_form(f1), _d_], 0]; + case 2: + var f2$0 = param[2], f1$0 = param[1], _e_ = coq_MPropF_of_form(f2$0); + return [1, [1, coq_MPropF_of_form(f1$0), 0], _e_]; + case 3: + var f2$1 = param[2], f1$1 = param[1], _f_ = coq_MPropF_of_form(f2$1); + return [1, coq_MPropF_of_form(f1$1), _f_]; + default: var f0 = param[1]; return [2, coq_MPropF_of_form(f0)]; + } + } + function form_of_MPropF(param){ + if(typeof param === "number") return 0; + switch(param[0]){ + case 0: + var n = param[1]; return [0, n]; + case 1: + var f2 = param[2], f1 = param[1], _c_ = form_of_MPropF(f2); + return [3, form_of_MPropF(f1), _c_]; + default: var f0 = param[1]; return [4, form_of_MPropF(f0)]; + } + } + function gl_UI(p, s){ + var _b_ = [0, 0, [0, coq_MPropF_of_form(s), 0]]; + return form_of_MPropF(caml_call2(UIML_UIGL_braga[2], p, _b_)); + } + function k_UI(p, s){ + var _a_ = [0, 0, [0, coq_MPropF_of_form(s), 0]]; + return form_of_MPropF(caml_call2(UIML_UIK_braga[2], p, _a_)); + } + var + isl_E = UIML_PropQuantifiers[7], + isl_A = UIML_PropQuantifiers[8], + isl_simp = UIML_Simp[5], + isl_simplified_E = UIML_Simp[6], + isl_simplified_A = UIML_Simp[7], + UIML_UIML_extraction = + [0, + coq_MPropF_of_form, + form_of_MPropF, + gl_UI, + k_UI, + isl_E, + isl_A, + isl_simp, + isl_simplified_E, + isl_simplified_A]; + runtime.caml_register_global + (4, UIML_UIML_extraction, "UIML__UIML_extraction"); + return; + } + (globalThis)); + + +//# 1 "../.js/default/bigstringaf/bigstringaf.cma.js" +// Generated by js_of_ocaml +//# 3 "../.js/default/bigstringaf/bigstringaf.cma.js" + +//# 6 "../.js/default/bigstringaf/bigstringaf.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst = " }", + cst_len = ", len: ", + cst_Bigstringaf = "Bigstringaf.", + cst_blit$2 = "blit", + cst_blit_from_bytes$2 = "blit_from_bytes", + cst_blit_from_string$2 = "blit_from_string", + cst_blit_to_bytes$2 = "blit_to_bytes", + cst_memchr$1 = "memchr", + cst_memcmp$2 = "memcmp", + cst_memcmp_string$2 = "memcmp_string", + caml_ba_dim_1 = runtime.caml_ba_dim_1, + caml_ba_uint8_get16 = runtime.caml_ba_uint8_get16, + caml_ba_uint8_get32 = runtime.caml_ba_uint8_get32, + caml_ba_uint8_get64 = runtime.caml_ba_uint8_get64, + caml_ba_uint8_set16 = runtime.caml_ba_uint8_set16, + caml_ba_uint8_set32 = runtime.caml_ba_uint8_set32, + caml_ba_uint8_set64 = runtime.caml_ba_uint8_set64, + caml_bswap16 = runtime.caml_bswap16, + caml_create_bytes = runtime.caml_create_bytes, + caml_int32_bswap = runtime.caml_int32_bswap, + caml_int64_bswap = runtime.caml_int64_bswap, + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace, + caml_ml_bytes_length = runtime.caml_ml_bytes_length, + caml_ml_string_length = runtime.caml_ml_string_length; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + function caml_call5(f, a0, a1, a2, a3, a4){ + return (f.l >= 0 ? f.l : f.l = f.length) == 5 + ? f(a0, a1, a2, a3, a4) + : runtime.caml_call_gen(f, [a0, a1, a2, a3, a4]); + } + function caml_call7(f, a0, a1, a2, a3, a4, a5, a6){ + return (f.l >= 0 ? f.l : f.l = f.length) == 7 + ? f(a0, a1, a2, a3, a4, a5, a6) + : runtime.caml_call_gen(f, [a0, a1, a2, a3, a4, a5, a6]); + } + var + global_data = runtime.caml_get_global_data(), + partial = [11, cst_len, [4, 0, 0, 0, [11, cst, 0]]], + partial$0 = [11, cst_len, [4, 0, 0, 0, [11, cst, 0]]], + Stdlib_Sys = global_data.Stdlib__Sys, + Stdlib_Bytes = global_data.Stdlib__Bytes, + Stdlib_Printf = global_data.Stdlib__Printf, + Stdlib = global_data.Stdlib, + Stdlib_Bigarray = global_data.Stdlib__Bigarray; + function create(size){ + return caml_call3 + (Stdlib_Bigarray[19][1], + Stdlib_Bigarray[13], + Stdlib_Bigarray[15], + size); + } + var + empty = create(0), + length = caml_ba_dim_1, + sub = runtime.caml_ba_sub, + _a_ = + [0, + [11, + cst_Bigstringaf, + [2, + 0, + [11, + " invalid range: { buffer_len: ", + [4, + 0, + 0, + 0, + [11, + ", off: ", + [4, 0, 0, 0, [11, cst_len, [4, 0, 0, 0, [11, cst, 0]]]]]]]]], + "Bigstringaf.%s invalid range: { buffer_len: %d, off: %d, len: %d }"], + _b_ = + [0, + [11, + cst_Bigstringaf, + [2, + 0, + [11, + " invalid range: { src_len: ", + [4, + 0, + 0, + 0, + [11, + ", src_off: ", + [4, + 0, + 0, + 0, + [11, + ", dst_len: ", + [4, 0, 0, 0, [11, ", dst_off: ", [4, 0, 0, 0, partial$0]]]]]]]]]], + "Bigstringaf.%s invalid range: { src_len: %d, src_off: %d, dst_len: %d, dst_off: %d, len: %d }"], + _c_ = + [0, + [11, + cst_Bigstringaf, + [2, + 0, + [11, + " invalid range: { buf1_len: ", + [4, + 0, + 0, + 0, + [11, + ", buf1_off: ", + [4, + 0, + 0, + 0, + [11, + ", buf2_len: ", + [4, 0, 0, 0, [11, ", buf2_off: ", [4, 0, 0, 0, partial]]]]]]]]]], + "Bigstringaf.%s invalid range: { buf1_len: %d, buf1_off: %d, buf2_len: %d, buf2_off: %d, len: %d }"], + cst_copy = "copy", + cst_substring = "substring", + cst_of_string = "of_string", + cst_blit = cst_blit$2, + cst_blit$0 = cst_blit$2, + cst_blit$1 = cst_blit$2, + cst_blit_from_string = cst_blit_from_string$2, + cst_blit_from_string$0 = cst_blit_from_string$2, + cst_blit_from_string$1 = cst_blit_from_string$2, + cst_blit_from_bytes = cst_blit_from_bytes$2, + cst_blit_from_bytes$0 = cst_blit_from_bytes$2, + cst_blit_from_bytes$1 = cst_blit_from_bytes$2, + cst_blit_to_bytes = cst_blit_to_bytes$2, + cst_blit_to_bytes$0 = cst_blit_to_bytes$2, + cst_blit_to_bytes$1 = cst_blit_to_bytes$2, + cst_memcmp = cst_memcmp$2, + cst_memcmp$0 = cst_memcmp$2, + cst_memcmp$1 = cst_memcmp$2, + cst_memcmp_string = cst_memcmp_string$2, + cst_memcmp_string$0 = cst_memcmp_string$2, + cst_memcmp_string$1 = cst_memcmp_string$2, + cst_memchr = cst_memchr$1, + cst_memchr$0 = cst_memchr$1; + function invalid_bounds(op, buffer_len, off, len){ + var message = caml_call5(Stdlib_Printf[4], _a_, op, buffer_len, off, len); + throw caml_maybe_attach_backtrace([0, Stdlib[6], message], 1); + } + function invalid_bounds_blit(op, src_len, src_off, dst_len, dst_off, len){ + var + message = + caml_call7 + (Stdlib_Printf[4], _b_, op, src_len, src_off, dst_len, dst_off, len); + throw caml_maybe_attach_backtrace([0, Stdlib[6], message], 1); + } + function invalid_bounds_memcmp + (op, buf1_len, buf1_off, buf2_len, buf2_off, len){ + var + message = + caml_call7 + (Stdlib_Printf[4], + _c_, + op, + buf1_len, + buf1_off, + buf2_len, + buf2_off, + len); + throw caml_maybe_attach_backtrace([0, Stdlib[6], message], 1); + } + function copy(t, off, len){ + var buffer_len = caml_ba_dim_1(t), _ax_ = len < 0 ? 1 : 0; + if(_ax_) + var _ay_ = _ax_; + else + var + _az_ = off < 0 ? 1 : 0, + _ay_ = _az_ || ((buffer_len - off | 0) < len ? 1 : 0); + if(_ay_) invalid_bounds(cst_copy, buffer_len, off, len); + var dst = create(len); + runtime.bigstringaf_blit_to_bigstring(t, off, dst, 0, len); + return dst; + } + function substring(t, off, len){ + var buffer_len = caml_ba_dim_1(t), _au_ = len < 0 ? 1 : 0; + if(_au_) + var _av_ = _au_; + else + var + _aw_ = off < 0 ? 1 : 0, + _av_ = _aw_ || ((buffer_len - off | 0) < len ? 1 : 0); + if(_av_) invalid_bounds(cst_substring, buffer_len, off, len); + var b = caml_create_bytes(len); + runtime.bigstringaf_blit_to_bytes(t, off, b, 0, len); + return caml_call1(Stdlib_Bytes[48], b); + } + function to_string(t){ + var len = caml_ba_dim_1(t), b = caml_create_bytes(len); + runtime.bigstringaf_blit_to_bytes(t, 0, b, 0, len); + return caml_call1(Stdlib_Bytes[48], b); + } + function of_string(off, len, s){ + var buffer_len = caml_ml_string_length(s), _ar_ = len < 0 ? 1 : 0; + if(_ar_) + var _as_ = _ar_; + else + var + _at_ = off < 0 ? 1 : 0, + _as_ = _at_ || ((buffer_len - off | 0) < len ? 1 : 0); + if(_as_) invalid_bounds(cst_of_string, buffer_len, off, len); + var b = create(len); + runtime.bigstringaf_blit_from_bytes(s, off, b, 0, len); + return b; + } + function blit(src, src_off, dst, dst_off, len){ + var src_len = caml_ba_dim_1(src), dst_len = caml_ba_dim_1(dst); + if(len < 0) + invalid_bounds_blit(cst_blit, src_len, src_off, dst_len, dst_off, len); + var + _an_ = src_off < 0 ? 1 : 0, + _ao_ = _an_ || ((src_len - src_off | 0) < len ? 1 : 0); + if(_ao_) + invalid_bounds_blit(cst_blit$0, src_len, src_off, dst_len, dst_off, len); + var + _ap_ = dst_off < 0 ? 1 : 0, + _aq_ = _ap_ || ((dst_len - dst_off | 0) < len ? 1 : 0); + if(_aq_) + invalid_bounds_blit(cst_blit$1, src_len, src_off, dst_len, dst_off, len); + return runtime.bigstringaf_blit_to_bigstring + (src, src_off, dst, dst_off, len); + } + function blit_from_string(src, src_off, dst, dst_off, len){ + var src_len = caml_ml_string_length(src), dst_len = caml_ba_dim_1(dst); + if(len < 0) + invalid_bounds_blit + (cst_blit_from_string, src_len, src_off, dst_len, dst_off, len); + var + _aj_ = src_off < 0 ? 1 : 0, + _ak_ = _aj_ || ((src_len - src_off | 0) < len ? 1 : 0); + if(_ak_) + invalid_bounds_blit + (cst_blit_from_string$0, src_len, src_off, dst_len, dst_off, len); + var + _al_ = dst_off < 0 ? 1 : 0, + _am_ = _al_ || ((dst_len - dst_off | 0) < len ? 1 : 0); + if(_am_) + invalid_bounds_blit + (cst_blit_from_string$1, src_len, src_off, dst_len, dst_off, len); + return runtime.bigstringaf_blit_from_bytes + (src, src_off, dst, dst_off, len); + } + function blit_from_bytes(src, src_off, dst, dst_off, len){ + var src_len = caml_ml_bytes_length(src), dst_len = caml_ba_dim_1(dst); + if(len < 0) + invalid_bounds_blit + (cst_blit_from_bytes, src_len, src_off, dst_len, dst_off, len); + var + _af_ = src_off < 0 ? 1 : 0, + _ag_ = _af_ || ((src_len - src_off | 0) < len ? 1 : 0); + if(_ag_) + invalid_bounds_blit + (cst_blit_from_bytes$0, src_len, src_off, dst_len, dst_off, len); + var + _ah_ = dst_off < 0 ? 1 : 0, + _ai_ = _ah_ || ((dst_len - dst_off | 0) < len ? 1 : 0); + if(_ai_) + invalid_bounds_blit + (cst_blit_from_bytes$1, src_len, src_off, dst_len, dst_off, len); + return runtime.bigstringaf_blit_from_bytes + (src, src_off, dst, dst_off, len); + } + function blit_to_bytes(src, src_off, dst, dst_off, len){ + var src_len = caml_ba_dim_1(src), dst_len = caml_ml_bytes_length(dst); + if(len < 0) + invalid_bounds_blit + (cst_blit_to_bytes, src_len, src_off, dst_len, dst_off, len); + var + _ab_ = src_off < 0 ? 1 : 0, + _ac_ = _ab_ || ((src_len - src_off | 0) < len ? 1 : 0); + if(_ac_) + invalid_bounds_blit + (cst_blit_to_bytes$0, src_len, src_off, dst_len, dst_off, len); + var + _ad_ = dst_off < 0 ? 1 : 0, + _ae_ = _ad_ || ((dst_len - dst_off | 0) < len ? 1 : 0); + if(_ae_) + invalid_bounds_blit + (cst_blit_to_bytes$1, src_len, src_off, dst_len, dst_off, len); + return runtime.bigstringaf_blit_to_bytes(src, src_off, dst, dst_off, len); + } + function memcmp(buf1, buf1_off, buf2, buf2_off, len){ + var buf1_len = caml_ba_dim_1(buf1), buf2_len = caml_ba_dim_1(buf2); + if(len < 0) + invalid_bounds_memcmp + (cst_memcmp, buf1_len, buf1_off, buf2_len, buf2_off, len); + var + _Z_ = buf1_off < 0 ? 1 : 0, + ___ = _Z_ || ((buf1_len - buf1_off | 0) < len ? 1 : 0); + if(___) + invalid_bounds_memcmp + (cst_memcmp$0, buf1_len, buf1_off, buf2_len, buf2_off, len); + var + _$_ = buf2_off < 0 ? 1 : 0, + _aa_ = _$_ || ((buf2_len - buf2_off | 0) < len ? 1 : 0); + if(_aa_) + invalid_bounds_memcmp + (cst_memcmp$1, buf1_len, buf1_off, buf2_len, buf2_off, len); + return runtime.bigstringaf_memcmp_bigstring + (buf1, buf1_off, buf2, buf2_off, len); + } + function memcmp_string(buf1, buf1_off, buf2, buf2_off, len){ + var + buf1_len = caml_ba_dim_1(buf1), + buf2_len = caml_ml_string_length(buf2); + if(len < 0) + invalid_bounds_memcmp + (cst_memcmp_string, buf1_len, buf1_off, buf2_len, buf2_off, len); + var + _V_ = buf1_off < 0 ? 1 : 0, + _W_ = _V_ || ((buf1_len - buf1_off | 0) < len ? 1 : 0); + if(_W_) + invalid_bounds_memcmp + (cst_memcmp_string$0, buf1_len, buf1_off, buf2_len, buf2_off, len); + var + _X_ = buf2_off < 0 ? 1 : 0, + _Y_ = _X_ || ((buf2_len - buf2_off | 0) < len ? 1 : 0); + if(_Y_) + invalid_bounds_memcmp + (cst_memcmp_string$1, buf1_len, buf1_off, buf2_len, buf2_off, len); + return runtime.bigstringaf_memcmp_string + (buf1, buf1_off, buf2, buf2_off, len); + } + function memchr(buf, buf_off, chr, len){ + var buf_len = caml_ba_dim_1(buf); + if(len < 0) invalid_bounds(cst_memchr, buf_len, buf_off, len); + var + _T_ = buf_off < 0 ? 1 : 0, + _U_ = _T_ || ((buf_len - buf_off | 0) < len ? 1 : 0); + if(_U_) invalid_bounds(cst_memchr$0, buf_len, buf_off, len); + return runtime.bigstringaf_memchr(buf, buf_off, chr, len); + } + function caml_bigstring_set_16(bs, off, i){ + return caml_ba_uint8_set16(bs, off, caml_bswap16(i)); + } + function caml_bigstring_set_32(bs, off, i){ + return caml_ba_uint8_set32(bs, off, caml_int32_bswap(i)); + } + function caml_bigstring_set_64(bs, off, i){ + return caml_ba_uint8_set64(bs, off, caml_int64_bswap(i)); + } + function caml_bigstring_get_16(bs, off){ + return caml_bswap16(caml_ba_uint8_get16(bs, off)); + } + function caml_bigstring_get_32(bs, off){ + return caml_int32_bswap(caml_ba_uint8_get32(bs, off)); + } + function caml_bigstring_get_64(bs, off){ + return caml_int64_bswap(caml_ba_uint8_get64(bs, off)); + } + function get_int16_sign_extended(x, off){ + var _R_ = Stdlib_Sys[10] - 16 | 0, _S_ = Stdlib_Sys[10] - 16 | 0; + return caml_bigstring_get_16(x, off) << _S_ >> _R_; + } + if(Stdlib_Sys[11]) + var + set_int16_be = caml_ba_uint8_set16, + set_int16_le = caml_bigstring_set_16; + else + var + set_int16_be = caml_bigstring_set_16, + set_int16_le = caml_ba_uint8_set16; + if(Stdlib_Sys[11]) + var + set_int32_be = caml_ba_uint8_set32, + set_int32_le = caml_bigstring_set_32; + else + var + set_int32_be = caml_bigstring_set_32, + set_int32_le = caml_ba_uint8_set32; + if(Stdlib_Sys[11]) + var + set_int64_be = caml_ba_uint8_set64, + set_int64_le = caml_bigstring_set_64; + else + var + set_int64_be = caml_bigstring_set_64, + set_int64_le = caml_ba_uint8_set64; + if(Stdlib_Sys[11]) + var + get_int16_be = caml_ba_uint8_get16, + get_int16_le = caml_bigstring_get_16; + else + var + get_int16_be = caml_bigstring_get_16, + get_int16_le = caml_ba_uint8_get16; + function get_int16_sign_extended_noswap(x, off){ + var _P_ = Stdlib_Sys[10] - 16 | 0, _Q_ = Stdlib_Sys[10] - 16 | 0; + return caml_ba_uint8_get16(x, off) << _Q_ >> _P_; + } + if(Stdlib_Sys[11]) + var + get_int16_sign_extended_noswap$0 = get_int16_sign_extended_noswap, + get_int16_sign_extended_le = get_int16_sign_extended; + else + var + get_int16_sign_extended_noswap$0 = get_int16_sign_extended, + get_int16_sign_extended_le = get_int16_sign_extended_noswap; + if(Stdlib_Sys[11]) + var + get_int32_be = caml_ba_uint8_get32, + get_int32_le = caml_bigstring_get_32; + else + var + get_int32_be = caml_bigstring_get_32, + get_int32_le = caml_ba_uint8_get32; + if(Stdlib_Sys[11]) + var + get_int64_be = caml_ba_uint8_get64, + get_int64_le = caml_bigstring_get_64; + else + var + get_int64_be = caml_bigstring_get_64, + get_int64_le = caml_ba_uint8_get64; + function caml_bigstring_unsafe_set_16(bs, off, i){ + return caml_ba_uint8_set16(bs, off, caml_bswap16(i)); + } + function caml_bigstring_unsafe_set_32(bs, off, i){ + return caml_ba_uint8_set32(bs, off, caml_int32_bswap(i)); + } + function caml_bigstring_unsafe_set_64(bs, off, i){ + return caml_ba_uint8_set64(bs, off, caml_int64_bswap(i)); + } + function caml_bigstring_unsafe_get_16(bs, off){ + return caml_bswap16(caml_ba_uint8_get16(bs, off)); + } + function caml_bigstring_unsafe_get_32(bs, off){ + return caml_int32_bswap(caml_ba_uint8_get32(bs, off)); + } + function caml_bigstring_unsafe_get_64(bs, off){ + return caml_int64_bswap(caml_ba_uint8_get64(bs, off)); + } + if(Stdlib_Sys[11]) + var + unsafe_set_int16_be = caml_ba_uint8_set16, + unsafe_set_int16_le = caml_bigstring_unsafe_set_16; + else + var + unsafe_set_int16_be = caml_bigstring_unsafe_set_16, + unsafe_set_int16_le = caml_ba_uint8_set16; + if(Stdlib_Sys[11]) + var + unsafe_set_int32_be = caml_ba_uint8_set32, + unsafe_set_int32_le = caml_bigstring_unsafe_set_32; + else + var + unsafe_set_int32_be = caml_bigstring_unsafe_set_32, + unsafe_set_int32_le = caml_ba_uint8_set32; + if(Stdlib_Sys[11]) + var + unsafe_set_int64_be = caml_ba_uint8_set64, + unsafe_set_int64_le = caml_bigstring_unsafe_set_64; + else + var + unsafe_set_int64_be = caml_bigstring_unsafe_set_64, + unsafe_set_int64_le = caml_ba_uint8_set64; + if(Stdlib_Sys[11]) + var + unsafe_get_int16_be = caml_ba_uint8_get16, + unsafe_get_int16_le = caml_bigstring_unsafe_get_16; + else + var + unsafe_get_int16_be = caml_bigstring_unsafe_get_16, + unsafe_get_int16_le = caml_ba_uint8_get16; + function unsafe_get_int16_sign_extended(x, off){ + var _N_ = Stdlib_Sys[10] - 16 | 0, _O_ = Stdlib_Sys[10] - 16 | 0; + return unsafe_get_int16_le(x, off) << _O_ >> _N_; + } + function unsafe_get_int16_sign_extended$0(x, off){ + var _L_ = Stdlib_Sys[10] - 16 | 0, _M_ = Stdlib_Sys[10] - 16 | 0; + return unsafe_get_int16_be(x, off) << _M_ >> _L_; + } + if(Stdlib_Sys[11]) + var + unsafe_get_int32_be = caml_ba_uint8_get32, + unsafe_get_int32_le = caml_bigstring_unsafe_get_32; + else + var + unsafe_get_int32_be = caml_bigstring_unsafe_get_32, + unsafe_get_int32_le = caml_ba_uint8_get32; + if(Stdlib_Sys[11]) + var + unsafe_get_int64_be = caml_ba_uint8_get64, + unsafe_get_int64_le = caml_bigstring_unsafe_get_64; + else + var + unsafe_get_int64_be = caml_bigstring_unsafe_get_64, + unsafe_get_int64_le = caml_ba_uint8_get64; + var + Bigstringaf = + [0, + create, + empty, + of_string, + copy, + sub, + length, + substring, + to_string, + get_int16_le, + get_int16_sign_extended_le, + set_int16_le, + get_int32_le, + set_int32_le, + get_int64_le, + set_int64_le, + get_int16_be, + get_int16_sign_extended_noswap$0, + set_int16_be, + get_int32_be, + set_int32_be, + get_int64_be, + set_int64_be, + blit, + blit_from_string, + blit_from_bytes, + blit_to_bytes, + memcmp, + memcmp_string, + memchr, + unsafe_get_int16_le, + unsafe_get_int16_be, + unsafe_get_int16_sign_extended, + unsafe_get_int16_sign_extended$0, + unsafe_set_int16_le, + unsafe_set_int16_be, + unsafe_get_int32_le, + unsafe_get_int32_be, + unsafe_set_int32_le, + unsafe_set_int32_be, + unsafe_get_int64_le, + unsafe_get_int64_be, + unsafe_set_int64_le, + unsafe_set_int64_be, + function(_K_, _J_, _I_, _H_, _G_){ + return runtime.bigstringaf_blit_to_bigstring(_K_, _J_, _I_, _H_, _G_); + }, + function(_F_, _E_, _D_, _C_, _B_){ + return runtime.bigstringaf_blit_from_bytes(_F_, _E_, _D_, _C_, _B_); + }, + function(_A_, _z_, _y_, _x_, _w_){ + return runtime.bigstringaf_blit_from_bytes(_A_, _z_, _y_, _x_, _w_); + }, + function(_v_, _u_, _t_, _s_, _r_){ + return runtime.bigstringaf_blit_to_bytes(_v_, _u_, _t_, _s_, _r_); + }, + function(_q_, _p_, _o_, _n_, _m_){ + return runtime.bigstringaf_memcmp_bigstring(_q_, _p_, _o_, _n_, _m_); + }, + function(_l_, _k_, _j_, _i_, _h_){ + return runtime.bigstringaf_memcmp_string(_l_, _k_, _j_, _i_, _h_); + }, + function(_g_, _f_, _e_, _d_){ + return runtime.bigstringaf_memchr(_g_, _f_, _e_, _d_); + }]; + runtime.caml_register_global(31, Bigstringaf, "Bigstringaf"); + return; + } + (globalThis)); + + +//# 1 "../.js/default/angstrom/angstrom.cma.js" +// Generated by js_of_ocaml +//# 3 "../.js/default/angstrom/angstrom.cma.js" + +//# 25 "../.js/default/angstrom/angstrom.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + var + global_data = runtime.caml_get_global_data(), + cst = ": ", + cst$0 = " > ", + Stdlib = global_data.Stdlib, + Stdlib_String = global_data.Stdlib__String, + _a_ = [1, "incomplete input"]; + function state_to_option(x){ + switch(x[0]){ + case 0: + return 0; + case 1: + var v = x[2]; return [0, v]; + default: return 0; + } + } + function fail_to_string(marks, err){ + var + _b_ = caml_call2(Stdlib[28], cst, err), + _c_ = caml_call2(Stdlib_String[6], cst$0, marks); + return caml_call2(Stdlib[28], _c_, _b_); + } + function state_to_result(x){ + switch(x[0]){ + case 0: + return _a_; + case 1: + var v = x[2]; return [0, v]; + default: + var err = x[3], marks = x[2]; return [1, fail_to_string(marks, err)]; + } + } + var + Angstrom_Exported_state = + [0, state_to_option, fail_to_string, state_to_result]; + runtime.caml_register_global + (5, Angstrom_Exported_state, "Angstrom__Exported_state"); + return; + } + (globalThis)); + +//# 77 "../.js/default/angstrom/angstrom.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst_lib_input_ml = "lib/input.ml", + caml_ba_get_1 = runtime.caml_ba_get_1, + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + var + global_data = runtime.caml_get_global_data(), + Bigstringaf = global_data.Bigstringaf, + Assert_failure = global_data.Assert_failure, + _a_ = [0, cst_lib_input_ml, 60, 2], + _b_ = [0, cst_lib_input_ml, 59, 2]; + function create(buffer, off, len, committed_bytes){ + return [0, committed_bytes, committed_bytes, off, len, buffer]; + } + function length(t){return t[2] + t[4] | 0;} + function client_committed_bytes(t){return t[2];} + function parser_committed_bytes(t){return t[1];} + function bytes_for_client_to_commit(t){return t[1] - t[2] | 0;} + function parser_uncommitted_bytes(t){ + var _f_ = bytes_for_client_to_commit(t); + return t[4] - _f_ | 0; + } + function invariant(t){ + var _c_ = length(t), _d_ = parser_uncommitted_bytes(t); + if((t[1] + _d_ | 0) !== _c_) + throw caml_maybe_attach_backtrace([0, Assert_failure, _b_], 1); + var _e_ = bytes_for_client_to_commit(t); + if((t[1] - t[2] | 0) === _e_) return 0; + throw caml_maybe_attach_backtrace([0, Assert_failure, _a_], 1); + } + function offset_in_buffer(t, pos){return (t[3] + pos | 0) - t[2] | 0;} + function apply(t, pos, len, f){ + var off = offset_in_buffer(t, pos); + return caml_call3(f, t[5], off, len); + } + function unsafe_get_char(t, pos){ + var off = offset_in_buffer(t, pos); + return caml_ba_get_1(t[5], off); + } + function unsafe_get_int16_le(t, pos){ + var off = offset_in_buffer(t, pos); + return caml_call2(Bigstringaf[30], t[5], off); + } + function unsafe_get_int32_le(t, pos){ + var off = offset_in_buffer(t, pos); + return caml_call2(Bigstringaf[36], t[5], off); + } + function unsafe_get_int64_le(t, pos){ + var off = offset_in_buffer(t, pos); + return caml_call2(Bigstringaf[40], t[5], off); + } + function unsafe_get_int16_be(t, pos){ + var off = offset_in_buffer(t, pos); + return caml_call2(Bigstringaf[31], t[5], off); + } + function unsafe_get_int32_be(t, pos){ + var off = offset_in_buffer(t, pos); + return caml_call2(Bigstringaf[37], t[5], off); + } + function unsafe_get_int64_be(t, pos){ + var off = offset_in_buffer(t, pos); + return caml_call2(Bigstringaf[41], t[5], off); + } + function count_while(t, pos, f){ + var + buffer = t[5], + off = offset_in_buffer(t, pos), + i = [0, off], + limit = t[3] + t[4] | 0; + for(;;){ + if(i[1] < limit && caml_call1(f, caml_ba_get_1(buffer, i[1]))){i[1]++; continue;} + return i[1] - off | 0; + } + } + function commit(t, pos){t[1] = pos; return 0;} + var + Angstrom_Input = + [0, + create, + length, + client_committed_bytes, + parser_committed_bytes, + parser_uncommitted_bytes, + bytes_for_client_to_commit, + unsafe_get_char, + unsafe_get_int16_le, + unsafe_get_int32_le, + unsafe_get_int64_le, + unsafe_get_int16_be, + unsafe_get_int32_be, + unsafe_get_int64_be, + count_while, + apply, + commit, + invariant]; + runtime.caml_register_global(4, Angstrom_Input, "Angstrom__Input"); + return; + } + (globalThis)); + +//# 197 "../.js/default/angstrom/angstrom.cma.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + function caml_call4(f, a0, a1, a2, a3){ + return (f.l >= 0 ? f.l : f.l = f.length) == 4 + ? f(a0, a1, a2, a3) + : runtime.caml_call_gen(f, [a0, a1, a2, a3]); + } + function caml_call5(f, a0, a1, a2, a3, a4){ + return (f.l >= 0 ? f.l : f.l = f.length) == 5 + ? f(a0, a1, a2, a3, a4) + : runtime.caml_call_gen(f, [a0, a1, a2, a3, a4]); + } + var + global_data = runtime.caml_get_global_data(), + CamlinternalLazy = global_data.CamlinternalLazy, + Angstrom_Input = global_data.Angstrom__Input, + Bigstringaf = global_data.Bigstringaf, + Angstrom_Exported_state = global_data.Angstrom__Exported_state, + State = [0]; + function fail_k(input, pos, param, marks, msg){ + return [3, pos - caml_call1(Angstrom_Input[3], input) | 0, marks, msg]; + } + function succeed_k(input, pos, param, v){ + return [2, pos - caml_call1(Angstrom_Input[3], input) | 0, v]; + } + function to_exported_state(param){ + var param$0 = param; + for(;;) + switch(param$0[0]){ + case 0: + var match = param$0[1], continue$0 = match[2], committed = match[1]; + return [0, + [0, + committed, + function(bs, off, len, more){ + return to_exported_state + (caml_call4(continue$0, bs, off, len, more)); + }]]; + case 1: + var + x = param$0[1], + _c_ = runtime.caml_obj_tag(x), + param$1 = + 250 === _c_ + ? x[1] + : 246 === _c_ ? caml_call1(CamlinternalLazy[2], x) : x; + param$0 = param$1; + break; + case 2: + var x$0 = param$0[2], i = param$0[1]; return [1, i, x$0]; + default: + var s = param$0[3], sl = param$0[2], i$0 = param$0[1]; + return [2, i$0, sl, s]; + } + } + function parse(p){ + var input = caml_call4(Angstrom_Input[1], Bigstringaf[2], 0, 0, 0); + return to_exported_state(caml_call5(p[1], input, 0, 1, fail_k, succeed_k)); + } + function parse_bigstring(p, input){ + var + _a_ = caml_call1(Bigstringaf[6], input), + input$0 = caml_call4(Angstrom_Input[1], input, 0, _a_, 0), + _b_ = + to_exported_state(caml_call5(p[1], input$0, 0, 0, fail_k, succeed_k)); + return caml_call1(Angstrom_Exported_state[3], _b_); + } + function return$0(v){ + return [0, + function(input, pos, more, fail, succ){ + return caml_call4(succ, input, pos, more, v); + }]; + } + function fail(msg){ + return [0, + function(input, pos, more, fail, succ){ + return caml_call5(fail, input, pos, more, 0, msg); + }]; + } + function symbol_bind(p, f){ + return [0, + function(input, pos, more, fail, succ){ + function succ$0(input, pos, more, v){ + return caml_call5 + (caml_call1(f, v)[1], input, pos, more, fail, succ); + } + return caml_call5(p[1], input, pos, more, fail, succ$0); + }]; + } + function symbol_map(p, f){ + return [0, + function(input, pos, more, fail, succ){ + function succ$0(input, pos, more, v){ + return caml_call4(succ, input, pos, more, caml_call1(f, v)); + } + return caml_call5(p[1], input, pos, more, fail, succ$0); + }]; + } + function symbol(f, m){return symbol_map(m, f);} + function symbol$0(f, m){ + return [0, + function(input, pos, more, fail, succ){ + function succ0(input0, pos0, more0, f){ + function succ1(input1, pos1, more1, m){ + return caml_call4(succ, input1, pos1, more1, caml_call1(f, m)); + } + return caml_call5(m[1], input0, pos0, more0, fail, succ1); + } + return caml_call5(f[1], input, pos, more, fail, succ0); + }]; + } + function lift(f, m){return symbol_map(m, f);} + function lift2(f, m1, m2){ + return [0, + function(input, pos, more, fail, succ){ + function succ1(input1, pos1, more1, m1){ + function succ2(input2, pos2, more2, m2){ + return caml_call4 + (succ, input2, pos2, more2, caml_call2(f, m1, m2)); + } + return caml_call5(m2[1], input1, pos1, more1, fail, succ2); + } + return caml_call5(m1[1], input, pos, more, fail, succ1); + }]; + } + function lift3(f, m1, m2, m3){ + return [0, + function(input, pos, more, fail, succ){ + function succ1(input1, pos1, more1, m1){ + function succ2(input2, pos2, more2, m2){ + function succ3(input3, pos3, more3, m3){ + return caml_call4 + (succ, input3, pos3, more3, caml_call3(f, m1, m2, m3)); + } + return caml_call5(m3[1], input2, pos2, more2, fail, succ3); + } + return caml_call5(m2[1], input1, pos1, more1, fail, succ2); + } + return caml_call5(m1[1], input, pos, more, fail, succ1); + }]; + } + function lift4(f, m1, m2, m3, m4){ + return [0, + function(input, pos, more, fail, succ){ + function succ1(input1, pos1, more1, m1){ + function succ2(input2, pos2, more2, m2){ + function succ3(input3, pos3, more3, m3){ + function succ4(input4, pos4, more4, m4){ + return caml_call4 + (succ, input4, pos4, more4, caml_call4(f, m1, m2, m3, m4)); + } + return caml_call5(m4[1], input3, pos3, more3, fail, succ4); + } + return caml_call5(m3[1], input2, pos2, more2, fail, succ3); + } + return caml_call5(m2[1], input1, pos1, more1, fail, succ2); + } + return caml_call5(m1[1], input, pos, more, fail, succ1); + }]; + } + function symbol$1(a, b){ + return [0, + function(input, pos, more, fail, succ){ + function succ$0(input, pos, more, param){ + return caml_call5(b[1], input, pos, more, fail, succ); + } + return caml_call5(a[1], input, pos, more, fail, succ$0); + }]; + } + function symbol$2(a, b){ + return [0, + function(input, pos, more, fail, succ){ + function succ0(input0, pos0, more0, x){ + function succ1(input1, pos1, more1, param){ + return caml_call4(succ, input1, pos1, more1, x); + } + return caml_call5(b[1], input0, pos0, more0, fail, succ1); + } + return caml_call5(a[1], input, pos, more, fail, succ0); + }]; + } + var + Monad = + [0, + return$0, + fail, + symbol_bind, + symbol_map, + symbol, + symbol$0, + lift, + lift2, + lift3, + lift4, + symbol$1, + symbol$2]; + function symbol$3(p, mark){ + return [0, + function(input, pos, more, fail, succ){ + function fail$0(input, pos, more, marks, msg){ + return caml_call5(fail, input, pos, more, [0, mark, marks], msg); + } + return caml_call5(p[1], input, pos, more, fail$0, succ); + }]; + } + function symbol$4(p, q){ + return [0, + function(input, pos, more, fail, succ){ + function fail$0(input, pos$0, more$0, marks, msg){ + return pos < caml_call1(Angstrom_Input[4], input) + ? caml_call5(fail, input, pos$0, more, marks, msg) + : caml_call5(q[1], input, pos, more$0, fail, succ); + } + return caml_call5(p[1], input, pos, more, fail$0, succ); + }]; + } + var + Choice = [0, symbol$3, symbol$4], + return$1 = Monad[1], + fail$0 = Monad[2], + symbol_bind$0 = Monad[3]; + function symbol_map$0(m, f){ + return caml_call2 + (symbol_bind$0, + m, + function(x){return caml_call1(return$1, caml_call1(f, x));}); + } + function symbol$5(f, m){return symbol_map$0(m, f);} + function symbol$6(f, m){ + return caml_call2 + (symbol_bind$0, f, function(f){return symbol_map$0(m, f);}); + } + function lift2$0(f, m1, m2){return symbol$6(symbol_map$0(m1, f), m2);} + function lift3$0(f, m1, m2, m3){ + return symbol$6(symbol$6(symbol_map$0(m1, f), m2), m3); + } + function lift4$0(f, m1, m2, m3, m4){ + return symbol$6(symbol$6(symbol$6(symbol_map$0(m1, f), m2), m3), m4); + } + function symbol$7(a, b){ + return caml_call2(symbol_bind$0, a, function(param){return b;}); + } + function symbol$8(a, b){ + return caml_call2 + (symbol_bind$0, + a, + function(x){return symbol_map$0(b, function(param){return x;});}); + } + var + Monad_use_for_debugging = + [0, + return$1, + fail$0, + symbol_bind$0, + symbol_map$0, + symbol$5, + symbol$6, + symbol_map$0, + lift2$0, + lift3$0, + lift4$0, + symbol$7, + symbol$8], + Angstrom_Parser = + [0, + State, + fail_k, + succeed_k, + to_exported_state, + parse, + parse_bigstring, + Monad, + Choice, + Monad_use_for_debugging]; + runtime.caml_register_global(4, Angstrom_Parser, "Angstrom__Parser"); + return; + } + (globalThis)); + +//# 495 "../.js/default/angstrom/angstrom.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst_lib_buffering_ml = "lib/buffering.ml", + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace, + caml_ml_string_length = runtime.caml_ml_string_length; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + function caml_call5(f, a0, a1, a2, a3, a4){ + return (f.l >= 0 ? f.l : f.l = f.length) == 5 + ? f(a0, a1, a2, a3, a4) + : runtime.caml_call_gen(f, [a0, a1, a2, a3, a4]); + } + var + undef = undefined, + global_data = runtime.caml_get_global_data(), + Assert_failure = global_data.Assert_failure, + Bigstringaf = global_data.Bigstringaf, + _a_ = [0, cst_lib_buffering_ml, 8, 2], + _b_ = [0, cst_lib_buffering_ml, 7, 2], + _c_ = [0, cst_lib_buffering_ml, 47, 2], + _d_ = [0, cst_lib_buffering_ml, 46, 2], + _e_ = [0, cst_lib_buffering_ml, 54, 2], + _f_ = [0, cst_lib_buffering_ml, 53, 2], + _g_ = [0, cst_lib_buffering_ml, 64, 2], + _h_ = [0, cst_lib_buffering_ml, 79, 2]; + function of_bigstring(off, len, buf){ + if(0 > off) + throw caml_maybe_attach_backtrace([0, Assert_failure, _b_], 1); + if((len - off | 0) <= caml_call1(Bigstringaf[6], buf)) + return [0, buf, off, len]; + throw caml_maybe_attach_backtrace([0, Assert_failure, _a_], 1); + } + function create(len){ + return of_bigstring(0, 0, caml_call1(Bigstringaf[1], len)); + } + function writable_space(t){ + var _m_ = t[3]; + return caml_call1(Bigstringaf[6], t[1]) - _m_ | 0; + } + function ensure(t, to_copy){ + var + _k_ = t[2] + t[3] | 0, + _l_ = (caml_call1(Bigstringaf[6], t[1]) - _k_ | 0) < to_copy ? 1 : 0; + if(! _l_) return _l_; + if(to_copy <= writable_space(t)){ + caml_call5(Bigstringaf[44], t[1], t[2], t[1], 0, t[3]); + t[2] = 0; + return; + } + var + old_len = caml_call1(Bigstringaf[6], t[1]), + new_len = [0, old_len], + space = writable_space(t); + for(;;){ + if(((space + new_len[1] | 0) - old_len | 0) >= to_copy){ + var new_buf = caml_call1(Bigstringaf[1], new_len[1]); + caml_call5(Bigstringaf[44], t[1], t[2], new_buf, 0, t[3]); + t[1] = new_buf; + t[2] = 0; + return; + } + new_len[1] = (3 * new_len[1] | 0) / 2 | 0; + } + } + function write_pos(t){return t[2] + t[3] | 0;} + function feed_string(t, off, len, str){ + if(0 > off) + throw caml_maybe_attach_backtrace([0, Assert_failure, _d_], 1); + if((len - off | 0) > caml_ml_string_length(str)) + throw caml_maybe_attach_backtrace([0, Assert_failure, _c_], 1); + ensure(t, len); + var _j_ = write_pos(t); + caml_call5(Bigstringaf[45], str, off, t[1], _j_, len); + t[3] = t[3] + len | 0; + return 0; + } + function feed_bigstring(t, off, len, b){ + if(0 > off) + throw caml_maybe_attach_backtrace([0, Assert_failure, _f_], 1); + if((len - off | 0) > caml_call1(Bigstringaf[6], b)) + throw caml_maybe_attach_backtrace([0, Assert_failure, _e_], 1); + ensure(t, len); + var _i_ = write_pos(t); + caml_call5(Bigstringaf[44], b, off, t[1], _i_, len); + t[3] = t[3] + len | 0; + return 0; + } + function feed_input(t, param){ + if(608227697 <= param[1]){ + var b = param[2]; + return feed_bigstring(t, 0, caml_call1(Bigstringaf[6], b), b); + } + var s = param[2]; + return feed_string(t, 0, caml_ml_string_length(s), s); + } + function shift(t, n){ + if(n > t[3]) + throw caml_maybe_attach_backtrace([0, Assert_failure, _g_], 1); + t[2] = t[2] + n | 0; + t[3] = t[3] - n | 0; + return 0; + } + function for_reading(param){ + var buf = param[1], off = param[2], len = param[3]; + return caml_call3(Bigstringaf[5], buf, off, len); + } + function unconsumed(opt, param){ + if(opt) var sth = opt[1], shift = sth; else var shift = 0; + var buf = param[1], off = param[2], len = param[3]; + if(shift <= len) return [0, buf, off + shift | 0, len - shift | 0]; + throw caml_maybe_attach_backtrace([0, Assert_failure, _h_], 1); + } + function of_unconsumed(param){ + var len = param[3], off = param[2], buf = param[1]; + return [0, buf, off, len]; + } + var + Angstrom_Buffering = + [0, + create, + of_bigstring, + feed_string, + feed_bigstring, + feed_input, + shift, + for_reading, + unconsumed, + of_unconsumed]; + runtime.caml_register_global(10, Angstrom_Buffering, "Angstrom__Buffering"); + return; + } + (globalThis)); + +//# 641 "../.js/default/angstrom/angstrom.cma.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst_count_while1$1 = "count_while1", + cst_not_enough_input$1 = "not enough input", + cst_satisfy = "satisfy: ", + cst_satisfy_C = "satisfy: %C", + caml_int32_float_of_bits = runtime.caml_int32_float_of_bits, + caml_int64_float_of_bits = runtime.caml_int64_float_of_bits, + caml_ml_string_length = runtime.caml_ml_string_length, + caml_obj_tag = runtime.caml_obj_tag, + caml_update_dummy = runtime.caml_update_dummy; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + function caml_call4(f, a0, a1, a2, a3){ + return (f.l >= 0 ? f.l : f.l = f.length) == 4 + ? f(a0, a1, a2, a3) + : runtime.caml_call_gen(f, [a0, a1, a2, a3]); + } + function caml_call5(f, a0, a1, a2, a3, a4){ + return (f.l >= 0 ? f.l : f.l = f.length) == 5 + ? f(a0, a1, a2, a3, a4) + : runtime.caml_call_gen(f, [a0, a1, a2, a3, a4]); + } + var + global_data = runtime.caml_get_global_data(), + cst = "\r\n", + Stdlib = global_data.Stdlib, + Angstrom_Input = global_data.Angstrom__Input, + Bigstringaf = global_data.Bigstringaf, + Stdlib_Int64 = global_data.Stdlib__Int64, + Stdlib_Int32 = global_data.Stdlib__Int32, + CamlinternalLazy = global_data.CamlinternalLazy, + Stdlib_List = global_data.Stdlib__List, + Stdlib_Char = global_data.Stdlib__Char, + Stdlib_Printf = global_data.Stdlib__Printf, + Angstrom_Buffering = global_data.Angstrom__Buffering, + Angstrom_Parser = global_data.Angstrom__Parser, + Angstrom_Exported_state = global_data.Angstrom__Exported_state, + Stdlib_Sys = global_data.Stdlib__Sys, + parse = Angstrom_Parser[5], + parse_bigstring = Angstrom_Parser[6], + state_to_option = Angstrom_Exported_state[1], + fail_to_string = Angstrom_Exported_state[2], + state_to_result = Angstrom_Exported_state[3], + _a_ = Angstrom_Parser[7], + return$0 = _a_[1], + fail = _a_[2], + symbol_bind = _a_[3], + symbol_map = _a_[4], + symbol = _a_[5], + symbol$0 = _a_[6], + lift = _a_[7], + lift2 = _a_[8], + lift3 = _a_[9], + lift4 = _a_[10], + symbol$1 = _a_[11], + symbol$2 = _a_[12], + include = Angstrom_Parser[8], + symbol$3 = include[1], + symbol$4 = include[2], + cst_parse_invalid_argument_ini = + "parse: invalid argument, initial_buffer_size < 1", + _b_ = [1, "incomplete input"], + cst_prompt_input_shrunk = "prompt: input shrunk!", + cst_not_enough_input = cst_not_enough_input$1, + cst_not_enough_input$0 = cst_not_enough_input$1; + function from_unbuffered_state(f, buffering, param){ + switch(param[0]){ + case 0: + var p = param[1]; return [0, caml_call1(f, p)]; + case 1: + var + v = param[2], + consumed = param[1], + unconsumed = + caml_call2(Angstrom_Buffering[8], [0, consumed], buffering); + return [1, unconsumed, v]; + default: + var + msg = param[3], + marks = param[2], + consumed$0 = param[1], + unconsumed$0 = + caml_call2(Angstrom_Buffering[8], [0, consumed$0], buffering); + return [2, unconsumed$0, marks, msg]; + } + } + function parse$0(opt, p){ + if(opt) + var sth = opt[1], initial_buffer_size = sth; + else + var initial_buffer_size = 4096; + if(initial_buffer_size < 1) + caml_call1(Stdlib[2], cst_parse_invalid_argument_ini); + var buffering = caml_call1(Angstrom_Buffering[1], initial_buffer_size); + function f(p, input){ + caml_call2(Angstrom_Buffering[6], buffering, p[1]); + var + more = + typeof input === "number" + ? 0 + : (caml_call2(Angstrom_Buffering[5], buffering, input), 1), + for_reading = caml_call1(Angstrom_Buffering[7], buffering), + _P_ = caml_call1(Bigstringaf[6], for_reading); + return from_unbuffered_state + (f, buffering, caml_call4(p[2], for_reading, 0, _P_, more)); + } + return from_unbuffered_state(f, buffering, caml_call1(parse, p)); + } + function feed(state, input){ + switch(state[0]){ + case 0: + var k = state[1]; return caml_call1(k, input); + case 1: + var v = state[2], unconsumed = state[1]; + if(typeof input === "number") return state; + var buffering = caml_call1(Angstrom_Buffering[9], unconsumed); + caml_call2(Angstrom_Buffering[5], buffering, input); + return [1, caml_call2(Angstrom_Buffering[8], 0, buffering), v]; + default: + var msg = state[3], marks = state[2], unconsumed$0 = state[1]; + if(typeof input === "number") return state; + var buffering$0 = caml_call1(Angstrom_Buffering[9], unconsumed$0); + caml_call2(Angstrom_Buffering[5], buffering$0, input); + return [2, + caml_call2(Angstrom_Buffering[8], 0, buffering$0), + marks, + msg]; + } + } + function state_to_option$0(param){ + switch(param[0]){ + case 0: + return 0; + case 1: + var v = param[2]; return [0, v]; + default: return 0; + } + } + function state_to_result$0(param){ + switch(param[0]){ + case 0: + return _b_; + case 1: + var v = param[2]; return [0, v]; + default: + var msg = param[3], marks = param[2]; + return [1, caml_call2(fail_to_string, marks, msg)]; + } + } + function state_to_unconsumed(param){ + if(0 === param[0]) return 0; + var unconsumed = param[1]; + return [0, unconsumed]; + } + function prompt(input, pos, fail, succ){ + var + parser_uncommitted_bytes = caml_call1(Angstrom_Input[5], input), + parser_committed_bytes = caml_call1(Angstrom_Input[4], input); + function continue$0(input, off, len, more){ + if(len < parser_uncommitted_bytes) + caml_call1(Stdlib[2], cst_prompt_input_shrunk); + var + input$0 = + caml_call4(Angstrom_Input[1], input, off, len, parser_committed_bytes); + return len === parser_uncommitted_bytes + ? more + ? prompt(input$0, pos, fail, succ) + : caml_call3(fail, input$0, pos, 0) + : caml_call3(succ, input$0, pos, more); + } + return [0, [0, caml_call1(Angstrom_Input[6], input), continue$0]]; + } + var + demand_input = + [0, + function(input, pos, more, fail, succ){ + if(! more) + return caml_call5(fail, input, pos, more, 0, cst_not_enough_input$0); + function succ$0(input, pos, more){ + return caml_call4(succ, input, pos, more, 0); + } + function fail$0(input, pos, more){ + return caml_call5(fail, input, pos, more, 0, cst_not_enough_input); + } + return prompt(input, pos, fail$0, succ$0); + }]; + function ensure_suspended(n, input, pos, more, fail, succ){ + var go = []; + caml_update_dummy + (go, + [0, + function(input, pos, more, fail, succ){ + return (pos + n | 0) <= caml_call1(Angstrom_Input[2], input) + ? caml_call4(succ, input, pos, more, 0) + : caml_call5 + (caml_call2(symbol$1, demand_input, go)[1], + input, + pos, + more, + fail, + succ); + }]); + return caml_call5 + (caml_call2(symbol$1, demand_input, go)[1], + input, + pos, + more, + fail, + succ); + } + function unsafe_apply(len, f){ + return [0, + function(input, pos, more, fail, succ){ + return caml_call4 + (succ, + input, + pos + len | 0, + more, + caml_call4(Angstrom_Input[15], input, pos, len, f)); + }]; + } + function ensure(n, p){ + return [0, + function(input, pos, more, fail, succ){ + if((pos + n | 0) <= caml_call1(Angstrom_Input[2], input)) + return caml_call5(p[1], input, pos, more, fail, succ); + function succ$0(input, pos, more, param){ + return caml_call5(p[1], input, pos, more, fail, succ); + } + return ensure_suspended(n, input, pos, more, fail, succ$0); + }]; + } + var + at_end_of_input = + [0, + function(input, pos, more, param, succ){ + if(pos < caml_call1(Angstrom_Input[2], input)) + return caml_call4(succ, input, pos, more, 0); + if(! more) return caml_call4(succ, input, pos, more, 1); + function succ$0(input, pos, more){ + return caml_call4(succ, input, pos, more, 0); + } + function fail(input, pos, more){ + return caml_call4(succ, input, pos, more, 1); + } + return prompt(input, pos, fail, succ$0); + }], + cst_end_of_input = "end_of_input", + end_of_input = + caml_call2 + (symbol_bind, + at_end_of_input, + function(param){ + return param + ? caml_call1(return$0, 0) + : caml_call1(fail, cst_end_of_input); + }), + cst_advance = "advance"; + function advance(n){ + if(0 > n) return caml_call1(fail, cst_advance); + var + p = + [0, + function(input, pos, more, fail, succ){ + return caml_call4(succ, input, pos + n | 0, more, 0); + }]; + return ensure(n, p); + } + var + pos = + [0, + function(input, pos, more, fail, succ){ + return caml_call4(succ, input, pos, more, pos); + }], + available = + [0, + function(input, pos, more, fail, succ){ + return caml_call4 + (succ, + input, + pos, + more, + caml_call1(Angstrom_Input[2], input) - pos | 0); + }], + commit = + [0, + function(input, pos, more, fail, succ){ + caml_call2(Angstrom_Input[16], input, pos); + return caml_call4(succ, input, pos, more, 0); + }]; + function unsafe_lookahead(p){ + return [0, + function(input, pos, more, fail, succ){ + function succ$0(input, param, more, v){ + return caml_call4(succ, input, pos, more, v); + } + return caml_call5(p[1], input, pos, more, fail, succ$0); + }]; + } + var + peek_char = + [0, + function(input, pos, more, fail, succ){ + if(pos < caml_call1(Angstrom_Input[2], input)) + return caml_call4 + (succ, + input, + pos, + more, + [0, caml_call2(Angstrom_Input[7], input, pos)]); + if(0 === more) return caml_call4(succ, input, pos, more, 0); + function succ$0(input, pos, more){ + return caml_call4 + (succ, + input, + pos, + more, + [0, caml_call2(Angstrom_Input[7], input, pos)]); + } + function fail$0(input, pos, more){ + return caml_call4(succ, input, pos, more, 0); + } + return prompt(input, pos, fail$0, succ$0); + }], + peek_char_fail = []; + caml_update_dummy + (peek_char_fail, + [0, + function(input, pos, more, fail, succ){ + if(pos < caml_call1(Angstrom_Input[2], input)) + return caml_call4 + (succ, + input, + pos, + more, + caml_call2(Angstrom_Input[7], input, pos)); + function succ$0(input, pos, more, param){ + return caml_call5(peek_char_fail[1], input, pos, more, fail, succ); + } + return ensure_suspended(1, input, pos, more, fail, succ$0); + }]); + var + _c_ = [0, [11, cst_satisfy, [1, 0]], cst_satisfy_C], + _d_ = [0, [11, cst_satisfy, [1, 0]], cst_satisfy_C], + _e_ = [0, [11, "char ", [1, 0]], "char %C"], + _f_ = [0, [11, "not char ", [1, 0]], "not char %C"]; + function satisfy(f){ + return [0, + function(input, pos, more, fail, succ){ + if(pos >= caml_call1(Angstrom_Input[2], input)){ + var + succ$0 = + function(input, pos, more, param){ + var c = caml_call2(Angstrom_Input[7], input, pos); + if(caml_call1(f, c)) + return caml_call4(succ, input, pos + 1 | 0, more, c); + var _O_ = caml_call4(fail, input, pos, more, 0); + return caml_call3(Stdlib_Printf[10], _O_, _d_, c); + }; + return ensure_suspended(1, input, pos, more, fail, succ$0); + } + var c = caml_call2(Angstrom_Input[7], input, pos); + if(caml_call1(f, c)) + return caml_call4(succ, input, pos + 1 | 0, more, c); + var _N_ = caml_call4(fail, input, pos, more, 0); + return caml_call3(Stdlib_Printf[10], _N_, _c_, c); + }]; + } + function char$0(c){ + var + p = + [0, + function(input, pos, more, fail, succ){ + return caml_call2(Angstrom_Input[7], input, pos) === c + ? caml_call4(succ, input, pos + 1 | 0, more, c) + : caml_call5 + (fail, + input, + pos, + more, + 0, + caml_call2(Stdlib_Printf[4], _e_, c)); + }]; + return ensure(1, p); + } + function not_char(c){ + var + p = + [0, + function(input, pos, more, fail, succ){ + var c$0 = caml_call2(Angstrom_Input[7], input, pos); + return c !== c$0 + ? caml_call4(succ, input, pos + 1 | 0, more, c$0) + : caml_call5 + (fail, + input, + pos, + more, + 0, + caml_call2(Stdlib_Printf[4], _f_, c)); + }]; + return ensure(1, p); + } + var + p = + [0, + function(input, pos, more, fail, succ){ + return caml_call4 + (succ, + input, + pos + 1 | 0, + more, + caml_call2(Angstrom_Input[7], input, pos)); + }], + any_char = ensure(1, p), + _g_ = [0, [11, "int8 ", [4, 0, 0, 0, 0]], "int8 %d"]; + function int8(i){ + var + p = + [0, + function(input, pos, more, fail, succ){ + var c = caml_call2(Angstrom_Input[7], input, pos); + return c === (i & 255) + ? caml_call4(succ, input, pos + 1 | 0, more, c) + : caml_call5 + (fail, + input, + pos, + more, + 0, + caml_call2(Stdlib_Printf[4], _g_, i)); + }]; + return ensure(1, p); + } + var + p$0 = + [0, + function(input, pos, more, fail, succ){ + var c = caml_call2(Angstrom_Input[7], input, pos); + return caml_call4(succ, input, pos + 1 | 0, more, c); + }], + any_uint8 = ensure(1, p$0), + s = Stdlib_Sys[10] - 8 | 0, + p$1 = + [0, + function(input, pos, more, fail, succ){ + var c = caml_call2(Angstrom_Input[7], input, pos); + return caml_call4(succ, input, pos + 1 | 0, more, c << s >> s); + }], + any_int8 = ensure(1, p$1), + cst_skip = "skip", + cst_count_while1 = cst_count_while1$1, + cst_count_while1$0 = cst_count_while1$1, + _h_ = [1, "string"], + cst_take_n_0 = "take: n < 0", + cst_take_bigstring_n_0 = "take_bigstring: n < 0", + cst_no_more_choices = "no more choices"; + function skip(f){ + var + p = + [0, + function(input, pos, more, fail, succ){ + return caml_call1(f, caml_call2(Angstrom_Input[7], input, pos)) + ? caml_call4(succ, input, pos + 1 | 0, more, 0) + : caml_call5(fail, input, pos, more, 0, cst_skip); + }]; + return ensure(1, p); + } + function count_while(init, f, with_buffer){ + return [0, + function(input, pos, more, fail, succ){ + var + len = caml_call3(Angstrom_Input[14], input, pos + init | 0, f), + input_len = caml_call1(Angstrom_Input[2], input), + init$0 = init + len | 0; + if((pos + init$0 | 0) >= input_len && 0 !== more){ + var + succ$0 = + function(input, pos, more){ + return caml_call5 + (count_while(init$0, f, with_buffer)[1], + input, + pos, + more, + fail, + succ); + }, + fail$0 = + function(input, pos, more){ + return caml_call4 + (succ, + input, + pos + init$0 | 0, + more, + caml_call4 + (Angstrom_Input[15], input, pos, init$0, with_buffer)); + }; + return prompt(input, pos, fail$0, succ$0); + } + return caml_call4 + (succ, + input, + pos + init$0 | 0, + more, + caml_call4 + (Angstrom_Input[15], input, pos, init$0, with_buffer)); + }]; + } + function count_while1(f, with_buffer){ + return [0, + function(input, pos, more, fail, succ){ + var + len = caml_call3(Angstrom_Input[14], input, pos, f), + input_len = caml_call1(Angstrom_Input[2], input); + if(1 <= len){ + if((pos + len | 0) >= input_len && 0 !== more){ + var + succ$0 = + function(input, pos, more){ + return caml_call5 + (count_while(len, f, with_buffer)[1], + input, + pos, + more, + fail, + succ); + }, + fail$0 = + function(input, pos, more){ + return caml_call4 + (succ, + input, + pos + len | 0, + more, + caml_call4(Angstrom_Input[15], input, pos, len, with_buffer)); + }; + return prompt(input, pos, fail$0, succ$0); + } + return caml_call4 + (succ, + input, + pos + len | 0, + more, + caml_call4(Angstrom_Input[15], input, pos, len, with_buffer)); + } + if(pos >= input_len && 0 !== more){ + var + succ$1 = + function(input, pos, more){ + return caml_call5 + (count_while1(f, with_buffer)[1], + input, + pos, + more, + fail, + succ); + }, + fail$1 = + function(input, pos, more){ + return caml_call5 + (fail, input, pos, more, 0, cst_count_while1$0); + }; + return prompt(input, pos, fail$1, succ$1); + } + return caml_call5(fail, input, pos, more, 0, cst_count_while1); + }]; + } + function string(f, s){ + var len = caml_ml_string_length(s); + function f$0(buffer, off, len){ + var i = [0, 0]; + for(;;){ + if(i[1] < len){ + var + _L_ = caml_call1(f, runtime.caml_string_unsafe_get(s, i[1])), + _M_ = caml_call1(f, runtime.caml_ba_get_1(buffer, off + i[1] | 0)); + if(caml_call2(Stdlib_Char[8], _M_, _L_)){i[1]++; continue;} + } + return len === i[1] + ? [0, caml_call3(Bigstringaf[7], buffer, off, len)] + : _h_; + } + } + return ensure + (len, + [0, + function(input, pos, more, fail, succ){ + var + match = caml_call4(Angstrom_Input[15], input, pos, len, f$0); + if(0 === match[0]){ + var x = match[1]; + return caml_call4(succ, input, pos + len | 0, more, x); + } + var e = match[1]; + return caml_call5(fail, input, pos, more, 0, e); + }]); + } + function string$0(s){return string(function(x){return x;}, s);} + function string_ci(s){return string(Stdlib_Char[5], s);} + function skip_while(f){ + return count_while(0, f, function(param, _K_, _J_){return 0;}); + } + function take(n){ + if(0 > n) return caml_call1(fail, cst_take_n_0); + var n$0 = caml_call2(Stdlib[17], n, 0); + return ensure(n$0, unsafe_apply(n$0, Bigstringaf[7])); + } + function take_bigstring(n){ + if(0 > n) return caml_call1(fail, cst_take_bigstring_n_0); + var n$0 = caml_call2(Stdlib[17], n, 0); + return ensure(n$0, unsafe_apply(n$0, Bigstringaf[4])); + } + function take_bigstring_while(f){return count_while(0, f, Bigstringaf[4]);} + function take_bigstring_while1(f){return count_while1(f, Bigstringaf[4]);} + function take_bigstring_till(f){ + return take_bigstring_while(function(c){return 1 - caml_call1(f, c);}); + } + function peek_string(n){return unsafe_lookahead(take(n));} + function take_while(f){return count_while(0, f, Bigstringaf[7]);} + function take_while1(f){return count_while1(f, Bigstringaf[7]);} + function take_till(f){ + return take_while(function(c){return 1 - caml_call1(f, c);}); + } + function choice(opt, ps){ + if(opt) + var sth = opt[1], failure_msg = sth; + else + var failure_msg = cst_no_more_choices; + var _I_ = caml_call1(fail, failure_msg); + return caml_call3(Stdlib_List[26], symbol$4, ps, _I_); + } + function fix_direct(f){ + var p = [], r = []; + caml_update_dummy(p, [246, function(_H_){return caml_call1(f, r);}]); + caml_update_dummy + (r, + [0, + function(buf, pos, more, fail, succ){ + var + _F_ = caml_obj_tag(p), + _G_ = + 250 === _F_ + ? p[1] + : 246 === _F_ ? caml_call1(CamlinternalLazy[2], p) : p; + return caml_call5(_G_[1], buf, pos, more, fail, succ); + }]); + return r; + } + function fix_lazy(max_steps, f){ + var steps = [0, max_steps], p = [], r = []; + caml_update_dummy(p, [246, function(_E_){return caml_call1(f, r);}]); + caml_update_dummy + (r, + [0, + function(buf, pos, more, fail, succ){ + steps[1]--; + if(0 <= steps[1]){ + var + _z_ = caml_obj_tag(p), + _A_ = + 250 === _z_ + ? p[1] + : 246 === _z_ ? caml_call1(CamlinternalLazy[2], p) : p; + return caml_call5(_A_[1], buf, pos, more, fail, succ); + } + steps[1] = max_steps; + return [1, + [246, + function(_B_){ + var + _C_ = caml_obj_tag(p), + _D_ = + 250 === _C_ + ? p[1] + : 246 === _C_ ? caml_call1(CamlinternalLazy[2], p) : p; + return caml_call5(_D_[1], buf, pos, more, fail, succ); + }]]; + }]); + return r; + } + var + _i_ = Stdlib_Sys[5], + cst_LE_int64 = "LE.int64", + cst_LE_int32 = "LE.int32", + cst_LE_int16 = "LE.int16", + cst_BE_int64 = "BE.int64", + cst_BE_int32 = "BE.int32", + cst_BE_int16 = "BE.int16", + cst_consumed_parser_committed = "consumed: parser committed", + cst_count_n_0 = "count: n < 0", + cst_end_of_line = "end_of_line", + fix = + typeof _i_ === "number" + ? _i_ ? fix_direct : fix_direct + : function(f){return fix_lazy(20, f);}; + function option(x, p){ + return caml_call2(symbol$4, p, caml_call1(return$0, x)); + } + function cons(x, xs){return [0, x, xs];} + function list(ps){ + if(! ps) return caml_call1(return$0, 0); + var ps$0 = ps[2], p = ps[1]; + return caml_call3(lift2, cons, p, list(ps$0)); + } + function count(n, p){ + if(0 > n) return caml_call1(fail, cst_count_n_0); + function loop(n){ + return 0 === n + ? caml_call1(return$0, 0) + : caml_call3(lift2, cons, p, loop(n - 1 | 0)); + } + return loop(n); + } + function many(p){ + return fix + (function(m){ + var _y_ = caml_call1(return$0, 0); + return caml_call2(symbol$4, caml_call3(lift2, cons, p, m), _y_); + }); + } + function many1(p){return caml_call3(lift2, cons, p, many(p));} + function many_till(p, t){ + return fix + (function(m){ + var _x_ = caml_call3(lift2, cons, p, m); + return caml_call2 + (symbol$4, + caml_call2(symbol$1, t, caml_call1(return$0, 0)), + _x_); + }); + } + function sep_by1(s, p){ + return fix + (function(m){ + var _w_ = caml_call1(return$0, 0); + return caml_call3 + (lift2, + cons, + p, + caml_call2(symbol$4, caml_call2(symbol$1, s, m), _w_)); + }); + } + function sep_by(s, p){ + var _u_ = caml_call1(return$0, 0), _v_ = caml_call1(return$0, 0); + return caml_call2 + (symbol$4, + caml_call3 + (lift2, + cons, + p, + caml_call2 + (symbol$4, caml_call2(symbol$1, s, sep_by1(s, p)), _v_)), + _u_); + } + function skip_many(p){ + return fix + (function(m){ + var _t_ = caml_call1(return$0, 0); + return caml_call2 + (symbol_bind, + caml_call2 + (symbol$4, + caml_call2(symbol_map, p, function(param){return 1;}), + _t_), + function(param){return param ? m : caml_call1(return$0, 0);}); + }); + } + function skip_many1(p){return caml_call2(symbol$1, p, skip_many(p));} + var + _j_ = caml_call1(return$0, 0), + _k_ = caml_call2(symbol$1, string$0(cst), _j_), + _l_ = caml_call1(return$0, 0), + end_of_line = + caml_call2 + (symbol$3, + caml_call2(symbol$4, caml_call2(symbol$1, char$0(10), _l_), _k_), + cst_end_of_line); + function scan(state, f, with_buffer){ + return [0, + function(input, pos, more, fail, succ){ + var + state$0 = [0, state], + parser = + caml_call2 + (symbol_map, + count_while + (0, + function(c){ + var match = caml_call2(f, state$0[1], c); + if(! match) return 0; + var state = match[1]; + state$0[1] = state; + return 1; + }, + with_buffer), + function(x){return [0, x, state$0[1]];}); + return caml_call5(parser[1], input, pos, more, fail, succ); + }]; + } + function scan$0(state, f){return scan(state, f, Bigstringaf[7]);} + function scan_state(state, f){ + return caml_call2 + (symbol_map, + scan(state, f, function(param, _s_, _r_){return 0;}), + function(param){var state = param[2]; return state;}); + } + function scan_string(state, f){ + return caml_call2 + (symbol_map, scan$0(state, f), function(_q_){return _q_[1];}); + } + function consume_with(p, f){ + return [0, + function(input, pos, more, fail, succ){ + var + parser_committed_bytes = caml_call1(Angstrom_Input[4], input); + function succ$0(input, pos$0, more, param){ + if + (parser_committed_bytes + !== caml_call1(Angstrom_Input[4], input)) + return caml_call5 + (fail, input, pos$0, more, 0, cst_consumed_parser_committed); + var + len = pos$0 - pos | 0, + consumed = caml_call4(Angstrom_Input[15], input, pos, len, f); + return caml_call4(succ, input, pos$0, more, consumed); + } + return caml_call5(p[1], input, pos, more, fail, succ$0); + }]; + } + function consumed(p){return consume_with(p, Bigstringaf[7]);} + function consumed_bigstring(p){return consume_with(p, Bigstringaf[4]);} + function both(a, b){ + return caml_call3(lift2, function(a, b){return [0, a, b];}, a, b); + } + function map(t, f){return caml_call2(symbol_map, t, f);} + function bind(t, f){return caml_call2(symbol_bind, t, f);} + function map2(a, b, f){return caml_call3(lift2, f, a, b);} + function map3(a, b, c, f){return caml_call4(lift3, f, a, b, c);} + function map4(a, b, c, d, f){return caml_call5(lift4, f, a, b, c, d);} + var + Let_syntax = [0, return$0, map, bind, both, map2, map3, map4], + Let_syntax$0 = [0, return$0, symbol_map, symbol_bind, Let_syntax]; + function int16(n){ + var + p = + [0, + function(input, pos, more, fail, succ){ + return caml_call2(Angstrom_Input[11], input, pos) === (n & 65535) + ? caml_call4(succ, input, pos + 2 | 0, more, 0) + : caml_call5(fail, input, pos, more, 0, cst_BE_int16); + }]; + return ensure(2, p); + } + function int32(n){ + var + p = + [0, + function(input, pos, more, fail, succ){ + var _p_ = caml_call2(Angstrom_Input[12], input, pos); + return caml_call2(Stdlib_Int32[17], _p_, n) + ? caml_call4(succ, input, pos + 4 | 0, more, 0) + : caml_call5(fail, input, pos, more, 0, cst_BE_int32); + }]; + return ensure(4, p); + } + function int64(n){ + var + p = + [0, + function(input, pos, more, fail, succ){ + var _o_ = caml_call2(Angstrom_Input[13], input, pos); + return caml_call2(Stdlib_Int64[17], _o_, n) + ? caml_call4(succ, input, pos + 8 | 0, more, 0) + : caml_call5(fail, input, pos, more, 0, cst_BE_int64); + }]; + return ensure(8, p); + } + var + any_uint16 = + ensure + (2, + unsafe_apply + (2, + function(bs, off, param){ + return caml_call2(Bigstringaf[31], bs, off); + })), + any_int16 = + ensure + (2, + unsafe_apply + (2, + function(bs, off, param){ + return caml_call2(Bigstringaf[33], bs, off); + })), + any_int32 = + ensure + (4, + unsafe_apply + (4, + function(bs, off, param){ + return caml_call2(Bigstringaf[37], bs, off); + })), + any_int64 = + ensure + (8, + unsafe_apply + (8, + function(bs, off, param){ + return caml_call2(Bigstringaf[41], bs, off); + })), + any_float = + ensure + (4, + unsafe_apply + (4, + function(bs, off, param){ + return caml_int32_float_of_bits + (caml_call2(Bigstringaf[37], bs, off)); + })), + any_double = + ensure + (8, + unsafe_apply + (8, + function(bs, off, param){ + return caml_int64_float_of_bits + (caml_call2(Bigstringaf[41], bs, off)); + })); + function int16$0(n){ + var + p = + [0, + function(input, pos, more, fail, succ){ + return caml_call2(Angstrom_Input[8], input, pos) === (n & 65535) + ? caml_call4(succ, input, pos + 2 | 0, more, 0) + : caml_call5(fail, input, pos, more, 0, cst_LE_int16); + }]; + return ensure(2, p); + } + function int32$0(n){ + var + p = + [0, + function(input, pos, more, fail, succ){ + var _n_ = caml_call2(Angstrom_Input[9], input, pos); + return caml_call2(Stdlib_Int32[17], _n_, n) + ? caml_call4(succ, input, pos + 4 | 0, more, 0) + : caml_call5(fail, input, pos, more, 0, cst_LE_int32); + }]; + return ensure(4, p); + } + function int64$0(n){ + var + p = + [0, + function(input, pos, more, fail, succ){ + var _m_ = caml_call2(Angstrom_Input[10], input, pos); + return caml_call2(Stdlib_Int64[17], _m_, n) + ? caml_call4(succ, input, pos + 8 | 0, more, 0) + : caml_call5(fail, input, pos, more, 0, cst_LE_int64); + }]; + return ensure(8, p); + } + var + any_uint16$0 = + ensure + (2, + unsafe_apply + (2, + function(bs, off, param){ + return caml_call2(Bigstringaf[30], bs, off); + })), + any_int16$0 = + ensure + (2, + unsafe_apply + (2, + function(bs, off, param){ + return caml_call2(Bigstringaf[32], bs, off); + })), + any_int32$0 = + ensure + (4, + unsafe_apply + (4, + function(bs, off, param){ + return caml_call2(Bigstringaf[36], bs, off); + })), + any_int64$0 = + ensure + (8, + unsafe_apply + (8, + function(bs, off, param){ + return caml_call2(Bigstringaf[40], bs, off); + })), + any_float$0 = + ensure + (4, + unsafe_apply + (4, + function(bs, off, param){ + return caml_int32_float_of_bits + (caml_call2(Bigstringaf[36], bs, off)); + })), + any_double$0 = + ensure + (8, + unsafe_apply + (8, + function(bs, off, param){ + return caml_int64_float_of_bits + (caml_call2(Bigstringaf[40], bs, off)); + })); + function take$0(n, f){ + var n$0 = caml_call2(Stdlib[17], n, 0); + return ensure(n$0, unsafe_apply(n$0, f)); + } + function peek(n, f){return unsafe_lookahead(take$0(n, f));} + function take_while$0(check, f){return count_while(0, check, f);} + function take_while1$0(check, f){return count_while1(check, f);} + function take_till$0(check, f){ + return take_while$0(function(c){return 1 - caml_call1(check, c);}, f); + } + var Consume = [0]; + function parse_bigstring$0(consume, p, bs){ + var p$0 = consume ? caml_call2(symbol$2, p, end_of_input) : p; + return caml_call2(parse_bigstring, p$0, bs); + } + function parse_string(consume, p, s){ + var len = caml_ml_string_length(s), bs = caml_call1(Bigstringaf[1], len); + caml_call5(Bigstringaf[45], s, 0, bs, 0, len); + return parse_bigstring$0(consume, p, bs); + } + var + Angstrom = + [0, + peek_char, + peek_char_fail, + peek_string, + char$0, + not_char, + any_char, + satisfy, + string$0, + string_ci, + skip, + skip_while, + take, + take_while, + take_while1, + take_till, + consumed, + take_bigstring, + take_bigstring_while, + take_bigstring_while1, + take_bigstring_till, + consumed_bigstring, + advance, + end_of_line, + at_end_of_input, + end_of_input, + scan$0, + scan_state, + scan_string, + int8, + any_uint8, + any_int8, + [0, + int16, + int32, + int64, + any_int16, + any_int32, + any_int64, + any_uint16, + any_float, + any_double], + [0, + int16$0, + int32$0, + int64$0, + any_int16$0, + any_int32$0, + any_int64$0, + any_uint16$0, + any_float$0, + any_double$0], + option, + both, + list, + count, + many, + many1, + many_till, + sep_by, + sep_by1, + skip_many, + skip_many1, + fix, + fix_lazy, + symbol$4, + choice, + symbol$3, + commit, + return$0, + fail, + symbol_bind, + bind, + symbol_map, + symbol$0, + symbol, + symbol$1, + symbol$2, + lift, + lift2, + lift3, + lift4, + map, + map2, + map3, + map4, + Let_syntax$0, + symbol_map, + symbol_bind, + both, + [0, take$0, take_while$0, take_while1$0, take_till$0, peek], + Consume, + parse_bigstring$0, + parse_string, + [0, + parse$0, + feed, + state_to_option$0, + state_to_result$0, + state_to_unconsumed], + [0, parse, state_to_option, state_to_result], + pos, + available]; + runtime.caml_register_global(42, Angstrom, "Angstrom"); + return; + } + (globalThis)); + + +//# 1 "../.js/default/zarith/zarith.cma.js" +// Generated by js_of_ocaml +//# 3 "../.js/default/zarith/zarith.cma.js" + + +//# 1 "../.js/default/exenum.internals/exenum_internals.cma.js" +// Generated by js_of_ocaml +//# 3 "../.js/default/exenum.internals/exenum_internals.cma.js" + + +//# 1 "../.js/default/exenum/exenum.cma.js" +// Generated by js_of_ocaml +//# 3 "../.js/default/exenum/exenum.cma.js" + + +//# 1 ".uiml_demo.eobjs/jsoo/dune__exe.cmo.js" +// Generated by js_of_ocaml +//# 3 ".uiml_demo.eobjs/jsoo/dune__exe.cmo.js" + +//# 5 ".uiml_demo.eobjs/jsoo/dune__exe.cmo.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime, Dune_exe = [0]; + runtime.caml_register_global(0, Dune_exe, "Dune__exe"); + return; + } + (globalThis)); + + +//# 1 ".uiml_demo.eobjs/jsoo/dune__exe__Stringconversion.cmo.js" +// Generated by js_of_ocaml +//# 3 ".uiml_demo.eobjs/jsoo/dune__exe__Stringconversion.cmo.js" + +//# 6 ".uiml_demo.eobjs/jsoo/dune__exe__Stringconversion.cmo.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + var + global_data = runtime.caml_get_global_data(), + Stdlib_List = global_data.Stdlib__List, + Stdlib_Bytes = global_data.Stdlib__Bytes; + function camlstring_of_coqstring(s){ + var + r = runtime.caml_create_bytes(caml_call1(Stdlib_List[1], s)), + pos = 0, + param = s; + for(;;){ + if(! param) return caml_call1(Stdlib_Bytes[6], r); + var s$0 = param[2], c = param[1]; + runtime.caml_bytes_set(r, pos, c); + var pos$0 = pos + 1 | 0; + pos = pos$0; + param = s$0; + } + } + function coqstring_of_camlstring(s){ + var + pos$1 = runtime.caml_ml_string_length(s) - 1 | 0, + accu = 0, + pos = pos$1; + for(;;){ + if(0 > pos) return accu; + var + pos$0 = pos - 1 | 0, + accu$0 = [0, runtime.caml_string_get(s, pos), accu]; + accu = accu$0; + pos = pos$0; + } + } + var + Dune_exe_Stringconversion = + [0, camlstring_of_coqstring, coqstring_of_camlstring]; + runtime.caml_register_global + (2, Dune_exe_Stringconversion, "Dune__exe__Stringconversion"); + return; + } + (globalThis)); + + +//# 1 ".uiml_demo.eobjs/jsoo/dune__exe__Modal_expressions_parser.cmo.js" +// Generated by js_of_ocaml +//# 3 ".uiml_demo.eobjs/jsoo/dune__exe__Modal_expressions_parser.cmo.js" + +//# 6 ".uiml_demo.eobjs/jsoo/dune__exe__Modal_expressions_parser.cmo.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + function caml_call3(f, a0, a1, a2){ + return (f.l >= 0 ? f.l : f.l = f.length) == 3 + ? f(a0, a1, a2) + : runtime.caml_call_gen(f, [a0, a1, a2]); + } + var + global_data = runtime.caml_get_global_data(), + Angstrom = global_data.Angstrom, + Dune_exe_Stringconversion = global_data.Dune__exe__Stringconversion, + Stdlib = global_data.Stdlib; + function is_space(param){ + a: + { + if(11 <= param){if(32 === param) break a;} else if(9 <= param) break a; + return 0; + } + return 1; + } + var spaces = caml_call1(Angstrom[11], is_space); + function parens(p){ + var + _aZ_ = caml_call1(Angstrom[4], 41), + _a0_ = caml_call1(Angstrom[4], 40), + _a1_ = caml_call2(Angstrom[58], _a0_, p); + return caml_call2(Angstrom[59], _a1_, _aZ_); + } + function box(p){ + var + _aO_ = caml_call1(Angstrom[4], 161), + _aP_ = caml_call1(Angstrom[4], 150), + _aQ_ = caml_call1(Angstrom[4], 226), + _aR_ = caml_call2(Angstrom[58], _aQ_, _aP_), + _aS_ = caml_call2(Angstrom[58], _aR_, _aO_), + _aT_ = caml_call1(Angstrom[4], 93), + _aU_ = caml_call1(Angstrom[4], 91), + _aV_ = caml_call2(Angstrom[58], _aU_, _aT_), + _aW_ = caml_call2(Angstrom[47], _aV_, _aS_), + _aX_ = caml_call2(Angstrom[58], _aW_, spaces), + _aY_ = caml_call2(Angstrom[58], _aX_, p); + return caml_call2(Angstrom[55], _aY_, function(x){return [4, x];}); + } + function diamond(p){ + var + _aD_ = caml_call1(Angstrom[4], 132), + _aE_ = caml_call1(Angstrom[4], 139), + _aF_ = caml_call1(Angstrom[4], 226), + _aG_ = caml_call2(Angstrom[58], _aF_, _aE_), + _aH_ = caml_call2(Angstrom[58], _aG_, _aD_), + _aI_ = caml_call1(Angstrom[4], 62), + _aJ_ = caml_call1(Angstrom[4], 60), + _aK_ = caml_call2(Angstrom[58], _aJ_, _aI_), + _aL_ = caml_call2(Angstrom[47], _aK_, _aH_), + _aM_ = caml_call2(Angstrom[58], _aL_, spaces), + _aN_ = caml_call2(Angstrom[58], _aM_, p); + return caml_call2 + (Angstrom[55], _aN_, function(x){return [3, [4, [3, x, 0]], 0];}); + } + function neg(p){ + var + _aw_ = caml_call1(Angstrom[4], 172), + _ax_ = caml_call1(Angstrom[4], 194), + _ay_ = caml_call2(Angstrom[58], _ax_, _aw_), + _az_ = caml_call1(Angstrom[4], 126), + _aA_ = caml_call2(Angstrom[47], _az_, _ay_), + _aB_ = caml_call2(Angstrom[58], _aA_, spaces), + _aC_ = caml_call2(Angstrom[58], _aB_, p); + return caml_call2(Angstrom[55], _aC_, function(x){return [3, x, 0];}); + } + var + _a_ = caml_call1(Angstrom[51], function(x, y){return [2, x, y];}), + _b_ = caml_call1(Angstrom[4], 124), + _c_ = caml_call1(Angstrom[4], 168), + _d_ = caml_call1(Angstrom[4], 136), + _e_ = caml_call1(Angstrom[4], 226), + _f_ = caml_call2(Angstrom[58], _e_, _d_), + _g_ = caml_call2(Angstrom[58], _f_, _c_), + _h_ = caml_call2(Angstrom[47], _g_, _b_), + _i_ = caml_call2(Angstrom[58], spaces, _h_), + _j_ = caml_call2(Angstrom[58], _i_, spaces), + disj = caml_call2(Angstrom[58], _j_, _a_), + _k_ = caml_call1(Angstrom[51], function(x, y){return [1, x, y];}), + _l_ = caml_call1(Angstrom[4], 38), + _m_ = caml_call1(Angstrom[4], 167), + _n_ = caml_call1(Angstrom[4], 136), + _o_ = caml_call1(Angstrom[4], 226), + _p_ = caml_call2(Angstrom[58], _o_, _n_), + _q_ = caml_call2(Angstrom[58], _p_, _m_), + _r_ = caml_call2(Angstrom[47], _q_, _l_), + _s_ = caml_call2(Angstrom[58], spaces, _r_), + _t_ = caml_call2(Angstrom[58], _s_, spaces), + conj = caml_call2(Angstrom[58], _t_, _k_); + function modal(p){ + var + _as_ = diamond(p), + _at_ = neg(p), + _au_ = box(p), + _av_ = caml_call2(Angstrom[47], _au_, _at_); + return caml_call2(Angstrom[47], _av_, _as_); + } + var + _u_ = caml_call1(Angstrom[51], function(x, y){return [3, x, y];}), + _v_ = caml_call1(Angstrom[4], 62), + _w_ = caml_call1(Angstrom[4], 45), + _x_ = caml_call2(Angstrom[58], _w_, _v_), + _y_ = caml_call1(Angstrom[4], 146), + _z_ = caml_call1(Angstrom[4], 134), + _A_ = caml_call1(Angstrom[4], 226), + _B_ = caml_call2(Angstrom[58], _A_, _z_), + _C_ = caml_call2(Angstrom[58], _B_, _y_), + _D_ = caml_call2(Angstrom[47], _C_, _x_), + _E_ = caml_call2(Angstrom[58], spaces, _D_), + _F_ = caml_call2(Angstrom[58], _E_, spaces), + impl = caml_call2(Angstrom[58], _F_, _u_), + _G_ = caml_call1(Angstrom[51], 0), + _H_ = caml_call1(Angstrom[4], 70), + _I_ = caml_call1(Angstrom[4], 35), + _J_ = caml_call1(Angstrom[4], 165), + _K_ = caml_call1(Angstrom[4], 138), + _L_ = caml_call1(Angstrom[4], 226), + _M_ = caml_call2(Angstrom[58], _L_, _K_), + _N_ = caml_call2(Angstrom[58], _M_, _J_), + _O_ = caml_call2(Angstrom[47], _N_, _I_), + _P_ = caml_call2(Angstrom[47], _O_, _H_), + _Q_ = caml_call2(Angstrom[58], spaces, _P_), + _R_ = caml_call2(Angstrom[58], _Q_, spaces), + bot = caml_call2(Angstrom[58], _R_, _G_), + _S_ = caml_call1(Angstrom[51], [3, 0, 0]), + _T_ = caml_call1(Angstrom[4], 84), + _U_ = caml_call1(Angstrom[4], 164), + _V_ = caml_call1(Angstrom[4], 138), + _W_ = caml_call1(Angstrom[4], 226), + _X_ = caml_call2(Angstrom[58], _W_, _V_), + _Y_ = caml_call2(Angstrom[58], _X_, _U_), + _Z_ = caml_call2(Angstrom[47], _Y_, _T_), + ___ = caml_call2(Angstrom[58], spaces, _Z_), + _$_ = caml_call2(Angstrom[58], ___, spaces), + top = caml_call2(Angstrom[58], _$_, _S_); + function letter(param){return 25 < param - 97 >>> 0 ? 0 : 1;} + function letter_or_digit(param){ + var _ar_ = param - 48 | 0; + a: + { + if(42 < _ar_ >>> 0){ + if(25 < _ar_ - 49 >>> 0) break a; + } + else if(6 >= _ar_ - 10 >>> 0) break a; + return 1; + } + return 0; + } + var + _aa_ = caml_call1(Angstrom[13], letter_or_digit), + _ab_ = caml_call1(Angstrom[14], letter), + _ac_ = caml_call3(Angstrom[61], Stdlib[28], _ab_, _aa_), + identifier = + caml_call2 + (Angstrom[55], + _ac_, + function(x){return [0, caml_call1(Dune_exe_Stringconversion[2], x)];}); + function chainl1(e, op){ + function go(acc){ + var + _ao_ = caml_call1(Angstrom[51], acc), + _ap_ = + caml_call3 + (Angstrom[61], function(f, x){return caml_call2(f, acc, x);}, op, e), + _aq_ = caml_call2(Angstrom[53], _ap_, go); + return caml_call2(Angstrom[47], _aq_, _ao_); + } + return caml_call2(Angstrom[53], e, function(init){return go(init);}); + } + function chainr1(e, op){ + function go(acc){ + var + _al_ = caml_call1(Angstrom[51], acc), + _am_ = caml_call2(Angstrom[53], e, go), + _an_ = + caml_call3 + (Angstrom[61], + function(f, x){return caml_call2(f, acc, x);}, + op, + _am_); + return caml_call2(Angstrom[47], _an_, _al_); + } + return caml_call2(Angstrom[53], e, go); + } + function chainmod(e, op){ + return caml_call1 + (Angstrom[45], + function(x){ + var _ak_ = caml_call1(op, x); + return caml_call2(Angstrom[47], _ak_, e); + }); + } + var + expr = + caml_call1 + (Angstrom[45], + function(expr){ + var + _ad_ = parens(expr), + _ae_ = caml_call2(Angstrom[47], _ad_, identifier), + _af_ = caml_call2(Angstrom[47], _ae_, bot), + factor = caml_call2(Angstrom[47], _af_, top), + modality = chainmod(factor, modal), + term = chainl1(modality, conj), + _ag_ = chainl1(term, disj), + _ah_ = caml_call2(Angstrom[58], spaces, _ag_), + disjunctions = caml_call2(Angstrom[59], _ah_, spaces), + _ai_ = chainr1(disjunctions, impl), + _aj_ = caml_call2(Angstrom[58], spaces, _ai_); + return caml_call2(Angstrom[59], _aj_, spaces); + }), + ParseError = + [248, + "Dune__exe__Modal_expressions_parser.ParseError", + runtime.caml_fresh_oo_id(0)]; + function eval$0(str){ + var match = caml_call3(Angstrom[75], 1, expr, str); + if(0 !== match[0]) throw caml_maybe_attach_backtrace(ParseError, 1); + var v = match[1]; + return v; + } + var + Dune_exe_Modal_expressions_par = + [0, + is_space, + spaces, + parens, + box, + diamond, + neg, + disj, + conj, + modal, + impl, + bot, + top, + letter, + letter_or_digit, + identifier, + chainl1, + chainr1, + chainmod, + expr, + ParseError, + eval$0]; + runtime.caml_register_global + (5, Dune_exe_Modal_expressions_par, "Dune__exe__Modal_expressions_parser"); + return; + } + (globalThis)); + + +//# 1 ".uiml_demo.eobjs/jsoo/dune__exe__Printer.cmo.js" +// Generated by js_of_ocaml +//# 3 ".uiml_demo.eobjs/jsoo/dune__exe__Printer.cmo.js" + +//# 6 ".uiml_demo.eobjs/jsoo/dune__exe__Printer.cmo.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime, cst$10 = "\xe2\x8b\x84 "; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + var + global_data = runtime.caml_get_global_data(), + cst = "\xe2\x8a\xa5", + cst$0 = " \xe2\x88\xa7 ", + cst$1 = " \xe2\x88\xa8 ", + cst$2 = "\xe2\x8a\xa4", + cst$5 = cst$10, + cst$4 = "\xc2\xac ", + cst$3 = " \xe2\x86\x92 ", + cst$6 = "\xe2\x96\xa1 ", + cst$9 = cst$10, + cst$7 = ")", + cst$8 = "(", + Dune_exe_Stringconversion = global_data.Dune__exe__Stringconversion, + Stdlib = global_data.Stdlib; + function int_of_nat(param){ + if(! param) return 0; + var n = param[1]; + return 1 + int_of_nat(n) | 0; + } + function string_of_formula(opt){ + if(opt) var sth = opt[1], classical = sth; else var classical = 0; + function string_of_formula(param){ + var param$0 = param; + for(;;){ + if(typeof param$0 === "number") return cst; + a: + switch(param$0[0]){ + case 0: + var v = param$0[1]; + return caml_call1(Dune_exe_Stringconversion[1], v); + case 1: + var + g = param$0[2], + f = param$0[1], + _f_ = bracket(g), + _g_ = caml_call2(Stdlib[28], cst$0, _f_), + _h_ = bracket(f); + return caml_call2(Stdlib[28], _h_, _g_); + case 2: + var + g$0 = param$0[2], + f$0 = param$0[1], + _i_ = bracket(g$0), + _j_ = caml_call2(Stdlib[28], cst$1, _i_), + _k_ = bracket(f$0); + return caml_call2(Stdlib[28], _k_, _j_); + case 3: + var f$1 = param$0[1]; + b: + if(typeof f$1 === "number"){ + if(typeof param$0[2] === "number") return cst$2; + } + else{ + switch(f$1[0]){ + case 3: + if(typeof f$1[2] === "number"){ + if(typeof param$0[2] !== "number") break b; + var f$2 = f$1[1]; + if(classical){param$0 = f$2; break a;} + } + break; + case 4: + var _p_ = f$1[1]; + if(typeof _p_ !== "number" && 3 === _p_[0]){ + if(typeof _p_[2] !== "number") break; + if(typeof param$0[2] !== "number") break b; + var f$3 = _p_[1]; + if(! classical) break; + var _q_ = bracket(f$3); + return caml_call2(Stdlib[28], cst$5, _q_); + } + break; + } + if(typeof param$0[2] === "number"){ + var _o_ = bracket(f$1); + return caml_call2(Stdlib[28], cst$4, _o_); + } + } + var + g$1 = param$0[2], + _l_ = bracket(g$1), + _m_ = caml_call2(Stdlib[28], cst$3, _l_), + _n_ = bracket(f$1); + return caml_call2(Stdlib[28], _n_, _m_); + default: + var f$4 = param$0[1], _r_ = bracket(f$4); + return caml_call2(Stdlib[28], cst$6, _r_); + } + } + } + function bracket(e){ + var e$0 = e; + for(;;){ + a: + if(typeof e$0 !== "number"){ + b: + switch(e$0[0]){ + case 3: + var _c_ = e$0[1]; + if(typeof _c_ !== "number") + switch(_c_[0]){ + case 3: + if(typeof _c_[2] === "number"){ + if(typeof e$0[2] !== "number") break b; + var f = _c_[1]; + if(classical){e$0 = f; continue;} + } + break; + case 4: + var _d_ = _c_[1]; + if(typeof _d_ !== "number" && 3 === _d_[0]){ + if(typeof _d_[2] !== "number") break; + if(typeof e$0[2] !== "number") break b; + var f$0 = _d_[1]; + if(! classical) break; + var _e_ = bracket(f$0); + return caml_call2(Stdlib[28], cst$9, _e_); + } + break; + } + if(typeof e$0[2] === "number") break a; + break; + case 1: + case 2: break; + default: break a; + } + var + _a_ = string_of_formula(e$0), + _b_ = caml_call2(Stdlib[28], _a_, cst$7); + return caml_call2(Stdlib[28], cst$8, _b_); + } + return string_of_formula(e$0); + } + } + return string_of_formula; + } + var Dune_exe_Printer = [0, int_of_nat, string_of_formula]; + runtime.caml_register_global(13, Dune_exe_Printer, "Dune__exe__Printer"); + return; + } + (globalThis)); + + +//# 1 ".uiml_demo.eobjs/jsoo/dune__exe__Uiml_demo.cmo.js" +// Generated by js_of_ocaml +//# 3 ".uiml_demo.eobjs/jsoo/dune__exe__Uiml_demo.cmo.js" + +//# 6 ".uiml_demo.eobjs/jsoo/dune__exe__Uiml_demo.cmo.js" +(function + (globalThis){ + "use strict"; + var + runtime = globalThis.jsoo_runtime, + cst_Error$1 = "Error: ", + caml_js_wrap_meth_callback = runtime.caml_js_wrap_meth_callback, + caml_wrap_exception = runtime.caml_wrap_exception; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + function caml_call2(f, a0, a1){ + return (f.l >= 0 ? f.l : f.l = f.length) == 2 + ? f(a0, a1) + : runtime.caml_call_gen(f, [a0, a1]); + } + var + undef = undefined, + global_data = runtime.caml_get_global_data(), + Dune_exe_Modal_expressions_par = + global_data.Dune__exe__Modal_expressions_parser, + UIML_UIML_extraction = global_data.UIML__UIML_extraction, + Dune_exe_Printer = global_data.Dune__exe__Printer; + global_data.CamlinternalOO; + var + Stdlib = global_data.Stdlib, + Stdlib_Printexc = global_data.Stdlib__Printexc, + Dune_exe_Stringconversion = global_data.Dune__exe__Stringconversion, + Js_of_ocaml_Js = global_data.Js_of_ocaml__Js, + cst_Parse_Error = "Parse Error", + cst_Error = cst_Error$1, + cst_Error$0 = cst_Error$1, + cst_The_provided_formula_conta = + "The provided formula contains modalities"; + function catch_e(f){ + try{var _q_ = caml_call1(f, 0); return _q_;} + catch(e$0){ + var e = caml_wrap_exception(e$0); + if(e === Dune_exe_Modal_expressions_par[20]) return cst_Parse_Error; + if(e[1] === Stdlib[7]){ + var s = e[2]; + return caml_call2(Stdlib[28], cst_Error, s); + } + var _p_ = caml_call1(Stdlib_Printexc[1], e); + return caml_call2(Stdlib[28], cst_Error$0, _p_); + } + } + function fail_on_modality(f){ + function aux(param){ + var param$0 = param; + for(;;){ + if(typeof param$0 !== "number") + switch(param$0[0]){ + case 4: + return caml_call1(Stdlib[2], cst_The_provided_formula_conta); + case 0: break; + default: + var y = param$0[2], x = param$0[1]; aux(x); param$0 = y; continue; + } + return; + } + } + aux(f); + return f; + } + var + v = caml_call1(Dune_exe_Stringconversion[2], "p"), + _a_ = [0, 1], + _b_ = [0, 1]; + function t13(param, s){ + return catch_e + (function(param){ + var _o_ = caml_call1(Dune_exe_Modal_expressions_par[21], s); + return caml_call2(Dune_exe_Printer[2], 0, _o_); + }); + } + function t12(param, s){ + return catch_e + (function(param){ + var + _m_ = caml_call1(Dune_exe_Modal_expressions_par[21], s), + _n_ = caml_call1(caml_call1(UIML_UIML_extraction[4], v), _m_); + return caml_call1(caml_call1(Dune_exe_Printer[2], _a_), _n_); + }); + } + function t11(param, s){ + return catch_e + (function(param){ + var + _k_ = caml_call1(Dune_exe_Modal_expressions_par[21], s), + _l_ = caml_call1(caml_call1(UIML_UIML_extraction[3], v), _k_); + return caml_call1(caml_call1(Dune_exe_Printer[2], _b_), _l_); + }); + } + function t10(param, s){ + return catch_e + (function(param){ + var + _i_ = caml_call1(Dune_exe_Modal_expressions_par[21], s), + _j_ = caml_call1(caml_call1(UIML_UIML_extraction[8], v), _i_); + return caml_call2(Dune_exe_Printer[2], 0, _j_); + }); + } + function t9(param, s){ + return catch_e + (function(param){ + var + _g_ = caml_call1(Dune_exe_Modal_expressions_par[21], s), + _h_ = caml_call1(caml_call1(UIML_UIML_extraction[9], v), _g_); + return caml_call2(Dune_exe_Printer[2], 0, _h_); + }); + } + function t8(param, s){ + return catch_e + (function(param){ + var + _e_ = + fail_on_modality + (caml_call1(Dune_exe_Modal_expressions_par[21], s)), + _f_ = caml_call1(caml_call1(UIML_UIML_extraction[5], v), _e_); + return caml_call2(Dune_exe_Printer[2], 0, _f_); + }); + } + function t7(param, s){ + return catch_e + (function(param){ + var + _c_ = + fail_on_modality + (caml_call1(Dune_exe_Modal_expressions_par[21], s)), + _d_ = caml_call1(caml_call1(UIML_UIML_extraction[6], v), _c_); + return caml_call2(Dune_exe_Printer[2], 0, _d_); + }); + } + caml_call2 + (Js_of_ocaml_Js[50], + "UIML", + {iA: caml_js_wrap_meth_callback(t7), + iE: caml_js_wrap_meth_callback(t8), + islA: caml_js_wrap_meth_callback(t9), + islE: caml_js_wrap_meth_callback(t10), + k: caml_js_wrap_meth_callback(t11), + gl: caml_js_wrap_meth_callback(t12), + parse: caml_js_wrap_meth_callback(t13)}); + var Dune_exe_Uiml_demo = [0]; + runtime.caml_register_global + (26, Dune_exe_Uiml_demo, "Dune__exe__Uiml_demo"); + return; + } + (globalThis)); + + +//# 1 "../.js/default/stdlib/std_exit.cmo.js" +// Generated by js_of_ocaml +//# 3 "../.js/default/stdlib/std_exit.cmo.js" + +//# 6 "../.js/default/stdlib/std_exit.cmo.js" +(function + (globalThis){ + "use strict"; + var runtime = globalThis.jsoo_runtime; + function caml_call1(f, a0){ + return (f.l >= 0 ? f.l : f.l = f.length) == 1 + ? f(a0) + : runtime.caml_call_gen(f, [a0]); + } + var + global_data = runtime.caml_get_global_data(), + Stdlib = global_data.Stdlib; + caml_call1(Stdlib[103], 0); + var Std_exit = [0]; + runtime.caml_register_global(1, Std_exit, "Std_exit"); + return; + } + (globalThis)); + + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLjAsImZpbGUiOiJ1aW1sX2RlbW8uYmMuanMiLCJzb3VyY2VSb290IjoiIiwibmFtZXMiOlsiY2FtbF9zdWJhcnJheV90b19qc2J5dGVzIiwiYSIsImkiLCJsZW4iLCJmIiwiU3RyaW5nIiwibnVsbCIsInMiLCJNYXRoIiwiY2FtbF9zdHJpbmdfb2ZfanNieXRlcyIsIngiLCJjYW1sX3N0cmluZ19vZl9hcnJheSIsImNhbWxfYmFfZ2V0XzEiLCJiYSIsImkwIiwiQmlnU3RyaW5nUmVhZGVyIiwiYnMiLCJ0aGlzIiwiYXJyIiwiQXJyYXkiLCJqIiwib2Zmc2V0IiwiY2FtbF9zdHJfcmVwZWF0IiwibiIsInIiLCJsIiwiY2FtbF9jb252ZXJ0X3N0cmluZ190b19ieXRlcyIsImpzb29faXNfYXNjaWkiLCJjYW1sX3V0ZjE2X29mX3V0ZjgiLCJiIiwidCIsImMiLCJjMSIsImMyIiwidiIsIk1sQnl0ZXMiLCJ0YWciLCJjb250ZW50cyIsImxlbmd0aCIsImNvbnRlbnQiLCJjYW1sX3V0Zjhfb2ZfdXRmMTYiLCJkIiwiY2FtbF9zdHJpbmdfb2ZfanNzdHJpbmciLCJ1bml4X2Vycm9yIiwibWFrZV91bml4X2Vycl9hcmdzIiwiY29kZSIsInN5c2NhbGwiLCJwYXRoIiwiZXJybm8iLCJ2YXJpYW50IiwiYXJncyIsImNhbWxfbmFtZWRfdmFsdWVzIiwiY2FtbF9uYW1lZF92YWx1ZSIsIm5tIiwianNvb19zeXNfZ2V0ZW52IiwicHJvY2VzcyIsImdsb2JhbFRoaXMiLCJ1bmRlZmluZWQiLCJjYW1sX3JlY29yZF9iYWNrdHJhY2VfZmxhZyIsImNhbWxfZ2xvYmFsX2RhdGEiLCJjYW1sX2V4bl93aXRoX2pzX2JhY2t0cmFjZSIsImV4biIsImZvcmNlIiwiY2FtbF9tYXliZV9hdHRhY2hfYmFja3RyYWNlIiwiY2FtbF9yYWlzZV93aXRoX2FyZ3MiLCJjYW1sX2lzX21sX2J5dGVzIiwiY2FtbF9pc19tbF9zdHJpbmciLCJjYW1sX2J5dGVzX29mX2FycmF5IiwiVWludDhBcnJheSIsImNhbWxfYnl0ZXNfb2ZfanNieXRlcyIsImNhbWxfanNieXRlc19vZl9zdHJpbmciLCJjYW1sX2J5dGVzX29mX3N0cmluZyIsImNhbWxfcmFpc2Vfd2l0aF9hcmciLCJhcmciLCJjYW1sX3JhaXNlX3dpdGhfc3RyaW5nIiwibXNnIiwiY2FtbF9yYWlzZV9zeXNfZXJyb3IiLCJjYW1sX3JhaXNlX25vX3N1Y2hfZmlsZSIsIm5hbWUiLCJjYW1sX2NvbnZlcnRfYnl0ZXNfdG9fYXJyYXkiLCJjYW1sX3VpbnQ4X2FycmF5X29mX2J5dGVzIiwiY2FtbF9pbnZhbGlkX2FyZ3VtZW50IiwiY2FtbF9jcmVhdGVfYnl0ZXMiLCJjYW1sX21sX2J5dGVzX2xlbmd0aCIsImNhbWxfYmxpdF9ieXRlcyIsInMxIiwiaTEiLCJzMiIsImkyIiwiTWxGaWxlIiwiTWxGYWtlRmlsZSIsIm9sZCIsImJ1ZiIsInBvcyIsImNsZW4iLCJuZXdfc3RyIiwib2xkX2RhdGEiLCJkYXRhIiwiTWxGYWtlRmQiLCJmaWxlIiwiZmxhZ3MiLCJNbEZha2VEZXZpY2UiLCJyb290IiwiY29tcCIsInJlcyIsIlN5bWJvbCIsIm5hbWVfc2xhc2giLCJtb2RlIiwicmFpc2VfdW5peCIsInBhcmVudCIsIlJlZ0V4cCIsInNlZW4iLCJtIiwiZW50cnkiLCJvayIsImJ5dGVzIiwiTWxGYWtlRmRfb3V0IiwiZmQiLCJjb25zb2xlIiwic3JjIiwiY2FtbF9pbnQ2NF9vZmZzZXQiLCJjYW1sX3JhaXNlX2NvbnN0YW50IiwiY2FtbF9yYWlzZV96ZXJvX2RpdmlkZSIsIk1sSW50NjQiLCJsbyIsIm1pIiwiaGkiLCJ4aGkiLCJoIiwic2lnbiIsIm1vZHVsdXMiLCJkaXZpc29yIiwicXVvdGllbnQiLCJ5IiwicSIsIk1sTXV0ZXgiLCJNbE5hdCIsIkludDMyQXJyYXkiLCJjYW1sX21sX3N0cmluZ19sZW5ndGgiLCJjYW1sX3N0cmluZ191bnNhZmVfZ2V0IiwiY2FtbF91aW50OF9hcnJheV9vZl9zdHJpbmciLCJjYW1sX2J5dGVzX2JvdW5kX2Vycm9yIiwiY2FtbF9ieXRlc191bnNhZmVfc2V0IiwiY2FtbF9ieXRlc19zZXQiLCJNbE5vZGVGZCIsInJlcXVpcmUiLCJlcnIiLCJidWZfb2Zmc2V0IiwicmVhZCIsIk1sTm9kZURldmljZSIsImNvbnN0cyIsImtleSIsImlzQ2hhcmFjdGVyRGV2aWNlIiwibyIsImpzX3N0YXRzIiwidG9fZGlyIiwidGFyZ2V0IiwibGluayIsImZpbGVfa2luZCIsIk1sT2JqZWN0VGFibGUiLCJOYWl2ZUxvb2t1cCIsIm9ianMiLCJNbFN0cmluZ1JlYWRlciIsImNhbWxfaW50NjRfY3JlYXRlX2xvX2hpIiwiY2FtbF9pbnQ2NF9oaTMyIiwiY2FtbF9pbnQ2NF9sbzMyIiwiY2FtbF9hcnJheV9ib3VuZF9lcnJvciIsImNhbWxfYmFfY3VzdG9tX25hbWUiLCJNbF9CaWdhcnJheSIsImtpbmQiLCJsYXlvdXQiLCJkaW1zIiwiYnVmZmVyIiwib2ZzIiwiaW0iLCJyZSIsInRvdGFsIiwiazEiLCJrMiIsIk5hTiIsIk1sX0JpZ2FycmF5X2NfMV8xIiwiVUludDhBcnJheVJlYWRlciIsImluY3JfbmF0IiwibmF0IiwiY2FycnlfaW4iLCJjYXJyeSIsImFkZF9uYXQiLCJuYXQxIiwib2ZzMSIsImxlbjEiLCJuYXQyIiwib2ZzMiIsImxlbjIiLCJjYW1sX2JhX2dldF9zaXplIiwibl9kaW1zIiwic2l6ZSIsImNhbWxfYmFfZ2V0X3NpemVfcGVyX2VsZW1lbnQiLCJjYW1sX2JhX2NyZWF0ZV91bnNhZmUiLCJzaXplX3Blcl9lbGVtZW50IiwiYmlnc3RyaW5nX29mX2FycmF5X2J1ZmZlciIsImFiIiwidGEiLCJiaWdzdHJpbmdfb2ZfdHlwZWRfYXJyYXkiLCJiaWdzdHJpbmdfdG9fYXJyYXlfYnVmZmVyIiwiYmlnc3RyaW5nX3RvX3R5cGVkX2FycmF5IiwiY2FtbF9iaWdzdHJpbmdfYmxpdF9zdHJpbmdfdG9fYmEiLCJzdHIxIiwicG9zMSIsImJhMiIsInBvczIiLCJzbGljZSIsImJpZ3N0cmluZ2FmX2JsaXRfZnJvbV9ieXRlcyIsInNyY19vZmYiLCJkc3QiLCJkc3Rfb2ZmIiwiY2FtbF9iaWdzdHJpbmdfYmxpdF9iYV90b19iYSIsImJhMSIsImJpZ3N0cmluZ2FmX2JsaXRfdG9fYmlnc3RyaW5nIiwiY2FtbF9iaWdzdHJpbmdfYmxpdF9iYV90b19ieXRlcyIsImJ5dGVzMiIsImJpZ3N0cmluZ2FmX2JsaXRfdG9fYnl0ZXMiLCJiaWdzdHJpbmdhZl9tZW1jaHIiLCJiYV9vZmYiLCJjaHIiLCJjYW1sX2ludF9jb21wYXJlIiwiYmlnc3RyaW5nYWZfbWVtY21wX2JpZ3N0cmluZyIsImJhMV9vZmYiLCJiYTJfb2ZmIiwiYmlnc3RyaW5nYWZfbWVtY21wX3N0cmluZyIsInN0ciIsInN0cl9vZmYiLCJibGl0X25hdCIsImNhbWxfTUQ1VHJhbnNmb3JtIiwiYWRkIiwieHgiLCJmZiIsImdnIiwiaGgiLCJpaSIsInciLCJjYW1sX01ENUZpbmFsIiwiY3R4IiwiaW5fYnVmIiwiY2FtbF9NRDVJbml0IiwiQXJyYXlCdWZmZXIiLCJiMzIiLCJVaW50MzJBcnJheSIsImI4IiwiY2FtbF9NRDVVcGRhdGUiLCJpbnB1dCIsImlucHV0X2xlbiIsImlucHV0X3BvcyIsIm1pc3NpbmciLCJjYW1sX2Fjb3NoX2Zsb2F0IiwiY2FtbF9jYWxsX2dlbiIsImFyZ3NMZW4iLCJnIiwibmFyZ3MiLCJleHRyYV9hcmdzIiwiYXJndW1lbnRzIiwiY2FtbF9hbGxvY19kdW1teV9pbmZpeCIsImNhbWxfYWxsb2Nfc3RhY2siLCJodiIsImh4IiwiaGYiLCJjYW1sX2FyZ3YiLCJtYWluIiwiYXJndiIsInAiLCJhcmdzMiIsImNhbWxfYXJyYXlfYXBwZW5kIiwiYTEiLCJhMiIsImwxIiwibDIiLCJjYW1sX2FycmF5X2JsaXQiLCJjYW1sX2FycmF5X2NvbmNhdCIsImNhbWxfYXJyYXlfZmlsbCIsImFycmF5IiwiY2FtbF9hcnJheV9nZXQiLCJpbmRleCIsImNhbWxfYXJyYXlfb2ZfYnl0ZXMiLCJjYW1sX2FycmF5X29mX3N0cmluZyIsImNhbWxfYXJyYXlfc2V0IiwibmV3dmFsIiwiY2FtbF9hcnJheV9zdWIiLCJjYW1sX2FzaW5oX2Zsb2F0IiwiY2FtbF9hdGFuaF9mbG9hdCIsImNhbWxfYXRvbWljX2NhcyIsInJlZiIsImNhbWxfYXRvbWljX2V4Y2hhbmdlIiwiY2FtbF9hdG9taWNfZmV0Y2hfYWRkIiwiY2FtbF9hdG9taWNfbG9hZCIsImNhbWxfYXRvbWljX21ha2VfY29udGVuZGVkIiwiY2FtbF9iYV9ibGl0IiwiY2FtbF9iYV9jaGFuZ2VfbGF5b3V0IiwibmV3X2RpbXMiLCJjYW1sX2JhX2NvbXBhcmUiLCJjYW1sX2JhX2NyZWF0ZV9idWZmZXIiLCJ2aWV3IiwiRmxvYXQzMkFycmF5IiwiRmxvYXQ2NEFycmF5IiwiSW50OEFycmF5IiwiSW50MTZBcnJheSIsIlVpbnQxNkFycmF5IiwiY2FtbF9qc19mcm9tX2FycmF5IiwiY2FtbF9iYV9jcmVhdGUiLCJkaW1zX21sIiwiY2FtbF9iYV9jcmVhdGVfZnJvbSIsImRhdGExIiwiZGF0YTIiLCJqc3R5cCIsImNhbWxfaW50MzJfZmxvYXRfb2ZfYml0cyIsImludDMyYSIsImZsb2F0MzJhIiwiY2FtbF9pbnQ2NF9vZl9ieXRlcyIsImNhbWxfaW50NjRfZmxvYXRfb2ZfYml0cyIsImV4cCIsIkluZmluaXR5IiwiayIsImNhbWxfZmFpbHdpdGgiLCJjYW1sX2JhX2Rlc2VyaWFsaXplIiwicmVhZGVyIiwic3oiLCJudW1fZGltcyIsInNpemVfZGltIiwic2l6ZV9kaW1faGkiLCJzaXplX2RpbV9sbyIsInNpeHR5IiwiaW50NjQiLCJjYW1sX2JhX2RpbSIsImNhbWxfYmFfZGltXzEiLCJjYW1sX2JhX2RpbV8yIiwiY2FtbF9iYV9kaW1fMyIsImNhbWxfYmFfZmlsbCIsImNhbWxfYmFfa2luZF9vZl90eXBlZF9hcnJheSIsIlVpbnQ4Q2xhbXBlZEFycmF5IiwiY2FtbF9iYV9mcm9tX3R5cGVkX2FycmF5IiwiY2FtbF9iYV9nZXRfMiIsImNhbWxfYmFfZ2V0XzMiLCJjYW1sX2JhX2dldF9nZW5lcmljIiwiY2FtbF9tdWwiLCJjYW1sX2hhc2hfbWl4X2ludCIsImxvZzJfb2siLCJqc29vX2Zsb29yX2xvZzIiLCJjYW1sX2ludDY0X2NyZWF0ZV9sb19taV9oaSIsImNhbWxfaW50NjRfYml0c19vZl9mbG9hdCIsImlzRmluaXRlIiwiaXNOYU4iLCJyMyIsInIyIiwicjEiLCJjYW1sX2hhc2hfbWl4X2ludDY0IiwiY2FtbF9oYXNoX21peF9mbG9hdCIsInYwIiwiY2FtbF9iYV9oYXNoIiwibnVtX2VsdHMiLCJjYW1sX2JhX2luaXQiLCJjYW1sX2JhX2tpbmQiLCJjYW1sX2JhX2xheW91dCIsImNhbWxfYmFfbWFwX2ZpbGUiLCJ2ZmQiLCJzaGFyZWQiLCJjYW1sX2JhX21hcF9maWxlX2J5dGVjb2RlIiwiYXJnbiIsImNhbWxfYmFfbnVtX2RpbXMiLCJjYW1sX2JhX3Jlc2hhcGUiLCJ2aW5kIiwibmV3X2RpbSIsImNhbWxfaW50MzJfYml0c19vZl9mbG9hdCIsImNhbWxfaW50NjRfdG9fYnl0ZXMiLCJjYW1sX2JhX3NlcmlhbGl6ZSIsIndyaXRlciIsImNvbXBsZXgiLCJjYW1sX2JhX3NldF8xIiwiY2FtbF9iYV9zZXRfMiIsImNhbWxfYmFfc2V0XzMiLCJjYW1sX2JhX3NldF9nZW5lcmljIiwiY2FtbF9iYV9zbGljZSIsIm51bV9pbmRzIiwic3ViX2RpbXMiLCJuZXdfZGF0YSIsImNhbWxfYmFfc3ViIiwiY2hhbmdlZF9kaW0iLCJtdWwiLCJjYW1sX2JhX3RvX3R5cGVkX2FycmF5IiwiY2FtbF9iYV91aW50OF9nZXQxNiIsImIxIiwiYjIiLCJjYW1sX2JhX3VpbnQ4X2dldDMyIiwiYjMiLCJiNCIsImNhbWxfYmFfdWludDhfZ2V0NjQiLCJiNSIsImI2IiwiYjciLCJjYW1sX2JhX3VpbnQ4X3NldDE2IiwiY2FtbF9iYV91aW50OF9zZXQzMiIsImNhbWxfYmFfdWludDhfc2V0NjQiLCJjYW1sX2JhY2t0cmFjZV9zdGF0dXMiLCJfdW5pdCIsImNhbWxfYmlnc3RyaW5nX2JsaXRfYnl0ZXNfdG9fYmEiLCJjYW1sX2JpZ3N0cmluZ19tZW1jbXAiLCJjYW1sX2JsaXRfc3RyaW5nIiwiZSIsImNhbWxfYnN3YXAxNiIsImNhbWxfanNzdHJpbmdfb2Zfc3RyaW5nIiwiY2FtbF9idWlsZF9zeW1ib2xzIiwic3ltYiIsImNhbWxfYnl0ZXNfY29tcGFyZSIsImNhbWxfYnl0ZXNfZXF1YWwiLCJjYW1sX2J5dGVzX3Vuc2FmZV9nZXQiLCJjYW1sX2J5dGVzX2dldCIsImNhbWxfYnl0ZXNfZ2V0MTYiLCJjYW1sX2J5dGVzX2dldDMyIiwiY2FtbF9ieXRlc19nZXQ2NCIsImNhbWxfYnl0ZXNfbGVzc2VxdWFsIiwiY2FtbF9ieXRlc19ncmVhdGVyZXF1YWwiLCJjYW1sX2J5dGVzX2xlc3N0aGFuIiwiY2FtbF9ieXRlc19ncmVhdGVydGhhbiIsImNhbWxfYnl0ZXNfbm90ZXF1YWwiLCJjYW1sX2J5dGVzX29mX3V0ZjE2X2pzc3RyaW5nIiwiY2FtbF9ieXRlc19zZXQxNiIsImkxNiIsImNhbWxfYnl0ZXNfc2V0MzIiLCJpMzIiLCJjYW1sX2J5dGVzX3NldDY0IiwiaTY0IiwiY2FtbF9jYWxsYmFjayIsImNhbWxfY2JydF9mbG9hdCIsImNhbWxfbWxfY2hhbm5lbHMiLCJjYW1sX21sX2NoYW5uZWxfZ2V0IiwiaWQiLCJjYW1sX2NoYW5uZWxfZGVzY3JpcHRvciIsImNoYW5pZCIsImNoYW4iLCJjYW1sX2NoZWNrX2JvdW5kIiwiY2FtbF9jbGFzc2lmeV9mbG9hdCIsImNhbWxfaXNfY29udGludWF0aW9uX3RhZyIsImNhbWxfaW50MzJfdW5tYXJzaGFsIiwiY2FtbF9uYXRpdmVpbnRfdW5tYXJzaGFsIiwiY2FtbF9pbnQ2NF91bm1hcnNoYWwiLCJjYW1sX2ludDY0X21hcnNoYWwiLCJzaXplcyIsImNhbWxfaW50NjRfY29tcGFyZSIsImNhbWxfaW50NjRfaGFzaCIsImNhbWxfY3VzdG9tX29wcyIsImNhbWxfY29tcGFyZV92YWxfZ2V0X2N1c3RvbSIsImNhbWxfY29tcGFyZV92YWxfbnVtYmVyX2N1c3RvbSIsIm51bSIsImN1c3RvbSIsInN3YXAiLCJjYW1sX2NvbXBhcmVfdmFsX3RhZyIsIk51bWJlciIsImNhbWxfc3RyaW5nX2NvbXBhcmUiLCJjYW1sX2NvbXBhcmVfdmFsIiwic3RhY2siLCJ0YWdfYSIsInRhZ19iIiwiY2FtbF9jb21wYXJlIiwiY2FtbF9jb250aW51YXRpb25fdXNlX25vZXhjIiwiY29udCIsImNhbWxfY29udGludWF0aW9uX3VzZV9hbmRfdXBkYXRlX2hhbmRsZXJfbm9leGMiLCJodmFsIiwiaGV4biIsImhlZmYiLCJjYW1sX2NvbnZlcnRfcmF3X2JhY2t0cmFjZSIsImNhbWxfY29udmVydF9yYXdfYmFja3RyYWNlX3Nsb3QiLCJjYW1sX2NvcHlzaWduX2Zsb2F0IiwiY2FtbF9jb3NoX2Zsb2F0IiwiZnNfbm9kZV9zdXBwb3J0ZWQiLCJtYWtlX3BhdGhfaXNfYWJzb2x1dGUiLCJwb3NpeCIsIndpbjMyIiwic3BsaXREZXZpY2VSZSIsInJlc3VsdCIsImRldmljZSIsImlzVW5jIiwiQm9vbGVhbiIsInNlcCIsInBhdGhfaXNfYWJzb2x1dGUiLCJjYW1sX3RyYWlsaW5nX3NsYXNoIiwiY2FtbF9jdXJyZW50X2RpciIsImNhbWxfbWFrZV9wYXRoIiwiY29tcDAiLCJuY29tcCIsImNhbWxfZ2V0X3Jvb3QiLCJjYW1sX3Jvb3QiLCJqc29vX21vdW50X3BvaW50IiwicmVzb2x2ZV9mc19kZXZpY2UiLCJjYW1sX2NyZWF0ZV9maWxlIiwiY2FtbF9jcmVhdGVfc3RyaW5nIiwiY2FtbF9jdXN0b21fZXZlbnRfaW5kZXgiLCJjYW1sX2RlY29tcHJlc3NfaW5wdXQiLCJjYW1sX2RpdiIsImNhbWxfZG9tYWluX2RscyIsImNhbWxfZG9tYWluX2Rsc19nZXQiLCJ1bml0IiwiY2FtbF9kb21haW5fZGxzX3NldCIsImNhbWxfZG9tYWluX2lkIiwiY2FtbF9tbF9tdXRleF91bmxvY2siLCJjYW1sX2RvbWFpbl9sYXRlc3RfaWR4IiwiY2FtbF9kb21haW5fc3Bhd24iLCJtdXRleCIsImNhbWxfZXBoZV9kYXRhX29mZnNldCIsImNhbWxfZXBoZV9rZXlfb2Zmc2V0IiwiY2FtbF9lcGhlX3Vuc2V0X2RhdGEiLCJjYW1sX2VwaGVfc2V0X2RhdGEiLCJjYW1sX2VwaGVfYmxpdF9kYXRhIiwiY2FtbF9lcGhlX2JsaXRfa2V5IiwiY2FtbF9lcGhlX2NoZWNrX2RhdGEiLCJjYW1sX2VwaGVfY2hlY2tfa2V5Iiwid2VhayIsImNhbWxfd2Vha19jcmVhdGUiLCJjYW1sX2VwaGVfY3JlYXRlIiwiY2FtbF9lcGhlX2dldF9kYXRhIiwiY2FtbF9vYmpfZHVwIiwiY2FtbF9lcGhlX2dldF9kYXRhX2NvcHkiLCJjYW1sX2VwaGVfZ2V0X2tleSIsImNhbWxfZXBoZV9nZXRfa2V5X2NvcHkiLCJ6IiwiY2FtbF9lcGhlX3NldF9rZXkiLCJPYmplY3QiLCJjYW1sX2VwaGVfdW5zZXRfa2V5IiwiY291bnQiLCJjYW1sX2VxdWFsIiwiY2FtbF9lcmZfZmxvYXQiLCJhMyIsImE0IiwiYTUiLCJjYW1sX2VyZmNfZmxvYXQiLCJjYW1sX2V2ZW50bG9nX3BhdXNlIiwiY2FtbF9ldmVudGxvZ19yZXN1bWUiLCJjYW1sX2V4ZWN1dGFibGVfbmFtZSIsImNhbWxfZXhwMl9mbG9hdCIsImNhbWxfZXhwbTFfZmxvYXQiLCJjYW1sX2lzX3NwZWNpYWxfZXhjZXB0aW9uIiwiY2FtbF9mb3JtYXRfZXhjZXB0aW9uIiwiYnVja2V0Iiwic3RhcnQiLCJjYW1sX2ZhdGFsX3VuY2F1Z2h0X2V4Y2VwdGlvbiIsImhhbmRsZXIiLCJhdF9leGl0IiwiY2FtbF9maWxsX2J5dGVzIiwiY2FtbF9maW5hbF9yZWdpc3RlciIsImFsbF9maW5hbGl6ZXJzIiwiY2FtbF9maW5hbF9yZWdpc3Rlcl9jYWxsZWRfd2l0aG91dF92YWx1ZSIsImNiIiwiY2FtbF9maW5hbF9yZWxlYXNlIiwiY2FtbF9maW5pc2hfZm9ybWF0dGluZyIsInJhd2J1ZmZlciIsImNhbWxfZmxvYXRfY29tcGFyZSIsImNhbWxfZmxvYXRfb2ZfYnl0ZXMiLCJjYW1sX2Zsb2F0X29mX3N0cmluZyIsIm0zIiwibWFudGlzc2EiLCJwYXJzZUludCIsImV4cG9uZW50IiwiY2FtbF9mbG9hdGFycmF5X2JsaXQiLCJjYW1sX2Zsb2F0YXJyYXlfY3JlYXRlIiwiY2FtbF9mbWFfZmxvYXQiLCJTUExJVCIsIk1JTl9WQUxVRSIsIkVQU0lMT04iLCJDIiwiQSIsIkIiLCJtdWx0aXBseSIsImF0IiwiYWhpIiwiYWxvIiwiYnQiLCJiaGkiLCJibG8iLCJhZGp1c3QiLCJzY2FsZSIsInhzIiwieXMiLCJ6cyIsInh5IiwidSIsImZzIiwiY2FtbF9wYXJzZV9mb3JtYXQiLCJmbXQiLCJjYW1sX2Zvcm1hdF9mbG9hdCIsInRvRml4ZWQiLCJkcCIsInByZWMiLCJjYW1sX2Zvcm1hdF9pbnQiLCJjYW1sX29vX2xhc3RfaWQiLCJjYW1sX2ZyZXNoX29vX2lkIiwiY2FtbF9mcmV4cF9mbG9hdCIsIm5lZyIsImpzb29fY3JlYXRlX2ZpbGUiLCJjYW1sX2ZzX2luaXQiLCJ0bXAiLCJjYW1sX2djX2NvbXBhY3Rpb24iLCJjYW1sX2djX2NvdW50ZXJzIiwiY2FtbF9nY19mdWxsX21ham9yIiwiY2FtbF9nY19nZXQiLCJjYW1sX2djX2h1Z2VfZmFsbGJhY2tfY291bnQiLCJjYW1sX2djX21ham9yIiwiY2FtbF9nY19tYWpvcl9zbGljZSIsIndvcmsiLCJjYW1sX2djX21pbm9yIiwiY2FtbF9nY19taW5vcl93b3JkcyIsImNhbWxfZ2NfcXVpY2tfc3RhdCIsImNhbWxfZ2Nfc2V0IiwiX2NvbnRyb2wiLCJjYW1sX2djX3N0YXQiLCJjYW1sX2dldF9jb250aW51YXRpb25fY2FsbHN0YWNrIiwiY2FtbF9nZXRfY3VycmVudF9jYWxsc3RhY2siLCJjYW1sX2dldF9leGNlcHRpb25fYmFja3RyYWNlIiwiY2FtbF9nZXRfZXhjZXB0aW9uX3Jhd19iYWNrdHJhY2UiLCJjYW1sX2dldF9nbG9iYWxfZGF0YSIsImNhbWxfZ2V0X21ham9yX2J1Y2tldCIsImNhbWxfZ2V0X21ham9yX2NyZWRpdCIsImNhbWxfZ2V0X21pbm9yX2ZyZWUiLCJjYW1sX21ldGhvZF9jYWNoZSIsImNhbWxfZ2V0X3B1YmxpY19tZXRob2QiLCJvYmoiLCJjYWNoZWlkIiwibWV0aHMiLCJsaSIsImNhbWxfZ3JfYXJjX2F1eCIsImN4IiwiY3kiLCJyeSIsInJ4Iiwicm90IiwieFBvcyIsInlQb3MiLCJ4UG9zX3ByZXYiLCJ5UG9zX3ByZXYiLCJzcGFjZSIsImRlbHRhIiwiY2FtbF9ncl9zdGF0ZSIsImNhbWxfZ3Jfc3RhdGVfZ2V0IiwiY2FtbF9ncl9ibGl0X2ltYWdlIiwiaW0yIiwiY2FtbF9ncl9jbGVhcl9ncmFwaCIsImNhbWxfZ3JfY2xvc2VfZ3JhcGgiLCJjYW1sX2dyX2Nsb3NlX3N1YndpbmRvdyIsImNhbWxfZ3JfY3JlYXRlX2ltYWdlIiwiY2FtbF9ncl9jdXJyZW50X3giLCJjYW1sX2dyX2N1cnJlbnRfeSIsImNhbWxfZ3JfZGlzcGxheV9tb2RlIiwiY2FtbF9ncl9kb2Nfb2Zfc3RhdGUiLCJzdGF0ZSIsImNhbWxfZ3JfZHJhd19hcmMiLCJjYW1sX2dyX2RyYXdfc3RyIiwiZHgiLCJjYW1sX2dyX2RyYXdfY2hhciIsImNhbWxfZ3JfZHJhd19pbWFnZSIsImNhbnZhcyIsImRvY3VtZW50IiwiaW1hZ2UiLCJjYW1sX2dyX2RyYXdfcmVjdCIsImNhbWxfZ3JfZHJhd19zdHJpbmciLCJjYW1sX2dyX2R1bXBfaW1hZ2UiLCJjYW1sX2dyX2ZpbGxfYXJjIiwiY2FtbF9ncl9maWxsX3BvbHkiLCJhciIsImNhbWxfZ3JfZmlsbF9yZWN0IiwiY2FtbF9ncl9saW5ldG8iLCJjYW1sX2dyX21ha2VfaW1hZ2UiLCJjYW1sX2dyX21vdmV0byIsImNhbWxfZ3Jfc2V0X3dpbmRvd190aXRsZSIsImpzbmFtZSIsImNhbWxfZ3Jfc2V0X2xpbmVfd2lkdGgiLCJjYW1sX2dyX3NldF90ZXh0X3NpemUiLCJjYW1sX2dyX3NldF9mb250IiwiY2FtbF9ncl9zZXRfY29sb3IiLCJjb2xvciIsImNvbnZlcnQiLCJudW1iZXIiLCJjX3N0ciIsImNhbWxfZ3JfcmVzaXplX3dpbmRvdyIsImNhbWxfZ3Jfc3RhdGVfaW5pdCIsImNhbWxfZ3Jfc3RhdGVfc2V0IiwiY2FtbF9ncl9zdGF0ZV9jcmVhdGUiLCJjb250ZXh0IiwiY2FtbF9ncl9vcGVuX2dyYXBoIiwiaW5mbyIsImdldCIsInNwZWNzIiwic3RhdHVzIiwid2luIiwiZG9jIiwidGl0bGUiLCJib2R5IiwiY2FtbF9ncl9vcGVuX3N1YndpbmRvdyIsImNhbWxfZ3JfcGxvdCIsImNhbWxfZ3JfcG9pbnRfY29sb3IiLCJjYW1sX2dyX3JlbWVtYmVyX21vZGUiLCJjYW1sX2dyX3NpZ2lvX2hhbmRsZXIiLCJjYW1sX2dyX3NpZ2lvX3NpZ25hbCIsImNhbWxfZ3Jfc2l6ZV94IiwiY2FtbF9ncl9zaXplX3kiLCJjYW1sX2dyX3N5bmNocm9uaXplIiwiY2FtbF9ncl90ZXh0X3NpemUiLCJ0eHQiLCJjYW1sX2dyX3dhaXRfZXZlbnQiLCJfZXZsIiwiY2FtbF9ncl93aW5kb3dfaWQiLCJjYW1sX2dyZWF0ZXJlcXVhbCIsImNhbWxfZ3JlYXRlcnRoYW4iLCJjYW1sX2hhc2hfbWl4X2pzYnl0ZXMiLCJjYW1sX2hhc2hfbWl4X3N0cmluZyIsImNhbWxfaGFzaF9taXhfYnl0ZXNfYXJyIiwiY2FtbF9tbF9ieXRlc19jb250ZW50IiwiY2FtbF9oYXNoX21peF9ieXRlcyIsImNhbWxfaGFzaF9taXhfZmluYWwiLCJjYW1sX2hhc2giLCJsaW1pdCIsInNlZWQiLCJxdWV1ZSIsInJkIiwid3IiLCJjYW1sX2hhc2hfbWl4X2JpZ3N0cmluZyIsIm51bV9kaWdpdHNfbmF0IiwiY2FtbF9oYXNoX25hdCIsImNhbWxfaGV4c3RyaW5nX29mX2Zsb2F0Iiwic3R5bGUiLCJleHBfc2lnbiIsInNpZ25fc3RyIiwiY3N0IiwieF9zdHIiLCJpZHgiLCJjYW1sX2h5cG90X2Zsb2F0IiwiY2FtbF9tYXJzaGFsX2hlYWRlcl9zaXplIiwiY2FtbF9yZWZpbGwiLCJzdHJfYSIsIm5yZWFkIiwiY2FtbF9yYWlzZV9lbmRfb2ZfZmlsZSIsImNhbWxfbWFyc2hhbF9kYXRhX3NpemUiLCJyZWFkdmxxIiwib3ZlcmZsb3ciLCJuNyIsImhlYWRlcl9sZW4iLCJkYXRhX2xlbiIsImNhbWxfaW5wdXRfdmFsdWVfZnJvbV9yZWFkZXIiLCJtYWdpYyIsImNvbXByZXNzZWQiLCJ1bmNvbXByZXNzZWRfZGF0YV9sZW4iLCJudW1fb2JqZWN0cyIsIl9zaXplXzMyIiwiX3NpemVfNjQiLCJpbnRlcm5fb2JqX3RhYmxlIiwib2JqX2NvdW50ZXIiLCJpbnRlcm5fcmVjIiwiaGVhZGVyIiwib3BzIiwiZXhwZWN0ZWRfc2l6ZSIsIm9sZF9wb3MiLCJjYW1sX3N0cmluZ19vZl9ieXRlcyIsImNhbWxfaW5wdXRfdmFsdWVfZnJvbV9ieXRlcyIsImNhbWxfaW5wdXRfdmFsdWUiLCJibG9jayIsImNhbWxfaW5wdXRfdmFsdWVfZnJvbV9zdHJpbmciLCJjYW1sX2lucHV0X3ZhbHVlX3RvX291dHNpZGVfaGVhcCIsImNhbWxfaW5zdGFsbF9zaWduYWxfaGFuZGxlciIsImNhbWxfaW50MzJfYnN3YXAiLCJjYW1sX2ludDY0X2FkZCIsImNhbWxfaW50NjRfYW5kIiwiY2FtbF9pbnQ2NF9ic3dhcCIsImNhbWxfaW50NjRfZGl2IiwiY2FtbF9pbnQ2NF9pc196ZXJvIiwiY2FtbF9pbnQ2NF9vZl9pbnQzMiIsImNhbWxfaW50NjRfdG9faW50MzIiLCJjYW1sX2ludDY0X2lzX25lZ2F0aXZlIiwiY2FtbF9pbnQ2NF9uZWciLCJjYW1sX2ludDY0X2Zvcm1hdCIsIndiYXNlIiwiY3Z0YmwiLCJjYW1sX2ludDY0X21vZCIsImNhbWxfaW50NjRfbXVsIiwiY2FtbF9pbnQ2NF9vZl9mbG9hdCIsImNhbWxfaW50NjRfdWx0IiwiY2FtbF9wYXJzZV9zaWduX2FuZF9iYXNlIiwiYmFzZSIsImNhbWxfcGFyc2VfZGlnaXQiLCJjYW1sX2ludDY0X29mX3N0cmluZyIsImJhc2U2NCIsInRocmVzaG9sZCIsImNhbWxfaW50NjRfb3IiLCJjYW1sX2ludDY0X3NoaWZ0X2xlZnQiLCJjYW1sX2ludDY0X3NoaWZ0X3JpZ2h0IiwiY2FtbF9pbnQ2NF9zaGlmdF9yaWdodF91bnNpZ25lZCIsImNhbWxfaW50NjRfc3ViIiwiY2FtbF9pbnQ2NF90b19mbG9hdCIsImNhbWxfaW50NjRfeG9yIiwiY2FtbF9pbnRfb2Zfc3RyaW5nIiwiY2FtbF9pc19qcyIsImNhbWxfaXNfcHJpbnRhYmxlIiwiY2FtbF9qc19jYWxsIiwiY2FtbF9qc19kZWxldGUiLCJjYW1sX2pzX2VxdWFscyIsImNhbWxfanNfZXJyb3Jfb2ZfZXhjZXB0aW9uIiwiY2FtbF9qc19lcnJvcl9vcHRpb25fb2ZfZXhjZXB0aW9uIiwiY2FtbF9qc19ldmFsX3N0cmluZyIsImV2YWwiLCJjYW1sX2pzX2V4cHIiLCJjYW1sX2pzX2Zyb21fYm9vbCIsImNhbWxfanNfZnJvbV9mbG9hdCIsImNhbWxfanNfZnJvbV9zdHJpbmciLCJjYW1sX2pzX2Z1bl9jYWxsIiwiY2FtbF9qc19mdW5jdGlvbl9hcml0eSIsImNhbWxfanNfZ2V0IiwiY2FtbF9qc19nZXRfY29uc29sZSIsImNhbWxfanNfaHRtbF9lbnRpdGllcyIsImVudGl0eSIsInRlbXAiLCJjYW1sX2pzX3JlZ2V4cHMiLCJjYW1sX2pzX2h0bWxfZXNjYXBlIiwiY2FtbF9qc19pbnN0YW5jZW9mIiwiY2FtbF9qc19tZXRoX2NhbGwiLCJjYW1sX2pzX25ldyIsIkYiLCJjYW1sX2pzX29iamVjdCIsImNhbWxfanNfb25faWUiLCJ1YSIsImNhbWxfanNfcHVyZV9leHByIiwiY2FtbF9qc19zZXQiLCJjYW1sX2pzX3N0cmljdF9lcXVhbHMiLCJjYW1sX2pzX3RvX2FycmF5IiwiY2FtbF9qc190b19ib29sIiwiY2FtbF9qc190b19ieXRlX3N0cmluZyIsImNhbWxfanNfdG9fZmxvYXQiLCJjYW1sX2pzX3RvX2ludDMyIiwiY2FtbF9qc190b19zdHJpbmciLCJjYW1sX2pzX3R5cGVvZiIsImNhbWxfanNfdmFyIiwiY2FtbF9qc193cmFwX2NhbGxiYWNrIiwiRnVuY3Rpb24iLCJjYW1sX2pzX3dyYXBfY2FsbGJhY2tfYXJndW1lbnRzIiwiY2FtbF9qc193cmFwX2NhbGxiYWNrX3N0cmljdCIsImFyaXR5IiwiY2FtbF9qc193cmFwX2NhbGxiYWNrX3Vuc2FmZSIsImNhbWxfanNfd3JhcF9tZXRoX2NhbGxiYWNrIiwiY2FtbF9qc193cmFwX21ldGhfY2FsbGJhY2tfYXJndW1lbnRzIiwiY2FtbF9qc193cmFwX21ldGhfY2FsbGJhY2tfc3RyaWN0IiwiY2FtbF9qc193cmFwX21ldGhfY2FsbGJhY2tfdW5zYWZlIiwiY2FtbF9qc29vX2ZsYWdzX2VmZmVjdHMiLCJjYW1sX2pzb29fZmxhZ3NfdXNlX2pzX3N0cmluZyIsImNhbWxfbGF6eV9tYWtlX2ZvcndhcmQiLCJjYW1sX29ial90YWciLCJjYW1sX2xhenlfcmVhZF9yZXN1bHQiLCJjYW1sX29ial91cGRhdGVfdGFnIiwiY2FtbF9sYXp5X3Jlc2V0X3RvX2xhenkiLCJjYW1sX2xhenlfdXBkYXRlX3RvX2ZvcmNpbmciLCJjYW1sX2xhenlfdXBkYXRlX3RvX2ZvcndhcmQiLCJjYW1sX2xkZXhwX2Zsb2F0IiwiY2FtbF9sZXNzZXF1YWwiLCJjYW1sX2xlc3N0aGFuIiwiY2FtbF9sZXhfYXJyYXkiLCJjYW1sX2xleF9lbmdpbmUiLCJ0YmwiLCJzdGFydF9zdGF0ZSIsImxleGJ1ZiIsImxleF9idWZmZXIiLCJsZXhfYnVmZmVyX2xlbiIsImxleF9zdGFydF9wb3MiLCJsZXhfY3Vycl9wb3MiLCJsZXhfbGFzdF9wb3MiLCJsZXhfbGFzdF9hY3Rpb24iLCJsZXhfZW9mX3JlYWNoZWQiLCJsZXhfYmFzZSIsImxleF9iYWNrdHJrIiwibGV4X2RlZmF1bHQiLCJsZXhfdHJhbnMiLCJsZXhfY2hlY2siLCJiYWNrdHJrIiwiY2FtbF9saXN0X21vdW50X3BvaW50IiwicHJldiIsImNhbWxfbGlzdF9vZl9qc19hcnJheSIsImNhbWxfbGlzdF90b19qc19hcnJheSIsImNhbWxfbG9nMTBfZmxvYXQiLCJjYW1sX2xvZzFwX2Zsb2F0IiwiY2FtbF9sb2cyX2Zsb2F0IiwiY2FtbF9uZXdfc3RyaW5nIiwiY2FtbF9seG1fbmV4dCIsInNoaWZ0X2wiLCJzaGlmdF9yIiwib3IiLCJ4b3IiLCJyb3RsIiwic2V0IiwiTSIsImRhYmEiLCJxMCIsInExIiwic3QiLCJ4MCIsIngxIiwiY2FtbF9tYWtlX2Zsb2F0X3ZlY3QiLCJjYW1sX21ha2VfdmVjdCIsImluaXQiLCJjYW1sX21hcnNoYWxfY29uc3RhbnRzIiwiY2FtbF9tYXliZV9wcmludF9zdGF0cyIsImNhbWxfbWQ1X2J5dGVzIiwiY2FtbF9tbF9pbnB1dF9ibG9jayIsImF2YWlsIiwiY2FtbF9tZDVfY2hhbiIsInRvcmVhZCIsImNhbWxfbWQ1X3N0cmluZyIsImNhbWxfbWVtcHJvZl9kaXNjYXJkIiwiY2FtbF9tZW1wcm9mX3NldCIsImNhbWxfbWVtcHJvZl9zdGFydCIsInJhdGUiLCJzdGFja19zaXplIiwidHJhY2tlciIsImNhbWxfbWVtcHJvZl9zdG9wIiwiY2FtbF9tbF9jaGFubmVsX3JlZGlyZWN0IiwiY2FwdHVyZWQiLCJpbnRvIiwidG9fcmVzdG9yZSIsIm5ld18iLCJjYW1sX21sX2NoYW5uZWxfcmVzdG9yZSIsImNhbWxfbWxfY2hhbm5lbF9zaXplIiwiY2FtbF9tbF9jaGFubmVsX3NpemVfNjQiLCJjYW1sX3N5c19mZHMiLCJjYW1sX3N5c19jbG9zZSIsImNhbWxfbWxfZmx1c2giLCJjYW1sX21sX2Nsb3NlX2NoYW5uZWwiLCJjYW1sX21sX2NvbmRpdGlvbl9icm9hZGNhc3QiLCJjYW1sX21sX2NvbmRpdGlvbl9uZXciLCJjYW1sX21sX2NvbmRpdGlvbl9zaWduYWwiLCJjYW1sX21sX2NvbmRpdGlvbl93YWl0IiwibXV0ZXh0IiwiY2FtbF9tbF9kZWJ1Z19pbmZvX3N0YXR1cyIsImNhbWxfbWxfZG9tYWluX2NwdV9yZWxheCIsImNhbWxfbWxfZG9tYWluX2lkIiwiY2FtbF9tbF9kb21haW5fc2V0X25hbWUiLCJfbmFtZSIsImNhbWxfbWxfZG9tYWluX3VuaXF1ZV90b2tlbl8iLCJjYW1sX21sX2RvbWFpbl91bmlxdWVfdG9rZW4iLCJjYW1sX3J1bnRpbWVfd2FybmluZ3MiLCJjYW1sX21sX2VuYWJsZV9ydW50aW1lX3dhcm5pbmdzIiwiYm9vbCIsImNhbWxfbWxfaW5wdXQiLCJjYW1sX21sX2lucHV0X2JpZ2FycmF5IiwiY2FtbF9tbF9pbnB1dF9jaGFyIiwiY2FtbF9tbF9pbnB1dF9pbnQiLCJjYW1sX21sX2lucHV0X3NjYW5fbGluZSIsInByZXZfbWF4IiwiY2FtbF9tbF9pc19idWZmZXJlZCIsImNhbWxfbWxfbXV0ZXhfbG9jayIsImNhbWxfbWxfbXV0ZXhfbmV3IiwiY2FtbF9tbF9tdXRleF90cnlfbG9jayIsImNhbWxfc3lzX29wZW5fZm9yX25vZGUiLCJmZDIiLCJjYW1sX3N5c19vcGVuX2ludGVybmFsIiwiY2FtbF9zeXNfb3BlbiIsIl9wZXJtcyIsImNhbWxfbWxfb3Blbl9kZXNjcmlwdG9yX2luIiwicmVmaWxsIiwiY2hhbm5lbCIsImNhbWxfbWxfb3Blbl9kZXNjcmlwdG9yX291dCIsImJ1ZmZlcmVkIiwiY2FtbF9tbF9vdXRfY2hhbm5lbHNfbGlzdCIsImNhbWxfbWxfb3V0cHV0X3RhIiwiY2FtbF9tbF9vdXRwdXRfYnl0ZXMiLCJjYW1sX21sX291dHB1dCIsImNhbWxfbWxfb3V0cHV0X2JpZ2FycmF5IiwiY2FtbF9tbF9vdXRwdXRfY2hhciIsImNhbWxfbWxfb3V0cHV0X2ludCIsImNhbWxfcG9zX2luIiwiY2FtbF9tbF9wb3NfaW4iLCJjYW1sX21sX3Bvc19pbl82NCIsImNhbWxfcG9zX291dCIsImNhbWxfbWxfcG9zX291dCIsImNhbWxfbWxfcG9zX291dF82NCIsImNhbWxfbWxfcnVudGltZV9ldmVudHNfcGF1c2UiLCJjYW1sX21sX3J1bnRpbWVfZXZlbnRzX3Jlc3VtZSIsImNhbWxfbWxfcnVudGltZV9ldmVudHNfc3RhcnQiLCJjYW1sX21sX3J1bnRpbWVfd2FybmluZ3NfZW5hYmxlZCIsImNhbWxfc2Vla19pbiIsImNhbWxfbWxfc2Vla19pbiIsImNhbWxfbWxfc2Vla19pbl82NCIsImNhbWxfc2Vla19vdXQiLCJjYW1sX21sX3NlZWtfb3V0IiwiY2FtbF9tbF9zZWVrX291dF82NCIsImNhbWxfbWxfc2V0X2JpbmFyeV9tb2RlIiwiY2FtbF9tbF9zZXRfYnVmZmVyZWQiLCJjYW1sX21sX3NldF9jaGFubmVsX25hbWUiLCJjYW1sX21sX3NldF9jaGFubmVsX291dHB1dCIsImNhbWxfbWxfc2V0X2NoYW5uZWxfcmVmaWxsIiwiY2FtbF9tb2QiLCJjYW1sX21vZGZfZmxvYXQiLCJjYW1sX21vdW50X2F1dG9sb2FkIiwiY2FtbF9sZXhfcnVuX21lbSIsIm1lbSIsImN1cnJfcG9zIiwiY2FtbF9sZXhfcnVuX3RhZyIsImNhbWxfbmV3X2xleF9lbmdpbmUiLCJsZXhfbWVtIiwibGV4X2Jhc2VfY29kZSIsImxleF9iYWNrdHJrX2NvZGUiLCJsZXhfZGVmYXVsdF9jb2RlIiwibGV4X3RyYW5zX2NvZGUiLCJsZXhfY2hlY2tfY29kZSIsImxleF9jb2RlIiwicGNfb2ZmIiwicHN0YXRlIiwiYmFzZV9jb2RlIiwiY2FtbF9uZXh0YWZ0ZXJfZmxvYXQiLCJiaXRzIiwib25lIiwiY2FtbF9ub3RlcXVhbCIsImNhbWxfb2JqX2FkZF9vZmZzZXQiLCJjYW1sX29ial9ibG9jayIsImNhbWxfb2JqX2NvbXBhcmVfYW5kX3N3YXAiLCJjYW1sX29ial9pc19ibG9jayIsImNhbWxfb2JqX2lzX3NoYXJlZCIsImNhbWxfb2JqX21ha2VfZm9yd2FyZCIsImNhbWxfb2JqX3Jhd19maWVsZCIsImNhbWxfb2JqX3JlYWNoYWJsZV93b3JkcyIsImNhbWxfb2JqX3NldF9yYXdfZmllbGQiLCJjYW1sX29ial9zZXRfdGFnIiwiY2FtbF9vYmpfdHJ1bmNhdGUiLCJjYW1sX29ial93aXRoX3RhZyIsImNhbWxfb2pzX25ld19hcnIiLCJjYW1sX291dHB1dF92YWwiLCJXcml0ZXIiLCJ2YWx1ZSIsIm5vX3NoYXJpbmciLCJjbG9zdXJlcyIsIm1lbW8iLCJleGlzdGluZ19vZmZzZXQiLCJleHRlcm5fcmVjIiwic3pfMzJfNjQiLCJoZWFkZXJfcG9zIiwidHlwZV9vZl92IiwiY2FtbF9vdXRwdXRfdmFsdWVfdG9fc3RyaW5nIiwiY2FtbF9vdXRwdXRfdmFsdWUiLCJjYW1sX291dHB1dF92YWx1ZV90b19idWZmZXIiLCJjYW1sX291dHB1dF92YWx1ZV90b19ieXRlcyIsImNhbWxfcGFyc2VyX3RyYWNlIiwiY2FtbF9wYXJzZV9lbmdpbmUiLCJ0YWJsZXMiLCJlbnYiLCJjbWQiLCJFUlJDT0RFIiwibG9vcCIsInRlc3RzaGlmdCIsInNoaWZ0Iiwic2hpZnRfcmVjb3ZlciIsInJlZHVjZSIsIlJFQURfVE9LRU4iLCJSQUlTRV9QQVJTRV9FUlJPUiIsIkdST1dfU1RBQ0tTXzEiLCJHUk9XX1NUQUNLU18yIiwiQ09NUFVURV9TRU1BTlRJQ19BQ1RJT04iLCJDQUxMX0VSUk9SX0ZVTkNUSU9OIiwiZW52X3Nfc3RhY2siLCJlbnZfdl9zdGFjayIsImVudl9zeW1iX3N0YXJ0X3N0YWNrIiwiZW52X3N5bWJfZW5kX3N0YWNrIiwiZW52X3N0YWNrc2l6ZSIsImVudl9zdGFja2Jhc2UiLCJlbnZfY3Vycl9jaGFyIiwiZW52X2x2YWwiLCJlbnZfc3ltYl9zdGFydCIsImVudl9zeW1iX2VuZCIsImVudl9hc3AiLCJlbnZfcnVsZV9sZW4iLCJlbnZfcnVsZV9udW1iZXIiLCJlbnZfc3AiLCJlbnZfc3RhdGUiLCJlbnZfZXJyZmxhZyIsInRibF90cmFuc2xfY29uc3QiLCJ0YmxfdHJhbnNsX2Jsb2NrIiwidGJsX2xocyIsInRibF9sZW4iLCJ0YmxfZGVmcmVkIiwidGJsX2Rnb3RvIiwidGJsX3NpbmRleCIsInRibF9yaW5kZXgiLCJ0YmxfZ2luZGV4IiwidGJsX3RhYmxlc2l6ZSIsInRibF90YWJsZSIsInRibF9jaGVjayIsInRibF9uYW1lc19jb25zdCIsInRibF9uYW1lc19ibG9jayIsImxvZyIsInRva2VuX25hbWUiLCJuYW1lcyIsInByaW50X3Rva2VuIiwidG9rIiwidG9rZW4iLCJuMSIsIm4yIiwic3RhdGUxIiwic3AiLCJlcnJmbGFnIiwiYXNwIiwiY2FtbF9wdXJlX2pzX2V4cHIiLCJjYW1sX3JhaXNlX25vdF9hX2RpciIsImNhbWxfcmFpc2Vfbm90X2ZvdW5kIiwiY2FtbF9yYXdfYmFja3RyYWNlX2xlbmd0aCIsImNhbWxfcmF3X2JhY2t0cmFjZV9uZXh0X3Nsb3QiLCJjYW1sX3Jhd19iYWNrdHJhY2Vfc2xvdCIsImNhbWxfcmVhZF9maWxlX2NvbnRlbnQiLCJjYW1sX3JlY29tbWVuZGVkX2RvbWFpbl9jb3VudCIsImNhbWxfcmVjb3JkX2JhY2t0cmFjZSIsImNhbWxfcmVnaXN0ZXJfY2hhbm5lbF9mb3Jfc3BhY2V0aW1lIiwiX2NoYW5uZWwiLCJjYW1sX3JlZ2lzdGVyX2dsb2JhbCIsIm5hbWVfb3B0IiwibmlkIiwiY2FtbF9yZWdpc3Rlcl9uYW1lZF92YWx1ZSIsImNhbWxfcmVzdG9yZV9yYXdfYmFja3RyYWNlIiwiY2FtbF9yb3VuZF9mbG9hdCIsImNhbWxfcnVudGltZV9ldmVudHNfY3JlYXRlX2N1cnNvciIsImNhbWxfcnVudGltZV9ldmVudHNfZnJlZV9jdXJzb3IiLCJjdXJzb3IiLCJjYW1sX3J1bnRpbWVfZXZlbnRzX3JlYWRfcG9sbCIsImNhbGxiYWNrcyIsImNhbWxfcnVudGltZV9ldmVudHNfdXNlcl9yZWdpc3RlciIsImV2ZW50X25hbWUiLCJldmVudF90YWciLCJldmVudF90eXBlIiwiY2FtbF9ydW50aW1lX2V2ZW50c191c2VyX3Jlc29sdmUiLCJjYW1sX3J1bnRpbWVfZXZlbnRzX3VzZXJfd3JpdGUiLCJldmVudCIsImV2ZW50X2NvbnRlbnQiLCJjYW1sX3J1bnRpbWVfcGFyYW1ldGVycyIsImNhbWxfcnVudGltZV92YXJpYW50IiwiY2FtbF9zZXRfb29faWQiLCJjYW1sX3NldF9wYXJzZXJfdHJhY2UiLCJvbGRmbGFnIiwiY2FtbF9zZXRfc3RhdGljX2VudiIsImNhbWxfc2lnbmJpdF9mbG9hdCIsImNhbWxfc2luaF9mbG9hdCIsImNhbWxfc3BhY2V0aW1lX2VuYWJsZWQiLCJjYW1sX3NwYWNldGltZV9vbmx5X3dvcmtzX2Zvcl9uYXRpdmVfY29kZSIsImNhbWxfc3RyX2luaXRpYWxpemUiLCJjYW1sX3N0cmluZ19ib3VuZF9lcnJvciIsImNhbWxfc3RyaW5nX2NvbmNhdCIsImNhbWxfc3RyaW5nX2VxdWFsIiwiY2FtbF9zdHJpbmdfZ2V0IiwiY2FtbF9zdHJpbmdfZ2V0MTYiLCJjYW1sX3N0cmluZ19nZXQzMiIsImNhbWxfc3RyaW5nX2dldDY0IiwiY2FtbF9zdHJpbmdfbGVzc2VxdWFsIiwiY2FtbF9zdHJpbmdfZ3JlYXRlcmVxdWFsIiwiY2FtbF9zdHJpbmdfbGVzc3RoYW4iLCJjYW1sX3N0cmluZ19ncmVhdGVydGhhbiIsImNhbWxfc3RyaW5nX2hhc2giLCJjYW1sX3N0cmluZ19ub3RlcXVhbCIsImNhbWxfc3RyaW5nX3NldCIsImNhbWxfc3RyaW5nX3NldDE2IiwiY2FtbF9zdHJpbmdfc2V0MzIiLCJjYW1sX3N0cmluZ19zZXQ2NCIsImNhbWxfc3RyaW5nX3Vuc2FmZV9zZXQiLCJjYW1sX3N5c19hcmd2IiwiY2FtbF9zeXNfY2hkaXIiLCJkaXIiLCJjYW1sX3N5c19jb25zdF9iYWNrZW5kX3R5cGUiLCJjYW1sX3N5c19jb25zdF9iaWdfZW5kaWFuIiwiY2FtbF9zeXNfY29uc3RfaW50X3NpemUiLCJjYW1sX3N5c19jb25zdF9tYXhfd29zaXplIiwiY2FtbF9zeXNfY29uc3RfbmFrZWRfcG9pbnRlcnNfY2hlY2tlZCIsIm9zX3R5cGUiLCJjYW1sX3N5c19jb25zdF9vc3R5cGVfY3lnd2luIiwiY2FtbF9zeXNfY29uc3Rfb3N0eXBlX3VuaXgiLCJjYW1sX3N5c19jb25zdF9vc3R5cGVfd2luMzIiLCJjYW1sX3N5c19jb25zdF93b3JkX3NpemUiLCJjYW1sX3N5c19leGVjdXRhYmxlX25hbWUiLCJjYW1sX3N5c19leGl0IiwiY2FtbF9zeXNfZmlsZV9leGlzdHMiLCJjYW1sX3N5c19nZXRfYXJndiIsImNhbWxfc3lzX2dldF9jb25maWciLCJjYW1sX3N5c19nZXRjd2QiLCJjYW1sX3N5c19nZXRlbnYiLCJjYW1sX3N5c19pc19kaXJlY3RvcnkiLCJjYW1sX3N5c19pc19yZWd1bGFyX2ZpbGUiLCJjYW1sX3N5c19pc2F0dHkiLCJfY2hhbiIsImNhbWxfc3lzX21rZGlyIiwicGVybSIsImNhbWxfc3lzX21vZGlmeV9hcmd2IiwiY2FtbF9zeXNfcmFuZG9tX3NlZWQiLCJub3ciLCJEYXRlIiwiY2FtbF9zeXNfcmVhZF9kaXJlY3RvcnkiLCJjYW1sX3N5c19yZW1vdmUiLCJjYW1sX3N5c19yZW5hbWUiLCJvX3Jvb3QiLCJuX3Jvb3QiLCJjYW1sX3N5c19ybWRpciIsImNhbWxfc3lzX3N5c3RlbV9jb21tYW5kIiwiY2hpbGRfcHJvY2VzcyIsImNhbWxfaW5pdGlhbF90aW1lIiwiY2FtbF9zeXNfdGltZSIsImNhbWxfc3lzX3RpbWVfaW5jbHVkZV9jaGlsZHJlbiIsImNhbWxfc3lzX3Vuc2FmZV9nZXRlbnYiLCJjYW1sX3RhbmhfZmxvYXQiLCJjYW1sX3RvX2pzX3N0cmluZyIsImNhbWxfdHJhbXBvbGluZSIsImNhbWxfdHJhbXBvbGluZV9yZXR1cm4iLCJjYW1sX3RydW5jX2Zsb2F0IiwiY2FtbF91bml4X2NsZWFudXAiLCJjYW1sX3VuaXhfY2xvc2VkaXIiLCJkaXJfaGFuZGxlIiwiY2FtbF91bml4X2ZpbGVkZXNjcl9vZl9mZCIsImNhbWxfdW5peF9maW5kY2xvc2UiLCJjYW1sX3VuaXhfb3BlbmRpciIsImNhbWxfdW5peF9yZWFkZGlyIiwiY2FtbF91bml4X2ZpbmRmaXJzdCIsInBhdGhfanMiLCJmaXJzdF9lbnRyeSIsImNhbWxfdW5peF9maW5kbmV4dCIsImNhbWxfdW5peF9nZXRwd3VpZCIsImNhbWxfdW5peF9nZXR0aW1lb2ZkYXkiLCJjYW1sX3VuaXhfZ2V0dWlkIiwiY2FtbF91bml4X2dtdGltZSIsImRfbnVtIiwiamFudWFyeWZpcnN0IiwiZG95IiwiY2FtbF91bml4X2hhc19zeW1saW5rIiwiY2FtbF91bml4X2luZXRfYWRkcl9vZl9zdHJpbmciLCJjYW1sX3VuaXhfaXNhdHR5IiwiZmlsZURlc2NyaXB0b3IiLCJ0dHkiLCJjYW1sX3VuaXhfbG9jYWx0aW1lIiwiamFuIiwianVsIiwic3RkVGltZXpvbmVPZmZzZXQiLCJjYW1sX3VuaXhfbHN0YXQiLCJjYW1sX3VuaXhfbHN0YXRfNjQiLCJjYW1sX3VuaXhfbWtkaXIiLCJjYW1sX3VuaXhfbWt0aW1lIiwidG0iLCJ0bTIiLCJjYW1sX3VuaXhfcmVhZGxpbmsiLCJjYW1sX3VuaXhfcmV3aW5kZGlyIiwibmV3X2Rpcl9oYW5kbGUiLCJjYW1sX3VuaXhfcm1kaXIiLCJjYW1sX3VuaXhfc3RhcnR1cCIsImNhbWxfdW5peF9zdGF0IiwiY2FtbF91bml4X3N0YXRfNjQiLCJjYW1sX3VuaXhfc3ltbGluayIsInNyY19yb290IiwiZHN0X3Jvb3QiLCJjYW1sX3VuaXhfdGltZSIsImNhbWxfdW5peF91bmxpbmsiLCJjYW1sX3VubW91bnQiLCJjYW1sX3VwZGF0ZV9kdW1teSIsImNhbWxfd2Vha19zZXQiLCJjYW1sX3dyYXBfZXhjZXB0aW9uIiwiY2FtbF94bWxodHRwcmVxdWVzdF9jcmVhdGUiLCJjb21wYXJlX2RpZ2l0c19uYXQiLCJjb21wYXJlX25hdCIsImNvbXBhcmVfbmF0X3JlYWwiLCJjb21wbGVtZW50X25hdCIsImNyZWF0ZV9uYXQiLCJkZWNyX25hdCIsImJvcnJvdyIsImRlc2VyaWFsaXplX25hdCIsImRpdl9oZWxwZXIiLCJkaXZfZGlnaXRfbmF0IiwibmF0cSIsIm9mc3EiLCJuYXRyIiwib2ZzciIsInJlbSIsIm51bV9sZWFkaW5nX3plcm9fYml0c19pbl9kaWdpdCIsInNoaWZ0X2xlZnRfbmF0IiwibmJpdHMiLCJ3cmFwIiwic2hpZnRfcmlnaHRfbmF0Iiwic2V0X3RvX3plcm9fbmF0IiwibmF0X29mX2FycmF5IiwibXVsdF9kaWdpdF9uYXQiLCJuYXQzIiwib2ZzMyIsIngyIiwieDMiLCJzdWJfbmF0IiwiZGl2X25hdCIsInF1byIsInNlcmlhbGl6ZV9uYXQiLCJpbml0aWFsaXplX25hdCIsImlzX2RpZ2l0X2ludCIsImlzX2RpZ2l0X29kZCIsImlzX2RpZ2l0X3plcm8iLCJqc29vX2NyZWF0ZV9maWxlX2V4dGVybiIsImpzb29fZWZmZWN0X25vdF9zdXBwb3J0ZWQiLCJsYW5kX2RpZ2l0X25hdCIsImxlbmd0aF9uYXQiLCJsb3JfZGlnaXRfbmF0IiwibHhvcl9kaWdpdF9uYXQiLCJtdWx0X25hdCIsImxlbjMiLCJudGhfZGlnaXRfbmF0IiwibnRoX2RpZ2l0X25hdF9uYXRpdmUiLCJyZV9tYXRjaCIsInJlX3dvcmRfbGV0dGVycyIsIm9wY29kZXMiLCJpc193b3JkX2xldHRlciIsImluX2JpdHNldCIsInJlX21hdGNoX2ltcGwiLCJwYXJ0aWFsIiwicHJvZyIsImNwb29sIiwibm9ybXRhYmxlIiwibnVtZ3JvdXBzIiwibnVtcmVnaXN0ZXJzIiwic3RhcnRjaGFycyIsInBjIiwicXVpdCIsImdyb3VwcyIsInJlX3JlZ2lzdGVyIiwiYmFja3RyYWNrIiwiaXRlbSIsInB1c2giLCJhY2NlcHQiLCJwcmVmaXhfbWF0Y2giLCJvcCIsInNhcmciLCJ1YXJnIiwiZ3JvdXAiLCJFcnJvciIsInJlX3BhcnRpYWxfbWF0Y2giLCJyZV9yZXBsYWNlbWVudF90ZXh0IiwicmVwbCIsIm9yaWciLCJjdXIiLCJlbmQiLCJyZV9zZWFyY2hfYmFja3dhcmQiLCJyZV9zZWFyY2hfZm9yd2FyZCIsInJlX3N0cmluZ19tYXRjaCIsInNldF9kaWdpdF9uYXQiLCJkaWdpdCIsInNldF9kaWdpdF9uYXRfbmF0aXZlIiwic3F1YXJlX25hdCIsImNhbWxfc2V0dXBfdW5jYXVnaHRfZXhjZXB0aW9uX2hhbmRsZXIiLCJvcmlnaW4iLCJlcmFzZV9yZWwiLCJyZXN0IiwicmVzdCQwIiwicmVzdCQxIiwicmVzdCQyIiwicmVzdCQzIiwicmVzdCQ0IiwicmVzdCQ1IiwicmVzdCQ2IiwicmVzdCQ3IiwidHkiLCJyZXN0JDgiLCJ0eTEiLCJyZXN0JDkiLCJyZXN0JDEwIiwicmVzdCQxMSIsInJlc3QkMTIiLCJyZXN0JDEzIiwiY29uY2F0X2ZtdHR5IiwiZm10dHkxIiwiZm10dHkyIiwidHkyIiwiY29uY2F0X2ZtdCIsImZtdDEiLCJmbXQyIiwicGFkIiwicGFkJDAiLCJwcmVjIiwicGFkJDEiLCJpY29udiIsInByZWMkMCIsInBhZCQyIiwiaWNvbnYkMCIsInByZWMkMSIsInBhZCQzIiwiaWNvbnYkMSIsInByZWMkMiIsInBhZCQ0IiwiaWNvbnYkMiIsInByZWMkMyIsInBhZCQ1IiwiZmNvbnYiLCJwYWQkNiIsInN0ciIsImNociIsImZtdHR5IiwicGFkJDciLCJmbXR0eSQwIiwicGFkJDgiLCJyZXN0JDE0IiwicmVzdCQxNSIsInJlc3QkMTYiLCJmbXRpbmdfbGl0IiwicmVzdCQxNyIsImZtdGluZ19nZW4iLCJyZXN0JDE4IiwicmVzdCQxOSIsImNoYXJfc2V0Iiwid2lkdGhfb3B0IiwicmVzdCQyMCIsImNvdW50ZXIiLCJyZXN0JDIxIiwicmVzdCQyMiIsImlnbiIsInJlc3QkMjMiLCJmIiwiYXJpdHkiLCJtYWtlIiwidiIsImdldCIsInIiLCJzZXQiLCJleGNoYW5nZSIsImN1ciIsImNvbXBhcmVfYW5kX3NldCIsInNlZW4iLCJmZXRjaF9hbmRfYWRkIiwibiIsImluY3IiLCJkZWNyIiwiZmFpbHdpdGgiLCJzIiwiaW52YWxpZF9hcmciLCJtaW4iLCJ4IiwieSIsIm1heCIsImFicyIsImxub3QiLCJpbmZpbml0eSIsIm5lZ19pbmZpbml0eSIsIm5hbiIsIm1heF9mbG9hdCIsIm1pbl9mbG9hdCIsImVwc2lsb25fZmxvYXQiLCJzeW1ib2xfY29uY2F0IiwiY2hhcl9vZl9pbnQiLCJzdHJpbmdfb2ZfYm9vbCIsImIiLCJib29sX29mX3N0cmluZyIsImJvb2xfb2Zfc3RyaW5nX29wdCIsInN0cmluZ19vZl9pbnQiLCJpbnRfb2Zfc3RyaW5nX29wdCIsInZhbGlkX2Zsb2F0X2xleGVtIiwiczEiLCJsIiwiaSIsImkkMCIsInN0cmluZ19vZl9mbG9hdCIsImZsb2F0X29mX3N0cmluZ19vcHQiLCJzeW1ib2wiLCJsMSIsImwyIiwidGwiLCJoZCIsInN0ZGluIiwic3Rkb3V0Iiwic3RkZXJyIiwib3Blbl9vdXRfZ2VuIiwibW9kZSIsInBlcm0iLCJuYW1lIiwiYyIsIm9wZW5fb3V0Iiwib3Blbl9vdXRfYmluIiwiZmx1c2hfYWxsIiwiYSIsIm91dHB1dF9ieXRlcyIsIm9jIiwib3V0cHV0X3N0cmluZyIsIm91dHB1dCIsIm9mcyIsImxlbiIsIm91dHB1dF9zdWJzdHJpbmciLCJvdXRwdXRfdmFsdWUiLCJjaGFuIiwiY2xvc2Vfb3V0IiwiY2xvc2Vfb3V0X25vZXJyIiwib3Blbl9pbl9nZW4iLCJvcGVuX2luIiwib3Blbl9pbl9iaW4iLCJpbnB1dCIsImljIiwidW5zYWZlX3JlYWxseV9pbnB1dCIsIm9mcyQwIiwibGVuJDAiLCJsZW4kMSIsIm9mcyQxIiwicmVhbGx5X2lucHV0IiwicmVhbGx5X2lucHV0X3N0cmluZyIsImlucHV0X2xpbmUiLCJidWlsZF9yZXN1bHQiLCJidWYiLCJwb3MkMCIsImFjY3UiLCJiZWciLCJhY2N1JDAiLCJyZXMiLCJjbG9zZV9pbl9ub2VyciIsInByaW50X2NoYXIiLCJwcmludF9zdHJpbmciLCJwcmludF9ieXRlcyIsInByaW50X2ludCIsInByaW50X2Zsb2F0IiwicHJpbnRfZW5kbGluZSIsInByaW50X25ld2xpbmUiLCJwcmVycl9jaGFyIiwicHJlcnJfc3RyaW5nIiwicHJlcnJfYnl0ZXMiLCJwcmVycl9pbnQiLCJwcmVycl9mbG9hdCIsInByZXJyX2VuZGxpbmUiLCJwcmVycl9uZXdsaW5lIiwicmVhZF9saW5lIiwicmVhZF9pbnQiLCJyZWFkX2ludF9vcHQiLCJyZWFkX2Zsb2F0IiwicmVhZF9mbG9hdF9vcHQiLCJzdHJpbmdfb2ZfZm9ybWF0Iiwic3ltYm9sJDAiLCJzdHIyIiwic3RyMSIsInMyIiwiZXhpdF9mdW5jdGlvbiIsImF0X2V4aXQiLCJmX3lldF90b19ydW4iLCJvbGRfZXhpdCIsImZfeWV0X3RvX3J1biQwIiwib2xkX2V4aXQkMCIsIm5ld19leGl0Iiwic3VjY2VzcyIsImRvX2F0X2V4aXQiLCJleGl0IiwicmV0Y29kZSIsIm1heF9pbnQiLCJtaW5faW50IiwiZmx1c2giLCJvdXRwdXRfY2hhciIsIm91dHB1dF9ieXRlIiwib3V0cHV0X2JpbmFyeV9pbnQiLCJzZWVrX291dCIsInBvc19vdXQiLCJvdXRfY2hhbm5lbF9sZW5ndGgiLCJzZXRfYmluYXJ5X21vZGVfb3V0IiwiaW5wdXRfY2hhciIsImlucHV0X2J5dGUiLCJpbnB1dF9iaW5hcnlfaW50IiwiaW5wdXRfdmFsdWUiLCJzZWVrX2luIiwicG9zX2luIiwiaW5fY2hhbm5lbF9sZW5ndGgiLCJjbG9zZV9pbiIsInNldF9iaW5hcnlfbW9kZV9pbiIsImVtcHR5IiwicmV0dXJuJDAiLCJjb25zIiwibmV4dCIsImFwcGVuZCIsInNlcTEiLCJzZXEyIiwibWFwIiwic2VxIiwiZmlsdGVyX21hcCIsInNlcSQwIiwiZmlsdGVyIiwiY29uY2F0IiwiZmxhdF9tYXAiLCJmb2xkX2xlZnQiLCJhY2MiLCJhY2MkMCIsImFjYyQxIiwiaXRlciIsInVuZm9sZCIsInUiLCJ1JDAiLCJzb21lIiwidmFsdWUiLCJvIiwiZGVmYXVsdCQwIiwiYmluZCIsImpvaW4iLCJmb2xkIiwibm9uZSIsImlzX25vbmUiLCJpc19zb21lIiwiZXF1YWwiLCJlcSIsIm8wIiwibzEiLCJ2MSIsInYwIiwiY29tcGFyZSIsImNtcCIsInRvX3Jlc3VsdCIsInRvX2xpc3QiLCJ0b19zZXEiLCJsZWZ0IiwicmlnaHQiLCJpc19sZWZ0IiwiaXNfcmlnaHQiLCJmaW5kX2xlZnQiLCJmaW5kX3JpZ2h0IiwibWFwX2xlZnQiLCJlIiwibWFwX3JpZ2h0IiwidiQwIiwiZTEiLCJlMiIsInYyIiwidjEkMCIsInYyJDAiLCJvayIsImVycm9yIiwiZ2V0X29rIiwiZ2V0X2Vycm9yIiwibWFwX2Vycm9yIiwiaXRlcl9lcnJvciIsImlzX29rIiwiaXNfZXJyb3IiLCJyMCIsInIxIiwiZTAiLCJ0b19vcHRpb24iLCJ0b19mbG9hdCIsInRvX3N0cmluZyIsImVzY2FwZWQiLCJzJDAiLCJsb3dlcmNhc2UiLCJ1cHBlcmNhc2UiLCJsb3dlcmNhc2VfYXNjaWkiLCJ1cHBlcmNhc2VfYXNjaWkiLCJjMSIsImMyIiwiZXJyX25vX3ByZWQiLCJlcnJfbm9fc3VjYyIsImxvX2JvdW5kIiwiaGlfYm91bmQiLCJzdWNjIiwicHJlZCIsImlzX3ZhbGlkIiwib2ZfaW50IiwiaXNfY2hhciIsIm9mX2NoYXIiLCJ0b19jaGFyIiwidW5zYWZlX3RvX2NoYXIiLCJoYXNoIiwibGVuZ3RoIiwibCQwIiwibnRoIiwibiQwIiwibCQxIiwibiQxIiwibnRoX29wdCIsInJldl9hcHBlbmQiLCJsMSQwIiwibDIkMCIsImwxJDEiLCJsMiQxIiwicmV2IiwiaW5pdF9hdXgiLCJyZXZfaW5pdF90aHJlc2hvbGQiLCJpbml0IiwiZmxhdHRlbiIsIm1hcGkiLCJyZXZfbWFwIiwiaXRlcmkiLCJhY2N1JDEiLCJmb2xkX3JpZ2h0IiwibWFwMiIsImEyIiwiYTEiLCJyZXZfbWFwMiIsIml0ZXIyIiwiZm9sZF9sZWZ0MiIsImZvbGRfcmlnaHQyIiwiZm9yX2FsbCIsInAiLCJleGlzdHMiLCJmb3JfYWxsMiIsImV4aXN0czIiLCJtZW0iLCJtZW1xIiwiYXNzb2MiLCJhc3NvY19vcHQiLCJhc3NxIiwiYXNzcV9vcHQiLCJtZW1fYXNzb2MiLCJtZW1fYXNzcSIsInJlbW92ZV9hc3NvYyIsInBhaXIiLCJyZW1vdmVfYXNzcSIsImZpbmQiLCJmaW5kX29wdCIsImZpbmRfbWFwIiwicmVzdWx0IiwiZmluZF9hbGwiLCJmaWx0ZXJpIiwiY29uY2F0X21hcCIsInhzIiwiZm9sZF9sZWZ0X21hcCIsImxfYWNjdSIsIngkMCIsInBhcnRpdGlvbiIsInllcyIsIm5vIiwicGFydGl0aW9uX21hcCIsInNwbGl0IiwicnkiLCJyeCIsImNvbWJpbmUiLCJtZXJnZSIsInQyIiwiaDIiLCJ0MSIsImgxIiwic3RhYmxlX3NvcnQiLCJzb3J0IiwieDIiLCJ4MSIsInRsJDEiLCJ4MyIsIngyJDAiLCJ4MSQwIiwibjEiLCJuMiIsInJldl9zb3J0IiwidGwkMCIsInNvcnRfdW5pcSIsImMkMCIsImMkMSIsImMkMiIsImMkMyIsImMkNCIsImMkNSIsImMkNiIsImFjY3UkMiIsImNvbXBhcmVfbGVuZ3RocyIsImNvbXBhcmVfbGVuZ3RoX3dpdGgiLCJhdXgiLCJ0YWlsIiwib2Zfc2VxIiwiZGlyZWN0IiwiZGVwdGgiLCJsb2dub3QiLCJjb3B5Iiwib2Zfc3RyaW5nIiwic3ViIiwic3ViX3N0cmluZyIsImV4dGVuZCIsImRzdG9mZiIsInNyY29mZiIsImNweWxlbiIsImZpbGwiLCJibGl0Iiwib2ZzMSIsIm9mczIiLCJibGl0X3N0cmluZyIsInNlcCIsInNlcGxlbiIsImRzdCIsInBvcyIsImhkJDAiLCJjYXQiLCJpc19zcGFjZSIsInRyaW0iLCJqIiwiYXBwbHkxIiwiY2FwaXRhbGl6ZV9hc2NpaSIsInVuY2FwaXRhbGl6ZV9hc2NpaSIsInN0YXJ0c193aXRoIiwicHJlZml4IiwibGVuX3MiLCJsZW5fcHJlIiwiZW5kc193aXRoIiwic3VmZml4IiwibGVuX3N1ZiIsImRpZmYiLCJpbmRleF9yZWMiLCJsaW0iLCJpJDEiLCJpbmRleCIsImluZGV4X3JlY19vcHQiLCJpbmRleF9vcHQiLCJpbmRleF9mcm9tIiwiaW5kZXhfZnJvbV9vcHQiLCJyaW5kZXhfcmVjIiwicmluZGV4IiwicmluZGV4X2Zyb20iLCJyaW5kZXhfcmVjX29wdCIsInJpbmRleF9vcHQiLCJyaW5kZXhfZnJvbV9vcHQiLCJjb250YWluc19mcm9tIiwiY29udGFpbnMiLCJyY29udGFpbnNfZnJvbSIsInNwbGl0X29uX2NoYXIiLCJjYXBpdGFsaXplIiwidW5jYXBpdGFsaXplIiwidG9fc2VxaSIsIm5ld19sZW4iLCJuZXdfYnVmIiwiZ2V0X2ludDgiLCJnZXRfdWludDE2X2xlIiwiZ2V0X3VpbnQxNl9iZSIsImdldF9pbnQxNl9uZSIsImdldF9pbnQxNl9sZSIsImdldF9pbnQxNl9iZSIsImdldF9pbnQzMl9sZSIsImdldF9pbnQzMl9iZSIsImdldF9pbnQ2NF9sZSIsImdldF9pbnQ2NF9iZSIsInNldF9pbnQxNl9sZSIsInNldF9pbnQxNl9iZSIsInNldF9pbnQzMl9sZSIsInNldF9pbnQzMl9iZSIsInNldF9pbnQ2NF9sZSIsInNldF9pbnQ2NF9iZSIsInNldF91aW50OCIsInNldF91aW50MTZfbmUiLCJidHMiLCJib3MiLCJvZl9ieXRlcyIsInRvX2J5dGVzIiwiZyIsInRvX2J1ZmZlciIsImJ1ZmYiLCJmbGFncyIsImRhdGFfc2l6ZSIsInRvdGFsX3NpemUiLCJmcm9tX2J5dGVzIiwiZnJvbV9zdHJpbmciLCJpc19ibG9jayIsImRvdWJsZV9maWVsZCIsInNldF9kb3VibGVfZmllbGQiLCJtYXJzaGFsIiwib2JqIiwidW5tYXJzaGFsIiwiY3VzdG9tX3RhZyIsImluZm8iLCJzdGFydF9lbnYiLCJvZl92YWwiLCJzbG90IiwiaWQiLCJleHRlbnNpb25fY29uc3RydWN0b3IiLCJleHRlbnNpb25fbmFtZSIsImV4dGVuc2lvbl9pZCIsIm1heF9lcGhlX2xlbmd0aCIsImNyZWF0ZSIsInJhaXNlX2lmX2ludmFsaWRfb2Zmc2V0IiwibXNnIiwiZ2V0X2tleSIsImdldF9rZXlfY29weSIsInNldF9rZXkiLCJ1bnNldF9rZXkiLCJjaGVja19rZXkiLCJibGl0X2tleSIsIm8yIiwibWFrZV9mbG9hdCIsIm1ha2VfbWF0cml4Iiwic3giLCJzeSIsImxhIiwibGIiLCJyZXMkMCIsImxpc3RfbGVuZ3RoIiwidCIsIm9mX2xpc3QiLCJpbnB1dF9hcnJheSIsImVsdCIsIm91dHB1dF9hcnJheSIsImVsdCQwIiwiYWNjJDIiLCJiMCIsImEwIiwiYmkiLCJhaSIsIm5hIiwibmIiLCJtYXhzb24iLCJpMzEiLCJpJDYiLCJlJDEiLCJpJDQiLCJlJDAiLCJpJDUiLCJqJDAiLCJpJDIiLCJpJDMiLCJmYXRoZXIiLCJzcmMxb2ZzIiwic3JjMWxlbiIsInNyYzIiLCJzcmMyb2ZzIiwic3JjMmxlbiIsImRzdG9mcyIsInNyYzFyIiwic3JjMnIiLCJzMiQxIiwiczEkMSIsImkxIiwiaTIiLCJkIiwiaTIkMCIsImQkMCIsInMyJDAiLCJpMSQwIiwiZCQxIiwiczEkMCIsImlzb3J0dG8iLCJzcmNvZnMiLCJzb3J0dG8iLCJpc19maW5pdGUiLCJpc19pbmZpbml0ZSIsImlzX25hbiIsImVwc2lsb24iLCJvZl9zdHJpbmdfb3B0IiwiaXNfaW50ZWdlciIsIm1pbl9tYXgiLCJtaW5fbnVtIiwibWF4X251bSIsIm1pbl9tYXhfbnVtIiwidW5zYWZlX2ZpbGwiLCJjaGVjayIsImhsZW4iLCJzcmMiLCJzb2ZzIiwiZG9mcyIsImgiLCJtZW1faWVlZSIsIm1hcF90b19hcnJheSIsIm1hcF9mcm9tX2FycmF5IiwiemVybyIsIm9uZSIsIm1pbnVzX29uZSIsIm1heF9pbnQkMCIsInVuc2lnbmVkX3RvX2ludCIsInVuc2lnbmVkX2NvbXBhcmUiLCJtIiwidW5zaWduZWRfZGl2IiwicSIsInVuc2lnbmVkX3JlbSIsInNpemUiLCJkdW1teV9wb3MiLCJ6ZXJvX3BvcyIsImVuZ2luZSIsInRibCIsInN0YXRlIiwibmV3X2VuZ2luZSIsImZyb21fZnVuY3Rpb24iLCJvcHQiLCJyZWFkX2Z1biIsInN0aCIsIndpdGhfcG9zaXRpb25zIiwiYXV4X2J1ZmZlciIsImxleGJ1ZiIsInJlYWQiLCJuZXdsZW4iLCJuZXdidWYiLCJmcm9tX2NoYW5uZWwiLCJzZXRfcG9zaXRpb24iLCJwb3NpdGlvbiIsInNldF9maWxlbmFtZSIsImZuYW1lIiwibGV4ZW1lIiwic3ViX2xleGVtZSIsInN1Yl9sZXhlbWVfb3B0Iiwic3ViX2xleGVtZV9jaGFyIiwic3ViX2xleGVtZV9jaGFyX29wdCIsImxleGVtZV9jaGFyIiwibGV4ZW1lX3N0YXJ0IiwibGV4ZW1lX2VuZCIsImxleGVtZV9zdGFydF9wIiwibGV4ZW1lX2VuZF9wIiwibmV3X2xpbmUiLCJsY3AiLCJmbHVzaF9pbnB1dCIsImVudiIsImdyb3dfc3RhY2tzIiwib2xkc2l6ZSIsIm5ld3NpemUiLCJuZXdfcyIsIm5ld192IiwibmV3X3N0YXJ0IiwibmV3X2VuZCIsImNsZWFyX3BhcnNlciIsImN1cnJlbnRfbG9va2FoZWFkX2Z1biIsInl5cGFyc2UiLCJ0YWJsZXMiLCJzdGFydCIsImxleGVyIiwiaW5pdF9hc3AiLCJpbml0X3NwIiwiaW5pdF9zdGFja2Jhc2UiLCJpbml0X3N0YXRlIiwiaW5pdF9jdXJyX2NoYXIiLCJpbml0X2x2YWwiLCJpbml0X2VycmZsYWciLCJjbWQiLCJhcmciLCJhcmckMCIsImFjdGlvbiIsImV4biQwIiwiZXhuIiwiY3Vycl9jaGFyIiwidG9rIiwicGVla192YWwiLCJzeW1ib2xfc3RhcnRfcG9zIiwic3QiLCJlbiIsInN5bWJvbF9lbmRfcG9zIiwicmhzX3N0YXJ0X3BvcyIsInJoc19lbmRfcG9zIiwic3ltYm9sX3N0YXJ0Iiwic3ltYm9sX2VuZCIsInJoc19zdGFydCIsInJoc19lbmQiLCJpc19jdXJyZW50X2xvb2thaGVhZCIsInBhcnNlX2Vycm9yIiwiaGVpZ2h0IiwiaGwiLCJoJDAiLCJociIsImJhbCIsImxyIiwibHYiLCJsbCIsImxyciIsImxydiIsImxybCIsInJyIiwicnYiLCJybCIsInJsciIsInJsdiIsInJsbCIsImFkZCIsInNpbmdsZXRvbiIsImFkZF9taW5fZWxlbWVudCIsImFkZF9tYXhfZWxlbWVudCIsInJoIiwibGgiLCJtaW5fZWx0IiwibWluX2VsdF9vcHQiLCJtYXhfZWx0IiwibWF4X2VsdF9vcHQiLCJyZW1vdmVfbWluX2VsdCIsInIkMCIsInByZXMiLCJwcmVzJDAiLCJpc19lbXB0eSIsInJlbW92ZSIsInVuaW9uIiwicjIiLCJyMiQwIiwicjEkMCIsImludGVyIiwic3BsaXRfYmlzIiwiZGlzam9pbnQiLCJjb25zX2VudW0iLCJlMiQyIiwiZTEkMiIsImUyJDAiLCJlMSQwIiwiZTIkMSIsImUxJDEiLCJzdWJzZXQiLCJwdiIsImxmIiwibHQiLCJyZiIsInJ0IiwiY2FyZGluYWwiLCJlbGVtZW50c19hdXgiLCJlbGVtZW50cyIsImZpbmRfZmlyc3QiLCJ2MCQxIiwidjAkMCIsImZpbmRfZmlyc3Rfb3B0IiwiZmluZF9sYXN0IiwiZmluZF9sYXN0X29wdCIsInRyeV9qb2luIiwidiQxIiwieDAiLCJsJDMiLCJsJDQiLCJ4MCQwIiwibCQ1IiwieDAkMSIsIm5sIiwibWlkIiwibCQyIiwieDQiLCJhZGRfc2VxIiwic2VxX29mX2VudW0iLCJzbm9jX2VudW0iLCJyZXZfc2VxX29mX2VudW0iLCJ0b19yZXZfc2VxIiwidG9fc2VxX2Zyb20iLCJsb3ciLCJsZCIsImxyZCIsInJkIiwicmxkIiwiZGF0YSIsImQwJDEiLCJkMCIsImQwJDAiLCJtaW5fYmluZGluZyIsIm1pbl9iaW5kaW5nX29wdCIsIm1heF9iaW5kaW5nIiwibWF4X2JpbmRpbmdfb3B0IiwicmVtb3ZlX21pbl9iaW5kaW5nIiwidXBkYXRlIiwiZGF0YSQwIiwibSQwIiwiYWRkX21pbl9iaW5kaW5nIiwiayIsImFkZF9tYXhfYmluZGluZyIsImNvbmNhdF9vcl9qb2luIiwiZDEiLCJkMiIsImQyJDAiLCJkMSQwIiwiZDIkMSIsImQxJDEiLCJwdmQiLCJmdmQiLCJtMSIsIm0yIiwiYmluZGluZ3NfYXV4IiwiYmluZGluZ3MiLCJjbGVhciIsInB1c2giLCJwb3AiLCJwb3Bfb3B0IiwidG9wIiwidG9wX29wdCIsImNlbGwiLCJtYXRjaCIsInBlZWsiLCJjb250ZW50IiwicGVla19vcHQiLCJ0YWtlIiwidGFrZV9vcHQiLCJjZWxsJDAiLCJxX3JlcyIsInByZXYiLCJwcmV2JDAiLCJ0cmFuc2ZlciIsInExIiwicTIiLCJyYWlzZV91bmRlZmluZWQiLCJmb3JjZV9sYXp5X2Jsb2NrIiwiYmxrIiwiY2xvc3VyZSIsImZvcmNlX3ZhbF9sYXp5X2Jsb2NrIiwiZm9yY2UiLCJsenYiLCJmb3JjZV92YWwiLCJmcm9tX2Z1biIsImZyb21fdmFsIiwiaXNfdmFsIiwibWFwX3ZhbCIsImNvdW50IiwiZmlsbF9idWZmIiwiZ2V0X2RhdGEiLCJkMTEiLCJhJDAiLCJhJDEiLCJwZWVrX2RhdGEiLCJqdW5rX2RhdGEiLCJqdW5rIiwibmdldF9kYXRhIiwiYWwiLCJucGVlayIsInN0cm0iLCJmcm9tIiwib2ZfY2hhbm5lbCIsImlhcHAiLCJpY29ucyIsImlzaW5nIiwibGFwcCIsImxjb25zIiwibHNpbmciLCJzbGF6eSIsImR1bXAiLCJkdW1wX2RhdGEiLCJjb250ZW50cyIsInJlc2V0IiwicmVzaXplIiwibW9yZSIsIm9sZF9wb3MiLCJvbGRfbGVuIiwibmV3X2J1ZmZlciIsImFkZF9jaGFyIiwiYWRkX3V0Zl84X3VjaGFyIiwicG9zJDEiLCJhZGRfdXRmXzE2YmVfdWNoYXIiLCJ1JDEiLCJoaSIsImxvIiwiYWRkX3V0Zl8xNmxlX3VjaGFyIiwiYWRkX3N1YnN0cmluZyIsIm9mZnNldCIsIm5ld19wb3NpdGlvbiIsImFkZF9zdWJieXRlcyIsImFkZF9zdHJpbmciLCJhZGRfYnl0ZXMiLCJhZGRfYnVmZmVyIiwiYnMiLCJhZGRfY2hhbm5lbCIsInRvX3JlYWQkMSIsImFscmVhZHlfcmVhZCIsInRvX3JlYWQiLCJhbHJlYWR5X3JlYWQkMCIsInRvX3JlYWQkMCIsIm91dHB1dF9idWZmZXIiLCJhZGRfc3Vic3RpdHV0ZSIsImxpbSQxIiwicHJldmlvdXMiLCJwcmV2aW91cyQwIiwic3RhcnQkMCIsIm9wZW5pbmciLCJsaW0kMCIsInN0b3AkMCIsImskMiIsImNsb3NpbmciLCJzdG9wIiwiayQwIiwiayQxIiwibmV4dF9pIiwiaWRlbnQiLCJpJDciLCJpJDgiLCJ0cnVuY2F0ZSIsImFkZF9pbnQ4IiwiYWRkX2ludDE2X25lIiwiYWRkX2ludDMyX25lIiwiYWRkX2ludDY0X25lIiwiYWRkX2ludDE2X2xlIiwiYWRkX2ludDE2X2JlIiwiYWRkX2ludDMyX2xlIiwiYWRkX2ludDMyX2JlIiwiYWRkX2ludDY0X2xlIiwiYWRkX2ludDY0X2JlIiwic3ViX2Zvcm1hdCIsImZvcm1hdHRpbmdfbGl0IiwiY3JlYXRlX2NoYXJfc2V0IiwiYWRkX2luX2NoYXJfc2V0Iiwic3RyX2luZCIsIm1hc2siLCJmcmVlemVfY2hhcl9zZXQiLCJyZXZfY2hhcl9zZXQiLCJjaGFyX3NldCQwIiwiaXNfaW5fY2hhcl9zZXQiLCJwYWRfb2ZfcGFkX29wdCIsInBhZF9vcHQiLCJ3aWR0aCIsInBhcmFtX2Zvcm1hdF9vZl9pZ25vcmVkX2Zvcm1hdCIsImZtdCIsInBhZF9vcHQkMCIsInBhZF9vcHQkMSIsInBhZF9vcHQkMiIsInBhZF9vcHQkMyIsInBhZF9vcHQkNCIsInByZWNfb3B0IiwicGFkX29wdCQ1IiwibmRlYyIsInBhZF9vcHQkNiIsInBhZF9vcHQkNyIsInBhZF9vcHQkOCIsImRlZmF1bHRfZmxvYXRfcHJlY2lzaW9uIiwiYnVmZmVyX2NyZWF0ZSIsImluaXRfc2l6ZSIsImJ1ZmZlcl9jaGVja19zaXplIiwib3ZlcmhlYWQiLCJtaW5fbGVuIiwibmV3X3N0ciIsImJ1ZmZlcl9hZGRfY2hhciIsImJ1ZmZlcl9hZGRfc3RyaW5nIiwic3RyX2xlbiIsImJ1ZmZlcl9jb250ZW50cyIsImNoYXJfb2ZfaWNvbnYiLCJjaGFyX29mX2Zjb252IiwiY0YiLCJicHJpbnRfcGFkdHkiLCJwYWR0eSIsImJwcmludF9pZ25vcmVkX2ZsYWciLCJpZ25fZmxhZyIsImJwcmludF9wYWRfb3B0IiwiYnByaW50X3BhZGRpbmciLCJwYWR0eSQwIiwiYnByaW50X3ByZWNpc2lvbiIsImJwcmludF9pY29udl9mbGFnIiwiYnByaW50X2FsdGludF9mbXQiLCJicHJpbnRfZmNvbnZfZmxhZyIsInN0cmluZ19vZl9mb3JtYXR0aW5nX2xpdCIsInN0ciQwIiwiYnByaW50X2NoYXJfbGl0ZXJhbCIsImJwcmludF9zdHJpbmdfbGl0ZXJhbCIsImJwcmludF9mbXR0eSIsImZtdHR5JDEiLCJmbXR0eSQyIiwiZm10dHkkMyIsImZtdHR5JDQiLCJmbXR0eSQ1IiwiZm10dHkkNiIsImZtdHR5JDciLCJmbXR0eSQ4IiwiZm10dHkkOSIsInN1Yl9mbXR0eSIsImZtdHR5JDEwIiwic3ViX2ZtdHR5JDAiLCJmbXR0eSQxMSIsImZtdHR5JDEyIiwiZm10dHkkMTMiLCJmbXR0eSQxNCIsImZtdHR5JDE1IiwiaW50X29mX2N1c3RvbV9hcml0eSIsInN0cmluZ19vZl9mbXQiLCJmbXRpdGVyIiwiZm10JDAiLCJpZ25fZmxhZyQwIiwic3RyJDEiLCJzZXQkMCIsImlzX2Fsb25lIiwiYWZ0ZXIiLCJiZWZvcmUiLCJqJDEiLCJmbXQkMSIsInN5bW0iLCJmbXR0eV9yZWxfZGV0IiwiZGUiLCJlZCIsImFmIiwiZmEiLCJkZSQwIiwiZWQkMCIsImFmJDAiLCJmYSQwIiwiZGUkMSIsImVkJDEiLCJhZiQxIiwiZmEkMSIsImRlJDIiLCJlZCQyIiwiYWYkMiIsImZhJDIiLCJkZSQzIiwiZWQkMyIsImFmJDMiLCJmYSQzIiwiZGUkNCIsImVkJDQiLCJhZiQ0IiwiZmEkNCIsImRlJDUiLCJlZCQ1IiwiYWYkNSIsImZhJDUiLCJkZSQ2IiwiZWQkNiIsImFmJDYiLCJmYSQ2IiwiZGUkNyIsImVkJDciLCJhZiQ3IiwiZmEkNyIsImRlJDgiLCJlZCQ4IiwiYWYkOCIsImZhJDgiLCJ0cmFucyIsImpkIiwiZGoiLCJnYSIsImFnIiwiZGUkOSIsImVkJDkiLCJhZiQ5IiwiZmEkOSIsImRlJDEwIiwiZWQkMTAiLCJhZiQxMCIsImZhJDEwIiwiZGUkMTEiLCJlZCQxMSIsImFmJDExIiwiZmEkMTEiLCJkZSQxMiIsImVkJDEyIiwiYWYkMTIiLCJmYSQxMiIsImRlJDEzIiwiZWQkMTMiLCJhZiQxMyIsImZhJDEzIiwicmVzdDEiLCJyZXN0MiIsInJlc3QxJDAiLCJyZXN0MiQwIiwicmVzdDEkMSIsInJlc3QyJDEiLCJyZXN0MSQyIiwicmVzdDIkMiIsInJlc3QxJDMiLCJyZXN0MiQzIiwicmVzdDEkNCIsInJlc3QyJDQiLCJyZXN0MSQ1IiwicmVzdDIkNSIsInJlc3QxJDYiLCJyZXN0MiQ2IiwicmVzdDEkNyIsInR5MSQwIiwicmVzdDIkNyIsInR5MiQwIiwicmVzdDEkOCIsInR5MTIiLCJ0eTExIiwicmVzdDIkOCIsInR5MjIiLCJ0eTIxIiwiZjQiLCJmMiIsInJlc3QxJDkiLCJyZXN0MiQ5IiwicmVzdDEkMTAiLCJyZXN0MiQxMCIsInJlc3QxJDExIiwicmVzdDIkMTEiLCJyZXN0MSQxMiIsInJlc3QyJDEyIiwicmVzdDEkMTMiLCJyZXN0MiQxMyIsImZtdHR5X29mX2ZtdCIsImZtdHR5X29mX3BhZGRpbmdfZm10dHkiLCJ0eV9yZXN0IiwicHJlY190eSIsImZtdHR5X29mX3ByZWNpc2lvbl9mbXR0eSIsInR5X3Jlc3QkMCIsInByZWNfdHkkMCIsInR5X3Jlc3QkMSIsInByZWNfdHkkMSIsInR5X3Jlc3QkMiIsInByZWNfdHkkMiIsInR5X3Jlc3QkMyIsInByZWNfdHkkMyIsInR5JDAiLCJmb3JtYXR0aW5nX2dlbiIsImZtdHR5X29mX2N1c3RvbSIsImFyaXR5JDAiLCJ0eXBlX3BhZGRpbmciLCJ3IiwidHlwZV9wYWRwcmVjIiwidHlwZV9mb3JtYXQiLCJ0eXBlX2Zvcm1hdF9nZW4iLCJmbXR0eTAiLCJmbXR0eV9yZXN0IiwiZm10X3Jlc3QiLCJmbXR0eV9yZXN0JDAiLCJmbXRfcmVzdCQwIiwiZm10X3Jlc3QkMSIsImZtdHR5X3Jlc3QkMSIsImZtdCQyIiwiZm10X3Jlc3QkMiIsImZtdHR5X3Jlc3QkMiIsImZtdCQzIiwiZm10X3Jlc3QkMyIsImZtdHR5X3Jlc3QkMyIsImZtdCQ0IiwiZm10X3Jlc3QkNCIsImZtdHR5X3Jlc3QkNCIsImZtdCQ1IiwiZm10X3Jlc3QkNSIsImZtdHR5X3Jlc3QkNSIsInByZWMkNCIsImZtdCQ2IiwiZm10X3Jlc3QkNiIsInByZWMkNSIsInBhZCQ5IiwicGFkJDEwIiwiZm10dHlfcmVzdCQ2IiwicHJlYyQ2IiwiZm10JDciLCJmbXRfcmVzdCQ3IiwicHJlYyQ3IiwicGFkJDExIiwicGFkJDEyIiwiZm10dHlfcmVzdCQ3IiwicHJlYyQ4IiwiZm10JDgiLCJmbXRfcmVzdCQ4IiwicGFkJDEzIiwicGFkJDE0IiwiZm10dHlfcmVzdCQ4IiwiZm10JDkiLCJmbXRfcmVzdCQ5IiwiZm10JDEwIiwiZm10X3Jlc3QkMTAiLCJmbXQkMTEiLCJmbXRfcmVzdCQxMSIsImZtdCQxMiIsImZtdHR5X3Jlc3QkOSIsImZtdF9yZXN0JDEyIiwiZm10JDEzIiwiZm10dHlfcmVzdCQxMCIsInN1Yl9mbXR0eTEiLCJmbXRfcmVzdCQxMyIsInN1Yl9mbXR0eSQxIiwiZm10JDE0IiwiZm10dHlfcmVzdCQxMSIsImZtdF9yZXN0JDE0IiwiZm10JDE1IiwiZm10dHlfcmVzdCQxMiIsImZtdF9yZXN0JDE1IiwiZm10JDE2IiwiZm10X3Jlc3QkMTYiLCJmbXR0eSQxNiIsImZtdCQxNyIsImZtdF9yZXN0JDE3IiwiZm10dHkzIiwiZm10MyIsImZtdDEkMCIsImZtdHR5MiQwIiwiZm10MiQwIiwiZm10dHkzJDAiLCJmbXQzJDAiLCJmbXR0eV9yZXN0JDEzIiwiZm10X3Jlc3QkMTgiLCJmbXR0eSQxNyIsImZtdCQxOCIsImZtdHR5X3Jlc3QkMTQiLCJmbXRfcmVzdCQxOSIsImZtdHR5JDE4IiwiZm10JDE5IiwiZm10dHlfcmVzdCQxNSIsImZtdF9yZXN0JDIwIiwiZm10dHkkMTkiLCJmbXQkMjAiLCJ0eXBlX2lnbm9yZWRfcGFyYW1fb25lIiwic3ViX2ZtdHR5JDIiLCJzdWJfZm10dHkkMyIsInR5cGVfaWdub3JlZF9mb3JtYXRfc3Vic3RpdHV0aSIsImZtdHR5JDIxIiwiZm10JDIyIiwic3ViX2ZtdHR5JDQiLCJmbXR0eV9yZXN0JDE2IiwiZm10dHkkMjAiLCJmbXQkMjEiLCJzdWJfZm10dHlfcmVzdCIsInN1Yl9mbXR0eV9yZXN0JDAiLCJzdWJfZm10dHlfcmVzdCQxIiwic3ViX2ZtdHR5X3Jlc3QkMiIsInN1Yl9mbXR0eV9yZXN0JDMiLCJzdWJfZm10dHlfcmVzdCQ0Iiwic3ViX2ZtdHR5X3Jlc3QkNSIsInN1Yl9mbXR0eV9yZXN0JDYiLCJzdWJfZm10dHlfcmVzdCQ3Iiwic3ViX2ZtdHR5X3Jlc3QkOCIsInN1Yl9mbXR0eV9yZXN0JDkiLCJzdWJfZm10dHlfcmVzdCQxMCIsInN1Yl9mbXR0eV9yZXN0JDExIiwic3ViX2ZtdHR5X3Jlc3QkMTIiLCJzdWJfZm10dHlfcmVzdCQxMyIsInN1Yl9mbXR0eV9yZXN0JDE0Iiwic3ViMl9mbXR0eSIsInN1Yl9mbXR0eV9yZXN0JDE1Iiwic3ViMl9mbXR0eSQwIiwic3ViX2ZtdHR5X3Jlc3QkMTYiLCJzdWIyX2ZtdHR5JDEiLCJzdWIxX2ZtdHR5Iiwic3ViX2ZtdHR5X3Jlc3QkMTciLCJzdWIyX2ZtdHR5JDIiLCJzdWIxX2ZtdHR5JDAiLCJzdWJfZm10dHlfcmVzdCQxOCIsInN1Yl9mbXR0eV9yZXN0JDE5Iiwic3ViX2ZtdHR5X3Jlc3QkMjAiLCJzdWJfZm10dHlfcmVzdCQyMSIsInN1Yl9mbXR0eV9yZXN0JDIyIiwic3ViX2ZtdHR5X3Jlc3QkMjMiLCJzdWJfZm10dHlfcmVzdCQyNCIsInN1Yl9mbXR0eV9yZXN0JDI1Iiwic3ViX2ZtdHR5X3Jlc3QkMjYiLCJyZWNhc3QiLCJmaXhfcGFkZGluZyIsIndpZHRoJDAiLCJmaXhfaW50X3ByZWNpc2lvbiIsInJlcyQxIiwic3RyaW5nX3RvX2NhbWxfc3RyaW5nIiwiZm9ybWF0X29mX2Zjb252Iiwic3ltYiIsInRyYW5zZm9ybV9pbnRfYWx0IiwiZGlnaXRzIiwicHV0IiwiY29udmVydF9pbnQiLCJjb252ZXJ0X2ludDMyIiwiY29udmVydF9uYXRpdmVpbnQiLCJjb252ZXJ0X2ludDY0IiwiY29udmVydF9mbG9hdCIsImhleCIsInNpZ24iLCJjYW1sX3NwZWNpYWxfdmFsIiwic3RyaW5nX29mX2ZtdHR5IiwibWFrZV9wcmludGYkMCIsIm5ld19hY2MiLCJtYWtlX3ByaW50ZiIsIm1ha2VfcGFkZGluZyIsIm1ha2VfaW50X3BhZGRpbmdfcHJlY2lzaW9uIiwicCQwIiwicCQxIiwiYWNjJDMiLCJhY2MkNCIsImthY2MiLCJtYWtlX2lnbm9yZWRfcGFyYW0kMCIsIm1ha2VfY3VzdG9tJDAiLCJtYWtlX2ludmFsaWRfYXJnIiwibWFrZV9mcm9tX2ZtdHR5JDAiLCJtYWtlX2lnbm9yZWRfcGFyYW0iLCJtYWtlX2Zyb21fZm10dHkiLCJtYWtlX2N1c3RvbSIsIm1ha2VfaXByaW50ZiQwIiwibWFrZV9pcHJpbnRmIiwieCQxIiwieCQyIiwieCQzIiwieCQ0IiwieCQ1IiwieCQ2IiwieCQ3IiwieCQ4IiwiZm5fb2ZfcGFkZGluZ19wcmVjaXNpb24iLCJ4JDkiLCJ4JDEwIiwieCQxMSIsIngkMTIiLCJ4JDEzIiwieCQxNCIsIngkMTUiLCJ4JDE2Iiwia29jIiwicmVzdCQyNCIsInJlc3QkMjUiLCJ4JDE3IiwicmVzdCQyNiIsIngkMTgiLCJyZXN0JDI3IiwieCQxOSIsInJlc3QkMjgiLCJyZXN0JDI5IiwiZm5fb2ZfY3VzdG9tX2FyaXR5JDAiLCJmbl9vZl9jdXN0b21fYXJpdHkiLCJvdXRwdXRfYWNjIiwicCQzIiwicCQ0IiwicCQ1IiwicCQyIiwiYnVmcHV0X2FjYyIsInN0cnB1dF9hY2MiLCJmYWlsd2l0aF9tZXNzYWdlIiwib3Blbl9ib3hfb2Zfc3RyaW5nIiwiaW52YWxpZF9ib3giLCJwYXJzZV9zcGFjZXMiLCJ3c3RhcnQiLCJ3ZW5kIiwiYm94X25hbWUiLCJuc3RhcnQiLCJuZW5kIiwiaW5kZW50IiwiZXhwX2VuZCIsImJveF90eXBlIiwibWFrZV9wYWRkaW5nX2ZtdF9lYmIiLCJtYWtlX3BhZHByZWNfZm10X2ViYiIsImZtdF9lYmJfb2Zfc3RyaW5nIiwibGVnYWN5X2JlaGF2aW9yIiwiZmxhZyIsImxlZ2FjeV9iZWhhdmlvciQwIiwiaW52YWxpZF9mb3JtYXRfbWVzc2FnZSIsImludmFsaWRfZm9ybWF0X3dpdGhvdXQiLCJleHBlY3RlZF9jaGFyYWN0ZXIiLCJleHBlY3RlZCIsInBhcnNlIiwibGl0X3N0YXJ0IiwiZW5kX2luZCIsImFkZF9saXRlcmFsIiwic3RyX2luZCQxIiwic3RyX2luZCQyIiwicGFyc2VfZmxhZ3MiLCJzdHJfaW5kJDAiLCJwYXJzZV90YWciLCJzdHJfaW5kJDMiLCJzdHJfaW5kXzEiLCJwYXJzZV9pbnRlZ2VyIiwic3RyX2luZF8yIiwic3RyX2luZF8zIiwiZm9ybWF0dGluZ19saXQkMCIsIm5leHRfaW5kIiwic3RyX2luZF80Iiwic3RyX2luZF81Iiwic3RyX2luZCQ0Iiwic3RyX2luZF8xJDAiLCJzdHJfaW5kXzIkMCIsInN0cl9pbmRfMyQwIiwicyQxIiwiZm9ybWF0dGluZ19saXQkMSIsIm5leHRfaW5kJDAiLCJwY3RfaW5kIiwibWludXMiLCJwbHVzIiwic3BhY2UiLCJzZXRfZmxhZyIsInN0cl9pbmQkNSIsInNwYWNlJDAiLCJoYXNoJDAiLCJwbHVzJDAiLCJtaW51cyQwIiwiemVybyQwIiwiaW5jb21wYXRpYmxlX2ZsYWciLCJwYXJzZV9wb3NpdGl2ZSIsIm5ld19pbmQiLCJwYXJzZV9hZnRlcl9wYWRkaW5nIiwicGFyc2VfY29udmVyc2lvbiIsInBhcnNlX2xpdGVyYWwiLCJwYXJzZV9hZnRlcl9wcmVjaXNpb24iLCJzeW1iJDAiLCJwYXJzZV9jb252IiwicGFkcHJlYyIsInBsdXNfdXNlZCIsImhhc2hfdXNlZCIsInNwYWNlX3VzZWQiLCJpZ25fdXNlZCIsInBhZF91c2VkIiwicHJlY191c2VkIiwiZ2V0X3BsdXMiLCJnZXRfaGFzaCIsImdldF9zcGFjZSIsImdldF9pZ24iLCJnZXRfcGFkIiwiZ2V0X3ByZWMiLCJnZXRfcGFkcHJlYyIsImdldF9pbnRfcGFkIiwiY2hlY2tfbm9fMCIsIm9wdF9vZl9wYWQiLCJ3aWR0aCQxIiwiZ2V0X3BhZF9vcHQiLCJnZXRfcGFkcHJlY19vcHQiLCJmbXRfcmVzdWx0Iiwic3ViX2VuZCIsInNlYXJjaF9zdWJmb3JtYXRfZW5kIiwic3ViX2ZtdCIsImlnbm9yZWQkMiIsImNvdW50ZXIkMCIsImlnbm9yZWQkNiIsImlnbm9yZWQkNyIsImFkZF9yYW5nZSIsImZhaWxfc2luZ2xlX3BlcmNlbnQiLCJwYXJzZV9jaGFyX3NldF9jb250ZW50IiwicGFyc2VfY2hhcl9zZXRfYWZ0ZXJfY2hhciQwIiwicGFyc2VfY2hhcl9zZXRfYWZ0ZXJfY2hhciIsInJldmVyc2UiLCJjaGFyX3NldCQxIiwiaWdub3JlZCQ5IiwiY2hhcl9mb3JtYXQiLCJmbXRfcmVzdCQyMSIsImZtdF9yZXN0JDIyIiwiZm10X3Jlc3QkMjMiLCJpZ25vcmVkJDEwIiwiZm10X3Jlc3QkMjQiLCJmbXRfcmVzdCQyNSIsInN1Yl9lbmQkMCIsInN1Yl9mbXQkMCIsImZtdF9yZXN0JDI2IiwiaWdub3JlZCQxMSIsImlnbm9yZWQkMyIsImlnbm9yZWQkNSIsImNvbXB1dGVfaW50X2NvbnYiLCJpZ25vcmVkJDgiLCJzcGFjZSQxIiwiaGFzaCQxIiwicGx1cyQyIiwia2luZCIsImlnbm9yZWQkNCIsImlnbm9yZWQiLCJpZ25vcmVkJDAiLCJpZ25vcmVkJDEiLCJwbHVzJDEiLCJpZ24kMCIsImlzX29wZW5fdGFnIiwiaW5kIiwic3ViX3N0ciIsInN1Yl9mb3JtYXQkMCIsImZvcm1hdHRpbmckMCIsImZvcm1hdHRpbmciLCJzdWJfZW5kJDEiLCJzdWJfZW5kJDIiLCJzdHJfaW5kJDYiLCJzdHJfaW5kJDciLCJvcHRpb24iLCJzdWJmbXQiLCJmb3JtYXRfb2Zfc3RyaW5nX2ZtdHR5IiwiZm9ybWF0X29mX3N0cmluZ19mb3JtYXQiLCJrZnByaW50ZiIsImticHJpbnRmIiwiaWtmcHJpbnRmIiwiZnByaW50ZiIsImJwcmludGYiLCJpZnByaW50ZiIsImlicHJpbnRmIiwicHJpbnRmIiwiZXByaW50ZiIsImtzcHJpbnRmIiwic3ByaW50ZiIsImFzc29jMyIsInkyIiwieTEiLCJtYWtlX3N5bWxpc3QiLCJoZWxwX2FjdGlvbiIsImFkZF9oZWxwIiwic3BlY2xpc3QiLCJhZGQxIiwiYWRkMiIsInVzYWdlX2IiLCJlcnJtc2ciLCJkb2MiLCJzcGVjIiwia2V5IiwidXNhZ2Vfc3RyaW5nIiwidXNhZ2UiLCJjdXJyZW50IiwicGFyc2VfYW5kX2V4cGFuZF9hcmd2X2R5bmFtaWNfIiwiYWxsb3dfZXhwYW5kIiwiYXJndiIsImFub25mdW4iLCJpbml0cG9zIiwiY29udmVydF9lcnJvciIsInByb2duYW1lIiwiZm9sbG93JDAiLCJrZXl3b3JkIiwiZm9sbG93JDIiLCJub19hcmciLCJnZXRfYXJnIiwiY29uc3VtZV9hcmciLCJ0cmVhdF9hY3Rpb24iLCJub19hcmckMCIsImYkMCIsImdldF9hcmckMCIsImNvbnN1bWVfYXJnJDAiLCJmJDEiLCJyJDEiLCJmJDIiLCJhcmckMSIsInIkMiIsImFyZyQyIiwiZiQzIiwiYXJnJDMiLCJyJDMiLCJhcmckNCIsInNwZWNzIiwidHJlYXRfYWN0aW9uJDAiLCJmJDQiLCJhcmckNSIsImYkNSIsImYkNiIsImYkNyIsImFyZyQ2IiwibmV3YXJnIiwicGFyc2VfYW5kX2V4cGFuZF9hcmd2X2R5bmFtaWMiLCJwYXJzZV9hcmd2X2R5bmFtaWMiLCJjdXJyZW50JDAiLCJwYXJzZV9hcmd2IiwibXNnJDAiLCJtc2ckMSIsInBhcnNlX2R5bmFtaWMiLCJwYXJzZV9leHBhbmQiLCJzZWNvbmRfd29yZCIsImxvb3AiLCJtYXhfYXJnX2xlbiIsImt3ZCIsInJlcGxhY2VfbGVhZGluZ190YWIiLCJhbGlnbiIsImxpbWl0IiwiY29tcGxldGVkIiwia3NkIiwiY3V0Y29sJDAiLCJzcGFjZXMkMCIsInNwZWMkMCIsImN1dGNvbCIsImt3ZF9sZW4iLCJzcGFjZXMiLCJyZWFkX2F1eCIsImZpbGUiLCJ3b3JkcyIsInN0YXNoIiwid29yZCIsIndvcmQkMCIsInJlYWRfYXJnIiwicmVhZF9hcmcwIiwid3JpdGVfYXV4IiwiYXJncyIsIndyaXRlX2FyZyIsIndyaXRlX2FyZzAiLCJsb2NmbXQiLCJwcmludGVycyIsImZpZWxkIiwib3RoZXJfZmllbGRzIiwidXNlX3ByaW50ZXJzIiwidG9fc3RyaW5nX2RlZmF1bHQiLCJjaGFyJDAiLCJsaW5lIiwiY2hhciQxIiwibGluZSQwIiwiZmlsZSQwIiwiY2hhciQyIiwibGluZSQxIiwiZmlsZSQxIiwiY29uc3RydWN0b3IiLCJwcmludCIsImZjdCIsImNhdGNoJDAiLCJyYXdfYmFja3RyYWNlX2VudHJpZXMiLCJidCIsImNvbnZlcnRfcmF3X2JhY2t0cmFjZSIsImZvcm1hdF9iYWNrdHJhY2Vfc2xvdCIsImlzX3JhaXNlIiwicHJpbnRfcmF3X2JhY2t0cmFjZSIsIm91dGNoYW4iLCJyYXdfYmFja3RyYWNlIiwiYmFja3RyYWNlIiwicHJpbnRfYmFja3RyYWNlIiwicmF3X2JhY2t0cmFjZV90b19zdHJpbmciLCJiYWNrdHJhY2Vfc2xvdF9pc19yYWlzZSIsInBhcmFtIiwiYmFja3RyYWNlX3Nsb3RfaXNfaW5saW5lIiwiYmFja3RyYWNlX3Nsb3RfbG9jYXRpb24iLCJiYWNrdHJhY2Vfc2xvdF9kZWZuYW1lIiwiYmFja3RyYWNlX3Nsb3RzIiwiYmFja3RyYWNlX3Nsb3RzX29mX3Jhd19lbnRyeSIsImVudHJ5IiwicmF3X2JhY2t0cmFjZV9sZW5ndGgiLCJnZXRfYmFja3RyYWNlIiwicmVnaXN0ZXJfcHJpbnRlciIsImZuIiwib2xkX3ByaW50ZXJzIiwibmV3X3ByaW50ZXJzIiwiZXhuX3Nsb3QiLCJleG5fc2xvdF9pZCIsImV4bl9zbG90X25hbWUiLCJlcnJvcnMiLCJkZWZhdWx0X3VuY2F1Z2h0X2V4Y2VwdGlvbl9oYW4iLCJzdGF0dXMiLCJ1bmNhdWdodF9leGNlcHRpb25faGFuZGxlciIsInNldF91bmNhdWdodF9leGNlcHRpb25faGFuZGxlciIsImVtcHR5X2JhY2t0cmFjZSIsImhhbmRsZV91bmNhdWdodF9leGNlcHRpb24iLCJkZWJ1Z2dlcl9pbl91c2UiLCJleG4kMSIsInJhd19iYWNrdHJhY2UkMCIsImNvbnN0JDAiLCJmbGlwIiwibmVnYXRlIiwicHJvdGVjdCIsImZpbmFsbHkkMCIsIndvcmsiLCJmaW5hbGx5X25vX2V4biIsIndvcmtfZXhuJDAiLCJ3b3JrX2V4biIsIndvcmtfYnQiLCJwcmludF9zdGF0IiwiYWxsb2NhdGVkX2J5dGVzIiwibWEiLCJwcm8iLCJtaSIsImNyZWF0ZV9hbGFybSIsImRlbGV0ZV9hbGFybSIsIm51bGxfdHJhY2tlciIsInNhbXBsaW5nX3JhdGUiLCJ0cmFja2VyIiwiY2FsbHN0YWNrX3NpemUiLCJzdHJpbmciLCJieXRlcyIsInN1YnN0cmluZyIsInN1YmJ5dGVzIiwiZmlsZW5hbWUiLCJkaWdlc3QiLCJjaGFyX2hleCIsInRvX2hleCIsImZyb21faGV4IiwiZGlnaXQiLCJuZXdfc3RhdGUiLCJhc3NpZ24iLCJzdDEiLCJzdDIiLCJmdWxsX2luaXQiLCJzZWVkIiwic2VlZCQwIiwibWFrZV9zZWxmX2luaXQiLCJiaXRzIiwiY3VydmFsIiwibmV3dmFsIiwibmV3dmFsMzAiLCJpbnRhdXgiLCJpbnQkMCIsImJvdW5kIiwiZnVsbF9pbnQiLCJiMSIsImIyIiwibWF4X2ludF8zMiIsImJwb3MiLCJiMyIsImludDMyIiwiaW50NjQiLCJuYXRpdmVpbnQiLCJmbG9hdCQwIiwiYm9vbCIsImJpdHMkMCIsImludCQxIiwiZnVsbF9pbnQkMCIsImludDMyJDAiLCJuYXRpdmVpbnQkMCIsImludDY0JDAiLCJmbG9hdCQxIiwic2NhbGUiLCJib29sJDAiLCJmdWxsX2luaXQkMCIsInNlbGZfaW5pdCIsImdldF9zdGF0ZSIsInNldF9zdGF0ZSIsIm9uZ29pbmdfdHJhdmVyc2FsIiwiZmxpcF9vbmdvaW5nX3RyYXZlcnNhbCIsInBhcmFtcyIsInJhbmRvbWl6ZWRfZGVmYXVsdCIsInJhbmRvbWl6ZWQiLCJyYW5kb21pemUiLCJpc19yYW5kb21pemVkIiwicHJuZyIsInBvd2VyXzJfYWJvdmUiLCJpbml0aWFsX3NpemUiLCJyYW5kb20iLCJjb3B5X2J1Y2tldGxpc3QiLCJrZXkkMCIsIm5leHQkMCIsImluc2VydF9hbGxfYnVja2V0cyIsImluZGV4ZnVuIiwiaW5wbGFjZSIsIm9kYXRhIiwibmRhdGEiLCJuc2l6ZSIsIm5kYXRhX3RhaWwiLCJuaWR4IiwibWF0Y2gkMCIsIm9zaXplIiwib2xkX3RyYXYiLCJmaWx0ZXJfbWFwX2lucGxhY2UiLCJiJDAiLCJidWNrZXRfbGVuZ3RoIiwic3RhdHMiLCJtYmwiLCJoaXN0byIsInRibF9kYXRhIiwiYnVjayIsImJ1Y2skMCIsImJ1Y2skMSIsInRvX3NlcV9rZXlzIiwidG9fc2VxX3ZhbHVlcyIsImtleV9pbmRleCIsImJ1Y2tldCIsImsxIiwibmV4dDEiLCJrMiIsIm5leHQyIiwiazMiLCJkMyIsIm5leHQzIiwiZmluZF9pbl9idWNrZXQiLCJyZXBsYWNlIiwicmVwbGFjZV9zZXEiLCJzeiIsImhhc2hfcGFyYW0iLCJzZWVkZWRfaGFzaCIsInJlYnVpbGQiLCJnZXRfY29weSIsImFyIiwiZW1wdHlidWNrZXQiLCJnZXRfaW5kZXgiLCJjcmVhdGUkMCIsInN6JDAiLCJzeiQxIiwiY291bnRfYnVja2V0IiwiYWRkX2F1eCIsInNldHRlciIsImJ1Y2tldCQwIiwiaGFzaGVzIiwibmV3c3oiLCJuZXdidWNrZXQkMCIsIm5ld2hhc2hlcyIsImhidWNrZXQiLCJwcmV2X2xlbiIsImxpdmUiLCJqJDIiLCJuZXdidWNrZXQiLCJvbGRsZW4iLCJuZXd0Iiwib2IiLCJvaSIsIm9oIiwib2kkMCIsIm5pIiwiZmluZF9vciIsImlmbm90Zm91bmQiLCJmaW5kX3NoYWRvdyIsImlmZm91bmQiLCJsZW5zIiwidG90bGVuIiwidW5rbm93biIsInBwX2VucXVldWUiLCJ0b2tlbiIsInBwX2luZmluaXR5IiwicHBfb3V0cHV0X3N0cmluZyIsInBwX291dHB1dF9uZXdsaW5lIiwiZm9ybWF0X3BwX3RleHQiLCJ0ZXh0IiwiZm9ybWF0X3N0cmluZyIsImJyZWFrX25ld19saW5lIiwicmVhbF9pbmRlbnQiLCJicmVha19zYW1lX2xpbmUiLCJmb3JtYXRfcHBfdG9rZW4iLCJzaXplJDAiLCJ0YWJzIiwiYWRkX3RhYiIsImxzIiwidGFnX25hbWUiLCJtYXJrZXIiLCJicmVha3MiLCJmaXRzIiwib2ZmIiwiYm94X3R5cGUkMCIsIm9mZiQwIiwiaW5zZXJ0aW9uX3BvaW50IiwidGFicyQwIiwiZmlyc3QiLCJoZWFkIiwidGFiIiwib2ZmJDEiLCJpbnNlcnRpb25fcG9pbnQkMCIsIndpZHRoJDIiLCJib3hfdHlwZSQxIiwidGJveCIsInRhZ19uYW1lJDAiLCJtYXJrZXIkMCIsImFkdmFuY2VfbGVmdCIsInBlbmRpbmdfY291bnQiLCJlbnF1ZXVlX2FkdmFuY2UiLCJlbnF1ZXVlX3N0cmluZ19hcyIsImluaXRpYWxpemVfc2Nhbl9zdGFjayIsInN0YWNrIiwicXVldWVfZWxlbSIsInNldF9zaXplIiwibGVmdF90b3RhbCIsInNjYW5fcHVzaCIsImVsZW0iLCJwcF9vcGVuX2JveF9nZW4iLCJicl90eSIsInBwX2Nsb3NlX2JveCIsInBwX29wZW5fc3RhZyIsInBwX2Nsb3NlX3N0YWciLCJwcF9vcGVuX3RhZyIsInBwX2Nsb3NlX3RhZyIsInBwX3NldF9wcmludF90YWdzIiwicHBfc2V0X21hcmtfdGFncyIsInBwX2dldF9wcmludF90YWdzIiwicHBfZ2V0X21hcmtfdGFncyIsInBwX3NldF90YWdzIiwicHBfZ2V0X2Zvcm1hdHRlcl9zdGFnX2Z1bmN0aW9uIiwicHBfc2V0X2Zvcm1hdHRlcl9zdGFnX2Z1bmN0aW9uIiwicGN0IiwicG90IiwibWN0IiwibW90IiwicHBfcmluaXQiLCJwcF9mbHVzaF9xdWV1ZSIsInBwX3ByaW50X2FzX3NpemUiLCJwcF9wcmludF9hcyIsImlzaXplIiwicHBfcHJpbnRfc3RyaW5nIiwicHBfcHJpbnRfYnl0ZXMiLCJwcF9wcmludF9pbnQiLCJwcF9wcmludF9mbG9hdCIsInBwX3ByaW50X2Jvb2wiLCJwcF9wcmludF9jaGFyIiwicHBfb3Blbl9oYm94IiwicHBfb3Blbl92Ym94IiwicHBfb3Blbl9odmJveCIsInBwX29wZW5faG92Ym94IiwicHBfb3Blbl9ib3giLCJwcF9wcmludF9uZXdsaW5lIiwicHBfcHJpbnRfZmx1c2giLCJwcF9mb3JjZV9uZXdsaW5lIiwicHBfcHJpbnRfaWZfbmV3bGluZSIsInBwX3ByaW50X2N1c3RvbV9icmVhayIsInBwX3ByaW50X2JyZWFrIiwicHBfcHJpbnRfc3BhY2UiLCJwcF9wcmludF9jdXQiLCJwcF9vcGVuX3Rib3giLCJwcF9jbG9zZV90Ym94IiwicHBfcHJpbnRfdGJyZWFrIiwicHBfcHJpbnRfdGFiIiwicHBfc2V0X3RhYiIsInBwX3NldF9tYXhfYm94ZXMiLCJwcF9nZXRfbWF4X2JveGVzIiwicHBfb3Zlcl9tYXhfYm94ZXMiLCJwcF9zZXRfZWxsaXBzaXNfdGV4dCIsInBwX2dldF9lbGxpcHNpc190ZXh0IiwicHBfbGltaXQiLCJwcF9zZXRfbWF4X2luZGVudCIsInBwX2dldF9tYXhfaW5kZW50IiwicHBfc2V0X21hcmdpbiIsIm5ld19tYXhfaW5kZW50IiwidmFsaWRhdGVfZ2VvbWV0cnkiLCJtYXJnaW4iLCJtYXhfaW5kZW50IiwiY2hlY2tfZ2VvbWV0cnkiLCJnZW9tZXRyeSIsInBwX2dldF9tYXJnaW4iLCJwcF9zZXRfZnVsbF9nZW9tZXRyeSIsInBwX3NldF9nZW9tZXRyeSIsInBwX3NhZmVfc2V0X2dlb21ldHJ5IiwicHBfZ2V0X2dlb21ldHJ5IiwicHBfdXBkYXRlX2dlb21ldHJ5IiwicHBfc2V0X2Zvcm1hdHRlcl9vdXRfZnVuY3Rpb25zIiwicHBfZ2V0X2Zvcm1hdHRlcl9vdXRfZnVuY3Rpb25zIiwicHBfc2V0X2Zvcm1hdHRlcl9vdXRwdXRfZnVuY3RpIiwicHBfZ2V0X2Zvcm1hdHRlcl9vdXRwdXRfZnVuY3RpIiwiZGlzcGxheV9uZXdsaW5lIiwiYmxhbmtfbGluZSIsImRpc3BsYXlfYmxhbmtzIiwicHBfc2V0X2Zvcm1hdHRlcl9vdXRfY2hhbm5lbCIsImRlZmF1bHRfcHBfbWFya19vcGVuX3RhZyIsImRlZmF1bHRfcHBfbWFya19jbG9zZV90YWciLCJkZWZhdWx0X3BwX3ByaW50X29wZW5fdGFnIiwiZGVmYXVsdF9wcF9wcmludF9jbG9zZV90YWciLCJwcF9tYWtlX2Zvcm1hdHRlciIsInBwX3F1ZXVlIiwic3lzX3RvayIsInNjYW5fc3RhY2siLCJwcF9tYXJnaW4iLCJmb3JtYXR0ZXJfb2Zfb3V0X2Z1bmN0aW9ucyIsIm91dF9mdW5zIiwibWFrZV9mb3JtYXR0ZXIiLCJwcGYiLCJmb3JtYXR0ZXJfb2Zfb3V0X2NoYW5uZWwiLCJmb3JtYXR0ZXJfb2ZfYnVmZmVyIiwicHBfYnVmZmVyX3NpemUiLCJwcF9tYWtlX2J1ZmZlciIsInN0ZGJ1ZiIsInN0ZF9mb3JtYXR0ZXIiLCJlcnJfZm9ybWF0dGVyIiwic3RyX2Zvcm1hdHRlciIsImZsdXNoX2J1ZmZlcl9mb3JtYXR0ZXIiLCJmbHVzaF9zdHJfZm9ybWF0dGVyIiwibWFrZV9zeW1ib2xpY19vdXRwdXRfYnVmZmVyIiwiY2xlYXJfc3ltYm9saWNfb3V0cHV0X2J1ZmZlciIsInNvYiIsImdldF9zeW1ib2xpY19vdXRwdXRfYnVmZmVyIiwiZmx1c2hfc3ltYm9saWNfb3V0cHV0X2J1ZmZlciIsIml0ZW1zIiwiYWRkX3N5bWJvbGljX291dHB1dF9pdGVtIiwiaXRlbSIsImZvcm1hdHRlcl9vZl9zeW1ib2xpY19vdXRwdXRfYiIsIm9wZW5faGJveCIsIm9wZW5fdmJveCIsIm9wZW5faHZib3giLCJvcGVuX2hvdmJveCIsIm9wZW5fYm94IiwiY2xvc2VfYm94Iiwib3Blbl90YWciLCJjbG9zZV90YWciLCJvcGVuX3N0YWciLCJjbG9zZV9zdGFnIiwicHJpbnRfYXMiLCJwcmludF9ib29sIiwicHJpbnRfYnJlYWsiLCJwcmludF9jdXQiLCJwcmludF9zcGFjZSIsImZvcmNlX25ld2xpbmUiLCJwcmludF9mbHVzaCIsInByaW50X2lmX25ld2xpbmUiLCJvcGVuX3Rib3giLCJjbG9zZV90Ym94IiwicHJpbnRfdGJyZWFrIiwic2V0X3RhYiIsInByaW50X3RhYiIsInNldF9tYXJnaW4iLCJnZXRfbWFyZ2luIiwic2V0X21heF9pbmRlbnQiLCJnZXRfbWF4X2luZGVudCIsInNldF9nZW9tZXRyeSIsInNhZmVfc2V0X2dlb21ldHJ5IiwiZ2V0X2dlb21ldHJ5IiwidXBkYXRlX2dlb21ldHJ5Iiwic2V0X21heF9ib3hlcyIsImdldF9tYXhfYm94ZXMiLCJvdmVyX21heF9ib3hlcyIsInNldF9lbGxpcHNpc190ZXh0IiwiZ2V0X2VsbGlwc2lzX3RleHQiLCJzZXRfZm9ybWF0dGVyX291dF9jaGFubmVsIiwic2V0X2Zvcm1hdHRlcl9vdXRfZnVuY3Rpb25zIiwiZ2V0X2Zvcm1hdHRlcl9vdXRfZnVuY3Rpb25zIiwic2V0X2Zvcm1hdHRlcl9vdXRwdXRfZnVuY3Rpb25zIiwiZ2V0X2Zvcm1hdHRlcl9vdXRwdXRfZnVuY3Rpb25zIiwic2V0X2Zvcm1hdHRlcl9zdGFnX2Z1bmN0aW9ucyIsImdldF9mb3JtYXR0ZXJfc3RhZ19mdW5jdGlvbnMiLCJzZXRfcHJpbnRfdGFncyIsImdldF9wcmludF90YWdzIiwic2V0X21hcmtfdGFncyIsImdldF9tYXJrX3RhZ3MiLCJzZXRfdGFncyIsInBwX3ByaW50X2xpc3QiLCJwcF92Iiwib3B0JDAiLCJwcF9zZXAiLCJvcHQkMSIsInBwX3ByaW50X3NlcSIsInNlcSQxIiwic2VxJDIiLCJwcF9wcmludF90ZXh0IiwicHBfcHJpbnRfb3B0aW9uIiwicHBfcHJpbnRfcmVzdWx0IiwicHBfcHJpbnRfZWl0aGVyIiwiY29tcHV0ZV90YWciLCJ0YWdfYWNjIiwib3V0cHV0X2Zvcm1hdHRpbmdfbGl0IiwiYnR5IiwicCQ2IiwicCQ3Iiwic2l6ZSQxIiwicCQ4Iiwia2RwcmludGYiLCJkcHJpbnRmIiwia2FzcHJpbnRmIiwiYXNwcmludGYiLCJmbHVzaF9zdGFuZGFyZF9mb3JtYXR0ZXJzIiwicHBfc2V0X2FsbF9mb3JtYXR0ZXJfb3V0cHV0X2Z1IiwicHBfZ2V0X2FsbF9mb3JtYXR0ZXJfb3V0cHV0X2Z1Iiwic2V0X2FsbF9mb3JtYXR0ZXJfb3V0cHV0X2Z1bmN0IiwiZ2V0X2FsbF9mb3JtYXR0ZXJfb3V0cHV0X2Z1bmN0IiwicHBfc2V0X2Zvcm1hdHRlcl90YWdfZnVuY3Rpb25zIiwic3RyaW5naWZ5IiwicHBfZ2V0X2Zvcm1hdHRlcl90YWdfZnVuY3Rpb25zIiwiZnVucyIsIm1hcmtfb3Blbl90YWciLCJtYXJrX2Nsb3NlX3RhZyIsInByaW50X29wZW5fdGFnIiwicHJpbnRfY2xvc2VfdGFnIiwic2V0X2Zvcm1hdHRlcl90YWdfZnVuY3Rpb25zIiwiZ2V0X2Zvcm1hdHRlcl90YWdfZnVuY3Rpb25zIiwibnVsbF9jaGFyIiwibmV4dF9jaGFyIiwiaWIiLCJwZWVrX2NoYXIiLCJjaGVja2VkX3BlZWtfY2hhciIsImVuZF9vZl9pbnB1dCIsImJlZ2lubmluZ19vZl9pbnB1dCIsIm5hbWVfb2ZfaW5wdXQiLCJjaGFyX2NvdW50IiwiaW52YWxpZGF0ZV9jdXJyZW50X2NoYXIiLCJ0b2tlbl9zdHJpbmciLCJ0b2tlbl9idWZmZXIiLCJpZ25vcmVfY2hhciIsInN0b3JlX2NoYXIiLCJkZWZhdWx0X3Rva2VuX2J1ZmZlcl9zaXplIiwiaW5hbWUiLCJzY2FuX2Nsb3NlX2F0X2VuZCIsInNjYW5fcmFpc2VfYXRfZW5kIiwiZnJvbV9pYyIsInNjYW5fY2xvc2VfaWMiLCJlb2YiLCJvcGVuX2luX2ZpbGUiLCJpYyQwIiwibWVtbyIsIm1lbW9fZnJvbV9jaGFubmVsIiwiYmFkX2lucHV0IiwiYmFkX2lucHV0X2VzY2FwZSIsImJhZF90b2tlbl9sZW5ndGgiLCJtZXNzYWdlIiwiYmFkX2hleF9mbG9hdCIsImNoYXJhY3Rlcl9taXNtYXRjaCIsImNpIiwiY2hlY2tfY2hhciIsImNoZWNrX3RoaXNfY2hhciIsInRva2VuX2NoYXIiLCJ0b2tlbl9ib29sIiwiaW50ZWdlcl9jb252ZXJzaW9uX29mX2NoYXIiLCJ0b2tlbl9pbnRfbGl0ZXJhbCIsImNvbnYiLCJ0b2tlbl9mbG9hdCIsInNjYW5fZGVjaW1hbF9kaWdpdF9zdGFyIiwic2Nhbl9kZWNpbWFsX2RpZ2l0X3BsdXMiLCJzY2FuX2RpZ2l0X3BsdXMiLCJiYXNpcyIsImRpZ2l0cCIsIndpZHRoJDMiLCJpc19iaW5hcnlfZGlnaXQiLCJpc19vY3RhbF9kaWdpdCIsImlzX2hleGFfZGlnaXQiLCJzY2FuX3NpZ24iLCJzY2FuX29wdGlvbmFsbHlfc2lnbmVkX2RlY2ltYWwiLCJzY2FuX2ludF9jb252ZXJzaW9uIiwic2Nhbl9mcmFjdGlvbmFsX3BhcnQiLCJzY2FuX2V4cG9uZW50X3BhcnQiLCJzY2FuX2Zsb2F0IiwicHJlY2lzaW9uIiwicHJlY2lzaW9uJDAiLCJjaGVja19jYXNlX2luc2Vuc2l0aXZlX3N0cmluZyIsInNjYW5faGV4X2Zsb2F0Iiwid2lkdGgkNCIsIndpZHRoJDUiLCJ3aWR0aCQ2Iiwid2lkdGgkMTAiLCJ3aWR0aCQ3Iiwid2lkdGgkOCIsIndpZHRoJDkiLCJzY2FuX2NhbWxfZmxvYXRfcmVzdCIsIndpZHRoX3ByZWNpc2lvbiIsImZyYWNfd2lkdGgiLCJzY2FuX2NhbWxfZmxvYXQiLCJzY2FuX3N0cmluZyIsInN0cCIsImhleGFkZWNpbWFsX3ZhbHVlX29mX2NoYXIiLCJjaGVja19uZXh0X2NoYXIiLCJzY2FuX2JhY2tzbGFzaF9jaGFyIiwiYzAiLCJnZXRfZGlnaXQkMCIsImMxJDAiLCJjMiQwIiwiZ2V0X2RpZ2l0Iiwic2Nhbl9jYW1sX3N0cmluZyIsImZpbmRfc3RvcCQwIiwic2tpcF9zcGFjZXMiLCJmaW5kX3N0b3AiLCJzY2FuX2NoYXJzX2luX2NoYXJfc2V0Iiwic2Nhbl9pbmRpYyIsInNjYW5fY2hhcnMiLCJzY2FuZl9iYWRfaW5wdXQiLCJ3aWR0aF9vZl9wYWRfb3B0Iiwic3RvcHBlcl9vZl9mb3JtYXR0aW5nX2xpdCIsImZtdGluZyIsInRha2VfZm9ybWF0X3JlYWRlcnMkMCIsInRha2VfZm10dHlfZm9ybWF0X3JlYWRlcnMkMCIsInJlYWRlciIsIm5ld19rIiwicmVhZGVyc19yZXN0IiwidGFrZV9mb3JtYXRfcmVhZGVycyIsInRha2VfZm10dHlfZm9ybWF0X3JlYWRlcnMiLCJtYWtlX3NjYW5mIiwicmVhZGVycyIsInNjYW4kMCIsInN0cl9yZXN0IiwicGFkX3ByZWNfc2NhbmYiLCJzY2FuJDEiLCJzY2FuJDIiLCJzY2FuIiwic2NhbiQzIiwic2NhbiQ0IiwiY29udiQwIiwic2NhbiQ1IiwiY29udiQxIiwic2NhbiQ2IiwiY29udiQyIiwic2NhbiQ3Iiwic2NhbiQ4IiwiZm10aW5nX2xpdCQwIiwic3RwJDAiLCJzJDIiLCJzdHJfcmVzdCQwIiwiYXJnX3Jlc3QiLCJrc2NhbmYiLCJlZiIsImV4YyQwIiwiZXhjIiwiYXJncyQxIiwiYXJncyQwIiwiYnNjYW5mIiwia3NzY2FuZiIsInNzY2FuZiIsInNjYW5mIiwiYnNjYW5mX2Zvcm1hdCIsImZvcm1hdCIsInNzY2FuZl9mb3JtYXQiLCJmb3JtYXRfZnJvbV9zdHJpbmciLCJ1bmVzY2FwZWQiLCJrZnNjYW5mIiwiZnNjYW5mIiwicmVnaXN0ZXIiLCJyZWdpc3Rlcl9leGNlcHRpb24iLCJvJDAiLCJwdWJsaWNfbWV0aG9kX2xhYmVsIiwidGFnIiwiY29tcGFyZSQwIiwiY29tcGFyZSQxIiwiZHVtbXlfdGFibGUiLCJ0YWJsZV9jb3VudCIsImR1bW15X21ldCIsImluaXRpYWxfb2JqZWN0X3NpemUiLCJmaXRfc2l6ZSIsIm5ld190YWJsZSIsInB1Yl9sYWJlbHMiLCJtZXRob2RzIiwiYXJyYXkiLCJuZXdfc2l6ZSIsIm9sZF9zaXplIiwibmV3X2J1Y2siLCJtZXRob2RfY291bnQiLCJpbnN0X3Zhcl9jb3VudCIsIm5ld19tZXRob2QiLCJ0YWJsZSIsImdldF9tZXRob2RfbGFiZWwiLCJsYWJlbCIsImdldF9tZXRob2RfbGFiZWxzIiwibmFtZXMiLCJzZXRfbWV0aG9kIiwiZWxlbWVudCIsImdldF9tZXRob2QiLCJhcnIiLCJuYXJyb3ciLCJ2YXJzIiwidmlydF9tZXRocyIsImNvbmNyX21ldGhzIiwidmFycyQwIiwidmlydF9tZXRocyQwIiwiY29uY3JfbWV0aHMkMCIsInZpcnRfbWV0aF9sYWJzIiwiY29uY3JfbWV0aF9sYWJzIiwibGFiIiwidHZhcnMiLCJieV9uYW1lIiwiYnlfbGFiZWwiLCJtZXQiLCJobSIsIndpZGVuIiwic2F2ZWRfdmFycyIsInNhdmVkX2hpZGRlbl9tZXRocyIsIm5ld192YXJpYWJsZSIsInRvX2FycmF5IiwibmV3X21ldGhvZHNfdmFyaWFibGVzIiwibWV0aHMiLCJ2YWxzIiwibWV0aHMkMCIsIm5tZXRocyIsIm52YWxzIiwiZ2V0X3ZhcmlhYmxlIiwiZ2V0X3ZhcmlhYmxlcyIsImFkZF9pbml0aWFsaXplciIsImNyZWF0ZV90YWJsZSIsInB1YmxpY19tZXRob2RzIiwidGFncyIsImluaXRfY2xhc3MiLCJpbmhlcml0cyIsImNsYSIsInN1cGVyJDAiLCJubSIsIm1ha2VfY2xhc3MiLCJwdWJfbWV0aHMiLCJjbGFzc19pbml0IiwiZW52X2luaXQiLCJtYWtlX2NsYXNzX3N0b3JlIiwiaW5pdF90YWJsZSIsImR1bW15X2NsYXNzIiwibG9jIiwidW5kZWYiLCJjcmVhdGVfb2JqZWN0IiwiY3JlYXRlX29iamVjdF9vcHQiLCJvYmpfMCIsIml0ZXJfZiIsInJ1bl9pbml0aWFsaXplcnMiLCJpbml0cyIsInJ1bl9pbml0aWFsaXplcnNfb3B0IiwiY3JlYXRlX29iamVjdF9hbmRfcnVuX2luaXRpYWxpIiwiYnVpbGRfcGF0aCIsImtleXMiLCJsb29rdXBfdGFibGVzIiwicm9vdCIsInJvb3RfZGF0YSIsInRhYmxlcyQwIiwidGFibGVzJDEiLCJ0YWJsZXNfZGF0YSIsIm5ld19jYWNoZSIsInNldF9tZXRob2RzIiwiY2xvIiwieCQyMCIsImNsbyQwIiwibiQzOCIsImUkMTAiLCJuJDM3IiwibiQzNiIsIm4kMiIsIm4kMzUiLCJmJDIwIiwibiQzIiwiZiQxOSIsIm4kMzQiLCJuJDQiLCJmJDE4IiwiZSQ5IiwibiQzMyIsIm4kNSIsImYkMTciLCJuJDMyIiwiZiQxNiIsInkkMCIsIm4kNiIsImYkMTUiLCJuJDMxIiwibiQ3IiwiZiQxNCIsImUkOCIsIm4kMzAiLCJuJDgiLCJmJDEzIiwibiQyOSIsIm4kOSIsImYkMTIiLCJuJDI4IiwiZiQ4IiwiZSQyIiwibiQxMCIsImYkMTEiLCJlJDciLCJuJDI3IiwiZiQ5IiwibiQxMSIsImYkMTAiLCJuJDI2IiwibiQxMiIsIm4kMjUiLCJuJDEzIiwibiQyNCIsIm0kMTIiLCJuJDE0IiwiZSQzIiwibiQyMyIsImUkNiIsIm0kMTEiLCJuJDE1IiwibSQxIiwibiQyMiIsIm0kMTAiLCJtJDIiLCJtJDkiLCJtJDMiLCJuJDE2IiwibSQ4IiwibiQyMSIsIm0kNCIsImUkNCIsIm4kMTciLCJtJDciLCJlJDUiLCJuJDIwIiwibSQ1IiwibiQxOCIsIm0kNiIsIm4kMTkiLCJpbml0X21vZF9ibG9jayIsImNvbXBzJDAiLCJtb2R1Iiwic2hhcGUiLCJmbiQwIiwiY29tcHMiLCJpbml0X21vZCIsInVwZGF0ZV9tb2RfYmxvY2siLCJjbCIsInVwZGF0ZV9tb2QiLCJpbml0aWFsX2J1ZmZlciIsImJ1ZmZlciIsImJ1ZnBvcyIsInJlc2V0X2J1ZmZlciIsInN0b3JlIiwibmV3YnVmZmVyIiwiZ2V0X3N0cmluZyIsIm1ha2VfbGV4ZXIiLCJrZXl3b3JkcyIsImt3ZF90YWJsZSIsImlkZW50X29yX2tleXdvcmQiLCJrZXl3b3JkX29yX2Vycm9yIiwibmV4dF90b2tlbiIsImVzY2FwZSIsImNvbW1lbnQiLCJudW1iZXIiLCJpZGVudDIiLCJleHBvbmVudF9wYXJ0IiwiZW5kX2V4cG9uZW50X3BhcnQiLCJjMyIsImhrZXkiLCJjbGVhbiIsImRvX2J1Y2tldCIsImluc2VydF9idWNrZXQiLCJjb250YWluZXIiLCJyZW1vdmVfYnVja2V0IiwiaGsiLCJuZXdfZCIsImJ1Y2tldF9sZW5ndGhfYWxpdmUiLCJzdGF0c19hbGl2ZSIsImdldF9kYXRhX2NvcHkiLCJzZXRfZGF0YSIsInVuc2V0X2RhdGEiLCJjaGVja19kYXRhIiwiYmxpdF9kYXRhIiwic2V0X2tleV9kYXRhIiwiZ2V0X2tleTEiLCJnZXRfa2V5MV9jb3B5Iiwic2V0X2tleTEiLCJ1bnNldF9rZXkxIiwiY2hlY2tfa2V5MSIsImdldF9rZXkyIiwiZ2V0X2tleTJfY29weSIsInNldF9rZXkyIiwidW5zZXRfa2V5MiIsImNoZWNrX2tleTIiLCJibGl0X2tleTEiLCJibGl0X2tleTIiLCJibGl0X2tleTEyIiwiZ2V0X2RhdGEkMCIsImdldF9kYXRhX2NvcHkkMCIsInNldF9kYXRhJDAiLCJ1bnNldF9kYXRhJDAiLCJjaGVja19kYXRhJDAiLCJibGl0X2RhdGEkMCIsImsyJDAiLCJrMSQwIiwiZXF1YWwkMCIsImNyZWF0ZSQxIiwiZ2V0X2tleSQwIiwiZ2V0X2tleV9jb3B5JDAiLCJzZXRfa2V5JDAiLCJ1bnNldF9rZXkkMCIsImNoZWNrX2tleSQwIiwiYmxpdF9rZXkkMCIsImdldF9kYXRhJDEiLCJnZXRfZGF0YV9jb3B5JDEiLCJzZXRfZGF0YSQxIiwidW5zZXRfZGF0YSQxIiwiY2hlY2tfZGF0YSQxIiwiYmxpdF9kYXRhJDEiLCJraSIsImswIiwibnVsbCQwIiwiY3VycmVudF9kaXJfbmFtZSIsInBhcmVudF9kaXJfbmFtZSIsImRpcl9zZXAiLCJxdW90ZXF1b3RlIiwibnVsbCQxIiwiY3VycmVudF9kaXJfbmFtZSQwIiwicGFyZW50X2Rpcl9uYW1lJDAiLCJkaXJfc2VwJDAiLCJudWxsJDIiLCJjdXJyZW50X2Rpcl9uYW1lJDEiLCJwYXJlbnRfZGlyX25hbWUkMSIsImRpcl9zZXAkMSIsImdlbmVyaWNfYmFzZW5hbWUiLCJpc19kaXJfc2VwIiwiZ2VuZXJpY19kaXJuYW1lIiwiaXNfcmVsYXRpdmUiLCJpc19pbXBsaWNpdCIsImNoZWNrX3N1ZmZpeCIsInN1ZmYiLCJjaG9wX3N1ZmZpeF9vcHQiLCJsZW5fZiIsInRlbXBfZGlyX25hbWUiLCJxdW90ZSIsInF1b3RlX2NvbW1hbmQiLCJiYXNlbmFtZSIsImRpcm5hbWUiLCJpc19kaXJfc2VwJDAiLCJpc19yZWxhdGl2ZSQwIiwiaXNfaW1wbGljaXQkMCIsImNoZWNrX3N1ZmZpeCQwIiwiY2hvcF9zdWZmaXhfb3B0JDAiLCJ0ZW1wX2Rpcl9uYW1lJDAiLCJxdW90ZSQwIiwibG9vcCQwIiwibG9vcF9icyIsImFkZF9icyIsInF1b3RlX2NtZF9maWxlbmFtZSIsInF1b3RlX2NvbW1hbmQkMCIsImRyaXZlX2FuZF9wYXRoIiwiZGlybmFtZSQwIiwicGF0aCIsImRyaXZlIiwiZGlyIiwiYmFzZW5hbWUkMCIsImJhc2VuYW1lJDEiLCJkaXJuYW1lJDEiLCJudWxsJDMiLCJjdXJyZW50X2Rpcl9uYW1lJDIiLCJwYXJlbnRfZGlyX25hbWUkMiIsImRpcl9zZXAkMiIsImlzX2Rpcl9zZXAkMSIsImlzX3JlbGF0aXZlJDEiLCJpc19pbXBsaWNpdCQxIiwiY2hlY2tfc3VmZml4JDEiLCJjaG9wX3N1ZmZpeF9vcHQkMSIsInRlbXBfZGlyX25hbWUkMSIsInF1b3RlJDEiLCJxdW90ZV9jb21tYW5kJDEiLCJiYXNlbmFtZSQyIiwiZGlybmFtZSQyIiwiY2hvcF9zdWZmaXgiLCJleHRlbnNpb25fbGVuIiwiaTAiLCJleHRlbnNpb24iLCJjaG9wX2V4dGVuc2lvbiIsInJlbW92ZV9leHRlbnNpb24iLCJ0ZW1wX2ZpbGVfbmFtZSIsInRlbXBfZGlyIiwicm5kIiwiY3VycmVudF90ZW1wX2Rpcl9uYW1lIiwic2V0X3RlbXBfZGlyX25hbWUiLCJnZXRfdGVtcF9kaXJfbmFtZSIsInRlbXBfZmlsZSIsIm9wZW5fdGVtcF9maWxlIiwic3RoJDAiLCJwZXJtcyIsInN0aCQxIiwibmVnIiwiY29uaiIsIm11bCIsImRpdiIsImludiIsIm5vcm0yIiwibm9ybSIsInEkMCIsInBvbGFyIiwic3FydCIsInckMCIsImV4cCIsImxvZyIsInBvdyIsImtpbmRfc2l6ZV9pbl9ieXRlcyIsImNsb29wIiwiaWR4IiwiY29sIiwiZmxvb3AiLCJsYXlvdXQiLCJkaW1zIiwic2l6ZV9pbl9ieXRlcyIsInNpemVfaW5fYnl0ZXMkMCIsIm9mX3ZhbHVlIiwiZGltIiwic2l6ZV9pbl9ieXRlcyQxIiwic2xpY2UiLCJpbml0JDAiLCJvZl9hcnJheSIsImJhIiwiZGltMSIsImRpbTIiLCJzaXplX2luX2J5dGVzJDIiLCJzbGljZV9sZWZ0Iiwic2xpY2VfcmlnaHQiLCJpbml0JDEiLCJvZl9hcnJheSQwIiwicm93IiwiY3JlYXRlJDIiLCJkaW0zIiwic2l6ZV9pbl9ieXRlcyQzIiwic2xpY2VfbGVmdF8xIiwic2xpY2VfcmlnaHRfMSIsInNsaWNlX2xlZnRfMiIsInNsaWNlX3JpZ2h0XzIiLCJpbml0JDIiLCJvZl9hcnJheSQxIiwiYXJyYXkwX29mX2dlbmFycmF5IiwiYXJyYXkxX29mX2dlbmFycmF5IiwiYXJyYXkyX29mX2dlbmFycmF5IiwiYXJyYXkzX29mX2dlbmFycmF5IiwicmVzaGFwZV8wIiwicmVzaGFwZV8xIiwicmVzaGFwZV8yIiwicmVzaGFwZV8zIiwidmVyc2lvbiIsImdpdF92ZXJzaW9uIiwicmFpc2UiLCJtYXgiLCJ4IiwieSIsIm1pbiIsImVxdWFsIiwiZXF1YWwkMCIsIm1heCQwIiwibWluJDAiLCJnbG9iYWwiLCJudWxsJDAiLCJ1bmRlZmluZWQkMCIsInJldHVybiQwIiwibWFwIiwiZiIsImJpbmQiLCJ0ZXN0IiwiaXRlciIsImNhc2UkMCIsImciLCJnZXQiLCJvcHRpb24iLCJ4JDAiLCJ0b19vcHRpb24iLCJyZXR1cm4kMSIsIm1hcCQwIiwiYmluZCQwIiwidGVzdCQwIiwiaXRlciQwIiwiY2FzZSQxIiwiZ2V0JDAiLCJvcHRpb24kMCIsInRvX29wdGlvbiQwIiwiY29lcmNlIiwiY29lcmNlX29wdCIsInRydWUkMCIsImZhbHNlJDAiLCJuZmMiLCJuZmQiLCJuZmtjIiwibmZrZCIsInN0cmluZ19jb25zdHIiLCJyZWdFeHAiLCJvYmplY3Rfa2V5cyIsImFycmF5X2NvbnN0cnVjdG9yIiwiYXJyYXlfZ2V0IiwiYXJyYXlfc2V0IiwiYXJyYXlfbWFwIiwiaWR4IiwiYXJyYXlfbWFwaSIsInN0cl9hcnJheSIsIm1hdGNoX3Jlc3VsdCIsImRhdGVfY29uc3RyIiwibWF0aCIsImVycm9yX2NvbnN0ciIsImV4bl93aXRoX2pzX2JhY2t0cmFjZSIsIm5hbWUiLCJtZXNzYWdlIiwic3RhY2siLCJ0b19zdHJpbmciLCJyYWlzZV9qc19lcnJvciIsImUiLCJzdHJpbmdfb2ZfZXJyb3IiLCJKU09OIiwiZGVjb2RlVVJJIiwicyIsImRlY29kZVVSSUNvbXBvbmVudCIsImVuY29kZVVSSSIsImVuY29kZVVSSUNvbXBvbmVudCIsImVzY2FwZSIsInVuZXNjYXBlIiwiaXNOYU4iLCJpIiwicGFyc2VJbnQiLCJzJDAiLCJwYXJzZUZsb2F0IiwiZXhwb3J0X2pzIiwiZmllbGQiLCJleHBvcnQkMCIsImV4cG9ydF9hbGwiLCJrZXkiLCJsaXN0X29mX25vZGVMaXN0IiwibGVuZ3RoIiwiYWNjIiwidDEiLCJhY2MkMCIsImkkMCIsImhhcyIsInQiLCJtYXNrIiwiYWRkIiwiYXBwZW5kQ2hpbGQiLCJyZW1vdmVDaGlsZCIsInJlcGxhY2VDaGlsZCIsImluc2VydEJlZm9yZSIsIm5vZGVUeXBlIiwidDEzIiwiY2FzdCIsInQxNCIsImVsZW1lbnQiLCJ0ZXh0IiwiYXR0ciIsIm5vX2hhbmRsZXIiLCJoYW5kbGVyIiwicmVzIiwiZnVsbF9oYW5kbGVyIiwidGhpcyQwIiwiaW52b2tlX2hhbmRsZXIiLCJldmVudCIsImV2ZW50VGFyZ2V0IiwibWFrZSIsImFkZEV2ZW50TGlzdGVuZXJXaXRoT3B0aW9ucyIsImNhcHR1cmUiLCJvbmNlIiwicGFzc2l2ZSIsInQ0NCIsImFkZEV2ZW50TGlzdGVuZXIiLCJ0eXAiLCJoIiwiY2FwdCIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJpZCIsInByZXZlbnREZWZhdWx0IiwiY3JlYXRlQ3VzdG9tRXZlbnQiLCJidWJibGVzIiwiY2FuY2VsYWJsZSIsImRldGFpbCIsIngkMSIsImFycmF5QnVmZmVyIiwiaW50OEFycmF5IiwiaW50MTZBcnJheSIsInVpbnQxNkFycmF5IiwiaW50MzJBcnJheSIsInVpbnQzMkFycmF5IiwiZmxvYXQzMkFycmF5IiwiZmxvYXQ2NEFycmF5Iiwic2V0IiwiYSIsInYiLCJ1bnNhZmVfZ2V0IiwiZGF0YVZpZXciLCJvZl9hcnJheUJ1ZmZlciIsInVpbnQ4Iiwib2ZfYXJyYXlCdWZmZXIkMCIsImZpbHRlcl9tYXAiLCJxIiwidiQwIiwiYmxvYl9yYXciLCJjb250ZW50VHlwZSIsImVuZGluZ3MiLCJvcHRpb25zIiwiYmxvYl9mcm9tX3N0cmluZyIsImJsb2JfZnJvbV9hbnkiLCJsIiwibCQwIiwiYSQwIiwiYiIsImZpbGVuYW1lIiwibmFtZSQwIiwiZG9jX2NvbnN0ciIsImRvY3VtZW50IiwiYmxvYiIsInN0cmluZyIsImxvYWRzdGFydCIsInByb2dyZXNzIiwiYWJvcnQiLCJlcnJvciIsImxvYWQiLCJsb2FkZW5kIiwiZmlsZVJlYWRlciIsIm5hbWUkNTYiLCJuYW1lJDU1IiwibmFtZSQ1NCIsIm5hbWUkNTMiLCJuYW1lJDUyIiwibmFtZSQ1MSIsIm5hbWUkNTAiLCJuYW1lJDQ5IiwibmFtZSQ0OCIsIm5hbWUkNDciLCJuYW1lJDQ2IiwibmFtZSQ0NSIsIm5hbWUkNDQiLCJuYW1lJDQzIiwibmFtZSQ0MiIsIm5hbWUkNDEiLCJuYW1lJDQwIiwibmFtZSQzOSIsIm5hbWUkMzgiLCJuYW1lJDM3IiwibmFtZSQzNiIsIm5hbWUkMzUiLCJuYW1lJDM0IiwibmFtZSQzMyIsIm5hbWUkMzIiLCJuYW1lJDMxIiwibmFtZSQzMCIsIm5hbWUkMjkiLCJuYW1lJDI4IiwibmFtZSQyNyIsIm5hbWUkMjYiLCJuYW1lJDI1IiwibmFtZSQyNCIsIm5hbWUkMjMiLCJuYW1lJDIyIiwibmFtZSQyMSIsIm5hbWUkMjAiLCJuYW1lJDE5IiwibmFtZSQxOCIsIm5hbWUkMTciLCJuYW1lJDE2IiwibmFtZSQxNSIsIm5hbWUkMTQiLCJuYW1lJDEzIiwibmFtZSQxMiIsIm5hbWUkMTEiLCJuYW1lJDEwIiwibmFtZSQ5IiwibmFtZSQ4IiwibmFtZSQ3IiwibmFtZSQ2IiwibmFtZSQ1IiwibmFtZSQ0IiwibmFtZSQzIiwibmFtZSQyIiwibmFtZSQxIiwib25JRSIsImNhbmNlbCIsImNsaWNrIiwiY2xvc2UiLCJjb3B5IiwiY3V0IiwicGFzdGUiLCJkYmxjbGljayIsIm1vdXNlZG93biIsIm1vdXNldXAiLCJtb3VzZW92ZXIiLCJtb3VzZW1vdmUiLCJtb3VzZW91dCIsImtleXByZXNzIiwia2V5ZG93biIsImtleXVwIiwibW91c2V3aGVlbCIsIndoZWVsIiwiRE9NTW91c2VTY3JvbGwiLCJ0b3VjaHN0YXJ0IiwidG91Y2htb3ZlIiwidG91Y2hlbmQiLCJ0b3VjaGNhbmNlbCIsImRyYWdzdGFydCIsImRyYWdlbmQiLCJkcmFnZW50ZXIiLCJkcmFnb3ZlciIsImRyYWdsZWF2ZSIsImRyYWciLCJkcm9wIiwiaGFzaGNoYW5nZSIsImNoYW5nZSIsImlucHV0IiwidGltZXVwZGF0ZSIsInN1Ym1pdCIsInNjcm9sbCIsImZvY3VzIiwiYmx1ciIsInVubG9hZCIsImJlZm9yZXVubG9hZCIsInJlc2l6ZSIsIm9yaWVudGF0aW9uY2hhbmdlIiwicG9wc3RhdGUiLCJzZWxlY3QiLCJvbmxpbmUiLCJvZmZsaW5lIiwiY2hlY2tpbmciLCJub3VwZGF0ZSIsImRvd25sb2FkaW5nIiwidXBkYXRlcmVhZHkiLCJjYWNoZWQiLCJvYnNvbGV0ZSIsImRvbUNvbnRlbnRMb2FkZWQiLCJhbmltYXRpb25zdGFydCIsImFuaW1hdGlvbmVuZCIsImFuaW1hdGlvbml0ZXJhdGlvbiIsImFuaW1hdGlvbmNhbmNlbCIsInRyYW5zaXRpb25ydW4iLCJ0cmFuc2l0aW9uc3RhcnQiLCJ0cmFuc2l0aW9uZW5kIiwidHJhbnNpdGlvbmNhbmNlbCIsImNhbnBsYXkiLCJjYW5wbGF5dGhyb3VnaCIsImR1cmF0aW9uY2hhbmdlIiwiZW1wdGllZCIsImVuZGVkIiwiZ290cG9pbnRlcmNhcHR1cmUiLCJsb2FkZWRkYXRhIiwibG9hZGVkbWV0YWRhdGEiLCJsb3N0cG9pbnRlcmNhcHR1cmUiLCJwYXVzZSIsInBsYXkiLCJwbGF5aW5nIiwicG9pbnRlcmVudGVyIiwicG9pbnRlcmNhbmNlbCIsInBvaW50ZXJkb3duIiwicG9pbnRlcmxlYXZlIiwicG9pbnRlcm1vdmUiLCJwb2ludGVyb3V0IiwicG9pbnRlcm92ZXIiLCJwb2ludGVydXAiLCJyYXRlY2hhbmdlIiwic2Vla2VkIiwic2Vla2luZyIsInN0YWxsZWQiLCJzdXNwZW5kIiwidm9sdW1lY2hhbmdlIiwid2FpdGluZyIsImQiLCJsb2NhdGlvbl9vcmlnaW4iLCJvIiwid2luZG93IiwiZ2V0RWxlbWVudEJ5SWQiLCJwbm9kZSIsImdldEVsZW1lbnRCeUlkX2V4biIsImdldEVsZW1lbnRCeUlkX29wdCIsImdldEVsZW1lbnRCeUlkX2NvZXJjZSIsImNyZWF0ZUVsZW1lbnQiLCJjcmVhdGVFbGVtZW50U3ludGF4IiwidW5zYWZlQ3JlYXRlRWxlbWVudEV4IiwidHlwZSIsImRvYyIsImVsdCIsImNyZWF0ZUh0bWwiLCJjcmVhdGVIZWFkIiwiY3JlYXRlTGluayIsImNyZWF0ZVRpdGxlIiwiY3JlYXRlTWV0YSIsImNyZWF0ZUJhc2UiLCJjcmVhdGVTdHlsZSIsImNyZWF0ZUJvZHkiLCJjcmVhdGVGb3JtIiwiY3JlYXRlT3B0Z3JvdXAiLCJjcmVhdGVPcHRpb24iLCJjcmVhdGVTZWxlY3QiLCJjcmVhdGVJbnB1dCIsImNyZWF0ZVRleHRhcmVhIiwiY3JlYXRlQnV0dG9uIiwiY3JlYXRlTGFiZWwiLCJjcmVhdGVGaWVsZHNldCIsImNyZWF0ZUxlZ2VuZCIsImNyZWF0ZVVsIiwiY3JlYXRlT2wiLCJjcmVhdGVEbCIsImNyZWF0ZUxpIiwiY3JlYXRlRGlhbG9nIiwiY3JlYXRlRGl2IiwiY3JlYXRlRW1iZWQiLCJjcmVhdGVQIiwiY3JlYXRlSDEiLCJjcmVhdGVIMiIsImNyZWF0ZUgzIiwiY3JlYXRlSDQiLCJjcmVhdGVINSIsImNyZWF0ZUg2IiwiY3JlYXRlUSIsImNyZWF0ZUJsb2NrcXVvdGUiLCJjcmVhdGVQcmUiLCJjcmVhdGVCciIsImNyZWF0ZUhyIiwiY3JlYXRlSW5zIiwiY3JlYXRlRGVsIiwiY3JlYXRlQSIsImNyZWF0ZUltZyIsImNyZWF0ZU9iamVjdCIsImNyZWF0ZVBhcmFtIiwiY3JlYXRlTWFwIiwiY3JlYXRlQXJlYSIsImNyZWF0ZVNjcmlwdCIsImNyZWF0ZVRhYmxlIiwiY3JlYXRlQ2FwdGlvbiIsImNyZWF0ZUNvbCIsImNyZWF0ZUNvbGdyb3VwIiwiY3JlYXRlVGhlYWQiLCJjcmVhdGVUZm9vdCIsImNyZWF0ZVRib2R5IiwiY3JlYXRlVHIiLCJjcmVhdGVUaCIsImNyZWF0ZVRkIiwiY3JlYXRlU3ViIiwiY3JlYXRlU3VwIiwiY3JlYXRlU3BhbiIsImNyZWF0ZVR0IiwiY3JlYXRlSSIsImNyZWF0ZUIiLCJjcmVhdGVCaWciLCJjcmVhdGVTbWFsbCIsImNyZWF0ZUVtIiwiY3JlYXRlU3Ryb25nIiwiY3JlYXRlQ2l0ZSIsImNyZWF0ZURmbiIsImNyZWF0ZUNvZGUiLCJjcmVhdGVTYW1wIiwiY3JlYXRlS2JkIiwiY3JlYXRlVmFyIiwiY3JlYXRlQWJiciIsImNyZWF0ZURkIiwiY3JlYXRlRHQiLCJjcmVhdGVOb3NjcmlwdCIsImNyZWF0ZUFkZHJlc3MiLCJjcmVhdGVGcmFtZXNldCIsImNyZWF0ZUZyYW1lIiwiY3JlYXRlSWZyYW1lIiwiY3JlYXRlQXVkaW8iLCJjcmVhdGVWaWRlbyIsImNyZWF0ZUNhbnZhcyIsImh0bWxfZWxlbWVudCIsInQ1NCIsInVuc2FmZUNvZXJjZSIsInRhZyIsInQ1NSIsImFyZWEiLCJiYXNlIiwiYmxvY2txdW90ZSIsImJvZHkiLCJiciIsImJ1dHRvbiIsImNhbnZhcyIsImNhcHRpb24iLCJjb2wiLCJjb2xncm91cCIsImRlbCIsImRpdiIsImRsIiwiZmllbGRzZXQiLCJlbWJlZCIsImZvcm0iLCJmcmFtZXNldCIsImZyYW1lIiwiaDEiLCJoMiIsImgzIiwiaDQiLCJoNSIsImg2IiwiaGVhZCIsImhyIiwiaHRtbCIsImlmcmFtZSIsImltZyIsImlucHV0JDAiLCJpbnMiLCJsYWJlbCIsImxlZ2VuZCIsImxpIiwibGluayIsIm1ldGEiLCJvYmplY3QiLCJvbCIsIm9wdGdyb3VwIiwicCIsInByZSIsInNjcmlwdCIsInNlbGVjdCQwIiwic3R5bGUiLCJ0YWJsZSIsInRib2R5IiwidGQiLCJ0ZXh0YXJlYSIsInRmb290IiwidGgiLCJ0aGVhZCIsInRpdGxlIiwidHIiLCJ1bCIsImF1ZGlvIiwidmlkZW8iLCJ1bnNhZmVDb2VyY2VFdmVudCIsImNvbnN0ciIsImV2IiwibW91c2VFdmVudCIsImtleWJvYXJkRXZlbnQiLCJ3aGVlbEV2ZW50IiwibW91c2VTY3JvbGxFdmVudCIsInBvcFN0YXRlRXZlbnQiLCJtZXNzYWdlRXZlbnQiLCJldmVudFJlbGF0ZWRUYXJnZXQiLCJldmVudEFic29sdXRlUG9zaXRpb24iLCJldmVudEFic29sdXRlUG9zaXRpb24kMCIsImVsZW1lbnRDbGllbnRQb3NpdGlvbiIsImdldERvY3VtZW50U2Nyb2xsIiwiYnV0dG9uUHJlc3NlZCIsImFkZE1vdXNld2hlZWxFdmVudExpc3RlbmVyV2l0aCIsImR4IiwiZHkiLCJhZGRNb3VzZXdoZWVsRXZlbnRMaXN0ZW5lciIsInRyeV9jb2RlIiwidHJ5X2tleV9jb2RlX25vcm1hbCIsIm1ha2VfdW5pZGVudGlmaWVkIiwib2ZfZXZlbnQiLCJ2YWx1ZSIsInZhbHVlJDMiLCJ2YWx1ZSQyIiwidmFsdWUkMSIsInZhbHVlJDAiLCJjaGFyX29mX2ludCIsImVtcHR5X3N0cmluZyIsIm5vbmUiLCJvZl9ldmVudCQwIiwiZWxlbWVudCQwIiwidGFnZ2VkIiwidDEwNSIsIm9wdF90YWdnZWQiLCJ0YWdnZWRFdmVudCIsIm9wdF90YWdnZWRFdmVudCIsInN0b3BQcm9wYWdhdGlvbiIsInJlcXVlc3RBbmltYXRpb25GcmFtZSIsInJlcSIsImMiLCJjYWxsYmFjayIsIm5vdyIsImxhc3QiLCJkdCIsImhhc1B1c2hTdGF0ZSIsImhhc1BsYWNlaG9sZGVyIiwiaGFzUmVxdWlyZWQiLCJvdmVyZmxvd19saW1pdCIsInNldFRpbWVvdXQiLCJsb29wIiwicmVtYWluIiwic3RlcCIsImNiIiwiY2xlYXJUaW1lb3V0IiwianNfYXJyYXlfb2ZfY29sbGVjdGlvbiIsImZvcm1EYXRhIiwiZm9ybURhdGFfZm9ybSIsImhhdmVfY29udGVudCIsImdldF9lbGVtZW50X2NvbnRlbnQiLCJzdGgiLCJmaWxlIiwiZm9ybV9lbGVtZW50cyIsImkkMSIsInQzMSIsImFwcGVuZCIsImZvcm1fY29udGVudHMiLCJmb3JtX2VsdCIsImxpc3QiLCJlbXB0eV9mb3JtX2NvbnRlbnRzIiwicG9zdF9mb3JtX2NvbnRlbnRzIiwiY29udGVudHMiLCJnZXRfZm9ybV9jb250ZW50cyIsInJlYWR5c3RhdGVjaGFuZ2UiLCJ0aW1lb3V0IiwiY3JlYXRlIiwiaW1wb3J0X3NjcmlwdHMiLCJzY3JpcHRzIiwic2V0X29ubWVzc2FnZSIsImpzX2hhbmRsZXIiLCJwb3N0X21lc3NhZ2UiLCJ3ZWJTb2NrZXQiLCJpc19zdXBwb3J0ZWQiLCJkZWZhdWx0Q29udGV4dEF0dHJpYnV0ZXMiLCJ3ZWJnbGNvbnRleHRsb3N0Iiwid2ViZ2xjb250ZXh0cmVzdG9yZWQiLCJ3ZWJnbGNvbnRleHRjcmVhdGlvbmVycm9yIiwiZ2V0Q29udGV4dCIsImN0eCIsImdldENvbnRleHRXaXRoQXR0cmlidXRlcyIsInJlZ2V4cCIsInJlZ2V4cF9jYXNlX2ZvbGQiLCJyZWdleHBfd2l0aF9mbGFnIiwiYmx1bnRfc3RyX2FycmF5X2dldCIsInN0cmluZ19tYXRjaCIsInNlYXJjaCIsInJlc19wcmUiLCJtYXRjaGVkX3N0cmluZyIsInIiLCJtYXRjaGVkX2dyb3VwIiwicXVvdGVfcmVwbCIsImdsb2JhbF9yZXBsYWNlIiwic19ieSIsInJlcGxhY2VfZmlyc3QiLCJ0MjkiLCJsaXN0X29mX2pzX2FycmF5IiwiaWR4JDEiLCJhY2N1IiwiaWR4JDAiLCJhY2N1JDAiLCJzcGxpdCIsImJvdW5kZWRfc3BsaXQiLCJxdW90ZSIsInJlZ2V4cF9zdHJpbmciLCJyZWdleHBfc3RyaW5nX2Nhc2VfZm9sZCIsImludGVycnVwdCIsInBsdXNfcmUiLCJ1cmxkZWNvZGVfanNfc3RyaW5nX3N0cmluZyIsInQxNiIsInVybGRlY29kZSIsInVybGVuY29kZSIsIm9wdCIsIndpdGhfcGx1cyIsInBhdGhfb2ZfcGF0aF9zdHJpbmciLCJhdXgiLCJqIiwid29yZCIsImVuY29kZV9hcmd1bWVudHMiLCJuIiwiZGVjb2RlX2FyZ3VtZW50c19qc19zdHJpbmciLCJsZW4iLCJ0MyIsImRlY29kZV9hcmd1bWVudHMiLCJ1cmxfb2ZfanNfc3RyaW5nIiwiaGFuZGxlIiwicGF0aF9zdHIiLCJzc2wiLCJ1cmwiLCJ1cmxfb2Zfc3RyaW5nIiwic3RyaW5nX29mX3VybCIsImZyYWciLCJhcmdzIiwicGF0aCIsInBvcnQiLCJob3N0IiwiZnJhZyQwIiwiYXJncyQwIiwicGF0aCQwIiwicG9ydCQwIiwiaG9zdCQwIiwiZnJhZyQxIiwiYXJncyQxIiwicGF0aCQxIiwiZGVmYXVsdF9odHRwX3BvcnQiLCJkZWZhdWx0X2h0dHBzX3BvcnQiLCJwcm90b2NvbCIsInBhdGhfc3RyaW5nIiwiYXJndW1lbnRzJDAiLCJnZXRfZnJhZ21lbnQiLCJzZXRfZnJhZ21lbnQiLCJ1IiwiYXNfc3RyaW5nIiwidXBkYXRlX2ZpbGUiLCJjb250ZW50Iiwib2MiLCJzZXRfY2hhbm5lbF9mbHVzaGVyIiwib3V0X2NoYW5uZWwiLCJmJDAiLCJzZXRfY2hhbm5lbF9maWxsZXIiLCJpbl9jaGFubmVsIiwibW91bnQiLCJwcmVmaXgiLCJ1bm1vdW50IiwianNfb2Zfb2NhbWxfdmVyc2lvbiIsImVtcHR5X3Jlc2l6ZV9vYnNlcnZlcl9vcHRpb25zIiwib2JzZXJ2ZSIsImJveCIsImVudHJ5X3R5cGVzIiwiZW1wdHlfbXV0YXRpb25fb2JzZXJ2ZXJfaW5pdCIsImNoaWxkX2xpc3QiLCJhdHRyaWJ1dGVzIiwiY2hhcmFjdGVyX2RhdGEiLCJzdWJ0cmVlIiwiYXR0cmlidXRlX29sZF92YWx1ZSIsImNoYXJhY3Rlcl9kYXRhX29sZF92YWx1ZSIsImF0dHJpYnV0ZV9maWx0ZXIiLCJyZW1vdmUiLCJmaW5kIiwia2V5cyIsInJldml2ZXIiLCJ1bnNhZmVfaW5wdXQiLCJtbEludDY0X2NvbnN0ciIsIm91dHB1dF9yZXZpdmVyIiwib3V0cHV0Iiwic3RyaW5nX29mX25hbWUiLCJuYW1lX29mX3N0cmluZyIsInJnYl9vZl9uYW1lIiwicmdiIiwiaHNsIiwic3RyaW5nX29mX3QiLCJiJDAiLCJnJDAiLCJyJDAiLCJiJDEiLCJnJDEiLCJyJDEiLCJiJDIiLCJnJDIiLCJyJDIiLCJhJDEiLCJoJDAiLCJoZXhfb2ZfcmdiIiwiYmx1ZSIsImdyZWVuIiwicmVkIiwiaW5fcmFuZ2UiLCJqc190X29mX2pzX3N0cmluZyIsInQxMiIsImpzIiwiY24iLCJtbCIsImZhaWwiLCJyZV9yZ2IiLCJyZV9yZ2JfcGN0IiwicmVfaHNsIiwiaV9vZl9zX28iLCJmX29mX3MiLCJhbHBoYSIsInJlZCQwIiwiZ3JlZW4kMCIsImJsdWUkMCIsImFscGhhJDAiLCJyZWQkMSIsImdyZWVuJDEiLCJibHVlJDEiLCJhbHBoYSQxIiwic3RyaW5nX29mX3QkMCIsImYkMSIsImYkMiIsImYkMyIsImYkNCIsImYkNSIsImYkNiIsImYkNyIsImYkOCIsImYkOSIsImYkMTAiLCJmJDExIiwiZiQxMiIsImpzJDAiLCJtbCQwIiwicmUiLCJzdHJpbmdfb2ZfdCQxIiwianMkMSIsIm1sJDEiLCJsaXN0ZW4iLCJ0YXJnZXQiLCJzdG9wX2xpc3RlbiIsImNyZWF0ZUFsdEdseXBoIiwiY3JlYXRlQWx0R2x5cGhEZWYiLCJjcmVhdGVBbHRHbHlwaEl0ZW0iLCJjcmVhdGVBbmltYXRlIiwiY3JlYXRlQW5pbWF0ZUNvbG9yIiwiY3JlYXRlQW5pbWF0ZU1vdGlvbiIsImNyZWF0ZUFuaW1hdGVUcmFuc2Zvcm0iLCJjcmVhdGVDaXJjbGUiLCJjcmVhdGVDbGlwUGF0aCIsImNyZWF0ZUN1cnNvciIsImNyZWF0ZURlZnMiLCJjcmVhdGVEZXNjIiwiY3JlYXRlRWxsaXBzZSIsImNyZWF0ZUZpbHRlciIsImNyZWF0ZUZvbnQiLCJjcmVhdGVGb250RmFjZSIsImNyZWF0ZUZvbnRGYWNlRm9ybWF0IiwiY3JlYXRlRm9udEZhY2VOYW1lIiwiY3JlYXRlRm9udEZhY2VTcmMiLCJjcmVhdGVGb250RmFjZVVyaSIsImNyZWF0ZUZvcmVpZ25PYmplY3QiLCJjcmVhdGVHIiwiY3JlYXRlR2x5cGgiLCJjcmVhdGVHbHlwaFJlZiIsImNyZWF0ZWhrZXJuIiwiY3JlYXRlSW1hZ2UiLCJjcmVhdGVMaW5lRWxlbWVudCIsImNyZWF0ZUxpbmVhckVsZW1lbnQiLCJjcmVhdGVNYXNrIiwiY3JlYXRlTWV0YURhdGEiLCJjcmVhdGVNaXNzaW5nR2x5cGgiLCJjcmVhdGVNUGF0aCIsImNyZWF0ZVBhdGgiLCJjcmVhdGVQYXR0ZXJuIiwiY3JlYXRlUG9seWdvbiIsImNyZWF0ZVBvbHlsaW5lIiwiY3JlYXRlUmFkaWFsZ3JhZGllbnQiLCJjcmVhdGVSZWN0IiwiY3JlYXRlU2V0IiwiY3JlYXRlU3RvcCIsImNyZWF0ZVN2ZyIsImNyZWF0ZVN3aXRjaCIsImNyZWF0ZVN5bWJvbCIsImNyZWF0ZVRleHRFbGVtZW50IiwiY3JlYXRlVGV4dHBhdGgiLCJjcmVhdGVUcmVmIiwiY3JlYXRlVHNwYW4iLCJjcmVhdGVVc2UiLCJjcmVhdGVWaWV3IiwiY3JlYXRldmtlcm4iLCJzdmdfZWxlbWVudCIsInQ4IiwiYWx0R2x5cGgiLCJhbHRHbHlwaERlZiIsImFsdEdseXBoSXRlbSIsImFuaW1hdGUiLCJhbmltYXRlQ29sb3IiLCJhbmltYXRlTW90aW9uIiwiYW5pbWF0ZVRyYW5zZm9ybSIsImNpcmNsZSIsImNsaXBQYXRoIiwiY3Vyc29yIiwiZGVmcyIsImRlc2MiLCJlbGxpcHNlIiwiZmlsdGVyIiwiZm9udCIsImZvbnRGYWNlIiwiZm9udEZhY2VGb3JtYXQiLCJmb250RmFjZU5hbWUiLCJmb250RmFjZVNyYyIsImZvbnRGYWNlVXJpIiwiZm9yZWlnbk9iamVjdCIsImdseXBoIiwiZ2x5cGhSZWYiLCJoa2VybiIsImltYWdlIiwibGluZUVsZW1lbnQiLCJsaW5lYXJFbGVtZW50IiwibWV0YURhdGEiLCJtaXNzaW5nR2x5cGgiLCJtUGF0aCIsInBhdHRlcm4iLCJwb2x5Z29uIiwicG9seWxpbmUiLCJyYWRpYWxncmFkaWVudCIsInJlY3QiLCJzdG9wIiwic3ZnIiwic3dpdGNoJDAiLCJzeW1ib2wiLCJ0ZXh0RWxlbWVudCIsInRleHRwYXRoIiwidHJlZiIsInRzcGFuIiwidXNlIiwidmlldyIsInZrZXJuIiwid2l0aENyZWRlbnRpYWxzIiwiZXZlbnRTb3VyY2UiLCJldmVudFNvdXJjZV9vcHRpb25zIiwiY29uc29sZSIsImVtcHR5X3Bvc2l0aW9uX29wdGlvbnMiLCJnZW9sb2NhdGlvbiIsImVtcHR5X2ludGVyc2VjdGlvbl9vYnNlcnZlcl9vcCIsImludGVyc2VjdGlvbk9ic2VydmVyX3Vuc2FmZSIsIm9iamVjdF9vcHRpb25zIiwib3B0aW9ucyQwIiwib3B0aW9ucyQxIiwib3B0aW9ucyQyIiwiaW50bCIsImNvbGxhdG9yX2NvbnN0ciIsImRhdGVUaW1lRm9ybWF0X2NvbnN0ciIsIm51bWJlckZvcm1hdF9jb25zdHIiLCJwbHVyYWxSdWxlc19jb25zdHIiLCJkZWNpZGUiLCJkZWNpc2lvbiIsImRlY2lkZV9yZWwiLCJyZWxEZWNpc2lvbiIsInRvcCIsInRvcDAiLCJib3R0b20iLCJib3R0b20wIiwiY29xX1RvcCIsImNvcV9OZWciLCJhIiwiY29xX0FuZCIsImIiLCJjb3FfT3IiLCJjb3FfRGlhbSIsImVxX2RlY19mb3JtIiwibSIsIngwIiwibSQwIiwieDAkMCIsInMiLCJzMCIsImYiLCJzMSIsIngxIiwiczIiLCJzMyIsImEwIiwiaCQwIiwiaSIsImI2IiwiYjUiLCJiNCIsImIzIiwiYjIiLCJiMSIsImIwIiwiZiQwIiwiYjciLCJiOCIsImI5IiwiYjEwIiwiYjExIiwiYjEyIiwiYjEzIiwiYjE0IiwiaCIsIm0xIiwibTAiLCJtMyIsIm0yIiwibTAkMCIsIm0xJDAiLCJ1bkJveF9mb3JtdWxhIiwieCIsInVuYm94ZWRfbGlzdCIsInQiLCJ0b3BfYm94ZXMiLCJmc3QiLCJzbmQiLCJ5IiwibGVuZ3RoIiwibCIsImFwcCIsImwxIiwibGVfbHRfZGVjIiwibiIsIm4kMCIsIm4wIiwibjEiLCJsdF9kZWMiLCJhZGQiLCJwIiwic3RyaW5nX2RlYyIsInMkMCIsIngkMCIsImZvcm1fdG9wIiwiZm9ybV9lcV9kZWMiLCJ2IiwidjAiLCJmMSIsImYwIiwiZjMiLCJmMiIsImYxJDAiLCJmMCQwIiwiZjMkMCIsImYyJDAiLCJmMSQxIiwiZjAkMSIsImYzJDEiLCJmMiQxIiwiZjAkMiIsImYxJDIiLCJ3ZWlnaHQiLCJVVTAzYzgiLCJVVTAzYzZfMCIsIlVVMDNjOCQwIiwiVVUwM2M2XzAkMCIsIlVVMDNjOCQxIiwiVVUwM2M2XzAkMSIsIlVVMDNjNl8wJDIiLCJpbl9kZWMiLCJsMCIsInJlbW92ZSIsImVxX2RlYyIsInRsIiwibGlzdF9lcV9kZWMiLCJsJDAiLCJsJDIiLCJsJDEiLCJtYXAiLCJub2R1cCIsImRlY0EiLCJ4cyIsImZvbGRsIiwiYSQwIiwiZWxlbV9vZl9saXN0X2RlYyIsImRlYyIsImNvbXBhcmlzb25fZXFfZGVjIiwic3ltYm9sIiwiZGVjaWRhYmxlX2lzX2ltcGxpY2F0aW9uIiwiVVUwM2M2IiwiZGVjaWRhYmxlX2lzX25lZ2F0aW9uIiwib2J2aW91c2x5X3NtYWxsZXIiLCJVVTAzYzhfMCIsImMiLCJjMCIsImMkMCIsImMwJDAiLCJVVTAzYzhfMCQwIiwiYyQxIiwiYzAkMSIsImYkMSIsImMkMiIsImMwJDIiLCJmJDIiLCJjaG9vc2VfY29uaiIsIm1ha2VfY29uaiIsIlVVMDNjOF8yIiwiVVUwM2M4XzEiLCJVVTAzYzhfMiQwIiwiVVUwM2M4XzEkMCIsIlVVMDNjOF8yJDEiLCJVVTAzYzhfMSQxIiwiVVUwM2M2XzIiLCJVVTAzYzZfMSIsImNob29zZV9kaXNqIiwibWFrZV9kaXNqIiwibWFrZV9pbXBsIiwiVVUwM2M2JDAiLCJVVTAzYzYkMSIsImNvbmp1bmN0aW9uIiwiZGlzanVuY3Rpb24iLCJpbl9tYXBfYXV4IiwiVVUwMzkzIiwiVVUwMzkzXzAiLCJpbl9tYXAiLCJybSIsIm9wZW5fYm94IiwiY29xX1hCb3hlZF9saXN0IiwiY29xX0luVF9lcSIsImNvcV9JblRfYXBwX29yIiwibDIiLCJpMCIsImkwJDAiLCJjb3FfSW5UX29yX2FwcCIsImkkMSIsImkkMCIsImFwcDAiLCJsMyIsImluX3NwbGl0VCIsImgwIiwiZXFfZGVjX2xpc3RzRiIsImVxX2RlY19zZXFzIiwic2Vxc19pbl9zcGxpdFQiLCJjb3FfSW5fSW5UX3NlcXMiLCJzZXEiLCJjb3FfSW5fZGVjIiwicmVtb3ZlX2xpc3QiLCJ0MSIsImgxIiwiZGVjX3Byb3BfdmFyX2luIiwiczAkMCIsImRlY19pc19ib3giLCJkZWNfYm94X2luIiwiZGVjX2luaXRfcnVsZXMiLCJ4MiIsIngzIiwiczEkMCIsInMyJDAiLCJzMiQxIiwiczMkMCIsIngkMSIsInM0IiwieDAkMSIsIngxJDAiLCJoMCQwIiwiczUiLCJ4MiQwIiwieDMkMCIsInByb2oxX3NpZ1QyIiwicHJvajJfc2lnVDIiLCJjb3FfSW5fSW5UX3BhaXIiLCJjb3FfSW5UX21hcF9pZmYiLCJpSGwiLCJ5MCIsInAwIiwicG9zX3RvcF9pbXBzIiwidG9wX2JveGVzX25vYm94X2dlbl9leHQiLCJmbGF0dGVuX2xpc3QiLCJjb3FfSW5UX2ZsYXR0ZW5fbGlzdF9JblRfZWxlbSIsImkyIiwiaTEiLCJjb3FfSW5UX3RyYW5zX2ZsYXR0ZW5fbGlzdCIsImJzIiwibGlzdF9vZl9zcGxpdHMiLCJsaXN0SW5zZXJ0cyIsImxpc3RJbnNlcnRzUl9TZXFzIiwiVVUwMzk0IiwibGlzdEluc2VydHNMX1NlcXMiLCJyZW1vdmVfbnRoIiwidGwkMCIsImIkMCIsIm50aF9zcGxpdCIsInByZW1zX0ltcF9SIiwiY29xX0luX3Bvc190b3BfaW1wc19zcGxpdF9sIiwibjAkMCIsImNvcV9JbXBSX2hlbHAwMSIsInByZW0iLCJzMCQxIiwiczEkMSIsIngxJDIiLCJzMyQxIiwieDIkMiIsInM0JDEiLCJ4MyQyIiwiczUkMSIsIng0JDIiLCJzNiQxIiwieDUkMSIsIng2JDEiLCJwcmVtc19JbXBfUjAiLCJsNCIsImw0JDAiLCJsNCQxIiwieDQkMCIsImw1IiwieDEkMSIsIngyJDEiLCJ4MyQxIiwiczQkMCIsIng0JDEiLCJzNSQwIiwieDUkMCIsInM2JDAiLCJ4NiQwIiwieDciLCJ4NCIsInM2IiwieDUiLCJ4NiIsImNvcV9JbXBSX2hlbHAxIiwiY29xX0ltcFJfaGVscDAwMiIsIlVVMDM5M18xIiwiVVUwMzk0XzAiLCJVVTAzOTRfMSIsImNvcV9JbXBSX2hlbHAwMiIsImgxJDAiLCJsMiQwIiwibDIkMSIsInRsJDQiLCJiMCQyIiwidGwkNSIsInRsJDYiLCJiMCQwIiwidGwkMSIsImIwJDEiLCJ0bCQyIiwidGwkMyIsIm4kMSIsImNvcV9JbXBSX2hlbHAyIiwiZmluaXRlX0ltcFJfcHJlbWlzZXNfb2ZfUyIsInByZW1zIiwicHJlbXNfSW1wX0wiLCJ6IiwiY29xX0ltcExfaGVscDAwMiIsInAxIiwicCQwIiwiY29xX0ltcExfaGVscDAyIiwicHJlbXNfSW1wX0wwIiwibDEkMCIsImwxJDEiLCJjb3FfSW1wTF9oZWxwMiIsImNvcV9JbXBMX2hlbHAwMSIsIng1JDIiLCJzNyQxIiwieDYkMiIsInM4JDEiLCJ4NyQyIiwieDgkMiIsInM3JDAiLCJ4NyQxIiwiczgkMCIsIng4JDEiLCJ4OSIsImkzIiwiaTQiLCJiJDIiLCJiJDEiLCJpNSIsImk2IiwiaTciLCJwMiIsImk4IiwibDQkMyIsIng3JDAiLCJpOSIsIng4JDAiLCJsNCQyIiwiczciLCJzOCIsIng4IiwiY29xX0ltcExfaGVscDEiLCJmaW5pdGVfSW1wTF9wcmVtaXNlc19vZl9TIiwicHJlbXNfQm94X1IiLCJjb3FfR0xSX2hlbHAwMSIsImNvcV9HTFJfaGVscDEiLCJjb3FfR0xSX2hlbHAwMiIsImJfVVUwMzkzIiwiY29xX0dMUl9oZWxwMiIsImZpbml0ZV9HTFJfcHJlbWlzZXNfb2ZfUyIsInN1YmZvcm1fYm94ZXNGIiwic3ViZm9ybV9ib3hlc0xGIiwic3ViZm9ybV9ib3hlc1MiLCJ1c2FibGVfYm94ZXMiLCJkZWNfaXNfUHJvcFZhciIsImRlY19LU19pbml0X3J1bGVzIiwiY29xX0tSX2hlbHAwMSIsImNvcV9LUl9oZWxwMSIsImNvcV9LUl9oZWxwMDIiLCJjb3FfS1JfaGVscDIiLCJmaW5pdGVfS1JfcHJlbWlzZXNfb2ZfUyIsImVfcnVsZSIsIlVVMDNkNSIsImVBMCIsIlVVMDNiOCIsImUiLCJwZTAiLCJVVTAzOTQkMCIsInEiLCJVVTAzYjRfVVUyMDgyIiwiVVUwM2I0X1VVMjA4MSIsIlVVMDNiNF9VVTIwODIkMCIsIlVVMDNiNF9VVTIwODEkMCIsIlVVMDNiNF8yIiwicSQwIiwiVVUwM2I0X1VVMjA4MiQxIiwiVVUwM2I0X1VVMjA4MSQxIiwiVVUwM2I0X1VVMjA4MiQyIiwiVVUwM2I0X1VVMjA4MSQyIiwiVVUwM2I0X1VVMjA4MiQzIiwiVVUwM2I0X1VVMjA4MSQzIiwiVVUwM2I0XzEiLCJhX3J1bGVfZW52IiwiYV9ydWxlX2Zvcm0iLCJVVTAzZDVfVVUyMDgyIiwiVVUwM2Q1X1VVMjA4MSIsIlVVMDNkNV9VVTIwODIkMCIsIlVVMDNkNV9VVTIwODEkMCIsIlVVMDNkNV9VVTIwODIkMSIsIlVVMDNkNV9VVTIwODEkMSIsIlVVMDNiNCIsImNvcV9FQSIsInBlIiwiY29xX0UiLCJjb3FfQSIsImNvcV9FZiIsImNvcV9BZiIsInNpbXBfb3JzIiwic2ltcF9hbmRzIiwic2ltcF9pbXAiLCJzaW1wX2ltcHMiLCJzaW1wIiwiY29xX0Vfc2ltcGxpZmllZCIsImNvcV9BX3NpbXBsaWZpZWQiLCJsaXN0X2lzX25pbCIsImZsYXRtYXAiLCJpcnJlZCIsImZpbml0ZV9JbXBSdWxlc19wcmVtaXNlc19vZl9TIiwicHJlbXMwIiwiVVUwMzk0XzEkMCIsIlVVMDM5NF8wJDAiLCJVVTAzOTNfMSQwIiwiVVUwMzkzXzAkMCIsInByZW1zMCQwIiwiaW52X3ByZW1zIiwiY29xX0Nhbm9weSIsImlzX1ByaW1lX2RlYyIsImNyaXRpY2FsX1NlcV9kZWMiLCJjb3FfR0xSX3ByZW1zIiwiY29xX0xleFNlcV9pbmQiLCJlbXB0eV9zZXFfZGVjIiwibGlzdF9jb25qIiwibGlzdF9kaXNqIiwibGlzdF9wcm9wX0YiLCJsaXN0X3Byb3BfTEYiLCJyZXN0cl9saXN0X3Byb3AiLCJub2R1cHNlcSIsImltYXAiLCJjb3FfR1VJX3RvdCIsImlIIiwiY29xX0tSX3ByZW1zIiwiY29xX0x0U2VxX2luZCIsImoxMCIsImNvcV9NUHJvcEZfb2ZfZm9ybSIsImZvcm1fb2ZfTVByb3BGIiwiZ2xfVUkiLCJrX1VJIiwiaXNsX0UiLCJpc2xfQSIsImlzbF9zaW1wIiwiaXNsX3NpbXBsaWZpZWRfRSIsImlzbF9zaW1wbGlmaWVkX0EiLCJleGlzdHNfZGVjIiwiY29xX1Byb3ZhYmxlX2RlYyIsIlVVMDM5M18yIiwiaGluZCIsImhBbmRSIiwiZjIkNyIsImYxJDEwIiwidiQwIiwiaHZhciIsImZBIiwiaEFuZEwiLCJzJDEiLCJoSW1wUiIsImYyJDYiLCJmMSQ5IiwicyQyIiwiczAkMiIsIngwJDIiLCJmQSQwIiwicyQzIiwiczAkMyIsIngwJDMiLCJoT3JMIiwicyQ0IiwiczAkNCIsIngwJDQiLCJzMSQyIiwiZklwIiwiZnAiLCJzJDUiLCJzMCQ1IiwieDAkNSIsInMxJDMiLCJ4MSQzIiwiaEltcExWYXIiLCJzJDYiLCJzMCQ2IiwieDAkNiIsIngxJDQiLCJzMSQ0IiwiZklJIiwicyQ3IiwiczAkNyIsIngwJDciLCJmMiQyIiwiZjQiLCJoSW1wTEFuZCIsInMkOCIsInMwJDgiLCJ4MCQ4IiwiczEkNSIsIngxJDUiLCJzMiQyIiwiZklJJDAiLCJzJDkiLCJzMCQ5IiwieDAkOSIsImYyJDMiLCJmMSQzIiwiZjQkMCIsImhJbXBMT3IiLCJzJDEwIiwiczAkMTAiLCJ4MCQxMCIsInMxJDYiLCJ4MSQ2IiwiczIkMyIsImhPclIxIiwiZjIkNSIsImYxJDgiLCJzJDE0IiwiaE9yUjIiLCJmMiQ0IiwiZjEkNyIsInMkMTMiLCJoQm94UiIsImYxJDYiLCJzJDEyIiwiZjEkNCIsIlVVMDM5M18zIiwiZjUiLCJzJDExIiwiZjEkNSIsInMwJDExIiwiY3JlYXRlIiwic2l6ZSIsImVtcHR5IiwibGVuZ3RoIiwic3ViIiwiaW52YWxpZF9ib3VuZHMiLCJvcCIsImJ1ZmZlcl9sZW4iLCJvZmYiLCJsZW4iLCJtZXNzYWdlIiwiaW52YWxpZF9ib3VuZHNfYmxpdCIsInNyY19sZW4iLCJzcmNfb2ZmIiwiZHN0X2xlbiIsImRzdF9vZmYiLCJpbnZhbGlkX2JvdW5kc19tZW1jbXAiLCJidWYxX2xlbiIsImJ1ZjFfb2ZmIiwiYnVmMl9sZW4iLCJidWYyX29mZiIsImNvcHkiLCJ0IiwiZHN0Iiwic3Vic3RyaW5nIiwiYiIsInRvX3N0cmluZyIsIm9mX3N0cmluZyIsInMiLCJibGl0Iiwic3JjIiwiYmxpdF9mcm9tX3N0cmluZyIsImJsaXRfZnJvbV9ieXRlcyIsImJsaXRfdG9fYnl0ZXMiLCJtZW1jbXAiLCJidWYxIiwiYnVmMiIsIm1lbWNtcF9zdHJpbmciLCJtZW1jaHIiLCJidWYiLCJidWZfb2ZmIiwiY2hyIiwiYnVmX2xlbiIsImNhbWxfYmlnc3RyaW5nX3NldF8xNiIsImJzIiwiaSIsImNhbWxfYmlnc3RyaW5nX3NldF8zMiIsImNhbWxfYmlnc3RyaW5nX3NldF82NCIsImNhbWxfYmlnc3RyaW5nX2dldF8xNiIsImNhbWxfYmlnc3RyaW5nX2dldF8zMiIsImNhbWxfYmlnc3RyaW5nX2dldF82NCIsImdldF9pbnQxNl9zaWduX2V4dGVuZGVkIiwieCIsInNldF9pbnQxNl9iZSIsInNldF9pbnQxNl9sZSIsInNldF9pbnQzMl9iZSIsInNldF9pbnQzMl9sZSIsInNldF9pbnQ2NF9iZSIsInNldF9pbnQ2NF9sZSIsImdldF9pbnQxNl9iZSIsImdldF9pbnQxNl9sZSIsImdldF9pbnQxNl9zaWduX2V4dGVuZGVkX25vc3dhcCIsImdldF9pbnQxNl9zaWduX2V4dGVuZGVkX25vc3dhcCQwIiwiZ2V0X2ludDE2X3NpZ25fZXh0ZW5kZWRfbGUiLCJnZXRfaW50MzJfYmUiLCJnZXRfaW50MzJfbGUiLCJnZXRfaW50NjRfYmUiLCJnZXRfaW50NjRfbGUiLCJjYW1sX2JpZ3N0cmluZ191bnNhZmVfc2V0XzE2IiwiY2FtbF9iaWdzdHJpbmdfdW5zYWZlX3NldF8zMiIsImNhbWxfYmlnc3RyaW5nX3Vuc2FmZV9zZXRfNjQiLCJjYW1sX2JpZ3N0cmluZ191bnNhZmVfZ2V0XzE2IiwiY2FtbF9iaWdzdHJpbmdfdW5zYWZlX2dldF8zMiIsImNhbWxfYmlnc3RyaW5nX3Vuc2FmZV9nZXRfNjQiLCJ1bnNhZmVfc2V0X2ludDE2X2JlIiwidW5zYWZlX3NldF9pbnQxNl9sZSIsInVuc2FmZV9zZXRfaW50MzJfYmUiLCJ1bnNhZmVfc2V0X2ludDMyX2xlIiwidW5zYWZlX3NldF9pbnQ2NF9iZSIsInVuc2FmZV9zZXRfaW50NjRfbGUiLCJ1bnNhZmVfZ2V0X2ludDE2X2JlIiwidW5zYWZlX2dldF9pbnQxNl9sZSIsInVuc2FmZV9nZXRfaW50MTZfc2lnbl9leHRlbmRlZCIsInVuc2FmZV9nZXRfaW50MTZfc2lnbl9leHRlbmRlZCQwIiwidW5zYWZlX2dldF9pbnQzMl9iZSIsInVuc2FmZV9nZXRfaW50MzJfbGUiLCJ1bnNhZmVfZ2V0X2ludDY0X2JlIiwidW5zYWZlX2dldF9pbnQ2NF9sZSIsInN0YXRlX3RvX29wdGlvbiIsIngiLCJ2IiwiZmFpbF90b19zdHJpbmciLCJtYXJrcyIsImVyciIsInN0YXRlX3RvX3Jlc3VsdCIsImNyZWF0ZSIsImJ1ZmZlciIsIm9mZiIsImxlbiIsImNvbW1pdHRlZF9ieXRlcyIsImxlbmd0aCIsInQiLCJjbGllbnRfY29tbWl0dGVkX2J5dGVzIiwicGFyc2VyX2NvbW1pdHRlZF9ieXRlcyIsImJ5dGVzX2Zvcl9jbGllbnRfdG9fY29tbWl0IiwicGFyc2VyX3VuY29tbWl0dGVkX2J5dGVzIiwiaW52YXJpYW50Iiwib2Zmc2V0X2luX2J1ZmZlciIsInBvcyIsImFwcGx5IiwiZiIsInVuc2FmZV9nZXRfY2hhciIsInVuc2FmZV9nZXRfaW50MTZfbGUiLCJ1bnNhZmVfZ2V0X2ludDMyX2xlIiwidW5zYWZlX2dldF9pbnQ2NF9sZSIsInVuc2FmZV9nZXRfaW50MTZfYmUiLCJ1bnNhZmVfZ2V0X2ludDMyX2JlIiwidW5zYWZlX2dldF9pbnQ2NF9iZSIsImNvdW50X3doaWxlIiwiaSIsImxpbWl0IiwiY29tbWl0IiwiZmFpbF9rIiwiaW5wdXQiLCJtc2ciLCJzdWNjZWVkX2siLCJ0b19leHBvcnRlZF9zdGF0ZSIsImNvbnRpbnVlJDAiLCJjb21taXR0ZWQiLCJicyIsIm1vcmUiLCJ4JDAiLCJzIiwic2wiLCJpJDAiLCJwYXJzZSIsInAiLCJwYXJzZV9iaWdzdHJpbmciLCJpbnB1dCQwIiwicmV0dXJuJDAiLCJmYWlsIiwic3VjYyIsInN5bWJvbF9iaW5kIiwic3VjYyQwIiwic3ltYm9sX21hcCIsInN5bWJvbCIsIm0iLCJzeW1ib2wkMCIsInN1Y2MwIiwiaW5wdXQwIiwicG9zMCIsIm1vcmUwIiwic3VjYzEiLCJpbnB1dDEiLCJwb3MxIiwibW9yZTEiLCJsaWZ0IiwibGlmdDIiLCJtMSIsIm0yIiwic3VjYzIiLCJpbnB1dDIiLCJwb3MyIiwibW9yZTIiLCJsaWZ0MyIsIm0zIiwic3VjYzMiLCJpbnB1dDMiLCJwb3MzIiwibW9yZTMiLCJsaWZ0NCIsIm00Iiwic3VjYzQiLCJpbnB1dDQiLCJwb3M0IiwibW9yZTQiLCJzeW1ib2wkMSIsImEiLCJiIiwic3ltYm9sJDIiLCJzeW1ib2wkMyIsIm1hcmsiLCJmYWlsJDAiLCJzeW1ib2wkNCIsInEiLCJwb3MkMCIsIm1vcmUkMCIsInJldHVybiQxIiwic3ltYm9sX2JpbmQkMCIsInN5bWJvbF9tYXAkMCIsInN5bWJvbCQ1Iiwic3ltYm9sJDYiLCJsaWZ0MiQwIiwibGlmdDMkMCIsImxpZnQ0JDAiLCJzeW1ib2wkNyIsInN5bWJvbCQ4Iiwib2ZfYmlnc3RyaW5nIiwiYnVmIiwid3JpdGFibGVfc3BhY2UiLCJlbnN1cmUiLCJ0b19jb3B5Iiwib2xkX2xlbiIsIm5ld19sZW4iLCJzcGFjZSIsIm5ld19idWYiLCJ3cml0ZV9wb3MiLCJmZWVkX3N0cmluZyIsInN0ciIsImZlZWRfYmlnc3RyaW5nIiwiZmVlZF9pbnB1dCIsInNoaWZ0IiwibiIsImZvcl9yZWFkaW5nIiwidW5jb25zdW1lZCIsIm9wdCIsInN0aCIsIm9mX3VuY29uc3VtZWQiLCJmcm9tX3VuYnVmZmVyZWRfc3RhdGUiLCJidWZmZXJpbmciLCJjb25zdW1lZCIsImNvbnN1bWVkJDAiLCJ1bmNvbnN1bWVkJDAiLCJwYXJzZSQwIiwiaW5pdGlhbF9idWZmZXJfc2l6ZSIsImZlZWQiLCJzdGF0ZSIsImsiLCJidWZmZXJpbmckMCIsInN0YXRlX3RvX29wdGlvbiQwIiwic3RhdGVfdG9fcmVzdWx0JDAiLCJzdGF0ZV90b191bmNvbnN1bWVkIiwicHJvbXB0IiwiZGVtYW5kX2lucHV0IiwiZW5zdXJlX3N1c3BlbmRlZCIsImdvIiwidW5zYWZlX2FwcGx5IiwiYXRfZW5kX29mX2lucHV0IiwiZW5kX29mX2lucHV0IiwiYWR2YW5jZSIsImF2YWlsYWJsZSIsInVuc2FmZV9sb29rYWhlYWQiLCJwZWVrX2NoYXIiLCJwZWVrX2NoYXJfZmFpbCIsInNhdGlzZnkiLCJjIiwiY2hhciQwIiwibm90X2NoYXIiLCJjJDAiLCJhbnlfY2hhciIsImludDgiLCJwJDAiLCJhbnlfdWludDgiLCJwJDEiLCJhbnlfaW50OCIsInNraXAiLCJpbml0Iiwid2l0aF9idWZmZXIiLCJpbnB1dF9sZW4iLCJpbml0JDAiLCJjb3VudF93aGlsZTEiLCJzdWNjJDEiLCJmYWlsJDEiLCJzdHJpbmciLCJmJDAiLCJlIiwic3RyaW5nJDAiLCJzdHJpbmdfY2kiLCJza2lwX3doaWxlIiwidGFrZSIsIm4kMCIsInRha2VfYmlnc3RyaW5nIiwidGFrZV9iaWdzdHJpbmdfd2hpbGUiLCJ0YWtlX2JpZ3N0cmluZ193aGlsZTEiLCJ0YWtlX2JpZ3N0cmluZ190aWxsIiwicGVla19zdHJpbmciLCJ0YWtlX3doaWxlIiwidGFrZV93aGlsZTEiLCJ0YWtlX3RpbGwiLCJjaG9pY2UiLCJwcyIsImZhaWx1cmVfbXNnIiwiZml4X2RpcmVjdCIsInIiLCJmaXhfbGF6eSIsIm1heF9zdGVwcyIsInN0ZXBzIiwiZml4Iiwib3B0aW9uIiwiY29ucyIsInhzIiwibGlzdCIsInBzJDAiLCJjb3VudCIsImxvb3AiLCJtYW55IiwibWFueTEiLCJtYW55X3RpbGwiLCJzZXBfYnkxIiwic2VwX2J5Iiwic2tpcF9tYW55Iiwic2tpcF9tYW55MSIsImVuZF9vZl9saW5lIiwic2NhbiIsInN0YXRlJDAiLCJwYXJzZXIiLCJzY2FuJDAiLCJzY2FuX3N0YXRlIiwic2Nhbl9zdHJpbmciLCJjb25zdW1lX3dpdGgiLCJjb25zdW1lZF9iaWdzdHJpbmciLCJib3RoIiwibWFwIiwiYmluZCIsIm1hcDIiLCJtYXAzIiwibWFwNCIsImQiLCJpbnQxNiIsImludDMyIiwiaW50NjQiLCJhbnlfdWludDE2IiwiYW55X2ludDE2IiwiYW55X2ludDMyIiwiYW55X2ludDY0IiwiYW55X2Zsb2F0IiwiYW55X2RvdWJsZSIsImludDE2JDAiLCJpbnQzMiQwIiwiaW50NjQkMCIsImFueV91aW50MTYkMCIsImFueV9pbnQxNiQwIiwiYW55X2ludDMyJDAiLCJhbnlfaW50NjQkMCIsImFueV9mbG9hdCQwIiwiYW55X2RvdWJsZSQwIiwidGFrZSQwIiwicGVlayIsInRha2Vfd2hpbGUkMCIsImNoZWNrIiwidGFrZV93aGlsZTEkMCIsInRha2VfdGlsbCQwIiwicGFyc2VfYmlnc3RyaW5nJDAiLCJjb25zdW1lIiwicGFyc2Vfc3RyaW5nIiwibXlmb2xkIiwibCIsImEiLCJmIiwibXlyZXZtYXAiLCJteXJldm1hcDIiLCJsMSIsImwyIiwic2VwIiwibWFwIiwic3AiLCJhY3UiLCJ4Iiwic3ltYm9sIiwic3ltYm9sJDAiLCJiIiwiaSIsInN1Y2MiLCJzeW1ib2wkMSIsIm1pbnVzIiwic3ltYm9sJDIiLCJqIiwic3ltYm9sJDMiLCJzeW1ib2wkNCIsInF1b21vZCIsImJpZ21vZCIsInNpZ24iLCJiaWdfY29tcGFyZSIsImJpZ3plcm8iLCJiaWdvbmUiLCJpc19iaWdvbmUiLCJzb2IiLCJib3MiLCJib2kiLCJpb2IiLCJjcmVhdGUiLCJuIiwidiIsImNvcHkiLCJ0IiwiZ2V0IiwiaW5kZXgiLCJzZXQiLCJsZW4iLCJuZXdhcnJheSIsInNpemUiLCJmb2xkIiwiYWtrIiwiaXRlciIsImZpbmRfcHJpbWUiLCJ5IiwieCQwIiwiZ2NkIiwieCQxIiwiY29tcHV0ZV9zaHVmZmxlIiwiY2FyZCIsImNvbXB1dGUiLCJwcmltZSIsIm5ld19pbmRleCIsImdldF9jYXJkaW5hbCIsInAiLCJzaHVmZmxlIiwicGFydCIsImVtcHR5X3BhcnQiLCJ1bmluaXRpYWxpemVkX3BhcnQiLCJtYXBfcGFydCIsInBhcnRfZnJvbV9saXN0IiwidmFsdWVzIiwiYXZhbHVlcyIsInVuaW9uX3BhcnRzIiwicGFydGxpc3QiLCJpbmRleCQxIiwicGFydGxpc3QkMCIsInBhcnRsaXN0JDEiLCJpbmRleCQwIiwicHJlX3Jlc3VsdCIsInByb2R1Y3RfcGFydHMiLCJwYXJ0cyIsInBhcnRfcmV2dmVjdG9yIiwicGFydF9yZXZ2ZWN0b3IkMCIsInZlY3RvciIsInBhcnRfcmV2dmVjdG9yJDEiLCJwY2FyZCIsIm1vZCIsInBfY2FyZGluYWwiLCJjYXJkaW5hbCIsImV4ZW4iLCJjaGVja19hcnJheV9pbmRleCIsImdldF9wYXJ0IiwiYXJyYXlfaW5kZXgiLCJuZXdjZWxsIiwicGFydCQwIiwiZ2V0X2luX3BhcnRzIiwidmFsdWVfaW5kZXgiLCJ2YWx1ZV9pbmRleCQwIiwiYXJyYXlfaW5kZXgkMCIsImFycmF5X2luZGV4JDEiLCJ2YWx1ZV9pbmRleCQxIiwibWF4IiwiZnJvbV9zaW5nbGVfcGFydCIsInRpdGxlIiwiYV9wYXJ0IiwiZnJvbV9saXN0Iiwib3B0Iiwic3RoIiwibmFtZSIsInBheSIsImxfZXhlbiIsImlzX2luZmluaXRlIiwibmV3X3BhcnQiLCJzdWIiLCJib3VuZCIsIm5ld2NhcmRpbmFsIiwic3VtX2NhcmRpbmFscyIsImFjdSQwIiwiZXhlbnMiLCJpbmZtYXgiLCJtYXhfcGFydHMiLCJ1bmlvbiIsImV4IiwiZSIsInByb2RfY2FyZGluYWxzIiwieiIsImsiLCJmaW5kX3ZlY3RvcnNfYXV4IiwibGFzdF9jaGFuY2UiLCJkZXB0aCIsImZsYWciLCJ0ZW1wX3ZlY3QiLCJwb3MiLCJyZXZfbWF4Iiwib3RoZXJzIiwiY3VycmVudF92dXAiLCJ2dXAiLCJ2bG93IiwicmFjdSIsImN1cnJlbnRfaW5kZXgiLCJmbGFnJDAiLCJmaW5kX3ZlY3RvcnMiLCJyZXZfbWF4X2luZGV4ZXMiLCJsYXN0IiwiY3VycmVudF9wb3MiLCJ2ZWN0b3JfdG9fcGFydF9saXN0IiwicHJvZF9wYXJ0cyIsIm1heF9yZXZpbmRleGVzIiwiYWxsX3ZlY3RvcnMiLCJhbGxfcmV2X3BhcnRzIiwiYWxsX3Byb2RfcGFydHMiLCJwcm9kdWN0IiwiZ2VuX3Rlc3RlciIsInByaW50IiwidG9zIiwiYmluZCIsInVuaXQiLCJ1cHRvIiwicmVtYWluaW5nIiwiZnJvbSIsInN0aCQwIiwidmVyYm9zZV9wZXJpb2QiLCJiaWd2ZXJib3NlX3BlcmlvZCIsIml0ZXJhdGUiLCJjb3VudCIsImN1cnJlbnQiLCJyZW1haW5pbmckMCIsImN1cnJlbnQkMCIsInJlbWFpbmluZyQxIiwidXBwZXJfYm91bmQiLCJjb250aW51ZSQwIiwidmVyYm9zZSIsInRlc3RfdmFsdWUiLCJ0b3MkMCIsImN1cnJlbnQkMSIsImdldF9leGVuIiwieCIsInByb2R1Y3QiLCJ1bmlvbiIsImZyb21fbGlzdCIsInNpbmdsZSIsIm5hbWUiLCJtYXAiLCJnZXQiLCJjYXJkaW5hbCIsInBheSIsInN1YiIsImMxXzIiLCJjMl8yIiwicHJvajIiLCJhIiwiYiIsInR1cGxlMiIsImV4MSIsImV4MiIsIm1leDEiLCJtZXgyIiwiYzFfMyIsImMyXzMiLCJjM18zIiwicHJvajMiLCJjIiwidHJpcGxlIiwiZXgzIiwibWV4MyIsInR1cGxlNCIsImUxIiwiZTIiLCJlMyIsImU0IiwiZCIsInR1cGxlNSIsImU1IiwiZSIsInR1cGxlNiIsImU2IiwiZiIsImNoYXJfcGFydCIsIm4iLCJ1c3VhbF9jaGFyX3BhcnQiLCJlX3VuaXQiLCJlX2Jvb2wiLCJlX2NoYXIiLCJlX3BjaGFyIiwiZV96ZXJvIiwiZV9vbmUiLCJiaWcybiIsImJpZzJucDEiLCJlX2JpZ3BvcyIsImVfYmlncG9zJDAiLCJlX2JpZ25hdCIsImVfYmlnbmVnIiwiZV9iaWdpbnQiLCJlX2JpZ2ludGVydmFsIiwiZV9pbnRlcnZhbCIsImJtYXhfaW50IiwidG9pbnQiLCJlX25hdCIsImVfcG9zIiwiZV9uZWciLCJlX2ludCIsImVfc3RyaW5nX2Zyb21fZWNoYXIiLCJlbnVtX2NoYXJzIiwiZW51bSQwIiwiZV9zdHJpbmciLCJlX3JzdHJpbmciLCJjaGFybGlzdCIsImVfbGlzdCIsImV4ZW4iLCJlX25lX2xpc3QiLCJlX2FycmF5IiwiZV9vcHRpb24iLCJiaWdzaG93IiwidG9fc3RyaW5nIiwibjEiLCJuMiIsImkiLCJpbmRleCIsInNob3ciLCJ0ZXN0ZXIiLCJmcm9tIiwidXB0byIsInZlcmJvc2VfcGVyaW9kIiwidG9zIiwibGVuIiwiY2FtbHN0cmluZ19vZl9jb3FzdHJpbmciLCJzIiwiciIsInBvcyIsInMkMCIsImMiLCJjb3FzdHJpbmdfb2ZfY2FtbHN0cmluZyIsInBvcyQxIiwiYWNjdSIsInBvcyQwIiwiYWNjdSQwIiwiaXNfc3BhY2UiLCJzcGFjZXMiLCJwYXJlbnMiLCJwIiwiYm94IiwieCIsImRpYW1vbmQiLCJuZWciLCJ5IiwiZGlzaiIsImNvbmoiLCJtb2RhbCIsImltcGwiLCJib3QiLCJ0b3AiLCJsZXR0ZXIiLCJsZXR0ZXJfb3JfZGlnaXQiLCJpZGVudGlmaWVyIiwiY2hhaW5sMSIsImUiLCJvcCIsImdvIiwiYWNjIiwiZiIsImluaXQiLCJjaGFpbnIxIiwiY2hhaW5tb2QiLCJleHByIiwiZmFjdG9yIiwibW9kYWxpdHkiLCJ0ZXJtIiwiZGlzanVuY3Rpb25zIiwiZXZhbCQwIiwic3RyIiwidiIsImludF9vZl9uYXQiLCJuIiwic3RyaW5nX29mX2Zvcm11bGEiLCJvcHQiLCJzdGgiLCJjbGFzc2ljYWwiLCJ2IiwiZyIsImYiLCJicmFja2V0IiwiZyQwIiwiZiQwIiwiZiQxIiwiZiQyIiwiZiQzIiwiZyQxIiwiZiQ0IiwiZSIsImUkMCIsImNhdGNoX2UiLCJmIiwiZSQwIiwiZSIsInMiLCJmYWlsX29uX21vZGFsaXR5IiwiYXV4IiwieSIsIngiLCJ2Il0sInNvdXJjZXMiOlsiL2J1aWx0aW4vK21sQnl0ZXMuanMiLCIvYnVpbHRpbi8rYmlnYXJyYXkuanMiLCIvYnVpbHRpbi8rbWFyc2hhbC5qcyIsIi9idWlsdGluLyt1bml4LmpzIiwiL2J1aWx0aW4vK3N0ZGxpYi5qcyIsIi9idWlsdGluLytzeXMuanMiLCIvYnVpbHRpbi8rYmFja3RyYWNlLmpzIiwiL2J1aWx0aW4vK2pzbGliLmpzIiwiL2J1aWx0aW4vK2ZhaWwuanMiLCIvYnVpbHRpbi8rZnMuanMiLCIvYnVpbHRpbi8rZnNfZmFrZS5qcyIsIi9idWlsdGluLytpbnQ2NC5qcyIsIi9idWlsdGluLytzeW5jLmpzIiwiL2J1aWx0aW4vK25hdC5qcyIsIi9idWlsdGluLytmc19ub2RlLmpzIiwiL2J1aWx0aW4vK2JpZ3N0cmluZy5qcyIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvYmlnc3RyaW5nYWYvcnVudGltZS5qcyIsIi9idWlsdGluLytjb21wYXJlLmpzIiwiL2J1aWx0aW4vK21kNS5qcyIsIi9idWlsdGluLytpZWVlXzc1NC5qcyIsIi9idWlsdGluLytvYmouanMiLCIvYnVpbHRpbi8rZWZmZWN0LmpzIiwiL2J1aWx0aW4vK2FycmF5LmpzIiwiL2J1aWx0aW4vK2RvbWFpbi5qcyIsIi9idWlsdGluLytpbnRzLmpzIiwiL2J1aWx0aW4vK2hhc2guanMiLCIvYnVpbHRpbi8raW8uanMiLCIvYnVpbHRpbi8rcnVudGltZV9ldmVudHMuanMiLCIvYnVpbHRpbi8renN0ZC5qcyIsIi9idWlsdGluLyt3ZWFrLmpzIiwiL2J1aWx0aW4vK2djLmpzIiwiL2J1aWx0aW4vK2Zvcm1hdC5qcyIsIi9idWlsdGluLytncmFwaGljcy5qcyIsIi9idWlsdGluLytqc2xpYl9qc19vZl9vY2FtbC5qcyIsIi9idWlsdGluLytsZXhpbmcuanMiLCIvYnVpbHRpbi8rcHJuZy5qcyIsIi9idWlsdGluLytwYXJzaW5nLmpzIiwiL2J1aWx0aW4vK3N0ci5qcyIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvb2NhbWwvY2FtbGludGVybmFsRm9ybWF0QmFzaWNzLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9vY2FtbC9jYW1saW50ZXJuYWxBdG9taWMubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL29jYW1sL3N0ZGxpYi5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvb2NhbWwvcGVydmFzaXZlcy5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvb2NhbWwvc2VxLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9vY2FtbC9vcHRpb24ubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL29jYW1sL2VpdGhlci5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvb2NhbWwvcmVzdWx0Lm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9vY2FtbC9ib29sLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9vY2FtbC9jaGFyLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9vY2FtbC91Y2hhci5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvb2NhbWwvbGlzdC5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvb2NhbWwvaW50Lm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9vY2FtbC9ieXRlcy5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvb2NhbWwvc3RyaW5nLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9vY2FtbC91bml0Lm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9vY2FtbC9tYXJzaGFsLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9vY2FtbC9vYmoubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL29jYW1sL2FycmF5Lm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9vY2FtbC9mbG9hdC5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvb2NhbWwvaW50MzIubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL29jYW1sL2ludDY0Lm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9vY2FtbC9uYXRpdmVpbnQubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL29jYW1sL2xleGluZy5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvb2NhbWwvcGFyc2luZy5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvb2NhbWwvc2V0Lm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9vY2FtbC9tYXAubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL29jYW1sL3N0YWNrLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9vY2FtbC9xdWV1ZS5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvb2NhbWwvY2FtbGludGVybmFsTGF6eS5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvb2NhbWwvbGF6eS5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvb2NhbWwvc3RyZWFtLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9vY2FtbC9idWZmZXIubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL29jYW1sL2NhbWxpbnRlcm5hbEZvcm1hdC5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvb2NhbWwvcHJpbnRmLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9vY2FtbC9hcmcubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL29jYW1sL3ByaW50ZXhjLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9vY2FtbC9mdW4ubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL29jYW1sL2djLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9vY2FtbC9kaWdlc3QubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL29jYW1sL3JhbmRvbS5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvb2NhbWwvaGFzaHRibC5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvb2NhbWwvd2Vhay5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvb2NhbWwvZm9ybWF0Lm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9vY2FtbC9zY2FuZi5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvb2NhbWwvY2FsbGJhY2subWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL29jYW1sL2NhbWxpbnRlcm5hbE9PLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9vY2FtbC9jYW1saW50ZXJuYWxNb2QubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL29jYW1sL2dlbmxleC5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvb2NhbWwvZXBoZW1lcm9uLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9vY2FtbC9maWxlbmFtZS5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvb2NhbWwvY29tcGxleC5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvb2NhbWwvYmlnYXJyYXkubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL2pzX29mX29jYW1sLWNvbXBpbGVyL3J1bnRpbWUvanNvb19ydW50aW1lX18ubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL2pzX29mX29jYW1sLWNvbXBpbGVyL3J1bnRpbWUvanNvb19ydW50aW1lLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9qc19vZl9vY2FtbC9qc19vZl9vY2FtbF9fLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9qc19vZl9vY2FtbC9pbXBvcnQubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL2pzX29mX29jYW1sL2pzLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9qc19vZl9vY2FtbC9kb20ubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL2pzX29mX29jYW1sL3R5cGVkX2FycmF5Lm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9qc19vZl9vY2FtbC9maWxlLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9qc19vZl9vY2FtbC9kb21faHRtbC5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvanNfb2Zfb2NhbWwvZm9ybS5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvanNfb2Zfb2NhbWwveG1sSHR0cFJlcXVlc3QubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL2pzX29mX29jYW1sL3dvcmtlci5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvanNfb2Zfb2NhbWwvd2ViU29ja2V0cy5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvanNfb2Zfb2NhbWwvd2ViR0wubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL2pzX29mX29jYW1sL3JlZ2V4cC5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvanNfb2Zfb2NhbWwvdXJsLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9qc19vZl9vY2FtbC9zeXNfanMubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL2pzX29mX29jYW1sL3Jlc2l6ZU9ic2VydmVyLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9qc19vZl9vY2FtbC9wZXJmb3JtYW5jZU9ic2VydmVyLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9qc19vZl9vY2FtbC9tdXRhdGlvbk9ic2VydmVyLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9qc19vZl9vY2FtbC9qc3RhYmxlLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9qc19vZl9vY2FtbC9qc29uLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9qc19vZl9vY2FtbC9jU1MubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL2pzX29mX29jYW1sL2RvbV9ldmVudHMubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL2pzX29mX29jYW1sL2RvbV9zdmcubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL2pzX29mX29jYW1sL2V2ZW50U291cmNlLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9qc19vZl9vY2FtbC9maXJlYnVnLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9qc19vZl9vY2FtbC9nZW9sb2NhdGlvbi5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvanNfb2Zfb2NhbWwvaW50ZXJzZWN0aW9uT2JzZXJ2ZXIubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL2pzX29mX29jYW1sL2ludGwubWwiLCIvd29ya3NwYWNlX3Jvb3QvZXh0cmFjdGlvbi9iYXNlLm1sIiwiL3dvcmtzcGFjZV9yb290L2V4dHJhY3Rpb24vQ01MX1N5bnRheC5tbCIsIi93b3Jrc3BhY2Vfcm9vdC9leHRyYWN0aW9uL0RhdGF0eXBlcy5tbCIsIi93b3Jrc3BhY2Vfcm9vdC9leHRyYWN0aW9uL0NvbXBhcmVfZGVjLm1sIiwiL3dvcmtzcGFjZV9yb290L2V4dHJhY3Rpb24vTmF0Lm1sIiwiL3dvcmtzcGFjZV9yb290L2V4dHJhY3Rpb24vU3RyaW5nLm1sIiwiL3dvcmtzcGFjZV9yb290L2V4dHJhY3Rpb24vRm9ybXVsYXMubWwiLCIvd29ya3NwYWNlX3Jvb3QvZXh0cmFjdGlvbi9MaXN0Lm1sIiwiL3dvcmtzcGFjZV9yb290L2V4dHJhY3Rpb24vbGlzdDAubWwiLCIvd29ya3NwYWNlX3Jvb3QvZXh0cmFjdGlvbi9udW1iZXJzLm1sIiwiL3dvcmtzcGFjZV9yb290L2V4dHJhY3Rpb24vRW52aXJvbm1lbnRzLm1sIiwiL3dvcmtzcGFjZV9yb290L2V4dHJhY3Rpb24vR0xTX2NhbGNzLm1sIiwiL3dvcmtzcGFjZV9yb290L2V4dHJhY3Rpb24vZ2VuVC5tbCIsIi93b3Jrc3BhY2Vfcm9vdC9leHRyYWN0aW9uL0xpc3RfbGVtbWFzVC5tbCIsIi93b3Jrc3BhY2Vfcm9vdC9leHRyYWN0aW9uL2xpc3RfbGVtcy5tbCIsIi93b3Jrc3BhY2Vfcm9vdC9leHRyYWN0aW9uL3JlbW92ZV9saXN0X2xlbXMubWwiLCIvd29ya3NwYWNlX3Jvb3QvZXh0cmFjdGlvbi9HTFNfZGVjLm1sIiwiL3dvcmtzcGFjZV9yb290L2V4dHJhY3Rpb24vUGVhbm9OYXQubWwiLCIvd29ya3NwYWNlX3Jvb3QvZXh0cmFjdGlvbi9HTFNfZGVyX2RlYy5tbCIsIi93b3Jrc3BhY2Vfcm9vdC9leHRyYWN0aW9uL0dMU190ZXJtaW5hdGlvbl9tZWFzdXJlLm1sIiwiL3dvcmtzcGFjZV9yb290L2V4dHJhY3Rpb24vS1NfZGVjLm1sIiwiL3dvcmtzcGFjZV9yb290L2V4dHJhY3Rpb24vS1NfdGVybWluYXRpb25fcHJlbGltcy5tbCIsIi93b3Jrc3BhY2Vfcm9vdC9leHRyYWN0aW9uL0tTX3Rlcm1pbmF0aW9uX0ltcFIubWwiLCIvd29ya3NwYWNlX3Jvb3QvZXh0cmFjdGlvbi9LU190ZXJtaW5hdGlvbl9JbXBMLm1sIiwiL3dvcmtzcGFjZV9yb290L2V4dHJhY3Rpb24vS1NfdGVybWluYXRpb25fS1IubWwiLCIvd29ya3NwYWNlX3Jvb3QvZXh0cmFjdGlvbi9Qcm9wUXVhbnRpZmllcnMubWwiLCIvd29ya3NwYWNlX3Jvb3QvZXh0cmFjdGlvbi9TaW1wLm1sIiwiL3dvcmtzcGFjZV9yb290L2V4dHJhY3Rpb24vVUlHTF9pcnJlZF9zaG9ydC5tbCIsIi93b3Jrc3BhY2Vfcm9vdC9leHRyYWN0aW9uL1VJR0xfQ2Fub3B5Lm1sIiwiL3dvcmtzcGFjZV9yb290L2V4dHJhY3Rpb24vVUlHTF9MZXhTZXEubWwiLCIvd29ya3NwYWNlX3Jvb3QvZXh0cmFjdGlvbi9VSUdMX2Jhc2ljcy5tbCIsIi93b3Jrc3BhY2Vfcm9vdC9leHRyYWN0aW9uL1VJR0xfbm9kdXBzZXEubWwiLCIvd29ya3NwYWNlX3Jvb3QvZXh0cmFjdGlvbi9VSUdMX2JyYWdhLm1sIiwiL3dvcmtzcGFjZV9yb290L2V4dHJhY3Rpb24vVUlLX2lycmVkX3Nob3J0Lm1sIiwiL3dvcmtzcGFjZV9yb290L2V4dHJhY3Rpb24vVUlLX0Nhbm9weS5tbCIsIi93b3Jrc3BhY2Vfcm9vdC9leHRyYWN0aW9uL1VJS19iYXNpY3MubWwiLCIvd29ya3NwYWNlX3Jvb3QvZXh0cmFjdGlvbi9VSUtfYnJhZ2EubWwiLCIvd29ya3NwYWNlX3Jvb3QvZXh0cmFjdGlvbi9VSU1MX2V4dHJhY3Rpb24ubWwiLCIvd29ya3NwYWNlX3Jvb3QvZXh0cmFjdGlvbi9EZWNpc2lvblByb2NlZHVyZS5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvYmlnc3RyaW5nYWYvYmlnc3RyaW5nYWYubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL2FuZ3N0cm9tL2V4cG9ydGVkX3N0YXRlLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9hbmdzdHJvbS9pbnB1dC5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvYW5nc3Ryb20vcGFyc2VyLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9hbmdzdHJvbS9idWZmZXJpbmcubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL2FuZ3N0cm9tL2FuZ3N0cm9tLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9leGVudW0vaW50ZXJuYWxzL2NvbnZlbmllbmNlLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9leGVudW0vaW50ZXJuYWxzL2V4dEFycmF5Lm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9leGVudW0vaW50ZXJuYWxzL3NodWZmbGUubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL2V4ZW51bS9pbnRlcm5hbHMvcGFydHMubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL2V4ZW51bS9pbnRlcm5hbHMvZXhlbi5tbCIsIi9ob21lL2NvcS8ub3BhbS80LjEzLjErZmxhbWJkYS9saWIvZXhlbnVtL2ludGVybmFscy90ZXN0ZXIubWwiLCIvaG9tZS9jb3EvLm9wYW0vNC4xMy4xK2ZsYW1iZGEvbGliL2V4ZW51bS9leGVudW0ubWwiLCIvd29ya3NwYWNlX3Jvb3QvYmluL3N0cmluZ2NvbnZlcnNpb24ubWwiLCIvd29ya3NwYWNlX3Jvb3QvYmluL21vZGFsX2V4cHJlc3Npb25zX3BhcnNlci5tbCIsIi93b3Jrc3BhY2Vfcm9vdC9iaW4vcHJpbnRlci5tbCIsIi93b3Jrc3BhY2Vfcm9vdC9iaW4vdWltbF9kZW1vLm1sIiwiL2hvbWUvY29xLy5vcGFtLzQuMTMuMStmbGFtYmRhL2xpYi9vY2FtbC9zdGRfZXhpdC5tbCJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0EsQzs7Rzs7O1E7Uzs7O0c7STtJO0k7RztFOzs7O0dBd0VBLFNBQVNBLHlCQUEwQkMsR0FBR0MsR0FBR0M7SUFDakMsSUFBRkMsSUFBSUM7SUFDUixHQUFJSCxVQUFVQyxlQUFlQSxPQUFPRixVQUFVLE9BQU9HLFFBQVNFLE1BQU1MO0lBQzlELElBQUZNO0lBQ0osVUFBV0osS0FBS0QsV0FBVUM7S0FDeEJJLEtBQUtILFFBQVNFLE1BQU1MLFFBQVFDLEdBQUVBLElBQUlNLFNBQVNMO0lBQzdDLE9BQU9JO0dBQ1Q7R0Ftb0JBLFNBQVNFLHVCQUF1QkMsR0FBSyxPQUFPQSxFQUFFO0dBek45QyxTQUFTQyxxQkFBc0JWO0lBQzdCLE9BQU9RLHVCQUF1QlQseUJBQXlCQyxNQUFJQTtHQUM3RDtHQ2xGQSxTQUFTVyxjQUFjQyxJQUFJQyxJQUN6QixPQUFPRCxPQUFPQSxVQUFVQyxLQUMxQjtHQ2xTQSxTQUFTQyxnQkFBaUJDLElBQUlkLEdBQUtlLFNBQVNELElBQUlDLFNBQVNmLEVBQUc7R0FDNURhO3dCQUN1QixPQUFPSCxjQUFjSyxRQUFPQSxVQUExQzt3QkFDYyxPQUFPTCxj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O2VBQUEsTUFBQSwrQ0FBdkJJO2VBQXVCLE1BQUEsV0FBYSxvQ0FUbkRLO2NBU3NDLE9BQUE7YUFBb0Q7R0FBQztzQkFEOUVMO0lBQUssT0F0QmxCSjs7Y0FzQnFDO2VBQUE7aUJBakJyQ0s7bUJBaUJxQywrQ0FBeEJEO2VBQXdCLE1BQUEsV0FBaUMsb0NBUnRFSztjQVFxQyxPQUFBO2FBQTZEO0dBQUM7c0JBRHRGTDtJQUFLLE9BckJsQko7O2NBcUJxQztlQUFBO2lCQWhCckNLO21CQWdCcUMsK0NBQXhCRDtlQUF3QixNQUFBLFdBQWlDLG9DQVB0RUs7Y0FPcUMsT0FBQTthQUE2RDtHQUFDO0dBTHJHOzs7Ozs7Ozs7O0dBQUE7Ozs7RTs7Ozs7Ozs7Ozs7OztHOzs7Ozs7OztHQ05NO0dBQUE7OztFIiwic291cmNlc0NvbnRlbnQiOlsiLy8gSnNfb2Zfb2NhbWwgcnVudGltZSBzdXBwb3J0XG4vLyBodHRwOi8vd3d3Lm9jc2lnZW4ub3JnL2pzX29mX29jYW1sL1xuLy8gQ29weXJpZ2h0IChDKSAyMDEwLTIwMTQgSsOpcsO0bWUgVm91aWxsb25cbi8vIExhYm9yYXRvaXJlIFBQUyAtIENOUlMgVW5pdmVyc2l0w6kgUGFyaXMgRGlkZXJvdFxuLy9cbi8vIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4vLyBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbi8vIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHdpdGggbGlua2luZyBleGNlcHRpb247XG4vLyBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vL1xuLy8gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuLy8gR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vL1xuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4vLyBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcsIFVTQS5cblxuLy8gQW4gT0NhbWwgc3RyaW5nIGlzIGFuIG9iamVjdCB3aXRoIHRocmVlIGZpZWxkczpcbi8vIC0gdGFnICd0J1xuLy8gLSBsZW5ndGggJ2wnXG4vLyAtIGNvbnRlbnRzICdjJ1xuLy9cbi8vIFRoZSBjb250ZW50cyBvZiB0aGUgc3RyaW5nIGNhbiBiZSBlaXRoZXIgYSBKYXZhU2NyaXB0IGFycmF5IG9yXG4vLyBhIEphdmFTY3JpcHQgc3RyaW5nLiBUaGUgbGVuZ3RoIG9mIHRoaXMgc3RyaW5nIGNhbiBiZSBsZXNzIHRoYW4gdGhlXG4vLyBsZW5ndGggb2YgdGhlIE9DYW1sIHN0cmluZy4gSW4gdGhpcyBjYXNlLCByZW1haW5pbmcgYnl0ZXMgYXJlXG4vLyBhc3N1bWVkIHRvIGJlIHplcm9lcy4gQXJyYXlzIGFyZSBtdXRhYmxlIGJ1dCBjb25zdW1lcyBtb3JlIG1lbW9yeVxuLy8gdGhhbiBzdHJpbmdzLiBBIGNvbW1vbiBwYXR0ZXJuIGlzIHRvIHN0YXJ0IGZyb20gYW4gZW1wdHkgc3RyaW5nIGFuZFxuLy8gcHJvZ3Jlc3NpdmVseSBmaWxsIGl0IGZyb20gdGhlIHN0YXJ0LiBQYXJ0aWFsIHN0cmluZ3MgbWFrZXMgaXRcbi8vIHBvc3NpYmxlIHRvIGltcGxlbWVudCB0aGlzIGVmZmljaWVudGx5LlxuLy9cbi8vIFdoZW4gY29udmVydGluZyB0byBhbmQgZnJvbSBVVEYtMTYsIHdlIGtlZXAgdHJhY2sgb2Ygd2hldGhlciB0aGVcbi8vIHN0cmluZyBpcyBjb21wb3NlZCBvbmx5IG9mIEFTQ0lJIGNoYXJhY3RlcnMgKGluIHdoaWNoIGNhc2UsIG5vXG4vLyBjb252ZXJzaW9uIG5lZWRzIHRvIGJlIHBlcmZvcm1lZCkgb3Igbm90LlxuLy9cbi8vIFRoZSBzdHJpbmcgdGFnIGNhbiB0aHVzIHRha2UgdGhlIGZvbGxvd2luZyB2YWx1ZXM6XG4vLyAgIGZ1bGwgc3RyaW5nICAgICBCWVRFIHwgVU5LTk9XTjogICAgICAwXG4vLyAgICAgICAgICAgICAgICAgICBCWVRFIHwgQVNDSUk6ICAgICAgICA5XG4vLyAgICAgICAgICAgICAgICAgICBCWVRFIHwgTk9UX0FTQ0lJOiAgICA4XG4vLyAgIHN0cmluZyBwcmVmaXggICBQQVJUSUFMOiAgICAgICAgICAgICAyXG4vLyAgIGFycmF5ICAgICAgICAgICBBUlJBWTogICAgICAgICAgICAgICA0XG4vL1xuLy8gT25lIGNhbiB1c2UgYml0IG1hc2tpbmcgdG8gZGlzY3JpbWluYXRlIHRoZXNlIGRpZmZlcmVudCBjYXNlczpcbi8vICAga25vd25fZW5jb2RpbmcoeCkgPSB4Jjhcbi8vICAgaXNfYXNjaWkoeCkgPSAgICAgICB4JjFcbi8vICAga2luZCh4KSA9ICAgICAgICAgICB4JjZcblxuLy9Qcm92aWRlczogY2FtbF9zdHJfcmVwZWF0XG5mdW5jdGlvbiBjYW1sX3N0cl9yZXBlYXQobiwgcykge1xuICBpZihuID09IDApIHJldHVybiBcIlwiO1xuICBpZiAocy5yZXBlYXQpIHtyZXR1cm4gcy5yZXBlYXQobik7fSAvLyBFQ01Bc2NyaXB0IDYgYW5kIEZpcmVmb3ggMjQrXG4gIHZhciByID0gXCJcIiwgbCA9IDA7XG4gIGZvcig7Oykge1xuICAgIGlmIChuICYgMSkgciArPSBzO1xuICAgIG4gPj49IDE7XG4gICAgaWYgKG4gPT0gMCkgcmV0dXJuIHI7XG4gICAgcyArPSBzO1xuICAgIGwrKztcbiAgICBpZiAobCA9PSA5KSB7XG4gICAgICBzLnNsaWNlKDAsMSk7IC8vIGZsYXR0ZW4gdGhlIHN0cmluZ1xuICAgICAgLy8gdGhlbiwgdGhlIGZsYXR0ZW5pbmcgb2YgdGhlIHdob2xlIHN0cmluZyB3aWxsIGJlIGZhc3RlcixcbiAgICAgIC8vIGFzIGl0IHdpbGwgYmUgY29tcG9zZWQgb2YgbGFyZ2VyIHBpZWNlc1xuICAgIH1cbiAgfVxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N1YmFycmF5X3RvX2pzYnl0ZXNcbi8vV2Vha2RlZlxuLy8gUHJlIEVDTUFTY3JpcHQgNSwgW2FwcGx5XSB3b3VsZCBub3Qgc3VwcG9ydCBhcnJheS1saWtlIG9iamVjdC5cbi8vIEluIHN1Y2ggc2V0dXAsIFR5cGVkX2FycmF5IHdvdWxkIGJlIGltcGxlbWVudGVkIGFzIHBvbHlmaWxsLCBhbmQgW2YuYXBwbHldIHdvdWxkXG4vLyBmYWlsIGhlcmUuIE1hcmsgdGhlIHByaW1pdGl2ZSBhcyBXZWFrZGVmLCBzbyB0aGF0IHBlb3BsZSBjYW4gb3ZlcnJpZGUgaXQgZWFzaWx5LlxuZnVuY3Rpb24gY2FtbF9zdWJhcnJheV90b19qc2J5dGVzIChhLCBpLCBsZW4pIHtcbiAgdmFyIGYgPSBTdHJpbmcuZnJvbUNoYXJDb2RlO1xuICBpZiAoaSA9PSAwICYmIGxlbiA8PSA0MDk2ICYmIGxlbiA9PSBhLmxlbmd0aCkgcmV0dXJuIGYuYXBwbHkgKG51bGwsIGEpO1xuICB2YXIgcyA9IFwiXCI7XG4gIGZvciAoOyAwIDwgbGVuOyBpICs9IDEwMjQsbGVuLT0xMDI0KVxuICAgIHMgKz0gZi5hcHBseSAobnVsbCwgYS5zbGljZShpLGkgKyBNYXRoLm1pbihsZW4sIDEwMjQpKSk7XG4gIHJldHVybiBzO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3V0Zjhfb2ZfdXRmMTZcbmZ1bmN0aW9uIGNhbWxfdXRmOF9vZl91dGYxNihzKSB7XG4gIGZvciAodmFyIGIgPSBcIlwiLCB0ID0gYiwgYywgZCwgaSA9IDAsIGwgPSBzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGMgPSBzLmNoYXJDb2RlQXQoaSk7XG4gICAgaWYgKGMgPCAweDgwKSB7XG4gICAgICBmb3IgKHZhciBqID0gaSArIDE7IChqIDwgbCkgJiYgKGMgPSBzLmNoYXJDb2RlQXQoaikpIDwgMHg4MDsgaisrKTtcbiAgICAgIGlmIChqIC0gaSA+IDUxMikgeyB0LnN1YnN0cigwLCAxKTsgYiArPSB0OyB0ID0gXCJcIjsgYiArPSBzLnNsaWNlKGksIGopIH1cbiAgICAgIGVsc2UgdCArPSBzLnNsaWNlKGksIGopO1xuICAgICAgaWYgKGogPT0gbCkgYnJlYWs7XG4gICAgICBpID0gajtcbiAgICB9XG4gICAgaWYgKGMgPCAweDgwMCkge1xuICAgICAgdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4YzAgfCAoYyA+PiA2KSk7XG4gICAgICB0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHg4MCB8IChjICYgMHgzZikpO1xuICAgIH0gZWxzZSBpZiAoYyA8IDB4ZDgwMCB8fCBjID49IDB4ZGZmZikge1xuICAgICAgdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4ZTAgfCAoYyA+PiAxMiksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4MCB8ICgoYyA+PiA2KSAmIDB4M2YpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ODAgfCAoYyAmIDB4M2YpKTtcbiAgICB9IGVsc2UgaWYgKGMgPj0gMHhkYmZmIHx8IGkgKyAxID09IGwgfHxcbiAgICAgICAgICAgICAgIChkID0gcy5jaGFyQ29kZUF0KGkgKyAxKSkgPCAweGRjMDAgfHwgZCA+IDB4ZGZmZikge1xuICAgICAgLy8gVW5tYXRjaGVkIHN1cnJvZ2F0ZSBwYWlyLCByZXBsYWNlZCBieSBcXHVmZmZkIChyZXBsYWNlbWVudCBjaGFyYWN0ZXIpXG4gICAgICB0ICs9IFwiXFx4ZWZcXHhiZlxceGJkXCI7XG4gICAgfSBlbHNlIHtcbiAgICAgIGkrKztcbiAgICAgIGMgPSAoYyA8PCAxMCkgKyBkIC0gMHgzNWZkYzAwO1xuICAgICAgdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4ZjAgfCAoYyA+PiAxOCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4MCB8ICgoYyA+PiAxMikgJiAweDNmKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDgwIHwgKChjID4+IDYpICYgMHgzZiksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4MCB8IChjICYgMHgzZikpO1xuICAgIH1cbiAgICBpZiAodC5sZW5ndGggPiAxMDI0KSB7dC5zdWJzdHIoMCwgMSk7IGIgKz0gdDsgdCA9IFwiXCI7fVxuICB9XG4gIHJldHVybiBiK3Q7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfdXRmMTZfb2ZfdXRmOFxuZnVuY3Rpb24gY2FtbF91dGYxNl9vZl91dGY4KHMpIHtcbiAgZm9yICh2YXIgYiA9IFwiXCIsIHQgPSBcIlwiLCBjLCBjMSwgYzIsIHYsIGkgPSAwLCBsID0gcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBjMSA9IHMuY2hhckNvZGVBdChpKTtcbiAgICBpZiAoYzEgPCAweDgwKSB7XG4gICAgICBmb3IgKHZhciBqID0gaSArIDE7IChqIDwgbCkgJiYgKGMxID0gcy5jaGFyQ29kZUF0KGopKSA8IDB4ODA7IGorKyk7XG4gICAgICBpZiAoaiAtIGkgPiA1MTIpIHsgdC5zdWJzdHIoMCwgMSk7IGIgKz0gdDsgdCA9IFwiXCI7IGIgKz0gcy5zbGljZShpLCBqKSB9XG4gICAgICBlbHNlIHQgKz0gcy5zbGljZShpLCBqKTtcbiAgICAgIGlmIChqID09IGwpIGJyZWFrO1xuICAgICAgaSA9IGo7XG4gICAgfVxuICAgIHYgPSAxO1xuICAgIGlmICgoKytpIDwgbCkgJiYgKCgoYzIgPSBzLmNoYXJDb2RlQXQoaSkpICYgLTY0KSA9PSAxMjgpKSB7XG4gICAgICBjID0gYzIgKyAoYzEgPDwgNik7XG4gICAgICBpZiAoYzEgPCAweGUwKSB7XG4gICAgICAgIHYgPSBjIC0gMHgzMDgwO1xuICAgICAgICBpZiAodiA8IDB4ODApIHYgPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdiA9IDI7XG4gICAgICAgIGlmICgoKytpIDwgbCkgJiYgKCgoYzIgPSBzLmNoYXJDb2RlQXQoaSkpICYgLTY0KSA9PSAxMjgpKSB7XG4gICAgICAgICAgYyA9IGMyICsgKGMgPDwgNik7XG4gICAgICAgICAgaWYgKGMxIDwgMHhmMCkge1xuICAgICAgICAgICAgdiA9IGMgLSAweGUyMDgwO1xuICAgICAgICAgICAgaWYgKCh2IDwgMHg4MDApIHx8ICgodiA+PSAweGQ3ZmYpICYmICh2IDwgMHhlMDAwKSkpIHYgPSAyO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2ID0gMztcbiAgICAgICAgICAgIGlmICgoKytpIDwgbCkgJiYgKCgoYzIgPSBzLmNoYXJDb2RlQXQoaSkpICYgLTY0KSA9PSAxMjgpICYmXG4gICAgICAgICAgICAgICAgKGMxIDwgMHhmNSkpIHtcbiAgICAgICAgICAgICAgdiA9IGMyIC0gMHgzYzgyMDgwICsgKGMgPDwgNik7XG4gICAgICAgICAgICAgIGlmICh2IDwgMHgxMDAwMCB8fCB2ID4gMHgxMGZmZmYpIHYgPSAzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAodiA8IDQpIHsgLy8gSW52YWxpZCBzZXF1ZW5jZVxuICAgICAgaSAtPSB2O1xuICAgICAgdCArPSBcIlxcdWZmZmRcIjtcbiAgICB9IGVsc2UgaWYgKHYgPiAweGZmZmYpXG4gICAgICB0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHhkN2MwICsgKHYgPj4gMTApLCAweGRjMDAgKyAodiAmIDB4M0ZGKSlcbiAgICBlbHNlXG4gICAgICB0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodik7XG4gICAgaWYgKHQubGVuZ3RoID4gMTAyNCkge3Quc3Vic3RyKDAsIDEpOyBiICs9IHQ7IHQgPSBcIlwiO31cbiAgfVxuICByZXR1cm4gYit0O1xufVxuXG4vL1Byb3ZpZGVzOiBqc29vX2lzX2FzY2lpXG5mdW5jdGlvbiBqc29vX2lzX2FzY2lpIChzKSB7XG4gIC8vIFRoZSByZWd1bGFyIGV4cHJlc3Npb24gZ2V0cyBiZXR0ZXIgYXQgYXJvdW5kIHRoaXMgcG9pbnQgZm9yIGFsbCBicm93c2Vyc1xuICBpZiAocy5sZW5ndGggPCAyNCkge1xuICAgIC8vIFNwaWRlcm1vbmtleSBnZXRzIG11Y2ggc2xvd2VyIHdoZW4gcy5sZW5ndGggPj0gMjQgKG9uIDY0IGJpdCBhcmNocylcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHMubGVuZ3RoOyBpKyspIGlmIChzLmNoYXJDb2RlQXQoaSkgPiAxMjcpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlXG4gICAgcmV0dXJuICEvW15cXHgwMC1cXHg3Zl0vLnRlc3Qocyk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfYnl0ZXNfdW5zYWZlX2dldCBtdXRhYmxlXG5mdW5jdGlvbiBjYW1sX2J5dGVzX3Vuc2FmZV9nZXQgKHMsIGkpIHtcbiAgc3dpdGNoIChzLnQgJiA2KSB7XG4gIGRlZmF1bHQ6IC8qIFBBUlRJQUwgKi9cbiAgICBpZiAoaSA+PSBzLmMubGVuZ3RoKSByZXR1cm4gMDtcbiAgY2FzZSAwOiAvKiBCWVRFUyAqL1xuICAgIHJldHVybiBzLmMuY2hhckNvZGVBdChpKTtcbiAgY2FzZSA0OiAvKiBBUlJBWSAqL1xuICAgIHJldHVybiBzLmNbaV1cbiAgfVxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2J5dGVzX3Vuc2FmZV9zZXRcbi8vUmVxdWlyZXM6IGNhbWxfY29udmVydF9ieXRlc190b19hcnJheVxuZnVuY3Rpb24gY2FtbF9ieXRlc191bnNhZmVfc2V0IChzLCBpLCBjKSB7XG4gIC8vIFRoZSBPQ2FtbCBjb21waWxlciB1c2VzIENoYXIudW5zYWZlX2NociBvbiBpbnRlZ2VycyBsYXJnZXIgdGhhbiAyNTUhXG4gIGMgJj0gMHhmZjtcbiAgaWYgKHMudCAhPSA0IC8qIEFSUkFZICovKSB7XG4gICAgaWYgKGkgPT0gcy5jLmxlbmd0aCkge1xuICAgICAgcy5jICs9IFN0cmluZy5mcm9tQ2hhckNvZGUgKGMpO1xuICAgICAgaWYgKGkgKyAxID09IHMubCkgcy50ID0gMDsgLypCWVRFUyB8IFVOS09XTiovXG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgY2FtbF9jb252ZXJ0X2J5dGVzX3RvX2FycmF5IChzKTtcbiAgfVxuICBzLmNbaV0gPSBjO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zdHJpbmdfYm91bmRfZXJyb3Jcbi8vUmVxdWlyZXM6IGNhbWxfaW52YWxpZF9hcmd1bWVudFxuZnVuY3Rpb24gY2FtbF9zdHJpbmdfYm91bmRfZXJyb3IgKCkge1xuICBjYW1sX2ludmFsaWRfYXJndW1lbnQgKFwiaW5kZXggb3V0IG9mIGJvdW5kc1wiKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9ieXRlc19ib3VuZF9lcnJvclxuLy9SZXF1aXJlczogY2FtbF9pbnZhbGlkX2FyZ3VtZW50XG5mdW5jdGlvbiBjYW1sX2J5dGVzX2JvdW5kX2Vycm9yICgpIHtcbiAgY2FtbF9pbnZhbGlkX2FyZ3VtZW50IChcImluZGV4IG91dCBvZiBib3VuZHNcIik7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3RyaW5nX2dldFxuLy9SZXF1aXJlczogY2FtbF9zdHJpbmdfYm91bmRfZXJyb3IsIGNhbWxfc3RyaW5nX3Vuc2FmZV9nZXRcbi8vUmVxdWlyZXM6IGNhbWxfbWxfc3RyaW5nX2xlbmd0aFxuZnVuY3Rpb24gY2FtbF9zdHJpbmdfZ2V0IChzLCBpKSB7XG4gIGlmIChpID4+PiAwID49IGNhbWxfbWxfc3RyaW5nX2xlbmd0aChzKSkgY2FtbF9zdHJpbmdfYm91bmRfZXJyb3IoKTtcbiAgcmV0dXJuIGNhbWxfc3RyaW5nX3Vuc2FmZV9nZXQgKHMsIGkpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N0cmluZ19nZXQxNlxuLy9SZXF1aXJlczogY2FtbF9zdHJpbmdfdW5zYWZlX2dldCwgY2FtbF9zdHJpbmdfYm91bmRfZXJyb3Jcbi8vUmVxdWlyZXM6IGNhbWxfbWxfc3RyaW5nX2xlbmd0aFxuZnVuY3Rpb24gY2FtbF9zdHJpbmdfZ2V0MTYocyxpKSB7XG4gIGlmIChpID4+PiAwID49IGNhbWxfbWxfc3RyaW5nX2xlbmd0aChzKSAtIDEpIGNhbWxfc3RyaW5nX2JvdW5kX2Vycm9yKCk7XG4gIHZhciBiMSA9IGNhbWxfc3RyaW5nX3Vuc2FmZV9nZXQgKHMsIGkpLFxuICAgICAgYjIgPSBjYW1sX3N0cmluZ191bnNhZmVfZ2V0IChzLCBpICsgMSk7XG4gIHJldHVybiAoYjIgPDwgOCB8IGIxKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9ieXRlc19nZXQxNlxuLy9SZXF1aXJlczogY2FtbF9ieXRlc191bnNhZmVfZ2V0LCBjYW1sX2J5dGVzX2JvdW5kX2Vycm9yXG5mdW5jdGlvbiBjYW1sX2J5dGVzX2dldDE2KHMsaSkge1xuICBpZiAoaSA+Pj4gMCA+PSBzLmwgLSAxKSBjYW1sX2J5dGVzX2JvdW5kX2Vycm9yKCk7XG4gIHZhciBiMSA9IGNhbWxfYnl0ZXNfdW5zYWZlX2dldCAocywgaSksXG4gICAgICBiMiA9IGNhbWxfYnl0ZXNfdW5zYWZlX2dldCAocywgaSArIDEpO1xuICByZXR1cm4gKGIyIDw8IDggfCBiMSk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3RyaW5nX2dldDMyXG4vL1JlcXVpcmVzOiBjYW1sX3N0cmluZ191bnNhZmVfZ2V0LCBjYW1sX3N0cmluZ19ib3VuZF9lcnJvclxuLy9SZXF1aXJlczogY2FtbF9tbF9zdHJpbmdfbGVuZ3RoXG5mdW5jdGlvbiBjYW1sX3N0cmluZ19nZXQzMihzLGkpIHtcbiAgaWYgKGkgPj4+IDAgPj0gY2FtbF9tbF9zdHJpbmdfbGVuZ3RoKHMpIC0gMykgY2FtbF9zdHJpbmdfYm91bmRfZXJyb3IoKTtcbiAgdmFyIGIxID0gY2FtbF9zdHJpbmdfdW5zYWZlX2dldCAocywgaSksXG4gICAgICBiMiA9IGNhbWxfc3RyaW5nX3Vuc2FmZV9nZXQgKHMsIGkgKyAxKSxcbiAgICAgIGIzID0gY2FtbF9zdHJpbmdfdW5zYWZlX2dldCAocywgaSArIDIpLFxuICAgICAgYjQgPSBjYW1sX3N0cmluZ191bnNhZmVfZ2V0IChzLCBpICsgMyk7XG4gIHJldHVybiAoYjQgPDwgMjQgfCBiMyA8PCAxNiB8IGIyIDw8IDggfCBiMSk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfYnl0ZXNfZ2V0MzJcbi8vUmVxdWlyZXM6IGNhbWxfYnl0ZXNfdW5zYWZlX2dldCwgY2FtbF9ieXRlc19ib3VuZF9lcnJvclxuZnVuY3Rpb24gY2FtbF9ieXRlc19nZXQzMihzLGkpIHtcbiAgaWYgKGkgPj4+IDAgPj0gcy5sIC0gMykgY2FtbF9ieXRlc19ib3VuZF9lcnJvcigpO1xuICB2YXIgYjEgPSBjYW1sX2J5dGVzX3Vuc2FmZV9nZXQgKHMsIGkpLFxuICAgICAgYjIgPSBjYW1sX2J5dGVzX3Vuc2FmZV9nZXQgKHMsIGkgKyAxKSxcbiAgICAgIGIzID0gY2FtbF9ieXRlc191bnNhZmVfZ2V0IChzLCBpICsgMiksXG4gICAgICBiNCA9IGNhbWxfYnl0ZXNfdW5zYWZlX2dldCAocywgaSArIDMpO1xuICByZXR1cm4gKGI0IDw8IDI0IHwgYjMgPDwgMTYgfCBiMiA8PCA4IHwgYjEpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N0cmluZ19nZXQ2NFxuLy9SZXF1aXJlczogY2FtbF9zdHJpbmdfdW5zYWZlX2dldCwgY2FtbF9zdHJpbmdfYm91bmRfZXJyb3Jcbi8vUmVxdWlyZXM6IGNhbWxfaW50NjRfb2ZfYnl0ZXNcbi8vUmVxdWlyZXM6IGNhbWxfbWxfc3RyaW5nX2xlbmd0aFxuZnVuY3Rpb24gY2FtbF9zdHJpbmdfZ2V0NjQocyxpKSB7XG4gIGlmIChpID4+PiAwID49IGNhbWxfbWxfc3RyaW5nX2xlbmd0aChzKSAtIDcpIGNhbWxfc3RyaW5nX2JvdW5kX2Vycm9yKCk7XG4gIHZhciBhID0gbmV3IEFycmF5KDgpO1xuICBmb3IodmFyIGogPSAwOyBqIDwgODsgaisrKXtcbiAgICBhWzcgLSBqXSA9IGNhbWxfc3RyaW5nX3Vuc2FmZV9nZXQgKHMsIGkgKyBqKTtcbiAgfVxuICByZXR1cm4gY2FtbF9pbnQ2NF9vZl9ieXRlcyhhKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9ieXRlc19nZXQ2NFxuLy9SZXF1aXJlczogY2FtbF9ieXRlc191bnNhZmVfZ2V0LCBjYW1sX2J5dGVzX2JvdW5kX2Vycm9yXG4vL1JlcXVpcmVzOiBjYW1sX2ludDY0X29mX2J5dGVzXG5mdW5jdGlvbiBjYW1sX2J5dGVzX2dldDY0KHMsaSkge1xuICBpZiAoaSA+Pj4gMCA+PSBzLmwgLSA3KSBjYW1sX2J5dGVzX2JvdW5kX2Vycm9yKCk7XG4gIHZhciBhID0gbmV3IEFycmF5KDgpO1xuICBmb3IodmFyIGogPSAwOyBqIDwgODsgaisrKXtcbiAgICBhWzcgLSBqXSA9IGNhbWxfYnl0ZXNfdW5zYWZlX2dldCAocywgaSArIGopO1xuICB9XG4gIHJldHVybiBjYW1sX2ludDY0X29mX2J5dGVzKGEpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2J5dGVzX2dldFxuLy9SZXF1aXJlczogY2FtbF9ieXRlc19ib3VuZF9lcnJvciwgY2FtbF9ieXRlc191bnNhZmVfZ2V0XG5mdW5jdGlvbiBjYW1sX2J5dGVzX2dldCAocywgaSkge1xuICBpZiAoaSA+Pj4gMCA+PSBzLmwpIGNhbWxfYnl0ZXNfYm91bmRfZXJyb3IoKTtcbiAgcmV0dXJuIGNhbWxfYnl0ZXNfdW5zYWZlX2dldCAocywgaSk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3RyaW5nX3NldFxuLy9SZXF1aXJlczogY2FtbF9mYWlsd2l0aFxuLy9JZjoganMtc3RyaW5nXG5mdW5jdGlvbiBjYW1sX3N0cmluZ19zZXQgKHMsIGksIGMpIHtcbiAgY2FtbF9mYWlsd2l0aChcImNhbWxfc3RyaW5nX3NldFwiKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zdHJpbmdfc2V0XG4vL1JlcXVpcmVzOiBjYW1sX3N0cmluZ191bnNhZmVfc2V0LCBjYW1sX3N0cmluZ19ib3VuZF9lcnJvclxuLy9JZjogIWpzLXN0cmluZ1xuZnVuY3Rpb24gY2FtbF9zdHJpbmdfc2V0IChzLCBpLCBjKSB7XG4gIGlmIChpID4+PiAwID49IHMubCkgY2FtbF9zdHJpbmdfYm91bmRfZXJyb3IoKTtcbiAgcmV0dXJuIGNhbWxfc3RyaW5nX3Vuc2FmZV9zZXQgKHMsIGksIGMpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2J5dGVzX3NldDE2XG4vL1JlcXVpcmVzOiBjYW1sX2J5dGVzX2JvdW5kX2Vycm9yLCBjYW1sX2J5dGVzX3Vuc2FmZV9zZXRcbmZ1bmN0aW9uIGNhbWxfYnl0ZXNfc2V0MTYocyxpLGkxNil7XG4gIGlmIChpID4+PiAwID49IHMubCAtIDEpIGNhbWxfYnl0ZXNfYm91bmRfZXJyb3IoKTtcbiAgdmFyIGIyID0gMHhGRiAmIGkxNiA+PiA4LFxuICAgICAgYjEgPSAweEZGICYgaTE2O1xuICBjYW1sX2J5dGVzX3Vuc2FmZV9zZXQgKHMsIGkgKyAwLCBiMSk7XG4gIGNhbWxfYnl0ZXNfdW5zYWZlX3NldCAocywgaSArIDEsIGIyKTtcbiAgcmV0dXJuIDBcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zdHJpbmdfc2V0MTZcbi8vUmVxdWlyZXM6IGNhbWxfZmFpbHdpdGhcbi8vSWY6IGpzLXN0cmluZ1xuZnVuY3Rpb24gY2FtbF9zdHJpbmdfc2V0MTYocyxpLGkxNil7XG4gIGNhbWxfZmFpbHdpdGgoXCJjYW1sX3N0cmluZ19zZXQxNlwiKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zdHJpbmdfc2V0MTZcbi8vUmVxdWlyZXM6IGNhbWxfYnl0ZXNfc2V0MTZcbi8vSWY6ICFqcy1zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfc3RyaW5nX3NldDE2KHMsaSxpMTYpe1xuICByZXR1cm4gY2FtbF9ieXRlc19zZXQxNihzLGksaTE2KTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9ieXRlc19zZXQzMlxuLy9SZXF1aXJlczogY2FtbF9ieXRlc19ib3VuZF9lcnJvciwgY2FtbF9ieXRlc191bnNhZmVfc2V0XG5mdW5jdGlvbiBjYW1sX2J5dGVzX3NldDMyKHMsaSxpMzIpe1xuICBpZiAoaSA+Pj4gMCA+PSBzLmwgLSAzKSBjYW1sX2J5dGVzX2JvdW5kX2Vycm9yKCk7XG4gIHZhciBiNCA9IDB4RkYgJiBpMzIgPj4gMjQsXG4gICAgICBiMyA9IDB4RkYgJiBpMzIgPj4gMTYsXG4gICAgICBiMiA9IDB4RkYgJiBpMzIgPj4gOCxcbiAgICAgIGIxID0gMHhGRiAmIGkzMjtcbiAgY2FtbF9ieXRlc191bnNhZmVfc2V0IChzLCBpICsgMCwgYjEpO1xuICBjYW1sX2J5dGVzX3Vuc2FmZV9zZXQgKHMsIGkgKyAxLCBiMik7XG4gIGNhbWxfYnl0ZXNfdW5zYWZlX3NldCAocywgaSArIDIsIGIzKTtcbiAgY2FtbF9ieXRlc191bnNhZmVfc2V0IChzLCBpICsgMywgYjQpO1xuICByZXR1cm4gMFxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N0cmluZ19zZXQzMlxuLy9SZXF1aXJlczogY2FtbF9mYWlsd2l0aFxuLy9JZjoganMtc3RyaW5nXG5mdW5jdGlvbiBjYW1sX3N0cmluZ19zZXQzMihzLGksaTMyKXtcbiAgY2FtbF9mYWlsd2l0aChcImNhbWxfc3RyaW5nX3NldDMyXCIpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N0cmluZ19zZXQzMlxuLy9SZXF1aXJlczogY2FtbF9ieXRlc19zZXQzMlxuLy9JZjogIWpzLXN0cmluZ1xuZnVuY3Rpb24gY2FtbF9zdHJpbmdfc2V0MzIocyxpLGkzMil7XG4gIHJldHVybiBjYW1sX2J5dGVzX3NldDMyKHMsaSxpMzIpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2J5dGVzX3NldDY0XG4vL1JlcXVpcmVzOiBjYW1sX2J5dGVzX2JvdW5kX2Vycm9yLCBjYW1sX2J5dGVzX3Vuc2FmZV9zZXRcbi8vUmVxdWlyZXM6IGNhbWxfaW50NjRfdG9fYnl0ZXNcbmZ1bmN0aW9uIGNhbWxfYnl0ZXNfc2V0NjQocyxpLGk2NCl7XG4gIGlmIChpID4+PiAwID49IHMubCAtIDcpIGNhbWxfYnl0ZXNfYm91bmRfZXJyb3IoKTtcbiAgdmFyIGEgPSBjYW1sX2ludDY0X3RvX2J5dGVzKGk2NCk7XG4gIGZvcih2YXIgaiA9IDA7IGogPCA4OyBqKyspIHtcbiAgICBjYW1sX2J5dGVzX3Vuc2FmZV9zZXQgKHMsIGkgKyA3IC0gaiwgYVtqXSk7XG4gIH1cbiAgcmV0dXJuIDBcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zdHJpbmdfc2V0NjRcbi8vUmVxdWlyZXM6IGNhbWxfZmFpbHdpdGhcbi8vSWY6IGpzLXN0cmluZ1xuZnVuY3Rpb24gY2FtbF9zdHJpbmdfc2V0NjQocyxpLGk2NCl7XG4gIGNhbWxfZmFpbHdpdGgoXCJjYW1sX3N0cmluZ19zZXQ2NFwiKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zdHJpbmdfc2V0NjRcbi8vUmVxdWlyZXM6IGNhbWxfYnl0ZXNfc2V0NjRcbi8vSWY6ICFqcy1zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfc3RyaW5nX3NldDY0KHMsaSxpNjQpe1xuICByZXR1cm4gY2FtbF9ieXRlc19zZXQ2NChzLGksaTY0KTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9ieXRlc19zZXRcbi8vUmVxdWlyZXM6IGNhbWxfYnl0ZXNfYm91bmRfZXJyb3IsIGNhbWxfYnl0ZXNfdW5zYWZlX3NldFxuZnVuY3Rpb24gY2FtbF9ieXRlc19zZXQgKHMsIGksIGMpIHtcbiAgaWYgKGkgPj4+IDAgPj0gcy5sKSBjYW1sX2J5dGVzX2JvdW5kX2Vycm9yKCk7XG4gIHJldHVybiBjYW1sX2J5dGVzX3Vuc2FmZV9zZXQgKHMsIGksIGMpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2J5dGVzX29mX3V0ZjE2X2pzc3RyaW5nXG4vL1JlcXVpcmVzOiBqc29vX2lzX2FzY2lpLCBjYW1sX3V0Zjhfb2ZfdXRmMTYsIE1sQnl0ZXNcbmZ1bmN0aW9uIGNhbWxfYnl0ZXNfb2ZfdXRmMTZfanNzdHJpbmcgKHMpIHtcbiAgdmFyIHRhZyA9IDkgLyogQllURVMgfCBBU0NJSSAqLztcbiAgaWYgKCFqc29vX2lzX2FzY2lpKHMpKVxuICAgIHRhZyA9IDggLyogQllURVMgfCBOT1RfQVNDSUkgKi8sIHMgPSBjYW1sX3V0Zjhfb2ZfdXRmMTYocyk7XG4gIHJldHVybiBuZXcgTWxCeXRlcyh0YWcsIHMsIHMubGVuZ3RoKTtcbn1cblxuXG4vL1Byb3ZpZGVzOiBNbEJ5dGVzXG4vL1JlcXVpcmVzOiBjYW1sX2NvbnZlcnRfc3RyaW5nX3RvX2J5dGVzLCBqc29vX2lzX2FzY2lpLCBjYW1sX3V0ZjE2X29mX3V0ZjhcbmZ1bmN0aW9uIE1sQnl0ZXMgKHRhZywgY29udGVudHMsIGxlbmd0aCkge1xuICB0aGlzLnQ9dGFnOyB0aGlzLmM9Y29udGVudHM7IHRoaXMubD1sZW5ndGg7XG59XG5NbEJ5dGVzLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKCl7XG4gIHN3aXRjaCAodGhpcy50KSB7XG4gIGNhc2UgOTogLypCWVRFUyB8IEFTQ0lJKi9cbiAgICByZXR1cm4gdGhpcy5jO1xuICBkZWZhdWx0OlxuICAgIGNhbWxfY29udmVydF9zdHJpbmdfdG9fYnl0ZXModGhpcyk7XG4gIGNhc2UgMDogLypCWVRFUyB8IFVOS09XTiovXG4gICAgaWYgKGpzb29faXNfYXNjaWkodGhpcy5jKSkge1xuICAgICAgdGhpcy50ID0gOTsgLypCWVRFUyB8IEFTQ0lJKi9cbiAgICAgIHJldHVybiB0aGlzLmM7XG4gICAgfVxuICAgIHRoaXMudCA9IDg7IC8qQllURVMgfCBOT1RfQVNDSUkqL1xuICBjYXNlIDg6IC8qQllURVMgfCBOT1RfQVNDSUkqL1xuICAgIHJldHVybiB0aGlzLmM7XG4gIH1cbn07XG5NbEJ5dGVzLnByb3RvdHlwZS50b1V0ZjE2ID0gZnVuY3Rpb24gKCl7XG4gIHZhciByID0gdGhpcy50b1N0cmluZygpO1xuICBpZih0aGlzLnQgPT0gOSkgcmV0dXJuIHJcbiAgcmV0dXJuIGNhbWxfdXRmMTZfb2ZfdXRmOChyKTtcbn1cbk1sQnl0ZXMucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24gKCl7XG4gIHZhciBjb250ZW50ID0gdGhpcy50ID09IDQgPyB0aGlzLmMuc2xpY2UoKSA6IHRoaXMuYztcbiAgcmV0dXJuIG5ldyBNbEJ5dGVzKHRoaXMudCxjb250ZW50LHRoaXMubCk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfY29udmVydF9zdHJpbmdfdG9fYnl0ZXNcbi8vUmVxdWlyZXM6IGNhbWxfc3RyX3JlcGVhdCwgY2FtbF9zdWJhcnJheV90b19qc2J5dGVzXG5mdW5jdGlvbiBjYW1sX2NvbnZlcnRfc3RyaW5nX3RvX2J5dGVzIChzKSB7XG4gIC8qIEFzc3VtZXMgbm90IEJZVEVTICovXG4gIGlmIChzLnQgPT0gMiAvKiBQQVJUSUFMICovKVxuICAgIHMuYyArPSBjYW1sX3N0cl9yZXBlYXQocy5sIC0gcy5jLmxlbmd0aCwgJ1xcMCcpXG4gIGVsc2VcbiAgICBzLmMgPSBjYW1sX3N1YmFycmF5X3RvX2pzYnl0ZXMgKHMuYywgMCwgcy5jLmxlbmd0aCk7XG4gIHMudCA9IDA7IC8qQllURVMgfCBVTktPV04qL1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2NvbnZlcnRfYnl0ZXNfdG9fYXJyYXlcbmZ1bmN0aW9uIGNhbWxfY29udmVydF9ieXRlc190b19hcnJheSAocykge1xuICAvKiBBc3N1bWVzIG5vdCBBUlJBWSAqL1xuICB2YXIgYSA9IG5ldyBVaW50OEFycmF5KHMubCk7XG4gIHZhciBiID0gcy5jLCBsID0gYi5sZW5ndGgsIGkgPSAwO1xuICBmb3IgKDsgaSA8IGw7IGkrKykgYVtpXSA9IGIuY2hhckNvZGVBdChpKTtcbiAgZm9yIChsID0gcy5sOyBpIDwgbDsgaSsrKSBhW2ldID0gMDtcbiAgcy5jID0gYTtcbiAgcy50ID0gNDsgLyogQVJSQVkgKi9cbiAgcmV0dXJuIGE7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfdWludDhfYXJyYXlfb2ZfYnl0ZXMgbXV0YWJsZVxuLy9SZXF1aXJlczogY2FtbF9jb252ZXJ0X2J5dGVzX3RvX2FycmF5XG5mdW5jdGlvbiBjYW1sX3VpbnQ4X2FycmF5X29mX2J5dGVzIChzKSB7XG4gIGlmIChzLnQgIT0gNCAvKiBBUlJBWSAqLykgY2FtbF9jb252ZXJ0X2J5dGVzX3RvX2FycmF5KHMpO1xuICByZXR1cm4gcy5jO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3VpbnQ4X2FycmF5X29mX3N0cmluZyBtdXRhYmxlXG4vL1JlcXVpcmVzOiBjYW1sX2NvbnZlcnRfYnl0ZXNfdG9fYXJyYXlcbi8vUmVxdWlyZXM6IGNhbWxfbWxfc3RyaW5nX2xlbmd0aCwgY2FtbF9zdHJpbmdfdW5zYWZlX2dldFxuZnVuY3Rpb24gY2FtbF91aW50OF9hcnJheV9vZl9zdHJpbmcgKHMpIHtcbiAgdmFyIGwgPSBjYW1sX21sX3N0cmluZ19sZW5ndGgocyk7XG4gIHZhciBhID0gbmV3IFVpbnQ4QXJyYXkobCk7XG4gIHZhciBpID0gMDtcbiAgZm9yICg7IGkgPCBsOyBpKyspIGFbaV0gPSBjYW1sX3N0cmluZ191bnNhZmVfZ2V0KHMsaSk7XG4gIHJldHVybiBhO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2NyZWF0ZV9zdHJpbmcgY29uc3Rcbi8vUmVxdWlyZXM6IE1sQnl0ZXMsIGNhbWxfaW52YWxpZF9hcmd1bWVudFxuLy9JZjogIWpzLXN0cmluZ1xuZnVuY3Rpb24gY2FtbF9jcmVhdGVfc3RyaW5nKGxlbikge1xuICBpZihsZW4gPCAwKSBjYW1sX2ludmFsaWRfYXJndW1lbnQoXCJTdHJpbmcuY3JlYXRlXCIpO1xuICByZXR1cm4gbmV3IE1sQnl0ZXMobGVuPzI6OSxcIlwiLGxlbik7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfY3JlYXRlX3N0cmluZyBjb25zdFxuLy9SZXF1aXJlczogY2FtbF9pbnZhbGlkX2FyZ3VtZW50XG4vL0lmOiBqcy1zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfY3JlYXRlX3N0cmluZyhsZW4pIHtcbiAgY2FtbF9pbnZhbGlkX2FyZ3VtZW50KFwiU3RyaW5nLmNyZWF0ZVwiKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9jcmVhdGVfYnl0ZXMgY29uc3Rcbi8vUmVxdWlyZXM6IE1sQnl0ZXMsY2FtbF9pbnZhbGlkX2FyZ3VtZW50XG5mdW5jdGlvbiBjYW1sX2NyZWF0ZV9ieXRlcyhsZW4pIHtcbiAgaWYgKGxlbiA8IDApIGNhbWxfaW52YWxpZF9hcmd1bWVudChcIkJ5dGVzLmNyZWF0ZVwiKTtcbiAgcmV0dXJuIG5ldyBNbEJ5dGVzKGxlbj8yOjksXCJcIixsZW4pO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N0cmluZ19vZl9hcnJheVxuLy9SZXF1aXJlczogY2FtbF9zdWJhcnJheV90b19qc2J5dGVzLCBjYW1sX3N0cmluZ19vZl9qc2J5dGVzXG5mdW5jdGlvbiBjYW1sX3N0cmluZ19vZl9hcnJheSAoYSkge1xuICByZXR1cm4gY2FtbF9zdHJpbmdfb2ZfanNieXRlcyhjYW1sX3N1YmFycmF5X3RvX2pzYnl0ZXMoYSwwLGEubGVuZ3RoKSk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfYnl0ZXNfb2ZfYXJyYXlcbi8vUmVxdWlyZXM6IE1sQnl0ZXNcbmZ1bmN0aW9uIGNhbWxfYnl0ZXNfb2ZfYXJyYXkgKGEpIHtcbiAgaWYoISAoYSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpKSB7XG4gICAgYSA9IG5ldyBVaW50OEFycmF5KGEpO1xuICB9XG4gIHJldHVybiBuZXcgTWxCeXRlcyg0LGEsYS5sZW5ndGgpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2J5dGVzX2NvbXBhcmUgbXV0YWJsZVxuLy9SZXF1aXJlczogY2FtbF9jb252ZXJ0X3N0cmluZ190b19ieXRlc1xuZnVuY3Rpb24gY2FtbF9ieXRlc19jb21wYXJlKHMxLCBzMikge1xuICAoczEudCAmIDYpICYmIGNhbWxfY29udmVydF9zdHJpbmdfdG9fYnl0ZXMoczEpO1xuICAoczIudCAmIDYpICYmIGNhbWxfY29udmVydF9zdHJpbmdfdG9fYnl0ZXMoczIpO1xuICByZXR1cm4gKHMxLmMgPCBzMi5jKT8tMTooczEuYyA+IHMyLmMpPzE6MDtcbn1cblxuXG4vL1Byb3ZpZGVzOiBjYW1sX2J5dGVzX2VxdWFsIG11dGFibGUgKGNvbnN0LCBjb25zdClcbi8vUmVxdWlyZXM6IGNhbWxfY29udmVydF9zdHJpbmdfdG9fYnl0ZXNcbmZ1bmN0aW9uIGNhbWxfYnl0ZXNfZXF1YWwoczEsIHMyKSB7XG4gIGlmKHMxID09PSBzMikgcmV0dXJuIDE7XG4gIChzMS50ICYgNikgJiYgY2FtbF9jb252ZXJ0X3N0cmluZ190b19ieXRlcyhzMSk7XG4gIChzMi50ICYgNikgJiYgY2FtbF9jb252ZXJ0X3N0cmluZ190b19ieXRlcyhzMik7XG4gIHJldHVybiAoczEuYyA9PSBzMi5jKT8xOjA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3RyaW5nX25vdGVxdWFsIG11dGFibGUgKGNvbnN0LCBjb25zdClcbi8vUmVxdWlyZXM6IGNhbWxfc3RyaW5nX2VxdWFsXG5mdW5jdGlvbiBjYW1sX3N0cmluZ19ub3RlcXVhbChzMSwgczIpIHsgcmV0dXJuIDEtY2FtbF9zdHJpbmdfZXF1YWwoczEsIHMyKTsgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2J5dGVzX25vdGVxdWFsIG11dGFibGUgKGNvbnN0LCBjb25zdClcbi8vUmVxdWlyZXM6IGNhbWxfYnl0ZXNfZXF1YWxcbmZ1bmN0aW9uIGNhbWxfYnl0ZXNfbm90ZXF1YWwoczEsIHMyKSB7IHJldHVybiAxLWNhbWxfYnl0ZXNfZXF1YWwoczEsIHMyKTsgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2J5dGVzX2xlc3NlcXVhbCBtdXRhYmxlXG4vL1JlcXVpcmVzOiBjYW1sX2NvbnZlcnRfc3RyaW5nX3RvX2J5dGVzXG5mdW5jdGlvbiBjYW1sX2J5dGVzX2xlc3NlcXVhbChzMSwgczIpIHtcbiAgKHMxLnQgJiA2KSAmJiBjYW1sX2NvbnZlcnRfc3RyaW5nX3RvX2J5dGVzKHMxKTtcbiAgKHMyLnQgJiA2KSAmJiBjYW1sX2NvbnZlcnRfc3RyaW5nX3RvX2J5dGVzKHMyKTtcbiAgcmV0dXJuIChzMS5jIDw9IHMyLmMpPzE6MDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9ieXRlc19sZXNzdGhhbiBtdXRhYmxlXG4vL1JlcXVpcmVzOiBjYW1sX2NvbnZlcnRfc3RyaW5nX3RvX2J5dGVzXG5mdW5jdGlvbiBjYW1sX2J5dGVzX2xlc3N0aGFuKHMxLCBzMikge1xuICAoczEudCAmIDYpICYmIGNhbWxfY29udmVydF9zdHJpbmdfdG9fYnl0ZXMoczEpO1xuICAoczIudCAmIDYpICYmIGNhbWxfY29udmVydF9zdHJpbmdfdG9fYnl0ZXMoczIpO1xuICByZXR1cm4gKHMxLmMgPCBzMi5jKT8xOjA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3RyaW5nX2dyZWF0ZXJlcXVhbFxuLy9SZXF1aXJlczogY2FtbF9zdHJpbmdfbGVzc2VxdWFsXG5mdW5jdGlvbiBjYW1sX3N0cmluZ19ncmVhdGVyZXF1YWwoczEsIHMyKSB7XG4gIHJldHVybiBjYW1sX3N0cmluZ19sZXNzZXF1YWwoczIsczEpO1xufVxuLy9Qcm92aWRlczogY2FtbF9ieXRlc19ncmVhdGVyZXF1YWxcbi8vUmVxdWlyZXM6IGNhbWxfYnl0ZXNfbGVzc2VxdWFsXG5mdW5jdGlvbiBjYW1sX2J5dGVzX2dyZWF0ZXJlcXVhbChzMSwgczIpIHtcbiAgcmV0dXJuIGNhbWxfYnl0ZXNfbGVzc2VxdWFsKHMyLHMxKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zdHJpbmdfZ3JlYXRlcnRoYW5cbi8vUmVxdWlyZXM6IGNhbWxfc3RyaW5nX2xlc3N0aGFuXG5mdW5jdGlvbiBjYW1sX3N0cmluZ19ncmVhdGVydGhhbihzMSwgczIpIHtcbiAgcmV0dXJuIGNhbWxfc3RyaW5nX2xlc3N0aGFuKHMyLCBzMSk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfYnl0ZXNfZ3JlYXRlcnRoYW5cbi8vUmVxdWlyZXM6IGNhbWxfYnl0ZXNfbGVzc3RoYW5cbmZ1bmN0aW9uIGNhbWxfYnl0ZXNfZ3JlYXRlcnRoYW4oczEsIHMyKSB7XG4gIHJldHVybiBjYW1sX2J5dGVzX2xlc3N0aGFuKHMyLCBzMSk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfZmlsbF9ieXRlc1xuLy9SZXF1aXJlczogY2FtbF9zdHJfcmVwZWF0LCBjYW1sX2NvbnZlcnRfYnl0ZXNfdG9fYXJyYXlcbi8vQWxpYXM6IGNhbWxfZmlsbF9zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfZmlsbF9ieXRlcyhzLCBpLCBsLCBjKSB7XG4gIGlmIChsID4gMCkge1xuICAgIGlmIChpID09IDAgJiYgKGwgPj0gcy5sIHx8IChzLnQgPT0gMiAvKiBQQVJUSUFMICovICYmIGwgPj0gcy5jLmxlbmd0aCkpKSB7XG4gICAgICBpZiAoYyA9PSAwKSB7XG4gICAgICAgIHMuYyA9IFwiXCI7XG4gICAgICAgIHMudCA9IDI7IC8qIFBBUlRJQUwgKi9cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHMuYyA9IGNhbWxfc3RyX3JlcGVhdCAobCwgU3RyaW5nLmZyb21DaGFyQ29kZShjKSk7XG4gICAgICAgIHMudCA9IChsID09IHMubCk/MCAvKiBCWVRFUyB8IFVOS09XTiAqLyA6MjsgLyogUEFSVElBTCAqL1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAocy50ICE9IDQgLyogQVJSQVkgKi8pIGNhbWxfY29udmVydF9ieXRlc190b19hcnJheShzKTtcbiAgICAgIGZvciAobCArPSBpOyBpIDwgbDsgaSsrKSBzLmNbaV0gPSBjO1xuICAgIH1cbiAgfVxuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9ibGl0X2J5dGVzXG4vL1JlcXVpcmVzOiBjYW1sX3N1YmFycmF5X3RvX2pzYnl0ZXMsIGNhbWxfY29udmVydF9ieXRlc190b19hcnJheVxuZnVuY3Rpb24gY2FtbF9ibGl0X2J5dGVzKHMxLCBpMSwgczIsIGkyLCBsZW4pIHtcbiAgaWYgKGxlbiA9PSAwKSByZXR1cm4gMDtcbiAgaWYgKChpMiA9PSAwKSAmJlxuICAgICAgKGxlbiA+PSBzMi5sIHx8IChzMi50ID09IDIgLyogUEFSVElBTCAqLyAmJiBsZW4gPj0gczIuYy5sZW5ndGgpKSkge1xuICAgIHMyLmMgPSAoczEudCA9PSA0IC8qIEFSUkFZICovKT9cbiAgICAgIGNhbWxfc3ViYXJyYXlfdG9fanNieXRlcyhzMS5jLCBpMSwgbGVuKTpcbiAgICAgIChpMSA9PSAwICYmIHMxLmMubGVuZ3RoID09IGxlbik/czEuYzpzMS5jLnN1YnN0cihpMSwgbGVuKTtcbiAgICBzMi50ID0gKHMyLmMubGVuZ3RoID09IHMyLmwpPzAgLyogQllURVMgfCBVTktPV04gKi8gOjI7IC8qIFBBUlRJQUwgKi9cbiAgfSBlbHNlIGlmIChzMi50ID09IDIgLyogUEFSVElBTCAqLyAmJiBpMiA9PSBzMi5jLmxlbmd0aCkge1xuICAgIHMyLmMgKz0gKHMxLnQgPT0gNCAvKiBBUlJBWSAqLyk/XG4gICAgICBjYW1sX3N1YmFycmF5X3RvX2pzYnl0ZXMoczEuYywgaTEsIGxlbik6XG4gICAgICAoaTEgPT0gMCAmJiBzMS5jLmxlbmd0aCA9PSBsZW4pP3MxLmM6czEuYy5zdWJzdHIoaTEsIGxlbik7XG4gICAgczIudCA9IChzMi5jLmxlbmd0aCA9PSBzMi5sKT8wIC8qIEJZVEVTIHwgVU5LT1dOICovIDoyOyAvKiBQQVJUSUFMICovXG4gIH0gZWxzZSB7XG4gICAgaWYgKHMyLnQgIT0gNCAvKiBBUlJBWSAqLykgY2FtbF9jb252ZXJ0X2J5dGVzX3RvX2FycmF5KHMyKTtcbiAgICB2YXIgYzEgPSBzMS5jLCBjMiA9IHMyLmM7XG4gICAgaWYgKHMxLnQgPT0gNCAvKiBBUlJBWSAqLykge1xuICAgICAgaWYgKGkyIDw9IGkxKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIGMyIFtpMiArIGldID0gYzEgW2kxICsgaV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKHZhciBpID0gbGVuIC0gMTsgaSA+PSAwOyBpLS0pIGMyIFtpMiArIGldID0gYzEgW2kxICsgaV07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBsID0gTWF0aC5taW4gKGxlbiwgYzEubGVuZ3RoIC0gaTEpO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsOyBpKyspIGMyIFtpMiArIGldID0gYzEuY2hhckNvZGVBdChpMSArIGkpO1xuICAgICAgZm9yICg7IGkgPCBsZW47IGkrKykgYzIgW2kyICsgaV0gPSAwO1xuICAgIH1cbiAgfVxuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9ibGl0X3N0cmluZ1xuLy9SZXF1aXJlczogY2FtbF9ibGl0X2J5dGVzLCBjYW1sX2J5dGVzX29mX3N0cmluZ1xuZnVuY3Rpb24gY2FtbF9ibGl0X3N0cmluZyhhLGIsYyxkLGUpIHtcbiAgY2FtbF9ibGl0X2J5dGVzKGNhbWxfYnl0ZXNfb2Zfc3RyaW5nKGEpLGIsYyxkLGUpO1xuICByZXR1cm4gMFxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21sX2J5dGVzX2xlbmd0aCBjb25zdFxuZnVuY3Rpb24gY2FtbF9tbF9ieXRlc19sZW5ndGgocykgeyByZXR1cm4gcy5sIH1cblxuLy9Qcm92aWRlczogY2FtbF9zdHJpbmdfY29uY2F0XG4vL0lmOiBqcy1zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfc3RyaW5nX2NvbmNhdChhLGIpIHsgcmV0dXJuIGEgKyBiIH1cblxuLy9Qcm92aWRlczogY2FtbF9zdHJpbmdfY29uY2F0XG4vL1JlcXVpcmVzOiBjYW1sX2NvbnZlcnRfc3RyaW5nX3RvX2J5dGVzLCBNbEJ5dGVzXG4vL0lmOiAhanMtc3RyaW5nXG5mdW5jdGlvbiBjYW1sX3N0cmluZ19jb25jYXQoczEsczIpe1xuICAoczEudCAmIDYpICYmIGNhbWxfY29udmVydF9zdHJpbmdfdG9fYnl0ZXMoczEpO1xuICAoczIudCAmIDYpICYmIGNhbWxfY29udmVydF9zdHJpbmdfdG9fYnl0ZXMoczIpO1xuICByZXR1cm4gbmV3IE1sQnl0ZXMoczEudCxzMS5jK3MyLmMsczEubCtzMi5sKVxufVxuXG5cbi8vUHJvdmlkZXM6IGNhbWxfc3RyaW5nX3Vuc2FmZV9nZXQgY29uc3Rcbi8vSWY6IGpzLXN0cmluZ1xuZnVuY3Rpb24gY2FtbF9zdHJpbmdfdW5zYWZlX2dldCAocywgaSkge1xuICByZXR1cm4gcy5jaGFyQ29kZUF0KGkpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N0cmluZ191bnNhZmVfc2V0XG4vL1JlcXVpcmVzOiBjYW1sX2ZhaWx3aXRoXG4vL0lmOiBqcy1zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfc3RyaW5nX3Vuc2FmZV9zZXQgKHMsIGksIGMpIHtcbiAgY2FtbF9mYWlsd2l0aChcImNhbWxfc3RyaW5nX3Vuc2FmZV9zZXRcIik7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfc3RyaW5nX2xlbmd0aCBjb25zdFxuLy9JZjoganMtc3RyaW5nXG5mdW5jdGlvbiBjYW1sX21sX3N0cmluZ19sZW5ndGgocykge1xuICByZXR1cm4gcy5sZW5ndGhcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zdHJpbmdfY29tcGFyZSBjb25zdFxuLy9JZjoganMtc3RyaW5nXG5mdW5jdGlvbiBjYW1sX3N0cmluZ19jb21wYXJlKHMxLCBzMikge1xuICByZXR1cm4gKHMxIDwgczIpPy0xOihzMSA+IHMyKT8xOjA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3RyaW5nX2VxdWFsIGNvbnN0XG4vL0lmOiBqcy1zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfc3RyaW5nX2VxdWFsKHMxLCBzMikge1xuICBpZihzMSA9PT0gczIpIHJldHVybiAxO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zdHJpbmdfbGVzc2VxdWFsIGNvbnN0XG4vL0lmOiBqcy1zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfc3RyaW5nX2xlc3NlcXVhbChzMSwgczIpIHtcbiAgcmV0dXJuIChzMSA8PSBzMik/MTowO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N0cmluZ19sZXNzdGhhbiBjb25zdFxuLy9JZjoganMtc3RyaW5nXG5mdW5jdGlvbiBjYW1sX3N0cmluZ19sZXNzdGhhbihzMSwgczIpIHtcbiAgcmV0dXJuIChzMSA8IHMyKT8xOjA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3RyaW5nX29mX2J5dGVzXG4vL1JlcXVpcmVzOiBjYW1sX2NvbnZlcnRfc3RyaW5nX3RvX2J5dGVzLCBjYW1sX3N0cmluZ19vZl9qc2J5dGVzXG4vL0lmOiBqcy1zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfc3RyaW5nX29mX2J5dGVzKHMpIHtcbiAgKHMudCAmIDYpICYmIGNhbWxfY29udmVydF9zdHJpbmdfdG9fYnl0ZXMocyk7XG4gIHJldHVybiBjYW1sX3N0cmluZ19vZl9qc2J5dGVzKHMuYyk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfYnl0ZXNfb2Zfc3RyaW5nIGNvbnN0XG4vL1JlcXVpcmVzOiBjYW1sX2J5dGVzX29mX2pzYnl0ZXMsIGNhbWxfanNieXRlc19vZl9zdHJpbmdcbi8vSWY6IGpzLXN0cmluZ1xuZnVuY3Rpb24gY2FtbF9ieXRlc19vZl9zdHJpbmcocykge1xuICByZXR1cm4gY2FtbF9ieXRlc19vZl9qc2J5dGVzKGNhbWxfanNieXRlc19vZl9zdHJpbmcocykpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N0cmluZ19vZl9qc2J5dGVzIGNvbnN0XG4vL0lmOiBqcy1zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfc3RyaW5nX29mX2pzYnl0ZXMoeCkgeyByZXR1cm4geCB9XG5cbi8vUHJvdmlkZXM6IGNhbWxfanNieXRlc19vZl9zdHJpbmcgY29uc3Rcbi8vSWY6IGpzLXN0cmluZ1xuZnVuY3Rpb24gY2FtbF9qc2J5dGVzX29mX3N0cmluZyh4KSB7IHJldHVybiB4IH1cblxuLy9Qcm92aWRlczogY2FtbF9qc3N0cmluZ19vZl9zdHJpbmcgY29uc3Rcbi8vUmVxdWlyZXM6IGpzb29faXNfYXNjaWksIGNhbWxfdXRmMTZfb2ZfdXRmOFxuLy9JZjoganMtc3RyaW5nXG5mdW5jdGlvbiBjYW1sX2pzc3RyaW5nX29mX3N0cmluZyhzKSB7XG4gIGlmKGpzb29faXNfYXNjaWkocykpXG4gICAgcmV0dXJuIHM7XG4gIHJldHVybiBjYW1sX3V0ZjE2X29mX3V0Zjgocyk7IH1cblxuLy9Qcm92aWRlczogY2FtbF9zdHJpbmdfb2ZfanNzdHJpbmcgY29uc3Rcbi8vUmVxdWlyZXM6IGpzb29faXNfYXNjaWksIGNhbWxfdXRmOF9vZl91dGYxNiwgY2FtbF9zdHJpbmdfb2ZfanNieXRlc1xuLy9JZjoganMtc3RyaW5nXG5mdW5jdGlvbiBjYW1sX3N0cmluZ19vZl9qc3N0cmluZyAocykge1xuICBpZiAoanNvb19pc19hc2NpaShzKSlcbiAgICByZXR1cm4gY2FtbF9zdHJpbmdfb2ZfanNieXRlcyhzKVxuICBlbHNlIHJldHVybiBjYW1sX3N0cmluZ19vZl9qc2J5dGVzKGNhbWxfdXRmOF9vZl91dGYxNihzKSk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfYnl0ZXNfb2ZfanNieXRlcyBjb25zdFxuLy9SZXF1aXJlczogTWxCeXRlc1xuZnVuY3Rpb24gY2FtbF9ieXRlc19vZl9qc2J5dGVzKHMpIHsgcmV0dXJuIG5ldyBNbEJ5dGVzKDAscyxzLmxlbmd0aCk7IH1cblxuXG4vLyBUaGUgc2VjdGlvbiBiZWxvdyBzaG91bGQgYmUgdXNlZCB3aGVuIHVzZS1qcy1zdHJpbmc9ZmFsc2VcblxuLy9Qcm92aWRlczogY2FtbF9zdHJpbmdfdW5zYWZlX2dldCBjb25zdFxuLy9SZXF1aXJlczogY2FtbF9ieXRlc191bnNhZmVfZ2V0XG4vL0lmOiAhanMtc3RyaW5nXG5mdW5jdGlvbiBjYW1sX3N0cmluZ191bnNhZmVfZ2V0IChzLCBpKSB7XG4gIHJldHVybiBjYW1sX2J5dGVzX3Vuc2FmZV9nZXQocyxpKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zdHJpbmdfdW5zYWZlX3NldFxuLy9SZXF1aXJlczogY2FtbF9ieXRlc191bnNhZmVfc2V0XG4vL0lmOiAhanMtc3RyaW5nXG5mdW5jdGlvbiBjYW1sX3N0cmluZ191bnNhZmVfc2V0IChzLCBpLCBjKSB7XG4gIHJldHVybiBjYW1sX2J5dGVzX3Vuc2FmZV9zZXQocyxpLGMpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21sX3N0cmluZ19sZW5ndGggY29uc3Rcbi8vUmVxdWlyZXM6IGNhbWxfbWxfYnl0ZXNfbGVuZ3RoXG4vL0lmOiAhanMtc3RyaW5nXG5mdW5jdGlvbiBjYW1sX21sX3N0cmluZ19sZW5ndGgocykge1xuICByZXR1cm4gY2FtbF9tbF9ieXRlc19sZW5ndGgocylcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zdHJpbmdfY29tcGFyZVxuLy9SZXF1aXJlczogY2FtbF9ieXRlc19jb21wYXJlXG4vL0lmOiAhanMtc3RyaW5nXG5mdW5jdGlvbiBjYW1sX3N0cmluZ19jb21wYXJlKHMxLCBzMikge1xuICByZXR1cm4gY2FtbF9ieXRlc19jb21wYXJlKHMxLHMyKVxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N0cmluZ19lcXVhbFxuLy9SZXF1aXJlczogY2FtbF9ieXRlc19lcXVhbFxuLy9JZjogIWpzLXN0cmluZ1xuZnVuY3Rpb24gY2FtbF9zdHJpbmdfZXF1YWwoczEsIHMyKSB7XG4gIHJldHVybiBjYW1sX2J5dGVzX2VxdWFsKHMxLHMyKVxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N0cmluZ19sZXNzZXF1YWxcbi8vUmVxdWlyZXM6IGNhbWxfYnl0ZXNfbGVzc2VxdWFsXG4vL0lmOiAhanMtc3RyaW5nXG5mdW5jdGlvbiBjYW1sX3N0cmluZ19sZXNzZXF1YWwoczEsIHMyKSB7XG4gIHJldHVybiBjYW1sX2J5dGVzX2xlc3NlcXVhbChzMSxzMilcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zdHJpbmdfbGVzc3RoYW5cbi8vUmVxdWlyZXM6IGNhbWxfYnl0ZXNfbGVzc3RoYW5cbi8vSWY6ICFqcy1zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfc3RyaW5nX2xlc3N0aGFuKHMxLCBzMikge1xuICByZXR1cm4gY2FtbF9ieXRlc19sZXNzdGhhbihzMSxzMilcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zdHJpbmdfb2ZfYnl0ZXNcbi8vSWY6ICFqcy1zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfc3RyaW5nX29mX2J5dGVzKHMpIHsgcmV0dXJuIHMgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2J5dGVzX29mX3N0cmluZyBjb25zdFxuLy9JZjogIWpzLXN0cmluZ1xuZnVuY3Rpb24gY2FtbF9ieXRlc19vZl9zdHJpbmcocykgeyByZXR1cm4gcyB9XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3RyaW5nX29mX2pzYnl0ZXMgY29uc3Rcbi8vUmVxdWlyZXM6IGNhbWxfYnl0ZXNfb2ZfanNieXRlc1xuLy9JZjogIWpzLXN0cmluZ1xuZnVuY3Rpb24gY2FtbF9zdHJpbmdfb2ZfanNieXRlcyhzKSB7IHJldHVybiBjYW1sX2J5dGVzX29mX2pzYnl0ZXMocyk7IH1cblxuLy9Qcm92aWRlczogY2FtbF9qc2J5dGVzX29mX3N0cmluZyBjb25zdFxuLy9SZXF1aXJlczogY2FtbF9jb252ZXJ0X3N0cmluZ190b19ieXRlc1xuLy9JZjogIWpzLXN0cmluZ1xuZnVuY3Rpb24gY2FtbF9qc2J5dGVzX29mX3N0cmluZyhzKSB7XG4gIChzLnQgJiA2KSAmJiBjYW1sX2NvbnZlcnRfc3RyaW5nX3RvX2J5dGVzKHMpO1xuICByZXR1cm4gcy5jIH1cblxuLy9Qcm92aWRlczogY2FtbF9qc3N0cmluZ19vZl9zdHJpbmcgbXV0YWJsZSAoY29uc3QpXG4vL0lmOiAhanMtc3RyaW5nXG5mdW5jdGlvbiBjYW1sX2pzc3RyaW5nX29mX3N0cmluZyhzKXtcbiAgcmV0dXJuIHMudG9VdGYxNigpXG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3RyaW5nX29mX2pzc3RyaW5nXG4vL1JlcXVpcmVzOiBjYW1sX2J5dGVzX29mX3V0ZjE2X2pzc3RyaW5nXG4vL0lmOiAhanMtc3RyaW5nXG5mdW5jdGlvbiBjYW1sX3N0cmluZ19vZl9qc3N0cmluZyAocykge1xuICByZXR1cm4gY2FtbF9ieXRlc19vZl91dGYxNl9qc3N0cmluZyhzKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9pc19tbF9ieXRlc1xuLy9SZXF1aXJlczogTWxCeXRlc1xuZnVuY3Rpb24gY2FtbF9pc19tbF9ieXRlcyhzKSB7XG4gIHJldHVybiAocyBpbnN0YW5jZW9mIE1sQnl0ZXMpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21sX2J5dGVzX2NvbnRlbnRcbi8vUmVxdWlyZXM6IE1sQnl0ZXMsIGNhbWxfY29udmVydF9zdHJpbmdfdG9fYnl0ZXNcbmZ1bmN0aW9uIGNhbWxfbWxfYnl0ZXNfY29udGVudChzKSB7XG4gIHN3aXRjaCAocy50ICYgNikge1xuICBkZWZhdWx0OiAvKiBQQVJUSUFMICovXG4gICAgY2FtbF9jb252ZXJ0X3N0cmluZ190b19ieXRlcyhzKTtcbiAgY2FzZSAwOiAvKiBCWVRFUyAqL1xuICAgIHJldHVybiBzLmM7XG4gIGNhc2UgNDpcbiAgICByZXR1cm4gcy5jXG4gIH1cbn1cblxuLy9Qcm92aWRlczogY2FtbF9pc19tbF9zdHJpbmdcbi8vUmVxdWlyZXM6IGpzb29faXNfYXNjaWlcbi8vSWY6IGpzLXN0cmluZ1xuZnVuY3Rpb24gY2FtbF9pc19tbF9zdHJpbmcocykge1xuICByZXR1cm4gKHR5cGVvZiBzID09PSBcInN0cmluZ1wiICYmICEvW15cXHgwMC1cXHhmZl0vLnRlc3QocykpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2lzX21sX3N0cmluZ1xuLy9SZXF1aXJlczogY2FtbF9pc19tbF9ieXRlc1xuLy9JZjogIWpzLXN0cmluZ1xuZnVuY3Rpb24gY2FtbF9pc19tbF9zdHJpbmcocykge1xuICByZXR1cm4gY2FtbF9pc19tbF9ieXRlcyhzKTtcbn1cblxuLy8gVGhlIGZ1bmN0aW9ucyBiZWxvdyBhcmUgZGVwcmVjYXRlZFxuXG4vL1Byb3ZpZGVzOiBjYW1sX2pzX3RvX2J5dGVfc3RyaW5nIGNvbnN0XG4vL1JlcXVpcmVzOiBjYW1sX3N0cmluZ19vZl9qc2J5dGVzXG5mdW5jdGlvbiBjYW1sX2pzX3RvX2J5dGVfc3RyaW5nKHMpIHsgcmV0dXJuIGNhbWxfc3RyaW5nX29mX2pzYnl0ZXMocykgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX25ld19zdHJpbmdcbi8vUmVxdWlyZXM6IGNhbWxfc3RyaW5nX29mX2pzYnl0ZXNcbmZ1bmN0aW9uIGNhbWxfbmV3X3N0cmluZyAocykgeyByZXR1cm4gY2FtbF9zdHJpbmdfb2ZfanNieXRlcyhzKSB9XG5cbi8vUHJvdmlkZXM6IGNhbWxfanNfZnJvbV9zdHJpbmcgbXV0YWJsZSAoY29uc3QpXG4vL1JlcXVpcmVzOiBjYW1sX2pzc3RyaW5nX29mX3N0cmluZ1xuZnVuY3Rpb24gY2FtbF9qc19mcm9tX3N0cmluZyhzKSB7XG4gIHJldHVybiBjYW1sX2pzc3RyaW5nX29mX3N0cmluZyhzKVxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3RvX2pzX3N0cmluZyBtdXRhYmxlIChjb25zdClcbi8vUmVxdWlyZXM6IGNhbWxfanNzdHJpbmdfb2Zfc3RyaW5nXG5mdW5jdGlvbiBjYW1sX3RvX2pzX3N0cmluZyhzKSB7XG4gIHJldHVybiBjYW1sX2pzc3RyaW5nX29mX3N0cmluZyhzKVxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2pzX3RvX3N0cmluZyBjb25zdFxuLy9SZXF1aXJlczogY2FtbF9zdHJpbmdfb2ZfanNzdHJpbmdcbmZ1bmN0aW9uIGNhbWxfanNfdG9fc3RyaW5nIChzKSB7XG4gIHJldHVybiBjYW1sX3N0cmluZ19vZl9qc3N0cmluZyhzKTtcbn1cblxuXG4vL1Byb3ZpZGVzOiBjYW1sX2FycmF5X29mX3N0cmluZ1xuLy9SZXF1aXJlczogY2FtbF91aW50OF9hcnJheV9vZl9zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfYXJyYXlfb2Zfc3RyaW5nKHgpIHsgcmV0dXJuIGNhbWxfdWludDhfYXJyYXlfb2Zfc3RyaW5nKHgpIH1cblxuLy9Qcm92aWRlczogY2FtbF9hcnJheV9vZl9ieXRlc1xuLy9SZXF1aXJlczogY2FtbF91aW50OF9hcnJheV9vZl9ieXRlc1xuZnVuY3Rpb24gY2FtbF9hcnJheV9vZl9ieXRlcyh4KSB7IHJldHVybiBjYW1sX3VpbnQ4X2FycmF5X29mX2J5dGVzKHgpIH1cbiIsIi8vIEpzX29mX29jYW1sIHJ1bnRpbWUgc3VwcG9ydFxuLy8gaHR0cDovL3d3dy5vY3NpZ2VuLm9yZy9qc19vZl9vY2FtbC9cbi8vIENvcHlyaWdodCAoQykgMjAxNCBKw6lyw7RtZSBWb3VpbGxvbiwgSHVnbyBIZXV6YXJkLCBBbmR5IFJheVxuLy8gTGFib3JhdG9pcmUgUFBTIC0gQ05SUyBVbml2ZXJzaXTDqSBQYXJpcyBEaWRlcm90XG4vL1xuLy8gVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbi8vIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuLy8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgd2l0aCBsaW5raW5nIGV4Y2VwdGlvbjtcbi8vIGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vXG4vLyBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4vLyBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2Vcbi8vIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLlxuLy9cbi8vIEJpZ2FycmF5LlxuLy9cbi8vIC0gYWxsIGJpZ2FycmF5IHR5cGVzIGluY2x1ZGluZyBJbnQ2NCBhbmQgQ29tcGxleC5cbi8vIC0gZm9ydHJhbiArIGMgbGF5b3V0c1xuLy8gLSBzdWIvc2xpY2UvcmVzaGFwZVxuLy8gLSByZXRhaW4gZmFzdCBwYXRoIGZvciAxZCBhcnJheSBhY2Nlc3NcblxuLy9Qcm92aWRlczogY2FtbF9iYV9pbml0IGNvbnN0XG5mdW5jdGlvbiBjYW1sX2JhX2luaXQoKSB7XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2JhX2dldF9zaXplXG4vL1JlcXVpcmVzOiBjYW1sX2ludmFsaWRfYXJndW1lbnRcbmZ1bmN0aW9uIGNhbWxfYmFfZ2V0X3NpemUoZGltcykge1xuICB2YXIgbl9kaW1zID0gZGltcy5sZW5ndGg7XG4gIHZhciBzaXplID0gMTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBuX2RpbXM7IGkrKykge1xuICAgIGlmIChkaW1zW2ldIDwgMClcbiAgICAgIGNhbWxfaW52YWxpZF9hcmd1bWVudChcIkJpZ2FycmF5LmNyZWF0ZTogbmVnYXRpdmUgZGltZW5zaW9uXCIpO1xuICAgIHNpemUgPSBzaXplICogZGltc1tpXTtcbiAgfVxuICByZXR1cm4gc2l6ZTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iYV9nZXRfc2l6ZV9wZXJfZWxlbWVudFxuZnVuY3Rpb24gY2FtbF9iYV9nZXRfc2l6ZV9wZXJfZWxlbWVudChraW5kKXtcbiAgc3dpdGNoKGtpbmQpe1xuICBjYXNlIDc6IGNhc2UgMTA6IGNhc2UgMTE6IHJldHVybiAyO1xuICBkZWZhdWx0OiByZXR1cm4gMTtcbiAgfVxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2JhX2NyZWF0ZV9idWZmZXJcbi8vUmVxdWlyZXM6IGNhbWxfYmFfZ2V0X3NpemVfcGVyX2VsZW1lbnRcbi8vUmVxdWlyZXM6IGNhbWxfaW52YWxpZF9hcmd1bWVudFxuZnVuY3Rpb24gY2FtbF9iYV9jcmVhdGVfYnVmZmVyKGtpbmQsIHNpemUpe1xuICB2YXIgdmlldztcbiAgc3dpdGNoKGtpbmQpe1xuICBjYXNlIDA6ICB2aWV3ID0gRmxvYXQzMkFycmF5OyBicmVhaztcbiAgY2FzZSAxOiAgdmlldyA9IEZsb2F0NjRBcnJheTsgYnJlYWs7XG4gIGNhc2UgMjogIHZpZXcgPSBJbnQ4QXJyYXk7IGJyZWFrO1xuICBjYXNlIDM6ICB2aWV3ID0gVWludDhBcnJheTsgYnJlYWs7XG4gIGNhc2UgNDogIHZpZXcgPSBJbnQxNkFycmF5OyBicmVhaztcbiAgY2FzZSA1OiAgdmlldyA9IFVpbnQxNkFycmF5OyBicmVhaztcbiAgY2FzZSA2OiAgdmlldyA9IEludDMyQXJyYXk7IGJyZWFrO1xuICBjYXNlIDc6ICB2aWV3ID0gSW50MzJBcnJheTsgYnJlYWs7XG4gIGNhc2UgODogIHZpZXcgPSBJbnQzMkFycmF5OyBicmVhaztcbiAgY2FzZSA5OiAgdmlldyA9IEludDMyQXJyYXk7IGJyZWFrO1xuICBjYXNlIDEwOiB2aWV3ID0gRmxvYXQzMkFycmF5OyBicmVhaztcbiAgY2FzZSAxMTogdmlldyA9IEZsb2F0NjRBcnJheTsgYnJlYWs7XG4gIGNhc2UgMTI6IHZpZXcgPSBVaW50OEFycmF5OyBicmVhaztcbiAgfVxuICBpZiAoIXZpZXcpIGNhbWxfaW52YWxpZF9hcmd1bWVudChcIkJpZ2FycmF5LmNyZWF0ZTogdW5zdXBwb3J0ZWQga2luZFwiKTtcbiAgdmFyIGRhdGEgPSBuZXcgdmlldyhzaXplICogY2FtbF9iYV9nZXRfc2l6ZV9wZXJfZWxlbWVudChraW5kKSk7XG4gIHJldHVybiBkYXRhO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2JhX2N1c3RvbV9uYW1lXG4vL1ZlcnNpb246IDwgNC4xMVxudmFyIGNhbWxfYmFfY3VzdG9tX25hbWUgPSBcIl9iaWdhcnJheVwiXG5cbi8vUHJvdmlkZXM6IGNhbWxfYmFfY3VzdG9tX25hbWVcbi8vVmVyc2lvbjogPj0gNC4xMVxudmFyIGNhbWxfYmFfY3VzdG9tX25hbWUgPSBcIl9iaWdhcnIwMlwiXG5cbi8vUHJvdmlkZXM6IE1sX0JpZ2FycmF5XG4vL1JlcXVpcmVzOiBjYW1sX2FycmF5X2JvdW5kX2Vycm9yLCBjYW1sX2ludmFsaWRfYXJndW1lbnQsIGNhbWxfYmFfY3VzdG9tX25hbWVcbi8vUmVxdWlyZXM6IGNhbWxfaW50NjRfY3JlYXRlX2xvX2hpLCBjYW1sX2ludDY0X2hpMzIsIGNhbWxfaW50NjRfbG8zMlxuZnVuY3Rpb24gTWxfQmlnYXJyYXkgKGtpbmQsIGxheW91dCwgZGltcywgYnVmZmVyKSB7XG5cbiAgdGhpcy5raW5kICAgPSBraW5kIDtcbiAgdGhpcy5sYXlvdXQgPSBsYXlvdXQ7XG4gIHRoaXMuZGltcyAgID0gZGltcztcbiAgdGhpcy5kYXRhID0gYnVmZmVyO1xufVxuXG5NbF9CaWdhcnJheS5wcm90b3R5cGUuY2FtbF9jdXN0b20gPSBjYW1sX2JhX2N1c3RvbV9uYW1lO1xuXG5NbF9CaWdhcnJheS5wcm90b3R5cGUub2Zmc2V0ID0gZnVuY3Rpb24gKGFyZykge1xuICB2YXIgb2ZzID0gMDtcbiAgaWYodHlwZW9mIGFyZyA9PT0gXCJudW1iZXJcIikgYXJnID0gW2FyZ107XG4gIGlmICghIChhcmcgaW5zdGFuY2VvZiBBcnJheSkpIGNhbWxfaW52YWxpZF9hcmd1bWVudChcImJpZ2FycmF5LmpzOiBpbnZhbGlkIG9mZnNldFwiKTtcbiAgaWYgKHRoaXMuZGltcy5sZW5ndGggIT0gYXJnLmxlbmd0aClcbiAgICBjYW1sX2ludmFsaWRfYXJndW1lbnQoXCJCaWdhcnJheS5nZXQvc2V0OiBiYWQgbnVtYmVyIG9mIGRpbWVuc2lvbnNcIik7XG4gIGlmKHRoaXMubGF5b3V0ID09IDAgLyogY19sYXlvdXQgKi8pIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuZGltcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGFyZ1tpXSA8IDAgfHwgYXJnW2ldID49IHRoaXMuZGltc1tpXSlcbiAgICAgICAgY2FtbF9hcnJheV9ib3VuZF9lcnJvcigpO1xuICAgICAgb2ZzID0gKG9mcyAqIHRoaXMuZGltc1tpXSkgKyBhcmdbaV07XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGZvciAodmFyIGkgPSB0aGlzLmRpbXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGlmIChhcmdbaV0gPCAxIHx8IGFyZ1tpXSA+IHRoaXMuZGltc1tpXSl7XG4gICAgICAgIGNhbWxfYXJyYXlfYm91bmRfZXJyb3IoKTtcbiAgICAgIH1cbiAgICAgIG9mcyA9IChvZnMgKiB0aGlzLmRpbXNbaV0pICsgKGFyZ1tpXSAtIDEpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gb2ZzO1xufVxuXG5NbF9CaWdhcnJheS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKG9mcykge1xuICBzd2l0Y2godGhpcy5raW5kKXtcbiAgY2FzZSA3OlxuICAgIC8vIEludDY0XG4gICAgdmFyIGwgPSB0aGlzLmRhdGFbb2ZzICogMiArIDBdO1xuICAgIHZhciBoID0gdGhpcy5kYXRhW29mcyAqIDIgKyAxXTtcbiAgICByZXR1cm4gY2FtbF9pbnQ2NF9jcmVhdGVfbG9faGkobCxoKTtcbiAgY2FzZSAxMDogY2FzZSAxMTpcbiAgICAvLyBDb21wbGV4MzIsIENvbXBsZXg2NFxuICAgIHZhciByID0gdGhpcy5kYXRhW29mcyAqIDIgKyAwXTtcbiAgICB2YXIgaSA9IHRoaXMuZGF0YVtvZnMgKiAyICsgMV07XG4gICAgcmV0dXJuIFsyNTQsIHIsIGldO1xuICBkZWZhdWx0OlxuICAgIHJldHVybiB0aGlzLmRhdGFbb2ZzXVxuICB9XG59XG5cbk1sX0JpZ2FycmF5LnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAob2ZzLHYpIHtcbiAgc3dpdGNoKHRoaXMua2luZCl7XG4gIGNhc2UgNzpcbiAgICAvLyBJbnQ2NFxuICAgIHRoaXMuZGF0YVtvZnMgKiAyICsgMF0gPSBjYW1sX2ludDY0X2xvMzIodik7XG4gICAgdGhpcy5kYXRhW29mcyAqIDIgKyAxXSA9IGNhbWxfaW50NjRfaGkzMih2KTtcbiAgICBicmVhaztcbiAgY2FzZSAxMDogY2FzZSAxMTpcbiAgICAvLyBDb21wbGV4MzIsIENvbXBsZXg2NFxuICAgIHRoaXMuZGF0YVtvZnMgKiAyICsgMF0gPSB2WzFdO1xuICAgIHRoaXMuZGF0YVtvZnMgKiAyICsgMV0gPSB2WzJdO1xuICAgIGJyZWFrO1xuICBkZWZhdWx0OlxuICAgIHRoaXMuZGF0YVtvZnNdID0gdjtcbiAgICBicmVhaztcbiAgfVxuICByZXR1cm4gMFxufVxuXG5cbk1sX0JpZ2FycmF5LnByb3RvdHlwZS5maWxsID0gZnVuY3Rpb24gKHYpIHtcbiAgc3dpdGNoKHRoaXMua2luZCl7XG4gIGNhc2UgNzpcbiAgICAvLyBJbnQ2NFxuICAgIHZhciBhID0gY2FtbF9pbnQ2NF9sbzMyKHYpO1xuICAgIHZhciBiID0gY2FtbF9pbnQ2NF9oaTMyKHYpO1xuICAgIGlmKGEgPT0gYil7XG4gICAgICB0aGlzLmRhdGEuZmlsbChhKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBmb3IodmFyIGkgPSAwOyBpPHRoaXMuZGF0YS5sZW5ndGg7IGkrKyl7XG4gICAgICAgIHRoaXMuZGF0YVtpXSA9IChpJTIgPT0gMCkgPyBhIDogYjtcbiAgICAgIH1cbiAgICB9XG4gICAgYnJlYWs7XG4gIGNhc2UgMTA6IGNhc2UgMTE6XG4gICAgLy8gQ29tcGxleDMyLCBDb21wbGV4NjRcbiAgICB2YXIgaW0gPSB2WzFdO1xuICAgIHZhciByZSA9IHZbMl07XG4gICAgaWYoaW0gPT0gcmUpe1xuICAgICAgdGhpcy5kYXRhLmZpbGwoaW0pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGZvcih2YXIgaSA9IDA7IGk8dGhpcy5kYXRhLmxlbmd0aDsgaSsrKXtcbiAgICAgICAgdGhpcy5kYXRhW2ldID0gKGklMiA9PSAwKSA/IGltIDogcmU7XG4gICAgICB9XG4gICAgfVxuICAgIGJyZWFrO1xuICBkZWZhdWx0OlxuICAgIHRoaXMuZGF0YS5maWxsKHYpO1xuICAgIGJyZWFrO1xuICB9XG59XG5cblxuTWxfQmlnYXJyYXkucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiAoYiwgdG90YWwpIHtcbiAgaWYgKHRoaXMubGF5b3V0ICE9IGIubGF5b3V0IHx8IHRoaXMua2luZCAhPSBiLmtpbmQpIHtcbiAgICB2YXIgazEgPSB0aGlzLmtpbmQgfCAodGhpcy5sYXlvdXQgPDwgOCk7XG4gICAgdmFyIGsyID0gICAgYi5raW5kIHwgKGIubGF5b3V0IDw8IDgpO1xuICAgIHJldHVybiBrMiAtIGsxO1xuICB9XG4gIGlmICh0aGlzLmRpbXMubGVuZ3RoICE9IGIuZGltcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gYi5kaW1zLmxlbmd0aCAtIHRoaXMuZGltcy5sZW5ndGg7XG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmRpbXMubGVuZ3RoOyBpKyspXG4gICAgaWYgKHRoaXMuZGltc1tpXSAhPSBiLmRpbXNbaV0pXG4gICAgICByZXR1cm4gKHRoaXMuZGltc1tpXSA8IGIuZGltc1tpXSkgPyAtMSA6IDE7XG4gIHN3aXRjaCAodGhpcy5raW5kKSB7XG4gIGNhc2UgMDpcbiAgY2FzZSAxOlxuICBjYXNlIDEwOlxuICBjYXNlIDExOlxuICAgIC8vIEZsb2F0c1xuICAgIHZhciB4LCB5O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5kYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICB4ID0gdGhpcy5kYXRhW2ldO1xuICAgICAgeSA9IGIuZGF0YVtpXTtcbiAgICAgIGlmICh4IDwgeSlcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgaWYgKHggPiB5KVxuICAgICAgICByZXR1cm4gMTtcbiAgICAgIGlmICh4ICE9IHkpIHtcbiAgICAgICAgaWYgKCF0b3RhbCkgcmV0dXJuIE5hTjtcbiAgICAgICAgaWYgKHggPT0geCkgcmV0dXJuIDE7XG4gICAgICAgIGlmICh5ID09IHkpIHJldHVybiAtMTtcbiAgICAgIH1cbiAgICB9XG4gICAgYnJlYWs7XG4gIGNhc2UgNzpcbiAgICAvLyBJbnQ2NFxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5kYXRhLmxlbmd0aDsgaSs9Mikge1xuICAgICAgLy8gQ2hlY2sgaGlnaGVzdCBiaXRzIGZpcnN0XG4gICAgICBpZiAodGhpcy5kYXRhW2krMV0gPCBiLmRhdGFbaSsxXSlcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgaWYgKHRoaXMuZGF0YVtpKzFdID4gYi5kYXRhW2krMV0pXG4gICAgICAgIHJldHVybiAxO1xuICAgICAgaWYgKCh0aGlzLmRhdGFbaV0gPj4+IDApIDwgKGIuZGF0YVtpXSA+Pj4gMCkpXG4gICAgICAgIHJldHVybiAtMTtcbiAgICAgIGlmICgodGhpcy5kYXRhW2ldID4+PiAwKSA+IChiLmRhdGFbaV0gPj4+IDApKVxuICAgICAgICByZXR1cm4gMTtcbiAgICB9XG4gICAgYnJlYWs7XG4gIGNhc2UgMjpcbiAgY2FzZSAzOlxuICBjYXNlIDQ6XG4gIGNhc2UgNTpcbiAgY2FzZSA2OlxuICBjYXNlIDg6XG4gIGNhc2UgOTpcbiAgY2FzZSAxMjpcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHRoaXMuZGF0YVtpXSA8IGIuZGF0YVtpXSlcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgaWYgKHRoaXMuZGF0YVtpXSA+IGIuZGF0YVtpXSlcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICAgIGJyZWFrO1xuICB9XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBNbF9CaWdhcnJheV9jXzFfMVxuLy9SZXF1aXJlczogTWxfQmlnYXJyYXksIGNhbWxfYXJyYXlfYm91bmRfZXJyb3IsIGNhbWxfaW52YWxpZF9hcmd1bWVudFxuZnVuY3Rpb24gTWxfQmlnYXJyYXlfY18xXzEoa2luZCwgbGF5b3V0LCBkaW1zLCBidWZmZXIpIHtcbiAgdGhpcy5raW5kICAgPSBraW5kIDtcbiAgdGhpcy5sYXlvdXQgPSBsYXlvdXQ7XG4gIHRoaXMuZGltcyAgID0gZGltcztcbiAgdGhpcy5kYXRhICAgPSBidWZmZXI7XG59XG5cbk1sX0JpZ2FycmF5X2NfMV8xLnByb3RvdHlwZSA9IG5ldyBNbF9CaWdhcnJheSgpXG5NbF9CaWdhcnJheV9jXzFfMS5wcm90b3R5cGUub2Zmc2V0ID0gZnVuY3Rpb24gKGFyZykge1xuICBpZih0eXBlb2YgYXJnICE9PSBcIm51bWJlclwiKXtcbiAgICBpZigoYXJnIGluc3RhbmNlb2YgQXJyYXkpICYmIGFyZy5sZW5ndGggPT0gMSlcbiAgICAgIGFyZyA9IGFyZ1swXTtcbiAgICBlbHNlIGNhbWxfaW52YWxpZF9hcmd1bWVudChcIk1sX0JpZ2FycmF5X2NfMV8xLm9mZnNldFwiKTtcbiAgfVxuICBpZiAoYXJnIDwgMCB8fCBhcmcgPj0gdGhpcy5kaW1zWzBdKVxuICAgIGNhbWxfYXJyYXlfYm91bmRfZXJyb3IoKTtcbiAgcmV0dXJuIGFyZztcbn1cblxuTWxfQmlnYXJyYXlfY18xXzEucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChvZnMpIHtcbiAgcmV0dXJuIHRoaXMuZGF0YVtvZnNdO1xufVxuXG5NbF9CaWdhcnJheV9jXzFfMS5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKG9mcyx2KSB7XG4gIHRoaXMuZGF0YVtvZnNdID0gdjtcbiAgcmV0dXJuIDBcbn1cblxuTWxfQmlnYXJyYXlfY18xXzEucHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbiAodikge1xuICB0aGlzLmRhdGEuZmlsbCh2KTtcbiAgcmV0dXJuIDBcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iYV9jb21wYXJlXG5mdW5jdGlvbiBjYW1sX2JhX2NvbXBhcmUoYSxiLHRvdGFsKXtcbiAgcmV0dXJuIGEuY29tcGFyZShiLHRvdGFsKVxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2JhX2NyZWF0ZV91bnNhZmVcbi8vUmVxdWlyZXM6IE1sX0JpZ2FycmF5LCBNbF9CaWdhcnJheV9jXzFfMSwgY2FtbF9iYV9nZXRfc2l6ZSwgY2FtbF9iYV9nZXRfc2l6ZV9wZXJfZWxlbWVudFxuLy9SZXF1aXJlczogY2FtbF9pbnZhbGlkX2FyZ3VtZW50XG5mdW5jdGlvbiBjYW1sX2JhX2NyZWF0ZV91bnNhZmUoa2luZCwgbGF5b3V0LCBkaW1zLCBkYXRhKXtcbiAgdmFyIHNpemVfcGVyX2VsZW1lbnQgPSBjYW1sX2JhX2dldF9zaXplX3Blcl9lbGVtZW50KGtpbmQpO1xuICBpZihjYW1sX2JhX2dldF9zaXplKGRpbXMpICogc2l6ZV9wZXJfZWxlbWVudCAhPSBkYXRhLmxlbmd0aCkge1xuICAgIGNhbWxfaW52YWxpZF9hcmd1bWVudChcImxlbmd0aCBkb2Vzbid0IG1hdGNoIGRpbXNcIik7XG4gIH1cbiAgaWYobGF5b3V0ID09IDAgJiYgLy8gY19sYXlvdXRcbiAgICAgZGltcy5sZW5ndGggPT0gMSAmJiAvLyBBcnJheTFcbiAgICAgc2l6ZV9wZXJfZWxlbWVudCA9PSAxKSAvLyAxLXRvLTEgbWFwcGluZ1xuICAgIHJldHVybiBuZXcgTWxfQmlnYXJyYXlfY18xXzEoa2luZCwgbGF5b3V0LCBkaW1zLCBkYXRhKTtcbiAgcmV0dXJuIG5ldyBNbF9CaWdhcnJheShraW5kLCBsYXlvdXQsIGRpbXMsIGRhdGEpO1xuXG59XG5cblxuLy9Qcm92aWRlczogY2FtbF9iYV9jcmVhdGVcbi8vUmVxdWlyZXM6IGNhbWxfanNfZnJvbV9hcnJheVxuLy9SZXF1aXJlczogY2FtbF9iYV9nZXRfc2l6ZSwgY2FtbF9iYV9jcmVhdGVfdW5zYWZlXG4vL1JlcXVpcmVzOiBjYW1sX2JhX2NyZWF0ZV9idWZmZXJcbmZ1bmN0aW9uIGNhbWxfYmFfY3JlYXRlKGtpbmQsIGxheW91dCwgZGltc19tbCkge1xuICB2YXIgZGltcyA9IGNhbWxfanNfZnJvbV9hcnJheShkaW1zX21sKTtcbiAgdmFyIGRhdGEgPSBjYW1sX2JhX2NyZWF0ZV9idWZmZXIoa2luZCwgY2FtbF9iYV9nZXRfc2l6ZShkaW1zKSk7XG4gIHJldHVybiBjYW1sX2JhX2NyZWF0ZV91bnNhZmUoa2luZCwgbGF5b3V0LCBkaW1zLCBkYXRhKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iYV9jaGFuZ2VfbGF5b3V0XG4vL1JlcXVpcmVzOiBjYW1sX2JhX2NyZWF0ZV91bnNhZmVcbmZ1bmN0aW9uIGNhbWxfYmFfY2hhbmdlX2xheW91dChiYSwgbGF5b3V0KSB7XG4gIGlmKGJhLmxheW91dCA9PSBsYXlvdXQpIHJldHVybiBiYTtcbiAgdmFyIG5ld19kaW1zID0gW11cbiAgZm9yKHZhciBpID0gMDsgaSA8IGJhLmRpbXMubGVuZ3RoOyBpKyspIG5ld19kaW1zW2ldID0gYmEuZGltc1tiYS5kaW1zLmxlbmd0aCAtIGkgLSAxXTtcbiAgcmV0dXJuIGNhbWxfYmFfY3JlYXRlX3Vuc2FmZShiYS5raW5kLCBsYXlvdXQsIG5ld19kaW1zLCBiYS5kYXRhKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iYV9raW5kXG5mdW5jdGlvbiBjYW1sX2JhX2tpbmQoYmEpIHtcbiAgcmV0dXJuIGJhLmtpbmQ7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfYmFfbGF5b3V0XG5mdW5jdGlvbiBjYW1sX2JhX2xheW91dChiYSkge1xuICByZXR1cm4gYmEubGF5b3V0O1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2JhX251bV9kaW1zXG5mdW5jdGlvbiBjYW1sX2JhX251bV9kaW1zKGJhKSB7XG4gIHJldHVybiBiYS5kaW1zLmxlbmd0aDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iYV9kaW1cbi8vUmVxdWlyZXM6IGNhbWxfaW52YWxpZF9hcmd1bWVudFxuZnVuY3Rpb24gY2FtbF9iYV9kaW0oYmEsIGkpIHtcbiAgaWYgKGkgPCAwIHx8IGkgPj0gYmEuZGltcy5sZW5ndGgpXG4gICAgY2FtbF9pbnZhbGlkX2FyZ3VtZW50KFwiQmlnYXJyYXkuZGltXCIpO1xuICByZXR1cm4gYmEuZGltc1tpXTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iYV9kaW1fMVxuLy9SZXF1aXJlczogY2FtbF9iYV9kaW1cbmZ1bmN0aW9uIGNhbWxfYmFfZGltXzEoYmEpIHtcbiAgcmV0dXJuIGNhbWxfYmFfZGltKGJhLCAwKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iYV9kaW1fMlxuLy9SZXF1aXJlczogY2FtbF9iYV9kaW1cbmZ1bmN0aW9uIGNhbWxfYmFfZGltXzIoYmEpIHtcbiAgcmV0dXJuIGNhbWxfYmFfZGltKGJhLCAxKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iYV9kaW1fM1xuLy9SZXF1aXJlczogY2FtbF9iYV9kaW1cbmZ1bmN0aW9uIGNhbWxfYmFfZGltXzMoYmEpIHtcbiAgcmV0dXJuIGNhbWxfYmFfZGltKGJhLCAyKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iYV9nZXRfZ2VuZXJpY1xuLy9SZXF1aXJlczogY2FtbF9qc19mcm9tX2FycmF5XG5mdW5jdGlvbiBjYW1sX2JhX2dldF9nZW5lcmljKGJhLCBpKSB7XG4gIHZhciBvZnMgPSBiYS5vZmZzZXQoY2FtbF9qc19mcm9tX2FycmF5KGkpKTtcbiAgcmV0dXJuIGJhLmdldChvZnMpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2JhX3VpbnQ4X2dldDE2XG4vL1JlcXVpcmVzOiBjYW1sX2FycmF5X2JvdW5kX2Vycm9yXG5mdW5jdGlvbiBjYW1sX2JhX3VpbnQ4X2dldDE2KGJhLCBpMCkge1xuICB2YXIgb2ZzID0gYmEub2Zmc2V0KGkwKTtcbiAgaWYob2ZzICsgMSA+PSBiYS5kYXRhLmxlbmd0aCkgY2FtbF9hcnJheV9ib3VuZF9lcnJvcigpO1xuICB2YXIgYjEgPSBiYS5nZXQob2ZzKTtcbiAgdmFyIGIyID0gYmEuZ2V0KG9mcyArIDEpO1xuICByZXR1cm4gKGIxIHwgKGIyIDw8IDgpKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iYV91aW50OF9nZXQzMlxuLy9SZXF1aXJlczogY2FtbF9hcnJheV9ib3VuZF9lcnJvclxuZnVuY3Rpb24gY2FtbF9iYV91aW50OF9nZXQzMihiYSwgaTApIHtcbiAgdmFyIG9mcyA9IGJhLm9mZnNldChpMCk7XG4gIGlmKG9mcyArIDMgPj0gYmEuZGF0YS5sZW5ndGgpIGNhbWxfYXJyYXlfYm91bmRfZXJyb3IoKTtcbiAgdmFyIGIxID0gYmEuZ2V0KG9mcyswKTtcbiAgdmFyIGIyID0gYmEuZ2V0KG9mcysxKTtcbiAgdmFyIGIzID0gYmEuZ2V0KG9mcysyKTtcbiAgdmFyIGI0ID0gYmEuZ2V0KG9mcyszKTtcbiAgcmV0dXJuICggKGIxIDw8IDApICB8XG4gICAgICAgICAgIChiMiA8PCA4KSAgfFxuICAgICAgICAgICAoYjMgPDwgMTYpIHxcbiAgICAgICAgICAgKGI0IDw8IDI0KSApO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2JhX3VpbnQ4X2dldDY0XG4vL1JlcXVpcmVzOiBjYW1sX2FycmF5X2JvdW5kX2Vycm9yLCBjYW1sX2ludDY0X29mX2J5dGVzXG5mdW5jdGlvbiBjYW1sX2JhX3VpbnQ4X2dldDY0KGJhLCBpMCkge1xuICB2YXIgb2ZzID0gYmEub2Zmc2V0KGkwKTtcbiAgaWYob2ZzICsgNyA+PSBiYS5kYXRhLmxlbmd0aCkgY2FtbF9hcnJheV9ib3VuZF9lcnJvcigpO1xuICB2YXIgYjEgPSBiYS5nZXQob2ZzKzApO1xuICB2YXIgYjIgPSBiYS5nZXQob2ZzKzEpO1xuICB2YXIgYjMgPSBiYS5nZXQob2ZzKzIpO1xuICB2YXIgYjQgPSBiYS5nZXQob2ZzKzMpO1xuICB2YXIgYjUgPSBiYS5nZXQob2ZzKzQpO1xuICB2YXIgYjYgPSBiYS5nZXQob2ZzKzUpO1xuICB2YXIgYjcgPSBiYS5nZXQob2ZzKzYpO1xuICB2YXIgYjggPSBiYS5nZXQob2ZzKzcpO1xuICByZXR1cm4gY2FtbF9pbnQ2NF9vZl9ieXRlcyhbYjgsYjcsYjYsYjUsYjQsYjMsYjIsYjFdKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iYV9nZXRfMVxuZnVuY3Rpb24gY2FtbF9iYV9nZXRfMShiYSwgaTApIHtcbiAgcmV0dXJuIGJhLmdldChiYS5vZmZzZXQoaTApKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iYV9nZXRfMlxuZnVuY3Rpb24gY2FtbF9iYV9nZXRfMihiYSwgaTAsIGkxKSB7XG4gIHJldHVybiBiYS5nZXQoYmEub2Zmc2V0KFtpMCxpMV0pKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iYV9nZXRfM1xuZnVuY3Rpb24gY2FtbF9iYV9nZXRfMyhiYSwgaTAsIGkxLCBpMikge1xuICByZXR1cm4gYmEuZ2V0KGJhLm9mZnNldChbaTAsaTEsaTJdKSk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfYmFfc2V0X2dlbmVyaWNcbi8vUmVxdWlyZXM6IGNhbWxfanNfZnJvbV9hcnJheVxuZnVuY3Rpb24gY2FtbF9iYV9zZXRfZ2VuZXJpYyhiYSwgaSwgdikge1xuICBiYS5zZXQoYmEub2Zmc2V0KGNhbWxfanNfZnJvbV9hcnJheShpKSksIHYpO1xuICByZXR1cm4gMFxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2JhX3VpbnQ4X3NldDE2XG4vL1JlcXVpcmVzOiBjYW1sX2FycmF5X2JvdW5kX2Vycm9yXG5mdW5jdGlvbiBjYW1sX2JhX3VpbnQ4X3NldDE2KGJhLCBpMCwgdikge1xuICB2YXIgb2ZzID0gYmEub2Zmc2V0KGkwKTtcbiAgaWYob2ZzICsgMSA+PSBiYS5kYXRhLmxlbmd0aCkgY2FtbF9hcnJheV9ib3VuZF9lcnJvcigpO1xuICBiYS5zZXQob2ZzKzAsICB2ICAgICAgICAmIDB4ZmYpO1xuICBiYS5zZXQob2ZzKzEsICh2ID4+PiA4KSAmIDB4ZmYpO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iYV91aW50OF9zZXQzMlxuLy9SZXF1aXJlczogY2FtbF9hcnJheV9ib3VuZF9lcnJvclxuZnVuY3Rpb24gY2FtbF9iYV91aW50OF9zZXQzMihiYSwgaTAsIHYpIHtcbiAgdmFyIG9mcyA9IGJhLm9mZnNldChpMCk7XG4gIGlmKG9mcyArIDMgPj0gYmEuZGF0YS5sZW5ndGgpIGNhbWxfYXJyYXlfYm91bmRfZXJyb3IoKTtcbiAgYmEuc2V0KG9mcyswLCAgdiAgICAgICAgICYgMHhmZik7XG4gIGJhLnNldChvZnMrMSwgKHYgPj4+IDgpICAmIDB4ZmYpO1xuICBiYS5zZXQob2ZzKzIsICh2ID4+PiAxNikgJiAweGZmKTtcbiAgYmEuc2V0KG9mcyszLCAodiA+Pj4gMjQpICYgMHhmZik7XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2JhX3VpbnQ4X3NldDY0XG4vL1JlcXVpcmVzOiBjYW1sX2FycmF5X2JvdW5kX2Vycm9yLCBjYW1sX2ludDY0X3RvX2J5dGVzXG5mdW5jdGlvbiBjYW1sX2JhX3VpbnQ4X3NldDY0KGJhLCBpMCwgdikge1xuICB2YXIgb2ZzID0gYmEub2Zmc2V0KGkwKTtcbiAgaWYob2ZzICsgNyA+PSBiYS5kYXRhLmxlbmd0aCkgY2FtbF9hcnJheV9ib3VuZF9lcnJvcigpO1xuICB2YXIgdiA9IGNhbWxfaW50NjRfdG9fYnl0ZXModik7XG4gIGZvcih2YXIgaSA9IDA7IGkgPCA4OyBpKyspIGJhLnNldChvZnMraSwgdls3LWldKVxuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iYV9zZXRfMVxuZnVuY3Rpb24gY2FtbF9iYV9zZXRfMShiYSwgaTAsIHYpIHtcbiAgYmEuc2V0KGJhLm9mZnNldChpMCksIHYpO1xuICByZXR1cm4gMFxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2JhX3NldF8yXG5mdW5jdGlvbiBjYW1sX2JhX3NldF8yKGJhLCBpMCwgaTEsIHYpIHtcbiAgYmEuc2V0KGJhLm9mZnNldChbaTAsaTFdKSwgdik7XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2JhX3NldF8zXG5mdW5jdGlvbiBjYW1sX2JhX3NldF8zKGJhLCBpMCwgaTEsIGkyLCB2KSB7XG4gIGJhLnNldChiYS5vZmZzZXQoW2kwLGkxLGkyXSksIHYpO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iYV9maWxsXG5mdW5jdGlvbiBjYW1sX2JhX2ZpbGwoYmEsIHYpIHtcbiAgYmEuZmlsbCh2KTtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfYmFfYmxpdFxuLy9SZXF1aXJlczogY2FtbF9pbnZhbGlkX2FyZ3VtZW50XG5mdW5jdGlvbiBjYW1sX2JhX2JsaXQoc3JjLCBkc3QpIHtcbiAgaWYgKGRzdC5kaW1zLmxlbmd0aCAhPSBzcmMuZGltcy5sZW5ndGgpXG4gICAgY2FtbF9pbnZhbGlkX2FyZ3VtZW50KFwiQmlnYXJyYXkuYmxpdDogZGltZW5zaW9uIG1pc21hdGNoXCIpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGRzdC5kaW1zLmxlbmd0aDsgaSsrKVxuICAgIGlmIChkc3QuZGltc1tpXSAhPSBzcmMuZGltc1tpXSlcbiAgICAgIGNhbWxfaW52YWxpZF9hcmd1bWVudChcIkJpZ2FycmF5LmJsaXQ6IGRpbWVuc2lvbiBtaXNtYXRjaFwiKTtcbiAgZHN0LmRhdGEuc2V0KHNyYy5kYXRhKTtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfYmFfc3ViXG4vL1JlcXVpcmVzOiBjYW1sX2ludmFsaWRfYXJndW1lbnQsIGNhbWxfYmFfY3JlYXRlX3Vuc2FmZSwgY2FtbF9iYV9nZXRfc2l6ZVxuLy9SZXF1aXJlczogY2FtbF9iYV9nZXRfc2l6ZV9wZXJfZWxlbWVudFxuZnVuY3Rpb24gY2FtbF9iYV9zdWIoYmEsIG9mcywgbGVuKSB7XG4gIHZhciBjaGFuZ2VkX2RpbTtcbiAgdmFyIG11bCA9IDE7XG4gIGlmIChiYS5sYXlvdXQgPT0gMCkge1xuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYmEuZGltcy5sZW5ndGg7IGkrKylcbiAgICAgIG11bCA9IG11bCAqIGJhLmRpbXNbaV07XG4gICAgY2hhbmdlZF9kaW0gPSAwO1xuICB9IGVsc2Uge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgKGJhLmRpbXMubGVuZ3RoIC0gMSk7IGkrKylcbiAgICAgIG11bCA9IG11bCAqIGJhLmRpbXNbaV07XG4gICAgY2hhbmdlZF9kaW0gPSBiYS5kaW1zLmxlbmd0aCAtIDE7XG4gICAgb2ZzID0gb2ZzIC0gMTtcbiAgfVxuICBpZiAob2ZzIDwgMCB8fCBsZW4gPCAwIHx8IChvZnMgKyBsZW4pID4gYmEuZGltc1tjaGFuZ2VkX2RpbV0pe1xuICAgIGNhbWxfaW52YWxpZF9hcmd1bWVudChcIkJpZ2FycmF5LnN1YjogYmFkIHN1Yi1hcnJheVwiKTtcbiAgfVxuICB2YXIgbmV3X2RpbXMgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBiYS5kaW1zLmxlbmd0aDsgaSsrKVxuICAgIG5ld19kaW1zW2ldID0gYmEuZGltc1tpXTtcbiAgbmV3X2RpbXNbY2hhbmdlZF9kaW1dID0gbGVuO1xuICBtdWwgKj0gY2FtbF9iYV9nZXRfc2l6ZV9wZXJfZWxlbWVudChiYS5raW5kKTtcbiAgdmFyIG5ld19kYXRhID0gYmEuZGF0YS5zdWJhcnJheShvZnMgKiBtdWwsIChvZnMgKyBsZW4pICogbXVsKTtcbiAgcmV0dXJuIGNhbWxfYmFfY3JlYXRlX3Vuc2FmZShiYS5raW5kLCBiYS5sYXlvdXQsIG5ld19kaW1zLCBuZXdfZGF0YSk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfYmFfc2xpY2Vcbi8vUmVxdWlyZXM6IGNhbWxfanNfZnJvbV9hcnJheSwgY2FtbF9iYV9jcmVhdGVfdW5zYWZlLCBjYW1sX2ludmFsaWRfYXJndW1lbnQsIGNhbWxfYmFfZ2V0X3NpemVcbi8vUmVxdWlyZXM6IGNhbWxfYmFfZ2V0X3NpemVfcGVyX2VsZW1lbnRcbmZ1bmN0aW9uIGNhbWxfYmFfc2xpY2UoYmEsIHZpbmQpIHtcbiAgdmluZCA9IGNhbWxfanNfZnJvbV9hcnJheSh2aW5kKTtcbiAgdmFyIG51bV9pbmRzID0gdmluZC5sZW5ndGg7XG4gIHZhciBpbmRleCA9IFtdO1xuICB2YXIgc3ViX2RpbXMgPSBbXTtcbiAgdmFyIG9mcztcblxuICBpZiAobnVtX2luZHMgPiBiYS5kaW1zLmxlbmd0aClcbiAgICBjYW1sX2ludmFsaWRfYXJndW1lbnQoXCJCaWdhcnJheS5zbGljZTogdG9vIG1hbnkgaW5kaWNlc1wiKTtcblxuICAvLyBDb21wdXRlIG9mZnNldCBhbmQgY2hlY2sgYm91bmRzXG4gIGlmIChiYS5sYXlvdXQgPT0gMCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbnVtX2luZHM7IGkrKylcbiAgICAgIGluZGV4W2ldID0gdmluZFtpXTtcbiAgICBmb3IgKDsgaSA8IGJhLmRpbXMubGVuZ3RoOyBpKyspXG4gICAgICBpbmRleFtpXSA9IDA7XG4gICAgc3ViX2RpbXMgPSBiYS5kaW1zLnNsaWNlKG51bV9pbmRzKTtcbiAgfSBlbHNlIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG51bV9pbmRzOyBpKyspXG4gICAgICBpbmRleFtiYS5kaW1zLmxlbmd0aCAtIG51bV9pbmRzICsgaV0gPSB2aW5kW2ldO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmEuZGltcy5sZW5ndGggLSBudW1faW5kczsgaSsrKVxuICAgICAgaW5kZXhbaV0gPSAxO1xuICAgIHN1Yl9kaW1zID0gYmEuZGltcy5zbGljZSgwLCBiYS5kaW1zLmxlbmd0aCAtIG51bV9pbmRzKTtcbiAgfVxuICBvZnMgPSBiYS5vZmZzZXQoaW5kZXgpO1xuICB2YXIgc2l6ZSA9IGNhbWxfYmFfZ2V0X3NpemUoc3ViX2RpbXMpO1xuICB2YXIgc2l6ZV9wZXJfZWxlbWVudCA9IGNhbWxfYmFfZ2V0X3NpemVfcGVyX2VsZW1lbnQoYmEua2luZCk7XG4gIHZhciBuZXdfZGF0YSA9IGJhLmRhdGEuc3ViYXJyYXkob2ZzICogc2l6ZV9wZXJfZWxlbWVudCwgKG9mcyArIHNpemUpICogc2l6ZV9wZXJfZWxlbWVudCk7XG4gIHJldHVybiBjYW1sX2JhX2NyZWF0ZV91bnNhZmUoYmEua2luZCwgYmEubGF5b3V0LCBzdWJfZGltcywgbmV3X2RhdGEpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2JhX3Jlc2hhcGVcbi8vUmVxdWlyZXM6IGNhbWxfanNfZnJvbV9hcnJheSwgY2FtbF9pbnZhbGlkX2FyZ3VtZW50LCBjYW1sX2JhX2NyZWF0ZV91bnNhZmUsIGNhbWxfYmFfZ2V0X3NpemVcbmZ1bmN0aW9uIGNhbWxfYmFfcmVzaGFwZShiYSwgdmluZCkge1xuICB2aW5kID0gY2FtbF9qc19mcm9tX2FycmF5KHZpbmQpO1xuICB2YXIgbmV3X2RpbSA9IFtdO1xuICB2YXIgbnVtX2RpbXMgPSB2aW5kLmxlbmd0aDtcblxuICBpZiAobnVtX2RpbXMgPCAwIHx8IG51bV9kaW1zID4gMTYpe1xuICAgIGNhbWxfaW52YWxpZF9hcmd1bWVudChcIkJpZ2FycmF5LnJlc2hhcGU6IGJhZCBudW1iZXIgb2YgZGltZW5zaW9uc1wiKTtcbiAgfVxuICB2YXIgbnVtX2VsdHMgPSAxO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG51bV9kaW1zOyBpKyspIHtcbiAgICBuZXdfZGltW2ldID0gdmluZFtpXTtcbiAgICBpZiAobmV3X2RpbVtpXSA8IDApXG4gICAgICBjYW1sX2ludmFsaWRfYXJndW1lbnQoXCJCaWdhcnJheS5yZXNoYXBlOiBuZWdhdGl2ZSBkaW1lbnNpb25cIik7XG4gICAgbnVtX2VsdHMgPSBudW1fZWx0cyAqIG5ld19kaW1baV07XG4gIH1cblxuICB2YXIgc2l6ZSA9IGNhbWxfYmFfZ2V0X3NpemUoYmEuZGltcyk7XG4gIC8vIENoZWNrIHRoYXQgc2l6ZXMgYWdyZWVcbiAgaWYgKG51bV9lbHRzICE9IHNpemUpXG4gICAgY2FtbF9pbnZhbGlkX2FyZ3VtZW50KFwiQmlnYXJyYXkucmVzaGFwZTogc2l6ZSBtaXNtYXRjaFwiKTtcbiAgcmV0dXJuIGNhbWxfYmFfY3JlYXRlX3Vuc2FmZShiYS5raW5kLCBiYS5sYXlvdXQsIG5ld19kaW0sIGJhLmRhdGEpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2JhX3NlcmlhbGl6ZVxuLy9SZXF1aXJlczogY2FtbF9pbnQ2NF9iaXRzX29mX2Zsb2F0LCBjYW1sX2ludDY0X3RvX2J5dGVzXG4vL1JlcXVpcmVzOiBjYW1sX2ludDMyX2JpdHNfb2ZfZmxvYXRcbmZ1bmN0aW9uIGNhbWxfYmFfc2VyaWFsaXplKHdyaXRlciwgYmEsIHN6KSB7XG4gIHdyaXRlci53cml0ZSgzMiwgYmEuZGltcy5sZW5ndGgpO1xuICB3cml0ZXIud3JpdGUoMzIsIChiYS5raW5kIHwgKGJhLmxheW91dCA8PCA4KSkpO1xuICBpZihiYS5jYW1sX2N1c3RvbSA9PSBcIl9iaWdhcnIwMlwiKVxuICAgIGZvcih2YXIgaSA9IDA7IGkgPCBiYS5kaW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZihiYS5kaW1zW2ldIDwgMHhmZmZmKVxuICAgICAgICB3cml0ZXIud3JpdGUoMTYsIGJhLmRpbXNbaV0pO1xuICAgICAgZWxzZSB7XG4gICAgICAgIHdyaXRlci53cml0ZSgxNiwgMHhmZmZmKTtcbiAgICAgICAgd3JpdGVyLndyaXRlKDMyLCAwKTtcbiAgICAgICAgd3JpdGVyLndyaXRlKDMyLCBiYS5kaW1zW2ldKTtcbiAgICAgIH1cbiAgICB9XG4gIGVsc2VcbiAgICBmb3IodmFyIGkgPSAwOyBpIDwgYmEuZGltcy5sZW5ndGg7IGkrKykgd3JpdGVyLndyaXRlKDMyLGJhLmRpbXNbaV0pXG4gIHN3aXRjaChiYS5raW5kKXtcbiAgY2FzZSAyOiAgLy9JbnQ4QXJyYXlcbiAgY2FzZSAzOiAgLy9VaW50OEFycmF5XG4gIGNhc2UgMTI6IC8vVWludDhBcnJheVxuICAgIGZvcih2YXIgaSA9IDA7IGkgPCBiYS5kYXRhLmxlbmd0aDsgaSsrKXtcbiAgICAgIHdyaXRlci53cml0ZSg4LCBiYS5kYXRhW2ldKTtcbiAgICB9XG4gICAgYnJlYWs7XG4gIGNhc2UgNDogIC8vIEludDE2QXJyYXlcbiAgY2FzZSA1OiAgLy8gVWludDE2QXJyYXlcbiAgICBmb3IodmFyIGkgPSAwOyBpIDwgYmEuZGF0YS5sZW5ndGg7IGkrKyl7XG4gICAgICB3cml0ZXIud3JpdGUoMTYsIGJhLmRhdGFbaV0pO1xuICAgIH1cbiAgICBicmVhaztcbiAgY2FzZSA2OiAgLy8gSW50MzJBcnJheSAoaW50MzIpXG4gICAgZm9yKHZhciBpID0gMDsgaSA8IGJhLmRhdGEubGVuZ3RoOyBpKyspe1xuICAgICAgd3JpdGVyLndyaXRlKDMyLCBiYS5kYXRhW2ldKTtcbiAgICB9XG4gICAgYnJlYWs7XG4gIGNhc2UgODogIC8vIEludDMyQXJyYXkgKGludClcbiAgY2FzZSA5OiAgLy8gSW50MzJBcnJheSAobmF0aXZlaW50KVxuICAgIHdyaXRlci53cml0ZSg4LDApO1xuICAgIGZvcih2YXIgaSA9IDA7IGkgPCBiYS5kYXRhLmxlbmd0aDsgaSsrKXtcbiAgICAgIHdyaXRlci53cml0ZSgzMiwgYmEuZGF0YVtpXSk7XG4gICAgfVxuICAgIGJyZWFrO1xuICBjYXNlIDc6ICAvLyBJbnQzMkFycmF5IChpbnQ2NClcbiAgICBmb3IodmFyIGkgPSAwOyBpIDwgYmEuZGF0YS5sZW5ndGggLyAyOyBpKyspe1xuICAgICAgdmFyIGIgPSBjYW1sX2ludDY0X3RvX2J5dGVzKGJhLmdldChpKSk7XG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IDg7IGorKykgd3JpdGVyLndyaXRlICg4LCBiW2pdKTtcbiAgICB9XG4gICAgYnJlYWs7XG4gIGNhc2UgMTogIC8vIEZsb2F0NjRBcnJheVxuICAgIGZvcih2YXIgaSA9IDA7IGkgPCBiYS5kYXRhLmxlbmd0aDsgaSsrKXtcbiAgICAgIHZhciBiID0gY2FtbF9pbnQ2NF90b19ieXRlcyhjYW1sX2ludDY0X2JpdHNfb2ZfZmxvYXQoYmEuZ2V0KGkpKSk7XG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IDg7IGorKykgd3JpdGVyLndyaXRlICg4LCBiW2pdKTtcbiAgICB9XG4gICAgYnJlYWs7XG4gIGNhc2UgMDogIC8vIEZsb2F0MzJBcnJheVxuICAgIGZvcih2YXIgaSA9IDA7IGkgPCBiYS5kYXRhLmxlbmd0aDsgaSsrKXtcbiAgICAgIHZhciBiID0gY2FtbF9pbnQzMl9iaXRzX29mX2Zsb2F0KGJhLmdldChpKSk7XG4gICAgICB3cml0ZXIud3JpdGUoMzIsIGIpO1xuICAgIH1cbiAgICBicmVhaztcbiAgY2FzZSAxMDogLy8gRmxvYXQzMkFycmF5IChjb21wbGV4MzIpXG4gICAgZm9yKHZhciBpID0gMDsgaSA8IGJhLmRhdGEubGVuZ3RoIC8gMjsgaSsrKXtcbiAgICAgIHZhciBqID0gYmEuZ2V0KGkpO1xuICAgICAgd3JpdGVyLndyaXRlKDMyLCBjYW1sX2ludDMyX2JpdHNfb2ZfZmxvYXQoalsxXSkpO1xuICAgICAgd3JpdGVyLndyaXRlKDMyLCBjYW1sX2ludDMyX2JpdHNfb2ZfZmxvYXQoalsyXSkpO1xuICAgIH1cbiAgICBicmVhaztcbiAgY2FzZSAxMTogLy8gRmxvYXQ2NEFycmF5IChjb21wbGV4NjQpXG4gICAgZm9yKHZhciBpID0gMDsgaSA8IGJhLmRhdGEubGVuZ3RoIC8gMjsgaSsrKXtcbiAgICAgIHZhciBjb21wbGV4ID0gYmEuZ2V0KGkpO1xuICAgICAgdmFyIGIgPSBjYW1sX2ludDY0X3RvX2J5dGVzKGNhbWxfaW50NjRfYml0c19vZl9mbG9hdChjb21wbGV4WzFdKSk7XG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IDg7IGorKykgd3JpdGVyLndyaXRlICg4LCBiW2pdKTtcbiAgICAgIHZhciBiID0gY2FtbF9pbnQ2NF90b19ieXRlcyhjYW1sX2ludDY0X2JpdHNfb2ZfZmxvYXQoY29tcGxleFsyXSkpO1xuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCA4OyBqKyspIHdyaXRlci53cml0ZSAoOCwgYltqXSk7XG4gICAgfVxuICAgIGJyZWFrO1xuICB9XG4gIHN6WzBdID0gKDQgKyBiYS5kaW1zLmxlbmd0aCkgKiA0O1xuICBzelsxXSA9ICg0ICsgYmEuZGltcy5sZW5ndGgpICogODtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iYV9kZXNlcmlhbGl6ZVxuLy9SZXF1aXJlczogY2FtbF9iYV9jcmVhdGVfdW5zYWZlLCBjYW1sX2ZhaWx3aXRoXG4vL1JlcXVpcmVzOiBjYW1sX2JhX2dldF9zaXplXG4vL1JlcXVpcmVzOiBjYW1sX2ludDY0X29mX2J5dGVzLCBjYW1sX2ludDY0X2Zsb2F0X29mX2JpdHNcbi8vUmVxdWlyZXM6IGNhbWxfaW50MzJfZmxvYXRfb2ZfYml0c1xuLy9SZXF1aXJlczogY2FtbF9iYV9jcmVhdGVfYnVmZmVyXG5mdW5jdGlvbiBjYW1sX2JhX2Rlc2VyaWFsaXplKHJlYWRlciwgc3osIG5hbWUpe1xuICB2YXIgbnVtX2RpbXMgPSByZWFkZXIucmVhZDMycygpO1xuICBpZiAobnVtX2RpbXMgPCAwIHx8IG51bV9kaW1zID4gMTYpXG4gICAgY2FtbF9mYWlsd2l0aChcImlucHV0X3ZhbHVlOiB3cm9uZyBudW1iZXIgb2YgYmlnYXJyYXkgZGltZW5zaW9uc1wiKTtcbiAgdmFyIHRhZyA9IHJlYWRlci5yZWFkMzJzKCk7XG4gIHZhciBraW5kID0gdGFnICYgMHhmZlxuICB2YXIgbGF5b3V0ID0gKHRhZyA+PiA4KSAmIDE7XG4gIHZhciBkaW1zID0gW11cbiAgaWYobmFtZSA9PSBcIl9iaWdhcnIwMlwiKVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbnVtX2RpbXM7IGkrKykge1xuICAgICAgdmFyIHNpemVfZGltID0gcmVhZGVyLnJlYWQxNnUoKTtcbiAgICAgIGlmKHNpemVfZGltID09IDB4ZmZmZil7XG4gICAgICAgIHZhciBzaXplX2RpbV9oaSA9IHJlYWRlci5yZWFkMzJ1KCk7XG4gICAgICAgIHZhciBzaXplX2RpbV9sbyA9IHJlYWRlci5yZWFkMzJ1KCk7XG4gICAgICAgIGlmKHNpemVfZGltX2hpICE9IDApXG4gICAgICAgICAgY2FtbF9mYWlsd2l0aChcImlucHV0X3ZhbHVlOiBiaWdhcnJheSBkaW1lbnNpb24gb3ZlcmZsb3cgaW4gMzJiaXRcIik7XG4gICAgICAgIHNpemVfZGltID0gc2l6ZV9kaW1fbG87XG4gICAgICB9XG4gICAgICBkaW1zLnB1c2goc2l6ZV9kaW0pO1xuICAgIH1cbiAgZWxzZVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbnVtX2RpbXM7IGkrKykgZGltcy5wdXNoKHJlYWRlci5yZWFkMzJ1KCkpO1xuICB2YXIgc2l6ZSA9IGNhbWxfYmFfZ2V0X3NpemUoZGltcyk7XG4gIHZhciBkYXRhID0gY2FtbF9iYV9jcmVhdGVfYnVmZmVyKGtpbmQsIHNpemUpO1xuICB2YXIgYmEgPSBjYW1sX2JhX2NyZWF0ZV91bnNhZmUoa2luZCwgbGF5b3V0LCBkaW1zLCBkYXRhKTtcbiAgc3dpdGNoKGtpbmQpe1xuICBjYXNlIDI6ICAvL0ludDhBcnJheVxuICAgIGZvcih2YXIgaSA9IDA7IGkgPCBzaXplOyBpKyspe1xuICAgICAgZGF0YVtpXSA9IHJlYWRlci5yZWFkOHMoKTtcbiAgICB9XG4gICAgYnJlYWs7XG4gIGNhc2UgMzogIC8vVWludDhBcnJheVxuICBjYXNlIDEyOiAvL1VpbnQ4QXJyYXlcbiAgICBmb3IodmFyIGkgPSAwOyBpIDwgc2l6ZTsgaSsrKXtcbiAgICAgIGRhdGFbaV0gPSByZWFkZXIucmVhZDh1KCk7XG4gICAgfVxuICAgIGJyZWFrO1xuICBjYXNlIDQ6ICAvLyBJbnQxNkFycmF5XG4gICAgZm9yKHZhciBpID0gMDsgaSA8IHNpemU7IGkrKyl7XG4gICAgICBkYXRhW2ldID0gcmVhZGVyLnJlYWQxNnMoKTtcbiAgICB9XG4gICAgYnJlYWs7XG4gIGNhc2UgNTogIC8vIFVpbnQxNkFycmF5XG4gICAgZm9yKHZhciBpID0gMDsgaSA8IHNpemU7IGkrKyl7XG4gICAgICBkYXRhW2ldID0gcmVhZGVyLnJlYWQxNnUoKTtcbiAgICB9XG4gICAgYnJlYWs7XG4gIGNhc2UgNjogIC8vIEludDMyQXJyYXkgKGludDMyKVxuICAgIGZvcih2YXIgaSA9IDA7IGkgPCBzaXplOyBpKyspe1xuICAgICAgZGF0YVtpXSA9IHJlYWRlci5yZWFkMzJzKCk7XG4gICAgfVxuICAgIGJyZWFrO1xuICBjYXNlIDg6ICAvLyBJbnQzMkFycmF5IChpbnQpXG4gIGNhc2UgOTogIC8vIEludDMyQXJyYXkgKG5hdGl2ZWludClcbiAgICB2YXIgc2l4dHkgPSByZWFkZXIucmVhZDh1KCk7XG4gICAgaWYoc2l4dHkpIGNhbWxfZmFpbHdpdGgoXCJpbnB1dF92YWx1ZTogY2Fubm90IHJlYWQgYmlnYXJyYXkgd2l0aCA2NC1iaXQgT0NhbWwgaW50c1wiKTtcbiAgICBmb3IodmFyIGkgPSAwOyBpIDwgc2l6ZTsgaSsrKXtcbiAgICAgIGRhdGFbaV0gPSByZWFkZXIucmVhZDMycygpO1xuICAgIH1cbiAgICBicmVhaztcbiAgY2FzZSA3OiAvLyAoaW50NjQpXG4gICAgdmFyIHQgPSBuZXcgQXJyYXkoOCk7O1xuICAgIGZvcih2YXIgaSA9IDA7IGkgPCBzaXplOyBpKyspe1xuICAgICAgZm9yICh2YXIgaiA9IDA7aiA8IDg7aisrKSB0W2pdID0gcmVhZGVyLnJlYWQ4dSgpO1xuICAgICAgdmFyIGludDY0ID0gY2FtbF9pbnQ2NF9vZl9ieXRlcyh0KTtcbiAgICAgIGJhLnNldChpLGludDY0KTtcbiAgICB9XG4gICAgYnJlYWs7XG4gIGNhc2UgMTogIC8vIEZsb2F0NjRBcnJheVxuICAgIHZhciB0ID0gbmV3IEFycmF5KDgpOztcbiAgICBmb3IodmFyIGkgPSAwOyBpIDwgc2l6ZTsgaSsrKXtcbiAgICAgIGZvciAodmFyIGogPSAwO2ogPCA4O2orKykgdFtqXSA9IHJlYWRlci5yZWFkOHUoKTtcbiAgICAgIHZhciBmID0gY2FtbF9pbnQ2NF9mbG9hdF9vZl9iaXRzKGNhbWxfaW50NjRfb2ZfYnl0ZXModCkpO1xuICAgICAgYmEuc2V0KGksZik7XG4gICAgfVxuICAgIGJyZWFrO1xuICBjYXNlIDA6ICAvLyBGbG9hdDMyQXJyYXlcbiAgICBmb3IodmFyIGkgPSAwOyBpIDwgc2l6ZTsgaSsrKXtcbiAgICAgIHZhciBmID0gY2FtbF9pbnQzMl9mbG9hdF9vZl9iaXRzKHJlYWRlci5yZWFkMzJzKCkpO1xuICAgICAgYmEuc2V0KGksZik7XG4gICAgfVxuICAgIGJyZWFrO1xuICBjYXNlIDEwOiAvLyBGbG9hdDMyQXJyYXkgKGNvbXBsZXgzMilcbiAgICBmb3IodmFyIGkgPSAwOyBpIDwgc2l6ZTsgaSsrKXtcbiAgICAgIHZhciByZSA9IGNhbWxfaW50MzJfZmxvYXRfb2ZfYml0cyhyZWFkZXIucmVhZDMycygpKTtcbiAgICAgIHZhciBpbSA9IGNhbWxfaW50MzJfZmxvYXRfb2ZfYml0cyhyZWFkZXIucmVhZDMycygpKTtcbiAgICAgIGJhLnNldChpLFsyNTQscmUsaW1dKTtcbiAgICB9XG4gICAgYnJlYWs7XG4gIGNhc2UgMTE6IC8vIEZsb2F0NjRBcnJheSAoY29tcGxleDY0KVxuICAgIHZhciB0ID0gbmV3IEFycmF5KDgpOztcbiAgICBmb3IodmFyIGkgPSAwOyBpIDwgc2l6ZTsgaSsrKXtcbiAgICAgIGZvciAodmFyIGogPSAwO2ogPCA4O2orKykgdFtqXSA9IHJlYWRlci5yZWFkOHUoKTtcbiAgICAgIHZhciByZSA9IGNhbWxfaW50NjRfZmxvYXRfb2ZfYml0cyhjYW1sX2ludDY0X29mX2J5dGVzKHQpKTtcbiAgICAgIGZvciAodmFyIGogPSAwO2ogPCA4O2orKykgdFtqXSA9IHJlYWRlci5yZWFkOHUoKTtcbiAgICAgIHZhciBpbSA9IGNhbWxfaW50NjRfZmxvYXRfb2ZfYml0cyhjYW1sX2ludDY0X29mX2J5dGVzKHQpKTtcbiAgICAgIGJhLnNldChpLFsyNTQscmUsaW1dKTtcbiAgICB9XG4gICAgYnJlYWtcbiAgfVxuICBzelswXSA9ICg0ICsgbnVtX2RpbXMpICogNDtcbiAgcmV0dXJuIGNhbWxfYmFfY3JlYXRlX3Vuc2FmZShraW5kLCBsYXlvdXQsIGRpbXMsIGRhdGEpO1xufVxuXG4vL0RlcHJlY2F0ZWRcbi8vUHJvdmlkZXM6IGNhbWxfYmFfY3JlYXRlX2Zyb21cbi8vUmVxdWlyZXM6IGNhbWxfYmFfY3JlYXRlX3Vuc2FmZSwgY2FtbF9pbnZhbGlkX2FyZ3VtZW50LCBjYW1sX2JhX2dldF9zaXplX3Blcl9lbGVtZW50XG5mdW5jdGlvbiBjYW1sX2JhX2NyZWF0ZV9mcm9tKGRhdGExLCBkYXRhMiwganN0eXAsIGtpbmQsIGxheW91dCwgZGltcyl7XG4gIGlmKGRhdGEyIHx8IGNhbWxfYmFfZ2V0X3NpemVfcGVyX2VsZW1lbnQoa2luZCkgPT0gMil7XG4gICAgY2FtbF9pbnZhbGlkX2FyZ3VtZW50KFwiY2FtbF9iYV9jcmVhdGVfZnJvbTogdXNlIHJldHVybiBjYW1sX2JhX2NyZWF0ZV91bnNhZmVcIik7XG4gIH1cbiAgcmV0dXJuIGNhbWxfYmFfY3JlYXRlX3Vuc2FmZShraW5kLCBsYXlvdXQsIGRpbXMsIGRhdGExKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iYV9oYXNoIGNvbnN0XG4vL1JlcXVpcmVzOiBjYW1sX2JhX2dldF9zaXplLCBjYW1sX2hhc2hfbWl4X2ludCwgY2FtbF9oYXNoX21peF9mbG9hdFxuZnVuY3Rpb24gY2FtbF9iYV9oYXNoKGJhKXtcbiAgdmFyIG51bV9lbHRzID0gY2FtbF9iYV9nZXRfc2l6ZShiYS5kaW1zKTtcbiAgdmFyIGggPSAwO1xuICBzd2l0Y2goYmEua2luZCl7XG4gIGNhc2UgMjogIC8vSW50OEFycmF5XG4gIGNhc2UgMzogIC8vVWludDhBcnJheVxuICBjYXNlIDEyOiAvL1VpbnQ4QXJyYXlcbiAgICBpZihudW1fZWx0cyA+IDI1NikgbnVtX2VsdHMgPSAyNTY7XG4gICAgdmFyIHcgPSAwLCBpID0wO1xuICAgIGZvcihpID0gMDsgaSArIDQgPD0gYmEuZGF0YS5sZW5ndGg7IGkrPTQpe1xuICAgICAgdyA9IGJhLmRhdGFbaSswXSB8IChiYS5kYXRhW2krMV0gPDwgOCkgfCAoYmEuZGF0YVtpKzJdIDw8IDE2KSB8IChiYS5kYXRhW2krM10gPDwgMjQpO1xuICAgICAgaCA9IGNhbWxfaGFzaF9taXhfaW50KGgsdyk7XG4gICAgfVxuICAgIHcgPSAwO1xuICAgIHN3aXRjaCAobnVtX2VsdHMgJiAzKSB7XG4gICAgY2FzZSAzOiB3ICA9IGJhLmRhdGFbaSsyXSA8PCAxNjsgICAgLyogZmFsbHRocm91Z2ggKi9cbiAgICBjYXNlIDI6IHcgfD0gYmEuZGF0YVtpKzFdIDw8IDg7ICAgICAvKiBmYWxsdGhyb3VnaCAqL1xuICAgIGNhc2UgMTogdyB8PSBiYS5kYXRhW2krMF07XG4gICAgICBoID0gY2FtbF9oYXNoX21peF9pbnQoaCwgdyk7XG4gICAgfVxuICAgIGJyZWFrO1xuICBjYXNlIDQ6ICAvLyBJbnQxNkFycmF5XG4gIGNhc2UgNTogIC8vIFVpbnQxNkFycmF5XG4gICAgaWYobnVtX2VsdHMgPiAxMjgpIG51bV9lbHRzID0gMTI4O1xuICAgIHZhciB3ID0gMCwgaSA9MDtcbiAgICBmb3IoaSA9IDA7IGkgKyAyIDw9IGJhLmRhdGEubGVuZ3RoOyBpKz0yKXtcbiAgICAgIHcgPSBiYS5kYXRhW2krMF0gfCAoYmEuZGF0YVtpKzFdIDw8IDE2KTtcbiAgICAgIGggPSBjYW1sX2hhc2hfbWl4X2ludChoLHcpO1xuICAgIH1cbiAgICBpZiAoKG51bV9lbHRzICYgMSkgIT0gMClcbiAgICAgIGggPSBjYW1sX2hhc2hfbWl4X2ludChoLCBiYS5kYXRhW2ldKTtcbiAgICBicmVhaztcbiAgY2FzZSA2OiAgLy8gSW50MzJBcnJheSAoaW50MzIpXG4gICAgaWYgKG51bV9lbHRzID4gNjQpIG51bV9lbHRzID0gNjQ7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBudW1fZWx0czsgaSsrKSBoID0gY2FtbF9oYXNoX21peF9pbnQoaCwgYmEuZGF0YVtpXSk7XG4gICAgYnJlYWs7XG4gIGNhc2UgODogIC8vIEludDMyQXJyYXkgKGludClcbiAgY2FzZSA5OiAgLy8gSW50MzJBcnJheSAobmF0aXZlaW50KVxuICAgIGlmIChudW1fZWx0cyA+IDY0KSBudW1fZWx0cyA9IDY0O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbnVtX2VsdHM7IGkrKykgaCA9IGNhbWxfaGFzaF9taXhfaW50KGgsIGJhLmRhdGFbaV0pO1xuICAgIGJyZWFrO1xuICBjYXNlIDc6ICAvLyBJbnQzMkFycmF5IChpbnQ2NClcbiAgICBpZiAobnVtX2VsdHMgPiAzMikgbnVtX2VsdHMgPSAzMjtcbiAgICBudW1fZWx0cyAqPSAyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBudW1fZWx0czsgaSsrKSB7XG4gICAgICBoID0gY2FtbF9oYXNoX21peF9pbnQoaCwgYmEuZGF0YVtpXSk7XG4gICAgfVxuICAgIGJyZWFrO1xuICBjYXNlIDEwOiAvLyBGbG9hdDMyQXJyYXkgKGNvbXBsZXgzMilcbiAgICBudW1fZWx0cyAqPTI7IC8qIGZhbGx0aHJvdWdoICovXG4gIGNhc2UgMDogIC8vIEZsb2F0MzJBcnJheVxuICAgIGlmIChudW1fZWx0cyA+IDY0KSBudW1fZWx0cyA9IDY0O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbnVtX2VsdHM7IGkrKykgaCA9IGNhbWxfaGFzaF9taXhfZmxvYXQoaCwgYmEuZGF0YVtpXSk7XG4gICAgYnJlYWs7XG4gIGNhc2UgMTE6IC8vIEZsb2F0NjRBcnJheSAoY29tcGxleDY0KVxuICAgIG51bV9lbHRzICo9MjsgLyogZmFsbHRocm91Z2ggKi9cbiAgY2FzZSAxOiAgLy8gRmxvYXQ2NEFycmF5XG4gICAgaWYgKG51bV9lbHRzID4gMzIpIG51bV9lbHRzID0gMzI7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBudW1fZWx0czsgaSsrKSBoID0gY2FtbF9oYXNoX21peF9mbG9hdChoLCBiYS5kYXRhW2ldKTtcbiAgICBicmVhaztcbiAgfVxuICByZXR1cm4gaDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iYV90b190eXBlZF9hcnJheSBtdXRhYmxlXG5mdW5jdGlvbiBjYW1sX2JhX3RvX3R5cGVkX2FycmF5KGJhKXtcbiAgcmV0dXJuIGJhLmRhdGE7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfYmFfa2luZF9vZl90eXBlZF9hcnJheSBtdXRhYmxlXG4vL1JlcXVpcmVzOiBjYW1sX2ludmFsaWRfYXJndW1lbnRcbmZ1bmN0aW9uIGNhbWxfYmFfa2luZF9vZl90eXBlZF9hcnJheSh0YSl7XG4gIHZhciBraW5kO1xuICBpZiAgICAgICh0YSBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSkga2luZCA9IDA7XG4gIGVsc2UgaWYgKHRhIGluc3RhbmNlb2YgRmxvYXQ2NEFycmF5KSBraW5kID0gMTtcbiAgZWxzZSBpZiAodGEgaW5zdGFuY2VvZiBJbnQ4QXJyYXkpIGtpbmQgPSAyO1xuICBlbHNlIGlmICh0YSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIGtpbmQgPSAzO1xuICBlbHNlIGlmICh0YSBpbnN0YW5jZW9mIFVpbnQ4Q2xhbXBlZEFycmF5KSBraW5kID0gMztcbiAgZWxzZSBpZiAodGEgaW5zdGFuY2VvZiBJbnQxNkFycmF5KSBraW5kID0gNDtcbiAgZWxzZSBpZiAodGEgaW5zdGFuY2VvZiBVaW50MTZBcnJheSkga2luZCA9IDU7XG4gIGVsc2UgaWYgKHRhIGluc3RhbmNlb2YgSW50MzJBcnJheSkga2luZCA9IDY7XG4gIGVsc2UgaWYgKHRhIGluc3RhbmNlb2YgVWludDMyQXJyYXkpIGtpbmQgPSA2O1xuICBlbHNlIGNhbWxfaW52YWxpZF9hcmd1bWVudChcImNhbWxfYmFfa2luZF9vZl90eXBlZF9hcnJheTogdW5zdXBwb3J0ZWQga2luZFwiKTtcbiAgcmV0dXJuIGtpbmQ7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfYmFfZnJvbV90eXBlZF9hcnJheSBtdXRhYmxlXG4vL1JlcXVpcmVzOiBjYW1sX2JhX2tpbmRfb2ZfdHlwZWRfYXJyYXlcbi8vUmVxdWlyZXM6IGNhbWxfYmFfY3JlYXRlX3Vuc2FmZVxuZnVuY3Rpb24gY2FtbF9iYV9mcm9tX3R5cGVkX2FycmF5KHRhKXtcbiAgdmFyIGtpbmQgPSBjYW1sX2JhX2tpbmRfb2ZfdHlwZWRfYXJyYXkodGEpO1xuICB2YXIgdGEgPVxuICAgICAgLyogTmVlZGVkIHRvIGF2b2lkIHVuc2lnbmVkIHNldHRlcnMgb3ZlcmZsb3dpbmdcbiAgICAgICAgIHRoZSByYW5nZSBvZiBPQ2FtbCBbaW50MzJdIHZhbHVlcy4gKi9cbiAgICAgIHRhIGluc3RhbmNlb2YgVWludDMyQXJyYXkgP1xuICAgICAgbmV3IEludDMyQXJyYXkodGEuYnVmZmVyICx0YS5ieXRlT2Zmc2V0LCB0YS5sZW5ndGgpIDogdGE7XG4gIHJldHVybiBjYW1sX2JhX2NyZWF0ZV91bnNhZmUoa2luZCwgMCwgW3RhLmxlbmd0aF0sIHRhKTtcbn1cbiIsIi8vIEpzX29mX29jYW1sIHJ1bnRpbWUgc3VwcG9ydFxuLy8gaHR0cDovL3d3dy5vY3NpZ2VuLm9yZy9qc19vZl9vY2FtbC9cbi8vIENvcHlyaWdodCAoQykgMjAxMCBKw6lyw7RtZSBWb3VpbGxvblxuLy8gTGFib3JhdG9pcmUgUFBTIC0gQ05SUyBVbml2ZXJzaXTDqSBQYXJpcyBEaWRlcm90XG4vL1xuLy8gVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbi8vIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuLy8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgd2l0aCBsaW5raW5nIGV4Y2VwdGlvbjtcbi8vIGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vXG4vLyBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4vLyBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2Vcbi8vIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLlxuXG4vL1Byb3ZpZGVzOiBjYW1sX21hcnNoYWxfY29uc3RhbnRzXG52YXIgY2FtbF9tYXJzaGFsX2NvbnN0YW50cyA9IHtcbiAgUFJFRklYX1NNQUxMX0JMT0NLOiAgICAgICAgIDB4ODAsXG4gIFBSRUZJWF9TTUFMTF9JTlQ6ICAgICAgICAgICAweDQwLFxuICBQUkVGSVhfU01BTExfU1RSSU5HOiAgICAgICAgMHgyMCxcbiAgQ09ERV9JTlQ4OiAgICAgICAgICAgICAgICAgIDB4MDAsXG4gIENPREVfSU5UMTY6ICAgICAgICAgICAgICAgICAweDAxLFxuICBDT0RFX0lOVDMyOiAgICAgICAgICAgICAgICAgMHgwMixcbiAgQ09ERV9JTlQ2NDogICAgICAgICAgICAgICAgIDB4MDMsXG4gIENPREVfU0hBUkVEODogICAgICAgICAgICAgICAweDA0LFxuICBDT0RFX1NIQVJFRDE2OiAgICAgICAgICAgICAgMHgwNSxcbiAgQ09ERV9TSEFSRUQzMjogICAgICAgICAgICAgIDB4MDYsXG4gIENPREVfQkxPQ0szMjogICAgICAgICAgICAgICAweDA4LFxuICBDT0RFX0JMT0NLNjQ6ICAgICAgICAgICAgICAgMHgxMyxcbiAgQ09ERV9TVFJJTkc4OiAgICAgICAgICAgICAgIDB4MDksXG4gIENPREVfU1RSSU5HMzI6ICAgICAgICAgICAgICAweDBBLFxuICBDT0RFX0RPVUJMRV9CSUc6ICAgICAgICAgICAgMHgwQixcbiAgQ09ERV9ET1VCTEVfTElUVExFOiAgICAgICAgIDB4MEMsXG4gIENPREVfRE9VQkxFX0FSUkFZOF9CSUc6ICAgICAweDBELFxuICBDT0RFX0RPVUJMRV9BUlJBWThfTElUVExFOiAgMHgwRSxcbiAgQ09ERV9ET1VCTEVfQVJSQVkzMl9CSUc6ICAgIDB4MEYsXG4gIENPREVfRE9VQkxFX0FSUkFZMzJfTElUVExFOiAweDA3LFxuICBDT0RFX0NPREVQT0lOVEVSOiAgICAgICAgICAgMHgxMCxcbiAgQ09ERV9JTkZJWFBPSU5URVI6ICAgICAgICAgIDB4MTEsXG4gIENPREVfQ1VTVE9NOiAgICAgICAgICAgICAgICAweDEyLFxuICBDT0RFX0NVU1RPTV9MRU46ICAgICAgICAgICAgMHgxOCxcbiAgQ09ERV9DVVNUT01fRklYRUQ6ICAgICAgICAgIDB4MTlcbn1cblxuXG4vL1Byb3ZpZGVzOiBVSW50OEFycmF5UmVhZGVyXG4vL1JlcXVpcmVzOiBjYW1sX3N0cmluZ19vZl9hcnJheSwgY2FtbF9qc2J5dGVzX29mX3N0cmluZ1xuZnVuY3Rpb24gVUludDhBcnJheVJlYWRlciAocywgaSkgeyB0aGlzLnMgPSBzOyB0aGlzLmkgPSBpOyB9XG5VSW50OEFycmF5UmVhZGVyLnByb3RvdHlwZSA9IHtcbiAgcmVhZDh1OmZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMuc1t0aGlzLmkrK107IH0sXG4gIHJlYWQ4czpmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzLnNbdGhpcy5pKytdIDw8IDI0ID4+IDI0OyB9LFxuICByZWFkMTZ1OmZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcyA9IHRoaXMucywgaSA9IHRoaXMuaTtcbiAgICB0aGlzLmkgPSBpICsgMjtcbiAgICByZXR1cm4gKHNbaV0gPDwgOCkgfCBzW2kgKyAxXVxuICB9LFxuICByZWFkMTZzOmZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcyA9IHRoaXMucywgaSA9IHRoaXMuaTtcbiAgICB0aGlzLmkgPSBpICsgMjtcbiAgICByZXR1cm4gKHNbaV0gPDwgMjQgPj4gMTYpIHwgc1tpICsgMV07XG4gIH0sXG4gIHJlYWQzMnU6ZnVuY3Rpb24gKCkge1xuICAgIHZhciBzID0gdGhpcy5zLCBpID0gdGhpcy5pO1xuICAgIHRoaXMuaSA9IGkgKyA0O1xuICAgIHJldHVybiAoKHNbaV0gPDwgMjQpIHwgKHNbaSsxXSA8PCAxNikgfFxuICAgICAgICAgICAgKHNbaSsyXSA8PCA4KSB8IHNbaSszXSkgPj4+IDA7XG4gIH0sXG4gIHJlYWQzMnM6ZnVuY3Rpb24gKCkge1xuICAgIHZhciBzID0gdGhpcy5zLCBpID0gdGhpcy5pO1xuICAgIHRoaXMuaSA9IGkgKyA0O1xuICAgIHJldHVybiAoc1tpXSA8PCAyNCkgfCAoc1tpKzFdIDw8IDE2KSB8XG4gICAgICAoc1tpKzJdIDw8IDgpIHwgc1tpKzNdO1xuICB9LFxuICByZWFkc3RyOmZ1bmN0aW9uIChsZW4pIHtcbiAgICB2YXIgaSA9IHRoaXMuaTtcbiAgICB0aGlzLmkgPSBpICsgbGVuO1xuICAgIHJldHVybiBjYW1sX3N0cmluZ19vZl9hcnJheSh0aGlzLnMuc3ViYXJyYXkoaSwgaSArIGxlbikpO1xuICB9LFxuICByZWFkdWludDhhcnJheTpmdW5jdGlvbiAobGVuKSB7XG4gICAgdmFyIGkgPSB0aGlzLmk7XG4gICAgdGhpcy5pID0gaSArIGxlbjtcbiAgICByZXR1cm4gdGhpcy5zLnN1YmFycmF5KGksIGkgKyBsZW4pO1xuICB9XG59XG5cblxuLy9Qcm92aWRlczogTWxTdHJpbmdSZWFkZXJcbi8vUmVxdWlyZXM6IGNhbWxfc3RyaW5nX29mX2pzYnl0ZXMsIGNhbWxfanNieXRlc19vZl9zdHJpbmdcbmZ1bmN0aW9uIE1sU3RyaW5nUmVhZGVyIChzLCBpKSB7IHRoaXMucyA9IGNhbWxfanNieXRlc19vZl9zdHJpbmcocyk7IHRoaXMuaSA9IGk7IH1cbk1sU3RyaW5nUmVhZGVyLnByb3RvdHlwZSA9IHtcbiAgcmVhZDh1OmZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMucy5jaGFyQ29kZUF0KHRoaXMuaSsrKTsgfSxcbiAgcmVhZDhzOmZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMucy5jaGFyQ29kZUF0KHRoaXMuaSsrKSA8PCAyNCA+PiAyNDsgfSxcbiAgcmVhZDE2dTpmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHMgPSB0aGlzLnMsIGkgPSB0aGlzLmk7XG4gICAgdGhpcy5pID0gaSArIDI7XG4gICAgcmV0dXJuIChzLmNoYXJDb2RlQXQoaSkgPDwgOCkgfCBzLmNoYXJDb2RlQXQoaSArIDEpXG4gIH0sXG4gIHJlYWQxNnM6ZnVuY3Rpb24gKCkge1xuICAgIHZhciBzID0gdGhpcy5zLCBpID0gdGhpcy5pO1xuICAgIHRoaXMuaSA9IGkgKyAyO1xuICAgIHJldHVybiAocy5jaGFyQ29kZUF0KGkpIDw8IDI0ID4+IDE2KSB8IHMuY2hhckNvZGVBdChpICsgMSk7XG4gIH0sXG4gIHJlYWQzMnU6ZnVuY3Rpb24gKCkge1xuICAgIHZhciBzID0gdGhpcy5zLCBpID0gdGhpcy5pO1xuICAgIHRoaXMuaSA9IGkgKyA0O1xuICAgIHJldHVybiAoKHMuY2hhckNvZGVBdChpKSA8PCAyNCkgfCAocy5jaGFyQ29kZUF0KGkrMSkgPDwgMTYpIHxcbiAgICAgICAgICAgIChzLmNoYXJDb2RlQXQoaSsyKSA8PCA4KSB8IHMuY2hhckNvZGVBdChpKzMpKSA+Pj4gMDtcbiAgfSxcbiAgcmVhZDMyczpmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHMgPSB0aGlzLnMsIGkgPSB0aGlzLmk7XG4gICAgdGhpcy5pID0gaSArIDQ7XG4gICAgcmV0dXJuIChzLmNoYXJDb2RlQXQoaSkgPDwgMjQpIHwgKHMuY2hhckNvZGVBdChpKzEpIDw8IDE2KSB8XG4gICAgICAocy5jaGFyQ29kZUF0KGkrMikgPDwgOCkgfCBzLmNoYXJDb2RlQXQoaSszKTtcbiAgfSxcbiAgcmVhZHN0cjpmdW5jdGlvbiAobGVuKSB7XG4gICAgdmFyIGkgPSB0aGlzLmk7XG4gICAgdGhpcy5pID0gaSArIGxlbjtcbiAgICByZXR1cm4gY2FtbF9zdHJpbmdfb2ZfanNieXRlcyh0aGlzLnMuc3Vic3RyaW5nKGksIGkgKyBsZW4pKTtcbiAgfSxcbiAgcmVhZHVpbnQ4YXJyYXk6ZnVuY3Rpb24gKGxlbikge1xuICAgIHZhciBiID0gbmV3IFVpbnQ4QXJyYXkobGVuKTtcbiAgICB2YXIgcyA9IHRoaXMucztcbiAgICB2YXIgaSA9IHRoaXMuaTtcbiAgICBmb3IodmFyIGogPSAwOyBqIDwgbGVuOyBqKyspIHtcbiAgICAgIGJbal0gPSBzLmNoYXJDb2RlQXQoaSArIGopO1xuICAgIH1cbiAgICB0aGlzLmkgPSBpICsgbGVuO1xuICAgIHJldHVybiBiO1xuICB9XG59XG5cbi8vUHJvdmlkZXM6IEJpZ1N0cmluZ1JlYWRlclxuLy9SZXF1aXJlczogY2FtbF9zdHJpbmdfb2ZfYXJyYXksIGNhbWxfYmFfZ2V0XzFcbmZ1bmN0aW9uIEJpZ1N0cmluZ1JlYWRlciAoYnMsIGkpIHsgdGhpcy5zID0gYnM7IHRoaXMuaSA9IGk7IH1cbkJpZ1N0cmluZ1JlYWRlci5wcm90b3R5cGUgPSB7XG4gIHJlYWQ4dTpmdW5jdGlvbiAoKSB7IHJldHVybiBjYW1sX2JhX2dldF8xKHRoaXMucyx0aGlzLmkrKyk7IH0sXG4gIHJlYWQ4czpmdW5jdGlvbiAoKSB7IHJldHVybiBjYW1sX2JhX2dldF8xKHRoaXMucyx0aGlzLmkrKykgPDwgMjQgPj4gMjQ7IH0sXG4gIHJlYWQxNnU6ZnVuY3Rpb24gKCkge1xuICAgIHZhciBzID0gdGhpcy5zLCBpID0gdGhpcy5pO1xuICAgIHRoaXMuaSA9IGkgKyAyO1xuICAgIHJldHVybiAoY2FtbF9iYV9nZXRfMShzLGkpIDw8IDgpIHwgY2FtbF9iYV9nZXRfMShzLGkgKyAxKVxuICB9LFxuICByZWFkMTZzOmZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcyA9IHRoaXMucywgaSA9IHRoaXMuaTtcbiAgICB0aGlzLmkgPSBpICsgMjtcbiAgICByZXR1cm4gKGNhbWxfYmFfZ2V0XzEocyxpKSA8PCAyNCA+PiAxNikgfCBjYW1sX2JhX2dldF8xKHMsaSArIDEpO1xuICB9LFxuICByZWFkMzJ1OmZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcyA9IHRoaXMucywgaSA9IHRoaXMuaTtcbiAgICB0aGlzLmkgPSBpICsgNDtcbiAgICByZXR1cm4gKChjYW1sX2JhX2dldF8xKHMsaSkgICA8PCAyNCkgfCAoY2FtbF9iYV9nZXRfMShzLGkrMSkgPDwgMTYpIHxcbiAgICAgICAgICAgIChjYW1sX2JhX2dldF8xKHMsaSsyKSA8PCA4KSAgfCBjYW1sX2JhX2dldF8xKHMsaSszKSAgICAgICAgICkgPj4+IDA7XG4gIH0sXG4gIHJlYWQzMnM6ZnVuY3Rpb24gKCkge1xuICAgIHZhciBzID0gdGhpcy5zLCBpID0gdGhpcy5pO1xuICAgIHRoaXMuaSA9IGkgKyA0O1xuICAgIHJldHVybiAoY2FtbF9iYV9nZXRfMShzLGkpICAgPDwgMjQpIHwgKGNhbWxfYmFfZ2V0XzEocyxpKzEpIDw8IDE2KSB8XG4gICAgICAoY2FtbF9iYV9nZXRfMShzLGkrMikgPDwgOCkgIHwgY2FtbF9iYV9nZXRfMShzLGkrMyk7XG4gIH0sXG4gIHJlYWRzdHI6ZnVuY3Rpb24gKGxlbikge1xuICAgIHZhciBpID0gdGhpcy5pO1xuICAgIHZhciBhcnIgPSBuZXcgQXJyYXkobGVuKVxuICAgIGZvcih2YXIgaiA9IDA7IGogPCBsZW47IGorKyl7XG4gICAgICBhcnJbal0gPSBjYW1sX2JhX2dldF8xKHRoaXMucywgaStqKTtcbiAgICB9XG4gICAgdGhpcy5pID0gaSArIGxlbjtcbiAgICByZXR1cm4gY2FtbF9zdHJpbmdfb2ZfYXJyYXkoYXJyKTtcbiAgfSxcbiAgcmVhZHVpbnQ4YXJyYXk6ZnVuY3Rpb24gKGxlbikge1xuICAgIHZhciBpID0gdGhpcy5pO1xuICAgIHZhciBvZmZzZXQgPSB0aGlzLm9mZnNldChpKTtcbiAgICB0aGlzLmkgPSBpICsgbGVuO1xuICAgIHJldHVybiB0aGlzLnMuZGF0YS5zdWJhcnJheShvZmZzZXQsIG9mZnNldCArIGxlbik7XG4gIH1cbn1cblxuXG5cbi8vUHJvdmlkZXM6IGNhbWxfZmxvYXRfb2ZfYnl0ZXNcbi8vUmVxdWlyZXM6IGNhbWxfaW50NjRfZmxvYXRfb2ZfYml0cywgY2FtbF9pbnQ2NF9vZl9ieXRlc1xuZnVuY3Rpb24gY2FtbF9mbG9hdF9vZl9ieXRlcyAoYSkge1xuICByZXR1cm4gY2FtbF9pbnQ2NF9mbG9hdF9vZl9iaXRzIChjYW1sX2ludDY0X29mX2J5dGVzIChhKSk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfaW5wdXRfdmFsdWVfZnJvbV9zdHJpbmcgbXV0YWJsZVxuLy9SZXF1aXJlczogTWxTdHJpbmdSZWFkZXIsIGNhbWxfaW5wdXRfdmFsdWVfZnJvbV9yZWFkZXJcbmZ1bmN0aW9uIGNhbWxfaW5wdXRfdmFsdWVfZnJvbV9zdHJpbmcocyxvZnMpIHtcbiAgdmFyIHJlYWRlciA9IG5ldyBNbFN0cmluZ1JlYWRlciAocywgdHlwZW9mIG9mcz09XCJudW1iZXJcIj9vZnM6b2ZzWzBdKTtcbiAgcmV0dXJuIGNhbWxfaW5wdXRfdmFsdWVfZnJvbV9yZWFkZXIocmVhZGVyLCBvZnMpXG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfaW5wdXRfdmFsdWVfZnJvbV9ieXRlcyBtdXRhYmxlXG4vL1JlcXVpcmVzOiBNbFN0cmluZ1JlYWRlciwgY2FtbF9pbnB1dF92YWx1ZV9mcm9tX3JlYWRlciwgY2FtbF9zdHJpbmdfb2ZfYnl0ZXNcbmZ1bmN0aW9uIGNhbWxfaW5wdXRfdmFsdWVfZnJvbV9ieXRlcyhzLG9mcykge1xuICB2YXIgcmVhZGVyID0gbmV3IE1sU3RyaW5nUmVhZGVyIChjYW1sX3N0cmluZ19vZl9ieXRlcyhzKSwgdHlwZW9mIG9mcz09XCJudW1iZXJcIj9vZnM6b2ZzWzBdKTtcbiAgcmV0dXJuIGNhbWxfaW5wdXRfdmFsdWVfZnJvbV9yZWFkZXIocmVhZGVyLCBvZnMpXG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfaW50NjRfdW5tYXJzaGFsXG4vL1JlcXVpcmVzOiBjYW1sX2ludDY0X29mX2J5dGVzXG5mdW5jdGlvbiBjYW1sX2ludDY0X3VubWFyc2hhbChyZWFkZXIsIHNpemUpe1xuICB2YXIgdCA9IG5ldyBBcnJheSg4KTs7XG4gIGZvciAodmFyIGogPSAwO2ogPCA4O2orKykgdFtqXSA9IHJlYWRlci5yZWFkOHUoKTtcbiAgc2l6ZVswXSA9IDg7XG4gIHJldHVybiBjYW1sX2ludDY0X29mX2J5dGVzICh0KTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9pbnQ2NF9tYXJzaGFsXG4vL1JlcXVpcmVzOiBjYW1sX2ludDY0X3RvX2J5dGVzXG5mdW5jdGlvbiBjYW1sX2ludDY0X21hcnNoYWwod3JpdGVyLCB2LCBzaXplcykge1xuICB2YXIgYiA9IGNhbWxfaW50NjRfdG9fYnl0ZXMgKHYpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IDg7IGkrKykgd3JpdGVyLndyaXRlICg4LCBiW2ldKTtcbiAgc2l6ZXNbMF0gPSA4OyBzaXplc1sxXSA9IDg7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfaW50MzJfdW5tYXJzaGFsXG5mdW5jdGlvbiBjYW1sX2ludDMyX3VubWFyc2hhbChyZWFkZXIsIHNpemUpe1xuICBzaXplWzBdID0gNDtcbiAgcmV0dXJuIHJlYWRlci5yZWFkMzJzICgpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX25hdGl2ZWludF91bm1hcnNoYWxcbi8vUmVxdWlyZXM6IGNhbWxfZmFpbHdpdGhcbmZ1bmN0aW9uIGNhbWxfbmF0aXZlaW50X3VubWFyc2hhbChyZWFkZXIsIHNpemUpe1xuICBzd2l0Y2ggKHJlYWRlci5yZWFkOHUgKCkpIHtcbiAgY2FzZSAxOlxuICAgIHNpemVbMF0gPSA0O1xuICAgIHJldHVybiByZWFkZXIucmVhZDMycyAoKTtcbiAgY2FzZSAyOlxuICAgIGNhbWxfZmFpbHdpdGgoXCJpbnB1dF92YWx1ZTogbmF0aXZlIGludGVnZXIgdmFsdWUgdG9vIGxhcmdlXCIpO1xuICBkZWZhdWx0OiBjYW1sX2ZhaWx3aXRoKFwiaW5wdXRfdmFsdWU6IGlsbC1mb3JtZWQgbmF0aXZlIGludGVnZXJcIik7XG4gIH1cbn1cblxuLy9Qcm92aWRlczogY2FtbF9jdXN0b21fb3BzXG4vL1JlcXVpcmVzOiBjYW1sX2ludDY0X3VubWFyc2hhbCwgY2FtbF9pbnQ2NF9tYXJzaGFsLCBjYW1sX2ludDY0X2NvbXBhcmUsIGNhbWxfaW50NjRfaGFzaFxuLy9SZXF1aXJlczogY2FtbF9pbnQzMl91bm1hcnNoYWwsIGNhbWxfbmF0aXZlaW50X3VubWFyc2hhbFxuLy9SZXF1aXJlczogY2FtbF9iYV9zZXJpYWxpemUsIGNhbWxfYmFfZGVzZXJpYWxpemUsIGNhbWxfYmFfY29tcGFyZSwgY2FtbF9iYV9oYXNoXG52YXIgY2FtbF9jdXN0b21fb3BzID1cbiAgICB7XCJfalwiOiB7XG4gICAgICBkZXNlcmlhbGl6ZSA6IGNhbWxfaW50NjRfdW5tYXJzaGFsLFxuICAgICAgc2VyaWFsaXplICA6IGNhbWxfaW50NjRfbWFyc2hhbCxcbiAgICAgIGZpeGVkX2xlbmd0aCA6IDgsXG4gICAgICBjb21wYXJlIDogY2FtbF9pbnQ2NF9jb21wYXJlLFxuICAgICAgaGFzaCA6IGNhbWxfaW50NjRfaGFzaFxuICAgIH0sXG4gICAgIFwiX2lcIjoge1xuICAgICAgIGRlc2VyaWFsaXplIDogY2FtbF9pbnQzMl91bm1hcnNoYWwsXG4gICAgICAgZml4ZWRfbGVuZ3RoIDogNCxcbiAgICAgfSxcbiAgICAgXCJfblwiOiB7XG4gICAgICAgZGVzZXJpYWxpemUgOiBjYW1sX25hdGl2ZWludF91bm1hcnNoYWwsXG4gICAgICAgZml4ZWRfbGVuZ3RoIDogNCxcbiAgICAgfSxcbiAgICAgXCJfYmlnYXJyYXlcIjp7XG4gICAgICAgZGVzZXJpYWxpemUgOiAoZnVuY3Rpb24gKHJlYWRlciwgc3opIHtyZXR1cm4gY2FtbF9iYV9kZXNlcmlhbGl6ZSAocmVhZGVyLHN6LFwiX2JpZ2FycmF5XCIpfSksXG4gICAgICAgc2VyaWFsaXplIDogY2FtbF9iYV9zZXJpYWxpemUsXG4gICAgICAgY29tcGFyZSA6IGNhbWxfYmFfY29tcGFyZSxcbiAgICAgICBoYXNoOiBjYW1sX2JhX2hhc2gsXG4gICAgIH0sXG4gICAgIFwiX2JpZ2FycjAyXCI6e1xuICAgICAgIGRlc2VyaWFsaXplIDogKGZ1bmN0aW9uIChyZWFkZXIsIHN6KSB7cmV0dXJuIGNhbWxfYmFfZGVzZXJpYWxpemUgKHJlYWRlcixzeixcIl9iaWdhcnIwMlwiKX0pLFxuICAgICAgIHNlcmlhbGl6ZSA6IGNhbWxfYmFfc2VyaWFsaXplLFxuICAgICAgIGNvbXBhcmUgOiBjYW1sX2JhX2NvbXBhcmUsXG4gICAgICAgaGFzaDogY2FtbF9iYV9oYXNoLFxuICAgICB9XG4gICAgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2lucHV0X3ZhbHVlX2Zyb21fcmVhZGVyIG11dGFibGVcbi8vUmVxdWlyZXM6IGNhbWxfZmFpbHdpdGhcbi8vUmVxdWlyZXM6IGNhbWxfZmxvYXRfb2ZfYnl0ZXMsIGNhbWxfY3VzdG9tX29wc1xuLy9SZXF1aXJlczogVUludDhBcnJheVJlYWRlclxuLy9SZXF1aXJlczogY2FtbF9kZWNvbXByZXNzX2lucHV0XG5mdW5jdGlvbiBjYW1sX2lucHV0X3ZhbHVlX2Zyb21fcmVhZGVyKHJlYWRlciwgb2ZzKSB7XG4gIGZ1bmN0aW9uIHJlYWR2bHEob3ZlcmZsb3cpIHtcbiAgICB2YXIgYyA9IHJlYWRlci5yZWFkOHUoKTtcbiAgICB2YXIgbiA9IGMgJiAweDdGO1xuICAgIHdoaWxlICgoYyAmIDB4ODApICE9IDApIHtcbiAgICAgIGMgPSByZWFkZXIucmVhZDh1KCk7XG4gICAgICB2YXIgbjcgPSBuIDw8IDc7XG4gICAgICBpZiAobiAhPSBuNyA+PiA3KSBvdmVyZmxvd1swXSA9IHRydWU7XG4gICAgICBuID0gbjcgfCAoYyAmIDB4N0YpO1xuICAgIH1cbiAgICByZXR1cm4gbjtcbiAgfVxuICB2YXIgbWFnaWMgPSByZWFkZXIucmVhZDMydSAoKVxuICBzd2l0Y2gobWFnaWMpe1xuICBjYXNlIDB4ODQ5NUE2QkU6IC8qIEludGV4dF9tYWdpY19udW1iZXJfc21hbGwgKi9cbiAgICB2YXIgaGVhZGVyX2xlbiA9IDIwO1xuICAgIHZhciBjb21wcmVzc2VkID0gMDtcbiAgICB2YXIgZGF0YV9sZW4gPSByZWFkZXIucmVhZDMydSAoKTtcbiAgICB2YXIgdW5jb21wcmVzc2VkX2RhdGFfbGVuID0gZGF0YV9sZW47XG4gICAgdmFyIG51bV9vYmplY3RzID0gcmVhZGVyLnJlYWQzMnUgKCk7XG4gICAgdmFyIF9zaXplXzMyID0gcmVhZGVyLnJlYWQzMnUgKCk7XG4gICAgdmFyIF9zaXplXzY0ID0gcmVhZGVyLnJlYWQzMnUgKCk7XG4gICAgYnJlYWtcbiAgY2FzZSAweDg0OTVBNkJEOiAvKiBJbnRleHRfbWFnaWNfbnVtYmVyX2NvbXByZXNzZWQgKi9cbiAgICB2YXIgaGVhZGVyX2xlbiA9IHJlYWRlci5yZWFkOHUoKSAmIDB4M0Y7XG4gICAgdmFyIGNvbXByZXNzZWQgPSAxO1xuICAgIHZhciBvdmVyZmxvdyA9IFtmYWxzZV07XG4gICAgdmFyIGRhdGFfbGVuID0gcmVhZHZscShvdmVyZmxvdyk7XG4gICAgdmFyIHVuY29tcHJlc3NlZF9kYXRhX2xlbiA9IHJlYWR2bHEob3ZlcmZsb3cpO1xuICAgIHZhciBudW1fb2JqZWN0cyA9IHJlYWR2bHEob3ZlcmZsb3cpO1xuICAgIHZhciBfc2l6ZV8zMiA9IHJlYWR2bHEgKG92ZXJmbG93KTtcbiAgICB2YXIgX3NpemVfNjQgPSByZWFkdmxxIChvdmVyZmxvdyk7XG4gICAgaWYob3ZlcmZsb3dbMF0pe1xuICAgICAgICBjYW1sX2ZhaWx3aXRoKFwiY2FtbF9pbnB1dF92YWx1ZV9mcm9tX3JlYWRlcjogb2JqZWN0IHRvbyBsYXJnZSB0byBiZSByZWFkIGJhY2sgb24gdGhpcyBwbGF0Zm9ybVwiKTtcbiAgICB9XG4gICAgYnJlYWtcbiAgY2FzZSAweDg0OTVBNkJGOiAvKiBJbnRleHRfbWFnaWNfbnVtYmVyX2JpZyAqL1xuICAgIGNhbWxfZmFpbHdpdGgoXCJjYW1sX2lucHV0X3ZhbHVlX2Zyb21fcmVhZGVyOiBvYmplY3QgdG9vIGxhcmdlIHRvIGJlIHJlYWQgYmFjayBvbiBhIDMyLWJpdCBwbGF0Zm9ybVwiKTtcbiAgICBicmVha1xuICBkZWZhdWx0OlxuICAgIGNhbWxfZmFpbHdpdGgoXCJjYW1sX2lucHV0X3ZhbHVlX2Zyb21fcmVhZGVyOiBiYWQgb2JqZWN0XCIpO1xuICAgIGJyZWFrO1xuICB9XG4gIHZhciBzdGFjayA9IFtdO1xuICB2YXIgaW50ZXJuX29ial90YWJsZSA9IChudW1fb2JqZWN0cyA+IDApP1tdOm51bGw7XG4gIHZhciBvYmpfY291bnRlciA9IDA7XG4gIGZ1bmN0aW9uIGludGVybl9yZWMgKHJlYWRlcikge1xuICAgIHZhciBjb2RlID0gcmVhZGVyLnJlYWQ4dSAoKTtcbiAgICBpZiAoY29kZSA+PSAweDQwIC8qY3N0LlBSRUZJWF9TTUFMTF9JTlQqLykge1xuICAgICAgaWYgKGNvZGUgPj0gMHg4MCAvKmNzdC5QUkVGSVhfU01BTExfQkxPQ0sqLykge1xuICAgICAgICB2YXIgdGFnID0gY29kZSAmIDB4RjtcbiAgICAgICAgdmFyIHNpemUgPSAoY29kZSA+PiA0KSAmIDB4NztcbiAgICAgICAgdmFyIHYgPSBbdGFnXTtcbiAgICAgICAgaWYgKHNpemUgPT0gMCkgcmV0dXJuIHY7XG4gICAgICAgIGlmIChpbnRlcm5fb2JqX3RhYmxlKSBpbnRlcm5fb2JqX3RhYmxlW29ial9jb3VudGVyKytdID0gdjtcbiAgICAgICAgc3RhY2sucHVzaCh2LCBzaXplKTtcbiAgICAgICAgcmV0dXJuIHY7XG4gICAgICB9IGVsc2VcbiAgICAgICAgcmV0dXJuIChjb2RlICYgMHgzRik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChjb2RlID49IDB4MjAvKmNzdC5QUkVGSVhfU01BTExfU1RSSU5HICovKSB7XG4gICAgICAgIHZhciBsZW4gPSBjb2RlICYgMHgxRjtcbiAgICAgICAgdmFyIHYgPSByZWFkZXIucmVhZHN0ciAobGVuKTtcbiAgICAgICAgaWYgKGludGVybl9vYmpfdGFibGUpIGludGVybl9vYmpfdGFibGVbb2JqX2NvdW50ZXIrK10gPSB2O1xuICAgICAgICByZXR1cm4gdjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN3aXRjaChjb2RlKSB7XG4gICAgICAgIGNhc2UgMHgwMDogLy9jc3QuQ09ERV9JTlQ4OlxuICAgICAgICAgIHJldHVybiByZWFkZXIucmVhZDhzICgpO1xuICAgICAgICBjYXNlIDB4MDE6IC8vY3N0LkNPREVfSU5UMTY6XG4gICAgICAgICAgcmV0dXJuIHJlYWRlci5yZWFkMTZzICgpO1xuICAgICAgICBjYXNlIDB4MDI6IC8vY3N0LkNPREVfSU5UMzI6XG4gICAgICAgICAgcmV0dXJuIHJlYWRlci5yZWFkMzJzICgpO1xuICAgICAgICBjYXNlIDB4MDM6IC8vY3N0LkNPREVfSU5UNjQ6XG4gICAgICAgICAgY2FtbF9mYWlsd2l0aChcImlucHV0X3ZhbHVlOiBpbnRlZ2VyIHRvbyBsYXJnZVwiKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAweDA0OiAvL2NzdC5DT0RFX1NIQVJFRDg6XG4gICAgICAgICAgdmFyIG9mZnNldCA9IHJlYWRlci5yZWFkOHUgKCk7XG4gICAgICAgICAgaWYoY29tcHJlc3NlZCA9PSAwKSBvZmZzZXQgPSBvYmpfY291bnRlciAtIG9mZnNldDtcbiAgICAgICAgICByZXR1cm4gaW50ZXJuX29ial90YWJsZVtvZmZzZXRdO1xuICAgICAgICBjYXNlIDB4MDU6IC8vY3N0LkNPREVfU0hBUkVEMTY6XG4gICAgICAgICAgdmFyIG9mZnNldCA9IHJlYWRlci5yZWFkMTZ1ICgpO1xuICAgICAgICAgIGlmKGNvbXByZXNzZWQgPT0gMCkgb2Zmc2V0ID0gb2JqX2NvdW50ZXIgLSBvZmZzZXQ7XG4gICAgICAgICAgcmV0dXJuIGludGVybl9vYmpfdGFibGVbb2Zmc2V0XTtcbiAgICAgICAgY2FzZSAweDA2OiAvL2NzdC5DT0RFX1NIQVJFRDMyOlxuICAgICAgICAgIHZhciBvZmZzZXQgPSByZWFkZXIucmVhZDMydSAoKTtcbiAgICAgICAgICBpZihjb21wcmVzc2VkID09IDApIG9mZnNldCA9IG9ial9jb3VudGVyIC0gb2Zmc2V0O1xuICAgICAgICAgIHJldHVybiBpbnRlcm5fb2JqX3RhYmxlW29mZnNldF07XG4gICAgICAgIGNhc2UgMHgwODogLy9jc3QuQ09ERV9CTE9DSzMyOlxuICAgICAgICAgIHZhciBoZWFkZXIgPSByZWFkZXIucmVhZDMydSAoKTtcbiAgICAgICAgICB2YXIgdGFnID0gaGVhZGVyICYgMHhGRjtcbiAgICAgICAgICB2YXIgc2l6ZSA9IGhlYWRlciA+PiAxMDtcbiAgICAgICAgICB2YXIgdiA9IFt0YWddO1xuICAgICAgICAgIGlmIChzaXplID09IDApIHJldHVybiB2O1xuICAgICAgICAgIGlmIChpbnRlcm5fb2JqX3RhYmxlKSBpbnRlcm5fb2JqX3RhYmxlW29ial9jb3VudGVyKytdID0gdjtcbiAgICAgICAgICBzdGFjay5wdXNoKHYsIHNpemUpO1xuICAgICAgICAgIHJldHVybiB2O1xuICAgICAgICBjYXNlIDB4MTM6IC8vY3N0LkNPREVfQkxPQ0s2NDpcbiAgICAgICAgICBjYW1sX2ZhaWx3aXRoIChcImlucHV0X3ZhbHVlOiBkYXRhIGJsb2NrIHRvbyBsYXJnZVwiKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAweDA5OiAvL2NzdC5DT0RFX1NUUklORzg6XG4gICAgICAgICAgdmFyIGxlbiA9IHJlYWRlci5yZWFkOHUoKTtcbiAgICAgICAgICB2YXIgdiA9IHJlYWRlci5yZWFkc3RyIChsZW4pO1xuICAgICAgICAgIGlmIChpbnRlcm5fb2JqX3RhYmxlKSBpbnRlcm5fb2JqX3RhYmxlW29ial9jb3VudGVyKytdID0gdjtcbiAgICAgICAgICByZXR1cm4gdjtcbiAgICAgICAgY2FzZSAweDBBOiAvL2NzdC5DT0RFX1NUUklORzMyOlxuICAgICAgICAgIHZhciBsZW4gPSByZWFkZXIucmVhZDMydSgpO1xuICAgICAgICAgIHZhciB2ID0gcmVhZGVyLnJlYWRzdHIgKGxlbik7XG4gICAgICAgICAgaWYgKGludGVybl9vYmpfdGFibGUpIGludGVybl9vYmpfdGFibGVbb2JqX2NvdW50ZXIrK10gPSB2O1xuICAgICAgICAgIHJldHVybiB2O1xuICAgICAgICBjYXNlIDB4MEM6IC8vY3N0LkNPREVfRE9VQkxFX0xJVFRMRTpcbiAgICAgICAgICB2YXIgdCA9IG5ldyBBcnJheSg4KTs7XG4gICAgICAgICAgZm9yICh2YXIgaSA9IDA7aSA8IDg7aSsrKSB0WzcgLSBpXSA9IHJlYWRlci5yZWFkOHUgKCk7XG4gICAgICAgICAgdmFyIHYgPSBjYW1sX2Zsb2F0X29mX2J5dGVzICh0KTtcbiAgICAgICAgICBpZiAoaW50ZXJuX29ial90YWJsZSkgaW50ZXJuX29ial90YWJsZVtvYmpfY291bnRlcisrXSA9IHY7XG4gICAgICAgICAgcmV0dXJuIHY7XG4gICAgICAgIGNhc2UgMHgwQjogLy9jc3QuQ09ERV9ET1VCTEVfQklHOlxuICAgICAgICAgIHZhciB0ID0gbmV3IEFycmF5KDgpOztcbiAgICAgICAgICBmb3IgKHZhciBpID0gMDtpIDwgODtpKyspIHRbaV0gPSByZWFkZXIucmVhZDh1ICgpO1xuICAgICAgICAgIHZhciB2ID0gY2FtbF9mbG9hdF9vZl9ieXRlcyAodCk7XG4gICAgICAgICAgaWYgKGludGVybl9vYmpfdGFibGUpIGludGVybl9vYmpfdGFibGVbb2JqX2NvdW50ZXIrK10gPSB2O1xuICAgICAgICAgIHJldHVybiB2O1xuICAgICAgICBjYXNlIDB4MEU6IC8vY3N0LkNPREVfRE9VQkxFX0FSUkFZOF9MSVRUTEU6XG4gICAgICAgICAgdmFyIGxlbiA9IHJlYWRlci5yZWFkOHUoKTtcbiAgICAgICAgICB2YXIgdiA9IG5ldyBBcnJheShsZW4rMSk7XG4gICAgICAgICAgdlswXSA9IDI1NDtcbiAgICAgICAgICB2YXIgdCA9IG5ldyBBcnJheSg4KTs7XG4gICAgICAgICAgaWYgKGludGVybl9vYmpfdGFibGUpIGludGVybl9vYmpfdGFibGVbb2JqX2NvdW50ZXIrK10gPSB2O1xuICAgICAgICAgIGZvciAodmFyIGkgPSAxO2kgPD0gbGVuO2krKykge1xuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7aiA8IDg7aisrKSB0WzcgLSBqXSA9IHJlYWRlci5yZWFkOHUoKTtcbiAgICAgICAgICAgIHZbaV0gPSBjYW1sX2Zsb2F0X29mX2J5dGVzICh0KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHY7XG4gICAgICAgIGNhc2UgMHgwRDogLy9jc3QuQ09ERV9ET1VCTEVfQVJSQVk4X0JJRzpcbiAgICAgICAgICB2YXIgbGVuID0gcmVhZGVyLnJlYWQ4dSgpO1xuICAgICAgICAgIHZhciB2ID0gbmV3IEFycmF5KGxlbisxKTtcbiAgICAgICAgICB2WzBdID0gMjU0O1xuICAgICAgICAgIHZhciB0ID0gbmV3IEFycmF5KDgpOztcbiAgICAgICAgICBpZiAoaW50ZXJuX29ial90YWJsZSkgaW50ZXJuX29ial90YWJsZVtvYmpfY291bnRlcisrXSA9IHY7XG4gICAgICAgICAgZm9yICh2YXIgaSA9IDE7aSA8PSBsZW47aSsrKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBqID0gMDtqIDwgODtqKyspIHRbal0gPSByZWFkZXIucmVhZDh1KCk7XG4gICAgICAgICAgICB2IFtpXSA9IGNhbWxfZmxvYXRfb2ZfYnl0ZXMgKHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdjtcbiAgICAgICAgY2FzZSAweDA3OiAvL2NzdC5DT0RFX0RPVUJMRV9BUlJBWTMyX0xJVFRMRTpcbiAgICAgICAgICB2YXIgbGVuID0gcmVhZGVyLnJlYWQzMnUoKTtcbiAgICAgICAgICB2YXIgdiA9IG5ldyBBcnJheShsZW4rMSk7XG4gICAgICAgICAgdlswXSA9IDI1NDtcbiAgICAgICAgICBpZiAoaW50ZXJuX29ial90YWJsZSkgaW50ZXJuX29ial90YWJsZVtvYmpfY291bnRlcisrXSA9IHY7XG4gICAgICAgICAgdmFyIHQgPSBuZXcgQXJyYXkoOCk7O1xuICAgICAgICAgIGZvciAodmFyIGkgPSAxO2kgPD0gbGVuO2krKykge1xuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7aiA8IDg7aisrKSB0WzcgLSBqXSA9IHJlYWRlci5yZWFkOHUoKTtcbiAgICAgICAgICAgIHZbaV0gPSBjYW1sX2Zsb2F0X29mX2J5dGVzICh0KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHY7XG4gICAgICAgIGNhc2UgMHgwRjogLy9jc3QuQ09ERV9ET1VCTEVfQVJSQVkzMl9CSUc6XG4gICAgICAgICAgdmFyIGxlbiA9IHJlYWRlci5yZWFkMzJ1KCk7XG4gICAgICAgICAgdmFyIHYgPSBuZXcgQXJyYXkobGVuKzEpO1xuICAgICAgICAgIHZbMF0gPSAyNTQ7XG4gICAgICAgICAgdmFyIHQgPSBuZXcgQXJyYXkoOCk7O1xuICAgICAgICAgIGZvciAodmFyIGkgPSAxO2kgPD0gbGVuO2krKykge1xuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7aiA8IDg7aisrKSB0W2pdID0gcmVhZGVyLnJlYWQ4dSgpO1xuICAgICAgICAgICAgdiBbaV0gPSBjYW1sX2Zsb2F0X29mX2J5dGVzICh0KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHY7XG4gICAgICAgIGNhc2UgMHgxMDogLy9jc3QuQ09ERV9DT0RFUE9JTlRFUjpcbiAgICAgICAgY2FzZSAweDExOiAvL2NzdC5DT0RFX0lORklYUE9JTlRFUjpcbiAgICAgICAgICBjYW1sX2ZhaWx3aXRoIChcImlucHV0X3ZhbHVlOiBjb2RlIHBvaW50ZXJcIik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMHgxMjogLy9jc3QuQ09ERV9DVVNUT006XG4gICAgICAgIGNhc2UgMHgxODogLy9jc3QuQ09ERV9DVVNUT01fTEVOOlxuICAgICAgICBjYXNlIDB4MTk6IC8vY3N0LkNPREVfQ1VTVE9NX0ZJWEVEOlxuICAgICAgICAgIHZhciBjLCBzID0gXCJcIjtcbiAgICAgICAgICB3aGlsZSAoKGMgPSByZWFkZXIucmVhZDh1ICgpKSAhPSAwKSBzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUgKGMpO1xuICAgICAgICAgIHZhciBvcHMgPSBjYW1sX2N1c3RvbV9vcHNbc107XG4gICAgICAgICAgdmFyIGV4cGVjdGVkX3NpemU7XG4gICAgICAgICAgaWYoIW9wcylcbiAgICAgICAgICAgIGNhbWxfZmFpbHdpdGgoXCJpbnB1dF92YWx1ZTogdW5rbm93biBjdXN0b20gYmxvY2sgaWRlbnRpZmllclwiKTtcbiAgICAgICAgICBzd2l0Y2goY29kZSl7XG4gICAgICAgICAgY2FzZSAweDEyOiAvLyBjc3QuQ09ERV9DVVNUT00gKGRlcHJlY2F0ZWQpXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIDB4MTk6IC8vIGNzdC5DT0RFX0NVU1RPTV9GSVhFRFxuICAgICAgICAgICAgaWYoIW9wcy5maXhlZF9sZW5ndGgpXG4gICAgICAgICAgICAgIGNhbWxfZmFpbHdpdGgoXCJpbnB1dF92YWx1ZTogZXhwZWN0ZWQgYSBmaXhlZC1zaXplIGN1c3RvbSBibG9ja1wiKTtcbiAgICAgICAgICAgIGV4cGVjdGVkX3NpemUgPSBvcHMuZml4ZWRfbGVuZ3RoO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAweDE4OiAvLyBjc3QuQ09ERV9DVVNUT01fTEVOXG4gICAgICAgICAgICBleHBlY3RlZF9zaXplID0gcmVhZGVyLnJlYWQzMnUgKCk7XG4gICAgICAgICAgICAvLyBTa2lwIHNpemU2NFxuICAgICAgICAgICAgcmVhZGVyLnJlYWQzMnMoKTsgcmVhZGVyLnJlYWQzMnMoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICB2YXIgb2xkX3BvcyA9IHJlYWRlci5pO1xuICAgICAgICAgIHZhciBzaXplID0gWzBdO1xuICAgICAgICAgIHZhciB2ID0gb3BzLmRlc2VyaWFsaXplKHJlYWRlciwgc2l6ZSk7XG4gICAgICAgICAgaWYoZXhwZWN0ZWRfc2l6ZSAhPSB1bmRlZmluZWQpe1xuICAgICAgICAgICAgaWYoZXhwZWN0ZWRfc2l6ZSAhPSBzaXplWzBdKVxuICAgICAgICAgICAgICBjYW1sX2ZhaWx3aXRoKFwiaW5wdXRfdmFsdWU6IGluY29ycmVjdCBsZW5ndGggb2Ygc2VyaWFsaXplZCBjdXN0b20gYmxvY2tcIik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChpbnRlcm5fb2JqX3RhYmxlKSBpbnRlcm5fb2JqX3RhYmxlW29ial9jb3VudGVyKytdID0gdjtcbiAgICAgICAgICByZXR1cm4gdjtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBjYW1sX2ZhaWx3aXRoIChcImlucHV0X3ZhbHVlOiBpbGwtZm9ybWVkIG1lc3NhZ2VcIik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYoY29tcHJlc3NlZCkge1xuICAgIGlmKGNhbWxfZGVjb21wcmVzc19pbnB1dCkge1xuICAgICAgdmFyIGRhdGEgPSByZWFkZXIucmVhZHVpbnQ4YXJyYXkoZGF0YV9sZW4pO1xuICAgICAgdmFyIHJlcyA9IG5ldyBVaW50OEFycmF5KHVuY29tcHJlc3NlZF9kYXRhX2xlbik7XG4gICAgICB2YXIgcmVzID0gY2FtbF9kZWNvbXByZXNzX2lucHV0KGRhdGEsIHJlcyk7XG4gICAgICB2YXIgcmVhZGVyID0gbmV3IFVJbnQ4QXJyYXlSZWFkZXIocmVzLCAwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY2FtbF9mYWlsd2l0aChcImlucHV0X3ZhbHVlOiBjb21wcmVzc2VkIG9iamVjdCwgY2Fubm90IGRlY29tcHJlc3NcIik7XG4gICAgfVxuICB9XG4gIHZhciByZXMgPSBpbnRlcm5fcmVjIChyZWFkZXIpO1xuICB3aGlsZSAoc3RhY2subGVuZ3RoID4gMCkge1xuICAgIHZhciBzaXplID0gc3RhY2sucG9wKCk7XG4gICAgdmFyIHYgPSBzdGFjay5wb3AoKTtcbiAgICB2YXIgZCA9IHYubGVuZ3RoO1xuICAgIGlmIChkIDwgc2l6ZSkgc3RhY2sucHVzaCh2LCBzaXplKTtcbiAgICB2W2RdID0gaW50ZXJuX3JlYyAocmVhZGVyKTtcbiAgfVxuICBpZiAodHlwZW9mIG9mcyE9XCJudW1iZXJcIikgb2ZzWzBdID0gcmVhZGVyLmk7XG4gIHJldHVybiByZXM7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfbWFyc2hhbF9oZWFkZXJfc2l6ZVxuLy9WZXJzaW9uOiA8IDUuMS4wXG52YXIgY2FtbF9tYXJzaGFsX2hlYWRlcl9zaXplID0gMjBcblxuLy9Qcm92aWRlczogY2FtbF9tYXJzaGFsX2hlYWRlcl9zaXplXG4vL1ZlcnNpb246ID49IDUuMS4wXG52YXIgY2FtbF9tYXJzaGFsX2hlYWRlcl9zaXplID0gMTZcblxuXG5cbi8vUHJvdmlkZXM6IGNhbWxfbWFyc2hhbF9kYXRhX3NpemUgbXV0YWJsZVxuLy9SZXF1aXJlczogY2FtbF9mYWlsd2l0aCwgY2FtbF9ieXRlc191bnNhZmVfZ2V0XG4vL1JlcXVpcmVzOiBjYW1sX3VpbnQ4X2FycmF5X29mX2J5dGVzXG4vL1JlcXVpcmVzOiBVSW50OEFycmF5UmVhZGVyXG4vL1JlcXVpcmVzOiBjYW1sX21hcnNoYWxfaGVhZGVyX3NpemVcbmZ1bmN0aW9uIGNhbWxfbWFyc2hhbF9kYXRhX3NpemUgKHMsIG9mcykge1xuICB2YXIgciA9IG5ldyBVSW50OEFycmF5UmVhZGVyKGNhbWxfdWludDhfYXJyYXlfb2ZfYnl0ZXMocyksIG9mcyk7XG4gIGZ1bmN0aW9uIHJlYWR2bHEob3ZlcmZsb3cpIHtcbiAgICB2YXIgYyA9IHIucmVhZDh1KCk7XG4gICAgdmFyIG4gPSBjICYgMHg3RjtcbiAgICB3aGlsZSAoKGMgJiAweDgwKSAhPSAwKSB7XG4gICAgICBjID0gci5yZWFkOHUoKTtcbiAgICAgIHZhciBuNyA9IG4gPDwgNztcbiAgICAgIGlmIChuICE9IG43ID4+IDcpIG92ZXJmbG93WzBdID0gdHJ1ZTtcbiAgICAgIG4gPSBuNyB8IChjICYgMHg3Rik7XG4gICAgfVxuICAgIHJldHVybiBuO1xuICB9XG5cbiAgc3dpdGNoKHIucmVhZDMydSgpKXtcbiAgY2FzZSAweDg0OTVBNkJFOiAvKiBJbnRleHRfbWFnaWNfbnVtYmVyX3NtYWxsICovXG4gICAgdmFyIGhlYWRlcl9sZW4gPSAyMDtcbiAgICB2YXIgZGF0YV9sZW4gPSByLnJlYWQzMnUoKTtcbiAgICBicmVhaztcbiAgY2FzZSAweDg0OTVBNkJEOiAvKiBJbnRleHRfbWFnaWNfbnVtYmVyX2NvbXByZXNzZWQgKi9cbiAgICB2YXIgaGVhZGVyX2xlbiA9IHIucmVhZDh1KCkgJiAweDNGO1xuICAgIHZhciBvdmVyZmxvdyA9IFtmYWxzZV07XG4gICAgdmFyIGRhdGFfbGVuID0gcmVhZHZscShvdmVyZmxvdyk7XG4gICAgaWYob3ZlcmZsb3dbMF0pe1xuICAgICAgY2FtbF9mYWlsd2l0aChcIk1hcnNoYWwuZGF0YV9zaXplOiBvYmplY3QgdG9vIGxhcmdlIHRvIGJlIHJlYWQgYmFjayBvbiB0aGlzIHBsYXRmb3JtXCIpO1xuICAgIH1cbiAgICBicmVha1xuICBjYXNlIDB4ODQ5NUE2QkY6IC8qIEludGV4dF9tYWdpY19udW1iZXJfYmlnICovXG4gIGRlZmF1bHQ6XG4gICAgY2FtbF9mYWlsd2l0aChcIk1hcnNoYWwuZGF0YV9zaXplOiBiYWQgb2JqZWN0XCIpO1xuICAgIGJyZWFrXG4gIH1cbiAgcmV0dXJuIGhlYWRlcl9sZW4gLSBjYW1sX21hcnNoYWxfaGVhZGVyX3NpemUgKyBkYXRhX2xlbjtcbn1cblxuLy9Qcm92aWRlczogTWxPYmplY3RUYWJsZVxudmFyIE1sT2JqZWN0VGFibGU7XG5pZiAodHlwZW9mIGdsb2JhbFRoaXMuTWFwID09PSAndW5kZWZpbmVkJykge1xuICBNbE9iamVjdFRhYmxlID0gZnVuY3Rpb24oKSB7XG4gICAgLyogcG9seWZpbGwgKHVzaW5nIGxpbmVhciBzZWFyY2gpICovXG4gICAgZnVuY3Rpb24gTmFpdmVMb29rdXAob2JqcykgeyB0aGlzLm9ianMgPSBvYmpzOyB9XG4gICAgTmFpdmVMb29rdXAucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKHYpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5vYmpzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICh0aGlzLm9ianNbaV0gPT09IHYpIHJldHVybiBpO1xuICAgICAgfVxuICAgIH07XG4gICAgTmFpdmVMb29rdXAucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uKCkge1xuICAgICAgLy8gRG8gbm90aGluZyBoZXJlLiBbTWxPYmplY3RUYWJsZS5zdG9yZV0gd2lsbCBwdXNoIHRvIFt0aGlzLm9ianNdIGRpcmVjdGx5LlxuICAgIH07XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gTWxPYmplY3RUYWJsZSgpIHtcbiAgICAgIHRoaXMub2JqcyA9IFtdOyB0aGlzLmxvb2t1cCA9IG5ldyBOYWl2ZUxvb2t1cCh0aGlzLm9ianMpO1xuICAgIH07XG4gIH0oKTtcbn1cbmVsc2Uge1xuICBNbE9iamVjdFRhYmxlID0gZnVuY3Rpb24gTWxPYmplY3RUYWJsZSgpIHtcbiAgICB0aGlzLm9ianMgPSBbXTsgdGhpcy5sb29rdXAgPSBuZXcgZ2xvYmFsVGhpcy5NYXAoKTtcbiAgfTtcbn1cblxuTWxPYmplY3RUYWJsZS5wcm90b3R5cGUuc3RvcmUgPSBmdW5jdGlvbih2KSB7XG4gIHRoaXMubG9va3VwLnNldCh2LCB0aGlzLm9ianMubGVuZ3RoKTtcbiAgdGhpcy5vYmpzLnB1c2godik7XG59XG5cbk1sT2JqZWN0VGFibGUucHJvdG90eXBlLnJlY2FsbCA9IGZ1bmN0aW9uKHYpIHtcbiAgdmFyIGkgPSB0aGlzLmxvb2t1cC5nZXQodik7XG4gIHJldHVybiAoaSA9PT0gdW5kZWZpbmVkKVxuICAgID8gdW5kZWZpbmVkIDogdGhpcy5vYmpzLmxlbmd0aCAtIGk7ICAgLyogaW5kZXggaXMgcmVsYXRpdmUgKi9cbn1cblxuLy9Qcm92aWRlczogY2FtbF9vdXRwdXRfdmFsXG4vL1JlcXVpcmVzOiBjYW1sX2ludDY0X3RvX2J5dGVzLCBjYW1sX2ZhaWx3aXRoXG4vL1JlcXVpcmVzOiBjYW1sX2ludDY0X2JpdHNfb2ZfZmxvYXRcbi8vUmVxdWlyZXM6IGNhbWxfaXNfbWxfYnl0ZXMsIGNhbWxfbWxfYnl0ZXNfbGVuZ3RoLCBjYW1sX2J5dGVzX3Vuc2FmZV9nZXRcbi8vUmVxdWlyZXM6IGNhbWxfaXNfbWxfc3RyaW5nLCBjYW1sX21sX3N0cmluZ19sZW5ndGgsIGNhbWxfc3RyaW5nX3Vuc2FmZV9nZXRcbi8vUmVxdWlyZXM6IE1sT2JqZWN0VGFibGUsIGNhbWxfbGlzdF90b19qc19hcnJheSwgY2FtbF9jdXN0b21fb3BzXG4vL1JlcXVpcmVzOiBjYW1sX2ludmFsaWRfYXJndW1lbnQsY2FtbF9zdHJpbmdfb2ZfanNieXRlcywgY2FtbF9pc19jb250aW51YXRpb25fdGFnXG52YXIgY2FtbF9vdXRwdXRfdmFsID0gZnVuY3Rpb24gKCl7XG4gIGZ1bmN0aW9uIFdyaXRlciAoKSB7IHRoaXMuY2h1bmsgPSBbXTsgfVxuICBXcml0ZXIucHJvdG90eXBlID0ge1xuICAgIGNodW5rX2lkeDoyMCwgYmxvY2tfbGVuOjAsIG9ial9jb3VudGVyOjAsIHNpemVfMzI6MCwgc2l6ZV82NDowLFxuICAgIHdyaXRlOmZ1bmN0aW9uIChzaXplLCB2YWx1ZSkge1xuICAgICAgZm9yICh2YXIgaSA9IHNpemUgLSA4O2kgPj0gMDtpIC09IDgpXG4gICAgICAgIHRoaXMuY2h1bmtbdGhpcy5jaHVua19pZHgrK10gPSAodmFsdWUgPj4gaSkgJiAweEZGO1xuICAgIH0sXG4gICAgd3JpdGVfYXQ6ZnVuY3Rpb24gKHBvcywgc2l6ZSwgdmFsdWUpIHtcbiAgICAgIHZhciBwb3MgPSBwb3M7XG4gICAgICBmb3IgKHZhciBpID0gc2l6ZSAtIDg7aSA+PSAwO2kgLT0gOClcbiAgICAgICAgdGhpcy5jaHVua1twb3MrK10gPSAodmFsdWUgPj4gaSkgJiAweEZGO1xuICAgIH0sXG4gICAgd3JpdGVfY29kZTpmdW5jdGlvbiAoc2l6ZSwgY29kZSwgdmFsdWUpIHtcbiAgICAgIHRoaXMuY2h1bmtbdGhpcy5jaHVua19pZHgrK10gPSBjb2RlO1xuICAgICAgZm9yICh2YXIgaSA9IHNpemUgLSA4O2kgPj0gMDtpIC09IDgpXG4gICAgICAgIHRoaXMuY2h1bmtbdGhpcy5jaHVua19pZHgrK10gPSAodmFsdWUgPj4gaSkgJiAweEZGO1xuICAgIH0sXG4gICAgd3JpdGVfc2hhcmVkOmZ1bmN0aW9uIChvZmZzZXQpIHtcbiAgICAgIGlmIChvZmZzZXQgPCAoMSA8PCA4KSkgdGhpcy53cml0ZV9jb2RlKDgsIDB4MDQgLypjc3QuQ09ERV9TSEFSRUQ4Ki8sIG9mZnNldCk7XG4gICAgICBlbHNlIGlmIChvZmZzZXQgPCAoMSA8PCAxNikpIHRoaXMud3JpdGVfY29kZSgxNiwgMHgwNSAvKmNzdC5DT0RFX1NIQVJFRDE2Ki8sIG9mZnNldCk7XG4gICAgICBlbHNlIHRoaXMud3JpdGVfY29kZSgzMiwgMHgwNiAvKmNzdC5DT0RFX1NIQVJFRDMyKi8sIG9mZnNldCk7XG4gICAgfSxcbiAgICBwb3M6ZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5jaHVua19pZHggfSxcbiAgICBmaW5hbGl6ZTpmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLmJsb2NrX2xlbiA9IHRoaXMuY2h1bmtfaWR4IC0gMjA7XG4gICAgICB0aGlzLmNodW5rX2lkeCA9IDA7XG4gICAgICB0aGlzLndyaXRlICgzMiwgMHg4NDk1QTZCRSk7XG4gICAgICB0aGlzLndyaXRlICgzMiwgdGhpcy5ibG9ja19sZW4pO1xuICAgICAgdGhpcy53cml0ZSAoMzIsIHRoaXMub2JqX2NvdW50ZXIpO1xuICAgICAgdGhpcy53cml0ZSAoMzIsIHRoaXMuc2l6ZV8zMik7XG4gICAgICB0aGlzLndyaXRlICgzMiwgdGhpcy5zaXplXzY0KTtcbiAgICAgIHJldHVybiB0aGlzLmNodW5rO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZnVuY3Rpb24gKHYsIGZsYWdzKSB7XG4gICAgZmxhZ3MgPSBjYW1sX2xpc3RfdG9fanNfYXJyYXkoZmxhZ3MpO1xuXG4gICAgdmFyIG5vX3NoYXJpbmcgPSAoZmxhZ3MuaW5kZXhPZigwIC8qTWFyc2hhbC5Ob19zaGFyaW5nKi8pICE9PSAtMSksXG4gICAgICAgIGNsb3N1cmVzID0gIChmbGFncy5pbmRleE9mKDEgLypNYXJzaGFsLkNsb3N1cmVzKi8pICE9PSAtMSk7XG4gICAgLyogTWFyc2hhbC5Db21wYXRfMzIgaXMgcmVkdW5kYW50IHNpbmNlIGludGVnZXJzIGFyZSAzMi1iaXQgYW55d2F5ICovXG5cbiAgICBpZiAoY2xvc3VyZXMpXG4gICAgICBjb25zb2xlLndhcm4oXCJpbiBjYW1sX291dHB1dF92YWw6IGZsYWcgTWFyc2hhbC5DbG9zdXJlcyBpcyBub3Qgc3VwcG9ydGVkLlwiKTtcblxuICAgIHZhciB3cml0ZXIgPSBuZXcgV3JpdGVyICgpO1xuICAgIHZhciBzdGFjayA9IFtdO1xuICAgIHZhciBpbnRlcm5fb2JqX3RhYmxlID0gbm9fc2hhcmluZyA/IG51bGwgOiBuZXcgTWxPYmplY3RUYWJsZSgpO1xuXG4gICAgZnVuY3Rpb24gbWVtbyh2KSB7XG4gICAgICBpZiAobm9fc2hhcmluZykgcmV0dXJuIGZhbHNlO1xuICAgICAgdmFyIGV4aXN0aW5nX29mZnNldCA9IGludGVybl9vYmpfdGFibGUucmVjYWxsKHYpO1xuICAgICAgaWYgKGV4aXN0aW5nX29mZnNldCkgeyB3cml0ZXIud3JpdGVfc2hhcmVkKGV4aXN0aW5nX29mZnNldCk7IHJldHVybiB0cnVlOyB9XG4gICAgICBlbHNlIHsgaW50ZXJuX29ial90YWJsZS5zdG9yZSh2KTsgcmV0dXJuIGZhbHNlOyB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZXh0ZXJuX3JlYyAodikge1xuICAgICAgaWYgKHYuY2FtbF9jdXN0b20pIHtcbiAgICAgICAgaWYgKG1lbW8odikpIHJldHVybjtcbiAgICAgICAgdmFyIG5hbWUgPSB2LmNhbWxfY3VzdG9tO1xuICAgICAgICB2YXIgb3BzID0gY2FtbF9jdXN0b21fb3BzW25hbWVdO1xuICAgICAgICB2YXIgc3pfMzJfNjQgPSBbMCwwXTtcbiAgICAgICAgaWYoIW9wcy5zZXJpYWxpemUpXG4gICAgICAgICAgY2FtbF9pbnZhbGlkX2FyZ3VtZW50KFwib3V0cHV0X3ZhbHVlOiBhYnN0cmFjdCB2YWx1ZSAoQ3VzdG9tKVwiKTtcbiAgICAgICAgaWYob3BzLmZpeGVkX2xlbmd0aCA9PSB1bmRlZmluZWQpe1xuICAgICAgICAgIHdyaXRlci53cml0ZSAoOCwgMHgxOCAvKmNzdC5DT0RFX0NVU1RPTV9MRU4qLyk7XG4gICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuYW1lLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgd3JpdGVyLndyaXRlICg4LCBuYW1lLmNoYXJDb2RlQXQoaSkpO1xuICAgICAgICAgIHdyaXRlci53cml0ZSg4LCAwKTtcbiAgICAgICAgICB2YXIgaGVhZGVyX3BvcyA9IHdyaXRlci5wb3MgKCk7XG4gICAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IDEyOyBpKyspIHtcbiAgICAgICAgICAgIHdyaXRlci53cml0ZSg4LCAwKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgb3BzLnNlcmlhbGl6ZSh3cml0ZXIsIHYsIHN6XzMyXzY0KTtcbiAgICAgICAgICB3cml0ZXIud3JpdGVfYXQoaGVhZGVyX3BvcywgMzIsIHN6XzMyXzY0WzBdKTtcbiAgICAgICAgICB3cml0ZXIud3JpdGVfYXQoaGVhZGVyX3BvcyArIDQsIDMyLCAwKTsgLy8gemVyb1xuICAgICAgICAgIHdyaXRlci53cml0ZV9hdChoZWFkZXJfcG9zICsgOCwgMzIsIHN6XzMyXzY0WzFdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB3cml0ZXIud3JpdGUgKDgsIDB4MTkgLypjc3QuQ09ERV9DVVNUT01fRklYRUQqLyk7XG4gICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuYW1lLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgd3JpdGVyLndyaXRlICg4LCBuYW1lLmNoYXJDb2RlQXQoaSkpO1xuICAgICAgICAgIHdyaXRlci53cml0ZSg4LCAwKTtcbiAgICAgICAgICB2YXIgb2xkX3BvcyA9IHdyaXRlci5wb3MoKTtcbiAgICAgICAgICBvcHMuc2VyaWFsaXplKHdyaXRlciwgdiwgc3pfMzJfNjQpO1xuICAgICAgICAgIGlmIChvcHMuZml4ZWRfbGVuZ3RoICE9IHdyaXRlci5wb3MoKSAtIG9sZF9wb3MpXG4gICAgICAgICAgICBjYW1sX2ZhaWx3aXRoKFwib3V0cHV0X3ZhbHVlOiBpbmNvcnJlY3QgZml4ZWQgc2l6ZXMgc3BlY2lmaWVkIGJ5IFwiICsgbmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgd3JpdGVyLnNpemVfMzIgKz0gMiArICgoc3pfMzJfNjRbMF0gKyAzKSA+PiAyKTtcbiAgICAgICAgd3JpdGVyLnNpemVfNjQgKz0gMiArICgoc3pfMzJfNjRbMV0gKyA3KSA+PiAzKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKHYgaW5zdGFuY2VvZiBBcnJheSAmJiB2WzBdID09PSAodlswXXwwKSkge1xuICAgICAgICBpZiAodlswXSA9PSAyNTEpIHtcbiAgICAgICAgICBjYW1sX2ZhaWx3aXRoKFwib3V0cHV0X3ZhbHVlOiBhYnN0cmFjdCB2YWx1ZSAoQWJzdHJhY3QpXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjYW1sX2lzX2NvbnRpbnVhdGlvbl90YWcodlswXSkpXG4gICAgICAgICAgY2FtbF9pbnZhbGlkX2FyZ3VtZW50KFwib3V0cHV0X3ZhbHVlOiBjb250aW51YXRpb24gdmFsdWVcIik7XG4gICAgICAgIGlmICh2Lmxlbmd0aCA+IDEgJiYgbWVtbyh2KSkgcmV0dXJuO1xuICAgICAgICBpZiAodlswXSA8IDE2ICYmIHYubGVuZ3RoIC0gMSA8IDgpXG4gICAgICAgICAgd3JpdGVyLndyaXRlICg4LCAweDgwIC8qY3N0LlBSRUZJWF9TTUFMTF9CTE9DSyovICsgdlswXSArICgodi5sZW5ndGggLSAxKTw8NCkpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgd3JpdGVyLndyaXRlX2NvZGUoMzIsIDB4MDggLypjc3QuQ09ERV9CTE9DSzMyKi8sICgodi5sZW5ndGgtMSkgPDwgMTApIHwgdlswXSk7XG4gICAgICAgIHdyaXRlci5zaXplXzMyICs9IHYubGVuZ3RoO1xuICAgICAgICB3cml0ZXIuc2l6ZV82NCArPSB2Lmxlbmd0aDtcbiAgICAgICAgaWYgKHYubGVuZ3RoID4gMSkgc3RhY2sucHVzaCAodiwgMSk7XG4gICAgICB9IGVsc2UgaWYgKGNhbWxfaXNfbWxfYnl0ZXModikpIHtcbiAgICAgICAgaWYoIShjYW1sX2lzX21sX2J5dGVzKGNhbWxfc3RyaW5nX29mX2pzYnl0ZXMoXCJcIikpKSkge1xuICAgICAgICAgIGNhbWxfZmFpbHdpdGgoXCJvdXRwdXRfdmFsdWU6IFtCeXRlcy50XSBjYW5ub3Qgc2FmZWx5IGJlIG1hcnNoYWxlZCB3aXRoIFstLWVuYWJsZSB1c2UtanMtc3RyaW5nXVwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWVtbyh2KSkgcmV0dXJuO1xuICAgICAgICB2YXIgbGVuID0gY2FtbF9tbF9ieXRlc19sZW5ndGgodik7XG4gICAgICAgIGlmIChsZW4gPCAweDIwKVxuICAgICAgICAgIHdyaXRlci53cml0ZSAoOCwgMHgyMCAvKmNzdC5QUkVGSVhfU01BTExfU1RSSU5HKi8gKyBsZW4pO1xuICAgICAgICBlbHNlIGlmIChsZW4gPCAweDEwMClcbiAgICAgICAgICB3cml0ZXIud3JpdGVfY29kZSAoOCwgMHgwOS8qY3N0LkNPREVfU1RSSU5HOCovLCBsZW4pO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgd3JpdGVyLndyaXRlX2NvZGUgKDMyLCAweDBBIC8qY3N0LkNPREVfU1RSSU5HMzIqLywgbGVuKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7aSA8IGxlbjtpKyspXG4gICAgICAgICAgd3JpdGVyLndyaXRlICg4LCBjYW1sX2J5dGVzX3Vuc2FmZV9nZXQodixpKSk7XG4gICAgICAgIHdyaXRlci5zaXplXzMyICs9IDEgKyAoKChsZW4gKyA0KSAvIDQpfDApO1xuICAgICAgICB3cml0ZXIuc2l6ZV82NCArPSAxICsgKCgobGVuICsgOCkgLyA4KXwwKTtcbiAgICAgIH0gZWxzZSBpZiAoY2FtbF9pc19tbF9zdHJpbmcodikpIHtcbiAgICAgICAgaWYgKG1lbW8odikpIHJldHVybjtcbiAgICAgICAgdmFyIGxlbiA9IGNhbWxfbWxfc3RyaW5nX2xlbmd0aCh2KTtcbiAgICAgICAgaWYgKGxlbiA8IDB4MjApXG4gICAgICAgICAgd3JpdGVyLndyaXRlICg4LCAweDIwIC8qY3N0LlBSRUZJWF9TTUFMTF9TVFJJTkcqLyArIGxlbik7XG4gICAgICAgIGVsc2UgaWYgKGxlbiA8IDB4MTAwKVxuICAgICAgICAgIHdyaXRlci53cml0ZV9jb2RlICg4LCAweDA5Lypjc3QuQ09ERV9TVFJJTkc4Ki8sIGxlbik7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICB3cml0ZXIud3JpdGVfY29kZSAoMzIsIDB4MEEgLypjc3QuQ09ERV9TVFJJTkczMiovLCBsZW4pO1xuICAgICAgICBmb3IgKHZhciBpID0gMDtpIDwgbGVuO2krKylcbiAgICAgICAgICB3cml0ZXIud3JpdGUgKDgsIGNhbWxfc3RyaW5nX3Vuc2FmZV9nZXQodixpKSk7XG4gICAgICAgIHdyaXRlci5zaXplXzMyICs9IDEgKyAoKChsZW4gKyA0KSAvIDQpfDApO1xuICAgICAgICB3cml0ZXIuc2l6ZV82NCArPSAxICsgKCgobGVuICsgOCkgLyA4KXwwKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh2ICE9ICh2fDApKXtcbiAgICAgICAgICB2YXIgdHlwZV9vZl92ID0gdHlwZW9mIHY7XG4gICAgICAgICAgaWYodHlwZV9vZl92ICE9IFwibnVtYmVyXCIpXG4gICAgICAgICAgICBjYW1sX2ZhaWx3aXRoKFwib3V0cHV0X3ZhbHVlOiBhYnN0cmFjdCB2YWx1ZSAoXCIrdHlwZV9vZl92K1wiKVwiKTtcbiAgICAgICAgICAvLyBJZiBhIGZsb2F0IGhhcHBlbnMgdG8gYmUgYW4gaW50ZWdlciBpdCBpcyBzZXJpYWxpemVkIGFzIGFuIGludGVnZXJcbiAgICAgICAgICAvLyAoSnNfb2Zfb2NhbWwgY2Fubm90IHRlbGwgd2hldGhlciB0aGUgdHlwZSBvZiBhbiBpbnRlZ2VyIG51bWJlciBpc1xuICAgICAgICAgIC8vIGZsb2F0IG9yIGludGVnZXIuKSBUaGlzIGNhbiByZXN1bHQgaW4gdW5leHBlY3RlZCBjcmFzaGVzIHdoZW5cbiAgICAgICAgICAvLyB1bm1hcnNoYWxsaW5nIHVzaW5nIHRoZSBzdGFuZGFyZCBydW50aW1lLlxuICAgICAgICAgIGlmIChtZW1vKHYpKSByZXR1cm47XG4gICAgICAgICAgdmFyIHQgPSBjYW1sX2ludDY0X3RvX2J5dGVzKGNhbWxfaW50NjRfYml0c19vZl9mbG9hdCh2KSk7XG4gICAgICAgICAgd3JpdGVyLndyaXRlICg4LCAweDBDIC8qY3N0LkNPREVfRE9VQkxFX0xJVFRMRSovKTtcbiAgICAgICAgICBmb3IodmFyIGkgPSAwOyBpPDg7IGkrKyl7d3JpdGVyLndyaXRlKDgsdFs3IC0gaV0pfVxuICAgICAgICAgIHdyaXRlci5zaXplXzMyICs9IDNcbiAgICAgICAgICB3cml0ZXIuc2l6ZV82NCArPSAyXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodiA+PSAwICYmIHYgPCAweDQwKSB7XG4gICAgICAgICAgd3JpdGVyLndyaXRlICg4LCAwWDQwIC8qY3N0LlBSRUZJWF9TTUFMTF9JTlQqLyArIHYpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICh2ID49IC0oMSA8PCA3KSAmJiB2IDwgKDEgPDwgNykpXG4gICAgICAgICAgICB3cml0ZXIud3JpdGVfY29kZSg4LCAweDAwIC8qY3N0LkNPREVfSU5UOCovLCB2KTtcbiAgICAgICAgICBlbHNlIGlmICh2ID49IC0oMSA8PCAxNSkgJiYgdiA8ICgxIDw8IDE1KSlcbiAgICAgICAgICAgIHdyaXRlci53cml0ZV9jb2RlKDE2LCAweDAxIC8qY3N0LkNPREVfSU5UMTYqLywgdik7XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgd3JpdGVyLndyaXRlX2NvZGUoMzIsIDB4MDIgLypjc3QuQ09ERV9JTlQzMiovLCB2KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBleHRlcm5fcmVjICh2KTtcbiAgICB3aGlsZSAoc3RhY2subGVuZ3RoID4gMCkge1xuICAgICAgdmFyIGkgPSBzdGFjay5wb3AgKCk7XG4gICAgICB2YXIgdiA9IHN0YWNrLnBvcCAoKTtcbiAgICAgIGlmIChpICsgMSA8IHYubGVuZ3RoKSBzdGFjay5wdXNoICh2LCBpICsgMSk7XG4gICAgICBleHRlcm5fcmVjICh2W2ldKTtcbiAgICB9XG4gICAgaWYgKGludGVybl9vYmpfdGFibGUpIHdyaXRlci5vYmpfY291bnRlciA9IGludGVybl9vYmpfdGFibGUub2Jqcy5sZW5ndGg7XG4gICAgd3JpdGVyLmZpbmFsaXplKCk7XG4gICAgcmV0dXJuIHdyaXRlci5jaHVuaztcbiAgfVxufSAoKTtcblxuLy9Qcm92aWRlczogY2FtbF9vdXRwdXRfdmFsdWVfdG9fc3RyaW5nIG11dGFibGVcbi8vUmVxdWlyZXM6IGNhbWxfb3V0cHV0X3ZhbCwgY2FtbF9zdHJpbmdfb2ZfYXJyYXlcbmZ1bmN0aW9uIGNhbWxfb3V0cHV0X3ZhbHVlX3RvX3N0cmluZyAodiwgZmxhZ3MpIHtcbiAgcmV0dXJuIGNhbWxfc3RyaW5nX29mX2FycmF5IChjYW1sX291dHB1dF92YWwgKHYsIGZsYWdzKSk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfb3V0cHV0X3ZhbHVlX3RvX2J5dGVzIG11dGFibGVcbi8vUmVxdWlyZXM6IGNhbWxfb3V0cHV0X3ZhbCwgY2FtbF9ieXRlc19vZl9hcnJheVxuZnVuY3Rpb24gY2FtbF9vdXRwdXRfdmFsdWVfdG9fYnl0ZXMgKHYsIGZsYWdzKSB7XG4gIHJldHVybiBjYW1sX2J5dGVzX29mX2FycmF5IChjYW1sX291dHB1dF92YWwgKHYsIGZsYWdzKSk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfb3V0cHV0X3ZhbHVlX3RvX2J1ZmZlclxuLy9SZXF1aXJlczogY2FtbF9vdXRwdXRfdmFsLCBjYW1sX2ZhaWx3aXRoLCBjYW1sX2JsaXRfYnl0ZXNcbmZ1bmN0aW9uIGNhbWxfb3V0cHV0X3ZhbHVlX3RvX2J1ZmZlciAocywgb2ZzLCBsZW4sIHYsIGZsYWdzKSB7XG4gIHZhciB0ID0gY2FtbF9vdXRwdXRfdmFsICh2LCBmbGFncyk7XG4gIGlmICh0Lmxlbmd0aCA+IGxlbikgY2FtbF9mYWlsd2l0aCAoXCJNYXJzaGFsLnRvX2J1ZmZlcjogYnVmZmVyIG92ZXJmbG93XCIpO1xuICBjYW1sX2JsaXRfYnl0ZXModCwgMCwgcywgb2ZzLCB0Lmxlbmd0aCk7XG4gIHJldHVybiAwO1xufVxuIiwiLy9Qcm92aWRlczogY2FtbF91bml4X2dldHRpbWVvZmRheVxuLy9BbGlhczogdW5peF9nZXR0aW1lb2ZkYXlcbmZ1bmN0aW9uIGNhbWxfdW5peF9nZXR0aW1lb2ZkYXkgKCkge1xuICByZXR1cm4gKG5ldyBEYXRlKCkpLmdldFRpbWUoKSAvIDEwMDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfdW5peF90aW1lXG4vL1JlcXVpcmVzOiBjYW1sX3VuaXhfZ2V0dGltZW9mZGF5XG4vL0FsaWFzOiB1bml4X3RpbWVcbmZ1bmN0aW9uIGNhbWxfdW5peF90aW1lICgpIHtcbiAgcmV0dXJuIE1hdGguZmxvb3IoY2FtbF91bml4X2dldHRpbWVvZmRheSAoKSk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfdW5peF9nbXRpbWVcbi8vQWxpYXM6IHVuaXhfZ210aW1lXG5mdW5jdGlvbiBjYW1sX3VuaXhfZ210aW1lICh0KSB7XG4gIHZhciBkID0gbmV3IERhdGUgKHQgKiAxMDAwKTtcbiAgdmFyIGRfbnVtID0gZC5nZXRUaW1lKCk7XG4gIHZhciBqYW51YXJ5Zmlyc3QgPSAobmV3IERhdGUoRGF0ZS5VVEMoZC5nZXRVVENGdWxsWWVhcigpLCAwLCAxKSkpLmdldFRpbWUoKTtcbiAgdmFyIGRveSA9IE1hdGguZmxvb3IoKGRfbnVtIC0gamFudWFyeWZpcnN0KSAvIDg2NDAwMDAwKTtcbiAgcmV0dXJuIEJMT0NLKDAsIGQuZ2V0VVRDU2Vjb25kcygpLCBkLmdldFVUQ01pbnV0ZXMoKSwgZC5nZXRVVENIb3VycygpLFxuICAgICAgICAgICAgICAgZC5nZXRVVENEYXRlKCksIGQuZ2V0VVRDTW9udGgoKSwgZC5nZXRVVENGdWxsWWVhcigpIC0gMTkwMCxcbiAgICAgICAgICAgICAgIGQuZ2V0VVRDRGF5KCksIGRveSxcbiAgICAgICAgICAgICAgIGZhbHNlIHwgMCAvKiBmb3IgVVRDIGRheWxpZ2h0IHNhdmluZ3MgdGltZSBpcyBmYWxzZSAqLylcbn1cblxuLy9Qcm92aWRlczogY2FtbF91bml4X2xvY2FsdGltZVxuLy9BbGlhczogdW5peF9sb2NhbHRpbWVcbmZ1bmN0aW9uIGNhbWxfdW5peF9sb2NhbHRpbWUgKHQpIHtcbiAgdmFyIGQgPSBuZXcgRGF0ZSAodCAqIDEwMDApO1xuICB2YXIgZF9udW0gPSBkLmdldFRpbWUoKTtcbiAgdmFyIGphbnVhcnlmaXJzdCA9IChuZXcgRGF0ZShkLmdldEZ1bGxZZWFyKCksIDAsIDEpKS5nZXRUaW1lKCk7XG4gIHZhciBkb3kgPSBNYXRoLmZsb29yKChkX251bSAtIGphbnVhcnlmaXJzdCkgLyA4NjQwMDAwMCk7XG4gIHZhciBqYW4gPSBuZXcgRGF0ZShkLmdldEZ1bGxZZWFyKCksIDAsIDEpO1xuICB2YXIganVsID0gbmV3IERhdGUoZC5nZXRGdWxsWWVhcigpLCA2LCAxKTtcbiAgdmFyIHN0ZFRpbWV6b25lT2Zmc2V0ID0gTWF0aC5tYXgoamFuLmdldFRpbWV6b25lT2Zmc2V0KCksIGp1bC5nZXRUaW1lem9uZU9mZnNldCgpKTtcbiAgcmV0dXJuIEJMT0NLKDAsIGQuZ2V0U2Vjb25kcygpLCBkLmdldE1pbnV0ZXMoKSwgZC5nZXRIb3VycygpLFxuICAgICAgICAgICAgICAgZC5nZXREYXRlKCksIGQuZ2V0TW9udGgoKSwgZC5nZXRGdWxsWWVhcigpIC0gMTkwMCxcbiAgICAgICAgICAgICAgIGQuZ2V0RGF5KCksIGRveSxcbiAgICAgICAgICAgICAgIChkLmdldFRpbWV6b25lT2Zmc2V0KCkgPCBzdGRUaW1lem9uZU9mZnNldCkgfCAwIC8qIGRheWxpZ2h0IHNhdmluZ3MgdGltZSAgZmllbGQuICovKVxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3VuaXhfbWt0aW1lXG4vL1JlcXVpcmVzOiBjYW1sX3VuaXhfbG9jYWx0aW1lXG4vL0FsaWFzOiB1bml4X21rdGltZVxuZnVuY3Rpb24gY2FtbF91bml4X21rdGltZSh0bSl7XG4gIHZhciBkID0gKG5ldyBEYXRlKHRtWzZdKzE5MDAsdG1bNV0sdG1bNF0sdG1bM10sdG1bMl0sdG1bMV0pKS5nZXRUaW1lKCk7XG4gIHZhciB0ID0gTWF0aC5mbG9vcihkIC8gMTAwMCk7XG4gIHZhciB0bTIgPSBjYW1sX3VuaXhfbG9jYWx0aW1lKHQpO1xuICByZXR1cm4gQkxPQ0soMCx0LHRtMik7XG59XG4vL1Byb3ZpZGVzOiBjYW1sX3VuaXhfc3RhcnR1cCBjb25zdFxuLy9BbGlhczogd2luX3N0YXJ0dXBcbmZ1bmN0aW9uIGNhbWxfdW5peF9zdGFydHVwKCkge31cblxuLy9Qcm92aWRlczogY2FtbF91bml4X2NsZWFudXAgY29uc3Rcbi8vQWxpYXM6IHdpbl9jbGVhbnVwXG5mdW5jdGlvbiBjYW1sX3VuaXhfY2xlYW51cCgpIHt9XG5cbi8vUHJvdmlkZXM6IGNhbWxfdW5peF9maWxlZGVzY3Jfb2ZfZmQgY29uc3Rcbi8vQWxpYXM6IHdpbl9oYW5kbGVfZmRcbmZ1bmN0aW9uIGNhbWxfdW5peF9maWxlZGVzY3Jfb2ZfZmQoeCkge3JldHVybiB4O31cblxuLy9Qcm92aWRlczogY2FtbF91bml4X2lzYXR0eVxuLy9SZXF1aXJlczogZnNfbm9kZV9zdXBwb3J0ZWRcbi8vQWxpYXM6IHVuaXhfaXNhdHR5XG5mdW5jdGlvbiBjYW1sX3VuaXhfaXNhdHR5KGZpbGVEZXNjcmlwdG9yKSB7XG4gIGlmKGZzX25vZGVfc3VwcG9ydGVkKCkpIHtcbiAgICB2YXIgdHR5ID0gcmVxdWlyZSgndHR5Jyk7XG4gICAgcmV0dXJuIHR0eS5pc2F0dHkoZmlsZURlc2NyaXB0b3IpPzE6MDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gMDtcbiAgfVxufVxuXG5cbi8vUHJvdmlkZXM6IGNhbWxfdW5peF9pc2F0dHlcbi8vQWxpYXM6IHVuaXhfaXNhdHR5XG4vL0lmOiBicm93c2VyXG5mdW5jdGlvbiBjYW1sX3VuaXhfaXNhdHR5KGZpbGVEZXNjcmlwdG9yKSB7XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBtYWtlX3VuaXhfZXJyX2FyZ3Ncbi8vUmVxdWlyZXM6IGNhbWxfc3RyaW5nX29mX2pzc3RyaW5nXG52YXIgdW5peF9lcnJvciA9IFtcbiAgLyogPT09VW5peC5lcnJvcj09PVxuICAgKlxuICAgKiBUaGlzIGFycmF5IGlzIGluIG9yZGVyIG9mIHRoZSB2YXJpYW50IGluIE9DYW1sXG4gICAqL1xuICBcIkUyQklHXCIsIFwiRUFDQ0VTXCIsIFwiRUFHQUlOXCIsIFwiRUJBREZcIiwgXCJFQlVTWVwiLCBcIkVDSElMRFwiLCBcIkVERUFETEtcIiwgXCJFRE9NXCIsXG4gIFwiRUVYSVNUXCIsIFwiRUZBVUxUXCIsIFwiRUZCSUdcIiwgXCJFSU5UUlwiLCBcIkVJTlZBTFwiLCBcIkVJT1wiLCBcIkVJU0RJUlwiLCBcIkVNRklMRVwiLFxuICBcIkVNTElOS1wiLCBcIkVOQU1FVE9PTE9OR1wiLCBcIkVORklMRVwiLCBcIkVOT0RFVlwiLCBcIkVOT0VOVFwiLCBcIkVOT0VYRUNcIiwgXCJFTk9MQ0tcIixcbiAgXCJFTk9NRU1cIiwgXCJFTk9TUENcIiwgXCJFTk9TWVNcIiwgXCJFTk9URElSXCIsIFwiRU5PVEVNUFRZXCIsIFwiRU5PVFRZXCIsIFwiRU5YSU9cIixcbiAgXCJFUEVSTVwiLCBcIkVQSVBFXCIsIFwiRVJBTkdFXCIsIFwiRVJPRlNcIiwgXCJFU1BJUEVcIiwgXCJFU1JDSFwiLCBcIkVYREVWXCIsIFwiRVdPVUxEQkxPQ0tcIixcbiAgXCJFSU5QUk9HUkVTU1wiLCBcIkVBTFJFQURZXCIsIFwiRU5PVFNPQ0tcIiwgXCJFREVTVEFERFJSRVFcIiwgXCJFTVNHU0laRVwiLFxuICBcIkVQUk9UT1RZUEVcIiwgXCJFTk9QUk9UT09QVFwiLCBcIkVQUk9UT05PU1VQUE9SVFwiLCBcIkVTT0NLVE5PU1VQUE9SVFwiLFxuICBcIkVPUE5PVFNVUFBcIiwgXCJFUEZOT1NVUFBPUlRcIiwgXCJFQUZOT1NVUFBPUlRcIiwgXCJFQUREUklOVVNFXCIsIFwiRUFERFJOT1RBVkFJTFwiLFxuICBcIkVORVRET1dOXCIsIFwiRU5FVFVOUkVBQ0hcIiwgXCJFTkVUUkVTRVRcIiwgXCJFQ09OTkFCT1JURURcIiwgXCJFQ09OTlJFU0VUXCIsIFwiRU5PQlVGU1wiLFxuICBcIkVJU0NPTk5cIiwgXCJFTk9UQ09OTlwiLCBcIkVTSFVURE9XTlwiLCBcIkVUT09NQU5ZUkVGU1wiLCBcIkVUSU1FRE9VVFwiLCBcIkVDT05OUkVGVVNFRFwiLFxuICBcIkVIT1NURE9XTlwiLCBcIkVIT1NUVU5SRUFDSFwiLCBcIkVMT09QXCIsIFwiRU9WRVJGTE9XXCJcbl07XG5mdW5jdGlvbiBtYWtlX3VuaXhfZXJyX2FyZ3MoY29kZSwgc3lzY2FsbCwgcGF0aCwgZXJybm8pIHtcbiAgdmFyIHZhcmlhbnQgPSB1bml4X2Vycm9yLmluZGV4T2YoY29kZSk7XG4gIGlmICh2YXJpYW50IDwgMCkge1xuICAgIC8vIERlZmF1bHQgaWYgdW5kZWZpbmVkXG4gICAgaWYgKGVycm5vID09IG51bGwpIHtcbiAgICAgIGVycm5vID0gLTk5OTlcbiAgICB9XG4gICAgLy8gSWYgbm9uZSBvZiB0aGUgYWJvdmUgdmFyaWFudHMsIGZhbGxiYWNrIHRvIEVVTktOT1dORVJSKGludClcbiAgICB2YXJpYW50ID0gQkxPQ0soMCwgZXJybm8pO1xuICB9XG4gIHZhciBhcmdzID0gW1xuICAgIHZhcmlhbnQsXG4gICAgY2FtbF9zdHJpbmdfb2ZfanNzdHJpbmcoc3lzY2FsbCB8fCBcIlwiKSxcbiAgICBjYW1sX3N0cmluZ19vZl9qc3N0cmluZyhwYXRoIHx8IFwiXCIpXG4gIF07XG4gIHJldHVybiBhcmdzO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3VuaXhfc3RhdFxuLy9SZXF1aXJlczogcmVzb2x2ZV9mc19kZXZpY2UsIGNhbWxfZmFpbHdpdGhcbi8vQWxpYXM6IHVuaXhfc3RhdFxuZnVuY3Rpb24gY2FtbF91bml4X3N0YXQobmFtZSkge1xuICB2YXIgcm9vdCA9IHJlc29sdmVfZnNfZGV2aWNlKG5hbWUpO1xuICBpZiAoIXJvb3QuZGV2aWNlLnN0YXQpIHtcbiAgICBjYW1sX2ZhaWx3aXRoKFwiY2FtbF91bml4X3N0YXQ6IG5vdCBpbXBsZW1lbnRlZFwiKTtcbiAgfVxuICByZXR1cm4gcm9vdC5kZXZpY2Uuc3RhdChyb290LnJlc3QsIC8qIHJhaXNlIFVuaXhfZXJyb3IgKi8gdHJ1ZSk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfdW5peF9zdGF0XzY0XG4vL1JlcXVpcmVzOiBjYW1sX3VuaXhfc3RhdCwgY2FtbF9pbnQ2NF9vZl9pbnQzMlxuLy9BbGlhczogdW5peF9zdGF0XzY0XG5mdW5jdGlvbiBjYW1sX3VuaXhfc3RhdF82NChuYW1lKSB7XG4gIHZhciByID0gY2FtbF91bml4X3N0YXQobmFtZSk7XG4gIHJbOV0gPSBjYW1sX2ludDY0X29mX2ludDMyKHJbOV0pO1xuICByZXR1cm4gcjtcbn1cblxuLy9Qcm92aWRlczogY2FtbF91bml4X2xzdGF0XG4vL1JlcXVpcmVzOiByZXNvbHZlX2ZzX2RldmljZSwgY2FtbF9mYWlsd2l0aFxuLy9BbGlhczogdW5peF9sc3RhdFxuZnVuY3Rpb24gY2FtbF91bml4X2xzdGF0KG5hbWUpIHtcbiAgdmFyIHJvb3QgPSByZXNvbHZlX2ZzX2RldmljZShuYW1lKTtcbiAgaWYgKCFyb290LmRldmljZS5sc3RhdCkge1xuICAgIGNhbWxfZmFpbHdpdGgoXCJjYW1sX3VuaXhfbHN0YXQ6IG5vdCBpbXBsZW1lbnRlZFwiKTtcbiAgfVxuICByZXR1cm4gcm9vdC5kZXZpY2UubHN0YXQocm9vdC5yZXN0LCAvKiByYWlzZSBVbml4X2Vycm9yICovIHRydWUpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3VuaXhfbHN0YXRfNjRcbi8vUmVxdWlyZXM6IGNhbWxfdW5peF9sc3RhdCwgY2FtbF9pbnQ2NF9vZl9pbnQzMlxuLy9BbGlhczogdW5peF9sc3RhdF82NFxuZnVuY3Rpb24gY2FtbF91bml4X2xzdGF0XzY0KG5hbWUpIHtcbiAgdmFyIHIgPSBjYW1sX3VuaXhfbHN0YXQobmFtZSk7XG4gIHJbOV0gPSBjYW1sX2ludDY0X29mX2ludDMyKHJbOV0pO1xuICByZXR1cm4gcjtcbn1cblxuLy9Qcm92aWRlczogY2FtbF91bml4X21rZGlyXG4vL1JlcXVpcmVzOiByZXNvbHZlX2ZzX2RldmljZSwgY2FtbF9mYWlsd2l0aFxuLy9BbGlhczogdW5peF9ta2RpclxuZnVuY3Rpb24gY2FtbF91bml4X21rZGlyKG5hbWUsIHBlcm0pIHtcbiAgdmFyIHJvb3QgPSByZXNvbHZlX2ZzX2RldmljZShuYW1lKTtcbiAgaWYgKCFyb290LmRldmljZS5ta2Rpcikge1xuICAgIGNhbWxfZmFpbHdpdGgoXCJjYW1sX3VuaXhfbWtkaXI6IG5vdCBpbXBsZW1lbnRlZFwiKTtcbiAgfVxuICByZXR1cm4gcm9vdC5kZXZpY2UubWtkaXIocm9vdC5yZXN0LCBwZXJtLCAvKiByYWlzZSBVbml4X2Vycm9yICovIHRydWUpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3VuaXhfcm1kaXJcbi8vUmVxdWlyZXM6IHJlc29sdmVfZnNfZGV2aWNlLCBjYW1sX2ZhaWx3aXRoXG4vL0FsaWFzOiB1bml4X3JtZGlyXG5mdW5jdGlvbiBjYW1sX3VuaXhfcm1kaXIobmFtZSkge1xuICB2YXIgcm9vdCA9IHJlc29sdmVfZnNfZGV2aWNlKG5hbWUpO1xuICBpZiAoIXJvb3QuZGV2aWNlLnJtZGlyKSB7XG4gICAgY2FtbF9mYWlsd2l0aChcImNhbWxfdW5peF9ybWRpcjogbm90IGltcGxlbWVudGVkXCIpO1xuICB9XG4gIHJldHVybiByb290LmRldmljZS5ybWRpcihyb290LnJlc3QsIC8qIHJhaXNlIFVuaXhfZXJyb3IgKi8gdHJ1ZSk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfdW5peF9zeW1saW5rXG4vL1JlcXVpcmVzOiByZXNvbHZlX2ZzX2RldmljZSwgY2FtbF9mYWlsd2l0aFxuLy9BbGlhczogdW5peF9zeW1saW5rXG5mdW5jdGlvbiBjYW1sX3VuaXhfc3ltbGluayh0b19kaXIsIHNyYywgZHN0KSB7XG4gIHZhciBzcmNfcm9vdCA9IHJlc29sdmVfZnNfZGV2aWNlKHNyYyk7XG4gIHZhciBkc3Rfcm9vdCA9IHJlc29sdmVfZnNfZGV2aWNlKGRzdCk7XG4gIGlmKHNyY19yb290LmRldmljZSAhPSBkc3Rfcm9vdC5kZXZpY2UpXG4gICAgY2FtbF9mYWlsd2l0aChcImNhbWxfdW5peF9zeW1saW5rOiBjYW5ub3Qgc3ltbGluayBiZXR3ZWVuIHR3byBmaWxlc3lzdGVtc1wiKTtcbiAgaWYgKCFzcmNfcm9vdC5kZXZpY2Uuc3ltbGluaykge1xuICAgIGNhbWxfZmFpbHdpdGgoXCJjYW1sX3VuaXhfc3ltbGluazogbm90IGltcGxlbWVudGVkXCIpO1xuICB9XG4gIHJldHVybiBzcmNfcm9vdC5kZXZpY2Uuc3ltbGluayh0b19kaXIsIHNyY19yb290LnJlc3QsIGRzdF9yb290LnJlc3QsIC8qIHJhaXNlIFVuaXhfZXJyb3IgKi8gdHJ1ZSk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfdW5peF9yZWFkbGlua1xuLy9SZXF1aXJlczogcmVzb2x2ZV9mc19kZXZpY2UsIGNhbWxfZmFpbHdpdGhcbi8vQWxpYXM6IHVuaXhfcmVhZGxpbmtcbmZ1bmN0aW9uIGNhbWxfdW5peF9yZWFkbGluayhuYW1lKSB7XG4gIHZhciByb290ID0gcmVzb2x2ZV9mc19kZXZpY2UobmFtZSk7XG4gIGlmICghcm9vdC5kZXZpY2UucmVhZGxpbmspIHtcbiAgICBjYW1sX2ZhaWx3aXRoKFwiY2FtbF91bml4X3JlYWRsaW5rOiBub3QgaW1wbGVtZW50ZWRcIik7XG4gIH1cbiAgcmV0dXJuIHJvb3QuZGV2aWNlLnJlYWRsaW5rKHJvb3QucmVzdCwgLyogcmFpc2UgVW5peF9lcnJvciAqLyB0cnVlKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF91bml4X3VubGlua1xuLy9SZXF1aXJlczogcmVzb2x2ZV9mc19kZXZpY2UsIGNhbWxfZmFpbHdpdGhcbi8vQWxpYXM6IHVuaXhfdW5saW5rXG5mdW5jdGlvbiBjYW1sX3VuaXhfdW5saW5rKG5hbWUpIHtcbiAgdmFyIHJvb3QgPSByZXNvbHZlX2ZzX2RldmljZShuYW1lKTtcbiAgaWYgKCFyb290LmRldmljZS51bmxpbmspIHtcbiAgICBjYW1sX2ZhaWx3aXRoKFwiY2FtbF91bml4X3VubGluazogbm90IGltcGxlbWVudGVkXCIpO1xuICB9XG4gIHJldHVybiByb290LmRldmljZS51bmxpbmsocm9vdC5yZXN0LCAvKiByYWlzZSBVbml4X2Vycm9yICovIHRydWUpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3VuaXhfZ2V0dWlkXG4vL1JlcXVpcmVzOiBjYW1sX3JhaXNlX25vdF9mb3VuZFxuLy9BbGlhczogdW5peF9nZXR1aWRcbmZ1bmN0aW9uIGNhbWxfdW5peF9nZXR1aWQodW5pdCkge1xuICBpZihnbG9iYWxUaGlzLnByb2Nlc3MgJiYgZ2xvYmFsVGhpcy5wcm9jZXNzLmdldHVpZCl7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXMucHJvY2Vzcy5nZXR1aWQoKTtcbiAgfVxuICBjYW1sX3JhaXNlX25vdF9mb3VuZCgpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3VuaXhfZ2V0cHd1aWRcbi8vUmVxdWlyZXM6IGNhbWxfcmFpc2Vfbm90X2ZvdW5kXG4vL0FsaWFzOiB1bml4X2dldHB3dWlkXG5mdW5jdGlvbiBjYW1sX3VuaXhfZ2V0cHd1aWQodW5pdCkge1xuICBjYW1sX3JhaXNlX25vdF9mb3VuZCgpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3VuaXhfaGFzX3N5bWxpbmtcbi8vUmVxdWlyZXM6IGZzX25vZGVfc3VwcG9ydGVkXG4vL0FsaWFzOiB1bml4X2hhc19zeW1saW5rXG5mdW5jdGlvbiBjYW1sX3VuaXhfaGFzX3N5bWxpbmsodW5pdCkge1xuICByZXR1cm4gZnNfbm9kZV9zdXBwb3J0ZWQoKT8xOjBcbn1cblxuLy9Qcm92aWRlczogY2FtbF91bml4X29wZW5kaXJcbi8vUmVxdWlyZXM6IHJlc29sdmVfZnNfZGV2aWNlLCBjYW1sX2ZhaWx3aXRoXG4vL0FsaWFzOiB1bml4X29wZW5kaXJcbmZ1bmN0aW9uIGNhbWxfdW5peF9vcGVuZGlyKHBhdGgpIHtcbiAgdmFyIHJvb3QgPSByZXNvbHZlX2ZzX2RldmljZShwYXRoKTtcbiAgaWYgKCFyb290LmRldmljZS5vcGVuZGlyKSB7XG4gICAgY2FtbF9mYWlsd2l0aChcImNhbWxfdW5peF9vcGVuZGlyOiBub3QgaW1wbGVtZW50ZWRcIik7XG4gIH1cbiAgdmFyIGRpcl9oYW5kbGUgPSByb290LmRldmljZS5vcGVuZGlyKHJvb3QucmVzdCwgLyogcmFpc2UgVW5peF9lcnJvciAqLyB0cnVlKTtcbiAgcmV0dXJuIHsgcG9pbnRlciA6IGRpcl9oYW5kbGUsIHBhdGg6IHBhdGggfVxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3VuaXhfcmVhZGRpclxuLy9SZXF1aXJlczogY2FtbF9yYWlzZV9lbmRfb2ZfZmlsZVxuLy9SZXF1aXJlczogY2FtbF9zdHJpbmdfb2ZfanNzdHJpbmdcbi8vUmVxdWlyZXM6IG1ha2VfdW5peF9lcnJfYXJncywgY2FtbF9yYWlzZV93aXRoX2FyZ3MsIGNhbWxfbmFtZWRfdmFsdWVcbi8vQWxpYXM6IHVuaXhfcmVhZGRpclxuZnVuY3Rpb24gY2FtbF91bml4X3JlYWRkaXIoZGlyX2hhbmRsZSkge1xuICB2YXIgZW50cnk7XG4gIHRyeSB7XG4gICAgICBlbnRyeSA9IGRpcl9oYW5kbGUucG9pbnRlci5yZWFkU3luYygpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgICB2YXIgdW5peF9lcnJvciA9IGNhbWxfbmFtZWRfdmFsdWUoJ1VuaXguVW5peF9lcnJvcicpO1xuICAgICAgY2FtbF9yYWlzZV93aXRoX2FyZ3ModW5peF9lcnJvciwgbWFrZV91bml4X2Vycl9hcmdzKFwiRUJBREZcIiwgXCJyZWFkZGlyXCIsIGRpcl9oYW5kbGUucGF0aCkpO1xuICB9XG4gIGlmIChlbnRyeSA9PT0gbnVsbCkge1xuICAgICAgY2FtbF9yYWlzZV9lbmRfb2ZfZmlsZSgpO1xuICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGNhbWxfc3RyaW5nX29mX2pzc3RyaW5nKGVudHJ5Lm5hbWUpO1xuICB9XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfdW5peF9jbG9zZWRpclxuLy9SZXF1aXJlczogbWFrZV91bml4X2Vycl9hcmdzLCBjYW1sX3JhaXNlX3dpdGhfYXJncywgY2FtbF9uYW1lZF92YWx1ZVxuLy9BbGlhczogdW5peF9jbG9zZWRpclxuZnVuY3Rpb24gY2FtbF91bml4X2Nsb3NlZGlyKGRpcl9oYW5kbGUpIHtcbiAgdHJ5IHtcbiAgICAgIGRpcl9oYW5kbGUucG9pbnRlci5jbG9zZVN5bmMoKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgICAgdmFyIHVuaXhfZXJyb3IgPSBjYW1sX25hbWVkX3ZhbHVlKCdVbml4LlVuaXhfZXJyb3InKTtcbiAgICAgIGNhbWxfcmFpc2Vfd2l0aF9hcmdzKHVuaXhfZXJyb3IsIG1ha2VfdW5peF9lcnJfYXJncyhcIkVCQURGXCIsIFwiY2xvc2VkaXJcIiwgZGlyX2hhbmRsZS5wYXRoKSk7XG4gIH1cbn1cblxuLy9Qcm92aWRlczogY2FtbF91bml4X3Jld2luZGRpclxuLy9SZXF1aXJlczogY2FtbF91bml4X2Nsb3NlZGlyLCBjYW1sX3VuaXhfb3BlbmRpclxuLy9BbGlhczogdW5peF9yZXdpbmRkaXJcbmZ1bmN0aW9uIGNhbWxfdW5peF9yZXdpbmRkaXIoZGlyX2hhbmRsZSkge1xuICBjYW1sX3VuaXhfY2xvc2VkaXIoZGlyX2hhbmRsZSk7XG4gIHZhciBuZXdfZGlyX2hhbmRsZSA9IGNhbWxfdW5peF9vcGVuZGlyKGRpcl9oYW5kbGUucGF0aCk7XG4gIGRpcl9oYW5kbGUucG9pbnRlciA9IG5ld19kaXJfaGFuZGxlLnBvaW50ZXI7XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3VuaXhfZmluZGZpcnN0XG4vL1JlcXVpcmVzOiBjYW1sX2pzc3RyaW5nX29mX3N0cmluZywgY2FtbF9zdHJpbmdfb2ZfanNzdHJpbmdcbi8vUmVxdWlyZXM6IGNhbWxfdW5peF9vcGVuZGlyLCBjYW1sX3VuaXhfcmVhZGRpclxuLy9BbGlhczogd2luX2ZpbmRmaXJzdFxuZnVuY3Rpb24gY2FtbF91bml4X2ZpbmRmaXJzdChwYXRoKSB7XG4gIC8vIFRoZSBXaW5kb3dzIGNvZGUgYWRkcyB0aGlzIGdsb2IgdG8gdGhlIHBhdGgsIHNvIHdlIG5lZWQgdG8gcmVtb3ZlIGl0XG4gIHZhciBwYXRoX2pzID0gY2FtbF9qc3N0cmluZ19vZl9zdHJpbmcocGF0aCk7XG4gIHBhdGhfanMgPSBwYXRoX2pzLnJlcGxhY2UoLyhefFtcXFxcXFwvXSlcXCpcXC5cXCokLywgXCJcIik7XG4gIHBhdGggPSBjYW1sX3N0cmluZ19vZl9qc3N0cmluZyhwYXRoX2pzKTtcbiAgLy8gKi4qIGlzIG5vdyBzdHJpcHBlZFxuICB2YXIgZGlyX2hhbmRsZSA9IGNhbWxfdW5peF9vcGVuZGlyKHBhdGgpO1xuICB2YXIgZmlyc3RfZW50cnkgPSBjYW1sX3VuaXhfcmVhZGRpcihkaXJfaGFuZGxlKTtcbiAgLy8gVGhlIFdpbmRvd3MgYmluZGluZ3MgdHlwZSBkaXJfaGFuZGxlIGFzIGFuIGBpbnRgIGJ1dCBpdCdzIG5vdCBpbiBKU1xuICByZXR1cm4gWzAsIGZpcnN0X2VudHJ5LCBkaXJfaGFuZGxlXTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF91bml4X2ZpbmRuZXh0XG4vL1JlcXVpcmVzOiBjYW1sX3VuaXhfcmVhZGRpclxuLy9BbGlhczogd2luX2ZpbmRuZXh0XG5mdW5jdGlvbiBjYW1sX3VuaXhfZmluZG5leHQoZGlyX2hhbmRsZSkge1xuICByZXR1cm4gY2FtbF91bml4X3JlYWRkaXIoZGlyX2hhbmRsZSk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfdW5peF9maW5kY2xvc2Vcbi8vUmVxdWlyZXM6IGNhbWxfdW5peF9jbG9zZWRpclxuLy9BbGlhczogd2luX2ZpbmRjbG9zZVxuZnVuY3Rpb24gY2FtbF91bml4X2ZpbmRjbG9zZShkaXJfaGFuZGxlKSB7XG4gIHJldHVybiBjYW1sX3VuaXhfY2xvc2VkaXIoZGlyX2hhbmRsZSk7XG59XG5cblxuLy9Qcm92aWRlczogY2FtbF91bml4X2luZXRfYWRkcl9vZl9zdHJpbmcgY29uc3Rcbi8vQWxpYXM6IHVuaXhfaW5ldF9hZGRyX29mX3N0cmluZ1xuZnVuY3Rpb24gY2FtbF91bml4X2luZXRfYWRkcl9vZl9zdHJpbmcgKCkge3JldHVybiAwO31cblxuXG4iLCIvLyBKc19vZl9vY2FtbCBydW50aW1lIHN1cHBvcnRcbi8vIGh0dHA6Ly93d3cub2NzaWdlbi5vcmcvanNfb2Zfb2NhbWwvXG4vLyBDb3B5cmlnaHQgKEMpIDIwMTAgSsOpcsO0bWUgVm91aWxsb25cbi8vIExhYm9yYXRvaXJlIFBQUyAtIENOUlMgVW5pdmVyc2l0w6kgUGFyaXMgRGlkZXJvdFxuLy9cbi8vIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4vLyBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbi8vIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHdpdGggbGlua2luZyBleGNlcHRpb247XG4vLyBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vL1xuLy8gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuLy8gR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vL1xuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4vLyBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcsIFVTQS5cblxuLy9Qcm92aWRlczogY2FtbF9jYWxsX2dlbiAoY29uc3QsIHNoYWxsb3cpXG4vL0lmOiAhZWZmZWN0c1xuLy9XZWFrZGVmXG5mdW5jdGlvbiBjYW1sX2NhbGxfZ2VuKGYsIGFyZ3MpIHtcbiAgdmFyIG4gPSAoZi5sID49IDApP2YubDooZi5sID0gZi5sZW5ndGgpO1xuICB2YXIgYXJnc0xlbiA9IGFyZ3MubGVuZ3RoO1xuICB2YXIgZCA9IG4gLSBhcmdzTGVuO1xuICBpZiAoZCA9PSAwKVxuICAgIHJldHVybiBmLmFwcGx5KG51bGwsIGFyZ3MpO1xuICBlbHNlIGlmIChkIDwgMCkge1xuICAgIHZhciBnID0gZi5hcHBseShudWxsLGFyZ3Muc2xpY2UoMCxuKSk7XG4gICAgaWYodHlwZW9mIGcgIT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIGc7XG4gICAgcmV0dXJuIGNhbWxfY2FsbF9nZW4oZyxhcmdzLnNsaWNlKG4pKTtcbiAgfVxuICBlbHNlIHtcbiAgICBzd2l0Y2ggKGQpIHtcbiAgICBjYXNlIDE6IHtcbiAgICAgIHZhciBnID0gZnVuY3Rpb24gKHgpe1xuICAgICAgICB2YXIgbmFyZ3MgPSBuZXcgQXJyYXkoYXJnc0xlbiArIDEpO1xuICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgYXJnc0xlbjsgaSsrICkgbmFyZ3NbaV0gPSBhcmdzW2ldO1xuICAgICAgICBuYXJnc1thcmdzTGVuXSA9IHg7XG4gICAgICAgIHJldHVybiBmLmFwcGx5KG51bGwsIG5hcmdzKVxuICAgICAgfTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBjYXNlIDI6IHtcbiAgICAgIHZhciBnID0gZnVuY3Rpb24gKHgsIHkpe1xuICAgICAgICB2YXIgbmFyZ3MgPSBuZXcgQXJyYXkoYXJnc0xlbiArIDIpO1xuICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgYXJnc0xlbjsgaSsrICkgbmFyZ3NbaV0gPSBhcmdzW2ldO1xuICAgICAgICBuYXJnc1thcmdzTGVuXSA9IHg7XG4gICAgICAgIG5hcmdzW2FyZ3NMZW4gKyAxXSA9IHk7XG4gICAgICAgIHJldHVybiBmLmFwcGx5KG51bGwsIG5hcmdzKVxuICAgICAgfTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBkZWZhdWx0OiB7XG4gICAgICB2YXIgZyA9IGZ1bmN0aW9uICgpe1xuICAgICAgICB2YXIgZXh0cmFfYXJncyA9IChhcmd1bWVudHMubGVuZ3RoID09IDApPzE6YXJndW1lbnRzLmxlbmd0aDtcbiAgICAgICAgdmFyIG5hcmdzID0gbmV3IEFycmF5KGFyZ3MubGVuZ3RoK2V4dHJhX2FyZ3MpO1xuICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKyApIG5hcmdzW2ldID0gYXJnc1tpXTtcbiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKyApIG5hcmdzW2FyZ3MubGVuZ3RoK2ldID0gYXJndW1lbnRzW2ldO1xuICAgICAgICByZXR1cm4gY2FtbF9jYWxsX2dlbihmLCBuYXJncylcbiAgICAgIH07XG4gICAgfX1cbiAgICBnLmwgPSBkO1xuICAgIHJldHVybiBnO1xuICB9XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfY2FsbF9nZW4gKGNvbnN0LCBzaGFsbG93KVxuLy9JZjogZWZmZWN0c1xuLy9XZWFrZGVmXG5mdW5jdGlvbiBjYW1sX2NhbGxfZ2VuKGYsIGFyZ3MpIHtcbiAgdmFyIG4gPSAoZi5sID49IDApP2YubDooZi5sID0gZi5sZW5ndGgpO1xuICB2YXIgYXJnc0xlbiA9IGFyZ3MubGVuZ3RoO1xuICB2YXIgZCA9IG4gLSBhcmdzTGVuO1xuICBpZiAoZCA9PSAwKSB7XG4gICAgcmV0dXJuIGYuYXBwbHkobnVsbCwgYXJncyk7XG4gIH0gZWxzZSBpZiAoZCA8IDApIHtcbiAgICB2YXIgcmVzdCA9IGFyZ3Muc2xpY2UobiAtIDEpO1xuICAgIHZhciBrID0gYXJncyBbYXJnc0xlbiAtIDFdO1xuICAgIGFyZ3MgPSBhcmdzLnNsaWNlKDAsIG4pO1xuICAgIGFyZ3NbbiAtIDFdID0gZnVuY3Rpb24gKGcpIHtcbiAgICAgIGlmICh0eXBlb2YgZyAhPT0gXCJmdW5jdGlvblwiKSByZXR1cm4gayhnKTtcbiAgICAgIHZhciBhcmdzID0gcmVzdC5zbGljZSgpO1xuICAgICAgYXJnc1thcmdzLmxlbmd0aCAtIDFdID0gaztcbiAgICAgIHJldHVybiBjYW1sX2NhbGxfZ2VuKGcsIGFyZ3MpOyB9O1xuICAgIHJldHVybiBmLmFwcGx5KG51bGwsIGFyZ3MpO1xuICB9IGVsc2Uge1xuICAgIGFyZ3NMZW4tLTtcbiAgICB2YXIgayA9IGFyZ3MgW2FyZ3NMZW5dO1xuICAgIHN3aXRjaCAoZCkge1xuICAgIGNhc2UgMToge1xuICAgICAgdmFyIGcgPSBmdW5jdGlvbiAoeCwgeSl7XG4gICAgICAgIHZhciBuYXJncyA9IG5ldyBBcnJheShhcmdzTGVuICsgMik7XG4gICAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBhcmdzTGVuOyBpKysgKSBuYXJnc1tpXSA9IGFyZ3NbaV07XG4gICAgICAgIG5hcmdzW2FyZ3NMZW5dID0geDtcbiAgICAgICAgbmFyZ3NbYXJnc0xlbiArIDFdID0geTtcbiAgICAgICAgcmV0dXJuIGYuYXBwbHkobnVsbCwgbmFyZ3MpXG4gICAgICB9O1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGNhc2UgMjoge1xuICAgICAgdmFyIGcgPSBmdW5jdGlvbiAoeCwgeSwgeil7XG4gICAgICAgIHZhciBuYXJncyA9IG5ldyBBcnJheShhcmdzTGVuICsgMyk7XG4gICAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBhcmdzTGVuOyBpKysgKSBuYXJnc1tpXSA9IGFyZ3NbaV07XG4gICAgICAgIG5hcmdzW2FyZ3NMZW5dID0geDtcbiAgICAgICAgbmFyZ3NbYXJnc0xlbiArIDFdID0geTtcbiAgICAgICAgbmFyZ3NbYXJnc0xlbiArIDJdID0gejtcbiAgICAgICAgcmV0dXJuIGYuYXBwbHkobnVsbCwgbmFyZ3MpXG4gICAgICB9O1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGRlZmF1bHQ6IHtcbiAgICAgIHZhciBnID0gZnVuY3Rpb24gKCl7XG4gICAgICAgIHZhciBleHRyYV9hcmdzID0gKGFyZ3VtZW50cy5sZW5ndGggPT0gMCk/MTphcmd1bWVudHMubGVuZ3RoO1xuICAgICAgICB2YXIgbmFyZ3MgPSBuZXcgQXJyYXkoYXJnc0xlbiArIGV4dHJhX2FyZ3MpO1xuICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgYXJnc0xlbjsgaSsrICkgbmFyZ3NbaV0gPSBhcmdzW2ldO1xuICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrIClcbiAgICAgICAgICBuYXJnc1thcmdzTGVuICsgaV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIHJldHVybiBjYW1sX2NhbGxfZ2VuKGYsIG5hcmdzKVxuICAgICAgfTtcbiAgICB9fVxuICAgIGcubCA9IGQgKyAxO1xuICAgIHJldHVybiBrKGcpO1xuICB9XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfbmFtZWRfdmFsdWVzXG52YXIgY2FtbF9uYW1lZF92YWx1ZXMgPSB7fTtcblxuLy9Qcm92aWRlczogY2FtbF9yZWdpc3Rlcl9uYW1lZF92YWx1ZSAoY29uc3QsbXV0YWJsZSlcbi8vUmVxdWlyZXM6IGNhbWxfbmFtZWRfdmFsdWVzLCBjYW1sX2pzYnl0ZXNfb2Zfc3RyaW5nXG5mdW5jdGlvbiBjYW1sX3JlZ2lzdGVyX25hbWVkX3ZhbHVlKG5tLHYpIHtcbiAgY2FtbF9uYW1lZF92YWx1ZXNbY2FtbF9qc2J5dGVzX29mX3N0cmluZyhubSldID0gdjtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfbmFtZWRfdmFsdWVcbi8vUmVxdWlyZXM6IGNhbWxfbmFtZWRfdmFsdWVzXG5mdW5jdGlvbiBjYW1sX25hbWVkX3ZhbHVlKG5tKSB7XG4gIHJldHVybiBjYW1sX25hbWVkX3ZhbHVlc1tubV1cbn1cblxuLy9Qcm92aWRlczogY2FtbF9nbG9iYWxfZGF0YVxudmFyIGNhbWxfZ2xvYmFsX2RhdGEgPSBbMF07XG5cbi8vUHJvdmlkZXM6IGNhbWxfYnVpbGRfc3ltYm9sc1xuLy9SZXF1aXJlczogY2FtbF9qc3N0cmluZ19vZl9zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfYnVpbGRfc3ltYm9scyhzeW1iKSB7XG4gIHZhciByID0ge307XG4gIGlmKHN5bWIpIHtcbiAgICBmb3IodmFyIGkgPSAxOyBpIDwgc3ltYi5sZW5ndGg7IGkrKyl7XG4gICAgICByW2NhbWxfanNzdHJpbmdfb2Zfc3RyaW5nKHN5bWJbaV1bMV0pXSA9IHN5bWJbaV1bMl1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfcmVnaXN0ZXJfZ2xvYmFsIChjb25zdCwgc2hhbGxvdywgY29uc3QpXG4vL1JlcXVpcmVzOiBjYW1sX2dsb2JhbF9kYXRhLCBjYW1sX2NhbGxiYWNrLCBjYW1sX2J1aWxkX3N5bWJvbHNcbi8vUmVxdWlyZXM6IGNhbWxfZmFpbHdpdGhcbmZ1bmN0aW9uIGNhbWxfcmVnaXN0ZXJfZ2xvYmFsIChuLCB2LCBuYW1lX29wdCkge1xuICBpZiAobmFtZV9vcHQpIHtcbiAgICB2YXIgbmFtZSA9IG5hbWVfb3B0O1xuICAgIGlmKGdsb2JhbFRoaXMudG9wbGV2ZWxSZWxvYykge1xuICAgICAgbiA9IGNhbWxfY2FsbGJhY2soZ2xvYmFsVGhpcy50b3BsZXZlbFJlbG9jLCBbbmFtZV0pO1xuICAgIH1cbiAgICBlbHNlIGlmIChjYW1sX2dsb2JhbF9kYXRhLnN5bWJvbHMpIHtcbiAgICAgIGlmKCFjYW1sX2dsb2JhbF9kYXRhLnN5bWlkeCkge1xuICAgICAgICBjYW1sX2dsb2JhbF9kYXRhLnN5bWlkeCA9IGNhbWxfYnVpbGRfc3ltYm9scyhjYW1sX2dsb2JhbF9kYXRhLnN5bWJvbHMpXG4gICAgICB9XG4gICAgICB2YXIgbmlkID0gY2FtbF9nbG9iYWxfZGF0YS5zeW1pZHhbbmFtZV1cbiAgICAgIGlmKG5pZCA+PSAwKVxuICAgICAgICBuID0gbmlkXG4gICAgICBlbHNlIHtcbiAgICAgICAgY2FtbF9mYWlsd2l0aChcImNhbWxfcmVnaXN0ZXJfZ2xvYmFsOiBjYW5ub3QgbG9jYXRlIFwiICsgbmFtZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGNhbWxfZ2xvYmFsX2RhdGFbbiArIDFdID0gdjtcbiAgaWYobmFtZV9vcHQpIGNhbWxfZ2xvYmFsX2RhdGFbbmFtZV9vcHRdID0gdjtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9nZXRfZ2xvYmFsX2RhdGEgbXV0YWJsZVxuLy9SZXF1aXJlczogY2FtbF9nbG9iYWxfZGF0YVxuZnVuY3Rpb24gY2FtbF9nZXRfZ2xvYmFsX2RhdGEgKCkgeyByZXR1cm4gY2FtbF9nbG9iYWxfZGF0YTsgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2lzX3ByaW50YWJsZSBjb25zdCAoY29uc3QpXG5mdW5jdGlvbiBjYW1sX2lzX3ByaW50YWJsZShjKSB7IHJldHVybiArKGMgPiAzMSAmJiBjIDwgMTI3KTsgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21heWJlX3ByaW50X3N0YXRzXG5mdW5jdGlvbiBjYW1sX21heWJlX3ByaW50X3N0YXRzKHVuaXQpIHsgcmV0dXJuIDAgfVxuIiwiLy8gSnNfb2Zfb2NhbWwgcnVudGltZSBzdXBwb3J0XG4vLyBodHRwOi8vd3d3Lm9jc2lnZW4ub3JnL2pzX29mX29jYW1sL1xuLy9cbi8vIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4vLyBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbi8vIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHdpdGggbGlua2luZyBleGNlcHRpb247XG4vLyBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vL1xuLy8gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuLy8gR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vL1xuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4vLyBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcsIFVTQS5cblxuLy8vLy8vLy8vLy8vLyBTeXNcblxuLy9Qcm92aWRlczogY2FtbF9yYWlzZV9zeXNfZXJyb3IgKGNvbnN0KVxuLy9SZXF1aXJlczogY2FtbF9yYWlzZV93aXRoX3N0cmluZywgY2FtbF9nbG9iYWxfZGF0YVxuZnVuY3Rpb24gY2FtbF9yYWlzZV9zeXNfZXJyb3IgKG1zZykge1xuICBjYW1sX3JhaXNlX3dpdGhfc3RyaW5nKGNhbWxfZ2xvYmFsX2RhdGEuU3lzX2Vycm9yLCBtc2cpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N5c19leGl0XG4vL1JlcXVpcmVzOiBjYW1sX2ludmFsaWRfYXJndW1lbnRcbmZ1bmN0aW9uIGNhbWxfc3lzX2V4aXQgKGNvZGUpIHtcbiAgaWYoZ2xvYmFsVGhpcy5xdWl0KSBnbG9iYWxUaGlzLnF1aXQoY29kZSk7XG4gIC8vbm9kZWpzXG4gIGlmKGdsb2JhbFRoaXMucHJvY2VzcyAmJiBnbG9iYWxUaGlzLnByb2Nlc3MuZXhpdClcbiAgICBnbG9iYWxUaGlzLnByb2Nlc3MuZXhpdChjb2RlKTtcbiAgY2FtbF9pbnZhbGlkX2FyZ3VtZW50KFwiRnVuY3Rpb24gJ2V4aXQnIG5vdCBpbXBsZW1lbnRlZFwiKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9pc19zcGVjaWFsX2V4Y2VwdGlvblxuZnVuY3Rpb24gY2FtbF9pc19zcGVjaWFsX2V4Y2VwdGlvbihleG4pe1xuICBzd2l0Y2goZXhuWzJdKSB7XG4gIGNhc2UgLTg6IC8vIE1hdGNoX2ZhaWx1cmVcbiAgY2FzZSAtMTE6IC8vIEFzc2VydF9mYWlsdXJlXG4gIGNhc2UgLTEyOiAvLyBVbmRlZmluZWRfcmVjdXJzaXZlX21vZHVsZVxuICAgIHJldHVybiAxO1xuICBkZWZhdWx0OlxuICAgIHJldHVybiAwO1xuICB9XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfZm9ybWF0X2V4Y2VwdGlvblxuLy9SZXF1aXJlczogTWxCeXRlcywgY2FtbF9pc19zcGVjaWFsX2V4Y2VwdGlvblxuZnVuY3Rpb24gY2FtbF9mb3JtYXRfZXhjZXB0aW9uKGV4bil7XG4gIHZhciByID0gXCJcIjtcbiAgaWYoZXhuWzBdID09IDApIHtcbiAgICByICs9IGV4blsxXVsxXTtcbiAgICBpZihleG4ubGVuZ3RoID09IDMgJiYgZXhuWzJdWzBdID09IDAgJiYgY2FtbF9pc19zcGVjaWFsX2V4Y2VwdGlvbihleG5bMV0pKSB7XG5cbiAgICAgIHZhciBidWNrZXQgPSBleG5bMl07XG4gICAgICB2YXIgc3RhcnQgPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgc3RhcnQgPSAyXG4gICAgICB2YXIgYnVja2V0ID0gZXhuO1xuICAgIH1cbiAgICByICs9IFwiKFwiO1xuICAgIGZvcih2YXIgaSA9IHN0YXJ0OyBpIDwgYnVja2V0Lmxlbmd0aDsgaSArKyl7XG4gICAgICBpZihpID4gc3RhcnQpIHIrPVwiLCBcIjtcbiAgICAgIHZhciB2ID0gYnVja2V0W2ldXG4gICAgICBpZih0eXBlb2YgdiA9PSBcIm51bWJlclwiKVxuICAgICAgICByKz0gdi50b1N0cmluZygpO1xuICAgICAgZWxzZSBpZih2IGluc3RhbmNlb2YgTWxCeXRlcyl7XG4gICAgICAgIHIrPSAnXCInICsgdi50b1N0cmluZygpICsgJ1wiJztcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYodHlwZW9mIHYgPT0gXCJzdHJpbmdcIil7XG4gICAgICAgIHIrPSAnXCInICsgdi50b1N0cmluZygpICsgJ1wiJztcbiAgICAgIH1cbiAgICAgIGVsc2UgciArPSBcIl9cIjtcbiAgICB9XG4gICAgciArPSBcIilcIlxuICB9IGVsc2UgaWYgKGV4blswXSA9PSAyNDgpe1xuICAgIHIgKz0gZXhuWzFdXG4gIH1cbiAgcmV0dXJuIHJcbn1cblxuLy9Qcm92aWRlczogY2FtbF9mYXRhbF91bmNhdWdodF9leGNlcHRpb25cbi8vUmVxdWlyZXM6IGNhbWxfbmFtZWRfdmFsdWUsIGNhbWxfZm9ybWF0X2V4Y2VwdGlvbiwgY2FtbF9jYWxsYmFja1xuZnVuY3Rpb24gY2FtbF9mYXRhbF91bmNhdWdodF9leGNlcHRpb24oZXJyKXtcbiAgaWYoZXJyIGluc3RhbmNlb2YgQXJyYXkgJiYgKGVyclswXSA9PSAwIHx8IGVyclswXSA9PSAyNDgpKSB7XG4gICAgdmFyIGhhbmRsZXIgPSBjYW1sX25hbWVkX3ZhbHVlKFwiUHJpbnRleGMuaGFuZGxlX3VuY2F1Z2h0X2V4Y2VwdGlvblwiKTtcbiAgICBpZihoYW5kbGVyKSBjYW1sX2NhbGxiYWNrKGhhbmRsZXIsIFtlcnIsZmFsc2VdKTtcbiAgICBlbHNlIHtcbiAgICAgIHZhciBtc2cgPSBjYW1sX2Zvcm1hdF9leGNlcHRpb24oZXJyKTtcbiAgICAgIHZhciBhdF9leGl0ID0gY2FtbF9uYW1lZF92YWx1ZShcIlBlcnZhc2l2ZXMuZG9fYXRfZXhpdFwiKTtcbiAgICAgIGlmKGF0X2V4aXQpIGNhbWxfY2FsbGJhY2soYXRfZXhpdCwgWzBdKTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJGYXRhbCBlcnJvcjogZXhjZXB0aW9uIFwiICsgbXNnKTtcbiAgICAgIGlmKGVyci5qc19lcnJvcikgdGhyb3cgZXJyLmpzX2Vycm9yO1xuICAgIH1cbiAgfVxuICBlbHNlIHtcbiAgICB0aHJvdyBlcnJcbiAgfVxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3NldF9zdGF0aWNfZW52XG5mdW5jdGlvbiBjYW1sX3NldF9zdGF0aWNfZW52KGssdil7XG4gIGlmKCFnbG9iYWxUaGlzLmpzb29fc3RhdGljX2VudilcbiAgICBnbG9iYWxUaGlzLmpzb29fc3RhdGljX2VudiA9IHt9XG4gIGdsb2JhbFRoaXMuanNvb19zdGF0aWNfZW52W2tdID0gdjtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGpzb29fc3lzX2dldGVudiAoY29uc3QpXG5mdW5jdGlvbiBqc29vX3N5c19nZXRlbnYobikge1xuICB2YXIgcHJvY2VzcyA9IGdsb2JhbFRoaXMucHJvY2VzcztcbiAgLy9ub2RlanMgZW52XG4gIGlmKHByb2Nlc3NcbiAgICAgJiYgcHJvY2Vzcy5lbnZcbiAgICAgJiYgcHJvY2Vzcy5lbnZbbl0gIT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBwcm9jZXNzLmVudltuXTtcbiAgaWYoZ2xvYmFsVGhpcy5qc29vX3N0YXRpY19lbnZcbiAgICAgJiYgZ2xvYmFsVGhpcy5qc29vX3N0YXRpY19lbnZbbl0pXG4gICAgcmV0dXJuIGdsb2JhbFRoaXMuanNvb19zdGF0aWNfZW52W25dXG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3lzX2dldGVudiAoY29uc3QpXG4vL1JlcXVpcmVzOiBjYW1sX3JhaXNlX25vdF9mb3VuZFxuLy9SZXF1aXJlczogY2FtbF9zdHJpbmdfb2ZfanNzdHJpbmdcbi8vUmVxdWlyZXM6IGNhbWxfanNzdHJpbmdfb2Zfc3RyaW5nXG4vL1JlcXVpcmVzOiBqc29vX3N5c19nZXRlbnZcbmZ1bmN0aW9uIGNhbWxfc3lzX2dldGVudiAobmFtZSkge1xuICB2YXIgciA9IGpzb29fc3lzX2dldGVudihjYW1sX2pzc3RyaW5nX29mX3N0cmluZyhuYW1lKSk7XG4gIGlmKHIgPT09IHVuZGVmaW5lZClcbiAgICBjYW1sX3JhaXNlX25vdF9mb3VuZCAoKTtcbiAgcmV0dXJuIGNhbWxfc3RyaW5nX29mX2pzc3RyaW5nKHIpXG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3lzX3Vuc2FmZV9nZXRlbnZcbi8vUmVxdWlyZXM6IGNhbWxfc3lzX2dldGVudlxuZnVuY3Rpb24gY2FtbF9zeXNfdW5zYWZlX2dldGVudihuYW1lKXtcbiAgcmV0dXJuIGNhbWxfc3lzX2dldGVudiAobmFtZSk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfYXJndlxuLy9SZXF1aXJlczogY2FtbF9zdHJpbmdfb2ZfanNzdHJpbmdcbnZhciBjYW1sX2FyZ3YgPSAoKGZ1bmN0aW9uICgpIHtcbiAgdmFyIHByb2Nlc3MgPSBnbG9iYWxUaGlzLnByb2Nlc3M7XG4gIHZhciBtYWluID0gXCJhLm91dFwiO1xuICB2YXIgYXJncyA9IFtdXG5cbiAgaWYocHJvY2Vzc1xuICAgICAmJiBwcm9jZXNzLmFyZ3ZcbiAgICAgJiYgcHJvY2Vzcy5hcmd2Lmxlbmd0aCA+IDEpIHtcbiAgICB2YXIgYXJndiA9IHByb2Nlc3MuYXJndlxuICAgIC8vbm9kZWpzXG4gICAgbWFpbiA9IGFyZ3ZbMV07XG4gICAgYXJncyA9IGFyZ3Yuc2xpY2UoMik7XG4gIH1cblxuICB2YXIgcCA9IGNhbWxfc3RyaW5nX29mX2pzc3RyaW5nKG1haW4pO1xuICB2YXIgYXJnczIgPSBbMCwgcF07XG4gIGZvcih2YXIgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKVxuICAgIGFyZ3MyLnB1c2goY2FtbF9zdHJpbmdfb2ZfanNzdHJpbmcoYXJnc1tpXSkpO1xuICByZXR1cm4gYXJnczI7XG59KSgpKVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2V4ZWN1dGFibGVfbmFtZVxuLy9SZXF1aXJlczogY2FtbF9hcmd2XG52YXIgY2FtbF9leGVjdXRhYmxlX25hbWUgPSBjYW1sX2FyZ3ZbMV1cblxuLy9Qcm92aWRlczogY2FtbF9zeXNfZ2V0X2FyZ3Zcbi8vUmVxdWlyZXM6IGNhbWxfYXJndlxuZnVuY3Rpb24gY2FtbF9zeXNfZ2V0X2FyZ3YgKGEpIHtcbiAgcmV0dXJuIFswLCBjYW1sX2FyZ3ZbMV0sIGNhbWxfYXJndl07XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3lzX2FyZ3Zcbi8vUmVxdWlyZXM6IGNhbWxfYXJndlxuZnVuY3Rpb24gY2FtbF9zeXNfYXJndiAoYSkge1xuICByZXR1cm4gY2FtbF9hcmd2O1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N5c19tb2RpZnlfYXJndlxuLy9SZXF1aXJlczogY2FtbF9hcmd2XG5mdW5jdGlvbiBjYW1sX3N5c19tb2RpZnlfYXJndihhcmcpe1xuICBjYW1sX2FyZ3YgPSBhcmc7XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N5c19leGVjdXRhYmxlX25hbWUgY29uc3Rcbi8vUmVxdWlyZXM6IGNhbWxfZXhlY3V0YWJsZV9uYW1lXG5mdW5jdGlvbiBjYW1sX3N5c19leGVjdXRhYmxlX25hbWUoYSl7XG4gIHJldHVybiBjYW1sX2V4ZWN1dGFibGVfbmFtZVxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N5c19zeXN0ZW1fY29tbWFuZFxuLy9SZXF1aXJlczogY2FtbF9qc3N0cmluZ19vZl9zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfc3lzX3N5c3RlbV9jb21tYW5kKGNtZCl7XG4gIHZhciBjbWQgPSBjYW1sX2pzc3RyaW5nX29mX3N0cmluZyhjbWQpO1xuICBpZiAodHlwZW9mIHJlcXVpcmUgIT0gXCJ1bmRlZmluZWRcIil7XG4gICAgdmFyIGNoaWxkX3Byb2Nlc3MgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJyk7XG4gICAgaWYoY2hpbGRfcHJvY2VzcyAmJiBjaGlsZF9wcm9jZXNzLmV4ZWNTeW5jKVxuICAgICAgdHJ5IHtcbiAgICAgICAgY2hpbGRfcHJvY2Vzcy5leGVjU3luYyhjbWQse3N0ZGlvOiAnaW5oZXJpdCd9KTtcbiAgICAgICAgcmV0dXJuIDBcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIDFcbiAgICAgIH1cbiAgfVxuICBlbHNlIHJldHVybiAxMjc7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3lzX3N5c3RlbV9jb21tYW5kXG4vL1JlcXVpcmVzOiBjYW1sX2pzc3RyaW5nX29mX3N0cmluZ1xuLy9JZjogYnJvd3NlclxuZnVuY3Rpb24gY2FtbF9zeXNfc3lzdGVtX2NvbW1hbmQoY21kKXtcbiAgcmV0dXJuIDEyNztcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zeXNfdGltZSBtdXRhYmxlXG52YXIgY2FtbF9pbml0aWFsX3RpbWUgPSAobmV3IERhdGUoKSkuZ2V0VGltZSgpICogMC4wMDE7XG5mdW5jdGlvbiBjYW1sX3N5c190aW1lICgpIHtcbiAgdmFyIG5vdyA9IChuZXcgRGF0ZSgpKS5nZXRUaW1lKCk7XG4gIHJldHVybiBub3cgKiAwLjAwMSAtIGNhbWxfaW5pdGlhbF90aW1lO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N5c190aW1lX2luY2x1ZGVfY2hpbGRyZW5cbi8vUmVxdWlyZXM6IGNhbWxfc3lzX3RpbWVcbmZ1bmN0aW9uIGNhbWxfc3lzX3RpbWVfaW5jbHVkZV9jaGlsZHJlbihiKSB7XG4gIHJldHVybiBjYW1sX3N5c190aW1lKCk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3lzX3JhbmRvbV9zZWVkIG11dGFibGVcbi8vVGhlIGZ1bmN0aW9uIG5lZWRzIHRvIHJldHVybiBhbiBhcnJheSBzaW5jZSBPQ2FtbCA0LjAuLi5cbmZ1bmN0aW9uIGNhbWxfc3lzX3JhbmRvbV9zZWVkICgpIHtcbiAgaWYgKGdsb2JhbFRoaXMuY3J5cHRvKSB7XG4gICAgIGlmIChnbG9iYWxUaGlzLmNyeXB0by5nZXRSYW5kb21WYWx1ZXMpIHtcbiAgICAgICB2YXIgYSA9IGdsb2JhbFRoaXMuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhuZXcgSW50MzJBcnJheSg0KSk7XG4gICAgICAgcmV0dXJuIFswLCBhWzBdLCBhWzFdLCBhWzJdLCBhWzNdXTtcbiAgICAgfSBlbHNlIGlmIChnbG9iYWxUaGlzLmNyeXB0by5yYW5kb21CeXRlcykge1xuICAgICAgIHZhciBhID0gbmV3IEludDMyQXJyYXkoZ2xvYmFsVGhpcy5jcnlwdG8ucmFuZG9tQnl0ZXMoMTYpLmJ1ZmZlcik7XG4gICAgICAgcmV0dXJuIFswLCBhWzBdLCBhWzFdLCBhWzJdLCBhWzNdXTtcbiAgICAgfVxuICB9XG4gIHZhciBub3cgPSAobmV3IERhdGUoKSkuZ2V0VGltZSgpO1xuICB2YXIgeCA9IG5vd14weGZmZmZmZmZmKk1hdGgucmFuZG9tKCk7XG4gIHJldHVybiBbMCx4XTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zeXNfY29uc3RfYmlnX2VuZGlhbiBjb25zdFxuZnVuY3Rpb24gY2FtbF9zeXNfY29uc3RfYmlnX2VuZGlhbiAoKSB7IHJldHVybiAwOyB9XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3lzX2NvbnN0X3dvcmRfc2l6ZSBjb25zdFxuZnVuY3Rpb24gY2FtbF9zeXNfY29uc3Rfd29yZF9zaXplICgpIHsgcmV0dXJuIDMyOyB9XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3lzX2NvbnN0X2ludF9zaXplIGNvbnN0XG5mdW5jdGlvbiBjYW1sX3N5c19jb25zdF9pbnRfc2l6ZSAoKSB7IHJldHVybiAzMjsgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N5c19jb25zdF9tYXhfd29zaXplIGNvbnN0XG4vLyBtYXhfaW50IC8gNCBzbyB0aGF0IHRoZSBmb2xsb3dpbmcgZG9lcyBub3Qgb3ZlcmZsb3dcbi8vbGV0IG1heF9zdHJpbmdfbGVuZ3RoID0gd29yZF9zaXplIC8gOCAqIG1heF9hcnJheV9sZW5ndGggLSAxOztcbmZ1bmN0aW9uIGNhbWxfc3lzX2NvbnN0X21heF93b3NpemUgKCkgeyByZXR1cm4gKDB4N0ZGRkZGRkYvNCkgfCAwO31cblxuLy9Qcm92aWRlczogY2FtbF9zeXNfY29uc3Rfb3N0eXBlX3VuaXggY29uc3Rcbi8vUmVxdWlyZXM6IG9zX3R5cGVcbmZ1bmN0aW9uIGNhbWxfc3lzX2NvbnN0X29zdHlwZV91bml4ICgpIHsgcmV0dXJuIG9zX3R5cGUgPT0gXCJVbml4XCIgPyAxIDogMDsgfVxuLy9Qcm92aWRlczogY2FtbF9zeXNfY29uc3Rfb3N0eXBlX3dpbjMyIGNvbnN0XG4vL1JlcXVpcmVzOiBvc190eXBlXG5mdW5jdGlvbiBjYW1sX3N5c19jb25zdF9vc3R5cGVfd2luMzIgKCkgeyByZXR1cm4gb3NfdHlwZSA9PSBcIldpbjMyXCIgPyAxIDogMDsgfVxuLy9Qcm92aWRlczogY2FtbF9zeXNfY29uc3Rfb3N0eXBlX2N5Z3dpbiBjb25zdFxuLy9SZXF1aXJlczogb3NfdHlwZVxuZnVuY3Rpb24gY2FtbF9zeXNfY29uc3Rfb3N0eXBlX2N5Z3dpbiAoKSB7IHJldHVybiBvc190eXBlID09IFwiQ3lnd2luXCIgPyAxIDogMDsgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N5c19jb25zdF9iYWNrZW5kX3R5cGUgY29uc3Rcbi8vUmVxdWlyZXM6IGNhbWxfc3RyaW5nX29mX2pzYnl0ZXNcbmZ1bmN0aW9uIGNhbWxfc3lzX2NvbnN0X2JhY2tlbmRfdHlwZSAoKSB7XG4gIHJldHVybiBbMCwgY2FtbF9zdHJpbmdfb2ZfanNieXRlcyhcImpzX29mX29jYW1sXCIpXTtcbn1cblxuLy9Qcm92aWRlczogb3NfdHlwZVxudmFyIG9zX3R5cGUgPSAoZ2xvYmFsVGhpcy5wcm9jZXNzICYmXG4gICAgICAgICAgICAgICBnbG9iYWxUaGlzLnByb2Nlc3MucGxhdGZvcm0gJiZcbiAgICAgICAgICAgICAgIGdsb2JhbFRoaXMucHJvY2Vzcy5wbGF0Zm9ybSA9PSBcIndpbjMyXCIpID8gXCJDeWd3aW5cIiA6IFwiVW5peFwiO1xuXG5cbi8vUHJvdmlkZXM6IGNhbWxfc3lzX2dldF9jb25maWcgY29uc3Rcbi8vUmVxdWlyZXM6IGNhbWxfc3RyaW5nX29mX2pzYnl0ZXMsIG9zX3R5cGVcbmZ1bmN0aW9uIGNhbWxfc3lzX2dldF9jb25maWcgKCkge1xuICByZXR1cm4gWzAsIGNhbWxfc3RyaW5nX29mX2pzYnl0ZXMob3NfdHlwZSksIDMyLCAwXTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zeXNfaXNhdHR5XG5mdW5jdGlvbiBjYW1sX3N5c19pc2F0dHkoX2NoYW4pIHtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfcnVudGltZV92YXJpYW50XG4vL1JlcXVpcmVzOiBjYW1sX3N0cmluZ19vZl9qc2J5dGVzXG5mdW5jdGlvbiBjYW1sX3J1bnRpbWVfdmFyaWFudChfdW5pdCkge1xuICByZXR1cm4gY2FtbF9zdHJpbmdfb2ZfanNieXRlcyhcIlwiKTtcbn1cbi8vUHJvdmlkZXM6IGNhbWxfcnVudGltZV9wYXJhbWV0ZXJzXG4vL1JlcXVpcmVzOiBjYW1sX3N0cmluZ19vZl9qc2J5dGVzXG5mdW5jdGlvbiBjYW1sX3J1bnRpbWVfcGFyYW1ldGVycyhfdW5pdCkge1xuICByZXR1cm4gY2FtbF9zdHJpbmdfb2ZfanNieXRlcyhcIlwiKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9pbnN0YWxsX3NpZ25hbF9oYW5kbGVyIGNvbnN0XG5mdW5jdGlvbiBjYW1sX2luc3RhbGxfc2lnbmFsX2hhbmRsZXIoKXtyZXR1cm4gMH1cblxuLy9Qcm92aWRlczogY2FtbF9ydW50aW1lX3dhcm5pbmdzXG52YXIgY2FtbF9ydW50aW1lX3dhcm5pbmdzID0gMDtcblxuLy9Qcm92aWRlczogY2FtbF9tbF9lbmFibGVfcnVudGltZV93YXJuaW5nc1xuLy9SZXF1aXJlczogY2FtbF9ydW50aW1lX3dhcm5pbmdzXG5mdW5jdGlvbiBjYW1sX21sX2VuYWJsZV9ydW50aW1lX3dhcm5pbmdzIChib29sKSB7XG4gIGNhbWxfcnVudGltZV93YXJuaW5ncyA9IGJvb2w7XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21sX3J1bnRpbWVfd2FybmluZ3NfZW5hYmxlZFxuLy9SZXF1aXJlczogY2FtbF9ydW50aW1lX3dhcm5pbmdzXG5mdW5jdGlvbiBjYW1sX21sX3J1bnRpbWVfd2FybmluZ3NfZW5hYmxlZCAoX3VuaXQpIHtcbiAgcmV0dXJuIGNhbWxfcnVudGltZV93YXJuaW5ncztcbn1cblxuXG4vL1Byb3ZpZGVzOiBjYW1sX3NwYWNldGltZV9lbmFibGVkIGNvbnN0IChjb25zdClcbmZ1bmN0aW9uIGNhbWxfc3BhY2V0aW1lX2VuYWJsZWQoX3VuaXQpIHtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3lzX2NvbnN0X25ha2VkX3BvaW50ZXJzX2NoZWNrZWQgY29uc3QgKGNvbnN0KVxuZnVuY3Rpb24gY2FtbF9zeXNfY29uc3RfbmFrZWRfcG9pbnRlcnNfY2hlY2tlZChfdW5pdCkge1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9yZWdpc3Rlcl9jaGFubmVsX2Zvcl9zcGFjZXRpbWUgY29uc3QgKGNvbnN0KVxuZnVuY3Rpb24gY2FtbF9yZWdpc3Rlcl9jaGFubmVsX2Zvcl9zcGFjZXRpbWUoX2NoYW5uZWwpIHtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3BhY2V0aW1lX29ubHlfd29ya3NfZm9yX25hdGl2ZV9jb2RlXG4vL1JlcXVpcmVzOiBjYW1sX2ZhaWx3aXRoXG5mdW5jdGlvbiBjYW1sX3NwYWNldGltZV9vbmx5X3dvcmtzX2Zvcl9uYXRpdmVfY29kZSgpIHtcbiAgY2FtbF9mYWlsd2l0aChcIlNwYWNldGltZSBwcm9maWxpbmcgb25seSB3b3JrcyBmb3IgbmF0aXZlIGNvZGVcIik7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfeGRnX2RlZmF1bHRzXG4vL1ZlcnNpb246ID49IDUuMlxuZnVuY3Rpb24gY2FtbF94ZGdfZGVmYXVsdHMoX3VuaXQpIHtcbiAgcmV0dXJuIDA7IC8vIGVtcHR5IGxpc3Rcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zeXNfaXNfcmVndWxhcl9maWxlXG4vL1JlcXVpcmVzOiByZXNvbHZlX2ZzX2RldmljZVxuZnVuY3Rpb24gY2FtbF9zeXNfaXNfcmVndWxhcl9maWxlKG5hbWUpIHtcbiAgdmFyIHJvb3QgPSByZXNvbHZlX2ZzX2RldmljZShuYW1lKTtcbiAgcmV0dXJuIHJvb3QuZGV2aWNlLmlzRmlsZShyb290LnJlc3QpO1xufVxuLy9BbHdheXNcbi8vUmVxdWlyZXM6IGNhbWxfZmF0YWxfdW5jYXVnaHRfZXhjZXB0aW9uXG5mdW5jdGlvbiBjYW1sX3NldHVwX3VuY2F1Z2h0X2V4Y2VwdGlvbl9oYW5kbGVyKCkge1xuICB2YXIgcHJvY2VzcyA9IGdsb2JhbFRoaXMucHJvY2VzcztcbiAgaWYocHJvY2VzcyAmJiBwcm9jZXNzLm9uKSB7XG4gICAgcHJvY2Vzcy5vbigndW5jYXVnaHRFeGNlcHRpb24nLCBmdW5jdGlvbiAoZXJyLCBvcmlnaW4pIHtcbiAgICAgIGNhbWxfZmF0YWxfdW5jYXVnaHRfZXhjZXB0aW9uKGVycik7XG4gICAgICBwcm9jZXNzLmV4aXQgKDIpO1xuICAgIH0pXG4gIH1cbiAgZWxzZSBpZihnbG9iYWxUaGlzLmFkZEV2ZW50TGlzdGVuZXIpe1xuICAgIGdsb2JhbFRoaXMuYWRkRXZlbnRMaXN0ZW5lcignZXJyb3InLCBmdW5jdGlvbihldmVudCl7XG4gICAgICBpZihldmVudC5lcnJvcil7XG4gICAgICAgIGNhbWxfZmF0YWxfdW5jYXVnaHRfZXhjZXB0aW9uKGV2ZW50LmVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuY2FtbF9zZXR1cF91bmNhdWdodF9leGNlcHRpb25faGFuZGxlcigpO1xuXG5cbiIsIi8vIEpzX29mX29jYW1sIHJ1bnRpbWUgc3VwcG9ydFxuLy8gaHR0cDovL3d3dy5vY3NpZ2VuLm9yZy9qc19vZl9vY2FtbC9cbi8vXG4vLyBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuLy8gaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4vLyB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCB3aXRoIGxpbmtpbmcgZXhjZXB0aW9uO1xuLy8gZWl0aGVyIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy9cbi8vIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbi8vIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy9cbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuLy8gYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuXG5cblxuLy9Qcm92aWRlczogY2FtbF9yZWNvcmRfYmFja3RyYWNlX2ZsYWdcbi8vUmVxdWlyZXM6IGpzb29fc3lzX2dldGVudlxudmFyIGNhbWxfcmVjb3JkX2JhY2t0cmFjZV9mbGFnID0gRkxBRyhcIndpdGgtanMtZXJyb3JcIik7XG5cbihmdW5jdGlvbiAoKSB7XG4gIHZhciByID0ganNvb19zeXNfZ2V0ZW52KFwiT0NBTUxSVU5QQVJBTVwiKVxuICBpZihyICE9PSB1bmRlZmluZWQpe1xuICAgIHZhciBsID0gci5zcGxpdChcIixcIik7XG4gICAgZm9yKHZhciBpID0gMDsgaSA8IGwubGVuZ3RoOyBpKyspe1xuICAgICAgaWYobFtpXSA9PSBcImJcIikgeyBjYW1sX3JlY29yZF9iYWNrdHJhY2VfZmxhZyA9IDE7IGJyZWFrIH1cbiAgICAgIGVsc2UgaWYgKGxbaV0uc3RhcnRzV2l0aChcImI9XCIpKSB7XG4gICAgICAgIGNhbWxfcmVjb3JkX2JhY2t0cmFjZV9mbGFnID0gKyhsW2ldLnNsaWNlKDIpKX1cbiAgICAgIGVsc2UgY29udGludWU7XG4gICAgfVxuICB9XG59KSAoKVxuXG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfZGVidWdfaW5mb19zdGF0dXMgY29uc3RcbmZ1bmN0aW9uIGNhbWxfbWxfZGVidWdfaW5mb19zdGF0dXMgKCkgeyByZXR1cm4gMDsgfVxuLy9Qcm92aWRlczogY2FtbF9iYWNrdHJhY2Vfc3RhdHVzXG4vL1JlcXVpcmVzOiBjYW1sX3JlY29yZF9iYWNrdHJhY2VfZmxhZ1xuZnVuY3Rpb24gY2FtbF9iYWNrdHJhY2Vfc3RhdHVzIChfdW5pdCkgeyByZXR1cm4gY2FtbF9yZWNvcmRfYmFja3RyYWNlX2ZsYWcgPyAxIDogMDsgfVxuLy9Qcm92aWRlczogY2FtbF9nZXRfZXhjZXB0aW9uX2JhY2t0cmFjZSBjb25zdFxuZnVuY3Rpb24gY2FtbF9nZXRfZXhjZXB0aW9uX2JhY2t0cmFjZSAoKSB7IHJldHVybiAwOyB9XG4vL1Byb3ZpZGVzOiBjYW1sX2dldF9leGNlcHRpb25fcmF3X2JhY2t0cmFjZSBjb25zdFxuZnVuY3Rpb24gY2FtbF9nZXRfZXhjZXB0aW9uX3Jhd19iYWNrdHJhY2UgKCkgeyByZXR1cm4gWzBdOyB9XG4vL1Byb3ZpZGVzOiBjYW1sX3JlY29yZF9iYWNrdHJhY2Vcbi8vUmVxdWlyZXM6IGNhbWxfcmVjb3JkX2JhY2t0cmFjZV9mbGFnXG5mdW5jdGlvbiBjYW1sX3JlY29yZF9iYWNrdHJhY2UgKGIpIHsgY2FtbF9yZWNvcmRfYmFja3RyYWNlX2ZsYWcgPSBiOyByZXR1cm4gMDsgfVxuLy9Qcm92aWRlczogY2FtbF9jb252ZXJ0X3Jhd19iYWNrdHJhY2UgY29uc3RcbmZ1bmN0aW9uIGNhbWxfY29udmVydF9yYXdfYmFja3RyYWNlICgpIHsgcmV0dXJuIFswXTsgfVxuLy9Qcm92aWRlczogY2FtbF9yYXdfYmFja3RyYWNlX2xlbmd0aFxuZnVuY3Rpb24gY2FtbF9yYXdfYmFja3RyYWNlX2xlbmd0aCgpIHsgcmV0dXJuIDA7IH1cbi8vUHJvdmlkZXM6IGNhbWxfcmF3X2JhY2t0cmFjZV9uZXh0X3Nsb3RcbmZ1bmN0aW9uIGNhbWxfcmF3X2JhY2t0cmFjZV9uZXh0X3Nsb3QoKSB7IHJldHVybiAwIH1cbi8vUHJvdmlkZXM6IGNhbWxfcmF3X2JhY2t0cmFjZV9zbG90XG4vL1JlcXVpcmVzOiBjYW1sX2ludmFsaWRfYXJndW1lbnRcbmZ1bmN0aW9uIGNhbWxfcmF3X2JhY2t0cmFjZV9zbG90ICgpIHtcbiAgY2FtbF9pbnZhbGlkX2FyZ3VtZW50KFwiUHJpbnRleGMuZ2V0X3Jhd19iYWNrdHJhY2Vfc2xvdDogaW5kZXggb3V0IG9mIGJvdW5kc1wiKTtcbn1cbi8vUHJvdmlkZXM6IGNhbWxfcmVzdG9yZV9yYXdfYmFja3RyYWNlXG5mdW5jdGlvbiBjYW1sX3Jlc3RvcmVfcmF3X2JhY2t0cmFjZShleG4sIGJ0KSB7IHJldHVybiAwIH1cbi8vUHJvdmlkZXM6IGNhbWxfZ2V0X2N1cnJlbnRfY2FsbHN0YWNrIGNvbnN0XG5mdW5jdGlvbiBjYW1sX2dldF9jdXJyZW50X2NhbGxzdGFjayAoKSB7IHJldHVybiBbMF07IH1cblxuLy9Qcm92aWRlczogY2FtbF9jb252ZXJ0X3Jhd19iYWNrdHJhY2Vfc2xvdFxuLy9SZXF1aXJlczogY2FtbF9mYWlsd2l0aFxuZnVuY3Rpb24gY2FtbF9jb252ZXJ0X3Jhd19iYWNrdHJhY2Vfc2xvdCgpe1xuICBjYW1sX2ZhaWx3aXRoKFwiY2FtbF9jb252ZXJ0X3Jhd19iYWNrdHJhY2Vfc2xvdFwiKTtcbn1cbiIsIi8vIEpzX29mX29jYW1sIGxpYnJhcnlcbi8vIGh0dHA6Ly93d3cub2NzaWdlbi5vcmcvanNfb2Zfb2NhbWwvXG4vLyBDb3B5cmlnaHQgKEMpIDIwMTAgSsOpcsO0bWUgVm91aWxsb25cbi8vIExhYm9yYXRvaXJlIFBQUyAtIENOUlMgVW5pdmVyc2l0w6kgUGFyaXMgRGlkZXJvdFxuLy9cbi8vIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4vLyBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbi8vIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHdpdGggbGlua2luZyBleGNlcHRpb247XG4vLyBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vL1xuLy8gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuLy8gR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vL1xuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4vLyBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcsIFVTQS5cblxuLy8vLy8vLy8vLy8vLyBKc2xpYlxuXG4vL1Byb3ZpZGVzOiBjYW1sX2pzX3B1cmVfZXhwciBjb25zdFxuLy9SZXF1aXJlczogY2FtbF9jYWxsYmFja1xuZnVuY3Rpb24gY2FtbF9qc19wdXJlX2V4cHIgKGYpIHsgcmV0dXJuIGNhbWxfY2FsbGJhY2soZiwgWzBdKTsgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2pzX3NldCAobXV0YWJsZSwgY29uc3QsIG11dGFibGUpXG5mdW5jdGlvbiBjYW1sX2pzX3NldChvLGYsdikgeyBvW2ZdPXY7cmV0dXJuIDB9XG4vL1Byb3ZpZGVzOiBjYW1sX2pzX2dldCAobXV0YWJsZSwgY29uc3QpXG5mdW5jdGlvbiBjYW1sX2pzX2dldChvLGYpIHsgcmV0dXJuIG9bZl07IH1cbi8vUHJvdmlkZXM6IGNhbWxfanNfZGVsZXRlIChtdXRhYmxlLCBjb25zdClcbmZ1bmN0aW9uIGNhbWxfanNfZGVsZXRlKG8sZikgeyBkZWxldGUgb1tmXTsgcmV0dXJuIDB9XG5cbi8vUHJvdmlkZXM6IGNhbWxfanNfaW5zdGFuY2VvZiAoY29uc3QsIGNvbnN0KVxuZnVuY3Rpb24gY2FtbF9qc19pbnN0YW5jZW9mKG8sYykgeyByZXR1cm4gKG8gaW5zdGFuY2VvZiBjKSA/IDEgOiAwOyB9XG5cbi8vUHJvdmlkZXM6IGNhbWxfanNfdHlwZW9mIChjb25zdClcbmZ1bmN0aW9uIGNhbWxfanNfdHlwZW9mKG8pIHsgcmV0dXJuIHR5cGVvZiBvOyB9XG5cbi8vUHJvdmlkZXM6Y2FtbF90cmFtcG9saW5lXG5mdW5jdGlvbiBjYW1sX3RyYW1wb2xpbmUocmVzKSB7XG4gIHZhciBjID0gMTtcbiAgd2hpbGUocmVzICYmIHJlcy5qb29fdHJhbXApe1xuICAgIHJlcyA9IHJlcy5qb29fdHJhbXAuYXBwbHkobnVsbCwgcmVzLmpvb19hcmdzKTtcbiAgICBjKys7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cblxuLy9Qcm92aWRlczpjYW1sX3RyYW1wb2xpbmVfcmV0dXJuXG5mdW5jdGlvbiBjYW1sX3RyYW1wb2xpbmVfcmV0dXJuKGYsYXJncykge1xuICByZXR1cm4ge2pvb190cmFtcDpmLGpvb19hcmdzOmFyZ3N9O1xufVxuXG4vL1Byb3ZpZGVzOmNhbWxfc3RhY2tfZGVwdGhcbi8vSWY6IGVmZmVjdHNcbnZhciBjYW1sX3N0YWNrX2RlcHRoID0gMDtcblxuLy9Qcm92aWRlczpjYW1sX3N0YWNrX2NoZWNrX2RlcHRoXG4vL0lmOiBlZmZlY3RzXG4vL1JlcXVpcmVzOmNhbWxfc3RhY2tfZGVwdGhcbmZ1bmN0aW9uIGNhbWxfc3RhY2tfY2hlY2tfZGVwdGgoKSB7XG4gICAgcmV0dXJuIC0tY2FtbF9zdGFja19kZXB0aCA+IDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfY2FsbGJhY2tcbi8vSWY6ICFlZmZlY3RzXG4vL1JlcXVpcmVzOmNhbWxfY2FsbF9nZW5cbnZhciBjYW1sX2NhbGxiYWNrID0gY2FtbF9jYWxsX2dlbjtcblxuLy9Qcm92aWRlczogY2FtbF9jYWxsYmFja1xuLy9JZjogZWZmZWN0c1xuLy9SZXF1aXJlczpjYW1sX3N0YWNrX2RlcHRoLCBjYW1sX2NhbGxfZ2VuLCBjYW1sX2V4bl9zdGFjaywgY2FtbF9maWJlcl9zdGFjaywgY2FtbF93cmFwX2V4Y2VwdGlvbiwgY2FtbF9yZXN1bWVfc3RhY2ssIGNhbWxfZnJlc2hfb29faWQsIGNhbWxfbmFtZWRfdmFsdWUsIGNhbWxfcmFpc2Vfd2l0aF9hcmcsIGNhbWxfc3RyaW5nX29mX2pzYnl0ZXNcbi8vUmVxdWlyZXM6IGNhbWxfcmFpc2VfY29uc3RhbnRcbmZ1bmN0aW9uIGNhbWxfY2FsbGJhY2soZixhcmdzKSB7XG4gIGZ1bmN0aW9uIHVuY2F1Z2h0X2VmZmVjdF9oYW5kbGVyKGVmZixrLG1zKSB7XG4gICAgLy8gUmVzdW1lcyB0aGUgY29udGludWF0aW9uIGsgYnkgcmFpc2luZyBleGNlcHRpb24gVW5oYW5kbGVkLlxuICAgIGNhbWxfcmVzdW1lX3N0YWNrKGtbMV0sbXMpO1xuICAgIHZhciBleG4gPSBjYW1sX25hbWVkX3ZhbHVlKFwiRWZmZWN0LlVuaGFuZGxlZFwiKTtcbiAgICBpZihleG4pIGNhbWxfcmFpc2Vfd2l0aF9hcmcoZXhuLCBlZmYpO1xuICAgIGVsc2Uge1xuICAgICAgZXhuID0gWzI0OCxjYW1sX3N0cmluZ19vZl9qc2J5dGVzKFwiRWZmZWN0LlVuaGFuZGxlZFwiKSwgY2FtbF9mcmVzaF9vb19pZCgwKV07XG4gICAgICBjYW1sX3JhaXNlX2NvbnN0YW50KGV4bik7XG4gICAgfVxuICB9XG4gIHZhciBzYXZlZF9zdGFja19kZXB0aCA9IGNhbWxfc3RhY2tfZGVwdGg7XG4gIHZhciBzYXZlZF9leG5fc3RhY2sgPSBjYW1sX2V4bl9zdGFjaztcbiAgdmFyIHNhdmVkX2ZpYmVyX3N0YWNrID0gY2FtbF9maWJlcl9zdGFjaztcbiAgdHJ5IHtcbiAgICBjYW1sX2V4bl9zdGFjayA9IDA7XG4gICAgY2FtbF9maWJlcl9zdGFjayA9XG4gICAgICB7aDpbMCwgMCwgMCwgdW5jYXVnaHRfZWZmZWN0X2hhbmRsZXJdLCByOntrOjAsIHg6MCwgZTowfX07XG4gICAgdmFyIHJlcyA9IHtqb29fdHJhbXA6IGYsXG4gICAgICAgICAgICAgICBqb29fYXJnczogYXJncy5jb25jYXQoZnVuY3Rpb24gKHgpe3JldHVybiB4O30pfTtcbiAgICBkbyB7XG4gICAgICBjYW1sX3N0YWNrX2RlcHRoID0gNDA7XG4gICAgICB0cnkge1xuICAgICAgICByZXMgPSBjYW1sX2NhbGxfZ2VuKHJlcy5qb29fdHJhbXAsIHJlcy5qb29fYXJncyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8qIEhhbmRsZSBleGNlcHRpb24gY29taW5nIGZyb20gSmF2YVNjcmlwdCBvciBmcm9tIHRoZSBydW50aW1lLiAqL1xuICAgICAgICBpZiAoIWNhbWxfZXhuX3N0YWNrKSB0aHJvdyBlO1xuICAgICAgICB2YXIgaGFuZGxlciA9IGNhbWxfZXhuX3N0YWNrWzFdO1xuICAgICAgICBjYW1sX2V4bl9zdGFjayA9IGNhbWxfZXhuX3N0YWNrWzJdO1xuICAgICAgICByZXMgPSB7am9vX3RyYW1wOiBoYW5kbGVyLFxuICAgICAgICAgICAgICAgam9vX2FyZ3M6IFtjYW1sX3dyYXBfZXhjZXB0aW9uKGUpXX07XG4gICAgICB9XG4gICAgfSB3aGlsZShyZXMgJiYgcmVzLmpvb19hcmdzKVxuICB9IGZpbmFsbHkge1xuICAgIGNhbWxfc3RhY2tfZGVwdGggPSBzYXZlZF9zdGFja19kZXB0aDtcbiAgICBjYW1sX2V4bl9zdGFjayA9IHNhdmVkX2V4bl9zdGFjaztcbiAgICBjYW1sX2ZpYmVyX3N0YWNrID0gc2F2ZWRfZmliZXJfc3RhY2s7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cblxuLy9Qcm92aWRlczogY2FtbF9pc19qc1xuZnVuY3Rpb24gY2FtbF9pc19qcygpIHtcbiAgcmV0dXJuIDE7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfanNvb19mbGFnc191c2VfanNfc3RyaW5nXG5mdW5jdGlvbiBjYW1sX2pzb29fZmxhZ3NfdXNlX2pzX3N0cmluZyh1bml0KXtcbiAgcmV0dXJuIEZMQUcoXCJ1c2UtanMtc3RyaW5nXCIpXG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfanNvb19mbGFnc19lZmZlY3RzXG5mdW5jdGlvbiBjYW1sX2pzb29fZmxhZ3NfZWZmZWN0cyh1bml0KXtcbiAgcmV0dXJuIEZMQUcoXCJlZmZlY3RzXCIpXG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfd3JhcF9leGNlcHRpb24gY29uc3QgKG11dGFibGUpXG4vL1JlcXVpcmVzOiBjYW1sX2dsb2JhbF9kYXRhLGNhbWxfc3RyaW5nX29mX2pzc3RyaW5nLGNhbWxfbmFtZWRfdmFsdWVcbmZ1bmN0aW9uIGNhbWxfd3JhcF9leGNlcHRpb24oZSkge1xuICBpZiAoRkxBRyhcImV4Y3dyYXBcIikpIHtcbiAgICBpZihlIGluc3RhbmNlb2YgQXJyYXkpIHJldHVybiBlO1xuICAgIHZhciBleG47XG4gICAgLy9TdGFja19vdmVyZmxvdzogY2hyb21lLCBzYWZhcmlcbiAgICBpZihnbG9iYWxUaGlzLlJhbmdlRXJyb3JcbiAgICAgICAmJiBlIGluc3RhbmNlb2YgZ2xvYmFsVGhpcy5SYW5nZUVycm9yXG4gICAgICAgJiYgZS5tZXNzYWdlXG4gICAgICAgJiYgZS5tZXNzYWdlLm1hdGNoKC9tYXhpbXVtIGNhbGwgc3RhY2svaSkpXG4gICAgICBleG4gPSBjYW1sX2dsb2JhbF9kYXRhLlN0YWNrX292ZXJmbG93O1xuICAgIC8vU3RhY2tfb3ZlcmZsb3c6IGZpcmVmb3hcbiAgICBlbHNlIGlmKGdsb2JhbFRoaXMuSW50ZXJuYWxFcnJvclxuICAgICAgICYmIGUgaW5zdGFuY2VvZiBnbG9iYWxUaGlzLkludGVybmFsRXJyb3JcbiAgICAgICAmJiBlLm1lc3NhZ2VcbiAgICAgICAmJiBlLm1lc3NhZ2UubWF0Y2goL3RvbyBtdWNoIHJlY3Vyc2lvbi9pKSlcbiAgICAgIGV4biA9IGNhbWxfZ2xvYmFsX2RhdGEuU3RhY2tfb3ZlcmZsb3c7XG4gICAgLy9XcmFwIEVycm9yIGluIEpzLkVycm9yIGV4Y2VwdGlvblxuICAgIGVsc2UgaWYoZSBpbnN0YW5jZW9mIGdsb2JhbFRoaXMuRXJyb3IgJiYgY2FtbF9uYW1lZF92YWx1ZShcImpzRXJyb3JcIikpXG4gICAgICBleG4gPSBbMCxjYW1sX25hbWVkX3ZhbHVlKFwianNFcnJvclwiKSxlXTtcbiAgICBlbHNlXG4gICAgICAvL2ZhbGxiYWNrOiB3cmFwcGVkIGluIEZhaWx1cmVcbiAgICAgIGV4biA9IFswLGNhbWxfZ2xvYmFsX2RhdGEuRmFpbHVyZSxjYW1sX3N0cmluZ19vZl9qc3N0cmluZyAoU3RyaW5nKGUpKV07XG4gICAgLy8gV2UgYWxyZWFkeSBoYXZlIGFuIGVycm9yIGF0IGhhbmQsIGxldCdzIHVzZSBpdC5cbiAgICBpZiAoZSBpbnN0YW5jZW9mIGdsb2JhbFRoaXMuRXJyb3IpXG4gICAgICBleG4uanNfZXJyb3IgPSBlO1xuICAgIHJldHVybiBleG47XG4gIH0gZWxzZVxuICAgIHJldHVybiBlO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21heWJlX2F0dGFjaF9iYWNrdHJhY2Vcbi8vUmVxdWlyZXM6IGNhbWxfZXhuX3dpdGhfanNfYmFja3RyYWNlXG4vL1JlcXVpcmVzOiBjYW1sX3JlY29yZF9iYWNrdHJhY2VfZmxhZ1xuZnVuY3Rpb24gY2FtbF9tYXliZV9hdHRhY2hfYmFja3RyYWNlKGV4biwgZm9yY2UpIHtcbiAgaWYoY2FtbF9yZWNvcmRfYmFja3RyYWNlX2ZsYWcpXG4gICAgcmV0dXJuIGNhbWxfZXhuX3dpdGhfanNfYmFja3RyYWNlKGV4biwgZm9yY2UpO1xuICBlbHNlIHJldHVybiBleG5cbn1cblxuLy8gRXhwZXJpbWVudGFsXG4vL1Byb3ZpZGVzOiBjYW1sX2V4bl93aXRoX2pzX2JhY2t0cmFjZVxuLy9SZXF1aXJlczogY2FtbF9nbG9iYWxfZGF0YVxuZnVuY3Rpb24gY2FtbF9leG5fd2l0aF9qc19iYWNrdHJhY2UoZXhuLCBmb3JjZSkge1xuICAvL25ldmVyIHJlcmFpc2UgZm9yIGNvbnN0YW50IGV4blxuICBpZighZXhuLmpzX2Vycm9yIHx8IGZvcmNlIHx8IGV4blswXSA9PSAyNDgpIGV4bi5qc19lcnJvciA9IG5ldyBnbG9iYWxUaGlzLkVycm9yKFwiSnMgZXhjZXB0aW9uIGNvbnRhaW5pbmcgYmFja3RyYWNlXCIpO1xuICByZXR1cm4gZXhuO1xufVxuXG5cbi8vUHJvdmlkZXM6IGNhbWxfanNfZXJyb3Jfb3B0aW9uX29mX2V4Y2VwdGlvblxuZnVuY3Rpb24gY2FtbF9qc19lcnJvcl9vcHRpb25fb2ZfZXhjZXB0aW9uKGV4bikge1xuICBpZihleG4uanNfZXJyb3IpIHsgcmV0dXJuIFswLCBleG4uanNfZXJyb3JdOyB9XG4gIHJldHVybiAwO1xufVxuXG5cblxuLy9Qcm92aWRlczogY2FtbF9qc19mcm9tX2Jvb2wgY29uc3QgKGNvbnN0KVxuZnVuY3Rpb24gY2FtbF9qc19mcm9tX2Jvb2woeCkgeyByZXR1cm4gISF4OyB9XG4vL1Byb3ZpZGVzOiBjYW1sX2pzX3RvX2Jvb2wgY29uc3QgKGNvbnN0KVxuZnVuY3Rpb24gY2FtbF9qc190b19ib29sKHgpIHsgcmV0dXJuICt4OyB9XG4vL1Byb3ZpZGVzOiBjYW1sX2pzX2Zyb21fZmxvYXQgY29uc3QgKGNvbnN0KVxuLy9BbGlhczogY2FtbF9qc19mcm9tX2ludDMyXG4vL0FsaWFzOiBjYW1sX2pzX2Zyb21fbmF0aXZlaW50XG5mdW5jdGlvbiBjYW1sX2pzX2Zyb21fZmxvYXQoeCkgeyByZXR1cm4geDsgfVxuLy9Qcm92aWRlczogY2FtbF9qc190b19mbG9hdCBjb25zdCAoY29uc3QpXG5mdW5jdGlvbiBjYW1sX2pzX3RvX2Zsb2F0KHgpIHsgcmV0dXJuIHg7IH1cbi8vUHJvdmlkZXM6IGNhbWxfanNfdG9faW50MzIgY29uc3QgKGNvbnN0KVxuLy9BbGlhczogY2FtbF9qc190b19uYXRpdmVpbnRcbmZ1bmN0aW9uIGNhbWxfanNfdG9faW50MzIoeCkgeyByZXR1cm4geHwwOyB9XG5cbi8vUHJvdmlkZXM6IGNhbWxfanNfZnJvbV9hcnJheSBtdXRhYmxlIChzaGFsbG93KVxuZnVuY3Rpb24gY2FtbF9qc19mcm9tX2FycmF5KGEpIHtcbiAgcmV0dXJuIGEuc2xpY2UoMSk7XG59XG4vL1Byb3ZpZGVzOiBjYW1sX2pzX3RvX2FycmF5IG11dGFibGUgKHNoYWxsb3cpXG5mdW5jdGlvbiBjYW1sX2pzX3RvX2FycmF5KGEpIHtcbiAgdmFyIGxlbiA9IGEubGVuZ3RoO1xuICB2YXIgYiA9IG5ldyBBcnJheShsZW4rMSk7XG4gIGJbMF0gPSAwO1xuICBmb3IodmFyIGk9MDtpPGxlbjtpKyspIGJbaSsxXSA9IGFbaV07XG4gIHJldHVybiBiO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2xpc3Rfb2ZfanNfYXJyYXkgY29uc3QgKG11dGFibGUpXG5mdW5jdGlvbiBjYW1sX2xpc3Rfb2ZfanNfYXJyYXkoYSl7XG4gIHZhciBsID0gMDtcbiAgZm9yKHZhciBpPWEubGVuZ3RoIC0gMTsgaT49MDsgaS0tKXtcbiAgICB2YXIgZSA9IGFbaV07XG4gICAgbCA9IFswLGUsbF07XG4gIH1cbiAgcmV0dXJuIGxcbn1cblxuLy9Qcm92aWRlczogY2FtbF9saXN0X3RvX2pzX2FycmF5IGNvbnN0IChtdXRhYmxlKVxuZnVuY3Rpb24gY2FtbF9saXN0X3RvX2pzX2FycmF5KGwpe1xuICB2YXIgYSA9IFtdO1xuICBmb3IoOyBsICE9PSAwOyBsID0gbFsyXSkge1xuICAgIGEucHVzaChsWzFdKTtcbiAgfVxuICByZXR1cm4gYTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9qc192YXIgbXV0YWJsZVxuLy9SZXF1aXJlczogY2FtbF9qc3N0cmluZ19vZl9zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfanNfdmFyKHgpIHtcbiAgdmFyIHggPSBjYW1sX2pzc3RyaW5nX29mX3N0cmluZyh4KTtcbiAgLy9DaGVja3MgdGhhdCB4IGhhcyB0aGUgZm9ybSBpZGVudFsuaWRlbnRdKlxuICBpZigheC5tYXRjaCgvXlthLXpBLVpfJF1bYS16QS1aXyQwLTldKihcXC5bYS16QS1aXyRdW2EtekEtWl8kMC05XSopKiQvKSl7XG4gICAgY29uc29sZS5lcnJvcihcImNhbWxfanNfdmFyOiBcXFwiXCIgKyB4ICsgXCJcXFwiIGlzIG5vdCBhIHZhbGlkIEphdmFTY3JpcHQgdmFyaWFibGUuIGNvbnRpbnVpbmcgLi5cIik7XG4gICAgLy9jb25zb2xlLmVycm9yKFwiSnMuVW5zYWZlLmV2YWxfc3RyaW5nXCIpXG4gIH1cbiAgcmV0dXJuIGV2YWwoeCk7XG59XG4vL1Byb3ZpZGVzOiBjYW1sX2pzX2NhbGwgKGNvbnN0LCBtdXRhYmxlLCBzaGFsbG93KVxuLy9SZXF1aXJlczogY2FtbF9qc19mcm9tX2FycmF5XG5mdW5jdGlvbiBjYW1sX2pzX2NhbGwoZiwgbywgYXJncykgeyByZXR1cm4gZi5hcHBseShvLCBjYW1sX2pzX2Zyb21fYXJyYXkoYXJncykpOyB9XG4vL1Byb3ZpZGVzOiBjYW1sX2pzX2Z1bl9jYWxsIChjb25zdCwgc2hhbGxvdylcbi8vUmVxdWlyZXM6IGNhbWxfanNfZnJvbV9hcnJheVxuZnVuY3Rpb24gY2FtbF9qc19mdW5fY2FsbChmLCBhKSB7XG4gIHN3aXRjaCAoYS5sZW5ndGgpIHtcbiAgY2FzZSAxOiByZXR1cm4gZigpO1xuICBjYXNlIDI6IHJldHVybiBmIChhWzFdKTtcbiAgY2FzZSAzOiByZXR1cm4gZiAoYVsxXSxhWzJdKTtcbiAgY2FzZSA0OiByZXR1cm4gZiAoYVsxXSxhWzJdLGFbM10pO1xuICBjYXNlIDU6IHJldHVybiBmIChhWzFdLGFbMl0sYVszXSxhWzRdKTtcbiAgY2FzZSA2OiByZXR1cm4gZiAoYVsxXSxhWzJdLGFbM10sYVs0XSxhWzVdKTtcbiAgY2FzZSA3OiByZXR1cm4gZiAoYVsxXSxhWzJdLGFbM10sYVs0XSxhWzVdLGFbNl0pO1xuICBjYXNlIDg6IHJldHVybiBmIChhWzFdLGFbMl0sYVszXSxhWzRdLGFbNV0sYVs2XSxhWzddKTtcbiAgfVxuICByZXR1cm4gZi5hcHBseShudWxsLCBjYW1sX2pzX2Zyb21fYXJyYXkoYSkpO1xufVxuLy9Qcm92aWRlczogY2FtbF9qc19tZXRoX2NhbGwgKG11dGFibGUsIGNvbnN0LCBzaGFsbG93KVxuLy9SZXF1aXJlczogY2FtbF9qc3N0cmluZ19vZl9zdHJpbmdcbi8vUmVxdWlyZXM6IGNhbWxfanNfZnJvbV9hcnJheVxuZnVuY3Rpb24gY2FtbF9qc19tZXRoX2NhbGwobywgZiwgYXJncykge1xuICByZXR1cm4gb1tjYW1sX2pzc3RyaW5nX29mX3N0cmluZyhmKV0uYXBwbHkobywgY2FtbF9qc19mcm9tX2FycmF5KGFyZ3MpKTtcbn1cbi8vUHJvdmlkZXM6IGNhbWxfanNfbmV3IChjb25zdCwgc2hhbGxvdylcbi8vUmVxdWlyZXM6IGNhbWxfanNfZnJvbV9hcnJheVxuZnVuY3Rpb24gY2FtbF9qc19uZXcoYywgYSkge1xuICBzd2l0Y2ggKGEubGVuZ3RoKSB7XG4gIGNhc2UgMTogcmV0dXJuIG5ldyBjO1xuICBjYXNlIDI6IHJldHVybiBuZXcgYyAoYVsxXSk7XG4gIGNhc2UgMzogcmV0dXJuIG5ldyBjIChhWzFdLGFbMl0pO1xuICBjYXNlIDQ6IHJldHVybiBuZXcgYyAoYVsxXSxhWzJdLGFbM10pO1xuICBjYXNlIDU6IHJldHVybiBuZXcgYyAoYVsxXSxhWzJdLGFbM10sYVs0XSk7XG4gIGNhc2UgNjogcmV0dXJuIG5ldyBjIChhWzFdLGFbMl0sYVszXSxhWzRdLGFbNV0pO1xuICBjYXNlIDc6IHJldHVybiBuZXcgYyAoYVsxXSxhWzJdLGFbM10sYVs0XSxhWzVdLGFbNl0pO1xuICBjYXNlIDg6IHJldHVybiBuZXcgYyAoYVsxXSxhWzJdLGFbM10sYVs0XSxhWzVdLGFbNl0sYVs3XSk7XG4gIH1cbiAgZnVuY3Rpb24gRigpIHsgcmV0dXJuIGMuYXBwbHkodGhpcywgY2FtbF9qc19mcm9tX2FycmF5KGEpKTsgfVxuICBGLnByb3RvdHlwZSA9IGMucHJvdG90eXBlO1xuICByZXR1cm4gbmV3IEY7XG59XG4vL1Byb3ZpZGVzOiBjYW1sX29qc19uZXdfYXJyIChjb25zdCwgc2hhbGxvdylcbi8vUmVxdWlyZXM6IGNhbWxfanNfZnJvbV9hcnJheVxuZnVuY3Rpb24gY2FtbF9vanNfbmV3X2FycihjLCBhKSB7XG4gIHN3aXRjaCAoYS5sZW5ndGgpIHtcbiAgY2FzZSAwOiByZXR1cm4gbmV3IGM7XG4gIGNhc2UgMTogcmV0dXJuIG5ldyBjIChhWzBdKTtcbiAgY2FzZSAyOiByZXR1cm4gbmV3IGMgKGFbMF0sYVsxXSk7XG4gIGNhc2UgMzogcmV0dXJuIG5ldyBjIChhWzBdLGFbMV0sYVsyXSk7XG4gIGNhc2UgNDogcmV0dXJuIG5ldyBjIChhWzBdLGFbMV0sYVsyXSxhWzNdKTtcbiAgY2FzZSA1OiByZXR1cm4gbmV3IGMgKGFbMF0sYVsxXSxhWzJdLGFbM10sYVs0XSk7XG4gIGNhc2UgNjogcmV0dXJuIG5ldyBjIChhWzBdLGFbMV0sYVsyXSxhWzNdLGFbNF0sYVs1XSk7XG4gIGNhc2UgNzogcmV0dXJuIG5ldyBjIChhWzBdLGFbMV0sYVsyXSxhWzNdLGFbNF0sYVs1XSxhWzZdKTtcbiAgfVxuICBmdW5jdGlvbiBGKCkgeyByZXR1cm4gYy5hcHBseSh0aGlzLCBhKTsgfVxuICBGLnByb3RvdHlwZSA9IGMucHJvdG90eXBlO1xuICByZXR1cm4gbmV3IEY7XG59XG4vL1Byb3ZpZGVzOiBjYW1sX2pzX3dyYXBfY2FsbGJhY2sgY29uc3QgKGNvbnN0KVxuLy9SZXF1aXJlczogY2FtbF9jYWxsYmFja1xuZnVuY3Rpb24gY2FtbF9qc193cmFwX2NhbGxiYWNrKGYpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICBpZihsZW4gPiAwKXtcbiAgICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGxlbik7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSBhcmdzW2ldID0gYXJndW1lbnRzW2ldO1xuICAgIH0gZWxzZSB7XG4gICAgICBhcmdzID0gW3VuZGVmaW5lZF07XG4gICAgfVxuICAgIHZhciByZXMgPSBjYW1sX2NhbGxiYWNrKGYsIGFyZ3MpO1xuICAgIHJldHVybiAocmVzIGluc3RhbmNlb2YgRnVuY3Rpb24pP2NhbWxfanNfd3JhcF9jYWxsYmFjayhyZXMpOnJlcztcbiAgfVxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2pzX3dyYXBfY2FsbGJhY2tfYXJndW1lbnRzXG4vL1JlcXVpcmVzOiBjYW1sX2NhbGxiYWNrXG5mdW5jdGlvbiBjYW1sX2pzX3dyYXBfY2FsbGJhY2tfYXJndW1lbnRzKGYpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykgYXJnc1tpXSA9IGFyZ3VtZW50c1tpXTtcbiAgICByZXR1cm4gY2FtbF9jYWxsYmFjayhmLCBbYXJnc10pO1xuICB9XG59XG4vL1Byb3ZpZGVzOiBjYW1sX2pzX3dyYXBfY2FsbGJhY2tfc3RyaWN0IGNvbnN0XG4vL1JlcXVpcmVzOiBjYW1sX2NhbGxiYWNrXG5mdW5jdGlvbiBjYW1sX2pzX3dyYXBfY2FsbGJhY2tfc3RyaWN0KGFyaXR5LCBmKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyaXR5KTtcbiAgICB2YXIgbGVuID0gTWF0aC5taW4oYXJndW1lbnRzLmxlbmd0aCwgYXJpdHkpXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykgYXJnc1tpXSA9IGFyZ3VtZW50c1tpXTtcbiAgICByZXR1cm4gY2FtbF9jYWxsYmFjayhmLCBhcmdzKTtcbiAgfTtcbn1cbi8vUHJvdmlkZXM6IGNhbWxfanNfd3JhcF9jYWxsYmFja191bnNhZmUgY29uc3QgKGNvbnN0KVxuLy9SZXF1aXJlczogY2FtbF9jYWxsYmFjaywgY2FtbF9qc19mdW5jdGlvbl9hcml0eVxuZnVuY3Rpb24gY2FtbF9qc193cmFwX2NhbGxiYWNrX3Vuc2FmZShmKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGxlbiA9IGNhbWxfanNfZnVuY3Rpb25fYXJpdHkoZik7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkobGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSBhcmdzW2ldID0gYXJndW1lbnRzW2ldO1xuICAgIHJldHVybiBjYW1sX2NhbGxiYWNrKGYsIGFyZ3MpOyB9XG59XG4vL1Byb3ZpZGVzOiBjYW1sX2pzX3dyYXBfbWV0aF9jYWxsYmFjayBjb25zdCAoY29uc3QpXG4vL1JlcXVpcmVzOiBjYW1sX2NhbGxiYWNrLCBjYW1sX2pzX3dyYXBfY2FsbGJhY2tcbmZ1bmN0aW9uIGNhbWxfanNfd3JhcF9tZXRoX2NhbGxiYWNrKGYpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICB2YXIgYXJncyA9IG5ldyBBcnJheShsZW4gKyAxKTtcbiAgICBhcmdzWzBdID0gdGhpcztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSBhcmdzW2krMV0gPSBhcmd1bWVudHNbaV07XG4gICAgdmFyIHJlcyA9IGNhbWxfY2FsbGJhY2soZixhcmdzKTtcbiAgICByZXR1cm4gKHJlcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKT9jYW1sX2pzX3dyYXBfY2FsbGJhY2socmVzKTpyZXM7XG4gIH1cbn1cbi8vUHJvdmlkZXM6IGNhbWxfanNfd3JhcF9tZXRoX2NhbGxiYWNrX2FyZ3VtZW50cyBjb25zdCAoY29uc3QpXG4vL1JlcXVpcmVzOiBjYW1sX2NhbGxiYWNrXG5mdW5jdGlvbiBjYW1sX2pzX3dyYXBfbWV0aF9jYWxsYmFja19hcmd1bWVudHMoZikge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykgYXJnc1tpXSA9IGFyZ3VtZW50c1tpXTtcbiAgICByZXR1cm4gY2FtbF9jYWxsYmFjayhmLFt0aGlzLGFyZ3NdKTtcbiAgfVxufVxuLy9Qcm92aWRlczogY2FtbF9qc193cmFwX21ldGhfY2FsbGJhY2tfc3RyaWN0IGNvbnN0XG4vL1JlcXVpcmVzOiBjYW1sX2NhbGxiYWNrXG5mdW5jdGlvbiBjYW1sX2pzX3dyYXBfbWV0aF9jYWxsYmFja19zdHJpY3QoYXJpdHksIGYpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgYXJncyA9IG5ldyBBcnJheShhcml0eSArIDEpO1xuICAgIHZhciBsZW4gPSBNYXRoLm1pbihhcmd1bWVudHMubGVuZ3RoLCBhcml0eSlcbiAgICBhcmdzWzBdID0gdGhpcztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSBhcmdzW2krMV0gPSBhcmd1bWVudHNbaV07XG4gICAgcmV0dXJuIGNhbWxfY2FsbGJhY2soZiwgYXJncyk7XG4gIH07XG59XG4vL1Byb3ZpZGVzOiBjYW1sX2pzX3dyYXBfbWV0aF9jYWxsYmFja191bnNhZmUgY29uc3QgKGNvbnN0KVxuLy9SZXF1aXJlczogY2FtbF9jYWxsYmFjaywgY2FtbF9qc19mdW5jdGlvbl9hcml0eVxuZnVuY3Rpb24gY2FtbF9qc193cmFwX21ldGhfY2FsbGJhY2tfdW5zYWZlKGYpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbGVuID0gY2FtbF9qc19mdW5jdGlvbl9hcml0eShmKSAtIDE7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkobGVuICsgMSk7XG4gICAgYXJnc1swXSA9IHRoaXM7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykgYXJnc1tpKzFdID0gYXJndW1lbnRzW2ldO1xuICAgIHJldHVybiBjYW1sX2NhbGxiYWNrKGYsIGFyZ3MpOyB9XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfanNfZnVuY3Rpb25fYXJpdHlcbi8vSWY6ICFlZmZlY3RzXG5mdW5jdGlvbiBjYW1sX2pzX2Z1bmN0aW9uX2FyaXR5KGYpIHtcbiAgcmV0dXJuIChmLmwgPj0gMCk/Zi5sOihmLmwgPSBmLmxlbmd0aClcbn1cblxuLy9Qcm92aWRlczogY2FtbF9qc19mdW5jdGlvbl9hcml0eVxuLy9JZjogZWZmZWN0c1xuZnVuY3Rpb24gY2FtbF9qc19mdW5jdGlvbl9hcml0eShmKSB7XG4gIC8vIEZ1bmN0aW9ucyBoYXZlIGFuIGFkZGl0aW9uYWwgY29udGludWF0aW9uIHBhcmFtZXRlci4gVGhpcyBzaG91bGRcbiAgLy8gbm90IGJlIHZpc2libGUgd2hlbiBjYWxsaW5nIHRoZW0gZnJvbSBKYXZhU2NyaXB0XG4gIHJldHVybiAoKGYubCA+PSAwKT9mLmw6KGYubCA9IGYubGVuZ3RoKSkgLSAxXG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfanNfZXF1YWxzIG11dGFibGUgKGNvbnN0LCBjb25zdClcbmZ1bmN0aW9uIGNhbWxfanNfZXF1YWxzICh4LCB5KSB7IHJldHVybiArKHggPT0geSk7IH1cblxuLy9Qcm92aWRlczogY2FtbF9qc19zdHJpY3RfZXF1YWxzIG11dGFibGUgKGNvbnN0LCBjb25zdClcbmZ1bmN0aW9uIGNhbWxfanNfc3RyaWN0X2VxdWFscyAoeCwgeSkgeyByZXR1cm4gKyh4ID09PSB5KTsgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2pzX2V2YWxfc3RyaW5nIChjb25zdClcbi8vUmVxdWlyZXM6IGNhbWxfanNzdHJpbmdfb2Zfc3RyaW5nXG5mdW5jdGlvbiBjYW1sX2pzX2V2YWxfc3RyaW5nIChzKSB7cmV0dXJuIGV2YWwoY2FtbF9qc3N0cmluZ19vZl9zdHJpbmcocykpO31cblxuLy9Qcm92aWRlczogY2FtbF9qc19leHByIChjb25zdClcbi8vUmVxdWlyZXM6IGNhbWxfanNzdHJpbmdfb2Zfc3RyaW5nXG5mdW5jdGlvbiBjYW1sX2pzX2V4cHIocykge1xuICBjb25zb2xlLmVycm9yKFwiY2FtbF9qc19leHByOiBmYWxsYmFjayB0byBydW50aW1lIGV2YWx1YXRpb25cXG5cIik7XG4gIHJldHVybiBldmFsKGNhbWxfanNzdHJpbmdfb2Zfc3RyaW5nKHMpKTt9XG5cbi8vUHJvdmlkZXM6IGNhbWxfcHVyZV9qc19leHByIGNvbnN0IChjb25zdClcbi8vUmVxdWlyZXM6IGNhbWxfanNzdHJpbmdfb2Zfc3RyaW5nXG5mdW5jdGlvbiBjYW1sX3B1cmVfanNfZXhwciAocyl7XG4gIGNvbnNvbGUuZXJyb3IoXCJjYW1sX3B1cmVfanNfZXhwcjogZmFsbGJhY2sgdG8gcnVudGltZSBldmFsdWF0aW9uXFxuXCIpO1xuICByZXR1cm4gZXZhbChjYW1sX2pzc3RyaW5nX29mX3N0cmluZyhzKSk7fVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2pzX29iamVjdCAob2JqZWN0X2xpdGVyYWwpXG4vL1JlcXVpcmVzOiBjYW1sX2pzc3RyaW5nX29mX3N0cmluZ1xuZnVuY3Rpb24gY2FtbF9qc19vYmplY3QgKGEpIHtcbiAgdmFyIG8gPSB7fTtcbiAgZm9yICh2YXIgaSA9IDE7IGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHAgPSBhW2ldO1xuICAgIG9bY2FtbF9qc3N0cmluZ19vZl9zdHJpbmcocFsxXSldID0gcFsyXTtcbiAgfVxuICByZXR1cm4gbztcbn1cbiIsIi8vIEpzX29mX29jYW1sIHJ1bnRpbWUgc3VwcG9ydFxuLy8gaHR0cDovL3d3dy5vY3NpZ2VuLm9yZy9qc19vZl9vY2FtbC9cbi8vXG4vLyBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuLy8gaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4vLyB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCB3aXRoIGxpbmtpbmcgZXhjZXB0aW9uO1xuLy8gZWl0aGVyIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy9cbi8vIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbi8vIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy9cbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuLy8gYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuXG5cbi8vUmFpc2UgZXhjZXB0aW9uXG5cbi8vUHJvdmlkZXM6IGNhbWxfcmFpc2VfY29uc3RhbnQgKGNvbnN0KVxuZnVuY3Rpb24gY2FtbF9yYWlzZV9jb25zdGFudCAodGFnKSB7IHRocm93IHRhZzsgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3JhaXNlX3dpdGhfYXJnIChjb25zdCwgbXV0YWJsZSlcbi8vUmVxdWlyZXM6IGNhbWxfbWF5YmVfYXR0YWNoX2JhY2t0cmFjZVxuZnVuY3Rpb24gY2FtbF9yYWlzZV93aXRoX2FyZyAodGFnLCBhcmcpIHsgdGhyb3cgY2FtbF9tYXliZV9hdHRhY2hfYmFja3RyYWNlKFswLCB0YWcsIGFyZ10pOyB9XG5cbi8vUHJvdmlkZXM6IGNhbWxfcmFpc2Vfd2l0aF9hcmdzIChjb25zdCwgbXV0YWJsZSlcbi8vUmVxdWlyZXM6IGNhbWxfbWF5YmVfYXR0YWNoX2JhY2t0cmFjZVxuZnVuY3Rpb24gY2FtbF9yYWlzZV93aXRoX2FyZ3MgKHRhZywgYXJncykgeyB0aHJvdyBjYW1sX21heWJlX2F0dGFjaF9iYWNrdHJhY2UoWzAsIHRhZ10uY29uY2F0KGFyZ3MpKTsgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3JhaXNlX3dpdGhfc3RyaW5nIChjb25zdCwgY29uc3QpXG4vL1JlcXVpcmVzOiBjYW1sX3JhaXNlX3dpdGhfYXJnLCBjYW1sX3N0cmluZ19vZl9qc2J5dGVzXG5mdW5jdGlvbiBjYW1sX3JhaXNlX3dpdGhfc3RyaW5nICh0YWcsIG1zZykge1xuICBjYW1sX3JhaXNlX3dpdGhfYXJnICh0YWcsIGNhbWxfc3RyaW5nX29mX2pzYnl0ZXMobXNnKSk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfZmFpbHdpdGggKGNvbnN0KVxuLy9SZXF1aXJlczogY2FtbF9yYWlzZV93aXRoX3N0cmluZywgY2FtbF9nbG9iYWxfZGF0YSwgY2FtbF9zdHJpbmdfb2ZfanNieXRlc1xuZnVuY3Rpb24gY2FtbF9mYWlsd2l0aCAobXNnKSB7XG4gIGlmKCFjYW1sX2dsb2JhbF9kYXRhLkZhaWx1cmUpXG4gICAgY2FtbF9nbG9iYWxfZGF0YS5GYWlsdXJlPVsyNDgsY2FtbF9zdHJpbmdfb2ZfanNieXRlcyhcIkZhaWx1cmVcIiksLTNdO1xuICBjYW1sX3JhaXNlX3dpdGhfc3RyaW5nKGNhbWxfZ2xvYmFsX2RhdGEuRmFpbHVyZSwgbXNnKTtcbn1cblxuXG4vL1Byb3ZpZGVzOiBjYW1sX2ludmFsaWRfYXJndW1lbnQgKGNvbnN0KVxuLy9SZXF1aXJlczogY2FtbF9yYWlzZV93aXRoX3N0cmluZywgY2FtbF9nbG9iYWxfZGF0YVxuZnVuY3Rpb24gY2FtbF9pbnZhbGlkX2FyZ3VtZW50IChtc2cpIHtcbiAgY2FtbF9yYWlzZV93aXRoX3N0cmluZyhjYW1sX2dsb2JhbF9kYXRhLkludmFsaWRfYXJndW1lbnQsIG1zZyk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfcmFpc2VfZW5kX29mX2ZpbGVcbi8vUmVxdWlyZXM6IGNhbWxfcmFpc2VfY29uc3RhbnQsIGNhbWxfZ2xvYmFsX2RhdGFcbmZ1bmN0aW9uIGNhbWxfcmFpc2VfZW5kX29mX2ZpbGUgKCkge1xuICBjYW1sX3JhaXNlX2NvbnN0YW50KGNhbWxfZ2xvYmFsX2RhdGEuRW5kX29mX2ZpbGUpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3JhaXNlX3plcm9fZGl2aWRlXG4vL1JlcXVpcmVzOiBjYW1sX3JhaXNlX2NvbnN0YW50LCBjYW1sX2dsb2JhbF9kYXRhXG5mdW5jdGlvbiBjYW1sX3JhaXNlX3plcm9fZGl2aWRlICgpIHtcbiAgY2FtbF9yYWlzZV9jb25zdGFudChjYW1sX2dsb2JhbF9kYXRhLkRpdmlzaW9uX2J5X3plcm8pO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3JhaXNlX25vdF9mb3VuZFxuLy9SZXF1aXJlczogY2FtbF9yYWlzZV9jb25zdGFudCwgY2FtbF9nbG9iYWxfZGF0YVxuZnVuY3Rpb24gY2FtbF9yYWlzZV9ub3RfZm91bmQgKCkge1xuICBjYW1sX3JhaXNlX2NvbnN0YW50KGNhbWxfZ2xvYmFsX2RhdGEuTm90X2ZvdW5kKTsgfVxuXG5cbi8vUHJvdmlkZXM6IGNhbWxfYXJyYXlfYm91bmRfZXJyb3Jcbi8vUmVxdWlyZXM6IGNhbWxfaW52YWxpZF9hcmd1bWVudFxuZnVuY3Rpb24gY2FtbF9hcnJheV9ib3VuZF9lcnJvciAoKSB7XG4gIGNhbWxfaW52YWxpZF9hcmd1bWVudChcImluZGV4IG91dCBvZiBib3VuZHNcIik7XG59XG4iLCIvLyBKc19vZl9vY2FtbCBydW50aW1lIHN1cHBvcnRcbi8vIGh0dHA6Ly93d3cub2NzaWdlbi5vcmcvanNfb2Zfb2NhbWwvXG4vLyBDb3B5cmlnaHQgKEMpIDIwMTQgSsOpcsO0bWUgVm91aWxsb24sIEh1Z28gSGV1emFyZFxuLy8gTGFib3JhdG9pcmUgUFBTIC0gQ05SUyBVbml2ZXJzaXTDqSBQYXJpcyBEaWRlcm90XG4vL1xuLy8gVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbi8vIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuLy8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgd2l0aCBsaW5raW5nIGV4Y2VwdGlvbjtcbi8vIGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vXG4vLyBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4vLyBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2Vcbi8vIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLlxuXG4vLy8vLy8vLy8vLy8vIER1bW15IGZpbGVzeXN0ZW1cblxuLy9Qcm92aWRlczogY2FtbF90cmFpbGluZ19zbGFzaFxuZnVuY3Rpb24gY2FtbF90cmFpbGluZ19zbGFzaChuYW1lKXtcbiAgcmV0dXJuIChuYW1lLnNsaWNlKC0xKSAhPT0gXCIvXCIpID8gKG5hbWUgKyBcIi9cIikgOiBuYW1lO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2N1cnJlbnRfZGlyXG4vL1JlcXVpcmVzOiBjYW1sX3RyYWlsaW5nX3NsYXNoLCBmc19ub2RlX3N1cHBvcnRlZFxuaWYoZnNfbm9kZV9zdXBwb3J0ZWQgKCkgJiYgZ2xvYmFsVGhpcy5wcm9jZXNzICYmIGdsb2JhbFRoaXMucHJvY2Vzcy5jd2QpXG4gIHZhciBjYW1sX2N1cnJlbnRfZGlyID0gZ2xvYmFsVGhpcy5wcm9jZXNzLmN3ZCgpLnJlcGxhY2UoL1xcXFwvZywnLycpO1xuZWxzZVxuICB2YXIgY2FtbF9jdXJyZW50X2RpciA9ICBcIi9zdGF0aWNcIjtcbmNhbWxfY3VycmVudF9kaXIgPSBjYW1sX3RyYWlsaW5nX3NsYXNoKGNhbWxfY3VycmVudF9kaXIpO1xuXG4vL1Byb3ZpZGVzOiBjYW1sX2dldF9yb290XG4vL1JlcXVpcmVzOiBwYXRoX2lzX2Fic29sdXRlXG5mdW5jdGlvbiBjYW1sX2dldF9yb290KHBhdGgpe1xuICB2YXIgeCA9IHBhdGhfaXNfYWJzb2x1dGUocGF0aCk7XG4gIGlmICgheCkgcmV0dXJuO1xuICByZXR1cm4geFswXSArIFwiL1wifVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3Jvb3Rcbi8vUmVxdWlyZXM6IGNhbWxfZ2V0X3Jvb3QsIGNhbWxfY3VycmVudF9kaXIsIGNhbWxfZmFpbHdpdGhcbnZhciBjYW1sX3Jvb3QgPSBjYW1sX2dldF9yb290KGNhbWxfY3VycmVudF9kaXIpIHx8IGNhbWxfZmFpbHdpdGgoXCJ1bmFibGUgdG8gY29tcHV0ZSBjYW1sX3Jvb3RcIik7XG5cblxuLy9Qcm92aWRlczogTWxGaWxlXG5mdW5jdGlvbiBNbEZpbGUoKXsgIH1cblxuLy9Qcm92aWRlczogcGF0aF9pc19hYnNvbHV0ZVxuLy9SZXF1aXJlczogZnNfbm9kZV9zdXBwb3J0ZWRcbmZ1bmN0aW9uIG1ha2VfcGF0aF9pc19hYnNvbHV0ZSgpIHtcbiAgZnVuY3Rpb24gcG9zaXgocGF0aCkge1xuICAgIGlmIChwYXRoLmNoYXJBdCgwKSA9PT0gJy8nKSByZXR1cm4gW1wiXCIsIHBhdGguc3Vic3RyaW5nKDEpXTtcbiAgICByZXR1cm47XG4gIH1cblxuICBmdW5jdGlvbiB3aW4zMihwYXRoKSB7XG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL25vZGVqcy9ub2RlL2Jsb2IvYjNmY2MyNDVmYjI1NTM5OTA5ZWYxZDVlYWEwMWRiZjkyZTE2ODYzMy9saWIvcGF0aC5qcyNMNTZcbiAgICB2YXIgc3BsaXREZXZpY2VSZSA9IC9eKFthLXpBLVpdOnxbXFxcXC9dezJ9W15cXFxcL10rW1xcXFwvXStbXlxcXFwvXSspPyhbXFxcXC9dKT8oW1xcc1xcU10qPykkLztcbiAgICB2YXIgcmVzdWx0ID0gc3BsaXREZXZpY2VSZS5leGVjKHBhdGgpO1xuICAgIHZhciBkZXZpY2UgPSByZXN1bHRbMV0gfHwgJyc7XG4gICAgdmFyIGlzVW5jID0gQm9vbGVhbihkZXZpY2UgJiYgZGV2aWNlLmNoYXJBdCgxKSAhPT0gJzonKTtcblxuICAgIC8vIFVOQyBwYXRocyBhcmUgYWx3YXlzIGFic29sdXRlXG4gICAgaWYgKEJvb2xlYW4ocmVzdWx0WzJdIHx8IGlzVW5jKSkge1xuICAgICAgdmFyIHJvb3QgPSAocmVzdWx0WzFdIHx8ICcnKTtcbiAgICAgIHZhciBzZXAgPSAocmVzdWx0WzJdIHx8ICcnKTtcbiAgICAgIHJldHVybiBbcm9vdCwgcGF0aC5zdWJzdHJpbmcocm9vdC5sZW5ndGggKyBzZXAubGVuZ3RoKV1cbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmKGZzX25vZGVfc3VwcG9ydGVkICgpICYmIGdsb2JhbFRoaXMucHJvY2VzcyAmJiBnbG9iYWxUaGlzLnByb2Nlc3MucGxhdGZvcm0pIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpcy5wcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInID8gd2luMzIgOiBwb3NpeDtcbiAgfVxuICBlbHNlIHJldHVybiBwb3NpeFxufVxudmFyIHBhdGhfaXNfYWJzb2x1dGUgPSBtYWtlX3BhdGhfaXNfYWJzb2x1dGUoKTtcblxuLy9Qcm92aWRlczogY2FtbF9tYWtlX3BhdGhcbi8vUmVxdWlyZXM6IGNhbWxfY3VycmVudF9kaXJcbi8vUmVxdWlyZXM6IGNhbWxfanNzdHJpbmdfb2Zfc3RyaW5nLCBwYXRoX2lzX2Fic29sdXRlXG5mdW5jdGlvbiBjYW1sX21ha2VfcGF0aCAobmFtZSkge1xuICBuYW1lPWNhbWxfanNzdHJpbmdfb2Zfc3RyaW5nKG5hbWUpO1xuICBpZiggIXBhdGhfaXNfYWJzb2x1dGUobmFtZSkgKVxuICAgIG5hbWUgPSBjYW1sX2N1cnJlbnRfZGlyICsgbmFtZTtcbiAgdmFyIGNvbXAwID0gcGF0aF9pc19hYnNvbHV0ZShuYW1lKTtcbiAgdmFyIGNvbXAgPSBjb21wMFsxXS5zcGxpdChcIi9cIik7XG4gIHZhciBuY29tcCA9IFtdXG4gIGZvcih2YXIgaSA9IDA7IGk8Y29tcC5sZW5ndGg7IGkrKyl7XG4gICAgc3dpdGNoKGNvbXBbaV0pe1xuICAgIGNhc2UgXCIuLlwiOiBpZihuY29tcC5sZW5ndGg+MSkgbmNvbXAucG9wKCk7IGJyZWFrO1xuICAgIGNhc2UgXCIuXCI6IGJyZWFrO1xuICAgIGNhc2UgXCJcIjogYnJlYWs7XG4gICAgZGVmYXVsdDogbmNvbXAucHVzaChjb21wW2ldKTticmVha1xuICAgIH1cbiAgfVxuICBuY29tcC51bnNoaWZ0KGNvbXAwWzBdKTtcbiAgbmNvbXAub3JpZyA9IG5hbWU7XG4gIHJldHVybiBuY29tcDtcbn1cblxuLy9Qcm92aWRlczpqc29vX21vdW50X3BvaW50XG4vL1JlcXVpcmVzOiBNbEZha2VEZXZpY2UsIE1sTm9kZURldmljZSwgY2FtbF9yb290LCBmc19ub2RlX3N1cHBvcnRlZFxudmFyIGpzb29fbW91bnRfcG9pbnQgPSBbXVxuaWYgKGZzX25vZGVfc3VwcG9ydGVkKCkpIHtcbiAganNvb19tb3VudF9wb2ludC5wdXNoKHtwYXRoOmNhbWxfcm9vdCxkZXZpY2U6bmV3IE1sTm9kZURldmljZShjYW1sX3Jvb3QpfSk7XG59IGVsc2Uge1xuICBqc29vX21vdW50X3BvaW50LnB1c2goe3BhdGg6Y2FtbF9yb290LGRldmljZTpuZXcgTWxGYWtlRGV2aWNlKGNhbWxfcm9vdCl9KTtcbn1cbmpzb29fbW91bnRfcG9pbnQucHVzaCh7cGF0aDpcIi9zdGF0aWMvXCIsIGRldmljZTpuZXcgTWxGYWtlRGV2aWNlKFwiL3N0YXRpYy9cIil9KTtcblxuLy9Qcm92aWRlczpjYW1sX2xpc3RfbW91bnRfcG9pbnRcbi8vUmVxdWlyZXM6IGpzb29fbW91bnRfcG9pbnQsIGNhbWxfc3RyaW5nX29mX2pzYnl0ZXNcbmZ1bmN0aW9uIGNhbWxfbGlzdF9tb3VudF9wb2ludCgpe1xuICB2YXIgcHJldiA9IDBcbiAgZm9yKHZhciBpID0gMDsgaSA8IGpzb29fbW91bnRfcG9pbnQubGVuZ3RoOyBpKyspe1xuICAgIHZhciBvbGQgPSBwcmV2O1xuICAgIHByZXYgPSBbMCwgY2FtbF9zdHJpbmdfb2ZfanNieXRlcyhqc29vX21vdW50X3BvaW50W2ldLnBhdGgpLCBvbGRdXG4gIH1cbiAgcmV0dXJuIHByZXY7XG59XG5cbi8vUHJvdmlkZXM6IHJlc29sdmVfZnNfZGV2aWNlXG4vL1JlcXVpcmVzOiBjYW1sX21ha2VfcGF0aCwganNvb19tb3VudF9wb2ludCwgY2FtbF9yYWlzZV9zeXNfZXJyb3IsIGNhbWxfZ2V0X3Jvb3QsIE1sTm9kZURldmljZSwgY2FtbF90cmFpbGluZ19zbGFzaCwgZnNfbm9kZV9zdXBwb3J0ZWRcbmZ1bmN0aW9uIHJlc29sdmVfZnNfZGV2aWNlKG5hbWUpe1xuICB2YXIgcGF0aCA9IGNhbWxfbWFrZV9wYXRoKG5hbWUpO1xuICB2YXIgbmFtZSA9IHBhdGguam9pbihcIi9cIik7XG4gIHZhciBuYW1lX3NsYXNoID0gY2FtbF90cmFpbGluZ19zbGFzaChuYW1lKTtcbiAgdmFyIHJlcztcbiAgZm9yKHZhciBpID0gMDsgaSA8IGpzb29fbW91bnRfcG9pbnQubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgbSA9IGpzb29fbW91bnRfcG9pbnRbaV07XG4gICAgaWYobmFtZV9zbGFzaC5zZWFyY2gobS5wYXRoKSA9PSAwXG4gICAgICAgJiYgKCFyZXMgfHwgcmVzLnBhdGgubGVuZ3RoIDwgbS5wYXRoLmxlbmd0aCkpXG4gICAgICByZXMgPSB7cGF0aDptLnBhdGgsZGV2aWNlOm0uZGV2aWNlLHJlc3Q6bmFtZS5zdWJzdHJpbmcobS5wYXRoLmxlbmd0aCxuYW1lLmxlbmd0aCl9O1xuICB9XG4gIGlmKCAhcmVzICYmIGZzX25vZGVfc3VwcG9ydGVkKCkpIHtcbiAgICB2YXIgcm9vdCA9IGNhbWxfZ2V0X3Jvb3QobmFtZSk7XG4gICAgaWYgKHJvb3QgJiYgcm9vdC5tYXRjaCgvXlthLXpBLVpdOlxcLyQvKSl7XG4gICAgICB2YXIgbSA9IHtwYXRoOnJvb3QsZGV2aWNlOm5ldyBNbE5vZGVEZXZpY2Uocm9vdCl9O1xuICAgICAganNvb19tb3VudF9wb2ludC5wdXNoKG0pO1xuICAgICAgcmVzID0ge3BhdGg6bS5wYXRoLGRldmljZTptLmRldmljZSxyZXN0Om5hbWUuc3Vic3RyaW5nKG0ucGF0aC5sZW5ndGgsbmFtZS5sZW5ndGgpfTtcbiAgICB9XG4gIH1cbiAgaWYoIHJlcyApIHJldHVybiByZXM7XG4gIGNhbWxfcmFpc2Vfc3lzX2Vycm9yKFwibm8gZGV2aWNlIGZvdW5kIGZvciBcIiArIG5hbWVfc2xhc2gpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21vdW50X2F1dG9sb2FkXG4vL1JlcXVpcmVzOiBNbEZha2VEZXZpY2UsIGNhbWxfbWFrZV9wYXRoLCBqc29vX21vdW50X3BvaW50LCBjYW1sX3RyYWlsaW5nX3NsYXNoXG5mdW5jdGlvbiBjYW1sX21vdW50X2F1dG9sb2FkKG5hbWUsZil7XG4gIHZhciBwYXRoID0gY2FtbF9tYWtlX3BhdGgobmFtZSk7XG4gIHZhciBuYW1lID0gY2FtbF90cmFpbGluZ19zbGFzaChwYXRoLmpvaW4oXCIvXCIpKTtcbiAganNvb19tb3VudF9wb2ludC5wdXNoKHtwYXRoOm5hbWUsZGV2aWNlOm5ldyBNbEZha2VEZXZpY2UobmFtZSxmKX0pXG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3VubW91bnRcbi8vUmVxdWlyZXM6IGpzb29fbW91bnRfcG9pbnQsIGNhbWxfbWFrZV9wYXRoLCBjYW1sX3RyYWlsaW5nX3NsYXNoXG5mdW5jdGlvbiBjYW1sX3VubW91bnQobmFtZSl7XG4gIHZhciBwYXRoID0gY2FtbF9tYWtlX3BhdGgobmFtZSk7XG4gIHZhciBuYW1lID0gY2FtbF90cmFpbGluZ19zbGFzaChwYXRoLmpvaW4oXCIvXCIpKTtcbiAgdmFyIGlkeCA9IC0xO1xuICBmb3IodmFyIGkgPSAwOyBpIDwganNvb19tb3VudF9wb2ludC5sZW5ndGg7IGkrKylcbiAgICBpZihqc29vX21vdW50X3BvaW50W2ldLnBhdGggPT0gbmFtZSkgaWR4ID0gaTtcbiAgaWYoaWR4ID4gLTEpIGpzb29fbW91bnRfcG9pbnQuc3BsaWNlKGlkeCwxKTtcbiAgcmV0dXJuIDBcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zeXNfZ2V0Y3dkXG4vL1JlcXVpcmVzOiBjYW1sX2N1cnJlbnRfZGlyLCBjYW1sX3N0cmluZ19vZl9qc2J5dGVzXG5mdW5jdGlvbiBjYW1sX3N5c19nZXRjd2QoKSB7XG4gIHJldHVybiBjYW1sX3N0cmluZ19vZl9qc2J5dGVzKGNhbWxfY3VycmVudF9kaXIpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N5c19jaGRpclxuLy9SZXF1aXJlczogY2FtbF9jdXJyZW50X2RpciwgY2FtbF9yYWlzZV9ub19zdWNoX2ZpbGUsIHJlc29sdmVfZnNfZGV2aWNlLCBjYW1sX3RyYWlsaW5nX3NsYXNoLCBjYW1sX2pzYnl0ZXNfb2Zfc3RyaW5nXG5mdW5jdGlvbiBjYW1sX3N5c19jaGRpcihkaXIpIHtcbiAgdmFyIHJvb3QgPSByZXNvbHZlX2ZzX2RldmljZShkaXIpO1xuICBpZihyb290LmRldmljZS5leGlzdHMocm9vdC5yZXN0KSkge1xuICAgIGlmKHJvb3QucmVzdCkgY2FtbF9jdXJyZW50X2RpciA9IGNhbWxfdHJhaWxpbmdfc2xhc2gocm9vdC5wYXRoICsgcm9vdC5yZXN0KTtcbiAgICBlbHNlIGNhbWxfY3VycmVudF9kaXIgPSByb290LnBhdGg7XG4gICAgcmV0dXJuIDA7XG4gIH1cbiAgZWxzZSB7XG4gICAgY2FtbF9yYWlzZV9ub19zdWNoX2ZpbGUoY2FtbF9qc2J5dGVzX29mX3N0cmluZyhkaXIpKTtcbiAgfVxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3JhaXNlX25vX3N1Y2hfZmlsZVxuLy9SZXF1aXJlczogY2FtbF9yYWlzZV9zeXNfZXJyb3JcbmZ1bmN0aW9uIGNhbWxfcmFpc2Vfbm9fc3VjaF9maWxlKG5hbWUpe1xuICBjYW1sX3JhaXNlX3N5c19lcnJvciAobmFtZSArIFwiOiBObyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5XCIpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3JhaXNlX25vdF9hX2RpclxuLy9SZXF1aXJlczogY2FtbF9yYWlzZV9zeXNfZXJyb3JcbmZ1bmN0aW9uIGNhbWxfcmFpc2Vfbm90X2FfZGlyKG5hbWUpe1xuICBjYW1sX3JhaXNlX3N5c19lcnJvciAobmFtZSArIFwiOiBOb3QgYSBkaXJlY3RvcnlcIik7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3lzX2ZpbGVfZXhpc3RzXG4vL1JlcXVpcmVzOiByZXNvbHZlX2ZzX2RldmljZVxuZnVuY3Rpb24gY2FtbF9zeXNfZmlsZV9leGlzdHMgKG5hbWUpIHtcbiAgdmFyIHJvb3QgPSByZXNvbHZlX2ZzX2RldmljZShuYW1lKTtcbiAgcmV0dXJuIHJvb3QuZGV2aWNlLmV4aXN0cyhyb290LnJlc3QpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N5c19yZWFkX2RpcmVjdG9yeVxuLy9SZXF1aXJlczogY2FtbF9zdHJpbmdfb2ZfanNieXRlc1xuLy9SZXF1aXJlczogY2FtbF9yYWlzZV9ub3RfYV9kaXIsIHJlc29sdmVfZnNfZGV2aWNlXG5mdW5jdGlvbiBjYW1sX3N5c19yZWFkX2RpcmVjdG9yeShuYW1lKXtcbiAgdmFyIHJvb3QgPSByZXNvbHZlX2ZzX2RldmljZShuYW1lKTtcbiAgdmFyIGEgPSByb290LmRldmljZS5yZWFkZGlyKHJvb3QucmVzdCk7XG4gIHZhciBsID0gbmV3IEFycmF5KGEubGVuZ3RoICsgMSk7XG4gIGxbMF0gPSAwO1xuICBmb3IodmFyIGk9MDtpPGEubGVuZ3RoO2krKylcbiAgICBsW2krMV0gPSBjYW1sX3N0cmluZ19vZl9qc2J5dGVzKGFbaV0pO1xuICByZXR1cm4gbDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zeXNfcmVtb3ZlXG4vL1JlcXVpcmVzOiBjYW1sX3JhaXNlX25vX3N1Y2hfZmlsZSwgcmVzb2x2ZV9mc19kZXZpY2UsIGNhbWxfanNieXRlc19vZl9zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfc3lzX3JlbW92ZShuYW1lKXtcbiAgdmFyIHJvb3QgPSByZXNvbHZlX2ZzX2RldmljZShuYW1lKTtcbiAgdmFyIG9rID0gcm9vdC5kZXZpY2UudW5saW5rKHJvb3QucmVzdCk7XG4gIGlmKG9rID09IDApIGNhbWxfcmFpc2Vfbm9fc3VjaF9maWxlKGNhbWxfanNieXRlc19vZl9zdHJpbmcobmFtZSkpO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zeXNfaXNfZGlyZWN0b3J5XG4vL1JlcXVpcmVzOiByZXNvbHZlX2ZzX2RldmljZVxuZnVuY3Rpb24gY2FtbF9zeXNfaXNfZGlyZWN0b3J5KG5hbWUpe1xuICB2YXIgcm9vdCA9IHJlc29sdmVfZnNfZGV2aWNlKG5hbWUpO1xuICB2YXIgYSA9IHJvb3QuZGV2aWNlLmlzX2Rpcihyb290LnJlc3QpO1xuICByZXR1cm4gYT8xOjA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3lzX3JlbmFtZVxuLy9SZXF1aXJlczogY2FtbF9mYWlsd2l0aCwgcmVzb2x2ZV9mc19kZXZpY2VcbmZ1bmN0aW9uIGNhbWxfc3lzX3JlbmFtZShvLG4pe1xuICB2YXIgb19yb290ID0gcmVzb2x2ZV9mc19kZXZpY2Uobyk7XG4gIHZhciBuX3Jvb3QgPSByZXNvbHZlX2ZzX2RldmljZShuKTtcbiAgaWYob19yb290LmRldmljZSAhPSBuX3Jvb3QuZGV2aWNlKVxuICAgIGNhbWxfZmFpbHdpdGgoXCJjYW1sX3N5c19yZW5hbWU6IGNhbm5vdCBtb3ZlIGZpbGUgYmV0d2VlbiB0d28gZmlsZXN5c3RlbVwiKTtcbiAgaWYoIW9fcm9vdC5kZXZpY2UucmVuYW1lKVxuICAgIGNhbWxfZmFpbHdpdGgoXCJjYW1sX3N5c19yZW5hbWU6IG5vIGltcGxlbWVudGVkXCIpO1xuICBvX3Jvb3QuZGV2aWNlLnJlbmFtZShvX3Jvb3QucmVzdCwgbl9yb290LnJlc3QpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N5c19ta2RpclxuLy9SZXF1aXJlczogcmVzb2x2ZV9mc19kZXZpY2UsIGNhbWxfcmFpc2Vfc3lzX2Vycm9yXG5mdW5jdGlvbiBjYW1sX3N5c19ta2RpcihuYW1lLCBwZXJtKXtcbiAgdmFyIHJvb3QgPSByZXNvbHZlX2ZzX2RldmljZShuYW1lKTtcbiAgcm9vdC5kZXZpY2UubWtkaXIocm9vdC5yZXN0LHBlcm0pO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zeXNfcm1kaXJcbi8vUmVxdWlyZXM6IHJlc29sdmVfZnNfZGV2aWNlLCBjYW1sX3JhaXNlX3N5c19lcnJvciwgY2FtbF9yYWlzZV9ub3RfYV9kaXJcbmZ1bmN0aW9uIGNhbWxfc3lzX3JtZGlyKG5hbWUpe1xuICB2YXIgcm9vdCA9IHJlc29sdmVfZnNfZGV2aWNlKG5hbWUpO1xuICByb290LmRldmljZS5ybWRpcihyb290LnJlc3QpO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iYV9tYXBfZmlsZVxuLy9SZXF1aXJlczogY2FtbF9mYWlsd2l0aFxuZnVuY3Rpb24gY2FtbF9iYV9tYXBfZmlsZSh2ZmQsIGtpbmQsIGxheW91dCwgc2hhcmVkLCBkaW1zLCBwb3MpIHtcbiAgLy8gdmFyIGRhdGEgPSBjYW1sX3N5c19mZHNbdmZkXTtcbiAgY2FtbF9mYWlsd2l0aChcImNhbWxfYmFfbWFwX2ZpbGUgbm90IGltcGxlbWVudGVkXCIpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2JhX21hcF9maWxlX2J5dGVjb2RlXG4vL1JlcXVpcmVzOiBjYW1sX2JhX21hcF9maWxlXG5mdW5jdGlvbiBjYW1sX2JhX21hcF9maWxlX2J5dGVjb2RlKGFyZ3YsYXJnbil7XG4gIHJldHVybiBjYW1sX2JhX21hcF9maWxlKGFyZ3ZbMF0sYXJndlsxXSxhcmd2WzJdLGFyZ3ZbM10sYXJndls0XSxhcmd2WzVdKTtcbn1cblxuLy9Qcm92aWRlczoganNvb19jcmVhdGVfZmlsZV9leHRlcm5cbmZ1bmN0aW9uIGpzb29fY3JlYXRlX2ZpbGVfZXh0ZXJuKG5hbWUsY29udGVudCl7XG4gIGlmKGdsb2JhbFRoaXMuanNvb19jcmVhdGVfZmlsZSlcbiAgICBnbG9iYWxUaGlzLmpzb29fY3JlYXRlX2ZpbGUobmFtZSxjb250ZW50KTtcbiAgZWxzZSB7XG4gICAgaWYoIWdsb2JhbFRoaXMuY2FtbF9mc190bXApIGdsb2JhbFRoaXMuY2FtbF9mc190bXAgPSBbXTtcbiAgICBnbG9iYWxUaGlzLmNhbWxfZnNfdG1wLnB1c2goe25hbWU6bmFtZSxjb250ZW50OmNvbnRlbnR9KTtcbiAgfVxuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9mc19pbml0XG4vL1JlcXVpcmVzOiBqc29vX2NyZWF0ZV9maWxlXG5mdW5jdGlvbiBjYW1sX2ZzX2luaXQgKCl7XG4gIHZhciB0bXA9Z2xvYmFsVGhpcy5jYW1sX2ZzX3RtcFxuICBpZih0bXApe1xuICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0bXAubGVuZ3RoOyBpKyspe1xuICAgICAganNvb19jcmVhdGVfZmlsZSh0bXBbaV0ubmFtZSx0bXBbaV0uY29udGVudCk7XG4gICAgfVxuICB9XG4gIGdsb2JhbFRoaXMuanNvb19jcmVhdGVfZmlsZSA9IGpzb29fY3JlYXRlX2ZpbGU7XG4gIGdsb2JhbFRoaXMuY2FtbF9mc190bXAgPSBbXTtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfY3JlYXRlX2ZpbGVcbi8vUmVxdWlyZXM6IGNhbWxfZmFpbHdpdGgsIHJlc29sdmVfZnNfZGV2aWNlXG5mdW5jdGlvbiBjYW1sX2NyZWF0ZV9maWxlKG5hbWUsY29udGVudCkge1xuICB2YXIgcm9vdCA9IHJlc29sdmVfZnNfZGV2aWNlKG5hbWUpO1xuICBpZighIHJvb3QuZGV2aWNlLnJlZ2lzdGVyKSBjYW1sX2ZhaWx3aXRoKFwiY2Fubm90IHJlZ2lzdGVyIGZpbGVcIik7XG4gIHJvb3QuZGV2aWNlLnJlZ2lzdGVyKHJvb3QucmVzdCxjb250ZW50KTtcbiAgcmV0dXJuIDA7XG59XG5cblxuLy9Qcm92aWRlczoganNvb19jcmVhdGVfZmlsZVxuLy9SZXF1aXJlczogY2FtbF9jcmVhdGVfZmlsZSwgY2FtbF9zdHJpbmdfb2ZfanNieXRlc1xuZnVuY3Rpb24ganNvb19jcmVhdGVfZmlsZShuYW1lLGNvbnRlbnQpIHtcbiAgdmFyIG5hbWUgPSBjYW1sX3N0cmluZ19vZl9qc2J5dGVzKG5hbWUpO1xuICB2YXIgY29udGVudCA9IGNhbWxfc3RyaW5nX29mX2pzYnl0ZXMoY29udGVudCk7XG4gIHJldHVybiBjYW1sX2NyZWF0ZV9maWxlKG5hbWUsIGNvbnRlbnQpO1xufVxuXG5cbi8vUHJvdmlkZXM6IGNhbWxfcmVhZF9maWxlX2NvbnRlbnRcbi8vUmVxdWlyZXM6IHJlc29sdmVfZnNfZGV2aWNlLCBjYW1sX3JhaXNlX25vX3N1Y2hfZmlsZSwgY2FtbF9zdHJpbmdfb2ZfYXJyYXlcbi8vUmVxdWlyZXM6IGNhbWxfc3RyaW5nX29mX2pzYnl0ZXMsIGNhbWxfanNieXRlc19vZl9zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfcmVhZF9maWxlX2NvbnRlbnQgKG5hbWUpIHtcbiAgdmFyIG5hbWUgPSAodHlwZW9mIG5hbWUgPT0gXCJzdHJpbmdcIik/Y2FtbF9zdHJpbmdfb2ZfanNieXRlcyhuYW1lKTpuYW1lO1xuICB2YXIgcm9vdCA9IHJlc29sdmVfZnNfZGV2aWNlKG5hbWUpO1xuICBpZihyb290LmRldmljZS5leGlzdHMocm9vdC5yZXN0KSkge1xuICAgIHZhciBmaWxlID0gcm9vdC5kZXZpY2Uub3Blbihyb290LnJlc3Qse3Jkb25seToxfSk7XG4gICAgdmFyIGxlbiAgPSBmaWxlLmxlbmd0aCgpO1xuICAgIHZhciBidWYgPSBuZXcgVWludDhBcnJheShsZW4pO1xuICAgIGZpbGUucmVhZCgwLGJ1ZiwwLGxlbik7XG4gICAgcmV0dXJuIGNhbWxfc3RyaW5nX29mX2FycmF5KGJ1ZilcbiAgfVxuICBjYW1sX3JhaXNlX25vX3N1Y2hfZmlsZShjYW1sX2pzYnl0ZXNfb2Zfc3RyaW5nKG5hbWUpKTtcbn1cbiIsIi8vIEpzX29mX29jYW1sIHJ1bnRpbWUgc3VwcG9ydFxuLy8gaHR0cDovL3d3dy5vY3NpZ2VuLm9yZy9qc19vZl9vY2FtbC9cbi8vIENvcHlyaWdodCAoQykgMjAxNCBKw6lyw7RtZSBWb3VpbGxvbiwgSHVnbyBIZXV6YXJkXG4vLyBMYWJvcmF0b2lyZSBQUFMgLSBDTlJTIFVuaXZlcnNpdMOpIFBhcmlzIERpZGVyb3Rcbi8vXG4vLyBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuLy8gaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4vLyB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCB3aXRoIGxpbmtpbmcgZXhjZXB0aW9uO1xuLy8gZWl0aGVyIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy9cbi8vIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbi8vIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy9cbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuLy8gYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuXG5cbi8vUHJvdmlkZXM6IE1sRmFrZURldmljZVxuLy9SZXF1aXJlczogTWxGYWtlRmlsZSwgTWxGYWtlRmQsIGNhbWxfY3JlYXRlX2J5dGVzXG4vL1JlcXVpcmVzOiBjYW1sX3JhaXNlX3N5c19lcnJvciwgY2FtbF9yYWlzZV9ub19zdWNoX2ZpbGVcbi8vUmVxdWlyZXM6IGNhbWxfc3RyaW5nX29mX2pzYnl0ZXMsIGNhbWxfc3RyaW5nX29mX2pzc3RyaW5nXG4vL1JlcXVpcmVzOiBjYW1sX2J5dGVzX29mX2FycmF5LCBjYW1sX2J5dGVzX29mX3N0cmluZywgY2FtbF9ieXRlc19vZl9qc2J5dGVzXG4vL1JlcXVpcmVzOiBjYW1sX2lzX21sX2J5dGVzLCBjYW1sX2lzX21sX3N0cmluZ1xuLy9SZXF1aXJlczogY2FtbF9uYW1lZF92YWx1ZSwgY2FtbF9yYWlzZV93aXRoX2FyZ3MsIGNhbWxfbmFtZWRfdmFsdWVzXG4vL1JlcXVpcmVzOiBtYWtlX3VuaXhfZXJyX2FyZ3NcbmZ1bmN0aW9uIE1sRmFrZURldmljZSAocm9vdCwgZikge1xuICB0aGlzLmNvbnRlbnQ9e307XG4gIHRoaXMucm9vdCA9IHJvb3Q7XG4gIHRoaXMubG9va3VwRnVuID0gZjtcbn1cbk1sRmFrZURldmljZS5wcm90b3R5cGUubm0gPSBmdW5jdGlvbihuYW1lKSB7XG4gIHJldHVybiAodGhpcy5yb290ICsgbmFtZSk7XG59XG5NbEZha2VEZXZpY2UucHJvdG90eXBlLmNyZWF0ZV9kaXJfaWZfbmVlZGVkID0gZnVuY3Rpb24obmFtZSkge1xuICB2YXIgY29tcCA9IG5hbWUuc3BsaXQoXCIvXCIpO1xuICB2YXIgcmVzID0gXCJcIjtcbiAgZm9yKHZhciBpID0gMDsgaSA8IGNvbXAubGVuZ3RoIC0gMTsgaSsrKXtcbiAgICByZXMgKz0gY29tcFtpXSArIFwiL1wiO1xuICAgIGlmKHRoaXMuY29udGVudFtyZXNdKSBjb250aW51ZTtcbiAgICB0aGlzLmNvbnRlbnRbcmVzXSA9IFN5bWJvbChcImRpcmVjdG9yeVwiKTtcbiAgfVxufVxuTWxGYWtlRGV2aWNlLnByb3RvdHlwZS5zbGFzaCA9IGZ1bmN0aW9uKG5hbWUpe1xuICByZXR1cm4gL1xcLyQvLnRlc3QobmFtZSk/bmFtZToobmFtZSArIFwiL1wiKTtcbn1cbk1sRmFrZURldmljZS5wcm90b3R5cGUubG9va3VwID0gZnVuY3Rpb24obmFtZSkge1xuICBpZighdGhpcy5jb250ZW50W25hbWVdICYmIHRoaXMubG9va3VwRnVuKSB7XG4gICAgdmFyIHJlcyA9IHRoaXMubG9va3VwRnVuKGNhbWxfc3RyaW5nX29mX2pzYnl0ZXModGhpcy5yb290KSwgY2FtbF9zdHJpbmdfb2ZfanNieXRlcyhuYW1lKSk7XG4gICAgaWYocmVzICE9PSAwKSB7XG4gICAgICB0aGlzLmNyZWF0ZV9kaXJfaWZfbmVlZGVkKG5hbWUpO1xuICAgICAgdGhpcy5jb250ZW50W25hbWVdPW5ldyBNbEZha2VGaWxlKGNhbWxfYnl0ZXNfb2Zfc3RyaW5nKHJlc1sxXSkpO1xuICAgIH1cbiAgfVxufVxuTWxGYWtlRGV2aWNlLnByb3RvdHlwZS5leGlzdHMgPSBmdW5jdGlvbihuYW1lKSB7XG4gIC8vIFRoZSByb290IG9mIHRoZSBkZXZpY2UgZXhpc3RzXG4gIGlmKG5hbWUgPT0gXCJcIikgcmV0dXJuIDE7XG4gIC8vIENoZWNrIGlmIGEgZGlyZWN0b3J5IGV4aXN0c1xuICB2YXIgbmFtZV9zbGFzaCA9IHRoaXMuc2xhc2gobmFtZSk7XG4gIGlmKHRoaXMuY29udGVudFtuYW1lX3NsYXNoXSkgcmV0dXJuIDE7XG4gIC8vIENoZWNrIGlmIGEgZmlsZSBleGlzdHNcbiAgdGhpcy5sb29rdXAobmFtZSk7XG4gIHJldHVybiB0aGlzLmNvbnRlbnRbbmFtZV0/MTowO1xufVxuTWxGYWtlRGV2aWNlLnByb3RvdHlwZS5pc0ZpbGUgPSBmdW5jdGlvbihuYW1lKSB7XG4gIGlmKHRoaXMuZXhpc3RzKG5hbWUpICYmICF0aGlzLmlzX2RpcihuYW1lKSkge1xuICAgIHJldHVybiAxXG4gIH1cbiAgZWxzZSB7XG4gICAgcmV0dXJuIDBcbiAgfVxufVxuTWxGYWtlRGV2aWNlLnByb3RvdHlwZS5ta2RpciA9IGZ1bmN0aW9uKG5hbWUsbW9kZSwgcmFpc2VfdW5peCkge1xuICB2YXIgdW5peF9lcnJvciA9IHJhaXNlX3VuaXggJiYgY2FtbF9uYW1lZF92YWx1ZSgnVW5peC5Vbml4X2Vycm9yJyk7XG4gIGlmKHRoaXMuZXhpc3RzKG5hbWUpKSB7XG4gICAgaWYgKHVuaXhfZXJyb3IpIHtcbiAgICAgIGNhbWxfcmFpc2Vfd2l0aF9hcmdzKHVuaXhfZXJyb3IsIG1ha2VfdW5peF9lcnJfYXJncyhcIkVFWElTVFwiLCBcIm1rZGlyXCIsIHRoaXMubm0obmFtZSkpKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBjYW1sX3JhaXNlX3N5c19lcnJvcihuYW1lICsgXCI6IEZpbGUgZXhpc3RzXCIpO1xuICAgIH1cbiAgfVxuICB2YXIgcGFyZW50ID0gL14oLiopXFwvW14vXSsvLmV4ZWMobmFtZSk7XG4gIHBhcmVudCA9IChwYXJlbnQgJiYgcGFyZW50WzFdKSB8fCAnJztcbiAgaWYoIXRoaXMuZXhpc3RzKHBhcmVudCkpe1xuICAgIGlmICh1bml4X2Vycm9yKSB7XG4gICAgICBjYW1sX3JhaXNlX3dpdGhfYXJncyh1bml4X2Vycm9yLCBtYWtlX3VuaXhfZXJyX2FyZ3MoXCJFTk9FTlRcIiwgXCJta2RpclwiLCB0aGlzLm5tKHBhcmVudCkpKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBjYW1sX3JhaXNlX3N5c19lcnJvcihwYXJlbnQgKyBcIjogTm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeVwiKTtcbiAgICB9XG4gIH1cbiAgaWYoIXRoaXMuaXNfZGlyKHBhcmVudCkpe1xuICAgIGlmICh1bml4X2Vycm9yKSB7XG4gICAgICBjYW1sX3JhaXNlX3dpdGhfYXJncyh1bml4X2Vycm9yLCBtYWtlX3VuaXhfZXJyX2FyZ3MoXCJFTk9URElSXCIsIFwibWtkaXJcIiwgdGhpcy5ubShwYXJlbnQpKSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgY2FtbF9yYWlzZV9zeXNfZXJyb3IocGFyZW50ICsgXCI6IE5vdCBhIGRpcmVjdG9yeVwiKTtcbiAgICB9XG4gIH1cbiAgdGhpcy5jcmVhdGVfZGlyX2lmX25lZWRlZCh0aGlzLnNsYXNoKG5hbWUpKTtcbn1cbk1sRmFrZURldmljZS5wcm90b3R5cGUucm1kaXIgPSBmdW5jdGlvbihuYW1lLCByYWlzZV91bml4KSB7XG4gIHZhciB1bml4X2Vycm9yID0gcmFpc2VfdW5peCAmJiBjYW1sX25hbWVkX3ZhbHVlKCdVbml4LlVuaXhfZXJyb3InKTtcbiAgdmFyIG5hbWVfc2xhc2ggPSAobmFtZSA9PSBcIlwiKT9cIlwiOih0aGlzLnNsYXNoKG5hbWUpKTtcbiAgdmFyIHIgPSBuZXcgUmVnRXhwKFwiXlwiICsgbmFtZV9zbGFzaCArIFwiKFteL10rKVwiKTtcbiAgaWYoIXRoaXMuZXhpc3RzKG5hbWUpKSB7XG4gICAgaWYgKHVuaXhfZXJyb3IpIHtcbiAgICAgIGNhbWxfcmFpc2Vfd2l0aF9hcmdzKHVuaXhfZXJyb3IsIG1ha2VfdW5peF9lcnJfYXJncyhcIkVOT0VOVFwiLCBcInJtZGlyXCIsIHRoaXMubm0obmFtZSkpKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBjYW1sX3JhaXNlX3N5c19lcnJvcihuYW1lICsgXCI6IE5vIHN1Y2ggZmlsZSBvciBkaXJlY3RvcnlcIik7XG4gICAgfVxuICB9XG4gIGlmKCF0aGlzLmlzX2RpcihuYW1lKSkge1xuICAgIGlmICh1bml4X2Vycm9yKSB7XG4gICAgICBjYW1sX3JhaXNlX3dpdGhfYXJncyh1bml4X2Vycm9yLCBtYWtlX3VuaXhfZXJyX2FyZ3MoXCJFTk9URElSXCIsIFwicm1kaXJcIiwgdGhpcy5ubShuYW1lKSkpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGNhbWxfcmFpc2Vfc3lzX2Vycm9yKG5hbWUgKyBcIjogTm90IGEgZGlyZWN0b3J5XCIpO1xuICAgIH1cbiAgfVxuICBmb3IodmFyIG4gaW4gdGhpcy5jb250ZW50KSB7XG4gICAgaWYobi5tYXRjaChyKSkge1xuICAgICAgaWYgKHVuaXhfZXJyb3IpIHtcbiAgICAgICAgY2FtbF9yYWlzZV93aXRoX2FyZ3ModW5peF9lcnJvciwgbWFrZV91bml4X2Vycl9hcmdzKFwiRU5PVEVNUFRZXCIsIFwicm1kaXJcIiwgdGhpcy5ubShuYW1lKSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FtbF9yYWlzZV9zeXNfZXJyb3IodGhpcy5ubShuYW1lKSArIFwiOiBEaXJlY3Rvcnkgbm90IGVtcHR5XCIpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBkZWxldGUgdGhpcy5jb250ZW50W25hbWVfc2xhc2hdO1xufVxuTWxGYWtlRGV2aWNlLnByb3RvdHlwZS5yZWFkZGlyID0gZnVuY3Rpb24obmFtZSkge1xuICB2YXIgbmFtZV9zbGFzaCA9IChuYW1lID09IFwiXCIpP1wiXCI6KHRoaXMuc2xhc2gobmFtZSkpO1xuICBpZighdGhpcy5leGlzdHMobmFtZSkpIHtcbiAgICBjYW1sX3JhaXNlX3N5c19lcnJvcihuYW1lICsgXCI6IE5vIHN1Y2ggZmlsZSBvciBkaXJlY3RvcnlcIik7XG4gIH1cbiAgaWYoIXRoaXMuaXNfZGlyKG5hbWUpKSB7XG4gICAgY2FtbF9yYWlzZV9zeXNfZXJyb3IobmFtZSArIFwiOiBOb3QgYSBkaXJlY3RvcnlcIik7XG4gIH1cbiAgdmFyIHIgPSBuZXcgUmVnRXhwKFwiXlwiICsgbmFtZV9zbGFzaCArIFwiKFteL10rKVwiKTtcbiAgdmFyIHNlZW4gPSB7fVxuICB2YXIgYSA9IFtdO1xuICBmb3IodmFyIG4gaW4gdGhpcy5jb250ZW50KSB7XG4gICAgdmFyIG0gPSBuLm1hdGNoKHIpO1xuICAgIGlmKG0gJiYgIXNlZW5bbVsxXV0pIHtzZWVuW21bMV1dID0gdHJ1ZTsgYS5wdXNoKG1bMV0pfVxuICB9XG4gIHJldHVybiBhO1xufVxuTWxGYWtlRGV2aWNlLnByb3RvdHlwZS5vcGVuZGlyID0gZnVuY3Rpb24obmFtZSwgcmFpc2VfdW5peCkge1xuICB2YXIgdW5peF9lcnJvciA9IHJhaXNlX3VuaXggJiYgY2FtbF9uYW1lZF92YWx1ZSgnVW5peC5Vbml4X2Vycm9yJyk7XG5cbiAgdmFyIGEgPSB0aGlzLnJlYWRkaXIobmFtZSk7XG4gIHZhciBjID0gZmFsc2U7XG4gIHZhciBpID0gMDtcbiAgcmV0dXJuIHsgcmVhZFN5bmMgOiAoZnVuY3Rpb24gKCkge1xuICAgIGlmIChjKSB7XG4gICAgICBpZiAodW5peF9lcnJvcikge1xuICAgICAgICBjYW1sX3JhaXNlX3dpdGhfYXJncyh1bml4X2Vycm9yLCBtYWtlX3VuaXhfZXJyX2FyZ3MoXCJFQkFERlwiLCBcImNsb3NlZGlyXCIsIHRoaXMubm0obmFtZSkpKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBjYW1sX3JhaXNlX3N5c19lcnJvcihuYW1lICsgXCI6IGNsb3NlZGlyIGZhaWxlZFwiKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYoaSA9PSBhLmxlbmd0aCkgcmV0dXJuIG51bGw7XG4gICAgdmFyIGVudHJ5ID0gYVtpXTtcbiAgICBpKys7XG4gICAgcmV0dXJuIHsgbmFtZTogZW50cnkgfVxuICB9KVxuICAgICwgY2xvc2VTeW5jOiAoZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKGMpIHtcbiAgICAgICAgaWYgKHVuaXhfZXJyb3IpIHtcbiAgICAgICAgICBjYW1sX3JhaXNlX3dpdGhfYXJncyh1bml4X2Vycm9yLCBtYWtlX3VuaXhfZXJyX2FyZ3MoXCJFQkFERlwiLCBcImNsb3NlZGlyXCIsIHRoaXMubm0obmFtZSkpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBjYW1sX3JhaXNlX3N5c19lcnJvcihuYW1lICsgXCI6IGNsb3NlZGlyIGZhaWxlZFwiKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYyA9IHRydWU7XG4gICAgICBhID0gW107XG4gICAgfSlcbiAgfVxufVxuTWxGYWtlRGV2aWNlLnByb3RvdHlwZS5pc19kaXIgPSBmdW5jdGlvbihuYW1lKSB7XG4gIGlmKG5hbWUgPT0gXCJcIikgIHJldHVybiB0cnVlO1xuICB2YXIgbmFtZV9zbGFzaCA9IHRoaXMuc2xhc2gobmFtZSk7XG4gIHJldHVybiB0aGlzLmNvbnRlbnRbbmFtZV9zbGFzaF0/MTowO1xufVxuTWxGYWtlRGV2aWNlLnByb3RvdHlwZS51bmxpbmsgPSBmdW5jdGlvbihuYW1lKSB7XG4gIHZhciBvayA9IHRoaXMuY29udGVudFtuYW1lXT90cnVlOmZhbHNlO1xuICBkZWxldGUgdGhpcy5jb250ZW50W25hbWVdO1xuICByZXR1cm4gb2s7XG59XG5NbEZha2VEZXZpY2UucHJvdG90eXBlLm9wZW4gPSBmdW5jdGlvbihuYW1lLCBmKSB7XG4gIHZhciBmaWxlO1xuICBpZihmLnJkb25seSAmJiBmLndyb25seSlcbiAgICBjYW1sX3JhaXNlX3N5c19lcnJvcih0aGlzLm5tKG5hbWUpICsgXCIgOiBmbGFncyBPcGVuX3Jkb25seSBhbmQgT3Blbl93cm9ubHkgYXJlIG5vdCBjb21wYXRpYmxlXCIpO1xuICBpZihmLnRleHQgJiYgZi5iaW5hcnkpXG4gICAgY2FtbF9yYWlzZV9zeXNfZXJyb3IodGhpcy5ubShuYW1lKSArIFwiIDogZmxhZ3MgT3Blbl90ZXh0IGFuZCBPcGVuX2JpbmFyeSBhcmUgbm90IGNvbXBhdGlibGVcIik7XG4gIHRoaXMubG9va3VwKG5hbWUpO1xuICBpZiAodGhpcy5jb250ZW50W25hbWVdKSB7XG4gICAgaWYgKHRoaXMuaXNfZGlyKG5hbWUpKSBjYW1sX3JhaXNlX3N5c19lcnJvcih0aGlzLm5tKG5hbWUpICsgXCIgOiBpcyBhIGRpcmVjdG9yeVwiKTtcbiAgICBpZiAoZi5jcmVhdGUgJiYgZi5leGNsKSBjYW1sX3JhaXNlX3N5c19lcnJvcih0aGlzLm5tKG5hbWUpICsgXCIgOiBmaWxlIGFscmVhZHkgZXhpc3RzXCIpO1xuICAgIGZpbGUgPSB0aGlzLmNvbnRlbnRbbmFtZV07XG4gICAgaWYoZi50cnVuY2F0ZSkgZmlsZS50cnVuY2F0ZSgpO1xuICB9IGVsc2UgaWYgKGYuY3JlYXRlKSB7XG4gICAgdGhpcy5jcmVhdGVfZGlyX2lmX25lZWRlZChuYW1lKTtcbiAgICB0aGlzLmNvbnRlbnRbbmFtZV0gPSBuZXcgTWxGYWtlRmlsZShjYW1sX2NyZWF0ZV9ieXRlcygwKSk7XG4gICAgZmlsZSA9IHRoaXMuY29udGVudFtuYW1lXTtcbiAgfSBlbHNlIHtcbiAgICBjYW1sX3JhaXNlX25vX3N1Y2hfZmlsZSAodGhpcy5ubShuYW1lKSk7XG4gIH1cbiAgcmV0dXJuIG5ldyBNbEZha2VGZCh0aGlzLm5tKG5hbWUpLCBmaWxlLCBmKTtcbn1cblxuTWxGYWtlRGV2aWNlLnByb3RvdHlwZS5vcGVuID0gZnVuY3Rpb24obmFtZSwgZikge1xuICB2YXIgZmlsZTtcbiAgaWYoZi5yZG9ubHkgJiYgZi53cm9ubHkpXG4gICAgY2FtbF9yYWlzZV9zeXNfZXJyb3IodGhpcy5ubShuYW1lKSArIFwiIDogZmxhZ3MgT3Blbl9yZG9ubHkgYW5kIE9wZW5fd3Jvbmx5IGFyZSBub3QgY29tcGF0aWJsZVwiKTtcbiAgaWYoZi50ZXh0ICYmIGYuYmluYXJ5KVxuICAgIGNhbWxfcmFpc2Vfc3lzX2Vycm9yKHRoaXMubm0obmFtZSkgKyBcIiA6IGZsYWdzIE9wZW5fdGV4dCBhbmQgT3Blbl9iaW5hcnkgYXJlIG5vdCBjb21wYXRpYmxlXCIpO1xuICB0aGlzLmxvb2t1cChuYW1lKTtcbiAgaWYgKHRoaXMuY29udGVudFtuYW1lXSkge1xuICAgIGlmICh0aGlzLmlzX2RpcihuYW1lKSkgY2FtbF9yYWlzZV9zeXNfZXJyb3IodGhpcy5ubShuYW1lKSArIFwiIDogaXMgYSBkaXJlY3RvcnlcIik7XG4gICAgaWYgKGYuY3JlYXRlICYmIGYuZXhjbCkgY2FtbF9yYWlzZV9zeXNfZXJyb3IodGhpcy5ubShuYW1lKSArIFwiIDogZmlsZSBhbHJlYWR5IGV4aXN0c1wiKTtcbiAgICBmaWxlID0gdGhpcy5jb250ZW50W25hbWVdO1xuICAgIGlmKGYudHJ1bmNhdGUpIGZpbGUudHJ1bmNhdGUoKTtcbiAgfSBlbHNlIGlmIChmLmNyZWF0ZSkge1xuICAgIHRoaXMuY3JlYXRlX2Rpcl9pZl9uZWVkZWQobmFtZSk7XG4gICAgdGhpcy5jb250ZW50W25hbWVdID0gbmV3IE1sRmFrZUZpbGUoY2FtbF9jcmVhdGVfYnl0ZXMoMCkpO1xuICAgIGZpbGUgPSB0aGlzLmNvbnRlbnRbbmFtZV07XG4gIH0gZWxzZSB7XG4gICAgY2FtbF9yYWlzZV9ub19zdWNoX2ZpbGUgKHRoaXMubm0obmFtZSkpO1xuICB9XG4gIHJldHVybiBuZXcgTWxGYWtlRmQodGhpcy5ubShuYW1lKSwgZmlsZSwgZik7XG59XG5cbk1sRmFrZURldmljZS5wcm90b3R5cGUucmVnaXN0ZXI9IGZ1bmN0aW9uIChuYW1lLGNvbnRlbnQpe1xuICB2YXIgZmlsZTtcbiAgaWYodGhpcy5jb250ZW50W25hbWVdKSBjYW1sX3JhaXNlX3N5c19lcnJvcih0aGlzLm5tKG5hbWUpICsgXCIgOiBmaWxlIGFscmVhZHkgZXhpc3RzXCIpO1xuICBpZihjYW1sX2lzX21sX2J5dGVzKGNvbnRlbnQpKVxuICAgIGZpbGUgPSBuZXcgTWxGYWtlRmlsZShjb250ZW50KTtcbiAgaWYoY2FtbF9pc19tbF9zdHJpbmcoY29udGVudCkpXG4gICAgZmlsZSA9IG5ldyBNbEZha2VGaWxlKGNhbWxfYnl0ZXNfb2Zfc3RyaW5nKGNvbnRlbnQpKTtcbiAgZWxzZSBpZihjb250ZW50IGluc3RhbmNlb2YgQXJyYXkpXG4gICAgZmlsZSA9IG5ldyBNbEZha2VGaWxlKGNhbWxfYnl0ZXNfb2ZfYXJyYXkoY29udGVudCkpO1xuICBlbHNlIGlmKHR5cGVvZiBjb250ZW50ID09PSBcInN0cmluZ1wiKVxuICAgIGZpbGUgPSBuZXcgTWxGYWtlRmlsZShjYW1sX2J5dGVzX29mX2pzYnl0ZXMoY29udGVudCkpO1xuICBlbHNlIGlmKGNvbnRlbnQudG9TdHJpbmcpIHtcbiAgICB2YXIgYnl0ZXMgPSBjYW1sX2J5dGVzX29mX3N0cmluZyhjYW1sX3N0cmluZ19vZl9qc3N0cmluZyhjb250ZW50LnRvU3RyaW5nKCkpKTtcbiAgICBmaWxlID0gbmV3IE1sRmFrZUZpbGUoYnl0ZXMpO1xuICB9XG4gIGlmKGZpbGUpe1xuICAgIHRoaXMuY3JlYXRlX2Rpcl9pZl9uZWVkZWQobmFtZSk7XG4gICAgdGhpcy5jb250ZW50W25hbWVdID0gZmlsZTtcbiAgfVxuICBlbHNlIGNhbWxfcmFpc2Vfc3lzX2Vycm9yKHRoaXMubm0obmFtZSkgKyBcIiA6IHJlZ2lzdGVyaW5nIGZpbGUgd2l0aCBpbnZhbGlkIGNvbnRlbnQgdHlwZVwiKTtcbn1cblxuTWxGYWtlRGV2aWNlLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IE1sRmFrZURldmljZVxuXG4vL1Byb3ZpZGVzOiBNbEZha2VGaWxlXG4vL1JlcXVpcmVzOiBNbEZpbGVcbi8vUmVxdWlyZXM6IGNhbWxfY3JlYXRlX2J5dGVzLCBjYW1sX21sX2J5dGVzX2xlbmd0aCwgY2FtbF9ibGl0X2J5dGVzXG4vL1JlcXVpcmVzOiBjYW1sX3VpbnQ4X2FycmF5X29mX2J5dGVzLCBjYW1sX2J5dGVzX29mX2FycmF5XG5mdW5jdGlvbiBNbEZha2VGaWxlKGNvbnRlbnQpe1xuICB0aGlzLmRhdGEgPSBjb250ZW50O1xufVxuTWxGYWtlRmlsZS5wcm90b3R5cGUgPSBuZXcgTWxGaWxlICgpO1xuTWxGYWtlRmlsZS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBNbEZha2VGaWxlXG5NbEZha2VGaWxlLnByb3RvdHlwZS50cnVuY2F0ZSA9IGZ1bmN0aW9uKGxlbil7XG4gIHZhciBvbGQgPSB0aGlzLmRhdGE7XG4gIHRoaXMuZGF0YSA9IGNhbWxfY3JlYXRlX2J5dGVzKGxlbnwwKTtcbiAgY2FtbF9ibGl0X2J5dGVzKG9sZCwgMCwgdGhpcy5kYXRhLCAwLCBsZW4pO1xufVxuTWxGYWtlRmlsZS5wcm90b3R5cGUubGVuZ3RoID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gY2FtbF9tbF9ieXRlc19sZW5ndGgodGhpcy5kYXRhKTtcbn1cbk1sRmFrZUZpbGUucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24ob2Zmc2V0LGJ1Zixwb3MsbGVuKXtcbiAgdmFyIGNsZW4gPSB0aGlzLmxlbmd0aCgpO1xuICBpZihvZmZzZXQgKyBsZW4gPj0gY2xlbikge1xuICAgIHZhciBuZXdfc3RyID0gY2FtbF9jcmVhdGVfYnl0ZXMob2Zmc2V0ICsgbGVuKTtcbiAgICB2YXIgb2xkX2RhdGEgPSB0aGlzLmRhdGE7XG4gICAgdGhpcy5kYXRhID0gbmV3X3N0cjtcbiAgICBjYW1sX2JsaXRfYnl0ZXMob2xkX2RhdGEsIDAsIHRoaXMuZGF0YSwgMCwgY2xlbik7XG4gIH1cbiAgY2FtbF9ibGl0X2J5dGVzKGNhbWxfYnl0ZXNfb2ZfYXJyYXkoYnVmKSwgcG9zLCB0aGlzLmRhdGEsIG9mZnNldCwgbGVuKTtcbiAgcmV0dXJuIDBcbn1cbk1sRmFrZUZpbGUucHJvdG90eXBlLnJlYWQgPSBmdW5jdGlvbihvZmZzZXQsYnVmLHBvcyxsZW4pe1xuICB2YXIgY2xlbiA9IHRoaXMubGVuZ3RoKCk7XG4gIGlmKG9mZnNldCArIGxlbiA+PSBjbGVuKSB7XG4gICAgbGVuID0gY2xlbiAtIG9mZnNldDtcbiAgfVxuICBpZihsZW4pIHtcbiAgICB2YXIgZGF0YSA9IGNhbWxfY3JlYXRlX2J5dGVzKGxlbnwwKTtcbiAgICBjYW1sX2JsaXRfYnl0ZXModGhpcy5kYXRhLCBvZmZzZXQsIGRhdGEsIDAsIGxlbik7XG4gICAgYnVmLnNldChjYW1sX3VpbnQ4X2FycmF5X29mX2J5dGVzKGRhdGEpLCBwb3MpO1xuICB9XG4gIHJldHVybiBsZW5cbn1cblxuXG4vL1Byb3ZpZGVzOiBNbEZha2VGZF9vdXRcbi8vUmVxdWlyZXM6IE1sRmFrZUZpbGUsIGNhbWxfY3JlYXRlX2J5dGVzLCBjYW1sX2JsaXRfYnl0ZXMsIGNhbWxfYnl0ZXNfb2ZfYXJyYXlcbi8vUmVxdWlyZXM6IGNhbWxfcmFpc2Vfc3lzX2Vycm9yXG5mdW5jdGlvbiBNbEZha2VGZF9vdXQoZmQsZmxhZ3MpIHtcbiAgTWxGYWtlRmlsZS5jYWxsKHRoaXMsIGNhbWxfY3JlYXRlX2J5dGVzKDApKTtcbiAgdGhpcy5sb2cgPSAoZnVuY3Rpb24gKHMpIHsgcmV0dXJuIDAgfSk7XG4gIGlmKGZkID09IDEgJiYgdHlwZW9mIGNvbnNvbGUubG9nID09IFwiZnVuY3Rpb25cIilcbiAgICB0aGlzLmxvZyA9IGNvbnNvbGUubG9nO1xuICBlbHNlIGlmKGZkID09IDIgJiYgdHlwZW9mIGNvbnNvbGUuZXJyb3IgPT0gXCJmdW5jdGlvblwiKVxuICAgIHRoaXMubG9nID0gY29uc29sZS5lcnJvcjtcbiAgZWxzZSBpZih0eXBlb2YgY29uc29sZS5sb2cgPT0gXCJmdW5jdGlvblwiKVxuICAgIHRoaXMubG9nID0gY29uc29sZS5sb2dcbiAgdGhpcy5mbGFncyA9IGZsYWdzO1xufVxuTWxGYWtlRmRfb3V0LnByb3RvdHlwZS5sZW5ndGggPSBmdW5jdGlvbigpIHsgcmV0dXJuIDAgfVxuTWxGYWtlRmRfb3V0LnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIChvZmZzZXQsYnVmLHBvcyxsZW4pIHtcbiAgaWYodGhpcy5sb2cpIHtcbiAgICBpZihsZW4gPiAwXG4gICAgICAgJiYgcG9zID49IDBcbiAgICAgICAmJiBwb3MrbGVuIDw9IGJ1Zi5sZW5ndGhcbiAgICAgICAmJiBidWZbcG9zK2xlbi0xXSA9PSAxMClcbiAgICAgIGxlbiAtLTtcbiAgICAvLyBEbyBub3Qgb3V0cHV0IHRoZSBsYXN0IFxcbiBpZiBwcmVzZW50XG4gICAgLy8gYXMgY29uc29sZSBsb2dnaW5nIGRpc3BsYXkgYSBuZXdsaW5lIGF0IHRoZSBlbmRcbiAgICB2YXIgc3JjID0gY2FtbF9jcmVhdGVfYnl0ZXMobGVuKTtcbiAgICBjYW1sX2JsaXRfYnl0ZXMoY2FtbF9ieXRlc19vZl9hcnJheShidWYpLCBwb3MsIHNyYywgMCwgbGVuKTtcbiAgICB0aGlzLmxvZyhzcmMudG9VdGYxNigpKTtcbiAgICByZXR1cm4gMDtcbiAgfVxuICBjYW1sX3JhaXNlX3N5c19lcnJvcih0aGlzLmZkICArIFwiOiBmaWxlIGRlc2NyaXB0b3IgYWxyZWFkeSBjbG9zZWRcIik7XG59XG5NbEZha2VGZF9vdXQucHJvdG90eXBlLnJlYWQgPSBmdW5jdGlvbiAob2Zmc2V0LCBidWYsIHBvcywgbGVuKSB7XG4gIGNhbWxfcmFpc2Vfc3lzX2Vycm9yKHRoaXMuZmQgICsgXCI6IGZpbGUgZGVzY3JpcHRvciBpcyB3cml0ZSBvbmx5XCIpO1xufVxuTWxGYWtlRmRfb3V0LnByb3RvdHlwZS5jbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5sb2cgPSB1bmRlZmluZWQ7XG59XG5cblxuLy9Qcm92aWRlczogTWxGYWtlRmRcbi8vUmVxdWlyZXM6IE1sRmFrZUZpbGVcbi8vUmVxdWlyZXM6IGNhbWxfcmFpc2Vfc3lzX2Vycm9yXG5mdW5jdGlvbiBNbEZha2VGZChuYW1lLCBmaWxlLGZsYWdzKSB7XG4gIHRoaXMuZmlsZSA9IGZpbGU7XG4gIHRoaXMubmFtZSA9IG5hbWU7XG4gIHRoaXMuZmxhZ3MgPSBmbGFncztcbn1cblxuTWxGYWtlRmQucHJvdG90eXBlLmVycl9jbG9zZWQgPSBmdW5jdGlvbiAoKSB7XG4gIGNhbWxfcmFpc2Vfc3lzX2Vycm9yKHRoaXMubmFtZSAgKyBcIjogZmlsZSBkZXNjcmlwdG9yIGFscmVhZHkgY2xvc2VkXCIpO1xufVxuTWxGYWtlRmQucHJvdG90eXBlLmxlbmd0aCA9IGZ1bmN0aW9uKCkge1xuICBpZih0aGlzLmZpbGUpIHJldHVybiB0aGlzLmZpbGUubGVuZ3RoICgpXG4gIHRoaXMuZXJyX2Nsb3NlZCgpO1xufVxuTWxGYWtlRmQucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gKG9mZnNldCxidWYscG9zLGxlbikge1xuICBpZih0aGlzLmZpbGUpIHJldHVybiB0aGlzLmZpbGUud3JpdGUob2Zmc2V0LGJ1Zixwb3MsbGVuKVxuICB0aGlzLmVycl9jbG9zZWQoKTtcbn1cbk1sRmFrZUZkLnByb3RvdHlwZS5yZWFkID0gZnVuY3Rpb24gKG9mZnNldCwgYnVmLCBwb3MsIGxlbikge1xuICBpZih0aGlzLmZpbGUpIHJldHVybiB0aGlzLmZpbGUucmVhZChvZmZzZXQsIGJ1ZiwgcG9zLCBsZW4pXG4gIHRoaXMuZXJyX2Nsb3NlZCgpO1xufVxuTWxGYWtlRmQucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmZpbGUgPSB1bmRlZmluZWQ7XG59XG4iLCIvLyBKc19vZl9vY2FtbCBydW50aW1lIHN1cHBvcnRcbi8vIGh0dHA6Ly93d3cub2NzaWdlbi5vcmcvanNfb2Zfb2NhbWwvXG4vLyBDb3B5cmlnaHQgKEMpIDIwMTAgSsOpcsO0bWUgVm91aWxsb25cbi8vIExhYm9yYXRvaXJlIFBQUyAtIENOUlMgVW5pdmVyc2l0w6kgUGFyaXMgRGlkZXJvdFxuLy9cbi8vIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4vLyBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbi8vIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHdpdGggbGlua2luZyBleGNlcHRpb247XG4vLyBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vL1xuLy8gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuLy8gR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vL1xuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4vLyBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcsIFVTQS5cblxuLy9Qcm92aWRlczogY2FtbF9pbnQ2NF9vZmZzZXRcbnZhciBjYW1sX2ludDY0X29mZnNldCA9IE1hdGgucG93KDIsIC0yNCk7XG5cbi8vUHJvdmlkZXM6IE1sSW50NjRcbi8vUmVxdWlyZXM6IGNhbWxfaW50NjRfb2Zmc2V0LCBjYW1sX3JhaXNlX3plcm9fZGl2aWRlXG5mdW5jdGlvbiBNbEludDY0IChsbyxtaSxoaSkge1xuICB0aGlzLmxvID0gbG8gJiAweGZmZmZmZjtcbiAgdGhpcy5taSA9IG1pICYgMHhmZmZmZmY7XG4gIHRoaXMuaGkgPSBoaSAmIDB4ZmZmZjtcbn1cbk1sSW50NjQucHJvdG90eXBlLmNhbWxfY3VzdG9tID0gXCJfalwiXG5NbEludDY0LnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gbmV3IE1sSW50NjQodGhpcy5sbyx0aGlzLm1pLHRoaXMuaGkpO1xufVxuXG5NbEludDY0LnByb3RvdHlwZS51Y29tcGFyZSA9IGZ1bmN0aW9uICh4KSB7XG4gIGlmICh0aGlzLmhpID4geC5oaSkgcmV0dXJuIDE7XG4gIGlmICh0aGlzLmhpIDwgeC5oaSkgcmV0dXJuIC0xO1xuICBpZiAodGhpcy5taSA+IHgubWkpIHJldHVybiAxO1xuICBpZiAodGhpcy5taSA8IHgubWkpIHJldHVybiAtMTtcbiAgaWYgKHRoaXMubG8gPiB4LmxvKSByZXR1cm4gMTtcbiAgaWYgKHRoaXMubG8gPCB4LmxvKSByZXR1cm4gLTE7XG4gIHJldHVybiAwO1xufVxuTWxJbnQ2NC5wcm90b3R5cGUuY29tcGFyZSA9IGZ1bmN0aW9uICh4KSB7XG4gIHZhciBoaSA9IHRoaXMuaGkgPDwgMTY7XG4gIHZhciB4aGkgPSB4LmhpIDw8IDE2O1xuICBpZiAoaGkgPiB4aGkpIHJldHVybiAxO1xuICBpZiAoaGkgPCB4aGkpIHJldHVybiAtMTtcbiAgaWYgKHRoaXMubWkgPiB4Lm1pKSByZXR1cm4gMTtcbiAgaWYgKHRoaXMubWkgPCB4Lm1pKSByZXR1cm4gLTE7XG4gIGlmICh0aGlzLmxvID4geC5sbykgcmV0dXJuIDE7XG4gIGlmICh0aGlzLmxvIDwgeC5sbykgcmV0dXJuIC0xO1xuICByZXR1cm4gMDtcbn1cbk1sSW50NjQucHJvdG90eXBlLm5lZyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGxvID0gLSB0aGlzLmxvO1xuICB2YXIgbWkgPSAtIHRoaXMubWkgKyAobG8gPj4gMjQpO1xuICB2YXIgaGkgPSAtIHRoaXMuaGkgKyAobWkgPj4gMjQpO1xuICByZXR1cm4gbmV3IE1sSW50NjQobG8sIG1pLCBoaSk7XG59XG5NbEludDY0LnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiAoeCkge1xuICB2YXIgbG8gPSB0aGlzLmxvICsgeC5sbztcbiAgdmFyIG1pID0gdGhpcy5taSArIHgubWkgKyAobG8gPj4gMjQpO1xuICB2YXIgaGkgPSB0aGlzLmhpICsgeC5oaSArIChtaSA+PiAyNCk7XG4gIHJldHVybiBuZXcgTWxJbnQ2NChsbywgbWksIGhpKTtcbn1cbk1sSW50NjQucHJvdG90eXBlLnN1YiA9IGZ1bmN0aW9uICh4KSB7XG4gIHZhciBsbyA9IHRoaXMubG8gLSB4LmxvO1xuICB2YXIgbWkgPSB0aGlzLm1pIC0geC5taSArIChsbyA+PiAyNCk7XG4gIHZhciBoaSA9IHRoaXMuaGkgLSB4LmhpICsgKG1pID4+IDI0KTtcbiAgcmV0dXJuIG5ldyBNbEludDY0KGxvLCBtaSwgaGkpO1xufVxuTWxJbnQ2NC5wcm90b3R5cGUubXVsID0gZnVuY3Rpb24gKHgpIHtcbiAgdmFyIGxvID0gdGhpcy5sbyAqIHgubG87XG4gIHZhciBtaSA9ICgobG8gKiBjYW1sX2ludDY0X29mZnNldCkgfCAwKSArIHRoaXMubWkgKiB4LmxvICsgdGhpcy5sbyAqIHgubWk7XG4gIHZhciBoaSA9ICgobWkgKiBjYW1sX2ludDY0X29mZnNldCkgfCAwKSArIHRoaXMuaGkgKiB4LmxvICsgdGhpcy5taSAqIHgubWkgKyB0aGlzLmxvICogeC5oaTtcbiAgcmV0dXJuIG5ldyBNbEludDY0KGxvLCBtaSwgaGkpO1xufVxuTWxJbnQ2NC5wcm90b3R5cGUuaXNaZXJvID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gKHRoaXMubG98dGhpcy5taXx0aGlzLmhpKSA9PSAwO1xufVxuTWxJbnQ2NC5wcm90b3R5cGUuaXNOZWcgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAodGhpcy5oaSA8PCAxNikgPCAwO1xufVxuTWxJbnQ2NC5wcm90b3R5cGUuYW5kID0gZnVuY3Rpb24gKHgpIHtcbiAgcmV0dXJuIG5ldyBNbEludDY0KHRoaXMubG8gJiB4LmxvLCB0aGlzLm1pICYgeC5taSwgdGhpcy5oaSAmIHguaGkpO1xufVxuTWxJbnQ2NC5wcm90b3R5cGUub3IgPSBmdW5jdGlvbiAoeCkge1xuICByZXR1cm4gbmV3IE1sSW50NjQodGhpcy5sb3x4LmxvLCB0aGlzLm1pfHgubWksIHRoaXMuaGl8eC5oaSk7XG59XG5NbEludDY0LnByb3RvdHlwZS54b3IgPSBmdW5jdGlvbiAoeCkge1xuICByZXR1cm4gbmV3IE1sSW50NjQodGhpcy5sb154LmxvLCB0aGlzLm1pXngubWksIHRoaXMuaGleeC5oaSk7XG59XG5NbEludDY0LnByb3RvdHlwZS5zaGlmdF9sZWZ0ID0gZnVuY3Rpb24gKHMpIHtcbiAgcyA9IHMgJiA2MztcbiAgaWYgKHMgPT0gMCkgcmV0dXJuIHRoaXM7XG4gIGlmIChzIDwgMjQpIHtcbiAgICByZXR1cm4gbmV3IE1sSW50NjQgKHRoaXMubG8gPDwgcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICh0aGlzLm1pIDw8IHMpIHwgKHRoaXMubG8gPj4gKDI0IC0gcykpLFxuICAgICAgICAgICAgICAgICAgICAgICAgKHRoaXMuaGkgPDwgcykgfCAodGhpcy5taSA+PiAoMjQgLSBzKSkpO1xuICB9XG4gIGlmIChzIDwgNDgpXG4gICAgcmV0dXJuIG5ldyBNbEludDY0ICgwLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sbyA8PCAocyAtIDI0KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICh0aGlzLm1pIDw8IChzIC0gMjQpKSB8ICh0aGlzLmxvID4+ICg0OCAtIHMpKSk7XG4gIHJldHVybiBuZXcgTWxJbnQ2NCgwLCAwLCB0aGlzLmxvIDw8IChzIC0gNDgpKVxufVxuTWxJbnQ2NC5wcm90b3R5cGUuc2hpZnRfcmlnaHRfdW5zaWduZWQgPSBmdW5jdGlvbiAocykge1xuICBzID0gcyAmIDYzO1xuICBpZiAocyA9PSAwKSByZXR1cm4gdGhpcztcbiAgaWYgKHMgPCAyNClcbiAgICByZXR1cm4gbmV3IE1sSW50NjQgKFxuICAgICAgKHRoaXMubG8gPj4gcykgfCAodGhpcy5taSA8PCAoMjQgLSBzKSksXG4gICAgICAodGhpcy5taSA+PiBzKSB8ICh0aGlzLmhpIDw8ICgyNCAtIHMpKSxcbiAgICAgICh0aGlzLmhpID4+IHMpKTtcbiAgaWYgKHMgPCA0OClcbiAgICByZXR1cm4gbmV3IE1sSW50NjQgKFxuICAgICAgKHRoaXMubWkgPj4gKHMgLSAyNCkpIHwgKHRoaXMuaGkgPDwgKDQ4IC0gcykpLFxuICAgICAgKHRoaXMuaGkgPj4gKHMgLSAyNCkpLFxuICAgICAgMCk7XG4gIHJldHVybiBuZXcgTWxJbnQ2NCAodGhpcy5oaSA+PiAocyAtIDQ4KSwgMCwgMCk7XG59XG5NbEludDY0LnByb3RvdHlwZS5zaGlmdF9yaWdodCA9IGZ1bmN0aW9uIChzKSB7XG4gIHMgPSBzICYgNjM7XG4gIGlmIChzID09IDApIHJldHVybiB0aGlzO1xuICB2YXIgaCA9ICh0aGlzLmhpIDw8IDE2KSA+PiAxNjtcbiAgaWYgKHMgPCAyNClcbiAgICByZXR1cm4gbmV3IE1sSW50NjQgKFxuICAgICAgKHRoaXMubG8gPj4gcykgfCAodGhpcy5taSA8PCAoMjQgLSBzKSksXG4gICAgICAodGhpcy5taSA+PiBzKSB8IChoIDw8ICgyNCAtIHMpKSxcbiAgICAgICgodGhpcy5oaSA8PCAxNikgPj4gcykgPj4+IDE2KTtcbiAgdmFyIHNpZ24gPSAodGhpcy5oaSA8PCAxNikgPj4gMzE7XG4gIGlmIChzIDwgNDgpXG4gICAgcmV0dXJuIG5ldyBNbEludDY0IChcbiAgICAgICh0aGlzLm1pID4+IChzIC0gMjQpKSB8ICh0aGlzLmhpIDw8ICg0OCAtIHMpKSxcbiAgICAgICh0aGlzLmhpIDw8IDE2KSA+PiAocyAtIDI0KSA+PiAxNixcbiAgICAgIHNpZ24gJiAweGZmZmYpO1xuICByZXR1cm4gbmV3IE1sSW50NjQgKCh0aGlzLmhpIDw8IDE2KSA+PiAocyAtIDMyKSwgc2lnbiwgc2lnbik7XG59XG5NbEludDY0LnByb3RvdHlwZS5sc2wxID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmhpID0gKHRoaXMuaGkgPDwgMSkgfCAodGhpcy5taSA+PiAyMyk7XG4gIHRoaXMubWkgPSAoKHRoaXMubWkgPDwgMSkgfCAodGhpcy5sbyA+PiAyMykpICYgMHhmZmZmZmY7XG4gIHRoaXMubG8gPSAodGhpcy5sbyA8PCAxKSAmIDB4ZmZmZmZmO1xufVxuTWxJbnQ2NC5wcm90b3R5cGUubHNyMSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5sbyA9ICgodGhpcy5sbyA+Pj4gMSkgfCAodGhpcy5taSA8PCAyMykpICYgMHhmZmZmZmY7XG4gIHRoaXMubWkgPSAoKHRoaXMubWkgPj4+IDEpIHwgKHRoaXMuaGkgPDwgMjMpKSAmIDB4ZmZmZmZmO1xuICB0aGlzLmhpID0gdGhpcy5oaSA+Pj4gMTtcbn1cbk1sSW50NjQucHJvdG90eXBlLnVkaXZtb2QgPSBmdW5jdGlvbiAoeCkge1xuICB2YXIgb2Zmc2V0ID0gMDtcbiAgdmFyIG1vZHVsdXMgPSB0aGlzLmNvcHkoKTtcbiAgdmFyIGRpdmlzb3IgPSB4LmNvcHkoKTtcbiAgdmFyIHF1b3RpZW50ID0gbmV3IE1sSW50NjQoMCwwLDApO1xuICB3aGlsZSAobW9kdWx1cy51Y29tcGFyZShkaXZpc29yKSA+IDApIHtcbiAgICBvZmZzZXQrKztcbiAgICBkaXZpc29yLmxzbDEoKTtcbiAgfVxuICB3aGlsZSAob2Zmc2V0ID49IDApIHtcbiAgICBvZmZzZXQgLS07XG4gICAgcXVvdGllbnQubHNsMSgpO1xuICAgIGlmIChtb2R1bHVzLnVjb21wYXJlKGRpdmlzb3IpID49IDApIHtcbiAgICAgIHF1b3RpZW50LmxvICsrO1xuICAgICAgbW9kdWx1cyA9IG1vZHVsdXMuc3ViKGRpdmlzb3IpO1xuICAgIH1cbiAgICBkaXZpc29yLmxzcjEoKTtcbiAgfVxuICByZXR1cm4geyBxdW90aWVudCA6IHF1b3RpZW50LCBtb2R1bHVzIDogbW9kdWx1cyB9O1xufVxuTWxJbnQ2NC5wcm90b3R5cGUuZGl2ID0gZnVuY3Rpb24gKHkpXG57XG4gIHZhciB4ID0gdGhpcztcbiAgaWYgKHkuaXNaZXJvKCkpIGNhbWxfcmFpc2VfemVyb19kaXZpZGUgKCk7XG4gIHZhciBzaWduID0geC5oaSBeIHkuaGk7XG4gIGlmICh4LmhpICYgMHg4MDAwKSB4ID0geC5uZWcoKTtcbiAgaWYgKHkuaGkgJiAweDgwMDApIHkgPSB5Lm5lZygpO1xuICB2YXIgcSA9IHgudWRpdm1vZCh5KS5xdW90aWVudDtcbiAgaWYgKHNpZ24gJiAweDgwMDApIHEgPSBxLm5lZygpO1xuICByZXR1cm4gcTtcbn1cbk1sSW50NjQucHJvdG90eXBlLm1vZCA9IGZ1bmN0aW9uICh5KVxue1xuICB2YXIgeCA9IHRoaXM7XG4gIGlmICh5LmlzWmVybygpKSBjYW1sX3JhaXNlX3plcm9fZGl2aWRlICgpO1xuICB2YXIgc2lnbiA9IHguaGk7XG4gIGlmICh4LmhpICYgMHg4MDAwKSB4ID0geC5uZWcoKTtcbiAgaWYgKHkuaGkgJiAweDgwMDApIHkgPSB5Lm5lZygpO1xuICB2YXIgciA9IHgudWRpdm1vZCh5KS5tb2R1bHVzO1xuICBpZiAoc2lnbiAmIDB4ODAwMCkgciA9IHIubmVnKCk7XG4gIHJldHVybiByO1xufVxuTWxJbnQ2NC5wcm90b3R5cGUudG9JbnQgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLmxvIHwgKHRoaXMubWkgPDwgMjQpO1xufVxuTWxJbnQ2NC5wcm90b3R5cGUudG9GbG9hdCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuICgodGhpcy5oaSA8PCAxNikgKiBNYXRoLnBvdygyLCAzMikgKyB0aGlzLm1pICogTWF0aC5wb3coMiwgMjQpKSArIHRoaXMubG87XG59XG5NbEludDY0LnByb3RvdHlwZS50b0FycmF5ID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gW3RoaXMuaGkgPj4gOCxcbiAgICAgICAgICB0aGlzLmhpICYgMHhmZixcbiAgICAgICAgICB0aGlzLm1pID4+IDE2LFxuICAgICAgICAgICh0aGlzLm1pID4+IDgpICYgMHhmZixcbiAgICAgICAgICB0aGlzLm1pICYgMHhmZixcbiAgICAgICAgICB0aGlzLmxvID4+IDE2LFxuICAgICAgICAgICh0aGlzLmxvID4+IDgpICYgMHhmZixcbiAgICAgICAgICB0aGlzLmxvICYgMHhmZl07XG59XG5NbEludDY0LnByb3RvdHlwZS5sbzMyID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5sbyB8ICgodGhpcy5taSAmIDB4ZmYpIDw8IDI0KTtcbn1cbk1sSW50NjQucHJvdG90eXBlLmhpMzIgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAoKHRoaXMubWkgPj4+IDgpICYgMHhmZmZmKSB8ICh0aGlzLmhpIDw8IDE2KTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9pbnQ2NF91bHQgY29uc3RcbmZ1bmN0aW9uIGNhbWxfaW50NjRfdWx0KHgseSkgeyByZXR1cm4geC51Y29tcGFyZSh5KSA8IDA7IH1cblxuLy9Qcm92aWRlczogY2FtbF9pbnQ2NF9jb21wYXJlIGNvbnN0XG5mdW5jdGlvbiBjYW1sX2ludDY0X2NvbXBhcmUoeCx5LCB0b3RhbCkgeyByZXR1cm4geC5jb21wYXJlKHkpIH1cblxuLy9Qcm92aWRlczogY2FtbF9pbnQ2NF9uZWcgY29uc3RcbmZ1bmN0aW9uIGNhbWxfaW50NjRfbmVnICh4KSB7IHJldHVybiB4Lm5lZygpIH1cblxuLy9Qcm92aWRlczogY2FtbF9pbnQ2NF9hZGQgY29uc3RcbmZ1bmN0aW9uIGNhbWxfaW50NjRfYWRkICh4LCB5KSB7IHJldHVybiB4LmFkZCh5KSB9XG5cbi8vUHJvdmlkZXM6IGNhbWxfaW50NjRfc3ViIGNvbnN0XG5mdW5jdGlvbiBjYW1sX2ludDY0X3N1YiAoeCwgeSkgeyByZXR1cm4geC5zdWIoeSkgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2ludDY0X211bCBjb25zdFxuLy9SZXF1aXJlczogY2FtbF9pbnQ2NF9vZmZzZXRcbmZ1bmN0aW9uIGNhbWxfaW50NjRfbXVsKHgseSkgeyByZXR1cm4geC5tdWwoeSkgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2ludDY0X2lzX3plcm8gY29uc3RcbmZ1bmN0aW9uIGNhbWxfaW50NjRfaXNfemVybyh4KSB7IHJldHVybiAreC5pc1plcm8oKTsgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2ludDY0X2lzX25lZ2F0aXZlIGNvbnN0XG5mdW5jdGlvbiBjYW1sX2ludDY0X2lzX25lZ2F0aXZlKHgpIHsgcmV0dXJuICt4LmlzTmVnKCk7IH1cblxuLy9Qcm92aWRlczogY2FtbF9pbnQ2NF9hbmQgY29uc3RcbmZ1bmN0aW9uIGNhbWxfaW50NjRfYW5kICh4LCB5KSB7IHJldHVybiB4LmFuZCh5KTsgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2ludDY0X29yIGNvbnN0XG5mdW5jdGlvbiBjYW1sX2ludDY0X29yICh4LCB5KSB7IHJldHVybiB4Lm9yKHkpOyB9XG5cbi8vUHJvdmlkZXM6IGNhbWxfaW50NjRfeG9yIGNvbnN0XG5mdW5jdGlvbiBjYW1sX2ludDY0X3hvciAoeCwgeSkgeyByZXR1cm4geC54b3IoeSkgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2ludDY0X3NoaWZ0X2xlZnQgY29uc3RcbmZ1bmN0aW9uIGNhbWxfaW50NjRfc2hpZnRfbGVmdCAoeCwgcykgeyByZXR1cm4geC5zaGlmdF9sZWZ0KHMpIH1cblxuLy9Qcm92aWRlczogY2FtbF9pbnQ2NF9zaGlmdF9yaWdodF91bnNpZ25lZCBjb25zdFxuZnVuY3Rpb24gY2FtbF9pbnQ2NF9zaGlmdF9yaWdodF91bnNpZ25lZCAoeCwgcykgeyByZXR1cm4geC5zaGlmdF9yaWdodF91bnNpZ25lZChzKSB9XG5cbi8vUHJvdmlkZXM6IGNhbWxfaW50NjRfc2hpZnRfcmlnaHQgY29uc3RcbmZ1bmN0aW9uIGNhbWxfaW50NjRfc2hpZnRfcmlnaHQgKHgsIHMpIHsgcmV0dXJuIHguc2hpZnRfcmlnaHQocykgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2ludDY0X2RpdiBjb25zdFxuZnVuY3Rpb24gY2FtbF9pbnQ2NF9kaXYgKHgsIHkpIHsgcmV0dXJuIHguZGl2KHkpIH1cblxuLy9Qcm92aWRlczogY2FtbF9pbnQ2NF9tb2QgY29uc3RcbmZ1bmN0aW9uIGNhbWxfaW50NjRfbW9kICh4LCB5KSB7IHJldHVybiB4Lm1vZCh5KSB9XG5cbi8vUHJvdmlkZXM6IGNhbWxfaW50NjRfb2ZfaW50MzIgY29uc3Rcbi8vUmVxdWlyZXM6IE1sSW50NjRcbmZ1bmN0aW9uIGNhbWxfaW50NjRfb2ZfaW50MzIgKHgpIHtcbiAgcmV0dXJuIG5ldyBNbEludDY0KHggJiAweGZmZmZmZiwgKHggPj4gMjQpICYgMHhmZmZmZmYsICh4ID4+IDMxKSAmIDB4ZmZmZilcbn1cblxuLy9Qcm92aWRlczogY2FtbF9pbnQ2NF90b19pbnQzMiBjb25zdFxuZnVuY3Rpb24gY2FtbF9pbnQ2NF90b19pbnQzMiAoeCkgeyByZXR1cm4geC50b0ludCgpIH1cblxuLy9Qcm92aWRlczogY2FtbF9pbnQ2NF90b19mbG9hdCBjb25zdFxuZnVuY3Rpb24gY2FtbF9pbnQ2NF90b19mbG9hdCAoeCkgeyByZXR1cm4geC50b0Zsb2F0ICgpIH1cblxuLy9Qcm92aWRlczogY2FtbF9pbnQ2NF9vZl9mbG9hdCBjb25zdFxuLy9SZXF1aXJlczogY2FtbF9pbnQ2NF9vZmZzZXQsIE1sSW50NjRcbmZ1bmN0aW9uIGNhbWxfaW50NjRfb2ZfZmxvYXQgKHgpIHtcbiAgaWYgKHggPCAwKSB4ID0gTWF0aC5jZWlsKHgpO1xuICByZXR1cm4gbmV3IE1sSW50NjQoXG4gICAgeCAmIDB4ZmZmZmZmLFxuICAgIE1hdGguZmxvb3IoeCAqIGNhbWxfaW50NjRfb2Zmc2V0KSAmIDB4ZmZmZmZmLFxuICAgIE1hdGguZmxvb3IoeCAqIGNhbWxfaW50NjRfb2Zmc2V0ICogY2FtbF9pbnQ2NF9vZmZzZXQpICYgMHhmZmZmKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9pbnQ2NF9mb3JtYXQgY29uc3Rcbi8vUmVxdWlyZXM6IGNhbWxfcGFyc2VfZm9ybWF0LCBjYW1sX2ZpbmlzaF9mb3JtYXR0aW5nXG4vL1JlcXVpcmVzOiBjYW1sX2ludDY0X2lzX25lZ2F0aXZlLCBjYW1sX2ludDY0X25lZ1xuLy9SZXF1aXJlczogY2FtbF9pbnQ2NF9vZl9pbnQzMiwgY2FtbF9pbnQ2NF90b19pbnQzMlxuLy9SZXF1aXJlczogY2FtbF9pbnQ2NF9pc196ZXJvLCBjYW1sX3N0cl9yZXBlYXRcbmZ1bmN0aW9uIGNhbWxfaW50NjRfZm9ybWF0IChmbXQsIHgpIHtcbiAgdmFyIGYgPSBjYW1sX3BhcnNlX2Zvcm1hdChmbXQpO1xuICBpZiAoZi5zaWduZWRjb252ICYmIGNhbWxfaW50NjRfaXNfbmVnYXRpdmUoeCkpIHtcbiAgICBmLnNpZ24gPSAtMTsgeCA9IGNhbWxfaW50NjRfbmVnKHgpO1xuICB9XG4gIHZhciBidWZmZXIgPSBcIlwiO1xuICB2YXIgd2Jhc2UgPSBjYW1sX2ludDY0X29mX2ludDMyKGYuYmFzZSk7XG4gIHZhciBjdnRibCA9IFwiMDEyMzQ1Njc4OWFiY2RlZlwiO1xuICBkbyB7XG4gICAgdmFyIHAgPSB4LnVkaXZtb2Qod2Jhc2UpO1xuICAgIHggPSBwLnF1b3RpZW50O1xuICAgIGJ1ZmZlciA9IGN2dGJsLmNoYXJBdChjYW1sX2ludDY0X3RvX2ludDMyKHAubW9kdWx1cykpICsgYnVmZmVyO1xuICB9IHdoaWxlICghIGNhbWxfaW50NjRfaXNfemVybyh4KSk7XG4gIGlmIChmLnByZWMgPj0gMCkge1xuICAgIGYuZmlsbGVyID0gJyAnO1xuICAgIHZhciBuID0gZi5wcmVjIC0gYnVmZmVyLmxlbmd0aDtcbiAgICBpZiAobiA+IDApIGJ1ZmZlciA9IGNhbWxfc3RyX3JlcGVhdCAobiwgJzAnKSArIGJ1ZmZlcjtcbiAgfVxuICByZXR1cm4gY2FtbF9maW5pc2hfZm9ybWF0dGluZyhmLCBidWZmZXIpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2ludDY0X29mX3N0cmluZ1xuLy9SZXF1aXJlczogY2FtbF9wYXJzZV9zaWduX2FuZF9iYXNlLCBjYW1sX2ZhaWx3aXRoLCBjYW1sX3BhcnNlX2RpZ2l0XG4vL1JlcXVpcmVzOiBjYW1sX2ludDY0X29mX2ludDMyLCBjYW1sX2ludDY0X3VsdFxuLy9SZXF1aXJlczogY2FtbF9pbnQ2NF9hZGQsIGNhbWxfaW50NjRfbXVsLCBjYW1sX2ludDY0X25lZ1xuLy9SZXF1aXJlczogY2FtbF9tbF9zdHJpbmdfbGVuZ3RoLGNhbWxfc3RyaW5nX3Vuc2FmZV9nZXQsIE1sSW50NjRcbmZ1bmN0aW9uIGNhbWxfaW50NjRfb2Zfc3RyaW5nKHMpIHtcbiAgdmFyIHIgPSBjYW1sX3BhcnNlX3NpZ25fYW5kX2Jhc2UgKHMpO1xuICB2YXIgaSA9IHJbMF0sIHNpZ24gPSByWzFdLCBiYXNlID0gclsyXTtcbiAgdmFyIGJhc2U2NCA9IGNhbWxfaW50NjRfb2ZfaW50MzIoYmFzZSk7XG4gIHZhciB0aHJlc2hvbGQgPVxuICAgICAgbmV3IE1sSW50NjQoMHhmZmZmZmYsIDB4ZmZmZmZmZiwgMHhmZmZmKS51ZGl2bW9kKGJhc2U2NCkucXVvdGllbnQ7XG4gIHZhciBjID0gY2FtbF9zdHJpbmdfdW5zYWZlX2dldChzLCBpKTtcbiAgdmFyIGQgPSBjYW1sX3BhcnNlX2RpZ2l0KGMpO1xuICBpZiAoZCA8IDAgfHwgZCA+PSBiYXNlKSBjYW1sX2ZhaWx3aXRoKFwiaW50X29mX3N0cmluZ1wiKTtcbiAgdmFyIHJlcyA9IGNhbWxfaW50NjRfb2ZfaW50MzIoZCk7XG4gIGZvciAoOzspIHtcbiAgICBpKys7XG4gICAgYyA9IGNhbWxfc3RyaW5nX3Vuc2FmZV9nZXQocywgaSk7XG4gICAgaWYgKGMgPT0gOTUpIGNvbnRpbnVlO1xuICAgIGQgPSBjYW1sX3BhcnNlX2RpZ2l0KGMpO1xuICAgIGlmIChkIDwgMCB8fCBkID49IGJhc2UpIGJyZWFrO1xuICAgIC8qIERldGVjdCBvdmVyZmxvdyBpbiBtdWx0aXBsaWNhdGlvbiBiYXNlICogcmVzICovXG4gICAgaWYgKGNhbWxfaW50NjRfdWx0KHRocmVzaG9sZCwgcmVzKSkgY2FtbF9mYWlsd2l0aChcImludF9vZl9zdHJpbmdcIik7XG4gICAgZCA9IGNhbWxfaW50NjRfb2ZfaW50MzIoZCk7XG4gICAgcmVzID0gY2FtbF9pbnQ2NF9hZGQoY2FtbF9pbnQ2NF9tdWwoYmFzZTY0LCByZXMpLCBkKTtcbiAgICAvKiBEZXRlY3Qgb3ZlcmZsb3cgaW4gYWRkaXRpb24gKGJhc2UgKiByZXMpICsgZCAqL1xuICAgIGlmIChjYW1sX2ludDY0X3VsdChyZXMsIGQpKSBjYW1sX2ZhaWx3aXRoKFwiaW50X29mX3N0cmluZ1wiKTtcbiAgfVxuICBpZiAoaSAhPSBjYW1sX21sX3N0cmluZ19sZW5ndGgocykpIGNhbWxfZmFpbHdpdGgoXCJpbnRfb2Zfc3RyaW5nXCIpO1xuICBpZiAoYmFzZSA9PSAxMCAmJiBjYW1sX2ludDY0X3VsdChuZXcgTWxJbnQ2NCgwLCAwLCAweDgwMDApLCByZXMpKVxuICAgIGNhbWxfZmFpbHdpdGgoXCJpbnRfb2Zfc3RyaW5nXCIpO1xuICBpZiAoc2lnbiA8IDApIHJlcyA9IGNhbWxfaW50NjRfbmVnKHJlcyk7XG4gIHJldHVybiByZXM7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfaW50NjRfY3JlYXRlX2xvX21pX2hpIGNvbnN0XG4vL1JlcXVpcmVzOiBNbEludDY0XG5mdW5jdGlvbiBjYW1sX2ludDY0X2NyZWF0ZV9sb19taV9oaShsbywgbWksIGhpKXtcbiAgcmV0dXJuIG5ldyBNbEludDY0KGxvLCBtaSwgaGkpXG59XG4vL1Byb3ZpZGVzOiBjYW1sX2ludDY0X2NyZWF0ZV9sb19oaSBjb25zdFxuLy9SZXF1aXJlczogTWxJbnQ2NFxuZnVuY3Rpb24gY2FtbF9pbnQ2NF9jcmVhdGVfbG9faGkobG8sIGhpKXtcbiAgcmV0dXJuIG5ldyBNbEludDY0IChcbiAgICBsbyAmIDB4ZmZmZmZmLFxuICAgICgobG8gPj4+IDI0KSAmIDB4ZmYpIHwgKChoaSAmIDB4ZmZmZikgPDwgOCksXG4gICAgKGhpID4+PiAxNikgJiAweGZmZmYpO1xufVxuLy9Qcm92aWRlczogY2FtbF9pbnQ2NF9sbzMyIGNvbnN0XG5mdW5jdGlvbiBjYW1sX2ludDY0X2xvMzIodil7IHJldHVybiB2LmxvMzIoKSB9XG5cbi8vUHJvdmlkZXM6IGNhbWxfaW50NjRfaGkzMiBjb25zdFxuZnVuY3Rpb24gY2FtbF9pbnQ2NF9oaTMyKHYpeyByZXR1cm4gdi5oaTMyKCkgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2ludDY0X29mX2J5dGVzIGNvbnN0XG4vL1JlcXVpcmVzOiBNbEludDY0XG5mdW5jdGlvbiBjYW1sX2ludDY0X29mX2J5dGVzKGEpIHtcbiAgcmV0dXJuIG5ldyBNbEludDY0KGFbN10gPDwgMCB8IChhWzZdIDw8IDgpIHwgKGFbNV0gPDwgMTYpLFxuICAgICAgICAgICAgICAgICAgICAgYVs0XSA8PCAwIHwgKGFbM10gPDwgOCkgfCAoYVsyXSA8PCAxNiksXG4gICAgICAgICAgICAgICAgICAgICBhWzFdIDw8IDAgfCAoYVswXSA8PCA4KSk7XG59XG4vL1Byb3ZpZGVzOiBjYW1sX2ludDY0X3RvX2J5dGVzIGNvbnN0XG5mdW5jdGlvbiBjYW1sX2ludDY0X3RvX2J5dGVzKHgpIHsgcmV0dXJuIHgudG9BcnJheSgpIH1cblxuLy9Qcm92aWRlczogY2FtbF9pbnQ2NF9oYXNoIGNvbnN0XG5mdW5jdGlvbiBjYW1sX2ludDY0X2hhc2godil7XG4gIHJldHVybiAodi5sbzMyKCkpIF4gKHYuaGkzMigpKVxufVxuIiwiXG4vL1Byb3ZpZGVzOiBNbE11dGV4XG5mdW5jdGlvbiBNbE11dGV4KCkge1xuICB0aGlzLmxvY2tlZCA9IGZhbHNlXG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfbXV0ZXhfbmV3XG4vL1JlcXVpcmVzOiBNbE11dGV4XG5mdW5jdGlvbiBjYW1sX21sX211dGV4X25ldyh1bml0KSB7XG4gIHJldHVybiBuZXcgTWxNdXRleCgpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21sX211dGV4X2xvY2tcbi8vUmVxdWlyZXM6IGNhbWxfZmFpbHdpdGhcbmZ1bmN0aW9uIGNhbWxfbWxfbXV0ZXhfbG9jayh0KSB7XG4gIGlmKHQubG9ja2VkKVxuICAgIGNhbWxfZmFpbHdpdGgoXCJNdXRleC5sb2NrOiBtdXRleCBhbHJlYWR5IGxvY2tlZC4gQ2Fubm90IHdhaXQuXCIpO1xuICBlbHNlIHQubG9ja2VkID0gdHJ1ZTtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfbXV0ZXhfdHJ5X2xvY2tcbmZ1bmN0aW9uIGNhbWxfbWxfbXV0ZXhfdHJ5X2xvY2sodCkge1xuICBpZighdC5sb2NrZWQpIHtcbiAgICB0LmxvY2tlZCA9IHRydWU7XG4gICAgcmV0dXJuIDE7XG4gIH1cbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfbXV0ZXhfdW5sb2NrXG5mdW5jdGlvbiBjYW1sX21sX211dGV4X3VubG9jayh0KSB7XG4gIHQubG9ja2VkID0gZmFsc2U7XG4gIHJldHVybiAwO1xufVxuIiwiLy9Qcm92aWRlczogaW5pdGlhbGl6ZV9uYXRcbi8vUmVxdWlyZXM6IGNhbWxfY3VzdG9tX29wc1xuLy9SZXF1aXJlczogc2VyaWFsaXplX25hdCwgZGVzZXJpYWxpemVfbmF0LCBjYW1sX2hhc2hfbmF0XG5mdW5jdGlvbiBpbml0aWFsaXplX25hdCgpIHtcbiAgY2FtbF9jdXN0b21fb3BzW1wiX25hdFwiXSA9XG4gICAgeyBkZXNlcmlhbGl6ZSA6IGRlc2VyaWFsaXplX25hdCxcbiAgICAgIHNlcmlhbGl6ZSA6IHNlcmlhbGl6ZV9uYXQsXG4gICAgICBoYXNoIDogY2FtbF9oYXNoX25hdFxuICAgIH1cbn1cblxuLy9Qcm92aWRlczogTWxOYXRcbmZ1bmN0aW9uIE1sTmF0KHgpe1xuICB0aGlzLmRhdGEgPSBuZXcgSW50MzJBcnJheSh4KTtcbiAgLy8gRm9yIG51bSA8IDEuNVxuICAvLyBsZW5ndGhfbmF0IGlzbid0IGV4dGVybmFsLCBzbyB3ZSBoYXZlIHRvIG1ha2UgdGhlIE9iai5zaXplXG4gIC8vIHdvcmsgb3V0IHJpZ2h0LlxuICAvLyBXZSBhZGQgKzIgdG8gdGhlIGFycmF5IGxlbmd0aDpcbiAgLy8gLSArMSBmb3IgdGhlIHRhZ1xuICAvLyAtICsxIGZvciB0aGUgY3VzdG9tX29wcyBzbG90XG4gIHRoaXMubGVuZ3RoID0gdGhpcy5kYXRhLmxlbmd0aCArIDJcbn1cblxuTWxOYXQucHJvdG90eXBlLmNhbWxfY3VzdG9tID0gXCJfbmF0XCI7XG5cbi8vUHJvdmlkZXM6IGNhbWxfaGFzaF9uYXRcbi8vUmVxdWlyZXM6IGNhbWxfaGFzaF9taXhfaW50LCBudW1fZGlnaXRzX25hdFxuZnVuY3Rpb24gY2FtbF9oYXNoX25hdCh4KSB7XG4gIHZhciBsZW4gPSBudW1fZGlnaXRzX25hdCh4LCAwLCB4LmRhdGEubGVuZ3RoKTtcbiAgdmFyIGggPSAwO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgaCA9IGNhbWxfaGFzaF9taXhfaW50KGgsIHguZGF0YVtpXSk7XG4gIH1cbiAgcmV0dXJuIGg7XG59XG5cbi8vUHJvdmlkZXM6IGxlbmd0aF9uYXRcbmZ1bmN0aW9uIGxlbmd0aF9uYXQoeCkge1xuICByZXR1cm4geC5kYXRhLmxlbmd0aDtcbn1cblxuLy9Qcm92aWRlczogbmF0X29mX2FycmF5XG4vL1JlcXVpcmVzOiBNbE5hdFxuZnVuY3Rpb24gbmF0X29mX2FycmF5KGwpe1xuICByZXR1cm4gbmV3IE1sTmF0KGwpO1xufVxuXG4vL1Byb3ZpZGVzOiBjcmVhdGVfbmF0XG4vL1JlcXVpcmVzOiBNbE5hdFxuZnVuY3Rpb24gY3JlYXRlX25hdChzaXplKSB7XG4gIHZhciBhcnIgPSBuZXcgTWxOYXQoc2l6ZSk7XG4gIGZvcih2YXIgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICBhcnIuZGF0YVtpXSA9IC0xO1xuICB9XG4gIHJldHVybiBhcnI7XG59XG5cbi8vUHJvdmlkZXM6IHNldF90b196ZXJvX25hdFxuZnVuY3Rpb24gc2V0X3RvX3plcm9fbmF0KG5hdCwgb2ZzLCBsZW4pIHtcbiAgZm9yKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgbmF0LmRhdGFbb2ZzK2ldID0gMDtcbiAgfVxuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogYmxpdF9uYXRcbmZ1bmN0aW9uIGJsaXRfbmF0KG5hdDEsIG9mczEsIG5hdDIsIG9mczIsIGxlbikge1xuICBmb3IodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICBuYXQxLmRhdGFbb2ZzMStpXSA9IG5hdDIuZGF0YVtvZnMyK2ldO1xuICB9XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBzZXRfZGlnaXRfbmF0XG5mdW5jdGlvbiBzZXRfZGlnaXRfbmF0KG5hdCwgb2ZzLCBkaWdpdCkge1xuICBuYXQuZGF0YVtvZnNdID0gZGlnaXQ7XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBudGhfZGlnaXRfbmF0XG5mdW5jdGlvbiBudGhfZGlnaXRfbmF0KG5hdCwgb2ZzKSB7XG4gIHJldHVybiBuYXQuZGF0YVtvZnNdO1xufVxuXG4vL1Byb3ZpZGVzOiBzZXRfZGlnaXRfbmF0X25hdGl2ZVxuZnVuY3Rpb24gc2V0X2RpZ2l0X25hdF9uYXRpdmUobmF0LCBvZnMsIGRpZ2l0KSB7XG4gIG5hdC5kYXRhW29mc10gPSBkaWdpdDtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IG50aF9kaWdpdF9uYXRfbmF0aXZlXG5mdW5jdGlvbiBudGhfZGlnaXRfbmF0X25hdGl2ZShuYXQsIG9mcykge1xuICByZXR1cm4gbmF0LmRhdGFbb2ZzXTtcbn1cblxuLy9Qcm92aWRlczogbnVtX2RpZ2l0c19uYXRcbmZ1bmN0aW9uIG51bV9kaWdpdHNfbmF0KG5hdCwgb2ZzLCBsZW4pIHtcbiAgZm9yKHZhciBpID0gbGVuIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBpZihuYXQuZGF0YVtvZnMraV0gIT0gMCkgcmV0dXJuIGkrMTtcbiAgfVxuICByZXR1cm4gMTsgLy8gMCBjb3VudHMgYXMgMSBkaWdpdFxufVxuXG4vL1Byb3ZpZGVzOiBudW1fbGVhZGluZ196ZXJvX2JpdHNfaW5fZGlnaXRcbmZ1bmN0aW9uIG51bV9sZWFkaW5nX3plcm9fYml0c19pbl9kaWdpdChuYXQsIG9mcykge1xuICB2YXIgYSA9IG5hdC5kYXRhW29mc107XG4gIHZhciBiID0gMDtcbiAgaWYoYSAmIDB4RkZGRjAwMDApIHsgYiArPTE2OyBhID4+Pj0xNjsgfVxuICBpZihhICYgMHhGRjAwKSAgICAgeyBiICs9IDg7IGEgPj4+PSA4OyB9XG4gIGlmKGEgJiAweEYwKSAgICAgICB7IGIgKz0gNDsgYSA+Pj49IDQ7IH1cbiAgaWYoYSAmIDEyKSAgICAgICAgIHsgYiArPSAyOyBhID4+Pj0gMjsgfVxuICBpZihhICYgMikgICAgICAgICAgeyBiICs9IDE7IGEgPj4+PSAxOyB9XG4gIGlmKGEgJiAxKSAgICAgICAgICB7IGIgKz0gMTsgfVxuICByZXR1cm4gMzIgLSBiO1xufVxuXG4vL1Byb3ZpZGVzOiBpc19kaWdpdF9pbnRcbmZ1bmN0aW9uIGlzX2RpZ2l0X2ludChuYXQsIG9mcykge1xuICBpZiAobmF0LmRhdGFbb2ZzXSA+PSAwKSByZXR1cm4gMVxuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogaXNfZGlnaXRfemVyb1xuZnVuY3Rpb24gaXNfZGlnaXRfemVybyhuYXQsIG9mcykge1xuICBpZihuYXQuZGF0YVtvZnNdID09IDApIHJldHVybiAxO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogaXNfZGlnaXRfb2RkXG5mdW5jdGlvbiBpc19kaWdpdF9vZGQobmF0LCBvZnMpIHtcbiAgaWYobmF0LmRhdGFbb2ZzXSAmIDEpIHJldHVybiAxO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogaW5jcl9uYXRcbmZ1bmN0aW9uIGluY3JfbmF0KG5hdCwgb2ZzLCBsZW4sIGNhcnJ5X2luKSB7XG4gIHZhciBjYXJyeSA9IGNhcnJ5X2luO1xuICBmb3IodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICB2YXIgeCA9IChuYXQuZGF0YVtvZnMraV0gPj4+IDApICsgY2Fycnk7XG4gICAgbmF0LmRhdGFbb2ZzK2ldID0gKHggfCAwKTtcbiAgICBpZih4ID09ICh4ID4+PiAwKSkge1xuICAgICAgY2FycnkgPSAwO1xuICAgICAgYnJlYWs7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNhcnJ5ID0gMTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNhcnJ5O1xufVxuXG4vLyBsZW4xID49IGxlbjJcbi8vUHJvdmlkZXM6IGFkZF9uYXRcbi8vUmVxdWlyZXM6IGluY3JfbmF0XG5mdW5jdGlvbiBhZGRfbmF0KG5hdDEsIG9mczEsIGxlbjEsIG5hdDIsIG9mczIsIGxlbjIsIGNhcnJ5X2luKSB7XG4gIHZhciBjYXJyeSA9IGNhcnJ5X2luO1xuICBmb3IodmFyIGkgPSAwOyBpIDwgbGVuMjsgaSsrKSB7XG4gICAgdmFyIHggPSAobmF0MS5kYXRhW29mczEraV0gPj4+IDApICsgKG5hdDIuZGF0YVtvZnMyK2ldID4+PiAwKSArIGNhcnJ5O1xuICAgIG5hdDEuZGF0YVtvZnMxK2ldID0geFxuICAgIGlmKHggPT0gKHggPj4+IDApKSB7XG4gICAgICBjYXJyeSA9IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNhcnJ5ID0gMTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGluY3JfbmF0KG5hdDEsIG9mczErbGVuMiwgbGVuMS1sZW4yLCBjYXJyeSk7XG59XG5cbi8vUHJvdmlkZXM6IGNvbXBsZW1lbnRfbmF0XG5mdW5jdGlvbiBjb21wbGVtZW50X25hdChuYXQsIG9mcywgbGVuKSB7XG4gIGZvcih2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIG5hdC5kYXRhW29mcytpXSA9ICgtMSA+Pj4gMCkgLSAobmF0LmRhdGFbb2ZzK2ldID4+PiAwKTtcbiAgfVxufVxuXG4vLyBvY2FtbCBmbGlwcyBjYXJyeV9pblxuLy9Qcm92aWRlczogZGVjcl9uYXRcbmZ1bmN0aW9uIGRlY3JfbmF0KG5hdCwgb2ZzLCBsZW4sIGNhcnJ5X2luKSB7XG4gIHZhciBib3Jyb3cgPSAoY2FycnlfaW4gPT0gMSkgPyAwIDogMTtcbiAgZm9yKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgdmFyIHggPSAobmF0LmRhdGFbb2ZzK2ldID4+PjApIC0gYm9ycm93O1xuICAgIG5hdC5kYXRhW29mcytpXSA9IHg7XG4gICAgaWYgKHggPj0gMCkge1xuICAgICAgYm9ycm93ID0gMDtcbiAgICAgIGJyZWFrO1xuICAgIH0gZWxzZSB7XG4gICAgICBib3Jyb3cgPSAxO1xuICAgIH1cbiAgfVxuICByZXR1cm4gKGJvcnJvdyA9PSAxKSA/IDAgOiAxO1xufVxuXG4vLyBvY2FtbCBmbGlwcyBjYXJyeV9pblxuLy8gbGVuMSA+PSBsZW4yXG4vL1Byb3ZpZGVzOiBzdWJfbmF0XG4vL1JlcXVpcmVzOiBkZWNyX25hdFxuZnVuY3Rpb24gc3ViX25hdChuYXQxLCBvZnMxLCBsZW4xLCBuYXQyLCBvZnMyLCBsZW4yLCBjYXJyeV9pbikge1xuICB2YXIgYm9ycm93ID0gKGNhcnJ5X2luID09IDEpID8gMCA6IDE7XG4gIGZvcih2YXIgaSA9IDA7IGkgPCBsZW4yOyBpKyspIHtcbiAgICB2YXIgeCA9IChuYXQxLmRhdGFbb2ZzMStpXSA+Pj4gMCkgLSAobmF0Mi5kYXRhW29mczIraV0gPj4+IDApIC0gYm9ycm93O1xuICAgIG5hdDEuZGF0YVtvZnMxK2ldID0geDtcbiAgICBpZiAoeCA+PSAwKSB7XG4gICAgICBib3Jyb3cgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICBib3Jyb3cgPSAxO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZGVjcl9uYXQobmF0MSwgb2ZzMStsZW4yLCBsZW4xLWxlbjIsIChib3Jyb3c9PTEpPzA6MSk7XG59XG5cbi8vIG5hdDEgKz0gbmF0MiAqIG5hdDNbb2ZzM11cbi8vIGxlbjEgPj0gbGVuMlxuLy9Qcm92aWRlczogbXVsdF9kaWdpdF9uYXRcbi8vUmVxdWlyZXM6IGFkZF9uYXQsIG5hdF9vZl9hcnJheVxuZnVuY3Rpb24gbXVsdF9kaWdpdF9uYXQobmF0MSwgb2ZzMSwgbGVuMSwgbmF0Miwgb2ZzMiwgbGVuMiwgbmF0Mywgb2ZzMykge1xuICB2YXIgY2FycnkgPSAwO1xuICB2YXIgYSA9IChuYXQzLmRhdGFbb2ZzM10gPj4+IDApO1xuICBmb3IodmFyIGkgPSAwOyBpIDwgbGVuMjsgaSsrKSB7XG4gICAgdmFyIHgxID0gKG5hdDEuZGF0YVtvZnMxK2ldID4+PiAwKSArIChuYXQyLmRhdGFbb2ZzMitpXSA+Pj4gMCkgKiAoYSAmIDB4MDAwMEZGRkYpICsgY2Fycnk7XG4gICAgdmFyIHgyID0gKG5hdDIuZGF0YVtvZnMyK2ldID4+PiAwKSAqIChhID4+PiAxNik7XG4gICAgY2FycnkgPSBNYXRoLmZsb29yKHgyLzY1NTM2KTtcbiAgICB2YXIgeDMgPSB4MSArICh4MiAlIDY1NTM2KSAqIDY1NTM2O1xuICAgIG5hdDEuZGF0YVtvZnMxK2ldID0geDM7XG4gICAgY2FycnkgKz0gTWF0aC5mbG9vcih4My80Mjk0OTY3Mjk2KTtcbiAgfVxuXG4gIGlmKGxlbjIgPCBsZW4xICYmIGNhcnJ5KSB7XG4gICAgcmV0dXJuIGFkZF9uYXQobmF0MSwgb2ZzMStsZW4yLCBsZW4xLWxlbjIsIG5hdF9vZl9hcnJheShbY2FycnldKSwgMCwgMSwgMCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGNhcnJ5O1xuICB9XG59XG5cbi8vIG5hdDEgKz0gbmF0MiAqIG5hdDNcbi8vIGxlbjEgPj0gbGVuMiArIGxlbjMuXG4vL1Byb3ZpZGVzOiBtdWx0X25hdFxuLy9SZXF1aXJlczogbXVsdF9kaWdpdF9uYXRcbmZ1bmN0aW9uIG11bHRfbmF0KG5hdDEsIG9mczEsIGxlbjEsIG5hdDIsIG9mczIsIGxlbjIsIG5hdDMsIG9mczMsIGxlbjMpIHtcbiAgdmFyIGNhcnJ5ID0gMDtcbiAgZm9yKHZhciBpID0gMDsgaSA8IGxlbjM7IGkrKykge1xuICAgIGNhcnJ5ICs9IG11bHRfZGlnaXRfbmF0KG5hdDEsIG9mczEraSwgbGVuMS1pLCBuYXQyLCBvZnMyLCBsZW4yLCBuYXQzLCBvZnMzK2kpO1xuICB9XG4gIHJldHVybiBjYXJyeTtcbn1cblxuLy8gbmF0MSA9IDIgKiBuYXQxICsgbmF0MiAqIG5hdDJcbi8vIGxlbjEgPj0gMiAqIGxlbjJcbi8vUHJvdmlkZXM6IHNxdWFyZV9uYXRcbi8vUmVxdWlyZXM6IG11bHRfbmF0LCBhZGRfbmF0XG5mdW5jdGlvbiBzcXVhcmVfbmF0KG5hdDEsIG9mczEsIGxlbjEsIG5hdDIsIG9mczIsIGxlbjIpIHtcbiAgdmFyIGNhcnJ5ID0gMDtcbiAgY2FycnkgKz0gYWRkX25hdChuYXQxLCBvZnMxLCBsZW4xLCBuYXQxLCBvZnMxLCBsZW4xLCAwKTtcbiAgY2FycnkgKz0gbXVsdF9uYXQobmF0MSwgb2ZzMSwgbGVuMSwgbmF0Miwgb2ZzMiwgbGVuMiwgbmF0Miwgb2ZzMiwgbGVuMik7XG4gIHJldHVybiBjYXJyeTtcbn1cblxuXG4vLyAwIDw9IHNoaWZ0IDwgMzJcbi8vUHJvdmlkZXM6IHNoaWZ0X2xlZnRfbmF0XG5mdW5jdGlvbiBzaGlmdF9sZWZ0X25hdChuYXQxLCBvZnMxLCBsZW4xLCBuYXQyLCBvZnMyLCBuYml0cykge1xuICBpZihuYml0cyA9PSAwKSB7XG4gICAgbmF0Mi5kYXRhW29mczJdID0gMDtcbiAgICByZXR1cm4gMDtcbiAgfVxuICB2YXIgd3JhcCA9IDA7XG4gIGZvcih2YXIgaSA9IDA7IGkgPCBsZW4xOyBpKyspIHtcbiAgICB2YXIgYSA9IChuYXQxLmRhdGFbb2ZzMStpXSA+Pj4gMCk7XG4gICAgbmF0MS5kYXRhW29mczEraV0gPSAoYSA8PCBuYml0cykgfCB3cmFwO1xuICAgIHdyYXAgPSBhID4+PiAoMzIgLSBuYml0cyk7XG4gIH1cbiAgbmF0Mi5kYXRhW29mczJdID0gd3JhcDtcbiAgcmV0dXJuIDA7XG59XG5cbi8vIEFzc3VtaW5nIGMgPiBhLCByZXR1cm5zIFtxdW90aWVudCwgcmVtYWluZGVyXSBvZiAoYTw8MzIgKyBiKS9jXG4vL1Byb3ZpZGVzOiBkaXZfaGVscGVyXG5mdW5jdGlvbiBkaXZfaGVscGVyKGEsIGIsIGMpIHtcbiAgdmFyIHggPSBhICogNjU1MzYgKyAoYj4+PjE2KTtcbiAgdmFyIHkgPSBNYXRoLmZsb29yKHgvYykgKiA2NTUzNjtcbiAgdmFyIHogPSAoeCAlIGMpICogNjU1MzY7XG4gIHZhciB3ID0geiArIChiICYgMHgwMDAwRkZGRik7XG4gIHJldHVybiBbeSArIE1hdGguZmxvb3Iody9jKSwgdyAlIGNdO1xufVxuXG4vLyBuYXQxW29mczErbGVuXSA8IG5hdDJbb2ZzMl1cbi8vUHJvdmlkZXM6IGRpdl9kaWdpdF9uYXRcbi8vUmVxdWlyZXM6IGRpdl9oZWxwZXJcbmZ1bmN0aW9uIGRpdl9kaWdpdF9uYXQobmF0cSwgb2ZzcSwgbmF0ciwgb2ZzciwgbmF0MSwgb2ZzMSwgbGVuLCBuYXQyLCBvZnMyKSB7XG4gIHZhciByZW0gPSAobmF0MS5kYXRhW29mczErbGVuLTFdID4+PjApO1xuICAvLyBuYXRxW29mc3ErbGVuLTFdIGlzIGd1YXJhbnRlZWQgdG8gYmUgemVybyAoZHVlIHRvIHRoZSBNU0QgcmVxdWlyZW1lbnQpLFxuICAvLyBhbmQgc2hvdWxkIG5vdCBiZSB3cml0dGVuIHRvLlxuICBmb3IodmFyIGkgPSBsZW4tMjsgaSA+PSAwOyBpLS0pIHtcbiAgICB2YXIgeCA9IGRpdl9oZWxwZXIocmVtLCAobmF0MS5kYXRhW29mczEraV0gPj4+IDApLCAobmF0Mi5kYXRhW29mczJdID4+PiAwKSk7XG4gICAgbmF0cS5kYXRhW29mc3EraV0gPSB4WzBdO1xuICAgIHJlbSA9IHhbMV07XG4gIH1cbiAgbmF0ci5kYXRhW29mc3JdID0gcmVtO1xuICByZXR1cm4gMDtcbn1cblxuLy8gbmF0MVtuYXQyOl0gOj0gbmF0MSAvIG5hdDJcbi8vIG5hdDFbOm5hdDJdIDo9IG5hdDEgJSBuYXQyXG4vLyBsZW4xID4gbGVuMiwgbmF0MltvZnMyK2xlbjItMV0gPiBuYXQxW29mczErbGVuMS0xXVxuLy9Qcm92aWRlczogZGl2X25hdFxuLy9SZXF1aXJlczogZGl2X2RpZ2l0X25hdCwgZGl2X2hlbHBlciwgbnVtX2xlYWRpbmdfemVyb19iaXRzX2luX2RpZ2l0LCBzaGlmdF9sZWZ0X25hdCwgc2hpZnRfcmlnaHRfbmF0LCBjcmVhdGVfbmF0LCBzZXRfdG9femVyb19uYXQsIG11bHRfZGlnaXRfbmF0LCBzdWJfbmF0LCBjb21wYXJlX25hdCwgbmF0X29mX2FycmF5XG5mdW5jdGlvbiBkaXZfbmF0KG5hdDEsIG9mczEsIGxlbjEsIG5hdDIsIG9mczIsIGxlbjIpIHtcbiAgaWYobGVuMiA9PSAxKSB7XG4gICAgZGl2X2RpZ2l0X25hdChuYXQxLCBvZnMxKzEsIG5hdDEsIG9mczEsIG5hdDEsIG9mczEsIGxlbjEsIG5hdDIsIG9mczIpO1xuICAgIHJldHVybiAwO1xuICB9XG5cbiAgdmFyIHMgPSBudW1fbGVhZGluZ196ZXJvX2JpdHNfaW5fZGlnaXQobmF0Miwgb2ZzMitsZW4yLTEpO1xuICBzaGlmdF9sZWZ0X25hdChuYXQyLCBvZnMyLCBsZW4yLCBuYXRfb2ZfYXJyYXkoWzBdKSwgMCwgcyk7XG4gIHNoaWZ0X2xlZnRfbmF0KG5hdDEsIG9mczEsIGxlbjEsIG5hdF9vZl9hcnJheShbMF0pLCAwLCBzKTtcblxuICB2YXIgZCA9IChuYXQyLmRhdGFbb2ZzMitsZW4yLTFdID4+PiAwKSArIDE7XG4gIHZhciBhID0gY3JlYXRlX25hdChsZW4yKzEpO1xuICBmb3IgKHZhciBpID0gbGVuMSAtIDE7IGkgPj0gbGVuMjsgaS0tKSB7XG4gICAgLy8gRGVjZW50IGxvd2VyIGJvdW5kIG9uIHF1b1xuICAgIHZhciBxdW8gPSBkID09IDQyOTQ5NjcyOTYgPyAobmF0MS5kYXRhW29mczEraV0gPj4+IDApIDogZGl2X2hlbHBlcigobmF0MS5kYXRhW29mczEraV0gPj4+IDApLCAobmF0MS5kYXRhW29mczEraS0xXSA+Pj4wKSwgZClbMF07XG4gICAgc2V0X3RvX3plcm9fbmF0KGEsIDAsIGxlbjIrMSk7XG4gICAgbXVsdF9kaWdpdF9uYXQoYSwgMCwgbGVuMisxLCBuYXQyLCBvZnMyLCBsZW4yLCBuYXRfb2ZfYXJyYXkoW3F1b10pLCAwKTtcbiAgICBzdWJfbmF0KG5hdDEsIG9mczEraS1sZW4yLCBsZW4yKzEsIGEsIDAsIGxlbjIrMSwgMSk7XG5cbiAgICB3aGlsZSAobmF0MS5kYXRhW29mczEraV0gIT0gMCB8fCBjb21wYXJlX25hdChuYXQxLCBvZnMxK2ktbGVuMiwgbGVuMiwgbmF0Miwgb2ZzMiwgbGVuMikgPj0gMCkge1xuICAgICAgcXVvID0gcXVvICsgMTtcbiAgICAgIHN1Yl9uYXQobmF0MSwgb2ZzMStpLWxlbjIsIGxlbjIrMSwgbmF0Miwgb2ZzMiwgbGVuMiwgMSk7XG4gICAgfVxuXG4gICAgbmF0MS5kYXRhW29mczEraV0gPSBxdW87XG4gIH1cblxuICBzaGlmdF9yaWdodF9uYXQobmF0MSwgb2ZzMSwgbGVuMiwgbmF0X29mX2FycmF5KFswXSksIDAsIHMpOyAvLyBzaGlmdCByZW1haW5kZXJcbiAgc2hpZnRfcmlnaHRfbmF0KG5hdDIsIG9mczIsIGxlbjIsIG5hdF9vZl9hcnJheShbMF0pLCAwLCBzKTsgLy8gcmVzdG9yZVxuICByZXR1cm4gMDtcbn1cblxuXG4vLyAwIDw9IHNoaWZ0IDwgMzJcbi8vUHJvdmlkZXM6IHNoaWZ0X3JpZ2h0X25hdFxuZnVuY3Rpb24gc2hpZnRfcmlnaHRfbmF0KG5hdDEsIG9mczEsIGxlbjEsIG5hdDIsIG9mczIsIG5iaXRzKSB7XG4gIGlmKG5iaXRzID09IDApIHtcbiAgICBuYXQyLmRhdGFbb2ZzMl0gPSAwO1xuICAgIHJldHVybiAwO1xuICB9XG4gIHZhciB3cmFwID0gMDtcbiAgZm9yKHZhciBpID0gbGVuMS0xOyBpID49IDA7IGktLSkge1xuICAgIHZhciBhID0gbmF0MS5kYXRhW29mczEraV0gPj4+IDA7XG4gICAgbmF0MS5kYXRhW29mczEraV0gPSAoYSA+Pj4gbmJpdHMpIHwgd3JhcDtcbiAgICB3cmFwID0gYSA8PCAoMzIgLSBuYml0cyk7XG4gIH1cbiAgbmF0Mi5kYXRhW29mczJdID0gd3JhcDtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNvbXBhcmVfZGlnaXRzX25hdFxuZnVuY3Rpb24gY29tcGFyZV9kaWdpdHNfbmF0KG5hdDEsIG9mczEsIG5hdDIsIG9mczIpIHtcbiAgaWYobmF0MS5kYXRhW29mczFdID4gbmF0Mi5kYXRhW29mczJdKSByZXR1cm4gMTtcbiAgaWYobmF0MS5kYXRhW29mczFdIDwgbmF0Mi5kYXRhW29mczJdKSByZXR1cm4gLTE7XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjb21wYXJlX25hdFxuLy9SZXF1aXJlczogbnVtX2RpZ2l0c19uYXRcbmZ1bmN0aW9uIGNvbXBhcmVfbmF0KG5hdDEsIG9mczEsIGxlbjEsIG5hdDIsIG9mczIsIGxlbjIpIHtcbiAgdmFyIGEgPSBudW1fZGlnaXRzX25hdChuYXQxLCBvZnMxLCBsZW4xKTtcbiAgdmFyIGIgPSBudW1fZGlnaXRzX25hdChuYXQyLCBvZnMyLCBsZW4yKTtcbiAgaWYoYSA+IGIpIHJldHVybiAxO1xuICBpZihhIDwgYikgcmV0dXJuIC0xO1xuICBmb3IodmFyIGkgPSBsZW4xIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBpZiAoKG5hdDEuZGF0YVtvZnMxK2ldID4+PiAwKSA+IChuYXQyLmRhdGFbb2ZzMitpXSA+Pj4gMCkpIHJldHVybiAxO1xuICAgIGlmICgobmF0MS5kYXRhW29mczEraV0gPj4+IDApIDwgKG5hdDIuZGF0YVtvZnMyK2ldID4+PiAwKSkgcmV0dXJuIC0xO1xuICB9XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjb21wYXJlX25hdF9yZWFsXG4vL1JlcXVpcmVzOiBjb21wYXJlX25hdFxuZnVuY3Rpb24gY29tcGFyZV9uYXRfcmVhbChuYXQxLG5hdDIpe1xuICByZXR1cm4gY29tcGFyZV9uYXQobmF0MSwwLG5hdDEuZGF0YS5sZW5ndGgsbmF0MiwwLG5hdDIuZGF0YS5sZW5ndGgpO1xufVxuXG4vL1Byb3ZpZGVzOiBsYW5kX2RpZ2l0X25hdFxuZnVuY3Rpb24gbGFuZF9kaWdpdF9uYXQobmF0MSwgb2ZzMSwgbmF0Miwgb2ZzMikge1xuICBuYXQxLmRhdGFbb2ZzMV0gJj0gbmF0Mi5kYXRhW29mczJdO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogbG9yX2RpZ2l0X25hdFxuZnVuY3Rpb24gbG9yX2RpZ2l0X25hdChuYXQxLCBvZnMxLCBuYXQyLCBvZnMyKSB7XG4gIG5hdDEuZGF0YVtvZnMxXSB8PSBuYXQyLmRhdGFbb2ZzMl07XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBseG9yX2RpZ2l0X25hdFxuZnVuY3Rpb24gbHhvcl9kaWdpdF9uYXQobmF0MSwgb2ZzMSwgbmF0Miwgb2ZzMikge1xuICBuYXQxLmRhdGFbb2ZzMV0gXj0gbmF0Mi5kYXRhW29mczJdO1xuICByZXR1cm4gMDtcbn1cblxuXG4vL1Byb3ZpZGVzOiBzZXJpYWxpemVfbmF0XG5mdW5jdGlvbiBzZXJpYWxpemVfbmF0KHdyaXRlciwgbmF0LCBzeil7XG4gIHZhciBsZW4gPSBuYXQuZGF0YS5sZW5ndGg7XG4gIHdyaXRlci53cml0ZSgzMiwgbGVuKTtcbiAgZm9yKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKXtcbiAgICB3cml0ZXIud3JpdGUoMzIsIG5hdC5kYXRhW2ldKTtcbiAgfVxuICBzelswXSA9IGxlbiAqIDQ7XG4gIHN6WzFdID0gbGVuICogODtcbn1cblxuLy9Qcm92aWRlczogZGVzZXJpYWxpemVfbmF0XG4vL1JlcXVpcmVzOiBNbE5hdFxuZnVuY3Rpb24gZGVzZXJpYWxpemVfbmF0KHJlYWRlciwgc3ope1xuICB2YXIgbGVuID0gcmVhZGVyLnJlYWQzMnMoKTtcbiAgdmFyIG5hdCA9IG5ldyBNbE5hdChsZW4pO1xuICBmb3IodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspe1xuICAgIG5hdC5kYXRhW2ldID0gcmVhZGVyLnJlYWQzMnMoKTtcbiAgfVxuICBzelswXSA9IGxlbiAqIDQ7XG4gIHJldHVybiBuYXQ7XG59XG4iLCIvLyBKc19vZl9vY2FtbCBydW50aW1lIHN1cHBvcnRcbi8vIGh0dHA6Ly93d3cub2NzaWdlbi5vcmcvanNfb2Zfb2NhbWwvXG4vLyBDb3B5cmlnaHQgKEMpIDIwMTQgSsOpcsO0bWUgVm91aWxsb24sIEh1Z28gSGV1emFyZFxuLy8gTGFib3JhdG9pcmUgUFBTIC0gQ05SUyBVbml2ZXJzaXTDqSBQYXJpcyBEaWRlcm90XG4vL1xuLy8gVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbi8vIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuLy8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgd2l0aCBsaW5raW5nIGV4Y2VwdGlvbjtcbi8vIGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vXG4vLyBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4vLyBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2Vcbi8vIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLlxuXG4vL1Byb3ZpZGVzOiBmc19ub2RlX3N1cHBvcnRlZFxuZnVuY3Rpb24gZnNfbm9kZV9zdXBwb3J0ZWQgKCkge1xuICByZXR1cm4gKFxuICAgIHR5cGVvZiBnbG9iYWxUaGlzLnByb2Nlc3MgIT09ICd1bmRlZmluZWQnXG4gICAgICAmJiB0eXBlb2YgZ2xvYmFsVGhpcy5wcm9jZXNzLnZlcnNpb25zICE9PSAndW5kZWZpbmVkJ1xuICAgICAgJiYgdHlwZW9mIGdsb2JhbFRoaXMucHJvY2Vzcy52ZXJzaW9ucy5ub2RlICE9PSAndW5kZWZpbmVkJylcbn1cbi8vUHJvdmlkZXM6IGZzX25vZGVfc3VwcG9ydGVkXG4vL0lmOiBicm93c2VyXG5mdW5jdGlvbiBmc19ub2RlX3N1cHBvcnRlZCAoKSB7XG4gIHJldHVybiBmYWxzZVxufVxuXG5cbi8vUHJvdmlkZXM6IE1sTm9kZURldmljZVxuLy9SZXF1aXJlczogTWxOb2RlRmQsIGNhbWxfcmFpc2Vfc3lzX2Vycm9yLCBjYW1sX3JhaXNlX3dpdGhfYXJnc1xuLy9SZXF1aXJlczogbWFrZV91bml4X2Vycl9hcmdzLCBjYW1sX25hbWVkX3ZhbHVlLCBjYW1sX3N0cmluZ19vZl9qc3N0cmluZ1xuZnVuY3Rpb24gTWxOb2RlRGV2aWNlKHJvb3QpIHtcbiAgdGhpcy5mcyA9IHJlcXVpcmUoJ2ZzJyk7XG4gIHRoaXMucm9vdCA9IHJvb3Q7XG59XG5NbE5vZGVEZXZpY2UucHJvdG90eXBlLm5tID0gZnVuY3Rpb24obmFtZSkge1xuICByZXR1cm4gKHRoaXMucm9vdCArIG5hbWUpO1xufVxuTWxOb2RlRGV2aWNlLnByb3RvdHlwZS5leGlzdHMgPSBmdW5jdGlvbihuYW1lKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHRoaXMuZnMuZXhpc3RzU3luYyh0aGlzLm5tKG5hbWUpKT8xOjA7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHJldHVybiAwO1xuICB9XG59XG5NbE5vZGVEZXZpY2UucHJvdG90eXBlLmlzRmlsZSA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gdGhpcy5mcy5zdGF0U3luYyh0aGlzLm5tKG5hbWUpKS5pc0ZpbGUoKT8xOjA7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGNhbWxfcmFpc2Vfc3lzX2Vycm9yKGVyci50b1N0cmluZygpKTtcbiAgfVxufVxuTWxOb2RlRGV2aWNlLnByb3RvdHlwZS5ta2RpciA9IGZ1bmN0aW9uKG5hbWUsIG1vZGUsIHJhaXNlX3VuaXgpIHtcbiAgdHJ5IHtcbiAgICB0aGlzLmZzLm1rZGlyU3luYyh0aGlzLm5tKG5hbWUpLHttb2RlOm1vZGV9KTtcbiAgICByZXR1cm4gMFxuICB9IGNhdGNoIChlcnIpIHtcbiAgICB0aGlzLnJhaXNlX25vZGVqc19lcnJvcihlcnIsIHJhaXNlX3VuaXgpO1xuICB9XG59XG5NbE5vZGVEZXZpY2UucHJvdG90eXBlLnJtZGlyID0gZnVuY3Rpb24obmFtZSwgcmFpc2VfdW5peCkge1xuICB0cnkge1xuICAgIHRoaXMuZnMucm1kaXJTeW5jKHRoaXMubm0obmFtZSkpO1xuICAgIHJldHVybiAwXG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHRoaXMucmFpc2Vfbm9kZWpzX2Vycm9yKGVyciwgcmFpc2VfdW5peCk7XG4gIH1cbn1cbk1sTm9kZURldmljZS5wcm90b3R5cGUucmVhZGRpciA9IGZ1bmN0aW9uKG5hbWUsIHJhaXNlX3VuaXgpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gdGhpcy5mcy5yZWFkZGlyU3luYyh0aGlzLm5tKG5hbWUpKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgdGhpcy5yYWlzZV9ub2RlanNfZXJyb3IoZXJyLCByYWlzZV91bml4KTtcbiAgfVxufVxuTWxOb2RlRGV2aWNlLnByb3RvdHlwZS5pc19kaXIgPSBmdW5jdGlvbihuYW1lKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHRoaXMuZnMuc3RhdFN5bmModGhpcy5ubShuYW1lKSkuaXNEaXJlY3RvcnkoKT8xOjA7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGNhbWxfcmFpc2Vfc3lzX2Vycm9yKGVyci50b1N0cmluZygpKTtcbiAgfVxufVxuTWxOb2RlRGV2aWNlLnByb3RvdHlwZS51bmxpbmsgPSBmdW5jdGlvbihuYW1lLCByYWlzZV91bml4KSB7XG4gIHRyeSB7XG4gICAgdmFyIGIgPSB0aGlzLmZzLmV4aXN0c1N5bmModGhpcy5ubShuYW1lKSk/MTowO1xuICAgIHRoaXMuZnMudW5saW5rU3luYyh0aGlzLm5tKG5hbWUpKTtcbiAgICByZXR1cm4gYjtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgdGhpcy5yYWlzZV9ub2RlanNfZXJyb3IoZXJyLCByYWlzZV91bml4KTtcbiAgfVxufVxuTWxOb2RlRGV2aWNlLnByb3RvdHlwZS5vcGVuID0gZnVuY3Rpb24obmFtZSwgZiwgcmFpc2VfdW5peCkge1xuICB2YXIgY29uc3RzID0gcmVxdWlyZSgnY29uc3RhbnRzJyk7XG4gIHZhciByZXMgPSAwO1xuICBmb3IodmFyIGtleSBpbiBmKXtcbiAgICBzd2l0Y2goa2V5KXtcbiAgICBjYXNlIFwicmRvbmx5XCIgIDogcmVzIHw9IGNvbnN0cy5PX1JET05MWTsgYnJlYWs7XG4gICAgY2FzZSBcIndyb25seVwiICA6IHJlcyB8PSBjb25zdHMuT19XUk9OTFk7IGJyZWFrO1xuICAgIGNhc2UgXCJhcHBlbmRcIiAgOlxuICAgICAgcmVzIHw9IGNvbnN0cy5PX1dST05MWSB8IGNvbnN0cy5PX0FQUEVORDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgXCJjcmVhdGVcIiAgIDogcmVzIHw9IGNvbnN0cy5PX0NSRUFUOyAgICBicmVhaztcbiAgICBjYXNlIFwidHJ1bmNhdGVcIiA6IHJlcyB8PSBjb25zdHMuT19UUlVOQzsgICAgYnJlYWs7XG4gICAgY2FzZSBcImV4Y2xcIiAgICAgOiByZXMgfD0gY29uc3RzLk9fRVhDTDsgICAgIGJyZWFrO1xuICAgIGNhc2UgXCJiaW5hcnlcIiAgIDogcmVzIHw9IGNvbnN0cy5PX0JJTkFSWTsgICBicmVhaztcbiAgICBjYXNlIFwidGV4dFwiICAgICA6IHJlcyB8PSBjb25zdHMuT19URVhUOyAgICAgYnJlYWs7XG4gICAgY2FzZSBcIm5vbmJsb2NrXCIgOiByZXMgfD0gY29uc3RzLk9fTk9OQkxPQ0s7IGJyZWFrO1xuICAgIH1cbiAgfVxuICB0cnkge1xuICAgIHZhciBmZCA9IHRoaXMuZnMub3BlblN5bmModGhpcy5ubShuYW1lKSwgcmVzKTtcbiAgICB2YXIgaXNDaGFyYWN0ZXJEZXZpY2UgPSB0aGlzLmZzLmxzdGF0U3luYyh0aGlzLm5tKG5hbWUpKS5pc0NoYXJhY3RlckRldmljZSgpO1xuICAgIGYuaXNDaGFyYWN0ZXJEZXZpY2UgPSBpc0NoYXJhY3RlckRldmljZTtcbiAgICByZXR1cm4gbmV3IE1sTm9kZUZkKGZkLCBmKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgdGhpcy5yYWlzZV9ub2RlanNfZXJyb3IoZXJyLCByYWlzZV91bml4KTtcbiAgfVxufVxuXG5NbE5vZGVEZXZpY2UucHJvdG90eXBlLnJlbmFtZSA9IGZ1bmN0aW9uKG8sIG4sIHJhaXNlX3VuaXgpIHtcbiAgdHJ5IHtcbiAgICB0aGlzLmZzLnJlbmFtZVN5bmModGhpcy5ubShvKSwgdGhpcy5ubShuKSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHRoaXMucmFpc2Vfbm9kZWpzX2Vycm9yKGVyciwgcmFpc2VfdW5peCk7XG4gIH1cbn1cbk1sTm9kZURldmljZS5wcm90b3R5cGUuc3RhdCA9IGZ1bmN0aW9uKG5hbWUsIHJhaXNlX3VuaXgpIHtcbiAgdHJ5IHtcbiAgICB2YXIganNfc3RhdHMgPSB0aGlzLmZzLnN0YXRTeW5jKHRoaXMubm0obmFtZSkpO1xuICAgIHJldHVybiB0aGlzLnN0YXRzX2Zyb21fanMoanNfc3RhdHMpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICB0aGlzLnJhaXNlX25vZGVqc19lcnJvcihlcnIsIHJhaXNlX3VuaXgpO1xuICB9XG59XG5NbE5vZGVEZXZpY2UucHJvdG90eXBlLmxzdGF0ID0gZnVuY3Rpb24obmFtZSwgcmFpc2VfdW5peCkge1xuICB0cnkge1xuICAgIHZhciBqc19zdGF0cyA9IHRoaXMuZnMubHN0YXRTeW5jKHRoaXMubm0obmFtZSkpO1xuICAgIHJldHVybiB0aGlzLnN0YXRzX2Zyb21fanMoanNfc3RhdHMpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICB0aGlzLnJhaXNlX25vZGVqc19lcnJvcihlcnIsIHJhaXNlX3VuaXgpO1xuICB9XG59XG5NbE5vZGVEZXZpY2UucHJvdG90eXBlLnN5bWxpbmsgPSBmdW5jdGlvbih0b19kaXIsIHRhcmdldCwgcGF0aCwgcmFpc2VfdW5peCkge1xuICB0cnkge1xuICAgIHRoaXMuZnMuc3ltbGlua1N5bmModGhpcy5ubSh0YXJnZXQpLCB0aGlzLm5tKHBhdGgpLCB0b19kaXIgPyAnZGlyJyA6ICdmaWxlJyk7XG4gICAgcmV0dXJuIDA7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHRoaXMucmFpc2Vfbm9kZWpzX2Vycm9yKGVyciwgcmFpc2VfdW5peCk7XG4gIH1cbn1cbk1sTm9kZURldmljZS5wcm90b3R5cGUucmVhZGxpbmsgPSBmdW5jdGlvbihuYW1lLCByYWlzZV91bml4KSB7XG4gIHRyeSB7XG4gICAgdmFyIGxpbmsgPSB0aGlzLmZzLnJlYWRsaW5rU3luYyh0aGlzLm5tKG5hbWUpLCAndXRmOCcpO1xuICAgIHJldHVybiBjYW1sX3N0cmluZ19vZl9qc3N0cmluZyhsaW5rKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgdGhpcy5yYWlzZV9ub2RlanNfZXJyb3IoZXJyLCByYWlzZV91bml4KTtcbiAgfVxufVxuTWxOb2RlRGV2aWNlLnByb3RvdHlwZS5vcGVuZGlyID0gZnVuY3Rpb24obmFtZSwgcmFpc2VfdW5peCkge1xuICB0cnkge1xuICAgIHJldHVybiB0aGlzLmZzLm9wZW5kaXJTeW5jKHRoaXMubm0obmFtZSkpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICB0aGlzLnJhaXNlX25vZGVqc19lcnJvcihlcnIsIHJhaXNlX3VuaXgpO1xuICB9XG59XG5NbE5vZGVEZXZpY2UucHJvdG90eXBlLnJhaXNlX25vZGVqc19lcnJvciA9IGZ1bmN0aW9uKGVyciwgcmFpc2VfdW5peCkge1xuICB2YXIgdW5peF9lcnJvciA9IGNhbWxfbmFtZWRfdmFsdWUoXCJVbml4LlVuaXhfZXJyb3JcIik7XG4gIGlmIChyYWlzZV91bml4ICYmIHVuaXhfZXJyb3IpIHtcbiAgICB2YXIgYXJncyA9IG1ha2VfdW5peF9lcnJfYXJncyhlcnIuY29kZSwgZXJyLnN5c2NhbGwsIGVyci5wYXRoLCBlcnIuZXJybm8pO1xuICAgIGNhbWxfcmFpc2Vfd2l0aF9hcmdzKHVuaXhfZXJyb3IsIGFyZ3MpO1xuICB9IGVsc2Uge1xuICAgIGNhbWxfcmFpc2Vfc3lzX2Vycm9yKGVyci50b1N0cmluZygpKTtcbiAgfVxufVxuTWxOb2RlRGV2aWNlLnByb3RvdHlwZS5zdGF0c19mcm9tX2pzID0gZnVuY3Rpb24oanNfc3RhdHMpIHtcbiAgLyogPT09VW5peC5maWxlX2tpbmQ9PT1cbiAgICogdHlwZSBmaWxlX2tpbmQgPVxuICAgKiAgICAgU19SRUcgICAgICAgICAgICAgICAgICAgICAgICgqKiBSZWd1bGFyIGZpbGUgKilcbiAgICogICB8IFNfRElSICAgICAgICAgICAgICAgICAgICAgICAoKiogRGlyZWN0b3J5ICopXG4gICAqICAgfCBTX0NIUiAgICAgICAgICAgICAgICAgICAgICAgKCoqIENoYXJhY3RlciBkZXZpY2UgKilcbiAgICogICB8IFNfQkxLICAgICAgICAgICAgICAgICAgICAgICAoKiogQmxvY2sgZGV2aWNlICopXG4gICAqICAgfCBTX0xOSyAgICAgICAgICAgICAgICAgICAgICAgKCoqIFN5bWJvbGljIGxpbmsgKilcbiAgICogICB8IFNfRklGTyAgICAgICAgICAgICAgICAgICAgICAoKiogTmFtZWQgcGlwZSAqKVxuICAgKiAgIHwgU19TT0NLICAgICAgICAgICAgICAgICAgICAgICgqKiBTb2NrZXQgKilcbiAgICovXG4gIHZhciBmaWxlX2tpbmQ7XG4gIGlmIChqc19zdGF0cy5pc0ZpbGUoKSkge1xuICAgIGZpbGVfa2luZCA9IDA7XG4gIH0gZWxzZSBpZiAoanNfc3RhdHMuaXNEaXJlY3RvcnkoKSkge1xuICAgIGZpbGVfa2luZCA9IDE7XG4gIH0gZWxzZSBpZiAoanNfc3RhdHMuaXNDaGFyYWN0ZXJEZXZpY2UoKSkge1xuICAgIGZpbGVfa2luZCA9IDI7XG4gIH0gZWxzZSBpZiAoanNfc3RhdHMuaXNCbG9ja0RldmljZSgpKSB7XG4gICAgZmlsZV9raW5kID0gMztcbiAgfSBlbHNlIGlmIChqc19zdGF0cy5pc1N5bWJvbGljTGluaygpKSB7XG4gICAgZmlsZV9raW5kID0gNDtcbiAgfSBlbHNlIGlmIChqc19zdGF0cy5pc0ZJRk8oKSkge1xuICAgIGZpbGVfa2luZCA9IDU7XG4gIH0gZWxzZSBpZiAoanNfc3RhdHMuaXNTb2NrZXQoKSkge1xuICAgIGZpbGVfa2luZCA9IDY7XG4gIH1cbiAgLyogPT09VW5peC5zdGF0cz09PVxuICAgKiB0eXBlIHN0YXRzID1cbiAgICogIHsgc3RfZGV2IDogaW50OyAgICAgICAgICAgICAgICgqKiBEZXZpY2UgbnVtYmVyICopXG4gICAqICAgIHN0X2lubyA6IGludDsgICAgICAgICAgICAgICAoKiogSW5vZGUgbnVtYmVyICopXG4gICAqICAgIHN0X2tpbmQgOiBmaWxlX2tpbmQ7ICAgICAgICAoKiogS2luZCBvZiB0aGUgZmlsZSAqKVxuICAgKiAgICBzdF9wZXJtIDogZmlsZV9wZXJtOyAgICAgICAgKCoqIEFjY2VzcyByaWdodHMgKilcbiAgICogICAgc3RfbmxpbmsgOiBpbnQ7ICAgICAgICAgICAgICgqKiBOdW1iZXIgb2YgbGlua3MgKilcbiAgICogICAgc3RfdWlkIDogaW50OyAgICAgICAgICAgICAgICgqKiBVc2VyIGlkIG9mIHRoZSBvd25lciAqKVxuICAgKiAgICBzdF9naWQgOiBpbnQ7ICAgICAgICAgICAgICAgKCoqIEdyb3VwIElEIG9mIHRoZSBmaWxlJ3MgZ3JvdXAgKilcbiAgICogICAgc3RfcmRldiA6IGludDsgICAgICAgICAgICAgICgqKiBEZXZpY2UgSUQgKGlmIHNwZWNpYWwgZmlsZSkgKilcbiAgICogICAgc3Rfc2l6ZSA6IGludDsgICAgICAgICAgICAgICgqKiBTaXplIGluIGJ5dGVzICopXG4gICAqICAgIHN0X2F0aW1lIDogZmxvYXQ7ICAgICAgICAgICAoKiogTGFzdCBhY2Nlc3MgdGltZSAqKVxuICAgKiAgICBzdF9tdGltZSA6IGZsb2F0OyAgICAgICAgICAgKCoqIExhc3QgbW9kaWZpY2F0aW9uIHRpbWUgKilcbiAgICogICAgc3RfY3RpbWUgOiBmbG9hdDsgICAgICAgICAgICgqKiBMYXN0IHN0YXR1cyBjaGFuZ2UgdGltZSAqKVxuICAgKiAgfVxuICAgKi9cbiAgcmV0dXJuIEJMT0NLKFxuICAgIDAsXG4gICAganNfc3RhdHMuZGV2LFxuICAgIGpzX3N0YXRzLmlubyxcbiAgICBmaWxlX2tpbmQsXG4gICAganNfc3RhdHMubW9kZSxcbiAgICBqc19zdGF0cy5ubGluayxcbiAgICBqc19zdGF0cy51aWQsXG4gICAganNfc3RhdHMuZ2lkLFxuICAgIGpzX3N0YXRzLnJkZXYsXG4gICAganNfc3RhdHMuc2l6ZSxcbiAgICBqc19zdGF0cy5hdGltZU1zLFxuICAgIGpzX3N0YXRzLm10aW1lTXMsXG4gICAganNfc3RhdHMuY3RpbWVNc1xuICApO1xufVxuXG5NbE5vZGVEZXZpY2UucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gTWxOb2RlRGV2aWNlXG5cbi8vUHJvdmlkZXM6IE1sTm9kZURldmljZVxuLy9JZjogYnJvd3NlclxuZnVuY3Rpb24gTWxOb2RlRGV2aWNlKCkge1xufVxuXG4vL1Byb3ZpZGVzOiBNbE5vZGVGZFxuLy9SZXF1aXJlczogTWxGaWxlLCBjYW1sX3VpbnQ4X2FycmF5X29mX3N0cmluZywgY2FtbF91aW50OF9hcnJheV9vZl9ieXRlcywgY2FtbF9ieXRlc19zZXQsIGNhbWxfcmFpc2Vfc3lzX2Vycm9yXG5mdW5jdGlvbiBNbE5vZGVGZChmZCwgZmxhZ3Mpe1xuICB0aGlzLmZzID0gcmVxdWlyZSgnZnMnKTtcbiAgdGhpcy5mZCA9IGZkO1xuICB0aGlzLmZsYWdzID0gZmxhZ3M7XG59XG5NbE5vZGVGZC5wcm90b3R5cGUgPSBuZXcgTWxGaWxlICgpO1xuTWxOb2RlRmQucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gTWxOb2RlRmQ7XG5cbk1sTm9kZUZkLnByb3RvdHlwZS50cnVuY2F0ZSA9IGZ1bmN0aW9uKGxlbil7XG4gIHRyeSB7XG4gICAgdGhpcy5mcy5mdHJ1bmNhdGVTeW5jKHRoaXMuZmQsbGVufDApO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBjYW1sX3JhaXNlX3N5c19lcnJvcihlcnIudG9TdHJpbmcoKSk7XG4gIH1cbn1cbk1sTm9kZUZkLnByb3RvdHlwZS5sZW5ndGggPSBmdW5jdGlvbiAoKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHRoaXMuZnMuZnN0YXRTeW5jKHRoaXMuZmQpLnNpemU7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGNhbWxfcmFpc2Vfc3lzX2Vycm9yKGVyci50b1N0cmluZygpKTtcbiAgfVxufVxuTWxOb2RlRmQucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24ob2Zmc2V0LGJ1ZixidWZfb2Zmc2V0LGxlbil7XG4gIHRyeSB7XG4gICAgaWYodGhpcy5mbGFncy5pc0NoYXJhY3RlckRldmljZSlcbiAgICAgIHRoaXMuZnMud3JpdGVTeW5jKHRoaXMuZmQsIGJ1ZiwgYnVmX29mZnNldCwgbGVuKTtcbiAgICBlbHNlXG4gICAgICB0aGlzLmZzLndyaXRlU3luYyh0aGlzLmZkLCBidWYsIGJ1Zl9vZmZzZXQsIGxlbiwgb2Zmc2V0KTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgY2FtbF9yYWlzZV9zeXNfZXJyb3IoZXJyLnRvU3RyaW5nKCkpO1xuICB9XG4gIHJldHVybiAwO1xufVxuTWxOb2RlRmQucHJvdG90eXBlLnJlYWQgPSBmdW5jdGlvbihvZmZzZXQsYSxidWZfb2Zmc2V0LGxlbil7XG4gIHRyeSB7XG4gICAgaWYodGhpcy5mbGFncy5pc0NoYXJhY3RlckRldmljZSlcbiAgICAgIHZhciByZWFkID0gdGhpcy5mcy5yZWFkU3luYyh0aGlzLmZkLCBhLCBidWZfb2Zmc2V0LCBsZW4pO1xuICAgIGVsc2VcbiAgICAgIHZhciByZWFkID0gdGhpcy5mcy5yZWFkU3luYyh0aGlzLmZkLCBhLCBidWZfb2Zmc2V0LCBsZW4sIG9mZnNldCk7XG4gICAgcmV0dXJuIHJlYWQ7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGNhbWxfcmFpc2Vfc3lzX2Vycm9yKGVyci50b1N0cmluZygpKTtcbiAgfVxufVxuTWxOb2RlRmQucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24oKXtcbiAgdHJ5IHtcbiAgICB0aGlzLmZzLmNsb3NlU3luYyh0aGlzLmZkKTtcbiAgICByZXR1cm4gMFxuICB9IGNhdGNoIChlcnIpIHtcbiAgICBjYW1sX3JhaXNlX3N5c19lcnJvcihlcnIudG9TdHJpbmcoKSk7XG4gIH1cbn1cblxuXG4vL1Byb3ZpZGVzOiBNbE5vZGVGZFxuLy9JZjogYnJvd3NlclxuZnVuY3Rpb24gTWxOb2RlRmQoKXtcbn1cblxuXG4vL1Byb3ZpZGVzOiBjYW1sX3N5c19vcGVuX2Zvcl9ub2RlXG4vL1JlcXVpcmVzOiBNbE5vZGVGZFxuZnVuY3Rpb24gY2FtbF9zeXNfb3Blbl9mb3Jfbm9kZShmZCwgZmxhZ3Mpe1xuICBpZihmbGFncy5uYW1lKSB7XG4gICAgdHJ5IHtcbiAgICAgIHZhciBmcyA9IHJlcXVpcmUoXCJmc1wiKTtcbiAgICAgIHZhciBmZDIgPSBmcy5vcGVuU3luYyhmbGFncy5uYW1lLCBcInJzXCIpO1xuICAgICAgcmV0dXJuIG5ldyBNbE5vZGVGZChmZDIsIGZsYWdzKTtcbiAgICB9IGNhdGNoKGUpIHsgIH1cbiAgfVxuICByZXR1cm4gbmV3IE1sTm9kZUZkKGZkLCBmbGFncyk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3lzX29wZW5fZm9yX25vZGVcbi8vSWY6IGJyb3dzZXJcbmZ1bmN0aW9uIGNhbWxfc3lzX29wZW5fZm9yX25vZGUoZmQsIGZsYWdzKXtcbiAgcmV0dXJuIG51bGw7XG59XG4iLCIvLy8vLy8vLy8gQklHU1RSSU5HXG5cbi8vUHJvdmlkZXM6IGNhbWxfaGFzaF9taXhfYmlnc3RyaW5nXG4vL1JlcXVpcmVzOiBjYW1sX2hhc2hfbWl4X2J5dGVzX2FyclxuZnVuY3Rpb24gY2FtbF9oYXNoX21peF9iaWdzdHJpbmcoaCwgYnMpIHtcbiAgcmV0dXJuIGNhbWxfaGFzaF9taXhfYnl0ZXNfYXJyKGgsYnMuZGF0YSk7XG59XG5cbi8vUHJvdmlkZXM6IGJpZ3N0cmluZ190b19hcnJheV9idWZmZXIgbXV0YWJsZVxuZnVuY3Rpb24gYmlnc3RyaW5nX3RvX2FycmF5X2J1ZmZlcihicykge1xuICByZXR1cm4gYnMuZGF0YS5idWZmZXJcbn1cblxuLy9Qcm92aWRlczogYmlnc3RyaW5nX3RvX3R5cGVkX2FycmF5IG11dGFibGVcbmZ1bmN0aW9uIGJpZ3N0cmluZ190b190eXBlZF9hcnJheShicykge1xuICByZXR1cm4gYnMuZGF0YVxufVxuXG4vL1Byb3ZpZGVzOiBiaWdzdHJpbmdfb2ZfYXJyYXlfYnVmZmVyIG11dGFibGVcbi8vUmVxdWlyZXM6IGNhbWxfYmFfY3JlYXRlX3Vuc2FmZVxuZnVuY3Rpb24gYmlnc3RyaW5nX29mX2FycmF5X2J1ZmZlcihhYikge1xuICB2YXIgdGEgPSBuZXcgVWludDhBcnJheShhYik7XG4gIHJldHVybiBjYW1sX2JhX2NyZWF0ZV91bnNhZmUoMTIsIDAsIFt0YS5sZW5ndGhdLCB0YSk7XG59XG5cbi8vUHJvdmlkZXM6IGJpZ3N0cmluZ19vZl90eXBlZF9hcnJheSBtdXRhYmxlXG4vL1JlcXVpcmVzOiBjYW1sX2JhX2NyZWF0ZV91bnNhZmVcbmZ1bmN0aW9uIGJpZ3N0cmluZ19vZl90eXBlZF9hcnJheShiYSkge1xuICB2YXIgdGEgPSBuZXcgVWludDhBcnJheShiYS5idWZmZXIsIGJhLmJ5dGVPZmZzZXQsIGJhLmxlbmd0aCAqIGJhLkJZVEVTX1BFUl9FTEVNRU5UKTtcbiAgcmV0dXJuIGNhbWxfYmFfY3JlYXRlX3Vuc2FmZSgxMiwgMCwgW3RhLmxlbmd0aF0sIHRhKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iaWdzdHJpbmdfbWVtY21wXG4vL1JlcXVpcmVzOiBjYW1sX2JhX2dldF8xXG5mdW5jdGlvbiBjYW1sX2JpZ3N0cmluZ19tZW1jbXAoczEsIHBvczEsIHMyLCBwb3MyLCBsZW4pe1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgdmFyIGEgPSBjYW1sX2JhX2dldF8xKHMxLHBvczEgKyBpKTtcbiAgICB2YXIgYiA9IGNhbWxfYmFfZ2V0XzEoczIscG9zMiArIGkpO1xuICAgIGlmIChhIDwgYikgcmV0dXJuIC0xO1xuICAgIGlmIChhID4gYikgcmV0dXJuIDE7XG4gIH1cbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfYmlnc3RyaW5nX2JsaXRfYmFfdG9fYmFcbi8vUmVxdWlyZXM6IGNhbWxfaW52YWxpZF9hcmd1bWVudCwgY2FtbF9hcnJheV9ib3VuZF9lcnJvclxuZnVuY3Rpb24gY2FtbF9iaWdzdHJpbmdfYmxpdF9iYV90b19iYShiYTEsIHBvczEsIGJhMiwgcG9zMiwgbGVuKXtcbiAgaWYoMTIgIT0gYmExLmtpbmQpXG4gICAgY2FtbF9pbnZhbGlkX2FyZ3VtZW50KFwiY2FtbF9iaWdzdHJpbmdfYmxpdF9iYV90b19iYToga2luZCBtaXNtYXRjaFwiKTtcbiAgaWYoMTIgIT0gYmEyLmtpbmQpXG4gICAgY2FtbF9pbnZhbGlkX2FyZ3VtZW50KFwiY2FtbF9iaWdzdHJpbmdfYmxpdF9iYV90b19iYToga2luZCBtaXNtYXRjaFwiKTtcbiAgaWYobGVuID09IDApIHJldHVybiAwO1xuICB2YXIgb2ZzMSA9IGJhMS5vZmZzZXQocG9zMSk7XG4gIHZhciBvZnMyID0gYmEyLm9mZnNldChwb3MyKTtcbiAgaWYob2ZzMSArIGxlbiA+IGJhMS5kYXRhLmxlbmd0aCl7XG4gICAgY2FtbF9hcnJheV9ib3VuZF9lcnJvcigpO1xuICB9XG4gIGlmKG9mczIgKyBsZW4gPiBiYTIuZGF0YS5sZW5ndGgpe1xuICAgIGNhbWxfYXJyYXlfYm91bmRfZXJyb3IoKTtcbiAgfVxuICB2YXIgc2xpY2UgPSBiYTEuZGF0YS5zdWJhcnJheShvZnMxLG9mczErbGVuKTtcbiAgYmEyLmRhdGEuc2V0KHNsaWNlLHBvczIpO1xuICByZXR1cm4gMFxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2JpZ3N0cmluZ19ibGl0X3N0cmluZ190b19iYVxuLy9SZXF1aXJlczogY2FtbF9pbnZhbGlkX2FyZ3VtZW50LCBjYW1sX2FycmF5X2JvdW5kX2Vycm9yLCBjYW1sX3VpbnQ4X2FycmF5X29mX3N0cmluZ1xuLy9SZXF1aXJlczogY2FtbF9tbF9zdHJpbmdfbGVuZ3RoXG5mdW5jdGlvbiBjYW1sX2JpZ3N0cmluZ19ibGl0X3N0cmluZ190b19iYShzdHIxLCBwb3MxLCBiYTIsIHBvczIsIGxlbil7XG4gIGlmKDEyICE9IGJhMi5raW5kKVxuICAgIGNhbWxfaW52YWxpZF9hcmd1bWVudChcImNhbWxfYmlnc3RyaW5nX2JsaXRfc3RyaW5nX3RvX2JhOiBraW5kIG1pc21hdGNoXCIpO1xuICBpZihsZW4gPT0gMCkgcmV0dXJuIDA7XG4gIHZhciBvZnMyID0gYmEyLm9mZnNldChwb3MyKTtcbiAgaWYocG9zMSArIGxlbiA+IGNhbWxfbWxfc3RyaW5nX2xlbmd0aChzdHIxKSkge1xuICAgIGNhbWxfYXJyYXlfYm91bmRfZXJyb3IoKTtcbiAgfVxuICBpZihvZnMyICsgbGVuID4gYmEyLmRhdGEubGVuZ3RoKSB7XG4gICAgY2FtbF9hcnJheV9ib3VuZF9lcnJvcigpO1xuICB9XG4gIHZhciBzbGljZSA9IGNhbWxfdWludDhfYXJyYXlfb2Zfc3RyaW5nKHN0cjEpLnNsaWNlKHBvczEscG9zMSArIGxlbik7XG4gIGJhMi5kYXRhLnNldChzbGljZSxvZnMyKTtcbiAgcmV0dXJuIDBcbn1cblxuLy9Qcm92aWRlczogY2FtbF9iaWdzdHJpbmdfYmxpdF9ieXRlc190b19iYVxuLy9SZXF1aXJlczogY2FtbF9pbnZhbGlkX2FyZ3VtZW50LCBjYW1sX2FycmF5X2JvdW5kX2Vycm9yLCBjYW1sX3VpbnQ4X2FycmF5X29mX2J5dGVzXG4vL1JlcXVpcmVzOiBjYW1sX21sX2J5dGVzX2xlbmd0aFxuZnVuY3Rpb24gY2FtbF9iaWdzdHJpbmdfYmxpdF9ieXRlc190b19iYShzdHIxLCBwb3MxLCBiYTIsIHBvczIsIGxlbil7XG4gIGlmKDEyICE9IGJhMi5raW5kKVxuICAgIGNhbWxfaW52YWxpZF9hcmd1bWVudChcImNhbWxfYmlnc3RyaW5nX2JsaXRfc3RyaW5nX3RvX2JhOiBraW5kIG1pc21hdGNoXCIpO1xuICBpZihsZW4gPT0gMCkgcmV0dXJuIDA7XG4gIHZhciBvZnMyID0gYmEyLm9mZnNldChwb3MyKTtcbiAgaWYocG9zMSArIGxlbiA+IGNhbWxfbWxfYnl0ZXNfbGVuZ3RoKHN0cjEpKSB7XG4gICAgY2FtbF9hcnJheV9ib3VuZF9lcnJvcigpO1xuICB9XG4gIGlmKG9mczIgKyBsZW4gPiBiYTIuZGF0YS5sZW5ndGgpIHtcbiAgICBjYW1sX2FycmF5X2JvdW5kX2Vycm9yKCk7XG4gIH1cbiAgdmFyIHNsaWNlID0gY2FtbF91aW50OF9hcnJheV9vZl9ieXRlcyhzdHIxKS5zbGljZShwb3MxLHBvczEgKyBsZW4pO1xuICBiYTIuZGF0YS5zZXQoc2xpY2Usb2ZzMik7XG4gIHJldHVybiAwXG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfYmlnc3RyaW5nX2JsaXRfYmFfdG9fYnl0ZXNcbi8vUmVxdWlyZXM6IGNhbWxfaW52YWxpZF9hcmd1bWVudCwgY2FtbF9hcnJheV9ib3VuZF9lcnJvclxuLy9SZXF1aXJlczogY2FtbF9ibGl0X2J5dGVzLCBjYW1sX2J5dGVzX29mX2FycmF5XG4vL1JlcXVpcmVzOiBjYW1sX21sX2J5dGVzX2xlbmd0aFxuZnVuY3Rpb24gY2FtbF9iaWdzdHJpbmdfYmxpdF9iYV90b19ieXRlcyhiYTEsIHBvczEsIGJ5dGVzMiwgcG9zMiwgbGVuKXtcbiAgaWYoMTIgIT0gYmExLmtpbmQpXG4gICAgY2FtbF9pbnZhbGlkX2FyZ3VtZW50KFwiY2FtbF9iaWdzdHJpbmdfYmxpdF9zdHJpbmdfdG9fYmE6IGtpbmQgbWlzbWF0Y2hcIik7XG4gIGlmKGxlbiA9PSAwKSByZXR1cm4gMDtcbiAgdmFyIG9mczEgPSBiYTEub2Zmc2V0KHBvczEpO1xuICBpZihvZnMxICsgbGVuID4gYmExLmRhdGEubGVuZ3RoKXtcbiAgICBjYW1sX2FycmF5X2JvdW5kX2Vycm9yKCk7XG4gIH1cbiAgaWYocG9zMiArIGxlbiA+IGNhbWxfbWxfYnl0ZXNfbGVuZ3RoKGJ5dGVzMikpe1xuICAgIGNhbWxfYXJyYXlfYm91bmRfZXJyb3IoKTtcbiAgfVxuICB2YXIgc2xpY2UgPSBiYTEuZGF0YS5zbGljZShvZnMxLCBvZnMxK2xlbik7XG4gIGNhbWxfYmxpdF9ieXRlcyhjYW1sX2J5dGVzX29mX2FycmF5KHNsaWNlKSwgMCwgYnl0ZXMyLCBwb3MyLCBsZW4pO1xuICByZXR1cm4gMFxufVxuIiwiLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgQ29weXJpZ2h0IChjKSAyMDE3IEluaGFiaXRlZCBUeXBlIExMQy5cblxuICAgIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG5cbiAgICBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAgICBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnNcbiAgICBhcmUgbWV0OlxuXG4gICAgMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAgICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG5cbiAgICAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuICAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcbiAgICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuXG4gICAgMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgYXV0aG9yIG5vciB0aGUgbmFtZXMgb2YgaGlzIGNvbnRyaWJ1dG9yc1xuICAgICAgIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuICAgICAgIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuXG4gICAgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09OVFJJQlVUT1JTIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NcbiAgICBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRFxuICAgIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcbiAgICBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1JcbiAgICBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMXG4gICAgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFNcbiAgICBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTilcbiAgICBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsXG4gICAgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOXG4gICAgQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4gICAgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4vL1Byb3ZpZGVzOiBiaWdzdHJpbmdhZl9ibGl0X3RvX2J5dGVzXG4vL1JlcXVpcmVzOiBjYW1sX2JpZ3N0cmluZ19ibGl0X2JhX3RvX2J5dGVzXG5mdW5jdGlvbiBiaWdzdHJpbmdhZl9ibGl0X3RvX2J5dGVzKHNyYywgc3JjX29mZiwgZHN0LCBkc3Rfb2ZmLCBsZW4pIHtcbiAgcmV0dXJuIGNhbWxfYmlnc3RyaW5nX2JsaXRfYmFfdG9fYnl0ZXMoc3JjLHNyY19vZmYsZHN0LGRzdF9vZmYsbGVuKTtcbn1cblxuLy9Qcm92aWRlczogYmlnc3RyaW5nYWZfYmxpdF90b19iaWdzdHJpbmdcbi8vUmVxdWlyZXM6IGNhbWxfYmlnc3RyaW5nX2JsaXRfYmFfdG9fYmFcbmZ1bmN0aW9uIGJpZ3N0cmluZ2FmX2JsaXRfdG9fYmlnc3RyaW5nKHNyYywgc3JjX29mZiwgZHN0LCBkc3Rfb2ZmLCBsZW4pIHtcbiAgcmV0dXJuIGNhbWxfYmlnc3RyaW5nX2JsaXRfYmFfdG9fYmEoc3JjLCBzcmNfb2ZmLCBkc3QsIGRzdF9vZmYsIGxlbik7XG59XG5cbi8vUHJvdmlkZXM6IGJpZ3N0cmluZ2FmX2JsaXRfZnJvbV9ieXRlc1xuLy9SZXF1aXJlczogY2FtbF9iaWdzdHJpbmdfYmxpdF9zdHJpbmdfdG9fYmFcbmZ1bmN0aW9uIGJpZ3N0cmluZ2FmX2JsaXRfZnJvbV9ieXRlcyhzcmMsIHNyY19vZmYsIGRzdCwgZHN0X29mZiwgbGVuKSB7XG4gIHJldHVybiBjYW1sX2JpZ3N0cmluZ19ibGl0X3N0cmluZ190b19iYShzcmMsIHNyY19vZmYsIGRzdCwgZHN0X29mZiwgbGVuKTtcbn1cblxuLy9Qcm92aWRlczogYmlnc3RyaW5nYWZfbWVtY21wX2JpZ3N0cmluZ1xuLy9SZXF1aXJlczogY2FtbF9iYV9nZXRfMSwgY2FtbF9pbnRfY29tcGFyZVxuZnVuY3Rpb24gYmlnc3RyaW5nYWZfbWVtY21wX2JpZ3N0cmluZyhiYTEsIGJhMV9vZmYsIGJhMiwgYmEyX29mZiwgbGVuKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICB2YXIgYyA9IGNhbWxfaW50X2NvbXBhcmUoY2FtbF9iYV9nZXRfMShiYTEsIGJhMV9vZmYgKyBpKSwgY2FtbF9iYV9nZXRfMShiYTIsIGJhMl9vZmYgKyBpKSk7XG4gICAgaWYgKGMgIT0gMCkgcmV0dXJuIGNcbiAgfVxuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogYmlnc3RyaW5nYWZfbWVtY21wX3N0cmluZ1xuLy9SZXF1aXJlczogY2FtbF9iYV9nZXRfMSwgY2FtbF9pbnRfY29tcGFyZSwgY2FtbF9zdHJpbmdfdW5zYWZlX2dldFxuZnVuY3Rpb24gYmlnc3RyaW5nYWZfbWVtY21wX3N0cmluZyhiYSwgYmFfb2ZmLCBzdHIsIHN0cl9vZmYsIGxlbikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgdmFyIGMgPSBjYW1sX2ludF9jb21wYXJlKGNhbWxfYmFfZ2V0XzEoYmEsIGJhX29mZiArIGkpLCBjYW1sX3N0cmluZ191bnNhZmVfZ2V0KHN0ciwgc3RyX29mZiArIGkpKTtcbiAgICBpZiAoYyAhPSAwKSByZXR1cm4gY1xuICB9XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBiaWdzdHJpbmdhZl9tZW1jaHJcbi8vUmVxdWlyZXM6IGNhbWxfYmFfZ2V0XzFcbmZ1bmN0aW9uIGJpZ3N0cmluZ2FmX21lbWNocihiYSwgYmFfb2ZmLCBjaHIsIGxlbikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgaWYgKGNhbWxfYmFfZ2V0XzEoYmEsIGJhX29mZiArIGkpID09IGNocikge1xuICAgICAgcmV0dXJuIChiYV9vZmYgKyBpKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuIiwiLy8gSnNfb2Zfb2NhbWwgcnVudGltZSBzdXBwb3J0XG4vLyBodHRwOi8vd3d3Lm9jc2lnZW4ub3JnL2pzX29mX29jYW1sL1xuLy9cbi8vIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4vLyBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbi8vIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHdpdGggbGlua2luZyBleGNlcHRpb247XG4vLyBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vL1xuLy8gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuLy8gR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vL1xuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4vLyBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcsIFVTQS5cblxuLy9Qcm92aWRlczogY2FtbF9jb21wYXJlX3ZhbF90YWdcbi8vUmVxdWlyZXM6IGNhbWxfaXNfbWxfc3RyaW5nLCBjYW1sX2lzX21sX2J5dGVzXG5mdW5jdGlvbiBjYW1sX2NvbXBhcmVfdmFsX3RhZyhhKXtcbiAgaWYgKHR5cGVvZiBhID09PSBcIm51bWJlclwiKSByZXR1cm4gMTAwMDsgLy8gaW50X3RhZyAod2UgdXNlIGl0IGZvciBhbGwgbnVtYmVycylcbiAgZWxzZSBpZiAoY2FtbF9pc19tbF9ieXRlcyhhKSkgcmV0dXJuIDI1MjsgLy8gc3RyaW5nX3RhZ1xuICBlbHNlIGlmIChjYW1sX2lzX21sX3N0cmluZyhhKSkgcmV0dXJuIDEyNTI7IC8vIG9jYW1sIHN0cmluZyAoaWYgZGlmZmVyZW50IGZyb20gYnl0ZXMpXG4gIGVsc2UgaWYgKGEgaW5zdGFuY2VvZiBBcnJheSAmJiBhWzBdID09PSAoYVswXT4+PjApICYmIGFbMF0gPD0gMjU1KSB7XG4gICAgLy8gTG9vayBsaWtlIGFuIG9jYW1sIGJsb2NrXG4gICAgdmFyIHRhZyA9IGFbMF0gfCAwO1xuICAgIC8vIGlnbm9yZSBkb3VibGVfYXJyYXlfdGFnIGJlY2F1c2Ugd2UgY2Fubm90IGFjY3VyYXRlbHkgc2V0XG4gICAgLy8gdGhpcyB0YWcgd2hlbiB3ZSBjcmVhdGUgYW4gYXJyYXkgb2YgZmxvYXQuXG4gICAgcmV0dXJuICh0YWcgPT0gMjU0KT8wOnRhZ1xuICB9XG4gIGVsc2UgaWYgKGEgaW5zdGFuY2VvZiBTdHJpbmcpIHJldHVybiAxMjUyMDsgLy8gamF2YXNjcmlwdCBzdHJpbmcsIGxpa2Ugc3RyaW5nX3RhZyAoMjUyKVxuICBlbHNlIGlmICh0eXBlb2YgYSA9PSBcInN0cmluZ1wiKSByZXR1cm4gMTI1MjA7IC8vIGphdmFzY3JpcHQgc3RyaW5nLCBsaWtlIHN0cmluZ190YWcgKDI1MilcbiAgZWxzZSBpZiAoYSBpbnN0YW5jZW9mIE51bWJlcikgcmV0dXJuIDEwMDA7IC8vIGludF90YWcgKHdlIHVzZSBpdCBmb3IgYWxsIG51bWJlcnMpXG4gIGVsc2UgaWYgKGEgJiYgYS5jYW1sX2N1c3RvbSkgcmV0dXJuIDEyNTU7IC8vIGxpa2UgY3VzdG9tX3RhZyAoMjU1KVxuICBlbHNlIGlmIChhICYmIGEuY29tcGFyZSkgcmV0dXJuIDEyNTY7IC8vIGxpa2UgY3VzdG9tX3RhZyAoMjU1KVxuICBlbHNlIGlmICh0eXBlb2YgYSA9PSBcImZ1bmN0aW9uXCIpIHJldHVybiAxMjQ3OyAvLyBsaWtlIGNsb3N1cmVfdGFnICgyNDcpXG4gIGVsc2UgaWYgKHR5cGVvZiBhID09IFwic3ltYm9sXCIpIHJldHVybiAxMjUxO1xuICByZXR1cm4gMTAwMTsgLy9vdXRfb2ZfaGVhcF90YWdcbn1cblxuLy9Qcm92aWRlczogY2FtbF9jb21wYXJlX3ZhbF9nZXRfY3VzdG9tXG4vL1JlcXVpcmVzOiBjYW1sX2N1c3RvbV9vcHNcbmZ1bmN0aW9uIGNhbWxfY29tcGFyZV92YWxfZ2V0X2N1c3RvbShhKXtcbiAgcmV0dXJuIGNhbWxfY3VzdG9tX29wc1thLmNhbWxfY3VzdG9tXSAmJiBjYW1sX2N1c3RvbV9vcHNbYS5jYW1sX2N1c3RvbV0uY29tcGFyZTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9jb21wYXJlX3ZhbF9udW1iZXJfY3VzdG9tXG4vL1JlcXVpcmVzOiBjYW1sX2NvbXBhcmVfdmFsX2dldF9jdXN0b21cbmZ1bmN0aW9uIGNhbWxfY29tcGFyZV92YWxfbnVtYmVyX2N1c3RvbShudW0sIGN1c3RvbSwgc3dhcCwgdG90YWwpIHtcbiAgdmFyIGNvbXAgPSBjYW1sX2NvbXBhcmVfdmFsX2dldF9jdXN0b20oY3VzdG9tKTtcbiAgaWYoY29tcCkge1xuICAgIHZhciB4ID0gKHN3YXAgPiAwKT9jb21wKGN1c3RvbSxudW0sdG90YWwpOmNvbXAobnVtLGN1c3RvbSx0b3RhbCk7XG4gICAgaWYodG90YWwgJiYgeCAhPSB4KSByZXR1cm4gc3dhcDsgLy8gdG90YWwgJiYgbmFuXG4gICAgaWYoK3ggIT0gK3gpIHJldHVybiAreDsgLy8gbmFuXG4gICAgaWYoKHggfCAwKSAhPSAwKSByZXR1cm4gKHggfCAwKTsgLy8gIW5hblxuICB9XG4gIHJldHVybiBzd2FwXG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfY29tcGFyZV92YWwgKGNvbnN0LCBjb25zdCwgY29uc3QpXG4vL1JlcXVpcmVzOiBjYW1sX2ludF9jb21wYXJlLCBjYW1sX3N0cmluZ19jb21wYXJlLCBjYW1sX2J5dGVzX2NvbXBhcmVcbi8vUmVxdWlyZXM6IGNhbWxfaW52YWxpZF9hcmd1bWVudCwgY2FtbF9jb21wYXJlX3ZhbF9nZXRfY3VzdG9tLCBjYW1sX2NvbXBhcmVfdmFsX3RhZ1xuLy9SZXF1aXJlczogY2FtbF9jb21wYXJlX3ZhbF9udW1iZXJfY3VzdG9tXG4vL1JlcXVpcmVzOiBjYW1sX2pzYnl0ZXNfb2Zfc3RyaW5nXG4vL1JlcXVpcmVzOiBjYW1sX2lzX2NvbnRpbnVhdGlvbl90YWdcbmZ1bmN0aW9uIGNhbWxfY29tcGFyZV92YWwgKGEsIGIsIHRvdGFsKSB7XG4gIHZhciBzdGFjayA9IFtdO1xuICBmb3IoOzspIHtcbiAgICBpZiAoISh0b3RhbCAmJiBhID09PSBiKSkge1xuICAgICAgdmFyIHRhZ19hID0gY2FtbF9jb21wYXJlX3ZhbF90YWcoYSk7XG4gICAgICAvLyBmb3J3YXJkX3RhZyA/XG4gICAgICBpZih0YWdfYSA9PSAyNTApIHsgYSA9IGFbMV07IGNvbnRpbnVlIH1cblxuICAgICAgdmFyIHRhZ19iID0gY2FtbF9jb21wYXJlX3ZhbF90YWcoYik7XG4gICAgICAvLyBmb3J3YXJkX3RhZyA/XG4gICAgICBpZih0YWdfYiA9PSAyNTApIHsgYiA9IGJbMV07IGNvbnRpbnVlIH1cblxuICAgICAgLy8gdGFncyBhcmUgZGlmZmVyZW50XG4gICAgICBpZih0YWdfYSAhPT0gdGFnX2IpIHtcbiAgICAgICAgaWYodGFnX2EgPT0gMTAwMCkge1xuICAgICAgICAgIGlmKHRhZ19iID09IDEyNTUpIHsgLy9pbW1lZGlhdGUgY2FuIGNvbXBhcmUgYWdhaW5zdCBjdXN0b21cbiAgICAgICAgICAgIHJldHVybiBjYW1sX2NvbXBhcmVfdmFsX251bWJlcl9jdXN0b20oYSwgYiwgLTEsIHRvdGFsKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIC0xXG4gICAgICAgIH1cbiAgICAgICAgaWYodGFnX2IgPT0gMTAwMCkge1xuICAgICAgICAgIGlmKHRhZ19hID09IDEyNTUpIHsgLy9pbW1lZGlhdGUgY2FuIGNvbXBhcmUgYWdhaW5zdCBjdXN0b21cbiAgICAgICAgICAgIHJldHVybiBjYW1sX2NvbXBhcmVfdmFsX251bWJlcl9jdXN0b20oYiwgYSwgMSwgdG90YWwpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gMVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAodGFnX2EgPCB0YWdfYik/LTE6MTtcbiAgICAgIH1cbiAgICAgIHN3aXRjaCh0YWdfYSl7XG4gICAgICAgIC8vIDI0NjogTGF6eV90YWcgaGFuZGxlZCBiZWxsb3dcbiAgICAgIGNhc2UgMjQ3OiAvLyBDbG9zdXJlX3RhZ1xuICAgICAgICAvLyBDYW5ub3QgaGFwcGVuXG4gICAgICAgIGNhbWxfaW52YWxpZF9hcmd1bWVudChcImNvbXBhcmU6IGZ1bmN0aW9uYWwgdmFsdWVcIik7XG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlIDI0ODogLy8gT2JqZWN0XG4gICAgICAgIHZhciB4ID0gY2FtbF9pbnRfY29tcGFyZShhWzJdLCBiWzJdKTtcbiAgICAgICAgaWYgKHggIT0gMCkgcmV0dXJuICh4IHwgMCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyNDk6IC8vIEluZml4XG4gICAgICAgIC8vIENhbm5vdCBoYXBwZW5cbiAgICAgICAgY2FtbF9pbnZhbGlkX2FyZ3VtZW50KFwiY29tcGFyZTogZnVuY3Rpb25hbCB2YWx1ZVwiKTtcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgMjUwOiAvLyBGb3J3YXJkIHRhZ1xuICAgICAgICAvLyBDYW5ub3QgaGFwcGVuLCBoYW5kbGVkIGFib3ZlXG4gICAgICAgIGNhbWxfaW52YWxpZF9hcmd1bWVudChcImVxdWFsOiBnb3QgRm9yd2FyZF90YWcsIHNob3VsZCBub3QgaGFwcGVuXCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjUxOiAvL0Fic3RyYWN0XG4gICAgICAgIGNhbWxfaW52YWxpZF9hcmd1bWVudChcImVxdWFsOiBhYnN0cmFjdCB2YWx1ZVwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI1MjogLy8gT0NhbWwgYnl0ZXNcbiAgICAgICAgaWYgKGEgIT09IGIpIHtcbiAgICAgICAgICB2YXIgeCA9IGNhbWxfYnl0ZXNfY29tcGFyZShhLCBiKTtcbiAgICAgICAgICBpZiAoeCAhPSAwKSByZXR1cm4gKHggfCAwKTtcbiAgICAgICAgfTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI1MzogLy8gRG91YmxlX3RhZ1xuICAgICAgICAvLyBDYW5ub3QgaGFwcGVuXG4gICAgICAgIGNhbWxfaW52YWxpZF9hcmd1bWVudChcImVxdWFsOiBnb3QgRG91YmxlX3RhZywgc2hvdWxkIG5vdCBoYXBwZW5cIik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyNTQ6IC8vIERvdWJsZV9hcnJheV90YWdcbiAgICAgICAgLy8gQ2Fubm90IGhhcHBlbiwgaGFuZGxlZCBhYm92ZVxuICAgICAgICBjYW1sX2ludmFsaWRfYXJndW1lbnQoXCJlcXVhbDogZ290IERvdWJsZV9hcnJheV90YWcsIHNob3VsZCBub3QgaGFwcGVuXCIpO1xuICAgICAgICBicmVha1xuICAgICAgY2FzZSAyNTU6IC8vIEN1c3RvbV90YWdcbiAgICAgICAgY2FtbF9pbnZhbGlkX2FyZ3VtZW50KFwiZXF1YWw6IGdvdCBDdXN0b21fdGFnLCBzaG91bGQgbm90IGhhcHBlblwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDEyNDc6IC8vIEZ1bmN0aW9uXG4gICAgICAgIGNhbWxfaW52YWxpZF9hcmd1bWVudChcImNvbXBhcmU6IGZ1bmN0aW9uYWwgdmFsdWVcIik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxMjU1OiAvLyBDdXN0b21cbiAgICAgICAgdmFyIGNvbXAgPSBjYW1sX2NvbXBhcmVfdmFsX2dldF9jdXN0b20oYSk7XG4gICAgICAgIGlmKGNvbXAgIT0gY2FtbF9jb21wYXJlX3ZhbF9nZXRfY3VzdG9tKGIpKXtcbiAgICAgICAgICByZXR1cm4gKGEuY2FtbF9jdXN0b208Yi5jYW1sX2N1c3RvbSk/LTE6MTtcbiAgICAgICAgfVxuICAgICAgICBpZighY29tcClcbiAgICAgICAgICBjYW1sX2ludmFsaWRfYXJndW1lbnQoXCJjb21wYXJlOiBhYnN0cmFjdCB2YWx1ZVwiKTtcbiAgICAgICAgdmFyIHggPSBjb21wKGEsYix0b3RhbCk7XG4gICAgICAgIGlmKHggIT0geCl7IC8vIFByb3RlY3QgYWdhaW5zdCBpbnZhbGlkIFVOT1JERVJFRFxuICAgICAgICAgIHJldHVybiB0b3RhbD8tMTp4O1xuICAgICAgICB9XG4gICAgICAgIGlmKHggIT09ICh4fDApKXsgLy8gUHJvdGVjdCBhZ2FpbnN0IGludmFsaWQgcmV0dXJuIHZhbHVlXG4gICAgICAgICAgcmV0dXJuIC0xXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHggIT0gMCkgcmV0dXJuICh4IHwgMCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxMjU2OiAvLyBjb21wYXJlIGZ1bmN0aW9uXG4gICAgICAgIHZhciB4ID0gYS5jb21wYXJlKGIsdG90YWwpO1xuICAgICAgICBpZih4ICE9IHgpIHsgLy8gUHJvdGVjdCBhZ2FpbnN0IGludmFsaWQgVU5PUkRFUkVEXG4gICAgICAgICAgcmV0dXJuIHRvdGFsPy0xOng7XG4gICAgICAgIH1cbiAgICAgICAgaWYoeCAhPT0gKHh8MCkpeyAvLyBQcm90ZWN0IGFnYWluc3QgaW52YWxpZCByZXR1cm4gdmFsdWVcbiAgICAgICAgICByZXR1cm4gLTFcbiAgICAgICAgfVxuICAgICAgICBpZiAoeCAhPSAwKSByZXR1cm4gKHggfCAwKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDEwMDA6IC8vIE51bWJlclxuICAgICAgICBhID0gK2E7XG4gICAgICAgIGIgPSArYjtcbiAgICAgICAgaWYgKGEgPCBiKSByZXR1cm4gLTE7XG4gICAgICAgIGlmIChhID4gYikgcmV0dXJuIDE7XG4gICAgICAgIGlmIChhICE9IGIpIHtcbiAgICAgICAgICBpZiAoIXRvdGFsKSByZXR1cm4gTmFOO1xuICAgICAgICAgIGlmIChhID09IGEpIHJldHVybiAxO1xuICAgICAgICAgIGlmIChiID09IGIpIHJldHVybiAtMTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTAwMTogLy8gVGhlIHJlc3RcbiAgICAgICAgLy8gSGVyZSB3ZSBjYW4gYmUgaW4gdGhlIGZvbGxvd2luZyBjYXNlczpcbiAgICAgICAgLy8gMS4gSmF2YVNjcmlwdCBwcmltaXRpdmUgdHlwZXNcbiAgICAgICAgLy8gMi4gSmF2YVNjcmlwdCBvYmplY3QgdGhhdCBjYW4gYmUgY29lcmNlZCB0byBwcmltaXRpdmUgdHlwZXNcbiAgICAgICAgLy8gMy4gSmF2YVNjcmlwdCBvYmplY3QgdGhhbiBjYW5ub3QgYmUgY29lcmNlZCB0byBwcmltaXRpdmUgdHlwZXNcbiAgICAgICAgLy9cbiAgICAgICAgLy8gKDMpIHdpbGwgcmFpc2UgYSBbVHlwZUVycm9yXVxuICAgICAgICAvLyAoMikgd2lsbCBjb2VyY2UgdG8gcHJpbWl0aXZlIHR5cGVzIHVzaW5nIFt2YWx1ZU9mXSBvciBbdG9TdHJpbmddXG4gICAgICAgIC8vICgyKSBhbmQgKDMpLCBhZnRlciBldmVudHVhbCBjb2VyY2lvblxuICAgICAgICAvLyAtIGlmIGEgYW5kIGIgYXJlIHN0cmluZ3MsIGFwcGx5IGxleGljb2dyYXBoaWMgY29tcGFyaXNvblxuICAgICAgICAvLyAtIGlmIGEgb3IgYiBhcmUgbm90IHN0cmluZ3MsIGNvbnZlcnQgYSBhbmQgYiB0byBudW1iZXJcbiAgICAgICAgLy8gICBhbmQgYXBwbHkgc3RhbmRhcmQgY29tcGFyaXNvblxuICAgICAgICAvL1xuICAgICAgICAvLyBFeGNlcHRpb246IGAhPWAgd2lsbCBub3QgY29lcmNlL2NvbnZlcnQgaWYgYm90aCBhIGFuZCBiIGFyZSBvYmplY3RzXG4gICAgICAgIGlmIChhIDwgYikgcmV0dXJuIC0xO1xuICAgICAgICBpZiAoYSA+IGIpIHJldHVybiAxO1xuICAgICAgICBpZiAoYSAhPSBiKSB7XG4gICAgICAgICAgaWYgKCF0b3RhbCkgcmV0dXJuIE5hTjtcbiAgICAgICAgICBpZiAoYSA9PSBhKSByZXR1cm4gMTtcbiAgICAgICAgICBpZiAoYiA9PSBiKSByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDEyNTE6IC8vIEphdmFTY3JpcHQgU3ltYm9sLCBubyBvcmRlcmluZy5cbiAgICAgICAgaWYoYSAhPT0gYikge1xuICAgICAgICAgIGlmICghdG90YWwpIHJldHVybiBOYU47XG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDEyNTI6IC8vIG9jYW1sIHN0cmluZ3NcbiAgICAgICAgdmFyIGEgPSBjYW1sX2pzYnl0ZXNfb2Zfc3RyaW5nKGEpO1xuICAgICAgICB2YXIgYiA9IGNhbWxfanNieXRlc19vZl9zdHJpbmcoYik7XG4gICAgICAgIGlmKGEgIT09IGIpIHtcbiAgICAgICAgICBpZihhIDwgYikgcmV0dXJuIC0xO1xuICAgICAgICAgIGlmKGEgPiBiKSByZXR1cm4gMTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTI1MjA6IC8vIGphdmFzY3JpcHQgc3RyaW5nc1xuICAgICAgICB2YXIgYSA9IGEudG9TdHJpbmcoKTtcbiAgICAgICAgdmFyIGIgPSBiLnRvU3RyaW5nKCk7XG4gICAgICAgIGlmKGEgIT09IGIpIHtcbiAgICAgICAgICBpZihhIDwgYikgcmV0dXJuIC0xO1xuICAgICAgICAgIGlmKGEgPiBiKSByZXR1cm4gMTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjQ2OiAvLyBMYXp5X3RhZ1xuICAgICAgY2FzZSAyNTQ6IC8vIERvdWJsZV9hcnJheVxuICAgICAgZGVmYXVsdDogLy8gQmxvY2sgd2l0aCBvdGhlciB0YWdcbiAgICAgICAgaWYoY2FtbF9pc19jb250aW51YXRpb25fdGFnKHRhZ19hKSkge1xuICAgICAgICAgIGNhbWxfaW52YWxpZF9hcmd1bWVudChcImNvbXBhcmU6IGNvbnRpbnVhdGlvbiB2YWx1ZVwiKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoYS5sZW5ndGggIT0gYi5sZW5ndGgpIHJldHVybiAoYS5sZW5ndGggPCBiLmxlbmd0aCk/LTE6MTtcbiAgICAgICAgaWYgKGEubGVuZ3RoID4gMSkgc3RhY2sucHVzaChhLCBiLCAxKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChzdGFjay5sZW5ndGggPT0gMCkgcmV0dXJuIDA7XG4gICAgdmFyIGkgPSBzdGFjay5wb3AoKTtcbiAgICBiID0gc3RhY2sucG9wKCk7XG4gICAgYSA9IHN0YWNrLnBvcCgpO1xuICAgIGlmIChpICsgMSA8IGEubGVuZ3RoKSBzdGFjay5wdXNoKGEsIGIsIGkgKyAxKTtcbiAgICBhID0gYVtpXTtcbiAgICBiID0gYltpXTtcbiAgfVxufVxuLy9Qcm92aWRlczogY2FtbF9jb21wYXJlIChjb25zdCwgY29uc3QpXG4vL1JlcXVpcmVzOiBjYW1sX2NvbXBhcmVfdmFsXG5mdW5jdGlvbiBjYW1sX2NvbXBhcmUgKGEsIGIpIHsgcmV0dXJuIGNhbWxfY29tcGFyZV92YWwgKGEsIGIsIHRydWUpOyB9XG4vL1Byb3ZpZGVzOiBjYW1sX2ludF9jb21wYXJlIG11dGFibGUgKGNvbnN0LCBjb25zdClcbmZ1bmN0aW9uIGNhbWxfaW50X2NvbXBhcmUgKGEsIGIpIHtcbiAgaWYgKGEgPCBiKSByZXR1cm4gKC0xKTsgaWYgKGEgPT0gYikgcmV0dXJuIDA7IHJldHVybiAxO1xufVxuLy9Qcm92aWRlczogY2FtbF9lcXVhbCBtdXRhYmxlIChjb25zdCwgY29uc3QpXG4vL1JlcXVpcmVzOiBjYW1sX2NvbXBhcmVfdmFsXG5mdW5jdGlvbiBjYW1sX2VxdWFsICh4LCB5KSB7IHJldHVybiArKGNhbWxfY29tcGFyZV92YWwoeCx5LGZhbHNlKSA9PSAwKTsgfVxuLy9Qcm92aWRlczogY2FtbF9ub3RlcXVhbCBtdXRhYmxlIChjb25zdCwgY29uc3QpXG4vL1JlcXVpcmVzOiBjYW1sX2NvbXBhcmVfdmFsXG5mdW5jdGlvbiBjYW1sX25vdGVxdWFsICh4LCB5KSB7IHJldHVybiArKGNhbWxfY29tcGFyZV92YWwoeCx5LGZhbHNlKSAhPSAwKTsgfVxuLy9Qcm92aWRlczogY2FtbF9ncmVhdGVyZXF1YWwgbXV0YWJsZSAoY29uc3QsIGNvbnN0KVxuLy9SZXF1aXJlczogY2FtbF9jb21wYXJlX3ZhbFxuZnVuY3Rpb24gY2FtbF9ncmVhdGVyZXF1YWwgKHgsIHkpIHsgcmV0dXJuICsoY2FtbF9jb21wYXJlX3ZhbCh4LHksZmFsc2UpID49IDApOyB9XG4vL1Byb3ZpZGVzOiBjYW1sX2dyZWF0ZXJ0aGFuIG11dGFibGUgKGNvbnN0LCBjb25zdClcbi8vUmVxdWlyZXM6IGNhbWxfY29tcGFyZV92YWxcbmZ1bmN0aW9uIGNhbWxfZ3JlYXRlcnRoYW4gKHgsIHkpIHsgcmV0dXJuICsoY2FtbF9jb21wYXJlX3ZhbCh4LHksZmFsc2UpID4gMCk7IH1cbi8vUHJvdmlkZXM6IGNhbWxfbGVzc2VxdWFsIG11dGFibGUgKGNvbnN0LCBjb25zdClcbi8vUmVxdWlyZXM6IGNhbWxfY29tcGFyZV92YWxcbmZ1bmN0aW9uIGNhbWxfbGVzc2VxdWFsICh4LCB5KSB7IHJldHVybiArKGNhbWxfY29tcGFyZV92YWwoeCx5LGZhbHNlKSA8PSAwKTsgfVxuLy9Qcm92aWRlczogY2FtbF9sZXNzdGhhbiBtdXRhYmxlIChjb25zdCwgY29uc3QpXG4vL1JlcXVpcmVzOiBjYW1sX2NvbXBhcmVfdmFsXG5mdW5jdGlvbiBjYW1sX2xlc3N0aGFuICh4LCB5KSB7IHJldHVybiArKGNhbWxfY29tcGFyZV92YWwoeCx5LGZhbHNlKSA8IDApOyB9XG4iLCIvLyBKc19vZl9vY2FtbCBydW50aW1lIHN1cHBvcnRcbi8vIGh0dHA6Ly93d3cub2NzaWdlbi5vcmcvanNfb2Zfb2NhbWwvXG4vLyBDb3B5cmlnaHQgKEMpIDIwMTAgSsOpcsO0bWUgVm91aWxsb25cbi8vIExhYm9yYXRvaXJlIFBQUyAtIENOUlMgVW5pdmVyc2l0w6kgUGFyaXMgRGlkZXJvdFxuLy9cbi8vIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4vLyBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbi8vIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHdpdGggbGlua2luZyBleGNlcHRpb247XG4vLyBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vL1xuLy8gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuLy8gR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vL1xuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4vLyBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcsIFVTQS5cblxuLy9Qcm92aWRlczogY2FtbF9tZDVfY2hhblxuLy9SZXF1aXJlczogY2FtbF9zdHJpbmdfb2ZfYXJyYXlcbi8vUmVxdWlyZXM6IGNhbWxfcmFpc2VfZW5kX29mX2ZpbGUsIGNhbWxfbWxfaW5wdXRfYmxvY2tcbi8vUmVxdWlyZXM6IGNhbWxfTUQ1SW5pdCwgY2FtbF9NRDVVcGRhdGUsIGNhbWxfTUQ1RmluYWxcbmZ1bmN0aW9uIGNhbWxfbWQ1X2NoYW4oY2hhbmlkLHRvcmVhZCl7XG4gIHZhciBjdHggPSBjYW1sX01ENUluaXQoKTtcbiAgdmFyIGJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KDQwOTYpO1xuICBpZih0b3JlYWQgPCAwKXtcbiAgICB3aGlsZSh0cnVlKXtcbiAgICAgIHZhciByZWFkID0gY2FtbF9tbF9pbnB1dF9ibG9jayhjaGFuaWQsYnVmZmVyLDAsYnVmZmVyLmxlbmd0aCk7XG4gICAgICBpZihyZWFkID09IDApIGJyZWFrO1xuICAgICAgY2FtbF9NRDVVcGRhdGUoY3R4LGJ1ZmZlci5zdWJhcnJheSgwLCByZWFkKSwgcmVhZCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHdoaWxlKHRvcmVhZCA+IDApIHtcbiAgICAgIHZhciByZWFkID0gY2FtbF9tbF9pbnB1dF9ibG9jayhjaGFuaWQsYnVmZmVyLDAsICh0b3JlYWQgPiBidWZmZXIubGVuZ3RoID8gYnVmZmVyLmxlbmd0aCA6IHRvcmVhZCkpO1xuICAgICAgaWYocmVhZCA9PSAwKSBjYW1sX3JhaXNlX2VuZF9vZl9maWxlKCk7XG4gICAgICBjYW1sX01ENVVwZGF0ZShjdHgsYnVmZmVyLnN1YmFycmF5KDAsIHJlYWQpLCByZWFkKTtcbiAgICAgIHRvcmVhZCAtPSByZWFkXG4gICAgfVxuICB9XG4gIHJldHVybiBjYW1sX3N0cmluZ19vZl9hcnJheShjYW1sX01ENUZpbmFsKGN0eCkpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21kNV9zdHJpbmdcbi8vUmVxdWlyZXM6IGNhbWxfYnl0ZXNfb2Zfc3RyaW5nLCBjYW1sX21kNV9ieXRlc1xuZnVuY3Rpb24gY2FtbF9tZDVfc3RyaW5nKHMsIG9mcywgbGVuKSB7XG4gIHJldHVybiBjYW1sX21kNV9ieXRlcyhjYW1sX2J5dGVzX29mX3N0cmluZyhzKSxvZnMsbGVuKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9NRDVUcmFuc2Zvcm1cbnZhciBjYW1sX01ENVRyYW5zZm9ybSA9IChmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIGFkZCAoeCwgeSkgeyByZXR1cm4gKHggKyB5KSB8IDA7IH1cbiAgZnVuY3Rpb24geHgocSxhLGIseCxzLHQpIHtcbiAgICBhID0gYWRkKGFkZChhLCBxKSwgYWRkKHgsIHQpKTtcbiAgICByZXR1cm4gYWRkKChhIDw8IHMpIHwgKGEgPj4+ICgzMiAtIHMpKSwgYik7XG4gIH1cbiAgZnVuY3Rpb24gZmYoYSxiLGMsZCx4LHMsdCkge1xuICAgIHJldHVybiB4eCgoYiAmIGMpIHwgKCh+YikgJiBkKSwgYSwgYiwgeCwgcywgdCk7XG4gIH1cbiAgZnVuY3Rpb24gZ2coYSxiLGMsZCx4LHMsdCkge1xuICAgIHJldHVybiB4eCgoYiAmIGQpIHwgKGMgJiAofmQpKSwgYSwgYiwgeCwgcywgdCk7XG4gIH1cbiAgZnVuY3Rpb24gaGgoYSxiLGMsZCx4LHMsdCkgeyByZXR1cm4geHgoYiBeIGMgXiBkLCBhLCBiLCB4LCBzLCB0KTsgfVxuICBmdW5jdGlvbiBpaShhLGIsYyxkLHgscyx0KSB7IHJldHVybiB4eChjIF4gKGIgfCAofmQpKSwgYSwgYiwgeCwgcywgdCk7IH1cblxuICByZXR1cm4gZnVuY3Rpb24gKHcsIGJ1ZmZlcikge1xuICAgIHZhciBhID0gd1swXSwgYiA9IHdbMV0sIGMgPSB3WzJdLCBkID0gd1szXTtcblxuICAgIGEgPSBmZihhLCBiLCBjLCBkLCBidWZmZXJbIDBdLCA3LCAweEQ3NkFBNDc4KTtcbiAgICBkID0gZmYoZCwgYSwgYiwgYywgYnVmZmVyWyAxXSwgMTIsIDB4RThDN0I3NTYpO1xuICAgIGMgPSBmZihjLCBkLCBhLCBiLCBidWZmZXJbIDJdLCAxNywgMHgyNDIwNzBEQik7XG4gICAgYiA9IGZmKGIsIGMsIGQsIGEsIGJ1ZmZlclsgM10sIDIyLCAweEMxQkRDRUVFKTtcbiAgICBhID0gZmYoYSwgYiwgYywgZCwgYnVmZmVyWyA0XSwgNywgMHhGNTdDMEZBRik7XG4gICAgZCA9IGZmKGQsIGEsIGIsIGMsIGJ1ZmZlclsgNV0sIDEyLCAweDQ3ODdDNjJBKTtcbiAgICBjID0gZmYoYywgZCwgYSwgYiwgYnVmZmVyWyA2XSwgMTcsIDB4QTgzMDQ2MTMpO1xuICAgIGIgPSBmZihiLCBjLCBkLCBhLCBidWZmZXJbIDddLCAyMiwgMHhGRDQ2OTUwMSk7XG4gICAgYSA9IGZmKGEsIGIsIGMsIGQsIGJ1ZmZlclsgOF0sIDcsIDB4Njk4MDk4RDgpO1xuICAgIGQgPSBmZihkLCBhLCBiLCBjLCBidWZmZXJbIDldLCAxMiwgMHg4QjQ0RjdBRik7XG4gICAgYyA9IGZmKGMsIGQsIGEsIGIsIGJ1ZmZlclsxMF0sIDE3LCAweEZGRkY1QkIxKTtcbiAgICBiID0gZmYoYiwgYywgZCwgYSwgYnVmZmVyWzExXSwgMjIsIDB4ODk1Q0Q3QkUpO1xuICAgIGEgPSBmZihhLCBiLCBjLCBkLCBidWZmZXJbMTJdLCA3LCAweDZCOTAxMTIyKTtcbiAgICBkID0gZmYoZCwgYSwgYiwgYywgYnVmZmVyWzEzXSwgMTIsIDB4RkQ5ODcxOTMpO1xuICAgIGMgPSBmZihjLCBkLCBhLCBiLCBidWZmZXJbMTRdLCAxNywgMHhBNjc5NDM4RSk7XG4gICAgYiA9IGZmKGIsIGMsIGQsIGEsIGJ1ZmZlclsxNV0sIDIyLCAweDQ5QjQwODIxKTtcblxuICAgIGEgPSBnZyhhLCBiLCBjLCBkLCBidWZmZXJbIDFdLCA1LCAweEY2MUUyNTYyKTtcbiAgICBkID0gZ2coZCwgYSwgYiwgYywgYnVmZmVyWyA2XSwgOSwgMHhDMDQwQjM0MCk7XG4gICAgYyA9IGdnKGMsIGQsIGEsIGIsIGJ1ZmZlclsxMV0sIDE0LCAweDI2NUU1QTUxKTtcbiAgICBiID0gZ2coYiwgYywgZCwgYSwgYnVmZmVyWyAwXSwgMjAsIDB4RTlCNkM3QUEpO1xuICAgIGEgPSBnZyhhLCBiLCBjLCBkLCBidWZmZXJbIDVdLCA1LCAweEQ2MkYxMDVEKTtcbiAgICBkID0gZ2coZCwgYSwgYiwgYywgYnVmZmVyWzEwXSwgOSwgMHgwMjQ0MTQ1Myk7XG4gICAgYyA9IGdnKGMsIGQsIGEsIGIsIGJ1ZmZlclsxNV0sIDE0LCAweEQ4QTFFNjgxKTtcbiAgICBiID0gZ2coYiwgYywgZCwgYSwgYnVmZmVyWyA0XSwgMjAsIDB4RTdEM0ZCQzgpO1xuICAgIGEgPSBnZyhhLCBiLCBjLCBkLCBidWZmZXJbIDldLCA1LCAweDIxRTFDREU2KTtcbiAgICBkID0gZ2coZCwgYSwgYiwgYywgYnVmZmVyWzE0XSwgOSwgMHhDMzM3MDdENik7XG4gICAgYyA9IGdnKGMsIGQsIGEsIGIsIGJ1ZmZlclsgM10sIDE0LCAweEY0RDUwRDg3KTtcbiAgICBiID0gZ2coYiwgYywgZCwgYSwgYnVmZmVyWyA4XSwgMjAsIDB4NDU1QTE0RUQpO1xuICAgIGEgPSBnZyhhLCBiLCBjLCBkLCBidWZmZXJbMTNdLCA1LCAweEE5RTNFOTA1KTtcbiAgICBkID0gZ2coZCwgYSwgYiwgYywgYnVmZmVyWyAyXSwgOSwgMHhGQ0VGQTNGOCk7XG4gICAgYyA9IGdnKGMsIGQsIGEsIGIsIGJ1ZmZlclsgN10sIDE0LCAweDY3NkYwMkQ5KTtcbiAgICBiID0gZ2coYiwgYywgZCwgYSwgYnVmZmVyWzEyXSwgMjAsIDB4OEQyQTRDOEEpO1xuXG4gICAgYSA9IGhoKGEsIGIsIGMsIGQsIGJ1ZmZlclsgNV0sIDQsIDB4RkZGQTM5NDIpO1xuICAgIGQgPSBoaChkLCBhLCBiLCBjLCBidWZmZXJbIDhdLCAxMSwgMHg4NzcxRjY4MSk7XG4gICAgYyA9IGhoKGMsIGQsIGEsIGIsIGJ1ZmZlclsxMV0sIDE2LCAweDZEOUQ2MTIyKTtcbiAgICBiID0gaGgoYiwgYywgZCwgYSwgYnVmZmVyWzE0XSwgMjMsIDB4RkRFNTM4MEMpO1xuICAgIGEgPSBoaChhLCBiLCBjLCBkLCBidWZmZXJbIDFdLCA0LCAweEE0QkVFQTQ0KTtcbiAgICBkID0gaGgoZCwgYSwgYiwgYywgYnVmZmVyWyA0XSwgMTEsIDB4NEJERUNGQTkpO1xuICAgIGMgPSBoaChjLCBkLCBhLCBiLCBidWZmZXJbIDddLCAxNiwgMHhGNkJCNEI2MCk7XG4gICAgYiA9IGhoKGIsIGMsIGQsIGEsIGJ1ZmZlclsxMF0sIDIzLCAweEJFQkZCQzcwKTtcbiAgICBhID0gaGgoYSwgYiwgYywgZCwgYnVmZmVyWzEzXSwgNCwgMHgyODlCN0VDNik7XG4gICAgZCA9IGhoKGQsIGEsIGIsIGMsIGJ1ZmZlclsgMF0sIDExLCAweEVBQTEyN0ZBKTtcbiAgICBjID0gaGgoYywgZCwgYSwgYiwgYnVmZmVyWyAzXSwgMTYsIDB4RDRFRjMwODUpO1xuICAgIGIgPSBoaChiLCBjLCBkLCBhLCBidWZmZXJbIDZdLCAyMywgMHgwNDg4MUQwNSk7XG4gICAgYSA9IGhoKGEsIGIsIGMsIGQsIGJ1ZmZlclsgOV0sIDQsIDB4RDlENEQwMzkpO1xuICAgIGQgPSBoaChkLCBhLCBiLCBjLCBidWZmZXJbMTJdLCAxMSwgMHhFNkRCOTlFNSk7XG4gICAgYyA9IGhoKGMsIGQsIGEsIGIsIGJ1ZmZlclsxNV0sIDE2LCAweDFGQTI3Q0Y4KTtcbiAgICBiID0gaGgoYiwgYywgZCwgYSwgYnVmZmVyWyAyXSwgMjMsIDB4QzRBQzU2NjUpO1xuXG4gICAgYSA9IGlpKGEsIGIsIGMsIGQsIGJ1ZmZlclsgMF0sIDYsIDB4RjQyOTIyNDQpO1xuICAgIGQgPSBpaShkLCBhLCBiLCBjLCBidWZmZXJbIDddLCAxMCwgMHg0MzJBRkY5Nyk7XG4gICAgYyA9IGlpKGMsIGQsIGEsIGIsIGJ1ZmZlclsxNF0sIDE1LCAweEFCOTQyM0E3KTtcbiAgICBiID0gaWkoYiwgYywgZCwgYSwgYnVmZmVyWyA1XSwgMjEsIDB4RkM5M0EwMzkpO1xuICAgIGEgPSBpaShhLCBiLCBjLCBkLCBidWZmZXJbMTJdLCA2LCAweDY1NUI1OUMzKTtcbiAgICBkID0gaWkoZCwgYSwgYiwgYywgYnVmZmVyWyAzXSwgMTAsIDB4OEYwQ0NDOTIpO1xuICAgIGMgPSBpaShjLCBkLCBhLCBiLCBidWZmZXJbMTBdLCAxNSwgMHhGRkVGRjQ3RCk7XG4gICAgYiA9IGlpKGIsIGMsIGQsIGEsIGJ1ZmZlclsgMV0sIDIxLCAweDg1ODQ1REQxKTtcbiAgICBhID0gaWkoYSwgYiwgYywgZCwgYnVmZmVyWyA4XSwgNiwgMHg2RkE4N0U0Rik7XG4gICAgZCA9IGlpKGQsIGEsIGIsIGMsIGJ1ZmZlclsxNV0sIDEwLCAweEZFMkNFNkUwKTtcbiAgICBjID0gaWkoYywgZCwgYSwgYiwgYnVmZmVyWyA2XSwgMTUsIDB4QTMwMTQzMTQpO1xuICAgIGIgPSBpaShiLCBjLCBkLCBhLCBidWZmZXJbMTNdLCAyMSwgMHg0RTA4MTFBMSk7XG4gICAgYSA9IGlpKGEsIGIsIGMsIGQsIGJ1ZmZlclsgNF0sIDYsIDB4Rjc1MzdFODIpO1xuICAgIGQgPSBpaShkLCBhLCBiLCBjLCBidWZmZXJbMTFdLCAxMCwgMHhCRDNBRjIzNSk7XG4gICAgYyA9IGlpKGMsIGQsIGEsIGIsIGJ1ZmZlclsgMl0sIDE1LCAweDJBRDdEMkJCKTtcbiAgICBiID0gaWkoYiwgYywgZCwgYSwgYnVmZmVyWyA5XSwgMjEsIDB4RUI4NkQzOTEpO1xuXG4gICAgd1swXSA9IGFkZChhLCB3WzBdKTtcbiAgICB3WzFdID0gYWRkKGIsIHdbMV0pO1xuICAgIHdbMl0gPSBhZGQoYywgd1syXSk7XG4gICAgd1szXSA9IGFkZChkLCB3WzNdKTtcbiAgfX0pKClcblxuLy9Qcm92aWRlczogY2FtbF9NRDVJbml0XG5mdW5jdGlvbiBjYW1sX01ENUluaXQoKSB7XG4gIHZhciBidWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoNjQpO1xuICB2YXIgYjMyID0gbmV3IFVpbnQzMkFycmF5KGJ1ZmZlcik7XG4gIHZhciBiOCA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XG4gIHJldHVybiB7bGVuOjAsXG4gICAgICAgICAgdzpuZXcgVWludDMyQXJyYXkoWzB4Njc0NTIzMDEsIDB4RUZDREFCODksIDB4OThCQURDRkUsIDB4MTAzMjU0NzZdKSxcbiAgICAgICAgICBiMzI6YjMyLFxuICAgICAgICAgIGI4OmI4fVxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX01ENVVwZGF0ZVxuLy9SZXF1aXJlczogY2FtbF9NRDVUcmFuc2Zvcm1cbmZ1bmN0aW9uIGNhbWxfTUQ1VXBkYXRlKGN0eCwgaW5wdXQsIGlucHV0X2xlbil7XG4gIHZhciBpbl9idWYgPSBjdHgubGVuICYgMHgzZjtcbiAgdmFyIGlucHV0X3BvcyA9IDA7XG4gIGN0eC5sZW4gKz0gaW5wdXRfbGVuO1xuICBpZihpbl9idWYpe1xuICAgIHZhciBtaXNzaW5nID0gNjQgLSBpbl9idWY7XG4gICAgaWYoaW5wdXRfbGVuIDwgbWlzc2luZykge1xuICAgICAgY3R4LmI4LnNldChpbnB1dC5zdWJhcnJheSgwLGlucHV0X2xlbiksaW5fYnVmKTtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBjdHguYjguc2V0KGlucHV0LnN1YmFycmF5KDAsbWlzc2luZyksaW5fYnVmKTtcbiAgICBjYW1sX01ENVRyYW5zZm9ybShjdHgudywgY3R4LmIzMik7XG4gICAgaW5wdXRfbGVuIC09IG1pc3Npbmc7XG4gICAgaW5wdXRfcG9zICs9IG1pc3Npbmc7XG4gIH1cbiAgd2hpbGUoaW5wdXRfbGVuID49IDY0KXtcbiAgICBjdHguYjguc2V0KGlucHV0LnN1YmFycmF5KGlucHV0X3BvcyxpbnB1dF9wb3MgKyA2NCksIDApO1xuICAgIGNhbWxfTUQ1VHJhbnNmb3JtKGN0eC53LCBjdHguYjMyKTtcbiAgICBpbnB1dF9sZW4gLT0gNjQ7XG4gICAgaW5wdXRfcG9zICs9IDY0O1xuICB9XG4gIGlmKGlucHV0X2xlbilcbiAgICBjdHguYjguc2V0KGlucHV0LnN1YmFycmF5KGlucHV0X3BvcyxpbnB1dF9wb3MgKyBpbnB1dF9sZW4pLCAwKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9NRDVGaW5hbFxuLy9SZXF1aXJlczogY2FtbF9NRDVUcmFuc2Zvcm1cbmZ1bmN0aW9uIGNhbWxfTUQ1RmluYWwoY3R4KXtcbiAgdmFyIGluX2J1ZiA9IGN0eC5sZW4gJiAweDNmO1xuICBjdHguYjhbaW5fYnVmXSA9IDB4ODA7XG4gIGluX2J1ZiArKztcbiAgaWYoaW5fYnVmID4gNTYpIHtcbiAgICBmb3IodmFyIGogPSBpbl9idWY7IGogPCA2NDsgaisrKXtcbiAgICAgIGN0eC5iOFtqXSA9IDA7XG4gICAgfVxuICAgIGNhbWxfTUQ1VHJhbnNmb3JtKGN0eC53LCBjdHguYjMyKTtcbiAgICBmb3IodmFyIGogPSAwOyBqIDwgNTY7IGorKyl7XG4gICAgICBjdHguYjhbal0gPSAwO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBmb3IodmFyIGogPSBpbl9idWY7IGogPCA1NjsgaisrKXtcbiAgICAgIGN0eC5iOFtqXSA9IDA7XG4gICAgfVxuICB9XG4gIGN0eC5iMzJbMTRdID0gY3R4LmxlbiA8PCAzO1xuICBjdHguYjMyWzE1XSA9IChjdHgubGVuID4+IDI5KSAmIDB4MUZGRkZGRkY7XG4gIGNhbWxfTUQ1VHJhbnNmb3JtKGN0eC53LCBjdHguYjMyKTtcbiAgdmFyIHQgPSBuZXcgVWludDhBcnJheSgxNik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKVxuICAgIGZvciAodmFyIGogPSAwOyBqIDwgNDsgaisrKVxuICAgICAgdFtpICogNCArIGpdID0gKGN0eC53W2ldID4+ICg4ICogaikpICYgMHhGRjtcbiAgcmV0dXJuIHQ7XG59XG5cblxuLy9Qcm92aWRlczogY2FtbF9tZDVfYnl0ZXNcbi8vUmVxdWlyZXM6IGNhbWxfdWludDhfYXJyYXlfb2ZfYnl0ZXMsIGNhbWxfc3RyaW5nX29mX2FycmF5XG4vL1JlcXVpcmVzOiBjYW1sX01ENUluaXQsIGNhbWxfTUQ1VXBkYXRlLCBjYW1sX01ENUZpbmFsXG5mdW5jdGlvbiBjYW1sX21kNV9ieXRlcyhzLCBvZnMsIGxlbikge1xuICB2YXIgY3R4ID0gY2FtbF9NRDVJbml0KCk7XG4gIHZhciBhID0gY2FtbF91aW50OF9hcnJheV9vZl9ieXRlcyhzKTtcbiAgY2FtbF9NRDVVcGRhdGUoY3R4LGEuc3ViYXJyYXkob2ZzLCBvZnMgKyBsZW4pLCBsZW4pO1xuICByZXR1cm4gY2FtbF9zdHJpbmdfb2ZfYXJyYXkoY2FtbF9NRDVGaW5hbChjdHgpKTtcbn1cbiIsIi8vIEpzX29mX29jYW1sIHJ1bnRpbWUgc3VwcG9ydFxuLy8gaHR0cDovL3d3dy5vY3NpZ2VuLm9yZy9qc19vZl9vY2FtbC9cbi8vIENvcHlyaWdodCAoQykgMjAxMCBKw6lyw7RtZSBWb3VpbGxvblxuLy8gTGFib3JhdG9pcmUgUFBTIC0gQ05SUyBVbml2ZXJzaXTDqSBQYXJpcyBEaWRlcm90XG4vL1xuLy8gVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbi8vIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuLy8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgd2l0aCBsaW5raW5nIGV4Y2VwdGlvbjtcbi8vIGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vXG4vLyBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4vLyBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2Vcbi8vIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLlxuXG4vL1Byb3ZpZGVzOiBqc29vX2Zsb29yX2xvZzJcbnZhciBsb2cyX29rID0gTWF0aC5sb2cyICYmIE1hdGgubG9nMigxLjEyMzU1ODIwOTI4ODk0NzRFKzMwNykgPT0gMTAyMFxuZnVuY3Rpb24ganNvb19mbG9vcl9sb2cyKHgpIHtcbiAgaWYobG9nMl9vaykgcmV0dXJuIE1hdGguZmxvb3IoTWF0aC5sb2cyKHgpKVxuICB2YXIgaSA9IDA7XG4gIGlmICh4ID09IDApIHJldHVybiAtSW5maW5pdHk7XG4gIGlmKHg+PTEpIHt3aGlsZSAoeD49Mikge3gvPTI7IGkrK30gfVxuICBlbHNlIHt3aGlsZSAoeCA8IDEpIHt4Kj0yOyBpLS19IH07XG4gIHJldHVybiBpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2ludDY0X2JpdHNfb2ZfZmxvYXQgY29uc3Rcbi8vUmVxdWlyZXM6IGpzb29fZmxvb3JfbG9nMiwgY2FtbF9pbnQ2NF9jcmVhdGVfbG9fbWlfaGlcbmZ1bmN0aW9uIGNhbWxfaW50NjRfYml0c19vZl9mbG9hdCAoeCkge1xuICBpZiAoIWlzRmluaXRlKHgpKSB7XG4gICAgaWYgKGlzTmFOKHgpKVxuICAgICAgcmV0dXJuIGNhbWxfaW50NjRfY3JlYXRlX2xvX21pX2hpKDEsIDAsIDB4N2ZmMCk7XG4gICAgaWYgKHggPiAwKVxuICAgICAgcmV0dXJuIGNhbWxfaW50NjRfY3JlYXRlX2xvX21pX2hpKDAsIDAsIDB4N2ZmMClcbiAgICBlbHNlXG4gICAgICByZXR1cm4gY2FtbF9pbnQ2NF9jcmVhdGVfbG9fbWlfaGkoMCwgMCwgMHhmZmYwKVxuICB9XG4gIHZhciBzaWduID0gKHg9PTAgJiYgMS94ID09IC1JbmZpbml0eSk/MHg4MDAwOih4Pj0wKT8wOjB4ODAwMDtcbiAgaWYgKHNpZ24pIHggPSAteDtcbiAgLy8gSW50NjQuYml0c19vZl9mbG9hdCAxLjEyMzU1ODIwOTI4ODk0NzRFKzMwNyA9IDB4N2ZiMDAwMDAwMDAwMDAwMExcbiAgLy8gdXNpbmcgTWF0aC5MT0cyRSpNYXRoLmxvZyh4KSBpbiBwbGFjZSBvZiBNYXRoLmxvZzIgcmVzdWx0IGluIHByZWNpc2lvbiBsb3N0XG4gIHZhciBleHAgPSBqc29vX2Zsb29yX2xvZzIoeCkgKyAxMDIzO1xuICBpZiAoZXhwIDw9IDApIHtcbiAgICBleHAgPSAwO1xuICAgIHggLz0gTWF0aC5wb3coMiwtMTAyNik7XG4gIH0gZWxzZSB7XG4gICAgeCAvPSBNYXRoLnBvdygyLGV4cC0xMDI3KTtcbiAgICBpZiAoeCA8IDE2KSB7XG4gICAgICB4ICo9IDI7IGV4cCAtPTE7IH1cbiAgICBpZiAoZXhwID09IDApIHtcbiAgICAgIHggLz0gMjsgfVxuICB9XG4gIHZhciBrID0gTWF0aC5wb3coMiwyNCk7XG4gIHZhciByMyA9IHh8MDtcbiAgeCA9ICh4IC0gcjMpICogaztcbiAgdmFyIHIyID0geHwwO1xuICB4ID0gKHggLSByMikgKiBrO1xuICB2YXIgcjEgPSB4fDA7XG4gIHIzID0gKHIzICYweGYpIHwgc2lnbiB8IGV4cCA8PCA0O1xuICByZXR1cm4gY2FtbF9pbnQ2NF9jcmVhdGVfbG9fbWlfaGkocjEsIHIyLCByMyk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfaW50MzJfYml0c19vZl9mbG9hdCBjb25zdFxuLy9SZXF1aXJlczoganNvb19mbG9vcl9sb2cyXG5mdW5jdGlvbiBjYW1sX2ludDMyX2JpdHNfb2ZfZmxvYXQgKHgpIHtcbiAgdmFyIGZsb2F0MzJhID0gbmV3IEZsb2F0MzJBcnJheSgxKTtcbiAgZmxvYXQzMmFbMF0gPSB4O1xuICB2YXIgaW50MzJhID0gbmV3IEludDMyQXJyYXkoZmxvYXQzMmEuYnVmZmVyKTtcbiAgcmV0dXJuIGludDMyYVswXSB8IDA7XG59XG5cbi8vRlAgbGl0ZXJhbHMgY2FuIGJlIHdyaXR0ZW4gdXNpbmcgdGhlIGhleGFkZWNpbWFsXG4vL25vdGF0aW9uIDB4PG1hbnRpc3NhIGluIGhleD5wPGV4cG9uZW50PiBmcm9tIElTTyBDOTkuXG4vL2h0dHBzOi8vZ2l0aHViLmNvbS9kYW5rb2dhaS9qcy1oZXhmbG9hdC9ibG9iL21hc3Rlci9oZXhmbG9hdC5qc1xuLy9Qcm92aWRlczogY2FtbF9oZXhzdHJpbmdfb2ZfZmxvYXQgY29uc3Rcbi8vUmVxdWlyZXM6IGNhbWxfc3RyaW5nX29mX2pzc3RyaW5nLCBjYW1sX3N0cl9yZXBlYXRcbmZ1bmN0aW9uIGNhbWxfaGV4c3RyaW5nX29mX2Zsb2F0ICh4LCBwcmVjLCBzdHlsZSkge1xuICBpZiAoIWlzRmluaXRlKHgpKSB7XG4gICAgaWYgKGlzTmFOKHgpKSByZXR1cm4gY2FtbF9zdHJpbmdfb2ZfanNzdHJpbmcoXCJuYW5cIik7XG4gICAgcmV0dXJuIGNhbWxfc3RyaW5nX29mX2pzc3RyaW5nICgoeCA+IDApP1wiaW5maW5pdHlcIjpcIi1pbmZpbml0eVwiKTtcbiAgfVxuICB2YXIgc2lnbiA9ICh4PT0wICYmIDEveCA9PSAtSW5maW5pdHkpPzE6KHg+PTApPzA6MTtcbiAgaWYoc2lnbikgeCA9IC14O1xuICB2YXIgZXhwID0gMDtcbiAgaWYgKHggPT0gMCkgeyB9XG4gIGVsc2UgaWYgKHggPCAxKSB7XG4gICAgd2hpbGUgKHggPCAxICYmIGV4cCA+IC0xMDIyKSAgeyB4ICo9IDI7IGV4cC0tIH1cbiAgfSBlbHNlIHtcbiAgICB3aGlsZSAoeCA+PSAyKSB7IHggLz0gMjsgZXhwKysgfVxuICB9XG4gIHZhciBleHBfc2lnbiA9IGV4cCA8IDAgPyAnJyA6ICcrJztcbiAgdmFyIHNpZ25fc3RyID0gJyc7XG4gIGlmIChzaWduKSBzaWduX3N0ciA9ICctJ1xuICBlbHNlIHtcbiAgICBzd2l0Y2goc3R5bGUpe1xuICAgIGNhc2UgNDMgLyogJysnICovOiBzaWduX3N0ciA9ICcrJzsgYnJlYWs7XG4gICAgY2FzZSAzMiAvKiAnICcgKi86IHNpZ25fc3RyID0gJyAnOyBicmVhaztcbiAgICBkZWZhdWx0OiBicmVhaztcbiAgICB9XG4gIH1cbiAgaWYgKHByZWMgPj0gMCAmJiBwcmVjIDwgMTMpIHtcbiAgICAvKiBJZiBhIHByZWNpc2lvbiBpcyBnaXZlbiwgYW5kIGlzIHNtYWxsLCByb3VuZCBtYW50aXNzYSBhY2NvcmRpbmdseSAqL1xuICAgIHZhciBjc3QgPSBNYXRoLnBvdygyLHByZWMgKiA0KTtcbiAgICB4ID0gTWF0aC5yb3VuZCh4ICogY3N0KSAvIGNzdDtcbiAgfVxuICB2YXIgeF9zdHIgPSB4LnRvU3RyaW5nKDE2KTtcbiAgaWYocHJlYyA+PSAwKXtcbiAgICB2YXIgaWR4ID0geF9zdHIuaW5kZXhPZignLicpO1xuICAgIGlmKGlkeDwwKSB7XG4gICAgICB4X3N0ciArPSAnLicgKyBjYW1sX3N0cl9yZXBlYXQocHJlYywgJzAnKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB2YXIgc2l6ZSA9IGlkeCsxK3ByZWM7XG4gICAgICBpZih4X3N0ci5sZW5ndGggPCBzaXplKVxuICAgICAgICB4X3N0ciArPSBjYW1sX3N0cl9yZXBlYXQoc2l6ZSAtIHhfc3RyLmxlbmd0aCwgJzAnKTtcbiAgICAgIGVsc2VcbiAgICAgICAgeF9zdHIgPSB4X3N0ci5zdWJzdHIoMCxzaXplKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNhbWxfc3RyaW5nX29mX2pzc3RyaW5nIChzaWduX3N0ciArICcweCcgKyB4X3N0ciArICdwJyArIGV4cF9zaWduICsgZXhwLnRvU3RyaW5nKDEwKSk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfaW50NjRfZmxvYXRfb2ZfYml0cyBjb25zdFxuZnVuY3Rpb24gY2FtbF9pbnQ2NF9mbG9hdF9vZl9iaXRzICh4KSB7XG4gIHZhciBsbyA9IHgubG87XG4gIHZhciBtaSA9IHgubWk7XG4gIHZhciBoaSA9IHguaGk7XG4gIHZhciBleHAgPSAoaGkgJiAweDdmZmYpID4+IDQ7XG4gIGlmIChleHAgPT0gMjA0Nykge1xuICAgIGlmICgobG98bWl8KGhpJjB4ZikpID09IDApXG4gICAgICByZXR1cm4gKGhpICYgMHg4MDAwKT8oLUluZmluaXR5KTpJbmZpbml0eTtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gTmFOO1xuICB9XG4gIHZhciBrID0gTWF0aC5wb3coMiwtMjQpO1xuICB2YXIgcmVzID0gKGxvKmsrbWkpKmsrKGhpJjB4Zik7XG4gIGlmIChleHAgPiAwKSB7XG4gICAgcmVzICs9IDE2O1xuICAgIHJlcyAqPSBNYXRoLnBvdygyLGV4cC0xMDI3KTtcbiAgfSBlbHNlXG4gICAgcmVzICo9IE1hdGgucG93KDIsLTEwMjYpO1xuICBpZiAoaGkgJiAweDgwMDApIHJlcyA9IC0gcmVzO1xuICByZXR1cm4gcmVzO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX25leHRhZnRlcl9mbG9hdCBjb25zdFxuLy9SZXF1aXJlczogY2FtbF9pbnQ2NF9mbG9hdF9vZl9iaXRzLCBjYW1sX2ludDY0X2JpdHNfb2ZfZmxvYXQsIGNhbWxfaW50NjRfYWRkLCBjYW1sX2ludDY0X3N1YixjYW1sX2ludDY0X29mX2ludDMyXG5mdW5jdGlvbiBjYW1sX25leHRhZnRlcl9mbG9hdCAoeCx5KSB7XG4gIGlmKGlzTmFOKHgpIHx8IGlzTmFOKHkpKSByZXR1cm4gTmFOO1xuICBpZih4PT15KSByZXR1cm4geTtcbiAgaWYoeD09MCl7XG4gICAgaWYoeSA8IDApXG4gICAgICByZXR1cm4gLU1hdGgucG93KDIsIC0xMDc0KVxuICAgIGVsc2VcbiAgICAgIHJldHVybiBNYXRoLnBvdygyLCAtMTA3NClcbiAgfVxuICB2YXIgYml0cyA9IGNhbWxfaW50NjRfYml0c19vZl9mbG9hdCh4KTtcbiAgdmFyIG9uZSA9IGNhbWxfaW50NjRfb2ZfaW50MzIoMSk7XG4gIGlmICgoeDx5KSA9PSAoeD4wKSlcbiAgICBiaXRzID0gY2FtbF9pbnQ2NF9hZGQoYml0cywgb25lKVxuICBlbHNlXG4gICAgYml0cyA9IGNhbWxfaW50NjRfc3ViKGJpdHMsIG9uZSlcbiAgcmV0dXJuIGNhbWxfaW50NjRfZmxvYXRfb2ZfYml0cyhiaXRzKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF90cnVuY19mbG9hdFxuZnVuY3Rpb24gY2FtbF90cnVuY19mbG9hdCh4KXtcbiAgcmV0dXJuIE1hdGgudHJ1bmMoeCk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfaW50MzJfZmxvYXRfb2ZfYml0cyBjb25zdFxuZnVuY3Rpb24gY2FtbF9pbnQzMl9mbG9hdF9vZl9iaXRzICh4KSB7XG4gIHZhciBpbnQzMmEgPSBuZXcgSW50MzJBcnJheSgxKTtcbiAgaW50MzJhWzBdID0geDtcbiAgdmFyIGZsb2F0MzJhID0gbmV3IEZsb2F0MzJBcnJheShpbnQzMmEuYnVmZmVyKTtcbiAgcmV0dXJuIGZsb2F0MzJhWzBdO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2NsYXNzaWZ5X2Zsb2F0IGNvbnN0XG5mdW5jdGlvbiBjYW1sX2NsYXNzaWZ5X2Zsb2F0ICh4KSB7XG4gIGlmIChpc0Zpbml0ZSAoeCkpIHtcbiAgICBpZiAoTWF0aC5hYnMoeCkgPj0gMi4yMjUwNzM4NTg1MDcyMDE0ZS0zMDgpIHJldHVybiAwO1xuICAgIGlmICh4ICE9IDApIHJldHVybiAxO1xuICAgIHJldHVybiAyO1xuICB9XG4gIHJldHVybiBpc05hTih4KT80OjM7XG59XG4vL1Byb3ZpZGVzOiBjYW1sX21vZGZfZmxvYXQgY29uc3RcbmZ1bmN0aW9uIGNhbWxfbW9kZl9mbG9hdCAoeCkge1xuICBpZiAoaXNGaW5pdGUgKHgpKSB7XG4gICAgdmFyIG5lZyA9ICgxL3gpIDwgMDtcbiAgICB4ID0gTWF0aC5hYnMoeCk7XG4gICAgdmFyIGkgPSBNYXRoLmZsb29yICh4KTtcbiAgICB2YXIgZiA9IHggLSBpO1xuICAgIGlmIChuZWcpIHsgaSA9IC1pOyBmID0gLWY7IH1cbiAgICByZXR1cm4gWzAsIGYsIGldO1xuICB9XG4gIGlmIChpc05hTiAoeCkpIHJldHVybiBbMCwgTmFOLCBOYU5dO1xuICByZXR1cm4gWzAsIDEveCwgeF07XG59XG4vL1Byb3ZpZGVzOiBjYW1sX2xkZXhwX2Zsb2F0IGNvbnN0XG5mdW5jdGlvbiBjYW1sX2xkZXhwX2Zsb2F0ICh4LGV4cCkge1xuICBleHAgfD0gMDtcbiAgaWYgKGV4cCA+IDEwMjMpIHtcbiAgICBleHAgLT0gMTAyMztcbiAgICB4ICo9IE1hdGgucG93KDIsIDEwMjMpO1xuICAgIGlmIChleHAgPiAxMDIzKSB7ICAvLyBpbiBjYXNlIHggaXMgc3Vibm9ybWFsXG4gICAgICBleHAgLT0gMTAyMztcbiAgICAgIHggKj0gTWF0aC5wb3coMiwgMTAyMyk7XG4gICAgfVxuICB9XG4gIGlmIChleHAgPCAtMTAyMykge1xuICAgIGV4cCArPSAxMDIzO1xuICAgIHggKj0gTWF0aC5wb3coMiwgLTEwMjMpO1xuICB9XG4gIHggKj0gTWF0aC5wb3coMiwgZXhwKTtcbiAgcmV0dXJuIHg7XG59XG4vL1Byb3ZpZGVzOiBjYW1sX2ZyZXhwX2Zsb2F0IGNvbnN0XG4vL1JlcXVpcmVzOiBqc29vX2Zsb29yX2xvZzJcbmZ1bmN0aW9uIGNhbWxfZnJleHBfZmxvYXQgKHgpIHtcbiAgaWYgKCh4ID09IDApIHx8ICFpc0Zpbml0ZSh4KSkgcmV0dXJuIFswLCB4LCAwXTtcbiAgdmFyIG5lZyA9IHggPCAwO1xuICBpZiAobmVnKSB4ID0gLSB4O1xuICB2YXIgZXhwID0gTWF0aC5tYXgoLTEwMjMsIGpzb29fZmxvb3JfbG9nMih4KSArIDEpO1xuICB4ICo9IE1hdGgucG93KDIsLWV4cCk7XG4gIHdoaWxlICh4IDwgMC41KSB7XG4gICAgeCAqPSAyO1xuICAgIGV4cC0tO1xuICB9XG4gIHdoaWxlICh4ID49IDEpIHtcbiAgICB4ICo9IDAuNTtcbiAgICBleHArKztcbiAgfVxuICBpZiAobmVnKSB4ID0gLSB4O1xuICByZXR1cm4gWzAsIHgsIGV4cF07XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfZmxvYXRfY29tcGFyZSBjb25zdFxuZnVuY3Rpb24gY2FtbF9mbG9hdF9jb21wYXJlICh4LCB5KSB7XG4gIGlmICh4ID09PSB5KSByZXR1cm4gMDtcbiAgaWYgKHggPCB5KSByZXR1cm4gLTE7XG4gIGlmICh4ID4geSkgcmV0dXJuIDE7XG4gIGlmICh4ID09PSB4KSByZXR1cm4gMTtcbiAgaWYgKHkgPT09IHkpIHJldHVybiAtMTtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfY29weXNpZ25fZmxvYXQgY29uc3RcbmZ1bmN0aW9uIGNhbWxfY29weXNpZ25fZmxvYXQgKHgsIHkpIHtcbiAgaWYgKHkgPT0gMCkgeSA9IDEgLyB5O1xuICB4ID0gTWF0aC5hYnMoeCk7XG4gIHJldHVybiAoeSA8IDApPygteCk6eDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zaWduYml0X2Zsb2F0IGNvbnN0XG5mdW5jdGlvbiBjYW1sX3NpZ25iaXRfZmxvYXQoeCkge1xuICBpZiAoeCA9PSAwKSB4ID0gMSAvIHg7XG4gIHJldHVybiAoeCA8IDApPzE6MDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9leHBtMV9mbG9hdCBjb25zdFxuZnVuY3Rpb24gY2FtbF9leHBtMV9mbG9hdCAoeCkgeyByZXR1cm4gTWF0aC5leHBtMSh4KTsgfVxuLy9Qcm92aWRlczogY2FtbF9leHAyX2Zsb2F0IGNvbnN0XG5mdW5jdGlvbiBjYW1sX2V4cDJfZmxvYXQoeCkgeyByZXR1cm4gTWF0aC5wb3coMiwgeCk7IH1cbi8vUHJvdmlkZXM6IGNhbWxfbG9nMXBfZmxvYXQgY29uc3RcbmZ1bmN0aW9uIGNhbWxfbG9nMXBfZmxvYXQoeCkgeyByZXR1cm4gTWF0aC5sb2cxcCh4KTsgfVxuLy9Qcm92aWRlczogY2FtbF9sb2cyX2Zsb2F0IGNvbnN0XG5mdW5jdGlvbiBjYW1sX2xvZzJfZmxvYXQoeCkgeyByZXR1cm4gTWF0aC5sb2cyKHgpOyB9XG4vL1Byb3ZpZGVzOiBjYW1sX2h5cG90X2Zsb2F0IGNvbnN0XG5mdW5jdGlvbiBjYW1sX2h5cG90X2Zsb2F0ICh4LCB5KSB7IHJldHVybiBNYXRoLmh5cG90KHgsIHkpOyB9XG4vL1Byb3ZpZGVzOiBjYW1sX2xvZzEwX2Zsb2F0IGNvbnN0XG5mdW5jdGlvbiBjYW1sX2xvZzEwX2Zsb2F0ICh4KSB7IHJldHVybiBNYXRoLmxvZzEwKHgpOyB9XG4vL1Byb3ZpZGVzOiBjYW1sX2Nvc2hfZmxvYXQgY29uc3RcbmZ1bmN0aW9uIGNhbWxfY29zaF9mbG9hdCAoeCkgeyByZXR1cm4gTWF0aC5jb3NoKHgpOyB9XG4vL1Byb3ZpZGVzOiBjYW1sX2Fjb3NoX2Zsb2F0IGNvbnN0XG5mdW5jdGlvbiBjYW1sX2Fjb3NoX2Zsb2F0ICh4KSB7IHJldHVybiBNYXRoLmFjb3NoKHgpOyB9XG4vL1Byb3ZpZGVzOiBjYW1sX3NpbmhfZmxvYXQgY29uc3RcbmZ1bmN0aW9uIGNhbWxfc2luaF9mbG9hdCAoeCkgeyByZXR1cm4gTWF0aC5zaW5oKHgpOyB9XG4vL1Byb3ZpZGVzOiBjYW1sX2FzaW5oX2Zsb2F0IGNvbnN0XG5mdW5jdGlvbiBjYW1sX2FzaW5oX2Zsb2F0ICh4KSB7IHJldHVybiBNYXRoLmFzaW5oKHgpOyB9XG4vL1Byb3ZpZGVzOiBjYW1sX3RhbmhfZmxvYXQgY29uc3RcbmZ1bmN0aW9uIGNhbWxfdGFuaF9mbG9hdCAoeCkgeyByZXR1cm4gTWF0aC50YW5oKHgpOyB9XG4vL1Byb3ZpZGVzOiBjYW1sX2F0YW5oX2Zsb2F0IGNvbnN0XG5mdW5jdGlvbiBjYW1sX2F0YW5oX2Zsb2F0ICh4KSB7IHJldHVybiBNYXRoLmF0YW5oKHgpOyB9XG4vL1Byb3ZpZGVzOiBjYW1sX3JvdW5kX2Zsb2F0IGNvbnN0XG5mdW5jdGlvbiBjYW1sX3JvdW5kX2Zsb2F0ICh4KSB7XG4gIGlmICh4ID49IDApIHtcbiAgICB2YXIgeSA9IE1hdGguZmxvb3IoeCk7XG4gICAgcmV0dXJuICh4IC0geSA+PSAwLjUpPyh5ICsgMSk6eVxuICB9IGVsc2Uge1xuICAgIHZhciB5ID0gTWF0aC5jZWlsKHgpO1xuICAgIHJldHVybiAoeSAtIHggPj0gMC41KT8oeSAtIDEpOnlcbiAgfVxufVxuLy9Qcm92aWRlczogY2FtbF9jYnJ0X2Zsb2F0IGNvbnN0XG5mdW5jdGlvbiBjYW1sX2NicnRfZmxvYXQgKHgpIHsgcmV0dXJuIE1hdGguY2JydCh4KTsgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2VyZl9mbG9hdCBjb25zdFxuZnVuY3Rpb24gY2FtbF9lcmZfZmxvYXQoeCkge1xuICB2YXIgYTEgPSAwLjI1NDgyOTU5MjtcbiAgdmFyIGEyID0gLTAuMjg0NDk2NzM2O1xuICB2YXIgYTMgPSAxLjQyMTQxMzc0MTtcbiAgdmFyIGE0ID0gLTEuNDUzMTUyMDI3O1xuICB2YXIgYTUgPSAxLjA2MTQwNTQyOTtcbiAgdmFyIHAgPSAwLjMyNzU5MTE7XG5cbiAgdmFyIHNpZ24gPSAxO1xuICBpZiAoeCA8IDApIHtcbiAgICBzaWduID0gLTE7XG4gIH1cbiAgeCA9IE1hdGguYWJzKHgpO1xuICB2YXIgdCA9IDEuMCAvICgxLjAgKyBwICogeCk7XG4gIHZhciB5ID0gMS4wIC0gKCgoKGE1ICogdCArIGE0KSAqIHQgKyBhMykgKiB0ICsgYTIpICogdCArIGExKSAqIHQgKiBNYXRoLmV4cCgteCAqIHgpO1xuXG4gIHJldHVybiBzaWduICogeTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9lcmZjX2Zsb2F0IGNvbnN0XG4vL1JlcXVpcmVzOiBjYW1sX2VyZl9mbG9hdFxuZnVuY3Rpb24gY2FtbF9lcmZjX2Zsb2F0KHgpIHtcbiAgcmV0dXJuIDEgLSBjYW1sX2VyZl9mbG9hdCh4KTtcbn1cblxuXG4vL1Byb3ZpZGVzOiBjYW1sX2ZtYV9mbG9hdCBjb25zdFxuZnVuY3Rpb24gY2FtbF9mbWFfZmxvYXQoeCwgeSwgeikge1xuICB2YXIgU1BMSVQgPSBNYXRoLnBvdygyLCAyNykgKyAxO1xuICB2YXIgTUlOX1ZBTFVFID0gTWF0aC5wb3coMiwgLTEwMjIpO1xuICB2YXIgRVBTSUxPTiA9IE1hdGgucG93KDIsIC01Mik7XG4gIHZhciBDID0gNDE2O1xuICB2YXIgQSA9IE1hdGgucG93KDIsICtDKTtcbiAgdmFyIEIgPSBNYXRoLnBvdygyLCAtQyk7XG5cbiAgZnVuY3Rpb24gbXVsdGlwbHkgKGEsIGIpIHtcbiAgICB2YXIgYXQgPSBTUExJVCAqIGE7XG4gICAgdmFyIGFoaSA9IGF0IC0gKGF0IC0gYSk7XG4gICAgdmFyIGFsbyA9IGEgLSBhaGk7XG4gICAgdmFyIGJ0ID0gU1BMSVQgKiBiO1xuICAgIHZhciBiaGkgPSBidCAtIChidCAtIGIpO1xuICAgIHZhciBibG8gPSBiIC0gYmhpO1xuICAgIHZhciBwID0gYSAqIGI7XG4gICAgdmFyIGUgPSAoKGFoaSAqIGJoaSAtIHApICsgYWhpICogYmxvICsgYWxvICogYmhpKSArIGFsbyAqIGJsbztcbiAgICByZXR1cm4ge1xuICAgICAgcDogcCxcbiAgICAgIGU6IGVcbiAgICB9O1xuICB9O1xuXG4gIGZ1bmN0aW9uIGFkZCAoYSwgYikge1xuICAgIHZhciBzID0gYSArIGI7XG4gICAgdmFyIHYgPSBzIC0gYTtcbiAgICB2YXIgZSA9IChhIC0gKHMgLSB2KSkgKyAoYiAtIHYpO1xuICAgIHJldHVybiB7XG4gICAgICBzOiBzLFxuICAgICAgZTogZVxuICAgIH07XG4gIH07XG5cbiAgZnVuY3Rpb24gYWRqdXN0ICh4LCB5KSB7XG4gICAgcmV0dXJuIHggIT09IDAgJiYgeSAhPT0gMCAmJiBTUExJVCAqIHggLSAoU1BMSVQgKiB4IC0geCkgPT09IHggPyB4ICogKDEgKyAoeCA8IDAgPyAtMSA6ICsxKSAqICh5IDwgMCA/IC0xIDogKzEpICogRVBTSUxPTikgOiB4O1xuICB9O1xuXG4gIGlmICh4ID09PSAwIHx8IHggIT09IHggfHwgeCA9PT0gKzEgLyAwIHx8IHggPT09IC0xIC8gMCB8fFxuICAgICAgeSA9PT0gMCB8fCB5ICE9PSB5IHx8IHkgPT09ICsxIC8gMCB8fCB5ID09PSAtMSAvIDApIHtcbiAgICByZXR1cm4geCAqIHkgKyB6O1xuICB9XG4gIGlmICh6ID09PSAwKSB7XG4gICAgcmV0dXJuIHggKiB5O1xuICB9XG4gIGlmICh6ICE9PSB6IHx8IHogPT09ICsxIC8gMCB8fCB6ID09PSAtMSAvIDApIHtcbiAgICByZXR1cm4gejtcbiAgfVxuXG4gIHZhciBzY2FsZSA9IDE7XG4gIHdoaWxlIChNYXRoLmFicyh4KSA+IEEpIHtcbiAgICBzY2FsZSAqPSBBO1xuICAgIHggKj0gQjtcbiAgfVxuICB3aGlsZSAoTWF0aC5hYnMoeSkgPiBBKSB7XG4gICAgc2NhbGUgKj0gQTtcbiAgICB5ICo9IEI7XG4gIH1cbiAgaWYgKHNjYWxlID09PSAxIC8gMCkge1xuICAgIHJldHVybiB4ICogeSAqIHNjYWxlO1xuICB9XG4gIHdoaWxlIChNYXRoLmFicyh4KSA8IEIpIHtcbiAgICBzY2FsZSAqPSBCO1xuICAgIHggKj0gQTtcbiAgfVxuICB3aGlsZSAoTWF0aC5hYnMoeSkgPCBCKSB7XG4gICAgc2NhbGUgKj0gQjtcbiAgICB5ICo9IEE7XG4gIH1cbiAgaWYgKHNjYWxlID09PSAwKSB7XG4gICAgcmV0dXJuIHo7XG4gIH1cblxuICB2YXIgeHMgPSB4O1xuICB2YXIgeXMgPSB5O1xuICB2YXIgenMgPSB6IC8gc2NhbGU7XG5cbiAgaWYgKE1hdGguYWJzKHpzKSA+IE1hdGguYWJzKHhzICogeXMpICogNCAvIEVQU0lMT04pIHtcbiAgICByZXR1cm4gejtcbiAgfVxuICBpZiAoTWF0aC5hYnMoenMpIDwgTWF0aC5hYnMoeHMgKiB5cykgKiBFUFNJTE9OIC8gNCAqIEVQU0lMT04gLyA0KSB7XG4gICAgenMgPSAoeiA8IDAgPyAtMSA6ICsxKSAqIE1JTl9WQUxVRTtcbiAgfVxuXG4gIHZhciB4eSA9IG11bHRpcGx5KHhzLCB5cyk7XG4gIHZhciBzID0gYWRkKHh5LnAsIHpzKTtcbiAgdmFyIHUgPSBhZGQoeHkuZSwgcy5lKTtcbiAgdmFyIGkgPSBhZGQocy5zLCB1LnMpO1xuXG4gIHZhciBmID0gaS5zICsgYWRqdXN0KGkuZSwgdS5lKTtcbiAgaWYgKGYgPT09IDApIHtcbiAgICByZXR1cm4gZjtcbiAgfVxuXG4gIHZhciBmcyA9IGYgKiBzY2FsZTtcbiAgaWYgKE1hdGguYWJzKGZzKSA+IE1JTl9WQUxVRSkge1xuICAgIHJldHVybiBmcztcbiAgfVxuXG4gIC8vIEl0IGlzIHBvc3NpYmxlIHRoYXQgdGhlcmUgd2FzIGV4dHJhIHJvdW5kaW5nIGZvciBhIGRlbm9ybWFsaXplZCB2YWx1ZS5cbiAgcmV0dXJuIGZzICsgYWRqdXN0KGYgLSBmcyAvIHNjYWxlLCBpLmUpICogc2NhbGU7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfZm9ybWF0X2Zsb2F0IGNvbnN0XG4vL1JlcXVpcmVzOiBjYW1sX3BhcnNlX2Zvcm1hdCwgY2FtbF9maW5pc2hfZm9ybWF0dGluZ1xuZnVuY3Rpb24gY2FtbF9mb3JtYXRfZmxvYXQgKGZtdCwgeCkge1xuICBmdW5jdGlvbiB0b0ZpeGVkKHgsZHApIHtcbiAgICBpZiAoTWF0aC5hYnMoeCkgPCAxLjApIHtcbiAgICAgIHJldHVybiB4LnRvRml4ZWQoZHApO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgZSA9IHBhcnNlSW50KHgudG9TdHJpbmcoKS5zcGxpdCgnKycpWzFdKTtcbiAgICAgIGlmIChlID4gMjApIHtcbiAgICAgICAgZSAtPSAyMDtcbiAgICAgICAgeCAvPSBNYXRoLnBvdygxMCxlKTtcbiAgICAgICAgeCArPSAobmV3IEFycmF5KGUrMSkpLmpvaW4oJzAnKTtcbiAgICAgICAgaWYoZHAgPiAwKSB7XG4gICAgICAgICAgeCA9IHggKyAnLicgKyAobmV3IEFycmF5KGRwKzEpKS5qb2luKCcwJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHg7XG4gICAgICB9XG4gICAgICBlbHNlIHJldHVybiB4LnRvRml4ZWQoZHApXG4gICAgfVxuICB9XG4gIHZhciBzLCBmID0gY2FtbF9wYXJzZV9mb3JtYXQoZm10KTtcbiAgdmFyIHByZWMgPSAoZi5wcmVjIDwgMCk/NjpmLnByZWM7XG4gIGlmICh4IDwgMCB8fCAoeCA9PSAwICYmIDEveCA9PSAtSW5maW5pdHkpKSB7IGYuc2lnbiA9IC0xOyB4ID0gLXg7IH1cbiAgaWYgKGlzTmFOKHgpKSB7IHMgPSBcIm5hblwiOyBmLmZpbGxlciA9ICcgJzsgfVxuICBlbHNlIGlmICghaXNGaW5pdGUoeCkpIHsgcyA9IFwiaW5mXCI7IGYuZmlsbGVyID0gJyAnOyB9XG4gIGVsc2VcbiAgICBzd2l0Y2ggKGYuY29udikge1xuICAgIGNhc2UgJ2UnOlxuICAgICAgdmFyIHMgPSB4LnRvRXhwb25lbnRpYWwocHJlYyk7XG4gICAgICAvLyBleHBvbmVudCBzaG91bGQgYmUgYXQgbGVhc3QgdHdvIGRpZ2l0c1xuICAgICAgdmFyIGkgPSBzLmxlbmd0aDtcbiAgICAgIGlmIChzLmNoYXJBdChpIC0gMykgPT0gJ2UnKVxuICAgICAgICBzID0gcy5zbGljZSAoMCwgaSAtIDEpICsgJzAnICsgcy5zbGljZSAoaSAtIDEpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnZic6XG4gICAgICBzID0gdG9GaXhlZCh4LCBwcmVjKTsgYnJlYWs7XG4gICAgY2FzZSAnZyc6XG4gICAgICBwcmVjID0gcHJlYz9wcmVjOjE7XG4gICAgICBzID0geC50b0V4cG9uZW50aWFsKHByZWMgLSAxKTtcbiAgICAgIHZhciBqID0gcy5pbmRleE9mKCdlJyk7XG4gICAgICB2YXIgZXhwID0gK3Muc2xpY2UoaiArIDEpO1xuICAgICAgaWYgKGV4cCA8IC00IHx8IHggPj0gMWUyMSB8fCB4LnRvRml4ZWQoMCkubGVuZ3RoID4gcHJlYykge1xuICAgICAgICAvLyByZW1vdmUgdHJhaWxpbmcgemVyb2VzXG4gICAgICAgIHZhciBpID0gaiAtIDE7IHdoaWxlIChzLmNoYXJBdChpKSA9PSAnMCcpIGktLTtcbiAgICAgICAgaWYgKHMuY2hhckF0KGkpID09ICcuJykgaS0tO1xuICAgICAgICBzID0gcy5zbGljZSgwLCBpICsgMSkgKyBzLnNsaWNlKGopO1xuICAgICAgICBpID0gcy5sZW5ndGg7XG4gICAgICAgIGlmIChzLmNoYXJBdChpIC0gMykgPT0gJ2UnKVxuICAgICAgICAgIHMgPSBzLnNsaWNlICgwLCBpIC0gMSkgKyAnMCcgKyBzLnNsaWNlIChpIC0gMSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHAgPSBwcmVjO1xuICAgICAgICBpZiAoZXhwIDwgMCkgeyBwIC09IGV4cCArIDE7IHMgPSB4LnRvRml4ZWQocCk7IH1cbiAgICAgICAgZWxzZSB3aGlsZSAocyA9IHgudG9GaXhlZChwKSwgcy5sZW5ndGggPiBwcmVjICsgMSkgcC0tO1xuICAgICAgICBpZiAocCkge1xuICAgICAgICAgIC8vIHJlbW92ZSB0cmFpbGluZyB6ZXJvZXNcbiAgICAgICAgICB2YXIgaSA9IHMubGVuZ3RoIC0gMTsgd2hpbGUgKHMuY2hhckF0KGkpID09ICcwJykgaS0tO1xuICAgICAgICAgIGlmIChzLmNoYXJBdChpKSA9PSAnLicpIGktLTtcbiAgICAgICAgICBzID0gcy5zbGljZSgwLCBpICsgMSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgcmV0dXJuIGNhbWxfZmluaXNoX2Zvcm1hdHRpbmcoZiwgcyk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfZmxvYXRfb2Zfc3RyaW5nIChjb25zdClcbi8vUmVxdWlyZXM6IGNhbWxfZmFpbHdpdGgsIGNhbWxfanNieXRlc19vZl9zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfZmxvYXRfb2Zfc3RyaW5nKHMpIHtcbiAgdmFyIHJlcztcbiAgcyA9IGNhbWxfanNieXRlc19vZl9zdHJpbmcocylcbiAgcmVzID0gK3M7XG4gIGlmICgocy5sZW5ndGggPiAwKSAmJiAocmVzID09PSByZXMpKSByZXR1cm4gcmVzO1xuICBzID0gcy5yZXBsYWNlKC9fL2csXCJcIik7XG4gIHJlcyA9ICtzO1xuICBpZiAoKChzLmxlbmd0aCA+IDApICYmIChyZXMgPT09IHJlcykpIHx8IC9eWystXT9uYW4kL2kudGVzdChzKSkgcmV0dXJuIHJlcztcbiAgdmFyIG0gPSAvXiAqKFsrLV0/KTB4KFswLTlhLWZdKylcXC4/KFswLTlhLWZdKikocChbKy1dP1swLTldKykpPy9pLmV4ZWMocyk7XG4gIC8vICAgICAgICAgIDEgICAgICAgIDIgICAgICAgICAgICAgMyAgICAgICAgICAgNVxuICBpZihtKXtcbiAgICB2YXIgbTMgPSBtWzNdLnJlcGxhY2UoLzArJC8sJycpO1xuICAgIHZhciBtYW50aXNzYSA9IHBhcnNlSW50KG1bMV0gKyBtWzJdICsgbTMsIDE2KTtcbiAgICB2YXIgZXhwb25lbnQgPSAobVs1XXwwKSAtIDQqbTMubGVuZ3RoO1xuICAgIHJlcyA9IG1hbnRpc3NhICogTWF0aC5wb3coMiwgZXhwb25lbnQpO1xuICAgIHJldHVybiByZXM7XG4gIH1cbiAgaWYoL15cXCs/aW5mKGluaXR5KT8kL2kudGVzdChzKSkgcmV0dXJuIEluZmluaXR5O1xuICBpZigvXi1pbmYoaW5pdHkpPyQvaS50ZXN0KHMpKSByZXR1cm4gLUluZmluaXR5O1xuICBjYW1sX2ZhaWx3aXRoKFwiZmxvYXRfb2Zfc3RyaW5nXCIpO1xufVxuIiwiLy8gSnNfb2Zfb2NhbWwgcnVudGltZSBzdXBwb3J0XG4vLyBodHRwOi8vd3d3Lm9jc2lnZW4ub3JnL2pzX29mX29jYW1sL1xuLy9cbi8vIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4vLyBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbi8vIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHdpdGggbGlua2luZyBleGNlcHRpb247XG4vLyBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vL1xuLy8gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuLy8gR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vL1xuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4vLyBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcsIFVTQS5cblxuLy9Qcm92aWRlczogY2FtbF91cGRhdGVfZHVtbXlcbmZ1bmN0aW9uIGNhbWxfdXBkYXRlX2R1bW15ICh4LCB5KSB7XG4gIGlmKCB5LmZ1biApIHsgeC5mdW4gPSB5LmZ1bjsgcmV0dXJuIDA7IH1cbiAgaWYoIHR5cGVvZiB5PT09XCJmdW5jdGlvblwiICkgeyB4LmZ1biA9IHk7IHJldHVybiAwOyB9XG4gIHZhciBpID0geS5sZW5ndGg7IHdoaWxlIChpLS0pIHhbaV0gPSB5W2ldOyByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9hbGxvY19kdW1teV9pbmZpeFxuLy9SZXF1aXJlczogY2FtbF9jYWxsX2dlblxuZnVuY3Rpb24gY2FtbF9hbGxvY19kdW1teV9pbmZpeCAoKSB7XG4gIHJldHVybiBmdW5jdGlvbiBmICh4KSB7IHJldHVybiBjYW1sX2NhbGxfZ2VuKGYuZnVuLCBbeF0pIH1cbn1cblxuLy9Qcm92aWRlczogY2FtbF9vYmpfaXNfYmxvY2sgY29uc3QgKGNvbnN0KVxuZnVuY3Rpb24gY2FtbF9vYmpfaXNfYmxvY2sgKHgpIHsgcmV0dXJuICsoeCBpbnN0YW5jZW9mIEFycmF5KTsgfVxuXG5cbi8vUHJvdmlkZXM6IGNhbWxfb2JqX3RhZ1xuLy9SZXF1aXJlczogY2FtbF9pc19tbF9ieXRlcywgY2FtbF9pc19tbF9zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfb2JqX3RhZyAoeCkge1xuICBpZiAoKHggaW5zdGFuY2VvZiBBcnJheSkgJiYgeFswXSA9PSAoeFswXSA+Pj4gMCkpXG4gICAgcmV0dXJuIHhbMF1cbiAgZWxzZSBpZiAoY2FtbF9pc19tbF9ieXRlcyh4KSlcbiAgICByZXR1cm4gMjUyXG4gIGVsc2UgaWYgKGNhbWxfaXNfbWxfc3RyaW5nKHgpKVxuICAgIHJldHVybiAyNTJcbiAgZWxzZSBpZiAoKHggaW5zdGFuY2VvZiBGdW5jdGlvbikgfHwgdHlwZW9mIHggPT0gXCJmdW5jdGlvblwiKVxuICAgIHJldHVybiAyNDdcbiAgZWxzZSBpZiAoeCAmJiB4LmNhbWxfY3VzdG9tKVxuICAgIHJldHVybiAyNTVcbiAgZWxzZVxuICAgIHJldHVybiAxMDAwXG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfb2JqX3NldF90YWcgKG11dGFibGUsIGNvbnN0KVxuZnVuY3Rpb24gY2FtbF9vYmpfc2V0X3RhZyAoeCwgdGFnKSB7IHhbMF0gPSB0YWc7IHJldHVybiAwOyB9XG4vL1Byb3ZpZGVzOiBjYW1sX29ial9ibG9jayBjb25zdCAoY29uc3QsY29uc3QpXG5mdW5jdGlvbiBjYW1sX29ial9ibG9jayAodGFnLCBzaXplKSB7XG4gIHZhciBvID0gbmV3IEFycmF5KHNpemUrMSk7XG4gIG9bMF09dGFnO1xuICBmb3IgKHZhciBpID0gMTsgaSA8PSBzaXplOyBpKyspIG9baV0gPSAwO1xuICByZXR1cm4gbztcbn1cblxuLy9Qcm92aWRlczogY2FtbF9vYmpfd2l0aF90YWdcbmZ1bmN0aW9uIGNhbWxfb2JqX3dpdGhfdGFnKHRhZyx4KSB7XG4gIHZhciBsID0geC5sZW5ndGg7XG4gIHZhciBhID0gbmV3IEFycmF5KGwpO1xuICBhWzBdID0gdGFnO1xuICBmb3IodmFyIGkgPSAxOyBpIDwgbDsgaSsrICkgYVtpXSA9IHhbaV07XG4gIHJldHVybiBhO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX29ial9kdXAgbXV0YWJsZSAobXV0YWJsZSlcbmZ1bmN0aW9uIGNhbWxfb2JqX2R1cCAoeCkge1xuICB2YXIgbCA9IHgubGVuZ3RoO1xuICB2YXIgYSA9IG5ldyBBcnJheShsKTtcbiAgZm9yKHZhciBpID0gMDsgaSA8IGw7IGkrKyApIGFbaV0gPSB4W2ldO1xuICByZXR1cm4gYTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9vYmpfdHJ1bmNhdGUgKG11dGFibGUsIGNvbnN0KVxuLy9SZXF1aXJlczogY2FtbF9pbnZhbGlkX2FyZ3VtZW50XG5mdW5jdGlvbiBjYW1sX29ial90cnVuY2F0ZSAoeCwgcykge1xuICBpZiAoczw9MCB8fCBzICsgMSA+IHgubGVuZ3RoKVxuICAgIGNhbWxfaW52YWxpZF9hcmd1bWVudCAoXCJPYmoudHJ1bmNhdGVcIik7XG4gIGlmICh4Lmxlbmd0aCAhPSBzICsgMSkgeC5sZW5ndGggPSBzICsgMTtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfb2JqX21ha2VfZm9yd2FyZFxuZnVuY3Rpb24gY2FtbF9vYmpfbWFrZV9mb3J3YXJkIChiLHYpIHtcbiAgYlswXT0yNTA7XG4gIGJbMV09djtcbiAgcmV0dXJuIDBcbn1cblxuLy9Qcm92aWRlczogY2FtbF9vYmpfY29tcGFyZV9hbmRfc3dhcFxuZnVuY3Rpb24gY2FtbF9vYmpfY29tcGFyZV9hbmRfc3dhcCh4LGksb2xkLG4pe1xuICBpZih4W2krMV0gPT0gb2xkKSB7XG4gICAgeFtpKzFdID0gbjtcbiAgICByZXR1cm4gMTtcbiAgfVxuICByZXR1cm4gMFxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX29ial9pc19zaGFyZWRcbmZ1bmN0aW9uIGNhbWxfb2JqX2lzX3NoYXJlZCh4KXtcbiAgcmV0dXJuIDFcbn1cblxuLy9Qcm92aWRlczogY2FtbF9sYXp5X21ha2VfZm9yd2FyZCBjb25zdCAobXV0YWJsZSlcbmZ1bmN0aW9uIGNhbWxfbGF6eV9tYWtlX2ZvcndhcmQgKHYpIHsgcmV0dXJuIFsyNTAsIHZdOyB9XG5cbi8vLy8vLy8vLy8vLy8gQ2FtbGludGVybmFsT09cbi8vUHJvdmlkZXM6IGNhbWxfZ2V0X3B1YmxpY19tZXRob2QgY29uc3RcbnZhciBjYW1sX21ldGhvZF9jYWNoZSA9IFtdO1xuZnVuY3Rpb24gY2FtbF9nZXRfcHVibGljX21ldGhvZCAob2JqLCB0YWcsIGNhY2hlaWQpIHtcbiAgdmFyIG1ldGhzID0gb2JqWzFdO1xuICB2YXIgb2ZzID0gY2FtbF9tZXRob2RfY2FjaGVbY2FjaGVpZF07XG4gIGlmIChvZnMgPT09IHVuZGVmaW5lZCkge1xuICAgIC8vIE1ha2Ugc3VyZSB0aGUgYXJyYXkgaXMgbm90IHNwYXJzZVxuICAgIGZvciAodmFyIGkgPSBjYW1sX21ldGhvZF9jYWNoZS5sZW5ndGg7IGkgPCBjYWNoZWlkOyBpKyspXG4gICAgICBjYW1sX21ldGhvZF9jYWNoZVtpXSA9IDA7XG4gIH0gZWxzZSBpZiAobWV0aHNbb2ZzXSA9PT0gdGFnKSB7XG4gICAgcmV0dXJuIG1ldGhzW29mcyAtIDFdO1xuICB9XG4gIHZhciBsaSA9IDMsIGhpID0gbWV0aHNbMV0gKiAyICsgMSwgbWk7XG4gIHdoaWxlIChsaSA8IGhpKSB7XG4gICAgbWkgPSAoKGxpK2hpKSA+PiAxKSB8IDE7XG4gICAgaWYgKHRhZyA8IG1ldGhzW21pKzFdKSBoaSA9IG1pLTI7XG4gICAgZWxzZSBsaSA9IG1pO1xuICB9XG4gIGNhbWxfbWV0aG9kX2NhY2hlW2NhY2hlaWRdID0gbGkgKyAxO1xuICAvKiByZXR1cm4gMCBpZiB0YWcgaXMgbm90IHRoZXJlICovXG4gIHJldHVybiAodGFnID09IG1ldGhzW2xpKzFdID8gbWV0aHNbbGldIDogMCk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfb29fbGFzdF9pZFxudmFyIGNhbWxfb29fbGFzdF9pZCA9IDA7XG5cbi8vUHJvdmlkZXM6IGNhbWxfc2V0X29vX2lkXG4vL1JlcXVpcmVzOiBjYW1sX29vX2xhc3RfaWRcbmZ1bmN0aW9uIGNhbWxfc2V0X29vX2lkIChiKSB7XG4gIGJbMl09Y2FtbF9vb19sYXN0X2lkKys7XG4gIHJldHVybiBiO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2ZyZXNoX29vX2lkIGNvbnN0XG4vL1JlcXVpcmVzOiBjYW1sX29vX2xhc3RfaWRcbmZ1bmN0aW9uIGNhbWxfZnJlc2hfb29faWQoKSB7XG4gIHJldHVybiBjYW1sX29vX2xhc3RfaWQrKztcbn1cblxuLy9Qcm92aWRlczogY2FtbF9vYmpfcmF3X2ZpZWxkXG5mdW5jdGlvbiBjYW1sX29ial9yYXdfZmllbGQobyxpKSB7IHJldHVybiBvW2krMV0gfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX29ial9zZXRfcmF3X2ZpZWxkXG5mdW5jdGlvbiBjYW1sX29ial9zZXRfcmF3X2ZpZWxkKG8saSx2KSB7IHJldHVybiBvW2krMV0gPSB2IH1cblxuLy9Qcm92aWRlczogY2FtbF9vYmpfcmVhY2hhYmxlX3dvcmRzXG5mdW5jdGlvbiBjYW1sX29ial9yZWFjaGFibGVfd29yZHMobykgeyByZXR1cm4gMDsgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX29ial9hZGRfb2Zmc2V0XG4vL1JlcXVpcmVzOiBjYW1sX2ZhaWx3aXRoXG5mdW5jdGlvbiBjYW1sX29ial9hZGRfb2Zmc2V0KHYsb2Zmc2V0KSB7XG4gIGNhbWxfZmFpbHdpdGgoXCJPYmouYWRkX29mZnNldCBpcyBub3Qgc3VwcG9ydGVkXCIpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX29ial91cGRhdGVfdGFnXG5mdW5jdGlvbiBjYW1sX29ial91cGRhdGVfdGFnKGIsbyxuKSB7XG4gICAgaWYoYlswXT09bykgeyBiWzBdID0gbjsgcmV0dXJuIDEgfVxuICAgIHJldHVybiAwXG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfbGF6eV91cGRhdGVfdG9fZm9yY2luZ1xuLy9SZXF1aXJlczogY2FtbF9vYmpfdXBkYXRlX3RhZ1xuZnVuY3Rpb24gY2FtbF9sYXp5X3VwZGF0ZV90b19mb3JjaW5nKG8pIHtcbiAgaWYgKChvIGluc3RhbmNlb2YgQXJyYXkpICYmIG9bMF0gPT0gKG9bMF0gPj4+IDApICYmXG4gICAgICBjYW1sX29ial91cGRhdGVfdGFnKG8sIDI0NiwgMjQ0KSkge1xuICAgIHJldHVybiAwO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAxO1xuICB9XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfbGF6eV91cGRhdGVfdG9fZm9yd2FyZFxuLy9SZXF1aXJlczogY2FtbF9vYmpfdXBkYXRlX3RhZ1xuICBmdW5jdGlvbiBjYW1sX2xhenlfdXBkYXRlX3RvX2ZvcndhcmQobykge1xuICBjYW1sX29ial91cGRhdGVfdGFnKG8sMjQ0LDI1MCk7XG4gIHJldHVybiAwOyAvLyB1bml0XG59XG5cblxuLy9Qcm92aWRlczogY2FtbF9sYXp5X3Jlc2V0X3RvX2xhenlcbi8vUmVxdWlyZXM6IGNhbWxfb2JqX3VwZGF0ZV90YWdcbmZ1bmN0aW9uIGNhbWxfbGF6eV9yZXNldF90b19sYXp5KG8pIHtcbiAgY2FtbF9vYmpfdXBkYXRlX3RhZyhvLDI0NCwyNDYpO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9sYXp5X3JlYWRfcmVzdWx0XG4vL1JlcXVpcmVzOiBjYW1sX29ial90YWdcbmZ1bmN0aW9uIGNhbWxfbGF6eV9yZWFkX3Jlc3VsdChvKSB7XG4gIHJldHVybiAoY2FtbF9vYmpfdGFnKG8pID09IDI1MCk/b1sxXTpvO1xufVxuXG5cbi8vUHJvdmlkZXM6IGNhbWxfaXNfY29udGludWF0aW9uX3RhZ1xuLy9WZXJzaW9uOiA8IDVcbmZ1bmN0aW9uIGNhbWxfaXNfY29udGludWF0aW9uX3RhZyh0KSB7XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2lzX2NvbnRpbnVhdGlvbl90YWdcbi8vVmVyc2lvbjogPj0gNVxuZnVuY3Rpb24gY2FtbF9pc19jb250aW51YXRpb25fdGFnKHQpIHtcbiAgcmV0dXJuICh0ID09IDI0NSkgPyAxIDogMDtcbn1cbiIsIi8qXG5UbyBkZWFsIHdpdGggZWZmZWN0cywgdGhlIGV4ZWN1dGlvbiBjb250ZXh0IGlzIGludHVpdGl2ZWx5IGNvbXBvc2VkIG9mXG5hIHN0YWNrIG9mIGZpYmVycy4gRWFjaCBmaWJlciBoYXMgYSBjdXJyZW50IGxvdy1sZXZlbCBjb250aW51YXRpb25cbihvbmUtYXJndW1lbnQgSmF2YVNjcmlwdCBmdW5jdGlvbiksIGEgc3RhY2sgb2YgZXhjZXB0aW9uIGhhbmRsZXJzIGFuZFxuYSB0cmlwbGUgb2YgaGFuZGxlcnMsIHdoaWNoIGFyZSBpbnZva2VkIHdoZW4gdGhlIGZpYmVyIHRlcm1pbmF0ZXNcbihlaXRoZXIgd2l0aCBhIHZhbHVlIG9yIGFuIGV4Y2VwdGlvbikgb3Igd2hlbiBhbiBlZmZlY3QgaXMgcGVyZm9ybWVkLlxuVGhlIGxvdy1sZXZlbCBjb250aW51YXRpb24gb2YgdGhlIHRvcG1vc3QgZmliZXIgKHdoaWNoIGlzIGN1cnJlbnRseVxuZXhlY3V0aW5nKSBpcyBwYXNzZWQgZnJvbSBmdW5jdGlvbiB0byBmdW5jdGlvbiBhcyBhbiBhZGRpdGlvbmFsXG5hcmd1bWVudC4gSXRzIHN0YWNrIG9mIGV4Y2VwdGlvbiBoYW5kbGVycyBpcyBzdG9yZWQgaW5cbltjYW1sX2V4bl9zdGFja10uIEV4Y2VwdGlvbiBoYW5kbGVycyBhcmUgcHVzaGVkIGludG8gdGhpcyBzdGFjayB3aGVuXG5lbnRlcmluZyBhIFt0cnkgLi4uIHdpdGggLi4uXSBhbmQgcG9wcGVkIG9uIGV4aXQuIFRoZW4sIGhhbmRsZXJzIGFuZFxudGhlIHJlbWFpbmluZyBmaWJlcnMgYXJlIHN0b3JlZCBpbiBbY2FtbF9maWJlcl9zdGFja10uIFRvIGluc3RhbGwgYW5cbmVmZmVjdCBoYW5kbGVyLCB3ZSBwdXNoIGEgbmV3IGZpYmVyIGludG8gdGhlIGV4ZWN1dGlvbiBjb250ZXh0LlxuXG5XZSBoYXZlIGJhc2ljYWxseSB0aGUgZm9sbG93aW5nIHR5cGUgZm9yIHJlaWZpZWQgY29udGludWF0aW9ucyAodHlwZVxuW2NvbnRpbnVhdGlvbl0gaW4gbW9kdWxlIFtFZmZlY3RdIG9mIHRoZSBzdGFuZGFyZCBsaWJyYXJ5KTpcblxuICB0eXBlICgnYSwgJ2IpIGNvbnRpbnVhdGlvbiA9ICgnYSwgJ2IpIHN0YWNrIHJlZlxuXG4gIGFuZCAoXywgXykgc3RhY2sgPVxuICAgICAgQ29ucyA6ICgnYiAtPiB1bml0KSAqICAgICAgICAgICAgICgqIGxvdy1sZXZlbCBjb250aW51YXRpb24gKilcbiAgICAgICAgICAgICAoZXhuIC0+IHVuaXQpIGxpc3QgKiAgICAgICAoKiBleGNlcHRpb24gaGFuZGxlcnMgKilcbiAgICAgICAgICAgICAoJ2IsICdjKSBoYW5kbGVyICpcbiAgICAgICAgICAgICAoJ2EsICdiKSBzdGFja1xuICAgICAgICAgICAgIC0+ICgnYSwgJ2MpIHN0YWNrXG4gICAgfCBFbXB0eSA6ICgnYSwgJ2EpIHN0YWNrXG5cbiAgYW5kICgnYSwnYikgaGFuZGxlciA9ICAgKCogQXMgaW4gbW9kdWxlIEVmZmVjdCBmcm9tIHRoZSBzdGFuZGFyZCBsaWJyYXJ5ICopXG4gICAgeyByZXRjOiAnYSAtPiAnYjtcbiAgICAgIGV4bmM6IGV4biAtPiAnYjtcbiAgICAgIGVmZmM6ICdjLidjIEVmZmVjdC50IC0+ICgoJ2MsJ2IpIGNvbnRpbnVhdGlvbiAtPiAnYikgb3B0aW9uIH1cblxuQ29udGludWF0aW9ucyBhcmUgb25lLXNob3QuIEEgY29udGludWF0aW9uIFtyZWYgRW1wdHldIGhhcyBhbHJlYWR5XG5iZWVuIHJlc3VtZWQuXG5cbkEgY29udGludWF0aW9uIGlzIGJhc2ljYWxseSBjb21wb3NlZCBvZiBhIGxpc3Qgb2YgZmliZXJzLCB3aGljaCBlYWNoXG5oYXMgaXRzIGxvdy1sZXZlbCBjb250aW51YXRpb24sIGl0cyBzdGFjayBvZiBleGNlcHRpb24gaGFuZGxlcnMgYW5kIGFcbnRyaXBsZSBvZiBoYW5kbGVycyB0byBkZWFsIHdpdGggd2hlbiB0aGUgZmliZXIgdGVybWluYXRlcyBvciBhblxuZWZmZWN0IGlzIHBlcmZvcm1lZC4gV2hlbiByZXN1bWluZyBhIGNvbnRpbnVhdGlvbiwgdGhlIGlubmVybW9zdCBmaWJlclxuaXMgcmVzdW1lZCBmaXJzdC5cblxuVGhlIGhhbmRsZXJzIGFyZSBDUFMtdHJhbnNmb3JtZWQgZnVuY3Rpb25zOiB0aGV5IGFjdHVhbGx5IHRha2UgYW5cbmFkZGl0aW9uYWwgcGFyYW1ldGVyIHdoaWNoIGlzIHRoZSBjdXJyZW50IGxvdy1sZXZlbCBjb250aW51YXRpb24uXG4qL1xuXG4vL1Byb3ZpZGVzOiBjYW1sX2V4bl9zdGFja1xuLy9JZjogZWZmZWN0c1xuLy8gVGhpcyBpcyBhbiBPQ2FtbCBsaXN0IG9mIGV4Y2VwdGlvbiBoYW5kbGVyc1xudmFyIGNhbWxfZXhuX3N0YWNrID0gMDtcblxuLy9Qcm92aWRlczogY2FtbF9wdXNoX3RyYXBcbi8vUmVxdWlyZXM6IGNhbWxfZXhuX3N0YWNrXG4vL0lmOiBlZmZlY3RzXG5mdW5jdGlvbiBjYW1sX3B1c2hfdHJhcChoYW5kbGVyKSB7XG4gIGNhbWxfZXhuX3N0YWNrPVswLGhhbmRsZXIsY2FtbF9leG5fc3RhY2tdO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3BvcF90cmFwXG4vL1JlcXVpcmVzOiBjYW1sX2V4bl9zdGFja1xuLy9JZjogZWZmZWN0c1xuZnVuY3Rpb24gY2FtbF9wb3BfdHJhcCgpIHtcbiAgaWYgKCFjYW1sX2V4bl9zdGFjaykgcmV0dXJuIGZ1bmN0aW9uKHgpe3Rocm93IHg7fVxuICB2YXIgaCA9IGNhbWxfZXhuX3N0YWNrWzFdO1xuICBjYW1sX2V4bl9zdGFjaz1jYW1sX2V4bl9zdGFja1syXTtcbiAgcmV0dXJuIGhcbn1cblxuLy9Qcm92aWRlczogY2FtbF9maWJlcl9zdGFja1xuLy9JZjogZWZmZWN0c1xuLy8gVGhpcyBoYXMgdGhlIHNoYXBlIHtoLCByOntrLCB4LCBlfX0gd2hlcmUgaCBpcyBhIHRyaXBsZSBvZiBoYW5kbGVyc1xuLy8gKHNlZSBlZmZlY3QuanMpIGFuZCBrLCB4IGFuZCBlIGFyZSB0aGUgc2F2ZWQgY29udGludWF0aW9uLFxuLy8gZXhjZXB0aW9uIHN0YWNrIGFuZCBmaWJlciBzdGFjayBvZiB0aGUgcGFyZW50IGZpYmVyLlxudmFyIGNhbWxfZmliZXJfc3RhY2s7XG5cbi8vUHJvdmlkZXM6Y2FtbF9yZXN1bWVfc3RhY2tcbi8vUmVxdWlyZXM6IGNhbWxfbmFtZWRfdmFsdWUsIGNhbWxfcmFpc2VfY29uc3RhbnQsIGNhbWxfZXhuX3N0YWNrLCBjYW1sX2ZpYmVyX3N0YWNrXG4vL0lmOiBlZmZlY3RzXG5mdW5jdGlvbiBjYW1sX3Jlc3VtZV9zdGFjayhzdGFjaywgaykge1xuICBpZiAoIXN0YWNrKSBjYW1sX3JhaXNlX2NvbnN0YW50XG4gICAgICAgICAgICAgICAgIChjYW1sX25hbWVkX3ZhbHVlKFwiRWZmZWN0LkNvbnRpbnVhdGlvbl9hbHJlYWR5X3Jlc3VtZWRcIikpO1xuICAvLyBVcGRhdGUgdGhlIGV4ZWN1dGlvbiBjb250ZXh0IHdpdGggdGhlIHN0YWNrIG9mIGZpYmVycyBpbiBbc3RhY2tdIGluXG4gIC8vIG9yZGVyIHRvIHJlc3VtZSB0aGUgY29udGludWF0aW9uXG4gIGRvIHtcbiAgICBjYW1sX2ZpYmVyX3N0YWNrID1cbiAgICAgIHtoOnN0YWNrWzNdLCByOntrOmssIHg6Y2FtbF9leG5fc3RhY2ssIGU6Y2FtbF9maWJlcl9zdGFja319O1xuICAgIGsgPSBzdGFja1sxXTtcbiAgICBjYW1sX2V4bl9zdGFjayA9IHN0YWNrWzJdO1xuICAgIHN0YWNrID0gc3RhY2tbNF07XG4gIH0gd2hpbGUgKHN0YWNrKVxuICByZXR1cm4gaztcbn1cblxuLy9Qcm92aWRlczogY2FtbF9wb3BfZmliZXJcbi8vUmVxdWlyZXM6IGNhbWxfZXhuX3N0YWNrLCBjYW1sX2ZpYmVyX3N0YWNrXG4vL0lmOiBlZmZlY3RzXG5mdW5jdGlvbiBjYW1sX3BvcF9maWJlcigpIHtcbiAgLy8gTW92ZSB0byB0aGUgcGFyZW50IGZpYmVyLCByZXR1cm5pbmcgdGhlIHBhcmVudCdzIGxvdy1sZXZlbCBjb250aW51YXRpb25cbiAgdmFyIHJlbSA9IGNhbWxfZmliZXJfc3RhY2sucjtcbiAgY2FtbF9leG5fc3RhY2sgPSByZW0ueDtcbiAgY2FtbF9maWJlcl9zdGFjayA9IHJlbS5lO1xuICByZXR1cm4gcmVtLms7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfcGVyZm9ybV9lZmZlY3Rcbi8vUmVxdWlyZXM6IGNhbWxfcG9wX2ZpYmVyLCBjYW1sX3N0YWNrX2NoZWNrX2RlcHRoLCBjYW1sX3RyYW1wb2xpbmVfcmV0dXJuLCBjYW1sX2V4bl9zdGFjaywgY2FtbF9maWJlcl9zdGFja1xuLy9JZjogZWZmZWN0c1xuZnVuY3Rpb24gY2FtbF9wZXJmb3JtX2VmZmVjdChlZmYsIGNvbnQsIGswKSB7XG4gIC8vIEFsbG9jYXRlIGEgY29udGludWF0aW9uIGlmIHdlIGRvbid0IGFscmVhZHkgaGF2ZSBvbmVcbiAgaWYgKCFjb250KSBjb250ID0gWzI0NSAvKmNvbnRpbnVhdGlvbiovLCAwXTtcbiAgLy8gR2V0IGN1cnJlbnQgZWZmZWN0IGhhbmRsZXJcbiAgdmFyIGhhbmRsZXIgPSBjYW1sX2ZpYmVyX3N0YWNrLmhbM107XG4gIC8vIENvbnMgdGhlIGN1cnJlbnQgZmliZXIgb250byB0aGUgY29udGludWF0aW9uOlxuICAvLyAgIGNvbnQgOj0gQ29ucyAoaywgZXhuX3N0YWNrLCBoYW5kbGVycywgIWNvbnQpXG4gIGNvbnRbMV0gPSBbMCxrMCxjYW1sX2V4bl9zdGFjayxjYW1sX2ZpYmVyX3N0YWNrLmgsY29udFsxXV07XG4gIC8vIE1vdmUgdG8gcGFyZW50IGZpYmVyIGFuZCBleGVjdXRlIHRoZSBlZmZlY3QgaGFuZGxlciB0aGVyZVxuICAvLyBUaGUgaGFuZGxlciBpcyBkZWZpbmVkIGluIFN0ZGxpYi5FZmZlY3QsIHNvIHdlIGtub3cgdGhhdCB0aGUgYXJpdHkgbWF0Y2hlc1xuICB2YXIgazEgPSBjYW1sX3BvcF9maWJlcigpO1xuICByZXR1cm4gY2FtbF9zdGFja19jaGVja19kZXB0aCgpP2hhbmRsZXIoZWZmLGNvbnQsazEsazEpXG4gICAgICAgICA6Y2FtbF90cmFtcG9saW5lX3JldHVybihoYW5kbGVyLFtlZmYsY29udCxrMSxrMV0pO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2FsbG9jX3N0YWNrXG4vL1JlcXVpcmVzOiBjYW1sX3BvcF9maWJlciwgY2FtbF9maWJlcl9zdGFjaywgY2FtbF9jYWxsX2dlbiwgY2FtbF9zdGFja19jaGVja19kZXB0aCwgY2FtbF90cmFtcG9saW5lX3JldHVyblxuLy9JZjogZWZmZWN0c1xuZnVuY3Rpb24gY2FtbF9hbGxvY19zdGFjayhodiwgaHgsIGhmKSB7XG4gIGZ1bmN0aW9uIGNhbGwoaSwgeCkge1xuICAgIHZhciBmPWNhbWxfZmliZXJfc3RhY2suaFtpXTtcbiAgICB2YXIgYXJncyA9IFt4LCBjYW1sX3BvcF9maWJlcigpXTtcbiAgICByZXR1cm4gY2FtbF9zdGFja19jaGVja19kZXB0aCgpP2NhbWxfY2FsbF9nZW4oZixhcmdzKVxuICAgICAgICAgICA6Y2FtbF90cmFtcG9saW5lX3JldHVybihmLGFyZ3MpO1xuICB9XG4gIGZ1bmN0aW9uIGh2YWwoeCkge1xuICAgIC8vIENhbGwgW2h2XSBpbiB0aGUgcGFyZW50IGZpYmVyXG4gICAgcmV0dXJuIGNhbGwoMSwgeCk7XG4gIH1cbiAgZnVuY3Rpb24gaGV4bihlKSB7XG4gICAgLy8gQ2FsbCBbaHhdIGluIHRoZSBwYXJlbnQgZmliZXJcbiAgICByZXR1cm4gY2FsbCgyLCBlKTtcbiAgfVxuICByZXR1cm4gWzAsIGh2YWwsIFswLCBoZXhuLCAwXSwgWzAsIGh2LCBoeCwgaGZdLCAwXTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9hbGxvY19zdGFja1xuLy9JZjogIWVmZmVjdHNcbmZ1bmN0aW9uIGNhbWxfYWxsb2Nfc3RhY2soaHYsIGh4LCBoZikge1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9jb250aW51YXRpb25fdXNlX25vZXhjXG5mdW5jdGlvbiBjYW1sX2NvbnRpbnVhdGlvbl91c2Vfbm9leGMoY29udCkge1xuICB2YXIgc3RhY2s9Y29udFsxXTtcbiAgY29udFsxXT0wO1xuICByZXR1cm4gc3RhY2s7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfY29udGludWF0aW9uX3VzZV9hbmRfdXBkYXRlX2hhbmRsZXJfbm9leGNcbi8vUmVxdWlyZXM6IGNhbWxfY29udGludWF0aW9uX3VzZV9ub2V4Y1xuZnVuY3Rpb24gY2FtbF9jb250aW51YXRpb25fdXNlX2FuZF91cGRhdGVfaGFuZGxlcl9ub2V4Yyhjb250LCBodmFsLCBoZXhuLCBoZWZmKSB7XG4gIHZhciBzdGFjayA9IGNhbWxfY29udGludWF0aW9uX3VzZV9ub2V4Yyhjb250KTtcbiAgc3RhY2tbM10gPSBbMCwgaHZhbCwgaGV4biwgaGVmZl07XG4gIHJldHVybiBzdGFjaztcbn1cblxuLy9Qcm92aWRlczogY2FtbF9nZXRfY29udGludWF0aW9uX2NhbGxzdGFja1xuZnVuY3Rpb24gY2FtbF9nZXRfY29udGludWF0aW9uX2NhbGxzdGFjayAoKSB7IHJldHVybiBbMF07IH1cblxuLy9Qcm92aWRlczogY2FtbF9tbF9jb25kaXRpb25fbmV3XG5mdW5jdGlvbiBjYW1sX21sX2NvbmRpdGlvbl9uZXcodW5pdCl7XG4gICAgcmV0dXJuIHtjb25kaXRpb246MX07XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfY29uZGl0aW9uX3dhaXRcbmZ1bmN0aW9uIGNhbWxfbWxfY29uZGl0aW9uX3dhaXQodCxtdXRleHQpe1xuICAgIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21sX2NvbmRpdGlvbl9icm9hZGNhc3RcbmZ1bmN0aW9uIGNhbWxfbWxfY29uZGl0aW9uX2Jyb2FkY2FzdCh0KXtcbiAgICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9tbF9jb25kaXRpb25fc2lnbmFsXG5mdW5jdGlvbiBjYW1sX21sX2NvbmRpdGlvbl9zaWduYWwodCl7XG4gICAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGpzb29fZWZmZWN0X25vdF9zdXBwb3J0ZWRcbi8vUmVxdWlyZXM6IGNhbWxfZmFpbHdpdGhcbi8vIUlmOiBlZmZlY3RzXG5mdW5jdGlvbiBqc29vX2VmZmVjdF9ub3Rfc3VwcG9ydGVkKCl7XG4gIGNhbWxfZmFpbHdpdGgoXCJFZmZlY3QgaGFuZGxlcnMgYXJlIG5vdCBzdXBwb3J0ZWRcIik7XG59XG4iLCIvLyBKc19vZl9vY2FtbCBydW50aW1lIHN1cHBvcnRcbi8vIGh0dHA6Ly93d3cub2NzaWdlbi5vcmcvanNfb2Zfb2NhbWwvXG4vL1xuLy8gVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbi8vIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuLy8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgd2l0aCBsaW5raW5nIGV4Y2VwdGlvbjtcbi8vIGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vXG4vLyBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4vLyBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2Vcbi8vIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLlxuXG4vLy8vLy8vLy8vLy8vIEFycmF5XG5cbi8vUHJvdmlkZXM6IGNhbWxfYXJyYXlfc3ViIG11dGFibGVcbmZ1bmN0aW9uIGNhbWxfYXJyYXlfc3ViIChhLCBpLCBsZW4pIHtcbiAgdmFyIGEyID0gbmV3IEFycmF5KGxlbisxKTtcbiAgYTJbMF09MDtcbiAgZm9yKHZhciBpMiA9IDEsIGkxPSBpKzE7IGkyIDw9IGxlbjsgaTIrKyxpMSsrICl7XG4gICAgYTJbaTJdPWFbaTFdO1xuICB9XG4gIHJldHVybiBhMjtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9hcnJheV9hcHBlbmQgbXV0YWJsZVxuZnVuY3Rpb24gY2FtbF9hcnJheV9hcHBlbmQoYTEsIGEyKSB7XG4gIHZhciBsMSA9IGExLmxlbmd0aCwgbDIgPSBhMi5sZW5ndGg7XG4gIHZhciBsID0gbDErbDItMVxuICB2YXIgYSA9IG5ldyBBcnJheShsKTtcbiAgYVswXSA9IDA7XG4gIHZhciBpID0gMSxqID0gMTtcbiAgZm9yKDtpPGwxO2krKykgYVtpXT1hMVtpXTtcbiAgZm9yKDtpPGw7aSsrLGorKykgYVtpXT1hMltqXTtcbiAgcmV0dXJuIGE7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfYXJyYXlfY29uY2F0IG11dGFibGVcbmZ1bmN0aW9uIGNhbWxfYXJyYXlfY29uY2F0KGwpIHtcbiAgdmFyIGEgPSBbMF07XG4gIHdoaWxlIChsICE9PSAwKSB7XG4gICAgdmFyIGIgPSBsWzFdO1xuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYi5sZW5ndGg7IGkrKykgYS5wdXNoKGJbaV0pO1xuICAgIGwgPSBsWzJdO1xuICB9XG4gIHJldHVybiBhO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2FycmF5X2JsaXRcbmZ1bmN0aW9uIGNhbWxfYXJyYXlfYmxpdChhMSwgaTEsIGEyLCBpMiwgbGVuKSB7XG4gIGlmIChpMiA8PSBpMSkge1xuICAgIGZvciAodmFyIGogPSAxOyBqIDw9IGxlbjsgaisrKSBhMltpMiArIGpdID0gYTFbaTEgKyBqXTtcbiAgfSBlbHNlIHtcbiAgICBmb3IgKHZhciBqID0gbGVuOyBqID49IDE7IGotLSkgYTJbaTIgKyBqXSA9IGExW2kxICsgal07XG4gIH07XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2Zsb2F0YXJyYXlfYmxpdFxuZnVuY3Rpb24gY2FtbF9mbG9hdGFycmF5X2JsaXQoYTEsIGkxLCBhMiwgaTIsIGxlbikge1xuICBpZiAoaTIgPD0gaTEpIHtcbiAgICBmb3IgKHZhciBqID0gMTsgaiA8PSBsZW47IGorKykgYTJbaTIgKyBqXSA9IGExW2kxICsgal07XG4gIH0gZWxzZSB7XG4gICAgZm9yICh2YXIgaiA9IGxlbjsgaiA+PSAxOyBqLS0pIGEyW2kyICsgal0gPSBhMVtpMSArIGpdO1xuICB9O1xuICByZXR1cm4gMDtcbn1cblxuLy8vLy8vLy8vLy8vLyBQZXJ2YXNpdmVcbi8vUHJvdmlkZXM6IGNhbWxfYXJyYXlfc2V0IChtdXRhYmxlLCBjb25zdCwgbXV0YWJsZSlcbi8vUmVxdWlyZXM6IGNhbWxfYXJyYXlfYm91bmRfZXJyb3JcbmZ1bmN0aW9uIGNhbWxfYXJyYXlfc2V0IChhcnJheSwgaW5kZXgsIG5ld3ZhbCkge1xuICBpZiAoKGluZGV4IDwgMCkgfHwgKGluZGV4ID49IGFycmF5Lmxlbmd0aCAtIDEpKSBjYW1sX2FycmF5X2JvdW5kX2Vycm9yKCk7XG4gIGFycmF5W2luZGV4KzFdPW5ld3ZhbDsgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfYXJyYXlfZ2V0IG11dGFibGUgKG11dGFibGUsIGNvbnN0KVxuLy9SZXF1aXJlczogY2FtbF9hcnJheV9ib3VuZF9lcnJvclxuZnVuY3Rpb24gY2FtbF9hcnJheV9nZXQgKGFycmF5LCBpbmRleCkge1xuICBpZiAoKGluZGV4IDwgMCkgfHwgKGluZGV4ID49IGFycmF5Lmxlbmd0aCAtIDEpKSBjYW1sX2FycmF5X2JvdW5kX2Vycm9yKCk7XG4gIHJldHVybiBhcnJheVtpbmRleCsxXTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9hcnJheV9maWxsXG5mdW5jdGlvbiBjYW1sX2FycmF5X2ZpbGwoYXJyYXksIG9mcywgbGVuLCB2KXtcbiAgZm9yKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKXtcbiAgICBhcnJheVtvZnMraSsxXSA9IHY7XG4gIH1cbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfY2hlY2tfYm91bmQgKG11dGFibGUsIGNvbnN0KVxuLy9SZXF1aXJlczogY2FtbF9hcnJheV9ib3VuZF9lcnJvclxuZnVuY3Rpb24gY2FtbF9jaGVja19ib3VuZCAoYXJyYXksIGluZGV4KSB7XG4gIGlmIChpbmRleCA+Pj4gMCA+PSBhcnJheS5sZW5ndGggLSAxKSBjYW1sX2FycmF5X2JvdW5kX2Vycm9yKCk7XG4gIHJldHVybiBhcnJheTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9tYWtlX3ZlY3QgY29uc3QgKGNvbnN0LCBtdXRhYmxlKVxuLy9SZXF1aXJlczogY2FtbF9hcnJheV9ib3VuZF9lcnJvclxuZnVuY3Rpb24gY2FtbF9tYWtlX3ZlY3QgKGxlbiwgaW5pdCkge1xuICBpZiAobGVuIDwgMCkgY2FtbF9hcnJheV9ib3VuZF9lcnJvcigpO1xuICB2YXIgbGVuID0gbGVuICsgMSB8IDA7XG4gIHZhciBiID0gbmV3IEFycmF5KGxlbik7XG4gIGJbMF09MDtcbiAgZm9yICh2YXIgaSA9IDE7IGkgPCBsZW47IGkrKykgYltpXSA9IGluaXQ7XG4gIHJldHVybiBiO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21ha2VfZmxvYXRfdmVjdCBjb25zdCAoY29uc3QpXG4vL1JlcXVpcmVzOiBjYW1sX2FycmF5X2JvdW5kX2Vycm9yXG5mdW5jdGlvbiBjYW1sX21ha2VfZmxvYXRfdmVjdChsZW4pe1xuICBpZiAobGVuIDwgMCkgY2FtbF9hcnJheV9ib3VuZF9lcnJvcigpO1xuICB2YXIgbGVuID0gbGVuICsgMSB8IDA7XG4gIHZhciBiID0gbmV3IEFycmF5KGxlbik7XG4gIGJbMF09MjU0O1xuICBmb3IgKHZhciBpID0gMTsgaSA8IGxlbjsgaSsrKSBiW2ldID0gMDtcbiAgcmV0dXJuIGJcbn1cbi8vUHJvdmlkZXM6IGNhbWxfZmxvYXRhcnJheV9jcmVhdGUgY29uc3QgKGNvbnN0KVxuLy9SZXF1aXJlczogY2FtbF9hcnJheV9ib3VuZF9lcnJvclxuZnVuY3Rpb24gY2FtbF9mbG9hdGFycmF5X2NyZWF0ZShsZW4pe1xuICBpZiAobGVuIDwgMCkgY2FtbF9hcnJheV9ib3VuZF9lcnJvcigpO1xuICB2YXIgbGVuID0gbGVuICsgMSB8IDA7XG4gIHZhciBiID0gbmV3IEFycmF5KGxlbik7XG4gIGJbMF09MjU0O1xuICBmb3IgKHZhciBpID0gMTsgaSA8IGxlbjsgaSsrKSBiW2ldID0gMDtcbiAgcmV0dXJuIGJcbn1cbiIsIi8vUHJvdmlkZXM6IGNhbWxfZG9tYWluX2Rsc1xudmFyIGNhbWxfZG9tYWluX2RscyA9IFswXTtcblxuLy9Qcm92aWRlczogY2FtbF9kb21haW5fZGxzX3NldFxuLy9SZXF1aXJlczogY2FtbF9kb21haW5fZGxzXG5mdW5jdGlvbiBjYW1sX2RvbWFpbl9kbHNfc2V0KGEpIHtcbiAgY2FtbF9kb21haW5fZGxzID0gYTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9kb21haW5fZGxzX2NvbXBhcmVfYW5kX3NldFxuLy9SZXF1aXJlczogY2FtbF9kb21haW5fZGxzXG4vL1ZlcnNpb246ID49IDUuMlxuZnVuY3Rpb24gY2FtbF9kb21haW5fZGxzX2NvbXBhcmVfYW5kX3NldChvbGQsbikge1xuICBpZihjYW1sX2RvbWFpbl9kbHMgIT09IG9sZCkgcmV0dXJuIDBcbiAgY2FtbF9kb21haW5fZGxzID0gbjtcbiAgcmV0dXJuIDE7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfZG9tYWluX2Rsc19nZXRcbi8vUmVxdWlyZXM6IGNhbWxfZG9tYWluX2Rsc1xuZnVuY3Rpb24gY2FtbF9kb21haW5fZGxzX2dldCh1bml0KSB7XG4gIHJldHVybiBjYW1sX2RvbWFpbl9kbHM7XG59XG5cblxuLy9Qcm92aWRlczogY2FtbF9hdG9taWNfbG9hZFxuZnVuY3Rpb24gY2FtbF9hdG9taWNfbG9hZChyZWYpe1xuICByZXR1cm4gcmVmWzFdO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2F0b21pY19jYXNcbmZ1bmN0aW9uIGNhbWxfYXRvbWljX2NhcyhyZWYsbyxuKSB7XG4gIGlmKHJlZlsxXSA9PT0gbyl7XG4gICAgcmVmWzFdID0gbjtcbiAgICByZXR1cm4gMTtcbiAgfVxuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9hdG9taWNfZmV0Y2hfYWRkXG5mdW5jdGlvbiBjYW1sX2F0b21pY19mZXRjaF9hZGQocmVmLCBpKSB7XG4gIHZhciBvbGQgPSByZWZbMV07XG4gIHJlZlsxXSArPSBpO1xuICByZXR1cm4gb2xkO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2F0b21pY19leGNoYW5nZVxuZnVuY3Rpb24gY2FtbF9hdG9taWNfZXhjaGFuZ2UocmVmLCB2KSB7XG4gIHZhciByID0gcmVmWzFdO1xuICByZWZbMV0gPSB2O1xuICByZXR1cm4gcjtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9hdG9taWNfbWFrZV9jb250ZW5kZWRcbmZ1bmN0aW9uIGNhbWxfYXRvbWljX21ha2VfY29udGVuZGVkKGEpIHtcbiAgcmV0dXJuIFswLCBhXVxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21sX2RvbWFpbl91bmlxdWVfdG9rZW5cbi8vVmVyc2lvbjogPCA1LjJcbnZhciBjYW1sX21sX2RvbWFpbl91bmlxdWVfdG9rZW5fID0gWzBdXG5mdW5jdGlvbiBjYW1sX21sX2RvbWFpbl91bmlxdWVfdG9rZW4odW5pdCkge1xuICByZXR1cm4gY2FtbF9tbF9kb21haW5fdW5pcXVlX3Rva2VuX1xufVxuXG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfZG9tYWluX3NldF9uYW1lXG5mdW5jdGlvbiBjYW1sX21sX2RvbWFpbl9zZXRfbmFtZShfbmFtZSkge1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9yZWNvbW1lbmRlZF9kb21haW5fY291bnRcbmZ1bmN0aW9uIGNhbWxfcmVjb21tZW5kZWRfZG9tYWluX2NvdW50KHVuaXQpIHsgcmV0dXJuIDEgfVxuXG5cbi8vUHJvdmlkZXM6IGNhbWxfZG9tYWluX2lkXG52YXIgY2FtbF9kb21haW5faWQgPSAwO1xuXG4vL1Byb3ZpZGVzOiBjYW1sX2RvbWFpbl9zcGF3blxuLy9SZXF1aXJlczogY2FtbF9tbF9tdXRleF91bmxvY2tcbi8vUmVxdWlyZXM6IGNhbWxfZG9tYWluX2lkXG4vL1JlcXVpcmVzOiBjYW1sX2NhbGxiYWNrXG4vL1ZlcnNpb246ID49IDUuMlxudmFyIGNhbWxfZG9tYWluX2xhdGVzdF9pZHggPSAxXG5mdW5jdGlvbiBjYW1sX2RvbWFpbl9zcGF3bihmLHRlcm1fc3luYyl7XG4gICAgdmFyIGlkID0gY2FtbF9kb21haW5fbGF0ZXN0X2lkeCsrO1xuICAgIHZhciBvbGQgPSBjYW1sX2RvbWFpbl9pZDtcbiAgICBjYW1sX2RvbWFpbl9pZCA9IGlkO1xuICAgIHZhciByZXMgPSBjYW1sX2NhbGxiYWNrKGYsWzBdKTtcbiAgICBjYW1sX2RvbWFpbl9pZCA9IG9sZDtcbiAgICBjYW1sX21sX211dGV4X3VubG9jayh0ZXJtX3N5bmNbMl0pO1xuICAgIC8vVE9ETzogZml4IGV4biBjYXNlXG4gICAgdGVybV9zeW5jWzFdID0gWzAsIFswLCByZXNdXTtcbiAgICByZXR1cm4gaWQ7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfZG9tYWluX3NwYXduXG4vL1JlcXVpcmVzOiBjYW1sX21sX211dGV4X3VubG9ja1xuLy9SZXF1aXJlczogY2FtbF9kb21haW5faWRcbi8vUmVxdWlyZXM6IGNhbWxfY2FsbGJhY2tcbi8vVmVyc2lvbjogPCA1LjJcbnZhciBjYW1sX2RvbWFpbl9sYXRlc3RfaWR4ID0gMVxuZnVuY3Rpb24gY2FtbF9kb21haW5fc3Bhd24oZixtdXRleCl7XG4gICAgdmFyIGlkID0gY2FtbF9kb21haW5fbGF0ZXN0X2lkeCsrO1xuICAgIHZhciBvbGQgPSBjYW1sX2RvbWFpbl9pZDtcbiAgICBjYW1sX2RvbWFpbl9pZCA9IGlkO1xuICAgIHZhciByZXMgPSBjYW1sX2NhbGxiYWNrKGYsWzBdKTtcbiAgICBjYW1sX2RvbWFpbl9pZCA9IG9sZDtcbiAgICBjYW1sX21sX211dGV4X3VubG9jayhtdXRleCk7XG4gICAgcmV0dXJuIGlkO1xufVxuXG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfZG9tYWluX2lkXG4vL1JlcXVpcmVzOiBjYW1sX2RvbWFpbl9pZFxuZnVuY3Rpb24gY2FtbF9tbF9kb21haW5faWQodW5pdCl7XG4gICAgcmV0dXJuIGNhbWxfZG9tYWluX2lkO1xufVxuXG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfZG9tYWluX2NwdV9yZWxheFxuZnVuY3Rpb24gY2FtbF9tbF9kb21haW5fY3B1X3JlbGF4KHVuaXQpe1xuICAgIHJldHVybiAwO1xufVxuIiwiLy8gSnNfb2Zfb2NhbWwgcnVudGltZSBzdXBwb3J0XG4vLyBodHRwOi8vd3d3Lm9jc2lnZW4ub3JnL2pzX29mX29jYW1sL1xuLy9cbi8vIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4vLyBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbi8vIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHdpdGggbGlua2luZyBleGNlcHRpb247XG4vLyBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vL1xuLy8gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuLy8gR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vL1xuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4vLyBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcsIFVTQS5cblxuLy9Qcm92aWRlczogY2FtbF9mb3JtYXRfaW50IGNvbnN0IChjb25zdCwgY29uc3QpXG4vL1JlcXVpcmVzOiBjYW1sX3BhcnNlX2Zvcm1hdCwgY2FtbF9maW5pc2hfZm9ybWF0dGluZywgY2FtbF9zdHJfcmVwZWF0XG4vL1JlcXVpcmVzOiBjYW1sX3N0cmluZ19vZl9qc2J5dGVzLCBjYW1sX2pzYnl0ZXNfb2Zfc3RyaW5nXG5mdW5jdGlvbiBjYW1sX2Zvcm1hdF9pbnQoZm10LCBpKSB7XG4gIGlmIChjYW1sX2pzYnl0ZXNfb2Zfc3RyaW5nKGZtdCkgPT0gXCIlZFwiKSByZXR1cm4gY2FtbF9zdHJpbmdfb2ZfanNieXRlcyhcIlwiK2kpO1xuICB2YXIgZiA9IGNhbWxfcGFyc2VfZm9ybWF0KGZtdCk7XG4gIGlmIChpIDwgMCkgeyBpZiAoZi5zaWduZWRjb252KSB7IGYuc2lnbiA9IC0xOyBpID0gLWk7IH0gZWxzZSBpID4+Pj0gMDsgfVxuICB2YXIgcyA9IGkudG9TdHJpbmcoZi5iYXNlKTtcbiAgaWYgKGYucHJlYyA+PSAwKSB7XG4gICAgZi5maWxsZXIgPSAnICc7XG4gICAgdmFyIG4gPSBmLnByZWMgLSBzLmxlbmd0aDtcbiAgICBpZiAobiA+IDApIHMgPSBjYW1sX3N0cl9yZXBlYXQgKG4sICcwJykgKyBzO1xuICB9XG4gIHJldHVybiBjYW1sX2ZpbmlzaF9mb3JtYXR0aW5nKGYsIHMpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3BhcnNlX3NpZ25fYW5kX2Jhc2Vcbi8vUmVxdWlyZXM6IGNhbWxfc3RyaW5nX3Vuc2FmZV9nZXQsIGNhbWxfbWxfc3RyaW5nX2xlbmd0aFxuZnVuY3Rpb24gY2FtbF9wYXJzZV9zaWduX2FuZF9iYXNlIChzKSB7XG4gIHZhciBpID0gMCwgbGVuID0gY2FtbF9tbF9zdHJpbmdfbGVuZ3RoKHMpLCBiYXNlID0gMTAsIHNpZ24gPSAxO1xuICBpZiAobGVuID4gMCkge1xuICAgIHN3aXRjaCAoY2FtbF9zdHJpbmdfdW5zYWZlX2dldChzLGkpKSB7XG4gICAgY2FzZSA0NTogaSsrOyBzaWduID0gLTE7IGJyZWFrO1xuICAgIGNhc2UgNDM6IGkrKzsgc2lnbiA9IDE7IGJyZWFrO1xuICAgIH1cbiAgfVxuICBpZiAoaSArIDEgPCBsZW4gJiYgY2FtbF9zdHJpbmdfdW5zYWZlX2dldChzLCBpKSA9PSA0OClcbiAgICBzd2l0Y2ggKGNhbWxfc3RyaW5nX3Vuc2FmZV9nZXQocywgaSArIDEpKSB7XG4gICAgY2FzZSAxMjA6IGNhc2UgODg6IGJhc2UgPSAxNjsgaSArPSAyOyBicmVhaztcbiAgICBjYXNlIDExMTogY2FzZSA3OTogYmFzZSA9ICA4OyBpICs9IDI7IGJyZWFrO1xuICAgIGNhc2UgIDk4OiBjYXNlIDY2OiBiYXNlID0gIDI7IGkgKz0gMjsgYnJlYWs7XG4gICAgY2FzZSAxMTc6IGNhc2UgODU6IGkgKz0gMjsgYnJlYWs7XG4gICAgfVxuICByZXR1cm4gW2ksIHNpZ24sIGJhc2VdO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3BhcnNlX2RpZ2l0XG5mdW5jdGlvbiBjYW1sX3BhcnNlX2RpZ2l0KGMpIHtcbiAgaWYgKGMgPj0gNDggJiYgYyA8PSA1NykgIHJldHVybiBjIC0gNDg7XG4gIGlmIChjID49IDY1ICYmIGMgPD0gOTApICByZXR1cm4gYyAtIDU1O1xuICBpZiAoYyA+PSA5NyAmJiBjIDw9IDEyMikgcmV0dXJuIGMgLSA4NztcbiAgcmV0dXJuIC0xO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2ludF9vZl9zdHJpbmcgKGNvbnN0KVxuLy9SZXF1aXJlczogY2FtbF9tbF9zdHJpbmdfbGVuZ3RoLCBjYW1sX3N0cmluZ191bnNhZmVfZ2V0XG4vL1JlcXVpcmVzOiBjYW1sX3BhcnNlX3NpZ25fYW5kX2Jhc2UsIGNhbWxfcGFyc2VfZGlnaXQsIGNhbWxfZmFpbHdpdGhcbmZ1bmN0aW9uIGNhbWxfaW50X29mX3N0cmluZyAocykge1xuICB2YXIgciA9IGNhbWxfcGFyc2Vfc2lnbl9hbmRfYmFzZSAocyk7XG4gIHZhciBpID0gclswXSwgc2lnbiA9IHJbMV0sIGJhc2UgPSByWzJdO1xuICB2YXIgbGVuID0gY2FtbF9tbF9zdHJpbmdfbGVuZ3RoKHMpO1xuICB2YXIgdGhyZXNob2xkID0gLTEgPj4+IDA7XG4gIHZhciBjID0gKGkgPCBsZW4pP2NhbWxfc3RyaW5nX3Vuc2FmZV9nZXQocywgaSk6MDtcbiAgdmFyIGQgPSBjYW1sX3BhcnNlX2RpZ2l0KGMpO1xuICBpZiAoZCA8IDAgfHwgZCA+PSBiYXNlKSBjYW1sX2ZhaWx3aXRoKFwiaW50X29mX3N0cmluZ1wiKTtcbiAgdmFyIHJlcyA9IGQ7XG4gIGZvciAoaSsrO2k8bGVuO2krKykge1xuICAgIGMgPSBjYW1sX3N0cmluZ191bnNhZmVfZ2V0KHMsIGkpO1xuICAgIGlmIChjID09IDk1KSBjb250aW51ZTtcbiAgICBkID0gY2FtbF9wYXJzZV9kaWdpdChjKTtcbiAgICBpZiAoZCA8IDAgfHwgZCA+PSBiYXNlKSBicmVhaztcbiAgICByZXMgPSBiYXNlICogcmVzICsgZDtcbiAgICBpZiAocmVzID4gdGhyZXNob2xkKSBjYW1sX2ZhaWx3aXRoKFwiaW50X29mX3N0cmluZ1wiKTtcbiAgfVxuICBpZiAoaSAhPSBsZW4pIGNhbWxfZmFpbHdpdGgoXCJpbnRfb2Zfc3RyaW5nXCIpO1xuICAvLyBGb3IgYmFzZSBkaWZmZXJlbnQgZnJvbSAxMCwgd2UgZXhwZWN0IGFuIHVuc2lnbmVkIHJlcHJlc2VudGF0aW9uLFxuICAvLyBoZW5jZSBhbnkgdmFsdWUgb2YgJ3JlcycgKGxlc3MgdGhhbiAndGhyZXNob2xkJykgaXMgYWNjZXB0YWJsZS5cbiAgLy8gQnV0IHdlIGhhdmUgdG8gY29udmVydCB0aGUgcmVzdWx0IGJhY2sgdG8gYSBzaWduZWQgaW50ZWdlci5cbiAgcmVzID0gc2lnbiAqIHJlcztcbiAgaWYgKChiYXNlID09IDEwKSAmJiAoKHJlcyB8IDApICE9IHJlcykpXG4gICAgLyogU2lnbmVkIHJlcHJlc2VudGF0aW9uIGV4cGVjdGVkLCBhbGxvdyAtMl4obmJpdHMtMSkgdG8gMl4obmJpdHMtMSkgLSAxICovXG4gICAgY2FtbF9mYWlsd2l0aChcImludF9vZl9zdHJpbmdcIik7XG4gIHJldHVybiByZXMgfCAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX211bCBjb25zdFxuZnVuY3Rpb24gY2FtbF9tdWwoYSxiKXtcbiAgcmV0dXJuIE1hdGguaW11bChhLGIpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2RpdlxuLy9SZXF1aXJlczogY2FtbF9yYWlzZV96ZXJvX2RpdmlkZVxuZnVuY3Rpb24gY2FtbF9kaXYoeCx5KSB7XG4gIGlmICh5ID09IDApIGNhbWxfcmFpc2VfemVyb19kaXZpZGUgKCk7XG4gIHJldHVybiAoeC95KXwwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21vZFxuLy9SZXF1aXJlczogY2FtbF9yYWlzZV96ZXJvX2RpdmlkZVxuZnVuY3Rpb24gY2FtbF9tb2QoeCx5KSB7XG4gIGlmICh5ID09IDApIGNhbWxfcmFpc2VfemVyb19kaXZpZGUgKCk7XG4gIHJldHVybiB4JXk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfYnN3YXAxNlxuZnVuY3Rpb24gY2FtbF9ic3dhcDE2KHgpIHtcbiAgcmV0dXJuICgoKCh4ICYgMHgwMEZGKSA8PCA4KSB8XG4gICAgICAgICAgICgoeCAmIDB4RkYwMCkgPj4gOCkpKTtcbn1cbi8vUHJvdmlkZXM6IGNhbWxfaW50MzJfYnN3YXBcbmZ1bmN0aW9uIGNhbWxfaW50MzJfYnN3YXAoeCkge1xuICByZXR1cm4gKCgoeCAmIDB4MDAwMDAwRkYpIDw8IDI0KSB8XG4gICAgICAgICAgKCh4ICYgMHgwMDAwRkYwMCkgPDwgOCkgfFxuICAgICAgICAgICgoeCAmIDB4MDBGRjAwMDApID4+PiA4KSB8XG4gICAgICAgICAgKCh4ICYgMHhGRjAwMDAwMCkgPj4+IDI0KSk7XG59XG4vL1Byb3ZpZGVzOiBjYW1sX2ludDY0X2Jzd2FwXG4vL1JlcXVpcmVzOiBjYW1sX2ludDY0X3RvX2J5dGVzLCBjYW1sX2ludDY0X29mX2J5dGVzXG5mdW5jdGlvbiBjYW1sX2ludDY0X2Jzd2FwKHgpIHtcbiAgdmFyIHkgPSBjYW1sX2ludDY0X3RvX2J5dGVzKHgpO1xuICByZXR1cm4gY2FtbF9pbnQ2NF9vZl9ieXRlcyhbeVs3XSwgeVs2XSwgeVs1XSwgeVs0XSwgeVszXSwgeVsyXSwgeVsxXSwgeVswXV0pO1xufVxuIiwiLy8gSnNfb2Zfb2NhbWwgcnVudGltZSBzdXBwb3J0XG4vLyBodHRwOi8vd3d3Lm9jc2lnZW4ub3JnL2pzX29mX29jYW1sL1xuLy9cbi8vIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4vLyBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbi8vIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHdpdGggbGlua2luZyBleGNlcHRpb247XG4vLyBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vL1xuLy8gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuLy8gR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vL1xuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4vLyBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcsIFVTQS5cblxuLy8vLy8vLy8vLy8vLyBIYXNodGJsXG5cblxuLy9Qcm92aWRlczogY2FtbF9oYXNoX3VuaXZfcGFyYW0gbXV0YWJsZVxuLy9SZXF1aXJlczogY2FtbF9pc19tbF9zdHJpbmcsIGNhbWxfaXNfbWxfYnl0ZXNcbi8vUmVxdWlyZXM6IGNhbWxfbWxfYnl0ZXNfY29udGVudFxuLy9SZXF1aXJlczogY2FtbF9pbnQ2NF90b19ieXRlcywgY2FtbF9pbnQ2NF9iaXRzX29mX2Zsb2F0LCBjYW1sX2N1c3RvbV9vcHNcbi8vUmVxdWlyZXM6IGNhbWxfbWxfYnl0ZXNfbGVuZ3RoLCBjYW1sX2pzYnl0ZXNfb2Zfc3RyaW5nXG4vL1ZlcnNpb246IDwgNC4xMlxuZnVuY3Rpb24gY2FtbF9oYXNoX3VuaXZfcGFyYW0gKGNvdW50LCBsaW1pdCwgb2JqKSB7XG4gIHZhciBoYXNoX2FjY3UgPSAwO1xuICBmdW5jdGlvbiBoYXNoX2F1eCAob2JqKSB7XG4gICAgbGltaXQgLS07XG4gICAgaWYgKGNvdW50IDwgMCB8fCBsaW1pdCA8IDApIHJldHVybjtcbiAgICBpZiAob2JqIGluc3RhbmNlb2YgQXJyYXkgJiYgb2JqWzBdID09PSAob2JqWzBdfDApKSB7XG4gICAgICBzd2l0Y2ggKG9ialswXSkge1xuICAgICAgY2FzZSAyNDg6XG4gICAgICAgIC8vIE9iamVjdFxuICAgICAgICBjb3VudCAtLTtcbiAgICAgICAgaGFzaF9hY2N1ID0gKGhhc2hfYWNjdSAqIDY1NTk5ICsgb2JqWzJdKSB8IDA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyNTA6XG4gICAgICAgIC8vIEZvcndhcmRcbiAgICAgICAgbGltaXQrKzsgaGFzaF9hdXgob2JqKTsgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBjb3VudCAtLTtcbiAgICAgICAgaGFzaF9hY2N1ID0gKGhhc2hfYWNjdSAqIDE5ICsgb2JqWzBdKSB8IDA7XG4gICAgICAgIGZvciAodmFyIGkgPSBvYmoubGVuZ3RoIC0gMTsgaSA+IDA7IGktLSkgaGFzaF9hdXggKG9ialtpXSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChjYW1sX2lzX21sX2J5dGVzKG9iaikpIHtcbiAgICAgIGNvdW50IC0tO1xuICAgICAgdmFyIGNvbnRlbnQgPSBjYW1sX21sX2J5dGVzX2NvbnRlbnQob2JqKTtcbiAgICAgIGlmKHR5cGVvZiBjb250ZW50ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIGZvciAodmFyIGIgPSBjb250ZW50LCBsID0gYi5sZW5ndGgsIGkgPSAwOyBpIDwgbDsgaSsrKVxuICAgICAgICAgIGhhc2hfYWNjdSA9IChoYXNoX2FjY3UgKiAxOSArIGIuY2hhckNvZGVBdChpKSkgfCAwO1xuICAgICAgfSBlbHNlIHsgLyogQVJSQVkgKi9cbiAgICAgICAgZm9yICh2YXIgYSA9IGNvbnRlbnQsIGwgPSBhLmxlbmd0aCwgaSA9IDA7IGkgPCBsOyBpKyspXG4gICAgICAgICAgaGFzaF9hY2N1ID0gKGhhc2hfYWNjdSAqIDE5ICsgYVtpXSkgfCAwO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoY2FtbF9pc19tbF9zdHJpbmcob2JqKSkge1xuICAgICAgdmFyIGpzYnl0ZXMgPSBjYW1sX2pzYnl0ZXNfb2Zfc3RyaW5nKG9iaik7XG4gICAgICBmb3IgKHZhciBiID0ganNieXRlcywgbCA9IGpzYnl0ZXMubGVuZ3RoLCBpID0gMDsgaSA8IGw7IGkrKylcbiAgICAgICAgaGFzaF9hY2N1ID0gKGhhc2hfYWNjdSAqIDE5ICsgYi5jaGFyQ29kZUF0KGkpKSB8IDA7XG4gICAgfSBlbHNlIGlmICh0eXBlb2Ygb2JqID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBmb3IgKHZhciBiID0gb2JqLCBsID0gb2JqLmxlbmd0aCwgaSA9IDA7IGkgPCBsOyBpKyspXG4gICAgICAgIGhhc2hfYWNjdSA9IChoYXNoX2FjY3UgKiAxOSArIGIuY2hhckNvZGVBdChpKSkgfCAwO1xuICAgIH0gZWxzZSBpZiAob2JqID09PSAob2JqfDApKSB7XG4gICAgICAvLyBJbnRlZ2VyXG4gICAgICBjb3VudCAtLTtcbiAgICAgIGhhc2hfYWNjdSA9IChoYXNoX2FjY3UgKiA2NTU5OSArIG9iaikgfCAwO1xuICAgIH0gZWxzZSBpZiAob2JqID09PSArb2JqKSB7XG4gICAgICAvLyBGbG9hdFxuICAgICAgY291bnQtLTtcbiAgICAgIHZhciBwID0gY2FtbF9pbnQ2NF90b19ieXRlcyAoY2FtbF9pbnQ2NF9iaXRzX29mX2Zsb2F0IChvYmopKTtcbiAgICAgIGZvciAodmFyIGkgPSA3OyBpID49IDA7IGktLSkgaGFzaF9hY2N1ID0gKGhhc2hfYWNjdSAqIDE5ICsgcFtpXSkgfCAwO1xuICAgIH0gZWxzZSBpZihvYmogJiYgb2JqLmNhbWxfY3VzdG9tKSB7XG4gICAgICBpZihjYW1sX2N1c3RvbV9vcHNbb2JqLmNhbWxfY3VzdG9tXSAmJiBjYW1sX2N1c3RvbV9vcHNbb2JqLmNhbWxfY3VzdG9tXS5oYXNoKSB7XG4gICAgICAgIHZhciBoID0gY2FtbF9jdXN0b21fb3BzW29iai5jYW1sX2N1c3RvbV0uaGFzaChvYmopIHwgMDtcbiAgICAgICAgaGFzaF9hY2N1ID0gKGhhc2hfYWNjdSAqIDY1NTk5ICsgaCkgfCAwO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBoYXNoX2F1eCAob2JqKTtcbiAgcmV0dXJuIGhhc2hfYWNjdSAmIDB4M0ZGRkZGRkY7XG59XG5cbi8vZnVuY3Rpb24gUk9UTDMyKHgsbikgeyByZXR1cm4gKCh4IDw8IG4pIHwgKHggPj4+ICgzMi1uKSkpOyB9XG4vL1Byb3ZpZGVzOiBjYW1sX2hhc2hfbWl4X2ludFxuLy9SZXF1aXJlczogY2FtbF9tdWxcbmZ1bmN0aW9uIGNhbWxfaGFzaF9taXhfaW50KGgsZCkge1xuICBkID0gY2FtbF9tdWwoZCwgMHhjYzllMmQ1MXwwKTtcbiAgZCA9ICgoZCA8PCAxNSkgfCAoZCA+Pj4gKDMyLTE1KSkpOyAvLyBST1RMMzIoZCwgMTUpO1xuICBkID0gY2FtbF9tdWwoZCwgMHgxYjg3MzU5Myk7XG4gIGggXj0gZDtcbiAgaCA9ICgoaCA8PCAxMykgfCAoaCA+Pj4gKDMyLTEzKSkpOyAgIC8vUk9UTDMyKGgsIDEzKTtcbiAgcmV0dXJuICgoKGggKyAoaCA8PCAyKSl8MCkgKyAoMHhlNjU0NmI2NHwwKSl8MDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9oYXNoX21peF9maW5hbFxuLy9SZXF1aXJlczogY2FtbF9tdWxcbmZ1bmN0aW9uIGNhbWxfaGFzaF9taXhfZmluYWwoaCkge1xuICBoIF49IGggPj4+IDE2O1xuICBoID0gY2FtbF9tdWwgKGgsIDB4ODVlYmNhNmJ8MCk7XG4gIGggXj0gaCA+Pj4gMTM7XG4gIGggPSBjYW1sX211bCAoaCwgMHhjMmIyYWUzNXwwKTtcbiAgaCBePSBoID4+PiAxNjtcbiAgcmV0dXJuIGg7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfaGFzaF9taXhfZmxvYXRcbi8vUmVxdWlyZXM6IGNhbWxfaW50NjRfYml0c19vZl9mbG9hdCwgY2FtbF9oYXNoX21peF9pbnQ2NFxuZnVuY3Rpb24gY2FtbF9oYXNoX21peF9mbG9hdCAoaCwgdjApIHtcbiAgcmV0dXJuIGNhbWxfaGFzaF9taXhfaW50NjQoaCwgY2FtbF9pbnQ2NF9iaXRzX29mX2Zsb2F0ICh2MCkpO1xufVxuLy9Qcm92aWRlczogY2FtbF9oYXNoX21peF9pbnQ2NFxuLy9SZXF1aXJlczogY2FtbF9oYXNoX21peF9pbnRcbi8vUmVxdWlyZXM6IGNhbWxfaW50NjRfbG8zMiwgY2FtbF9pbnQ2NF9oaTMyXG5mdW5jdGlvbiBjYW1sX2hhc2hfbWl4X2ludDY0IChoLCB2KSB7XG4gIGggPSBjYW1sX2hhc2hfbWl4X2ludChoLCBjYW1sX2ludDY0X2xvMzIodikpO1xuICBoID0gY2FtbF9oYXNoX21peF9pbnQoaCwgY2FtbF9pbnQ2NF9oaTMyKHYpKTtcbiAgcmV0dXJuIGg7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfaGFzaF9taXhfanNieXRlc1xuLy9SZXF1aXJlczogY2FtbF9oYXNoX21peF9pbnRcbmZ1bmN0aW9uIGNhbWxfaGFzaF9taXhfanNieXRlcyhoLCBzKSB7XG4gIHZhciBsZW4gPSBzLmxlbmd0aCwgaSwgdztcbiAgZm9yIChpID0gMDsgaSArIDQgPD0gbGVuOyBpICs9IDQpIHtcbiAgICB3ID0gcy5jaGFyQ29kZUF0KGkpXG4gICAgICB8IChzLmNoYXJDb2RlQXQoaSsxKSA8PCA4KVxuICAgICAgfCAocy5jaGFyQ29kZUF0KGkrMikgPDwgMTYpXG4gICAgICB8IChzLmNoYXJDb2RlQXQoaSszKSA8PCAyNCk7XG4gICAgaCA9IGNhbWxfaGFzaF9taXhfaW50KGgsIHcpO1xuICB9XG4gIHcgPSAwO1xuICBzd2l0Y2ggKGxlbiAmIDMpIHtcbiAgY2FzZSAzOiB3ICA9IHMuY2hhckNvZGVBdChpKzIpIDw8IDE2O1xuICBjYXNlIDI6IHcgfD0gcy5jaGFyQ29kZUF0KGkrMSkgPDwgODtcbiAgY2FzZSAxOlxuICAgIHcgfD0gcy5jaGFyQ29kZUF0KGkpO1xuICAgIGggPSBjYW1sX2hhc2hfbWl4X2ludChoLCB3KTtcbiAgZGVmYXVsdDpcbiAgfVxuICBoIF49IGxlbjtcbiAgcmV0dXJuIGg7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfaGFzaF9taXhfYnl0ZXNfYXJyXG4vL1JlcXVpcmVzOiBjYW1sX2hhc2hfbWl4X2ludFxuZnVuY3Rpb24gY2FtbF9oYXNoX21peF9ieXRlc19hcnIoaCwgcykge1xuICB2YXIgbGVuID0gcy5sZW5ndGgsIGksIHc7XG4gIGZvciAoaSA9IDA7IGkgKyA0IDw9IGxlbjsgaSArPSA0KSB7XG4gICAgdyA9IHNbaV1cbiAgICAgIHwgKHNbaSsxXSA8PCA4KVxuICAgICAgfCAoc1tpKzJdIDw8IDE2KVxuICAgICAgfCAoc1tpKzNdIDw8IDI0KTtcbiAgICBoID0gY2FtbF9oYXNoX21peF9pbnQoaCwgdyk7XG4gIH1cbiAgdyA9IDA7XG4gIHN3aXRjaCAobGVuICYgMykge1xuICBjYXNlIDM6IHcgID0gc1tpKzJdIDw8IDE2O1xuICBjYXNlIDI6IHcgfD0gc1tpKzFdIDw8IDg7XG4gIGNhc2UgMTogdyB8PSBzW2ldO1xuICAgIGggPSBjYW1sX2hhc2hfbWl4X2ludChoLCB3KTtcbiAgZGVmYXVsdDpcbiAgfVxuICBoIF49IGxlbjtcbiAgcmV0dXJuIGg7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfaGFzaF9taXhfYnl0ZXNcbi8vUmVxdWlyZXM6IGNhbWxfbWxfYnl0ZXNfY29udGVudFxuLy9SZXF1aXJlczogY2FtbF9oYXNoX21peF9qc2J5dGVzXG4vL1JlcXVpcmVzOiBjYW1sX2hhc2hfbWl4X2J5dGVzX2FyclxuZnVuY3Rpb24gY2FtbF9oYXNoX21peF9ieXRlcyhoLCB2KSB7XG4gIHZhciBjb250ZW50ID0gY2FtbF9tbF9ieXRlc19jb250ZW50KHYpO1xuICBpZih0eXBlb2YgY29udGVudCA9PT0gXCJzdHJpbmdcIilcbiAgICByZXR1cm4gY2FtbF9oYXNoX21peF9qc2J5dGVzKGgsIGNvbnRlbnQpXG4gIGVsc2UgLyogQVJSQVkgKi9cbiAgICByZXR1cm4gY2FtbF9oYXNoX21peF9ieXRlc19hcnIoaCwgY29udGVudCk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfaGFzaF9taXhfc3RyaW5nXG4vL1JlcXVpcmVzOiBjYW1sX2hhc2hfbWl4X2pzYnl0ZXMsIGNhbWxfanNieXRlc19vZl9zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfaGFzaF9taXhfc3RyaW5nKGgsIHYpIHtcbiAgcmV0dXJuIGNhbWxfaGFzaF9taXhfanNieXRlcyhoLCBjYW1sX2pzYnl0ZXNfb2Zfc3RyaW5nKHYpKTtcbn1cblxuXG4vL1Byb3ZpZGVzOiBjYW1sX2hhc2ggbXV0YWJsZVxuLy9SZXF1aXJlczogY2FtbF9pc19tbF9zdHJpbmcsIGNhbWxfaXNfbWxfYnl0ZXNcbi8vUmVxdWlyZXM6IGNhbWxfaGFzaF9taXhfaW50LCBjYW1sX2hhc2hfbWl4X2ZpbmFsXG4vL1JlcXVpcmVzOiBjYW1sX2hhc2hfbWl4X2Zsb2F0LCBjYW1sX2hhc2hfbWl4X3N0cmluZywgY2FtbF9oYXNoX21peF9ieXRlcywgY2FtbF9jdXN0b21fb3BzXG4vL1JlcXVpcmVzOiBjYW1sX2hhc2hfbWl4X2pzYnl0ZXNcbi8vUmVxdWlyZXM6IGNhbWxfaXNfY29udGludWF0aW9uX3RhZ1xuZnVuY3Rpb24gY2FtbF9oYXNoIChjb3VudCwgbGltaXQsIHNlZWQsIG9iaikge1xuICB2YXIgcXVldWUsIHJkLCB3ciwgc3osIG51bSwgaCwgdiwgaSwgbGVuO1xuICBzeiA9IGxpbWl0O1xuICBpZiAoc3ogPCAwIHx8IHN6ID4gMjU2KSBzeiA9IDI1NjtcbiAgbnVtID0gY291bnQ7XG4gIGggPSBzZWVkO1xuICBxdWV1ZSA9IFtvYmpdOyByZCA9IDA7IHdyID0gMTtcbiAgd2hpbGUgKHJkIDwgd3IgJiYgbnVtID4gMCkge1xuICAgIHYgPSBxdWV1ZVtyZCsrXTtcbiAgICBpZiAodiAmJiB2LmNhbWxfY3VzdG9tKXtcbiAgICAgIGlmKGNhbWxfY3VzdG9tX29wc1t2LmNhbWxfY3VzdG9tXSAmJiBjYW1sX2N1c3RvbV9vcHNbdi5jYW1sX2N1c3RvbV0uaGFzaCkge1xuICAgICAgICB2YXIgaGggPSBjYW1sX2N1c3RvbV9vcHNbdi5jYW1sX2N1c3RvbV0uaGFzaCh2KTtcbiAgICAgICAgaCA9IGNhbWxfaGFzaF9taXhfaW50IChoLCBoaCk7XG4gICAgICAgIG51bSAtLTtcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSBpZiAodiBpbnN0YW5jZW9mIEFycmF5ICYmIHZbMF0gPT09ICh2WzBdfDApKSB7XG4gICAgICBzd2l0Y2ggKHZbMF0pIHtcbiAgICAgIGNhc2UgMjQ4OlxuICAgICAgICAvLyBPYmplY3RcbiAgICAgICAgaCA9IGNhbWxfaGFzaF9taXhfaW50KGgsIHZbMl0pO1xuICAgICAgICBudW0tLTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI1MDpcbiAgICAgICAgLy8gRm9yd2FyZFxuICAgICAgICBxdWV1ZVstLXJkXSA9IHZbMV07XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYoY2FtbF9pc19jb250aW51YXRpb25fdGFnKHZbMF0pKSB7XG4gICAgICAgICAgLyogQWxsIGNvbnRpbnVhdGlvbnMgaGFzaCB0byB0aGUgc2FtZSB2YWx1ZSxcbiAgICAgICAgICAgICBzaW5jZSB3ZSBoYXZlIG5vIGlkZWEgaG93IHRvIGRpc3Rpbmd1aXNoIHRoZW0uICovXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHRhZyA9ICgodi5sZW5ndGggLSAxKSA8PCAxMCkgfCB2WzBdO1xuICAgICAgICBoID0gY2FtbF9oYXNoX21peF9pbnQoaCwgdGFnKTtcbiAgICAgICAgZm9yIChpID0gMSwgbGVuID0gdi5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgIGlmICh3ciA+PSBzeikgYnJlYWs7XG4gICAgICAgICAgcXVldWVbd3IrK10gPSB2W2ldO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoY2FtbF9pc19tbF9ieXRlcyh2KSkge1xuICAgICAgaCA9IGNhbWxfaGFzaF9taXhfYnl0ZXMoaCx2KVxuICAgICAgbnVtLS07XG4gICAgfSBlbHNlIGlmIChjYW1sX2lzX21sX3N0cmluZyh2KSkge1xuICAgICAgaCA9IGNhbWxfaGFzaF9taXhfc3RyaW5nKGgsdilcbiAgICAgIG51bS0tO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHYgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIGggPSBjYW1sX2hhc2hfbWl4X2pzYnl0ZXMoaCx2KVxuICAgICAgbnVtLS07XG4gICAgfSBlbHNlIGlmICh2ID09PSAodnwwKSkge1xuICAgICAgLy8gSW50ZWdlclxuICAgICAgaCA9IGNhbWxfaGFzaF9taXhfaW50KGgsIHYrdisxKTtcbiAgICAgIG51bS0tO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHYgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgIC8vIEZsb2F0XG4gICAgICBoID0gY2FtbF9oYXNoX21peF9mbG9hdChoLHYpO1xuICAgICAgbnVtLS07XG4gICAgfVxuICB9XG4gIGggPSBjYW1sX2hhc2hfbWl4X2ZpbmFsKGgpO1xuICByZXR1cm4gaCAmIDB4M0ZGRkZGRkY7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3RyaW5nX2hhc2hcbi8vUmVxdWlyZXM6IGNhbWxfaGFzaF9taXhfZmluYWwsIGNhbWxfaGFzaF9taXhfc3RyaW5nXG5mdW5jdGlvbiBjYW1sX3N0cmluZ19oYXNoKGgsIHYpe1xuICB2YXIgaCA9IGNhbWxfaGFzaF9taXhfc3RyaW5nKGgsdik7XG4gIHZhciBoID0gY2FtbF9oYXNoX21peF9maW5hbChoKTtcbiAgcmV0dXJuIGggJiAweDNGRkZGRkZGO1xufVxuIiwiLy8gSnNfb2Zfb2NhbWwgcnVudGltZSBzdXBwb3J0XG4vLyBodHRwOi8vd3d3Lm9jc2lnZW4ub3JnL2pzX29mX29jYW1sL1xuLy8gQ29weXJpZ2h0IChDKSAyMDE0IErDqXLDtG1lIFZvdWlsbG9uLCBIdWdvIEhldXphcmRcbi8vIExhYm9yYXRvaXJlIFBQUyAtIENOUlMgVW5pdmVyc2l0w6kgUGFyaXMgRGlkZXJvdFxuLy9cbi8vIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4vLyBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbi8vIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHdpdGggbGlua2luZyBleGNlcHRpb247XG4vLyBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vL1xuLy8gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuLy8gR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vL1xuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4vLyBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcsIFVTQS5cblxuLy8vLy8vLy8vLy8vLyBJb1xuXG4vL1Byb3ZpZGVzOiBjYW1sX3N5c19mZHNcbnZhciBjYW1sX3N5c19mZHMgPSBuZXcgQXJyYXkoMyk7XG5cbi8vUHJvdmlkZXM6IGNhbWxfc3lzX2Nsb3NlXG4vL1JlcXVpcmVzOiBjYW1sX3N5c19mZHNcbmZ1bmN0aW9uIGNhbWxfc3lzX2Nsb3NlKGZkKSB7XG4gIHZhciBmaWxlID0gY2FtbF9zeXNfZmRzW2ZkXTtcbiAgaWYoZmlsZSkgZmlsZS5jbG9zZSgpO1xuICBkZWxldGUgY2FtbF9zeXNfZmRzW2ZkXTtcbiAgcmV0dXJuIDA7XG59XG5cblxuLy9Qcm92aWRlczogY2FtbF9zeXNfb3BlblxuLy9SZXF1aXJlczogY2FtbF9yYWlzZV9zeXNfZXJyb3Jcbi8vUmVxdWlyZXM6IE1sRmFrZUZkX291dFxuLy9SZXF1aXJlczogcmVzb2x2ZV9mc19kZXZpY2Vcbi8vUmVxdWlyZXM6IGNhbWxfanNieXRlc19vZl9zdHJpbmdcbi8vUmVxdWlyZXM6IGZzX25vZGVfc3VwcG9ydGVkXG4vL1JlcXVpcmVzOiBjYW1sX3N5c19mZHNcbi8vUmVxdWlyZXM6IGNhbWxfc3lzX29wZW5fZm9yX25vZGVcbmZ1bmN0aW9uIGNhbWxfc3lzX29wZW5faW50ZXJuYWwoZmlsZSxpZHgpIHtcbiAgaWYoaWR4ID09IHVuZGVmaW5lZCl7XG4gICAgaWR4ID0gY2FtbF9zeXNfZmRzLmxlbmd0aDtcbiAgfVxuICBjYW1sX3N5c19mZHNbaWR4XSA9IGZpbGU7XG4gIHJldHVybiBpZHggfCAwO1xufVxuZnVuY3Rpb24gY2FtbF9zeXNfb3BlbiAobmFtZSwgZmxhZ3MsIF9wZXJtcykge1xuICB2YXIgZiA9IHt9O1xuICB3aGlsZShmbGFncyl7XG4gICAgc3dpdGNoKGZsYWdzWzFdKXtcbiAgICBjYXNlIDA6IGYucmRvbmx5ID0gMTticmVhaztcbiAgICBjYXNlIDE6IGYud3Jvbmx5ID0gMTticmVhaztcbiAgICBjYXNlIDI6IGYuYXBwZW5kID0gMTticmVhaztcbiAgICBjYXNlIDM6IGYuY3JlYXRlID0gMTticmVhaztcbiAgICBjYXNlIDQ6IGYudHJ1bmNhdGUgPSAxO2JyZWFrO1xuICAgIGNhc2UgNTogZi5leGNsID0gMTsgYnJlYWs7XG4gICAgY2FzZSA2OiBmLmJpbmFyeSA9IDE7YnJlYWs7XG4gICAgY2FzZSA3OiBmLnRleHQgPSAxO2JyZWFrO1xuICAgIGNhc2UgODogZi5ub25ibG9jayA9IDE7YnJlYWs7XG4gICAgfVxuICAgIGZsYWdzPWZsYWdzWzJdO1xuICB9XG4gIGlmKGYucmRvbmx5ICYmIGYud3Jvbmx5KVxuICAgIGNhbWxfcmFpc2Vfc3lzX2Vycm9yKGNhbWxfanNieXRlc19vZl9zdHJpbmcobmFtZSkgKyBcIiA6IGZsYWdzIE9wZW5fcmRvbmx5IGFuZCBPcGVuX3dyb25seSBhcmUgbm90IGNvbXBhdGlibGVcIik7XG4gIGlmKGYudGV4dCAmJiBmLmJpbmFyeSlcbiAgICBjYW1sX3JhaXNlX3N5c19lcnJvcihjYW1sX2pzYnl0ZXNfb2Zfc3RyaW5nKG5hbWUpICsgXCIgOiBmbGFncyBPcGVuX3RleHQgYW5kIE9wZW5fYmluYXJ5IGFyZSBub3QgY29tcGF0aWJsZVwiKTtcbiAgdmFyIHJvb3QgPSByZXNvbHZlX2ZzX2RldmljZShuYW1lKTtcbiAgdmFyIGZpbGUgPSByb290LmRldmljZS5vcGVuKHJvb3QucmVzdCxmKTtcbiAgcmV0dXJuIGNhbWxfc3lzX29wZW5faW50ZXJuYWwgKGZpbGUsIHVuZGVmaW5lZCk7XG59XG4oZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBmaWxlKGZkLCBmbGFncykge1xuICAgIGlmKGZzX25vZGVfc3VwcG9ydGVkKCkpIHtcbiAgICAgIHJldHVybiBjYW1sX3N5c19vcGVuX2Zvcl9ub2RlKGZkLCBmbGFncyk7XG4gICAgfVxuICAgIGVsc2VcbiAgICAgIHJldHVybiBuZXcgTWxGYWtlRmRfb3V0KGZkLCBmbGFncylcbiAgfVxuICBjYW1sX3N5c19vcGVuX2ludGVybmFsKGZpbGUoMCx7cmRvbmx5OjEsYWx0bmFtZTpcIi9kZXYvc3RkaW5cIixpc0NoYXJhY3RlckRldmljZTp0cnVlfSksIDApO1xuICBjYW1sX3N5c19vcGVuX2ludGVybmFsKGZpbGUoMSx7YnVmZmVyZWQ6Mix3cm9ubHk6MSxpc0NoYXJhY3RlckRldmljZTp0cnVlfSksIDEpO1xuICBjYW1sX3N5c19vcGVuX2ludGVybmFsKGZpbGUoMix7YnVmZmVyZWQ6Mix3cm9ubHk6MSxpc0NoYXJhY3RlckRldmljZTp0cnVlfSksIDIpO1xufSkoKVxuXG5cbi8vIG9jYW1sIENoYW5uZWxzXG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfc2V0X2NoYW5uZWxfbmFtZVxuLy9SZXF1aXJlczogY2FtbF9tbF9jaGFubmVsX2dldFxuZnVuY3Rpb24gY2FtbF9tbF9zZXRfY2hhbm5lbF9uYW1lKGNoYW5pZCwgbmFtZSkge1xuICB2YXIgY2hhbiA9IGNhbWxfbWxfY2hhbm5lbF9nZXQoY2hhbmlkKTtcbiAgY2hhbi5uYW1lID0gbmFtZTtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfY2hhbm5lbHNcbnZhciBjYW1sX21sX2NoYW5uZWxzID0gbmV3IEFycmF5KCk7XG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfY2hhbm5lbF9yZWRpcmVjdFxuLy9SZXF1aXJlczogY2FtbF9tbF9jaGFubmVsX2dldCwgY2FtbF9tbF9jaGFubmVsc1xuZnVuY3Rpb24gY2FtbF9tbF9jaGFubmVsX3JlZGlyZWN0IChjYXB0dXJlZCwgaW50byl7XG4gIHZhciB0b19yZXN0b3JlID0gY2FtbF9tbF9jaGFubmVsX2dldChjYXB0dXJlZCk7XG4gIHZhciBuZXdfID0gY2FtbF9tbF9jaGFubmVsX2dldChpbnRvKTtcbiAgY2FtbF9tbF9jaGFubmVsc1tjYXB0dXJlZF0gPSBuZXdfOyAvLyBYWFhcbiAgcmV0dXJuIHRvX3Jlc3RvcmU7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfY2hhbm5lbF9yZXN0b3JlXG4vL1JlcXVpcmVzOiBjYW1sX21sX2NoYW5uZWxzXG5mdW5jdGlvbiBjYW1sX21sX2NoYW5uZWxfcmVzdG9yZSAoY2FwdHVyZWQsIHRvX3Jlc3RvcmUpe1xuICBjYW1sX21sX2NoYW5uZWxzW2NhcHR1cmVkXSA9IHRvX3Jlc3RvcmU7IC8vIFhYWFxuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9tbF9jaGFubmVsX2dldFxuLy9SZXF1aXJlczogY2FtbF9tbF9jaGFubmVsc1xuZnVuY3Rpb24gY2FtbF9tbF9jaGFubmVsX2dldChpZCkge1xuICByZXR1cm4gY2FtbF9tbF9jaGFubmVsc1tpZF07IC8vIFhYWFxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21sX291dF9jaGFubmVsc19saXN0XG4vL1JlcXVpcmVzOiBjYW1sX21sX2NoYW5uZWxzXG5mdW5jdGlvbiBjYW1sX21sX291dF9jaGFubmVsc19saXN0ICgpIHtcbiAgdmFyIGwgPSAwO1xuICBmb3IodmFyIGMgPSAwOyBjIDwgY2FtbF9tbF9jaGFubmVscy5sZW5ndGg7IGMrKyl7XG4gICAgaWYoY2FtbF9tbF9jaGFubmVsc1tjXSAmJiBjYW1sX21sX2NoYW5uZWxzW2NdLm9wZW5lZCAmJiBjYW1sX21sX2NoYW5uZWxzW2NdLm91dClcbiAgICAgIGw9WzAsY2FtbF9tbF9jaGFubmVsc1tjXS5mZCxsXTtcbiAgfVxuICByZXR1cm4gbDtcbn1cblxuXG4vL1Byb3ZpZGVzOiBjYW1sX21sX29wZW5fZGVzY3JpcHRvcl9vdXRcbi8vUmVxdWlyZXM6IGNhbWxfbWxfY2hhbm5lbHMsIGNhbWxfc3lzX2Zkc1xuLy9SZXF1aXJlczogY2FtbF9yYWlzZV9zeXNfZXJyb3Jcbi8vUmVxdWlyZXM6IGNhbWxfc3lzX29wZW5cbmZ1bmN0aW9uIGNhbWxfbWxfb3Blbl9kZXNjcmlwdG9yX291dCAoZmQpIHtcbiAgdmFyIGZpbGUgPSBjYW1sX3N5c19mZHNbZmRdO1xuICBpZihmaWxlLmZsYWdzLnJkb25seSkgY2FtbF9yYWlzZV9zeXNfZXJyb3IoXCJmZCBcIisgZmQgKyBcIiBpcyByZWFkb25seVwiKTtcbiAgdmFyIGJ1ZmZlcmVkID0gKGZpbGUuZmxhZ3MuYnVmZmVyZWQgIT09IHVuZGVmaW5lZCkgPyBmaWxlLmZsYWdzLmJ1ZmZlcmVkIDogMTtcbiAgdmFyIGNoYW5uZWwgPSB7XG4gICAgZmlsZTpmaWxlLFxuICAgIG9mZnNldDpmaWxlLmZsYWdzLmFwcGVuZD9maWxlLmxlbmd0aCgpOjAsXG4gICAgZmQ6ZmQsXG4gICAgb3BlbmVkOnRydWUsXG4gICAgb3V0OnRydWUsXG4gICAgYnVmZmVyX2N1cnI6MCxcbiAgICBidWZmZXI6bmV3IFVpbnQ4QXJyYXkoNjU1MzYpLFxuICAgIGJ1ZmZlcmVkOmJ1ZmZlcmVkXG4gIH07XG4gIGNhbWxfbWxfY2hhbm5lbHNbY2hhbm5lbC5mZF09Y2hhbm5lbDtcbiAgcmV0dXJuIGNoYW5uZWwuZmQ7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfb3Blbl9kZXNjcmlwdG9yX2luXG4vL1JlcXVpcmVzOiBjYW1sX21sX2NoYW5uZWxzLCBjYW1sX3N5c19mZHNcbi8vUmVxdWlyZXM6IGNhbWxfcmFpc2Vfc3lzX2Vycm9yXG4vL1JlcXVpcmVzOiBjYW1sX3N5c19vcGVuXG5mdW5jdGlvbiBjYW1sX21sX29wZW5fZGVzY3JpcHRvcl9pbiAoZmQpICB7XG4gIHZhciBmaWxlID0gY2FtbF9zeXNfZmRzW2ZkXTtcbiAgaWYoZmlsZS5mbGFncy53cm9ubHkpIGNhbWxfcmFpc2Vfc3lzX2Vycm9yKFwiZmQgXCIrIGZkICsgXCIgaXMgd3JpdGVvbmx5XCIpO1xuICB2YXIgcmVmaWxsID0gbnVsbDtcbiAgdmFyIGNoYW5uZWwgPSB7XG4gICAgZmlsZTpmaWxlLFxuICAgIG9mZnNldDpmaWxlLmZsYWdzLmFwcGVuZD9maWxlLmxlbmd0aCgpOjAsXG4gICAgZmQ6ZmQsXG4gICAgb3BlbmVkOnRydWUsXG4gICAgb3V0OiBmYWxzZSxcbiAgICBidWZmZXJfY3VycjowLFxuICAgIGJ1ZmZlcl9tYXg6MCxcbiAgICBidWZmZXI6bmV3IFVpbnQ4QXJyYXkoNjU1MzYpLFxuICAgIHJlZmlsbDpyZWZpbGxcbiAgfTtcbiAgY2FtbF9tbF9jaGFubmVsc1tjaGFubmVsLmZkXT1jaGFubmVsO1xuICByZXR1cm4gY2hhbm5lbC5mZDtcbn1cblxuXG4vL1Byb3ZpZGVzOiBjYW1sX21sX29wZW5fZGVzY3JpcHRvcl9pbl93aXRoX2ZsYWdzXG4vL1JlcXVpcmVzOiBjYW1sX21sX29wZW5fZGVzY3JpcHRvcl9pblxuLy9WZXJzaW9uOiA+PSA1LjFcbmZ1bmN0aW9uIGNhbWxfbWxfb3Blbl9kZXNjcmlwdG9yX2luX3dpdGhfZmxhZ3MoZmQsIGZsYWdzKXtcbiAgcmV0dXJuIGNhbWxfbWxfb3Blbl9kZXNjcmlwdG9yX2luKGZkKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9tbF9vcGVuX2Rlc2NyaXB0b3Jfb3V0X3dpdGhfZmxhZ3Ncbi8vUmVxdWlyZXM6IGNhbWxfbWxfb3Blbl9kZXNjcmlwdG9yX291dFxuLy9WZXJzaW9uOiA+PSA1LjFcbmZ1bmN0aW9uIGNhbWxfbWxfb3Blbl9kZXNjcmlwdG9yX291dF93aXRoX2ZsYWdzKGZkLCBmbGFncyl7XG4gIHJldHVybiBjYW1sX21sX29wZW5fZGVzY3JpcHRvcl9vdXQoZmQpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2NoYW5uZWxfZGVzY3JpcHRvclxuLy9SZXF1aXJlczogY2FtbF9tbF9jaGFubmVsX2dldFxuLy9BbGlhczogd2luX2ZpbGVkZXNjcl9vZl9jaGFubmVsXG5mdW5jdGlvbiBjYW1sX2NoYW5uZWxfZGVzY3JpcHRvcihjaGFuaWQpe1xuICB2YXIgY2hhbiA9IGNhbWxfbWxfY2hhbm5lbF9nZXQoY2hhbmlkKTtcbiAgcmV0dXJuIGNoYW4uZmQ7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfc2V0X2JpbmFyeV9tb2RlXG4vL1JlcXVpcmVzOiBjYW1sX21sX2NoYW5uZWxfZ2V0XG5mdW5jdGlvbiBjYW1sX21sX3NldF9iaW5hcnlfbW9kZShjaGFuaWQsbW9kZSl7XG4gIHZhciBjaGFuID0gY2FtbF9tbF9jaGFubmVsX2dldChjaGFuaWQpO1xuICBjaGFuLmZpbGUuZmxhZ3MudGV4dCA9ICFtb2RlXG4gIGNoYW4uZmlsZS5mbGFncy5iaW5hcnkgPSBtb2RlXG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21sX2lzX2JpbmFyeV9tb2RlXG4vL1JlcXVpcmVzOiBjYW1sX21sX2NoYW5uZWxfZ2V0XG4vL1ZlcnNpb246ID49IDUuMlxuZnVuY3Rpb24gY2FtbF9tbF9pc19iaW5hcnlfbW9kZShjaGFuaWQpIHtcbiAgdmFyIGNoYW4gPSBjYW1sX21sX2NoYW5uZWxfZ2V0KGNoYW5pZCk7XG4gIHJldHVybiBjaGFuLmZpbGUuZmxhZ3MuYmluYXJ5XG59XG5cbi8vSW5wdXQgZnJvbSBpbl9jaGFubmVsXG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfY2xvc2VfY2hhbm5lbFxuLy9SZXF1aXJlczogY2FtbF9tbF9mbHVzaCwgY2FtbF9tbF9jaGFubmVsX2dldFxuLy9SZXF1aXJlczogY2FtbF9zeXNfY2xvc2VcbmZ1bmN0aW9uIGNhbWxfbWxfY2xvc2VfY2hhbm5lbCAoY2hhbmlkKSB7XG4gIHZhciBjaGFuID0gY2FtbF9tbF9jaGFubmVsX2dldChjaGFuaWQpO1xuICBpZihjaGFuLm9wZW5lZCkge1xuICAgIGNoYW4ub3BlbmVkID0gZmFsc2U7XG4gICAgY2FtbF9zeXNfY2xvc2UoY2hhbi5mZCk7XG4gICAgY2hhbi5mZCA9IC0xO1xuICAgIGNoYW4uYnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkoMCk7XG4gICAgY2hhbi5idWZmZXJfY3VyciA9IDA7XG4gICAgY2hhbi5idWZmZXJfbWF4ID0gMDtcbiAgfVxuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9tbF9jaGFubmVsX3NpemVcbi8vUmVxdWlyZXM6IGNhbWxfbWxfY2hhbm5lbF9nZXRcbmZ1bmN0aW9uIGNhbWxfbWxfY2hhbm5lbF9zaXplKGNoYW5pZCkge1xuICB2YXIgY2hhbiA9IGNhbWxfbWxfY2hhbm5lbF9nZXQoY2hhbmlkKTtcbiAgcmV0dXJuIGNoYW4uZmlsZS5sZW5ndGgoKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9tbF9jaGFubmVsX3NpemVfNjRcbi8vUmVxdWlyZXM6IGNhbWxfaW50NjRfb2ZfZmxvYXQsY2FtbF9tbF9jaGFubmVsX2dldFxuZnVuY3Rpb24gY2FtbF9tbF9jaGFubmVsX3NpemVfNjQoY2hhbmlkKSB7XG4gIHZhciBjaGFuID0gY2FtbF9tbF9jaGFubmVsX2dldChjaGFuaWQpO1xuICByZXR1cm4gY2FtbF9pbnQ2NF9vZl9mbG9hdChjaGFuLmZpbGUubGVuZ3RoICgpKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9tbF9zZXRfY2hhbm5lbF9vdXRwdXRcbi8vUmVxdWlyZXM6IGNhbWxfbWxfY2hhbm5lbF9nZXRcbmZ1bmN0aW9uIGNhbWxfbWxfc2V0X2NoYW5uZWxfb3V0cHV0KGNoYW5pZCxmKSB7XG4gIHZhciBjaGFuID0gY2FtbF9tbF9jaGFubmVsX2dldChjaGFuaWQpO1xuICBjaGFuLm91dHB1dCA9IChmdW5jdGlvbiAocykge2Yocyl9KTtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfc2V0X2NoYW5uZWxfcmVmaWxsXG4vL1JlcXVpcmVzOiBjYW1sX21sX2NoYW5uZWxfZ2V0XG5mdW5jdGlvbiBjYW1sX21sX3NldF9jaGFubmVsX3JlZmlsbChjaGFuaWQsZikge1xuICBjYW1sX21sX2NoYW5uZWxfZ2V0KGNoYW5pZCkucmVmaWxsID0gZjtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfcmVmaWxsXG4vL1JlcXVpcmVzOiBjYW1sX21sX3N0cmluZ19sZW5ndGgsIGNhbWxfdWludDhfYXJyYXlfb2Zfc3RyaW5nXG5mdW5jdGlvbiBjYW1sX3JlZmlsbCAoY2hhbikge1xuICBpZihjaGFuLnJlZmlsbCAhPSBudWxsKXtcbiAgICB2YXIgc3RyID0gY2hhbi5yZWZpbGwoKTtcbiAgICB2YXIgc3RyX2EgPSBjYW1sX3VpbnQ4X2FycmF5X29mX3N0cmluZyhzdHIpO1xuICAgIGlmIChzdHJfYS5sZW5ndGggPT0gMCkge1xuICAgICAgY2hhbi5yZWZpbGwgPSBudWxsXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgaWYoY2hhbi5idWZmZXIubGVuZ3RoIDwgY2hhbi5idWZmZXJfbWF4ICsgc3RyX2EubGVuZ3RoKXtcbiAgICAgICAgdmFyIGIgPSBuZXcgVWludDhBcnJheShjaGFuLmJ1ZmZlcl9tYXggKyBzdHJfYS5sZW5ndGgpO1xuICAgICAgICBiLnNldChjaGFuLmJ1ZmZlcik7XG4gICAgICAgIGNoYW4uYnVmZmVyID0gYjtcbiAgICAgIH1cbiAgICAgIGNoYW4uYnVmZmVyLnNldChzdHJfYSxjaGFuLmJ1ZmZlcl9tYXgpO1xuICAgICAgY2hhbi5vZmZzZXQgKz0gc3RyX2EubGVuZ3RoO1xuICAgICAgY2hhbi5idWZmZXJfbWF4ICs9IHN0cl9hLmxlbmd0aDtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIG5yZWFkID0gY2hhbi5maWxlLnJlYWQoY2hhbi5vZmZzZXQsIGNoYW4uYnVmZmVyLCBjaGFuLmJ1ZmZlcl9tYXgsIGNoYW4uYnVmZmVyLmxlbmd0aCAtIGNoYW4uYnVmZmVyX21heCk7XG4gICAgY2hhbi5vZmZzZXQgKz0gbnJlYWQ7XG4gICAgY2hhbi5idWZmZXJfbWF4ICs9IG5yZWFkO1xuICB9XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfaW5wdXRcbi8vUmVxdWlyZXM6IGNhbWxfbWxfaW5wdXRfYmxvY2tcbi8vUmVxdWlyZXM6IGNhbWxfdWludDhfYXJyYXlfb2ZfYnl0ZXNcbmZ1bmN0aW9uIGNhbWxfbWxfaW5wdXQgKGNoYW5pZCwgYiwgaSwgbCkge1xuICB2YXIgYmEgPSBjYW1sX3VpbnQ4X2FycmF5X29mX2J5dGVzKGIpO1xuICByZXR1cm4gY2FtbF9tbF9pbnB1dF9ibG9jayhjaGFuaWQsIGJhLCBpLCBsKVxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21sX2lucHV0X2JpZ2FycmF5XG4vL1JlcXVpcmVzOiBjYW1sX21sX2lucHV0X2Jsb2NrXG4vL1JlcXVpcmVzOiBjYW1sX2JhX3RvX3R5cGVkX2FycmF5XG5mdW5jdGlvbiBjYW1sX21sX2lucHV0X2JpZ2FycmF5IChjaGFuaWQsIGIsIGksIGwpIHtcbiAgdmFyIGJhID0gY2FtbF9iYV90b190eXBlZF9hcnJheShiKTtcbiAgcmV0dXJuIGNhbWxfbWxfaW5wdXRfYmxvY2soY2hhbmlkLCBiYSwgaSwgbClcbn1cblxuLy9Qcm92aWRlczogY2FtbF9tbF9pbnB1dF9ibG9ja1xuLy9SZXF1aXJlczogY2FtbF9yZWZpbGwsIGNhbWxfbWxfY2hhbm5lbF9nZXRcbmZ1bmN0aW9uIGNhbWxfbWxfaW5wdXRfYmxvY2sgKGNoYW5pZCwgYmEsIGksIGwpIHtcbiAgdmFyIGNoYW4gPSBjYW1sX21sX2NoYW5uZWxfZ2V0KGNoYW5pZCk7XG4gIHZhciBuID0gbDtcbiAgdmFyIGF2YWlsID0gY2hhbi5idWZmZXJfbWF4IC0gY2hhbi5idWZmZXJfY3VycjtcbiAgaWYobCA8PSBhdmFpbCkge1xuICAgIGJhLnNldChjaGFuLmJ1ZmZlci5zdWJhcnJheShjaGFuLmJ1ZmZlcl9jdXJyLGNoYW4uYnVmZmVyX2N1cnIgKyBsKSwgaSk7XG4gICAgY2hhbi5idWZmZXJfY3VyciArPSBsO1xuICB9XG4gIGVsc2UgaWYoYXZhaWwgPiAwKSB7XG4gICAgYmEuc2V0KGNoYW4uYnVmZmVyLnN1YmFycmF5KGNoYW4uYnVmZmVyX2N1cnIsY2hhbi5idWZmZXJfY3VyciArIGF2YWlsKSwgaSk7XG4gICAgY2hhbi5idWZmZXJfY3VyciArPSBhdmFpbDtcbiAgICBuID0gYXZhaWw7XG4gIH0gZWxzZSB7XG4gICAgY2hhbi5idWZmZXJfY3VyciA9IDA7XG4gICAgY2hhbi5idWZmZXJfbWF4ID0gMDtcbiAgICBjYW1sX3JlZmlsbChjaGFuKTtcbiAgICB2YXIgYXZhaWwgPSBjaGFuLmJ1ZmZlcl9tYXggLSBjaGFuLmJ1ZmZlcl9jdXJyO1xuICAgIGlmKG4gPiBhdmFpbCkgbiA9IGF2YWlsO1xuICAgIGJhLnNldChjaGFuLmJ1ZmZlci5zdWJhcnJheShjaGFuLmJ1ZmZlcl9jdXJyLGNoYW4uYnVmZmVyX2N1cnIgKyBuKSwgaSk7XG4gICAgY2hhbi5idWZmZXJfY3VyciArPSBuO1xuICB9XG4gIHJldHVybiBuIHwgMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9pbnB1dF92YWx1ZVxuLy9SZXF1aXJlczogY2FtbF9tYXJzaGFsX2RhdGFfc2l6ZSwgY2FtbF9pbnB1dF92YWx1ZV9mcm9tX2J5dGVzLCBjYW1sX2NyZWF0ZV9ieXRlcywgY2FtbF9tbF9jaGFubmVsX2dldCwgY2FtbF9ieXRlc19vZl9hcnJheVxuLy9SZXF1aXJlczogY2FtbF9yZWZpbGwsIGNhbWxfZmFpbHdpdGgsIGNhbWxfcmFpc2VfZW5kX29mX2ZpbGVcbi8vUmVxdWlyZXM6IGNhbWxfbWFyc2hhbF9oZWFkZXJfc2l6ZVxuZnVuY3Rpb24gY2FtbF9pbnB1dF92YWx1ZSAoY2hhbmlkKSB7XG4gIHZhciBjaGFuID0gY2FtbF9tbF9jaGFubmVsX2dldChjaGFuaWQpO1xuICB2YXIgaGVhZGVyID0gbmV3IFVpbnQ4QXJyYXkoY2FtbF9tYXJzaGFsX2hlYWRlcl9zaXplKTtcbiAgZnVuY3Rpb24gYmxvY2soYnVmZmVyLCBvZmZzZXQsIG4pIHtcbiAgICB2YXIgciA9IDA7XG4gICAgd2hpbGUociA8IG4pe1xuICAgICAgaWYoY2hhbi5idWZmZXJfY3VyciA+PSBjaGFuLmJ1ZmZlcl9tYXgpe1xuICAgICAgICBjaGFuLmJ1ZmZlcl9jdXJyID0gMDtcbiAgICAgICAgY2hhbi5idWZmZXJfbWF4ID0gMDtcbiAgICAgICAgY2FtbF9yZWZpbGwoY2hhbik7XG4gICAgICB9XG4gICAgICBpZiAoY2hhbi5idWZmZXJfY3VyciA+PSBjaGFuLmJ1ZmZlcl9tYXgpXG4gICAgICAgIGJyZWFrO1xuICAgICAgYnVmZmVyW29mZnNldCtyXSA9IGNoYW4uYnVmZmVyW2NoYW4uYnVmZmVyX2N1cnJdO1xuICAgICAgY2hhbi5idWZmZXJfY3VycisrO1xuICAgICAgcisrO1xuICAgIH1cbiAgICByZXR1cm4gcjtcbiAgfVxuICB2YXIgciA9IGJsb2NrKGhlYWRlciwgMCwgY2FtbF9tYXJzaGFsX2hlYWRlcl9zaXplKTtcbiAgaWYociA9PSAwKVxuICAgIGNhbWxfcmFpc2VfZW5kX29mX2ZpbGUoKTtcbiAgZWxzZSBpZiAociA8IGNhbWxfbWFyc2hhbF9oZWFkZXJfc2l6ZSlcbiAgICBjYW1sX2ZhaWx3aXRoKFwiaW5wdXRfdmFsdWU6IHRydW5jYXRlZCBvYmplY3RcIik7XG4gIHZhciBsZW4gPSBjYW1sX21hcnNoYWxfZGF0YV9zaXplIChjYW1sX2J5dGVzX29mX2FycmF5KGhlYWRlciksIDApO1xuICB2YXIgYnVmID0gbmV3IFVpbnQ4QXJyYXkobGVuICsgY2FtbF9tYXJzaGFsX2hlYWRlcl9zaXplKTtcbiAgYnVmLnNldChoZWFkZXIsMCk7XG4gIHZhciByID0gYmxvY2soYnVmLCBjYW1sX21hcnNoYWxfaGVhZGVyX3NpemUsIGxlbilcbiAgaWYociA8IGxlbilcbiAgICBjYW1sX2ZhaWx3aXRoKFwiaW5wdXRfdmFsdWU6IHRydW5jYXRlZCBvYmplY3QgXCIgKyByICsgXCIgIFwiICsgbGVuKTtcbiAgdmFyIG9mZnNldCA9IFswXTtcbiAgdmFyIHJlcyA9IGNhbWxfaW5wdXRfdmFsdWVfZnJvbV9ieXRlcyhjYW1sX2J5dGVzX29mX2FycmF5KGJ1ZiksIG9mZnNldCk7XG4gIGNoYW4ub2Zmc2V0ID0gY2hhbi5vZmZzZXQgKyBvZmZzZXRbMF07XG4gIHJldHVybiByZXM7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfaW5wdXRfdmFsdWVfdG9fb3V0c2lkZV9oZWFwXG4vL1JlcXVpcmVzOiBjYW1sX2lucHV0X3ZhbHVlXG5mdW5jdGlvbiBjYW1sX2lucHV0X3ZhbHVlX3RvX291dHNpZGVfaGVhcChjKSB7XG4gIHJldHVybiBjYW1sX2lucHV0X3ZhbHVlKGMpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21sX2lucHV0X2NoYXJcbi8vUmVxdWlyZXM6IGNhbWxfcmFpc2VfZW5kX29mX2ZpbGUsIGNhbWxfYXJyYXlfYm91bmRfZXJyb3Jcbi8vUmVxdWlyZXM6IGNhbWxfbWxfY2hhbm5lbF9nZXQsIGNhbWxfcmVmaWxsXG5mdW5jdGlvbiBjYW1sX21sX2lucHV0X2NoYXIgKGNoYW5pZCkge1xuICB2YXIgY2hhbiA9IGNhbWxfbWxfY2hhbm5lbF9nZXQoY2hhbmlkKTtcbiAgaWYoY2hhbi5idWZmZXJfY3VyciA+PSBjaGFuLmJ1ZmZlcl9tYXgpe1xuICAgIGNoYW4uYnVmZmVyX2N1cnIgPSAwO1xuICAgIGNoYW4uYnVmZmVyX21heCA9IDA7XG4gICAgY2FtbF9yZWZpbGwoY2hhbik7XG4gIH1cbiAgaWYgKGNoYW4uYnVmZmVyX2N1cnIgPj0gY2hhbi5idWZmZXJfbWF4KVxuICAgIGNhbWxfcmFpc2VfZW5kX29mX2ZpbGUoKTtcbiAgdmFyIHJlcyA9IGNoYW4uYnVmZmVyW2NoYW4uYnVmZmVyX2N1cnJdO1xuICBjaGFuLmJ1ZmZlcl9jdXJyKys7XG4gIHJldHVybiByZXM7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfaW5wdXRfaW50XG4vL1JlcXVpcmVzOiBjYW1sX3JhaXNlX2VuZF9vZl9maWxlXG4vL1JlcXVpcmVzOiBjYW1sX21sX2lucHV0X2NoYXIsIGNhbWxfbWxfY2hhbm5lbF9nZXRcbmZ1bmN0aW9uIGNhbWxfbWxfaW5wdXRfaW50IChjaGFuaWQpIHtcbiAgdmFyIGNoYW4gPSBjYW1sX21sX2NoYW5uZWxfZ2V0KGNoYW5pZCk7XG4gIHZhciByZXMgPSAwO1xuICBmb3IodmFyIGkgPSAwOyBpIDwgNDsgaSsrKXtcbiAgICByZXMgPSAocmVzIDw8IDgpICsgY2FtbF9tbF9pbnB1dF9jaGFyKGNoYW5pZCkgfCAwO1xuICB9XG4gIHJldHVybiByZXMgfCAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3NlZWtfaW5cbi8vUmVxdWlyZXM6IGNhbWxfcmFpc2Vfc3lzX2Vycm9yLCBjYW1sX21sX2NoYW5uZWxfZ2V0XG5mdW5jdGlvbiBjYW1sX3NlZWtfaW4oY2hhbmlkLCBwb3MpIHtcbiAgdmFyIGNoYW4gPSBjYW1sX21sX2NoYW5uZWxfZ2V0KGNoYW5pZCk7XG4gIGlmIChjaGFuLnJlZmlsbCAhPSBudWxsKSBjYW1sX3JhaXNlX3N5c19lcnJvcihcIklsbGVnYWwgc2Vla1wiKTtcbiAgaWYocG9zID49IGNoYW4ub2Zmc2V0IC0gY2hhbi5idWZmZXJfbWF4XG4gICAgICYmIHBvcyA8PSBjaGFuLm9mZnNldFxuICAgICAmJiBjaGFuLmZpbGUuZmxhZ3MuYmluYXJ5KSB7XG4gICAgY2hhbi5idWZmZXJfY3VyciA9IGNoYW4uYnVmZmVyX21heCAtIChjaGFuLm9mZnNldCAtIHBvcyk7XG4gIH0gZWxzZSB7XG4gICAgY2hhbi5vZmZzZXQgPSBwb3M7XG4gICAgY2hhbi5idWZmZXJfY3VyciA9IDA7XG4gICAgY2hhbi5idWZmZXJfbWF4ID0gMDtcbiAgfVxuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9tbF9zZWVrX2luXG4vL1JlcXVpcmVzOiBjYW1sX3NlZWtfaW5cbmZ1bmN0aW9uIGNhbWxfbWxfc2Vla19pbihjaGFuaWQscG9zKXtcbiAgcmV0dXJuIGNhbWxfc2Vla19pbihjaGFuaWQscG9zKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9tbF9zZWVrX2luXzY0XG4vL1JlcXVpcmVzOiBjYW1sX2ludDY0X3RvX2Zsb2F0LCBjYW1sX3NlZWtfaW5cbmZ1bmN0aW9uIGNhbWxfbWxfc2Vla19pbl82NChjaGFuaWQscG9zKXtcbiAgdmFyIHBvcyA9IGNhbWxfaW50NjRfdG9fZmxvYXQocG9zKTtcbiAgcmV0dXJuIGNhbWxfc2Vla19pbihjaGFuaWQsIHBvcyk7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfcG9zX2luXG4vL1JlcXVpcmVzOiBjYW1sX21sX2NoYW5uZWxfZ2V0XG5mdW5jdGlvbiBjYW1sX3Bvc19pbihjaGFuaWQpIHtcbiAgdmFyIGNoYW4gPSBjYW1sX21sX2NoYW5uZWxfZ2V0KGNoYW5pZCk7XG4gIHJldHVybiBjaGFuLm9mZnNldCAtIChjaGFuLmJ1ZmZlcl9tYXggLSBjaGFuLmJ1ZmZlcl9jdXJyKSB8IDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfcG9zX2luXG4vL1JlcXVpcmVzOiBjYW1sX3Bvc19pblxuZnVuY3Rpb24gY2FtbF9tbF9wb3NfaW4oY2hhbmlkKSB7XG4gIHJldHVybiBjYW1sX3Bvc19pbihjaGFuaWQpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21sX3Bvc19pbl82NFxuLy9SZXF1aXJlczogY2FtbF9pbnQ2NF9vZl9mbG9hdCwgY2FtbF9wb3NfaW5cbmZ1bmN0aW9uIGNhbWxfbWxfcG9zX2luXzY0KGNoYW5pZCkge1xuICByZXR1cm4gY2FtbF9pbnQ2NF9vZl9mbG9hdChjYW1sX3Bvc19pbihjaGFuaWQpKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9tbF9pbnB1dF9zY2FuX2xpbmVcbi8vUmVxdWlyZXM6IGNhbWxfYXJyYXlfYm91bmRfZXJyb3Jcbi8vUmVxdWlyZXM6IGNhbWxfbWxfY2hhbm5lbF9nZXQsIGNhbWxfcmVmaWxsXG5mdW5jdGlvbiBjYW1sX21sX2lucHV0X3NjYW5fbGluZShjaGFuaWQpe1xuICB2YXIgY2hhbiA9IGNhbWxfbWxfY2hhbm5lbF9nZXQoY2hhbmlkKTtcbiAgdmFyIHAgPSBjaGFuLmJ1ZmZlcl9jdXJyO1xuICBkbyB7XG4gICAgaWYocCA+PSBjaGFuLmJ1ZmZlcl9tYXgpIHtcbiAgICAgIGlmKGNoYW4uYnVmZmVyX2N1cnIgPiAwKSB7XG4gICAgICAgIGNoYW4uYnVmZmVyLnNldChjaGFuLmJ1ZmZlci5zdWJhcnJheShjaGFuLmJ1ZmZlcl9jdXJyKSwwKTtcbiAgICAgICAgcCAtPSBjaGFuLmJ1ZmZlcl9jdXJyO1xuICAgICAgICBjaGFuLmJ1ZmZlcl9tYXggLT0gY2hhbi5idWZmZXJfY3VycjtcbiAgICAgICAgY2hhbi5idWZmZXJfY3VyciA9IDA7XG4gICAgICB9XG4gICAgICBpZihjaGFuLmJ1ZmZlcl9tYXggPj0gY2hhbi5idWZmZXIubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiAtKGNoYW4uYnVmZmVyX21heCkgfCAwO1xuICAgICAgfVxuICAgICAgdmFyIHByZXZfbWF4ID0gY2hhbi5idWZmZXJfbWF4O1xuICAgICAgY2FtbF9yZWZpbGwgKGNoYW4pO1xuICAgICAgaWYocHJldl9tYXggPT0gY2hhbi5idWZmZXJfbWF4KSB7XG4gICAgICAgIHJldHVybiAtKGNoYW4uYnVmZmVyX21heCkgfCAwO1xuICAgICAgfVxuICAgIH1cbiAgfSB3aGlsZSAoY2hhbi5idWZmZXJbcCsrXSAhPSAxMCk7XG4gIHJldHVybiAocCAtIGNoYW4uYnVmZmVyX2N1cnIpIHwgMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9tbF9mbHVzaFxuLy9SZXF1aXJlczogY2FtbF9yYWlzZV9zeXNfZXJyb3IsIGNhbWxfbWxfY2hhbm5lbF9nZXRcbi8vUmVxdWlyZXM6IGNhbWxfc3ViYXJyYXlfdG9fanNieXRlc1xuZnVuY3Rpb24gY2FtbF9tbF9mbHVzaCAoY2hhbmlkKSB7XG4gIHZhciBjaGFuID0gY2FtbF9tbF9jaGFubmVsX2dldChjaGFuaWQpO1xuICBpZighIGNoYW4ub3BlbmVkKSBjYW1sX3JhaXNlX3N5c19lcnJvcihcIkNhbm5vdCBmbHVzaCBhIGNsb3NlZCBjaGFubmVsXCIpO1xuICBpZighY2hhbi5idWZmZXIgfHwgY2hhbi5idWZmZXJfY3VyciA9PSAwKSByZXR1cm4gMDtcbiAgaWYoY2hhbi5vdXRwdXQpIHtcbiAgICBjaGFuLm91dHB1dChjYW1sX3N1YmFycmF5X3RvX2pzYnl0ZXMoY2hhbi5idWZmZXIsIDAsIGNoYW4uYnVmZmVyX2N1cnIpKTtcbiAgfSBlbHNlIHtcbiAgICBjaGFuLmZpbGUud3JpdGUoY2hhbi5vZmZzZXQsIGNoYW4uYnVmZmVyLCAwLCBjaGFuLmJ1ZmZlcl9jdXJyKTtcbiAgfVxuICBjaGFuLm9mZnNldCArPSBjaGFuLmJ1ZmZlcl9jdXJyO1xuICBjaGFuLmJ1ZmZlcl9jdXJyID0gMDtcbiAgcmV0dXJuIDA7XG59XG5cbi8vb3V0cHV0IHRvIG91dF9jaGFubmVsXG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfb3V0cHV0X3RhXG4vL1JlcXVpcmVzOiBjYW1sX21sX2ZsdXNoLGNhbWxfbWxfYnl0ZXNfbGVuZ3RoXG4vL1JlcXVpcmVzOiBjYW1sX3JhaXNlX3N5c19lcnJvciwgY2FtbF9tbF9jaGFubmVsX2dldFxuZnVuY3Rpb24gY2FtbF9tbF9vdXRwdXRfdGEoY2hhbmlkLGJ1ZmZlcixvZmZzZXQsbGVuKSB7XG4gIHZhciBjaGFuID0gY2FtbF9tbF9jaGFubmVsX2dldChjaGFuaWQpO1xuICBpZighIGNoYW4ub3BlbmVkKSBjYW1sX3JhaXNlX3N5c19lcnJvcihcIkNhbm5vdCBvdXRwdXQgdG8gYSBjbG9zZWQgY2hhbm5lbFwiKTtcbiAgYnVmZmVyID0gYnVmZmVyLnN1YmFycmF5KG9mZnNldCwgb2Zmc2V0ICsgbGVuKTtcbiAgaWYoY2hhbi5idWZmZXJfY3VyciArIGJ1ZmZlci5sZW5ndGggPiBjaGFuLmJ1ZmZlci5sZW5ndGgpIHtcbiAgICB2YXIgYiA9IG5ldyBVaW50OEFycmF5KGNoYW4uYnVmZmVyX2N1cnIgKyBidWZmZXIubGVuZ3RoKTtcbiAgICBiLnNldChjaGFuLmJ1ZmZlcik7XG4gICAgY2hhbi5idWZmZXIgPSBiXG4gIH1cbiAgc3dpdGNoKGNoYW4uYnVmZmVyZWQpe1xuICBjYXNlIDA6IC8vIFVuYnVmZmVyZWRcbiAgICBjaGFuLmJ1ZmZlci5zZXQoYnVmZmVyLCBjaGFuLmJ1ZmZlcl9jdXJyKTtcbiAgICBjaGFuLmJ1ZmZlcl9jdXJyICs9IGJ1ZmZlci5sZW5ndGg7XG4gICAgY2FtbF9tbF9mbHVzaCAoY2hhbmlkKTtcbiAgICBicmVha1xuICBjYXNlIDE6IC8vIEJ1ZmZlcmVkICh0aGUgZGVmYXVsdClcbiAgICBjaGFuLmJ1ZmZlci5zZXQoYnVmZmVyLCBjaGFuLmJ1ZmZlcl9jdXJyKTtcbiAgICBjaGFuLmJ1ZmZlcl9jdXJyICs9IGJ1ZmZlci5sZW5ndGg7XG4gICAgaWYoY2hhbi5idWZmZXJfY3VyciA+PSBjaGFuLmJ1ZmZlci5sZW5ndGgpXG4gICAgICBjYW1sX21sX2ZsdXNoIChjaGFuaWQpO1xuICAgIGJyZWFrO1xuICBjYXNlIDI6IC8vIEJ1ZmZlcmVkIChvbmx5IGZvciBzdGRvdXQgYW5kIHN0ZGVycilcbiAgICB2YXIgaWQgPSBidWZmZXIubGFzdEluZGV4T2YoMTApXG4gICAgaWYoaWQgPCAwKSB7XG4gICAgICBjaGFuLmJ1ZmZlci5zZXQoYnVmZmVyLCBjaGFuLmJ1ZmZlcl9jdXJyKTtcbiAgICAgIGNoYW4uYnVmZmVyX2N1cnIgKz0gYnVmZmVyLmxlbmd0aDtcbiAgICAgIGlmKGNoYW4uYnVmZmVyX2N1cnIgPj0gY2hhbi5idWZmZXIubGVuZ3RoKVxuICAgICAgICBjYW1sX21sX2ZsdXNoIChjaGFuaWQpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGNoYW4uYnVmZmVyLnNldChidWZmZXIuc3ViYXJyYXkoMCwgaWQgKyAxKSwgY2hhbi5idWZmZXJfY3Vycik7XG4gICAgICBjaGFuLmJ1ZmZlcl9jdXJyICs9IGlkICsgMTtcbiAgICAgIGNhbWxfbWxfZmx1c2ggKGNoYW5pZCk7XG4gICAgICBjaGFuLmJ1ZmZlci5zZXQoYnVmZmVyLnN1YmFycmF5KGlkICsgMSksIGNoYW4uYnVmZmVyX2N1cnIpO1xuICAgICAgY2hhbi5idWZmZXJfY3VyciArPSBidWZmZXIubGVuZ3RoIC0gaWQgLSAxO1xuICAgIH1cbiAgICBicmVhaztcbiAgfVxuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9tbF9vdXRwdXRfYnl0ZXNcbi8vUmVxdWlyZXM6IGNhbWxfdWludDhfYXJyYXlfb2ZfYnl0ZXMsIGNhbWxfbWxfb3V0cHV0X3RhXG5mdW5jdGlvbiBjYW1sX21sX291dHB1dF9ieXRlcyhjaGFuaWQsYnVmZmVyLG9mZnNldCxsZW4pIHtcbiAgdmFyIGJ1ZmZlciA9IGNhbWxfdWludDhfYXJyYXlfb2ZfYnl0ZXMoYnVmZmVyKTtcbiAgcmV0dXJuIGNhbWxfbWxfb3V0cHV0X3RhKGNoYW5pZCxidWZmZXIsb2Zmc2V0LGxlbik7XG59XG5cblxuLy9Qcm92aWRlczogY2FtbF9tbF9vdXRwdXRfYmlnYXJyYXlcbi8vUmVxdWlyZXM6IGNhbWxfYmFfdG9fdHlwZWRfYXJyYXksIGNhbWxfbWxfb3V0cHV0X3RhXG5mdW5jdGlvbiBjYW1sX21sX291dHB1dF9iaWdhcnJheShjaGFuaWQsYnVmZmVyLG9mZnNldCxsZW4pIHtcbiAgdmFyIGJ1ZmZlciA9IGNhbWxfYmFfdG9fdHlwZWRfYXJyYXkoYnVmZmVyKTtcbiAgcmV0dXJuIGNhbWxfbWxfb3V0cHV0X3RhKGNoYW5pZCxidWZmZXIsb2Zmc2V0LGxlbik7XG59XG5cblxuXG4vL1Byb3ZpZGVzOiBjYW1sX21sX291dHB1dFxuLy9SZXF1aXJlczogY2FtbF9tbF9vdXRwdXRfYnl0ZXMsIGNhbWxfYnl0ZXNfb2Zfc3RyaW5nXG5mdW5jdGlvbiBjYW1sX21sX291dHB1dChjaGFuaWQsYnVmZmVyLG9mZnNldCxsZW4pe1xuICByZXR1cm4gY2FtbF9tbF9vdXRwdXRfYnl0ZXMoY2hhbmlkLGNhbWxfYnl0ZXNfb2Zfc3RyaW5nKGJ1ZmZlciksb2Zmc2V0LGxlbik7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfb3V0cHV0X2NoYXJcbi8vUmVxdWlyZXM6IGNhbWxfbWxfb3V0cHV0XG4vL1JlcXVpcmVzOiBjYW1sX3N0cmluZ19vZl9qc2J5dGVzXG5mdW5jdGlvbiBjYW1sX21sX291dHB1dF9jaGFyIChjaGFuaWQsYykge1xuICB2YXIgcyA9IGNhbWxfc3RyaW5nX29mX2pzYnl0ZXMoU3RyaW5nLmZyb21DaGFyQ29kZShjKSk7XG4gIGNhbWxfbWxfb3V0cHV0KGNoYW5pZCxzLDAsMSk7XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX291dHB1dF92YWx1ZVxuLy9SZXF1aXJlczogY2FtbF9vdXRwdXRfdmFsdWVfdG9fc3RyaW5nLCBjYW1sX21sX291dHB1dCxjYW1sX21sX3N0cmluZ19sZW5ndGhcbmZ1bmN0aW9uIGNhbWxfb3V0cHV0X3ZhbHVlIChjaGFuaWQsdixmbGFncykge1xuICB2YXIgcyA9IGNhbWxfb3V0cHV0X3ZhbHVlX3RvX3N0cmluZyh2LCBmbGFncyk7XG4gIGNhbWxfbWxfb3V0cHV0KGNoYW5pZCxzLDAsY2FtbF9tbF9zdHJpbmdfbGVuZ3RoKHMpKTtcbiAgcmV0dXJuIDA7XG59XG5cblxuLy9Qcm92aWRlczogY2FtbF9zZWVrX291dFxuLy9SZXF1aXJlczogY2FtbF9tbF9jaGFubmVsX2dldCwgY2FtbF9tbF9mbHVzaFxuZnVuY3Rpb24gY2FtbF9zZWVrX291dChjaGFuaWQsIHBvcyl7XG4gIGNhbWxfbWxfZmx1c2goY2hhbmlkKTtcbiAgdmFyIGNoYW4gPSBjYW1sX21sX2NoYW5uZWxfZ2V0KGNoYW5pZCk7XG4gIGNoYW4ub2Zmc2V0ID0gcG9zO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9tbF9zZWVrX291dFxuLy9SZXF1aXJlczogY2FtbF9zZWVrX291dFxuZnVuY3Rpb24gY2FtbF9tbF9zZWVrX291dChjaGFuaWQscG9zKXtcbiAgcmV0dXJuIGNhbWxfc2Vla19vdXQoY2hhbmlkLCBwb3MpO1xufVxuLy9Qcm92aWRlczogY2FtbF9tbF9zZWVrX291dF82NFxuLy9SZXF1aXJlczogY2FtbF9pbnQ2NF90b19mbG9hdCwgY2FtbF9zZWVrX291dFxuZnVuY3Rpb24gY2FtbF9tbF9zZWVrX291dF82NChjaGFuaWQscG9zKXtcbiAgdmFyIHBvcyA9IGNhbWxfaW50NjRfdG9fZmxvYXQocG9zKTtcbiAgcmV0dXJuIGNhbWxfc2Vla19vdXQoY2hhbmlkLCBwb3MpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3Bvc19vdXRcbi8vUmVxdWlyZXM6IGNhbWxfbWxfY2hhbm5lbF9nZXQsIGNhbWxfbWxfZmx1c2hcbmZ1bmN0aW9uIGNhbWxfcG9zX291dChjaGFuaWQpIHtcbiAgdmFyIGNoYW4gPSBjYW1sX21sX2NoYW5uZWxfZ2V0KGNoYW5pZCk7XG4gIHJldHVybiBjaGFuLm9mZnNldCArIGNoYW4uYnVmZmVyX2N1cnJcbn1cblxuLy9Qcm92aWRlczogY2FtbF9tbF9wb3Nfb3V0XG4vL1JlcXVpcmVzOiBjYW1sX3Bvc19vdXRcbmZ1bmN0aW9uIGNhbWxfbWxfcG9zX291dChjaGFuaWQpIHtcbiAgcmV0dXJuIGNhbWxfcG9zX291dChjaGFuaWQpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21sX3Bvc19vdXRfNjRcbi8vUmVxdWlyZXM6IGNhbWxfaW50NjRfb2ZfZmxvYXQsIGNhbWxfcG9zX291dFxuZnVuY3Rpb24gY2FtbF9tbF9wb3Nfb3V0XzY0KGNoYW5pZCkge1xuICByZXR1cm4gY2FtbF9pbnQ2NF9vZl9mbG9hdCAoY2FtbF9wb3Nfb3V0KGNoYW5pZCkpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21sX291dHB1dF9pbnRcbi8vUmVxdWlyZXM6IGNhbWxfbWxfb3V0cHV0XG4vL1JlcXVpcmVzOiBjYW1sX3N0cmluZ19vZl9hcnJheVxuZnVuY3Rpb24gY2FtbF9tbF9vdXRwdXRfaW50IChjaGFuaWQsaSkge1xuICB2YXIgYXJyID0gWyhpPj4yNCkgJiAweEZGLChpPj4xNikgJiAweEZGLChpPj44KSAmIDB4RkYsaSAmIDB4RkYgXTtcbiAgdmFyIHMgPSBjYW1sX3N0cmluZ19vZl9hcnJheShhcnIpO1xuICBjYW1sX21sX291dHB1dChjaGFuaWQscywwLDQpO1xuICByZXR1cm4gMFxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21sX2lzX2J1ZmZlcmVkXG4vL1JlcXVpcmVzOiBjYW1sX21sX2NoYW5uZWxfZ2V0XG5mdW5jdGlvbiBjYW1sX21sX2lzX2J1ZmZlcmVkKGNoYW5pZCkge1xuICByZXR1cm4gY2FtbF9tbF9jaGFubmVsX2dldChjaGFuaWQpLmJ1ZmZlcmVkID8gMSA6IDBcbn1cblxuLy9Qcm92aWRlczogY2FtbF9tbF9zZXRfYnVmZmVyZWRcbi8vUmVxdWlyZXM6IGNhbWxfbWxfY2hhbm5lbF9nZXQsIGNhbWxfbWxfZmx1c2hcbmZ1bmN0aW9uIGNhbWxfbWxfc2V0X2J1ZmZlcmVkKGNoYW5pZCx2KSB7XG4gIGNhbWxfbWxfY2hhbm5lbF9nZXQoY2hhbmlkKS5idWZmZXJlZCA9IHY7XG4gIGlmKCF2KSBjYW1sX21sX2ZsdXNoKGNoYW5pZCk7XG4gIHJldHVybiAwXG59XG4iLCJcbi8vUHJvdmlkZXM6IGNhbWxfY3VzdG9tX2V2ZW50X2luZGV4XG52YXIgY2FtbF9jdXN0b21fZXZlbnRfaW5kZXggPSAwO1xuXG4vL1Byb3ZpZGVzOiBjYW1sX3J1bnRpbWVfZXZlbnRzX3VzZXJfcmVnaXN0ZXJcbi8vUmVxdWlyZXM6IGNhbWxfY3VzdG9tX2V2ZW50X2luZGV4XG5mdW5jdGlvbiBjYW1sX3J1bnRpbWVfZXZlbnRzX3VzZXJfcmVnaXN0ZXIoZXZlbnRfbmFtZSwgZXZlbnRfdGFnLCBldmVudF90eXBlKSB7XG4gIGNhbWxfY3VzdG9tX2V2ZW50X2luZGV4ICs9IDE7XG4gIHJldHVybiBbMCwgY2FtbF9jdXN0b21fZXZlbnRfaW5kZXgsIGV2ZW50X25hbWUsIGV2ZW50X3R5cGUsIGV2ZW50X3RhZ107XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfcnVudGltZV9ldmVudHNfdXNlcl93cml0ZVxuZnVuY3Rpb24gY2FtbF9ydW50aW1lX2V2ZW50c191c2VyX3dyaXRlKGV2ZW50LCBldmVudF9jb250ZW50KSB7XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3J1bnRpbWVfZXZlbnRzX3VzZXJfcmVzb2x2ZVxuZnVuY3Rpb24gY2FtbF9ydW50aW1lX2V2ZW50c191c2VyX3Jlc29sdmUoKSB7XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21sX3J1bnRpbWVfZXZlbnRzX3N0YXJ0XG4vL0FsaWFzOiBjYW1sX3J1bnRpbWVfZXZlbnRzX3N0YXJ0XG5mdW5jdGlvbiBjYW1sX21sX3J1bnRpbWVfZXZlbnRzX3N0YXJ0KCkge1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9tbF9ydW50aW1lX2V2ZW50c19wYXVzZVxuLy9BbGlhczogY2FtbF9ydW50aW1lX2V2ZW50c19wYXVzZVxuZnVuY3Rpb24gY2FtbF9tbF9ydW50aW1lX2V2ZW50c19wYXVzZSgpIHtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfcnVudGltZV9ldmVudHNfYXJlX2FjdGl2ZVxuLy9WZXJzaW9uOiA+PSA1LjJcbmZ1bmN0aW9uIGNhbWxfbWxfcnVudGltZV9ldmVudHNfYXJlX2FjdGl2ZSgpIHtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfbWxfcnVudGltZV9ldmVudHNfcmVzdW1lXG4vL0FsaWFzOiBjYW1sX3J1bnRpbWVfZXZlbnRzX3Jlc3VtZVxuZnVuY3Rpb24gY2FtbF9tbF9ydW50aW1lX2V2ZW50c19yZXN1bWUoKSB7XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3J1bnRpbWVfZXZlbnRzX2NyZWF0ZV9jdXJzb3JcbmZ1bmN0aW9uIGNhbWxfcnVudGltZV9ldmVudHNfY3JlYXRlX2N1cnNvcih0YXJnZXQpIHtcbiAgcmV0dXJuIHt9O1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX3J1bnRpbWVfZXZlbnRzX2ZyZWVfY3Vyc29yXG5mdW5jdGlvbiBjYW1sX3J1bnRpbWVfZXZlbnRzX2ZyZWVfY3Vyc29yKGN1cnNvcikge1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9ydW50aW1lX2V2ZW50c19yZWFkX3BvbGxcbmZ1bmN0aW9uIGNhbWxfcnVudGltZV9ldmVudHNfcmVhZF9wb2xsKGN1cnNvciwgY2FsbGJhY2tzLCBudW0pIHtcbiAgcmV0dXJuIDA7XG59XG4iLCJcbi8vUHJvdmlkZXM6IHpzdGRfZGVjb21wcmVzc1xuLy9WZXJzaW9uOiA+PSA1LjFcbnZhciB6c3RkX2RlY29tcHJlc3MgPSAoZnVuY3Rpb24gKCkge1xuXCJ1c2Ugc3RyaWN0XCI7XG4vLyBhbGlhc2VzIGZvciBzaG9ydGVyIGNvbXByZXNzZWQgY29kZSAobW9zdCBtaW5pZmVycyBkb24ndCBkbyB0aGlzKVxudmFyIGFiID0gQXJyYXlCdWZmZXIsIHU4ID0gVWludDhBcnJheSwgdTE2ID0gVWludDE2QXJyYXksIGkxNiA9IEludDE2QXJyYXksIHUzMiA9IFVpbnQzMkFycmF5LCBpMzIgPSBJbnQzMkFycmF5O1xudmFyIHNsYyA9IGZ1bmN0aW9uICh2LCBzLCBlKSB7XG4gICAgaWYgKHU4LnByb3RvdHlwZS5zbGljZSlcbiAgICAgICAgcmV0dXJuIHU4LnByb3RvdHlwZS5zbGljZS5jYWxsKHYsIHMsIGUpO1xuICAgIGlmIChzID09IG51bGwgfHwgcyA8IDApXG4gICAgICAgIHMgPSAwO1xuICAgIGlmIChlID09IG51bGwgfHwgZSA+IHYubGVuZ3RoKVxuICAgICAgICBlID0gdi5sZW5ndGg7XG4gICAgdmFyIG4gPSBuZXcgdTgoZSAtIHMpO1xuICAgIG4uc2V0KHYuc3ViYXJyYXkocywgZSkpO1xuICAgIHJldHVybiBuO1xufTtcbnZhciBmaWxsID0gZnVuY3Rpb24gKHYsIG4sIHMsIGUpIHtcbiAgICBpZiAodTgucHJvdG90eXBlLmZpbGwpXG4gICAgICAgIHJldHVybiB1OC5wcm90b3R5cGUuZmlsbC5jYWxsKHYsIG4sIHMsIGUpO1xuICAgIGlmIChzID09IG51bGwgfHwgcyA8IDApXG4gICAgICAgIHMgPSAwO1xuICAgIGlmIChlID09IG51bGwgfHwgZSA+IHYubGVuZ3RoKVxuICAgICAgICBlID0gdi5sZW5ndGg7XG4gICAgZm9yICg7IHMgPCBlOyArK3MpXG4gICAgICAgIHZbc10gPSBuO1xuICAgIHJldHVybiB2O1xufTtcbnZhciBjcHcgPSBmdW5jdGlvbiAodiwgdCwgcywgZSkge1xuICAgIGlmICh1OC5wcm90b3R5cGUuY29weVdpdGhpbilcbiAgICAgICAgcmV0dXJuIHU4LnByb3RvdHlwZS5jb3B5V2l0aGluLmNhbGwodiwgdCwgcywgZSk7XG4gICAgaWYgKHMgPT0gbnVsbCB8fCBzIDwgMClcbiAgICAgICAgcyA9IDA7XG4gICAgaWYgKGUgPT0gbnVsbCB8fCBlID4gdi5sZW5ndGgpXG4gICAgICAgIGUgPSB2Lmxlbmd0aDtcbiAgICB3aGlsZSAocyA8IGUpIHtcbiAgICAgICAgdlt0KytdID0gdltzKytdO1xuICAgIH1cbn07XG4vKipcbiAqIENvZGVzIGZvciBlcnJvcnMgZ2VuZXJhdGVkIHdpdGhpbiB0aGlzIGxpYnJhcnlcbiAqL1xuLy8gZXJyb3IgY29kZXNcbnZhciBlYyA9IFtcbiAgICAnaW52YWxpZCB6c3RkIGRhdGEnLFxuICAgICd3aW5kb3cgc2l6ZSB0b28gbGFyZ2UgKD4yMDQ2TUIpJyxcbiAgICAnaW52YWxpZCBibG9jayB0eXBlJyxcbiAgICAnRlNFIGFjY3VyYWN5IHRvbyBoaWdoJyxcbiAgICAnbWF0Y2ggZGlzdGFuY2UgdG9vIGZhciBiYWNrJyxcbiAgICAndW5leHBlY3RlZCBFT0YnXG5dO1xuO1xudmFyIGVyciA9IGZ1bmN0aW9uIChpbmQsIG1zZywgbnQpIHtcbiAgICB2YXIgZSA9IG5ldyBFcnJvcihtc2cgfHwgZWNbaW5kXSk7XG4gICAgZS5jb2RlID0gaW5kO1xuICAgIGlmICghbnQpXG4gICAgICAgIHRocm93IGU7XG4gICAgcmV0dXJuIGU7XG59O1xudmFyIHJiID0gZnVuY3Rpb24gKGQsIGIsIG4pIHtcbiAgICB2YXIgaSA9IDAsIG8gPSAwO1xuICAgIGZvciAoOyBpIDwgbjsgKytpKVxuICAgICAgICBvIHw9IGRbYisrXSA8PCAoaSA8PCAzKTtcbiAgICByZXR1cm4gbztcbn07XG52YXIgYjQgPSBmdW5jdGlvbiAoZCwgYikgeyByZXR1cm4gKGRbYl0gfCAoZFtiICsgMV0gPDwgOCkgfCAoZFtiICsgMl0gPDwgMTYpIHwgKGRbYiArIDNdIDw8IDI0KSkgPj4+IDA7IH07XG4vLyByZWFkIFpzdGFuZGFyZCBmcmFtZSBoZWFkZXJcbnZhciByemZoID0gZnVuY3Rpb24gKGRhdCwgdykge1xuICAgIHZhciBuMyA9IGRhdFswXSB8IChkYXRbMV0gPDwgOCkgfCAoZGF0WzJdIDw8IDE2KTtcbiAgICBpZiAobjMgPT0gMHgyRkI1MjggJiYgZGF0WzNdID09IDI1Mykge1xuICAgICAgICAvLyBac3RhbmRhcmRcbiAgICAgICAgdmFyIGZsZyA9IGRhdFs0XTtcbiAgICAgICAgLy8gICAgc2luZ2xlIHNlZ21lbnQgICAgICAgY2hlY2tzdW0gICAgICAgICAgICAgZGljdCBmbGFnICAgICBmcmFtZSBjb250ZW50IGZsYWdcbiAgICAgICAgdmFyIHNzID0gKGZsZyA+PiA1KSAmIDEsIGNjID0gKGZsZyA+PiAyKSAmIDEsIGRmID0gZmxnICYgMywgZmNmID0gZmxnID4+IDY7XG4gICAgICAgIGlmIChmbGcgJiA4KVxuICAgICAgICAgICAgZXJyKDApO1xuICAgICAgICAvLyBieXRlXG4gICAgICAgIHZhciBidCA9IDYgLSBzcztcbiAgICAgICAgLy8gZGljdCBieXRlc1xuICAgICAgICB2YXIgZGIgPSBkZiA9PSAzID8gNCA6IGRmO1xuICAgICAgICAvLyBkaWN0aW9uYXJ5IGlkXG4gICAgICAgIHZhciBkaSA9IHJiKGRhdCwgYnQsIGRiKTtcbiAgICAgICAgYnQgKz0gZGI7XG4gICAgICAgIC8vIGZyYW1lIHNpemUgYnl0ZXNcbiAgICAgICAgdmFyIGZzYiA9IGZjZiA/ICgxIDw8IGZjZikgOiBzcztcbiAgICAgICAgLy8gZnJhbWUgc291cmNlIHNpemVcbiAgICAgICAgdmFyIGZzcyA9IHJiKGRhdCwgYnQsIGZzYikgKyAoKGZjZiA9PSAxKSAmJiAyNTYpO1xuICAgICAgICAvLyB3aW5kb3cgc2l6ZVxuICAgICAgICB2YXIgd3MgPSBmc3M7XG4gICAgICAgIGlmICghc3MpIHtcbiAgICAgICAgICAgIC8vIHdpbmRvdyBkZXNjcmlwdG9yXG4gICAgICAgICAgICB2YXIgd2IgPSAxIDw8ICgxMCArIChkYXRbNV0gPj4gMykpO1xuICAgICAgICAgICAgd3MgPSB3YiArICh3YiA+PiAzKSAqIChkYXRbNV0gJiA3KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAod3MgPiAyMTQ1Mzg2NDk2KVxuICAgICAgICAgICAgZXJyKDEpO1xuICAgICAgICB2YXIgYnVmID0gbmV3IHU4KCh3ID09IDEgPyAoZnNzIHx8IHdzKSA6IHcgPyAwIDogd3MpICsgMTIpO1xuICAgICAgICBidWZbMF0gPSAxLCBidWZbNF0gPSA0LCBidWZbOF0gPSA4O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYjogYnQgKyBmc2IsXG4gICAgICAgICAgICB5OiAwLFxuICAgICAgICAgICAgbDogMCxcbiAgICAgICAgICAgIGQ6IGRpLFxuICAgICAgICAgICAgdzogKHcgJiYgdyAhPSAxKSA/IHcgOiBidWYuc3ViYXJyYXkoMTIpLFxuICAgICAgICAgICAgZTogd3MsXG4gICAgICAgICAgICBvOiBuZXcgaTMyKGJ1Zi5idWZmZXIsIDAsIDMpLFxuICAgICAgICAgICAgdTogZnNzLFxuICAgICAgICAgICAgYzogY2MsXG4gICAgICAgICAgICBtOiBNYXRoLm1pbigxMzEwNzIsIHdzKVxuICAgICAgICB9O1xuICAgIH1cbiAgICBlbHNlIGlmICgoKG4zID4+IDQpIHwgKGRhdFszXSA8PCAyMCkpID09IDB4MTg0RDJBNSkge1xuICAgICAgICAvLyBza2lwcGFibGVcbiAgICAgICAgcmV0dXJuIGI0KGRhdCwgNCkgKyA4O1xuICAgIH1cbiAgICBlcnIoMCk7XG59O1xuLy8gbW9zdCBzaWduaWZpY2FudCBiaXQgZm9yIG5vbnplcm9cbnZhciBtc2IgPSBmdW5jdGlvbiAodmFsKSB7XG4gICAgdmFyIGJpdHMgPSAwO1xuICAgIGZvciAoOyAoMSA8PCBiaXRzKSA8PSB2YWw7ICsrYml0cylcbiAgICAgICAgO1xuICAgIHJldHVybiBiaXRzIC0gMTtcbn07XG4vLyByZWFkIGZpbml0ZSBzdGF0ZSBlbnRyb3B5XG52YXIgcmZzZSA9IGZ1bmN0aW9uIChkYXQsIGJ0LCBtYWwpIHtcbiAgICAvLyB0YWJsZSBwb3NcbiAgICB2YXIgdHBvcyA9IChidCA8PCAzKSArIDQ7XG4gICAgLy8gYWNjdXJhY3kgbG9nXG4gICAgdmFyIGFsID0gKGRhdFtidF0gJiAxNSkgKyA1O1xuICAgIGlmIChhbCA+IG1hbClcbiAgICAgICAgZXJyKDMpO1xuICAgIC8vIHNpemVcbiAgICB2YXIgc3ogPSAxIDw8IGFsO1xuICAgIC8vIHByb2JhYmlsaXRpZXMgc3ltYm9scyAgcmVwZWF0ICAgaW5kZXggICBoaWdoIHRocmVzaG9sZFxuICAgIHZhciBwcm9icyA9IHN6LCBzeW0gPSAtMSwgcmUgPSAtMSwgaSA9IC0xLCBodCA9IHN6O1xuICAgIC8vIG9wdGltaXphdGlvbjogc2luZ2xlIGFsbG9jYXRpb24gaXMgbXVjaCBmYXN0ZXJcbiAgICB2YXIgYnVmID0gbmV3IGFiKDUxMiArIChzeiA8PCAyKSk7XG4gICAgdmFyIGZyZXEgPSBuZXcgaTE2KGJ1ZiwgMCwgMjU2KTtcbiAgICAvLyBzYW1lIHZpZXcgYXMgZnJlcVxuICAgIHZhciBkc3RhdGUgPSBuZXcgdTE2KGJ1ZiwgMCwgMjU2KTtcbiAgICB2YXIgbnN0YXRlID0gbmV3IHUxNihidWYsIDUxMiwgc3opO1xuICAgIHZhciBiYjEgPSA1MTIgKyAoc3ogPDwgMSk7XG4gICAgdmFyIHN5bXMgPSBuZXcgdTgoYnVmLCBiYjEsIHN6KTtcbiAgICB2YXIgbmJpdHMgPSBuZXcgdTgoYnVmLCBiYjEgKyBzeik7XG4gICAgd2hpbGUgKHN5bSA8IDI1NSAmJiBwcm9icyA+IDApIHtcbiAgICAgICAgdmFyIGJpdHMgPSBtc2IocHJvYnMgKyAxKTtcbiAgICAgICAgdmFyIGNidCA9IHRwb3MgPj4gMztcbiAgICAgICAgLy8gbWFza1xuICAgICAgICB2YXIgbXNrID0gKDEgPDwgKGJpdHMgKyAxKSkgLSAxO1xuICAgICAgICB2YXIgdmFsID0gKChkYXRbY2J0XSB8IChkYXRbY2J0ICsgMV0gPDwgOCkgfCAoZGF0W2NidCArIDJdIDw8IDE2KSkgPj4gKHRwb3MgJiA3KSkgJiBtc2s7XG4gICAgICAgIC8vIG1hc2sgKDEgZmV3ZXIgYml0KVxuICAgICAgICB2YXIgbXNrMWZiID0gKDEgPDwgYml0cykgLSAxO1xuICAgICAgICAvLyBtYXggc21hbGwgdmFsdWVcbiAgICAgICAgdmFyIG1zdiA9IG1zayAtIHByb2JzIC0gMTtcbiAgICAgICAgLy8gc21hbGwgdmFsdWVcbiAgICAgICAgdmFyIHN2YWwgPSB2YWwgJiBtc2sxZmI7XG4gICAgICAgIGlmIChzdmFsIDwgbXN2KVxuICAgICAgICAgICAgdHBvcyArPSBiaXRzLCB2YWwgPSBzdmFsO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRwb3MgKz0gYml0cyArIDE7XG4gICAgICAgICAgICBpZiAodmFsID4gbXNrMWZiKVxuICAgICAgICAgICAgICAgIHZhbCAtPSBtc3Y7XG4gICAgICAgIH1cbiAgICAgICAgZnJlcVsrK3N5bV0gPSAtLXZhbDtcbiAgICAgICAgaWYgKHZhbCA9PSAtMSkge1xuICAgICAgICAgICAgcHJvYnMgKz0gdmFsO1xuICAgICAgICAgICAgc3ltc1stLWh0XSA9IHN5bTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlXG4gICAgICAgICAgICBwcm9icyAtPSB2YWw7XG4gICAgICAgIGlmICghdmFsKSB7XG4gICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgLy8gcmVwZWF0IGJ5dGVcbiAgICAgICAgICAgICAgICB2YXIgcmJ0ID0gdHBvcyA+PiAzO1xuICAgICAgICAgICAgICAgIHJlID0gKChkYXRbcmJ0XSB8IChkYXRbcmJ0ICsgMV0gPDwgOCkpID4+ICh0cG9zICYgNykpICYgMztcbiAgICAgICAgICAgICAgICB0cG9zICs9IDI7XG4gICAgICAgICAgICAgICAgc3ltICs9IHJlO1xuICAgICAgICAgICAgfSB3aGlsZSAocmUgPT0gMyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKHN5bSA+IDI1NSB8fCBwcm9icylcbiAgICAgICAgZXJyKDApO1xuICAgIHZhciBzeW1wb3MgPSAwO1xuICAgIC8vIHN5bSBzdGVwIChjb3ByaW1lIHdpdGggc3ogLSBmb3JtdWxhIGZyb20genN0ZCBzb3VyY2UpXG4gICAgdmFyIHNzdGVwID0gKHN6ID4+IDEpICsgKHN6ID4+IDMpICsgMztcbiAgICAvLyBzeW0gbWFza1xuICAgIHZhciBzbWFzayA9IHN6IC0gMTtcbiAgICBmb3IgKHZhciBzID0gMDsgcyA8PSBzeW07ICsrcykge1xuICAgICAgICB2YXIgc2YgPSBmcmVxW3NdO1xuICAgICAgICBpZiAoc2YgPCAxKSB7XG4gICAgICAgICAgICBkc3RhdGVbc10gPSAtc2Y7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBUaGlzIGlzIHNwbGl0IGludG8gdHdvIGxvb3BzIGluIHpzdGQgdG8gYXZvaWQgYnJhbmNoaW5nLCBidXQgYXMgSlMgaXMgaGlnaGVyLWxldmVsIHRoYXQgaXMgdW5uZWNlc3NhcnlcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IHNmOyArK2kpIHtcbiAgICAgICAgICAgIHN5bXNbc3ltcG9zXSA9IHM7XG4gICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgc3ltcG9zID0gKHN5bXBvcyArIHNzdGVwKSAmIHNtYXNrO1xuICAgICAgICAgICAgfSB3aGlsZSAoc3ltcG9zID49IGh0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBBZnRlciBzcHJlYWRpbmcgc3ltYm9scywgc2hvdWxkIGJlIHplcm8gYWdhaW5cbiAgICBpZiAoc3ltcG9zKVxuICAgICAgICBlcnIoMCk7XG4gICAgZm9yIChpID0gMDsgaSA8IHN6OyArK2kpIHtcbiAgICAgICAgLy8gbmV4dCBzdGF0ZVxuICAgICAgICB2YXIgbnMgPSBkc3RhdGVbc3ltc1tpXV0rKztcbiAgICAgICAgLy8gbnVtIGJpdHNcbiAgICAgICAgdmFyIG5iID0gbmJpdHNbaV0gPSBhbCAtIG1zYihucyk7XG4gICAgICAgIG5zdGF0ZVtpXSA9IChucyA8PCBuYikgLSBzejtcbiAgICB9XG4gICAgcmV0dXJuIFsodHBvcyArIDcpID4+IDMsIHtcbiAgICAgICAgICAgIGI6IGFsLFxuICAgICAgICAgICAgczogc3ltcyxcbiAgICAgICAgICAgIG46IG5iaXRzLFxuICAgICAgICAgICAgdDogbnN0YXRlXG4gICAgICAgIH1dO1xufTtcbi8vIHJlYWQgaHVmZm1hblxudmFyIHJodSA9IGZ1bmN0aW9uIChkYXQsIGJ0KSB7XG4gICAgLy8gIGluZGV4ICB3ZWlnaHQgY291bnRcbiAgICB2YXIgaSA9IDAsIHdjID0gLTE7XG4gICAgLy8gICAgYnVmZmVyICAgICAgICAgICAgIGhlYWRlciBieXRlXG4gICAgdmFyIGJ1ZiA9IG5ldyB1OCgyOTIpLCBoYiA9IGRhdFtidF07XG4gICAgLy8gaHVmZm1hbiB3ZWlnaHRzXG4gICAgdmFyIGh3ID0gYnVmLnN1YmFycmF5KDAsIDI1Nik7XG4gICAgLy8gcmFuayBjb3VudFxuICAgIHZhciByYyA9IGJ1Zi5zdWJhcnJheSgyNTYsIDI2OCk7XG4gICAgLy8gcmFuayBpbmRleFxuICAgIHZhciByaSA9IG5ldyB1MTYoYnVmLmJ1ZmZlciwgMjY4KTtcbiAgICAvLyBOT1RFOiBhdCB0aGlzIHBvaW50IGJ0IGlzIDEgbGVzcyB0aGFuIGV4cGVjdGVkXG4gICAgaWYgKGhiIDwgMTI4KSB7XG4gICAgICAgIC8vIGVuZCBieXRlLCBmc2UgZGVjb2RlIHRhYmxlXG4gICAgICAgIHZhciBfYSA9IHJmc2UoZGF0LCBidCArIDEsIDYpLCBlYnQgPSBfYVswXSwgZmR0ID0gX2FbMV07XG4gICAgICAgIGJ0ICs9IGhiO1xuICAgICAgICB2YXIgZXBvcyA9IGVidCA8PCAzO1xuICAgICAgICAvLyBsYXN0IGJ5dGVcbiAgICAgICAgdmFyIGxiID0gZGF0W2J0XTtcbiAgICAgICAgaWYgKCFsYilcbiAgICAgICAgICAgIGVycigwKTtcbiAgICAgICAgLy8gIHN0YXRlMSAgIHN0YXRlMiAgIHN0YXRlMSBiaXRzICAgc3RhdGUyIGJpdHNcbiAgICAgICAgdmFyIHN0MSA9IDAsIHN0MiA9IDAsIGJ0cjEgPSBmZHQuYiwgYnRyMiA9IGJ0cjE7XG4gICAgICAgIC8vIGZzZSBwb3NcbiAgICAgICAgLy8gcHJlLWluY3JlbWVudCB0byBhY2NvdW50IGZvciBvcmlnaW5hbCBkZWZpY2l0IG9mIDFcbiAgICAgICAgdmFyIGZwb3MgPSAoKytidCA8PCAzKSAtIDggKyBtc2IobGIpO1xuICAgICAgICBmb3IgKDs7KSB7XG4gICAgICAgICAgICBmcG9zIC09IGJ0cjE7XG4gICAgICAgICAgICBpZiAoZnBvcyA8IGVwb3MpXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB2YXIgY2J0ID0gZnBvcyA+PiAzO1xuICAgICAgICAgICAgc3QxICs9ICgoZGF0W2NidF0gfCAoZGF0W2NidCArIDFdIDw8IDgpKSA+PiAoZnBvcyAmIDcpKSAmICgoMSA8PCBidHIxKSAtIDEpO1xuICAgICAgICAgICAgaHdbKyt3Y10gPSBmZHQuc1tzdDFdO1xuICAgICAgICAgICAgZnBvcyAtPSBidHIyO1xuICAgICAgICAgICAgaWYgKGZwb3MgPCBlcG9zKVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2J0ID0gZnBvcyA+PiAzO1xuICAgICAgICAgICAgc3QyICs9ICgoZGF0W2NidF0gfCAoZGF0W2NidCArIDFdIDw8IDgpKSA+PiAoZnBvcyAmIDcpKSAmICgoMSA8PCBidHIyKSAtIDEpO1xuICAgICAgICAgICAgaHdbKyt3Y10gPSBmZHQuc1tzdDJdO1xuICAgICAgICAgICAgYnRyMSA9IGZkdC5uW3N0MV07XG4gICAgICAgICAgICBzdDEgPSBmZHQudFtzdDFdO1xuICAgICAgICAgICAgYnRyMiA9IGZkdC5uW3N0Ml07XG4gICAgICAgICAgICBzdDIgPSBmZHQudFtzdDJdO1xuICAgICAgICB9XG4gICAgICAgIGlmICgrK3djID4gMjU1KVxuICAgICAgICAgICAgZXJyKDApO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgd2MgPSBoYiAtIDEyNztcbiAgICAgICAgZm9yICg7IGkgPCB3YzsgaSArPSAyKSB7XG4gICAgICAgICAgICB2YXIgYnl0ZSA9IGRhdFsrK2J0XTtcbiAgICAgICAgICAgIGh3W2ldID0gYnl0ZSA+PiA0O1xuICAgICAgICAgICAgaHdbaSArIDFdID0gYnl0ZSAmIDE1O1xuICAgICAgICB9XG4gICAgICAgICsrYnQ7XG4gICAgfVxuICAgIC8vIHdlaWdodCBleHBvbmVudGlhbCBzdW1cbiAgICB2YXIgd2VzID0gMDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgd2M7ICsraSkge1xuICAgICAgICB2YXIgd3QgPSBod1tpXTtcbiAgICAgICAgLy8gYml0cyBtdXN0IGJlIGF0IG1vc3QgMTEsIHNhbWUgYXMgd2VpZ2h0XG4gICAgICAgIGlmICh3dCA+IDExKVxuICAgICAgICAgICAgZXJyKDApO1xuICAgICAgICB3ZXMgKz0gd3QgJiYgKDEgPDwgKHd0IC0gMSkpO1xuICAgIH1cbiAgICAvLyBtYXggYml0c1xuICAgIHZhciBtYiA9IG1zYih3ZXMpICsgMTtcbiAgICAvLyB0YWJsZSBzaXplXG4gICAgdmFyIHRzID0gMSA8PCBtYjtcbiAgICAvLyByZW1haW5pbmcgc3VtXG4gICAgdmFyIHJlbSA9IHRzIC0gd2VzO1xuICAgIC8vIG11c3QgYmUgcG93ZXIgb2YgMlxuICAgIGlmIChyZW0gJiAocmVtIC0gMSkpXG4gICAgICAgIGVycigwKTtcbiAgICBod1t3YysrXSA9IG1zYihyZW0pICsgMTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgd2M7ICsraSkge1xuICAgICAgICB2YXIgd3QgPSBod1tpXTtcbiAgICAgICAgKytyY1tod1tpXSA9IHd0ICYmIChtYiArIDEgLSB3dCldO1xuICAgIH1cbiAgICAvLyBodWYgYnVmXG4gICAgdmFyIGhidWYgPSBuZXcgdTgodHMgPDwgMSk7XG4gICAgLy8gICAgc3ltYm9scyAgICAgICAgICAgICAgICAgICAgICBudW0gYml0c1xuICAgIHZhciBzeW1zID0gaGJ1Zi5zdWJhcnJheSgwLCB0cyksIG5iID0gaGJ1Zi5zdWJhcnJheSh0cyk7XG4gICAgcmlbbWJdID0gMDtcbiAgICBmb3IgKGkgPSBtYjsgaSA+IDA7IC0taSkge1xuICAgICAgICB2YXIgcHYgPSByaVtpXTtcbiAgICAgICAgZmlsbChuYiwgaSwgcHYsIHJpW2kgLSAxXSA9IHB2ICsgcmNbaV0gKiAoMSA8PCAobWIgLSBpKSkpO1xuICAgIH1cbiAgICBpZiAocmlbMF0gIT0gdHMpXG4gICAgICAgIGVycigwKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgd2M7ICsraSkge1xuICAgICAgICB2YXIgYml0cyA9IGh3W2ldO1xuICAgICAgICBpZiAoYml0cykge1xuICAgICAgICAgICAgdmFyIGNvZGUgPSByaVtiaXRzXTtcbiAgICAgICAgICAgIGZpbGwoc3ltcywgaSwgY29kZSwgcmlbYml0c10gPSBjb2RlICsgKDEgPDwgKG1iIC0gYml0cykpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gW2J0LCB7XG4gICAgICAgICAgICBuOiBuYixcbiAgICAgICAgICAgIGI6IG1iLFxuICAgICAgICAgICAgczogc3ltc1xuICAgICAgICB9XTtcbn07XG4vLyBUYWJsZXMgZ2VuZXJhdGVkIHVzaW5nIHRoaXM6XG4vLyBodHRwczovL2dpc3QuZ2l0aHViLmNvbS8xMDFhcnJvd3ovYTk3OTQ1MmQ0MzU1OTkyY2JmOGYyNTdjYmZmYzllZGRcbi8vIGRlZmF1bHQgbGl0ZXJhbCBsZW5ndGggdGFibGVcbnZhciBkbGx0ID0gLyojX19QVVJFX18qLyByZnNlKC8qI19fUFVSRV9fKi8gbmV3IHU4KFtcbiAgICA4MSwgMTYsIDk5LCAxNDAsIDQ5LCAxOTgsIDI0LCA5OSwgMTIsIDMzLCAxOTYsIDI0LCA5OSwgMTAyLCAxMDIsIDEzNCwgNzAsIDE0NiwgNFxuXSksIDAsIDYpWzFdO1xuLy8gZGVmYXVsdCBtYXRjaCBsZW5ndGggdGFibGVcbnZhciBkbWx0ID0gLyojX19QVVJFX18qLyByZnNlKC8qI19fUFVSRV9fKi8gbmV3IHU4KFtcbiAgICAzMywgMjAsIDE5NiwgMjQsIDk5LCAxNDAsIDMzLCAxMzIsIDE2LCA2NiwgOCwgMzMsIDEzMiwgMTYsIDY2LCA4LCAzMywgNjgsIDY4LCA2OCwgNjgsIDY4LCA2OCwgNjgsIDY4LCAzNiwgOVxuXSksIDAsIDYpWzFdO1xuLy8gZGVmYXVsdCBvZmZzZXQgY29kZSB0YWJsZVxudmFyIGRvY3QgPSAvKiNfX1BVUkVfXyAqLyByZnNlKC8qI19fUFVSRV9fKi8gbmV3IHU4KFtcbiAgICAzMiwgMTMyLCAxNiwgNjYsIDEwMiwgNzAsIDY4LCA2OCwgNjgsIDY4LCAzNiwgNzMsIDJcbl0pLCAwLCA1KVsxXTtcbi8vIGJpdHMgdG8gYmFzZWxpbmVcbnZhciBiMmJsID0gZnVuY3Rpb24gKGIsIHMpIHtcbiAgICB2YXIgbGVuID0gYi5sZW5ndGgsIGJsID0gbmV3IGkzMihsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAgYmxbaV0gPSBzO1xuICAgICAgICBzICs9IDEgPDwgYltpXTtcbiAgICB9XG4gICAgcmV0dXJuIGJsO1xufTtcbi8vIGxpdGVyYWwgbGVuZ3RoIGJpdHNcbnZhciBsbGIgPSAvKiNfX1BVUkVfXyAqLyBuZXcgdTgoKCAvKiNfX1BVUkVfXyAqL25ldyBpMzIoW1xuICAgIDAsIDAsIDAsIDAsIDE2ODQzMDA5LCA1MDUyODc3MCwgMTM0Njc4MDIwLCAyMDIwNTAwNTcsIDI2OTQyMjA5M1xuXSkpLmJ1ZmZlciwgMCwgMzYpO1xuLy8gbGl0ZXJhbCBsZW5ndGggYmFzZWxpbmVcbnZhciBsbGJsID0gLyojX19QVVJFX18gKi8gYjJibChsbGIsIDApO1xuLy8gbWF0Y2ggbGVuZ3RoIGJpdHNcbnZhciBtbGIgPSAvKiNfX1BVUkVfXyAqLyBuZXcgdTgoKCAvKiNfX1BVUkVfXyAqL25ldyBpMzIoW1xuICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDE2ODQzMDA5LCA1MDUyODc3MCwgMTE3NzY5MjIwLCAxODUyMDcwNDgsIDI1MjU3OTA4NCwgMTZcbl0pKS5idWZmZXIsIDAsIDUzKTtcbi8vIG1hdGNoIGxlbmd0aCBiYXNlbGluZVxudmFyIG1sYmwgPSAvKiNfX1BVUkVfXyAqLyBiMmJsKG1sYiwgMyk7XG4vLyBkZWNvZGUgaHVmZm1hbiBzdHJlYW1cbnZhciBkaHUgPSBmdW5jdGlvbiAoZGF0LCBvdXQsIGh1KSB7XG4gICAgdmFyIGxlbiA9IGRhdC5sZW5ndGgsIHNzID0gb3V0Lmxlbmd0aCwgbGIgPSBkYXRbbGVuIC0gMV0sIG1zayA9ICgxIDw8IGh1LmIpIC0gMSwgZWIgPSAtaHUuYjtcbiAgICBpZiAoIWxiKVxuICAgICAgICBlcnIoMCk7XG4gICAgdmFyIHN0ID0gMCwgYnRyID0gaHUuYiwgcG9zID0gKGxlbiA8PCAzKSAtIDggKyBtc2IobGIpIC0gYnRyLCBpID0gLTE7XG4gICAgZm9yICg7IHBvcyA+IGViICYmIGkgPCBzczspIHtcbiAgICAgICAgdmFyIGNidCA9IHBvcyA+PiAzO1xuICAgICAgICB2YXIgdmFsID0gKGRhdFtjYnRdIHwgKGRhdFtjYnQgKyAxXSA8PCA4KSB8IChkYXRbY2J0ICsgMl0gPDwgMTYpKSA+PiAocG9zICYgNyk7XG4gICAgICAgIHN0ID0gKChzdCA8PCBidHIpIHwgdmFsKSAmIG1zaztcbiAgICAgICAgb3V0WysraV0gPSBodS5zW3N0XTtcbiAgICAgICAgcG9zIC09IChidHIgPSBodS5uW3N0XSk7XG4gICAgfVxuICAgIGlmIChwb3MgIT0gZWIgfHwgaSArIDEgIT0gc3MpXG4gICAgICAgIGVycigwKTtcbn07XG4vLyBkZWNvZGUgaHVmZm1hbiBzdHJlYW0gNHhcbi8vIFRPRE86IHVzZSB3b3JrZXJzIHRvIHBhcmFsbGVsaXplXG52YXIgZGh1NCA9IGZ1bmN0aW9uIChkYXQsIG91dCwgaHUpIHtcbiAgICB2YXIgYnQgPSA2O1xuICAgIHZhciBzcyA9IG91dC5sZW5ndGgsIHN6MSA9IChzcyArIDMpID4+IDIsIHN6MiA9IHN6MSA8PCAxLCBzejMgPSBzejEgKyBzejI7XG4gICAgZGh1KGRhdC5zdWJhcnJheShidCwgYnQgKz0gZGF0WzBdIHwgKGRhdFsxXSA8PCA4KSksIG91dC5zdWJhcnJheSgwLCBzejEpLCBodSk7XG4gICAgZGh1KGRhdC5zdWJhcnJheShidCwgYnQgKz0gZGF0WzJdIHwgKGRhdFszXSA8PCA4KSksIG91dC5zdWJhcnJheShzejEsIHN6MiksIGh1KTtcbiAgICBkaHUoZGF0LnN1YmFycmF5KGJ0LCBidCArPSBkYXRbNF0gfCAoZGF0WzVdIDw8IDgpKSwgb3V0LnN1YmFycmF5KHN6Miwgc3ozKSwgaHUpO1xuICAgIGRodShkYXQuc3ViYXJyYXkoYnQpLCBvdXQuc3ViYXJyYXkoc3ozKSwgaHUpO1xufTtcbi8vIHJlYWQgWnN0YW5kYXJkIGJsb2NrXG52YXIgcnpiID0gZnVuY3Rpb24gKGRhdCwgc3QsIG91dCkge1xuICAgIHZhciBfYTtcbiAgICB2YXIgYnQgPSBzdC5iO1xuICAgIC8vICAgIGJ5dGUgMCAgICAgICAgYmxvY2sgdHlwZVxuICAgIHZhciBiMCA9IGRhdFtidF0sIGJ0eXBlID0gKGIwID4+IDEpICYgMztcbiAgICBzdC5sID0gYjAgJiAxO1xuICAgIHZhciBzeiA9IChiMCA+PiAzKSB8IChkYXRbYnQgKyAxXSA8PCA1KSB8IChkYXRbYnQgKyAyXSA8PCAxMyk7XG4gICAgLy8gZW5kIGJ5dGUgZm9yIGJsb2NrXG4gICAgdmFyIGVidCA9IChidCArPSAzKSArIHN6O1xuICAgIGlmIChidHlwZSA9PSAxKSB7XG4gICAgICAgIGlmIChidCA+PSBkYXQubGVuZ3RoKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBzdC5iID0gYnQgKyAxO1xuICAgICAgICBpZiAob3V0KSB7XG4gICAgICAgICAgICBmaWxsKG91dCwgZGF0W2J0XSwgc3QueSwgc3QueSArPSBzeik7XG4gICAgICAgICAgICByZXR1cm4gb3V0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmaWxsKG5ldyB1OChzeiksIGRhdFtidF0pO1xuICAgIH1cbiAgICBpZiAoZWJ0ID4gZGF0Lmxlbmd0aClcbiAgICAgICAgcmV0dXJuO1xuICAgIGlmIChidHlwZSA9PSAwKSB7XG4gICAgICAgIHN0LmIgPSBlYnQ7XG4gICAgICAgIGlmIChvdXQpIHtcbiAgICAgICAgICAgIG91dC5zZXQoZGF0LnN1YmFycmF5KGJ0LCBlYnQpLCBzdC55KTtcbiAgICAgICAgICAgIHN0LnkgKz0gc3o7XG4gICAgICAgICAgICByZXR1cm4gb3V0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzbGMoZGF0LCBidCwgZWJ0KTtcbiAgICB9XG4gICAgaWYgKGJ0eXBlID09IDIpIHtcbiAgICAgICAgLy8gICAgYnl0ZSAzICAgICAgICBsaXQgYnR5cGUgICAgIHNpemUgZm9ybWF0XG4gICAgICAgIHZhciBiMyA9IGRhdFtidF0sIGxidCA9IGIzICYgMywgc2YgPSAoYjMgPj4gMikgJiAzO1xuICAgICAgICAvLyBsaXQgc3JjIHNpemUgIGxpdCBjbXAgc3ogNCBzdHJlYW1zXG4gICAgICAgIHZhciBsc3MgPSBiMyA+PiA0LCBsY3MgPSAwLCBzNCA9IDA7XG4gICAgICAgIGlmIChsYnQgPCAyKSB7XG4gICAgICAgICAgICBpZiAoc2YgJiAxKVxuICAgICAgICAgICAgICAgIGxzcyB8PSAoZGF0WysrYnRdIDw8IDQpIHwgKChzZiAmIDIpICYmIChkYXRbKytidF0gPDwgMTIpKTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBsc3MgPSBiMyA+PiAzO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgczQgPSBzZjtcbiAgICAgICAgICAgIGlmIChzZiA8IDIpXG4gICAgICAgICAgICAgICAgbHNzIHw9ICgoZGF0WysrYnRdICYgNjMpIDw8IDQpLCBsY3MgPSAoZGF0W2J0XSA+PiA2KSB8IChkYXRbKytidF0gPDwgMik7XG4gICAgICAgICAgICBlbHNlIGlmIChzZiA9PSAyKVxuICAgICAgICAgICAgICAgIGxzcyB8PSAoZGF0WysrYnRdIDw8IDQpIHwgKChkYXRbKytidF0gJiAzKSA8PCAxMiksIGxjcyA9IChkYXRbYnRdID4+IDIpIHwgKGRhdFsrK2J0XSA8PCA2KTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBsc3MgfD0gKGRhdFsrK2J0XSA8PCA0KSB8ICgoZGF0WysrYnRdICYgNjMpIDw8IDEyKSwgbGNzID0gKGRhdFtidF0gPj4gNikgfCAoZGF0WysrYnRdIDw8IDIpIHwgKGRhdFsrK2J0XSA8PCAxMCk7XG4gICAgICAgIH1cbiAgICAgICAgKytidDtcbiAgICAgICAgLy8gYWRkIGxpdGVyYWxzIHRvIGVuZCAtIGNhbiBuZXZlciBvdmVybGFwIHdpdGggYmFja3JlZmVyZW5jZXMgYmVjYXVzZSB1bnVzZWQgbGl0ZXJhbHMgYWx3YXlzIGFwcGVuZGVkXG4gICAgICAgIHZhciBidWYgPSBvdXQgPyBvdXQuc3ViYXJyYXkoc3QueSwgc3QueSArIHN0Lm0pIDogbmV3IHU4KHN0Lm0pO1xuICAgICAgICAvLyBzdGFydGluZyBwb2ludCBmb3IgbGl0ZXJhbHNcbiAgICAgICAgdmFyIHNwbCA9IGJ1Zi5sZW5ndGggLSBsc3M7XG4gICAgICAgIGlmIChsYnQgPT0gMClcbiAgICAgICAgICAgIGJ1Zi5zZXQoZGF0LnN1YmFycmF5KGJ0LCBidCArPSBsc3MpLCBzcGwpO1xuICAgICAgICBlbHNlIGlmIChsYnQgPT0gMSlcbiAgICAgICAgICAgIGZpbGwoYnVmLCBkYXRbYnQrK10sIHNwbCk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gaHVmZm1hbiB0YWJsZVxuICAgICAgICAgICAgdmFyIGh1ID0gc3QuaDtcbiAgICAgICAgICAgIGlmIChsYnQgPT0gMikge1xuICAgICAgICAgICAgICAgIHZhciBodWQgPSByaHUoZGF0LCBidCk7XG4gICAgICAgICAgICAgICAgLy8gc3VidHJhY3QgZGVzY3JpcHRpb24gbGVuZ3RoXG4gICAgICAgICAgICAgICAgbGNzICs9IGJ0IC0gKGJ0ID0gaHVkWzBdKTtcbiAgICAgICAgICAgICAgICBzdC5oID0gaHUgPSBodWRbMV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICghaHUpXG4gICAgICAgICAgICAgICAgZXJyKDApO1xuICAgICAgICAgICAgKHM0ID8gZGh1NCA6IGRodSkoZGF0LnN1YmFycmF5KGJ0LCBidCArPSBsY3MpLCBidWYuc3ViYXJyYXkoc3BsKSwgaHUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIG51bSBzZXF1ZW5jZXNcbiAgICAgICAgdmFyIG5zID0gZGF0W2J0KytdO1xuICAgICAgICBpZiAobnMpIHtcbiAgICAgICAgICAgIGlmIChucyA9PSAyNTUpXG4gICAgICAgICAgICAgICAgbnMgPSAoZGF0W2J0KytdIHwgKGRhdFtidCsrXSA8PCA4KSkgKyAweDdGMDA7XG4gICAgICAgICAgICBlbHNlIGlmIChucyA+IDEyNylcbiAgICAgICAgICAgICAgICBucyA9ICgobnMgLSAxMjgpIDw8IDgpIHwgZGF0W2J0KytdO1xuICAgICAgICAgICAgLy8gc3ltYm9sIGNvbXByZXNzaW9uIG1vZGVzXG4gICAgICAgICAgICB2YXIgc2NtID0gZGF0W2J0KytdO1xuICAgICAgICAgICAgaWYgKHNjbSAmIDMpXG4gICAgICAgICAgICAgICAgZXJyKDApO1xuICAgICAgICAgICAgdmFyIGR0cyA9IFtkbWx0LCBkb2N0LCBkbGx0XTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAyOyBpID4gLTE7IC0taSkge1xuICAgICAgICAgICAgICAgIHZhciBtZCA9IChzY20gPj4gKChpIDw8IDEpICsgMikpICYgMztcbiAgICAgICAgICAgICAgICBpZiAobWQgPT0gMSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBybGUgYnVmXG4gICAgICAgICAgICAgICAgICAgIHZhciByYnVmID0gbmV3IHU4KFswLCAwLCBkYXRbYnQrK11dKTtcbiAgICAgICAgICAgICAgICAgICAgZHRzW2ldID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgczogcmJ1Zi5zdWJhcnJheSgyLCAzKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG46IHJidWYuc3ViYXJyYXkoMCwgMSksXG4gICAgICAgICAgICAgICAgICAgICAgICB0OiBuZXcgdTE2KHJidWYuYnVmZmVyLCAwLCAxKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGI6IDBcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAobWQgPT0gMikge1xuICAgICAgICAgICAgICAgICAgICAvLyBhY2N1cmFjeSBsb2cgOCBmb3Igb2Zmc2V0cywgOSBmb3Igb3RoZXJzXG4gICAgICAgICAgICAgICAgICAgIF9hID0gcmZzZShkYXQsIGJ0LCA5IC0gKGkgJiAxKSksIGJ0ID0gX2FbMF0sIGR0c1tpXSA9IF9hWzFdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChtZCA9PSAzKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghc3QudClcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycigwKTtcbiAgICAgICAgICAgICAgICAgICAgZHRzW2ldID0gc3QudFtpXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgX2IgPSBzdC50ID0gZHRzLCBtbHQgPSBfYlswXSwgb2N0ID0gX2JbMV0sIGxsdCA9IF9iWzJdO1xuICAgICAgICAgICAgdmFyIGxiID0gZGF0W2VidCAtIDFdO1xuICAgICAgICAgICAgaWYgKCFsYilcbiAgICAgICAgICAgICAgICBlcnIoMCk7XG4gICAgICAgICAgICB2YXIgc3BvcyA9IChlYnQgPDwgMykgLSA4ICsgbXNiKGxiKSAtIGxsdC5iLCBjYnQgPSBzcG9zID4+IDMsIG91YnQgPSAwO1xuICAgICAgICAgICAgdmFyIGxzdCA9ICgoZGF0W2NidF0gfCAoZGF0W2NidCArIDFdIDw8IDgpKSA+PiAoc3BvcyAmIDcpKSAmICgoMSA8PCBsbHQuYikgLSAxKTtcbiAgICAgICAgICAgIGNidCA9IChzcG9zIC09IG9jdC5iKSA+PiAzO1xuICAgICAgICAgICAgdmFyIG9zdCA9ICgoZGF0W2NidF0gfCAoZGF0W2NidCArIDFdIDw8IDgpKSA+PiAoc3BvcyAmIDcpKSAmICgoMSA8PCBvY3QuYikgLSAxKTtcbiAgICAgICAgICAgIGNidCA9IChzcG9zIC09IG1sdC5iKSA+PiAzO1xuICAgICAgICAgICAgdmFyIG1zdCA9ICgoZGF0W2NidF0gfCAoZGF0W2NidCArIDFdIDw8IDgpKSA+PiAoc3BvcyAmIDcpKSAmICgoMSA8PCBtbHQuYikgLSAxKTtcbiAgICAgICAgICAgIGZvciAoKytuczsgLS1uczspIHtcbiAgICAgICAgICAgICAgICB2YXIgbGxjID0gbGx0LnNbbHN0XTtcbiAgICAgICAgICAgICAgICB2YXIgbGJ0ciA9IGxsdC5uW2xzdF07XG4gICAgICAgICAgICAgICAgdmFyIG1sYyA9IG1sdC5zW21zdF07XG4gICAgICAgICAgICAgICAgdmFyIG1idHIgPSBtbHQublttc3RdO1xuICAgICAgICAgICAgICAgIHZhciBvZmMgPSBvY3Quc1tvc3RdO1xuICAgICAgICAgICAgICAgIHZhciBvYnRyID0gb2N0Lm5bb3N0XTtcbiAgICAgICAgICAgICAgICBjYnQgPSAoc3BvcyAtPSBvZmMpID4+IDM7XG4gICAgICAgICAgICAgICAgdmFyIG9mcCA9IDEgPDwgb2ZjO1xuICAgICAgICAgICAgICAgIHZhciBvZmYgPSBvZnAgKyAoKChkYXRbY2J0XSB8IChkYXRbY2J0ICsgMV0gPDwgOCkgfCAoZGF0W2NidCArIDJdIDw8IDE2KSB8IChkYXRbY2J0ICsgM10gPDwgMjQpKSA+Pj4gKHNwb3MgJiA3KSkgJiAob2ZwIC0gMSkpO1xuICAgICAgICAgICAgICAgIGNidCA9IChzcG9zIC09IG1sYlttbGNdKSA+PiAzO1xuICAgICAgICAgICAgICAgIHZhciBtbCA9IG1sYmxbbWxjXSArICgoKGRhdFtjYnRdIHwgKGRhdFtjYnQgKyAxXSA8PCA4KSB8IChkYXRbY2J0ICsgMl0gPDwgMTYpKSA+PiAoc3BvcyAmIDcpKSAmICgoMSA8PCBtbGJbbWxjXSkgLSAxKSk7XG4gICAgICAgICAgICAgICAgY2J0ID0gKHNwb3MgLT0gbGxiW2xsY10pID4+IDM7XG4gICAgICAgICAgICAgICAgdmFyIGxsID0gbGxibFtsbGNdICsgKCgoZGF0W2NidF0gfCAoZGF0W2NidCArIDFdIDw8IDgpIHwgKGRhdFtjYnQgKyAyXSA8PCAxNikpID4+IChzcG9zICYgNykpICYgKCgxIDw8IGxsYltsbGNdKSAtIDEpKTtcbiAgICAgICAgICAgICAgICBjYnQgPSAoc3BvcyAtPSBsYnRyKSA+PiAzO1xuICAgICAgICAgICAgICAgIGxzdCA9IGxsdC50W2xzdF0gKyAoKChkYXRbY2J0XSB8IChkYXRbY2J0ICsgMV0gPDwgOCkpID4+IChzcG9zICYgNykpICYgKCgxIDw8IGxidHIpIC0gMSkpO1xuICAgICAgICAgICAgICAgIGNidCA9IChzcG9zIC09IG1idHIpID4+IDM7XG4gICAgICAgICAgICAgICAgbXN0ID0gbWx0LnRbbXN0XSArICgoKGRhdFtjYnRdIHwgKGRhdFtjYnQgKyAxXSA8PCA4KSkgPj4gKHNwb3MgJiA3KSkgJiAoKDEgPDwgbWJ0cikgLSAxKSk7XG4gICAgICAgICAgICAgICAgY2J0ID0gKHNwb3MgLT0gb2J0cikgPj4gMztcbiAgICAgICAgICAgICAgICBvc3QgPSBvY3QudFtvc3RdICsgKCgoZGF0W2NidF0gfCAoZGF0W2NidCArIDFdIDw8IDgpKSA+PiAoc3BvcyAmIDcpKSAmICgoMSA8PCBvYnRyKSAtIDEpKTtcbiAgICAgICAgICAgICAgICBpZiAob2ZmID4gMykge1xuICAgICAgICAgICAgICAgICAgICBzdC5vWzJdID0gc3Qub1sxXTtcbiAgICAgICAgICAgICAgICAgICAgc3Qub1sxXSA9IHN0Lm9bMF07XG4gICAgICAgICAgICAgICAgICAgIHN0Lm9bMF0gPSBvZmYgLT0gMztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBpZHggPSBvZmYgLSAobGwgIT0gMCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpZHgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9mZiA9IGlkeCA9PSAzID8gc3Qub1swXSAtIDEgOiBzdC5vW2lkeF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaWR4ID4gMSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdC5vWzJdID0gc3Qub1sxXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0Lm9bMV0gPSBzdC5vWzBdO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3Qub1swXSA9IG9mZjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICBvZmYgPSBzdC5vWzBdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxsOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgYnVmW291YnQgKyBpXSA9IGJ1ZltzcGwgKyBpXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb3VidCArPSBsbCwgc3BsICs9IGxsO1xuICAgICAgICAgICAgICAgIHZhciBzdGluID0gb3VidCAtIG9mZjtcbiAgICAgICAgICAgICAgICBpZiAoc3RpbiA8IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGxlbiA9IC1zdGluO1xuICAgICAgICAgICAgICAgICAgICB2YXIgYnMgPSBzdC5lICsgc3RpbjtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxlbiA+IG1sKVxuICAgICAgICAgICAgICAgICAgICAgICAgbGVuID0gbWw7XG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZltvdWJ0ICsgaV0gPSBzdC53W2JzICsgaV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgb3VidCArPSBsZW4sIG1sIC09IGxlbiwgc3RpbiA9IDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWw7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICBidWZbb3VidCArIGldID0gYnVmW3N0aW4gKyBpXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb3VidCArPSBtbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvdWJ0ICE9IHNwbCkge1xuICAgICAgICAgICAgICAgIHdoaWxlIChzcGwgPCBidWYubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIGJ1ZltvdWJ0KytdID0gYnVmW3NwbCsrXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgb3VidCA9IGJ1Zi5sZW5ndGg7XG4gICAgICAgICAgICBpZiAob3V0KVxuICAgICAgICAgICAgICAgIHN0LnkgKz0gb3VidDtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBidWYgPSBzbGMoYnVmLCAwLCBvdWJ0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChvdXQpIHtcbiAgICAgICAgICAgICAgICBzdC55ICs9IGxzcztcbiAgICAgICAgICAgICAgICBpZiAoc3BsKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbHNzOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZltpXSA9IGJ1ZltzcGwgKyBpXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHNwbClcbiAgICAgICAgICAgICAgICBidWYgPSBzbGMoYnVmLCBzcGwpO1xuICAgICAgICB9XG4gICAgICAgIHN0LmIgPSBlYnQ7XG4gICAgICAgIHJldHVybiBidWY7XG4gICAgfVxuICAgIGVycigyKTtcbn07XG4vLyBjb25jYXRcbnZhciBjY3QgPSBmdW5jdGlvbiAoYnVmcywgb2wpIHtcbiAgICBpZiAoYnVmcy5sZW5ndGggPT0gMSlcbiAgICAgICAgcmV0dXJuIGJ1ZnNbMF07XG4gICAgdmFyIGJ1ZiA9IG5ldyB1OChvbCk7XG4gICAgZm9yICh2YXIgaSA9IDAsIGIgPSAwOyBpIDwgYnVmcy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgY2hrID0gYnVmc1tpXTtcbiAgICAgICAgYnVmLnNldChjaGssIGIpO1xuICAgICAgICBiICs9IGNoay5sZW5ndGg7XG4gICAgfVxuICAgIHJldHVybiBidWY7XG59O1xuLyoqXG4gKiBEZWNvbXByZXNzZXMgWnN0YW5kYXJkIGRhdGFcbiAqIEBwYXJhbSBkYXQgVGhlIGlucHV0IGRhdGFcbiAqIEBwYXJhbSBidWYgVGhlIG91dHB1dCBidWZmZXIuIElmIHVuc3BlY2lmaWVkLCB0aGUgZnVuY3Rpb24gd2lsbCBhbGxvY2F0ZVxuICogICAgICAgICAgICBleGFjdGx5IGVub3VnaCBtZW1vcnkgdG8gZml0IHRoZSBkZWNvbXByZXNzZWQgZGF0YS4gSWYgeW91clxuICogICAgICAgICAgICBkYXRhIGhhcyBtdWx0aXBsZSBmcmFtZXMgYW5kIHlvdSBrbm93IHRoZSBvdXRwdXQgc2l6ZSwgc3BlY2lmeWluZ1xuICogICAgICAgICAgICBpdCB3aWxsIHlpZWxkIGJldHRlciBwZXJmb3JtYW5jZS5cbiAqIEByZXR1cm5zIFRoZSBkZWNvbXByZXNzZWQgZGF0YVxuICovXG5yZXR1cm4gZnVuY3Rpb24gZGVjb21wcmVzcyhkYXQsIGJ1Zikge1xuICAgIHZhciBidCA9IDAsIGJ1ZnMgPSBbXSwgbmIgPSArIWJ1Ziwgb2wgPSAwO1xuICAgIGZvciAoOyBkYXQubGVuZ3RoOykge1xuICAgICAgICB2YXIgc3QgPSByemZoKGRhdCwgbmIgfHwgYnVmKTtcbiAgICAgICAgaWYgKHR5cGVvZiBzdCA9PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgaWYgKG5iKSB7XG4gICAgICAgICAgICAgICAgYnVmID0gbnVsbDtcbiAgICAgICAgICAgICAgICBpZiAoc3Qudy5sZW5ndGggPT0gc3QudSkge1xuICAgICAgICAgICAgICAgICAgICBidWZzLnB1c2goYnVmID0gc3Qudyk7XG4gICAgICAgICAgICAgICAgICAgIG9sICs9IHN0LnU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYnVmcy5wdXNoKGJ1Zik7XG4gICAgICAgICAgICAgICAgc3QuZSA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKDsgIXN0Lmw7KSB7XG4gICAgICAgICAgICAgICAgdmFyIGJsayA9IHJ6YihkYXQsIHN0LCBidWYpO1xuICAgICAgICAgICAgICAgIGlmICghYmxrKVxuICAgICAgICAgICAgICAgICAgICBlcnIoNSk7XG4gICAgICAgICAgICAgICAgaWYgKGJ1ZilcbiAgICAgICAgICAgICAgICAgICAgc3QuZSA9IHN0Lnk7XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGJ1ZnMucHVzaChibGspO1xuICAgICAgICAgICAgICAgICAgICBvbCArPSBibGsubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICBjcHcoc3QudywgMCwgYmxrLmxlbmd0aCk7XG4gICAgICAgICAgICAgICAgICAgIHN0Lncuc2V0KGJsaywgc3Qudy5sZW5ndGggLSBibGsubGVuZ3RoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBidCA9IHN0LmIgKyAoc3QuYyAqIDQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIGJ0ID0gc3Q7XG4gICAgICAgIGRhdCA9IGRhdC5zdWJhcnJheShidCk7XG4gICAgfVxuICAgIHJldHVybiBjY3QoYnVmcywgb2wpO1xufVxufSkgKClcblxuXG4vL1Byb3ZpZGVzOiBjYW1sX2RlY29tcHJlc3NfaW5wdXRcbi8vVmVyc2lvbjogPCA1LjEuMFxudmFyIGNhbWxfZGVjb21wcmVzc19pbnB1dCA9IG51bGxcblxuLy9Qcm92aWRlczogY2FtbF9kZWNvbXByZXNzX2lucHV0XG4vL1ZlcnNpb246ID49IDUuMS4wXG4vL1ZlcnNpb246IDwgNS4xLjFcbi8vUmVxdWlyZXM6IHpzdGRfZGVjb21wcmVzc1xudmFyIGNhbWxfZGVjb21wcmVzc19pbnB1dCA9IHpzdGRfZGVjb21wcmVzcztcblxuLy9Qcm92aWRlczogY2FtbF9kZWNvbXByZXNzX2lucHV0XG4vL1ZlcnNpb246ID49IDUuMS4xXG4vL1ZlcnNpb246IDwgNS4yLjBcbnZhciBjYW1sX2RlY29tcHJlc3NfaW5wdXQgPSBudWxsXG5cbi8vUHJvdmlkZXM6IGNhbWxfZGVjb21wcmVzc19pbnB1dFxuLy9WZXJzaW9uOiA+PSA1LjJcbi8vUmVxdWlyZXM6IHpzdGRfZGVjb21wcmVzc1xudmFyIGNhbWxfZGVjb21wcmVzc19pbnB1dCA9IHpzdGRfZGVjb21wcmVzcztcblxuLy9Qcm92aWRlczogY2FtbF96c3RkX2luaXRpYWxpemVcbi8vUmVxdWlyZXM6IGNhbWxfZGVjb21wcmVzc19pbnB1dFxuLy9SZXF1aXJlczogenN0ZF9kZWNvbXByZXNzXG4vL1ZlcnNpb246ID49IDUuMS4xXG5mdW5jdGlvbiBjYW1sX3pzdGRfaW5pdGlhbGl6ZSh1bml0KSB7XG4gIGNhbWxfZGVjb21wcmVzc19pbnB1dCA9IHpzdGRfZGVjb21wcmVzcztcbiAgcmV0dXJuIDFcbn1cblxuIiwiLy8gSnNfb2Zfb2NhbWwgcnVudGltZSBzdXBwb3J0XG4vLyBodHRwOi8vd3d3Lm9jc2lnZW4ub3JnL2pzX29mX29jYW1sL1xuLy8gQ29weXJpZ2h0IChDKSAyMDEwIErDqXLDtG1lIFZvdWlsbG9uXG4vLyBMYWJvcmF0b2lyZSBQUFMgLSBDTlJTIFVuaXZlcnNpdMOpIFBhcmlzIERpZGVyb3Rcbi8vXG4vLyBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuLy8gaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4vLyB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCB3aXRoIGxpbmtpbmcgZXhjZXB0aW9uO1xuLy8gZWl0aGVyIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy9cbi8vIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbi8vIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy9cbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuLy8gYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuXG5cbi8vIFdlYWsgQVBJXG5cbi8vUHJvdmlkZXM6IGNhbWxfZXBoZV9rZXlfb2Zmc2V0XG52YXIgY2FtbF9lcGhlX2tleV9vZmZzZXQgPSAzXG5cbi8vUHJvdmlkZXM6IGNhbWxfZXBoZV9kYXRhX29mZnNldFxudmFyIGNhbWxfZXBoZV9kYXRhX29mZnNldCA9IDJcblxuLy9Qcm92aWRlczogY2FtbF9lcGhlX3NldF9rZXlcbi8vUmVxdWlyZXM6IGNhbWxfaW52YWxpZF9hcmd1bWVudCwgY2FtbF9lcGhlX2tleV9vZmZzZXRcbmZ1bmN0aW9uIGNhbWxfZXBoZV9zZXRfa2V5KHgsIGksIHYpIHtcbiAgaWYoaSA8IDAgfHwgY2FtbF9lcGhlX2tleV9vZmZzZXQgKyBpID49IHgubGVuZ3RoKVxuICAgIGNhbWxfaW52YWxpZF9hcmd1bWVudCAoXCJXZWFrLnNldFwiKTtcbiAgaWYgKHYgaW5zdGFuY2VvZiBPYmplY3QgJiYgZ2xvYmFsVGhpcy5XZWFrUmVmKSB7XG4gICAgaWYoeFsxXS5yZWdpc3RlcikgeFsxXS5yZWdpc3Rlcih2LCB1bmRlZmluZWQsIHYpO1xuICAgIHhbY2FtbF9lcGhlX2tleV9vZmZzZXQgKyBpXSA9IG5ldyBnbG9iYWxUaGlzLldlYWtSZWYodik7XG4gIH1cbiAgZWxzZSB4W2NhbWxfZXBoZV9rZXlfb2Zmc2V0ICsgaV0gPSB2O1xuICByZXR1cm4gMFxufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2VwaGVfdW5zZXRfa2V5XG4vL1JlcXVpcmVzOiBjYW1sX2ludmFsaWRfYXJndW1lbnQsIGNhbWxfZXBoZV9rZXlfb2Zmc2V0XG5mdW5jdGlvbiBjYW1sX2VwaGVfdW5zZXRfa2V5KHgsIGkpIHtcbiAgaWYoaSA8IDAgfHwgY2FtbF9lcGhlX2tleV9vZmZzZXQgKyBpID49IHgubGVuZ3RoKVxuICAgIGNhbWxfaW52YWxpZF9hcmd1bWVudCAoXCJXZWFrLnNldFwiKTtcbiAgaWYoZ2xvYmFsVGhpcy5XZWFrUmVmICYmIHhbY2FtbF9lcGhlX2tleV9vZmZzZXQgKyBpXSBpbnN0YW5jZW9mIGdsb2JhbFRoaXMuV2Vha1JlZiAmJiB4WzFdLnVucmVnaXN0ZXIpIHtcbiAgICB2YXIgb2xkID0geFtjYW1sX2VwaGVfa2V5X29mZnNldCArIGldLmRlcmVmKCk7XG4gICAgaWYob2xkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHZhciBjb3VudCA9IDBcbiAgICAgIGZvcih2YXIgaiA9IGNhbWxfZXBoZV9rZXlfb2Zmc2V0OyBqIDwgeC5sZW5ndGg7IGorKyl7XG4gICAgICAgIHZhciBrZXkgPSB4W2pdO1xuICAgICAgICBpZihrZXkgaW5zdGFuY2VvZiBnbG9iYWxUaGlzLldlYWtSZWYpe1xuICAgICAgICAgIGtleSA9IGtleS5kZXJlZigpXG4gICAgICAgICAgaWYoa2V5ID09PSBvbGQpIGNvdW50Kys7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmKGNvdW50ID09IDEpIHhbMV0udW5yZWdpc3RlcihvbGQpO1xuICAgIH1cbiAgfVxuICB4W2NhbWxfZXBoZV9rZXlfb2Zmc2V0ICsgaV0gPSB1bmRlZmluZWQ7XG4gIHJldHVybiAwXG59XG5cblxuLy9Qcm92aWRlczogY2FtbF9lcGhlX2NyZWF0ZVxuLy9SZXF1aXJlczogY2FtbF93ZWFrX2NyZWF0ZSwgY2FtbF9lcGhlX2RhdGFfb2Zmc2V0XG5mdW5jdGlvbiBjYW1sX2VwaGVfY3JlYXRlIChuKSB7XG4gIHZhciB4ID0gY2FtbF93ZWFrX2NyZWF0ZShuKTtcbiAgcmV0dXJuIHg7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfd2Vha19jcmVhdGVcbi8vUmVxdWlyZXM6IGNhbWxfZXBoZV9rZXlfb2Zmc2V0LCBjYW1sX2ludmFsaWRfYXJndW1lbnQsY2FtbF9lcGhlX2RhdGFfb2Zmc2V0XG5mdW5jdGlvbiBjYW1sX3dlYWtfY3JlYXRlIChuKSB7XG4gIGlmIChuIDwgMCkgY2FtbF9pbnZhbGlkX2FyZ3VtZW50IChcIldlYWsuY3JlYXRlXCIpO1xuICB2YXIgeCA9IFsyNTEsXCJjYW1sX2VwaGVfbGlzdF9oZWFkXCJdO1xuICB4Lmxlbmd0aCA9IGNhbWxfZXBoZV9rZXlfb2Zmc2V0ICsgbjtcbiAgcmV0dXJuIHg7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfd2Vha19zZXRcbi8vUmVxdWlyZXM6IGNhbWxfaW52YWxpZF9hcmd1bWVudFxuLy9SZXF1aXJlczogY2FtbF9lcGhlX3NldF9rZXksIGNhbWxfZXBoZV91bnNldF9rZXlcbmZ1bmN0aW9uIGNhbWxfd2Vha19zZXQoeCwgaSwgdikge1xuICBpZih2ID09IDApIGNhbWxfZXBoZV91bnNldF9rZXkoeCxpKVxuICBlbHNlIGNhbWxfZXBoZV9zZXRfa2V5KHgsaSx2WzFdKVxuICByZXR1cm4gMDtcbn1cbi8vUHJvdmlkZXM6IGNhbWxfZXBoZV9nZXRfa2V5XG4vL1JlcXVpcmVzOiBjYW1sX2VwaGVfa2V5X29mZnNldCwgY2FtbF9pbnZhbGlkX2FyZ3VtZW50XG4vL0FsaWFzOiBjYW1sX3dlYWtfZ2V0XG5mdW5jdGlvbiBjYW1sX2VwaGVfZ2V0X2tleSh4LCBpKSB7XG4gIGlmKGkgPCAwIHx8IGNhbWxfZXBoZV9rZXlfb2Zmc2V0ICsgaSA+PSB4Lmxlbmd0aClcbiAgICBjYW1sX2ludmFsaWRfYXJndW1lbnQgKFwiV2Vhay5nZXRfa2V5XCIpO1xuICB2YXIgd2VhayA9IHhbY2FtbF9lcGhlX2tleV9vZmZzZXQgKyBpIF07XG4gIGlmKGdsb2JhbFRoaXMuV2Vha1JlZiAmJiB3ZWFrIGluc3RhbmNlb2YgZ2xvYmFsVGhpcy5XZWFrUmVmKSB3ZWFrID0gd2Vhay5kZXJlZigpO1xuICByZXR1cm4gKHdlYWs9PT11bmRlZmluZWQpPzA6WzAsIHdlYWtdO1xufVxuLy9Qcm92aWRlczogY2FtbF9lcGhlX2dldF9rZXlfY29weVxuLy9SZXF1aXJlczogY2FtbF9lcGhlX2dldF9rZXksY2FtbF9lcGhlX2tleV9vZmZzZXRcbi8vUmVxdWlyZXM6IGNhbWxfb2JqX2R1cCwgY2FtbF9pbnZhbGlkX2FyZ3VtZW50XG4vL0FsaWFzOiBjYW1sX3dlYWtfZ2V0X2NvcHlcbmZ1bmN0aW9uIGNhbWxfZXBoZV9nZXRfa2V5X2NvcHkoeCwgaSkge1xuICBpZihpIDwgMCB8fCBjYW1sX2VwaGVfa2V5X29mZnNldCArIGkgPj0geC5sZW5ndGgpXG4gICAgY2FtbF9pbnZhbGlkX2FyZ3VtZW50IChcIldlYWsuZ2V0X2NvcHlcIik7XG4gIHZhciB5ID0gY2FtbF9lcGhlX2dldF9rZXkoeCwgaSk7XG4gIGlmICh5ID09PSAwKSByZXR1cm4geTtcbiAgdmFyIHogPSB5WzFdO1xuICBpZiAoeiBpbnN0YW5jZW9mIEFycmF5KSByZXR1cm4gWzAsIGNhbWxfb2JqX2R1cCh6KV07XG4gIHJldHVybiB5O1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2VwaGVfY2hlY2tfa2V5IG11dGFibGVcbi8vUmVxdWlyZXM6IGNhbWxfZXBoZV9rZXlfb2Zmc2V0XG4vL0FsaWFzOiBjYW1sX3dlYWtfY2hlY2tcbmZ1bmN0aW9uIGNhbWxfZXBoZV9jaGVja19rZXkoeCwgaSkge1xuICB2YXIgd2VhayA9IHhbY2FtbF9lcGhlX2tleV9vZmZzZXQgKyBpXTtcbiAgaWYoZ2xvYmFsVGhpcy5XZWFrUmVmICYmIHdlYWsgaW5zdGFuY2VvZiBnbG9iYWxUaGlzLldlYWtSZWYpIHdlYWsgPSB3ZWFrLmRlcmVmKCk7XG4gIGlmKHdlYWs9PT11bmRlZmluZWQpXG4gICAgcmV0dXJuIDA7XG4gIGVsc2VcbiAgICByZXR1cm4gMTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9lcGhlX2JsaXRfa2V5XG4vL1JlcXVpcmVzOiBjYW1sX2FycmF5X2JsaXRcbi8vUmVxdWlyZXM6IGNhbWxfZXBoZV9rZXlfb2Zmc2V0XG4vL0FsaWFzOiBjYW1sX3dlYWtfYmxpdFxuZnVuY3Rpb24gY2FtbF9lcGhlX2JsaXRfa2V5KGExLCBpMSwgYTIsIGkyLCBsZW4pIHtcbiAgLy8gbWludXMgb25lIGJlY2F1c2UgY2FtbF9hcnJheV9ibGl0IHdvcmtzIG9uIG9jYW1sIGFycmF5XG4gIGNhbWxfYXJyYXlfYmxpdChhMSwgY2FtbF9lcGhlX2tleV9vZmZzZXQgKyBpMSAtIDEsXG4gICAgICAgICAgICAgICAgICBhMiwgY2FtbF9lcGhlX2tleV9vZmZzZXQgKyBpMiAtIDEsXG4gICAgICAgICAgICAgICAgICBsZW4pO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9lcGhlX2JsaXRfZGF0YVxuLy9SZXF1aXJlczogY2FtbF9lcGhlX2RhdGFfb2Zmc2V0LCBjYW1sX2VwaGVfc2V0X2RhdGEsIGNhbWxfZXBoZV91bnNldF9kYXRhXG5mdW5jdGlvbiBjYW1sX2VwaGVfYmxpdF9kYXRhKHNyYywgZHN0KXtcbiAgdmFyIG4gPSBzcmNbY2FtbF9lcGhlX2RhdGFfb2Zmc2V0XTtcbiAgaWYobiA9PT0gdW5kZWZpbmVkKSBjYW1sX2VwaGVfdW5zZXRfZGF0YShkc3QpO1xuICBlbHNlIGNhbWxfZXBoZV9zZXRfZGF0YShkc3QsIG4pO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9lcGhlX2dldF9kYXRhXG4vL1JlcXVpcmVzOiBjYW1sX2VwaGVfZGF0YV9vZmZzZXRcbmZ1bmN0aW9uIGNhbWxfZXBoZV9nZXRfZGF0YSh4KXtcbiAgaWYoeFtjYW1sX2VwaGVfZGF0YV9vZmZzZXRdID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIDA7XG4gIGVsc2VcbiAgICByZXR1cm4gWzAsIHhbY2FtbF9lcGhlX2RhdGFfb2Zmc2V0XV07XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfZXBoZV9nZXRfZGF0YV9jb3B5XG4vL1JlcXVpcmVzOiBjYW1sX2VwaGVfZGF0YV9vZmZzZXRcbi8vUmVxdWlyZXM6IGNhbWxfb2JqX2R1cFxuZnVuY3Rpb24gY2FtbF9lcGhlX2dldF9kYXRhX2NvcHkoeCl7XG4gIGlmKHhbY2FtbF9lcGhlX2RhdGFfb2Zmc2V0XSA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiAwO1xuICBlbHNlXG4gICAgcmV0dXJuIFswLCBjYW1sX29ial9kdXAoeFtjYW1sX2VwaGVfZGF0YV9vZmZzZXRdKV07XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfZXBoZV9zZXRfZGF0YVxuLy9SZXF1aXJlczogY2FtbF9lcGhlX2RhdGFfb2Zmc2V0LCBjYW1sX2VwaGVfa2V5X29mZnNldCwgY2FtbF9lcGhlX3Vuc2V0X2RhdGFcbmZ1bmN0aW9uIGNhbWxfZXBoZV9zZXRfZGF0YSh4LCBkYXRhKXtcbiAgaWYoZ2xvYmFsVGhpcy5GaW5hbGl6YXRpb25SZWdpc3RyeSAmJiBnbG9iYWxUaGlzLldlYWtSZWYpIHtcbiAgICBpZighICh4WzFdIGluc3RhbmNlb2YgZ2xvYmFsVGhpcy5GaW5hbGl6YXRpb25SZWdpc3RyeSkpIHtcbiAgICAgIHhbMV0gPSBuZXcgZ2xvYmFsVGhpcy5GaW5hbGl6YXRpb25SZWdpc3RyeShmdW5jdGlvbiAoKSB7IGNhbWxfZXBoZV91bnNldF9kYXRhKHgpIH0pO1xuICAgICAgLy9yZWdpc3RlciBhbGwga2V5c1xuICAgICAgZm9yKHZhciBqID0gY2FtbF9lcGhlX2tleV9vZmZzZXQ7IGogPCB4Lmxlbmd0aDsgaisrKXtcbiAgICAgICAgdmFyIGtleSA9IHhbal07XG4gICAgICAgIGlmKGtleSBpbnN0YW5jZW9mIGdsb2JhbFRoaXMuV2Vha1JlZikge1xuICAgICAgICAgIGtleSA9IGtleS5kZXJlZigpO1xuICAgICAgICAgIGlmKGtleSkgeFsxXS5yZWdpc3RlcihrZXksIHVuZGVmaW5lZCwga2V5KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICB4W2NhbWxfZXBoZV9kYXRhX29mZnNldF0gPSBkYXRhO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9lcGhlX3Vuc2V0X2RhdGFcbi8vUmVxdWlyZXM6IGNhbWxfZXBoZV9kYXRhX29mZnNldCwgY2FtbF9lcGhlX2tleV9vZmZzZXRcbmZ1bmN0aW9uIGNhbWxfZXBoZV91bnNldF9kYXRhKHgpe1xuICBpZihnbG9iYWxUaGlzLkZpbmFsaXphdGlvblJlZ2lzdHJ5ICYmIGdsb2JhbFRoaXMuV2Vha1JlZikge1xuICAgIGlmKHhbMV0gaW5zdGFuY2VvZiBnbG9iYWxUaGlzLkZpbmFsaXphdGlvblJlZ2lzdHJ5KXtcbiAgICAgIC8vdW5yZWdpc3RlciBhbGwga2V5c1xuICAgICAgZm9yKHZhciBqID0gY2FtbF9lcGhlX2tleV9vZmZzZXQ7IGogPCB4Lmxlbmd0aDsgaisrKXtcbiAgICAgICAgdmFyIGtleSA9IHhbal07XG4gICAgICAgIGlmKGtleSBpbnN0YW5jZW9mIGdsb2JhbFRoaXMuV2Vha1JlZikge1xuICAgICAgICAgIGtleSA9IGtleS5kZXJlZigpO1xuICAgICAgICAgIGlmKGtleSkgeFsxXS51bnJlZ2lzdGVyKGtleSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgeFtjYW1sX2VwaGVfZGF0YV9vZmZzZXRdID0gdW5kZWZpbmVkO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9lcGhlX2NoZWNrX2RhdGFcbi8vUmVxdWlyZXM6IGNhbWxfZXBoZV9kYXRhX29mZnNldFxuZnVuY3Rpb24gY2FtbF9lcGhlX2NoZWNrX2RhdGEoeCl7XG4gIGlmKHhbY2FtbF9lcGhlX2RhdGFfb2Zmc2V0XSA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiAwO1xuICBlbHNlXG4gICAgcmV0dXJuIDE7XG59XG4iLCJcblxuLy9Qcm92aWRlczogY2FtbF9nY19taW5vclxuZnVuY3Rpb24gY2FtbF9nY19taW5vcih1bml0KXtcbiAgLy9hdmFpbGFibGUgd2l0aCBbbm9kZSAtLWV4cG9zZS1nY11cbiAgaWYodHlwZW9mIGdsb2JhbFRoaXMuZ2MgPT0gJ2Z1bmN0aW9uJykgZ2xvYmFsVGhpcy5nYyh0cnVlKTtcbiAgcmV0dXJuIDBcbn1cbi8vUHJvdmlkZXM6IGNhbWxfZ2NfbWFqb3JcbmZ1bmN0aW9uIGNhbWxfZ2NfbWFqb3IodW5pdCl7XG4gIC8vYXZhaWxhYmxlIHdpdGggW25vZGUgLS1leHBvc2UtZ2NdXG4gIGlmKHR5cGVvZiBnbG9iYWxUaGlzLmdjID09ICdmdW5jdGlvbicpIGdsb2JhbFRoaXMuZ2MoKTtcbiAgcmV0dXJuIDBcbn1cbi8vUHJvdmlkZXM6IGNhbWxfZ2NfZnVsbF9tYWpvclxuZnVuY3Rpb24gY2FtbF9nY19mdWxsX21ham9yKHVuaXQpe1xuICAvL2F2YWlsYWJsZSB3aXRoIFtub2RlIC0tZXhwb3NlLWdjXVxuICBpZih0eXBlb2YgZ2xvYmFsVGhpcy5nYyA9PSAnZnVuY3Rpb24nKSBnbG9iYWxUaGlzLmdjKCk7XG4gIHJldHVybiAwXG59XG4vL1Byb3ZpZGVzOiBjYW1sX2djX2NvbXBhY3Rpb25cbmZ1bmN0aW9uIGNhbWxfZ2NfY29tcGFjdGlvbigpeyByZXR1cm4gMH1cbi8vUHJvdmlkZXM6IGNhbWxfZ2NfY291bnRlcnNcbmZ1bmN0aW9uIGNhbWxfZ2NfY291bnRlcnMoKSB7IHJldHVybiBbMjU0LDAsMCwwXSB9XG4vL1Byb3ZpZGVzOiBjYW1sX2djX3F1aWNrX3N0YXRcbi8vVmVyc2lvbjogPj0gNC4xMlxuZnVuY3Rpb24gY2FtbF9nY19xdWlja19zdGF0KCl7XG4gIHJldHVybiBbMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDBdXG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfZ2NfcXVpY2tfc3RhdFxuLy9WZXJzaW9uOiA8IDQuMTJcbmZ1bmN0aW9uIGNhbWxfZ2NfcXVpY2tfc3RhdCgpe1xuICByZXR1cm4gWzAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMF1cbn1cbi8vUHJvdmlkZXM6IGNhbWxfZ2Nfc3RhdFxuLy9SZXF1aXJlczogY2FtbF9nY19xdWlja19zdGF0XG5mdW5jdGlvbiBjYW1sX2djX3N0YXQoKSB7XG4gIHJldHVybiBjYW1sX2djX3F1aWNrX3N0YXQoKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9nY19zZXRcbmZ1bmN0aW9uIGNhbWxfZ2Nfc2V0KF9jb250cm9sKSB7XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2djX2dldFxuZnVuY3Rpb24gY2FtbF9nY19nZXQoKXtcbiAgcmV0dXJuIFswLDAsMCwwLDAsMCwwLDAsMCwwLDAsMF1cbn1cblxuLy9Qcm92aWRlczogY2FtbF9tZW1wcm9mX3NldFxuZnVuY3Rpb24gY2FtbF9tZW1wcm9mX3NldChfY29udHJvbCkge1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9maW5hbF9yZWdpc3RlciBjb25zdFxuZnVuY3Rpb24gY2FtbF9maW5hbF9yZWdpc3RlciAoKSB7IHJldHVybiAwOyB9XG5cbi8vUHJvdmlkZXM6IGNhbWxfZmluYWxfcmVnaXN0ZXJfY2FsbGVkX3dpdGhvdXRfdmFsdWVcbnZhciBhbGxfZmluYWxpemVycyA9IG5ldyBnbG9iYWxUaGlzLlNldCgpXG5mdW5jdGlvbiBjYW1sX2ZpbmFsX3JlZ2lzdGVyX2NhbGxlZF93aXRob3V0X3ZhbHVlIChjYiwgYSkge1xuICBpZihnbG9iYWxUaGlzLkZpbmFsaXphdGlvblJlZ2lzdHJ5ICYmIGEgaW5zdGFuY2VvZiBPYmplY3QpIHtcbiAgICB2YXIgeCA9IG5ldyBnbG9iYWxUaGlzLkZpbmFsaXphdGlvblJlZ2lzdHJ5KGZ1bmN0aW9uICh4KXthbGxfZmluYWxpemVycy5kZWxldGUoeCk7IGNiKDApOyByZXR1cm47fSk7XG4gICAgeC5yZWdpc3RlcihhLHgpO1xuICAgIGFsbF9maW5hbGl6ZXJzLmFkZCh4KTtcbiAgfVxuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9maW5hbF9yZWxlYXNlIGNvbnN0XG5mdW5jdGlvbiBjYW1sX2ZpbmFsX3JlbGVhc2UgKCkgeyByZXR1cm4gMDsgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21lbXByb2Zfc3RhcnRcbmZ1bmN0aW9uIGNhbWxfbWVtcHJvZl9zdGFydChyYXRlLHN0YWNrX3NpemUsdHJhY2tlcil7XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX21lbXByb2Zfc3RvcFxuZnVuY3Rpb24gY2FtbF9tZW1wcm9mX3N0b3AodW5pdCkge1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9tZW1wcm9mX2Rpc2NhcmRcbmZ1bmN0aW9uIGNhbWxfbWVtcHJvZl9kaXNjYXJkKHQpIHsgcmV0dXJuIDAgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2V2ZW50bG9nX3Jlc3VtZVxuZnVuY3Rpb24gY2FtbF9ldmVudGxvZ19yZXN1bWUodW5pdCkgeyByZXR1cm4gMDsgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2V2ZW50bG9nX3BhdXNlXG5mdW5jdGlvbiBjYW1sX2V2ZW50bG9nX3BhdXNlKHVuaXQpIHsgcmV0dXJuIDA7IH1cblxuLy9Qcm92aWRlczogY2FtbF9nY19odWdlX2ZhbGxiYWNrX2NvdW50XG5mdW5jdGlvbiBjYW1sX2djX2h1Z2VfZmFsbGJhY2tfY291bnQodW5pdCkgeyByZXR1cm4gMDsgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2djX21ham9yX3NsaWNlXG5mdW5jdGlvbiBjYW1sX2djX21ham9yX3NsaWNlKHdvcmspIHsgcmV0dXJuIDA7IH1cblxuLy9Qcm92aWRlczogY2FtbF9nY19taW5vcl93b3Jkc1xuZnVuY3Rpb24gY2FtbF9nY19taW5vcl93b3Jkcyh1bml0KSB7IHJldHVybiAwOyB9XG5cbi8vUHJvdmlkZXM6IGNhbWxfZ2V0X21pbm9yX2ZyZWVcbmZ1bmN0aW9uIGNhbWxfZ2V0X21pbm9yX2ZyZWUodW5pdCkgeyByZXR1cm4gMDsgfVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2dldF9tYWpvcl9idWNrZXRcbmZ1bmN0aW9uIGNhbWxfZ2V0X21ham9yX2J1Y2tldChuKSB7IHJldHVybiAwOyB9XG5cbi8vUHJvdmlkZXM6IGNhbWxfZ2V0X21ham9yX2NyZWRpdFxuZnVuY3Rpb24gY2FtbF9nZXRfbWFqb3JfY3JlZGl0KG4pIHsgcmV0dXJuIDA7IH1cbiIsIi8vIEpzX29mX29jYW1sIHJ1bnRpbWUgc3VwcG9ydFxuLy8gaHR0cDovL3d3dy5vY3NpZ2VuLm9yZy9qc19vZl9vY2FtbC9cbi8vXG4vLyBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuLy8gaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4vLyB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCB3aXRoIGxpbmtpbmcgZXhjZXB0aW9uO1xuLy8gZWl0aGVyIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy9cbi8vIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbi8vIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy9cbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuLy8gYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuXG5cbi8vLy8vLy8vLy8vLy8gRm9ybWF0XG5cbi8vUHJvdmlkZXM6IGNhbWxfcGFyc2VfZm9ybWF0XG4vL1JlcXVpcmVzOiBjYW1sX2pzYnl0ZXNfb2Zfc3RyaW5nLCBjYW1sX2ludmFsaWRfYXJndW1lbnRcbmZ1bmN0aW9uIGNhbWxfcGFyc2VfZm9ybWF0IChmbXQpIHtcbiAgZm10ID0gY2FtbF9qc2J5dGVzX29mX3N0cmluZyhmbXQpO1xuICB2YXIgbGVuID0gZm10Lmxlbmd0aDtcbiAgaWYgKGxlbiA+IDMxKSBjYW1sX2ludmFsaWRfYXJndW1lbnQoXCJmb3JtYXRfaW50OiBmb3JtYXQgdG9vIGxvbmdcIik7XG4gIHZhciBmID1cbiAgICAgIHsganVzdGlmeTonKycsIHNpZ25zdHlsZTonLScsIGZpbGxlcjonICcsIGFsdGVybmF0ZTpmYWxzZSxcbiAgICAgICAgYmFzZTowLCBzaWduZWRjb252OmZhbHNlLCB3aWR0aDowLCB1cHBlcmNhc2U6ZmFsc2UsXG4gICAgICAgIHNpZ246MSwgcHJlYzotMSwgY29udjonZicgfTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIHZhciBjID0gZm10LmNoYXJBdChpKTtcbiAgICBzd2l0Y2ggKGMpIHtcbiAgICBjYXNlICctJzpcbiAgICAgIGYuanVzdGlmeSA9ICctJzsgYnJlYWs7XG4gICAgY2FzZSAnKyc6IGNhc2UgJyAnOlxuICAgICAgZi5zaWduc3R5bGUgPSBjOyBicmVhaztcbiAgICBjYXNlICcwJzpcbiAgICAgIGYuZmlsbGVyID0gJzAnOyBicmVhaztcbiAgICBjYXNlICcjJzpcbiAgICAgIGYuYWx0ZXJuYXRlID0gdHJ1ZTsgYnJlYWs7XG4gICAgY2FzZSAnMSc6IGNhc2UgJzInOiBjYXNlICczJzogY2FzZSAnNCc6IGNhc2UgJzUnOlxuICAgIGNhc2UgJzYnOiBjYXNlICc3JzogY2FzZSAnOCc6IGNhc2UgJzknOlxuICAgICAgZi53aWR0aCA9IDA7XG4gICAgICB3aGlsZSAoYz1mbXQuY2hhckNvZGVBdChpKSAtIDQ4LCBjID49IDAgJiYgYyA8PSA5KSB7XG4gICAgICAgIGYud2lkdGggPSBmLndpZHRoICogMTAgKyBjOyBpKytcbiAgICAgIH1cbiAgICAgIGktLTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJy4nOlxuICAgICAgZi5wcmVjID0gMDtcbiAgICAgIGkrKztcbiAgICAgIHdoaWxlIChjPWZtdC5jaGFyQ29kZUF0KGkpIC0gNDgsIGMgPj0gMCAmJiBjIDw9IDkpIHtcbiAgICAgICAgZi5wcmVjID0gZi5wcmVjICogMTAgKyBjOyBpKytcbiAgICAgIH1cbiAgICAgIGktLTtcbiAgICBjYXNlICdkJzogY2FzZSAnaSc6XG4gICAgICBmLnNpZ25lZGNvbnYgPSB0cnVlOyAvKiBmYWxsdGhyb3VnaCAqL1xuICAgIGNhc2UgJ3UnOlxuICAgICAgZi5iYXNlID0gMTA7IGJyZWFrO1xuICAgIGNhc2UgJ3gnOlxuICAgICAgZi5iYXNlID0gMTY7IGJyZWFrO1xuICAgIGNhc2UgJ1gnOlxuICAgICAgZi5iYXNlID0gMTY7IGYudXBwZXJjYXNlID0gdHJ1ZTsgYnJlYWs7XG4gICAgY2FzZSAnbyc6XG4gICAgICBmLmJhc2UgPSA4OyBicmVhaztcbiAgICBjYXNlICdlJzogY2FzZSAnZic6IGNhc2UgJ2cnOlxuICAgICAgZi5zaWduZWRjb252ID0gdHJ1ZTsgZi5jb252ID0gYzsgYnJlYWs7XG4gICAgY2FzZSAnRSc6IGNhc2UgJ0YnOiBjYXNlICdHJzpcbiAgICAgIGYuc2lnbmVkY29udiA9IHRydWU7IGYudXBwZXJjYXNlID0gdHJ1ZTtcbiAgICAgIGYuY29udiA9IGMudG9Mb3dlckNhc2UgKCk7IGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZjtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9maW5pc2hfZm9ybWF0dGluZ1xuLy9SZXF1aXJlczogY2FtbF9zdHJpbmdfb2ZfanNieXRlc1xuZnVuY3Rpb24gY2FtbF9maW5pc2hfZm9ybWF0dGluZyhmLCByYXdidWZmZXIpIHtcbiAgaWYgKGYudXBwZXJjYXNlKSByYXdidWZmZXIgPSByYXdidWZmZXIudG9VcHBlckNhc2UoKTtcbiAgdmFyIGxlbiA9IHJhd2J1ZmZlci5sZW5ndGg7XG4gIC8qIEFkanVzdCBsZW4gdG8gcmVmbGVjdCBhZGRpdGlvbmFsIGNoYXJzIChzaWduLCBldGMpICovXG4gIGlmIChmLnNpZ25lZGNvbnYgJiYgKGYuc2lnbiA8IDAgfHwgZi5zaWduc3R5bGUgIT0gJy0nKSkgbGVuKys7XG4gIGlmIChmLmFsdGVybmF0ZSkge1xuICAgIGlmIChmLmJhc2UgPT0gOCkgbGVuICs9IDE7XG4gICAgaWYgKGYuYmFzZSA9PSAxNikgbGVuICs9IDI7XG4gIH1cbiAgLyogRG8gdGhlIGZvcm1hdHRpbmcgKi9cbiAgdmFyIGJ1ZmZlciA9IFwiXCI7XG4gIGlmIChmLmp1c3RpZnkgPT0gJysnICYmIGYuZmlsbGVyID09ICcgJylcbiAgICBmb3IgKHZhciBpID0gbGVuOyBpIDwgZi53aWR0aDsgaSsrKSBidWZmZXIgKz0gJyAnO1xuICBpZiAoZi5zaWduZWRjb252KSB7XG4gICAgaWYgKGYuc2lnbiA8IDApIGJ1ZmZlciArPSAnLSc7XG4gICAgZWxzZSBpZiAoZi5zaWduc3R5bGUgIT0gJy0nKSBidWZmZXIgKz0gZi5zaWduc3R5bGU7XG4gIH1cbiAgaWYgKGYuYWx0ZXJuYXRlICYmIGYuYmFzZSA9PSA4KSBidWZmZXIgKz0gJzAnO1xuICBpZiAoZi5hbHRlcm5hdGUgJiYgZi5iYXNlID09IDE2KSBidWZmZXIgKz0gZi51cHBlcmNhc2U/XCIwWFwiOlwiMHhcIjtcbiAgaWYgKGYuanVzdGlmeSA9PSAnKycgJiYgZi5maWxsZXIgPT0gJzAnKVxuICAgIGZvciAodmFyIGkgPSBsZW47IGkgPCBmLndpZHRoOyBpKyspIGJ1ZmZlciArPSAnMCc7XG4gIGJ1ZmZlciArPSByYXdidWZmZXI7XG4gIGlmIChmLmp1c3RpZnkgPT0gJy0nKVxuICAgIGZvciAodmFyIGkgPSBsZW47IGkgPCBmLndpZHRoOyBpKyspIGJ1ZmZlciArPSAnICc7XG4gIHJldHVybiBjYW1sX3N0cmluZ19vZl9qc2J5dGVzKGJ1ZmZlcik7XG59XG4iLCIvLyBKc19vZl9vY2FtbCBydW50aW1lIHN1cHBvcnRcbi8vIGh0dHA6Ly93d3cub2NzaWdlbi5vcmcvanNfb2Zfb2NhbWwvXG4vLyBDb3B5cmlnaHQgKEMpIDIwMTQgSHVnbyBIZXV6YXJkXG5cbi8vIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4vLyBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbi8vIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHdpdGggbGlua2luZyBleGNlcHRpb247XG4vLyBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG5cbi8vIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbi8vIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2Vcbi8vIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLlxuXG4vL1Byb3ZpZGVzOiBjYW1sX2dyX3N0YXRlXG52YXIgY2FtbF9ncl9zdGF0ZTtcblxuLy9Qcm92aWRlczogY2FtbF9ncl9zdGF0ZV9nZXRcbi8vUmVxdWlyZXM6IGNhbWxfZ3Jfc3RhdGVcbi8vUmVxdWlyZXM6IGNhbWxfbmFtZWRfdmFsdWUsIGNhbWxfc3RyaW5nX29mX2pzYnl0ZXNcbi8vUmVxdWlyZXM6IGNhbWxfbWF5YmVfYXR0YWNoX2JhY2t0cmFjZVxuZnVuY3Rpb24gY2FtbF9ncl9zdGF0ZV9nZXQoKSB7XG4gIGlmKGNhbWxfZ3Jfc3RhdGUpIHtcbiAgICByZXR1cm4gY2FtbF9ncl9zdGF0ZTtcbiAgfVxuICB0aHJvdyBjYW1sX21heWJlX2F0dGFjaF9iYWNrdHJhY2UoWzAsY2FtbF9uYW1lZF92YWx1ZShcIkdyYXBoaWNzLkdyYXBoaWNfZmFpbHVyZVwiKSwgY2FtbF9zdHJpbmdfb2ZfanNieXRlcyhcIk5vdCBpbml0aWFsaXplZFwiKV0pO1xufVxuLy9Qcm92aWRlczogY2FtbF9ncl9zdGF0ZV9zZXRcbi8vUmVxdWlyZXM6IGNhbWxfZ3Jfc3RhdGUsY2FtbF9ncl9zdGF0ZV9pbml0XG5mdW5jdGlvbiBjYW1sX2dyX3N0YXRlX3NldChjdHgpIHtcbiAgY2FtbF9ncl9zdGF0ZT1jdHg7XG4gIGNhbWxfZ3Jfc3RhdGVfaW5pdCgpXG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2dyX29wZW5fZ3JhcGhcbi8vUmVxdWlyZXM6IGNhbWxfZ3Jfc3RhdGVfY3JlYXRlXG4vL1JlcXVpcmVzOiBjYW1sX2dyX3N0YXRlX3NldFxuLy9SZXF1aXJlczogY2FtbF9mYWlsd2l0aFxuLy9SZXF1aXJlczogY2FtbF9qc3N0cmluZ19vZl9zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfZ3Jfb3Blbl9ncmFwaChpbmZvKXtcbiAgdmFyIGluZm8gPSBjYW1sX2pzc3RyaW5nX29mX3N0cmluZyhpbmZvKTtcbiAgZnVuY3Rpb24gZ2V0KG5hbWUpe1xuICAgIHZhciByZXMgPSBpbmZvLm1hdGNoKFwiKF58LCkgKlwiK25hbWUrXCIgKj0gKihbYS16QS1aMC05X10rKSAqKCx8JClcIik7XG4gICAgaWYocmVzKSByZXR1cm4gcmVzWzJdO1xuICB9XG4gIHZhciBzcGVjcyA9IFtdO1xuICBpZighKGluZm89PVwiXCIpKSBzcGVjcy5wdXNoKGluZm8pO1xuICB2YXIgdGFyZ2V0ID0gZ2V0KFwidGFyZ2V0XCIpO1xuICBpZighdGFyZ2V0KSB0YXJnZXQ9XCJcIjtcbiAgdmFyIHN0YXR1cyA9IGdldChcInN0YXR1c1wiKTtcbiAgaWYoIXN0YXR1cykgc3BlY3MucHVzaChcInN0YXR1cz0xXCIpXG5cbiAgdmFyIHcgPSBnZXQoXCJ3aWR0aFwiKTtcbiAgdyA9IHc/cGFyc2VJbnQodyk6MjAwO1xuICBzcGVjcy5wdXNoKFwid2lkdGg9XCIrdyk7XG5cbiAgdmFyIGggPSBnZXQoXCJoZWlnaHRcIik7XG4gIGggPSBoP3BhcnNlSW50KGgpOjIwMDtcbiAgc3BlY3MucHVzaChcImhlaWdodD1cIitoKTtcblxuICB2YXIgd2luID0gZ2xvYmFsVGhpcy5vcGVuKFwiYWJvdXQ6YmxhbmtcIix0YXJnZXQsc3BlY3Muam9pbihcIixcIikpO1xuICBpZighd2luKSB7Y2FtbF9mYWlsd2l0aChcIkdyYXBoaWNzLm9wZW5fZ3JhcGg6IGNhbm5vdCBvcGVuIHRoZSB3aW5kb3dcIil9XG4gIHZhciBkb2MgPSB3aW4uZG9jdW1lbnQ7XG4gIHZhciBjYW52YXMgPSBkb2MuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgY2FudmFzLndpZHRoID0gdztcbiAgY2FudmFzLmhlaWdodCA9IGg7XG4gIHZhciBjdHggPSBjYW1sX2dyX3N0YXRlX2NyZWF0ZShjYW52YXMsdyxoKTtcbiAgY3R4LnNldF90aXRsZSA9IGZ1bmN0aW9uICh0aXRsZSkge1xuICAgIGRvYy50aXRsZSA9IHRpdGxlO1xuICB9O1xuICBjYW1sX2dyX3N0YXRlX3NldChjdHgpO1xuICB2YXIgYm9keSA9IGRvYy5ib2R5O1xuICBib2R5LnN0eWxlLm1hcmdpbiA9IFwiMHB4XCI7XG4gIGJvZHkuYXBwZW5kQ2hpbGQoY2FudmFzKTtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfZ3Jfc3RhdGVfaW5pdFxuLy9SZXF1aXJlczogY2FtbF9ncl9zdGF0ZVxuLy9SZXF1aXJlczogY2FtbF9ncl9zZXRfY29sb3IsY2FtbF9ncl9tb3ZldG8sY2FtbF9ncl9yZXNpemVfd2luZG93XG4vL1JlcXVpcmVzOiBjYW1sX2dyX3NldF9saW5lX3dpZHRoLGNhbWxfZ3Jfc2V0X3RleHRfc2l6ZSxjYW1sX2dyX3NldF9mb250XG4vL1JlcXVpcmVzOiBjYW1sX2dyX3NldF93aW5kb3dfdGl0bGVcbmZ1bmN0aW9uIGNhbWxfZ3Jfc3RhdGVfaW5pdCgpe1xuICBjYW1sX2dyX21vdmV0byhjYW1sX2dyX3N0YXRlLngsY2FtbF9ncl9zdGF0ZS55KTtcbiAgY2FtbF9ncl9yZXNpemVfd2luZG93KGNhbWxfZ3Jfc3RhdGUud2lkdGgsY2FtbF9ncl9zdGF0ZS5oZWlnaHQpO1xuICBjYW1sX2dyX3NldF9saW5lX3dpZHRoKGNhbWxfZ3Jfc3RhdGUubGluZV93aWR0aCk7XG4gIGNhbWxfZ3Jfc2V0X3RleHRfc2l6ZShjYW1sX2dyX3N0YXRlLnRleHRfc2l6ZSk7XG4gIGNhbWxfZ3Jfc2V0X2ZvbnQoY2FtbF9ncl9zdGF0ZS5mb250KTtcbiAgY2FtbF9ncl9zZXRfY29sb3IoY2FtbF9ncl9zdGF0ZS5jb2xvcik7XG4gIGNhbWxfZ3Jfc2V0X3dpbmRvd190aXRsZShjYW1sX2dyX3N0YXRlLnRpdGxlKTtcbiAgLy9jYW1sX2dyX3Jlc2l6ZV93aW5kb3cgbWlnaHQgcmVzZXQgc29tZSBjYW52YXMnIHByb3BlcnRpZXNcbiAgY2FtbF9ncl9zdGF0ZS5jb250ZXh0LnRleHRCYXNlbGluZSA9ICdib3R0b20nO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2dyX3N0YXRlX2NyZWF0ZVxuLy9SZXF1aXJlczogY2FtbF9zdHJpbmdfb2ZfanNieXRlc1xuZnVuY3Rpb24gY2FtbF9ncl9zdGF0ZV9jcmVhdGUoY2FudmFzLHcsaCl7XG4gIHZhciBjb250ZXh0ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcbiAgcmV0dXJuIHtcbiAgICBjb250ZXh0OiBjb250ZXh0LFxuICAgIGNhbnZhcyA6IGNhbnZhcyxcbiAgICB4IDogMCxcbiAgICB5IDogMCxcbiAgICB3aWR0aCA6IHcsXG4gICAgaGVpZ2h0IDogaCxcbiAgICBsaW5lX3dpZHRoIDogMSxcbiAgICBmb250IDogY2FtbF9zdHJpbmdfb2ZfanNieXRlcyhcImZpeGVkXCIpLFxuICAgIHRleHRfc2l6ZSA6IDI2LFxuICAgIGNvbG9yIDogMHgwMDAwMDAsXG4gICAgdGl0bGUgOiBjYW1sX3N0cmluZ19vZl9qc2J5dGVzKFwiXCIpXG4gIH07XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfZ3JfZG9jX29mX3N0YXRlXG5mdW5jdGlvbiBjYW1sX2dyX2RvY19vZl9zdGF0ZShzdGF0ZSkge1xuICBpZihzdGF0ZS5jYW52YXMub3duZXJEb2N1bWVudClcbiAgICByZXR1cm4gc3RhdGUuY2FudmFzLm93bmVyRG9jdW1lbnQ7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfZ3JfY2xvc2VfZ3JhcGhcbi8vUmVxdWlyZXM6IGNhbWxfZ3Jfc3RhdGVfZ2V0XG5mdW5jdGlvbiBjYW1sX2dyX2Nsb3NlX2dyYXBoKCl7XG4gIHZhciBzID0gY2FtbF9ncl9zdGF0ZV9nZXQoKTtcbiAgcy5jYW52YXMud2lkdGggPSAwO1xuICBzLmNhbnZhcy5oZWlnaHQgPSAwO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9ncl9zZXRfd2luZG93X3RpdGxlXG4vL1JlcXVpcmVzOiBjYW1sX2dyX3N0YXRlX2dldFxuLy9SZXF1aXJlczogY2FtbF9qc3N0cmluZ19vZl9zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfZ3Jfc2V0X3dpbmRvd190aXRsZShuYW1lKXtcbiAgdmFyIHMgPSBjYW1sX2dyX3N0YXRlX2dldCgpO1xuICBzLnRpdGxlID0gbmFtZTtcbiAgdmFyIGpzbmFtZSA9IGNhbWxfanNzdHJpbmdfb2Zfc3RyaW5nKG5hbWUpO1xuICBpZihzLnNldF90aXRsZSkgcy5zZXRfdGl0bGUoanNuYW1lKTtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfZ3JfcmVzaXplX3dpbmRvd1xuLy9SZXF1aXJlczogY2FtbF9ncl9zdGF0ZV9nZXRcbmZ1bmN0aW9uIGNhbWxfZ3JfcmVzaXplX3dpbmRvdyh3LGgpe1xuICB2YXIgcyA9IGNhbWxfZ3Jfc3RhdGVfZ2V0KClcbiAgcy53aWR0aCA9IHc7XG4gIHMuaGVpZ2h0ID0gaDtcbiAgcy5jYW52YXMud2lkdGggPSB3O1xuICBzLmNhbnZhcy5oZWlnaHQgPSBoO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9ncl9jbGVhcl9ncmFwaFxuLy9SZXF1aXJlczogY2FtbF9ncl9zdGF0ZV9nZXRcbmZ1bmN0aW9uIGNhbWxfZ3JfY2xlYXJfZ3JhcGgoKXtcbiAgdmFyIHMgPSBjYW1sX2dyX3N0YXRlX2dldCgpO1xuICBzLmNhbnZhcy53aWR0aCA9IHMud2lkdGg7XG4gIHMuY2FudmFzLmhlaWdodCA9IHMuaGVpZ2h0O1xuICAvLyAgcy5jb250ZXh0LnN0cm9rZVJlY3QgKDAuLCAwLiwgcy53aWR0aCwgcy5oZWlnaHQpO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9ncl9zaXplX3hcbi8vUmVxdWlyZXM6IGNhbWxfZ3Jfc3RhdGVfZ2V0XG5mdW5jdGlvbiBjYW1sX2dyX3NpemVfeCgpe1xuICB2YXIgcyA9IGNhbWxfZ3Jfc3RhdGVfZ2V0KCk7XG4gIHJldHVybiBzLndpZHRoO1xufVxuLy9Qcm92aWRlczogY2FtbF9ncl9zaXplX3lcbi8vUmVxdWlyZXM6IGNhbWxfZ3Jfc3RhdGVfZ2V0XG5mdW5jdGlvbiBjYW1sX2dyX3NpemVfeSgpe1xuICB2YXIgcyA9IGNhbWxfZ3Jfc3RhdGVfZ2V0KCk7XG4gIHJldHVybiBzLmhlaWdodDtcbn1cblxuXG4vL1Byb3ZpZGVzOiBjYW1sX2dyX3NldF9jb2xvclxuLy9SZXF1aXJlczogY2FtbF9ncl9zdGF0ZV9nZXRcbmZ1bmN0aW9uIGNhbWxfZ3Jfc2V0X2NvbG9yKGNvbG9yKXtcbiAgdmFyIHMgPSBjYW1sX2dyX3N0YXRlX2dldCgpO1xuICBmdW5jdGlvbiBjb252ZXJ0KG51bWJlcikge1xuICAgIHZhciBzdHIgPSAnJyArIG51bWJlci50b1N0cmluZygxNik7XG4gICAgd2hpbGUgKHN0ci5sZW5ndGggPCAyKSBzdHIgPSAnMCcgKyBzdHI7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxuICB2YXJcbiAgciA9IChjb2xvciA+PiAxNikgJiAweGZmLFxuICBnID0gKGNvbG9yID4+IDgpICAmIDB4ZmYsXG4gIGIgPSAoY29sb3IgPj4gMCkgICYgMHhmZjtcbiAgcy5jb2xvcj1jb2xvcjtcbiAgdmFyIGNfc3RyID0gJyMnICsgY29udmVydChyKSArIGNvbnZlcnQoZykgKyBjb252ZXJ0KGIpO1xuICBzLmNvbnRleHQuZmlsbFN0eWxlID0gICBjX3N0cjtcbiAgcy5jb250ZXh0LnN0cm9rZVN0eWxlID0gY19zdHI7XG4gIHJldHVybiAwO1xufVxuLy9Qcm92aWRlczogY2FtbF9ncl9wbG90XG4vL1JlcXVpcmVzOiBjYW1sX2dyX3N0YXRlX2dldFxuZnVuY3Rpb24gY2FtbF9ncl9wbG90KHgseSl7XG4gIHZhciBzID0gY2FtbF9ncl9zdGF0ZV9nZXQoKTtcbiAgdmFyIGltPXMuY29udGV4dC5jcmVhdGVJbWFnZURhdGEoMSwxKTtcbiAgdmFyIGQgPSBpbS5kYXRhO1xuICB2YXIgY29sb3IgPSBzLmNvbG9yO1xuICBkWzBdID0gKGNvbG9yID4+IDE2KSAmIDB4ZmY7IC8vclxuICBkWzFdID0gKGNvbG9yID4+IDgpICAmIDB4ZmYsIC8vZ1xuICBkWzJdID0gKGNvbG9yID4+IDApICAmIDB4ZmY7IC8vYlxuICBkWzNdID0gMHhGRjsgLy9hXG4gIHMueD14O1xuICBzLnk9eTtcbiAgcy5jb250ZXh0LnB1dEltYWdlRGF0YShpbSx4LHMuaGVpZ2h0IC0geSk7XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2dyX3BvaW50X2NvbG9yXG4vL1JlcXVpcmVzOiBjYW1sX2dyX3N0YXRlX2dldFxuZnVuY3Rpb24gY2FtbF9ncl9wb2ludF9jb2xvcih4LHkpe1xuICB2YXIgcyA9IGNhbWxfZ3Jfc3RhdGVfZ2V0KCk7XG4gIHZhciBpbT1zLmNvbnRleHQuZ2V0SW1hZ2VEYXRhKHgscy5oZWlnaHQgLSB5LDEsMSk7XG4gIHZhciBkID0gaW0uZGF0YTtcbiAgcmV0dXJuIChkWzBdIDw8IDE2KSArIChkWzFdIDw8IDgpICsgZFsyXTtcbn1cbi8vUHJvdmlkZXM6IGNhbWxfZ3JfbW92ZXRvXG4vL1JlcXVpcmVzOiBjYW1sX2dyX3N0YXRlX2dldFxuZnVuY3Rpb24gY2FtbF9ncl9tb3ZldG8oeCx5KXtcbiAgdmFyIHMgPSBjYW1sX2dyX3N0YXRlX2dldCgpO1xuICBzLng9eDtcbiAgcy55PXk7XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2dyX2N1cnJlbnRfeFxuLy9SZXF1aXJlczogY2FtbF9ncl9zdGF0ZV9nZXRcbmZ1bmN0aW9uIGNhbWxfZ3JfY3VycmVudF94KCl7XG4gIHZhciBzID0gY2FtbF9ncl9zdGF0ZV9nZXQoKTtcbiAgcmV0dXJuIHMueFxufVxuLy9Qcm92aWRlczogY2FtbF9ncl9jdXJyZW50X3lcbi8vUmVxdWlyZXM6IGNhbWxfZ3Jfc3RhdGVfZ2V0XG5mdW5jdGlvbiBjYW1sX2dyX2N1cnJlbnRfeSgpe1xuICB2YXIgcyA9IGNhbWxfZ3Jfc3RhdGVfZ2V0KCk7XG4gIHJldHVybiBzLnlcbn1cbi8vUHJvdmlkZXM6IGNhbWxfZ3JfbGluZXRvXG4vL1JlcXVpcmVzOiBjYW1sX2dyX3N0YXRlX2dldFxuZnVuY3Rpb24gY2FtbF9ncl9saW5ldG8oeCx5KXtcbiAgdmFyIHMgPSBjYW1sX2dyX3N0YXRlX2dldCgpO1xuICBzLmNvbnRleHQuYmVnaW5QYXRoKCk7XG4gIHMuY29udGV4dC5tb3ZlVG8ocy54LHMuaGVpZ2h0IC0gcy55KTtcbiAgcy5jb250ZXh0LmxpbmVUbyh4LHMuaGVpZ2h0IC0geSk7XG4gIHMuY29udGV4dC5zdHJva2UoKTtcbiAgcy54PXg7XG4gIHMueT15O1xuICByZXR1cm4gMDtcbn1cbi8vUHJvdmlkZXM6IGNhbWxfZ3JfZHJhd19yZWN0XG4vL1JlcXVpcmVzOiBjYW1sX2dyX3N0YXRlX2dldFxuZnVuY3Rpb24gY2FtbF9ncl9kcmF3X3JlY3QoeCx5LHcsaCl7XG4gIHZhciBzID0gY2FtbF9ncl9zdGF0ZV9nZXQoKTtcbiAgcy5jb250ZXh0LnN0cm9rZVJlY3QoeCxzLmhlaWdodCAtIHksdywtaCk7XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2dyX2FyY19hdXhcbmZ1bmN0aW9uIGNhbWxfZ3JfYXJjX2F1eChjdHgsY3gsY3kscnkscngsYTEsYTIpe1xuICB3aGlsZShhMT5hMikgYTIrPTM2MDtcbiAgYTEgLz0gMTgwO1xuICBhMiAvPSAxODA7XG4gIHZhciByb3QgPSAwLHhQb3MseVBvcyx4UG9zX3ByZXYseVBvc19wcmV2O1xuICB2YXIgc3BhY2UgPSAyO1xuICB2YXIgbnVtID0gKCgoYTIgLSBhMSkgKiBNYXRoLlBJICogKChyeCtyeSkvMikpIC8gc3BhY2UpIHwgMDtcbiAgdmFyIGRlbHRhID0gKGEyIC0gYTEpICogTWF0aC5QSSAvIG51bTtcbiAgdmFyIGkgPSBhMSAqIE1hdGguUEk7XG4gIGZvciAodmFyIGo9MDtqPD1udW07aisrKXtcbiAgICB4UG9zID0gY3ggLSAocnggKiBNYXRoLnNpbihpKSkgKiBNYXRoLnNpbihyb3QgKiBNYXRoLlBJKSArIChyeSAqIE1hdGguY29zKGkpKSAqIE1hdGguY29zKHJvdCAqIE1hdGguUEkpO1xuICAgIHhQb3MgPSB4UG9zLnRvRml4ZWQoMik7XG4gICAgeVBvcyA9IGN5ICsgKHJ5ICogTWF0aC5jb3MoaSkpICogTWF0aC5zaW4ocm90ICogTWF0aC5QSSkgKyAocnggKiBNYXRoLnNpbihpKSkgKiBNYXRoLmNvcyhyb3QgKiBNYXRoLlBJKTtcbiAgICB5UG9zID0geVBvcy50b0ZpeGVkKDIpO1xuICAgIGlmIChqPT0wKSB7XG4gICAgICBjdHgubW92ZVRvKHhQb3MsIHlQb3MpO1xuICAgIH0gZWxzZSBpZiAoeFBvc19wcmV2IT14UG9zIHx8IHlQb3NfcHJldiE9eVBvcyl7XG4gICAgICBjdHgubGluZVRvKHhQb3MsIHlQb3MpO1xuICAgIH1cbiAgICB4UG9zX3ByZXY9eFBvcztcbiAgICB5UG9zX3ByZXY9eVBvcztcbiAgICBpLT0gZGVsdGE7Ly9jY3dcbiAgfVxuICByZXR1cm4gMDtcbn1cblxuXG4vL1Byb3ZpZGVzOiBjYW1sX2dyX2RyYXdfYXJjXG4vL1JlcXVpcmVzOiBjYW1sX2dyX3N0YXRlX2dldCwgY2FtbF9ncl9hcmNfYXV4XG5mdW5jdGlvbiBjYW1sX2dyX2RyYXdfYXJjKHgseSxyeCxyeSxhMSxhMil7XG4gIHZhciBzID0gY2FtbF9ncl9zdGF0ZV9nZXQoKTtcbiAgcy5jb250ZXh0LmJlZ2luUGF0aCgpO1xuICBjYW1sX2dyX2FyY19hdXgocy5jb250ZXh0LHgscy5oZWlnaHQgLSB5LHJ4LHJ5LGExLGEyKTtcbiAgcy5jb250ZXh0LnN0cm9rZSgpO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9ncl9zZXRfbGluZV93aWR0aFxuLy9SZXF1aXJlczogY2FtbF9ncl9zdGF0ZV9nZXRcbmZ1bmN0aW9uIGNhbWxfZ3Jfc2V0X2xpbmVfd2lkdGgodyl7XG4gIHZhciBzID0gY2FtbF9ncl9zdGF0ZV9nZXQoKTtcbiAgcy5saW5lX3dpZHRoID0gdztcbiAgcy5jb250ZXh0LmxpbmVXaWR0aCA9IHdcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfZ3JfZmlsbF9yZWN0XG4vL1JlcXVpcmVzOiBjYW1sX2dyX3N0YXRlX2dldFxuZnVuY3Rpb24gY2FtbF9ncl9maWxsX3JlY3QoeCx5LHcsaCl7XG4gIHZhciBzID0gY2FtbF9ncl9zdGF0ZV9nZXQoKTtcbiAgcy5jb250ZXh0LmZpbGxSZWN0KHgscy5oZWlnaHQgLSB5LHcsLWgpO1xuICByZXR1cm4gMDtcbn1cbi8vUHJvdmlkZXM6IGNhbWxfZ3JfZmlsbF9wb2x5XG4vL1JlcXVpcmVzOiBjYW1sX2dyX3N0YXRlX2dldFxuZnVuY3Rpb24gY2FtbF9ncl9maWxsX3BvbHkoYXIpe1xuICB2YXIgcyA9IGNhbWxfZ3Jfc3RhdGVfZ2V0KCk7XG4gIHMuY29udGV4dC5iZWdpblBhdGgoKTtcbiAgcy5jb250ZXh0Lm1vdmVUbyhhclsxXVsxXSxzLmhlaWdodCAtIGFyWzFdWzJdKTtcbiAgZm9yKHZhciBpID0gMjsgaSA8IGFyLmxlbmd0aDsgaSsrKVxuICAgIHMuY29udGV4dC5saW5lVG8oYXJbaV1bMV0scy5oZWlnaHQgLSBhcltpXVsyXSk7XG4gIHMuY29udGV4dC5saW5lVG8oYXJbMV1bMV0scy5oZWlnaHQgLSBhclsxXVsyXSk7XG4gIHMuY29udGV4dC5maWxsKCk7XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2dyX2ZpbGxfYXJjXG4vL1JlcXVpcmVzOiBjYW1sX2dyX3N0YXRlX2dldCwgY2FtbF9ncl9hcmNfYXV4XG5mdW5jdGlvbiBjYW1sX2dyX2ZpbGxfYXJjKHgseSxyeCxyeSxhMSxhMil7XG4gIHZhciBzID0gY2FtbF9ncl9zdGF0ZV9nZXQoKTtcbiAgcy5jb250ZXh0LmJlZ2luUGF0aCgpO1xuICBjYW1sX2dyX2FyY19hdXgocy5jb250ZXh0LHgscy5oZWlnaHQgLSB5LHJ4LHJ5LGExLGEyKTtcbiAgcy5jb250ZXh0LmZpbGwoKTtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfZ3JfZHJhd19zdHJcbi8vUmVxdWlyZXM6IGNhbWxfZ3Jfc3RhdGVfZ2V0XG5mdW5jdGlvbiBjYW1sX2dyX2RyYXdfc3RyKHN0cil7XG4gIHZhciBzID0gY2FtbF9ncl9zdGF0ZV9nZXQoKTtcbiAgdmFyIG0gPSBzLmNvbnRleHQubWVhc3VyZVRleHQoc3RyKTtcbiAgdmFyIGR4ID0gbS53aWR0aDtcbiAgcy5jb250ZXh0LmZpbGxUZXh0KHN0cixzLngscy5oZWlnaHQgLSBzLnkpO1xuICBzLnggKz0gZHggfCAwO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9ncl9kcmF3X2NoYXJcbi8vUmVxdWlyZXM6IGNhbWxfZ3JfZHJhd19zdHJcbmZ1bmN0aW9uIGNhbWxfZ3JfZHJhd19jaGFyKGMpe1xuICBjYW1sX2dyX2RyYXdfc3RyKFN0cmluZy5mcm9tQ2hhckNvZGUoYykpO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9ncl9kcmF3X3N0cmluZ1xuLy9SZXF1aXJlczogY2FtbF9ncl9kcmF3X3N0clxuLy9SZXF1aXJlczogY2FtbF9qc3N0cmluZ19vZl9zdHJpbmdcbmZ1bmN0aW9uIGNhbWxfZ3JfZHJhd19zdHJpbmcoc3RyKXtcbiAgY2FtbF9ncl9kcmF3X3N0cihjYW1sX2pzc3RyaW5nX29mX3N0cmluZyhzdHIpKTtcbiAgcmV0dXJuIDA7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfZ3Jfc2V0X2ZvbnRcbi8vUmVxdWlyZXM6IGNhbWxfZ3Jfc3RhdGVfZ2V0XG4vL1JlcXVpcmVzOiBjYW1sX2pzc3RyaW5nX29mX3N0cmluZ1xuZnVuY3Rpb24gY2FtbF9ncl9zZXRfZm9udChmKXtcbiAgdmFyIHMgPSBjYW1sX2dyX3N0YXRlX2dldCgpO1xuICBzLmZvbnQgPSBmO1xuICBzLmNvbnRleHQuZm9udCA9IHMudGV4dF9zaXplICsgXCJweCBcIiArIGNhbWxfanNzdHJpbmdfb2Zfc3RyaW5nKHMuZm9udCk7XG4gIHJldHVybiAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2dyX3NldF90ZXh0X3NpemVcbi8vUmVxdWlyZXM6IGNhbWxfZ3Jfc3RhdGVfZ2V0XG4vL1JlcXVpcmVzOiBjYW1sX2pzc3RyaW5nX29mX3N0cmluZ1xuZnVuY3Rpb24gY2FtbF9ncl9zZXRfdGV4dF9zaXplKHNpemUpe1xuICB2YXIgcyA9IGNhbWxfZ3Jfc3RhdGVfZ2V0KCk7XG4gIHMudGV4dF9zaXplID0gc2l6ZTtcbiAgcy5jb250ZXh0LmZvbnQgPSBzLnRleHRfc2l6ZSArIFwicHggXCIgKyBjYW1sX2pzc3RyaW5nX29mX3N0cmluZyhzLmZvbnQpO1xuICByZXR1cm4gMDtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9ncl90ZXh0X3NpemVcbi8vUmVxdWlyZXM6IGNhbWxfZ3Jfc3RhdGVfZ2V0XG4vL1JlcXVpcmVzOiBjYW1sX2pzc3RyaW5nX29mX3N0cmluZ1xuZnVuY3Rpb24gY2FtbF9ncl90ZXh0X3NpemUodHh0KXtcbiAgdmFyIHMgPSBjYW1sX2dyX3N0YXRlX2dldCgpO1xuICB2YXIgdyA9IHMuY29udGV4dC5tZWFzdXJlVGV4dChjYW1sX2pzc3RyaW5nX29mX3N0cmluZyh0eHQpKS53aWR0aDtcbiAgcmV0dXJuIFswLHcscy50ZXh0X3NpemVdO1xufVxuXG5cbi8vUHJvdmlkZXM6IGNhbWxfZ3JfbWFrZV9pbWFnZVxuLy9SZXF1aXJlczogY2FtbF9ncl9zdGF0ZV9nZXRcbmZ1bmN0aW9uIGNhbWxfZ3JfbWFrZV9pbWFnZShhcnIpe1xuICB2YXIgcyA9IGNhbWxfZ3Jfc3RhdGVfZ2V0KCk7XG4gIHZhciBoID0gYXJyLmxlbmd0aCAtIDEgO1xuICB2YXIgdyA9IGFyclsxXS5sZW5ndGggLSAxO1xuICB2YXIgaW0gPSBzLmNvbnRleHQuY3JlYXRlSW1hZ2VEYXRhKHcsaCk7XG4gIGZvcih2YXIgaT0wO2k8aDtpKyspe1xuICAgIGZvcih2YXIgaj0wO2o8dztqKyspe1xuICAgICAgdmFyIGMgPSBhcnJbaSsxXVtqKzFdO1xuICAgICAgdmFyIG8gPSBpKih3KjQpICsgKGogKiA0KTtcbiAgICAgIGlmKGMgPT0gLTEpIHtcbiAgICAgICAgaW0uZGF0YVtvICsgMF0gPSAwO1xuICAgICAgICBpbS5kYXRhW28gKyAxXSA9IDA7XG4gICAgICAgIGltLmRhdGFbbyArIDJdID0gMDtcbiAgICAgICAgaW0uZGF0YVtvICsgM10gPSAwO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaW0uZGF0YVtvICsgMF0gPSBjID4+IDE2ICYgMHhmZjtcbiAgICAgICAgaW0uZGF0YVtvICsgMV0gPSBjID4+ICA4ICYgMHhmZjtcbiAgICAgICAgaW0uZGF0YVtvICsgMl0gPSBjID4+ICAwICYgMFhmZjtcbiAgICAgICAgaW0uZGF0YVtvICsgM10gPSAweGZmO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gaW1cbn1cbi8vUHJvdmlkZXM6IGNhbWxfZ3JfZHVtcF9pbWFnZVxuLy9SZXF1aXJlczogY2FtbF9ncl9zdGF0ZV9nZXRcbmZ1bmN0aW9uIGNhbWxfZ3JfZHVtcF9pbWFnZShpbSl7XG4gIHZhciBkYXRhID0gWzBdXG4gIGZvcih2YXIgaT0wOyBpPGltLmhlaWdodDtpKyspe1xuICAgIGRhdGFbaSsxXSA9IFswXVxuICAgIGZvcih2YXIgaj0wOyBqPGltLndpZHRoO2orKyl7XG4gICAgICB2YXIgbyA9IGkqKGltLndpZHRoKjQpICsgKGogKiA0KSxcbiAgICAgICAgICByID0gaW0uZGF0YVtvKzBdLFxuICAgICAgICAgIGcgPSBpbS5kYXRhW28rMV0sXG4gICAgICAgICAgYiA9IGltLmRhdGFbbysyXTtcbiAgICAgIGRhdGFbaSsxXVtqKzFdID0gKHIgPDwgMTYpICsgKGcgPDwgOCkgKyBiXG4gICAgfVxuICB9XG4gIHJldHVybiBkYXRhXG59XG4vL1Byb3ZpZGVzOiBjYW1sX2dyX2RyYXdfaW1hZ2Vcbi8vUmVxdWlyZXM6IGNhbWxfZ3Jfc3RhdGVfZ2V0XG5mdW5jdGlvbiBjYW1sX2dyX2RyYXdfaW1hZ2UoaW0seCx5KXtcbiAgdmFyIHMgPSBjYW1sX2dyX3N0YXRlX2dldCgpO1xuICBpZighaW0uaW1hZ2UpIHtcbiAgICB2YXIgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgICBjYW52YXMud2lkdGggPSBzLndpZHRoO1xuICAgIGNhbnZhcy5oZWlnaHQgPSBzLmhlaWdodDtcbiAgICBjYW52YXMuZ2V0Q29udGV4dChcIjJkXCIpLnB1dEltYWdlRGF0YShpbSwwLDApO1xuICAgIHZhciBpbWFnZSA9IG5ldyBnbG9iYWxUaGlzLkltYWdlKCk7XG4gICAgaW1hZ2Uub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgcy5jb250ZXh0LmRyYXdJbWFnZShpbWFnZSx4LHMuaGVpZ2h0IC0gaW0uaGVpZ2h0IC0geSk7XG4gICAgICBpbS5pbWFnZSA9IGltYWdlO1xuICAgIH1cbiAgICBpbWFnZS5zcmMgPSBjYW52YXMudG9EYXRhVVJMKFwiaW1hZ2UvcG5nXCIpO1xuICB9IGVsc2Uge1xuICAgIHMuY29udGV4dC5kcmF3SW1hZ2UoaW0uaW1hZ2UseCxzLmhlaWdodCAtIGltLmhlaWdodCAtIHkpO1xuICB9XG4gIHJldHVybiAwO1xufVxuLy9Qcm92aWRlczogY2FtbF9ncl9jcmVhdGVfaW1hZ2Vcbi8vUmVxdWlyZXM6IGNhbWxfZ3Jfc3RhdGVfZ2V0XG5mdW5jdGlvbiBjYW1sX2dyX2NyZWF0ZV9pbWFnZSh4LHkpe1xuICB2YXIgcyA9IGNhbWxfZ3Jfc3RhdGVfZ2V0KCk7XG4gIHJldHVybiBzLmNvbnRleHQuY3JlYXRlSW1hZ2VEYXRhKHgseSk7XG59XG4vL1Byb3ZpZGVzOiBjYW1sX2dyX2JsaXRfaW1hZ2Vcbi8vUmVxdWlyZXM6IGNhbWxfZ3Jfc3RhdGVfZ2V0XG5mdW5jdGlvbiBjYW1sX2dyX2JsaXRfaW1hZ2UoaW0seCx5KXtcbiAgdmFyIHMgPSBjYW1sX2dyX3N0YXRlX2dldCgpO1xuICB2YXIgaW0yID0gcy5jb250ZXh0LmdldEltYWdlRGF0YSh4LHMuaGVpZ2h0IC0gaW0uaGVpZ2h0IC0geSxpbS53aWR0aCxpbS5oZWlnaHQpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGltMi5kYXRhLmxlbmd0aDsgaSs9NCl7XG4gICAgaW0uZGF0YVtpXSA9IGltMi5kYXRhW2ldO1xuICAgIGltLmRhdGFbaSsxXSA9IGltMi5kYXRhW2krMV07XG4gICAgaW0uZGF0YVtpKzJdID0gaW0yLmRhdGFbaSsyXTtcbiAgICBpbS5kYXRhW2krM10gPSBpbTIuZGF0YVtpKzNdO1xuICB9XG4gIHJldHVybiAwO1xufVxuLy9Qcm92aWRlczogY2FtbF9ncl9zaWdpb19oYW5kbGVyXG5mdW5jdGlvbiBjYW1sX2dyX3NpZ2lvX2hhbmRsZXIoKXtyZXR1cm4gMH1cbi8vUHJvdmlkZXM6IGNhbWxfZ3Jfc2lnaW9fc2lnbmFsXG5mdW5jdGlvbiBjYW1sX2dyX3NpZ2lvX3NpZ25hbCgpe3JldHVybiAwfVxuLy9Qcm92aWRlczogY2FtbF9ncl93YWl0X2V2ZW50XG4vL1JlcXVpcmVzOiBjYW1sX2ZhaWx3aXRoXG5mdW5jdGlvbiBjYW1sX2dyX3dhaXRfZXZlbnQoX2V2bCl7XG4gIGNhbWxfZmFpbHdpdGgoXCJjYW1sX2dyX3dhaXRfZXZlbnQgbm90IEltcGxlbWVudGVkOiB1c2UgR3JhcGhpY3NfanMgaW5zdGVhZFwiKTtcbn1cblxuLy9Qcm92aWRlczogY2FtbF9ncl9zeW5jaHJvbml6ZVxuLy9SZXF1aXJlczogY2FtbF9mYWlsd2l0aFxuZnVuY3Rpb24gY2FtbF9ncl9zeW5jaHJvbml6ZSAoKSB7XG4gIGNhbWxfZmFpbHdpdGgoXCJjYW1sX2dyX3N5bmNocm9uaXplIG5vdCBJbXBsZW1lbnRlZFwiKTtcbn1cbi8vUHJvdmlkZXM6IGNhbWxfZ3JfcmVtZW1iZXJfbW9kZVxuLy9SZXF1aXJlczogY2FtbF9mYWlsd2l0aFxuZnVuY3Rpb24gY2FtbF9ncl9yZW1lbWJlcl9tb2RlICgpIHtcbiAgY2FtbF9mYWlsd2l0aChcImNhbWxfZ3JfcmVtZW1iZXJfbW9kZSBub3QgSW1wbGVtZW50ZWRcIik7XG59XG4vL1Byb3ZpZGVzOiBjYW1sX2dyX2Rpc3BsYXlfbW9kZVxuLy9SZXF1aXJlczogY2FtbF9mYWlsd2l0aFxuZnVuY3Rpb24gY2FtbF9ncl9kaXNwbGF5X21vZGUoKSB7XG4gIGNhbWxfZmFpbHdpdGgoXCJjYW1sX2dyX2Rpc3BsYXlfbW9kZSBub3QgSW1wbGVtZW50ZWRcIik7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfZ3Jfd2luZG93X2lkXG4vL1JlcXVpcmVzOiBjYW1sX2ZhaWx3aXRoXG5mdW5jdGlvbiBjYW1sX2dyX3dpbmRvd19pZChhKSB7XG4gIGNhbWxfZmFpbHdpdGgoXCJjYW1sX2dyX3dpbmRvd19pZCBub3QgSW1wbGVtZW50ZWRcIik7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfZ3Jfb3Blbl9zdWJ3aW5kb3dcbi8vUmVxdWlyZXM6IGNhbWxfZmFpbHdpdGhcbmZ1bmN0aW9uIGNhbWxfZ3Jfb3Blbl9zdWJ3aW5kb3coYSxiLGMsZCkge1xuICBjYW1sX2ZhaWx3aXRoKFwiY2FtbF9ncl9vcGVuX3N1YndpbmRvdyBub3QgSW1wbGVtZW50ZWRcIik7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfZ3JfY2xvc2Vfc3Vid2luZG93XG4vL1JlcXVpcmVzOiBjYW1sX2ZhaWx3aXRoXG5mdW5jdGlvbiBjYW1sX2dyX2Nsb3NlX3N1YndpbmRvdyhhKSB7XG4gIGNhbWxfZmFpbHdpdGgoXCJjYW1sX2dyX2Nsb3NlX3N1YndpbmRvdyBub3QgSW1wbGVtZW50ZWRcIik7XG59XG4iLCIvLyBKc19vZl9vY2FtbCBsaWJyYXJ5XG4vLyBodHRwOi8vd3d3Lm9jc2lnZW4ub3JnL2pzX29mX29jYW1sL1xuLy8gQ29weXJpZ2h0IChDKSAyMDEwIErDqXLDtG1lIFZvdWlsbG9uXG4vLyBMYWJvcmF0b2lyZSBQUFMgLSBDTlJTIFVuaXZlcnNpdMOpIFBhcmlzIERpZGVyb3Rcbi8vXG4vLyBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuLy8gaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4vLyB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCB3aXRoIGxpbmtpbmcgZXhjZXB0aW9uO1xuLy8gZWl0aGVyIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy9cbi8vIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbi8vIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy9cbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuLy8gYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuXG5cbi8vLy8vLy8vLy8vLy8gSnNsaWI6IGNvZGUgc3BlY2lmaWMgdG8gSnNfb2Zfb2NhbWxcblxuLy9Qcm92aWRlczogY2FtbF9qc19vbl9pZSBjb25zdFxuZnVuY3Rpb24gY2FtbF9qc19vbl9pZSAoKSB7XG4gIHZhciB1YSA9XG4gICAgICAoZ2xvYmFsVGhpcy5uYXZpZ2F0b3ImJmdsb2JhbFRoaXMubmF2aWdhdG9yLnVzZXJBZ2VudClcbiAgICAgID9nbG9iYWxUaGlzLm5hdmlnYXRvci51c2VyQWdlbnQ6XCJcIjtcbiAgcmV0dXJuIHVhLmluZGV4T2YoXCJNU0lFXCIpICE9IC0xICYmIHVhLmluZGV4T2YoXCJPcGVyYVwiKSAhPSAwO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2pzX2h0bWxfZXNjYXBlIGNvbnN0IChjb25zdClcbnZhciBjYW1sX2pzX3JlZ2V4cHMgPSB7IGFtcDovJi9nLCBsdDovPC9nLCBxdW90Oi9cXFwiL2csIGFsbDovWyY8XFxcIl0vIH07XG5mdW5jdGlvbiBjYW1sX2pzX2h0bWxfZXNjYXBlIChzKSB7XG4gIGlmICghY2FtbF9qc19yZWdleHBzLmFsbC50ZXN0KHMpKSByZXR1cm4gcztcbiAgcmV0dXJuIHMucmVwbGFjZShjYW1sX2pzX3JlZ2V4cHMuYW1wLCBcIiZhbXA7XCIpXG4gICAgLnJlcGxhY2UoY2FtbF9qc19yZWdleHBzLmx0LCBcIiZsdDtcIilcbiAgICAucmVwbGFjZShjYW1sX2pzX3JlZ2V4cHMucXVvdCwgXCImcXVvdDtcIik7XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfanNfaHRtbF9lbnRpdGllc1xuLy9SZXF1aXJlczogY2FtbF9mYWlsd2l0aFxuZnVuY3Rpb24gY2FtbF9qc19odG1sX2VudGl0aWVzKHMpIHtcbiAgdmFyIGVudGl0eSA9IC9eJiM/WzAtOWEtekEtWl0rOyQvXG4gIGlmKHMubWF0Y2goZW50aXR5KSlcbiAge1xuICAgIHZhciBzdHIsIHRlbXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdwJyk7XG4gICAgdGVtcC5pbm5lckhUTUw9IHM7XG4gICAgc3RyPSB0ZW1wLnRleHRDb250ZW50IHx8IHRlbXAuaW5uZXJUZXh0O1xuICAgIHRlbXA9bnVsbDtcbiAgICByZXR1cm4gc3RyO1xuICB9XG4gIGVsc2Uge1xuICAgIGNhbWxfZmFpbHdpdGgoXCJJbnZhbGlkIGVudGl0eSBcIiArIHMpO1xuICB9XG59XG5cbi8vUHJvdmlkZXM6IGNhbWxfanNfZ2V0X2NvbnNvbGUgY29uc3RcbmZ1bmN0aW9uIGNhbWxfanNfZ2V0X2NvbnNvbGUgKCkge1xuICB2YXIgYyA9IGNvbnNvbGU7XG4gIHZhciBtID0gW1wibG9nXCIsIFwiZGVidWdcIiwgXCJpbmZvXCIsIFwid2FyblwiLCBcImVycm9yXCIsIFwiYXNzZXJ0XCIsIFwiZGlyXCIsIFwiZGlyeG1sXCIsXG4gICAgICAgICAgIFwidHJhY2VcIiwgXCJncm91cFwiLCBcImdyb3VwQ29sbGFwc2VkXCIsIFwiZ3JvdXBFbmRcIiwgXCJ0aW1lXCIsIFwidGltZUVuZFwiXTtcbiAgZnVuY3Rpb24gZiAoKSB7fVxuICBmb3IgKHZhciBpID0gMDsgaSA8IG0ubGVuZ3RoOyBpKyspIGlmICghY1ttW2ldXSkgY1ttW2ldXT1mO1xuICByZXR1cm4gYztcbn1cblxuLy9Qcm92aWRlczogY2FtbF94bWxodHRwcmVxdWVzdF9jcmVhdGVcbi8vUmVxdWlyZXM6IGNhbWxfZmFpbHdpdGhcbi8vV2Vha2RlZlxuZnVuY3Rpb24gY2FtbF94bWxodHRwcmVxdWVzdF9jcmVhdGUodW5pdCl7XG4gIGlmKHR5cGVvZiBnbG9iYWxUaGlzLlhNTEh0dHBSZXF1ZXN0ICE9PSAndW5kZWZpbmVkJykge1xuICAgIHRyeSB7IHJldHVybiBuZXcgZ2xvYmFsVGhpcy5YTUxIdHRwUmVxdWVzdCB9IGNhdGNoIChlKSB7IH07XG4gIH1cbiAgaWYodHlwZW9mIGdsb2JhbFRoaXMuYWN0aXZlWE9iamVjdCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB0cnkgeyByZXR1cm4gbmV3IGdsb2JhbFRoaXMuYWN0aXZlWE9iamVjdChcIk1zeG1sMi5YTUxIVFRQXCIpIH0gY2F0Y2goZSl7IH07XG4gICAgdHJ5IHsgcmV0dXJuIG5ldyBnbG9iYWxUaGlzLmFjdGl2ZVhPYmplY3QoXCJNc3htbDMuWE1MSFRUUFwiKSB9IGNhdGNoKGUpeyB9O1xuICAgIHRyeSB7IHJldHVybiBuZXcgZ2xvYmFsVGhpcy5hY3RpdmVYT2JqZWN0KFwiTWljcm9zb2Z0LlhNTEhUVFBcIikgfSBjYXRjaChlKXsgfTtcbiAgfVxuICBjYW1sX2ZhaWx3aXRoKFwiQ2Fubm90IGNyZWF0ZSBhIFhNTEh0dHBSZXF1ZXN0XCIpO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2pzX2Vycm9yX29mX2V4Y2VwdGlvblxuZnVuY3Rpb24gY2FtbF9qc19lcnJvcl9vZl9leGNlcHRpb24oZXhuKSB7XG4gIGlmKGV4bi5qc19lcnJvcikgeyByZXR1cm4gZXhuLmpzX2Vycm9yOyB9XG4gIHJldHVybiBudWxsO1xufVxuIiwiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuLyogICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RpdmUgQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuLyogICAgICAgICAgICBYYXZpZXIgTGVyb3ksIHByb2pldCBDcmlzdGFsLCBJTlJJQSBSb2NxdWVuY291cnQgICAgICAgICAqL1xuLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuLyogIENvcHlyaWdodCAxOTk2IEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgICAqL1xuLyogIGVuIEF1dG9tYXRpcXVlLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4gIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCAgICAqL1xuLyogIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLCB3aXRoICAgICAqL1xuLyogIHRoZSBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiBmaWxlIC4uL0xJQ0VOU0UuICAgICAqL1xuLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4vKiAkSWQ6IGxleGluZy5jIDYwNDUgMjAwNC0wMS0wMSAxNjo0Mjo0M1ogZG9saWdleiAkICovXG5cbi8qIFRoZSB0YWJsZS1kcml2ZW4gYXV0b21hdG9uIGZvciBsZXhlcnMgZ2VuZXJhdGVkIGJ5IGNhbWxsZXguICovXG5cbi8vUHJvdmlkZXM6IGNhbWxfbGV4X2FycmF5XG4vL1JlcXVpcmVzOiBjYW1sX2pzYnl0ZXNfb2Zfc3RyaW5nXG5mdW5jdGlvbiBjYW1sX2xleF9hcnJheShzKSB7XG4gIHMgPSBjYW1sX2pzYnl0ZXNfb2Zfc3RyaW5nKHMpO1xuICB2YXIgbCA9IHMubGVuZ3RoIC8gMjtcbiAgdmFyIGEgPSBuZXcgQXJyYXkobCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbDsgaSsrKVxuICAgIGFbaV0gPSAocy5jaGFyQ29kZUF0KDIgKiBpKSB8IChzLmNoYXJDb2RlQXQoMiAqIGkgKyAxKSA8PCA4KSkgPDwgMTYgPj4gMTY7XG4gIHJldHVybiBhO1xufVxuXG4vL1Byb3ZpZGVzOiBjYW1sX2xleF9lbmdpbmVcbi8vUmVxdWlyZXM6IGNhbWxfZmFpbHdpdGgsIGNhbWxfbGV4X2FycmF5LCBjYW1sX3VpbnQ4X2FycmF5X29mX2J5dGVzXG5mdW5jdGlvbiBjYW1sX2xleF9lbmdpbmUodGJsLCBzdGFydF9zdGF0ZSwgbGV4YnVmKSB7XG4gIHZhciBsZXhfYnVmZmVyID0gMjtcbiAgdmFyIGxleF9idWZmZXJfbGVuID0gMztcbiAgdmFyIGxleF9zdGFydF9wb3MgPSA1O1xuICB2YXIgbGV4X2N1cnJfcG9zID0gNjtcbiAgdmFyIGxleF9sYXN0X3BvcyA9IDc7XG4gIHZhciBsZXhfbGFzdF9hY3Rpb24gPSA4O1xuICB2YXIgbGV4X2VvZl9yZWFjaGVkID0gOTtcbiAgdmFyIGxleF9iYXNlID0gMTtcbiAgdmFyIGxleF9iYWNrdHJrID0gMjtcbiAgdmFyIGxleF9kZWZhdWx0ID0gMztcbiAgdmFyIGxleF90cmFucyA9IDQ7XG4gIHZhciBsZXhfY2hlY2sgPSA1O1xuXG4gIGlmICghdGJsLmxleF9kZWZhdWx0KSB7XG4gICAgdGJsLmxleF9iYXNlID0gICAgY2FtbF9sZXhfYXJyYXkgKHRibFtsZXhfYmFzZV0pO1xuICAgIHRibC5sZXhfYmFja3RyayA9IGNhbWxfbGV4X2FycmF5ICh0YmxbbGV4X2JhY2t0cmtdKTtcbiAgICB0YmwubGV4X2NoZWNrID0gICBjYW1sX2xleF9hcnJheSAodGJsW2xleF9jaGVja10pO1xuICAgIHRibC5sZXhfdHJhbnMgPSAgIGNhbWxfbGV4X2FycmF5ICh0YmxbbGV4X3RyYW5zXSk7XG4gICAgdGJsLmxleF9kZWZhdWx0ID0gY2FtbF9sZXhfYXJyYXkgKHRibFtsZXhfZGVmYXVsdF0pO1xuICB9XG5cbiAgdmFyIGMsIHN0YXRlID0gc3RhcnRfc3RhdGU7XG5cbiAgdmFyIGJ1ZmZlciA9IGNhbWxfdWludDhfYXJyYXlfb2ZfYnl0ZXMobGV4YnVmW2xleF9idWZmZXJdKTtcblxuICBpZiAoc3RhdGUgPj0gMCkge1xuICAgIC8qIEZpcnN0IGVudHJ5ICovXG4gICAgbGV4YnVmW2xleF9sYXN0X3Bvc10gPSBsZXhidWZbbGV4X3N0YXJ0X3Bvc10gPSBsZXhidWZbbGV4X2N1cnJfcG9zXTtcbiAgICBsZXhidWZbbGV4X2xhc3RfYWN0aW9uXSA9IC0xO1xuICB9IGVsc2Uge1xuICAgIC8qIFJlZW50cnkgYWZ0ZXIgcmVmaWxsICovXG4gICAgc3RhdGUgPSAtc3RhdGUgLSAxO1xuICB9XG4gIGZvcig7Oykge1xuICAgIC8qIExvb2t1cCBiYXNlIGFkZHJlc3Mgb3IgYWN0aW9uIG51bWJlciBmb3IgY3VycmVudCBzdGF0ZSAqL1xuICAgIHZhciBiYXNlID0gdGJsLmxleF9iYXNlW3N0YXRlXTtcbiAgICBpZiAoYmFzZSA8IDApIHJldHVybiAtYmFzZS0xO1xuICAgIC8qIFNlZSBpZiBpdCdzIGEgYmFja3RyYWNrIHBvaW50ICovXG4gICAgdmFyIGJhY2t0cmsgPSB0YmwubGV4X2JhY2t0cmtbc3RhdGVdO1xuICAgIGlmIChiYWNrdHJrID49IDApIHtcbiAgICAgIGxleGJ1ZltsZXhfbGFzdF9wb3NdID0gbGV4YnVmW2xleF9jdXJyX3Bvc107XG4gICAgICBsZXhidWZbbGV4X2xhc3RfYWN0aW9uXSA9IGJhY2t0cms7XG4gICAgfVxuICAgIC8qIFNlZSBpZiB3ZSBuZWVkIGEgcmVmaWxsICovXG4gICAgaWYgKGxleGJ1ZltsZXhfY3Vycl9wb3NdID49IGxleGJ1ZltsZXhfYnVmZmVyX2xlbl0pe1xuICAgICAgaWYgKGxleGJ1ZltsZXhfZW9mX3JlYWNoZWRdID09IDApXG4gICAgICAgIHJldHVybiAtc3RhdGUgLSAxO1xuICAgICAgZWxzZVxuICAgICAgICBjID0gMjU2O1xuICAgIH1lbHNle1xuICAgICAgLyogUmVhZCBuZXh0IGlucHV0IGNoYXIgKi9cbiAgICAgIGMgPSBidWZmZXJbbGV4YnVmW2xleF9jdXJyX3Bvc11dO1xuICAgICAgbGV4YnVmW2xleF9jdXJyX3Bvc10gKys7XG4gICAgfVxuICAgIC8qIERldGVybWluZSBuZXh0IHN0YXRlICovXG4gICAgaWYgKHRibC5sZXhfY2hlY2tbYmFzZSArIGNdID09IHN0YXRlKVxuICAgICAgc3RhdGUgPSB0YmwubGV4X3RyYW5zW2Jhc2UgKyBjXTtcbiAgICBlbHNlXG4gICAgICBzdGF0ZSA9IHRibC5sZXhfZGVmYXVsdFtzdGF0ZV07XG4gICAgLyogSWYgbm8gdHJhbnNpdGlvbiBvbiB0aGlzIGNoYXIsIHJldHVybiB0byBsYXN0IGJhY2t0cmFjayBwb2ludCAqL1xuICAgIGlmIChzdGF0ZSA8IDApIHtcbiAgICAgIGxleGJ1ZltsZXhfY3Vycl9wb3NdID0gbGV4YnVmW2xleF9sYXN0X3Bvc107XG4gICAgICBpZiAobGV4YnVmW2xleF9sYXN0X2FjdGlvbl0gPT0gLTEpXG4gICAgICAgIGNhbWxfZmFpbHdpdGgoXCJsZXhpbmc6IGVtcHR5IHRva2VuXCIpO1xuICAgICAgZWxzZVxuICAgICAgICByZXR1cm4gbGV4YnVmW2xleF9sYXN0X2FjdGlvbl07XG4gICAgfWVsc2V7XG4gICAgICAvKiBFcmFzZSB0aGUgRU9GIGNvbmRpdGlvbiBvbmx5IGlmIHRoZSBFT0YgcHNldWRvLWNoYXJhY3RlciB3YXNcbiAgICAgICAgIGNvbnN1bWVkIGJ5IHRoZSBhdXRvbWF0b24gKGkuZS4gdGhlcmUgd2FzIG5vIGJhY2t0cmFjayBhYm92ZSlcbiAgICAgICovXG4gICAgICBpZiAoYyA9PSAyNTYpIGxleGJ1ZltsZXhfZW9mX3JlYWNoZWRdID0gMDtcbiAgICB9XG4gIH1cbn1cblxuLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyogTmV3IGxleGVyIGVuZ2luZSwgd2l0aCBtZW1vcnkgb2YgcG9zaXRpb25zICAqL1xuLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4vL1Byb3ZpZGVzOiBjYW1sX25ld19sZXhfZW5naW5lXG4vL1JlcXVpcmVzOiBjYW1sX2ZhaWx3aXRoLCBjYW1sX2xleF9hcnJheVxuLy9SZXF1aXJlczogY2FtbF9qc2J5dGVzX29mX3N0cmluZywgY2FtbF91aW50OF9hcnJheV9vZl9ieXRlc1xuZnVuY3Rpb24gY2FtbF9sZXhfcnVuX21lbShzLCBpLCBtZW0sIGN1cnJfcG9zKSB7XG4gIGZvciAoOzspIHtcbiAgICB2YXIgZHN0ID0gcy5jaGFyQ29kZUF0KGkpOyBpKys7XG4gICAgaWYgKGRzdCA9PSAweGZmKSByZXR1cm47XG4gICAgdmFyIHNyYyA9IHMuY2hhckNvZGVBdChpKTsgaSsrO1xuICAgIGlmIChzcmMgPT0gMHhmZilcbiAgICAgIG1lbSBbZHN0ICsgMV0gPSBjdXJyX3BvcztcbiAgICBlbHNlXG4gICAgICBtZW0gW2RzdCArIDFdID0gbWVtIFtzcmMgKyAxXTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjYW1sX2xleF9ydW5fdGFnKHMsIGksIG1lbSkge1xuICBmb3IgKDs7KSB7XG4gICAgdmFyIGRzdCA9IHMuY2hhckNvZGVBdChpKTsgaSsrO1xuICAgIGlmIChkc3QgPT0gMHhmZikgcmV0dXJuIDtcbiAgICB2YXIgc3JjID0gcy5jaGFyQ29kZUF0KGkpOyBpKys7XG4gICAgaWYgKHNyYyA9PSAweGZmKVxuICAgICAgbWVtIFtkc3QgKyAxXSA9IC0xO1xuICAgIGVsc2VcbiAgICAgIG1lbSBbZHN0ICsgMV0gPSBtZW0gW3NyYyArIDFdO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNhbWxfbmV3X2xleF9lbmdpbmUodGJsLCBzdGFydF9zdGF0ZSwgbGV4YnVmKSB7XG4gIHZhciBsZXhfYnVmZmVyID0gMjtcbiAgdmFyIGxleF9idWZmZXJfbGVuID0gMztcbiAgdmFyIGxleF9zdGFydF9wb3MgPSA1O1xuICB2YXIgbGV4X2N1cnJfcG9zID0gNjtcbiAgdmFyIGxleF9sYXN0X3BvcyA9IDc7XG4gIHZhciBsZXhfbGFzdF9hY3Rpb24gPSA4O1xuICB2YXIgbGV4X2VvZl9yZWFjaGVkID0gOTtcbiAgdmFyIGxleF9tZW0gPSAxMDtcbiAgdmFyIGxleF9iYXNlID0gMTtcbiAgdmFyIGxleF9iYWNrdHJrID0gMjtcbiAgdmFyIGxleF9kZWZhdWx0ID0gMztcbiAgdmFyIGxleF90cmFucyA9IDQ7XG4gIHZhciBsZXhfY2hlY2sgPSA1O1xuICB2YXIgbGV4X2Jhc2VfY29kZSA9IDY7XG4gIHZhciBsZXhfYmFja3Rya19jb2RlID0gNztcbiAgdmFyIGxleF9kZWZhdWx0X2NvZGUgPSA4O1xuICB2YXIgbGV4X3RyYW5zX2NvZGUgPSA5O1xuICB2YXIgbGV4X2NoZWNrX2NvZGUgPSAxMDtcbiAgdmFyIGxleF9jb2RlID0gMTE7XG5cbiAgaWYgKCF0YmwubGV4X2RlZmF1bHQpIHtcbiAgICB0YmwubGV4X2Jhc2UgPSAgICBjYW1sX2xleF9hcnJheSAodGJsW2xleF9iYXNlXSk7XG4gICAgdGJsLmxleF9iYWNrdHJrID0gY2FtbF9sZXhfYXJyYXkgKHRibFtsZXhfYmFja3Rya10pO1xuICAgIHRibC5sZXhfY2hlY2sgPSAgIGNhbWxfbGV4X2FycmF5ICh0YmxbbGV4X2NoZWNrXSk7XG4gICAgdGJsLmxleF90cmFucyA9ICAgY2FtbF9sZXhfYXJyYXkgKHRibFtsZXhfdHJhbnNdKTtcbiAgICB0YmwubGV4X2RlZmF1bHQgPSBjYW1sX2xleF9hcnJheSAodGJsW2xleF9kZWZhdWx0XSk7XG4gIH1cbiAgaWYgKCF0YmwubGV4X2RlZmF1bHRfY29kZSkge1xuICAgIHRibC5sZXhfYmFzZV9jb2RlID0gICAgY2FtbF9sZXhfYXJyYXkgKHRibFtsZXhfYmFzZV9jb2RlXSk7XG4gICAgdGJsLmxleF9iYWNrdHJrX2NvZGUgPSBjYW1sX2xleF9hcnJheSAodGJsW2xleF9iYWNrdHJrX2NvZGVdKTtcbiAgICB0YmwubGV4X2NoZWNrX2NvZGUgPSAgIGNhbWxfbGV4X2FycmF5ICh0YmxbbGV4X2NoZWNrX2NvZGVdKTtcbiAgICB0YmwubGV4X3RyYW5zX2NvZGUgPSAgIGNhbWxfbGV4X2FycmF5ICh0YmxbbGV4X3RyYW5zX2NvZGVdKTtcbiAgICB0YmwubGV4X2RlZmF1bHRfY29kZSA9IGNhbWxfbGV4X2FycmF5ICh0YmxbbGV4X2RlZmF1bHRfY29kZV0pO1xuICB9XG4gIGlmICh0YmwubGV4X2NvZGUgPT0gbnVsbCkgdGJsLmxleF9jb2RlID0gY2FtbF9qc2J5dGVzX29mX3N0cmluZyh0YmxbbGV4X2NvZGVdKTtcblxuICB2YXIgYywgc3RhdGUgPSBzdGFydF9zdGF0ZTtcblxuICB2YXIgYnVmZmVyID0gY2FtbF91aW50OF9hcnJheV9vZl9ieXRlcyhsZXhidWZbbGV4X2J1ZmZlcl0pO1xuXG4gIGlmIChzdGF0ZSA+PSAwKSB7XG4gICAgLyogRmlyc3QgZW50cnkgKi9cbiAgICBsZXhidWZbbGV4X2xhc3RfcG9zXSA9IGxleGJ1ZltsZXhfc3RhcnRfcG9zXSA9IGxleGJ1ZltsZXhfY3Vycl9wb3NdO1xuICAgIGxleGJ1ZltsZXhfbGFzdF9hY3Rpb25dID0gLTE7XG4gIH0gZWxzZSB7XG4gICAgLyogUmVlbnRyeSBhZnRlciByZWZpbGwgKi9cbiAgICBzdGF0ZSA9IC1zdGF0ZSAtIDE7XG4gIH1cbiAgZm9yKDs7KSB7XG4gICAgLyogTG9va3VwIGJhc2UgYWRkcmVzcyBvciBhY3Rpb24gbnVtYmVyIGZvciBjdXJyZW50IHN0YXRlICovXG4gICAgdmFyIGJhc2UgPSB0YmwubGV4X2Jhc2Vbc3RhdGVdO1xuICAgIGlmIChiYXNlIDwgMCkge1xuICAgICAgdmFyIHBjX29mZiA9IHRibC5sZXhfYmFzZV9jb2RlW3N0YXRlXTtcbiAgICAgIGNhbWxfbGV4X3J1bl90YWcodGJsLmxleF9jb2RlLCBwY19vZmYsIGxleGJ1ZltsZXhfbWVtXSk7XG4gICAgICByZXR1cm4gLWJhc2UtMTtcbiAgICB9XG4gICAgLyogU2VlIGlmIGl0J3MgYSBiYWNrdHJhY2sgcG9pbnQgKi9cbiAgICB2YXIgYmFja3RyayA9IHRibC5sZXhfYmFja3Rya1tzdGF0ZV07XG4gICAgaWYgKGJhY2t0cmsgPj0gMCkge1xuICAgICAgdmFyIHBjX29mZiA9IHRibC5sZXhfYmFja3Rya19jb2RlW3N0YXRlXTtcbiAgICAgIGNhbWxfbGV4X3J1bl90YWcodGJsLmxleF9jb2RlLCBwY19vZmYsIGxleGJ1ZltsZXhfbWVtXSk7XG4gICAgICBsZXhidWZbbGV4X2xhc3RfcG9zXSA9IGxleGJ1ZltsZXhfY3Vycl9wb3NdO1xuICAgICAgbGV4YnVmW2xleF9sYXN0X2FjdGlvbl0gPSBiYWNrdHJrO1xuICAgIH1cbiAgICAvKiBTZWUgaWYgd2UgbmVlZCBhIHJlZmlsbCAqL1xuICAgIGlmIChsZXhidWZbbGV4X2N1cnJfcG9zXSA+PSBsZXhidWZbbGV4X2J1ZmZlcl9sZW5dKXtcbiAgICAgIGlmIChsZXhidWZbbGV4X2VvZl9yZWFjaGVkXSA9PSAwKVxuICAgICAgICByZXR1cm4gLXN0YXRlIC0gMTtcbiAgICAgIGVsc2VcbiAgICAgICAgYyA9IDI1NjtcbiAgICB9ZWxzZXtcbiAgICAgIC8qIFJlYWQgbmV4dCBpbnB1dCBjaGFyICovXG4gICAgICBjID0gYnVmZmVyW2xleGJ1ZltsZXhfY3Vycl9wb3NdXTtcbiAgICAgIGxleGJ1ZltsZXhfY3Vycl9wb3NdICsrO1xuICAgIH1cbiAgICAvKiBEZXRlcm1pbmUgbmV4dCBzdGF0ZSAqL1xuICAgIHZhciBwc3RhdGUgPSBzdGF0ZSA7XG4gICAgaWYgKHRibC5sZXhfY2hlY2tbYmFzZSArIGNdID09IHN0YXRlKVxuICAgICAgc3RhdGUgPSB0YmwubGV4X3RyYW5zW2Jhc2UgKyBjXTtcbiAgICBlbHNlXG4gICAgICBzdGF0ZSA9IHRibC5sZXhfZGVmYXVsdFtzdGF0ZV07XG4gICAgLyogSWYgbm8gdHJhbnNpdGlvbiBvbiB0aGlzIGNoYXIsIHJldHVybiB0byBsYXN0IGJhY2t0cmFjayBwb2ludCAqL1xuICAgIGlmIChzdGF0ZSA8IDApIHtcbiAgICAgIGxleGJ1ZltsZXhfY3Vycl9wb3NdID0gbGV4YnVmW2xleF9sYXN0X3Bvc107XG4gICAgICBpZiAobGV4YnVmW2xleF9sYXN0X2FjdGlvbl0gPT0gLTEpXG4gICAgICAgIGNhbWxfZmFpbHdpdGgoXCJsZXhpbmc6IGVtcHR5IHRva2VuXCIpO1xuICAgICAgZWxzZVxuICAgICAgICByZXR1cm4gbGV4YnVmW2xleF9sYXN0X2FjdGlvbl07XG4gICAgfWVsc2V7XG4gICAgICAvKiBJZiBzb21lIHRyYW5zaXRpb24sIGdldCBhbmQgcGVyZm9ybSBtZW1vcnkgbW92ZXMgKi9cbiAgICAgIHZhciBiYXNlX2NvZGUgPSB0YmwubGV4X2Jhc2VfY29kZVtwc3RhdGVdLCBwY19vZmY7XG4gICAgICBpZiAodGJsLmxleF9jaGVja19jb2RlW2Jhc2VfY29kZSArIGNdID09IHBzdGF0ZSlcbiAgICAgICAgcGNfb2ZmID0gdGJsLmxleF90cmFuc19jb2RlW2Jhc2VfY29kZSArIGNdO1xuICAgICAgZWxzZVxuICAgICAgICBwY19vZmYgPSB0YmwubGV4X2RlZmF1bHRfY29kZVtwc3RhdGVdO1xuICAgICAgaWYgKHBjX29mZiA+IDApXG4gICAgICAgIGNhbWxfbGV4X3J1bl9tZW1cbiAgICAgICh0YmwubGV4X2NvZGUsIHBjX29mZiwgbGV4YnVmW2xleF9tZW1dLCBsZXhidWZbbGV4X2N1cnJfcG9zXSk7XG4gICAgICAvKiBFcmFzZSB0aGUgRU9GIGNvbmRpdGlvbiBvbmx5IGlmIHRoZSBFT0YgcHNldWRvLWNoYXJhY3RlciB3YXNcbiAgICAgICAgIGNvbnN1bWVkIGJ5IHRoZSBhdXRvbWF0b24gKGkuZS4gdGhlcmUgd2FzIG5vIGJhY2t0cmFjayBhYm92ZSlcbiAgICAgICovXG4gICAgICBpZiAoYyA9PSAyNTYpIGxleGJ1ZltsZXhfZW9mX3JlYWNoZWRdID0gMDtcbiAgICB9XG4gIH1cbn1cbiIsIlxuLy9Qcm92aWRlczogY2FtbF9seG1fbmV4dFxuLy9SZXF1aXJlczogY2FtbF9pbnQ2NF9zaGlmdF9sZWZ0XG4vL1JlcXVpcmVzOiBjYW1sX2ludDY0X3NoaWZ0X3JpZ2h0X3Vuc2lnbmVkXG4vL1JlcXVpcmVzOiBjYW1sX2ludDY0X29yXG4vL1JlcXVpcmVzOiBjYW1sX2ludDY0X3hvclxuLy9SZXF1aXJlczogY2FtbF9pbnQ2NF9hZGRcbi8vUmVxdWlyZXM6IGNhbWxfaW50NjRfbXVsXG4vL1JlcXVpcmVzOiBjYW1sX2JhX2dldF8xXG4vL1JlcXVpcmVzOiBjYW1sX2JhX3NldF8xXG4vL1JlcXVpcmVzOiBjYW1sX2ludDY0X29mX3N0cmluZ1xuLy9SZXF1aXJlczogY2FtbF9uZXdfc3RyaW5nXG5mdW5jdGlvbiBjYW1sX2x4bV9uZXh0KHYpIHtcbiAgZnVuY3Rpb24gc2hpZnRfbCh4LCBrKXtcbiAgICByZXR1cm4gY2FtbF9pbnQ2NF9zaGlmdF9sZWZ0KHgsayk7XG4gIH1cbiAgZnVuY3Rpb24gc2hpZnRfcih4LCBrKXtcbiAgICByZXR1cm4gY2FtbF9pbnQ2NF9zaGlmdF9yaWdodF91bnNpZ25lZCh4LGspO1xuICB9XG4gIGZ1bmN0aW9uIG9yKGEsIGIpe1xuICAgIHJldHVybiBjYW1sX2ludDY0X29yKGEsYik7XG4gIH1cbiAgZnVuY3Rpb24geG9yKGEsIGIpe1xuICAgIHJldHVybiBjYW1sX2ludDY0X3hvcihhLGIpO1xuICB9XG4gIGZ1bmN0aW9uIGFkZChhLCBiKXtcbiAgICByZXR1cm4gY2FtbF9pbnQ2NF9hZGQoYSxiKTtcbiAgfVxuICBmdW5jdGlvbiBtdWwoYSwgYil7XG4gICAgcmV0dXJuIGNhbWxfaW50NjRfbXVsKGEsYik7XG4gIH1cbiAgZnVuY3Rpb24gcm90bCh4LCBrKSB7XG4gICAgcmV0dXJuIG9yKHNoaWZ0X2woeCxrKSxzaGlmdF9yICh4LCA2NCAtIGspKTtcbiAgfVxuICBmdW5jdGlvbiBnZXQoYSwgaSkge1xuICAgIHJldHVybiBjYW1sX2JhX2dldF8xKGEsIGkpO1xuICB9XG4gIGZ1bmN0aW9uIHNldChhLCBpLCB4KSB7XG4gICAgcmV0dXJuIGNhbWxfYmFfc2V0XzEoYSwgaSwgeCk7XG4gIH1cbiAgdmFyIE0gPSBjYW1sX2ludDY0X29mX3N0cmluZyhjYW1sX25ld19zdHJpbmcoXCIweGQxMzQyNTQzZGU4MmVmOTVcIikpO1xuICB2YXIgZGFiYSA9IGNhbWxfaW50NjRfb2Zfc3RyaW5nKGNhbWxfbmV3X3N0cmluZyhcIjB4ZGFiYTBiNmViMDkzMjJlM1wiKSk7XG4gIHZhciB6LCBxMCwgcTE7XG4gIHZhciBzdCA9IHY7XG4gIHZhciBhID0gZ2V0KHN0LDApO1xuICB2YXIgcyA9IGdldChzdCwxKTtcbiAgdmFyIHgwID0gZ2V0KHN0LDIpO1xuICB2YXIgeDEgPSBnZXQoc3QsMyk7XG4gIC8qIENvbWJpbmluZyBvcGVyYXRpb24gKi9cbiAgeiA9IGFkZChzLCB4MCk7XG4gIC8qIE1peGluZyBmdW5jdGlvbiAqL1xuICB6ID0gbXVsKHhvcih6LHNoaWZ0X3IoeiwzMikpLCBkYWJhKTtcbiAgeiA9IG11bCh4b3IoeixzaGlmdF9yKHosMzIpKSwgZGFiYSk7XG4gIHogPSB4b3IoeixzaGlmdF9yKHosMzIpKTtcbiAgLyogTENHIHVwZGF0ZSAqL1xuICBzZXQoc3QsIDEsIGFkZCAobXVsKHMsTSksIGEpKTtcbiAgLyogWEJHIHVwZGF0ZSAqL1xuICB2YXIgcTAgPSB4MFxuICB2YXIgcTEgPSB4MVxuICBxMSA9IHhvcihxMSxxMCk7XG4gIHEwID0gcm90bChxMCwgMjQpO1xuICBxMCA9IHhvcih4b3IocTAsIHExKSwgKHNoaWZ0X2wocTEsMTYpKSk7XG4gIHExID0gcm90bChxMSwgMzcpO1xuICBzZXQoc3QsIDIsIHEwKTtcbiAgc2V0KHN0LCAzLCBxMSk7XG4gIC8qIFJldHVybiByZXN1bHQgKi9cbiAgcmV0dXJuIHo7XG59XG4iLCIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG4vKiAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdGl2ZSBDYW1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG4vKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG4vKiAgICAgICAgICAgIFhhdmllciBMZXJveSwgcHJvamV0IENyaXN0YWwsIElOUklBIFJvY3F1ZW5jb3VydCAgICAgICAgICovXG4vKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG4vKiAgQ29weXJpZ2h0IDE5OTYgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCAgICovXG4vKiAgZW4gQXV0b21hdGlxdWUuICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkICAgICovXG4vKiAgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsIHdpdGggICAgICovXG4vKiAgdGhlIHNwZWNpYWwgZXhjZXB0aW9uIG9uIGxpbmtpbmcgZGVzY3JpYmVkIGluIGZpbGUgLi4vTElDRU5TRS4gICAgICovXG4vKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG4vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbi8qICRJZDogcGFyc2luZy5jIDg5ODMgMjAwOC0wOC0wNiAwOTozODoyNVogeGxlcm95ICQgKi9cblxuLyogVGhlIFBEQSBhdXRvbWF0b24gZm9yIHBhcnNlcnMgZ2VuZXJhdGVkIGJ5IGNhbWx5YWNjICovXG5cbi8qIFRoZSBwdXNoZG93biBhdXRvbWF0YSAqL1xuXG4vL1Byb3ZpZGVzOiBjYW1sX3BhcnNlcl90cmFjZVxudmFyIGNhbWxfcGFyc2VyX3RyYWNlID0gMDtcblxuLy9Qcm92aWRlczogY2FtbF9wYXJzZV9lbmdpbmVcbi8vUmVxdWlyZXM6IGNhbWxfbGV4X2FycmF5LCBjYW1sX3BhcnNlcl90cmFjZSxjYW1sX2pzc3RyaW5nX29mX3N0cmluZ1xuLy9SZXF1aXJlczogY2FtbF9tbF9vdXRwdXQsIGNhbWxfbWxfc3RyaW5nX2xlbmd0aCwgY2FtbF9zdHJpbmdfb2ZfanNieXRlc1xuLy9SZXF1aXJlczogY2FtbF9qc2J5dGVzX29mX3N0cmluZywgTWxCeXRlc1xuZnVuY3Rpb24gY2FtbF9wYXJzZV9lbmdpbmUodGFibGVzLCBlbnYsIGNtZCwgYXJnKVxue1xuICB2YXIgRVJSQ09ERSA9IDI1NjtcblxuICAvL3ZhciBTVEFSVCA9IDA7XG4gIC8vdmFyIFRPS0VOX1JFQUQgPSAxO1xuICAvL3ZhciBTVEFDS1NfR1JPV05fMSA9IDI7XG4gIC8vdmFyIFNUQUNLU19HUk9XTl8yID0gMztcbiAgLy92YXIgU0VNQU5USUNfQUNUSU9OX0NPTVBVVEVEID0gNDtcbiAgLy92YXIgRVJST1JfREVURUNURUQgPSA1O1xuICB2YXIgbG9vcCA9IDY7XG4gIHZhciB0ZXN0c2hpZnQgPSA3O1xuICB2YXIgc2hpZnQgPSA4O1xuICB2YXIgc2hpZnRfcmVjb3ZlciA9IDk7XG4gIHZhciByZWR1Y2UgPSAxMDtcblxuICB2YXIgUkVBRF9UT0tFTiA9IDA7XG4gIHZhciBSQUlTRV9QQVJTRV9FUlJPUiA9IDE7XG4gIHZhciBHUk9XX1NUQUNLU18xID0gMjtcbiAgdmFyIEdST1dfU1RBQ0tTXzIgPSAzO1xuICB2YXIgQ09NUFVURV9TRU1BTlRJQ19BQ1RJT04gPSA0O1xuICB2YXIgQ0FMTF9FUlJPUl9GVU5DVElPTiA9IDU7XG5cbiAgdmFyIGVudl9zX3N0YWNrID0gMTtcbiAgdmFyIGVudl92X3N0YWNrID0gMjtcbiAgdmFyIGVudl9zeW1iX3N0YXJ0X3N0YWNrID0gMztcbiAgdmFyIGVudl9zeW1iX2VuZF9zdGFjayA9IDQ7XG4gIHZhciBlbnZfc3RhY2tzaXplID0gNTtcbiAgdmFyIGVudl9zdGFja2Jhc2UgPSA2O1xuICB2YXIgZW52X2N1cnJfY2hhciA9IDc7XG4gIHZhciBlbnZfbHZhbCA9IDg7XG4gIHZhciBlbnZfc3ltYl9zdGFydCA9IDk7XG4gIHZhciBlbnZfc3ltYl9lbmQgPSAxMDtcbiAgdmFyIGVudl9hc3AgPSAxMTtcbiAgdmFyIGVudl9ydWxlX2xlbiA9IDEyO1xuICB2YXIgZW52X3J1bGVfbnVtYmVyID0gMTM7XG4gIHZhciBlbnZfc3AgPSAxNDtcbiAgdmFyIGVudl9zdGF0ZSA9IDE1O1xuICB2YXIgZW52X2VycmZsYWcgPSAxNjtcblxuICAvLyB2YXIgX3RibF9hY3Rpb25zID0gMTtcbiAgdmFyIHRibF90cmFuc2xfY29uc3QgPSAyO1xuICB2YXIgdGJsX3RyYW5zbF9ibG9jayA9IDM7XG4gIHZhciB0YmxfbGhzID0gNDtcbiAgdmFyIHRibF9sZW4gPSA1O1xuICB2YXIgdGJsX2RlZnJlZCA9IDY7XG4gIHZhciB0YmxfZGdvdG8gPSA3O1xuICB2YXIgdGJsX3NpbmRleCA9IDg7XG4gIHZhciB0YmxfcmluZGV4ID0gOTtcbiAgdmFyIHRibF9naW5kZXggPSAxMDtcbiAgdmFyIHRibF90YWJsZXNpemUgPSAxMTtcbiAgdmFyIHRibF90YWJsZSA9IDEyO1xuICB2YXIgdGJsX2NoZWNrID0gMTM7XG4gIC8vIHZhciBfdGJsX2Vycm9yX2Z1bmN0aW9uID0gMTQ7XG4gIHZhciB0YmxfbmFtZXNfY29uc3QgPSAxNTtcbiAgdmFyIHRibF9uYW1lc19ibG9jayA9IDE2O1xuXG5cbiAgZnVuY3Rpb24gbG9nKHgpIHtcbiAgICB2YXIgcyA9IGNhbWxfc3RyaW5nX29mX2pzYnl0ZXMoeCArIFwiXFxuXCIpO1xuICAgIGNhbWxfbWxfb3V0cHV0KDIsIHMsIDAsIGNhbWxfbWxfc3RyaW5nX2xlbmd0aChzKSk7XG4gIH1cblxuICBmdW5jdGlvbiB0b2tlbl9uYW1lKG5hbWVzLCBudW1iZXIpXG4gIHtcbiAgICB2YXIgc3RyID0gY2FtbF9qc3N0cmluZ19vZl9zdHJpbmcobmFtZXMpO1xuICAgIGlmIChzdHJbMF0gPT0gJ1xceDAwJylcbiAgICAgIHJldHVybiBcIjx1bmtub3duIHRva2VuPlwiO1xuICAgIHJldHVybiBzdHIuc3BsaXQoJ1xceDAwJylbbnVtYmVyXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHByaW50X3Rva2VuKHN0YXRlLCB0b2spXG4gIHtcbiAgICB2YXIgdG9rZW4sIGtpbmQ7XG4gICAgaWYgKHRvayBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICB0b2tlbiA9IHRva2VuX25hbWUodGFibGVzW3RibF9uYW1lc19ibG9ja10sIHRva1swXSk7XG4gICAgICBpZiAodHlwZW9mIHRva1sxXSA9PSBcIm51bWJlclwiKVxuICAgICAgICBraW5kID0gXCJcIiArIHRva1sxXTtcbiAgICAgIGVsc2UgaWYgKHR5cGVvZiB0b2tbMV0gPT0gXCJzdHJpbmdcIilcbiAgICAgICAga2luZCA9IHRva1sxXVxuICAgICAgZWxzZSBpZiAodG9rWzFdIGluc3RhbmNlb2YgTWxCeXRlcylcbiAgICAgICAga2luZCA9IGNhbWxfanNieXRlc19vZl9zdHJpbmcodG9rWzFdKVxuICAgICAgZWxzZVxuICAgICAgICBraW5kID0gXCJfXCJcbiAgICAgIGxvZyhcIlN0YXRlIFwiICsgc3RhdGUgKyBcIjogcmVhZCB0b2tlbiBcIiArIHRva2VuICsgXCIoXCIgKyBraW5kICsgXCIpXCIpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0b2tlbiA9IHRva2VuX25hbWUodGFibGVzW3RibF9uYW1lc19jb25zdF0sIHRvayk7XG4gICAgICBsb2coXCJTdGF0ZSBcIiArIHN0YXRlICsgXCI6IHJlYWQgdG9rZW4gXCIgKyB0b2tlbik7XG4gICAgfVxuICB9XG5cbiAgaWYgKCF0YWJsZXMuZGdvdG8pIHtcbiAgICB0YWJsZXMuZGVmcmVkID0gY2FtbF9sZXhfYXJyYXkgKHRhYmxlc1t0YmxfZGVmcmVkXSk7XG4gICAgdGFibGVzLnNpbmRleCA9IGNhbWxfbGV4X2FycmF5ICh0YWJsZXNbdGJsX3NpbmRleF0pO1xuICAgIHRhYmxlcy5jaGVjayAgPSBjYW1sX2xleF9hcnJheSAodGFibGVzW3RibF9jaGVja10pO1xuICAgIHRhYmxlcy5yaW5kZXggPSBjYW1sX2xleF9hcnJheSAodGFibGVzW3RibF9yaW5kZXhdKTtcbiAgICB0YWJsZXMudGFibGUgID0gY2FtbF9sZXhfYXJyYXkgKHRhYmxlc1t0YmxfdGFibGVdKTtcbiAgICB0YWJsZXMubGVuICAgID0gY2FtbF9sZXhfYXJyYXkgKHRhYmxlc1t0YmxfbGVuXSk7XG4gICAgdGFibGVzLmxocyAgICA9IGNhbWxfbGV4X2FycmF5ICh0YWJsZXNbdGJsX2xoc10pO1xuICAgIHRhYmxlcy5naW5kZXggPSBjYW1sX2xleF9hcnJheSAodGFibGVzW3RibF9naW5kZXhdKTtcbiAgICB0YWJsZXMuZGdvdG8gID0gY2FtbF9sZXhfYXJyYXkgKHRhYmxlc1t0YmxfZGdvdG9dKTtcbiAgfVxuXG4gIHZhciByZXMgPSAwLCBuLCBuMSwgbjIsIHN0YXRlMTtcblxuICAvLyBSRVNUT1JFXG4gIHZhciBzcCA9IGVudltlbnZfc3BdO1xuICB2YXIgc3RhdGUgPSBlbnZbZW52X3N0YXRlXTtcbiAgdmFyIGVycmZsYWcgPSBlbnZbZW52X2VycmZsYWddO1xuXG4gIGV4aXQ6Zm9yICg7Oykge1xuICAgIG5leHQ6c3dpdGNoKGNtZCkge1xuICAgIGNhc2UgMDovL1NUQVJUOlxuICAgICAgc3RhdGUgPSAwO1xuICAgICAgZXJyZmxhZyA9IDA7XG4gICAgICAvLyBGYWxsIHRocm91Z2hcblxuICAgIGNhc2UgNjovL2xvb3A6XG4gICAgICBuID0gdGFibGVzLmRlZnJlZFtzdGF0ZV07XG4gICAgICBpZiAobiAhPSAwKSB7IGNtZCA9IHJlZHVjZTsgYnJlYWs7IH1cbiAgICAgIGlmIChlbnZbZW52X2N1cnJfY2hhcl0gPj0gMCkgeyBjbWQgPSB0ZXN0c2hpZnQ7IGJyZWFrOyB9XG4gICAgICByZXMgPSBSRUFEX1RPS0VOO1xuICAgICAgYnJlYWsgZXhpdDtcbiAgICAgIC8qIFRoZSBNTCBjb2RlIGNhbGxzIHRoZSBsZXhlciBhbmQgdXBkYXRlcyAqL1xuICAgICAgLyogc3ltYl9zdGFydCBhbmQgc3ltYl9lbmQgKi9cbiAgICBjYXNlIDE6Ly9UT0tFTl9SRUFEOlxuICAgICAgaWYgKGFyZyBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgIGVudltlbnZfY3Vycl9jaGFyXSA9IHRhYmxlc1t0YmxfdHJhbnNsX2Jsb2NrXVthcmdbMF0gKyAxXTtcbiAgICAgICAgZW52W2Vudl9sdmFsXSA9IGFyZ1sxXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVudltlbnZfY3Vycl9jaGFyXSA9IHRhYmxlc1t0YmxfdHJhbnNsX2NvbnN0XVthcmcgKyAxXTtcbiAgICAgICAgZW52W2Vudl9sdmFsXSA9IDA7XG4gICAgICB9XG4gICAgICBpZiAoY2FtbF9wYXJzZXJfdHJhY2UpIHByaW50X3Rva2VuIChzdGF0ZSwgYXJnKTtcbiAgICAgIC8vIEZhbGwgdGhyb3VnaFxuXG4gICAgY2FzZSA3Oi8vdGVzdHNoaWZ0OlxuICAgICAgbjEgPSB0YWJsZXMuc2luZGV4W3N0YXRlXTtcbiAgICAgIG4yID0gbjEgKyBlbnZbZW52X2N1cnJfY2hhcl07XG4gICAgICBpZiAobjEgIT0gMCAmJiBuMiA+PSAwICYmIG4yIDw9IHRhYmxlc1t0YmxfdGFibGVzaXplXSAmJlxuICAgICAgICAgIHRhYmxlcy5jaGVja1tuMl0gPT0gZW52W2Vudl9jdXJyX2NoYXJdKSB7XG4gICAgICAgIGNtZCA9IHNoaWZ0OyBicmVhaztcbiAgICAgIH1cbiAgICAgIG4xID0gdGFibGVzLnJpbmRleFtzdGF0ZV07XG4gICAgICBuMiA9IG4xICsgZW52W2Vudl9jdXJyX2NoYXJdO1xuICAgICAgaWYgKG4xICE9IDAgJiYgbjIgPj0gMCAmJiBuMiA8PSB0YWJsZXNbdGJsX3RhYmxlc2l6ZV0gJiZcbiAgICAgICAgICB0YWJsZXMuY2hlY2tbbjJdID09IGVudltlbnZfY3Vycl9jaGFyXSkge1xuICAgICAgICBuID0gdGFibGVzLnRhYmxlW24yXTtcbiAgICAgICAgY21kID0gcmVkdWNlOyBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChlcnJmbGFnIDw9IDApIHtcbiAgICAgICAgcmVzID0gQ0FMTF9FUlJPUl9GVU5DVElPTjtcbiAgICAgICAgYnJlYWsgZXhpdDtcbiAgICAgIH1cbiAgICAgIC8vIEZhbGwgdGhyb3VnaFxuICAgICAgLyogVGhlIE1MIGNvZGUgY2FsbHMgdGhlIGVycm9yIGZ1bmN0aW9uICovXG4gICAgY2FzZSA1Oi8vRVJST1JfREVURUNURUQ6XG4gICAgICBpZiAoZXJyZmxhZyA8IDMpIHtcbiAgICAgICAgZXJyZmxhZyA9IDM7XG4gICAgICAgIGZvciAoOzspIHtcbiAgICAgICAgICBzdGF0ZTEgPSBlbnZbZW52X3Nfc3RhY2tdW3NwICsgMV07XG4gICAgICAgICAgbjEgPSB0YWJsZXMuc2luZGV4W3N0YXRlMV07XG4gICAgICAgICAgbjIgPSBuMSArIEVSUkNPREU7XG4gICAgICAgICAgaWYgKG4xICE9IDAgJiYgbjIgPj0gMCAmJiBuMiA8PSB0YWJsZXNbdGJsX3RhYmxlc2l6ZV0gJiZcbiAgICAgICAgICAgICAgdGFibGVzLmNoZWNrW24yXSA9PSBFUlJDT0RFKSB7XG4gICAgICAgICAgICBpZiAoY2FtbF9wYXJzZXJfdHJhY2UpXG4gICAgICAgICAgICAgIGxvZyhcIlJlY292ZXJpbmcgaW4gc3RhdGUgXCIgKyBzdGF0ZTEpO1xuICAgICAgICAgICAgY21kID0gc2hpZnRfcmVjb3ZlcjsgYnJlYWsgbmV4dDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGNhbWxfcGFyc2VyX3RyYWNlKVxuICAgICAgICAgICAgICBsb2coXCJEaXNjYXJkaW5nIHN0YXRlIFwiICsgc3RhdGUxKTtcbiAgICAgICAgICAgIGlmIChzcCA8PSBlbnZbZW52X3N0YWNrYmFzZV0pIHtcbiAgICAgICAgICAgICAgaWYgKGNhbWxfcGFyc2VyX3RyYWNlKVxuICAgICAgICAgICAgICAgIGxvZyhcIk5vIG1vcmUgc3RhdGVzIHRvIGRpc2NhcmRcIik7XG4gICAgICAgICAgICAgIHJldHVybiBSQUlTRV9QQVJTRV9FUlJPUjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8qIFRoZSBNTCBjb2RlIHJhaXNlcyBQYXJzZV9lcnJvciAqL1xuICAgICAgICAgICAgc3AtLTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChlbnZbZW52X2N1cnJfY2hhcl0gPT0gMClcbiAgICAgICAgICByZXR1cm4gUkFJU0VfUEFSU0VfRVJST1I7IC8qIFRoZSBNTCBjb2RlIHJhaXNlcyBQYXJzZV9lcnJvciAqL1xuICAgICAgICBpZiAoY2FtbF9wYXJzZXJfdHJhY2UpXG4gICAgICAgICAgbG9nKFwiRGlzY2FyZGluZyBsYXN0IHRva2VuIHJlYWRcIik7XG4gICAgICAgIGVudltlbnZfY3Vycl9jaGFyXSA9IC0xO1xuICAgICAgICBjbWQgPSBsb29wOyBicmVhaztcbiAgICAgIH1cbiAgICAgIC8vIEZhbGwgdGhyb3VnaFxuICAgIGNhc2UgODovL3NoaWZ0OlxuICAgICAgZW52W2Vudl9jdXJyX2NoYXJdID0gLTE7XG4gICAgICBpZiAoZXJyZmxhZyA+IDApIGVycmZsYWctLTtcbiAgICAgIC8vIEZhbGwgdGhyb3VnaFxuICAgIGNhc2UgOTovL3NoaWZ0X3JlY292ZXI6XG4gICAgICBpZiAoY2FtbF9wYXJzZXJfdHJhY2UpXG4gICAgICAgIGxvZyhcIlN0YXRlIFwiICsgc3RhdGUgKyBcIjogc2hpZnQgdG8gc3RhdGUgXCIgKyB0YWJsZXMudGFibGVbbjJdKTtcbiAgICAgIHN0YXRlID0gdGFibGVzLnRhYmxlW24yXTtcbiAgICAgIHNwKys7XG4gICAgICBpZiAoc3AgPj0gZW52W2Vudl9zdGFja3NpemVdKSB7XG4gICAgICAgIHJlcyA9IEdST1dfU1RBQ0tTXzE7XG4gICAgICAgIGJyZWFrIGV4aXQ7XG4gICAgICB9XG4gICAgICAvLyBGYWxsIHRocm91Z2hcbiAgICAgIC8qIFRoZSBNTCBjb2RlIHJlc2l6ZXMgdGhlIHN0YWNrcyAqL1xuICAgIGNhc2UgMjovL1NUQUNLU19HUk9XTl8xOlxuICAgICAgZW52W2Vudl9zX3N0YWNrXVtzcCArIDFdID0gc3RhdGU7XG4gICAgICBlbnZbZW52X3Zfc3RhY2tdW3NwICsgMV0gPSBlbnZbZW52X2x2YWxdO1xuICAgICAgZW52W2Vudl9zeW1iX3N0YXJ0X3N0YWNrXVtzcCArIDFdID0gZW52W2Vudl9zeW1iX3N0YXJ0XTtcbiAgICAgIGVudltlbnZfc3ltYl9lbmRfc3RhY2tdW3NwICsgMV0gPSBlbnZbZW52X3N5bWJfZW5kXTtcbiAgICAgIGNtZCA9IGxvb3A7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgMTA6Ly9yZWR1Y2U6XG4gICAgICBpZiAoY2FtbF9wYXJzZXJfdHJhY2UpXG4gICAgICAgIGxvZyhcIlN0YXRlIFwiICsgc3RhdGUgKyBcIjogcmVkdWNlIGJ5IHJ1bGUgXCIgKyBuKTtcbiAgICAgIHZhciBtID0gdGFibGVzLmxlbltuXTtcbiAgICAgIGVudltlbnZfYXNwXSA9IHNwO1xuICAgICAgZW52W2Vudl9ydWxlX251bWJlcl0gPSBuO1xuICAgICAgZW52W2Vudl9ydWxlX2xlbl0gPSBtO1xuICAgICAgc3AgPSBzcCAtIG0gKyAxO1xuICAgICAgbSA9IHRhYmxlcy5saHNbbl07XG4gICAgICBzdGF0ZTEgPSBlbnZbZW52X3Nfc3RhY2tdW3NwXTtcbiAgICAgIG4xID0gdGFibGVzLmdpbmRleFttXTtcbiAgICAgIG4yID0gbjEgKyBzdGF0ZTE7XG4gICAgICBpZiAobjEgIT0gMCAmJiBuMiA+PSAwICYmIG4yIDw9IHRhYmxlc1t0YmxfdGFibGVzaXplXSAmJlxuICAgICAgICAgIHRhYmxlcy5jaGVja1tuMl0gPT0gc3RhdGUxKVxuICAgICAgICBzdGF0ZSA9IHRhYmxlcy50YWJsZVtuMl07XG4gICAgICBlbHNlXG4gICAgICAgIHN0YXRlID0gdGFibGVzLmRnb3RvW21dO1xuICAgICAgaWYgKHNwID49IGVudltlbnZfc3RhY2tzaXplXSkge1xuICAgICAgICByZXMgPSBHUk9XX1NUQUNLU18yO1xuICAgICAgICBicmVhayBleGl0O1xuICAgICAgfVxuICAgICAgLy8gRmFsbCB0aHJvdWdoXG4gICAgICAvKiBUaGUgTUwgY29kZSByZXNpemVzIHRoZSBzdGFja3MgKi9cbiAgICBjYXNlIDM6Ly9TVEFDS1NfR1JPV05fMjpcbiAgICAgIHJlcyA9IENPTVBVVEVfU0VNQU5USUNfQUNUSU9OO1xuICAgICAgYnJlYWsgZXhpdDtcbiAgICAgIC8qIFRoZSBNTCBjb2RlIGNhbGxzIHRoZSBzZW1hbnRpYyBhY3Rpb24gKi9cbiAgICBjYXNlIDQ6Ly9TRU1BTlRJQ19BQ1RJT05fQ09NUFVURUQ6XG4gICAgICBlbnZbZW52X3Nfc3RhY2tdW3NwICsgMV0gPSBzdGF0ZTtcbiAgICAgIGVudltlbnZfdl9zdGFja11bc3AgKyAxXSA9IGFyZztcbiAgICAgIHZhciBhc3AgPSBlbnZbZW52X2FzcF07XG4gICAgICBlbnZbZW52X3N5bWJfZW5kX3N0YWNrXVtzcCArIDFdID0gZW52W2Vudl9zeW1iX2VuZF9zdGFja11bYXNwICsgMV07XG4gICAgICBpZiAoc3AgPiBhc3ApIHtcbiAgICAgICAgLyogVGhpcyBpcyBhbiBlcHNpbG9uIHByb2R1Y3Rpb24uIFRha2Ugc3ltYl9zdGFydCBlcXVhbCB0byBzeW1iX2VuZC4gKi9cbiAgICAgICAgZW52W2Vudl9zeW1iX3N0YXJ0X3N0YWNrXVtzcCArIDFdID0gZW52W2Vudl9zeW1iX2VuZF9zdGFja11bYXNwICsgMV07XG4gICAgICB9XG4gICAgICBjbWQgPSBsb29wOyBicmVhaztcbiAgICAgIC8qIFNob3VsZCBub3QgaGFwcGVuICovXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBSQUlTRV9QQVJTRV9FUlJPUjtcbiAgICB9XG4gIH1cbiAgLy8gU0FWRVxuICBlbnZbZW52X3NwXSA9IHNwO1xuICBlbnZbZW52X3N0YXRlXSA9IHN0YXRlO1xuICBlbnZbZW52X2VycmZsYWddID0gZXJyZmxhZztcbiAgcmV0dXJuIHJlcztcbn1cblxuLy9Qcm92aWRlczogY2FtbF9zZXRfcGFyc2VyX3RyYWNlXG4vL1JlcXVpcmVzOiBjYW1sX3BhcnNlcl90cmFjZVxuZnVuY3Rpb24gY2FtbF9zZXRfcGFyc2VyX3RyYWNlKGJvb2wpIHtcbiAgdmFyIG9sZGZsYWcgPSBjYW1sX3BhcnNlcl90cmFjZTtcbiAgY2FtbF9wYXJzZXJfdHJhY2UgPSBib29sO1xuICByZXR1cm4gb2xkZmxhZztcbn1cbiIsIi8vIEpzX29mX29jYW1sIHJ1bnRpbWUgc3VwcG9ydFxuLy8gaHR0cDovL3d3dy5vY3NpZ2VuLm9yZy9qc19vZl9vY2FtbC9cbi8vIENvcHlyaWdodCAoQykgMjAyMCAtIEh1Z28gSGV1emFyZFxuLy8gQ29weXJpZ2h0IChDKSAyMDIwIC0gU2hhY2hhciBJdHpoYWt5XG4vL1xuLy8gVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbi8vIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuLy8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgd2l0aCBsaW5raW5nIGV4Y2VwdGlvbjtcbi8vIGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vXG4vLyBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4vLyBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2Vcbi8vIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLlxuXG4vLyBCYXNlZCBvbiBodHRwczovL2dpdGh1Yi5jb20vb2NhbWwvb2NhbWwvYmxvYi80LjA3L290aGVybGlicy9zdHIvc3Ryc3R1YnMuY1xuLy8gQ29waWVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2pzY29xL2pzY29xL2Jsb2IvdjguMTEvY29xLWpzL2pzX3N0dWIvc3RyLmpzXG5cbi8vUHJvdmlkZXM6IHJlX21hdGNoXG4vL1JlcXVpcmVzOiBjYW1sX2pzYnl0ZXNfb2Zfc3RyaW5nLCBjYW1sX2pzX2Zyb21fYXJyYXksIGNhbWxfdWludDhfYXJyYXlfb2Zfc3RyaW5nXG4vL1JlcXVpcmVzOiBjYW1sX3N0cmluZ19nZXRcblxudmFyIHJlX21hdGNoID0gZnVuY3Rpb24oKXtcbiAgdmFyIHJlX3dvcmRfbGV0dGVycyA9IFtcbiAgICAweDAwLCAweDAwLCAweDAwLCAweDAwLCAgICAgICAvKiAweDAwLTB4MUY6IG5vbmUgKi9cbiAgICAweDAwLCAweDAwLCAweEZGLCAweDAzLCAgICAgICAvKiAweDIwLTB4M0Y6IGRpZ2l0cyAwLTkgKi9cbiAgICAweEZFLCAweEZGLCAweEZGLCAweDg3LCAgICAgICAvKiAweDQwLTB4NUY6IEEgdG8gWiwgXyAqL1xuICAgIDB4RkUsIDB4RkYsIDB4RkYsIDB4MDcsICAgICAgIC8qIDB4NjAtMHg3RjogYSB0byB6ICovXG4gICAgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgICAgICAgLyogMHg4MC0weDlGOiBub25lICovXG4gICAgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgICAgICAgLyogMHhBMC0weEJGOiBub25lICovXG4gICAgMHhGRiwgMHhGRiwgMHg3RiwgMHhGRiwgICAgICAgLyogMHhDMC0weERGOiBMYXRpbi0xIGFjY2VudGVkIHVwcGVyY2FzZSAqL1xuICAgIDB4RkYsIDB4RkYsIDB4N0YsIDB4RkYgICAgICAgIC8qIDB4RTAtMHhGRjogTGF0aW4tMSBhY2NlbnRlZCBsb3dlcmNhc2UgKi9cbiAgXTtcblxuICB2YXIgb3Bjb2RlcyA9IHtcbiAgICBDSEFSOiAwLCBDSEFSTk9STTogMSwgU1RSSU5HOiAyLCBTVFJJTkdOT1JNOiAzLCBDSEFSQ0xBU1M6IDQsXG4gICAgQk9MOiA1LCBFT0w6IDYsIFdPUkRCT1VOREFSWTogNyxcbiAgICBCRUdHUk9VUDogOCwgRU5ER1JPVVA6IDksIFJFRkdST1VQOiAxMCxcbiAgICBBQ0NFUFQ6IDExLFxuICAgIFNJTVBMRU9QVDogMTIsIFNJTVBMRVNUQVI6IDEzLCBTSU1QTEVQTFVTOiAxNCxcbiAgICBHT1RPOiAxNSwgUFVTSEJBQ0s6IDE2LCBTRVRNQVJLOiAxNyxcbiAgICBDSEVDS1BST0dSRVNTOiAxOFxuICB9O1xuXG4gIGZ1bmN0aW9uIGlzX3dvcmRfbGV0dGVyKGMpIHtcbiAgICByZXR1cm4gKHJlX3dvcmRfbGV0dGVyc1sgIChjID4+IDMpXSA+PiAoYyAmIDcpKSAmIDE7XG4gIH1cblxuICBmdW5jdGlvbiBpbl9iaXRzZXQocyxpKSB7XG4gICAgcmV0dXJuIChjYW1sX3N0cmluZ19nZXQocywoaSA+PiAzKSkgPj4gKGkgJiA3KSkgJiAxO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVfbWF0Y2hfaW1wbChyZSwgcywgcG9zLCBwYXJ0aWFsKSB7XG5cbiAgICB2YXIgcHJvZyAgICAgICAgICA9IGNhbWxfanNfZnJvbV9hcnJheShyZVsxXSksXG4gICAgICAgIGNwb29sICAgICAgICAgPSBjYW1sX2pzX2Zyb21fYXJyYXkocmVbMl0pLFxuICAgICAgICBub3JtdGFibGUgICAgID0gY2FtbF9qc2J5dGVzX29mX3N0cmluZyhyZVszXSksXG4gICAgICAgIG51bWdyb3VwcyAgICAgPSByZVs0XSB8IDAsXG4gICAgICAgIG51bXJlZ2lzdGVycyAgPSByZVs1XSB8IDAsXG4gICAgICAgIHN0YXJ0Y2hhcnMgICAgPSByZVs2XSB8IDA7XG5cbiAgICB2YXIgcyA9IGNhbWxfdWludDhfYXJyYXlfb2Zfc3RyaW5nKHMpO1xuXG4gICAgdmFyIHBjID0gMCxcbiAgICAgICAgcXVpdCA9IGZhbHNlLFxuICAgICAgICBzdGFjayA9IFtdLFxuICAgICAgICBncm91cHMgPSBuZXcgQXJyYXkobnVtZ3JvdXBzKSxcbiAgICAgICAgcmVfcmVnaXN0ZXIgPSBuZXcgQXJyYXkobnVtcmVnaXN0ZXJzKTtcblxuICAgIGZvcih2YXIgaSA9IDA7IGkgPCBncm91cHMubGVuZ3RoOyBpKyspe1xuICAgICAgZ3JvdXBzW2ldID0ge3N0YXJ0OiAtMSwgZW5kOi0xfVxuICAgIH1cbiAgICBncm91cHNbMF0uc3RhcnQgPSBwb3M7XG5cbiAgICB2YXIgYmFja3RyYWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgd2hpbGUgKHN0YWNrLmxlbmd0aCkge1xuICAgICAgICB2YXIgaXRlbSA9IHN0YWNrLnBvcCgpO1xuICAgICAgICBpZiAoaXRlbS51bmRvKSB7XG4gICAgICAgICAgaXRlbS51bmRvLm9ialtpdGVtLnVuZG8ucHJvcF0gPSBpdGVtLnVuZG8udmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZihpdGVtLnBvcykge1xuICAgICAgICAgIHBjID0gaXRlbS5wb3MucGM7XG4gICAgICAgICAgcG9zID0gaXRlbS5wb3MudHh0O1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcXVpdCA9IHRydWU7XG4gICAgfTtcblxuICAgIHZhciBwdXNoID0gZnVuY3Rpb24oaXRlbSkgeyBzdGFjay5wdXNoKGl0ZW0pOyB9O1xuXG4gICAgdmFyIGFjY2VwdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGdyb3Vwc1swXS5lbmQgPSBwb3M7XG4gICAgICB2YXIgcmVzdWx0ID0gbmV3IEFycmF5KDEgKyBncm91cHMubGVuZ3RoKjIpO1xuICAgICAgcmVzdWx0WzBdID0gMDsgLy8gdGFnXG4gICAgICBmb3IodmFyIGkgPSAwOyBpIDwgZ3JvdXBzLmxlbmd0aDsgaSsrKXtcbiAgICAgICAgdmFyIGcgPSBncm91cHNbaV07XG4gICAgICAgIGlmKGcuc3RhcnQgPCAwIHx8IGcuZW5kIDwgMCkge1xuICAgICAgICAgIGcuc3RhcnQgPSBnLmVuZCA9IC0xO1xuICAgICAgICB9XG4gICAgICAgIHJlc3VsdFsyKmkgKyAxIF0gPSBnLnN0YXJ0O1xuICAgICAgICByZXN1bHRbMippICsgMSArIDEgXSA9IGcuZW5kO1xuICAgICAgfTtcbiAgICAgIHJldHVybiByZXN1bHRcbiAgICB9O1xuXG4gICAgdmFyIHByZWZpeF9tYXRjaCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmKHBhcnRpYWwpIHJldHVybiBhY2NlcHQgKCk7XG4gICAgICBlbHNlIGJhY2t0cmFjayAoKTtcbiAgICB9XG5cbiAgICAvKiBNYWluIERGQSBpbnRlcnByZXRlciBsb29wICovXG4gICAgd2hpbGUgKCFxdWl0KSB7XG4gICAgICB2YXIgb3AgPSBwcm9nW3BjXSAmIDB4ZmYsXG4gICAgICAgICAgc2FyZyA9IHByb2dbcGNdID4+IDgsXG4gICAgICAgICAgdWFyZyA9IHNhcmcgJiAweGZmLFxuICAgICAgICAgIGMgPSBzW3Bvc10sXG4gICAgICAgICAgZ3JvdXA7XG5cbiAgICAgIHBjKys7XG5cbiAgICAgIHN3aXRjaCAob3ApIHtcbiAgICAgIGNhc2Ugb3Bjb2Rlcy5DSEFSOlxuICAgICAgICBpZihwb3MgPT09IHMubGVuZ3RoKSB7cHJlZml4X21hdGNoICgpOyBicmVha307XG4gICAgICAgIGlmIChjID09PSB1YXJnKSBwb3MrKztcbiAgICAgICAgZWxzZSBiYWNrdHJhY2soKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIG9wY29kZXMuQ0hBUk5PUk06XG4gICAgICAgIGlmKHBvcyA9PT0gcy5sZW5ndGgpIHtwcmVmaXhfbWF0Y2ggKCk7IGJyZWFrfTtcbiAgICAgICAgaWYgKG5vcm10YWJsZS5jaGFyQ29kZUF0KGMpID09PSB1YXJnKSBwb3MrKztcbiAgICAgICAgZWxzZSBiYWNrdHJhY2soKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIG9wY29kZXMuU1RSSU5HOlxuICAgICAgICBmb3IgKHZhciBhcmcgPSBjYW1sX2pzYnl0ZXNfb2Zfc3RyaW5nKGNwb29sW3VhcmddKSwgaSA9IDA7IGkgPCBhcmcubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBpZihwb3MgPT09IHMubGVuZ3RoKSB7cHJlZml4X21hdGNoICgpOyBicmVha307XG4gICAgICAgICAgaWYgKGMgPT09IGFyZy5jaGFyQ29kZUF0KGkpKVxuICAgICAgICAgICAgYyA9IHNbKytwb3NdO1xuICAgICAgICAgIGVsc2UgeyBiYWNrdHJhY2soKTsgYnJlYWs7IH1cbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2Ugb3Bjb2Rlcy5TVFJJTkdOT1JNOlxuICAgICAgICBmb3IgKHZhciBhcmcgPSBjYW1sX2pzYnl0ZXNfb2Zfc3RyaW5nKGNwb29sW3VhcmddKSwgaSA9IDA7IGkgPCBhcmcubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBpZihwb3MgPT09IHMubGVuZ3RoKSB7cHJlZml4X21hdGNoICgpOyBicmVha307XG4gICAgICAgICAgaWYgKG5vcm10YWJsZS5jaGFyQ29kZUF0KGMpID09PSBhcmcuY2hhckNvZGVBdChpKSlcbiAgICAgICAgICAgIGMgPSBzWysrcG9zXTtcbiAgICAgICAgICBlbHNlIHsgYmFja3RyYWNrKCk7IGJyZWFrOyB9XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIG9wY29kZXMuQ0hBUkNMQVNTOlxuICAgICAgICBpZihwb3MgPT09IHMubGVuZ3RoKSB7cHJlZml4X21hdGNoICgpOyBicmVha307XG4gICAgICAgIGlmIChpbl9iaXRzZXQoY3Bvb2xbdWFyZ10sIGMpKSBwb3MrKztcbiAgICAgICAgZWxzZSBiYWNrdHJhY2soKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIG9wY29kZXMuQk9MOlxuICAgICAgICBpZihwb3MgPiAwICYmIHNbcG9zIC0gMV0gIT0gMTAgLyogXFxuICovKSB7YmFja3RyYWNrKCl9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBvcGNvZGVzLkVPTDpcbiAgICAgICAgaWYocG9zIDwgcy5sZW5ndGggJiYgc1twb3NdICE9IDEwIC8qIFxcbiAqLykge2JhY2t0cmFjaygpfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2Ugb3Bjb2Rlcy5XT1JEQk9VTkRBUlk6XG4gICAgICAgIGlmKHBvcyA9PSAwKSB7XG4gICAgICAgICAgaWYocG9zID09PSBzLmxlbmd0aCkge3ByZWZpeF9tYXRjaCAoKTsgYnJlYWt9O1xuICAgICAgICAgIGlmKGlzX3dvcmRfbGV0dGVyKHNbMF0pKSBicmVhaztcbiAgICAgICAgICBiYWNrdHJhY2soKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChwb3MgPT09IHMubGVuZ3RoKSB7XG4gICAgICAgICAgaWYoaXNfd29yZF9sZXR0ZXIoc1twb3MgLSAxXSkpIGJyZWFrO1xuICAgICAgICAgIGJhY2t0cmFjayAoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBpZihpc193b3JkX2xldHRlcihzW3BvcyAtIDFdKSAhPSBpc193b3JkX2xldHRlcihzW3Bvc10pKSBicmVhaztcbiAgICAgICAgICBiYWNrdHJhY2sgKCk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIG9wY29kZXMuQkVHR1JPVVA6XG4gICAgICAgIGdyb3VwID0gZ3JvdXBzW3VhcmddO1xuICAgICAgICBwdXNoKHt1bmRvOiB7b2JqOmdyb3VwLFxuICAgICAgICAgICAgICAgICAgICAgcHJvcDonc3RhcnQnLFxuICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGdyb3VwLnN0YXJ0fX0pO1xuICAgICAgICBncm91cC5zdGFydCA9IHBvcztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIG9wY29kZXMuRU5ER1JPVVA6XG4gICAgICAgIGdyb3VwID0gZ3JvdXBzW3VhcmddO1xuICAgICAgICBwdXNoKHt1bmRvOiB7b2JqOiBncm91cCxcbiAgICAgICAgICAgICAgICAgICAgIHByb3A6J2VuZCcsXG4gICAgICAgICAgICAgICAgICAgICB2YWx1ZTogZ3JvdXAuZW5kfX0pO1xuICAgICAgICBncm91cC5lbmQgPSBwb3M7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBvcGNvZGVzLlJFRkdST1VQOlxuICAgICAgICBncm91cCA9IGdyb3Vwc1t1YXJnXTtcbiAgICAgICAgaWYoZ3JvdXAuc3RhcnQgPCAwIHx8IGdyb3VwLmVuZCA8IDApIHtiYWNrdHJhY2sgKCk7IGJyZWFrfVxuICAgICAgICBmb3IgKHZhciBpID0gZ3JvdXAuc3RhcnQ7IGkgPCBncm91cC5lbmQ7IGkrKyl7XG4gICAgICAgICAgaWYocG9zID09PSBzLmxlbmd0aCkge3ByZWZpeF9tYXRjaCAoKTsgYnJlYWt9O1xuICAgICAgICAgIGlmKHNbaV0gIT0gc1twb3NdKSB7YmFja3RyYWNrICgpOyBicmVha31cbiAgICAgICAgICBwb3MrKztcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2Ugb3Bjb2Rlcy5TSU1QTEVPUFQ6XG4gICAgICAgIGlmIChpbl9iaXRzZXQoY3Bvb2xbdWFyZ10sIGMpKSBwb3MrKztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIG9wY29kZXMuU0lNUExFU1RBUjpcbiAgICAgICAgd2hpbGUgKGluX2JpdHNldChjcG9vbFt1YXJnXSwgYykpXG4gICAgICAgICAgYyA9IHNbKytwb3NdO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2Ugb3Bjb2Rlcy5TSU1QTEVQTFVTOlxuICAgICAgICBpZihwb3MgPT09IHMubGVuZ3RoKSB7cHJlZml4X21hdGNoICgpOyBicmVha307XG4gICAgICAgIGlmIChpbl9iaXRzZXQoY3Bvb2xbdWFyZ10sIGMpKSB7XG4gICAgICAgICAgZG8ge1xuICAgICAgICAgICAgYyA9IHNbKytwb3NdO1xuICAgICAgICAgIH0gd2hpbGUgKGluX2JpdHNldChjcG9vbFt1YXJnXSwgYykpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgYmFja3RyYWNrKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBvcGNvZGVzLkFDQ0VQVDpcbiAgICAgICAgcmV0dXJuIGFjY2VwdCgpO1xuICAgICAgY2FzZSBvcGNvZGVzLkdPVE86XG4gICAgICAgIHBjID0gcGMgKyBzYXJnO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2Ugb3Bjb2Rlcy5QVVNIQkFDSzpcbiAgICAgICAgcHVzaCh7cG9zOiB7cGM6IHBjICsgc2FyZywgdHh0OiBwb3N9fSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBvcGNvZGVzLlNFVE1BUks6XG4gICAgICAgIHB1c2goe3VuZG86IHtvYmo6cmVfcmVnaXN0ZXIsXG4gICAgICAgICAgICAgICAgICAgICBwcm9wOiB1YXJnLFxuICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHJlX3JlZ2lzdGVyW3VhcmddfX0pO1xuICAgICAgICByZV9yZWdpc3Rlclt1YXJnXSA9IHBvcztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIG9wY29kZXMuQ0hFQ0tQUk9HUkVTUzpcbiAgICAgICAgaWYgKHJlX3JlZ2lzdGVyW3VhcmddID09PSBwb3MpIGJhY2t0cmFjaygpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgYnl0ZWNvZGVcIik7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiAwO1xuICB9XG5cbiAgcmV0dXJuIHJlX21hdGNoX2ltcGw7XG59KCk7XG5cblxuLy9Qcm92aWRlczogcmVfc2VhcmNoX2ZvcndhcmRcbi8vUmVxdWlyZXM6IHJlX21hdGNoLCBjYW1sX21sX3N0cmluZ19sZW5ndGgsIGNhbWxfaW52YWxpZF9hcmd1bWVudFxuZnVuY3Rpb24gcmVfc2VhcmNoX2ZvcndhcmQocmUsIHMsIHBvcykge1xuICBpZihwb3MgPCAwIHx8IHBvcyA+IGNhbWxfbWxfc3RyaW5nX2xlbmd0aChzKSlcbiAgICBjYW1sX2ludmFsaWRfYXJndW1lbnQoXCJTdHIuc2VhcmNoX2ZvcndhcmRcIilcbiAgd2hpbGUgKHBvcyA8PSBjYW1sX21sX3N0cmluZ19sZW5ndGgocykpIHtcbiAgICB2YXIgcmVzID0gcmVfbWF0Y2gocmUsIHMsIHBvcywgMCk7XG4gICAgaWYgKHJlcykgcmV0dXJuIHJlcztcbiAgICBwb3MrKztcbiAgfVxuXG4gIHJldHVybiBbMF07ICAvKiBbfHxdIDogaW50IGFycmF5ICovXG59XG5cbi8vUHJvdmlkZXM6IHJlX3NlYXJjaF9iYWNrd2FyZFxuLy9SZXF1aXJlczogcmVfbWF0Y2gsIGNhbWxfbWxfc3RyaW5nX2xlbmd0aCwgY2FtbF9pbnZhbGlkX2FyZ3VtZW50XG5mdW5jdGlvbiByZV9zZWFyY2hfYmFja3dhcmQocmUsIHMsIHBvcykge1xuICBpZihwb3MgPCAwIHx8IHBvcyA+IGNhbWxfbWxfc3RyaW5nX2xlbmd0aChzKSlcbiAgICBjYW1sX2ludmFsaWRfYXJndW1lbnQoXCJTdHIuc2VhcmNoX2JhY2t3YXJkXCIpXG4gIHdoaWxlIChwb3MgPj0gMCkge1xuICAgIHZhciByZXMgPSByZV9tYXRjaChyZSwgcywgcG9zLCAwKTtcbiAgICBpZiAocmVzKSByZXR1cm4gcmVzO1xuICAgIHBvcy0tO1xuICB9XG5cbiAgcmV0dXJuIFswXTsgIC8qIFt8fF0gOiBpbnQgYXJyYXkgKi9cbn1cblxuXG4vL1Byb3ZpZGVzOiByZV9zdHJpbmdfbWF0Y2hcbi8vUmVxdWlyZXM6IHJlX21hdGNoLCBjYW1sX21sX3N0cmluZ19sZW5ndGgsIGNhbWxfaW52YWxpZF9hcmd1bWVudFxuZnVuY3Rpb24gcmVfc3RyaW5nX21hdGNoKHJlLHMscG9zKXtcbiAgaWYocG9zIDwgMCB8fCBwb3MgPiBjYW1sX21sX3N0cmluZ19sZW5ndGgocykpXG4gICAgY2FtbF9pbnZhbGlkX2FyZ3VtZW50KFwiU3RyLnN0cmluZ19tYXRjaFwiKVxuICB2YXIgcmVzID0gcmVfbWF0Y2gocmUsIHMsIHBvcywgMCk7XG4gIGlmIChyZXMpIHJldHVybiByZXM7XG4gIGVsc2UgcmV0dXJuIFswXTtcbn1cblxuLy9Qcm92aWRlczogcmVfcGFydGlhbF9tYXRjaFxuLy9SZXF1aXJlczogcmVfbWF0Y2gsIGNhbWxfbWxfc3RyaW5nX2xlbmd0aCwgY2FtbF9pbnZhbGlkX2FyZ3VtZW50XG5mdW5jdGlvbiByZV9wYXJ0aWFsX21hdGNoKHJlLHMscG9zKXtcbiAgaWYocG9zIDwgMCB8fCBwb3MgPiBjYW1sX21sX3N0cmluZ19sZW5ndGgocykpXG4gICAgY2FtbF9pbnZhbGlkX2FyZ3VtZW50KFwiU3RyLnBhcnRpYWxfbWF0Y2hcIilcbiAgdmFyIHJlcyA9IHJlX21hdGNoKHJlLCBzLCBwb3MsIDEpO1xuICBpZiAocmVzKSByZXR1cm4gcmVzO1xuICBlbHNlIHJldHVybiBbMF07XG59XG5cbi8vUHJvdmlkZXM6IHJlX3JlcGxhY2VtZW50X3RleHRcbi8vUmVxdWlyZXM6IGNhbWxfanNieXRlc19vZl9zdHJpbmcsIGNhbWxfc3RyaW5nX29mX2pzYnl0ZXNcbi8vUmVxdWlyZXM6IGNhbWxfYXJyYXlfZ2V0XG4vL1JlcXVpcmVzOiBjYW1sX2ZhaWx3aXRoXG4vLyBleHRlcm5hbCByZV9yZXBsYWNlbWVudF90ZXh0OiBzdHJpbmcgLT4gaW50IGFycmF5IC0+IHN0cmluZyAtPiBzdHJpbmdcbmZ1bmN0aW9uIHJlX3JlcGxhY2VtZW50X3RleHQocmVwbCxncm91cHMsb3JpZykge1xuICB2YXIgcmVwbCA9IGNhbWxfanNieXRlc19vZl9zdHJpbmcocmVwbCk7XG4gIHZhciBsZW4gPSByZXBsLmxlbmd0aDtcbiAgdmFyIG9yaWcgPSBjYW1sX2pzYnl0ZXNfb2Zfc3RyaW5nKG9yaWcpO1xuICB2YXIgcmVzID0gXCJcIjsgLy9yZXN1bHRcbiAgdmFyIG4gPSAwOyAvLyBjdXJyZW50IHBvc2l0aW9uXG4gIHZhciBjdXI7IC8vY3VycmVudCBjaGFyXG4gIHZhciBzdGFydCwgZW5kLCBjO1xuICB3aGlsZShuIDwgbGVuKXtcbiAgICBjdXIgPSByZXBsLmNoYXJBdChuKyspO1xuICAgIGlmKGN1ciAhPSAnXFxcXCcpe1xuICAgICAgcmVzICs9IGN1cjtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBpZihuID09IGxlbikgY2FtbF9mYWlsd2l0aChcIlN0ci5yZXBsYWNlOiBpbGxlZ2FsIGJhY2tzbGFzaCBzZXF1ZW5jZVwiKTtcbiAgICAgIGN1ciA9IHJlcGwuY2hhckF0KG4rKyk7XG4gICAgICBzd2l0Y2goY3VyKXtcbiAgICAgIGNhc2UgJ1xcXFwnOlxuICAgICAgICByZXMgKz0gY3VyO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJzAnOiBjYXNlICcxJzogY2FzZSAnMic6IGNhc2UgJzMnOiBjYXNlICc0JzpcbiAgICAgIGNhc2UgJzUnOiBjYXNlICc2JzogY2FzZSAnNyc6IGNhc2UgJzgnOiBjYXNlICc5JzpcbiAgICAgICAgYyA9ICtjdXI7XG4gICAgICAgIGlmIChjKjIgPj0gZ3JvdXBzLmxlbmd0aCAtIDEgKVxuICAgICAgICAgIGNhbWxfZmFpbHdpdGgoXCJTdHIucmVwbGFjZTogcmVmZXJlbmNlIHRvIHVubWF0Y2hlZCBncm91cFwiICk7XG4gICAgICAgIHN0YXJ0ID0gY2FtbF9hcnJheV9nZXQoZ3JvdXBzLGMqMik7XG4gICAgICAgIGVuZCA9IGNhbWxfYXJyYXlfZ2V0KGdyb3VwcywgYyoyICsxKTtcbiAgICAgICAgaWYgKHN0YXJ0ID09IC0xKVxuICAgICAgICAgIGNhbWxfZmFpbHdpdGgoXCJTdHIucmVwbGFjZTogcmVmZXJlbmNlIHRvIHVubWF0Y2hlZCBncm91cFwiKTtcbiAgICAgICAgcmVzKz1vcmlnLnNsaWNlKHN0YXJ0LGVuZCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmVzICs9ICgnXFxcXCcgICsgY3VyKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNhbWxfc3RyaW5nX29mX2pzYnl0ZXMocmVzKTsgfVxuXG5cbi8vUHJvdmlkZXM6IGNhbWxfc3RyX2luaXRpYWxpemVcbmZ1bmN0aW9uIGNhbWxfc3RyX2luaXRpYWxpemUodW5pdCkge1xuICByZXR1cm4gMDtcbn1cbiIsIigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0NhbWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICBCZW5vaXQgVmF1Z29uLCBFTlNUQSAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQ29weXJpZ2h0IDIwMTQgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCAgICAgKilcbigqICAgICBlbiBBdXRvbWF0aXF1ZS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQWxsIHJpZ2h0cyByZXNlcnZlZC4gIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgICAgKilcbigqICAgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIuMSwgd2l0aCB0aGUgICAgICAgICAgKilcbigqICAgc3BlY2lhbCBleGNlcHRpb24gb24gbGlua2luZyBkZXNjcmliZWQgaW4gdGhlIGZpbGUgTElDRU5TRS4gICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcblxuKCogUGFkZGluZyBwb3NpdGlvbi4gKilcbnR5cGUgcGFkdHkgPVxuICB8IExlZnQgICAoKiBUZXh0IGlzIGxlZnQganVzdGlmaWVkICgnLScgb3B0aW9uKS4gICAgICAgICAgICAgICAqKVxuICB8IFJpZ2h0ICAoKiBUZXh0IGlzIHJpZ2h0IGp1c3RpZmllZCAobm8gJy0nIG9wdGlvbikuICAgICAgICAgICAqKVxuICB8IFplcm9zICAoKiBUZXh0IGlzIHJpZ2h0IGp1c3RpZmllZCBieSB6ZXJvcyAoc2VlICcwJyBvcHRpb24pLiAqKVxuXG4oKioqKVxuXG4oKiBJbnRlZ2VyIGNvbnZlcnNpb24uICopXG50eXBlIGludF9jb252ID1cbiAgfCBJbnRfZCB8IEludF9wZCB8IEludF9zZCAgICAgICAgKCogICVkIHwgJStkIHwgJSBkICAqKVxuICB8IEludF9pIHwgSW50X3BpIHwgSW50X3NpICAgICAgICAoKiAgJWkgfCAlK2kgfCAlIGkgICopXG4gIHwgSW50X3ggfCBJbnRfQ3ggICAgICAgICAgICAgICAgICgqICAleCB8ICUjeCAgICAgICAgKilcbiAgfCBJbnRfWCB8IEludF9DWCAgICAgICAgICAgICAgICAgKCogICVYIHwgJSNYICAgICAgICAqKVxuICB8IEludF9vIHwgSW50X0NvICAgICAgICAgICAgICAgICAoKiAgJW8gfCAlI28gICAgICAgICopXG4gIHwgSW50X3UgICAgICAgICAgICAgICAgICAgICAgICAgICgqICAldSAgICAgICAgICAgICAgKilcbiAgfCBJbnRfQ2QgfCBJbnRfQ2kgfCBJbnRfQ3UgICAgICAgKCogICUjZCB8ICUjaSB8ICUjdSAqKVxuXG4oKiBGbG9hdCBjb252ZXJzaW9uLiAqKVxudHlwZSBmbG9hdF9mbGFnX2NvbnYgPVxuICB8IEZsb2F0X2ZsYWdfICAgICAgICAgICAgICAgICAgICAoKiAlW2ZlRWdHRmhIXSAqKVxuICB8IEZsb2F0X2ZsYWdfcCAgICAgICAgICAgICAgICAgICAoKiAlK1tmZUVnR0ZoSF0gKilcbiAgfCBGbG9hdF9mbGFnX3MgICAgICAgICAgICAgICAgICAgKCogJSBbZmVFZ0dGaEhdICopXG50eXBlIGZsb2F0X2tpbmRfY29udiA9XG4gIHwgRmxvYXRfZiAgICAgICAgICAgICAgICAgICAgICAgICgqICAlZiB8ICUrZiB8ICUgZiAgKilcbiAgfCBGbG9hdF9lICAgICAgICAgICAgICAgICAgICAgICAgKCogICVlIHwgJStlIHwgJSBlICAqKVxuICB8IEZsb2F0X0UgICAgICAgICAgICAgICAgICAgICAgICAoKiAgJUUgfCAlK0UgfCAlIEUgICopXG4gIHwgRmxvYXRfZyAgICAgICAgICAgICAgICAgICAgICAgICgqICAlZyB8ICUrZyB8ICUgZyAgKilcbiAgfCBGbG9hdF9HICAgICAgICAgICAgICAgICAgICAgICAgKCogICVHIHwgJStHIHwgJSBHICAqKVxuICB8IEZsb2F0X0YgICAgICAgICAgICAgICAgICAgICAgICAoKiAgJUYgfCAlK0YgfCAlIEYgICopXG4gIHwgRmxvYXRfaCAgICAgICAgICAgICAgICAgICAgICAgICgqICAlaCB8ICUraCB8ICUgaCAgKilcbiAgfCBGbG9hdF9IICAgICAgICAgICAgICAgICAgICAgICAgKCogICVIIHwgJStIIHwgJSBIICAqKVxuICB8IEZsb2F0X0NGICAgICAgICAgICAgICAgICAgICAgICAoKiAgJSNGfCAlKyNGfCAlICNGICopXG50eXBlIGZsb2F0X2NvbnYgPSBmbG9hdF9mbGFnX2NvbnYgKiBmbG9hdF9raW5kX2NvbnZcblxuKCoqKilcblxuKCogQ2hhciBzZXRzIChzZWUgJVsuLi5dKSBhcmUgYml0bWFwcyBpbXBsZW1lbnRlZCBhcyAzMi1jaGFyIHN0cmluZ3MuICopXG50eXBlIGNoYXJfc2V0ID0gc3RyaW5nXG5cbigqKiopXG5cbigqIENvdW50ZXIgdXNlZCBpbiBTY2FuZi4gKilcbnR5cGUgY291bnRlciA9XG4gIHwgTGluZV9jb3VudGVyICAgICAoKiAgJWwgICAgICAqKVxuICB8IENoYXJfY291bnRlciAgICAgKCogICVuICAgICAgKilcbiAgfCBUb2tlbl9jb3VudGVyICAgICgqICAlTiwgJUwgICopXG5cbigqKiopXG5cbigqIFBhZGRpbmcgb2Ygc3RyaW5ncyBhbmQgbnVtYmVycy4gKilcbnR5cGUgKCdhLCAnYikgcGFkZGluZyA9XG4gICgqIE5vIHBhZGRpbmcgKGV4OiBcIiVkXCIpICopXG4gIHwgTm9fcGFkZGluZyAgOiAoJ2EsICdhKSBwYWRkaW5nXG4gICgqIExpdGVyYWwgcGFkZGluZyAoZXg6IFwiJThkXCIpICopXG4gIHwgTGl0X3BhZGRpbmcgOiBwYWR0eSAqIGludCAtPiAoJ2EsICdhKSBwYWRkaW5nXG4gICgqIFBhZGRpbmcgYXMgZXh0cmEgYXJndW1lbnQgKGV4OiBcIiUqZFwiKSAqKVxuICB8IEFyZ19wYWRkaW5nIDogcGFkdHkgLT4gKGludCAtPiAnYSwgJ2EpIHBhZGRpbmdcblxuKCogU29tZSBmb3JtYXRzLCBzdWNoIGFzICVfZCxcbiAgIG9ubHkgYWNjZXB0IGFuIG9wdGlvbmFsIG51bWJlciBhcyBwYWRkaW5nIG9wdGlvbiAobm8gZXh0cmEgYXJndW1lbnQpICopXG50eXBlIHBhZF9vcHRpb24gPSBpbnQgb3B0aW9uXG5cbigqIFByZWNpc2lvbiBvZiBmbG9hdHMgYW5kICcwJy1wYWRkaW5nIG9mIGludGVnZXJzLiAqKVxudHlwZSAoJ2EsICdiKSBwcmVjaXNpb24gPVxuICAoKiBObyBwcmVjaXNpb24gKGV4OiBcIiVmXCIpICopXG4gIHwgTm9fcHJlY2lzaW9uIDogKCdhLCAnYSkgcHJlY2lzaW9uXG4gICgqIExpdGVyYWwgcHJlY2lzaW9uIChleDogXCIlLjNmXCIpICopXG4gIHwgTGl0X3ByZWNpc2lvbiA6IGludCAtPiAoJ2EsICdhKSBwcmVjaXNpb25cbiAgKCogUHJlY2lzaW9uIGFzIGV4dHJhIGFyZ3VtZW50IChleDogXCIlLipmXCIpICopXG4gIHwgQXJnX3ByZWNpc2lvbiA6IChpbnQgLT4gJ2EsICdhKSBwcmVjaXNpb25cblxuKCogU29tZSBmb3JtYXRzLCBzdWNoIGFzICVfZixcbiAgIG9ubHkgYWNjZXB0IGFuIG9wdGlvbmFsIG51bWJlciBhcyBwcmVjaXNpb24gb3B0aW9uIChubyBleHRyYSBhcmd1bWVudCkgKilcbnR5cGUgcHJlY19vcHRpb24gPSBpbnQgb3B0aW9uXG5cbigqIHNlZSB0aGUgQ3VzdG9tIGZvcm1hdCBjb21iaW5hdG9yICopXG50eXBlICgnYSwgJ2IsICdjKSBjdXN0b21fYXJpdHkgPVxuICB8IEN1c3RvbV96ZXJvIDogKCdhLCBzdHJpbmcsICdhKSBjdXN0b21fYXJpdHlcbiAgfCBDdXN0b21fc3VjYyA6ICgnYSwgJ2IsICdjKSBjdXN0b21fYXJpdHkgLT5cbiAgICAoJ2EsICd4IC0+ICdiLCAneCAtPiAnYykgY3VzdG9tX2FyaXR5XG5cbigqKiopXG5cbigqICAgICAgICBSZWxhdGlvbmFsIGZvcm1hdCB0eXBlc1xuXG5JbiB0aGUgZmlyc3QgZm9ybWF0K2dhZHRzIGltcGxlbWVudGF0aW9uLCB0aGUgdHlwZSBmb3IgJSguLiUpIGluIHRoZVxuZm10IEdBRFQgd2FzIGFzIGZvbGxvd3M6XG5cbnwgRm9ybWF0X3N1YnN0IDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogJSguLi4lKSAqKVxuICAgIHBhZF9vcHRpb24gKiAoJ2QxLCAncTEsICdkMiwgJ3EyKSByZWFkZXJfbmJfdW5pZmllciAqXG4gICAgKCd4LCAnYiwgJ2MsICdkMSwgJ3ExLCAndSkgZm10dHkgKlxuICAgICgndSwgJ2IsICdjLCAncTEsICdlMSwgJ2YpIGZtdCAtPlxuICAgICAgKCgneCwgJ2IsICdjLCAnZDIsICdxMiwgJ3UpIGZvcm1hdDYgLT4gJ3gsICdiLCAnYywgJ2QxLCAnZTEsICdmKSBmbXRcblxuTm90aWNlIHRoYXQgdGhlICd1IHBhcmFtZXRlciBpbiAnZiBwb3NpdGlvbiBpbiB0aGUgZm9ybWF0IGFyZ3VtZW50XG4oKCd4LCAuLiwgJ3UpIGZvcm1hdDYgLT4gLi4pIGlzIGVxdWFsIHRvIHRoZSAndSBwYXJhbWV0ZXIgaW4gJ2FcbnBvc2l0aW9uIGluIHRoZSBmb3JtYXQgdGFpbCAoKCd1LCAuLiwgJ2YpIGZtdCkuIFRoaXMgbWVhbnMgdGhhdCB0aGVcbnR5cGUgb2YgdGhlIGV4cGVjdGVkIGZvcm1hdCBwYXJhbWV0ZXIgZGVwZW5kcyBvZiB3aGVyZSB0aGUgJSguLi4lKVxuYXJlIGluIHRoZSBmb3JtYXQgc3RyaW5nOlxuXG4gICMgUHJpbnRmLnByaW50ZiBcIiUoJSlcIlxuICAtIDogKHVuaXQsIG91dF9jaGFubmVsLCB1bml0LCAnX2EsICdfYSwgdW5pdClcbiAgICAgIENhbWxpbnRlcm5hbEZvcm1hdEJhc2ljcy5mb3JtYXQ2IC0+IHVuaXRcbiAgPSA8ZnVuPlxuICAjIFByaW50Zi5wcmludGYgXCIlKCUpJWRcIlxuICAtIDogKGludCAtPiB1bml0LCBvdXRfY2hhbm5lbCwgdW5pdCwgJ19hLCAnX2EsIGludCAtPiB1bml0KVxuICAgICAgQ2FtbGludGVybmFsRm9ybWF0QmFzaWNzLmZvcm1hdDYgLT4gaW50IC0+IHVuaXRcbiAgPSA8ZnVuPlxuXG5PbiB0aGUgY29udHJhcnksIHRoZSBsZWdhY3kgdHlwZXIgZ2l2ZXMgYSBjbGV2ZXIgdHlwZSB0aGF0IGRvZXMgbm90XG5kZXBlbmQgb24gdGhlIHBvc2l0aW9uIG9mICUoLi4lKSBpbiB0aGUgZm9ybWF0IHN0cmluZy4gRm9yIGV4YW1wbGUsXG4lKCUpIHdpbGwgaGF2ZSB0aGUgcG9seW1vcnBoaWMgdHlwZSAoJ2EsICdiLCAnYywgJ2QsICdkLCAnYSk6IGl0IGNhblxuYmUgY29uY2F0ZW5hdGVkIHRvIGFueSBmb3JtYXQgdHlwZSwgYW5kIG9ubHkgZW5mb3JjZXMgdGhlIGNvbnN0cmFpbnRcbnRoYXQgaXRzICdhIGFuZCAnZiBwYXJhbWV0ZXJzIGFyZSBlcXVhbCAobm8gZm9ybWF0IGFyZ3VtZW50cykgYW5kICdkXG5hbmQgJ2UgYXJlIGVxdWFsIChubyByZWFkZXIgYXJndW1lbnQpLlxuXG5UaGUgd2Vha2VuaW5nIG9mIHRoaXMgcGFyYW1ldGVyIHR5cGUgaW4gdGhlIEdBRFQgdmVyc2lvbiBicm9rZSB1c2VyXG5jb2RlIChpbiBmYWN0IGl0IGVzc2VudGlhbGx5IG1hZGUgJSguLi4lKSB1bnVzYWJsZSBleGNlcHQgYXQgdGhlIGxhc3RcbnBvc2l0aW9uIG9mIGEgZm9ybWF0KS4gSW4gcGFydGljdWxhciwgdGhlIGZvbGxvd2luZyB3b3VsZCBub3Qgd29ya1xuYW55bW9yZTpcblxuICBmdW4gc2VwIC0+XG4gICAgRm9ybWF0LnByaW50ZiBcImZvbyUoJSliYXIlKCUpYmF6XCIgc2VwIHNlcFxuXG5BcyB0aGUgdHlwZS1jaGVja2VyIHdvdWxkIHJlcXVpcmUgdHdvICppbmNvbXBhdGlibGUqIHR5cGVzIGZvciB0aGUgJSglKVxuaW4gZGlmZmVyZW50IHBvc2l0aW9ucy5cblxuVGhlIHNvbHV0aW9uIHRvIHJlZ2FpbiBhIGdlbmVyYWwgdHlwZSBmb3IgJSguLiUpIGlzIHRvIGdlbmVyYWxpemUgdGhpc1xudGVjaG5pcXVlLCBub3Qgb25seSBvbiB0aGUgJ2QsICdlIHBhcmFtZXRlcnMsIGJ1dCBvbiBhbGwgc2l4XG5wYXJhbWV0ZXJzIG9mIGEgZm9ybWF0OiB3ZSBpbnRyb2R1Y2UgYSBcInJlbGF0aW9uYWxcIiB0eXBlXG4gICgnYTEsICdiMSwgJ2MxLCAnZDEsICdlMSwgJ2YxLFxuICAgJ2EyLCAnYjIsICdjMiwgJ2QyLCAnZTIsICdmMikgZm10dHlfcmVsXG53aG9zZSB2YWx1ZXMgYXJlIHByb29mcyB0aGF0ICgnYTEsIC4uLCAnZjEpIGFuZCAoJ2EyLCAuLiwgJ2YyKSBtb3JhbGx5XG5jb3JyZXNwb25kIHRvIHRoZSBzYW1lIGZvcm1hdCB0eXBlOiAnYTEgaXMgb2J0YWluZWQgZnJvbSAnZjEsJ2IxLCdjMVxuaW4gdGhlIGV4YWN0IHNhbWUgd2F5IHRoYXQgJ2EyIGlzIG9idGFpbmVkIGZyb20gJ2YyLCdiMiwnYzIsIGV0Yy5cblxuRm9yIGV4YW1wbGUsIHRoZSByZWxhdGlvbiBiZXR3ZWVuIHR3byBmb3JtYXQgdHlwZXMgYmVnaW5uaW5nIHdpdGggYSBDaGFyXG5wYXJhbWV0ZXIgaXMgYXMgZm9sbG93czpcblxufCBDaGFyX3R5IDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogJWMgICopXG4gICAgKCdhMSwgJ2IxLCAnYzEsICdkMSwgJ2UxLCAnZjEsXG4gICAgICdhMiwgJ2IyLCAnYzIsICdkMiwgJ2UyLCAnZjIpIGZtdHR5X3JlbCAtPlxuICAgIChjaGFyIC0+ICdhMSwgJ2IxLCAnYzEsICdkMSwgJ2UxLCAnZjEsXG4gICAgIGNoYXIgLT4gJ2EyLCAnYjIsICdjMiwgJ2QyLCAnZTIsICdmMikgZm10dHlfcmVsXG5cbkluIHRoZSBnZW5lcmFsIGNhc2UsIHRoZSB0ZXJtIHN0cnVjdHVyZSBvZiBmbXR0eV9yZWwgaXMgKGFsbW9zdFsxXSlcbmlzb21vcnBoaWMgdG8gdGhlIGZtdHR5IG9mIHRoZSBwcmV2aW91cyBpbXBsZW1lbnRhdGlvbjogZXZlcnlcbmNvbnN0cnVjdG9yIGlzIHJlLXJlYWQgd2l0aCBhIGJpbmFyeSwgcmVsYXRpb25hbCB0eXBlLCBpbnN0ZWFkIG9mIHRoZVxucHJldmlvdXMgdW5hcnkgdHlwaW5nLiBmbXR0eSBjYW4gdGhlbiBiZSByZS1kZWZpbmVkIGFzIHRoZSBkaWFnb25hbCBvZlxuZm10dHlfcmVsOlxuXG4gIHR5cGUgKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdHR5ID1cbiAgICAgICAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZixcbiAgICAgICAgJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm10dHlfcmVsXG5cbk9uY2Ugd2UgaGF2ZSB0aGlzIGZtdHR5X3JlbCB0eXBlIGluIHBsYWNlLCB3ZSBjYW4gZ2l2ZSB0aGUgbW9yZVxuZ2VuZXJhbCB0eXBlIHRvICUoLi4uJSk6XG5cbnwgRm9ybWF0X3N1YnN0IDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogJSguLi4lKSAqKVxuICAgIHBhZF9vcHRpb24gKlxuICAgICgnZywgJ2gsICdpLCAnaiwgJ2ssICdsLFxuICAgICAnZzIsICdiLCAnYywgJ2oyLCAnZCwgJ2EpIGZtdHR5X3JlbCAqXG4gICAgKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdCAtPlxuICAgICgoJ2csICdoLCAnaSwgJ2osICdrLCAnbCkgZm9ybWF0NiAtPiAnZzIsICdiLCAnYywgJ2oyLCAnZSwgJ2YpIGZtdFxuXG5XZSBhY2NlcHQgYW55IGZvcm1hdCAoKCdnLCAnaCwgJ2ksICdqLCAnaywgJ2wpIGZvcm1hdDYpICh0aGlzIGlzXG5jb21wbGV0ZWx5IHVucmVsYXRlZCB0byB0aGUgdHlwZSBvZiB0aGUgY3VycmVudCBmb3JtYXQpLCBidXQgYWxzb1xucmVxdWlyZSBhIHByb29mIHRoYXQgdGhpcyBmb3JtYXQgaXMgaW4gcmVsYXRpb24gdG8gYW5vdGhlciBmb3JtYXQgdGhhdFxuaXMgY29uY2F0ZW5hYmxlIHRvIHRoZSBmb3JtYXQgdGFpbC4gV2hlbiBleGVjdXRpbmcgYSAlKC4uLiUpIGZvcm1hdFxuKGluIGNhbWxpbnRlcm5hbEZvcm1hdC5tbDptYWtlX3ByaW50ZiBvciBzY2FuZi5tbDptYWtlX3NjYW5mKSwgd2VcbnRyYW5zdHlwZSB0aGUgZm9ybWF0IGFsb25nIHRoaXMgcmVsYXRpb24gdXNpbmcgdGhlICdyZWNhc3QnIGZ1bmN0aW9uXG50byB0cmFuc3Bvc2UgYmV0d2VlbiByZWxhdGVkIGZvcm1hdCB0eXBlcy5cblxuICB2YWwgcmVjYXN0IDpcbiAgICAgKCdhMSwgJ2IxLCAnYzEsICdkMSwgJ2UxLCAnZjEpIGZtdFxuICAtPiAoJ2ExLCAnYjEsICdjMSwgJ2QxLCAnZTEsICdmMSxcbiAgICAgICdhMiwgJ2IyLCAnYzIsICdkMiwgJ2UyLCAnZjIpIGZtdHR5X3JlbFxuICAtPiAoJ2EyLCAnYjIsICdjMiwgJ2QyLCAnZTIsICdmMikgZm10XG5cbk5PVEUgWzFdOiB0aGUgdHlwaW5nIG9mIEZvcm1hdF9zdWJzdF90eSByZXF1aXJlcyBub3Qgb25lIGZvcm1hdCB0eXBlLCBidXRcbnR3bywgb25lIHRvIGVzdGFibGlzaCB0aGUgbGluayBiZXR3ZWVuIHRoZSBmb3JtYXQgYXJndW1lbnQgYW5kIHRoZVxuZmlyc3Qgc2l4IHBhcmFtZXRlcnMsIGFuZCB0aGUgb3RoZXIgZm9yIHRoZSBsaW5rIGJldHdlZW4gdGhlIGZvcm1hdFxuYXJndW1lbnQgYW5kIHRoZSBsYXN0IHNpeCBwYXJhbWV0ZXJzLlxuXG58IEZvcm1hdF9zdWJzdF90eSA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiAlKC4uLiUpICopXG4gICAgKCdnLCAnaCwgJ2ksICdqLCAnaywgJ2wsXG4gICAgICdnMSwgJ2IxLCAnYzEsICdqMSwgJ2QxLCAnYTEpIGZtdHR5X3JlbCAqXG4gICAgKCdnLCAnaCwgJ2ksICdqLCAnaywgJ2wsXG4gICAgICdnMiwgJ2IyLCAnYzIsICdqMiwgJ2QyLCAnYTIpIGZtdHR5X3JlbCAqXG4gICAgKCdhMSwgJ2IxLCAnYzEsICdkMSwgJ2UxLCAnZjEsXG4gICAgICdhMiwgJ2IyLCAnYzIsICdkMiwgJ2UyLCAnZjIpIGZtdHR5X3JlbCAtPlxuICAgICgoJ2csICdoLCAnaSwgJ2osICdrLCAnbCkgZm9ybWF0NiAtPiAnZzEsICdiMSwgJ2MxLCAnajEsICdlMSwgJ2YxLFxuICAgICAoJ2csICdoLCAnaSwgJ2osICdrLCAnbCkgZm9ybWF0NiAtPiAnZzIsICdiMiwgJ2MyLCAnajIsICdlMiwgJ2YyKSBmbXR0eV9yZWxcblxuV2hlbiB3ZSBnZW5lcmF0ZSBhIGZvcm1hdCBBU1QsIHdlIGdlbmVyYXRlIGV4YWN0bHkgdGhlIHNhbWUgd2l0bmVzc1xuZm9yIGJvdGggcmVsYXRpb25zLCBhbmQgdGhlIHdpdG5lc3MtY29udmVyc2lvbiBmdW5jdGlvbnMgaW5cbmNhbWxpbnRlcm5hbEZvcm1hdCBkbyByZWx5IG9uIHRoaXMgaW52YXJpYW50LiBGb3IgZXhhbXBsZSwgdGhlXG5mdW5jdGlvbiB0aGF0IHByb3ZlcyB0aGF0IHRoZSByZWxhdGlvbiBpcyB0cmFuc2l0aXZlXG5cbiAgdmFsIHRyYW5zIDpcbiAgICAgKCdhMSwgJ2IxLCAnYzEsICdkMSwgJ2UxLCAnZjEsXG4gICAgICAnYTIsICdiMiwgJ2MyLCAnZDIsICdlMiwgJ2YyKSBmbXR0eV9yZWxcbiAgLT4gKCdhMiwgJ2IyLCAnYzIsICdkMiwgJ2UyLCAnZjIsXG4gICAgICAnYTMsICdiMywgJ2MzLCAnZDMsICdlMywgJ2YzKSBmbXR0eV9yZWxcbiAgLT4gKCdhMSwgJ2IxLCAnYzEsICdkMSwgJ2UxLCAnZjEsXG4gICAgICAnYTMsICdiMywgJ2MzLCAnZDMsICdlMywgJ2YzKSBmbXR0eV9yZWxcblxuZG9lcyBhc3N1bWUgdGhhdCB0aGUgdHdvIGlucHV0cyBoYXZlIGV4YWN0bHkgdGhlIHNhbWUgdGVybSBzdHJ1Y3R1cmVcbihhbmQgaXMgb25seSBldmVyeSB1c2VkIGZvciBhcmd1bWVudCB3aXRuZXNzZXMgb2YgdGhlXG5Gb3JtYXRfc3Vic3RfdHkgY29uc3RydWN0b3IpLlxuKilcblxuKCogVHlwZSBvZiBhIGJsb2NrIHVzZWQgYnkgdGhlIEZvcm1hdCBwcmV0dHktcHJpbnRlci4gKilcbnR5cGUgYmxvY2tfdHlwZSA9XG4gIHwgUHBfaGJveCAgICgqIEhvcml6b250YWwgYmxvY2sgbm8gbGluZSBicmVha2luZyAqKVxuICB8IFBwX3Zib3ggICAoKiBWZXJ0aWNhbCBibG9jayBlYWNoIGJyZWFrIGxlYWRzIHRvIGEgbmV3IGxpbmUgKilcbiAgfCBQcF9odmJveCAgKCogSG9yaXpvbnRhbC12ZXJ0aWNhbCBibG9jazogc2FtZSBhcyB2Ym94LCBleGNlcHQgaWYgdGhpcyBibG9ja1xuICAgICAgICAgICAgICAgICBpcyBzbWFsbCBlbm91Z2ggdG8gZml0IG9uIGEgc2luZ2xlIGxpbmUgKilcbiAgfCBQcF9ob3Zib3ggKCogSG9yaXpvbnRhbCBvciBWZXJ0aWNhbCBibG9jazogYnJlYWtzIGxlYWQgdG8gbmV3IGxpbmVcbiAgICAgICAgICAgICAgICAgb25seSB3aGVuIG5lY2Vzc2FyeSB0byBwcmludCB0aGUgY29udGVudCBvZiB0aGUgYmxvY2sgKilcbiAgfCBQcF9ib3ggICAgKCogSG9yaXpvbnRhbCBvciBJbmRlbnQgYmxvY2s6IGJyZWFrcyBsZWFkIHRvIG5ldyBsaW5lXG4gICAgICAgICAgICAgICAgIG9ubHkgd2hlbiBuZWNlc3NhcnkgdG8gcHJpbnQgdGhlIGNvbnRlbnQgb2YgdGhlIGJsb2NrLCBvclxuICAgICAgICAgICAgICAgICB3aGVuIGl0IGxlYWRzIHRvIGEgbmV3IGluZGVudGF0aW9uIG9mIHRoZSBjdXJyZW50IGxpbmUgKilcbiAgfCBQcF9maXRzICAgKCogSW50ZXJuYWwgdXNhZ2U6IHdoZW4gYSBibG9jayBmaXRzIG9uIGEgc2luZ2xlIGxpbmUgKilcblxuKCogRm9ybWF0dGluZyBlbGVtZW50IHVzZWQgYnkgdGhlIEZvcm1hdCBwcmV0dHktcHJpbnRlci4gKilcbnR5cGUgZm9ybWF0dGluZ19saXQgPVxuICB8IENsb3NlX2JveCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiBAXSAgICopXG4gIHwgQ2xvc2VfdGFnICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqIEB9ICAgKilcbiAgfCBCcmVhayBvZiBzdHJpbmcgKiBpbnQgKiBpbnQgICAgICAgICAgKCogQCwgfCBAICB8IEA7IHwgQDs8PiAqKVxuICB8IEZGbHVzaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiBAPyAgICopXG4gIHwgRm9yY2VfbmV3bGluZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqIEBcXG4gICopXG4gIHwgRmx1c2hfbmV3bGluZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqIEAuICAgKilcbiAgfCBNYWdpY19zaXplIG9mIHN0cmluZyAqIGludCAgICAgICAgICAgICAgICAgICAgICAgICAgKCogQDxuPiAqKVxuICB8IEVzY2FwZWRfYXQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiBAQCAgICopXG4gIHwgRXNjYXBlZF9wZXJjZW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqIEAlJSAgKilcbiAgfCBTY2FuX2luZGljIG9mIGNoYXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogQFggICAqKVxuXG4oKiBGb3JtYXR0aW5nIGVsZW1lbnQgdXNlZCBieSB0aGUgRm9ybWF0IHByZXR0eS1wcmludGVyLiAqKVxudHlwZSAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm9ybWF0dGluZ19nZW4gPVxuICB8IE9wZW5fdGFnIDogKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZvcm1hdDYgLT4gICAgICAoKiBAeyAgICopXG4gICAgKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZvcm1hdHRpbmdfZ2VuXG4gIHwgT3Blbl9ib3ggOiAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm9ybWF0NiAtPiAgICAgICgqIEBbICAgKilcbiAgICAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm9ybWF0dGluZ19nZW5cblxuKCoqKilcblxuKCogTGlzdCBvZiBmb3JtYXQgdHlwZSBlbGVtZW50cy4gKilcbigqIEluIHBhcnRpY3VsYXIgdXNlZCB0byByZXByZXNlbnQgJSguLi4lKSBhbmQgJXsuLi4lfSBjb250ZW50cy4gKilcbmFuZCAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm10dHkgPVxuICAgICAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZixcbiAgICAgICdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdHR5X3JlbFxuYW5kICgnYTEsICdiMSwgJ2MxLCAnZDEsICdlMSwgJ2YxLFxuICAgICAnYTIsICdiMiwgJ2MyLCAnZDIsICdlMiwgJ2YyKSBmbXR0eV9yZWwgPVxuICB8IENoYXJfdHkgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiAlYyAgKilcbiAgICAgICgnYTEsICdiMSwgJ2MxLCAnZDEsICdlMSwgJ2YxLFxuICAgICAgICdhMiwgJ2IyLCAnYzIsICdkMiwgJ2UyLCAnZjIpIGZtdHR5X3JlbCAtPlxuICAgICAgKGNoYXIgLT4gJ2ExLCAnYjEsICdjMSwgJ2QxLCAnZTEsICdmMSxcbiAgICAgICBjaGFyIC0+ICdhMiwgJ2IyLCAnYzIsICdkMiwgJ2UyLCAnZjIpIGZtdHR5X3JlbFxuICB8IFN0cmluZ190eSA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiAlcyAgKilcbiAgICAgICgnYTEsICdiMSwgJ2MxLCAnZDEsICdlMSwgJ2YxLFxuICAgICAgICdhMiwgJ2IyLCAnYzIsICdkMiwgJ2UyLCAnZjIpIGZtdHR5X3JlbCAtPlxuICAgICAgKHN0cmluZyAtPiAnYTEsICdiMSwgJ2MxLCAnZDEsICdlMSwgJ2YxLFxuICAgICAgIHN0cmluZyAtPiAnYTIsICdiMiwgJ2MyLCAnZDIsICdlMiwgJ2YyKSBmbXR0eV9yZWxcbiAgfCBJbnRfdHkgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogJWQgICopXG4gICAgICAoJ2ExLCAnYjEsICdjMSwgJ2QxLCAnZTEsICdmMSxcbiAgICAgICAnYTIsICdiMiwgJ2MyLCAnZDIsICdlMiwgJ2YyKSBmbXR0eV9yZWwgLT5cbiAgICAgIChpbnQgLT4gJ2ExLCAnYjEsICdjMSwgJ2QxLCAnZTEsICdmMSxcbiAgICAgICBpbnQgLT4gJ2EyLCAnYjIsICdjMiwgJ2QyLCAnZTIsICdmMikgZm10dHlfcmVsXG4gIHwgSW50MzJfdHkgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqICVsZCAqKVxuICAgICAgKCdhMSwgJ2IxLCAnYzEsICdkMSwgJ2UxLCAnZjEsXG4gICAgICAgJ2EyLCAnYjIsICdjMiwgJ2QyLCAnZTIsICdmMikgZm10dHlfcmVsIC0+XG4gICAgICAoaW50MzIgLT4gJ2ExLCAnYjEsICdjMSwgJ2QxLCAnZTEsICdmMSxcbiAgICAgICBpbnQzMiAtPiAnYTIsICdiMiwgJ2MyLCAnZDIsICdlMiwgJ2YyKSBmbXR0eV9yZWxcbiAgfCBOYXRpdmVpbnRfdHkgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogJW5kICopXG4gICAgICAoJ2ExLCAnYjEsICdjMSwgJ2QxLCAnZTEsICdmMSxcbiAgICAgICAnYTIsICdiMiwgJ2MyLCAnZDIsICdlMiwgJ2YyKSBmbXR0eV9yZWwgLT5cbiAgICAgIChuYXRpdmVpbnQgLT4gJ2ExLCAnYjEsICdjMSwgJ2QxLCAnZTEsICdmMSxcbiAgICAgICBuYXRpdmVpbnQgLT4gJ2EyLCAnYjIsICdjMiwgJ2QyLCAnZTIsICdmMikgZm10dHlfcmVsXG4gIHwgSW50NjRfdHkgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqICVMZCAqKVxuICAgICAgKCdhMSwgJ2IxLCAnYzEsICdkMSwgJ2UxLCAnZjEsXG4gICAgICAgJ2EyLCAnYjIsICdjMiwgJ2QyLCAnZTIsICdmMikgZm10dHlfcmVsIC0+XG4gICAgICAoaW50NjQgLT4gJ2ExLCAnYjEsICdjMSwgJ2QxLCAnZTEsICdmMSxcbiAgICAgICBpbnQ2NCAtPiAnYTIsICdiMiwgJ2MyLCAnZDIsICdlMiwgJ2YyKSBmbXR0eV9yZWxcbiAgfCBGbG9hdF90eSA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogJWYgICopXG4gICAgICAoJ2ExLCAnYjEsICdjMSwgJ2QxLCAnZTEsICdmMSxcbiAgICAgICAnYTIsICdiMiwgJ2MyLCAnZDIsICdlMiwgJ2YyKSBmbXR0eV9yZWwgLT5cbiAgICAgIChmbG9hdCAtPiAnYTEsICdiMSwgJ2MxLCAnZDEsICdlMSwgJ2YxLFxuICAgICAgIGZsb2F0IC0+ICdhMiwgJ2IyLCAnYzIsICdkMiwgJ2UyLCAnZjIpIGZtdHR5X3JlbFxuICB8IEJvb2xfdHkgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiAlQiAgKilcbiAgICAgICgnYTEsICdiMSwgJ2MxLCAnZDEsICdlMSwgJ2YxLFxuICAgICAgICdhMiwgJ2IyLCAnYzIsICdkMiwgJ2UyLCAnZjIpIGZtdHR5X3JlbCAtPlxuICAgICAgKGJvb2wgLT4gJ2ExLCAnYjEsICdjMSwgJ2QxLCAnZTEsICdmMSxcbiAgICAgICBib29sIC0+ICdhMiwgJ2IyLCAnYzIsICdkMiwgJ2UyLCAnZjIpIGZtdHR5X3JlbFxuXG4gIHwgRm9ybWF0X2FyZ190eSA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqICV7Li4uJX0gKilcbiAgICAgICgnZywgJ2gsICdpLCAnaiwgJ2ssICdsKSBmbXR0eSAqXG4gICAgICAoJ2ExLCAnYjEsICdjMSwgJ2QxLCAnZTEsICdmMSxcbiAgICAgICAnYTIsICdiMiwgJ2MyLCAnZDIsICdlMiwgJ2YyKSBmbXR0eV9yZWwgLT5cbiAgICAgICgoJ2csICdoLCAnaSwgJ2osICdrLCAnbCkgZm9ybWF0NiAtPiAnYTEsICdiMSwgJ2MxLCAnZDEsICdlMSwgJ2YxLFxuICAgICAgICgnZywgJ2gsICdpLCAnaiwgJ2ssICdsKSBmb3JtYXQ2IC0+ICdhMiwgJ2IyLCAnYzIsICdkMiwgJ2UyLCAnZjIpXG4gICAgICAgICAgIGZtdHR5X3JlbFxuICB8IEZvcm1hdF9zdWJzdF90eSA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiAlKC4uLiUpICopXG4gICAgICAoJ2csICdoLCAnaSwgJ2osICdrLCAnbCxcbiAgICAgICAnZzEsICdiMSwgJ2MxLCAnajEsICdkMSwgJ2ExKSBmbXR0eV9yZWwgKlxuICAgICAgKCdnLCAnaCwgJ2ksICdqLCAnaywgJ2wsXG4gICAgICAgJ2cyLCAnYjIsICdjMiwgJ2oyLCAnZDIsICdhMikgZm10dHlfcmVsICpcbiAgICAgICgnYTEsICdiMSwgJ2MxLCAnZDEsICdlMSwgJ2YxLFxuICAgICAgICdhMiwgJ2IyLCAnYzIsICdkMiwgJ2UyLCAnZjIpIGZtdHR5X3JlbCAtPlxuICAgICAgKCgnZywgJ2gsICdpLCAnaiwgJ2ssICdsKSBmb3JtYXQ2IC0+ICdnMSwgJ2IxLCAnYzEsICdqMSwgJ2UxLCAnZjEsXG4gICAgICAgKCdnLCAnaCwgJ2ksICdqLCAnaywgJ2wpIGZvcm1hdDYgLT4gJ2cyLCAnYjIsICdjMiwgJ2oyLCAnZTIsICdmMilcbiAgICAgICAgICAgZm10dHlfcmVsXG5cbiAgKCogUHJpbnRmIGFuZCBGb3JtYXQgc3BlY2lmaWMgY29uc3RydWN0b3JzLiAqKVxuICB8IEFscGhhX3R5IDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiAlYSAgKilcbiAgICAgICgnYTEsICdiMSwgJ2MxLCAnZDEsICdlMSwgJ2YxLFxuICAgICAgICdhMiwgJ2IyLCAnYzIsICdkMiwgJ2UyLCAnZjIpIGZtdHR5X3JlbCAtPlxuICAgICAgKCgnYjEgLT4gJ3ggLT4gJ2MxKSAtPiAneCAtPiAnYTEsICdiMSwgJ2MxLCAnZDEsICdlMSwgJ2YxLFxuICAgICAgICgnYjIgLT4gJ3ggLT4gJ2MyKSAtPiAneCAtPiAnYTIsICdiMiwgJ2MyLCAnZDIsICdlMiwgJ2YyKSBmbXR0eV9yZWxcbiAgfCBUaGV0YV90eSA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogJXQgICopXG4gICAgICAoJ2ExLCAnYjEsICdjMSwgJ2QxLCAnZTEsICdmMSxcbiAgICAgICAnYTIsICdiMiwgJ2MyLCAnZDIsICdlMiwgJ2YyKSBmbXR0eV9yZWwgLT5cbiAgICAgICgoJ2IxIC0+ICdjMSkgLT4gJ2ExLCAnYjEsICdjMSwgJ2QxLCAnZTEsICdmMSxcbiAgICAgICAoJ2IyIC0+ICdjMikgLT4gJ2EyLCAnYjIsICdjMiwgJ2QyLCAnZTIsICdmMikgZm10dHlfcmVsXG4gIHwgQW55X3R5IDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiBVc2VkIGZvciBjdXN0b20gZm9ybWF0cyAqKVxuICAgICAgKCdhMSwgJ2IxLCAnYzEsICdkMSwgJ2UxLCAnZjEsXG4gICAgICAgJ2EyLCAnYjIsICdjMiwgJ2QyLCAnZTIsICdmMikgZm10dHlfcmVsIC0+XG4gICAgICAoJ3ggLT4gJ2ExLCAnYjEsICdjMSwgJ2QxLCAnZTEsICdmMSxcbiAgICAgICAneCAtPiAnYTIsICdiMiwgJ2MyLCAnZDIsICdlMiwgJ2YyKSBmbXR0eV9yZWxcblxuICAoKiBTY2FuZiBzcGVjaWZpYyBjb25zdHJ1Y3Rvci4gKilcbiAgfCBSZWFkZXJfdHkgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogJXIgICopXG4gICAgICAoJ2ExLCAnYjEsICdjMSwgJ2QxLCAnZTEsICdmMSxcbiAgICAgICAnYTIsICdiMiwgJ2MyLCAnZDIsICdlMiwgJ2YyKSBmbXR0eV9yZWwgLT5cbiAgICAgICgneCAtPiAnYTEsICdiMSwgJ2MxLCAoJ2IxIC0+ICd4KSAtPiAnZDEsICdlMSwgJ2YxLFxuICAgICAgICd4IC0+ICdhMiwgJ2IyLCAnYzIsICgnYjIgLT4gJ3gpIC0+ICdkMiwgJ2UyLCAnZjIpIGZtdHR5X3JlbFxuICB8IElnbm9yZWRfcmVhZGVyX3R5IDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiAlX3IgICopXG4gICAgICAoJ2ExLCAnYjEsICdjMSwgJ2QxLCAnZTEsICdmMSxcbiAgICAgICAnYTIsICdiMiwgJ2MyLCAnZDIsICdlMiwgJ2YyKSBmbXR0eV9yZWwgLT5cbiAgICAgICgnYTEsICdiMSwgJ2MxLCAoJ2IxIC0+ICd4KSAtPiAnZDEsICdlMSwgJ2YxLFxuICAgICAgICdhMiwgJ2IyLCAnYzIsICgnYjIgLT4gJ3gpIC0+ICdkMiwgJ2UyLCAnZjIpIGZtdHR5X3JlbFxuXG4gIHwgRW5kX29mX2ZtdHR5IDpcbiAgICAgICgnZjEsICdiMSwgJ2MxLCAnZDEsICdkMSwgJ2YxLFxuICAgICAgICdmMiwgJ2IyLCAnYzIsICdkMiwgJ2QyLCAnZjIpIGZtdHR5X3JlbFxuXG4oKioqKVxuXG4oKiBMaXN0IG9mIGZvcm1hdCBlbGVtZW50cy4gKilcbmFuZCAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm10ID1cbiAgfCBDaGFyIDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiAlYyAqKVxuICAgICAgKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdCAtPlxuICAgICAgICAoY2hhciAtPiAnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmbXRcbiAgfCBDYW1sX2NoYXIgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiAlQyAqKVxuICAgICAgKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdCAtPlxuICAgICAgICAoY2hhciAtPiAnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmbXRcbiAgfCBTdHJpbmcgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiAlcyAqKVxuICAgICAgKCd4LCBzdHJpbmcgLT4gJ2EpIHBhZGRpbmcgKiAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm10IC0+XG4gICAgICAgICgneCwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmbXRcbiAgfCBDYW1sX3N0cmluZyA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiAlUyAqKVxuICAgICAgKCd4LCBzdHJpbmcgLT4gJ2EpIHBhZGRpbmcgKiAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm10IC0+XG4gICAgICAgICgneCwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmbXRcbiAgfCBJbnQgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiAlW2RpeFh1b10gKilcbiAgICAgIGludF9jb252ICogKCd4LCAneSkgcGFkZGluZyAqICgneSwgaW50IC0+ICdhKSBwcmVjaXNpb24gKlxuICAgICAgKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdCAtPlxuICAgICAgICAoJ3gsICdiLCAnYywgJ2QsICdlLCAnZikgZm10XG4gIHwgSW50MzIgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogJWxbZGl4WHVvXSAqKVxuICAgICAgaW50X2NvbnYgKiAoJ3gsICd5KSBwYWRkaW5nICogKCd5LCBpbnQzMiAtPiAnYSkgcHJlY2lzaW9uICpcbiAgICAgICgnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmbXQgLT5cbiAgICAgICAgKCd4LCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdFxuICB8IE5hdGl2ZWludCA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqICVuW2RpeFh1b10gKilcbiAgICAgIGludF9jb252ICogKCd4LCAneSkgcGFkZGluZyAqICgneSwgbmF0aXZlaW50IC0+ICdhKSBwcmVjaXNpb24gKlxuICAgICAgKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdCAtPlxuICAgICAgICAoJ3gsICdiLCAnYywgJ2QsICdlLCAnZikgZm10XG4gIHwgSW50NjQgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogJUxbZGl4WHVvXSAqKVxuICAgICAgaW50X2NvbnYgKiAoJ3gsICd5KSBwYWRkaW5nICogKCd5LCBpbnQ2NCAtPiAnYSkgcHJlY2lzaW9uICpcbiAgICAgICgnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmbXQgLT5cbiAgICAgICAgKCd4LCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdFxuICB8IEZsb2F0IDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqICVbZmVFZ0dGaEhdICopXG4gICAgICBmbG9hdF9jb252ICogKCd4LCAneSkgcGFkZGluZyAqICgneSwgZmxvYXQgLT4gJ2EpIHByZWNpc2lvbiAqXG4gICAgICAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm10IC0+XG4gICAgICAgICgneCwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmbXRcbiAgfCBCb29sIDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiAlW2JCXSAqKVxuICAgICAgKCd4LCBib29sIC0+ICdhKSBwYWRkaW5nICogKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdCAtPlxuICAgICAgICAoJ3gsICdiLCAnYywgJ2QsICdlLCAnZikgZm10XG4gIHwgRmx1c2ggOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogJSEgKilcbiAgICAgICgnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmbXQgLT5cbiAgICAgICAgKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdFxuXG4gIHwgU3RyaW5nX2xpdGVyYWwgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogYWJjICopXG4gICAgICBzdHJpbmcgKiAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm10IC0+XG4gICAgICAgICgnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmbXRcbiAgfCBDaGFyX2xpdGVyYWwgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiB4ICopXG4gICAgICBjaGFyICogKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdCAtPlxuICAgICAgICAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm10XG5cbiAgfCBGb3JtYXRfYXJnIDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiAley4uLiV9ICopXG4gICAgICBwYWRfb3B0aW9uICogKCdnLCAnaCwgJ2ksICdqLCAnaywgJ2wpIGZtdHR5ICpcbiAgICAgICgnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmbXQgLT5cbiAgICAgICAgKCgnZywgJ2gsICdpLCAnaiwgJ2ssICdsKSBmb3JtYXQ2IC0+ICdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdFxuICB8IEZvcm1hdF9zdWJzdCA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqICUoLi4uJSkgKilcbiAgICAgIHBhZF9vcHRpb24gKlxuICAgICAgKCdnLCAnaCwgJ2ksICdqLCAnaywgJ2wsXG4gICAgICAgJ2cyLCAnYiwgJ2MsICdqMiwgJ2QsICdhKSBmbXR0eV9yZWwgKlxuICAgICAgKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdCAtPlxuICAgICAgKCgnZywgJ2gsICdpLCAnaiwgJ2ssICdsKSBmb3JtYXQ2IC0+ICdnMiwgJ2IsICdjLCAnajIsICdlLCAnZikgZm10XG5cbiAgKCogUHJpbnRmIGFuZCBGb3JtYXQgc3BlY2lmaWMgY29uc3RydWN0b3IuICopXG4gIHwgQWxwaGEgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogJWEgKilcbiAgICAgICgnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmbXQgLT5cbiAgICAgICAgKCgnYiAtPiAneCAtPiAnYykgLT4gJ3ggLT4gJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm10XG4gIHwgVGhldGEgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogJXQgKilcbiAgICAgICgnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmbXQgLT5cbiAgICAgICAgKCgnYiAtPiAnYykgLT4gJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm10XG5cbiAgKCogRm9ybWF0IHNwZWNpZmljIGNvbnN0cnVjdG9yOiAqKVxuICB8IEZvcm1hdHRpbmdfbGl0IDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqIEBfICopXG4gICAgICBmb3JtYXR0aW5nX2xpdCAqICgnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmbXQgLT5cbiAgICAgICAgKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdFxuICB8IEZvcm1hdHRpbmdfZ2VuIDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiBAXyAqKVxuICAgICAgKCdhMSwgJ2IsICdjLCAnZDEsICdlMSwgJ2YxKSBmb3JtYXR0aW5nX2dlbiAqXG4gICAgICAoJ2YxLCAnYiwgJ2MsICdlMSwgJ2UyLCAnZjIpIGZtdCAtPiAoJ2ExLCAnYiwgJ2MsICdkMSwgJ2UyLCAnZjIpIGZtdFxuXG4gICgqIFNjYW5mIHNwZWNpZmljIGNvbnN0cnVjdG9yczogKilcbiAgfCBSZWFkZXIgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiAlciAqKVxuICAgICAgKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdCAtPlxuICAgICAgICAoJ3ggLT4gJ2EsICdiLCAnYywgKCdiIC0+ICd4KSAtPiAnZCwgJ2UsICdmKSBmbXRcbiAgfCBTY2FuX2NoYXJfc2V0IDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiAlWy4uLl0gKilcbiAgICAgIHBhZF9vcHRpb24gKiBjaGFyX3NldCAqICgnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmbXQgLT5cbiAgICAgICAgKHN0cmluZyAtPiAnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmbXRcbiAgfCBTY2FuX2dldF9jb3VudGVyIDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiAlW25sTkxdICopXG4gICAgICBjb3VudGVyICogKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdCAtPlxuICAgICAgICAoaW50IC0+ICdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdFxuICB8IFNjYW5fbmV4dF9jaGFyIDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqICUwYyAqKVxuICAgICAgKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdCAtPlxuICAgICAgKGNoYXIgLT4gJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm10XG4gIHwgSWdub3JlZF9wYXJhbSA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogJV8gKilcbiAgICAgICgnYSwgJ2IsICdjLCAnZCwgJ3ksICd4KSBpZ25vcmVkICogKCd4LCAnYiwgJ2MsICd5LCAnZSwgJ2YpIGZtdCAtPlxuICAgICAgICAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm10XG5cbiAgKCogQ3VzdG9tIHByaW50aW5nIGZvcm1hdCAoUFIjNjQ1MiwgR1BSIzE0MClcblxuICAgICBXZSBpbmNsdWRlIGEgdHlwZSBDdXN0b20gb2YgXCJjdXN0b20gY29udmVydGVyc1wiLCB3aGVyZSBhblxuICAgICBhcmJpdHJhcnkgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gY29udmVydCBvbmUgb3IgbW9yZVxuICAgICBhcmd1bWVudHMuIFRoZXJlIGlzIG5vIHN5bnRheCBmb3IgY3VzdG9tIGNvbnZlcnRlcnMsIGl0IGlzIG9ubHlcbiAgICAgaW50ZW5kZWQgZm9yIGN1c3RvbSBwcm9jZXNzb3JzIHRoYXQgd2lzaCB0byByZWx5IG9uIHRoZVxuICAgICBzdGRsaWItZGVmaW5lZCBmb3JtYXQgR0FEVHMuXG5cbiAgICAgRm9yIGluc3RhbmNlIGEgcHJlLXByb2Nlc3NvciBjb3VsZCBjaG9vc2UgdG8gaW50ZXJwcmV0IHN0cmluZ3NcbiAgICAgcHJlZml4ZWQgd2l0aCBbXCIhXCJdIGFzIGZvcm1hdCBzdHJpbmdzIHdoZXJlIFsle3sgLi4uIH19XSBpc1xuICAgICBhIHNwZWNpYWwgZm9ybSB0byBwYXNzIGEgdG9fc3RyaW5nIGZ1bmN0aW9uLCBzbyB0aGF0IG9uZSBjb3VsZFxuICAgICB3cml0ZTpcblxuICAgICB7W1xuICAgICAgIHR5cGUgdCA9IHsgeCA6IGludDsgeSA6IGludCB9XG5cbiAgICAgICBsZXQgc3RyaW5nX29mX3QgdCA9IFByaW50Zi5zcHJpbnRmIFwieyB4ID0gJWQ7IHkgPSAlZCB9XCIgdC54IHQueVxuXG4gICAgICAgUHJpbnRmLnByaW50ZiAhXCJ0ID0gJXt7c3RyaW5nX29mX3R9fVwiIHsgeCA9IDQyOyB5ID0gNDIgfVxuICAgICBdfVxuICAqKVxuICB8IEN1c3RvbSA6XG4gICAgICAoJ2EsICd4LCAneSkgY3VzdG9tX2FyaXR5ICogKHVuaXQgLT4gJ3gpICogKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdCAtPlxuICAgICAgKCd5LCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdFxuXG4gICgqIGVuZCBvZiBhIGZvcm1hdCBzcGVjaWZpY2F0aW9uICopXG4gIHwgRW5kX29mX2Zvcm1hdCA6XG4gICAgICAgICgnZiwgJ2IsICdjLCAnZSwgJ2UsICdmKSBmbXRcblxuKCoqKilcblxuKCogVHlwZSBmb3IgaWdub3JlZCBwYXJhbWV0ZXJzIChzZWUgXCIlX1wiKS4gKilcbmFuZCAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgaWdub3JlZCA9XG4gIHwgSWdub3JlZF9jaGFyIDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogJV9jICopXG4gICAgICAoJ2EsICdiLCAnYywgJ2QsICdkLCAnYSkgaWdub3JlZFxuICB8IElnbm9yZWRfY2FtbF9jaGFyIDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqICVfQyAqKVxuICAgICAgKCdhLCAnYiwgJ2MsICdkLCAnZCwgJ2EpIGlnbm9yZWRcbiAgfCBJZ25vcmVkX3N0cmluZyA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiAlX3MgKilcbiAgICAgIHBhZF9vcHRpb24gLT4gKCdhLCAnYiwgJ2MsICdkLCAnZCwgJ2EpIGlnbm9yZWRcbiAgfCBJZ25vcmVkX2NhbWxfc3RyaW5nIDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiAlX1MgKilcbiAgICAgIHBhZF9vcHRpb24gLT4gKCdhLCAnYiwgJ2MsICdkLCAnZCwgJ2EpIGlnbm9yZWRcbiAgfCBJZ25vcmVkX2ludCA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiAlX2QgKilcbiAgICAgIGludF9jb252ICogcGFkX29wdGlvbiAtPiAoJ2EsICdiLCAnYywgJ2QsICdkLCAnYSkgaWdub3JlZFxuICB8IElnbm9yZWRfaW50MzIgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqICVfbGQgKilcbiAgICAgIGludF9jb252ICogcGFkX29wdGlvbiAtPiAoJ2EsICdiLCAnYywgJ2QsICdkLCAnYSkgaWdub3JlZFxuICB8IElnbm9yZWRfbmF0aXZlaW50IDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqICVfbmQgKilcbiAgICAgIGludF9jb252ICogcGFkX29wdGlvbiAtPiAoJ2EsICdiLCAnYywgJ2QsICdkLCAnYSkgaWdub3JlZFxuICB8IElnbm9yZWRfaW50NjQgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqICVfTGQgKilcbiAgICAgIGludF9jb252ICogcGFkX29wdGlvbiAtPiAoJ2EsICdiLCAnYywgJ2QsICdkLCAnYSkgaWdub3JlZFxuICB8IElnbm9yZWRfZmxvYXQgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqICVfZiAqKVxuICAgICAgcGFkX29wdGlvbiAqIHByZWNfb3B0aW9uIC0+ICgnYSwgJ2IsICdjLCAnZCwgJ2QsICdhKSBpZ25vcmVkXG4gIHwgSWdub3JlZF9ib29sIDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogJV9CICopXG4gICAgICBwYWRfb3B0aW9uIC0+ICgnYSwgJ2IsICdjLCAnZCwgJ2QsICdhKSBpZ25vcmVkXG4gIHwgSWdub3JlZF9mb3JtYXRfYXJnIDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogJV97Li4uJX0gKilcbiAgICAgIHBhZF9vcHRpb24gKiAoJ2csICdoLCAnaSwgJ2osICdrLCAnbCkgZm10dHkgLT5cbiAgICAgICAgKCdhLCAnYiwgJ2MsICdkLCAnZCwgJ2EpIGlnbm9yZWRcbiAgfCBJZ25vcmVkX2Zvcm1hdF9zdWJzdCA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiAlXyguLi4lKSAqKVxuICAgICAgcGFkX29wdGlvbiAqICgnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmbXR0eSAtPlxuICAgICAgICAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgaWdub3JlZFxuICB8IElnbm9yZWRfcmVhZGVyIDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqICVfciAqKVxuICAgICAgKCdhLCAnYiwgJ2MsICgnYiAtPiAneCkgLT4gJ2QsICdkLCAnYSkgaWdub3JlZFxuICB8IElnbm9yZWRfc2Nhbl9jaGFyX3NldCA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqICVfWy4uLl0gKilcbiAgICAgIHBhZF9vcHRpb24gKiBjaGFyX3NldCAtPiAoJ2EsICdiLCAnYywgJ2QsICdkLCAnYSkgaWdub3JlZFxuICB8IElnbm9yZWRfc2Nhbl9nZXRfY291bnRlciA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqICVfW25sTkxdICopXG4gICAgICBjb3VudGVyIC0+ICgnYSwgJ2IsICdjLCAnZCwgJ2QsICdhKSBpZ25vcmVkXG4gIHwgSWdub3JlZF9zY2FuX25leHRfY2hhciA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogJV8wYyAqKVxuICAgICAgKCdhLCAnYiwgJ2MsICdkLCAnZCwgJ2EpIGlnbm9yZWRcblxuYW5kICgnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmb3JtYXQ2ID1cbiAgRm9ybWF0IG9mICgnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmbXQgKiBzdHJpbmdcblxubGV0IHJlYyBlcmFzZV9yZWwgOiB0eXBlIGEgYiBjIGQgZSBmIGcgaCBpIGogayBsIC5cbiAgKGEsIGIsIGMsIGQsIGUsIGYsXG4gICBnLCBoLCBpLCBqLCBrLCBsKSBmbXR0eV9yZWwgLT4gKGEsIGIsIGMsIGQsIGUsIGYpIGZtdHR5XG49IGZ1bmN0aW9uXG4gIHwgQ2hhcl90eSByZXN0IC0+XG4gICAgQ2hhcl90eSAoZXJhc2VfcmVsIHJlc3QpXG4gIHwgU3RyaW5nX3R5IHJlc3QgLT5cbiAgICBTdHJpbmdfdHkgKGVyYXNlX3JlbCByZXN0KVxuICB8IEludF90eSByZXN0IC0+XG4gICAgSW50X3R5IChlcmFzZV9yZWwgcmVzdClcbiAgfCBJbnQzMl90eSByZXN0IC0+XG4gICAgSW50MzJfdHkgKGVyYXNlX3JlbCByZXN0KVxuICB8IEludDY0X3R5IHJlc3QgLT5cbiAgICBJbnQ2NF90eSAoZXJhc2VfcmVsIHJlc3QpXG4gIHwgTmF0aXZlaW50X3R5IHJlc3QgLT5cbiAgICBOYXRpdmVpbnRfdHkgKGVyYXNlX3JlbCByZXN0KVxuICB8IEZsb2F0X3R5IHJlc3QgLT5cbiAgICBGbG9hdF90eSAoZXJhc2VfcmVsIHJlc3QpXG4gIHwgQm9vbF90eSByZXN0IC0+XG4gICAgQm9vbF90eSAoZXJhc2VfcmVsIHJlc3QpXG4gIHwgRm9ybWF0X2FyZ190eSAodHksIHJlc3QpIC0+XG4gICAgRm9ybWF0X2FyZ190eSAodHksIGVyYXNlX3JlbCByZXN0KVxuICB8IEZvcm1hdF9zdWJzdF90eSAodHkxLCBfdHkyLCByZXN0KSAtPlxuICAgIEZvcm1hdF9zdWJzdF90eSAodHkxLCB0eTEsIGVyYXNlX3JlbCByZXN0KVxuICB8IEFscGhhX3R5IHJlc3QgLT5cbiAgICBBbHBoYV90eSAoZXJhc2VfcmVsIHJlc3QpXG4gIHwgVGhldGFfdHkgcmVzdCAtPlxuICAgIFRoZXRhX3R5IChlcmFzZV9yZWwgcmVzdClcbiAgfCBBbnlfdHkgcmVzdCAtPlxuICAgIEFueV90eSAoZXJhc2VfcmVsIHJlc3QpXG4gIHwgUmVhZGVyX3R5IHJlc3QgLT5cbiAgICBSZWFkZXJfdHkgKGVyYXNlX3JlbCByZXN0KVxuICB8IElnbm9yZWRfcmVhZGVyX3R5IHJlc3QgLT5cbiAgICBJZ25vcmVkX3JlYWRlcl90eSAoZXJhc2VfcmVsIHJlc3QpXG4gIHwgRW5kX29mX2ZtdHR5IC0+IEVuZF9vZl9mbXR0eVxuXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuICAgICAgICAgICAgICAgICAgICAgICAgICgqIEZvcm1hdCB0eXBlIGNvbmNhdGVuYXRpb24gKilcblxuKCogQ29uY2F0ZW5hdGUgdHdvIGZvcm1hdCB0eXBlcy4gKilcbigqIFVzZWQgYnk6XG4gICAqIHJlYWRlcl9uYl91bmlmaWVyX29mX2ZtdHR5IHRvIGNvdW50IHJlYWRlcnMgaW4gYW4gZm10dHksXG4gICAqIFNjYW5mLnRha2VfZm10dHlfZm9ybWF0X3JlYWRlcnMgdG8gZXh0cmFjdCByZWFkZXJzIGluc2lkZSAlKC4uLiUpLFxuICAgKiBDYW1saW50ZXJuYWxGb3JtYXQuZm10dHlfb2ZfaWdub3JlZF9mb3JtYXQgdG8gZXh0cmFjdCBmb3JtYXQgdHlwZS4gKilcblxuKCpcbmxldCByZWMgY29uY2F0X2ZtdHR5IDogdHlwZSBhIGIgYyBkIGUgZiBnIGggLlxuICAgIChhLCBiLCBjLCBkLCBlLCBmKSBmbXR0eSAtPlxuICAgIChmLCBiLCBjLCBlLCBnLCBoKSBmbXR0eSAtPlxuICAgIChhLCBiLCBjLCBkLCBnLCBoKSBmbXR0eSA9XG4qKVxubGV0IHJlYyBjb25jYXRfZm10dHkgOlxuICB0eXBlIGExIGIxIGMxIGQxIGUxIGYxXG4gICAgICAgYTIgYjIgYzIgZDIgZTIgZjJcbiAgICAgICBnMSBqMSBnMiBqMlxuICAuXG4gICAgKGcxLCBiMSwgYzEsIGoxLCBkMSwgYTEsXG4gICAgIGcyLCBiMiwgYzIsIGoyLCBkMiwgYTIpIGZtdHR5X3JlbCAtPlxuICAgIChhMSwgYjEsIGMxLCBkMSwgZTEsIGYxLFxuICAgICBhMiwgYjIsIGMyLCBkMiwgZTIsIGYyKSBmbXR0eV9yZWwgLT5cbiAgICAoZzEsIGIxLCBjMSwgajEsIGUxLCBmMSxcbiAgICAgZzIsIGIyLCBjMiwgajIsIGUyLCBmMikgZm10dHlfcmVsID1cbmZ1biBmbXR0eTEgZm10dHkyIC0+IG1hdGNoIGZtdHR5MSB3aXRoXG4gIHwgQ2hhcl90eSByZXN0IC0+XG4gICAgQ2hhcl90eSAoY29uY2F0X2ZtdHR5IHJlc3QgZm10dHkyKVxuICB8IFN0cmluZ190eSByZXN0IC0+XG4gICAgU3RyaW5nX3R5IChjb25jYXRfZm10dHkgcmVzdCBmbXR0eTIpXG4gIHwgSW50X3R5IHJlc3QgLT5cbiAgICBJbnRfdHkgKGNvbmNhdF9mbXR0eSByZXN0IGZtdHR5MilcbiAgfCBJbnQzMl90eSByZXN0IC0+XG4gICAgSW50MzJfdHkgKGNvbmNhdF9mbXR0eSByZXN0IGZtdHR5MilcbiAgfCBOYXRpdmVpbnRfdHkgcmVzdCAtPlxuICAgIE5hdGl2ZWludF90eSAoY29uY2F0X2ZtdHR5IHJlc3QgZm10dHkyKVxuICB8IEludDY0X3R5IHJlc3QgLT5cbiAgICBJbnQ2NF90eSAoY29uY2F0X2ZtdHR5IHJlc3QgZm10dHkyKVxuICB8IEZsb2F0X3R5IHJlc3QgLT5cbiAgICBGbG9hdF90eSAoY29uY2F0X2ZtdHR5IHJlc3QgZm10dHkyKVxuICB8IEJvb2xfdHkgcmVzdCAtPlxuICAgIEJvb2xfdHkgKGNvbmNhdF9mbXR0eSByZXN0IGZtdHR5MilcbiAgfCBBbHBoYV90eSByZXN0IC0+XG4gICAgQWxwaGFfdHkgKGNvbmNhdF9mbXR0eSByZXN0IGZtdHR5MilcbiAgfCBUaGV0YV90eSByZXN0IC0+XG4gICAgVGhldGFfdHkgKGNvbmNhdF9mbXR0eSByZXN0IGZtdHR5MilcbiAgfCBBbnlfdHkgcmVzdCAtPlxuICAgIEFueV90eSAoY29uY2F0X2ZtdHR5IHJlc3QgZm10dHkyKVxuICB8IFJlYWRlcl90eSByZXN0IC0+XG4gICAgUmVhZGVyX3R5IChjb25jYXRfZm10dHkgcmVzdCBmbXR0eTIpXG4gIHwgSWdub3JlZF9yZWFkZXJfdHkgcmVzdCAtPlxuICAgIElnbm9yZWRfcmVhZGVyX3R5IChjb25jYXRfZm10dHkgcmVzdCBmbXR0eTIpXG4gIHwgRm9ybWF0X2FyZ190eSAodHksIHJlc3QpIC0+XG4gICAgRm9ybWF0X2FyZ190eSAodHksIGNvbmNhdF9mbXR0eSByZXN0IGZtdHR5MilcbiAgfCBGb3JtYXRfc3Vic3RfdHkgKHR5MSwgdHkyLCByZXN0KSAtPlxuICAgIEZvcm1hdF9zdWJzdF90eSAodHkxLCB0eTIsIGNvbmNhdF9mbXR0eSByZXN0IGZtdHR5MilcbiAgfCBFbmRfb2ZfZm10dHkgLT4gZm10dHkyXG5cbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAoKiBGb3JtYXQgY29uY2F0ZW5hdGlvbiAqKVxuXG4oKiBDb25jYXRlbmF0ZSB0d28gZm9ybWF0cy4gKilcbmxldCByZWMgY29uY2F0X2ZtdCA6IHR5cGUgYSBiIGMgZCBlIGYgZyBoIC5cbiAgICAoYSwgYiwgYywgZCwgZSwgZikgZm10IC0+XG4gICAgKGYsIGIsIGMsIGUsIGcsIGgpIGZtdCAtPlxuICAgIChhLCBiLCBjLCBkLCBnLCBoKSBmbXQgPVxuZnVuIGZtdDEgZm10MiAtPiBtYXRjaCBmbXQxIHdpdGhcbiAgfCBTdHJpbmcgKHBhZCwgcmVzdCkgLT5cbiAgICBTdHJpbmcgKHBhZCwgY29uY2F0X2ZtdCByZXN0IGZtdDIpXG4gIHwgQ2FtbF9zdHJpbmcgKHBhZCwgcmVzdCkgLT5cbiAgICBDYW1sX3N0cmluZyAocGFkLCBjb25jYXRfZm10IHJlc3QgZm10MilcblxuICB8IEludCAoaWNvbnYsIHBhZCwgcHJlYywgcmVzdCkgLT5cbiAgICBJbnQgKGljb252LCBwYWQsIHByZWMsIGNvbmNhdF9mbXQgcmVzdCBmbXQyKVxuICB8IEludDMyIChpY29udiwgcGFkLCBwcmVjLCByZXN0KSAtPlxuICAgIEludDMyIChpY29udiwgcGFkLCBwcmVjLCBjb25jYXRfZm10IHJlc3QgZm10MilcbiAgfCBOYXRpdmVpbnQgKGljb252LCBwYWQsIHByZWMsIHJlc3QpIC0+XG4gICAgTmF0aXZlaW50IChpY29udiwgcGFkLCBwcmVjLCBjb25jYXRfZm10IHJlc3QgZm10MilcbiAgfCBJbnQ2NCAoaWNvbnYsIHBhZCwgcHJlYywgcmVzdCkgLT5cbiAgICBJbnQ2NCAoaWNvbnYsIHBhZCwgcHJlYywgY29uY2F0X2ZtdCByZXN0IGZtdDIpXG4gIHwgRmxvYXQgKGZjb252LCBwYWQsIHByZWMsIHJlc3QpIC0+XG4gICAgRmxvYXQgKGZjb252LCBwYWQsIHByZWMsIGNvbmNhdF9mbXQgcmVzdCBmbXQyKVxuXG4gIHwgQ2hhciAocmVzdCkgLT5cbiAgICBDaGFyIChjb25jYXRfZm10IHJlc3QgZm10MilcbiAgfCBDYW1sX2NoYXIgcmVzdCAtPlxuICAgIENhbWxfY2hhciAoY29uY2F0X2ZtdCByZXN0IGZtdDIpXG4gIHwgQm9vbCAocGFkLCByZXN0KSAtPlxuICAgIEJvb2wgKHBhZCwgY29uY2F0X2ZtdCByZXN0IGZtdDIpXG4gIHwgQWxwaGEgcmVzdCAtPlxuICAgIEFscGhhIChjb25jYXRfZm10IHJlc3QgZm10MilcbiAgfCBUaGV0YSByZXN0IC0+XG4gICAgVGhldGEgKGNvbmNhdF9mbXQgcmVzdCBmbXQyKVxuICB8IEN1c3RvbSAoYXJpdHksIGYsIHJlc3QpIC0+XG4gICAgQ3VzdG9tIChhcml0eSwgZiwgY29uY2F0X2ZtdCByZXN0IGZtdDIpXG4gIHwgUmVhZGVyIHJlc3QgLT5cbiAgICBSZWFkZXIgKGNvbmNhdF9mbXQgcmVzdCBmbXQyKVxuICB8IEZsdXNoIHJlc3QgLT5cbiAgICBGbHVzaCAoY29uY2F0X2ZtdCByZXN0IGZtdDIpXG5cbiAgfCBTdHJpbmdfbGl0ZXJhbCAoc3RyLCByZXN0KSAtPlxuICAgIFN0cmluZ19saXRlcmFsIChzdHIsIGNvbmNhdF9mbXQgcmVzdCBmbXQyKVxuICB8IENoYXJfbGl0ZXJhbCAoY2hyLCByZXN0KSAtPlxuICAgIENoYXJfbGl0ZXJhbCAgIChjaHIsIGNvbmNhdF9mbXQgcmVzdCBmbXQyKVxuXG4gIHwgRm9ybWF0X2FyZyAocGFkLCBmbXR0eSwgcmVzdCkgLT5cbiAgICBGb3JtYXRfYXJnICAgKHBhZCwgZm10dHksIGNvbmNhdF9mbXQgcmVzdCBmbXQyKVxuICB8IEZvcm1hdF9zdWJzdCAocGFkLCBmbXR0eSwgcmVzdCkgLT5cbiAgICBGb3JtYXRfc3Vic3QgKHBhZCwgZm10dHksIGNvbmNhdF9mbXQgcmVzdCBmbXQyKVxuXG4gIHwgU2Nhbl9jaGFyX3NldCAod2lkdGhfb3B0LCBjaGFyX3NldCwgcmVzdCkgLT5cbiAgICBTY2FuX2NoYXJfc2V0ICh3aWR0aF9vcHQsIGNoYXJfc2V0LCBjb25jYXRfZm10IHJlc3QgZm10MilcbiAgfCBTY2FuX2dldF9jb3VudGVyIChjb3VudGVyLCByZXN0KSAtPlxuICAgIFNjYW5fZ2V0X2NvdW50ZXIgKGNvdW50ZXIsIGNvbmNhdF9mbXQgcmVzdCBmbXQyKVxuICB8IFNjYW5fbmV4dF9jaGFyIChyZXN0KSAtPlxuICAgIFNjYW5fbmV4dF9jaGFyIChjb25jYXRfZm10IHJlc3QgZm10MilcbiAgfCBJZ25vcmVkX3BhcmFtIChpZ24sIHJlc3QpIC0+XG4gICAgSWdub3JlZF9wYXJhbSAoaWduLCBjb25jYXRfZm10IHJlc3QgZm10MilcblxuICB8IEZvcm1hdHRpbmdfbGl0IChmbXRpbmdfbGl0LCByZXN0KSAtPlxuICAgIEZvcm1hdHRpbmdfbGl0IChmbXRpbmdfbGl0LCBjb25jYXRfZm10IHJlc3QgZm10MilcbiAgfCBGb3JtYXR0aW5nX2dlbiAoZm10aW5nX2dlbiwgcmVzdCkgLT5cbiAgICBGb3JtYXR0aW5nX2dlbiAoZm10aW5nX2dlbiwgY29uY2F0X2ZtdCByZXN0IGZtdDIpXG5cbiAgfCBFbmRfb2ZfZm9ybWF0IC0+XG4gICAgZm10MlxuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgR2FicmllbCBTY2hlcmVyLCBwcm9qZXQgUGFydG91dCwgSU5SSUEgUGFyaXMtU2FjbGF5ICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMjAyMCBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0ICAgICAqKVxuKCogICAgIGVuIEF1dG9tYXRpcXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG4oKiBDYW1saW50ZXJuYWxBdG9taWMgaXMgYSBkZXBlbmRlbmN5IG9mIFN0ZGxpYiwgc28gaXQgaXMgY29tcGlsZWQgd2l0aFxuICAgLW5vcGVydmFzaXZlcy4gKilcbmV4dGVybmFsICggPT0gKSA6ICdhIC0+ICdhIC0+IGJvb2wgPSBcIiVlcVwiXG5leHRlcm5hbCAoICsgKSA6IGludCAtPiBpbnQgLT4gaW50ID0gXCIlYWRkaW50XCJcbmV4dGVybmFsIGlnbm9yZSA6ICdhIC0+IHVuaXQgPSBcIiVpZ25vcmVcIlxuXG4oKiBXZSBhcmUgbm90IHJldXNpbmcgKCdhIHJlZikgZGlyZWN0bHkgdG8gbWFrZSBpdCBlYXNpZXIgdG8gcmVhc29uXG4gICBhYm91dCBhdG9taWNpdHkgaWYgd2Ugd2lzaCB0bzogZXZlbiBpbiBhIHNlcXVlbnRpYWwgaW1wbGVtZW50YXRpb24sXG4gICBzaWduYWxzIGFuZCBvdGhlciBhc3luY2hyb25vdXMgY2FsbGJhY2tzIG1pZ2h0IGJyZWFrIGF0b21pY2l0eS4gKilcbnR5cGUgJ2EgdCA9IHttdXRhYmxlIHY6ICdhfVxuXG5sZXQgbWFrZSB2ID0ge3Z9XG5sZXQgZ2V0IHIgPSByLnZcbmxldCBzZXQgciB2ID0gci52IDwtIHZcblxuKCogVGhlIGZvbGxvd2luZyBmdW5jdGlvbnMgYXJlIHNldCB0byBuZXZlciBiZSBpbmxpbmVkOiBGbGFtYmRhIGlzXG4gICBhbGxvd2VkIHRvIG1vdmUgc3Vycm91bmRpbmcgY29kZSBpbnNpZGUgdGhlIGNyaXRpY2FsIHNlY3Rpb24sXG4gICBpbmNsdWRpbmcgYWxsb2NhdGlvbnMuICopXG5cbmxldFtAaW5saW5lIG5ldmVyXSBleGNoYW5nZSByIHYgPVxuICAoKiBCRUdJTiBBVE9NSUMgKilcbiAgbGV0IGN1ciA9IHIudiBpblxuICByLnYgPC0gdjtcbiAgKCogRU5EIEFUT01JQyAqKVxuICBjdXJcblxubGV0W0BpbmxpbmUgbmV2ZXJdIGNvbXBhcmVfYW5kX3NldCByIHNlZW4gdiA9XG4gICgqIEJFR0lOIEFUT01JQyAqKVxuICBsZXQgY3VyID0gci52IGluXG4gIGlmIGN1ciA9PSBzZWVuIHRoZW4gKFxuICAgIHIudiA8LSB2O1xuICAgICgqIEVORCBBVE9NSUMgKilcbiAgICB0cnVlXG4gICkgZWxzZVxuICAgIGZhbHNlXG5cbmxldFtAaW5saW5lIG5ldmVyXSBmZXRjaF9hbmRfYWRkIHIgbiA9XG4gICgqIEJFR0lOIEFUT01JQyAqKVxuICBsZXQgY3VyID0gci52IGluXG4gIHIudiA8LSAoY3VyICsgbik7XG4gICgqIEVORCBBVE9NSUMgKilcbiAgY3VyXG5cbmxldCBpbmNyIHIgPSBpZ25vcmUgKGZldGNoX2FuZF9hZGQgciAxKVxubGV0IGRlY3IgciA9IGlnbm9yZSAoZmV0Y2hfYW5kX2FkZCByICgtMSkpXG4iLCIoKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9DYW1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICBYYXZpZXIgTGVyb3ksIHByb2pldCBDcmlzdGFsLCBJTlJJQSBSb2NxdWVuY291cnQgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIENvcHlyaWdodCAxOTk2IEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgICAgICopXG4oKiAgICAgZW4gQXV0b21hdGlxdWUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIEFsbCByaWdodHMgcmVzZXJ2ZWQuICBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mICAgICopXG4oKiAgIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyLjEsIHdpdGggdGhlICAgICAgICAgICopXG4oKiAgIHNwZWNpYWwgZXhjZXB0aW9uIG9uIGxpbmtpbmcgZGVzY3JpYmVkIGluIHRoZSBmaWxlIExJQ0VOU0UuICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG5cbigqIEV4Y2VwdGlvbnMgKilcblxuZXh0ZXJuYWwgcmVnaXN0ZXJfbmFtZWRfdmFsdWUgOiBzdHJpbmcgLT4gJ2EgLT4gdW5pdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBcImNhbWxfcmVnaXN0ZXJfbmFtZWRfdmFsdWVcIlxuXG5sZXQgKCkgPVxuICAoKiBmb3IgcnVudGltZS9mYWlsX25hdC5jICopXG4gIHJlZ2lzdGVyX25hbWVkX3ZhbHVlIFwiUGVydmFzaXZlcy5hcnJheV9ib3VuZF9lcnJvclwiXG4gICAgKEludmFsaWRfYXJndW1lbnQgXCJpbmRleCBvdXQgb2YgYm91bmRzXCIpXG5cbmV4dGVybmFsIHJhaXNlIDogZXhuIC0+ICdhID0gXCIlcmFpc2VcIlxuZXh0ZXJuYWwgcmFpc2Vfbm90cmFjZSA6IGV4biAtPiAnYSA9IFwiJXJhaXNlX25vdHJhY2VcIlxuXG5sZXQgZmFpbHdpdGggcyA9IHJhaXNlKEZhaWx1cmUgcylcbmxldCBpbnZhbGlkX2FyZyBzID0gcmFpc2UoSW52YWxpZF9hcmd1bWVudCBzKVxuXG5leGNlcHRpb24gRXhpdFxuZXhjZXB0aW9uIE1hdGNoX2ZhaWx1cmUgPSBNYXRjaF9mYWlsdXJlXG5leGNlcHRpb24gQXNzZXJ0X2ZhaWx1cmUgPSBBc3NlcnRfZmFpbHVyZVxuZXhjZXB0aW9uIEludmFsaWRfYXJndW1lbnQgPSBJbnZhbGlkX2FyZ3VtZW50XG5leGNlcHRpb24gRmFpbHVyZSA9IEZhaWx1cmVcbmV4Y2VwdGlvbiBOb3RfZm91bmQgPSBOb3RfZm91bmRcbmV4Y2VwdGlvbiBPdXRfb2ZfbWVtb3J5ID0gT3V0X29mX21lbW9yeVxuZXhjZXB0aW9uIFN0YWNrX292ZXJmbG93ID0gU3RhY2tfb3ZlcmZsb3dcbmV4Y2VwdGlvbiBTeXNfZXJyb3IgPSBTeXNfZXJyb3JcbmV4Y2VwdGlvbiBFbmRfb2ZfZmlsZSA9IEVuZF9vZl9maWxlXG5leGNlcHRpb24gRGl2aXNpb25fYnlfemVybyA9IERpdmlzaW9uX2J5X3plcm9cbmV4Y2VwdGlvbiBTeXNfYmxvY2tlZF9pbyA9IFN5c19ibG9ja2VkX2lvXG5leGNlcHRpb24gVW5kZWZpbmVkX3JlY3Vyc2l2ZV9tb2R1bGUgPSBVbmRlZmluZWRfcmVjdXJzaXZlX21vZHVsZVxuXG4oKiBDb21wb3NpdGlvbiBvcGVyYXRvcnMgKilcblxuZXh0ZXJuYWwgKCB8PiApIDogJ2EgLT4gKCdhIC0+ICdiKSAtPiAnYiA9IFwiJXJldmFwcGx5XCJcbmV4dGVybmFsICggQEAgKSA6ICgnYSAtPiAnYikgLT4gJ2EgLT4gJ2IgPSBcIiVhcHBseVwiXG5cbigqIERlYnVnZ2luZyAqKVxuXG5leHRlcm5hbCBfX0xPQ19fIDogc3RyaW5nID0gXCIlbG9jX0xPQ1wiXG5leHRlcm5hbCBfX0ZJTEVfXyA6IHN0cmluZyA9IFwiJWxvY19GSUxFXCJcbmV4dGVybmFsIF9fTElORV9fIDogaW50ID0gXCIlbG9jX0xJTkVcIlxuZXh0ZXJuYWwgX19NT0RVTEVfXyA6IHN0cmluZyA9IFwiJWxvY19NT0RVTEVcIlxuZXh0ZXJuYWwgX19QT1NfXyA6IHN0cmluZyAqIGludCAqIGludCAqIGludCA9IFwiJWxvY19QT1NcIlxuZXh0ZXJuYWwgX19GVU5DVElPTl9fIDogc3RyaW5nID0gXCIlbG9jX0ZVTkNUSU9OXCJcblxuZXh0ZXJuYWwgX19MT0NfT0ZfXyA6ICdhIC0+IHN0cmluZyAqICdhID0gXCIlbG9jX0xPQ1wiXG5leHRlcm5hbCBfX0xJTkVfT0ZfXyA6ICdhIC0+IGludCAqICdhID0gXCIlbG9jX0xJTkVcIlxuZXh0ZXJuYWwgX19QT1NfT0ZfXyA6ICdhIC0+IChzdHJpbmcgKiBpbnQgKiBpbnQgKiBpbnQpICogJ2EgPSBcIiVsb2NfUE9TXCJcblxuKCogQ29tcGFyaXNvbnMgKilcblxuZXh0ZXJuYWwgKCA9ICkgOiAnYSAtPiAnYSAtPiBib29sID0gXCIlZXF1YWxcIlxuZXh0ZXJuYWwgKCA8PiApIDogJ2EgLT4gJ2EgLT4gYm9vbCA9IFwiJW5vdGVxdWFsXCJcbmV4dGVybmFsICggPCApIDogJ2EgLT4gJ2EgLT4gYm9vbCA9IFwiJWxlc3N0aGFuXCJcbmV4dGVybmFsICggPiApIDogJ2EgLT4gJ2EgLT4gYm9vbCA9IFwiJWdyZWF0ZXJ0aGFuXCJcbmV4dGVybmFsICggPD0gKSA6ICdhIC0+ICdhIC0+IGJvb2wgPSBcIiVsZXNzZXF1YWxcIlxuZXh0ZXJuYWwgKCA+PSApIDogJ2EgLT4gJ2EgLT4gYm9vbCA9IFwiJWdyZWF0ZXJlcXVhbFwiXG5leHRlcm5hbCBjb21wYXJlIDogJ2EgLT4gJ2EgLT4gaW50ID0gXCIlY29tcGFyZVwiXG5cbmxldCBtaW4geCB5ID0gaWYgeCA8PSB5IHRoZW4geCBlbHNlIHlcbmxldCBtYXggeCB5ID0gaWYgeCA+PSB5IHRoZW4geCBlbHNlIHlcblxuZXh0ZXJuYWwgKCA9PSApIDogJ2EgLT4gJ2EgLT4gYm9vbCA9IFwiJWVxXCJcbmV4dGVybmFsICggIT0gKSA6ICdhIC0+ICdhIC0+IGJvb2wgPSBcIiVub3RlcVwiXG5cbigqIEJvb2xlYW4gb3BlcmF0aW9ucyAqKVxuXG5leHRlcm5hbCBub3QgOiBib29sIC0+IGJvb2wgPSBcIiVib29sbm90XCJcbmV4dGVybmFsICggJiApIDogYm9vbCAtPiBib29sIC0+IGJvb2wgPSBcIiVzZXF1YW5kXCJcbmV4dGVybmFsICggJiYgKSA6IGJvb2wgLT4gYm9vbCAtPiBib29sID0gXCIlc2VxdWFuZFwiXG5leHRlcm5hbCAoIG9yICkgOiBib29sIC0+IGJvb2wgLT4gYm9vbCA9IFwiJXNlcXVvclwiXG5leHRlcm5hbCAoIHx8ICkgOiBib29sIC0+IGJvb2wgLT4gYm9vbCA9IFwiJXNlcXVvclwiXG5cbigqIEludGVnZXIgb3BlcmF0aW9ucyAqKVxuXG5leHRlcm5hbCAoIH4tICkgOiBpbnQgLT4gaW50ID0gXCIlbmVnaW50XCJcbmV4dGVybmFsICggfisgKSA6IGludCAtPiBpbnQgPSBcIiVpZGVudGl0eVwiXG5leHRlcm5hbCBzdWNjIDogaW50IC0+IGludCA9IFwiJXN1Y2NpbnRcIlxuZXh0ZXJuYWwgcHJlZCA6IGludCAtPiBpbnQgPSBcIiVwcmVkaW50XCJcbmV4dGVybmFsICggKyApIDogaW50IC0+IGludCAtPiBpbnQgPSBcIiVhZGRpbnRcIlxuZXh0ZXJuYWwgKCAtICkgOiBpbnQgLT4gaW50IC0+IGludCA9IFwiJXN1YmludFwiXG5leHRlcm5hbCAoICogKSA6IGludCAtPiBpbnQgLT4gaW50ID0gXCIlbXVsaW50XCJcbmV4dGVybmFsICggLyApIDogaW50IC0+IGludCAtPiBpbnQgPSBcIiVkaXZpbnRcIlxuZXh0ZXJuYWwgKCBtb2QgKSA6IGludCAtPiBpbnQgLT4gaW50ID0gXCIlbW9kaW50XCJcblxubGV0IGFicyB4ID0gaWYgeCA+PSAwIHRoZW4geCBlbHNlIC14XG5cbmV4dGVybmFsICggbGFuZCApIDogaW50IC0+IGludCAtPiBpbnQgPSBcIiVhbmRpbnRcIlxuZXh0ZXJuYWwgKCBsb3IgKSA6IGludCAtPiBpbnQgLT4gaW50ID0gXCIlb3JpbnRcIlxuZXh0ZXJuYWwgKCBseG9yICkgOiBpbnQgLT4gaW50IC0+IGludCA9IFwiJXhvcmludFwiXG5cbmxldCBsbm90IHggPSB4IGx4b3IgKC0xKVxuXG5leHRlcm5hbCAoIGxzbCApIDogaW50IC0+IGludCAtPiBpbnQgPSBcIiVsc2xpbnRcIlxuZXh0ZXJuYWwgKCBsc3IgKSA6IGludCAtPiBpbnQgLT4gaW50ID0gXCIlbHNyaW50XCJcbmV4dGVybmFsICggYXNyICkgOiBpbnQgLT4gaW50IC0+IGludCA9IFwiJWFzcmludFwiXG5cbmxldCBtYXhfaW50ID0gKC0xKSBsc3IgMVxubGV0IG1pbl9pbnQgPSBtYXhfaW50ICsgMVxuXG4oKiBGbG9hdGluZy1wb2ludCBvcGVyYXRpb25zICopXG5cbmV4dGVybmFsICggfi0uICkgOiBmbG9hdCAtPiBmbG9hdCA9IFwiJW5lZ2Zsb2F0XCJcbmV4dGVybmFsICggfisuICkgOiBmbG9hdCAtPiBmbG9hdCA9IFwiJWlkZW50aXR5XCJcbmV4dGVybmFsICggKy4gKSA6IGZsb2F0IC0+IGZsb2F0IC0+IGZsb2F0ID0gXCIlYWRkZmxvYXRcIlxuZXh0ZXJuYWwgKCAtLiApIDogZmxvYXQgLT4gZmxvYXQgLT4gZmxvYXQgPSBcIiVzdWJmbG9hdFwiXG5leHRlcm5hbCAoICouICkgOiBmbG9hdCAtPiBmbG9hdCAtPiBmbG9hdCA9IFwiJW11bGZsb2F0XCJcbmV4dGVybmFsICggLy4gKSA6IGZsb2F0IC0+IGZsb2F0IC0+IGZsb2F0ID0gXCIlZGl2ZmxvYXRcIlxuZXh0ZXJuYWwgKCAqKiApIDogZmxvYXQgLT4gZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfcG93ZXJfZmxvYXRcIiBcInBvd1wiXG4gIFtAQHVuYm94ZWRdIFtAQG5vYWxsb2NdXG5leHRlcm5hbCBleHAgOiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9leHBfZmxvYXRcIiBcImV4cFwiIFtAQHVuYm94ZWRdIFtAQG5vYWxsb2NdXG5leHRlcm5hbCBleHBtMSA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX2V4cG0xX2Zsb2F0XCIgXCJjYW1sX2V4cG0xXCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIGFjb3MgOiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9hY29zX2Zsb2F0XCIgXCJhY29zXCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIGFzaW4gOiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9hc2luX2Zsb2F0XCIgXCJhc2luXCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIGF0YW4gOiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9hdGFuX2Zsb2F0XCIgXCJhdGFuXCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIGF0YW4yIDogZmxvYXQgLT4gZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfYXRhbjJfZmxvYXRcIiBcImF0YW4yXCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIGh5cG90IDogZmxvYXQgLT4gZmxvYXQgLT4gZmxvYXRcbiAgICAgICAgICAgICAgID0gXCJjYW1sX2h5cG90X2Zsb2F0XCIgXCJjYW1sX2h5cG90XCIgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIGNvcyA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX2Nvc19mbG9hdFwiIFwiY29zXCIgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIGNvc2ggOiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9jb3NoX2Zsb2F0XCIgXCJjb3NoXCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIGFjb3NoIDogZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfYWNvc2hfZmxvYXRcIiBcImNhbWxfYWNvc2hcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgbG9nIDogZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfbG9nX2Zsb2F0XCIgXCJsb2dcIiBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgbG9nMTAgOiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9sb2cxMF9mbG9hdFwiIFwibG9nMTBcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgbG9nMXAgOiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9sb2cxcF9mbG9hdFwiIFwiY2FtbF9sb2cxcFwiXG4gIFtAQHVuYm94ZWRdIFtAQG5vYWxsb2NdXG5leHRlcm5hbCBzaW4gOiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9zaW5fZmxvYXRcIiBcInNpblwiIFtAQHVuYm94ZWRdIFtAQG5vYWxsb2NdXG5leHRlcm5hbCBzaW5oIDogZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfc2luaF9mbG9hdFwiIFwic2luaFwiXG4gIFtAQHVuYm94ZWRdIFtAQG5vYWxsb2NdXG5leHRlcm5hbCBhc2luaCA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX2FzaW5oX2Zsb2F0XCIgXCJjYW1sX2FzaW5oXCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIHNxcnQgOiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9zcXJ0X2Zsb2F0XCIgXCJzcXJ0XCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIHRhbiA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX3Rhbl9mbG9hdFwiIFwidGFuXCIgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIHRhbmggOiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF90YW5oX2Zsb2F0XCIgXCJ0YW5oXCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIGF0YW5oIDogZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfYXRhbmhfZmxvYXRcIiBcImNhbWxfYXRhbmhcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgY2VpbCA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX2NlaWxfZmxvYXRcIiBcImNlaWxcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgZmxvb3IgOiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9mbG9vcl9mbG9hdFwiIFwiZmxvb3JcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgYWJzX2Zsb2F0IDogZmxvYXQgLT4gZmxvYXQgPSBcIiVhYnNmbG9hdFwiXG5leHRlcm5hbCBjb3B5c2lnbiA6IGZsb2F0IC0+IGZsb2F0IC0+IGZsb2F0XG4gICAgICAgICAgICAgICAgICA9IFwiY2FtbF9jb3B5c2lnbl9mbG9hdFwiIFwiY2FtbF9jb3B5c2lnblwiXG4gICAgICAgICAgICAgICAgICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgbW9kX2Zsb2F0IDogZmxvYXQgLT4gZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfZm1vZF9mbG9hdFwiIFwiZm1vZFwiXG4gIFtAQHVuYm94ZWRdIFtAQG5vYWxsb2NdXG5leHRlcm5hbCBmcmV4cCA6IGZsb2F0IC0+IGZsb2F0ICogaW50ID0gXCJjYW1sX2ZyZXhwX2Zsb2F0XCJcbmV4dGVybmFsIGxkZXhwIDogKGZsb2F0IFtAdW5ib3hlZF0pIC0+IChpbnQgW0B1bnRhZ2dlZF0pIC0+IChmbG9hdCBbQHVuYm94ZWRdKSA9XG4gIFwiY2FtbF9sZGV4cF9mbG9hdFwiIFwiY2FtbF9sZGV4cF9mbG9hdF91bmJveGVkXCIgW0BAbm9hbGxvY11cbmV4dGVybmFsIG1vZGYgOiBmbG9hdCAtPiBmbG9hdCAqIGZsb2F0ID0gXCJjYW1sX21vZGZfZmxvYXRcIlxuZXh0ZXJuYWwgZmxvYXQgOiBpbnQgLT4gZmxvYXQgPSBcIiVmbG9hdG9maW50XCJcbmV4dGVybmFsIGZsb2F0X29mX2ludCA6IGludCAtPiBmbG9hdCA9IFwiJWZsb2F0b2ZpbnRcIlxuZXh0ZXJuYWwgdHJ1bmNhdGUgOiBmbG9hdCAtPiBpbnQgPSBcIiVpbnRvZmZsb2F0XCJcbmV4dGVybmFsIGludF9vZl9mbG9hdCA6IGZsb2F0IC0+IGludCA9IFwiJWludG9mZmxvYXRcIlxuZXh0ZXJuYWwgZmxvYXRfb2ZfYml0cyA6IGludDY0IC0+IGZsb2F0XG4gID0gXCJjYW1sX2ludDY0X2Zsb2F0X29mX2JpdHNcIiBcImNhbWxfaW50NjRfZmxvYXRfb2ZfYml0c191bmJveGVkXCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmxldCBpbmZpbml0eSA9XG4gIGZsb2F0X29mX2JpdHMgMHg3Rl9GMF8wMF8wMF8wMF8wMF8wMF8wMExcbmxldCBuZWdfaW5maW5pdHkgPVxuICBmbG9hdF9vZl9iaXRzIDB4RkZfRjBfMDBfMDBfMDBfMDBfMDBfMDBMXG5sZXQgbmFuID1cbiAgZmxvYXRfb2ZfYml0cyAweDdGX0YwXzAwXzAwXzAwXzAwXzAwXzAxTFxubGV0IG1heF9mbG9hdCA9XG4gIGZsb2F0X29mX2JpdHMgMHg3Rl9FRl9GRl9GRl9GRl9GRl9GRl9GRkxcbmxldCBtaW5fZmxvYXQgPVxuICBmbG9hdF9vZl9iaXRzIDB4MDBfMTBfMDBfMDBfMDBfMDBfMDBfMDBMXG5sZXQgZXBzaWxvbl9mbG9hdCA9XG4gIGZsb2F0X29mX2JpdHMgMHgzQ19CMF8wMF8wMF8wMF8wMF8wMF8wMExcblxudHlwZSBmcGNsYXNzID1cbiAgICBGUF9ub3JtYWxcbiAgfCBGUF9zdWJub3JtYWxcbiAgfCBGUF96ZXJvXG4gIHwgRlBfaW5maW5pdGVcbiAgfCBGUF9uYW5cbmV4dGVybmFsIGNsYXNzaWZ5X2Zsb2F0IDogKGZsb2F0IFtAdW5ib3hlZF0pIC0+IGZwY2xhc3MgPVxuICBcImNhbWxfY2xhc3NpZnlfZmxvYXRcIiBcImNhbWxfY2xhc3NpZnlfZmxvYXRfdW5ib3hlZFwiIFtAQG5vYWxsb2NdXG5cbigqIFN0cmluZyBhbmQgYnl0ZSBzZXF1ZW5jZSBvcGVyYXRpb25zIC0tIG1vcmUgaW4gbW9kdWxlcyBTdHJpbmcgYW5kIEJ5dGVzICopXG5cbmV4dGVybmFsIHN0cmluZ19sZW5ndGggOiBzdHJpbmcgLT4gaW50ID0gXCIlc3RyaW5nX2xlbmd0aFwiXG5leHRlcm5hbCBieXRlc19sZW5ndGggOiBieXRlcyAtPiBpbnQgPSBcIiVieXRlc19sZW5ndGhcIlxuZXh0ZXJuYWwgYnl0ZXNfY3JlYXRlIDogaW50IC0+IGJ5dGVzID0gXCJjYW1sX2NyZWF0ZV9ieXRlc1wiXG5leHRlcm5hbCBzdHJpbmdfYmxpdCA6IHN0cmluZyAtPiBpbnQgLT4gYnl0ZXMgLT4gaW50IC0+IGludCAtPiB1bml0XG4gICAgICAgICAgICAgICAgICAgICA9IFwiY2FtbF9ibGl0X3N0cmluZ1wiIFtAQG5vYWxsb2NdXG5leHRlcm5hbCBieXRlc19ibGl0IDogYnl0ZXMgLT4gaW50IC0+IGJ5dGVzIC0+IGludCAtPiBpbnQgLT4gdW5pdFxuICAgICAgICAgICAgICAgICAgICAgICAgPSBcImNhbWxfYmxpdF9ieXRlc1wiIFtAQG5vYWxsb2NdXG5leHRlcm5hbCBieXRlc191bnNhZmVfdG9fc3RyaW5nIDogYnl0ZXMgLT4gc3RyaW5nID0gXCIlYnl0ZXNfdG9fc3RyaW5nXCJcblxubGV0ICggXiApIHMxIHMyID1cbiAgbGV0IGwxID0gc3RyaW5nX2xlbmd0aCBzMSBhbmQgbDIgPSBzdHJpbmdfbGVuZ3RoIHMyIGluXG4gIGxldCBzID0gYnl0ZXNfY3JlYXRlIChsMSArIGwyKSBpblxuICBzdHJpbmdfYmxpdCBzMSAwIHMgMCBsMTtcbiAgc3RyaW5nX2JsaXQgczIgMCBzIGwxIGwyO1xuICBieXRlc191bnNhZmVfdG9fc3RyaW5nIHNcblxuKCogQ2hhcmFjdGVyIG9wZXJhdGlvbnMgLS0gbW9yZSBpbiBtb2R1bGUgQ2hhciAqKVxuXG5leHRlcm5hbCBpbnRfb2ZfY2hhciA6IGNoYXIgLT4gaW50ID0gXCIlaWRlbnRpdHlcIlxuZXh0ZXJuYWwgdW5zYWZlX2NoYXJfb2ZfaW50IDogaW50IC0+IGNoYXIgPSBcIiVpZGVudGl0eVwiXG5sZXQgY2hhcl9vZl9pbnQgbiA9XG4gIGlmIG4gPCAwIHx8IG4gPiAyNTUgdGhlbiBpbnZhbGlkX2FyZyBcImNoYXJfb2ZfaW50XCIgZWxzZSB1bnNhZmVfY2hhcl9vZl9pbnQgblxuXG4oKiBVbml0IG9wZXJhdGlvbnMgKilcblxuZXh0ZXJuYWwgaWdub3JlIDogJ2EgLT4gdW5pdCA9IFwiJWlnbm9yZVwiXG5cbigqIFBhaXIgb3BlcmF0aW9ucyAqKVxuXG5leHRlcm5hbCBmc3QgOiAnYSAqICdiIC0+ICdhID0gXCIlZmllbGQwXCJcbmV4dGVybmFsIHNuZCA6ICdhICogJ2IgLT4gJ2IgPSBcIiVmaWVsZDFcIlxuXG4oKiBSZWZlcmVuY2VzICopXG5cbnR5cGUgJ2EgcmVmID0geyBtdXRhYmxlIGNvbnRlbnRzIDogJ2EgfVxuZXh0ZXJuYWwgcmVmIDogJ2EgLT4gJ2EgcmVmID0gXCIlbWFrZW11dGFibGVcIlxuZXh0ZXJuYWwgKCAhICkgOiAnYSByZWYgLT4gJ2EgPSBcIiVmaWVsZDBcIlxuZXh0ZXJuYWwgKCA6PSApIDogJ2EgcmVmIC0+ICdhIC0+IHVuaXQgPSBcIiVzZXRmaWVsZDBcIlxuZXh0ZXJuYWwgaW5jciA6IGludCByZWYgLT4gdW5pdCA9IFwiJWluY3JcIlxuZXh0ZXJuYWwgZGVjciA6IGludCByZWYgLT4gdW5pdCA9IFwiJWRlY3JcIlxuXG4oKiBSZXN1bHQgdHlwZSAqKVxuXG50eXBlICgnYSwnYikgcmVzdWx0ID0gT2sgb2YgJ2EgfCBFcnJvciBvZiAnYlxuXG4oKiBTdHJpbmcgY29udmVyc2lvbiBmdW5jdGlvbnMgKilcblxuZXh0ZXJuYWwgZm9ybWF0X2ludCA6IHN0cmluZyAtPiBpbnQgLT4gc3RyaW5nID0gXCJjYW1sX2Zvcm1hdF9pbnRcIlxuZXh0ZXJuYWwgZm9ybWF0X2Zsb2F0IDogc3RyaW5nIC0+IGZsb2F0IC0+IHN0cmluZyA9IFwiY2FtbF9mb3JtYXRfZmxvYXRcIlxuXG5sZXQgc3RyaW5nX29mX2Jvb2wgYiA9XG4gIGlmIGIgdGhlbiBcInRydWVcIiBlbHNlIFwiZmFsc2VcIlxubGV0IGJvb2xfb2Zfc3RyaW5nID0gZnVuY3Rpb25cbiAgfCBcInRydWVcIiAtPiB0cnVlXG4gIHwgXCJmYWxzZVwiIC0+IGZhbHNlXG4gIHwgXyAtPiBpbnZhbGlkX2FyZyBcImJvb2xfb2Zfc3RyaW5nXCJcblxubGV0IGJvb2xfb2Zfc3RyaW5nX29wdCA9IGZ1bmN0aW9uXG4gIHwgXCJ0cnVlXCIgLT4gU29tZSB0cnVlXG4gIHwgXCJmYWxzZVwiIC0+IFNvbWUgZmFsc2VcbiAgfCBfIC0+IE5vbmVcblxubGV0IHN0cmluZ19vZl9pbnQgbiA9XG4gIGZvcm1hdF9pbnQgXCIlZFwiIG5cblxuZXh0ZXJuYWwgaW50X29mX3N0cmluZyA6IHN0cmluZyAtPiBpbnQgPSBcImNhbWxfaW50X29mX3N0cmluZ1wiXG5cbmxldCBpbnRfb2Zfc3RyaW5nX29wdCBzID1cbiAgKCogVE9ETzogcHJvdmlkZSB0aGlzIGRpcmVjdGx5IGFzIGEgbm9uLXJhaXNpbmcgcHJpbWl0aXZlLiAqKVxuICB0cnkgU29tZSAoaW50X29mX3N0cmluZyBzKVxuICB3aXRoIEZhaWx1cmUgXyAtPiBOb25lXG5cbmV4dGVybmFsIHN0cmluZ19nZXQgOiBzdHJpbmcgLT4gaW50IC0+IGNoYXIgPSBcIiVzdHJpbmdfc2FmZV9nZXRcIlxuXG5sZXQgdmFsaWRfZmxvYXRfbGV4ZW0gcyA9XG4gIGxldCBsID0gc3RyaW5nX2xlbmd0aCBzIGluXG4gIGxldCByZWMgbG9vcCBpID1cbiAgICBpZiBpID49IGwgdGhlbiBzIF4gXCIuXCIgZWxzZVxuICAgIG1hdGNoIHN0cmluZ19nZXQgcyBpIHdpdGhcbiAgICB8ICcwJyAuLiAnOScgfCAnLScgLT4gbG9vcCAoaSArIDEpXG4gICAgfCBfIC0+IHNcbiAgaW5cbiAgbG9vcCAwXG5cbmxldCBzdHJpbmdfb2ZfZmxvYXQgZiA9IHZhbGlkX2Zsb2F0X2xleGVtIChmb3JtYXRfZmxvYXQgXCIlLjEyZ1wiIGYpXG5cbmV4dGVybmFsIGZsb2F0X29mX3N0cmluZyA6IHN0cmluZyAtPiBmbG9hdCA9IFwiY2FtbF9mbG9hdF9vZl9zdHJpbmdcIlxuXG5sZXQgZmxvYXRfb2Zfc3RyaW5nX29wdCBzID1cbiAgKCogVE9ETzogcHJvdmlkZSB0aGlzIGRpcmVjdGx5IGFzIGEgbm9uLXJhaXNpbmcgcHJpbWl0aXZlLiAqKVxuICB0cnkgU29tZSAoZmxvYXRfb2Zfc3RyaW5nIHMpXG4gIHdpdGggRmFpbHVyZSBfIC0+IE5vbmVcblxuKCogTGlzdCBvcGVyYXRpb25zIC0tIG1vcmUgaW4gbW9kdWxlIExpc3QgKilcblxubGV0IHJlYyAoIEAgKSBsMSBsMiA9XG4gIG1hdGNoIGwxIHdpdGhcbiAgICBbXSAtPiBsMlxuICB8IGhkIDo6IHRsIC0+IGhkIDo6ICh0bCBAIGwyKVxuXG4oKiBJL08gb3BlcmF0aW9ucyAqKVxuXG50eXBlIGluX2NoYW5uZWxcbnR5cGUgb3V0X2NoYW5uZWxcblxuZXh0ZXJuYWwgb3Blbl9kZXNjcmlwdG9yX291dCA6IGludCAtPiBvdXRfY2hhbm5lbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IFwiY2FtbF9tbF9vcGVuX2Rlc2NyaXB0b3Jfb3V0XCJcbmV4dGVybmFsIG9wZW5fZGVzY3JpcHRvcl9pbiA6IGludCAtPiBpbl9jaGFubmVsID0gXCJjYW1sX21sX29wZW5fZGVzY3JpcHRvcl9pblwiXG5cbmxldCBzdGRpbiA9IG9wZW5fZGVzY3JpcHRvcl9pbiAwXG5sZXQgc3Rkb3V0ID0gb3Blbl9kZXNjcmlwdG9yX291dCAxXG5sZXQgc3RkZXJyID0gb3Blbl9kZXNjcmlwdG9yX291dCAyXG5cbigqIEdlbmVyYWwgb3V0cHV0IGZ1bmN0aW9ucyAqKVxuXG50eXBlIG9wZW5fZmxhZyA9XG4gICAgT3Blbl9yZG9ubHkgfCBPcGVuX3dyb25seSB8IE9wZW5fYXBwZW5kXG4gIHwgT3Blbl9jcmVhdCB8IE9wZW5fdHJ1bmMgfCBPcGVuX2V4Y2xcbiAgfCBPcGVuX2JpbmFyeSB8IE9wZW5fdGV4dCB8IE9wZW5fbm9uYmxvY2tcblxuZXh0ZXJuYWwgb3Blbl9kZXNjIDogc3RyaW5nIC0+IG9wZW5fZmxhZyBsaXN0IC0+IGludCAtPiBpbnQgPSBcImNhbWxfc3lzX29wZW5cIlxuXG5leHRlcm5hbCBzZXRfb3V0X2NoYW5uZWxfbmFtZTogb3V0X2NoYW5uZWwgLT4gc3RyaW5nIC0+IHVuaXQgPVxuICBcImNhbWxfbWxfc2V0X2NoYW5uZWxfbmFtZVwiXG5cbmxldCBvcGVuX291dF9nZW4gbW9kZSBwZXJtIG5hbWUgPVxuICBsZXQgYyA9IG9wZW5fZGVzY3JpcHRvcl9vdXQob3Blbl9kZXNjIG5hbWUgbW9kZSBwZXJtKSBpblxuICBzZXRfb3V0X2NoYW5uZWxfbmFtZSBjIG5hbWU7XG4gIGNcblxubGV0IG9wZW5fb3V0IG5hbWUgPVxuICBvcGVuX291dF9nZW4gW09wZW5fd3Jvbmx5OyBPcGVuX2NyZWF0OyBPcGVuX3RydW5jOyBPcGVuX3RleHRdIDBvNjY2IG5hbWVcblxubGV0IG9wZW5fb3V0X2JpbiBuYW1lID1cbiAgb3Blbl9vdXRfZ2VuIFtPcGVuX3dyb25seTsgT3Blbl9jcmVhdDsgT3Blbl90cnVuYzsgT3Blbl9iaW5hcnldIDBvNjY2IG5hbWVcblxuZXh0ZXJuYWwgZmx1c2ggOiBvdXRfY2hhbm5lbCAtPiB1bml0ID0gXCJjYW1sX21sX2ZsdXNoXCJcblxuZXh0ZXJuYWwgb3V0X2NoYW5uZWxzX2xpc3QgOiB1bml0IC0+IG91dF9jaGFubmVsIGxpc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgID0gXCJjYW1sX21sX291dF9jaGFubmVsc19saXN0XCJcblxubGV0IGZsdXNoX2FsbCAoKSA9XG4gIGxldCByZWMgaXRlciA9IGZ1bmN0aW9uXG4gICAgICBbXSAtPiAoKVxuICAgIHwgYTo6bCAtPlxuICAgICAgICBiZWdpbiB0cnlcbiAgICAgICAgICAgIGZsdXNoIGFcbiAgICAgICAgd2l0aCBTeXNfZXJyb3IgXyAtPlxuICAgICAgICAgICgpICgqIGlnbm9yZSBjaGFubmVscyBjbG9zZWQgZHVyaW5nIGEgcHJlY2VkaW5nIGZsdXNoLiAqKVxuICAgICAgICBlbmQ7XG4gICAgICAgIGl0ZXIgbFxuICBpbiBpdGVyIChvdXRfY2hhbm5lbHNfbGlzdCAoKSlcblxuZXh0ZXJuYWwgdW5zYWZlX291dHB1dCA6IG91dF9jaGFubmVsIC0+IGJ5dGVzIC0+IGludCAtPiBpbnQgLT4gdW5pdFxuICAgICAgICAgICAgICAgICAgICAgICA9IFwiY2FtbF9tbF9vdXRwdXRfYnl0ZXNcIlxuZXh0ZXJuYWwgdW5zYWZlX291dHB1dF9zdHJpbmcgOiBvdXRfY2hhbm5lbCAtPiBzdHJpbmcgLT4gaW50IC0+IGludCAtPiB1bml0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IFwiY2FtbF9tbF9vdXRwdXRcIlxuXG5leHRlcm5hbCBvdXRwdXRfY2hhciA6IG91dF9jaGFubmVsIC0+IGNoYXIgLT4gdW5pdCA9IFwiY2FtbF9tbF9vdXRwdXRfY2hhclwiXG5cbmxldCBvdXRwdXRfYnl0ZXMgb2MgcyA9XG4gIHVuc2FmZV9vdXRwdXQgb2MgcyAwIChieXRlc19sZW5ndGggcylcblxubGV0IG91dHB1dF9zdHJpbmcgb2MgcyA9XG4gIHVuc2FmZV9vdXRwdXRfc3RyaW5nIG9jIHMgMCAoc3RyaW5nX2xlbmd0aCBzKVxuXG5sZXQgb3V0cHV0IG9jIHMgb2ZzIGxlbiA9XG4gIGlmIG9mcyA8IDAgfHwgbGVuIDwgMCB8fCBvZnMgPiBieXRlc19sZW5ndGggcyAtIGxlblxuICB0aGVuIGludmFsaWRfYXJnIFwib3V0cHV0XCJcbiAgZWxzZSB1bnNhZmVfb3V0cHV0IG9jIHMgb2ZzIGxlblxuXG5sZXQgb3V0cHV0X3N1YnN0cmluZyBvYyBzIG9mcyBsZW4gPVxuICBpZiBvZnMgPCAwIHx8IGxlbiA8IDAgfHwgb2ZzID4gc3RyaW5nX2xlbmd0aCBzIC0gbGVuXG4gIHRoZW4gaW52YWxpZF9hcmcgXCJvdXRwdXRfc3Vic3RyaW5nXCJcbiAgZWxzZSB1bnNhZmVfb3V0cHV0X3N0cmluZyBvYyBzIG9mcyBsZW5cblxuZXh0ZXJuYWwgb3V0cHV0X2J5dGUgOiBvdXRfY2hhbm5lbCAtPiBpbnQgLT4gdW5pdCA9IFwiY2FtbF9tbF9vdXRwdXRfY2hhclwiXG5leHRlcm5hbCBvdXRwdXRfYmluYXJ5X2ludCA6IG91dF9jaGFubmVsIC0+IGludCAtPiB1bml0ID0gXCJjYW1sX21sX291dHB1dF9pbnRcIlxuXG5leHRlcm5hbCBtYXJzaGFsX3RvX2NoYW5uZWwgOiBvdXRfY2hhbm5lbCAtPiAnYSAtPiB1bml0IGxpc3QgLT4gdW5pdFxuICAgICA9IFwiY2FtbF9vdXRwdXRfdmFsdWVcIlxubGV0IG91dHB1dF92YWx1ZSBjaGFuIHYgPSBtYXJzaGFsX3RvX2NoYW5uZWwgY2hhbiB2IFtdXG5cbmV4dGVybmFsIHNlZWtfb3V0IDogb3V0X2NoYW5uZWwgLT4gaW50IC0+IHVuaXQgPSBcImNhbWxfbWxfc2Vla19vdXRcIlxuZXh0ZXJuYWwgcG9zX291dCA6IG91dF9jaGFubmVsIC0+IGludCA9IFwiY2FtbF9tbF9wb3Nfb3V0XCJcbmV4dGVybmFsIG91dF9jaGFubmVsX2xlbmd0aCA6IG91dF9jaGFubmVsIC0+IGludCA9IFwiY2FtbF9tbF9jaGFubmVsX3NpemVcIlxuZXh0ZXJuYWwgY2xvc2Vfb3V0X2NoYW5uZWwgOiBvdXRfY2hhbm5lbCAtPiB1bml0ID0gXCJjYW1sX21sX2Nsb3NlX2NoYW5uZWxcIlxubGV0IGNsb3NlX291dCBvYyA9IGZsdXNoIG9jOyBjbG9zZV9vdXRfY2hhbm5lbCBvY1xubGV0IGNsb3NlX291dF9ub2VyciBvYyA9XG4gICh0cnkgZmx1c2ggb2Mgd2l0aCBfIC0+ICgpKTtcbiAgKHRyeSBjbG9zZV9vdXRfY2hhbm5lbCBvYyB3aXRoIF8gLT4gKCkpXG5leHRlcm5hbCBzZXRfYmluYXJ5X21vZGVfb3V0IDogb3V0X2NoYW5uZWwgLT4gYm9vbCAtPiB1bml0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gXCJjYW1sX21sX3NldF9iaW5hcnlfbW9kZVwiXG5cbigqIEdlbmVyYWwgaW5wdXQgZnVuY3Rpb25zICopXG5cbmV4dGVybmFsIHNldF9pbl9jaGFubmVsX25hbWU6IGluX2NoYW5uZWwgLT4gc3RyaW5nIC0+IHVuaXQgPVxuICBcImNhbWxfbWxfc2V0X2NoYW5uZWxfbmFtZVwiXG5cbmxldCBvcGVuX2luX2dlbiBtb2RlIHBlcm0gbmFtZSA9XG4gIGxldCBjID0gb3Blbl9kZXNjcmlwdG9yX2luKG9wZW5fZGVzYyBuYW1lIG1vZGUgcGVybSkgaW5cbiAgc2V0X2luX2NoYW5uZWxfbmFtZSBjIG5hbWU7XG4gIGNcblxubGV0IG9wZW5faW4gbmFtZSA9XG4gIG9wZW5faW5fZ2VuIFtPcGVuX3Jkb25seTsgT3Blbl90ZXh0XSAwIG5hbWVcblxubGV0IG9wZW5faW5fYmluIG5hbWUgPVxuICBvcGVuX2luX2dlbiBbT3Blbl9yZG9ubHk7IE9wZW5fYmluYXJ5XSAwIG5hbWVcblxuZXh0ZXJuYWwgaW5wdXRfY2hhciA6IGluX2NoYW5uZWwgLT4gY2hhciA9IFwiY2FtbF9tbF9pbnB1dF9jaGFyXCJcblxuZXh0ZXJuYWwgdW5zYWZlX2lucHV0IDogaW5fY2hhbm5lbCAtPiBieXRlcyAtPiBpbnQgLT4gaW50IC0+IGludFxuICAgICAgICAgICAgICAgICAgICAgID0gXCJjYW1sX21sX2lucHV0XCJcblxubGV0IGlucHV0IGljIHMgb2ZzIGxlbiA9XG4gIGlmIG9mcyA8IDAgfHwgbGVuIDwgMCB8fCBvZnMgPiBieXRlc19sZW5ndGggcyAtIGxlblxuICB0aGVuIGludmFsaWRfYXJnIFwiaW5wdXRcIlxuICBlbHNlIHVuc2FmZV9pbnB1dCBpYyBzIG9mcyBsZW5cblxubGV0IHJlYyB1bnNhZmVfcmVhbGx5X2lucHV0IGljIHMgb2ZzIGxlbiA9XG4gIGlmIGxlbiA8PSAwIHRoZW4gKCkgZWxzZSBiZWdpblxuICAgIGxldCByID0gdW5zYWZlX2lucHV0IGljIHMgb2ZzIGxlbiBpblxuICAgIGlmIHIgPSAwXG4gICAgdGhlbiByYWlzZSBFbmRfb2ZfZmlsZVxuICAgIGVsc2UgdW5zYWZlX3JlYWxseV9pbnB1dCBpYyBzIChvZnMgKyByKSAobGVuIC0gcilcbiAgZW5kXG5cbmxldCByZWFsbHlfaW5wdXQgaWMgcyBvZnMgbGVuID1cbiAgaWYgb2ZzIDwgMCB8fCBsZW4gPCAwIHx8IG9mcyA+IGJ5dGVzX2xlbmd0aCBzIC0gbGVuXG4gIHRoZW4gaW52YWxpZF9hcmcgXCJyZWFsbHlfaW5wdXRcIlxuICBlbHNlIHVuc2FmZV9yZWFsbHlfaW5wdXQgaWMgcyBvZnMgbGVuXG5cbmxldCByZWFsbHlfaW5wdXRfc3RyaW5nIGljIGxlbiA9XG4gIGxldCBzID0gYnl0ZXNfY3JlYXRlIGxlbiBpblxuICByZWFsbHlfaW5wdXQgaWMgcyAwIGxlbjtcbiAgYnl0ZXNfdW5zYWZlX3RvX3N0cmluZyBzXG5cbmV4dGVybmFsIGlucHV0X3NjYW5fbGluZSA6IGluX2NoYW5uZWwgLT4gaW50ID0gXCJjYW1sX21sX2lucHV0X3NjYW5fbGluZVwiXG5cbmxldCBpbnB1dF9saW5lIGNoYW4gPVxuICBsZXQgcmVjIGJ1aWxkX3Jlc3VsdCBidWYgcG9zID0gZnVuY3Rpb25cbiAgICBbXSAtPiBidWZcbiAgfCBoZCA6OiB0bCAtPlxuICAgICAgbGV0IGxlbiA9IGJ5dGVzX2xlbmd0aCBoZCBpblxuICAgICAgYnl0ZXNfYmxpdCBoZCAwIGJ1ZiAocG9zIC0gbGVuKSBsZW47XG4gICAgICBidWlsZF9yZXN1bHQgYnVmIChwb3MgLSBsZW4pIHRsIGluXG4gIGxldCByZWMgc2NhbiBhY2N1IGxlbiA9XG4gICAgbGV0IG4gPSBpbnB1dF9zY2FuX2xpbmUgY2hhbiBpblxuICAgIGlmIG4gPSAwIHRoZW4gYmVnaW4gICAgICAgICAgICAgICAgICAgKCogbiA9IDA6IHdlIGFyZSBhdCBFT0YgKilcbiAgICAgIG1hdGNoIGFjY3Ugd2l0aFxuICAgICAgICBbXSAtPiByYWlzZSBFbmRfb2ZfZmlsZVxuICAgICAgfCBfICAtPiBidWlsZF9yZXN1bHQgKGJ5dGVzX2NyZWF0ZSBsZW4pIGxlbiBhY2N1XG4gICAgZW5kIGVsc2UgaWYgbiA+IDAgdGhlbiBiZWdpbiAgICAgICAgICAoKiBuID4gMDogbmV3bGluZSBmb3VuZCBpbiBidWZmZXIgKilcbiAgICAgIGxldCByZXMgPSBieXRlc19jcmVhdGUgKG4gLSAxKSBpblxuICAgICAgaWdub3JlICh1bnNhZmVfaW5wdXQgY2hhbiByZXMgMCAobiAtIDEpKTtcbiAgICAgIGlnbm9yZSAoaW5wdXRfY2hhciBjaGFuKTsgICAgICAgICAgICgqIHNraXAgdGhlIG5ld2xpbmUgKilcbiAgICAgIG1hdGNoIGFjY3Ugd2l0aFxuICAgICAgICBbXSAtPiByZXNcbiAgICAgIHwgIF8gLT4gbGV0IGxlbiA9IGxlbiArIG4gLSAxIGluXG4gICAgICAgICAgICAgIGJ1aWxkX3Jlc3VsdCAoYnl0ZXNfY3JlYXRlIGxlbikgbGVuIChyZXMgOjogYWNjdSlcbiAgICBlbmQgZWxzZSBiZWdpbiAgICAgICAgICAgICAgICAgICAgICAgICgqIG4gPCAwOiBuZXdsaW5lIG5vdCBmb3VuZCAqKVxuICAgICAgbGV0IGJlZyA9IGJ5dGVzX2NyZWF0ZSAoLW4pIGluXG4gICAgICBpZ25vcmUodW5zYWZlX2lucHV0IGNoYW4gYmVnIDAgKC1uKSk7XG4gICAgICBzY2FuIChiZWcgOjogYWNjdSkgKGxlbiAtIG4pXG4gICAgZW5kXG4gIGluIGJ5dGVzX3Vuc2FmZV90b19zdHJpbmcgKHNjYW4gW10gMClcblxuZXh0ZXJuYWwgaW5wdXRfYnl0ZSA6IGluX2NoYW5uZWwgLT4gaW50ID0gXCJjYW1sX21sX2lucHV0X2NoYXJcIlxuZXh0ZXJuYWwgaW5wdXRfYmluYXJ5X2ludCA6IGluX2NoYW5uZWwgLT4gaW50ID0gXCJjYW1sX21sX2lucHV0X2ludFwiXG5leHRlcm5hbCBpbnB1dF92YWx1ZSA6IGluX2NoYW5uZWwgLT4gJ2EgPSBcImNhbWxfaW5wdXRfdmFsdWVcIlxuZXh0ZXJuYWwgc2Vla19pbiA6IGluX2NoYW5uZWwgLT4gaW50IC0+IHVuaXQgPSBcImNhbWxfbWxfc2Vla19pblwiXG5leHRlcm5hbCBwb3NfaW4gOiBpbl9jaGFubmVsIC0+IGludCA9IFwiY2FtbF9tbF9wb3NfaW5cIlxuZXh0ZXJuYWwgaW5fY2hhbm5lbF9sZW5ndGggOiBpbl9jaGFubmVsIC0+IGludCA9IFwiY2FtbF9tbF9jaGFubmVsX3NpemVcIlxuZXh0ZXJuYWwgY2xvc2VfaW4gOiBpbl9jaGFubmVsIC0+IHVuaXQgPSBcImNhbWxfbWxfY2xvc2VfY2hhbm5lbFwiXG5sZXQgY2xvc2VfaW5fbm9lcnIgaWMgPSAodHJ5IGNsb3NlX2luIGljIHdpdGggXyAtPiAoKSlcbmV4dGVybmFsIHNldF9iaW5hcnlfbW9kZV9pbiA6IGluX2NoYW5uZWwgLT4gYm9vbCAtPiB1bml0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBcImNhbWxfbWxfc2V0X2JpbmFyeV9tb2RlXCJcblxuKCogT3V0cHV0IGZ1bmN0aW9ucyBvbiBzdGFuZGFyZCBvdXRwdXQgKilcblxubGV0IHByaW50X2NoYXIgYyA9IG91dHB1dF9jaGFyIHN0ZG91dCBjXG5sZXQgcHJpbnRfc3RyaW5nIHMgPSBvdXRwdXRfc3RyaW5nIHN0ZG91dCBzXG5sZXQgcHJpbnRfYnl0ZXMgcyA9IG91dHB1dF9ieXRlcyBzdGRvdXQgc1xubGV0IHByaW50X2ludCBpID0gb3V0cHV0X3N0cmluZyBzdGRvdXQgKHN0cmluZ19vZl9pbnQgaSlcbmxldCBwcmludF9mbG9hdCBmID0gb3V0cHV0X3N0cmluZyBzdGRvdXQgKHN0cmluZ19vZl9mbG9hdCBmKVxubGV0IHByaW50X2VuZGxpbmUgcyA9XG4gIG91dHB1dF9zdHJpbmcgc3Rkb3V0IHM7IG91dHB1dF9jaGFyIHN0ZG91dCAnXFxuJzsgZmx1c2ggc3Rkb3V0XG5sZXQgcHJpbnRfbmV3bGluZSAoKSA9IG91dHB1dF9jaGFyIHN0ZG91dCAnXFxuJzsgZmx1c2ggc3Rkb3V0XG5cbigqIE91dHB1dCBmdW5jdGlvbnMgb24gc3RhbmRhcmQgZXJyb3IgKilcblxubGV0IHByZXJyX2NoYXIgYyA9IG91dHB1dF9jaGFyIHN0ZGVyciBjXG5sZXQgcHJlcnJfc3RyaW5nIHMgPSBvdXRwdXRfc3RyaW5nIHN0ZGVyciBzXG5sZXQgcHJlcnJfYnl0ZXMgcyA9IG91dHB1dF9ieXRlcyBzdGRlcnIgc1xubGV0IHByZXJyX2ludCBpID0gb3V0cHV0X3N0cmluZyBzdGRlcnIgKHN0cmluZ19vZl9pbnQgaSlcbmxldCBwcmVycl9mbG9hdCBmID0gb3V0cHV0X3N0cmluZyBzdGRlcnIgKHN0cmluZ19vZl9mbG9hdCBmKVxubGV0IHByZXJyX2VuZGxpbmUgcyA9XG4gIG91dHB1dF9zdHJpbmcgc3RkZXJyIHM7IG91dHB1dF9jaGFyIHN0ZGVyciAnXFxuJzsgZmx1c2ggc3RkZXJyXG5sZXQgcHJlcnJfbmV3bGluZSAoKSA9IG91dHB1dF9jaGFyIHN0ZGVyciAnXFxuJzsgZmx1c2ggc3RkZXJyXG5cbigqIElucHV0IGZ1bmN0aW9ucyBvbiBzdGFuZGFyZCBpbnB1dCAqKVxuXG5sZXQgcmVhZF9saW5lICgpID0gZmx1c2ggc3Rkb3V0OyBpbnB1dF9saW5lIHN0ZGluXG5sZXQgcmVhZF9pbnQgKCkgPSBpbnRfb2Zfc3RyaW5nKHJlYWRfbGluZSgpKVxubGV0IHJlYWRfaW50X29wdCAoKSA9IGludF9vZl9zdHJpbmdfb3B0KHJlYWRfbGluZSgpKVxubGV0IHJlYWRfZmxvYXQgKCkgPSBmbG9hdF9vZl9zdHJpbmcocmVhZF9saW5lKCkpXG5sZXQgcmVhZF9mbG9hdF9vcHQgKCkgPSBmbG9hdF9vZl9zdHJpbmdfb3B0KHJlYWRfbGluZSgpKVxuXG4oKiBPcGVyYXRpb25zIG9uIGxhcmdlIGZpbGVzICopXG5cbm1vZHVsZSBMYXJnZUZpbGUgPVxuICBzdHJ1Y3RcbiAgICBleHRlcm5hbCBzZWVrX291dCA6IG91dF9jaGFubmVsIC0+IGludDY0IC0+IHVuaXQgPSBcImNhbWxfbWxfc2Vla19vdXRfNjRcIlxuICAgIGV4dGVybmFsIHBvc19vdXQgOiBvdXRfY2hhbm5lbCAtPiBpbnQ2NCA9IFwiY2FtbF9tbF9wb3Nfb3V0XzY0XCJcbiAgICBleHRlcm5hbCBvdXRfY2hhbm5lbF9sZW5ndGggOiBvdXRfY2hhbm5lbCAtPiBpbnQ2NFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IFwiY2FtbF9tbF9jaGFubmVsX3NpemVfNjRcIlxuICAgIGV4dGVybmFsIHNlZWtfaW4gOiBpbl9jaGFubmVsIC0+IGludDY0IC0+IHVuaXQgPSBcImNhbWxfbWxfc2Vla19pbl82NFwiXG4gICAgZXh0ZXJuYWwgcG9zX2luIDogaW5fY2hhbm5lbCAtPiBpbnQ2NCA9IFwiY2FtbF9tbF9wb3NfaW5fNjRcIlxuICAgIGV4dGVybmFsIGluX2NoYW5uZWxfbGVuZ3RoIDogaW5fY2hhbm5lbCAtPiBpbnQ2NCA9IFwiY2FtbF9tbF9jaGFubmVsX3NpemVfNjRcIlxuICBlbmRcblxuKCogRm9ybWF0cyAqKVxuXG50eXBlICgnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmb3JtYXQ2XG4gICA9ICgnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBDYW1saW50ZXJuYWxGb3JtYXRCYXNpY3MuZm9ybWF0NlxuICAgPSBGb3JtYXQgb2YgKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIENhbWxpbnRlcm5hbEZvcm1hdEJhc2ljcy5mbXRcbiAgICAgICAgICAgICAgICogc3RyaW5nXG5cbnR5cGUgKCdhLCAnYiwgJ2MsICdkKSBmb3JtYXQ0ID0gKCdhLCAnYiwgJ2MsICdjLCAnYywgJ2QpIGZvcm1hdDZcblxudHlwZSAoJ2EsICdiLCAnYykgZm9ybWF0ID0gKCdhLCAnYiwgJ2MsICdjKSBmb3JtYXQ0XG5cbmxldCBzdHJpbmdfb2ZfZm9ybWF0IChGb3JtYXQgKF9mbXQsIHN0cikpID0gc3RyXG5cbmV4dGVybmFsIGZvcm1hdF9vZl9zdHJpbmcgOlxuICgnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmb3JtYXQ2IC0+XG4gKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZvcm1hdDYgPSBcIiVpZGVudGl0eVwiXG5cbmxldCAoIF5eICkgKEZvcm1hdCAoZm10MSwgc3RyMSkpIChGb3JtYXQgKGZtdDIsIHN0cjIpKSA9XG4gIEZvcm1hdCAoQ2FtbGludGVybmFsRm9ybWF0QmFzaWNzLmNvbmNhdF9mbXQgZm10MSBmbXQyLFxuICAgICAgICAgIHN0cjEgXiBcIiUsXCIgXiBzdHIyKVxuXG4oKiBNaXNjZWxsYW5lb3VzICopXG5cbmV4dGVybmFsIHN5c19leGl0IDogaW50IC0+ICdhID0gXCJjYW1sX3N5c19leGl0XCJcblxubGV0IGV4aXRfZnVuY3Rpb24gPSBDYW1saW50ZXJuYWxBdG9taWMubWFrZSBmbHVzaF9hbGxcblxubGV0IHJlYyBhdF9leGl0IGYgPVxuICBsZXQgbW9kdWxlIEF0b21pYyA9IENhbWxpbnRlcm5hbEF0b21pYyBpblxuICAoKiBNUFIjNzI1MywgTVBSIzc3OTY6IG1ha2Ugc3VyZSBcImZcIiBpcyBleGVjdXRlZCBvbmx5IG9uY2UgKilcbiAgbGV0IGZfeWV0X3RvX3J1biA9IEF0b21pYy5tYWtlIHRydWUgaW5cbiAgbGV0IG9sZF9leGl0ID0gQXRvbWljLmdldCBleGl0X2Z1bmN0aW9uIGluXG4gIGxldCBuZXdfZXhpdCAoKSA9XG4gICAgaWYgQXRvbWljLmNvbXBhcmVfYW5kX3NldCBmX3lldF90b19ydW4gdHJ1ZSBmYWxzZSB0aGVuIGYgKCkgO1xuICAgIG9sZF9leGl0ICgpXG4gIGluXG4gIGxldCBzdWNjZXNzID0gQXRvbWljLmNvbXBhcmVfYW5kX3NldCBleGl0X2Z1bmN0aW9uIG9sZF9leGl0IG5ld19leGl0IGluXG4gIGlmIG5vdCBzdWNjZXNzIHRoZW4gYXRfZXhpdCBmXG5cbmxldCBkb19hdF9leGl0ICgpID0gKENhbWxpbnRlcm5hbEF0b21pYy5nZXQgZXhpdF9mdW5jdGlvbikgKClcblxubGV0IGV4aXQgcmV0Y29kZSA9XG4gIGRvX2F0X2V4aXQgKCk7XG4gIHN5c19leGl0IHJldGNvZGVcblxubGV0IF8gPSByZWdpc3Rlcl9uYW1lZF92YWx1ZSBcIlBlcnZhc2l2ZXMuZG9fYXRfZXhpdFwiIGRvX2F0X2V4aXRcblxuZXh0ZXJuYWwgbWFqb3IgOiB1bml0IC0+IHVuaXQgPSBcImNhbWxfZ2NfbWFqb3JcIlxuZXh0ZXJuYWwgbmFrZWRfcG9pbnRlcnNfY2hlY2tlZCA6IHVuaXQgLT4gYm9vbFxuICA9IFwiY2FtbF9zeXNfY29uc3RfbmFrZWRfcG9pbnRlcnNfY2hlY2tlZFwiXG5sZXQgKCkgPSBpZiBuYWtlZF9wb2ludGVyc19jaGVja2VkICgpIHRoZW4gYXRfZXhpdCBtYWpvclxuXG4oKk1PRFVMRV9BTElBU0VTKilcbm1vZHVsZSBBcmcgICAgICAgICAgPSBBcmdcbm1vZHVsZSBBcnJheSAgICAgICAgPSBBcnJheVxubW9kdWxlIEFycmF5TGFiZWxzICA9IEFycmF5TGFiZWxzXG5tb2R1bGUgQXRvbWljICAgICAgID0gQXRvbWljXG5tb2R1bGUgQmlnYXJyYXkgICAgID0gQmlnYXJyYXlcbm1vZHVsZSBCb29sICAgICAgICAgPSBCb29sXG5tb2R1bGUgQnVmZmVyICAgICAgID0gQnVmZmVyXG5tb2R1bGUgQnl0ZXMgICAgICAgID0gQnl0ZXNcbm1vZHVsZSBCeXRlc0xhYmVscyAgPSBCeXRlc0xhYmVsc1xubW9kdWxlIENhbGxiYWNrICAgICA9IENhbGxiYWNrXG5tb2R1bGUgQ2hhciAgICAgICAgID0gQ2hhclxubW9kdWxlIENvbXBsZXggICAgICA9IENvbXBsZXhcbm1vZHVsZSBEaWdlc3QgICAgICAgPSBEaWdlc3Rcbm1vZHVsZSBFaXRoZXIgICAgICAgPSBFaXRoZXJcbm1vZHVsZSBFcGhlbWVyb24gICAgPSBFcGhlbWVyb25cbm1vZHVsZSBGaWxlbmFtZSAgICAgPSBGaWxlbmFtZVxubW9kdWxlIEZsb2F0ICAgICAgICA9IEZsb2F0XG5tb2R1bGUgRm9ybWF0ICAgICAgID0gRm9ybWF0XG5tb2R1bGUgRnVuICAgICAgICAgID0gRnVuXG5tb2R1bGUgR2MgICAgICAgICAgID0gR2Ncbm1vZHVsZSBHZW5sZXggICAgICAgPSBHZW5sZXhcbm1vZHVsZSBIYXNodGJsICAgICAgPSBIYXNodGJsXG5tb2R1bGUgSW50ICAgICAgICAgID0gSW50XG5tb2R1bGUgSW50MzIgICAgICAgID0gSW50MzJcbm1vZHVsZSBJbnQ2NCAgICAgICAgPSBJbnQ2NFxubW9kdWxlIExhenkgICAgICAgICA9IExhenlcbm1vZHVsZSBMZXhpbmcgICAgICAgPSBMZXhpbmdcbm1vZHVsZSBMaXN0ICAgICAgICAgPSBMaXN0XG5tb2R1bGUgTGlzdExhYmVscyAgID0gTGlzdExhYmVsc1xubW9kdWxlIE1hcCAgICAgICAgICA9IE1hcFxubW9kdWxlIE1hcnNoYWwgICAgICA9IE1hcnNoYWxcbm1vZHVsZSBNb3JlTGFiZWxzICAgPSBNb3JlTGFiZWxzXG5tb2R1bGUgTmF0aXZlaW50ICAgID0gTmF0aXZlaW50XG5tb2R1bGUgT2JqICAgICAgICAgID0gT2JqXG5tb2R1bGUgT28gICAgICAgICAgID0gT29cbm1vZHVsZSBPcHRpb24gICAgICAgPSBPcHRpb25cbm1vZHVsZSBQYXJzaW5nICAgICAgPSBQYXJzaW5nXG5tb2R1bGUgUGVydmFzaXZlcyAgID0gUGVydmFzaXZlc1xubW9kdWxlIFByaW50ZXhjICAgICA9IFByaW50ZXhjXG5tb2R1bGUgUHJpbnRmICAgICAgID0gUHJpbnRmXG5tb2R1bGUgUXVldWUgICAgICAgID0gUXVldWVcbm1vZHVsZSBSYW5kb20gICAgICAgPSBSYW5kb21cbm1vZHVsZSBSZXN1bHQgICAgICAgPSBSZXN1bHRcbm1vZHVsZSBTY2FuZiAgICAgICAgPSBTY2FuZlxubW9kdWxlIFNlcSAgICAgICAgICA9IFNlcVxubW9kdWxlIFNldCAgICAgICAgICA9IFNldFxubW9kdWxlIFN0YWNrICAgICAgICA9IFN0YWNrXG5tb2R1bGUgU3RkTGFiZWxzICAgID0gU3RkTGFiZWxzXG5tb2R1bGUgU3RyZWFtICAgICAgID0gU3RyZWFtXG5tb2R1bGUgU3RyaW5nICAgICAgID0gU3RyaW5nXG5tb2R1bGUgU3RyaW5nTGFiZWxzID0gU3RyaW5nTGFiZWxzXG5tb2R1bGUgU3lzICAgICAgICAgID0gU3lzXG5tb2R1bGUgVWNoYXIgICAgICAgID0gVWNoYXJcbm1vZHVsZSBVbml0ICAgICAgICAgPSBVbml0XG5tb2R1bGUgV2VhayAgICAgICAgID0gV2Vha1xuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgSmVyZW1pZSBEaW1pbm8sIEphbmUgU3RyZWV0IEV1cm9wZSAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMjAxNyBKYW5lIFN0cmVldCBHcm91cCBMTEMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG4oKiogQGRlcHJlY2F0ZWQgVXNlIHshU3RkbGlifSAqKVxuXG5leHRlcm5hbCByYWlzZSA6IGV4biAtPiAnYSA9IFwiJXJhaXNlXCJcbmV4dGVybmFsIHJhaXNlX25vdHJhY2UgOiBleG4gLT4gJ2EgPSBcIiVyYWlzZV9ub3RyYWNlXCJcbmxldCBpbnZhbGlkX2FyZyA9IGludmFsaWRfYXJnXG5sZXQgZmFpbHdpdGggPSBmYWlsd2l0aFxuZXhjZXB0aW9uIEV4aXRcbmV4dGVybmFsICggPSApIDogJ2EgLT4gJ2EgLT4gYm9vbCA9IFwiJWVxdWFsXCJcbmV4dGVybmFsICggPD4gKSA6ICdhIC0+ICdhIC0+IGJvb2wgPSBcIiVub3RlcXVhbFwiXG5leHRlcm5hbCAoIDwgKSA6ICdhIC0+ICdhIC0+IGJvb2wgPSBcIiVsZXNzdGhhblwiXG5leHRlcm5hbCAoID4gKSA6ICdhIC0+ICdhIC0+IGJvb2wgPSBcIiVncmVhdGVydGhhblwiXG5leHRlcm5hbCAoIDw9ICkgOiAnYSAtPiAnYSAtPiBib29sID0gXCIlbGVzc2VxdWFsXCJcbmV4dGVybmFsICggPj0gKSA6ICdhIC0+ICdhIC0+IGJvb2wgPSBcIiVncmVhdGVyZXF1YWxcIlxuZXh0ZXJuYWwgY29tcGFyZSA6ICdhIC0+ICdhIC0+IGludCA9IFwiJWNvbXBhcmVcIlxubGV0IG1pbiA9IG1pblxubGV0IG1heCA9IG1heFxuZXh0ZXJuYWwgKCA9PSApIDogJ2EgLT4gJ2EgLT4gYm9vbCA9IFwiJWVxXCJcbmV4dGVybmFsICggIT0gKSA6ICdhIC0+ICdhIC0+IGJvb2wgPSBcIiVub3RlcVwiXG5leHRlcm5hbCBub3QgOiBib29sIC0+IGJvb2wgPSBcIiVib29sbm90XCJcbmV4dGVybmFsICggJiYgKSA6IGJvb2wgLT4gYm9vbCAtPiBib29sID0gXCIlc2VxdWFuZFwiXG5leHRlcm5hbCAoICYgKSA6IGJvb2wgLT4gYm9vbCAtPiBib29sID0gXCIlc2VxdWFuZFwiXG4gIFtAQG9jYW1sLmRlcHJlY2F0ZWQgXCJVc2UgKCYmKSBpbnN0ZWFkLlwiXVxuZXh0ZXJuYWwgKCB8fCApIDogYm9vbCAtPiBib29sIC0+IGJvb2wgPSBcIiVzZXF1b3JcIlxuZXh0ZXJuYWwgKCBvciApIDogYm9vbCAtPiBib29sIC0+IGJvb2wgPSBcIiVzZXF1b3JcIlxuICBbQEBvY2FtbC5kZXByZWNhdGVkIFwiVXNlICh8fCkgaW5zdGVhZC5cIl1cbmV4dGVybmFsIF9fTE9DX18gOiBzdHJpbmcgPSBcIiVsb2NfTE9DXCJcbmV4dGVybmFsIF9fRklMRV9fIDogc3RyaW5nID0gXCIlbG9jX0ZJTEVcIlxuZXh0ZXJuYWwgX19MSU5FX18gOiBpbnQgPSBcIiVsb2NfTElORVwiXG5leHRlcm5hbCBfX01PRFVMRV9fIDogc3RyaW5nID0gXCIlbG9jX01PRFVMRVwiXG5leHRlcm5hbCBfX1BPU19fIDogc3RyaW5nICogaW50ICogaW50ICogaW50ID0gXCIlbG9jX1BPU1wiXG5leHRlcm5hbCBfX0xPQ19PRl9fIDogJ2EgLT4gc3RyaW5nICogJ2EgPSBcIiVsb2NfTE9DXCJcbmV4dGVybmFsIF9fTElORV9PRl9fIDogJ2EgLT4gaW50ICogJ2EgPSBcIiVsb2NfTElORVwiXG5leHRlcm5hbCBfX1BPU19PRl9fIDogJ2EgLT4gKHN0cmluZyAqIGludCAqIGludCAqIGludCkgKiAnYSA9IFwiJWxvY19QT1NcIlxuZXh0ZXJuYWwgKCB8PiApIDogJ2EgLT4gKCdhIC0+ICdiKSAtPiAnYiA9IFwiJXJldmFwcGx5XCJcbmV4dGVybmFsICggQEAgKSA6ICgnYSAtPiAnYikgLT4gJ2EgLT4gJ2IgPSBcIiVhcHBseVwiXG5leHRlcm5hbCAoIH4tICkgOiBpbnQgLT4gaW50ID0gXCIlbmVnaW50XCJcbmV4dGVybmFsICggfisgKSA6IGludCAtPiBpbnQgPSBcIiVpZGVudGl0eVwiXG5leHRlcm5hbCBzdWNjIDogaW50IC0+IGludCA9IFwiJXN1Y2NpbnRcIlxuZXh0ZXJuYWwgcHJlZCA6IGludCAtPiBpbnQgPSBcIiVwcmVkaW50XCJcbmV4dGVybmFsICggKyApIDogaW50IC0+IGludCAtPiBpbnQgPSBcIiVhZGRpbnRcIlxuZXh0ZXJuYWwgKCAtICkgOiBpbnQgLT4gaW50IC0+IGludCA9IFwiJXN1YmludFwiXG5leHRlcm5hbCAoICogKSA6IGludCAtPiBpbnQgLT4gaW50ID0gXCIlbXVsaW50XCJcbmV4dGVybmFsICggLyApIDogaW50IC0+IGludCAtPiBpbnQgPSBcIiVkaXZpbnRcIlxuZXh0ZXJuYWwgKCBtb2QgKSA6IGludCAtPiBpbnQgLT4gaW50ID0gXCIlbW9kaW50XCJcbmxldCBhYnMgPSBhYnNcbmxldCBtYXhfaW50ID0gbWF4X2ludFxubGV0IG1pbl9pbnQgPSBtaW5faW50XG5leHRlcm5hbCAoIGxhbmQgKSA6IGludCAtPiBpbnQgLT4gaW50ID0gXCIlYW5kaW50XCJcbmV4dGVybmFsICggbG9yICkgOiBpbnQgLT4gaW50IC0+IGludCA9IFwiJW9yaW50XCJcbmV4dGVybmFsICggbHhvciApIDogaW50IC0+IGludCAtPiBpbnQgPSBcIiV4b3JpbnRcIlxubGV0IGxub3QgPSBsbm90XG5leHRlcm5hbCAoIGxzbCApIDogaW50IC0+IGludCAtPiBpbnQgPSBcIiVsc2xpbnRcIlxuZXh0ZXJuYWwgKCBsc3IgKSA6IGludCAtPiBpbnQgLT4gaW50ID0gXCIlbHNyaW50XCJcbmV4dGVybmFsICggYXNyICkgOiBpbnQgLT4gaW50IC0+IGludCA9IFwiJWFzcmludFwiXG5leHRlcm5hbCAoIH4tLiApIDogZmxvYXQgLT4gZmxvYXQgPSBcIiVuZWdmbG9hdFwiXG5leHRlcm5hbCAoIH4rLiApIDogZmxvYXQgLT4gZmxvYXQgPSBcIiVpZGVudGl0eVwiXG5leHRlcm5hbCAoICsuICkgOiBmbG9hdCAtPiBmbG9hdCAtPiBmbG9hdCA9IFwiJWFkZGZsb2F0XCJcbmV4dGVybmFsICggLS4gKSA6IGZsb2F0IC0+IGZsb2F0IC0+IGZsb2F0ID0gXCIlc3ViZmxvYXRcIlxuZXh0ZXJuYWwgKCAqLiApIDogZmxvYXQgLT4gZmxvYXQgLT4gZmxvYXQgPSBcIiVtdWxmbG9hdFwiXG5leHRlcm5hbCAoIC8uICkgOiBmbG9hdCAtPiBmbG9hdCAtPiBmbG9hdCA9IFwiJWRpdmZsb2F0XCJcbmV4dGVybmFsICggKiogKSA6IGZsb2F0IC0+IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX3Bvd2VyX2Zsb2F0XCIgXCJwb3dcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgc3FydCA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX3NxcnRfZmxvYXRcIiBcInNxcnRcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgZXhwIDogZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfZXhwX2Zsb2F0XCIgXCJleHBcIiBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgbG9nIDogZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfbG9nX2Zsb2F0XCIgXCJsb2dcIiBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgbG9nMTAgOiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9sb2cxMF9mbG9hdFwiIFwibG9nMTBcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgZXhwbTEgOiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9leHBtMV9mbG9hdFwiIFwiY2FtbF9leHBtMVwiXG4gIFtAQHVuYm94ZWRdIFtAQG5vYWxsb2NdXG5leHRlcm5hbCBsb2cxcCA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX2xvZzFwX2Zsb2F0XCIgXCJjYW1sX2xvZzFwXCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIGNvcyA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX2Nvc19mbG9hdFwiIFwiY29zXCIgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIHNpbiA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX3Npbl9mbG9hdFwiIFwic2luXCIgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIHRhbiA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX3Rhbl9mbG9hdFwiIFwidGFuXCIgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIGFjb3MgOiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9hY29zX2Zsb2F0XCIgXCJhY29zXCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIGFzaW4gOiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9hc2luX2Zsb2F0XCIgXCJhc2luXCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIGF0YW4gOiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9hdGFuX2Zsb2F0XCIgXCJhdGFuXCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIGF0YW4yIDogZmxvYXQgLT4gZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfYXRhbjJfZmxvYXRcIiBcImF0YW4yXCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIGh5cG90IDogZmxvYXQgLT4gZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfaHlwb3RfZmxvYXRcIiBcImNhbWxfaHlwb3RcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgY29zaCA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX2Nvc2hfZmxvYXRcIiBcImNvc2hcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgc2luaCA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX3NpbmhfZmxvYXRcIiBcInNpbmhcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgdGFuaCA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX3RhbmhfZmxvYXRcIiBcInRhbmhcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgY2VpbCA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX2NlaWxfZmxvYXRcIiBcImNlaWxcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgZmxvb3IgOiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9mbG9vcl9mbG9hdFwiIFwiZmxvb3JcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgYWJzX2Zsb2F0IDogZmxvYXQgLT4gZmxvYXQgPSBcIiVhYnNmbG9hdFwiXG5leHRlcm5hbCBjb3B5c2lnbiA6IGZsb2F0IC0+IGZsb2F0IC0+IGZsb2F0XG4gICAgICAgICAgICAgICAgICA9IFwiY2FtbF9jb3B5c2lnbl9mbG9hdFwiIFwiY2FtbF9jb3B5c2lnblwiXG4gICAgICAgICAgICAgICAgICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgbW9kX2Zsb2F0IDogZmxvYXQgLT4gZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfZm1vZF9mbG9hdFwiIFwiZm1vZFwiXG4gIFtAQHVuYm94ZWRdIFtAQG5vYWxsb2NdXG5leHRlcm5hbCBmcmV4cCA6IGZsb2F0IC0+IGZsb2F0ICogaW50ID0gXCJjYW1sX2ZyZXhwX2Zsb2F0XCJcbmV4dGVybmFsIGxkZXhwIDogKGZsb2F0IFtAdW5ib3hlZF0pIC0+IChpbnQgW0B1bnRhZ2dlZF0pIC0+IChmbG9hdCBbQHVuYm94ZWRdKSA9XG4gIFwiY2FtbF9sZGV4cF9mbG9hdFwiIFwiY2FtbF9sZGV4cF9mbG9hdF91bmJveGVkXCIgW0BAbm9hbGxvY11cbmV4dGVybmFsIG1vZGYgOiBmbG9hdCAtPiBmbG9hdCAqIGZsb2F0ID0gXCJjYW1sX21vZGZfZmxvYXRcIlxuZXh0ZXJuYWwgZmxvYXQgOiBpbnQgLT4gZmxvYXQgPSBcIiVmbG9hdG9maW50XCJcbmV4dGVybmFsIGZsb2F0X29mX2ludCA6IGludCAtPiBmbG9hdCA9IFwiJWZsb2F0b2ZpbnRcIlxuZXh0ZXJuYWwgdHJ1bmNhdGUgOiBmbG9hdCAtPiBpbnQgPSBcIiVpbnRvZmZsb2F0XCJcbmV4dGVybmFsIGludF9vZl9mbG9hdCA6IGZsb2F0IC0+IGludCA9IFwiJWludG9mZmxvYXRcIlxubGV0IGluZmluaXR5ID0gaW5maW5pdHlcbmxldCBuZWdfaW5maW5pdHkgPSBuZWdfaW5maW5pdHlcbmxldCBuYW4gPSBuYW5cbmxldCBtYXhfZmxvYXQgPSBtYXhfZmxvYXRcbmxldCBtaW5fZmxvYXQgPSBtaW5fZmxvYXRcbmxldCBlcHNpbG9uX2Zsb2F0ID0gZXBzaWxvbl9mbG9hdFxudHlwZSBub25yZWMgZnBjbGFzcyA9IGZwY2xhc3MgPVxuICAgIEZQX25vcm1hbFxuICB8IEZQX3N1Ym5vcm1hbFxuICB8IEZQX3plcm9cbiAgfCBGUF9pbmZpbml0ZVxuICB8IEZQX25hblxuZXh0ZXJuYWwgY2xhc3NpZnlfZmxvYXQgOiAoZmxvYXQgW0B1bmJveGVkXSkgLT4gZnBjbGFzcyA9XG4gIFwiY2FtbF9jbGFzc2lmeV9mbG9hdFwiIFwiY2FtbF9jbGFzc2lmeV9mbG9hdF91bmJveGVkXCIgW0BAbm9hbGxvY11cbmxldCAoIF4gKSA9ICggXiApXG5leHRlcm5hbCBpbnRfb2ZfY2hhciA6IGNoYXIgLT4gaW50ID0gXCIlaWRlbnRpdHlcIlxubGV0IGNoYXJfb2ZfaW50ID0gY2hhcl9vZl9pbnRcbmV4dGVybmFsIGlnbm9yZSA6ICdhIC0+IHVuaXQgPSBcIiVpZ25vcmVcIlxubGV0IHN0cmluZ19vZl9ib29sID0gc3RyaW5nX29mX2Jvb2xcbmxldCBib29sX29mX3N0cmluZyA9IGJvb2xfb2Zfc3RyaW5nXG5sZXQgYm9vbF9vZl9zdHJpbmdfb3B0ID0gYm9vbF9vZl9zdHJpbmdfb3B0XG5sZXQgc3RyaW5nX29mX2ludCA9IHN0cmluZ19vZl9pbnRcbmV4dGVybmFsIGludF9vZl9zdHJpbmcgOiBzdHJpbmcgLT4gaW50ID0gXCJjYW1sX2ludF9vZl9zdHJpbmdcIlxubGV0IGludF9vZl9zdHJpbmdfb3B0ID0gaW50X29mX3N0cmluZ19vcHRcbmxldCBzdHJpbmdfb2ZfZmxvYXQgPSBzdHJpbmdfb2ZfZmxvYXRcbmV4dGVybmFsIGZsb2F0X29mX3N0cmluZyA6IHN0cmluZyAtPiBmbG9hdCA9IFwiY2FtbF9mbG9hdF9vZl9zdHJpbmdcIlxubGV0IGZsb2F0X29mX3N0cmluZ19vcHQgPSBmbG9hdF9vZl9zdHJpbmdfb3B0XG5leHRlcm5hbCBmc3QgOiAnYSAqICdiIC0+ICdhID0gXCIlZmllbGQwXCJcbmV4dGVybmFsIHNuZCA6ICdhICogJ2IgLT4gJ2IgPSBcIiVmaWVsZDFcIlxubGV0ICggQCApICA9ICggQCApXG50eXBlIG5vbnJlYyBpbl9jaGFubmVsID0gaW5fY2hhbm5lbFxudHlwZSBub25yZWMgb3V0X2NoYW5uZWwgPSBvdXRfY2hhbm5lbFxubGV0IHN0ZGluID0gc3RkaW5cbmxldCBzdGRvdXQgPSBzdGRvdXRcbmxldCBzdGRlcnIgPSBzdGRlcnJcbmxldCBwcmludF9jaGFyID0gcHJpbnRfY2hhclxubGV0IHByaW50X3N0cmluZyA9IHByaW50X3N0cmluZ1xubGV0IHByaW50X2J5dGVzID0gcHJpbnRfYnl0ZXNcbmxldCBwcmludF9pbnQgPSBwcmludF9pbnRcbmxldCBwcmludF9mbG9hdCA9IHByaW50X2Zsb2F0XG5sZXQgcHJpbnRfZW5kbGluZSA9IHByaW50X2VuZGxpbmVcbmxldCBwcmludF9uZXdsaW5lID0gcHJpbnRfbmV3bGluZVxubGV0IHByZXJyX2NoYXIgPSBwcmVycl9jaGFyXG5sZXQgcHJlcnJfc3RyaW5nID0gcHJlcnJfc3RyaW5nXG5sZXQgcHJlcnJfYnl0ZXMgPSBwcmVycl9ieXRlc1xubGV0IHByZXJyX2ludCA9IHByZXJyX2ludFxubGV0IHByZXJyX2Zsb2F0ID0gcHJlcnJfZmxvYXRcbmxldCBwcmVycl9lbmRsaW5lID0gcHJlcnJfZW5kbGluZVxubGV0IHByZXJyX25ld2xpbmUgPSBwcmVycl9uZXdsaW5lXG5sZXQgcmVhZF9saW5lID0gcmVhZF9saW5lXG5sZXQgcmVhZF9pbnQgPSByZWFkX2ludFxubGV0IHJlYWRfaW50X29wdCA9IHJlYWRfaW50X29wdFxubGV0IHJlYWRfZmxvYXQgPSByZWFkX2Zsb2F0XG5sZXQgcmVhZF9mbG9hdF9vcHQgPSByZWFkX2Zsb2F0X29wdFxudHlwZSBub25yZWMgb3Blbl9mbGFnID0gb3Blbl9mbGFnID1cbiAgICBPcGVuX3Jkb25seVxuICB8IE9wZW5fd3Jvbmx5XG4gIHwgT3Blbl9hcHBlbmRcbiAgfCBPcGVuX2NyZWF0XG4gIHwgT3Blbl90cnVuY1xuICB8IE9wZW5fZXhjbFxuICB8IE9wZW5fYmluYXJ5XG4gIHwgT3Blbl90ZXh0XG4gIHwgT3Blbl9ub25ibG9ja1xubGV0IG9wZW5fb3V0ID0gb3Blbl9vdXRcbmxldCBvcGVuX291dF9iaW4gPSBvcGVuX291dF9iaW5cbmxldCBvcGVuX291dF9nZW4gPSBvcGVuX291dF9nZW5cbmxldCBmbHVzaCA9IGZsdXNoXG5sZXQgZmx1c2hfYWxsID0gZmx1c2hfYWxsXG5sZXQgb3V0cHV0X2NoYXIgPSBvdXRwdXRfY2hhclxubGV0IG91dHB1dF9zdHJpbmcgPSBvdXRwdXRfc3RyaW5nXG5sZXQgb3V0cHV0X2J5dGVzID0gb3V0cHV0X2J5dGVzXG5sZXQgb3V0cHV0ID0gb3V0cHV0XG5sZXQgb3V0cHV0X3N1YnN0cmluZyA9IG91dHB1dF9zdWJzdHJpbmdcbmxldCBvdXRwdXRfYnl0ZSA9IG91dHB1dF9ieXRlXG5sZXQgb3V0cHV0X2JpbmFyeV9pbnQgPSBvdXRwdXRfYmluYXJ5X2ludFxubGV0IG91dHB1dF92YWx1ZSA9IG91dHB1dF92YWx1ZVxubGV0IHNlZWtfb3V0ID0gc2Vla19vdXRcbmxldCBwb3Nfb3V0ID0gcG9zX291dFxubGV0IG91dF9jaGFubmVsX2xlbmd0aCA9IG91dF9jaGFubmVsX2xlbmd0aFxubGV0IGNsb3NlX291dCA9IGNsb3NlX291dFxubGV0IGNsb3NlX291dF9ub2VyciA9IGNsb3NlX291dF9ub2VyclxubGV0IHNldF9iaW5hcnlfbW9kZV9vdXQgPSBzZXRfYmluYXJ5X21vZGVfb3V0XG5sZXQgb3Blbl9pbiA9IG9wZW5faW5cbmxldCBvcGVuX2luX2JpbiA9IG9wZW5faW5fYmluXG5sZXQgb3Blbl9pbl9nZW4gPSBvcGVuX2luX2dlblxubGV0IGlucHV0X2NoYXIgPSBpbnB1dF9jaGFyXG5sZXQgaW5wdXRfbGluZSA9IGlucHV0X2xpbmVcbmxldCBpbnB1dCA9IGlucHV0XG5sZXQgcmVhbGx5X2lucHV0ID0gcmVhbGx5X2lucHV0XG5sZXQgcmVhbGx5X2lucHV0X3N0cmluZyA9IHJlYWxseV9pbnB1dF9zdHJpbmdcbmxldCBpbnB1dF9ieXRlID0gaW5wdXRfYnl0ZVxubGV0IGlucHV0X2JpbmFyeV9pbnQgPSBpbnB1dF9iaW5hcnlfaW50XG5sZXQgaW5wdXRfdmFsdWUgPSBpbnB1dF92YWx1ZVxubGV0IHNlZWtfaW4gPSBzZWVrX2luXG5sZXQgcG9zX2luID0gcG9zX2luXG5sZXQgaW5fY2hhbm5lbF9sZW5ndGggPSBpbl9jaGFubmVsX2xlbmd0aFxubGV0IGNsb3NlX2luID0gY2xvc2VfaW5cbmxldCBjbG9zZV9pbl9ub2VyciA9IGNsb3NlX2luX25vZXJyXG5sZXQgc2V0X2JpbmFyeV9tb2RlX2luID0gc2V0X2JpbmFyeV9tb2RlX2luXG5tb2R1bGUgTGFyZ2VGaWxlID0gTGFyZ2VGaWxlXG50eXBlIG5vbnJlYyAnYSByZWYgPSAnYSByZWYgPSB7IG11dGFibGUgY29udGVudHMgOiAnYSB9XG5leHRlcm5hbCByZWYgOiAnYSAtPiAnYSByZWYgPSBcIiVtYWtlbXV0YWJsZVwiXG5leHRlcm5hbCAoICEgKSA6ICdhIHJlZiAtPiAnYSA9IFwiJWZpZWxkMFwiXG5leHRlcm5hbCAoIDo9ICkgOiAnYSByZWYgLT4gJ2EgLT4gdW5pdCA9IFwiJXNldGZpZWxkMFwiXG5leHRlcm5hbCBpbmNyIDogaW50IHJlZiAtPiB1bml0ID0gXCIlaW5jclwiXG5leHRlcm5hbCBkZWNyIDogaW50IHJlZiAtPiB1bml0ID0gXCIlZGVjclwiXG50eXBlIG5vbnJlYyAoJ2EsJ2IpIHJlc3VsdCA9ICgnYSwnYikgcmVzdWx0ID0gT2sgb2YgJ2EgfCBFcnJvciBvZiAnYlxudHlwZSAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm9ybWF0NiA9XG4gICgnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBDYW1saW50ZXJuYWxGb3JtYXRCYXNpY3MuZm9ybWF0NlxudHlwZSAoJ2EsICdiLCAnYywgJ2QpIGZvcm1hdDQgPSAoJ2EsICdiLCAnYywgJ2MsICdjLCAnZCkgZm9ybWF0NlxudHlwZSAoJ2EsICdiLCAnYykgZm9ybWF0ID0gKCdhLCAnYiwgJ2MsICdjKSBmb3JtYXQ0XG5sZXQgc3RyaW5nX29mX2Zvcm1hdCA9IHN0cmluZ19vZl9mb3JtYXRcbmV4dGVybmFsIGZvcm1hdF9vZl9zdHJpbmcgOlxuICAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm9ybWF0NiAtPlxuICAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm9ybWF0NiA9IFwiJWlkZW50aXR5XCJcbmxldCAoIF5eICkgPSAoIF5eIClcbmxldCBleGl0ID0gZXhpdFxubGV0IGF0X2V4aXQgPSBhdF9leGl0XG5sZXQgdmFsaWRfZmxvYXRfbGV4ZW0gPSB2YWxpZF9mbG9hdF9sZXhlbVxubGV0IGRvX2F0X2V4aXQgPSBkb19hdF9leGl0XG4iLCIoKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9DYW1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgU2ltb24gQ3J1YW5lcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIENvcHlyaWdodCAyMDE3IEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgICAgICopXG4oKiAgICAgZW4gQXV0b21hdGlxdWUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIEFsbCByaWdodHMgcmVzZXJ2ZWQuICBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mICAgICopXG4oKiAgIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyLjEsIHdpdGggdGhlICAgICAgICAgICopXG4oKiAgIHNwZWNpYWwgZXhjZXB0aW9uIG9uIGxpbmtpbmcgZGVzY3JpYmVkIGluIHRoZSBmaWxlIExJQ0VOU0UuICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG5cbigqIE1vZHVsZSBbU2VxXTogZnVuY3Rpb25hbCBpdGVyYXRvcnMgKilcblxudHlwZSArJ2Egbm9kZSA9XG4gIHwgTmlsXG4gIHwgQ29ucyBvZiAnYSAqICdhIHRcblxuYW5kICdhIHQgPSB1bml0IC0+ICdhIG5vZGVcblxubGV0IGVtcHR5ICgpID0gTmlsXG5cbmxldCByZXR1cm4geCAoKSA9IENvbnMgKHgsIGVtcHR5KVxuXG5sZXQgY29ucyB4IG5leHQgKCkgPSBDb25zICh4LCBuZXh0KVxuXG5sZXQgcmVjIGFwcGVuZCBzZXExIHNlcTIgKCkgPVxuICBtYXRjaCBzZXExKCkgd2l0aFxuICB8IE5pbCAtPiBzZXEyKClcbiAgfCBDb25zICh4LCBuZXh0KSAtPiBDb25zICh4LCBhcHBlbmQgbmV4dCBzZXEyKVxuXG5sZXQgcmVjIG1hcCBmIHNlcSAoKSA9IG1hdGNoIHNlcSgpIHdpdGhcbiAgfCBOaWwgLT4gTmlsXG4gIHwgQ29ucyAoeCwgbmV4dCkgLT4gQ29ucyAoZiB4LCBtYXAgZiBuZXh0KVxuXG5sZXQgcmVjIGZpbHRlcl9tYXAgZiBzZXEgKCkgPSBtYXRjaCBzZXEoKSB3aXRoXG4gIHwgTmlsIC0+IE5pbFxuICB8IENvbnMgKHgsIG5leHQpIC0+XG4gICAgICBtYXRjaCBmIHggd2l0aFxuICAgICAgICB8IE5vbmUgLT4gZmlsdGVyX21hcCBmIG5leHQgKClcbiAgICAgICAgfCBTb21lIHkgLT4gQ29ucyAoeSwgZmlsdGVyX21hcCBmIG5leHQpXG5cbmxldCByZWMgZmlsdGVyIGYgc2VxICgpID0gbWF0Y2ggc2VxKCkgd2l0aFxuICB8IE5pbCAtPiBOaWxcbiAgfCBDb25zICh4LCBuZXh0KSAtPlxuICAgICAgaWYgZiB4XG4gICAgICB0aGVuIENvbnMgKHgsIGZpbHRlciBmIG5leHQpXG4gICAgICBlbHNlIGZpbHRlciBmIG5leHQgKClcblxubGV0IHJlYyBjb25jYXQgc2VxICgpID0gbWF0Y2ggc2VxICgpIHdpdGhcbiAgfCBOaWwgLT4gTmlsXG4gIHwgQ29ucyAoeCwgbmV4dCkgLT5cbiAgICAgYXBwZW5kIHggKGNvbmNhdCBuZXh0KSAoKVxuXG5sZXQgcmVjIGZsYXRfbWFwIGYgc2VxICgpID0gbWF0Y2ggc2VxICgpIHdpdGhcbiAgfCBOaWwgLT4gTmlsXG4gIHwgQ29ucyAoeCwgbmV4dCkgLT5cbiAgICBhcHBlbmQgKGYgeCkgKGZsYXRfbWFwIGYgbmV4dCkgKClcblxubGV0IGNvbmNhdF9tYXAgPSBmbGF0X21hcFxuXG5sZXQgZm9sZF9sZWZ0IGYgYWNjIHNlcSA9XG4gIGxldCByZWMgYXV4IGYgYWNjIHNlcSA9IG1hdGNoIHNlcSAoKSB3aXRoXG4gICAgfCBOaWwgLT4gYWNjXG4gICAgfCBDb25zICh4LCBuZXh0KSAtPlxuICAgICAgICBsZXQgYWNjID0gZiBhY2MgeCBpblxuICAgICAgICBhdXggZiBhY2MgbmV4dFxuICBpblxuICBhdXggZiBhY2Mgc2VxXG5cbmxldCBpdGVyIGYgc2VxID1cbiAgbGV0IHJlYyBhdXggc2VxID0gbWF0Y2ggc2VxICgpIHdpdGhcbiAgICB8IE5pbCAtPiAoKVxuICAgIHwgQ29ucyAoeCwgbmV4dCkgLT5cbiAgICAgICAgZiB4O1xuICAgICAgICBhdXggbmV4dFxuICBpblxuICBhdXggc2VxXG5cbmxldCByZWMgdW5mb2xkIGYgdSAoKSA9XG4gIG1hdGNoIGYgdSB3aXRoXG4gIHwgTm9uZSAtPiBOaWxcbiAgfCBTb21lICh4LCB1JykgLT4gQ29ucyAoeCwgdW5mb2xkIGYgdScpXG4iLCIoKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9DYW1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICBUaGUgT0NhbWwgcHJvZ3JhbW1lcnMgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIENvcHlyaWdodCAyMDE4IEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgICAgICopXG4oKiAgICAgZW4gQXV0b21hdGlxdWUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIEFsbCByaWdodHMgcmVzZXJ2ZWQuICBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mICAgICopXG4oKiAgIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyLjEsIHdpdGggdGhlICAgICAgICAgICopXG4oKiAgIHNwZWNpYWwgZXhjZXB0aW9uIG9uIGxpbmtpbmcgZGVzY3JpYmVkIGluIHRoZSBmaWxlIExJQ0VOU0UuICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG5cbnR5cGUgJ2EgdCA9ICdhIG9wdGlvbiA9IE5vbmUgfCBTb21lIG9mICdhXG5cbmxldCBub25lID0gTm9uZVxubGV0IHNvbWUgdiA9IFNvbWUgdlxubGV0IHZhbHVlIG8gfmRlZmF1bHQgPSBtYXRjaCBvIHdpdGggU29tZSB2IC0+IHYgfCBOb25lIC0+IGRlZmF1bHRcbmxldCBnZXQgPSBmdW5jdGlvbiBTb21lIHYgLT4gdiB8IE5vbmUgLT4gaW52YWxpZF9hcmcgXCJvcHRpb24gaXMgTm9uZVwiXG5sZXQgYmluZCBvIGYgPSBtYXRjaCBvIHdpdGggTm9uZSAtPiBOb25lIHwgU29tZSB2IC0+IGYgdlxubGV0IGpvaW4gPSBmdW5jdGlvbiBTb21lIG8gLT4gbyB8IE5vbmUgLT4gTm9uZVxubGV0IG1hcCBmIG8gPSBtYXRjaCBvIHdpdGggTm9uZSAtPiBOb25lIHwgU29tZSB2IC0+IFNvbWUgKGYgdilcbmxldCBmb2xkIH5ub25lIH5zb21lID0gZnVuY3Rpb24gU29tZSB2IC0+IHNvbWUgdiB8IE5vbmUgLT4gbm9uZVxubGV0IGl0ZXIgZiA9IGZ1bmN0aW9uIFNvbWUgdiAtPiBmIHYgfCBOb25lIC0+ICgpXG5sZXQgaXNfbm9uZSA9IGZ1bmN0aW9uIE5vbmUgLT4gdHJ1ZSB8IFNvbWUgXyAtPiBmYWxzZVxubGV0IGlzX3NvbWUgPSBmdW5jdGlvbiBOb25lIC0+IGZhbHNlIHwgU29tZSBfIC0+IHRydWVcblxubGV0IGVxdWFsIGVxIG8wIG8xID0gbWF0Y2ggbzAsIG8xIHdpdGhcbnwgU29tZSB2MCwgU29tZSB2MSAtPiBlcSB2MCB2MVxufCBOb25lLCBOb25lIC0+IHRydWVcbnwgXyAtPiBmYWxzZVxuXG5sZXQgY29tcGFyZSBjbXAgbzAgbzEgPSBtYXRjaCBvMCwgbzEgd2l0aFxufCBTb21lIHYwLCBTb21lIHYxIC0+IGNtcCB2MCB2MVxufCBOb25lLCBOb25lIC0+IDBcbnwgTm9uZSwgU29tZSBfIC0+IC0xXG58IFNvbWUgXywgTm9uZSAtPiAxXG5cbmxldCB0b19yZXN1bHQgfm5vbmUgPSBmdW5jdGlvbiBOb25lIC0+IEVycm9yIG5vbmUgfCBTb21lIHYgLT4gT2sgdlxubGV0IHRvX2xpc3QgPSBmdW5jdGlvbiBOb25lIC0+IFtdIHwgU29tZSB2IC0+IFt2XVxubGV0IHRvX3NlcSA9IGZ1bmN0aW9uIE5vbmUgLT4gU2VxLmVtcHR5IHwgU29tZSB2IC0+IFNlcS5yZXR1cm4gdlxuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICBHYWJyaWVsIFNjaGVyZXIsIHByb2pldCBQYXJzaWZhbCwgSU5SSUEgU2FjbGF5ICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMjAxOSBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0ICAgICAqKVxuKCogICAgIGVuIEF1dG9tYXRpcXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG50eXBlICgnYSwgJ2IpIHQgPSBMZWZ0IG9mICdhIHwgUmlnaHQgb2YgJ2JcblxubGV0IGxlZnQgdiA9IExlZnQgdlxubGV0IHJpZ2h0IHYgPSBSaWdodCB2XG5cbmxldCBpc19sZWZ0ID0gZnVuY3Rpb25cbnwgTGVmdCBfIC0+IHRydWVcbnwgUmlnaHQgXyAtPiBmYWxzZVxuXG5sZXQgaXNfcmlnaHQgPSBmdW5jdGlvblxufCBMZWZ0IF8gLT4gZmFsc2VcbnwgUmlnaHQgXyAtPiB0cnVlXG5cbmxldCBmaW5kX2xlZnQgPSBmdW5jdGlvblxufCBMZWZ0IHYgLT4gU29tZSB2XG58IFJpZ2h0IF8gLT4gTm9uZVxuXG5sZXQgZmluZF9yaWdodCA9IGZ1bmN0aW9uXG58IExlZnQgXyAtPiBOb25lXG58IFJpZ2h0IHYgLT4gU29tZSB2XG5cbmxldCBtYXBfbGVmdCBmID0gZnVuY3Rpb25cbnwgTGVmdCB2IC0+IExlZnQgKGYgdilcbnwgUmlnaHQgXyBhcyBlIC0+IGVcblxubGV0IG1hcF9yaWdodCBmID0gZnVuY3Rpb25cbnwgTGVmdCBfIGFzIGUgLT4gZVxufCBSaWdodCB2IC0+IFJpZ2h0IChmIHYpXG5cbmxldCBtYXAgfmxlZnQgfnJpZ2h0ID0gZnVuY3Rpb25cbnwgTGVmdCB2IC0+IExlZnQgKGxlZnQgdilcbnwgUmlnaHQgdiAtPiBSaWdodCAocmlnaHQgdilcblxubGV0IGZvbGQgfmxlZnQgfnJpZ2h0ID0gZnVuY3Rpb25cbnwgTGVmdCB2IC0+IGxlZnQgdlxufCBSaWdodCB2IC0+IHJpZ2h0IHZcblxubGV0IGl0ZXIgPSBmb2xkXG5cbmxldCBmb3JfYWxsID0gZm9sZFxuXG5sZXQgZXF1YWwgfmxlZnQgfnJpZ2h0IGUxIGUyID0gbWF0Y2ggZTEsIGUyIHdpdGhcbnwgTGVmdCB2MSwgTGVmdCB2MiAtPiBsZWZ0IHYxIHYyXG58IFJpZ2h0IHYxLCBSaWdodCB2MiAtPiByaWdodCB2MSB2MlxufCBMZWZ0IF8sIFJpZ2h0IF8gfCBSaWdodCBfLCBMZWZ0IF8gLT4gZmFsc2VcblxubGV0IGNvbXBhcmUgfmxlZnQgfnJpZ2h0IGUxIGUyID0gbWF0Y2ggZTEsIGUyIHdpdGhcbnwgTGVmdCB2MSwgTGVmdCB2MiAtPiBsZWZ0IHYxIHYyXG58IFJpZ2h0IHYxLCBSaWdodCB2MiAtPiByaWdodCB2MSB2MlxufCBMZWZ0IF8sIFJpZ2h0IF8gLT4gKC0xKVxufCBSaWdodCBfLCBMZWZ0IF8gLT4gMVxuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgVGhlIE9DYW1sIHByb2dyYW1tZXJzICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMjAxOCBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0ICAgICAqKVxuKCogICAgIGVuIEF1dG9tYXRpcXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG50eXBlICgnYSwgJ2UpIHQgPSAoJ2EsICdlKSByZXN1bHQgPSBPayBvZiAnYSB8IEVycm9yIG9mICdlXG5cbmxldCBvayB2ID0gT2sgdlxubGV0IGVycm9yIGUgPSBFcnJvciBlXG5sZXQgdmFsdWUgciB+ZGVmYXVsdCA9IG1hdGNoIHIgd2l0aCBPayB2IC0+IHYgfCBFcnJvciBfIC0+IGRlZmF1bHRcbmxldCBnZXRfb2sgPSBmdW5jdGlvbiBPayB2IC0+IHYgfCBFcnJvciBfIC0+IGludmFsaWRfYXJnIFwicmVzdWx0IGlzIEVycm9yIF9cIlxubGV0IGdldF9lcnJvciA9IGZ1bmN0aW9uIEVycm9yIGUgLT4gZSB8IE9rIF8gLT4gaW52YWxpZF9hcmcgXCJyZXN1bHQgaXMgT2sgX1wiXG5sZXQgYmluZCByIGYgPSBtYXRjaCByIHdpdGggT2sgdiAtPiBmIHYgfCBFcnJvciBfIGFzIGUgLT4gZVxubGV0IGpvaW4gPSBmdW5jdGlvbiBPayByIC0+IHIgfCBFcnJvciBfIGFzIGUgLT4gZVxubGV0IG1hcCBmID0gZnVuY3Rpb24gT2sgdiAtPiBPayAoZiB2KSB8IEVycm9yIF8gYXMgZSAtPiBlXG5sZXQgbWFwX2Vycm9yIGYgPSBmdW5jdGlvbiBFcnJvciBlIC0+IEVycm9yIChmIGUpIHwgT2sgXyBhcyB2IC0+IHZcbmxldCBmb2xkIH5vayB+ZXJyb3IgPSBmdW5jdGlvbiBPayB2IC0+IG9rIHYgfCBFcnJvciBlIC0+IGVycm9yIGVcbmxldCBpdGVyIGYgPSBmdW5jdGlvbiBPayB2IC0+IGYgdiB8IEVycm9yIF8gLT4gKClcbmxldCBpdGVyX2Vycm9yIGYgPSBmdW5jdGlvbiBFcnJvciBlIC0+IGYgZSB8IE9rIF8gLT4gKClcbmxldCBpc19vayA9IGZ1bmN0aW9uIE9rIF8gLT4gdHJ1ZSB8IEVycm9yIF8gLT4gZmFsc2VcbmxldCBpc19lcnJvciA9IGZ1bmN0aW9uIEVycm9yIF8gLT4gdHJ1ZSB8IE9rIF8gLT4gZmFsc2VcblxubGV0IGVxdWFsIH5vayB+ZXJyb3IgcjAgcjEgPSBtYXRjaCByMCwgcjEgd2l0aFxufCBPayB2MCwgT2sgdjEgLT4gb2sgdjAgdjFcbnwgRXJyb3IgZTAsIEVycm9yIGUxIC0+IGVycm9yIGUwIGUxXG58IF8sIF8gLT4gZmFsc2VcblxubGV0IGNvbXBhcmUgfm9rIH5lcnJvciByMCByMSA9IG1hdGNoIHIwLCByMSB3aXRoXG58IE9rIHYwLCBPayB2MSAtPiBvayB2MCB2MVxufCBFcnJvciBlMCwgRXJyb3IgZTEgLT4gZXJyb3IgZTAgZTFcbnwgT2sgXywgRXJyb3IgXyAtPiAtMVxufCBFcnJvciBfLCBPayBfIC0+IDFcblxubGV0IHRvX29wdGlvbiA9IGZ1bmN0aW9uIE9rIHYgLT4gU29tZSB2IHwgRXJyb3IgXyAtPiBOb25lXG5sZXQgdG9fbGlzdCA9IGZ1bmN0aW9uIE9rIHYgLT4gW3ZdIHwgRXJyb3IgXyAtPiBbXVxubGV0IHRvX3NlcSA9IGZ1bmN0aW9uIE9rIHYgLT4gU2VxLnJldHVybiB2IHwgRXJyb3IgXyAtPiBTZXEuZW1wdHlcbiIsIigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0NhbWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgIFRoZSBPQ2FtbCBwcm9ncmFtbWVycyAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQ29weXJpZ2h0IDIwMTggSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCAgICAgKilcbigqICAgICBlbiBBdXRvbWF0aXF1ZS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQWxsIHJpZ2h0cyByZXNlcnZlZC4gIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgICAgKilcbigqICAgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIuMSwgd2l0aCB0aGUgICAgICAgICAgKilcbigqICAgc3BlY2lhbCBleGNlcHRpb24gb24gbGlua2luZyBkZXNjcmliZWQgaW4gdGhlIGZpbGUgTElDRU5TRS4gICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcblxudHlwZSB0ID0gYm9vbCA9IGZhbHNlIHwgdHJ1ZVxuXG5leHRlcm5hbCBub3QgOiBib29sIC0+IGJvb2wgPSBcIiVib29sbm90XCJcbmV4dGVybmFsICggJiYgKSA6IGJvb2wgLT4gYm9vbCAtPiBib29sID0gXCIlc2VxdWFuZFwiXG5leHRlcm5hbCAoIHx8ICkgOiBib29sIC0+IGJvb2wgLT4gYm9vbCA9IFwiJXNlcXVvclwiXG5sZXQgZXF1YWwgOiBib29sIC0+IGJvb2wgLT4gYm9vbCA9ICggPSApXG5sZXQgY29tcGFyZSA6IGJvb2wgLT4gYm9vbCAtPiBpbnQgPSBTdGRsaWIuY29tcGFyZVxuZXh0ZXJuYWwgdG9faW50IDogYm9vbCAtPiBpbnQgPSBcIiVpZGVudGl0eVwiXG5sZXQgdG9fZmxvYXQgPSBmdW5jdGlvbiBmYWxzZSAtPiAwLiB8IHRydWUgLT4gMS5cblxuKCpcbmxldCBvZl9zdHJpbmcgPSBmdW5jdGlvblxufCBcImZhbHNlXCIgLT4gU29tZSBmYWxzZVxufCBcInRydWVcIiAtPiBTb21lIHRydWVcbnwgXyAtPiBOb25lXG4qKVxuXG5sZXQgdG9fc3RyaW5nID0gZnVuY3Rpb24gZmFsc2UgLT4gXCJmYWxzZVwiIHwgdHJ1ZSAtPiBcInRydWVcIlxuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgWGF2aWVyIExlcm95LCBwcm9qZXQgQ3Jpc3RhbCwgSU5SSUEgUm9jcXVlbmNvdXJ0ICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMTk5NiBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0ICAgICAqKVxuKCogICAgIGVuIEF1dG9tYXRpcXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG4oKiBDaGFyYWN0ZXIgb3BlcmF0aW9ucyAqKVxuXG5leHRlcm5hbCBjb2RlOiBjaGFyIC0+IGludCA9IFwiJWlkZW50aXR5XCJcbmV4dGVybmFsIHVuc2FmZV9jaHI6IGludCAtPiBjaGFyID0gXCIlaWRlbnRpdHlcIlxuXG5sZXQgY2hyIG4gPVxuICBpZiBuIDwgMCB8fCBuID4gMjU1IHRoZW4gaW52YWxpZF9hcmcgXCJDaGFyLmNoclwiIGVsc2UgdW5zYWZlX2NociBuXG5cbmV4dGVybmFsIGJ5dGVzX2NyZWF0ZTogaW50IC0+IGJ5dGVzID0gXCJjYW1sX2NyZWF0ZV9ieXRlc1wiXG5leHRlcm5hbCBieXRlc191bnNhZmVfc2V0IDogYnl0ZXMgLT4gaW50IC0+IGNoYXIgLT4gdW5pdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBcIiVieXRlc191bnNhZmVfc2V0XCJcbmV4dGVybmFsIHVuc2FmZV90b19zdHJpbmcgOiBieXRlcyAtPiBzdHJpbmcgPSBcIiVieXRlc190b19zdHJpbmdcIlxuXG5sZXQgZXNjYXBlZCA9IGZ1bmN0aW9uXG4gIHwgJ1xcJycgLT4gXCJcXFxcJ1wiXG4gIHwgJ1xcXFwnIC0+IFwiXFxcXFxcXFxcIlxuICB8ICdcXG4nIC0+IFwiXFxcXG5cIlxuICB8ICdcXHQnIC0+IFwiXFxcXHRcIlxuICB8ICdcXHInIC0+IFwiXFxcXHJcIlxuICB8ICdcXGInIC0+IFwiXFxcXGJcIlxuICB8ICcgJyAuLiAnficgYXMgYyAtPlxuICAgICAgbGV0IHMgPSBieXRlc19jcmVhdGUgMSBpblxuICAgICAgYnl0ZXNfdW5zYWZlX3NldCBzIDAgYztcbiAgICAgIHVuc2FmZV90b19zdHJpbmcgc1xuICB8IGMgLT5cbiAgICAgIGxldCBuID0gY29kZSBjIGluXG4gICAgICBsZXQgcyA9IGJ5dGVzX2NyZWF0ZSA0IGluXG4gICAgICBieXRlc191bnNhZmVfc2V0IHMgMCAnXFxcXCc7XG4gICAgICBieXRlc191bnNhZmVfc2V0IHMgMSAodW5zYWZlX2NociAoNDggKyBuIC8gMTAwKSk7XG4gICAgICBieXRlc191bnNhZmVfc2V0IHMgMiAodW5zYWZlX2NociAoNDggKyAobiAvIDEwKSBtb2QgMTApKTtcbiAgICAgIGJ5dGVzX3Vuc2FmZV9zZXQgcyAzICh1bnNhZmVfY2hyICg0OCArIG4gbW9kIDEwKSk7XG4gICAgICB1bnNhZmVfdG9fc3RyaW5nIHNcblxubGV0IGxvd2VyY2FzZSA9IGZ1bmN0aW9uXG4gIHwgJ0EnIC4uICdaJ1xuICB8ICdcXDE5MicgLi4gJ1xcMjE0J1xuICB8ICdcXDIxNicgLi4gJ1xcMjIyJyBhcyBjIC0+XG4gICAgdW5zYWZlX2Nocihjb2RlIGMgKyAzMilcbiAgfCBjIC0+IGNcblxubGV0IHVwcGVyY2FzZSA9IGZ1bmN0aW9uXG4gIHwgJ2EnIC4uICd6J1xuICB8ICdcXDIyNCcgLi4gJ1xcMjQ2J1xuICB8ICdcXDI0OCcgLi4gJ1xcMjU0JyBhcyBjIC0+XG4gICAgdW5zYWZlX2Nocihjb2RlIGMgLSAzMilcbiAgfCBjIC0+IGNcblxubGV0IGxvd2VyY2FzZV9hc2NpaSA9IGZ1bmN0aW9uXG4gIHwgJ0EnIC4uICdaJyBhcyBjIC0+IHVuc2FmZV9jaHIoY29kZSBjICsgMzIpXG4gIHwgYyAtPiBjXG5cbmxldCB1cHBlcmNhc2VfYXNjaWkgPSBmdW5jdGlvblxuICB8ICdhJyAuLiAneicgYXMgYyAtPiB1bnNhZmVfY2hyKGNvZGUgYyAtIDMyKVxuICB8IGMgLT4gY1xuXG50eXBlIHQgPSBjaGFyXG5cbmxldCBjb21wYXJlIGMxIGMyID0gY29kZSBjMSAtIGNvZGUgYzJcbmxldCBlcXVhbCAoYzE6IHQpIChjMjogdCkgPSBjb21wYXJlIGMxIGMyID0gMFxuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICBEYW5pZWwgQy4gQnVlbnpsaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMjAxNCBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0ICAgICAqKVxuKCogICAgIGVuIEF1dG9tYXRpcXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG5leHRlcm5hbCBmb3JtYXRfaW50IDogc3RyaW5nIC0+IGludCAtPiBzdHJpbmcgPSBcImNhbWxfZm9ybWF0X2ludFwiXG5cbmxldCBlcnJfbm9fcHJlZCA9IFwiVSswMDAwIGhhcyBubyBwcmVkZWNlc3NvclwiXG5sZXQgZXJyX25vX3N1Y2MgPSBcIlUrMTBGRkZGIGhhcyBubyBzdWNjZXNzb3JcIlxubGV0IGVycl9ub3Rfc3YgaSA9IGZvcm1hdF9pbnQgXCIlWFwiIGkgXiBcIiBpcyBub3QgYW4gVW5pY29kZSBzY2FsYXIgdmFsdWVcIlxubGV0IGVycl9ub3RfbGF0aW4xIHUgPSBcIlUrXCIgXiBmb3JtYXRfaW50IFwiJTA0WFwiIHUgXiBcIiBpcyBub3QgYSBsYXRpbjEgY2hhcmFjdGVyXCJcblxudHlwZSB0ID0gaW50XG5cbmxldCBtaW4gPSAweDAwMDBcbmxldCBtYXggPSAweDEwRkZGRlxubGV0IGxvX2JvdW5kID0gMHhEN0ZGXG5sZXQgaGlfYm91bmQgPSAweEUwMDBcblxubGV0IGJvbSA9IDB4RkVGRlxubGV0IHJlcCA9IDB4RkZGRFxuXG5sZXQgc3VjYyB1ID1cbiAgaWYgdSA9IGxvX2JvdW5kIHRoZW4gaGlfYm91bmQgZWxzZVxuICBpZiB1ID0gbWF4IHRoZW4gaW52YWxpZF9hcmcgZXJyX25vX3N1Y2MgZWxzZVxuICB1ICsgMVxuXG5sZXQgcHJlZCB1ID1cbiAgaWYgdSA9IGhpX2JvdW5kIHRoZW4gbG9fYm91bmQgZWxzZVxuICBpZiB1ID0gbWluIHRoZW4gaW52YWxpZF9hcmcgZXJyX25vX3ByZWQgZWxzZVxuICB1IC0gMVxuXG5sZXQgaXNfdmFsaWQgaSA9IChtaW4gPD0gaSAmJiBpIDw9IGxvX2JvdW5kKSB8fCAoaGlfYm91bmQgPD0gaSAmJiBpIDw9IG1heClcbmxldCBvZl9pbnQgaSA9IGlmIGlzX3ZhbGlkIGkgdGhlbiBpIGVsc2UgaW52YWxpZF9hcmcgKGVycl9ub3Rfc3YgaSlcbmV4dGVybmFsIHVuc2FmZV9vZl9pbnQgOiBpbnQgLT4gdCA9IFwiJWlkZW50aXR5XCJcbmV4dGVybmFsIHRvX2ludCA6IHQgLT4gaW50ID0gXCIlaWRlbnRpdHlcIlxuXG5sZXQgaXNfY2hhciB1ID0gdSA8IDI1NlxubGV0IG9mX2NoYXIgYyA9IENoYXIuY29kZSBjXG5sZXQgdG9fY2hhciB1ID1cbiAgaWYgdSA+IDI1NSB0aGVuIGludmFsaWRfYXJnIChlcnJfbm90X2xhdGluMSB1KSBlbHNlXG4gIENoYXIudW5zYWZlX2NociB1XG5cbmxldCB1bnNhZmVfdG9fY2hhciA9IENoYXIudW5zYWZlX2NoclxuXG5sZXQgZXF1YWwgOiBpbnQgLT4gaW50IC0+IGJvb2wgPSAoID0gKVxubGV0IGNvbXBhcmUgOiBpbnQgLT4gaW50IC0+IGludCA9IFN0ZGxpYi5jb21wYXJlXG5sZXQgaGFzaCA9IHRvX2ludFxuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgWGF2aWVyIExlcm95LCBwcm9qZXQgQ3Jpc3RhbCwgSU5SSUEgUm9jcXVlbmNvdXJ0ICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMTk5NiBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0ICAgICAqKVxuKCogICAgIGVuIEF1dG9tYXRpcXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG4oKiBBbiBhbGlhcyBmb3IgdGhlIHR5cGUgb2YgbGlzdHMuICopXG50eXBlICdhIHQgPSAnYSBsaXN0ID0gW10gfCAoOjopIG9mICdhICogJ2EgbGlzdFxuXG4oKiBMaXN0IG9wZXJhdGlvbnMgKilcblxubGV0IHJlYyBsZW5ndGhfYXV4IGxlbiA9IGZ1bmN0aW9uXG4gICAgW10gLT4gbGVuXG4gIHwgXzo6bCAtPiBsZW5ndGhfYXV4IChsZW4gKyAxKSBsXG5cbmxldCBsZW5ndGggbCA9IGxlbmd0aF9hdXggMCBsXG5cbmxldCBjb25zIGEgbCA9IGE6OmxcblxubGV0IGhkID0gZnVuY3Rpb25cbiAgICBbXSAtPiBmYWlsd2l0aCBcImhkXCJcbiAgfCBhOjpfIC0+IGFcblxubGV0IHRsID0gZnVuY3Rpb25cbiAgICBbXSAtPiBmYWlsd2l0aCBcInRsXCJcbiAgfCBfOjpsIC0+IGxcblxubGV0IG50aCBsIG4gPVxuICBpZiBuIDwgMCB0aGVuIGludmFsaWRfYXJnIFwiTGlzdC5udGhcIiBlbHNlXG4gIGxldCByZWMgbnRoX2F1eCBsIG4gPVxuICAgIG1hdGNoIGwgd2l0aFxuICAgIHwgW10gLT4gZmFpbHdpdGggXCJudGhcIlxuICAgIHwgYTo6bCAtPiBpZiBuID0gMCB0aGVuIGEgZWxzZSBudGhfYXV4IGwgKG4tMSlcbiAgaW4gbnRoX2F1eCBsIG5cblxubGV0IG50aF9vcHQgbCBuID1cbiAgaWYgbiA8IDAgdGhlbiBpbnZhbGlkX2FyZyBcIkxpc3QubnRoXCIgZWxzZVxuICBsZXQgcmVjIG50aF9hdXggbCBuID1cbiAgICBtYXRjaCBsIHdpdGhcbiAgICB8IFtdIC0+IE5vbmVcbiAgICB8IGE6OmwgLT4gaWYgbiA9IDAgdGhlbiBTb21lIGEgZWxzZSBudGhfYXV4IGwgKG4tMSlcbiAgaW4gbnRoX2F1eCBsIG5cblxubGV0IGFwcGVuZCA9IChAKVxuXG5sZXQgcmVjIHJldl9hcHBlbmQgbDEgbDIgPVxuICBtYXRjaCBsMSB3aXRoXG4gICAgW10gLT4gbDJcbiAgfCBhIDo6IGwgLT4gcmV2X2FwcGVuZCBsIChhIDo6IGwyKVxuXG5sZXQgcmV2IGwgPSByZXZfYXBwZW5kIGwgW11cblxubGV0IHJlYyBpbml0X3RhaWxyZWNfYXV4IGFjYyBpIG4gZiA9XG4gIGlmIGkgPj0gbiB0aGVuIGFjY1xuICBlbHNlIGluaXRfdGFpbHJlY19hdXggKGYgaSA6OiBhY2MpIChpKzEpIG4gZlxuXG5sZXQgcmVjIGluaXRfYXV4IGkgbiBmID1cbiAgaWYgaSA+PSBuIHRoZW4gW11cbiAgZWxzZVxuICAgIGxldCByID0gZiBpIGluXG4gICAgciA6OiBpbml0X2F1eCAoaSsxKSBuIGZcblxubGV0IHJldl9pbml0X3RocmVzaG9sZCA9XG4gIG1hdGNoIFN5cy5iYWNrZW5kX3R5cGUgd2l0aFxuICB8IFN5cy5OYXRpdmUgfCBTeXMuQnl0ZWNvZGUgLT4gMTBfMDAwXG4gICgqIFdlIGRvbid0IGtub3cgdGhlIHNpemUgb2YgdGhlIHN0YWNrLCBiZXR0ZXIgYmUgc2FmZSBhbmQgYXNzdW1lIGl0J3NcbiAgICAgc21hbGwuICopXG4gIHwgU3lzLk90aGVyIF8gLT4gNTBcblxubGV0IGluaXQgbGVuIGYgPVxuICBpZiBsZW4gPCAwIHRoZW4gaW52YWxpZF9hcmcgXCJMaXN0LmluaXRcIiBlbHNlXG4gIGlmIGxlbiA+IHJldl9pbml0X3RocmVzaG9sZCB0aGVuIHJldiAoaW5pdF90YWlscmVjX2F1eCBbXSAwIGxlbiBmKVxuICBlbHNlIGluaXRfYXV4IDAgbGVuIGZcblxubGV0IHJlYyBmbGF0dGVuID0gZnVuY3Rpb25cbiAgICBbXSAtPiBbXVxuICB8IGw6OnIgLT4gbCBAIGZsYXR0ZW4gclxuXG5sZXQgY29uY2F0ID0gZmxhdHRlblxuXG5sZXQgcmVjIG1hcCBmID0gZnVuY3Rpb25cbiAgICBbXSAtPiBbXVxuICB8IGE6OmwgLT4gbGV0IHIgPSBmIGEgaW4gciA6OiBtYXAgZiBsXG5cbmxldCByZWMgbWFwaSBpIGYgPSBmdW5jdGlvblxuICAgIFtdIC0+IFtdXG4gIHwgYTo6bCAtPiBsZXQgciA9IGYgaSBhIGluIHIgOjogbWFwaSAoaSArIDEpIGYgbFxuXG5sZXQgbWFwaSBmIGwgPSBtYXBpIDAgZiBsXG5cbmxldCByZXZfbWFwIGYgbCA9XG4gIGxldCByZWMgcm1hcF9mIGFjY3UgPSBmdW5jdGlvblxuICAgIHwgW10gLT4gYWNjdVxuICAgIHwgYTo6bCAtPiBybWFwX2YgKGYgYSA6OiBhY2N1KSBsXG4gIGluXG4gIHJtYXBfZiBbXSBsXG5cblxubGV0IHJlYyBpdGVyIGYgPSBmdW5jdGlvblxuICAgIFtdIC0+ICgpXG4gIHwgYTo6bCAtPiBmIGE7IGl0ZXIgZiBsXG5cbmxldCByZWMgaXRlcmkgaSBmID0gZnVuY3Rpb25cbiAgICBbXSAtPiAoKVxuICB8IGE6OmwgLT4gZiBpIGE7IGl0ZXJpIChpICsgMSkgZiBsXG5cbmxldCBpdGVyaSBmIGwgPSBpdGVyaSAwIGYgbFxuXG5sZXQgcmVjIGZvbGRfbGVmdCBmIGFjY3UgbCA9XG4gIG1hdGNoIGwgd2l0aFxuICAgIFtdIC0+IGFjY3VcbiAgfCBhOjpsIC0+IGZvbGRfbGVmdCBmIChmIGFjY3UgYSkgbFxuXG5sZXQgcmVjIGZvbGRfcmlnaHQgZiBsIGFjY3UgPVxuICBtYXRjaCBsIHdpdGhcbiAgICBbXSAtPiBhY2N1XG4gIHwgYTo6bCAtPiBmIGEgKGZvbGRfcmlnaHQgZiBsIGFjY3UpXG5cbmxldCByZWMgbWFwMiBmIGwxIGwyID1cbiAgbWF0Y2ggKGwxLCBsMikgd2l0aFxuICAgIChbXSwgW10pIC0+IFtdXG4gIHwgKGExOjpsMSwgYTI6OmwyKSAtPiBsZXQgciA9IGYgYTEgYTIgaW4gciA6OiBtYXAyIGYgbDEgbDJcbiAgfCAoXywgXykgLT4gaW52YWxpZF9hcmcgXCJMaXN0Lm1hcDJcIlxuXG5sZXQgcmV2X21hcDIgZiBsMSBsMiA9XG4gIGxldCByZWMgcm1hcDJfZiBhY2N1IGwxIGwyID1cbiAgICBtYXRjaCAobDEsIGwyKSB3aXRoXG4gICAgfCAoW10sIFtdKSAtPiBhY2N1XG4gICAgfCAoYTE6OmwxLCBhMjo6bDIpIC0+IHJtYXAyX2YgKGYgYTEgYTIgOjogYWNjdSkgbDEgbDJcbiAgICB8IChfLCBfKSAtPiBpbnZhbGlkX2FyZyBcIkxpc3QucmV2X21hcDJcIlxuICBpblxuICBybWFwMl9mIFtdIGwxIGwyXG5cblxubGV0IHJlYyBpdGVyMiBmIGwxIGwyID1cbiAgbWF0Y2ggKGwxLCBsMikgd2l0aFxuICAgIChbXSwgW10pIC0+ICgpXG4gIHwgKGExOjpsMSwgYTI6OmwyKSAtPiBmIGExIGEyOyBpdGVyMiBmIGwxIGwyXG4gIHwgKF8sIF8pIC0+IGludmFsaWRfYXJnIFwiTGlzdC5pdGVyMlwiXG5cbmxldCByZWMgZm9sZF9sZWZ0MiBmIGFjY3UgbDEgbDIgPVxuICBtYXRjaCAobDEsIGwyKSB3aXRoXG4gICAgKFtdLCBbXSkgLT4gYWNjdVxuICB8IChhMTo6bDEsIGEyOjpsMikgLT4gZm9sZF9sZWZ0MiBmIChmIGFjY3UgYTEgYTIpIGwxIGwyXG4gIHwgKF8sIF8pIC0+IGludmFsaWRfYXJnIFwiTGlzdC5mb2xkX2xlZnQyXCJcblxubGV0IHJlYyBmb2xkX3JpZ2h0MiBmIGwxIGwyIGFjY3UgPVxuICBtYXRjaCAobDEsIGwyKSB3aXRoXG4gICAgKFtdLCBbXSkgLT4gYWNjdVxuICB8IChhMTo6bDEsIGEyOjpsMikgLT4gZiBhMSBhMiAoZm9sZF9yaWdodDIgZiBsMSBsMiBhY2N1KVxuICB8IChfLCBfKSAtPiBpbnZhbGlkX2FyZyBcIkxpc3QuZm9sZF9yaWdodDJcIlxuXG5sZXQgcmVjIGZvcl9hbGwgcCA9IGZ1bmN0aW9uXG4gICAgW10gLT4gdHJ1ZVxuICB8IGE6OmwgLT4gcCBhICYmIGZvcl9hbGwgcCBsXG5cbmxldCByZWMgZXhpc3RzIHAgPSBmdW5jdGlvblxuICAgIFtdIC0+IGZhbHNlXG4gIHwgYTo6bCAtPiBwIGEgfHwgZXhpc3RzIHAgbFxuXG5sZXQgcmVjIGZvcl9hbGwyIHAgbDEgbDIgPVxuICBtYXRjaCAobDEsIGwyKSB3aXRoXG4gICAgKFtdLCBbXSkgLT4gdHJ1ZVxuICB8IChhMTo6bDEsIGEyOjpsMikgLT4gcCBhMSBhMiAmJiBmb3JfYWxsMiBwIGwxIGwyXG4gIHwgKF8sIF8pIC0+IGludmFsaWRfYXJnIFwiTGlzdC5mb3JfYWxsMlwiXG5cbmxldCByZWMgZXhpc3RzMiBwIGwxIGwyID1cbiAgbWF0Y2ggKGwxLCBsMikgd2l0aFxuICAgIChbXSwgW10pIC0+IGZhbHNlXG4gIHwgKGExOjpsMSwgYTI6OmwyKSAtPiBwIGExIGEyIHx8IGV4aXN0czIgcCBsMSBsMlxuICB8IChfLCBfKSAtPiBpbnZhbGlkX2FyZyBcIkxpc3QuZXhpc3RzMlwiXG5cbmxldCByZWMgbWVtIHggPSBmdW5jdGlvblxuICAgIFtdIC0+IGZhbHNlXG4gIHwgYTo6bCAtPiBjb21wYXJlIGEgeCA9IDAgfHwgbWVtIHggbFxuXG5sZXQgcmVjIG1lbXEgeCA9IGZ1bmN0aW9uXG4gICAgW10gLT4gZmFsc2VcbiAgfCBhOjpsIC0+IGEgPT0geCB8fCBtZW1xIHggbFxuXG5sZXQgcmVjIGFzc29jIHggPSBmdW5jdGlvblxuICAgIFtdIC0+IHJhaXNlIE5vdF9mb3VuZFxuICB8IChhLGIpOjpsIC0+IGlmIGNvbXBhcmUgYSB4ID0gMCB0aGVuIGIgZWxzZSBhc3NvYyB4IGxcblxubGV0IHJlYyBhc3NvY19vcHQgeCA9IGZ1bmN0aW9uXG4gICAgW10gLT4gTm9uZVxuICB8IChhLGIpOjpsIC0+IGlmIGNvbXBhcmUgYSB4ID0gMCB0aGVuIFNvbWUgYiBlbHNlIGFzc29jX29wdCB4IGxcblxubGV0IHJlYyBhc3NxIHggPSBmdW5jdGlvblxuICAgIFtdIC0+IHJhaXNlIE5vdF9mb3VuZFxuICB8IChhLGIpOjpsIC0+IGlmIGEgPT0geCB0aGVuIGIgZWxzZSBhc3NxIHggbFxuXG5sZXQgcmVjIGFzc3Ffb3B0IHggPSBmdW5jdGlvblxuICAgIFtdIC0+IE5vbmVcbiAgfCAoYSxiKTo6bCAtPiBpZiBhID09IHggdGhlbiBTb21lIGIgZWxzZSBhc3NxX29wdCB4IGxcblxubGV0IHJlYyBtZW1fYXNzb2MgeCA9IGZ1bmN0aW9uXG4gIHwgW10gLT4gZmFsc2VcbiAgfCAoYSwgXykgOjogbCAtPiBjb21wYXJlIGEgeCA9IDAgfHwgbWVtX2Fzc29jIHggbFxuXG5sZXQgcmVjIG1lbV9hc3NxIHggPSBmdW5jdGlvblxuICB8IFtdIC0+IGZhbHNlXG4gIHwgKGEsIF8pIDo6IGwgLT4gYSA9PSB4IHx8IG1lbV9hc3NxIHggbFxuXG5sZXQgcmVjIHJlbW92ZV9hc3NvYyB4ID0gZnVuY3Rpb25cbiAgfCBbXSAtPiBbXVxuICB8IChhLCBfIGFzIHBhaXIpIDo6IGwgLT5cbiAgICAgIGlmIGNvbXBhcmUgYSB4ID0gMCB0aGVuIGwgZWxzZSBwYWlyIDo6IHJlbW92ZV9hc3NvYyB4IGxcblxubGV0IHJlYyByZW1vdmVfYXNzcSB4ID0gZnVuY3Rpb25cbiAgfCBbXSAtPiBbXVxuICB8IChhLCBfIGFzIHBhaXIpIDo6IGwgLT4gaWYgYSA9PSB4IHRoZW4gbCBlbHNlIHBhaXIgOjogcmVtb3ZlX2Fzc3EgeCBsXG5cbmxldCByZWMgZmluZCBwID0gZnVuY3Rpb25cbiAgfCBbXSAtPiByYWlzZSBOb3RfZm91bmRcbiAgfCB4IDo6IGwgLT4gaWYgcCB4IHRoZW4geCBlbHNlIGZpbmQgcCBsXG5cbmxldCByZWMgZmluZF9vcHQgcCA9IGZ1bmN0aW9uXG4gIHwgW10gLT4gTm9uZVxuICB8IHggOjogbCAtPiBpZiBwIHggdGhlbiBTb21lIHggZWxzZSBmaW5kX29wdCBwIGxcblxubGV0IHJlYyBmaW5kX21hcCBmID0gZnVuY3Rpb25cbiAgfCBbXSAtPiBOb25lXG4gIHwgeCA6OiBsIC0+XG4gICAgIGJlZ2luIG1hdGNoIGYgeCB3aXRoXG4gICAgICAgfCBTb21lIF8gYXMgcmVzdWx0IC0+IHJlc3VsdFxuICAgICAgIHwgTm9uZSAtPiBmaW5kX21hcCBmIGxcbiAgICAgZW5kXG5cbmxldCBmaW5kX2FsbCBwID1cbiAgbGV0IHJlYyBmaW5kIGFjY3UgPSBmdW5jdGlvblxuICB8IFtdIC0+IHJldiBhY2N1XG4gIHwgeCA6OiBsIC0+IGlmIHAgeCB0aGVuIGZpbmQgKHggOjogYWNjdSkgbCBlbHNlIGZpbmQgYWNjdSBsIGluXG4gIGZpbmQgW11cblxubGV0IGZpbHRlciA9IGZpbmRfYWxsXG5cbmxldCBmaWx0ZXJpIHAgbCA9XG4gIGxldCByZWMgYXV4IGkgYWNjID0gZnVuY3Rpb25cbiAgfCBbXSAtPiByZXYgYWNjXG4gIHwgeDo6bCAtPiBhdXggKGkgKyAxKSAoaWYgcCBpIHggdGhlbiB4OjphY2MgZWxzZSBhY2MpIGxcbiAgaW5cbiAgYXV4IDAgW10gbFxuXG5sZXQgZmlsdGVyX21hcCBmID1cbiAgbGV0IHJlYyBhdXggYWNjdSA9IGZ1bmN0aW9uXG4gICAgfCBbXSAtPiByZXYgYWNjdVxuICAgIHwgeCA6OiBsIC0+XG4gICAgICAgIG1hdGNoIGYgeCB3aXRoXG4gICAgICAgIHwgTm9uZSAtPiBhdXggYWNjdSBsXG4gICAgICAgIHwgU29tZSB2IC0+IGF1eCAodiA6OiBhY2N1KSBsXG4gIGluXG4gIGF1eCBbXVxuXG5sZXQgY29uY2F0X21hcCBmIGwgPVxuICBsZXQgcmVjIGF1eCBmIGFjYyA9IGZ1bmN0aW9uXG4gICAgfCBbXSAtPiByZXYgYWNjXG4gICAgfCB4IDo6IGwgLT5cbiAgICAgICBsZXQgeHMgPSBmIHggaW5cbiAgICAgICBhdXggZiAocmV2X2FwcGVuZCB4cyBhY2MpIGxcbiAgaW4gYXV4IGYgW10gbFxuXG5sZXQgZm9sZF9sZWZ0X21hcCBmIGFjY3UgbCA9XG4gIGxldCByZWMgYXV4IGFjY3UgbF9hY2N1ID0gZnVuY3Rpb25cbiAgICB8IFtdIC0+IGFjY3UsIHJldiBsX2FjY3VcbiAgICB8IHggOjogbCAtPlxuICAgICAgICBsZXQgYWNjdSwgeCA9IGYgYWNjdSB4IGluXG4gICAgICAgIGF1eCBhY2N1ICh4IDo6IGxfYWNjdSkgbCBpblxuICBhdXggYWNjdSBbXSBsXG5cbmxldCBwYXJ0aXRpb24gcCBsID1cbiAgbGV0IHJlYyBwYXJ0IHllcyBubyA9IGZ1bmN0aW9uXG4gIHwgW10gLT4gKHJldiB5ZXMsIHJldiBubylcbiAgfCB4IDo6IGwgLT4gaWYgcCB4IHRoZW4gcGFydCAoeCA6OiB5ZXMpIG5vIGwgZWxzZSBwYXJ0IHllcyAoeCA6OiBubykgbCBpblxuICBwYXJ0IFtdIFtdIGxcblxubGV0IHBhcnRpdGlvbl9tYXAgcCBsID1cbiAgbGV0IHJlYyBwYXJ0IGxlZnQgcmlnaHQgPSBmdW5jdGlvblxuICB8IFtdIC0+IChyZXYgbGVmdCwgcmV2IHJpZ2h0KVxuICB8IHggOjogbCAtPlxuICAgICBiZWdpbiBtYXRjaCBwIHggd2l0aFxuICAgICAgIHwgRWl0aGVyLkxlZnQgdiAtPiBwYXJ0ICh2IDo6IGxlZnQpIHJpZ2h0IGxcbiAgICAgICB8IEVpdGhlci5SaWdodCB2IC0+IHBhcnQgbGVmdCAodiA6OiByaWdodCkgbFxuICAgICBlbmRcbiAgaW5cbiAgcGFydCBbXSBbXSBsXG5cbmxldCByZWMgc3BsaXQgPSBmdW5jdGlvblxuICAgIFtdIC0+IChbXSwgW10pXG4gIHwgKHgseSk6OmwgLT5cbiAgICAgIGxldCAocngsIHJ5KSA9IHNwbGl0IGwgaW4gKHg6OnJ4LCB5OjpyeSlcblxubGV0IHJlYyBjb21iaW5lIGwxIGwyID1cbiAgbWF0Y2ggKGwxLCBsMikgd2l0aFxuICAgIChbXSwgW10pIC0+IFtdXG4gIHwgKGExOjpsMSwgYTI6OmwyKSAtPiAoYTEsIGEyKSA6OiBjb21iaW5lIGwxIGwyXG4gIHwgKF8sIF8pIC0+IGludmFsaWRfYXJnIFwiTGlzdC5jb21iaW5lXCJcblxuKCoqIHNvcnRpbmcgKilcblxubGV0IHJlYyBtZXJnZSBjbXAgbDEgbDIgPVxuICBtYXRjaCBsMSwgbDIgd2l0aFxuICB8IFtdLCBsMiAtPiBsMlxuICB8IGwxLCBbXSAtPiBsMVxuICB8IGgxIDo6IHQxLCBoMiA6OiB0MiAtPlxuICAgICAgaWYgY21wIGgxIGgyIDw9IDBcbiAgICAgIHRoZW4gaDEgOjogbWVyZ2UgY21wIHQxIGwyXG4gICAgICBlbHNlIGgyIDo6IG1lcmdlIGNtcCBsMSB0MlxuXG5cbmxldCBzdGFibGVfc29ydCBjbXAgbCA9XG4gIGxldCByZWMgcmV2X21lcmdlIGwxIGwyIGFjY3UgPVxuICAgIG1hdGNoIGwxLCBsMiB3aXRoXG4gICAgfCBbXSwgbDIgLT4gcmV2X2FwcGVuZCBsMiBhY2N1XG4gICAgfCBsMSwgW10gLT4gcmV2X2FwcGVuZCBsMSBhY2N1XG4gICAgfCBoMTo6dDEsIGgyOjp0MiAtPlxuICAgICAgICBpZiBjbXAgaDEgaDIgPD0gMFxuICAgICAgICB0aGVuIHJldl9tZXJnZSB0MSBsMiAoaDE6OmFjY3UpXG4gICAgICAgIGVsc2UgcmV2X21lcmdlIGwxIHQyIChoMjo6YWNjdSlcbiAgaW5cbiAgbGV0IHJlYyByZXZfbWVyZ2VfcmV2IGwxIGwyIGFjY3UgPVxuICAgIG1hdGNoIGwxLCBsMiB3aXRoXG4gICAgfCBbXSwgbDIgLT4gcmV2X2FwcGVuZCBsMiBhY2N1XG4gICAgfCBsMSwgW10gLT4gcmV2X2FwcGVuZCBsMSBhY2N1XG4gICAgfCBoMTo6dDEsIGgyOjp0MiAtPlxuICAgICAgICBpZiBjbXAgaDEgaDIgPiAwXG4gICAgICAgIHRoZW4gcmV2X21lcmdlX3JldiB0MSBsMiAoaDE6OmFjY3UpXG4gICAgICAgIGVsc2UgcmV2X21lcmdlX3JldiBsMSB0MiAoaDI6OmFjY3UpXG4gIGluXG4gIGxldCByZWMgc29ydCBuIGwgPVxuICAgIG1hdGNoIG4sIGwgd2l0aFxuICAgIHwgMiwgeDEgOjogeDIgOjogdGwgLT5cbiAgICAgICAgbGV0IHMgPSBpZiBjbXAgeDEgeDIgPD0gMCB0aGVuIFt4MTsgeDJdIGVsc2UgW3gyOyB4MV0gaW5cbiAgICAgICAgKHMsIHRsKVxuICAgIHwgMywgeDEgOjogeDIgOjogeDMgOjogdGwgLT5cbiAgICAgICAgbGV0IHMgPVxuICAgICAgICAgIGlmIGNtcCB4MSB4MiA8PSAwIHRoZW5cbiAgICAgICAgICAgIGlmIGNtcCB4MiB4MyA8PSAwIHRoZW4gW3gxOyB4MjsgeDNdXG4gICAgICAgICAgICBlbHNlIGlmIGNtcCB4MSB4MyA8PSAwIHRoZW4gW3gxOyB4MzsgeDJdXG4gICAgICAgICAgICBlbHNlIFt4MzsgeDE7IHgyXVxuICAgICAgICAgIGVsc2UgaWYgY21wIHgxIHgzIDw9IDAgdGhlbiBbeDI7IHgxOyB4M11cbiAgICAgICAgICBlbHNlIGlmIGNtcCB4MiB4MyA8PSAwIHRoZW4gW3gyOyB4MzsgeDFdXG4gICAgICAgICAgZWxzZSBbeDM7IHgyOyB4MV1cbiAgICAgICAgaW5cbiAgICAgICAgKHMsIHRsKVxuICAgIHwgbiwgbCAtPlxuICAgICAgICBsZXQgbjEgPSBuIGFzciAxIGluXG4gICAgICAgIGxldCBuMiA9IG4gLSBuMSBpblxuICAgICAgICBsZXQgczEsIGwyID0gcmV2X3NvcnQgbjEgbCBpblxuICAgICAgICBsZXQgczIsIHRsID0gcmV2X3NvcnQgbjIgbDIgaW5cbiAgICAgICAgKHJldl9tZXJnZV9yZXYgczEgczIgW10sIHRsKVxuICBhbmQgcmV2X3NvcnQgbiBsID1cbiAgICBtYXRjaCBuLCBsIHdpdGhcbiAgICB8IDIsIHgxIDo6IHgyIDo6IHRsIC0+XG4gICAgICAgIGxldCBzID0gaWYgY21wIHgxIHgyID4gMCB0aGVuIFt4MTsgeDJdIGVsc2UgW3gyOyB4MV0gaW5cbiAgICAgICAgKHMsIHRsKVxuICAgIHwgMywgeDEgOjogeDIgOjogeDMgOjogdGwgLT5cbiAgICAgICAgbGV0IHMgPVxuICAgICAgICAgIGlmIGNtcCB4MSB4MiA+IDAgdGhlblxuICAgICAgICAgICAgaWYgY21wIHgyIHgzID4gMCB0aGVuIFt4MTsgeDI7IHgzXVxuICAgICAgICAgICAgZWxzZSBpZiBjbXAgeDEgeDMgPiAwIHRoZW4gW3gxOyB4MzsgeDJdXG4gICAgICAgICAgICBlbHNlIFt4MzsgeDE7IHgyXVxuICAgICAgICAgIGVsc2UgaWYgY21wIHgxIHgzID4gMCB0aGVuIFt4MjsgeDE7IHgzXVxuICAgICAgICAgIGVsc2UgaWYgY21wIHgyIHgzID4gMCB0aGVuIFt4MjsgeDM7IHgxXVxuICAgICAgICAgIGVsc2UgW3gzOyB4MjsgeDFdXG4gICAgICAgIGluXG4gICAgICAgIChzLCB0bClcbiAgICB8IG4sIGwgLT5cbiAgICAgICAgbGV0IG4xID0gbiBhc3IgMSBpblxuICAgICAgICBsZXQgbjIgPSBuIC0gbjEgaW5cbiAgICAgICAgbGV0IHMxLCBsMiA9IHNvcnQgbjEgbCBpblxuICAgICAgICBsZXQgczIsIHRsID0gc29ydCBuMiBsMiBpblxuICAgICAgICAocmV2X21lcmdlIHMxIHMyIFtdLCB0bClcbiAgaW5cbiAgbGV0IGxlbiA9IGxlbmd0aCBsIGluXG4gIGlmIGxlbiA8IDIgdGhlbiBsIGVsc2UgZnN0IChzb3J0IGxlbiBsKVxuXG5cbmxldCBzb3J0ID0gc3RhYmxlX3NvcnRcbmxldCBmYXN0X3NvcnQgPSBzdGFibGVfc29ydFxuXG4oKiBOb3RlOiBvbiBhIGxpc3Qgb2YgbGVuZ3RoIGJldHdlZW4gYWJvdXQgMTAwMDAwIChkZXBlbmRpbmcgb24gdGhlIG1pbm9yXG4gICBoZWFwIHNpemUgYW5kIHRoZSB0eXBlIG9mIHRoZSBsaXN0KSBhbmQgU3lzLm1heF9hcnJheV9zaXplLCBpdCBpc1xuICAgYWN0dWFsbHkgZmFzdGVyIHRvIHVzZSB0aGUgZm9sbG93aW5nLCBidXQgaXQgbWlnaHQgYWxzbyB1c2UgbW9yZSBtZW1vcnlcbiAgIGJlY2F1c2UgdGhlIGFyZ3VtZW50IGxpc3QgY2Fubm90IGJlIGRlYWxsb2NhdGVkIGluY3JlbWVudGFsbHkuXG5cbiAgIEFsc28sIHRoZXJlIHNlZW1zIHRvIGJlIGEgYnVnIGluIHRoaXMgY29kZSBvciBpbiB0aGVcbiAgIGltcGxlbWVudGF0aW9uIG9mIG9ial90cnVuY2F0ZS5cblxuZXh0ZXJuYWwgb2JqX3RydW5jYXRlIDogJ2EgYXJyYXkgLT4gaW50IC0+IHVuaXQgPSBcImNhbWxfb2JqX3RydW5jYXRlXCJcblxubGV0IGFycmF5X3RvX2xpc3RfaW5fcGxhY2UgYSA9XG4gIGxldCBsID0gQXJyYXkubGVuZ3RoIGEgaW5cbiAgbGV0IHJlYyBsb29wIGFjY3UgbiBwID1cbiAgICBpZiBwIDw9IDAgdGhlbiBhY2N1IGVsc2UgYmVnaW5cbiAgICAgIGlmIHAgPSBuIHRoZW4gYmVnaW5cbiAgICAgICAgb2JqX3RydW5jYXRlIGEgcDtcbiAgICAgICAgbG9vcCAoYS4ocC0xKSA6OiBhY2N1KSAobi0xMDAwKSAocC0xKVxuICAgICAgZW5kIGVsc2UgYmVnaW5cbiAgICAgICAgbG9vcCAoYS4ocC0xKSA6OiBhY2N1KSBuIChwLTEpXG4gICAgICBlbmRcbiAgICBlbmRcbiAgaW5cbiAgbG9vcCBbXSAobC0xMDAwKSBsXG5cblxubGV0IHN0YWJsZV9zb3J0IGNtcCBsID1cbiAgbGV0IGEgPSBBcnJheS5vZl9saXN0IGwgaW5cbiAgQXJyYXkuc3RhYmxlX3NvcnQgY21wIGE7XG4gIGFycmF5X3RvX2xpc3RfaW5fcGxhY2UgYVxuXG4qKVxuXG5cbigqKiBzb3J0aW5nICsgcmVtb3ZpbmcgZHVwbGljYXRlcyAqKVxuXG5sZXQgc29ydF91bmlxIGNtcCBsID1cbiAgbGV0IHJlYyByZXZfbWVyZ2UgbDEgbDIgYWNjdSA9XG4gICAgbWF0Y2ggbDEsIGwyIHdpdGhcbiAgICB8IFtdLCBsMiAtPiByZXZfYXBwZW5kIGwyIGFjY3VcbiAgICB8IGwxLCBbXSAtPiByZXZfYXBwZW5kIGwxIGFjY3VcbiAgICB8IGgxOjp0MSwgaDI6OnQyIC0+XG4gICAgICAgIGxldCBjID0gY21wIGgxIGgyIGluXG4gICAgICAgIGlmIGMgPSAwIHRoZW4gcmV2X21lcmdlIHQxIHQyIChoMTo6YWNjdSlcbiAgICAgICAgZWxzZSBpZiBjIDwgMFxuICAgICAgICB0aGVuIHJldl9tZXJnZSB0MSBsMiAoaDE6OmFjY3UpXG4gICAgICAgIGVsc2UgcmV2X21lcmdlIGwxIHQyIChoMjo6YWNjdSlcbiAgaW5cbiAgbGV0IHJlYyByZXZfbWVyZ2VfcmV2IGwxIGwyIGFjY3UgPVxuICAgIG1hdGNoIGwxLCBsMiB3aXRoXG4gICAgfCBbXSwgbDIgLT4gcmV2X2FwcGVuZCBsMiBhY2N1XG4gICAgfCBsMSwgW10gLT4gcmV2X2FwcGVuZCBsMSBhY2N1XG4gICAgfCBoMTo6dDEsIGgyOjp0MiAtPlxuICAgICAgICBsZXQgYyA9IGNtcCBoMSBoMiBpblxuICAgICAgICBpZiBjID0gMCB0aGVuIHJldl9tZXJnZV9yZXYgdDEgdDIgKGgxOjphY2N1KVxuICAgICAgICBlbHNlIGlmIGMgPiAwXG4gICAgICAgIHRoZW4gcmV2X21lcmdlX3JldiB0MSBsMiAoaDE6OmFjY3UpXG4gICAgICAgIGVsc2UgcmV2X21lcmdlX3JldiBsMSB0MiAoaDI6OmFjY3UpXG4gIGluXG4gIGxldCByZWMgc29ydCBuIGwgPVxuICAgIG1hdGNoIG4sIGwgd2l0aFxuICAgIHwgMiwgeDEgOjogeDIgOjogdGwgLT5cbiAgICAgICAgbGV0IHMgPVxuICAgICAgICAgIGxldCBjID0gY21wIHgxIHgyIGluXG4gICAgICAgICAgaWYgYyA9IDAgdGhlbiBbeDFdIGVsc2UgaWYgYyA8IDAgdGhlbiBbeDE7IHgyXSBlbHNlIFt4MjsgeDFdXG4gICAgICAgIGluXG4gICAgICAgIChzLCB0bClcbiAgICB8IDMsIHgxIDo6IHgyIDo6IHgzIDo6IHRsIC0+XG4gICAgICAgIGxldCBzID1cbiAgICAgICAgICBsZXQgYyA9IGNtcCB4MSB4MiBpblxuICAgICAgICAgIGlmIGMgPSAwIHRoZW5cbiAgICAgICAgICAgIGxldCBjID0gY21wIHgyIHgzIGluXG4gICAgICAgICAgICBpZiBjID0gMCB0aGVuIFt4Ml0gZWxzZSBpZiBjIDwgMCB0aGVuIFt4MjsgeDNdIGVsc2UgW3gzOyB4Ml1cbiAgICAgICAgICBlbHNlIGlmIGMgPCAwIHRoZW5cbiAgICAgICAgICAgIGxldCBjID0gY21wIHgyIHgzIGluXG4gICAgICAgICAgICBpZiBjID0gMCB0aGVuIFt4MTsgeDJdXG4gICAgICAgICAgICBlbHNlIGlmIGMgPCAwIHRoZW4gW3gxOyB4MjsgeDNdXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgIGxldCBjID0gY21wIHgxIHgzIGluXG4gICAgICAgICAgICAgIGlmIGMgPSAwIHRoZW4gW3gxOyB4Ml1cbiAgICAgICAgICAgICAgZWxzZSBpZiBjIDwgMCB0aGVuIFt4MTsgeDM7IHgyXVxuICAgICAgICAgICAgICBlbHNlIFt4MzsgeDE7IHgyXVxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGxldCBjID0gY21wIHgxIHgzIGluXG4gICAgICAgICAgICBpZiBjID0gMCB0aGVuIFt4MjsgeDFdXG4gICAgICAgICAgICBlbHNlIGlmIGMgPCAwIHRoZW4gW3gyOyB4MTsgeDNdXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgIGxldCBjID0gY21wIHgyIHgzIGluXG4gICAgICAgICAgICAgIGlmIGMgPSAwIHRoZW4gW3gyOyB4MV1cbiAgICAgICAgICAgICAgZWxzZSBpZiBjIDwgMCB0aGVuIFt4MjsgeDM7IHgxXVxuICAgICAgICAgICAgICBlbHNlIFt4MzsgeDI7IHgxXVxuICAgICAgICBpblxuICAgICAgICAocywgdGwpXG4gICAgfCBuLCBsIC0+XG4gICAgICAgIGxldCBuMSA9IG4gYXNyIDEgaW5cbiAgICAgICAgbGV0IG4yID0gbiAtIG4xIGluXG4gICAgICAgIGxldCBzMSwgbDIgPSByZXZfc29ydCBuMSBsIGluXG4gICAgICAgIGxldCBzMiwgdGwgPSByZXZfc29ydCBuMiBsMiBpblxuICAgICAgICAocmV2X21lcmdlX3JldiBzMSBzMiBbXSwgdGwpXG4gIGFuZCByZXZfc29ydCBuIGwgPVxuICAgIG1hdGNoIG4sIGwgd2l0aFxuICAgIHwgMiwgeDEgOjogeDIgOjogdGwgLT5cbiAgICAgICAgbGV0IHMgPVxuICAgICAgICAgIGxldCBjID0gY21wIHgxIHgyIGluXG4gICAgICAgICAgaWYgYyA9IDAgdGhlbiBbeDFdIGVsc2UgaWYgYyA+IDAgdGhlbiBbeDE7IHgyXSBlbHNlIFt4MjsgeDFdXG4gICAgICAgIGluXG4gICAgICAgIChzLCB0bClcbiAgICB8IDMsIHgxIDo6IHgyIDo6IHgzIDo6IHRsIC0+XG4gICAgICAgIGxldCBzID1cbiAgICAgICAgICBsZXQgYyA9IGNtcCB4MSB4MiBpblxuICAgICAgICAgIGlmIGMgPSAwIHRoZW5cbiAgICAgICAgICAgIGxldCBjID0gY21wIHgyIHgzIGluXG4gICAgICAgICAgICBpZiBjID0gMCB0aGVuIFt4Ml0gZWxzZSBpZiBjID4gMCB0aGVuIFt4MjsgeDNdIGVsc2UgW3gzOyB4Ml1cbiAgICAgICAgICBlbHNlIGlmIGMgPiAwIHRoZW5cbiAgICAgICAgICAgIGxldCBjID0gY21wIHgyIHgzIGluXG4gICAgICAgICAgICBpZiBjID0gMCB0aGVuIFt4MTsgeDJdXG4gICAgICAgICAgICBlbHNlIGlmIGMgPiAwIHRoZW4gW3gxOyB4MjsgeDNdXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgIGxldCBjID0gY21wIHgxIHgzIGluXG4gICAgICAgICAgICAgIGlmIGMgPSAwIHRoZW4gW3gxOyB4Ml1cbiAgICAgICAgICAgICAgZWxzZSBpZiBjID4gMCB0aGVuIFt4MTsgeDM7IHgyXVxuICAgICAgICAgICAgICBlbHNlIFt4MzsgeDE7IHgyXVxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGxldCBjID0gY21wIHgxIHgzIGluXG4gICAgICAgICAgICBpZiBjID0gMCB0aGVuIFt4MjsgeDFdXG4gICAgICAgICAgICBlbHNlIGlmIGMgPiAwIHRoZW4gW3gyOyB4MTsgeDNdXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgIGxldCBjID0gY21wIHgyIHgzIGluXG4gICAgICAgICAgICAgIGlmIGMgPSAwIHRoZW4gW3gyOyB4MV1cbiAgICAgICAgICAgICAgZWxzZSBpZiBjID4gMCB0aGVuIFt4MjsgeDM7IHgxXVxuICAgICAgICAgICAgICBlbHNlIFt4MzsgeDI7IHgxXVxuICAgICAgICBpblxuICAgICAgICAocywgdGwpXG4gICAgfCBuLCBsIC0+XG4gICAgICAgIGxldCBuMSA9IG4gYXNyIDEgaW5cbiAgICAgICAgbGV0IG4yID0gbiAtIG4xIGluXG4gICAgICAgIGxldCBzMSwgbDIgPSBzb3J0IG4xIGwgaW5cbiAgICAgICAgbGV0IHMyLCB0bCA9IHNvcnQgbjIgbDIgaW5cbiAgICAgICAgKHJldl9tZXJnZSBzMSBzMiBbXSwgdGwpXG4gIGluXG4gIGxldCBsZW4gPSBsZW5ndGggbCBpblxuICBpZiBsZW4gPCAyIHRoZW4gbCBlbHNlIGZzdCAoc29ydCBsZW4gbClcblxuXG5sZXQgcmVjIGNvbXBhcmVfbGVuZ3RocyBsMSBsMiA9XG4gIG1hdGNoIGwxLCBsMiB3aXRoXG4gIHwgW10sIFtdIC0+IDBcbiAgfCBbXSwgXyAtPiAtMVxuICB8IF8sIFtdIC0+IDFcbiAgfCBfIDo6IGwxLCBfIDo6IGwyIC0+IGNvbXBhcmVfbGVuZ3RocyBsMSBsMlxuOztcblxubGV0IHJlYyBjb21wYXJlX2xlbmd0aF93aXRoIGwgbiA9XG4gIG1hdGNoIGwgd2l0aFxuICB8IFtdIC0+XG4gICAgaWYgbiA9IDAgdGhlbiAwIGVsc2VcbiAgICAgIGlmIG4gPiAwIHRoZW4gLTEgZWxzZSAxXG4gIHwgXyA6OiBsIC0+XG4gICAgaWYgbiA8PSAwIHRoZW4gMSBlbHNlXG4gICAgICBjb21wYXJlX2xlbmd0aF93aXRoIGwgKG4tMSlcbjs7XG5cbigqKiB7MSBDb21wYXJpc29ufSAqKVxuXG4oKiBOb3RlOiB3ZSBhcmUgKm5vdCogc2hvcnRjdXR0aW5nIHRoZSBsaXN0IGJ5IHVzaW5nXG4gICBbTGlzdC5jb21wYXJlX2xlbmd0aHNdIGZpcnN0OyB0aGlzIG1heSBiZSBzbG93ZXIgb24gbG9uZyBsaXN0c1xuICAgaW1tZWRpYXRlbHkgc3RhcnQgd2l0aCBkaXN0aW5jdCBlbGVtZW50cy4gSXQgaXMgYWxzbyBpbmNvcnJlY3QgZm9yXG4gICBbY29tcGFyZV0gYmVsb3csIGFuZCBpdCBpcyBiZXR0ZXIgKHByaW5jaXBsZSBvZiBsZWFzdCBzdXJwcmlzZSkgdG9cbiAgIHVzZSB0aGUgc2FtZSBhcHByb2FjaCBmb3IgYm90aCBmdW5jdGlvbnMuICopXG5sZXQgcmVjIGVxdWFsIGVxIGwxIGwyID1cbiAgbWF0Y2ggbDEsIGwyIHdpdGhcbiAgfCBbXSwgW10gLT4gdHJ1ZVxuICB8IFtdLCBfOjpfIHwgXzo6XywgW10gLT4gZmFsc2VcbiAgfCBhMTo6bDEsIGEyOjpsMiAtPiBlcSBhMSBhMiAmJiBlcXVhbCBlcSBsMSBsMlxuXG5sZXQgcmVjIGNvbXBhcmUgY21wIGwxIGwyID1cbiAgbWF0Y2ggbDEsIGwyIHdpdGhcbiAgfCBbXSwgW10gLT4gMFxuICB8IFtdLCBfOjpfIC0+IC0xXG4gIHwgXzo6XywgW10gLT4gMVxuICB8IGExOjpsMSwgYTI6OmwyIC0+XG4gICAgbGV0IGMgPSBjbXAgYTEgYTIgaW5cbiAgICBpZiBjIDw+IDAgdGhlbiBjXG4gICAgZWxzZSBjb21wYXJlIGNtcCBsMSBsMlxuXG4oKiogezEgSXRlcmF0b3JzfSAqKVxuXG5sZXQgdG9fc2VxIGwgPVxuICBsZXQgcmVjIGF1eCBsICgpID0gbWF0Y2ggbCB3aXRoXG4gICAgfCBbXSAtPiBTZXEuTmlsXG4gICAgfCB4IDo6IHRhaWwgLT4gU2VxLkNvbnMgKHgsIGF1eCB0YWlsKVxuICBpblxuICBhdXggbFxuXG5sZXQgb2Zfc2VxIHNlcSA9XG4gIGxldCByZWMgZGlyZWN0IGRlcHRoIHNlcSA6IF8gbGlzdCA9XG4gICAgaWYgZGVwdGg9MFxuICAgIHRoZW5cbiAgICAgIFNlcS5mb2xkX2xlZnQgKGZ1biBhY2MgeCAtPiB4OjphY2MpIFtdIHNlcVxuICAgICAgfD4gcmV2ICgqIHRhaWxyZWMgKilcbiAgICBlbHNlIG1hdGNoIHNlcSgpIHdpdGhcbiAgICAgIHwgU2VxLk5pbCAtPiBbXVxuICAgICAgfCBTZXEuQ29ucyAoeCwgbmV4dCkgLT4geCA6OiBkaXJlY3QgKGRlcHRoLTEpIG5leHRcbiAgaW5cbiAgZGlyZWN0IDUwMCBzZXFcbiIsIigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0NhbWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgIFRoZSBPQ2FtbCBwcm9ncmFtbWVycyAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQ29weXJpZ2h0IDIwMTggSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCAgICAgKilcbigqICAgICBlbiBBdXRvbWF0aXF1ZS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQWxsIHJpZ2h0cyByZXNlcnZlZC4gIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgICAgKilcbigqICAgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIuMSwgd2l0aCB0aGUgICAgICAgICAgKilcbigqICAgc3BlY2lhbCBleGNlcHRpb24gb24gbGlua2luZyBkZXNjcmliZWQgaW4gdGhlIGZpbGUgTElDRU5TRS4gICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcblxudHlwZSB0ID0gaW50XG5cbmxldCB6ZXJvID0gMFxubGV0IG9uZSA9IDFcbmxldCBtaW51c19vbmUgPSAtMVxuZXh0ZXJuYWwgbmVnIDogaW50IC0+IGludCA9IFwiJW5lZ2ludFwiXG5leHRlcm5hbCBhZGQgOiBpbnQgLT4gaW50IC0+IGludCA9IFwiJWFkZGludFwiXG5leHRlcm5hbCBzdWIgOiBpbnQgLT4gaW50IC0+IGludCA9IFwiJXN1YmludFwiXG5leHRlcm5hbCBtdWwgOiBpbnQgLT4gaW50IC0+IGludCA9IFwiJW11bGludFwiXG5leHRlcm5hbCBkaXYgOiBpbnQgLT4gaW50IC0+IGludCA9IFwiJWRpdmludFwiXG5leHRlcm5hbCByZW0gOiBpbnQgLT4gaW50IC0+IGludCA9IFwiJW1vZGludFwiXG5leHRlcm5hbCBzdWNjIDogaW50IC0+IGludCA9IFwiJXN1Y2NpbnRcIlxuZXh0ZXJuYWwgcHJlZCA6IGludCAtPiBpbnQgPSBcIiVwcmVkaW50XCJcbmxldCBhYnMgeCA9IGlmIHggPj0gMCB0aGVuIHggZWxzZSAteFxubGV0IG1heF9pbnQgPSAoLTEpIGxzciAxXG5sZXQgbWluX2ludCA9IG1heF9pbnQgKyAxXG5leHRlcm5hbCBsb2dhbmQgOiBpbnQgLT4gaW50IC0+IGludCA9IFwiJWFuZGludFwiXG5leHRlcm5hbCBsb2dvciA6IGludCAtPiBpbnQgLT4gaW50ID0gXCIlb3JpbnRcIlxuZXh0ZXJuYWwgbG9neG9yIDogaW50IC0+IGludCAtPiBpbnQgPSBcIiV4b3JpbnRcIlxubGV0IGxvZ25vdCB4ID0gbG9neG9yIHggKC0xKVxuZXh0ZXJuYWwgc2hpZnRfbGVmdCA6IGludCAtPiBpbnQgLT4gaW50ID0gXCIlbHNsaW50XCJcbmV4dGVybmFsIHNoaWZ0X3JpZ2h0IDogaW50IC0+IGludCAtPiBpbnQgPSBcIiVhc3JpbnRcIlxuZXh0ZXJuYWwgc2hpZnRfcmlnaHRfbG9naWNhbCA6IGludCAtPiBpbnQgLT4gaW50ID0gXCIlbHNyaW50XCJcbmxldCBlcXVhbCA6IGludCAtPiBpbnQgLT4gYm9vbCA9ICggPSApXG5sZXQgY29tcGFyZSA6IGludCAtPiBpbnQgLT4gaW50ID0gU3RkbGliLmNvbXBhcmVcbmxldCBtaW4geCB5IDogdCA9IGlmIHggPD0geSB0aGVuIHggZWxzZSB5XG5sZXQgbWF4IHggeSA6IHQgPSBpZiB4ID49IHkgdGhlbiB4IGVsc2UgeVxuZXh0ZXJuYWwgdG9fZmxvYXQgOiBpbnQgLT4gZmxvYXQgPSBcIiVmbG9hdG9maW50XCJcbmV4dGVybmFsIG9mX2Zsb2F0IDogZmxvYXQgLT4gaW50ID0gXCIlaW50b2ZmbG9hdFwiXG5cbigqXG5leHRlcm5hbCBpbnRfb2Zfc3RyaW5nIDogc3RyaW5nIC0+IGludCA9IFwiY2FtbF9pbnRfb2Zfc3RyaW5nXCJcbmxldCBvZl9zdHJpbmcgcyA9IHRyeSBTb21lIChpbnRfb2Zfc3RyaW5nIHMpIHdpdGggRmFpbHVyZSBfIC0+IE5vbmVcbiopXG5cbmV4dGVybmFsIGZvcm1hdF9pbnQgOiBzdHJpbmcgLT4gaW50IC0+IHN0cmluZyA9IFwiY2FtbF9mb3JtYXRfaW50XCJcbmxldCB0b19zdHJpbmcgeCA9IGZvcm1hdF9pbnQgXCIlZFwiIHhcbiIsIigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0NhbWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgIFhhdmllciBMZXJveSwgcHJvamV0IENyaXN0YWwsIElOUklBIFJvY3F1ZW5jb3VydCAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQ29weXJpZ2h0IDE5OTYgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCAgICAgKilcbigqICAgICBlbiBBdXRvbWF0aXF1ZS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQWxsIHJpZ2h0cyByZXNlcnZlZC4gIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgICAgKilcbigqICAgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIuMSwgd2l0aCB0aGUgICAgICAgICAgKilcbigqICAgc3BlY2lhbCBleGNlcHRpb24gb24gbGlua2luZyBkZXNjcmliZWQgaW4gdGhlIGZpbGUgTElDRU5TRS4gICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcblxuKCogQnl0ZSBzZXF1ZW5jZSBvcGVyYXRpb25zICopXG5cbigqIFdBUk5JTkc6IFNvbWUgZnVuY3Rpb25zIGluIHRoaXMgZmlsZSBhcmUgZHVwbGljYXRlZCBpbiBzdHJpbmcubWwgZm9yXG4gICBlZmZpY2llbmN5IHJlYXNvbnMuIFdoZW4geW91IG1vZGlmeSB0aGUgb25lIGluIHRoaXMgZmlsZSB5b3UgbmVlZCB0b1xuICAgbW9kaWZ5IGl0cyBkdXBsaWNhdGUgaW4gc3RyaW5nLm1sLlxuICAgVGhlc2UgZnVuY3Rpb25zIGhhdmUgYSBcImR1cGxpY2F0ZWRcIiBjb21tZW50IGFib3ZlIHRoZWlyIGRlZmluaXRpb24uXG4qKVxuXG5leHRlcm5hbCBsZW5ndGggOiBieXRlcyAtPiBpbnQgPSBcIiVieXRlc19sZW5ndGhcIlxuZXh0ZXJuYWwgc3RyaW5nX2xlbmd0aCA6IHN0cmluZyAtPiBpbnQgPSBcIiVzdHJpbmdfbGVuZ3RoXCJcbmV4dGVybmFsIGdldCA6IGJ5dGVzIC0+IGludCAtPiBjaGFyID0gXCIlYnl0ZXNfc2FmZV9nZXRcIlxuZXh0ZXJuYWwgc2V0IDogYnl0ZXMgLT4gaW50IC0+IGNoYXIgLT4gdW5pdCA9IFwiJWJ5dGVzX3NhZmVfc2V0XCJcbmV4dGVybmFsIGNyZWF0ZSA6IGludCAtPiBieXRlcyA9IFwiY2FtbF9jcmVhdGVfYnl0ZXNcIlxuZXh0ZXJuYWwgdW5zYWZlX2dldCA6IGJ5dGVzIC0+IGludCAtPiBjaGFyID0gXCIlYnl0ZXNfdW5zYWZlX2dldFwiXG5leHRlcm5hbCB1bnNhZmVfc2V0IDogYnl0ZXMgLT4gaW50IC0+IGNoYXIgLT4gdW5pdCA9IFwiJWJ5dGVzX3Vuc2FmZV9zZXRcIlxuZXh0ZXJuYWwgdW5zYWZlX2ZpbGwgOiBieXRlcyAtPiBpbnQgLT4gaW50IC0+IGNoYXIgLT4gdW5pdFxuICAgICAgICAgICAgICAgICAgICAgPSBcImNhbWxfZmlsbF9ieXRlc1wiIFtAQG5vYWxsb2NdXG5leHRlcm5hbCB1bnNhZmVfdG9fc3RyaW5nIDogYnl0ZXMgLT4gc3RyaW5nID0gXCIlYnl0ZXNfdG9fc3RyaW5nXCJcbmV4dGVybmFsIHVuc2FmZV9vZl9zdHJpbmcgOiBzdHJpbmcgLT4gYnl0ZXMgPSBcIiVieXRlc19vZl9zdHJpbmdcIlxuXG5leHRlcm5hbCB1bnNhZmVfYmxpdCA6IGJ5dGVzIC0+IGludCAtPiBieXRlcyAtPiBpbnQgLT4gaW50IC0+IHVuaXRcbiAgICAgICAgICAgICAgICAgICAgID0gXCJjYW1sX2JsaXRfYnl0ZXNcIiBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgdW5zYWZlX2JsaXRfc3RyaW5nIDogc3RyaW5nIC0+IGludCAtPiBieXRlcyAtPiBpbnQgLT4gaW50IC0+IHVuaXRcbiAgICAgICAgICAgICAgICAgICAgID0gXCJjYW1sX2JsaXRfc3RyaW5nXCIgW0BAbm9hbGxvY11cblxubGV0IG1ha2UgbiBjID1cbiAgbGV0IHMgPSBjcmVhdGUgbiBpblxuICB1bnNhZmVfZmlsbCBzIDAgbiBjO1xuICBzXG5cbmxldCBpbml0IG4gZiA9XG4gIGxldCBzID0gY3JlYXRlIG4gaW5cbiAgZm9yIGkgPSAwIHRvIG4gLSAxIGRvXG4gICAgdW5zYWZlX3NldCBzIGkgKGYgaSlcbiAgZG9uZTtcbiAgc1xuXG5sZXQgZW1wdHkgPSBjcmVhdGUgMFxuXG5sZXQgY29weSBzID1cbiAgbGV0IGxlbiA9IGxlbmd0aCBzIGluXG4gIGxldCByID0gY3JlYXRlIGxlbiBpblxuICB1bnNhZmVfYmxpdCBzIDAgciAwIGxlbjtcbiAgclxuXG5sZXQgdG9fc3RyaW5nIGIgPSB1bnNhZmVfdG9fc3RyaW5nIChjb3B5IGIpXG5sZXQgb2Zfc3RyaW5nIHMgPSBjb3B5ICh1bnNhZmVfb2Zfc3RyaW5nIHMpXG5cbmxldCBzdWIgcyBvZnMgbGVuID1cbiAgaWYgb2ZzIDwgMCB8fCBsZW4gPCAwIHx8IG9mcyA+IGxlbmd0aCBzIC0gbGVuXG4gIHRoZW4gaW52YWxpZF9hcmcgXCJTdHJpbmcuc3ViIC8gQnl0ZXMuc3ViXCJcbiAgZWxzZSBiZWdpblxuICAgIGxldCByID0gY3JlYXRlIGxlbiBpblxuICAgIHVuc2FmZV9ibGl0IHMgb2ZzIHIgMCBsZW47XG4gICAgclxuICBlbmRcblxubGV0IHN1Yl9zdHJpbmcgYiBvZnMgbGVuID0gdW5zYWZlX3RvX3N0cmluZyAoc3ViIGIgb2ZzIGxlbilcblxuKCogYWRkaXRpb24gd2l0aCBhbiBvdmVyZmxvdyBjaGVjayAqKVxubGV0ICgrKykgYSBiID1cbiAgbGV0IGMgPSBhICsgYiBpblxuICBtYXRjaCBhIDwgMCwgYiA8IDAsIGMgPCAwIHdpdGhcbiAgfCB0cnVlICwgdHJ1ZSAsIGZhbHNlXG4gIHwgZmFsc2UsIGZhbHNlLCB0cnVlICAtPiBpbnZhbGlkX2FyZyBcIkJ5dGVzLmV4dGVuZFwiICgqIG92ZXJmbG93ICopXG4gIHwgXyAtPiBjXG5cbmxldCBleHRlbmQgcyBsZWZ0IHJpZ2h0ID1cbiAgbGV0IGxlbiA9IGxlbmd0aCBzICsrIGxlZnQgKysgcmlnaHQgaW5cbiAgbGV0IHIgPSBjcmVhdGUgbGVuIGluXG4gIGxldCAoc3Jjb2ZmLCBkc3RvZmYpID0gaWYgbGVmdCA8IDAgdGhlbiAtbGVmdCwgMCBlbHNlIDAsIGxlZnQgaW5cbiAgbGV0IGNweWxlbiA9IEludC5taW4gKGxlbmd0aCBzIC0gc3Jjb2ZmKSAobGVuIC0gZHN0b2ZmKSBpblxuICBpZiBjcHlsZW4gPiAwIHRoZW4gdW5zYWZlX2JsaXQgcyBzcmNvZmYgciBkc3RvZmYgY3B5bGVuO1xuICByXG5cbmxldCBmaWxsIHMgb2ZzIGxlbiBjID1cbiAgaWYgb2ZzIDwgMCB8fCBsZW4gPCAwIHx8IG9mcyA+IGxlbmd0aCBzIC0gbGVuXG4gIHRoZW4gaW52YWxpZF9hcmcgXCJTdHJpbmcuZmlsbCAvIEJ5dGVzLmZpbGxcIlxuICBlbHNlIHVuc2FmZV9maWxsIHMgb2ZzIGxlbiBjXG5cbmxldCBibGl0IHMxIG9mczEgczIgb2ZzMiBsZW4gPVxuICBpZiBsZW4gPCAwIHx8IG9mczEgPCAwIHx8IG9mczEgPiBsZW5ndGggczEgLSBsZW5cbiAgICAgICAgICAgICB8fCBvZnMyIDwgMCB8fCBvZnMyID4gbGVuZ3RoIHMyIC0gbGVuXG4gIHRoZW4gaW52YWxpZF9hcmcgXCJCeXRlcy5ibGl0XCJcbiAgZWxzZSB1bnNhZmVfYmxpdCBzMSBvZnMxIHMyIG9mczIgbGVuXG5cbmxldCBibGl0X3N0cmluZyBzMSBvZnMxIHMyIG9mczIgbGVuID1cbiAgaWYgbGVuIDwgMCB8fCBvZnMxIDwgMCB8fCBvZnMxID4gc3RyaW5nX2xlbmd0aCBzMSAtIGxlblxuICAgICAgICAgICAgIHx8IG9mczIgPCAwIHx8IG9mczIgPiBsZW5ndGggczIgLSBsZW5cbiAgdGhlbiBpbnZhbGlkX2FyZyBcIlN0cmluZy5ibGl0IC8gQnl0ZXMuYmxpdF9zdHJpbmdcIlxuICBlbHNlIHVuc2FmZV9ibGl0X3N0cmluZyBzMSBvZnMxIHMyIG9mczIgbGVuXG5cbigqIGR1cGxpY2F0ZWQgaW4gc3RyaW5nLm1sICopXG5sZXQgaXRlciBmIGEgPVxuICBmb3IgaSA9IDAgdG8gbGVuZ3RoIGEgLSAxIGRvIGYodW5zYWZlX2dldCBhIGkpIGRvbmVcblxuKCogZHVwbGljYXRlZCBpbiBzdHJpbmcubWwgKilcbmxldCBpdGVyaSBmIGEgPVxuICBmb3IgaSA9IDAgdG8gbGVuZ3RoIGEgLSAxIGRvIGYgaSAodW5zYWZlX2dldCBhIGkpIGRvbmVcblxubGV0IGVuc3VyZV9nZSAoeDppbnQpIHkgPSBpZiB4ID49IHkgdGhlbiB4IGVsc2UgaW52YWxpZF9hcmcgXCJCeXRlcy5jb25jYXRcIlxuXG5sZXQgcmVjIHN1bV9sZW5ndGhzIGFjYyBzZXBsZW4gPSBmdW5jdGlvblxuICB8IFtdIC0+IGFjY1xuICB8IGhkIDo6IFtdIC0+IGxlbmd0aCBoZCArIGFjY1xuICB8IGhkIDo6IHRsIC0+IHN1bV9sZW5ndGhzIChlbnN1cmVfZ2UgKGxlbmd0aCBoZCArIHNlcGxlbiArIGFjYykgYWNjKSBzZXBsZW4gdGxcblxubGV0IHJlYyB1bnNhZmVfYmxpdHMgZHN0IHBvcyBzZXAgc2VwbGVuID0gZnVuY3Rpb25cbiAgICBbXSAtPiBkc3RcbiAgfCBoZCA6OiBbXSAtPlxuICAgIHVuc2FmZV9ibGl0IGhkIDAgZHN0IHBvcyAobGVuZ3RoIGhkKTsgZHN0XG4gIHwgaGQgOjogdGwgLT5cbiAgICB1bnNhZmVfYmxpdCBoZCAwIGRzdCBwb3MgKGxlbmd0aCBoZCk7XG4gICAgdW5zYWZlX2JsaXQgc2VwIDAgZHN0IChwb3MgKyBsZW5ndGggaGQpIHNlcGxlbjtcbiAgICB1bnNhZmVfYmxpdHMgZHN0IChwb3MgKyBsZW5ndGggaGQgKyBzZXBsZW4pIHNlcCBzZXBsZW4gdGxcblxubGV0IGNvbmNhdCBzZXAgPSBmdW5jdGlvblxuICAgIFtdIC0+IGVtcHR5XG4gIHwgbCAtPiBsZXQgc2VwbGVuID0gbGVuZ3RoIHNlcCBpblxuICAgICAgICAgIHVuc2FmZV9ibGl0c1xuICAgICAgICAgICAgKGNyZWF0ZSAoc3VtX2xlbmd0aHMgMCBzZXBsZW4gbCkpXG4gICAgICAgICAgICAwIHNlcCBzZXBsZW4gbFxuXG5sZXQgY2F0IHMxIHMyID1cbiAgbGV0IGwxID0gbGVuZ3RoIHMxIGluXG4gIGxldCBsMiA9IGxlbmd0aCBzMiBpblxuICBsZXQgciA9IGNyZWF0ZSAobDEgKyBsMikgaW5cbiAgdW5zYWZlX2JsaXQgczEgMCByIDAgbDE7XG4gIHVuc2FmZV9ibGl0IHMyIDAgciBsMSBsMjtcbiAgclxuXG5cbmV4dGVybmFsIGNoYXJfY29kZTogY2hhciAtPiBpbnQgPSBcIiVpZGVudGl0eVwiXG5leHRlcm5hbCBjaGFyX2NocjogaW50IC0+IGNoYXIgPSBcIiVpZGVudGl0eVwiXG5cbmxldCBpc19zcGFjZSA9IGZ1bmN0aW9uXG4gIHwgJyAnIHwgJ1xcMDEyJyB8ICdcXG4nIHwgJ1xccicgfCAnXFx0JyAtPiB0cnVlXG4gIHwgXyAtPiBmYWxzZVxuXG5sZXQgdHJpbSBzID1cbiAgbGV0IGxlbiA9IGxlbmd0aCBzIGluXG4gIGxldCBpID0gcmVmIDAgaW5cbiAgd2hpbGUgIWkgPCBsZW4gJiYgaXNfc3BhY2UgKHVuc2FmZV9nZXQgcyAhaSkgZG9cbiAgICBpbmNyIGlcbiAgZG9uZTtcbiAgbGV0IGogPSByZWYgKGxlbiAtIDEpIGluXG4gIHdoaWxlICFqID49ICFpICYmIGlzX3NwYWNlICh1bnNhZmVfZ2V0IHMgIWopIGRvXG4gICAgZGVjciBqXG4gIGRvbmU7XG4gIGlmICFqID49ICFpIHRoZW5cbiAgICBzdWIgcyAhaSAoIWogLSAhaSArIDEpXG4gIGVsc2VcbiAgICBlbXB0eVxuXG5sZXQgZXNjYXBlZCBzID1cbiAgbGV0IG4gPSByZWYgMCBpblxuICBmb3IgaSA9IDAgdG8gbGVuZ3RoIHMgLSAxIGRvXG4gICAgbiA6PSAhbiArXG4gICAgICAobWF0Y2ggdW5zYWZlX2dldCBzIGkgd2l0aFxuICAgICAgIHwgJ1xcXCInIHwgJ1xcXFwnIHwgJ1xcbicgfCAnXFx0JyB8ICdcXHInIHwgJ1xcYicgLT4gMlxuICAgICAgIHwgJyAnIC4uICd+JyAtPiAxXG4gICAgICAgfCBfIC0+IDQpXG4gIGRvbmU7XG4gIGlmICFuID0gbGVuZ3RoIHMgdGhlbiBjb3B5IHMgZWxzZSBiZWdpblxuICAgIGxldCBzJyA9IGNyZWF0ZSAhbiBpblxuICAgIG4gOj0gMDtcbiAgICBmb3IgaSA9IDAgdG8gbGVuZ3RoIHMgLSAxIGRvXG4gICAgICBiZWdpbiBtYXRjaCB1bnNhZmVfZ2V0IHMgaSB3aXRoXG4gICAgICB8ICgnXFxcIicgfCAnXFxcXCcpIGFzIGMgLT5cbiAgICAgICAgICB1bnNhZmVfc2V0IHMnICFuICdcXFxcJzsgaW5jciBuOyB1bnNhZmVfc2V0IHMnICFuIGNcbiAgICAgIHwgJ1xcbicgLT5cbiAgICAgICAgICB1bnNhZmVfc2V0IHMnICFuICdcXFxcJzsgaW5jciBuOyB1bnNhZmVfc2V0IHMnICFuICduJ1xuICAgICAgfCAnXFx0JyAtPlxuICAgICAgICAgIHVuc2FmZV9zZXQgcycgIW4gJ1xcXFwnOyBpbmNyIG47IHVuc2FmZV9zZXQgcycgIW4gJ3QnXG4gICAgICB8ICdcXHInIC0+XG4gICAgICAgICAgdW5zYWZlX3NldCBzJyAhbiAnXFxcXCc7IGluY3IgbjsgdW5zYWZlX3NldCBzJyAhbiAncidcbiAgICAgIHwgJ1xcYicgLT5cbiAgICAgICAgICB1bnNhZmVfc2V0IHMnICFuICdcXFxcJzsgaW5jciBuOyB1bnNhZmVfc2V0IHMnICFuICdiJ1xuICAgICAgfCAoJyAnIC4uICd+JykgYXMgYyAtPiB1bnNhZmVfc2V0IHMnICFuIGNcbiAgICAgIHwgYyAtPlxuICAgICAgICAgIGxldCBhID0gY2hhcl9jb2RlIGMgaW5cbiAgICAgICAgICB1bnNhZmVfc2V0IHMnICFuICdcXFxcJztcbiAgICAgICAgICBpbmNyIG47XG4gICAgICAgICAgdW5zYWZlX3NldCBzJyAhbiAoY2hhcl9jaHIgKDQ4ICsgYSAvIDEwMCkpO1xuICAgICAgICAgIGluY3IgbjtcbiAgICAgICAgICB1bnNhZmVfc2V0IHMnICFuIChjaGFyX2NociAoNDggKyAoYSAvIDEwKSBtb2QgMTApKTtcbiAgICAgICAgICBpbmNyIG47XG4gICAgICAgICAgdW5zYWZlX3NldCBzJyAhbiAoY2hhcl9jaHIgKDQ4ICsgYSBtb2QgMTApKTtcbiAgICAgIGVuZDtcbiAgICAgIGluY3IgblxuICAgIGRvbmU7XG4gICAgcydcbiAgZW5kXG5cbmxldCBtYXAgZiBzID1cbiAgbGV0IGwgPSBsZW5ndGggcyBpblxuICBpZiBsID0gMCB0aGVuIHMgZWxzZSBiZWdpblxuICAgIGxldCByID0gY3JlYXRlIGwgaW5cbiAgICBmb3IgaSA9IDAgdG8gbCAtIDEgZG8gdW5zYWZlX3NldCByIGkgKGYgKHVuc2FmZV9nZXQgcyBpKSkgZG9uZTtcbiAgICByXG4gIGVuZFxuXG5sZXQgbWFwaSBmIHMgPVxuICBsZXQgbCA9IGxlbmd0aCBzIGluXG4gIGlmIGwgPSAwIHRoZW4gcyBlbHNlIGJlZ2luXG4gICAgbGV0IHIgPSBjcmVhdGUgbCBpblxuICAgIGZvciBpID0gMCB0byBsIC0gMSBkbyB1bnNhZmVfc2V0IHIgaSAoZiBpICh1bnNhZmVfZ2V0IHMgaSkpIGRvbmU7XG4gICAgclxuICBlbmRcblxubGV0IGZvbGRfbGVmdCBmIHggYSA9XG4gIGxldCByID0gcmVmIHggaW5cbiAgZm9yIGkgPSAwIHRvIGxlbmd0aCBhIC0gMSBkb1xuICAgIHIgOj0gZiAhciAodW5zYWZlX2dldCBhIGkpXG4gIGRvbmU7XG4gICFyXG5cbmxldCBmb2xkX3JpZ2h0IGYgYSB4ID1cbiAgbGV0IHIgPSByZWYgeCBpblxuICBmb3IgaSA9IGxlbmd0aCBhIC0gMSBkb3dudG8gMCBkb1xuICAgIHIgOj0gZiAodW5zYWZlX2dldCBhIGkpICFyXG4gIGRvbmU7XG4gICFyXG5cbmxldCBleGlzdHMgcCBzID1cbiAgbGV0IG4gPSBsZW5ndGggcyBpblxuICBsZXQgcmVjIGxvb3AgaSA9XG4gICAgaWYgaSA9IG4gdGhlbiBmYWxzZVxuICAgIGVsc2UgaWYgcCAodW5zYWZlX2dldCBzIGkpIHRoZW4gdHJ1ZVxuICAgIGVsc2UgbG9vcCAoc3VjYyBpKSBpblxuICBsb29wIDBcblxubGV0IGZvcl9hbGwgcCBzID1cbiAgbGV0IG4gPSBsZW5ndGggcyBpblxuICBsZXQgcmVjIGxvb3AgaSA9XG4gICAgaWYgaSA9IG4gdGhlbiB0cnVlXG4gICAgZWxzZSBpZiBwICh1bnNhZmVfZ2V0IHMgaSkgdGhlbiBsb29wIChzdWNjIGkpXG4gICAgZWxzZSBmYWxzZSBpblxuICBsb29wIDBcblxubGV0IHVwcGVyY2FzZV9hc2NpaSBzID0gbWFwIENoYXIudXBwZXJjYXNlX2FzY2lpIHNcbmxldCBsb3dlcmNhc2VfYXNjaWkgcyA9IG1hcCBDaGFyLmxvd2VyY2FzZV9hc2NpaSBzXG5cbmxldCBhcHBseTEgZiBzID1cbiAgaWYgbGVuZ3RoIHMgPSAwIHRoZW4gcyBlbHNlIGJlZ2luXG4gICAgbGV0IHIgPSBjb3B5IHMgaW5cbiAgICB1bnNhZmVfc2V0IHIgMCAoZih1bnNhZmVfZ2V0IHMgMCkpO1xuICAgIHJcbiAgZW5kXG5cbmxldCBjYXBpdGFsaXplX2FzY2lpIHMgPSBhcHBseTEgQ2hhci51cHBlcmNhc2VfYXNjaWkgc1xubGV0IHVuY2FwaXRhbGl6ZV9hc2NpaSBzID0gYXBwbHkxIENoYXIubG93ZXJjYXNlX2FzY2lpIHNcblxuKCogZHVwbGljYXRlZCBpbiBzdHJpbmcubWwgKilcbmxldCBzdGFydHNfd2l0aCB+cHJlZml4IHMgPVxuICBsZXQgbGVuX3MgPSBsZW5ndGggc1xuICBhbmQgbGVuX3ByZSA9IGxlbmd0aCBwcmVmaXggaW5cbiAgbGV0IHJlYyBhdXggaSA9XG4gICAgaWYgaSA9IGxlbl9wcmUgdGhlbiB0cnVlXG4gICAgZWxzZSBpZiB1bnNhZmVfZ2V0IHMgaSA8PiB1bnNhZmVfZ2V0IHByZWZpeCBpIHRoZW4gZmFsc2VcbiAgICBlbHNlIGF1eCAoaSArIDEpXG4gIGluIGxlbl9zID49IGxlbl9wcmUgJiYgYXV4IDBcblxuKCogZHVwbGljYXRlZCBpbiBzdHJpbmcubWwgKilcbmxldCBlbmRzX3dpdGggfnN1ZmZpeCBzID1cbiAgbGV0IGxlbl9zID0gbGVuZ3RoIHNcbiAgYW5kIGxlbl9zdWYgPSBsZW5ndGggc3VmZml4IGluXG4gIGxldCBkaWZmID0gbGVuX3MgLSBsZW5fc3VmIGluXG4gIGxldCByZWMgYXV4IGkgPVxuICAgIGlmIGkgPSBsZW5fc3VmIHRoZW4gdHJ1ZVxuICAgIGVsc2UgaWYgdW5zYWZlX2dldCBzIChkaWZmICsgaSkgPD4gdW5zYWZlX2dldCBzdWZmaXggaSB0aGVuIGZhbHNlXG4gICAgZWxzZSBhdXggKGkgKyAxKVxuICBpbiBkaWZmID49IDAgJiYgYXV4IDBcblxuKCogZHVwbGljYXRlZCBpbiBzdHJpbmcubWwgKilcbmxldCByZWMgaW5kZXhfcmVjIHMgbGltIGkgYyA9XG4gIGlmIGkgPj0gbGltIHRoZW4gcmFpc2UgTm90X2ZvdW5kIGVsc2VcbiAgaWYgdW5zYWZlX2dldCBzIGkgPSBjIHRoZW4gaSBlbHNlIGluZGV4X3JlYyBzIGxpbSAoaSArIDEpIGNcblxuKCogZHVwbGljYXRlZCBpbiBzdHJpbmcubWwgKilcbmxldCBpbmRleCBzIGMgPSBpbmRleF9yZWMgcyAobGVuZ3RoIHMpIDAgY1xuXG4oKiBkdXBsaWNhdGVkIGluIHN0cmluZy5tbCAqKVxubGV0IHJlYyBpbmRleF9yZWNfb3B0IHMgbGltIGkgYyA9XG4gIGlmIGkgPj0gbGltIHRoZW4gTm9uZSBlbHNlXG4gIGlmIHVuc2FmZV9nZXQgcyBpID0gYyB0aGVuIFNvbWUgaSBlbHNlIGluZGV4X3JlY19vcHQgcyBsaW0gKGkgKyAxKSBjXG5cbigqIGR1cGxpY2F0ZWQgaW4gc3RyaW5nLm1sICopXG5sZXQgaW5kZXhfb3B0IHMgYyA9IGluZGV4X3JlY19vcHQgcyAobGVuZ3RoIHMpIDAgY1xuXG4oKiBkdXBsaWNhdGVkIGluIHN0cmluZy5tbCAqKVxubGV0IGluZGV4X2Zyb20gcyBpIGMgPVxuICBsZXQgbCA9IGxlbmd0aCBzIGluXG4gIGlmIGkgPCAwIHx8IGkgPiBsIHRoZW4gaW52YWxpZF9hcmcgXCJTdHJpbmcuaW5kZXhfZnJvbSAvIEJ5dGVzLmluZGV4X2Zyb21cIiBlbHNlXG4gIGluZGV4X3JlYyBzIGwgaSBjXG5cbigqIGR1cGxpY2F0ZWQgaW4gc3RyaW5nLm1sICopXG5sZXQgaW5kZXhfZnJvbV9vcHQgcyBpIGMgPVxuICBsZXQgbCA9IGxlbmd0aCBzIGluXG4gIGlmIGkgPCAwIHx8IGkgPiBsIHRoZW5cbiAgICBpbnZhbGlkX2FyZyBcIlN0cmluZy5pbmRleF9mcm9tX29wdCAvIEJ5dGVzLmluZGV4X2Zyb21fb3B0XCJcbiAgZWxzZVxuICAgIGluZGV4X3JlY19vcHQgcyBsIGkgY1xuXG4oKiBkdXBsaWNhdGVkIGluIHN0cmluZy5tbCAqKVxubGV0IHJlYyByaW5kZXhfcmVjIHMgaSBjID1cbiAgaWYgaSA8IDAgdGhlbiByYWlzZSBOb3RfZm91bmQgZWxzZVxuICBpZiB1bnNhZmVfZ2V0IHMgaSA9IGMgdGhlbiBpIGVsc2UgcmluZGV4X3JlYyBzIChpIC0gMSkgY1xuXG4oKiBkdXBsaWNhdGVkIGluIHN0cmluZy5tbCAqKVxubGV0IHJpbmRleCBzIGMgPSByaW5kZXhfcmVjIHMgKGxlbmd0aCBzIC0gMSkgY1xuXG4oKiBkdXBsaWNhdGVkIGluIHN0cmluZy5tbCAqKVxubGV0IHJpbmRleF9mcm9tIHMgaSBjID1cbiAgaWYgaSA8IC0xIHx8IGkgPj0gbGVuZ3RoIHMgdGhlblxuICAgIGludmFsaWRfYXJnIFwiU3RyaW5nLnJpbmRleF9mcm9tIC8gQnl0ZXMucmluZGV4X2Zyb21cIlxuICBlbHNlXG4gICAgcmluZGV4X3JlYyBzIGkgY1xuXG4oKiBkdXBsaWNhdGVkIGluIHN0cmluZy5tbCAqKVxubGV0IHJlYyByaW5kZXhfcmVjX29wdCBzIGkgYyA9XG4gIGlmIGkgPCAwIHRoZW4gTm9uZSBlbHNlXG4gIGlmIHVuc2FmZV9nZXQgcyBpID0gYyB0aGVuIFNvbWUgaSBlbHNlIHJpbmRleF9yZWNfb3B0IHMgKGkgLSAxKSBjXG5cbigqIGR1cGxpY2F0ZWQgaW4gc3RyaW5nLm1sICopXG5sZXQgcmluZGV4X29wdCBzIGMgPSByaW5kZXhfcmVjX29wdCBzIChsZW5ndGggcyAtIDEpIGNcblxuKCogZHVwbGljYXRlZCBpbiBzdHJpbmcubWwgKilcbmxldCByaW5kZXhfZnJvbV9vcHQgcyBpIGMgPVxuICBpZiBpIDwgLTEgfHwgaSA+PSBsZW5ndGggcyB0aGVuXG4gICAgaW52YWxpZF9hcmcgXCJTdHJpbmcucmluZGV4X2Zyb21fb3B0IC8gQnl0ZXMucmluZGV4X2Zyb21fb3B0XCJcbiAgZWxzZVxuICAgIHJpbmRleF9yZWNfb3B0IHMgaSBjXG5cblxuKCogZHVwbGljYXRlZCBpbiBzdHJpbmcubWwgKilcbmxldCBjb250YWluc19mcm9tIHMgaSBjID1cbiAgbGV0IGwgPSBsZW5ndGggcyBpblxuICBpZiBpIDwgMCB8fCBpID4gbCB0aGVuXG4gICAgaW52YWxpZF9hcmcgXCJTdHJpbmcuY29udGFpbnNfZnJvbSAvIEJ5dGVzLmNvbnRhaW5zX2Zyb21cIlxuICBlbHNlXG4gICAgdHJ5IGlnbm9yZSAoaW5kZXhfcmVjIHMgbCBpIGMpOyB0cnVlIHdpdGggTm90X2ZvdW5kIC0+IGZhbHNlXG5cblxuKCogZHVwbGljYXRlZCBpbiBzdHJpbmcubWwgKilcbmxldCBjb250YWlucyBzIGMgPSBjb250YWluc19mcm9tIHMgMCBjXG5cbigqIGR1cGxpY2F0ZWQgaW4gc3RyaW5nLm1sICopXG5sZXQgcmNvbnRhaW5zX2Zyb20gcyBpIGMgPVxuICBpZiBpIDwgMCB8fCBpID49IGxlbmd0aCBzIHRoZW5cbiAgICBpbnZhbGlkX2FyZyBcIlN0cmluZy5yY29udGFpbnNfZnJvbSAvIEJ5dGVzLnJjb250YWluc19mcm9tXCJcbiAgZWxzZVxuICAgIHRyeSBpZ25vcmUgKHJpbmRleF9yZWMgcyBpIGMpOyB0cnVlIHdpdGggTm90X2ZvdW5kIC0+IGZhbHNlXG5cblxudHlwZSB0ID0gYnl0ZXNcblxubGV0IGNvbXBhcmUgKHg6IHQpICh5OiB0KSA9IFN0ZGxpYi5jb21wYXJlIHggeVxuZXh0ZXJuYWwgZXF1YWwgOiB0IC0+IHQgLT4gYm9vbCA9IFwiY2FtbF9ieXRlc19lcXVhbFwiIFtAQG5vYWxsb2NdXG5cbigqIGR1cGxpY2F0ZWQgaW4gc3RyaW5nLm1sICopXG5sZXQgc3BsaXRfb25fY2hhciBzZXAgcyA9XG4gIGxldCByID0gcmVmIFtdIGluXG4gIGxldCBqID0gcmVmIChsZW5ndGggcykgaW5cbiAgZm9yIGkgPSBsZW5ndGggcyAtIDEgZG93bnRvIDAgZG9cbiAgICBpZiB1bnNhZmVfZ2V0IHMgaSA9IHNlcCB0aGVuIGJlZ2luXG4gICAgICByIDo9IHN1YiBzIChpICsgMSkgKCFqIC0gaSAtIDEpIDo6ICFyO1xuICAgICAgaiA6PSBpXG4gICAgZW5kXG4gIGRvbmU7XG4gIHN1YiBzIDAgIWogOjogIXJcblxuKCogRGVwcmVjYXRlZCBmdW5jdGlvbnMgaW1wbGVtZW50ZWQgdmlhIG90aGVyIGRlcHJlY2F0ZWQgZnVuY3Rpb25zICopXG5bQEBAb2NhbWwud2FybmluZyBcIi0zXCJdXG5sZXQgdXBwZXJjYXNlIHMgPSBtYXAgQ2hhci51cHBlcmNhc2Ugc1xubGV0IGxvd2VyY2FzZSBzID0gbWFwIENoYXIubG93ZXJjYXNlIHNcblxubGV0IGNhcGl0YWxpemUgcyA9IGFwcGx5MSBDaGFyLnVwcGVyY2FzZSBzXG5sZXQgdW5jYXBpdGFsaXplIHMgPSBhcHBseTEgQ2hhci5sb3dlcmNhc2Ugc1xuXG4oKiogezEgSXRlcmF0b3JzfSAqKVxuXG5sZXQgdG9fc2VxIHMgPVxuICBsZXQgcmVjIGF1eCBpICgpID1cbiAgICBpZiBpID0gbGVuZ3RoIHMgdGhlbiBTZXEuTmlsXG4gICAgZWxzZVxuICAgICAgbGV0IHggPSBnZXQgcyBpIGluXG4gICAgICBTZXEuQ29ucyAoeCwgYXV4IChpKzEpKVxuICBpblxuICBhdXggMFxuXG5sZXQgdG9fc2VxaSBzID1cbiAgbGV0IHJlYyBhdXggaSAoKSA9XG4gICAgaWYgaSA9IGxlbmd0aCBzIHRoZW4gU2VxLk5pbFxuICAgIGVsc2VcbiAgICAgIGxldCB4ID0gZ2V0IHMgaSBpblxuICAgICAgU2VxLkNvbnMgKChpLHgpLCBhdXggKGkrMSkpXG4gIGluXG4gIGF1eCAwXG5cbmxldCBvZl9zZXEgaSA9XG4gIGxldCBuID0gcmVmIDAgaW5cbiAgbGV0IGJ1ZiA9IHJlZiAobWFrZSAyNTYgJ1xcMDAwJykgaW5cbiAgbGV0IHJlc2l6ZSAoKSA9XG4gICAgKCogcmVzaXplICopXG4gICAgbGV0IG5ld19sZW4gPSBJbnQubWluICgyICogbGVuZ3RoICFidWYpIFN5cy5tYXhfc3RyaW5nX2xlbmd0aCBpblxuICAgIGlmIGxlbmd0aCAhYnVmID0gbmV3X2xlbiB0aGVuIGZhaWx3aXRoIFwiQnl0ZXMub2Zfc2VxOiBjYW5ub3QgZ3JvdyBieXRlc1wiO1xuICAgIGxldCBuZXdfYnVmID0gbWFrZSBuZXdfbGVuICdcXDAwMCcgaW5cbiAgICBibGl0ICFidWYgMCBuZXdfYnVmIDAgIW47XG4gICAgYnVmIDo9IG5ld19idWZcbiAgaW5cbiAgU2VxLml0ZXJcbiAgICAoZnVuIGMgLT5cbiAgICAgICBpZiAhbiA9IGxlbmd0aCAhYnVmIHRoZW4gcmVzaXplKCk7XG4gICAgICAgc2V0ICFidWYgIW4gYztcbiAgICAgICBpbmNyIG4pXG4gICAgaTtcbiAgc3ViICFidWYgMCAhblxuXG4oKiogezYgQmluYXJ5IGVuY29kaW5nL2RlY29kaW5nIG9mIGludGVnZXJzfSAqKVxuXG4oKiBUaGUgZ2V0XyBmdW5jdGlvbnMgYXJlIGFsbCBkdXBsaWNhdGVkIGluIHN0cmluZy5tbCAqKVxuXG5leHRlcm5hbCBnZXRfdWludDggOiBieXRlcyAtPiBpbnQgLT4gaW50ID0gXCIlYnl0ZXNfc2FmZV9nZXRcIlxuZXh0ZXJuYWwgZ2V0X3VpbnQxNl9uZSA6IGJ5dGVzIC0+IGludCAtPiBpbnQgPSBcIiVjYW1sX2J5dGVzX2dldDE2XCJcbmV4dGVybmFsIGdldF9pbnQzMl9uZSA6IGJ5dGVzIC0+IGludCAtPiBpbnQzMiA9IFwiJWNhbWxfYnl0ZXNfZ2V0MzJcIlxuZXh0ZXJuYWwgZ2V0X2ludDY0X25lIDogYnl0ZXMgLT4gaW50IC0+IGludDY0ID0gXCIlY2FtbF9ieXRlc19nZXQ2NFwiXG5leHRlcm5hbCBzZXRfaW50OCA6IGJ5dGVzIC0+IGludCAtPiBpbnQgLT4gdW5pdCA9IFwiJWJ5dGVzX3NhZmVfc2V0XCJcbmV4dGVybmFsIHNldF9pbnQxNl9uZSA6IGJ5dGVzIC0+IGludCAtPiBpbnQgLT4gdW5pdCA9IFwiJWNhbWxfYnl0ZXNfc2V0MTZcIlxuZXh0ZXJuYWwgc2V0X2ludDMyX25lIDogYnl0ZXMgLT4gaW50IC0+IGludDMyIC0+IHVuaXQgPSBcIiVjYW1sX2J5dGVzX3NldDMyXCJcbmV4dGVybmFsIHNldF9pbnQ2NF9uZSA6IGJ5dGVzIC0+IGludCAtPiBpbnQ2NCAtPiB1bml0ID0gXCIlY2FtbF9ieXRlc19zZXQ2NFwiXG5leHRlcm5hbCBzd2FwMTYgOiBpbnQgLT4gaW50ID0gXCIlYnN3YXAxNlwiXG5leHRlcm5hbCBzd2FwMzIgOiBpbnQzMiAtPiBpbnQzMiA9IFwiJWJzd2FwX2ludDMyXCJcbmV4dGVybmFsIHN3YXA2NCA6IGludDY0IC0+IGludDY0ID0gXCIlYnN3YXBfaW50NjRcIlxuXG5sZXQgZ2V0X2ludDggYiBpID1cbiAgKChnZXRfdWludDggYiBpKSBsc2wgKFN5cy5pbnRfc2l6ZSAtIDgpKSBhc3IgKFN5cy5pbnRfc2l6ZSAtIDgpXG5cbmxldCBnZXRfdWludDE2X2xlIGIgaSA9XG4gIGlmIFN5cy5iaWdfZW5kaWFuIHRoZW4gc3dhcDE2IChnZXRfdWludDE2X25lIGIgaSlcbiAgZWxzZSBnZXRfdWludDE2X25lIGIgaVxuXG5sZXQgZ2V0X3VpbnQxNl9iZSBiIGkgPVxuICBpZiBub3QgU3lzLmJpZ19lbmRpYW4gdGhlbiBzd2FwMTYgKGdldF91aW50MTZfbmUgYiBpKVxuICBlbHNlIGdldF91aW50MTZfbmUgYiBpXG5cbmxldCBnZXRfaW50MTZfbmUgYiBpID1cbiAgKChnZXRfdWludDE2X25lIGIgaSkgbHNsIChTeXMuaW50X3NpemUgLSAxNikpIGFzciAoU3lzLmludF9zaXplIC0gMTYpXG5cbmxldCBnZXRfaW50MTZfbGUgYiBpID1cbiAgKChnZXRfdWludDE2X2xlIGIgaSkgbHNsIChTeXMuaW50X3NpemUgLSAxNikpIGFzciAoU3lzLmludF9zaXplIC0gMTYpXG5cbmxldCBnZXRfaW50MTZfYmUgYiBpID1cbiAgKChnZXRfdWludDE2X2JlIGIgaSkgbHNsIChTeXMuaW50X3NpemUgLSAxNikpIGFzciAoU3lzLmludF9zaXplIC0gMTYpXG5cbmxldCBnZXRfaW50MzJfbGUgYiBpID1cbiAgaWYgU3lzLmJpZ19lbmRpYW4gdGhlbiBzd2FwMzIgKGdldF9pbnQzMl9uZSBiIGkpXG4gIGVsc2UgZ2V0X2ludDMyX25lIGIgaVxuXG5sZXQgZ2V0X2ludDMyX2JlIGIgaSA9XG4gIGlmIG5vdCBTeXMuYmlnX2VuZGlhbiB0aGVuIHN3YXAzMiAoZ2V0X2ludDMyX25lIGIgaSlcbiAgZWxzZSBnZXRfaW50MzJfbmUgYiBpXG5cbmxldCBnZXRfaW50NjRfbGUgYiBpID1cbiAgaWYgU3lzLmJpZ19lbmRpYW4gdGhlbiBzd2FwNjQgKGdldF9pbnQ2NF9uZSBiIGkpXG4gIGVsc2UgZ2V0X2ludDY0X25lIGIgaVxuXG5sZXQgZ2V0X2ludDY0X2JlIGIgaSA9XG4gIGlmIG5vdCBTeXMuYmlnX2VuZGlhbiB0aGVuIHN3YXA2NCAoZ2V0X2ludDY0X25lIGIgaSlcbiAgZWxzZSBnZXRfaW50NjRfbmUgYiBpXG5cbmxldCBzZXRfaW50MTZfbGUgYiBpIHggPVxuICBpZiBTeXMuYmlnX2VuZGlhbiB0aGVuIHNldF9pbnQxNl9uZSBiIGkgKHN3YXAxNiB4KVxuICBlbHNlIHNldF9pbnQxNl9uZSBiIGkgeFxuXG5sZXQgc2V0X2ludDE2X2JlIGIgaSB4ID1cbiAgaWYgbm90IFN5cy5iaWdfZW5kaWFuIHRoZW4gc2V0X2ludDE2X25lIGIgaSAoc3dhcDE2IHgpXG4gIGVsc2Ugc2V0X2ludDE2X25lIGIgaSB4XG5cbmxldCBzZXRfaW50MzJfbGUgYiBpIHggPVxuICBpZiBTeXMuYmlnX2VuZGlhbiB0aGVuIHNldF9pbnQzMl9uZSBiIGkgKHN3YXAzMiB4KVxuICBlbHNlIHNldF9pbnQzMl9uZSBiIGkgeFxuXG5sZXQgc2V0X2ludDMyX2JlIGIgaSB4ID1cbiAgaWYgbm90IFN5cy5iaWdfZW5kaWFuIHRoZW4gc2V0X2ludDMyX25lIGIgaSAoc3dhcDMyIHgpXG4gIGVsc2Ugc2V0X2ludDMyX25lIGIgaSB4XG5cbmxldCBzZXRfaW50NjRfbGUgYiBpIHggPVxuICBpZiBTeXMuYmlnX2VuZGlhbiB0aGVuIHNldF9pbnQ2NF9uZSBiIGkgKHN3YXA2NCB4KVxuICBlbHNlIHNldF9pbnQ2NF9uZSBiIGkgeFxuXG5sZXQgc2V0X2ludDY0X2JlIGIgaSB4ID1cbiAgaWYgbm90IFN5cy5iaWdfZW5kaWFuIHRoZW4gc2V0X2ludDY0X25lIGIgaSAoc3dhcDY0IHgpXG4gIGVsc2Ugc2V0X2ludDY0X25lIGIgaSB4XG5cbmxldCBzZXRfdWludDggPSBzZXRfaW50OFxubGV0IHNldF91aW50MTZfbmUgPSBzZXRfaW50MTZfbmVcbmxldCBzZXRfdWludDE2X2JlID0gc2V0X2ludDE2X2JlXG5sZXQgc2V0X3VpbnQxNl9sZSA9IHNldF9pbnQxNl9sZVxuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgIERhbWllbiBEb2xpZ2V6LCBwcm9qZXQgR2FsbGl1bSwgSU5SSUEgUm9jcXVlbmNvdXJ0ICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMjAxNCBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0ICAgICAqKVxuKCogICAgIGVuIEF1dG9tYXRpcXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG4oKiBTdHJpbmcgb3BlcmF0aW9ucywgYmFzZWQgb24gYnl0ZSBzZXF1ZW5jZSBvcGVyYXRpb25zICopXG5cbigqIFdBUk5JTkc6IFNvbWUgZnVuY3Rpb25zIGluIHRoaXMgZmlsZSBhcmUgZHVwbGljYXRlZCBpbiBieXRlcy5tbCBmb3JcbiAgIGVmZmljaWVuY3kgcmVhc29ucy4gV2hlbiB5b3UgbW9kaWZ5IHRoZSBvbmUgaW4gdGhpcyBmaWxlIHlvdSBuZWVkIHRvXG4gICBtb2RpZnkgaXRzIGR1cGxpY2F0ZSBpbiBieXRlcy5tbC5cbiAgIFRoZXNlIGZ1bmN0aW9ucyBoYXZlIGEgXCJkdXBsaWNhdGVkXCIgY29tbWVudCBhYm92ZSB0aGVpciBkZWZpbml0aW9uLlxuKilcblxuZXh0ZXJuYWwgbGVuZ3RoIDogc3RyaW5nIC0+IGludCA9IFwiJXN0cmluZ19sZW5ndGhcIlxuZXh0ZXJuYWwgZ2V0IDogc3RyaW5nIC0+IGludCAtPiBjaGFyID0gXCIlc3RyaW5nX3NhZmVfZ2V0XCJcbmV4dGVybmFsIHNldCA6IGJ5dGVzIC0+IGludCAtPiBjaGFyIC0+IHVuaXQgPSBcIiVzdHJpbmdfc2FmZV9zZXRcIlxuZXh0ZXJuYWwgY3JlYXRlIDogaW50IC0+IGJ5dGVzID0gXCJjYW1sX2NyZWF0ZV9zdHJpbmdcIlxuZXh0ZXJuYWwgdW5zYWZlX2dldCA6IHN0cmluZyAtPiBpbnQgLT4gY2hhciA9IFwiJXN0cmluZ191bnNhZmVfZ2V0XCJcbmV4dGVybmFsIHVuc2FmZV9zZXQgOiBieXRlcyAtPiBpbnQgLT4gY2hhciAtPiB1bml0ID0gXCIlc3RyaW5nX3Vuc2FmZV9zZXRcIlxuZXh0ZXJuYWwgdW5zYWZlX2JsaXQgOiBzdHJpbmcgLT4gaW50IC0+ICBieXRlcyAtPiBpbnQgLT4gaW50IC0+IHVuaXRcbiAgICAgICAgICAgICAgICAgICAgID0gXCJjYW1sX2JsaXRfc3RyaW5nXCIgW0BAbm9hbGxvY11cbmV4dGVybmFsIHVuc2FmZV9maWxsIDogYnl0ZXMgLT4gaW50IC0+IGludCAtPiBjaGFyIC0+IHVuaXRcbiAgICAgICAgICAgICAgICAgICAgID0gXCJjYW1sX2ZpbGxfc3RyaW5nXCIgW0BAbm9hbGxvY11cblxubW9kdWxlIEIgPSBCeXRlc1xuXG5sZXQgYnRzID0gQi51bnNhZmVfdG9fc3RyaW5nXG5sZXQgYm9zID0gQi51bnNhZmVfb2Zfc3RyaW5nXG5cbmxldCBtYWtlIG4gYyA9XG4gIEIubWFrZSBuIGMgfD4gYnRzXG5sZXQgaW5pdCBuIGYgPVxuICBCLmluaXQgbiBmIHw+IGJ0c1xubGV0IGVtcHR5ID0gXCJcIlxubGV0IGNvcHkgcyA9XG4gIEIuY29weSAoYm9zIHMpIHw+IGJ0c1xubGV0IG9mX2J5dGVzID0gQi50b19zdHJpbmdcbmxldCB0b19ieXRlcyA9IEIub2Zfc3RyaW5nXG5sZXQgc3ViIHMgb2ZzIGxlbiA9XG4gIEIuc3ViIChib3Mgcykgb2ZzIGxlbiB8PiBidHNcbmxldCBmaWxsID1cbiAgQi5maWxsXG5sZXQgYmxpdCA9XG4gIEIuYmxpdF9zdHJpbmdcblxubGV0IGVuc3VyZV9nZSAoeDppbnQpIHkgPSBpZiB4ID49IHkgdGhlbiB4IGVsc2UgaW52YWxpZF9hcmcgXCJTdHJpbmcuY29uY2F0XCJcblxubGV0IHJlYyBzdW1fbGVuZ3RocyBhY2Mgc2VwbGVuID0gZnVuY3Rpb25cbiAgfCBbXSAtPiBhY2NcbiAgfCBoZCA6OiBbXSAtPiBsZW5ndGggaGQgKyBhY2NcbiAgfCBoZCA6OiB0bCAtPiBzdW1fbGVuZ3RocyAoZW5zdXJlX2dlIChsZW5ndGggaGQgKyBzZXBsZW4gKyBhY2MpIGFjYykgc2VwbGVuIHRsXG5cbmxldCByZWMgdW5zYWZlX2JsaXRzIGRzdCBwb3Mgc2VwIHNlcGxlbiA9IGZ1bmN0aW9uXG4gICAgW10gLT4gZHN0XG4gIHwgaGQgOjogW10gLT5cbiAgICB1bnNhZmVfYmxpdCBoZCAwIGRzdCBwb3MgKGxlbmd0aCBoZCk7IGRzdFxuICB8IGhkIDo6IHRsIC0+XG4gICAgdW5zYWZlX2JsaXQgaGQgMCBkc3QgcG9zIChsZW5ndGggaGQpO1xuICAgIHVuc2FmZV9ibGl0IHNlcCAwIGRzdCAocG9zICsgbGVuZ3RoIGhkKSBzZXBsZW47XG4gICAgdW5zYWZlX2JsaXRzIGRzdCAocG9zICsgbGVuZ3RoIGhkICsgc2VwbGVuKSBzZXAgc2VwbGVuIHRsXG5cbmxldCBjb25jYXQgc2VwID0gZnVuY3Rpb25cbiAgICBbXSAtPiBcIlwiXG4gIHwgbCAtPiBsZXQgc2VwbGVuID0gbGVuZ3RoIHNlcCBpbiBidHMgQEBcbiAgICAgICAgICB1bnNhZmVfYmxpdHNcbiAgICAgICAgICAgIChCLmNyZWF0ZSAoc3VtX2xlbmd0aHMgMCBzZXBsZW4gbCkpXG4gICAgICAgICAgICAwIHNlcCBzZXBsZW4gbFxuXG5sZXQgY2F0ID0gKCBeIClcblxuKCogZHVwbGljYXRlZCBpbiBieXRlcy5tbCAqKVxubGV0IGl0ZXIgZiBzID1cbiAgZm9yIGkgPSAwIHRvIGxlbmd0aCBzIC0gMSBkbyBmICh1bnNhZmVfZ2V0IHMgaSkgZG9uZVxuXG4oKiBkdXBsaWNhdGVkIGluIGJ5dGVzLm1sICopXG5sZXQgaXRlcmkgZiBzID1cbiAgZm9yIGkgPSAwIHRvIGxlbmd0aCBzIC0gMSBkbyBmIGkgKHVuc2FmZV9nZXQgcyBpKSBkb25lXG5cbmxldCBtYXAgZiBzID1cbiAgQi5tYXAgZiAoYm9zIHMpIHw+IGJ0c1xubGV0IG1hcGkgZiBzID1cbiAgQi5tYXBpIGYgKGJvcyBzKSB8PiBidHNcbmxldCBmb2xkX3JpZ2h0IGYgeCBhID1cbiAgQi5mb2xkX3JpZ2h0IGYgKGJvcyB4KSBhXG5sZXQgZm9sZF9sZWZ0IGYgYSB4ID1cbiAgQi5mb2xkX2xlZnQgZiBhIChib3MgeClcbmxldCBleGlzdHMgZiBzID1cbiAgQi5leGlzdHMgZiAoYm9zIHMpXG5sZXQgZm9yX2FsbCBmIHMgPVxuICBCLmZvcl9hbGwgZiAoYm9zIHMpXG5cbigqIEJld2FyZTogd2UgY2Fubm90IHVzZSBCLnRyaW0gb3IgQi5lc2NhcGUgYmVjYXVzZSB0aGV5IGFsd2F5cyBtYWtlIGFcbiAgIGNvcHksIGJ1dCBTdHJpbmcubWxpIHNwZWxscyBvdXQgc29tZSBjYXNlcyB3aGVyZSB3ZSBhcmUgbm90IGFsbG93ZWRcbiAgIHRvIG1ha2UgYSBjb3B5LiAqKVxuXG5sZXQgaXNfc3BhY2UgPSBmdW5jdGlvblxuICB8ICcgJyB8ICdcXDAxMicgfCAnXFxuJyB8ICdcXHInIHwgJ1xcdCcgLT4gdHJ1ZVxuICB8IF8gLT4gZmFsc2VcblxubGV0IHRyaW0gcyA9XG4gIGlmIHMgPSBcIlwiIHRoZW4gc1xuICBlbHNlIGlmIGlzX3NwYWNlICh1bnNhZmVfZ2V0IHMgMCkgfHwgaXNfc3BhY2UgKHVuc2FmZV9nZXQgcyAobGVuZ3RoIHMgLSAxKSlcbiAgICB0aGVuIGJ0cyAoQi50cmltIChib3MgcykpXG4gIGVsc2Ugc1xuXG5sZXQgZXNjYXBlZCBzID1cbiAgbGV0IHJlYyBlc2NhcGVfaWZfbmVlZGVkIHMgbiBpID1cbiAgICBpZiBpID49IG4gdGhlbiBzIGVsc2VcbiAgICAgIG1hdGNoIHVuc2FmZV9nZXQgcyBpIHdpdGhcbiAgICAgIHwgJ1xcXCInIHwgJ1xcXFwnIHwgJ1xcMDAwJy4uJ1xcMDMxJyB8ICdcXDEyNycuLiAnXFwyNTUnIC0+XG4gICAgICAgICAgYnRzIChCLmVzY2FwZWQgKGJvcyBzKSlcbiAgICAgIHwgXyAtPiBlc2NhcGVfaWZfbmVlZGVkIHMgbiAoaSsxKVxuICBpblxuICBlc2NhcGVfaWZfbmVlZGVkIHMgKGxlbmd0aCBzKSAwXG5cbigqIGR1cGxpY2F0ZWQgaW4gYnl0ZXMubWwgKilcbmxldCByZWMgaW5kZXhfcmVjIHMgbGltIGkgYyA9XG4gIGlmIGkgPj0gbGltIHRoZW4gcmFpc2UgTm90X2ZvdW5kIGVsc2VcbiAgaWYgdW5zYWZlX2dldCBzIGkgPSBjIHRoZW4gaSBlbHNlIGluZGV4X3JlYyBzIGxpbSAoaSArIDEpIGNcblxuKCogZHVwbGljYXRlZCBpbiBieXRlcy5tbCAqKVxubGV0IGluZGV4IHMgYyA9IGluZGV4X3JlYyBzIChsZW5ndGggcykgMCBjXG5cbigqIGR1cGxpY2F0ZWQgaW4gYnl0ZXMubWwgKilcbmxldCByZWMgaW5kZXhfcmVjX29wdCBzIGxpbSBpIGMgPVxuICBpZiBpID49IGxpbSB0aGVuIE5vbmUgZWxzZVxuICBpZiB1bnNhZmVfZ2V0IHMgaSA9IGMgdGhlbiBTb21lIGkgZWxzZSBpbmRleF9yZWNfb3B0IHMgbGltIChpICsgMSkgY1xuXG4oKiBkdXBsaWNhdGVkIGluIGJ5dGVzLm1sICopXG5sZXQgaW5kZXhfb3B0IHMgYyA9IGluZGV4X3JlY19vcHQgcyAobGVuZ3RoIHMpIDAgY1xuXG4oKiBkdXBsaWNhdGVkIGluIGJ5dGVzLm1sICopXG5sZXQgaW5kZXhfZnJvbSBzIGkgYyA9XG4gIGxldCBsID0gbGVuZ3RoIHMgaW5cbiAgaWYgaSA8IDAgfHwgaSA+IGwgdGhlbiBpbnZhbGlkX2FyZyBcIlN0cmluZy5pbmRleF9mcm9tIC8gQnl0ZXMuaW5kZXhfZnJvbVwiIGVsc2VcbiAgICBpbmRleF9yZWMgcyBsIGkgY1xuXG4oKiBkdXBsaWNhdGVkIGluIGJ5dGVzLm1sICopXG5sZXQgaW5kZXhfZnJvbV9vcHQgcyBpIGMgPVxuICBsZXQgbCA9IGxlbmd0aCBzIGluXG4gIGlmIGkgPCAwIHx8IGkgPiBsIHRoZW5cbiAgICBpbnZhbGlkX2FyZyBcIlN0cmluZy5pbmRleF9mcm9tX29wdCAvIEJ5dGVzLmluZGV4X2Zyb21fb3B0XCJcbiAgZWxzZVxuICAgIGluZGV4X3JlY19vcHQgcyBsIGkgY1xuXG4oKiBkdXBsaWNhdGVkIGluIGJ5dGVzLm1sICopXG5sZXQgcmVjIHJpbmRleF9yZWMgcyBpIGMgPVxuICBpZiBpIDwgMCB0aGVuIHJhaXNlIE5vdF9mb3VuZCBlbHNlXG4gIGlmIHVuc2FmZV9nZXQgcyBpID0gYyB0aGVuIGkgZWxzZSByaW5kZXhfcmVjIHMgKGkgLSAxKSBjXG5cbigqIGR1cGxpY2F0ZWQgaW4gYnl0ZXMubWwgKilcbmxldCByaW5kZXggcyBjID0gcmluZGV4X3JlYyBzIChsZW5ndGggcyAtIDEpIGNcblxuKCogZHVwbGljYXRlZCBpbiBieXRlcy5tbCAqKVxubGV0IHJpbmRleF9mcm9tIHMgaSBjID1cbiAgaWYgaSA8IC0xIHx8IGkgPj0gbGVuZ3RoIHMgdGhlblxuICAgIGludmFsaWRfYXJnIFwiU3RyaW5nLnJpbmRleF9mcm9tIC8gQnl0ZXMucmluZGV4X2Zyb21cIlxuICBlbHNlXG4gICAgcmluZGV4X3JlYyBzIGkgY1xuXG4oKiBkdXBsaWNhdGVkIGluIGJ5dGVzLm1sICopXG5sZXQgcmVjIHJpbmRleF9yZWNfb3B0IHMgaSBjID1cbiAgaWYgaSA8IDAgdGhlbiBOb25lIGVsc2VcbiAgaWYgdW5zYWZlX2dldCBzIGkgPSBjIHRoZW4gU29tZSBpIGVsc2UgcmluZGV4X3JlY19vcHQgcyAoaSAtIDEpIGNcblxuKCogZHVwbGljYXRlZCBpbiBieXRlcy5tbCAqKVxubGV0IHJpbmRleF9vcHQgcyBjID0gcmluZGV4X3JlY19vcHQgcyAobGVuZ3RoIHMgLSAxKSBjXG5cbigqIGR1cGxpY2F0ZWQgaW4gYnl0ZXMubWwgKilcbmxldCByaW5kZXhfZnJvbV9vcHQgcyBpIGMgPVxuICBpZiBpIDwgLTEgfHwgaSA+PSBsZW5ndGggcyB0aGVuXG4gICAgaW52YWxpZF9hcmcgXCJTdHJpbmcucmluZGV4X2Zyb21fb3B0IC8gQnl0ZXMucmluZGV4X2Zyb21fb3B0XCJcbiAgZWxzZVxuICAgIHJpbmRleF9yZWNfb3B0IHMgaSBjXG5cbigqIGR1cGxpY2F0ZWQgaW4gYnl0ZXMubWwgKilcbmxldCBjb250YWluc19mcm9tIHMgaSBjID1cbiAgbGV0IGwgPSBsZW5ndGggcyBpblxuICBpZiBpIDwgMCB8fCBpID4gbCB0aGVuXG4gICAgaW52YWxpZF9hcmcgXCJTdHJpbmcuY29udGFpbnNfZnJvbSAvIEJ5dGVzLmNvbnRhaW5zX2Zyb21cIlxuICBlbHNlXG4gICAgdHJ5IGlnbm9yZSAoaW5kZXhfcmVjIHMgbCBpIGMpOyB0cnVlIHdpdGggTm90X2ZvdW5kIC0+IGZhbHNlXG5cbigqIGR1cGxpY2F0ZWQgaW4gYnl0ZXMubWwgKilcbmxldCBjb250YWlucyBzIGMgPSBjb250YWluc19mcm9tIHMgMCBjXG5cbigqIGR1cGxpY2F0ZWQgaW4gYnl0ZXMubWwgKilcbmxldCByY29udGFpbnNfZnJvbSBzIGkgYyA9XG4gIGlmIGkgPCAwIHx8IGkgPj0gbGVuZ3RoIHMgdGhlblxuICAgIGludmFsaWRfYXJnIFwiU3RyaW5nLnJjb250YWluc19mcm9tIC8gQnl0ZXMucmNvbnRhaW5zX2Zyb21cIlxuICBlbHNlXG4gICAgdHJ5IGlnbm9yZSAocmluZGV4X3JlYyBzIGkgYyk7IHRydWUgd2l0aCBOb3RfZm91bmQgLT4gZmFsc2VcblxubGV0IHVwcGVyY2FzZV9hc2NpaSBzID1cbiAgQi51cHBlcmNhc2VfYXNjaWkgKGJvcyBzKSB8PiBidHNcbmxldCBsb3dlcmNhc2VfYXNjaWkgcyA9XG4gIEIubG93ZXJjYXNlX2FzY2lpIChib3MgcykgfD4gYnRzXG5sZXQgY2FwaXRhbGl6ZV9hc2NpaSBzID1cbiAgQi5jYXBpdGFsaXplX2FzY2lpIChib3MgcykgfD4gYnRzXG5sZXQgdW5jYXBpdGFsaXplX2FzY2lpIHMgPVxuICBCLnVuY2FwaXRhbGl6ZV9hc2NpaSAoYm9zIHMpIHw+IGJ0c1xuXG4oKiBkdXBsaWNhdGVkIGluIGJ5dGVzLm1sICopXG5sZXQgc3RhcnRzX3dpdGggfnByZWZpeCBzID1cbiAgbGV0IGxlbl9zID0gbGVuZ3RoIHNcbiAgYW5kIGxlbl9wcmUgPSBsZW5ndGggcHJlZml4IGluXG4gIGxldCByZWMgYXV4IGkgPVxuICAgIGlmIGkgPSBsZW5fcHJlIHRoZW4gdHJ1ZVxuICAgIGVsc2UgaWYgdW5zYWZlX2dldCBzIGkgPD4gdW5zYWZlX2dldCBwcmVmaXggaSB0aGVuIGZhbHNlXG4gICAgZWxzZSBhdXggKGkgKyAxKVxuICBpbiBsZW5fcyA+PSBsZW5fcHJlICYmIGF1eCAwXG5cbigqIGR1cGxpY2F0ZWQgaW4gYnl0ZXMubWwgKilcbmxldCBlbmRzX3dpdGggfnN1ZmZpeCBzID1cbiAgbGV0IGxlbl9zID0gbGVuZ3RoIHNcbiAgYW5kIGxlbl9zdWYgPSBsZW5ndGggc3VmZml4IGluXG4gIGxldCBkaWZmID0gbGVuX3MgLSBsZW5fc3VmIGluXG4gIGxldCByZWMgYXV4IGkgPVxuICAgIGlmIGkgPSBsZW5fc3VmIHRoZW4gdHJ1ZVxuICAgIGVsc2UgaWYgdW5zYWZlX2dldCBzIChkaWZmICsgaSkgPD4gdW5zYWZlX2dldCBzdWZmaXggaSB0aGVuIGZhbHNlXG4gICAgZWxzZSBhdXggKGkgKyAxKVxuICBpbiBkaWZmID49IDAgJiYgYXV4IDBcblxuKCogZHVwbGljYXRlZCBpbiBieXRlcy5tbCAqKVxubGV0IHNwbGl0X29uX2NoYXIgc2VwIHMgPVxuICBsZXQgciA9IHJlZiBbXSBpblxuICBsZXQgaiA9IHJlZiAobGVuZ3RoIHMpIGluXG4gIGZvciBpID0gbGVuZ3RoIHMgLSAxIGRvd250byAwIGRvXG4gICAgaWYgdW5zYWZlX2dldCBzIGkgPSBzZXAgdGhlbiBiZWdpblxuICAgICAgciA6PSBzdWIgcyAoaSArIDEpICghaiAtIGkgLSAxKSA6OiAhcjtcbiAgICAgIGogOj0gaVxuICAgIGVuZFxuICBkb25lO1xuICBzdWIgcyAwICFqIDo6ICFyXG5cbigqIERlcHJlY2F0ZWQgZnVuY3Rpb25zIGltcGxlbWVudGVkIHZpYSBvdGhlciBkZXByZWNhdGVkIGZ1bmN0aW9ucyAqKVxuW0BAQG9jYW1sLndhcm5pbmcgXCItM1wiXVxubGV0IHVwcGVyY2FzZSBzID1cbiAgQi51cHBlcmNhc2UgKGJvcyBzKSB8PiBidHNcbmxldCBsb3dlcmNhc2UgcyA9XG4gIEIubG93ZXJjYXNlIChib3MgcykgfD4gYnRzXG5sZXQgY2FwaXRhbGl6ZSBzID1cbiAgQi5jYXBpdGFsaXplIChib3MgcykgfD4gYnRzXG5sZXQgdW5jYXBpdGFsaXplIHMgPVxuICBCLnVuY2FwaXRhbGl6ZSAoYm9zIHMpIHw+IGJ0c1xuXG50eXBlIHQgPSBzdHJpbmdcblxubGV0IGNvbXBhcmUgKHg6IHQpICh5OiB0KSA9IFN0ZGxpYi5jb21wYXJlIHggeVxuZXh0ZXJuYWwgZXF1YWwgOiBzdHJpbmcgLT4gc3RyaW5nIC0+IGJvb2wgPSBcImNhbWxfc3RyaW5nX2VxdWFsXCIgW0BAbm9hbGxvY11cblxuKCoqIHsxIEl0ZXJhdG9yc30gKilcblxubGV0IHRvX3NlcSBzID0gYm9zIHMgfD4gQi50b19zZXFcblxubGV0IHRvX3NlcWkgcyA9IGJvcyBzIHw+IEIudG9fc2VxaVxuXG5sZXQgb2Zfc2VxIGcgPSBCLm9mX3NlcSBnIHw+IGJ0c1xuXG4oKiogezYgQmluYXJ5IGVuY29kaW5nL2RlY29kaW5nIG9mIGludGVnZXJzfSAqKVxuXG5leHRlcm5hbCBnZXRfdWludDggOiBzdHJpbmcgLT4gaW50IC0+IGludCA9IFwiJXN0cmluZ19zYWZlX2dldFwiXG5leHRlcm5hbCBnZXRfdWludDE2X25lIDogc3RyaW5nIC0+IGludCAtPiBpbnQgPSBcIiVjYW1sX3N0cmluZ19nZXQxNlwiXG5leHRlcm5hbCBnZXRfaW50MzJfbmUgOiBzdHJpbmcgLT4gaW50IC0+IGludDMyID0gXCIlY2FtbF9zdHJpbmdfZ2V0MzJcIlxuZXh0ZXJuYWwgZ2V0X2ludDY0X25lIDogc3RyaW5nIC0+IGludCAtPiBpbnQ2NCA9IFwiJWNhbWxfc3RyaW5nX2dldDY0XCJcblxubGV0IGdldF9pbnQ4IHMgaSA9IEIuZ2V0X2ludDggKGJvcyBzKSBpXG5sZXQgZ2V0X3VpbnQxNl9sZSBzIGkgPSBCLmdldF91aW50MTZfbGUgKGJvcyBzKSBpXG5sZXQgZ2V0X3VpbnQxNl9iZSBzIGkgPSBCLmdldF91aW50MTZfYmUgKGJvcyBzKSBpXG5sZXQgZ2V0X2ludDE2X25lIHMgaSA9IEIuZ2V0X2ludDE2X25lIChib3MgcykgaVxubGV0IGdldF9pbnQxNl9sZSBzIGkgPSBCLmdldF9pbnQxNl9sZSAoYm9zIHMpIGlcbmxldCBnZXRfaW50MTZfYmUgcyBpID0gQi5nZXRfaW50MTZfYmUgKGJvcyBzKSBpXG5sZXQgZ2V0X2ludDMyX2xlIHMgaSA9IEIuZ2V0X2ludDMyX2xlIChib3MgcykgaVxubGV0IGdldF9pbnQzMl9iZSBzIGkgPSBCLmdldF9pbnQzMl9iZSAoYm9zIHMpIGlcbmxldCBnZXRfaW50NjRfbGUgcyBpID0gQi5nZXRfaW50NjRfbGUgKGJvcyBzKSBpXG5sZXQgZ2V0X2ludDY0X2JlIHMgaSA9IEIuZ2V0X2ludDY0X2JlIChib3MgcykgaVxuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgVGhlIE9DYW1sIHByb2dyYW1tZXJzICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMjAxOCBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0ICAgICAqKVxuKCogICAgIGVuIEF1dG9tYXRpcXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG50eXBlIHQgPSB1bml0ID0gKClcblxubGV0IGVxdWFsICgpICgpID0gdHJ1ZVxubGV0IGNvbXBhcmUgKCkgKCkgPSAwXG5sZXQgdG9fc3RyaW5nICgpID0gXCIoKVwiXG4iLCIoKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9DYW1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICBYYXZpZXIgTGVyb3ksIHByb2pldCBDcmlzdGFsLCBJTlJJQSBSb2NxdWVuY291cnQgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIENvcHlyaWdodCAxOTk3IEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgICAgICopXG4oKiAgICAgZW4gQXV0b21hdGlxdWUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIEFsbCByaWdodHMgcmVzZXJ2ZWQuICBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mICAgICopXG4oKiAgIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyLjEsIHdpdGggdGhlICAgICAgICAgICopXG4oKiAgIHNwZWNpYWwgZXhjZXB0aW9uIG9uIGxpbmtpbmcgZGVzY3JpYmVkIGluIHRoZSBmaWxlIExJQ0VOU0UuICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG5cbnR5cGUgZXh0ZXJuX2ZsYWdzID1cbiAgICBOb19zaGFyaW5nXG4gIHwgQ2xvc3VyZXNcbiAgfCBDb21wYXRfMzJcbigqIG5vdGU6IHRoaXMgdHlwZSBkZWZpbml0aW9uIGlzIHVzZWQgaW4gJ3J1bnRpbWUvZGVidWdnZXIuYycgKilcblxuZXh0ZXJuYWwgdG9fY2hhbm5lbDogb3V0X2NoYW5uZWwgLT4gJ2EgLT4gZXh0ZXJuX2ZsYWdzIGxpc3QgLT4gdW5pdFxuICAgID0gXCJjYW1sX291dHB1dF92YWx1ZVwiXG5leHRlcm5hbCB0b19ieXRlczogJ2EgLT4gZXh0ZXJuX2ZsYWdzIGxpc3QgLT4gYnl0ZXNcbiAgICA9IFwiY2FtbF9vdXRwdXRfdmFsdWVfdG9fYnl0ZXNcIlxuZXh0ZXJuYWwgdG9fc3RyaW5nOiAnYSAtPiBleHRlcm5fZmxhZ3MgbGlzdCAtPiBzdHJpbmdcbiAgICA9IFwiY2FtbF9vdXRwdXRfdmFsdWVfdG9fc3RyaW5nXCJcbmV4dGVybmFsIHRvX2J1ZmZlcl91bnNhZmU6XG4gICAgICBieXRlcyAtPiBpbnQgLT4gaW50IC0+ICdhIC0+IGV4dGVybl9mbGFncyBsaXN0IC0+IGludFxuICAgID0gXCJjYW1sX291dHB1dF92YWx1ZV90b19idWZmZXJcIlxuXG5sZXQgdG9fYnVmZmVyIGJ1ZmYgb2ZzIGxlbiB2IGZsYWdzID1cbiAgaWYgb2ZzIDwgMCB8fCBsZW4gPCAwIHx8IG9mcyA+IEJ5dGVzLmxlbmd0aCBidWZmIC0gbGVuXG4gIHRoZW4gaW52YWxpZF9hcmcgXCJNYXJzaGFsLnRvX2J1ZmZlcjogc3Vic3RyaW5nIG91dCBvZiBib3VuZHNcIlxuICBlbHNlIHRvX2J1ZmZlcl91bnNhZmUgYnVmZiBvZnMgbGVuIHYgZmxhZ3NcblxuKCogVGhlIGZ1bmN0aW9ucyBiZWxvdyB1c2UgYnl0ZSBzZXF1ZW5jZXMgYXMgaW5wdXQsIG5ldmVyIHVzaW5nIGFueVxuICAgbXV0YXRpb24uIEl0IG1ha2VzIHNlbnNlIHRvIHVzZSBub24tbXV0YXRlZCBbYnl0ZXNdIHJhdGhlciB0aGFuXG4gICBbc3RyaW5nXSwgYmVjYXVzZSB3ZSByZWFsbHkgd29yayB3aXRoIHNlcXVlbmNlcyBvZiBieXRlcywgbm90XG4gICBhIHRleHQgcmVwcmVzZW50YXRpb24uXG4qKVxuXG5leHRlcm5hbCBmcm9tX2NoYW5uZWw6IGluX2NoYW5uZWwgLT4gJ2EgPSBcImNhbWxfaW5wdXRfdmFsdWVcIlxuZXh0ZXJuYWwgZnJvbV9ieXRlc191bnNhZmU6IGJ5dGVzIC0+IGludCAtPiAnYSA9IFwiY2FtbF9pbnB1dF92YWx1ZV9mcm9tX2J5dGVzXCJcbmV4dGVybmFsIGRhdGFfc2l6ZV91bnNhZmU6IGJ5dGVzIC0+IGludCAtPiBpbnQgPSBcImNhbWxfbWFyc2hhbF9kYXRhX3NpemVcIlxuXG5sZXQgaGVhZGVyX3NpemUgPSAyMFxubGV0IGRhdGFfc2l6ZSBidWZmIG9mcyA9XG4gIGlmIG9mcyA8IDAgfHwgb2ZzID4gQnl0ZXMubGVuZ3RoIGJ1ZmYgLSBoZWFkZXJfc2l6ZVxuICB0aGVuIGludmFsaWRfYXJnIFwiTWFyc2hhbC5kYXRhX3NpemVcIlxuICBlbHNlIGRhdGFfc2l6ZV91bnNhZmUgYnVmZiBvZnNcbmxldCB0b3RhbF9zaXplIGJ1ZmYgb2ZzID0gaGVhZGVyX3NpemUgKyBkYXRhX3NpemUgYnVmZiBvZnNcblxubGV0IGZyb21fYnl0ZXMgYnVmZiBvZnMgPVxuICBpZiBvZnMgPCAwIHx8IG9mcyA+IEJ5dGVzLmxlbmd0aCBidWZmIC0gaGVhZGVyX3NpemVcbiAgdGhlbiBpbnZhbGlkX2FyZyBcIk1hcnNoYWwuZnJvbV9ieXRlc1wiXG4gIGVsc2UgYmVnaW5cbiAgICBsZXQgbGVuID0gZGF0YV9zaXplX3Vuc2FmZSBidWZmIG9mcyBpblxuICAgIGlmIG9mcyA+IEJ5dGVzLmxlbmd0aCBidWZmIC0gKGhlYWRlcl9zaXplICsgbGVuKVxuICAgIHRoZW4gaW52YWxpZF9hcmcgXCJNYXJzaGFsLmZyb21fYnl0ZXNcIlxuICAgIGVsc2UgZnJvbV9ieXRlc191bnNhZmUgYnVmZiBvZnNcbiAgZW5kXG5cbmxldCBmcm9tX3N0cmluZyBidWZmIG9mcyA9XG4gICgqIEJ5dGVzLnVuc2FmZV9vZl9zdHJpbmcgaXMgc2FmZSBoZXJlLCBhcyB0aGUgcHJvZHVjZWQgYnl0ZVxuICAgICBzZXF1ZW5jZSBpcyBuZXZlciBtdXRhdGVkICopXG4gIGZyb21fYnl0ZXMgKEJ5dGVzLnVuc2FmZV9vZl9zdHJpbmcgYnVmZikgb2ZzXG4iLCIoKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9DYW1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICBYYXZpZXIgTGVyb3ksIHByb2pldCBDcmlzdGFsLCBJTlJJQSBSb2NxdWVuY291cnQgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIENvcHlyaWdodCAxOTk2IEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgICAgICopXG4oKiAgICAgZW4gQXV0b21hdGlxdWUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIEFsbCByaWdodHMgcmVzZXJ2ZWQuICBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mICAgICopXG4oKiAgIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyLjEsIHdpdGggdGhlICAgICAgICAgICopXG4oKiAgIHNwZWNpYWwgZXhjZXB0aW9uIG9uIGxpbmtpbmcgZGVzY3JpYmVkIGluIHRoZSBmaWxlIExJQ0VOU0UuICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG5cbigqIE9wZXJhdGlvbnMgb24gaW50ZXJuYWwgcmVwcmVzZW50YXRpb25zIG9mIHZhbHVlcyAqKVxuXG50eXBlIHRcblxudHlwZSByYXdfZGF0YSA9IG5hdGl2ZWludFxuXG5leHRlcm5hbCByZXByIDogJ2EgLT4gdCA9IFwiJWlkZW50aXR5XCJcbmV4dGVybmFsIG9iaiA6IHQgLT4gJ2EgPSBcIiVpZGVudGl0eVwiXG5leHRlcm5hbCBtYWdpYyA6ICdhIC0+ICdiID0gXCIlaWRlbnRpdHlcIlxuZXh0ZXJuYWwgaXNfaW50IDogdCAtPiBib29sID0gXCIlb2JqX2lzX2ludFwiXG5sZXQgW0BpbmxpbmUgYWx3YXlzXSBpc19ibG9jayBhID0gbm90IChpc19pbnQgYSlcbmV4dGVybmFsIHRhZyA6IHQgLT4gaW50ID0gXCJjYW1sX29ial90YWdcIiBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgc2V0X3RhZyA6IHQgLT4gaW50IC0+IHVuaXQgPSBcImNhbWxfb2JqX3NldF90YWdcIlxuZXh0ZXJuYWwgc2l6ZSA6IHQgLT4gaW50ID0gXCIlb2JqX3NpemVcIlxuZXh0ZXJuYWwgcmVhY2hhYmxlX3dvcmRzIDogdCAtPiBpbnQgPSBcImNhbWxfb2JqX3JlYWNoYWJsZV93b3Jkc1wiXG5leHRlcm5hbCBmaWVsZCA6IHQgLT4gaW50IC0+IHQgPSBcIiVvYmpfZmllbGRcIlxuZXh0ZXJuYWwgc2V0X2ZpZWxkIDogdCAtPiBpbnQgLT4gdCAtPiB1bml0ID0gXCIlb2JqX3NldF9maWVsZFwiXG5leHRlcm5hbCBmbG9hdGFycmF5X2dldCA6IGZsb2F0YXJyYXkgLT4gaW50IC0+IGZsb2F0ID0gXCJjYW1sX2Zsb2F0YXJyYXlfZ2V0XCJcbmV4dGVybmFsIGZsb2F0YXJyYXlfc2V0IDpcbiAgICBmbG9hdGFycmF5IC0+IGludCAtPiBmbG9hdCAtPiB1bml0ID0gXCJjYW1sX2Zsb2F0YXJyYXlfc2V0XCJcbmxldCBbQGlubGluZSBhbHdheXNdIGRvdWJsZV9maWVsZCB4IGkgPSBmbG9hdGFycmF5X2dldCAob2JqIHggOiBmbG9hdGFycmF5KSBpXG5sZXQgW0BpbmxpbmUgYWx3YXlzXSBzZXRfZG91YmxlX2ZpZWxkIHggaSB2ID1cbiAgZmxvYXRhcnJheV9zZXQgKG9iaiB4IDogZmxvYXRhcnJheSkgaSB2XG5leHRlcm5hbCByYXdfZmllbGQgOiB0IC0+IGludCAtPiByYXdfZGF0YSA9IFwiY2FtbF9vYmpfcmF3X2ZpZWxkXCJcbmV4dGVybmFsIHNldF9yYXdfZmllbGQgOiB0IC0+IGludCAtPiByYXdfZGF0YSAtPiB1bml0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IFwiY2FtbF9vYmpfc2V0X3Jhd19maWVsZFwiXG5cbmV4dGVybmFsIG5ld19ibG9jayA6IGludCAtPiBpbnQgLT4gdCA9IFwiY2FtbF9vYmpfYmxvY2tcIlxuZXh0ZXJuYWwgZHVwIDogdCAtPiB0ID0gXCJjYW1sX29ial9kdXBcIlxuZXh0ZXJuYWwgdHJ1bmNhdGUgOiB0IC0+IGludCAtPiB1bml0ID0gXCJjYW1sX29ial90cnVuY2F0ZVwiXG5leHRlcm5hbCBhZGRfb2Zmc2V0IDogdCAtPiBJbnQzMi50IC0+IHQgPSBcImNhbWxfb2JqX2FkZF9vZmZzZXRcIlxuZXh0ZXJuYWwgd2l0aF90YWcgOiBpbnQgLT4gdCAtPiB0ID0gXCJjYW1sX29ial93aXRoX3RhZ1wiXG5cbmxldCBtYXJzaGFsIChvYmogOiB0KSA9XG4gIE1hcnNoYWwudG9fYnl0ZXMgb2JqIFtdXG5sZXQgdW5tYXJzaGFsIHN0ciBwb3MgPVxuICAoTWFyc2hhbC5mcm9tX2J5dGVzIHN0ciBwb3MsIHBvcyArIE1hcnNoYWwudG90YWxfc2l6ZSBzdHIgcG9zKVxuXG5sZXQgZmlyc3Rfbm9uX2NvbnN0YW50X2NvbnN0cnVjdG9yX3RhZyA9IDBcbmxldCBsYXN0X25vbl9jb25zdGFudF9jb25zdHJ1Y3Rvcl90YWcgPSAyNDVcblxubGV0IGxhenlfdGFnID0gMjQ2XG5sZXQgY2xvc3VyZV90YWcgPSAyNDdcbmxldCBvYmplY3RfdGFnID0gMjQ4XG5sZXQgaW5maXhfdGFnID0gMjQ5XG5sZXQgZm9yd2FyZF90YWcgPSAyNTBcblxubGV0IG5vX3NjYW5fdGFnID0gMjUxXG5cbmxldCBhYnN0cmFjdF90YWcgPSAyNTFcbmxldCBzdHJpbmdfdGFnID0gMjUyXG5sZXQgZG91YmxlX3RhZyA9IDI1M1xubGV0IGRvdWJsZV9hcnJheV90YWcgPSAyNTRcbmxldCBjdXN0b21fdGFnID0gMjU1XG5sZXQgZmluYWxfdGFnID0gY3VzdG9tX3RhZ1xuXG5cbmxldCBpbnRfdGFnID0gMTAwMFxubGV0IG91dF9vZl9oZWFwX3RhZyA9IDEwMDFcbmxldCB1bmFsaWduZWRfdGFnID0gMTAwMlxuXG5tb2R1bGUgQ2xvc3VyZSA9IHN0cnVjdFxuICB0eXBlIGluZm8gPSB7XG4gICAgYXJpdHk6IGludDtcbiAgICBzdGFydF9lbnY6IGludDtcbiAgfVxuXG4gIGxldCBpbmZvX29mX3JhdyAoaW5mbyA6IG5hdGl2ZWludCkgPVxuICAgIGxldCBvcGVuIE5hdGl2ZWludCBpblxuICAgIGxldCBhcml0eSA9XG4gICAgICAoKiBzaWduZWQ6IG5lZ2F0aXZlIGZvciB0dXBsZWQgZnVuY3Rpb25zICopXG4gICAgICBpZiBTeXMud29yZF9zaXplID0gNjQgdGhlblxuICAgICAgICB0b19pbnQgKHNoaWZ0X3JpZ2h0IGluZm8gNTYpXG4gICAgICBlbHNlXG4gICAgICAgIHRvX2ludCAoc2hpZnRfcmlnaHQgaW5mbyAyNClcbiAgICBpblxuICAgIGxldCBzdGFydF9lbnYgPVxuICAgICAgKCogc3RhcnRfZW52IGlzIHVuc2lnbmVkLCBidXQgd2Uga25vdyBpdCBjYW4gYWx3YXlzIGZpdCBhbiBPQ2FtbFxuICAgICAgICAgaW50ZWdlciBzbyB3ZSB1c2UgW3RvX2ludF0gaW5zdGVhZCBvZiBbdW5zaWduZWRfdG9faW50XS4gKilcbiAgICAgIHRvX2ludCAoc2hpZnRfcmlnaHRfbG9naWNhbCAoc2hpZnRfbGVmdCBpbmZvIDgpIDkpIGluXG4gICAgeyBhcml0eTsgc3RhcnRfZW52IH1cblxuICAoKiBub3RlOiB3ZSBleHBlY3QgYSBjbG9zdXJlLCBub3QgYW4gaW5maXggcG9pbnRlciAqKVxuICBsZXQgaW5mbyAob2JqIDogdCkgPVxuICAgIGFzc2VydCAodGFnIG9iaiA9IGNsb3N1cmVfdGFnKTtcbiAgICBpbmZvX29mX3JhdyAocmF3X2ZpZWxkIG9iaiAxKVxuZW5kXG5cbm1vZHVsZSBFeHRlbnNpb25fY29uc3RydWN0b3IgPVxuc3RydWN0XG4gIHR5cGUgdCA9IGV4dGVuc2lvbl9jb25zdHJ1Y3RvclxuICBsZXQgb2ZfdmFsIHggPVxuICAgIGxldCB4ID0gcmVwciB4IGluXG4gICAgbGV0IHNsb3QgPVxuICAgICAgaWYgKGlzX2Jsb2NrIHgpICYmICh0YWcgeCkgPD4gb2JqZWN0X3RhZyAmJiAoc2l6ZSB4KSA+PSAxIHRoZW4gZmllbGQgeCAwXG4gICAgICBlbHNlIHhcbiAgICBpblxuICAgIGxldCBuYW1lID1cbiAgICAgIGlmIChpc19ibG9jayBzbG90KSAmJiAodGFnIHNsb3QpID0gb2JqZWN0X3RhZyB0aGVuIGZpZWxkIHNsb3QgMFxuICAgICAgZWxzZSBpbnZhbGlkX2FyZyBcIk9iai5leHRlbnNpb25fY29uc3RydWN0b3JcIlxuICAgIGluXG4gICAgICBpZiAodGFnIG5hbWUpID0gc3RyaW5nX3RhZyB0aGVuIChvYmogc2xvdCA6IHQpXG4gICAgICBlbHNlIGludmFsaWRfYXJnIFwiT2JqLmV4dGVuc2lvbl9jb25zdHJ1Y3RvclwiXG5cbiAgbGV0IFtAaW5saW5lIGFsd2F5c10gbmFtZSAoc2xvdCA6IHQpID1cbiAgICAob2JqIChmaWVsZCAocmVwciBzbG90KSAwKSA6IHN0cmluZylcblxuICBsZXQgW0BpbmxpbmUgYWx3YXlzXSBpZCAoc2xvdCA6IHQpID1cbiAgICAob2JqIChmaWVsZCAocmVwciBzbG90KSAxKSA6IGludClcbmVuZFxuXG5sZXQgZXh0ZW5zaW9uX2NvbnN0cnVjdG9yID0gRXh0ZW5zaW9uX2NvbnN0cnVjdG9yLm9mX3ZhbFxubGV0IGV4dGVuc2lvbl9uYW1lID0gRXh0ZW5zaW9uX2NvbnN0cnVjdG9yLm5hbWVcbmxldCBleHRlbnNpb25faWQgPSBFeHRlbnNpb25fY29uc3RydWN0b3IuaWRcblxubW9kdWxlIEVwaGVtZXJvbiA9IHN0cnVjdFxuICB0eXBlIG9ial90ID0gdFxuXG4gIHR5cGUgdCAoKiogZXBoZW1lcm9uICopXG5cbiAgICgqKiBUbyBjaGFuZ2UgaW4gc3luYyB3aXRoIHdlYWsuaCAqKVxuICBsZXQgYWRkaXRpb25hbF92YWx1ZXMgPSAyXG4gIGxldCBtYXhfZXBoZV9sZW5ndGggPSBTeXMubWF4X2FycmF5X2xlbmd0aCAtIGFkZGl0aW9uYWxfdmFsdWVzXG5cbiAgZXh0ZXJuYWwgY3JlYXRlIDogaW50IC0+IHQgPSBcImNhbWxfZXBoZV9jcmVhdGVcIjs7XG4gIGxldCBjcmVhdGUgbCA9XG4gICAgaWYgbm90ICgwIDw9IGwgJiYgbCA8PSBtYXhfZXBoZV9sZW5ndGgpIHRoZW5cbiAgICAgIGludmFsaWRfYXJnIFwiT2JqLkVwaGVtZXJvbi5jcmVhdGVcIjtcbiAgICBjcmVhdGUgbFxuXG4gIGxldCBsZW5ndGggeCA9IHNpemUocmVwciB4KSAtIGFkZGl0aW9uYWxfdmFsdWVzXG5cbiAgbGV0IHJhaXNlX2lmX2ludmFsaWRfb2Zmc2V0IGUgbyBtc2cgPVxuICAgIGlmIG5vdCAoMCA8PSBvICYmIG8gPCBsZW5ndGggZSkgdGhlblxuICAgICAgaW52YWxpZF9hcmcgbXNnXG5cbiAgZXh0ZXJuYWwgZ2V0X2tleTogdCAtPiBpbnQgLT4gb2JqX3Qgb3B0aW9uID0gXCJjYW1sX2VwaGVfZ2V0X2tleVwiXG4gIGxldCBnZXRfa2V5IGUgbyA9XG4gICAgcmFpc2VfaWZfaW52YWxpZF9vZmZzZXQgZSBvIFwiT2JqLkVwaGVtZXJvbi5nZXRfa2V5XCI7XG4gICAgZ2V0X2tleSBlIG9cblxuICBleHRlcm5hbCBnZXRfa2V5X2NvcHk6IHQgLT4gaW50IC0+IG9ial90IG9wdGlvbiA9IFwiY2FtbF9lcGhlX2dldF9rZXlfY29weVwiXG4gIGxldCBnZXRfa2V5X2NvcHkgZSBvID1cbiAgICByYWlzZV9pZl9pbnZhbGlkX29mZnNldCBlIG8gXCJPYmouRXBoZW1lcm9uLmdldF9rZXlfY29weVwiO1xuICAgIGdldF9rZXlfY29weSBlIG9cblxuICBleHRlcm5hbCBzZXRfa2V5OiB0IC0+IGludCAtPiBvYmpfdCAtPiB1bml0ID0gXCJjYW1sX2VwaGVfc2V0X2tleVwiXG4gIGxldCBzZXRfa2V5IGUgbyB4ID1cbiAgICByYWlzZV9pZl9pbnZhbGlkX29mZnNldCBlIG8gXCJPYmouRXBoZW1lcm9uLnNldF9rZXlcIjtcbiAgICBzZXRfa2V5IGUgbyB4XG5cbiAgZXh0ZXJuYWwgdW5zZXRfa2V5OiB0IC0+IGludCAtPiB1bml0ID0gXCJjYW1sX2VwaGVfdW5zZXRfa2V5XCJcbiAgbGV0IHVuc2V0X2tleSBlIG8gPVxuICAgIHJhaXNlX2lmX2ludmFsaWRfb2Zmc2V0IGUgbyBcIk9iai5FcGhlbWVyb24udW5zZXRfa2V5XCI7XG4gICAgdW5zZXRfa2V5IGUgb1xuXG4gIGV4dGVybmFsIGNoZWNrX2tleTogdCAtPiBpbnQgLT4gYm9vbCA9IFwiY2FtbF9lcGhlX2NoZWNrX2tleVwiXG4gIGxldCBjaGVja19rZXkgZSBvID1cbiAgICByYWlzZV9pZl9pbnZhbGlkX29mZnNldCBlIG8gXCJPYmouRXBoZW1lcm9uLmNoZWNrX2tleVwiO1xuICAgIGNoZWNrX2tleSBlIG9cblxuICBleHRlcm5hbCBibGl0X2tleSA6IHQgLT4gaW50IC0+IHQgLT4gaW50IC0+IGludCAtPiB1bml0XG4gICAgPSBcImNhbWxfZXBoZV9ibGl0X2tleVwiXG5cbiAgbGV0IGJsaXRfa2V5IGUxIG8xIGUyIG8yIGwgPVxuICAgIGlmIGwgPCAwIHx8IG8xIDwgMCB8fCBvMSA+IGxlbmd0aCBlMSAtIGxcbiAgICAgICB8fCBvMiA8IDAgfHwgbzIgPiBsZW5ndGggZTIgLSBsXG4gICAgdGhlbiBpbnZhbGlkX2FyZyBcIk9iai5FcGhlbWVyb24uYmxpdF9rZXlcIlxuICAgIGVsc2UgaWYgbCA8PiAwIHRoZW4gYmxpdF9rZXkgZTEgbzEgZTIgbzIgbFxuXG4gIGV4dGVybmFsIGdldF9kYXRhOiB0IC0+IG9ial90IG9wdGlvbiA9IFwiY2FtbF9lcGhlX2dldF9kYXRhXCJcbiAgZXh0ZXJuYWwgZ2V0X2RhdGFfY29weTogdCAtPiBvYmpfdCBvcHRpb24gPSBcImNhbWxfZXBoZV9nZXRfZGF0YV9jb3B5XCJcbiAgZXh0ZXJuYWwgc2V0X2RhdGE6IHQgLT4gb2JqX3QgLT4gdW5pdCA9IFwiY2FtbF9lcGhlX3NldF9kYXRhXCJcbiAgZXh0ZXJuYWwgdW5zZXRfZGF0YTogdCAtPiB1bml0ID0gXCJjYW1sX2VwaGVfdW5zZXRfZGF0YVwiXG4gIGV4dGVybmFsIGNoZWNrX2RhdGE6IHQgLT4gYm9vbCA9IFwiY2FtbF9lcGhlX2NoZWNrX2RhdGFcIlxuICBleHRlcm5hbCBibGl0X2RhdGEgOiB0IC0+IHQgLT4gdW5pdCA9IFwiY2FtbF9lcGhlX2JsaXRfZGF0YVwiXG5cbmVuZFxuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgWGF2aWVyIExlcm95LCBwcm9qZXQgQ3Jpc3RhbCwgSU5SSUEgUm9jcXVlbmNvdXJ0ICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMTk5NiBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0ICAgICAqKVxuKCogICAgIGVuIEF1dG9tYXRpcXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG4oKiBBbiBhbGlhcyBmb3IgdGhlIHR5cGUgb2YgYXJyYXlzLiAqKVxudHlwZSAnYSB0ID0gJ2EgYXJyYXlcblxuKCogQXJyYXkgb3BlcmF0aW9ucyAqKVxuXG5leHRlcm5hbCBsZW5ndGggOiAnYSBhcnJheSAtPiBpbnQgPSBcIiVhcnJheV9sZW5ndGhcIlxuZXh0ZXJuYWwgZ2V0OiAnYSBhcnJheSAtPiBpbnQgLT4gJ2EgPSBcIiVhcnJheV9zYWZlX2dldFwiXG5leHRlcm5hbCBzZXQ6ICdhIGFycmF5IC0+IGludCAtPiAnYSAtPiB1bml0ID0gXCIlYXJyYXlfc2FmZV9zZXRcIlxuZXh0ZXJuYWwgdW5zYWZlX2dldDogJ2EgYXJyYXkgLT4gaW50IC0+ICdhID0gXCIlYXJyYXlfdW5zYWZlX2dldFwiXG5leHRlcm5hbCB1bnNhZmVfc2V0OiAnYSBhcnJheSAtPiBpbnQgLT4gJ2EgLT4gdW5pdCA9IFwiJWFycmF5X3Vuc2FmZV9zZXRcIlxuZXh0ZXJuYWwgbWFrZTogaW50IC0+ICdhIC0+ICdhIGFycmF5ID0gXCJjYW1sX21ha2VfdmVjdFwiXG5leHRlcm5hbCBjcmVhdGU6IGludCAtPiAnYSAtPiAnYSBhcnJheSA9IFwiY2FtbF9tYWtlX3ZlY3RcIlxuZXh0ZXJuYWwgdW5zYWZlX3N1YiA6ICdhIGFycmF5IC0+IGludCAtPiBpbnQgLT4gJ2EgYXJyYXkgPSBcImNhbWxfYXJyYXlfc3ViXCJcbmV4dGVybmFsIGFwcGVuZF9wcmltIDogJ2EgYXJyYXkgLT4gJ2EgYXJyYXkgLT4gJ2EgYXJyYXkgPSBcImNhbWxfYXJyYXlfYXBwZW5kXCJcbmV4dGVybmFsIGNvbmNhdCA6ICdhIGFycmF5IGxpc3QgLT4gJ2EgYXJyYXkgPSBcImNhbWxfYXJyYXlfY29uY2F0XCJcbmV4dGVybmFsIHVuc2FmZV9ibGl0IDpcbiAgJ2EgYXJyYXkgLT4gaW50IC0+ICdhIGFycmF5IC0+IGludCAtPiBpbnQgLT4gdW5pdCA9IFwiY2FtbF9hcnJheV9ibGl0XCJcbmV4dGVybmFsIHVuc2FmZV9maWxsIDpcbiAgJ2EgYXJyYXkgLT4gaW50IC0+IGludCAtPiAnYSAtPiB1bml0ID0gXCJjYW1sX2FycmF5X2ZpbGxcIlxuZXh0ZXJuYWwgY3JlYXRlX2Zsb2F0OiBpbnQgLT4gZmxvYXQgYXJyYXkgPSBcImNhbWxfbWFrZV9mbG9hdF92ZWN0XCJcbmxldCBtYWtlX2Zsb2F0ID0gY3JlYXRlX2Zsb2F0XG5cbm1vZHVsZSBGbG9hdGFycmF5ID0gc3RydWN0XG4gIGV4dGVybmFsIGNyZWF0ZSA6IGludCAtPiBmbG9hdGFycmF5ID0gXCJjYW1sX2Zsb2F0YXJyYXlfY3JlYXRlXCJcbiAgZXh0ZXJuYWwgbGVuZ3RoIDogZmxvYXRhcnJheSAtPiBpbnQgPSBcIiVmbG9hdGFycmF5X2xlbmd0aFwiXG4gIGV4dGVybmFsIGdldCA6IGZsb2F0YXJyYXkgLT4gaW50IC0+IGZsb2F0ID0gXCIlZmxvYXRhcnJheV9zYWZlX2dldFwiXG4gIGV4dGVybmFsIHNldCA6IGZsb2F0YXJyYXkgLT4gaW50IC0+IGZsb2F0IC0+IHVuaXQgPSBcIiVmbG9hdGFycmF5X3NhZmVfc2V0XCJcbiAgZXh0ZXJuYWwgdW5zYWZlX2dldCA6IGZsb2F0YXJyYXkgLT4gaW50IC0+IGZsb2F0ID0gXCIlZmxvYXRhcnJheV91bnNhZmVfZ2V0XCJcbiAgZXh0ZXJuYWwgdW5zYWZlX3NldCA6IGZsb2F0YXJyYXkgLT4gaW50IC0+IGZsb2F0IC0+IHVuaXRcbiAgICAgID0gXCIlZmxvYXRhcnJheV91bnNhZmVfc2V0XCJcbmVuZFxuXG5sZXQgaW5pdCBsIGYgPVxuICBpZiBsID0gMCB0aGVuIFt8fF0gZWxzZVxuICBpZiBsIDwgMCB0aGVuIGludmFsaWRfYXJnIFwiQXJyYXkuaW5pdFwiXG4gICgqIFNlZSAjNjU3NS4gV2UgY291bGQgYWxzbyBjaGVjayBmb3IgbWF4aW11bSBhcnJheSBzaXplLCBidXQgdGhpcyBkZXBlbmRzXG4gICAgIG9uIHdoZXRoZXIgd2UgY3JlYXRlIGEgZmxvYXQgYXJyYXkgb3IgYSByZWd1bGFyIG9uZS4uLiAqKVxuICBlbHNlXG4gICBsZXQgcmVzID0gY3JlYXRlIGwgKGYgMCkgaW5cbiAgIGZvciBpID0gMSB0byBwcmVkIGwgZG9cbiAgICAgdW5zYWZlX3NldCByZXMgaSAoZiBpKVxuICAgZG9uZTtcbiAgIHJlc1xuXG5sZXQgbWFrZV9tYXRyaXggc3ggc3kgaW5pdCA9XG4gIGxldCByZXMgPSBjcmVhdGUgc3ggW3x8XSBpblxuICBmb3IgeCA9IDAgdG8gcHJlZCBzeCBkb1xuICAgIHVuc2FmZV9zZXQgcmVzIHggKGNyZWF0ZSBzeSBpbml0KVxuICBkb25lO1xuICByZXNcblxubGV0IGNyZWF0ZV9tYXRyaXggPSBtYWtlX21hdHJpeFxuXG5sZXQgY29weSBhID1cbiAgbGV0IGwgPSBsZW5ndGggYSBpbiBpZiBsID0gMCB0aGVuIFt8fF0gZWxzZSB1bnNhZmVfc3ViIGEgMCBsXG5cbmxldCBhcHBlbmQgYTEgYTIgPVxuICBsZXQgbDEgPSBsZW5ndGggYTEgaW5cbiAgaWYgbDEgPSAwIHRoZW4gY29weSBhMlxuICBlbHNlIGlmIGxlbmd0aCBhMiA9IDAgdGhlbiB1bnNhZmVfc3ViIGExIDAgbDFcbiAgZWxzZSBhcHBlbmRfcHJpbSBhMSBhMlxuXG5sZXQgc3ViIGEgb2ZzIGxlbiA9XG4gIGlmIG9mcyA8IDAgfHwgbGVuIDwgMCB8fCBvZnMgPiBsZW5ndGggYSAtIGxlblxuICB0aGVuIGludmFsaWRfYXJnIFwiQXJyYXkuc3ViXCJcbiAgZWxzZSB1bnNhZmVfc3ViIGEgb2ZzIGxlblxuXG5sZXQgZmlsbCBhIG9mcyBsZW4gdiA9XG4gIGlmIG9mcyA8IDAgfHwgbGVuIDwgMCB8fCBvZnMgPiBsZW5ndGggYSAtIGxlblxuICB0aGVuIGludmFsaWRfYXJnIFwiQXJyYXkuZmlsbFwiXG4gIGVsc2UgdW5zYWZlX2ZpbGwgYSBvZnMgbGVuIHZcblxubGV0IGJsaXQgYTEgb2ZzMSBhMiBvZnMyIGxlbiA9XG4gIGlmIGxlbiA8IDAgfHwgb2ZzMSA8IDAgfHwgb2ZzMSA+IGxlbmd0aCBhMSAtIGxlblxuICAgICAgICAgICAgIHx8IG9mczIgPCAwIHx8IG9mczIgPiBsZW5ndGggYTIgLSBsZW5cbiAgdGhlbiBpbnZhbGlkX2FyZyBcIkFycmF5LmJsaXRcIlxuICBlbHNlIHVuc2FmZV9ibGl0IGExIG9mczEgYTIgb2ZzMiBsZW5cblxubGV0IGl0ZXIgZiBhID1cbiAgZm9yIGkgPSAwIHRvIGxlbmd0aCBhIC0gMSBkbyBmKHVuc2FmZV9nZXQgYSBpKSBkb25lXG5cbmxldCBpdGVyMiBmIGEgYiA9XG4gIGlmIGxlbmd0aCBhIDw+IGxlbmd0aCBiIHRoZW5cbiAgICBpbnZhbGlkX2FyZyBcIkFycmF5Lml0ZXIyOiBhcnJheXMgbXVzdCBoYXZlIHRoZSBzYW1lIGxlbmd0aFwiXG4gIGVsc2VcbiAgICBmb3IgaSA9IDAgdG8gbGVuZ3RoIGEgLSAxIGRvIGYgKHVuc2FmZV9nZXQgYSBpKSAodW5zYWZlX2dldCBiIGkpIGRvbmVcblxubGV0IG1hcCBmIGEgPVxuICBsZXQgbCA9IGxlbmd0aCBhIGluXG4gIGlmIGwgPSAwIHRoZW4gW3x8XSBlbHNlIGJlZ2luXG4gICAgbGV0IHIgPSBjcmVhdGUgbCAoZih1bnNhZmVfZ2V0IGEgMCkpIGluXG4gICAgZm9yIGkgPSAxIHRvIGwgLSAxIGRvXG4gICAgICB1bnNhZmVfc2V0IHIgaSAoZih1bnNhZmVfZ2V0IGEgaSkpXG4gICAgZG9uZTtcbiAgICByXG4gIGVuZFxuXG5sZXQgbWFwMiBmIGEgYiA9XG4gIGxldCBsYSA9IGxlbmd0aCBhIGluXG4gIGxldCBsYiA9IGxlbmd0aCBiIGluXG4gIGlmIGxhIDw+IGxiIHRoZW5cbiAgICBpbnZhbGlkX2FyZyBcIkFycmF5Lm1hcDI6IGFycmF5cyBtdXN0IGhhdmUgdGhlIHNhbWUgbGVuZ3RoXCJcbiAgZWxzZSBiZWdpblxuICAgIGlmIGxhID0gMCB0aGVuIFt8fF0gZWxzZSBiZWdpblxuICAgICAgbGV0IHIgPSBjcmVhdGUgbGEgKGYgKHVuc2FmZV9nZXQgYSAwKSAodW5zYWZlX2dldCBiIDApKSBpblxuICAgICAgZm9yIGkgPSAxIHRvIGxhIC0gMSBkb1xuICAgICAgICB1bnNhZmVfc2V0IHIgaSAoZiAodW5zYWZlX2dldCBhIGkpICh1bnNhZmVfZ2V0IGIgaSkpXG4gICAgICBkb25lO1xuICAgICAgclxuICAgIGVuZFxuICBlbmRcblxubGV0IGl0ZXJpIGYgYSA9XG4gIGZvciBpID0gMCB0byBsZW5ndGggYSAtIDEgZG8gZiBpICh1bnNhZmVfZ2V0IGEgaSkgZG9uZVxuXG5sZXQgbWFwaSBmIGEgPVxuICBsZXQgbCA9IGxlbmd0aCBhIGluXG4gIGlmIGwgPSAwIHRoZW4gW3x8XSBlbHNlIGJlZ2luXG4gICAgbGV0IHIgPSBjcmVhdGUgbCAoZiAwICh1bnNhZmVfZ2V0IGEgMCkpIGluXG4gICAgZm9yIGkgPSAxIHRvIGwgLSAxIGRvXG4gICAgICB1bnNhZmVfc2V0IHIgaSAoZiBpICh1bnNhZmVfZ2V0IGEgaSkpXG4gICAgZG9uZTtcbiAgICByXG4gIGVuZFxuXG5sZXQgdG9fbGlzdCBhID1cbiAgbGV0IHJlYyB0b2xpc3QgaSByZXMgPVxuICAgIGlmIGkgPCAwIHRoZW4gcmVzIGVsc2UgdG9saXN0IChpIC0gMSkgKHVuc2FmZV9nZXQgYSBpIDo6IHJlcykgaW5cbiAgdG9saXN0IChsZW5ndGggYSAtIDEpIFtdXG5cbigqIENhbm5vdCB1c2UgTGlzdC5sZW5ndGggaGVyZSBiZWNhdXNlIHRoZSBMaXN0IG1vZHVsZSBkZXBlbmRzIG9uIEFycmF5LiAqKVxubGV0IHJlYyBsaXN0X2xlbmd0aCBhY2N1ID0gZnVuY3Rpb25cbiAgfCBbXSAtPiBhY2N1XG4gIHwgXzo6dCAtPiBsaXN0X2xlbmd0aCAoc3VjYyBhY2N1KSB0XG5cbmxldCBvZl9saXN0ID0gZnVuY3Rpb25cbiAgICBbXSAtPiBbfHxdXG4gIHwgaGQ6OnRsIGFzIGwgLT5cbiAgICAgIGxldCBhID0gY3JlYXRlIChsaXN0X2xlbmd0aCAwIGwpIGhkIGluXG4gICAgICBsZXQgcmVjIGZpbGwgaSA9IGZ1bmN0aW9uXG4gICAgICAgICAgW10gLT4gYVxuICAgICAgICB8IGhkOjp0bCAtPiB1bnNhZmVfc2V0IGEgaSBoZDsgZmlsbCAoaSsxKSB0bCBpblxuICAgICAgZmlsbCAxIHRsXG5cbmxldCBmb2xkX2xlZnQgZiB4IGEgPVxuICBsZXQgciA9IHJlZiB4IGluXG4gIGZvciBpID0gMCB0byBsZW5ndGggYSAtIDEgZG9cbiAgICByIDo9IGYgIXIgKHVuc2FmZV9nZXQgYSBpKVxuICBkb25lO1xuICAhclxuXG5sZXQgZm9sZF9sZWZ0X21hcCBmIGFjYyBpbnB1dF9hcnJheSA9XG4gIGxldCBsZW4gPSBsZW5ndGggaW5wdXRfYXJyYXkgaW5cbiAgaWYgbGVuID0gMCB0aGVuIChhY2MsIFt8fF0pIGVsc2UgYmVnaW5cbiAgICBsZXQgYWNjLCBlbHQgPSBmIGFjYyAodW5zYWZlX2dldCBpbnB1dF9hcnJheSAwKSBpblxuICAgIGxldCBvdXRwdXRfYXJyYXkgPSBjcmVhdGUgbGVuIGVsdCBpblxuICAgIGxldCBhY2MgPSByZWYgYWNjIGluXG4gICAgZm9yIGkgPSAxIHRvIGxlbiAtIDEgZG9cbiAgICAgIGxldCBhY2MnLCBlbHQgPSBmICFhY2MgKHVuc2FmZV9nZXQgaW5wdXRfYXJyYXkgaSkgaW5cbiAgICAgIGFjYyA6PSBhY2MnO1xuICAgICAgdW5zYWZlX3NldCBvdXRwdXRfYXJyYXkgaSBlbHQ7XG4gICAgZG9uZTtcbiAgICAhYWNjLCBvdXRwdXRfYXJyYXlcbiAgZW5kXG5cbmxldCBmb2xkX3JpZ2h0IGYgYSB4ID1cbiAgbGV0IHIgPSByZWYgeCBpblxuICBmb3IgaSA9IGxlbmd0aCBhIC0gMSBkb3dudG8gMCBkb1xuICAgIHIgOj0gZiAodW5zYWZlX2dldCBhIGkpICFyXG4gIGRvbmU7XG4gICFyXG5cbmxldCBleGlzdHMgcCBhID1cbiAgbGV0IG4gPSBsZW5ndGggYSBpblxuICBsZXQgcmVjIGxvb3AgaSA9XG4gICAgaWYgaSA9IG4gdGhlbiBmYWxzZVxuICAgIGVsc2UgaWYgcCAodW5zYWZlX2dldCBhIGkpIHRoZW4gdHJ1ZVxuICAgIGVsc2UgbG9vcCAoc3VjYyBpKSBpblxuICBsb29wIDBcblxubGV0IGZvcl9hbGwgcCBhID1cbiAgbGV0IG4gPSBsZW5ndGggYSBpblxuICBsZXQgcmVjIGxvb3AgaSA9XG4gICAgaWYgaSA9IG4gdGhlbiB0cnVlXG4gICAgZWxzZSBpZiBwICh1bnNhZmVfZ2V0IGEgaSkgdGhlbiBsb29wIChzdWNjIGkpXG4gICAgZWxzZSBmYWxzZSBpblxuICBsb29wIDBcblxubGV0IGZvcl9hbGwyIHAgbDEgbDIgPVxuICBsZXQgbjEgPSBsZW5ndGggbDFcbiAgYW5kIG4yID0gbGVuZ3RoIGwyIGluXG4gIGlmIG4xIDw+IG4yIHRoZW4gaW52YWxpZF9hcmcgXCJBcnJheS5mb3JfYWxsMlwiXG4gIGVsc2UgbGV0IHJlYyBsb29wIGkgPVxuICAgIGlmIGkgPSBuMSB0aGVuIHRydWVcbiAgICBlbHNlIGlmIHAgKHVuc2FmZV9nZXQgbDEgaSkgKHVuc2FmZV9nZXQgbDIgaSkgdGhlbiBsb29wIChzdWNjIGkpXG4gICAgZWxzZSBmYWxzZSBpblxuICBsb29wIDBcblxubGV0IGV4aXN0czIgcCBsMSBsMiA9XG4gIGxldCBuMSA9IGxlbmd0aCBsMVxuICBhbmQgbjIgPSBsZW5ndGggbDIgaW5cbiAgaWYgbjEgPD4gbjIgdGhlbiBpbnZhbGlkX2FyZyBcIkFycmF5LmV4aXN0czJcIlxuICBlbHNlIGxldCByZWMgbG9vcCBpID1cbiAgICBpZiBpID0gbjEgdGhlbiBmYWxzZVxuICAgIGVsc2UgaWYgcCAodW5zYWZlX2dldCBsMSBpKSAodW5zYWZlX2dldCBsMiBpKSB0aGVuIHRydWVcbiAgICBlbHNlIGxvb3AgKHN1Y2MgaSkgaW5cbiAgbG9vcCAwXG5cbmxldCBtZW0geCBhID1cbiAgbGV0IG4gPSBsZW5ndGggYSBpblxuICBsZXQgcmVjIGxvb3AgaSA9XG4gICAgaWYgaSA9IG4gdGhlbiBmYWxzZVxuICAgIGVsc2UgaWYgY29tcGFyZSAodW5zYWZlX2dldCBhIGkpIHggPSAwIHRoZW4gdHJ1ZVxuICAgIGVsc2UgbG9vcCAoc3VjYyBpKSBpblxuICBsb29wIDBcblxubGV0IG1lbXEgeCBhID1cbiAgbGV0IG4gPSBsZW5ndGggYSBpblxuICBsZXQgcmVjIGxvb3AgaSA9XG4gICAgaWYgaSA9IG4gdGhlbiBmYWxzZVxuICAgIGVsc2UgaWYgeCA9PSAodW5zYWZlX2dldCBhIGkpIHRoZW4gdHJ1ZVxuICAgIGVsc2UgbG9vcCAoc3VjYyBpKSBpblxuICBsb29wIDBcblxubGV0IGZpbmRfb3B0IHAgYSA9XG4gIGxldCBuID0gbGVuZ3RoIGEgaW5cbiAgbGV0IHJlYyBsb29wIGkgPVxuICAgIGlmIGkgPSBuIHRoZW4gTm9uZVxuICAgIGVsc2VcbiAgICAgIGxldCB4ID0gdW5zYWZlX2dldCBhIGkgaW5cbiAgICAgIGlmIHAgeCB0aGVuIFNvbWUgeFxuICAgICAgZWxzZSBsb29wIChzdWNjIGkpXG4gIGluXG4gIGxvb3AgMFxuXG5sZXQgZmluZF9tYXAgZiBhID1cbiAgbGV0IG4gPSBsZW5ndGggYSBpblxuICBsZXQgcmVjIGxvb3AgaSA9XG4gICAgaWYgaSA9IG4gdGhlbiBOb25lXG4gICAgZWxzZVxuICAgICAgbWF0Y2ggZiAodW5zYWZlX2dldCBhIGkpIHdpdGhcbiAgICAgIHwgTm9uZSAtPiBsb29wIChzdWNjIGkpXG4gICAgICB8IFNvbWUgXyBhcyByIC0+IHJcbiAgaW5cbiAgbG9vcCAwXG5cbmxldCBzcGxpdCB4ID1cbiAgaWYgeCA9IFt8fF0gdGhlbiBbfHxdLCBbfHxdXG4gIGVsc2UgYmVnaW5cbiAgICBsZXQgYTAsIGIwID0gdW5zYWZlX2dldCB4IDAgaW5cbiAgICBsZXQgbiA9IGxlbmd0aCB4IGluXG4gICAgbGV0IGEgPSBjcmVhdGUgbiBhMCBpblxuICAgIGxldCBiID0gY3JlYXRlIG4gYjAgaW5cbiAgICBmb3IgaSA9IDEgdG8gbiAtIDEgZG9cbiAgICAgIGxldCBhaSwgYmkgPSB1bnNhZmVfZ2V0IHggaSBpblxuICAgICAgdW5zYWZlX3NldCBhIGkgYWk7XG4gICAgICB1bnNhZmVfc2V0IGIgaSBiaVxuICAgIGRvbmU7XG4gICAgYSwgYlxuICBlbmRcblxubGV0IGNvbWJpbmUgYSBiID1cbiAgbGV0IG5hID0gbGVuZ3RoIGEgaW5cbiAgbGV0IG5iID0gbGVuZ3RoIGIgaW5cbiAgaWYgbmEgPD4gbmIgdGhlbiBpbnZhbGlkX2FyZyBcIkFycmF5LmNvbWJpbmVcIjtcbiAgaWYgbmEgPSAwIHRoZW4gW3x8XVxuICBlbHNlIGJlZ2luXG4gICAgbGV0IHggPSBjcmVhdGUgbmEgKHVuc2FmZV9nZXQgYSAwLCB1bnNhZmVfZ2V0IGIgMCkgaW5cbiAgICBmb3IgaSA9IDEgdG8gbmEgLSAxIGRvXG4gICAgICB1bnNhZmVfc2V0IHggaSAodW5zYWZlX2dldCBhIGksIHVuc2FmZV9nZXQgYiBpKVxuICAgIGRvbmU7XG4gICAgeFxuICBlbmRcblxuZXhjZXB0aW9uIEJvdHRvbSBvZiBpbnRcbmxldCBzb3J0IGNtcCBhID1cbiAgbGV0IG1heHNvbiBsIGkgPVxuICAgIGxldCBpMzEgPSBpK2kraSsxIGluXG4gICAgbGV0IHggPSByZWYgaTMxIGluXG4gICAgaWYgaTMxKzIgPCBsIHRoZW4gYmVnaW5cbiAgICAgIGlmIGNtcCAoZ2V0IGEgaTMxKSAoZ2V0IGEgKGkzMSsxKSkgPCAwIHRoZW4geCA6PSBpMzErMTtcbiAgICAgIGlmIGNtcCAoZ2V0IGEgIXgpIChnZXQgYSAoaTMxKzIpKSA8IDAgdGhlbiB4IDo9IGkzMSsyO1xuICAgICAgIXhcbiAgICBlbmQgZWxzZVxuICAgICAgaWYgaTMxKzEgPCBsICYmIGNtcCAoZ2V0IGEgaTMxKSAoZ2V0IGEgKGkzMSsxKSkgPCAwXG4gICAgICB0aGVuIGkzMSsxXG4gICAgICBlbHNlIGlmIGkzMSA8IGwgdGhlbiBpMzEgZWxzZSByYWlzZSAoQm90dG9tIGkpXG4gIGluXG4gIGxldCByZWMgdHJpY2tsZWRvd24gbCBpIGUgPVxuICAgIGxldCBqID0gbWF4c29uIGwgaSBpblxuICAgIGlmIGNtcCAoZ2V0IGEgaikgZSA+IDAgdGhlbiBiZWdpblxuICAgICAgc2V0IGEgaSAoZ2V0IGEgaik7XG4gICAgICB0cmlja2xlZG93biBsIGogZTtcbiAgICBlbmQgZWxzZSBiZWdpblxuICAgICAgc2V0IGEgaSBlO1xuICAgIGVuZDtcbiAgaW5cbiAgbGV0IHRyaWNrbGUgbCBpIGUgPSB0cnkgdHJpY2tsZWRvd24gbCBpIGUgd2l0aCBCb3R0b20gaSAtPiBzZXQgYSBpIGUgaW5cbiAgbGV0IHJlYyBidWJibGVkb3duIGwgaSA9XG4gICAgbGV0IGogPSBtYXhzb24gbCBpIGluXG4gICAgc2V0IGEgaSAoZ2V0IGEgaik7XG4gICAgYnViYmxlZG93biBsIGpcbiAgaW5cbiAgbGV0IGJ1YmJsZSBsIGkgPSB0cnkgYnViYmxlZG93biBsIGkgd2l0aCBCb3R0b20gaSAtPiBpIGluXG4gIGxldCByZWMgdHJpY2tsZXVwIGkgZSA9XG4gICAgbGV0IGZhdGhlciA9IChpIC0gMSkgLyAzIGluXG4gICAgYXNzZXJ0IChpIDw+IGZhdGhlcik7XG4gICAgaWYgY21wIChnZXQgYSBmYXRoZXIpIGUgPCAwIHRoZW4gYmVnaW5cbiAgICAgIHNldCBhIGkgKGdldCBhIGZhdGhlcik7XG4gICAgICBpZiBmYXRoZXIgPiAwIHRoZW4gdHJpY2tsZXVwIGZhdGhlciBlIGVsc2Ugc2V0IGEgMCBlO1xuICAgIGVuZCBlbHNlIGJlZ2luXG4gICAgICBzZXQgYSBpIGU7XG4gICAgZW5kO1xuICBpblxuICBsZXQgbCA9IGxlbmd0aCBhIGluXG4gIGZvciBpID0gKGwgKyAxKSAvIDMgLSAxIGRvd250byAwIGRvIHRyaWNrbGUgbCBpIChnZXQgYSBpKTsgZG9uZTtcbiAgZm9yIGkgPSBsIC0gMSBkb3dudG8gMiBkb1xuICAgIGxldCBlID0gKGdldCBhIGkpIGluXG4gICAgc2V0IGEgaSAoZ2V0IGEgMCk7XG4gICAgdHJpY2tsZXVwIChidWJibGUgaSAwKSBlO1xuICBkb25lO1xuICBpZiBsID4gMSB0aGVuIChsZXQgZSA9IChnZXQgYSAxKSBpbiBzZXQgYSAxIChnZXQgYSAwKTsgc2V0IGEgMCBlKVxuXG5cbmxldCBjdXRvZmYgPSA1XG5sZXQgc3RhYmxlX3NvcnQgY21wIGEgPVxuICBsZXQgbWVyZ2Ugc3JjMW9mcyBzcmMxbGVuIHNyYzIgc3JjMm9mcyBzcmMybGVuIGRzdCBkc3RvZnMgPVxuICAgIGxldCBzcmMxciA9IHNyYzFvZnMgKyBzcmMxbGVuIGFuZCBzcmMyciA9IHNyYzJvZnMgKyBzcmMybGVuIGluXG4gICAgbGV0IHJlYyBsb29wIGkxIHMxIGkyIHMyIGQgPVxuICAgICAgaWYgY21wIHMxIHMyIDw9IDAgdGhlbiBiZWdpblxuICAgICAgICBzZXQgZHN0IGQgczE7XG4gICAgICAgIGxldCBpMSA9IGkxICsgMSBpblxuICAgICAgICBpZiBpMSA8IHNyYzFyIHRoZW5cbiAgICAgICAgICBsb29wIGkxIChnZXQgYSBpMSkgaTIgczIgKGQgKyAxKVxuICAgICAgICBlbHNlXG4gICAgICAgICAgYmxpdCBzcmMyIGkyIGRzdCAoZCArIDEpIChzcmMyciAtIGkyKVxuICAgICAgZW5kIGVsc2UgYmVnaW5cbiAgICAgICAgc2V0IGRzdCBkIHMyO1xuICAgICAgICBsZXQgaTIgPSBpMiArIDEgaW5cbiAgICAgICAgaWYgaTIgPCBzcmMyciB0aGVuXG4gICAgICAgICAgbG9vcCBpMSBzMSBpMiAoZ2V0IHNyYzIgaTIpIChkICsgMSlcbiAgICAgICAgZWxzZVxuICAgICAgICAgIGJsaXQgYSBpMSBkc3QgKGQgKyAxKSAoc3JjMXIgLSBpMSlcbiAgICAgIGVuZFxuICAgIGluIGxvb3Agc3JjMW9mcyAoZ2V0IGEgc3JjMW9mcykgc3JjMm9mcyAoZ2V0IHNyYzIgc3JjMm9mcykgZHN0b2ZzO1xuICBpblxuICBsZXQgaXNvcnR0byBzcmNvZnMgZHN0IGRzdG9mcyBsZW4gPVxuICAgIGZvciBpID0gMCB0byBsZW4gLSAxIGRvXG4gICAgICBsZXQgZSA9IChnZXQgYSAoc3Jjb2ZzICsgaSkpIGluXG4gICAgICBsZXQgaiA9IHJlZiAoZHN0b2ZzICsgaSAtIDEpIGluXG4gICAgICB3aGlsZSAoIWogPj0gZHN0b2ZzICYmIGNtcCAoZ2V0IGRzdCAhaikgZSA+IDApIGRvXG4gICAgICAgIHNldCBkc3QgKCFqICsgMSkgKGdldCBkc3QgIWopO1xuICAgICAgICBkZWNyIGo7XG4gICAgICBkb25lO1xuICAgICAgc2V0IGRzdCAoIWogKyAxKSBlO1xuICAgIGRvbmU7XG4gIGluXG4gIGxldCByZWMgc29ydHRvIHNyY29mcyBkc3QgZHN0b2ZzIGxlbiA9XG4gICAgaWYgbGVuIDw9IGN1dG9mZiB0aGVuIGlzb3J0dG8gc3Jjb2ZzIGRzdCBkc3RvZnMgbGVuIGVsc2UgYmVnaW5cbiAgICAgIGxldCBsMSA9IGxlbiAvIDIgaW5cbiAgICAgIGxldCBsMiA9IGxlbiAtIGwxIGluXG4gICAgICBzb3J0dG8gKHNyY29mcyArIGwxKSBkc3QgKGRzdG9mcyArIGwxKSBsMjtcbiAgICAgIHNvcnR0byBzcmNvZnMgYSAoc3Jjb2ZzICsgbDIpIGwxO1xuICAgICAgbWVyZ2UgKHNyY29mcyArIGwyKSBsMSBkc3QgKGRzdG9mcyArIGwxKSBsMiBkc3QgZHN0b2ZzO1xuICAgIGVuZDtcbiAgaW5cbiAgbGV0IGwgPSBsZW5ndGggYSBpblxuICBpZiBsIDw9IGN1dG9mZiB0aGVuIGlzb3J0dG8gMCBhIDAgbCBlbHNlIGJlZ2luXG4gICAgbGV0IGwxID0gbCAvIDIgaW5cbiAgICBsZXQgbDIgPSBsIC0gbDEgaW5cbiAgICBsZXQgdCA9IG1ha2UgbDIgKGdldCBhIDApIGluXG4gICAgc29ydHRvIGwxIHQgMCBsMjtcbiAgICBzb3J0dG8gMCBhIGwyIGwxO1xuICAgIG1lcmdlIGwyIGwxIHQgMCBsMiBhIDA7XG4gIGVuZFxuXG5cbmxldCBmYXN0X3NvcnQgPSBzdGFibGVfc29ydFxuXG4oKiogezEgSXRlcmF0b3JzfSAqKVxuXG5sZXQgdG9fc2VxIGEgPVxuICBsZXQgcmVjIGF1eCBpICgpID1cbiAgICBpZiBpIDwgbGVuZ3RoIGFcbiAgICB0aGVuXG4gICAgICBsZXQgeCA9IHVuc2FmZV9nZXQgYSBpIGluXG4gICAgICBTZXEuQ29ucyAoeCwgYXV4IChpKzEpKVxuICAgIGVsc2UgU2VxLk5pbFxuICBpblxuICBhdXggMFxuXG5sZXQgdG9fc2VxaSBhID1cbiAgbGV0IHJlYyBhdXggaSAoKSA9XG4gICAgaWYgaSA8IGxlbmd0aCBhXG4gICAgdGhlblxuICAgICAgbGV0IHggPSB1bnNhZmVfZ2V0IGEgaSBpblxuICAgICAgU2VxLkNvbnMgKChpLHgpLCBhdXggKGkrMSkpXG4gICAgZWxzZSBTZXEuTmlsXG4gIGluXG4gIGF1eCAwXG5cbmxldCBvZl9yZXZfbGlzdCA9IGZ1bmN0aW9uXG4gICAgW10gLT4gW3x8XVxuICB8IGhkOjp0bCBhcyBsIC0+XG4gICAgICBsZXQgbGVuID0gbGlzdF9sZW5ndGggMCBsIGluXG4gICAgICBsZXQgYSA9IGNyZWF0ZSBsZW4gaGQgaW5cbiAgICAgIGxldCByZWMgZmlsbCBpID0gZnVuY3Rpb25cbiAgICAgICAgICBbXSAtPiBhXG4gICAgICAgIHwgaGQ6OnRsIC0+IHVuc2FmZV9zZXQgYSBpIGhkOyBmaWxsIChpLTEpIHRsXG4gICAgICBpblxuICAgICAgZmlsbCAobGVuLTIpIHRsXG5cbmxldCBvZl9zZXEgaSA9XG4gIGxldCBsID0gU2VxLmZvbGRfbGVmdCAoZnVuIGFjYyB4IC0+IHg6OmFjYykgW10gaSBpblxuICBvZl9yZXZfbGlzdCBsXG4iLCIoKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9DYW1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICBYYXZpZXIgTGVyb3ksIHByb2pldCBDcmlzdGFsLCBJTlJJQSBSb2NxdWVuY291cnQgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgIE5pY29sYXMgT2plZGEgQmFyLCBMZXhpRmkgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIENvcHlyaWdodCAyMDE4IEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgICAgICopXG4oKiAgICAgZW4gQXV0b21hdGlxdWUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIEFsbCByaWdodHMgcmVzZXJ2ZWQuICBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mICAgICopXG4oKiAgIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyLjEsIHdpdGggdGhlICAgICAgICAgICopXG4oKiAgIHNwZWNpYWwgZXhjZXB0aW9uIG9uIGxpbmtpbmcgZGVzY3JpYmVkIGluIHRoZSBmaWxlIExJQ0VOU0UuICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG5cbmV4dGVybmFsIG5lZyA6IGZsb2F0IC0+IGZsb2F0ID0gXCIlbmVnZmxvYXRcIlxuZXh0ZXJuYWwgYWRkIDogZmxvYXQgLT4gZmxvYXQgLT4gZmxvYXQgPSBcIiVhZGRmbG9hdFwiXG5leHRlcm5hbCBzdWIgOiBmbG9hdCAtPiBmbG9hdCAtPiBmbG9hdCA9IFwiJXN1YmZsb2F0XCJcbmV4dGVybmFsIG11bCA6IGZsb2F0IC0+IGZsb2F0IC0+IGZsb2F0ID0gXCIlbXVsZmxvYXRcIlxuZXh0ZXJuYWwgZGl2IDogZmxvYXQgLT4gZmxvYXQgLT4gZmxvYXQgPSBcIiVkaXZmbG9hdFwiXG5leHRlcm5hbCByZW0gOiBmbG9hdCAtPiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9mbW9kX2Zsb2F0XCIgXCJmbW9kXCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIGZtYSA6IGZsb2F0IC0+IGZsb2F0IC0+IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX2ZtYV9mbG9hdFwiIFwiY2FtbF9mbWFcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgYWJzIDogZmxvYXQgLT4gZmxvYXQgPSBcIiVhYnNmbG9hdFwiXG5cbmxldCB6ZXJvID0gMC5cbmxldCBvbmUgPSAxLlxubGV0IG1pbnVzX29uZSA9IC0xLlxubGV0IGluZmluaXR5ID0gU3RkbGliLmluZmluaXR5XG5sZXQgbmVnX2luZmluaXR5ID0gU3RkbGliLm5lZ19pbmZpbml0eVxubGV0IG5hbiA9IFN0ZGxpYi5uYW5cbmxldCBpc19maW5pdGUgKHg6IGZsb2F0KSA9IHggLS4geCA9IDAuXG5sZXQgaXNfaW5maW5pdGUgKHg6IGZsb2F0KSA9IDEuIC8uIHggPSAwLlxubGV0IGlzX25hbiAoeDogZmxvYXQpID0geCA8PiB4XG5cbmxldCBwaSA9IDB4MS45MjFmYjU0NDQyZDE4cCsxXG5sZXQgbWF4X2Zsb2F0ID0gU3RkbGliLm1heF9mbG9hdFxubGV0IG1pbl9mbG9hdCA9IFN0ZGxpYi5taW5fZmxvYXRcbmxldCBlcHNpbG9uID0gU3RkbGliLmVwc2lsb25fZmxvYXRcbmV4dGVybmFsIG9mX2ludCA6IGludCAtPiBmbG9hdCA9IFwiJWZsb2F0b2ZpbnRcIlxuZXh0ZXJuYWwgdG9faW50IDogZmxvYXQgLT4gaW50ID0gXCIlaW50b2ZmbG9hdFwiXG5leHRlcm5hbCBvZl9zdHJpbmcgOiBzdHJpbmcgLT4gZmxvYXQgPSBcImNhbWxfZmxvYXRfb2Zfc3RyaW5nXCJcbmxldCBvZl9zdHJpbmdfb3B0ID0gU3RkbGliLmZsb2F0X29mX3N0cmluZ19vcHRcbmxldCB0b19zdHJpbmcgPSBTdGRsaWIuc3RyaW5nX29mX2Zsb2F0XG50eXBlIGZwY2xhc3MgPSBTdGRsaWIuZnBjbGFzcyA9XG4gICAgRlBfbm9ybWFsXG4gIHwgRlBfc3Vibm9ybWFsXG4gIHwgRlBfemVyb1xuICB8IEZQX2luZmluaXRlXG4gIHwgRlBfbmFuXG5leHRlcm5hbCBjbGFzc2lmeV9mbG9hdCA6IChmbG9hdCBbQHVuYm94ZWRdKSAtPiBmcGNsYXNzID1cbiAgXCJjYW1sX2NsYXNzaWZ5X2Zsb2F0XCIgXCJjYW1sX2NsYXNzaWZ5X2Zsb2F0X3VuYm94ZWRcIiBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgcG93IDogZmxvYXQgLT4gZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfcG93ZXJfZmxvYXRcIiBcInBvd1wiXG4gIFtAQHVuYm94ZWRdIFtAQG5vYWxsb2NdXG5leHRlcm5hbCBzcXJ0IDogZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfc3FydF9mbG9hdFwiIFwic3FydFwiXG4gIFtAQHVuYm94ZWRdIFtAQG5vYWxsb2NdXG5leHRlcm5hbCBjYnJ0IDogZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfY2JydF9mbG9hdFwiIFwiY2FtbF9jYnJ0XCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIGV4cCA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX2V4cF9mbG9hdFwiIFwiZXhwXCIgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIGV4cDIgOiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9leHAyX2Zsb2F0XCIgXCJjYW1sX2V4cDJcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgbG9nIDogZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfbG9nX2Zsb2F0XCIgXCJsb2dcIiBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgbG9nMTAgOiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9sb2cxMF9mbG9hdFwiIFwibG9nMTBcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgbG9nMiA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX2xvZzJfZmxvYXRcIiBcImNhbWxfbG9nMlwiXG4gIFtAQHVuYm94ZWRdIFtAQG5vYWxsb2NdXG5leHRlcm5hbCBleHBtMSA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX2V4cG0xX2Zsb2F0XCIgXCJjYW1sX2V4cG0xXCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIGxvZzFwIDogZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfbG9nMXBfZmxvYXRcIiBcImNhbWxfbG9nMXBcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgY29zIDogZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfY29zX2Zsb2F0XCIgXCJjb3NcIiBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgc2luIDogZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfc2luX2Zsb2F0XCIgXCJzaW5cIiBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgdGFuIDogZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfdGFuX2Zsb2F0XCIgXCJ0YW5cIiBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgYWNvcyA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX2Fjb3NfZmxvYXRcIiBcImFjb3NcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgYXNpbiA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX2FzaW5fZmxvYXRcIiBcImFzaW5cIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgYXRhbiA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX2F0YW5fZmxvYXRcIiBcImF0YW5cIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgYXRhbjIgOiBmbG9hdCAtPiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9hdGFuMl9mbG9hdFwiIFwiYXRhbjJcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgaHlwb3QgOiBmbG9hdCAtPiBmbG9hdCAtPiBmbG9hdFxuICAgICAgICAgICAgICAgPSBcImNhbWxfaHlwb3RfZmxvYXRcIiBcImNhbWxfaHlwb3RcIiBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgY29zaCA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX2Nvc2hfZmxvYXRcIiBcImNvc2hcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgc2luaCA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX3NpbmhfZmxvYXRcIiBcInNpbmhcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgdGFuaCA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX3RhbmhfZmxvYXRcIiBcInRhbmhcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgYWNvc2ggOiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9hY29zaF9mbG9hdFwiIFwiY2FtbF9hY29zaFwiXG4gIFtAQHVuYm94ZWRdIFtAQG5vYWxsb2NdXG5leHRlcm5hbCBhc2luaCA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX2FzaW5oX2Zsb2F0XCIgXCJjYW1sX2FzaW5oXCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIGF0YW5oIDogZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfYXRhbmhfZmxvYXRcIiBcImNhbWxfYXRhbmhcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgZXJmIDogZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfZXJmX2Zsb2F0XCIgXCJjYW1sX2VyZlwiXG4gIFtAQHVuYm94ZWRdIFtAQG5vYWxsb2NdXG5leHRlcm5hbCBlcmZjIDogZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfZXJmY19mbG9hdFwiIFwiY2FtbF9lcmZjXCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIHRydW5jIDogZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfdHJ1bmNfZmxvYXRcIiBcImNhbWxfdHJ1bmNcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgcm91bmQgOiBmbG9hdCAtPiBmbG9hdCA9IFwiY2FtbF9yb3VuZF9mbG9hdFwiIFwiY2FtbF9yb3VuZFwiXG4gIFtAQHVuYm94ZWRdIFtAQG5vYWxsb2NdXG5leHRlcm5hbCBjZWlsIDogZmxvYXQgLT4gZmxvYXQgPSBcImNhbWxfY2VpbF9mbG9hdFwiIFwiY2VpbFwiXG4gIFtAQHVuYm94ZWRdIFtAQG5vYWxsb2NdXG5leHRlcm5hbCBmbG9vciA6IGZsb2F0IC0+IGZsb2F0ID0gXCJjYW1sX2Zsb29yX2Zsb2F0XCIgXCJmbG9vclwiXG5bQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuXG5sZXQgaXNfaW50ZWdlciB4ID0geCA9IHRydW5jIHggJiYgaXNfZmluaXRlIHhcblxuZXh0ZXJuYWwgbmV4dF9hZnRlciA6IGZsb2F0IC0+IGZsb2F0IC0+IGZsb2F0XG4gID0gXCJjYW1sX25leHRhZnRlcl9mbG9hdFwiIFwiY2FtbF9uZXh0YWZ0ZXJcIiBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuXG5sZXQgc3VjYyB4ID0gbmV4dF9hZnRlciB4IGluZmluaXR5XG5sZXQgcHJlZCB4ID0gbmV4dF9hZnRlciB4IG5lZ19pbmZpbml0eVxuXG5leHRlcm5hbCBjb3B5X3NpZ24gOiBmbG9hdCAtPiBmbG9hdCAtPiBmbG9hdFxuICAgICAgICAgICAgICAgICAgPSBcImNhbWxfY29weXNpZ25fZmxvYXRcIiBcImNhbWxfY29weXNpZ25cIlxuICAgICAgICAgICAgICAgICAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIHNpZ25fYml0IDogKGZsb2F0IFtAdW5ib3hlZF0pIC0+IGJvb2xcbiAgPSBcImNhbWxfc2lnbmJpdF9mbG9hdFwiIFwiY2FtbF9zaWduYml0XCIgW0BAbm9hbGxvY11cblxuZXh0ZXJuYWwgZnJleHAgOiBmbG9hdCAtPiBmbG9hdCAqIGludCA9IFwiY2FtbF9mcmV4cF9mbG9hdFwiXG5leHRlcm5hbCBsZGV4cCA6IChmbG9hdCBbQHVuYm94ZWRdKSAtPiAoaW50IFtAdW50YWdnZWRdKSAtPiAoZmxvYXQgW0B1bmJveGVkXSkgPVxuICBcImNhbWxfbGRleHBfZmxvYXRcIiBcImNhbWxfbGRleHBfZmxvYXRfdW5ib3hlZFwiIFtAQG5vYWxsb2NdXG5leHRlcm5hbCBtb2RmIDogZmxvYXQgLT4gZmxvYXQgKiBmbG9hdCA9IFwiY2FtbF9tb2RmX2Zsb2F0XCJcbnR5cGUgdCA9IGZsb2F0XG5leHRlcm5hbCBjb21wYXJlIDogZmxvYXQgLT4gZmxvYXQgLT4gaW50ID0gXCIlY29tcGFyZVwiXG5sZXQgZXF1YWwgeCB5ID0gY29tcGFyZSB4IHkgPSAwXG5cbmxldFtAaW5saW5lXSBtaW4gKHg6IGZsb2F0KSAoeTogZmxvYXQpID1cbiAgaWYgeSA+IHggfHwgKG5vdChzaWduX2JpdCB5KSAmJiBzaWduX2JpdCB4KSB0aGVuXG4gICAgaWYgaXNfbmFuIHkgdGhlbiB5IGVsc2UgeFxuICBlbHNlIGlmIGlzX25hbiB4IHRoZW4geCBlbHNlIHlcblxubGV0W0BpbmxpbmVdIG1heCAoeDogZmxvYXQpICh5OiBmbG9hdCkgPVxuICBpZiB5ID4geCB8fCAobm90KHNpZ25fYml0IHkpICYmIHNpZ25fYml0IHgpIHRoZW5cbiAgICBpZiBpc19uYW4geCB0aGVuIHggZWxzZSB5XG4gIGVsc2UgaWYgaXNfbmFuIHkgdGhlbiB5IGVsc2UgeFxuXG5sZXRbQGlubGluZV0gbWluX21heCAoeDogZmxvYXQpICh5OiBmbG9hdCkgPVxuICBpZiBpc19uYW4geCB8fCBpc19uYW4geSB0aGVuIChuYW4sIG5hbilcbiAgZWxzZSBpZiB5ID4geCB8fCAobm90KHNpZ25fYml0IHkpICYmIHNpZ25fYml0IHgpIHRoZW4gKHgsIHkpIGVsc2UgKHksIHgpXG5cbmxldFtAaW5saW5lXSBtaW5fbnVtICh4OiBmbG9hdCkgKHk6IGZsb2F0KSA9XG4gIGlmIHkgPiB4IHx8IChub3Qoc2lnbl9iaXQgeSkgJiYgc2lnbl9iaXQgeCkgdGhlblxuICAgIGlmIGlzX25hbiB4IHRoZW4geSBlbHNlIHhcbiAgZWxzZSBpZiBpc19uYW4geSB0aGVuIHggZWxzZSB5XG5cbmxldFtAaW5saW5lXSBtYXhfbnVtICh4OiBmbG9hdCkgKHk6IGZsb2F0KSA9XG4gIGlmIHkgPiB4IHx8IChub3Qoc2lnbl9iaXQgeSkgJiYgc2lnbl9iaXQgeCkgdGhlblxuICAgIGlmIGlzX25hbiB5IHRoZW4geCBlbHNlIHlcbiAgZWxzZSBpZiBpc19uYW4geCB0aGVuIHkgZWxzZSB4XG5cbmxldFtAaW5saW5lXSBtaW5fbWF4X251bSAoeDogZmxvYXQpICh5OiBmbG9hdCkgPVxuICBpZiBpc19uYW4geCB0aGVuICh5LHkpXG4gIGVsc2UgaWYgaXNfbmFuIHkgdGhlbiAoeCx4KVxuICBlbHNlIGlmIHkgPiB4IHx8IChub3Qoc2lnbl9iaXQgeSkgJiYgc2lnbl9iaXQgeCkgdGhlbiAoeCx5KSBlbHNlICh5LHgpXG5cbmV4dGVybmFsIHNlZWRlZF9oYXNoX3BhcmFtIDogaW50IC0+IGludCAtPiBpbnQgLT4gZmxvYXQgLT4gaW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICA9IFwiY2FtbF9oYXNoXCIgW0BAbm9hbGxvY11cbmxldCBoYXNoIHggPSBzZWVkZWRfaGFzaF9wYXJhbSAxMCAxMDAgMCB4XG5cbm1vZHVsZSBBcnJheSA9IHN0cnVjdFxuXG4gIHR5cGUgdCA9IGZsb2F0YXJyYXlcblxuICBleHRlcm5hbCBsZW5ndGggOiB0IC0+IGludCA9IFwiJWZsb2F0YXJyYXlfbGVuZ3RoXCJcbiAgZXh0ZXJuYWwgZ2V0IDogdCAtPiBpbnQgLT4gZmxvYXQgPSBcIiVmbG9hdGFycmF5X3NhZmVfZ2V0XCJcbiAgZXh0ZXJuYWwgc2V0IDogdCAtPiBpbnQgLT4gZmxvYXQgLT4gdW5pdCA9IFwiJWZsb2F0YXJyYXlfc2FmZV9zZXRcIlxuICBleHRlcm5hbCBjcmVhdGUgOiBpbnQgLT4gdCA9IFwiY2FtbF9mbG9hdGFycmF5X2NyZWF0ZVwiXG4gIGV4dGVybmFsIHVuc2FmZV9nZXQgOiB0IC0+IGludCAtPiBmbG9hdCA9IFwiJWZsb2F0YXJyYXlfdW5zYWZlX2dldFwiXG4gIGV4dGVybmFsIHVuc2FmZV9zZXQgOiB0IC0+IGludCAtPiBmbG9hdCAtPiB1bml0ID0gXCIlZmxvYXRhcnJheV91bnNhZmVfc2V0XCJcblxuICBsZXQgdW5zYWZlX2ZpbGwgYSBvZnMgbGVuIHYgPVxuICAgIGZvciBpID0gb2ZzIHRvIG9mcyArIGxlbiAtIDEgZG8gdW5zYWZlX3NldCBhIGkgdiBkb25lXG5cbiAgZXh0ZXJuYWwgdW5zYWZlX2JsaXQ6IHQgLT4gaW50IC0+IHQgLT4gaW50IC0+IGludCAtPiB1bml0ID1cbiAgICBcImNhbWxfZmxvYXRhcnJheV9ibGl0XCIgW0BAbm9hbGxvY11cblxuICBsZXQgY2hlY2sgYSBvZnMgbGVuIG1zZyA9XG4gICAgaWYgb2ZzIDwgMCB8fCBsZW4gPCAwIHx8IG9mcyArIGxlbiA8IDAgfHwgb2ZzICsgbGVuID4gbGVuZ3RoIGEgdGhlblxuICAgICAgaW52YWxpZF9hcmcgbXNnXG5cbiAgbGV0IG1ha2UgbiB2ID1cbiAgICBsZXQgcmVzdWx0ID0gY3JlYXRlIG4gaW5cbiAgICB1bnNhZmVfZmlsbCByZXN1bHQgMCBuIHY7XG4gICAgcmVzdWx0XG5cbiAgbGV0IGluaXQgbCBmID1cbiAgICBpZiBsIDwgMCB0aGVuIGludmFsaWRfYXJnIFwiRmxvYXQuQXJyYXkuaW5pdFwiXG4gICAgZWxzZVxuICAgICAgbGV0IHJlcyA9IGNyZWF0ZSBsIGluXG4gICAgICBmb3IgaSA9IDAgdG8gbCAtIDEgZG9cbiAgICAgICAgdW5zYWZlX3NldCByZXMgaSAoZiBpKVxuICAgICAgZG9uZTtcbiAgICAgIHJlc1xuXG4gIGxldCBhcHBlbmQgYTEgYTIgPVxuICAgIGxldCBsMSA9IGxlbmd0aCBhMSBpblxuICAgIGxldCBsMiA9IGxlbmd0aCBhMiBpblxuICAgIGxldCByZXN1bHQgPSBjcmVhdGUgKGwxICsgbDIpIGluXG4gICAgdW5zYWZlX2JsaXQgYTEgMCByZXN1bHQgMCBsMTtcbiAgICB1bnNhZmVfYmxpdCBhMiAwIHJlc3VsdCBsMSBsMjtcbiAgICByZXN1bHRcblxuICAoKiBuZXh0IDMgZnVuY3Rpb25zOiBtb2RpZmllZCBjb3B5IG9mIGNvZGUgZnJvbSBzdHJpbmcubWwgKilcbiAgbGV0IGVuc3VyZV9nZSAoeDppbnQpIHkgPVxuICAgIGlmIHggPj0geSB0aGVuIHggZWxzZSBpbnZhbGlkX2FyZyBcIkZsb2F0LkFycmF5LmNvbmNhdFwiXG5cbiAgbGV0IHJlYyBzdW1fbGVuZ3RocyBhY2MgPSBmdW5jdGlvblxuICAgIHwgW10gLT4gYWNjXG4gICAgfCBoZCA6OiB0bCAtPiBzdW1fbGVuZ3RocyAoZW5zdXJlX2dlIChsZW5ndGggaGQgKyBhY2MpIGFjYykgdGxcblxuICBsZXQgY29uY2F0IGwgPVxuICAgIGxldCBsZW4gPSBzdW1fbGVuZ3RocyAwIGwgaW5cbiAgICBsZXQgcmVzdWx0ID0gY3JlYXRlIGxlbiBpblxuICAgIGxldCByZWMgbG9vcCBsIGkgPVxuICAgICAgbWF0Y2ggbCB3aXRoXG4gICAgICB8IFtdIC0+IGFzc2VydCAoaSA9IGxlbilcbiAgICAgIHwgaGQgOjogdGwgLT5cbiAgICAgICAgbGV0IGhsZW4gPSBsZW5ndGggaGQgaW5cbiAgICAgICAgdW5zYWZlX2JsaXQgaGQgMCByZXN1bHQgaSBobGVuO1xuICAgICAgICBsb29wIHRsIChpICsgaGxlbilcbiAgICBpblxuICAgIGxvb3AgbCAwO1xuICAgIHJlc3VsdFxuXG4gIGxldCBzdWIgYSBvZnMgbGVuID1cbiAgICBjaGVjayBhIG9mcyBsZW4gXCJGbG9hdC5BcnJheS5zdWJcIjtcbiAgICBsZXQgcmVzdWx0ID0gY3JlYXRlIGxlbiBpblxuICAgIHVuc2FmZV9ibGl0IGEgb2ZzIHJlc3VsdCAwIGxlbjtcbiAgICByZXN1bHRcblxuICBsZXQgY29weSBhID1cbiAgICBsZXQgbCA9IGxlbmd0aCBhIGluXG4gICAgbGV0IHJlc3VsdCA9IGNyZWF0ZSBsIGluXG4gICAgdW5zYWZlX2JsaXQgYSAwIHJlc3VsdCAwIGw7XG4gICAgcmVzdWx0XG5cbiAgbGV0IGZpbGwgYSBvZnMgbGVuIHYgPVxuICAgIGNoZWNrIGEgb2ZzIGxlbiBcIkZsb2F0LkFycmF5LmZpbGxcIjtcbiAgICB1bnNhZmVfZmlsbCBhIG9mcyBsZW4gdlxuXG4gIGxldCBibGl0IHNyYyBzb2ZzIGRzdCBkb2ZzIGxlbiA9XG4gICAgY2hlY2sgc3JjIHNvZnMgbGVuIFwiRmxvYXQuYXJyYXkuYmxpdFwiO1xuICAgIGNoZWNrIGRzdCBkb2ZzIGxlbiBcIkZsb2F0LmFycmF5LmJsaXRcIjtcbiAgICB1bnNhZmVfYmxpdCBzcmMgc29mcyBkc3QgZG9mcyBsZW5cblxuICBsZXQgdG9fbGlzdCBhID1cbiAgICBMaXN0LmluaXQgKGxlbmd0aCBhKSAodW5zYWZlX2dldCBhKVxuXG4gIGxldCBvZl9saXN0IGwgPVxuICAgIGxldCByZXN1bHQgPSBjcmVhdGUgKExpc3QubGVuZ3RoIGwpIGluXG4gICAgbGV0IHJlYyBmaWxsIGkgbCA9XG4gICAgICBtYXRjaCBsIHdpdGhcbiAgICAgIHwgW10gLT4gcmVzdWx0XG4gICAgICB8IGggOjogdCAtPiB1bnNhZmVfc2V0IHJlc3VsdCBpIGg7IGZpbGwgKGkgKyAxKSB0XG4gICAgaW5cbiAgICBmaWxsIDAgbFxuXG4gICgqIGR1cGxpY2F0ZWQgZnJvbSBhcnJheS5tbCAqKVxuICBsZXQgaXRlciBmIGEgPVxuICAgIGZvciBpID0gMCB0byBsZW5ndGggYSAtIDEgZG8gZiAodW5zYWZlX2dldCBhIGkpIGRvbmVcblxuICAoKiBkdXBsaWNhdGVkIGZyb20gYXJyYXkubWwgKilcbiAgbGV0IGl0ZXIyIGYgYSBiID1cbiAgICBpZiBsZW5ndGggYSA8PiBsZW5ndGggYiB0aGVuXG4gICAgICBpbnZhbGlkX2FyZyBcIkZsb2F0LkFycmF5Lml0ZXIyOiBhcnJheXMgbXVzdCBoYXZlIHRoZSBzYW1lIGxlbmd0aFwiXG4gICAgZWxzZVxuICAgICAgZm9yIGkgPSAwIHRvIGxlbmd0aCBhIC0gMSBkbyBmICh1bnNhZmVfZ2V0IGEgaSkgKHVuc2FmZV9nZXQgYiBpKSBkb25lXG5cbiAgbGV0IG1hcCBmIGEgPVxuICAgIGxldCBsID0gbGVuZ3RoIGEgaW5cbiAgICBsZXQgciA9IGNyZWF0ZSBsIGluXG4gICAgZm9yIGkgPSAwIHRvIGwgLSAxIGRvXG4gICAgICB1bnNhZmVfc2V0IHIgaSAoZiAodW5zYWZlX2dldCBhIGkpKVxuICAgIGRvbmU7XG4gICAgclxuXG4gIGxldCBtYXAyIGYgYSBiID1cbiAgICBsZXQgbGEgPSBsZW5ndGggYSBpblxuICAgIGxldCBsYiA9IGxlbmd0aCBiIGluXG4gICAgaWYgbGEgPD4gbGIgdGhlblxuICAgICAgaW52YWxpZF9hcmcgXCJGbG9hdC5BcnJheS5tYXAyOiBhcnJheXMgbXVzdCBoYXZlIHRoZSBzYW1lIGxlbmd0aFwiXG4gICAgZWxzZSBiZWdpblxuICAgICAgbGV0IHIgPSBjcmVhdGUgbGEgaW5cbiAgICAgIGZvciBpID0gMCB0byBsYSAtIDEgZG9cbiAgICAgICAgdW5zYWZlX3NldCByIGkgKGYgKHVuc2FmZV9nZXQgYSBpKSAodW5zYWZlX2dldCBiIGkpKVxuICAgICAgZG9uZTtcbiAgICAgIHJcbiAgICBlbmRcblxuICAoKiBkdXBsaWNhdGVkIGZyb20gYXJyYXkubWwgKilcbiAgbGV0IGl0ZXJpIGYgYSA9XG4gICAgZm9yIGkgPSAwIHRvIGxlbmd0aCBhIC0gMSBkbyBmIGkgKHVuc2FmZV9nZXQgYSBpKSBkb25lXG5cbiAgbGV0IG1hcGkgZiBhID1cbiAgICBsZXQgbCA9IGxlbmd0aCBhIGluXG4gICAgbGV0IHIgPSBjcmVhdGUgbCBpblxuICAgIGZvciBpID0gMCB0byBsIC0gMSBkb1xuICAgICAgdW5zYWZlX3NldCByIGkgKGYgaSAodW5zYWZlX2dldCBhIGkpKVxuICAgIGRvbmU7XG4gICAgclxuXG4gICgqIGR1cGxpY2F0ZWQgZnJvbSBhcnJheS5tbCAqKVxuICBsZXQgZm9sZF9sZWZ0IGYgeCBhID1cbiAgICBsZXQgciA9IHJlZiB4IGluXG4gICAgZm9yIGkgPSAwIHRvIGxlbmd0aCBhIC0gMSBkb1xuICAgICAgciA6PSBmICFyICh1bnNhZmVfZ2V0IGEgaSlcbiAgICBkb25lO1xuICAgICFyXG5cbiAgKCogZHVwbGljYXRlZCBmcm9tIGFycmF5Lm1sICopXG4gIGxldCBmb2xkX3JpZ2h0IGYgYSB4ID1cbiAgICBsZXQgciA9IHJlZiB4IGluXG4gICAgZm9yIGkgPSBsZW5ndGggYSAtIDEgZG93bnRvIDAgZG9cbiAgICAgIHIgOj0gZiAodW5zYWZlX2dldCBhIGkpICFyXG4gICAgZG9uZTtcbiAgICAhclxuXG4gICgqIGR1cGxpY2F0ZWQgZnJvbSBhcnJheS5tbCAqKVxuICBsZXQgZXhpc3RzIHAgYSA9XG4gICAgbGV0IG4gPSBsZW5ndGggYSBpblxuICAgIGxldCByZWMgbG9vcCBpID1cbiAgICAgIGlmIGkgPSBuIHRoZW4gZmFsc2VcbiAgICAgIGVsc2UgaWYgcCAodW5zYWZlX2dldCBhIGkpIHRoZW4gdHJ1ZVxuICAgICAgZWxzZSBsb29wIChpICsgMSkgaW5cbiAgICBsb29wIDBcblxuICAoKiBkdXBsaWNhdGVkIGZyb20gYXJyYXkubWwgKilcbiAgbGV0IGZvcl9hbGwgcCBhID1cbiAgICBsZXQgbiA9IGxlbmd0aCBhIGluXG4gICAgbGV0IHJlYyBsb29wIGkgPVxuICAgICAgaWYgaSA9IG4gdGhlbiB0cnVlXG4gICAgICBlbHNlIGlmIHAgKHVuc2FmZV9nZXQgYSBpKSB0aGVuIGxvb3AgKGkgKyAxKVxuICAgICAgZWxzZSBmYWxzZSBpblxuICAgIGxvb3AgMFxuXG4gICgqIGR1cGxpY2F0ZWQgZnJvbSBhcnJheS5tbCAqKVxuICBsZXQgbWVtIHggYSA9XG4gICAgbGV0IG4gPSBsZW5ndGggYSBpblxuICAgIGxldCByZWMgbG9vcCBpID1cbiAgICAgIGlmIGkgPSBuIHRoZW4gZmFsc2VcbiAgICAgIGVsc2UgaWYgY29tcGFyZSAodW5zYWZlX2dldCBhIGkpIHggPSAwIHRoZW4gdHJ1ZVxuICAgICAgZWxzZSBsb29wIChpICsgMSlcbiAgICBpblxuICAgIGxvb3AgMFxuXG4gICgqIG1vc3RseSBkdXBsaWNhdGVkIGZyb20gYXJyYXkubWwsIGJ1dCBzbGlnaHRseSBkaWZmZXJlbnQgKilcbiAgbGV0IG1lbV9pZWVlIHggYSA9XG4gICAgbGV0IG4gPSBsZW5ndGggYSBpblxuICAgIGxldCByZWMgbG9vcCBpID1cbiAgICAgIGlmIGkgPSBuIHRoZW4gZmFsc2VcbiAgICAgIGVsc2UgaWYgeCA9ICh1bnNhZmVfZ2V0IGEgaSkgdGhlbiB0cnVlXG4gICAgICBlbHNlIGxvb3AgKGkgKyAxKVxuICAgIGluXG4gICAgbG9vcCAwXG5cbiAgKCogZHVwbGljYXRlZCBmcm9tIGFycmF5Lm1sICopXG4gIGV4Y2VwdGlvbiBCb3R0b20gb2YgaW50XG4gIGxldCBzb3J0IGNtcCBhID1cbiAgICBsZXQgbWF4c29uIGwgaSA9XG4gICAgICBsZXQgaTMxID0gaStpK2krMSBpblxuICAgICAgbGV0IHggPSByZWYgaTMxIGluXG4gICAgICBpZiBpMzErMiA8IGwgdGhlbiBiZWdpblxuICAgICAgICBpZiBjbXAgKGdldCBhIGkzMSkgKGdldCBhIChpMzErMSkpIDwgMCB0aGVuIHggOj0gaTMxKzE7XG4gICAgICAgIGlmIGNtcCAoZ2V0IGEgIXgpIChnZXQgYSAoaTMxKzIpKSA8IDAgdGhlbiB4IDo9IGkzMSsyO1xuICAgICAgICAheFxuICAgICAgZW5kIGVsc2VcbiAgICAgICAgaWYgaTMxKzEgPCBsICYmIGNtcCAoZ2V0IGEgaTMxKSAoZ2V0IGEgKGkzMSsxKSkgPCAwXG4gICAgICAgIHRoZW4gaTMxKzFcbiAgICAgICAgZWxzZSBpZiBpMzEgPCBsIHRoZW4gaTMxIGVsc2UgcmFpc2UgKEJvdHRvbSBpKVxuICAgIGluXG4gICAgbGV0IHJlYyB0cmlja2xlZG93biBsIGkgZSA9XG4gICAgICBsZXQgaiA9IG1heHNvbiBsIGkgaW5cbiAgICAgIGlmIGNtcCAoZ2V0IGEgaikgZSA+IDAgdGhlbiBiZWdpblxuICAgICAgICBzZXQgYSBpIChnZXQgYSBqKTtcbiAgICAgICAgdHJpY2tsZWRvd24gbCBqIGU7XG4gICAgICBlbmQgZWxzZSBiZWdpblxuICAgICAgICBzZXQgYSBpIGU7XG4gICAgICBlbmQ7XG4gICAgaW5cbiAgICBsZXQgdHJpY2tsZSBsIGkgZSA9IHRyeSB0cmlja2xlZG93biBsIGkgZSB3aXRoIEJvdHRvbSBpIC0+IHNldCBhIGkgZSBpblxuICAgIGxldCByZWMgYnViYmxlZG93biBsIGkgPVxuICAgICAgbGV0IGogPSBtYXhzb24gbCBpIGluXG4gICAgICBzZXQgYSBpIChnZXQgYSBqKTtcbiAgICAgIGJ1YmJsZWRvd24gbCBqXG4gICAgaW5cbiAgICBsZXQgYnViYmxlIGwgaSA9IHRyeSBidWJibGVkb3duIGwgaSB3aXRoIEJvdHRvbSBpIC0+IGkgaW5cbiAgICBsZXQgcmVjIHRyaWNrbGV1cCBpIGUgPVxuICAgICAgbGV0IGZhdGhlciA9IChpIC0gMSkgLyAzIGluXG4gICAgICBhc3NlcnQgKGkgPD4gZmF0aGVyKTtcbiAgICAgIGlmIGNtcCAoZ2V0IGEgZmF0aGVyKSBlIDwgMCB0aGVuIGJlZ2luXG4gICAgICAgIHNldCBhIGkgKGdldCBhIGZhdGhlcik7XG4gICAgICAgIGlmIGZhdGhlciA+IDAgdGhlbiB0cmlja2xldXAgZmF0aGVyIGUgZWxzZSBzZXQgYSAwIGU7XG4gICAgICBlbmQgZWxzZSBiZWdpblxuICAgICAgICBzZXQgYSBpIGU7XG4gICAgICBlbmQ7XG4gICAgaW5cbiAgICBsZXQgbCA9IGxlbmd0aCBhIGluXG4gICAgZm9yIGkgPSAobCArIDEpIC8gMyAtIDEgZG93bnRvIDAgZG8gdHJpY2tsZSBsIGkgKGdldCBhIGkpOyBkb25lO1xuICAgIGZvciBpID0gbCAtIDEgZG93bnRvIDIgZG9cbiAgICAgIGxldCBlID0gKGdldCBhIGkpIGluXG4gICAgICBzZXQgYSBpIChnZXQgYSAwKTtcbiAgICAgIHRyaWNrbGV1cCAoYnViYmxlIGkgMCkgZTtcbiAgICBkb25lO1xuICAgIGlmIGwgPiAxIHRoZW4gKGxldCBlID0gKGdldCBhIDEpIGluIHNldCBhIDEgKGdldCBhIDApOyBzZXQgYSAwIGUpXG5cbiAgKCogZHVwbGljYXRlZCBmcm9tIGFycmF5Lm1sLCBleGNlcHQgZm9yIHRoZSBjYWxsIHRvIFtjcmVhdGVdICopXG4gIGxldCBjdXRvZmYgPSA1XG4gIGxldCBzdGFibGVfc29ydCBjbXAgYSA9XG4gICAgbGV0IG1lcmdlIHNyYzFvZnMgc3JjMWxlbiBzcmMyIHNyYzJvZnMgc3JjMmxlbiBkc3QgZHN0b2ZzID1cbiAgICAgIGxldCBzcmMxciA9IHNyYzFvZnMgKyBzcmMxbGVuIGFuZCBzcmMyciA9IHNyYzJvZnMgKyBzcmMybGVuIGluXG4gICAgICBsZXQgcmVjIGxvb3AgaTEgczEgaTIgczIgZCA9XG4gICAgICAgIGlmIGNtcCBzMSBzMiA8PSAwIHRoZW4gYmVnaW5cbiAgICAgICAgICBzZXQgZHN0IGQgczE7XG4gICAgICAgICAgbGV0IGkxID0gaTEgKyAxIGluXG4gICAgICAgICAgaWYgaTEgPCBzcmMxciB0aGVuXG4gICAgICAgICAgICBsb29wIGkxIChnZXQgYSBpMSkgaTIgczIgKGQgKyAxKVxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGJsaXQgc3JjMiBpMiBkc3QgKGQgKyAxKSAoc3JjMnIgLSBpMilcbiAgICAgICAgZW5kIGVsc2UgYmVnaW5cbiAgICAgICAgICBzZXQgZHN0IGQgczI7XG4gICAgICAgICAgbGV0IGkyID0gaTIgKyAxIGluXG4gICAgICAgICAgaWYgaTIgPCBzcmMyciB0aGVuXG4gICAgICAgICAgICBsb29wIGkxIHMxIGkyIChnZXQgc3JjMiBpMikgKGQgKyAxKVxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGJsaXQgYSBpMSBkc3QgKGQgKyAxKSAoc3JjMXIgLSBpMSlcbiAgICAgICAgZW5kXG4gICAgICBpbiBsb29wIHNyYzFvZnMgKGdldCBhIHNyYzFvZnMpIHNyYzJvZnMgKGdldCBzcmMyIHNyYzJvZnMpIGRzdG9mcztcbiAgICBpblxuICAgIGxldCBpc29ydHRvIHNyY29mcyBkc3QgZHN0b2ZzIGxlbiA9XG4gICAgICBmb3IgaSA9IDAgdG8gbGVuIC0gMSBkb1xuICAgICAgICBsZXQgZSA9IChnZXQgYSAoc3Jjb2ZzICsgaSkpIGluXG4gICAgICAgIGxldCBqID0gcmVmIChkc3RvZnMgKyBpIC0gMSkgaW5cbiAgICAgICAgd2hpbGUgKCFqID49IGRzdG9mcyAmJiBjbXAgKGdldCBkc3QgIWopIGUgPiAwKSBkb1xuICAgICAgICAgIHNldCBkc3QgKCFqICsgMSkgKGdldCBkc3QgIWopO1xuICAgICAgICAgIGRlY3IgajtcbiAgICAgICAgZG9uZTtcbiAgICAgICAgc2V0IGRzdCAoIWogKyAxKSBlO1xuICAgICAgZG9uZTtcbiAgICBpblxuICAgIGxldCByZWMgc29ydHRvIHNyY29mcyBkc3QgZHN0b2ZzIGxlbiA9XG4gICAgICBpZiBsZW4gPD0gY3V0b2ZmIHRoZW4gaXNvcnR0byBzcmNvZnMgZHN0IGRzdG9mcyBsZW4gZWxzZSBiZWdpblxuICAgICAgICBsZXQgbDEgPSBsZW4gLyAyIGluXG4gICAgICAgIGxldCBsMiA9IGxlbiAtIGwxIGluXG4gICAgICAgIHNvcnR0byAoc3Jjb2ZzICsgbDEpIGRzdCAoZHN0b2ZzICsgbDEpIGwyO1xuICAgICAgICBzb3J0dG8gc3Jjb2ZzIGEgKHNyY29mcyArIGwyKSBsMTtcbiAgICAgICAgbWVyZ2UgKHNyY29mcyArIGwyKSBsMSBkc3QgKGRzdG9mcyArIGwxKSBsMiBkc3QgZHN0b2ZzO1xuICAgICAgZW5kO1xuICAgIGluXG4gICAgbGV0IGwgPSBsZW5ndGggYSBpblxuICAgIGlmIGwgPD0gY3V0b2ZmIHRoZW4gaXNvcnR0byAwIGEgMCBsIGVsc2UgYmVnaW5cbiAgICAgIGxldCBsMSA9IGwgLyAyIGluXG4gICAgICBsZXQgbDIgPSBsIC0gbDEgaW5cbiAgICAgIGxldCB0ID0gY3JlYXRlIGwyIGluXG4gICAgICBzb3J0dG8gbDEgdCAwIGwyO1xuICAgICAgc29ydHRvIDAgYSBsMiBsMTtcbiAgICAgIG1lcmdlIGwyIGwxIHQgMCBsMiBhIDA7XG4gICAgZW5kXG5cbiAgbGV0IGZhc3Rfc29ydCA9IHN0YWJsZV9zb3J0XG5cbiAgKCogZHVwbGljYXRlZCBmcm9tIGFycmF5Lm1sICopXG4gIGxldCB0b19zZXEgYSA9XG4gICAgbGV0IHJlYyBhdXggaSAoKSA9XG4gICAgICBpZiBpIDwgbGVuZ3RoIGFcbiAgICAgIHRoZW5cbiAgICAgICAgbGV0IHggPSB1bnNhZmVfZ2V0IGEgaSBpblxuICAgICAgICBTZXEuQ29ucyAoeCwgYXV4IChpKzEpKVxuICAgICAgZWxzZSBTZXEuTmlsXG4gICAgaW5cbiAgICBhdXggMFxuXG4gICgqIGR1cGxpY2F0ZWQgZnJvbSBhcnJheS5tbCAqKVxuICBsZXQgdG9fc2VxaSBhID1cbiAgICBsZXQgcmVjIGF1eCBpICgpID1cbiAgICAgIGlmIGkgPCBsZW5ndGggYVxuICAgICAgdGhlblxuICAgICAgICBsZXQgeCA9IHVuc2FmZV9nZXQgYSBpIGluXG4gICAgICAgIFNlcS5Db25zICgoaSx4KSwgYXV4IChpKzEpKVxuICAgICAgZWxzZSBTZXEuTmlsXG4gICAgaW5cbiAgICBhdXggMFxuXG4gICgqIG1vc3RseSBkdXBsaWNhdGVkIGZyb20gYXJyYXkubWwgKilcbiAgbGV0IG9mX3Jldl9saXN0IGwgPVxuICAgIGxldCBsZW4gPSBMaXN0Lmxlbmd0aCBsIGluXG4gICAgbGV0IGEgPSBjcmVhdGUgbGVuIGluXG4gICAgbGV0IHJlYyBmaWxsIGkgPSBmdW5jdGlvblxuICAgICAgICBbXSAtPiBhXG4gICAgICB8IGhkOjp0bCAtPiB1bnNhZmVfc2V0IGEgaSBoZDsgZmlsbCAoaS0xKSB0bFxuICAgIGluXG4gICAgZmlsbCAobGVuLTEpIGxcblxuICAoKiBkdXBsaWNhdGVkIGZyb20gYXJyYXkubWwgKilcbiAgbGV0IG9mX3NlcSBpID1cbiAgICBsZXQgbCA9IFNlcS5mb2xkX2xlZnQgKGZ1biBhY2MgeCAtPiB4OjphY2MpIFtdIGkgaW5cbiAgICBvZl9yZXZfbGlzdCBsXG5cblxuICBsZXQgbWFwX3RvX2FycmF5IGYgYSA9XG4gICAgbGV0IGwgPSBsZW5ndGggYSBpblxuICAgIGlmIGwgPSAwIHRoZW4gW3wgfF0gZWxzZSBiZWdpblxuICAgICAgbGV0IHIgPSBBcnJheS5tYWtlIGwgKGYgKHVuc2FmZV9nZXQgYSAwKSkgaW5cbiAgICAgIGZvciBpID0gMSB0byBsIC0gMSBkb1xuICAgICAgICBBcnJheS51bnNhZmVfc2V0IHIgaSAoZiAodW5zYWZlX2dldCBhIGkpKVxuICAgICAgZG9uZTtcbiAgICAgIHJcbiAgICBlbmRcblxuICBsZXQgbWFwX2Zyb21fYXJyYXkgZiBhID1cbiAgICBsZXQgbCA9IEFycmF5Lmxlbmd0aCBhIGluXG4gICAgbGV0IHIgPSBjcmVhdGUgbCBpblxuICAgIGZvciBpID0gMCB0byBsIC0gMSBkb1xuICAgICAgdW5zYWZlX3NldCByIGkgKGYgKEFycmF5LnVuc2FmZV9nZXQgYSBpKSlcbiAgICBkb25lO1xuICAgIHJcblxuZW5kXG5cbm1vZHVsZSBBcnJheUxhYmVscyA9IEFycmF5XG4iLCIoKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9DYW1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICBYYXZpZXIgTGVyb3ksIHByb2pldCBDcmlzdGFsLCBJTlJJQSBSb2NxdWVuY291cnQgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIENvcHlyaWdodCAxOTk2IEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgICAgICopXG4oKiAgICAgZW4gQXV0b21hdGlxdWUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIEFsbCByaWdodHMgcmVzZXJ2ZWQuICBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mICAgICopXG4oKiAgIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyLjEsIHdpdGggdGhlICAgICAgICAgICopXG4oKiAgIHNwZWNpYWwgZXhjZXB0aW9uIG9uIGxpbmtpbmcgZGVzY3JpYmVkIGluIHRoZSBmaWxlIExJQ0VOU0UuICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG5cbigqIE1vZHVsZSBbSW50MzJdOiAzMi1iaXQgaW50ZWdlcnMgKilcblxuZXh0ZXJuYWwgbmVnIDogaW50MzIgLT4gaW50MzIgPSBcIiVpbnQzMl9uZWdcIlxuZXh0ZXJuYWwgYWRkIDogaW50MzIgLT4gaW50MzIgLT4gaW50MzIgPSBcIiVpbnQzMl9hZGRcIlxuZXh0ZXJuYWwgc3ViIDogaW50MzIgLT4gaW50MzIgLT4gaW50MzIgPSBcIiVpbnQzMl9zdWJcIlxuZXh0ZXJuYWwgbXVsIDogaW50MzIgLT4gaW50MzIgLT4gaW50MzIgPSBcIiVpbnQzMl9tdWxcIlxuZXh0ZXJuYWwgZGl2IDogaW50MzIgLT4gaW50MzIgLT4gaW50MzIgPSBcIiVpbnQzMl9kaXZcIlxuZXh0ZXJuYWwgcmVtIDogaW50MzIgLT4gaW50MzIgLT4gaW50MzIgPSBcIiVpbnQzMl9tb2RcIlxuZXh0ZXJuYWwgbG9nYW5kIDogaW50MzIgLT4gaW50MzIgLT4gaW50MzIgPSBcIiVpbnQzMl9hbmRcIlxuZXh0ZXJuYWwgbG9nb3IgOiBpbnQzMiAtPiBpbnQzMiAtPiBpbnQzMiA9IFwiJWludDMyX29yXCJcbmV4dGVybmFsIGxvZ3hvciA6IGludDMyIC0+IGludDMyIC0+IGludDMyID0gXCIlaW50MzJfeG9yXCJcbmV4dGVybmFsIHNoaWZ0X2xlZnQgOiBpbnQzMiAtPiBpbnQgLT4gaW50MzIgPSBcIiVpbnQzMl9sc2xcIlxuZXh0ZXJuYWwgc2hpZnRfcmlnaHQgOiBpbnQzMiAtPiBpbnQgLT4gaW50MzIgPSBcIiVpbnQzMl9hc3JcIlxuZXh0ZXJuYWwgc2hpZnRfcmlnaHRfbG9naWNhbCA6IGludDMyIC0+IGludCAtPiBpbnQzMiA9IFwiJWludDMyX2xzclwiXG5leHRlcm5hbCBvZl9pbnQgOiBpbnQgLT4gaW50MzIgPSBcIiVpbnQzMl9vZl9pbnRcIlxuZXh0ZXJuYWwgdG9faW50IDogaW50MzIgLT4gaW50ID0gXCIlaW50MzJfdG9faW50XCJcbmV4dGVybmFsIG9mX2Zsb2F0IDogZmxvYXQgLT4gaW50MzJcbiAgPSBcImNhbWxfaW50MzJfb2ZfZmxvYXRcIiBcImNhbWxfaW50MzJfb2ZfZmxvYXRfdW5ib3hlZFwiXG4gIFtAQHVuYm94ZWRdIFtAQG5vYWxsb2NdXG5leHRlcm5hbCB0b19mbG9hdCA6IGludDMyIC0+IGZsb2F0XG4gID0gXCJjYW1sX2ludDMyX3RvX2Zsb2F0XCIgXCJjYW1sX2ludDMyX3RvX2Zsb2F0X3VuYm94ZWRcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgYml0c19vZl9mbG9hdCA6IGZsb2F0IC0+IGludDMyXG4gID0gXCJjYW1sX2ludDMyX2JpdHNfb2ZfZmxvYXRcIiBcImNhbWxfaW50MzJfYml0c19vZl9mbG9hdF91bmJveGVkXCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIGZsb2F0X29mX2JpdHMgOiBpbnQzMiAtPiBmbG9hdFxuICA9IFwiY2FtbF9pbnQzMl9mbG9hdF9vZl9iaXRzXCIgXCJjYW1sX2ludDMyX2Zsb2F0X29mX2JpdHNfdW5ib3hlZFwiXG4gIFtAQHVuYm94ZWRdIFtAQG5vYWxsb2NdXG5cbmxldCB6ZXJvID0gMGxcbmxldCBvbmUgPSAxbFxubGV0IG1pbnVzX29uZSA9IC0xbFxubGV0IHN1Y2MgbiA9IGFkZCBuIDFsXG5sZXQgcHJlZCBuID0gc3ViIG4gMWxcbmxldCBhYnMgbiA9IGlmIG4gPj0gMGwgdGhlbiBuIGVsc2UgbmVnIG5cbmxldCBtaW5faW50ID0gMHg4MDAwMDAwMGxcbmxldCBtYXhfaW50ID0gMHg3RkZGRkZGRmxcbmxldCBsb2dub3QgbiA9IGxvZ3hvciBuICgtMWwpXG5cbmxldCB1bnNpZ25lZF90b19pbnQgPVxuICBtYXRjaCBTeXMud29yZF9zaXplIHdpdGhcbiAgfCAzMiAtPlxuICAgICAgbGV0IG1heF9pbnQgPSBvZl9pbnQgU3RkbGliLm1heF9pbnQgaW5cbiAgICAgIGZ1biBuIC0+XG4gICAgICAgIGlmIGNvbXBhcmUgemVybyBuIDw9IDAgJiYgY29tcGFyZSBuIG1heF9pbnQgPD0gMCB0aGVuXG4gICAgICAgICAgU29tZSAodG9faW50IG4pXG4gICAgICAgIGVsc2VcbiAgICAgICAgICBOb25lXG4gIHwgNjQgLT5cbiAgICAgICgqIFNvIHRoYXQgaXQgY29tcGlsZXMgaW4gMzItYml0ICopXG4gICAgICBsZXQgbWFzayA9IDB4RkZGRiBsc2wgMTYgbG9yIDB4RkZGRiBpblxuICAgICAgZnVuIG4gLT4gU29tZSAodG9faW50IG4gbGFuZCBtYXNrKVxuICB8IF8gLT5cbiAgICAgIGFzc2VydCBmYWxzZVxuXG5leHRlcm5hbCBmb3JtYXQgOiBzdHJpbmcgLT4gaW50MzIgLT4gc3RyaW5nID0gXCJjYW1sX2ludDMyX2Zvcm1hdFwiXG5sZXQgdG9fc3RyaW5nIG4gPSBmb3JtYXQgXCIlZFwiIG5cblxuZXh0ZXJuYWwgb2Zfc3RyaW5nIDogc3RyaW5nIC0+IGludDMyID0gXCJjYW1sX2ludDMyX29mX3N0cmluZ1wiXG5cbmxldCBvZl9zdHJpbmdfb3B0IHMgPVxuICAoKiBUT0RPOiBleHBvc2UgYSBub24tcmFpc2luZyBwcmltaXRpdmUgZGlyZWN0bHkuICopXG4gIHRyeSBTb21lIChvZl9zdHJpbmcgcylcbiAgd2l0aCBGYWlsdXJlIF8gLT4gTm9uZVxuXG50eXBlIHQgPSBpbnQzMlxuXG5sZXQgY29tcGFyZSAoeDogdCkgKHk6IHQpID0gU3RkbGliLmNvbXBhcmUgeCB5XG5sZXQgZXF1YWwgKHg6IHQpICh5OiB0KSA9IGNvbXBhcmUgeCB5ID0gMFxuXG5sZXQgdW5zaWduZWRfY29tcGFyZSBuIG0gPVxuICBjb21wYXJlIChzdWIgbiBtaW5faW50KSAoc3ViIG0gbWluX2ludClcblxubGV0IG1pbiB4IHkgOiB0ID0gaWYgeCA8PSB5IHRoZW4geCBlbHNlIHlcbmxldCBtYXggeCB5IDogdCA9IGlmIHggPj0geSB0aGVuIHggZWxzZSB5XG5cbigqIFVuc2lnbmVkIGRpdmlzaW9uIGZyb20gc2lnbmVkIGRpdmlzaW9uIG9mIHRoZSBzYW1lXG4gICBiaXRuZXNzLiBTZWUgV2FycmVuIEpyLiwgSGVucnkgUy4gKDIwMTMpLiBIYWNrZXIncyBEZWxpZ2h0ICgyIGVkLiksIFNlYyA5LTMuXG4qKVxubGV0IHVuc2lnbmVkX2RpdiBuIGQgPVxuICBpZiBkIDwgemVybyB0aGVuXG4gICAgaWYgdW5zaWduZWRfY29tcGFyZSBuIGQgPCAwIHRoZW4gemVybyBlbHNlIG9uZVxuICBlbHNlXG4gICAgbGV0IHEgPSBzaGlmdF9sZWZ0IChkaXYgKHNoaWZ0X3JpZ2h0X2xvZ2ljYWwgbiAxKSBkKSAxIGluXG4gICAgbGV0IHIgPSBzdWIgbiAobXVsIHEgZCkgaW5cbiAgICBpZiB1bnNpZ25lZF9jb21wYXJlIHIgZCA+PSAwIHRoZW4gc3VjYyBxIGVsc2UgcVxuXG5sZXQgdW5zaWduZWRfcmVtIG4gZCA9XG4gIHN1YiBuIChtdWwgKHVuc2lnbmVkX2RpdiBuIGQpIGQpXG4iLCIoKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9DYW1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICBYYXZpZXIgTGVyb3ksIHByb2pldCBDcmlzdGFsLCBJTlJJQSBSb2NxdWVuY291cnQgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIENvcHlyaWdodCAxOTk2IEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgICAgICopXG4oKiAgICAgZW4gQXV0b21hdGlxdWUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIEFsbCByaWdodHMgcmVzZXJ2ZWQuICBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mICAgICopXG4oKiAgIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyLjEsIHdpdGggdGhlICAgICAgICAgICopXG4oKiAgIHNwZWNpYWwgZXhjZXB0aW9uIG9uIGxpbmtpbmcgZGVzY3JpYmVkIGluIHRoZSBmaWxlIExJQ0VOU0UuICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG5cbigqIE1vZHVsZSBbSW50NjRdOiA2NC1iaXQgaW50ZWdlcnMgKilcblxuZXh0ZXJuYWwgbmVnIDogaW50NjQgLT4gaW50NjQgPSBcIiVpbnQ2NF9uZWdcIlxuZXh0ZXJuYWwgYWRkIDogaW50NjQgLT4gaW50NjQgLT4gaW50NjQgPSBcIiVpbnQ2NF9hZGRcIlxuZXh0ZXJuYWwgc3ViIDogaW50NjQgLT4gaW50NjQgLT4gaW50NjQgPSBcIiVpbnQ2NF9zdWJcIlxuZXh0ZXJuYWwgbXVsIDogaW50NjQgLT4gaW50NjQgLT4gaW50NjQgPSBcIiVpbnQ2NF9tdWxcIlxuZXh0ZXJuYWwgZGl2IDogaW50NjQgLT4gaW50NjQgLT4gaW50NjQgPSBcIiVpbnQ2NF9kaXZcIlxuZXh0ZXJuYWwgcmVtIDogaW50NjQgLT4gaW50NjQgLT4gaW50NjQgPSBcIiVpbnQ2NF9tb2RcIlxuZXh0ZXJuYWwgbG9nYW5kIDogaW50NjQgLT4gaW50NjQgLT4gaW50NjQgPSBcIiVpbnQ2NF9hbmRcIlxuZXh0ZXJuYWwgbG9nb3IgOiBpbnQ2NCAtPiBpbnQ2NCAtPiBpbnQ2NCA9IFwiJWludDY0X29yXCJcbmV4dGVybmFsIGxvZ3hvciA6IGludDY0IC0+IGludDY0IC0+IGludDY0ID0gXCIlaW50NjRfeG9yXCJcbmV4dGVybmFsIHNoaWZ0X2xlZnQgOiBpbnQ2NCAtPiBpbnQgLT4gaW50NjQgPSBcIiVpbnQ2NF9sc2xcIlxuZXh0ZXJuYWwgc2hpZnRfcmlnaHQgOiBpbnQ2NCAtPiBpbnQgLT4gaW50NjQgPSBcIiVpbnQ2NF9hc3JcIlxuZXh0ZXJuYWwgc2hpZnRfcmlnaHRfbG9naWNhbCA6IGludDY0IC0+IGludCAtPiBpbnQ2NCA9IFwiJWludDY0X2xzclwiXG5leHRlcm5hbCBvZl9pbnQgOiBpbnQgLT4gaW50NjQgPSBcIiVpbnQ2NF9vZl9pbnRcIlxuZXh0ZXJuYWwgdG9faW50IDogaW50NjQgLT4gaW50ID0gXCIlaW50NjRfdG9faW50XCJcbmV4dGVybmFsIG9mX2Zsb2F0IDogZmxvYXQgLT4gaW50NjRcbiAgPSBcImNhbWxfaW50NjRfb2ZfZmxvYXRcIiBcImNhbWxfaW50NjRfb2ZfZmxvYXRfdW5ib3hlZFwiXG4gIFtAQHVuYm94ZWRdIFtAQG5vYWxsb2NdXG5leHRlcm5hbCB0b19mbG9hdCA6IGludDY0IC0+IGZsb2F0XG4gID0gXCJjYW1sX2ludDY0X3RvX2Zsb2F0XCIgXCJjYW1sX2ludDY0X3RvX2Zsb2F0X3VuYm94ZWRcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgb2ZfaW50MzIgOiBpbnQzMiAtPiBpbnQ2NCA9IFwiJWludDY0X29mX2ludDMyXCJcbmV4dGVybmFsIHRvX2ludDMyIDogaW50NjQgLT4gaW50MzIgPSBcIiVpbnQ2NF90b19pbnQzMlwiXG5leHRlcm5hbCBvZl9uYXRpdmVpbnQgOiBuYXRpdmVpbnQgLT4gaW50NjQgPSBcIiVpbnQ2NF9vZl9uYXRpdmVpbnRcIlxuZXh0ZXJuYWwgdG9fbmF0aXZlaW50IDogaW50NjQgLT4gbmF0aXZlaW50ID0gXCIlaW50NjRfdG9fbmF0aXZlaW50XCJcblxubGV0IHplcm8gPSAwTFxubGV0IG9uZSA9IDFMXG5sZXQgbWludXNfb25lID0gLTFMXG5sZXQgc3VjYyBuID0gYWRkIG4gMUxcbmxldCBwcmVkIG4gPSBzdWIgbiAxTFxubGV0IGFicyBuID0gaWYgbiA+PSAwTCB0aGVuIG4gZWxzZSBuZWcgblxubGV0IG1pbl9pbnQgPSAweDgwMDAwMDAwMDAwMDAwMDBMXG5sZXQgbWF4X2ludCA9IDB4N0ZGRkZGRkZGRkZGRkZGRkxcbmxldCBsb2dub3QgbiA9IGxvZ3hvciBuICgtMUwpXG5cbmxldCB1bnNpZ25lZF90b19pbnQgPVxuICBsZXQgbWF4X2ludCA9IG9mX2ludCBTdGRsaWIubWF4X2ludCBpblxuICBmdW4gbiAtPlxuICAgIGlmIGNvbXBhcmUgemVybyBuIDw9IDAgJiYgY29tcGFyZSBuIG1heF9pbnQgPD0gMCB0aGVuXG4gICAgICBTb21lICh0b19pbnQgbilcbiAgICBlbHNlXG4gICAgICBOb25lXG5cbmV4dGVybmFsIGZvcm1hdCA6IHN0cmluZyAtPiBpbnQ2NCAtPiBzdHJpbmcgPSBcImNhbWxfaW50NjRfZm9ybWF0XCJcbmxldCB0b19zdHJpbmcgbiA9IGZvcm1hdCBcIiVkXCIgblxuXG5leHRlcm5hbCBvZl9zdHJpbmcgOiBzdHJpbmcgLT4gaW50NjQgPSBcImNhbWxfaW50NjRfb2Zfc3RyaW5nXCJcblxubGV0IG9mX3N0cmluZ19vcHQgcyA9XG4gICgqIFRPRE86IGV4cG9zZSBhIG5vbi1yYWlzaW5nIHByaW1pdGl2ZSBkaXJlY3RseS4gKilcbiAgdHJ5IFNvbWUgKG9mX3N0cmluZyBzKVxuICB3aXRoIEZhaWx1cmUgXyAtPiBOb25lXG5cblxuXG5leHRlcm5hbCBiaXRzX29mX2Zsb2F0IDogZmxvYXQgLT4gaW50NjRcbiAgPSBcImNhbWxfaW50NjRfYml0c19vZl9mbG9hdFwiIFwiY2FtbF9pbnQ2NF9iaXRzX29mX2Zsb2F0X3VuYm94ZWRcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgZmxvYXRfb2ZfYml0cyA6IGludDY0IC0+IGZsb2F0XG4gID0gXCJjYW1sX2ludDY0X2Zsb2F0X29mX2JpdHNcIiBcImNhbWxfaW50NjRfZmxvYXRfb2ZfYml0c191bmJveGVkXCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cblxudHlwZSB0ID0gaW50NjRcblxubGV0IGNvbXBhcmUgKHg6IHQpICh5OiB0KSA9IFN0ZGxpYi5jb21wYXJlIHggeVxubGV0IGVxdWFsICh4OiB0KSAoeTogdCkgPSBjb21wYXJlIHggeSA9IDBcblxubGV0IHVuc2lnbmVkX2NvbXBhcmUgbiBtID1cbiAgY29tcGFyZSAoc3ViIG4gbWluX2ludCkgKHN1YiBtIG1pbl9pbnQpXG5cbmxldCBtaW4geCB5IDogdCA9IGlmIHggPD0geSB0aGVuIHggZWxzZSB5XG5sZXQgbWF4IHggeSA6IHQgPSBpZiB4ID49IHkgdGhlbiB4IGVsc2UgeVxuXG4oKiBVbnNpZ25lZCBkaXZpc2lvbiBmcm9tIHNpZ25lZCBkaXZpc2lvbiBvZiB0aGUgc2FtZVxuICAgYml0bmVzcy4gU2VlIFdhcnJlbiBKci4sIEhlbnJ5IFMuICgyMDEzKS4gSGFja2VyJ3MgRGVsaWdodCAoMiBlZC4pLCBTZWMgOS0zLlxuKilcbmxldCB1bnNpZ25lZF9kaXYgbiBkID1cbiAgaWYgZCA8IHplcm8gdGhlblxuICAgIGlmIHVuc2lnbmVkX2NvbXBhcmUgbiBkIDwgMCB0aGVuIHplcm8gZWxzZSBvbmVcbiAgZWxzZVxuICAgIGxldCBxID0gc2hpZnRfbGVmdCAoZGl2IChzaGlmdF9yaWdodF9sb2dpY2FsIG4gMSkgZCkgMSBpblxuICAgIGxldCByID0gc3ViIG4gKG11bCBxIGQpIGluXG4gICAgaWYgdW5zaWduZWRfY29tcGFyZSByIGQgPj0gMCB0aGVuIHN1Y2MgcSBlbHNlIHFcblxubGV0IHVuc2lnbmVkX3JlbSBuIGQgPVxuICBzdWIgbiAobXVsICh1bnNpZ25lZF9kaXYgbiBkKSBkKVxuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgWGF2aWVyIExlcm95LCBwcm9qZXQgQ3Jpc3RhbCwgSU5SSUEgUm9jcXVlbmNvdXJ0ICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMTk5NiBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0ICAgICAqKVxuKCogICAgIGVuIEF1dG9tYXRpcXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG4oKiBNb2R1bGUgW05hdGl2ZWludF06IHByb2Nlc3Nvci1uYXRpdmUgaW50ZWdlcnMgKilcblxuZXh0ZXJuYWwgbmVnOiBuYXRpdmVpbnQgLT4gbmF0aXZlaW50ID0gXCIlbmF0aXZlaW50X25lZ1wiXG5leHRlcm5hbCBhZGQ6IG5hdGl2ZWludCAtPiBuYXRpdmVpbnQgLT4gbmF0aXZlaW50ID0gXCIlbmF0aXZlaW50X2FkZFwiXG5leHRlcm5hbCBzdWI6IG5hdGl2ZWludCAtPiBuYXRpdmVpbnQgLT4gbmF0aXZlaW50ID0gXCIlbmF0aXZlaW50X3N1YlwiXG5leHRlcm5hbCBtdWw6IG5hdGl2ZWludCAtPiBuYXRpdmVpbnQgLT4gbmF0aXZlaW50ID0gXCIlbmF0aXZlaW50X211bFwiXG5leHRlcm5hbCBkaXY6IG5hdGl2ZWludCAtPiBuYXRpdmVpbnQgLT4gbmF0aXZlaW50ID0gXCIlbmF0aXZlaW50X2RpdlwiXG5leHRlcm5hbCByZW06IG5hdGl2ZWludCAtPiBuYXRpdmVpbnQgLT4gbmF0aXZlaW50ID0gXCIlbmF0aXZlaW50X21vZFwiXG5leHRlcm5hbCBsb2dhbmQ6IG5hdGl2ZWludCAtPiBuYXRpdmVpbnQgLT4gbmF0aXZlaW50ID0gXCIlbmF0aXZlaW50X2FuZFwiXG5leHRlcm5hbCBsb2dvcjogbmF0aXZlaW50IC0+IG5hdGl2ZWludCAtPiBuYXRpdmVpbnQgPSBcIiVuYXRpdmVpbnRfb3JcIlxuZXh0ZXJuYWwgbG9neG9yOiBuYXRpdmVpbnQgLT4gbmF0aXZlaW50IC0+IG5hdGl2ZWludCA9IFwiJW5hdGl2ZWludF94b3JcIlxuZXh0ZXJuYWwgc2hpZnRfbGVmdDogbmF0aXZlaW50IC0+IGludCAtPiBuYXRpdmVpbnQgPSBcIiVuYXRpdmVpbnRfbHNsXCJcbmV4dGVybmFsIHNoaWZ0X3JpZ2h0OiBuYXRpdmVpbnQgLT4gaW50IC0+IG5hdGl2ZWludCA9IFwiJW5hdGl2ZWludF9hc3JcIlxuZXh0ZXJuYWwgc2hpZnRfcmlnaHRfbG9naWNhbDogbmF0aXZlaW50IC0+IGludCAtPiBuYXRpdmVpbnQgPSBcIiVuYXRpdmVpbnRfbHNyXCJcbmV4dGVybmFsIG9mX2ludDogaW50IC0+IG5hdGl2ZWludCA9IFwiJW5hdGl2ZWludF9vZl9pbnRcIlxuZXh0ZXJuYWwgdG9faW50OiBuYXRpdmVpbnQgLT4gaW50ID0gXCIlbmF0aXZlaW50X3RvX2ludFwiXG5leHRlcm5hbCBvZl9mbG9hdCA6IGZsb2F0IC0+IG5hdGl2ZWludFxuICA9IFwiY2FtbF9uYXRpdmVpbnRfb2ZfZmxvYXRcIiBcImNhbWxfbmF0aXZlaW50X29mX2Zsb2F0X3VuYm94ZWRcIlxuICBbQEB1bmJveGVkXSBbQEBub2FsbG9jXVxuZXh0ZXJuYWwgdG9fZmxvYXQgOiBuYXRpdmVpbnQgLT4gZmxvYXRcbiAgPSBcImNhbWxfbmF0aXZlaW50X3RvX2Zsb2F0XCIgXCJjYW1sX25hdGl2ZWludF90b19mbG9hdF91bmJveGVkXCJcbiAgW0BAdW5ib3hlZF0gW0BAbm9hbGxvY11cbmV4dGVybmFsIG9mX2ludDMyOiBpbnQzMiAtPiBuYXRpdmVpbnQgPSBcIiVuYXRpdmVpbnRfb2ZfaW50MzJcIlxuZXh0ZXJuYWwgdG9faW50MzI6IG5hdGl2ZWludCAtPiBpbnQzMiA9IFwiJW5hdGl2ZWludF90b19pbnQzMlwiXG5cbmxldCB6ZXJvID0gMG5cbmxldCBvbmUgPSAxblxubGV0IG1pbnVzX29uZSA9IC0xblxubGV0IHN1Y2MgbiA9IGFkZCBuIDFuXG5sZXQgcHJlZCBuID0gc3ViIG4gMW5cbmxldCBhYnMgbiA9IGlmIG4gPj0gMG4gdGhlbiBuIGVsc2UgbmVnIG5cbmxldCBzaXplID0gU3lzLndvcmRfc2l6ZVxubGV0IG1pbl9pbnQgPSBzaGlmdF9sZWZ0IDFuIChzaXplIC0gMSlcbmxldCBtYXhfaW50ID0gc3ViIG1pbl9pbnQgMW5cbmxldCBsb2dub3QgbiA9IGxvZ3hvciBuICgtMW4pXG5cbmxldCB1bnNpZ25lZF90b19pbnQgPVxuICBsZXQgbWF4X2ludCA9IG9mX2ludCBTdGRsaWIubWF4X2ludCBpblxuICBmdW4gbiAtPlxuICAgIGlmIGNvbXBhcmUgemVybyBuIDw9IDAgJiYgY29tcGFyZSBuIG1heF9pbnQgPD0gMCB0aGVuXG4gICAgICBTb21lICh0b19pbnQgbilcbiAgICBlbHNlXG4gICAgICBOb25lXG5cbmV4dGVybmFsIGZvcm1hdCA6IHN0cmluZyAtPiBuYXRpdmVpbnQgLT4gc3RyaW5nID0gXCJjYW1sX25hdGl2ZWludF9mb3JtYXRcIlxubGV0IHRvX3N0cmluZyBuID0gZm9ybWF0IFwiJWRcIiBuXG5cbmV4dGVybmFsIG9mX3N0cmluZzogc3RyaW5nIC0+IG5hdGl2ZWludCA9IFwiY2FtbF9uYXRpdmVpbnRfb2Zfc3RyaW5nXCJcblxubGV0IG9mX3N0cmluZ19vcHQgcyA9XG4gICgqIFRPRE86IGV4cG9zZSBhIG5vbi1yYWlzaW5nIHByaW1pdGl2ZSBkaXJlY3RseS4gKilcbiAgdHJ5IFNvbWUgKG9mX3N0cmluZyBzKVxuICB3aXRoIEZhaWx1cmUgXyAtPiBOb25lXG5cbnR5cGUgdCA9IG5hdGl2ZWludFxuXG5sZXQgY29tcGFyZSAoeDogdCkgKHk6IHQpID0gU3RkbGliLmNvbXBhcmUgeCB5XG5sZXQgZXF1YWwgKHg6IHQpICh5OiB0KSA9IGNvbXBhcmUgeCB5ID0gMFxuXG5sZXQgdW5zaWduZWRfY29tcGFyZSBuIG0gPVxuICBjb21wYXJlIChzdWIgbiBtaW5faW50KSAoc3ViIG0gbWluX2ludClcblxubGV0IG1pbiB4IHkgOiB0ID0gaWYgeCA8PSB5IHRoZW4geCBlbHNlIHlcbmxldCBtYXggeCB5IDogdCA9IGlmIHggPj0geSB0aGVuIHggZWxzZSB5XG5cbigqIFVuc2lnbmVkIGRpdmlzaW9uIGZyb20gc2lnbmVkIGRpdmlzaW9uIG9mIHRoZSBzYW1lXG4gICBiaXRuZXNzLiBTZWUgV2FycmVuIEpyLiwgSGVucnkgUy4gKDIwMTMpLiBIYWNrZXIncyBEZWxpZ2h0ICgyIGVkLiksIFNlYyA5LTMuXG4qKVxubGV0IHVuc2lnbmVkX2RpdiBuIGQgPVxuICBpZiBkIDwgemVybyB0aGVuXG4gICAgaWYgdW5zaWduZWRfY29tcGFyZSBuIGQgPCAwIHRoZW4gemVybyBlbHNlIG9uZVxuICBlbHNlXG4gICAgbGV0IHEgPSBzaGlmdF9sZWZ0IChkaXYgKHNoaWZ0X3JpZ2h0X2xvZ2ljYWwgbiAxKSBkKSAxIGluXG4gICAgbGV0IHIgPSBzdWIgbiAobXVsIHEgZCkgaW5cbiAgICBpZiB1bnNpZ25lZF9jb21wYXJlIHIgZCA+PSAwIHRoZW4gc3VjYyBxIGVsc2UgcVxuXG5sZXQgdW5zaWduZWRfcmVtIG4gZCA9XG4gIHN1YiBuIChtdWwgKHVuc2lnbmVkX2RpdiBuIGQpIGQpXG4iLCIoKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9DYW1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICBYYXZpZXIgTGVyb3ksIHByb2pldCBDcmlzdGFsLCBJTlJJQSBSb2NxdWVuY291cnQgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIENvcHlyaWdodCAxOTk2IEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgICAgICopXG4oKiAgICAgZW4gQXV0b21hdGlxdWUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIEFsbCByaWdodHMgcmVzZXJ2ZWQuICBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mICAgICopXG4oKiAgIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyLjEsIHdpdGggdGhlICAgICAgICAgICopXG4oKiAgIHNwZWNpYWwgZXhjZXB0aW9uIG9uIGxpbmtpbmcgZGVzY3JpYmVkIGluIHRoZSBmaWxlIExJQ0VOU0UuICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG5cbigqIFRoZSBydW4tdGltZSBsaWJyYXJ5IGZvciBsZXhlcnMgZ2VuZXJhdGVkIGJ5IGNhbWxsZXggKilcblxudHlwZSBwb3NpdGlvbiA9IHtcbiAgcG9zX2ZuYW1lIDogc3RyaW5nO1xuICBwb3NfbG51bSA6IGludDtcbiAgcG9zX2JvbCA6IGludDtcbiAgcG9zX2NudW0gOiBpbnQ7XG59XG5cbmxldCBkdW1teV9wb3MgPSB7XG4gIHBvc19mbmFtZSA9IFwiXCI7XG4gIHBvc19sbnVtID0gMDtcbiAgcG9zX2JvbCA9IDA7XG4gIHBvc19jbnVtID0gLTE7XG59XG5cbnR5cGUgbGV4YnVmID1cbiAgeyByZWZpbGxfYnVmZiA6IGxleGJ1ZiAtPiB1bml0O1xuICAgIG11dGFibGUgbGV4X2J1ZmZlciA6IGJ5dGVzO1xuICAgIG11dGFibGUgbGV4X2J1ZmZlcl9sZW4gOiBpbnQ7XG4gICAgbXV0YWJsZSBsZXhfYWJzX3BvcyA6IGludDtcbiAgICBtdXRhYmxlIGxleF9zdGFydF9wb3MgOiBpbnQ7XG4gICAgbXV0YWJsZSBsZXhfY3Vycl9wb3MgOiBpbnQ7XG4gICAgbXV0YWJsZSBsZXhfbGFzdF9wb3MgOiBpbnQ7XG4gICAgbXV0YWJsZSBsZXhfbGFzdF9hY3Rpb24gOiBpbnQ7XG4gICAgbXV0YWJsZSBsZXhfZW9mX3JlYWNoZWQgOiBib29sO1xuICAgIG11dGFibGUgbGV4X21lbSA6IGludCBhcnJheTtcbiAgICBtdXRhYmxlIGxleF9zdGFydF9wIDogcG9zaXRpb247XG4gICAgbXV0YWJsZSBsZXhfY3Vycl9wIDogcG9zaXRpb247XG4gIH1cblxudHlwZSBsZXhfdGFibGVzID1cbiAgeyBsZXhfYmFzZTogc3RyaW5nO1xuICAgIGxleF9iYWNrdHJrOiBzdHJpbmc7XG4gICAgbGV4X2RlZmF1bHQ6IHN0cmluZztcbiAgICBsZXhfdHJhbnM6IHN0cmluZztcbiAgICBsZXhfY2hlY2s6IHN0cmluZztcbiAgICBsZXhfYmFzZV9jb2RlIDogc3RyaW5nO1xuICAgIGxleF9iYWNrdHJrX2NvZGUgOiBzdHJpbmc7XG4gICAgbGV4X2RlZmF1bHRfY29kZSA6IHN0cmluZztcbiAgICBsZXhfdHJhbnNfY29kZSA6IHN0cmluZztcbiAgICBsZXhfY2hlY2tfY29kZSA6IHN0cmluZztcbiAgICBsZXhfY29kZTogc3RyaW5nO31cblxuZXh0ZXJuYWwgY19lbmdpbmUgOiBsZXhfdGFibGVzIC0+IGludCAtPiBsZXhidWYgLT4gaW50ID0gXCJjYW1sX2xleF9lbmdpbmVcIlxuZXh0ZXJuYWwgY19uZXdfZW5naW5lIDogbGV4X3RhYmxlcyAtPiBpbnQgLT4gbGV4YnVmIC0+IGludFxuICAgICAgICAgICAgICAgICAgICAgID0gXCJjYW1sX25ld19sZXhfZW5naW5lXCJcblxubGV0IGVuZ2luZSB0Ymwgc3RhdGUgYnVmID1cbiAgbGV0IHJlc3VsdCA9IGNfZW5naW5lIHRibCBzdGF0ZSBidWYgaW5cbiAgaWYgcmVzdWx0ID49IDAgJiYgYnVmLmxleF9jdXJyX3AgIT0gZHVtbXlfcG9zIHRoZW4gYmVnaW5cbiAgICBidWYubGV4X3N0YXJ0X3AgPC0gYnVmLmxleF9jdXJyX3A7XG4gICAgYnVmLmxleF9jdXJyX3AgPC0ge2J1Zi5sZXhfY3Vycl9wXG4gICAgICAgICAgICAgICAgICAgICAgIHdpdGggcG9zX2NudW0gPSBidWYubGV4X2Fic19wb3MgKyBidWYubGV4X2N1cnJfcG9zfTtcbiAgZW5kO1xuICByZXN1bHRcblxuXG5sZXQgbmV3X2VuZ2luZSB0Ymwgc3RhdGUgYnVmID1cbiAgbGV0IHJlc3VsdCA9IGNfbmV3X2VuZ2luZSB0Ymwgc3RhdGUgYnVmIGluXG4gIGlmIHJlc3VsdCA+PSAwICYmIGJ1Zi5sZXhfY3Vycl9wICE9IGR1bW15X3BvcyB0aGVuIGJlZ2luXG4gICAgYnVmLmxleF9zdGFydF9wIDwtIGJ1Zi5sZXhfY3Vycl9wO1xuICAgIGJ1Zi5sZXhfY3Vycl9wIDwtIHtidWYubGV4X2N1cnJfcFxuICAgICAgICAgICAgICAgICAgICAgICB3aXRoIHBvc19jbnVtID0gYnVmLmxleF9hYnNfcG9zICsgYnVmLmxleF9jdXJyX3Bvc307XG4gIGVuZDtcbiAgcmVzdWx0XG5cbmxldCBsZXhfcmVmaWxsIHJlYWRfZnVuIGF1eF9idWZmZXIgbGV4YnVmID1cbiAgbGV0IHJlYWQgPVxuICAgIHJlYWRfZnVuIGF1eF9idWZmZXIgKEJ5dGVzLmxlbmd0aCBhdXhfYnVmZmVyKSBpblxuICBsZXQgbiA9XG4gICAgaWYgcmVhZCA+IDBcbiAgICB0aGVuIHJlYWRcbiAgICBlbHNlIChsZXhidWYubGV4X2VvZl9yZWFjaGVkIDwtIHRydWU7IDApIGluXG4gICgqIEN1cnJlbnQgc3RhdGUgb2YgdGhlIGJ1ZmZlcjpcbiAgICAgICAgPC0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tPlxuICAgICAgICB8ICBqdW5rIHwgICAgICB2YWxpZCBkYXRhICAgICB8ICAganVuayAgICB8XG4gICAgICAgIF4gICAgICAgXiAgICAgICAgICAgICAgICAgICAgIF4gICAgICAgICAgIF5cbiAgICAgICAgMCAgICBzdGFydF9wb3MgICAgICAgICAgICAgYnVmZmVyX2VuZCAgICBCeXRlcy5sZW5ndGggYnVmZmVyXG4gICopXG4gIGlmIGxleGJ1Zi5sZXhfYnVmZmVyX2xlbiArIG4gPiBCeXRlcy5sZW5ndGggbGV4YnVmLmxleF9idWZmZXIgdGhlbiBiZWdpblxuICAgICgqIFRoZXJlIGlzIG5vdCBlbm91Z2ggc3BhY2UgYXQgdGhlIGVuZCBvZiB0aGUgYnVmZmVyICopXG4gICAgaWYgbGV4YnVmLmxleF9idWZmZXJfbGVuIC0gbGV4YnVmLmxleF9zdGFydF9wb3MgKyBuXG4gICAgICAgPD0gQnl0ZXMubGVuZ3RoIGxleGJ1Zi5sZXhfYnVmZmVyXG4gICAgdGhlbiBiZWdpblxuICAgICAgKCogQnV0IHRoZXJlIGlzIGVub3VnaCBzcGFjZSBpZiB3ZSByZWNsYWltIHRoZSBqdW5rIGF0IHRoZSBiZWdpbm5pbmdcbiAgICAgICAgIG9mIHRoZSBidWZmZXIgKilcbiAgICAgIEJ5dGVzLmJsaXQgbGV4YnVmLmxleF9idWZmZXIgbGV4YnVmLmxleF9zdGFydF9wb3NcbiAgICAgICAgICAgICAgICAgIGxleGJ1Zi5sZXhfYnVmZmVyIDBcbiAgICAgICAgICAgICAgICAgIChsZXhidWYubGV4X2J1ZmZlcl9sZW4gLSBsZXhidWYubGV4X3N0YXJ0X3BvcylcbiAgICBlbmQgZWxzZSBiZWdpblxuICAgICAgKCogV2UgbXVzdCBncm93IHRoZSBidWZmZXIuICBEb3VibGluZyBpdHMgc2l6ZSB3aWxsIHByb3ZpZGUgZW5vdWdoXG4gICAgICAgICBzcGFjZSBzaW5jZSBuIDw9IFN0cmluZy5sZW5ndGggYXV4X2J1ZmZlciA8PSBTdHJpbmcubGVuZ3RoIGJ1ZmZlci5cbiAgICAgICAgIFdhdGNoIG91dCBmb3Igc3RyaW5nIGxlbmd0aCBvdmVyZmxvdywgdGhvdWdoLiAqKVxuICAgICAgbGV0IG5ld2xlbiA9XG4gICAgICAgIEludC5taW4gKDIgKiBCeXRlcy5sZW5ndGggbGV4YnVmLmxleF9idWZmZXIpIFN5cy5tYXhfc3RyaW5nX2xlbmd0aCBpblxuICAgICAgaWYgbGV4YnVmLmxleF9idWZmZXJfbGVuIC0gbGV4YnVmLmxleF9zdGFydF9wb3MgKyBuID4gbmV3bGVuXG4gICAgICB0aGVuIGZhaWx3aXRoIFwiTGV4aW5nLmxleF9yZWZpbGw6IGNhbm5vdCBncm93IGJ1ZmZlclwiO1xuICAgICAgbGV0IG5ld2J1ZiA9IEJ5dGVzLmNyZWF0ZSBuZXdsZW4gaW5cbiAgICAgICgqIENvcHkgdGhlIHZhbGlkIGRhdGEgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgbmV3IGJ1ZmZlciAqKVxuICAgICAgQnl0ZXMuYmxpdCBsZXhidWYubGV4X2J1ZmZlciBsZXhidWYubGV4X3N0YXJ0X3Bvc1xuICAgICAgICAgICAgICAgICAgbmV3YnVmIDBcbiAgICAgICAgICAgICAgICAgIChsZXhidWYubGV4X2J1ZmZlcl9sZW4gLSBsZXhidWYubGV4X3N0YXJ0X3Bvcyk7XG4gICAgICBsZXhidWYubGV4X2J1ZmZlciA8LSBuZXdidWZcbiAgICBlbmQ7XG4gICAgKCogUmVhbGxvY2F0aW9uIG9yIG5vdCwgd2UgaGF2ZSBzaGlmdGVkIHRoZSBkYXRhIGxlZnQgYnlcbiAgICAgICBzdGFydF9wb3MgY2hhcmFjdGVyczsgdXBkYXRlIHRoZSBwb3NpdGlvbnMgKilcbiAgICBsZXQgcyA9IGxleGJ1Zi5sZXhfc3RhcnRfcG9zIGluXG4gICAgbGV4YnVmLmxleF9hYnNfcG9zIDwtIGxleGJ1Zi5sZXhfYWJzX3BvcyArIHM7XG4gICAgbGV4YnVmLmxleF9jdXJyX3BvcyA8LSBsZXhidWYubGV4X2N1cnJfcG9zIC0gcztcbiAgICBsZXhidWYubGV4X3N0YXJ0X3BvcyA8LSAwO1xuICAgIGxleGJ1Zi5sZXhfbGFzdF9wb3MgPC0gbGV4YnVmLmxleF9sYXN0X3BvcyAtIHM7XG4gICAgbGV4YnVmLmxleF9idWZmZXJfbGVuIDwtIGxleGJ1Zi5sZXhfYnVmZmVyX2xlbiAtIHMgO1xuICAgIGxldCB0ID0gbGV4YnVmLmxleF9tZW0gaW5cbiAgICBmb3IgaSA9IDAgdG8gQXJyYXkubGVuZ3RoIHQtMSBkb1xuICAgICAgbGV0IHYgPSB0LihpKSBpblxuICAgICAgaWYgdiA+PSAwIHRoZW5cbiAgICAgICAgdC4oaSkgPC0gdi1zXG4gICAgZG9uZVxuICBlbmQ7XG4gICgqIFRoZXJlIGlzIG5vdyBlbm91Z2ggc3BhY2UgYXQgdGhlIGVuZCBvZiB0aGUgYnVmZmVyICopXG4gIEJ5dGVzLmJsaXQgYXV4X2J1ZmZlciAwIGxleGJ1Zi5sZXhfYnVmZmVyIGxleGJ1Zi5sZXhfYnVmZmVyX2xlbiBuO1xuICBsZXhidWYubGV4X2J1ZmZlcl9sZW4gPC0gbGV4YnVmLmxleF9idWZmZXJfbGVuICsgblxuXG5sZXQgemVyb19wb3MgPSB7XG4gIHBvc19mbmFtZSA9IFwiXCI7XG4gIHBvc19sbnVtID0gMTtcbiAgcG9zX2JvbCA9IDA7XG4gIHBvc19jbnVtID0gMDtcbn1cblxubGV0IGZyb21fZnVuY3Rpb24gPyh3aXRoX3Bvc2l0aW9ucyA9IHRydWUpIGYgPVxuICB7IHJlZmlsbF9idWZmID0gbGV4X3JlZmlsbCBmIChCeXRlcy5jcmVhdGUgNTEyKTtcbiAgICBsZXhfYnVmZmVyID0gQnl0ZXMuY3JlYXRlIDEwMjQ7XG4gICAgbGV4X2J1ZmZlcl9sZW4gPSAwO1xuICAgIGxleF9hYnNfcG9zID0gMDtcbiAgICBsZXhfc3RhcnRfcG9zID0gMDtcbiAgICBsZXhfY3Vycl9wb3MgPSAwO1xuICAgIGxleF9sYXN0X3BvcyA9IDA7XG4gICAgbGV4X2xhc3RfYWN0aW9uID0gMDtcbiAgICBsZXhfbWVtID0gW3x8XTtcbiAgICBsZXhfZW9mX3JlYWNoZWQgPSBmYWxzZTtcbiAgICBsZXhfc3RhcnRfcCA9IGlmIHdpdGhfcG9zaXRpb25zIHRoZW4gemVyb19wb3MgZWxzZSBkdW1teV9wb3M7XG4gICAgbGV4X2N1cnJfcCA9IGlmIHdpdGhfcG9zaXRpb25zIHRoZW4gemVyb19wb3MgZWxzZSBkdW1teV9wb3M7XG4gIH1cblxubGV0IGZyb21fY2hhbm5lbCA/d2l0aF9wb3NpdGlvbnMgaWMgPVxuICBmcm9tX2Z1bmN0aW9uID93aXRoX3Bvc2l0aW9ucyAoZnVuIGJ1ZiBuIC0+IGlucHV0IGljIGJ1ZiAwIG4pXG5cbmxldCBmcm9tX3N0cmluZyA/KHdpdGhfcG9zaXRpb25zID0gdHJ1ZSkgcyA9XG4gIHsgcmVmaWxsX2J1ZmYgPSAoZnVuIGxleGJ1ZiAtPiBsZXhidWYubGV4X2VvZl9yZWFjaGVkIDwtIHRydWUpO1xuICAgIGxleF9idWZmZXIgPSBCeXRlcy5vZl9zdHJpbmcgczsgKCogaGF2ZSB0byBtYWtlIGEgY29weSBmb3IgY29tcGF0aWJpbGl0eVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2l0aCB1bnNhZmUtc3RyaW5nIG1vZGUgKilcbiAgICBsZXhfYnVmZmVyX2xlbiA9IFN0cmluZy5sZW5ndGggcztcbiAgICBsZXhfYWJzX3BvcyA9IDA7XG4gICAgbGV4X3N0YXJ0X3BvcyA9IDA7XG4gICAgbGV4X2N1cnJfcG9zID0gMDtcbiAgICBsZXhfbGFzdF9wb3MgPSAwO1xuICAgIGxleF9sYXN0X2FjdGlvbiA9IDA7XG4gICAgbGV4X21lbSA9IFt8fF07XG4gICAgbGV4X2VvZl9yZWFjaGVkID0gdHJ1ZTtcbiAgICBsZXhfc3RhcnRfcCA9IGlmIHdpdGhfcG9zaXRpb25zIHRoZW4gemVyb19wb3MgZWxzZSBkdW1teV9wb3M7XG4gICAgbGV4X2N1cnJfcCA9IGlmIHdpdGhfcG9zaXRpb25zIHRoZW4gemVyb19wb3MgZWxzZSBkdW1teV9wb3M7XG4gIH1cblxubGV0IHNldF9wb3NpdGlvbiBsZXhidWYgcG9zaXRpb24gPVxuICBsZXhidWYubGV4X2N1cnJfcCAgPC0ge3Bvc2l0aW9uIHdpdGggcG9zX2ZuYW1lID0gbGV4YnVmLmxleF9jdXJyX3AucG9zX2ZuYW1lfTtcbiAgbGV4YnVmLmxleF9hYnNfcG9zIDwtIHBvc2l0aW9uLnBvc19jbnVtXG5cbmxldCBzZXRfZmlsZW5hbWUgbGV4YnVmIGZuYW1lID1cbiAgbGV4YnVmLmxleF9jdXJyX3AgPC0ge2xleGJ1Zi5sZXhfY3Vycl9wIHdpdGggcG9zX2ZuYW1lID0gZm5hbWV9XG5cbmxldCB3aXRoX3Bvc2l0aW9ucyBsZXhidWYgPSBsZXhidWYubGV4X2N1cnJfcCAhPSBkdW1teV9wb3NcblxubGV0IGxleGVtZSBsZXhidWYgPVxuICBsZXQgbGVuID0gbGV4YnVmLmxleF9jdXJyX3BvcyAtIGxleGJ1Zi5sZXhfc3RhcnRfcG9zIGluXG4gIEJ5dGVzLnN1Yl9zdHJpbmcgbGV4YnVmLmxleF9idWZmZXIgbGV4YnVmLmxleF9zdGFydF9wb3MgbGVuXG5cbmxldCBzdWJfbGV4ZW1lIGxleGJ1ZiBpMSBpMiA9XG4gIGxldCBsZW4gPSBpMi1pMSBpblxuICBCeXRlcy5zdWJfc3RyaW5nIGxleGJ1Zi5sZXhfYnVmZmVyIGkxIGxlblxuXG5sZXQgc3ViX2xleGVtZV9vcHQgbGV4YnVmIGkxIGkyID1cbiAgaWYgaTEgPj0gMCB0aGVuIGJlZ2luXG4gICAgbGV0IGxlbiA9IGkyLWkxIGluXG4gICAgU29tZSAoQnl0ZXMuc3ViX3N0cmluZyBsZXhidWYubGV4X2J1ZmZlciBpMSBsZW4pXG4gIGVuZCBlbHNlIGJlZ2luXG4gICAgTm9uZVxuICBlbmRcblxubGV0IHN1Yl9sZXhlbWVfY2hhciBsZXhidWYgaSA9IEJ5dGVzLmdldCBsZXhidWYubGV4X2J1ZmZlciBpXG5cbmxldCBzdWJfbGV4ZW1lX2NoYXJfb3B0IGxleGJ1ZiBpID1cbiAgaWYgaSA+PSAwIHRoZW5cbiAgICBTb21lIChCeXRlcy5nZXQgbGV4YnVmLmxleF9idWZmZXIgaSlcbiAgZWxzZVxuICAgIE5vbmVcblxuXG5sZXQgbGV4ZW1lX2NoYXIgbGV4YnVmIGkgPVxuICBCeXRlcy5nZXQgbGV4YnVmLmxleF9idWZmZXIgKGxleGJ1Zi5sZXhfc3RhcnRfcG9zICsgaSlcblxubGV0IGxleGVtZV9zdGFydCBsZXhidWYgPSBsZXhidWYubGV4X3N0YXJ0X3AucG9zX2NudW1cbmxldCBsZXhlbWVfZW5kIGxleGJ1ZiA9IGxleGJ1Zi5sZXhfY3Vycl9wLnBvc19jbnVtXG5cbmxldCBsZXhlbWVfc3RhcnRfcCBsZXhidWYgPSBsZXhidWYubGV4X3N0YXJ0X3BcbmxldCBsZXhlbWVfZW5kX3AgbGV4YnVmID0gbGV4YnVmLmxleF9jdXJyX3BcblxubGV0IG5ld19saW5lIGxleGJ1ZiA9XG4gIGxldCBsY3AgPSBsZXhidWYubGV4X2N1cnJfcCBpblxuICBpZiBsY3AgIT0gZHVtbXlfcG9zIHRoZW5cbiAgICBsZXhidWYubGV4X2N1cnJfcCA8LVxuICAgICAgeyBsY3Agd2l0aFxuICAgICAgICBwb3NfbG51bSA9IGxjcC5wb3NfbG51bSArIDE7XG4gICAgICAgIHBvc19ib2wgPSBsY3AucG9zX2NudW07XG4gICAgICB9XG5cblxuXG4oKiBEaXNjYXJkIGRhdGEgbGVmdCBpbiBsZXhlciBidWZmZXIuICopXG5cbmxldCBmbHVzaF9pbnB1dCBsYiA9XG4gIGxiLmxleF9jdXJyX3BvcyA8LSAwO1xuICBsYi5sZXhfYWJzX3BvcyA8LSAwO1xuICBsZXQgbGNwID0gbGIubGV4X2N1cnJfcCBpblxuICBpZiBsY3AgIT0gZHVtbXlfcG9zIHRoZW5cbiAgICBsYi5sZXhfY3Vycl9wIDwtIHt6ZXJvX3BvcyB3aXRoIHBvc19mbmFtZSA9IGxjcC5wb3NfZm5hbWV9O1xuICBsYi5sZXhfYnVmZmVyX2xlbiA8LSAwO1xuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgWGF2aWVyIExlcm95LCBwcm9qZXQgQ3Jpc3RhbCwgSU5SSUEgUm9jcXVlbmNvdXJ0ICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMTk5NiBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0ICAgICAqKVxuKCogICAgIGVuIEF1dG9tYXRpcXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG4oKiBUaGUgcGFyc2luZyBlbmdpbmUgKilcblxub3BlbiBMZXhpbmdcblxuKCogSW50ZXJuYWwgaW50ZXJmYWNlIHRvIHRoZSBwYXJzaW5nIGVuZ2luZSAqKVxuXG50eXBlIHBhcnNlcl9lbnYgPVxuICB7IG11dGFibGUgc19zdGFjayA6IGludCBhcnJheTsgICAgICAgICgqIFN0YXRlcyAqKVxuICAgIG11dGFibGUgdl9zdGFjayA6IE9iai50IGFycmF5OyAgICAgICgqIFNlbWFudGljIGF0dHJpYnV0ZXMgKilcbiAgICBtdXRhYmxlIHN5bWJfc3RhcnRfc3RhY2sgOiBwb3NpdGlvbiBhcnJheTsgKCogU3RhcnQgcG9zaXRpb25zICopXG4gICAgbXV0YWJsZSBzeW1iX2VuZF9zdGFjayA6IHBvc2l0aW9uIGFycmF5OyAgICgqIEVuZCBwb3NpdGlvbnMgKilcbiAgICBtdXRhYmxlIHN0YWNrc2l6ZSA6IGludDsgICAgICAgICAgICAoKiBTaXplIG9mIHRoZSBzdGFja3MgKilcbiAgICBtdXRhYmxlIHN0YWNrYmFzZSA6IGludDsgICAgICAgICAgICAoKiBCYXNlIHNwIGZvciBjdXJyZW50IHBhcnNlICopXG4gICAgbXV0YWJsZSBjdXJyX2NoYXIgOiBpbnQ7ICAgICAgICAgICAgKCogTGFzdCB0b2tlbiByZWFkICopXG4gICAgbXV0YWJsZSBsdmFsIDogT2JqLnQ7ICAgICAgICAgICAgICAgKCogSXRzIHNlbWFudGljIGF0dHJpYnV0ZSAqKVxuICAgIG11dGFibGUgc3ltYl9zdGFydCA6IHBvc2l0aW9uOyAgICAgICgqIFN0YXJ0IHBvcy4gb2YgdGhlIGN1cnJlbnQgc3ltYm9sKilcbiAgICBtdXRhYmxlIHN5bWJfZW5kIDogcG9zaXRpb247ICAgICAgICAoKiBFbmQgcG9zLiBvZiB0aGUgY3VycmVudCBzeW1ib2wgKilcbiAgICBtdXRhYmxlIGFzcCA6IGludDsgICAgICAgICAgICAgICAgICAoKiBUaGUgc3RhY2sgcG9pbnRlciBmb3IgYXR0cmlidXRlcyAqKVxuICAgIG11dGFibGUgcnVsZV9sZW4gOiBpbnQ7ICAgICAgICAgICAgICgqIE51bWJlciBvZiByaHMgaXRlbXMgaW4gdGhlIHJ1bGUgKilcbiAgICBtdXRhYmxlIHJ1bGVfbnVtYmVyIDogaW50OyAgICAgICAgICAoKiBSdWxlIG51bWJlciB0byByZWR1Y2UgYnkgKilcbiAgICBtdXRhYmxlIHNwIDogaW50OyAgICAgICAgICAgICAgICAgICAoKiBTYXZlZCBzcCBmb3IgcGFyc2VfZW5naW5lICopXG4gICAgbXV0YWJsZSBzdGF0ZSA6IGludDsgICAgICAgICAgICAgICAgKCogU2F2ZWQgc3RhdGUgZm9yIHBhcnNlX2VuZ2luZSAqKVxuICAgIG11dGFibGUgZXJyZmxhZyA6IGludCB9ICAgICAgICAgICAgICgqIFNhdmVkIGVycm9yIGZsYWcgZm9yIHBhcnNlX2VuZ2luZSAqKVxuW0BAd2FybmluZyBcIi11bnVzZWQtZmllbGRcIl1cblxudHlwZSBwYXJzZV90YWJsZXMgPVxuICB7IGFjdGlvbnMgOiAocGFyc2VyX2VudiAtPiBPYmoudCkgYXJyYXk7XG4gICAgdHJhbnNsX2NvbnN0IDogaW50IGFycmF5O1xuICAgIHRyYW5zbF9ibG9jayA6IGludCBhcnJheTtcbiAgICBsaHMgOiBzdHJpbmc7XG4gICAgbGVuIDogc3RyaW5nO1xuICAgIGRlZnJlZCA6IHN0cmluZztcbiAgICBkZ290byA6IHN0cmluZztcbiAgICBzaW5kZXggOiBzdHJpbmc7XG4gICAgcmluZGV4IDogc3RyaW5nO1xuICAgIGdpbmRleCA6IHN0cmluZztcbiAgICB0YWJsZXNpemUgOiBpbnQ7XG4gICAgdGFibGUgOiBzdHJpbmc7XG4gICAgY2hlY2sgOiBzdHJpbmc7XG4gICAgZXJyb3JfZnVuY3Rpb24gOiBzdHJpbmcgLT4gdW5pdDtcbiAgICBuYW1lc19jb25zdCA6IHN0cmluZztcbiAgICBuYW1lc19ibG9jayA6IHN0cmluZyB9XG5cbmV4Y2VwdGlvbiBZWWV4aXQgb2YgT2JqLnRcbmV4Y2VwdGlvbiBQYXJzZV9lcnJvclxuXG50eXBlIHBhcnNlcl9pbnB1dCA9XG4gICAgU3RhcnRcbiAgfCBUb2tlbl9yZWFkXG4gIHwgU3RhY2tzX2dyb3duXzFcbiAgfCBTdGFja3NfZ3Jvd25fMlxuICB8IFNlbWFudGljX2FjdGlvbl9jb21wdXRlZFxuICB8IEVycm9yX2RldGVjdGVkXG5cbnR5cGUgcGFyc2VyX291dHB1dCA9XG4gICAgUmVhZF90b2tlblxuICB8IFJhaXNlX3BhcnNlX2Vycm9yXG4gIHwgR3Jvd19zdGFja3NfMVxuICB8IEdyb3dfc3RhY2tzXzJcbiAgfCBDb21wdXRlX3NlbWFudGljX2FjdGlvblxuICB8IENhbGxfZXJyb3JfZnVuY3Rpb25cblxuKCogdG8gYXZvaWQgd2FybmluZ3MgKilcbmxldCBfID0gW1JlYWRfdG9rZW47IFJhaXNlX3BhcnNlX2Vycm9yOyBHcm93X3N0YWNrc18xOyBHcm93X3N0YWNrc18yO1xuICAgICAgICAgQ29tcHV0ZV9zZW1hbnRpY19hY3Rpb247IENhbGxfZXJyb3JfZnVuY3Rpb25dXG5cbmV4dGVybmFsIHBhcnNlX2VuZ2luZSA6XG4gICAgcGFyc2VfdGFibGVzIC0+IHBhcnNlcl9lbnYgLT4gcGFyc2VyX2lucHV0IC0+IE9iai50IC0+IHBhcnNlcl9vdXRwdXRcbiAgICA9IFwiY2FtbF9wYXJzZV9lbmdpbmVcIlxuXG5leHRlcm5hbCBzZXRfdHJhY2U6IGJvb2wgLT4gYm9vbFxuICAgID0gXCJjYW1sX3NldF9wYXJzZXJfdHJhY2VcIlxuXG5sZXQgZW52ID1cbiAgeyBzX3N0YWNrID0gQXJyYXkubWFrZSAxMDAgMDtcbiAgICB2X3N0YWNrID0gQXJyYXkubWFrZSAxMDAgKE9iai5yZXByICgpKTtcbiAgICBzeW1iX3N0YXJ0X3N0YWNrID0gQXJyYXkubWFrZSAxMDAgZHVtbXlfcG9zO1xuICAgIHN5bWJfZW5kX3N0YWNrID0gQXJyYXkubWFrZSAxMDAgZHVtbXlfcG9zO1xuICAgIHN0YWNrc2l6ZSA9IDEwMDtcbiAgICBzdGFja2Jhc2UgPSAwO1xuICAgIGN1cnJfY2hhciA9IDA7XG4gICAgbHZhbCA9IE9iai5yZXByICgpO1xuICAgIHN5bWJfc3RhcnQgPSBkdW1teV9wb3M7XG4gICAgc3ltYl9lbmQgPSBkdW1teV9wb3M7XG4gICAgYXNwID0gMDtcbiAgICBydWxlX2xlbiA9IDA7XG4gICAgcnVsZV9udW1iZXIgPSAwO1xuICAgIHNwID0gMDtcbiAgICBzdGF0ZSA9IDA7XG4gICAgZXJyZmxhZyA9IDAgfVxuXG5sZXQgZ3Jvd19zdGFja3MoKSA9XG4gIGxldCBvbGRzaXplID0gZW52LnN0YWNrc2l6ZSBpblxuICBsZXQgbmV3c2l6ZSA9IG9sZHNpemUgKiAyIGluXG4gIGxldCBuZXdfcyA9IEFycmF5Lm1ha2UgbmV3c2l6ZSAwXG4gIGFuZCBuZXdfdiA9IEFycmF5Lm1ha2UgbmV3c2l6ZSAoT2JqLnJlcHIgKCkpXG4gIGFuZCBuZXdfc3RhcnQgPSBBcnJheS5tYWtlIG5ld3NpemUgZHVtbXlfcG9zXG4gIGFuZCBuZXdfZW5kID0gQXJyYXkubWFrZSBuZXdzaXplIGR1bW15X3BvcyBpblxuICAgIEFycmF5LmJsaXQgZW52LnNfc3RhY2sgMCBuZXdfcyAwIG9sZHNpemU7XG4gICAgZW52LnNfc3RhY2sgPC0gbmV3X3M7XG4gICAgQXJyYXkuYmxpdCBlbnYudl9zdGFjayAwIG5ld192IDAgb2xkc2l6ZTtcbiAgICBlbnYudl9zdGFjayA8LSBuZXdfdjtcbiAgICBBcnJheS5ibGl0IGVudi5zeW1iX3N0YXJ0X3N0YWNrIDAgbmV3X3N0YXJ0IDAgb2xkc2l6ZTtcbiAgICBlbnYuc3ltYl9zdGFydF9zdGFjayA8LSBuZXdfc3RhcnQ7XG4gICAgQXJyYXkuYmxpdCBlbnYuc3ltYl9lbmRfc3RhY2sgMCBuZXdfZW5kIDAgb2xkc2l6ZTtcbiAgICBlbnYuc3ltYl9lbmRfc3RhY2sgPC0gbmV3X2VuZDtcbiAgICBlbnYuc3RhY2tzaXplIDwtIG5ld3NpemVcblxubGV0IGNsZWFyX3BhcnNlcigpID1cbiAgQXJyYXkuZmlsbCBlbnYudl9zdGFjayAwIGVudi5zdGFja3NpemUgKE9iai5yZXByICgpKTtcbiAgZW52Lmx2YWwgPC0gT2JqLnJlcHIgKClcblxubGV0IGN1cnJlbnRfbG9va2FoZWFkX2Z1biA9IHJlZiAoZnVuIChfIDogT2JqLnQpIC0+IGZhbHNlKVxuXG5sZXQgeXlwYXJzZSB0YWJsZXMgc3RhcnQgbGV4ZXIgbGV4YnVmID1cbiAgbGV0IHJlYyBsb29wIGNtZCBhcmcgPVxuICAgIG1hdGNoIHBhcnNlX2VuZ2luZSB0YWJsZXMgZW52IGNtZCBhcmcgd2l0aFxuICAgICAgUmVhZF90b2tlbiAtPlxuICAgICAgICBsZXQgdCA9IE9iai5yZXByKGxleGVyIGxleGJ1ZikgaW5cbiAgICAgICAgZW52LnN5bWJfc3RhcnQgPC0gbGV4YnVmLmxleF9zdGFydF9wO1xuICAgICAgICBlbnYuc3ltYl9lbmQgPC0gbGV4YnVmLmxleF9jdXJyX3A7XG4gICAgICAgIGxvb3AgVG9rZW5fcmVhZCB0XG4gICAgfCBSYWlzZV9wYXJzZV9lcnJvciAtPlxuICAgICAgICByYWlzZSBQYXJzZV9lcnJvclxuICAgIHwgQ29tcHV0ZV9zZW1hbnRpY19hY3Rpb24gLT5cbiAgICAgICAgbGV0IChhY3Rpb24sIHZhbHVlKSA9XG4gICAgICAgICAgdHJ5XG4gICAgICAgICAgICAoU2VtYW50aWNfYWN0aW9uX2NvbXB1dGVkLCB0YWJsZXMuYWN0aW9ucy4oZW52LnJ1bGVfbnVtYmVyKSBlbnYpXG4gICAgICAgICAgd2l0aCBQYXJzZV9lcnJvciAtPlxuICAgICAgICAgICAgKEVycm9yX2RldGVjdGVkLCBPYmoucmVwciAoKSkgaW5cbiAgICAgICAgbG9vcCBhY3Rpb24gdmFsdWVcbiAgICB8IEdyb3dfc3RhY2tzXzEgLT5cbiAgICAgICAgZ3Jvd19zdGFja3MoKTsgbG9vcCBTdGFja3NfZ3Jvd25fMSAoT2JqLnJlcHIgKCkpXG4gICAgfCBHcm93X3N0YWNrc18yIC0+XG4gICAgICAgIGdyb3dfc3RhY2tzKCk7IGxvb3AgU3RhY2tzX2dyb3duXzIgKE9iai5yZXByICgpKVxuICAgIHwgQ2FsbF9lcnJvcl9mdW5jdGlvbiAtPlxuICAgICAgICB0YWJsZXMuZXJyb3JfZnVuY3Rpb24gXCJzeW50YXggZXJyb3JcIjtcbiAgICAgICAgbG9vcCBFcnJvcl9kZXRlY3RlZCAoT2JqLnJlcHIgKCkpIGluXG4gIGxldCBpbml0X2FzcCA9IGVudi5hc3BcbiAgYW5kIGluaXRfc3AgPSBlbnYuc3BcbiAgYW5kIGluaXRfc3RhY2tiYXNlID0gZW52LnN0YWNrYmFzZVxuICBhbmQgaW5pdF9zdGF0ZSA9IGVudi5zdGF0ZVxuICBhbmQgaW5pdF9jdXJyX2NoYXIgPSBlbnYuY3Vycl9jaGFyXG4gIGFuZCBpbml0X2x2YWwgPSBlbnYubHZhbFxuICBhbmQgaW5pdF9lcnJmbGFnID0gZW52LmVycmZsYWcgaW5cbiAgZW52LnN0YWNrYmFzZSA8LSBlbnYuc3AgKyAxO1xuICBlbnYuY3Vycl9jaGFyIDwtIHN0YXJ0O1xuICBlbnYuc3ltYl9lbmQgPC0gbGV4YnVmLmxleF9jdXJyX3A7XG4gIHRyeVxuICAgIGxvb3AgU3RhcnQgKE9iai5yZXByICgpKVxuICB3aXRoIGV4biAtPlxuICAgIGxldCBjdXJyX2NoYXIgPSBlbnYuY3Vycl9jaGFyIGluXG4gICAgZW52LmFzcCA8LSBpbml0X2FzcDtcbiAgICBlbnYuc3AgPC0gaW5pdF9zcDtcbiAgICBlbnYuc3RhY2tiYXNlIDwtIGluaXRfc3RhY2tiYXNlO1xuICAgIGVudi5zdGF0ZSA8LSBpbml0X3N0YXRlO1xuICAgIGVudi5jdXJyX2NoYXIgPC0gaW5pdF9jdXJyX2NoYXI7XG4gICAgZW52Lmx2YWwgPC0gaW5pdF9sdmFsO1xuICAgIGVudi5lcnJmbGFnIDwtIGluaXRfZXJyZmxhZztcbiAgICBtYXRjaCBleG4gd2l0aFxuICAgICAgWVlleGl0IHYgLT5cbiAgICAgICAgT2JqLm1hZ2ljIHZcbiAgICB8IF8gLT5cbiAgICAgICAgY3VycmVudF9sb29rYWhlYWRfZnVuIDo9XG4gICAgICAgICAgKGZ1biB0b2sgLT5cbiAgICAgICAgICAgIGlmIE9iai5pc19ibG9jayB0b2tcbiAgICAgICAgICAgIHRoZW4gdGFibGVzLnRyYW5zbF9ibG9jay4oT2JqLnRhZyB0b2spID0gY3Vycl9jaGFyXG4gICAgICAgICAgICBlbHNlIHRhYmxlcy50cmFuc2xfY29uc3QuKE9iai5tYWdpYyB0b2spID0gY3Vycl9jaGFyKTtcbiAgICAgICAgcmFpc2UgZXhuXG5cbmxldCBwZWVrX3ZhbCBlbnYgbiA9XG4gIE9iai5tYWdpYyBlbnYudl9zdGFjay4oZW52LmFzcCAtIG4pXG5cbmxldCBzeW1ib2xfc3RhcnRfcG9zICgpID1cbiAgbGV0IHJlYyBsb29wIGkgPVxuICAgIGlmIGkgPD0gMCB0aGVuIGVudi5zeW1iX2VuZF9zdGFjay4oZW52LmFzcClcbiAgICBlbHNlIGJlZ2luXG4gICAgICBsZXQgc3QgPSBlbnYuc3ltYl9zdGFydF9zdGFjay4oZW52LmFzcCAtIGkgKyAxKSBpblxuICAgICAgbGV0IGVuID0gZW52LnN5bWJfZW5kX3N0YWNrLihlbnYuYXNwIC0gaSArIDEpIGluXG4gICAgICBpZiBzdCA8PiBlbiB0aGVuIHN0IGVsc2UgbG9vcCAoaSAtIDEpXG4gICAgZW5kXG4gIGluXG4gIGxvb3AgZW52LnJ1bGVfbGVuXG5cbmxldCBzeW1ib2xfZW5kX3BvcyAoKSA9IGVudi5zeW1iX2VuZF9zdGFjay4oZW52LmFzcClcbmxldCByaHNfc3RhcnRfcG9zIG4gPSBlbnYuc3ltYl9zdGFydF9zdGFjay4oZW52LmFzcCAtIChlbnYucnVsZV9sZW4gLSBuKSlcbmxldCByaHNfZW5kX3BvcyBuID0gZW52LnN5bWJfZW5kX3N0YWNrLihlbnYuYXNwIC0gKGVudi5ydWxlX2xlbiAtIG4pKVxuXG5sZXQgc3ltYm9sX3N0YXJ0ICgpID0gKHN5bWJvbF9zdGFydF9wb3MgKCkpLnBvc19jbnVtXG5sZXQgc3ltYm9sX2VuZCAoKSA9IChzeW1ib2xfZW5kX3BvcyAoKSkucG9zX2NudW1cbmxldCByaHNfc3RhcnQgbiA9IChyaHNfc3RhcnRfcG9zIG4pLnBvc19jbnVtXG5sZXQgcmhzX2VuZCBuID0gKHJoc19lbmRfcG9zIG4pLnBvc19jbnVtXG5cbmxldCBpc19jdXJyZW50X2xvb2thaGVhZCB0b2sgPVxuICAoIWN1cnJlbnRfbG9va2FoZWFkX2Z1bikoT2JqLnJlcHIgdG9rKVxuXG5sZXQgcGFyc2VfZXJyb3IgKF8gOiBzdHJpbmcpID0gKClcbiIsIigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0NhbWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgIFhhdmllciBMZXJveSwgcHJvamV0IENyaXN0YWwsIElOUklBIFJvY3F1ZW5jb3VydCAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQ29weXJpZ2h0IDE5OTYgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCAgICAgKilcbigqICAgICBlbiBBdXRvbWF0aXF1ZS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQWxsIHJpZ2h0cyByZXNlcnZlZC4gIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgICAgKilcbigqICAgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIuMSwgd2l0aCB0aGUgICAgICAgICAgKilcbigqICAgc3BlY2lhbCBleGNlcHRpb24gb24gbGlua2luZyBkZXNjcmliZWQgaW4gdGhlIGZpbGUgTElDRU5TRS4gICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcblxuKCogU2V0cyBvdmVyIG9yZGVyZWQgdHlwZXMgKilcblxubW9kdWxlIHR5cGUgT3JkZXJlZFR5cGUgPVxuICBzaWdcbiAgICB0eXBlIHRcbiAgICB2YWwgY29tcGFyZTogdCAtPiB0IC0+IGludFxuICBlbmRcblxubW9kdWxlIHR5cGUgUyA9XG4gIHNpZ1xuICAgIHR5cGUgZWx0XG4gICAgdHlwZSB0XG4gICAgdmFsIGVtcHR5OiB0XG4gICAgdmFsIGlzX2VtcHR5OiB0IC0+IGJvb2xcbiAgICB2YWwgbWVtOiBlbHQgLT4gdCAtPiBib29sXG4gICAgdmFsIGFkZDogZWx0IC0+IHQgLT4gdFxuICAgIHZhbCBzaW5nbGV0b246IGVsdCAtPiB0XG4gICAgdmFsIHJlbW92ZTogZWx0IC0+IHQgLT4gdFxuICAgIHZhbCB1bmlvbjogdCAtPiB0IC0+IHRcbiAgICB2YWwgaW50ZXI6IHQgLT4gdCAtPiB0XG4gICAgdmFsIGRpc2pvaW50OiB0IC0+IHQgLT4gYm9vbFxuICAgIHZhbCBkaWZmOiB0IC0+IHQgLT4gdFxuICAgIHZhbCBjb21wYXJlOiB0IC0+IHQgLT4gaW50XG4gICAgdmFsIGVxdWFsOiB0IC0+IHQgLT4gYm9vbFxuICAgIHZhbCBzdWJzZXQ6IHQgLT4gdCAtPiBib29sXG4gICAgdmFsIGl0ZXI6IChlbHQgLT4gdW5pdCkgLT4gdCAtPiB1bml0XG4gICAgdmFsIG1hcDogKGVsdCAtPiBlbHQpIC0+IHQgLT4gdFxuICAgIHZhbCBmb2xkOiAoZWx0IC0+ICdhIC0+ICdhKSAtPiB0IC0+ICdhIC0+ICdhXG4gICAgdmFsIGZvcl9hbGw6IChlbHQgLT4gYm9vbCkgLT4gdCAtPiBib29sXG4gICAgdmFsIGV4aXN0czogKGVsdCAtPiBib29sKSAtPiB0IC0+IGJvb2xcbiAgICB2YWwgZmlsdGVyOiAoZWx0IC0+IGJvb2wpIC0+IHQgLT4gdFxuICAgIHZhbCBmaWx0ZXJfbWFwOiAoZWx0IC0+IGVsdCBvcHRpb24pIC0+IHQgLT4gdFxuICAgIHZhbCBwYXJ0aXRpb246IChlbHQgLT4gYm9vbCkgLT4gdCAtPiB0ICogdFxuICAgIHZhbCBjYXJkaW5hbDogdCAtPiBpbnRcbiAgICB2YWwgZWxlbWVudHM6IHQgLT4gZWx0IGxpc3RcbiAgICB2YWwgbWluX2VsdDogdCAtPiBlbHRcbiAgICB2YWwgbWluX2VsdF9vcHQ6IHQgLT4gZWx0IG9wdGlvblxuICAgIHZhbCBtYXhfZWx0OiB0IC0+IGVsdFxuICAgIHZhbCBtYXhfZWx0X29wdDogdCAtPiBlbHQgb3B0aW9uXG4gICAgdmFsIGNob29zZTogdCAtPiBlbHRcbiAgICB2YWwgY2hvb3NlX29wdDogdCAtPiBlbHQgb3B0aW9uXG4gICAgdmFsIHNwbGl0OiBlbHQgLT4gdCAtPiB0ICogYm9vbCAqIHRcbiAgICB2YWwgZmluZDogZWx0IC0+IHQgLT4gZWx0XG4gICAgdmFsIGZpbmRfb3B0OiBlbHQgLT4gdCAtPiBlbHQgb3B0aW9uXG4gICAgdmFsIGZpbmRfZmlyc3Q6IChlbHQgLT4gYm9vbCkgLT4gdCAtPiBlbHRcbiAgICB2YWwgZmluZF9maXJzdF9vcHQ6IChlbHQgLT4gYm9vbCkgLT4gdCAtPiBlbHQgb3B0aW9uXG4gICAgdmFsIGZpbmRfbGFzdDogKGVsdCAtPiBib29sKSAtPiB0IC0+IGVsdFxuICAgIHZhbCBmaW5kX2xhc3Rfb3B0OiAoZWx0IC0+IGJvb2wpIC0+IHQgLT4gZWx0IG9wdGlvblxuICAgIHZhbCBvZl9saXN0OiBlbHQgbGlzdCAtPiB0XG4gICAgdmFsIHRvX3NlcV9mcm9tIDogZWx0IC0+IHQgLT4gZWx0IFNlcS50XG4gICAgdmFsIHRvX3NlcSA6IHQgLT4gZWx0IFNlcS50XG4gICAgdmFsIHRvX3Jldl9zZXEgOiB0IC0+IGVsdCBTZXEudFxuICAgIHZhbCBhZGRfc2VxIDogZWx0IFNlcS50IC0+IHQgLT4gdFxuICAgIHZhbCBvZl9zZXEgOiBlbHQgU2VxLnQgLT4gdFxuICBlbmRcblxubW9kdWxlIE1ha2UoT3JkOiBPcmRlcmVkVHlwZSkgPVxuICBzdHJ1Y3RcbiAgICB0eXBlIGVsdCA9IE9yZC50XG4gICAgdHlwZSB0ID0gRW1wdHkgfCBOb2RlIG9mIHtsOnQ7IHY6ZWx0OyByOnQ7IGg6aW50fVxuXG4gICAgKCogU2V0cyBhcmUgcmVwcmVzZW50ZWQgYnkgYmFsYW5jZWQgYmluYXJ5IHRyZWVzICh0aGUgaGVpZ2h0cyBvZiB0aGVcbiAgICAgICBjaGlsZHJlbiBkaWZmZXIgYnkgYXQgbW9zdCAyICopXG5cbiAgICBsZXQgaGVpZ2h0ID0gZnVuY3Rpb25cbiAgICAgICAgRW1wdHkgLT4gMFxuICAgICAgfCBOb2RlIHtofSAtPiBoXG5cbiAgICAoKiBDcmVhdGVzIGEgbmV3IG5vZGUgd2l0aCBsZWZ0IHNvbiBsLCB2YWx1ZSB2IGFuZCByaWdodCBzb24gci5cbiAgICAgICBXZSBtdXN0IGhhdmUgYWxsIGVsZW1lbnRzIG9mIGwgPCB2IDwgYWxsIGVsZW1lbnRzIG9mIHIuXG4gICAgICAgbCBhbmQgciBtdXN0IGJlIGJhbGFuY2VkIGFuZCB8IGhlaWdodCBsIC0gaGVpZ2h0IHIgfCA8PSAyLlxuICAgICAgIElubGluZSBleHBhbnNpb24gb2YgaGVpZ2h0IGZvciBiZXR0ZXIgc3BlZWQuICopXG5cbiAgICBsZXQgY3JlYXRlIGwgdiByID1cbiAgICAgIGxldCBobCA9IG1hdGNoIGwgd2l0aCBFbXB0eSAtPiAwIHwgTm9kZSB7aH0gLT4gaCBpblxuICAgICAgbGV0IGhyID0gbWF0Y2ggciB3aXRoIEVtcHR5IC0+IDAgfCBOb2RlIHtofSAtPiBoIGluXG4gICAgICBOb2Rle2w7IHY7IHI7IGg9KGlmIGhsID49IGhyIHRoZW4gaGwgKyAxIGVsc2UgaHIgKyAxKX1cblxuICAgICgqIFNhbWUgYXMgY3JlYXRlLCBidXQgcGVyZm9ybXMgb25lIHN0ZXAgb2YgcmViYWxhbmNpbmcgaWYgbmVjZXNzYXJ5LlxuICAgICAgIEFzc3VtZXMgbCBhbmQgciBiYWxhbmNlZCBhbmQgfCBoZWlnaHQgbCAtIGhlaWdodCByIHwgPD0gMy5cbiAgICAgICBJbmxpbmUgZXhwYW5zaW9uIG9mIGNyZWF0ZSBmb3IgYmV0dGVyIHNwZWVkIGluIHRoZSBtb3N0IGZyZXF1ZW50IGNhc2VcbiAgICAgICB3aGVyZSBubyByZWJhbGFuY2luZyBpcyByZXF1aXJlZC4gKilcblxuICAgIGxldCBiYWwgbCB2IHIgPVxuICAgICAgbGV0IGhsID0gbWF0Y2ggbCB3aXRoIEVtcHR5IC0+IDAgfCBOb2RlIHtofSAtPiBoIGluXG4gICAgICBsZXQgaHIgPSBtYXRjaCByIHdpdGggRW1wdHkgLT4gMCB8IE5vZGUge2h9IC0+IGggaW5cbiAgICAgIGlmIGhsID4gaHIgKyAyIHRoZW4gYmVnaW5cbiAgICAgICAgbWF0Y2ggbCB3aXRoXG4gICAgICAgICAgRW1wdHkgLT4gaW52YWxpZF9hcmcgXCJTZXQuYmFsXCJcbiAgICAgICAgfCBOb2Rle2w9bGw7IHY9bHY7IHI9bHJ9IC0+XG4gICAgICAgICAgICBpZiBoZWlnaHQgbGwgPj0gaGVpZ2h0IGxyIHRoZW5cbiAgICAgICAgICAgICAgY3JlYXRlIGxsIGx2IChjcmVhdGUgbHIgdiByKVxuICAgICAgICAgICAgZWxzZSBiZWdpblxuICAgICAgICAgICAgICBtYXRjaCBsciB3aXRoXG4gICAgICAgICAgICAgICAgRW1wdHkgLT4gaW52YWxpZF9hcmcgXCJTZXQuYmFsXCJcbiAgICAgICAgICAgICAgfCBOb2Rle2w9bHJsOyB2PWxydjsgcj1scnJ9LT5cbiAgICAgICAgICAgICAgICAgIGNyZWF0ZSAoY3JlYXRlIGxsIGx2IGxybCkgbHJ2IChjcmVhdGUgbHJyIHYgcilcbiAgICAgICAgICAgIGVuZFxuICAgICAgZW5kIGVsc2UgaWYgaHIgPiBobCArIDIgdGhlbiBiZWdpblxuICAgICAgICBtYXRjaCByIHdpdGhcbiAgICAgICAgICBFbXB0eSAtPiBpbnZhbGlkX2FyZyBcIlNldC5iYWxcIlxuICAgICAgICB8IE5vZGV7bD1ybDsgdj1ydjsgcj1ycn0gLT5cbiAgICAgICAgICAgIGlmIGhlaWdodCByciA+PSBoZWlnaHQgcmwgdGhlblxuICAgICAgICAgICAgICBjcmVhdGUgKGNyZWF0ZSBsIHYgcmwpIHJ2IHJyXG4gICAgICAgICAgICBlbHNlIGJlZ2luXG4gICAgICAgICAgICAgIG1hdGNoIHJsIHdpdGhcbiAgICAgICAgICAgICAgICBFbXB0eSAtPiBpbnZhbGlkX2FyZyBcIlNldC5iYWxcIlxuICAgICAgICAgICAgICB8IE5vZGV7bD1ybGw7IHY9cmx2OyByPXJscn0gLT5cbiAgICAgICAgICAgICAgICAgIGNyZWF0ZSAoY3JlYXRlIGwgdiBybGwpIHJsdiAoY3JlYXRlIHJsciBydiBycilcbiAgICAgICAgICAgIGVuZFxuICAgICAgZW5kIGVsc2VcbiAgICAgICAgTm9kZXtsOyB2OyByOyBoPShpZiBobCA+PSBociB0aGVuIGhsICsgMSBlbHNlIGhyICsgMSl9XG5cbiAgICAoKiBJbnNlcnRpb24gb2Ygb25lIGVsZW1lbnQgKilcblxuICAgIGxldCByZWMgYWRkIHggPSBmdW5jdGlvblxuICAgICAgICBFbXB0eSAtPiBOb2Rle2w9RW1wdHk7IHY9eDsgcj1FbXB0eTsgaD0xfVxuICAgICAgfCBOb2Rle2w7IHY7IHJ9IGFzIHQgLT5cbiAgICAgICAgICBsZXQgYyA9IE9yZC5jb21wYXJlIHggdiBpblxuICAgICAgICAgIGlmIGMgPSAwIHRoZW4gdCBlbHNlXG4gICAgICAgICAgaWYgYyA8IDAgdGhlblxuICAgICAgICAgICAgbGV0IGxsID0gYWRkIHggbCBpblxuICAgICAgICAgICAgaWYgbCA9PSBsbCB0aGVuIHQgZWxzZSBiYWwgbGwgdiByXG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgbGV0IHJyID0gYWRkIHggciBpblxuICAgICAgICAgICAgaWYgciA9PSByciB0aGVuIHQgZWxzZSBiYWwgbCB2IHJyXG5cbiAgICBsZXQgc2luZ2xldG9uIHggPSBOb2Rle2w9RW1wdHk7IHY9eDsgcj1FbXB0eTsgaD0xfVxuXG4gICAgKCogQmV3YXJlOiB0aG9zZSB0d28gZnVuY3Rpb25zIGFzc3VtZSB0aGF0IHRoZSBhZGRlZCB2IGlzICpzdHJpY3RseSpcbiAgICAgICBzbWFsbGVyIChvciBiaWdnZXIpIHRoYW4gYWxsIHRoZSBwcmVzZW50IGVsZW1lbnRzIGluIHRoZSB0cmVlOyBpdFxuICAgICAgIGRvZXMgbm90IHRlc3QgZm9yIGVxdWFsaXR5IHdpdGggdGhlIGN1cnJlbnQgbWluIChvciBtYXgpIGVsZW1lbnQuXG4gICAgICAgSW5kZWVkLCB0aGV5IGFyZSBvbmx5IHVzZWQgZHVyaW5nIHRoZSBcImpvaW5cIiBvcGVyYXRpb24gd2hpY2hcbiAgICAgICByZXNwZWN0cyB0aGlzIHByZWNvbmRpdGlvbi5cbiAgICAqKVxuXG4gICAgbGV0IHJlYyBhZGRfbWluX2VsZW1lbnQgeCA9IGZ1bmN0aW9uXG4gICAgICB8IEVtcHR5IC0+IHNpbmdsZXRvbiB4XG4gICAgICB8IE5vZGUge2w7IHY7IHJ9IC0+XG4gICAgICAgIGJhbCAoYWRkX21pbl9lbGVtZW50IHggbCkgdiByXG5cbiAgICBsZXQgcmVjIGFkZF9tYXhfZWxlbWVudCB4ID0gZnVuY3Rpb25cbiAgICAgIHwgRW1wdHkgLT4gc2luZ2xldG9uIHhcbiAgICAgIHwgTm9kZSB7bDsgdjsgcn0gLT5cbiAgICAgICAgYmFsIGwgdiAoYWRkX21heF9lbGVtZW50IHggcilcblxuICAgICgqIFNhbWUgYXMgY3JlYXRlIGFuZCBiYWwsIGJ1dCBubyBhc3N1bXB0aW9ucyBhcmUgbWFkZSBvbiB0aGVcbiAgICAgICByZWxhdGl2ZSBoZWlnaHRzIG9mIGwgYW5kIHIuICopXG5cbiAgICBsZXQgcmVjIGpvaW4gbCB2IHIgPVxuICAgICAgbWF0Y2ggKGwsIHIpIHdpdGhcbiAgICAgICAgKEVtcHR5LCBfKSAtPiBhZGRfbWluX2VsZW1lbnQgdiByXG4gICAgICB8IChfLCBFbXB0eSkgLT4gYWRkX21heF9lbGVtZW50IHYgbFxuICAgICAgfCAoTm9kZXtsPWxsOyB2PWx2OyByPWxyOyBoPWxofSwgTm9kZXtsPXJsOyB2PXJ2OyByPXJyOyBoPXJofSkgLT5cbiAgICAgICAgICBpZiBsaCA+IHJoICsgMiB0aGVuIGJhbCBsbCBsdiAoam9pbiBsciB2IHIpIGVsc2VcbiAgICAgICAgICBpZiByaCA+IGxoICsgMiB0aGVuIGJhbCAoam9pbiBsIHYgcmwpIHJ2IHJyIGVsc2VcbiAgICAgICAgICBjcmVhdGUgbCB2IHJcblxuICAgICgqIFNtYWxsZXN0IGFuZCBncmVhdGVzdCBlbGVtZW50IG9mIGEgc2V0ICopXG5cbiAgICBsZXQgcmVjIG1pbl9lbHQgPSBmdW5jdGlvblxuICAgICAgICBFbXB0eSAtPiByYWlzZSBOb3RfZm91bmRcbiAgICAgIHwgTm9kZXtsPUVtcHR5OyB2fSAtPiB2XG4gICAgICB8IE5vZGV7bH0gLT4gbWluX2VsdCBsXG5cbiAgICBsZXQgcmVjIG1pbl9lbHRfb3B0ID0gZnVuY3Rpb25cbiAgICAgICAgRW1wdHkgLT4gTm9uZVxuICAgICAgfCBOb2Rle2w9RW1wdHk7IHZ9IC0+IFNvbWUgdlxuICAgICAgfCBOb2Rle2x9IC0+IG1pbl9lbHRfb3B0IGxcblxuICAgIGxldCByZWMgbWF4X2VsdCA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+IHJhaXNlIE5vdF9mb3VuZFxuICAgICAgfCBOb2Rle3Y7IHI9RW1wdHl9IC0+IHZcbiAgICAgIHwgTm9kZXtyfSAtPiBtYXhfZWx0IHJcblxuICAgIGxldCByZWMgbWF4X2VsdF9vcHQgPSBmdW5jdGlvblxuICAgICAgICBFbXB0eSAtPiBOb25lXG4gICAgICB8IE5vZGV7djsgcj1FbXB0eX0gLT4gU29tZSB2XG4gICAgICB8IE5vZGV7cn0gLT4gbWF4X2VsdF9vcHQgclxuXG4gICAgKCogUmVtb3ZlIHRoZSBzbWFsbGVzdCBlbGVtZW50IG9mIHRoZSBnaXZlbiBzZXQgKilcblxuICAgIGxldCByZWMgcmVtb3ZlX21pbl9lbHQgPSBmdW5jdGlvblxuICAgICAgICBFbXB0eSAtPiBpbnZhbGlkX2FyZyBcIlNldC5yZW1vdmVfbWluX2VsdFwiXG4gICAgICB8IE5vZGV7bD1FbXB0eTsgcn0gLT4gclxuICAgICAgfCBOb2Rle2w7IHY7IHJ9IC0+IGJhbCAocmVtb3ZlX21pbl9lbHQgbCkgdiByXG5cbiAgICAoKiBNZXJnZSB0d28gdHJlZXMgbCBhbmQgciBpbnRvIG9uZS5cbiAgICAgICBBbGwgZWxlbWVudHMgb2YgbCBtdXN0IHByZWNlZGUgdGhlIGVsZW1lbnRzIG9mIHIuXG4gICAgICAgQXNzdW1lIHwgaGVpZ2h0IGwgLSBoZWlnaHQgciB8IDw9IDIuICopXG5cbiAgICBsZXQgbWVyZ2UgdDEgdDIgPVxuICAgICAgbWF0Y2ggKHQxLCB0Mikgd2l0aFxuICAgICAgICAoRW1wdHksIHQpIC0+IHRcbiAgICAgIHwgKHQsIEVtcHR5KSAtPiB0XG4gICAgICB8IChfLCBfKSAtPiBiYWwgdDEgKG1pbl9lbHQgdDIpIChyZW1vdmVfbWluX2VsdCB0MilcblxuICAgICgqIE1lcmdlIHR3byB0cmVlcyBsIGFuZCByIGludG8gb25lLlxuICAgICAgIEFsbCBlbGVtZW50cyBvZiBsIG11c3QgcHJlY2VkZSB0aGUgZWxlbWVudHMgb2Ygci5cbiAgICAgICBObyBhc3N1bXB0aW9uIG9uIHRoZSBoZWlnaHRzIG9mIGwgYW5kIHIuICopXG5cbiAgICBsZXQgY29uY2F0IHQxIHQyID1cbiAgICAgIG1hdGNoICh0MSwgdDIpIHdpdGhcbiAgICAgICAgKEVtcHR5LCB0KSAtPiB0XG4gICAgICB8ICh0LCBFbXB0eSkgLT4gdFxuICAgICAgfCAoXywgXykgLT4gam9pbiB0MSAobWluX2VsdCB0MikgKHJlbW92ZV9taW5fZWx0IHQyKVxuXG4gICAgKCogU3BsaXR0aW5nLiAgc3BsaXQgeCBzIHJldHVybnMgYSB0cmlwbGUgKGwsIHByZXNlbnQsIHIpIHdoZXJlXG4gICAgICAgIC0gbCBpcyB0aGUgc2V0IG9mIGVsZW1lbnRzIG9mIHMgdGhhdCBhcmUgPCB4XG4gICAgICAgIC0gciBpcyB0aGUgc2V0IG9mIGVsZW1lbnRzIG9mIHMgdGhhdCBhcmUgPiB4XG4gICAgICAgIC0gcHJlc2VudCBpcyBmYWxzZSBpZiBzIGNvbnRhaW5zIG5vIGVsZW1lbnQgZXF1YWwgdG8geCxcbiAgICAgICAgICBvciB0cnVlIGlmIHMgY29udGFpbnMgYW4gZWxlbWVudCBlcXVhbCB0byB4LiAqKVxuXG4gICAgbGV0IHJlYyBzcGxpdCB4ID0gZnVuY3Rpb25cbiAgICAgICAgRW1wdHkgLT5cbiAgICAgICAgICAoRW1wdHksIGZhbHNlLCBFbXB0eSlcbiAgICAgIHwgTm9kZXtsOyB2OyByfSAtPlxuICAgICAgICAgIGxldCBjID0gT3JkLmNvbXBhcmUgeCB2IGluXG4gICAgICAgICAgaWYgYyA9IDAgdGhlbiAobCwgdHJ1ZSwgcilcbiAgICAgICAgICBlbHNlIGlmIGMgPCAwIHRoZW5cbiAgICAgICAgICAgIGxldCAobGwsIHByZXMsIHJsKSA9IHNwbGl0IHggbCBpbiAobGwsIHByZXMsIGpvaW4gcmwgdiByKVxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGxldCAobHIsIHByZXMsIHJyKSA9IHNwbGl0IHggciBpbiAoam9pbiBsIHYgbHIsIHByZXMsIHJyKVxuXG4gICAgKCogSW1wbGVtZW50YXRpb24gb2YgdGhlIHNldCBvcGVyYXRpb25zICopXG5cbiAgICBsZXQgZW1wdHkgPSBFbXB0eVxuXG4gICAgbGV0IGlzX2VtcHR5ID0gZnVuY3Rpb24gRW1wdHkgLT4gdHJ1ZSB8IF8gLT4gZmFsc2VcblxuICAgIGxldCByZWMgbWVtIHggPSBmdW5jdGlvblxuICAgICAgICBFbXB0eSAtPiBmYWxzZVxuICAgICAgfCBOb2Rle2w7IHY7IHJ9IC0+XG4gICAgICAgICAgbGV0IGMgPSBPcmQuY29tcGFyZSB4IHYgaW5cbiAgICAgICAgICBjID0gMCB8fCBtZW0geCAoaWYgYyA8IDAgdGhlbiBsIGVsc2UgcilcblxuICAgIGxldCByZWMgcmVtb3ZlIHggPSBmdW5jdGlvblxuICAgICAgICBFbXB0eSAtPiBFbXB0eVxuICAgICAgfCAoTm9kZXtsOyB2OyByfSBhcyB0KSAtPlxuICAgICAgICAgIGxldCBjID0gT3JkLmNvbXBhcmUgeCB2IGluXG4gICAgICAgICAgaWYgYyA9IDAgdGhlbiBtZXJnZSBsIHJcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICBpZiBjIDwgMCB0aGVuXG4gICAgICAgICAgICAgIGxldCBsbCA9IHJlbW92ZSB4IGwgaW5cbiAgICAgICAgICAgICAgaWYgbCA9PSBsbCB0aGVuIHRcbiAgICAgICAgICAgICAgZWxzZSBiYWwgbGwgdiByXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgIGxldCByciA9IHJlbW92ZSB4IHIgaW5cbiAgICAgICAgICAgICAgaWYgciA9PSByciB0aGVuIHRcbiAgICAgICAgICAgICAgZWxzZSBiYWwgbCB2IHJyXG5cbiAgICBsZXQgcmVjIHVuaW9uIHMxIHMyID1cbiAgICAgIG1hdGNoIChzMSwgczIpIHdpdGhcbiAgICAgICAgKEVtcHR5LCB0MikgLT4gdDJcbiAgICAgIHwgKHQxLCBFbXB0eSkgLT4gdDFcbiAgICAgIHwgKE5vZGV7bD1sMTsgdj12MTsgcj1yMTsgaD1oMX0sIE5vZGV7bD1sMjsgdj12Mjsgcj1yMjsgaD1oMn0pIC0+XG4gICAgICAgICAgaWYgaDEgPj0gaDIgdGhlblxuICAgICAgICAgICAgaWYgaDIgPSAxIHRoZW4gYWRkIHYyIHMxIGVsc2UgYmVnaW5cbiAgICAgICAgICAgICAgbGV0IChsMiwgXywgcjIpID0gc3BsaXQgdjEgczIgaW5cbiAgICAgICAgICAgICAgam9pbiAodW5pb24gbDEgbDIpIHYxICh1bmlvbiByMSByMilcbiAgICAgICAgICAgIGVuZFxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGlmIGgxID0gMSB0aGVuIGFkZCB2MSBzMiBlbHNlIGJlZ2luXG4gICAgICAgICAgICAgIGxldCAobDEsIF8sIHIxKSA9IHNwbGl0IHYyIHMxIGluXG4gICAgICAgICAgICAgIGpvaW4gKHVuaW9uIGwxIGwyKSB2MiAodW5pb24gcjEgcjIpXG4gICAgICAgICAgICBlbmRcblxuICAgIGxldCByZWMgaW50ZXIgczEgczIgPVxuICAgICAgbWF0Y2ggKHMxLCBzMikgd2l0aFxuICAgICAgICAoRW1wdHksIF8pIC0+IEVtcHR5XG4gICAgICB8IChfLCBFbXB0eSkgLT4gRW1wdHlcbiAgICAgIHwgKE5vZGV7bD1sMTsgdj12MTsgcj1yMX0sIHQyKSAtPlxuICAgICAgICAgIG1hdGNoIHNwbGl0IHYxIHQyIHdpdGhcbiAgICAgICAgICAgIChsMiwgZmFsc2UsIHIyKSAtPlxuICAgICAgICAgICAgICBjb25jYXQgKGludGVyIGwxIGwyKSAoaW50ZXIgcjEgcjIpXG4gICAgICAgICAgfCAobDIsIHRydWUsIHIyKSAtPlxuICAgICAgICAgICAgICBqb2luIChpbnRlciBsMSBsMikgdjEgKGludGVyIHIxIHIyKVxuXG4gICAgKCogU2FtZSBhcyBzcGxpdCwgYnV0IGNvbXB1dGUgdGhlIGxlZnQgYW5kIHJpZ2h0IHN1YnRyZWVzXG4gICAgICAgb25seSBpZiB0aGUgcGl2b3QgZWxlbWVudCBpcyBub3QgaW4gdGhlIHNldC4gIFRoZSByaWdodCBzdWJ0cmVlXG4gICAgICAgaXMgY29tcHV0ZWQgb24gZGVtYW5kLiAqKVxuXG4gICAgdHlwZSBzcGxpdF9iaXMgPVxuICAgICAgfCBGb3VuZFxuICAgICAgfCBOb3RGb3VuZCBvZiB0ICogKHVuaXQgLT4gdClcblxuICAgIGxldCByZWMgc3BsaXRfYmlzIHggPSBmdW5jdGlvblxuICAgICAgICBFbXB0eSAtPlxuICAgICAgICAgIE5vdEZvdW5kIChFbXB0eSwgKGZ1biAoKSAtPiBFbXB0eSkpXG4gICAgICB8IE5vZGV7bDsgdjsgcjsgX30gLT5cbiAgICAgICAgICBsZXQgYyA9IE9yZC5jb21wYXJlIHggdiBpblxuICAgICAgICAgIGlmIGMgPSAwIHRoZW4gRm91bmRcbiAgICAgICAgICBlbHNlIGlmIGMgPCAwIHRoZW5cbiAgICAgICAgICAgIG1hdGNoIHNwbGl0X2JpcyB4IGwgd2l0aFxuICAgICAgICAgICAgfCBGb3VuZCAtPiBGb3VuZFxuICAgICAgICAgICAgfCBOb3RGb3VuZCAobGwsIHJsKSAtPiBOb3RGb3VuZCAobGwsIChmdW4gKCkgLT4gam9pbiAocmwgKCkpIHYgcikpXG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgbWF0Y2ggc3BsaXRfYmlzIHggciB3aXRoXG4gICAgICAgICAgICB8IEZvdW5kIC0+IEZvdW5kXG4gICAgICAgICAgICB8IE5vdEZvdW5kIChsciwgcnIpIC0+IE5vdEZvdW5kIChqb2luIGwgdiBsciwgcnIpXG5cbiAgICBsZXQgcmVjIGRpc2pvaW50IHMxIHMyID1cbiAgICAgIG1hdGNoIChzMSwgczIpIHdpdGhcbiAgICAgICAgKEVtcHR5LCBfKSB8IChfLCBFbXB0eSkgLT4gdHJ1ZVxuICAgICAgfCAoTm9kZXtsPWwxOyB2PXYxOyByPXIxfSwgdDIpIC0+XG4gICAgICAgICAgaWYgczEgPT0gczIgdGhlbiBmYWxzZVxuICAgICAgICAgIGVsc2UgbWF0Y2ggc3BsaXRfYmlzIHYxIHQyIHdpdGhcbiAgICAgICAgICAgICAgTm90Rm91bmQobDIsIHIyKSAtPiBkaXNqb2ludCBsMSBsMiAmJiBkaXNqb2ludCByMSAocjIgKCkpXG4gICAgICAgICAgICB8IEZvdW5kIC0+IGZhbHNlXG5cbiAgICBsZXQgcmVjIGRpZmYgczEgczIgPVxuICAgICAgbWF0Y2ggKHMxLCBzMikgd2l0aFxuICAgICAgICAoRW1wdHksIF8pIC0+IEVtcHR5XG4gICAgICB8ICh0MSwgRW1wdHkpIC0+IHQxXG4gICAgICB8IChOb2Rle2w9bDE7IHY9djE7IHI9cjF9LCB0MikgLT5cbiAgICAgICAgICBtYXRjaCBzcGxpdCB2MSB0MiB3aXRoXG4gICAgICAgICAgICAobDIsIGZhbHNlLCByMikgLT5cbiAgICAgICAgICAgICAgam9pbiAoZGlmZiBsMSBsMikgdjEgKGRpZmYgcjEgcjIpXG4gICAgICAgICAgfCAobDIsIHRydWUsIHIyKSAtPlxuICAgICAgICAgICAgICBjb25jYXQgKGRpZmYgbDEgbDIpIChkaWZmIHIxIHIyKVxuXG4gICAgdHlwZSBlbnVtZXJhdGlvbiA9IEVuZCB8IE1vcmUgb2YgZWx0ICogdCAqIGVudW1lcmF0aW9uXG5cbiAgICBsZXQgcmVjIGNvbnNfZW51bSBzIGUgPVxuICAgICAgbWF0Y2ggcyB3aXRoXG4gICAgICAgIEVtcHR5IC0+IGVcbiAgICAgIHwgTm9kZXtsOyB2OyByfSAtPiBjb25zX2VudW0gbCAoTW9yZSh2LCByLCBlKSlcblxuICAgIGxldCByZWMgY29tcGFyZV9hdXggZTEgZTIgPVxuICAgICAgICBtYXRjaCAoZTEsIGUyKSB3aXRoXG4gICAgICAgIChFbmQsIEVuZCkgLT4gMFxuICAgICAgfCAoRW5kLCBfKSAgLT4gLTFcbiAgICAgIHwgKF8sIEVuZCkgLT4gMVxuICAgICAgfCAoTW9yZSh2MSwgcjEsIGUxKSwgTW9yZSh2MiwgcjIsIGUyKSkgLT5cbiAgICAgICAgICBsZXQgYyA9IE9yZC5jb21wYXJlIHYxIHYyIGluXG4gICAgICAgICAgaWYgYyA8PiAwXG4gICAgICAgICAgdGhlbiBjXG4gICAgICAgICAgZWxzZSBjb21wYXJlX2F1eCAoY29uc19lbnVtIHIxIGUxKSAoY29uc19lbnVtIHIyIGUyKVxuXG4gICAgbGV0IGNvbXBhcmUgczEgczIgPVxuICAgICAgY29tcGFyZV9hdXggKGNvbnNfZW51bSBzMSBFbmQpIChjb25zX2VudW0gczIgRW5kKVxuXG4gICAgbGV0IGVxdWFsIHMxIHMyID1cbiAgICAgIGNvbXBhcmUgczEgczIgPSAwXG5cbiAgICBsZXQgcmVjIHN1YnNldCBzMSBzMiA9XG4gICAgICBtYXRjaCAoczEsIHMyKSB3aXRoXG4gICAgICAgIEVtcHR5LCBfIC0+XG4gICAgICAgICAgdHJ1ZVxuICAgICAgfCBfLCBFbXB0eSAtPlxuICAgICAgICAgIGZhbHNlXG4gICAgICB8IE5vZGUge2w9bDE7IHY9djE7IHI9cjF9LCAoTm9kZSB7bD1sMjsgdj12Mjsgcj1yMn0gYXMgdDIpIC0+XG4gICAgICAgICAgbGV0IGMgPSBPcmQuY29tcGFyZSB2MSB2MiBpblxuICAgICAgICAgIGlmIGMgPSAwIHRoZW5cbiAgICAgICAgICAgIHN1YnNldCBsMSBsMiAmJiBzdWJzZXQgcjEgcjJcbiAgICAgICAgICBlbHNlIGlmIGMgPCAwIHRoZW5cbiAgICAgICAgICAgIHN1YnNldCAoTm9kZSB7bD1sMTsgdj12MTsgcj1FbXB0eTsgaD0wfSkgbDIgJiYgc3Vic2V0IHIxIHQyXG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgc3Vic2V0IChOb2RlIHtsPUVtcHR5OyB2PXYxOyByPXIxOyBoPTB9KSByMiAmJiBzdWJzZXQgbDEgdDJcblxuICAgIGxldCByZWMgaXRlciBmID0gZnVuY3Rpb25cbiAgICAgICAgRW1wdHkgLT4gKClcbiAgICAgIHwgTm9kZXtsOyB2OyByfSAtPiBpdGVyIGYgbDsgZiB2OyBpdGVyIGYgclxuXG4gICAgbGV0IHJlYyBmb2xkIGYgcyBhY2N1ID1cbiAgICAgIG1hdGNoIHMgd2l0aFxuICAgICAgICBFbXB0eSAtPiBhY2N1XG4gICAgICB8IE5vZGV7bDsgdjsgcn0gLT4gZm9sZCBmIHIgKGYgdiAoZm9sZCBmIGwgYWNjdSkpXG5cbiAgICBsZXQgcmVjIGZvcl9hbGwgcCA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+IHRydWVcbiAgICAgIHwgTm9kZXtsOyB2OyByfSAtPiBwIHYgJiYgZm9yX2FsbCBwIGwgJiYgZm9yX2FsbCBwIHJcblxuICAgIGxldCByZWMgZXhpc3RzIHAgPSBmdW5jdGlvblxuICAgICAgICBFbXB0eSAtPiBmYWxzZVxuICAgICAgfCBOb2Rle2w7IHY7IHJ9IC0+IHAgdiB8fCBleGlzdHMgcCBsIHx8IGV4aXN0cyBwIHJcblxuICAgIGxldCByZWMgZmlsdGVyIHAgPSBmdW5jdGlvblxuICAgICAgICBFbXB0eSAtPiBFbXB0eVxuICAgICAgfCAoTm9kZXtsOyB2OyByfSkgYXMgdCAtPlxuICAgICAgICAgICgqIGNhbGwgW3BdIGluIHRoZSBleHBlY3RlZCBsZWZ0LXRvLXJpZ2h0IG9yZGVyICopXG4gICAgICAgICAgbGV0IGwnID0gZmlsdGVyIHAgbCBpblxuICAgICAgICAgIGxldCBwdiA9IHAgdiBpblxuICAgICAgICAgIGxldCByJyA9IGZpbHRlciBwIHIgaW5cbiAgICAgICAgICBpZiBwdiB0aGVuXG4gICAgICAgICAgICBpZiBsPT1sJyAmJiByPT1yJyB0aGVuIHQgZWxzZSBqb2luIGwnIHYgcidcbiAgICAgICAgICBlbHNlIGNvbmNhdCBsJyByJ1xuXG4gICAgbGV0IHJlYyBwYXJ0aXRpb24gcCA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+IChFbXB0eSwgRW1wdHkpXG4gICAgICB8IE5vZGV7bDsgdjsgcn0gLT5cbiAgICAgICAgICAoKiBjYWxsIFtwXSBpbiB0aGUgZXhwZWN0ZWQgbGVmdC10by1yaWdodCBvcmRlciAqKVxuICAgICAgICAgIGxldCAobHQsIGxmKSA9IHBhcnRpdGlvbiBwIGwgaW5cbiAgICAgICAgICBsZXQgcHYgPSBwIHYgaW5cbiAgICAgICAgICBsZXQgKHJ0LCByZikgPSBwYXJ0aXRpb24gcCByIGluXG4gICAgICAgICAgaWYgcHZcbiAgICAgICAgICB0aGVuIChqb2luIGx0IHYgcnQsIGNvbmNhdCBsZiByZilcbiAgICAgICAgICBlbHNlIChjb25jYXQgbHQgcnQsIGpvaW4gbGYgdiByZilcblxuICAgIGxldCByZWMgY2FyZGluYWwgPSBmdW5jdGlvblxuICAgICAgICBFbXB0eSAtPiAwXG4gICAgICB8IE5vZGV7bDsgcn0gLT4gY2FyZGluYWwgbCArIDEgKyBjYXJkaW5hbCByXG5cbiAgICBsZXQgcmVjIGVsZW1lbnRzX2F1eCBhY2N1ID0gZnVuY3Rpb25cbiAgICAgICAgRW1wdHkgLT4gYWNjdVxuICAgICAgfCBOb2Rle2w7IHY7IHJ9IC0+IGVsZW1lbnRzX2F1eCAodiA6OiBlbGVtZW50c19hdXggYWNjdSByKSBsXG5cbiAgICBsZXQgZWxlbWVudHMgcyA9XG4gICAgICBlbGVtZW50c19hdXggW10gc1xuXG4gICAgbGV0IGNob29zZSA9IG1pbl9lbHRcblxuICAgIGxldCBjaG9vc2Vfb3B0ID0gbWluX2VsdF9vcHRcblxuICAgIGxldCByZWMgZmluZCB4ID0gZnVuY3Rpb25cbiAgICAgICAgRW1wdHkgLT4gcmFpc2UgTm90X2ZvdW5kXG4gICAgICB8IE5vZGV7bDsgdjsgcn0gLT5cbiAgICAgICAgICBsZXQgYyA9IE9yZC5jb21wYXJlIHggdiBpblxuICAgICAgICAgIGlmIGMgPSAwIHRoZW4gdlxuICAgICAgICAgIGVsc2UgZmluZCB4IChpZiBjIDwgMCB0aGVuIGwgZWxzZSByKVxuXG4gICAgbGV0IHJlYyBmaW5kX2ZpcnN0X2F1eCB2MCBmID0gZnVuY3Rpb25cbiAgICAgICAgRW1wdHkgLT5cbiAgICAgICAgICB2MFxuICAgICAgfCBOb2Rle2w7IHY7IHJ9IC0+XG4gICAgICAgICAgaWYgZiB2IHRoZW5cbiAgICAgICAgICAgIGZpbmRfZmlyc3RfYXV4IHYgZiBsXG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgZmluZF9maXJzdF9hdXggdjAgZiByXG5cbiAgICBsZXQgcmVjIGZpbmRfZmlyc3QgZiA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+XG4gICAgICAgICAgcmFpc2UgTm90X2ZvdW5kXG4gICAgICB8IE5vZGV7bDsgdjsgcn0gLT5cbiAgICAgICAgICBpZiBmIHYgdGhlblxuICAgICAgICAgICAgZmluZF9maXJzdF9hdXggdiBmIGxcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICBmaW5kX2ZpcnN0IGYgclxuXG4gICAgbGV0IHJlYyBmaW5kX2ZpcnN0X29wdF9hdXggdjAgZiA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+XG4gICAgICAgICAgU29tZSB2MFxuICAgICAgfCBOb2Rle2w7IHY7IHJ9IC0+XG4gICAgICAgICAgaWYgZiB2IHRoZW5cbiAgICAgICAgICAgIGZpbmRfZmlyc3Rfb3B0X2F1eCB2IGYgbFxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGZpbmRfZmlyc3Rfb3B0X2F1eCB2MCBmIHJcblxuICAgIGxldCByZWMgZmluZF9maXJzdF9vcHQgZiA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+XG4gICAgICAgICAgTm9uZVxuICAgICAgfCBOb2Rle2w7IHY7IHJ9IC0+XG4gICAgICAgICAgaWYgZiB2IHRoZW5cbiAgICAgICAgICAgIGZpbmRfZmlyc3Rfb3B0X2F1eCB2IGYgbFxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGZpbmRfZmlyc3Rfb3B0IGYgclxuXG4gICAgbGV0IHJlYyBmaW5kX2xhc3RfYXV4IHYwIGYgPSBmdW5jdGlvblxuICAgICAgICBFbXB0eSAtPlxuICAgICAgICAgIHYwXG4gICAgICB8IE5vZGV7bDsgdjsgcn0gLT5cbiAgICAgICAgICBpZiBmIHYgdGhlblxuICAgICAgICAgICAgZmluZF9sYXN0X2F1eCB2IGYgclxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGZpbmRfbGFzdF9hdXggdjAgZiBsXG5cbiAgICBsZXQgcmVjIGZpbmRfbGFzdCBmID0gZnVuY3Rpb25cbiAgICAgICAgRW1wdHkgLT5cbiAgICAgICAgICByYWlzZSBOb3RfZm91bmRcbiAgICAgIHwgTm9kZXtsOyB2OyByfSAtPlxuICAgICAgICAgIGlmIGYgdiB0aGVuXG4gICAgICAgICAgICBmaW5kX2xhc3RfYXV4IHYgZiByXG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgZmluZF9sYXN0IGYgbFxuXG4gICAgbGV0IHJlYyBmaW5kX2xhc3Rfb3B0X2F1eCB2MCBmID0gZnVuY3Rpb25cbiAgICAgICAgRW1wdHkgLT5cbiAgICAgICAgICBTb21lIHYwXG4gICAgICB8IE5vZGV7bDsgdjsgcn0gLT5cbiAgICAgICAgICBpZiBmIHYgdGhlblxuICAgICAgICAgICAgZmluZF9sYXN0X29wdF9hdXggdiBmIHJcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICBmaW5kX2xhc3Rfb3B0X2F1eCB2MCBmIGxcblxuICAgIGxldCByZWMgZmluZF9sYXN0X29wdCBmID0gZnVuY3Rpb25cbiAgICAgICAgRW1wdHkgLT5cbiAgICAgICAgICBOb25lXG4gICAgICB8IE5vZGV7bDsgdjsgcn0gLT5cbiAgICAgICAgICBpZiBmIHYgdGhlblxuICAgICAgICAgICAgZmluZF9sYXN0X29wdF9hdXggdiBmIHJcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICBmaW5kX2xhc3Rfb3B0IGYgbFxuXG4gICAgbGV0IHJlYyBmaW5kX29wdCB4ID0gZnVuY3Rpb25cbiAgICAgICAgRW1wdHkgLT4gTm9uZVxuICAgICAgfCBOb2Rle2w7IHY7IHJ9IC0+XG4gICAgICAgICAgbGV0IGMgPSBPcmQuY29tcGFyZSB4IHYgaW5cbiAgICAgICAgICBpZiBjID0gMCB0aGVuIFNvbWUgdlxuICAgICAgICAgIGVsc2UgZmluZF9vcHQgeCAoaWYgYyA8IDAgdGhlbiBsIGVsc2UgcilcblxuICAgIGxldCB0cnlfam9pbiBsIHYgciA9XG4gICAgICAoKiBbam9pbiBsIHYgcl0gY2FuIG9ubHkgYmUgY2FsbGVkIHdoZW4gKGVsZW1lbnRzIG9mIGwgPCB2IDxcbiAgICAgICAgIGVsZW1lbnRzIG9mIHIpOyB1c2UgW3RyeV9qb2luIGwgdiByXSB3aGVuIHRoaXMgcHJvcGVydHkgbWF5XG4gICAgICAgICBub3QgaG9sZCwgYnV0IHlvdSBob3BlIGl0IGRvZXMgaG9sZCBpbiB0aGUgY29tbW9uIGNhc2UgKilcbiAgICAgIGlmIChsID0gRW1wdHkgfHwgT3JkLmNvbXBhcmUgKG1heF9lbHQgbCkgdiA8IDApXG4gICAgICAmJiAociA9IEVtcHR5IHx8IE9yZC5jb21wYXJlIHYgKG1pbl9lbHQgcikgPCAwKVxuICAgICAgdGhlbiBqb2luIGwgdiByXG4gICAgICBlbHNlIHVuaW9uIGwgKGFkZCB2IHIpXG5cbiAgICBsZXQgcmVjIG1hcCBmID0gZnVuY3Rpb25cbiAgICAgIHwgRW1wdHkgLT4gRW1wdHlcbiAgICAgIHwgTm9kZXtsOyB2OyByfSBhcyB0IC0+XG4gICAgICAgICAoKiBlbmZvcmNlIGxlZnQtdG8tcmlnaHQgZXZhbHVhdGlvbiBvcmRlciAqKVxuICAgICAgICAgbGV0IGwnID0gbWFwIGYgbCBpblxuICAgICAgICAgbGV0IHYnID0gZiB2IGluXG4gICAgICAgICBsZXQgcicgPSBtYXAgZiByIGluXG4gICAgICAgICBpZiBsID09IGwnICYmIHYgPT0gdicgJiYgciA9PSByJyB0aGVuIHRcbiAgICAgICAgIGVsc2UgdHJ5X2pvaW4gbCcgdicgcidcblxuICAgIGxldCB0cnlfY29uY2F0IHQxIHQyID1cbiAgICAgIG1hdGNoICh0MSwgdDIpIHdpdGhcbiAgICAgICAgKEVtcHR5LCB0KSAtPiB0XG4gICAgICB8ICh0LCBFbXB0eSkgLT4gdFxuICAgICAgfCAoXywgXykgLT4gdHJ5X2pvaW4gdDEgKG1pbl9lbHQgdDIpIChyZW1vdmVfbWluX2VsdCB0MilcblxuICAgIGxldCByZWMgZmlsdGVyX21hcCBmID0gZnVuY3Rpb25cbiAgICAgIHwgRW1wdHkgLT4gRW1wdHlcbiAgICAgIHwgTm9kZXtsOyB2OyByfSBhcyB0IC0+XG4gICAgICAgICAoKiBlbmZvcmNlIGxlZnQtdG8tcmlnaHQgZXZhbHVhdGlvbiBvcmRlciAqKVxuICAgICAgICAgbGV0IGwnID0gZmlsdGVyX21hcCBmIGwgaW5cbiAgICAgICAgIGxldCB2JyA9IGYgdiBpblxuICAgICAgICAgbGV0IHInID0gZmlsdGVyX21hcCBmIHIgaW5cbiAgICAgICAgIGJlZ2luIG1hdGNoIHYnIHdpdGhcbiAgICAgICAgICAgfCBTb21lIHYnIC0+XG4gICAgICAgICAgICAgIGlmIGwgPT0gbCcgJiYgdiA9PSB2JyAmJiByID09IHInIHRoZW4gdFxuICAgICAgICAgICAgICBlbHNlIHRyeV9qb2luIGwnIHYnIHInXG4gICAgICAgICAgIHwgTm9uZSAtPlxuICAgICAgICAgICAgICB0cnlfY29uY2F0IGwnIHInXG4gICAgICAgICBlbmRcblxuICAgIGxldCBvZl9zb3J0ZWRfbGlzdCBsID1cbiAgICAgIGxldCByZWMgc3ViIG4gbCA9XG4gICAgICAgIG1hdGNoIG4sIGwgd2l0aFxuICAgICAgICB8IDAsIGwgLT4gRW1wdHksIGxcbiAgICAgICAgfCAxLCB4MCA6OiBsIC0+IE5vZGUge2w9RW1wdHk7IHY9eDA7IHI9RW1wdHk7IGg9MX0sIGxcbiAgICAgICAgfCAyLCB4MCA6OiB4MSA6OiBsIC0+XG4gICAgICAgICAgICBOb2Rle2w9Tm9kZXtsPUVtcHR5OyB2PXgwOyByPUVtcHR5OyBoPTF9OyB2PXgxOyByPUVtcHR5OyBoPTJ9LCBsXG4gICAgICAgIHwgMywgeDAgOjogeDEgOjogeDIgOjogbCAtPlxuICAgICAgICAgICAgTm9kZXtsPU5vZGV7bD1FbXB0eTsgdj14MDsgcj1FbXB0eTsgaD0xfTsgdj14MTtcbiAgICAgICAgICAgICAgICAgcj1Ob2Rle2w9RW1wdHk7IHY9eDI7IHI9RW1wdHk7IGg9MX07IGg9Mn0sIGxcbiAgICAgICAgfCBuLCBsIC0+XG4gICAgICAgICAgbGV0IG5sID0gbiAvIDIgaW5cbiAgICAgICAgICBsZXQgbGVmdCwgbCA9IHN1YiBubCBsIGluXG4gICAgICAgICAgbWF0Y2ggbCB3aXRoXG4gICAgICAgICAgfCBbXSAtPiBhc3NlcnQgZmFsc2VcbiAgICAgICAgICB8IG1pZCA6OiBsIC0+XG4gICAgICAgICAgICBsZXQgcmlnaHQsIGwgPSBzdWIgKG4gLSBubCAtIDEpIGwgaW5cbiAgICAgICAgICAgIGNyZWF0ZSBsZWZ0IG1pZCByaWdodCwgbFxuICAgICAgaW5cbiAgICAgIGZzdCAoc3ViIChMaXN0Lmxlbmd0aCBsKSBsKVxuXG4gICAgbGV0IG9mX2xpc3QgbCA9XG4gICAgICBtYXRjaCBsIHdpdGhcbiAgICAgIHwgW10gLT4gZW1wdHlcbiAgICAgIHwgW3gwXSAtPiBzaW5nbGV0b24geDBcbiAgICAgIHwgW3gwOyB4MV0gLT4gYWRkIHgxIChzaW5nbGV0b24geDApXG4gICAgICB8IFt4MDsgeDE7IHgyXSAtPiBhZGQgeDIgKGFkZCB4MSAoc2luZ2xldG9uIHgwKSlcbiAgICAgIHwgW3gwOyB4MTsgeDI7IHgzXSAtPiBhZGQgeDMgKGFkZCB4MiAoYWRkIHgxIChzaW5nbGV0b24geDApKSlcbiAgICAgIHwgW3gwOyB4MTsgeDI7IHgzOyB4NF0gLT4gYWRkIHg0IChhZGQgeDMgKGFkZCB4MiAoYWRkIHgxIChzaW5nbGV0b24geDApKSkpXG4gICAgICB8IF8gLT4gb2Zfc29ydGVkX2xpc3QgKExpc3Quc29ydF91bmlxIE9yZC5jb21wYXJlIGwpXG5cbiAgICBsZXQgYWRkX3NlcSBpIG0gPVxuICAgICAgU2VxLmZvbGRfbGVmdCAoZnVuIHMgeCAtPiBhZGQgeCBzKSBtIGlcblxuICAgIGxldCBvZl9zZXEgaSA9IGFkZF9zZXEgaSBlbXB0eVxuXG4gICAgbGV0IHJlYyBzZXFfb2ZfZW51bV8gYyAoKSA9IG1hdGNoIGMgd2l0aFxuICAgICAgfCBFbmQgLT4gU2VxLk5pbFxuICAgICAgfCBNb3JlICh4LCB0LCByZXN0KSAtPiBTZXEuQ29ucyAoeCwgc2VxX29mX2VudW1fIChjb25zX2VudW0gdCByZXN0KSlcblxuICAgIGxldCB0b19zZXEgYyA9IHNlcV9vZl9lbnVtXyAoY29uc19lbnVtIGMgRW5kKVxuXG4gICAgbGV0IHJlYyBzbm9jX2VudW0gcyBlID1cbiAgICAgIG1hdGNoIHMgd2l0aFxuICAgICAgICBFbXB0eSAtPiBlXG4gICAgICB8IE5vZGV7bDsgdjsgcn0gLT4gc25vY19lbnVtIHIgKE1vcmUodiwgbCwgZSkpXG5cbiAgICBsZXQgcmVjIHJldl9zZXFfb2ZfZW51bV8gYyAoKSA9IG1hdGNoIGMgd2l0aFxuICAgICAgfCBFbmQgLT4gU2VxLk5pbFxuICAgICAgfCBNb3JlICh4LCB0LCByZXN0KSAtPiBTZXEuQ29ucyAoeCwgcmV2X3NlcV9vZl9lbnVtXyAoc25vY19lbnVtIHQgcmVzdCkpXG5cbiAgICBsZXQgdG9fcmV2X3NlcSBjID0gcmV2X3NlcV9vZl9lbnVtXyAoc25vY19lbnVtIGMgRW5kKVxuXG4gICAgbGV0IHRvX3NlcV9mcm9tIGxvdyBzID1cbiAgICAgIGxldCByZWMgYXV4IGxvdyBzIGMgPSBtYXRjaCBzIHdpdGhcbiAgICAgICAgfCBFbXB0eSAtPiBjXG4gICAgICAgIHwgTm9kZSB7bDsgcjsgdjsgX30gLT5cbiAgICAgICAgICAgIGJlZ2luIG1hdGNoIE9yZC5jb21wYXJlIHYgbG93IHdpdGhcbiAgICAgICAgICAgICAgfCAwIC0+IE1vcmUgKHYsIHIsIGMpXG4gICAgICAgICAgICAgIHwgbiB3aGVuIG48MCAtPiBhdXggbG93IHIgY1xuICAgICAgICAgICAgICB8IF8gLT4gYXV4IGxvdyBsIChNb3JlICh2LCByLCBjKSlcbiAgICAgICAgICAgIGVuZFxuICAgICAgaW5cbiAgICAgIHNlcV9vZl9lbnVtXyAoYXV4IGxvdyBzIEVuZClcbiAgZW5kXG4iLCIoKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9DYW1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICBYYXZpZXIgTGVyb3ksIHByb2pldCBDcmlzdGFsLCBJTlJJQSBSb2NxdWVuY291cnQgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIENvcHlyaWdodCAxOTk2IEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgICAgICopXG4oKiAgICAgZW4gQXV0b21hdGlxdWUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIEFsbCByaWdodHMgcmVzZXJ2ZWQuICBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mICAgICopXG4oKiAgIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyLjEsIHdpdGggdGhlICAgICAgICAgICopXG4oKiAgIHNwZWNpYWwgZXhjZXB0aW9uIG9uIGxpbmtpbmcgZGVzY3JpYmVkIGluIHRoZSBmaWxlIExJQ0VOU0UuICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG5cbm1vZHVsZSB0eXBlIE9yZGVyZWRUeXBlID1cbiAgc2lnXG4gICAgdHlwZSB0XG4gICAgdmFsIGNvbXBhcmU6IHQgLT4gdCAtPiBpbnRcbiAgZW5kXG5cbm1vZHVsZSB0eXBlIFMgPVxuICBzaWdcbiAgICB0eXBlIGtleVxuICAgIHR5cGUgISsnYSB0XG4gICAgdmFsIGVtcHR5OiAnYSB0XG4gICAgdmFsIGlzX2VtcHR5OiAnYSB0IC0+IGJvb2xcbiAgICB2YWwgbWVtOiAga2V5IC0+ICdhIHQgLT4gYm9vbFxuICAgIHZhbCBhZGQ6IGtleSAtPiAnYSAtPiAnYSB0IC0+ICdhIHRcbiAgICB2YWwgdXBkYXRlOiBrZXkgLT4gKCdhIG9wdGlvbiAtPiAnYSBvcHRpb24pIC0+ICdhIHQgLT4gJ2EgdFxuICAgIHZhbCBzaW5nbGV0b246IGtleSAtPiAnYSAtPiAnYSB0XG4gICAgdmFsIHJlbW92ZToga2V5IC0+ICdhIHQgLT4gJ2EgdFxuICAgIHZhbCBtZXJnZTpcbiAgICAgICAgICAoa2V5IC0+ICdhIG9wdGlvbiAtPiAnYiBvcHRpb24gLT4gJ2Mgb3B0aW9uKSAtPiAnYSB0IC0+ICdiIHQgLT4gJ2MgdFxuICAgIHZhbCB1bmlvbjogKGtleSAtPiAnYSAtPiAnYSAtPiAnYSBvcHRpb24pIC0+ICdhIHQgLT4gJ2EgdCAtPiAnYSB0XG4gICAgdmFsIGNvbXBhcmU6ICgnYSAtPiAnYSAtPiBpbnQpIC0+ICdhIHQgLT4gJ2EgdCAtPiBpbnRcbiAgICB2YWwgZXF1YWw6ICgnYSAtPiAnYSAtPiBib29sKSAtPiAnYSB0IC0+ICdhIHQgLT4gYm9vbFxuICAgIHZhbCBpdGVyOiAoa2V5IC0+ICdhIC0+IHVuaXQpIC0+ICdhIHQgLT4gdW5pdFxuICAgIHZhbCBmb2xkOiAoa2V5IC0+ICdhIC0+ICdiIC0+ICdiKSAtPiAnYSB0IC0+ICdiIC0+ICdiXG4gICAgdmFsIGZvcl9hbGw6IChrZXkgLT4gJ2EgLT4gYm9vbCkgLT4gJ2EgdCAtPiBib29sXG4gICAgdmFsIGV4aXN0czogKGtleSAtPiAnYSAtPiBib29sKSAtPiAnYSB0IC0+IGJvb2xcbiAgICB2YWwgZmlsdGVyOiAoa2V5IC0+ICdhIC0+IGJvb2wpIC0+ICdhIHQgLT4gJ2EgdFxuICAgIHZhbCBmaWx0ZXJfbWFwOiAoa2V5IC0+ICdhIC0+ICdiIG9wdGlvbikgLT4gJ2EgdCAtPiAnYiB0XG4gICAgdmFsIHBhcnRpdGlvbjogKGtleSAtPiAnYSAtPiBib29sKSAtPiAnYSB0IC0+ICdhIHQgKiAnYSB0XG4gICAgdmFsIGNhcmRpbmFsOiAnYSB0IC0+IGludFxuICAgIHZhbCBiaW5kaW5nczogJ2EgdCAtPiAoa2V5ICogJ2EpIGxpc3RcbiAgICB2YWwgbWluX2JpbmRpbmc6ICdhIHQgLT4gKGtleSAqICdhKVxuICAgIHZhbCBtaW5fYmluZGluZ19vcHQ6ICdhIHQgLT4gKGtleSAqICdhKSBvcHRpb25cbiAgICB2YWwgbWF4X2JpbmRpbmc6ICdhIHQgLT4gKGtleSAqICdhKVxuICAgIHZhbCBtYXhfYmluZGluZ19vcHQ6ICdhIHQgLT4gKGtleSAqICdhKSBvcHRpb25cbiAgICB2YWwgY2hvb3NlOiAnYSB0IC0+IChrZXkgKiAnYSlcbiAgICB2YWwgY2hvb3NlX29wdDogJ2EgdCAtPiAoa2V5ICogJ2EpIG9wdGlvblxuICAgIHZhbCBzcGxpdDoga2V5IC0+ICdhIHQgLT4gJ2EgdCAqICdhIG9wdGlvbiAqICdhIHRcbiAgICB2YWwgZmluZDoga2V5IC0+ICdhIHQgLT4gJ2FcbiAgICB2YWwgZmluZF9vcHQ6IGtleSAtPiAnYSB0IC0+ICdhIG9wdGlvblxuICAgIHZhbCBmaW5kX2ZpcnN0OiAoa2V5IC0+IGJvb2wpIC0+ICdhIHQgLT4ga2V5ICogJ2FcbiAgICB2YWwgZmluZF9maXJzdF9vcHQ6IChrZXkgLT4gYm9vbCkgLT4gJ2EgdCAtPiAoa2V5ICogJ2EpIG9wdGlvblxuICAgIHZhbCBmaW5kX2xhc3Q6IChrZXkgLT4gYm9vbCkgLT4gJ2EgdCAtPiBrZXkgKiAnYVxuICAgIHZhbCBmaW5kX2xhc3Rfb3B0OiAoa2V5IC0+IGJvb2wpIC0+ICdhIHQgLT4gKGtleSAqICdhKSBvcHRpb25cbiAgICB2YWwgbWFwOiAoJ2EgLT4gJ2IpIC0+ICdhIHQgLT4gJ2IgdFxuICAgIHZhbCBtYXBpOiAoa2V5IC0+ICdhIC0+ICdiKSAtPiAnYSB0IC0+ICdiIHRcbiAgICB2YWwgdG9fc2VxIDogJ2EgdCAtPiAoa2V5ICogJ2EpIFNlcS50XG4gICAgdmFsIHRvX3Jldl9zZXEgOiAnYSB0IC0+IChrZXkgKiAnYSkgU2VxLnRcbiAgICB2YWwgdG9fc2VxX2Zyb20gOiBrZXkgLT4gJ2EgdCAtPiAoa2V5ICogJ2EpIFNlcS50XG4gICAgdmFsIGFkZF9zZXEgOiAoa2V5ICogJ2EpIFNlcS50IC0+ICdhIHQgLT4gJ2EgdFxuICAgIHZhbCBvZl9zZXEgOiAoa2V5ICogJ2EpIFNlcS50IC0+ICdhIHRcbiAgZW5kXG5cbm1vZHVsZSBNYWtlKE9yZDogT3JkZXJlZFR5cGUpID0gc3RydWN0XG5cbiAgICB0eXBlIGtleSA9IE9yZC50XG5cbiAgICB0eXBlICdhIHQgPVxuICAgICAgICBFbXB0eVxuICAgICAgfCBOb2RlIG9mIHtsOidhIHQ7IHY6a2V5OyBkOidhOyByOidhIHQ7IGg6aW50fVxuXG4gICAgbGV0IGhlaWdodCA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+IDBcbiAgICAgIHwgTm9kZSB7aH0gLT4gaFxuXG4gICAgbGV0IGNyZWF0ZSBsIHggZCByID1cbiAgICAgIGxldCBobCA9IGhlaWdodCBsIGFuZCBociA9IGhlaWdodCByIGluXG4gICAgICBOb2Rle2w7IHY9eDsgZDsgcjsgaD0oaWYgaGwgPj0gaHIgdGhlbiBobCArIDEgZWxzZSBociArIDEpfVxuXG4gICAgbGV0IHNpbmdsZXRvbiB4IGQgPSBOb2Rle2w9RW1wdHk7IHY9eDsgZDsgcj1FbXB0eTsgaD0xfVxuXG4gICAgbGV0IGJhbCBsIHggZCByID1cbiAgICAgIGxldCBobCA9IG1hdGNoIGwgd2l0aCBFbXB0eSAtPiAwIHwgTm9kZSB7aH0gLT4gaCBpblxuICAgICAgbGV0IGhyID0gbWF0Y2ggciB3aXRoIEVtcHR5IC0+IDAgfCBOb2RlIHtofSAtPiBoIGluXG4gICAgICBpZiBobCA+IGhyICsgMiB0aGVuIGJlZ2luXG4gICAgICAgIG1hdGNoIGwgd2l0aFxuICAgICAgICAgIEVtcHR5IC0+IGludmFsaWRfYXJnIFwiTWFwLmJhbFwiXG4gICAgICAgIHwgTm9kZXtsPWxsOyB2PWx2OyBkPWxkOyByPWxyfSAtPlxuICAgICAgICAgICAgaWYgaGVpZ2h0IGxsID49IGhlaWdodCBsciB0aGVuXG4gICAgICAgICAgICAgIGNyZWF0ZSBsbCBsdiBsZCAoY3JlYXRlIGxyIHggZCByKVxuICAgICAgICAgICAgZWxzZSBiZWdpblxuICAgICAgICAgICAgICBtYXRjaCBsciB3aXRoXG4gICAgICAgICAgICAgICAgRW1wdHkgLT4gaW52YWxpZF9hcmcgXCJNYXAuYmFsXCJcbiAgICAgICAgICAgICAgfCBOb2Rle2w9bHJsOyB2PWxydjsgZD1scmQ7IHI9bHJyfS0+XG4gICAgICAgICAgICAgICAgICBjcmVhdGUgKGNyZWF0ZSBsbCBsdiBsZCBscmwpIGxydiBscmQgKGNyZWF0ZSBscnIgeCBkIHIpXG4gICAgICAgICAgICBlbmRcbiAgICAgIGVuZCBlbHNlIGlmIGhyID4gaGwgKyAyIHRoZW4gYmVnaW5cbiAgICAgICAgbWF0Y2ggciB3aXRoXG4gICAgICAgICAgRW1wdHkgLT4gaW52YWxpZF9hcmcgXCJNYXAuYmFsXCJcbiAgICAgICAgfCBOb2Rle2w9cmw7IHY9cnY7IGQ9cmQ7IHI9cnJ9IC0+XG4gICAgICAgICAgICBpZiBoZWlnaHQgcnIgPj0gaGVpZ2h0IHJsIHRoZW5cbiAgICAgICAgICAgICAgY3JlYXRlIChjcmVhdGUgbCB4IGQgcmwpIHJ2IHJkIHJyXG4gICAgICAgICAgICBlbHNlIGJlZ2luXG4gICAgICAgICAgICAgIG1hdGNoIHJsIHdpdGhcbiAgICAgICAgICAgICAgICBFbXB0eSAtPiBpbnZhbGlkX2FyZyBcIk1hcC5iYWxcIlxuICAgICAgICAgICAgICB8IE5vZGV7bD1ybGw7IHY9cmx2OyBkPXJsZDsgcj1ybHJ9IC0+XG4gICAgICAgICAgICAgICAgICBjcmVhdGUgKGNyZWF0ZSBsIHggZCBybGwpIHJsdiBybGQgKGNyZWF0ZSBybHIgcnYgcmQgcnIpXG4gICAgICAgICAgICBlbmRcbiAgICAgIGVuZCBlbHNlXG4gICAgICAgIE5vZGV7bDsgdj14OyBkOyByOyBoPShpZiBobCA+PSBociB0aGVuIGhsICsgMSBlbHNlIGhyICsgMSl9XG5cbiAgICBsZXQgZW1wdHkgPSBFbXB0eVxuXG4gICAgbGV0IGlzX2VtcHR5ID0gZnVuY3Rpb24gRW1wdHkgLT4gdHJ1ZSB8IF8gLT4gZmFsc2VcblxuICAgIGxldCByZWMgYWRkIHggZGF0YSA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+XG4gICAgICAgICAgTm9kZXtsPUVtcHR5OyB2PXg7IGQ9ZGF0YTsgcj1FbXB0eTsgaD0xfVxuICAgICAgfCBOb2RlIHtsOyB2OyBkOyByOyBofSBhcyBtIC0+XG4gICAgICAgICAgbGV0IGMgPSBPcmQuY29tcGFyZSB4IHYgaW5cbiAgICAgICAgICBpZiBjID0gMCB0aGVuXG4gICAgICAgICAgICBpZiBkID09IGRhdGEgdGhlbiBtIGVsc2UgTm9kZXtsOyB2PXg7IGQ9ZGF0YTsgcjsgaH1cbiAgICAgICAgICBlbHNlIGlmIGMgPCAwIHRoZW5cbiAgICAgICAgICAgIGxldCBsbCA9IGFkZCB4IGRhdGEgbCBpblxuICAgICAgICAgICAgaWYgbCA9PSBsbCB0aGVuIG0gZWxzZSBiYWwgbGwgdiBkIHJcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICBsZXQgcnIgPSBhZGQgeCBkYXRhIHIgaW5cbiAgICAgICAgICAgIGlmIHIgPT0gcnIgdGhlbiBtIGVsc2UgYmFsIGwgdiBkIHJyXG5cbiAgICBsZXQgcmVjIGZpbmQgeCA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+XG4gICAgICAgICAgcmFpc2UgTm90X2ZvdW5kXG4gICAgICB8IE5vZGUge2w7IHY7IGQ7IHJ9IC0+XG4gICAgICAgICAgbGV0IGMgPSBPcmQuY29tcGFyZSB4IHYgaW5cbiAgICAgICAgICBpZiBjID0gMCB0aGVuIGRcbiAgICAgICAgICBlbHNlIGZpbmQgeCAoaWYgYyA8IDAgdGhlbiBsIGVsc2UgcilcblxuICAgIGxldCByZWMgZmluZF9maXJzdF9hdXggdjAgZDAgZiA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+XG4gICAgICAgICAgKHYwLCBkMClcbiAgICAgIHwgTm9kZSB7bDsgdjsgZDsgcn0gLT5cbiAgICAgICAgICBpZiBmIHYgdGhlblxuICAgICAgICAgICAgZmluZF9maXJzdF9hdXggdiBkIGYgbFxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGZpbmRfZmlyc3RfYXV4IHYwIGQwIGYgclxuXG4gICAgbGV0IHJlYyBmaW5kX2ZpcnN0IGYgPSBmdW5jdGlvblxuICAgICAgICBFbXB0eSAtPlxuICAgICAgICAgIHJhaXNlIE5vdF9mb3VuZFxuICAgICAgfCBOb2RlIHtsOyB2OyBkOyByfSAtPlxuICAgICAgICAgIGlmIGYgdiB0aGVuXG4gICAgICAgICAgICBmaW5kX2ZpcnN0X2F1eCB2IGQgZiBsXG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgZmluZF9maXJzdCBmIHJcblxuICAgIGxldCByZWMgZmluZF9maXJzdF9vcHRfYXV4IHYwIGQwIGYgPSBmdW5jdGlvblxuICAgICAgICBFbXB0eSAtPlxuICAgICAgICAgIFNvbWUgKHYwLCBkMClcbiAgICAgIHwgTm9kZSB7bDsgdjsgZDsgcn0gLT5cbiAgICAgICAgICBpZiBmIHYgdGhlblxuICAgICAgICAgICAgZmluZF9maXJzdF9vcHRfYXV4IHYgZCBmIGxcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICBmaW5kX2ZpcnN0X29wdF9hdXggdjAgZDAgZiByXG5cbiAgICBsZXQgcmVjIGZpbmRfZmlyc3Rfb3B0IGYgPSBmdW5jdGlvblxuICAgICAgICBFbXB0eSAtPlxuICAgICAgICAgIE5vbmVcbiAgICAgIHwgTm9kZSB7bDsgdjsgZDsgcn0gLT5cbiAgICAgICAgICBpZiBmIHYgdGhlblxuICAgICAgICAgICAgZmluZF9maXJzdF9vcHRfYXV4IHYgZCBmIGxcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICBmaW5kX2ZpcnN0X29wdCBmIHJcblxuICAgIGxldCByZWMgZmluZF9sYXN0X2F1eCB2MCBkMCBmID0gZnVuY3Rpb25cbiAgICAgICAgRW1wdHkgLT5cbiAgICAgICAgICAodjAsIGQwKVxuICAgICAgfCBOb2RlIHtsOyB2OyBkOyByfSAtPlxuICAgICAgICAgIGlmIGYgdiB0aGVuXG4gICAgICAgICAgICBmaW5kX2xhc3RfYXV4IHYgZCBmIHJcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICBmaW5kX2xhc3RfYXV4IHYwIGQwIGYgbFxuXG4gICAgbGV0IHJlYyBmaW5kX2xhc3QgZiA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+XG4gICAgICAgICAgcmFpc2UgTm90X2ZvdW5kXG4gICAgICB8IE5vZGUge2w7IHY7IGQ7IHJ9IC0+XG4gICAgICAgICAgaWYgZiB2IHRoZW5cbiAgICAgICAgICAgIGZpbmRfbGFzdF9hdXggdiBkIGYgclxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGZpbmRfbGFzdCBmIGxcblxuICAgIGxldCByZWMgZmluZF9sYXN0X29wdF9hdXggdjAgZDAgZiA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+XG4gICAgICAgICAgU29tZSAodjAsIGQwKVxuICAgICAgfCBOb2RlIHtsOyB2OyBkOyByfSAtPlxuICAgICAgICAgIGlmIGYgdiB0aGVuXG4gICAgICAgICAgICBmaW5kX2xhc3Rfb3B0X2F1eCB2IGQgZiByXG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgZmluZF9sYXN0X29wdF9hdXggdjAgZDAgZiBsXG5cbiAgICBsZXQgcmVjIGZpbmRfbGFzdF9vcHQgZiA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+XG4gICAgICAgICAgTm9uZVxuICAgICAgfCBOb2RlIHtsOyB2OyBkOyByfSAtPlxuICAgICAgICAgIGlmIGYgdiB0aGVuXG4gICAgICAgICAgICBmaW5kX2xhc3Rfb3B0X2F1eCB2IGQgZiByXG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgZmluZF9sYXN0X29wdCBmIGxcblxuICAgIGxldCByZWMgZmluZF9vcHQgeCA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+XG4gICAgICAgICAgTm9uZVxuICAgICAgfCBOb2RlIHtsOyB2OyBkOyByfSAtPlxuICAgICAgICAgIGxldCBjID0gT3JkLmNvbXBhcmUgeCB2IGluXG4gICAgICAgICAgaWYgYyA9IDAgdGhlbiBTb21lIGRcbiAgICAgICAgICBlbHNlIGZpbmRfb3B0IHggKGlmIGMgPCAwIHRoZW4gbCBlbHNlIHIpXG5cbiAgICBsZXQgcmVjIG1lbSB4ID0gZnVuY3Rpb25cbiAgICAgICAgRW1wdHkgLT5cbiAgICAgICAgICBmYWxzZVxuICAgICAgfCBOb2RlIHtsOyB2OyByfSAtPlxuICAgICAgICAgIGxldCBjID0gT3JkLmNvbXBhcmUgeCB2IGluXG4gICAgICAgICAgYyA9IDAgfHwgbWVtIHggKGlmIGMgPCAwIHRoZW4gbCBlbHNlIHIpXG5cbiAgICBsZXQgcmVjIG1pbl9iaW5kaW5nID0gZnVuY3Rpb25cbiAgICAgICAgRW1wdHkgLT4gcmFpc2UgTm90X2ZvdW5kXG4gICAgICB8IE5vZGUge2w9RW1wdHk7IHY7IGR9IC0+ICh2LCBkKVxuICAgICAgfCBOb2RlIHtsfSAtPiBtaW5fYmluZGluZyBsXG5cbiAgICBsZXQgcmVjIG1pbl9iaW5kaW5nX29wdCA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+IE5vbmVcbiAgICAgIHwgTm9kZSB7bD1FbXB0eTsgdjsgZH0gLT4gU29tZSAodiwgZClcbiAgICAgIHwgTm9kZSB7bH0tPiBtaW5fYmluZGluZ19vcHQgbFxuXG4gICAgbGV0IHJlYyBtYXhfYmluZGluZyA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+IHJhaXNlIE5vdF9mb3VuZFxuICAgICAgfCBOb2RlIHt2OyBkOyByPUVtcHR5fSAtPiAodiwgZClcbiAgICAgIHwgTm9kZSB7cn0gLT4gbWF4X2JpbmRpbmcgclxuXG4gICAgbGV0IHJlYyBtYXhfYmluZGluZ19vcHQgPSBmdW5jdGlvblxuICAgICAgICBFbXB0eSAtPiBOb25lXG4gICAgICB8IE5vZGUge3Y7IGQ7IHI9RW1wdHl9IC0+IFNvbWUgKHYsIGQpXG4gICAgICB8IE5vZGUge3J9IC0+IG1heF9iaW5kaW5nX29wdCByXG5cbiAgICBsZXQgcmVjIHJlbW92ZV9taW5fYmluZGluZyA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+IGludmFsaWRfYXJnIFwiTWFwLnJlbW92ZV9taW5fZWx0XCJcbiAgICAgIHwgTm9kZSB7bD1FbXB0eTsgcn0gLT4gclxuICAgICAgfCBOb2RlIHtsOyB2OyBkOyByfSAtPiBiYWwgKHJlbW92ZV9taW5fYmluZGluZyBsKSB2IGQgclxuXG4gICAgbGV0IG1lcmdlIHQxIHQyID1cbiAgICAgIG1hdGNoICh0MSwgdDIpIHdpdGhcbiAgICAgICAgKEVtcHR5LCB0KSAtPiB0XG4gICAgICB8ICh0LCBFbXB0eSkgLT4gdFxuICAgICAgfCAoXywgXykgLT5cbiAgICAgICAgICBsZXQgKHgsIGQpID0gbWluX2JpbmRpbmcgdDIgaW5cbiAgICAgICAgICBiYWwgdDEgeCBkIChyZW1vdmVfbWluX2JpbmRpbmcgdDIpXG5cbiAgICBsZXQgcmVjIHJlbW92ZSB4ID0gZnVuY3Rpb25cbiAgICAgICAgRW1wdHkgLT5cbiAgICAgICAgICBFbXB0eVxuICAgICAgfCAoTm9kZSB7bDsgdjsgZDsgcn0gYXMgbSkgLT5cbiAgICAgICAgICBsZXQgYyA9IE9yZC5jb21wYXJlIHggdiBpblxuICAgICAgICAgIGlmIGMgPSAwIHRoZW4gbWVyZ2UgbCByXG4gICAgICAgICAgZWxzZSBpZiBjIDwgMCB0aGVuXG4gICAgICAgICAgICBsZXQgbGwgPSByZW1vdmUgeCBsIGluIGlmIGwgPT0gbGwgdGhlbiBtIGVsc2UgYmFsIGxsIHYgZCByXG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgbGV0IHJyID0gcmVtb3ZlIHggciBpbiBpZiByID09IHJyIHRoZW4gbSBlbHNlIGJhbCBsIHYgZCByclxuXG4gICAgbGV0IHJlYyB1cGRhdGUgeCBmID0gZnVuY3Rpb25cbiAgICAgICAgRW1wdHkgLT5cbiAgICAgICAgICBiZWdpbiBtYXRjaCBmIE5vbmUgd2l0aFxuICAgICAgICAgIHwgTm9uZSAtPiBFbXB0eVxuICAgICAgICAgIHwgU29tZSBkYXRhIC0+IE5vZGV7bD1FbXB0eTsgdj14OyBkPWRhdGE7IHI9RW1wdHk7IGg9MX1cbiAgICAgICAgICBlbmRcbiAgICAgIHwgTm9kZSB7bDsgdjsgZDsgcjsgaH0gYXMgbSAtPlxuICAgICAgICAgIGxldCBjID0gT3JkLmNvbXBhcmUgeCB2IGluXG4gICAgICAgICAgaWYgYyA9IDAgdGhlbiBiZWdpblxuICAgICAgICAgICAgbWF0Y2ggZiAoU29tZSBkKSB3aXRoXG4gICAgICAgICAgICB8IE5vbmUgLT4gbWVyZ2UgbCByXG4gICAgICAgICAgICB8IFNvbWUgZGF0YSAtPlxuICAgICAgICAgICAgICAgIGlmIGQgPT0gZGF0YSB0aGVuIG0gZWxzZSBOb2Rle2w7IHY9eDsgZD1kYXRhOyByOyBofVxuICAgICAgICAgIGVuZCBlbHNlIGlmIGMgPCAwIHRoZW5cbiAgICAgICAgICAgIGxldCBsbCA9IHVwZGF0ZSB4IGYgbCBpblxuICAgICAgICAgICAgaWYgbCA9PSBsbCB0aGVuIG0gZWxzZSBiYWwgbGwgdiBkIHJcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICBsZXQgcnIgPSB1cGRhdGUgeCBmIHIgaW5cbiAgICAgICAgICAgIGlmIHIgPT0gcnIgdGhlbiBtIGVsc2UgYmFsIGwgdiBkIHJyXG5cbiAgICBsZXQgcmVjIGl0ZXIgZiA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+ICgpXG4gICAgICB8IE5vZGUge2w7IHY7IGQ7IHJ9IC0+XG4gICAgICAgICAgaXRlciBmIGw7IGYgdiBkOyBpdGVyIGYgclxuXG4gICAgbGV0IHJlYyBtYXAgZiA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+XG4gICAgICAgICAgRW1wdHlcbiAgICAgIHwgTm9kZSB7bDsgdjsgZDsgcjsgaH0gLT5cbiAgICAgICAgICBsZXQgbCcgPSBtYXAgZiBsIGluXG4gICAgICAgICAgbGV0IGQnID0gZiBkIGluXG4gICAgICAgICAgbGV0IHInID0gbWFwIGYgciBpblxuICAgICAgICAgIE5vZGV7bD1sJzsgdjsgZD1kJzsgcj1yJzsgaH1cblxuICAgIGxldCByZWMgbWFwaSBmID0gZnVuY3Rpb25cbiAgICAgICAgRW1wdHkgLT5cbiAgICAgICAgICBFbXB0eVxuICAgICAgfCBOb2RlIHtsOyB2OyBkOyByOyBofSAtPlxuICAgICAgICAgIGxldCBsJyA9IG1hcGkgZiBsIGluXG4gICAgICAgICAgbGV0IGQnID0gZiB2IGQgaW5cbiAgICAgICAgICBsZXQgcicgPSBtYXBpIGYgciBpblxuICAgICAgICAgIE5vZGV7bD1sJzsgdjsgZD1kJzsgcj1yJzsgaH1cblxuICAgIGxldCByZWMgZm9sZCBmIG0gYWNjdSA9XG4gICAgICBtYXRjaCBtIHdpdGhcbiAgICAgICAgRW1wdHkgLT4gYWNjdVxuICAgICAgfCBOb2RlIHtsOyB2OyBkOyByfSAtPlxuICAgICAgICAgIGZvbGQgZiByIChmIHYgZCAoZm9sZCBmIGwgYWNjdSkpXG5cbiAgICBsZXQgcmVjIGZvcl9hbGwgcCA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+IHRydWVcbiAgICAgIHwgTm9kZSB7bDsgdjsgZDsgcn0gLT4gcCB2IGQgJiYgZm9yX2FsbCBwIGwgJiYgZm9yX2FsbCBwIHJcblxuICAgIGxldCByZWMgZXhpc3RzIHAgPSBmdW5jdGlvblxuICAgICAgICBFbXB0eSAtPiBmYWxzZVxuICAgICAgfCBOb2RlIHtsOyB2OyBkOyByfSAtPiBwIHYgZCB8fCBleGlzdHMgcCBsIHx8IGV4aXN0cyBwIHJcblxuICAgICgqIEJld2FyZTogdGhvc2UgdHdvIGZ1bmN0aW9ucyBhc3N1bWUgdGhhdCB0aGUgYWRkZWQgayBpcyAqc3RyaWN0bHkqXG4gICAgICAgc21hbGxlciAob3IgYmlnZ2VyKSB0aGFuIGFsbCB0aGUgcHJlc2VudCBrZXlzIGluIHRoZSB0cmVlOyBpdFxuICAgICAgIGRvZXMgbm90IHRlc3QgZm9yIGVxdWFsaXR5IHdpdGggdGhlIGN1cnJlbnQgbWluIChvciBtYXgpIGtleS5cblxuICAgICAgIEluZGVlZCwgdGhleSBhcmUgb25seSB1c2VkIGR1cmluZyB0aGUgXCJqb2luXCIgb3BlcmF0aW9uIHdoaWNoXG4gICAgICAgcmVzcGVjdHMgdGhpcyBwcmVjb25kaXRpb24uXG4gICAgKilcblxuICAgIGxldCByZWMgYWRkX21pbl9iaW5kaW5nIGsgeCA9IGZ1bmN0aW9uXG4gICAgICB8IEVtcHR5IC0+IHNpbmdsZXRvbiBrIHhcbiAgICAgIHwgTm9kZSB7bDsgdjsgZDsgcn0gLT5cbiAgICAgICAgYmFsIChhZGRfbWluX2JpbmRpbmcgayB4IGwpIHYgZCByXG5cbiAgICBsZXQgcmVjIGFkZF9tYXhfYmluZGluZyBrIHggPSBmdW5jdGlvblxuICAgICAgfCBFbXB0eSAtPiBzaW5nbGV0b24gayB4XG4gICAgICB8IE5vZGUge2w7IHY7IGQ7IHJ9IC0+XG4gICAgICAgIGJhbCBsIHYgZCAoYWRkX21heF9iaW5kaW5nIGsgeCByKVxuXG4gICAgKCogU2FtZSBhcyBjcmVhdGUgYW5kIGJhbCwgYnV0IG5vIGFzc3VtcHRpb25zIGFyZSBtYWRlIG9uIHRoZVxuICAgICAgIHJlbGF0aXZlIGhlaWdodHMgb2YgbCBhbmQgci4gKilcblxuICAgIGxldCByZWMgam9pbiBsIHYgZCByID1cbiAgICAgIG1hdGNoIChsLCByKSB3aXRoXG4gICAgICAgIChFbXB0eSwgXykgLT4gYWRkX21pbl9iaW5kaW5nIHYgZCByXG4gICAgICB8IChfLCBFbXB0eSkgLT4gYWRkX21heF9iaW5kaW5nIHYgZCBsXG4gICAgICB8IChOb2Rle2w9bGw7IHY9bHY7IGQ9bGQ7IHI9bHI7IGg9bGh9LFxuICAgICAgICAgTm9kZXtsPXJsOyB2PXJ2OyBkPXJkOyByPXJyOyBoPXJofSkgLT5cbiAgICAgICAgICBpZiBsaCA+IHJoICsgMiB0aGVuIGJhbCBsbCBsdiBsZCAoam9pbiBsciB2IGQgcikgZWxzZVxuICAgICAgICAgIGlmIHJoID4gbGggKyAyIHRoZW4gYmFsIChqb2luIGwgdiBkIHJsKSBydiByZCByciBlbHNlXG4gICAgICAgICAgY3JlYXRlIGwgdiBkIHJcblxuICAgICgqIE1lcmdlIHR3byB0cmVlcyBsIGFuZCByIGludG8gb25lLlxuICAgICAgIEFsbCBlbGVtZW50cyBvZiBsIG11c3QgcHJlY2VkZSB0aGUgZWxlbWVudHMgb2Ygci5cbiAgICAgICBObyBhc3N1bXB0aW9uIG9uIHRoZSBoZWlnaHRzIG9mIGwgYW5kIHIuICopXG5cbiAgICBsZXQgY29uY2F0IHQxIHQyID1cbiAgICAgIG1hdGNoICh0MSwgdDIpIHdpdGhcbiAgICAgICAgKEVtcHR5LCB0KSAtPiB0XG4gICAgICB8ICh0LCBFbXB0eSkgLT4gdFxuICAgICAgfCAoXywgXykgLT5cbiAgICAgICAgICBsZXQgKHgsIGQpID0gbWluX2JpbmRpbmcgdDIgaW5cbiAgICAgICAgICBqb2luIHQxIHggZCAocmVtb3ZlX21pbl9iaW5kaW5nIHQyKVxuXG4gICAgbGV0IGNvbmNhdF9vcl9qb2luIHQxIHYgZCB0MiA9XG4gICAgICBtYXRjaCBkIHdpdGhcbiAgICAgIHwgU29tZSBkIC0+IGpvaW4gdDEgdiBkIHQyXG4gICAgICB8IE5vbmUgLT4gY29uY2F0IHQxIHQyXG5cbiAgICBsZXQgcmVjIHNwbGl0IHggPSBmdW5jdGlvblxuICAgICAgICBFbXB0eSAtPlxuICAgICAgICAgIChFbXB0eSwgTm9uZSwgRW1wdHkpXG4gICAgICB8IE5vZGUge2w7IHY7IGQ7IHJ9IC0+XG4gICAgICAgICAgbGV0IGMgPSBPcmQuY29tcGFyZSB4IHYgaW5cbiAgICAgICAgICBpZiBjID0gMCB0aGVuIChsLCBTb21lIGQsIHIpXG4gICAgICAgICAgZWxzZSBpZiBjIDwgMCB0aGVuXG4gICAgICAgICAgICBsZXQgKGxsLCBwcmVzLCBybCkgPSBzcGxpdCB4IGwgaW4gKGxsLCBwcmVzLCBqb2luIHJsIHYgZCByKVxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGxldCAobHIsIHByZXMsIHJyKSA9IHNwbGl0IHggciBpbiAoam9pbiBsIHYgZCBsciwgcHJlcywgcnIpXG5cbiAgICBsZXQgcmVjIG1lcmdlIGYgczEgczIgPVxuICAgICAgbWF0Y2ggKHMxLCBzMikgd2l0aFxuICAgICAgICAoRW1wdHksIEVtcHR5KSAtPiBFbXB0eVxuICAgICAgfCAoTm9kZSB7bD1sMTsgdj12MTsgZD1kMTsgcj1yMTsgaD1oMX0sIF8pIHdoZW4gaDEgPj0gaGVpZ2h0IHMyIC0+XG4gICAgICAgICAgbGV0IChsMiwgZDIsIHIyKSA9IHNwbGl0IHYxIHMyIGluXG4gICAgICAgICAgY29uY2F0X29yX2pvaW4gKG1lcmdlIGYgbDEgbDIpIHYxIChmIHYxIChTb21lIGQxKSBkMikgKG1lcmdlIGYgcjEgcjIpXG4gICAgICB8IChfLCBOb2RlIHtsPWwyOyB2PXYyOyBkPWQyOyByPXIyfSkgLT5cbiAgICAgICAgICBsZXQgKGwxLCBkMSwgcjEpID0gc3BsaXQgdjIgczEgaW5cbiAgICAgICAgICBjb25jYXRfb3Jfam9pbiAobWVyZ2UgZiBsMSBsMikgdjIgKGYgdjIgZDEgKFNvbWUgZDIpKSAobWVyZ2UgZiByMSByMilcbiAgICAgIHwgXyAtPlxuICAgICAgICAgIGFzc2VydCBmYWxzZVxuXG4gICAgbGV0IHJlYyB1bmlvbiBmIHMxIHMyID1cbiAgICAgIG1hdGNoIChzMSwgczIpIHdpdGhcbiAgICAgIHwgKEVtcHR5LCBzKSB8IChzLCBFbXB0eSkgLT4gc1xuICAgICAgfCAoTm9kZSB7bD1sMTsgdj12MTsgZD1kMTsgcj1yMTsgaD1oMX0sXG4gICAgICAgICBOb2RlIHtsPWwyOyB2PXYyOyBkPWQyOyByPXIyOyBoPWgyfSkgLT5cbiAgICAgICAgICBpZiBoMSA+PSBoMiB0aGVuXG4gICAgICAgICAgICBsZXQgKGwyLCBkMiwgcjIpID0gc3BsaXQgdjEgczIgaW5cbiAgICAgICAgICAgIGxldCBsID0gdW5pb24gZiBsMSBsMiBhbmQgciA9IHVuaW9uIGYgcjEgcjIgaW5cbiAgICAgICAgICAgIG1hdGNoIGQyIHdpdGhcbiAgICAgICAgICAgIHwgTm9uZSAtPiBqb2luIGwgdjEgZDEgclxuICAgICAgICAgICAgfCBTb21lIGQyIC0+IGNvbmNhdF9vcl9qb2luIGwgdjEgKGYgdjEgZDEgZDIpIHJcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICBsZXQgKGwxLCBkMSwgcjEpID0gc3BsaXQgdjIgczEgaW5cbiAgICAgICAgICAgIGxldCBsID0gdW5pb24gZiBsMSBsMiBhbmQgciA9IHVuaW9uIGYgcjEgcjIgaW5cbiAgICAgICAgICAgIG1hdGNoIGQxIHdpdGhcbiAgICAgICAgICAgIHwgTm9uZSAtPiBqb2luIGwgdjIgZDIgclxuICAgICAgICAgICAgfCBTb21lIGQxIC0+IGNvbmNhdF9vcl9qb2luIGwgdjIgKGYgdjIgZDEgZDIpIHJcblxuICAgIGxldCByZWMgZmlsdGVyIHAgPSBmdW5jdGlvblxuICAgICAgICBFbXB0eSAtPiBFbXB0eVxuICAgICAgfCBOb2RlIHtsOyB2OyBkOyByfSBhcyBtIC0+XG4gICAgICAgICAgKCogY2FsbCBbcF0gaW4gdGhlIGV4cGVjdGVkIGxlZnQtdG8tcmlnaHQgb3JkZXIgKilcbiAgICAgICAgICBsZXQgbCcgPSBmaWx0ZXIgcCBsIGluXG4gICAgICAgICAgbGV0IHB2ZCA9IHAgdiBkIGluXG4gICAgICAgICAgbGV0IHInID0gZmlsdGVyIHAgciBpblxuICAgICAgICAgIGlmIHB2ZCB0aGVuIGlmIGw9PWwnICYmIHI9PXInIHRoZW4gbSBlbHNlIGpvaW4gbCcgdiBkIHInXG4gICAgICAgICAgZWxzZSBjb25jYXQgbCcgcidcblxuICAgIGxldCByZWMgZmlsdGVyX21hcCBmID0gZnVuY3Rpb25cbiAgICAgICAgRW1wdHkgLT4gRW1wdHlcbiAgICAgIHwgTm9kZSB7bDsgdjsgZDsgcn0gLT5cbiAgICAgICAgICAoKiBjYWxsIFtmXSBpbiB0aGUgZXhwZWN0ZWQgbGVmdC10by1yaWdodCBvcmRlciAqKVxuICAgICAgICAgIGxldCBsJyA9IGZpbHRlcl9tYXAgZiBsIGluXG4gICAgICAgICAgbGV0IGZ2ZCA9IGYgdiBkIGluXG4gICAgICAgICAgbGV0IHInID0gZmlsdGVyX21hcCBmIHIgaW5cbiAgICAgICAgICBiZWdpbiBtYXRjaCBmdmQgd2l0aFxuICAgICAgICAgICAgfCBTb21lIGQnIC0+IGpvaW4gbCcgdiBkJyByJ1xuICAgICAgICAgICAgfCBOb25lIC0+IGNvbmNhdCBsJyByJ1xuICAgICAgICAgIGVuZFxuXG4gICAgbGV0IHJlYyBwYXJ0aXRpb24gcCA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+IChFbXB0eSwgRW1wdHkpXG4gICAgICB8IE5vZGUge2w7IHY7IGQ7IHJ9IC0+XG4gICAgICAgICAgKCogY2FsbCBbcF0gaW4gdGhlIGV4cGVjdGVkIGxlZnQtdG8tcmlnaHQgb3JkZXIgKilcbiAgICAgICAgICBsZXQgKGx0LCBsZikgPSBwYXJ0aXRpb24gcCBsIGluXG4gICAgICAgICAgbGV0IHB2ZCA9IHAgdiBkIGluXG4gICAgICAgICAgbGV0IChydCwgcmYpID0gcGFydGl0aW9uIHAgciBpblxuICAgICAgICAgIGlmIHB2ZFxuICAgICAgICAgIHRoZW4gKGpvaW4gbHQgdiBkIHJ0LCBjb25jYXQgbGYgcmYpXG4gICAgICAgICAgZWxzZSAoY29uY2F0IGx0IHJ0LCBqb2luIGxmIHYgZCByZilcblxuICAgIHR5cGUgJ2EgZW51bWVyYXRpb24gPSBFbmQgfCBNb3JlIG9mIGtleSAqICdhICogJ2EgdCAqICdhIGVudW1lcmF0aW9uXG5cbiAgICBsZXQgcmVjIGNvbnNfZW51bSBtIGUgPVxuICAgICAgbWF0Y2ggbSB3aXRoXG4gICAgICAgIEVtcHR5IC0+IGVcbiAgICAgIHwgTm9kZSB7bDsgdjsgZDsgcn0gLT4gY29uc19lbnVtIGwgKE1vcmUodiwgZCwgciwgZSkpXG5cbiAgICBsZXQgY29tcGFyZSBjbXAgbTEgbTIgPVxuICAgICAgbGV0IHJlYyBjb21wYXJlX2F1eCBlMSBlMiA9XG4gICAgICAgICAgbWF0Y2ggKGUxLCBlMikgd2l0aFxuICAgICAgICAgIChFbmQsIEVuZCkgLT4gMFxuICAgICAgICB8IChFbmQsIF8pICAtPiAtMVxuICAgICAgICB8IChfLCBFbmQpIC0+IDFcbiAgICAgICAgfCAoTW9yZSh2MSwgZDEsIHIxLCBlMSksIE1vcmUodjIsIGQyLCByMiwgZTIpKSAtPlxuICAgICAgICAgICAgbGV0IGMgPSBPcmQuY29tcGFyZSB2MSB2MiBpblxuICAgICAgICAgICAgaWYgYyA8PiAwIHRoZW4gYyBlbHNlXG4gICAgICAgICAgICBsZXQgYyA9IGNtcCBkMSBkMiBpblxuICAgICAgICAgICAgaWYgYyA8PiAwIHRoZW4gYyBlbHNlXG4gICAgICAgICAgICBjb21wYXJlX2F1eCAoY29uc19lbnVtIHIxIGUxKSAoY29uc19lbnVtIHIyIGUyKVxuICAgICAgaW4gY29tcGFyZV9hdXggKGNvbnNfZW51bSBtMSBFbmQpIChjb25zX2VudW0gbTIgRW5kKVxuXG4gICAgbGV0IGVxdWFsIGNtcCBtMSBtMiA9XG4gICAgICBsZXQgcmVjIGVxdWFsX2F1eCBlMSBlMiA9XG4gICAgICAgICAgbWF0Y2ggKGUxLCBlMikgd2l0aFxuICAgICAgICAgIChFbmQsIEVuZCkgLT4gdHJ1ZVxuICAgICAgICB8IChFbmQsIF8pICAtPiBmYWxzZVxuICAgICAgICB8IChfLCBFbmQpIC0+IGZhbHNlXG4gICAgICAgIHwgKE1vcmUodjEsIGQxLCByMSwgZTEpLCBNb3JlKHYyLCBkMiwgcjIsIGUyKSkgLT5cbiAgICAgICAgICAgIE9yZC5jb21wYXJlIHYxIHYyID0gMCAmJiBjbXAgZDEgZDIgJiZcbiAgICAgICAgICAgIGVxdWFsX2F1eCAoY29uc19lbnVtIHIxIGUxKSAoY29uc19lbnVtIHIyIGUyKVxuICAgICAgaW4gZXF1YWxfYXV4IChjb25zX2VudW0gbTEgRW5kKSAoY29uc19lbnVtIG0yIEVuZClcblxuICAgIGxldCByZWMgY2FyZGluYWwgPSBmdW5jdGlvblxuICAgICAgICBFbXB0eSAtPiAwXG4gICAgICB8IE5vZGUge2w7IHJ9IC0+IGNhcmRpbmFsIGwgKyAxICsgY2FyZGluYWwgclxuXG4gICAgbGV0IHJlYyBiaW5kaW5nc19hdXggYWNjdSA9IGZ1bmN0aW9uXG4gICAgICAgIEVtcHR5IC0+IGFjY3VcbiAgICAgIHwgTm9kZSB7bDsgdjsgZDsgcn0gLT4gYmluZGluZ3NfYXV4ICgodiwgZCkgOjogYmluZGluZ3NfYXV4IGFjY3UgcikgbFxuXG4gICAgbGV0IGJpbmRpbmdzIHMgPVxuICAgICAgYmluZGluZ3NfYXV4IFtdIHNcblxuICAgIGxldCBjaG9vc2UgPSBtaW5fYmluZGluZ1xuXG4gICAgbGV0IGNob29zZV9vcHQgPSBtaW5fYmluZGluZ19vcHRcblxuICAgIGxldCBhZGRfc2VxIGkgbSA9XG4gICAgICBTZXEuZm9sZF9sZWZ0IChmdW4gbSAoayx2KSAtPiBhZGQgayB2IG0pIG0gaVxuXG4gICAgbGV0IG9mX3NlcSBpID0gYWRkX3NlcSBpIGVtcHR5XG5cbiAgICBsZXQgcmVjIHNlcV9vZl9lbnVtXyBjICgpID0gbWF0Y2ggYyB3aXRoXG4gICAgICB8IEVuZCAtPiBTZXEuTmlsXG4gICAgICB8IE1vcmUgKGssdix0LHJlc3QpIC0+IFNlcS5Db25zICgoayx2KSwgc2VxX29mX2VudW1fIChjb25zX2VudW0gdCByZXN0KSlcblxuICAgIGxldCB0b19zZXEgbSA9XG4gICAgICBzZXFfb2ZfZW51bV8gKGNvbnNfZW51bSBtIEVuZClcblxuICAgIGxldCByZWMgc25vY19lbnVtIHMgZSA9XG4gICAgICBtYXRjaCBzIHdpdGhcbiAgICAgICAgRW1wdHkgLT4gZVxuICAgICAgfCBOb2Rle2w7IHY7IGQ7IHJ9IC0+IHNub2NfZW51bSByIChNb3JlKHYsIGQsIGwsIGUpKVxuXG4gICAgbGV0IHJlYyByZXZfc2VxX29mX2VudW1fIGMgKCkgPSBtYXRjaCBjIHdpdGhcbiAgICAgIHwgRW5kIC0+IFNlcS5OaWxcbiAgICAgIHwgTW9yZSAoayx2LHQscmVzdCkgLT5cbiAgICAgICAgICBTZXEuQ29ucyAoKGssdiksIHJldl9zZXFfb2ZfZW51bV8gKHNub2NfZW51bSB0IHJlc3QpKVxuXG4gICAgbGV0IHRvX3Jldl9zZXEgYyA9XG4gICAgICByZXZfc2VxX29mX2VudW1fIChzbm9jX2VudW0gYyBFbmQpXG5cbiAgICBsZXQgdG9fc2VxX2Zyb20gbG93IG0gPVxuICAgICAgbGV0IHJlYyBhdXggbG93IG0gYyA9IG1hdGNoIG0gd2l0aFxuICAgICAgICB8IEVtcHR5IC0+IGNcbiAgICAgICAgfCBOb2RlIHtsOyB2OyBkOyByOyBffSAtPlxuICAgICAgICAgICAgYmVnaW4gbWF0Y2ggT3JkLmNvbXBhcmUgdiBsb3cgd2l0aFxuICAgICAgICAgICAgICB8IDAgLT4gTW9yZSAodiwgZCwgciwgYylcbiAgICAgICAgICAgICAgfCBuIHdoZW4gbjwwIC0+IGF1eCBsb3cgciBjXG4gICAgICAgICAgICAgIHwgXyAtPiBhdXggbG93IGwgKE1vcmUgKHYsIGQsIHIsIGMpKVxuICAgICAgICAgICAgZW5kXG4gICAgICBpblxuICAgICAgc2VxX29mX2VudW1fIChhdXggbG93IG0gRW5kKVxuZW5kXG4iLCIoKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9DYW1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICBYYXZpZXIgTGVyb3ksIHByb2pldCBDcmlzdGFsLCBJTlJJQSBSb2NxdWVuY291cnQgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIENvcHlyaWdodCAxOTk2IEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgICAgICopXG4oKiAgICAgZW4gQXV0b21hdGlxdWUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIEFsbCByaWdodHMgcmVzZXJ2ZWQuICBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mICAgICopXG4oKiAgIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyLjEsIHdpdGggdGhlICAgICAgICAgICopXG4oKiAgIHNwZWNpYWwgZXhjZXB0aW9uIG9uIGxpbmtpbmcgZGVzY3JpYmVkIGluIHRoZSBmaWxlIExJQ0VOU0UuICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG5cbnR5cGUgJ2EgdCA9IHsgbXV0YWJsZSBjIDogJ2EgbGlzdDsgbXV0YWJsZSBsZW4gOiBpbnQ7IH1cblxuZXhjZXB0aW9uIEVtcHR5XG5cbmxldCBjcmVhdGUgKCkgPSB7IGMgPSBbXTsgbGVuID0gMDsgfVxuXG5sZXQgY2xlYXIgcyA9IHMuYyA8LSBbXTsgcy5sZW4gPC0gMFxuXG5sZXQgY29weSBzID0geyBjID0gcy5jOyBsZW4gPSBzLmxlbjsgfVxuXG5sZXQgcHVzaCB4IHMgPSBzLmMgPC0geCA6OiBzLmM7IHMubGVuIDwtIHMubGVuICsgMVxuXG5sZXQgcG9wIHMgPVxuICBtYXRjaCBzLmMgd2l0aFxuICB8IGhkOjp0bCAtPiBzLmMgPC0gdGw7IHMubGVuIDwtIHMubGVuIC0gMTsgaGRcbiAgfCBbXSAgICAgLT4gcmFpc2UgRW1wdHlcblxubGV0IHBvcF9vcHQgcyA9XG4gIG1hdGNoIHMuYyB3aXRoXG4gIHwgaGQ6OnRsIC0+IHMuYyA8LSB0bDsgcy5sZW4gPC0gcy5sZW4gLSAxOyBTb21lIGhkXG4gIHwgW10gICAgIC0+IE5vbmVcblxubGV0IHRvcCBzID1cbiAgbWF0Y2ggcy5jIHdpdGhcbiAgfCBoZDo6XyAtPiBoZFxuICB8IFtdICAgIC0+IHJhaXNlIEVtcHR5XG5cbmxldCB0b3Bfb3B0IHMgPVxuICBtYXRjaCBzLmMgd2l0aFxuICB8IGhkOjpfIC0+IFNvbWUgaGRcbiAgfCBbXSAgICAtPiBOb25lXG5cbmxldCBpc19lbXB0eSBzID0gKHMuYyA9IFtdKVxuXG5sZXQgbGVuZ3RoIHMgPSBzLmxlblxuXG5sZXQgaXRlciBmIHMgPSBMaXN0Lml0ZXIgZiBzLmNcblxubGV0IGZvbGQgZiBhY2MgcyA9IExpc3QuZm9sZF9sZWZ0IGYgYWNjIHMuY1xuXG4oKiogezEgSXRlcmF0b3JzfSAqKVxuXG5sZXQgdG9fc2VxIHMgPSBMaXN0LnRvX3NlcSBzLmNcblxubGV0IGFkZF9zZXEgcSBpID0gU2VxLml0ZXIgKGZ1biB4IC0+IHB1c2ggeCBxKSBpXG5cbmxldCBvZl9zZXEgZyA9XG4gIGxldCBzID0gY3JlYXRlKCkgaW5cbiAgYWRkX3NlcSBzIGc7XG4gIHNcbiIsIigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0NhbWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgRnJhbmNvaXMgUG90dGllciwgcHJvamV0IENyaXN0YWwsIElOUklBIFJvY3F1ZW5jb3VydCAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgSmVyZW1pZSBEaW1pbm8sIEphbmUgU3RyZWV0IEV1cm9wZSAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQ29weXJpZ2h0IDIwMDIgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCAgICAgKilcbigqICAgICBlbiBBdXRvbWF0aXF1ZS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQWxsIHJpZ2h0cyByZXNlcnZlZC4gIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgICAgKilcbigqICAgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIuMSwgd2l0aCB0aGUgICAgICAgICAgKilcbigqICAgc3BlY2lhbCBleGNlcHRpb24gb24gbGlua2luZyBkZXNjcmliZWQgaW4gdGhlIGZpbGUgTElDRU5TRS4gICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcblxuZXhjZXB0aW9uIEVtcHR5XG5cbnR5cGUgJ2EgY2VsbCA9XG4gIHwgTmlsXG4gIHwgQ29ucyBvZiB7IGNvbnRlbnQ6ICdhOyBtdXRhYmxlIG5leHQ6ICdhIGNlbGwgfVxuXG50eXBlICdhIHQgPSB7XG4gIG11dGFibGUgbGVuZ3RoOiBpbnQ7XG4gIG11dGFibGUgZmlyc3Q6ICdhIGNlbGw7XG4gIG11dGFibGUgbGFzdDogJ2EgY2VsbFxufVxuXG5sZXQgY3JlYXRlICgpID0ge1xuICBsZW5ndGggPSAwO1xuICBmaXJzdCA9IE5pbDtcbiAgbGFzdCA9IE5pbFxufVxuXG5sZXQgY2xlYXIgcSA9XG4gIHEubGVuZ3RoIDwtIDA7XG4gIHEuZmlyc3QgPC0gTmlsO1xuICBxLmxhc3QgPC0gTmlsXG5cbmxldCBhZGQgeCBxID1cbiAgbGV0IGNlbGwgPSBDb25zIHtcbiAgICBjb250ZW50ID0geDtcbiAgICBuZXh0ID0gTmlsXG4gIH0gaW5cbiAgbWF0Y2ggcS5sYXN0IHdpdGhcbiAgfCBOaWwgLT5cbiAgICBxLmxlbmd0aCA8LSAxO1xuICAgIHEuZmlyc3QgPC0gY2VsbDtcbiAgICBxLmxhc3QgPC0gY2VsbFxuICB8IENvbnMgbGFzdCAtPlxuICAgIHEubGVuZ3RoIDwtIHEubGVuZ3RoICsgMTtcbiAgICBsYXN0Lm5leHQgPC0gY2VsbDtcbiAgICBxLmxhc3QgPC0gY2VsbFxuXG5sZXQgcHVzaCA9XG4gIGFkZFxuXG5sZXQgcGVlayBxID1cbiAgbWF0Y2ggcS5maXJzdCB3aXRoXG4gIHwgTmlsIC0+IHJhaXNlIEVtcHR5XG4gIHwgQ29ucyB7IGNvbnRlbnQgfSAtPiBjb250ZW50XG5cbmxldCBwZWVrX29wdCBxID1cbiAgbWF0Y2ggcS5maXJzdCB3aXRoXG4gIHwgTmlsIC0+IE5vbmVcbiAgfCBDb25zIHsgY29udGVudCB9IC0+IFNvbWUgY29udGVudFxuXG5sZXQgdG9wID1cbiAgcGVla1xuXG5sZXQgdGFrZSBxID1cbiAgbWF0Y2ggcS5maXJzdCB3aXRoXG4gIHwgTmlsIC0+IHJhaXNlIEVtcHR5XG4gIHwgQ29ucyB7IGNvbnRlbnQ7IG5leHQgPSBOaWwgfSAtPlxuICAgIGNsZWFyIHE7XG4gICAgY29udGVudFxuICB8IENvbnMgeyBjb250ZW50OyBuZXh0IH0gLT5cbiAgICBxLmxlbmd0aCA8LSBxLmxlbmd0aCAtIDE7XG4gICAgcS5maXJzdCA8LSBuZXh0O1xuICAgIGNvbnRlbnRcblxubGV0IHRha2Vfb3B0IHEgPVxuICBtYXRjaCBxLmZpcnN0IHdpdGhcbiAgfCBOaWwgLT4gTm9uZVxuICB8IENvbnMgeyBjb250ZW50OyBuZXh0ID0gTmlsIH0gLT5cbiAgICBjbGVhciBxO1xuICAgIFNvbWUgY29udGVudFxuICB8IENvbnMgeyBjb250ZW50OyBuZXh0IH0gLT5cbiAgICBxLmxlbmd0aCA8LSBxLmxlbmd0aCAtIDE7XG4gICAgcS5maXJzdCA8LSBuZXh0O1xuICAgIFNvbWUgY29udGVudFxuXG5sZXQgcG9wID1cbiAgdGFrZVxuXG5sZXQgY29weSA9XG4gIGxldCByZWMgY29weSBxX3JlcyBwcmV2IGNlbGwgPVxuICAgIG1hdGNoIGNlbGwgd2l0aFxuICAgIHwgTmlsIC0+IHFfcmVzLmxhc3QgPC0gcHJldjsgcV9yZXNcbiAgICB8IENvbnMgeyBjb250ZW50OyBuZXh0IH0gLT5cbiAgICAgIGxldCByZXMgPSBDb25zIHsgY29udGVudDsgbmV4dCA9IE5pbCB9IGluXG4gICAgICBiZWdpbiBtYXRjaCBwcmV2IHdpdGhcbiAgICAgIHwgTmlsIC0+IHFfcmVzLmZpcnN0IDwtIHJlc1xuICAgICAgfCBDb25zIHAgLT4gcC5uZXh0IDwtIHJlc1xuICAgICAgZW5kO1xuICAgICAgY29weSBxX3JlcyByZXMgbmV4dFxuICBpblxuICBmdW4gcSAtPiBjb3B5IHsgbGVuZ3RoID0gcS5sZW5ndGg7IGZpcnN0ID0gTmlsOyBsYXN0ID0gTmlsIH0gTmlsIHEuZmlyc3RcblxubGV0IGlzX2VtcHR5IHEgPVxuICBxLmxlbmd0aCA9IDBcblxubGV0IGxlbmd0aCBxID1cbiAgcS5sZW5ndGhcblxubGV0IGl0ZXIgPVxuICBsZXQgcmVjIGl0ZXIgZiBjZWxsID1cbiAgICBtYXRjaCBjZWxsIHdpdGhcbiAgICB8IE5pbCAtPiAoKVxuICAgIHwgQ29ucyB7IGNvbnRlbnQ7IG5leHQgfSAtPlxuICAgICAgZiBjb250ZW50O1xuICAgICAgaXRlciBmIG5leHRcbiAgaW5cbiAgZnVuIGYgcSAtPiBpdGVyIGYgcS5maXJzdFxuXG5sZXQgZm9sZCA9XG4gIGxldCByZWMgZm9sZCBmIGFjY3UgY2VsbCA9XG4gICAgbWF0Y2ggY2VsbCB3aXRoXG4gICAgfCBOaWwgLT4gYWNjdVxuICAgIHwgQ29ucyB7IGNvbnRlbnQ7IG5leHQgfSAtPlxuICAgICAgbGV0IGFjY3UgPSBmIGFjY3UgY29udGVudCBpblxuICAgICAgZm9sZCBmIGFjY3UgbmV4dFxuICBpblxuICBmdW4gZiBhY2N1IHEgLT4gZm9sZCBmIGFjY3UgcS5maXJzdFxuXG5sZXQgdHJhbnNmZXIgcTEgcTIgPVxuICBpZiBxMS5sZW5ndGggPiAwIHRoZW5cbiAgICBtYXRjaCBxMi5sYXN0IHdpdGhcbiAgICB8IE5pbCAtPlxuICAgICAgcTIubGVuZ3RoIDwtIHExLmxlbmd0aDtcbiAgICAgIHEyLmZpcnN0IDwtIHExLmZpcnN0O1xuICAgICAgcTIubGFzdCA8LSBxMS5sYXN0O1xuICAgICAgY2xlYXIgcTFcbiAgICB8IENvbnMgbGFzdCAtPlxuICAgICAgcTIubGVuZ3RoIDwtIHEyLmxlbmd0aCArIHExLmxlbmd0aDtcbiAgICAgIGxhc3QubmV4dCA8LSBxMS5maXJzdDtcbiAgICAgIHEyLmxhc3QgPC0gcTEubGFzdDtcbiAgICAgIGNsZWFyIHExXG5cbigqKiB7MSBJdGVyYXRvcnN9ICopXG5cbmxldCB0b19zZXEgcSA9XG4gIGxldCByZWMgYXV4IGMgKCkgPSBtYXRjaCBjIHdpdGhcbiAgICB8IE5pbCAtPiBTZXEuTmlsXG4gICAgfCBDb25zIHsgY29udGVudD14OyBuZXh0OyB9IC0+IFNlcS5Db25zICh4LCBhdXggbmV4dClcbiAgaW5cbiAgYXV4IHEuZmlyc3RcblxubGV0IGFkZF9zZXEgcSBpID0gU2VxLml0ZXIgKGZ1biB4IC0+IHB1c2ggeCBxKSBpXG5cbmxldCBvZl9zZXEgZyA9XG4gIGxldCBxID0gY3JlYXRlKCkgaW5cbiAgYWRkX3NlcSBxIGc7XG4gIHFcbiIsIigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0NhbWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgIERhbWllbiBEb2xpZ2V6LCBwcm9qZXQgUGFyYSwgSU5SSUEgUm9jcXVlbmNvdXJ0ICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQ29weXJpZ2h0IDE5OTcgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCAgICAgKilcbigqICAgICBlbiBBdXRvbWF0aXF1ZS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQWxsIHJpZ2h0cyByZXNlcnZlZC4gIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgICAgKilcbigqICAgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIuMSwgd2l0aCB0aGUgICAgICAgICAgKilcbigqICAgc3BlY2lhbCBleGNlcHRpb24gb24gbGlua2luZyBkZXNjcmliZWQgaW4gdGhlIGZpbGUgTElDRU5TRS4gICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcblxuKCogSW50ZXJuYWxzIG9mIGZvcmNpbmcgbGF6eSB2YWx1ZXMuICopXG5cbnR5cGUgJ2EgdCA9ICdhIGxhenlfdFxuXG5leGNlcHRpb24gVW5kZWZpbmVkXG5cbmxldCByYWlzZV91bmRlZmluZWQgPSBPYmoucmVwciAoZnVuICgpIC0+IHJhaXNlIFVuZGVmaW5lZClcblxuZXh0ZXJuYWwgbWFrZV9mb3J3YXJkIDogT2JqLnQgLT4gT2JqLnQgLT4gdW5pdCA9IFwiY2FtbF9vYmpfbWFrZV9mb3J3YXJkXCJcblxuKCogQXNzdW1lIFtibGtdIGlzIGEgYmxvY2sgd2l0aCB0YWcgbGF6eSAqKVxubGV0IGZvcmNlX2xhenlfYmxvY2sgKGJsayA6ICdhcmcgbGF6eV90KSA9XG4gIGxldCBjbG9zdXJlID0gKE9iai5vYmogKE9iai5maWVsZCAoT2JqLnJlcHIgYmxrKSAwKSA6IHVuaXQgLT4gJ2FyZykgaW5cbiAgT2JqLnNldF9maWVsZCAoT2JqLnJlcHIgYmxrKSAwIHJhaXNlX3VuZGVmaW5lZDtcbiAgdHJ5XG4gICAgbGV0IHJlc3VsdCA9IGNsb3N1cmUgKCkgaW5cbiAgICBtYWtlX2ZvcndhcmQgKE9iai5yZXByIGJsaykgKE9iai5yZXByIHJlc3VsdCk7XG4gICAgcmVzdWx0XG4gIHdpdGggZSAtPlxuICAgIE9iai5zZXRfZmllbGQgKE9iai5yZXByIGJsaykgMCAoT2JqLnJlcHIgKGZ1biAoKSAtPiByYWlzZSBlKSk7XG4gICAgcmFpc2UgZVxuXG5cbigqIEFzc3VtZSBbYmxrXSBpcyBhIGJsb2NrIHdpdGggdGFnIGxhenkgKilcbmxldCBmb3JjZV92YWxfbGF6eV9ibG9jayAoYmxrIDogJ2FyZyBsYXp5X3QpID1cbiAgbGV0IGNsb3N1cmUgPSAoT2JqLm9iaiAoT2JqLmZpZWxkIChPYmoucmVwciBibGspIDApIDogdW5pdCAtPiAnYXJnKSBpblxuICBPYmouc2V0X2ZpZWxkIChPYmoucmVwciBibGspIDAgcmFpc2VfdW5kZWZpbmVkO1xuICBsZXQgcmVzdWx0ID0gY2xvc3VyZSAoKSBpblxuICBtYWtlX2ZvcndhcmQgKE9iai5yZXByIGJsaykgKE9iai5yZXByIHJlc3VsdCk7XG4gIHJlc3VsdFxuXG5cbigqIFtmb3JjZV0gaXMgbm90IHVzZWQsIHNpbmNlIFtMYXp5LmZvcmNlXSBpcyBkZWNsYXJlZCBhcyBhIHByaW1pdGl2ZVxuICAgd2hvc2UgY29kZSBpbmxpbmVzIHRoZSB0YWcgdGVzdHMgb2YgaXRzIGFyZ3VtZW50LCBleGNlcHQgd2hlbiBhZmxcbiAgIGluc3RydW1lbnRhdGlvbiBpcyB0dXJuZWQgb24uICopXG5cbmxldCBmb3JjZSAobHp2IDogJ2FyZyBsYXp5X3QpID1cbiAgKCogVXNpbmcgW1N5cy5vcGFxdWVfaWRlbnRpdHldIHByZXZlbnRzIHR3byBwb3RlbnRpYWwgcHJvYmxlbXM6XG4gICAgIC0gSWYgdGhlIHZhbHVlIGlzIGtub3duIHRvIGhhdmUgRm9yd2FyZF90YWcsIHRoZW4gaXRzIHRhZyBjb3VsZCBoYXZlXG4gICAgICAgY2hhbmdlZCBkdXJpbmcgR0MsIHNvIHRoYXQgaW5mb3JtYXRpb24gbXVzdCBiZSBmb3Jnb3R0ZW4gKHNlZSBHUFIjNzEzXG4gICAgICAgYW5kIGlzc3VlICM3MzAxKVxuICAgICAtIElmIHRoZSB2YWx1ZSBpcyBrbm93biB0byBiZSBpbW11dGFibGUsIHRoZW4gaWYgdGhlIGNvbXBpbGVyXG4gICAgICAgY2Fubm90IHByb3ZlIHRoYXQgdGhlIGxhc3QgYnJhbmNoIGlzIG5vdCB0YWtlbiBpdCB3aWxsIGlzc3VlIGFcbiAgICAgICB3YXJuaW5nIDU5IChtb2RpZmljYXRpb24gb2YgYW4gaW1tdXRhYmxlIHZhbHVlKSAqKVxuICBsZXQgbHp2ID0gU3lzLm9wYXF1ZV9pZGVudGl0eSBsenYgaW5cbiAgbGV0IHggPSBPYmoucmVwciBsenYgaW5cbiAgbGV0IHQgPSBPYmoudGFnIHggaW5cbiAgaWYgdCA9IE9iai5mb3J3YXJkX3RhZyB0aGVuIChPYmoub2JqIChPYmouZmllbGQgeCAwKSA6ICdhcmcpIGVsc2VcbiAgaWYgdCA8PiBPYmoubGF6eV90YWcgdGhlbiAoT2JqLm9iaiB4IDogJ2FyZylcbiAgZWxzZSBmb3JjZV9sYXp5X2Jsb2NrIGx6dlxuXG5cbmxldCBmb3JjZV92YWwgKGx6diA6ICdhcmcgbGF6eV90KSA9XG4gIGxldCB4ID0gT2JqLnJlcHIgbHp2IGluXG4gIGxldCB0ID0gT2JqLnRhZyB4IGluXG4gIGlmIHQgPSBPYmouZm9yd2FyZF90YWcgdGhlbiAoT2JqLm9iaiAoT2JqLmZpZWxkIHggMCkgOiAnYXJnKSBlbHNlXG4gIGlmIHQgPD4gT2JqLmxhenlfdGFnIHRoZW4gKE9iai5vYmogeCA6ICdhcmcpXG4gIGVsc2UgZm9yY2VfdmFsX2xhenlfYmxvY2sgbHp2XG4iLCIoKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9DYW1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICBEYW1pZW4gRG9saWdleiwgcHJvamV0IFBhcmEsIElOUklBIFJvY3F1ZW5jb3VydCAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIENvcHlyaWdodCAxOTk3IEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgICAgICopXG4oKiAgICAgZW4gQXV0b21hdGlxdWUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIEFsbCByaWdodHMgcmVzZXJ2ZWQuICBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mICAgICopXG4oKiAgIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyLjEsIHdpdGggdGhlICAgICAgICAgICopXG4oKiAgIHNwZWNpYWwgZXhjZXB0aW9uIG9uIGxpbmtpbmcgZGVzY3JpYmVkIGluIHRoZSBmaWxlIExJQ0VOU0UuICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG5cbigqIE1vZHVsZSBbTGF6eV06IGRlZmVycmVkIGNvbXB1dGF0aW9ucyAqKVxuXG5cbigqXG4gICBXQVJOSU5HOiBzb21lIHB1cnBsZSBtYWdpYyBpcyBnb2luZyBvbiBoZXJlLiAgRG8gbm90IHRha2UgdGhpcyBmaWxlXG4gICBhcyBhbiBleGFtcGxlIG9mIGhvdyB0byBwcm9ncmFtIGluIE9DYW1sLlxuKilcblxuXG4oKiBXZSBtYWtlIHVzZSBvZiB0d28gc3BlY2lhbCB0YWdzIHByb3ZpZGVkIGJ5IHRoZSBydW50aW1lOlxuICAgW2xhenlfdGFnXSBhbmQgW2ZvcndhcmRfdGFnXS5cblxuICAgQSB2YWx1ZSBvZiB0eXBlIFsnYSBMYXp5LnRdIGNhbiBiZSBvbmUgb2YgdGhyZWUgdGhpbmdzOlxuICAgMS4gQSBibG9jayBvZiBzaXplIDEgd2l0aCB0YWcgW2xhenlfdGFnXS4gIEl0cyBmaWVsZCBpcyBhIGNsb3N1cmUgb2ZcbiAgICAgIHR5cGUgW3VuaXQgLT4gJ2FdIHRoYXQgY29tcHV0ZXMgdGhlIHZhbHVlLlxuICAgMi4gQSBibG9jayBvZiBzaXplIDEgd2l0aCB0YWcgW2ZvcndhcmRfdGFnXS4gIEl0cyBmaWVsZCBpcyB0aGUgdmFsdWVcbiAgICAgIG9mIHR5cGUgWydhXSB0aGF0IHdhcyBjb21wdXRlZC5cbiAgIDMuIEFueXRoaW5nIGVsc2UgZXhjZXB0IGEgZmxvYXQuICBUaGlzIGhhcyB0eXBlIFsnYV0gYW5kIGlzIHRoZSB2YWx1ZVxuICAgICAgdGhhdCB3YXMgY29tcHV0ZWQuXG4gICBFeGNlcHRpb25zIGFyZSBzdG9yZWQgaW4gZm9ybWF0ICgxKS5cbiAgIFRoZSBHQyB3aWxsIG1hZ2ljYWxseSBjaGFuZ2UgdGhpbmdzIGZyb20gKDIpIHRvICgzKSBhY2NvcmRpbmcgdG8gaXRzXG4gICBmYW5jeS5cblxuICAgSWYgT0NhbWwgd2FzIGNvbmZpZ3VyZWQgd2l0aCB0aGUgLWZsYXQtZmxvYXQtYXJyYXkgb3B0aW9uICh3aGljaCBpc1xuICAgY3VycmVudGx5IHRoZSBkZWZhdWx0KSwgdGhlIGZvbGxvd2luZyBpcyBhbHNvIHRydWU6XG4gICBXZSBjYW5ub3QgdXNlIHJlcHJlc2VudGF0aW9uICgzKSBmb3IgYSBbZmxvYXQgTGF6eS50XSBiZWNhdXNlXG4gICBbY2FtbF9tYWtlX2FycmF5XSBhc3N1bWVzIHRoYXQgb25seSBhIFtmbG9hdF0gdmFsdWUgY2FuIGhhdmUgdGFnXG4gICBbRG91YmxlX3RhZ10uXG5cbiAgIFdlIGhhdmUgdG8gdXNlIHRoZSBidWlsdC1pbiB0eXBlIGNvbnN0cnVjdG9yIFtsYXp5X3RdIHRvXG4gICBsZXQgdGhlIGNvbXBpbGVyIGltcGxlbWVudCB0aGUgc3BlY2lhbCB0eXBpbmcgYW5kIGNvbXBpbGF0aW9uXG4gICBydWxlcyBmb3IgdGhlIFtsYXp5XSBrZXl3b3JkLlxuKilcblxudHlwZSAnYSB0ID0gJ2EgQ2FtbGludGVybmFsTGF6eS50XG5cbmV4Y2VwdGlvbiBVbmRlZmluZWQgPSBDYW1saW50ZXJuYWxMYXp5LlVuZGVmaW5lZFxuXG5leHRlcm5hbCBtYWtlX2ZvcndhcmQgOiAnYSAtPiAnYSBsYXp5X3QgPSBcImNhbWxfbGF6eV9tYWtlX2ZvcndhcmRcIlxuXG5leHRlcm5hbCBmb3JjZSA6ICdhIHQgLT4gJ2EgPSBcIiVsYXp5X2ZvcmNlXCJcblxuXG5sZXQgZm9yY2VfdmFsID0gQ2FtbGludGVybmFsTGF6eS5mb3JjZV92YWxcblxubGV0IGZyb21fZnVuIChmIDogdW5pdCAtPiAnYXJnKSA9XG4gIGxldCB4ID0gT2JqLm5ld19ibG9jayBPYmoubGF6eV90YWcgMSBpblxuICBPYmouc2V0X2ZpZWxkIHggMCAoT2JqLnJlcHIgZik7XG4gIChPYmoub2JqIHggOiAnYXJnIHQpXG5cbmxldCBmcm9tX3ZhbCAodiA6ICdhcmcpID1cbiAgbGV0IHQgPSBPYmoudGFnIChPYmoucmVwciB2KSBpblxuICBpZiB0ID0gT2JqLmZvcndhcmRfdGFnIHx8IHQgPSBPYmoubGF6eV90YWcgfHwgdCA9IE9iai5kb3VibGVfdGFnIHRoZW4gYmVnaW5cbiAgICBtYWtlX2ZvcndhcmQgdlxuICBlbmQgZWxzZSBiZWdpblxuICAgIChPYmoubWFnaWMgdiA6ICdhcmcgdClcbiAgZW5kXG5cblxubGV0IGlzX3ZhbCAobCA6ICdhcmcgdCkgPSBPYmoudGFnIChPYmoucmVwciBsKSA8PiBPYmoubGF6eV90YWdcblxubGV0IGxhenlfZnJvbV9mdW4gPSBmcm9tX2Z1blxuXG5sZXQgbGF6eV9mcm9tX3ZhbCA9IGZyb21fdmFsXG5cbmxldCBsYXp5X2lzX3ZhbCA9IGlzX3ZhbFxuXG5cbmxldCBtYXAgZiB4ID1cbiAgbGF6eSAoZiAoZm9yY2UgeCkpXG5cbmxldCBtYXBfdmFsIGYgeCA9XG4gIGlmIGlzX3ZhbCB4XG4gIHRoZW4gbGF6eV9mcm9tX3ZhbCAoZiAoZm9yY2UgeCkpXG4gIGVsc2UgbGF6eSAoZiAoZm9yY2UgeCkpXG4iLCIoKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9DYW1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgIERhbmllbCBkZSBSYXVnbGF1ZHJlLCBwcm9qZXQgQ3Jpc3RhbCwgSU5SSUEgUm9jcXVlbmNvdXJ0ICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIENvcHlyaWdodCAxOTk3IEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgICAgICopXG4oKiAgICAgZW4gQXV0b21hdGlxdWUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIEFsbCByaWdodHMgcmVzZXJ2ZWQuICBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mICAgICopXG4oKiAgIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyLjEsIHdpdGggdGhlICAgICAgICAgICopXG4oKiAgIHNwZWNpYWwgZXhjZXB0aW9uIG9uIGxpbmtpbmcgZGVzY3JpYmVkIGluIHRoZSBmaWxlIExJQ0VOU0UuICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG5cbnR5cGUgJ2EgdCA9ICdhIGNlbGwgb3B0aW9uXG5hbmQgJ2EgY2VsbCA9IHsgbXV0YWJsZSBjb3VudCA6IGludDsgbXV0YWJsZSBkYXRhIDogJ2EgZGF0YSB9XG5hbmQgJ2EgZGF0YSA9XG4gICAgU2VtcHR5XG4gIHwgU2NvbnMgb2YgJ2EgKiAnYSBkYXRhXG4gIHwgU2FwcCBvZiAnYSBkYXRhICogJ2EgZGF0YVxuICB8IFNsYXp5IG9mICdhIGRhdGEgTGF6eS50XG4gIHwgU2dlbiBvZiAnYSBnZW5cbiAgfCBTYnVmZmlvIDogYnVmZmlvIC0+IGNoYXIgZGF0YVxuYW5kICdhIGdlbiA9IHsgbXV0YWJsZSBjdXJyIDogJ2Egb3B0aW9uIG9wdGlvbjsgZnVuYyA6IGludCAtPiAnYSBvcHRpb24gfVxuYW5kIGJ1ZmZpbyA9XG4gIHsgaWMgOiBpbl9jaGFubmVsOyBidWZmIDogYnl0ZXM7IG11dGFibGUgbGVuIDogaW50OyBtdXRhYmxlIGluZCA6IGludCB9XG5cbmV4Y2VwdGlvbiBGYWlsdXJlXG5leGNlcHRpb24gRXJyb3Igb2Ygc3RyaW5nXG5cbmxldCBjb3VudCA9IGZ1bmN0aW9uXG4gIHwgTm9uZSAtPiAwXG4gIHwgU29tZSB7IGNvdW50IH0gLT4gY291bnRcbmxldCBkYXRhID0gZnVuY3Rpb25cbiAgfCBOb25lIC0+IFNlbXB0eVxuICB8IFNvbWUgeyBkYXRhIH0gLT4gZGF0YVxuXG5sZXQgZmlsbF9idWZmIGIgPVxuICBiLmxlbiA8LSBpbnB1dCBiLmljIGIuYnVmZiAwIChCeXRlcy5sZW5ndGggYi5idWZmKTsgYi5pbmQgPC0gMFxuXG5cbmxldCByZWMgZ2V0X2RhdGEgOiB0eXBlIHYuIGludCAtPiB2IGRhdGEgLT4gdiBkYXRhID0gZnVuIGNvdW50IGQgLT4gbWF0Y2ggZCB3aXRoXG4gKCogUmV0dXJucyBlaXRoZXIgU2VtcHR5IG9yIFNjb25zKGEsIF8pIGV2ZW4gd2hlbiBkIGlzIGEgZ2VuZXJhdG9yXG4gICAgb3IgYSBidWZmZXIuIEluIHRob3NlIGNhc2VzLCB0aGUgaXRlbSBhIGlzIHNlZW4gYXMgZXh0cmFjdGVkIGZyb21cbiB0aGUgZ2VuZXJhdG9yL2J1ZmZlci5cbiBUaGUgY291bnQgcGFyYW1ldGVyIGlzIHVzZWQgZm9yIGNhbGxpbmcgYFNnZW4tZnVuY3Rpb25zJy4gICopXG4gICBTZW1wdHkgfCBTY29ucyAoXywgXykgLT4gZFxuIHwgU2FwcCAoZDEsIGQyKSAtPlxuICAgICBiZWdpbiBtYXRjaCBnZXRfZGF0YSBjb3VudCBkMSB3aXRoXG4gICAgICAgU2NvbnMgKGEsIGQxMSkgLT4gU2NvbnMgKGEsIFNhcHAgKGQxMSwgZDIpKVxuICAgICB8IFNlbXB0eSAtPiBnZXRfZGF0YSBjb3VudCBkMlxuICAgICB8IF8gLT4gYXNzZXJ0IGZhbHNlXG4gICAgIGVuZFxuIHwgU2dlbiB7Y3VyciA9IFNvbWUgTm9uZX0gLT4gU2VtcHR5XG4gfCBTZ2VuICh7Y3VyciA9IFNvbWUoU29tZSBhKX0gYXMgZykgLT5cbiAgICAgZy5jdXJyIDwtIE5vbmU7IFNjb25zKGEsIGQpXG4gfCBTZ2VuIGcgLT5cbiAgICAgYmVnaW4gbWF0Y2ggZy5mdW5jIGNvdW50IHdpdGhcbiAgICAgICBOb25lIC0+IGcuY3VyciA8LSBTb21lKE5vbmUpOyBTZW1wdHlcbiAgICAgfCBTb21lIGEgLT4gU2NvbnMoYSwgZClcbiAgICAgICAgICgqIFdhcm5pbmc6IGFueW9uZSB1c2luZyBnIHRoaW5rcyB0aGF0IGFuIGl0ZW0gaGFzIGJlZW4gcmVhZCAqKVxuICAgICBlbmRcbiB8IFNidWZmaW8gYiAtPlxuICAgICBpZiBiLmluZCA+PSBiLmxlbiB0aGVuIGZpbGxfYnVmZiBiO1xuICAgICBpZiBiLmxlbiA9PSAwIHRoZW4gU2VtcHR5IGVsc2VcbiAgICAgICBsZXQgciA9IEJ5dGVzLnVuc2FmZV9nZXQgYi5idWZmIGIuaW5kIGluXG4gICAgICAgKCogV2FybmluZzogYW55b25lIHVzaW5nIGcgdGhpbmtzIHRoYXQgYW4gaXRlbSBoYXMgYmVlbiByZWFkICopXG4gICAgICAgYi5pbmQgPC0gc3VjYyBiLmluZDsgU2NvbnMociwgZClcbiB8IFNsYXp5IGYgLT4gZ2V0X2RhdGEgY291bnQgKExhenkuZm9yY2UgZilcblxuXG5sZXQgcmVjIHBlZWtfZGF0YSA6IHR5cGUgdi4gdiBjZWxsIC0+IHYgb3B0aW9uID0gZnVuIHMgLT5cbiAoKiBjb25zdWx0IHRoZSBmaXJzdCBpdGVtIG9mIHMgKilcbiBtYXRjaCBzLmRhdGEgd2l0aFxuICAgU2VtcHR5IC0+IE5vbmVcbiB8IFNjb25zIChhLCBfKSAtPiBTb21lIGFcbiB8IFNhcHAgKF8sIF8pIC0+XG4gICAgIGJlZ2luIG1hdGNoIGdldF9kYXRhIHMuY291bnQgcy5kYXRhIHdpdGhcbiAgICAgICBTY29ucyhhLCBfKSBhcyBkIC0+IHMuZGF0YSA8LSBkOyBTb21lIGFcbiAgICAgfCBTZW1wdHkgLT4gTm9uZVxuICAgICB8IF8gLT4gYXNzZXJ0IGZhbHNlXG4gICAgIGVuZFxuIHwgU2xhenkgZiAtPiBzLmRhdGEgPC0gKExhenkuZm9yY2UgZik7IHBlZWtfZGF0YSBzXG4gfCBTZ2VuIHtjdXJyID0gU29tZSBhfSAtPiBhXG4gfCBTZ2VuIGcgLT4gbGV0IHggPSBnLmZ1bmMgcy5jb3VudCBpbiBnLmN1cnIgPC0gU29tZSB4OyB4XG4gfCBTYnVmZmlvIGIgLT5cbiAgICAgaWYgYi5pbmQgPj0gYi5sZW4gdGhlbiBmaWxsX2J1ZmYgYjtcbiAgICAgaWYgYi5sZW4gPT0gMCB0aGVuIGJlZ2luIHMuZGF0YSA8LSBTZW1wdHk7IE5vbmUgZW5kXG4gICAgIGVsc2UgU29tZSAoQnl0ZXMudW5zYWZlX2dldCBiLmJ1ZmYgYi5pbmQpXG5cblxubGV0IHBlZWsgPSBmdW5jdGlvblxuICB8IE5vbmUgLT4gTm9uZVxuICB8IFNvbWUgcyAtPiBwZWVrX2RhdGEgc1xuXG5cbmxldCByZWMganVua19kYXRhIDogdHlwZSB2LiB2IGNlbGwgLT4gdW5pdCA9IGZ1biBzIC0+XG4gIG1hdGNoIHMuZGF0YSB3aXRoXG4gICAgU2NvbnMgKF8sIGQpIC0+IHMuY291bnQgPC0gKHN1Y2Mgcy5jb3VudCk7IHMuZGF0YSA8LSBkXG4gIHwgU2dlbiAoe2N1cnIgPSBTb21lIF99IGFzIGcpIC0+IHMuY291bnQgPC0gKHN1Y2Mgcy5jb3VudCk7IGcuY3VyciA8LSBOb25lXG4gIHwgU2J1ZmZpbyBiIC0+XG4gICAgICBpZiBiLmluZCA+PSBiLmxlbiB0aGVuIGZpbGxfYnVmZiBiO1xuICAgICAgaWYgYi5sZW4gPT0gMCB0aGVuIHMuZGF0YSA8LSBTZW1wdHlcbiAgICAgIGVsc2UgKHMuY291bnQgPC0gKHN1Y2Mgcy5jb3VudCk7IGIuaW5kIDwtIHN1Y2MgYi5pbmQpXG4gIHwgXyAtPlxuICAgICAgbWF0Y2ggcGVla19kYXRhIHMgd2l0aFxuICAgICAgICBOb25lIC0+ICgpXG4gICAgICB8IFNvbWUgXyAtPiBqdW5rX2RhdGEgc1xuXG5cbmxldCBqdW5rID0gZnVuY3Rpb25cbiAgfCBOb25lIC0+ICgpXG4gIHwgU29tZSBkYXRhIC0+IGp1bmtfZGF0YSBkYXRhXG5cbmxldCByZWMgbmdldF9kYXRhIG4gcyA9XG4gIGlmIG4gPD0gMCB0aGVuIFtdLCBzLmRhdGEsIDBcbiAgZWxzZVxuICAgIG1hdGNoIHBlZWtfZGF0YSBzIHdpdGhcbiAgICAgIFNvbWUgYSAtPlxuICAgICAgICBqdW5rX2RhdGEgcztcbiAgICAgICAgbGV0IChhbCwgZCwgaykgPSBuZ2V0X2RhdGEgKHByZWQgbikgcyBpbiBhIDo6IGFsLCBTY29ucyAoYSwgZCksIHN1Y2Mga1xuICAgIHwgTm9uZSAtPiBbXSwgcy5kYXRhLCAwXG5cblxubGV0IG5wZWVrX2RhdGEgbiBzID1cbiAgbGV0IChhbCwgZCwgbGVuKSA9IG5nZXRfZGF0YSBuIHMgaW5cbiAgcy5jb3VudCA8LSAocy5jb3VudCAtIGxlbik7XG4gIHMuZGF0YSA8LSBkO1xuICBhbFxuXG5cbmxldCBucGVlayBuID0gZnVuY3Rpb25cbiAgfCBOb25lIC0+IFtdXG4gIHwgU29tZSBkIC0+IG5wZWVrX2RhdGEgbiBkXG5cbmxldCBuZXh0IHMgPVxuICBtYXRjaCBwZWVrIHMgd2l0aFxuICAgIFNvbWUgYSAtPiBqdW5rIHM7IGFcbiAgfCBOb25lIC0+IHJhaXNlIEZhaWx1cmVcblxuXG5sZXQgZW1wdHkgcyA9XG4gIG1hdGNoIHBlZWsgcyB3aXRoXG4gICAgU29tZSBfIC0+IHJhaXNlIEZhaWx1cmVcbiAgfCBOb25lIC0+ICgpXG5cblxubGV0IGl0ZXIgZiBzdHJtID1cbiAgbGV0IHJlYyBkb19yZWMgKCkgPVxuICAgIG1hdGNoIHBlZWsgc3RybSB3aXRoXG4gICAgICBTb21lIGEgLT4ganVuayBzdHJtOyBpZ25vcmUoZiBhKTsgZG9fcmVjICgpXG4gICAgfCBOb25lIC0+ICgpXG4gIGluXG4gIGRvX3JlYyAoKVxuXG5cbigqIFN0cmVhbSBidWlsZGluZyBmdW5jdGlvbnMgKilcblxubGV0IGZyb20gZiA9IFNvbWUge2NvdW50ID0gMDsgZGF0YSA9IFNnZW4ge2N1cnIgPSBOb25lOyBmdW5jID0gZn19XG5cbmxldCBvZl9saXN0IGwgPVxuICBTb21lIHtjb3VudCA9IDA7IGRhdGEgPSBMaXN0LmZvbGRfcmlnaHQgKGZ1biB4IGwgLT4gU2NvbnMgKHgsIGwpKSBsIFNlbXB0eX1cblxuXG5sZXQgb2Zfc3RyaW5nIHMgPVxuICBsZXQgY291bnQgPSByZWYgMCBpblxuICBmcm9tIChmdW4gXyAtPlxuICAgICgqIFdlIGNhbm5vdCB1c2UgdGhlIGluZGV4IHBhc3NlZCBieSB0aGUgW2Zyb21dIGZ1bmN0aW9uIGRpcmVjdGx5XG4gICAgICAgYmVjYXVzZSBpdCByZXR1cm5zIHRoZSBjdXJyZW50IHN0cmVhbSBjb3VudCwgd2l0aCBhYnNvbHV0ZWx5IG5vXG4gICAgICAgZ3VhcmFudGVlIHRoYXQgaXQgd2lsbCBzdGFydCBmcm9tIDAuIEZvciBleGFtcGxlLCBpbiB0aGUgY2FzZVxuICAgICAgIG9mIFtTdHJlYW0uaWNvbnMgJ2MnIChTdHJlYW0uZnJvbV9zdHJpbmcgXCJhYlwiKV0sIHRoZSBmaXJzdFxuICAgICAgIGFjY2VzcyB0byB0aGUgc3RyaW5nIHdpbGwgYmUgbWFkZSB3aXRoIGNvdW50IFsxXSBhbHJlYWR5LlxuICAgICopXG4gICAgbGV0IGMgPSAhY291bnQgaW5cbiAgICBpZiBjIDwgU3RyaW5nLmxlbmd0aCBzXG4gICAgdGhlbiAoaW5jciBjb3VudDsgU29tZSBzLltjXSlcbiAgICBlbHNlIE5vbmUpXG5cblxubGV0IG9mX2J5dGVzIHMgPVxuICBsZXQgY291bnQgPSByZWYgMCBpblxuICBmcm9tIChmdW4gXyAtPlxuICAgIGxldCBjID0gIWNvdW50IGluXG4gICAgaWYgYyA8IEJ5dGVzLmxlbmd0aCBzXG4gICAgdGhlbiAoaW5jciBjb3VudDsgU29tZSAoQnl0ZXMuZ2V0IHMgYykpXG4gICAgZWxzZSBOb25lKVxuXG5cbmxldCBvZl9jaGFubmVsIGljID1cbiAgU29tZSB7Y291bnQgPSAwO1xuICAgICAgICBkYXRhID0gU2J1ZmZpbyB7aWMgPSBpYzsgYnVmZiA9IEJ5dGVzLmNyZWF0ZSA0MDk2OyBsZW4gPSAwOyBpbmQgPSAwfX1cblxuXG4oKiBTdHJlYW0gZXhwcmVzc2lvbnMgYnVpbGRlcnMgKilcblxubGV0IGlhcHAgaSBzID0gU29tZSB7Y291bnQgPSAwOyBkYXRhID0gU2FwcCAoZGF0YSBpLCBkYXRhIHMpfVxubGV0IGljb25zIGkgcyA9IFNvbWUge2NvdW50ID0gMDsgZGF0YSA9IFNjb25zIChpLCBkYXRhIHMpfVxubGV0IGlzaW5nIGkgPSBTb21lIHtjb3VudCA9IDA7IGRhdGEgPSBTY29ucyAoaSwgU2VtcHR5KX1cblxubGV0IGxhcHAgZiBzID1cbiAgU29tZSB7Y291bnQgPSAwOyBkYXRhID0gU2xhenkgKGxhenkoU2FwcCAoZGF0YSAoZiAoKSksIGRhdGEgcykpKX1cblxubGV0IGxjb25zIGYgcyA9IFNvbWUge2NvdW50ID0gMDsgZGF0YSA9IFNsYXp5IChsYXp5KFNjb25zIChmICgpLCBkYXRhIHMpKSl9XG5sZXQgbHNpbmcgZiA9IFNvbWUge2NvdW50ID0gMDsgZGF0YSA9IFNsYXp5IChsYXp5KFNjb25zIChmICgpLCBTZW1wdHkpKSl9XG5cbmxldCBzZW1wdHkgPSBOb25lXG5sZXQgc2xhenkgZiA9IFNvbWUge2NvdW50ID0gMDsgZGF0YSA9IFNsYXp5IChsYXp5KGRhdGEgKGYgKCkpKSl9XG5cbigqIEZvciBkZWJ1Z2dpbmcgdXNlICopXG5cbmxldCByZWMgZHVtcCA6IHR5cGUgdi4gKHYgLT4gdW5pdCkgLT4gdiB0IC0+IHVuaXQgPSBmdW4gZiBzIC0+XG4gIHByaW50X3N0cmluZyBcIntjb3VudCA9IFwiO1xuICBwcmludF9pbnQgKGNvdW50IHMpO1xuICBwcmludF9zdHJpbmcgXCI7IGRhdGEgPSBcIjtcbiAgZHVtcF9kYXRhIGYgKGRhdGEgcyk7XG4gIHByaW50X3N0cmluZyBcIn1cIjtcbiAgcHJpbnRfbmV3bGluZSAoKVxuYW5kIGR1bXBfZGF0YSA6IHR5cGUgdi4gKHYgLT4gdW5pdCkgLT4gdiBkYXRhIC0+IHVuaXQgPSBmdW4gZiAtPlxuICBmdW5jdGlvblxuICAgIFNlbXB0eSAtPiBwcmludF9zdHJpbmcgXCJTZW1wdHlcIlxuICB8IFNjb25zIChhLCBkKSAtPlxuICAgICAgcHJpbnRfc3RyaW5nIFwiU2NvbnMgKFwiO1xuICAgICAgZiBhO1xuICAgICAgcHJpbnRfc3RyaW5nIFwiLCBcIjtcbiAgICAgIGR1bXBfZGF0YSBmIGQ7XG4gICAgICBwcmludF9zdHJpbmcgXCIpXCJcbiAgfCBTYXBwIChkMSwgZDIpIC0+XG4gICAgICBwcmludF9zdHJpbmcgXCJTYXBwIChcIjtcbiAgICAgIGR1bXBfZGF0YSBmIGQxO1xuICAgICAgcHJpbnRfc3RyaW5nIFwiLCBcIjtcbiAgICAgIGR1bXBfZGF0YSBmIGQyO1xuICAgICAgcHJpbnRfc3RyaW5nIFwiKVwiXG4gIHwgU2xhenkgXyAtPiBwcmludF9zdHJpbmcgXCJTbGF6eVwiXG4gIHwgU2dlbiBfIC0+IHByaW50X3N0cmluZyBcIlNnZW5cIlxuICB8IFNidWZmaW8gXyAtPiBwcmludF9zdHJpbmcgXCJTYnVmZmlvXCJcbiIsIigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0NhbWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgIFBpZXJyZSBXZWlzIGFuZCBYYXZpZXIgTGVyb3ksIHByb2pldCBDcmlzdGFsLCBJTlJJQSBSb2NxdWVuY291cnQgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQ29weXJpZ2h0IDE5OTkgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCAgICAgKilcbigqICAgICBlbiBBdXRvbWF0aXF1ZS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQWxsIHJpZ2h0cyByZXNlcnZlZC4gIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgICAgKilcbigqICAgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIuMSwgd2l0aCB0aGUgICAgICAgICAgKilcbigqICAgc3BlY2lhbCBleGNlcHRpb24gb24gbGlua2luZyBkZXNjcmliZWQgaW4gdGhlIGZpbGUgTElDRU5TRS4gICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcblxuKCogRXh0ZW5zaWJsZSBidWZmZXJzICopXG5cbnR5cGUgdCA9XG4ge211dGFibGUgYnVmZmVyIDogYnl0ZXM7XG4gIG11dGFibGUgcG9zaXRpb24gOiBpbnQ7XG4gIG11dGFibGUgbGVuZ3RoIDogaW50O1xuICBpbml0aWFsX2J1ZmZlciA6IGJ5dGVzfVxuKCogSW52YXJpYW50czogYWxsIHBhcnRzIG9mIHRoZSBjb2RlIHByZXNlcnZlIHRoZSBpbnZhcmlhbnRzIHRoYXQ6XG4gICAtIFswIDw9IGIucG9zaXRpb24gPD0gYi5sZW5ndGhdXG4gICAtIFtiLmxlbmd0aCA9IEJ5dGVzLmxlbmd0aCBiLmJ1ZmZlcl1cblxuICAgTm90ZSBpbiBwYXJ0aWN1bGFyIHRoYXQgW2IucG9zaXRpb24gPSBiLmxlbmd0aF0gaXMgbGVnYWwsXG4gICBpdCBtZWFucyB0aGF0IHRoZSBidWZmZXIgaXMgZnVsbCBhbmQgd2lsbCBoYXZlIHRvIGJlIGV4dGVuZGVkXG4gICBiZWZvcmUgYW55IGZ1cnRoZXIgYWRkaXRpb24uICopXG5cbmxldCBjcmVhdGUgbiA9XG4gbGV0IG4gPSBpZiBuIDwgMSB0aGVuIDEgZWxzZSBuIGluXG4gbGV0IG4gPSBpZiBuID4gU3lzLm1heF9zdHJpbmdfbGVuZ3RoIHRoZW4gU3lzLm1heF9zdHJpbmdfbGVuZ3RoIGVsc2UgbiBpblxuIGxldCBzID0gQnl0ZXMuY3JlYXRlIG4gaW5cbiB7YnVmZmVyID0gczsgcG9zaXRpb24gPSAwOyBsZW5ndGggPSBuOyBpbml0aWFsX2J1ZmZlciA9IHN9XG5cbmxldCBjb250ZW50cyBiID0gQnl0ZXMuc3ViX3N0cmluZyBiLmJ1ZmZlciAwIGIucG9zaXRpb25cbmxldCB0b19ieXRlcyBiID0gQnl0ZXMuc3ViIGIuYnVmZmVyIDAgYi5wb3NpdGlvblxuXG5sZXQgc3ViIGIgb2ZzIGxlbiA9XG4gIGlmIG9mcyA8IDAgfHwgbGVuIDwgMCB8fCBvZnMgPiBiLnBvc2l0aW9uIC0gbGVuXG4gIHRoZW4gaW52YWxpZF9hcmcgXCJCdWZmZXIuc3ViXCJcbiAgZWxzZSBCeXRlcy5zdWJfc3RyaW5nIGIuYnVmZmVyIG9mcyBsZW5cblxuXG5sZXQgYmxpdCBzcmMgc3Jjb2ZmIGRzdCBkc3RvZmYgbGVuID1cbiAgaWYgbGVuIDwgMCB8fCBzcmNvZmYgPCAwIHx8IHNyY29mZiA+IHNyYy5wb3NpdGlvbiAtIGxlblxuICAgICAgICAgICAgIHx8IGRzdG9mZiA8IDAgfHwgZHN0b2ZmID4gKEJ5dGVzLmxlbmd0aCBkc3QpIC0gbGVuXG4gIHRoZW4gaW52YWxpZF9hcmcgXCJCdWZmZXIuYmxpdFwiXG4gIGVsc2VcbiAgICBCeXRlcy51bnNhZmVfYmxpdCBzcmMuYnVmZmVyIHNyY29mZiBkc3QgZHN0b2ZmIGxlblxuXG5cbmxldCBudGggYiBvZnMgPVxuICBpZiBvZnMgPCAwIHx8IG9mcyA+PSBiLnBvc2l0aW9uIHRoZW5cbiAgIGludmFsaWRfYXJnIFwiQnVmZmVyLm50aFwiXG4gIGVsc2UgQnl0ZXMudW5zYWZlX2dldCBiLmJ1ZmZlciBvZnNcblxuXG5sZXQgbGVuZ3RoIGIgPSBiLnBvc2l0aW9uXG5cbmxldCBjbGVhciBiID0gYi5wb3NpdGlvbiA8LSAwXG5cbmxldCByZXNldCBiID1cbiAgYi5wb3NpdGlvbiA8LSAwO1xuICBiLmJ1ZmZlciA8LSBiLmluaXRpYWxfYnVmZmVyO1xuICBiLmxlbmd0aCA8LSBCeXRlcy5sZW5ndGggYi5idWZmZXJcblxuKCogW3Jlc2l6ZSBiIG1vcmVdIGVuc3VyZXMgdGhhdCBbYi5wb3NpdGlvbiArIG1vcmUgPD0gYi5sZW5ndGhdIGhvbGRzXG4gICBieSBkeW5hbWljYWxseSBleHRlbmRpbmcgW2IuYnVmZmVyXSBpZiBuZWNlc3NhcnkgLS0gYW5kIHRodXNcbiAgIGluY3JlYXNpbmcgW2IubGVuZ3RoXS5cblxuICAgSW4gcGFydGljdWxhciwgYWZ0ZXIgW3Jlc2l6ZSBiIG1vcmVdIGlzIGNhbGxlZCwgYSBkaXJlY3QgYWNjZXNzIG9mXG4gICBzaXplIFttb3JlXSBhdCBbYi5wb3NpdGlvbl0gd2lsbCBhbHdheXMgYmUgaW4tYm91bmRzLCBzbyB0aGF0XG4gICAodW5zYWZlX3tnZXQsc2V0fSkgbWF5IGJlIHVzZWQgZm9yIHBlcmZvcm1hbmNlLlxuKilcbmxldCByZXNpemUgYiBtb3JlID1cbiAgbGV0IG9sZF9wb3MgPSBiLnBvc2l0aW9uIGluXG4gIGxldCBvbGRfbGVuID0gYi5sZW5ndGggaW5cbiAgbGV0IG5ld19sZW4gPSByZWYgb2xkX2xlbiBpblxuICB3aGlsZSBvbGRfcG9zICsgbW9yZSA+ICFuZXdfbGVuIGRvIG5ld19sZW4gOj0gMiAqICFuZXdfbGVuIGRvbmU7XG4gIGlmICFuZXdfbGVuID4gU3lzLm1heF9zdHJpbmdfbGVuZ3RoIHRoZW4gYmVnaW5cbiAgICBpZiBvbGRfcG9zICsgbW9yZSA8PSBTeXMubWF4X3N0cmluZ19sZW5ndGhcbiAgICB0aGVuIG5ld19sZW4gOj0gU3lzLm1heF9zdHJpbmdfbGVuZ3RoXG4gICAgZWxzZSBmYWlsd2l0aCBcIkJ1ZmZlci5hZGQ6IGNhbm5vdCBncm93IGJ1ZmZlclwiXG4gIGVuZDtcbiAgbGV0IG5ld19idWZmZXIgPSBCeXRlcy5jcmVhdGUgIW5ld19sZW4gaW5cbiAgKCogUFIjNjE0ODogbGV0J3Mga2VlcCB1c2luZyBbYmxpdF0gcmF0aGVyIHRoYW4gW3Vuc2FmZV9ibGl0XSBpblxuICAgICB0aGlzIHRyaWNreSBmdW5jdGlvbiB0aGF0IGlzIHNsb3cgYW55d2F5LiAqKVxuICBCeXRlcy5ibGl0IGIuYnVmZmVyIDAgbmV3X2J1ZmZlciAwIGIucG9zaXRpb247XG4gIGIuYnVmZmVyIDwtIG5ld19idWZmZXI7XG4gIGIubGVuZ3RoIDwtICFuZXdfbGVuO1xuICBhc3NlcnQgKGIucG9zaXRpb24gKyBtb3JlIDw9IGIubGVuZ3RoKTtcbiAgYXNzZXJ0IChvbGRfcG9zICsgbW9yZSA8PSBiLmxlbmd0aCk7XG4gICgpXG4gICgqIE5vdGU6IHRoZXJlIGFyZSB2YXJpb3VzIHNpdHVhdGlvbnMgKHByZWVtcHRpdmUgdGhyZWFkcywgc2lnbmFscyBhbmRcbiAgICAgZ2MgZmluYWxpemVycykgd2hlcmUgT0NhbWwgY29kZSBtYXkgYmUgcnVuIGFzeW5jaHJvbm91c2x5OyBpblxuICAgICBwYXJ0aWN1bGFyLCB0aGVyZSBtYXkgYmUgYSByYWNlIHdpdGggYW5vdGhlciB1c2VyIG9mIFtiXSwgY2hhbmdpbmdcbiAgICAgaXRzIG11dGFibGUgZmllbGRzIGluIHRoZSBtaWRkbGUgb2YgdGhlIFtyZXNpemVdIGNhbGwuIFRoZSBCdWZmZXJcbiAgICAgbW9kdWxlIGRvZXMgbm90IHByb3ZpZGUgYW55IGNvcnJlY3RuZXNzIGd1YXJhbnRlZSBpZiB0aGF0IGhhcHBlbnMsXG4gICAgIGJ1dCB3ZSBtdXN0IHN0aWxsIGVuc3VyZSB0aGF0IHRoZSBkYXRhc3RydWN0dXJlIGludmFyaWFudHMgaG9sZCBmb3JcbiAgICAgbWVtb3J5LXNhZmV0eSAtLSBhcyB3ZSBwbGFuIHRvIHVzZSBbdW5zYWZlX3tnZXQsc2V0fV0uXG5cbiAgICAgVGhlcmUgYXJlIHR3byBwb3RlbnRpYWwgYWxsb2NhdGlvbiBwb2ludHMgaW4gdGhpcyBmdW5jdGlvbixcbiAgICAgW3JlZl0gYW5kIFtCeXRlcy5jcmVhdGVdLCBidXQgYWxsIHJlYWRzIGFuZCB3cml0ZXMgdG8gdGhlIGZpZWxkc1xuICAgICBvZiBbYl0gaGFwcGVuIGJlZm9yZSBib3RoIG9mIHRoZW0gb3IgYWZ0ZXIgYm90aCBvZiB0aGVtLlxuXG4gICAgIFdlIHRoZXJlZm9yZSBhc3N1bWUgdGhhdCBbYi5wb3NpdGlvbl0gbWF5IGNoYW5nZSBhdCB0aGVzZSBhbGxvY2F0aW9ucyxcbiAgICAgYW5kIGNoZWNrIHRoYXQgdGhlIFtiLnBvc2l0aW9uICsgbW9yZSA8PSBiLmxlbmd0aF0gcG9zdGNvbmRpdGlvblxuICAgICBob2xkcyBmb3IgYm90aCB2YWx1ZXMgb2YgW2IucG9zaXRpb25dLCBiZWZvcmUgb3IgYWZ0ZXIgdGhlIGZ1bmN0aW9uXG4gICAgIGlzIGNhbGxlZC4gTW9yZSBwcmVjaXNlbHksIHRoZSBmb2xsb3dpbmcgaW52YXJpYW50cyBtdXN0IGhvbGQgaWYgdGhlXG4gICAgIGZ1bmN0aW9uIHJldHVybnMgY29ycmVjdGx5LCBpbiBhZGRpdGlvbiB0byB0aGUgdXN1YWwgYnVmZmVyIGludmFyaWFudHM6XG4gICAgIC0gW29sZChiLnBvc2l0aW9uKSArIG1vcmUgPD0gbmV3KGIubGVuZ3RoKV1cbiAgICAgLSBbbmV3KGIucG9zaXRpb24pICsgbW9yZSA8PSBuZXcoYi5sZW5ndGgpXVxuICAgICAtIFtvbGQoYi5sZW5ndGgpIDw9IG5ldyhiLmxlbmd0aCldXG5cbiAgICAgTm90ZTogW2IucG9zaXRpb24gKyBtb3JlIDw9IG9sZChiLmxlbmd0aCldIGRvZXMgKm5vdCpcbiAgICAgaG9sZCBpbiBnZW5lcmFsLCBhcyBpdCBpcyBwcmVjaXNlbHkgdGhlIGNhc2Ugd2hlcmUgeW91IG5lZWRcbiAgICAgdG8gY2FsbCBbcmVzaXplXSB0byBpbmNyZWFzZSBbYi5sZW5ndGhdLlxuXG4gICAgIE5vdGU6IFthc3NlcnRdIGFib3ZlIGRvZXMgbm90IG1lYW4gdGhhdCB3ZSBrbm93IHRoZSBjb25kaXRpb25zXG4gICAgIGFsd2F5cyBob2xkLCBidXQgdGhhdCB0aGUgZnVuY3Rpb24gbWF5IHJldHVybiBjb3JyZWN0bHlcbiAgICAgb25seSBpZiB0aGV5IGhvbGQuXG5cbiAgICAgTm90ZTogdGhlIG90aGVyIGZ1bmN0aW9ucyBpbiB0aGlzIG1vZHVsZSBkb2VzIG5vdCBuZWVkXG4gICAgIHRvIGJlIGNoZWNrZWQgd2l0aCB0aGlzIGxldmVsIG9mIHNjcnV0aW55LCBnaXZlbiB0aGF0IHRoZXlcbiAgICAgcmVhZC93cml0ZSB0aGUgYnVmZmVyIGltbWVkaWF0ZWx5IGFmdGVyIGNoZWNraW5nIHRoYXRcbiAgICAgW2IucG9zaXRpb24gKyBtb3JlIDw9IGIubGVuZ3RoXSBob2xkIG9yIGNhbGxpbmcgW3Jlc2l6ZV0uXG4gICopXG5cbmxldCBhZGRfY2hhciBiIGMgPVxuICBsZXQgcG9zID0gYi5wb3NpdGlvbiBpblxuICBpZiBwb3MgPj0gYi5sZW5ndGggdGhlbiByZXNpemUgYiAxO1xuICBCeXRlcy51bnNhZmVfc2V0IGIuYnVmZmVyIHBvcyBjO1xuICBiLnBvc2l0aW9uIDwtIHBvcyArIDFcblxuIGxldCBhZGRfdXRmXzhfdWNoYXIgYiB1ID0gbWF0Y2ggVWNoYXIudG9faW50IHUgd2l0aFxuIHwgdSB3aGVuIHUgPCAwIC0+IGFzc2VydCBmYWxzZVxuIHwgdSB3aGVuIHUgPD0gMHgwMDdGIC0+XG4gICAgIGFkZF9jaGFyIGIgKENoYXIudW5zYWZlX2NociB1KVxuIHwgdSB3aGVuIHUgPD0gMHgwN0ZGIC0+XG4gICAgIGxldCBwb3MgPSBiLnBvc2l0aW9uIGluXG4gICAgIGlmIHBvcyArIDIgPiBiLmxlbmd0aCB0aGVuIHJlc2l6ZSBiIDI7XG4gICAgIEJ5dGVzLnVuc2FmZV9zZXQgYi5idWZmZXIgKHBvcyAgICApXG4gICAgICAgKENoYXIudW5zYWZlX2NociAoMHhDMCBsb3IgKHUgbHNyIDYpKSk7XG4gICAgIEJ5dGVzLnVuc2FmZV9zZXQgYi5idWZmZXIgKHBvcyArIDEpXG4gICAgICAgKENoYXIudW5zYWZlX2NociAoMHg4MCBsb3IgKHUgbGFuZCAweDNGKSkpO1xuICAgICBiLnBvc2l0aW9uIDwtIHBvcyArIDJcbiB8IHUgd2hlbiB1IDw9IDB4RkZGRiAtPlxuICAgICBsZXQgcG9zID0gYi5wb3NpdGlvbiBpblxuICAgICBpZiBwb3MgKyAzID4gYi5sZW5ndGggdGhlbiByZXNpemUgYiAzO1xuICAgICBCeXRlcy51bnNhZmVfc2V0IGIuYnVmZmVyIChwb3MgICAgKVxuICAgICAgIChDaGFyLnVuc2FmZV9jaHIgKDB4RTAgbG9yICh1IGxzciAxMikpKTtcbiAgICAgQnl0ZXMudW5zYWZlX3NldCBiLmJ1ZmZlciAocG9zICsgMSlcbiAgICAgICAoQ2hhci51bnNhZmVfY2hyICgweDgwIGxvciAoKHUgbHNyIDYpIGxhbmQgMHgzRikpKTtcbiAgICAgQnl0ZXMudW5zYWZlX3NldCBiLmJ1ZmZlciAocG9zICsgMilcbiAgICAgICAoQ2hhci51bnNhZmVfY2hyICgweDgwIGxvciAodSBsYW5kIDB4M0YpKSk7XG4gICAgIGIucG9zaXRpb24gPC0gcG9zICsgM1xuIHwgdSB3aGVuIHUgPD0gMHgxMEZGRkYgLT5cbiAgICAgbGV0IHBvcyA9IGIucG9zaXRpb24gaW5cbiAgICAgaWYgcG9zICsgNCA+IGIubGVuZ3RoIHRoZW4gcmVzaXplIGIgNDtcbiAgICAgQnl0ZXMudW5zYWZlX3NldCBiLmJ1ZmZlciAocG9zICAgIClcbiAgICAgICAoQ2hhci51bnNhZmVfY2hyICgweEYwIGxvciAodSBsc3IgMTgpKSk7XG4gICAgIEJ5dGVzLnVuc2FmZV9zZXQgYi5idWZmZXIgKHBvcyArIDEpXG4gICAgICAgKENoYXIudW5zYWZlX2NociAoMHg4MCBsb3IgKCh1IGxzciAxMikgbGFuZCAweDNGKSkpO1xuICAgICBCeXRlcy51bnNhZmVfc2V0IGIuYnVmZmVyIChwb3MgKyAyKVxuICAgICAgIChDaGFyLnVuc2FmZV9jaHIgKDB4ODAgbG9yICgodSBsc3IgNikgbGFuZCAweDNGKSkpO1xuICAgICBCeXRlcy51bnNhZmVfc2V0IGIuYnVmZmVyIChwb3MgKyAzKVxuICAgICAgIChDaGFyLnVuc2FmZV9jaHIgKDB4ODAgbG9yICh1IGxhbmQgMHgzRikpKTtcbiAgICAgYi5wb3NpdGlvbiA8LSBwb3MgKyA0XG4gfCBfIC0+IGFzc2VydCBmYWxzZVxuXG4gbGV0IGFkZF91dGZfMTZiZV91Y2hhciBiIHUgPSBtYXRjaCBVY2hhci50b19pbnQgdSB3aXRoXG4gfCB1IHdoZW4gdSA8IDAgLT4gYXNzZXJ0IGZhbHNlXG4gfCB1IHdoZW4gdSA8PSAweEZGRkYgLT5cbiAgICAgbGV0IHBvcyA9IGIucG9zaXRpb24gaW5cbiAgICAgaWYgcG9zICsgMiA+IGIubGVuZ3RoIHRoZW4gcmVzaXplIGIgMjtcbiAgICAgQnl0ZXMudW5zYWZlX3NldCBiLmJ1ZmZlciAocG9zICAgICkgKENoYXIudW5zYWZlX2NociAodSBsc3IgOCkpO1xuICAgICBCeXRlcy51bnNhZmVfc2V0IGIuYnVmZmVyIChwb3MgKyAxKSAoQ2hhci51bnNhZmVfY2hyICh1IGxhbmQgMHhGRikpO1xuICAgICBiLnBvc2l0aW9uIDwtIHBvcyArIDJcbiB8IHUgd2hlbiB1IDw9IDB4MTBGRkZGIC0+XG4gICAgIGxldCB1JyA9IHUgLSAweDEwMDAwIGluXG4gICAgIGxldCBoaSA9IDB4RDgwMCBsb3IgKHUnIGxzciAxMCkgaW5cbiAgICAgbGV0IGxvID0gMHhEQzAwIGxvciAodScgbGFuZCAweDNGRikgaW5cbiAgICAgbGV0IHBvcyA9IGIucG9zaXRpb24gaW5cbiAgICAgaWYgcG9zICsgNCA+IGIubGVuZ3RoIHRoZW4gcmVzaXplIGIgNDtcbiAgICAgQnl0ZXMudW5zYWZlX3NldCBiLmJ1ZmZlciAocG9zICAgICkgKENoYXIudW5zYWZlX2NociAoaGkgbHNyIDgpKTtcbiAgICAgQnl0ZXMudW5zYWZlX3NldCBiLmJ1ZmZlciAocG9zICsgMSkgKENoYXIudW5zYWZlX2NociAoaGkgbGFuZCAweEZGKSk7XG4gICAgIEJ5dGVzLnVuc2FmZV9zZXQgYi5idWZmZXIgKHBvcyArIDIpIChDaGFyLnVuc2FmZV9jaHIgKGxvIGxzciA4KSk7XG4gICAgIEJ5dGVzLnVuc2FmZV9zZXQgYi5idWZmZXIgKHBvcyArIDMpIChDaGFyLnVuc2FmZV9jaHIgKGxvIGxhbmQgMHhGRikpO1xuICAgICBiLnBvc2l0aW9uIDwtIHBvcyArIDRcbiB8IF8gLT4gYXNzZXJ0IGZhbHNlXG5cbiBsZXQgYWRkX3V0Zl8xNmxlX3VjaGFyIGIgdSA9IG1hdGNoIFVjaGFyLnRvX2ludCB1IHdpdGhcbiB8IHUgd2hlbiB1IDwgMCAtPiBhc3NlcnQgZmFsc2VcbiB8IHUgd2hlbiB1IDw9IDB4RkZGRiAtPlxuICAgICBsZXQgcG9zID0gYi5wb3NpdGlvbiBpblxuICAgICBpZiBwb3MgKyAyID4gYi5sZW5ndGggdGhlbiByZXNpemUgYiAyO1xuICAgICBCeXRlcy51bnNhZmVfc2V0IGIuYnVmZmVyIChwb3MgICAgKSAoQ2hhci51bnNhZmVfY2hyICh1IGxhbmQgMHhGRikpO1xuICAgICBCeXRlcy51bnNhZmVfc2V0IGIuYnVmZmVyIChwb3MgKyAxKSAoQ2hhci51bnNhZmVfY2hyICh1IGxzciA4KSk7XG4gICAgIGIucG9zaXRpb24gPC0gcG9zICsgMlxuIHwgdSB3aGVuIHUgPD0gMHgxMEZGRkYgLT5cbiAgICAgbGV0IHUnID0gdSAtIDB4MTAwMDAgaW5cbiAgICAgbGV0IGhpID0gMHhEODAwIGxvciAodScgbHNyIDEwKSBpblxuICAgICBsZXQgbG8gPSAweERDMDAgbG9yICh1JyBsYW5kIDB4M0ZGKSBpblxuICAgICBsZXQgcG9zID0gYi5wb3NpdGlvbiBpblxuICAgICBpZiBwb3MgKyA0ID4gYi5sZW5ndGggdGhlbiByZXNpemUgYiA0O1xuICAgICBCeXRlcy51bnNhZmVfc2V0IGIuYnVmZmVyIChwb3MgICAgKSAoQ2hhci51bnNhZmVfY2hyIChoaSBsYW5kIDB4RkYpKTtcbiAgICAgQnl0ZXMudW5zYWZlX3NldCBiLmJ1ZmZlciAocG9zICsgMSkgKENoYXIudW5zYWZlX2NociAoaGkgbHNyIDgpKTtcbiAgICAgQnl0ZXMudW5zYWZlX3NldCBiLmJ1ZmZlciAocG9zICsgMikgKENoYXIudW5zYWZlX2NociAobG8gbGFuZCAweEZGKSk7XG4gICAgIEJ5dGVzLnVuc2FmZV9zZXQgYi5idWZmZXIgKHBvcyArIDMpIChDaGFyLnVuc2FmZV9jaHIgKGxvIGxzciA4KSk7XG4gICAgIGIucG9zaXRpb24gPC0gcG9zICsgNFxuIHwgXyAtPiBhc3NlcnQgZmFsc2VcblxubGV0IGFkZF9zdWJzdHJpbmcgYiBzIG9mZnNldCBsZW4gPVxuICBpZiBvZmZzZXQgPCAwIHx8IGxlbiA8IDAgfHwgb2Zmc2V0ID4gU3RyaW5nLmxlbmd0aCBzIC0gbGVuXG4gIHRoZW4gaW52YWxpZF9hcmcgXCJCdWZmZXIuYWRkX3N1YnN0cmluZy9hZGRfc3ViYnl0ZXNcIjtcbiAgbGV0IG5ld19wb3NpdGlvbiA9IGIucG9zaXRpb24gKyBsZW4gaW5cbiAgaWYgbmV3X3Bvc2l0aW9uID4gYi5sZW5ndGggdGhlbiByZXNpemUgYiBsZW47XG4gIEJ5dGVzLnVuc2FmZV9ibGl0X3N0cmluZyBzIG9mZnNldCBiLmJ1ZmZlciBiLnBvc2l0aW9uIGxlbjtcbiAgYi5wb3NpdGlvbiA8LSBuZXdfcG9zaXRpb25cblxubGV0IGFkZF9zdWJieXRlcyBiIHMgb2Zmc2V0IGxlbiA9XG4gIGFkZF9zdWJzdHJpbmcgYiAoQnl0ZXMudW5zYWZlX3RvX3N0cmluZyBzKSBvZmZzZXQgbGVuXG5cbmxldCBhZGRfc3RyaW5nIGIgcyA9XG4gIGxldCBsZW4gPSBTdHJpbmcubGVuZ3RoIHMgaW5cbiAgbGV0IG5ld19wb3NpdGlvbiA9IGIucG9zaXRpb24gKyBsZW4gaW5cbiAgaWYgbmV3X3Bvc2l0aW9uID4gYi5sZW5ndGggdGhlbiByZXNpemUgYiBsZW47XG4gIEJ5dGVzLnVuc2FmZV9ibGl0X3N0cmluZyBzIDAgYi5idWZmZXIgYi5wb3NpdGlvbiBsZW47XG4gIGIucG9zaXRpb24gPC0gbmV3X3Bvc2l0aW9uXG5cbmxldCBhZGRfYnl0ZXMgYiBzID0gYWRkX3N0cmluZyBiIChCeXRlcy51bnNhZmVfdG9fc3RyaW5nIHMpXG5cbmxldCBhZGRfYnVmZmVyIGIgYnMgPVxuICBhZGRfc3ViYnl0ZXMgYiBicy5idWZmZXIgMCBicy5wb3NpdGlvblxuXG4oKiB0aGlzIChwcml2YXRlKSBmdW5jdGlvbiBjb3VsZCBtb3ZlIGludG8gdGhlIHN0YW5kYXJkIGxpYnJhcnkgKilcbmxldCByZWFsbHlfaW5wdXRfdXBfdG8gaWMgYnVmIG9mcyBsZW4gPVxuICBsZXQgcmVjIGxvb3AgaWMgYnVmIH5hbHJlYWR5X3JlYWQgfm9mcyB+dG9fcmVhZCA9XG4gICAgaWYgdG9fcmVhZCA9IDAgdGhlbiBhbHJlYWR5X3JlYWRcbiAgICBlbHNlIGJlZ2luXG4gICAgICBsZXQgciA9IGlucHV0IGljIGJ1ZiBvZnMgdG9fcmVhZCBpblxuICAgICAgaWYgciA9IDAgdGhlbiBhbHJlYWR5X3JlYWRcbiAgICAgIGVsc2UgYmVnaW5cbiAgICAgICAgbGV0IGFscmVhZHlfcmVhZCA9IGFscmVhZHlfcmVhZCArIHIgaW5cbiAgICAgICAgbGV0IG9mcyA9IG9mcyArIHIgaW5cbiAgICAgICAgbGV0IHRvX3JlYWQgPSB0b19yZWFkIC0gciBpblxuICAgICAgICBsb29wIGljIGJ1ZiB+YWxyZWFkeV9yZWFkIH5vZnMgfnRvX3JlYWRcbiAgICAgIGVuZFxuICAgIGVuZFxuICBpbiBsb29wIGljIGJ1ZiB+YWxyZWFkeV9yZWFkOjAgfm9mcyB+dG9fcmVhZDpsZW5cblxuXG5sZXQgdW5zYWZlX2FkZF9jaGFubmVsX3VwX3RvIGIgaWMgbGVuID1cbiAgaWYgYi5wb3NpdGlvbiArIGxlbiA+IGIubGVuZ3RoIHRoZW4gcmVzaXplIGIgbGVuO1xuICBsZXQgbiA9IHJlYWxseV9pbnB1dF91cF90byBpYyBiLmJ1ZmZlciBiLnBvc2l0aW9uIGxlbiBpblxuICAoKiBUaGUgYXNzZXJ0aW9uIGJlbG93IG1heSBmYWlsIGluIHdlaXJkIHNjZW5hcmlvIHdoZXJlXG4gICAgIHRocmVhZGVkL2ZpbmFsaXplciBjb2RlLCBydW4gYXN5bmNocm9ub3VzbHkgZHVyaW5nIHRoZVxuICAgICBbcmVhbGx5X2lucHV0X3VwX3RvXSBjYWxsLCByYWNlcyBvbiB0aGUgYnVmZmVyOyB3ZSBkb24ndCBlbnN1cmVcbiAgICAgY29ycmVjdG5lc3MgaW4gdGhpcyBjYXNlLCBidXQgbmVlZCB0byBwcmVzZXJ2ZSB0aGUgaW52YXJpYW50cyBmb3JcbiAgICAgbWVtb3J5LXNhZmV0eSAoc2VlIGRpc2N1c3Npb24gb2YgW3Jlc2l6ZV0pLiAqKVxuICBhc3NlcnQgKGIucG9zaXRpb24gKyBuIDw9IGIubGVuZ3RoKTtcbiAgYi5wb3NpdGlvbiA8LSBiLnBvc2l0aW9uICsgbjtcbiAgblxuXG5sZXQgYWRkX2NoYW5uZWwgYiBpYyBsZW4gPVxuICBpZiBsZW4gPCAwIHx8IGxlbiA+IFN5cy5tYXhfc3RyaW5nX2xlbmd0aCB0aGVuICAgKCogUFIjNTAwNCAqKVxuICAgIGludmFsaWRfYXJnIFwiQnVmZmVyLmFkZF9jaGFubmVsXCI7XG4gIGxldCBuID0gdW5zYWZlX2FkZF9jaGFubmVsX3VwX3RvIGIgaWMgbGVuIGluXG4gICgqIEl0IGlzIGludGVudGlvbmFsIHRoYXQgYSBjb25zdW1lciBjYXRjaGluZyBFbmRfb2ZfZmlsZVxuICAgICB3aWxsIHNlZSB0aGUgZGF0YSB3cml0dGVuIChzZWUgIzY3MTksICM3MTM2KS4gKilcbiAgaWYgbiA8IGxlbiB0aGVuIHJhaXNlIEVuZF9vZl9maWxlO1xuICAoKVxuXG5sZXQgb3V0cHV0X2J1ZmZlciBvYyBiID1cbiAgb3V0cHV0IG9jIGIuYnVmZmVyIDAgYi5wb3NpdGlvblxuXG5sZXQgY2xvc2luZyA9IGZ1bmN0aW9uXG4gIHwgJygnIC0+ICcpJ1xuICB8ICd7JyAtPiAnfSdcbiAgfCBfIC0+IGFzc2VydCBmYWxzZVxuXG4oKiBvcGVuaW5nIGFuZCBjbG9zaW5nOiBvcGVuIGFuZCBjbG9zZSBjaGFyYWN0ZXJzLCB0eXBpY2FsbHkgKCBhbmQgKVxuICAgazogYmFsYW5jZSBvZiBvcGVuaW5nIGFuZCBjbG9zaW5nIGNoYXJzXG4gICBzOiB0aGUgc3RyaW5nIHdoZXJlIHdlIGFyZSBzZWFyY2hpbmdcbiAgIHN0YXJ0OiB0aGUgaW5kZXggd2hlcmUgd2Ugc3RhcnQgdGhlIHNlYXJjaC4gKilcbmxldCBhZHZhbmNlX3RvX2Nsb3Npbmcgb3BlbmluZyBjbG9zaW5nIGsgcyBzdGFydCA9XG4gIGxldCByZWMgYWR2YW5jZSBrIGkgbGltID1cbiAgICBpZiBpID49IGxpbSB0aGVuIHJhaXNlIE5vdF9mb3VuZCBlbHNlXG4gICAgaWYgcy5baV0gPSBvcGVuaW5nIHRoZW4gYWR2YW5jZSAoayArIDEpIChpICsgMSkgbGltIGVsc2VcbiAgICBpZiBzLltpXSA9IGNsb3NpbmcgdGhlblxuICAgICAgaWYgayA9IDAgdGhlbiBpIGVsc2UgYWR2YW5jZSAoayAtIDEpIChpICsgMSkgbGltXG4gICAgZWxzZSBhZHZhbmNlIGsgKGkgKyAxKSBsaW0gaW5cbiAgYWR2YW5jZSBrIHN0YXJ0IChTdHJpbmcubGVuZ3RoIHMpXG5cbmxldCBhZHZhbmNlX3RvX25vbl9hbHBoYSBzIHN0YXJ0ID1cbiAgbGV0IHJlYyBhZHZhbmNlIGkgbGltID1cbiAgICBpZiBpID49IGxpbSB0aGVuIGxpbSBlbHNlXG4gICAgbWF0Y2ggcy5baV0gd2l0aFxuICAgIHwgJ2EnIC4uICd6JyB8ICdBJyAuLiAnWicgfCAnMCcgLi4gJzknIHwgJ18nIC0+IGFkdmFuY2UgKGkgKyAxKSBsaW1cbiAgICB8IF8gLT4gaSBpblxuICBhZHZhbmNlIHN0YXJ0IChTdHJpbmcubGVuZ3RoIHMpXG5cbigqIFdlIGFyZSBqdXN0IGF0IHRoZSBiZWdpbm5pbmcgb2YgYW4gaWRlbnQgaW4gcywgc3RhcnRpbmcgYXQgc3RhcnQuICopXG5sZXQgZmluZF9pZGVudCBzIHN0YXJ0IGxpbSA9XG4gIGlmIHN0YXJ0ID49IGxpbSB0aGVuIHJhaXNlIE5vdF9mb3VuZCBlbHNlXG4gIG1hdGNoIHMuW3N0YXJ0XSB3aXRoXG4gICgqIFBhcmVudGhlc2l6ZWQgaWRlbnQgPyAqKVxuICB8ICcoJyB8ICd7JyBhcyBjIC0+XG4gICAgIGxldCBuZXdfc3RhcnQgPSBzdGFydCArIDEgaW5cbiAgICAgbGV0IHN0b3AgPSBhZHZhbmNlX3RvX2Nsb3NpbmcgYyAoY2xvc2luZyBjKSAwIHMgbmV3X3N0YXJ0IGluXG4gICAgIFN0cmluZy5zdWIgcyBuZXdfc3RhcnQgKHN0b3AgLSBzdGFydCAtIDEpLCBzdG9wICsgMVxuICAoKiBSZWd1bGFyIGlkZW50ICopXG4gIHwgXyAtPlxuICAgICBsZXQgc3RvcCA9IGFkdmFuY2VfdG9fbm9uX2FscGhhIHMgKHN0YXJ0ICsgMSkgaW5cbiAgICAgU3RyaW5nLnN1YiBzIHN0YXJ0IChzdG9wIC0gc3RhcnQpLCBzdG9wXG5cbigqIFN1YnN0aXR1dGUgJGlkZW50LCAkKGlkZW50KSwgb3IgJHtpZGVudH0gaW4gcyxcbiAgICBhY2NvcmRpbmcgdG8gdGhlIGZ1bmN0aW9uIG1hcHBpbmcgZi4gKilcbmxldCBhZGRfc3Vic3RpdHV0ZSBiIGYgcyA9XG4gIGxldCBsaW0gPSBTdHJpbmcubGVuZ3RoIHMgaW5cbiAgbGV0IHJlYyBzdWJzdCBwcmV2aW91cyBpID1cbiAgICBpZiBpIDwgbGltIHRoZW4gYmVnaW5cbiAgICAgIG1hdGNoIHMuW2ldIHdpdGhcbiAgICAgIHwgJyQnIGFzIGN1cnJlbnQgd2hlbiBwcmV2aW91cyA9ICdcXFxcJyAtPlxuICAgICAgICAgYWRkX2NoYXIgYiBjdXJyZW50O1xuICAgICAgICAgc3Vic3QgJyAnIChpICsgMSlcbiAgICAgIHwgJyQnIC0+XG4gICAgICAgICBsZXQgaiA9IGkgKyAxIGluXG4gICAgICAgICBsZXQgaWRlbnQsIG5leHRfaSA9IGZpbmRfaWRlbnQgcyBqIGxpbSBpblxuICAgICAgICAgYWRkX3N0cmluZyBiIChmIGlkZW50KTtcbiAgICAgICAgIHN1YnN0ICcgJyBuZXh0X2lcbiAgICAgIHwgY3VycmVudCB3aGVuIHByZXZpb3VzID09ICdcXFxcJyAtPlxuICAgICAgICAgYWRkX2NoYXIgYiAnXFxcXCc7XG4gICAgICAgICBhZGRfY2hhciBiIGN1cnJlbnQ7XG4gICAgICAgICBzdWJzdCAnICcgKGkgKyAxKVxuICAgICAgfCAnXFxcXCcgYXMgY3VycmVudCAtPlxuICAgICAgICAgc3Vic3QgY3VycmVudCAoaSArIDEpXG4gICAgICB8IGN1cnJlbnQgLT5cbiAgICAgICAgIGFkZF9jaGFyIGIgY3VycmVudDtcbiAgICAgICAgIHN1YnN0IGN1cnJlbnQgKGkgKyAxKVxuICAgIGVuZCBlbHNlXG4gICAgaWYgcHJldmlvdXMgPSAnXFxcXCcgdGhlbiBhZGRfY2hhciBiIHByZXZpb3VzIGluXG4gIHN1YnN0ICcgJyAwXG5cbmxldCB0cnVuY2F0ZSBiIGxlbiA9XG4gICAgaWYgbGVuIDwgMCB8fCBsZW4gPiBsZW5ndGggYiB0aGVuXG4gICAgICBpbnZhbGlkX2FyZyBcIkJ1ZmZlci50cnVuY2F0ZVwiXG4gICAgZWxzZVxuICAgICAgYi5wb3NpdGlvbiA8LSBsZW5cblxuKCoqIHsxIEl0ZXJhdG9yc30gKilcblxubGV0IHRvX3NlcSBiID1cbiAgbGV0IHJlYyBhdXggaSAoKSA9XG4gICAgKCogTm90ZSB0aGF0IGIucG9zaXRpb24gaXMgbm90IGEgY29uc3RhbnQgYW5kIGNhbm5vdCBiZSBsaWZ0ZWQgb3V0IG9mIGF1eCAqKVxuICAgIGlmIGkgPj0gYi5wb3NpdGlvbiB0aGVuIFNlcS5OaWxcbiAgICBlbHNlXG4gICAgICBsZXQgeCA9IEJ5dGVzLnVuc2FmZV9nZXQgYi5idWZmZXIgaSBpblxuICAgICAgU2VxLkNvbnMgKHgsIGF1eCAoaSsxKSlcbiAgaW5cbiAgYXV4IDBcblxubGV0IHRvX3NlcWkgYiA9XG4gIGxldCByZWMgYXV4IGkgKCkgPVxuICAgICgqIE5vdGUgdGhhdCBiLnBvc2l0aW9uIGlzIG5vdCBhIGNvbnN0YW50IGFuZCBjYW5ub3QgYmUgbGlmdGVkIG91dCBvZiBhdXggKilcbiAgICBpZiBpID49IGIucG9zaXRpb24gdGhlbiBTZXEuTmlsXG4gICAgZWxzZVxuICAgICAgbGV0IHggPSBCeXRlcy51bnNhZmVfZ2V0IGIuYnVmZmVyIGkgaW5cbiAgICAgIFNlcS5Db25zICgoaSx4KSwgYXV4IChpKzEpKVxuICBpblxuICBhdXggMFxuXG5sZXQgYWRkX3NlcSBiIHNlcSA9IFNlcS5pdGVyIChhZGRfY2hhciBiKSBzZXFcblxubGV0IG9mX3NlcSBpID1cbiAgbGV0IGIgPSBjcmVhdGUgMzIgaW5cbiAgYWRkX3NlcSBiIGk7XG4gIGJcblxuKCoqIHs2IEJpbmFyeSBlbmNvZGluZyBvZiBpbnRlZ2Vyc30gKilcblxuZXh0ZXJuYWwgdW5zYWZlX3NldF9pbnQ4IDogYnl0ZXMgLT4gaW50IC0+IGludCAtPiB1bml0ID0gXCIlYnl0ZXNfdW5zYWZlX3NldFwiXG5leHRlcm5hbCB1bnNhZmVfc2V0X2ludDE2IDogYnl0ZXMgLT4gaW50IC0+IGludCAtPiB1bml0ID0gXCIlY2FtbF9ieXRlc19zZXQxNnVcIlxuZXh0ZXJuYWwgdW5zYWZlX3NldF9pbnQzMiA6IGJ5dGVzIC0+IGludCAtPiBpbnQzMiAtPiB1bml0ID0gXCIlY2FtbF9ieXRlc19zZXQzMnVcIlxuZXh0ZXJuYWwgdW5zYWZlX3NldF9pbnQ2NCA6IGJ5dGVzIC0+IGludCAtPiBpbnQ2NCAtPiB1bml0ID0gXCIlY2FtbF9ieXRlc19zZXQ2NHVcIlxuZXh0ZXJuYWwgc3dhcDE2IDogaW50IC0+IGludCA9IFwiJWJzd2FwMTZcIlxuZXh0ZXJuYWwgc3dhcDMyIDogaW50MzIgLT4gaW50MzIgPSBcIiVic3dhcF9pbnQzMlwiXG5leHRlcm5hbCBzd2FwNjQgOiBpbnQ2NCAtPiBpbnQ2NCA9IFwiJWJzd2FwX2ludDY0XCJcblxuXG5sZXQgYWRkX2ludDggYiB4ID1cbiAgbGV0IG5ld19wb3NpdGlvbiA9IGIucG9zaXRpb24gKyAxIGluXG4gIGlmIG5ld19wb3NpdGlvbiA+IGIubGVuZ3RoIHRoZW4gcmVzaXplIGIgMTtcbiAgdW5zYWZlX3NldF9pbnQ4IGIuYnVmZmVyIGIucG9zaXRpb24geDtcbiAgYi5wb3NpdGlvbiA8LSBuZXdfcG9zaXRpb25cblxubGV0IGFkZF9pbnQxNl9uZSBiIHggPVxuICBsZXQgbmV3X3Bvc2l0aW9uID0gYi5wb3NpdGlvbiArIDIgaW5cbiAgaWYgbmV3X3Bvc2l0aW9uID4gYi5sZW5ndGggdGhlbiByZXNpemUgYiAyO1xuICB1bnNhZmVfc2V0X2ludDE2IGIuYnVmZmVyIGIucG9zaXRpb24geDtcbiAgYi5wb3NpdGlvbiA8LSBuZXdfcG9zaXRpb25cblxubGV0IGFkZF9pbnQzMl9uZSBiIHggPVxuICBsZXQgbmV3X3Bvc2l0aW9uID0gYi5wb3NpdGlvbiArIDQgaW5cbiAgaWYgbmV3X3Bvc2l0aW9uID4gYi5sZW5ndGggdGhlbiByZXNpemUgYiA0O1xuICB1bnNhZmVfc2V0X2ludDMyIGIuYnVmZmVyIGIucG9zaXRpb24geDtcbiAgYi5wb3NpdGlvbiA8LSBuZXdfcG9zaXRpb25cblxubGV0IGFkZF9pbnQ2NF9uZSBiIHggPVxuICBsZXQgbmV3X3Bvc2l0aW9uID0gYi5wb3NpdGlvbiArIDggaW5cbiAgaWYgbmV3X3Bvc2l0aW9uID4gYi5sZW5ndGggdGhlbiByZXNpemUgYiA4O1xuICB1bnNhZmVfc2V0X2ludDY0IGIuYnVmZmVyIGIucG9zaXRpb24geDtcbiAgYi5wb3NpdGlvbiA8LSBuZXdfcG9zaXRpb25cblxubGV0IGFkZF9pbnQxNl9sZSBiIHggPVxuICBhZGRfaW50MTZfbmUgYiAoaWYgU3lzLmJpZ19lbmRpYW4gdGhlbiBzd2FwMTYgeCBlbHNlIHgpXG5cbmxldCBhZGRfaW50MTZfYmUgYiB4ID1cbiAgYWRkX2ludDE2X25lIGIgKGlmIFN5cy5iaWdfZW5kaWFuIHRoZW4geCBlbHNlIHN3YXAxNiB4KVxuXG5sZXQgYWRkX2ludDMyX2xlIGIgeCA9XG4gIGFkZF9pbnQzMl9uZSBiIChpZiBTeXMuYmlnX2VuZGlhbiB0aGVuIHN3YXAzMiB4IGVsc2UgeClcblxubGV0IGFkZF9pbnQzMl9iZSBiIHggPVxuICBhZGRfaW50MzJfbmUgYiAoaWYgU3lzLmJpZ19lbmRpYW4gdGhlbiB4IGVsc2Ugc3dhcDMyIHgpXG5cbmxldCBhZGRfaW50NjRfbGUgYiB4ID1cbiAgYWRkX2ludDY0X25lIGIgKGlmIFN5cy5iaWdfZW5kaWFuIHRoZW4gc3dhcDY0IHggZWxzZSB4KVxuXG5sZXQgYWRkX2ludDY0X2JlIGIgeCA9XG4gIGFkZF9pbnQ2NF9uZSBiIChpZiBTeXMuYmlnX2VuZGlhbiB0aGVuIHggZWxzZSBzd2FwNjQgeClcblxubGV0IGFkZF91aW50OCA9IGFkZF9pbnQ4XG5sZXQgYWRkX3VpbnQxNl9uZSA9IGFkZF9pbnQxNl9uZVxubGV0IGFkZF91aW50MTZfbGUgPSBhZGRfaW50MTZfbGVcbmxldCBhZGRfdWludDE2X2JlID0gYWRkX2ludDE2X2JlXG4iLCIoKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9DYW1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgQmVub2l0IFZhdWdvbiwgRU5TVEEgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIENvcHlyaWdodCAyMDE0IEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgICAgICopXG4oKiAgICAgZW4gQXV0b21hdGlxdWUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIEFsbCByaWdodHMgcmVzZXJ2ZWQuICBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mICAgICopXG4oKiAgIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyLjEsIHdpdGggdGhlICAgICAgICAgICopXG4oKiAgIHNwZWNpYWwgZXhjZXB0aW9uIG9uIGxpbmtpbmcgZGVzY3JpYmVkIGluIHRoZSBmaWxlIExJQ0VOU0UuICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG5cbm9wZW4gQ2FtbGludGVybmFsRm9ybWF0QmFzaWNzXG5cbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4gICAgICAgICAgICgqIFRvb2xzIHRvIG1hbmlwdWxhdGUgc2Nhbm5pbmcgc2V0IG9mIGNoYXJzIChzZWUgJVsuLi5dKSAqKVxuXG50eXBlIG11dGFibGVfY2hhcl9zZXQgPSBieXRlc1xuXG4oKiBDcmVhdGUgYSBmcmVzaCwgZW1wdHksIG11dGFibGUgY2hhciBzZXQuICopXG5sZXQgY3JlYXRlX2NoYXJfc2V0ICgpID0gQnl0ZXMubWFrZSAzMiAnXFwwMDAnXG5cbigqIEFkZCBhIGNoYXIgaW4gYSBtdXRhYmxlIGNoYXIgc2V0LiAqKVxubGV0IGFkZF9pbl9jaGFyX3NldCBjaGFyX3NldCBjID1cbiAgbGV0IGluZCA9IGludF9vZl9jaGFyIGMgaW5cbiAgbGV0IHN0cl9pbmQgPSBpbmQgbHNyIDMgYW5kIG1hc2sgPSAxIGxzbCAoaW5kIGxhbmQgMGIxMTEpIGluXG4gIEJ5dGVzLnNldCBjaGFyX3NldCBzdHJfaW5kXG4gICAgKGNoYXJfb2ZfaW50IChpbnRfb2ZfY2hhciAoQnl0ZXMuZ2V0IGNoYXJfc2V0IHN0cl9pbmQpIGxvciBtYXNrKSlcblxubGV0IGZyZWV6ZV9jaGFyX3NldCBjaGFyX3NldCA9XG4gIEJ5dGVzLnRvX3N0cmluZyBjaGFyX3NldFxuXG4oKiBDb21wdXRlIHRoZSBjb21wbGVtZW50IG9mIGEgY2hhciBzZXQuICopXG5sZXQgcmV2X2NoYXJfc2V0IGNoYXJfc2V0ID1cbiAgbGV0IGNoYXJfc2V0JyA9IGNyZWF0ZV9jaGFyX3NldCAoKSBpblxuICBmb3IgaSA9IDAgdG8gMzEgZG9cbiAgICBCeXRlcy5zZXQgY2hhcl9zZXQnIGlcbiAgICAgIChjaGFyX29mX2ludCAoaW50X29mX2NoYXIgKFN0cmluZy5nZXQgY2hhcl9zZXQgaSkgbHhvciAweEZGKSk7XG4gIGRvbmU7XG4gIEJ5dGVzLnVuc2FmZV90b19zdHJpbmcgY2hhcl9zZXQnXG5cbigqIFJldHVybiB0cnVlIGlmIGEgYGMnIGlzIGluIGBjaGFyX3NldCcuICopXG5sZXQgaXNfaW5fY2hhcl9zZXQgY2hhcl9zZXQgYyA9XG4gIGxldCBpbmQgPSBpbnRfb2ZfY2hhciBjIGluXG4gIGxldCBzdHJfaW5kID0gaW5kIGxzciAzIGFuZCBtYXNrID0gMSBsc2wgKGluZCBsYW5kIDBiMTExKSBpblxuICAoaW50X29mX2NoYXIgKFN0cmluZy5nZXQgY2hhcl9zZXQgc3RyX2luZCkgbGFuZCBtYXNrKSA8PiAwXG5cblxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbiAgICAgICAgICAgICAgICAgICAgICAgICAoKiBJZ25vcmVkIHBhcmFtIGNvbnZlcnNpb24gKilcblxuKCogR0FEVCB1c2VkIHRvIGFic3RyYWN0IGFuIGV4aXN0ZW50aWFsIHR5cGUgcGFyYW1ldGVyLiAqKVxuKCogU2VlIHBhcmFtX2Zvcm1hdF9vZl9pZ25vcmVkX2Zvcm1hdC4gKilcbnR5cGUgKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIHBhcmFtX2Zvcm1hdF9lYmIgPSBQYXJhbV9mb3JtYXRfRUJCIDpcbiAgICAoJ3ggLT4gJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm10IC0+XG4gICAgKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIHBhcmFtX2Zvcm1hdF9lYmJcblxuKCogQ29tcHV0ZSBhIHBhZGRpbmcgYXNzb2NpYXRlZCB0byBhIHBhZF9vcHRpb24gKHNlZSBcIiVfNDJkXCIpLiAqKVxubGV0IHBhZF9vZl9wYWRfb3B0IHBhZF9vcHQgPSBtYXRjaCBwYWRfb3B0IHdpdGhcbiAgfCBOb25lIC0+IE5vX3BhZGRpbmdcbiAgfCBTb21lIHdpZHRoIC0+IExpdF9wYWRkaW5nIChSaWdodCwgd2lkdGgpXG5cbigqIENvbXB1dGUgYSBwcmVjaXNpb24gYXNzb2NpYXRlZCB0byBhIHByZWNfb3B0aW9uIChzZWUgXCIlXy40MmZcIikuICopXG5sZXQgcHJlY19vZl9wcmVjX29wdCBwcmVjX29wdCA9IG1hdGNoIHByZWNfb3B0IHdpdGhcbiAgfCBOb25lIC0+IE5vX3ByZWNpc2lvblxuICB8IFNvbWUgbmRlYyAtPiBMaXRfcHJlY2lzaW9uIG5kZWNcblxuKCogVHVybiBhbiBpZ25vcmVkIHBhcmFtIGludG8gaXRzIGVxdWl2YWxlbnQgbm90LWlnbm9yZWQgZm9ybWF0IG5vZGUuICopXG4oKiBVc2VkIGZvciBmb3JtYXQgcHJldHR5LXByaW50aW5nIGFuZCBTY2FuZi4gKilcbmxldCBwYXJhbV9mb3JtYXRfb2ZfaWdub3JlZF9mb3JtYXQgOiB0eXBlIGEgYiBjIGQgZSBmIHggeSAuXG4gICAgKGEsIGIsIGMsIGQsIHksIHgpIGlnbm9yZWQgLT4gKHgsIGIsIGMsIHksIGUsIGYpIGZtdCAtPlxuICAgICAgKGEsIGIsIGMsIGQsIGUsIGYpIHBhcmFtX2Zvcm1hdF9lYmIgPVxuZnVuIGlnbiBmbXQgLT4gbWF0Y2ggaWduIHdpdGhcbiAgfCBJZ25vcmVkX2NoYXIgLT5cbiAgICBQYXJhbV9mb3JtYXRfRUJCIChDaGFyIGZtdClcbiAgfCBJZ25vcmVkX2NhbWxfY2hhciAtPlxuICAgIFBhcmFtX2Zvcm1hdF9FQkIgKENhbWxfY2hhciBmbXQpXG4gIHwgSWdub3JlZF9zdHJpbmcgcGFkX29wdCAtPlxuICAgIFBhcmFtX2Zvcm1hdF9FQkIgKFN0cmluZyAocGFkX29mX3BhZF9vcHQgcGFkX29wdCwgZm10KSlcbiAgfCBJZ25vcmVkX2NhbWxfc3RyaW5nIHBhZF9vcHQgLT5cbiAgICBQYXJhbV9mb3JtYXRfRUJCIChDYW1sX3N0cmluZyAocGFkX29mX3BhZF9vcHQgcGFkX29wdCwgZm10KSlcbiAgfCBJZ25vcmVkX2ludCAoaWNvbnYsIHBhZF9vcHQpIC0+XG4gICAgUGFyYW1fZm9ybWF0X0VCQiAoSW50IChpY29udiwgcGFkX29mX3BhZF9vcHQgcGFkX29wdCwgTm9fcHJlY2lzaW9uLCBmbXQpKVxuICB8IElnbm9yZWRfaW50MzIgKGljb252LCBwYWRfb3B0KSAtPlxuICAgIFBhcmFtX2Zvcm1hdF9FQkJcbiAgICAgIChJbnQzMiAoaWNvbnYsIHBhZF9vZl9wYWRfb3B0IHBhZF9vcHQsIE5vX3ByZWNpc2lvbiwgZm10KSlcbiAgfCBJZ25vcmVkX25hdGl2ZWludCAoaWNvbnYsIHBhZF9vcHQpIC0+XG4gICAgUGFyYW1fZm9ybWF0X0VCQlxuICAgICAgKE5hdGl2ZWludCAoaWNvbnYsIHBhZF9vZl9wYWRfb3B0IHBhZF9vcHQsIE5vX3ByZWNpc2lvbiwgZm10KSlcbiAgfCBJZ25vcmVkX2ludDY0IChpY29udiwgcGFkX29wdCkgLT5cbiAgICBQYXJhbV9mb3JtYXRfRUJCXG4gICAgICAoSW50NjQgKGljb252LCBwYWRfb2ZfcGFkX29wdCBwYWRfb3B0LCBOb19wcmVjaXNpb24sIGZtdCkpXG4gIHwgSWdub3JlZF9mbG9hdCAocGFkX29wdCwgcHJlY19vcHQpIC0+XG4gICAgUGFyYW1fZm9ybWF0X0VCQlxuICAgICAgKEZsb2F0ICgoRmxvYXRfZmxhZ18sIEZsb2F0X2YpLFxuICAgICAgICAgICAgICBwYWRfb2ZfcGFkX29wdCBwYWRfb3B0LCBwcmVjX29mX3ByZWNfb3B0IHByZWNfb3B0LCBmbXQpKVxuICB8IElnbm9yZWRfYm9vbCBwYWRfb3B0IC0+XG4gICAgUGFyYW1fZm9ybWF0X0VCQiAoQm9vbCAocGFkX29mX3BhZF9vcHQgcGFkX29wdCwgZm10KSlcbiAgfCBJZ25vcmVkX2Zvcm1hdF9hcmcgKHBhZF9vcHQsIGZtdHR5KSAtPlxuICAgIFBhcmFtX2Zvcm1hdF9FQkIgKEZvcm1hdF9hcmcgKHBhZF9vcHQsIGZtdHR5LCBmbXQpKVxuICB8IElnbm9yZWRfZm9ybWF0X3N1YnN0IChwYWRfb3B0LCBmbXR0eSkgLT5cbiAgICBQYXJhbV9mb3JtYXRfRUJCXG4gICAgICAoRm9ybWF0X3N1YnN0IChwYWRfb3B0LCBmbXR0eSwgZm10KSlcbiAgfCBJZ25vcmVkX3JlYWRlciAtPlxuICAgIFBhcmFtX2Zvcm1hdF9FQkIgKFJlYWRlciBmbXQpXG4gIHwgSWdub3JlZF9zY2FuX2NoYXJfc2V0ICh3aWR0aF9vcHQsIGNoYXJfc2V0KSAtPlxuICAgIFBhcmFtX2Zvcm1hdF9FQkIgKFNjYW5fY2hhcl9zZXQgKHdpZHRoX29wdCwgY2hhcl9zZXQsIGZtdCkpXG4gIHwgSWdub3JlZF9zY2FuX2dldF9jb3VudGVyIGNvdW50ZXIgLT5cbiAgICBQYXJhbV9mb3JtYXRfRUJCIChTY2FuX2dldF9jb3VudGVyIChjb3VudGVyLCBmbXQpKVxuICB8IElnbm9yZWRfc2Nhbl9uZXh0X2NoYXIgLT5cbiAgICBQYXJhbV9mb3JtYXRfRUJCIChTY2FuX25leHRfY2hhciBmbXQpXG5cblxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqIFR5cGVzICopXG5cbnR5cGUgKCdiLCAnYykgYWNjX2Zvcm1hdHRpbmdfZ2VuID1cbiAgfCBBY2Nfb3Blbl90YWcgb2YgKCdiLCAnYykgYWNjXG4gIHwgQWNjX29wZW5fYm94IG9mICgnYiwgJ2MpIGFjY1xuXG4oKiBSZXZlcnNlZCBsaXN0IG9mIHByaW50aW5nIGF0b21zLiAqKVxuKCogVXNlZCB0byBhY2N1bXVsYXRlIHByaW50ZiBhcmd1bWVudHMuICopXG5hbmQgKCdiLCAnYykgYWNjID1cbiAgfCBBY2NfZm9ybWF0dGluZ19saXQgb2YgKCdiLCAnYykgYWNjICogZm9ybWF0dGluZ19saXRcbiAgICAgICgqIFNwZWNpYWwgZm10dGluZyAoYm94KSAqKVxuICB8IEFjY19mb3JtYXR0aW5nX2dlbiBvZiAoJ2IsICdjKSBhY2MgKiAoJ2IsICdjKSBhY2NfZm9ybWF0dGluZ19nZW5cbiAgICAgICgqIFNwZWNpYWwgZm10dGluZyAoYm94KSAqKVxuICB8IEFjY19zdHJpbmdfbGl0ZXJhbCBvZiAoJ2IsICdjKSBhY2MgKiBzdHJpbmcgICAgICgqIExpdGVyYWwgc3RyaW5nICopXG4gIHwgQWNjX2NoYXJfbGl0ZXJhbCAgIG9mICgnYiwgJ2MpIGFjYyAqIGNoYXIgICAgICAgKCogTGl0ZXJhbCBjaGFyICopXG4gIHwgQWNjX2RhdGFfc3RyaW5nICAgIG9mICgnYiwgJ2MpIGFjYyAqIHN0cmluZyAgICAgKCogR2VuZXJhdGVkIHN0cmluZyAqKVxuICB8IEFjY19kYXRhX2NoYXIgICAgICBvZiAoJ2IsICdjKSBhY2MgKiBjaGFyICAgICAgICgqIEdlbmVyYXRlZCBjaGFyICopXG4gIHwgQWNjX2RlbGF5ICAgICAgICAgIG9mICgnYiwgJ2MpIGFjYyAqICgnYiAtPiAnYylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqIERlbGF5ZWQgcHJpbnRpbmcgKCVhLCAldCkgKilcbiAgfCBBY2NfZmx1c2ggICAgICAgICAgb2YgKCdiLCAnYykgYWNjICAgICAgICAgICAgICAoKiBGbHVzaCAqKVxuICB8IEFjY19pbnZhbGlkX2FyZyAgICBvZiAoJ2IsICdjKSBhY2MgKiBzdHJpbmdcbiAgICAgICgqIFJhaXNlIEludmFsaWRfYXJndW1lbnQgbXNnICopXG4gIHwgRW5kX29mX2FjY1xuXG4oKiBMaXN0IG9mIGhldGVyb2dlbmVvdXMgdmFsdWVzLiAqKVxuKCogVXNlZCB0byBhY2N1bXVsYXRlIHNjYW5mIGNhbGxiYWNrIGFyZ3VtZW50cy4gKilcbnR5cGUgKCdhLCAnYikgaGV0ZXJfbGlzdCA9XG4gIHwgQ29ucyA6ICdjICogKCdhLCAnYikgaGV0ZXJfbGlzdCAtPiAoJ2MgLT4gJ2EsICdiKSBoZXRlcl9saXN0XG4gIHwgTmlsIDogKCdiLCAnYikgaGV0ZXJfbGlzdFxuXG4oKiBFeGlzdGVudGlhbCBCbGFjayBCb3hlcy4gKilcbigqIFVzZWQgdG8gYWJzdHJhY3Qgc29tZSBleGlzdGVudGlhbCB0eXBlIHBhcmFtZXRlcnMuICopXG5cbigqIEdBRFQgdHlwZSBhc3NvY2lhdGluZyBhIHBhZGRpbmcgYW5kIGFuIGZtdHR5LiAqKVxuKCogU2VlIHRoZSB0eXBlX3BhZGRpbmcgZnVuY3Rpb24uICopXG50eXBlICgnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBwYWRkaW5nX2ZtdHR5X2ViYiA9IFBhZGRpbmdfZm10dHlfRUJCIDpcbiAgICAgKCd4LCAneSkgcGFkZGluZyAqICgneSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmbXR0eSAtPlxuICAgICAoJ3gsICdiLCAnYywgJ2QsICdlLCAnZikgcGFkZGluZ19mbXR0eV9lYmJcblxuKCogR0FEVCB0eXBlIGFzc29jaWF0aW5nIGEgcGFkZGluZywgYSBwcmVjaXNpb24gYW5kIGFuIGZtdHR5LiAqKVxuKCogU2VlIHRoZSB0eXBlX3BhZHByZWMgZnVuY3Rpb24uICopXG50eXBlICgnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBwYWRwcmVjX2ZtdHR5X2ViYiA9IFBhZHByZWNfZm10dHlfRUJCIDpcbiAgICAgKCd4LCAneSkgcGFkZGluZyAqICgneSwgJ3opIHByZWNpc2lvbiAqICgneiwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmbXR0eSAtPlxuICAgICAoJ3gsICdiLCAnYywgJ2QsICdlLCAnZikgcGFkcHJlY19mbXR0eV9lYmJcblxuKCogR0FEVCB0eXBlIGFzc29jaWF0aW5nIGEgcGFkZGluZyBhbmQgYW4gZm10LiAqKVxuKCogU2VlIG1ha2VfcGFkZGluZ19mbXRfZWJiIGFuZCBwYXJzZV9mb3JtYXQgZnVuY3Rpb25zLiAqKVxudHlwZSAoJ2EsICdiLCAnYywgJ2UsICdmKSBwYWRkaW5nX2ZtdF9lYmIgPSBQYWRkaW5nX2ZtdF9FQkIgOlxuICAgICAoXywgJ3ggLT4gJ2EpIHBhZGRpbmcgKlxuICAgICAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm10IC0+XG4gICAgICgneCwgJ2IsICdjLCAnZSwgJ2YpIHBhZGRpbmdfZm10X2ViYlxuXG4oKiBHQURUIHR5cGUgYXNzb2NpYXRpbmcgYSBwcmVjaXNpb24gYW5kIGFuIGZtdC4gKilcbigqIFNlZSBtYWtlX3ByZWNpc2lvbl9mbXRfZWJiIGFuZCBwYXJzZV9mb3JtYXQgZnVuY3Rpb25zLiAqKVxudHlwZSAoJ2EsICdiLCAnYywgJ2UsICdmKSBwcmVjaXNpb25fZm10X2ViYiA9IFByZWNpc2lvbl9mbXRfRUJCIDpcbiAgICAgKF8sICd4IC0+ICdhKSBwcmVjaXNpb24gKlxuICAgICAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm10IC0+XG4gICAgICgneCwgJ2IsICdjLCAnZSwgJ2YpIHByZWNpc2lvbl9mbXRfZWJiXG5cbigqIEdBRFQgdHlwZSBhc3NvY2lhdGluZyBhIHBhZGRpbmcsIGEgcHJlY2lzaW9uIGFuZCBhbiBmbXQuICopXG4oKiBTZWUgbWFrZV9wYWRwcmVjX2ZtdF9lYmIgYW5kIHBhcnNlX2Zvcm1hdCBmdW5jdGlvbnMuICopXG50eXBlICgncCwgJ2IsICdjLCAnZSwgJ2YpIHBhZHByZWNfZm10X2ViYiA9IFBhZHByZWNfZm10X0VCQiA6XG4gICAgICgneCwgJ3kpIHBhZGRpbmcgKiAoJ3ksICdwIC0+ICdhKSBwcmVjaXNpb24gKlxuICAgICAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm10IC0+XG4gICAgICgncCwgJ2IsICdjLCAnZSwgJ2YpIHBhZHByZWNfZm10X2ViYlxuXG4oKiBBYnN0cmFjdCB0aGUgJ2EgYW5kICdkIHBhcmFtZXRlcnMgb2YgYW4gZm10LiAqKVxuKCogT3V0cHV0IHR5cGUgb2YgdGhlIGZvcm1hdCBwYXJzaW5nIGZ1bmN0aW9uLiAqKVxudHlwZSAoJ2IsICdjLCAnZSwgJ2YpIGZtdF9lYmIgPSBGbXRfRUJCIDpcbiAgICAgKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdCAtPlxuICAgICAoJ2IsICdjLCAnZSwgJ2YpIGZtdF9lYmJcblxuKCogR0FEVCB0eXBlIGFzc29jaWF0aW5nIGFuIGZtdHR5IGFuZCBhbiBmbXQuICopXG4oKiBTZWUgdGhlIHR5cGVfZm9ybWF0X2dlbiBmdW5jdGlvbi4gKilcbnR5cGUgKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZtdF9mbXR0eV9lYmIgPSBGbXRfZm10dHlfRUJCIDpcbiAgICAgKCdhLCAnYiwgJ2MsICdkLCAneSwgJ3gpIGZtdCAqXG4gICAgICgneCwgJ2IsICdjLCAneSwgJ2UsICdmKSBmbXR0eSAtPlxuICAgICAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm10X2ZtdHR5X2ViYlxuXG4oKiBHQURUIHR5cGUgYXNzb2NpYXRpbmcgYW4gZm10dHkgYW5kIGFuIGZtdC4gKilcbigqIFNlZSB0aGUgdHlwZV9pZ25vcmVkX2Zvcm1hdF9zdWJzdGl0dXRpb24gZnVuY3Rpb24uICopXG50eXBlICgnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmbXR0eV9mbXRfZWJiID0gRm10dHlfZm10X0VCQiA6XG4gICAgICgnYSwgJ2IsICdjLCAnZCwgJ3ksICd4KSBmbXR0eSAqXG4gICAgICgneCwgJ2IsICdjLCAneSwgJ2UsICdmKSBmbXRfZm10dHlfZWJiIC0+XG4gICAgICgnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmbXR0eV9mbXRfZWJiXG5cbigqIEFic3RyYWN0IGFsbCBmbXR0eSB0eXBlIHBhcmFtZXRlcnMuICopXG4oKiBVc2VkIHRvIGNvbXBhcmUgZm9ybWF0IHR5cGVzLiAqKVxudHlwZSBmbXR0eV9lYmIgPSBGbXR0eV9FQkIgOiAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm10dHkgLT4gZm10dHlfZWJiXG5cbigqIEFic3RyYWN0IGFsbCBwYWRkaW5nIHR5cGUgcGFyYW1ldGVycy4gKilcbigqIFVzZWQgdG8gY29tcGFyZSBwYWRkaW5ncy4gKilcbnR5cGUgcGFkZGluZ19lYmIgPSBQYWRkaW5nX0VCQiA6ICgnYSwgJ2IpIHBhZGRpbmcgLT4gcGFkZGluZ19lYmJcblxuKCogQWJzdHJhY3QgYWxsIHByZWNpc2lvbiB0eXBlIHBhcmFtZXRlcnMuICopXG4oKiBVc2VkIHRvIGNvbXBhcmUgcHJlY2lzaW9ucy4gKilcbnR5cGUgcHJlY2lzaW9uX2ViYiA9IFByZWNpc2lvbl9FQkIgOiAoJ2EsICdiKSBwcmVjaXNpb24gLT4gcHJlY2lzaW9uX2ViYlxuXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqIENvbnN0YW50cyAqKVxuXG4oKiBEZWZhdWx0IHByZWNpc2lvbiBmb3IgZmxvYXQgcHJpbnRpbmcuICopXG5sZXQgZGVmYXVsdF9mbG9hdF9wcmVjaXNpb24gZmNvbnYgPVxuICBtYXRjaCBzbmQgZmNvbnYgd2l0aFxuICB8IEZsb2F0X2YgfCBGbG9hdF9lIHwgRmxvYXRfRSB8IEZsb2F0X2cgfCBGbG9hdF9HIHwgRmxvYXRfaCB8IEZsb2F0X0hcbiAgfCBGbG9hdF9DRiAtPiAtNlxuICAoKiBGb3IgJWggJUggYW5kICUjRiBmb3JtYXRzLCBhIG5lZ2F0aXZlIHByZWNpc2lvbiBtZWFucyBcImFzIG1hbnkgZGlnaXRzIGFzXG4gICAgIG5lY2Vzc2FyeVwiLiAgRm9yIHRoZSBvdGhlciBGUCBmb3JtYXRzLCB3ZSB0YWtlIHRoZSBhYnNvbHV0ZSB2YWx1ZVxuICAgICBvZiB0aGUgcHJlY2lzaW9uLCBoZW5jZSA2IGRpZ2l0cyBieSBkZWZhdWx0LiAqKVxuICB8IEZsb2F0X0YgLT4gMTJcbiAgKCogRGVmYXVsdCBwcmVjaXNpb24gZm9yIE9DYW1sIGZsb2F0IHByaW50aW5nICglRikuICopXG5cbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogRXh0ZXJuYWxzICopXG5cbmV4dGVybmFsIGZvcm1hdF9mbG9hdDogc3RyaW5nIC0+IGZsb2F0IC0+IHN0cmluZ1xuICA9IFwiY2FtbF9mb3JtYXRfZmxvYXRcIlxuZXh0ZXJuYWwgZm9ybWF0X2ludDogc3RyaW5nIC0+IGludCAtPiBzdHJpbmdcbiAgPSBcImNhbWxfZm9ybWF0X2ludFwiXG5leHRlcm5hbCBmb3JtYXRfaW50MzI6IHN0cmluZyAtPiBpbnQzMiAtPiBzdHJpbmdcbiAgPSBcImNhbWxfaW50MzJfZm9ybWF0XCJcbmV4dGVybmFsIGZvcm1hdF9uYXRpdmVpbnQ6IHN0cmluZyAtPiBuYXRpdmVpbnQgLT4gc3RyaW5nXG4gID0gXCJjYW1sX25hdGl2ZWludF9mb3JtYXRcIlxuZXh0ZXJuYWwgZm9ybWF0X2ludDY0OiBzdHJpbmcgLT4gaW50NjQgLT4gc3RyaW5nXG4gID0gXCJjYW1sX2ludDY0X2Zvcm1hdFwiXG5leHRlcm5hbCBoZXhzdHJpbmdfb2ZfZmxvYXQ6IGZsb2F0IC0+IGludCAtPiBjaGFyIC0+IHN0cmluZ1xuICA9IFwiY2FtbF9oZXhzdHJpbmdfb2ZfZmxvYXRcIlxuXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuICAgICAgICAgICAgICAgICAgICAgKCogVG9vbHMgdG8gcHJldHR5LXByaW50IGZvcm1hdHMgKilcblxuKCogVHlwZSBvZiBleHRlbnNpYmxlIGNoYXJhY3RlciBidWZmZXJzLiAqKVxudHlwZSBidWZmZXIgPSB7XG4gIG11dGFibGUgaW5kIDogaW50O1xuICBtdXRhYmxlIGJ5dGVzIDogYnl0ZXM7XG59XG5cbigqIENyZWF0ZSBhIGZyZXNoIGJ1ZmZlci4gKilcbmxldCBidWZmZXJfY3JlYXRlIGluaXRfc2l6ZSA9IHsgaW5kID0gMDsgYnl0ZXMgPSBCeXRlcy5jcmVhdGUgaW5pdF9zaXplIH1cblxuKCogQ2hlY2sgc2l6ZSBvZiB0aGUgYnVmZmVyIGFuZCBncm93IGl0IGlmIG5lZWRlZC4gKilcbmxldCBidWZmZXJfY2hlY2tfc2l6ZSBidWYgb3ZlcmhlYWQgPVxuICBsZXQgbGVuID0gQnl0ZXMubGVuZ3RoIGJ1Zi5ieXRlcyBpblxuICBsZXQgbWluX2xlbiA9IGJ1Zi5pbmQgKyBvdmVyaGVhZCBpblxuICBpZiBtaW5fbGVuID4gbGVuIHRoZW4gKFxuICAgIGxldCBuZXdfbGVuID0gSW50Lm1heCAobGVuICogMikgbWluX2xlbiBpblxuICAgIGxldCBuZXdfc3RyID0gQnl0ZXMuY3JlYXRlIG5ld19sZW4gaW5cbiAgICBCeXRlcy5ibGl0IGJ1Zi5ieXRlcyAwIG5ld19zdHIgMCBsZW47XG4gICAgYnVmLmJ5dGVzIDwtIG5ld19zdHI7XG4gIClcblxuKCogQWRkIHRoZSBjaGFyYWN0ZXIgYGMnIHRvIHRoZSBidWZmZXIgYGJ1ZicuICopXG5sZXQgYnVmZmVyX2FkZF9jaGFyIGJ1ZiBjID1cbiAgYnVmZmVyX2NoZWNrX3NpemUgYnVmIDE7XG4gIEJ5dGVzLnNldCBidWYuYnl0ZXMgYnVmLmluZCBjO1xuICBidWYuaW5kIDwtIGJ1Zi5pbmQgKyAxXG5cbigqIEFkZCB0aGUgc3RyaW5nIGBzJyB0byB0aGUgYnVmZmVyIGBidWYnLiAqKVxubGV0IGJ1ZmZlcl9hZGRfc3RyaW5nIGJ1ZiBzID1cbiAgbGV0IHN0cl9sZW4gPSBTdHJpbmcubGVuZ3RoIHMgaW5cbiAgYnVmZmVyX2NoZWNrX3NpemUgYnVmIHN0cl9sZW47XG4gIFN0cmluZy5ibGl0IHMgMCBidWYuYnl0ZXMgYnVmLmluZCBzdHJfbGVuO1xuICBidWYuaW5kIDwtIGJ1Zi5pbmQgKyBzdHJfbGVuXG5cbigqIEdldCB0aGUgY29udGVudCBvZiB0aGUgYnVmZmVyLiAqKVxubGV0IGJ1ZmZlcl9jb250ZW50cyBidWYgPVxuICBCeXRlcy5zdWJfc3RyaW5nIGJ1Zi5ieXRlcyAwIGJ1Zi5pbmRcblxuKCoqKilcblxuKCogQ29udmVydCBhbiBpbnRlZ2VyIGNvbnZlcnNpb24gdG8gY2hhci4gKilcbmxldCBjaGFyX29mX2ljb252IGljb252ID0gbWF0Y2ggaWNvbnYgd2l0aFxuICB8IEludF9kIHwgSW50X3BkIHwgSW50X3NkIHwgSW50X0NkIC0+ICdkJyB8IEludF9pIHwgSW50X3BpIHwgSW50X3NpXG4gIHwgSW50X0NpIC0+ICdpJyB8IEludF94IHwgSW50X0N4IC0+ICd4JyB8IEludF9YIHwgSW50X0NYIC0+ICdYJyB8IEludF9vXG4gIHwgSW50X0NvIC0+ICdvJyB8IEludF91IHwgSW50X0N1IC0+ICd1J1xuXG4oKiBDb252ZXJ0IGEgZmxvYXQgY29udmVyc2lvbiB0byBjaGFyLiAqKVxuKCogYGNGJyB3aWxsIGJlICdGJyBmb3IgZGlzcGxheWluZyBmb3JtYXQgYW5kICdnJyB0byBjYWxsIGxpYmMgcHJpbnRmICopXG5sZXQgY2hhcl9vZl9mY29udiA/KGNGPSdGJykgZmNvbnYgPSBtYXRjaCBzbmQgZmNvbnYgd2l0aFxuICB8IEZsb2F0X2YgLT4gJ2YnIHwgRmxvYXRfZSAtPiAnZSdcbiAgfCBGbG9hdF9FIC0+ICdFJyB8IEZsb2F0X2cgLT4gJ2cnXG4gIHwgRmxvYXRfRyAtPiAnRycgfCBGbG9hdF9GIC0+IGNGXG4gIHwgRmxvYXRfaCAtPiAnaCcgfCBGbG9hdF9IIC0+ICdIJ1xuICB8IEZsb2F0X0NGIC0+ICdGJ1xuXG5cbigqIENvbnZlcnQgYSBzY2FubmluZyBjb3VudGVyIHRvIGNoYXIuICopXG5sZXQgY2hhcl9vZl9jb3VudGVyIGNvdW50ZXIgPSBtYXRjaCBjb3VudGVyIHdpdGhcbiAgfCBMaW5lX2NvdW50ZXIgIC0+ICdsJ1xuICB8IENoYXJfY291bnRlciAgLT4gJ24nXG4gIHwgVG9rZW5fY291bnRlciAtPiAnTidcblxuKCoqKilcblxuKCogUHJpbnQgYSBjaGFyX3NldCBpbiBhIGJ1ZmZlciB3aXRoIHRoZSBPQ2FtbCBmb3JtYXQgbGV4aWNhbCBjb252ZW50aW9uLiAqKVxubGV0IGJwcmludF9jaGFyX3NldCBidWYgY2hhcl9zZXQgPVxuICBsZXQgcmVjIHByaW50X3N0YXJ0IHNldCA9XG4gICAgbGV0IGlzX2Fsb25lIGMgPVxuICAgICAgbGV0IGJlZm9yZSwgYWZ0ZXIgPSBDaGFyLihjaHIgKGNvZGUgYyAtIDEpLCBjaHIgKGNvZGUgYyArIDEpKSBpblxuICAgICAgaXNfaW5fY2hhcl9zZXQgc2V0IGNcbiAgICAgICYmIG5vdCAoaXNfaW5fY2hhcl9zZXQgc2V0IGJlZm9yZSAmJiBpc19pbl9jaGFyX3NldCBzZXQgYWZ0ZXIpIGluXG4gICAgaWYgaXNfYWxvbmUgJ10nIHRoZW4gYnVmZmVyX2FkZF9jaGFyIGJ1ZiAnXSc7XG4gICAgcHJpbnRfb3V0IHNldCAxO1xuICAgIGlmIGlzX2Fsb25lICctJyB0aGVuIGJ1ZmZlcl9hZGRfY2hhciBidWYgJy0nO1xuICBhbmQgcHJpbnRfb3V0IHNldCBpID1cbiAgICBpZiBpIDwgMjU2IHRoZW5cbiAgICAgIGlmIGlzX2luX2NoYXJfc2V0IHNldCAoY2hhcl9vZl9pbnQgaSkgdGhlbiBwcmludF9maXJzdCBzZXQgaVxuICAgICAgZWxzZSBwcmludF9vdXQgc2V0IChpICsgMSlcbiAgYW5kIHByaW50X2ZpcnN0IHNldCBpID1cbiAgICBtYXRjaCBjaGFyX29mX2ludCBpIHdpdGhcbiAgICB8ICdcXDI1NScgLT4gcHJpbnRfY2hhciBidWYgMjU1O1xuICAgIHwgJ10nIHwgJy0nIC0+IHByaW50X291dCBzZXQgKGkgKyAxKTtcbiAgICB8IF8gLT4gcHJpbnRfc2Vjb25kIHNldCAoaSArIDEpO1xuICBhbmQgcHJpbnRfc2Vjb25kIHNldCBpID1cbiAgICBpZiBpc19pbl9jaGFyX3NldCBzZXQgKGNoYXJfb2ZfaW50IGkpIHRoZW5cbiAgICAgIG1hdGNoIGNoYXJfb2ZfaW50IGkgd2l0aFxuICAgICAgfCAnXFwyNTUnIC0+XG4gICAgICAgIHByaW50X2NoYXIgYnVmIDI1NDtcbiAgICAgICAgcHJpbnRfY2hhciBidWYgMjU1O1xuICAgICAgfCAnXScgfCAnLScgd2hlbiBub3QgKGlzX2luX2NoYXJfc2V0IHNldCAoY2hhcl9vZl9pbnQgKGkgKyAxKSkpIC0+XG4gICAgICAgIHByaW50X2NoYXIgYnVmIChpIC0gMSk7XG4gICAgICAgIHByaW50X291dCBzZXQgKGkgKyAxKTtcbiAgICAgIHwgXyB3aGVuIG5vdCAoaXNfaW5fY2hhcl9zZXQgc2V0IChjaGFyX29mX2ludCAoaSArIDEpKSkgLT5cbiAgICAgICAgcHJpbnRfY2hhciBidWYgKGkgLSAxKTtcbiAgICAgICAgcHJpbnRfY2hhciBidWYgaTtcbiAgICAgICAgcHJpbnRfb3V0IHNldCAoaSArIDIpO1xuICAgICAgfCBfIC0+XG4gICAgICAgIHByaW50X2luIHNldCAoaSAtIDEpIChpICsgMik7XG4gICAgZWxzZSAoXG4gICAgICBwcmludF9jaGFyIGJ1ZiAoaSAtIDEpO1xuICAgICAgcHJpbnRfb3V0IHNldCAoaSArIDEpO1xuICAgIClcbiAgYW5kIHByaW50X2luIHNldCBpIGogPVxuICAgIGlmIGogPSAyNTYgfHwgbm90IChpc19pbl9jaGFyX3NldCBzZXQgKGNoYXJfb2ZfaW50IGopKSB0aGVuIChcbiAgICAgIHByaW50X2NoYXIgYnVmIGk7XG4gICAgICBwcmludF9jaGFyIGJ1ZiAoaW50X29mX2NoYXIgJy0nKTtcbiAgICAgIHByaW50X2NoYXIgYnVmIChqIC0gMSk7XG4gICAgICBpZiBqIDwgMjU2IHRoZW4gcHJpbnRfb3V0IHNldCAoaiArIDEpO1xuICAgICkgZWxzZVxuICAgICAgcHJpbnRfaW4gc2V0IGkgKGogKyAxKTtcbiAgYW5kIHByaW50X2NoYXIgYnVmIGkgPSBtYXRjaCBjaGFyX29mX2ludCBpIHdpdGhcbiAgICB8ICclJyAtPiBidWZmZXJfYWRkX2NoYXIgYnVmICclJzsgYnVmZmVyX2FkZF9jaGFyIGJ1ZiAnJSc7XG4gICAgfCAnQCcgLT4gYnVmZmVyX2FkZF9jaGFyIGJ1ZiAnJSc7IGJ1ZmZlcl9hZGRfY2hhciBidWYgJ0AnO1xuICAgIHwgYyAgIC0+IGJ1ZmZlcl9hZGRfY2hhciBidWYgYztcbiAgaW5cbiAgYnVmZmVyX2FkZF9jaGFyIGJ1ZiAnWyc7XG4gIHByaW50X3N0YXJ0IChcbiAgICBpZiBpc19pbl9jaGFyX3NldCBjaGFyX3NldCAnXFwwMDAnXG4gICAgdGhlbiAoIGJ1ZmZlcl9hZGRfY2hhciBidWYgJ14nOyByZXZfY2hhcl9zZXQgY2hhcl9zZXQgKVxuICAgIGVsc2UgY2hhcl9zZXRcbiAgKTtcbiAgYnVmZmVyX2FkZF9jaGFyIGJ1ZiAnXSdcblxuKCoqKilcblxuKCogUHJpbnQgYSBwYWR0eSBpbiBhIGJ1ZmZlciB3aXRoIHRoZSBmb3JtYXQtbGlrZSBzeW50YXguICopXG5sZXQgYnByaW50X3BhZHR5IGJ1ZiBwYWR0eSA9IG1hdGNoIHBhZHR5IHdpdGhcbiAgfCBMZWZ0ICAtPiBidWZmZXJfYWRkX2NoYXIgYnVmICctJ1xuICB8IFJpZ2h0IC0+ICgpXG4gIHwgWmVyb3MgLT4gYnVmZmVyX2FkZF9jaGFyIGJ1ZiAnMCdcblxuKCogUHJpbnQgdGhlICdfJyBvZiBhbiBpZ25vcmVkIGZsYWcgaWYgbmVlZGVkLiAqKVxubGV0IGJwcmludF9pZ25vcmVkX2ZsYWcgYnVmIGlnbl9mbGFnID1cbiAgaWYgaWduX2ZsYWcgdGhlbiBidWZmZXJfYWRkX2NoYXIgYnVmICdfJ1xuXG4oKioqKVxuXG5sZXQgYnByaW50X3BhZF9vcHQgYnVmIHBhZF9vcHQgPSBtYXRjaCBwYWRfb3B0IHdpdGhcbiAgfCBOb25lIC0+ICgpXG4gIHwgU29tZSB3aWR0aCAtPiBidWZmZXJfYWRkX3N0cmluZyBidWYgKEludC50b19zdHJpbmcgd2lkdGgpXG5cbigqKiopXG5cbigqIFByaW50IHBhZGRpbmcgaW4gYSBidWZmZXIgd2l0aCB0aGUgZm9ybWF0LWxpa2Ugc3ludGF4LiAqKVxubGV0IGJwcmludF9wYWRkaW5nIDogdHlwZSBhIGIgLiBidWZmZXIgLT4gKGEsIGIpIHBhZGRpbmcgLT4gdW5pdCA9XG5mdW4gYnVmIHBhZCAtPiBtYXRjaCBwYWQgd2l0aFxuICB8IE5vX3BhZGRpbmcgLT4gKClcbiAgfCBMaXRfcGFkZGluZyAocGFkdHksIG4pIC0+XG4gICAgYnByaW50X3BhZHR5IGJ1ZiBwYWR0eTtcbiAgICBidWZmZXJfYWRkX3N0cmluZyBidWYgKEludC50b19zdHJpbmcgbik7XG4gIHwgQXJnX3BhZGRpbmcgcGFkdHkgLT5cbiAgICBicHJpbnRfcGFkdHkgYnVmIHBhZHR5O1xuICAgIGJ1ZmZlcl9hZGRfY2hhciBidWYgJyonXG5cbigqIFByaW50IHByZWNpc2lvbiBpbiBhIGJ1ZmZlciB3aXRoIHRoZSBmb3JtYXQtbGlrZSBzeW50YXguICopXG5sZXQgYnByaW50X3ByZWNpc2lvbiA6IHR5cGUgYSBiIC4gYnVmZmVyIC0+IChhLCBiKSBwcmVjaXNpb24gLT4gdW5pdCA9XG4gIGZ1biBidWYgcHJlYyAtPiBtYXRjaCBwcmVjIHdpdGhcbiAgfCBOb19wcmVjaXNpb24gLT4gKClcbiAgfCBMaXRfcHJlY2lzaW9uIG4gLT5cbiAgICBidWZmZXJfYWRkX2NoYXIgYnVmICcuJztcbiAgICBidWZmZXJfYWRkX3N0cmluZyBidWYgKEludC50b19zdHJpbmcgbik7XG4gIHwgQXJnX3ByZWNpc2lvbiAtPlxuICAgIGJ1ZmZlcl9hZGRfc3RyaW5nIGJ1ZiBcIi4qXCJcblxuKCoqKilcblxuKCogUHJpbnQgdGhlIG9wdGlvbmFsICcrJywgJyAnIG9yICcjJyBhc3NvY2lhdGVkIHRvIGFuIGludCBjb252ZXJzaW9uLiAqKVxubGV0IGJwcmludF9pY29udl9mbGFnIGJ1ZiBpY29udiA9IG1hdGNoIGljb252IHdpdGhcbiAgfCBJbnRfcGQgfCBJbnRfcGkgLT4gYnVmZmVyX2FkZF9jaGFyIGJ1ZiAnKydcbiAgfCBJbnRfc2QgfCBJbnRfc2kgLT4gYnVmZmVyX2FkZF9jaGFyIGJ1ZiAnICdcbiAgfCBJbnRfQ3ggfCBJbnRfQ1ggfCBJbnRfQ28gfCBJbnRfQ2QgfCBJbnRfQ2kgfCBJbnRfQ3UgLT5cbiAgICAgIGJ1ZmZlcl9hZGRfY2hhciBidWYgJyMnXG4gIHwgSW50X2QgfCBJbnRfaSB8IEludF94IHwgSW50X1ggfCBJbnRfbyB8IEludF91IC0+ICgpXG5cbigqIFByaW50IGFuIGNvbXBsZXRlIGludCBmb3JtYXQgaW4gYSBidWZmZXIgKGV4OiBcIiUzLipkXCIpLiAqKVxubGV0IGJwcmludF9pbnRfZm10IGJ1ZiBpZ25fZmxhZyBpY29udiBwYWQgcHJlYyA9XG4gIGJ1ZmZlcl9hZGRfY2hhciBidWYgJyUnO1xuICBicHJpbnRfaWdub3JlZF9mbGFnIGJ1ZiBpZ25fZmxhZztcbiAgYnByaW50X2ljb252X2ZsYWcgYnVmIGljb252O1xuICBicHJpbnRfcGFkZGluZyBidWYgcGFkO1xuICBicHJpbnRfcHJlY2lzaW9uIGJ1ZiBwcmVjO1xuICBidWZmZXJfYWRkX2NoYXIgYnVmIChjaGFyX29mX2ljb252IGljb252KVxuXG4oKiBQcmludCBhIGNvbXBsZXRlIGludDMyLCBuYXRpdmVpbnQgb3IgaW50NjQgZm9ybWF0IGluIGEgYnVmZmVyLiAqKVxubGV0IGJwcmludF9hbHRpbnRfZm10IGJ1ZiBpZ25fZmxhZyBpY29udiBwYWQgcHJlYyBjID1cbiAgYnVmZmVyX2FkZF9jaGFyIGJ1ZiAnJSc7XG4gIGJwcmludF9pZ25vcmVkX2ZsYWcgYnVmIGlnbl9mbGFnO1xuICBicHJpbnRfaWNvbnZfZmxhZyBidWYgaWNvbnY7XG4gIGJwcmludF9wYWRkaW5nIGJ1ZiBwYWQ7XG4gIGJwcmludF9wcmVjaXNpb24gYnVmIHByZWM7XG4gIGJ1ZmZlcl9hZGRfY2hhciBidWYgYztcbiAgYnVmZmVyX2FkZF9jaGFyIGJ1ZiAoY2hhcl9vZl9pY29udiBpY29udilcblxuKCoqKilcblxuKCogUHJpbnQgdGhlIG9wdGlvbmFsICcrJywgJyAnIGFuZC9vciAnIycgYXNzb2NpYXRlZCB0byBhIGZsb2F0IGNvbnZlcnNpb24uICopXG5sZXQgYnByaW50X2Zjb252X2ZsYWcgYnVmIGZjb252ID1cbiAgYmVnaW4gbWF0Y2ggZnN0IGZjb252IHdpdGhcbiAgfCBGbG9hdF9mbGFnX3AgLT4gYnVmZmVyX2FkZF9jaGFyIGJ1ZiAnKydcbiAgfCBGbG9hdF9mbGFnX3MgLT4gYnVmZmVyX2FkZF9jaGFyIGJ1ZiAnICdcbiAgfCBGbG9hdF9mbGFnXyAtPiAoKSBlbmQ7XG4gIG1hdGNoIHNuZCBmY29udiB3aXRoXG4gIHwgRmxvYXRfQ0YgLT4gYnVmZmVyX2FkZF9jaGFyIGJ1ZiAnIydcbiAgfCBGbG9hdF9mIHwgRmxvYXRfZSB8IEZsb2F0X0UgfCBGbG9hdF9nIHwgRmxvYXRfR1xuICB8IEZsb2F0X0YgfCBGbG9hdF9oIHwgRmxvYXRfSCAtPiAoKVxuXG4oKiBQcmludCBhIGNvbXBsZXRlIGZsb2F0IGZvcm1hdCBpbiBhIGJ1ZmZlciAoZXg6IFwiJSsqLjNmXCIpLiAqKVxubGV0IGJwcmludF9mbG9hdF9mbXQgYnVmIGlnbl9mbGFnIGZjb252IHBhZCBwcmVjID1cbiAgYnVmZmVyX2FkZF9jaGFyIGJ1ZiAnJSc7XG4gIGJwcmludF9pZ25vcmVkX2ZsYWcgYnVmIGlnbl9mbGFnO1xuICBicHJpbnRfZmNvbnZfZmxhZyBidWYgZmNvbnY7XG4gIGJwcmludF9wYWRkaW5nIGJ1ZiBwYWQ7XG4gIGJwcmludF9wcmVjaXNpb24gYnVmIHByZWM7XG4gIGJ1ZmZlcl9hZGRfY2hhciBidWYgKGNoYXJfb2ZfZmNvbnYgZmNvbnYpXG5cbigqIENvbXB1dGUgdGhlIGxpdGVyYWwgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgRm9ybWF0dGluZ19saXQuICopXG4oKiBVc2VkIGJ5IFByaW50ZiBhbmQgU2NhbmYgd2hlcmUgZm9ybWF0dGluZyBpcyBub3QgaW50ZXJwcmV0ZWQuICopXG5sZXQgc3RyaW5nX29mX2Zvcm1hdHRpbmdfbGl0IGZvcm1hdHRpbmdfbGl0ID0gbWF0Y2ggZm9ybWF0dGluZ19saXQgd2l0aFxuICB8IENsb3NlX2JveCAgICAgICAgICAgIC0+IFwiQF1cIlxuICB8IENsb3NlX3RhZyAgICAgICAgICAgIC0+IFwiQH1cIlxuICB8IEJyZWFrIChzdHIsIF8sIF8pICAgIC0+IHN0clxuICB8IEZGbHVzaCAgICAgICAgICAgICAgIC0+IFwiQD9cIlxuICB8IEZvcmNlX25ld2xpbmUgICAgICAgIC0+IFwiQFxcblwiXG4gIHwgRmx1c2hfbmV3bGluZSAgICAgICAgLT4gXCJALlwiXG4gIHwgTWFnaWNfc2l6ZSAoc3RyLCBfKSAgLT4gc3RyXG4gIHwgRXNjYXBlZF9hdCAgICAgICAgICAgLT4gXCJAQFwiXG4gIHwgRXNjYXBlZF9wZXJjZW50ICAgICAgLT4gXCJAJVwiXG4gIHwgU2Nhbl9pbmRpYyBjIC0+IFwiQFwiIF4gKFN0cmluZy5tYWtlIDEgYylcblxuKCoqKilcblxuKCogUHJpbnQgYSBsaXRlcmFsIGNoYXIgaW4gYSBidWZmZXIsIGVzY2FwZSAnJScgYnkgXCIlJVwiLiAqKVxubGV0IGJwcmludF9jaGFyX2xpdGVyYWwgYnVmIGNociA9IG1hdGNoIGNociB3aXRoXG4gIHwgJyUnIC0+IGJ1ZmZlcl9hZGRfc3RyaW5nIGJ1ZiBcIiUlXCJcbiAgfCBfIC0+IGJ1ZmZlcl9hZGRfY2hhciBidWYgY2hyXG5cbigqIFByaW50IGEgbGl0ZXJhbCBzdHJpbmcgaW4gYSBidWZmZXIsIGVzY2FwZSBhbGwgJyUnIGJ5IFwiJSVcIi4gKilcbmxldCBicHJpbnRfc3RyaW5nX2xpdGVyYWwgYnVmIHN0ciA9XG4gIGZvciBpID0gMCB0byBTdHJpbmcubGVuZ3RoIHN0ciAtIDEgZG9cbiAgICBicHJpbnRfY2hhcl9saXRlcmFsIGJ1ZiBzdHIuW2ldXG4gIGRvbmVcblxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKCogRm9ybWF0IHByZXR0eS1wcmludGluZyAqKVxuXG4oKiBQcmludCBhIGNvbXBsZXRlIGZvcm1hdCB0eXBlIChhbiBmbXR0eSkgaW4gYSBidWZmZXIuICopXG5sZXQgcmVjIGJwcmludF9mbXR0eSA6IHR5cGUgYSBiIGMgZCBlIGYgZyBoIGkgaiBrIGwgLlxuICAgIGJ1ZmZlciAtPiAoYSwgYiwgYywgZCwgZSwgZiwgZywgaCwgaSwgaiwgaywgbCkgZm10dHlfcmVsIC0+IHVuaXQgPVxuZnVuIGJ1ZiBmbXR0eSAtPiBtYXRjaCBmbXR0eSB3aXRoXG4gIHwgQ2hhcl90eSByZXN0ICAgICAgLT4gYnVmZmVyX2FkZF9zdHJpbmcgYnVmIFwiJWNcIjsgIGJwcmludF9mbXR0eSBidWYgcmVzdDtcbiAgfCBTdHJpbmdfdHkgcmVzdCAgICAtPiBidWZmZXJfYWRkX3N0cmluZyBidWYgXCIlc1wiOyAgYnByaW50X2ZtdHR5IGJ1ZiByZXN0O1xuICB8IEludF90eSByZXN0ICAgICAgIC0+IGJ1ZmZlcl9hZGRfc3RyaW5nIGJ1ZiBcIiVpXCI7ICBicHJpbnRfZm10dHkgYnVmIHJlc3Q7XG4gIHwgSW50MzJfdHkgcmVzdCAgICAgLT4gYnVmZmVyX2FkZF9zdHJpbmcgYnVmIFwiJWxpXCI7IGJwcmludF9mbXR0eSBidWYgcmVzdDtcbiAgfCBOYXRpdmVpbnRfdHkgcmVzdCAtPiBidWZmZXJfYWRkX3N0cmluZyBidWYgXCIlbmlcIjsgYnByaW50X2ZtdHR5IGJ1ZiByZXN0O1xuICB8IEludDY0X3R5IHJlc3QgICAgIC0+IGJ1ZmZlcl9hZGRfc3RyaW5nIGJ1ZiBcIiVMaVwiOyBicHJpbnRfZm10dHkgYnVmIHJlc3Q7XG4gIHwgRmxvYXRfdHkgcmVzdCAgICAgLT4gYnVmZmVyX2FkZF9zdHJpbmcgYnVmIFwiJWZcIjsgIGJwcmludF9mbXR0eSBidWYgcmVzdDtcbiAgfCBCb29sX3R5IHJlc3QgICAgICAtPiBidWZmZXJfYWRkX3N0cmluZyBidWYgXCIlQlwiOyAgYnByaW50X2ZtdHR5IGJ1ZiByZXN0O1xuICB8IEFscGhhX3R5IHJlc3QgICAgIC0+IGJ1ZmZlcl9hZGRfc3RyaW5nIGJ1ZiBcIiVhXCI7ICBicHJpbnRfZm10dHkgYnVmIHJlc3Q7XG4gIHwgVGhldGFfdHkgcmVzdCAgICAgLT4gYnVmZmVyX2FkZF9zdHJpbmcgYnVmIFwiJXRcIjsgIGJwcmludF9mbXR0eSBidWYgcmVzdDtcbiAgfCBBbnlfdHkgcmVzdCAgICAgICAtPiBidWZmZXJfYWRkX3N0cmluZyBidWYgXCIlP1wiOyAgYnByaW50X2ZtdHR5IGJ1ZiByZXN0O1xuICB8IFJlYWRlcl90eSByZXN0ICAgIC0+IGJ1ZmZlcl9hZGRfc3RyaW5nIGJ1ZiBcIiVyXCI7ICBicHJpbnRfZm10dHkgYnVmIHJlc3Q7XG5cbiAgfCBJZ25vcmVkX3JlYWRlcl90eSByZXN0IC0+XG4gICAgYnVmZmVyX2FkZF9zdHJpbmcgYnVmIFwiJV9yXCI7XG4gICAgYnByaW50X2ZtdHR5IGJ1ZiByZXN0O1xuXG4gIHwgRm9ybWF0X2FyZ190eSAoc3ViX2ZtdHR5LCByZXN0KSAtPlxuICAgIGJ1ZmZlcl9hZGRfc3RyaW5nIGJ1ZiBcIiV7XCI7IGJwcmludF9mbXR0eSBidWYgc3ViX2ZtdHR5O1xuICAgIGJ1ZmZlcl9hZGRfc3RyaW5nIGJ1ZiBcIiV9XCI7IGJwcmludF9mbXR0eSBidWYgcmVzdDtcbiAgfCBGb3JtYXRfc3Vic3RfdHkgKHN1Yl9mbXR0eSwgXywgcmVzdCkgLT5cbiAgICBidWZmZXJfYWRkX3N0cmluZyBidWYgXCIlKFwiOyBicHJpbnRfZm10dHkgYnVmIHN1Yl9mbXR0eTtcbiAgICBidWZmZXJfYWRkX3N0cmluZyBidWYgXCIlKVwiOyBicHJpbnRfZm10dHkgYnVmIHJlc3Q7XG5cbiAgfCBFbmRfb2ZfZm10dHkgLT4gKClcblxuKCoqKilcblxubGV0IHJlYyBpbnRfb2ZfY3VzdG9tX2FyaXR5IDogdHlwZSBhIGIgYyAuXG4gIChhLCBiLCBjKSBjdXN0b21fYXJpdHkgLT4gaW50ID1cbiAgZnVuY3Rpb25cbiAgfCBDdXN0b21femVybyAtPiAwXG4gIHwgQ3VzdG9tX3N1Y2MgeCAtPiAxICsgaW50X29mX2N1c3RvbV9hcml0eSB4XG5cbigqIFByaW50IGEgY29tcGxldGUgZm9ybWF0IGluIGEgYnVmZmVyLiAqKVxubGV0IGJwcmludF9mbXQgYnVmIGZtdCA9XG4gIGxldCByZWMgZm10aXRlciA6IHR5cGUgYSBiIGMgZCBlIGYgLlxuICAgICAgKGEsIGIsIGMsIGQsIGUsIGYpIGZtdCAtPiBib29sIC0+IHVuaXQgPVxuICBmdW4gZm10IGlnbl9mbGFnIC0+IG1hdGNoIGZtdCB3aXRoXG4gICAgfCBTdHJpbmcgKHBhZCwgcmVzdCkgLT5cbiAgICAgIGJ1ZmZlcl9hZGRfY2hhciBidWYgJyUnOyBicHJpbnRfaWdub3JlZF9mbGFnIGJ1ZiBpZ25fZmxhZztcbiAgICAgIGJwcmludF9wYWRkaW5nIGJ1ZiBwYWQ7IGJ1ZmZlcl9hZGRfY2hhciBidWYgJ3MnO1xuICAgICAgZm10aXRlciByZXN0IGZhbHNlO1xuICAgIHwgQ2FtbF9zdHJpbmcgKHBhZCwgcmVzdCkgLT5cbiAgICAgIGJ1ZmZlcl9hZGRfY2hhciBidWYgJyUnOyBicHJpbnRfaWdub3JlZF9mbGFnIGJ1ZiBpZ25fZmxhZztcbiAgICAgIGJwcmludF9wYWRkaW5nIGJ1ZiBwYWQ7IGJ1ZmZlcl9hZGRfY2hhciBidWYgJ1MnO1xuICAgICAgZm10aXRlciByZXN0IGZhbHNlO1xuXG4gICAgfCBJbnQgKGljb252LCBwYWQsIHByZWMsIHJlc3QpIC0+XG4gICAgICBicHJpbnRfaW50X2ZtdCBidWYgaWduX2ZsYWcgaWNvbnYgcGFkIHByZWM7XG4gICAgICBmbXRpdGVyIHJlc3QgZmFsc2U7XG4gICAgfCBJbnQzMiAoaWNvbnYsIHBhZCwgcHJlYywgcmVzdCkgLT5cbiAgICAgIGJwcmludF9hbHRpbnRfZm10IGJ1ZiBpZ25fZmxhZyBpY29udiBwYWQgcHJlYyAnbCc7XG4gICAgICBmbXRpdGVyIHJlc3QgZmFsc2U7XG4gICAgfCBOYXRpdmVpbnQgKGljb252LCBwYWQsIHByZWMsIHJlc3QpIC0+XG4gICAgICBicHJpbnRfYWx0aW50X2ZtdCBidWYgaWduX2ZsYWcgaWNvbnYgcGFkIHByZWMgJ24nO1xuICAgICAgZm10aXRlciByZXN0IGZhbHNlO1xuICAgIHwgSW50NjQgKGljb252LCBwYWQsIHByZWMsIHJlc3QpIC0+XG4gICAgICBicHJpbnRfYWx0aW50X2ZtdCBidWYgaWduX2ZsYWcgaWNvbnYgcGFkIHByZWMgJ0wnO1xuICAgICAgZm10aXRlciByZXN0IGZhbHNlO1xuICAgIHwgRmxvYXQgKGZjb252LCBwYWQsIHByZWMsIHJlc3QpIC0+XG4gICAgICBicHJpbnRfZmxvYXRfZm10IGJ1ZiBpZ25fZmxhZyBmY29udiBwYWQgcHJlYztcbiAgICAgIGZtdGl0ZXIgcmVzdCBmYWxzZTtcblxuICAgIHwgQ2hhciByZXN0IC0+XG4gICAgICBidWZmZXJfYWRkX2NoYXIgYnVmICclJzsgYnByaW50X2lnbm9yZWRfZmxhZyBidWYgaWduX2ZsYWc7XG4gICAgICBidWZmZXJfYWRkX2NoYXIgYnVmICdjJzsgZm10aXRlciByZXN0IGZhbHNlO1xuICAgIHwgQ2FtbF9jaGFyIHJlc3QgLT5cbiAgICAgIGJ1ZmZlcl9hZGRfY2hhciBidWYgJyUnOyBicHJpbnRfaWdub3JlZF9mbGFnIGJ1ZiBpZ25fZmxhZztcbiAgICAgIGJ1ZmZlcl9hZGRfY2hhciBidWYgJ0MnOyBmbXRpdGVyIHJlc3QgZmFsc2U7XG4gICAgfCBCb29sIChwYWQsIHJlc3QpIC0+XG4gICAgICBidWZmZXJfYWRkX2NoYXIgYnVmICclJzsgYnByaW50X2lnbm9yZWRfZmxhZyBidWYgaWduX2ZsYWc7XG4gICAgICBicHJpbnRfcGFkZGluZyBidWYgcGFkOyBidWZmZXJfYWRkX2NoYXIgYnVmICdCJztcbiAgICAgIGZtdGl0ZXIgcmVzdCBmYWxzZTtcbiAgICB8IEFscGhhIHJlc3QgLT5cbiAgICAgIGJ1ZmZlcl9hZGRfY2hhciBidWYgJyUnOyBicHJpbnRfaWdub3JlZF9mbGFnIGJ1ZiBpZ25fZmxhZztcbiAgICAgIGJ1ZmZlcl9hZGRfY2hhciBidWYgJ2EnOyBmbXRpdGVyIHJlc3QgZmFsc2U7XG4gICAgfCBUaGV0YSByZXN0IC0+XG4gICAgICBidWZmZXJfYWRkX2NoYXIgYnVmICclJzsgYnByaW50X2lnbm9yZWRfZmxhZyBidWYgaWduX2ZsYWc7XG4gICAgICBidWZmZXJfYWRkX2NoYXIgYnVmICd0JzsgZm10aXRlciByZXN0IGZhbHNlO1xuICAgIHwgQ3VzdG9tIChhcml0eSwgXywgcmVzdCkgLT5cbiAgICAgIGZvciBfaSA9IDEgdG8gaW50X29mX2N1c3RvbV9hcml0eSBhcml0eSBkb1xuICAgICAgICBidWZmZXJfYWRkX2NoYXIgYnVmICclJzsgYnByaW50X2lnbm9yZWRfZmxhZyBidWYgaWduX2ZsYWc7XG4gICAgICAgIGJ1ZmZlcl9hZGRfY2hhciBidWYgJz8nO1xuICAgICAgZG9uZTtcbiAgICAgIGZtdGl0ZXIgcmVzdCBmYWxzZTtcbiAgICB8IFJlYWRlciByZXN0IC0+XG4gICAgICBidWZmZXJfYWRkX2NoYXIgYnVmICclJzsgYnByaW50X2lnbm9yZWRfZmxhZyBidWYgaWduX2ZsYWc7XG4gICAgICBidWZmZXJfYWRkX2NoYXIgYnVmICdyJzsgZm10aXRlciByZXN0IGZhbHNlO1xuICAgIHwgRmx1c2ggcmVzdCAtPlxuICAgICAgYnVmZmVyX2FkZF9zdHJpbmcgYnVmIFwiJSFcIjtcbiAgICAgIGZtdGl0ZXIgcmVzdCBpZ25fZmxhZztcblxuICAgIHwgU3RyaW5nX2xpdGVyYWwgKHN0ciwgcmVzdCkgLT5cbiAgICAgIGJwcmludF9zdHJpbmdfbGl0ZXJhbCBidWYgc3RyO1xuICAgICAgZm10aXRlciByZXN0IGlnbl9mbGFnO1xuICAgIHwgQ2hhcl9saXRlcmFsIChjaHIsIHJlc3QpIC0+XG4gICAgICBicHJpbnRfY2hhcl9saXRlcmFsIGJ1ZiBjaHI7XG4gICAgICBmbXRpdGVyIHJlc3QgaWduX2ZsYWc7XG5cbiAgICB8IEZvcm1hdF9hcmcgKHBhZF9vcHQsIGZtdHR5LCByZXN0KSAtPlxuICAgICAgYnVmZmVyX2FkZF9jaGFyIGJ1ZiAnJSc7IGJwcmludF9pZ25vcmVkX2ZsYWcgYnVmIGlnbl9mbGFnO1xuICAgICAgYnByaW50X3BhZF9vcHQgYnVmIHBhZF9vcHQ7IGJ1ZmZlcl9hZGRfY2hhciBidWYgJ3snO1xuICAgICAgYnByaW50X2ZtdHR5IGJ1ZiBmbXR0eTsgYnVmZmVyX2FkZF9jaGFyIGJ1ZiAnJSc7IGJ1ZmZlcl9hZGRfY2hhciBidWYgJ30nO1xuICAgICAgZm10aXRlciByZXN0IGZhbHNlO1xuICAgIHwgRm9ybWF0X3N1YnN0IChwYWRfb3B0LCBmbXR0eSwgcmVzdCkgLT5cbiAgICAgIGJ1ZmZlcl9hZGRfY2hhciBidWYgJyUnOyBicHJpbnRfaWdub3JlZF9mbGFnIGJ1ZiBpZ25fZmxhZztcbiAgICAgIGJwcmludF9wYWRfb3B0IGJ1ZiBwYWRfb3B0OyBidWZmZXJfYWRkX2NoYXIgYnVmICcoJztcbiAgICAgIGJwcmludF9mbXR0eSBidWYgZm10dHk7IGJ1ZmZlcl9hZGRfY2hhciBidWYgJyUnOyBidWZmZXJfYWRkX2NoYXIgYnVmICcpJztcbiAgICAgIGZtdGl0ZXIgcmVzdCBmYWxzZTtcblxuICAgIHwgU2Nhbl9jaGFyX3NldCAod2lkdGhfb3B0LCBjaGFyX3NldCwgcmVzdCkgLT5cbiAgICAgIGJ1ZmZlcl9hZGRfY2hhciBidWYgJyUnOyBicHJpbnRfaWdub3JlZF9mbGFnIGJ1ZiBpZ25fZmxhZztcbiAgICAgIGJwcmludF9wYWRfb3B0IGJ1ZiB3aWR0aF9vcHQ7IGJwcmludF9jaGFyX3NldCBidWYgY2hhcl9zZXQ7XG4gICAgICBmbXRpdGVyIHJlc3QgZmFsc2U7XG4gICAgfCBTY2FuX2dldF9jb3VudGVyIChjb3VudGVyLCByZXN0KSAtPlxuICAgICAgYnVmZmVyX2FkZF9jaGFyIGJ1ZiAnJSc7IGJwcmludF9pZ25vcmVkX2ZsYWcgYnVmIGlnbl9mbGFnO1xuICAgICAgYnVmZmVyX2FkZF9jaGFyIGJ1ZiAoY2hhcl9vZl9jb3VudGVyIGNvdW50ZXIpO1xuICAgICAgZm10aXRlciByZXN0IGZhbHNlO1xuICAgIHwgU2Nhbl9uZXh0X2NoYXIgcmVzdCAtPlxuICAgICAgYnVmZmVyX2FkZF9jaGFyIGJ1ZiAnJSc7IGJwcmludF9pZ25vcmVkX2ZsYWcgYnVmIGlnbl9mbGFnO1xuICAgICAgYnByaW50X3N0cmluZ19saXRlcmFsIGJ1ZiBcIjBjXCI7IGZtdGl0ZXIgcmVzdCBmYWxzZTtcblxuICAgIHwgSWdub3JlZF9wYXJhbSAoaWduLCByZXN0KSAtPlxuICAgICAgbGV0IFBhcmFtX2Zvcm1hdF9FQkIgZm10JyA9IHBhcmFtX2Zvcm1hdF9vZl9pZ25vcmVkX2Zvcm1hdCBpZ24gcmVzdCBpblxuICAgICAgZm10aXRlciBmbXQnIHRydWU7XG5cbiAgICB8IEZvcm1hdHRpbmdfbGl0IChmbXRpbmdfbGl0LCByZXN0KSAtPlxuICAgICAgYnByaW50X3N0cmluZ19saXRlcmFsIGJ1ZiAoc3RyaW5nX29mX2Zvcm1hdHRpbmdfbGl0IGZtdGluZ19saXQpO1xuICAgICAgZm10aXRlciByZXN0IGlnbl9mbGFnO1xuICAgIHwgRm9ybWF0dGluZ19nZW4gKGZtdGluZ19nZW4sIHJlc3QpIC0+XG4gICAgICBiZWdpbiBtYXRjaCBmbXRpbmdfZ2VuIHdpdGhcbiAgICAgIHwgT3Blbl90YWcgKEZvcm1hdCAoXywgc3RyKSkgLT5cbiAgICAgICAgYnVmZmVyX2FkZF9zdHJpbmcgYnVmIFwiQHtcIjsgYnVmZmVyX2FkZF9zdHJpbmcgYnVmIHN0clxuICAgICAgfCBPcGVuX2JveCAoRm9ybWF0IChfLCBzdHIpKSAtPlxuICAgICAgICBidWZmZXJfYWRkX3N0cmluZyBidWYgXCJAW1wiOyBidWZmZXJfYWRkX3N0cmluZyBidWYgc3RyXG4gICAgICBlbmQ7XG4gICAgICBmbXRpdGVyIHJlc3QgaWduX2ZsYWc7XG5cbiAgICB8IEVuZF9vZl9mb3JtYXQgLT4gKClcblxuICBpbiBmbXRpdGVyIGZtdCBmYWxzZVxuXG4oKioqKVxuXG4oKiBDb252ZXJ0IGEgZm9ybWF0IHRvIHN0cmluZy4gKilcbmxldCBzdHJpbmdfb2ZfZm10IGZtdCA9XG4gIGxldCBidWYgPSBidWZmZXJfY3JlYXRlIDE2IGluXG4gIGJwcmludF9mbXQgYnVmIGZtdDtcbiAgYnVmZmVyX2NvbnRlbnRzIGJ1ZlxuXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAoKiBUeXBlIGV4dHJhY3Rpb24gKilcblxudHlwZSAoXywgXykgZXEgPSBSZWZsIDogKCdhLCAnYSkgZXFcblxuKCogSW52YXJpYW50OiB0aGlzIGZ1bmN0aW9uIGlzIHRoZSBpZGVudGl0eSBvbiB2YWx1ZXMuXG5cbiAgIEluIHBhcnRpY3VsYXIsIGlmICh0eTEsIHR5MikgaGF2ZSBlcXVhbCB2YWx1ZXMsIHRoZW5cbiAgICh0cmFucyAoc3ltbSB0eTEpIHR5MikgcmVzcGVjdHMgdGhlICd0cmFucycgcHJlY29uZGl0aW9uLiAqKVxubGV0IHJlYyBzeW1tIDogdHlwZSBhMSBiMSBjMSBkMSBlMSBmMSBhMiBiMiBjMiBkMiBlMiBmMiAuXG4gICAoYTEsIGIxLCBjMSwgZDEsIGUxLCBmMSxcbiAgICBhMiwgYjIsIGMyLCBkMiwgZTIsIGYyKSBmbXR0eV9yZWxcbi0+IChhMiwgYjIsIGMyLCBkMiwgZTIsIGYyLFxuICAgIGExLCBiMSwgYzEsIGQxLCBlMSwgZjEpIGZtdHR5X3JlbFxuPSBmdW5jdGlvblxuICB8IENoYXJfdHkgcmVzdCAtPiBDaGFyX3R5IChzeW1tIHJlc3QpXG4gIHwgSW50X3R5IHJlc3QgLT4gSW50X3R5IChzeW1tIHJlc3QpXG4gIHwgSW50MzJfdHkgcmVzdCAtPiBJbnQzMl90eSAoc3ltbSByZXN0KVxuICB8IEludDY0X3R5IHJlc3QgLT4gSW50NjRfdHkgKHN5bW0gcmVzdClcbiAgfCBOYXRpdmVpbnRfdHkgcmVzdCAtPiBOYXRpdmVpbnRfdHkgKHN5bW0gcmVzdClcbiAgfCBGbG9hdF90eSByZXN0IC0+IEZsb2F0X3R5IChzeW1tIHJlc3QpXG4gIHwgQm9vbF90eSByZXN0IC0+IEJvb2xfdHkgKHN5bW0gcmVzdClcbiAgfCBTdHJpbmdfdHkgcmVzdCAtPiBTdHJpbmdfdHkgKHN5bW0gcmVzdClcbiAgfCBUaGV0YV90eSByZXN0IC0+IFRoZXRhX3R5IChzeW1tIHJlc3QpXG4gIHwgQWxwaGFfdHkgcmVzdCAtPiBBbHBoYV90eSAoc3ltbSByZXN0KVxuICB8IEFueV90eSByZXN0IC0+IEFueV90eSAoc3ltbSByZXN0KVxuICB8IFJlYWRlcl90eSByZXN0IC0+IFJlYWRlcl90eSAoc3ltbSByZXN0KVxuICB8IElnbm9yZWRfcmVhZGVyX3R5IHJlc3QgLT4gSWdub3JlZF9yZWFkZXJfdHkgKHN5bW0gcmVzdClcbiAgfCBGb3JtYXRfYXJnX3R5ICh0eSwgcmVzdCkgLT5cbiAgICBGb3JtYXRfYXJnX3R5ICh0eSwgc3ltbSByZXN0KVxuICB8IEZvcm1hdF9zdWJzdF90eSAodHkxLCB0eTIsIHJlc3QpIC0+XG4gICAgRm9ybWF0X3N1YnN0X3R5ICh0eTIsIHR5MSwgc3ltbSByZXN0KVxuICB8IEVuZF9vZl9mbXR0eSAtPiBFbmRfb2ZfZm10dHlcblxubGV0IHJlYyBmbXR0eV9yZWxfZGV0IDogdHlwZSBhMSBiIGMgZDEgZTEgZjEgYTIgZDIgZTIgZjIgLlxuICAoYTEsIGIsIGMsIGQxLCBlMSwgZjEsXG4gICBhMiwgYiwgYywgZDIsIGUyLCBmMikgZm10dHlfcmVsIC0+XG4gICAgKChmMSwgZjIpIGVxIC0+IChhMSwgYTIpIGVxKVxuICAqICgoYTEsIGEyKSBlcSAtPiAoZjEsIGYyKSBlcSlcbiAgKiAoKGUxLCBlMikgZXEgLT4gKGQxLCBkMikgZXEpXG4gICogKChkMSwgZDIpIGVxIC0+IChlMSwgZTIpIGVxKVxuPSBmdW5jdGlvblxuICB8IEVuZF9vZl9mbXR0eSAtPlxuICAgIChmdW4gUmVmbCAtPiBSZWZsKSxcbiAgICAoZnVuIFJlZmwgLT4gUmVmbCksXG4gICAgKGZ1biBSZWZsIC0+IFJlZmwpLFxuICAgIChmdW4gUmVmbCAtPiBSZWZsKVxuICB8IENoYXJfdHkgcmVzdCAtPlxuICAgIGxldCBmYSwgYWYsIGVkLCBkZSA9IGZtdHR5X3JlbF9kZXQgcmVzdCBpblxuICAgIChmdW4gUmVmbCAtPiBsZXQgUmVmbCA9IGZhIFJlZmwgaW4gUmVmbCksXG4gICAgKGZ1biBSZWZsIC0+IGxldCBSZWZsID0gYWYgUmVmbCBpbiBSZWZsKSxcbiAgICBlZCwgZGVcbiAgfCBTdHJpbmdfdHkgcmVzdCAtPlxuICAgIGxldCBmYSwgYWYsIGVkLCBkZSA9IGZtdHR5X3JlbF9kZXQgcmVzdCBpblxuICAgIChmdW4gUmVmbCAtPiBsZXQgUmVmbCA9IGZhIFJlZmwgaW4gUmVmbCksXG4gICAgKGZ1biBSZWZsIC0+IGxldCBSZWZsID0gYWYgUmVmbCBpbiBSZWZsKSxcbiAgICBlZCwgZGVcbiAgfCBJbnRfdHkgcmVzdCAtPlxuICAgIGxldCBmYSwgYWYsIGVkLCBkZSA9IGZtdHR5X3JlbF9kZXQgcmVzdCBpblxuICAgIChmdW4gUmVmbCAtPiBsZXQgUmVmbCA9IGZhIFJlZmwgaW4gUmVmbCksXG4gICAgKGZ1biBSZWZsIC0+IGxldCBSZWZsID0gYWYgUmVmbCBpbiBSZWZsKSxcbiAgICBlZCwgZGVcbiAgfCBJbnQzMl90eSByZXN0IC0+XG4gICAgbGV0IGZhLCBhZiwgZWQsIGRlID0gZm10dHlfcmVsX2RldCByZXN0IGluXG4gICAgKGZ1biBSZWZsIC0+IGxldCBSZWZsID0gZmEgUmVmbCBpbiBSZWZsKSxcbiAgICAoZnVuIFJlZmwgLT4gbGV0IFJlZmwgPSBhZiBSZWZsIGluIFJlZmwpLFxuICAgIGVkLCBkZVxuICB8IEludDY0X3R5IHJlc3QgLT5cbiAgICBsZXQgZmEsIGFmLCBlZCwgZGUgPSBmbXR0eV9yZWxfZGV0IHJlc3QgaW5cbiAgICAoZnVuIFJlZmwgLT4gbGV0IFJlZmwgPSBmYSBSZWZsIGluIFJlZmwpLFxuICAgIChmdW4gUmVmbCAtPiBsZXQgUmVmbCA9IGFmIFJlZmwgaW4gUmVmbCksXG4gICAgZWQsIGRlXG4gIHwgTmF0aXZlaW50X3R5IHJlc3QgLT5cbiAgICBsZXQgZmEsIGFmLCBlZCwgZGUgPSBmbXR0eV9yZWxfZGV0IHJlc3QgaW5cbiAgICAoZnVuIFJlZmwgLT4gbGV0IFJlZmwgPSBmYSBSZWZsIGluIFJlZmwpLFxuICAgIChmdW4gUmVmbCAtPiBsZXQgUmVmbCA9IGFmIFJlZmwgaW4gUmVmbCksXG4gICAgZWQsIGRlXG4gIHwgRmxvYXRfdHkgcmVzdCAtPlxuICAgIGxldCBmYSwgYWYsIGVkLCBkZSA9IGZtdHR5X3JlbF9kZXQgcmVzdCBpblxuICAgIChmdW4gUmVmbCAtPiBsZXQgUmVmbCA9IGZhIFJlZmwgaW4gUmVmbCksXG4gICAgKGZ1biBSZWZsIC0+IGxldCBSZWZsID0gYWYgUmVmbCBpbiBSZWZsKSxcbiAgICBlZCwgZGVcbiAgfCBCb29sX3R5IHJlc3QgLT5cbiAgICBsZXQgZmEsIGFmLCBlZCwgZGUgPSBmbXR0eV9yZWxfZGV0IHJlc3QgaW5cbiAgICAoZnVuIFJlZmwgLT4gbGV0IFJlZmwgPSBmYSBSZWZsIGluIFJlZmwpLFxuICAgIChmdW4gUmVmbCAtPiBsZXQgUmVmbCA9IGFmIFJlZmwgaW4gUmVmbCksXG4gICAgZWQsIGRlXG5cbiAgfCBUaGV0YV90eSByZXN0IC0+XG4gICAgbGV0IGZhLCBhZiwgZWQsIGRlID0gZm10dHlfcmVsX2RldCByZXN0IGluXG4gICAgKGZ1biBSZWZsIC0+IGxldCBSZWZsID0gZmEgUmVmbCBpbiBSZWZsKSxcbiAgICAoZnVuIFJlZmwgLT4gbGV0IFJlZmwgPSBhZiBSZWZsIGluIFJlZmwpLFxuICAgIGVkLCBkZVxuICB8IEFscGhhX3R5IHJlc3QgLT5cbiAgICBsZXQgZmEsIGFmLCBlZCwgZGUgPSBmbXR0eV9yZWxfZGV0IHJlc3QgaW5cbiAgICAoZnVuIFJlZmwgLT4gbGV0IFJlZmwgPSBmYSBSZWZsIGluIFJlZmwpLFxuICAgIChmdW4gUmVmbCAtPiBsZXQgUmVmbCA9IGFmIFJlZmwgaW4gUmVmbCksXG4gICAgZWQsIGRlXG4gIHwgQW55X3R5IHJlc3QgLT5cbiAgICBsZXQgZmEsIGFmLCBlZCwgZGUgPSBmbXR0eV9yZWxfZGV0IHJlc3QgaW5cbiAgICAoZnVuIFJlZmwgLT4gbGV0IFJlZmwgPSBmYSBSZWZsIGluIFJlZmwpLFxuICAgIChmdW4gUmVmbCAtPiBsZXQgUmVmbCA9IGFmIFJlZmwgaW4gUmVmbCksXG4gICAgZWQsIGRlXG4gIHwgUmVhZGVyX3R5IHJlc3QgLT5cbiAgICBsZXQgZmEsIGFmLCBlZCwgZGUgPSBmbXR0eV9yZWxfZGV0IHJlc3QgaW5cbiAgICAoZnVuIFJlZmwgLT4gbGV0IFJlZmwgPSBmYSBSZWZsIGluIFJlZmwpLFxuICAgIChmdW4gUmVmbCAtPiBsZXQgUmVmbCA9IGFmIFJlZmwgaW4gUmVmbCksXG4gICAgKGZ1biBSZWZsIC0+IGxldCBSZWZsID0gZWQgUmVmbCBpbiBSZWZsKSxcbiAgICAoZnVuIFJlZmwgLT4gbGV0IFJlZmwgPSBkZSBSZWZsIGluIFJlZmwpXG4gIHwgSWdub3JlZF9yZWFkZXJfdHkgcmVzdCAtPlxuICAgIGxldCBmYSwgYWYsIGVkLCBkZSA9IGZtdHR5X3JlbF9kZXQgcmVzdCBpblxuICAgIChmdW4gUmVmbCAtPiBsZXQgUmVmbCA9IGZhIFJlZmwgaW4gUmVmbCksXG4gICAgKGZ1biBSZWZsIC0+IGxldCBSZWZsID0gYWYgUmVmbCBpbiBSZWZsKSxcbiAgICAoZnVuIFJlZmwgLT4gbGV0IFJlZmwgPSBlZCBSZWZsIGluIFJlZmwpLFxuICAgIChmdW4gUmVmbCAtPiBsZXQgUmVmbCA9IGRlIFJlZmwgaW4gUmVmbClcbiAgfCBGb3JtYXRfYXJnX3R5IChfdHksIHJlc3QpIC0+XG4gICAgbGV0IGZhLCBhZiwgZWQsIGRlID0gZm10dHlfcmVsX2RldCByZXN0IGluXG4gICAgKGZ1biBSZWZsIC0+IGxldCBSZWZsID0gZmEgUmVmbCBpbiBSZWZsKSxcbiAgICAoZnVuIFJlZmwgLT4gbGV0IFJlZmwgPSBhZiBSZWZsIGluIFJlZmwpLFxuICAgIGVkLCBkZVxuICB8IEZvcm1hdF9zdWJzdF90eSAodHkxLCB0eTIsIHJlc3QpIC0+XG4gICAgbGV0IGZhLCBhZiwgZWQsIGRlID0gZm10dHlfcmVsX2RldCByZXN0IGluXG4gICAgbGV0IHR5ID0gdHJhbnMgKHN5bW0gdHkxKSB0eTIgaW5cbiAgICBsZXQgYWcsIGdhLCBkaiwgamQgPSBmbXR0eV9yZWxfZGV0IHR5IGluXG4gICAgKGZ1biBSZWZsIC0+IGxldCBSZWZsID0gZmEgUmVmbCBpbiBsZXQgUmVmbCA9IGFnIFJlZmwgaW4gUmVmbCksXG4gICAgKGZ1biBSZWZsIC0+IGxldCBSZWZsID0gZ2EgUmVmbCBpbiBsZXQgUmVmbCA9IGFmIFJlZmwgaW4gUmVmbCksXG4gICAgKGZ1biBSZWZsIC0+IGxldCBSZWZsID0gZWQgUmVmbCBpbiBsZXQgUmVmbCA9IGRqIFJlZmwgaW4gUmVmbCksXG4gICAgKGZ1biBSZWZsIC0+IGxldCBSZWZsID0gamQgUmVmbCBpbiBsZXQgUmVmbCA9IGRlIFJlZmwgaW4gUmVmbClcblxuKCogUHJlY29uZGl0aW9uOiB3ZSBhc3N1bWUgdGhhdCB0aGUgdHdvIGZtdHR5X3JlbCBhcmd1bWVudHMgaGF2ZSBlcXVhbFxuICAgdmFsdWVzIChhdCBwb3NzaWJseSBkaXN0aW5jdCB0eXBlcyk7IHRoaXMgaW52YXJpYW50IGNvbWVzIGZyb20gdGhlIHdheVxuICAgZm10dHlfcmVsIHdpdG5lc3NlcyBhcmUgcHJvZHVjZWQgYnkgdGhlIHR5cGUtY2hlY2tlclxuXG4gICBUaGUgY29kZSBiZWxvdyB1c2VzIChhc3NlcnQgZmFsc2UpIHdoZW4gdGhpcyBhc3N1bXB0aW9uIGlzIGJyb2tlbi4gVGhlXG4gICBjb2RlIHBhdHRlcm4gaXMgdGhlIGZvbGxvd2luZzpcblxuICAgICB8IEZvbyB4LCBGb28geSAtPlxuICAgICAgICgqIGNhc2Ugd2hlcmUgaW5kZWVkIGJvdGggdmFsdWVzXG4gICAgICAgICAgc3RhcnQgd2l0aCBjb25zdHJ1Y3RvciBGb28gKilcbiAgICAgfCBGb28gXywgX1xuICAgICB8IF8sIEZvbyBfIC0+XG4gICAgICAgKCogZGlmZmVyZW50IGhlYWQgY29uc3RydWN0b3JzOiBicm9rZW4gcHJlY29uZGl0aW9uICopXG4gICAgICAgYXNzZXJ0IGZhbHNlXG4qKVxuYW5kIHRyYW5zIDogdHlwZVxuICBhMSBiMSBjMSBkMSBlMSBmMVxuICBhMiBiMiBjMiBkMiBlMiBmMlxuICBhMyBiMyBjMyBkMyBlMyBmM1xuLlxuICAgKGExLCBiMSwgYzEsIGQxLCBlMSwgZjEsXG4gICAgYTIsIGIyLCBjMiwgZDIsIGUyLCBmMikgZm10dHlfcmVsXG4tPiAoYTIsIGIyLCBjMiwgZDIsIGUyLCBmMixcbiAgICBhMywgYjMsIGMzLCBkMywgZTMsIGYzKSBmbXR0eV9yZWxcbi0+IChhMSwgYjEsIGMxLCBkMSwgZTEsIGYxLFxuICAgIGEzLCBiMywgYzMsIGQzLCBlMywgZjMpIGZtdHR5X3JlbFxuPSBmdW4gdHkxIHR5MiAtPiBtYXRjaCB0eTEsIHR5MiB3aXRoXG4gIHwgQ2hhcl90eSByZXN0MSwgQ2hhcl90eSByZXN0MiAtPiBDaGFyX3R5ICh0cmFucyByZXN0MSByZXN0MilcbiAgfCBTdHJpbmdfdHkgcmVzdDEsIFN0cmluZ190eSByZXN0MiAtPiBTdHJpbmdfdHkgKHRyYW5zIHJlc3QxIHJlc3QyKVxuICB8IEJvb2xfdHkgcmVzdDEsIEJvb2xfdHkgcmVzdDIgLT4gQm9vbF90eSAodHJhbnMgcmVzdDEgcmVzdDIpXG4gIHwgSW50X3R5IHJlc3QxLCBJbnRfdHkgcmVzdDIgLT4gSW50X3R5ICh0cmFucyByZXN0MSByZXN0MilcbiAgfCBJbnQzMl90eSByZXN0MSwgSW50MzJfdHkgcmVzdDIgLT4gSW50MzJfdHkgKHRyYW5zIHJlc3QxIHJlc3QyKVxuICB8IEludDY0X3R5IHJlc3QxLCBJbnQ2NF90eSByZXN0MiAtPiBJbnQ2NF90eSAodHJhbnMgcmVzdDEgcmVzdDIpXG4gIHwgTmF0aXZlaW50X3R5IHJlc3QxLCBOYXRpdmVpbnRfdHkgcmVzdDIgLT4gTmF0aXZlaW50X3R5ICh0cmFucyByZXN0MSByZXN0MilcbiAgfCBGbG9hdF90eSByZXN0MSwgRmxvYXRfdHkgcmVzdDIgLT4gRmxvYXRfdHkgKHRyYW5zIHJlc3QxIHJlc3QyKVxuXG4gIHwgQWxwaGFfdHkgcmVzdDEsIEFscGhhX3R5IHJlc3QyIC0+IEFscGhhX3R5ICh0cmFucyByZXN0MSByZXN0MilcbiAgfCBBbHBoYV90eSBfLCBfIC0+IGFzc2VydCBmYWxzZVxuICB8IF8sIEFscGhhX3R5IF8gLT4gYXNzZXJ0IGZhbHNlXG5cbiAgfCBUaGV0YV90eSByZXN0MSwgVGhldGFfdHkgcmVzdDIgLT4gVGhldGFfdHkgKHRyYW5zIHJlc3QxIHJlc3QyKVxuICB8IFRoZXRhX3R5IF8sIF8gLT4gYXNzZXJ0IGZhbHNlXG4gIHwgXywgVGhldGFfdHkgXyAtPiBhc3NlcnQgZmFsc2VcblxuICB8IEFueV90eSByZXN0MSwgQW55X3R5IHJlc3QyIC0+IEFueV90eSAodHJhbnMgcmVzdDEgcmVzdDIpXG4gIHwgQW55X3R5IF8sIF8gLT4gYXNzZXJ0IGZhbHNlXG4gIHwgXywgQW55X3R5IF8gLT4gYXNzZXJ0IGZhbHNlXG5cbiAgfCBSZWFkZXJfdHkgcmVzdDEsIFJlYWRlcl90eSByZXN0MiAtPiBSZWFkZXJfdHkgKHRyYW5zIHJlc3QxIHJlc3QyKVxuICB8IFJlYWRlcl90eSBfLCBfIC0+IGFzc2VydCBmYWxzZVxuICB8IF8sIFJlYWRlcl90eSBfIC0+IGFzc2VydCBmYWxzZVxuXG4gIHwgSWdub3JlZF9yZWFkZXJfdHkgcmVzdDEsIElnbm9yZWRfcmVhZGVyX3R5IHJlc3QyIC0+XG4gICAgSWdub3JlZF9yZWFkZXJfdHkgKHRyYW5zIHJlc3QxIHJlc3QyKVxuICB8IElnbm9yZWRfcmVhZGVyX3R5IF8sIF8gLT4gYXNzZXJ0IGZhbHNlXG4gIHwgXywgSWdub3JlZF9yZWFkZXJfdHkgXyAtPiBhc3NlcnQgZmFsc2VcblxuICB8IEZvcm1hdF9hcmdfdHkgKHR5MSwgcmVzdDEpLCBGb3JtYXRfYXJnX3R5ICh0eTIsIHJlc3QyKSAtPlxuICAgIEZvcm1hdF9hcmdfdHkgKHRyYW5zIHR5MSB0eTIsIHRyYW5zIHJlc3QxIHJlc3QyKVxuICB8IEZvcm1hdF9hcmdfdHkgXywgXyAtPiBhc3NlcnQgZmFsc2VcbiAgfCBfLCBGb3JtYXRfYXJnX3R5IF8gLT4gYXNzZXJ0IGZhbHNlXG5cbiAgfCBGb3JtYXRfc3Vic3RfdHkgKHR5MTEsIHR5MTIsIHJlc3QxKSxcbiAgICBGb3JtYXRfc3Vic3RfdHkgKHR5MjEsIHR5MjIsIHJlc3QyKSAtPlxuICAgIGxldCB0eSA9IHRyYW5zIChzeW1tIHR5MTIpIHR5MjEgaW5cbiAgICBsZXQgXywgZjIsIF8sIGY0ID0gZm10dHlfcmVsX2RldCB0eSBpblxuICAgIGxldCBSZWZsID0gZjIgUmVmbCBpblxuICAgIGxldCBSZWZsID0gZjQgUmVmbCBpblxuICAgIEZvcm1hdF9zdWJzdF90eSAodHkxMSwgdHkyMiwgdHJhbnMgcmVzdDEgcmVzdDIpXG4gIHwgRm9ybWF0X3N1YnN0X3R5IF8sIF8gLT4gYXNzZXJ0IGZhbHNlXG4gIHwgXywgRm9ybWF0X3N1YnN0X3R5IF8gLT4gYXNzZXJ0IGZhbHNlXG5cbiAgfCBFbmRfb2ZfZm10dHksIEVuZF9vZl9mbXR0eSAtPiBFbmRfb2ZfZm10dHlcbiAgfCBFbmRfb2ZfZm10dHksIF8gLT4gYXNzZXJ0IGZhbHNlXG4gIHwgXywgRW5kX29mX2ZtdHR5IC0+IGFzc2VydCBmYWxzZVxuXG5sZXQgcmVjIGZtdHR5X29mX2Zvcm1hdHRpbmdfZ2VuIDogdHlwZSBhIGIgYyBkIGUgZiAuXG4gIChhLCBiLCBjLCBkLCBlLCBmKSBmb3JtYXR0aW5nX2dlbiAtPlxuICAgIChhLCBiLCBjLCBkLCBlLCBmKSBmbXR0eSA9XG5mdW4gZm9ybWF0dGluZ19nZW4gLT4gbWF0Y2ggZm9ybWF0dGluZ19nZW4gd2l0aFxuICB8IE9wZW5fdGFnIChGb3JtYXQgKGZtdCwgXykpIC0+IGZtdHR5X29mX2ZtdCBmbXRcbiAgfCBPcGVuX2JveCAoRm9ybWF0IChmbXQsIF8pKSAtPiBmbXR0eV9vZl9mbXQgZm10XG5cbigqIEV4dHJhY3QgdGhlIHR5cGUgcmVwcmVzZW50YXRpb24gKGFuIGZtdHR5KSBvZiBhIGZvcm1hdC4gKilcbmFuZCBmbXR0eV9vZl9mbXQgOiB0eXBlIGEgYiBjIGQgZSBmIC5cbiAgKGEsIGIsIGMsIGQsIGUsIGYpIGZtdCAtPiAoYSwgYiwgYywgZCwgZSwgZikgZm10dHkgPVxuZnVuIGZtdHR5IC0+IG1hdGNoIGZtdHR5IHdpdGhcbiAgfCBTdHJpbmcgKHBhZCwgcmVzdCkgLT5cbiAgICBmbXR0eV9vZl9wYWRkaW5nX2ZtdHR5IHBhZCAoU3RyaW5nX3R5IChmbXR0eV9vZl9mbXQgcmVzdCkpXG4gIHwgQ2FtbF9zdHJpbmcgKHBhZCwgcmVzdCkgLT5cbiAgICBmbXR0eV9vZl9wYWRkaW5nX2ZtdHR5IHBhZCAoU3RyaW5nX3R5IChmbXR0eV9vZl9mbXQgcmVzdCkpXG5cbiAgfCBJbnQgKF8sIHBhZCwgcHJlYywgcmVzdCkgLT5cbiAgICBsZXQgdHlfcmVzdCA9IGZtdHR5X29mX2ZtdCByZXN0IGluXG4gICAgbGV0IHByZWNfdHkgPSBmbXR0eV9vZl9wcmVjaXNpb25fZm10dHkgcHJlYyAoSW50X3R5IHR5X3Jlc3QpIGluXG4gICAgZm10dHlfb2ZfcGFkZGluZ19mbXR0eSBwYWQgcHJlY190eVxuICB8IEludDMyIChfLCBwYWQsIHByZWMsIHJlc3QpIC0+XG4gICAgbGV0IHR5X3Jlc3QgPSBmbXR0eV9vZl9mbXQgcmVzdCBpblxuICAgIGxldCBwcmVjX3R5ID0gZm10dHlfb2ZfcHJlY2lzaW9uX2ZtdHR5IHByZWMgKEludDMyX3R5IHR5X3Jlc3QpIGluXG4gICAgZm10dHlfb2ZfcGFkZGluZ19mbXR0eSBwYWQgcHJlY190eVxuICB8IE5hdGl2ZWludCAoXywgcGFkLCBwcmVjLCByZXN0KSAtPlxuICAgIGxldCB0eV9yZXN0ID0gZm10dHlfb2ZfZm10IHJlc3QgaW5cbiAgICBsZXQgcHJlY190eSA9IGZtdHR5X29mX3ByZWNpc2lvbl9mbXR0eSBwcmVjIChOYXRpdmVpbnRfdHkgdHlfcmVzdCkgaW5cbiAgICBmbXR0eV9vZl9wYWRkaW5nX2ZtdHR5IHBhZCBwcmVjX3R5XG4gIHwgSW50NjQgKF8sIHBhZCwgcHJlYywgcmVzdCkgLT5cbiAgICBsZXQgdHlfcmVzdCA9IGZtdHR5X29mX2ZtdCByZXN0IGluXG4gICAgbGV0IHByZWNfdHkgPSBmbXR0eV9vZl9wcmVjaXNpb25fZm10dHkgcHJlYyAoSW50NjRfdHkgdHlfcmVzdCkgaW5cbiAgICBmbXR0eV9vZl9wYWRkaW5nX2ZtdHR5IHBhZCBwcmVjX3R5XG4gIHwgRmxvYXQgKF8sIHBhZCwgcHJlYywgcmVzdCkgLT5cbiAgICBsZXQgdHlfcmVzdCA9IGZtdHR5X29mX2ZtdCByZXN0IGluXG4gICAgbGV0IHByZWNfdHkgPSBmbXR0eV9vZl9wcmVjaXNpb25fZm10dHkgcHJlYyAoRmxvYXRfdHkgdHlfcmVzdCkgaW5cbiAgICBmbXR0eV9vZl9wYWRkaW5nX2ZtdHR5IHBhZCBwcmVjX3R5XG5cbiAgfCBDaGFyIHJlc3QgICAgICAgICAgICAgICAgICAtPiBDaGFyX3R5IChmbXR0eV9vZl9mbXQgcmVzdClcbiAgfCBDYW1sX2NoYXIgcmVzdCAgICAgICAgICAgICAtPiBDaGFyX3R5IChmbXR0eV9vZl9mbXQgcmVzdClcbiAgfCBCb29sIChwYWQsIHJlc3QpICAgICAgICAgICAtPlxuICAgICAgZm10dHlfb2ZfcGFkZGluZ19mbXR0eSBwYWQgKEJvb2xfdHkgKGZtdHR5X29mX2ZtdCByZXN0KSlcbiAgfCBBbHBoYSByZXN0ICAgICAgICAgICAgICAgICAtPiBBbHBoYV90eSAoZm10dHlfb2ZfZm10IHJlc3QpXG4gIHwgVGhldGEgcmVzdCAgICAgICAgICAgICAgICAgLT4gVGhldGFfdHkgKGZtdHR5X29mX2ZtdCByZXN0KVxuICB8IEN1c3RvbSAoYXJpdHksIF8sIHJlc3QpICAgIC0+IGZtdHR5X29mX2N1c3RvbSBhcml0eSAoZm10dHlfb2ZfZm10IHJlc3QpXG4gIHwgUmVhZGVyIHJlc3QgICAgICAgICAgICAgICAgLT4gUmVhZGVyX3R5IChmbXR0eV9vZl9mbXQgcmVzdClcblxuICB8IEZvcm1hdF9hcmcgKF8sIHR5LCByZXN0KSAtPlxuICAgIEZvcm1hdF9hcmdfdHkgKHR5LCBmbXR0eV9vZl9mbXQgcmVzdClcbiAgfCBGb3JtYXRfc3Vic3QgKF8sIHR5LCByZXN0KSAtPlxuICAgIEZvcm1hdF9zdWJzdF90eSAodHksIHR5LCBmbXR0eV9vZl9mbXQgcmVzdClcblxuICB8IEZsdXNoIHJlc3QgICAgICAgICAgICAgICAgIC0+IGZtdHR5X29mX2ZtdCByZXN0XG4gIHwgU3RyaW5nX2xpdGVyYWwgKF8sIHJlc3QpICAgLT4gZm10dHlfb2ZfZm10IHJlc3RcbiAgfCBDaGFyX2xpdGVyYWwgKF8sIHJlc3QpICAgICAtPiBmbXR0eV9vZl9mbXQgcmVzdFxuXG4gIHwgU2Nhbl9jaGFyX3NldCAoXywgXywgcmVzdCkgLT4gU3RyaW5nX3R5IChmbXR0eV9vZl9mbXQgcmVzdClcbiAgfCBTY2FuX2dldF9jb3VudGVyIChfLCByZXN0KSAtPiBJbnRfdHkgKGZtdHR5X29mX2ZtdCByZXN0KVxuICB8IFNjYW5fbmV4dF9jaGFyIHJlc3QgICAgICAgIC0+IENoYXJfdHkgKGZtdHR5X29mX2ZtdCByZXN0KVxuICB8IElnbm9yZWRfcGFyYW0gKGlnbiwgcmVzdCkgIC0+IGZtdHR5X29mX2lnbm9yZWRfZm9ybWF0IGlnbiByZXN0XG4gIHwgRm9ybWF0dGluZ19saXQgKF8sIHJlc3QpICAgLT4gZm10dHlfb2ZfZm10IHJlc3RcbiAgfCBGb3JtYXR0aW5nX2dlbiAoZm10aW5nX2dlbiwgcmVzdCkgIC0+XG4gICAgY29uY2F0X2ZtdHR5IChmbXR0eV9vZl9mb3JtYXR0aW5nX2dlbiBmbXRpbmdfZ2VuKSAoZm10dHlfb2ZfZm10IHJlc3QpXG5cbiAgfCBFbmRfb2ZfZm9ybWF0ICAgICAgICAgICAgICAtPiBFbmRfb2ZfZm10dHlcblxuYW5kIGZtdHR5X29mX2N1c3RvbSA6IHR5cGUgeCB5IGEgYiBjIGQgZSBmIC5cbiAgKGEsIHgsIHkpIGN1c3RvbV9hcml0eSAtPiAoYSwgYiwgYywgZCwgZSwgZikgZm10dHkgLT5cbiAgKHksIGIsIGMsIGQsIGUsIGYpIGZtdHR5ID1cbmZ1biBhcml0eSBmbXR0eSAtPiBtYXRjaCBhcml0eSB3aXRoXG4gIHwgQ3VzdG9tX3plcm8gLT4gZm10dHlcbiAgfCBDdXN0b21fc3VjYyBhcml0eSAtPiBBbnlfdHkgKGZtdHR5X29mX2N1c3RvbSBhcml0eSBmbXR0eSlcblxuKCogRXh0cmFjdCB0aGUgZm10dHkgb2YgYW4gaWdub3JlZCBwYXJhbWV0ZXIgZm9sbG93ZWQgYnkgdGhlIHJlc3Qgb2ZcbiAgIHRoZSBmb3JtYXQuICopXG5hbmQgZm10dHlfb2ZfaWdub3JlZF9mb3JtYXQgOiB0eXBlIHggeSBhIGIgYyBkIGUgZiAuXG4gICAgKGEsIGIsIGMsIGQsIHksIHgpIGlnbm9yZWQgLT5cbiAgICAoeCwgYiwgYywgeSwgZSwgZikgZm10IC0+XG4gICAgKGEsIGIsIGMsIGQsIGUsIGYpIGZtdHR5ID1cbmZ1biBpZ24gZm10IC0+IG1hdGNoIGlnbiB3aXRoXG4gIHwgSWdub3JlZF9jaGFyICAgICAgICAgICAgICAgICAgICAtPiBmbXR0eV9vZl9mbXQgZm10XG4gIHwgSWdub3JlZF9jYW1sX2NoYXIgICAgICAgICAgICAgICAtPiBmbXR0eV9vZl9mbXQgZm10XG4gIHwgSWdub3JlZF9zdHJpbmcgXyAgICAgICAgICAgICAgICAtPiBmbXR0eV9vZl9mbXQgZm10XG4gIHwgSWdub3JlZF9jYW1sX3N0cmluZyBfICAgICAgICAgICAtPiBmbXR0eV9vZl9mbXQgZm10XG4gIHwgSWdub3JlZF9pbnQgKF8sIF8pICAgICAgICAgICAgICAtPiBmbXR0eV9vZl9mbXQgZm10XG4gIHwgSWdub3JlZF9pbnQzMiAoXywgXykgICAgICAgICAgICAtPiBmbXR0eV9vZl9mbXQgZm10XG4gIHwgSWdub3JlZF9uYXRpdmVpbnQgKF8sIF8pICAgICAgICAtPiBmbXR0eV9vZl9mbXQgZm10XG4gIHwgSWdub3JlZF9pbnQ2NCAoXywgXykgICAgICAgICAgICAtPiBmbXR0eV9vZl9mbXQgZm10XG4gIHwgSWdub3JlZF9mbG9hdCAoXywgXykgICAgICAgICAgICAtPiBmbXR0eV9vZl9mbXQgZm10XG4gIHwgSWdub3JlZF9ib29sIF8gICAgICAgICAgICAgICAgICAtPiBmbXR0eV9vZl9mbXQgZm10XG4gIHwgSWdub3JlZF9mb3JtYXRfYXJnIF8gICAgICAgICAgICAtPiBmbXR0eV9vZl9mbXQgZm10XG4gIHwgSWdub3JlZF9mb3JtYXRfc3Vic3QgKF8sIGZtdHR5KSAtPiBjb25jYXRfZm10dHkgZm10dHkgKGZtdHR5X29mX2ZtdCBmbXQpXG4gIHwgSWdub3JlZF9yZWFkZXIgICAgICAgICAgICAgICAgICAtPiBJZ25vcmVkX3JlYWRlcl90eSAoZm10dHlfb2ZfZm10IGZtdClcbiAgfCBJZ25vcmVkX3NjYW5fY2hhcl9zZXQgXyAgICAgICAgIC0+IGZtdHR5X29mX2ZtdCBmbXRcbiAgfCBJZ25vcmVkX3NjYW5fZ2V0X2NvdW50ZXIgXyAgICAgIC0+IGZtdHR5X29mX2ZtdCBmbXRcbiAgfCBJZ25vcmVkX3NjYW5fbmV4dF9jaGFyICAgICAgICAgIC0+IGZtdHR5X29mX2ZtdCBmbXRcblxuKCogQWRkIGFuIEludF90eSBub2RlIGlmIHBhZGRpbmcgaXMgdGFrZW4gYXMgYW4gZXh0cmEgYXJndW1lbnQgKGV4OiBcIiUqc1wiKS4gKilcbmFuZCBmbXR0eV9vZl9wYWRkaW5nX2ZtdHR5IDogdHlwZSB4IGEgYiBjIGQgZSBmIC5cbiAgICAoeCwgYSkgcGFkZGluZyAtPiAoYSwgYiwgYywgZCwgZSwgZikgZm10dHkgLT4gKHgsIGIsIGMsIGQsIGUsIGYpIGZtdHR5ID1cbiAgZnVuIHBhZCBmbXR0eSAtPiBtYXRjaCBwYWQgd2l0aFxuICAgIHwgTm9fcGFkZGluZyAgICAtPiBmbXR0eVxuICAgIHwgTGl0X3BhZGRpbmcgXyAtPiBmbXR0eVxuICAgIHwgQXJnX3BhZGRpbmcgXyAtPiBJbnRfdHkgZm10dHlcblxuKCogQWRkIGFuIEludF90eSBub2RlIGlmIHByZWNpc2lvbiBpcyB0YWtlbiBhcyBhbiBleHRyYSBhcmd1bWVudCAoZXg6IFwiJS4qZlwiKS4qKVxuYW5kIGZtdHR5X29mX3ByZWNpc2lvbl9mbXR0eSA6IHR5cGUgeCBhIGIgYyBkIGUgZiAuXG4gICAgKHgsIGEpIHByZWNpc2lvbiAtPiAoYSwgYiwgYywgZCwgZSwgZikgZm10dHkgLT4gKHgsIGIsIGMsIGQsIGUsIGYpIGZtdHR5ID1cbiAgZnVuIHByZWMgZm10dHkgLT4gbWF0Y2ggcHJlYyB3aXRoXG4gICAgfCBOb19wcmVjaXNpb24gICAgLT4gZm10dHlcbiAgICB8IExpdF9wcmVjaXNpb24gXyAtPiBmbXR0eVxuICAgIHwgQXJnX3ByZWNpc2lvbiAgIC0+IEludF90eSBmbXR0eVxuXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqIEZvcm1hdCB0eXBpbmcgKilcblxuKCogRXhjZXB0aW9uIHJhaXNlZCB3aGVuIGEgZm9ybWF0IGRvZXMgbm90IG1hdGNoIGEgZ2l2ZW4gZm9ybWF0IHR5cGUuICopXG5leGNlcHRpb24gVHlwZV9taXNtYXRjaFxuXG4oKiBUeXBlIGEgcGFkZGluZy4gKilcbigqIFRha2UgYW4gSW50X3R5IGZyb20gdGhlIGZtdHR5IGlmIHRoZSBpbnRlZ2VyIHNob3VsZCBiZSBrZXB0IGFzIGFyZ3VtZW50LiAqKVxuKCogUmFpc2UgVHlwZV9taXNtYXRjaCBpbiBjYXNlIG9mIHR5cGUgbWlzbWF0Y2guICopXG5sZXQgdHlwZV9wYWRkaW5nIDogdHlwZSBhIGIgYyBkIGUgZiB4IHkgLlxuICAgICh4LCB5KSBwYWRkaW5nIC0+IChhLCBiLCBjLCBkLCBlLCBmKSBmbXR0eSAtPlxuICAgICAgKGEsIGIsIGMsIGQsIGUsIGYpIHBhZGRpbmdfZm10dHlfZWJiID1cbmZ1biBwYWQgZm10dHkgLT4gbWF0Y2ggcGFkLCBmbXR0eSB3aXRoXG4gIHwgTm9fcGFkZGluZywgXyAtPiBQYWRkaW5nX2ZtdHR5X0VCQiAoTm9fcGFkZGluZywgZm10dHkpXG4gIHwgTGl0X3BhZGRpbmcgKHBhZHR5LCB3KSwgXyAtPiBQYWRkaW5nX2ZtdHR5X0VCQiAoTGl0X3BhZGRpbmcgKHBhZHR5LHcpLGZtdHR5KVxuICB8IEFyZ19wYWRkaW5nIHBhZHR5LCBJbnRfdHkgcmVzdCAtPiBQYWRkaW5nX2ZtdHR5X0VCQiAoQXJnX3BhZGRpbmcgcGFkdHkscmVzdClcbiAgfCBfIC0+IHJhaXNlIFR5cGVfbWlzbWF0Y2hcblxuKCogQ29udmVydCBhICh1cGFkZGluZywgdXByZWNpc2lvbikgdG8gYSAocGFkZGluZywgcHJlY2lzaW9uKS4gKilcbigqIFRha2Ugb25lIG9yIHR3byBJbnRfdHkgZnJvbSB0aGUgZm10dHkgaWYgbmVlZGVkLiAqKVxuKCogUmFpc2UgVHlwZV9taXNtYXRjaCBpbiBjYXNlIG9mIHR5cGUgbWlzbWF0Y2guICopXG5sZXQgdHlwZV9wYWRwcmVjIDogdHlwZSBhIGIgYyBkIGUgZiB4IHkgeiAuXG4gICh4LCB5KSBwYWRkaW5nIC0+ICh5LCB6KSBwcmVjaXNpb24gLT4gKGEsIGIsIGMsIGQsIGUsIGYpIGZtdHR5IC0+XG4gICAgKGEsIGIsIGMsIGQsIGUsIGYpIHBhZHByZWNfZm10dHlfZWJiID1cbmZ1biBwYWQgcHJlYyBmbXR0eSAtPiBtYXRjaCBwcmVjLCB0eXBlX3BhZGRpbmcgcGFkIGZtdHR5IHdpdGhcbiAgfCBOb19wcmVjaXNpb24sIFBhZGRpbmdfZm10dHlfRUJCIChwYWQsIHJlc3QpIC0+XG4gICAgUGFkcHJlY19mbXR0eV9FQkIgKHBhZCwgTm9fcHJlY2lzaW9uLCByZXN0KVxuICB8IExpdF9wcmVjaXNpb24gcCwgUGFkZGluZ19mbXR0eV9FQkIgKHBhZCwgcmVzdCkgLT5cbiAgICBQYWRwcmVjX2ZtdHR5X0VCQiAocGFkLCBMaXRfcHJlY2lzaW9uIHAsIHJlc3QpXG4gIHwgQXJnX3ByZWNpc2lvbiwgUGFkZGluZ19mbXR0eV9FQkIgKHBhZCwgSW50X3R5IHJlc3QpIC0+XG4gICAgUGFkcHJlY19mbXR0eV9FQkIgKHBhZCwgQXJnX3ByZWNpc2lvbiwgcmVzdClcbiAgfCBfLCBQYWRkaW5nX2ZtdHR5X0VCQiAoXywgXykgLT4gcmFpc2UgVHlwZV9taXNtYXRjaFxuXG4oKiBUeXBlIGEgZm9ybWF0IGFjY29yZGluZyB0byBhbiBmbXR0eS4gKilcbigqIElmIHR5cGluZyBzdWNjZWVkLCBnZW5lcmF0ZSBhIGNvcHkgb2YgdGhlIGZvcm1hdCB3aXRoIHRoZSBzYW1lXG4gICAgdHlwZSBwYXJhbWV0ZXJzIGFzIHRoZSBmbXR0eS4gKilcbigqIFJhaXNlIFtGYWlsdXJlXSB3aXRoIGFuIGVycm9yIG1lc3NhZ2UgaW4gY2FzZSBvZiB0eXBlIG1pc21hdGNoLiAqKVxubGV0IHJlYyB0eXBlX2Zvcm1hdCA6XG4gIHR5cGUgYTEgYjEgYzEgZDEgZTEgZjFcbiAgICAgICBhMiBiMiBjMiBkMiBlMiBmMiAgLlxuICAgICAoYTEsIGIxLCBjMSwgZDEsIGUxLCBmMSkgZm10XG4gIC0+IChhMiwgYjIsIGMyLCBkMiwgZTIsIGYyKSBmbXR0eVxuICAtPiAoYTIsIGIyLCBjMiwgZDIsIGUyLCBmMikgZm10XG49IGZ1biBmbXQgZm10dHkgLT4gbWF0Y2ggdHlwZV9mb3JtYXRfZ2VuIGZtdCBmbXR0eSB3aXRoXG4gIHwgRm10X2ZtdHR5X0VCQiAoZm10JywgRW5kX29mX2ZtdHR5KSAtPiBmbXQnXG4gIHwgXyAtPiByYWlzZSBUeXBlX21pc21hdGNoXG5cbmFuZCB0eXBlX2Zvcm1hdF9nZW4gOlxuICB0eXBlIGExIGIxIGMxIGQxIGUxIGYxXG4gICAgICAgYTIgYjIgYzIgZDIgZTIgZjIgIC5cbiAgICAgKGExLCBiMSwgYzEsIGQxLCBlMSwgZjEpIGZtdFxuICAtPiAoYTIsIGIyLCBjMiwgZDIsIGUyLCBmMikgZm10dHlcbiAgLT4gKGEyLCBiMiwgYzIsIGQyLCBlMiwgZjIpIGZtdF9mbXR0eV9lYmJcbj0gZnVuIGZtdCBmbXR0eSAtPiBtYXRjaCBmbXQsIGZtdHR5IHdpdGhcbiAgfCBDaGFyIGZtdF9yZXN0LCBDaGFyX3R5IGZtdHR5X3Jlc3QgLT5cbiAgICBsZXQgRm10X2ZtdHR5X0VCQiAoZm10JywgZm10dHknKSA9IHR5cGVfZm9ybWF0X2dlbiBmbXRfcmVzdCBmbXR0eV9yZXN0IGluXG4gICAgRm10X2ZtdHR5X0VCQiAoQ2hhciBmbXQnLCBmbXR0eScpXG4gIHwgQ2FtbF9jaGFyIGZtdF9yZXN0LCBDaGFyX3R5IGZtdHR5X3Jlc3QgLT5cbiAgICBsZXQgRm10X2ZtdHR5X0VCQiAoZm10JywgZm10dHknKSA9IHR5cGVfZm9ybWF0X2dlbiBmbXRfcmVzdCBmbXR0eV9yZXN0IGluXG4gICAgRm10X2ZtdHR5X0VCQiAoQ2FtbF9jaGFyIGZtdCcsIGZtdHR5JylcbiAgfCBTdHJpbmcgKHBhZCwgZm10X3Jlc3QpLCBfIC0+IChcbiAgICBtYXRjaCB0eXBlX3BhZGRpbmcgcGFkIGZtdHR5IHdpdGhcbiAgICB8IFBhZGRpbmdfZm10dHlfRUJCIChwYWQsIFN0cmluZ190eSBmbXR0eV9yZXN0KSAtPlxuICAgICAgbGV0IEZtdF9mbXR0eV9FQkIgKGZtdCcsIGZtdHR5JykgPSB0eXBlX2Zvcm1hdF9nZW4gZm10X3Jlc3QgZm10dHlfcmVzdCBpblxuICAgICAgRm10X2ZtdHR5X0VCQiAoU3RyaW5nIChwYWQsIGZtdCcpLCBmbXR0eScpXG4gICAgfCBQYWRkaW5nX2ZtdHR5X0VCQiAoXywgXykgLT4gcmFpc2UgVHlwZV9taXNtYXRjaFxuICApXG4gIHwgQ2FtbF9zdHJpbmcgKHBhZCwgZm10X3Jlc3QpLCBfIC0+IChcbiAgICBtYXRjaCB0eXBlX3BhZGRpbmcgcGFkIGZtdHR5IHdpdGhcbiAgICB8IFBhZGRpbmdfZm10dHlfRUJCIChwYWQsIFN0cmluZ190eSBmbXR0eV9yZXN0KSAtPlxuICAgICAgbGV0IEZtdF9mbXR0eV9FQkIgKGZtdCcsIGZtdHR5JykgPSB0eXBlX2Zvcm1hdF9nZW4gZm10X3Jlc3QgZm10dHlfcmVzdCBpblxuICAgICAgRm10X2ZtdHR5X0VCQiAoQ2FtbF9zdHJpbmcgKHBhZCwgZm10JyksIGZtdHR5JylcbiAgICB8IFBhZGRpbmdfZm10dHlfRUJCIChfLCBfKSAtPiByYWlzZSBUeXBlX21pc21hdGNoXG4gIClcbiAgfCBJbnQgKGljb252LCBwYWQsIHByZWMsIGZtdF9yZXN0KSwgXyAtPiAoXG4gICAgbWF0Y2ggdHlwZV9wYWRwcmVjIHBhZCBwcmVjIGZtdHR5IHdpdGhcbiAgICB8IFBhZHByZWNfZm10dHlfRUJCIChwYWQsIHByZWMsIEludF90eSBmbXR0eV9yZXN0KSAtPlxuICAgICAgbGV0IEZtdF9mbXR0eV9FQkIgKGZtdCcsIGZtdHR5JykgPSB0eXBlX2Zvcm1hdF9nZW4gZm10X3Jlc3QgZm10dHlfcmVzdCBpblxuICAgICAgRm10X2ZtdHR5X0VCQiAoSW50IChpY29udiwgcGFkLCBwcmVjLCBmbXQnKSwgZm10dHknKVxuICAgIHwgUGFkcHJlY19mbXR0eV9FQkIgKF8sIF8sIF8pIC0+IHJhaXNlIFR5cGVfbWlzbWF0Y2hcbiAgKVxuICB8IEludDMyIChpY29udiwgcGFkLCBwcmVjLCBmbXRfcmVzdCksIF8gLT4gKFxuICAgIG1hdGNoIHR5cGVfcGFkcHJlYyBwYWQgcHJlYyBmbXR0eSB3aXRoXG4gICAgfCBQYWRwcmVjX2ZtdHR5X0VCQiAocGFkLCBwcmVjLCBJbnQzMl90eSBmbXR0eV9yZXN0KSAtPlxuICAgICAgbGV0IEZtdF9mbXR0eV9FQkIgKGZtdCcsIGZtdHR5JykgPSB0eXBlX2Zvcm1hdF9nZW4gZm10X3Jlc3QgZm10dHlfcmVzdCBpblxuICAgICAgRm10X2ZtdHR5X0VCQiAoSW50MzIgKGljb252LCBwYWQsIHByZWMsIGZtdCcpLCBmbXR0eScpXG4gICAgfCBQYWRwcmVjX2ZtdHR5X0VCQiAoXywgXywgXykgLT4gcmFpc2UgVHlwZV9taXNtYXRjaFxuICApXG4gIHwgTmF0aXZlaW50IChpY29udiwgcGFkLCBwcmVjLCBmbXRfcmVzdCksIF8gLT4gKFxuICAgIG1hdGNoIHR5cGVfcGFkcHJlYyBwYWQgcHJlYyBmbXR0eSB3aXRoXG4gICAgfCBQYWRwcmVjX2ZtdHR5X0VCQiAocGFkLCBwcmVjLCBOYXRpdmVpbnRfdHkgZm10dHlfcmVzdCkgLT5cbiAgICAgIGxldCBGbXRfZm10dHlfRUJCIChmbXQnLCBmbXR0eScpID0gdHlwZV9mb3JtYXRfZ2VuIGZtdF9yZXN0IGZtdHR5X3Jlc3QgaW5cbiAgICAgIEZtdF9mbXR0eV9FQkIgKE5hdGl2ZWludCAoaWNvbnYsIHBhZCwgcHJlYywgZm10JyksIGZtdHR5JylcbiAgICB8IFBhZHByZWNfZm10dHlfRUJCIChfLCBfLCBfKSAtPiByYWlzZSBUeXBlX21pc21hdGNoXG4gIClcbiAgfCBJbnQ2NCAoaWNvbnYsIHBhZCwgcHJlYywgZm10X3Jlc3QpLCBfIC0+IChcbiAgICBtYXRjaCB0eXBlX3BhZHByZWMgcGFkIHByZWMgZm10dHkgd2l0aFxuICAgIHwgUGFkcHJlY19mbXR0eV9FQkIgKHBhZCwgcHJlYywgSW50NjRfdHkgZm10dHlfcmVzdCkgLT5cbiAgICAgIGxldCBGbXRfZm10dHlfRUJCIChmbXQnLCBmbXR0eScpID0gdHlwZV9mb3JtYXRfZ2VuIGZtdF9yZXN0IGZtdHR5X3Jlc3QgaW5cbiAgICAgIEZtdF9mbXR0eV9FQkIgKEludDY0IChpY29udiwgcGFkLCBwcmVjLCBmbXQnKSwgZm10dHknKVxuICAgIHwgUGFkcHJlY19mbXR0eV9FQkIgKF8sIF8sIF8pIC0+IHJhaXNlIFR5cGVfbWlzbWF0Y2hcbiAgKVxuICB8IEZsb2F0IChmY29udiwgcGFkLCBwcmVjLCBmbXRfcmVzdCksIF8gLT4gKFxuICAgIG1hdGNoIHR5cGVfcGFkcHJlYyBwYWQgcHJlYyBmbXR0eSB3aXRoXG4gICAgfCBQYWRwcmVjX2ZtdHR5X0VCQiAocGFkLCBwcmVjLCBGbG9hdF90eSBmbXR0eV9yZXN0KSAtPlxuICAgICAgbGV0IEZtdF9mbXR0eV9FQkIgKGZtdCcsIGZtdHR5JykgPSB0eXBlX2Zvcm1hdF9nZW4gZm10X3Jlc3QgZm10dHlfcmVzdCBpblxuICAgICAgRm10X2ZtdHR5X0VCQiAoRmxvYXQgKGZjb252LCBwYWQsIHByZWMsIGZtdCcpLCBmbXR0eScpXG4gICAgfCBQYWRwcmVjX2ZtdHR5X0VCQiAoXywgXywgXykgLT4gcmFpc2UgVHlwZV9taXNtYXRjaFxuICApXG4gIHwgQm9vbCAocGFkLCBmbXRfcmVzdCksIF8gLT4gKFxuICAgIG1hdGNoIHR5cGVfcGFkZGluZyBwYWQgZm10dHkgd2l0aFxuICAgIHwgUGFkZGluZ19mbXR0eV9FQkIgKHBhZCwgQm9vbF90eSBmbXR0eV9yZXN0KSAtPlxuICAgICAgbGV0IEZtdF9mbXR0eV9FQkIgKGZtdCcsIGZtdHR5JykgPSB0eXBlX2Zvcm1hdF9nZW4gZm10X3Jlc3QgZm10dHlfcmVzdCBpblxuICAgICAgRm10X2ZtdHR5X0VCQiAoQm9vbCAocGFkLCBmbXQnKSwgZm10dHknKVxuICAgIHwgUGFkZGluZ19mbXR0eV9FQkIgKF8sIF8pIC0+IHJhaXNlIFR5cGVfbWlzbWF0Y2hcbiAgKVxuICB8IEZsdXNoIGZtdF9yZXN0LCBmbXR0eV9yZXN0IC0+XG4gICAgbGV0IEZtdF9mbXR0eV9FQkIgKGZtdCcsIGZtdHR5JykgPSB0eXBlX2Zvcm1hdF9nZW4gZm10X3Jlc3QgZm10dHlfcmVzdCBpblxuICAgIEZtdF9mbXR0eV9FQkIgKEZsdXNoIGZtdCcsIGZtdHR5JylcblxuICB8IFN0cmluZ19saXRlcmFsIChzdHIsIGZtdF9yZXN0KSwgZm10dHlfcmVzdCAtPlxuICAgIGxldCBGbXRfZm10dHlfRUJCIChmbXQnLCBmbXR0eScpID0gdHlwZV9mb3JtYXRfZ2VuIGZtdF9yZXN0IGZtdHR5X3Jlc3QgaW5cbiAgICBGbXRfZm10dHlfRUJCIChTdHJpbmdfbGl0ZXJhbCAoc3RyLCBmbXQnKSwgZm10dHknKVxuICB8IENoYXJfbGl0ZXJhbCAoY2hyLCBmbXRfcmVzdCksIGZtdHR5X3Jlc3QgLT5cbiAgICBsZXQgRm10X2ZtdHR5X0VCQiAoZm10JywgZm10dHknKSA9IHR5cGVfZm9ybWF0X2dlbiBmbXRfcmVzdCBmbXR0eV9yZXN0IGluXG4gICAgRm10X2ZtdHR5X0VCQiAoQ2hhcl9saXRlcmFsIChjaHIsIGZtdCcpLCBmbXR0eScpXG5cbiAgfCBGb3JtYXRfYXJnIChwYWRfb3B0LCBzdWJfZm10dHksIGZtdF9yZXN0KSxcbiAgICBGb3JtYXRfYXJnX3R5IChzdWJfZm10dHknLCBmbXR0eV9yZXN0KSAtPlxuICAgIGlmIEZtdHR5X0VCQiBzdWJfZm10dHkgPD4gRm10dHlfRUJCIHN1Yl9mbXR0eScgdGhlbiByYWlzZSBUeXBlX21pc21hdGNoO1xuICAgIGxldCBGbXRfZm10dHlfRUJCIChmbXQnLCBmbXR0eScpID0gdHlwZV9mb3JtYXRfZ2VuIGZtdF9yZXN0IGZtdHR5X3Jlc3QgaW5cbiAgICBGbXRfZm10dHlfRUJCIChGb3JtYXRfYXJnIChwYWRfb3B0LCBzdWJfZm10dHknLCBmbXQnKSwgZm10dHknKVxuICB8IEZvcm1hdF9zdWJzdCAocGFkX29wdCwgc3ViX2ZtdHR5LCBmbXRfcmVzdCksXG4gICAgRm9ybWF0X3N1YnN0X3R5IChzdWJfZm10dHkxLCBfc3ViX2ZtdHR5MiwgZm10dHlfcmVzdCkgLT5cbiAgICBpZiBGbXR0eV9FQkIgKGVyYXNlX3JlbCBzdWJfZm10dHkpIDw+IEZtdHR5X0VCQiAoZXJhc2VfcmVsIHN1Yl9mbXR0eTEpIHRoZW5cbiAgICAgIHJhaXNlIFR5cGVfbWlzbWF0Y2g7XG4gICAgbGV0IEZtdF9mbXR0eV9FQkIgKGZtdCcsIGZtdHR5JykgPVxuICAgICAgdHlwZV9mb3JtYXRfZ2VuIGZtdF9yZXN0IChlcmFzZV9yZWwgZm10dHlfcmVzdClcbiAgICBpblxuICAgIEZtdF9mbXR0eV9FQkIgKEZvcm1hdF9zdWJzdCAocGFkX29wdCwgc3ViX2ZtdHR5MSwgZm10JyksIGZtdHR5JylcbiAgKCogUHJpbnRmIGFuZCBGb3JtYXQgc3BlY2lmaWMgY29uc3RydWN0b3JzOiAqKVxuICB8IEFscGhhIGZtdF9yZXN0LCBBbHBoYV90eSBmbXR0eV9yZXN0IC0+XG4gICAgbGV0IEZtdF9mbXR0eV9FQkIgKGZtdCcsIGZtdHR5JykgPSB0eXBlX2Zvcm1hdF9nZW4gZm10X3Jlc3QgZm10dHlfcmVzdCBpblxuICAgIEZtdF9mbXR0eV9FQkIgKEFscGhhIGZtdCcsIGZtdHR5JylcbiAgfCBUaGV0YSBmbXRfcmVzdCwgVGhldGFfdHkgZm10dHlfcmVzdCAtPlxuICAgIGxldCBGbXRfZm10dHlfRUJCIChmbXQnLCBmbXR0eScpID0gdHlwZV9mb3JtYXRfZ2VuIGZtdF9yZXN0IGZtdHR5X3Jlc3QgaW5cbiAgICBGbXRfZm10dHlfRUJCIChUaGV0YSBmbXQnLCBmbXR0eScpXG5cbiAgKCogRm9ybWF0IHNwZWNpZmljIGNvbnN0cnVjdG9yczogKilcbiAgfCBGb3JtYXR0aW5nX2xpdCAoZm9ybWF0dGluZ19saXQsIGZtdF9yZXN0KSwgZm10dHlfcmVzdCAtPlxuICAgIGxldCBGbXRfZm10dHlfRUJCIChmbXQnLCBmbXR0eScpID0gdHlwZV9mb3JtYXRfZ2VuIGZtdF9yZXN0IGZtdHR5X3Jlc3QgaW5cbiAgICBGbXRfZm10dHlfRUJCIChGb3JtYXR0aW5nX2xpdCAoZm9ybWF0dGluZ19saXQsIGZtdCcpLCBmbXR0eScpXG4gIHwgRm9ybWF0dGluZ19nZW4gKGZvcm1hdHRpbmdfZ2VuLCBmbXRfcmVzdCksIGZtdHR5X3Jlc3QgLT5cbiAgICB0eXBlX2Zvcm1hdHRpbmdfZ2VuIGZvcm1hdHRpbmdfZ2VuIGZtdF9yZXN0IGZtdHR5X3Jlc3RcblxuICAoKiBTY2FuZiBzcGVjaWZpYyBjb25zdHJ1Y3RvcnM6ICopXG4gIHwgUmVhZGVyIGZtdF9yZXN0LCBSZWFkZXJfdHkgZm10dHlfcmVzdCAtPlxuICAgIGxldCBGbXRfZm10dHlfRUJCIChmbXQnLCBmbXR0eScpID0gdHlwZV9mb3JtYXRfZ2VuIGZtdF9yZXN0IGZtdHR5X3Jlc3QgaW5cbiAgICBGbXRfZm10dHlfRUJCIChSZWFkZXIgZm10JywgZm10dHknKVxuICB8IFNjYW5fY2hhcl9zZXQgKHdpZHRoX29wdCwgY2hhcl9zZXQsIGZtdF9yZXN0KSwgU3RyaW5nX3R5IGZtdHR5X3Jlc3QgLT5cbiAgICBsZXQgRm10X2ZtdHR5X0VCQiAoZm10JywgZm10dHknKSA9IHR5cGVfZm9ybWF0X2dlbiBmbXRfcmVzdCBmbXR0eV9yZXN0IGluXG4gICAgRm10X2ZtdHR5X0VCQiAoU2Nhbl9jaGFyX3NldCAod2lkdGhfb3B0LCBjaGFyX3NldCwgZm10JyksIGZtdHR5JylcbiAgfCBTY2FuX2dldF9jb3VudGVyIChjb3VudGVyLCBmbXRfcmVzdCksIEludF90eSBmbXR0eV9yZXN0IC0+XG4gICAgbGV0IEZtdF9mbXR0eV9FQkIgKGZtdCcsIGZtdHR5JykgPSB0eXBlX2Zvcm1hdF9nZW4gZm10X3Jlc3QgZm10dHlfcmVzdCBpblxuICAgIEZtdF9mbXR0eV9FQkIgKFNjYW5fZ2V0X2NvdW50ZXIgKGNvdW50ZXIsIGZtdCcpLCBmbXR0eScpXG4gIHwgSWdub3JlZF9wYXJhbSAoaWduLCByZXN0KSwgZm10dHlfcmVzdCAtPlxuICAgIHR5cGVfaWdub3JlZF9wYXJhbSBpZ24gcmVzdCBmbXR0eV9yZXN0XG5cbiAgfCBFbmRfb2ZfZm9ybWF0LCBmbXR0eV9yZXN0IC0+IEZtdF9mbXR0eV9FQkIgKEVuZF9vZl9mb3JtYXQsIGZtdHR5X3Jlc3QpXG5cbiAgfCBfIC0+IHJhaXNlIFR5cGVfbWlzbWF0Y2hcblxuYW5kIHR5cGVfZm9ybWF0dGluZ19nZW4gOiB0eXBlIGExIGEzIGIxIGIzIGMxIGMzIGQxIGQzIGUxIGUyIGUzIGYxIGYyIGYzIC5cbiAgICAoYTEsIGIxLCBjMSwgZDEsIGUxLCBmMSkgZm9ybWF0dGluZ19nZW4gLT5cbiAgICAoZjEsIGIxLCBjMSwgZTEsIGUyLCBmMikgZm10IC0+XG4gICAgKGEzLCBiMywgYzMsIGQzLCBlMywgZjMpIGZtdHR5IC0+XG4gICAgKGEzLCBiMywgYzMsIGQzLCBlMywgZjMpIGZtdF9mbXR0eV9lYmIgPVxuZnVuIGZvcm1hdHRpbmdfZ2VuIGZtdDAgZm10dHkwIC0+IG1hdGNoIGZvcm1hdHRpbmdfZ2VuIHdpdGhcbiAgfCBPcGVuX3RhZyAoRm9ybWF0IChmbXQxLCBzdHIpKSAtPlxuICAgIGxldCBGbXRfZm10dHlfRUJCIChmbXQyLCBmbXR0eTIpID0gdHlwZV9mb3JtYXRfZ2VuIGZtdDEgZm10dHkwIGluXG4gICAgbGV0IEZtdF9mbXR0eV9FQkIgKGZtdDMsIGZtdHR5MykgPSB0eXBlX2Zvcm1hdF9nZW4gZm10MCBmbXR0eTIgaW5cbiAgICBGbXRfZm10dHlfRUJCIChGb3JtYXR0aW5nX2dlbiAoT3Blbl90YWcgKEZvcm1hdCAoZm10Miwgc3RyKSksIGZtdDMpLCBmbXR0eTMpXG4gIHwgT3Blbl9ib3ggKEZvcm1hdCAoZm10MSwgc3RyKSkgLT5cbiAgICBsZXQgRm10X2ZtdHR5X0VCQiAoZm10MiwgZm10dHkyKSA9IHR5cGVfZm9ybWF0X2dlbiBmbXQxIGZtdHR5MCBpblxuICAgIGxldCBGbXRfZm10dHlfRUJCIChmbXQzLCBmbXR0eTMpID0gdHlwZV9mb3JtYXRfZ2VuIGZtdDAgZm10dHkyIGluXG4gICAgRm10X2ZtdHR5X0VCQiAoRm9ybWF0dGluZ19nZW4gKE9wZW5fYm94IChGb3JtYXQgKGZtdDIsIHN0cikpLCBmbXQzKSwgZm10dHkzKVxuXG4oKiBUeXBlIGFuIElnbm9yZWRfcGFyYW0gbm9kZSBhY2NvcmRpbmcgdG8gYW4gZm10dHkuICopXG5hbmQgdHlwZV9pZ25vcmVkX3BhcmFtIDogdHlwZSBwIHEgeCB5IHogdCB1IHYgYSBiIGMgZCBlIGYgLlxuICAgICh4LCB5LCB6LCB0LCBxLCBwKSBpZ25vcmVkIC0+XG4gICAgKHAsIHksIHosIHEsIHUsIHYpIGZtdCAtPlxuICAgIChhLCBiLCBjLCBkLCBlLCBmKSBmbXR0eSAtPlxuICAgIChhLCBiLCBjLCBkLCBlLCBmKSBmbXRfZm10dHlfZWJiID1cbmZ1biBpZ24gZm10IGZtdHR5IC0+IG1hdGNoIGlnbiB3aXRoXG4gIHwgSWdub3JlZF9jaGFyICAgICAgICAgICAgICAgYXMgaWduJyAtPiB0eXBlX2lnbm9yZWRfcGFyYW1fb25lIGlnbicgZm10IGZtdHR5XG4gIHwgSWdub3JlZF9jYW1sX2NoYXIgICAgICAgICAgYXMgaWduJyAtPiB0eXBlX2lnbm9yZWRfcGFyYW1fb25lIGlnbicgZm10IGZtdHR5XG4gIHwgSWdub3JlZF9zdHJpbmcgXyAgICAgICAgICAgYXMgaWduJyAtPiB0eXBlX2lnbm9yZWRfcGFyYW1fb25lIGlnbicgZm10IGZtdHR5XG4gIHwgSWdub3JlZF9jYW1sX3N0cmluZyBfICAgICAgYXMgaWduJyAtPiB0eXBlX2lnbm9yZWRfcGFyYW1fb25lIGlnbicgZm10IGZtdHR5XG4gIHwgSWdub3JlZF9pbnQgXyAgICAgICAgICAgICAgYXMgaWduJyAtPiB0eXBlX2lnbm9yZWRfcGFyYW1fb25lIGlnbicgZm10IGZtdHR5XG4gIHwgSWdub3JlZF9pbnQzMiBfICAgICAgICAgICAgYXMgaWduJyAtPiB0eXBlX2lnbm9yZWRfcGFyYW1fb25lIGlnbicgZm10IGZtdHR5XG4gIHwgSWdub3JlZF9uYXRpdmVpbnQgXyAgICAgICAgYXMgaWduJyAtPiB0eXBlX2lnbm9yZWRfcGFyYW1fb25lIGlnbicgZm10IGZtdHR5XG4gIHwgSWdub3JlZF9pbnQ2NCBfICAgICAgICAgICAgYXMgaWduJyAtPiB0eXBlX2lnbm9yZWRfcGFyYW1fb25lIGlnbicgZm10IGZtdHR5XG4gIHwgSWdub3JlZF9mbG9hdCBfICAgICAgICAgICAgYXMgaWduJyAtPiB0eXBlX2lnbm9yZWRfcGFyYW1fb25lIGlnbicgZm10IGZtdHR5XG4gIHwgSWdub3JlZF9ib29sIF8gICAgICAgICAgICAgYXMgaWduJyAtPiB0eXBlX2lnbm9yZWRfcGFyYW1fb25lIGlnbicgZm10IGZtdHR5XG4gIHwgSWdub3JlZF9zY2FuX2NoYXJfc2V0IF8gICAgYXMgaWduJyAtPiB0eXBlX2lnbm9yZWRfcGFyYW1fb25lIGlnbicgZm10IGZtdHR5XG4gIHwgSWdub3JlZF9zY2FuX2dldF9jb3VudGVyIF8gYXMgaWduJyAtPiB0eXBlX2lnbm9yZWRfcGFyYW1fb25lIGlnbicgZm10IGZtdHR5XG4gIHwgSWdub3JlZF9zY2FuX25leHRfY2hhciAgICAgYXMgaWduJyAtPiB0eXBlX2lnbm9yZWRfcGFyYW1fb25lIGlnbicgZm10IGZtdHR5XG4gIHwgSWdub3JlZF9mb3JtYXRfYXJnIChwYWRfb3B0LCBzdWJfZm10dHkpIC0+XG4gICAgdHlwZV9pZ25vcmVkX3BhcmFtX29uZSAoSWdub3JlZF9mb3JtYXRfYXJnIChwYWRfb3B0LCBzdWJfZm10dHkpKSBmbXQgZm10dHlcbiAgfCBJZ25vcmVkX2Zvcm1hdF9zdWJzdCAocGFkX29wdCwgc3ViX2ZtdHR5KSAtPlxuICAgIGxldCBGbXR0eV9mbXRfRUJCIChzdWJfZm10dHknLCBGbXRfZm10dHlfRUJCIChmbXQnLCBmbXR0eScpKSA9XG4gICAgICB0eXBlX2lnbm9yZWRfZm9ybWF0X3N1YnN0aXR1dGlvbiBzdWJfZm10dHkgZm10IGZtdHR5IGluXG4gICAgRm10X2ZtdHR5X0VCQiAoSWdub3JlZF9wYXJhbSAoSWdub3JlZF9mb3JtYXRfc3Vic3QgKHBhZF9vcHQsIHN1Yl9mbXR0eScpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZtdCcpLFxuICAgICAgICAgICAgICAgICAgIGZtdHR5JylcbiAgfCBJZ25vcmVkX3JlYWRlciAtPiAoXG4gICAgbWF0Y2ggZm10dHkgd2l0aFxuICAgIHwgSWdub3JlZF9yZWFkZXJfdHkgZm10dHlfcmVzdCAtPlxuICAgICAgbGV0IEZtdF9mbXR0eV9FQkIgKGZtdCcsIGZtdHR5JykgPSB0eXBlX2Zvcm1hdF9nZW4gZm10IGZtdHR5X3Jlc3QgaW5cbiAgICAgIEZtdF9mbXR0eV9FQkIgKElnbm9yZWRfcGFyYW0gKElnbm9yZWRfcmVhZGVyLCBmbXQnKSwgZm10dHknKVxuICAgIHwgXyAtPiByYWlzZSBUeXBlX21pc21hdGNoXG4gIClcblxuYW5kIHR5cGVfaWdub3JlZF9wYXJhbV9vbmUgOiB0eXBlIGExIGEyIGIxIGIyIGMxIGMyIGQxIGQyIGUxIGUyIGYxIGYyIC5cbiAgICAoYTIsIGIyLCBjMiwgZDIsIGQyLCBhMikgaWdub3JlZCAtPlxuICAgIChhMSwgYjEsIGMxLCBkMSwgZTEsIGYxKSBmbXQgLT5cbiAgICAoYTIsIGIyLCBjMiwgZDIsIGUyLCBmMikgZm10dHkgLT5cbiAgICAoYTIsIGIyLCBjMiwgZDIsIGUyLCBmMikgZm10X2ZtdHR5X2ViYlxuPSBmdW4gaWduIGZtdCBmbXR0eSAtPlxuICBsZXQgRm10X2ZtdHR5X0VCQiAoZm10JywgZm10dHknKSA9IHR5cGVfZm9ybWF0X2dlbiBmbXQgZm10dHkgaW5cbiAgRm10X2ZtdHR5X0VCQiAoSWdub3JlZF9wYXJhbSAoaWduLCBmbXQnKSwgZm10dHknKVxuXG4oKiBUeXBpbmcgb2YgdGhlIGNvbXBsZXggY2FzZTogXCIlXyguLi4lKVwiLiAqKVxuYW5kIHR5cGVfaWdub3JlZF9mb3JtYXRfc3Vic3RpdHV0aW9uIDogdHlwZSB3IHggeSB6IHAgcyB0IHUgYSBiIGMgZCBlIGYgLlxuICAgICh3LCB4LCB5LCB6LCBzLCBwKSBmbXR0eSAtPlxuICAgIChwLCB4LCB5LCBzLCB0LCB1KSBmbXQgLT5cbiAgICAoYSwgYiwgYywgZCwgZSwgZikgZm10dHkgLT4gKGEsIGIsIGMsIGQsIGUsIGYpIGZtdHR5X2ZtdF9lYmIgPVxuZnVuIHN1Yl9mbXR0eSBmbXQgZm10dHkgLT4gbWF0Y2ggc3ViX2ZtdHR5LCBmbXR0eSB3aXRoXG4gIHwgQ2hhcl90eSBzdWJfZm10dHlfcmVzdCwgQ2hhcl90eSBmbXR0eV9yZXN0IC0+XG4gICAgbGV0IEZtdHR5X2ZtdF9FQkIgKHN1Yl9mbXR0eV9yZXN0JywgZm10JykgPVxuICAgICAgdHlwZV9pZ25vcmVkX2Zvcm1hdF9zdWJzdGl0dXRpb24gc3ViX2ZtdHR5X3Jlc3QgZm10IGZtdHR5X3Jlc3QgaW5cbiAgICBGbXR0eV9mbXRfRUJCIChDaGFyX3R5IHN1Yl9mbXR0eV9yZXN0JywgZm10JylcbiAgfCBTdHJpbmdfdHkgc3ViX2ZtdHR5X3Jlc3QsIFN0cmluZ190eSBmbXR0eV9yZXN0IC0+XG4gICAgbGV0IEZtdHR5X2ZtdF9FQkIgKHN1Yl9mbXR0eV9yZXN0JywgZm10JykgPVxuICAgICAgdHlwZV9pZ25vcmVkX2Zvcm1hdF9zdWJzdGl0dXRpb24gc3ViX2ZtdHR5X3Jlc3QgZm10IGZtdHR5X3Jlc3QgaW5cbiAgICBGbXR0eV9mbXRfRUJCIChTdHJpbmdfdHkgc3ViX2ZtdHR5X3Jlc3QnLCBmbXQnKVxuICB8IEludF90eSBzdWJfZm10dHlfcmVzdCwgSW50X3R5IGZtdHR5X3Jlc3QgLT5cbiAgICBsZXQgRm10dHlfZm10X0VCQiAoc3ViX2ZtdHR5X3Jlc3QnLCBmbXQnKSA9XG4gICAgICB0eXBlX2lnbm9yZWRfZm9ybWF0X3N1YnN0aXR1dGlvbiBzdWJfZm10dHlfcmVzdCBmbXQgZm10dHlfcmVzdCBpblxuICAgIEZtdHR5X2ZtdF9FQkIgKEludF90eSBzdWJfZm10dHlfcmVzdCcsIGZtdCcpXG4gIHwgSW50MzJfdHkgc3ViX2ZtdHR5X3Jlc3QsIEludDMyX3R5IGZtdHR5X3Jlc3QgLT5cbiAgICBsZXQgRm10dHlfZm10X0VCQiAoc3ViX2ZtdHR5X3Jlc3QnLCBmbXQnKSA9XG4gICAgICB0eXBlX2lnbm9yZWRfZm9ybWF0X3N1YnN0aXR1dGlvbiBzdWJfZm10dHlfcmVzdCBmbXQgZm10dHlfcmVzdCBpblxuICAgIEZtdHR5X2ZtdF9FQkIgKEludDMyX3R5IHN1Yl9mbXR0eV9yZXN0JywgZm10JylcbiAgfCBOYXRpdmVpbnRfdHkgc3ViX2ZtdHR5X3Jlc3QsIE5hdGl2ZWludF90eSBmbXR0eV9yZXN0IC0+XG4gICAgbGV0IEZtdHR5X2ZtdF9FQkIgKHN1Yl9mbXR0eV9yZXN0JywgZm10JykgPVxuICAgICAgdHlwZV9pZ25vcmVkX2Zvcm1hdF9zdWJzdGl0dXRpb24gc3ViX2ZtdHR5X3Jlc3QgZm10IGZtdHR5X3Jlc3QgaW5cbiAgICBGbXR0eV9mbXRfRUJCIChOYXRpdmVpbnRfdHkgc3ViX2ZtdHR5X3Jlc3QnLCBmbXQnKVxuICB8IEludDY0X3R5IHN1Yl9mbXR0eV9yZXN0LCBJbnQ2NF90eSBmbXR0eV9yZXN0IC0+XG4gICAgbGV0IEZtdHR5X2ZtdF9FQkIgKHN1Yl9mbXR0eV9yZXN0JywgZm10JykgPVxuICAgICAgdHlwZV9pZ25vcmVkX2Zvcm1hdF9zdWJzdGl0dXRpb24gc3ViX2ZtdHR5X3Jlc3QgZm10IGZtdHR5X3Jlc3QgaW5cbiAgICBGbXR0eV9mbXRfRUJCIChJbnQ2NF90eSBzdWJfZm10dHlfcmVzdCcsIGZtdCcpXG4gIHwgRmxvYXRfdHkgc3ViX2ZtdHR5X3Jlc3QsIEZsb2F0X3R5IGZtdHR5X3Jlc3QgLT5cbiAgICBsZXQgRm10dHlfZm10X0VCQiAoc3ViX2ZtdHR5X3Jlc3QnLCBmbXQnKSA9XG4gICAgICB0eXBlX2lnbm9yZWRfZm9ybWF0X3N1YnN0aXR1dGlvbiBzdWJfZm10dHlfcmVzdCBmbXQgZm10dHlfcmVzdCBpblxuICAgIEZtdHR5X2ZtdF9FQkIgKEZsb2F0X3R5IHN1Yl9mbXR0eV9yZXN0JywgZm10JylcbiAgfCBCb29sX3R5IHN1Yl9mbXR0eV9yZXN0LCBCb29sX3R5IGZtdHR5X3Jlc3QgLT5cbiAgICBsZXQgRm10dHlfZm10X0VCQiAoc3ViX2ZtdHR5X3Jlc3QnLCBmbXQnKSA9XG4gICAgICB0eXBlX2lnbm9yZWRfZm9ybWF0X3N1YnN0aXR1dGlvbiBzdWJfZm10dHlfcmVzdCBmbXQgZm10dHlfcmVzdCBpblxuICAgIEZtdHR5X2ZtdF9FQkIgKEJvb2xfdHkgc3ViX2ZtdHR5X3Jlc3QnLCBmbXQnKVxuICB8IEFscGhhX3R5IHN1Yl9mbXR0eV9yZXN0LCBBbHBoYV90eSBmbXR0eV9yZXN0IC0+XG4gICAgbGV0IEZtdHR5X2ZtdF9FQkIgKHN1Yl9mbXR0eV9yZXN0JywgZm10JykgPVxuICAgICAgdHlwZV9pZ25vcmVkX2Zvcm1hdF9zdWJzdGl0dXRpb24gc3ViX2ZtdHR5X3Jlc3QgZm10IGZtdHR5X3Jlc3QgaW5cbiAgICBGbXR0eV9mbXRfRUJCIChBbHBoYV90eSBzdWJfZm10dHlfcmVzdCcsIGZtdCcpXG4gIHwgVGhldGFfdHkgc3ViX2ZtdHR5X3Jlc3QsIFRoZXRhX3R5IGZtdHR5X3Jlc3QgLT5cbiAgICBsZXQgRm10dHlfZm10X0VCQiAoc3ViX2ZtdHR5X3Jlc3QnLCBmbXQnKSA9XG4gICAgICB0eXBlX2lnbm9yZWRfZm9ybWF0X3N1YnN0aXR1dGlvbiBzdWJfZm10dHlfcmVzdCBmbXQgZm10dHlfcmVzdCBpblxuICAgIEZtdHR5X2ZtdF9FQkIgKFRoZXRhX3R5IHN1Yl9mbXR0eV9yZXN0JywgZm10JylcbiAgfCBSZWFkZXJfdHkgc3ViX2ZtdHR5X3Jlc3QsIFJlYWRlcl90eSBmbXR0eV9yZXN0IC0+XG4gICAgbGV0IEZtdHR5X2ZtdF9FQkIgKHN1Yl9mbXR0eV9yZXN0JywgZm10JykgPVxuICAgICAgdHlwZV9pZ25vcmVkX2Zvcm1hdF9zdWJzdGl0dXRpb24gc3ViX2ZtdHR5X3Jlc3QgZm10IGZtdHR5X3Jlc3QgaW5cbiAgICBGbXR0eV9mbXRfRUJCIChSZWFkZXJfdHkgc3ViX2ZtdHR5X3Jlc3QnLCBmbXQnKVxuICB8IElnbm9yZWRfcmVhZGVyX3R5IHN1Yl9mbXR0eV9yZXN0LCBJZ25vcmVkX3JlYWRlcl90eSBmbXR0eV9yZXN0IC0+XG4gICAgbGV0IEZtdHR5X2ZtdF9FQkIgKHN1Yl9mbXR0eV9yZXN0JywgZm10JykgPVxuICAgICAgdHlwZV9pZ25vcmVkX2Zvcm1hdF9zdWJzdGl0dXRpb24gc3ViX2ZtdHR5X3Jlc3QgZm10IGZtdHR5X3Jlc3QgaW5cbiAgICBGbXR0eV9mbXRfRUJCIChJZ25vcmVkX3JlYWRlcl90eSBzdWJfZm10dHlfcmVzdCcsIGZtdCcpXG5cbiAgfCBGb3JtYXRfYXJnX3R5IChzdWIyX2ZtdHR5LCBzdWJfZm10dHlfcmVzdCksXG4gICAgRm9ybWF0X2FyZ190eSAoc3ViMl9mbXR0eScsIGZtdHR5X3Jlc3QpIC0+XG4gICAgaWYgRm10dHlfRUJCIHN1YjJfZm10dHkgPD4gRm10dHlfRUJCIHN1YjJfZm10dHknIHRoZW4gcmFpc2UgVHlwZV9taXNtYXRjaDtcbiAgICBsZXQgRm10dHlfZm10X0VCQiAoc3ViX2ZtdHR5X3Jlc3QnLCBmbXQnKSA9XG4gICAgICB0eXBlX2lnbm9yZWRfZm9ybWF0X3N1YnN0aXR1dGlvbiBzdWJfZm10dHlfcmVzdCBmbXQgZm10dHlfcmVzdCBpblxuICAgIEZtdHR5X2ZtdF9FQkIgKEZvcm1hdF9hcmdfdHkgKHN1YjJfZm10dHknLCBzdWJfZm10dHlfcmVzdCcpLCBmbXQnKVxuICB8IEZvcm1hdF9zdWJzdF90eSAoc3ViMV9mbXR0eSwgIHN1YjJfZm10dHksICBzdWJfZm10dHlfcmVzdCksXG4gICAgRm9ybWF0X3N1YnN0X3R5IChzdWIxX2ZtdHR5Jywgc3ViMl9mbXR0eScsIGZtdHR5X3Jlc3QpIC0+XG4gICAgKCogVE9ETyBkZWZpbmUgRm10dHlfcmVsX0VCQiB0byByZW1vdmUgdGhvc2UgZXJhc2VfcmVsICopXG4gICAgaWYgRm10dHlfRUJCIChlcmFzZV9yZWwgc3ViMV9mbXR0eSkgPD4gRm10dHlfRUJCIChlcmFzZV9yZWwgc3ViMV9mbXR0eScpXG4gICAgdGhlbiByYWlzZSBUeXBlX21pc21hdGNoO1xuICAgIGlmIEZtdHR5X0VCQiAoZXJhc2VfcmVsIHN1YjJfZm10dHkpIDw+IEZtdHR5X0VCQiAoZXJhc2VfcmVsIHN1YjJfZm10dHknKVxuICAgIHRoZW4gcmFpc2UgVHlwZV9taXNtYXRjaDtcbiAgICBsZXQgc3ViX2ZtdHR5JyA9IHRyYW5zIChzeW1tIHN1YjFfZm10dHknKSBzdWIyX2ZtdHR5JyBpblxuICAgIGxldCBfLCBmMiwgXywgZjQgPSBmbXR0eV9yZWxfZGV0IHN1Yl9mbXR0eScgaW5cbiAgICBsZXQgUmVmbCA9IGYyIFJlZmwgaW5cbiAgICBsZXQgUmVmbCA9IGY0IFJlZmwgaW5cbiAgICBsZXQgRm10dHlfZm10X0VCQiAoc3ViX2ZtdHR5X3Jlc3QnLCBmbXQnKSA9XG4gICAgICB0eXBlX2lnbm9yZWRfZm9ybWF0X3N1YnN0aXR1dGlvbiAoZXJhc2VfcmVsIHN1Yl9mbXR0eV9yZXN0KSBmbXQgZm10dHlfcmVzdFxuICAgIGluXG4gICAgRm10dHlfZm10X0VCQiAoRm9ybWF0X3N1YnN0X3R5IChzdWIxX2ZtdHR5Jywgc3ViMl9mbXR0eScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1tIHN1Yl9mbXR0eV9yZXN0JyksXG4gICAgICAgICAgICAgICAgICAgZm10JylcbiAgfCBFbmRfb2ZfZm10dHksIGZtdHR5IC0+XG4gICAgRm10dHlfZm10X0VCQiAoRW5kX29mX2ZtdHR5LCB0eXBlX2Zvcm1hdF9nZW4gZm10IGZtdHR5KVxuICB8IF8gLT4gcmFpc2UgVHlwZV9taXNtYXRjaFxuXG4oKiBUaGlzIGltcGxlbWVudGF0aW9uIG9mIGByZWNhc3RgIGlzIGEgYml0IGRpc2FwcG9pbnRpbmcuIFRoZVxuICAgaW52YXJpYW50IHByb3ZpZGVkIGJ5IHRoZSB0eXBlIGFyZSB2ZXJ5IHN0cm9uZzogdGhlIGlucHV0IGZvcm1hdCdzXG4gICB0eXBlIGlzIGluIHJlbGF0aW9uIHRvIHRoZSBvdXRwdXQgdHlwZSdzIGFzIHdpdG5lc3NlZCBieSB0aGVcbiAgIGZtdHR5X3JlbCBhcmd1bWVudC4gT25lIHdvdWxkIGF0IGZpcnN0IGV4cGVjdCB0aGlzIGZ1bmN0aW9uIHRvIGJlXG4gICB0b3RhbCwgYW5kIGltcGxlbWVudGFibGUgYnkgZXhoYXVzdGl2ZSBwYXR0ZXJuIG1hdGNoaW5nLiBJbnN0ZWFkLFxuICAgd2UgcmV1c2UgdGhlIGhpZ2hseSBwYXJ0aWFsIGFuZCBtdWNoIGxlc3Mgd2VsbC1kZWZpbmVkIGZ1bmN0aW9uXG4gICBgdHlwZV9mb3JtYXRgIHRoYXQgaGFzIGxvc3QgYWxsIGtub3dsZWRnZSBvZiB0aGUgY29ycmVzcG9uZGVuY2VcbiAgIGJldHdlZW4gdGhlIGFyZ3VtZW50J3MgdHlwZXMuXG5cbiAgIEJlc2lkZXMgdGhlIGZhY3QgdGhhdCB0aGlzIGZ1bmN0aW9uIHJldXNlcyBhIGxvdCBvZiB0aGVcbiAgIGB0eXBlX2Zvcm1hdGAgbG9naWMgKGVnLjogc2VlaW5nIEludF90eSBpbiB0aGUgZm10dHkgcGFyYW1ldGVyIGRvZXNcbiAgIG5vdCBsZXQgeW91IG1hdGNoIG9uIEludCBvbmx5LCBhcyB5b3UgbWF5IGluIGZhY3QgaGF2ZSBGbG9hdFxuICAgKEFyZ19wYWRkaW5nLCAuLi4pIChcIiUuKmRcIikgYmVnaW5uaW5nIHdpdGggYW4gSW50X3R5KSwgaXQgaXMgYWxzb1xuICAgYSBwYXJ0aWFsIGZ1bmN0aW9uLCBiZWNhdXNlIHRoZSB0eXBpbmcgaW5mb3JtYXRpb24gaW4gYSBmb3JtYXQgaXNcbiAgIG5vdCBxdWl0ZSBlbm91Z2ggdG8gcmVjb25zdHJ1Y3QgaXQgdW5hbWJpZ3VvdXNseS4gRm9yIGV4YW1wbGUsIHRoZVxuICAgZm9ybWF0IHR5cGVzIG9mIFwiJWQlX3JcIiBhbmQgXCIlX3IlZFwiIGhhdmUgdGhlIHNhbWUgZm9ybWF0NlxuICAgcGFyYW1ldGVycywgYnV0IHRoZXkgYXJlIG5vdCBhdCBhbGwgZXhjaGFuZ2VhYmxlLCBhbmQgcHV0dGluZyBvbmVcbiAgIGluIHBsYWNlIG9mIHRoZSBvdGhlciBtdXN0IHJlc3VsdCBpbiBhIGR5bmFtaWMgZmFpbHVyZS5cblxuICAgR2l2ZW4gdGhhdDpcbiAgIC0gd2UnZCBoYXZlIHRvIGR1cGxpY2F0ZSBhIGxvdCBvZiBub24tdHJpdmlhbCB0eXBpbmcgbG9naWMgZnJvbSB0eXBlX2Zvcm1hdFxuICAgLSB0aGlzIHdvdWxkbid0IGV2ZW4gZWxpbWluYXRlIChhbGwpIHRoZSBkeW5hbWljIGZhaWx1cmVzXG4gICB3ZSBkZWNpZGVkIHRvIGp1c3QgcmV1c2UgdHlwZV9mb3JtYXQgZGlyZWN0bHkgZm9yIG5vdy5cbiopXG5sZXQgcmVjYXN0IDpcbiAgdHlwZSBhMSBiMSBjMSBkMSBlMSBmMVxuICAgICAgIGEyIGIyIGMyIGQyIGUyIGYyXG4gIC5cbiAgICAgKGExLCBiMSwgYzEsIGQxLCBlMSwgZjEpIGZtdFxuICAtPiAoYTEsIGIxLCBjMSwgZDEsIGUxLCBmMSxcbiAgICAgIGEyLCBiMiwgYzIsIGQyLCBlMiwgZjIpIGZtdHR5X3JlbFxuICAtPiAoYTIsIGIyLCBjMiwgZDIsIGUyLCBmMikgZm10XG49IGZ1biBmbXQgZm10dHkgLT5cbiAgdHlwZV9mb3JtYXQgZm10IChlcmFzZV9yZWwgKHN5bW0gZm10dHkpKVxuXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiBQcmludGluZyB0b29scyAqKVxuXG4oKiBBZGQgcGFkZGluZyBzcGFjZXMgYXJvdW5kIGEgc3RyaW5nLiAqKVxubGV0IGZpeF9wYWRkaW5nIHBhZHR5IHdpZHRoIHN0ciA9XG4gIGxldCBsZW4gPSBTdHJpbmcubGVuZ3RoIHN0ciBpblxuICBsZXQgd2lkdGgsIHBhZHR5ID1cbiAgICBhYnMgd2lkdGgsXG4gICAgKCogd2hpbGUgbGl0ZXJhbCBwYWRkaW5nIHdpZHRocyBhcmUgYWx3YXlzIG5vbi1uZWdhdGl2ZSxcbiAgICAgICBkeW5hbWljYWxseS1zZXQgd2lkdGhzIChBcmdfcGFkZGluZywgZWcuICUqZCkgbWF5IGJlIG5lZ2F0aXZlO1xuICAgICAgIHdlIGludGVycHJldCB0aG9zZSBhcyBzcGVjaWZ5aW5nIGEgcGFkZGluZy10by10aGUtbGVmdDsgdGhpc1xuICAgICAgIG1lYW5zIHRoYXQgJzAnIG1heSBnZXQgZHJvcHBlZCBldmVuIGlmIGl0IHdhcyBleHBsaWNpdGx5IHNldCxcbiAgICAgICBidXQ6XG4gICAgICAgLSB0aGlzIGlzIHdoYXQgdGhlIGxlZ2FjeSBpbXBsZW1lbnRhdGlvbiBkb2VzLCBhbmRcbiAgICAgICAgIHdlIHByZXNlcnZlIGNvbXBhdGliaWxpdHkgaWYgcG9zc2libGVcbiAgICAgICAtIHdlIGNvdWxkIG9ubHkgc2lnbmFsIHRoaXMgaXNzdWUgYnkgZmFpbGluZyBhdCBydW50aW1lLFxuICAgICAgICAgd2hpY2ggaXMgbm90IHZlcnkgbmljZS4uLiAqKVxuICAgIGlmIHdpZHRoIDwgMCB0aGVuIExlZnQgZWxzZSBwYWR0eSBpblxuICBpZiB3aWR0aCA8PSBsZW4gdGhlbiBzdHIgZWxzZVxuICAgIGxldCByZXMgPSBCeXRlcy5tYWtlIHdpZHRoIChpZiBwYWR0eSA9IFplcm9zIHRoZW4gJzAnIGVsc2UgJyAnKSBpblxuICAgIGJlZ2luIG1hdGNoIHBhZHR5IHdpdGhcbiAgICB8IExlZnQgIC0+IFN0cmluZy5ibGl0IHN0ciAwIHJlcyAwIGxlblxuICAgIHwgUmlnaHQgLT4gU3RyaW5nLmJsaXQgc3RyIDAgcmVzICh3aWR0aCAtIGxlbikgbGVuXG4gICAgfCBaZXJvcyB3aGVuIGxlbiA+IDAgJiYgKHN0ci5bMF0gPSAnKycgfHwgc3RyLlswXSA9ICctJyB8fCBzdHIuWzBdID0gJyAnKSAtPlxuICAgICAgQnl0ZXMuc2V0IHJlcyAwIHN0ci5bMF07XG4gICAgICBTdHJpbmcuYmxpdCBzdHIgMSByZXMgKHdpZHRoIC0gbGVuICsgMSkgKGxlbiAtIDEpXG4gICAgfCBaZXJvcyB3aGVuIGxlbiA+IDEgJiYgc3RyLlswXSA9ICcwJyAmJiAoc3RyLlsxXSA9ICd4JyB8fCBzdHIuWzFdID0gJ1gnKSAtPlxuICAgICAgQnl0ZXMuc2V0IHJlcyAxIHN0ci5bMV07XG4gICAgICBTdHJpbmcuYmxpdCBzdHIgMiByZXMgKHdpZHRoIC0gbGVuICsgMikgKGxlbiAtIDIpXG4gICAgfCBaZXJvcyAtPlxuICAgICAgU3RyaW5nLmJsaXQgc3RyIDAgcmVzICh3aWR0aCAtIGxlbikgbGVuXG4gICAgZW5kO1xuICAgIEJ5dGVzLnVuc2FmZV90b19zdHJpbmcgcmVzXG5cbigqIEFkZCAnMCcgcGFkZGluZyB0byBpbnQsIGludDMyLCBuYXRpdmVpbnQgb3IgaW50NjQgc3RyaW5nIHJlcHJlc2VudGF0aW9uLiAqKVxubGV0IGZpeF9pbnRfcHJlY2lzaW9uIHByZWMgc3RyID1cbiAgbGV0IHByZWMgPSBhYnMgcHJlYyBpblxuICBsZXQgbGVuID0gU3RyaW5nLmxlbmd0aCBzdHIgaW5cbiAgbWF0Y2ggc3RyLlswXSB3aXRoXG4gIHwgKCcrJyB8ICctJyB8ICcgJykgYXMgYyB3aGVuIHByZWMgKyAxID4gbGVuIC0+XG4gICAgbGV0IHJlcyA9IEJ5dGVzLm1ha2UgKHByZWMgKyAxKSAnMCcgaW5cbiAgICBCeXRlcy5zZXQgcmVzIDAgYztcbiAgICBTdHJpbmcuYmxpdCBzdHIgMSByZXMgKHByZWMgLSBsZW4gKyAyKSAobGVuIC0gMSk7XG4gICAgQnl0ZXMudW5zYWZlX3RvX3N0cmluZyByZXNcbiAgfCAnMCcgd2hlbiBwcmVjICsgMiA+IGxlbiAmJiBsZW4gPiAxICYmIChzdHIuWzFdID0gJ3gnIHx8IHN0ci5bMV0gPSAnWCcpIC0+XG4gICAgbGV0IHJlcyA9IEJ5dGVzLm1ha2UgKHByZWMgKyAyKSAnMCcgaW5cbiAgICBCeXRlcy5zZXQgcmVzIDEgc3RyLlsxXTtcbiAgICBTdHJpbmcuYmxpdCBzdHIgMiByZXMgKHByZWMgLSBsZW4gKyA0KSAobGVuIC0gMik7XG4gICAgQnl0ZXMudW5zYWZlX3RvX3N0cmluZyByZXNcbiAgfCAnMCcgLi4gJzknIHwgJ2EnIC4uICdmJyB8ICdBJyAuLiAnRicgd2hlbiBwcmVjID4gbGVuIC0+XG4gICAgbGV0IHJlcyA9IEJ5dGVzLm1ha2UgcHJlYyAnMCcgaW5cbiAgICBTdHJpbmcuYmxpdCBzdHIgMCByZXMgKHByZWMgLSBsZW4pIGxlbjtcbiAgICBCeXRlcy51bnNhZmVfdG9fc3RyaW5nIHJlc1xuICB8IF8gLT5cbiAgICBzdHJcblxuKCogRXNjYXBlIGEgc3RyaW5nIGFjY29yZGluZyB0byB0aGUgT0NhbWwgbGV4aW5nIGNvbnZlbnRpb24uICopXG5sZXQgc3RyaW5nX3RvX2NhbWxfc3RyaW5nIHN0ciA9XG4gIGxldCBzdHIgPSBTdHJpbmcuZXNjYXBlZCBzdHIgaW5cbiAgbGV0IGwgPSBTdHJpbmcubGVuZ3RoIHN0ciBpblxuICBsZXQgcmVzID0gQnl0ZXMubWFrZSAobCArIDIpICdcXFwiJyBpblxuICBTdHJpbmcudW5zYWZlX2JsaXQgc3RyIDAgcmVzIDEgbDtcbiAgQnl0ZXMudW5zYWZlX3RvX3N0cmluZyByZXNcblxuKCogR2VuZXJhdGUgdGhlIGZvcm1hdF9pbnQvaW50MzIvbmF0aXZlaW50L2ludDY0IGZpcnN0IGFyZ3VtZW50XG4gICBmcm9tIGFuIGludF9jb252LiAqKVxubGV0IGZvcm1hdF9vZl9pY29udiA9IGZ1bmN0aW9uXG4gIHwgSW50X2QgfCBJbnRfQ2QgLT4gXCIlZFwiIHwgSW50X3BkIC0+IFwiJStkXCIgfCBJbnRfc2QgLT4gXCIlIGRcIlxuICB8IEludF9pIHwgSW50X0NpIC0+IFwiJWlcIiB8IEludF9waSAtPiBcIiUraVwiIHwgSW50X3NpIC0+IFwiJSBpXCJcbiAgfCBJbnRfeCAtPiBcIiV4XCIgfCBJbnRfQ3ggLT4gXCIlI3hcIlxuICB8IEludF9YIC0+IFwiJVhcIiB8IEludF9DWCAtPiBcIiUjWFwiXG4gIHwgSW50X28gLT4gXCIlb1wiIHwgSW50X0NvIC0+IFwiJSNvXCJcbiAgfCBJbnRfdSB8IEludF9DdSAtPiBcIiV1XCJcblxubGV0IGZvcm1hdF9vZl9pY29udkwgPSBmdW5jdGlvblxuICB8IEludF9kIHwgSW50X0NkIC0+IFwiJUxkXCIgfCBJbnRfcGQgLT4gXCIlK0xkXCIgfCBJbnRfc2QgLT4gXCIlIExkXCJcbiAgfCBJbnRfaSB8IEludF9DaSAtPiBcIiVMaVwiIHwgSW50X3BpIC0+IFwiJStMaVwiIHwgSW50X3NpIC0+IFwiJSBMaVwiXG4gIHwgSW50X3ggLT4gXCIlTHhcIiB8IEludF9DeCAtPiBcIiUjTHhcIlxuICB8IEludF9YIC0+IFwiJUxYXCIgfCBJbnRfQ1ggLT4gXCIlI0xYXCJcbiAgfCBJbnRfbyAtPiBcIiVMb1wiIHwgSW50X0NvIC0+IFwiJSNMb1wiXG4gIHwgSW50X3UgfCBJbnRfQ3UgLT4gXCIlTHVcIlxuXG5sZXQgZm9ybWF0X29mX2ljb252bCA9IGZ1bmN0aW9uXG4gIHwgSW50X2QgfCBJbnRfQ2QgLT4gXCIlbGRcIiB8IEludF9wZCAtPiBcIiUrbGRcIiB8IEludF9zZCAtPiBcIiUgbGRcIlxuICB8IEludF9pIHwgSW50X0NpIC0+IFwiJWxpXCIgfCBJbnRfcGkgLT4gXCIlK2xpXCIgfCBJbnRfc2kgLT4gXCIlIGxpXCJcbiAgfCBJbnRfeCAtPiBcIiVseFwiIHwgSW50X0N4IC0+IFwiJSNseFwiXG4gIHwgSW50X1ggLT4gXCIlbFhcIiB8IEludF9DWCAtPiBcIiUjbFhcIlxuICB8IEludF9vIC0+IFwiJWxvXCIgfCBJbnRfQ28gLT4gXCIlI2xvXCJcbiAgfCBJbnRfdSB8IEludF9DdSAtPiBcIiVsdVwiXG5cbmxldCBmb3JtYXRfb2ZfaWNvbnZuID0gZnVuY3Rpb25cbiAgfCBJbnRfZCB8IEludF9DZCAtPiBcIiVuZFwiIHwgSW50X3BkIC0+IFwiJStuZFwiIHwgSW50X3NkIC0+IFwiJSBuZFwiXG4gIHwgSW50X2kgfCBJbnRfQ2kgLT4gXCIlbmlcIiB8IEludF9waSAtPiBcIiUrbmlcIiB8IEludF9zaSAtPiBcIiUgbmlcIlxuICB8IEludF94IC0+IFwiJW54XCIgfCBJbnRfQ3ggLT4gXCIlI254XCJcbiAgfCBJbnRfWCAtPiBcIiVuWFwiIHwgSW50X0NYIC0+IFwiJSNuWFwiXG4gIHwgSW50X28gLT4gXCIlbm9cIiB8IEludF9DbyAtPiBcIiUjbm9cIlxuICB8IEludF91IHwgSW50X0N1IC0+IFwiJW51XCJcblxuKCogR2VuZXJhdGUgdGhlIGZvcm1hdF9mbG9hdCBmaXJzdCBhcmd1bWVudCBmcm9tIGEgZmxvYXRfY29udi4gKilcbmxldCBmb3JtYXRfb2ZfZmNvbnYgZmNvbnYgcHJlYyA9XG4gICAgbGV0IHByZWMgPSBhYnMgcHJlYyBpblxuICAgIGxldCBzeW1iID0gY2hhcl9vZl9mY29udiB+Y0Y6J2cnIGZjb252IGluXG4gICAgbGV0IGJ1ZiA9IGJ1ZmZlcl9jcmVhdGUgMTYgaW5cbiAgICBidWZmZXJfYWRkX2NoYXIgYnVmICclJztcbiAgICBicHJpbnRfZmNvbnZfZmxhZyBidWYgZmNvbnY7XG4gICAgYnVmZmVyX2FkZF9jaGFyIGJ1ZiAnLic7XG4gICAgYnVmZmVyX2FkZF9zdHJpbmcgYnVmIChJbnQudG9fc3RyaW5nIHByZWMpO1xuICAgIGJ1ZmZlcl9hZGRfY2hhciBidWYgc3ltYjtcbiAgICBidWZmZXJfY29udGVudHMgYnVmXG5cbmxldCB0cmFuc2Zvcm1faW50X2FsdCBpY29udiBzID1cbiAgbWF0Y2ggaWNvbnYgd2l0aFxuICB8IEludF9DZCB8IEludF9DaSB8IEludF9DdSAtPlxuICAgIGxldCBkaWdpdHMgPVxuICAgICAgbGV0IG4gPSByZWYgMCBpblxuICAgICAgZm9yIGkgPSAwIHRvIFN0cmluZy5sZW5ndGggcyAtIDEgZG9cbiAgICAgICAgbWF0Y2ggU3RyaW5nLnVuc2FmZV9nZXQgcyBpIHdpdGhcbiAgICAgICAgfCAnMCcuLic5JyAtPiBpbmNyIG5cbiAgICAgICAgfCBfIC0+ICgpXG4gICAgICBkb25lO1xuICAgICAgIW5cbiAgICBpblxuICAgIGxldCBidWYgPSBCeXRlcy5jcmVhdGUgKFN0cmluZy5sZW5ndGggcyArIChkaWdpdHMgLSAxKSAvIDMpIGluXG4gICAgbGV0IHBvcyA9IHJlZiAwIGluXG4gICAgbGV0IHB1dCBjID0gQnl0ZXMuc2V0IGJ1ZiAhcG9zIGM7IGluY3IgcG9zIGluXG4gICAgbGV0IGxlZnQgPSByZWYgKChkaWdpdHMgLSAxKSBtb2QgMyArIDEpIGluXG4gICAgZm9yIGkgPSAwIHRvIFN0cmluZy5sZW5ndGggcyAtIDEgZG9cbiAgICAgIG1hdGNoIFN0cmluZy51bnNhZmVfZ2V0IHMgaSB3aXRoXG4gICAgICB8ICcwJy4uJzknIGFzIGMgLT5cbiAgICAgICAgICBpZiAhbGVmdCA9IDAgdGhlbiAocHV0ICdfJzsgbGVmdCA6PSAzKTsgZGVjciBsZWZ0OyBwdXQgY1xuICAgICAgfCBjIC0+IHB1dCBjXG4gICAgZG9uZTtcbiAgICBCeXRlcy51bnNhZmVfdG9fc3RyaW5nIGJ1ZlxuICB8IF8gLT4gc1xuXG4oKiBDb252ZXJ0IGFuIGludGVnZXIgdG8gYSBzdHJpbmcgYWNjb3JkaW5nIHRvIGEgY29udmVyc2lvbi4gKilcbmxldCBjb252ZXJ0X2ludCBpY29udiBuID1cbiAgdHJhbnNmb3JtX2ludF9hbHQgaWNvbnYgKGZvcm1hdF9pbnQgKGZvcm1hdF9vZl9pY29udiBpY29udikgbilcbmxldCBjb252ZXJ0X2ludDMyIGljb252IG4gPVxuICB0cmFuc2Zvcm1faW50X2FsdCBpY29udiAoZm9ybWF0X2ludDMyIChmb3JtYXRfb2ZfaWNvbnZsIGljb252KSBuKVxubGV0IGNvbnZlcnRfbmF0aXZlaW50IGljb252IG4gPVxuICB0cmFuc2Zvcm1faW50X2FsdCBpY29udiAoZm9ybWF0X25hdGl2ZWludCAoZm9ybWF0X29mX2ljb252biBpY29udikgbilcbmxldCBjb252ZXJ0X2ludDY0IGljb252IG4gPVxuICB0cmFuc2Zvcm1faW50X2FsdCBpY29udiAoZm9ybWF0X2ludDY0IChmb3JtYXRfb2ZfaWNvbnZMIGljb252KSBuKVxuXG4oKiBDb252ZXJ0IGEgZmxvYXQgdG8gc3RyaW5nLiAqKVxuKCogRml4IHNwZWNpYWwgY2FzZSBvZiBcIk9DYW1sIGZsb2F0IGZvcm1hdFwiLiAqKVxubGV0IGNvbnZlcnRfZmxvYXQgZmNvbnYgcHJlYyB4ID1cbiAgbGV0IGhleCAoKSA9XG4gICAgbGV0IHNpZ24gPVxuICAgICAgbWF0Y2ggZnN0IGZjb252IHdpdGhcbiAgICAgIHwgRmxvYXRfZmxhZ19wIC0+ICcrJ1xuICAgICAgfCBGbG9hdF9mbGFnX3MgLT4gJyAnXG4gICAgICB8IF8gLT4gJy0nIGluXG4gICAgaGV4c3RyaW5nX29mX2Zsb2F0IHggcHJlYyBzaWduIGluXG4gIGxldCBhZGRfZG90X2lmX25lZWRlZCBzdHIgPVxuICAgIGxldCBsZW4gPSBTdHJpbmcubGVuZ3RoIHN0ciBpblxuICAgIGxldCByZWMgaXNfdmFsaWQgaSA9XG4gICAgICBpZiBpID0gbGVuIHRoZW4gZmFsc2UgZWxzZVxuICAgICAgICBtYXRjaCBzdHIuW2ldIHdpdGhcbiAgICAgICAgfCAnLicgfCAnZScgfCAnRScgLT4gdHJ1ZVxuICAgICAgICB8IF8gLT4gaXNfdmFsaWQgKGkgKyAxKSBpblxuICAgIGlmIGlzX3ZhbGlkIDAgdGhlbiBzdHIgZWxzZSBzdHIgXiBcIi5cIiBpblxuICBsZXQgY2FtbF9zcGVjaWFsX3ZhbCBzdHIgPSBtYXRjaCBjbGFzc2lmeV9mbG9hdCB4IHdpdGhcbiAgICB8IEZQX25vcm1hbCB8IEZQX3N1Ym5vcm1hbCB8IEZQX3plcm8gLT4gc3RyXG4gICAgfCBGUF9pbmZpbml0ZSAtPiBpZiB4IDwgMC4wIHRoZW4gXCJuZWdfaW5maW5pdHlcIiBlbHNlIFwiaW5maW5pdHlcIlxuICAgIHwgRlBfbmFuIC0+IFwibmFuXCIgaW5cbiAgbWF0Y2ggc25kIGZjb252IHdpdGhcbiAgfCBGbG9hdF9oIC0+IGhleCAoKVxuICB8IEZsb2F0X0ggLT4gU3RyaW5nLnVwcGVyY2FzZV9hc2NpaSAoaGV4ICgpKVxuICB8IEZsb2F0X0NGIC0+IGNhbWxfc3BlY2lhbF92YWwgKGhleCAoKSlcbiAgfCBGbG9hdF9GIC0+XG4gICAgbGV0IHN0ciA9IGZvcm1hdF9mbG9hdCAoZm9ybWF0X29mX2Zjb252IGZjb252IHByZWMpIHggaW5cbiAgICBjYW1sX3NwZWNpYWxfdmFsIChhZGRfZG90X2lmX25lZWRlZCBzdHIpXG4gIHwgRmxvYXRfZiB8IEZsb2F0X2UgfCBGbG9hdF9FIHwgRmxvYXRfZyB8IEZsb2F0X0cgLT5cbiAgICBmb3JtYXRfZmxvYXQgKGZvcm1hdF9vZl9mY29udiBmY29udiBwcmVjKSB4XG5cbigqIENvbnZlcnQgYSBjaGFyIHRvIGEgc3RyaW5nIGFjY29yZGluZyB0byB0aGUgT0NhbWwgbGV4aWNhbCBjb252ZW50aW9uLiAqKVxubGV0IGZvcm1hdF9jYW1sX2NoYXIgYyA9XG4gIGxldCBzdHIgPSBDaGFyLmVzY2FwZWQgYyBpblxuICBsZXQgbCA9IFN0cmluZy5sZW5ndGggc3RyIGluXG4gIGxldCByZXMgPSBCeXRlcy5tYWtlIChsICsgMikgJ1xcJycgaW5cbiAgU3RyaW5nLnVuc2FmZV9ibGl0IHN0ciAwIHJlcyAxIGw7XG4gIEJ5dGVzLnVuc2FmZV90b19zdHJpbmcgcmVzXG5cbigqIENvbnZlcnQgYSBmb3JtYXQgdHlwZSB0byBzdHJpbmcgKilcbmxldCBzdHJpbmdfb2ZfZm10dHkgZm10dHkgPVxuICBsZXQgYnVmID0gYnVmZmVyX2NyZWF0ZSAxNiBpblxuICBicHJpbnRfZm10dHkgYnVmIGZtdHR5O1xuICBidWZmZXJfY29udGVudHMgYnVmXG5cbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4gICAgICAgICAgICAgICAgICAgICAgICAoKiBHZW5lcmljIHByaW50aW5nIGZ1bmN0aW9uICopXG5cbigqIE1ha2UgYSBnZW5lcmljIHByaW50aW5nIGZ1bmN0aW9uLiAqKVxuKCogVXNlZCB0byBnZW5lcmF0ZSBQcmludGYgYW5kIEZvcm1hdCBwcmludGluZyBmdW5jdGlvbnMuICopXG4oKiBQYXJhbWV0ZXJzOlxuICAgICBrOiBhIGNvbnRpbnVhdGlvbiBmaW5hbGx5IGFwcGxpZWQgdG8gdGhlIG91dHB1dCBzdHJlYW0gYW5kIHRoZSBhY2N1bXVsYXRvci5cbiAgICAgbzogdGhlIG91dHB1dCBzdHJlYW0gKHNlZSBrLCAlYSBhbmQgJXQpLlxuICAgICBhY2M6IHJldiBsaXN0IG9mIHByaW50aW5nIGVudGl0aWVzIChzdHJpbmcsIGNoYXIsIGZsdXNoLCBmb3JtYXR0aW5nLCAuLi4pLlxuICAgICBmbXQ6IHRoZSBmb3JtYXQuICopXG5sZXQgcmVjIG1ha2VfcHJpbnRmIDogdHlwZSBhIGIgYyBkIGUgZiAuXG4gICAgKChiLCBjKSBhY2MgLT4gZikgLT4gKGIsIGMpIGFjYyAtPlxuICAgIChhLCBiLCBjLCBkLCBlLCBmKSBmbXQgLT4gYSA9XG5mdW4gayBhY2MgZm10IC0+IG1hdGNoIGZtdCB3aXRoXG4gIHwgQ2hhciByZXN0IC0+XG4gICAgZnVuIGMgLT5cbiAgICAgIGxldCBuZXdfYWNjID0gQWNjX2RhdGFfY2hhciAoYWNjLCBjKSBpblxuICAgICAgbWFrZV9wcmludGYgayBuZXdfYWNjIHJlc3RcbiAgfCBDYW1sX2NoYXIgcmVzdCAtPlxuICAgIGZ1biBjIC0+XG4gICAgICBsZXQgbmV3X2FjYyA9IEFjY19kYXRhX3N0cmluZyAoYWNjLCBmb3JtYXRfY2FtbF9jaGFyIGMpIGluXG4gICAgICBtYWtlX3ByaW50ZiBrIG5ld19hY2MgcmVzdFxuICB8IFN0cmluZyAocGFkLCByZXN0KSAtPlxuICAgIG1ha2VfcGFkZGluZyBrIGFjYyByZXN0IHBhZCAoZnVuIHN0ciAtPiBzdHIpXG4gIHwgQ2FtbF9zdHJpbmcgKHBhZCwgcmVzdCkgLT5cbiAgICBtYWtlX3BhZGRpbmcgayBhY2MgcmVzdCBwYWQgc3RyaW5nX3RvX2NhbWxfc3RyaW5nXG4gIHwgSW50IChpY29udiwgcGFkLCBwcmVjLCByZXN0KSAtPlxuICAgIG1ha2VfaW50X3BhZGRpbmdfcHJlY2lzaW9uIGsgYWNjIHJlc3QgcGFkIHByZWMgY29udmVydF9pbnQgaWNvbnZcbiAgfCBJbnQzMiAoaWNvbnYsIHBhZCwgcHJlYywgcmVzdCkgLT5cbiAgICBtYWtlX2ludF9wYWRkaW5nX3ByZWNpc2lvbiBrIGFjYyByZXN0IHBhZCBwcmVjIGNvbnZlcnRfaW50MzIgaWNvbnZcbiAgfCBOYXRpdmVpbnQgKGljb252LCBwYWQsIHByZWMsIHJlc3QpIC0+XG4gICAgbWFrZV9pbnRfcGFkZGluZ19wcmVjaXNpb24gayBhY2MgcmVzdCBwYWQgcHJlYyBjb252ZXJ0X25hdGl2ZWludCBpY29udlxuICB8IEludDY0IChpY29udiwgcGFkLCBwcmVjLCByZXN0KSAtPlxuICAgIG1ha2VfaW50X3BhZGRpbmdfcHJlY2lzaW9uIGsgYWNjIHJlc3QgcGFkIHByZWMgY29udmVydF9pbnQ2NCBpY29udlxuICB8IEZsb2F0IChmY29udiwgcGFkLCBwcmVjLCByZXN0KSAtPlxuICAgIG1ha2VfZmxvYXRfcGFkZGluZ19wcmVjaXNpb24gayBhY2MgcmVzdCBwYWQgcHJlYyBmY29udlxuICB8IEJvb2wgKHBhZCwgcmVzdCkgLT5cbiAgICBtYWtlX3BhZGRpbmcgayBhY2MgcmVzdCBwYWQgc3RyaW5nX29mX2Jvb2xcbiAgfCBBbHBoYSByZXN0IC0+XG4gICAgZnVuIGYgeCAtPiBtYWtlX3ByaW50ZiBrIChBY2NfZGVsYXkgKGFjYywgZnVuIG8gLT4gZiBvIHgpKSByZXN0XG4gIHwgVGhldGEgcmVzdCAtPlxuICAgIGZ1biBmIC0+IG1ha2VfcHJpbnRmIGsgKEFjY19kZWxheSAoYWNjLCBmKSkgcmVzdFxuICB8IEN1c3RvbSAoYXJpdHksIGYsIHJlc3QpIC0+XG4gICAgbWFrZV9jdXN0b20gayBhY2MgcmVzdCBhcml0eSAoZiAoKSlcbiAgfCBSZWFkZXIgXyAtPlxuICAgICgqIFRoaXMgY2FzZSBpcyBpbXBvc3NpYmxlLCBieSB0eXBpbmcgb2YgZm9ybWF0cy4gKilcbiAgICAoKiBJbmRlZWQsIHNpbmNlIHByaW50ZiBhbmQgY28uIHRha2UgYSBmb3JtYXQ0IGFzIGFyZ3VtZW50LCB0aGUgJ2QgYW5kICdlXG4gICAgICAgdHlwZSBwYXJhbWV0ZXJzIG9mIGZtdCBhcmUgb2J2aW91c2x5IGVxdWFscy4gVGhlIFJlYWRlciBpcyB0aGVcbiAgICAgICBvbmx5IGNvbnN0cnVjdG9yIHdoaWNoIHRvdWNoICdkIGFuZCAnZSB0eXBlIHBhcmFtZXRlcnMgb2YgdGhlIGZvcm1hdFxuICAgICAgIHR5cGUsIGl0IGFkZHMgYW4gKC0+KSB0byB0aGUgJ2QgcGFyYW1ldGVycy4gQ29uc2VxdWVudGx5LCBhIGZvcm1hdDRcbiAgICAgICBjYW5ub3QgY29udGFpbiBhIFJlYWRlciBub2RlLCBleGNlcHQgaW4gdGhlIHN1Yi1mb3JtYXQgYXNzb2NpYXRlZCB0b1xuICAgICAgIGFuICV7Li4uJX0uIEl0J3Mgbm90IGEgcHJvYmxlbSBiZWNhdXNlIG1ha2VfcHJpbnRmIGRvIG5vdCBjYWxsXG4gICAgICAgaXRzZWxmIHJlY3Vyc2l2ZWx5IG9uIHRoZSBzdWItZm9ybWF0IGFzc29jaWF0ZWQgdG8gJXsuLi4lfS4gKilcbiAgICBhc3NlcnQgZmFsc2VcbiAgfCBGbHVzaCByZXN0IC0+XG4gICAgbWFrZV9wcmludGYgayAoQWNjX2ZsdXNoIGFjYykgcmVzdFxuXG4gIHwgU3RyaW5nX2xpdGVyYWwgKHN0ciwgcmVzdCkgLT5cbiAgICBtYWtlX3ByaW50ZiBrIChBY2Nfc3RyaW5nX2xpdGVyYWwgKGFjYywgc3RyKSkgcmVzdFxuICB8IENoYXJfbGl0ZXJhbCAoY2hyLCByZXN0KSAtPlxuICAgIG1ha2VfcHJpbnRmIGsgKEFjY19jaGFyX2xpdGVyYWwgKGFjYywgY2hyKSkgcmVzdFxuXG4gIHwgRm9ybWF0X2FyZyAoXywgc3ViX2ZtdHR5LCByZXN0KSAtPlxuICAgIGxldCB0eSA9IHN0cmluZ19vZl9mbXR0eSBzdWJfZm10dHkgaW5cbiAgICAoZnVuIHN0ciAtPlxuICAgICAgaWdub3JlIHN0cjtcbiAgICAgIG1ha2VfcHJpbnRmIGsgKEFjY19kYXRhX3N0cmluZyAoYWNjLCB0eSkpIHJlc3QpXG4gIHwgRm9ybWF0X3N1YnN0IChfLCBmbXR0eSwgcmVzdCkgLT5cbiAgICBmdW4gKEZvcm1hdCAoZm10LCBfKSkgLT4gbWFrZV9wcmludGYgayBhY2NcbiAgICAgIChjb25jYXRfZm10IChyZWNhc3QgZm10IGZtdHR5KSByZXN0KVxuXG4gIHwgU2Nhbl9jaGFyX3NldCAoXywgXywgcmVzdCkgLT5cbiAgICBsZXQgbmV3X2FjYyA9IEFjY19pbnZhbGlkX2FyZyAoYWNjLCBcIlByaW50ZjogYmFkIGNvbnZlcnNpb24gJVtcIikgaW5cbiAgICBmdW4gXyAtPiBtYWtlX3ByaW50ZiBrIG5ld19hY2MgcmVzdFxuICB8IFNjYW5fZ2V0X2NvdW50ZXIgKF8sIHJlc3QpIC0+XG4gICAgKCogVGhpcyBjYXNlIHNob3VsZCBiZSByZWZ1c2VkIGZvciBQcmludGYuICopXG4gICAgKCogQWNjZXB0ZWQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkuICopXG4gICAgKCogSW50ZXJwcmV0ICVsLCAlbiBhbmQgJUwgYXMgJXUuICopXG4gICAgZnVuIG4gLT5cbiAgICAgIGxldCBuZXdfYWNjID0gQWNjX2RhdGFfc3RyaW5nIChhY2MsIGZvcm1hdF9pbnQgXCIldVwiIG4pIGluXG4gICAgICBtYWtlX3ByaW50ZiBrIG5ld19hY2MgcmVzdFxuICB8IFNjYW5fbmV4dF9jaGFyIHJlc3QgLT5cbiAgICBmdW4gYyAtPlxuICAgICAgbGV0IG5ld19hY2MgPSBBY2NfZGF0YV9jaGFyIChhY2MsIGMpIGluXG4gICAgICBtYWtlX3ByaW50ZiBrIG5ld19hY2MgcmVzdFxuICB8IElnbm9yZWRfcGFyYW0gKGlnbiwgcmVzdCkgLT5cbiAgICBtYWtlX2lnbm9yZWRfcGFyYW0gayBhY2MgaWduIHJlc3RcblxuICB8IEZvcm1hdHRpbmdfbGl0IChmbXRpbmdfbGl0LCByZXN0KSAtPlxuICAgIG1ha2VfcHJpbnRmIGsgKEFjY19mb3JtYXR0aW5nX2xpdCAoYWNjLCBmbXRpbmdfbGl0KSkgcmVzdFxuICB8IEZvcm1hdHRpbmdfZ2VuIChPcGVuX3RhZyAoRm9ybWF0IChmbXQnLCBfKSksIHJlc3QpIC0+XG4gICAgbGV0IGsnIGthY2MgPVxuICAgICAgbWFrZV9wcmludGYgayAoQWNjX2Zvcm1hdHRpbmdfZ2VuIChhY2MsIEFjY19vcGVuX3RhZyBrYWNjKSkgcmVzdCBpblxuICAgIG1ha2VfcHJpbnRmIGsnIEVuZF9vZl9hY2MgZm10J1xuICB8IEZvcm1hdHRpbmdfZ2VuIChPcGVuX2JveCAoRm9ybWF0IChmbXQnLCBfKSksIHJlc3QpIC0+XG4gICAgbGV0IGsnIGthY2MgPVxuICAgICAgbWFrZV9wcmludGYgayAoQWNjX2Zvcm1hdHRpbmdfZ2VuIChhY2MsIEFjY19vcGVuX2JveCBrYWNjKSkgcmVzdCBpblxuICAgIG1ha2VfcHJpbnRmIGsnIEVuZF9vZl9hY2MgZm10J1xuXG4gIHwgRW5kX29mX2Zvcm1hdCAtPlxuICAgIGsgYWNjXG5cbigqIERlbGF5IHRoZSBlcnJvciAoSW52YWxpZF9hcmd1bWVudCBcIlByaW50ZjogYmFkIGNvbnZlcnNpb24gJV9cIikuICopXG4oKiBHZW5lcmF0ZSBmdW5jdGlvbnMgdG8gdGFrZSByZW1haW5pbmcgYXJndW1lbnRzIChhZnRlciB0aGUgXCIlX1wiKS4gKilcbmFuZCBtYWtlX2lnbm9yZWRfcGFyYW0gOiB0eXBlIHggeSBhIGIgYyBkIGUgZiAuXG4gICAgKChiLCBjKSBhY2MgLT4gZikgLT4gKGIsIGMpIGFjYyAtPlxuICAgIChhLCBiLCBjLCBkLCB5LCB4KSBpZ25vcmVkIC0+XG4gICAgKHgsIGIsIGMsIHksIGUsIGYpIGZtdCAtPiBhID1cbmZ1biBrIGFjYyBpZ24gZm10IC0+IG1hdGNoIGlnbiB3aXRoXG4gIHwgSWdub3JlZF9jaGFyICAgICAgICAgICAgICAgICAgICAtPiBtYWtlX2ludmFsaWRfYXJnIGsgYWNjIGZtdFxuICB8IElnbm9yZWRfY2FtbF9jaGFyICAgICAgICAgICAgICAgLT4gbWFrZV9pbnZhbGlkX2FyZyBrIGFjYyBmbXRcbiAgfCBJZ25vcmVkX3N0cmluZyBfICAgICAgICAgICAgICAgIC0+IG1ha2VfaW52YWxpZF9hcmcgayBhY2MgZm10XG4gIHwgSWdub3JlZF9jYW1sX3N0cmluZyBfICAgICAgICAgICAtPiBtYWtlX2ludmFsaWRfYXJnIGsgYWNjIGZtdFxuICB8IElnbm9yZWRfaW50IChfLCBfKSAgICAgICAgICAgICAgLT4gbWFrZV9pbnZhbGlkX2FyZyBrIGFjYyBmbXRcbiAgfCBJZ25vcmVkX2ludDMyIChfLCBfKSAgICAgICAgICAgIC0+IG1ha2VfaW52YWxpZF9hcmcgayBhY2MgZm10XG4gIHwgSWdub3JlZF9uYXRpdmVpbnQgKF8sIF8pICAgICAgICAtPiBtYWtlX2ludmFsaWRfYXJnIGsgYWNjIGZtdFxuICB8IElnbm9yZWRfaW50NjQgKF8sIF8pICAgICAgICAgICAgLT4gbWFrZV9pbnZhbGlkX2FyZyBrIGFjYyBmbXRcbiAgfCBJZ25vcmVkX2Zsb2F0IChfLCBfKSAgICAgICAgICAgIC0+IG1ha2VfaW52YWxpZF9hcmcgayBhY2MgZm10XG4gIHwgSWdub3JlZF9ib29sIF8gICAgICAgICAgICAgICAgICAtPiBtYWtlX2ludmFsaWRfYXJnIGsgYWNjIGZtdFxuICB8IElnbm9yZWRfZm9ybWF0X2FyZyBfICAgICAgICAgICAgLT4gbWFrZV9pbnZhbGlkX2FyZyBrIGFjYyBmbXRcbiAgfCBJZ25vcmVkX2Zvcm1hdF9zdWJzdCAoXywgZm10dHkpIC0+IG1ha2VfZnJvbV9mbXR0eSBrIGFjYyBmbXR0eSBmbXRcbiAgfCBJZ25vcmVkX3JlYWRlciAgICAgICAgICAgICAgICAgIC0+IGFzc2VydCBmYWxzZVxuICB8IElnbm9yZWRfc2Nhbl9jaGFyX3NldCBfICAgICAgICAgLT4gbWFrZV9pbnZhbGlkX2FyZyBrIGFjYyBmbXRcbiAgfCBJZ25vcmVkX3NjYW5fZ2V0X2NvdW50ZXIgXyAgICAgIC0+IG1ha2VfaW52YWxpZF9hcmcgayBhY2MgZm10XG4gIHwgSWdub3JlZF9zY2FuX25leHRfY2hhciAgICAgICAgICAtPiBtYWtlX2ludmFsaWRfYXJnIGsgYWNjIGZtdFxuXG5cbigqIFNwZWNpYWwgY2FzZSBvZiBwcmludGYgXCIlXyhcIi4gKilcbmFuZCBtYWtlX2Zyb21fZm10dHkgOiB0eXBlIHggeSBhIGIgYyBkIGUgZiAuXG4gICAgKChiLCBjKSBhY2MgLT4gZikgLT4gKGIsIGMpIGFjYyAtPlxuICAgIChhLCBiLCBjLCBkLCB5LCB4KSBmbXR0eSAtPlxuICAgICh4LCBiLCBjLCB5LCBlLCBmKSBmbXQgLT4gYSA9XG5mdW4gayBhY2MgZm10dHkgZm10IC0+IG1hdGNoIGZtdHR5IHdpdGhcbiAgfCBDaGFyX3R5IHJlc3QgICAgICAgICAgICAtPiBmdW4gXyAtPiBtYWtlX2Zyb21fZm10dHkgayBhY2MgcmVzdCBmbXRcbiAgfCBTdHJpbmdfdHkgcmVzdCAgICAgICAgICAtPiBmdW4gXyAtPiBtYWtlX2Zyb21fZm10dHkgayBhY2MgcmVzdCBmbXRcbiAgfCBJbnRfdHkgcmVzdCAgICAgICAgICAgICAtPiBmdW4gXyAtPiBtYWtlX2Zyb21fZm10dHkgayBhY2MgcmVzdCBmbXRcbiAgfCBJbnQzMl90eSByZXN0ICAgICAgICAgICAtPiBmdW4gXyAtPiBtYWtlX2Zyb21fZm10dHkgayBhY2MgcmVzdCBmbXRcbiAgfCBOYXRpdmVpbnRfdHkgcmVzdCAgICAgICAtPiBmdW4gXyAtPiBtYWtlX2Zyb21fZm10dHkgayBhY2MgcmVzdCBmbXRcbiAgfCBJbnQ2NF90eSByZXN0ICAgICAgICAgICAtPiBmdW4gXyAtPiBtYWtlX2Zyb21fZm10dHkgayBhY2MgcmVzdCBmbXRcbiAgfCBGbG9hdF90eSByZXN0ICAgICAgICAgICAtPiBmdW4gXyAtPiBtYWtlX2Zyb21fZm10dHkgayBhY2MgcmVzdCBmbXRcbiAgfCBCb29sX3R5IHJlc3QgICAgICAgICAgICAtPiBmdW4gXyAtPiBtYWtlX2Zyb21fZm10dHkgayBhY2MgcmVzdCBmbXRcbiAgfCBBbHBoYV90eSByZXN0ICAgICAgICAgICAtPiBmdW4gXyBfIC0+IG1ha2VfZnJvbV9mbXR0eSBrIGFjYyByZXN0IGZtdFxuICB8IFRoZXRhX3R5IHJlc3QgICAgICAgICAgIC0+IGZ1biBfIC0+IG1ha2VfZnJvbV9mbXR0eSBrIGFjYyByZXN0IGZtdFxuICB8IEFueV90eSByZXN0ICAgICAgICAgICAgIC0+IGZ1biBfIC0+IG1ha2VfZnJvbV9mbXR0eSBrIGFjYyByZXN0IGZtdFxuICB8IFJlYWRlcl90eSBfICAgICAgICAgICAgIC0+IGFzc2VydCBmYWxzZVxuICB8IElnbm9yZWRfcmVhZGVyX3R5IF8gICAgIC0+IGFzc2VydCBmYWxzZVxuICB8IEZvcm1hdF9hcmdfdHkgKF8sIHJlc3QpIC0+IGZ1biBfIC0+IG1ha2VfZnJvbV9mbXR0eSBrIGFjYyByZXN0IGZtdFxuICB8IEVuZF9vZl9mbXR0eSAgICAgICAgICAgIC0+IG1ha2VfaW52YWxpZF9hcmcgayBhY2MgZm10XG4gIHwgRm9ybWF0X3N1YnN0X3R5ICh0eTEsIHR5MiwgcmVzdCkgLT5cbiAgICBsZXQgdHkgPSB0cmFucyAoc3ltbSB0eTEpIHR5MiBpblxuICAgIGZ1biBfIC0+IG1ha2VfZnJvbV9mbXR0eSBrIGFjYyAoY29uY2F0X2ZtdHR5IHR5IHJlc3QpIGZtdFxuXG4oKiBJbnNlcnQgYW4gQWNjX2ludmFsaWRfYXJnIGluIHRoZSBhY2N1bXVsYXRvciBhbmQgY29udGludWUgdG8gZ2VuZXJhdGVcbiAgIGNsb3N1cmVzIHRvIGdldCB0aGUgcmVtYWluaW5nIGFyZ3VtZW50cy4gKilcbmFuZCBtYWtlX2ludmFsaWRfYXJnIDogdHlwZSBhIGIgYyBkIGUgZiAuXG4gICAgKChiLCBjKSBhY2MgLT4gZikgLT4gKGIsIGMpIGFjYyAtPlxuICAgIChhLCBiLCBjLCBkLCBlLCBmKSBmbXQgLT4gYSA9XG5mdW4gayBhY2MgZm10IC0+XG4gIG1ha2VfcHJpbnRmIGsgKEFjY19pbnZhbGlkX2FyZyAoYWNjLCBcIlByaW50ZjogYmFkIGNvbnZlcnNpb24gJV9cIikpIGZtdFxuXG4oKiBGaXggcGFkZGluZywgdGFrZSBpdCBhcyBhbiBleHRyYSBpbnRlZ2VyIGFyZ3VtZW50IGlmIG5lZWRlZC4gKilcbmFuZCBtYWtlX3BhZGRpbmcgOiB0eXBlIHggeiBhIGIgYyBkIGUgZiAuXG4gICAgKChiLCBjKSBhY2MgLT4gZikgLT4gKGIsIGMpIGFjYyAtPlxuICAgIChhLCBiLCBjLCBkLCBlLCBmKSBmbXQgLT5cbiAgICAoeCwgeiAtPiBhKSBwYWRkaW5nIC0+ICh6IC0+IHN0cmluZykgLT4geCA9XG4gIGZ1biBrIGFjYyBmbXQgcGFkIHRyYW5zIC0+IG1hdGNoIHBhZCB3aXRoXG4gIHwgTm9fcGFkZGluZyAtPlxuICAgIGZ1biB4IC0+XG4gICAgICBsZXQgbmV3X2FjYyA9IEFjY19kYXRhX3N0cmluZyAoYWNjLCB0cmFucyB4KSBpblxuICAgICAgbWFrZV9wcmludGYgayBuZXdfYWNjIGZtdFxuICB8IExpdF9wYWRkaW5nIChwYWR0eSwgd2lkdGgpIC0+XG4gICAgZnVuIHggLT5cbiAgICAgIGxldCBuZXdfYWNjID0gQWNjX2RhdGFfc3RyaW5nIChhY2MsIGZpeF9wYWRkaW5nIHBhZHR5IHdpZHRoICh0cmFucyB4KSkgaW5cbiAgICAgIG1ha2VfcHJpbnRmIGsgbmV3X2FjYyBmbXRcbiAgfCBBcmdfcGFkZGluZyBwYWR0eSAtPlxuICAgIGZ1biB3IHggLT5cbiAgICAgIGxldCBuZXdfYWNjID0gQWNjX2RhdGFfc3RyaW5nIChhY2MsIGZpeF9wYWRkaW5nIHBhZHR5IHcgKHRyYW5zIHgpKSBpblxuICAgICAgbWFrZV9wcmludGYgayBuZXdfYWNjIGZtdFxuXG4oKiBGaXggcGFkZGluZyBhbmQgcHJlY2lzaW9uIGZvciBpbnQsIGludDMyLCBuYXRpdmVpbnQgb3IgaW50NjQuICopXG4oKiBUYWtlIG9uZSBvciB0d28gZXh0cmEgaW50ZWdlciBhcmd1bWVudHMgaWYgbmVlZGVkLiAqKVxuYW5kIG1ha2VfaW50X3BhZGRpbmdfcHJlY2lzaW9uIDogdHlwZSB4IHkgeiBhIGIgYyBkIGUgZiAuXG4gICAgKChiLCBjKSBhY2MgLT4gZikgLT4gKGIsIGMpIGFjYyAtPlxuICAgIChhLCBiLCBjLCBkLCBlLCBmKSBmbXQgLT5cbiAgICAoeCwgeSkgcGFkZGluZyAtPiAoeSwgeiAtPiBhKSBwcmVjaXNpb24gLT4gKGludF9jb252IC0+IHogLT4gc3RyaW5nKSAtPlxuICAgIGludF9jb252IC0+IHggPVxuICBmdW4gayBhY2MgZm10IHBhZCBwcmVjIHRyYW5zIGljb252IC0+IG1hdGNoIHBhZCwgcHJlYyB3aXRoXG4gIHwgTm9fcGFkZGluZywgTm9fcHJlY2lzaW9uIC0+XG4gICAgZnVuIHggLT5cbiAgICAgIGxldCBzdHIgPSB0cmFucyBpY29udiB4IGluXG4gICAgICBtYWtlX3ByaW50ZiBrIChBY2NfZGF0YV9zdHJpbmcgKGFjYywgc3RyKSkgZm10XG4gIHwgTm9fcGFkZGluZywgTGl0X3ByZWNpc2lvbiBwIC0+XG4gICAgZnVuIHggLT5cbiAgICAgIGxldCBzdHIgPSBmaXhfaW50X3ByZWNpc2lvbiBwICh0cmFucyBpY29udiB4KSBpblxuICAgICAgbWFrZV9wcmludGYgayAoQWNjX2RhdGFfc3RyaW5nIChhY2MsIHN0cikpIGZtdFxuICB8IE5vX3BhZGRpbmcsIEFyZ19wcmVjaXNpb24gLT5cbiAgICBmdW4gcCB4IC0+XG4gICAgICBsZXQgc3RyID0gZml4X2ludF9wcmVjaXNpb24gcCAodHJhbnMgaWNvbnYgeCkgaW5cbiAgICAgIG1ha2VfcHJpbnRmIGsgKEFjY19kYXRhX3N0cmluZyAoYWNjLCBzdHIpKSBmbXRcbiAgfCBMaXRfcGFkZGluZyAocGFkdHksIHcpLCBOb19wcmVjaXNpb24gLT5cbiAgICBmdW4geCAtPlxuICAgICAgbGV0IHN0ciA9IGZpeF9wYWRkaW5nIHBhZHR5IHcgKHRyYW5zIGljb252IHgpIGluXG4gICAgICBtYWtlX3ByaW50ZiBrIChBY2NfZGF0YV9zdHJpbmcgKGFjYywgc3RyKSkgZm10XG4gIHwgTGl0X3BhZGRpbmcgKHBhZHR5LCB3KSwgTGl0X3ByZWNpc2lvbiBwIC0+XG4gICAgZnVuIHggLT5cbiAgICAgIGxldCBzdHIgPSBmaXhfcGFkZGluZyBwYWR0eSB3IChmaXhfaW50X3ByZWNpc2lvbiBwICh0cmFucyBpY29udiB4KSkgaW5cbiAgICAgIG1ha2VfcHJpbnRmIGsgKEFjY19kYXRhX3N0cmluZyAoYWNjLCBzdHIpKSBmbXRcbiAgfCBMaXRfcGFkZGluZyAocGFkdHksIHcpLCBBcmdfcHJlY2lzaW9uIC0+XG4gICAgZnVuIHAgeCAtPlxuICAgICAgbGV0IHN0ciA9IGZpeF9wYWRkaW5nIHBhZHR5IHcgKGZpeF9pbnRfcHJlY2lzaW9uIHAgKHRyYW5zIGljb252IHgpKSBpblxuICAgICAgbWFrZV9wcmludGYgayAoQWNjX2RhdGFfc3RyaW5nIChhY2MsIHN0cikpIGZtdFxuICB8IEFyZ19wYWRkaW5nIHBhZHR5LCBOb19wcmVjaXNpb24gLT5cbiAgICBmdW4gdyB4IC0+XG4gICAgICBsZXQgc3RyID0gZml4X3BhZGRpbmcgcGFkdHkgdyAodHJhbnMgaWNvbnYgeCkgaW5cbiAgICAgIG1ha2VfcHJpbnRmIGsgKEFjY19kYXRhX3N0cmluZyAoYWNjLCBzdHIpKSBmbXRcbiAgfCBBcmdfcGFkZGluZyBwYWR0eSwgTGl0X3ByZWNpc2lvbiBwIC0+XG4gICAgZnVuIHcgeCAtPlxuICAgICAgbGV0IHN0ciA9IGZpeF9wYWRkaW5nIHBhZHR5IHcgKGZpeF9pbnRfcHJlY2lzaW9uIHAgKHRyYW5zIGljb252IHgpKSBpblxuICAgICAgbWFrZV9wcmludGYgayAoQWNjX2RhdGFfc3RyaW5nIChhY2MsIHN0cikpIGZtdFxuICB8IEFyZ19wYWRkaW5nIHBhZHR5LCBBcmdfcHJlY2lzaW9uIC0+XG4gICAgZnVuIHcgcCB4IC0+XG4gICAgICBsZXQgc3RyID0gZml4X3BhZGRpbmcgcGFkdHkgdyAoZml4X2ludF9wcmVjaXNpb24gcCAodHJhbnMgaWNvbnYgeCkpIGluXG4gICAgICBtYWtlX3ByaW50ZiBrIChBY2NfZGF0YV9zdHJpbmcgKGFjYywgc3RyKSkgZm10XG5cbigqIENvbnZlcnQgYSBmbG9hdCwgZml4IHBhZGRpbmcgYW5kIHByZWNpc2lvbiBpZiBuZWVkZWQuICopXG4oKiBUYWtlIHRoZSBmbG9hdCBhcmd1bWVudCBhbmQgb25lIG9yIHR3byBleHRyYSBpbnRlZ2VyIGFyZ3VtZW50cyBpZiBuZWVkZWQuICopXG5hbmQgbWFrZV9mbG9hdF9wYWRkaW5nX3ByZWNpc2lvbiA6IHR5cGUgeCB5IGEgYiBjIGQgZSBmIC5cbiAgICAoKGIsIGMpIGFjYyAtPiBmKSAtPiAoYiwgYykgYWNjIC0+XG4gICAgKGEsIGIsIGMsIGQsIGUsIGYpIGZtdCAtPlxuICAgICh4LCB5KSBwYWRkaW5nIC0+ICh5LCBmbG9hdCAtPiBhKSBwcmVjaXNpb24gLT4gZmxvYXRfY29udiAtPiB4ID1cbiAgZnVuIGsgYWNjIGZtdCBwYWQgcHJlYyBmY29udiAtPiBtYXRjaCBwYWQsIHByZWMgd2l0aFxuICB8IE5vX3BhZGRpbmcsIE5vX3ByZWNpc2lvbiAtPlxuICAgIGZ1biB4IC0+XG4gICAgICBsZXQgc3RyID0gY29udmVydF9mbG9hdCBmY29udiAoZGVmYXVsdF9mbG9hdF9wcmVjaXNpb24gZmNvbnYpIHggaW5cbiAgICAgIG1ha2VfcHJpbnRmIGsgKEFjY19kYXRhX3N0cmluZyAoYWNjLCBzdHIpKSBmbXRcbiAgfCBOb19wYWRkaW5nLCBMaXRfcHJlY2lzaW9uIHAgLT5cbiAgICBmdW4geCAtPlxuICAgICAgbGV0IHN0ciA9IGNvbnZlcnRfZmxvYXQgZmNvbnYgcCB4IGluXG4gICAgICBtYWtlX3ByaW50ZiBrIChBY2NfZGF0YV9zdHJpbmcgKGFjYywgc3RyKSkgZm10XG4gIHwgTm9fcGFkZGluZywgQXJnX3ByZWNpc2lvbiAtPlxuICAgIGZ1biBwIHggLT5cbiAgICAgIGxldCBzdHIgPSBjb252ZXJ0X2Zsb2F0IGZjb252IHAgeCBpblxuICAgICAgbWFrZV9wcmludGYgayAoQWNjX2RhdGFfc3RyaW5nIChhY2MsIHN0cikpIGZtdFxuICB8IExpdF9wYWRkaW5nIChwYWR0eSwgdyksIE5vX3ByZWNpc2lvbiAtPlxuICAgIGZ1biB4IC0+XG4gICAgICBsZXQgc3RyID0gY29udmVydF9mbG9hdCBmY29udiAoZGVmYXVsdF9mbG9hdF9wcmVjaXNpb24gZmNvbnYpIHggaW5cbiAgICAgIGxldCBzdHInID0gZml4X3BhZGRpbmcgcGFkdHkgdyBzdHIgaW5cbiAgICAgIG1ha2VfcHJpbnRmIGsgKEFjY19kYXRhX3N0cmluZyAoYWNjLCBzdHInKSkgZm10XG4gIHwgTGl0X3BhZGRpbmcgKHBhZHR5LCB3KSwgTGl0X3ByZWNpc2lvbiBwIC0+XG4gICAgZnVuIHggLT5cbiAgICAgIGxldCBzdHIgPSBmaXhfcGFkZGluZyBwYWR0eSB3IChjb252ZXJ0X2Zsb2F0IGZjb252IHAgeCkgaW5cbiAgICAgIG1ha2VfcHJpbnRmIGsgKEFjY19kYXRhX3N0cmluZyAoYWNjLCBzdHIpKSBmbXRcbiAgfCBMaXRfcGFkZGluZyAocGFkdHksIHcpLCBBcmdfcHJlY2lzaW9uIC0+XG4gICAgZnVuIHAgeCAtPlxuICAgICAgbGV0IHN0ciA9IGZpeF9wYWRkaW5nIHBhZHR5IHcgKGNvbnZlcnRfZmxvYXQgZmNvbnYgcCB4KSBpblxuICAgICAgbWFrZV9wcmludGYgayAoQWNjX2RhdGFfc3RyaW5nIChhY2MsIHN0cikpIGZtdFxuICB8IEFyZ19wYWRkaW5nIHBhZHR5LCBOb19wcmVjaXNpb24gLT5cbiAgICBmdW4gdyB4IC0+XG4gICAgICBsZXQgc3RyID0gY29udmVydF9mbG9hdCBmY29udiAoZGVmYXVsdF9mbG9hdF9wcmVjaXNpb24gZmNvbnYpIHggaW5cbiAgICAgIGxldCBzdHInID0gZml4X3BhZGRpbmcgcGFkdHkgdyBzdHIgaW5cbiAgICAgIG1ha2VfcHJpbnRmIGsgKEFjY19kYXRhX3N0cmluZyAoYWNjLCBzdHInKSkgZm10XG4gIHwgQXJnX3BhZGRpbmcgcGFkdHksIExpdF9wcmVjaXNpb24gcCAtPlxuICAgIGZ1biB3IHggLT5cbiAgICAgIGxldCBzdHIgPSBmaXhfcGFkZGluZyBwYWR0eSB3IChjb252ZXJ0X2Zsb2F0IGZjb252IHAgeCkgaW5cbiAgICAgIG1ha2VfcHJpbnRmIGsgKEFjY19kYXRhX3N0cmluZyAoYWNjLCBzdHIpKSBmbXRcbiAgfCBBcmdfcGFkZGluZyBwYWR0eSwgQXJnX3ByZWNpc2lvbiAtPlxuICAgIGZ1biB3IHAgeCAtPlxuICAgICAgbGV0IHN0ciA9IGZpeF9wYWRkaW5nIHBhZHR5IHcgKGNvbnZlcnRfZmxvYXQgZmNvbnYgcCB4KSBpblxuICAgICAgbWFrZV9wcmludGYgayAoQWNjX2RhdGFfc3RyaW5nIChhY2MsIHN0cikpIGZtdFxuYW5kIG1ha2VfY3VzdG9tIDogdHlwZSB4IHkgYSBiIGMgZCBlIGYgLlxuICAoKGIsIGMpIGFjYyAtPiBmKSAtPiAoYiwgYykgYWNjIC0+XG4gIChhLCBiLCBjLCBkLCBlLCBmKSBmbXQgLT5cbiAgKGEsIHgsIHkpIGN1c3RvbV9hcml0eSAtPiB4IC0+IHkgPVxuICBmdW4gayBhY2MgcmVzdCBhcml0eSBmIC0+IG1hdGNoIGFyaXR5IHdpdGhcbiAgfCBDdXN0b21femVybyAtPiBtYWtlX3ByaW50ZiBrIChBY2NfZGF0YV9zdHJpbmcgKGFjYywgZikpIHJlc3RcbiAgfCBDdXN0b21fc3VjYyBhcml0eSAtPlxuICAgIGZ1biB4IC0+XG4gICAgICBtYWtlX2N1c3RvbSBrIGFjYyByZXN0IGFyaXR5IChmIHgpXG5cbmxldCBjb25zdCB4IF8gPSB4XG5cbmxldCByZWMgbWFrZV9pcHJpbnRmIDogdHlwZSBhIGIgYyBkIGUgZiBzdGF0ZS5cbiAgKHN0YXRlIC0+IGYpIC0+IHN0YXRlIC0+IChhLCBiLCBjLCBkLCBlLCBmKSBmbXQgLT4gYSA9XG4gIGZ1biBrIG8gZm10IC0+IG1hdGNoIGZtdCB3aXRoXG4gICAgfCBDaGFyIHJlc3QgLT5cbiAgICAgICAgY29uc3QgKG1ha2VfaXByaW50ZiBrIG8gcmVzdClcbiAgICB8IENhbWxfY2hhciByZXN0IC0+XG4gICAgICAgIGNvbnN0IChtYWtlX2lwcmludGYgayBvIHJlc3QpXG4gICAgfCBTdHJpbmcgKE5vX3BhZGRpbmcsIHJlc3QpIC0+XG4gICAgICAgIGNvbnN0IChtYWtlX2lwcmludGYgayBvIHJlc3QpXG4gICAgfCBTdHJpbmcgKExpdF9wYWRkaW5nIF8sIHJlc3QpIC0+XG4gICAgICAgIGNvbnN0IChtYWtlX2lwcmludGYgayBvIHJlc3QpXG4gICAgfCBTdHJpbmcgKEFyZ19wYWRkaW5nIF8sIHJlc3QpIC0+XG4gICAgICAgIGNvbnN0IChjb25zdCAobWFrZV9pcHJpbnRmIGsgbyByZXN0KSlcbiAgICB8IENhbWxfc3RyaW5nIChOb19wYWRkaW5nLCByZXN0KSAtPlxuICAgICAgICBjb25zdCAobWFrZV9pcHJpbnRmIGsgbyByZXN0KVxuICAgIHwgQ2FtbF9zdHJpbmcgKExpdF9wYWRkaW5nIF8sIHJlc3QpIC0+XG4gICAgICAgIGNvbnN0IChtYWtlX2lwcmludGYgayBvIHJlc3QpXG4gICAgfCBDYW1sX3N0cmluZyAoQXJnX3BhZGRpbmcgXywgcmVzdCkgLT5cbiAgICAgICAgY29uc3QgKGNvbnN0IChtYWtlX2lwcmludGYgayBvIHJlc3QpKVxuICAgIHwgSW50IChfLCBwYWQsIHByZWMsIHJlc3QpIC0+XG4gICAgICAgIGZuX29mX3BhZGRpbmdfcHJlY2lzaW9uIGsgbyByZXN0IHBhZCBwcmVjXG4gICAgfCBJbnQzMiAoXywgcGFkLCBwcmVjLCByZXN0KSAtPlxuICAgICAgICBmbl9vZl9wYWRkaW5nX3ByZWNpc2lvbiBrIG8gcmVzdCBwYWQgcHJlY1xuICAgIHwgTmF0aXZlaW50IChfLCBwYWQsIHByZWMsIHJlc3QpIC0+XG4gICAgICAgIGZuX29mX3BhZGRpbmdfcHJlY2lzaW9uIGsgbyByZXN0IHBhZCBwcmVjXG4gICAgfCBJbnQ2NCAoXywgcGFkLCBwcmVjLCByZXN0KSAtPlxuICAgICAgICBmbl9vZl9wYWRkaW5nX3ByZWNpc2lvbiBrIG8gcmVzdCBwYWQgcHJlY1xuICAgIHwgRmxvYXQgKF8sIHBhZCwgcHJlYywgcmVzdCkgLT5cbiAgICAgICAgZm5fb2ZfcGFkZGluZ19wcmVjaXNpb24gayBvIHJlc3QgcGFkIHByZWNcbiAgICB8IEJvb2wgKE5vX3BhZGRpbmcsIHJlc3QpIC0+XG4gICAgICAgIGNvbnN0IChtYWtlX2lwcmludGYgayBvIHJlc3QpXG4gICAgfCBCb29sIChMaXRfcGFkZGluZyBfLCByZXN0KSAtPlxuICAgICAgICBjb25zdCAobWFrZV9pcHJpbnRmIGsgbyByZXN0KVxuICAgIHwgQm9vbCAoQXJnX3BhZGRpbmcgXywgcmVzdCkgLT5cbiAgICAgICAgY29uc3QgKGNvbnN0IChtYWtlX2lwcmludGYgayBvIHJlc3QpKVxuICAgIHwgQWxwaGEgcmVzdCAtPlxuICAgICAgICBjb25zdCAoY29uc3QgKG1ha2VfaXByaW50ZiBrIG8gcmVzdCkpXG4gICAgfCBUaGV0YSByZXN0IC0+XG4gICAgICAgIGNvbnN0IChtYWtlX2lwcmludGYgayBvIHJlc3QpXG4gICAgfCBDdXN0b20gKGFyaXR5LCBfLCByZXN0KSAtPlxuICAgICAgICBmbl9vZl9jdXN0b21fYXJpdHkgayBvIHJlc3QgYXJpdHlcbiAgICB8IFJlYWRlciBfIC0+XG4gICAgICAgICgqIFRoaXMgY2FzZSBpcyBpbXBvc3NpYmxlLCBieSB0eXBpbmcgb2YgZm9ybWF0cy4gIFNlZSB0aGVcbiAgICAgICAgICAgbm90ZSBpbiB0aGUgY29ycmVzcG9uZGluZyBjYXNlIGZvciBtYWtlX3ByaW50Zi4gKilcbiAgICAgICAgYXNzZXJ0IGZhbHNlXG4gICAgfCBGbHVzaCByZXN0IC0+XG4gICAgICAgIG1ha2VfaXByaW50ZiBrIG8gcmVzdFxuICAgIHwgU3RyaW5nX2xpdGVyYWwgKF8sIHJlc3QpIC0+XG4gICAgICAgIG1ha2VfaXByaW50ZiBrIG8gcmVzdFxuICAgIHwgQ2hhcl9saXRlcmFsIChfLCByZXN0KSAtPlxuICAgICAgICBtYWtlX2lwcmludGYgayBvIHJlc3RcbiAgICB8IEZvcm1hdF9hcmcgKF8sIF8sIHJlc3QpIC0+XG4gICAgICAgIGNvbnN0IChtYWtlX2lwcmludGYgayBvIHJlc3QpXG4gICAgfCBGb3JtYXRfc3Vic3QgKF8sIGZtdHR5LCByZXN0KSAtPlxuICAgICAgICBmdW4gKEZvcm1hdCAoZm10LCBfKSkgLT5cbiAgICAgICAgICBtYWtlX2lwcmludGYgayBvXG4gICAgICAgICAgICAoY29uY2F0X2ZtdCAocmVjYXN0IGZtdCBmbXR0eSkgcmVzdClcbiAgICB8IFNjYW5fY2hhcl9zZXQgKF8sIF8sIHJlc3QpIC0+XG4gICAgICAgIGNvbnN0IChtYWtlX2lwcmludGYgayBvIHJlc3QpXG4gICAgfCBTY2FuX2dldF9jb3VudGVyIChfLCByZXN0KSAtPlxuICAgICAgICBjb25zdCAobWFrZV9pcHJpbnRmIGsgbyByZXN0KVxuICAgIHwgU2Nhbl9uZXh0X2NoYXIgcmVzdCAtPlxuICAgICAgICBjb25zdCAobWFrZV9pcHJpbnRmIGsgbyByZXN0KVxuICAgIHwgSWdub3JlZF9wYXJhbSAoaWduLCByZXN0KSAtPlxuICAgICAgICBtYWtlX2lnbm9yZWRfcGFyYW0gKGZ1biBfIC0+IGsgbykgKEVuZF9vZl9hY2MpIGlnbiByZXN0XG4gICAgfCBGb3JtYXR0aW5nX2xpdCAoXywgcmVzdCkgLT5cbiAgICAgICAgbWFrZV9pcHJpbnRmIGsgbyByZXN0XG4gICAgfCBGb3JtYXR0aW5nX2dlbiAoT3Blbl90YWcgKEZvcm1hdCAoZm10JywgXykpLCByZXN0KSAtPlxuICAgICAgICBtYWtlX2lwcmludGYgKGZ1biBrb2MgLT4gbWFrZV9pcHJpbnRmIGsga29jIHJlc3QpIG8gZm10J1xuICAgIHwgRm9ybWF0dGluZ19nZW4gKE9wZW5fYm94IChGb3JtYXQgKGZtdCcsIF8pKSwgcmVzdCkgLT5cbiAgICAgICAgbWFrZV9pcHJpbnRmIChmdW4ga29jIC0+IG1ha2VfaXByaW50ZiBrIGtvYyByZXN0KSBvIGZtdCdcbiAgICB8IEVuZF9vZl9mb3JtYXQgLT5cbiAgICAgICAgayBvXG5hbmQgZm5fb2ZfcGFkZGluZ19wcmVjaXNpb24gOlxuICB0eXBlIHggeSB6IGEgYiBjIGQgZSBmIHN0YXRlLlxuICAoc3RhdGUgLT4gZikgLT4gc3RhdGUgLT4gKGEsIGIsIGMsIGQsIGUsIGYpIGZtdCAtPlxuICAoeCwgeSkgcGFkZGluZyAtPiAoeSwgeiAtPiBhKSBwcmVjaXNpb24gLT4geCA9XG4gIGZ1biBrIG8gZm10IHBhZCBwcmVjIC0+IG1hdGNoIHBhZCwgcHJlYyB3aXRoXG4gICAgfCBOb19wYWRkaW5nICAgLCBOb19wcmVjaXNpb24gICAgLT5cbiAgICAgICAgY29uc3QgKG1ha2VfaXByaW50ZiBrIG8gZm10KVxuICAgIHwgTm9fcGFkZGluZyAgICwgTGl0X3ByZWNpc2lvbiBfIC0+XG4gICAgICAgIGNvbnN0IChtYWtlX2lwcmludGYgayBvIGZtdClcbiAgICB8IE5vX3BhZGRpbmcgICAsIEFyZ19wcmVjaXNpb24gICAtPlxuICAgICAgICBjb25zdCAoY29uc3QgKG1ha2VfaXByaW50ZiBrIG8gZm10KSlcbiAgICB8IExpdF9wYWRkaW5nIF8sIE5vX3ByZWNpc2lvbiAgICAtPlxuICAgICAgICBjb25zdCAobWFrZV9pcHJpbnRmIGsgbyBmbXQpXG4gICAgfCBMaXRfcGFkZGluZyBfLCBMaXRfcHJlY2lzaW9uIF8gLT5cbiAgICAgICAgY29uc3QgKG1ha2VfaXByaW50ZiBrIG8gZm10KVxuICAgIHwgTGl0X3BhZGRpbmcgXywgQXJnX3ByZWNpc2lvbiAgIC0+XG4gICAgICAgIGNvbnN0IChjb25zdCAobWFrZV9pcHJpbnRmIGsgbyBmbXQpKVxuICAgIHwgQXJnX3BhZGRpbmcgXywgTm9fcHJlY2lzaW9uICAgIC0+XG4gICAgICAgIGNvbnN0IChjb25zdCAobWFrZV9pcHJpbnRmIGsgbyBmbXQpKVxuICAgIHwgQXJnX3BhZGRpbmcgXywgTGl0X3ByZWNpc2lvbiBfIC0+XG4gICAgICAgIGNvbnN0IChjb25zdCAobWFrZV9pcHJpbnRmIGsgbyBmbXQpKVxuICAgIHwgQXJnX3BhZGRpbmcgXywgQXJnX3ByZWNpc2lvbiAgIC0+XG4gICAgICAgIGNvbnN0IChjb25zdCAoY29uc3QgKG1ha2VfaXByaW50ZiBrIG8gZm10KSkpXG5hbmQgZm5fb2ZfY3VzdG9tX2FyaXR5IDogdHlwZSB4IHkgYSBiIGMgZCBlIGYgc3RhdGUuXG4gIChzdGF0ZSAtPiBmKSAtPlxuICBzdGF0ZSAtPiAoYSwgYiwgYywgZCwgZSwgZikgZm10IC0+IChhLCB4LCB5KSBjdXN0b21fYXJpdHkgLT4geSA9XG4gIGZ1biBrIG8gZm10IC0+IGZ1bmN0aW9uXG4gICAgfCBDdXN0b21femVybyAtPlxuICAgICAgICBtYWtlX2lwcmludGYgayBvIGZtdFxuICAgIHwgQ3VzdG9tX3N1Y2MgYXJpdHkgLT5cbiAgICAgICAgY29uc3QgKGZuX29mX2N1c3RvbV9hcml0eSBrIG8gZm10IGFyaXR5KVxuXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAoKiBDb250aW51YXRpb25zIGZvciBtYWtlX3ByaW50ZiAqKVxuXG4oKiBSZWN1cnNpdmVseSBvdXRwdXQgYW4gXCJhY2N1bXVsYXRvclwiIGNvbnRhaW5pbmcgYSByZXZlcnNlZCBsaXN0IG9mXG4gICBwcmludGluZyBlbnRpdGllcyAoc3RyaW5nLCBjaGFyLCBmbHVzLCAuLi4pIGluIGFuIG91dHB1dF9zdHJlYW0uICopXG4oKiBVc2VkIGFzIGEgY29udGludWF0aW9uIG9mIG1ha2VfcHJpbnRmLiAqKVxubGV0IHJlYyBvdXRwdXRfYWNjIG8gYWNjID0gbWF0Y2ggYWNjIHdpdGhcbiAgfCBBY2NfZm9ybWF0dGluZ19saXQgKHAsIGZtdGluZ19saXQpIC0+XG4gICAgbGV0IHMgPSBzdHJpbmdfb2ZfZm9ybWF0dGluZ19saXQgZm10aW5nX2xpdCBpblxuICAgIG91dHB1dF9hY2MgbyBwOyBvdXRwdXRfc3RyaW5nIG8gcztcbiAgfCBBY2NfZm9ybWF0dGluZ19nZW4gKHAsIEFjY19vcGVuX3RhZyBhY2MnKSAtPlxuICAgIG91dHB1dF9hY2MgbyBwOyBvdXRwdXRfc3RyaW5nIG8gXCJAe1wiOyBvdXRwdXRfYWNjIG8gYWNjJztcbiAgfCBBY2NfZm9ybWF0dGluZ19nZW4gKHAsIEFjY19vcGVuX2JveCBhY2MnKSAtPlxuICAgIG91dHB1dF9hY2MgbyBwOyBvdXRwdXRfc3RyaW5nIG8gXCJAW1wiOyBvdXRwdXRfYWNjIG8gYWNjJztcbiAgfCBBY2Nfc3RyaW5nX2xpdGVyYWwgKHAsIHMpXG4gIHwgQWNjX2RhdGFfc3RyaW5nIChwLCBzKSAgIC0+IG91dHB1dF9hY2MgbyBwOyBvdXRwdXRfc3RyaW5nIG8gc1xuICB8IEFjY19jaGFyX2xpdGVyYWwgKHAsIGMpXG4gIHwgQWNjX2RhdGFfY2hhciAocCwgYykgICAgIC0+IG91dHB1dF9hY2MgbyBwOyBvdXRwdXRfY2hhciBvIGNcbiAgfCBBY2NfZGVsYXkgKHAsIGYpICAgICAgICAgLT4gb3V0cHV0X2FjYyBvIHA7IGYgb1xuICB8IEFjY19mbHVzaCBwICAgICAgICAgICAgICAtPiBvdXRwdXRfYWNjIG8gcDsgZmx1c2ggb1xuICB8IEFjY19pbnZhbGlkX2FyZyAocCwgbXNnKSAtPiBvdXRwdXRfYWNjIG8gcDsgaW52YWxpZF9hcmcgbXNnO1xuICB8IEVuZF9vZl9hY2MgICAgICAgICAgICAgICAtPiAoKVxuXG4oKiBSZWN1cnNpdmVseSBvdXRwdXQgYW4gXCJhY2N1bXVsYXRvclwiIGNvbnRhaW5pbmcgYSByZXZlcnNlZCBsaXN0IG9mXG4gICBwcmludGluZyBlbnRpdGllcyAoc3RyaW5nLCBjaGFyLCBmbHVzLCAuLi4pIGluIGEgYnVmZmVyLiAqKVxuKCogVXNlZCBhcyBhIGNvbnRpbnVhdGlvbiBvZiBtYWtlX3ByaW50Zi4gKilcbmxldCByZWMgYnVmcHV0X2FjYyBiIGFjYyA9IG1hdGNoIGFjYyB3aXRoXG4gIHwgQWNjX2Zvcm1hdHRpbmdfbGl0IChwLCBmbXRpbmdfbGl0KSAtPlxuICAgIGxldCBzID0gc3RyaW5nX29mX2Zvcm1hdHRpbmdfbGl0IGZtdGluZ19saXQgaW5cbiAgICBidWZwdXRfYWNjIGIgcDsgQnVmZmVyLmFkZF9zdHJpbmcgYiBzO1xuICB8IEFjY19mb3JtYXR0aW5nX2dlbiAocCwgQWNjX29wZW5fdGFnIGFjYycpIC0+XG4gICAgYnVmcHV0X2FjYyBiIHA7IEJ1ZmZlci5hZGRfc3RyaW5nIGIgXCJAe1wiOyBidWZwdXRfYWNjIGIgYWNjJztcbiAgfCBBY2NfZm9ybWF0dGluZ19nZW4gKHAsIEFjY19vcGVuX2JveCBhY2MnKSAtPlxuICAgIGJ1ZnB1dF9hY2MgYiBwOyBCdWZmZXIuYWRkX3N0cmluZyBiIFwiQFtcIjsgYnVmcHV0X2FjYyBiIGFjYyc7XG4gIHwgQWNjX3N0cmluZ19saXRlcmFsIChwLCBzKVxuICB8IEFjY19kYXRhX3N0cmluZyAocCwgcykgICAtPiBidWZwdXRfYWNjIGIgcDsgQnVmZmVyLmFkZF9zdHJpbmcgYiBzXG4gIHwgQWNjX2NoYXJfbGl0ZXJhbCAocCwgYylcbiAgfCBBY2NfZGF0YV9jaGFyIChwLCBjKSAgICAgLT4gYnVmcHV0X2FjYyBiIHA7IEJ1ZmZlci5hZGRfY2hhciBiIGNcbiAgfCBBY2NfZGVsYXkgKHAsIGYpICAgICAgICAgLT4gYnVmcHV0X2FjYyBiIHA7IGYgYlxuICB8IEFjY19mbHVzaCBwICAgICAgICAgICAgICAtPiBidWZwdXRfYWNjIGIgcDtcbiAgfCBBY2NfaW52YWxpZF9hcmcgKHAsIG1zZykgLT4gYnVmcHV0X2FjYyBiIHA7IGludmFsaWRfYXJnIG1zZztcbiAgfCBFbmRfb2ZfYWNjICAgICAgICAgICAgICAgLT4gKClcblxuKCogUmVjdXJzaXZlbHkgb3V0cHV0IGFuIFwiYWNjdW11bGF0b3JcIiBjb250YWluaW5nIGEgcmV2ZXJzZWQgbGlzdCBvZlxuICAgcHJpbnRpbmcgZW50aXRpZXMgKHN0cmluZywgY2hhciwgZmx1cywgLi4uKSBpbiBhIGJ1ZmZlci4gKilcbigqIERpZmZlciBmcm9tIGJ1ZnB1dF9hY2MgYnkgdGhlIGludGVycHJldGF0aW9uIG9mICVhIGFuZCAldC4gKilcbigqIFVzZWQgYXMgYSBjb250aW51YXRpb24gb2YgbWFrZV9wcmludGYuICopXG5sZXQgcmVjIHN0cnB1dF9hY2MgYiBhY2MgPSBtYXRjaCBhY2Mgd2l0aFxuICB8IEFjY19mb3JtYXR0aW5nX2xpdCAocCwgZm10aW5nX2xpdCkgLT5cbiAgICBsZXQgcyA9IHN0cmluZ19vZl9mb3JtYXR0aW5nX2xpdCBmbXRpbmdfbGl0IGluXG4gICAgc3RycHV0X2FjYyBiIHA7IEJ1ZmZlci5hZGRfc3RyaW5nIGIgcztcbiAgfCBBY2NfZm9ybWF0dGluZ19nZW4gKHAsIEFjY19vcGVuX3RhZyBhY2MnKSAtPlxuICAgIHN0cnB1dF9hY2MgYiBwOyBCdWZmZXIuYWRkX3N0cmluZyBiIFwiQHtcIjsgc3RycHV0X2FjYyBiIGFjYyc7XG4gIHwgQWNjX2Zvcm1hdHRpbmdfZ2VuIChwLCBBY2Nfb3Blbl9ib3ggYWNjJykgLT5cbiAgICBzdHJwdXRfYWNjIGIgcDsgQnVmZmVyLmFkZF9zdHJpbmcgYiBcIkBbXCI7IHN0cnB1dF9hY2MgYiBhY2MnO1xuICB8IEFjY19zdHJpbmdfbGl0ZXJhbCAocCwgcylcbiAgfCBBY2NfZGF0YV9zdHJpbmcgKHAsIHMpICAgLT4gc3RycHV0X2FjYyBiIHA7IEJ1ZmZlci5hZGRfc3RyaW5nIGIgc1xuICB8IEFjY19jaGFyX2xpdGVyYWwgKHAsIGMpXG4gIHwgQWNjX2RhdGFfY2hhciAocCwgYykgICAgIC0+IHN0cnB1dF9hY2MgYiBwOyBCdWZmZXIuYWRkX2NoYXIgYiBjXG4gIHwgQWNjX2RlbGF5IChwLCBmKSAgICAgICAgIC0+IHN0cnB1dF9hY2MgYiBwOyBCdWZmZXIuYWRkX3N0cmluZyBiIChmICgpKVxuICB8IEFjY19mbHVzaCBwICAgICAgICAgICAgICAtPiBzdHJwdXRfYWNjIGIgcDtcbiAgfCBBY2NfaW52YWxpZF9hcmcgKHAsIG1zZykgLT4gc3RycHV0X2FjYyBiIHA7IGludmFsaWRfYXJnIG1zZztcbiAgfCBFbmRfb2ZfYWNjICAgICAgICAgICAgICAgLT4gKClcblxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKCogRXJyb3IgbWFuYWdlbWVudCAqKVxuXG4oKiBSYWlzZSBbRmFpbHVyZV0gd2l0aCBhIHByZXR0eS1wcmludGVkIGVycm9yIG1lc3NhZ2UuICopXG5sZXQgZmFpbHdpdGhfbWVzc2FnZSAoRm9ybWF0IChmbXQsIF8pKSA9XG4gIGxldCBidWYgPSBCdWZmZXIuY3JlYXRlIDI1NiBpblxuICBsZXQgayBhY2MgPSBzdHJwdXRfYWNjIGJ1ZiBhY2M7IGZhaWx3aXRoIChCdWZmZXIuY29udGVudHMgYnVmKSBpblxuICBtYWtlX3ByaW50ZiBrIEVuZF9vZl9hY2MgZm10XG5cbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogRm9ybWF0dGluZyB0b29scyAqKVxuXG4oKiBDb252ZXJ0IGEgc3RyaW5nIHRvIGFuIG9wZW4gYmxvY2sgZGVzY3JpcHRpb24gKGluZGVudCwgYmxvY2tfdHlwZSkgKilcbmxldCBvcGVuX2JveF9vZl9zdHJpbmcgc3RyID1cbiAgaWYgc3RyID0gXCJcIiB0aGVuICgwLCBQcF9ib3gpIGVsc2VcbiAgICBsZXQgbGVuID0gU3RyaW5nLmxlbmd0aCBzdHIgaW5cbiAgICBsZXQgaW52YWxpZF9ib3ggKCkgPSBmYWlsd2l0aF9tZXNzYWdlIFwiaW52YWxpZCBib3ggZGVzY3JpcHRpb24gJVNcIiBzdHIgaW5cbiAgICBsZXQgcmVjIHBhcnNlX3NwYWNlcyBpID1cbiAgICAgIGlmIGkgPSBsZW4gdGhlbiBpIGVsc2VcbiAgICAgICAgbWF0Y2ggc3RyLltpXSB3aXRoXG4gICAgICAgIHwgJyAnIHwgJ1xcdCcgLT4gcGFyc2Vfc3BhY2VzIChpICsgMSlcbiAgICAgICAgfCBfIC0+IGlcbiAgICBhbmQgcGFyc2VfbHdvcmQgaSBqID1cbiAgICAgIGlmIGogPSBsZW4gdGhlbiBqIGVsc2VcbiAgICAgICAgbWF0Y2ggc3RyLltqXSB3aXRoXG4gICAgICAgIHwgJ2EnIC4uICd6JyAtPiBwYXJzZV9sd29yZCBpIChqICsgMSlcbiAgICAgICAgfCBfIC0+IGpcbiAgICBhbmQgcGFyc2VfaW50IGkgaiA9XG4gICAgICBpZiBqID0gbGVuIHRoZW4gaiBlbHNlXG4gICAgICAgIG1hdGNoIHN0ci5bal0gd2l0aFxuICAgICAgICB8ICcwJyAuLiAnOScgfCAnLScgLT4gcGFyc2VfaW50IGkgKGogKyAxKVxuICAgICAgICB8IF8gLT4gaiBpblxuICAgIGxldCB3c3RhcnQgPSBwYXJzZV9zcGFjZXMgMCBpblxuICAgIGxldCB3ZW5kID0gcGFyc2VfbHdvcmQgd3N0YXJ0IHdzdGFydCBpblxuICAgIGxldCBib3hfbmFtZSA9IFN0cmluZy5zdWIgc3RyIHdzdGFydCAod2VuZCAtIHdzdGFydCkgaW5cbiAgICBsZXQgbnN0YXJ0ID0gcGFyc2Vfc3BhY2VzIHdlbmQgaW5cbiAgICBsZXQgbmVuZCA9IHBhcnNlX2ludCBuc3RhcnQgbnN0YXJ0IGluXG4gICAgbGV0IGluZGVudCA9XG4gICAgICBpZiBuc3RhcnQgPSBuZW5kIHRoZW4gMCBlbHNlXG4gICAgICAgIHRyeSBpbnRfb2Zfc3RyaW5nIChTdHJpbmcuc3ViIHN0ciBuc3RhcnQgKG5lbmQgLSBuc3RhcnQpKVxuICAgICAgICB3aXRoIEZhaWx1cmUgXyAtPiBpbnZhbGlkX2JveCAoKSBpblxuICAgIGxldCBleHBfZW5kID0gcGFyc2Vfc3BhY2VzIG5lbmQgaW5cbiAgICBpZiBleHBfZW5kIDw+IGxlbiB0aGVuIGludmFsaWRfYm94ICgpO1xuICAgIGxldCBib3hfdHlwZSA9IG1hdGNoIGJveF9uYW1lIHdpdGhcbiAgICAgIHwgXCJcIiB8IFwiYlwiIC0+IFBwX2JveFxuICAgICAgfCBcImhcIiAgICAgIC0+IFBwX2hib3hcbiAgICAgIHwgXCJ2XCIgICAgICAtPiBQcF92Ym94XG4gICAgICB8IFwiaHZcIiAgICAgLT4gUHBfaHZib3hcbiAgICAgIHwgXCJob3ZcIiAgICAtPiBQcF9ob3Zib3hcbiAgICAgIHwgXyAgICAgICAgLT4gaW52YWxpZF9ib3ggKCkgaW5cbiAgICAoaW5kZW50LCBib3hfdHlwZSlcblxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiBQYXJzaW5nIHRvb2xzICopXG5cbigqIENyZWF0ZSBhIHBhZGRpbmdfZm10X2ViYiBmcm9tIGEgcGFkZGluZyBhbmQgYSBmb3JtYXQuICopXG4oKiBDb3B5IHRoZSBwYWRkaW5nIHRvIGRpc2pvaW4gdGhlIHR5cGUgcGFyYW1ldGVycyBvZiBhcmd1bWVudCBhbmQgcmVzdWx0LiAqKVxubGV0IG1ha2VfcGFkZGluZ19mbXRfZWJiIDogdHlwZSB4IHkgLlxuICAgICh4LCB5KSBwYWRkaW5nIC0+IChfLCBfLCBfLCBfLCBfLCBfKSBmbXQgLT5cbiAgICAgIChfLCBfLCBfLCBfLCBfKSBwYWRkaW5nX2ZtdF9lYmIgPVxuZnVuIHBhZCBmbXQgLT4gbWF0Y2ggcGFkIHdpdGhcbiAgfCBOb19wYWRkaW5nICAgICAgICAgLT4gUGFkZGluZ19mbXRfRUJCIChOb19wYWRkaW5nLCBmbXQpXG4gIHwgTGl0X3BhZGRpbmcgKHMsIHcpIC0+IFBhZGRpbmdfZm10X0VCQiAoTGl0X3BhZGRpbmcgKHMsIHcpLCBmbXQpXG4gIHwgQXJnX3BhZGRpbmcgcyAgICAgIC0+IFBhZGRpbmdfZm10X0VCQiAoQXJnX3BhZGRpbmcgcywgZm10KVxuXG4oKiBDcmVhdGUgYSBwcmVjaXNpb25fZm10X2ViYiBmcm9tIGEgcHJlY2lzaW9uIGFuZCBhIGZvcm1hdC4gKilcbigqIENvcHkgdGhlIHByZWNpc2lvbiB0byBkaXNqb2luIHRoZSB0eXBlIHBhcmFtZXRlcnMgb2YgYXJndW1lbnQgYW5kIHJlc3VsdC4gKilcbmxldCBtYWtlX3ByZWNpc2lvbl9mbXRfZWJiIDogdHlwZSB4IHkgLlxuICAgICh4LCB5KSBwcmVjaXNpb24gLT4gKF8sIF8sIF8sIF8sIF8sIF8pIGZtdCAtPlxuICAgICAgKF8sIF8sIF8sIF8sIF8pIHByZWNpc2lvbl9mbXRfZWJiID1cbmZ1biBwcmVjIGZtdCAtPiBtYXRjaCBwcmVjIHdpdGhcbiAgfCBOb19wcmVjaXNpb24gICAgLT4gUHJlY2lzaW9uX2ZtdF9FQkIgKE5vX3ByZWNpc2lvbiwgZm10KVxuICB8IExpdF9wcmVjaXNpb24gcCAtPiBQcmVjaXNpb25fZm10X0VCQiAoTGl0X3ByZWNpc2lvbiBwLCBmbXQpXG4gIHwgQXJnX3ByZWNpc2lvbiAgIC0+IFByZWNpc2lvbl9mbXRfRUJCIChBcmdfcHJlY2lzaW9uLCBmbXQpXG5cbigqIENyZWF0ZSBhIHBhZHByZWNfZm10X2ViYiBmcm9tIGEgcGFkZGluZywgYSBwcmVjaXNpb24gYW5kIGEgZm9ybWF0LiAqKVxuKCogQ29weSB0aGUgcGFkZGluZyBhbmQgdGhlIHByZWNpc2lvbiB0byBkaXNqb2luIHR5cGUgcGFyYW1ldGVycyBvZiBhcmd1bWVudHNcbiAgIGFuZCByZXN1bHQuICopXG5sZXQgbWFrZV9wYWRwcmVjX2ZtdF9lYmIgOiB0eXBlIHggeSB6IHQgLlxuICAgICh4LCB5KSBwYWRkaW5nIC0+ICh6LCB0KSBwcmVjaXNpb24gLT5cbiAgICAoXywgXywgXywgXywgXywgXykgZm10IC0+XG4gICAgKF8sIF8sIF8sIF8sIF8pIHBhZHByZWNfZm10X2ViYiA9XG5mdW4gcGFkIHByZWMgZm10IC0+XG4gIGxldCBQcmVjaXNpb25fZm10X0VCQiAocHJlYywgZm10JykgPSBtYWtlX3ByZWNpc2lvbl9mbXRfZWJiIHByZWMgZm10IGluXG4gIG1hdGNoIHBhZCB3aXRoXG4gIHwgTm9fcGFkZGluZyAgICAgICAgIC0+IFBhZHByZWNfZm10X0VCQiAoTm9fcGFkZGluZywgcHJlYywgZm10JylcbiAgfCBMaXRfcGFkZGluZyAocywgdykgLT4gUGFkcHJlY19mbXRfRUJCIChMaXRfcGFkZGluZyAocywgdyksIHByZWMsIGZtdCcpXG4gIHwgQXJnX3BhZGRpbmcgcyAgICAgIC0+IFBhZHByZWNfZm10X0VCQiAoQXJnX3BhZGRpbmcgcywgcHJlYywgZm10JylcblxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogRm9ybWF0IHBhcnNpbmcgKilcblxuKCogUGFyc2UgYSBzdHJpbmcgcmVwcmVzZW50aW5nIGEgZm9ybWF0IGFuZCBjcmVhdGUgYSBmbXRfZWJiLiAqKVxuKCogUmFpc2UgW0ZhaWx1cmVdIGluIGNhc2Ugb2YgaW52YWxpZCBmb3JtYXQuICopXG5sZXQgZm10X2ViYl9vZl9zdHJpbmcgP2xlZ2FjeV9iZWhhdmlvciBzdHIgPVxuICAoKiBQYXJhbWV0ZXJzIG5hbWluZyBjb252ZW50aW9uOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4gICgqICAgLSBsaXRfc3RhcnQ6IHN0YXJ0IG9mIHRoZSBsaXRlcmFsIHNlcXVlbmNlLiAgICAgICAgICAgICAgICAgICAgKilcbiAgKCogICAtIHN0cl9pbmQ6IGN1cnJlbnQgaW5kZXggaW4gdGhlIHN0cmluZy4gICAgICAgICAgICAgICAgICAgICAgICAqKVxuICAoKiAgIC0gZW5kX2luZDogZW5kIG9mIHRoZSBjdXJyZW50IChzdWItKWZvcm1hdC4gICAgICAgICAgICAgICAgICAgICopXG4gICgqICAgLSBwY3RfaW5kOiBpbmRleCBvZiB0aGUgJyUnIGluIHRoZSBjdXJyZW50IG1pY3JvLWZvcm1hdC4gICAgICAgKilcbiAgKCogICAtIHplcm86ICBpcyB0aGUgJzAnIGZsYWcgZGVmaW5lZCBpbiB0aGUgY3VycmVudCBtaWNyby1mb3JtYXQuICAqKVxuICAoKiAgIC0gbWludXM6IGlzIHRoZSAnLScgZmxhZyBkZWZpbmVkIGluIHRoZSBjdXJyZW50IG1pY3JvLWZvcm1hdC4gICopXG4gICgqICAgLSBwbHVzOiAgaXMgdGhlICcrJyBmbGFnIGRlZmluZWQgaW4gdGhlIGN1cnJlbnQgbWljcm8tZm9ybWF0LiAgKilcbiAgKCogICAtIGhhc2g6ICBpcyB0aGUgJyMnIGZsYWcgZGVmaW5lZCBpbiB0aGUgY3VycmVudCBtaWNyby1mb3JtYXQuICAqKVxuICAoKiAgIC0gc3BhY2U6IGlzIHRoZSAnICcgZmxhZyBkZWZpbmVkIGluIHRoZSBjdXJyZW50IG1pY3JvLWZvcm1hdC4gICopXG4gICgqICAgLSBpZ246ICAgaXMgdGhlICdfJyBmbGFnIGRlZmluZWQgaW4gdGhlIGN1cnJlbnQgbWljcm8tZm9ybWF0LiAgKilcbiAgKCogICAtIHBhZDogcGFkZGluZyBvZiB0aGUgY3VycmVudCBtaWNyby1mb3JtYXQuICAgICAgICAgICAgICAgICAgICAqKVxuICAoKiAgIC0gcHJlYzogcHJlY2lzaW9uIG9mIHRoZSBjdXJyZW50IG1pY3JvLWZvcm1hdC4gICAgICAgICAgICAgICAgICopXG4gICgqICAgLSBzeW1iOiBjaGFyIHJlcHJlc2VudGluZyB0aGUgY29udmVyc2lvbiAoJ2MnLCAncycsICdkJywgLi4uKS4gKilcbiAgKCogICAtIGNoYXJfc2V0OiBzZXQgb2YgY2hhcmFjdGVycyBhcyBiaXRtYXAgKHNlZSBzY2FuZiAlWy4uLl0pLiAgICAqKVxuXG4gIGxldCBsZWdhY3lfYmVoYXZpb3IgPSBtYXRjaCBsZWdhY3lfYmVoYXZpb3Igd2l0aFxuICAgIHwgU29tZSBmbGFnIC0+IGZsYWdcbiAgICB8IE5vbmUgLT4gdHJ1ZVxuICAoKiAgV2hlbiB0aGlzIGZsYWcgaXMgZW5hYmxlZCwgdGhlIGZvcm1hdCBwYXJzZXIgdHJpZXMgdG8gYmVoYXZlIGFzXG4gICAgICB0aGUgPDQuMDIgaW1wbGVtZW50YXRpb25zLCBpbiBwYXJ0aWN1bGFyIGl0IGlnbm9yZXMgbW9zdCBiZW5pbmVcbiAgICAgIG5vbnNlbnNpY2FsIGZvcm1hdC4gV2hlbiB0aGUgZmxhZyBpcyBkaXNhYmxlZCwgaXQgd2lsbCByZWplY3QgYW55XG4gICAgICBmb3JtYXQgdGhhdCBpcyBub3QgYWNjZXB0ZWQgYnkgdGhlIHNwZWNpZmljYXRpb24uXG5cbiAgICAgIEEgdHlwaWNhbCBleGFtcGxlIHdvdWxkIGJlIFwiJSsgZFwiOiBzcGVjaWZ5aW5nIGJvdGggJysnIChpZiB0aGVcbiAgICAgIG51bWJlciBpcyBwb3NpdGl2ZSwgcGFkIHdpdGggYSAnKycgdG8gZ2V0IHRoZSBzYW1lIHdpZHRoIGFzXG4gICAgICBuZWdhdGl2ZSBudW1iZXJzKSBhbmQgJyAnIChpZiB0aGUgbnVtYmVyIGlzIHBvc2l0aXZlLCBwYWQgd2l0aFxuICAgICAgYSBzcGFjZSkgZG9lcyBub3QgbWFrZSBzZW5zZSwgYnV0IHRoZSBsZWdhY3kgKDwgNC4wMilcbiAgICAgIGltcGxlbWVudGF0aW9uIHdhcyBoYXBweSB0byBqdXN0IGlnbm9yZSB0aGUgc3BhY2UuXG4gICopXG4gIGluXG5cbiAgKCogUmFpc2UgW0ZhaWx1cmVdIHdpdGggYSBmcmllbmRseSBlcnJvciBtZXNzYWdlLiAqKVxuICBsZXQgaW52YWxpZF9mb3JtYXRfbWVzc2FnZSBzdHJfaW5kIG1zZyA9XG4gICAgZmFpbHdpdGhfbWVzc2FnZVxuICAgICAgXCJpbnZhbGlkIGZvcm1hdCAlUzogYXQgY2hhcmFjdGVyIG51bWJlciAlZCwgJXNcIlxuICAgICAgc3RyIHN0cl9pbmQgbXNnXG4gIGluXG5cbiAgKCogVXNlZCB3aGVuIHRoZSBlbmQgb2YgdGhlIGZvcm1hdCAob3IgdGhlIGN1cnJlbnQgc3ViLWZvcm1hdCkgd2FzIGVuY291bnRlcmVkXG4gICAgICB1bmV4cGVjdGVkbHkuICopXG4gIGxldCB1bmV4cGVjdGVkX2VuZF9vZl9mb3JtYXQgZW5kX2luZCA9XG4gICAgaW52YWxpZF9mb3JtYXRfbWVzc2FnZSBlbmRfaW5kXG4gICAgICBcInVuZXhwZWN0ZWQgZW5kIG9mIGZvcm1hdFwiXG4gIGluXG5cbiAgKCogVXNlZCBmb3IgJTBjOiBubyBvdGhlciB3aWR0aHMgYXJlIGltcGxlbWVudGVkICopXG4gIGxldCBpbnZhbGlkX25vbm51bGxfY2hhcl93aWR0aCBzdHJfaW5kID1cbiAgICBpbnZhbGlkX2Zvcm1hdF9tZXNzYWdlIHN0cl9pbmRcbiAgICAgIFwibm9uLXplcm8gd2lkdGhzIGFyZSB1bnN1cHBvcnRlZCBmb3IgJWMgY29udmVyc2lvbnNcIlxuICBpblxuICAoKiBSYWlzZSBbRmFpbHVyZV0gd2l0aCBhIGZyaWVuZGx5IGVycm9yIG1lc3NhZ2UgYWJvdXQgYW4gb3B0aW9uIGRlcGVuZGVuY3lcbiAgICAgcHJvYmxlbS4gKilcbiAgbGV0IGludmFsaWRfZm9ybWF0X3dpdGhvdXQgc3RyX2luZCBjIHMgPVxuICAgIGZhaWx3aXRoX21lc3NhZ2VcbiAgICAgIFwiaW52YWxpZCBmb3JtYXQgJVM6IGF0IGNoYXJhY3RlciBudW1iZXIgJWQsICclYycgd2l0aG91dCAlc1wiXG4gICAgICBzdHIgc3RyX2luZCBjIHNcbiAgaW5cblxuICAoKiBSYWlzZSBbRmFpbHVyZV0gd2l0aCBhIGZyaWVuZGx5IGVycm9yIG1lc3NhZ2UgYWJvdXQgYW4gdW5leHBlY3RlZFxuICAgICBjaGFyYWN0ZXIuICopXG4gIGxldCBleHBlY3RlZF9jaGFyYWN0ZXIgc3RyX2luZCBleHBlY3RlZCByZWFkID1cbiAgICBmYWlsd2l0aF9tZXNzYWdlXG4gICAgIFwiaW52YWxpZCBmb3JtYXQgJVM6IGF0IGNoYXJhY3RlciBudW1iZXIgJWQsICVzIGV4cGVjdGVkLCByZWFkICVDXCJcbiAgICAgIHN0ciBzdHJfaW5kIGV4cGVjdGVkIHJlYWRcbiAgaW5cblxuICAoKiBQYXJzZSB0aGUgc3RyaW5nIGZyb20gYmVnX2luZCAoaW5jbHVkZWQpIHRvIGVuZF9pbmQgKGV4Y2x1ZGVkKS4gKilcbiAgbGV0IHJlYyBwYXJzZSA6IHR5cGUgZSBmIC4gaW50IC0+IGludCAtPiAoXywgXywgZSwgZikgZm10X2ViYiA9XG4gIGZ1biBiZWdfaW5kIGVuZF9pbmQgLT4gcGFyc2VfbGl0ZXJhbCBiZWdfaW5kIGJlZ19pbmQgZW5kX2luZFxuXG4gICgqIFJlYWQgbGl0ZXJhbCBjaGFyYWN0ZXJzIHVwIHRvICclJyBvciAnQCcgc3BlY2lhbCBjaGFyYWN0ZXJzLiAqKVxuICBhbmQgcGFyc2VfbGl0ZXJhbCA6IHR5cGUgZSBmIC4gaW50IC0+IGludCAtPiBpbnQgLT4gKF8sIF8sIGUsIGYpIGZtdF9lYmIgPVxuICBmdW4gbGl0X3N0YXJ0IHN0cl9pbmQgZW5kX2luZCAtPlxuICAgIGlmIHN0cl9pbmQgPSBlbmRfaW5kIHRoZW4gYWRkX2xpdGVyYWwgbGl0X3N0YXJ0IHN0cl9pbmQgRW5kX29mX2Zvcm1hdCBlbHNlXG4gICAgICBtYXRjaCBzdHIuW3N0cl9pbmRdIHdpdGhcbiAgICAgIHwgJyUnIC0+XG4gICAgICAgIGxldCBGbXRfRUJCIGZtdF9yZXN0ID0gcGFyc2VfZm9ybWF0IHN0cl9pbmQgZW5kX2luZCBpblxuICAgICAgICBhZGRfbGl0ZXJhbCBsaXRfc3RhcnQgc3RyX2luZCBmbXRfcmVzdFxuICAgICAgfCAnQCcgLT5cbiAgICAgICAgbGV0IEZtdF9FQkIgZm10X3Jlc3QgPSBwYXJzZV9hZnRlcl9hdCAoc3RyX2luZCArIDEpIGVuZF9pbmQgaW5cbiAgICAgICAgYWRkX2xpdGVyYWwgbGl0X3N0YXJ0IHN0cl9pbmQgZm10X3Jlc3RcbiAgICAgIHwgXyAtPlxuICAgICAgICBwYXJzZV9saXRlcmFsIGxpdF9zdGFydCAoc3RyX2luZCArIDEpIGVuZF9pbmRcblxuICAoKiBQYXJzZSBhIGZvcm1hdCBhZnRlciAnJScgKilcbiAgYW5kIHBhcnNlX2Zvcm1hdCA6IHR5cGUgZSBmIC4gaW50IC0+IGludCAtPiAoXywgXywgZSwgZikgZm10X2ViYiA9XG4gIGZ1biBwY3RfaW5kIGVuZF9pbmQgLT4gcGFyc2VfaWduIHBjdF9pbmQgKHBjdF9pbmQgKyAxKSBlbmRfaW5kXG5cbiAgYW5kIHBhcnNlX2lnbiA6IHR5cGUgZSBmIC4gaW50IC0+IGludCAtPiBpbnQgLT4gKF8sIF8sIGUsIGYpIGZtdF9lYmIgPVxuICBmdW4gcGN0X2luZCBzdHJfaW5kIGVuZF9pbmQgLT5cbiAgICBpZiBzdHJfaW5kID0gZW5kX2luZCB0aGVuIHVuZXhwZWN0ZWRfZW5kX29mX2Zvcm1hdCBlbmRfaW5kO1xuICAgIG1hdGNoIHN0ci5bc3RyX2luZF0gd2l0aFxuICAgICAgfCAnXycgLT4gcGFyc2VfZmxhZ3MgcGN0X2luZCAoc3RyX2luZCsxKSBlbmRfaW5kIHRydWVcbiAgICAgIHwgXyAtPiBwYXJzZV9mbGFncyBwY3RfaW5kIHN0cl9pbmQgZW5kX2luZCBmYWxzZVxuXG4gIGFuZCBwYXJzZV9mbGFncyA6IHR5cGUgZSBmIC4gaW50IC0+IGludCAtPiBpbnQgLT4gYm9vbCAtPiAoXywgXywgZSwgZikgZm10X2ViYlxuICA9XG4gIGZ1biBwY3RfaW5kIHN0cl9pbmQgZW5kX2luZCBpZ24gLT5cbiAgICBsZXQgemVybyA9IHJlZiBmYWxzZSBhbmQgbWludXMgPSByZWYgZmFsc2VcbiAgICBhbmQgcGx1cyA9IHJlZiBmYWxzZSBhbmQgc3BhY2UgPSByZWYgZmFsc2VcbiAgICBhbmQgaGFzaCA9IHJlZiBmYWxzZSBpblxuICAgIGxldCBzZXRfZmxhZyBzdHJfaW5kIGZsYWcgPVxuICAgICAgKCogaW4gbGVnYWN5IG1vZGUsIGR1cGxpY2F0ZSBmbGFncyBhcmUgYWNjZXB0ZWQgKilcbiAgICAgIGlmICFmbGFnICYmIG5vdCBsZWdhY3lfYmVoYXZpb3IgdGhlblxuICAgICAgICBmYWlsd2l0aF9tZXNzYWdlXG4gICAgICAgICAgXCJpbnZhbGlkIGZvcm1hdCAlUzogYXQgY2hhcmFjdGVyIG51bWJlciAlZCwgZHVwbGljYXRlIGZsYWcgJUNcIlxuICAgICAgICAgIHN0ciBzdHJfaW5kIHN0ci5bc3RyX2luZF07XG4gICAgICBmbGFnIDo9IHRydWU7XG4gICAgaW5cbiAgICBsZXQgcmVjIHJlYWRfZmxhZ3Mgc3RyX2luZCA9XG4gICAgICBpZiBzdHJfaW5kID0gZW5kX2luZCB0aGVuIHVuZXhwZWN0ZWRfZW5kX29mX2Zvcm1hdCBlbmRfaW5kO1xuICAgICAgYmVnaW4gbWF0Y2ggc3RyLltzdHJfaW5kXSB3aXRoXG4gICAgICB8ICcwJyAtPiBzZXRfZmxhZyBzdHJfaW5kIHplcm87ICByZWFkX2ZsYWdzIChzdHJfaW5kICsgMSlcbiAgICAgIHwgJy0nIC0+IHNldF9mbGFnIHN0cl9pbmQgbWludXM7IHJlYWRfZmxhZ3MgKHN0cl9pbmQgKyAxKVxuICAgICAgfCAnKycgLT4gc2V0X2ZsYWcgc3RyX2luZCBwbHVzOyAgcmVhZF9mbGFncyAoc3RyX2luZCArIDEpXG4gICAgICB8ICcjJyAtPiBzZXRfZmxhZyBzdHJfaW5kIGhhc2g7IHJlYWRfZmxhZ3MgKHN0cl9pbmQgKyAxKVxuICAgICAgfCAnICcgLT4gc2V0X2ZsYWcgc3RyX2luZCBzcGFjZTsgcmVhZF9mbGFncyAoc3RyX2luZCArIDEpXG4gICAgICB8IF8gLT5cbiAgICAgICAgcGFyc2VfcGFkZGluZyBwY3RfaW5kIHN0cl9pbmQgZW5kX2luZFxuICAgICAgICAgICF6ZXJvICFtaW51cyAhcGx1cyAhaGFzaCAhc3BhY2UgaWduXG4gICAgICBlbmRcbiAgICBpblxuICAgIHJlYWRfZmxhZ3Mgc3RyX2luZFxuXG4gICgqIFRyeSB0byByZWFkIGEgZGlnaXRhbCBvciBhICcqJyBwYWRkaW5nLiAqKVxuICBhbmQgcGFyc2VfcGFkZGluZyA6IHR5cGUgZSBmIC5cbiAgICAgIGludCAtPiBpbnQgLT4gaW50IC0+IGJvb2wgLT4gYm9vbCAtPiBib29sIC0+IGJvb2wgLT4gYm9vbCAtPiBib29sIC0+XG4gICAgICAgIChfLCBfLCBlLCBmKSBmbXRfZWJiID1cbiAgZnVuIHBjdF9pbmQgc3RyX2luZCBlbmRfaW5kIHplcm8gbWludXMgcGx1cyBoYXNoIHNwYWNlIGlnbiAtPlxuICAgIGlmIHN0cl9pbmQgPSBlbmRfaW5kIHRoZW4gdW5leHBlY3RlZF9lbmRfb2ZfZm9ybWF0IGVuZF9pbmQ7XG4gICAgbGV0IHBhZHR5ID0gbWF0Y2ggemVybywgbWludXMgd2l0aFxuICAgICAgfCBmYWxzZSwgZmFsc2UgLT4gUmlnaHRcbiAgICAgIHwgZmFsc2UsIHRydWUgIC0+IExlZnRcbiAgICAgIHwgIHRydWUsIGZhbHNlIC0+IFplcm9zXG4gICAgICB8ICB0cnVlLCB0cnVlICAtPlxuICAgICAgICBpZiBsZWdhY3lfYmVoYXZpb3IgdGhlbiBMZWZ0XG4gICAgICAgIGVsc2UgaW5jb21wYXRpYmxlX2ZsYWcgcGN0X2luZCBzdHJfaW5kICctJyBcIjBcIiBpblxuICAgIG1hdGNoIHN0ci5bc3RyX2luZF0gd2l0aFxuICAgIHwgJzAnIC4uICc5JyAtPlxuICAgICAgbGV0IG5ld19pbmQsIHdpZHRoID0gcGFyc2VfcG9zaXRpdmUgc3RyX2luZCBlbmRfaW5kIDAgaW5cbiAgICAgIHBhcnNlX2FmdGVyX3BhZGRpbmcgcGN0X2luZCBuZXdfaW5kIGVuZF9pbmQgbWludXMgcGx1cyBoYXNoIHNwYWNlIGlnblxuICAgICAgICAoTGl0X3BhZGRpbmcgKHBhZHR5LCB3aWR0aCkpXG4gICAgfCAnKicgLT5cbiAgICAgIHBhcnNlX2FmdGVyX3BhZGRpbmcgcGN0X2luZCAoc3RyX2luZCArIDEpIGVuZF9pbmQgbWludXMgcGx1cyBoYXNoIHNwYWNlXG4gICAgICAgIGlnbiAoQXJnX3BhZGRpbmcgcGFkdHkpXG4gICAgfCBfIC0+XG4gICAgICBiZWdpbiBtYXRjaCBwYWR0eSB3aXRoXG4gICAgICB8IExlZnQgIC0+XG4gICAgICAgIGlmIG5vdCBsZWdhY3lfYmVoYXZpb3IgdGhlblxuICAgICAgICAgIGludmFsaWRfZm9ybWF0X3dpdGhvdXQgKHN0cl9pbmQgLSAxKSAnLScgXCJwYWRkaW5nXCI7XG4gICAgICAgIHBhcnNlX2FmdGVyX3BhZGRpbmcgcGN0X2luZCBzdHJfaW5kIGVuZF9pbmQgbWludXMgcGx1cyBoYXNoIHNwYWNlIGlnblxuICAgICAgICAgIE5vX3BhZGRpbmdcbiAgICAgIHwgWmVyb3MgLT5cbiAgICAgICAgICgqIGEgJzAnIHBhZGRpbmcgaW5kaWNhdGlvbiBub3QgZm9sbG93ZWQgYnkgYW55dGhpbmcgc2hvdWxkXG4gICAgICAgICAgIGJlIGludGVycHJldGVkIGFzIGEgUmlnaHQgcGFkZGluZyBvZiB3aWR0aCAwLiBUaGlzIGlzIHVzZWRcbiAgICAgICAgICAgYnkgc2Nhbm5pbmcgY29udmVyc2lvbnMgJTBzIGFuZCAlMGMgKilcbiAgICAgICAgcGFyc2VfYWZ0ZXJfcGFkZGluZyBwY3RfaW5kIHN0cl9pbmQgZW5kX2luZCBtaW51cyBwbHVzIGhhc2ggc3BhY2UgaWduXG4gICAgICAgICAgKExpdF9wYWRkaW5nIChSaWdodCwgMCkpXG4gICAgICB8IFJpZ2h0IC0+XG4gICAgICAgIHBhcnNlX2FmdGVyX3BhZGRpbmcgcGN0X2luZCBzdHJfaW5kIGVuZF9pbmQgbWludXMgcGx1cyBoYXNoIHNwYWNlIGlnblxuICAgICAgICAgIE5vX3BhZGRpbmdcbiAgICAgIGVuZFxuXG4gICgqIElzIHByZWNpc2lvbiBkZWZpbmVkPyAqKVxuICBhbmQgcGFyc2VfYWZ0ZXJfcGFkZGluZyA6IHR5cGUgeCBlIGYgLlxuICAgICAgaW50IC0+IGludCAtPiBpbnQgLT4gYm9vbCAtPiBib29sIC0+IGJvb2wgLT4gYm9vbCAtPiBib29sIC0+XG4gICAgICAgICh4LCBfKSBwYWRkaW5nIC0+IChfLCBfLCBlLCBmKSBmbXRfZWJiID1cbiAgZnVuIHBjdF9pbmQgc3RyX2luZCBlbmRfaW5kIG1pbnVzIHBsdXMgaGFzaCBzcGFjZSBpZ24gcGFkIC0+XG4gICAgaWYgc3RyX2luZCA9IGVuZF9pbmQgdGhlbiB1bmV4cGVjdGVkX2VuZF9vZl9mb3JtYXQgZW5kX2luZDtcbiAgICBtYXRjaCBzdHIuW3N0cl9pbmRdIHdpdGhcbiAgICB8ICcuJyAtPlxuICAgICAgcGFyc2VfcHJlY2lzaW9uIHBjdF9pbmQgKHN0cl9pbmQgKyAxKSBlbmRfaW5kIG1pbnVzIHBsdXMgaGFzaCBzcGFjZSBpZ25cbiAgICAgICAgcGFkXG4gICAgfCBzeW1iIC0+XG4gICAgICBwYXJzZV9jb252ZXJzaW9uIHBjdF9pbmQgKHN0cl9pbmQgKyAxKSBlbmRfaW5kIHBsdXMgaGFzaCBzcGFjZSBpZ24gcGFkXG4gICAgICAgIE5vX3ByZWNpc2lvbiBwYWQgc3ltYlxuXG4gICgqIFJlYWQgdGhlIGRpZ2l0YWwgb3IgJyonIHByZWNpc2lvbi4gKilcbiAgYW5kIHBhcnNlX3ByZWNpc2lvbiA6IHR5cGUgeCBlIGYgLlxuICAgICAgaW50IC0+IGludCAtPiBpbnQgLT4gYm9vbCAtPiBib29sIC0+IGJvb2wgLT4gYm9vbCAtPiBib29sIC0+XG4gICAgICAgICh4LCBfKSBwYWRkaW5nIC0+IChfLCBfLCBlLCBmKSBmbXRfZWJiID1cbiAgZnVuIHBjdF9pbmQgc3RyX2luZCBlbmRfaW5kIG1pbnVzIHBsdXMgaGFzaCBzcGFjZSBpZ24gcGFkIC0+XG4gICAgaWYgc3RyX2luZCA9IGVuZF9pbmQgdGhlbiB1bmV4cGVjdGVkX2VuZF9vZl9mb3JtYXQgZW5kX2luZDtcbiAgICBsZXQgcGFyc2VfbGl0ZXJhbCBtaW51cyBzdHJfaW5kID1cbiAgICAgIGxldCBuZXdfaW5kLCBwcmVjID0gcGFyc2VfcG9zaXRpdmUgc3RyX2luZCBlbmRfaW5kIDAgaW5cbiAgICAgIHBhcnNlX2FmdGVyX3ByZWNpc2lvbiBwY3RfaW5kIG5ld19pbmQgZW5kX2luZCBtaW51cyBwbHVzIGhhc2ggc3BhY2UgaWduXG4gICAgICAgIHBhZCAoTGl0X3ByZWNpc2lvbiBwcmVjKSBpblxuICAgIG1hdGNoIHN0ci5bc3RyX2luZF0gd2l0aFxuICAgIHwgJzAnIC4uICc5JyAtPiBwYXJzZV9saXRlcmFsIG1pbnVzIHN0cl9pbmRcbiAgICB8ICgnKycgfCAnLScpIGFzIHN5bWIgd2hlbiBsZWdhY3lfYmVoYXZpb3IgLT5cbiAgICAgICgqIExlZ2FjeSBtb2RlIHdvdWxkIGFjY2VwdCBhbmQgaWdub3JlICcrJyBvciAnLScgYmVmb3JlIHRoZVxuICAgICAgICAgaW50ZWdlciBkZXNjcmliaW5nIHRoZSBkZXNpcmVkIHByZWNpc2lvbjsgbm90ZSB0aGF0IHRoaXNcbiAgICAgICAgIGNhbm5vdCBoYXBwZW4gZm9yIHBhZGRpbmcgd2lkdGgsIGFzICcrJyBhbmQgJy0nIGFscmVhZHkgaGF2ZVxuICAgICAgICAgYSBzZW1hbnRpY3MgdGhlcmUuXG5cbiAgICAgICAgIFRoYXQgc2FpZCwgdGhlIGlkZWEgKHN1cHBvcnRlZCBieSB0aGlzIHR3ZWFrKSB0aGF0IHdpZHRoIGFuZFxuICAgICAgICAgcHJlY2lzaW9uIGxpdGVyYWxzIGFyZSBcImludGVnZXIgbGl0ZXJhbHNcIiBpbiB0aGUgT0NhbWwgc2Vuc2UgaXNcbiAgICAgICAgIHN0aWxsIGJsYXRhbnRseSB3cm9uZywgYXMgMTIzXzQ1NiBvciAweEZGIGFyZSByZWplY3RlZC4gKilcbiAgICAgIHBhcnNlX2xpdGVyYWwgKG1pbnVzIHx8IHN5bWIgPSAnLScpIChzdHJfaW5kICsgMSlcbiAgICB8ICcqJyAtPlxuICAgICAgcGFyc2VfYWZ0ZXJfcHJlY2lzaW9uIHBjdF9pbmQgKHN0cl9pbmQgKyAxKSBlbmRfaW5kIG1pbnVzIHBsdXMgaGFzaCBzcGFjZVxuICAgICAgICBpZ24gcGFkIEFyZ19wcmVjaXNpb25cbiAgICB8IF8gLT5cbiAgICAgIGlmIGxlZ2FjeV9iZWhhdmlvciB0aGVuXG4gICAgICAgICgqIG5vdGUgdGhhdCBsZWdhY3kgaW1wbGVtZW50YXRpb24gZGlkIG5vdCBpZ25vcmUgJy4nIHdpdGhvdXRcbiAgICAgICAgICAgYSBudW1iZXIgKGFzIGl0IGRvZXMgZm9yIHBhZGRpbmcgaW5kaWNhdGlvbnMpLCBidXRcbiAgICAgICAgICAgaW50ZXJwcmV0cyBpdCBhcyAnLjAnICopXG4gICAgICAgIHBhcnNlX2FmdGVyX3ByZWNpc2lvbiBwY3RfaW5kIHN0cl9pbmQgZW5kX2luZCBtaW51cyBwbHVzIGhhc2ggc3BhY2UgaWduXG4gICAgICAgICAgcGFkIChMaXRfcHJlY2lzaW9uIDApXG4gICAgICBlbHNlXG4gICAgICAgIGludmFsaWRfZm9ybWF0X3dpdGhvdXQgKHN0cl9pbmQgLSAxKSAnLicgXCJwcmVjaXNpb25cIlxuXG4gICgqIFRyeSB0byByZWFkIHRoZSBjb252ZXJzaW9uLiAqKVxuICBhbmQgcGFyc2VfYWZ0ZXJfcHJlY2lzaW9uIDogdHlwZSB4IHkgeiB0IGUgZiAuXG4gICAgICBpbnQgLT4gaW50IC0+IGludCAtPiBib29sIC0+IGJvb2wgLT4gYm9vbCAtPiBib29sIC0+IGJvb2wgLT5cbiAgICAgICAgKHgsIHkpIHBhZGRpbmcgLT4gKHosIHQpIHByZWNpc2lvbiAtPiAoXywgXywgZSwgZikgZm10X2ViYiA9XG4gIGZ1biBwY3RfaW5kIHN0cl9pbmQgZW5kX2luZCBtaW51cyBwbHVzIGhhc2ggc3BhY2UgaWduIHBhZCBwcmVjIC0+XG4gICAgaWYgc3RyX2luZCA9IGVuZF9pbmQgdGhlbiB1bmV4cGVjdGVkX2VuZF9vZl9mb3JtYXQgZW5kX2luZDtcbiAgICBsZXQgcGFyc2VfY29udiAodHlwZSB1KSAodHlwZSB2KSAocGFkcHJlYyA6ICh1LCB2KSBwYWRkaW5nKSA9XG4gICAgICBwYXJzZV9jb252ZXJzaW9uIHBjdF9pbmQgKHN0cl9pbmQgKyAxKSBlbmRfaW5kIHBsdXMgaGFzaCBzcGFjZSBpZ24gcGFkXG4gICAgICAgIHByZWMgcGFkcHJlYyBzdHIuW3N0cl9pbmRdIGluXG4gICAgKCogaW4gbGVnYWN5IG1vZGUsIHNvbWUgZm9ybWF0cyAoJXMgYW5kICVTKSBhY2NlcHQgYSB3ZWlyZCBtaXggb2ZcbiAgICAgICBwYWRkaW5nIGFuZCBwcmVjaXNpb24sIHdoaWNoIGlzIG1lcmdlZCBhcyBhIHNpbmdsZSBwYWRkaW5nXG4gICAgICAgaW5mb3JtYXRpb24uIEZvciBleGFtcGxlLCBpbiAlLjEwcyB0aGUgcHJlY2lzaW9uIGlzIGltcGxpY2l0bHlcbiAgICAgICB1bmRlcnN0b29kIGFzIHBhZGRpbmcgJTEwcywgYnV0IHRoZSBsZWZ0LXBhZGRpbmcgY29tcG9uZW50IG1heVxuICAgICAgIGJlIHNwZWNpZmllZCBlaXRoZXIgYXMgYSBsZWZ0IHBhZGRpbmcgb3IgYSBuZWdhdGl2ZSBwcmVjaXNpb246XG4gICAgICAgJS0uM3MgYW5kICUuLTNzIGFyZSBlcXVpdmFsZW50IHRvICUtM3MgKilcbiAgICBtYXRjaCBwYWQgd2l0aFxuICAgIHwgTm9fcGFkZGluZyAtPiAoXG4gICAgICBtYXRjaCBtaW51cywgcHJlYyB3aXRoXG4gICAgICAgIHwgXywgTm9fcHJlY2lzaW9uIC0+IHBhcnNlX2NvbnYgTm9fcGFkZGluZ1xuICAgICAgICB8IGZhbHNlLCBMaXRfcHJlY2lzaW9uIG4gLT4gcGFyc2VfY29udiAoTGl0X3BhZGRpbmcgKFJpZ2h0LCBuKSlcbiAgICAgICAgfCB0cnVlLCBMaXRfcHJlY2lzaW9uIG4gLT4gcGFyc2VfY29udiAoTGl0X3BhZGRpbmcgKExlZnQsIG4pKVxuICAgICAgICB8IGZhbHNlLCBBcmdfcHJlY2lzaW9uIC0+IHBhcnNlX2NvbnYgKEFyZ19wYWRkaW5nIFJpZ2h0KVxuICAgICAgICB8IHRydWUsIEFyZ19wcmVjaXNpb24gLT4gcGFyc2VfY29udiAoQXJnX3BhZGRpbmcgTGVmdClcbiAgICApXG4gICAgfCBwYWQgLT4gcGFyc2VfY29udiBwYWRcblxuICAoKiBDYXNlIGFuYWx5c2lzIG9uIGNvbnZlcnNpb24uICopXG4gIGFuZCBwYXJzZV9jb252ZXJzaW9uIDogdHlwZSB4IHkgeiB0IHUgdiBlIGYgLlxuICAgICAgaW50IC0+IGludCAtPiBpbnQgLT4gYm9vbCAtPiBib29sIC0+IGJvb2wgLT4gYm9vbCAtPiAoeCwgeSkgcGFkZGluZyAtPlxuICAgICAgICAoeiwgdCkgcHJlY2lzaW9uIC0+ICh1LCB2KSBwYWRkaW5nIC0+IGNoYXIgLT4gKF8sIF8sIGUsIGYpIGZtdF9lYmIgPVxuICBmdW4gcGN0X2luZCBzdHJfaW5kIGVuZF9pbmQgcGx1cyBoYXNoIHNwYWNlIGlnbiBwYWQgcHJlYyBwYWRwcmVjIHN5bWIgLT5cbiAgICAoKiBGbGFncyB1c2VkIHRvIGNoZWNrIG9wdGlvbiB1c2FnZXMvY29tcGF0aWJpbGl0aWVzLiAqKVxuICAgIGxldCBwbHVzX3VzZWQgID0gcmVmIGZhbHNlIGFuZCBoYXNoX3VzZWQgPSByZWYgZmFsc2VcbiAgICBhbmQgc3BhY2VfdXNlZCA9IHJlZiBmYWxzZSBhbmQgaWduX3VzZWQgICA9IHJlZiBmYWxzZVxuICAgIGFuZCBwYWRfdXNlZCAgID0gcmVmIGZhbHNlIGFuZCBwcmVjX3VzZWQgID0gcmVmIGZhbHNlIGluXG5cbiAgICAoKiBBY2Nlc3MgdG8gb3B0aW9ucywgdXBkYXRlIGZsYWdzLiAqKVxuICAgIGxldCBnZXRfcGx1cyAgICAoKSA9IHBsdXNfdXNlZCAgOj0gdHJ1ZTsgcGx1c1xuICAgIGFuZCBnZXRfaGFzaCAgICgpID0gaGFzaF91c2VkIDo9IHRydWU7IGhhc2hcbiAgICBhbmQgZ2V0X3NwYWNlICAgKCkgPSBzcGFjZV91c2VkIDo9IHRydWU7IHNwYWNlXG4gICAgYW5kIGdldF9pZ24gICAgICgpID0gaWduX3VzZWQgICA6PSB0cnVlOyBpZ25cbiAgICBhbmQgZ2V0X3BhZCAgICAgKCkgPSBwYWRfdXNlZCAgIDo9IHRydWU7IHBhZFxuICAgIGFuZCBnZXRfcHJlYyAgICAoKSA9IHByZWNfdXNlZCAgOj0gdHJ1ZTsgcHJlY1xuICAgIGFuZCBnZXRfcGFkcHJlYyAoKSA9IHBhZF91c2VkICAgOj0gdHJ1ZTsgcGFkcHJlYyBpblxuXG4gICAgbGV0IGdldF9pbnRfcGFkICgpIDogKHgseSkgcGFkZGluZyA9XG4gICAgICAoKiAlNS4zZCBpcyBhY2NlcHRlZCBhbmQgbWVhbmluZ2Z1bDogcGFkIHRvIGxlbmd0aCA1IHdpdGhcbiAgICAgICAgIHNwYWNlcywgYnV0IGZpcnN0IHBhZCB3aXRoIHplcm9zIHVwdG8gbGVuZ3RoIDMgKDAtcGFkZGluZ1xuICAgICAgICAgaXMgdGhlIGludGVycHJldGF0aW9uIG9mIFwicHJlY2lzaW9uXCIgZm9yIGludGVnZXIgZm9ybWF0cykuXG5cbiAgICAgICAgICUwNS4zZCBpcyByZWR1bmRhbnQ6IHBhZCB0byBsZW5ndGggNSAqd2l0aCB6ZXJvcyosIGJ1dFxuICAgICAgICAgZmlyc3QgcGFkIHdpdGggemVyb3MuLi4gVG8gYWRkIGluc3VsdCB0byB0aGUgaW5qdXJ5LCB0aGVcbiAgICAgICAgIGxlZ2FjeSBpbXBsZW1lbnRhdGlvbiBpZ25vcmVzIHRoZSAwLXBhZGRpbmcgaW5kaWNhdGlvbiBhbmRcbiAgICAgICAgIGRvZXMgdGhlIDUgcGFkZGluZyB3aXRoIHNwYWNlcyBpbnN0ZWFkLiBXZSByZXVzZSB0aGlzXG4gICAgICAgICBpbnRlcnByZXRhdGlvbiBmb3IgY29tcGF0aWJpbGl0eSwgYnV0IHN0YXRpY2FsbHkgcmVqZWN0IHRoaXNcbiAgICAgICAgIGZvcm1hdCB3aGVuIHRoZSBsZWdhY3kgbW9kZSBpcyBkaXNhYmxlZCwgdG8gcHJvdGVjdCBzdHJpY3RcbiAgICAgICAgIHVzZXJzIGZyb20gdGhpcyBjb3JuZXIgY2FzZS4gKilcbiAgICAgICBtYXRjaCBnZXRfcGFkICgpLCBnZXRfcHJlYyAoKSB3aXRoXG4gICAgICAgICB8IHBhZCwgTm9fcHJlY2lzaW9uIC0+IHBhZFxuICAgICAgICAgfCBOb19wYWRkaW5nLCBfICAgICAtPiBOb19wYWRkaW5nXG4gICAgICAgICB8IExpdF9wYWRkaW5nIChaZXJvcywgbiksIF8gLT5cbiAgICAgICAgICAgaWYgbGVnYWN5X2JlaGF2aW9yIHRoZW4gTGl0X3BhZGRpbmcgKFJpZ2h0LCBuKVxuICAgICAgICAgICBlbHNlIGluY29tcGF0aWJsZV9mbGFnIHBjdF9pbmQgc3RyX2luZCAnMCcgXCJwcmVjaXNpb25cIlxuICAgICAgICAgfCBBcmdfcGFkZGluZyBaZXJvcywgXyAtPlxuICAgICAgICAgICBpZiBsZWdhY3lfYmVoYXZpb3IgdGhlbiBBcmdfcGFkZGluZyBSaWdodFxuICAgICAgICAgICBlbHNlIGluY29tcGF0aWJsZV9mbGFnIHBjdF9pbmQgc3RyX2luZCAnMCcgXCJwcmVjaXNpb25cIlxuICAgICAgICAgfCBMaXRfcGFkZGluZyBfIGFzIHBhZCwgXyAtPiBwYWRcbiAgICAgICAgIHwgQXJnX3BhZGRpbmcgXyBhcyBwYWQsIF8gLT4gcGFkIGluXG5cbiAgICAoKiBDaGVjayB0aGF0IHBhZHR5IDw+IFplcm9zLiAqKVxuICAgIGxldCBjaGVja19ub18wIHN5bWIgKHR5cGUgYSBiKSAocGFkIDogKGEsIGIpIHBhZGRpbmcpIDogKGEsYikgcGFkZGluZyA9XG4gICAgICBtYXRjaCBwYWQgd2l0aFxuICAgICAgfCBOb19wYWRkaW5nIC0+IHBhZFxuICAgICAgfCBMaXRfcGFkZGluZyAoKExlZnQgfCBSaWdodCksIF8pIC0+IHBhZFxuICAgICAgfCBBcmdfcGFkZGluZyAoTGVmdCB8IFJpZ2h0KSAtPiBwYWRcbiAgICAgIHwgTGl0X3BhZGRpbmcgKFplcm9zLCB3aWR0aCkgLT5cbiAgICAgICAgaWYgbGVnYWN5X2JlaGF2aW9yIHRoZW4gTGl0X3BhZGRpbmcgKFJpZ2h0LCB3aWR0aClcbiAgICAgICAgZWxzZSBpbmNvbXBhdGlibGVfZmxhZyBwY3RfaW5kIHN0cl9pbmQgc3ltYiBcIjBcIlxuICAgICAgfCBBcmdfcGFkZGluZyBaZXJvcyAtPlxuICAgICAgICBpZiBsZWdhY3lfYmVoYXZpb3IgdGhlbiBBcmdfcGFkZGluZyBSaWdodFxuICAgICAgICBlbHNlIGluY29tcGF0aWJsZV9mbGFnIHBjdF9pbmQgc3RyX2luZCBzeW1iIFwiMFwiXG4gICAgaW5cblxuICAgICgqIEdldCBwYWRkaW5nIGFzIGEgcGFkX29wdGlvbiAoc2VlIFwiJV9cIiwgXCIle1wiLCBcIiUoXCIgYW5kIFwiJVtcIikuXG4gICAgICAgKG5vIG5lZWQgZm9yIGxlZ2FjeSBtb2RlIHR3ZWFraW5nLCB0aG9zZSB3ZXJlIHJlamVjdGVkIGJ5IHRoZVxuICAgICAgIGxlZ2FjeSBwYXJzZXIgYXMgd2VsbCkgKilcbiAgICBsZXQgb3B0X29mX3BhZCBjICh0eXBlIGEpICh0eXBlIGIpIChwYWQgOiAoYSwgYikgcGFkZGluZykgPSBtYXRjaCBwYWQgd2l0aFxuICAgICAgfCBOb19wYWRkaW5nIC0+IE5vbmVcbiAgICAgIHwgTGl0X3BhZGRpbmcgKFJpZ2h0LCB3aWR0aCkgLT4gU29tZSB3aWR0aFxuICAgICAgfCBMaXRfcGFkZGluZyAoWmVyb3MsIHdpZHRoKSAtPlxuICAgICAgICBpZiBsZWdhY3lfYmVoYXZpb3IgdGhlbiBTb21lIHdpZHRoXG4gICAgICAgIGVsc2UgaW5jb21wYXRpYmxlX2ZsYWcgcGN0X2luZCBzdHJfaW5kIGMgXCInMCdcIlxuICAgICAgfCBMaXRfcGFkZGluZyAoTGVmdCwgd2lkdGgpIC0+XG4gICAgICAgIGlmIGxlZ2FjeV9iZWhhdmlvciB0aGVuIFNvbWUgd2lkdGhcbiAgICAgICAgZWxzZSBpbmNvbXBhdGlibGVfZmxhZyBwY3RfaW5kIHN0cl9pbmQgYyBcIictJ1wiXG4gICAgICB8IEFyZ19wYWRkaW5nIF8gLT4gaW5jb21wYXRpYmxlX2ZsYWcgcGN0X2luZCBzdHJfaW5kIGMgXCInKidcIlxuICAgIGluXG4gICAgbGV0IGdldF9wYWRfb3B0IGMgPSBvcHRfb2ZfcGFkIGMgKGdldF9wYWQgKCkpIGluXG4gICAgbGV0IGdldF9wYWRwcmVjX29wdCBjID0gb3B0X29mX3BhZCBjIChnZXRfcGFkcHJlYyAoKSkgaW5cblxuICAgICgqIEdldCBwcmVjaXNpb24gYXMgYSBwcmVjX29wdGlvbiAoc2VlIFwiJV9mXCIpLlxuICAgICAgIChubyBuZWVkIGZvciBsZWdhY3kgbW9kZSB0d2Vha2luZywgdGhvc2Ugd2VyZSByZWplY3RlZCBieSB0aGVcbiAgICAgICBsZWdhY3kgcGFyc2VyIGFzIHdlbGwpICopXG4gICAgbGV0IGdldF9wcmVjX29wdCAoKSA9IG1hdGNoIGdldF9wcmVjICgpIHdpdGhcbiAgICAgIHwgTm9fcHJlY2lzaW9uICAgICAgIC0+IE5vbmVcbiAgICAgIHwgTGl0X3ByZWNpc2lvbiBuZGVjIC0+IFNvbWUgbmRlY1xuICAgICAgfCBBcmdfcHJlY2lzaW9uICAgICAgLT4gaW5jb21wYXRpYmxlX2ZsYWcgcGN0X2luZCBzdHJfaW5kICdfJyBcIicqJ1wiXG4gICAgaW5cblxuICAgIGxldCBmbXRfcmVzdWx0ID0gbWF0Y2ggc3ltYiB3aXRoXG4gICAgfCAnLCcgLT5cbiAgICAgIHBhcnNlIHN0cl9pbmQgZW5kX2luZFxuICAgIHwgJ2MnIC0+XG4gICAgICBsZXQgY2hhcl9mb3JtYXQgZm10X3Jlc3QgPSAoKiAlYyAqKVxuICAgICAgICBpZiBnZXRfaWduICgpXG4gICAgICAgIHRoZW4gRm10X0VCQiAoSWdub3JlZF9wYXJhbSAoSWdub3JlZF9jaGFyLCBmbXRfcmVzdCkpXG4gICAgICAgIGVsc2UgRm10X0VCQiAoQ2hhciBmbXRfcmVzdClcbiAgICAgIGluXG4gICAgICBsZXQgc2Nhbl9mb3JtYXQgZm10X3Jlc3QgPSAoKiAlMGMgKilcbiAgICAgICAgaWYgZ2V0X2lnbiAoKVxuICAgICAgICB0aGVuIEZtdF9FQkIgKElnbm9yZWRfcGFyYW0gKElnbm9yZWRfc2Nhbl9uZXh0X2NoYXIsIGZtdF9yZXN0KSlcbiAgICAgICAgZWxzZSBGbXRfRUJCIChTY2FuX25leHRfY2hhciBmbXRfcmVzdClcbiAgICAgIGluXG4gICAgICBsZXQgRm10X0VCQiBmbXRfcmVzdCA9IHBhcnNlIHN0cl9pbmQgZW5kX2luZCBpblxuICAgICAgYmVnaW4gbWF0Y2ggZ2V0X3BhZF9vcHQgJ2MnIHdpdGhcbiAgICAgICAgfCBOb25lIC0+IGNoYXJfZm9ybWF0IGZtdF9yZXN0XG4gICAgICAgIHwgU29tZSAwIC0+IHNjYW5fZm9ybWF0IGZtdF9yZXN0XG4gICAgICAgIHwgU29tZSBfbiAtPlxuICAgICAgICAgICBpZiBub3QgbGVnYWN5X2JlaGF2aW9yXG4gICAgICAgICAgIHRoZW4gaW52YWxpZF9ub25udWxsX2NoYXJfd2lkdGggc3RyX2luZFxuICAgICAgICAgICBlbHNlICgqIGxlZ2FjeSBpZ25vcmVzICVjIHdpZHRocyAqKSBjaGFyX2Zvcm1hdCBmbXRfcmVzdFxuICAgICAgZW5kXG4gICAgfCAnQycgLT5cbiAgICAgIGxldCBGbXRfRUJCIGZtdF9yZXN0ID0gcGFyc2Ugc3RyX2luZCBlbmRfaW5kIGluXG4gICAgICBpZiBnZXRfaWduICgpIHRoZW4gRm10X0VCQiAoSWdub3JlZF9wYXJhbSAoSWdub3JlZF9jYW1sX2NoYXIsZm10X3Jlc3QpKVxuICAgICAgZWxzZSBGbXRfRUJCIChDYW1sX2NoYXIgZm10X3Jlc3QpXG4gICAgfCAncycgLT5cbiAgICAgIGxldCBwYWQgPSBjaGVja19ub18wIHN5bWIgKGdldF9wYWRwcmVjICgpKSBpblxuICAgICAgbGV0IEZtdF9FQkIgZm10X3Jlc3QgPSBwYXJzZSBzdHJfaW5kIGVuZF9pbmQgaW5cbiAgICAgIGlmIGdldF9pZ24gKCkgdGhlblxuICAgICAgICBsZXQgaWdub3JlZCA9IElnbm9yZWRfc3RyaW5nIChnZXRfcGFkcHJlY19vcHQgJ18nKSBpblxuICAgICAgICBGbXRfRUJCIChJZ25vcmVkX3BhcmFtIChpZ25vcmVkLCBmbXRfcmVzdCkpXG4gICAgICBlbHNlXG4gICAgICAgIGxldCBQYWRkaW5nX2ZtdF9FQkIgKHBhZCcsIGZtdF9yZXN0JykgPVxuICAgICAgICAgIG1ha2VfcGFkZGluZ19mbXRfZWJiIHBhZCBmbXRfcmVzdCBpblxuICAgICAgICBGbXRfRUJCIChTdHJpbmcgKHBhZCcsIGZtdF9yZXN0JykpXG4gICAgfCAnUycgLT5cbiAgICAgIGxldCBwYWQgPSBjaGVja19ub18wIHN5bWIgKGdldF9wYWRwcmVjICgpKSBpblxuICAgICAgbGV0IEZtdF9FQkIgZm10X3Jlc3QgPSBwYXJzZSBzdHJfaW5kIGVuZF9pbmQgaW5cbiAgICAgIGlmIGdldF9pZ24gKCkgdGhlblxuICAgICAgICBsZXQgaWdub3JlZCA9IElnbm9yZWRfY2FtbF9zdHJpbmcgKGdldF9wYWRwcmVjX29wdCAnXycpIGluXG4gICAgICAgIEZtdF9FQkIgKElnbm9yZWRfcGFyYW0gKGlnbm9yZWQsIGZtdF9yZXN0KSlcbiAgICAgIGVsc2VcbiAgICAgICAgbGV0IFBhZGRpbmdfZm10X0VCQiAocGFkJywgZm10X3Jlc3QnKSA9XG4gICAgICAgICAgbWFrZV9wYWRkaW5nX2ZtdF9lYmIgcGFkIGZtdF9yZXN0IGluXG4gICAgICAgIEZtdF9FQkIgKENhbWxfc3RyaW5nIChwYWQnLCBmbXRfcmVzdCcpKVxuICAgIHwgJ2QnIHwgJ2knIHwgJ3gnIHwgJ1gnIHwgJ28nIHwgJ3UnIC0+XG4gICAgICBsZXQgaWNvbnYgPSBjb21wdXRlX2ludF9jb252IHBjdF9pbmQgc3RyX2luZCAoZ2V0X3BsdXMgKCkpIChnZXRfaGFzaCAoKSlcbiAgICAgICAgKGdldF9zcGFjZSAoKSkgc3ltYiBpblxuICAgICAgbGV0IEZtdF9FQkIgZm10X3Jlc3QgPSBwYXJzZSBzdHJfaW5kIGVuZF9pbmQgaW5cbiAgICAgIGlmIGdldF9pZ24gKCkgdGhlblxuICAgICAgICBsZXQgaWdub3JlZCA9IElnbm9yZWRfaW50IChpY29udiwgZ2V0X3BhZF9vcHQgJ18nKSBpblxuICAgICAgICBGbXRfRUJCIChJZ25vcmVkX3BhcmFtIChpZ25vcmVkLCBmbXRfcmVzdCkpXG4gICAgICBlbHNlXG4gICAgICAgIGxldCBQYWRwcmVjX2ZtdF9FQkIgKHBhZCcsIHByZWMnLCBmbXRfcmVzdCcpID1cbiAgICAgICAgICBtYWtlX3BhZHByZWNfZm10X2ViYiAoZ2V0X2ludF9wYWQgKCkpIChnZXRfcHJlYyAoKSkgZm10X3Jlc3QgaW5cbiAgICAgICAgRm10X0VCQiAoSW50IChpY29udiwgcGFkJywgcHJlYycsIGZtdF9yZXN0JykpXG4gICAgfCAnTicgLT5cbiAgICAgIGxldCBGbXRfRUJCIGZtdF9yZXN0ID0gcGFyc2Ugc3RyX2luZCBlbmRfaW5kIGluXG4gICAgICBsZXQgY291bnRlciA9IFRva2VuX2NvdW50ZXIgaW5cbiAgICAgIGlmIGdldF9pZ24gKCkgdGhlblxuICAgICAgICBsZXQgaWdub3JlZCA9IElnbm9yZWRfc2Nhbl9nZXRfY291bnRlciBjb3VudGVyIGluXG4gICAgICAgIEZtdF9FQkIgKElnbm9yZWRfcGFyYW0gKGlnbm9yZWQsIGZtdF9yZXN0KSlcbiAgICAgIGVsc2VcbiAgICAgICAgRm10X0VCQiAoU2Nhbl9nZXRfY291bnRlciAoY291bnRlciwgZm10X3Jlc3QpKVxuICAgIHwgJ2wnIHwgJ24nIHwgJ0wnIHdoZW4gc3RyX2luZD1lbmRfaW5kIHx8IG5vdCAoaXNfaW50X2Jhc2Ugc3RyLltzdHJfaW5kXSkgLT5cbiAgICAgIGxldCBGbXRfRUJCIGZtdF9yZXN0ID0gcGFyc2Ugc3RyX2luZCBlbmRfaW5kIGluXG4gICAgICBsZXQgY291bnRlciA9IGNvdW50ZXJfb2ZfY2hhciBzeW1iIGluXG4gICAgICBpZiBnZXRfaWduICgpIHRoZW5cbiAgICAgICAgbGV0IGlnbm9yZWQgPSBJZ25vcmVkX3NjYW5fZ2V0X2NvdW50ZXIgY291bnRlciBpblxuICAgICAgICBGbXRfRUJCIChJZ25vcmVkX3BhcmFtIChpZ25vcmVkLCBmbXRfcmVzdCkpXG4gICAgICBlbHNlXG4gICAgICAgIEZtdF9FQkIgKFNjYW5fZ2V0X2NvdW50ZXIgKGNvdW50ZXIsIGZtdF9yZXN0KSlcbiAgICB8ICdsJyAtPlxuICAgICAgbGV0IGljb252ID1cbiAgICAgICAgY29tcHV0ZV9pbnRfY29udiBwY3RfaW5kIChzdHJfaW5kICsgMSkgKGdldF9wbHVzICgpKSAoZ2V0X2hhc2ggKCkpXG4gICAgICAgICAgKGdldF9zcGFjZSAoKSkgc3RyLltzdHJfaW5kXSBpblxuICAgICAgbGV0IEZtdF9FQkIgZm10X3Jlc3QgPSBwYXJzZSAoc3RyX2luZCArIDEpIGVuZF9pbmQgaW5cbiAgICAgIGlmIGdldF9pZ24gKCkgdGhlblxuICAgICAgICBsZXQgaWdub3JlZCA9IElnbm9yZWRfaW50MzIgKGljb252LCBnZXRfcGFkX29wdCAnXycpIGluXG4gICAgICAgIEZtdF9FQkIgKElnbm9yZWRfcGFyYW0gKGlnbm9yZWQsIGZtdF9yZXN0KSlcbiAgICAgIGVsc2VcbiAgICAgICAgbGV0IFBhZHByZWNfZm10X0VCQiAocGFkJywgcHJlYycsIGZtdF9yZXN0JykgPVxuICAgICAgICAgIG1ha2VfcGFkcHJlY19mbXRfZWJiIChnZXRfaW50X3BhZCAoKSkgKGdldF9wcmVjICgpKSBmbXRfcmVzdCBpblxuICAgICAgICBGbXRfRUJCIChJbnQzMiAoaWNvbnYsIHBhZCcsIHByZWMnLCBmbXRfcmVzdCcpKVxuICAgIHwgJ24nIC0+XG4gICAgICBsZXQgaWNvbnYgPVxuICAgICAgICBjb21wdXRlX2ludF9jb252IHBjdF9pbmQgKHN0cl9pbmQgKyAxKSAoZ2V0X3BsdXMgKCkpXG4gICAgICAgICAgKGdldF9oYXNoICgpKSAoZ2V0X3NwYWNlICgpKSBzdHIuW3N0cl9pbmRdIGluXG4gICAgICBsZXQgRm10X0VCQiBmbXRfcmVzdCA9IHBhcnNlIChzdHJfaW5kICsgMSkgZW5kX2luZCBpblxuICAgICAgaWYgZ2V0X2lnbiAoKSB0aGVuXG4gICAgICAgIGxldCBpZ25vcmVkID0gSWdub3JlZF9uYXRpdmVpbnQgKGljb252LCBnZXRfcGFkX29wdCAnXycpIGluXG4gICAgICAgIEZtdF9FQkIgKElnbm9yZWRfcGFyYW0gKGlnbm9yZWQsIGZtdF9yZXN0KSlcbiAgICAgIGVsc2VcbiAgICAgICAgbGV0IFBhZHByZWNfZm10X0VCQiAocGFkJywgcHJlYycsIGZtdF9yZXN0JykgPVxuICAgICAgICAgIG1ha2VfcGFkcHJlY19mbXRfZWJiIChnZXRfaW50X3BhZCAoKSkgKGdldF9wcmVjICgpKSBmbXRfcmVzdCBpblxuICAgICAgICBGbXRfRUJCIChOYXRpdmVpbnQgKGljb252LCBwYWQnLCBwcmVjJywgZm10X3Jlc3QnKSlcbiAgICB8ICdMJyAtPlxuICAgICAgbGV0IGljb252ID1cbiAgICAgICAgY29tcHV0ZV9pbnRfY29udiBwY3RfaW5kIChzdHJfaW5kICsgMSkgKGdldF9wbHVzICgpKSAoZ2V0X2hhc2ggKCkpXG4gICAgICAgICAgKGdldF9zcGFjZSAoKSkgc3RyLltzdHJfaW5kXSBpblxuICAgICAgbGV0IEZtdF9FQkIgZm10X3Jlc3QgPSBwYXJzZSAoc3RyX2luZCArIDEpIGVuZF9pbmQgaW5cbiAgICAgIGlmIGdldF9pZ24gKCkgdGhlblxuICAgICAgICBsZXQgaWdub3JlZCA9IElnbm9yZWRfaW50NjQgKGljb252LCBnZXRfcGFkX29wdCAnXycpIGluXG4gICAgICAgIEZtdF9FQkIgKElnbm9yZWRfcGFyYW0gKGlnbm9yZWQsIGZtdF9yZXN0KSlcbiAgICAgIGVsc2VcbiAgICAgICAgbGV0IFBhZHByZWNfZm10X0VCQiAocGFkJywgcHJlYycsIGZtdF9yZXN0JykgPVxuICAgICAgICAgIG1ha2VfcGFkcHJlY19mbXRfZWJiIChnZXRfaW50X3BhZCAoKSkgKGdldF9wcmVjICgpKSBmbXRfcmVzdCBpblxuICAgICAgICBGbXRfRUJCIChJbnQ2NCAoaWNvbnYsIHBhZCcsIHByZWMnLCBmbXRfcmVzdCcpKVxuICAgIHwgJ2YnIHwgJ2UnIHwgJ0UnIHwgJ2cnIHwgJ0cnIHwgJ0YnIHwgJ2gnIHwgJ0gnIC0+XG4gICAgICBsZXQgZmNvbnYgPVxuICAgICAgICBjb21wdXRlX2Zsb2F0X2NvbnYgcGN0X2luZCBzdHJfaW5kXG4gICAgICAgICAgKGdldF9wbHVzICgpKSAoZ2V0X2hhc2ggKCkpIChnZXRfc3BhY2UgKCkpIHN5bWIgaW5cbiAgICAgIGxldCBGbXRfRUJCIGZtdF9yZXN0ID0gcGFyc2Ugc3RyX2luZCBlbmRfaW5kIGluXG4gICAgICBpZiBnZXRfaWduICgpIHRoZW5cbiAgICAgICAgbGV0IGlnbm9yZWQgPSBJZ25vcmVkX2Zsb2F0IChnZXRfcGFkX29wdCAnXycsIGdldF9wcmVjX29wdCAoKSkgaW5cbiAgICAgICAgRm10X0VCQiAoSWdub3JlZF9wYXJhbSAoaWdub3JlZCwgZm10X3Jlc3QpKVxuICAgICAgZWxzZVxuICAgICAgICBsZXQgUGFkcHJlY19mbXRfRUJCIChwYWQnLCBwcmVjJywgZm10X3Jlc3QnKSA9XG4gICAgICAgICAgbWFrZV9wYWRwcmVjX2ZtdF9lYmIgKGdldF9wYWQgKCkpIChnZXRfcHJlYyAoKSkgZm10X3Jlc3QgaW5cbiAgICAgICAgRm10X0VCQiAoRmxvYXQgKGZjb252LCBwYWQnLCBwcmVjJywgZm10X3Jlc3QnKSlcbiAgICB8ICdiJyB8ICdCJyAtPlxuICAgICAgbGV0IHBhZCA9IGNoZWNrX25vXzAgc3ltYiAoZ2V0X3BhZHByZWMgKCkpIGluXG4gICAgICBsZXQgRm10X0VCQiBmbXRfcmVzdCA9IHBhcnNlIHN0cl9pbmQgZW5kX2luZCBpblxuICAgICAgaWYgZ2V0X2lnbiAoKSB0aGVuXG4gICAgICAgIGxldCBpZ25vcmVkID0gSWdub3JlZF9ib29sIChnZXRfcGFkcHJlY19vcHQgJ18nKSBpblxuICAgICAgICBGbXRfRUJCIChJZ25vcmVkX3BhcmFtIChpZ25vcmVkLCBmbXRfcmVzdCkpXG4gICAgICBlbHNlXG4gICAgICAgIGxldCBQYWRkaW5nX2ZtdF9FQkIgKHBhZCcsIGZtdF9yZXN0JykgPVxuICAgICAgICAgIG1ha2VfcGFkZGluZ19mbXRfZWJiIHBhZCBmbXRfcmVzdCBpblxuICAgICAgICBGbXRfRUJCIChCb29sIChwYWQnLCBmbXRfcmVzdCcpKVxuICAgIHwgJ2EnIC0+XG4gICAgICBsZXQgRm10X0VCQiBmbXRfcmVzdCA9IHBhcnNlIHN0cl9pbmQgZW5kX2luZCBpblxuICAgICAgRm10X0VCQiAoQWxwaGEgZm10X3Jlc3QpXG4gICAgfCAndCcgLT5cbiAgICAgIGxldCBGbXRfRUJCIGZtdF9yZXN0ID0gcGFyc2Ugc3RyX2luZCBlbmRfaW5kIGluXG4gICAgICBGbXRfRUJCIChUaGV0YSBmbXRfcmVzdClcbiAgICB8ICdyJyAtPlxuICAgICAgbGV0IEZtdF9FQkIgZm10X3Jlc3QgPSBwYXJzZSBzdHJfaW5kIGVuZF9pbmQgaW5cbiAgICAgIGlmIGdldF9pZ24gKCkgdGhlbiBGbXRfRUJCIChJZ25vcmVkX3BhcmFtIChJZ25vcmVkX3JlYWRlciwgZm10X3Jlc3QpKVxuICAgICAgZWxzZSBGbXRfRUJCIChSZWFkZXIgZm10X3Jlc3QpXG4gICAgfCAnIScgLT5cbiAgICAgIGxldCBGbXRfRUJCIGZtdF9yZXN0ID0gcGFyc2Ugc3RyX2luZCBlbmRfaW5kIGluXG4gICAgICBGbXRfRUJCIChGbHVzaCBmbXRfcmVzdClcbiAgICB8ICgnJScgfCAnQCcpIGFzIGMgLT5cbiAgICAgIGxldCBGbXRfRUJCIGZtdF9yZXN0ID0gcGFyc2Ugc3RyX2luZCBlbmRfaW5kIGluXG4gICAgICBGbXRfRUJCIChDaGFyX2xpdGVyYWwgKGMsIGZtdF9yZXN0KSlcbiAgICB8ICd7JyAtPlxuICAgICAgbGV0IHN1Yl9lbmQgPSBzZWFyY2hfc3ViZm9ybWF0X2VuZCBzdHJfaW5kIGVuZF9pbmQgJ30nIGluXG4gICAgICBsZXQgRm10X0VCQiBzdWJfZm10ID0gcGFyc2Ugc3RyX2luZCBzdWJfZW5kIGluXG4gICAgICBsZXQgRm10X0VCQiBmbXRfcmVzdCA9IHBhcnNlIChzdWJfZW5kICsgMikgZW5kX2luZCBpblxuICAgICAgbGV0IHN1Yl9mbXR0eSA9IGZtdHR5X29mX2ZtdCBzdWJfZm10IGluXG4gICAgICBpZiBnZXRfaWduICgpIHRoZW5cbiAgICAgICAgbGV0IGlnbm9yZWQgPSBJZ25vcmVkX2Zvcm1hdF9hcmcgKGdldF9wYWRfb3B0ICdfJywgc3ViX2ZtdHR5KSBpblxuICAgICAgICBGbXRfRUJCIChJZ25vcmVkX3BhcmFtIChpZ25vcmVkLCBmbXRfcmVzdCkpXG4gICAgICBlbHNlXG4gICAgICAgIEZtdF9FQkIgKEZvcm1hdF9hcmcgKGdldF9wYWRfb3B0ICd7Jywgc3ViX2ZtdHR5LCBmbXRfcmVzdCkpXG4gICAgfCAnKCcgLT5cbiAgICAgIGxldCBzdWJfZW5kID0gc2VhcmNoX3N1YmZvcm1hdF9lbmQgc3RyX2luZCBlbmRfaW5kICcpJyBpblxuICAgICAgbGV0IEZtdF9FQkIgZm10X3Jlc3QgPSBwYXJzZSAoc3ViX2VuZCArIDIpIGVuZF9pbmQgaW5cbiAgICAgIGxldCBGbXRfRUJCIHN1Yl9mbXQgPSBwYXJzZSBzdHJfaW5kIHN1Yl9lbmQgaW5cbiAgICAgIGxldCBzdWJfZm10dHkgPSBmbXR0eV9vZl9mbXQgc3ViX2ZtdCBpblxuICAgICAgaWYgZ2V0X2lnbiAoKSB0aGVuXG4gICAgICAgIGxldCBpZ25vcmVkID0gSWdub3JlZF9mb3JtYXRfc3Vic3QgKGdldF9wYWRfb3B0ICdfJywgc3ViX2ZtdHR5KSBpblxuICAgICAgICBGbXRfRUJCIChJZ25vcmVkX3BhcmFtIChpZ25vcmVkLCBmbXRfcmVzdCkpXG4gICAgICBlbHNlXG4gICAgICAgIEZtdF9FQkIgKEZvcm1hdF9zdWJzdCAoZ2V0X3BhZF9vcHQgJygnLCBzdWJfZm10dHksIGZtdF9yZXN0KSlcbiAgICB8ICdbJyAtPlxuICAgICAgbGV0IG5leHRfaW5kLCBjaGFyX3NldCA9IHBhcnNlX2NoYXJfc2V0IHN0cl9pbmQgZW5kX2luZCBpblxuICAgICAgbGV0IEZtdF9FQkIgZm10X3Jlc3QgPSBwYXJzZSBuZXh0X2luZCBlbmRfaW5kIGluXG4gICAgICBpZiBnZXRfaWduICgpIHRoZW5cbiAgICAgICAgbGV0IGlnbm9yZWQgPSBJZ25vcmVkX3NjYW5fY2hhcl9zZXQgKGdldF9wYWRfb3B0ICdfJywgY2hhcl9zZXQpIGluXG4gICAgICAgIEZtdF9FQkIgKElnbm9yZWRfcGFyYW0gKGlnbm9yZWQsIGZtdF9yZXN0KSlcbiAgICAgIGVsc2VcbiAgICAgICAgRm10X0VCQiAoU2Nhbl9jaGFyX3NldCAoZ2V0X3BhZF9vcHQgJ1snLCBjaGFyX3NldCwgZm10X3Jlc3QpKVxuICAgIHwgJy0nIHwgJysnIHwgJyMnIHwgJyAnIHwgJ18nIC0+XG4gICAgICBmYWlsd2l0aF9tZXNzYWdlXG4gICAgICAgIFwiaW52YWxpZCBmb3JtYXQgJVM6IGF0IGNoYXJhY3RlciBudW1iZXIgJWQsIFxcXG4gICAgICAgICBmbGFnICVDIGlzIG9ubHkgYWxsb3dlZCBhZnRlciB0aGUgJyUlJywgYmVmb3JlIHBhZGRpbmcgYW5kIHByZWNpc2lvblwiXG4gICAgICAgIHN0ciBwY3RfaW5kIHN5bWJcbiAgICB8IF8gLT5cbiAgICAgIGZhaWx3aXRoX21lc3NhZ2VcbiAgICAgICAgXCJpbnZhbGlkIGZvcm1hdCAlUzogYXQgY2hhcmFjdGVyIG51bWJlciAlZCwgXFxcbiAgICAgICAgIGludmFsaWQgY29udmVyc2lvbiBcXFwiJSUlY1xcXCJcIiBzdHIgKHN0cl9pbmQgLSAxKSBzeW1iXG4gICAgaW5cbiAgICAoKiBDaGVjayBmb3IgdW51c2VkIG9wdGlvbnMsIGFuZCByZWplY3QgdGhlbSBhcyBpbmNvbXBhdGlibGUuXG5cbiAgICAgICBTdWNoIGNoZWNrcyBuZWVkIHRvIGJlIGRpc2FibGVkIGluIGxlZ2FjeSBtb2RlLCBhcyB0aGUgbGVnYWN5XG4gICAgICAgcGFyc2VyIHNpbGVudGx5IGlnbm9yZWQgaW5jb21wYXRpYmxlIGZsYWdzLiAqKVxuICAgIGlmIG5vdCBsZWdhY3lfYmVoYXZpb3IgdGhlbiBiZWdpblxuICAgIGlmIG5vdCAhcGx1c191c2VkICYmIHBsdXMgdGhlblxuICAgICAgaW5jb21wYXRpYmxlX2ZsYWcgcGN0X2luZCBzdHJfaW5kIHN5bWIgXCInKydcIjtcbiAgICBpZiBub3QgIWhhc2hfdXNlZCAmJiBoYXNoIHRoZW5cbiAgICAgIGluY29tcGF0aWJsZV9mbGFnIHBjdF9pbmQgc3RyX2luZCBzeW1iIFwiJyMnXCI7XG4gICAgaWYgbm90ICFzcGFjZV91c2VkICYmIHNwYWNlIHRoZW5cbiAgICAgIGluY29tcGF0aWJsZV9mbGFnIHBjdF9pbmQgc3RyX2luZCBzeW1iIFwiJyAnXCI7XG4gICAgaWYgbm90ICFwYWRfdXNlZCAgJiYgUGFkZGluZ19FQkIgcGFkIDw+IFBhZGRpbmdfRUJCIE5vX3BhZGRpbmcgdGhlblxuICAgICAgaW5jb21wYXRpYmxlX2ZsYWcgcGN0X2luZCBzdHJfaW5kIHN5bWIgXCJgcGFkZGluZydcIjtcbiAgICBpZiBub3QgIXByZWNfdXNlZCAmJiBQcmVjaXNpb25fRUJCIHByZWMgPD4gUHJlY2lzaW9uX0VCQiBOb19wcmVjaXNpb24gdGhlblxuICAgICAgaW5jb21wYXRpYmxlX2ZsYWcgcGN0X2luZCBzdHJfaW5kIChpZiBpZ24gdGhlbiAnXycgZWxzZSBzeW1iKVxuICAgICAgICBcImBwcmVjaXNpb24nXCI7XG4gICAgaWYgaWduICYmIHBsdXMgdGhlbiBpbmNvbXBhdGlibGVfZmxhZyBwY3RfaW5kIHN0cl9pbmQgJ18nIFwiJysnXCI7XG4gICAgZW5kO1xuICAgICgqIHRoaXMgbGFzdCB0ZXN0IG11c3Qgbm90IGJlIGRpc2FibGVkIGluIGxlZ2FjeSBtb2RlLFxuICAgICAgIGFzIGlnbm9yaW5nIGl0IHdvdWxkIHR5cGljYWxseSByZXN1bHQgaW4gYSBkaWZmZXJlbnQgdHlwaW5nXG4gICAgICAgdGhhbiB3aGF0IHRoZSBsZWdhY3kgcGFyc2VyIHVzZWQgKilcbiAgICBpZiBub3QgIWlnbl91c2VkICYmIGlnbiB0aGVuXG4gICAgICBiZWdpbiBtYXRjaCBzeW1iIHdpdGhcbiAgICAgICAgKCogYXJndW1lbnQtbGVzcyBmb3JtYXRzIGNhbiBzYWZlbHkgYmUgaWdub3JlZCBpbiBsZWdhY3kgbW9kZSAqKVxuICAgICAgICB8ICgnQCcgfCAnJScgfCAnIScgfCAnLCcpIHdoZW4gbGVnYWN5X2JlaGF2aW9yIC0+ICgpXG4gICAgICAgIHwgXyAtPlxuICAgICAgICAgIGluY29tcGF0aWJsZV9mbGFnIHBjdF9pbmQgc3RyX2luZCBzeW1iIFwiJ18nXCJcbiAgICAgIGVuZDtcbiAgICBmbXRfcmVzdWx0XG5cbiAgKCogUGFyc2UgZm9ybWF0dGluZyBpbmZvcm1hdGlvbiAoYWZ0ZXIgJ0AnKS4gKilcbiAgYW5kIHBhcnNlX2FmdGVyX2F0IDogdHlwZSBlIGYgLiBpbnQgLT4gaW50IC0+IChfLCBfLCBlLCBmKSBmbXRfZWJiID1cbiAgZnVuIHN0cl9pbmQgZW5kX2luZCAtPlxuICAgIGlmIHN0cl9pbmQgPSBlbmRfaW5kIHRoZW4gRm10X0VCQiAoQ2hhcl9saXRlcmFsICgnQCcsIEVuZF9vZl9mb3JtYXQpKVxuICAgIGVsc2VcbiAgICAgIG1hdGNoIHN0ci5bc3RyX2luZF0gd2l0aFxuICAgICAgfCAnWycgLT5cbiAgICAgICAgcGFyc2VfdGFnIGZhbHNlIChzdHJfaW5kICsgMSkgZW5kX2luZFxuICAgICAgfCAnXScgLT5cbiAgICAgICAgbGV0IEZtdF9FQkIgZm10X3Jlc3QgPSBwYXJzZSAoc3RyX2luZCArIDEpIGVuZF9pbmQgaW5cbiAgICAgICAgRm10X0VCQiAoRm9ybWF0dGluZ19saXQgKENsb3NlX2JveCwgZm10X3Jlc3QpKVxuICAgICAgfCAneycgLT5cbiAgICAgICAgcGFyc2VfdGFnIHRydWUgKHN0cl9pbmQgKyAxKSBlbmRfaW5kXG4gICAgICB8ICd9JyAtPlxuICAgICAgICBsZXQgRm10X0VCQiBmbXRfcmVzdCA9IHBhcnNlIChzdHJfaW5kICsgMSkgZW5kX2luZCBpblxuICAgICAgICBGbXRfRUJCIChGb3JtYXR0aW5nX2xpdCAoQ2xvc2VfdGFnLCBmbXRfcmVzdCkpXG4gICAgICB8ICcsJyAtPlxuICAgICAgICBsZXQgRm10X0VCQiBmbXRfcmVzdCA9IHBhcnNlIChzdHJfaW5kICsgMSkgZW5kX2luZCBpblxuICAgICAgICBGbXRfRUJCIChGb3JtYXR0aW5nX2xpdCAoQnJlYWsgKFwiQCxcIiwgMCwgMCksIGZtdF9yZXN0KSlcbiAgICAgIHwgJyAnIC0+XG4gICAgICAgIGxldCBGbXRfRUJCIGZtdF9yZXN0ID0gcGFyc2UgKHN0cl9pbmQgKyAxKSBlbmRfaW5kIGluXG4gICAgICAgIEZtdF9FQkIgKEZvcm1hdHRpbmdfbGl0IChCcmVhayAoXCJAIFwiLCAxLCAwKSwgZm10X3Jlc3QpKVxuICAgICAgfCAnOycgLT5cbiAgICAgICAgcGFyc2VfZ29vZF9icmVhayAoc3RyX2luZCArIDEpIGVuZF9pbmRcbiAgICAgIHwgJz8nIC0+XG4gICAgICAgIGxldCBGbXRfRUJCIGZtdF9yZXN0ID0gcGFyc2UgKHN0cl9pbmQgKyAxKSBlbmRfaW5kIGluXG4gICAgICAgIEZtdF9FQkIgKEZvcm1hdHRpbmdfbGl0IChGRmx1c2gsIGZtdF9yZXN0KSlcbiAgICAgIHwgJ1xcbicgLT5cbiAgICAgICAgbGV0IEZtdF9FQkIgZm10X3Jlc3QgPSBwYXJzZSAoc3RyX2luZCArIDEpIGVuZF9pbmQgaW5cbiAgICAgICAgRm10X0VCQiAoRm9ybWF0dGluZ19saXQgKEZvcmNlX25ld2xpbmUsIGZtdF9yZXN0KSlcbiAgICAgIHwgJy4nIC0+XG4gICAgICAgIGxldCBGbXRfRUJCIGZtdF9yZXN0ID0gcGFyc2UgKHN0cl9pbmQgKyAxKSBlbmRfaW5kIGluXG4gICAgICAgIEZtdF9FQkIgKEZvcm1hdHRpbmdfbGl0IChGbHVzaF9uZXdsaW5lLCBmbXRfcmVzdCkpXG4gICAgICB8ICc8JyAtPlxuICAgICAgICBwYXJzZV9tYWdpY19zaXplIChzdHJfaW5kICsgMSkgZW5kX2luZFxuICAgICAgfCAnQCcgLT5cbiAgICAgICAgbGV0IEZtdF9FQkIgZm10X3Jlc3QgPSBwYXJzZSAoc3RyX2luZCArIDEpIGVuZF9pbmQgaW5cbiAgICAgICAgRm10X0VCQiAoRm9ybWF0dGluZ19saXQgKEVzY2FwZWRfYXQsIGZtdF9yZXN0KSlcbiAgICAgIHwgJyUnIHdoZW4gc3RyX2luZCArIDEgPCBlbmRfaW5kICYmIHN0ci5bc3RyX2luZCArIDFdID0gJyUnIC0+XG4gICAgICAgIGxldCBGbXRfRUJCIGZtdF9yZXN0ID0gcGFyc2UgKHN0cl9pbmQgKyAyKSBlbmRfaW5kIGluXG4gICAgICAgIEZtdF9FQkIgKEZvcm1hdHRpbmdfbGl0IChFc2NhcGVkX3BlcmNlbnQsIGZtdF9yZXN0KSlcbiAgICAgIHwgJyUnIC0+XG4gICAgICAgIGxldCBGbXRfRUJCIGZtdF9yZXN0ID0gcGFyc2Ugc3RyX2luZCBlbmRfaW5kIGluXG4gICAgICAgIEZtdF9FQkIgKENoYXJfbGl0ZXJhbCAoJ0AnLCBmbXRfcmVzdCkpXG4gICAgICB8IGMgLT5cbiAgICAgICAgbGV0IEZtdF9FQkIgZm10X3Jlc3QgPSBwYXJzZSAoc3RyX2luZCArIDEpIGVuZF9pbmQgaW5cbiAgICAgICAgRm10X0VCQiAoRm9ybWF0dGluZ19saXQgKFNjYW5faW5kaWMgYywgZm10X3Jlc3QpKVxuXG4gICgqIFRyeSB0byByZWFkIHRoZSBvcHRpb25hbCA8bmFtZT4gYWZ0ZXIgXCJAe1wiIG9yIFwiQFtcIi4gKilcbiAgYW5kIHBhcnNlX3RhZyA6IHR5cGUgZSBmIC4gYm9vbCAtPiBpbnQgLT4gaW50IC0+IChfLCBfLCBlLCBmKSBmbXRfZWJiID1cbiAgZnVuIGlzX29wZW5fdGFnIHN0cl9pbmQgZW5kX2luZCAtPlxuICAgIHRyeVxuICAgICAgaWYgc3RyX2luZCA9IGVuZF9pbmQgdGhlbiByYWlzZSBOb3RfZm91bmQ7XG4gICAgICBtYXRjaCBzdHIuW3N0cl9pbmRdIHdpdGhcbiAgICAgIHwgJzwnIC0+XG4gICAgICAgIGxldCBpbmQgPSBTdHJpbmcuaW5kZXhfZnJvbSBzdHIgKHN0cl9pbmQgKyAxKSAnPicgaW5cbiAgICAgICAgaWYgaW5kID49IGVuZF9pbmQgdGhlbiByYWlzZSBOb3RfZm91bmQ7XG4gICAgICAgIGxldCBzdWJfc3RyID0gU3RyaW5nLnN1YiBzdHIgc3RyX2luZCAoaW5kIC0gc3RyX2luZCArIDEpIGluXG4gICAgICAgIGxldCBGbXRfRUJCIGZtdF9yZXN0ID0gcGFyc2UgKGluZCArIDEpIGVuZF9pbmQgaW5cbiAgICAgICAgbGV0IEZtdF9FQkIgc3ViX2ZtdCA9IHBhcnNlIHN0cl9pbmQgKGluZCArIDEpIGluXG4gICAgICAgIGxldCBzdWJfZm9ybWF0ID0gRm9ybWF0IChzdWJfZm10LCBzdWJfc3RyKSBpblxuICAgICAgICBsZXQgZm9ybWF0dGluZyA9XG4gICAgICAgICAgaWYgaXNfb3Blbl90YWcgdGhlbiBPcGVuX3RhZyBzdWJfZm9ybWF0IGVsc2UgT3Blbl9ib3ggc3ViX2Zvcm1hdCBpblxuICAgICAgICBGbXRfRUJCIChGb3JtYXR0aW5nX2dlbiAoZm9ybWF0dGluZywgZm10X3Jlc3QpKVxuICAgICAgfCBfIC0+XG4gICAgICAgIHJhaXNlIE5vdF9mb3VuZFxuICAgIHdpdGggTm90X2ZvdW5kIC0+XG4gICAgICBsZXQgRm10X0VCQiBmbXRfcmVzdCA9IHBhcnNlIHN0cl9pbmQgZW5kX2luZCBpblxuICAgICAgbGV0IHN1Yl9mb3JtYXQgPSBGb3JtYXQgKEVuZF9vZl9mb3JtYXQsIFwiXCIpIGluXG4gICAgICBsZXQgZm9ybWF0dGluZyA9XG4gICAgICAgIGlmIGlzX29wZW5fdGFnIHRoZW4gT3Blbl90YWcgc3ViX2Zvcm1hdCBlbHNlIE9wZW5fYm94IHN1Yl9mb3JtYXQgaW5cbiAgICAgIEZtdF9FQkIgKEZvcm1hdHRpbmdfZ2VuIChmb3JtYXR0aW5nLCBmbXRfcmVzdCkpXG5cbiAgKCogVHJ5IHRvIHJlYWQgdGhlIG9wdGlvbmFsIDx3aWR0aCBvZmZzZXQ+IGFmdGVyIFwiQDtcIi4gKilcbiAgYW5kIHBhcnNlX2dvb2RfYnJlYWsgOiB0eXBlIGUgZiAuIGludCAtPiBpbnQgLT4gKF8sIF8sIGUsIGYpIGZtdF9lYmIgPVxuICBmdW4gc3RyX2luZCBlbmRfaW5kIC0+XG4gICAgbGV0IG5leHRfaW5kLCBmb3JtYXR0aW5nX2xpdCA9XG4gICAgICB0cnlcbiAgICAgICAgaWYgc3RyX2luZCA9IGVuZF9pbmQgfHwgc3RyLltzdHJfaW5kXSA8PiAnPCcgdGhlbiByYWlzZSBOb3RfZm91bmQ7XG4gICAgICAgIGxldCBzdHJfaW5kXzEgPSBwYXJzZV9zcGFjZXMgKHN0cl9pbmQgKyAxKSBlbmRfaW5kIGluXG4gICAgICAgIG1hdGNoIHN0ci5bc3RyX2luZF8xXSB3aXRoXG4gICAgICAgIHwgJzAnIC4uICc5JyB8ICctJyAtPiAoXG4gICAgICAgICAgbGV0IHN0cl9pbmRfMiwgd2lkdGggPSBwYXJzZV9pbnRlZ2VyIHN0cl9pbmRfMSBlbmRfaW5kIGluXG4gICAgICAgICAgICBsZXQgc3RyX2luZF8zID0gcGFyc2Vfc3BhY2VzIHN0cl9pbmRfMiBlbmRfaW5kIGluXG4gICAgICAgICAgICBtYXRjaCBzdHIuW3N0cl9pbmRfM10gd2l0aFxuICAgICAgICAgICAgICB8ICc+JyAtPlxuICAgICAgICAgICAgICAgIGxldCBzID0gU3RyaW5nLnN1YiBzdHIgKHN0cl9pbmQtMikgKHN0cl9pbmRfMy1zdHJfaW5kKzMpIGluXG4gICAgICAgICAgICAgICAgc3RyX2luZF8zICsgMSwgQnJlYWsgKHMsIHdpZHRoLCAwKVxuICAgICAgICAgICAgICB8ICcwJyAuLiAnOScgfCAnLScgLT5cbiAgICAgICAgICAgICAgICBsZXQgc3RyX2luZF80LCBvZmZzZXQgPSBwYXJzZV9pbnRlZ2VyIHN0cl9pbmRfMyBlbmRfaW5kIGluXG4gICAgICAgICAgICAgICAgbGV0IHN0cl9pbmRfNSA9IHBhcnNlX3NwYWNlcyBzdHJfaW5kXzQgZW5kX2luZCBpblxuICAgICAgICAgICAgICAgIGlmIHN0ci5bc3RyX2luZF81XSA8PiAnPicgdGhlbiByYWlzZSBOb3RfZm91bmQ7XG4gICAgICAgICAgICAgICAgbGV0IHMgPSBTdHJpbmcuc3ViIHN0ciAoc3RyX2luZC0yKSAoc3RyX2luZF81LXN0cl9pbmQrMykgaW5cbiAgICAgICAgICAgICAgICBzdHJfaW5kXzUgKyAxLCBCcmVhayAocywgd2lkdGgsIG9mZnNldClcbiAgICAgICAgICAgICAgfCBfIC0+IHJhaXNlIE5vdF9mb3VuZFxuICAgICAgICApXG4gICAgICAgIHwgXyAtPiByYWlzZSBOb3RfZm91bmRcbiAgICAgIHdpdGggTm90X2ZvdW5kIHwgRmFpbHVyZSBfIC0+XG4gICAgICAgIHN0cl9pbmQsIEJyZWFrIChcIkA7XCIsIDEsIDApXG4gICAgaW5cbiAgICBsZXQgRm10X0VCQiBmbXRfcmVzdCA9IHBhcnNlIG5leHRfaW5kIGVuZF9pbmQgaW5cbiAgICBGbXRfRUJCIChGb3JtYXR0aW5nX2xpdCAoZm9ybWF0dGluZ19saXQsIGZtdF9yZXN0KSlcblxuICAoKiBQYXJzZSB0aGUgc2l6ZSBpbiBhIDxuPi4gKilcbiAgYW5kIHBhcnNlX21hZ2ljX3NpemUgOiB0eXBlIGUgZiAuIGludCAtPiBpbnQgLT4gKF8sIF8sIGUsIGYpIGZtdF9lYmIgPVxuICBmdW4gc3RyX2luZCBlbmRfaW5kIC0+XG4gICAgbWF0Y2hcbiAgICAgIHRyeVxuICAgICAgICBsZXQgc3RyX2luZF8xID0gcGFyc2Vfc3BhY2VzIHN0cl9pbmQgZW5kX2luZCBpblxuICAgICAgICBtYXRjaCBzdHIuW3N0cl9pbmRfMV0gd2l0aFxuICAgICAgICB8ICcwJyAuLiAnOScgfCAnLScgLT5cbiAgICAgICAgICBsZXQgc3RyX2luZF8yLCBzaXplID0gcGFyc2VfaW50ZWdlciBzdHJfaW5kXzEgZW5kX2luZCBpblxuICAgICAgICAgIGxldCBzdHJfaW5kXzMgPSBwYXJzZV9zcGFjZXMgc3RyX2luZF8yIGVuZF9pbmQgaW5cbiAgICAgICAgICBpZiBzdHIuW3N0cl9pbmRfM10gPD4gJz4nIHRoZW4gcmFpc2UgTm90X2ZvdW5kO1xuICAgICAgICAgIGxldCBzID0gU3RyaW5nLnN1YiBzdHIgKHN0cl9pbmQgLSAyKSAoc3RyX2luZF8zIC0gc3RyX2luZCArIDMpIGluXG4gICAgICAgICAgU29tZSAoc3RyX2luZF8zICsgMSwgTWFnaWNfc2l6ZSAocywgc2l6ZSkpXG4gICAgICAgIHwgXyAtPiBOb25lXG4gICAgICB3aXRoIE5vdF9mb3VuZCB8IEZhaWx1cmUgXyAtPlxuICAgICAgICBOb25lXG4gICAgd2l0aFxuICAgIHwgU29tZSAobmV4dF9pbmQsIGZvcm1hdHRpbmdfbGl0KSAtPlxuICAgICAgbGV0IEZtdF9FQkIgZm10X3Jlc3QgPSBwYXJzZSBuZXh0X2luZCBlbmRfaW5kIGluXG4gICAgICBGbXRfRUJCIChGb3JtYXR0aW5nX2xpdCAoZm9ybWF0dGluZ19saXQsIGZtdF9yZXN0KSlcbiAgICB8IE5vbmUgLT5cbiAgICAgIGxldCBGbXRfRUJCIGZtdF9yZXN0ID0gcGFyc2Ugc3RyX2luZCBlbmRfaW5kIGluXG4gICAgICBGbXRfRUJCIChGb3JtYXR0aW5nX2xpdCAoU2Nhbl9pbmRpYyAnPCcsIGZtdF9yZXN0KSlcblxuICAoKiBQYXJzZSBhbmQgY29uc3RydWN0IGEgY2hhciBzZXQuICopXG4gIGFuZCBwYXJzZV9jaGFyX3NldCBzdHJfaW5kIGVuZF9pbmQgPVxuICAgIGlmIHN0cl9pbmQgPSBlbmRfaW5kIHRoZW4gdW5leHBlY3RlZF9lbmRfb2ZfZm9ybWF0IGVuZF9pbmQ7XG5cbiAgICBsZXQgY2hhcl9zZXQgPSBjcmVhdGVfY2hhcl9zZXQgKCkgaW5cbiAgICBsZXQgYWRkX2NoYXIgYyA9XG4gICAgICBhZGRfaW5fY2hhcl9zZXQgY2hhcl9zZXQgYztcbiAgICBpblxuICAgIGxldCBhZGRfcmFuZ2UgYyBjJyA9XG4gICAgICBmb3IgaSA9IGludF9vZl9jaGFyIGMgdG8gaW50X29mX2NoYXIgYycgZG9cbiAgICAgICAgYWRkX2luX2NoYXJfc2V0IGNoYXJfc2V0IChjaGFyX29mX2ludCBpKTtcbiAgICAgIGRvbmU7XG4gICAgaW5cblxuICAgIGxldCBmYWlsX3NpbmdsZV9wZXJjZW50IHN0cl9pbmQgPVxuICAgICAgZmFpbHdpdGhfbWVzc2FnZVxuICAgICAgICBcImludmFsaWQgZm9ybWF0ICVTOiAnJSUnIGFsb25lIGlzIG5vdCBhY2NlcHRlZCBpbiBjaGFyYWN0ZXIgc2V0cywgXFxcbiAgICAgICAgIHVzZSAlJSUlIGluc3RlYWQgYXQgcG9zaXRpb24gJWQuXCIgc3RyIHN0cl9pbmRcbiAgICBpblxuXG4gICAgKCogUGFyc2UgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiBhIGNoYXIgc2V0LiAqKVxuICAgIGxldCByZWMgcGFyc2VfY2hhcl9zZXRfc3RhcnQgc3RyX2luZCBlbmRfaW5kID1cbiAgICAgIGlmIHN0cl9pbmQgPSBlbmRfaW5kIHRoZW4gdW5leHBlY3RlZF9lbmRfb2ZfZm9ybWF0IGVuZF9pbmQ7XG4gICAgICBsZXQgYyA9IHN0ci5bc3RyX2luZF0gaW5cbiAgICAgIHBhcnNlX2NoYXJfc2V0X2FmdGVyX2NoYXIgKHN0cl9pbmQgKyAxKSBlbmRfaW5kIGNcblxuICAgICgqIFBhcnNlIHRoZSBjb250ZW50IG9mIGEgY2hhciBzZXQgdW50aWwgdGhlIGZpcnN0ICddJy4gKilcbiAgICBhbmQgcGFyc2VfY2hhcl9zZXRfY29udGVudCBzdHJfaW5kIGVuZF9pbmQgPVxuICAgICAgaWYgc3RyX2luZCA9IGVuZF9pbmQgdGhlbiB1bmV4cGVjdGVkX2VuZF9vZl9mb3JtYXQgZW5kX2luZDtcbiAgICAgIG1hdGNoIHN0ci5bc3RyX2luZF0gd2l0aFxuICAgICAgfCAnXScgLT5cbiAgICAgICAgc3RyX2luZCArIDFcbiAgICAgIHwgJy0nIC0+XG4gICAgICAgIGFkZF9jaGFyICctJztcbiAgICAgICAgcGFyc2VfY2hhcl9zZXRfY29udGVudCAoc3RyX2luZCArIDEpIGVuZF9pbmRcbiAgICAgIHwgYyAtPlxuICAgICAgICBwYXJzZV9jaGFyX3NldF9hZnRlcl9jaGFyIChzdHJfaW5kICsgMSkgZW5kX2luZCBjXG5cbiAgICAoKiBUZXN0IGZvciByYW5nZSBpbiBjaGFyIHNldC4gKilcbiAgICBhbmQgcGFyc2VfY2hhcl9zZXRfYWZ0ZXJfY2hhciBzdHJfaW5kIGVuZF9pbmQgYyA9XG4gICAgICBpZiBzdHJfaW5kID0gZW5kX2luZCB0aGVuIHVuZXhwZWN0ZWRfZW5kX29mX2Zvcm1hdCBlbmRfaW5kO1xuICAgICAgbWF0Y2ggc3RyLltzdHJfaW5kXSB3aXRoXG4gICAgICB8ICddJyAtPlxuICAgICAgICBhZGRfY2hhciBjO1xuICAgICAgICBzdHJfaW5kICsgMVxuICAgICAgfCAnLScgLT5cbiAgICAgICAgcGFyc2VfY2hhcl9zZXRfYWZ0ZXJfbWludXMgKHN0cl9pbmQgKyAxKSBlbmRfaW5kIGNcbiAgICAgIHwgKCclJyB8ICdAJykgYXMgYycgd2hlbiBjID0gJyUnIC0+XG4gICAgICAgIGFkZF9jaGFyIGMnO1xuICAgICAgICBwYXJzZV9jaGFyX3NldF9jb250ZW50IChzdHJfaW5kICsgMSkgZW5kX2luZFxuICAgICAgfCBjJyAtPlxuICAgICAgICBpZiBjID0gJyUnIHRoZW4gZmFpbF9zaW5nbGVfcGVyY2VudCBzdHJfaW5kO1xuICAgICAgICAoKiBub3RlIHRoYXQgJ0AnIGFsb25lIGlzIGFjY2VwdGVkLCBhcyBkb25lIGJ5IHRoZSBsZWdhY3lcbiAgICAgICAgICAgaW1wbGVtZW50YXRpb247IHRoZSBkb2N1bWVudGF0aW9uIHNwZWNpZmljYWxseSByZXF1aXJlcyAlQFxuICAgICAgICAgICBzbyB3ZSBjb3VsZCB3YXJuIG9uIHRoYXQgKilcbiAgICAgICAgYWRkX2NoYXIgYztcbiAgICAgICAgcGFyc2VfY2hhcl9zZXRfYWZ0ZXJfY2hhciAoc3RyX2luZCArIDEpIGVuZF9pbmQgYydcblxuICAgICgqIE1hbmFnZSByYW5nZSBpbiBjaGFyIHNldCAoZXhjZXB0IGlmIHRoZSAnLScgdGhlIGxhc3QgY2hhciBiZWZvcmUgJ10nKSAqKVxuICAgIGFuZCBwYXJzZV9jaGFyX3NldF9hZnRlcl9taW51cyBzdHJfaW5kIGVuZF9pbmQgYyA9XG4gICAgICBpZiBzdHJfaW5kID0gZW5kX2luZCB0aGVuIHVuZXhwZWN0ZWRfZW5kX29mX2Zvcm1hdCBlbmRfaW5kO1xuICAgICAgbWF0Y2ggc3RyLltzdHJfaW5kXSB3aXRoXG4gICAgICB8ICddJyAtPlxuICAgICAgICBhZGRfY2hhciBjO1xuICAgICAgICBhZGRfY2hhciAnLSc7XG4gICAgICAgIHN0cl9pbmQgKyAxXG4gICAgICB8ICclJyAtPlxuICAgICAgICBpZiBzdHJfaW5kICsgMSA9IGVuZF9pbmQgdGhlbiB1bmV4cGVjdGVkX2VuZF9vZl9mb3JtYXQgZW5kX2luZDtcbiAgICAgICAgYmVnaW4gbWF0Y2ggc3RyLltzdHJfaW5kICsgMV0gd2l0aFxuICAgICAgICAgIHwgKCclJyB8ICdAJykgYXMgYycgLT5cbiAgICAgICAgICAgIGFkZF9yYW5nZSBjIGMnO1xuICAgICAgICAgICAgcGFyc2VfY2hhcl9zZXRfY29udGVudCAoc3RyX2luZCArIDIpIGVuZF9pbmRcbiAgICAgICAgICB8IF8gLT4gZmFpbF9zaW5nbGVfcGVyY2VudCBzdHJfaW5kXG4gICAgICAgIGVuZFxuICAgICAgfCBjJyAtPlxuICAgICAgICBhZGRfcmFuZ2UgYyBjJztcbiAgICAgICAgcGFyc2VfY2hhcl9zZXRfY29udGVudCAoc3RyX2luZCArIDEpIGVuZF9pbmRcbiAgICBpblxuICAgIGxldCBzdHJfaW5kLCByZXZlcnNlID1cbiAgICAgIGlmIHN0cl9pbmQgPSBlbmRfaW5kIHRoZW4gdW5leHBlY3RlZF9lbmRfb2ZfZm9ybWF0IGVuZF9pbmQ7XG4gICAgICBtYXRjaCBzdHIuW3N0cl9pbmRdIHdpdGhcbiAgICAgICAgfCAnXicgLT4gc3RyX2luZCArIDEsIHRydWVcbiAgICAgICAgfCBfIC0+IHN0cl9pbmQsIGZhbHNlIGluXG4gICAgbGV0IG5leHRfaW5kID0gcGFyc2VfY2hhcl9zZXRfc3RhcnQgc3RyX2luZCBlbmRfaW5kIGluXG4gICAgbGV0IGNoYXJfc2V0ID0gZnJlZXplX2NoYXJfc2V0IGNoYXJfc2V0IGluXG4gICAgbmV4dF9pbmQsIChpZiByZXZlcnNlIHRoZW4gcmV2X2NoYXJfc2V0IGNoYXJfc2V0IGVsc2UgY2hhcl9zZXQpXG5cbiAgKCogQ29uc3VtZSBhbGwgbmV4dCBzcGFjZXMsIHJhaXNlIGFuIEZhaWx1cmUgaWYgZW5kX2luZCBpcyByZWFjaGVkLiAqKVxuICBhbmQgcGFyc2Vfc3BhY2VzIHN0cl9pbmQgZW5kX2luZCA9XG4gICAgaWYgc3RyX2luZCA9IGVuZF9pbmQgdGhlbiB1bmV4cGVjdGVkX2VuZF9vZl9mb3JtYXQgZW5kX2luZDtcbiAgICBpZiBzdHIuW3N0cl9pbmRdID0gJyAnIHRoZW4gcGFyc2Vfc3BhY2VzIChzdHJfaW5kICsgMSkgZW5kX2luZCBlbHNlIHN0cl9pbmRcblxuICAoKiBSZWFkIGEgcG9zaXRpdmUgaW50ZWdlciBmcm9tIHRoZSBzdHJpbmcsIHJhaXNlIGEgRmFpbHVyZSBpZiBlbmRfaW5kIGlzXG4gICAgIHJlYWNoZWQuICopXG4gIGFuZCBwYXJzZV9wb3NpdGl2ZSBzdHJfaW5kIGVuZF9pbmQgYWNjID1cbiAgICBpZiBzdHJfaW5kID0gZW5kX2luZCB0aGVuIHVuZXhwZWN0ZWRfZW5kX29mX2Zvcm1hdCBlbmRfaW5kO1xuICAgIG1hdGNoIHN0ci5bc3RyX2luZF0gd2l0aFxuICAgIHwgJzAnIC4uICc5JyBhcyBjIC0+XG4gICAgICBsZXQgbmV3X2FjYyA9IGFjYyAqIDEwICsgKGludF9vZl9jaGFyIGMgLSBpbnRfb2ZfY2hhciAnMCcpIGluXG4gICAgICBpZiBuZXdfYWNjID4gU3lzLm1heF9zdHJpbmdfbGVuZ3RoIHRoZW5cbiAgICAgICAgZmFpbHdpdGhfbWVzc2FnZVxuICAgICAgICAgIFwiaW52YWxpZCBmb3JtYXQgJVM6IGludGVnZXIgJWQgaXMgZ3JlYXRlciB0aGFuIHRoZSBsaW1pdCAlZFwiXG4gICAgICAgICAgc3RyIG5ld19hY2MgU3lzLm1heF9zdHJpbmdfbGVuZ3RoXG4gICAgICBlbHNlXG4gICAgICAgIHBhcnNlX3Bvc2l0aXZlIChzdHJfaW5kICsgMSkgZW5kX2luZCBuZXdfYWNjXG4gICAgfCBfIC0+IHN0cl9pbmQsIGFjY1xuXG4gICgqIFJlYWQgYSBwb3NpdGl2ZSBvciBuZWdhdGl2ZSBpbnRlZ2VyIGZyb20gdGhlIHN0cmluZywgcmFpc2UgYSBGYWlsdXJlXG4gICAgIGlmIGVuZF9pbmQgaXMgcmVhY2hlZC4gKilcbiAgYW5kIHBhcnNlX2ludGVnZXIgc3RyX2luZCBlbmRfaW5kID1cbiAgICBpZiBzdHJfaW5kID0gZW5kX2luZCB0aGVuIHVuZXhwZWN0ZWRfZW5kX29mX2Zvcm1hdCBlbmRfaW5kO1xuICAgIG1hdGNoIHN0ci5bc3RyX2luZF0gd2l0aFxuICAgIHwgJzAnIC4uICc5JyAtPiBwYXJzZV9wb3NpdGl2ZSBzdHJfaW5kIGVuZF9pbmQgMFxuICAgIHwgJy0nIC0+IChcbiAgICAgIGlmIHN0cl9pbmQgKyAxID0gZW5kX2luZCB0aGVuIHVuZXhwZWN0ZWRfZW5kX29mX2Zvcm1hdCBlbmRfaW5kO1xuICAgICAgbWF0Y2ggc3RyLltzdHJfaW5kICsgMV0gd2l0aFxuICAgICAgfCAnMCcgLi4gJzknIC0+XG4gICAgICAgIGxldCBuZXh0X2luZCwgbiA9IHBhcnNlX3Bvc2l0aXZlIChzdHJfaW5kICsgMSkgZW5kX2luZCAwIGluXG4gICAgICAgIG5leHRfaW5kLCAtblxuICAgICAgfCBjIC0+XG4gICAgICAgIGV4cGVjdGVkX2NoYXJhY3RlciAoc3RyX2luZCArIDEpIFwiZGlnaXRcIiBjXG4gICAgKVxuICAgIHwgXyAtPiBhc3NlcnQgZmFsc2VcblxuICAoKiBBZGQgYSBsaXRlcmFsIHRvIGEgZm9ybWF0IGZyb20gYSBsaXRlcmFsIGNoYXJhY3RlciBzdWItc2VxdWVuY2UuICopXG4gIGFuZCBhZGRfbGl0ZXJhbCA6IHR5cGUgYSBkIGUgZiAuXG4gICAgICBpbnQgLT4gaW50IC0+IChhLCBfLCBfLCBkLCBlLCBmKSBmbXQgLT5cbiAgICAgIChfLCBfLCBlLCBmKSBmbXRfZWJiID1cbiAgZnVuIGxpdF9zdGFydCBzdHJfaW5kIGZtdCAtPiBtYXRjaCBzdHJfaW5kIC0gbGl0X3N0YXJ0IHdpdGhcbiAgICB8IDAgICAgLT4gRm10X0VCQiBmbXRcbiAgICB8IDEgICAgLT4gRm10X0VCQiAoQ2hhcl9saXRlcmFsIChzdHIuW2xpdF9zdGFydF0sIGZtdCkpXG4gICAgfCBzaXplIC0+IEZtdF9FQkIgKFN0cmluZ19saXRlcmFsIChTdHJpbmcuc3ViIHN0ciBsaXRfc3RhcnQgc2l6ZSwgZm10KSlcblxuICAoKiBTZWFyY2ggdGhlIGVuZCBvZiB0aGUgY3VycmVudCBzdWItZm9ybWF0XG4gICAgIChpLmUuIHRoZSBjb3JyZXNwb25kaW5nIFwiJX1cIiBvciBcIiUpXCIpICopXG4gIGFuZCBzZWFyY2hfc3ViZm9ybWF0X2VuZCBzdHJfaW5kIGVuZF9pbmQgYyA9XG4gICAgaWYgc3RyX2luZCA9IGVuZF9pbmQgdGhlblxuICAgICAgZmFpbHdpdGhfbWVzc2FnZVxuICAgICAgICBcImludmFsaWQgZm9ybWF0ICVTOiB1bmNsb3NlZCBzdWItZm9ybWF0LCBcXFxuICAgICAgICAgZXhwZWN0ZWQgXFxcIiUlJWNcXFwiIGF0IGNoYXJhY3RlciBudW1iZXIgJWRcIiBzdHIgYyBlbmRfaW5kO1xuICAgIG1hdGNoIHN0ci5bc3RyX2luZF0gd2l0aFxuICAgIHwgJyUnIC0+XG4gICAgICBpZiBzdHJfaW5kICsgMSA9IGVuZF9pbmQgdGhlbiB1bmV4cGVjdGVkX2VuZF9vZl9mb3JtYXQgZW5kX2luZDtcbiAgICAgIGlmIHN0ci5bc3RyX2luZCArIDFdID0gYyB0aGVuICgqIEVuZCBvZiBmb3JtYXQgZm91bmQgKikgc3RyX2luZCBlbHNlXG4gICAgICAgIGJlZ2luIG1hdGNoIHN0ci5bc3RyX2luZCArIDFdIHdpdGhcbiAgICAgICAgfCAnXycgLT5cbiAgICAgICAgICAoKiBTZWFyY2ggZm9yIFwiJV8oXCIgb3IgXCIlX3tcIi4gKilcbiAgICAgICAgICBpZiBzdHJfaW5kICsgMiA9IGVuZF9pbmQgdGhlbiB1bmV4cGVjdGVkX2VuZF9vZl9mb3JtYXQgZW5kX2luZDtcbiAgICAgICAgICBiZWdpbiBtYXRjaCBzdHIuW3N0cl9pbmQgKyAyXSB3aXRoXG4gICAgICAgICAgfCAneycgLT5cbiAgICAgICAgICAgIGxldCBzdWJfZW5kID0gc2VhcmNoX3N1YmZvcm1hdF9lbmQgKHN0cl9pbmQgKyAzKSBlbmRfaW5kICd9JyBpblxuICAgICAgICAgICAgc2VhcmNoX3N1YmZvcm1hdF9lbmQgKHN1Yl9lbmQgKyAyKSBlbmRfaW5kIGNcbiAgICAgICAgICB8ICcoJyAtPlxuICAgICAgICAgICAgbGV0IHN1Yl9lbmQgPSBzZWFyY2hfc3ViZm9ybWF0X2VuZCAoc3RyX2luZCArIDMpIGVuZF9pbmQgJyknIGluXG4gICAgICAgICAgICBzZWFyY2hfc3ViZm9ybWF0X2VuZCAoc3ViX2VuZCArIDIpIGVuZF9pbmQgY1xuICAgICAgICAgIHwgXyAtPiBzZWFyY2hfc3ViZm9ybWF0X2VuZCAoc3RyX2luZCArIDMpIGVuZF9pbmQgY1xuICAgICAgICAgIGVuZFxuICAgICAgICB8ICd7JyAtPlxuICAgICAgICAgICgqICV7Li4uJX0gc3ViLWZvcm1hdCBmb3VuZC4gKilcbiAgICAgICAgICBsZXQgc3ViX2VuZCA9IHNlYXJjaF9zdWJmb3JtYXRfZW5kIChzdHJfaW5kICsgMikgZW5kX2luZCAnfScgaW5cbiAgICAgICAgICBzZWFyY2hfc3ViZm9ybWF0X2VuZCAoc3ViX2VuZCArIDIpIGVuZF9pbmQgY1xuICAgICAgICB8ICcoJyAtPlxuICAgICAgICAgICgqICUoLi4uJSkgc3ViLWZvcm1hdCBmb3VuZC4gKilcbiAgICAgICAgICBsZXQgc3ViX2VuZCA9IHNlYXJjaF9zdWJmb3JtYXRfZW5kIChzdHJfaW5kICsgMikgZW5kX2luZCAnKScgaW5cbiAgICAgICAgICBzZWFyY2hfc3ViZm9ybWF0X2VuZCAoc3ViX2VuZCArIDIpIGVuZF9pbmQgY1xuICAgICAgICB8ICd9JyAtPlxuICAgICAgICAgICgqIEVycm9yOiAlKC4uLiV9LiAqKVxuICAgICAgICAgIGV4cGVjdGVkX2NoYXJhY3RlciAoc3RyX2luZCArIDEpIFwiY2hhcmFjdGVyICcpJ1wiICd9J1xuICAgICAgICB8ICcpJyAtPlxuICAgICAgICAgICgqIEVycm9yOiAley4uLiUpLiAqKVxuICAgICAgICAgIGV4cGVjdGVkX2NoYXJhY3RlciAoc3RyX2luZCArIDEpIFwiY2hhcmFjdGVyICd9J1wiICcpJ1xuICAgICAgICB8IF8gLT5cbiAgICAgICAgICBzZWFyY2hfc3ViZm9ybWF0X2VuZCAoc3RyX2luZCArIDIpIGVuZF9pbmQgY1xuICAgICAgICBlbmRcbiAgICB8IF8gLT4gc2VhcmNoX3N1YmZvcm1hdF9lbmQgKHN0cl9pbmQgKyAxKSBlbmRfaW5kIGNcblxuICAoKiBDaGVjayBpZiBzeW1iIGlzIGEgdmFsaWQgaW50IGNvbnZlcnNpb24gYWZ0ZXIgXCIlbFwiLCBcIiVuXCIgb3IgXCIlTFwiICopXG4gIGFuZCBpc19pbnRfYmFzZSBzeW1iID0gbWF0Y2ggc3ltYiB3aXRoXG4gICAgfCAnZCcgfCAnaScgfCAneCcgfCAnWCcgfCAnbycgfCAndScgLT4gdHJ1ZVxuICAgIHwgXyAtPiBmYWxzZVxuXG4gICgqIENvbnZlcnQgYSBjaGFyIChsLCBuIG9yIEwpIHRvIGl0cyBhc3NvY2lhdGVkIGNvdW50ZXIuICopXG4gIGFuZCBjb3VudGVyX29mX2NoYXIgc3ltYiA9IG1hdGNoIHN5bWIgd2l0aFxuICAgIHwgJ2wnIC0+IExpbmVfY291bnRlciAgfCAnbicgLT4gQ2hhcl9jb3VudGVyXG4gICAgfCAnTCcgLT4gVG9rZW5fY291bnRlciB8IF8gLT4gYXNzZXJ0IGZhbHNlXG5cbiAgKCogQ29udmVydCAocGx1cywgc3ltYikgdG8gaXRzIGFzc29jaWF0ZWQgaW50X2NvbnYuICopXG4gIGFuZCBjb21wdXRlX2ludF9jb252IHBjdF9pbmQgc3RyX2luZCBwbHVzIGhhc2ggc3BhY2Ugc3ltYiA9XG4gICAgbWF0Y2ggcGx1cywgaGFzaCwgc3BhY2UsIHN5bWIgd2l0aFxuICAgIHwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgJ2QnIC0+IEludF9kICB8IGZhbHNlLCBmYWxzZSwgZmFsc2UsICdpJyAtPiBJbnRfaVxuICAgIHwgZmFsc2UsIGZhbHNlLCAgdHJ1ZSwgJ2QnIC0+IEludF9zZCB8IGZhbHNlLCBmYWxzZSwgIHRydWUsICdpJyAtPiBJbnRfc2lcbiAgICB8ICB0cnVlLCBmYWxzZSwgZmFsc2UsICdkJyAtPiBJbnRfcGQgfCAgdHJ1ZSwgZmFsc2UsIGZhbHNlLCAnaScgLT4gSW50X3BpXG4gICAgfCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAneCcgLT4gSW50X3ggIHwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgJ1gnIC0+IEludF9YXG4gICAgfCBmYWxzZSwgIHRydWUsIGZhbHNlLCAneCcgLT4gSW50X0N4IHwgZmFsc2UsICB0cnVlLCBmYWxzZSwgJ1gnIC0+IEludF9DWFxuICAgIHwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgJ28nIC0+IEludF9vXG4gICAgfCBmYWxzZSwgIHRydWUsIGZhbHNlLCAnbycgLT4gSW50X0NvXG4gICAgfCBmYWxzZSwgZmFsc2UsIGZhbHNlLCAndScgLT4gSW50X3VcbiAgICB8IGZhbHNlLCAgdHJ1ZSwgZmFsc2UsICdkJyAtPiBJbnRfQ2RcbiAgICB8IGZhbHNlLCAgdHJ1ZSwgZmFsc2UsICdpJyAtPiBJbnRfQ2lcbiAgICB8IGZhbHNlLCAgdHJ1ZSwgZmFsc2UsICd1JyAtPiBJbnRfQ3VcbiAgICB8IF8sIHRydWUsIF8sICd4JyB3aGVuIGxlZ2FjeV9iZWhhdmlvciAtPiBJbnRfQ3hcbiAgICB8IF8sIHRydWUsIF8sICdYJyB3aGVuIGxlZ2FjeV9iZWhhdmlvciAtPiBJbnRfQ1hcbiAgICB8IF8sIHRydWUsIF8sICdvJyB3aGVuIGxlZ2FjeV9iZWhhdmlvciAtPiBJbnRfQ29cbiAgICB8IF8sIHRydWUsIF8sICgnZCcgfCAnaScgfCAndScpIC0+XG4gICAgICBpZiBsZWdhY3lfYmVoYXZpb3IgdGhlbiAoKiBpZ25vcmUgKilcbiAgICAgICAgY29tcHV0ZV9pbnRfY29udiBwY3RfaW5kIHN0cl9pbmQgcGx1cyBmYWxzZSBzcGFjZSBzeW1iXG4gICAgICBlbHNlIGluY29tcGF0aWJsZV9mbGFnIHBjdF9pbmQgc3RyX2luZCBzeW1iIFwiJyMnXCJcbiAgICB8IHRydWUsIF8sIHRydWUsIF8gLT5cbiAgICAgIGlmIGxlZ2FjeV9iZWhhdmlvciB0aGVuXG4gICAgICAgICgqIHBsdXMgYW5kIHNwYWNlOiBsZWdhY3kgaW1wbGVtZW50YXRpb24gcHJlZmVycyBwbHVzICopXG4gICAgICAgIGNvbXB1dGVfaW50X2NvbnYgcGN0X2luZCBzdHJfaW5kIHBsdXMgaGFzaCBmYWxzZSBzeW1iXG4gICAgICBlbHNlIGluY29tcGF0aWJsZV9mbGFnIHBjdF9pbmQgc3RyX2luZCAnICcgXCInKydcIlxuICAgIHwgZmFsc2UsIF8sIHRydWUsIF8gICAgLT5cbiAgICAgIGlmIGxlZ2FjeV9iZWhhdmlvciB0aGVuICgqIGlnbm9yZSAqKVxuICAgICAgICBjb21wdXRlX2ludF9jb252IHBjdF9pbmQgc3RyX2luZCBwbHVzIGhhc2ggZmFsc2Ugc3ltYlxuICAgICAgZWxzZSBpbmNvbXBhdGlibGVfZmxhZyBwY3RfaW5kIHN0cl9pbmQgc3ltYiBcIicgJ1wiXG4gICAgfCB0cnVlLCBfLCBmYWxzZSwgXyAgICAtPlxuICAgICAgaWYgbGVnYWN5X2JlaGF2aW9yIHRoZW4gKCogaWdub3JlICopXG4gICAgICAgIGNvbXB1dGVfaW50X2NvbnYgcGN0X2luZCBzdHJfaW5kIGZhbHNlIGhhc2ggc3BhY2Ugc3ltYlxuICAgICAgZWxzZSBpbmNvbXBhdGlibGVfZmxhZyBwY3RfaW5kIHN0cl9pbmQgc3ltYiBcIicrJ1wiXG4gICAgfCBmYWxzZSwgXywgZmFsc2UsIF8gLT4gYXNzZXJ0IGZhbHNlXG5cbiAgKCogQ29udmVydCAocGx1cywgc3BhY2UsIHN5bWIpIHRvIGl0cyBhc3NvY2lhdGVkIGZsb2F0X2NvbnYuICopXG4gIGFuZCBjb21wdXRlX2Zsb2F0X2NvbnYgcGN0X2luZCBzdHJfaW5kIHBsdXMgaGFzaCBzcGFjZSBzeW1iID1cbiAgICBsZXQgZmxhZyA9IG1hdGNoIHBsdXMsIHNwYWNlIHdpdGhcbiAgICB8IGZhbHNlLCBmYWxzZSAtPiBGbG9hdF9mbGFnX1xuICAgIHwgZmFsc2UsICB0cnVlIC0+IEZsb2F0X2ZsYWdfc1xuICAgIHwgIHRydWUsIGZhbHNlIC0+IEZsb2F0X2ZsYWdfcFxuICAgIHwgIHRydWUsICB0cnVlIC0+XG4gICAgICAoKiBwbHVzIGFuZCBzcGFjZTogbGVnYWN5IGltcGxlbWVudGF0aW9uIHByZWZlcnMgcGx1cyAqKVxuICAgICAgaWYgbGVnYWN5X2JlaGF2aW9yIHRoZW4gRmxvYXRfZmxhZ19wXG4gICAgICBlbHNlIGluY29tcGF0aWJsZV9mbGFnIHBjdF9pbmQgc3RyX2luZCAnICcgXCInKydcIiBpblxuICAgIGxldCBraW5kID0gbWF0Y2ggaGFzaCwgc3ltYiB3aXRoXG4gICAgfCBfLCAnZicgLT4gRmxvYXRfZlxuICAgIHwgXywgJ2UnIC0+IEZsb2F0X2VcbiAgICB8IF8sICdFJyAtPiBGbG9hdF9FXG4gICAgfCBfLCAnZycgLT4gRmxvYXRfZ1xuICAgIHwgXywgJ0cnIC0+IEZsb2F0X0dcbiAgICB8IF8sICdoJyAtPiBGbG9hdF9oXG4gICAgfCBfLCAnSCcgLT4gRmxvYXRfSFxuICAgIHwgZmFsc2UsICdGJyAtPiBGbG9hdF9GXG4gICAgfCB0cnVlLCAnRicgLT4gRmxvYXRfQ0ZcbiAgICB8IF8gLT4gYXNzZXJ0IGZhbHNlIGluXG4gICAgZmxhZywga2luZFxuXG4gICgqIFJhaXNlIFtGYWlsdXJlXSB3aXRoIGEgZnJpZW5kbHkgZXJyb3IgbWVzc2FnZSBhYm91dCBpbmNvbXBhdGlibGUgb3B0aW9ucy4qKVxuICBhbmQgaW5jb21wYXRpYmxlX2ZsYWcgOiB0eXBlIGEgLiBpbnQgLT4gaW50IC0+IGNoYXIgLT4gc3RyaW5nIC0+IGEgPVxuICAgIGZ1biBwY3RfaW5kIHN0cl9pbmQgc3ltYiBvcHRpb24gLT5cbiAgICAgIGxldCBzdWJmbXQgPSBTdHJpbmcuc3ViIHN0ciBwY3RfaW5kIChzdHJfaW5kIC0gcGN0X2luZCkgaW5cbiAgICAgIGZhaWx3aXRoX21lc3NhZ2VcbiAgICAgICAgXCJpbnZhbGlkIGZvcm1hdCAlUzogYXQgY2hhcmFjdGVyIG51bWJlciAlZCwgXFxcbiAgICAgICAgICVzIGlzIGluY29tcGF0aWJsZSB3aXRoICclYycgaW4gc3ViLWZvcm1hdCAlU1wiXG4gICAgICAgIHN0ciBwY3RfaW5kIG9wdGlvbiBzeW1iIHN1YmZtdFxuXG4gIGluIHBhcnNlIDAgKFN0cmluZy5sZW5ndGggc3RyKVxuXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuICAgICAgICAgICAgICAgICAgKCogR3VhcmRlZCBzdHJpbmcgdG8gZm9ybWF0IGNvbnZlcnNpb25zICopXG5cbigqIENvbnZlcnQgYSBzdHJpbmcgdG8gYSBmb3JtYXQgYWNjb3JkaW5nIHRvIGFuIGZtdHR5LiAqKVxuKCogUmFpc2UgW0ZhaWx1cmVdIHdpdGggYW4gZXJyb3IgbWVzc2FnZSBpbiBjYXNlIG9mIHR5cGUgbWlzbWF0Y2guICopXG5sZXQgZm9ybWF0X29mX3N0cmluZ19mbXR0eSBzdHIgZm10dHkgPVxuICBsZXQgRm10X0VCQiBmbXQgPSBmbXRfZWJiX29mX3N0cmluZyBzdHIgaW5cbiAgdHJ5IEZvcm1hdCAodHlwZV9mb3JtYXQgZm10IGZtdHR5LCBzdHIpXG4gIHdpdGggVHlwZV9taXNtYXRjaCAtPlxuICAgIGZhaWx3aXRoX21lc3NhZ2VcbiAgICAgIFwiYmFkIGlucHV0OiBmb3JtYXQgdHlwZSBtaXNtYXRjaCBiZXR3ZWVuICVTIGFuZCAlU1wiXG4gICAgICBzdHIgKHN0cmluZ19vZl9mbXR0eSBmbXR0eSlcblxuKCogQ29udmVydCBhIHN0cmluZyB0byBhIGZvcm1hdCBjb21wYXRpYmxlIHdpdGggYW4gb3RoZXIgZm9ybWF0LiAqKVxuKCogUmFpc2UgW0ZhaWx1cmVdIHdpdGggYW4gZXJyb3IgbWVzc2FnZSBpbiBjYXNlIG9mIHR5cGUgbWlzbWF0Y2guICopXG5sZXQgZm9ybWF0X29mX3N0cmluZ19mb3JtYXQgc3RyIChGb3JtYXQgKGZtdCcsIHN0cicpKSA9XG4gIGxldCBGbXRfRUJCIGZtdCA9IGZtdF9lYmJfb2Zfc3RyaW5nIHN0ciBpblxuICB0cnkgRm9ybWF0ICh0eXBlX2Zvcm1hdCBmbXQgKGZtdHR5X29mX2ZtdCBmbXQnKSwgc3RyKVxuICB3aXRoIFR5cGVfbWlzbWF0Y2ggLT5cbiAgICBmYWlsd2l0aF9tZXNzYWdlXG4gICAgICBcImJhZCBpbnB1dDogZm9ybWF0IHR5cGUgbWlzbWF0Y2ggYmV0d2VlbiAlUyBhbmQgJVNcIiBzdHIgc3RyJ1xuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBYYXZpZXIgTGVyb3kgYW5kIFBpZXJyZSBXZWlzLCBwcm9qZXQgQ3Jpc3RhbCwgSU5SSUEgUm9jcXVlbmNvdXJ0ICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMTk5NiBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0ICAgICAqKVxuKCogICAgIGVuIEF1dG9tYXRpcXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG5vcGVuIENhbWxpbnRlcm5hbEZvcm1hdEJhc2ljc1xub3BlbiBDYW1saW50ZXJuYWxGb3JtYXRcblxubGV0IGtmcHJpbnRmIGsgbyAoRm9ybWF0IChmbXQsIF8pKSA9XG4gIG1ha2VfcHJpbnRmIChmdW4gYWNjIC0+IG91dHB1dF9hY2MgbyBhY2M7IGsgbykgRW5kX29mX2FjYyBmbXRcbmxldCBrYnByaW50ZiBrIGIgKEZvcm1hdCAoZm10LCBfKSkgPVxuICBtYWtlX3ByaW50ZiAoZnVuIGFjYyAtPiBidWZwdXRfYWNjIGIgYWNjOyBrIGIpIEVuZF9vZl9hY2MgZm10XG5sZXQgaWtmcHJpbnRmIGsgb2MgKEZvcm1hdCAoZm10LCBfKSkgPVxuICBtYWtlX2lwcmludGYgayBvYyBmbXRcbmxldCBpa2JwcmludGYgPSBpa2ZwcmludGZcblxubGV0IGZwcmludGYgb2MgZm10ID0ga2ZwcmludGYgaWdub3JlIG9jIGZtdFxubGV0IGJwcmludGYgYiBmbXQgPSBrYnByaW50ZiBpZ25vcmUgYiBmbXRcbmxldCBpZnByaW50ZiBvYyBmbXQgPSBpa2ZwcmludGYgaWdub3JlIG9jIGZtdFxubGV0IGlicHJpbnRmIGIgZm10ID0gaWticHJpbnRmIGlnbm9yZSBiIGZtdFxubGV0IHByaW50ZiBmbXQgPSBmcHJpbnRmIHN0ZG91dCBmbXRcbmxldCBlcHJpbnRmIGZtdCA9IGZwcmludGYgc3RkZXJyIGZtdFxuXG5sZXQga3NwcmludGYgayAoRm9ybWF0IChmbXQsIF8pKSA9XG4gIGxldCBrJyBhY2MgPVxuICAgIGxldCBidWYgPSBCdWZmZXIuY3JlYXRlIDY0IGluXG4gICAgc3RycHV0X2FjYyBidWYgYWNjO1xuICAgIGsgKEJ1ZmZlci5jb250ZW50cyBidWYpIGluXG4gIG1ha2VfcHJpbnRmIGsnIEVuZF9vZl9hY2MgZm10XG5cbmxldCBzcHJpbnRmIGZtdCA9IGtzcHJpbnRmIChmdW4gcyAtPiBzKSBmbXRcblxubGV0IGtwcmludGYgPSBrc3ByaW50ZlxuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgIERhbWllbiBEb2xpZ2V6LCBwcm9qZXQgUGFyYSwgSU5SSUEgUm9jcXVlbmNvdXJ0ICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMTk5NiBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0ICAgICAqKVxuKCogICAgIGVuIEF1dG9tYXRpcXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG50eXBlIGtleSA9IHN0cmluZ1xudHlwZSBkb2MgPSBzdHJpbmdcbnR5cGUgdXNhZ2VfbXNnID0gc3RyaW5nXG50eXBlIGFub25fZnVuID0gKHN0cmluZyAtPiB1bml0KVxuXG50eXBlIHNwZWMgPVxuICB8IFVuaXQgb2YgKHVuaXQgLT4gdW5pdCkgICAgICgqIENhbGwgdGhlIGZ1bmN0aW9uIHdpdGggdW5pdCBhcmd1bWVudCAqKVxuICB8IEJvb2wgb2YgKGJvb2wgLT4gdW5pdCkgICAgICgqIENhbGwgdGhlIGZ1bmN0aW9uIHdpdGggYSBib29sIGFyZ3VtZW50ICopXG4gIHwgU2V0IG9mIGJvb2wgcmVmICAgICAgICAgICAgKCogU2V0IHRoZSByZWZlcmVuY2UgdG8gdHJ1ZSAqKVxuICB8IENsZWFyIG9mIGJvb2wgcmVmICAgICAgICAgICgqIFNldCB0aGUgcmVmZXJlbmNlIHRvIGZhbHNlICopXG4gIHwgU3RyaW5nIG9mIChzdHJpbmcgLT4gdW5pdCkgKCogQ2FsbCB0aGUgZnVuY3Rpb24gd2l0aCBhIHN0cmluZyBhcmd1bWVudCAqKVxuICB8IFNldF9zdHJpbmcgb2Ygc3RyaW5nIHJlZiAgICgqIFNldCB0aGUgcmVmZXJlbmNlIHRvIHRoZSBzdHJpbmcgYXJndW1lbnQgKilcbiAgfCBJbnQgb2YgKGludCAtPiB1bml0KSAgICAgICAoKiBDYWxsIHRoZSBmdW5jdGlvbiB3aXRoIGFuIGludCBhcmd1bWVudCAqKVxuICB8IFNldF9pbnQgb2YgaW50IHJlZiAgICAgICAgICgqIFNldCB0aGUgcmVmZXJlbmNlIHRvIHRoZSBpbnQgYXJndW1lbnQgKilcbiAgfCBGbG9hdCBvZiAoZmxvYXQgLT4gdW5pdCkgICAoKiBDYWxsIHRoZSBmdW5jdGlvbiB3aXRoIGEgZmxvYXQgYXJndW1lbnQgKilcbiAgfCBTZXRfZmxvYXQgb2YgZmxvYXQgcmVmICAgICAoKiBTZXQgdGhlIHJlZmVyZW5jZSB0byB0aGUgZmxvYXQgYXJndW1lbnQgKilcbiAgfCBUdXBsZSBvZiBzcGVjIGxpc3QgICAgICAgICAoKiBUYWtlIHNldmVyYWwgYXJndW1lbnRzIGFjY29yZGluZyB0byB0aGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjIGxpc3QgKilcbiAgfCBTeW1ib2wgb2Ygc3RyaW5nIGxpc3QgKiAoc3RyaW5nIC0+IHVuaXQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCogVGFrZSBvbmUgb2YgdGhlIHN5bWJvbHMgYXMgYXJndW1lbnQgYW5kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbCB0aGUgZnVuY3Rpb24gd2l0aCB0aGUgc3ltYm9sLiAqKVxuICB8IFJlc3Qgb2YgKHN0cmluZyAtPiB1bml0KSAgICgqIFN0b3AgaW50ZXJwcmV0aW5nIGtleXdvcmRzIGFuZCBjYWxsIHRoZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHdpdGggZWFjaCByZW1haW5pbmcgYXJndW1lbnQgKilcbiAgfCBSZXN0X2FsbCBvZiAoc3RyaW5nIGxpc3QgLT4gdW5pdClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKiBTdG9wIGludGVycHJldGluZyBrZXl3b3JkcyBhbmQgY2FsbCB0aGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiB3aXRoIGFsbCByZW1haW5pbmcgYXJndW1lbnRzLiAqKVxuICB8IEV4cGFuZCBvZiAoc3RyaW5nIC0+IHN0cmluZyBhcnJheSkgKCogSWYgdGhlIHJlbWFpbmluZyBhcmd1bWVudHMgdG8gcHJvY2Vzc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJlIG9mIHRoZSBmb3JtXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbW1wiLWZvb1wiOyBcImFyZ1wiXSBAIHJlc3RdIHdoZXJlIFwiZm9vXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzIHJlZ2lzdGVyZWQgYXMgW0V4cGFuZCBmXSwgdGhlbiB0aGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3VtZW50cyBbZiBcImFyZ1wiIEAgcmVzdF0gYXJlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzZWQuIE9ubHkgYWxsb3dlZCBpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BhcnNlX2FuZF9leHBhbmRfYXJndl9keW5hbWljXS4gKilcblxuZXhjZXB0aW9uIEJhZCBvZiBzdHJpbmdcbmV4Y2VwdGlvbiBIZWxwIG9mIHN0cmluZ1xuXG50eXBlIGVycm9yID1cbiAgfCBVbmtub3duIG9mIHN0cmluZ1xuICB8IFdyb25nIG9mIHN0cmluZyAqIHN0cmluZyAqIHN0cmluZyAgKCogb3B0aW9uLCBhY3R1YWwsIGV4cGVjdGVkICopXG4gIHwgTWlzc2luZyBvZiBzdHJpbmdcbiAgfCBNZXNzYWdlIG9mIHN0cmluZ1xuXG5leGNlcHRpb24gU3RvcCBvZiBlcnJvciAoKiB1c2VkIGludGVybmFsbHkgKilcblxub3BlbiBQcmludGZcblxubGV0IHJlYyBhc3NvYzMgeCBsID1cbiAgbWF0Y2ggbCB3aXRoXG4gIHwgW10gLT4gcmFpc2UgTm90X2ZvdW5kXG4gIHwgKHkxLCB5MiwgXykgOjogXyB3aGVuIHkxID0geCAtPiB5MlxuICB8IF8gOjogdCAtPiBhc3NvYzMgeCB0XG5cblxubGV0IHNwbGl0IHMgPVxuICBsZXQgaSA9IFN0cmluZy5pbmRleCBzICc9JyBpblxuICBsZXQgbGVuID0gU3RyaW5nLmxlbmd0aCBzIGluXG4gIFN0cmluZy5zdWIgcyAwIGksIFN0cmluZy5zdWIgcyAoaSsxKSAobGVuLShpKzEpKVxuXG5cbmxldCBtYWtlX3N5bWxpc3QgcHJlZml4IHNlcCBzdWZmaXggbCA9XG4gIG1hdGNoIGwgd2l0aFxuICB8IFtdIC0+IFwiPG5vbmU+XCJcbiAgfCBoOjp0IC0+IChMaXN0LmZvbGRfbGVmdCAoZnVuIHggeSAtPiB4IF4gc2VwIF4geSkgKHByZWZpeCBeIGgpIHQpIF4gc3VmZml4XG5cblxubGV0IHByaW50X3NwZWMgYnVmIChrZXksIHNwZWMsIGRvYykgPVxuICBpZiBTdHJpbmcubGVuZ3RoIGRvYyA+IDAgdGhlblxuICAgIG1hdGNoIHNwZWMgd2l0aFxuICAgIHwgU3ltYm9sIChsLCBfKSAtPlxuICAgICAgICBicHJpbnRmIGJ1ZiBcIiAgJXMgJXMlc1xcblwiIGtleSAobWFrZV9zeW1saXN0IFwie1wiIFwifFwiIFwifVwiIGwpIGRvY1xuICAgIHwgXyAtPlxuICAgICAgICBicHJpbnRmIGJ1ZiBcIiAgJXMgJXNcXG5cIiBrZXkgZG9jXG5cblxubGV0IGhlbHBfYWN0aW9uICgpID0gcmFpc2UgKFN0b3AgKFVua25vd24gXCItaGVscFwiKSlcblxubGV0IGFkZF9oZWxwIHNwZWNsaXN0ID1cbiAgbGV0IGFkZDEgPVxuICAgIHRyeSBpZ25vcmUgKGFzc29jMyBcIi1oZWxwXCIgc3BlY2xpc3QpOyBbXVxuICAgIHdpdGggTm90X2ZvdW5kIC0+XG4gICAgICAgICAgICBbXCItaGVscFwiLCBVbml0IGhlbHBfYWN0aW9uLCBcIiBEaXNwbGF5IHRoaXMgbGlzdCBvZiBvcHRpb25zXCJdXG4gIGFuZCBhZGQyID1cbiAgICB0cnkgaWdub3JlIChhc3NvYzMgXCItLWhlbHBcIiBzcGVjbGlzdCk7IFtdXG4gICAgd2l0aCBOb3RfZm91bmQgLT5cbiAgICAgICAgICAgIFtcIi0taGVscFwiLCBVbml0IGhlbHBfYWN0aW9uLCBcIiBEaXNwbGF5IHRoaXMgbGlzdCBvZiBvcHRpb25zXCJdXG4gIGluXG4gIHNwZWNsaXN0IEAgKGFkZDEgQCBhZGQyKVxuXG5cbmxldCB1c2FnZV9iIGJ1ZiBzcGVjbGlzdCBlcnJtc2cgPVxuICBicHJpbnRmIGJ1ZiBcIiVzXFxuXCIgZXJybXNnO1xuICBMaXN0Lml0ZXIgKHByaW50X3NwZWMgYnVmKSAoYWRkX2hlbHAgc3BlY2xpc3QpXG5cblxubGV0IHVzYWdlX3N0cmluZyBzcGVjbGlzdCBlcnJtc2cgPVxuICBsZXQgYiA9IEJ1ZmZlci5jcmVhdGUgMjAwIGluXG4gIHVzYWdlX2IgYiBzcGVjbGlzdCBlcnJtc2c7XG4gIEJ1ZmZlci5jb250ZW50cyBiXG5cblxubGV0IHVzYWdlIHNwZWNsaXN0IGVycm1zZyA9XG4gIGVwcmludGYgXCIlc1wiICh1c2FnZV9zdHJpbmcgc3BlY2xpc3QgZXJybXNnKVxuXG5cbmxldCBjdXJyZW50ID0gcmVmIDBcblxubGV0IGJvb2xfb2Zfc3RyaW5nX29wdCB4ID1cbiAgdHJ5IFNvbWUgKGJvb2xfb2Zfc3RyaW5nIHgpXG4gIHdpdGggSW52YWxpZF9hcmd1bWVudCBfIC0+IE5vbmVcblxubGV0IGludF9vZl9zdHJpbmdfb3B0IHggPVxuICB0cnkgU29tZSAoaW50X29mX3N0cmluZyB4KVxuICB3aXRoIEZhaWx1cmUgXyAtPiBOb25lXG5cbmxldCBmbG9hdF9vZl9zdHJpbmdfb3B0IHggPVxuICB0cnkgU29tZSAoZmxvYXRfb2Zfc3RyaW5nIHgpXG4gIHdpdGggRmFpbHVyZSBfIC0+IE5vbmVcblxubGV0IHBhcnNlX2FuZF9leHBhbmRfYXJndl9keW5hbWljX2F1eCBhbGxvd19leHBhbmQgY3VycmVudCBhcmd2IHNwZWNsaXN0IGFub25mdW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJybXNnID1cbiAgbGV0IGluaXRwb3MgPSAhY3VycmVudCBpblxuICBsZXQgY29udmVydF9lcnJvciBlcnJvciA9XG4gICAgKCogY29udmVydCBhbiBpbnRlcm5hbCBlcnJvciB0byBhIEJhZC9IZWxwIGV4Y2VwdGlvblxuICAgICAgICpvciogYWRkIHRoZSBwcm9ncmFtIG5hbWUgYXMgYSBwcmVmaXggYW5kIHRoZSB1c2FnZSBtZXNzYWdlIGFzIGEgc3VmZml4XG4gICAgICAgdG8gYW4gdXNlci1yYWlzZWQgQmFkIGV4Y2VwdGlvbi5cbiAgICAqKVxuICAgIGxldCBiID0gQnVmZmVyLmNyZWF0ZSAyMDAgaW5cbiAgICBsZXQgcHJvZ25hbWUgPVxuICAgICAgaWYgaW5pdHBvcyA8IChBcnJheS5sZW5ndGggIWFyZ3YpIHRoZW4gIWFyZ3YuKGluaXRwb3MpIGVsc2UgXCIoPylcIiBpblxuICAgIGJlZ2luIG1hdGNoIGVycm9yIHdpdGhcbiAgICAgIHwgVW5rbm93biBcIi1oZWxwXCIgLT4gKClcbiAgICAgIHwgVW5rbm93biBcIi0taGVscFwiIC0+ICgpXG4gICAgICB8IFVua25vd24gcyAtPlxuICAgICAgICAgIGJwcmludGYgYiBcIiVzOiB1bmtub3duIG9wdGlvbiAnJXMnLlxcblwiIHByb2duYW1lIHNcbiAgICAgIHwgTWlzc2luZyBzIC0+XG4gICAgICAgICAgYnByaW50ZiBiIFwiJXM6IG9wdGlvbiAnJXMnIG5lZWRzIGFuIGFyZ3VtZW50LlxcblwiIHByb2duYW1lIHNcbiAgICAgIHwgV3JvbmcgKG9wdCwgYXJnLCBleHBlY3RlZCkgLT5cbiAgICAgICAgICBicHJpbnRmIGIgXCIlczogd3JvbmcgYXJndW1lbnQgJyVzJzsgb3B0aW9uICclcycgZXhwZWN0cyAlcy5cXG5cIlxuICAgICAgICAgICAgICAgICAgcHJvZ25hbWUgYXJnIG9wdCBleHBlY3RlZFxuICAgICAgfCBNZXNzYWdlIHMgLT4gKCogdXNlciBlcnJvciBtZXNzYWdlICopXG4gICAgICAgICAgYnByaW50ZiBiIFwiJXM6ICVzLlxcblwiIHByb2duYW1lIHNcbiAgICBlbmQ7XG4gICAgdXNhZ2VfYiBiICFzcGVjbGlzdCBlcnJtc2c7XG4gICAgaWYgZXJyb3IgPSBVbmtub3duIFwiLWhlbHBcIiB8fCBlcnJvciA9IFVua25vd24gXCItLWhlbHBcIlxuICAgIHRoZW4gSGVscCAoQnVmZmVyLmNvbnRlbnRzIGIpXG4gICAgZWxzZSBCYWQgKEJ1ZmZlci5jb250ZW50cyBiKVxuICBpblxuICBpbmNyIGN1cnJlbnQ7XG4gIHdoaWxlICFjdXJyZW50IDwgKEFycmF5Lmxlbmd0aCAhYXJndikgZG9cbiAgICBiZWdpbiB0cnlcbiAgICAgIGxldCBzID0gIWFyZ3YuKCFjdXJyZW50KSBpblxuICAgICAgaWYgU3RyaW5nLmxlbmd0aCBzID49IDEgJiYgcy5bMF0gPSAnLScgdGhlbiBiZWdpblxuICAgICAgICBsZXQgYWN0aW9uLCBmb2xsb3cgPVxuICAgICAgICAgIHRyeSBhc3NvYzMgcyAhc3BlY2xpc3QsIE5vbmVcbiAgICAgICAgICB3aXRoIE5vdF9mb3VuZCAtPlxuICAgICAgICAgIHRyeVxuICAgICAgICAgICAgbGV0IGtleXdvcmQsIGFyZyA9IHNwbGl0IHMgaW5cbiAgICAgICAgICAgIGFzc29jMyBrZXl3b3JkICFzcGVjbGlzdCwgU29tZSBhcmdcbiAgICAgICAgICB3aXRoIE5vdF9mb3VuZCAtPiByYWlzZSAoU3RvcCAoVW5rbm93biBzKSlcbiAgICAgICAgaW5cbiAgICAgICAgbGV0IG5vX2FyZyAoKSA9XG4gICAgICAgICAgbWF0Y2ggZm9sbG93IHdpdGhcbiAgICAgICAgICB8IE5vbmUgLT4gKClcbiAgICAgICAgICB8IFNvbWUgYXJnIC0+IHJhaXNlIChTdG9wIChXcm9uZyAocywgYXJnLCBcIm5vIGFyZ3VtZW50XCIpKSkgaW5cbiAgICAgICAgbGV0IGdldF9hcmcgKCkgPVxuICAgICAgICAgIG1hdGNoIGZvbGxvdyB3aXRoXG4gICAgICAgICAgfCBOb25lIC0+XG4gICAgICAgICAgICAgIGlmICFjdXJyZW50ICsgMSA8IChBcnJheS5sZW5ndGggIWFyZ3YpIHRoZW4gIWFyZ3YuKCFjdXJyZW50ICsgMSlcbiAgICAgICAgICAgICAgZWxzZSByYWlzZSAoU3RvcCAoTWlzc2luZyBzKSlcbiAgICAgICAgICB8IFNvbWUgYXJnIC0+IGFyZ1xuICAgICAgICBpblxuICAgICAgICBsZXQgY29uc3VtZV9hcmcgKCkgPVxuICAgICAgICAgIG1hdGNoIGZvbGxvdyB3aXRoXG4gICAgICAgICAgfCBOb25lIC0+IGluY3IgY3VycmVudFxuICAgICAgICAgIHwgU29tZSBfIC0+ICgpXG4gICAgICAgIGluXG4gICAgICAgIGxldCByZWMgdHJlYXRfYWN0aW9uID0gZnVuY3Rpb25cbiAgICAgICAgfCBVbml0IGYgLT4gbm9fYXJnICgpOyBmICgpO1xuICAgICAgICB8IEJvb2wgZiAtPlxuICAgICAgICAgICAgbGV0IGFyZyA9IGdldF9hcmcgKCkgaW5cbiAgICAgICAgICAgIGJlZ2luIG1hdGNoIGJvb2xfb2Zfc3RyaW5nX29wdCBhcmcgd2l0aFxuICAgICAgICAgICAgfCBOb25lIC0+IHJhaXNlIChTdG9wIChXcm9uZyAocywgYXJnLCBcImEgYm9vbGVhblwiKSkpXG4gICAgICAgICAgICB8IFNvbWUgcyAtPiBmIHNcbiAgICAgICAgICAgIGVuZDtcbiAgICAgICAgICAgIGNvbnN1bWVfYXJnICgpO1xuICAgICAgICB8IFNldCByIC0+IG5vX2FyZyAoKTsgciA6PSB0cnVlO1xuICAgICAgICB8IENsZWFyIHIgLT4gbm9fYXJnICgpOyByIDo9IGZhbHNlO1xuICAgICAgICB8IFN0cmluZyBmIC0+XG4gICAgICAgICAgICBsZXQgYXJnID0gZ2V0X2FyZyAoKSBpblxuICAgICAgICAgICAgZiBhcmc7XG4gICAgICAgICAgICBjb25zdW1lX2FyZyAoKTtcbiAgICAgICAgfCBTeW1ib2wgKHN5bWIsIGYpIC0+XG4gICAgICAgICAgICBsZXQgYXJnID0gZ2V0X2FyZyAoKSBpblxuICAgICAgICAgICAgaWYgTGlzdC5tZW0gYXJnIHN5bWIgdGhlbiBiZWdpblxuICAgICAgICAgICAgICBmIGFyZztcbiAgICAgICAgICAgICAgY29uc3VtZV9hcmcgKCk7XG4gICAgICAgICAgICBlbmQgZWxzZSBiZWdpblxuICAgICAgICAgICAgICByYWlzZSAoU3RvcCAoV3JvbmcgKHMsIGFyZywgXCJvbmUgb2Y6IFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBeIChtYWtlX3N5bWxpc3QgXCJcIiBcIiBcIiBcIlwiIHN5bWIpKSkpXG4gICAgICAgICAgICBlbmRcbiAgICAgICAgfCBTZXRfc3RyaW5nIHIgLT5cbiAgICAgICAgICAgIHIgOj0gZ2V0X2FyZyAoKTtcbiAgICAgICAgICAgIGNvbnN1bWVfYXJnICgpO1xuICAgICAgICB8IEludCBmIC0+XG4gICAgICAgICAgICBsZXQgYXJnID0gZ2V0X2FyZyAoKSBpblxuICAgICAgICAgICAgYmVnaW4gbWF0Y2ggaW50X29mX3N0cmluZ19vcHQgYXJnIHdpdGhcbiAgICAgICAgICAgIHwgTm9uZSAtPiByYWlzZSAoU3RvcCAoV3JvbmcgKHMsIGFyZywgXCJhbiBpbnRlZ2VyXCIpKSlcbiAgICAgICAgICAgIHwgU29tZSB4IC0+IGYgeFxuICAgICAgICAgICAgZW5kO1xuICAgICAgICAgICAgY29uc3VtZV9hcmcgKCk7XG4gICAgICAgIHwgU2V0X2ludCByIC0+XG4gICAgICAgICAgICBsZXQgYXJnID0gZ2V0X2FyZyAoKSBpblxuICAgICAgICAgICAgYmVnaW4gbWF0Y2ggaW50X29mX3N0cmluZ19vcHQgYXJnIHdpdGhcbiAgICAgICAgICAgIHwgTm9uZSAtPiByYWlzZSAoU3RvcCAoV3JvbmcgKHMsIGFyZywgXCJhbiBpbnRlZ2VyXCIpKSlcbiAgICAgICAgICAgIHwgU29tZSB4IC0+IHIgOj0geFxuICAgICAgICAgICAgZW5kO1xuICAgICAgICAgICAgY29uc3VtZV9hcmcgKCk7XG4gICAgICAgIHwgRmxvYXQgZiAtPlxuICAgICAgICAgICAgbGV0IGFyZyA9IGdldF9hcmcgKCkgaW5cbiAgICAgICAgICAgIGJlZ2luIG1hdGNoIGZsb2F0X29mX3N0cmluZ19vcHQgYXJnIHdpdGhcbiAgICAgICAgICAgIHwgTm9uZSAtPiByYWlzZSAoU3RvcCAoV3JvbmcgKHMsIGFyZywgXCJhIGZsb2F0XCIpKSlcbiAgICAgICAgICAgIHwgU29tZSB4IC0+IGYgeFxuICAgICAgICAgICAgZW5kO1xuICAgICAgICAgICAgY29uc3VtZV9hcmcgKCk7XG4gICAgICAgIHwgU2V0X2Zsb2F0IHIgLT5cbiAgICAgICAgICAgIGxldCBhcmcgPSBnZXRfYXJnICgpIGluXG4gICAgICAgICAgICBiZWdpbiBtYXRjaCBmbG9hdF9vZl9zdHJpbmdfb3B0IGFyZyB3aXRoXG4gICAgICAgICAgICB8IE5vbmUgLT4gcmFpc2UgKFN0b3AgKFdyb25nIChzLCBhcmcsIFwiYSBmbG9hdFwiKSkpXG4gICAgICAgICAgICB8IFNvbWUgeCAtPiByIDo9IHhcbiAgICAgICAgICAgIGVuZDtcbiAgICAgICAgICAgIGNvbnN1bWVfYXJnICgpO1xuICAgICAgICB8IFR1cGxlIHNwZWNzIC0+XG4gICAgICAgICAgICBub19hcmcgKCk7XG4gICAgICAgICAgICBMaXN0Lml0ZXIgdHJlYXRfYWN0aW9uIHNwZWNzO1xuICAgICAgICB8IFJlc3QgZiAtPlxuICAgICAgICAgICAgbm9fYXJnICgpO1xuICAgICAgICAgICAgd2hpbGUgIWN1cnJlbnQgPCAoQXJyYXkubGVuZ3RoICFhcmd2KSAtIDEgZG9cbiAgICAgICAgICAgICAgZiAhYXJndi4oIWN1cnJlbnQgKyAxKTtcbiAgICAgICAgICAgICAgY29uc3VtZV9hcmcgKCk7XG4gICAgICAgICAgICBkb25lO1xuICAgICAgICB8IFJlc3RfYWxsIGYgLT5cbiAgICAgICAgICAgIG5vX2FyZyAoKTtcbiAgICAgICAgICAgIGxldCBhY2MgPSByZWYgW10gaW5cbiAgICAgICAgICAgIHdoaWxlICFjdXJyZW50IDwgQXJyYXkubGVuZ3RoICFhcmd2IC0gMSBkb1xuICAgICAgICAgICAgICBhY2MgOj0gIWFyZ3YuKCFjdXJyZW50ICsgMSkgOjogIWFjYztcbiAgICAgICAgICAgICAgY29uc3VtZV9hcmcgKCk7XG4gICAgICAgICAgICBkb25lO1xuICAgICAgICAgICAgZiAoTGlzdC5yZXYgIWFjYylcbiAgICAgICAgfCBFeHBhbmQgZiAtPlxuICAgICAgICAgICAgaWYgbm90IGFsbG93X2V4cGFuZCB0aGVuXG4gICAgICAgICAgICAgIHJhaXNlIChJbnZhbGlkX2FyZ3VtZW50IFwiQXJnLkV4cGFuZCBpcyBpcyBvbmx5IGFsbG93ZWQgd2l0aCBcXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJnLnBhcnNlX2FuZF9leHBhbmRfYXJndl9keW5hbWljXCIpO1xuICAgICAgICAgICAgbGV0IGFyZyA9IGdldF9hcmcgKCkgaW5cbiAgICAgICAgICAgIGxldCBuZXdhcmcgPSBmIGFyZyBpblxuICAgICAgICAgICAgY29uc3VtZV9hcmcgKCk7XG4gICAgICAgICAgICBsZXQgYmVmb3JlID0gQXJyYXkuc3ViICFhcmd2IDAgKCFjdXJyZW50ICsgMSlcbiAgICAgICAgICAgIGFuZCBhZnRlciA9XG4gICAgICAgICAgICAgIEFycmF5LnN1YiAhYXJndiAoIWN1cnJlbnQgKyAxKVxuICAgICAgICAgICAgICAgICAgICAgICAgKChBcnJheS5sZW5ndGggIWFyZ3YpIC0gIWN1cnJlbnQgLSAxKSBpblxuICAgICAgICAgICAgYXJndjo9IEFycmF5LmNvbmNhdCBbYmVmb3JlO25ld2FyZzthZnRlcl07XG4gICAgICAgIGluXG4gICAgICAgIHRyZWF0X2FjdGlvbiBhY3Rpb24gZW5kXG4gICAgICBlbHNlIGFub25mdW4gc1xuICAgIHdpdGggfCBCYWQgbSAtPiByYWlzZSAoY29udmVydF9lcnJvciAoTWVzc2FnZSBtKSk7XG4gICAgICAgICB8IFN0b3AgZSAtPiByYWlzZSAoY29udmVydF9lcnJvciBlKTtcbiAgICBlbmQ7XG4gICAgaW5jciBjdXJyZW50XG4gIGRvbmVcblxubGV0IHBhcnNlX2FuZF9leHBhbmRfYXJndl9keW5hbWljIGN1cnJlbnQgYXJndiBzcGVjbGlzdCBhbm9uZnVuIGVycm1zZyA9XG4gIHBhcnNlX2FuZF9leHBhbmRfYXJndl9keW5hbWljX2F1eCB0cnVlIGN1cnJlbnQgYXJndiBzcGVjbGlzdCBhbm9uZnVuIGVycm1zZ1xuXG5sZXQgcGFyc2VfYXJndl9keW5hbWljID8oY3VycmVudD1jdXJyZW50KSBhcmd2IHNwZWNsaXN0IGFub25mdW4gZXJybXNnID1cbiAgcGFyc2VfYW5kX2V4cGFuZF9hcmd2X2R5bmFtaWNfYXV4IGZhbHNlIGN1cnJlbnQgKHJlZiBhcmd2KSBzcGVjbGlzdCBhbm9uZnVuXG4gICAgZXJybXNnXG5cblxubGV0IHBhcnNlX2FyZ3YgPyhjdXJyZW50PWN1cnJlbnQpIGFyZ3Ygc3BlY2xpc3QgYW5vbmZ1biBlcnJtc2cgPVxuICBwYXJzZV9hcmd2X2R5bmFtaWMgfmN1cnJlbnQ6Y3VycmVudCBhcmd2IChyZWYgc3BlY2xpc3QpIGFub25mdW4gZXJybXNnXG5cblxubGV0IHBhcnNlIGwgZiBtc2cgPVxuICB0cnlcbiAgICBwYXJzZV9hcmd2IFN5cy5hcmd2IGwgZiBtc2dcbiAgd2l0aFxuICB8IEJhZCBtc2cgLT4gZXByaW50ZiBcIiVzXCIgbXNnOyBleGl0IDJcbiAgfCBIZWxwIG1zZyAtPiBwcmludGYgXCIlc1wiIG1zZzsgZXhpdCAwXG5cblxubGV0IHBhcnNlX2R5bmFtaWMgbCBmIG1zZyA9XG4gIHRyeVxuICAgIHBhcnNlX2FyZ3ZfZHluYW1pYyBTeXMuYXJndiBsIGYgbXNnXG4gIHdpdGhcbiAgfCBCYWQgbXNnIC0+IGVwcmludGYgXCIlc1wiIG1zZzsgZXhpdCAyXG4gIHwgSGVscCBtc2cgLT4gcHJpbnRmIFwiJXNcIiBtc2c7IGV4aXQgMFxuXG5sZXQgcGFyc2VfZXhwYW5kIGwgZiBtc2cgPVxuICB0cnlcbiAgICBsZXQgYXJndiA9IHJlZiBTeXMuYXJndiBpblxuICAgIGxldCBzcGVjID0gcmVmIGwgaW5cbiAgICBsZXQgY3VycmVudCA9IHJlZiAoIWN1cnJlbnQpIGluXG4gICAgcGFyc2VfYW5kX2V4cGFuZF9hcmd2X2R5bmFtaWMgY3VycmVudCBhcmd2IHNwZWMgZiBtc2dcbiAgd2l0aFxuICB8IEJhZCBtc2cgLT4gZXByaW50ZiBcIiVzXCIgbXNnOyBleGl0IDJcbiAgfCBIZWxwIG1zZyAtPiBwcmludGYgXCIlc1wiIG1zZzsgZXhpdCAwXG5cblxubGV0IHNlY29uZF93b3JkIHMgPVxuICBsZXQgbGVuID0gU3RyaW5nLmxlbmd0aCBzIGluXG4gIGxldCByZWMgbG9vcCBuID1cbiAgICBpZiBuID49IGxlbiB0aGVuIGxlblxuICAgIGVsc2UgaWYgcy5bbl0gPSAnICcgdGhlbiBsb29wIChuKzEpXG4gICAgZWxzZSBuXG4gIGluXG4gIG1hdGNoIFN0cmluZy5pbmRleCBzICdcXHQnIHdpdGhcbiAgfCBuIC0+IGxvb3AgKG4rMSlcbiAgfCBleGNlcHRpb24gTm90X2ZvdW5kIC0+XG4gICAgICBiZWdpbiBtYXRjaCBTdHJpbmcuaW5kZXggcyAnICcgd2l0aFxuICAgICAgfCBuIC0+IGxvb3AgKG4rMSlcbiAgICAgIHwgZXhjZXB0aW9uIE5vdF9mb3VuZCAtPiBsZW5cbiAgICAgIGVuZFxuXG5cbmxldCBtYXhfYXJnX2xlbiBjdXIgKGt3ZCwgc3BlYywgZG9jKSA9XG4gIG1hdGNoIHNwZWMgd2l0aFxuICB8IFN5bWJvbCBfIC0+IEludC5tYXggY3VyIChTdHJpbmcubGVuZ3RoIGt3ZClcbiAgfCBfIC0+IEludC5tYXggY3VyIChTdHJpbmcubGVuZ3RoIGt3ZCArIHNlY29uZF93b3JkIGRvYylcblxuXG5sZXQgcmVwbGFjZV9sZWFkaW5nX3RhYiBzID1cbiAgbGV0IHNlZW4gPSByZWYgZmFsc2UgaW5cbiAgU3RyaW5nLm1hcCAoZnVuY3Rpb24gJ1xcdCcgd2hlbiBub3QgIXNlZW4gLT4gc2VlbiA6PSB0cnVlOyAnICcgfCBjIC0+IGMpIHNcblxubGV0IGFkZF9wYWRkaW5nIGxlbiBrc2QgPVxuICBtYXRjaCBrc2Qgd2l0aFxuICB8IChfLCBfLCBcIlwiKSAtPlxuICAgICAgKCogRG8gbm90IHBhZCB1bmRvY3VtZW50ZWQgb3B0aW9ucywgc28gdGhhdCB0aGV5IHN0aWxsIGRvbid0IHNob3cgdXAgd2hlblxuICAgICAgICogcnVuIHRocm91Z2ggW3VzYWdlXSBvciBbcGFyc2VdLiAqKVxuICAgICAga3NkXG4gIHwgKGt3ZCwgKFN5bWJvbCBfIGFzIHNwZWMpLCBtc2cpIC0+XG4gICAgICBsZXQgY3V0Y29sID0gc2Vjb25kX3dvcmQgbXNnIGluXG4gICAgICBsZXQgc3BhY2VzID0gU3RyaW5nLm1ha2UgKChJbnQubWF4IDAgKGxlbiAtIGN1dGNvbCkpICsgMykgJyAnIGluXG4gICAgICAoa3dkLCBzcGVjLCBcIlxcblwiIF4gc3BhY2VzIF4gcmVwbGFjZV9sZWFkaW5nX3RhYiBtc2cpXG4gIHwgKGt3ZCwgc3BlYywgbXNnKSAtPlxuICAgICAgbGV0IGN1dGNvbCA9IHNlY29uZF93b3JkIG1zZyBpblxuICAgICAgbGV0IGt3ZF9sZW4gPSBTdHJpbmcubGVuZ3RoIGt3ZCBpblxuICAgICAgbGV0IGRpZmYgPSBsZW4gLSBrd2RfbGVuIC0gY3V0Y29sIGluXG4gICAgICBpZiBkaWZmIDw9IDAgdGhlblxuICAgICAgICAoa3dkLCBzcGVjLCByZXBsYWNlX2xlYWRpbmdfdGFiIG1zZylcbiAgICAgIGVsc2VcbiAgICAgICAgbGV0IHNwYWNlcyA9IFN0cmluZy5tYWtlIGRpZmYgJyAnIGluXG4gICAgICAgIGxldCBwcmVmaXggPSBTdHJpbmcuc3ViIChyZXBsYWNlX2xlYWRpbmdfdGFiIG1zZykgMCBjdXRjb2wgaW5cbiAgICAgICAgbGV0IHN1ZmZpeCA9IFN0cmluZy5zdWIgbXNnIGN1dGNvbCAoU3RyaW5nLmxlbmd0aCBtc2cgLSBjdXRjb2wpIGluXG4gICAgICAgIChrd2QsIHNwZWMsIHByZWZpeCBeIHNwYWNlcyBeIHN1ZmZpeClcblxuXG5sZXQgYWxpZ24gPyhsaW1pdD1tYXhfaW50KSBzcGVjbGlzdCA9XG4gIGxldCBjb21wbGV0ZWQgPSBhZGRfaGVscCBzcGVjbGlzdCBpblxuICBsZXQgbGVuID0gTGlzdC5mb2xkX2xlZnQgbWF4X2FyZ19sZW4gMCBjb21wbGV0ZWQgaW5cbiAgbGV0IGxlbiA9IEludC5taW4gbGVuIGxpbWl0IGluXG4gIExpc3QubWFwIChhZGRfcGFkZGluZyBsZW4pIGNvbXBsZXRlZFxuXG5sZXQgdHJpbV9jciBzID1cbiAgbGV0IGxlbiA9IFN0cmluZy5sZW5ndGggcyBpblxuICBpZiBsZW4gPiAwICYmIFN0cmluZy5nZXQgcyAobGVuIC0gMSkgPSAnXFxyJyB0aGVuXG4gICAgU3RyaW5nLnN1YiBzIDAgKGxlbiAtIDEpXG4gIGVsc2VcbiAgICBzXG5cbmxldCByZWFkX2F1eCB0cmltIHNlcCBmaWxlID1cbiAgbGV0IGljID0gb3Blbl9pbl9iaW4gZmlsZSBpblxuICBsZXQgYnVmID0gQnVmZmVyLmNyZWF0ZSAyMDAgaW5cbiAgbGV0IHdvcmRzID0gcmVmIFtdIGluXG4gIGxldCBzdGFzaCAoKSA9XG4gICAgbGV0IHdvcmQgPSBCdWZmZXIuY29udGVudHMgYnVmIGluXG4gICAgbGV0IHdvcmQgPSBpZiB0cmltIHRoZW4gdHJpbV9jciB3b3JkIGVsc2Ugd29yZCBpblxuICAgIHdvcmRzIDo9IHdvcmQgOjogIXdvcmRzO1xuICAgIEJ1ZmZlci5jbGVhciBidWZcbiAgaW5cbiAgYmVnaW5cbiAgICB0cnkgd2hpbGUgdHJ1ZSBkb1xuICAgICAgICBsZXQgYyA9IGlucHV0X2NoYXIgaWMgaW5cbiAgICAgICAgaWYgYyA9IHNlcCB0aGVuIHN0YXNoICgpIGVsc2UgQnVmZmVyLmFkZF9jaGFyIGJ1ZiBjXG4gICAgICBkb25lXG4gICAgd2l0aCBFbmRfb2ZfZmlsZSAtPiAoKVxuICBlbmQ7XG4gIGlmIEJ1ZmZlci5sZW5ndGggYnVmID4gMCB0aGVuIHN0YXNoICgpO1xuICBjbG9zZV9pbiBpYztcbiAgQXJyYXkub2ZfbGlzdCAoTGlzdC5yZXYgIXdvcmRzKVxuXG5sZXQgcmVhZF9hcmcgPSByZWFkX2F1eCB0cnVlICdcXG4nXG5cbmxldCByZWFkX2FyZzAgPSByZWFkX2F1eCBmYWxzZSAnXFx4MDAnXG5cbmxldCB3cml0ZV9hdXggc2VwIGZpbGUgYXJncyA9XG4gIGxldCBvYyA9IG9wZW5fb3V0X2JpbiBmaWxlIGluXG4gIEFycmF5Lml0ZXIgKGZ1biBzIC0+IGZwcmludGYgb2MgXCIlcyVjXCIgcyBzZXApIGFyZ3M7XG4gIGNsb3NlX291dCBvY1xuXG5sZXQgd3JpdGVfYXJnID0gd3JpdGVfYXV4ICdcXG4nXG5cbmxldCB3cml0ZV9hcmcwID0gd3JpdGVfYXV4ICdcXHgwMCdcbiIsIigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0NhbWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgIFhhdmllciBMZXJveSwgcHJvamV0IENyaXN0YWwsIElOUklBIFJvY3F1ZW5jb3VydCAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQ29weXJpZ2h0IDE5OTYgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCAgICAgKilcbigqICAgICBlbiBBdXRvbWF0aXF1ZS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQWxsIHJpZ2h0cyByZXNlcnZlZC4gIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgICAgKilcbigqICAgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIuMSwgd2l0aCB0aGUgICAgICAgICAgKilcbigqICAgc3BlY2lhbCBleGNlcHRpb24gb24gbGlua2luZyBkZXNjcmliZWQgaW4gdGhlIGZpbGUgTElDRU5TRS4gICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcblxub3BlbiBQcmludGZcblxudHlwZSB0ID0gZXhuID0gLi5cblxubGV0IHByaW50ZXJzID0gQXRvbWljLm1ha2UgW11cblxubGV0IGxvY2ZtdCA9IGZvcm1hdF9vZl9zdHJpbmcgXCJGaWxlIFxcXCIlc1xcXCIsIGxpbmUgJWQsIGNoYXJhY3RlcnMgJWQtJWQ6ICVzXCJcblxubGV0IGZpZWxkIHggaSA9XG4gIGxldCBmID0gT2JqLmZpZWxkIHggaSBpblxuICBpZiBub3QgKE9iai5pc19ibG9jayBmKSB0aGVuXG4gICAgc3ByaW50ZiBcIiVkXCIgKE9iai5tYWdpYyBmIDogaW50KSAgICAgICAgICAgKCogY2FuIGFsc28gYmUgYSBjaGFyICopXG4gIGVsc2UgaWYgT2JqLnRhZyBmID0gT2JqLnN0cmluZ190YWcgdGhlblxuICAgIHNwcmludGYgXCIlU1wiIChPYmoubWFnaWMgZiA6IHN0cmluZylcbiAgZWxzZSBpZiBPYmoudGFnIGYgPSBPYmouZG91YmxlX3RhZyB0aGVuXG4gICAgc3RyaW5nX29mX2Zsb2F0IChPYmoubWFnaWMgZiA6IGZsb2F0KVxuICBlbHNlXG4gICAgXCJfXCJcblxubGV0IHJlYyBvdGhlcl9maWVsZHMgeCBpID1cbiAgaWYgaSA+PSBPYmouc2l6ZSB4IHRoZW4gXCJcIlxuICBlbHNlIHNwcmludGYgXCIsICVzJXNcIiAoZmllbGQgeCBpKSAob3RoZXJfZmllbGRzIHggKGkrMSkpXG5cbmxldCBmaWVsZHMgeCA9XG4gIG1hdGNoIE9iai5zaXplIHggd2l0aFxuICB8IDAgLT4gXCJcIlxuICB8IDEgLT4gXCJcIlxuICB8IDIgLT4gc3ByaW50ZiBcIiglcylcIiAoZmllbGQgeCAxKVxuICB8IF8gLT4gc3ByaW50ZiBcIiglcyVzKVwiIChmaWVsZCB4IDEpIChvdGhlcl9maWVsZHMgeCAyKVxuXG5sZXQgdXNlX3ByaW50ZXJzIHggPVxuICBsZXQgcmVjIGNvbnYgPSBmdW5jdGlvblxuICAgIHwgaGQgOjogdGwgLT5cbiAgICAgICAgKG1hdGNoIGhkIHggd2l0aFxuICAgICAgICAgfCBOb25lIHwgZXhjZXB0aW9uIF8gLT4gY29udiB0bFxuICAgICAgICAgfCBTb21lIHMgLT4gU29tZSBzKVxuICAgIHwgW10gLT4gTm9uZSBpblxuICBjb252IChBdG9taWMuZ2V0IHByaW50ZXJzKVxuXG5sZXQgdG9fc3RyaW5nX2RlZmF1bHQgPSBmdW5jdGlvblxuICB8IE91dF9vZl9tZW1vcnkgLT4gXCJPdXQgb2YgbWVtb3J5XCJcbiAgfCBTdGFja19vdmVyZmxvdyAtPiBcIlN0YWNrIG92ZXJmbG93XCJcbiAgfCBNYXRjaF9mYWlsdXJlKGZpbGUsIGxpbmUsIGNoYXIpIC0+XG4gICAgICBzcHJpbnRmIGxvY2ZtdCBmaWxlIGxpbmUgY2hhciAoY2hhcis1KSBcIlBhdHRlcm4gbWF0Y2hpbmcgZmFpbGVkXCJcbiAgfCBBc3NlcnRfZmFpbHVyZShmaWxlLCBsaW5lLCBjaGFyKSAtPlxuICAgICAgc3ByaW50ZiBsb2NmbXQgZmlsZSBsaW5lIGNoYXIgKGNoYXIrNikgXCJBc3NlcnRpb24gZmFpbGVkXCJcbiAgfCBVbmRlZmluZWRfcmVjdXJzaXZlX21vZHVsZShmaWxlLCBsaW5lLCBjaGFyKSAtPlxuICAgICAgc3ByaW50ZiBsb2NmbXQgZmlsZSBsaW5lIGNoYXIgKGNoYXIrNikgXCJVbmRlZmluZWQgcmVjdXJzaXZlIG1vZHVsZVwiXG4gIHwgeCAtPlxuICAgICAgbGV0IHggPSBPYmoucmVwciB4IGluXG4gICAgICBpZiBPYmoudGFnIHggPD4gMCB0aGVuXG4gICAgICAgIChPYmoubWFnaWMgKE9iai5maWVsZCB4IDApIDogc3RyaW5nKVxuICAgICAgZWxzZVxuICAgICAgICBsZXQgY29uc3RydWN0b3IgPVxuICAgICAgICAgIChPYmoubWFnaWMgKE9iai5maWVsZCAoT2JqLmZpZWxkIHggMCkgMCkgOiBzdHJpbmcpIGluXG4gICAgICAgIGNvbnN0cnVjdG9yIF4gKGZpZWxkcyB4KVxuXG5sZXQgdG9fc3RyaW5nIGUgPVxuICBtYXRjaCB1c2VfcHJpbnRlcnMgZSB3aXRoXG4gIHwgU29tZSBzIC0+IHNcbiAgfCBOb25lIC0+IHRvX3N0cmluZ19kZWZhdWx0IGVcblxubGV0IHByaW50IGZjdCBhcmcgPVxuICB0cnlcbiAgICBmY3QgYXJnXG4gIHdpdGggeCAtPlxuICAgIGVwcmludGYgXCJVbmNhdWdodCBleGNlcHRpb246ICVzXFxuXCIgKHRvX3N0cmluZyB4KTtcbiAgICBmbHVzaCBzdGRlcnI7XG4gICAgcmFpc2UgeFxuXG5sZXQgY2F0Y2ggZmN0IGFyZyA9XG4gIHRyeVxuICAgIGZjdCBhcmdcbiAgd2l0aCB4IC0+XG4gICAgZmx1c2ggc3Rkb3V0O1xuICAgIGVwcmludGYgXCJVbmNhdWdodCBleGNlcHRpb246ICVzXFxuXCIgKHRvX3N0cmluZyB4KTtcbiAgICBleGl0IDJcblxudHlwZSByYXdfYmFja3RyYWNlX3Nsb3RcbnR5cGUgcmF3X2JhY2t0cmFjZV9lbnRyeSA9IHByaXZhdGUgaW50XG50eXBlIHJhd19iYWNrdHJhY2UgPSByYXdfYmFja3RyYWNlX2VudHJ5IGFycmF5XG5cbmxldCByYXdfYmFja3RyYWNlX2VudHJpZXMgYnQgPSBidFxuXG5leHRlcm5hbCBnZXRfcmF3X2JhY2t0cmFjZTpcbiAgdW5pdCAtPiByYXdfYmFja3RyYWNlID0gXCJjYW1sX2dldF9leGNlcHRpb25fcmF3X2JhY2t0cmFjZVwiXG5cbmV4dGVybmFsIHJhaXNlX3dpdGhfYmFja3RyYWNlOiBleG4gLT4gcmF3X2JhY2t0cmFjZSAtPiAnYVxuICA9IFwiJXJhaXNlX3dpdGhfYmFja3RyYWNlXCJcblxudHlwZSBiYWNrdHJhY2Vfc2xvdCA9XG4gIHwgS25vd25fbG9jYXRpb24gb2Yge1xuICAgICAgaXNfcmFpc2UgICAgOiBib29sO1xuICAgICAgZmlsZW5hbWUgICAgOiBzdHJpbmc7XG4gICAgICBsaW5lX251bWJlciA6IGludDtcbiAgICAgIHN0YXJ0X2NoYXIgIDogaW50O1xuICAgICAgZW5kX2NoYXIgICAgOiBpbnQ7XG4gICAgICBpc19pbmxpbmUgICA6IGJvb2w7XG4gICAgICBkZWZuYW1lICAgICA6IHN0cmluZztcbiAgICB9XG4gIHwgVW5rbm93bl9sb2NhdGlvbiBvZiB7XG4gICAgICBpc19yYWlzZSA6IGJvb2xcbiAgICB9XG5cbigqIHRvIGF2b2lkIHdhcm5pbmcgKilcbmxldCBfID0gW0tub3duX2xvY2F0aW9uIHsgaXNfcmFpc2UgPSBmYWxzZTsgZmlsZW5hbWUgPSBcIlwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lX251bWJlciA9IDA7IHN0YXJ0X2NoYXIgPSAwOyBlbmRfY2hhciA9IDA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2lubGluZSA9IGZhbHNlOyBkZWZuYW1lID0gXCJcIiB9O1xuICAgICAgICAgVW5rbm93bl9sb2NhdGlvbiB7IGlzX3JhaXNlID0gZmFsc2UgfV1cblxuZXh0ZXJuYWwgY29udmVydF9yYXdfYmFja3RyYWNlX3Nsb3Q6XG4gIHJhd19iYWNrdHJhY2Vfc2xvdCAtPiBiYWNrdHJhY2Vfc2xvdCA9IFwiY2FtbF9jb252ZXJ0X3Jhd19iYWNrdHJhY2Vfc2xvdFwiXG5cbmV4dGVybmFsIGNvbnZlcnRfcmF3X2JhY2t0cmFjZTpcbiAgcmF3X2JhY2t0cmFjZSAtPiBiYWNrdHJhY2Vfc2xvdCBhcnJheSA9IFwiY2FtbF9jb252ZXJ0X3Jhd19iYWNrdHJhY2VcIlxuXG5sZXQgY29udmVydF9yYXdfYmFja3RyYWNlIGJ0ID1cbiAgdHJ5IFNvbWUgKGNvbnZlcnRfcmF3X2JhY2t0cmFjZSBidClcbiAgd2l0aCBGYWlsdXJlIF8gLT4gTm9uZVxuXG5sZXQgZm9ybWF0X2JhY2t0cmFjZV9zbG90IHBvcyBzbG90ID1cbiAgbGV0IGluZm8gaXNfcmFpc2UgPVxuICAgIGlmIGlzX3JhaXNlIHRoZW5cbiAgICAgIGlmIHBvcyA9IDAgdGhlbiBcIlJhaXNlZCBhdFwiIGVsc2UgXCJSZS1yYWlzZWQgYXRcIlxuICAgIGVsc2VcbiAgICAgIGlmIHBvcyA9IDAgdGhlbiBcIlJhaXNlZCBieSBwcmltaXRpdmUgb3BlcmF0aW9uIGF0XCIgZWxzZSBcIkNhbGxlZCBmcm9tXCJcbiAgaW5cbiAgbWF0Y2ggc2xvdCB3aXRoXG4gIHwgVW5rbm93bl9sb2NhdGlvbiBsIC0+XG4gICAgICBpZiBsLmlzX3JhaXNlIHRoZW5cbiAgICAgICAgKCogY29tcGlsZXItaW5zZXJ0ZWQgcmUtcmFpc2UsIHNraXBwZWQgKikgTm9uZVxuICAgICAgZWxzZVxuICAgICAgICBTb21lIChzcHJpbnRmIFwiJXMgdW5rbm93biBsb2NhdGlvblwiIChpbmZvIGZhbHNlKSlcbiAgfCBLbm93bl9sb2NhdGlvbiBsIC0+XG4gICAgICBTb21lIChzcHJpbnRmIFwiJXMgJXMgaW4gZmlsZSBcXFwiJXNcXFwiJXMsIGxpbmUgJWQsIGNoYXJhY3RlcnMgJWQtJWRcIlxuICAgICAgICAgICAgICAoaW5mbyBsLmlzX3JhaXNlKSBsLmRlZm5hbWUgbC5maWxlbmFtZVxuICAgICAgICAgICAgICAoaWYgbC5pc19pbmxpbmUgdGhlbiBcIiAoaW5saW5lZClcIiBlbHNlIFwiXCIpXG4gICAgICAgICAgICAgIGwubGluZV9udW1iZXIgbC5zdGFydF9jaGFyIGwuZW5kX2NoYXIpXG5cbmxldCBwcmludF9leGNlcHRpb25fYmFja3RyYWNlIG91dGNoYW4gYmFja3RyYWNlID1cbiAgbWF0Y2ggYmFja3RyYWNlIHdpdGhcbiAgfCBOb25lIC0+XG4gICAgICBmcHJpbnRmIG91dGNoYW5cbiAgICAgICAgXCIoUHJvZ3JhbSBub3QgbGlua2VkIHdpdGggLWcsIGNhbm5vdCBwcmludCBzdGFjayBiYWNrdHJhY2UpXFxuXCJcbiAgfCBTb21lIGEgLT5cbiAgICAgIGZvciBpID0gMCB0byBBcnJheS5sZW5ndGggYSAtIDEgZG9cbiAgICAgICAgbWF0Y2ggZm9ybWF0X2JhY2t0cmFjZV9zbG90IGkgYS4oaSkgd2l0aFxuICAgICAgICAgIHwgTm9uZSAtPiAoKVxuICAgICAgICAgIHwgU29tZSBzdHIgLT4gZnByaW50ZiBvdXRjaGFuIFwiJXNcXG5cIiBzdHJcbiAgICAgIGRvbmVcblxubGV0IHByaW50X3Jhd19iYWNrdHJhY2Ugb3V0Y2hhbiByYXdfYmFja3RyYWNlID1cbiAgcHJpbnRfZXhjZXB0aW9uX2JhY2t0cmFjZSBvdXRjaGFuIChjb252ZXJ0X3Jhd19iYWNrdHJhY2UgcmF3X2JhY2t0cmFjZSlcblxuKCogY29uZnVzaW5nbHkgbmFtZWQ6IHByaW50cyB0aGUgZ2xvYmFsIGN1cnJlbnQgYmFja3RyYWNlICopXG5sZXQgcHJpbnRfYmFja3RyYWNlIG91dGNoYW4gPVxuICBwcmludF9yYXdfYmFja3RyYWNlIG91dGNoYW4gKGdldF9yYXdfYmFja3RyYWNlICgpKVxuXG5sZXQgYmFja3RyYWNlX3RvX3N0cmluZyBiYWNrdHJhY2UgPVxuICBtYXRjaCBiYWNrdHJhY2Ugd2l0aFxuICB8IE5vbmUgLT5cbiAgICAgXCIoUHJvZ3JhbSBub3QgbGlua2VkIHdpdGggLWcsIGNhbm5vdCBwcmludCBzdGFjayBiYWNrdHJhY2UpXFxuXCJcbiAgfCBTb21lIGEgLT5cbiAgICAgIGxldCBiID0gQnVmZmVyLmNyZWF0ZSAxMDI0IGluXG4gICAgICBmb3IgaSA9IDAgdG8gQXJyYXkubGVuZ3RoIGEgLSAxIGRvXG4gICAgICAgIG1hdGNoIGZvcm1hdF9iYWNrdHJhY2Vfc2xvdCBpIGEuKGkpIHdpdGhcbiAgICAgICAgICB8IE5vbmUgLT4gKClcbiAgICAgICAgICB8IFNvbWUgc3RyIC0+IGJwcmludGYgYiBcIiVzXFxuXCIgc3RyXG4gICAgICBkb25lO1xuICAgICAgQnVmZmVyLmNvbnRlbnRzIGJcblxubGV0IHJhd19iYWNrdHJhY2VfdG9fc3RyaW5nIHJhd19iYWNrdHJhY2UgPVxuICBiYWNrdHJhY2VfdG9fc3RyaW5nIChjb252ZXJ0X3Jhd19iYWNrdHJhY2UgcmF3X2JhY2t0cmFjZSlcblxubGV0IGJhY2t0cmFjZV9zbG90X2lzX3JhaXNlID0gZnVuY3Rpb25cbiAgfCBLbm93bl9sb2NhdGlvbiBsIC0+IGwuaXNfcmFpc2VcbiAgfCBVbmtub3duX2xvY2F0aW9uIGwgLT4gbC5pc19yYWlzZVxuXG5sZXQgYmFja3RyYWNlX3Nsb3RfaXNfaW5saW5lID0gZnVuY3Rpb25cbiAgfCBLbm93bl9sb2NhdGlvbiBsIC0+IGwuaXNfaW5saW5lXG4gIHwgVW5rbm93bl9sb2NhdGlvbiBfIC0+IGZhbHNlXG5cbnR5cGUgbG9jYXRpb24gPSB7XG4gIGZpbGVuYW1lIDogc3RyaW5nO1xuICBsaW5lX251bWJlciA6IGludDtcbiAgc3RhcnRfY2hhciA6IGludDtcbiAgZW5kX2NoYXIgOiBpbnQ7XG59XG5cbmxldCBiYWNrdHJhY2Vfc2xvdF9sb2NhdGlvbiA9IGZ1bmN0aW9uXG4gIHwgVW5rbm93bl9sb2NhdGlvbiBfIC0+IE5vbmVcbiAgfCBLbm93bl9sb2NhdGlvbiBsIC0+XG4gICAgU29tZSB7XG4gICAgICBmaWxlbmFtZSAgICA9IGwuZmlsZW5hbWU7XG4gICAgICBsaW5lX251bWJlciA9IGwubGluZV9udW1iZXI7XG4gICAgICBzdGFydF9jaGFyICA9IGwuc3RhcnRfY2hhcjtcbiAgICAgIGVuZF9jaGFyICAgID0gbC5lbmRfY2hhcjtcbiAgICB9XG5cbmxldCBiYWNrdHJhY2Vfc2xvdF9kZWZuYW1lID0gZnVuY3Rpb25cbiAgfCBVbmtub3duX2xvY2F0aW9uIF9cbiAgfCBLbm93bl9sb2NhdGlvbiB7IGRlZm5hbWUgPSBcIlwiIH0gLT4gTm9uZVxuICB8IEtub3duX2xvY2F0aW9uIGwgLT4gU29tZSBsLmRlZm5hbWVcblxubGV0IGJhY2t0cmFjZV9zbG90cyByYXdfYmFja3RyYWNlID1cbiAgKCogVGhlIGRvY3VtZW50YXRpb24gb2YgdGhpcyBmdW5jdGlvbiBndWFyYW50ZWVzIHRoYXQgU29tZSBpc1xuICAgICByZXR1cm5lZCBvbmx5IGlmIGEgcGFydCBvZiB0aGUgdHJhY2UgaXMgdXNhYmxlLiBUaGlzIGdpdmVzIHVzXG4gICAgIGEgYml0IG1vcmUgd29yayB0aGFuIGp1c3QgY29udmVydF9yYXdfYmFja3RyYWNlLCBidXQgaXQgbWFrZXMgdGhlXG4gICAgIEFQSSBtb3JlIHVzZXItZnJpZW5kbHkgLS0gb3RoZXJ3aXNlIG1vc3QgdXNlcnMgd291bGQgaGF2ZSB0b1xuICAgICByZWltcGxlbWVudCB0aGUgXCJQcm9ncmFtIG5vdCBsaW5rZWQgd2l0aCAtZywgc29ycnlcIiBsb2dpY1xuICAgICB0aGVtc2VsdmVzLiAqKVxuICBtYXRjaCBjb252ZXJ0X3Jhd19iYWNrdHJhY2UgcmF3X2JhY2t0cmFjZSB3aXRoXG4gICAgfCBOb25lIC0+IE5vbmVcbiAgICB8IFNvbWUgYmFja3RyYWNlIC0+XG4gICAgICBsZXQgdXNhYmxlX3Nsb3QgPSBmdW5jdGlvblxuICAgICAgICB8IFVua25vd25fbG9jYXRpb24gXyAtPiBmYWxzZVxuICAgICAgICB8IEtub3duX2xvY2F0aW9uIF8gLT4gdHJ1ZSBpblxuICAgICAgbGV0IHJlYyBleGlzdHNfdXNhYmxlID0gZnVuY3Rpb25cbiAgICAgICAgfCAoLTEpIC0+IGZhbHNlXG4gICAgICAgIHwgaSAtPiB1c2FibGVfc2xvdCBiYWNrdHJhY2UuKGkpIHx8IGV4aXN0c191c2FibGUgKGkgLSAxKSBpblxuICAgICAgaWYgZXhpc3RzX3VzYWJsZSAoQXJyYXkubGVuZ3RoIGJhY2t0cmFjZSAtIDEpXG4gICAgICB0aGVuIFNvbWUgYmFja3RyYWNlXG4gICAgICBlbHNlIE5vbmVcblxubGV0IGJhY2t0cmFjZV9zbG90c19vZl9yYXdfZW50cnkgZW50cnkgPVxuICBiYWNrdHJhY2Vfc2xvdHMgW3wgZW50cnkgfF1cblxubW9kdWxlIFNsb3QgPSBzdHJ1Y3RcbiAgdHlwZSB0ID0gYmFja3RyYWNlX3Nsb3RcbiAgbGV0IGZvcm1hdCA9IGZvcm1hdF9iYWNrdHJhY2Vfc2xvdFxuICBsZXQgaXNfcmFpc2UgPSBiYWNrdHJhY2Vfc2xvdF9pc19yYWlzZVxuICBsZXQgaXNfaW5saW5lID0gYmFja3RyYWNlX3Nsb3RfaXNfaW5saW5lXG4gIGxldCBsb2NhdGlvbiA9IGJhY2t0cmFjZV9zbG90X2xvY2F0aW9uXG4gIGxldCBuYW1lID0gYmFja3RyYWNlX3Nsb3RfZGVmbmFtZVxuZW5kXG5cbmxldCByYXdfYmFja3RyYWNlX2xlbmd0aCBidCA9IEFycmF5Lmxlbmd0aCBidFxuXG5leHRlcm5hbCBnZXRfcmF3X2JhY2t0cmFjZV9zbG90IDpcbiAgcmF3X2JhY2t0cmFjZSAtPiBpbnQgLT4gcmF3X2JhY2t0cmFjZV9zbG90ID0gXCJjYW1sX3Jhd19iYWNrdHJhY2Vfc2xvdFwiXG5cbmV4dGVybmFsIGdldF9yYXdfYmFja3RyYWNlX25leHRfc2xvdCA6XG4gIHJhd19iYWNrdHJhY2Vfc2xvdCAtPiByYXdfYmFja3RyYWNlX3Nsb3Qgb3B0aW9uXG4gID0gXCJjYW1sX3Jhd19iYWNrdHJhY2VfbmV4dF9zbG90XCJcblxuKCogY29uZnVzaW5nbHkgbmFtZWQ6XG4gICByZXR1cm5zIHRoZSAqc3RyaW5nKiBjb3JyZXNwb25kaW5nIHRvIHRoZSBnbG9iYWwgY3VycmVudCBiYWNrdHJhY2UgKilcbmxldCBnZXRfYmFja3RyYWNlICgpID0gcmF3X2JhY2t0cmFjZV90b19zdHJpbmcgKGdldF9yYXdfYmFja3RyYWNlICgpKVxuXG5leHRlcm5hbCByZWNvcmRfYmFja3RyYWNlOiBib29sIC0+IHVuaXQgPSBcImNhbWxfcmVjb3JkX2JhY2t0cmFjZVwiXG5leHRlcm5hbCBiYWNrdHJhY2Vfc3RhdHVzOiB1bml0IC0+IGJvb2wgPSBcImNhbWxfYmFja3RyYWNlX3N0YXR1c1wiXG5cbmxldCByZWMgcmVnaXN0ZXJfcHJpbnRlciBmbiA9XG4gIGxldCBvbGRfcHJpbnRlcnMgPSBBdG9taWMuZ2V0IHByaW50ZXJzIGluXG4gIGxldCBuZXdfcHJpbnRlcnMgPSBmbiA6OiBvbGRfcHJpbnRlcnMgaW5cbiAgbGV0IHN1Y2Nlc3MgPSBBdG9taWMuY29tcGFyZV9hbmRfc2V0IHByaW50ZXJzIG9sZF9wcmludGVycyBuZXdfcHJpbnRlcnMgaW5cbiAgaWYgbm90IHN1Y2Nlc3MgdGhlbiByZWdpc3Rlcl9wcmludGVyIGZuXG5cbmV4dGVybmFsIGdldF9jYWxsc3RhY2s6IGludCAtPiByYXdfYmFja3RyYWNlID0gXCJjYW1sX2dldF9jdXJyZW50X2NhbGxzdGFja1wiXG5cbmxldCBleG5fc2xvdCB4ID1cbiAgbGV0IHggPSBPYmoucmVwciB4IGluXG4gIGlmIE9iai50YWcgeCA9IDAgdGhlbiBPYmouZmllbGQgeCAwIGVsc2UgeFxuXG5sZXQgZXhuX3Nsb3RfaWQgeCA9XG4gIGxldCBzbG90ID0gZXhuX3Nsb3QgeCBpblxuICAoT2JqLm9iaiAoT2JqLmZpZWxkIHNsb3QgMSkgOiBpbnQpXG5cbmxldCBleG5fc2xvdF9uYW1lIHggPVxuICBsZXQgc2xvdCA9IGV4bl9zbG90IHggaW5cbiAgKE9iai5vYmogKE9iai5maWVsZCBzbG90IDApIDogc3RyaW5nKVxuXG5leHRlcm5hbCBnZXRfZGVidWdfaW5mb19zdGF0dXMgOiB1bml0IC0+IGludCA9IFwiY2FtbF9tbF9kZWJ1Z19pbmZvX3N0YXR1c1wiXG5cbigqIERlc2NyaXB0aW9ucyBmb3IgZXJyb3JzIGluIHN0YXJ0dXAuaC4gU2VlIGFsc28gYmFja3RyYWNlLmMgKilcbmxldCBlcnJvcnMgPSBbfCBcIlwiO1xuICAoKiBGSUxFX05PVF9GT1VORCAqKVxuICBcIihDYW5ub3QgcHJpbnQgbG9jYXRpb25zOlxcbiBcXFxuICAgICAgYnl0ZWNvZGUgZXhlY3V0YWJsZSBwcm9ncmFtIGZpbGUgbm90IGZvdW5kKVwiO1xuICAoKiBCQURfQllURUNPREUgKilcbiAgXCIoQ2Fubm90IHByaW50IGxvY2F0aW9uczpcXG4gXFxcbiAgICAgIGJ5dGVjb2RlIGV4ZWN1dGFibGUgcHJvZ3JhbSBmaWxlIGFwcGVhcnMgdG8gYmUgY29ycnVwdClcIjtcbiAgKCogV1JPTkdfTUFHSUMgKilcbiAgXCIoQ2Fubm90IHByaW50IGxvY2F0aW9uczpcXG4gXFxcbiAgICAgIGJ5dGVjb2RlIGV4ZWN1dGFibGUgcHJvZ3JhbSBmaWxlIGhhcyB3cm9uZyBtYWdpYyBudW1iZXIpXCI7XG4gICgqIE5PX0ZEUyAqKVxuICBcIihDYW5ub3QgcHJpbnQgbG9jYXRpb25zOlxcbiBcXFxuICAgICAgYnl0ZWNvZGUgZXhlY3V0YWJsZSBwcm9ncmFtIGZpbGUgY2Fubm90IGJlIG9wZW5lZDtcXG4gXFxcbiAgICAgIC0tIHRvbyBtYW55IG9wZW4gZmlsZXMuIFRyeSBydW5uaW5nIHdpdGggT0NBTUxSVU5QQVJBTT1iPTIpXCJcbnxdXG5cbmxldCBkZWZhdWx0X3VuY2F1Z2h0X2V4Y2VwdGlvbl9oYW5kbGVyIGV4biByYXdfYmFja3RyYWNlID1cbiAgZXByaW50ZiBcIkZhdGFsIGVycm9yOiBleGNlcHRpb24gJXNcXG5cIiAodG9fc3RyaW5nIGV4bik7XG4gIHByaW50X3Jhd19iYWNrdHJhY2Ugc3RkZXJyIHJhd19iYWNrdHJhY2U7XG4gIGxldCBzdGF0dXMgPSBnZXRfZGVidWdfaW5mb19zdGF0dXMgKCkgaW5cbiAgaWYgc3RhdHVzIDwgMCB0aGVuXG4gICAgcHJlcnJfZW5kbGluZSBlcnJvcnMuKGFicyBzdGF0dXMpO1xuICBmbHVzaCBzdGRlcnJcblxubGV0IHVuY2F1Z2h0X2V4Y2VwdGlvbl9oYW5kbGVyID0gcmVmIGRlZmF1bHRfdW5jYXVnaHRfZXhjZXB0aW9uX2hhbmRsZXJcblxubGV0IHNldF91bmNhdWdodF9leGNlcHRpb25faGFuZGxlciBmbiA9IHVuY2F1Z2h0X2V4Y2VwdGlvbl9oYW5kbGVyIDo9IGZuXG5cbmxldCBlbXB0eV9iYWNrdHJhY2UgOiByYXdfYmFja3RyYWNlID0gW3wgfF1cblxubGV0IHRyeV9nZXRfcmF3X2JhY2t0cmFjZSAoKSA9XG4gIHRyeVxuICAgIGdldF9yYXdfYmFja3RyYWNlICgpXG4gIHdpdGggXyAoKiBPdXRfb2ZfbWVtb3J5PyAqKSAtPlxuICAgIGVtcHR5X2JhY2t0cmFjZVxuXG5sZXQgaGFuZGxlX3VuY2F1Z2h0X2V4Y2VwdGlvbicgZXhuIGRlYnVnZ2VyX2luX3VzZSA9XG4gIHRyeVxuICAgICgqIEdldCB0aGUgYmFja3RyYWNlIG5vdywgaW4gY2FzZSBvbmUgb2YgdGhlIFthdF9leGl0XSBmdW5jdGlvblxuICAgICAgIGRlc3Ryb3lzIGl0LiAqKVxuICAgIGxldCByYXdfYmFja3RyYWNlID1cbiAgICAgIGlmIGRlYnVnZ2VyX2luX3VzZSAoKiBTYW1lIHRlc3QgYXMgaW4gW3J1bnRpbWUvcHJpbnRleGMuY10gKikgdGhlblxuICAgICAgICBlbXB0eV9iYWNrdHJhY2VcbiAgICAgIGVsc2VcbiAgICAgICAgdHJ5X2dldF9yYXdfYmFja3RyYWNlICgpXG4gICAgaW5cbiAgICAodHJ5IFN0ZGxpYi5kb19hdF9leGl0ICgpIHdpdGggXyAtPiAoKSk7XG4gICAgdHJ5XG4gICAgICAhdW5jYXVnaHRfZXhjZXB0aW9uX2hhbmRsZXIgZXhuIHJhd19iYWNrdHJhY2VcbiAgICB3aXRoIGV4bicgLT5cbiAgICAgIGxldCByYXdfYmFja3RyYWNlJyA9IHRyeV9nZXRfcmF3X2JhY2t0cmFjZSAoKSBpblxuICAgICAgZXByaW50ZiBcIkZhdGFsIGVycm9yOiBleGNlcHRpb24gJXNcXG5cIiAodG9fc3RyaW5nIGV4bik7XG4gICAgICBwcmludF9yYXdfYmFja3RyYWNlIHN0ZGVyciByYXdfYmFja3RyYWNlO1xuICAgICAgZXByaW50ZiBcIkZhdGFsIGVycm9yIGluIHVuY2F1Z2h0IGV4Y2VwdGlvbiBoYW5kbGVyOiBleGNlcHRpb24gJXNcXG5cIlxuICAgICAgICAodG9fc3RyaW5nIGV4bicpO1xuICAgICAgcHJpbnRfcmF3X2JhY2t0cmFjZSBzdGRlcnIgcmF3X2JhY2t0cmFjZSc7XG4gICAgICBmbHVzaCBzdGRlcnJcbiAgd2l0aFxuICAgIHwgT3V0X29mX21lbW9yeSAtPlxuICAgICAgICBwcmVycl9lbmRsaW5lXG4gICAgICAgICAgXCJGYXRhbCBlcnJvcjogb3V0IG9mIG1lbW9yeSBpbiB1bmNhdWdodCBleGNlcHRpb24gaGFuZGxlclwiXG5cbigqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGJ5IFtjYW1sX2ZhdGFsX3VuY2F1Z2h0X2V4Y2VwdGlvbl0gaW5cbiAgIFtydW50aW1lL3ByaW50ZXhjLmNdIHdoaWNoIGV4cGVjdHMgbm8gZXhjZXB0aW9uIGlzIHJhaXNlZC4gKilcbmxldCBoYW5kbGVfdW5jYXVnaHRfZXhjZXB0aW9uIGV4biBkZWJ1Z2dlcl9pbl91c2UgPVxuICB0cnlcbiAgICBoYW5kbGVfdW5jYXVnaHRfZXhjZXB0aW9uJyBleG4gZGVidWdnZXJfaW5fdXNlXG4gIHdpdGggXyAtPlxuICAgICgqIFRoZXJlIGlzIG5vdCBtdWNoIHdlIGNhbiBkbyBhdCB0aGlzIHBvaW50ICopXG4gICAgKClcblxuZXh0ZXJuYWwgcmVnaXN0ZXJfbmFtZWRfdmFsdWUgOiBzdHJpbmcgLT4gJ2EgLT4gdW5pdFxuICA9IFwiY2FtbF9yZWdpc3Rlcl9uYW1lZF92YWx1ZVwiXG5cbmxldCAoKSA9XG4gIHJlZ2lzdGVyX25hbWVkX3ZhbHVlIFwiUHJpbnRleGMuaGFuZGxlX3VuY2F1Z2h0X2V4Y2VwdGlvblwiXG4gICAgaGFuZGxlX3VuY2F1Z2h0X2V4Y2VwdGlvblxuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgVGhlIE9DYW1sIHByb2dyYW1tZXJzICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMjAxOCBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0ICAgICAqKVxuKCogICAgIGVuIEF1dG9tYXRpcXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG5leHRlcm5hbCBpZCA6ICdhIC0+ICdhID0gXCIlaWRlbnRpdHlcIlxubGV0IGNvbnN0IGMgXyA9IGNcbmxldCBmbGlwIGYgeCB5ID0gZiB5IHhcbmxldCBuZWdhdGUgcCB2ID0gbm90IChwIHYpXG5cbmV4Y2VwdGlvbiBGaW5hbGx5X3JhaXNlZCBvZiBleG5cblxubGV0ICgpID0gUHJpbnRleGMucmVnaXN0ZXJfcHJpbnRlciBAQCBmdW5jdGlvblxufCBGaW5hbGx5X3JhaXNlZCBleG4gLT4gU29tZSAoXCJGdW4uRmluYWxseV9yYWlzZWQ6IFwiIF4gUHJpbnRleGMudG9fc3RyaW5nIGV4bilcbnwgXyAtPiBOb25lXG5cbmxldCBwcm90ZWN0IH4oZmluYWxseSA6IHVuaXQgLT4gdW5pdCkgd29yayA9XG4gIGxldCBmaW5hbGx5X25vX2V4biAoKSA9XG4gICAgdHJ5IGZpbmFsbHkgKCkgd2l0aCBlIC0+XG4gICAgICBsZXQgYnQgPSBQcmludGV4Yy5nZXRfcmF3X2JhY2t0cmFjZSAoKSBpblxuICAgICAgUHJpbnRleGMucmFpc2Vfd2l0aF9iYWNrdHJhY2UgKEZpbmFsbHlfcmFpc2VkIGUpIGJ0XG4gIGluXG4gIG1hdGNoIHdvcmsgKCkgd2l0aFxuICB8IHJlc3VsdCAtPiBmaW5hbGx5X25vX2V4biAoKSA7IHJlc3VsdFxuICB8IGV4Y2VwdGlvbiB3b3JrX2V4biAtPlxuICAgICAgbGV0IHdvcmtfYnQgPSBQcmludGV4Yy5nZXRfcmF3X2JhY2t0cmFjZSAoKSBpblxuICAgICAgZmluYWxseV9ub19leG4gKCkgO1xuICAgICAgUHJpbnRleGMucmFpc2Vfd2l0aF9iYWNrdHJhY2Ugd29ya19leG4gd29ya19idFxuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICBEYW1pZW4gRG9saWdleiwgcHJvamV0IFBhcmEsIElOUklBIFJvY3F1ZW5jb3VydCAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICBKYWNxdWVzLUhlbnJpIEpvdXJkYW4sIHByb2pldCBHYWxsaXVtLCBJTlJJQSBQYXJpcyAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMTk5Ni0yMDE2IEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgICAqKVxuKCogICAgIGV0IGVuIEF1dG9tYXRpcXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG50eXBlIHN0YXQgPSB7XG4gIG1pbm9yX3dvcmRzIDogZmxvYXQ7XG4gIHByb21vdGVkX3dvcmRzIDogZmxvYXQ7XG4gIG1ham9yX3dvcmRzIDogZmxvYXQ7XG4gIG1pbm9yX2NvbGxlY3Rpb25zIDogaW50O1xuICBtYWpvcl9jb2xsZWN0aW9ucyA6IGludDtcbiAgaGVhcF93b3JkcyA6IGludDtcbiAgaGVhcF9jaHVua3MgOiBpbnQ7XG4gIGxpdmVfd29yZHMgOiBpbnQ7XG4gIGxpdmVfYmxvY2tzIDogaW50O1xuICBmcmVlX3dvcmRzIDogaW50O1xuICBmcmVlX2Jsb2NrcyA6IGludDtcbiAgbGFyZ2VzdF9mcmVlIDogaW50O1xuICBmcmFnbWVudHMgOiBpbnQ7XG4gIGNvbXBhY3Rpb25zIDogaW50O1xuICB0b3BfaGVhcF93b3JkcyA6IGludDtcbiAgc3RhY2tfc2l6ZSA6IGludDtcbiAgZm9yY2VkX21ham9yX2NvbGxlY3Rpb25zOiBpbnQ7XG59XG5cbnR5cGUgY29udHJvbCA9IHtcbiAgbXV0YWJsZSBtaW5vcl9oZWFwX3NpemUgOiBpbnQ7XG4gIG11dGFibGUgbWFqb3JfaGVhcF9pbmNyZW1lbnQgOiBpbnQ7XG4gIG11dGFibGUgc3BhY2Vfb3ZlcmhlYWQgOiBpbnQ7XG4gIG11dGFibGUgdmVyYm9zZSA6IGludDtcbiAgbXV0YWJsZSBtYXhfb3ZlcmhlYWQgOiBpbnQ7XG4gIG11dGFibGUgc3RhY2tfbGltaXQgOiBpbnQ7XG4gIG11dGFibGUgYWxsb2NhdGlvbl9wb2xpY3kgOiBpbnQ7XG4gIHdpbmRvd19zaXplIDogaW50O1xuICBjdXN0b21fbWFqb3JfcmF0aW8gOiBpbnQ7XG4gIGN1c3RvbV9taW5vcl9yYXRpbyA6IGludDtcbiAgY3VzdG9tX21pbm9yX21heF9zaXplIDogaW50O1xufVxuXG5leHRlcm5hbCBzdGF0IDogdW5pdCAtPiBzdGF0ID0gXCJjYW1sX2djX3N0YXRcIlxuZXh0ZXJuYWwgcXVpY2tfc3RhdCA6IHVuaXQgLT4gc3RhdCA9IFwiY2FtbF9nY19xdWlja19zdGF0XCJcbmV4dGVybmFsIGNvdW50ZXJzIDogdW5pdCAtPiAoZmxvYXQgKiBmbG9hdCAqIGZsb2F0KSA9IFwiY2FtbF9nY19jb3VudGVyc1wiXG5leHRlcm5hbCBtaW5vcl93b3JkcyA6IHVuaXQgLT4gKGZsb2F0IFtAdW5ib3hlZF0pXG4gID0gXCJjYW1sX2djX21pbm9yX3dvcmRzXCIgXCJjYW1sX2djX21pbm9yX3dvcmRzX3VuYm94ZWRcIlxuZXh0ZXJuYWwgZ2V0IDogdW5pdCAtPiBjb250cm9sID0gXCJjYW1sX2djX2dldFwiXG5leHRlcm5hbCBzZXQgOiBjb250cm9sIC0+IHVuaXQgPSBcImNhbWxfZ2Nfc2V0XCJcbmV4dGVybmFsIG1pbm9yIDogdW5pdCAtPiB1bml0ID0gXCJjYW1sX2djX21pbm9yXCJcbmV4dGVybmFsIG1ham9yX3NsaWNlIDogaW50IC0+IGludCA9IFwiY2FtbF9nY19tYWpvcl9zbGljZVwiXG5leHRlcm5hbCBtYWpvciA6IHVuaXQgLT4gdW5pdCA9IFwiY2FtbF9nY19tYWpvclwiXG5leHRlcm5hbCBmdWxsX21ham9yIDogdW5pdCAtPiB1bml0ID0gXCJjYW1sX2djX2Z1bGxfbWFqb3JcIlxuZXh0ZXJuYWwgY29tcGFjdCA6IHVuaXQgLT4gdW5pdCA9IFwiY2FtbF9nY19jb21wYWN0aW9uXCJcbmV4dGVybmFsIGdldF9taW5vcl9mcmVlIDogdW5pdCAtPiBpbnQgPSBcImNhbWxfZ2V0X21pbm9yX2ZyZWVcIlxuZXh0ZXJuYWwgZ2V0X2J1Y2tldCA6IGludCAtPiBpbnQgPSBcImNhbWxfZ2V0X21ham9yX2J1Y2tldFwiIFtAQG5vYWxsb2NdXG5leHRlcm5hbCBnZXRfY3JlZGl0IDogdW5pdCAtPiBpbnQgPSBcImNhbWxfZ2V0X21ham9yX2NyZWRpdFwiIFtAQG5vYWxsb2NdXG5leHRlcm5hbCBodWdlX2ZhbGxiYWNrX2NvdW50IDogdW5pdCAtPiBpbnQgPSBcImNhbWxfZ2NfaHVnZV9mYWxsYmFja19jb3VudFwiXG5leHRlcm5hbCBldmVudGxvZ19wYXVzZSA6IHVuaXQgLT4gdW5pdCA9IFwiY2FtbF9ldmVudGxvZ19wYXVzZVwiXG5leHRlcm5hbCBldmVudGxvZ19yZXN1bWUgOiB1bml0IC0+IHVuaXQgPSBcImNhbWxfZXZlbnRsb2dfcmVzdW1lXCJcblxub3BlbiBQcmludGZcblxubGV0IHByaW50X3N0YXQgYyA9XG4gIGxldCBzdCA9IHN0YXQgKCkgaW5cbiAgZnByaW50ZiBjIFwibWlub3JfY29sbGVjdGlvbnM6ICAgICAgJWRcXG5cIiBzdC5taW5vcl9jb2xsZWN0aW9ucztcbiAgZnByaW50ZiBjIFwibWFqb3JfY29sbGVjdGlvbnM6ICAgICAgJWRcXG5cIiBzdC5tYWpvcl9jb2xsZWN0aW9ucztcbiAgZnByaW50ZiBjIFwiY29tcGFjdGlvbnM6ICAgICAgICAgICAgJWRcXG5cIiBzdC5jb21wYWN0aW9ucztcbiAgZnByaW50ZiBjIFwiZm9yY2VkX21ham9yX2NvbGxlY3Rpb25zOiAlZFxcblwiIHN0LmZvcmNlZF9tYWpvcl9jb2xsZWN0aW9ucztcbiAgZnByaW50ZiBjIFwiXFxuXCI7XG4gIGxldCBsMSA9IFN0cmluZy5sZW5ndGggKHNwcmludGYgXCIlLjBmXCIgc3QubWlub3Jfd29yZHMpIGluXG4gIGZwcmludGYgYyBcIm1pbm9yX3dvcmRzOiAgICAlKi4wZlxcblwiIGwxIHN0Lm1pbm9yX3dvcmRzO1xuICBmcHJpbnRmIGMgXCJwcm9tb3RlZF93b3JkczogJSouMGZcXG5cIiBsMSBzdC5wcm9tb3RlZF93b3JkcztcbiAgZnByaW50ZiBjIFwibWFqb3Jfd29yZHM6ICAgICUqLjBmXFxuXCIgbDEgc3QubWFqb3Jfd29yZHM7XG4gIGZwcmludGYgYyBcIlxcblwiO1xuICBsZXQgbDIgPSBTdHJpbmcubGVuZ3RoIChzcHJpbnRmIFwiJWRcIiBzdC50b3BfaGVhcF93b3JkcykgaW5cbiAgZnByaW50ZiBjIFwidG9wX2hlYXBfd29yZHM6ICUqZFxcblwiIGwyIHN0LnRvcF9oZWFwX3dvcmRzO1xuICBmcHJpbnRmIGMgXCJoZWFwX3dvcmRzOiAgICAgJSpkXFxuXCIgbDIgc3QuaGVhcF93b3JkcztcbiAgZnByaW50ZiBjIFwibGl2ZV93b3JkczogICAgICUqZFxcblwiIGwyIHN0LmxpdmVfd29yZHM7XG4gIGZwcmludGYgYyBcImZyZWVfd29yZHM6ICAgICAlKmRcXG5cIiBsMiBzdC5mcmVlX3dvcmRzO1xuICBmcHJpbnRmIGMgXCJsYXJnZXN0X2ZyZWU6ICAgJSpkXFxuXCIgbDIgc3QubGFyZ2VzdF9mcmVlO1xuICBmcHJpbnRmIGMgXCJmcmFnbWVudHM6ICAgICAgJSpkXFxuXCIgbDIgc3QuZnJhZ21lbnRzO1xuICBmcHJpbnRmIGMgXCJcXG5cIjtcbiAgZnByaW50ZiBjIFwibGl2ZV9ibG9ja3M6ICVkXFxuXCIgc3QubGl2ZV9ibG9ja3M7XG4gIGZwcmludGYgYyBcImZyZWVfYmxvY2tzOiAlZFxcblwiIHN0LmZyZWVfYmxvY2tzO1xuICBmcHJpbnRmIGMgXCJoZWFwX2NodW5rczogJWRcXG5cIiBzdC5oZWFwX2NodW5rc1xuXG5cbmxldCBhbGxvY2F0ZWRfYnl0ZXMgKCkgPVxuICBsZXQgKG1pLCBwcm8sIG1hKSA9IGNvdW50ZXJzICgpIGluXG4gIChtaSArLiBtYSAtLiBwcm8pICouIGZsb2F0X29mX2ludCAoU3lzLndvcmRfc2l6ZSAvIDgpXG5cblxuZXh0ZXJuYWwgZmluYWxpc2UgOiAoJ2EgLT4gdW5pdCkgLT4gJ2EgLT4gdW5pdCA9IFwiY2FtbF9maW5hbF9yZWdpc3RlclwiXG5leHRlcm5hbCBmaW5hbGlzZV9sYXN0IDogKHVuaXQgLT4gdW5pdCkgLT4gJ2EgLT4gdW5pdCA9XG4gIFwiY2FtbF9maW5hbF9yZWdpc3Rlcl9jYWxsZWRfd2l0aG91dF92YWx1ZVwiXG5leHRlcm5hbCBmaW5hbGlzZV9yZWxlYXNlIDogdW5pdCAtPiB1bml0ID0gXCJjYW1sX2ZpbmFsX3JlbGVhc2VcIlxuXG5cbnR5cGUgYWxhcm0gPSBib29sIHJlZlxudHlwZSBhbGFybV9yZWMgPSB7YWN0aXZlIDogYWxhcm07IGYgOiB1bml0IC0+IHVuaXR9XG5cbmxldCByZWMgY2FsbF9hbGFybSBhcmVjID1cbiAgaWYgIShhcmVjLmFjdGl2ZSkgdGhlbiBiZWdpblxuICAgIGZpbmFsaXNlIGNhbGxfYWxhcm0gYXJlYztcbiAgICBhcmVjLmYgKCk7XG4gIGVuZFxuXG5cbmxldCBjcmVhdGVfYWxhcm0gZiA9XG4gIGxldCBhcmVjID0geyBhY3RpdmUgPSByZWYgdHJ1ZTsgZiA9IGYgfSBpblxuICBmaW5hbGlzZSBjYWxsX2FsYXJtIGFyZWM7XG4gIGFyZWMuYWN0aXZlXG5cblxubGV0IGRlbGV0ZV9hbGFybSBhID0gYSA6PSBmYWxzZVxuXG5tb2R1bGUgTWVtcHJvZiA9XG4gIHN0cnVjdFxuICAgIHR5cGUgYWxsb2NhdGlvbl9zb3VyY2UgPSBOb3JtYWwgfCBNYXJzaGFsIHwgQ3VzdG9tXG4gICAgdHlwZSBhbGxvY2F0aW9uID1cbiAgICAgIHsgbl9zYW1wbGVzIDogaW50O1xuICAgICAgICBzaXplIDogaW50O1xuICAgICAgICBzb3VyY2UgOiBhbGxvY2F0aW9uX3NvdXJjZTtcbiAgICAgICAgY2FsbHN0YWNrIDogUHJpbnRleGMucmF3X2JhY2t0cmFjZSB9XG5cbiAgICB0eXBlICgnbWlub3IsICdtYWpvcikgdHJhY2tlciA9IHtcbiAgICAgIGFsbG9jX21pbm9yOiBhbGxvY2F0aW9uIC0+ICdtaW5vciBvcHRpb247XG4gICAgICBhbGxvY19tYWpvcjogYWxsb2NhdGlvbiAtPiAnbWFqb3Igb3B0aW9uO1xuICAgICAgcHJvbW90ZTogJ21pbm9yIC0+ICdtYWpvciBvcHRpb247XG4gICAgICBkZWFsbG9jX21pbm9yOiAnbWlub3IgLT4gdW5pdDtcbiAgICAgIGRlYWxsb2NfbWFqb3I6ICdtYWpvciAtPiB1bml0O1xuICAgIH1cblxuICAgIGxldCBudWxsX3RyYWNrZXIgPSB7XG4gICAgICBhbGxvY19taW5vciA9IChmdW4gXyAtPiBOb25lKTtcbiAgICAgIGFsbG9jX21ham9yID0gKGZ1biBfIC0+IE5vbmUpO1xuICAgICAgcHJvbW90ZSA9IChmdW4gXyAtPiBOb25lKTtcbiAgICAgIGRlYWxsb2NfbWlub3IgPSAoZnVuIF8gLT4gKCkpO1xuICAgICAgZGVhbGxvY19tYWpvciA9IChmdW4gXyAtPiAoKSk7XG4gICAgfVxuXG4gICAgZXh0ZXJuYWwgY19zdGFydCA6XG4gICAgICBmbG9hdCAtPiBpbnQgLT4gKCdtaW5vciwgJ21ham9yKSB0cmFja2VyIC0+IHVuaXRcbiAgICAgID0gXCJjYW1sX21lbXByb2Zfc3RhcnRcIlxuXG4gICAgbGV0IHN0YXJ0XG4gICAgICB+c2FtcGxpbmdfcmF0ZVxuICAgICAgPyhjYWxsc3RhY2tfc2l6ZSA9IG1heF9pbnQpXG4gICAgICB0cmFja2VyID1cbiAgICAgIGNfc3RhcnQgc2FtcGxpbmdfcmF0ZSBjYWxsc3RhY2tfc2l6ZSB0cmFja2VyXG5cbiAgICBleHRlcm5hbCBzdG9wIDogdW5pdCAtPiB1bml0ID0gXCJjYW1sX21lbXByb2Zfc3RvcFwiXG4gIGVuZFxuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgWGF2aWVyIExlcm95LCBwcm9qZXQgQ3Jpc3RhbCwgSU5SSUEgUm9jcXVlbmNvdXJ0ICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMTk5NiBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0ICAgICAqKVxuKCogICAgIGVuIEF1dG9tYXRpcXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG4oKiBNZXNzYWdlIGRpZ2VzdCAoTUQ1KSAqKVxuXG50eXBlIHQgPSBzdHJpbmdcblxubGV0IGNvbXBhcmUgPSBTdHJpbmcuY29tcGFyZVxubGV0IGVxdWFsID0gU3RyaW5nLmVxdWFsXG5cbmV4dGVybmFsIHVuc2FmZV9zdHJpbmc6IHN0cmluZyAtPiBpbnQgLT4gaW50IC0+IHQgPSBcImNhbWxfbWQ1X3N0cmluZ1wiXG5leHRlcm5hbCBjaGFubmVsOiBpbl9jaGFubmVsIC0+IGludCAtPiB0ID0gXCJjYW1sX21kNV9jaGFuXCJcblxubGV0IHN0cmluZyBzdHIgPVxuICB1bnNhZmVfc3RyaW5nIHN0ciAwIChTdHJpbmcubGVuZ3RoIHN0cilcblxubGV0IGJ5dGVzIGIgPSBzdHJpbmcgKEJ5dGVzLnVuc2FmZV90b19zdHJpbmcgYilcblxubGV0IHN1YnN0cmluZyBzdHIgb2ZzIGxlbiA9XG4gIGlmIG9mcyA8IDAgfHwgbGVuIDwgMCB8fCBvZnMgPiBTdHJpbmcubGVuZ3RoIHN0ciAtIGxlblxuICB0aGVuIGludmFsaWRfYXJnIFwiRGlnZXN0LnN1YnN0cmluZ1wiXG4gIGVsc2UgdW5zYWZlX3N0cmluZyBzdHIgb2ZzIGxlblxuXG5sZXQgc3ViYnl0ZXMgYiBvZnMgbGVuID0gc3Vic3RyaW5nIChCeXRlcy51bnNhZmVfdG9fc3RyaW5nIGIpIG9mcyBsZW5cblxubGV0IGZpbGUgZmlsZW5hbWUgPVxuICBsZXQgaWMgPSBvcGVuX2luX2JpbiBmaWxlbmFtZSBpblxuICBtYXRjaCBjaGFubmVsIGljICgtMSkgd2l0aFxuICAgIHwgZCAtPiBjbG9zZV9pbiBpYzsgZFxuICAgIHwgZXhjZXB0aW9uIGUgLT4gY2xvc2VfaW4gaWM7IHJhaXNlIGVcblxubGV0IG91dHB1dCBjaGFuIGRpZ2VzdCA9XG4gIG91dHB1dF9zdHJpbmcgY2hhbiBkaWdlc3RcblxubGV0IGlucHV0IGNoYW4gPSByZWFsbHlfaW5wdXRfc3RyaW5nIGNoYW4gMTZcblxubGV0IGNoYXJfaGV4IG4gPVxuICBDaGFyLnVuc2FmZV9jaHIgKG4gKyBpZiBuIDwgMTAgdGhlbiBDaGFyLmNvZGUgJzAnIGVsc2UgKENoYXIuY29kZSAnYScgLSAxMCkpXG5cbmxldCB0b19oZXggZCA9XG4gIGlmIFN0cmluZy5sZW5ndGggZCA8PiAxNiB0aGVuIGludmFsaWRfYXJnIFwiRGlnZXN0LnRvX2hleFwiO1xuICBsZXQgcmVzdWx0ID0gQnl0ZXMuY3JlYXRlIDMyIGluXG4gIGZvciBpID0gMCB0byAxNSBkb1xuICAgIGxldCB4ID0gQ2hhci5jb2RlIGQuW2ldIGluXG4gICAgQnl0ZXMudW5zYWZlX3NldCByZXN1bHQgKGkqMikgKGNoYXJfaGV4ICh4IGxzciA0KSk7XG4gICAgQnl0ZXMudW5zYWZlX3NldCByZXN1bHQgKGkqMisxKSAoY2hhcl9oZXggKHggbGFuZCAweDBmKSk7XG4gIGRvbmU7XG4gIEJ5dGVzLnVuc2FmZV90b19zdHJpbmcgcmVzdWx0XG5cbmxldCBmcm9tX2hleCBzID1cbiAgaWYgU3RyaW5nLmxlbmd0aCBzIDw+IDMyIHRoZW4gaW52YWxpZF9hcmcgXCJEaWdlc3QuZnJvbV9oZXhcIjtcbiAgbGV0IGRpZ2l0IGMgPVxuICAgIG1hdGNoIGMgd2l0aFxuICAgIHwgJzAnLi4nOScgLT4gQ2hhci5jb2RlIGMgLSBDaGFyLmNvZGUgJzAnXG4gICAgfCAnQScuLidGJyAtPiBDaGFyLmNvZGUgYyAtIENoYXIuY29kZSAnQScgKyAxMFxuICAgIHwgJ2EnLi4nZicgLT4gQ2hhci5jb2RlIGMgLSBDaGFyLmNvZGUgJ2EnICsgMTBcbiAgICB8IF8gLT4gcmFpc2UgKEludmFsaWRfYXJndW1lbnQgXCJEaWdlc3QuZnJvbV9oZXhcIilcbiAgaW5cbiAgbGV0IGJ5dGUgaSA9IGRpZ2l0IHMuW2ldIGxzbCA0ICsgZGlnaXQgcy5baSsxXSBpblxuICBsZXQgcmVzdWx0ID0gQnl0ZXMuY3JlYXRlIDE2IGluXG4gIGZvciBpID0gMCB0byAxNSBkb1xuICAgIEJ5dGVzLnNldCByZXN1bHQgaSAoQ2hhci5jaHIgKGJ5dGUgKDIgKiBpKSkpO1xuICBkb25lO1xuICBCeXRlcy51bnNhZmVfdG9fc3RyaW5nIHJlc3VsdFxuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICBEYW1pZW4gRG9saWdleiwgcHJvamV0IFBhcmEsIElOUklBIFJvY3F1ZW5jb3VydCAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMTk5NiBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0ICAgICAqKVxuKCogICAgIGVuIEF1dG9tYXRpcXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG4oKiBQc2V1ZG8tcmFuZG9tIG51bWJlciBnZW5lcmF0b3JcbiAgIFRoaXMgaXMgYSBsYWdnZWQtRmlib25hY2NpIEYoNTUsIDI0LCArKSB3aXRoIGEgbW9kaWZpZWQgYWRkaXRpb25cbiAgIGZ1bmN0aW9uIHRvIGVuaGFuY2UgdGhlIG1peGluZyBvZiBiaXRzLlxuICAgSWYgd2UgdXNlIG5vcm1hbCBhZGRpdGlvbiwgdGhlIGxvdy1vcmRlciBiaXQgZmFpbHMgdGVzdHMgMSBhbmQgN1xuICAgb2YgdGhlIERpZWhhcmQgdGVzdCBzdWl0ZSwgYW5kIGJpdHMgMSBhbmQgMiBhbHNvIGZhaWwgdGVzdCA3LlxuICAgSWYgd2UgdXNlIG11bHRpcGxpY2F0aW9uIGFzIHN1Z2dlc3RlZCBieSBNYXJzYWdsaWEsIGl0IGRvZXNuJ3QgZmFyZVxuICAgbXVjaCBiZXR0ZXIuXG4gICBCeSBtaXhpbmcgdGhlIGJpdHMgb2Ygb25lIG9mIHRoZSBudW1iZXJzIGJlZm9yZSBhZGRpdGlvbiAoWE9SIHRoZVxuICAgNSBoaWdoLW9yZGVyIGJpdHMgaW50byB0aGUgbG93LW9yZGVyIGJpdHMpLCB3ZSBnZXQgYSBnZW5lcmF0b3IgdGhhdFxuICAgcGFzc2VzIGFsbCB0aGUgRGllaGFyZCB0ZXN0cy5cbiopXG5cbmV4dGVybmFsIHJhbmRvbV9zZWVkOiB1bml0IC0+IGludCBhcnJheSA9IFwiY2FtbF9zeXNfcmFuZG9tX3NlZWRcIlxuXG5tb2R1bGUgU3RhdGUgPSBzdHJ1Y3RcblxuICB0eXBlIHQgPSB7IHN0IDogaW50IGFycmF5OyBtdXRhYmxlIGlkeCA6IGludCB9XG5cbiAgbGV0IG5ld19zdGF0ZSAoKSA9IHsgc3QgPSBBcnJheS5tYWtlIDU1IDA7IGlkeCA9IDAgfVxuICBsZXQgYXNzaWduIHN0MSBzdDIgPVxuICAgIEFycmF5LmJsaXQgc3QyLnN0IDAgc3QxLnN0IDAgNTU7XG4gICAgc3QxLmlkeCA8LSBzdDIuaWR4XG5cblxuICBsZXQgZnVsbF9pbml0IHMgc2VlZCA9XG4gICAgbGV0IGNvbWJpbmUgYWNjdSB4ID0gRGlnZXN0LnN0cmluZyAoYWNjdSBeIEludC50b19zdHJpbmcgeCkgaW5cbiAgICBsZXQgZXh0cmFjdCBkID1cbiAgICAgIENoYXIuY29kZSBkLlswXSArIChDaGFyLmNvZGUgZC5bMV0gbHNsIDgpICsgKENoYXIuY29kZSBkLlsyXSBsc2wgMTYpXG4gICAgICArIChDaGFyLmNvZGUgZC5bM10gbHNsIDI0KVxuICAgIGluXG4gICAgbGV0IHNlZWQgPSBpZiBBcnJheS5sZW5ndGggc2VlZCA9IDAgdGhlbiBbfCAwIHxdIGVsc2Ugc2VlZCBpblxuICAgIGxldCBsID0gQXJyYXkubGVuZ3RoIHNlZWQgaW5cbiAgICBmb3IgaSA9IDAgdG8gNTQgZG9cbiAgICAgIHMuc3QuKGkpIDwtIGk7XG4gICAgZG9uZTtcbiAgICBsZXQgYWNjdSA9IHJlZiBcInhcIiBpblxuICAgIGZvciBpID0gMCB0byA1NCArIEludC5tYXggNTUgbCBkb1xuICAgICAgbGV0IGogPSBpIG1vZCA1NSBpblxuICAgICAgbGV0IGsgPSBpIG1vZCBsIGluXG4gICAgICBhY2N1IDo9IGNvbWJpbmUgIWFjY3Ugc2VlZC4oayk7XG4gICAgICBzLnN0LihqKSA8LSAocy5zdC4oaikgbHhvciBleHRyYWN0ICFhY2N1KSBsYW5kIDB4M0ZGRkZGRkY7ICAoKiBQUiM1NTc1ICopXG4gICAgZG9uZTtcbiAgICBzLmlkeCA8LSAwXG5cblxuICBsZXQgbWFrZSBzZWVkID1cbiAgICBsZXQgcmVzdWx0ID0gbmV3X3N0YXRlICgpIGluXG4gICAgZnVsbF9pbml0IHJlc3VsdCBzZWVkO1xuICAgIHJlc3VsdFxuXG5cbiAgbGV0IG1ha2Vfc2VsZl9pbml0ICgpID0gbWFrZSAocmFuZG9tX3NlZWQgKCkpXG5cbiAgbGV0IGNvcHkgcyA9XG4gICAgbGV0IHJlc3VsdCA9IG5ld19zdGF0ZSAoKSBpblxuICAgIGFzc2lnbiByZXN1bHQgcztcbiAgICByZXN1bHRcblxuXG4gICgqIFJldHVybnMgMzAgcmFuZG9tIGJpdHMgYXMgYW4gaW50ZWdlciAwIDw9IHggPCAxMDczNzQxODI0ICopXG4gIGxldCBiaXRzIHMgPVxuICAgIHMuaWR4IDwtIChzLmlkeCArIDEpIG1vZCA1NTtcbiAgICBsZXQgY3VydmFsID0gcy5zdC4ocy5pZHgpIGluXG4gICAgbGV0IG5ld3ZhbCA9IHMuc3QuKChzLmlkeCArIDI0KSBtb2QgNTUpXG4gICAgICAgICAgICAgICAgICsgKGN1cnZhbCBseG9yICgoY3VydmFsIGxzciAyNSkgbGFuZCAweDFGKSkgaW5cbiAgICBsZXQgbmV3dmFsMzAgPSBuZXd2YWwgbGFuZCAweDNGRkZGRkZGIGluICAoKiBQUiM1NTc1ICopXG4gICAgcy5zdC4ocy5pZHgpIDwtIG5ld3ZhbDMwO1xuICAgIG5ld3ZhbDMwXG5cblxuICBsZXQgcmVjIGludGF1eCBzIG4gPVxuICAgIGxldCByID0gYml0cyBzIGluXG4gICAgbGV0IHYgPSByIG1vZCBuIGluXG4gICAgaWYgciAtIHYgPiAweDNGRkZGRkZGIC0gbiArIDEgdGhlbiBpbnRhdXggcyBuIGVsc2UgdlxuXG4gIGxldCBpbnQgcyBib3VuZCA9XG4gICAgaWYgYm91bmQgPiAweDNGRkZGRkZGIHx8IGJvdW5kIDw9IDBcbiAgICB0aGVuIGludmFsaWRfYXJnIFwiUmFuZG9tLmludFwiXG4gICAgZWxzZSBpbnRhdXggcyBib3VuZFxuXG4gIGxldCByZWMgaW50NjNhdXggcyBuID1cbiAgICBsZXQgbWF4X2ludF8zMiA9ICgxIGxzbCAzMCkgKyAweDNGRkZGRkZGIGluICgqIDB4N0ZGRkZGRkYgKilcbiAgICBsZXQgYjEgPSBiaXRzIHMgaW5cbiAgICBsZXQgYjIgPSBiaXRzIHMgaW5cbiAgICBsZXQgKHIsIG1heF9pbnQpID1cbiAgICAgIGlmIG4gPD0gbWF4X2ludF8zMiB0aGVuXG4gICAgICAgICgqIDMxIHJhbmRvbSBiaXRzIG9uIGJvdGggNjQtYml0IE9DYW1sIGFuZCBKYXZhU2NyaXB0LlxuICAgICAgICAgICBVc2UgdXBwZXIgMTUgYml0cyBvZiBiMSBhbmQgMTYgYml0cyBvZiBiMi4gKilcbiAgICAgICAgbGV0IGJwb3MgPVxuICAgICAgICAgICgoKGIyIGxhbmQgMHgzRkZGQzAwMCkgbHNsIDEpIGxvciAoYjEgbHNyIDE1KSlcbiAgICAgICAgaW5cbiAgICAgICAgICAoYnBvcywgbWF4X2ludF8zMilcbiAgICAgIGVsc2VcbiAgICAgICAgbGV0IGIzID0gYml0cyBzIGluXG4gICAgICAgICgqIDYyIHJhbmRvbSBiaXRzIG9uIDY0LWJpdCBPQ2FtbDsgdW5yZWFjaGFibGUgb24gSmF2YVNjcmlwdC5cbiAgICAgICAgICAgVXNlIHVwcGVyIDIwIGJpdHMgb2YgYjEgYW5kIDIxIGJpdHMgb2YgYjIgYW5kIGIzLiAqKVxuICAgICAgICBsZXQgYnBvcyA9XG4gICAgICAgICAgKCgoKGIzIGxhbmQgMHgzRkZGRkUwMCkgbHNsIDEyKSBsb3IgKGIyIGxzciA5KSkgbHNsIDIwKVxuICAgICAgICAgICAgbG9yIChiMSBsc3IgMTApXG4gICAgICAgIGluXG4gICAgICAgICAgKGJwb3MsIG1heF9pbnQpXG4gICAgaW5cbiAgICBsZXQgdiA9IHIgbW9kIG4gaW5cbiAgICBpZiByIC0gdiA+IG1heF9pbnQgLSBuICsgMSB0aGVuIGludDYzYXV4IHMgbiBlbHNlIHZcblxuICBsZXQgZnVsbF9pbnQgcyBib3VuZCA9XG4gICAgaWYgYm91bmQgPD0gMCB0aGVuXG4gICAgICBpbnZhbGlkX2FyZyBcIlJhbmRvbS5mdWxsX2ludFwiXG4gICAgZWxzZSBpZiBib3VuZCA+IDB4M0ZGRkZGRkYgdGhlblxuICAgICAgaW50NjNhdXggcyBib3VuZFxuICAgIGVsc2VcbiAgICAgIGludGF1eCBzIGJvdW5kXG5cblxuICBsZXQgcmVjIGludDMyYXV4IHMgbiA9XG4gICAgbGV0IGIxID0gSW50MzIub2ZfaW50IChiaXRzIHMpIGluXG4gICAgbGV0IGIyID0gSW50MzIuc2hpZnRfbGVmdCAoSW50MzIub2ZfaW50IChiaXRzIHMgbGFuZCAxKSkgMzAgaW5cbiAgICBsZXQgciA9IEludDMyLmxvZ29yIGIxIGIyIGluXG4gICAgbGV0IHYgPSBJbnQzMi5yZW0gciBuIGluXG4gICAgaWYgSW50MzIuc3ViIHIgdiA+IEludDMyLmFkZCAoSW50MzIuc3ViIEludDMyLm1heF9pbnQgbikgMWxcbiAgICB0aGVuIGludDMyYXV4IHMgblxuICAgIGVsc2UgdlxuXG4gIGxldCBpbnQzMiBzIGJvdW5kID1cbiAgICBpZiBib3VuZCA8PSAwbFxuICAgIHRoZW4gaW52YWxpZF9hcmcgXCJSYW5kb20uaW50MzJcIlxuICAgIGVsc2UgaW50MzJhdXggcyBib3VuZFxuXG5cbiAgbGV0IHJlYyBpbnQ2NGF1eCBzIG4gPVxuICAgIGxldCBiMSA9IEludDY0Lm9mX2ludCAoYml0cyBzKSBpblxuICAgIGxldCBiMiA9IEludDY0LnNoaWZ0X2xlZnQgKEludDY0Lm9mX2ludCAoYml0cyBzKSkgMzAgaW5cbiAgICBsZXQgYjMgPSBJbnQ2NC5zaGlmdF9sZWZ0IChJbnQ2NC5vZl9pbnQgKGJpdHMgcyBsYW5kIDcpKSA2MCBpblxuICAgIGxldCByID0gSW50NjQubG9nb3IgYjEgKEludDY0LmxvZ29yIGIyIGIzKSBpblxuICAgIGxldCB2ID0gSW50NjQucmVtIHIgbiBpblxuICAgIGlmIEludDY0LnN1YiByIHYgPiBJbnQ2NC5hZGQgKEludDY0LnN1YiBJbnQ2NC5tYXhfaW50IG4pIDFMXG4gICAgdGhlbiBpbnQ2NGF1eCBzIG5cbiAgICBlbHNlIHZcblxuICBsZXQgaW50NjQgcyBib3VuZCA9XG4gICAgaWYgYm91bmQgPD0gMExcbiAgICB0aGVuIGludmFsaWRfYXJnIFwiUmFuZG9tLmludDY0XCJcbiAgICBlbHNlIGludDY0YXV4IHMgYm91bmRcblxuXG4gIGxldCBuYXRpdmVpbnQgPVxuICAgIGlmIE5hdGl2ZWludC5zaXplID0gMzJcbiAgICB0aGVuIGZ1biBzIGJvdW5kIC0+IE5hdGl2ZWludC5vZl9pbnQzMiAoaW50MzIgcyAoTmF0aXZlaW50LnRvX2ludDMyIGJvdW5kKSlcbiAgICBlbHNlIGZ1biBzIGJvdW5kIC0+IEludDY0LnRvX25hdGl2ZWludCAoaW50NjQgcyAoSW50NjQub2ZfbmF0aXZlaW50IGJvdW5kKSlcblxuXG4gICgqIFJldHVybnMgYSBmbG9hdCAwIDw9IHggPD0gMSB3aXRoIGF0IG1vc3QgNjAgYml0cyBvZiBwcmVjaXNpb24uICopXG4gIGxldCByYXdmbG9hdCBzID1cbiAgICBsZXQgc2NhbGUgPSAxMDczNzQxODI0LjAgICgqIDJeMzAgKilcbiAgICBhbmQgcjEgPSBTdGRsaWIuZmxvYXQgKGJpdHMgcylcbiAgICBhbmQgcjIgPSBTdGRsaWIuZmxvYXQgKGJpdHMgcylcbiAgICBpbiAocjEgLy4gc2NhbGUgKy4gcjIpIC8uIHNjYWxlXG5cblxuICBsZXQgZmxvYXQgcyBib3VuZCA9IHJhd2Zsb2F0IHMgKi4gYm91bmRcblxuICBsZXQgYm9vbCBzID0gKGJpdHMgcyBsYW5kIDEgPSAwKVxuXG5lbmRcblxuKCogVGhpcyBpcyB0aGUgc3RhdGUgeW91IGdldCB3aXRoIFtpbml0IDI3MTgyODE4XSBhbmQgdGhlbiBhcHBseWluZ1xuICAgdGhlIFwibGFuZCAweDNGRkZGRkZGXCIgZmlsdGVyIHRvIHRoZW0uICBTZWUgIzU1NzUsICM1NzkzLCAjNTk3Ny4gKilcbmxldCBkZWZhdWx0ID0ge1xuICBTdGF0ZS5zdCA9IFt8XG4gICAgICAweDNhZTI1MjJiOyAweDFkOGQ0NjM0OyAweDE1YjRmYWQwOyAweDE4YjE0YWNlOyAweDEyZjhhM2M0OyAweDNiMDg2YzQ3O1xuICAgICAgMHgxNmQ0NjdkNjsgMHgxMDFkOTFjNzsgMHgzMjFkZjE3NzsgMHgwMTc2YzE5MzsgMHgxZmY3MmJmMTsgMHgxZTg4OTEwOTtcbiAgICAgIDB4MGI0NjRiMTg7IDB4MmI4NmI5N2M7IDB4MDg5MWRhNDg7IDB4MDMxMzc0NjM7IDB4MDg1YWM1YTE7IDB4MTVkNjFmMmY7XG4gICAgICAweDNiY2VkMzU5OyAweDI5YzFjMTMyOyAweDNhODY3NjZlOyAweDM2NmQ4Yzg2OyAweDFmNWI2MjIyOyAweDNjZTFiNTlmO1xuICAgICAgMHgyZWJmNzhlMTsgMHgyN2NkMWI4NjsgMHgyNThmM2RjMzsgMHgzODlhODE5NDsgMHgwMmU0YzQ0YzsgMHgxOGM0M2Y3ZDtcbiAgICAgIDB4MGY2ZTUzNGY7IDB4MWU3ZGYzNTk7IDB4MDU1ZDBiN2U7IDB4MTBlODRlN2U7IDB4MTI2MTk4ZTQ7IDB4MGU3NzIyY2I7XG4gICAgICAweDFjYmVkZTI4OyAweDMzOTFiOTY0OyAweDNkNDBlOTJhOyAweDBjNTk5MzNkOyAweDBiOGNkMGI3OyAweDI0ZWZmZjFjO1xuICAgICAgMHgyODAzZmRhYTsgMHgwOGViYzcyZTsgMHgwZjUyMmUzMjsgMHgwNTM5OGVkYzsgMHgyMTQ0YTA0YzsgMHgwYWVmM2NiZDtcbiAgICAgIDB4MDFhZDQ3MTk7IDB4MzViOTNjZDY7IDB4MmE1NTlkNGY7IDB4MWU2ZmQ3Njg7IDB4MjZlMjdmMzY7IDB4MTg2ZjE4YzM7XG4gICAgICAweDJmYmY5NjdhO1xuICAgIHxdO1xuICBTdGF0ZS5pZHggPSAwO1xufVxuXG5sZXQgYml0cyAoKSA9IFN0YXRlLmJpdHMgZGVmYXVsdFxubGV0IGludCBib3VuZCA9IFN0YXRlLmludCBkZWZhdWx0IGJvdW5kXG5sZXQgZnVsbF9pbnQgYm91bmQgPSBTdGF0ZS5mdWxsX2ludCBkZWZhdWx0IGJvdW5kXG5sZXQgaW50MzIgYm91bmQgPSBTdGF0ZS5pbnQzMiBkZWZhdWx0IGJvdW5kXG5sZXQgbmF0aXZlaW50IGJvdW5kID0gU3RhdGUubmF0aXZlaW50IGRlZmF1bHQgYm91bmRcbmxldCBpbnQ2NCBib3VuZCA9IFN0YXRlLmludDY0IGRlZmF1bHQgYm91bmRcbmxldCBmbG9hdCBzY2FsZSA9IFN0YXRlLmZsb2F0IGRlZmF1bHQgc2NhbGVcbmxldCBib29sICgpID0gU3RhdGUuYm9vbCBkZWZhdWx0XG5cbmxldCBmdWxsX2luaXQgc2VlZCA9IFN0YXRlLmZ1bGxfaW5pdCBkZWZhdWx0IHNlZWRcbmxldCBpbml0IHNlZWQgPSBTdGF0ZS5mdWxsX2luaXQgZGVmYXVsdCBbfCBzZWVkIHxdXG5sZXQgc2VsZl9pbml0ICgpID0gZnVsbF9pbml0IChyYW5kb21fc2VlZCgpKVxuXG4oKiBNYW5pcHVsYXRpbmcgdGhlIGN1cnJlbnQgc3RhdGUuICopXG5cbmxldCBnZXRfc3RhdGUgKCkgPSBTdGF0ZS5jb3B5IGRlZmF1bHRcbmxldCBzZXRfc3RhdGUgcyA9IFN0YXRlLmFzc2lnbiBkZWZhdWx0IHNcblxuKCoqKioqKioqKioqKioqKioqKioqXG5cbigqIFRlc3QgZnVuY3Rpb25zLiAgTm90IGluY2x1ZGVkIGluIHRoZSBsaWJyYXJ5LlxuICAgVGhlIFtjaGlzcXVhcmVdIGZ1bmN0aW9uIHNob3VsZCBiZSBjYWxsZWQgd2l0aCBuID4gMTByLlxuICAgSXQgcmV0dXJucyBhIHRyaXBsZSAobG93LCBhY3R1YWwsIGhpZ2gpLlxuICAgSWYgbG93IDw9IGFjdHVhbCA8PSBoaWdoLCB0aGUgW2ddIGZ1bmN0aW9uIHBhc3NlZCB0aGUgdGVzdCxcbiAgIG90aGVyd2lzZSBpdCBmYWlsZWQuXG5cbiAgU29tZSByZXN1bHRzOlxuXG5pbml0IDI3MTgyODE4OyBjaGlzcXVhcmUgaW50IDEwMDAwMCAxMDAwXG5pbml0IDI3MTgyODE4OyBjaGlzcXVhcmUgaW50IDEwMDAwMCAxMDBcbmluaXQgMjcxODI4MTg7IGNoaXNxdWFyZSBpbnQgMTAwMDAwIDUwMDBcbmluaXQgMjcxODI4MTg7IGNoaXNxdWFyZSBpbnQgMTAwMDAwMCAxMDAwXG5pbml0IDI3MTgyODE4OyBjaGlzcXVhcmUgaW50IDEwMDAwMCAxMDI0XG5pbml0IDI5OTc5MjY0MzsgY2hpc3F1YXJlIGludCAxMDAwMDAgMTAyNFxuaW5pdCAxNDE0MjEzNjsgY2hpc3F1YXJlIGludCAxMDAwMDAgMTAyNFxuaW5pdCAyNzE4MjgxODsgaW5pdF9kaWZmIDEwMjQ7IGNoaXNxdWFyZSBkaWZmIDEwMDAwMCAxMDI0XG5pbml0IDI3MTgyODE4OyBpbml0X2RpZmYgMTAwOyBjaGlzcXVhcmUgZGlmZiAxMDAwMDAgMTAwXG5pbml0IDI3MTgyODE4OyBpbml0X2RpZmYyIDEwMjQ7IGNoaXNxdWFyZSBkaWZmMiAxMDAwMDAgMTAyNFxuaW5pdCAyNzE4MjgxODsgaW5pdF9kaWZmMiAxMDA7IGNoaXNxdWFyZSBkaWZmMiAxMDAwMDAgMTAwXG5pbml0IDE0MTQyMTM2OyBpbml0X2RpZmYyIDEwMDsgY2hpc3F1YXJlIGRpZmYyIDEwMDAwMCAxMDBcbmluaXQgMjk5NzkyNjQzOyBpbml0X2RpZmYyIDEwMDsgY2hpc3F1YXJlIGRpZmYyIDEwMDAwMCAxMDBcbi0gOiBmbG9hdCAqIGZsb2F0ICogZmxvYXQgPSAoOTM2Ljc1NDQ0Njc5NjYzMjQ2NSwgOTk3LjUsIDEwNjMuMjQ1NTUzMjAzMzY3NTQpXG4jIC0gOiBmbG9hdCAqIGZsb2F0ICogZmxvYXQgPSAoODAuLCA4OS43NDAwMDAwMDAwMDUyMzg3LCAxMjAuKVxuIyAtIDogZmxvYXQgKiBmbG9hdCAqIGZsb2F0ID0gKDQ4NTguNTc4NjQzNzYyNjksIDUwNDUuNSwgNTE0MS40MjEzNTYyMzczMSlcbiMgLSA6IGZsb2F0ICogZmxvYXQgKiBmbG9hdCA9XG4oOTM2Ljc1NDQ0Njc5NjYzMjQ2NSwgOTQ0LjgwNTk5OTk5OTk4MjMwNSwgMTA2My4yNDU1NTMyMDMzNjc1NClcbiMgLSA6IGZsb2F0ICogZmxvYXQgKiBmbG9hdCA9ICg5NjAuLCAxMDE5LjE5NzQ0MDAwMDAwMzU1LCAxMDg4LilcbiMgLSA6IGZsb2F0ICogZmxvYXQgKiBmbG9hdCA9ICg5NjAuLCAxMDU5LjMxNzc2MDAwMDAwNTM2LCAxMDg4LilcbiMgLSA6IGZsb2F0ICogZmxvYXQgKiBmbG9hdCA9ICg5NjAuLCAxMDM5Ljk4NDYzOTk5OTk5NTEyLCAxMDg4LilcbiMgLSA6IGZsb2F0ICogZmxvYXQgKiBmbG9hdCA9ICg5NjAuLCAxMDU0LjM4MjA3OTk5OTk5NTc3LCAxMDg4LilcbiMgLSA6IGZsb2F0ICogZmxvYXQgKiBmbG9hdCA9ICg4MC4sIDkwLjA5NjAwMDAwMDAwNSwgMTIwLilcbiMgLSA6IGZsb2F0ICogZmxvYXQgKiBmbG9hdCA9ICg5NjAuLCAxMDc2Ljc4NzIwMDAwMDAwNjEyLCAxMDg4LilcbiMgLSA6IGZsb2F0ICogZmxvYXQgKiBmbG9hdCA9ICg4MC4sIDg1LjE3NjAwMDAwMDAwNjc1MjEsIDEyMC4pXG4jIC0gOiBmbG9hdCAqIGZsb2F0ICogZmxvYXQgPSAoODAuLCA4NS4yMTYwMDAwMDAwMDAzNDkyLCAxMjAuKVxuIyAtIDogZmxvYXQgKiBmbG9hdCAqIGZsb2F0ID0gKDgwLiwgODAuNjIyMDAwMDAwMDAzMDI2OCwgMTIwLilcblxuKilcblxuKCogUmV0dXJuIHRoZSBzdW0gb2YgdGhlIHNxdWFyZXMgb2YgdltpMCxpMVsgKilcbmxldCByZWMgc3Vtc3EgdiBpMCBpMSA9XG4gIGlmIGkwID49IGkxIHRoZW4gMC4wXG4gIGVsc2UgaWYgaTEgPSBpMCArIDEgdGhlbiBTdGRsaWIuZmxvYXQgdi4oaTApICouIFN0ZGxpYi5mbG9hdCB2LihpMClcbiAgZWxzZSBzdW1zcSB2IGkwICgoaTAraTEpLzIpICsuIHN1bXNxIHYgKChpMCtpMSkvMikgaTFcblxuXG5sZXQgY2hpc3F1YXJlIGcgbiByID1cbiAgaWYgbiA8PSAxMCAqIHIgdGhlbiBpbnZhbGlkX2FyZyBcImNoaXNxdWFyZVwiO1xuICBsZXQgZiA9IEFycmF5Lm1ha2UgciAwIGluXG4gIGZvciBpID0gMSB0byBuIGRvXG4gICAgbGV0IHQgPSBnIHIgaW5cbiAgICBmLih0KSA8LSBmLih0KSArIDFcbiAgZG9uZTtcbiAgbGV0IHQgPSBzdW1zcSBmIDAgclxuICBhbmQgciA9IFN0ZGxpYi5mbG9hdCByXG4gIGFuZCBuID0gU3RkbGliLmZsb2F0IG4gaW5cbiAgbGV0IHNyID0gMi4wICouIHNxcnQgciBpblxuICAociAtLiBzciwgICAociAqLiB0IC8uIG4pIC0uIG4sICAgciArLiBzcilcblxuXG4oKiBUaGlzIGlzIHRvIHRlc3QgZm9yIGxpbmVhciBkZXBlbmRlbmNpZXMgYmV0d2VlbiBzdWNjZXNzaXZlIHJhbmRvbSBudW1iZXJzLlxuKilcbmxldCBzdCA9IHJlZiAwXG5sZXQgaW5pdF9kaWZmIHIgPSBzdCA6PSBpbnQgclxubGV0IGRpZmYgciA9XG4gIGxldCB4MSA9ICFzdFxuICBhbmQgeDIgPSBpbnQgclxuICBpblxuICBzdCA6PSB4MjtcbiAgaWYgeDEgPj0geDIgdGhlblxuICAgIHgxIC0geDJcbiAgZWxzZVxuICAgIHIgKyB4MSAtIHgyXG5cblxubGV0IHN0MSA9IHJlZiAwXG5hbmQgc3QyID0gcmVmIDBcblxuXG4oKiBUaGlzIGlzIHRvIHRlc3QgZm9yIHF1YWRyYXRpYyBkZXBlbmRlbmNpZXMgYmV0d2VlbiBzdWNjZXNzaXZlIHJhbmRvbVxuICAgbnVtYmVycy5cbiopXG5sZXQgaW5pdF9kaWZmMiByID0gc3QxIDo9IGludCByOyBzdDIgOj0gaW50IHJcbmxldCBkaWZmMiByID1cbiAgbGV0IHgxID0gIXN0MVxuICBhbmQgeDIgPSAhc3QyXG4gIGFuZCB4MyA9IGludCByXG4gIGluXG4gIHN0MSA6PSB4MjtcbiAgc3QyIDo9IHgzO1xuICAoeDMgLSB4MiAtIHgyICsgeDEgKyAyKnIpIG1vZCByXG5cblxuKioqKioqKioqKioqKioqKioqKiopXG4iLCIoKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9DYW1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICBYYXZpZXIgTGVyb3ksIHByb2pldCBDcmlzdGFsLCBJTlJJQSBSb2NxdWVuY291cnQgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIENvcHlyaWdodCAxOTk2IEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgICAgICopXG4oKiAgICAgZW4gQXV0b21hdGlxdWUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIEFsbCByaWdodHMgcmVzZXJ2ZWQuICBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mICAgICopXG4oKiAgIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyLjEsIHdpdGggdGhlICAgICAgICAgICopXG4oKiAgIHNwZWNpYWwgZXhjZXB0aW9uIG9uIGxpbmtpbmcgZGVzY3JpYmVkIGluIHRoZSBmaWxlIExJQ0VOU0UuICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG5cbigqIEhhc2ggdGFibGVzICopXG5cbigqIFdlIGRvIGR5bmFtaWMgaGFzaGluZywgYW5kIHJlc2l6ZSB0aGUgdGFibGUgYW5kIHJlaGFzaCB0aGUgZWxlbWVudHNcbiAgIHdoZW4gYnVja2V0cyBiZWNvbWUgdG9vIGxvbmcuICopXG5cbnR5cGUgKCdhLCAnYikgdCA9XG4gIHsgbXV0YWJsZSBzaXplOiBpbnQ7ICAgICAgICAgICAgICAgICAgICAgICAgKCogbnVtYmVyIG9mIGVudHJpZXMgKilcbiAgICBtdXRhYmxlIGRhdGE6ICgnYSwgJ2IpIGJ1Y2tldGxpc3QgYXJyYXk7ICAoKiB0aGUgYnVja2V0cyAqKVxuICAgIHNlZWQ6IGludDsgICAgICAgICAgICAgICAgICAgICAgICAoKiBmb3IgcmFuZG9taXphdGlvbiAqKVxuICAgIG11dGFibGUgaW5pdGlhbF9zaXplOiBpbnQ7ICAgICAgICAgICAgICAgICgqIGluaXRpYWwgYXJyYXkgc2l6ZSAqKVxuICB9XG5cbmFuZCAoJ2EsICdiKSBidWNrZXRsaXN0ID1cbiAgICBFbXB0eVxuICB8IENvbnMgb2YgeyBtdXRhYmxlIGtleTogJ2E7XG4gICAgICAgICAgICAgIG11dGFibGUgZGF0YTogJ2I7XG4gICAgICAgICAgICAgIG11dGFibGUgbmV4dDogKCdhLCAnYikgYnVja2V0bGlzdCB9XG5cbigqIFRoZSBzaWduIG9mIGluaXRpYWxfc2l6ZSBlbmNvZGVzIHRoZSBmYWN0IHRoYXQgYSB0cmF2ZXJzYWwgaXNcbiAgIG9uZ29pbmcgb3Igbm90LlxuXG4gICBUaGlzIGRpc2FibGVzIHRoZSBlZmZpY2llbnQgaW4gcGxhY2UgaW1wbGVtZW50YXRpb24gb2YgcmVzaXppbmcuXG4qKVxuXG5sZXQgb25nb2luZ190cmF2ZXJzYWwgaCA9XG4gIE9iai5zaXplIChPYmoucmVwciBoKSA8IDQgKCogY29tcGF0aWJpbGl0eSB3aXRoIG9sZCBoYXNoIHRhYmxlcyAqKVxuICB8fCBoLmluaXRpYWxfc2l6ZSA8IDBcblxubGV0IGZsaXBfb25nb2luZ190cmF2ZXJzYWwgaCA9XG4gIGguaW5pdGlhbF9zaXplIDwtIC0gaC5pbml0aWFsX3NpemVcblxuKCogVG8gcGljayByYW5kb20gc2VlZHMgaWYgcmVxdWVzdGVkICopXG5cbmxldCByYW5kb21pemVkX2RlZmF1bHQgPVxuICBsZXQgcGFyYW1zID1cbiAgICB0cnkgU3lzLmdldGVudiBcIk9DQU1MUlVOUEFSQU1cIiB3aXRoIE5vdF9mb3VuZCAtPlxuICAgIHRyeSBTeXMuZ2V0ZW52IFwiQ0FNTFJVTlBBUkFNXCIgd2l0aCBOb3RfZm91bmQgLT4gXCJcIiBpblxuICBTdHJpbmcuY29udGFpbnMgcGFyYW1zICdSJ1xuXG5sZXQgcmFuZG9taXplZCA9IHJlZiByYW5kb21pemVkX2RlZmF1bHRcblxubGV0IHJhbmRvbWl6ZSAoKSA9IHJhbmRvbWl6ZWQgOj0gdHJ1ZVxubGV0IGlzX3JhbmRvbWl6ZWQgKCkgPSAhcmFuZG9taXplZFxuXG5sZXQgcHJuZyA9IGxhenkgKFJhbmRvbS5TdGF0ZS5tYWtlX3NlbGZfaW5pdCgpKVxuXG4oKiBGdW5jdGlvbnMgd2hpY2ggYXBwZWFyIGJlZm9yZSB0aGUgZnVuY3RvcmlhbCBpbnRlcmZhY2UgbXVzdCBlaXRoZXIgYmVcbiAgIGluZGVwZW5kZW50IG9mIHRoZSBoYXNoIGZ1bmN0aW9uIG9yIHRha2UgaXQgYXMgYSBwYXJhbWV0ZXIgKHNlZSAjMjIwMiBhbmRcbiAgIGNvZGUgYmVsb3cgdGhlIGZ1bmN0b3IgZGVmaW5pdGlvbnMuICopXG5cbigqIENyZWF0aW5nIGEgZnJlc2gsIGVtcHR5IHRhYmxlICopXG5cbmxldCByZWMgcG93ZXJfMl9hYm92ZSB4IG4gPVxuICBpZiB4ID49IG4gdGhlbiB4XG4gIGVsc2UgaWYgeCAqIDIgPiBTeXMubWF4X2FycmF5X2xlbmd0aCB0aGVuIHhcbiAgZWxzZSBwb3dlcl8yX2Fib3ZlICh4ICogMikgblxuXG5sZXQgY3JlYXRlID8ocmFuZG9tID0gIXJhbmRvbWl6ZWQpIGluaXRpYWxfc2l6ZSA9XG4gIGxldCBzID0gcG93ZXJfMl9hYm92ZSAxNiBpbml0aWFsX3NpemUgaW5cbiAgbGV0IHNlZWQgPSBpZiByYW5kb20gdGhlbiBSYW5kb20uU3RhdGUuYml0cyAoTGF6eS5mb3JjZSBwcm5nKSBlbHNlIDAgaW5cbiAgeyBpbml0aWFsX3NpemUgPSBzOyBzaXplID0gMDsgc2VlZCA9IHNlZWQ7IGRhdGEgPSBBcnJheS5tYWtlIHMgRW1wdHkgfVxuXG5sZXQgY2xlYXIgaCA9XG4gIGlmIGguc2l6ZSA+IDAgdGhlbiBiZWdpblxuICAgIGguc2l6ZSA8LSAwO1xuICAgIEFycmF5LmZpbGwgaC5kYXRhIDAgKEFycmF5Lmxlbmd0aCBoLmRhdGEpIEVtcHR5XG4gIGVuZFxuXG5sZXQgcmVzZXQgaCA9XG4gIGxldCBsZW4gPSBBcnJheS5sZW5ndGggaC5kYXRhIGluXG4gIGlmIE9iai5zaXplIChPYmoucmVwciBoKSA8IDQgKCogY29tcGF0aWJpbGl0eSB3aXRoIG9sZCBoYXNoIHRhYmxlcyAqKVxuICAgIHx8IGxlbiA9IGFicyBoLmluaXRpYWxfc2l6ZSB0aGVuXG4gICAgY2xlYXIgaFxuICBlbHNlIGJlZ2luXG4gICAgaC5zaXplIDwtIDA7XG4gICAgaC5kYXRhIDwtIEFycmF5Lm1ha2UgKGFicyBoLmluaXRpYWxfc2l6ZSkgRW1wdHlcbiAgZW5kXG5cbmxldCBjb3B5X2J1Y2tldGxpc3QgPSBmdW5jdGlvblxuICB8IEVtcHR5IC0+IEVtcHR5XG4gIHwgQ29ucyB7a2V5OyBkYXRhOyBuZXh0fSAtPlxuICAgICAgbGV0IHJlYyBsb29wIHByZWMgPSBmdW5jdGlvblxuICAgICAgICB8IEVtcHR5IC0+ICgpXG4gICAgICAgIHwgQ29ucyB7a2V5OyBkYXRhOyBuZXh0fSAtPlxuICAgICAgICAgICAgbGV0IHIgPSBDb25zIHtrZXk7IGRhdGE7IG5leHR9IGluXG4gICAgICAgICAgICBiZWdpbiBtYXRjaCBwcmVjIHdpdGhcbiAgICAgICAgICAgIHwgRW1wdHkgLT4gYXNzZXJ0IGZhbHNlXG4gICAgICAgICAgICB8IENvbnMgcHJlYyAtPiAgcHJlYy5uZXh0IDwtIHJcbiAgICAgICAgICAgIGVuZDtcbiAgICAgICAgICAgIGxvb3AgciBuZXh0XG4gICAgICBpblxuICAgICAgbGV0IHIgPSBDb25zIHtrZXk7IGRhdGE7IG5leHR9IGluXG4gICAgICBsb29wIHIgbmV4dDtcbiAgICAgIHJcblxubGV0IGNvcHkgaCA9IHsgaCB3aXRoIGRhdGEgPSBBcnJheS5tYXAgY29weV9idWNrZXRsaXN0IGguZGF0YSB9XG5cbmxldCBsZW5ndGggaCA9IGguc2l6ZVxuXG5sZXQgaW5zZXJ0X2FsbF9idWNrZXRzIGluZGV4ZnVuIGlucGxhY2Ugb2RhdGEgbmRhdGEgPVxuICBsZXQgbnNpemUgPSBBcnJheS5sZW5ndGggbmRhdGEgaW5cbiAgbGV0IG5kYXRhX3RhaWwgPSBBcnJheS5tYWtlIG5zaXplIEVtcHR5IGluXG4gIGxldCByZWMgaW5zZXJ0X2J1Y2tldCA9IGZ1bmN0aW9uXG4gICAgfCBFbXB0eSAtPiAoKVxuICAgIHwgQ29ucyB7a2V5OyBkYXRhOyBuZXh0fSBhcyBjZWxsIC0+XG4gICAgICAgIGxldCBjZWxsID1cbiAgICAgICAgICBpZiBpbnBsYWNlIHRoZW4gY2VsbFxuICAgICAgICAgIGVsc2UgQ29ucyB7a2V5OyBkYXRhOyBuZXh0ID0gRW1wdHl9XG4gICAgICAgIGluXG4gICAgICAgIGxldCBuaWR4ID0gaW5kZXhmdW4ga2V5IGluXG4gICAgICAgIGJlZ2luIG1hdGNoIG5kYXRhX3RhaWwuKG5pZHgpIHdpdGhcbiAgICAgICAgfCBFbXB0eSAtPiBuZGF0YS4obmlkeCkgPC0gY2VsbDtcbiAgICAgICAgfCBDb25zIHRhaWwgLT4gdGFpbC5uZXh0IDwtIGNlbGw7XG4gICAgICAgIGVuZDtcbiAgICAgICAgbmRhdGFfdGFpbC4obmlkeCkgPC0gY2VsbDtcbiAgICAgICAgaW5zZXJ0X2J1Y2tldCBuZXh0XG4gIGluXG4gIGZvciBpID0gMCB0byBBcnJheS5sZW5ndGggb2RhdGEgLSAxIGRvXG4gICAgaW5zZXJ0X2J1Y2tldCBvZGF0YS4oaSlcbiAgZG9uZTtcbiAgaWYgaW5wbGFjZSB0aGVuXG4gICAgZm9yIGkgPSAwIHRvIG5zaXplIC0gMSBkb1xuICAgICAgbWF0Y2ggbmRhdGFfdGFpbC4oaSkgd2l0aFxuICAgICAgfCBFbXB0eSAtPiAoKVxuICAgICAgfCBDb25zIHRhaWwgLT4gdGFpbC5uZXh0IDwtIEVtcHR5XG4gICAgZG9uZVxuXG5sZXQgcmVzaXplIGluZGV4ZnVuIGggPVxuICBsZXQgb2RhdGEgPSBoLmRhdGEgaW5cbiAgbGV0IG9zaXplID0gQXJyYXkubGVuZ3RoIG9kYXRhIGluXG4gIGxldCBuc2l6ZSA9IG9zaXplICogMiBpblxuICBpZiBuc2l6ZSA8IFN5cy5tYXhfYXJyYXlfbGVuZ3RoIHRoZW4gYmVnaW5cbiAgICBsZXQgbmRhdGEgPSBBcnJheS5tYWtlIG5zaXplIEVtcHR5IGluXG4gICAgbGV0IGlucGxhY2UgPSBub3QgKG9uZ29pbmdfdHJhdmVyc2FsIGgpIGluXG4gICAgaC5kYXRhIDwtIG5kYXRhOyAgICAgICAgICAoKiBzbyB0aGF0IGluZGV4ZnVuIHNlZXMgdGhlIG5ldyBidWNrZXQgY291bnQgKilcbiAgICBpbnNlcnRfYWxsX2J1Y2tldHMgKGluZGV4ZnVuIGgpIGlucGxhY2Ugb2RhdGEgbmRhdGFcbiAgZW5kXG5cbmxldCBpdGVyIGYgaCA9XG4gIGxldCByZWMgZG9fYnVja2V0ID0gZnVuY3Rpb25cbiAgICB8IEVtcHR5IC0+XG4gICAgICAgICgpXG4gICAgfCBDb25ze2tleTsgZGF0YTsgbmV4dH0gLT5cbiAgICAgICAgZiBrZXkgZGF0YTsgZG9fYnVja2V0IG5leHQgaW5cbiAgbGV0IG9sZF90cmF2ID0gb25nb2luZ190cmF2ZXJzYWwgaCBpblxuICBpZiBub3Qgb2xkX3RyYXYgdGhlbiBmbGlwX29uZ29pbmdfdHJhdmVyc2FsIGg7XG4gIHRyeVxuICAgIGxldCBkID0gaC5kYXRhIGluXG4gICAgZm9yIGkgPSAwIHRvIEFycmF5Lmxlbmd0aCBkIC0gMSBkb1xuICAgICAgZG9fYnVja2V0IGQuKGkpXG4gICAgZG9uZTtcbiAgICBpZiBub3Qgb2xkX3RyYXYgdGhlbiBmbGlwX29uZ29pbmdfdHJhdmVyc2FsIGg7XG4gIHdpdGggZXhuIHdoZW4gbm90IG9sZF90cmF2IC0+XG4gICAgZmxpcF9vbmdvaW5nX3RyYXZlcnNhbCBoO1xuICAgIHJhaXNlIGV4blxuXG5sZXQgcmVjIGZpbHRlcl9tYXBfaW5wbGFjZV9idWNrZXQgZiBoIGkgcHJlYyA9IGZ1bmN0aW9uXG4gIHwgRW1wdHkgLT5cbiAgICAgIGJlZ2luIG1hdGNoIHByZWMgd2l0aFxuICAgICAgfCBFbXB0eSAtPiBoLmRhdGEuKGkpIDwtIEVtcHR5XG4gICAgICB8IENvbnMgYyAtPiBjLm5leHQgPC0gRW1wdHlcbiAgICAgIGVuZFxuICB8IChDb25zICh7a2V5OyBkYXRhOyBuZXh0fSBhcyBjKSkgYXMgc2xvdCAtPlxuICAgICAgYmVnaW4gbWF0Y2ggZiBrZXkgZGF0YSB3aXRoXG4gICAgICB8IE5vbmUgLT5cbiAgICAgICAgICBoLnNpemUgPC0gaC5zaXplIC0gMTtcbiAgICAgICAgICBmaWx0ZXJfbWFwX2lucGxhY2VfYnVja2V0IGYgaCBpIHByZWMgbmV4dFxuICAgICAgfCBTb21lIGRhdGEgLT5cbiAgICAgICAgICBiZWdpbiBtYXRjaCBwcmVjIHdpdGhcbiAgICAgICAgICB8IEVtcHR5IC0+IGguZGF0YS4oaSkgPC0gc2xvdFxuICAgICAgICAgIHwgQ29ucyBjIC0+IGMubmV4dCA8LSBzbG90XG4gICAgICAgICAgZW5kO1xuICAgICAgICAgIGMuZGF0YSA8LSBkYXRhO1xuICAgICAgICAgIGZpbHRlcl9tYXBfaW5wbGFjZV9idWNrZXQgZiBoIGkgc2xvdCBuZXh0XG4gICAgICBlbmRcblxubGV0IGZpbHRlcl9tYXBfaW5wbGFjZSBmIGggPVxuICBsZXQgZCA9IGguZGF0YSBpblxuICBsZXQgb2xkX3RyYXYgPSBvbmdvaW5nX3RyYXZlcnNhbCBoIGluXG4gIGlmIG5vdCBvbGRfdHJhdiB0aGVuIGZsaXBfb25nb2luZ190cmF2ZXJzYWwgaDtcbiAgdHJ5XG4gICAgZm9yIGkgPSAwIHRvIEFycmF5Lmxlbmd0aCBkIC0gMSBkb1xuICAgICAgZmlsdGVyX21hcF9pbnBsYWNlX2J1Y2tldCBmIGggaSBFbXB0eSBoLmRhdGEuKGkpXG4gICAgZG9uZTtcbiAgICBpZiBub3Qgb2xkX3RyYXYgdGhlbiBmbGlwX29uZ29pbmdfdHJhdmVyc2FsIGhcbiAgd2l0aCBleG4gd2hlbiBub3Qgb2xkX3RyYXYgLT5cbiAgICBmbGlwX29uZ29pbmdfdHJhdmVyc2FsIGg7XG4gICAgcmFpc2UgZXhuXG5cbmxldCBmb2xkIGYgaCBpbml0ID1cbiAgbGV0IHJlYyBkb19idWNrZXQgYiBhY2N1ID1cbiAgICBtYXRjaCBiIHdpdGhcbiAgICAgIEVtcHR5IC0+XG4gICAgICAgIGFjY3VcbiAgICB8IENvbnN7a2V5OyBkYXRhOyBuZXh0fSAtPlxuICAgICAgICBkb19idWNrZXQgbmV4dCAoZiBrZXkgZGF0YSBhY2N1KSBpblxuICBsZXQgb2xkX3RyYXYgPSBvbmdvaW5nX3RyYXZlcnNhbCBoIGluXG4gIGlmIG5vdCBvbGRfdHJhdiB0aGVuIGZsaXBfb25nb2luZ190cmF2ZXJzYWwgaDtcbiAgdHJ5XG4gICAgbGV0IGQgPSBoLmRhdGEgaW5cbiAgICBsZXQgYWNjdSA9IHJlZiBpbml0IGluXG4gICAgZm9yIGkgPSAwIHRvIEFycmF5Lmxlbmd0aCBkIC0gMSBkb1xuICAgICAgYWNjdSA6PSBkb19idWNrZXQgZC4oaSkgIWFjY3VcbiAgICBkb25lO1xuICAgIGlmIG5vdCBvbGRfdHJhdiB0aGVuIGZsaXBfb25nb2luZ190cmF2ZXJzYWwgaDtcbiAgICAhYWNjdVxuICB3aXRoIGV4biB3aGVuIG5vdCBvbGRfdHJhdiAtPlxuICAgIGZsaXBfb25nb2luZ190cmF2ZXJzYWwgaDtcbiAgICByYWlzZSBleG5cblxudHlwZSBzdGF0aXN0aWNzID0ge1xuICBudW1fYmluZGluZ3M6IGludDtcbiAgbnVtX2J1Y2tldHM6IGludDtcbiAgbWF4X2J1Y2tldF9sZW5ndGg6IGludDtcbiAgYnVja2V0X2hpc3RvZ3JhbTogaW50IGFycmF5XG59XG5cbmxldCByZWMgYnVja2V0X2xlbmd0aCBhY2N1ID0gZnVuY3Rpb25cbiAgfCBFbXB0eSAtPiBhY2N1XG4gIHwgQ29uc3tuZXh0fSAtPiBidWNrZXRfbGVuZ3RoIChhY2N1ICsgMSkgbmV4dFxuXG5sZXQgc3RhdHMgaCA9XG4gIGxldCBtYmwgPVxuICAgIEFycmF5LmZvbGRfbGVmdCAoZnVuIG0gYiAtPiBJbnQubWF4IG0gKGJ1Y2tldF9sZW5ndGggMCBiKSkgMCBoLmRhdGEgaW5cbiAgbGV0IGhpc3RvID0gQXJyYXkubWFrZSAobWJsICsgMSkgMCBpblxuICBBcnJheS5pdGVyXG4gICAgKGZ1biBiIC0+XG4gICAgICBsZXQgbCA9IGJ1Y2tldF9sZW5ndGggMCBiIGluXG4gICAgICBoaXN0by4obCkgPC0gaGlzdG8uKGwpICsgMSlcbiAgICBoLmRhdGE7XG4gIHsgbnVtX2JpbmRpbmdzID0gaC5zaXplO1xuICAgIG51bV9idWNrZXRzID0gQXJyYXkubGVuZ3RoIGguZGF0YTtcbiAgICBtYXhfYnVja2V0X2xlbmd0aCA9IG1ibDtcbiAgICBidWNrZXRfaGlzdG9ncmFtID0gaGlzdG8gfVxuXG4oKiogezEgSXRlcmF0b3JzfSAqKVxuXG5sZXQgdG9fc2VxIHRibCA9XG4gICgqIGNhcHR1cmUgY3VycmVudCBhcnJheSwgc28gdGhhdCBldmVuIGlmIHRoZSB0YWJsZSBpcyByZXNpemVkIHdlXG4gICAgIGtlZXAgaXRlcmF0aW5nIG9uIHRoZSBzYW1lIGFycmF5ICopXG4gIGxldCB0YmxfZGF0YSA9IHRibC5kYXRhIGluXG4gICgqIHN0YXRlOiBpbmRleCAqIG5leHQgYnVja2V0IHRvIHRyYXZlcnNlICopXG4gIGxldCByZWMgYXV4IGkgYnVjayAoKSA9IG1hdGNoIGJ1Y2sgd2l0aFxuICAgIHwgRW1wdHkgLT5cbiAgICAgICAgaWYgaSA9IEFycmF5Lmxlbmd0aCB0YmxfZGF0YVxuICAgICAgICB0aGVuIFNlcS5OaWxcbiAgICAgICAgZWxzZSBhdXgoaSsxKSB0YmxfZGF0YS4oaSkgKClcbiAgICB8IENvbnMge2tleTsgZGF0YTsgbmV4dH0gLT5cbiAgICAgICAgU2VxLkNvbnMgKChrZXksIGRhdGEpLCBhdXggaSBuZXh0KVxuICBpblxuICBhdXggMCBFbXB0eVxuXG5sZXQgdG9fc2VxX2tleXMgbSA9IFNlcS5tYXAgZnN0ICh0b19zZXEgbSlcblxubGV0IHRvX3NlcV92YWx1ZXMgbSA9IFNlcS5tYXAgc25kICh0b19zZXEgbSlcblxuKCogRnVuY3RvcmlhbCBpbnRlcmZhY2UgKilcblxubW9kdWxlIHR5cGUgSGFzaGVkVHlwZSA9XG4gIHNpZ1xuICAgIHR5cGUgdFxuICAgIHZhbCBlcXVhbDogdCAtPiB0IC0+IGJvb2xcbiAgICB2YWwgaGFzaDogdCAtPiBpbnRcbiAgZW5kXG5cbm1vZHVsZSB0eXBlIFNlZWRlZEhhc2hlZFR5cGUgPVxuICBzaWdcbiAgICB0eXBlIHRcbiAgICB2YWwgZXF1YWw6IHQgLT4gdCAtPiBib29sXG4gICAgdmFsIGhhc2g6IGludCAtPiB0IC0+IGludFxuICBlbmRcblxubW9kdWxlIHR5cGUgUyA9XG4gIHNpZ1xuICAgIHR5cGUga2V5XG4gICAgdHlwZSAhJ2EgdFxuICAgIHZhbCBjcmVhdGU6IGludCAtPiAnYSB0XG4gICAgdmFsIGNsZWFyIDogJ2EgdCAtPiB1bml0XG4gICAgdmFsIHJlc2V0IDogJ2EgdCAtPiB1bml0XG4gICAgdmFsIGNvcHk6ICdhIHQgLT4gJ2EgdFxuICAgIHZhbCBhZGQ6ICdhIHQgLT4ga2V5IC0+ICdhIC0+IHVuaXRcbiAgICB2YWwgcmVtb3ZlOiAnYSB0IC0+IGtleSAtPiB1bml0XG4gICAgdmFsIGZpbmQ6ICdhIHQgLT4ga2V5IC0+ICdhXG4gICAgdmFsIGZpbmRfb3B0OiAnYSB0IC0+IGtleSAtPiAnYSBvcHRpb25cbiAgICB2YWwgZmluZF9hbGw6ICdhIHQgLT4ga2V5IC0+ICdhIGxpc3RcbiAgICB2YWwgcmVwbGFjZSA6ICdhIHQgLT4ga2V5IC0+ICdhIC0+IHVuaXRcbiAgICB2YWwgbWVtIDogJ2EgdCAtPiBrZXkgLT4gYm9vbFxuICAgIHZhbCBpdGVyOiAoa2V5IC0+ICdhIC0+IHVuaXQpIC0+ICdhIHQgLT4gdW5pdFxuICAgIHZhbCBmaWx0ZXJfbWFwX2lucGxhY2U6IChrZXkgLT4gJ2EgLT4gJ2Egb3B0aW9uKSAtPiAnYSB0IC0+IHVuaXRcbiAgICB2YWwgZm9sZDogKGtleSAtPiAnYSAtPiAnYiAtPiAnYikgLT4gJ2EgdCAtPiAnYiAtPiAnYlxuICAgIHZhbCBsZW5ndGg6ICdhIHQgLT4gaW50XG4gICAgdmFsIHN0YXRzOiAnYSB0IC0+IHN0YXRpc3RpY3NcbiAgICB2YWwgdG9fc2VxIDogJ2EgdCAtPiAoa2V5ICogJ2EpIFNlcS50XG4gICAgdmFsIHRvX3NlcV9rZXlzIDogXyB0IC0+IGtleSBTZXEudFxuICAgIHZhbCB0b19zZXFfdmFsdWVzIDogJ2EgdCAtPiAnYSBTZXEudFxuICAgIHZhbCBhZGRfc2VxIDogJ2EgdCAtPiAoa2V5ICogJ2EpIFNlcS50IC0+IHVuaXRcbiAgICB2YWwgcmVwbGFjZV9zZXEgOiAnYSB0IC0+IChrZXkgKiAnYSkgU2VxLnQgLT4gdW5pdFxuICAgIHZhbCBvZl9zZXEgOiAoa2V5ICogJ2EpIFNlcS50IC0+ICdhIHRcbiAgZW5kXG5cbm1vZHVsZSB0eXBlIFNlZWRlZFMgPVxuICBzaWdcbiAgICB0eXBlIGtleVxuICAgIHR5cGUgISdhIHRcbiAgICB2YWwgY3JlYXRlIDogP3JhbmRvbTpib29sIC0+IGludCAtPiAnYSB0XG4gICAgdmFsIGNsZWFyIDogJ2EgdCAtPiB1bml0XG4gICAgdmFsIHJlc2V0IDogJ2EgdCAtPiB1bml0XG4gICAgdmFsIGNvcHkgOiAnYSB0IC0+ICdhIHRcbiAgICB2YWwgYWRkIDogJ2EgdCAtPiBrZXkgLT4gJ2EgLT4gdW5pdFxuICAgIHZhbCByZW1vdmUgOiAnYSB0IC0+IGtleSAtPiB1bml0XG4gICAgdmFsIGZpbmQgOiAnYSB0IC0+IGtleSAtPiAnYVxuICAgIHZhbCBmaW5kX29wdDogJ2EgdCAtPiBrZXkgLT4gJ2Egb3B0aW9uXG4gICAgdmFsIGZpbmRfYWxsIDogJ2EgdCAtPiBrZXkgLT4gJ2EgbGlzdFxuICAgIHZhbCByZXBsYWNlIDogJ2EgdCAtPiBrZXkgLT4gJ2EgLT4gdW5pdFxuICAgIHZhbCBtZW0gOiAnYSB0IC0+IGtleSAtPiBib29sXG4gICAgdmFsIGl0ZXIgOiAoa2V5IC0+ICdhIC0+IHVuaXQpIC0+ICdhIHQgLT4gdW5pdFxuICAgIHZhbCBmaWx0ZXJfbWFwX2lucGxhY2U6IChrZXkgLT4gJ2EgLT4gJ2Egb3B0aW9uKSAtPiAnYSB0IC0+IHVuaXRcbiAgICB2YWwgZm9sZCA6IChrZXkgLT4gJ2EgLT4gJ2IgLT4gJ2IpIC0+ICdhIHQgLT4gJ2IgLT4gJ2JcbiAgICB2YWwgbGVuZ3RoIDogJ2EgdCAtPiBpbnRcbiAgICB2YWwgc3RhdHM6ICdhIHQgLT4gc3RhdGlzdGljc1xuICAgIHZhbCB0b19zZXEgOiAnYSB0IC0+IChrZXkgKiAnYSkgU2VxLnRcbiAgICB2YWwgdG9fc2VxX2tleXMgOiBfIHQgLT4ga2V5IFNlcS50XG4gICAgdmFsIHRvX3NlcV92YWx1ZXMgOiAnYSB0IC0+ICdhIFNlcS50XG4gICAgdmFsIGFkZF9zZXEgOiAnYSB0IC0+IChrZXkgKiAnYSkgU2VxLnQgLT4gdW5pdFxuICAgIHZhbCByZXBsYWNlX3NlcSA6ICdhIHQgLT4gKGtleSAqICdhKSBTZXEudCAtPiB1bml0XG4gICAgdmFsIG9mX3NlcSA6IChrZXkgKiAnYSkgU2VxLnQgLT4gJ2EgdFxuICBlbmRcblxubW9kdWxlIE1ha2VTZWVkZWQoSDogU2VlZGVkSGFzaGVkVHlwZSk6IChTZWVkZWRTIHdpdGggdHlwZSBrZXkgPSBILnQpID1cbiAgc3RydWN0XG4gICAgdHlwZSBrZXkgPSBILnRcbiAgICB0eXBlICdhIGhhc2h0YmwgPSAoa2V5LCAnYSkgdFxuICAgIHR5cGUgJ2EgdCA9ICdhIGhhc2h0YmxcbiAgICBsZXQgY3JlYXRlID0gY3JlYXRlXG4gICAgbGV0IGNsZWFyID0gY2xlYXJcbiAgICBsZXQgcmVzZXQgPSByZXNldFxuICAgIGxldCBjb3B5ID0gY29weVxuXG4gICAgbGV0IGtleV9pbmRleCBoIGtleSA9XG4gICAgICAoSC5oYXNoIGguc2VlZCBrZXkpIGxhbmQgKEFycmF5Lmxlbmd0aCBoLmRhdGEgLSAxKVxuXG4gICAgbGV0IGFkZCBoIGtleSBkYXRhID1cbiAgICAgIGxldCBpID0ga2V5X2luZGV4IGgga2V5IGluXG4gICAgICBsZXQgYnVja2V0ID0gQ29uc3trZXk7IGRhdGE7IG5leHQ9aC5kYXRhLihpKX0gaW5cbiAgICAgIGguZGF0YS4oaSkgPC0gYnVja2V0O1xuICAgICAgaC5zaXplIDwtIGguc2l6ZSArIDE7XG4gICAgICBpZiBoLnNpemUgPiBBcnJheS5sZW5ndGggaC5kYXRhIGxzbCAxIHRoZW4gcmVzaXplIGtleV9pbmRleCBoXG5cbiAgICBsZXQgcmVjIHJlbW92ZV9idWNrZXQgaCBpIGtleSBwcmVjID0gZnVuY3Rpb25cbiAgICAgIHwgRW1wdHkgLT5cbiAgICAgICAgICAoKVxuICAgICAgfCAoQ29ucyB7a2V5PWs7IG5leHR9KSBhcyBjIC0+XG4gICAgICAgICAgaWYgSC5lcXVhbCBrIGtleVxuICAgICAgICAgIHRoZW4gYmVnaW5cbiAgICAgICAgICAgIGguc2l6ZSA8LSBoLnNpemUgLSAxO1xuICAgICAgICAgICAgbWF0Y2ggcHJlYyB3aXRoXG4gICAgICAgICAgICB8IEVtcHR5IC0+IGguZGF0YS4oaSkgPC0gbmV4dFxuICAgICAgICAgICAgfCBDb25zIGMgLT4gYy5uZXh0IDwtIG5leHRcbiAgICAgICAgICBlbmRcbiAgICAgICAgICBlbHNlIHJlbW92ZV9idWNrZXQgaCBpIGtleSBjIG5leHRcblxuICAgIGxldCByZW1vdmUgaCBrZXkgPVxuICAgICAgbGV0IGkgPSBrZXlfaW5kZXggaCBrZXkgaW5cbiAgICAgIHJlbW92ZV9idWNrZXQgaCBpIGtleSBFbXB0eSBoLmRhdGEuKGkpXG5cbiAgICBsZXQgcmVjIGZpbmRfcmVjIGtleSA9IGZ1bmN0aW9uXG4gICAgICB8IEVtcHR5IC0+XG4gICAgICAgICAgcmFpc2UgTm90X2ZvdW5kXG4gICAgICB8IENvbnN7a2V5PWs7IGRhdGE7IG5leHR9IC0+XG4gICAgICAgICAgaWYgSC5lcXVhbCBrZXkgayB0aGVuIGRhdGEgZWxzZSBmaW5kX3JlYyBrZXkgbmV4dFxuXG4gICAgbGV0IGZpbmQgaCBrZXkgPVxuICAgICAgbWF0Y2ggaC5kYXRhLihrZXlfaW5kZXggaCBrZXkpIHdpdGhcbiAgICAgIHwgRW1wdHkgLT4gcmFpc2UgTm90X2ZvdW5kXG4gICAgICB8IENvbnN7a2V5PWsxOyBkYXRhPWQxOyBuZXh0PW5leHQxfSAtPlxuICAgICAgICAgIGlmIEguZXF1YWwga2V5IGsxIHRoZW4gZDEgZWxzZVxuICAgICAgICAgIG1hdGNoIG5leHQxIHdpdGhcbiAgICAgICAgICB8IEVtcHR5IC0+IHJhaXNlIE5vdF9mb3VuZFxuICAgICAgICAgIHwgQ29uc3trZXk9azI7IGRhdGE9ZDI7IG5leHQ9bmV4dDJ9IC0+XG4gICAgICAgICAgICAgIGlmIEguZXF1YWwga2V5IGsyIHRoZW4gZDIgZWxzZVxuICAgICAgICAgICAgICBtYXRjaCBuZXh0MiB3aXRoXG4gICAgICAgICAgICAgIHwgRW1wdHkgLT4gcmFpc2UgTm90X2ZvdW5kXG4gICAgICAgICAgICAgIHwgQ29uc3trZXk9azM7IGRhdGE9ZDM7IG5leHQ9bmV4dDN9IC0+XG4gICAgICAgICAgICAgICAgICBpZiBILmVxdWFsIGtleSBrMyB0aGVuIGQzIGVsc2UgZmluZF9yZWMga2V5IG5leHQzXG5cbiAgICBsZXQgcmVjIGZpbmRfcmVjX29wdCBrZXkgPSBmdW5jdGlvblxuICAgICAgfCBFbXB0eSAtPlxuICAgICAgICAgIE5vbmVcbiAgICAgIHwgQ29uc3trZXk9azsgZGF0YTsgbmV4dH0gLT5cbiAgICAgICAgICBpZiBILmVxdWFsIGtleSBrIHRoZW4gU29tZSBkYXRhIGVsc2UgZmluZF9yZWNfb3B0IGtleSBuZXh0XG5cbiAgICBsZXQgZmluZF9vcHQgaCBrZXkgPVxuICAgICAgbWF0Y2ggaC5kYXRhLihrZXlfaW5kZXggaCBrZXkpIHdpdGhcbiAgICAgIHwgRW1wdHkgLT4gTm9uZVxuICAgICAgfCBDb25ze2tleT1rMTsgZGF0YT1kMTsgbmV4dD1uZXh0MX0gLT5cbiAgICAgICAgICBpZiBILmVxdWFsIGtleSBrMSB0aGVuIFNvbWUgZDEgZWxzZVxuICAgICAgICAgIG1hdGNoIG5leHQxIHdpdGhcbiAgICAgICAgICB8IEVtcHR5IC0+IE5vbmVcbiAgICAgICAgICB8IENvbnN7a2V5PWsyOyBkYXRhPWQyOyBuZXh0PW5leHQyfSAtPlxuICAgICAgICAgICAgICBpZiBILmVxdWFsIGtleSBrMiB0aGVuIFNvbWUgZDIgZWxzZVxuICAgICAgICAgICAgICBtYXRjaCBuZXh0MiB3aXRoXG4gICAgICAgICAgICAgIHwgRW1wdHkgLT4gTm9uZVxuICAgICAgICAgICAgICB8IENvbnN7a2V5PWszOyBkYXRhPWQzOyBuZXh0PW5leHQzfSAtPlxuICAgICAgICAgICAgICAgICAgaWYgSC5lcXVhbCBrZXkgazMgdGhlbiBTb21lIGQzIGVsc2UgZmluZF9yZWNfb3B0IGtleSBuZXh0M1xuXG4gICAgbGV0IGZpbmRfYWxsIGgga2V5ID1cbiAgICAgIGxldCByZWMgZmluZF9pbl9idWNrZXQgPSBmdW5jdGlvblxuICAgICAgfCBFbXB0eSAtPlxuICAgICAgICAgIFtdXG4gICAgICB8IENvbnN7a2V5PWs7IGRhdGE9ZDsgbmV4dH0gLT5cbiAgICAgICAgICBpZiBILmVxdWFsIGsga2V5XG4gICAgICAgICAgdGhlbiBkIDo6IGZpbmRfaW5fYnVja2V0IG5leHRcbiAgICAgICAgICBlbHNlIGZpbmRfaW5fYnVja2V0IG5leHQgaW5cbiAgICAgIGZpbmRfaW5fYnVja2V0IGguZGF0YS4oa2V5X2luZGV4IGgga2V5KVxuXG4gICAgbGV0IHJlYyByZXBsYWNlX2J1Y2tldCBrZXkgZGF0YSA9IGZ1bmN0aW9uXG4gICAgICB8IEVtcHR5IC0+XG4gICAgICAgICAgdHJ1ZVxuICAgICAgfCBDb25zICh7a2V5PWs7IG5leHR9IGFzIHNsb3QpIC0+XG4gICAgICAgICAgaWYgSC5lcXVhbCBrIGtleVxuICAgICAgICAgIHRoZW4gKHNsb3Qua2V5IDwtIGtleTsgc2xvdC5kYXRhIDwtIGRhdGE7IGZhbHNlKVxuICAgICAgICAgIGVsc2UgcmVwbGFjZV9idWNrZXQga2V5IGRhdGEgbmV4dFxuXG4gICAgbGV0IHJlcGxhY2UgaCBrZXkgZGF0YSA9XG4gICAgICBsZXQgaSA9IGtleV9pbmRleCBoIGtleSBpblxuICAgICAgbGV0IGwgPSBoLmRhdGEuKGkpIGluXG4gICAgICBpZiByZXBsYWNlX2J1Y2tldCBrZXkgZGF0YSBsIHRoZW4gYmVnaW5cbiAgICAgICAgaC5kYXRhLihpKSA8LSBDb25ze2tleTsgZGF0YTsgbmV4dD1sfTtcbiAgICAgICAgaC5zaXplIDwtIGguc2l6ZSArIDE7XG4gICAgICAgIGlmIGguc2l6ZSA+IEFycmF5Lmxlbmd0aCBoLmRhdGEgbHNsIDEgdGhlbiByZXNpemUga2V5X2luZGV4IGhcbiAgICAgIGVuZFxuXG4gICAgbGV0IG1lbSBoIGtleSA9XG4gICAgICBsZXQgcmVjIG1lbV9pbl9idWNrZXQgPSBmdW5jdGlvblxuICAgICAgfCBFbXB0eSAtPlxuICAgICAgICAgIGZhbHNlXG4gICAgICB8IENvbnN7a2V5PWs7IG5leHR9IC0+XG4gICAgICAgICAgSC5lcXVhbCBrIGtleSB8fCBtZW1faW5fYnVja2V0IG5leHQgaW5cbiAgICAgIG1lbV9pbl9idWNrZXQgaC5kYXRhLihrZXlfaW5kZXggaCBrZXkpXG5cbiAgICBsZXQgYWRkX3NlcSB0YmwgaSA9XG4gICAgICBTZXEuaXRlciAoZnVuIChrLHYpIC0+IGFkZCB0YmwgayB2KSBpXG5cbiAgICBsZXQgcmVwbGFjZV9zZXEgdGJsIGkgPVxuICAgICAgU2VxLml0ZXIgKGZ1biAoayx2KSAtPiByZXBsYWNlIHRibCBrIHYpIGlcblxuICAgIGxldCBvZl9zZXEgaSA9XG4gICAgICBsZXQgdGJsID0gY3JlYXRlIDE2IGluXG4gICAgICByZXBsYWNlX3NlcSB0YmwgaTtcbiAgICAgIHRibFxuXG4gICAgbGV0IGl0ZXIgPSBpdGVyXG4gICAgbGV0IGZpbHRlcl9tYXBfaW5wbGFjZSA9IGZpbHRlcl9tYXBfaW5wbGFjZVxuICAgIGxldCBmb2xkID0gZm9sZFxuICAgIGxldCBsZW5ndGggPSBsZW5ndGhcbiAgICBsZXQgc3RhdHMgPSBzdGF0c1xuICAgIGxldCB0b19zZXEgPSB0b19zZXFcbiAgICBsZXQgdG9fc2VxX2tleXMgPSB0b19zZXFfa2V5c1xuICAgIGxldCB0b19zZXFfdmFsdWVzID0gdG9fc2VxX3ZhbHVlc1xuICBlbmRcblxubW9kdWxlIE1ha2UoSDogSGFzaGVkVHlwZSk6IChTIHdpdGggdHlwZSBrZXkgPSBILnQpID1cbiAgc3RydWN0XG4gICAgaW5jbHVkZSBNYWtlU2VlZGVkKHN0cnVjdFxuICAgICAgICB0eXBlIHQgPSBILnRcbiAgICAgICAgbGV0IGVxdWFsID0gSC5lcXVhbFxuICAgICAgICBsZXQgaGFzaCAoX3NlZWQ6IGludCkgeCA9IEguaGFzaCB4XG4gICAgICBlbmQpXG4gICAgbGV0IGNyZWF0ZSBzeiA9IGNyZWF0ZSB+cmFuZG9tOmZhbHNlIHN6XG4gICAgbGV0IG9mX3NlcSBpID1cbiAgICAgIGxldCB0YmwgPSBjcmVhdGUgMTYgaW5cbiAgICAgIHJlcGxhY2Vfc2VxIHRibCBpO1xuICAgICAgdGJsXG4gIGVuZFxuXG4oKiBQb2x5bW9ycGhpYyBoYXNoIGZ1bmN0aW9uLWJhc2VkIHRhYmxlcyAqKVxuKCogQ29kZSBpbmNsdWRlZCBiZWxvdyB0aGUgZnVuY3RvcmlhbCBpbnRlcmZhY2UgdG8gZ3VhcmQgYWdhaW5zdCBhY2NpZGVudGFsXG4gICB1c2UgLSBzZWUgIzIyMDIgKilcblxuZXh0ZXJuYWwgc2VlZGVkX2hhc2hfcGFyYW0gOlxuICBpbnQgLT4gaW50IC0+IGludCAtPiAnYSAtPiBpbnQgPSBcImNhbWxfaGFzaFwiIFtAQG5vYWxsb2NdXG5cbmxldCBoYXNoIHggPSBzZWVkZWRfaGFzaF9wYXJhbSAxMCAxMDAgMCB4XG5sZXQgaGFzaF9wYXJhbSBuMSBuMiB4ID0gc2VlZGVkX2hhc2hfcGFyYW0gbjEgbjIgMCB4XG5sZXQgc2VlZGVkX2hhc2ggc2VlZCB4ID0gc2VlZGVkX2hhc2hfcGFyYW0gMTAgMTAwIHNlZWQgeFxuXG5sZXQga2V5X2luZGV4IGgga2V5ID1cbiAgaWYgT2JqLnNpemUgKE9iai5yZXByIGgpID49IDRcbiAgdGhlbiAoc2VlZGVkX2hhc2hfcGFyYW0gMTAgMTAwIGguc2VlZCBrZXkpIGxhbmQgKEFycmF5Lmxlbmd0aCBoLmRhdGEgLSAxKVxuICBlbHNlIGludmFsaWRfYXJnIFwiSGFzaHRibDogdW5zdXBwb3J0ZWQgaGFzaCB0YWJsZSBmb3JtYXRcIlxuXG5sZXQgYWRkIGgga2V5IGRhdGEgPVxuICBsZXQgaSA9IGtleV9pbmRleCBoIGtleSBpblxuICBsZXQgYnVja2V0ID0gQ29uc3trZXk7IGRhdGE7IG5leHQ9aC5kYXRhLihpKX0gaW5cbiAgaC5kYXRhLihpKSA8LSBidWNrZXQ7XG4gIGguc2l6ZSA8LSBoLnNpemUgKyAxO1xuICBpZiBoLnNpemUgPiBBcnJheS5sZW5ndGggaC5kYXRhIGxzbCAxIHRoZW4gcmVzaXplIGtleV9pbmRleCBoXG5cbmxldCByZWMgcmVtb3ZlX2J1Y2tldCBoIGkga2V5IHByZWMgPSBmdW5jdGlvblxuICB8IEVtcHR5IC0+XG4gICAgICAoKVxuICB8IChDb25zIHtrZXk9azsgbmV4dH0pIGFzIGMgLT5cbiAgICAgIGlmIGNvbXBhcmUgayBrZXkgPSAwXG4gICAgICB0aGVuIGJlZ2luXG4gICAgICAgIGguc2l6ZSA8LSBoLnNpemUgLSAxO1xuICAgICAgICBtYXRjaCBwcmVjIHdpdGhcbiAgICAgICAgfCBFbXB0eSAtPiBoLmRhdGEuKGkpIDwtIG5leHRcbiAgICAgICAgfCBDb25zIGMgLT4gYy5uZXh0IDwtIG5leHRcbiAgICAgIGVuZFxuICAgICAgZWxzZSByZW1vdmVfYnVja2V0IGggaSBrZXkgYyBuZXh0XG5cbmxldCByZW1vdmUgaCBrZXkgPVxuICBsZXQgaSA9IGtleV9pbmRleCBoIGtleSBpblxuICByZW1vdmVfYnVja2V0IGggaSBrZXkgRW1wdHkgaC5kYXRhLihpKVxuXG5sZXQgcmVjIGZpbmRfcmVjIGtleSA9IGZ1bmN0aW9uXG4gIHwgRW1wdHkgLT5cbiAgICAgIHJhaXNlIE5vdF9mb3VuZFxuICB8IENvbnN7a2V5PWs7IGRhdGE7IG5leHR9IC0+XG4gICAgICBpZiBjb21wYXJlIGtleSBrID0gMCB0aGVuIGRhdGEgZWxzZSBmaW5kX3JlYyBrZXkgbmV4dFxuXG5sZXQgZmluZCBoIGtleSA9XG4gIG1hdGNoIGguZGF0YS4oa2V5X2luZGV4IGgga2V5KSB3aXRoXG4gIHwgRW1wdHkgLT4gcmFpc2UgTm90X2ZvdW5kXG4gIHwgQ29uc3trZXk9azE7IGRhdGE9ZDE7IG5leHQ9bmV4dDF9IC0+XG4gICAgICBpZiBjb21wYXJlIGtleSBrMSA9IDAgdGhlbiBkMSBlbHNlXG4gICAgICBtYXRjaCBuZXh0MSB3aXRoXG4gICAgICB8IEVtcHR5IC0+IHJhaXNlIE5vdF9mb3VuZFxuICAgICAgfCBDb25ze2tleT1rMjsgZGF0YT1kMjsgbmV4dD1uZXh0Mn0gLT5cbiAgICAgICAgICBpZiBjb21wYXJlIGtleSBrMiA9IDAgdGhlbiBkMiBlbHNlXG4gICAgICAgICAgbWF0Y2ggbmV4dDIgd2l0aFxuICAgICAgICAgIHwgRW1wdHkgLT4gcmFpc2UgTm90X2ZvdW5kXG4gICAgICAgICAgfCBDb25ze2tleT1rMzsgZGF0YT1kMzsgbmV4dD1uZXh0M30gLT5cbiAgICAgICAgICAgICAgaWYgY29tcGFyZSBrZXkgazMgPSAwIHRoZW4gZDMgZWxzZSBmaW5kX3JlYyBrZXkgbmV4dDNcblxubGV0IHJlYyBmaW5kX3JlY19vcHQga2V5ID0gZnVuY3Rpb25cbiAgfCBFbXB0eSAtPlxuICAgICAgTm9uZVxuICB8IENvbnN7a2V5PWs7IGRhdGE7IG5leHR9IC0+XG4gICAgICBpZiBjb21wYXJlIGtleSBrID0gMCB0aGVuIFNvbWUgZGF0YSBlbHNlIGZpbmRfcmVjX29wdCBrZXkgbmV4dFxuXG5sZXQgZmluZF9vcHQgaCBrZXkgPVxuICBtYXRjaCBoLmRhdGEuKGtleV9pbmRleCBoIGtleSkgd2l0aFxuICB8IEVtcHR5IC0+IE5vbmVcbiAgfCBDb25ze2tleT1rMTsgZGF0YT1kMTsgbmV4dD1uZXh0MX0gLT5cbiAgICAgIGlmIGNvbXBhcmUga2V5IGsxID0gMCB0aGVuIFNvbWUgZDEgZWxzZVxuICAgICAgbWF0Y2ggbmV4dDEgd2l0aFxuICAgICAgfCBFbXB0eSAtPiBOb25lXG4gICAgICB8IENvbnN7a2V5PWsyOyBkYXRhPWQyOyBuZXh0PW5leHQyfSAtPlxuICAgICAgICAgIGlmIGNvbXBhcmUga2V5IGsyID0gMCB0aGVuIFNvbWUgZDIgZWxzZVxuICAgICAgICAgIG1hdGNoIG5leHQyIHdpdGhcbiAgICAgICAgICB8IEVtcHR5IC0+IE5vbmVcbiAgICAgICAgICB8IENvbnN7a2V5PWszOyBkYXRhPWQzOyBuZXh0PW5leHQzfSAtPlxuICAgICAgICAgICAgICBpZiBjb21wYXJlIGtleSBrMyA9IDAgdGhlbiBTb21lIGQzIGVsc2UgZmluZF9yZWNfb3B0IGtleSBuZXh0M1xuXG5sZXQgZmluZF9hbGwgaCBrZXkgPVxuICBsZXQgcmVjIGZpbmRfaW5fYnVja2V0ID0gZnVuY3Rpb25cbiAgfCBFbXB0eSAtPlxuICAgICAgW11cbiAgfCBDb25ze2tleT1rOyBkYXRhOyBuZXh0fSAtPlxuICAgICAgaWYgY29tcGFyZSBrIGtleSA9IDBcbiAgICAgIHRoZW4gZGF0YSA6OiBmaW5kX2luX2J1Y2tldCBuZXh0XG4gICAgICBlbHNlIGZpbmRfaW5fYnVja2V0IG5leHQgaW5cbiAgZmluZF9pbl9idWNrZXQgaC5kYXRhLihrZXlfaW5kZXggaCBrZXkpXG5cbmxldCByZWMgcmVwbGFjZV9idWNrZXQga2V5IGRhdGEgPSBmdW5jdGlvblxuICB8IEVtcHR5IC0+XG4gICAgICB0cnVlXG4gIHwgQ29ucyAoe2tleT1rOyBuZXh0fSBhcyBzbG90KSAtPlxuICAgICAgaWYgY29tcGFyZSBrIGtleSA9IDBcbiAgICAgIHRoZW4gKHNsb3Qua2V5IDwtIGtleTsgc2xvdC5kYXRhIDwtIGRhdGE7IGZhbHNlKVxuICAgICAgZWxzZSByZXBsYWNlX2J1Y2tldCBrZXkgZGF0YSBuZXh0XG5cbmxldCByZXBsYWNlIGgga2V5IGRhdGEgPVxuICBsZXQgaSA9IGtleV9pbmRleCBoIGtleSBpblxuICBsZXQgbCA9IGguZGF0YS4oaSkgaW5cbiAgaWYgcmVwbGFjZV9idWNrZXQga2V5IGRhdGEgbCB0aGVuIGJlZ2luXG4gICAgaC5kYXRhLihpKSA8LSBDb25ze2tleTsgZGF0YTsgbmV4dD1sfTtcbiAgICBoLnNpemUgPC0gaC5zaXplICsgMTtcbiAgICBpZiBoLnNpemUgPiBBcnJheS5sZW5ndGggaC5kYXRhIGxzbCAxIHRoZW4gcmVzaXplIGtleV9pbmRleCBoXG4gIGVuZFxuXG5sZXQgbWVtIGgga2V5ID1cbiAgbGV0IHJlYyBtZW1faW5fYnVja2V0ID0gZnVuY3Rpb25cbiAgfCBFbXB0eSAtPlxuICAgICAgZmFsc2VcbiAgfCBDb25ze2tleT1rOyBuZXh0fSAtPlxuICAgICAgY29tcGFyZSBrIGtleSA9IDAgfHwgbWVtX2luX2J1Y2tldCBuZXh0IGluXG4gIG1lbV9pbl9idWNrZXQgaC5kYXRhLihrZXlfaW5kZXggaCBrZXkpXG5cbmxldCBhZGRfc2VxIHRibCBpID1cbiAgU2VxLml0ZXIgKGZ1biAoayx2KSAtPiBhZGQgdGJsIGsgdikgaVxuXG5sZXQgcmVwbGFjZV9zZXEgdGJsIGkgPVxuICBTZXEuaXRlciAoZnVuIChrLHYpIC0+IHJlcGxhY2UgdGJsIGsgdikgaVxuXG5sZXQgb2Zfc2VxIGkgPVxuICBsZXQgdGJsID0gY3JlYXRlIDE2IGluXG4gIHJlcGxhY2Vfc2VxIHRibCBpO1xuICB0YmxcblxubGV0IHJlYnVpbGQgPyhyYW5kb20gPSAhcmFuZG9taXplZCkgaCA9XG4gIGxldCBzID0gcG93ZXJfMl9hYm92ZSAxNiAoQXJyYXkubGVuZ3RoIGguZGF0YSkgaW5cbiAgbGV0IHNlZWQgPVxuICAgIGlmIHJhbmRvbSB0aGVuIFJhbmRvbS5TdGF0ZS5iaXRzIChMYXp5LmZvcmNlIHBybmcpXG4gICAgZWxzZSBpZiBPYmouc2l6ZSAoT2JqLnJlcHIgaCkgPj0gNCB0aGVuIGguc2VlZFxuICAgIGVsc2UgMCBpblxuICBsZXQgaCcgPSB7XG4gICAgc2l6ZSA9IGguc2l6ZTtcbiAgICBkYXRhID0gQXJyYXkubWFrZSBzIEVtcHR5O1xuICAgIHNlZWQgPSBzZWVkO1xuICAgIGluaXRpYWxfc2l6ZSA9IGlmIE9iai5zaXplIChPYmoucmVwciBoKSA+PSA0IHRoZW4gaC5pbml0aWFsX3NpemUgZWxzZSBzXG4gIH0gaW5cbiAgaW5zZXJ0X2FsbF9idWNrZXRzIChrZXlfaW5kZXggaCcpIGZhbHNlIGguZGF0YSBoJy5kYXRhO1xuICBoJ1xuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgRGFtaWVuIERvbGlnZXosIHByb2pldCBQYXJhLCBJTlJJQSBSb2NxdWVuY291cnQgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMTk5NyBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0ICAgICAqKVxuKCogICAgIGVuIEF1dG9tYXRpcXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG4oKiogV2VhayBhcnJheSBvcGVyYXRpb25zICopXG5cbnR5cGUgISdhIHRcblxuZXh0ZXJuYWwgY3JlYXRlIDogaW50IC0+ICdhIHQgPSBcImNhbWxfd2Vha19jcmVhdGVcIlxuXG5sZXQgY3JlYXRlIGwgPVxuICBpZiBub3QgKDAgPD0gbCAmJiBsIDw9IE9iai5FcGhlbWVyb24ubWF4X2VwaGVfbGVuZ3RoKSB0aGVuXG4gICAgaW52YWxpZF9hcmcoXCJXZWFrLmNyZWF0ZVwiKTtcbiAgY3JlYXRlIGxcblxuKCoqIG51bWJlciBvZiBhZGRpdGlvbmFsIHZhbHVlcyBpbiBhIHdlYWsgcG9pbnRlciAqKVxubGV0IGFkZGl0aW9uYWxfdmFsdWVzID0gMlxuXG5sZXQgbGVuZ3RoIHggPSBPYmouc2l6ZShPYmoucmVwciB4KSAtIGFkZGl0aW9uYWxfdmFsdWVzXG5cbmxldCByYWlzZV9pZl9pbnZhbGlkX29mZnNldCBlIG8gbXNnID1cbiAgaWYgbm90ICgwIDw9IG8gJiYgbyA8IGxlbmd0aCBlKSB0aGVuXG4gICAgaW52YWxpZF9hcmcobXNnKVxuXG5leHRlcm5hbCBzZXQnIDogJ2EgdCAtPiBpbnQgLT4gJ2EgLT4gdW5pdCA9IFwiY2FtbF9lcGhlX3NldF9rZXlcIlxuZXh0ZXJuYWwgdW5zZXQgOiAnYSB0IC0+IGludCAtPiB1bml0ID0gXCJjYW1sX2VwaGVfdW5zZXRfa2V5XCJcbmxldCBzZXQgZSBvIHggPVxuICByYWlzZV9pZl9pbnZhbGlkX29mZnNldCBlIG8gXCJXZWFrLnNldFwiO1xuICBtYXRjaCB4IHdpdGhcbiAgfCBOb25lIC0+IHVuc2V0IGUgb1xuICB8IFNvbWUgeCAtPiBzZXQnIGUgbyB4XG5cbmV4dGVybmFsIGdldCA6ICdhIHQgLT4gaW50IC0+ICdhIG9wdGlvbiA9IFwiY2FtbF93ZWFrX2dldFwiXG5sZXQgZ2V0IGUgbyA9XG4gIHJhaXNlX2lmX2ludmFsaWRfb2Zmc2V0IGUgbyBcIldlYWsuZ2V0XCI7XG4gIGdldCBlIG9cblxuZXh0ZXJuYWwgZ2V0X2NvcHkgOiAnYSB0IC0+IGludCAtPiAnYSBvcHRpb24gPSBcImNhbWxfd2Vha19nZXRfY29weVwiXG5sZXQgZ2V0X2NvcHkgZSBvID1cbiAgcmFpc2VfaWZfaW52YWxpZF9vZmZzZXQgZSBvIFwiV2Vhay5nZXRfY29weVwiO1xuICBnZXRfY29weSBlIG9cblxuZXh0ZXJuYWwgY2hlY2sgOiAnYSB0IC0+IGludCAtPiBib29sID0gXCJjYW1sX3dlYWtfY2hlY2tcIlxubGV0IGNoZWNrIGUgbyA9XG4gIHJhaXNlX2lmX2ludmFsaWRfb2Zmc2V0IGUgbyBcIldlYWsuY2hlY2tcIjtcbiAgY2hlY2sgZSBvXG5cbmV4dGVybmFsIGJsaXQgOiAnYSB0IC0+IGludCAtPiAnYSB0IC0+IGludCAtPiBpbnQgLT4gdW5pdCA9IFwiY2FtbF93ZWFrX2JsaXRcIlxuXG4oKiBibGl0OiBzcmMgc3Jjb2ZmIGRzdCBkc3RvZmYgbGVuICopXG5sZXQgYmxpdCBlMSBvMSBlMiBvMiBsID1cbiAgaWYgbCA8IDAgfHwgbzEgPCAwIHx8IG8xID4gbGVuZ3RoIGUxIC0gbFxuICAgICB8fCBvMiA8IDAgfHwgbzIgPiBsZW5ndGggZTIgLSBsXG4gIHRoZW4gaW52YWxpZF9hcmcgXCJXZWFrLmJsaXRcIlxuICBlbHNlIGlmIGwgPD4gMCB0aGVuIGJsaXQgZTEgbzEgZTIgbzIgbFxuXG5sZXQgZmlsbCBhciBvZnMgbGVuIHggPVxuICBpZiBvZnMgPCAwIHx8IGxlbiA8IDAgfHwgb2ZzID4gbGVuZ3RoIGFyIC0gbGVuXG4gIHRoZW4gcmFpc2UgKEludmFsaWRfYXJndW1lbnQgXCJXZWFrLmZpbGxcIilcbiAgZWxzZSBiZWdpblxuICAgIGZvciBpID0gb2ZzIHRvIChvZnMgKyBsZW4gLSAxKSBkb1xuICAgICAgc2V0IGFyIGkgeFxuICAgIGRvbmVcbiAgZW5kXG5cblxuKCoqIFdlYWsgaGFzaCB0YWJsZXMgKilcblxubW9kdWxlIHR5cGUgUyA9IHNpZ1xuICB0eXBlIGRhdGFcbiAgdHlwZSB0XG4gIHZhbCBjcmVhdGUgOiBpbnQgLT4gdFxuICB2YWwgY2xlYXIgOiB0IC0+IHVuaXRcbiAgdmFsIG1lcmdlIDogdCAtPiBkYXRhIC0+IGRhdGFcbiAgdmFsIGFkZCA6IHQgLT4gZGF0YSAtPiB1bml0XG4gIHZhbCByZW1vdmUgOiB0IC0+IGRhdGEgLT4gdW5pdFxuICB2YWwgZmluZCA6IHQgLT4gZGF0YSAtPiBkYXRhXG4gIHZhbCBmaW5kX29wdCA6IHQgLT4gZGF0YSAtPiBkYXRhIG9wdGlvblxuICB2YWwgZmluZF9hbGwgOiB0IC0+IGRhdGEgLT4gZGF0YSBsaXN0XG4gIHZhbCBtZW0gOiB0IC0+IGRhdGEgLT4gYm9vbFxuICB2YWwgaXRlciA6IChkYXRhIC0+IHVuaXQpIC0+IHQgLT4gdW5pdFxuICB2YWwgZm9sZCA6IChkYXRhIC0+ICdhIC0+ICdhKSAtPiB0IC0+ICdhIC0+ICdhXG4gIHZhbCBjb3VudCA6IHQgLT4gaW50XG4gIHZhbCBzdGF0cyA6IHQgLT4gaW50ICogaW50ICogaW50ICogaW50ICogaW50ICogaW50XG5lbmRcblxubW9kdWxlIE1ha2UgKEggOiBIYXNodGJsLkhhc2hlZFR5cGUpIDogKFMgd2l0aCB0eXBlIGRhdGEgPSBILnQpID0gc3RydWN0XG5cbiAgdHlwZSAnYSB3ZWFrX3QgPSAnYSB0XG4gIGxldCB3ZWFrX2NyZWF0ZSA9IGNyZWF0ZVxuICBsZXQgZW1wdHlidWNrZXQgPSB3ZWFrX2NyZWF0ZSAwXG5cbiAgdHlwZSBkYXRhID0gSC50XG5cbiAgdHlwZSB0ID0ge1xuICAgIG11dGFibGUgdGFibGUgOiBkYXRhIHdlYWtfdCBhcnJheTtcbiAgICBtdXRhYmxlIGhhc2hlcyA6IGludCBhcnJheSBhcnJheTtcbiAgICBtdXRhYmxlIGxpbWl0IDogaW50OyAgICAgICAgICAgICAgICgqIGJ1Y2tldCBzaXplIGxpbWl0ICopXG4gICAgbXV0YWJsZSBvdmVyc2l6ZSA6IGludDsgICAgICAgICAgICAoKiBudW1iZXIgb2Ygb3ZlcnNpemUgYnVja2V0cyAqKVxuICAgIG11dGFibGUgcm92ZXIgOiBpbnQ7ICAgICAgICAgICAgICAgKCogZm9yIGludGVybmFsIGJvb2trZWVwaW5nICopXG4gIH1cblxuICBsZXQgZ2V0X2luZGV4IHQgaCA9IChoIGxhbmQgbWF4X2ludCkgbW9kIChBcnJheS5sZW5ndGggdC50YWJsZSlcblxuICBsZXQgbGltaXQgPSA3XG4gIGxldCBvdmVyX2xpbWl0ID0gMlxuXG4gIGxldCBjcmVhdGUgc3ogPVxuICAgIGxldCBzeiA9IGlmIHN6IDwgNyB0aGVuIDcgZWxzZSBzeiBpblxuICAgIGxldCBzeiA9IGlmIHN6ID4gU3lzLm1heF9hcnJheV9sZW5ndGggdGhlbiBTeXMubWF4X2FycmF5X2xlbmd0aCBlbHNlIHN6IGluXG4gICAge1xuICAgICAgdGFibGUgPSBBcnJheS5tYWtlIHN6IGVtcHR5YnVja2V0O1xuICAgICAgaGFzaGVzID0gQXJyYXkubWFrZSBzeiBbfCB8XTtcbiAgICAgIGxpbWl0ID0gbGltaXQ7XG4gICAgICBvdmVyc2l6ZSA9IDA7XG4gICAgICByb3ZlciA9IDA7XG4gICAgfVxuXG4gIGxldCBjbGVhciB0ID1cbiAgICBmb3IgaSA9IDAgdG8gQXJyYXkubGVuZ3RoIHQudGFibGUgLSAxIGRvXG4gICAgICB0LnRhYmxlLihpKSA8LSBlbXB0eWJ1Y2tldDtcbiAgICAgIHQuaGFzaGVzLihpKSA8LSBbfCB8XTtcbiAgICBkb25lO1xuICAgIHQubGltaXQgPC0gbGltaXQ7XG4gICAgdC5vdmVyc2l6ZSA8LSAwXG5cblxuICBsZXQgZm9sZCBmIHQgaW5pdCA9XG4gICAgbGV0IHJlYyBmb2xkX2J1Y2tldCBpIGIgYWNjdSA9XG4gICAgICBpZiBpID49IGxlbmd0aCBiIHRoZW4gYWNjdSBlbHNlXG4gICAgICBtYXRjaCBnZXQgYiBpIHdpdGhcbiAgICAgIHwgU29tZSB2IC0+IGZvbGRfYnVja2V0IChpKzEpIGIgKGYgdiBhY2N1KVxuICAgICAgfCBOb25lIC0+IGZvbGRfYnVja2V0IChpKzEpIGIgYWNjdVxuICAgIGluXG4gICAgQXJyYXkuZm9sZF9yaWdodCAoZm9sZF9idWNrZXQgMCkgdC50YWJsZSBpbml0XG5cblxuICBsZXQgaXRlciBmIHQgPVxuICAgIGxldCByZWMgaXRlcl9idWNrZXQgaSBiID1cbiAgICAgIGlmIGkgPj0gbGVuZ3RoIGIgdGhlbiAoKSBlbHNlXG4gICAgICBtYXRjaCBnZXQgYiBpIHdpdGhcbiAgICAgIHwgU29tZSB2IC0+IGYgdjsgaXRlcl9idWNrZXQgKGkrMSkgYlxuICAgICAgfCBOb25lIC0+IGl0ZXJfYnVja2V0IChpKzEpIGJcbiAgICBpblxuICAgIEFycmF5Lml0ZXIgKGl0ZXJfYnVja2V0IDApIHQudGFibGVcblxuXG4gIGxldCBpdGVyX3dlYWsgZiB0ID1cbiAgICBsZXQgcmVjIGl0ZXJfYnVja2V0IGkgaiBiID1cbiAgICAgIGlmIGkgPj0gbGVuZ3RoIGIgdGhlbiAoKSBlbHNlXG4gICAgICBtYXRjaCBjaGVjayBiIGkgd2l0aFxuICAgICAgfCB0cnVlIC0+IGYgYiB0Lmhhc2hlcy4oaikgaTsgaXRlcl9idWNrZXQgKGkrMSkgaiBiXG4gICAgICB8IGZhbHNlIC0+IGl0ZXJfYnVja2V0IChpKzEpIGogYlxuICAgIGluXG4gICAgQXJyYXkuaXRlcmkgKGl0ZXJfYnVja2V0IDApIHQudGFibGVcblxuXG4gIGxldCByZWMgY291bnRfYnVja2V0IGkgYiBhY2N1ID1cbiAgICBpZiBpID49IGxlbmd0aCBiIHRoZW4gYWNjdSBlbHNlXG4gICAgY291bnRfYnVja2V0IChpKzEpIGIgKGFjY3UgKyAoaWYgY2hlY2sgYiBpIHRoZW4gMSBlbHNlIDApKVxuXG5cbiAgbGV0IGNvdW50IHQgPVxuICAgIEFycmF5LmZvbGRfcmlnaHQgKGNvdW50X2J1Y2tldCAwKSB0LnRhYmxlIDBcblxuXG4gIGxldCBuZXh0X3N6IG4gPSBJbnQubWluICgzICogbiAvIDIgKyAzKSBTeXMubWF4X2FycmF5X2xlbmd0aFxuICBsZXQgcHJldl9zeiBuID0gKChuIC0gMykgKiAyICsgMikgLyAzXG5cbiAgbGV0IHRlc3Rfc2hyaW5rX2J1Y2tldCB0ID1cbiAgICBsZXQgYnVja2V0ID0gdC50YWJsZS4odC5yb3ZlcikgaW5cbiAgICBsZXQgaGJ1Y2tldCA9IHQuaGFzaGVzLih0LnJvdmVyKSBpblxuICAgIGxldCBsZW4gPSBsZW5ndGggYnVja2V0IGluXG4gICAgbGV0IHByZXZfbGVuID0gcHJldl9zeiBsZW4gaW5cbiAgICBsZXQgbGl2ZSA9IGNvdW50X2J1Y2tldCAwIGJ1Y2tldCAwIGluXG4gICAgaWYgbGl2ZSA8PSBwcmV2X2xlbiB0aGVuIGJlZ2luXG4gICAgICBsZXQgcmVjIGxvb3AgaSBqID1cbiAgICAgICAgaWYgaiA+PSBwcmV2X2xlbiB0aGVuIGJlZ2luXG4gICAgICAgICAgaWYgY2hlY2sgYnVja2V0IGkgdGhlbiBsb29wIChpICsgMSkgalxuICAgICAgICAgIGVsc2UgaWYgY2hlY2sgYnVja2V0IGogdGhlbiBiZWdpblxuICAgICAgICAgICAgYmxpdCBidWNrZXQgaiBidWNrZXQgaSAxO1xuICAgICAgICAgICAgaGJ1Y2tldC4oaSkgPC0gaGJ1Y2tldC4oaik7XG4gICAgICAgICAgICBsb29wIChpICsgMSkgKGogLSAxKTtcbiAgICAgICAgICBlbmQgZWxzZSBsb29wIGkgKGogLSAxKTtcbiAgICAgICAgZW5kO1xuICAgICAgaW5cbiAgICAgIGxvb3AgMCAobGVuZ3RoIGJ1Y2tldCAtIDEpO1xuICAgICAgaWYgcHJldl9sZW4gPSAwIHRoZW4gYmVnaW5cbiAgICAgICAgdC50YWJsZS4odC5yb3ZlcikgPC0gZW1wdHlidWNrZXQ7XG4gICAgICAgIHQuaGFzaGVzLih0LnJvdmVyKSA8LSBbfCB8XTtcbiAgICAgIGVuZCBlbHNlIGJlZ2luXG4gICAgICAgIGxldCBuZXdidWNrZXQgPSB3ZWFrX2NyZWF0ZSBwcmV2X2xlbiBpblxuICAgICAgICBibGl0IGJ1Y2tldCAwIG5ld2J1Y2tldCAwIHByZXZfbGVuO1xuICAgICAgICB0LnRhYmxlLih0LnJvdmVyKSA8LSBuZXdidWNrZXQ7XG4gICAgICAgIHQuaGFzaGVzLih0LnJvdmVyKSA8LSBBcnJheS5zdWIgaGJ1Y2tldCAwIHByZXZfbGVuXG4gICAgICBlbmQ7XG4gICAgICBpZiBsZW4gPiB0LmxpbWl0ICYmIHByZXZfbGVuIDw9IHQubGltaXQgdGhlbiB0Lm92ZXJzaXplIDwtIHQub3ZlcnNpemUgLSAxO1xuICAgIGVuZDtcbiAgICB0LnJvdmVyIDwtICh0LnJvdmVyICsgMSkgbW9kIChBcnJheS5sZW5ndGggdC50YWJsZSlcblxuXG4gIGxldCByZWMgcmVzaXplIHQgPVxuICAgIGxldCBvbGRsZW4gPSBBcnJheS5sZW5ndGggdC50YWJsZSBpblxuICAgIGxldCBuZXdsZW4gPSBuZXh0X3N6IG9sZGxlbiBpblxuICAgIGlmIG5ld2xlbiA+IG9sZGxlbiB0aGVuIGJlZ2luXG4gICAgICBsZXQgbmV3dCA9IGNyZWF0ZSBuZXdsZW4gaW5cbiAgICAgIGxldCBhZGRfd2VhayBvYiBvaCBvaSA9XG4gICAgICAgIGxldCBzZXR0ZXIgbmIgbmkgXyA9IGJsaXQgb2Igb2kgbmIgbmkgMSBpblxuICAgICAgICBsZXQgaCA9IG9oLihvaSkgaW5cbiAgICAgICAgYWRkX2F1eCBuZXd0IHNldHRlciBOb25lIGggKGdldF9pbmRleCBuZXd0IGgpO1xuICAgICAgaW5cbiAgICAgIGl0ZXJfd2VhayBhZGRfd2VhayB0O1xuICAgICAgdC50YWJsZSA8LSBuZXd0LnRhYmxlO1xuICAgICAgdC5oYXNoZXMgPC0gbmV3dC5oYXNoZXM7XG4gICAgICB0LmxpbWl0IDwtIG5ld3QubGltaXQ7XG4gICAgICB0Lm92ZXJzaXplIDwtIG5ld3Qub3ZlcnNpemU7XG4gICAgICB0LnJvdmVyIDwtIHQucm92ZXIgbW9kIEFycmF5Lmxlbmd0aCBuZXd0LnRhYmxlO1xuICAgIGVuZCBlbHNlIGJlZ2luXG4gICAgICB0LmxpbWl0IDwtIG1heF9pbnQ7ICAgICAgICAgICAgICgqIG1heGltdW0gc2l6ZSBhbHJlYWR5IHJlYWNoZWQgKilcbiAgICAgIHQub3ZlcnNpemUgPC0gMDtcbiAgICBlbmRcblxuICBhbmQgYWRkX2F1eCB0IHNldHRlciBkIGggaW5kZXggPVxuICAgIGxldCBidWNrZXQgPSB0LnRhYmxlLihpbmRleCkgaW5cbiAgICBsZXQgaGFzaGVzID0gdC5oYXNoZXMuKGluZGV4KSBpblxuICAgIGxldCBzeiA9IGxlbmd0aCBidWNrZXQgaW5cbiAgICBsZXQgcmVjIGxvb3AgaSA9XG4gICAgICBpZiBpID49IHN6IHRoZW4gYmVnaW5cbiAgICAgICAgbGV0IG5ld3N6ID1cbiAgICAgICAgICBJbnQubWluICgzICogc3ogLyAyICsgMykgKFN5cy5tYXhfYXJyYXlfbGVuZ3RoIC0gYWRkaXRpb25hbF92YWx1ZXMpXG4gICAgICAgIGluXG4gICAgICAgIGlmIG5ld3N6IDw9IHN6IHRoZW4gZmFpbHdpdGggXCJXZWFrLk1ha2U6IGhhc2ggYnVja2V0IGNhbm5vdCBncm93IG1vcmVcIjtcbiAgICAgICAgbGV0IG5ld2J1Y2tldCA9IHdlYWtfY3JlYXRlIG5ld3N6IGluXG4gICAgICAgIGxldCBuZXdoYXNoZXMgPSBBcnJheS5tYWtlIG5ld3N6IDAgaW5cbiAgICAgICAgYmxpdCBidWNrZXQgMCBuZXdidWNrZXQgMCBzejtcbiAgICAgICAgQXJyYXkuYmxpdCBoYXNoZXMgMCBuZXdoYXNoZXMgMCBzejtcbiAgICAgICAgc2V0dGVyIG5ld2J1Y2tldCBzeiBkO1xuICAgICAgICBuZXdoYXNoZXMuKHN6KSA8LSBoO1xuICAgICAgICB0LnRhYmxlLihpbmRleCkgPC0gbmV3YnVja2V0O1xuICAgICAgICB0Lmhhc2hlcy4oaW5kZXgpIDwtIG5ld2hhc2hlcztcbiAgICAgICAgaWYgc3ogPD0gdC5saW1pdCAmJiBuZXdzeiA+IHQubGltaXQgdGhlbiBiZWdpblxuICAgICAgICAgIHQub3ZlcnNpemUgPC0gdC5vdmVyc2l6ZSArIDE7XG4gICAgICAgICAgZm9yIF9pID0gMCB0byBvdmVyX2xpbWl0IGRvIHRlc3Rfc2hyaW5rX2J1Y2tldCB0IGRvbmU7XG4gICAgICAgIGVuZDtcbiAgICAgICAgaWYgdC5vdmVyc2l6ZSA+IEFycmF5Lmxlbmd0aCB0LnRhYmxlIC8gb3Zlcl9saW1pdCB0aGVuIHJlc2l6ZSB0O1xuICAgICAgZW5kIGVsc2UgaWYgY2hlY2sgYnVja2V0IGkgdGhlbiBiZWdpblxuICAgICAgICBsb29wIChpICsgMSlcbiAgICAgIGVuZCBlbHNlIGJlZ2luXG4gICAgICAgIHNldHRlciBidWNrZXQgaSBkO1xuICAgICAgICBoYXNoZXMuKGkpIDwtIGg7XG4gICAgICBlbmQ7XG4gICAgaW5cbiAgICBsb29wIDBcblxuXG4gIGxldCBhZGQgdCBkID1cbiAgICBsZXQgaCA9IEguaGFzaCBkIGluXG4gICAgYWRkX2F1eCB0IHNldCAoU29tZSBkKSBoIChnZXRfaW5kZXggdCBoKVxuXG5cbiAgbGV0IGZpbmRfb3IgdCBkIGlmbm90Zm91bmQgPVxuICAgIGxldCBoID0gSC5oYXNoIGQgaW5cbiAgICBsZXQgaW5kZXggPSBnZXRfaW5kZXggdCBoIGluXG4gICAgbGV0IGJ1Y2tldCA9IHQudGFibGUuKGluZGV4KSBpblxuICAgIGxldCBoYXNoZXMgPSB0Lmhhc2hlcy4oaW5kZXgpIGluXG4gICAgbGV0IHN6ID0gbGVuZ3RoIGJ1Y2tldCBpblxuICAgIGxldCByZWMgbG9vcCBpID1cbiAgICAgIGlmIGkgPj0gc3ogdGhlbiBpZm5vdGZvdW5kIGggaW5kZXhcbiAgICAgIGVsc2UgaWYgaCA9IGhhc2hlcy4oaSkgdGhlbiBiZWdpblxuICAgICAgICBtYXRjaCBnZXRfY29weSBidWNrZXQgaSB3aXRoXG4gICAgICAgIHwgU29tZSB2IHdoZW4gSC5lcXVhbCB2IGRcbiAgICAgICAgICAgLT4gYmVnaW4gbWF0Y2ggZ2V0IGJ1Y2tldCBpIHdpdGhcbiAgICAgICAgICAgICAgfCBTb21lIHYgLT4gdlxuICAgICAgICAgICAgICB8IE5vbmUgLT4gbG9vcCAoaSArIDEpXG4gICAgICAgICAgICAgIGVuZFxuICAgICAgICB8IF8gLT4gbG9vcCAoaSArIDEpXG4gICAgICBlbmQgZWxzZSBsb29wIChpICsgMSlcbiAgICBpblxuICAgIGxvb3AgMFxuXG5cbiAgbGV0IG1lcmdlIHQgZCA9XG4gICAgZmluZF9vciB0IGQgKGZ1biBoIGluZGV4IC0+IGFkZF9hdXggdCBzZXQgKFNvbWUgZCkgaCBpbmRleDsgZClcblxuXG4gIGxldCBmaW5kIHQgZCA9IGZpbmRfb3IgdCBkIChmdW4gX2ggX2luZGV4IC0+IHJhaXNlIE5vdF9mb3VuZClcblxuICBsZXQgZmluZF9vcHQgdCBkID1cbiAgICBsZXQgaCA9IEguaGFzaCBkIGluXG4gICAgbGV0IGluZGV4ID0gZ2V0X2luZGV4IHQgaCBpblxuICAgIGxldCBidWNrZXQgPSB0LnRhYmxlLihpbmRleCkgaW5cbiAgICBsZXQgaGFzaGVzID0gdC5oYXNoZXMuKGluZGV4KSBpblxuICAgIGxldCBzeiA9IGxlbmd0aCBidWNrZXQgaW5cbiAgICBsZXQgcmVjIGxvb3AgaSA9XG4gICAgICBpZiBpID49IHN6IHRoZW4gTm9uZVxuICAgICAgZWxzZSBpZiBoID0gaGFzaGVzLihpKSB0aGVuIGJlZ2luXG4gICAgICAgIG1hdGNoIGdldF9jb3B5IGJ1Y2tldCBpIHdpdGhcbiAgICAgICAgfCBTb21lIHYgd2hlbiBILmVxdWFsIHYgZFxuICAgICAgICAgICAtPiBiZWdpbiBtYXRjaCBnZXQgYnVja2V0IGkgd2l0aFxuICAgICAgICAgICAgICB8IFNvbWUgXyBhcyB2IC0+IHZcbiAgICAgICAgICAgICAgfCBOb25lIC0+IGxvb3AgKGkgKyAxKVxuICAgICAgICAgICAgICBlbmRcbiAgICAgICAgfCBfIC0+IGxvb3AgKGkgKyAxKVxuICAgICAgZW5kIGVsc2UgbG9vcCAoaSArIDEpXG4gICAgaW5cbiAgICBsb29wIDBcblxuXG4gIGxldCBmaW5kX3NoYWRvdyB0IGQgaWZmb3VuZCBpZm5vdGZvdW5kID1cbiAgICBsZXQgaCA9IEguaGFzaCBkIGluXG4gICAgbGV0IGluZGV4ID0gZ2V0X2luZGV4IHQgaCBpblxuICAgIGxldCBidWNrZXQgPSB0LnRhYmxlLihpbmRleCkgaW5cbiAgICBsZXQgaGFzaGVzID0gdC5oYXNoZXMuKGluZGV4KSBpblxuICAgIGxldCBzeiA9IGxlbmd0aCBidWNrZXQgaW5cbiAgICBsZXQgcmVjIGxvb3AgaSA9XG4gICAgICBpZiBpID49IHN6IHRoZW4gaWZub3Rmb3VuZFxuICAgICAgZWxzZSBpZiBoID0gaGFzaGVzLihpKSB0aGVuIGJlZ2luXG4gICAgICAgIG1hdGNoIGdldF9jb3B5IGJ1Y2tldCBpIHdpdGhcbiAgICAgICAgfCBTb21lIHYgd2hlbiBILmVxdWFsIHYgZCAtPiBpZmZvdW5kIGJ1Y2tldCBpXG4gICAgICAgIHwgXyAtPiBsb29wIChpICsgMSlcbiAgICAgIGVuZCBlbHNlIGxvb3AgKGkgKyAxKVxuICAgIGluXG4gICAgbG9vcCAwXG5cblxuICBsZXQgcmVtb3ZlIHQgZCA9IGZpbmRfc2hhZG93IHQgZCAoZnVuIHcgaSAtPiBzZXQgdyBpIE5vbmUpICgpXG5cblxuICBsZXQgbWVtIHQgZCA9IGZpbmRfc2hhZG93IHQgZCAoZnVuIF93IF9pIC0+IHRydWUpIGZhbHNlXG5cblxuICBsZXQgZmluZF9hbGwgdCBkID1cbiAgICBsZXQgaCA9IEguaGFzaCBkIGluXG4gICAgbGV0IGluZGV4ID0gZ2V0X2luZGV4IHQgaCBpblxuICAgIGxldCBidWNrZXQgPSB0LnRhYmxlLihpbmRleCkgaW5cbiAgICBsZXQgaGFzaGVzID0gdC5oYXNoZXMuKGluZGV4KSBpblxuICAgIGxldCBzeiA9IGxlbmd0aCBidWNrZXQgaW5cbiAgICBsZXQgcmVjIGxvb3AgaSBhY2N1ID1cbiAgICAgIGlmIGkgPj0gc3ogdGhlbiBhY2N1XG4gICAgICBlbHNlIGlmIGggPSBoYXNoZXMuKGkpIHRoZW4gYmVnaW5cbiAgICAgICAgbWF0Y2ggZ2V0X2NvcHkgYnVja2V0IGkgd2l0aFxuICAgICAgICB8IFNvbWUgdiB3aGVuIEguZXF1YWwgdiBkXG4gICAgICAgICAgIC0+IGJlZ2luIG1hdGNoIGdldCBidWNrZXQgaSB3aXRoXG4gICAgICAgICAgICAgIHwgU29tZSB2IC0+IGxvb3AgKGkgKyAxKSAodiA6OiBhY2N1KVxuICAgICAgICAgICAgICB8IE5vbmUgLT4gbG9vcCAoaSArIDEpIGFjY3VcbiAgICAgICAgICAgICAgZW5kXG4gICAgICAgIHwgXyAtPiBsb29wIChpICsgMSkgYWNjdVxuICAgICAgZW5kIGVsc2UgbG9vcCAoaSArIDEpIGFjY3VcbiAgICBpblxuICAgIGxvb3AgMCBbXVxuXG5cbiAgbGV0IHN0YXRzIHQgPVxuICAgIGxldCBsZW4gPSBBcnJheS5sZW5ndGggdC50YWJsZSBpblxuICAgIGxldCBsZW5zID0gQXJyYXkubWFwIGxlbmd0aCB0LnRhYmxlIGluXG4gICAgQXJyYXkuc29ydCBjb21wYXJlIGxlbnM7XG4gICAgbGV0IHRvdGxlbiA9IEFycmF5LmZvbGRfbGVmdCAoICsgKSAwIGxlbnMgaW5cbiAgICAobGVuLCBjb3VudCB0LCB0b3RsZW4sIGxlbnMuKDApLCBsZW5zLihsZW4vMiksIGxlbnMuKGxlbi0xKSlcblxuXG5lbmRcbiIsIigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0NhbWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgIFBpZXJyZSBXZWlzLCBwcm9qZXQgQ3Jpc3RhbCwgSU5SSUEgUm9jcXVlbmNvdXJ0ICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQ29weXJpZ2h0IDE5OTYgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCAgICAgKilcbigqICAgICBlbiBBdXRvbWF0aXF1ZS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQWxsIHJpZ2h0cyByZXNlcnZlZC4gIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgICAgKilcbigqICAgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIuMSwgd2l0aCB0aGUgICAgICAgICAgKilcbigqICAgc3BlY2lhbCBleGNlcHRpb24gb24gbGlua2luZyBkZXNjcmliZWQgaW4gdGhlIGZpbGUgTElDRU5TRS4gICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcblxuKCogQSBwcmV0dHktcHJpbnRpbmcgZmFjaWxpdHkgYW5kIGRlZmluaXRpb24gb2YgZm9ybWF0dGVycyBmb3IgJ3BhcmFsbGVsJ1xuICAgKGkuZS4gdW5yZWxhdGVkIG9yIGluZGVwZW5kZW50KSBwcmV0dHktcHJpbnRpbmcgb24gbXVsdGlwbGUgb3V0IGNoYW5uZWxzLiAqKVxuXG4oKlxuICAgVGhlIHByZXR0eS1wcmludGluZyBlbmdpbmUgaW50ZXJuYWwgZGF0YSBzdHJ1Y3R1cmVzLlxuKilcblxubGV0IGlkIHggPSB4XG5cbigqIEEgZGV2b3RlZCB0eXBlIGZvciBzaXplcyB0byBhdm9pZCBjb25mdXNpb25cbiAgIGJldHdlZW4gc2l6ZXMgYW5kIG1lcmUgaW50ZWdlcnMuICopXG5tb2R1bGUgU2l6ZSA6IHNpZ1xuICB0eXBlIHRcblxuICB2YWwgdG9faW50IDogdCAtPiBpbnRcbiAgdmFsIG9mX2ludCA6IGludCAtPiB0XG4gIHZhbCB6ZXJvIDogdFxuICB2YWwgdW5rbm93biA6IHRcbiAgdmFsIGlzX2tub3duIDogdCAtPiBib29sXG5lbmQgID0gc3RydWN0XG4gIHR5cGUgdCA9IGludFxuXG4gIGxldCB0b19pbnQgPSBpZFxuICBsZXQgb2ZfaW50ID0gaWRcbiAgbGV0IHplcm8gPSAwXG4gIGxldCB1bmtub3duID0gLTFcbiAgbGV0IGlzX2tub3duIG4gPSBuID49IDBcbmVuZFxuXG5cblxuKCogVGhlIHByZXR0eS1wcmludGluZyBib3hlcyBkZWZpbml0aW9uOlxuICAgYSBwcmV0dHktcHJpbnRpbmcgYm94IGlzIGVpdGhlclxuICAgLSBoYm94OiBob3Jpem9udGFsIGJveCAobm8gbGluZSBzcGxpdHRpbmcpXG4gICAtIHZib3g6IHZlcnRpY2FsIGJveCAoZXZlcnkgYnJlYWsgaGludCBzcGxpdHMgdGhlIGxpbmUpXG4gICAtIGh2Ym94OiBob3Jpem9udGFsL3ZlcnRpY2FsIGJveFxuICAgICAodGhlIGJveCBiZWhhdmVzIGFzIGFuIGhvcml6b250YWwgYm94IGlmIGl0IGZpdHMgb25cbiAgICAgIHRoZSBjdXJyZW50IGxpbmUsIG90aGVyd2lzZSB0aGUgYm94IGJlaGF2ZXMgYXMgYSB2ZXJ0aWNhbCBib3gpXG4gICAtIGhvdmJveDogaG9yaXpvbnRhbCBvciB2ZXJ0aWNhbCBjb21wYWN0aW5nIGJveFxuICAgICAodGhlIGJveCBpcyBjb21wYWN0aW5nIG1hdGVyaWFsLCBwcmludGluZyBhcyBtdWNoIG1hdGVyaWFsIGFzIHBvc3NpYmxlXG4gICAgICBvbiBldmVyeSBsaW5lcylcbiAgIC0gYm94OiBob3Jpem9udGFsIG9yIHZlcnRpY2FsIGNvbXBhY3RpbmcgYm94IHdpdGggZW5oYW5jZWQgYm94IHN0cnVjdHVyZVxuICAgICAodGhlIGJveCBiZWhhdmVzIGFzIGFuIGhvcml6b250YWwgb3IgdmVydGljYWwgYm94IGJ1dCBicmVhayBoaW50cyBzcGxpdFxuICAgICAgdGhlIGxpbmUgaWYgc3BsaXR0aW5nIHdvdWxkIG1vdmUgdG8gdGhlIGxlZnQpXG4qKVxudHlwZSBib3hfdHlwZSA9IENhbWxpbnRlcm5hbEZvcm1hdEJhc2ljcy5ibG9ja190eXBlID1cbiAgfCBQcF9oYm94IHwgUHBfdmJveCB8IFBwX2h2Ym94IHwgUHBfaG92Ym94IHwgUHBfYm94IHwgUHBfZml0c1xuXG5cbigqIFRoZSBwcmV0dHktcHJpbnRpbmcgdG9rZW5zIGRlZmluaXRpb246XG4gICBhcmUgZWl0aGVyIHRleHQgdG8gcHJpbnQgb3IgcHJldHR5IHByaW50aW5nXG4gICBlbGVtZW50cyB0aGF0IGRyaXZlIGluZGVudGF0aW9uIGFuZCBsaW5lIHNwbGl0dGluZy4gKilcbnR5cGUgcHBfdG9rZW4gPVxuICB8IFBwX3RleHQgb2Ygc3RyaW5nICAgICAgICAgICgqIG5vcm1hbCB0ZXh0ICopXG4gIHwgUHBfYnJlYWsgb2YgeyAgICAgICAgICAgICAgKCogY29tcGxldGUgYnJlYWsgKilcbiAgICAgIGZpdHM6IHN0cmluZyAqIGludCAqIHN0cmluZzsgICAoKiBsaW5lIGlzIG5vdCBzcGxpdCAqKVxuICAgICAgYnJlYWtzOiBzdHJpbmcgKiBpbnQgKiBzdHJpbmc7ICgqIGxpbmUgaXMgc3BsaXQgKilcbiAgICB9XG4gIHwgUHBfdGJyZWFrIG9mIGludCAqIGludCAgICAgKCogZ28gdG8gbmV4dCB0YWJ1bGF0aW9uICopXG4gIHwgUHBfc3RhYiAgICAgICAgICAgICAgICAgICAgKCogc2V0IGEgdGFidWxhdGlvbiAqKVxuICB8IFBwX2JlZ2luIG9mIGludCAqIGJveF90eXBlICgqIGJlZ2lubmluZyBvZiBhIGJveCAqKVxuICB8IFBwX2VuZCAgICAgICAgICAgICAgICAgICAgICgqIGVuZCBvZiBhIGJveCAqKVxuICB8IFBwX3RiZWdpbiBvZiB0Ym94ICAgICAgICAgICgqIGJlZ2lubmluZyBvZiBhIHRhYnVsYXRpb24gYm94ICopXG4gIHwgUHBfdGVuZCAgICAgICAgICAgICAgICAgICAgKCogZW5kIG9mIGEgdGFidWxhdGlvbiBib3ggKilcbiAgfCBQcF9uZXdsaW5lICAgICAgICAgICAgICAgICAoKiB0byBmb3JjZSBhIG5ld2xpbmUgaW5zaWRlIGEgYm94ICopXG4gIHwgUHBfaWZfbmV3bGluZSAgICAgICAgICAgICAgKCogdG8gZG8gc29tZXRoaW5nIG9ubHkgaWYgdGhpcyB2ZXJ5XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZSBoYXMgYmVlbiBicm9rZW4gKilcbiAgfCBQcF9vcGVuX3RhZyBvZiBzdGFnICAgICAgICAgKCogb3BlbmluZyBhIHRhZyBuYW1lICopXG4gIHwgUHBfY2xvc2VfdGFnICAgICAgICAgICAgICAgKCogY2xvc2luZyB0aGUgbW9zdCByZWNlbnRseSBvcGVuIHRhZyAqKVxuXG5hbmQgc3RhZyA9IC4uXG5cbmFuZCB0Ym94ID0gUHBfdGJveCBvZiBpbnQgbGlzdCByZWYgICgqIFRhYnVsYXRpb24gYm94ICopXG5cbnR5cGUgdGFnID0gc3RyaW5nXG50eXBlIHN0YWcgKz0gU3RyaW5nX3RhZyBvZiB0YWdcblxuXG4oKiBUaGUgcHJldHR5LXByaW50ZXIgcXVldWU6XG4gICBwcmV0dHktcHJpbnRpbmcgbWF0ZXJpYWwgaXMgbm90IHdyaXR0ZW4gaW4gdGhlIG91dHB1dCBhcyBzb29uIGFzIGVtaXR0ZWQ7XG4gICBpbnN0ZWFkLCB0aGUgbWF0ZXJpYWwgaXMgc2ltcGx5IHJlY29yZGVkIGluIHRoZSBwcmV0dHktcHJpbnRlciBxdWV1ZSxcbiAgIHVudGlsIHRoZSBlbmNsb3NpbmcgYm94IGhhcyBhIGtub3duIGNvbXB1dGVkIHNpemUgYW5kIHByb3BlciBzcGxpdHRpbmdcbiAgIGRlY2lzaW9ucyBjYW4gYmUgbWFkZS5cblxuICAgVGhlIHByZXR0eS1wcmludGVyIHF1ZXVlIGNvbnRhaW5zIGZvcm1hdHRpbmcgZWxlbWVudHMgdG8gYmUgcHJpbnRlZC5cbiAgIEVhY2ggZm9ybWF0dGluZyBlbGVtZW50IGlzIGEgdHVwbGUgKHNpemUsIHRva2VuLCBsZW5ndGgpLCB3aGVyZVxuICAgLSBsZW5ndGggaXMgdGhlIGRlY2xhcmVkIGxlbmd0aCBvZiB0aGUgdG9rZW4sXG4gICAtIHNpemUgaXMgZWZmZWN0aXZlIHNpemUgb2YgdGhlIHRva2VuIHdoZW4gaXQgaXMgcHJpbnRlZFxuICAgICAoc2l6ZSBpcyBzZXQgd2hlbiB0aGUgc2l6ZSBvZiB0aGUgYm94IGlzIGtub3duLCBzbyB0aGF0IHNpemUgb2YgYnJlYWtcbiAgICAgIGhpbnRzIGFyZSBkZWZpbml0aXZlKS4gKilcbnR5cGUgcHBfcXVldWVfZWxlbSA9IHtcbiAgbXV0YWJsZSBzaXplIDogU2l6ZS50O1xuICB0b2tlbiA6IHBwX3Rva2VuO1xuICBsZW5ndGggOiBpbnQ7XG59XG5cblxuKCogVGhlIHByZXR0eS1wcmludGVyIHF1ZXVlIGRlZmluaXRpb24uICopXG50eXBlIHBwX3F1ZXVlID0gcHBfcXVldWVfZWxlbSBRdWV1ZS50XG5cbigqIFRoZSBwcmV0dHktcHJpbnRlciBzY2FubmluZyBzdGFjay4gKilcblxuKCogVGhlIHByZXR0eS1wcmludGVyIHNjYW5uaW5nIHN0YWNrOiBzY2FubmluZyBlbGVtZW50IGRlZmluaXRpb24uICopXG50eXBlIHBwX3NjYW5fZWxlbSA9IHtcbiAgbGVmdF90b3RhbCA6IGludDsgKCogVmFsdWUgb2YgcHBfbGVmdF90b3RhbCB3aGVuIHRoZSBlbGVtZW50IHdhcyBlbnF1ZXVlZC4gKilcbiAgcXVldWVfZWxlbSA6IHBwX3F1ZXVlX2VsZW1cbn1cblxuKCogVGhlIHByZXR0eS1wcmludGVyIGZvcm1hdHRpbmcgc3RhY2s6XG4gICB0aGUgZm9ybWF0dGluZyBzdGFjayBjb250YWlucyB0aGUgZGVzY3JpcHRpb24gb2YgYWxsIHRoZSBjdXJyZW50bHkgYWN0aXZlXG4gICBib3hlczsgdGhlIHByZXR0eS1wcmludGVyIGZvcm1hdHRpbmcgc3RhY2sgaXMgdXNlZCB0byBzcGxpdCB0aGUgbGluZXNcbiAgIHdoaWxlIHByaW50aW5nIHRva2Vucy4gKilcblxuKCogVGhlIHByZXR0eS1wcmludGVyIGZvcm1hdHRpbmcgc3RhY2s6IGZvcm1hdHRpbmcgc3RhY2sgZWxlbWVudCBkZWZpbml0aW9uLlxuICAgRWFjaCBzdGFjayBlbGVtZW50IGRlc2NyaWJlcyBhIHByZXR0eS1wcmludGluZyBib3guICopXG50eXBlIHBwX2Zvcm1hdF9lbGVtID0geyBib3hfdHlwZSA6IGJveF90eXBlOyB3aWR0aCA6IGludCB9XG5cbigqIFRoZSBmb3JtYXR0ZXIgZGVmaW5pdGlvbi5cbiAgIEVhY2ggZm9ybWF0dGVyIHZhbHVlIGlzIGEgcHJldHR5LXByaW50ZXIgaW5zdGFuY2Ugd2l0aCBhbGwgaXRzXG4gICBtYWNoaW5lcnkuICopXG50eXBlIGZvcm1hdHRlciA9IHtcbiAgKCogVGhlIHByZXR0eS1wcmludGVyIHNjYW5uaW5nIHN0YWNrLiAqKVxuICBwcF9zY2FuX3N0YWNrIDogcHBfc2Nhbl9lbGVtIFN0YWNrLnQ7XG4gICgqIFRoZSBwcmV0dHktcHJpbnRlciBmb3JtYXR0aW5nIHN0YWNrLiAqKVxuICBwcF9mb3JtYXRfc3RhY2sgOiBwcF9mb3JtYXRfZWxlbSBTdGFjay50O1xuICBwcF90Ym94X3N0YWNrIDogdGJveCBTdGFjay50O1xuICAoKiBUaGUgcHJldHR5LXByaW50ZXIgc2VtYW50aWNzIHRhZyBzdGFjay4gKilcbiAgcHBfdGFnX3N0YWNrIDogc3RhZyBTdGFjay50O1xuICBwcF9tYXJrX3N0YWNrIDogc3RhZyBTdGFjay50O1xuICAoKiBWYWx1ZSBvZiByaWdodCBtYXJnaW4uICopXG4gIG11dGFibGUgcHBfbWFyZ2luIDogaW50O1xuICAoKiBNaW5pbWFsIHNwYWNlIGxlZnQgYmVmb3JlIG1hcmdpbiwgd2hlbiBvcGVuaW5nIGEgYm94LiAqKVxuICBtdXRhYmxlIHBwX21pbl9zcGFjZV9sZWZ0IDogaW50O1xuICAoKiBNYXhpbXVtIHZhbHVlIG9mIGluZGVudGF0aW9uOlxuICAgICBubyBib3ggY2FuIGJlIG9wZW5lZCBmdXJ0aGVyLiAqKVxuICBtdXRhYmxlIHBwX21heF9pbmRlbnQgOiBpbnQ7XG4gICgqIFNwYWNlIHJlbWFpbmluZyBvbiB0aGUgY3VycmVudCBsaW5lLiAqKVxuICBtdXRhYmxlIHBwX3NwYWNlX2xlZnQgOiBpbnQ7XG4gICgqIEN1cnJlbnQgdmFsdWUgb2YgaW5kZW50YXRpb24uICopXG4gIG11dGFibGUgcHBfY3VycmVudF9pbmRlbnQgOiBpbnQ7XG4gICgqIFRydWUgd2hlbiB0aGUgbGluZSBoYXMgYmVlbiBicm9rZW4gYnkgdGhlIHByZXR0eS1wcmludGVyLiAqKVxuICBtdXRhYmxlIHBwX2lzX25ld19saW5lIDogYm9vbDtcbiAgKCogVG90YWwgd2lkdGggb2YgdG9rZW5zIGFscmVhZHkgcHJpbnRlZC4gKilcbiAgbXV0YWJsZSBwcF9sZWZ0X3RvdGFsIDogaW50O1xuICAoKiBUb3RhbCB3aWR0aCBvZiB0b2tlbnMgZXZlciBwdXQgaW4gcXVldWUuICopXG4gIG11dGFibGUgcHBfcmlnaHRfdG90YWwgOiBpbnQ7XG4gICgqIEN1cnJlbnQgbnVtYmVyIG9mIG9wZW4gYm94ZXMuICopXG4gIG11dGFibGUgcHBfY3Vycl9kZXB0aCA6IGludDtcbiAgKCogTWF4aW11bSBudW1iZXIgb2YgYm94ZXMgd2hpY2ggY2FuIGJlIHNpbXVsdGFuZW91c2x5IG9wZW4uICopXG4gIG11dGFibGUgcHBfbWF4X2JveGVzIDogaW50O1xuICAoKiBFbGxpcHNpcyBzdHJpbmcuICopXG4gIG11dGFibGUgcHBfZWxsaXBzaXMgOiBzdHJpbmc7XG4gICgqIE91dHB1dCBmdW5jdGlvbi4gKilcbiAgbXV0YWJsZSBwcF9vdXRfc3RyaW5nIDogc3RyaW5nIC0+IGludCAtPiBpbnQgLT4gdW5pdDtcbiAgKCogRmx1c2hpbmcgZnVuY3Rpb24uICopXG4gIG11dGFibGUgcHBfb3V0X2ZsdXNoIDogdW5pdCAtPiB1bml0O1xuICAoKiBPdXRwdXQgb2YgbmV3IGxpbmVzLiAqKVxuICBtdXRhYmxlIHBwX291dF9uZXdsaW5lIDogdW5pdCAtPiB1bml0O1xuICAoKiBPdXRwdXQgb2YgYnJlYWsgaGludHMgc3BhY2VzLiAqKVxuICBtdXRhYmxlIHBwX291dF9zcGFjZXMgOiBpbnQgLT4gdW5pdDtcbiAgKCogT3V0cHV0IG9mIGluZGVudGF0aW9uIG9mIG5ldyBsaW5lcy4gKilcbiAgbXV0YWJsZSBwcF9vdXRfaW5kZW50IDogaW50IC0+IHVuaXQ7XG4gICgqIEFyZSB0YWdzIHByaW50ZWQgPyAqKVxuICBtdXRhYmxlIHBwX3ByaW50X3RhZ3MgOiBib29sO1xuICAoKiBBcmUgdGFncyBtYXJrZWQgPyAqKVxuICBtdXRhYmxlIHBwX21hcmtfdGFncyA6IGJvb2w7XG4gICgqIEZpbmQgb3BlbmluZyBhbmQgY2xvc2luZyBtYXJrZXJzIG9mIHRhZ3MuICopXG4gIG11dGFibGUgcHBfbWFya19vcGVuX3RhZyA6IHN0YWcgLT4gc3RyaW5nO1xuICBtdXRhYmxlIHBwX21hcmtfY2xvc2VfdGFnIDogc3RhZyAtPiBzdHJpbmc7XG4gIG11dGFibGUgcHBfcHJpbnRfb3Blbl90YWcgOiBzdGFnIC0+IHVuaXQ7XG4gIG11dGFibGUgcHBfcHJpbnRfY2xvc2VfdGFnIDogc3RhZyAtPiB1bml0O1xuICAoKiBUaGUgcHJldHR5LXByaW50ZXIgcXVldWUuICopXG4gIHBwX3F1ZXVlIDogcHBfcXVldWU7XG59XG5cblxuKCogVGhlIGZvcm1hdHRlciBzcGVjaWZpYyB0YWcgaGFuZGxpbmcgZnVuY3Rpb25zLiAqKVxudHlwZSBmb3JtYXR0ZXJfc3RhZ19mdW5jdGlvbnMgPSB7XG4gIG1hcmtfb3Blbl9zdGFnIDogc3RhZyAtPiBzdHJpbmc7XG4gIG1hcmtfY2xvc2Vfc3RhZyA6IHN0YWcgLT4gc3RyaW5nO1xuICBwcmludF9vcGVuX3N0YWcgOiBzdGFnIC0+IHVuaXQ7XG4gIHByaW50X2Nsb3NlX3N0YWcgOiBzdGFnIC0+IHVuaXQ7XG59XG5cblxuKCogVGhlIGZvcm1hdHRlciBmdW5jdGlvbnMgdG8gb3V0cHV0IG1hdGVyaWFsLiAqKVxudHlwZSBmb3JtYXR0ZXJfb3V0X2Z1bmN0aW9ucyA9IHtcbiAgb3V0X3N0cmluZyA6IHN0cmluZyAtPiBpbnQgLT4gaW50IC0+IHVuaXQ7XG4gIG91dF9mbHVzaCA6IHVuaXQgLT4gdW5pdDtcbiAgb3V0X25ld2xpbmUgOiB1bml0IC0+IHVuaXQ7XG4gIG91dF9zcGFjZXMgOiBpbnQgLT4gdW5pdDtcbiAgb3V0X2luZGVudCA6IGludCAtPiB1bml0O1xufVxuXG5cbigqXG5cbiAgQXV4aWxpYXJpZXMgYW5kIGJhc2ljIGZ1bmN0aW9ucy5cblxuKilcblxuKCogRW50ZXIgYSB0b2tlbiBpbiB0aGUgcHJldHR5LXByaW50ZXIgcXVldWUuICopXG5sZXQgcHBfZW5xdWV1ZSBzdGF0ZSB0b2tlbiA9XG4gIHN0YXRlLnBwX3JpZ2h0X3RvdGFsIDwtIHN0YXRlLnBwX3JpZ2h0X3RvdGFsICsgdG9rZW4ubGVuZ3RoO1xuICBRdWV1ZS5hZGQgdG9rZW4gc3RhdGUucHBfcXVldWVcblxuXG5sZXQgcHBfY2xlYXJfcXVldWUgc3RhdGUgPVxuICBzdGF0ZS5wcF9sZWZ0X3RvdGFsIDwtIDE7IHN0YXRlLnBwX3JpZ2h0X3RvdGFsIDwtIDE7XG4gIFF1ZXVlLmNsZWFyIHN0YXRlLnBwX3F1ZXVlXG5cblxuKCogUHBfaW5maW5pdHk6IGxhcmdlIHZhbHVlIGZvciBkZWZhdWx0IHRva2VucyBzaXplLlxuXG4gICBQcF9pbmZpbml0eSBpcyBkb2N1bWVudGVkIGFzIGJlaW5nIGdyZWF0ZXIgdGhhbiAxZTEwOyB0byBhdm9pZFxuICAgY29uZnVzaW9uIGFib3V0IHRoZSB3b3JkICdncmVhdGVyJywgd2UgY2hvb3NlIHBwX2luZmluaXR5IGdyZWF0ZXJcbiAgIHRoYW4gMWUxMCArIDE7IGZvciBjb3JyZWN0IGhhbmRsaW5nIG9mIHRlc3RzIGluIHRoZSBhbGdvcml0aG0sXG4gICBwcF9pbmZpbml0eSBtdXN0IGJlIGV2ZW4gb25lIG1vcmUgdGhhbiAxZTEwICsgMTsgbGV0J3Mgc3RhbmQgb24gdGhlXG4gICBzYWZlIHNpZGUgYnkgY2hvb3NpbmcgMS5lMTArMTAuXG5cbiAgIFBwX2luZmluaXR5IGNvdWxkIHByb2JhYmx5IGJlIDEwNzM3NDE4MjMgdGhhdCBpcyAyXjMwIC0gMSwgdGhhdCBpc1xuICAgdGhlIG1pbmltYWwgdXBwZXIgYm91bmQgZm9yIGludGVnZXJzOyBub3cgdGhhdCBtYXhfaW50IGlzIGRlZmluZWQsXG4gICB0aGlzIGxpbWl0IGNvdWxkIGFsc28gYmUgZGVmaW5lZCBhcyBtYXhfaW50IC0gMS5cblxuICAgSG93ZXZlciwgYmVmb3JlIHNldHRpbmcgcHBfaW5maW5pdHkgdG8gc29tZXRoaW5nIGFyb3VuZCBtYXhfaW50LCB3ZVxuICAgbXVzdCBjYXJlZnVsbHkgZG91YmxlLWNoZWNrIGFsbCB0aGUgaW50ZWdlciBhcml0aG1ldGljIG9wZXJhdGlvbnNcbiAgIHRoYXQgaW52b2x2ZSBwcF9pbmZpbml0eSwgc2luY2UgYW55IG92ZXJmbG93IHdvdWxkIHdyZWNrIGhhdm9jIHRoZVxuICAgcHJldHR5LXByaW50aW5nIGFsZ29yaXRobSdzIGludmFyaWFudHMuIEdpdmVuIHRoYXQgdGhpcyBhcml0aG1ldGljXG4gICBjb3JyZWN0bmVzcyBjaGVjayBpcyBkaWZmaWN1bHQgYW5kIGVycm9yIHByb25lIGFuZCBnaXZlbiB0aGF0IDFlMTBcbiAgICsgMSBpcyBpbiBwcmFjdGljZSBsYXJnZSBlbm91Z2gsIHRoZXJlIGlzIG5vIG5lZWQgdG8gYXR0ZW1wdCB0byBzZXRcbiAgIHBwX2luZmluaXR5IHRvIHRoZSB0aGVvcmV0aWNhbGx5IG1heGltdW0gbGltaXQuIEl0IGlzIG5vdCB3b3J0aCB0aGVcbiAgIGJ1cmRlbiAhICopXG5sZXQgcHBfaW5maW5pdHkgPSAxMDAwMDAwMDEwXG5cbigqIE91dHB1dCBmdW5jdGlvbnMgZm9yIHRoZSBmb3JtYXR0ZXIuICopXG5sZXQgcHBfb3V0cHV0X3N0cmluZyBzdGF0ZSBzID0gc3RhdGUucHBfb3V0X3N0cmluZyBzIDAgKFN0cmluZy5sZW5ndGggcylcbmFuZCBwcF9vdXRwdXRfbmV3bGluZSBzdGF0ZSA9IHN0YXRlLnBwX291dF9uZXdsaW5lICgpXG5hbmQgcHBfb3V0cHV0X3NwYWNlcyBzdGF0ZSBuID0gc3RhdGUucHBfb3V0X3NwYWNlcyBuXG5hbmQgcHBfb3V0cHV0X2luZGVudCBzdGF0ZSBuID0gc3RhdGUucHBfb3V0X2luZGVudCBuXG5cbigqIEZvcm1hdCBhIHRleHR1YWwgdG9rZW4gKilcbmxldCBmb3JtYXRfcHBfdGV4dCBzdGF0ZSBzaXplIHRleHQgPVxuICBzdGF0ZS5wcF9zcGFjZV9sZWZ0IDwtIHN0YXRlLnBwX3NwYWNlX2xlZnQgLSBzaXplO1xuICBwcF9vdXRwdXRfc3RyaW5nIHN0YXRlIHRleHQ7XG4gIHN0YXRlLnBwX2lzX25ld19saW5lIDwtIGZhbHNlXG5cbigqIEZvcm1hdCBhIHN0cmluZyBieSBpdHMgbGVuZ3RoLCBpZiBub3QgZW1wdHkgKilcbmxldCBmb3JtYXRfc3RyaW5nIHN0YXRlIHMgPVxuICBpZiBzIDw+IFwiXCIgdGhlbiBmb3JtYXRfcHBfdGV4dCBzdGF0ZSAoU3RyaW5nLmxlbmd0aCBzKSBzXG5cbigqIFRvIGZvcm1hdCBhIGJyZWFrLCBpbmRlbnRpbmcgYSBuZXcgbGluZS4gKilcbmxldCBicmVha19uZXdfbGluZSBzdGF0ZSAoYmVmb3JlLCBvZmZzZXQsIGFmdGVyKSB3aWR0aCA9XG4gIGZvcm1hdF9zdHJpbmcgc3RhdGUgYmVmb3JlO1xuICBwcF9vdXRwdXRfbmV3bGluZSBzdGF0ZTtcbiAgc3RhdGUucHBfaXNfbmV3X2xpbmUgPC0gdHJ1ZTtcbiAgbGV0IGluZGVudCA9IHN0YXRlLnBwX21hcmdpbiAtIHdpZHRoICsgb2Zmc2V0IGluXG4gICgqIERvbid0IGluZGVudCBtb3JlIHRoYW4gcHBfbWF4X2luZGVudC4gKilcbiAgbGV0IHJlYWxfaW5kZW50ID0gSW50Lm1pbiBzdGF0ZS5wcF9tYXhfaW5kZW50IGluZGVudCBpblxuICBzdGF0ZS5wcF9jdXJyZW50X2luZGVudCA8LSByZWFsX2luZGVudDtcbiAgc3RhdGUucHBfc3BhY2VfbGVmdCA8LSBzdGF0ZS5wcF9tYXJnaW4gLSBzdGF0ZS5wcF9jdXJyZW50X2luZGVudDtcbiAgcHBfb3V0cHV0X2luZGVudCBzdGF0ZSBzdGF0ZS5wcF9jdXJyZW50X2luZGVudDtcbiAgZm9ybWF0X3N0cmluZyBzdGF0ZSBhZnRlclxuXG5cbigqIFRvIGZvcmNlIGEgbGluZSBicmVhayBpbnNpZGUgYSBib3g6IG5vIG9mZnNldCBpcyBhZGRlZC4gKilcbmxldCBicmVha19saW5lIHN0YXRlIHdpZHRoID0gYnJlYWtfbmV3X2xpbmUgc3RhdGUgKFwiXCIsIDAsIFwiXCIpIHdpZHRoXG5cbigqIFRvIGZvcm1hdCBhIGJyZWFrIHRoYXQgZml0cyBvbiB0aGUgY3VycmVudCBsaW5lLiAqKVxubGV0IGJyZWFrX3NhbWVfbGluZSBzdGF0ZSAoYmVmb3JlLCB3aWR0aCwgYWZ0ZXIpID1cbiAgZm9ybWF0X3N0cmluZyBzdGF0ZSBiZWZvcmU7XG4gIHN0YXRlLnBwX3NwYWNlX2xlZnQgPC0gc3RhdGUucHBfc3BhY2VfbGVmdCAtIHdpZHRoO1xuICBwcF9vdXRwdXRfc3BhY2VzIHN0YXRlIHdpZHRoO1xuICBmb3JtYXRfc3RyaW5nIHN0YXRlIGFmdGVyXG5cblxuKCogVG8gaW5kZW50IG5vIG1vcmUgdGhhbiBwcF9tYXhfaW5kZW50LCBpZiBvbmUgdHJpZXMgdG8gb3BlbiBhIGJveFxuICAgYmV5b25kIHBwX21heF9pbmRlbnQsIHRoZW4gdGhlIGJveCBpcyByZWplY3RlZCBvbiB0aGUgbGVmdFxuICAgYnkgc2ltdWxhdGluZyBhIGJyZWFrLiAqKVxubGV0IHBwX2ZvcmNlX2JyZWFrX2xpbmUgc3RhdGUgPVxuICBtYXRjaCBTdGFjay50b3Bfb3B0IHN0YXRlLnBwX2Zvcm1hdF9zdGFjayB3aXRoXG4gIHwgTm9uZSAtPiBwcF9vdXRwdXRfbmV3bGluZSBzdGF0ZVxuICB8IFNvbWUgeyBib3hfdHlwZTsgd2lkdGggfSAtPlxuICAgIGlmIHdpZHRoID4gc3RhdGUucHBfc3BhY2VfbGVmdCB0aGVuXG4gICAgICBtYXRjaCBib3hfdHlwZSB3aXRoXG4gICAgICB8IFBwX2ZpdHMgfCBQcF9oYm94IC0+ICgpXG4gICAgICB8IFBwX3Zib3ggfCBQcF9odmJveCB8IFBwX2hvdmJveCB8IFBwX2JveCAtPiBicmVha19saW5lIHN0YXRlIHdpZHRoXG5cblxuKCogVG8gc2tpcCBhIHRva2VuLCBpZiB0aGUgcHJldmlvdXMgbGluZSBoYXMgYmVlbiBicm9rZW4uICopXG5sZXQgcHBfc2tpcF90b2tlbiBzdGF0ZSA9XG4gIG1hdGNoIFF1ZXVlLnRha2Vfb3B0IHN0YXRlLnBwX3F1ZXVlIHdpdGhcbiAgfCBOb25lIC0+ICgpICgqIHByaW50X2lmX25ld2xpbmUgbXVzdCBoYXZlIGJlZW4gdGhlIGxhc3QgcHJpbnRpbmcgY29tbWFuZCAqKVxuICB8IFNvbWUgeyBzaXplOyBsZW5ndGg7IF8gfSAtPlxuICAgIHN0YXRlLnBwX2xlZnRfdG90YWwgPC0gc3RhdGUucHBfbGVmdF90b3RhbCAtIGxlbmd0aDtcbiAgICBzdGF0ZS5wcF9zcGFjZV9sZWZ0IDwtIHN0YXRlLnBwX3NwYWNlX2xlZnQgKyBTaXplLnRvX2ludCBzaXplXG5cblxuKCpcblxuICBUaGUgbWFpbiBwcmV0dHkgcHJpbnRpbmcgZnVuY3Rpb25zLlxuXG4qKVxuXG4oKiBGb3JtYXR0aW5nIGEgdG9rZW4gd2l0aCBhIGdpdmVuIHNpemUuICopXG5sZXQgZm9ybWF0X3BwX3Rva2VuIHN0YXRlIHNpemUgPSBmdW5jdGlvblxuXG4gIHwgUHBfdGV4dCBzIC0+XG4gICAgZm9ybWF0X3BwX3RleHQgc3RhdGUgc2l6ZSBzXG5cbiAgfCBQcF9iZWdpbiAob2ZmLCB0eSkgLT5cbiAgICBsZXQgaW5zZXJ0aW9uX3BvaW50ID0gc3RhdGUucHBfbWFyZ2luIC0gc3RhdGUucHBfc3BhY2VfbGVmdCBpblxuICAgIGlmIGluc2VydGlvbl9wb2ludCA+IHN0YXRlLnBwX21heF9pbmRlbnQgdGhlblxuICAgICAgKCogY2FuIG5vdCBvcGVuIGEgYm94IHJpZ2h0IHRoZXJlLiAqKVxuICAgICAgYmVnaW4gcHBfZm9yY2VfYnJlYWtfbGluZSBzdGF0ZSBlbmQ7XG4gICAgbGV0IHdpZHRoID0gc3RhdGUucHBfc3BhY2VfbGVmdCAtIG9mZiBpblxuICAgIGxldCBib3hfdHlwZSA9XG4gICAgICBtYXRjaCB0eSB3aXRoXG4gICAgICB8IFBwX3Zib3ggLT4gUHBfdmJveFxuICAgICAgfCBQcF9oYm94IHwgUHBfaHZib3ggfCBQcF9ob3Zib3ggfCBQcF9ib3ggfCBQcF9maXRzIC0+XG4gICAgICAgIGlmIHNpemUgPiBzdGF0ZS5wcF9zcGFjZV9sZWZ0IHRoZW4gdHkgZWxzZSBQcF9maXRzIGluXG4gICAgU3RhY2sucHVzaCB7IGJveF90eXBlOyB3aWR0aCB9IHN0YXRlLnBwX2Zvcm1hdF9zdGFja1xuXG4gIHwgUHBfZW5kIC0+XG4gICAgU3RhY2sucG9wX29wdCBzdGF0ZS5wcF9mb3JtYXRfc3RhY2sgfD4gaWdub3JlXG5cbiAgfCBQcF90YmVnaW4gKFBwX3Rib3ggXyBhcyB0Ym94KSAtPlxuICAgIFN0YWNrLnB1c2ggdGJveCBzdGF0ZS5wcF90Ym94X3N0YWNrXG5cbiAgfCBQcF90ZW5kIC0+XG4gICAgU3RhY2sucG9wX29wdCBzdGF0ZS5wcF90Ym94X3N0YWNrIHw+IGlnbm9yZVxuXG4gIHwgUHBfc3RhYiAtPlxuICAgIGJlZ2luIG1hdGNoIFN0YWNrLnRvcF9vcHQgc3RhdGUucHBfdGJveF9zdGFjayB3aXRoXG4gICAgfCBOb25lIC0+ICgpICgqIE5vIG9wZW4gdGFidWxhdGlvbiBib3guICopXG4gICAgfCBTb21lIChQcF90Ym94IHRhYnMpIC0+XG4gICAgICBsZXQgcmVjIGFkZF90YWIgbiA9IGZ1bmN0aW9uXG4gICAgICAgIHwgW10gLT4gW25dXG4gICAgICAgIHwgeCA6OiBsIGFzIGxzIC0+IGlmIG4gPCB4IHRoZW4gbiA6OiBscyBlbHNlIHggOjogYWRkX3RhYiBuIGwgaW5cbiAgICAgIHRhYnMgOj0gYWRkX3RhYiAoc3RhdGUucHBfbWFyZ2luIC0gc3RhdGUucHBfc3BhY2VfbGVmdCkgIXRhYnNcbiAgICBlbmRcblxuICB8IFBwX3RicmVhayAobiwgb2ZmKSAtPlxuICAgIGxldCBpbnNlcnRpb25fcG9pbnQgPSBzdGF0ZS5wcF9tYXJnaW4gLSBzdGF0ZS5wcF9zcGFjZV9sZWZ0IGluXG4gICAgYmVnaW4gbWF0Y2ggU3RhY2sudG9wX29wdCBzdGF0ZS5wcF90Ym94X3N0YWNrIHdpdGhcbiAgICB8IE5vbmUgLT4gKCkgKCogTm8gb3BlbiB0YWJ1bGF0aW9uIGJveC4gKilcbiAgICB8IFNvbWUgKFBwX3Rib3ggdGFicykgLT5cbiAgICAgIGxldCB0YWIgPVxuICAgICAgICBtYXRjaCAhdGFicyB3aXRoXG4gICAgICAgIHwgW10gLT4gaW5zZXJ0aW9uX3BvaW50XG4gICAgICAgIHwgZmlyc3QgOjogXyAtPlxuICAgICAgICAgIGxldCByZWMgZmluZCA9IGZ1bmN0aW9uXG4gICAgICAgICAgICB8IGhlYWQgOjogdGFpbCAtPlxuICAgICAgICAgICAgICBpZiBoZWFkID49IGluc2VydGlvbl9wb2ludCB0aGVuIGhlYWQgZWxzZSBmaW5kIHRhaWxcbiAgICAgICAgICAgIHwgW10gLT4gZmlyc3QgaW5cbiAgICAgICAgICBmaW5kICF0YWJzIGluXG4gICAgICBsZXQgb2Zmc2V0ID0gdGFiIC0gaW5zZXJ0aW9uX3BvaW50IGluXG4gICAgICBpZiBvZmZzZXQgPj0gMFxuICAgICAgdGhlbiBicmVha19zYW1lX2xpbmUgc3RhdGUgKFwiXCIsIG9mZnNldCArIG4sIFwiXCIpXG4gICAgICBlbHNlIGJyZWFrX25ld19saW5lIHN0YXRlIChcIlwiLCB0YWIgKyBvZmYsIFwiXCIpIHN0YXRlLnBwX21hcmdpblxuICAgIGVuZFxuXG4gIHwgUHBfbmV3bGluZSAtPlxuICAgIGJlZ2luIG1hdGNoIFN0YWNrLnRvcF9vcHQgc3RhdGUucHBfZm9ybWF0X3N0YWNrIHdpdGhcbiAgICB8IE5vbmUgLT4gcHBfb3V0cHV0X25ld2xpbmUgc3RhdGUgKCogTm8gb3BlbiBib3guICopXG4gICAgfCBTb21lIHsgd2lkdGg7IF99IC0+IGJyZWFrX2xpbmUgc3RhdGUgd2lkdGhcbiAgICBlbmRcblxuICB8IFBwX2lmX25ld2xpbmUgLT5cbiAgICBpZiBzdGF0ZS5wcF9jdXJyZW50X2luZGVudCAhPSBzdGF0ZS5wcF9tYXJnaW4gLSBzdGF0ZS5wcF9zcGFjZV9sZWZ0XG4gICAgdGhlbiBwcF9za2lwX3Rva2VuIHN0YXRlXG5cbiAgfCBQcF9icmVhayB7IGZpdHM7IGJyZWFrcyB9IC0+XG4gICAgbGV0IGJlZm9yZSwgb2ZmLCBfID0gYnJlYWtzIGluXG4gICAgYmVnaW4gbWF0Y2ggU3RhY2sudG9wX29wdCBzdGF0ZS5wcF9mb3JtYXRfc3RhY2sgd2l0aFxuICAgIHwgTm9uZSAtPiAoKSAoKiBObyBvcGVuIGJveC4gKilcbiAgICB8IFNvbWUgeyBib3hfdHlwZTsgd2lkdGggfSAtPlxuICAgICAgYmVnaW4gbWF0Y2ggYm94X3R5cGUgd2l0aFxuICAgICAgfCBQcF9ob3Zib3ggLT5cbiAgICAgICAgaWYgc2l6ZSArIFN0cmluZy5sZW5ndGggYmVmb3JlID4gc3RhdGUucHBfc3BhY2VfbGVmdFxuICAgICAgICB0aGVuIGJyZWFrX25ld19saW5lIHN0YXRlIGJyZWFrcyB3aWR0aFxuICAgICAgICBlbHNlIGJyZWFrX3NhbWVfbGluZSBzdGF0ZSBmaXRzXG4gICAgICB8IFBwX2JveCAtPlxuICAgICAgICAoKiBIYXZlIHRoZSBsaW5lIGp1c3QgYmVlbiBicm9rZW4gaGVyZSA/ICopXG4gICAgICAgIGlmIHN0YXRlLnBwX2lzX25ld19saW5lIHRoZW4gYnJlYWtfc2FtZV9saW5lIHN0YXRlIGZpdHMgZWxzZVxuICAgICAgICBpZiBzaXplICsgU3RyaW5nLmxlbmd0aCBiZWZvcmUgPiBzdGF0ZS5wcF9zcGFjZV9sZWZ0XG4gICAgICAgICAgdGhlbiBicmVha19uZXdfbGluZSBzdGF0ZSBicmVha3Mgd2lkdGggZWxzZVxuICAgICAgICAoKiBicmVhayB0aGUgbGluZSBoZXJlIGxlYWRzIHRvIG5ldyBpbmRlbnRhdGlvbiA/ICopXG4gICAgICAgIGlmIHN0YXRlLnBwX2N1cnJlbnRfaW5kZW50ID4gc3RhdGUucHBfbWFyZ2luIC0gd2lkdGggKyBvZmZcbiAgICAgICAgdGhlbiBicmVha19uZXdfbGluZSBzdGF0ZSBicmVha3Mgd2lkdGhcbiAgICAgICAgZWxzZSBicmVha19zYW1lX2xpbmUgc3RhdGUgZml0c1xuICAgICAgfCBQcF9odmJveCAtPiBicmVha19uZXdfbGluZSBzdGF0ZSBicmVha3Mgd2lkdGhcbiAgICAgIHwgUHBfZml0cyAtPiBicmVha19zYW1lX2xpbmUgc3RhdGUgZml0c1xuICAgICAgfCBQcF92Ym94IC0+IGJyZWFrX25ld19saW5lIHN0YXRlIGJyZWFrcyB3aWR0aFxuICAgICAgfCBQcF9oYm94IC0+IGJyZWFrX3NhbWVfbGluZSBzdGF0ZSBmaXRzXG4gICAgICBlbmRcbiAgICBlbmRcblxuICAgfCBQcF9vcGVuX3RhZyB0YWdfbmFtZSAtPlxuICAgICBsZXQgbWFya2VyID0gc3RhdGUucHBfbWFya19vcGVuX3RhZyB0YWdfbmFtZSBpblxuICAgICBwcF9vdXRwdXRfc3RyaW5nIHN0YXRlIG1hcmtlcjtcbiAgICAgU3RhY2sucHVzaCB0YWdfbmFtZSBzdGF0ZS5wcF9tYXJrX3N0YWNrXG5cbiAgIHwgUHBfY2xvc2VfdGFnIC0+XG4gICAgIGJlZ2luIG1hdGNoIFN0YWNrLnBvcF9vcHQgc3RhdGUucHBfbWFya19zdGFjayB3aXRoXG4gICAgIHwgTm9uZSAtPiAoKSAoKiBObyBtb3JlIHRhZyB0byBjbG9zZS4gKilcbiAgICAgfCBTb21lIHRhZ19uYW1lIC0+XG4gICAgICAgbGV0IG1hcmtlciA9IHN0YXRlLnBwX21hcmtfY2xvc2VfdGFnIHRhZ19uYW1lIGluXG4gICAgICAgcHBfb3V0cHV0X3N0cmluZyBzdGF0ZSBtYXJrZXJcbiAgICAgZW5kXG5cblxuKCogUHJpbnQgaWYgdG9rZW4gc2l6ZSBpcyBrbm93biBlbHNlIHByaW50aW5nIGlzIGRlbGF5ZWQuXG4gICBQcmludGluZyBpcyBkZWxheWVkIHdoZW4gdGhlIHRleHQgd2FpdGluZyBpbiB0aGUgcXVldWUgcmVxdWlyZXNcbiAgIG1vcmUgcm9vbSB0byBmb3JtYXQgdGhhbiBleGlzdHMgb24gdGhlIGN1cnJlbnQgbGluZS4gKilcbmxldCByZWMgYWR2YW5jZV9sZWZ0IHN0YXRlID1cbiAgbWF0Y2ggUXVldWUucGVla19vcHQgc3RhdGUucHBfcXVldWUgd2l0aFxuICB8IE5vbmUgLT4gKCkgKCogTm8gdG9rZW5zIHRvIHByaW50ICopXG4gIHwgU29tZSB7IHNpemU7IHRva2VuOyBsZW5ndGggfSAtPlxuICAgIGxldCBwZW5kaW5nX2NvdW50ID0gc3RhdGUucHBfcmlnaHRfdG90YWwgLSBzdGF0ZS5wcF9sZWZ0X3RvdGFsIGluXG4gICAgaWYgU2l6ZS5pc19rbm93biBzaXplIHx8IHBlbmRpbmdfY291bnQgPj0gc3RhdGUucHBfc3BhY2VfbGVmdCB0aGVuIGJlZ2luXG4gICAgICBRdWV1ZS50YWtlIHN0YXRlLnBwX3F1ZXVlIHw+IGlnbm9yZTsgKCogTm90IGVtcHR5OiB3ZSBwZWVrIGludG8gaXQgKilcbiAgICAgIGxldCBzaXplID0gaWYgU2l6ZS5pc19rbm93biBzaXplIHRoZW4gU2l6ZS50b19pbnQgc2l6ZSBlbHNlIHBwX2luZmluaXR5IGluXG4gICAgICBmb3JtYXRfcHBfdG9rZW4gc3RhdGUgc2l6ZSB0b2tlbjtcbiAgICAgIHN0YXRlLnBwX2xlZnRfdG90YWwgPC0gbGVuZ3RoICsgc3RhdGUucHBfbGVmdF90b3RhbDtcbiAgICAgIChhZHZhbmNlX2xlZnQgW0B0YWlsY2FsbF0pIHN0YXRlXG4gICAgZW5kXG5cblxuKCogVG8gZW5xdWV1ZSBhIHRva2VuIDogdHJ5IHRvIGFkdmFuY2UuICopXG5sZXQgZW5xdWV1ZV9hZHZhbmNlIHN0YXRlIHRvayA9IHBwX2VucXVldWUgc3RhdGUgdG9rOyBhZHZhbmNlX2xlZnQgc3RhdGVcblxuXG4oKiBUbyBlbnF1ZXVlIHN0cmluZ3MuICopXG5sZXQgZW5xdWV1ZV9zdHJpbmdfYXMgc3RhdGUgc2l6ZSBzID1cbiAgZW5xdWV1ZV9hZHZhbmNlIHN0YXRlIHsgc2l6ZTsgdG9rZW4gPSBQcF90ZXh0IHM7IGxlbmd0aCA9IFNpemUudG9faW50IHNpemUgfVxuXG5cbmxldCBlbnF1ZXVlX3N0cmluZyBzdGF0ZSBzID1cbiAgZW5xdWV1ZV9zdHJpbmdfYXMgc3RhdGUgKFNpemUub2ZfaW50IChTdHJpbmcubGVuZ3RoIHMpKSBzXG5cblxuKCogUm91dGluZXMgZm9yIHNjYW4gc3RhY2tcbiAgIGRldGVybWluZSBzaXplIG9mIGJveGVzLiAqKVxuXG4oKiBUaGUgc2Nhbl9zdGFjayBpcyBuZXZlciBlbXB0eS4gKilcbmxldCBpbml0aWFsaXplX3NjYW5fc3RhY2sgc3RhY2sgPVxuICBTdGFjay5jbGVhciBzdGFjaztcbiAgbGV0IHF1ZXVlX2VsZW0gPSB7IHNpemUgPSBTaXplLnVua25vd247IHRva2VuID0gUHBfdGV4dCBcIlwiOyBsZW5ndGggPSAwIH0gaW5cbiAgU3RhY2sucHVzaCB7IGxlZnRfdG90YWwgPSAtMTsgcXVldWVfZWxlbSB9IHN0YWNrXG5cbigqIFNldHRpbmcgdGhlIHNpemUgb2YgYm94ZXMgb24gc2NhbiBzdGFjazpcbiAgIGlmIHR5ID0gdHJ1ZSB0aGVuIHNpemUgb2YgYnJlYWsgaXMgc2V0IGVsc2Ugc2l6ZSBvZiBib3ggaXMgc2V0O1xuICAgaW4gZWFjaCBjYXNlIHBwX3NjYW5fc3RhY2sgaXMgcG9wcGVkLlxuXG4gICBOb3RlOlxuICAgUGF0dGVybiBtYXRjaGluZyBvbiBzY2FuIHN0YWNrIGlzIGV4aGF1c3RpdmUsIHNpbmNlIHNjYW5fc3RhY2sgaXMgbmV2ZXJcbiAgIGVtcHR5LlxuICAgUGF0dGVybiBtYXRjaGluZyBvbiB0b2tlbiBpbiBzY2FuIHN0YWNrIGlzIGFsc28gZXhoYXVzdGl2ZSxcbiAgIHNpbmNlIHNjYW5fcHVzaCBpcyB1c2VkIG9uIGJyZWFrcyBhbmQgb3BlbmluZyBvZiBib3hlcy4gKilcbmxldCBzZXRfc2l6ZSBzdGF0ZSB0eSA9XG4gIG1hdGNoIFN0YWNrLnRvcF9vcHQgc3RhdGUucHBfc2Nhbl9zdGFjayB3aXRoXG4gIHwgTm9uZSAtPiAoKSAoKiBzY2FuX3N0YWNrIGlzIG5ldmVyIGVtcHR5LiAqKVxuICB8IFNvbWUgeyBsZWZ0X3RvdGFsOyBxdWV1ZV9lbGVtIH0gLT5cbiAgICBsZXQgc2l6ZSA9IFNpemUudG9faW50IHF1ZXVlX2VsZW0uc2l6ZSBpblxuICAgICgqIHRlc3QgaWYgc2NhbiBzdGFjayBjb250YWlucyBhbnkgZGF0YSB0aGF0IGlzIG5vdCBvYnNvbGV0ZS4gKilcbiAgICBpZiBsZWZ0X3RvdGFsIDwgc3RhdGUucHBfbGVmdF90b3RhbCB0aGVuXG4gICAgICBpbml0aWFsaXplX3NjYW5fc3RhY2sgc3RhdGUucHBfc2Nhbl9zdGFja1xuICAgIGVsc2VcbiAgICAgIG1hdGNoIHF1ZXVlX2VsZW0udG9rZW4gd2l0aFxuICAgICAgfCBQcF9icmVhayBfIHwgUHBfdGJyZWFrIChfLCBfKSAtPlxuICAgICAgICBpZiB0eSB0aGVuIGJlZ2luXG4gICAgICAgICAgcXVldWVfZWxlbS5zaXplIDwtIFNpemUub2ZfaW50IChzdGF0ZS5wcF9yaWdodF90b3RhbCArIHNpemUpO1xuICAgICAgICAgIFN0YWNrLnBvcF9vcHQgc3RhdGUucHBfc2Nhbl9zdGFjayB8PiBpZ25vcmVcbiAgICAgICAgZW5kXG4gICAgICB8IFBwX2JlZ2luIChfLCBfKSAtPlxuICAgICAgICBpZiBub3QgdHkgdGhlbiBiZWdpblxuICAgICAgICAgIHF1ZXVlX2VsZW0uc2l6ZSA8LSBTaXplLm9mX2ludCAoc3RhdGUucHBfcmlnaHRfdG90YWwgKyBzaXplKTtcbiAgICAgICAgICBTdGFjay5wb3Bfb3B0IHN0YXRlLnBwX3NjYW5fc3RhY2sgfD4gaWdub3JlXG4gICAgICAgIGVuZFxuICAgICAgfCBQcF90ZXh0IF8gfCBQcF9zdGFiIHwgUHBfdGJlZ2luIF8gfCBQcF90ZW5kIHwgUHBfZW5kXG4gICAgICB8IFBwX25ld2xpbmUgfCBQcF9pZl9uZXdsaW5lIHwgUHBfb3Blbl90YWcgXyB8IFBwX2Nsb3NlX3RhZyAtPlxuICAgICAgICAoKSAoKiBzY2FuX3B1c2ggaXMgb25seSB1c2VkIGZvciBicmVha3MgYW5kIGJveGVzLiAqKVxuXG5cbigqIFB1c2ggYSB0b2tlbiBvbiBwcmV0dHktcHJpbnRlciBzY2FubmluZyBzdGFjay5cbiAgIElmIGIgaXMgdHJ1ZSBzZXRfc2l6ZSBpcyBjYWxsZWQuICopXG5sZXQgc2Nhbl9wdXNoIHN0YXRlIGIgdG9rZW4gPVxuICBwcF9lbnF1ZXVlIHN0YXRlIHRva2VuO1xuICBpZiBiIHRoZW4gc2V0X3NpemUgc3RhdGUgdHJ1ZTtcbiAgbGV0IGVsZW0gPSB7IGxlZnRfdG90YWwgPSBzdGF0ZS5wcF9yaWdodF90b3RhbDsgcXVldWVfZWxlbSA9IHRva2VuIH0gaW5cbiAgU3RhY2sucHVzaCBlbGVtIHN0YXRlLnBwX3NjYW5fc3RhY2tcblxuXG4oKiBUbyBvcGVuIGEgbmV3IGJveCA6XG4gICB0aGUgdXNlciBtYXkgc2V0IHRoZSBkZXB0aCBib3VuZCBwcF9tYXhfYm94ZXNcbiAgIGFueSB0ZXh0IG5lc3RlZCBkZWVwZXIgaXMgcHJpbnRlZCBhcyB0aGUgZWxsaXBzaXMgc3RyaW5nLiAqKVxubGV0IHBwX29wZW5fYm94X2dlbiBzdGF0ZSBpbmRlbnQgYnJfdHkgPVxuICBzdGF0ZS5wcF9jdXJyX2RlcHRoIDwtIHN0YXRlLnBwX2N1cnJfZGVwdGggKyAxO1xuICBpZiBzdGF0ZS5wcF9jdXJyX2RlcHRoIDwgc3RhdGUucHBfbWF4X2JveGVzIHRoZW5cbiAgICBsZXQgc2l6ZSA9IFNpemUub2ZfaW50ICgtIHN0YXRlLnBwX3JpZ2h0X3RvdGFsKSBpblxuICAgIGxldCBlbGVtID0geyBzaXplOyB0b2tlbiA9IFBwX2JlZ2luIChpbmRlbnQsIGJyX3R5KTsgbGVuZ3RoID0gMCB9IGluXG4gICAgc2Nhbl9wdXNoIHN0YXRlIGZhbHNlIGVsZW0gZWxzZVxuICBpZiBzdGF0ZS5wcF9jdXJyX2RlcHRoID0gc3RhdGUucHBfbWF4X2JveGVzXG4gIHRoZW4gZW5xdWV1ZV9zdHJpbmcgc3RhdGUgc3RhdGUucHBfZWxsaXBzaXNcblxuXG4oKiBUaGUgYm94IHdoaWNoIGlzIGFsd2F5cyBvcGVuLiAqKVxubGV0IHBwX29wZW5fc3lzX2JveCBzdGF0ZSA9IHBwX29wZW5fYm94X2dlbiBzdGF0ZSAwIFBwX2hvdmJveFxuXG4oKiBDbG9zZSBhIGJveCwgc2V0dGluZyBzaXplcyBvZiBpdHMgc3ViIGJveGVzLiAqKVxubGV0IHBwX2Nsb3NlX2JveCBzdGF0ZSAoKSA9XG4gIGlmIHN0YXRlLnBwX2N1cnJfZGVwdGggPiAxIHRoZW5cbiAgYmVnaW5cbiAgICBpZiBzdGF0ZS5wcF9jdXJyX2RlcHRoIDwgc3RhdGUucHBfbWF4X2JveGVzIHRoZW5cbiAgICBiZWdpblxuICAgICAgcHBfZW5xdWV1ZSBzdGF0ZSB7IHNpemUgPSBTaXplLnplcm87IHRva2VuID0gUHBfZW5kOyBsZW5ndGggPSAwIH07XG4gICAgICBzZXRfc2l6ZSBzdGF0ZSB0cnVlOyBzZXRfc2l6ZSBzdGF0ZSBmYWxzZVxuICAgIGVuZDtcbiAgICBzdGF0ZS5wcF9jdXJyX2RlcHRoIDwtIHN0YXRlLnBwX2N1cnJfZGVwdGggLSAxO1xuICBlbmRcblxuXG4oKiBPcGVuIGEgdGFnLCBwdXNoaW5nIGl0IG9uIHRoZSB0YWcgc3RhY2suICopXG5sZXQgcHBfb3Blbl9zdGFnIHN0YXRlIHRhZ19uYW1lID1cbiAgaWYgc3RhdGUucHBfcHJpbnRfdGFncyB0aGVuXG4gIGJlZ2luXG4gICAgU3RhY2sucHVzaCB0YWdfbmFtZSBzdGF0ZS5wcF90YWdfc3RhY2s7XG4gICAgc3RhdGUucHBfcHJpbnRfb3Blbl90YWcgdGFnX25hbWVcbiAgZW5kO1xuICBpZiBzdGF0ZS5wcF9tYXJrX3RhZ3MgdGhlblxuICAgIGxldCB0b2tlbiA9IFBwX29wZW5fdGFnIHRhZ19uYW1lIGluXG4gICAgcHBfZW5xdWV1ZSBzdGF0ZSB7IHNpemUgPSBTaXplLnplcm87IHRva2VuOyBsZW5ndGggPSAwIH1cblxuXG4oKiBDbG9zZSBhIHRhZywgcG9wcGluZyBpdCBmcm9tIHRoZSB0YWcgc3RhY2suICopXG5sZXQgcHBfY2xvc2Vfc3RhZyBzdGF0ZSAoKSA9XG4gIGlmIHN0YXRlLnBwX21hcmtfdGFncyB0aGVuXG4gICAgcHBfZW5xdWV1ZSBzdGF0ZSB7IHNpemUgPSBTaXplLnplcm87IHRva2VuID0gUHBfY2xvc2VfdGFnOyBsZW5ndGggPSAwIH07XG4gIGlmIHN0YXRlLnBwX3ByaW50X3RhZ3MgdGhlblxuICAgIG1hdGNoIFN0YWNrLnBvcF9vcHQgc3RhdGUucHBfdGFnX3N0YWNrIHdpdGhcbiAgICB8IE5vbmUgLT4gKCkgKCogTm8gbW9yZSB0YWcgdG8gY2xvc2UuICopXG4gICAgfCBTb21lIHRhZ19uYW1lIC0+XG4gICAgICBzdGF0ZS5wcF9wcmludF9jbG9zZV90YWcgdGFnX25hbWVcblxubGV0IHBwX29wZW5fdGFnIHN0YXRlIHMgPSBwcF9vcGVuX3N0YWcgc3RhdGUgKFN0cmluZ190YWcgcylcbmxldCBwcF9jbG9zZV90YWcgc3RhdGUgKCkgPSBwcF9jbG9zZV9zdGFnIHN0YXRlICgpXG5cbmxldCBwcF9zZXRfcHJpbnRfdGFncyBzdGF0ZSBiID0gc3RhdGUucHBfcHJpbnRfdGFncyA8LSBiXG5sZXQgcHBfc2V0X21hcmtfdGFncyBzdGF0ZSBiID0gc3RhdGUucHBfbWFya190YWdzIDwtIGJcbmxldCBwcF9nZXRfcHJpbnRfdGFncyBzdGF0ZSAoKSA9IHN0YXRlLnBwX3ByaW50X3RhZ3NcbmxldCBwcF9nZXRfbWFya190YWdzIHN0YXRlICgpID0gc3RhdGUucHBfbWFya190YWdzXG5sZXQgcHBfc2V0X3RhZ3Mgc3RhdGUgYiA9XG4gIHBwX3NldF9wcmludF90YWdzIHN0YXRlIGI7IHBwX3NldF9tYXJrX3RhZ3Mgc3RhdGUgYlxuXG5cbigqIEhhbmRsaW5nIHRhZyBoYW5kbGluZyBmdW5jdGlvbnM6IGdldC9zZXQgZnVuY3Rpb25zLiAqKVxubGV0IHBwX2dldF9mb3JtYXR0ZXJfc3RhZ19mdW5jdGlvbnMgc3RhdGUgKCkgPSB7XG4gIG1hcmtfb3Blbl9zdGFnID0gc3RhdGUucHBfbWFya19vcGVuX3RhZztcbiAgbWFya19jbG9zZV9zdGFnID0gc3RhdGUucHBfbWFya19jbG9zZV90YWc7XG4gIHByaW50X29wZW5fc3RhZyA9IHN0YXRlLnBwX3ByaW50X29wZW5fdGFnO1xuICBwcmludF9jbG9zZV9zdGFnID0gc3RhdGUucHBfcHJpbnRfY2xvc2VfdGFnO1xufVxuXG5cbmxldCBwcF9zZXRfZm9ybWF0dGVyX3N0YWdfZnVuY3Rpb25zIHN0YXRlIHtcbiAgICAgbWFya19vcGVuX3N0YWcgPSBtb3Q7XG4gICAgIG1hcmtfY2xvc2Vfc3RhZyA9IG1jdDtcbiAgICAgcHJpbnRfb3Blbl9zdGFnID0gcG90O1xuICAgICBwcmludF9jbG9zZV9zdGFnID0gcGN0O1xuICB9ID1cbiAgc3RhdGUucHBfbWFya19vcGVuX3RhZyA8LSBtb3Q7XG4gIHN0YXRlLnBwX21hcmtfY2xvc2VfdGFnIDwtIG1jdDtcbiAgc3RhdGUucHBfcHJpbnRfb3Blbl90YWcgPC0gcG90O1xuICBzdGF0ZS5wcF9wcmludF9jbG9zZV90YWcgPC0gcGN0XG5cblxuKCogSW5pdGlhbGl6ZSBwcmV0dHktcHJpbnRlci4gKilcbmxldCBwcF9yaW5pdCBzdGF0ZSA9XG4gIHBwX2NsZWFyX3F1ZXVlIHN0YXRlO1xuICBpbml0aWFsaXplX3NjYW5fc3RhY2sgc3RhdGUucHBfc2Nhbl9zdGFjaztcbiAgU3RhY2suY2xlYXIgc3RhdGUucHBfZm9ybWF0X3N0YWNrO1xuICBTdGFjay5jbGVhciBzdGF0ZS5wcF90Ym94X3N0YWNrO1xuICBTdGFjay5jbGVhciBzdGF0ZS5wcF90YWdfc3RhY2s7XG4gIFN0YWNrLmNsZWFyIHN0YXRlLnBwX21hcmtfc3RhY2s7XG4gIHN0YXRlLnBwX2N1cnJlbnRfaW5kZW50IDwtIDA7XG4gIHN0YXRlLnBwX2N1cnJfZGVwdGggPC0gMDtcbiAgc3RhdGUucHBfc3BhY2VfbGVmdCA8LSBzdGF0ZS5wcF9tYXJnaW47XG4gIHBwX29wZW5fc3lzX2JveCBzdGF0ZVxuXG5sZXQgY2xlYXJfdGFnX3N0YWNrIHN0YXRlID1cbiAgU3RhY2suaXRlciAoZnVuIF8gLT4gcHBfY2xvc2VfdGFnIHN0YXRlICgpKSBzdGF0ZS5wcF90YWdfc3RhY2tcblxuXG4oKiBGbHVzaGluZyBwcmV0dHktcHJpbnRlciBxdWV1ZS4gKilcbmxldCBwcF9mbHVzaF9xdWV1ZSBzdGF0ZSBiID1cbiAgY2xlYXJfdGFnX3N0YWNrIHN0YXRlO1xuICB3aGlsZSBzdGF0ZS5wcF9jdXJyX2RlcHRoID4gMSBkb1xuICAgIHBwX2Nsb3NlX2JveCBzdGF0ZSAoKVxuICBkb25lO1xuICBzdGF0ZS5wcF9yaWdodF90b3RhbCA8LSBwcF9pbmZpbml0eTtcbiAgYWR2YW5jZV9sZWZ0IHN0YXRlO1xuICBpZiBiIHRoZW4gcHBfb3V0cHV0X25ld2xpbmUgc3RhdGU7XG4gIHBwX3Jpbml0IHN0YXRlXG5cbigqXG5cbiAgUHJvY2VkdXJlcyB0byBmb3JtYXQgdmFsdWVzIGFuZCB1c2UgYm94ZXMuXG5cbiopXG5cbigqIFRvIGZvcm1hdCBhIHN0cmluZy4gKilcbmxldCBwcF9wcmludF9hc19zaXplIHN0YXRlIHNpemUgcyA9XG4gIGlmIHN0YXRlLnBwX2N1cnJfZGVwdGggPCBzdGF0ZS5wcF9tYXhfYm94ZXNcbiAgdGhlbiBlbnF1ZXVlX3N0cmluZ19hcyBzdGF0ZSBzaXplIHNcblxuXG5sZXQgcHBfcHJpbnRfYXMgc3RhdGUgaXNpemUgcyA9XG4gIHBwX3ByaW50X2FzX3NpemUgc3RhdGUgKFNpemUub2ZfaW50IGlzaXplKSBzXG5cblxubGV0IHBwX3ByaW50X3N0cmluZyBzdGF0ZSBzID1cbiAgcHBfcHJpbnRfYXMgc3RhdGUgKFN0cmluZy5sZW5ndGggcykgc1xuXG5sZXQgcHBfcHJpbnRfYnl0ZXMgc3RhdGUgcyA9XG4gIHBwX3ByaW50X2FzIHN0YXRlIChCeXRlcy5sZW5ndGggcykgKEJ5dGVzLnRvX3N0cmluZyBzKVxuXG4oKiBUbyBmb3JtYXQgYW4gaW50ZWdlci4gKilcbmxldCBwcF9wcmludF9pbnQgc3RhdGUgaSA9IHBwX3ByaW50X3N0cmluZyBzdGF0ZSAoSW50LnRvX3N0cmluZyBpKVxuXG4oKiBUbyBmb3JtYXQgYSBmbG9hdC4gKilcbmxldCBwcF9wcmludF9mbG9hdCBzdGF0ZSBmID0gcHBfcHJpbnRfc3RyaW5nIHN0YXRlIChzdHJpbmdfb2ZfZmxvYXQgZilcblxuKCogVG8gZm9ybWF0IGEgYm9vbGVhbi4gKilcbmxldCBwcF9wcmludF9ib29sIHN0YXRlIGIgPSBwcF9wcmludF9zdHJpbmcgc3RhdGUgKHN0cmluZ19vZl9ib29sIGIpXG5cbigqIFRvIGZvcm1hdCBhIGNoYXIuICopXG5sZXQgcHBfcHJpbnRfY2hhciBzdGF0ZSBjID1cbiAgcHBfcHJpbnRfYXMgc3RhdGUgMSAoU3RyaW5nLm1ha2UgMSBjKVxuXG5cbigqIE9wZW5pbmcgYm94ZXMuICopXG5sZXQgcHBfb3Blbl9oYm94IHN0YXRlICgpID0gcHBfb3Blbl9ib3hfZ2VuIHN0YXRlIDAgUHBfaGJveFxuYW5kIHBwX29wZW5fdmJveCBzdGF0ZSBpbmRlbnQgPSBwcF9vcGVuX2JveF9nZW4gc3RhdGUgaW5kZW50IFBwX3Zib3hcblxuYW5kIHBwX29wZW5faHZib3ggc3RhdGUgaW5kZW50ID0gcHBfb3Blbl9ib3hfZ2VuIHN0YXRlIGluZGVudCBQcF9odmJveFxuYW5kIHBwX29wZW5faG92Ym94IHN0YXRlIGluZGVudCA9IHBwX29wZW5fYm94X2dlbiBzdGF0ZSBpbmRlbnQgUHBfaG92Ym94XG5hbmQgcHBfb3Blbl9ib3ggc3RhdGUgaW5kZW50ID0gcHBfb3Blbl9ib3hfZ2VuIHN0YXRlIGluZGVudCBQcF9ib3hcblxuXG4oKiBQcmludGluZyBxdWV1ZWQgdGV4dC5cblxuICAgW3BwX3ByaW50X2ZsdXNoXSBwcmludHMgYWxsIHBlbmRpbmcgaXRlbXMgaW4gdGhlIHByZXR0eS1wcmludGVyIHF1ZXVlIGFuZFxuICAgdGhlbiBmbHVzaGVzIHRoZSBsb3cgbGV2ZWwgb3V0cHV0IGRldmljZSBvZiB0aGUgZm9ybWF0dGVyIHRvIGFjdHVhbGx5XG4gICBkaXNwbGF5IHByaW50aW5nIG1hdGVyaWFsLlxuXG4gICBbcHBfcHJpbnRfbmV3bGluZV0gYmVoYXZlcyBhcyBbcHBfcHJpbnRfZmx1c2hdIGFmdGVyIHByaW50aW5nIGFuIGFkZGl0aW9uYWxcbiAgIG5ldyBsaW5lLiAqKVxubGV0IHBwX3ByaW50X25ld2xpbmUgc3RhdGUgKCkgPVxuICBwcF9mbHVzaF9xdWV1ZSBzdGF0ZSB0cnVlOyBzdGF0ZS5wcF9vdXRfZmx1c2ggKClcbmFuZCBwcF9wcmludF9mbHVzaCBzdGF0ZSAoKSA9XG4gIHBwX2ZsdXNoX3F1ZXVlIHN0YXRlIGZhbHNlOyBzdGF0ZS5wcF9vdXRfZmx1c2ggKClcblxuXG4oKiBUbyBnZXQgYSBuZXdsaW5lIHdoZW4gb25lIGRvZXMgbm90IHdhbnQgdG8gY2xvc2UgdGhlIGN1cnJlbnQgYm94LiAqKVxubGV0IHBwX2ZvcmNlX25ld2xpbmUgc3RhdGUgKCkgPVxuICBpZiBzdGF0ZS5wcF9jdXJyX2RlcHRoIDwgc3RhdGUucHBfbWF4X2JveGVzIHRoZW5cbiAgICBlbnF1ZXVlX2FkdmFuY2Ugc3RhdGUgeyBzaXplID0gU2l6ZS56ZXJvOyB0b2tlbiA9IFBwX25ld2xpbmU7IGxlbmd0aCA9IDAgfVxuXG5cbigqIFRvIGZvcm1hdCBzb21ldGhpbmcsIG9ubHkgaW4gY2FzZSB0aGUgbGluZSBoYXMganVzdCBiZWVuIGJyb2tlbi4gKilcbmxldCBwcF9wcmludF9pZl9uZXdsaW5lIHN0YXRlICgpID1cbiAgaWYgc3RhdGUucHBfY3Vycl9kZXB0aCA8IHN0YXRlLnBwX21heF9ib3hlcyB0aGVuXG4gICAgZW5xdWV1ZV9hZHZhbmNlIHN0YXRlXG4gICAgICB7IHNpemUgPSBTaXplLnplcm87IHRva2VuID0gUHBfaWZfbmV3bGluZTsgbGVuZ3RoID0gMCB9XG5cblxuKCogR2VuZXJhbGl6ZWQgYnJlYWsgaGludCB0aGF0IGFsbG93cyBwcmludGluZyBzdHJpbmdzIGJlZm9yZS9hZnRlclxuICAgc2FtZS1saW5lIG9mZnNldCAod2lkdGgpIG9yIG5ldy1saW5lIG9mZnNldCAqKVxubGV0IHBwX3ByaW50X2N1c3RvbV9icmVhayBzdGF0ZSB+Zml0cyB+YnJlYWtzID1cbiAgbGV0IGJlZm9yZSwgd2lkdGgsIGFmdGVyID0gZml0cyBpblxuICBpZiBzdGF0ZS5wcF9jdXJyX2RlcHRoIDwgc3RhdGUucHBfbWF4X2JveGVzIHRoZW5cbiAgICBsZXQgc2l6ZSA9IFNpemUub2ZfaW50ICgtIHN0YXRlLnBwX3JpZ2h0X3RvdGFsKSBpblxuICAgIGxldCB0b2tlbiA9IFBwX2JyZWFrIHsgZml0czsgYnJlYWtzIH0gaW5cbiAgICBsZXQgbGVuZ3RoID0gU3RyaW5nLmxlbmd0aCBiZWZvcmUgKyB3aWR0aCArIFN0cmluZy5sZW5ndGggYWZ0ZXIgaW5cbiAgICBsZXQgZWxlbSA9IHsgc2l6ZTsgdG9rZW47IGxlbmd0aCB9IGluXG4gICAgc2Nhbl9wdXNoIHN0YXRlIHRydWUgZWxlbVxuXG4oKiBQcmludGluZyBicmVhayBoaW50czpcbiAgIEEgYnJlYWsgaGludCBpbmRpY2F0ZXMgd2hlcmUgYSBib3ggbWF5IGJlIGJyb2tlbi5cbiAgIElmIGxpbmUgaXMgYnJva2VuIHRoZW4gb2Zmc2V0IGlzIGFkZGVkIHRvIHRoZSBpbmRlbnRhdGlvbiBvZiB0aGUgY3VycmVudFxuICAgYm94IGVsc2UgKHRoZSB2YWx1ZSBvZikgd2lkdGggYmxhbmtzIGFyZSBwcmludGVkLiAqKVxubGV0IHBwX3ByaW50X2JyZWFrIHN0YXRlIHdpZHRoIG9mZnNldCA9XG4gIHBwX3ByaW50X2N1c3RvbV9icmVhayBzdGF0ZVxuICAgIH5maXRzOihcIlwiLCB3aWR0aCwgXCJcIikgfmJyZWFrczooXCJcIiwgb2Zmc2V0LCBcIlwiKVxuXG5cbigqIFByaW50IGEgc3BhY2UgOlxuICAgYSBzcGFjZSBpcyBhIGJyZWFrIGhpbnQgdGhhdCBwcmludHMgYSBzaW5nbGUgc3BhY2UgaWYgdGhlIGJyZWFrIGRvZXMgbm90XG4gICBzcGxpdCB0aGUgbGluZTtcbiAgIGEgY3V0IGlzIGEgYnJlYWsgaGludCB0aGF0IHByaW50cyBub3RoaW5nIGlmIHRoZSBicmVhayBkb2VzIG5vdCBzcGxpdCB0aGVcbiAgIGxpbmUuICopXG5sZXQgcHBfcHJpbnRfc3BhY2Ugc3RhdGUgKCkgPSBwcF9wcmludF9icmVhayBzdGF0ZSAxIDBcbmFuZCBwcF9wcmludF9jdXQgc3RhdGUgKCkgPSBwcF9wcmludF9icmVhayBzdGF0ZSAwIDBcblxuXG4oKiBUYWJ1bGF0aW9uIGJveGVzLiAqKVxubGV0IHBwX29wZW5fdGJveCBzdGF0ZSAoKSA9XG4gIHN0YXRlLnBwX2N1cnJfZGVwdGggPC0gc3RhdGUucHBfY3Vycl9kZXB0aCArIDE7XG4gIGlmIHN0YXRlLnBwX2N1cnJfZGVwdGggPCBzdGF0ZS5wcF9tYXhfYm94ZXMgdGhlblxuICAgIGxldCBzaXplID0gU2l6ZS56ZXJvIGluXG4gICAgbGV0IGVsZW0gPSB7IHNpemU7IHRva2VuID0gUHBfdGJlZ2luIChQcF90Ym94IChyZWYgW10pKTsgbGVuZ3RoID0gMCB9IGluXG4gICAgZW5xdWV1ZV9hZHZhbmNlIHN0YXRlIGVsZW1cblxuXG4oKiBDbG9zZSBhIHRhYnVsYXRpb24gYm94LiAqKVxubGV0IHBwX2Nsb3NlX3Rib3ggc3RhdGUgKCkgPVxuICBpZiBzdGF0ZS5wcF9jdXJyX2RlcHRoID4gMSB0aGVuXG4gIGJlZ2luXG4gICBpZiBzdGF0ZS5wcF9jdXJyX2RlcHRoIDwgc3RhdGUucHBfbWF4X2JveGVzIHRoZW5cbiAgICAgbGV0IGVsZW0gPSB7IHNpemUgPSBTaXplLnplcm87IHRva2VuID0gUHBfdGVuZDsgbGVuZ3RoID0gMCB9IGluXG4gICAgIGVucXVldWVfYWR2YW5jZSBzdGF0ZSBlbGVtO1xuICAgICBzdGF0ZS5wcF9jdXJyX2RlcHRoIDwtIHN0YXRlLnBwX2N1cnJfZGVwdGggLSAxXG4gIGVuZFxuXG5cbigqIFByaW50IGEgdGFidWxhdGlvbiBicmVhay4gKilcbmxldCBwcF9wcmludF90YnJlYWsgc3RhdGUgd2lkdGggb2Zmc2V0ID1cbiAgaWYgc3RhdGUucHBfY3Vycl9kZXB0aCA8IHN0YXRlLnBwX21heF9ib3hlcyB0aGVuXG4gICAgbGV0IHNpemUgPSBTaXplLm9mX2ludCAoLSBzdGF0ZS5wcF9yaWdodF90b3RhbCkgaW5cbiAgICBsZXQgZWxlbSA9IHsgc2l6ZTsgdG9rZW4gPSBQcF90YnJlYWsgKHdpZHRoLCBvZmZzZXQpOyBsZW5ndGggPSB3aWR0aCB9IGluXG4gICAgc2Nhbl9wdXNoIHN0YXRlIHRydWUgZWxlbVxuXG5cbmxldCBwcF9wcmludF90YWIgc3RhdGUgKCkgPSBwcF9wcmludF90YnJlYWsgc3RhdGUgMCAwXG5cbmxldCBwcF9zZXRfdGFiIHN0YXRlICgpID1cbiAgaWYgc3RhdGUucHBfY3Vycl9kZXB0aCA8IHN0YXRlLnBwX21heF9ib3hlcyB0aGVuXG4gICAgbGV0IGVsZW0gPSB7IHNpemUgPSBTaXplLnplcm87IHRva2VuID0gUHBfc3RhYjsgbGVuZ3RoID0gMCB9IGluXG4gICAgZW5xdWV1ZV9hZHZhbmNlIHN0YXRlIGVsZW1cblxuXG4oKlxuXG4gIFByb2NlZHVyZXMgdG8gY29udHJvbCB0aGUgcHJldHR5LXByaW50ZXJzXG5cbiopXG5cbigqIFNldF9tYXhfYm94ZXMuICopXG5sZXQgcHBfc2V0X21heF9ib3hlcyBzdGF0ZSBuID0gaWYgbiA+IDEgdGhlbiBzdGF0ZS5wcF9tYXhfYm94ZXMgPC0gblxuXG4oKiBUbyBrbm93IHRoZSBjdXJyZW50IG1heGltdW0gbnVtYmVyIG9mIGJveGVzIGFsbG93ZWQuICopXG5sZXQgcHBfZ2V0X21heF9ib3hlcyBzdGF0ZSAoKSA9IHN0YXRlLnBwX21heF9ib3hlc1xuXG5sZXQgcHBfb3Zlcl9tYXhfYm94ZXMgc3RhdGUgKCkgPSBzdGF0ZS5wcF9jdXJyX2RlcHRoID0gc3RhdGUucHBfbWF4X2JveGVzXG5cbigqIEVsbGlwc2lzLiAqKVxubGV0IHBwX3NldF9lbGxpcHNpc190ZXh0IHN0YXRlIHMgPSBzdGF0ZS5wcF9lbGxpcHNpcyA8LSBzXG5hbmQgcHBfZ2V0X2VsbGlwc2lzX3RleHQgc3RhdGUgKCkgPSBzdGF0ZS5wcF9lbGxpcHNpc1xuXG5cbigqIFRvIHNldCB0aGUgbWFyZ2luIG9mIHByZXR0eS1wcmludGVyLiAqKVxubGV0IHBwX2xpbWl0IG4gPVxuICBpZiBuIDwgcHBfaW5maW5pdHkgdGhlbiBuIGVsc2UgcHJlZCBwcF9pbmZpbml0eVxuXG5cbigqIEludGVybmFsIHByZXR0eS1wcmludGVyIGZ1bmN0aW9ucy4gKilcbmxldCBwcF9zZXRfbWluX3NwYWNlX2xlZnQgc3RhdGUgbiA9XG4gIGlmIG4gPj0gMSB0aGVuXG4gICAgbGV0IG4gPSBwcF9saW1pdCBuIGluXG4gICAgc3RhdGUucHBfbWluX3NwYWNlX2xlZnQgPC0gbjtcbiAgICBzdGF0ZS5wcF9tYXhfaW5kZW50IDwtIHN0YXRlLnBwX21hcmdpbiAtIHN0YXRlLnBwX21pbl9zcGFjZV9sZWZ0O1xuICAgIHBwX3Jpbml0IHN0YXRlXG5cblxuKCogSW5pdGlhbGx5LCB3ZSBoYXZlIDpcbiAgIHBwX21heF9pbmRlbnQgPSBwcF9tYXJnaW4gLSBwcF9taW5fc3BhY2VfbGVmdCwgYW5kXG4gICBwcF9zcGFjZV9sZWZ0ID0gcHBfbWFyZ2luLiAqKVxubGV0IHBwX3NldF9tYXhfaW5kZW50IHN0YXRlIG4gPVxuICBpZiBuID4gMSB0aGVuXG4gICAgcHBfc2V0X21pbl9zcGFjZV9sZWZ0IHN0YXRlIChzdGF0ZS5wcF9tYXJnaW4gLSBuKVxuXG5cbmxldCBwcF9nZXRfbWF4X2luZGVudCBzdGF0ZSAoKSA9IHN0YXRlLnBwX21heF9pbmRlbnRcblxubGV0IHBwX3NldF9tYXJnaW4gc3RhdGUgbiA9XG4gIGlmIG4gPj0gMSB0aGVuXG4gICAgbGV0IG4gPSBwcF9saW1pdCBuIGluXG4gICAgc3RhdGUucHBfbWFyZ2luIDwtIG47XG4gICAgbGV0IG5ld19tYXhfaW5kZW50ID1cbiAgICAgICgqIFRyeSB0byBtYWludGFpbiBtYXhfaW5kZW50IHRvIGl0cyBhY3R1YWwgdmFsdWUuICopXG4gICAgICBpZiBzdGF0ZS5wcF9tYXhfaW5kZW50IDw9IHN0YXRlLnBwX21hcmdpblxuICAgICAgdGhlbiBzdGF0ZS5wcF9tYXhfaW5kZW50IGVsc2VcbiAgICAgICgqIElmIHBvc3NpYmxlIG1haW50YWluIHBwX21pbl9zcGFjZV9sZWZ0IHRvIGl0cyBhY3R1YWwgdmFsdWUsXG4gICAgICAgICBpZiB0aGlzIGxlYWRzIHRvIGEgdG9vIHNtYWxsIG1heF9pbmRlbnQsIHRha2UgaGFsZiBvZiB0aGVcbiAgICAgICAgIG5ldyBtYXJnaW4sIGlmIGl0IGlzIGdyZWF0ZXIgdGhhbiAxLiAqKVxuICAgICAgIEludC5tYXggKEludC5tYXggKHN0YXRlLnBwX21hcmdpbiAtIHN0YXRlLnBwX21pbl9zcGFjZV9sZWZ0KVxuICAgICAgICAgICAgICAgIChzdGF0ZS5wcF9tYXJnaW4gLyAyKSkgMSBpblxuICAgICgqIFJlYnVpbGQgaW52YXJpYW50cy4gKilcbiAgICBwcF9zZXRfbWF4X2luZGVudCBzdGF0ZSBuZXdfbWF4X2luZGVudFxuXG5cbigqKiBHZW9tZXRyeSBmdW5jdGlvbnMgYW5kIHR5cGVzICopXG50eXBlIGdlb21ldHJ5ID0geyBtYXhfaW5kZW50OmludDsgbWFyZ2luOiBpbnR9XG5cbmxldCB2YWxpZGF0ZV9nZW9tZXRyeSB7bWFyZ2luOyBtYXhfaW5kZW50fSA9XG4gIGlmIG1heF9pbmRlbnQgPCAyIHRoZW5cbiAgICBFcnJvciBcIm1heF9pbmRlbnQgPCAyXCJcbiAgZWxzZSBpZiBtYXJnaW4gPD0gbWF4X2luZGVudCB0aGVuXG4gICAgRXJyb3IgXCJtYXJnaW4gPD0gbWF4X2luZGVudFwiXG4gIGVsc2UgT2sgKClcblxubGV0IGNoZWNrX2dlb21ldHJ5IGdlb21ldHJ5ID1cbiAgbWF0Y2ggdmFsaWRhdGVfZ2VvbWV0cnkgZ2VvbWV0cnkgd2l0aFxuICB8IE9rICgpIC0+IHRydWVcbiAgfCBFcnJvciBfIC0+IGZhbHNlXG5cbmxldCBwcF9nZXRfbWFyZ2luIHN0YXRlICgpID0gc3RhdGUucHBfbWFyZ2luXG5cbmxldCBwcF9zZXRfZnVsbF9nZW9tZXRyeSBzdGF0ZSB7bWFyZ2luOyBtYXhfaW5kZW50fSA9XG4gIHBwX3NldF9tYXJnaW4gc3RhdGUgbWFyZ2luO1xuICBwcF9zZXRfbWF4X2luZGVudCBzdGF0ZSBtYXhfaW5kZW50O1xuICAoKVxuXG5sZXQgcHBfc2V0X2dlb21ldHJ5IHN0YXRlIH5tYXhfaW5kZW50IH5tYXJnaW4gPVxuICBsZXQgZ2VvbWV0cnkgPSB7IG1heF9pbmRlbnQ7IG1hcmdpbiB9IGluXG4gIG1hdGNoIHZhbGlkYXRlX2dlb21ldHJ5IGdlb21ldHJ5IHdpdGhcbiAgfCBFcnJvciBtc2cgLT5cbiAgICByYWlzZSAoSW52YWxpZF9hcmd1bWVudCAoXCJGb3JtYXQucHBfc2V0X2dlb21ldHJ5OiBcIiBeIG1zZykpXG4gIHwgT2sgKCkgLT5cbiAgICBwcF9zZXRfZnVsbF9nZW9tZXRyeSBzdGF0ZSBnZW9tZXRyeVxuXG5sZXQgcHBfc2FmZV9zZXRfZ2VvbWV0cnkgc3RhdGUgfm1heF9pbmRlbnQgfm1hcmdpbiA9XG4gIGxldCBnZW9tZXRyeSA9IHsgbWF4X2luZGVudDsgbWFyZ2luIH0gaW5cbiAgbWF0Y2ggdmFsaWRhdGVfZ2VvbWV0cnkgZ2VvbWV0cnkgd2l0aFxuICB8IEVycm9yIF9tc2cgLT5cbiAgICAgKClcbiAgfCBPayAoKSAtPlxuICAgIHBwX3NldF9mdWxsX2dlb21ldHJ5IHN0YXRlIGdlb21ldHJ5XG5cbmxldCBwcF9nZXRfZ2VvbWV0cnkgc3RhdGUgKCkgPVxuICB7IG1hcmdpbiA9IHBwX2dldF9tYXJnaW4gc3RhdGUgKCk7IG1heF9pbmRlbnQgPSBwcF9nZXRfbWF4X2luZGVudCBzdGF0ZSAoKSB9XG5cbmxldCBwcF91cGRhdGVfZ2VvbWV0cnkgc3RhdGUgdXBkYXRlID1cbiAgbGV0IGdlb21ldHJ5ID0gcHBfZ2V0X2dlb21ldHJ5IHN0YXRlICgpIGluXG4gIHBwX3NldF9mdWxsX2dlb21ldHJ5IHN0YXRlICh1cGRhdGUgZ2VvbWV0cnkpXG5cbigqIFNldHRpbmcgYSBmb3JtYXR0ZXIgYmFzaWMgb3V0cHV0IGZ1bmN0aW9ucy4gKilcbmxldCBwcF9zZXRfZm9ybWF0dGVyX291dF9mdW5jdGlvbnMgc3RhdGUge1xuICAgICAgb3V0X3N0cmluZyA9IGY7XG4gICAgICBvdXRfZmx1c2ggPSBnO1xuICAgICAgb3V0X25ld2xpbmUgPSBoO1xuICAgICAgb3V0X3NwYWNlcyA9IGk7XG4gICAgICBvdXRfaW5kZW50ID0gajtcbiAgICB9ID1cbiAgc3RhdGUucHBfb3V0X3N0cmluZyA8LSBmO1xuICBzdGF0ZS5wcF9vdXRfZmx1c2ggPC0gZztcbiAgc3RhdGUucHBfb3V0X25ld2xpbmUgPC0gaDtcbiAgc3RhdGUucHBfb3V0X3NwYWNlcyA8LSBpO1xuICBzdGF0ZS5wcF9vdXRfaW5kZW50IDwtIGpcblxubGV0IHBwX2dldF9mb3JtYXR0ZXJfb3V0X2Z1bmN0aW9ucyBzdGF0ZSAoKSA9IHtcbiAgb3V0X3N0cmluZyA9IHN0YXRlLnBwX291dF9zdHJpbmc7XG4gIG91dF9mbHVzaCA9IHN0YXRlLnBwX291dF9mbHVzaDtcbiAgb3V0X25ld2xpbmUgPSBzdGF0ZS5wcF9vdXRfbmV3bGluZTtcbiAgb3V0X3NwYWNlcyA9IHN0YXRlLnBwX291dF9zcGFjZXM7XG4gIG91dF9pbmRlbnQgPSBzdGF0ZS5wcF9vdXRfaW5kZW50O1xufVxuXG5cbigqIFNldHRpbmcgYSBmb3JtYXR0ZXIgYmFzaWMgc3RyaW5nIG91dHB1dCBhbmQgZmx1c2ggZnVuY3Rpb25zLiAqKVxubGV0IHBwX3NldF9mb3JtYXR0ZXJfb3V0cHV0X2Z1bmN0aW9ucyBzdGF0ZSBmIGcgPVxuICBzdGF0ZS5wcF9vdXRfc3RyaW5nIDwtIGY7IHN0YXRlLnBwX291dF9mbHVzaCA8LSBnXG5cbmxldCBwcF9nZXRfZm9ybWF0dGVyX291dHB1dF9mdW5jdGlvbnMgc3RhdGUgKCkgPVxuICAoc3RhdGUucHBfb3V0X3N0cmluZywgc3RhdGUucHBfb3V0X2ZsdXNoKVxuXG5cbigqIFRoZSBkZWZhdWx0IGZ1bmN0aW9uIHRvIG91dHB1dCBuZXcgbGluZXMuICopXG5sZXQgZGlzcGxheV9uZXdsaW5lIHN0YXRlICgpID0gc3RhdGUucHBfb3V0X3N0cmluZyBcIlxcblwiIDAgIDFcblxuKCogVGhlIGRlZmF1bHQgZnVuY3Rpb24gdG8gb3V0cHV0IHNwYWNlcy4gKilcbmxldCBibGFua19saW5lID0gU3RyaW5nLm1ha2UgODAgJyAnXG5sZXQgcmVjIGRpc3BsYXlfYmxhbmtzIHN0YXRlIG4gPVxuICBpZiBuID4gMCB0aGVuXG4gIGlmIG4gPD0gODAgdGhlbiBzdGF0ZS5wcF9vdXRfc3RyaW5nIGJsYW5rX2xpbmUgMCBuIGVsc2VcbiAgYmVnaW5cbiAgICBzdGF0ZS5wcF9vdXRfc3RyaW5nIGJsYW5rX2xpbmUgMCA4MDtcbiAgICBkaXNwbGF5X2JsYW5rcyBzdGF0ZSAobiAtIDgwKVxuICBlbmRcblxuXG4oKiBUaGUgZGVmYXVsdCBmdW5jdGlvbiB0byBvdXRwdXQgaW5kZW50YXRpb24gb2YgbmV3IGxpbmVzLiAqKVxubGV0IGRpc3BsYXlfaW5kZW50ID0gZGlzcGxheV9ibGFua3NcblxuKCogU2V0dGluZyBhIGZvcm1hdHRlciBiYXNpYyBvdXRwdXQgZnVuY3Rpb25zIGFzIHByaW50aW5nIHRvIGEgZ2l2ZW5cbiAgIFtQZXJ2YXNpdmUub3V0X2NoYW5uZWxdIHZhbHVlLiAqKVxubGV0IHBwX3NldF9mb3JtYXR0ZXJfb3V0X2NoYW5uZWwgc3RhdGUgb2MgPVxuICBzdGF0ZS5wcF9vdXRfc3RyaW5nIDwtIG91dHB1dF9zdWJzdHJpbmcgb2M7XG4gIHN0YXRlLnBwX291dF9mbHVzaCA8LSAoZnVuICgpIC0+IGZsdXNoIG9jKTtcbiAgc3RhdGUucHBfb3V0X25ld2xpbmUgPC0gZGlzcGxheV9uZXdsaW5lIHN0YXRlO1xuICBzdGF0ZS5wcF9vdXRfc3BhY2VzIDwtIGRpc3BsYXlfYmxhbmtzIHN0YXRlO1xuICBzdGF0ZS5wcF9vdXRfaW5kZW50IDwtIGRpc3BsYXlfaW5kZW50IHN0YXRlXG5cbigqXG5cbiAgRGVmaW5pbmcgc3BlY2lmaWMgZm9ybWF0dGVyc1xuXG4qKVxuXG5sZXQgZGVmYXVsdF9wcF9tYXJrX29wZW5fdGFnID0gZnVuY3Rpb25cbiAgfCBTdHJpbmdfdGFnIHMgLT4gXCI8XCIgXiBzIF4gXCI+XCJcbiAgfCBfIC0+IFwiXCJcbmxldCBkZWZhdWx0X3BwX21hcmtfY2xvc2VfdGFnID0gZnVuY3Rpb25cbiAgfCBTdHJpbmdfdGFnIHMgLT4gXCI8L1wiIF4gcyBeIFwiPlwiXG4gIHwgXyAtPiBcIlwiXG5cbmxldCBkZWZhdWx0X3BwX3ByaW50X29wZW5fdGFnID0gaWdub3JlXG5sZXQgZGVmYXVsdF9wcF9wcmludF9jbG9zZV90YWcgPSBpZ25vcmVcblxuKCogQnVpbGRpbmcgYSBmb3JtYXR0ZXIgZ2l2ZW4gaXRzIGJhc2ljIG91dHB1dCBmdW5jdGlvbnMuXG4gICBPdGhlciBmaWVsZHMgZ2V0IHJlYXNvbmFibGUgZGVmYXVsdCB2YWx1ZXMuICopXG5sZXQgcHBfbWFrZV9mb3JtYXR0ZXIgZiBnIGggaSBqID1cbiAgKCogVGhlIGluaXRpYWwgc3RhdGUgb2YgdGhlIGZvcm1hdHRlciBjb250YWlucyBhIGR1bW15IGJveC4gKilcbiAgbGV0IHBwX3F1ZXVlID0gUXVldWUuY3JlYXRlICgpIGluXG4gIGxldCBzeXNfdG9rID1cbiAgICB7IHNpemUgPSBTaXplLnVua25vd247IHRva2VuID0gUHBfYmVnaW4gKDAsIFBwX2hvdmJveCk7IGxlbmd0aCA9IDAgfSBpblxuICBRdWV1ZS5hZGQgc3lzX3RvayBwcF9xdWV1ZTtcbiAgbGV0IHNjYW5fc3RhY2sgPSBTdGFjay5jcmVhdGUgKCkgaW5cbiAgaW5pdGlhbGl6ZV9zY2FuX3N0YWNrIHNjYW5fc3RhY2s7XG4gIFN0YWNrLnB1c2ggeyBsZWZ0X3RvdGFsID0gMTsgcXVldWVfZWxlbSA9IHN5c190b2sgfSBzY2FuX3N0YWNrO1xuICBsZXQgcHBfbWFyZ2luID0gNzhcbiAgYW5kIHBwX21pbl9zcGFjZV9sZWZ0ID0gMTAgaW5cbiAge1xuICAgIHBwX3NjYW5fc3RhY2sgPSBzY2FuX3N0YWNrO1xuICAgIHBwX2Zvcm1hdF9zdGFjayA9IFN0YWNrLmNyZWF0ZSAoKTtcbiAgICBwcF90Ym94X3N0YWNrID0gU3RhY2suY3JlYXRlICgpO1xuICAgIHBwX3RhZ19zdGFjayA9IFN0YWNrLmNyZWF0ZSAoKTtcbiAgICBwcF9tYXJrX3N0YWNrID0gU3RhY2suY3JlYXRlICgpO1xuICAgIHBwX21hcmdpbiA9IHBwX21hcmdpbjtcbiAgICBwcF9taW5fc3BhY2VfbGVmdCA9IHBwX21pbl9zcGFjZV9sZWZ0O1xuICAgIHBwX21heF9pbmRlbnQgPSBwcF9tYXJnaW4gLSBwcF9taW5fc3BhY2VfbGVmdDtcbiAgICBwcF9zcGFjZV9sZWZ0ID0gcHBfbWFyZ2luO1xuICAgIHBwX2N1cnJlbnRfaW5kZW50ID0gMDtcbiAgICBwcF9pc19uZXdfbGluZSA9IHRydWU7XG4gICAgcHBfbGVmdF90b3RhbCA9IDE7XG4gICAgcHBfcmlnaHRfdG90YWwgPSAxO1xuICAgIHBwX2N1cnJfZGVwdGggPSAxO1xuICAgIHBwX21heF9ib3hlcyA9IG1heF9pbnQ7XG4gICAgcHBfZWxsaXBzaXMgPSBcIi5cIjtcbiAgICBwcF9vdXRfc3RyaW5nID0gZjtcbiAgICBwcF9vdXRfZmx1c2ggPSBnO1xuICAgIHBwX291dF9uZXdsaW5lID0gaDtcbiAgICBwcF9vdXRfc3BhY2VzID0gaTtcbiAgICBwcF9vdXRfaW5kZW50ID0gajtcbiAgICBwcF9wcmludF90YWdzID0gZmFsc2U7XG4gICAgcHBfbWFya190YWdzID0gZmFsc2U7XG4gICAgcHBfbWFya19vcGVuX3RhZyA9IGRlZmF1bHRfcHBfbWFya19vcGVuX3RhZztcbiAgICBwcF9tYXJrX2Nsb3NlX3RhZyA9IGRlZmF1bHRfcHBfbWFya19jbG9zZV90YWc7XG4gICAgcHBfcHJpbnRfb3Blbl90YWcgPSBkZWZhdWx0X3BwX3ByaW50X29wZW5fdGFnO1xuICAgIHBwX3ByaW50X2Nsb3NlX3RhZyA9IGRlZmF1bHRfcHBfcHJpbnRfY2xvc2VfdGFnO1xuICAgIHBwX3F1ZXVlID0gcHBfcXVldWU7XG4gIH1cblxuXG4oKiBCdWlsZCBhIGZvcm1hdHRlciBvdXQgb2YgaXRzIG91dCBmdW5jdGlvbnMuICopXG5sZXQgZm9ybWF0dGVyX29mX291dF9mdW5jdGlvbnMgb3V0X2Z1bnMgPVxuICBwcF9tYWtlX2Zvcm1hdHRlclxuICAgIG91dF9mdW5zLm91dF9zdHJpbmdcbiAgICBvdXRfZnVucy5vdXRfZmx1c2hcbiAgICBvdXRfZnVucy5vdXRfbmV3bGluZVxuICAgIG91dF9mdW5zLm91dF9zcGFjZXNcbiAgICBvdXRfZnVucy5vdXRfaW5kZW50XG5cblxuKCogTWFrZSBhIGZvcm1hdHRlciB3aXRoIGRlZmF1bHQgZnVuY3Rpb25zIHRvIG91dHB1dCBzcGFjZXMsXG4gIGluZGVudGF0aW9uLCBhbmQgbmV3IGxpbmVzLiAqKVxubGV0IG1ha2VfZm9ybWF0dGVyIG91dHB1dCBmbHVzaCA9XG4gIGxldCBwcGYgPSBwcF9tYWtlX2Zvcm1hdHRlciBvdXRwdXQgZmx1c2ggaWdub3JlIGlnbm9yZSBpZ25vcmUgaW5cbiAgcHBmLnBwX291dF9uZXdsaW5lIDwtIGRpc3BsYXlfbmV3bGluZSBwcGY7XG4gIHBwZi5wcF9vdXRfc3BhY2VzIDwtIGRpc3BsYXlfYmxhbmtzIHBwZjtcbiAgcHBmLnBwX291dF9pbmRlbnQgPC0gZGlzcGxheV9pbmRlbnQgcHBmO1xuICBwcGZcblxuXG4oKiBNYWtlIGEgZm9ybWF0dGVyIHdyaXRpbmcgdG8gYSBnaXZlbiBbUGVydmFzaXZlLm91dF9jaGFubmVsXSB2YWx1ZS4gKilcbmxldCBmb3JtYXR0ZXJfb2Zfb3V0X2NoYW5uZWwgb2MgPVxuICBtYWtlX2Zvcm1hdHRlciAob3V0cHV0X3N1YnN0cmluZyBvYykgKGZ1biAoKSAtPiBmbHVzaCBvYylcblxuXG4oKiBNYWtlIGEgZm9ybWF0dGVyIHdyaXRpbmcgdG8gYSBnaXZlbiBbQnVmZmVyLnRdIHZhbHVlLiAqKVxubGV0IGZvcm1hdHRlcl9vZl9idWZmZXIgYiA9XG4gIG1ha2VfZm9ybWF0dGVyIChCdWZmZXIuYWRkX3N1YnN0cmluZyBiKSBpZ25vcmVcblxuXG4oKiBBbGxvY2F0aW5nIGJ1ZmZlciBmb3IgcHJldHR5LXByaW50aW5nIHB1cnBvc2VzLlxuICAgRGVmYXVsdCBidWZmZXIgc2l6ZSBpcyBwcF9idWZmZXJfc2l6ZSBvciA1MTIuXG4qKVxubGV0IHBwX2J1ZmZlcl9zaXplID0gNTEyXG5sZXQgcHBfbWFrZV9idWZmZXIgKCkgPSBCdWZmZXIuY3JlYXRlIHBwX2J1ZmZlcl9zaXplXG5cbigqIFRoZSBzdGFuZGFyZCAoc2hhcmVkKSBidWZmZXIuICopXG5sZXQgc3RkYnVmID0gcHBfbWFrZV9idWZmZXIgKClcblxuKCogUHJlZGVmaW5lZCBmb3JtYXR0ZXJzIHN0YW5kYXJkIGZvcm1hdHRlciB0byBwcmludFxuICAgdG8gW1N0ZGxpYi5zdGRvdXRdLCBbU3RkbGliLnN0ZGVycl0sIGFuZCB7IXN0ZGJ1Zn0uICopXG5sZXQgc3RkX2Zvcm1hdHRlciA9IGZvcm1hdHRlcl9vZl9vdXRfY2hhbm5lbCBTdGRsaWIuc3Rkb3V0XG5hbmQgZXJyX2Zvcm1hdHRlciA9IGZvcm1hdHRlcl9vZl9vdXRfY2hhbm5lbCBTdGRsaWIuc3RkZXJyXG5hbmQgc3RyX2Zvcm1hdHRlciA9IGZvcm1hdHRlcl9vZl9idWZmZXIgc3RkYnVmXG5cblxuKCogW2ZsdXNoX2J1ZmZlcl9mb3JtYXR0ZXIgYnVmIHBwZl0gZmx1c2hlcyBmb3JtYXR0ZXIgW3BwZl0sXG4gICB0aGVuIHJldHVybnMgdGhlIGNvbnRlbnRzIG9mIGJ1ZmZlciBbYnVmXSB0aGF0IGlzIHJlc2V0LlxuICAgRm9ybWF0dGVyIFtwcGZdIGlzIHN1cHBvc2VkIHRvIHByaW50IHRvIGJ1ZmZlciBbYnVmXSwgb3RoZXJ3aXNlIHRoaXNcbiAgIGZ1bmN0aW9uIGlzIG5vdCByZWFsbHkgdXNlZnVsLiAqKVxubGV0IGZsdXNoX2J1ZmZlcl9mb3JtYXR0ZXIgYnVmIHBwZiA9XG4gIHBwX2ZsdXNoX3F1ZXVlIHBwZiBmYWxzZTtcbiAgbGV0IHMgPSBCdWZmZXIuY29udGVudHMgYnVmIGluXG4gIEJ1ZmZlci5yZXNldCBidWY7XG4gIHNcblxuXG4oKiBGbHVzaCBbc3RyX2Zvcm1hdHRlcl0gYW5kIGdldCB0aGUgY29udGVudHMgb2YgW3N0ZGJ1Zl0uICopXG5sZXQgZmx1c2hfc3RyX2Zvcm1hdHRlciAoKSA9IGZsdXNoX2J1ZmZlcl9mb3JtYXR0ZXIgc3RkYnVmIHN0cl9mb3JtYXR0ZXJcblxuKCpcbiAgU3ltYm9saWMgcHJldHR5LXByaW50aW5nXG4qKVxuXG4oKlxuICBTeW1ib2xpYyBwcmV0dHktcHJpbnRpbmcgaXMgcHJldHR5LXByaW50aW5nIHdpdGggbm8gbG93IGxldmVsIG91dHB1dC5cblxuICBXaGVuIHVzaW5nIGEgc3ltYm9saWMgZm9ybWF0dGVyLCBhbGwgcmVndWxhciBwcmV0dHktcHJpbnRpbmcgYWN0aXZpdGllc1xuICBvY2N1ciBidXQgb3V0cHV0IG1hdGVyaWFsIGlzIHN5bWJvbGljIGFuZCBzdG9yZWQgaW4gYSBidWZmZXIgb2Ygb3V0cHV0XG4gIGl0ZW1zLiBBdCB0aGUgZW5kIG9mIHByZXR0eS1wcmludGluZywgZmx1c2hpbmcgdGhlIG91dHB1dCBidWZmZXIgYWxsb3dzXG4gIHBvc3QtcHJvY2Vzc2luZyBvZiBzeW1ib2xpYyBvdXRwdXQgYmVmb3JlIGxvdyBsZXZlbCBvdXRwdXQgb3BlcmF0aW9ucy5cbiopXG5cbnR5cGUgc3ltYm9saWNfb3V0cHV0X2l0ZW0gPVxuICB8IE91dHB1dF9mbHVzaFxuICB8IE91dHB1dF9uZXdsaW5lXG4gIHwgT3V0cHV0X3N0cmluZyBvZiBzdHJpbmdcbiAgfCBPdXRwdXRfc3BhY2VzIG9mIGludFxuICB8IE91dHB1dF9pbmRlbnQgb2YgaW50XG5cbnR5cGUgc3ltYm9saWNfb3V0cHV0X2J1ZmZlciA9IHtcbiAgbXV0YWJsZSBzeW1ib2xpY19vdXRwdXRfY29udGVudHMgOiBzeW1ib2xpY19vdXRwdXRfaXRlbSBsaXN0O1xufVxuXG5sZXQgbWFrZV9zeW1ib2xpY19vdXRwdXRfYnVmZmVyICgpID1cbiAgeyBzeW1ib2xpY19vdXRwdXRfY29udGVudHMgPSBbXSB9XG5cbmxldCBjbGVhcl9zeW1ib2xpY19vdXRwdXRfYnVmZmVyIHNvYiA9XG4gIHNvYi5zeW1ib2xpY19vdXRwdXRfY29udGVudHMgPC0gW11cblxubGV0IGdldF9zeW1ib2xpY19vdXRwdXRfYnVmZmVyIHNvYiA9XG4gIExpc3QucmV2IHNvYi5zeW1ib2xpY19vdXRwdXRfY29udGVudHNcblxubGV0IGZsdXNoX3N5bWJvbGljX291dHB1dF9idWZmZXIgc29iID1cbiAgbGV0IGl0ZW1zID0gZ2V0X3N5bWJvbGljX291dHB1dF9idWZmZXIgc29iIGluXG4gIGNsZWFyX3N5bWJvbGljX291dHB1dF9idWZmZXIgc29iO1xuICBpdGVtc1xuXG5sZXQgYWRkX3N5bWJvbGljX291dHB1dF9pdGVtIHNvYiBpdGVtID1cbiAgc29iLnN5bWJvbGljX291dHB1dF9jb250ZW50cyA8LSBpdGVtIDo6IHNvYi5zeW1ib2xpY19vdXRwdXRfY29udGVudHNcblxubGV0IGZvcm1hdHRlcl9vZl9zeW1ib2xpY19vdXRwdXRfYnVmZmVyIHNvYiA9XG4gIGxldCBzeW1ib2xpY19mbHVzaCBzb2IgKCkgPVxuICAgIGFkZF9zeW1ib2xpY19vdXRwdXRfaXRlbSBzb2IgT3V0cHV0X2ZsdXNoXG4gIGFuZCBzeW1ib2xpY19uZXdsaW5lIHNvYiAoKSA9XG4gICAgYWRkX3N5bWJvbGljX291dHB1dF9pdGVtIHNvYiBPdXRwdXRfbmV3bGluZVxuICBhbmQgc3ltYm9saWNfc3RyaW5nIHNvYiBzIGkgbiA9XG4gICAgYWRkX3N5bWJvbGljX291dHB1dF9pdGVtIHNvYiAoT3V0cHV0X3N0cmluZyAoU3RyaW5nLnN1YiBzIGkgbikpXG4gIGFuZCBzeW1ib2xpY19zcGFjZXMgc29iIG4gPVxuICAgIGFkZF9zeW1ib2xpY19vdXRwdXRfaXRlbSBzb2IgKE91dHB1dF9zcGFjZXMgbilcbiAgYW5kIHN5bWJvbGljX2luZGVudCBzb2IgbiA9XG4gICAgYWRkX3N5bWJvbGljX291dHB1dF9pdGVtIHNvYiAoT3V0cHV0X2luZGVudCBuKSBpblxuXG4gIGxldCBmID0gc3ltYm9saWNfc3RyaW5nIHNvYlxuICBhbmQgZyA9IHN5bWJvbGljX2ZsdXNoIHNvYlxuICBhbmQgaCA9IHN5bWJvbGljX25ld2xpbmUgc29iXG4gIGFuZCBpID0gc3ltYm9saWNfc3BhY2VzIHNvYlxuICBhbmQgaiA9IHN5bWJvbGljX2luZGVudCBzb2IgaW5cbiAgcHBfbWFrZV9mb3JtYXR0ZXIgZiBnIGggaSBqXG5cbigqXG5cbiAgQmFzaWMgZnVuY3Rpb25zIG9uIHRoZSAnc3RhbmRhcmQnIGZvcm1hdHRlclxuICAodGhlIGZvcm1hdHRlciB0aGF0IHByaW50cyB0byBbU3RkbGliLnN0ZG91dF0pLlxuXG4qKVxuXG5sZXQgb3Blbl9oYm94ID0gcHBfb3Blbl9oYm94IHN0ZF9mb3JtYXR0ZXJcbmFuZCBvcGVuX3Zib3ggPSBwcF9vcGVuX3Zib3ggc3RkX2Zvcm1hdHRlclxuYW5kIG9wZW5faHZib3ggPSBwcF9vcGVuX2h2Ym94IHN0ZF9mb3JtYXR0ZXJcbmFuZCBvcGVuX2hvdmJveCA9IHBwX29wZW5faG92Ym94IHN0ZF9mb3JtYXR0ZXJcbmFuZCBvcGVuX2JveCA9IHBwX29wZW5fYm94IHN0ZF9mb3JtYXR0ZXJcbmFuZCBjbG9zZV9ib3ggPSBwcF9jbG9zZV9ib3ggc3RkX2Zvcm1hdHRlclxuYW5kIG9wZW5fdGFnID0gcHBfb3Blbl90YWcgc3RkX2Zvcm1hdHRlclxuYW5kIGNsb3NlX3RhZyA9IHBwX2Nsb3NlX3RhZyBzdGRfZm9ybWF0dGVyXG5hbmQgb3Blbl9zdGFnID0gcHBfb3Blbl9zdGFnIHN0ZF9mb3JtYXR0ZXJcbmFuZCBjbG9zZV9zdGFnID0gcHBfY2xvc2Vfc3RhZyBzdGRfZm9ybWF0dGVyXG5hbmQgcHJpbnRfYXMgPSBwcF9wcmludF9hcyBzdGRfZm9ybWF0dGVyXG5hbmQgcHJpbnRfc3RyaW5nID0gcHBfcHJpbnRfc3RyaW5nIHN0ZF9mb3JtYXR0ZXJcbmFuZCBwcmludF9ieXRlcyA9IHBwX3ByaW50X2J5dGVzIHN0ZF9mb3JtYXR0ZXJcbmFuZCBwcmludF9pbnQgPSBwcF9wcmludF9pbnQgc3RkX2Zvcm1hdHRlclxuYW5kIHByaW50X2Zsb2F0ID0gcHBfcHJpbnRfZmxvYXQgc3RkX2Zvcm1hdHRlclxuYW5kIHByaW50X2NoYXIgPSBwcF9wcmludF9jaGFyIHN0ZF9mb3JtYXR0ZXJcbmFuZCBwcmludF9ib29sID0gcHBfcHJpbnRfYm9vbCBzdGRfZm9ybWF0dGVyXG5hbmQgcHJpbnRfYnJlYWsgPSBwcF9wcmludF9icmVhayBzdGRfZm9ybWF0dGVyXG5hbmQgcHJpbnRfY3V0ID0gcHBfcHJpbnRfY3V0IHN0ZF9mb3JtYXR0ZXJcbmFuZCBwcmludF9zcGFjZSA9IHBwX3ByaW50X3NwYWNlIHN0ZF9mb3JtYXR0ZXJcbmFuZCBmb3JjZV9uZXdsaW5lID0gcHBfZm9yY2VfbmV3bGluZSBzdGRfZm9ybWF0dGVyXG5hbmQgcHJpbnRfZmx1c2ggPSBwcF9wcmludF9mbHVzaCBzdGRfZm9ybWF0dGVyXG5hbmQgcHJpbnRfbmV3bGluZSA9IHBwX3ByaW50X25ld2xpbmUgc3RkX2Zvcm1hdHRlclxuYW5kIHByaW50X2lmX25ld2xpbmUgPSBwcF9wcmludF9pZl9uZXdsaW5lIHN0ZF9mb3JtYXR0ZXJcblxuYW5kIG9wZW5fdGJveCA9IHBwX29wZW5fdGJveCBzdGRfZm9ybWF0dGVyXG5hbmQgY2xvc2VfdGJveCA9IHBwX2Nsb3NlX3Rib3ggc3RkX2Zvcm1hdHRlclxuYW5kIHByaW50X3RicmVhayA9IHBwX3ByaW50X3RicmVhayBzdGRfZm9ybWF0dGVyXG5cbmFuZCBzZXRfdGFiID0gcHBfc2V0X3RhYiBzdGRfZm9ybWF0dGVyXG5hbmQgcHJpbnRfdGFiID0gcHBfcHJpbnRfdGFiIHN0ZF9mb3JtYXR0ZXJcblxuYW5kIHNldF9tYXJnaW4gPSBwcF9zZXRfbWFyZ2luIHN0ZF9mb3JtYXR0ZXJcbmFuZCBnZXRfbWFyZ2luID0gcHBfZ2V0X21hcmdpbiBzdGRfZm9ybWF0dGVyXG5cbmFuZCBzZXRfbWF4X2luZGVudCA9IHBwX3NldF9tYXhfaW5kZW50IHN0ZF9mb3JtYXR0ZXJcbmFuZCBnZXRfbWF4X2luZGVudCA9IHBwX2dldF9tYXhfaW5kZW50IHN0ZF9mb3JtYXR0ZXJcblxuYW5kIHNldF9nZW9tZXRyeSA9IHBwX3NldF9nZW9tZXRyeSBzdGRfZm9ybWF0dGVyXG5hbmQgc2FmZV9zZXRfZ2VvbWV0cnkgPSBwcF9zYWZlX3NldF9nZW9tZXRyeSBzdGRfZm9ybWF0dGVyXG5hbmQgZ2V0X2dlb21ldHJ5ID0gcHBfZ2V0X2dlb21ldHJ5IHN0ZF9mb3JtYXR0ZXJcbmFuZCB1cGRhdGVfZ2VvbWV0cnkgPSBwcF91cGRhdGVfZ2VvbWV0cnkgc3RkX2Zvcm1hdHRlclxuXG5hbmQgc2V0X21heF9ib3hlcyA9IHBwX3NldF9tYXhfYm94ZXMgc3RkX2Zvcm1hdHRlclxuYW5kIGdldF9tYXhfYm94ZXMgPSBwcF9nZXRfbWF4X2JveGVzIHN0ZF9mb3JtYXR0ZXJcbmFuZCBvdmVyX21heF9ib3hlcyA9IHBwX292ZXJfbWF4X2JveGVzIHN0ZF9mb3JtYXR0ZXJcblxuYW5kIHNldF9lbGxpcHNpc190ZXh0ID0gcHBfc2V0X2VsbGlwc2lzX3RleHQgc3RkX2Zvcm1hdHRlclxuYW5kIGdldF9lbGxpcHNpc190ZXh0ID0gcHBfZ2V0X2VsbGlwc2lzX3RleHQgc3RkX2Zvcm1hdHRlclxuXG5hbmQgc2V0X2Zvcm1hdHRlcl9vdXRfY2hhbm5lbCA9XG4gIHBwX3NldF9mb3JtYXR0ZXJfb3V0X2NoYW5uZWwgc3RkX2Zvcm1hdHRlclxuXG5hbmQgc2V0X2Zvcm1hdHRlcl9vdXRfZnVuY3Rpb25zID1cbiAgcHBfc2V0X2Zvcm1hdHRlcl9vdXRfZnVuY3Rpb25zIHN0ZF9mb3JtYXR0ZXJcbmFuZCBnZXRfZm9ybWF0dGVyX291dF9mdW5jdGlvbnMgPVxuICBwcF9nZXRfZm9ybWF0dGVyX291dF9mdW5jdGlvbnMgc3RkX2Zvcm1hdHRlclxuXG5hbmQgc2V0X2Zvcm1hdHRlcl9vdXRwdXRfZnVuY3Rpb25zID1cbiAgcHBfc2V0X2Zvcm1hdHRlcl9vdXRwdXRfZnVuY3Rpb25zIHN0ZF9mb3JtYXR0ZXJcbmFuZCBnZXRfZm9ybWF0dGVyX291dHB1dF9mdW5jdGlvbnMgPVxuICBwcF9nZXRfZm9ybWF0dGVyX291dHB1dF9mdW5jdGlvbnMgc3RkX2Zvcm1hdHRlclxuXG5hbmQgc2V0X2Zvcm1hdHRlcl9zdGFnX2Z1bmN0aW9ucyA9XG4gIHBwX3NldF9mb3JtYXR0ZXJfc3RhZ19mdW5jdGlvbnMgc3RkX2Zvcm1hdHRlclxuYW5kIGdldF9mb3JtYXR0ZXJfc3RhZ19mdW5jdGlvbnMgPVxuICBwcF9nZXRfZm9ybWF0dGVyX3N0YWdfZnVuY3Rpb25zIHN0ZF9mb3JtYXR0ZXJcbmFuZCBzZXRfcHJpbnRfdGFncyA9XG4gIHBwX3NldF9wcmludF90YWdzIHN0ZF9mb3JtYXR0ZXJcbmFuZCBnZXRfcHJpbnRfdGFncyA9XG4gIHBwX2dldF9wcmludF90YWdzIHN0ZF9mb3JtYXR0ZXJcbmFuZCBzZXRfbWFya190YWdzID1cbiAgcHBfc2V0X21hcmtfdGFncyBzdGRfZm9ybWF0dGVyXG5hbmQgZ2V0X21hcmtfdGFncyA9XG4gIHBwX2dldF9tYXJrX3RhZ3Mgc3RkX2Zvcm1hdHRlclxuYW5kIHNldF90YWdzID1cbiAgcHBfc2V0X3RhZ3Mgc3RkX2Zvcm1hdHRlclxuXG5cbigqIENvbnZlbmllbmNlIGZ1bmN0aW9ucyAqKVxuXG4oKiBUbyBmb3JtYXQgYSBsaXN0ICopXG5sZXQgcmVjIHBwX3ByaW50X2xpc3QgPyhwcF9zZXAgPSBwcF9wcmludF9jdXQpIHBwX3YgcHBmID0gZnVuY3Rpb25cbiAgfCBbXSAtPiAoKVxuICB8IFt2XSAtPiBwcF92IHBwZiB2XG4gIHwgdiA6OiB2cyAtPlxuICAgIHBwX3YgcHBmIHY7XG4gICAgcHBfc2VwIHBwZiAoKTtcbiAgICBwcF9wcmludF9saXN0IH5wcF9zZXAgcHBfdiBwcGYgdnNcblxuKCogVG8gZm9ybWF0IGEgc2VxdWVuY2UgKilcbmxldCByZWMgcHBfcHJpbnRfc2VxX2luIH5wcF9zZXAgcHBfdiBwcGYgc2VxID1cbiAgbWF0Y2ggc2VxICgpIHdpdGhcbiAgfCBTZXEuTmlsIC0+ICgpXG4gIHwgU2VxLkNvbnMgKHYsIHNlcSkgLT5cbiAgICBwcF9zZXAgcHBmICgpO1xuICAgIHBwX3YgcHBmIHY7XG4gICAgcHBfcHJpbnRfc2VxX2luIH5wcF9zZXAgcHBfdiBwcGYgc2VxXG5cbmxldCBwcF9wcmludF9zZXEgPyhwcF9zZXAgPSBwcF9wcmludF9jdXQpIHBwX3YgcHBmIHNlcSA9XG4gIG1hdGNoIHNlcSAoKSB3aXRoXG4gIHwgU2VxLk5pbCAtPiAoKVxuICB8IFNlcS5Db25zICh2LCBzZXEpIC0+XG4gICAgcHBfdiBwcGYgdjtcbiAgICBwcF9wcmludF9zZXFfaW4gfnBwX3NlcCBwcF92IHBwZiBzZXFcblxuKCogVG8gZm9ybWF0IGZyZWUtZmxvd2luZyB0ZXh0ICopXG5sZXQgcHBfcHJpbnRfdGV4dCBwcGYgcyA9XG4gIGxldCBsZW4gPSBTdHJpbmcubGVuZ3RoIHMgaW5cbiAgbGV0IGxlZnQgPSByZWYgMCBpblxuICBsZXQgcmlnaHQgPSByZWYgMCBpblxuICBsZXQgZmx1c2ggKCkgPVxuICAgIHBwX3ByaW50X3N0cmluZyBwcGYgKFN0cmluZy5zdWIgcyAhbGVmdCAoIXJpZ2h0IC0gIWxlZnQpKTtcbiAgICBpbmNyIHJpZ2h0OyBsZWZ0IDo9ICFyaWdodDtcbiAgaW5cbiAgd2hpbGUgKCFyaWdodCA8PiBsZW4pIGRvXG4gICAgbWF0Y2ggcy5bIXJpZ2h0XSB3aXRoXG4gICAgICB8ICdcXG4nIC0+XG4gICAgICAgIGZsdXNoICgpO1xuICAgICAgICBwcF9mb3JjZV9uZXdsaW5lIHBwZiAoKVxuICAgICAgfCAnICcgLT5cbiAgICAgICAgZmx1c2ggKCk7IHBwX3ByaW50X3NwYWNlIHBwZiAoKVxuICAgICAgKCogdGhlcmUgaXMgbm8gc3BlY2lmaWMgc3VwcG9ydCBmb3IgJ1xcdCdcbiAgICAgICAgIGFzIGl0IGlzIHVuY2xlYXIgd2hhdCBhIHJpZ2h0IHNlbWFudGljcyB3b3VsZCBiZSAqKVxuICAgICAgfCBfIC0+IGluY3IgcmlnaHRcbiAgZG9uZTtcbiAgaWYgIWxlZnQgPD4gbGVuIHRoZW4gZmx1c2ggKClcblxubGV0IHBwX3ByaW50X29wdGlvbiA/KG5vbmUgPSBmdW4gXyAoKSAtPiAoKSkgcHBfdiBwcGYgPSBmdW5jdGlvblxufCBOb25lIC0+IG5vbmUgcHBmICgpXG58IFNvbWUgdiAtPiBwcF92IHBwZiB2XG5cbmxldCBwcF9wcmludF9yZXN1bHQgfm9rIH5lcnJvciBwcGYgPSBmdW5jdGlvblxufCBPayB2IC0+IG9rIHBwZiB2XG58IEVycm9yIGUgLT4gZXJyb3IgcHBmIGVcblxubGV0IHBwX3ByaW50X2VpdGhlciB+bGVmdCB+cmlnaHQgcHBmID0gZnVuY3Rpb25cbnwgRWl0aGVyLkxlZnQgbCAtPiBsZWZ0IHBwZiBsXG58IEVpdGhlci5SaWdodCByIC0+IHJpZ2h0IHBwZiByXG5cbiAoKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG5cbmxldCBjb21wdXRlX3RhZyBvdXRwdXQgdGFnX2FjYyA9XG4gIGxldCBidWYgPSBCdWZmZXIuY3JlYXRlIDE2IGluXG4gIGxldCBwcGYgPSBmb3JtYXR0ZXJfb2ZfYnVmZmVyIGJ1ZiBpblxuICBvdXRwdXQgcHBmIHRhZ19hY2M7XG4gIHBwX3ByaW50X2ZsdXNoIHBwZiAoKTtcbiAgbGV0IGxlbiA9IEJ1ZmZlci5sZW5ndGggYnVmIGluXG4gIGlmIGxlbiA8IDIgdGhlbiBCdWZmZXIuY29udGVudHMgYnVmXG4gIGVsc2UgQnVmZmVyLnN1YiBidWYgMSAobGVuIC0gMilcblxuICgqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuXG4gIERlZmluaW5nIGNvbnRpbnVhdGlvbnMgdG8gYmUgcGFzc2VkIGFzIGFyZ3VtZW50cyBvZlxuICBDYW1saW50ZXJuYWxGb3JtYXQubWFrZV9wcmludGYuXG5cbiAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG5cbm9wZW4gQ2FtbGludGVybmFsRm9ybWF0QmFzaWNzXG5vcGVuIENhbWxpbnRlcm5hbEZvcm1hdFxuXG4oKiBJbnRlcnByZXQgYSBmb3JtYXR0aW5nIGVudGl0eSBvbiBhIGZvcm1hdHRlci4gKilcbmxldCBvdXRwdXRfZm9ybWF0dGluZ19saXQgcHBmIGZtdGluZ19saXQgPSBtYXRjaCBmbXRpbmdfbGl0IHdpdGhcbiAgfCBDbG9zZV9ib3ggICAgICAgICAgICAgICAgIC0+IHBwX2Nsb3NlX2JveCBwcGYgKClcbiAgfCBDbG9zZV90YWcgICAgICAgICAgICAgICAgIC0+IHBwX2Nsb3NlX3RhZyBwcGYgKClcbiAgfCBCcmVhayAoXywgd2lkdGgsIG9mZnNldCkgIC0+IHBwX3ByaW50X2JyZWFrIHBwZiB3aWR0aCBvZmZzZXRcbiAgfCBGRmx1c2ggICAgICAgICAgICAgICAgICAgIC0+IHBwX3ByaW50X2ZsdXNoIHBwZiAoKVxuICB8IEZvcmNlX25ld2xpbmUgICAgICAgICAgICAgLT4gcHBfZm9yY2VfbmV3bGluZSBwcGYgKClcbiAgfCBGbHVzaF9uZXdsaW5lICAgICAgICAgICAgIC0+IHBwX3ByaW50X25ld2xpbmUgcHBmICgpXG4gIHwgTWFnaWNfc2l6ZSAoXywgXykgICAgICAgICAtPiAoKVxuICB8IEVzY2FwZWRfYXQgICAgICAgICAgICAgICAgLT4gcHBfcHJpbnRfY2hhciBwcGYgJ0AnXG4gIHwgRXNjYXBlZF9wZXJjZW50ICAgICAgICAgICAtPiBwcF9wcmludF9jaGFyIHBwZiAnJSdcbiAgfCBTY2FuX2luZGljIGMgICAgICAgICAgICAgIC0+IHBwX3ByaW50X2NoYXIgcHBmICdAJzsgcHBfcHJpbnRfY2hhciBwcGYgY1xuXG4oKiBSZWN1cnNpdmVseSBvdXRwdXQgYW4gXCJhY2N1bXVsYXRvclwiIGNvbnRhaW5pbmcgYSByZXZlcnNlZCBsaXN0IG9mXG4gICBwcmludGluZyBlbnRpdGllcyAoc3RyaW5nLCBjaGFyLCBmbHVzLCAuLi4pIGluIGFuIG91dHB1dF9zdHJlYW0uICopXG4oKiBEaWZmZXIgZnJvbSBQcmludGYub3V0cHV0X2FjYyBieSB0aGUgaW50ZXJwcmV0YXRpb24gb2YgZm9ybWF0dGluZy4gKilcbigqIFVzZWQgYXMgYSBjb250aW51YXRpb24gb2YgQ2FtbGludGVybmFsRm9ybWF0Lm1ha2VfcHJpbnRmLiAqKVxubGV0IHJlYyBvdXRwdXRfYWNjIHBwZiBhY2MgPSBtYXRjaCBhY2Mgd2l0aFxuICB8IEFjY19zdHJpbmdfbGl0ZXJhbCAoQWNjX2Zvcm1hdHRpbmdfbGl0IChwLCBNYWdpY19zaXplIChfLCBzaXplKSksIHMpXG4gIHwgQWNjX2RhdGFfc3RyaW5nIChBY2NfZm9ybWF0dGluZ19saXQgKHAsIE1hZ2ljX3NpemUgKF8sIHNpemUpKSwgcykgLT5cbiAgICBvdXRwdXRfYWNjIHBwZiBwO1xuICAgIHBwX3ByaW50X2FzX3NpemUgcHBmIChTaXplLm9mX2ludCBzaXplKSBzO1xuICB8IEFjY19jaGFyX2xpdGVyYWwgKEFjY19mb3JtYXR0aW5nX2xpdCAocCwgTWFnaWNfc2l6ZSAoXywgc2l6ZSkpLCBjKVxuICB8IEFjY19kYXRhX2NoYXIgKEFjY19mb3JtYXR0aW5nX2xpdCAocCwgTWFnaWNfc2l6ZSAoXywgc2l6ZSkpLCBjKSAtPlxuICAgIG91dHB1dF9hY2MgcHBmIHA7XG4gICAgcHBfcHJpbnRfYXNfc2l6ZSBwcGYgKFNpemUub2ZfaW50IHNpemUpIChTdHJpbmcubWFrZSAxIGMpO1xuICB8IEFjY19mb3JtYXR0aW5nX2xpdCAocCwgZikgLT5cbiAgICBvdXRwdXRfYWNjIHBwZiBwO1xuICAgIG91dHB1dF9mb3JtYXR0aW5nX2xpdCBwcGYgZjtcbiAgfCBBY2NfZm9ybWF0dGluZ19nZW4gKHAsIEFjY19vcGVuX3RhZyBhY2MnKSAtPlxuICAgIG91dHB1dF9hY2MgcHBmIHA7XG4gICAgcHBfb3Blbl9zdGFnIHBwZiAoU3RyaW5nX3RhZyAoY29tcHV0ZV90YWcgb3V0cHV0X2FjYyBhY2MnKSlcbiAgfCBBY2NfZm9ybWF0dGluZ19nZW4gKHAsIEFjY19vcGVuX2JveCBhY2MnKSAtPlxuICAgIG91dHB1dF9hY2MgcHBmIHA7XG4gICAgbGV0IChpbmRlbnQsIGJ0eSkgPSBvcGVuX2JveF9vZl9zdHJpbmcgKGNvbXB1dGVfdGFnIG91dHB1dF9hY2MgYWNjJykgaW5cbiAgICBwcF9vcGVuX2JveF9nZW4gcHBmIGluZGVudCBidHlcbiAgfCBBY2Nfc3RyaW5nX2xpdGVyYWwgKHAsIHMpXG4gIHwgQWNjX2RhdGFfc3RyaW5nIChwLCBzKSAgIC0+IG91dHB1dF9hY2MgcHBmIHA7IHBwX3ByaW50X3N0cmluZyBwcGYgcztcbiAgfCBBY2NfY2hhcl9saXRlcmFsIChwLCBjKVxuICB8IEFjY19kYXRhX2NoYXIgKHAsIGMpICAgICAtPiBvdXRwdXRfYWNjIHBwZiBwOyBwcF9wcmludF9jaGFyIHBwZiBjO1xuICB8IEFjY19kZWxheSAocCwgZikgICAgICAgICAtPiBvdXRwdXRfYWNjIHBwZiBwOyBmIHBwZjtcbiAgfCBBY2NfZmx1c2ggcCAgICAgICAgICAgICAgLT4gb3V0cHV0X2FjYyBwcGYgcDsgcHBfcHJpbnRfZmx1c2ggcHBmICgpO1xuICB8IEFjY19pbnZhbGlkX2FyZyAocCwgbXNnKSAtPiBvdXRwdXRfYWNjIHBwZiBwOyBpbnZhbGlkX2FyZyBtc2c7XG4gIHwgRW5kX29mX2FjYyAgICAgICAgICAgICAgIC0+ICgpXG5cbigqIFJlY3Vyc2l2ZWx5IG91dHB1dCBhbiBcImFjY3VtdWxhdG9yXCIgY29udGFpbmluZyBhIHJldmVyc2VkIGxpc3Qgb2ZcbiAgIHByaW50aW5nIGVudGl0aWVzIChzdHJpbmcsIGNoYXIsIGZsdXMsIC4uLikgaW4gYSBidWZmZXIuICopXG4oKiBEaWZmZXIgZnJvbSBQcmludGYuYnVmcHV0X2FjYyBieSB0aGUgaW50ZXJwcmV0YXRpb24gb2YgZm9ybWF0dGluZy4gKilcbigqIFVzZWQgYXMgYSBjb250aW51YXRpb24gb2YgQ2FtbGludGVybmFsRm9ybWF0Lm1ha2VfcHJpbnRmLiAqKVxubGV0IHJlYyBzdHJwdXRfYWNjIHBwZiBhY2MgPSBtYXRjaCBhY2Mgd2l0aFxuICB8IEFjY19zdHJpbmdfbGl0ZXJhbCAoQWNjX2Zvcm1hdHRpbmdfbGl0IChwLCBNYWdpY19zaXplIChfLCBzaXplKSksIHMpXG4gIHwgQWNjX2RhdGFfc3RyaW5nIChBY2NfZm9ybWF0dGluZ19saXQgKHAsIE1hZ2ljX3NpemUgKF8sIHNpemUpKSwgcykgLT5cbiAgICBzdHJwdXRfYWNjIHBwZiBwO1xuICAgIHBwX3ByaW50X2FzX3NpemUgcHBmIChTaXplLm9mX2ludCBzaXplKSBzO1xuICB8IEFjY19jaGFyX2xpdGVyYWwgKEFjY19mb3JtYXR0aW5nX2xpdCAocCwgTWFnaWNfc2l6ZSAoXywgc2l6ZSkpLCBjKVxuICB8IEFjY19kYXRhX2NoYXIgKEFjY19mb3JtYXR0aW5nX2xpdCAocCwgTWFnaWNfc2l6ZSAoXywgc2l6ZSkpLCBjKSAtPlxuICAgIHN0cnB1dF9hY2MgcHBmIHA7XG4gICAgcHBfcHJpbnRfYXNfc2l6ZSBwcGYgKFNpemUub2ZfaW50IHNpemUpIChTdHJpbmcubWFrZSAxIGMpO1xuICB8IEFjY19kZWxheSAoQWNjX2Zvcm1hdHRpbmdfbGl0IChwLCBNYWdpY19zaXplIChfLCBzaXplKSksIGYpIC0+XG4gICAgc3RycHV0X2FjYyBwcGYgcDtcbiAgICBwcF9wcmludF9hc19zaXplIHBwZiAoU2l6ZS5vZl9pbnQgc2l6ZSkgKGYgKCkpO1xuICB8IEFjY19mb3JtYXR0aW5nX2xpdCAocCwgZikgLT5cbiAgICBzdHJwdXRfYWNjIHBwZiBwO1xuICAgIG91dHB1dF9mb3JtYXR0aW5nX2xpdCBwcGYgZjtcbiAgfCBBY2NfZm9ybWF0dGluZ19nZW4gKHAsIEFjY19vcGVuX3RhZyBhY2MnKSAtPlxuICAgIHN0cnB1dF9hY2MgcHBmIHA7XG4gICAgcHBfb3Blbl9zdGFnIHBwZiAoU3RyaW5nX3RhZyAoY29tcHV0ZV90YWcgc3RycHV0X2FjYyBhY2MnKSlcbiAgfCBBY2NfZm9ybWF0dGluZ19nZW4gKHAsIEFjY19vcGVuX2JveCBhY2MnKSAtPlxuICAgIHN0cnB1dF9hY2MgcHBmIHA7XG4gICAgbGV0IChpbmRlbnQsIGJ0eSkgPSBvcGVuX2JveF9vZl9zdHJpbmcgKGNvbXB1dGVfdGFnIHN0cnB1dF9hY2MgYWNjJykgaW5cbiAgICBwcF9vcGVuX2JveF9nZW4gcHBmIGluZGVudCBidHlcbiAgfCBBY2Nfc3RyaW5nX2xpdGVyYWwgKHAsIHMpXG4gIHwgQWNjX2RhdGFfc3RyaW5nIChwLCBzKSAgIC0+IHN0cnB1dF9hY2MgcHBmIHA7IHBwX3ByaW50X3N0cmluZyBwcGYgcztcbiAgfCBBY2NfY2hhcl9saXRlcmFsIChwLCBjKVxuICB8IEFjY19kYXRhX2NoYXIgKHAsIGMpICAgICAtPiBzdHJwdXRfYWNjIHBwZiBwOyBwcF9wcmludF9jaGFyIHBwZiBjO1xuICB8IEFjY19kZWxheSAocCwgZikgICAgICAgICAtPiBzdHJwdXRfYWNjIHBwZiBwOyBwcF9wcmludF9zdHJpbmcgcHBmIChmICgpKTtcbiAgfCBBY2NfZmx1c2ggcCAgICAgICAgICAgICAgLT4gc3RycHV0X2FjYyBwcGYgcDsgcHBfcHJpbnRfZmx1c2ggcHBmICgpO1xuICB8IEFjY19pbnZhbGlkX2FyZyAocCwgbXNnKSAtPiBzdHJwdXRfYWNjIHBwZiBwOyBpbnZhbGlkX2FyZyBtc2c7XG4gIHwgRW5kX29mX2FjYyAgICAgICAgICAgICAgIC0+ICgpXG5cbigqXG5cbiAgRGVmaW5pbmcgW2ZwcmludGZdIGFuZCB2YXJpb3VzIGZsYXZvcnMgb2YgW2ZwcmludGZdLlxuXG4qKVxuXG5sZXQga2ZwcmludGYgayBwcGYgKEZvcm1hdCAoZm10LCBfKSkgPVxuICBtYWtlX3ByaW50ZlxuICAgIChmdW4gYWNjIC0+IG91dHB1dF9hY2MgcHBmIGFjYzsgayBwcGYpXG4gICAgRW5kX29mX2FjYyBmbXRcblxuYW5kIGlrZnByaW50ZiBrIHBwZiAoRm9ybWF0IChmbXQsIF8pKSA9XG4gIG1ha2VfaXByaW50ZiBrIHBwZiBmbXRcblxubGV0IGlmcHJpbnRmIF9wcGYgKEZvcm1hdCAoZm10LCBfKSkgPVxuICBtYWtlX2lwcmludGYgaWdub3JlICgpIGZtdFxuXG5sZXQgZnByaW50ZiBwcGYgPSBrZnByaW50ZiBpZ25vcmUgcHBmXG5sZXQgcHJpbnRmIGZtdCA9IGZwcmludGYgc3RkX2Zvcm1hdHRlciBmbXRcbmxldCBlcHJpbnRmIGZtdCA9IGZwcmludGYgZXJyX2Zvcm1hdHRlciBmbXRcblxubGV0IGtkcHJpbnRmIGsgKEZvcm1hdCAoZm10LCBfKSkgPVxuICBtYWtlX3ByaW50ZlxuICAgIChmdW4gYWNjIC0+IGsgKGZ1biBwcGYgLT4gb3V0cHV0X2FjYyBwcGYgYWNjKSlcbiAgICBFbmRfb2ZfYWNjIGZtdFxuXG5sZXQgZHByaW50ZiBmbXQgPSBrZHByaW50ZiAoZnVuIGkgLT4gaSkgZm10XG5cbmxldCBrc3ByaW50ZiBrIChGb3JtYXQgKGZtdCwgXykpID1cbiAgbGV0IGIgPSBwcF9tYWtlX2J1ZmZlciAoKSBpblxuICBsZXQgcHBmID0gZm9ybWF0dGVyX29mX2J1ZmZlciBiIGluXG4gIGxldCBrIGFjYyA9XG4gICAgc3RycHV0X2FjYyBwcGYgYWNjO1xuICAgIGsgKGZsdXNoX2J1ZmZlcl9mb3JtYXR0ZXIgYiBwcGYpIGluXG4gIG1ha2VfcHJpbnRmIGsgRW5kX29mX2FjYyBmbXRcblxuXG5sZXQgc3ByaW50ZiBmbXQgPSBrc3ByaW50ZiBpZCBmbXRcblxubGV0IGthc3ByaW50ZiBrIChGb3JtYXQgKGZtdCwgXykpID1cbiAgbGV0IGIgPSBwcF9tYWtlX2J1ZmZlciAoKSBpblxuICBsZXQgcHBmID0gZm9ybWF0dGVyX29mX2J1ZmZlciBiIGluXG4gIGxldCBrIGFjYyA9XG4gICAgb3V0cHV0X2FjYyBwcGYgYWNjO1xuICAgIGsgKGZsdXNoX2J1ZmZlcl9mb3JtYXR0ZXIgYiBwcGYpIGluXG4gIG1ha2VfcHJpbnRmIGsgRW5kX29mX2FjYyBmbXRcblxuXG5sZXQgYXNwcmludGYgZm10ID0ga2FzcHJpbnRmIGlkIGZtdFxuXG4oKiBGbHVzaGluZyBzdGFuZGFyZCBmb3JtYXR0ZXJzIGF0IGVuZCBvZiBleGVjdXRpb24uICopXG5cbmxldCBmbHVzaF9zdGFuZGFyZF9mb3JtYXR0ZXJzICgpID1cbiAgcHBfcHJpbnRfZmx1c2ggc3RkX2Zvcm1hdHRlciAoKTtcbiAgcHBfcHJpbnRfZmx1c2ggZXJyX2Zvcm1hdHRlciAoKVxuXG5sZXQgKCkgPSBhdF9leGl0IGZsdXNoX3N0YW5kYXJkX2Zvcm1hdHRlcnNcblxuKCpcblxuICBEZXByZWNhdGVkIHN0dWZmLlxuXG4qKVxuXG4oKiBEZXByZWNhdGVkIDogc3Vic3VtZWQgYnkgcHBfc2V0X2Zvcm1hdHRlcl9vdXRfZnVuY3Rpb25zICopXG5sZXQgcHBfc2V0X2FsbF9mb3JtYXR0ZXJfb3V0cHV0X2Z1bmN0aW9ucyBzdGF0ZVxuICAgIH5vdXQ6ZiB+Zmx1c2g6ZyB+bmV3bGluZTpoIH5zcGFjZXM6aSA9XG4gIHBwX3NldF9mb3JtYXR0ZXJfb3V0cHV0X2Z1bmN0aW9ucyBzdGF0ZSBmIGc7XG4gIHN0YXRlLnBwX291dF9uZXdsaW5lIDwtIGg7XG4gIHN0YXRlLnBwX291dF9zcGFjZXMgPC0gaVxuXG4oKiBEZXByZWNhdGVkIDogc3Vic3VtZWQgYnkgcHBfZ2V0X2Zvcm1hdHRlcl9vdXRfZnVuY3Rpb25zICopXG5sZXQgcHBfZ2V0X2FsbF9mb3JtYXR0ZXJfb3V0cHV0X2Z1bmN0aW9ucyBzdGF0ZSAoKSA9XG4gIChzdGF0ZS5wcF9vdXRfc3RyaW5nLCBzdGF0ZS5wcF9vdXRfZmx1c2gsXG4gICBzdGF0ZS5wcF9vdXRfbmV3bGluZSwgc3RhdGUucHBfb3V0X3NwYWNlcylcblxuXG4oKiBEZXByZWNhdGVkIDogc3Vic3VtZWQgYnkgc2V0X2Zvcm1hdHRlcl9vdXRfZnVuY3Rpb25zICopXG5sZXQgc2V0X2FsbF9mb3JtYXR0ZXJfb3V0cHV0X2Z1bmN0aW9ucyA9XG4gIHBwX3NldF9hbGxfZm9ybWF0dGVyX291dHB1dF9mdW5jdGlvbnMgc3RkX2Zvcm1hdHRlclxuXG5cbigqIERlcHJlY2F0ZWQgOiBzdWJzdW1lZCBieSBnZXRfZm9ybWF0dGVyX291dF9mdW5jdGlvbnMgKilcbmxldCBnZXRfYWxsX2Zvcm1hdHRlcl9vdXRwdXRfZnVuY3Rpb25zID1cbiAgcHBfZ2V0X2FsbF9mb3JtYXR0ZXJfb3V0cHV0X2Z1bmN0aW9ucyBzdGRfZm9ybWF0dGVyXG5cblxuKCogRGVwcmVjYXRlZCA6IGVycm9yIHByb25lIGZ1bmN0aW9uLCBkbyBub3QgdXNlIGl0LlxuICAgVGhpcyBmdW5jdGlvbiBpcyBuZWl0aGVyIGNvbXBvc2l0aW9uYWwgbm9yIGluY3JlbWVudGFsLCBzaW5jZSBpdCBmbHVzaGVzXG4gICB0aGUgcHJldHR5LXByaW50ZXIgcXVldWUgYXQgZWFjaCBjYWxsLlxuICAgVG8gZ2V0IHRoZSBzYW1lIGZ1bmN0aW9uYWxpdHksIGRlZmluZSBhIGZvcm1hdHRlciBvZiB5b3VyIG93biB3cml0aW5nIHRvXG4gICB0aGUgYnVmZmVyIGFyZ3VtZW50LCBhcyBpblxuICAgbGV0IHBwZiA9IGZvcm1hdHRlcl9vZl9idWZmZXIgYlxuICAgdGhlbiB1c2UgeyFmcHJpbnRmIHBwZn0gYXMgdXN1YWwuICopXG5sZXQgYnByaW50ZiBiIChGb3JtYXQgKGZtdCwgXykgOiAoJ2EsIGZvcm1hdHRlciwgdW5pdCkgZm9ybWF0KSA9XG4gIGxldCBwcGYgPSBmb3JtYXR0ZXJfb2ZfYnVmZmVyIGIgaW5cbiAgbGV0IGsgYWNjID0gb3V0cHV0X2FjYyBwcGYgYWNjOyBwcF9mbHVzaF9xdWV1ZSBwcGYgZmFsc2UgaW5cbiAgbWFrZV9wcmludGYgayBFbmRfb2ZfYWNjIGZtdFxuXG5cbigqIERlcHJlY2F0ZWQgOiBhbGlhcyBmb3Iga3NwcmludGYuICopXG5sZXQga3ByaW50ZiA9IGtzcHJpbnRmXG5cblxuXG4oKiBEZXByZWNhdGVkIHRhZyBmdW5jdGlvbnMgKilcblxudHlwZSBmb3JtYXR0ZXJfdGFnX2Z1bmN0aW9ucyA9IHtcbiAgbWFya19vcGVuX3RhZyA6IHRhZyAtPiBzdHJpbmc7XG4gIG1hcmtfY2xvc2VfdGFnIDogdGFnIC0+IHN0cmluZztcbiAgcHJpbnRfb3Blbl90YWcgOiB0YWcgLT4gdW5pdDtcbiAgcHJpbnRfY2xvc2VfdGFnIDogdGFnIC0+IHVuaXQ7XG59XG5cblxubGV0IHBwX3NldF9mb3JtYXR0ZXJfdGFnX2Z1bmN0aW9ucyBzdGF0ZSB7XG4gICAgIG1hcmtfb3Blbl90YWcgPSBtb3Q7XG4gICAgIG1hcmtfY2xvc2VfdGFnID0gbWN0O1xuICAgICBwcmludF9vcGVuX3RhZyA9IHBvdDtcbiAgICAgcHJpbnRfY2xvc2VfdGFnID0gcGN0O1xuICAgfSA9XG4gIGxldCBzdHJpbmdpZnkgZiBlID0gZnVuY3Rpb24gU3RyaW5nX3RhZyBzIC0+IGYgcyB8IF8gLT4gZSBpblxuICBzdGF0ZS5wcF9tYXJrX29wZW5fdGFnIDwtIHN0cmluZ2lmeSBtb3QgXCJcIjtcbiAgc3RhdGUucHBfbWFya19jbG9zZV90YWcgPC0gc3RyaW5naWZ5IG1jdCBcIlwiO1xuICBzdGF0ZS5wcF9wcmludF9vcGVuX3RhZyA8LSBzdHJpbmdpZnkgcG90ICgpO1xuICBzdGF0ZS5wcF9wcmludF9jbG9zZV90YWcgPC0gc3RyaW5naWZ5IHBjdCAoKVxuXG5sZXQgcHBfZ2V0X2Zvcm1hdHRlcl90YWdfZnVuY3Rpb25zIGZtdCAoKSA9XG4gIGxldCBmdW5zID0gcHBfZ2V0X2Zvcm1hdHRlcl9zdGFnX2Z1bmN0aW9ucyBmbXQgKCkgaW5cbiAgbGV0IG1hcmtfb3Blbl90YWcgcyA9IGZ1bnMubWFya19vcGVuX3N0YWcgKFN0cmluZ190YWcgcykgaW5cbiAgbGV0IG1hcmtfY2xvc2VfdGFnIHMgPSBmdW5zLm1hcmtfY2xvc2Vfc3RhZyAoU3RyaW5nX3RhZyBzKSBpblxuICBsZXQgcHJpbnRfb3Blbl90YWcgcyA9IGZ1bnMucHJpbnRfb3Blbl9zdGFnIChTdHJpbmdfdGFnIHMpIGluXG4gIGxldCBwcmludF9jbG9zZV90YWcgcyA9IGZ1bnMucHJpbnRfY2xvc2Vfc3RhZyAoU3RyaW5nX3RhZyBzKSBpblxuICB7bWFya19vcGVuX3RhZzsgbWFya19jbG9zZV90YWc7IHByaW50X29wZW5fdGFnOyBwcmludF9jbG9zZV90YWd9XG5cbmxldCBzZXRfZm9ybWF0dGVyX3RhZ19mdW5jdGlvbnMgPVxuICBwcF9zZXRfZm9ybWF0dGVyX3RhZ19mdW5jdGlvbnMgc3RkX2Zvcm1hdHRlclxuYW5kIGdldF9mb3JtYXR0ZXJfdGFnX2Z1bmN0aW9ucyA9XG4gIHBwX2dldF9mb3JtYXR0ZXJfdGFnX2Z1bmN0aW9ucyBzdGRfZm9ybWF0dGVyXG4iLCIoKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9DYW1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICBQaWVycmUgV2VpcywgcHJvamV0IENyaXN0YWwsIElOUklBIFJvY3F1ZW5jb3VydCAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIENvcHlyaWdodCAyMDAyIEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgICAgICopXG4oKiAgICAgZW4gQXV0b21hdGlxdWUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgIEFsbCByaWdodHMgcmVzZXJ2ZWQuICBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mICAgICopXG4oKiAgIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyLjEsIHdpdGggdGhlICAgICAgICAgICopXG4oKiAgIHNwZWNpYWwgZXhjZXB0aW9uIG9uIGxpbmtpbmcgZGVzY3JpYmVkIGluIHRoZSBmaWxlIExJQ0VOU0UuICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG5cbm9wZW4gQ2FtbGludGVybmFsRm9ybWF0QmFzaWNzXG5vcGVuIENhbWxpbnRlcm5hbEZvcm1hdFxuXG4oKiBhbGlhcyB0byBhdm9pZCB3YXJuaW5nIGZvciBhbWJpZ3VpdHkgYmV0d2VlblxuICAgU3RkbGliLmZvcm1hdDZcbiAgIGFuZCBDYW1saW50ZXJuYWxGb3JtYXRCYXNpY3MuZm9ybWF0NlxuXG4gICAodGhlIGZvcm1lciBpcyBpbiBmYWN0IGFuIGFsaWFzIGZvciB0aGUgbGF0dGVyLFxuICAgIGJ1dCB0aGUgYW1iaWd1aXR5IHdhcm5pbmcgZG9lc24ndCBjYXJlKVxuKilcbnR5cGUgKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZvcm1hdDYgPVxuICAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgU3RkbGliLmZvcm1hdDZcblxuXG4oKiBUaGUgcnVuLXRpbWUgbGlicmFyeSBmb3Igc2Nhbm5lcnMuICopXG5cbigqIFNjYW5uaW5nIGJ1ZmZlcnMuICopXG5tb2R1bGUgdHlwZSBTQ0FOTklORyA9IHNpZ1xuXG4gIHR5cGUgaW5fY2hhbm5lbFxuXG4gIHR5cGUgc2NhbmJ1ZiA9IGluX2NoYW5uZWxcblxuICB0eXBlIGZpbGVfbmFtZSA9IHN0cmluZ1xuXG4gIHZhbCBzdGRpbiA6IGluX2NoYW5uZWxcbiAgKCogVGhlIHNjYW5uaW5nIGJ1ZmZlciByZWFkaW5nIGZyb20gW1N0ZGxpYi5zdGRpbl0uXG4gICAgIFtzdGRpYl0gaXMgZXF1aXZhbGVudCB0byBbU2Nhbm5pbmcuZnJvbV9jaGFubmVsIFN0ZGxpYi5zdGRpbl0uICopXG5cbiAgdmFsIHN0ZGliIDogaW5fY2hhbm5lbFxuICAoKiBBbiBhbGlhcyBmb3IgW1NjYW5mLnN0ZGluXSwgdGhlIHNjYW5uaW5nIGJ1ZmZlciByZWFkaW5nIGZyb21cbiAgICAgW1N0ZGxpYi5zdGRpbl0uICopXG5cbiAgdmFsIG5leHRfY2hhciA6IHNjYW5idWYgLT4gY2hhclxuICAoKiBbU2Nhbm5pbmcubmV4dF9jaGFyIGliXSBhZHZhbmNlIHRoZSBzY2FubmluZyBidWZmZXIgZm9yXG4gICAgIG9uZSBjaGFyYWN0ZXIuXG4gICAgIElmIG5vIG1vcmUgY2hhcmFjdGVyIGNhbiBiZSByZWFkLCBzZXRzIGEgZW5kIG9mIGZpbGUgY29uZGl0aW9uIGFuZFxuICAgICByZXR1cm5zICdcXDAwMCcuICopXG5cbiAgdmFsIGludmFsaWRhdGVfY3VycmVudF9jaGFyIDogc2NhbmJ1ZiAtPiB1bml0XG4gICgqIFtTY2FubmluZy5pbnZhbGlkYXRlX2N1cnJlbnRfY2hhciBpYl0gbWFyayB0aGUgY3VycmVudF9jaGFyIGFzIGFscmVhZHlcbiAgICAgc2Nhbm5lZC4gKilcblxuICB2YWwgcGVla19jaGFyIDogc2NhbmJ1ZiAtPiBjaGFyXG4gICgqIFtTY2FubmluZy5wZWVrX2NoYXIgaWJdIHJldHVybnMgdGhlIGN1cnJlbnQgY2hhciBhdmFpbGFibGUgaW5cbiAgICAgdGhlIGJ1ZmZlciBvciByZWFkcyBvbmUgaWYgbmVjZXNzYXJ5ICh3aGVuIHRoZSBjdXJyZW50IGNoYXJhY3RlciBpc1xuICAgICBhbHJlYWR5IHNjYW5uZWQpLlxuICAgICBJZiBubyBjaGFyYWN0ZXIgY2FuIGJlIHJlYWQsIHNldHMgYW4gZW5kIG9mIGZpbGUgY29uZGl0aW9uIGFuZFxuICAgICByZXR1cm5zICdcXDAwMCcuICopXG5cbiAgdmFsIGNoZWNrZWRfcGVla19jaGFyIDogc2NhbmJ1ZiAtPiBjaGFyXG4gICgqIFNhbWUgYXMgW1NjYW5uaW5nLnBlZWtfY2hhcl0gYWJvdmUgYnV0IGFsd2F5cyByZXR1cm5zIGEgdmFsaWQgY2hhciBvclxuICAgICBmYWlsczogaW5zdGVhZCBvZiByZXR1cm5pbmcgYSBudWxsIGNoYXIgd2hlbiB0aGUgcmVhZGluZyBtZXRob2Qgb2YgdGhlXG4gICAgIGlucHV0IGJ1ZmZlciBoYXMgcmVhY2hlZCBhbiBlbmQgb2YgZmlsZSwgdGhlIGZ1bmN0aW9uIHJhaXNlcyBleGNlcHRpb25cbiAgICAgW0VuZF9vZl9maWxlXS4gKilcblxuICB2YWwgc3RvcmVfY2hhciA6IGludCAtPiBzY2FuYnVmIC0+IGNoYXIgLT4gaW50XG4gICgqIFtTY2FubmluZy5zdG9yZV9jaGFyIGxpbSBpYiBjXSBhZGRzIFtjXSB0byB0aGUgdG9rZW4gYnVmZmVyXG4gICAgIG9mIHRoZSBzY2FubmluZyBidWZmZXIgW2liXS4gSXQgYWxzbyBhZHZhbmNlcyB0aGUgc2Nhbm5pbmcgYnVmZmVyIGZvclxuICAgICBvbmUgY2hhcmFjdGVyIGFuZCByZXR1cm5zIFtsaW0gLSAxXSwgaW5kaWNhdGluZyB0aGUgbmV3IGxpbWl0IGZvciB0aGVcbiAgICAgbGVuZ3RoIG9mIHRoZSBjdXJyZW50IHRva2VuLiAqKVxuXG4gIHZhbCBza2lwX2NoYXIgOiBpbnQgLT4gc2NhbmJ1ZiAtPiBpbnRcbiAgKCogW1NjYW5uaW5nLnNraXBfY2hhciBsaW0gaWJdIGlnbm9yZXMgdGhlIGN1cnJlbnQgY2hhcmFjdGVyLiAqKVxuXG4gIHZhbCBpZ25vcmVfY2hhciA6IGludCAtPiBzY2FuYnVmIC0+IGludFxuICAoKiBbU2Nhbm5pbmcuaWdub3JlX2NoYXIgaWIgbGltXSBpZ25vcmVzIHRoZSBjdXJyZW50IGNoYXJhY3RlciBhbmRcbiAgICAgZGVjcmVtZW50cyB0aGUgbGltaXQuICopXG5cbiAgdmFsIHRva2VuIDogc2NhbmJ1ZiAtPiBzdHJpbmdcbiAgKCogW1NjYW5uaW5nLnRva2VuIGliXSByZXR1cm5zIHRoZSBzdHJpbmcgc3RvcmVkIGludG8gdGhlIHRva2VuXG4gICAgIGJ1ZmZlciBvZiB0aGUgc2Nhbm5pbmcgYnVmZmVyOiBpdCByZXR1cm5zIHRoZSB0b2tlbiBtYXRjaGVkIGJ5IHRoZVxuICAgICBmb3JtYXQuICopXG5cbiAgdmFsIHJlc2V0X3Rva2VuIDogc2NhbmJ1ZiAtPiB1bml0XG4gICgqIFtTY2FubmluZy5yZXNldF90b2tlbiBpYl0gcmVzZXRzIHRoZSB0b2tlbiBidWZmZXIgb2ZcbiAgICAgdGhlIGdpdmVuIHNjYW5uaW5nIGJ1ZmZlci4gKilcblxuICB2YWwgY2hhcl9jb3VudCA6IHNjYW5idWYgLT4gaW50XG4gICgqIFtTY2FubmluZy5jaGFyX2NvdW50IGliXSByZXR1cm5zIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVyc1xuICAgICByZWFkIHNvIGZhciBmcm9tIHRoZSBnaXZlbiBidWZmZXIuICopXG5cbiAgdmFsIGxpbmVfY291bnQgOiBzY2FuYnVmIC0+IGludFxuICAoKiBbU2Nhbm5pbmcubGluZV9jb3VudCBpYl0gcmV0dXJucyB0aGUgbnVtYmVyIG9mIG5ldyBsaW5lXG4gICAgIGNoYXJhY3RlcnMgcmVhZCBzbyBmYXIgZnJvbSB0aGUgZ2l2ZW4gYnVmZmVyLiAqKVxuXG4gIHZhbCB0b2tlbl9jb3VudCA6IHNjYW5idWYgLT4gaW50XG4gICgqIFtTY2FubmluZy50b2tlbl9jb3VudCBpYl0gcmV0dXJucyB0aGUgbnVtYmVyIG9mIHRva2VucyByZWFkXG4gICAgIHNvIGZhciBmcm9tIFtpYl0uICopXG5cbiAgdmFsIGVvZiA6IHNjYW5idWYgLT4gYm9vbFxuICAoKiBbU2Nhbm5pbmcuZW9mIGliXSByZXR1cm5zIHRoZSBlbmQgb2YgaW5wdXQgY29uZGl0aW9uXG4gICAgIG9mIHRoZSBnaXZlbiBidWZmZXIuICopXG5cbiAgdmFsIGVuZF9vZl9pbnB1dCA6IHNjYW5idWYgLT4gYm9vbFxuICAoKiBbU2Nhbm5pbmcuZW5kX29mX2lucHV0IGliXSB0ZXN0cyB0aGUgZW5kIG9mIGlucHV0IGNvbmRpdGlvblxuICAgICBvZiB0aGUgZ2l2ZW4gYnVmZmVyIChpZiBubyBjaGFyIGhhcyBldmVyIGJlZW4gcmVhZCwgYW4gYXR0ZW1wdCB0b1xuICAgICByZWFkIG9uZSBpcyBwZXJmb3JtZWQpLiAqKVxuXG4gIHZhbCBiZWdpbm5pbmdfb2ZfaW5wdXQgOiBzY2FuYnVmIC0+IGJvb2xcbiAgKCogW1NjYW5uaW5nLmJlZ2lubmluZ19vZl9pbnB1dCBpYl0gdGVzdHMgdGhlIGJlZ2lubmluZyBvZiBpbnB1dFxuICAgICBjb25kaXRpb24gb2YgdGhlIGdpdmVuIGJ1ZmZlci4gKilcblxuICB2YWwgbmFtZV9vZl9pbnB1dCA6IHNjYW5idWYgLT4gc3RyaW5nXG4gICgqIFtTY2FubmluZy5uYW1lX29mX2lucHV0IGliXSByZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBjaGFyYWN0ZXJcbiAgICAgc291cmNlIGZvciBpbnB1dCBidWZmZXIgW2liXS4gKilcblxuICB2YWwgb3Blbl9pbiA6IGZpbGVfbmFtZSAtPiBpbl9jaGFubmVsXG4gIHZhbCBvcGVuX2luX2JpbiA6IGZpbGVfbmFtZSAtPiBpbl9jaGFubmVsXG4gIHZhbCBmcm9tX2ZpbGUgOiBmaWxlX25hbWUgLT4gaW5fY2hhbm5lbFxuICB2YWwgZnJvbV9maWxlX2JpbiA6IGZpbGVfbmFtZSAtPiBpbl9jaGFubmVsXG4gIHZhbCBmcm9tX3N0cmluZyA6IHN0cmluZyAtPiBpbl9jaGFubmVsXG4gIHZhbCBmcm9tX2Z1bmN0aW9uIDogKHVuaXQgLT4gY2hhcikgLT4gaW5fY2hhbm5lbFxuICB2YWwgZnJvbV9jaGFubmVsIDogU3RkbGliLmluX2NoYW5uZWwgLT4gaW5fY2hhbm5lbFxuXG4gIHZhbCBjbG9zZV9pbiA6IGluX2NoYW5uZWwgLT4gdW5pdFxuXG4gIHZhbCBtZW1vX2Zyb21fY2hhbm5lbCA6IFN0ZGxpYi5pbl9jaGFubmVsIC0+IGluX2NoYW5uZWxcbiAgKCogT2Jzb2xldGUuICopXG5cbmVuZFxuXG5cbm1vZHVsZSBTY2FubmluZyA6IFNDQU5OSU5HID0gc3RydWN0XG5cbiAgKCogVGhlIHJ1bi10aW1lIGxpYnJhcnkgZm9yIHNjYW5mLiAqKVxuXG4gIHR5cGUgZmlsZV9uYW1lID0gc3RyaW5nXG5cbiAgdHlwZSBpbl9jaGFubmVsX25hbWUgPVxuICAgIHwgRnJvbV9jaGFubmVsIG9mIFN0ZGxpYi5pbl9jaGFubmVsXG4gICAgfCBGcm9tX2ZpbGUgb2YgZmlsZV9uYW1lICogU3RkbGliLmluX2NoYW5uZWxcbiAgICB8IEZyb21fZnVuY3Rpb25cbiAgICB8IEZyb21fc3RyaW5nXG5cblxuICB0eXBlIGluX2NoYW5uZWwgPSB7XG4gICAgbXV0YWJsZSBpY19lb2YgOiBib29sO1xuICAgIG11dGFibGUgaWNfY3VycmVudF9jaGFyIDogY2hhcjtcbiAgICBtdXRhYmxlIGljX2N1cnJlbnRfY2hhcl9pc192YWxpZCA6IGJvb2w7XG4gICAgbXV0YWJsZSBpY19jaGFyX2NvdW50IDogaW50O1xuICAgIG11dGFibGUgaWNfbGluZV9jb3VudCA6IGludDtcbiAgICBtdXRhYmxlIGljX3Rva2VuX2NvdW50IDogaW50O1xuICAgIGljX2dldF9uZXh0X2NoYXIgOiB1bml0IC0+IGNoYXI7XG4gICAgaWNfdG9rZW5fYnVmZmVyIDogQnVmZmVyLnQ7XG4gICAgaWNfaW5wdXRfbmFtZSA6IGluX2NoYW5uZWxfbmFtZTtcbiAgfVxuXG5cbiAgdHlwZSBzY2FuYnVmID0gaW5fY2hhbm5lbFxuXG4gIGxldCBudWxsX2NoYXIgPSAnXFwwMDAnXG5cbiAgKCogUmVhZHMgYSBuZXcgY2hhcmFjdGVyIGZyb20gaW5wdXQgYnVmZmVyLlxuICAgICBOZXh0X2NoYXIgbmV2ZXIgZmFpbHMsIGV2ZW4gaW4gY2FzZSBvZiBlbmQgb2YgaW5wdXQ6XG4gICAgIGl0IHRoZW4gc2ltcGx5IHNldHMgdGhlIGVuZCBvZiBmaWxlIGNvbmRpdGlvbi4gKilcbiAgbGV0IG5leHRfY2hhciBpYiA9XG4gICAgdHJ5XG4gICAgICBsZXQgYyA9IGliLmljX2dldF9uZXh0X2NoYXIgKCkgaW5cbiAgICAgIGliLmljX2N1cnJlbnRfY2hhciA8LSBjO1xuICAgICAgaWIuaWNfY3VycmVudF9jaGFyX2lzX3ZhbGlkIDwtIHRydWU7XG4gICAgICBpYi5pY19jaGFyX2NvdW50IDwtIHN1Y2MgaWIuaWNfY2hhcl9jb3VudDtcbiAgICAgIGlmIGMgPSAnXFxuJyB0aGVuIGliLmljX2xpbmVfY291bnQgPC0gc3VjYyBpYi5pY19saW5lX2NvdW50O1xuICAgICAgYyB3aXRoXG4gICAgfCBFbmRfb2ZfZmlsZSAtPlxuICAgICAgbGV0IGMgPSBudWxsX2NoYXIgaW5cbiAgICAgIGliLmljX2N1cnJlbnRfY2hhciA8LSBjO1xuICAgICAgaWIuaWNfY3VycmVudF9jaGFyX2lzX3ZhbGlkIDwtIGZhbHNlO1xuICAgICAgaWIuaWNfZW9mIDwtIHRydWU7XG4gICAgICBjXG5cblxuICBsZXQgcGVla19jaGFyIGliID1cbiAgICBpZiBpYi5pY19jdXJyZW50X2NoYXJfaXNfdmFsaWRcbiAgICB0aGVuIGliLmljX2N1cnJlbnRfY2hhclxuICAgIGVsc2UgbmV4dF9jaGFyIGliXG5cblxuICAoKiBSZXR1cm5zIGEgdmFsaWQgY3VycmVudCBjaGFyIGZvciB0aGUgaW5wdXQgYnVmZmVyLiBJbiBwYXJ0aWN1bGFyXG4gICAgIG5vIGlycmVsZXZhbnQgbnVsbCBjaGFyYWN0ZXIgKGFzIHNldCBieSBbbmV4dF9jaGFyXSBpbiBjYXNlIG9mIGVuZFxuICAgICBvZiBpbnB1dCkgaXMgcmV0dXJuZWQsIHNpbmNlIFtFbmRfb2ZfZmlsZV0gaXMgcmFpc2VkIHdoZW5cbiAgICAgW25leHRfY2hhcl0gc2V0cyB0aGUgZW5kIG9mIGZpbGUgY29uZGl0aW9uIHdoaWxlIHRyeWluZyB0byByZWFkIGFcbiAgICAgbmV3IGNoYXJhY3Rlci4gKilcbiAgbGV0IGNoZWNrZWRfcGVla19jaGFyIGliID1cbiAgICBsZXQgYyA9IHBlZWtfY2hhciBpYiBpblxuICAgIGlmIGliLmljX2VvZiB0aGVuIHJhaXNlIEVuZF9vZl9maWxlO1xuICAgIGNcblxuXG4gIGxldCBlbmRfb2ZfaW5wdXQgaWIgPVxuICAgIGlnbm9yZSAocGVla19jaGFyIGliKTtcbiAgICBpYi5pY19lb2ZcblxuXG4gIGxldCBlb2YgaWIgPSBpYi5pY19lb2ZcblxuICBsZXQgYmVnaW5uaW5nX29mX2lucHV0IGliID0gaWIuaWNfY2hhcl9jb3VudCA9IDBcblxuICBsZXQgbmFtZV9vZl9pbnB1dCBpYiA9XG4gICAgbWF0Y2ggaWIuaWNfaW5wdXRfbmFtZSB3aXRoXG4gICAgfCBGcm9tX2NoYW5uZWwgX2ljIC0+IFwidW5uYW1lZCBTdGRsaWIgaW5wdXQgY2hhbm5lbFwiXG4gICAgfCBGcm9tX2ZpbGUgKGZuYW1lLCBfaWMpIC0+IGZuYW1lXG4gICAgfCBGcm9tX2Z1bmN0aW9uIC0+IFwidW5uYW1lZCBmdW5jdGlvblwiXG4gICAgfCBGcm9tX3N0cmluZyAtPiBcInVubmFtZWQgY2hhcmFjdGVyIHN0cmluZ1wiXG5cblxuICBsZXQgY2hhcl9jb3VudCBpYiA9XG4gICAgaWYgaWIuaWNfY3VycmVudF9jaGFyX2lzX3ZhbGlkXG4gICAgdGhlbiBpYi5pY19jaGFyX2NvdW50IC0gMVxuICAgIGVsc2UgaWIuaWNfY2hhcl9jb3VudFxuXG5cbiAgbGV0IGxpbmVfY291bnQgaWIgPSBpYi5pY19saW5lX2NvdW50XG5cbiAgbGV0IHJlc2V0X3Rva2VuIGliID0gQnVmZmVyLnJlc2V0IGliLmljX3Rva2VuX2J1ZmZlclxuXG4gIGxldCBpbnZhbGlkYXRlX2N1cnJlbnRfY2hhciBpYiA9IGliLmljX2N1cnJlbnRfY2hhcl9pc192YWxpZCA8LSBmYWxzZVxuXG4gIGxldCB0b2tlbiBpYiA9XG4gICAgbGV0IHRva2VuX2J1ZmZlciA9IGliLmljX3Rva2VuX2J1ZmZlciBpblxuICAgIGxldCB0b2sgPSBCdWZmZXIuY29udGVudHMgdG9rZW5fYnVmZmVyIGluXG4gICAgQnVmZmVyLmNsZWFyIHRva2VuX2J1ZmZlcjtcbiAgICBpYi5pY190b2tlbl9jb3VudCA8LSBzdWNjIGliLmljX3Rva2VuX2NvdW50O1xuICAgIHRva1xuXG5cbiAgbGV0IHRva2VuX2NvdW50IGliID0gaWIuaWNfdG9rZW5fY291bnRcblxuICBsZXQgc2tpcF9jaGFyIHdpZHRoIGliID1cbiAgICBpbnZhbGlkYXRlX2N1cnJlbnRfY2hhciBpYjtcbiAgICB3aWR0aFxuXG5cbiAgbGV0IGlnbm9yZV9jaGFyIHdpZHRoIGliID0gc2tpcF9jaGFyICh3aWR0aCAtIDEpIGliXG5cbiAgbGV0IHN0b3JlX2NoYXIgd2lkdGggaWIgYyA9XG4gICAgQnVmZmVyLmFkZF9jaGFyIGliLmljX3Rva2VuX2J1ZmZlciBjO1xuICAgIGlnbm9yZV9jaGFyIHdpZHRoIGliXG5cblxuICBsZXQgZGVmYXVsdF90b2tlbl9idWZmZXJfc2l6ZSA9IDEwMjRcblxuICBsZXQgY3JlYXRlIGluYW1lIG5leHQgPSB7XG4gICAgaWNfZW9mID0gZmFsc2U7XG4gICAgaWNfY3VycmVudF9jaGFyID0gbnVsbF9jaGFyO1xuICAgIGljX2N1cnJlbnRfY2hhcl9pc192YWxpZCA9IGZhbHNlO1xuICAgIGljX2NoYXJfY291bnQgPSAwO1xuICAgIGljX2xpbmVfY291bnQgPSAwO1xuICAgIGljX3Rva2VuX2NvdW50ID0gMDtcbiAgICBpY19nZXRfbmV4dF9jaGFyID0gbmV4dDtcbiAgICBpY190b2tlbl9idWZmZXIgPSBCdWZmZXIuY3JlYXRlIGRlZmF1bHRfdG9rZW5fYnVmZmVyX3NpemU7XG4gICAgaWNfaW5wdXRfbmFtZSA9IGluYW1lO1xuICB9XG5cblxuICBsZXQgZnJvbV9zdHJpbmcgcyA9XG4gICAgbGV0IGkgPSByZWYgMCBpblxuICAgIGxldCBsZW4gPSBTdHJpbmcubGVuZ3RoIHMgaW5cbiAgICBsZXQgbmV4dCAoKSA9XG4gICAgICBpZiAhaSA+PSBsZW4gdGhlbiByYWlzZSBFbmRfb2ZfZmlsZSBlbHNlXG4gICAgICBsZXQgYyA9IHMuWyFpXSBpblxuICAgICAgaW5jciBpO1xuICAgICAgYyBpblxuICAgIGNyZWF0ZSBGcm9tX3N0cmluZyBuZXh0XG5cblxuICBsZXQgZnJvbV9mdW5jdGlvbiA9IGNyZWF0ZSBGcm9tX2Z1bmN0aW9uXG5cbiAgKCogU2Nhbm5pbmcgZnJvbSBhbiBpbnB1dCBjaGFubmVsLiAqKVxuXG4gICgqIFBvc2l0aW9uIG9mIHRoZSBwcm9ibGVtOlxuXG4gICAgIFdlIGNhbm5vdCBwcmV2ZW50IHRoZSBzY2FubmluZyBtZWNoYW5pc20gdG8gdXNlIG9uZSBsb29rYWhlYWQgY2hhcmFjdGVyLFxuICAgICBpZiBuZWVkZWQgYnkgdGhlIHNlbWFudGljcyBvZiB0aGUgZm9ybWF0IHN0cmluZyBzcGVjaWZpY2F0aW9ucyAoZS5nLiBhXG4gICAgIHRyYWlsaW5nICdza2lwIHNwYWNlJyBzcGVjaWZpY2F0aW9uIGluIHRoZSBmb3JtYXQgc3RyaW5nKTsgaW4gdGhpcyBjYXNlLFxuICAgICB0aGUgbWFuZGF0b3J5IGxvb2thaGVhZCBjaGFyYWN0ZXIgaXMgaW5kZWVkIHJlYWQgZnJvbSB0aGUgaW5wdXQgYW5kIG5vdFxuICAgICB1c2VkIHRvIHJldHVybiB0aGUgdG9rZW4gcmVhZC4gSXQgaXMgdGh1cyBtYW5kYXRvcnkgdG8gYmUgYWJsZSB0byBzdG9yZVxuICAgICBhbiB1bnVzZWQgbG9va2FoZWFkIGNoYXJhY3RlciBzb21ld2hlcmUgdG8gZ2V0IGl0IGFzIHRoZSBmaXJzdCBjaGFyYWN0ZXJcbiAgICAgb2YgdGhlIG5leHQgc2Nhbi5cblxuICAgICBUbyBjaXJjdW12ZW50IHRoaXMgcHJvYmxlbSwgYWxsIHRoZSBzY2FubmluZyBmdW5jdGlvbnMgZ2V0IGEgbG93IGxldmVsXG4gICAgIGlucHV0IGJ1ZmZlciBhcmd1bWVudCB3aGVyZSB0aGV5IHN0b3JlIHRoZSBsb29rYWhlYWQgY2hhcmFjdGVyIHdoZW5cbiAgICAgbmVlZGVkOyBhZGRpdGlvbmFsbHksIHRoZSBpbnB1dCBidWZmZXIgaXMgdGhlIG9ubHkgc291cmNlIG9mIGNoYXJhY3RlciBvZlxuICAgICBhIHNjYW5uZXIuIFRoZSBbc2NhbmJ1Zl0gaW5wdXQgYnVmZmVycyBhcmUgZGVmaW5lZCBpbiBtb2R1bGUgeyFTY2FubmluZ30uXG5cbiAgICAgTm93IHdlIHVuZGVyc3RhbmQgdGhhdCBpdCBpcyBleHRyZW1lbHkgaW1wb3J0YW50IHRoYXQgcmVsYXRlZCBhbmRcbiAgICAgc3VjY2Vzc2l2ZSBjYWxscyB0byBzY2FubmVycyBpbmRlZWQgcmVhZCBmcm9tIHRoZSBzYW1lIGlucHV0IGJ1ZmZlci5cbiAgICAgSW4gZWZmZWN0LCBpZiBhIHNjYW5uZXIgW3NjYW4xXSBpcyByZWFkaW5nIGZyb20gW2liMV0gYW5kIHN0b3JlcyBhblxuICAgICB1bnVzZWQgbG9va2FoZWFkIGNoYXJhY3RlciBbYzFdIGludG8gaXRzIGlucHV0IGJ1ZmZlciBbaWIxXSwgdGhlblxuICAgICBhbm90aGVyIHNjYW5uZXIgW3NjYW4yXSBub3QgcmVhZGluZyBmcm9tIHRoZSBzYW1lIGJ1ZmZlciBbaWIxXSB3aWxsIG1pc3NcbiAgICAgdGhlIGNoYXJhY3RlciBbYzFdLCBzZWVtaW5nbHkgdmFuaXNoZWQgaW4gdGhlIGFpciBmcm9tIHRoZSBwb2ludCBvZiB2aWV3XG4gICAgIG9mIFtzY2FuMl0uXG5cbiAgICAgVGhpcyBtZWNoYW5pc20gd29ya3MgcGVyZmVjdGx5IHRvIHJlYWQgZnJvbSBzdHJpbmdzLCBmcm9tIGZpbGVzLCBhbmQgZnJvbVxuICAgICBmdW5jdGlvbnMsIHNpbmNlIGluIHRob3NlIGNhc2VzLCBhbGxvY2F0aW5nIHR3byBidWZmZXJzIHJlYWRpbmcgZnJvbSB0aGVcbiAgICAgc2FtZSBzb3VyY2UgaXMgdW5uYXR1cmFsLlxuXG4gICAgIFN0aWxsLCB0aGVyZSBpcyBhIGRpZmZpY3VsdHkgaW4gdGhlIGNhc2Ugb2Ygc2Nhbm5pbmcgZnJvbSBhbiBpbnB1dFxuICAgICBjaGFubmVsLiBJbiBlZmZlY3QsIHdoZW4gc2Nhbm5pbmcgZnJvbSBhbiBpbnB1dCBjaGFubmVsIFtpY10sIHRoaXMgY2hhbm5lbFxuICAgICBtYXkgbm90IGhhdmUgYmVlbiBhbGxvY2F0ZWQgZnJvbSB3aXRoaW4gdGhpcyBsaWJyYXJ5LiBIZW5jZSwgaXQgbWF5IGJlXG4gICAgIHNoYXJlZCAodHdvIGZ1bmN0aW9ucyBvZiB0aGUgdXNlcidzIHByb2dyYW0gbWF5IHN1Y2Nlc3NpdmVseSByZWFkIGZyb21cbiAgICAgW2ljXSkuIFRoaXMgaXMgaGlnaGx5IGVycm9yIHByb25lIHNpbmNlLCBvbmUgb2YgdGhlIGZ1bmN0aW9uIG1heSBzZWVrIHRoZVxuICAgICBpbnB1dCBjaGFubmVsLCB3aGlsZSB0aGUgb3RoZXIgZnVuY3Rpb24gaGFzIHN0aWxsIGFuIHVudXNlZCBsb29rYWhlYWRcbiAgICAgY2hhcmFjdGVyIGluIGl0cyBpbnB1dCBidWZmZXIuIEluIGNvbmNsdXNpb24sIHlvdSBzaG91bGQgbmV2ZXIgbWl4IGRpcmVjdFxuICAgICBsb3cgbGV2ZWwgcmVhZGluZyBhbmQgaGlnaCBsZXZlbCBzY2FubmluZyBmcm9tIHRoZSBzYW1lIGlucHV0IGNoYW5uZWwuXG5cbiAgKilcblxuICAoKiBQZXJmb3JtIGJ1ZmZlcml6ZWQgaW5wdXQgdG8gaW1wcm92ZSBlZmZpY2llbmN5LiAqKVxuICBsZXQgZmlsZV9idWZmZXJfc2l6ZSA9IHJlZiAxMDI0XG5cbiAgKCogVGhlIHNjYW5uZXIgY2xvc2VzIHRoZSBpbnB1dCBjaGFubmVsIGF0IGVuZCBvZiBpbnB1dC4gKilcbiAgbGV0IHNjYW5fY2xvc2VfYXRfZW5kIGljID0gU3RkbGliLmNsb3NlX2luIGljOyByYWlzZSBFbmRfb2ZfZmlsZVxuXG4gICgqIFRoZSBzY2FubmVyIGRvZXMgbm90IGNsb3NlIHRoZSBpbnB1dCBjaGFubmVsIGF0IGVuZCBvZiBpbnB1dDpcbiAgICAgaXQganVzdCByYWlzZXMgW0VuZF9vZl9maWxlXS4gKilcbiAgbGV0IHNjYW5fcmFpc2VfYXRfZW5kIF9pYyA9IHJhaXNlIEVuZF9vZl9maWxlXG5cbiAgbGV0IGZyb21faWMgc2Nhbl9jbG9zZV9pYyBpbmFtZSBpYyA9XG4gICAgbGV0IGxlbiA9ICFmaWxlX2J1ZmZlcl9zaXplIGluXG4gICAgbGV0IGJ1ZiA9IEJ5dGVzLmNyZWF0ZSBsZW4gaW5cbiAgICBsZXQgaSA9IHJlZiAwIGluXG4gICAgbGV0IGxpbSA9IHJlZiAwIGluXG4gICAgbGV0IGVvZiA9IHJlZiBmYWxzZSBpblxuICAgIGxldCBuZXh0ICgpID1cbiAgICAgIGlmICFpIDwgIWxpbSB0aGVuIGJlZ2luIGxldCBjID0gQnl0ZXMuZ2V0IGJ1ZiAhaSBpbiBpbmNyIGk7IGMgZW5kIGVsc2VcbiAgICAgIGlmICFlb2YgdGhlbiByYWlzZSBFbmRfb2ZfZmlsZSBlbHNlIGJlZ2luXG4gICAgICAgIGxpbSA6PSBpbnB1dCBpYyBidWYgMCBsZW47XG4gICAgICAgIGlmICFsaW0gPSAwIHRoZW4gYmVnaW4gZW9mIDo9IHRydWU7IHNjYW5fY2xvc2VfaWMgaWMgZW5kIGVsc2UgYmVnaW5cbiAgICAgICAgICBpIDo9IDE7XG4gICAgICAgICAgQnl0ZXMuZ2V0IGJ1ZiAwXG4gICAgICAgIGVuZFxuICAgICAgZW5kIGluXG4gICAgY3JlYXRlIGluYW1lIG5leHRcblxuXG4gIGxldCBmcm9tX2ljX2Nsb3NlX2F0X2VuZCA9IGZyb21faWMgc2Nhbl9jbG9zZV9hdF9lbmRcbiAgbGV0IGZyb21faWNfcmFpc2VfYXRfZW5kID0gZnJvbV9pYyBzY2FuX3JhaXNlX2F0X2VuZFxuXG4gICgqIFRoZSBzY2FubmluZyBidWZmZXIgcmVhZGluZyBmcm9tIFtTdGRsaWIuc3RkaW5dLlxuICAgICBPbmUgY291bGQgdHJ5IHRvIGRlZmluZSBbc3RkaWJdIGFzIGEgc2Nhbm5pbmcgYnVmZmVyIHJlYWRpbmcgYSBjaGFyYWN0ZXJcbiAgICAgYXQgYSB0aW1lIChubyBidWZmZXJpemF0aW9uIGF0IGFsbCksIGJ1dCB1bmZvcnR1bmF0ZWx5IHRoZSB0b3AtbGV2ZWxcbiAgICAgaW50ZXJhY3Rpb24gd291bGQgYmUgd3JvbmcuIFRoaXMgaXMgZHVlIHRvIHNvbWUga2luZCBvZlxuICAgICAncmFjZSBjb25kaXRpb24nIHdoZW4gcmVhZGluZyBmcm9tIFtTdGRsaWIuc3RkaW5dLFxuICAgICBzaW5jZSB0aGUgaW50ZXJhY3RpdmUgY29tcGlsZXIgYW5kIFtTY2FuZi5zY2FuZl0gd2lsbCBzaW11bHRhbmVvdXNseVxuICAgICByZWFkIHRoZSBtYXRlcmlhbCB0aGV5IG5lZWQgZnJvbSBbU3RkbGliLnN0ZGluXTsgdGhlbiwgY29uZnVzaW9uXG4gICAgIHdpbGwgcmVzdWx0IGZyb20gd2hhdCBzaG91bGQgYmUgcmVhZCBieSB0aGUgdG9wLWxldmVsIGFuZCB3aGF0IHNob3VsZCBiZVxuICAgICByZWFkIGJ5IFtTY2FuZi5zY2FuZl0uXG4gICAgIFRoaXMgaXMgZXZlbiBtb3JlIGNvbXBsaWNhdGVkIGJ5IHRoZSBvbmUgY2hhcmFjdGVyIGxvb2thaGVhZCB0aGF0XG4gICAgIFtTY2FuZi5zY2FuZl0gaXMgc29tZXRpbWVzIG9ibGlnZWQgdG8gbWFpbnRhaW46IHRoZSBsb29rYWhlYWQgY2hhcmFjdGVyXG4gICAgIHdpbGwgYmUgYXZhaWxhYmxlIGZvciB0aGUgbmV4dCBbU2NhbmYuc2NhbmZdIGVudHJ5LCBzZWVtaW5nbHkgY29taW5nIGZyb21cbiAgICAgbm93aGVyZS5cbiAgICAgQWxzbyBubyBbRW5kX29mX2ZpbGVdIGlzIHJhaXNlZCB3aGVuIHJlYWRpbmcgZnJvbSBzdGRpbjogaWYgbm90IGVub3VnaFxuICAgICBjaGFyYWN0ZXJzIGhhdmUgYmVlbiByZWFkLCB3ZSBzaW1wbHkgYXNrIHRvIHJlYWQgbW9yZS4gKilcbiAgbGV0IHN0ZGluID1cbiAgICBmcm9tX2ljIHNjYW5fcmFpc2VfYXRfZW5kXG4gICAgICAoRnJvbV9maWxlIChcIi1cIiwgU3RkbGliLnN0ZGluKSkgU3RkbGliLnN0ZGluXG5cblxuICBsZXQgc3RkaWIgPSBzdGRpblxuXG4gIGxldCBvcGVuX2luX2ZpbGUgb3Blbl9pbiBmbmFtZSA9XG4gICAgbWF0Y2ggZm5hbWUgd2l0aFxuICAgIHwgXCItXCIgLT4gc3RkaW5cbiAgICB8IGZuYW1lIC0+XG4gICAgICBsZXQgaWMgPSBvcGVuX2luIGZuYW1lIGluXG4gICAgICBmcm9tX2ljX2Nsb3NlX2F0X2VuZCAoRnJvbV9maWxlIChmbmFtZSwgaWMpKSBpY1xuXG5cbiAgbGV0IG9wZW5faW4gPSBvcGVuX2luX2ZpbGUgU3RkbGliLm9wZW5faW5cbiAgbGV0IG9wZW5faW5fYmluID0gb3Blbl9pbl9maWxlIFN0ZGxpYi5vcGVuX2luX2JpblxuXG4gIGxldCBmcm9tX2ZpbGUgPSBvcGVuX2luXG4gIGxldCBmcm9tX2ZpbGVfYmluID0gb3Blbl9pbl9iaW5cblxuICBsZXQgZnJvbV9jaGFubmVsIGljID1cbiAgICBmcm9tX2ljX3JhaXNlX2F0X2VuZCAoRnJvbV9jaGFubmVsIGljKSBpY1xuXG5cbiAgbGV0IGNsb3NlX2luIGliID1cbiAgICBtYXRjaCBpYi5pY19pbnB1dF9uYW1lIHdpdGhcbiAgICB8IEZyb21fY2hhbm5lbCBpYyAtPlxuICAgICAgU3RkbGliLmNsb3NlX2luIGljXG4gICAgfCBGcm9tX2ZpbGUgKF9mbmFtZSwgaWMpIC0+IFN0ZGxpYi5jbG9zZV9pbiBpY1xuICAgIHwgRnJvbV9mdW5jdGlvbiB8IEZyb21fc3RyaW5nIC0+ICgpXG5cblxuICAoKlxuICAgICBPYnNvbGV0ZTogYSBtZW1vIFtmcm9tX2NoYW5uZWxdIHZlcnNpb24gdG8gYnVpbGQgYSBbU2Nhbm5pbmcuaW5fY2hhbm5lbF1cbiAgICAgc2Nhbm5pbmcgYnVmZmVyIG91dCBvZiBhIFtTdGRsaWIuaW5fY2hhbm5lbF0uXG4gICAgIFRoaXMgZnVuY3Rpb24gd2FzIHVzZWQgdG8gdHJ5IHRvIHByZXNlcnZlIHRoZSBzY2FubmluZ1xuICAgICBzZW1hbnRpY3MgZm9yIHRoZSAobm93IG9ic29sZXRlKSBmdW5jdGlvbiBbZnNjYW5mXS5cbiAgICAgR2l2ZW4gdGhhdCBhbGwgc2Nhbm5lciBtdXN0IHJlYWQgZnJvbSBhIFtTY2FubmluZy5pbl9jaGFubmVsXSBzY2FubmluZ1xuICAgICBidWZmZXIsIFtmc2NhbmZdIG11c3QgcmVhZCBmcm9tIG9uZSFcbiAgICAgTW9yZSBwcmVjaXNlbHksIGdpdmVuIFtpY10sIGFsbCBzdWNjZXNzaXZlIGNhbGxzIFtmc2NhbmYgaWNdIG11c3QgcmVhZFxuICAgICBmcm9tIHRoZSBzYW1lIHNjYW5uaW5nIGJ1ZmZlci5cbiAgICAgVGhpcyBvYmxpZ2VkIHRoaXMgbGlicmFyeSB0byBhbGxvY2F0ZWQgc2Nhbm5pbmcgYnVmZmVycyB0aGF0IHdlcmVcbiAgICAgbm90IHByb3Blcmx5IGdhcmJhZ2UgY29sbGVjdGFibGUsIGhlbmNlIGxlYWRpbmcgdG8gbWVtb3J5IGxlYWtzLlxuICAgICBJZiB5b3UgbmVlZCB0byByZWFkIGZyb20gYSBbU3RkbGliLmluX2NoYW5uZWxdIGlucHV0IGNoYW5uZWxcbiAgICAgW2ljXSwgc2ltcGx5IGRlZmluZSBhIFtTY2FubmluZy5pbl9jaGFubmVsXSBmb3JtYXR0ZWQgaW5wdXQgY2hhbm5lbCBhcyBpblxuICAgICBbbGV0IGliID0gU2Nhbm5pbmcuZnJvbV9jaGFubmVsIGljXSwgdGhlbiB1c2UgW1NjYW5mLmJzY2FuZiBpYl0gYXMgdXN1YWwuXG4gICopXG4gIGxldCBtZW1vX2Zyb21faWMgPVxuICAgIGxldCBtZW1vID0gcmVmIFtdIGluXG4gICAgKGZ1biBzY2FuX2Nsb3NlX2ljIGljIC0+XG4gICAgIHRyeSBMaXN0LmFzc3EgaWMgIW1lbW8gd2l0aFxuICAgICB8IE5vdF9mb3VuZCAtPlxuICAgICAgIGxldCBpYiA9XG4gICAgICAgICBmcm9tX2ljIHNjYW5fY2xvc2VfaWMgKEZyb21fY2hhbm5lbCBpYykgaWMgaW5cbiAgICAgICBtZW1vIDo9IChpYywgaWIpIDo6ICFtZW1vO1xuICAgICAgIGliKVxuXG5cbiAgKCogT2Jzb2xldGU6IHNlZSB7IW1lbW9fZnJvbV9pY30gYWJvdmUuICopXG4gIGxldCBtZW1vX2Zyb21fY2hhbm5lbCA9IG1lbW9fZnJvbV9pYyBzY2FuX3JhaXNlX2F0X2VuZFxuXG5lbmRcblxuXG4oKiBGb3JtYXR0ZWQgaW5wdXQgZnVuY3Rpb25zLiAqKVxuXG50eXBlICgnYSwgJ2IsICdjLCAnZCkgc2Nhbm5lciA9XG4gICAgICgnYSwgU2Nhbm5pbmcuaW5fY2hhbm5lbCwgJ2IsICdjLCAnYSAtPiAnZCwgJ2QpIGZvcm1hdDYgLT4gJ2NcblxuXG4oKiBSZXBvcnRpbmcgZXJyb3JzLiAqKVxuZXhjZXB0aW9uIFNjYW5fZmFpbHVyZSBvZiBzdHJpbmdcblxubGV0IGJhZF9pbnB1dCBzID0gcmFpc2UgKFNjYW5fZmFpbHVyZSBzKVxuXG5sZXQgYmFkX2lucHV0X2VzY2FwZSBjID1cbiAgYmFkX2lucHV0IChQcmludGYuc3ByaW50ZiBcImlsbGVnYWwgZXNjYXBlIGNoYXJhY3RlciAlQ1wiIGMpXG5cblxubGV0IGJhZF90b2tlbl9sZW5ndGggbWVzc2FnZSA9XG4gIGJhZF9pbnB1dFxuICAgIChQcmludGYuc3ByaW50ZlxuICAgICAgIFwic2Nhbm5pbmcgb2YgJXMgZmFpbGVkOiBcXFxuICAgICAgICB0aGUgc3BlY2lmaWVkIGxlbmd0aCB3YXMgdG9vIHNob3J0IGZvciB0b2tlblwiXG4gICAgICAgbWVzc2FnZSlcblxuXG5sZXQgYmFkX2VuZF9vZl9pbnB1dCBtZXNzYWdlID1cbiAgYmFkX2lucHV0XG4gICAgKFByaW50Zi5zcHJpbnRmXG4gICAgICAgXCJzY2FubmluZyBvZiAlcyBmYWlsZWQ6IFxcXG4gICAgICAgIHByZW1hdHVyZSBlbmQgb2YgZmlsZSBvY2N1cnJlZCBiZWZvcmUgZW5kIG9mIHRva2VuXCJcbiAgICAgICBtZXNzYWdlKVxuXG5cbmxldCBiYWRfZmxvYXQgKCkgPVxuICBiYWRfaW5wdXQgXCJubyBkb3Qgb3IgZXhwb25lbnQgcGFydCBmb3VuZCBpbiBmbG9hdCB0b2tlblwiXG5cblxubGV0IGJhZF9oZXhfZmxvYXQgKCkgPVxuICBiYWRfaW5wdXQgXCJub3QgYSB2YWxpZCBmbG9hdCBpbiBoZXhhZGVjaW1hbCBub3RhdGlvblwiXG5cblxubGV0IGNoYXJhY3Rlcl9taXNtYXRjaF9lcnIgYyBjaSA9XG4gIFByaW50Zi5zcHJpbnRmIFwibG9va2luZyBmb3IgJUMsIGZvdW5kICVDXCIgYyBjaVxuXG5cbmxldCBjaGFyYWN0ZXJfbWlzbWF0Y2ggYyBjaSA9XG4gIGJhZF9pbnB1dCAoY2hhcmFjdGVyX21pc21hdGNoX2VyciBjIGNpKVxuXG5cbmxldCByZWMgc2tpcF93aGl0ZXMgaWIgPVxuICBsZXQgYyA9IFNjYW5uaW5nLnBlZWtfY2hhciBpYiBpblxuICBpZiBub3QgKFNjYW5uaW5nLmVvZiBpYikgdGhlbiBiZWdpblxuICAgIG1hdGNoIGMgd2l0aFxuICAgIHwgJyAnIHwgJ1xcdCcgfCAnXFxuJyB8ICdcXHInIC0+XG4gICAgICBTY2FubmluZy5pbnZhbGlkYXRlX2N1cnJlbnRfY2hhciBpYjsgc2tpcF93aGl0ZXMgaWJcbiAgICB8IF8gLT4gKClcbiAgZW5kXG5cblxuKCogQ2hlY2tpbmcgdGhhdCBbY10gaXMgaW5kZWVkIGluIHRoZSBpbnB1dCwgdGhlbiBza2lwcyBpdC5cbiAgIEluIHRoaXMgY2FzZSwgdGhlIGNoYXJhY3RlciBbY10gaGFzIGJlZW4gZXhwbGljaXRseSBzcGVjaWZpZWQgaW4gdGhlXG4gICBmb3JtYXQgYXMgYmVpbmcgbWFuZGF0b3J5IGluIHRoZSBpbnB1dDsgaGVuY2Ugd2Ugc2hvdWxkIGZhaWwgd2l0aFxuICAgW0VuZF9vZl9maWxlXSBpbiBjYXNlIG9mIGVuZF9vZl9pbnB1dC5cbiAgIChSZW1lbWJlciB0aGF0IFtTY2FuX2ZhaWx1cmVdIGlzIHJhaXNlZCBvbmx5IHdoZW4gKHdlIGNhbiBwcm92ZSBieVxuICAgZXZpZGVuY2UpIHRoYXQgdGhlIGlucHV0IGRvZXMgbm90IG1hdGNoIHRoZSBmb3JtYXQgc3RyaW5nIGdpdmVuLiBXZSBtdXN0XG4gICB0aHVzIGRpZmZlcmVudGlhdGUgW0VuZF9vZl9maWxlXSBhcyBhbiBlcnJvciBkdWUgdG8gbGFjayBvZiBpbnB1dCwgYW5kXG4gICBbU2Nhbl9mYWlsdXJlXSB3aGljaCBpcyBkdWUgdG8gcHJvdmFibHkgd3JvbmcgaW5wdXQuIEkgYW0gbm90IHN1cmUgdGhpcyBpc1xuICAgd29ydGggdGhlIGJ1cmRlbjogaXQgaXMgY29tcGxleCBhbmQgc29tZWhvdyBzdWJsaW1pbmFsOyBzaG91bGQgYmUgY2xlYXJlclxuICAgdG8gZmFpbCB3aXRoIFNjYW5fZmFpbHVyZSBcIk5vdCBlbm91Z2ggaW5wdXQgdG8gY29tcGxldGUgc2Nhbm5pbmdcIiEpXG5cbiAgIFRoYXQncyB3aHksIHdhaXRpbmcgZm9yIGEgYmV0dGVyIHNvbHV0aW9uLCB3ZSB1c2UgY2hlY2tlZF9wZWVrX2NoYXIgaGVyZS5cbiAgIFdlIGFyZSBhbHNvIGNhcmVmdWwgdG8gdHJlYXQgXCJcXHJcXG5cIiBpbiB0aGUgaW5wdXQgYXMgYW4gZW5kIG9mIGxpbmUgbWFya2VyOlxuICAgaXQgYWx3YXlzIG1hdGNoZXMgYSAnXFxuJyBzcGVjaWZpY2F0aW9uIGluIHRoZSBpbnB1dCBmb3JtYXQgc3RyaW5nLiAqKVxubGV0IHJlYyBjaGVja19jaGFyIGliIGMgPVxuICBtYXRjaCBjIHdpdGhcbiAgfCAnICcgLT4gc2tpcF93aGl0ZXMgaWJcbiAgfCAnXFxuJyAtPiBjaGVja19uZXdsaW5lIGliXG4gIHwgYyAtPiBjaGVja190aGlzX2NoYXIgaWIgY1xuXG5hbmQgY2hlY2tfdGhpc19jaGFyIGliIGMgPVxuICBsZXQgY2kgPSBTY2FubmluZy5jaGVja2VkX3BlZWtfY2hhciBpYiBpblxuICBpZiBjaSA9IGMgdGhlbiBTY2FubmluZy5pbnZhbGlkYXRlX2N1cnJlbnRfY2hhciBpYiBlbHNlXG4gIGNoYXJhY3Rlcl9taXNtYXRjaCBjIGNpXG5cbmFuZCBjaGVja19uZXdsaW5lIGliID1cbiAgbGV0IGNpID0gU2Nhbm5pbmcuY2hlY2tlZF9wZWVrX2NoYXIgaWIgaW5cbiAgbWF0Y2ggY2kgd2l0aFxuICB8ICdcXG4nIC0+IFNjYW5uaW5nLmludmFsaWRhdGVfY3VycmVudF9jaGFyIGliXG4gIHwgJ1xccicgLT4gU2Nhbm5pbmcuaW52YWxpZGF0ZV9jdXJyZW50X2NoYXIgaWI7IGNoZWNrX3RoaXNfY2hhciBpYiAnXFxuJ1xuICB8IF8gLT4gY2hhcmFjdGVyX21pc21hdGNoICdcXG4nIGNpXG5cblxuKCogRXh0cmFjdGluZyB0b2tlbnMgZnJvbSB0aGUgb3V0cHV0IHRva2VuIGJ1ZmZlci4gKilcblxubGV0IHRva2VuX2NoYXIgaWIgPSAoU2Nhbm5pbmcudG9rZW4gaWIpLlswXVxuXG5sZXQgdG9rZW5fc3RyaW5nID0gU2Nhbm5pbmcudG9rZW5cblxubGV0IHRva2VuX2Jvb2wgaWIgPVxuICBtYXRjaCBTY2FubmluZy50b2tlbiBpYiB3aXRoXG4gIHwgXCJ0cnVlXCIgLT4gdHJ1ZVxuICB8IFwiZmFsc2VcIiAtPiBmYWxzZVxuICB8IHMgLT4gYmFkX2lucHV0IChQcmludGYuc3ByaW50ZiBcImludmFsaWQgYm9vbGVhbiAnJXMnXCIgcylcblxuXG4oKiBUaGUgdHlwZSBvZiBpbnRlZ2VyIGNvbnZlcnNpb25zLiAqKVxudHlwZSBpbnRlZ2VyX2NvbnZlcnNpb24gPVxuICB8IEJfY29udmVyc2lvbiAoKiBVbnNpZ25lZCBiaW5hcnkgY29udmVyc2lvbiAqKVxuICB8IERfY29udmVyc2lvbiAoKiBTaWduZWQgZGVjaW1hbCBjb252ZXJzaW9uICopXG4gIHwgSV9jb252ZXJzaW9uICgqIFNpZ25lZCBpbnRlZ2VyIGNvbnZlcnNpb24gKilcbiAgfCBPX2NvbnZlcnNpb24gKCogVW5zaWduZWQgb2N0YWwgY29udmVyc2lvbiAqKVxuICB8IFVfY29udmVyc2lvbiAoKiBVbnNpZ25lZCBkZWNpbWFsIGNvbnZlcnNpb24gKilcbiAgfCBYX2NvbnZlcnNpb24gKCogVW5zaWduZWQgaGV4YWRlY2ltYWwgY29udmVyc2lvbiAqKVxuXG5cbmxldCBpbnRlZ2VyX2NvbnZlcnNpb25fb2ZfY2hhciA9IGZ1bmN0aW9uXG4gIHwgJ2InIC0+IEJfY29udmVyc2lvblxuICB8ICdkJyAtPiBEX2NvbnZlcnNpb25cbiAgfCAnaScgLT4gSV9jb252ZXJzaW9uXG4gIHwgJ28nIC0+IE9fY29udmVyc2lvblxuICB8ICd1JyAtPiBVX2NvbnZlcnNpb25cbiAgfCAneCcgfCAnWCcgLT4gWF9jb252ZXJzaW9uXG4gIHwgXyAtPiBhc3NlcnQgZmFsc2VcblxuXG4oKiBFeHRyYWN0IGFuIGludGVnZXIgbGl0ZXJhbCB0b2tlbi5cbiAgIFNpbmNlIHRoZSBmdW5jdGlvbnMgU3RkbGliLippbnQqX29mX3N0cmluZyBkbyBub3QgYWNjZXB0IGEgbGVhZGluZyArLFxuICAgd2Ugc2tpcCBpdCBpZiBuZWNlc3NhcnkuICopXG5sZXQgdG9rZW5faW50X2xpdGVyYWwgY29udiBpYiA9XG4gIGxldCB0b2sgPVxuICAgIG1hdGNoIGNvbnYgd2l0aFxuICAgIHwgRF9jb252ZXJzaW9uIHwgSV9jb252ZXJzaW9uIC0+IFNjYW5uaW5nLnRva2VuIGliXG4gICAgfCBVX2NvbnZlcnNpb24gLT4gXCIwdVwiIF4gU2Nhbm5pbmcudG9rZW4gaWJcbiAgICB8IE9fY29udmVyc2lvbiAtPiBcIjBvXCIgXiBTY2FubmluZy50b2tlbiBpYlxuICAgIHwgWF9jb252ZXJzaW9uIC0+IFwiMHhcIiBeIFNjYW5uaW5nLnRva2VuIGliXG4gICAgfCBCX2NvbnZlcnNpb24gLT4gXCIwYlwiIF4gU2Nhbm5pbmcudG9rZW4gaWIgaW5cbiAgbGV0IGwgPSBTdHJpbmcubGVuZ3RoIHRvayBpblxuICBpZiBsID0gMCB8fCB0b2suWzBdIDw+ICcrJyB0aGVuIHRvayBlbHNlIFN0cmluZy5zdWIgdG9rIDEgKGwgLSAxKVxuXG5cbigqIEFsbCB0aGUgZnVuY3Rpb25zIHRoYXQgY29udmVydCBhIHN0cmluZyB0byBhIG51bWJlciByYWlzZSB0aGUgZXhjZXB0aW9uXG4gICBGYWlsdXJlIHdoZW4gdGhlIGNvbnZlcnNpb24gaXMgbm90IHBvc3NpYmxlLlxuICAgVGhpcyBleGNlcHRpb24gaXMgdGhlbiB0cmFwcGVkIGluIFtrc2NhbmZdLiAqKVxubGV0IHRva2VuX2ludCBjb252IGliID0gaW50X29mX3N0cmluZyAodG9rZW5faW50X2xpdGVyYWwgY29udiBpYilcblxubGV0IHRva2VuX2Zsb2F0IGliID0gZmxvYXRfb2Zfc3RyaW5nIChTY2FubmluZy50b2tlbiBpYilcblxuKCogVG8gc2NhbiBuYXRpdmUgaW50cywgaW50MzIgYW5kIGludDY0IGludGVnZXJzLlxuICAgV2UgY2Fubm90IGFjY2VzcyB0byBjb252ZXJzaW9ucyB0by9mcm9tIHN0cmluZ3MgZm9yIHRob3NlIHR5cGVzLFxuICAgTmF0aXZlaW50Lm9mX3N0cmluZywgSW50MzIub2Zfc3RyaW5nLCBhbmQgSW50NjQub2Zfc3RyaW5nLFxuICAgc2luY2UgdGhvc2UgbW9kdWxlcyBhcmUgbm90IGF2YWlsYWJsZSB0byBbU2NhbmZdLlxuICAgSG93ZXZlciwgd2UgY2FuIGJpbmQgYW5kIHVzZSB0aGUgY29ycmVzcG9uZGluZyBwcmltaXRpdmVzIHRoYXQgYXJlXG4gICBhdmFpbGFibGUgaW4gdGhlIHJ1bnRpbWUuICopXG5leHRlcm5hbCBuYXRpdmVpbnRfb2Zfc3RyaW5nIDogc3RyaW5nIC0+IG5hdGl2ZWludFxuICA9IFwiY2FtbF9uYXRpdmVpbnRfb2Zfc3RyaW5nXCJcblxuZXh0ZXJuYWwgaW50MzJfb2Zfc3RyaW5nIDogc3RyaW5nIC0+IGludDMyXG4gID0gXCJjYW1sX2ludDMyX29mX3N0cmluZ1wiXG5cbmV4dGVybmFsIGludDY0X29mX3N0cmluZyA6IHN0cmluZyAtPiBpbnQ2NFxuICA9IFwiY2FtbF9pbnQ2NF9vZl9zdHJpbmdcIlxuXG5cbmxldCB0b2tlbl9uYXRpdmVpbnQgY29udiBpYiA9IG5hdGl2ZWludF9vZl9zdHJpbmcgKHRva2VuX2ludF9saXRlcmFsIGNvbnYgaWIpXG5sZXQgdG9rZW5faW50MzIgY29udiBpYiA9IGludDMyX29mX3N0cmluZyAodG9rZW5faW50X2xpdGVyYWwgY29udiBpYilcbmxldCB0b2tlbl9pbnQ2NCBjb252IGliID0gaW50NjRfb2Zfc3RyaW5nICh0b2tlbl9pbnRfbGl0ZXJhbCBjb252IGliKVxuXG4oKiBTY2FubmluZyBudW1iZXJzLiAqKVxuXG4oKiBEaWdpdHMgc2Nhbm5pbmcgZnVuY3Rpb25zIHN1cHBvc2UgdGhhdCBvbmUgY2hhcmFjdGVyIGhhcyBiZWVuIGNoZWNrZWQgYW5kXG4gICBpcyBhdmFpbGFibGUsIHNpbmNlIHRoZXkgcmV0dXJuIGF0IGVuZCBvZiBmaWxlIHdpdGggdGhlIGN1cnJlbnRseSBmb3VuZFxuICAgdG9rZW4gc2VsZWN0ZWQuXG5cbiAgIFB1dCBpdCBpbiBhbm90aGVyIHdheSwgdGhlIGRpZ2l0cyBzY2FubmluZyBmdW5jdGlvbnMgc2NhbiBmb3IgYSBwb3NzaWJseVxuICAgZW1wdHkgc2VxdWVuY2Ugb2YgZGlnaXRzLCAoaGVuY2UsIGEgc3VjY2Vzc2Z1bCBzY2FubmluZyBmcm9tIG9uZSBvZiB0aG9zZVxuICAgZnVuY3Rpb25zIGRvZXMgbm90IGltcGx5IHRoYXQgdGhlIHRva2VuIGlzIGEgd2VsbC1mb3JtZWQgbnVtYmVyOiB0byBnZXQgYVxuICAgdHJ1ZSBudW1iZXIsIGl0IGlzIG1hbmRhdG9yeSB0byBjaGVjayB0aGF0IGF0IGxlYXN0IG9uZSB2YWxpZCBkaWdpdCBpc1xuICAgYXZhaWxhYmxlIGJlZm9yZSBjYWxsaW5nIG9uZSBvZiB0aGUgZGlnaXQgc2Nhbm5pbmcgZnVuY3Rpb25zKS4gKilcblxuKCogVGhlIGRlY2ltYWwgY2FzZSBpcyB0cmVhdGVkIGVzcGVjaWFsbHkgZm9yIG9wdGltaXphdGlvbiBwdXJwb3Nlcy4gKilcbmxldCByZWMgc2Nhbl9kZWNpbWFsX2RpZ2l0X3N0YXIgd2lkdGggaWIgPVxuICBpZiB3aWR0aCA9IDAgdGhlbiB3aWR0aCBlbHNlXG4gIGxldCBjID0gU2Nhbm5pbmcucGVla19jaGFyIGliIGluXG4gIGlmIFNjYW5uaW5nLmVvZiBpYiB0aGVuIHdpZHRoIGVsc2VcbiAgbWF0Y2ggYyB3aXRoXG4gIHwgJzAnIC4uICc5JyBhcyBjIC0+XG4gICAgbGV0IHdpZHRoID0gU2Nhbm5pbmcuc3RvcmVfY2hhciB3aWR0aCBpYiBjIGluXG4gICAgc2Nhbl9kZWNpbWFsX2RpZ2l0X3N0YXIgd2lkdGggaWJcbiAgfCAnXycgLT5cbiAgICBsZXQgd2lkdGggPSBTY2FubmluZy5pZ25vcmVfY2hhciB3aWR0aCBpYiBpblxuICAgIHNjYW5fZGVjaW1hbF9kaWdpdF9zdGFyIHdpZHRoIGliXG4gIHwgXyAtPiB3aWR0aFxuXG5cbmxldCBzY2FuX2RlY2ltYWxfZGlnaXRfcGx1cyB3aWR0aCBpYiA9XG4gIGlmIHdpZHRoID0gMCB0aGVuIGJhZF90b2tlbl9sZW5ndGggXCJkZWNpbWFsIGRpZ2l0c1wiIGVsc2VcbiAgbGV0IGMgPSBTY2FubmluZy5jaGVja2VkX3BlZWtfY2hhciBpYiBpblxuICBtYXRjaCBjIHdpdGhcbiAgfCAnMCcgLi4gJzknIC0+XG4gICAgbGV0IHdpZHRoID0gU2Nhbm5pbmcuc3RvcmVfY2hhciB3aWR0aCBpYiBjIGluXG4gICAgc2Nhbl9kZWNpbWFsX2RpZ2l0X3N0YXIgd2lkdGggaWJcbiAgfCBjIC0+XG4gICAgYmFkX2lucHV0IChQcmludGYuc3ByaW50ZiBcImNoYXJhY3RlciAlQyBpcyBub3QgYSBkZWNpbWFsIGRpZ2l0XCIgYylcblxuXG4oKiBUbyBzY2FuIG51bWJlcnMgZnJvbSBvdGhlciBiYXNlcywgd2UgdXNlIGEgcHJlZGljYXRlIGFyZ3VtZW50IHRvXG4gICBzY2FuIGRpZ2l0cy4gKilcbmxldCBzY2FuX2RpZ2l0X3N0YXIgZGlnaXRwIHdpZHRoIGliID1cbiAgbGV0IHJlYyBzY2FuX2RpZ2l0cyB3aWR0aCBpYiA9XG4gICAgaWYgd2lkdGggPSAwIHRoZW4gd2lkdGggZWxzZVxuICAgIGxldCBjID0gU2Nhbm5pbmcucGVla19jaGFyIGliIGluXG4gICAgaWYgU2Nhbm5pbmcuZW9mIGliIHRoZW4gd2lkdGggZWxzZVxuICAgIG1hdGNoIGMgd2l0aFxuICAgIHwgYyB3aGVuIGRpZ2l0cCBjIC0+XG4gICAgICBsZXQgd2lkdGggPSBTY2FubmluZy5zdG9yZV9jaGFyIHdpZHRoIGliIGMgaW5cbiAgICAgIHNjYW5fZGlnaXRzIHdpZHRoIGliXG4gICAgfCAnXycgLT5cbiAgICAgIGxldCB3aWR0aCA9IFNjYW5uaW5nLmlnbm9yZV9jaGFyIHdpZHRoIGliIGluXG4gICAgICBzY2FuX2RpZ2l0cyB3aWR0aCBpYlxuICAgIHwgXyAtPiB3aWR0aCBpblxuICBzY2FuX2RpZ2l0cyB3aWR0aCBpYlxuXG5cbmxldCBzY2FuX2RpZ2l0X3BsdXMgYmFzaXMgZGlnaXRwIHdpZHRoIGliID1cbiAgKCogRW5zdXJlIHdlIGhhdmUgZ290IGVub3VnaCB3aWR0aCBsZWZ0LFxuICAgICBhbmQgcmVhZCBhdCBsZWFzdCBvbmUgZGlnaXQuICopXG4gIGlmIHdpZHRoID0gMCB0aGVuIGJhZF90b2tlbl9sZW5ndGggXCJkaWdpdHNcIiBlbHNlXG4gIGxldCBjID0gU2Nhbm5pbmcuY2hlY2tlZF9wZWVrX2NoYXIgaWIgaW5cbiAgaWYgZGlnaXRwIGMgdGhlblxuICAgIGxldCB3aWR0aCA9IFNjYW5uaW5nLnN0b3JlX2NoYXIgd2lkdGggaWIgYyBpblxuICAgIHNjYW5fZGlnaXRfc3RhciBkaWdpdHAgd2lkdGggaWJcbiAgZWxzZVxuICAgIGJhZF9pbnB1dCAoUHJpbnRmLnNwcmludGYgXCJjaGFyYWN0ZXIgJUMgaXMgbm90IGEgdmFsaWQgJXMgZGlnaXRcIiBjIGJhc2lzKVxuXG5cbmxldCBpc19iaW5hcnlfZGlnaXQgPSBmdW5jdGlvblxuICB8ICcwJyAuLiAnMScgLT4gdHJ1ZVxuICB8IF8gLT4gZmFsc2VcblxuXG5sZXQgc2Nhbl9iaW5hcnlfaW50ID0gc2Nhbl9kaWdpdF9wbHVzIFwiYmluYXJ5XCIgaXNfYmluYXJ5X2RpZ2l0XG5cbmxldCBpc19vY3RhbF9kaWdpdCA9IGZ1bmN0aW9uXG4gIHwgJzAnIC4uICc3JyAtPiB0cnVlXG4gIHwgXyAtPiBmYWxzZVxuXG5cbmxldCBzY2FuX29jdGFsX2ludCA9IHNjYW5fZGlnaXRfcGx1cyBcIm9jdGFsXCIgaXNfb2N0YWxfZGlnaXRcblxubGV0IGlzX2hleGFfZGlnaXQgPSBmdW5jdGlvblxuICB8ICcwJyAuLiAnOScgfCAnYScgLi4gJ2YnIHwgJ0EnIC4uICdGJyAtPiB0cnVlXG4gIHwgXyAtPiBmYWxzZVxuXG5cbmxldCBzY2FuX2hleGFkZWNpbWFsX2ludCA9IHNjYW5fZGlnaXRfcGx1cyBcImhleGFkZWNpbWFsXCIgaXNfaGV4YV9kaWdpdFxuXG4oKiBTY2FuIGEgZGVjaW1hbCBpbnRlZ2VyLiAqKVxubGV0IHNjYW5fdW5zaWduZWRfZGVjaW1hbF9pbnQgPSBzY2FuX2RlY2ltYWxfZGlnaXRfcGx1c1xuXG5sZXQgc2Nhbl9zaWduIHdpZHRoIGliID1cbiAgbGV0IGMgPSBTY2FubmluZy5jaGVja2VkX3BlZWtfY2hhciBpYiBpblxuICBtYXRjaCBjIHdpdGhcbiAgfCAnKycgLT4gU2Nhbm5pbmcuc3RvcmVfY2hhciB3aWR0aCBpYiBjXG4gIHwgJy0nIC0+IFNjYW5uaW5nLnN0b3JlX2NoYXIgd2lkdGggaWIgY1xuICB8IF8gLT4gd2lkdGhcblxuXG5sZXQgc2Nhbl9vcHRpb25hbGx5X3NpZ25lZF9kZWNpbWFsX2ludCB3aWR0aCBpYiA9XG4gIGxldCB3aWR0aCA9IHNjYW5fc2lnbiB3aWR0aCBpYiBpblxuICBzY2FuX3Vuc2lnbmVkX2RlY2ltYWxfaW50IHdpZHRoIGliXG5cblxuKCogU2NhbiBhbiB1bnNpZ25lZCBpbnRlZ2VyIHRoYXQgY291bGQgYmUgZ2l2ZW4gaW4gYW55IChjb21tb24pIGJhc2lzLlxuICAgSWYgZGlnaXRzIGFyZSBwcmVmaXhlZCBieSBvbmUgb2YgMHgsIDBYLCAwbywgb3IgMGIsIHRoZSBudW1iZXIgaXNcbiAgIGFzc3VtZWQgdG8gYmUgd3JpdHRlbiByZXNwZWN0aXZlbHkgaW4gaGV4YWRlY2ltYWwsIGhleGFkZWNpbWFsLFxuICAgb2N0YWwsIG9yIGJpbmFyeS4gKilcbmxldCBzY2FuX3Vuc2lnbmVkX2ludCB3aWR0aCBpYiA9XG4gIG1hdGNoIFNjYW5uaW5nLmNoZWNrZWRfcGVla19jaGFyIGliIHdpdGhcbiAgfCAnMCcgYXMgYyAtPlxuICAgIGxldCB3aWR0aCA9IFNjYW5uaW5nLnN0b3JlX2NoYXIgd2lkdGggaWIgYyBpblxuICAgIGlmIHdpZHRoID0gMCB0aGVuIHdpZHRoIGVsc2VcbiAgICBsZXQgYyA9IFNjYW5uaW5nLnBlZWtfY2hhciBpYiBpblxuICAgIGlmIFNjYW5uaW5nLmVvZiBpYiB0aGVuIHdpZHRoIGVsc2VcbiAgICBiZWdpbiBtYXRjaCBjIHdpdGhcbiAgICB8ICd4JyB8ICdYJyAtPiBzY2FuX2hleGFkZWNpbWFsX2ludCAoU2Nhbm5pbmcuc3RvcmVfY2hhciB3aWR0aCBpYiBjKSBpYlxuICAgIHwgJ28nIC0+IHNjYW5fb2N0YWxfaW50IChTY2FubmluZy5zdG9yZV9jaGFyIHdpZHRoIGliIGMpIGliXG4gICAgfCAnYicgLT4gc2Nhbl9iaW5hcnlfaW50IChTY2FubmluZy5zdG9yZV9jaGFyIHdpZHRoIGliIGMpIGliXG4gICAgfCBfIC0+IHNjYW5fZGVjaW1hbF9kaWdpdF9zdGFyIHdpZHRoIGliIGVuZFxuICB8IF8gLT4gc2Nhbl91bnNpZ25lZF9kZWNpbWFsX2ludCB3aWR0aCBpYlxuXG5cbmxldCBzY2FuX29wdGlvbmFsbHlfc2lnbmVkX2ludCB3aWR0aCBpYiA9XG4gIGxldCB3aWR0aCA9IHNjYW5fc2lnbiB3aWR0aCBpYiBpblxuICBzY2FuX3Vuc2lnbmVkX2ludCB3aWR0aCBpYlxuXG5cbmxldCBzY2FuX2ludF9jb252ZXJzaW9uIGNvbnYgd2lkdGggaWIgPVxuICBtYXRjaCBjb252IHdpdGhcbiAgfCBCX2NvbnZlcnNpb24gLT4gc2Nhbl9iaW5hcnlfaW50IHdpZHRoIGliXG4gIHwgRF9jb252ZXJzaW9uIC0+IHNjYW5fb3B0aW9uYWxseV9zaWduZWRfZGVjaW1hbF9pbnQgd2lkdGggaWJcbiAgfCBJX2NvbnZlcnNpb24gLT4gc2Nhbl9vcHRpb25hbGx5X3NpZ25lZF9pbnQgd2lkdGggaWJcbiAgfCBPX2NvbnZlcnNpb24gLT4gc2Nhbl9vY3RhbF9pbnQgd2lkdGggaWJcbiAgfCBVX2NvbnZlcnNpb24gLT4gc2Nhbl91bnNpZ25lZF9kZWNpbWFsX2ludCB3aWR0aCBpYlxuICB8IFhfY29udmVyc2lvbiAtPiBzY2FuX2hleGFkZWNpbWFsX2ludCB3aWR0aCBpYlxuXG5cbigqIFNjYW5uaW5nIGZsb2F0aW5nIHBvaW50IG51bWJlcnMuICopXG5cbigqIEZyYWN0aW9uYWwgcGFydCBpcyBvcHRpb25hbCBhbmQgY2FuIGJlIHJlZHVjZWQgdG8gMCBkaWdpdHMuICopXG5sZXQgc2Nhbl9mcmFjdGlvbmFsX3BhcnQgd2lkdGggaWIgPVxuICBpZiB3aWR0aCA9IDAgdGhlbiB3aWR0aCBlbHNlXG4gIGxldCBjID0gU2Nhbm5pbmcucGVla19jaGFyIGliIGluXG4gIGlmIFNjYW5uaW5nLmVvZiBpYiB0aGVuIHdpZHRoIGVsc2VcbiAgbWF0Y2ggYyB3aXRoXG4gIHwgJzAnIC4uICc5JyBhcyBjIC0+XG4gICAgc2Nhbl9kZWNpbWFsX2RpZ2l0X3N0YXIgKFNjYW5uaW5nLnN0b3JlX2NoYXIgd2lkdGggaWIgYykgaWJcbiAgfCBfIC0+IHdpZHRoXG5cblxuKCogRXhwIHBhcnQgaXMgb3B0aW9uYWwgYW5kIGNhbiBiZSByZWR1Y2VkIHRvIDAgZGlnaXRzLiAqKVxubGV0IHNjYW5fZXhwb25lbnRfcGFydCB3aWR0aCBpYiA9XG4gIGlmIHdpZHRoID0gMCB0aGVuIHdpZHRoIGVsc2VcbiAgbGV0IGMgPSBTY2FubmluZy5wZWVrX2NoYXIgaWIgaW5cbiAgaWYgU2Nhbm5pbmcuZW9mIGliIHRoZW4gd2lkdGggZWxzZVxuICBtYXRjaCBjIHdpdGhcbiAgfCAnZScgfCAnRScgYXMgYyAtPlxuICAgIHNjYW5fb3B0aW9uYWxseV9zaWduZWRfZGVjaW1hbF9pbnQgKFNjYW5uaW5nLnN0b3JlX2NoYXIgd2lkdGggaWIgYykgaWJcbiAgfCBfIC0+IHdpZHRoXG5cblxuKCogU2NhbiB0aGUgaW50ZWdlciBwYXJ0IG9mIGEgZmxvYXRpbmcgcG9pbnQgbnVtYmVyLCAobm90IHVzaW5nIHRoZVxuICAgT0NhbWwgbGV4aWNhbCBjb252ZW50aW9uIHNpbmNlIHRoZSBpbnRlZ2VyIHBhcnQgY2FuIGJlIGVtcHR5KTpcbiAgIGFuIG9wdGlvbmFsIHNpZ24sIGZvbGxvd2VkIGJ5IGEgcG9zc2libHkgZW1wdHkgc2VxdWVuY2Ugb2YgZGVjaW1hbFxuICAgZGlnaXRzIChlLmcuIC0uMSkuICopXG5sZXQgc2Nhbl9pbnRlZ2VyX3BhcnQgd2lkdGggaWIgPVxuICBsZXQgd2lkdGggPSBzY2FuX3NpZ24gd2lkdGggaWIgaW5cbiAgc2Nhbl9kZWNpbWFsX2RpZ2l0X3N0YXIgd2lkdGggaWJcblxuXG4oKlxuICAgRm9yIHRoZSB0aW1lIGJlaW5nIHdlIGhhdmUgKGFzIGZvdW5kIGluIHNjYW5mLm1saSk6XG4gICB0aGUgZmllbGQgd2lkdGggaXMgY29tcG9zZWQgb2YgYW4gb3B0aW9uYWwgaW50ZWdlciBsaXRlcmFsXG4gICBpbmRpY2F0aW5nIHRoZSBtYXhpbWFsIHdpZHRoIG9mIHRoZSB0b2tlbiB0byByZWFkLlxuICAgVW5mb3J0dW5hdGVseSwgdGhlIHR5cGUtY2hlY2tlciBsZXQgdGhlIHVzZXIgd3JpdGUgYW4gb3B0aW9uYWwgcHJlY2lzaW9uLFxuICAgc2luY2UgdGhpcyBpcyB2YWxpZCBmb3IgcHJpbnRmIGZvcm1hdCBzdHJpbmdzLlxuXG4gICBUaHVzLCB0aGUgbmV4dCBzdGVwIGZvciBTY2FuZiBpcyB0byBzdXBwb3J0IGEgZnVsbCB3aWR0aCBhbmQgcHJlY2lzaW9uXG4gICBpbmRpY2F0aW9uLCBtb3JlIG9yIGxlc3Mgc2ltaWxhciB0byB0aGUgb25lIGZvciBwcmludGYsIHBvc3NpYmx5IGV4dGVuZGVkXG4gICB0byB0aGUgc3BlY2lmaWNhdGlvbiBvZiBhIFttYXgsIG1pbl0gcmFuZ2UgZm9yIHRoZSB3aWR0aCBvZiB0aGUgdG9rZW4gcmVhZFxuICAgZm9yIHN0cmluZ3MuIFNvbWV0aGluZyBsaWtlIHRoZSBmb2xsb3dpbmcgc3BlYyBmb3Igc2NhbmYubWxpOlxuXG4gICBUaGUgb3B0aW9uYWwgW3dpZHRoXSBpcyBhbiBpbnRlZ2VyIGluZGljYXRpbmcgdGhlIG1heGltYWxcbiAgIHdpZHRoIG9mIHRoZSB0b2tlbiByZWFkLiBGb3IgaW5zdGFuY2UsIFslNmRdIHJlYWRzIGFuIGludGVnZXIsXG4gICBoYXZpbmcgYXQgbW9zdCA2IGNoYXJhY3RlcnMuXG5cbiAgIFRoZSBvcHRpb25hbCBbcHJlY2lzaW9uXSBpcyBhIGRvdCBbLl0gZm9sbG93ZWQgYnkgYW4gaW50ZWdlcjpcblxuICAgLSBpbiB0aGUgZmxvYXRpbmcgcG9pbnQgbnVtYmVyIGNvbnZlcnNpb25zIChbJWZdLCBbJWVdLCBbJWddLCBbJUZdLCBbJUVdLFxuICAgYW5kIFslRl0gY29udmVyc2lvbnMsIHRoZSBbcHJlY2lzaW9uXSBpbmRpY2F0ZXMgdGhlIG1heGltdW0gbnVtYmVyIG9mXG4gICBkaWdpdHMgdGhhdCBtYXkgZm9sbG93IHRoZSBkZWNpbWFsIHBvaW50LiBGb3IgaW5zdGFuY2UsIFslLjRmXSByZWFkcyBhXG4gICBbZmxvYXRdIHdpdGggYXQgbW9zdCA0IGZyYWN0aW9uYWwgZGlnaXRzLFxuXG4gICAtIGluIHRoZSBzdHJpbmcgY29udmVyc2lvbnMgKFslc10sIFslU10sIFslXFxbIHJhbmdlIFxcXV0pLCBhbmQgaW4gdGhlXG4gICBpbnRlZ2VyIG51bWJlciBjb252ZXJzaW9ucyAoWyVpXSwgWyVkXSwgWyV1XSwgWyV4XSwgWyVvXSwgYW5kIHRoZWlyXG4gICBbaW50MzJdLCBbaW50NjRdLCBhbmQgW25hdGl2ZV9pbnRdIGNvcnJlc3BvbmRlbnQpLCB0aGUgW3ByZWNpc2lvbl1cbiAgIGluZGljYXRlcyB0aGUgcmVxdWlyZWQgbWluaW11bSB3aWR0aCBvZiB0aGUgdG9rZW4gcmVhZCxcblxuICAgLSBvbiBhbGwgb3RoZXIgY29udmVyc2lvbnMsIHRoZSB3aWR0aCBhbmQgcHJlY2lzaW9uIHNwZWNpZnkgdGhlIFttYXgsIG1pbl1cbiAgIHJhbmdlIGZvciB0aGUgd2lkdGggb2YgdGhlIHRva2VuIHJlYWQuXG4qKVxubGV0IHNjYW5fZmxvYXQgd2lkdGggcHJlY2lzaW9uIGliID1cbiAgbGV0IHdpZHRoID0gc2Nhbl9pbnRlZ2VyX3BhcnQgd2lkdGggaWIgaW5cbiAgaWYgd2lkdGggPSAwIHRoZW4gd2lkdGgsIHByZWNpc2lvbiBlbHNlXG4gIGxldCBjID0gU2Nhbm5pbmcucGVla19jaGFyIGliIGluXG4gIGlmIFNjYW5uaW5nLmVvZiBpYiB0aGVuIHdpZHRoLCBwcmVjaXNpb24gZWxzZVxuICBtYXRjaCBjIHdpdGhcbiAgfCAnLicgLT5cbiAgICBsZXQgd2lkdGggPSBTY2FubmluZy5zdG9yZV9jaGFyIHdpZHRoIGliIGMgaW5cbiAgICBsZXQgcHJlY2lzaW9uID0gSW50Lm1pbiB3aWR0aCBwcmVjaXNpb24gaW5cbiAgICBsZXQgd2lkdGggPSB3aWR0aCAtIChwcmVjaXNpb24gLSBzY2FuX2ZyYWN0aW9uYWxfcGFydCBwcmVjaXNpb24gaWIpIGluXG4gICAgc2Nhbl9leHBvbmVudF9wYXJ0IHdpZHRoIGliLCBwcmVjaXNpb25cbiAgfCBfIC0+XG4gICAgc2Nhbl9leHBvbmVudF9wYXJ0IHdpZHRoIGliLCBwcmVjaXNpb25cblxuXG5sZXQgY2hlY2tfY2FzZV9pbnNlbnNpdGl2ZV9zdHJpbmcgd2lkdGggaWIgZXJyb3Igc3RyID1cbiAgbGV0IGxvd2VyY2FzZSBjID1cbiAgICBtYXRjaCBjIHdpdGhcbiAgICB8ICdBJyAuLiAnWicgLT5cbiAgICAgIGNoYXJfb2ZfaW50IChpbnRfb2ZfY2hhciBjIC0gaW50X29mX2NoYXIgJ0EnICsgaW50X29mX2NoYXIgJ2EnKVxuICAgIHwgXyAtPiBjIGluXG4gIGxldCBsZW4gPSBTdHJpbmcubGVuZ3RoIHN0ciBpblxuICBsZXQgd2lkdGggPSByZWYgd2lkdGggaW5cbiAgZm9yIGkgPSAwIHRvIGxlbiAtIDEgZG9cbiAgICBsZXQgYyA9IFNjYW5uaW5nLnBlZWtfY2hhciBpYiBpblxuICAgIGlmIGxvd2VyY2FzZSBjIDw+IGxvd2VyY2FzZSBzdHIuW2ldIHRoZW4gZXJyb3IgKCk7XG4gICAgaWYgIXdpZHRoID0gMCB0aGVuIGVycm9yICgpO1xuICAgIHdpZHRoIDo9IFNjYW5uaW5nLnN0b3JlX2NoYXIgIXdpZHRoIGliIGM7XG4gIGRvbmU7XG4gICF3aWR0aFxuXG5cbmxldCBzY2FuX2hleF9mbG9hdCB3aWR0aCBwcmVjaXNpb24gaWIgPVxuICBpZiB3aWR0aCA9IDAgfHwgU2Nhbm5pbmcuZW5kX29mX2lucHV0IGliIHRoZW4gYmFkX2hleF9mbG9hdCAoKTtcbiAgbGV0IHdpZHRoID0gc2Nhbl9zaWduIHdpZHRoIGliIGluXG4gIGlmIHdpZHRoID0gMCB8fCBTY2FubmluZy5lbmRfb2ZfaW5wdXQgaWIgdGhlbiBiYWRfaGV4X2Zsb2F0ICgpO1xuICBtYXRjaCBTY2FubmluZy5wZWVrX2NoYXIgaWIgd2l0aFxuICB8ICcwJyBhcyBjIC0+IChcbiAgICBsZXQgd2lkdGggPSBTY2FubmluZy5zdG9yZV9jaGFyIHdpZHRoIGliIGMgaW5cbiAgICBpZiB3aWR0aCA9IDAgfHwgU2Nhbm5pbmcuZW5kX29mX2lucHV0IGliIHRoZW4gYmFkX2hleF9mbG9hdCAoKTtcbiAgICBsZXQgd2lkdGggPSBjaGVja19jYXNlX2luc2Vuc2l0aXZlX3N0cmluZyB3aWR0aCBpYiBiYWRfaGV4X2Zsb2F0IFwieFwiIGluXG4gICAgaWYgd2lkdGggPSAwIHx8IFNjYW5uaW5nLmVuZF9vZl9pbnB1dCBpYiB0aGVuIHdpZHRoIGVsc2VcbiAgICAgIGxldCB3aWR0aCA9IG1hdGNoIFNjYW5uaW5nLnBlZWtfY2hhciBpYiB3aXRoXG4gICAgICAgIHwgJy4nIHwgJ3AnIHwgJ1AnIC0+IHdpZHRoXG4gICAgICAgIHwgXyAtPiBzY2FuX2hleGFkZWNpbWFsX2ludCB3aWR0aCBpYiBpblxuICAgICAgaWYgd2lkdGggPSAwIHx8IFNjYW5uaW5nLmVuZF9vZl9pbnB1dCBpYiB0aGVuIHdpZHRoIGVsc2VcbiAgICAgICAgbGV0IHdpZHRoID0gbWF0Y2ggU2Nhbm5pbmcucGVla19jaGFyIGliIHdpdGhcbiAgICAgICAgICB8ICcuJyBhcyBjIC0+IChcbiAgICAgICAgICAgIGxldCB3aWR0aCA9IFNjYW5uaW5nLnN0b3JlX2NoYXIgd2lkdGggaWIgYyBpblxuICAgICAgICAgICAgaWYgd2lkdGggPSAwIHx8IFNjYW5uaW5nLmVuZF9vZl9pbnB1dCBpYiB0aGVuIHdpZHRoIGVsc2VcbiAgICAgICAgICAgICAgbWF0Y2ggU2Nhbm5pbmcucGVla19jaGFyIGliIHdpdGhcbiAgICAgICAgICAgICAgfCAncCcgfCAnUCcgLT4gd2lkdGhcbiAgICAgICAgICAgICAgfCBfIC0+XG4gICAgICAgICAgICAgICAgbGV0IHByZWNpc2lvbiA9IEludC5taW4gd2lkdGggcHJlY2lzaW9uIGluXG4gICAgICAgICAgICAgICAgd2lkdGggLSAocHJlY2lzaW9uIC0gc2Nhbl9oZXhhZGVjaW1hbF9pbnQgcHJlY2lzaW9uIGliKVxuICAgICAgICAgIClcbiAgICAgICAgICB8IF8gLT4gd2lkdGggaW5cbiAgICAgICAgaWYgd2lkdGggPSAwIHx8IFNjYW5uaW5nLmVuZF9vZl9pbnB1dCBpYiB0aGVuIHdpZHRoIGVsc2VcbiAgICAgICAgICBtYXRjaCBTY2FubmluZy5wZWVrX2NoYXIgaWIgd2l0aFxuICAgICAgICAgIHwgJ3AnIHwgJ1AnIGFzIGMgLT5cbiAgICAgICAgICAgIGxldCB3aWR0aCA9IFNjYW5uaW5nLnN0b3JlX2NoYXIgd2lkdGggaWIgYyBpblxuICAgICAgICAgICAgaWYgd2lkdGggPSAwIHx8IFNjYW5uaW5nLmVuZF9vZl9pbnB1dCBpYiB0aGVuIGJhZF9oZXhfZmxvYXQgKCk7XG4gICAgICAgICAgICBzY2FuX29wdGlvbmFsbHlfc2lnbmVkX2RlY2ltYWxfaW50IHdpZHRoIGliXG4gICAgICAgICAgfCBfIC0+IHdpZHRoXG4gIClcbiAgfCAnbicgfCAnTicgYXMgYyAtPlxuICAgIGxldCB3aWR0aCA9IFNjYW5uaW5nLnN0b3JlX2NoYXIgd2lkdGggaWIgYyBpblxuICAgIGlmIHdpZHRoID0gMCB8fCBTY2FubmluZy5lbmRfb2ZfaW5wdXQgaWIgdGhlbiBiYWRfaGV4X2Zsb2F0ICgpO1xuICAgIGNoZWNrX2Nhc2VfaW5zZW5zaXRpdmVfc3RyaW5nIHdpZHRoIGliIGJhZF9oZXhfZmxvYXQgXCJhblwiXG4gIHwgJ2knIHwgJ0knIGFzIGMgLT5cbiAgICBsZXQgd2lkdGggPSBTY2FubmluZy5zdG9yZV9jaGFyIHdpZHRoIGliIGMgaW5cbiAgICBpZiB3aWR0aCA9IDAgfHwgU2Nhbm5pbmcuZW5kX29mX2lucHV0IGliIHRoZW4gYmFkX2hleF9mbG9hdCAoKTtcbiAgICBjaGVja19jYXNlX2luc2Vuc2l0aXZlX3N0cmluZyB3aWR0aCBpYiBiYWRfaGV4X2Zsb2F0IFwibmZpbml0eVwiXG4gIHwgXyAtPiBiYWRfaGV4X2Zsb2F0ICgpXG5cblxubGV0IHNjYW5fY2FtbF9mbG9hdF9yZXN0IHdpZHRoIHByZWNpc2lvbiBpYiA9XG4gIGlmIHdpZHRoID0gMCB8fCBTY2FubmluZy5lbmRfb2ZfaW5wdXQgaWIgdGhlbiBiYWRfZmxvYXQgKCk7XG4gIGxldCB3aWR0aCA9IHNjYW5fZGVjaW1hbF9kaWdpdF9zdGFyIHdpZHRoIGliIGluXG4gIGlmIHdpZHRoID0gMCB8fCBTY2FubmluZy5lbmRfb2ZfaW5wdXQgaWIgdGhlbiBiYWRfZmxvYXQgKCk7XG4gIGxldCBjID0gU2Nhbm5pbmcucGVla19jaGFyIGliIGluXG4gIG1hdGNoIGMgd2l0aFxuICB8ICcuJyAtPlxuICAgIGxldCB3aWR0aCA9IFNjYW5uaW5nLnN0b3JlX2NoYXIgd2lkdGggaWIgYyBpblxuICAgICgqIFRoZSBlZmZlY3RpdmUgd2lkdGggYXZhaWxhYmxlIGZvciBzY2FubmluZyB0aGUgZnJhY3Rpb25hbCBwYXJ0IGlzXG4gICAgICAgdGhlIG1pbmltdW0gb2YgZGVjbGFyZWQgcHJlY2lzaW9uIGFuZCB3aWR0aCBsZWZ0LiAqKVxuICAgIGxldCBwcmVjaXNpb24gPSBJbnQubWluIHdpZHRoIHByZWNpc2lvbiBpblxuICAgICgqIEFmdGVyIHNjYW5uaW5nIHRoZSBmcmFjdGlvbmFsIHBhcnQgd2l0aCBbcHJlY2lzaW9uXSBwcm92aXNpb25hbCB3aWR0aCxcbiAgICAgICBbd2lkdGhfcHJlY2lzaW9uXSBpcyBsZWZ0LiAqKVxuICAgIGxldCB3aWR0aF9wcmVjaXNpb24gPSBzY2FuX2ZyYWN0aW9uYWxfcGFydCBwcmVjaXNpb24gaWIgaW5cbiAgICAoKiBIZW5jZSwgc2Nhbm5pbmcgdGhlIGZyYWN0aW9uYWwgcGFydCB0b29rIGV4YWN0bHlcbiAgICAgICBbcHJlY2lzaW9uIC0gd2lkdGhfcHJlY2lzaW9uXSBjaGFycy4gKilcbiAgICBsZXQgZnJhY193aWR0aCA9IHByZWNpc2lvbiAtIHdpZHRoX3ByZWNpc2lvbiBpblxuICAgICgqIEFuZCBuZXcgcHJvdmlzaW9uYWwgd2lkdGggaXMgW3dpZHRoIC0gd2lkdGhfcHJlY2lzaW9uLiAqKVxuICAgIGxldCB3aWR0aCA9IHdpZHRoIC0gZnJhY193aWR0aCBpblxuICAgIHNjYW5fZXhwb25lbnRfcGFydCB3aWR0aCBpYlxuICB8ICdlJyB8ICdFJyAtPlxuICAgIHNjYW5fZXhwb25lbnRfcGFydCB3aWR0aCBpYlxuICB8IF8gLT4gYmFkX2Zsb2F0ICgpXG5cblxubGV0IHNjYW5fY2FtbF9mbG9hdCB3aWR0aCBwcmVjaXNpb24gaWIgPVxuICBpZiB3aWR0aCA9IDAgfHwgU2Nhbm5pbmcuZW5kX29mX2lucHV0IGliIHRoZW4gYmFkX2Zsb2F0ICgpO1xuICBsZXQgd2lkdGggPSBzY2FuX3NpZ24gd2lkdGggaWIgaW5cbiAgaWYgd2lkdGggPSAwIHx8IFNjYW5uaW5nLmVuZF9vZl9pbnB1dCBpYiB0aGVuIGJhZF9mbG9hdCAoKTtcbiAgbWF0Y2ggU2Nhbm5pbmcucGVla19jaGFyIGliIHdpdGhcbiAgfCAnMCcgYXMgYyAtPiAoXG4gICAgbGV0IHdpZHRoID0gU2Nhbm5pbmcuc3RvcmVfY2hhciB3aWR0aCBpYiBjIGluXG4gICAgaWYgd2lkdGggPSAwIHx8IFNjYW5uaW5nLmVuZF9vZl9pbnB1dCBpYiB0aGVuIGJhZF9mbG9hdCAoKTtcbiAgICBtYXRjaCBTY2FubmluZy5wZWVrX2NoYXIgaWIgd2l0aFxuICAgIHwgJ3gnIHwgJ1gnIGFzIGMgLT4gKFxuICAgICAgbGV0IHdpZHRoID0gU2Nhbm5pbmcuc3RvcmVfY2hhciB3aWR0aCBpYiBjIGluXG4gICAgICBpZiB3aWR0aCA9IDAgfHwgU2Nhbm5pbmcuZW5kX29mX2lucHV0IGliIHRoZW4gYmFkX2Zsb2F0ICgpO1xuICAgICAgbGV0IHdpZHRoID0gc2Nhbl9oZXhhZGVjaW1hbF9pbnQgd2lkdGggaWIgaW5cbiAgICAgIGlmIHdpZHRoID0gMCB8fCBTY2FubmluZy5lbmRfb2ZfaW5wdXQgaWIgdGhlbiBiYWRfZmxvYXQgKCk7XG4gICAgICBsZXQgd2lkdGggPSBtYXRjaCBTY2FubmluZy5wZWVrX2NoYXIgaWIgd2l0aFxuICAgICAgICB8ICcuJyBhcyBjIC0+IChcbiAgICAgICAgICBsZXQgd2lkdGggPSBTY2FubmluZy5zdG9yZV9jaGFyIHdpZHRoIGliIGMgaW5cbiAgICAgICAgICBpZiB3aWR0aCA9IDAgfHwgU2Nhbm5pbmcuZW5kX29mX2lucHV0IGliIHRoZW4gd2lkdGggZWxzZVxuICAgICAgICAgICAgbWF0Y2ggU2Nhbm5pbmcucGVla19jaGFyIGliIHdpdGhcbiAgICAgICAgICAgIHwgJ3AnIHwgJ1AnIC0+IHdpZHRoXG4gICAgICAgICAgICB8IF8gLT5cbiAgICAgICAgICAgICAgbGV0IHByZWNpc2lvbiA9IEludC5taW4gd2lkdGggcHJlY2lzaW9uIGluXG4gICAgICAgICAgICAgIHdpZHRoIC0gKHByZWNpc2lvbiAtIHNjYW5faGV4YWRlY2ltYWxfaW50IHByZWNpc2lvbiBpYilcbiAgICAgICAgKVxuICAgICAgICB8ICdwJyB8ICdQJyAtPiB3aWR0aFxuICAgICAgICB8IF8gLT4gYmFkX2Zsb2F0ICgpIGluXG4gICAgICBpZiB3aWR0aCA9IDAgfHwgU2Nhbm5pbmcuZW5kX29mX2lucHV0IGliIHRoZW4gd2lkdGggZWxzZVxuICAgICAgICBtYXRjaCBTY2FubmluZy5wZWVrX2NoYXIgaWIgd2l0aFxuICAgICAgICB8ICdwJyB8ICdQJyBhcyBjIC0+XG4gICAgICAgICAgbGV0IHdpZHRoID0gU2Nhbm5pbmcuc3RvcmVfY2hhciB3aWR0aCBpYiBjIGluXG4gICAgICAgICAgaWYgd2lkdGggPSAwIHx8IFNjYW5uaW5nLmVuZF9vZl9pbnB1dCBpYiB0aGVuIGJhZF9oZXhfZmxvYXQgKCk7XG4gICAgICAgICAgc2Nhbl9vcHRpb25hbGx5X3NpZ25lZF9kZWNpbWFsX2ludCB3aWR0aCBpYlxuICAgICAgICB8IF8gLT4gd2lkdGhcbiAgICApXG4gICAgfCBfIC0+XG4gICAgICBzY2FuX2NhbWxfZmxvYXRfcmVzdCB3aWR0aCBwcmVjaXNpb24gaWJcbiAgKVxuICB8ICcxJyAuLiAnOScgYXMgYyAtPlxuICAgIGxldCB3aWR0aCA9IFNjYW5uaW5nLnN0b3JlX2NoYXIgd2lkdGggaWIgYyBpblxuICAgIGlmIHdpZHRoID0gMCB8fCBTY2FubmluZy5lbmRfb2ZfaW5wdXQgaWIgdGhlbiBiYWRfZmxvYXQgKCk7XG4gICAgc2Nhbl9jYW1sX2Zsb2F0X3Jlc3Qgd2lkdGggcHJlY2lzaW9uIGliXG4oKiBTcGVjaWFsIGNhc2Ugb2YgbmFuIGFuZCBpbmZpbml0eTpcbiAgfCAnaScgLT5cbiAgfCAnbicgLT5cbiopXG4gIHwgXyAtPiBiYWRfZmxvYXQgKClcblxuXG4oKiBTY2FuIGEgcmVndWxhciBzdHJpbmc6XG4gICBzdG9wcyB3aGVuIGVuY291bnRlcmluZyBhIHNwYWNlLCBpZiBubyBzY2FubmluZyBpbmRpY2F0aW9uIGhhcyBiZWVuIGdpdmVuO1xuICAgb3RoZXJ3aXNlLCBzdG9wcyB3aGVuIGVuY291bnRlcmluZyB0aGUgY2hhcmFjdGVycyBpbiB0aGUgc2Nhbm5pbmdcbiAgIGluZGljYXRpb24gW3N0cF0uXG4gICBJdCBhbHNvIHN0b3BzIGF0IGVuZCBvZiBmaWxlIG9yIHdoZW4gdGhlIG1heGltdW0gbnVtYmVyIG9mIGNoYXJhY3RlcnMgaGFzXG4gICBiZWVuIHJlYWQuICopXG5sZXQgc2Nhbl9zdHJpbmcgc3RwIHdpZHRoIGliID1cbiAgbGV0IHJlYyBsb29wIHdpZHRoID1cbiAgICBpZiB3aWR0aCA9IDAgdGhlbiB3aWR0aCBlbHNlXG4gICAgbGV0IGMgPSBTY2FubmluZy5wZWVrX2NoYXIgaWIgaW5cbiAgICBpZiBTY2FubmluZy5lb2YgaWIgdGhlbiB3aWR0aCBlbHNlXG4gICAgICBtYXRjaCBzdHAgd2l0aFxuICAgICAgfCBTb21lIGMnIHdoZW4gYyA9IGMnIC0+IFNjYW5uaW5nLnNraXBfY2hhciB3aWR0aCBpYlxuICAgICAgfCBTb21lIF8gLT4gbG9vcCAoU2Nhbm5pbmcuc3RvcmVfY2hhciB3aWR0aCBpYiBjKVxuICAgICAgfCBOb25lIC0+XG4gICAgICAgIG1hdGNoIGMgd2l0aFxuICAgICAgICB8ICcgJyB8ICdcXHQnIHwgJ1xcbicgfCAnXFxyJyAtPiB3aWR0aFxuICAgICAgICB8IF8gLT4gbG9vcCAoU2Nhbm5pbmcuc3RvcmVfY2hhciB3aWR0aCBpYiBjKSBpblxuICBsb29wIHdpZHRoXG5cblxuKCogU2NhbiBhIGNoYXI6IHBlZWsgc3RyaWN0bHkgb25lIGNoYXJhY3RlciBpbiB0aGUgaW5wdXQsIHdoYXRzb2V2ZXIuICopXG5sZXQgc2Nhbl9jaGFyIHdpZHRoIGliID1cbiAgKCogVGhlIGNhc2Ugd2lkdGggPSAwIGNvdWxkIG5vdCBoYXBwZW4gaGVyZSwgc2luY2UgaXQgaXMgdGVzdGVkIGJlZm9yZVxuICAgICBjYWxsaW5nIHNjYW5fY2hhciwgaW4gdGhlIG1haW4gc2Nhbm5pbmcgZnVuY3Rpb24uXG4gICAgaWYgd2lkdGggPSAwIHRoZW4gYmFkX3Rva2VuX2xlbmd0aCBcImEgY2hhcmFjdGVyXCIgZWxzZSAqKVxuICBTY2FubmluZy5zdG9yZV9jaGFyIHdpZHRoIGliIChTY2FubmluZy5jaGVja2VkX3BlZWtfY2hhciBpYilcblxuXG5sZXQgY2hhcl9mb3JfYmFja3NsYXNoID0gZnVuY3Rpb25cbiAgfCAnbicgLT4gJ1xcMDEwJ1xuICB8ICdyJyAtPiAnXFwwMTMnXG4gIHwgJ2InIC0+ICdcXDAwOCdcbiAgfCAndCcgLT4gJ1xcMDA5J1xuICB8IGMgLT4gY1xuXG5cbigqIFRoZSBpbnRlZ2VyIHZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGZhY2lhbCB2YWx1ZSBvZiBhIHZhbGlkXG4gICBkZWNpbWFsIGRpZ2l0IGNoYXJhY3Rlci4gKilcbmxldCBkZWNpbWFsX3ZhbHVlX29mX2NoYXIgYyA9IGludF9vZl9jaGFyIGMgLSBpbnRfb2ZfY2hhciAnMCdcblxubGV0IGNoYXJfZm9yX2RlY2ltYWxfY29kZSBjMCBjMSBjMiA9XG4gIGxldCBjID1cbiAgICAxMDAgKiBkZWNpbWFsX3ZhbHVlX29mX2NoYXIgYzAgK1xuICAgICAxMCAqIGRlY2ltYWxfdmFsdWVfb2ZfY2hhciBjMSArXG4gICAgICAgICAgZGVjaW1hbF92YWx1ZV9vZl9jaGFyIGMyIGluXG4gIGlmIGMgPCAwIHx8IGMgPiAyNTUgdGhlblxuICAgIGJhZF9pbnB1dFxuICAgICAgKFByaW50Zi5zcHJpbnRmXG4gICAgICAgICBcImJhZCBjaGFyYWN0ZXIgZGVjaW1hbCBlbmNvZGluZyBcXFxcJWMlYyVjXCIgYzAgYzEgYzIpIGVsc2VcbiAgY2hhcl9vZl9pbnQgY1xuXG5cbigqIFRoZSBpbnRlZ2VyIHZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGZhY2lhbCB2YWx1ZSBvZiBhIHZhbGlkXG4gICBoZXhhZGVjaW1hbCBkaWdpdCBjaGFyYWN0ZXIuICopXG5sZXQgaGV4YWRlY2ltYWxfdmFsdWVfb2ZfY2hhciBjID1cbiAgbGV0IGQgPSBpbnRfb2ZfY2hhciBjIGluXG4gICgqIENvdWxkIGFsc28gYmU6XG4gICAgaWYgZCA8PSBpbnRfb2ZfY2hhciAnOScgdGhlbiBkIC0gaW50X29mX2NoYXIgJzAnIGVsc2VcbiAgICBpZiBkIDw9IGludF9vZl9jaGFyICdGJyB0aGVuIDEwICsgZCAtIGludF9vZl9jaGFyICdBJyBlbHNlXG4gICAgaWYgZCA8PSBpbnRfb2ZfY2hhciAnZicgdGhlbiAxMCArIGQgLSBpbnRfb2ZfY2hhciAnYScgZWxzZSBhc3NlcnQgZmFsc2VcbiAgKilcbiAgaWYgZCA+PSBpbnRfb2ZfY2hhciAnYScgdGhlblxuICAgIGQgLSA4NyAoKiAxMCArIGludF9vZl9jaGFyIGMgLSBpbnRfb2ZfY2hhciAnYScgKikgZWxzZVxuICBpZiBkID49IGludF9vZl9jaGFyICdBJyB0aGVuXG4gICAgZCAtIDU1ICAoKiAxMCArIGludF9vZl9jaGFyIGMgLSBpbnRfb2ZfY2hhciAnQScgKikgZWxzZVxuICAgIGQgLSBpbnRfb2ZfY2hhciAnMCdcblxuXG5sZXQgY2hhcl9mb3JfaGV4YWRlY2ltYWxfY29kZSBjMSBjMiA9XG4gIGxldCBjID1cbiAgICAxNiAqIGhleGFkZWNpbWFsX3ZhbHVlX29mX2NoYXIgYzEgK1xuICAgICAgICAgaGV4YWRlY2ltYWxfdmFsdWVfb2ZfY2hhciBjMiBpblxuICBpZiBjIDwgMCB8fCBjID4gMjU1IHRoZW5cbiAgICBiYWRfaW5wdXRcbiAgICAgIChQcmludGYuc3ByaW50ZiBcImJhZCBjaGFyYWN0ZXIgaGV4YWRlY2ltYWwgZW5jb2RpbmcgXFxcXCVjJWNcIiBjMSBjMikgZWxzZVxuICBjaGFyX29mX2ludCBjXG5cblxuKCogQ2FsbGVkIGluIHBhcnRpY3VsYXIgd2hlbiBlbmNvdW50ZXJpbmcgJ1xcXFwnIGFzIHN0YXJ0ZXIgb2YgYSBjaGFyLlxuICAgU3RvcHMgYmVmb3JlIHRoZSBjb3JyZXNwb25kaW5nICdcXCcnLiAqKVxubGV0IGNoZWNrX25leHRfY2hhciBtZXNzYWdlIHdpZHRoIGliID1cbiAgaWYgd2lkdGggPSAwIHRoZW4gYmFkX3Rva2VuX2xlbmd0aCBtZXNzYWdlIGVsc2VcbiAgbGV0IGMgPSBTY2FubmluZy5wZWVrX2NoYXIgaWIgaW5cbiAgaWYgU2Nhbm5pbmcuZW9mIGliIHRoZW4gYmFkX2VuZF9vZl9pbnB1dCBtZXNzYWdlIGVsc2VcbiAgY1xuXG5cbmxldCBjaGVja19uZXh0X2NoYXJfZm9yX2NoYXIgPSBjaGVja19uZXh0X2NoYXIgXCJhIENoYXJcIlxubGV0IGNoZWNrX25leHRfY2hhcl9mb3Jfc3RyaW5nID0gY2hlY2tfbmV4dF9jaGFyIFwiYSBTdHJpbmdcIlxuXG5sZXQgc2Nhbl9iYWNrc2xhc2hfY2hhciB3aWR0aCBpYiA9XG4gIG1hdGNoIGNoZWNrX25leHRfY2hhcl9mb3JfY2hhciB3aWR0aCBpYiB3aXRoXG4gIHwgJ1xcXFwnIHwgJ1xcJycgfCAnXFxcIicgfCAnbicgfCAndCcgfCAnYicgfCAncicgYXMgYyAtPlxuICAgIFNjYW5uaW5nLnN0b3JlX2NoYXIgd2lkdGggaWIgKGNoYXJfZm9yX2JhY2tzbGFzaCBjKVxuICB8ICcwJyAuLiAnOScgYXMgYyAtPlxuICAgIGxldCBnZXRfZGlnaXQgKCkgPVxuICAgICAgbGV0IGMgPSBTY2FubmluZy5uZXh0X2NoYXIgaWIgaW5cbiAgICAgIG1hdGNoIGMgd2l0aFxuICAgICAgfCAnMCcgLi4gJzknIGFzIGMgLT4gY1xuICAgICAgfCBjIC0+IGJhZF9pbnB1dF9lc2NhcGUgYyBpblxuICAgIGxldCBjMCA9IGMgaW5cbiAgICBsZXQgYzEgPSBnZXRfZGlnaXQgKCkgaW5cbiAgICBsZXQgYzIgPSBnZXRfZGlnaXQgKCkgaW5cbiAgICBTY2FubmluZy5zdG9yZV9jaGFyICh3aWR0aCAtIDIpIGliIChjaGFyX2Zvcl9kZWNpbWFsX2NvZGUgYzAgYzEgYzIpXG4gIHwgJ3gnIC0+XG4gICAgbGV0IGdldF9kaWdpdCAoKSA9XG4gICAgICBsZXQgYyA9IFNjYW5uaW5nLm5leHRfY2hhciBpYiBpblxuICAgICAgbWF0Y2ggYyB3aXRoXG4gICAgICB8ICcwJyAuLiAnOScgfCAnQScgLi4gJ0YnIHwgJ2EnIC4uICdmJyBhcyBjIC0+IGNcbiAgICAgIHwgYyAtPiBiYWRfaW5wdXRfZXNjYXBlIGMgaW5cbiAgICBsZXQgYzEgPSBnZXRfZGlnaXQgKCkgaW5cbiAgICBsZXQgYzIgPSBnZXRfZGlnaXQgKCkgaW5cbiAgICBTY2FubmluZy5zdG9yZV9jaGFyICh3aWR0aCAtIDIpIGliIChjaGFyX2Zvcl9oZXhhZGVjaW1hbF9jb2RlIGMxIGMyKVxuICB8IGMgLT5cbiAgICBiYWRfaW5wdXRfZXNjYXBlIGNcblxuXG4oKiBTY2FuIGEgY2hhcmFjdGVyIChhbiBPQ2FtbCB0b2tlbikuICopXG5sZXQgc2Nhbl9jYW1sX2NoYXIgd2lkdGggaWIgPVxuXG4gIGxldCByZWMgZmluZF9zdGFydCB3aWR0aCA9XG4gICAgbWF0Y2ggU2Nhbm5pbmcuY2hlY2tlZF9wZWVrX2NoYXIgaWIgd2l0aFxuICAgIHwgJ1xcJycgLT4gZmluZF9jaGFyIChTY2FubmluZy5pZ25vcmVfY2hhciB3aWR0aCBpYilcbiAgICB8IGMgLT4gY2hhcmFjdGVyX21pc21hdGNoICdcXCcnIGNcblxuICBhbmQgZmluZF9jaGFyIHdpZHRoID1cbiAgICBtYXRjaCBjaGVja19uZXh0X2NoYXJfZm9yX2NoYXIgd2lkdGggaWIgd2l0aFxuICAgIHwgJ1xcXFwnIC0+XG4gICAgICBmaW5kX3N0b3AgKHNjYW5fYmFja3NsYXNoX2NoYXIgKFNjYW5uaW5nLmlnbm9yZV9jaGFyIHdpZHRoIGliKSBpYilcbiAgICB8IGMgLT5cbiAgICAgIGZpbmRfc3RvcCAoU2Nhbm5pbmcuc3RvcmVfY2hhciB3aWR0aCBpYiBjKVxuXG4gIGFuZCBmaW5kX3N0b3Agd2lkdGggPVxuICAgIG1hdGNoIGNoZWNrX25leHRfY2hhcl9mb3JfY2hhciB3aWR0aCBpYiB3aXRoXG4gICAgfCAnXFwnJyAtPiBTY2FubmluZy5pZ25vcmVfY2hhciB3aWR0aCBpYlxuICAgIHwgYyAtPiBjaGFyYWN0ZXJfbWlzbWF0Y2ggJ1xcJycgYyBpblxuXG4gIGZpbmRfc3RhcnQgd2lkdGhcblxuXG4oKiBTY2FuIGEgZGVsaW1pdGVkIHN0cmluZyAoYW4gT0NhbWwgdG9rZW4pLiAqKVxubGV0IHNjYW5fY2FtbF9zdHJpbmcgd2lkdGggaWIgPVxuXG4gIGxldCByZWMgZmluZF9zdGFydCB3aWR0aCA9XG4gICAgbWF0Y2ggU2Nhbm5pbmcuY2hlY2tlZF9wZWVrX2NoYXIgaWIgd2l0aFxuICAgIHwgJ1xcXCInIC0+IGZpbmRfc3RvcCAoU2Nhbm5pbmcuaWdub3JlX2NoYXIgd2lkdGggaWIpXG4gICAgfCBjIC0+IGNoYXJhY3Rlcl9taXNtYXRjaCAnXFxcIicgY1xuXG4gIGFuZCBmaW5kX3N0b3Agd2lkdGggPVxuICAgIG1hdGNoIGNoZWNrX25leHRfY2hhcl9mb3Jfc3RyaW5nIHdpZHRoIGliIHdpdGhcbiAgICB8ICdcXFwiJyAtPiBTY2FubmluZy5pZ25vcmVfY2hhciB3aWR0aCBpYlxuICAgIHwgJ1xcXFwnIC0+IHNjYW5fYmFja3NsYXNoIChTY2FubmluZy5pZ25vcmVfY2hhciB3aWR0aCBpYilcbiAgICB8IGMgLT4gZmluZF9zdG9wIChTY2FubmluZy5zdG9yZV9jaGFyIHdpZHRoIGliIGMpXG5cbiAgYW5kIHNjYW5fYmFja3NsYXNoIHdpZHRoID1cbiAgICBtYXRjaCBjaGVja19uZXh0X2NoYXJfZm9yX3N0cmluZyB3aWR0aCBpYiB3aXRoXG4gICAgfCAnXFxyJyAtPiBza2lwX25ld2xpbmUgKFNjYW5uaW5nLmlnbm9yZV9jaGFyIHdpZHRoIGliKVxuICAgIHwgJ1xcbicgLT4gc2tpcF9zcGFjZXMgKFNjYW5uaW5nLmlnbm9yZV9jaGFyIHdpZHRoIGliKVxuICAgIHwgXyAtPiBmaW5kX3N0b3AgKHNjYW5fYmFja3NsYXNoX2NoYXIgd2lkdGggaWIpXG5cbiAgYW5kIHNraXBfbmV3bGluZSB3aWR0aCA9XG4gICAgbWF0Y2ggY2hlY2tfbmV4dF9jaGFyX2Zvcl9zdHJpbmcgd2lkdGggaWIgd2l0aFxuICAgIHwgJ1xcbicgLT4gc2tpcF9zcGFjZXMgKFNjYW5uaW5nLmlnbm9yZV9jaGFyIHdpZHRoIGliKVxuICAgIHwgXyAtPiBmaW5kX3N0b3AgKFNjYW5uaW5nLnN0b3JlX2NoYXIgd2lkdGggaWIgJ1xccicpXG5cbiAgYW5kIHNraXBfc3BhY2VzIHdpZHRoID1cbiAgICBtYXRjaCBjaGVja19uZXh0X2NoYXJfZm9yX3N0cmluZyB3aWR0aCBpYiB3aXRoXG4gICAgfCAnICcgLT4gc2tpcF9zcGFjZXMgKFNjYW5uaW5nLmlnbm9yZV9jaGFyIHdpZHRoIGliKVxuICAgIHwgXyAtPiBmaW5kX3N0b3Agd2lkdGggaW5cblxuICBmaW5kX3N0YXJ0IHdpZHRoXG5cblxuKCogU2NhbiBhIGJvb2xlYW4gKGFuIE9DYW1sIHRva2VuKS4gKilcbmxldCBzY2FuX2Jvb2wgaWIgPVxuICBsZXQgYyA9IFNjYW5uaW5nLmNoZWNrZWRfcGVla19jaGFyIGliIGluXG4gIGxldCBtID1cbiAgICBtYXRjaCBjIHdpdGhcbiAgICB8ICd0JyAtPiA0XG4gICAgfCAnZicgLT4gNVxuICAgIHwgYyAtPlxuICAgICAgYmFkX2lucHV0XG4gICAgICAgIChQcmludGYuc3ByaW50ZiBcInRoZSBjaGFyYWN0ZXIgJUMgY2Fubm90IHN0YXJ0IGEgYm9vbGVhblwiIGMpIGluXG4gIHNjYW5fc3RyaW5nIE5vbmUgbSBpYlxuXG5cbigqIFNjYW4gYSBzdHJpbmcgY29udGFpbmluZyBlbGVtZW50cyBpbiBjaGFyX3NldCBhbmQgdGVybWluYXRlZCBieSBzY2FuX2luZGljXG4gICBpZiBwcm92aWRlZC4gKilcbmxldCBzY2FuX2NoYXJzX2luX2NoYXJfc2V0IGNoYXJfc2V0IHNjYW5faW5kaWMgd2lkdGggaWIgPVxuICBsZXQgcmVjIHNjYW5fY2hhcnMgaSBzdHAgPVxuICAgIGxldCBjID0gU2Nhbm5pbmcucGVla19jaGFyIGliIGluXG4gICAgaWYgaSA+IDAgJiYgbm90IChTY2FubmluZy5lb2YgaWIpICYmXG4gICAgICAgaXNfaW5fY2hhcl9zZXQgY2hhcl9zZXQgYyAmJlxuICAgICAgIGludF9vZl9jaGFyIGMgPD4gc3RwIHRoZW5cbiAgICAgIGxldCBfID0gU2Nhbm5pbmcuc3RvcmVfY2hhciBtYXhfaW50IGliIGMgaW5cbiAgICAgIHNjYW5fY2hhcnMgKGkgLSAxKSBzdHAgaW5cbiAgbWF0Y2ggc2Nhbl9pbmRpYyB3aXRoXG4gIHwgTm9uZSAtPiBzY2FuX2NoYXJzIHdpZHRoICgtMSk7XG4gIHwgU29tZSBjIC0+XG4gICAgc2Nhbl9jaGFycyB3aWR0aCAoaW50X29mX2NoYXIgYyk7XG4gICAgaWYgbm90IChTY2FubmluZy5lb2YgaWIpIHRoZW5cbiAgICAgIGxldCBjaSA9IFNjYW5uaW5nLnBlZWtfY2hhciBpYiBpblxuICAgICAgaWYgYyA9IGNpXG4gICAgICB0aGVuIFNjYW5uaW5nLmludmFsaWRhdGVfY3VycmVudF9jaGFyIGliXG4gICAgICBlbHNlIGNoYXJhY3Rlcl9taXNtYXRjaCBjIGNpXG5cblxuKCogVGhlIGdsb2JhbCBlcnJvciByZXBvcnQgZnVuY3Rpb24gZm9yIFtTY2FuZl0uICopXG5sZXQgc2NhbmZfYmFkX2lucHV0IGliID0gZnVuY3Rpb25cbiAgfCBTY2FuX2ZhaWx1cmUgcyB8IEZhaWx1cmUgcyAtPlxuICAgIGxldCBpID0gU2Nhbm5pbmcuY2hhcl9jb3VudCBpYiBpblxuICAgIGJhZF9pbnB1dCAoUHJpbnRmLnNwcmludGYgXCJzY2FuZjogYmFkIGlucHV0IGF0IGNoYXIgbnVtYmVyICVpOiAlc1wiIGkgcylcbiAgfCB4IC0+IHJhaXNlIHhcblxuXG4oKiBHZXQgdGhlIGNvbnRlbnQgb2YgYSBjb3VudGVyIGZyb20gYW4gaW5wdXQgYnVmZmVyLiAqKVxubGV0IGdldF9jb3VudGVyIGliIGNvdW50ZXIgPVxuICBtYXRjaCBjb3VudGVyIHdpdGhcbiAgfCBMaW5lX2NvdW50ZXIgLT4gU2Nhbm5pbmcubGluZV9jb3VudCBpYlxuICB8IENoYXJfY291bnRlciAtPiBTY2FubmluZy5jaGFyX2NvdW50IGliXG4gIHwgVG9rZW5fY291bnRlciAtPiBTY2FubmluZy50b2tlbl9jb3VudCBpYlxuXG5cbigqIENvbXB1dGUgdGhlIHdpZHRoIG9mIGEgcGFkZGluZyBvcHRpb24gKHNlZSBcIiU0MntcIiBhbmQgXCIlMTIzKFwiKS4gKilcbmxldCB3aWR0aF9vZl9wYWRfb3B0IHBhZF9vcHQgPSBtYXRjaCBwYWRfb3B0IHdpdGhcbiAgfCBOb25lIC0+IG1heF9pbnRcbiAgfCBTb21lIHdpZHRoIC0+IHdpZHRoXG5cblxubGV0IHN0b3BwZXJfb2ZfZm9ybWF0dGluZ19saXQgZm10aW5nID1cbiAgaWYgZm10aW5nID0gRXNjYXBlZF9wZXJjZW50IHRoZW4gJyUnLCBcIlwiIGVsc2VcbiAgICBsZXQgc3RyID0gc3RyaW5nX29mX2Zvcm1hdHRpbmdfbGl0IGZtdGluZyBpblxuICAgIGxldCBzdHAgPSBzdHIuWzFdIGluXG4gICAgbGV0IHN1Yl9zdHIgPSBTdHJpbmcuc3ViIHN0ciAyIChTdHJpbmcubGVuZ3RoIHN0ciAtIDIpIGluXG4gICAgc3RwLCBzdWJfc3RyXG5cblxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICgqIFJlYWRlciBtYW5hZ2VtZW50ICopXG5cbigqIEEgY2FsbCB0byB0YWtlX2Zvcm1hdF9yZWFkZXJzIG9uIGEgZm9ybWF0IGlzIGV2YWx1YXRlZCBpbnRvIGZ1bmN0aW9uc1xuICAgdGFraW5nIHJlYWRlcnMgYXMgYXJndW1lbnRzIGFuZCBhZ2dyZWdhdGUgdGhlbSBpbnRvIGFuIGhldGVyb2dlbmVvdXMgbGlzdCAqKVxuKCogV2hlbiBhbGwgcmVhZGVycyBhcmUgdGFrZW4sIGZpbmFsbHkgcGFzcyB0aGUgbGlzdCBvZiB0aGUgcmVhZGVycyB0byB0aGVcbiAgIGNvbnRpbnVhdGlvbiBrLiAqKVxubGV0IHJlYyB0YWtlX2Zvcm1hdF9yZWFkZXJzIDogdHlwZSBhIGMgZCBlIGYgLlxuICAgICgoZCwgZSkgaGV0ZXJfbGlzdCAtPiBlKSAtPiAoYSwgU2Nhbm5pbmcuaW5fY2hhbm5lbCwgYywgZCwgZSwgZikgZm10IC0+XG4gICAgZCA9XG5mdW4gayBmbXQgLT4gbWF0Y2ggZm10IHdpdGhcbiAgfCBSZWFkZXIgZm10X3Jlc3QgLT5cbiAgICBmdW4gcmVhZGVyIC0+XG4gICAgICBsZXQgbmV3X2sgcmVhZGVyc19yZXN0ID0gayAoQ29ucyAocmVhZGVyLCByZWFkZXJzX3Jlc3QpKSBpblxuICAgICAgdGFrZV9mb3JtYXRfcmVhZGVycyBuZXdfayBmbXRfcmVzdFxuICB8IENoYXIgcmVzdCAgICAgICAgICAgICAgICAgICAgICAgIC0+IHRha2VfZm9ybWF0X3JlYWRlcnMgayByZXN0XG4gIHwgQ2FtbF9jaGFyIHJlc3QgICAgICAgICAgICAgICAgICAgLT4gdGFrZV9mb3JtYXRfcmVhZGVycyBrIHJlc3RcbiAgfCBTdHJpbmcgKF8sIHJlc3QpICAgICAgICAgICAgICAgICAtPiB0YWtlX2Zvcm1hdF9yZWFkZXJzIGsgcmVzdFxuICB8IENhbWxfc3RyaW5nIChfLCByZXN0KSAgICAgICAgICAgIC0+IHRha2VfZm9ybWF0X3JlYWRlcnMgayByZXN0XG4gIHwgSW50IChfLCBfLCBfLCByZXN0KSAgICAgICAgICAgICAgLT4gdGFrZV9mb3JtYXRfcmVhZGVycyBrIHJlc3RcbiAgfCBJbnQzMiAoXywgXywgXywgcmVzdCkgICAgICAgICAgICAtPiB0YWtlX2Zvcm1hdF9yZWFkZXJzIGsgcmVzdFxuICB8IE5hdGl2ZWludCAoXywgXywgXywgcmVzdCkgICAgICAgIC0+IHRha2VfZm9ybWF0X3JlYWRlcnMgayByZXN0XG4gIHwgSW50NjQgKF8sIF8sIF8sIHJlc3QpICAgICAgICAgICAgLT4gdGFrZV9mb3JtYXRfcmVhZGVycyBrIHJlc3RcbiAgfCBGbG9hdCAoXywgXywgXywgcmVzdCkgICAgICAgICAgICAtPiB0YWtlX2Zvcm1hdF9yZWFkZXJzIGsgcmVzdFxuICB8IEJvb2wgKF8sIHJlc3QpICAgICAgICAgICAgICAgICAgIC0+IHRha2VfZm9ybWF0X3JlYWRlcnMgayByZXN0XG4gIHwgQWxwaGEgcmVzdCAgICAgICAgICAgICAgICAgICAgICAgLT4gdGFrZV9mb3JtYXRfcmVhZGVycyBrIHJlc3RcbiAgfCBUaGV0YSByZXN0ICAgICAgICAgICAgICAgICAgICAgICAtPiB0YWtlX2Zvcm1hdF9yZWFkZXJzIGsgcmVzdFxuICB8IEZsdXNoIHJlc3QgICAgICAgICAgICAgICAgICAgICAgIC0+IHRha2VfZm9ybWF0X3JlYWRlcnMgayByZXN0XG4gIHwgU3RyaW5nX2xpdGVyYWwgKF8sIHJlc3QpICAgICAgICAgLT4gdGFrZV9mb3JtYXRfcmVhZGVycyBrIHJlc3RcbiAgfCBDaGFyX2xpdGVyYWwgKF8sIHJlc3QpICAgICAgICAgICAtPiB0YWtlX2Zvcm1hdF9yZWFkZXJzIGsgcmVzdFxuICB8IEN1c3RvbSAoXywgXywgcmVzdCkgICAgICAgICAgICAgIC0+IHRha2VfZm9ybWF0X3JlYWRlcnMgayByZXN0XG5cbiAgfCBTY2FuX2NoYXJfc2V0IChfLCBfLCByZXN0KSAgICAgICAtPiB0YWtlX2Zvcm1hdF9yZWFkZXJzIGsgcmVzdFxuICB8IFNjYW5fZ2V0X2NvdW50ZXIgKF8sIHJlc3QpICAgICAgIC0+IHRha2VfZm9ybWF0X3JlYWRlcnMgayByZXN0XG4gIHwgU2Nhbl9uZXh0X2NoYXIgcmVzdCAgICAgICAgICAgICAgLT4gdGFrZV9mb3JtYXRfcmVhZGVycyBrIHJlc3RcblxuICB8IEZvcm1hdHRpbmdfbGl0IChfLCByZXN0KSAgICAgICAgIC0+IHRha2VfZm9ybWF0X3JlYWRlcnMgayByZXN0XG4gIHwgRm9ybWF0dGluZ19nZW4gKE9wZW5fdGFnIChGb3JtYXQgKGZtdCwgXykpLCByZXN0KSAtPlxuICAgICAgdGFrZV9mb3JtYXRfcmVhZGVycyBrIChjb25jYXRfZm10IGZtdCByZXN0KVxuICB8IEZvcm1hdHRpbmdfZ2VuIChPcGVuX2JveCAoRm9ybWF0IChmbXQsIF8pKSwgcmVzdCkgLT5cbiAgICAgIHRha2VfZm9ybWF0X3JlYWRlcnMgayAoY29uY2F0X2ZtdCBmbXQgcmVzdClcblxuICB8IEZvcm1hdF9hcmcgKF8sIF8sIHJlc3QpICAgICAgICAgIC0+IHRha2VfZm9ybWF0X3JlYWRlcnMgayByZXN0XG4gIHwgRm9ybWF0X3N1YnN0IChfLCBmbXR0eSwgcmVzdCkgICAgLT5cbiAgICAgdGFrZV9mbXR0eV9mb3JtYXRfcmVhZGVycyBrIChlcmFzZV9yZWwgKHN5bW0gZm10dHkpKSByZXN0XG4gIHwgSWdub3JlZF9wYXJhbSAoaWduLCByZXN0KSAgICAgICAgLT4gdGFrZV9pZ25vcmVkX2Zvcm1hdF9yZWFkZXJzIGsgaWduIHJlc3RcblxuICB8IEVuZF9vZl9mb3JtYXQgICAgICAgICAgICAgICAgICAgIC0+IGsgTmlsXG5cbigqIFRha2UgcmVhZGVycyBhc3NvY2lhdGVkIHRvIGFuIGZtdHR5IGNvbWluZyBmcm9tIGEgRm9ybWF0X3N1YnN0IFwiJSguLi4lKVwiLiAqKVxuYW5kIHRha2VfZm10dHlfZm9ybWF0X3JlYWRlcnMgOiB0eXBlIHggeSBhIGMgZCBlIGYgLlxuICAgICgoZCwgZSkgaGV0ZXJfbGlzdCAtPiBlKSAtPiAoYSwgU2Nhbm5pbmcuaW5fY2hhbm5lbCwgYywgZCwgeCwgeSkgZm10dHkgLT5cbiAgICAgICh5LCBTY2FubmluZy5pbl9jaGFubmVsLCBjLCB4LCBlLCBmKSBmbXQgLT4gZCA9XG5mdW4gayBmbXR0eSBmbXQgLT4gbWF0Y2ggZm10dHkgd2l0aFxuICB8IFJlYWRlcl90eSBmbXRfcmVzdCAtPlxuICAgIGZ1biByZWFkZXIgLT5cbiAgICAgIGxldCBuZXdfayByZWFkZXJzX3Jlc3QgPSBrIChDb25zIChyZWFkZXIsIHJlYWRlcnNfcmVzdCkpIGluXG4gICAgICB0YWtlX2ZtdHR5X2Zvcm1hdF9yZWFkZXJzIG5ld19rIGZtdF9yZXN0IGZtdFxuICB8IElnbm9yZWRfcmVhZGVyX3R5IGZtdF9yZXN0IC0+XG4gICAgZnVuIHJlYWRlciAtPlxuICAgICAgbGV0IG5ld19rIHJlYWRlcnNfcmVzdCA9IGsgKENvbnMgKHJlYWRlciwgcmVhZGVyc19yZXN0KSkgaW5cbiAgICAgIHRha2VfZm10dHlfZm9ybWF0X3JlYWRlcnMgbmV3X2sgZm10X3Jlc3QgZm10XG4gIHwgQ2hhcl90eSByZXN0ICAgICAgICAgICAgICAgIC0+IHRha2VfZm10dHlfZm9ybWF0X3JlYWRlcnMgayByZXN0IGZtdFxuICB8IFN0cmluZ190eSByZXN0ICAgICAgICAgICAgICAtPiB0YWtlX2ZtdHR5X2Zvcm1hdF9yZWFkZXJzIGsgcmVzdCBmbXRcbiAgfCBJbnRfdHkgcmVzdCAgICAgICAgICAgICAgICAgLT4gdGFrZV9mbXR0eV9mb3JtYXRfcmVhZGVycyBrIHJlc3QgZm10XG4gIHwgSW50MzJfdHkgcmVzdCAgICAgICAgICAgICAgIC0+IHRha2VfZm10dHlfZm9ybWF0X3JlYWRlcnMgayByZXN0IGZtdFxuICB8IE5hdGl2ZWludF90eSByZXN0ICAgICAgICAgICAtPiB0YWtlX2ZtdHR5X2Zvcm1hdF9yZWFkZXJzIGsgcmVzdCBmbXRcbiAgfCBJbnQ2NF90eSByZXN0ICAgICAgICAgICAgICAgLT4gdGFrZV9mbXR0eV9mb3JtYXRfcmVhZGVycyBrIHJlc3QgZm10XG4gIHwgRmxvYXRfdHkgcmVzdCAgICAgICAgICAgICAgIC0+IHRha2VfZm10dHlfZm9ybWF0X3JlYWRlcnMgayByZXN0IGZtdFxuICB8IEJvb2xfdHkgcmVzdCAgICAgICAgICAgICAgICAtPiB0YWtlX2ZtdHR5X2Zvcm1hdF9yZWFkZXJzIGsgcmVzdCBmbXRcbiAgfCBBbHBoYV90eSByZXN0ICAgICAgICAgICAgICAgLT4gdGFrZV9mbXR0eV9mb3JtYXRfcmVhZGVycyBrIHJlc3QgZm10XG4gIHwgVGhldGFfdHkgcmVzdCAgICAgICAgICAgICAgIC0+IHRha2VfZm10dHlfZm9ybWF0X3JlYWRlcnMgayByZXN0IGZtdFxuICB8IEFueV90eSByZXN0ICAgICAgICAgICAgICAgICAtPiB0YWtlX2ZtdHR5X2Zvcm1hdF9yZWFkZXJzIGsgcmVzdCBmbXRcbiAgfCBGb3JtYXRfYXJnX3R5IChfLCByZXN0KSAgICAgLT4gdGFrZV9mbXR0eV9mb3JtYXRfcmVhZGVycyBrIHJlc3QgZm10XG4gIHwgRW5kX29mX2ZtdHR5ICAgICAgICAgICAgICAgIC0+IHRha2VfZm9ybWF0X3JlYWRlcnMgayBmbXRcbiAgfCBGb3JtYXRfc3Vic3RfdHkgKHR5MSwgdHkyLCByZXN0KSAtPlxuICAgIGxldCB0eSA9IHRyYW5zIChzeW1tIHR5MSkgdHkyIGluXG4gICAgdGFrZV9mbXR0eV9mb3JtYXRfcmVhZGVycyBrIChjb25jYXRfZm10dHkgdHkgcmVzdCkgZm10XG5cbigqIFRha2UgcmVhZGVycyBhc3NvY2lhdGVkIHRvIGFuIGlnbm9yZWQgcGFyYW1ldGVyLiAqKVxuYW5kIHRha2VfaWdub3JlZF9mb3JtYXRfcmVhZGVycyA6IHR5cGUgeCB5IGEgYyBkIGUgZiAuXG4gICAgKChkLCBlKSBoZXRlcl9saXN0IC0+IGUpIC0+IChhLCBTY2FubmluZy5pbl9jaGFubmVsLCBjLCBkLCB4LCB5KSBpZ25vcmVkIC0+XG4gICAgICAoeSwgU2Nhbm5pbmcuaW5fY2hhbm5lbCwgYywgeCwgZSwgZikgZm10IC0+IGQgPVxuZnVuIGsgaWduIGZtdCAtPiBtYXRjaCBpZ24gd2l0aFxuICB8IElnbm9yZWRfcmVhZGVyIC0+XG4gICAgZnVuIHJlYWRlciAtPlxuICAgICAgbGV0IG5ld19rIHJlYWRlcnNfcmVzdCA9IGsgKENvbnMgKHJlYWRlciwgcmVhZGVyc19yZXN0KSkgaW5cbiAgICAgIHRha2VfZm9ybWF0X3JlYWRlcnMgbmV3X2sgZm10XG4gIHwgSWdub3JlZF9jaGFyICAgICAgICAgICAgICAgICAgICAtPiB0YWtlX2Zvcm1hdF9yZWFkZXJzIGsgZm10XG4gIHwgSWdub3JlZF9jYW1sX2NoYXIgICAgICAgICAgICAgICAtPiB0YWtlX2Zvcm1hdF9yZWFkZXJzIGsgZm10XG4gIHwgSWdub3JlZF9zdHJpbmcgXyAgICAgICAgICAgICAgICAtPiB0YWtlX2Zvcm1hdF9yZWFkZXJzIGsgZm10XG4gIHwgSWdub3JlZF9jYW1sX3N0cmluZyBfICAgICAgICAgICAtPiB0YWtlX2Zvcm1hdF9yZWFkZXJzIGsgZm10XG4gIHwgSWdub3JlZF9pbnQgKF8sIF8pICAgICAgICAgICAgICAtPiB0YWtlX2Zvcm1hdF9yZWFkZXJzIGsgZm10XG4gIHwgSWdub3JlZF9pbnQzMiAoXywgXykgICAgICAgICAgICAtPiB0YWtlX2Zvcm1hdF9yZWFkZXJzIGsgZm10XG4gIHwgSWdub3JlZF9uYXRpdmVpbnQgKF8sIF8pICAgICAgICAtPiB0YWtlX2Zvcm1hdF9yZWFkZXJzIGsgZm10XG4gIHwgSWdub3JlZF9pbnQ2NCAoXywgXykgICAgICAgICAgICAtPiB0YWtlX2Zvcm1hdF9yZWFkZXJzIGsgZm10XG4gIHwgSWdub3JlZF9mbG9hdCAoXywgXykgICAgICAgICAgICAtPiB0YWtlX2Zvcm1hdF9yZWFkZXJzIGsgZm10XG4gIHwgSWdub3JlZF9ib29sIF8gICAgICAgICAgICAgICAgICAtPiB0YWtlX2Zvcm1hdF9yZWFkZXJzIGsgZm10XG4gIHwgSWdub3JlZF9mb3JtYXRfYXJnIF8gICAgICAgICAgICAtPiB0YWtlX2Zvcm1hdF9yZWFkZXJzIGsgZm10XG4gIHwgSWdub3JlZF9mb3JtYXRfc3Vic3QgKF8sIGZtdHR5KSAtPiB0YWtlX2ZtdHR5X2Zvcm1hdF9yZWFkZXJzIGsgZm10dHkgZm10XG4gIHwgSWdub3JlZF9zY2FuX2NoYXJfc2V0IF8gICAgICAgICAtPiB0YWtlX2Zvcm1hdF9yZWFkZXJzIGsgZm10XG4gIHwgSWdub3JlZF9zY2FuX2dldF9jb3VudGVyIF8gICAgICAtPiB0YWtlX2Zvcm1hdF9yZWFkZXJzIGsgZm10XG4gIHwgSWdub3JlZF9zY2FuX25leHRfY2hhciAgICAgICAgICAtPiB0YWtlX2Zvcm1hdF9yZWFkZXJzIGsgZm10XG5cbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4gICAgICAgICAgICAgICAgICAgICAgICAgICgqIEdlbmVyaWMgc2Nhbm5pbmcgKilcblxuKCogTWFrZSBhIGdlbmVyaWMgc2Nhbm5pbmcgZnVuY3Rpb24uICopXG4oKiBTY2FuIGEgc3RyZWFtIGFjY29yZGluZyB0byBhIGZvcm1hdCBhbmQgcmVhZGVycyBvYnRhaW5lZCBieVxuICAgdGFrZV9mb3JtYXRfcmVhZGVycywgYW5kIGFnZ3JlZ2F0ZSBzY2FubmVkIHZhbHVlcyBpbnRvIGFuXG4gICBoZXRlcm9nZW5lb3VzIGxpc3QuICopXG4oKiBSZXR1cm4gdGhlIGhldGVyb2dlbmVvdXMgbGlzdCBvZiBzY2FubmVkIHZhbHVlcy4gKilcbmxldCByZWMgbWFrZV9zY2FuZiA6IHR5cGUgYSBjIGQgZSBmLlxuICAgIFNjYW5uaW5nLmluX2NoYW5uZWwgLT4gKGEsIFNjYW5uaW5nLmluX2NoYW5uZWwsIGMsIGQsIGUsIGYpIGZtdCAtPlxuICAgICAgKGQsIGUpIGhldGVyX2xpc3QgLT4gKGEsIGYpIGhldGVyX2xpc3QgPVxuZnVuIGliIGZtdCByZWFkZXJzIC0+IG1hdGNoIGZtdCB3aXRoXG4gIHwgQ2hhciByZXN0IC0+XG4gICAgbGV0IF8gPSBzY2FuX2NoYXIgMCBpYiBpblxuICAgIGxldCBjID0gdG9rZW5fY2hhciBpYiBpblxuICAgIENvbnMgKGMsIG1ha2Vfc2NhbmYgaWIgcmVzdCByZWFkZXJzKVxuICB8IENhbWxfY2hhciByZXN0IC0+XG4gICAgbGV0IF8gPSBzY2FuX2NhbWxfY2hhciAwIGliIGluXG4gICAgbGV0IGMgPSB0b2tlbl9jaGFyIGliIGluXG4gICAgQ29ucyAoYywgbWFrZV9zY2FuZiBpYiByZXN0IHJlYWRlcnMpXG5cbiAgfCBTdHJpbmcgKHBhZCwgRm9ybWF0dGluZ19saXQgKGZtdGluZ19saXQsIHJlc3QpKSAtPlxuICAgIGxldCBzdHAsIHN0ciA9IHN0b3BwZXJfb2ZfZm9ybWF0dGluZ19saXQgZm10aW5nX2xpdCBpblxuICAgIGxldCBzY2FuIHdpZHRoIF8gaWIgPSBzY2FuX3N0cmluZyAoU29tZSBzdHApIHdpZHRoIGliIGluXG4gICAgbGV0IHN0cl9yZXN0ID0gU3RyaW5nX2xpdGVyYWwgKHN0ciwgcmVzdCkgaW5cbiAgICBwYWRfcHJlY19zY2FuZiBpYiBzdHJfcmVzdCByZWFkZXJzIHBhZCBOb19wcmVjaXNpb24gc2NhbiB0b2tlbl9zdHJpbmdcbiAgfCBTdHJpbmcgKHBhZCwgRm9ybWF0dGluZ19nZW4gKE9wZW5fdGFnIChGb3JtYXQgKGZtdCcsIF8pKSwgcmVzdCkpIC0+XG4gICAgbGV0IHNjYW4gd2lkdGggXyBpYiA9IHNjYW5fc3RyaW5nIChTb21lICd7Jykgd2lkdGggaWIgaW5cbiAgICBwYWRfcHJlY19zY2FuZiBpYiAoY29uY2F0X2ZtdCBmbXQnIHJlc3QpIHJlYWRlcnMgcGFkIE5vX3ByZWNpc2lvbiBzY2FuXG4gICAgICAgICAgICAgICAgICAgdG9rZW5fc3RyaW5nXG4gIHwgU3RyaW5nIChwYWQsIEZvcm1hdHRpbmdfZ2VuIChPcGVuX2JveCAoRm9ybWF0IChmbXQnLCBfKSksIHJlc3QpKSAtPlxuICAgIGxldCBzY2FuIHdpZHRoIF8gaWIgPSBzY2FuX3N0cmluZyAoU29tZSAnWycpIHdpZHRoIGliIGluXG4gICAgcGFkX3ByZWNfc2NhbmYgaWIgKGNvbmNhdF9mbXQgZm10JyByZXN0KSByZWFkZXJzIHBhZCBOb19wcmVjaXNpb24gc2NhblxuICAgICAgICAgICAgICAgICAgIHRva2VuX3N0cmluZ1xuICB8IFN0cmluZyAocGFkLCByZXN0KSAtPlxuICAgIGxldCBzY2FuIHdpZHRoIF8gaWIgPSBzY2FuX3N0cmluZyBOb25lIHdpZHRoIGliIGluXG4gICAgcGFkX3ByZWNfc2NhbmYgaWIgcmVzdCByZWFkZXJzIHBhZCBOb19wcmVjaXNpb24gc2NhbiB0b2tlbl9zdHJpbmdcblxuICB8IENhbWxfc3RyaW5nIChwYWQsIHJlc3QpIC0+XG4gICAgbGV0IHNjYW4gd2lkdGggXyBpYiA9IHNjYW5fY2FtbF9zdHJpbmcgd2lkdGggaWIgaW5cbiAgICBwYWRfcHJlY19zY2FuZiBpYiByZXN0IHJlYWRlcnMgcGFkIE5vX3ByZWNpc2lvbiBzY2FuIHRva2VuX3N0cmluZ1xuICB8IEludCAoaWNvbnYsIHBhZCwgcHJlYywgcmVzdCkgLT5cbiAgICBsZXQgYyA9IGludGVnZXJfY29udmVyc2lvbl9vZl9jaGFyIChjaGFyX29mX2ljb252IGljb252KSBpblxuICAgIGxldCBzY2FuIHdpZHRoIF8gaWIgPSBzY2FuX2ludF9jb252ZXJzaW9uIGMgd2lkdGggaWIgaW5cbiAgICBwYWRfcHJlY19zY2FuZiBpYiByZXN0IHJlYWRlcnMgcGFkIHByZWMgc2NhbiAodG9rZW5faW50IGMpXG4gIHwgSW50MzIgKGljb252LCBwYWQsIHByZWMsIHJlc3QpIC0+XG4gICAgbGV0IGMgPSBpbnRlZ2VyX2NvbnZlcnNpb25fb2ZfY2hhciAoY2hhcl9vZl9pY29udiBpY29udikgaW5cbiAgICBsZXQgc2NhbiB3aWR0aCBfIGliID0gc2Nhbl9pbnRfY29udmVyc2lvbiBjIHdpZHRoIGliIGluXG4gICAgcGFkX3ByZWNfc2NhbmYgaWIgcmVzdCByZWFkZXJzIHBhZCBwcmVjIHNjYW4gKHRva2VuX2ludDMyIGMpXG4gIHwgTmF0aXZlaW50IChpY29udiwgcGFkLCBwcmVjLCByZXN0KSAtPlxuICAgIGxldCBjID0gaW50ZWdlcl9jb252ZXJzaW9uX29mX2NoYXIgKGNoYXJfb2ZfaWNvbnYgaWNvbnYpIGluXG4gICAgbGV0IHNjYW4gd2lkdGggXyBpYiA9IHNjYW5faW50X2NvbnZlcnNpb24gYyB3aWR0aCBpYiBpblxuICAgIHBhZF9wcmVjX3NjYW5mIGliIHJlc3QgcmVhZGVycyBwYWQgcHJlYyBzY2FuICh0b2tlbl9uYXRpdmVpbnQgYylcbiAgfCBJbnQ2NCAoaWNvbnYsIHBhZCwgcHJlYywgcmVzdCkgLT5cbiAgICBsZXQgYyA9IGludGVnZXJfY29udmVyc2lvbl9vZl9jaGFyIChjaGFyX29mX2ljb252IGljb252KSBpblxuICAgIGxldCBzY2FuIHdpZHRoIF8gaWIgPSBzY2FuX2ludF9jb252ZXJzaW9uIGMgd2lkdGggaWIgaW5cbiAgICBwYWRfcHJlY19zY2FuZiBpYiByZXN0IHJlYWRlcnMgcGFkIHByZWMgc2NhbiAodG9rZW5faW50NjQgYylcbiAgfCBGbG9hdCAoKF8sIChGbG9hdF9GIHwgRmxvYXRfQ0YpKSwgcGFkLCBwcmVjLCByZXN0KSAtPlxuICAgIHBhZF9wcmVjX3NjYW5mIGliIHJlc3QgcmVhZGVycyBwYWQgcHJlYyBzY2FuX2NhbWxfZmxvYXQgdG9rZW5fZmxvYXRcbiAgfCBGbG9hdCAoKF8sIChGbG9hdF9mIHwgRmxvYXRfZSB8IEZsb2F0X0UgfCBGbG9hdF9nIHwgRmxvYXRfRykpLFxuICAgICAgICAgICBwYWQsIHByZWMsIHJlc3QpIC0+XG4gICAgcGFkX3ByZWNfc2NhbmYgaWIgcmVzdCByZWFkZXJzIHBhZCBwcmVjIHNjYW5fZmxvYXQgdG9rZW5fZmxvYXRcbiAgfCBGbG9hdCAoKF8sIChGbG9hdF9oIHwgRmxvYXRfSCkpLCBwYWQsIHByZWMsIHJlc3QpIC0+XG4gICAgcGFkX3ByZWNfc2NhbmYgaWIgcmVzdCByZWFkZXJzIHBhZCBwcmVjIHNjYW5faGV4X2Zsb2F0IHRva2VuX2Zsb2F0XG4gIHwgQm9vbCAocGFkLCByZXN0KSAtPlxuICAgIGxldCBzY2FuIF8gXyBpYiA9IHNjYW5fYm9vbCBpYiBpblxuICAgIHBhZF9wcmVjX3NjYW5mIGliIHJlc3QgcmVhZGVycyBwYWQgTm9fcHJlY2lzaW9uIHNjYW4gdG9rZW5fYm9vbFxuICB8IEFscGhhIF8gLT5cbiAgICBpbnZhbGlkX2FyZyBcInNjYW5mOiBiYWQgY29udmVyc2lvbiBcXFwiJWFcXFwiXCJcbiAgfCBUaGV0YSBfIC0+XG4gICAgaW52YWxpZF9hcmcgXCJzY2FuZjogYmFkIGNvbnZlcnNpb24gXFxcIiV0XFxcIlwiXG4gIHwgQ3VzdG9tIF8gLT5cbiAgICBpbnZhbGlkX2FyZyBcInNjYW5mOiBiYWQgY29udmVyc2lvbiBcXFwiJT9cXFwiIChjdXN0b20gY29udmVydGVyKVwiXG4gIHwgUmVhZGVyIGZtdF9yZXN0IC0+XG4gICAgYmVnaW4gbWF0Y2ggcmVhZGVycyB3aXRoXG4gICAgfCBDb25zIChyZWFkZXIsIHJlYWRlcnNfcmVzdCkgLT5cbiAgICAgICAgbGV0IHggPSByZWFkZXIgaWIgaW5cbiAgICAgICAgQ29ucyAoeCwgbWFrZV9zY2FuZiBpYiBmbXRfcmVzdCByZWFkZXJzX3Jlc3QpXG4gICAgfCBOaWwgLT5cbiAgICAgICAgaW52YWxpZF9hcmcgXCJzY2FuZjogbWlzc2luZyByZWFkZXJcIlxuICAgIGVuZFxuICB8IEZsdXNoIHJlc3QgLT5cbiAgICBpZiBTY2FubmluZy5lbmRfb2ZfaW5wdXQgaWIgdGhlbiBtYWtlX3NjYW5mIGliIHJlc3QgcmVhZGVyc1xuICAgIGVsc2UgYmFkX2lucHV0IFwiZW5kIG9mIGlucHV0IG5vdCBmb3VuZFwiXG5cbiAgfCBTdHJpbmdfbGl0ZXJhbCAoc3RyLCByZXN0KSAtPlxuICAgIFN0cmluZy5pdGVyIChjaGVja19jaGFyIGliKSBzdHI7XG4gICAgbWFrZV9zY2FuZiBpYiByZXN0IHJlYWRlcnNcbiAgfCBDaGFyX2xpdGVyYWwgKGNociwgcmVzdCkgLT5cbiAgICBjaGVja19jaGFyIGliIGNocjtcbiAgICBtYWtlX3NjYW5mIGliIHJlc3QgcmVhZGVyc1xuXG4gIHwgRm9ybWF0X2FyZyAocGFkX29wdCwgZm10dHksIHJlc3QpIC0+XG4gICAgbGV0IF8gPSBzY2FuX2NhbWxfc3RyaW5nICh3aWR0aF9vZl9wYWRfb3B0IHBhZF9vcHQpIGliIGluXG4gICAgbGV0IHMgPSB0b2tlbl9zdHJpbmcgaWIgaW5cbiAgICBsZXQgZm10ID1cbiAgICAgIHRyeSBmb3JtYXRfb2Zfc3RyaW5nX2ZtdHR5IHMgZm10dHlcbiAgICAgIHdpdGggRmFpbHVyZSBtc2cgLT4gYmFkX2lucHV0IG1zZ1xuICAgIGluXG4gICAgQ29ucyAoZm10LCBtYWtlX3NjYW5mIGliIHJlc3QgcmVhZGVycylcbiAgfCBGb3JtYXRfc3Vic3QgKHBhZF9vcHQsIGZtdHR5LCByZXN0KSAtPlxuICAgIGxldCBfID0gc2Nhbl9jYW1sX3N0cmluZyAod2lkdGhfb2ZfcGFkX29wdCBwYWRfb3B0KSBpYiBpblxuICAgIGxldCBzID0gdG9rZW5fc3RyaW5nIGliIGluXG4gICAgbGV0IGZtdCwgZm10JyA9XG4gICAgICB0cnlcbiAgICAgICAgbGV0IEZtdF9FQkIgZm10ID0gZm10X2ViYl9vZl9zdHJpbmcgcyBpblxuICAgICAgICBsZXQgRm10X0VCQiBmbXQnID0gZm10X2ViYl9vZl9zdHJpbmcgcyBpblxuICAgICAgICAoKiBUT0RPOiBmaW5kIGEgd2F5IHRvIGF2b2lkIHJlcGFyc2luZyB0d2ljZSAqKVxuXG4gICAgICAgICgqIFRPRE86IHRoZXNlIHR5cGUtY2hlY2tzIGJlbG93ICpjYW4qIGZhaWwgYmVjYXVzZSBvZiB0eXBlXG4gICAgICAgICAgIGFtYmlndWl0eSBpbiBwcmVzZW5jZSBvZiBpZ25vcmVkLXJlYWRlcnM6IFwiJV9yJWRcIiBhbmQgXCIlZCVfclwiXG4gICAgICAgICAgIGFyZSB0eXBlZCBpbiB0aGUgc2FtZSB3YXkuXG5cbiAgICAgICAgICAgIyBTY2FuZi5zc2NhbmYgXCJcXFwiJV9yJWRcXFwiM1wiIFwiJSglZCVfciUpXCIgaWdub3JlXG4gICAgICAgICAgICAgKGZ1biBmbXQgbiAtPiBzdHJpbmdfb2ZfZm9ybWF0IGZtdCwgbilcbiAgICAgICAgICAgRXhjZXB0aW9uOiBDYW1saW50ZXJuYWxGb3JtYXQuVHlwZV9taXNtYXRjaC5cblxuICAgICAgICAgICBXZSBzaG91bGQgcHJvcGVybHkgY2F0Y2ggdGhpcyBleGNlcHRpb24uXG4gICAgICAgICopXG4gICAgICAgIHR5cGVfZm9ybWF0IGZtdCAoZXJhc2VfcmVsIGZtdHR5KSxcbiAgICAgICAgdHlwZV9mb3JtYXQgZm10JyAoZXJhc2VfcmVsIChzeW1tIGZtdHR5KSlcbiAgICAgIHdpdGggRmFpbHVyZSBtc2cgLT4gYmFkX2lucHV0IG1zZ1xuICAgIGluXG4gICAgQ29ucyAoRm9ybWF0IChmbXQsIHMpLFxuICAgICAgICAgIG1ha2Vfc2NhbmYgaWIgKGNvbmNhdF9mbXQgZm10JyByZXN0KSByZWFkZXJzKVxuXG4gIHwgU2Nhbl9jaGFyX3NldCAod2lkdGhfb3B0LCBjaGFyX3NldCwgRm9ybWF0dGluZ19saXQgKGZtdGluZ19saXQsIHJlc3QpKSAtPlxuICAgIGxldCBzdHAsIHN0ciA9IHN0b3BwZXJfb2ZfZm9ybWF0dGluZ19saXQgZm10aW5nX2xpdCBpblxuICAgIGxldCB3aWR0aCA9IHdpZHRoX29mX3BhZF9vcHQgd2lkdGhfb3B0IGluXG4gICAgc2Nhbl9jaGFyc19pbl9jaGFyX3NldCBjaGFyX3NldCAoU29tZSBzdHApIHdpZHRoIGliO1xuICAgIGxldCBzID0gdG9rZW5fc3RyaW5nIGliIGluXG4gICAgbGV0IHN0cl9yZXN0ID0gU3RyaW5nX2xpdGVyYWwgKHN0ciwgcmVzdCkgaW5cbiAgICBDb25zIChzLCBtYWtlX3NjYW5mIGliIHN0cl9yZXN0IHJlYWRlcnMpXG4gIHwgU2Nhbl9jaGFyX3NldCAod2lkdGhfb3B0LCBjaGFyX3NldCwgcmVzdCkgLT5cbiAgICBsZXQgd2lkdGggPSB3aWR0aF9vZl9wYWRfb3B0IHdpZHRoX29wdCBpblxuICAgIHNjYW5fY2hhcnNfaW5fY2hhcl9zZXQgY2hhcl9zZXQgTm9uZSB3aWR0aCBpYjtcbiAgICBsZXQgcyA9IHRva2VuX3N0cmluZyBpYiBpblxuICAgIENvbnMgKHMsIG1ha2Vfc2NhbmYgaWIgcmVzdCByZWFkZXJzKVxuICB8IFNjYW5fZ2V0X2NvdW50ZXIgKGNvdW50ZXIsIHJlc3QpIC0+XG4gICAgbGV0IGNvdW50ID0gZ2V0X2NvdW50ZXIgaWIgY291bnRlciBpblxuICAgIENvbnMgKGNvdW50LCBtYWtlX3NjYW5mIGliIHJlc3QgcmVhZGVycylcbiAgfCBTY2FuX25leHRfY2hhciByZXN0IC0+XG4gICAgbGV0IGMgPSBTY2FubmluZy5jaGVja2VkX3BlZWtfY2hhciBpYiBpblxuICAgIENvbnMgKGMsIG1ha2Vfc2NhbmYgaWIgcmVzdCByZWFkZXJzKVxuXG4gIHwgRm9ybWF0dGluZ19saXQgKGZvcm1hdHRpbmdfbGl0LCByZXN0KSAtPlxuICAgIFN0cmluZy5pdGVyIChjaGVja19jaGFyIGliKSAoc3RyaW5nX29mX2Zvcm1hdHRpbmdfbGl0IGZvcm1hdHRpbmdfbGl0KTtcbiAgICBtYWtlX3NjYW5mIGliIHJlc3QgcmVhZGVyc1xuICB8IEZvcm1hdHRpbmdfZ2VuIChPcGVuX3RhZyAoRm9ybWF0IChmbXQnLCBfKSksIHJlc3QpIC0+XG4gICAgY2hlY2tfY2hhciBpYiAnQCc7IGNoZWNrX2NoYXIgaWIgJ3snO1xuICAgIG1ha2Vfc2NhbmYgaWIgKGNvbmNhdF9mbXQgZm10JyByZXN0KSByZWFkZXJzXG4gIHwgRm9ybWF0dGluZ19nZW4gKE9wZW5fYm94IChGb3JtYXQgKGZtdCcsIF8pKSwgcmVzdCkgLT5cbiAgICBjaGVja19jaGFyIGliICdAJzsgY2hlY2tfY2hhciBpYiAnWyc7XG4gICAgbWFrZV9zY2FuZiBpYiAoY29uY2F0X2ZtdCBmbXQnIHJlc3QpIHJlYWRlcnNcblxuICB8IElnbm9yZWRfcGFyYW0gKGlnbiwgcmVzdCkgLT5cbiAgICBsZXQgUGFyYW1fZm9ybWF0X0VCQiBmbXQnID0gcGFyYW1fZm9ybWF0X29mX2lnbm9yZWRfZm9ybWF0IGlnbiByZXN0IGluXG4gICAgYmVnaW4gbWF0Y2ggbWFrZV9zY2FuZiBpYiBmbXQnIHJlYWRlcnMgd2l0aFxuICAgIHwgQ29ucyAoXywgYXJnX3Jlc3QpIC0+IGFyZ19yZXN0XG4gICAgfCBOaWwgLT4gYXNzZXJ0IGZhbHNlXG4gICAgZW5kXG5cbiAgfCBFbmRfb2ZfZm9ybWF0IC0+XG4gICAgTmlsXG5cbigqIENhc2UgYW5hbHlzaXMgb24gcGFkZGluZyBhbmQgcHJlY2lzaW9uLiAqKVxuKCogUmVqZWN0IGZvcm1hdHMgY29udGFpbmluZyBcIiUqXCIgb3IgXCIlLipcIi4gKilcbigqIFBhc3MgcGFkZGluZyBhbmQgcHJlY2lzaW9uIHRvIHRoZSBnZW5lcmljIHNjYW5uZXIgYHNjYW4nLiAqKVxuYW5kIHBhZF9wcmVjX3NjYW5mIDogdHlwZSBhIGMgZCBlIGYgeCB5IHogdCAuXG4gICAgU2Nhbm5pbmcuaW5fY2hhbm5lbCAtPiAoYSwgU2Nhbm5pbmcuaW5fY2hhbm5lbCwgYywgZCwgZSwgZikgZm10IC0+XG4gICAgICAoZCwgZSkgaGV0ZXJfbGlzdCAtPiAoeCwgeSkgcGFkZGluZyAtPiAoeSwgeiAtPiBhKSBwcmVjaXNpb24gLT5cbiAgICAgIChpbnQgLT4gaW50IC0+IFNjYW5uaW5nLmluX2NoYW5uZWwgLT4gdCkgLT5cbiAgICAgIChTY2FubmluZy5pbl9jaGFubmVsIC0+IHopIC0+XG4gICAgICAoeCwgZikgaGV0ZXJfbGlzdCA9XG5mdW4gaWIgZm10IHJlYWRlcnMgcGFkIHByZWMgc2NhbiB0b2tlbiAtPiBtYXRjaCBwYWQsIHByZWMgd2l0aFxuICB8IE5vX3BhZGRpbmcsIE5vX3ByZWNpc2lvbiAtPlxuICAgIGxldCBfID0gc2NhbiBtYXhfaW50IG1heF9pbnQgaWIgaW5cbiAgICBsZXQgeCA9IHRva2VuIGliIGluXG4gICAgQ29ucyAoeCwgbWFrZV9zY2FuZiBpYiBmbXQgcmVhZGVycylcbiAgfCBOb19wYWRkaW5nLCBMaXRfcHJlY2lzaW9uIHAgLT5cbiAgICBsZXQgXyA9IHNjYW4gbWF4X2ludCBwIGliIGluXG4gICAgbGV0IHggPSB0b2tlbiBpYiBpblxuICAgIENvbnMgKHgsIG1ha2Vfc2NhbmYgaWIgZm10IHJlYWRlcnMpXG4gIHwgTGl0X3BhZGRpbmcgKChSaWdodCB8IFplcm9zKSwgdyksIE5vX3ByZWNpc2lvbiAtPlxuICAgIGxldCBfID0gc2NhbiB3IG1heF9pbnQgaWIgaW5cbiAgICBsZXQgeCA9IHRva2VuIGliIGluXG4gICAgQ29ucyAoeCwgbWFrZV9zY2FuZiBpYiBmbXQgcmVhZGVycylcbiAgfCBMaXRfcGFkZGluZyAoKFJpZ2h0IHwgWmVyb3MpLCB3KSwgTGl0X3ByZWNpc2lvbiBwIC0+XG4gICAgbGV0IF8gPSBzY2FuIHcgcCBpYiBpblxuICAgIGxldCB4ID0gdG9rZW4gaWIgaW5cbiAgICBDb25zICh4LCBtYWtlX3NjYW5mIGliIGZtdCByZWFkZXJzKVxuICB8IExpdF9wYWRkaW5nIChMZWZ0LCBfKSwgXyAtPlxuICAgIGludmFsaWRfYXJnIFwic2NhbmY6IGJhZCBjb252ZXJzaW9uIFxcXCIlLVxcXCJcIlxuICB8IExpdF9wYWRkaW5nICgoUmlnaHQgfCBaZXJvcyksIF8pLCBBcmdfcHJlY2lzaW9uIC0+XG4gICAgaW52YWxpZF9hcmcgXCJzY2FuZjogYmFkIGNvbnZlcnNpb24gXFxcIiUqXFxcIlwiXG4gIHwgQXJnX3BhZGRpbmcgXywgXyAtPlxuICAgIGludmFsaWRfYXJnIFwic2NhbmY6IGJhZCBjb252ZXJzaW9uIFxcXCIlKlxcXCJcIlxuICB8IE5vX3BhZGRpbmcsIEFyZ19wcmVjaXNpb24gLT5cbiAgICBpbnZhbGlkX2FyZyBcInNjYW5mOiBiYWQgY29udmVyc2lvbiBcXFwiJSpcXFwiXCJcblxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbiAgICAgICAgICAgICgqIERlZmluaW5nIFtzY2FuZl0gYW5kIHZhcmlvdXMgZmxhdm9ycyBvZiBbc2NhbmZdICopXG5cbnR5cGUgJ2Ega3NjYW5mX3Jlc3VsdCA9IEFyZ3Mgb2YgJ2EgfCBFeGMgb2YgZXhuXG5cbmxldCBrc2NhbmYgaWIgZWYgKEZvcm1hdCAoZm10LCBzdHIpKSA9XG4gIGxldCByZWMgYXBwbHkgOiB0eXBlIGEgYiAuIGEgLT4gKGEsIGIpIGhldGVyX2xpc3QgLT4gYiA9XG4gICAgZnVuIGYgYXJncyAtPiBtYXRjaCBhcmdzIHdpdGhcbiAgICB8IENvbnMgKHgsIHIpIC0+IGFwcGx5IChmIHgpIHJcbiAgICB8IE5pbCAtPiBmXG4gIGluXG4gIGxldCBrIHJlYWRlcnMgZiA9XG4gICAgU2Nhbm5pbmcucmVzZXRfdG9rZW4gaWI7XG4gICAgbWF0Y2ggdHJ5IEFyZ3MgKG1ha2Vfc2NhbmYgaWIgZm10IHJlYWRlcnMpIHdpdGhcbiAgICAgIHwgKFNjYW5fZmFpbHVyZSBfIHwgRmFpbHVyZSBfIHwgRW5kX29mX2ZpbGUpIGFzIGV4YyAtPiBFeGMgZXhjXG4gICAgICB8IEludmFsaWRfYXJndW1lbnQgbXNnIC0+XG4gICAgICAgIGludmFsaWRfYXJnIChtc2cgXiBcIiBpbiBmb3JtYXQgXFxcIlwiIF4gU3RyaW5nLmVzY2FwZWQgc3RyIF4gXCJcXFwiXCIpXG4gICAgd2l0aFxuICAgICAgfCBBcmdzIGFyZ3MgLT4gYXBwbHkgZiBhcmdzXG4gICAgICB8IEV4YyBleGMgLT4gZWYgaWIgZXhjXG4gIGluXG4gIHRha2VfZm9ybWF0X3JlYWRlcnMgayBmbXRcblxuKCoqKilcblxubGV0IGtic2NhbmYgPSBrc2NhbmZcbmxldCBic2NhbmYgaWIgZm10ID0ga2JzY2FuZiBpYiBzY2FuZl9iYWRfaW5wdXQgZm10XG5cbmxldCBrc3NjYW5mIHMgZWYgZm10ID0ga2JzY2FuZiAoU2Nhbm5pbmcuZnJvbV9zdHJpbmcgcykgZWYgZm10XG5sZXQgc3NjYW5mIHMgZm10ID0ga2JzY2FuZiAoU2Nhbm5pbmcuZnJvbV9zdHJpbmcgcykgc2NhbmZfYmFkX2lucHV0IGZtdFxuXG5sZXQgc2NhbmYgZm10ID0ga3NjYW5mIFNjYW5uaW5nLnN0ZGliIHNjYW5mX2JhZF9pbnB1dCBmbXRcblxuKCoqKilcblxuKCogU2Nhbm5pbmcgZm9ybWF0IHN0cmluZ3MuICopXG5sZXQgYnNjYW5mX2Zvcm1hdCA6XG4gIFNjYW5uaW5nLmluX2NoYW5uZWwgLT4gKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZvcm1hdDYgLT5cbiAgKCgnYSwgJ2IsICdjLCAnZCwgJ2UsICdmKSBmb3JtYXQ2IC0+ICdnKSAtPiAnZyA9XG4gIGZ1biBpYiBmb3JtYXQgZiAtPlxuICAgIGxldCBfID0gc2Nhbl9jYW1sX3N0cmluZyBtYXhfaW50IGliIGluXG4gICAgbGV0IHN0ciA9IHRva2VuX3N0cmluZyBpYiBpblxuICAgIGxldCBmbXQnID1cbiAgICAgIHRyeSBmb3JtYXRfb2Zfc3RyaW5nX2Zvcm1hdCBzdHIgZm9ybWF0XG4gICAgICB3aXRoIEZhaWx1cmUgbXNnIC0+IGJhZF9pbnB1dCBtc2cgaW5cbiAgICBmIGZtdCdcblxuXG5sZXQgc3NjYW5mX2Zvcm1hdCA6XG4gIHN0cmluZyAtPiAoJ2EsICdiLCAnYywgJ2QsICdlLCAnZikgZm9ybWF0NiAtPlxuICAoKCdhLCAnYiwgJ2MsICdkLCAnZSwgJ2YpIGZvcm1hdDYgLT4gJ2cpIC0+ICdnID1cbiAgZnVuIHMgZm9ybWF0IGYgLT4gYnNjYW5mX2Zvcm1hdCAoU2Nhbm5pbmcuZnJvbV9zdHJpbmcgcykgZm9ybWF0IGZcblxuXG5sZXQgZm9ybWF0X2Zyb21fc3RyaW5nIHMgZm10ID1cbiAgc3NjYW5mX2Zvcm1hdCAoXCJcXFwiXCIgXiBTdHJpbmcuZXNjYXBlZCBzIF4gXCJcXFwiXCIpIGZtdCAoZnVuIHggLT4geClcblxuXG5sZXQgdW5lc2NhcGVkIHMgPVxuICBzc2NhbmYgKFwiXFxcIlwiIF4gcyBeIFwiXFxcIlwiKSBcIiVTJSFcIiAoZnVuIHggLT4geClcblxuXG4oKiBEZXByZWNhdGVkICopXG5sZXQga2ZzY2FuZiBpYyBlZiBmbXQgPSBrYnNjYW5mIChTY2FubmluZy5tZW1vX2Zyb21fY2hhbm5lbCBpYykgZWYgZm10XG5sZXQgZnNjYW5mIGljIGZtdCA9IGtzY2FuZiAoU2Nhbm5pbmcubWVtb19mcm9tX2NoYW5uZWwgaWMpIHNjYW5mX2JhZF9pbnB1dCBmbXRcbiIsIigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0NhbWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgIFhhdmllciBMZXJveSwgcHJvamV0IENyaXN0YWwsIElOUklBIFJvY3F1ZW5jb3VydCAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQ29weXJpZ2h0IDE5OTYgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCAgICAgKilcbigqICAgICBlbiBBdXRvbWF0aXF1ZS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQWxsIHJpZ2h0cyByZXNlcnZlZC4gIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgICAgKilcbigqICAgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIuMSwgd2l0aCB0aGUgICAgICAgICAgKilcbigqICAgc3BlY2lhbCBleGNlcHRpb24gb24gbGlua2luZyBkZXNjcmliZWQgaW4gdGhlIGZpbGUgTElDRU5TRS4gICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcblxuKCogUmVnaXN0ZXJpbmcgT0NhbWwgdmFsdWVzIHdpdGggdGhlIEMgcnVudGltZSBmb3IgbGF0ZXIgY2FsbGJhY2tzICopXG5cbmV4dGVybmFsIHJlZ2lzdGVyX25hbWVkX3ZhbHVlIDogc3RyaW5nIC0+IE9iai50IC0+IHVuaXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gXCJjYW1sX3JlZ2lzdGVyX25hbWVkX3ZhbHVlXCJcblxubGV0IHJlZ2lzdGVyIG5hbWUgdiA9XG4gIHJlZ2lzdGVyX25hbWVkX3ZhbHVlIG5hbWUgKE9iai5yZXByIHYpXG5cbmxldCByZWdpc3Rlcl9leGNlcHRpb24gbmFtZSAoZXhuIDogZXhuKSA9XG4gIGxldCBleG4gPSBPYmoucmVwciBleG4gaW5cbiAgbGV0IHNsb3QgPSBpZiBPYmoudGFnIGV4biA9IE9iai5vYmplY3RfdGFnIHRoZW4gZXhuIGVsc2UgT2JqLmZpZWxkIGV4biAwIGluXG4gIHJlZ2lzdGVyX25hbWVkX3ZhbHVlIG5hbWUgc2xvdFxuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgSmVyb21lIFZvdWlsbG9uLCBwcm9qZXQgQ3Jpc3RhbCwgSU5SSUEgUm9jcXVlbmNvdXJ0ICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMjAwMiBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0ICAgICAqKVxuKCogICAgIGVuIEF1dG9tYXRpcXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG5vcGVuIE9ialxuXG4oKioqKiBPYmplY3QgcmVwcmVzZW50YXRpb24gKioqKilcblxuZXh0ZXJuYWwgc2V0X2lkOiAnYSAtPiAnYSA9IFwiY2FtbF9zZXRfb29faWRcIiBbQEBub2FsbG9jXVxuXG4oKioqKiBPYmplY3QgY29weSAqKioqKVxuXG5sZXQgY29weSBvID1cbiAgbGV0IG8gPSAoT2JqLm9iaiAoT2JqLmR1cCAoT2JqLnJlcHIgbykpKSBpblxuICBzZXRfaWQgb1xuXG4oKioqKiBDb21wcmVzc2lvbiBvcHRpb25zICoqKiopXG4oKiBQYXJhbWV0ZXJzICopXG50eXBlIHBhcmFtcyA9IHtcbiAgICBtdXRhYmxlIGNvbXBhY3RfdGFibGUgOiBib29sO1xuICAgIG11dGFibGUgY29weV9wYXJlbnQgOiBib29sO1xuICAgIG11dGFibGUgY2xlYW5fd2hlbl9jb3B5aW5nIDogYm9vbDtcbiAgICBtdXRhYmxlIHJldHJ5X2NvdW50IDogaW50O1xuICAgIG11dGFibGUgYnVja2V0X3NtYWxsX3NpemUgOiBpbnRcbiAgfVxuXG5sZXQgcGFyYW1zID0ge1xuICBjb21wYWN0X3RhYmxlID0gdHJ1ZTtcbiAgY29weV9wYXJlbnQgPSB0cnVlO1xuICBjbGVhbl93aGVuX2NvcHlpbmcgPSB0cnVlO1xuICByZXRyeV9jb3VudCA9IDM7XG4gIGJ1Y2tldF9zbWFsbF9zaXplID0gMTZcbn1cblxuKCoqKiogUGFyYW1ldGVycyAqKioqKVxuXG5sZXQgaW5pdGlhbF9vYmplY3Rfc2l6ZSA9IDJcblxuKCoqKiogSXRlbXMgKioqKilcblxudHlwZSBpdGVtID0gRHVtbXlBIHwgRHVtbXlCIHwgRHVtbXlDIG9mIGludFxubGV0IF8gPSBbRHVtbXlBOyBEdW1teUI7IER1bW15QyAwXSAoKiB0byBhdm9pZCB3YXJuaW5ncyAqKVxuXG5sZXQgZHVtbXlfaXRlbSA9IChtYWdpYyAoKSA6IGl0ZW0pXG5cbigqKioqIFR5cGVzICoqKiopXG5cbnR5cGUgdGFnXG50eXBlIGxhYmVsID0gaW50XG50eXBlIGNsb3N1cmUgPSBpdGVtXG50eXBlIHQgPSBEdW1teUEgfCBEdW1teUIgfCBEdW1teUMgb2YgaW50XG5sZXQgXyA9IFtEdW1teUE7IER1bW15QjsgRHVtbXlDIDBdICgqIHRvIGF2b2lkIHdhcm5pbmdzICopXG5cbnR5cGUgb2JqID0gdCBhcnJheVxuZXh0ZXJuYWwgcmV0IDogKG9iaiAtPiAnYSkgLT4gY2xvc3VyZSA9IFwiJWlkZW50aXR5XCJcblxuKCoqKiogTGFiZWxzICoqKiopXG5cbmxldCBwdWJsaWNfbWV0aG9kX2xhYmVsIHMgOiB0YWcgPVxuICBsZXQgYWNjdSA9IHJlZiAwIGluXG4gIGZvciBpID0gMCB0byBTdHJpbmcubGVuZ3RoIHMgLSAxIGRvXG4gICAgYWNjdSA6PSAyMjMgKiAhYWNjdSArIENoYXIuY29kZSBzLltpXVxuICBkb25lO1xuICAoKiByZWR1Y2UgdG8gMzEgYml0cyAqKVxuICBhY2N1IDo9ICFhY2N1IGxhbmQgKDEgbHNsIDMxIC0gMSk7XG4gICgqIG1ha2UgaXQgc2lnbmVkIGZvciA2NCBiaXRzIGFyY2hpdGVjdHVyZXMgKilcbiAgbGV0IHRhZyA9IGlmICFhY2N1ID4gMHgzRkZGRkZGRiB0aGVuICFhY2N1IC0gKDEgbHNsIDMxKSBlbHNlICFhY2N1IGluXG4gICgqIFByaW50Zi5lcHJpbnRmIFwiJXMgPSAlZFxcblwiIHMgdGFnOyBmbHVzaCBzdGRlcnI7ICopXG4gIG1hZ2ljIHRhZ1xuXG4oKioqKiBTcGFyc2UgYXJyYXkgKioqKilcblxubW9kdWxlIFZhcnMgPVxuICBNYXAuTWFrZShzdHJ1Y3QgdHlwZSB0ID0gc3RyaW5nIGxldCBjb21wYXJlICh4OnQpIHkgPSBjb21wYXJlIHggeSBlbmQpXG50eXBlIHZhcnMgPSBpbnQgVmFycy50XG5cbm1vZHVsZSBNZXRocyA9XG4gIE1hcC5NYWtlKHN0cnVjdCB0eXBlIHQgPSBzdHJpbmcgbGV0IGNvbXBhcmUgKHg6dCkgeSA9IGNvbXBhcmUgeCB5IGVuZClcbnR5cGUgbWV0aHMgPSBsYWJlbCBNZXRocy50XG5tb2R1bGUgTGFicyA9XG4gIE1hcC5NYWtlKHN0cnVjdCB0eXBlIHQgPSBsYWJlbCBsZXQgY29tcGFyZSAoeDp0KSB5ID0gY29tcGFyZSB4IHkgZW5kKVxudHlwZSBsYWJzID0gYm9vbCBMYWJzLnRcblxuKCogVGhlIGNvbXBpbGVyIGFzc3VtZXMgdGhhdCB0aGUgZmlyc3QgZmllbGQgb2YgdGhpcyBzdHJ1Y3R1cmUgaXMgW3NpemVdLiAqKVxudHlwZSB0YWJsZSA9XG4geyBtdXRhYmxlIHNpemU6IGludDtcbiAgIG11dGFibGUgbWV0aG9kczogY2xvc3VyZSBhcnJheTtcbiAgIG11dGFibGUgbWV0aG9kc19ieV9uYW1lOiBtZXRocztcbiAgIG11dGFibGUgbWV0aG9kc19ieV9sYWJlbDogbGFicztcbiAgIG11dGFibGUgcHJldmlvdXNfc3RhdGVzOlxuICAgICAobWV0aHMgKiBsYWJzICogKGxhYmVsICogaXRlbSkgbGlzdCAqIHZhcnMgKlxuICAgICAgbGFiZWwgbGlzdCAqIHN0cmluZyBsaXN0KSBsaXN0O1xuICAgbXV0YWJsZSBoaWRkZW5fbWV0aHM6IChsYWJlbCAqIGl0ZW0pIGxpc3Q7XG4gICBtdXRhYmxlIHZhcnM6IHZhcnM7XG4gICBtdXRhYmxlIGluaXRpYWxpemVyczogKG9iaiAtPiB1bml0KSBsaXN0IH1cblxubGV0IGR1bW15X3RhYmxlID1cbiAgeyBtZXRob2RzID0gW3wgZHVtbXlfaXRlbSB8XTtcbiAgICBtZXRob2RzX2J5X25hbWUgPSBNZXRocy5lbXB0eTtcbiAgICBtZXRob2RzX2J5X2xhYmVsID0gTGFicy5lbXB0eTtcbiAgICBwcmV2aW91c19zdGF0ZXMgPSBbXTtcbiAgICBoaWRkZW5fbWV0aHMgPSBbXTtcbiAgICB2YXJzID0gVmFycy5lbXB0eTtcbiAgICBpbml0aWFsaXplcnMgPSBbXTtcbiAgICBzaXplID0gMCB9XG5cbmxldCB0YWJsZV9jb3VudCA9IHJlZiAwXG5cbigqIGR1bW15X21ldCBzaG91bGQgYmUgYSBwb2ludGVyLCBzbyB1c2UgYW4gYXRvbSAqKVxubGV0IGR1bW15X21ldCA6IGl0ZW0gPSBvYmogKE9iai5uZXdfYmxvY2sgMCAwKVxuKCogaWYgZGVidWdnaW5nIGlzIG5lZWRlZCwgdGhpcyBjb3VsZCBiZSBhIGdvb2QgaWRlYTogKilcbigqIGxldCBkdW1teV9tZXQgKCkgPSBmYWlsd2l0aCBcIlVuZGVmaW5lZCBtZXRob2RcIiAqKVxuXG5sZXQgcmVjIGZpdF9zaXplIG4gPVxuICBpZiBuIDw9IDIgdGhlbiBuIGVsc2VcbiAgZml0X3NpemUgKChuKzEpLzIpICogMlxuXG5sZXQgbmV3X3RhYmxlIHB1Yl9sYWJlbHMgPVxuICBpbmNyIHRhYmxlX2NvdW50O1xuICBsZXQgbGVuID0gQXJyYXkubGVuZ3RoIHB1Yl9sYWJlbHMgaW5cbiAgbGV0IG1ldGhvZHMgPSBBcnJheS5tYWtlIChsZW4qMisyKSBkdW1teV9tZXQgaW5cbiAgbWV0aG9kcy4oMCkgPC0gbWFnaWMgbGVuO1xuICBtZXRob2RzLigxKSA8LSBtYWdpYyAoZml0X3NpemUgbGVuICogU3lzLndvcmRfc2l6ZSAvIDggLSAxKTtcbiAgZm9yIGkgPSAwIHRvIGxlbiAtIDEgZG8gbWV0aG9kcy4oaSoyKzMpIDwtIG1hZ2ljIHB1Yl9sYWJlbHMuKGkpIGRvbmU7XG4gIHsgbWV0aG9kcyA9IG1ldGhvZHM7XG4gICAgbWV0aG9kc19ieV9uYW1lID0gTWV0aHMuZW1wdHk7XG4gICAgbWV0aG9kc19ieV9sYWJlbCA9IExhYnMuZW1wdHk7XG4gICAgcHJldmlvdXNfc3RhdGVzID0gW107XG4gICAgaGlkZGVuX21ldGhzID0gW107XG4gICAgdmFycyA9IFZhcnMuZW1wdHk7XG4gICAgaW5pdGlhbGl6ZXJzID0gW107XG4gICAgc2l6ZSA9IGluaXRpYWxfb2JqZWN0X3NpemUgfVxuXG5sZXQgcmVzaXplIGFycmF5IG5ld19zaXplID1cbiAgbGV0IG9sZF9zaXplID0gQXJyYXkubGVuZ3RoIGFycmF5Lm1ldGhvZHMgaW5cbiAgaWYgbmV3X3NpemUgPiBvbGRfc2l6ZSB0aGVuIGJlZ2luXG4gICAgbGV0IG5ld19idWNrID0gQXJyYXkubWFrZSBuZXdfc2l6ZSBkdW1teV9tZXQgaW5cbiAgICBBcnJheS5ibGl0IGFycmF5Lm1ldGhvZHMgMCBuZXdfYnVjayAwIG9sZF9zaXplO1xuICAgIGFycmF5Lm1ldGhvZHMgPC0gbmV3X2J1Y2tcbiBlbmRcblxubGV0IHB1dCBhcnJheSBsYWJlbCBlbGVtZW50ID1cbiAgcmVzaXplIGFycmF5IChsYWJlbCArIDEpO1xuICBhcnJheS5tZXRob2RzLihsYWJlbCkgPC0gZWxlbWVudFxuXG4oKioqKiBDbGFzc2VzICoqKiopXG5cbmxldCBtZXRob2RfY291bnQgPSByZWYgMFxubGV0IGluc3RfdmFyX2NvdW50ID0gcmVmIDBcblxuKCogdHlwZSB0ICopXG50eXBlIG1ldGggPSBpdGVtXG5cbmxldCBuZXdfbWV0aG9kIHRhYmxlID1cbiAgbGV0IGluZGV4ID0gQXJyYXkubGVuZ3RoIHRhYmxlLm1ldGhvZHMgaW5cbiAgcmVzaXplIHRhYmxlIChpbmRleCArIDEpO1xuICBpbmRleFxuXG5sZXQgZ2V0X21ldGhvZF9sYWJlbCB0YWJsZSBuYW1lID1cbiAgdHJ5XG4gICAgTWV0aHMuZmluZCBuYW1lIHRhYmxlLm1ldGhvZHNfYnlfbmFtZVxuICB3aXRoIE5vdF9mb3VuZCAtPlxuICAgIGxldCBsYWJlbCA9IG5ld19tZXRob2QgdGFibGUgaW5cbiAgICB0YWJsZS5tZXRob2RzX2J5X25hbWUgPC0gTWV0aHMuYWRkIG5hbWUgbGFiZWwgdGFibGUubWV0aG9kc19ieV9uYW1lO1xuICAgIHRhYmxlLm1ldGhvZHNfYnlfbGFiZWwgPC0gTGFicy5hZGQgbGFiZWwgdHJ1ZSB0YWJsZS5tZXRob2RzX2J5X2xhYmVsO1xuICAgIGxhYmVsXG5cbmxldCBnZXRfbWV0aG9kX2xhYmVscyB0YWJsZSBuYW1lcyA9XG4gIEFycmF5Lm1hcCAoZ2V0X21ldGhvZF9sYWJlbCB0YWJsZSkgbmFtZXNcblxubGV0IHNldF9tZXRob2QgdGFibGUgbGFiZWwgZWxlbWVudCA9XG4gIGluY3IgbWV0aG9kX2NvdW50O1xuICBpZiBMYWJzLmZpbmQgbGFiZWwgdGFibGUubWV0aG9kc19ieV9sYWJlbCB0aGVuXG4gICAgcHV0IHRhYmxlIGxhYmVsIGVsZW1lbnRcbiAgZWxzZVxuICAgIHRhYmxlLmhpZGRlbl9tZXRocyA8LSAobGFiZWwsIGVsZW1lbnQpIDo6IHRhYmxlLmhpZGRlbl9tZXRoc1xuXG5sZXQgZ2V0X21ldGhvZCB0YWJsZSBsYWJlbCA9XG4gIHRyeSBMaXN0LmFzc29jIGxhYmVsIHRhYmxlLmhpZGRlbl9tZXRoc1xuICB3aXRoIE5vdF9mb3VuZCAtPiB0YWJsZS5tZXRob2RzLihsYWJlbClcblxubGV0IHRvX2xpc3QgYXJyID1cbiAgaWYgYXJyID09IG1hZ2ljIDAgdGhlbiBbXSBlbHNlIEFycmF5LnRvX2xpc3QgYXJyXG5cbmxldCBuYXJyb3cgdGFibGUgdmFycyB2aXJ0X21ldGhzIGNvbmNyX21ldGhzID1cbiAgbGV0IHZhcnMgPSB0b19saXN0IHZhcnNcbiAgYW5kIHZpcnRfbWV0aHMgPSB0b19saXN0IHZpcnRfbWV0aHNcbiAgYW5kIGNvbmNyX21ldGhzID0gdG9fbGlzdCBjb25jcl9tZXRocyBpblxuICBsZXQgdmlydF9tZXRoX2xhYnMgPSBMaXN0Lm1hcCAoZ2V0X21ldGhvZF9sYWJlbCB0YWJsZSkgdmlydF9tZXRocyBpblxuICBsZXQgY29uY3JfbWV0aF9sYWJzID0gTGlzdC5tYXAgKGdldF9tZXRob2RfbGFiZWwgdGFibGUpIGNvbmNyX21ldGhzIGluXG4gIHRhYmxlLnByZXZpb3VzX3N0YXRlcyA8LVxuICAgICAodGFibGUubWV0aG9kc19ieV9uYW1lLCB0YWJsZS5tZXRob2RzX2J5X2xhYmVsLCB0YWJsZS5oaWRkZW5fbWV0aHMsXG4gICAgICB0YWJsZS52YXJzLCB2aXJ0X21ldGhfbGFicywgdmFycylcbiAgICAgOjogdGFibGUucHJldmlvdXNfc3RhdGVzO1xuICB0YWJsZS52YXJzIDwtXG4gICAgVmFycy5mb2xkXG4gICAgICAoZnVuIGxhYiBpbmZvIHR2YXJzIC0+XG4gICAgICAgIGlmIExpc3QubWVtIGxhYiB2YXJzIHRoZW4gVmFycy5hZGQgbGFiIGluZm8gdHZhcnMgZWxzZSB0dmFycylcbiAgICAgIHRhYmxlLnZhcnMgVmFycy5lbXB0eTtcbiAgbGV0IGJ5X25hbWUgPSByZWYgTWV0aHMuZW1wdHkgaW5cbiAgbGV0IGJ5X2xhYmVsID0gcmVmIExhYnMuZW1wdHkgaW5cbiAgTGlzdC5pdGVyMlxuICAgIChmdW4gbWV0IGxhYmVsIC0+XG4gICAgICAgYnlfbmFtZSA6PSBNZXRocy5hZGQgbWV0IGxhYmVsICFieV9uYW1lO1xuICAgICAgIGJ5X2xhYmVsIDo9XG4gICAgICAgICAgTGFicy5hZGQgbGFiZWxcbiAgICAgICAgICAgICh0cnkgTGFicy5maW5kIGxhYmVsIHRhYmxlLm1ldGhvZHNfYnlfbGFiZWwgd2l0aCBOb3RfZm91bmQgLT4gdHJ1ZSlcbiAgICAgICAgICAgICFieV9sYWJlbClcbiAgICBjb25jcl9tZXRocyBjb25jcl9tZXRoX2xhYnM7XG4gIExpc3QuaXRlcjJcbiAgICAoZnVuIG1ldCBsYWJlbCAtPlxuICAgICAgIGJ5X25hbWUgOj0gTWV0aHMuYWRkIG1ldCBsYWJlbCAhYnlfbmFtZTtcbiAgICAgICBieV9sYWJlbCA6PSBMYWJzLmFkZCBsYWJlbCBmYWxzZSAhYnlfbGFiZWwpXG4gICAgdmlydF9tZXRocyB2aXJ0X21ldGhfbGFicztcbiAgdGFibGUubWV0aG9kc19ieV9uYW1lIDwtICFieV9uYW1lO1xuICB0YWJsZS5tZXRob2RzX2J5X2xhYmVsIDwtICFieV9sYWJlbDtcbiAgdGFibGUuaGlkZGVuX21ldGhzIDwtXG4gICAgIExpc3QuZm9sZF9yaWdodFxuICAgICAgIChmdW4gKChsYWIsIF8pIGFzIG1ldCkgaG0gLT5cbiAgICAgICAgICBpZiBMaXN0Lm1lbSBsYWIgdmlydF9tZXRoX2xhYnMgdGhlbiBobSBlbHNlIG1ldDo6aG0pXG4gICAgICAgdGFibGUuaGlkZGVuX21ldGhzXG4gICAgICAgW11cblxubGV0IHdpZGVuIHRhYmxlID1cbiAgbGV0IChieV9uYW1lLCBieV9sYWJlbCwgc2F2ZWRfaGlkZGVuX21ldGhzLCBzYXZlZF92YXJzLCB2aXJ0X21ldGhzLCB2YXJzKSA9XG4gICAgTGlzdC5oZCB0YWJsZS5wcmV2aW91c19zdGF0ZXNcbiAgaW5cbiAgdGFibGUucHJldmlvdXNfc3RhdGVzIDwtIExpc3QudGwgdGFibGUucHJldmlvdXNfc3RhdGVzO1xuICB0YWJsZS52YXJzIDwtXG4gICAgIExpc3QuZm9sZF9sZWZ0XG4gICAgICAgKGZ1biBzIHYgLT4gVmFycy5hZGQgdiAoVmFycy5maW5kIHYgdGFibGUudmFycykgcylcbiAgICAgICBzYXZlZF92YXJzIHZhcnM7XG4gIHRhYmxlLm1ldGhvZHNfYnlfbmFtZSA8LSBieV9uYW1lO1xuICB0YWJsZS5tZXRob2RzX2J5X2xhYmVsIDwtIGJ5X2xhYmVsO1xuICB0YWJsZS5oaWRkZW5fbWV0aHMgPC1cbiAgICAgTGlzdC5mb2xkX3JpZ2h0XG4gICAgICAgKGZ1biAoKGxhYiwgXykgYXMgbWV0KSBobSAtPlxuICAgICAgICAgIGlmIExpc3QubWVtIGxhYiB2aXJ0X21ldGhzIHRoZW4gaG0gZWxzZSBtZXQ6OmhtKVxuICAgICAgIHRhYmxlLmhpZGRlbl9tZXRoc1xuICAgICAgIHNhdmVkX2hpZGRlbl9tZXRoc1xuXG5sZXQgbmV3X3Nsb3QgdGFibGUgPVxuICBsZXQgaW5kZXggPSB0YWJsZS5zaXplIGluXG4gIHRhYmxlLnNpemUgPC0gaW5kZXggKyAxO1xuICBpbmRleFxuXG5sZXQgbmV3X3ZhcmlhYmxlIHRhYmxlIG5hbWUgPVxuICB0cnkgVmFycy5maW5kIG5hbWUgdGFibGUudmFyc1xuICB3aXRoIE5vdF9mb3VuZCAtPlxuICAgIGxldCBpbmRleCA9IG5ld19zbG90IHRhYmxlIGluXG4gICAgaWYgbmFtZSA8PiBcIlwiIHRoZW4gdGFibGUudmFycyA8LSBWYXJzLmFkZCBuYW1lIGluZGV4IHRhYmxlLnZhcnM7XG4gICAgaW5kZXhcblxubGV0IHRvX2FycmF5IGFyciA9XG4gIGlmIGFyciA9IE9iai5tYWdpYyAwIHRoZW4gW3x8XSBlbHNlIGFyclxuXG5sZXQgbmV3X21ldGhvZHNfdmFyaWFibGVzIHRhYmxlIG1ldGhzIHZhbHMgPVxuICBsZXQgbWV0aHMgPSB0b19hcnJheSBtZXRocyBpblxuICBsZXQgbm1ldGhzID0gQXJyYXkubGVuZ3RoIG1ldGhzIGFuZCBudmFscyA9IEFycmF5Lmxlbmd0aCB2YWxzIGluXG4gIGxldCByZXMgPSBBcnJheS5tYWtlIChubWV0aHMgKyBudmFscykgMCBpblxuICBmb3IgaSA9IDAgdG8gbm1ldGhzIC0gMSBkb1xuICAgIHJlcy4oaSkgPC0gZ2V0X21ldGhvZF9sYWJlbCB0YWJsZSBtZXRocy4oaSlcbiAgZG9uZTtcbiAgZm9yIGkgPSAwIHRvIG52YWxzIC0gMSBkb1xuICAgIHJlcy4oaStubWV0aHMpIDwtIG5ld192YXJpYWJsZSB0YWJsZSB2YWxzLihpKVxuICBkb25lO1xuICByZXNcblxubGV0IGdldF92YXJpYWJsZSB0YWJsZSBuYW1lID1cbiAgdHJ5IFZhcnMuZmluZCBuYW1lIHRhYmxlLnZhcnMgd2l0aCBOb3RfZm91bmQgLT4gYXNzZXJ0IGZhbHNlXG5cbmxldCBnZXRfdmFyaWFibGVzIHRhYmxlIG5hbWVzID1cbiAgQXJyYXkubWFwIChnZXRfdmFyaWFibGUgdGFibGUpIG5hbWVzXG5cbmxldCBhZGRfaW5pdGlhbGl6ZXIgdGFibGUgZiA9XG4gIHRhYmxlLmluaXRpYWxpemVycyA8LSBmOjp0YWJsZS5pbml0aWFsaXplcnNcblxuKCpcbm1vZHVsZSBLZXlzID1cbiAgTWFwLk1ha2Uoc3RydWN0IHR5cGUgdCA9IHRhZyBhcnJheSBsZXQgY29tcGFyZSAoeDp0KSB5ID0gY29tcGFyZSB4IHkgZW5kKVxubGV0IGtleV9tYXAgPSByZWYgS2V5cy5lbXB0eVxubGV0IGdldF9rZXkgdGFncyA6IGl0ZW0gPVxuICB0cnkgbWFnaWMgKEtleXMuZmluZCB0YWdzICFrZXlfbWFwIDogdGFnIGFycmF5KVxuICB3aXRoIE5vdF9mb3VuZCAtPlxuICAgIGtleV9tYXAgOj0gS2V5cy5hZGQgdGFncyB0YWdzICFrZXlfbWFwO1xuICAgIG1hZ2ljIHRhZ3NcbiopXG5cbmxldCBjcmVhdGVfdGFibGUgcHVibGljX21ldGhvZHMgPVxuICBpZiBwdWJsaWNfbWV0aG9kcyA9PSBtYWdpYyAwIHRoZW4gbmV3X3RhYmxlIFt8fF0gZWxzZVxuICAoKiBbcHVibGljX21ldGhvZHNdIG11c3QgYmUgaW4gYXNjZW5kaW5nIG9yZGVyIGZvciBieXRlY29kZSAqKVxuICBsZXQgdGFncyA9IEFycmF5Lm1hcCBwdWJsaWNfbWV0aG9kX2xhYmVsIHB1YmxpY19tZXRob2RzIGluXG4gIGxldCB0YWJsZSA9IG5ld190YWJsZSB0YWdzIGluXG4gIEFycmF5Lml0ZXJpXG4gICAgKGZ1biBpIG1ldCAtPlxuICAgICAgbGV0IGxhYiA9IGkqMisyIGluXG4gICAgICB0YWJsZS5tZXRob2RzX2J5X25hbWUgIDwtIE1ldGhzLmFkZCBtZXQgbGFiIHRhYmxlLm1ldGhvZHNfYnlfbmFtZTtcbiAgICAgIHRhYmxlLm1ldGhvZHNfYnlfbGFiZWwgPC0gTGFicy5hZGQgbGFiIHRydWUgdGFibGUubWV0aG9kc19ieV9sYWJlbClcbiAgICBwdWJsaWNfbWV0aG9kcztcbiAgdGFibGVcblxubGV0IGluaXRfY2xhc3MgdGFibGUgPVxuICBpbnN0X3Zhcl9jb3VudCA6PSAhaW5zdF92YXJfY291bnQgKyB0YWJsZS5zaXplIC0gMTtcbiAgdGFibGUuaW5pdGlhbGl6ZXJzIDwtIExpc3QucmV2IHRhYmxlLmluaXRpYWxpemVycztcbiAgcmVzaXplIHRhYmxlICgzICsgbWFnaWMgdGFibGUubWV0aG9kcy4oMSkgKiAxNiAvIFN5cy53b3JkX3NpemUpXG5cbmxldCBpbmhlcml0cyBjbGEgdmFscyB2aXJ0X21ldGhzIGNvbmNyX21ldGhzIChfLCBzdXBlciwgXywgZW52KSB0b3AgPVxuICBuYXJyb3cgY2xhIHZhbHMgdmlydF9tZXRocyBjb25jcl9tZXRocztcbiAgbGV0IGluaXQgPVxuICAgIGlmIHRvcCB0aGVuIHN1cGVyIGNsYSBlbnYgZWxzZSBPYmoucmVwciAoc3VwZXIgY2xhKSBpblxuICB3aWRlbiBjbGE7XG4gIEFycmF5LmNvbmNhdFxuICAgIFtbfCByZXByIGluaXQgfF07XG4gICAgIG1hZ2ljIChBcnJheS5tYXAgKGdldF92YXJpYWJsZSBjbGEpICh0b19hcnJheSB2YWxzKSA6IGludCBhcnJheSk7XG4gICAgIEFycmF5Lm1hcFxuICAgICAgIChmdW4gbm0gLT4gcmVwciAoZ2V0X21ldGhvZCBjbGEgKGdldF9tZXRob2RfbGFiZWwgY2xhIG5tKSA6IGNsb3N1cmUpKVxuICAgICAgICh0b19hcnJheSBjb25jcl9tZXRocykgXVxuXG5sZXQgbWFrZV9jbGFzcyBwdWJfbWV0aHMgY2xhc3NfaW5pdCA9XG4gIGxldCB0YWJsZSA9IGNyZWF0ZV90YWJsZSBwdWJfbWV0aHMgaW5cbiAgbGV0IGVudl9pbml0ID0gY2xhc3NfaW5pdCB0YWJsZSBpblxuICBpbml0X2NsYXNzIHRhYmxlO1xuICAoZW52X2luaXQgKE9iai5yZXByIDApLCBjbGFzc19pbml0LCBlbnZfaW5pdCwgT2JqLnJlcHIgMClcblxudHlwZSBpbml0X3RhYmxlID0geyBtdXRhYmxlIGVudl9pbml0OiB0OyBtdXRhYmxlIGNsYXNzX2luaXQ6IHRhYmxlIC0+IHQgfVxuW0BAd2FybmluZyBcIi11bnVzZWQtZmllbGRcIl1cblxubGV0IG1ha2VfY2xhc3Nfc3RvcmUgcHViX21ldGhzIGNsYXNzX2luaXQgaW5pdF90YWJsZSA9XG4gIGxldCB0YWJsZSA9IGNyZWF0ZV90YWJsZSBwdWJfbWV0aHMgaW5cbiAgbGV0IGVudl9pbml0ID0gY2xhc3NfaW5pdCB0YWJsZSBpblxuICBpbml0X2NsYXNzIHRhYmxlO1xuICBpbml0X3RhYmxlLmNsYXNzX2luaXQgPC0gY2xhc3NfaW5pdDtcbiAgaW5pdF90YWJsZS5lbnZfaW5pdCA8LSBlbnZfaW5pdFxuXG5sZXQgZHVtbXlfY2xhc3MgbG9jID1cbiAgbGV0IHVuZGVmID0gZnVuIF8gLT4gcmFpc2UgKFVuZGVmaW5lZF9yZWN1cnNpdmVfbW9kdWxlIGxvYykgaW5cbiAgKE9iai5tYWdpYyB1bmRlZiwgdW5kZWYsIHVuZGVmLCBPYmoucmVwciAwKVxuXG4oKioqKiBPYmplY3RzICoqKiopXG5cbmxldCBjcmVhdGVfb2JqZWN0IHRhYmxlID1cbiAgKCogWFhYIEFwcGVsIGRlIFtvYmpfYmxvY2tdIHwgQ2FsbCB0byBbb2JqX2Jsb2NrXSAgKilcbiAgbGV0IG9iaiA9IE9iai5uZXdfYmxvY2sgT2JqLm9iamVjdF90YWcgdGFibGUuc2l6ZSBpblxuICAoKiBYWFggQXBwZWwgZGUgW2NhbWxfbW9kaWZ5XSB8IENhbGwgdG8gW2NhbWxfbW9kaWZ5XSAqKVxuICBPYmouc2V0X2ZpZWxkIG9iaiAwIChPYmoucmVwciB0YWJsZS5tZXRob2RzKTtcbiAgT2JqLm9iaiAoc2V0X2lkIG9iailcblxubGV0IGNyZWF0ZV9vYmplY3Rfb3B0IG9ial8wIHRhYmxlID1cbiAgaWYgKE9iai5tYWdpYyBvYmpfMCA6IGJvb2wpIHRoZW4gb2JqXzAgZWxzZSBiZWdpblxuICAgICgqIFhYWCBBcHBlbCBkZSBbb2JqX2Jsb2NrXSB8IENhbGwgdG8gW29ial9ibG9ja10gICopXG4gICAgbGV0IG9iaiA9IE9iai5uZXdfYmxvY2sgT2JqLm9iamVjdF90YWcgdGFibGUuc2l6ZSBpblxuICAgICgqIFhYWCBBcHBlbCBkZSBbY2FtbF9tb2RpZnldIHwgQ2FsbCB0byBbY2FtbF9tb2RpZnldICopXG4gICAgT2JqLnNldF9maWVsZCBvYmogMCAoT2JqLnJlcHIgdGFibGUubWV0aG9kcyk7XG4gICAgT2JqLm9iaiAoc2V0X2lkIG9iailcbiAgZW5kXG5cbmxldCByZWMgaXRlcl9mIG9iaiA9XG4gIGZ1bmN0aW9uXG4gICAgW10gICAtPiAoKVxuICB8IGY6OmwgLT4gZiBvYmo7IGl0ZXJfZiBvYmogbFxuXG5sZXQgcnVuX2luaXRpYWxpemVycyBvYmogdGFibGUgPVxuICBsZXQgaW5pdHMgPSB0YWJsZS5pbml0aWFsaXplcnMgaW5cbiAgaWYgaW5pdHMgPD4gW10gdGhlblxuICAgIGl0ZXJfZiBvYmogaW5pdHNcblxubGV0IHJ1bl9pbml0aWFsaXplcnNfb3B0IG9ial8wIG9iaiB0YWJsZSA9XG4gIGlmIChPYmoubWFnaWMgb2JqXzAgOiBib29sKSB0aGVuIG9iaiBlbHNlIGJlZ2luXG4gICAgbGV0IGluaXRzID0gdGFibGUuaW5pdGlhbGl6ZXJzIGluXG4gICAgaWYgaW5pdHMgPD4gW10gdGhlbiBpdGVyX2Ygb2JqIGluaXRzO1xuICAgIG9ialxuICBlbmRcblxubGV0IGNyZWF0ZV9vYmplY3RfYW5kX3J1bl9pbml0aWFsaXplcnMgb2JqXzAgdGFibGUgPVxuICBpZiAoT2JqLm1hZ2ljIG9ial8wIDogYm9vbCkgdGhlbiBvYmpfMCBlbHNlIGJlZ2luXG4gICAgbGV0IG9iaiA9IGNyZWF0ZV9vYmplY3QgdGFibGUgaW5cbiAgICBydW5faW5pdGlhbGl6ZXJzIG9iaiB0YWJsZTtcbiAgICBvYmpcbiAgZW5kXG5cbigqIEVxdWl2YWxlbnQgcHJpbWl0aXZlIGJlbG93XG5sZXQgc2VuZHNlbGYgb2JqIGxhYiA9XG4gIChtYWdpYyBvYmogOiAob2JqIC0+IHQpIGFycmF5IGFycmF5KS4oMCkuKGxhYikgb2JqXG4qKVxuZXh0ZXJuYWwgc2VuZCA6IG9iaiAtPiB0YWcgLT4gJ2EgPSBcIiVzZW5kXCJcbmV4dGVybmFsIHNlbmRjYWNoZSA6IG9iaiAtPiB0YWcgLT4gdCAtPiBpbnQgLT4gJ2EgPSBcIiVzZW5kY2FjaGVcIlxuZXh0ZXJuYWwgc2VuZHNlbGYgOiBvYmogLT4gbGFiZWwgLT4gJ2EgPSBcIiVzZW5kc2VsZlwiXG5leHRlcm5hbCBnZXRfcHVibGljX21ldGhvZCA6IG9iaiAtPiB0YWcgLT4gY2xvc3VyZVxuICAgID0gXCJjYW1sX2dldF9wdWJsaWNfbWV0aG9kXCIgW0BAbm9hbGxvY11cblxuKCoqKiogdGFibGUgY29sbGVjdGlvbiBhY2Nlc3MgKioqKilcblxudHlwZSB0YWJsZXMgPVxuICB8IEVtcHR5XG4gIHwgQ29ucyBvZiB7a2V5IDogY2xvc3VyZTsgbXV0YWJsZSBkYXRhOiB0YWJsZXM7IG11dGFibGUgbmV4dDogdGFibGVzfVxuXG5sZXQgc2V0X2RhdGEgdGFibGVzIHYgPSBtYXRjaCB0YWJsZXMgd2l0aFxuICB8IEVtcHR5IC0+IGFzc2VydCBmYWxzZVxuICB8IENvbnMgdGFibGVzIC0+IHRhYmxlcy5kYXRhIDwtIHZcbmxldCBzZXRfbmV4dCB0YWJsZXMgdiA9IG1hdGNoIHRhYmxlcyB3aXRoXG4gIHwgRW1wdHkgLT4gYXNzZXJ0IGZhbHNlXG4gIHwgQ29ucyB0YWJsZXMgLT4gdGFibGVzLm5leHQgPC0gdlxubGV0IGdldF9rZXkgPSBmdW5jdGlvblxuICB8IEVtcHR5IC0+IGFzc2VydCBmYWxzZVxuICB8IENvbnMgdGFibGVzIC0+IHRhYmxlcy5rZXlcbmxldCBnZXRfZGF0YSA9IGZ1bmN0aW9uXG4gIHwgRW1wdHkgLT4gYXNzZXJ0IGZhbHNlXG4gIHwgQ29ucyB0YWJsZXMgLT4gdGFibGVzLmRhdGFcbmxldCBnZXRfbmV4dCA9IGZ1bmN0aW9uXG4gIHwgRW1wdHkgLT4gYXNzZXJ0IGZhbHNlXG4gIHwgQ29ucyB0YWJsZXMgLT4gdGFibGVzLm5leHRcblxubGV0IGJ1aWxkX3BhdGggbiBrZXlzIHRhYmxlcyA9XG4gIGxldCByZXMgPSBDb25zIHtrZXkgPSBPYmoubWFnaWMgMDsgZGF0YSA9IEVtcHR5OyBuZXh0ID0gRW1wdHl9IGluXG4gIGxldCByID0gcmVmIHJlcyBpblxuICBmb3IgaSA9IDAgdG8gbiBkb1xuICAgIHIgOj0gQ29ucyB7a2V5ID0ga2V5cy4oaSk7IGRhdGEgPSAhcjsgbmV4dCA9IEVtcHR5fVxuICBkb25lO1xuICBzZXRfZGF0YSB0YWJsZXMgIXI7XG4gIHJlc1xuXG5sZXQgcmVjIGxvb2t1cF9rZXlzIGkga2V5cyB0YWJsZXMgPVxuICBpZiBpIDwgMCB0aGVuIHRhYmxlcyBlbHNlXG4gIGxldCBrZXkgPSBrZXlzLihpKSBpblxuICBsZXQgcmVjIGxvb2t1cF9rZXkgKHRhYmxlczp0YWJsZXMpID1cbiAgICBpZiBnZXRfa2V5IHRhYmxlcyA9PSBrZXkgdGhlblxuICAgICAgbWF0Y2ggZ2V0X2RhdGEgdGFibGVzIHdpdGhcbiAgICAgIHwgRW1wdHkgLT4gYXNzZXJ0IGZhbHNlXG4gICAgICB8IENvbnMgXyBhcyB0YWJsZXNfZGF0YSAtPlxuICAgICAgICAgIGxvb2t1cF9rZXlzIChpLTEpIGtleXMgdGFibGVzX2RhdGFcbiAgICBlbHNlXG4gICAgICBtYXRjaCBnZXRfbmV4dCB0YWJsZXMgd2l0aFxuICAgICAgfCBDb25zIF8gYXMgbmV4dCAtPiBsb29rdXBfa2V5IG5leHRcbiAgICAgIHwgRW1wdHkgLT5cbiAgICAgICAgICBsZXQgbmV4dCA6IHRhYmxlcyA9IENvbnMge2tleTsgZGF0YSA9IEVtcHR5OyBuZXh0ID0gRW1wdHl9IGluXG4gICAgICAgICAgc2V0X25leHQgdGFibGVzIG5leHQ7XG4gICAgICAgICAgYnVpbGRfcGF0aCAoaS0xKSBrZXlzIG5leHRcbiAgaW5cbiAgbG9va3VwX2tleSB0YWJsZXNcblxubGV0IGxvb2t1cF90YWJsZXMgcm9vdCBrZXlzID1cbiAgbWF0Y2ggZ2V0X2RhdGEgcm9vdCB3aXRoXG4gIHwgQ29ucyBfIGFzIHJvb3RfZGF0YSAtPlxuICAgIGxvb2t1cF9rZXlzIChBcnJheS5sZW5ndGgga2V5cyAtIDEpIGtleXMgcm9vdF9kYXRhXG4gIHwgRW1wdHkgLT5cbiAgICBidWlsZF9wYXRoIChBcnJheS5sZW5ndGgga2V5cyAtIDEpIGtleXMgcm9vdFxuXG4oKioqKiBidWlsdGluIG1ldGhvZHMgKioqKilcblxubGV0IGdldF9jb25zdCB4ID0gcmV0IChmdW4gX29iaiAtPiB4KVxubGV0IGdldF92YXIgbiAgID0gcmV0IChmdW4gb2JqIC0+IEFycmF5LnVuc2FmZV9nZXQgb2JqIG4pXG5sZXQgZ2V0X2VudiBlIG4gPVxuICByZXQgKGZ1biBvYmogLT5cbiAgICBBcnJheS51bnNhZmVfZ2V0IChPYmoubWFnaWMgKEFycmF5LnVuc2FmZV9nZXQgb2JqIGUpIDogb2JqKSBuKVxubGV0IGdldF9tZXRoIG4gID0gcmV0IChmdW4gb2JqIC0+IHNlbmRzZWxmIG9iaiBuKVxubGV0IHNldF92YXIgbiAgID0gcmV0IChmdW4gb2JqIHggLT4gQXJyYXkudW5zYWZlX3NldCBvYmogbiB4KVxubGV0IGFwcF9jb25zdCBmIHggPSByZXQgKGZ1biBfb2JqIC0+IGYgeClcbmxldCBhcHBfdmFyIGYgbiAgID0gcmV0IChmdW4gb2JqIC0+IGYgKEFycmF5LnVuc2FmZV9nZXQgb2JqIG4pKVxubGV0IGFwcF9lbnYgZiBlIG4gPVxuICByZXQgKGZ1biBvYmogLT5cbiAgICBmIChBcnJheS51bnNhZmVfZ2V0IChPYmoubWFnaWMgKEFycmF5LnVuc2FmZV9nZXQgb2JqIGUpIDogb2JqKSBuKSlcbmxldCBhcHBfbWV0aCBmIG4gID0gcmV0IChmdW4gb2JqIC0+IGYgKHNlbmRzZWxmIG9iaiBuKSlcbmxldCBhcHBfY29uc3RfY29uc3QgZiB4IHkgPSByZXQgKGZ1biBfb2JqIC0+IGYgeCB5KVxubGV0IGFwcF9jb25zdF92YXIgZiB4IG4gICA9IHJldCAoZnVuIG9iaiAtPiBmIHggKEFycmF5LnVuc2FmZV9nZXQgb2JqIG4pKVxubGV0IGFwcF9jb25zdF9tZXRoIGYgeCBuID0gcmV0IChmdW4gb2JqIC0+IGYgeCAoc2VuZHNlbGYgb2JqIG4pKVxubGV0IGFwcF92YXJfY29uc3QgZiBuIHggPSByZXQgKGZ1biBvYmogLT4gZiAoQXJyYXkudW5zYWZlX2dldCBvYmogbikgeClcbmxldCBhcHBfbWV0aF9jb25zdCBmIG4geCA9IHJldCAoZnVuIG9iaiAtPiBmIChzZW5kc2VsZiBvYmogbikgeClcbmxldCBhcHBfY29uc3RfZW52IGYgeCBlIG4gPVxuICByZXQgKGZ1biBvYmogLT5cbiAgICBmIHggKEFycmF5LnVuc2FmZV9nZXQgKE9iai5tYWdpYyAoQXJyYXkudW5zYWZlX2dldCBvYmogZSkgOiBvYmopIG4pKVxubGV0IGFwcF9lbnZfY29uc3QgZiBlIG4geCA9XG4gIHJldCAoZnVuIG9iaiAtPlxuICAgIGYgKEFycmF5LnVuc2FmZV9nZXQgKE9iai5tYWdpYyAoQXJyYXkudW5zYWZlX2dldCBvYmogZSkgOiBvYmopIG4pIHgpXG5sZXQgbWV0aF9hcHBfY29uc3QgbiB4ID0gcmV0IChmdW4gb2JqIC0+IChzZW5kc2VsZiBvYmogbiA6IF8gLT4gXykgeClcbmxldCBtZXRoX2FwcF92YXIgbiBtID1cbiAgcmV0IChmdW4gb2JqIC0+IChzZW5kc2VsZiBvYmogbiA6IF8gLT4gXykgKEFycmF5LnVuc2FmZV9nZXQgb2JqIG0pKVxubGV0IG1ldGhfYXBwX2VudiBuIGUgbSA9XG4gIHJldCAoZnVuIG9iaiAtPiAoc2VuZHNlbGYgb2JqIG4gOiBfIC0+IF8pXG4gICAgICAoQXJyYXkudW5zYWZlX2dldCAoT2JqLm1hZ2ljIChBcnJheS51bnNhZmVfZ2V0IG9iaiBlKSA6IG9iaikgbSkpXG5sZXQgbWV0aF9hcHBfbWV0aCBuIG0gPVxuICByZXQgKGZ1biBvYmogLT4gKHNlbmRzZWxmIG9iaiBuIDogXyAtPiBfKSAoc2VuZHNlbGYgb2JqIG0pKVxubGV0IHNlbmRfY29uc3QgbSB4IGMgPVxuICByZXQgKGZ1biBvYmogLT4gc2VuZGNhY2hlIHggbSAoQXJyYXkudW5zYWZlX2dldCBvYmogMCkgYylcbmxldCBzZW5kX3ZhciBtIG4gYyA9XG4gIHJldCAoZnVuIG9iaiAtPlxuICAgIHNlbmRjYWNoZSAoT2JqLm1hZ2ljIChBcnJheS51bnNhZmVfZ2V0IG9iaiBuKSA6IG9iaikgbVxuICAgICAgKEFycmF5LnVuc2FmZV9nZXQgb2JqIDApIGMpXG5sZXQgc2VuZF9lbnYgbSBlIG4gYyA9XG4gIHJldCAoZnVuIG9iaiAtPlxuICAgIHNlbmRjYWNoZVxuICAgICAgKE9iai5tYWdpYyAoQXJyYXkudW5zYWZlX2dldFxuICAgICAgICAgICAgICAgICAgICAoT2JqLm1hZ2ljIChBcnJheS51bnNhZmVfZ2V0IG9iaiBlKSA6IG9iaikgbikgOiBvYmopXG4gICAgICBtIChBcnJheS51bnNhZmVfZ2V0IG9iaiAwKSBjKVxubGV0IHNlbmRfbWV0aCBtIG4gYyA9XG4gIHJldCAoZnVuIG9iaiAtPlxuICAgIHNlbmRjYWNoZSAoc2VuZHNlbGYgb2JqIG4pIG0gKEFycmF5LnVuc2FmZV9nZXQgb2JqIDApIGMpXG5sZXQgbmV3X2NhY2hlIHRhYmxlID1cbiAgbGV0IG4gPSBuZXdfbWV0aG9kIHRhYmxlIGluXG4gIGxldCBuID1cbiAgICBpZiBuIG1vZCAyID0gMCB8fCBuID4gMiArIG1hZ2ljIHRhYmxlLm1ldGhvZHMuKDEpICogMTYgLyBTeXMud29yZF9zaXplXG4gICAgdGhlbiBuIGVsc2UgbmV3X21ldGhvZCB0YWJsZVxuICBpblxuICB0YWJsZS5tZXRob2RzLihuKSA8LSBPYmoubWFnaWMgMDtcbiAgblxuXG50eXBlIGltcGwgPVxuICAgIEdldENvbnN0XG4gIHwgR2V0VmFyXG4gIHwgR2V0RW52XG4gIHwgR2V0TWV0aFxuICB8IFNldFZhclxuICB8IEFwcENvbnN0XG4gIHwgQXBwVmFyXG4gIHwgQXBwRW52XG4gIHwgQXBwTWV0aFxuICB8IEFwcENvbnN0Q29uc3RcbiAgfCBBcHBDb25zdFZhclxuICB8IEFwcENvbnN0RW52XG4gIHwgQXBwQ29uc3RNZXRoXG4gIHwgQXBwVmFyQ29uc3RcbiAgfCBBcHBFbnZDb25zdFxuICB8IEFwcE1ldGhDb25zdFxuICB8IE1ldGhBcHBDb25zdFxuICB8IE1ldGhBcHBWYXJcbiAgfCBNZXRoQXBwRW52XG4gIHwgTWV0aEFwcE1ldGhcbiAgfCBTZW5kQ29uc3RcbiAgfCBTZW5kVmFyXG4gIHwgU2VuZEVudlxuICB8IFNlbmRNZXRoXG4gIHwgQ2xvc3VyZSBvZiBjbG9zdXJlXG5cbmxldCBtZXRob2RfaW1wbCB0YWJsZSBpIGFyciA9XG4gIGxldCBuZXh0ICgpID0gaW5jciBpOyBtYWdpYyBhcnIuKCFpKSBpblxuICBtYXRjaCBuZXh0KCkgd2l0aFxuICAgIEdldENvbnN0IC0+IGxldCB4IDogdCA9IG5leHQoKSBpbiBnZXRfY29uc3QgeFxuICB8IEdldFZhciAgIC0+IGxldCBuID0gbmV4dCgpIGluIGdldF92YXIgblxuICB8IEdldEVudiAgIC0+IGxldCBlID0gbmV4dCgpIGluIGxldCBuID0gbmV4dCgpIGluIGdldF9lbnYgZSBuXG4gIHwgR2V0TWV0aCAgLT4gbGV0IG4gPSBuZXh0KCkgaW4gZ2V0X21ldGggblxuICB8IFNldFZhciAgIC0+IGxldCBuID0gbmV4dCgpIGluIHNldF92YXIgblxuICB8IEFwcENvbnN0IC0+IGxldCBmID0gbmV4dCgpIGluIGxldCB4ID0gbmV4dCgpIGluIGFwcF9jb25zdCBmIHhcbiAgfCBBcHBWYXIgICAtPiBsZXQgZiA9IG5leHQoKSBpbiBsZXQgbiA9IG5leHQgKCkgaW4gYXBwX3ZhciBmIG5cbiAgfCBBcHBFbnYgICAtPlxuICAgICAgbGV0IGYgPSBuZXh0KCkgaW4gIGxldCBlID0gbmV4dCgpIGluIGxldCBuID0gbmV4dCgpIGluXG4gICAgICBhcHBfZW52IGYgZSBuXG4gIHwgQXBwTWV0aCAgLT4gbGV0IGYgPSBuZXh0KCkgaW4gbGV0IG4gPSBuZXh0ICgpIGluIGFwcF9tZXRoIGYgblxuICB8IEFwcENvbnN0Q29uc3QgLT5cbiAgICAgIGxldCBmID0gbmV4dCgpIGluIGxldCB4ID0gbmV4dCgpIGluIGxldCB5ID0gbmV4dCgpIGluXG4gICAgICBhcHBfY29uc3RfY29uc3QgZiB4IHlcbiAgfCBBcHBDb25zdFZhciAtPlxuICAgICAgbGV0IGYgPSBuZXh0KCkgaW4gbGV0IHggPSBuZXh0KCkgaW4gbGV0IG4gPSBuZXh0KCkgaW5cbiAgICAgIGFwcF9jb25zdF92YXIgZiB4IG5cbiAgfCBBcHBDb25zdEVudiAtPlxuICAgICAgbGV0IGYgPSBuZXh0KCkgaW4gbGV0IHggPSBuZXh0KCkgaW4gbGV0IGUgPSBuZXh0ICgpIGluIGxldCBuID0gbmV4dCgpIGluXG4gICAgICBhcHBfY29uc3RfZW52IGYgeCBlIG5cbiAgfCBBcHBDb25zdE1ldGggLT5cbiAgICAgIGxldCBmID0gbmV4dCgpIGluIGxldCB4ID0gbmV4dCgpIGluIGxldCBuID0gbmV4dCgpIGluXG4gICAgICBhcHBfY29uc3RfbWV0aCBmIHggblxuICB8IEFwcFZhckNvbnN0IC0+XG4gICAgICBsZXQgZiA9IG5leHQoKSBpbiBsZXQgbiA9IG5leHQoKSBpbiBsZXQgeCA9IG5leHQoKSBpblxuICAgICAgYXBwX3Zhcl9jb25zdCBmIG4geFxuICB8IEFwcEVudkNvbnN0IC0+XG4gICAgICBsZXQgZiA9IG5leHQoKSBpbiBsZXQgZSA9IG5leHQgKCkgaW4gbGV0IG4gPSBuZXh0KCkgaW4gbGV0IHggPSBuZXh0KCkgaW5cbiAgICAgIGFwcF9lbnZfY29uc3QgZiBlIG4geFxuICB8IEFwcE1ldGhDb25zdCAtPlxuICAgICAgbGV0IGYgPSBuZXh0KCkgaW4gbGV0IG4gPSBuZXh0KCkgaW4gbGV0IHggPSBuZXh0KCkgaW5cbiAgICAgIGFwcF9tZXRoX2NvbnN0IGYgbiB4XG4gIHwgTWV0aEFwcENvbnN0IC0+XG4gICAgICBsZXQgbiA9IG5leHQoKSBpbiBsZXQgeCA9IG5leHQoKSBpbiBtZXRoX2FwcF9jb25zdCBuIHhcbiAgfCBNZXRoQXBwVmFyIC0+XG4gICAgICBsZXQgbiA9IG5leHQoKSBpbiBsZXQgbSA9IG5leHQoKSBpbiBtZXRoX2FwcF92YXIgbiBtXG4gIHwgTWV0aEFwcEVudiAtPlxuICAgICAgbGV0IG4gPSBuZXh0KCkgaW4gbGV0IGUgPSBuZXh0KCkgaW4gbGV0IG0gPSBuZXh0KCkgaW5cbiAgICAgIG1ldGhfYXBwX2VudiBuIGUgbVxuICB8IE1ldGhBcHBNZXRoIC0+XG4gICAgICBsZXQgbiA9IG5leHQoKSBpbiBsZXQgbSA9IG5leHQoKSBpbiBtZXRoX2FwcF9tZXRoIG4gbVxuICB8IFNlbmRDb25zdCAtPlxuICAgICAgbGV0IG0gPSBuZXh0KCkgaW4gbGV0IHggPSBuZXh0KCkgaW4gc2VuZF9jb25zdCBtIHggKG5ld19jYWNoZSB0YWJsZSlcbiAgfCBTZW5kVmFyIC0+XG4gICAgICBsZXQgbSA9IG5leHQoKSBpbiBsZXQgbiA9IG5leHQgKCkgaW4gc2VuZF92YXIgbSBuIChuZXdfY2FjaGUgdGFibGUpXG4gIHwgU2VuZEVudiAtPlxuICAgICAgbGV0IG0gPSBuZXh0KCkgaW4gbGV0IGUgPSBuZXh0KCkgaW4gbGV0IG4gPSBuZXh0KCkgaW5cbiAgICAgIHNlbmRfZW52IG0gZSBuIChuZXdfY2FjaGUgdGFibGUpXG4gIHwgU2VuZE1ldGggLT5cbiAgICAgIGxldCBtID0gbmV4dCgpIGluIGxldCBuID0gbmV4dCAoKSBpbiBzZW5kX21ldGggbSBuIChuZXdfY2FjaGUgdGFibGUpXG4gIHwgQ2xvc3VyZSBfIGFzIGNsbyAtPiBtYWdpYyBjbG9cblxubGV0IHNldF9tZXRob2RzIHRhYmxlIG1ldGhvZHMgPVxuICBsZXQgbGVuID0gQXJyYXkubGVuZ3RoIG1ldGhvZHMgaW4gbGV0IGkgPSByZWYgMCBpblxuICB3aGlsZSAhaSA8IGxlbiBkb1xuICAgIGxldCBsYWJlbCA9IG1ldGhvZHMuKCFpKSBpbiBsZXQgY2xvID0gbWV0aG9kX2ltcGwgdGFibGUgaSBtZXRob2RzIGluXG4gICAgc2V0X21ldGhvZCB0YWJsZSBsYWJlbCBjbG87XG4gICAgaW5jciBpXG4gIGRvbmVcblxuKCoqKiogU3RhdGlzdGljcyAqKioqKVxuXG50eXBlIHN0YXRzID1cbiAgeyBjbGFzc2VzOiBpbnQ7IG1ldGhvZHM6IGludDsgaW5zdF92YXJzOiBpbnQ7IH1cblxubGV0IHN0YXRzICgpID1cbiAgeyBjbGFzc2VzID0gIXRhYmxlX2NvdW50O1xuICAgIG1ldGhvZHMgPSAhbWV0aG9kX2NvdW50OyBpbnN0X3ZhcnMgPSAhaW5zdF92YXJfY291bnQ7IH1cbiIsIigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0NhbWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgIFhhdmllciBMZXJveSwgcHJvamV0IENyaXN0YWwsIElOUklBIFJvY3F1ZW5jb3VydCAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQ29weXJpZ2h0IDIwMDQgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCAgICAgKilcbigqICAgICBlbiBBdXRvbWF0aXF1ZS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQWxsIHJpZ2h0cyByZXNlcnZlZC4gIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgICAgKilcbigqICAgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIuMSwgd2l0aCB0aGUgICAgICAgICAgKilcbigqICAgc3BlY2lhbCBleGNlcHRpb24gb24gbGlua2luZyBkZXNjcmliZWQgaW4gdGhlIGZpbGUgTElDRU5TRS4gICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcblxudHlwZSBzaGFwZSA9XG4gIHwgRnVuY3Rpb25cbiAgfCBMYXp5XG4gIHwgQ2xhc3NcbiAgfCBNb2R1bGUgb2Ygc2hhcGUgYXJyYXlcbiAgfCBWYWx1ZSBvZiBPYmoudFxuXG5sZXQgcmVjIGluaXRfbW9kX2ZpZWxkIG1vZHUgaSBsb2Mgc2hhcGUgPVxuICBsZXQgaW5pdCA9XG4gICAgbWF0Y2ggc2hhcGUgd2l0aFxuICAgIHwgRnVuY3Rpb24gLT5cbiAgICAgICBsZXQgcmVjIGZuICh4IDogJ2EpID1cbiAgICAgICAgIGxldCBmbicgOiAnYSAtPiAnYiA9IE9iai5vYmogKE9iai5maWVsZCBtb2R1IGkpIGluXG4gICAgICAgICBpZiBmbiA9PSBmbicgdGhlblxuICAgICAgICAgICByYWlzZSAoVW5kZWZpbmVkX3JlY3Vyc2l2ZV9tb2R1bGUgbG9jKVxuICAgICAgICAgZWxzZVxuICAgICAgICAgICBmbicgeCBpblxuICAgICAgIE9iai5yZXByIGZuXG4gICAgfCBMYXp5IC0+XG4gICAgICAgbGV0IHJlYyBsID1cbiAgICAgICAgIGxhenkgKFxuICAgICAgICAgICBsZXQgbCcgPSBPYmoub2JqIChPYmouZmllbGQgbW9kdSBpKSBpblxuICAgICAgICAgICBpZiBsID09IGwnIHRoZW5cbiAgICAgICAgICAgICByYWlzZSAoVW5kZWZpbmVkX3JlY3Vyc2l2ZV9tb2R1bGUgbG9jKVxuICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgTGF6eS5mb3JjZSBsJykgaW5cbiAgICAgICBPYmoucmVwciBsXG4gICAgfCBDbGFzcyAtPlxuICAgICAgIE9iai5yZXByIChDYW1saW50ZXJuYWxPTy5kdW1teV9jbGFzcyBsb2MpXG4gICAgfCBNb2R1bGUgY29tcHMgLT5cbiAgICAgICBPYmoucmVwciAoaW5pdF9tb2RfYmxvY2sgbG9jIGNvbXBzKVxuICAgIHwgVmFsdWUgdiAtPiB2XG4gIGluXG4gIE9iai5zZXRfZmllbGQgbW9kdSBpIGluaXRcblxuYW5kIGluaXRfbW9kX2Jsb2NrIGxvYyBjb21wcyA9XG4gIGxldCBsZW5ndGggPSBBcnJheS5sZW5ndGggY29tcHMgaW5cbiAgbGV0IG1vZHUgPSBPYmoubmV3X2Jsb2NrIDAgbGVuZ3RoIGluXG4gIGZvciBpID0gMCB0byBsZW5ndGggLSAxIGRvXG4gICAgaW5pdF9tb2RfZmllbGQgbW9kdSBpIGxvYyBjb21wcy4oaSlcbiAgZG9uZTtcbiAgbW9kdVxuXG5sZXQgaW5pdF9tb2QgbG9jIHNoYXBlID1cbiAgbWF0Y2ggc2hhcGUgd2l0aFxuICB8IE1vZHVsZSBjb21wcyAtPlxuICAgICBPYmoucmVwciAoaW5pdF9tb2RfYmxvY2sgbG9jIGNvbXBzKVxuICB8IF8gLT4gZmFpbHdpdGggXCJDYW1saW50ZXJuYWxNb2QuaW5pdF9tb2Q6IG5vdCBhIG1vZHVsZVwiXG5cbmxldCByZWMgdXBkYXRlX21vZF9maWVsZCBtb2R1IGkgc2hhcGUgbiA9XG4gIG1hdGNoIHNoYXBlIHdpdGhcbiAgfCBGdW5jdGlvbiB8IExhenkgLT5cbiAgICAgT2JqLnNldF9maWVsZCBtb2R1IGkgblxuICB8IFZhbHVlIF8gLT5cbiAgICAgKCkgKCogdGhlIHZhbHVlIGlzIGFscmVhZHkgdGhlcmUgKilcbiAgfCBDbGFzcyAtPlxuICAgICBhc3NlcnQgKE9iai50YWcgbiA9IDAgJiYgT2JqLnNpemUgbiA9IDQpO1xuICAgICBsZXQgY2wgPSBPYmouZmllbGQgbW9kdSBpIGluXG4gICAgIGZvciBqID0gMCB0byAzIGRvXG4gICAgICAgT2JqLnNldF9maWVsZCBjbCBqIChPYmouZmllbGQgbiBqKVxuICAgICBkb25lXG4gIHwgTW9kdWxlIGNvbXBzIC0+XG4gICAgIHVwZGF0ZV9tb2RfYmxvY2sgY29tcHMgKE9iai5maWVsZCBtb2R1IGkpIG5cblxuYW5kIHVwZGF0ZV9tb2RfYmxvY2sgY29tcHMgbyBuID1cbiAgYXNzZXJ0IChPYmoudGFnIG4gPSAwICYmIE9iai5zaXplIG4gPj0gQXJyYXkubGVuZ3RoIGNvbXBzKTtcbiAgZm9yIGkgPSAwIHRvIEFycmF5Lmxlbmd0aCBjb21wcyAtIDEgZG9cbiAgICB1cGRhdGVfbW9kX2ZpZWxkIG8gaSBjb21wcy4oaSkgKE9iai5maWVsZCBuIGkpXG4gIGRvbmVcblxubGV0IHVwZGF0ZV9tb2Qgc2hhcGUgbyBuID1cbiAgbWF0Y2ggc2hhcGUgd2l0aFxuICB8IE1vZHVsZSBjb21wcyAtPlxuICAgICB1cGRhdGVfbW9kX2Jsb2NrIGNvbXBzIG8gblxuICB8IF8gLT4gZmFpbHdpdGggXCJDYW1saW50ZXJuYWxNb2QudXBkYXRlX21vZDogbm90IGEgbW9kdWxlXCJcbiIsIigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0NhbWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgWGF2aWVyIExlcm95LCBwcm9qZXQgQ3Jpc3RhbCwgSU5SSUEgUm9jcXVlbmNvdXJ0ICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQ29weXJpZ2h0IDE5OTYgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCAgICAgKilcbigqICAgICBlbiBBdXRvbWF0aXF1ZS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQWxsIHJpZ2h0cyByZXNlcnZlZC4gIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgICAgKilcbigqICAgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIuMSwgd2l0aCB0aGUgICAgICAgICAgKilcbigqICAgc3BlY2lhbCBleGNlcHRpb24gb24gbGlua2luZyBkZXNjcmliZWQgaW4gdGhlIGZpbGUgTElDRU5TRS4gICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcblxudHlwZSB0b2tlbiA9XG4gICAgS3dkIG9mIHN0cmluZ1xuICB8IElkZW50IG9mIHN0cmluZ1xuICB8IEludCBvZiBpbnRcbiAgfCBGbG9hdCBvZiBmbG9hdFxuICB8IFN0cmluZyBvZiBzdHJpbmdcbiAgfCBDaGFyIG9mIGNoYXJcblxuKCogVGhlIHN0cmluZyBidWZmZXJpbmcgbWFjaGluZXJ5ICopXG5cbmxldCBpbml0aWFsX2J1ZmZlciA9IEJ5dGVzLmNyZWF0ZSAzMlxuXG5sZXQgYnVmZmVyID0gcmVmIGluaXRpYWxfYnVmZmVyXG5sZXQgYnVmcG9zID0gcmVmIDBcblxubGV0IHJlc2V0X2J1ZmZlciAoKSA9IGJ1ZmZlciA6PSBpbml0aWFsX2J1ZmZlcjsgYnVmcG9zIDo9IDBcblxubGV0IHN0b3JlIGMgPVxuICBpZiAhYnVmcG9zID49IEJ5dGVzLmxlbmd0aCAhYnVmZmVyIHRoZW4gYmVnaW5cbiAgICBsZXQgbmV3YnVmZmVyID0gQnl0ZXMuY3JlYXRlICgyICogIWJ1ZnBvcykgaW5cbiAgICBCeXRlcy5ibGl0ICFidWZmZXIgMCBuZXdidWZmZXIgMCAhYnVmcG9zO1xuICAgIGJ1ZmZlciA6PSBuZXdidWZmZXJcbiAgZW5kO1xuICBCeXRlcy5zZXQgIWJ1ZmZlciAhYnVmcG9zIGM7XG4gIGluY3IgYnVmcG9zXG5cbmxldCBnZXRfc3RyaW5nICgpID1cbiAgbGV0IHMgPSBCeXRlcy5zdWJfc3RyaW5nICFidWZmZXIgMCAhYnVmcG9zIGluIGJ1ZmZlciA6PSBpbml0aWFsX2J1ZmZlcjsgc1xuXG4oKiBUaGUgbGV4ZXIgKilcblxubGV0IG1ha2VfbGV4ZXIga2V5d29yZHMgPVxuICBsZXQga3dkX3RhYmxlID0gSGFzaHRibC5jcmVhdGUgMTcgaW5cbiAgTGlzdC5pdGVyIChmdW4gcyAtPiBIYXNodGJsLmFkZCBrd2RfdGFibGUgcyAoS3dkIHMpKSBrZXl3b3JkcztcbiAgbGV0IGlkZW50X29yX2tleXdvcmQgaWQgPVxuICAgIHRyeSBIYXNodGJsLmZpbmQga3dkX3RhYmxlIGlkIHdpdGhcbiAgICAgIE5vdF9mb3VuZCAtPiBJZGVudCBpZFxuICBhbmQga2V5d29yZF9vcl9lcnJvciBjID1cbiAgICBsZXQgcyA9IFN0cmluZy5tYWtlIDEgYyBpblxuICAgIHRyeSBIYXNodGJsLmZpbmQga3dkX3RhYmxlIHMgd2l0aFxuICAgICAgTm90X2ZvdW5kIC0+IHJhaXNlIChTdHJlYW0uRXJyb3IgKFwiSWxsZWdhbCBjaGFyYWN0ZXIgXCIgXiBzKSlcbiAgaW5cbiAgbGV0IHJlYyBuZXh0X3Rva2VuIChzdHJtX18gOiBfIFN0cmVhbS50KSA9XG4gICAgbWF0Y2ggU3RyZWFtLnBlZWsgc3RybV9fIHdpdGhcbiAgICAgIFNvbWUgKCcgJyB8ICdcXDAxMCcgfCAnXFwwMTMnIHwgJ1xcMDA5JyB8ICdcXDAyNicgfCAnXFwwMTInKSAtPlxuICAgICAgICBTdHJlYW0uanVuayBzdHJtX187IG5leHRfdG9rZW4gc3RybV9fXG4gICAgfCBTb21lICgnQScuLidaJyB8ICdhJy4uJ3onIHwgJ18nIHwgJ1xcMTkyJy4uJ1xcMjU1JyBhcyBjKSAtPlxuICAgICAgICBTdHJlYW0uanVuayBzdHJtX187XG4gICAgICAgIGxldCBzID0gc3RybV9fIGluIHJlc2V0X2J1ZmZlciAoKTsgc3RvcmUgYzsgaWRlbnQgc1xuICAgIHwgU29tZVxuICAgICAgICAoJyEnIHwgJyUnIHwgJyYnIHwgJyQnIHwgJyMnIHwgJysnIHwgJy8nIHwgJzonIHwgJzwnIHwgJz0nIHwgJz4nIHxcbiAgICAgICAgICc/JyB8ICdAJyB8ICdcXFxcJyB8ICd+JyB8ICdeJyB8ICd8JyB8ICcqJyBhcyBjKSAtPlxuICAgICAgICBTdHJlYW0uanVuayBzdHJtX187XG4gICAgICAgIGxldCBzID0gc3RybV9fIGluIHJlc2V0X2J1ZmZlciAoKTsgc3RvcmUgYzsgaWRlbnQyIHNcbiAgICB8IFNvbWUgKCcwJy4uJzknIGFzIGMpIC0+XG4gICAgICAgIFN0cmVhbS5qdW5rIHN0cm1fXztcbiAgICAgICAgbGV0IHMgPSBzdHJtX18gaW4gcmVzZXRfYnVmZmVyICgpOyBzdG9yZSBjOyBudW1iZXIgc1xuICAgIHwgU29tZSAnXFwnJyAtPlxuICAgICAgICBTdHJlYW0uanVuayBzdHJtX187XG4gICAgICAgIGxldCBjID1cbiAgICAgICAgICB0cnkgY2hhciBzdHJtX18gd2l0aFxuICAgICAgICAgICAgU3RyZWFtLkZhaWx1cmUgLT4gcmFpc2UgKFN0cmVhbS5FcnJvciBcIlwiKVxuICAgICAgICBpblxuICAgICAgICBiZWdpbiBtYXRjaCBTdHJlYW0ucGVlayBzdHJtX18gd2l0aFxuICAgICAgICAgIFNvbWUgJ1xcJycgLT4gU3RyZWFtLmp1bmsgc3RybV9fOyBTb21lIChDaGFyIGMpXG4gICAgICAgIHwgXyAtPiByYWlzZSAoU3RyZWFtLkVycm9yIFwiXCIpXG4gICAgICAgIGVuZFxuICAgIHwgU29tZSAnXFxcIicgLT5cbiAgICAgICAgU3RyZWFtLmp1bmsgc3RybV9fO1xuICAgICAgICBsZXQgcyA9IHN0cm1fXyBpbiByZXNldF9idWZmZXIgKCk7IFNvbWUgKFN0cmluZyAoc3RyaW5nIHMpKVxuICAgIHwgU29tZSAnLScgLT4gU3RyZWFtLmp1bmsgc3RybV9fOyBuZWdfbnVtYmVyIHN0cm1fX1xuICAgIHwgU29tZSAnKCcgLT4gU3RyZWFtLmp1bmsgc3RybV9fOyBtYXliZV9jb21tZW50IHN0cm1fX1xuICAgIHwgU29tZSBjIC0+IFN0cmVhbS5qdW5rIHN0cm1fXzsgU29tZSAoa2V5d29yZF9vcl9lcnJvciBjKVxuICAgIHwgXyAtPiBOb25lXG4gIGFuZCBpZGVudCAoc3RybV9fIDogXyBTdHJlYW0udCkgPVxuICAgIG1hdGNoIFN0cmVhbS5wZWVrIHN0cm1fXyB3aXRoXG4gICAgICBTb21lXG4gICAgICAgICgnQScuLidaJyB8ICdhJy4uJ3onIHwgJ1xcMTkyJy4uJ1xcMjU1JyB8ICcwJy4uJzknIHwgJ18nIHwgJ1xcJycgYXMgYykgLT5cbiAgICAgICAgU3RyZWFtLmp1bmsgc3RybV9fOyBsZXQgcyA9IHN0cm1fXyBpbiBzdG9yZSBjOyBpZGVudCBzXG4gICAgfCBfIC0+IFNvbWUgKGlkZW50X29yX2tleXdvcmQgKGdldF9zdHJpbmcgKCkpKVxuICBhbmQgaWRlbnQyIChzdHJtX18gOiBfIFN0cmVhbS50KSA9XG4gICAgbWF0Y2ggU3RyZWFtLnBlZWsgc3RybV9fIHdpdGhcbiAgICAgIFNvbWVcbiAgICAgICAgKCchJyB8ICclJyB8ICcmJyB8ICckJyB8ICcjJyB8ICcrJyB8ICctJyB8ICcvJyB8ICc6JyB8ICc8JyB8ICc9JyB8XG4gICAgICAgICAnPicgfCAnPycgfCAnQCcgfCAnXFxcXCcgfCAnficgfCAnXicgfCAnfCcgfCAnKicgYXMgYykgLT5cbiAgICAgICAgU3RyZWFtLmp1bmsgc3RybV9fOyBsZXQgcyA9IHN0cm1fXyBpbiBzdG9yZSBjOyBpZGVudDIgc1xuICAgIHwgXyAtPiBTb21lIChpZGVudF9vcl9rZXl3b3JkIChnZXRfc3RyaW5nICgpKSlcbiAgYW5kIG5lZ19udW1iZXIgKHN0cm1fXyA6IF8gU3RyZWFtLnQpID1cbiAgICBtYXRjaCBTdHJlYW0ucGVlayBzdHJtX18gd2l0aFxuICAgICAgU29tZSAoJzAnLi4nOScgYXMgYykgLT5cbiAgICAgICAgU3RyZWFtLmp1bmsgc3RybV9fO1xuICAgICAgICBsZXQgcyA9IHN0cm1fXyBpbiByZXNldF9idWZmZXIgKCk7IHN0b3JlICctJzsgc3RvcmUgYzsgbnVtYmVyIHNcbiAgICB8IF8gLT4gbGV0IHMgPSBzdHJtX18gaW4gcmVzZXRfYnVmZmVyICgpOyBzdG9yZSAnLSc7IGlkZW50MiBzXG4gIGFuZCBudW1iZXIgKHN0cm1fXyA6IF8gU3RyZWFtLnQpID1cbiAgICBtYXRjaCBTdHJlYW0ucGVlayBzdHJtX18gd2l0aFxuICAgICAgU29tZSAoJzAnLi4nOScgYXMgYykgLT5cbiAgICAgICAgU3RyZWFtLmp1bmsgc3RybV9fOyBsZXQgcyA9IHN0cm1fXyBpbiBzdG9yZSBjOyBudW1iZXIgc1xuICAgIHwgU29tZSAnLicgLT5cbiAgICAgICAgU3RyZWFtLmp1bmsgc3RybV9fOyBsZXQgcyA9IHN0cm1fXyBpbiBzdG9yZSAnLic7IGRlY2ltYWxfcGFydCBzXG4gICAgfCBTb21lICgnZScgfCAnRScpIC0+XG4gICAgICAgIFN0cmVhbS5qdW5rIHN0cm1fXzsgbGV0IHMgPSBzdHJtX18gaW4gc3RvcmUgJ0UnOyBleHBvbmVudF9wYXJ0IHNcbiAgICB8IF8gLT4gU29tZSAoSW50IChpbnRfb2Zfc3RyaW5nIChnZXRfc3RyaW5nICgpKSkpXG4gIGFuZCBkZWNpbWFsX3BhcnQgKHN0cm1fXyA6IF8gU3RyZWFtLnQpID1cbiAgICBtYXRjaCBTdHJlYW0ucGVlayBzdHJtX18gd2l0aFxuICAgICAgU29tZSAoJzAnLi4nOScgYXMgYykgLT5cbiAgICAgICAgU3RyZWFtLmp1bmsgc3RybV9fOyBsZXQgcyA9IHN0cm1fXyBpbiBzdG9yZSBjOyBkZWNpbWFsX3BhcnQgc1xuICAgIHwgU29tZSAoJ2UnIHwgJ0UnKSAtPlxuICAgICAgICBTdHJlYW0uanVuayBzdHJtX187IGxldCBzID0gc3RybV9fIGluIHN0b3JlICdFJzsgZXhwb25lbnRfcGFydCBzXG4gICAgfCBfIC0+IFNvbWUgKEZsb2F0IChmbG9hdF9vZl9zdHJpbmcgKGdldF9zdHJpbmcgKCkpKSlcbiAgYW5kIGV4cG9uZW50X3BhcnQgKHN0cm1fXyA6IF8gU3RyZWFtLnQpID1cbiAgICBtYXRjaCBTdHJlYW0ucGVlayBzdHJtX18gd2l0aFxuICAgICAgU29tZSAoJysnIHwgJy0nIGFzIGMpIC0+XG4gICAgICAgIFN0cmVhbS5qdW5rIHN0cm1fXzsgbGV0IHMgPSBzdHJtX18gaW4gc3RvcmUgYzsgZW5kX2V4cG9uZW50X3BhcnQgc1xuICAgIHwgXyAtPiBlbmRfZXhwb25lbnRfcGFydCBzdHJtX19cbiAgYW5kIGVuZF9leHBvbmVudF9wYXJ0IChzdHJtX18gOiBfIFN0cmVhbS50KSA9XG4gICAgbWF0Y2ggU3RyZWFtLnBlZWsgc3RybV9fIHdpdGhcbiAgICAgIFNvbWUgKCcwJy4uJzknIGFzIGMpIC0+XG4gICAgICAgIFN0cmVhbS5qdW5rIHN0cm1fXzsgbGV0IHMgPSBzdHJtX18gaW4gc3RvcmUgYzsgZW5kX2V4cG9uZW50X3BhcnQgc1xuICAgIHwgXyAtPiBTb21lIChGbG9hdCAoZmxvYXRfb2Zfc3RyaW5nIChnZXRfc3RyaW5nICgpKSkpXG4gIGFuZCBzdHJpbmcgKHN0cm1fXyA6IF8gU3RyZWFtLnQpID1cbiAgICBtYXRjaCBTdHJlYW0ucGVlayBzdHJtX18gd2l0aFxuICAgICAgU29tZSAnXFxcIicgLT4gU3RyZWFtLmp1bmsgc3RybV9fOyBnZXRfc3RyaW5nICgpXG4gICAgfCBTb21lICdcXFxcJyAtPlxuICAgICAgICBTdHJlYW0uanVuayBzdHJtX187XG4gICAgICAgIGxldCBjID1cbiAgICAgICAgICB0cnkgZXNjYXBlIHN0cm1fXyB3aXRoXG4gICAgICAgICAgICBTdHJlYW0uRmFpbHVyZSAtPiByYWlzZSAoU3RyZWFtLkVycm9yIFwiXCIpXG4gICAgICAgIGluXG4gICAgICAgIGxldCBzID0gc3RybV9fIGluIHN0b3JlIGM7IHN0cmluZyBzXG4gICAgfCBTb21lIGMgLT4gU3RyZWFtLmp1bmsgc3RybV9fOyBsZXQgcyA9IHN0cm1fXyBpbiBzdG9yZSBjOyBzdHJpbmcgc1xuICAgIHwgXyAtPiByYWlzZSBTdHJlYW0uRmFpbHVyZVxuICBhbmQgY2hhciAoc3RybV9fIDogXyBTdHJlYW0udCkgPVxuICAgIG1hdGNoIFN0cmVhbS5wZWVrIHN0cm1fXyB3aXRoXG4gICAgICBTb21lICdcXFxcJyAtPlxuICAgICAgICBTdHJlYW0uanVuayBzdHJtX187XG4gICAgICAgIGJlZ2luIHRyeSBlc2NhcGUgc3RybV9fIHdpdGhcbiAgICAgICAgICBTdHJlYW0uRmFpbHVyZSAtPiByYWlzZSAoU3RyZWFtLkVycm9yIFwiXCIpXG4gICAgICAgIGVuZFxuICAgIHwgU29tZSBjIC0+IFN0cmVhbS5qdW5rIHN0cm1fXzsgY1xuICAgIHwgXyAtPiByYWlzZSBTdHJlYW0uRmFpbHVyZVxuICBhbmQgZXNjYXBlIChzdHJtX18gOiBfIFN0cmVhbS50KSA9XG4gICAgbWF0Y2ggU3RyZWFtLnBlZWsgc3RybV9fIHdpdGhcbiAgICAgIFNvbWUgJ24nIC0+IFN0cmVhbS5qdW5rIHN0cm1fXzsgJ1xcbidcbiAgICB8IFNvbWUgJ3InIC0+IFN0cmVhbS5qdW5rIHN0cm1fXzsgJ1xccidcbiAgICB8IFNvbWUgJ3QnIC0+IFN0cmVhbS5qdW5rIHN0cm1fXzsgJ1xcdCdcbiAgICB8IFNvbWUgKCcwJy4uJzknIGFzIGMxKSAtPlxuICAgICAgICBTdHJlYW0uanVuayBzdHJtX187XG4gICAgICAgIGJlZ2luIG1hdGNoIFN0cmVhbS5wZWVrIHN0cm1fXyB3aXRoXG4gICAgICAgICAgU29tZSAoJzAnLi4nOScgYXMgYzIpIC0+XG4gICAgICAgICAgICBTdHJlYW0uanVuayBzdHJtX187XG4gICAgICAgICAgICBiZWdpbiBtYXRjaCBTdHJlYW0ucGVlayBzdHJtX18gd2l0aFxuICAgICAgICAgICAgICBTb21lICgnMCcuLic5JyBhcyBjMykgLT5cbiAgICAgICAgICAgICAgICBTdHJlYW0uanVuayBzdHJtX187XG4gICAgICAgICAgICAgICAgQ2hhci5jaHJcbiAgICAgICAgICAgICAgICAgICgoQ2hhci5jb2RlIGMxIC0gNDgpICogMTAwICsgKENoYXIuY29kZSBjMiAtIDQ4KSAqIDEwICtcbiAgICAgICAgICAgICAgICAgICAgIChDaGFyLmNvZGUgYzMgLSA0OCkpXG4gICAgICAgICAgICB8IF8gLT4gcmFpc2UgKFN0cmVhbS5FcnJvciBcIlwiKVxuICAgICAgICAgICAgZW5kXG4gICAgICAgIHwgXyAtPiByYWlzZSAoU3RyZWFtLkVycm9yIFwiXCIpXG4gICAgICAgIGVuZFxuICAgIHwgU29tZSBjIC0+IFN0cmVhbS5qdW5rIHN0cm1fXzsgY1xuICAgIHwgXyAtPiByYWlzZSBTdHJlYW0uRmFpbHVyZVxuICBhbmQgbWF5YmVfY29tbWVudCAoc3RybV9fIDogXyBTdHJlYW0udCkgPVxuICAgIG1hdGNoIFN0cmVhbS5wZWVrIHN0cm1fXyB3aXRoXG4gICAgICBTb21lICcqJyAtPlxuICAgICAgICBTdHJlYW0uanVuayBzdHJtX187IGxldCBzID0gc3RybV9fIGluIGNvbW1lbnQgczsgbmV4dF90b2tlbiBzXG4gICAgfCBfIC0+IFNvbWUgKGtleXdvcmRfb3JfZXJyb3IgJygnKVxuICBhbmQgY29tbWVudCAoc3RybV9fIDogXyBTdHJlYW0udCkgPVxuICAgIG1hdGNoIFN0cmVhbS5wZWVrIHN0cm1fXyB3aXRoXG4gICAgICBTb21lICcoJyAtPiBTdHJlYW0uanVuayBzdHJtX187IG1heWJlX25lc3RlZF9jb21tZW50IHN0cm1fX1xuICAgIHwgU29tZSAnKicgLT4gU3RyZWFtLmp1bmsgc3RybV9fOyBtYXliZV9lbmRfY29tbWVudCBzdHJtX19cbiAgICB8IFNvbWUgXyAtPiBTdHJlYW0uanVuayBzdHJtX187IGNvbW1lbnQgc3RybV9fXG4gICAgfCBfIC0+IHJhaXNlIFN0cmVhbS5GYWlsdXJlXG4gIGFuZCBtYXliZV9uZXN0ZWRfY29tbWVudCAoc3RybV9fIDogXyBTdHJlYW0udCkgPVxuICAgIG1hdGNoIFN0cmVhbS5wZWVrIHN0cm1fXyB3aXRoXG4gICAgICBTb21lICcqJyAtPiBTdHJlYW0uanVuayBzdHJtX187IGxldCBzID0gc3RybV9fIGluIGNvbW1lbnQgczsgY29tbWVudCBzXG4gICAgfCBTb21lIF8gLT4gU3RyZWFtLmp1bmsgc3RybV9fOyBjb21tZW50IHN0cm1fX1xuICAgIHwgXyAtPiByYWlzZSBTdHJlYW0uRmFpbHVyZVxuICBhbmQgbWF5YmVfZW5kX2NvbW1lbnQgKHN0cm1fXyA6IF8gU3RyZWFtLnQpID1cbiAgICBtYXRjaCBTdHJlYW0ucGVlayBzdHJtX18gd2l0aFxuICAgICAgU29tZSAnKScgLT4gU3RyZWFtLmp1bmsgc3RybV9fOyAoKVxuICAgIHwgU29tZSAnKicgLT4gU3RyZWFtLmp1bmsgc3RybV9fOyBtYXliZV9lbmRfY29tbWVudCBzdHJtX19cbiAgICB8IFNvbWUgXyAtPiBTdHJlYW0uanVuayBzdHJtX187IGNvbW1lbnQgc3RybV9fXG4gICAgfCBfIC0+IHJhaXNlIFN0cmVhbS5GYWlsdXJlXG4gIGluXG4gIGZ1biBpbnB1dCAtPiBTdHJlYW0uZnJvbSAoZnVuIF9jb3VudCAtPiBuZXh0X3Rva2VuIGlucHV0KVxuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgRGFtaWVuIERvbGlnZXosIHByb2pldCBQYXJhLCBJTlJJQSBSb2NxdWVuY291cnQgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMTk5NyBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0ICAgICAqKVxuKCogICAgIGVuIEF1dG9tYXRpcXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG5tb2R1bGUgdHlwZSBTZWVkZWRTID0gc2lnXG4gIGluY2x1ZGUgSGFzaHRibC5TZWVkZWRTXG4gIHZhbCBjbGVhbjogJ2EgdCAtPiB1bml0XG4gIHZhbCBzdGF0c19hbGl2ZTogJ2EgdCAtPiBIYXNodGJsLnN0YXRpc3RpY3NcbiAgICAoKiogc2FtZSBhcyB7IXN0YXRzfSBidXQgb25seSBjb3VudCB0aGUgYWxpdmUgYmluZGluZ3MgKilcbmVuZFxuXG5tb2R1bGUgdHlwZSBTID0gc2lnXG4gIGluY2x1ZGUgSGFzaHRibC5TXG4gIHZhbCBjbGVhbjogJ2EgdCAtPiB1bml0XG4gIHZhbCBzdGF0c19hbGl2ZTogJ2EgdCAtPiBIYXNodGJsLnN0YXRpc3RpY3NcbiAgICAoKiogc2FtZSBhcyB7IXN0YXRzfSBidXQgb25seSBjb3VudCB0aGUgYWxpdmUgYmluZGluZ3MgKilcbmVuZFxuXG5tb2R1bGUgR2VuSGFzaFRhYmxlID0gc3RydWN0XG5cbiAgdHlwZSBlcXVhbCA9XG4gIHwgRVRydWUgfCBFRmFsc2VcbiAgfCBFRGVhZCAoKiogdGhlIGdhcmJhZ2UgY29sbGVjdG9yIHJlY2xhaW1lZCB0aGUgZGF0YSAqKVxuXG4gIG1vZHVsZSBNYWtlU2VlZGVkKEg6IHNpZ1xuICAgIHR5cGUgdFxuICAgIHR5cGUgJ2EgY29udGFpbmVyXG4gICAgdmFsIGNyZWF0ZTogdCAtPiAnYSAtPiAnYSBjb250YWluZXJcbiAgICB2YWwgaGFzaDogaW50IC0+IHQgLT4gaW50XG4gICAgdmFsIGVxdWFsOiAnYSBjb250YWluZXIgLT4gdCAtPiBlcXVhbFxuICAgIHZhbCBnZXRfZGF0YTogJ2EgY29udGFpbmVyIC0+ICdhIG9wdGlvblxuICAgIHZhbCBnZXRfa2V5OiAnYSBjb250YWluZXIgLT4gdCBvcHRpb25cbiAgICB2YWwgc2V0X2tleV9kYXRhOiAnYSBjb250YWluZXIgLT4gdCAtPiAnYSAtPiB1bml0XG4gICAgdmFsIGNoZWNrX2tleTogJ2EgY29udGFpbmVyIC0+IGJvb2xcbiAgZW5kKSA6IFNlZWRlZFMgd2l0aCB0eXBlIGtleSA9IEgudFxuICA9IHN0cnVjdFxuXG4gICAgdHlwZSAnYSB0ID1cbiAgICAgIHsgbXV0YWJsZSBzaXplOiBpbnQ7ICAgICAgICAgICAgICAgICAgKCogbnVtYmVyIG9mIGVudHJpZXMgKilcbiAgICAgICAgbXV0YWJsZSBkYXRhOiAnYSBidWNrZXRsaXN0IGFycmF5OyAgKCogdGhlIGJ1Y2tldHMgKilcbiAgICAgICAgc2VlZDogaW50OyAgICAgICAgICAgICAgICAgICAgICAgICAgKCogZm9yIHJhbmRvbWl6YXRpb24gKilcbiAgICAgICAgaW5pdGlhbF9zaXplOiBpbnQ7ICAgICAgICAgICAgICAgICAgKCogaW5pdGlhbCBhcnJheSBzaXplICopXG4gICAgICB9XG5cbiAgICBhbmQgJ2EgYnVja2V0bGlzdCA9XG4gICAgfCBFbXB0eVxuICAgIHwgQ29ucyBvZiBpbnQgKCogaGFzaCBvZiB0aGUga2V5ICopICogJ2EgSC5jb250YWluZXIgKiAnYSBidWNrZXRsaXN0XG5cbiAgICAoKiogdGhlIGhhc2ggb2YgdGhlIGtleSBpcyBrZXB0IGluIG9yZGVyIHRvIHRlc3QgdGhlIGVxdWFsaXR5IG9mIHRoZSBoYXNoXG4gICAgICBiZWZvcmUgdGhlIGtleS4gU2FtZSByZWFzb24gYXMgZm9yIFdlYWsuTWFrZSAqKVxuXG4gICAgdHlwZSBrZXkgPSBILnRcblxuICAgIGxldCByZWMgcG93ZXJfMl9hYm92ZSB4IG4gPVxuICAgICAgaWYgeCA+PSBuIHRoZW4geFxuICAgICAgZWxzZSBpZiB4ICogMiA+IFN5cy5tYXhfYXJyYXlfbGVuZ3RoIHRoZW4geFxuICAgICAgZWxzZSBwb3dlcl8yX2Fib3ZlICh4ICogMikgblxuXG4gICAgbGV0IHBybmcgPSBsYXp5IChSYW5kb20uU3RhdGUubWFrZV9zZWxmX2luaXQoKSlcblxuICAgIGxldCBjcmVhdGUgPyhyYW5kb20gPSAoSGFzaHRibC5pc19yYW5kb21pemVkICgpKSkgaW5pdGlhbF9zaXplID1cbiAgICAgIGxldCBzID0gcG93ZXJfMl9hYm92ZSAxNiBpbml0aWFsX3NpemUgaW5cbiAgICAgIGxldCBzZWVkID0gaWYgcmFuZG9tIHRoZW4gUmFuZG9tLlN0YXRlLmJpdHMgKExhenkuZm9yY2UgcHJuZykgZWxzZSAwIGluXG4gICAgICB7IGluaXRpYWxfc2l6ZSA9IHM7IHNpemUgPSAwOyBzZWVkID0gc2VlZDsgZGF0YSA9IEFycmF5Lm1ha2UgcyBFbXB0eSB9XG5cbiAgICBsZXQgY2xlYXIgaCA9XG4gICAgICBoLnNpemUgPC0gMDtcbiAgICAgIGxldCBsZW4gPSBBcnJheS5sZW5ndGggaC5kYXRhIGluXG4gICAgICBmb3IgaSA9IDAgdG8gbGVuIC0gMSBkb1xuICAgICAgICBoLmRhdGEuKGkpIDwtIEVtcHR5XG4gICAgICBkb25lXG5cbiAgICBsZXQgcmVzZXQgaCA9XG4gICAgICBsZXQgbGVuID0gQXJyYXkubGVuZ3RoIGguZGF0YSBpblxuICAgICAgaWYgbGVuID0gaC5pbml0aWFsX3NpemUgdGhlblxuICAgICAgICBjbGVhciBoXG4gICAgICBlbHNlIGJlZ2luXG4gICAgICAgIGguc2l6ZSA8LSAwO1xuICAgICAgICBoLmRhdGEgPC0gQXJyYXkubWFrZSBoLmluaXRpYWxfc2l6ZSBFbXB0eVxuICAgICAgZW5kXG5cbiAgICBsZXQgY29weSBoID0geyBoIHdpdGggZGF0YSA9IEFycmF5LmNvcHkgaC5kYXRhIH1cblxuICAgIGxldCBrZXlfaW5kZXggaCBoa2V5ID1cbiAgICAgIGhrZXkgbGFuZCAoQXJyYXkubGVuZ3RoIGguZGF0YSAtIDEpXG5cbiAgICBsZXQgY2xlYW4gaCA9XG4gICAgICBsZXQgcmVjIGRvX2J1Y2tldCA9IGZ1bmN0aW9uXG4gICAgICAgIHwgRW1wdHkgLT5cbiAgICAgICAgICAgIEVtcHR5XG4gICAgICAgIHwgQ29ucyhfLCBjLCByZXN0KSB3aGVuIG5vdCAoSC5jaGVja19rZXkgYykgLT5cbiAgICAgICAgICAgIGguc2l6ZSA8LSBoLnNpemUgLSAxO1xuICAgICAgICAgICAgZG9fYnVja2V0IHJlc3RcbiAgICAgICAgfCBDb25zKGhrZXksIGMsIHJlc3QpIC0+XG4gICAgICAgICAgICBDb25zKGhrZXksIGMsIGRvX2J1Y2tldCByZXN0KVxuICAgICAgaW5cbiAgICAgIGxldCBkID0gaC5kYXRhIGluXG4gICAgICBmb3IgaSA9IDAgdG8gQXJyYXkubGVuZ3RoIGQgLSAxIGRvXG4gICAgICAgIGQuKGkpIDwtIGRvX2J1Y2tldCBkLihpKVxuICAgICAgZG9uZVxuXG4gICAgKCoqIHJlc2l6ZSBpcyB0aGUgb25seSBmdW5jdGlvbiB0byBkbyB0aGUgYWN0dWFsIGNsZWFuaW5nIG9mIGRlYWQga2V5c1xuICAgICAgICAocmVtb3ZlIGRvZXMgaXQganVzdCBiZWNhdXNlIGl0IGNvdWxkKS5cblxuICAgICAgICBUaGUgZ29hbCBpcyB0bzpcblxuICAgICAgICAtIG5vdCByZXNpemUgaW5maW5pdGVseSB3aGVuIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGFsaXZlIGtleXMgaXNcbiAgICAgICAgYm91bmRlZCBidXQga2V5cyBhcmUgY29udGludW91c2x5IGFkZGVkLiBUaGF0IHdvdWxkIGhhcHBlbiBpZlxuICAgICAgICB0aGlzIGZ1bmN0aW9uIGFsd2F5cyByZXNpemUuXG4gICAgICAgIC0gbm90IGNhbGwgdGhpcyBmdW5jdGlvbiBhZnRlciBlYWNoIGFkZGl0aW9uLCB0aGF0IHdvdWxkIGhhcHBlbiBpZiB0aGlzXG4gICAgICAgIGZ1bmN0aW9uIGRvbid0IHJlc2l6ZSBldmVuIHdoZW4gb25seSBvbmUga2V5IGlzIGRlYWQuXG5cbiAgICAgICAgU28gdGhlIGFsZ29yaXRobTpcbiAgICAgICAgLSBjbGVhbiB0aGUga2V5cyBiZWZvcmUgcmVzaXppbmdcbiAgICAgICAgLSBpZiB0aGUgbnVtYmVyIG9mIHJlbWFpbmluZyBrZXlzIGlzIGxlc3MgdGhhbiBoYWxmIHRoZSBzaXplIG9mIHRoZVxuICAgICAgICBhcnJheSwgZG9uJ3QgcmVzaXplLlxuICAgICAgICAtIGlmIGl0IGlzIG1vcmUsIHJlc2l6ZS5cblxuICAgICAgICBUaGUgc2Vjb25kIHByb2JsZW0gcmVtYWlucyBpZiB0aGUgdGFibGUgcmVhY2hlcyB7IVN5cy5tYXhfYXJyYXlfbGVuZ3RofS5cblxuICAgICopXG4gICAgbGV0IHJlc2l6ZSBoID1cbiAgICAgIGxldCBvZGF0YSA9IGguZGF0YSBpblxuICAgICAgbGV0IG9zaXplID0gQXJyYXkubGVuZ3RoIG9kYXRhIGluXG4gICAgICBsZXQgbnNpemUgPSBvc2l6ZSAqIDIgaW5cbiAgICAgIGNsZWFuIGg7XG4gICAgICBpZiBuc2l6ZSA8IFN5cy5tYXhfYXJyYXlfbGVuZ3RoICYmIGguc2l6ZSA+PSBvc2l6ZSBsc3IgMSB0aGVuIGJlZ2luXG4gICAgICAgIGxldCBuZGF0YSA9IEFycmF5Lm1ha2UgbnNpemUgRW1wdHkgaW5cbiAgICAgICAgaC5kYXRhIDwtIG5kYXRhOyAgICAgICAoKiBzbyB0aGF0IGtleV9pbmRleCBzZWVzIHRoZSBuZXcgYnVja2V0IGNvdW50ICopXG4gICAgICAgIGxldCByZWMgaW5zZXJ0X2J1Y2tldCA9IGZ1bmN0aW9uXG4gICAgICAgICAgICBFbXB0eSAtPiAoKVxuICAgICAgICAgIHwgQ29ucyhoa2V5LCBkYXRhLCByZXN0KSAtPlxuICAgICAgICAgICAgICBpbnNlcnRfYnVja2V0IHJlc3Q7ICgqIHByZXNlcnZlIG9yaWdpbmFsIG9yZGVyIG9mIGVsZW1lbnRzICopXG4gICAgICAgICAgICAgIGxldCBuaWR4ID0ga2V5X2luZGV4IGggaGtleSBpblxuICAgICAgICAgICAgICBuZGF0YS4obmlkeCkgPC0gQ29ucyhoa2V5LCBkYXRhLCBuZGF0YS4obmlkeCkpIGluXG4gICAgICAgIGZvciBpID0gMCB0byBvc2l6ZSAtIDEgZG9cbiAgICAgICAgICBpbnNlcnRfYnVja2V0IG9kYXRhLihpKVxuICAgICAgICBkb25lXG4gICAgICBlbmRcblxuICAgIGxldCBhZGQgaCBrZXkgaW5mbyA9XG4gICAgICBsZXQgaGtleSA9IEguaGFzaCBoLnNlZWQga2V5IGluXG4gICAgICBsZXQgaSA9IGtleV9pbmRleCBoIGhrZXkgaW5cbiAgICAgIGxldCBjb250YWluZXIgPSBILmNyZWF0ZSBrZXkgaW5mbyBpblxuICAgICAgbGV0IGJ1Y2tldCA9IENvbnMoaGtleSwgY29udGFpbmVyLCBoLmRhdGEuKGkpKSBpblxuICAgICAgaC5kYXRhLihpKSA8LSBidWNrZXQ7XG4gICAgICBoLnNpemUgPC0gaC5zaXplICsgMTtcbiAgICAgIGlmIGguc2l6ZSA+IEFycmF5Lmxlbmd0aCBoLmRhdGEgbHNsIDEgdGhlbiByZXNpemUgaFxuXG4gICAgbGV0IHJlbW92ZSBoIGtleSA9XG4gICAgICBsZXQgaGtleSA9IEguaGFzaCBoLnNlZWQga2V5IGluXG4gICAgICBsZXQgcmVjIHJlbW92ZV9idWNrZXQgPSBmdW5jdGlvblxuICAgICAgICB8IEVtcHR5IC0+IEVtcHR5XG4gICAgICAgIHwgQ29ucyhoaywgYywgbmV4dCkgd2hlbiBoa2V5ID0gaGsgLT5cbiAgICAgICAgICAgIGJlZ2luIG1hdGNoIEguZXF1YWwgYyBrZXkgd2l0aFxuICAgICAgICAgICAgfCBFVHJ1ZSAtPiBoLnNpemUgPC0gaC5zaXplIC0gMTsgbmV4dFxuICAgICAgICAgICAgfCBFRmFsc2UgLT4gQ29ucyhoaywgYywgcmVtb3ZlX2J1Y2tldCBuZXh0KVxuICAgICAgICAgICAgfCBFRGVhZCAtPlxuICAgICAgICAgICAgICAgICgqIFRoZSBkZWFkIGtleSBpcyBhdXRvbWF0aWNhbGx5IHJlbW92ZWQuIEl0IGlzIGFjY2VwdGFibGVcbiAgICAgICAgICAgICAgICAgICAgZm9yIHRoaXMgZnVuY3Rpb24gc2luY2UgaXQgYWxyZWFkeSByZW1vdmVzIGEgYmluZGluZyAqKVxuICAgICAgICAgICAgICAgIGguc2l6ZSA8LSBoLnNpemUgLSAxO1xuICAgICAgICAgICAgICAgIHJlbW92ZV9idWNrZXQgbmV4dFxuICAgICAgICAgICAgZW5kXG4gICAgICAgIHwgQ29ucyhoayxjLG5leHQpIC0+IENvbnMoaGssIGMsIHJlbW92ZV9idWNrZXQgbmV4dCkgaW5cbiAgICAgIGxldCBpID0ga2V5X2luZGV4IGggaGtleSBpblxuICAgICAgaC5kYXRhLihpKSA8LSByZW1vdmVfYnVja2V0IGguZGF0YS4oaSlcblxuICAgICgqKiB7IWZpbmR9IGRvbid0IHJlbW92ZSBkZWFkIGtleXMgYmVjYXVzZSBpdCB3b3VsZCBiZSBzdXJwcmlzaW5nIGZvclxuICAgICAgICB0aGUgdXNlciB0aGF0IGEgcmVhZC1vbmx5IGZ1bmN0aW9uIG11dGF0ZXMgdGhlIHN0YXRlIChlZy4gY29uY3VycmVudFxuICAgICAgICBhY2Nlc3MpLiBTYW1lIGZvciB7IWl0ZXJ9LCB7IWZvbGR9LCB7IW1lbX0uXG4gICAgKilcbiAgICBsZXQgcmVjIGZpbmRfcmVjIGtleSBoa2V5ID0gZnVuY3Rpb25cbiAgICAgIHwgRW1wdHkgLT5cbiAgICAgICAgICByYWlzZSBOb3RfZm91bmRcbiAgICAgIHwgQ29ucyhoaywgYywgcmVzdCkgd2hlbiBoa2V5ID0gaGsgIC0+XG4gICAgICAgICAgYmVnaW4gbWF0Y2ggSC5lcXVhbCBjIGtleSB3aXRoXG4gICAgICAgICAgfCBFVHJ1ZSAtPlxuICAgICAgICAgICAgICBiZWdpbiBtYXRjaCBILmdldF9kYXRhIGMgd2l0aFxuICAgICAgICAgICAgICB8IE5vbmUgLT5cbiAgICAgICAgICAgICAgICAgICgqIFRoaXMgY2FzZSBpcyBub3QgaW1wb3NzaWJsZSBiZWNhdXNlIHRoZSBnYyBjYW4gcnVuIGJldHdlZW5cbiAgICAgICAgICAgICAgICAgICAgICBILmVxdWFsIGFuZCBILmdldF9kYXRhICopXG4gICAgICAgICAgICAgICAgICBmaW5kX3JlYyBrZXkgaGtleSByZXN0XG4gICAgICAgICAgICAgIHwgU29tZSBkIC0+IGRcbiAgICAgICAgICAgICAgZW5kXG4gICAgICAgICAgfCBFRmFsc2UgLT4gZmluZF9yZWMga2V5IGhrZXkgcmVzdFxuICAgICAgICAgIHwgRURlYWQgLT5cbiAgICAgICAgICAgICAgZmluZF9yZWMga2V5IGhrZXkgcmVzdFxuICAgICAgICAgIGVuZFxuICAgICAgfCBDb25zKF8sIF8sIHJlc3QpIC0+XG4gICAgICAgICAgZmluZF9yZWMga2V5IGhrZXkgcmVzdFxuXG4gICAgbGV0IGZpbmQgaCBrZXkgPVxuICAgICAgbGV0IGhrZXkgPSBILmhhc2ggaC5zZWVkIGtleSBpblxuICAgICAgKCogVE9ETyBpbmxpbmUgMyBpdGVyYXRpb25zICopXG4gICAgICBmaW5kX3JlYyBrZXkgaGtleSAoaC5kYXRhLihrZXlfaW5kZXggaCBoa2V5KSlcblxuICAgIGxldCByZWMgZmluZF9yZWNfb3B0IGtleSBoa2V5ID0gZnVuY3Rpb25cbiAgICAgIHwgRW1wdHkgLT5cbiAgICAgICAgICBOb25lXG4gICAgICB8IENvbnMoaGssIGMsIHJlc3QpIHdoZW4gaGtleSA9IGhrICAtPlxuICAgICAgICAgIGJlZ2luIG1hdGNoIEguZXF1YWwgYyBrZXkgd2l0aFxuICAgICAgICAgIHwgRVRydWUgLT5cbiAgICAgICAgICAgICAgYmVnaW4gbWF0Y2ggSC5nZXRfZGF0YSBjIHdpdGhcbiAgICAgICAgICAgICAgfCBOb25lIC0+XG4gICAgICAgICAgICAgICAgICAoKiBUaGlzIGNhc2UgaXMgbm90IGltcG9zc2libGUgYmVjYXVzZSB0aGUgZ2MgY2FuIHJ1biBiZXR3ZWVuXG4gICAgICAgICAgICAgICAgICAgICAgSC5lcXVhbCBhbmQgSC5nZXRfZGF0YSAqKVxuICAgICAgICAgICAgICAgICAgZmluZF9yZWNfb3B0IGtleSBoa2V5IHJlc3RcbiAgICAgICAgICAgICAgfCBTb21lIF8gYXMgZCAtPiBkXG4gICAgICAgICAgICAgIGVuZFxuICAgICAgICAgIHwgRUZhbHNlIC0+IGZpbmRfcmVjX29wdCBrZXkgaGtleSByZXN0XG4gICAgICAgICAgfCBFRGVhZCAtPlxuICAgICAgICAgICAgICBmaW5kX3JlY19vcHQga2V5IGhrZXkgcmVzdFxuICAgICAgICAgIGVuZFxuICAgICAgfCBDb25zKF8sIF8sIHJlc3QpIC0+XG4gICAgICAgICAgZmluZF9yZWNfb3B0IGtleSBoa2V5IHJlc3RcblxuICAgIGxldCBmaW5kX29wdCBoIGtleSA9XG4gICAgICBsZXQgaGtleSA9IEguaGFzaCBoLnNlZWQga2V5IGluXG4gICAgICAoKiBUT0RPIGlubGluZSAzIGl0ZXJhdGlvbnMgKilcbiAgICAgIGZpbmRfcmVjX29wdCBrZXkgaGtleSAoaC5kYXRhLihrZXlfaW5kZXggaCBoa2V5KSlcblxuICAgIGxldCBmaW5kX2FsbCBoIGtleSA9XG4gICAgICBsZXQgaGtleSA9IEguaGFzaCBoLnNlZWQga2V5IGluXG4gICAgICBsZXQgcmVjIGZpbmRfaW5fYnVja2V0ID0gZnVuY3Rpb25cbiAgICAgIHwgRW1wdHkgLT4gW11cbiAgICAgIHwgQ29ucyhoaywgYywgcmVzdCkgd2hlbiBoa2V5ID0gaGsgIC0+XG4gICAgICAgICAgYmVnaW4gbWF0Y2ggSC5lcXVhbCBjIGtleSB3aXRoXG4gICAgICAgICAgfCBFVHJ1ZSAtPiBiZWdpbiBtYXRjaCBILmdldF9kYXRhIGMgd2l0aFxuICAgICAgICAgICAgICB8IE5vbmUgLT5cbiAgICAgICAgICAgICAgICAgIGZpbmRfaW5fYnVja2V0IHJlc3RcbiAgICAgICAgICAgICAgfCBTb21lIGQgLT4gZDo6ZmluZF9pbl9idWNrZXQgcmVzdFxuICAgICAgICAgICAgZW5kXG4gICAgICAgICAgfCBFRmFsc2UgLT4gZmluZF9pbl9idWNrZXQgcmVzdFxuICAgICAgICAgIHwgRURlYWQgLT5cbiAgICAgICAgICAgICAgZmluZF9pbl9idWNrZXQgcmVzdFxuICAgICAgICAgIGVuZFxuICAgICAgfCBDb25zKF8sIF8sIHJlc3QpIC0+XG4gICAgICAgICAgZmluZF9pbl9idWNrZXQgcmVzdCBpblxuICAgICAgZmluZF9pbl9idWNrZXQgaC5kYXRhLihrZXlfaW5kZXggaCBoa2V5KVxuXG5cbiAgICBsZXQgcmVwbGFjZSBoIGtleSBpbmZvID1cbiAgICAgIGxldCBoa2V5ID0gSC5oYXNoIGguc2VlZCBrZXkgaW5cbiAgICAgIGxldCByZWMgcmVwbGFjZV9idWNrZXQgPSBmdW5jdGlvblxuICAgICAgICB8IEVtcHR5IC0+IHJhaXNlIE5vdF9mb3VuZFxuICAgICAgICB8IENvbnMoaGssIGMsIG5leHQpIHdoZW4gaGtleSA9IGhrIC0+XG4gICAgICAgICAgICBiZWdpbiBtYXRjaCBILmVxdWFsIGMga2V5IHdpdGhcbiAgICAgICAgICAgIHwgRVRydWUgLT4gSC5zZXRfa2V5X2RhdGEgYyBrZXkgaW5mb1xuICAgICAgICAgICAgfCBFRmFsc2UgfCBFRGVhZCAtPiByZXBsYWNlX2J1Y2tldCBuZXh0XG4gICAgICAgICAgICBlbmRcbiAgICAgICAgfCBDb25zKF8sXyxuZXh0KSAtPiByZXBsYWNlX2J1Y2tldCBuZXh0XG4gICAgICBpblxuICAgICAgbGV0IGkgPSBrZXlfaW5kZXggaCBoa2V5IGluXG4gICAgICBsZXQgbCA9IGguZGF0YS4oaSkgaW5cbiAgICAgIHRyeVxuICAgICAgICByZXBsYWNlX2J1Y2tldCBsXG4gICAgICB3aXRoIE5vdF9mb3VuZCAtPlxuICAgICAgICBsZXQgY29udGFpbmVyID0gSC5jcmVhdGUga2V5IGluZm8gaW5cbiAgICAgICAgaC5kYXRhLihpKSA8LSBDb25zKGhrZXksIGNvbnRhaW5lciwgbCk7XG4gICAgICAgIGguc2l6ZSA8LSBoLnNpemUgKyAxO1xuICAgICAgICBpZiBoLnNpemUgPiBBcnJheS5sZW5ndGggaC5kYXRhIGxzbCAxIHRoZW4gcmVzaXplIGhcblxuICAgIGxldCBtZW0gaCBrZXkgPVxuICAgICAgbGV0IGhrZXkgPSBILmhhc2ggaC5zZWVkIGtleSBpblxuICAgICAgbGV0IHJlYyBtZW1faW5fYnVja2V0ID0gZnVuY3Rpb25cbiAgICAgIHwgRW1wdHkgLT5cbiAgICAgICAgICBmYWxzZVxuICAgICAgfCBDb25zKGhrLCBjLCByZXN0KSB3aGVuIGhrID0gaGtleSAtPlxuICAgICAgICAgIGJlZ2luIG1hdGNoIEguZXF1YWwgYyBrZXkgd2l0aFxuICAgICAgICAgIHwgRVRydWUgLT4gdHJ1ZVxuICAgICAgICAgIHwgRUZhbHNlIHwgRURlYWQgLT4gbWVtX2luX2J1Y2tldCByZXN0XG4gICAgICAgICAgZW5kXG4gICAgICB8IENvbnMoX2hrLCBfYywgcmVzdCkgLT4gbWVtX2luX2J1Y2tldCByZXN0IGluXG4gICAgICBtZW1faW5fYnVja2V0IGguZGF0YS4oa2V5X2luZGV4IGggaGtleSlcblxuICAgIGxldCBpdGVyIGYgaCA9XG4gICAgICBsZXQgcmVjIGRvX2J1Y2tldCA9IGZ1bmN0aW9uXG4gICAgICAgIHwgRW1wdHkgLT5cbiAgICAgICAgICAgICgpXG4gICAgICAgIHwgQ29ucyhfLCBjLCByZXN0KSAtPlxuICAgICAgICAgICAgYmVnaW4gbWF0Y2ggSC5nZXRfa2V5IGMsIEguZ2V0X2RhdGEgYyB3aXRoXG4gICAgICAgICAgICB8IE5vbmUsIF8gfCBfLCBOb25lIC0+ICgpXG4gICAgICAgICAgICB8IFNvbWUgaywgU29tZSBkIC0+IGYgayBkXG4gICAgICAgICAgICBlbmQ7IGRvX2J1Y2tldCByZXN0IGluXG4gICAgICBsZXQgZCA9IGguZGF0YSBpblxuICAgICAgZm9yIGkgPSAwIHRvIEFycmF5Lmxlbmd0aCBkIC0gMSBkb1xuICAgICAgICBkb19idWNrZXQgZC4oaSlcbiAgICAgIGRvbmVcblxuICAgIGxldCBmb2xkIGYgaCBpbml0ID1cbiAgICAgIGxldCByZWMgZG9fYnVja2V0IGIgYWNjdSA9XG4gICAgICAgIG1hdGNoIGIgd2l0aFxuICAgICAgICAgIEVtcHR5IC0+XG4gICAgICAgICAgICBhY2N1XG4gICAgICAgIHwgQ29ucyhfLCBjLCByZXN0KSAtPlxuICAgICAgICAgICAgbGV0IGFjY3UgPSBiZWdpbiBtYXRjaCBILmdldF9rZXkgYywgSC5nZXRfZGF0YSBjIHdpdGhcbiAgICAgICAgICAgICAgfCBOb25lLCBfIHwgXywgTm9uZSAtPiBhY2N1XG4gICAgICAgICAgICAgIHwgU29tZSBrLCBTb21lIGQgLT4gZiBrIGQgYWNjdVxuICAgICAgICAgICAgZW5kIGluXG4gICAgICAgICAgICBkb19idWNrZXQgcmVzdCBhY2N1ICBpblxuICAgICAgbGV0IGQgPSBoLmRhdGEgaW5cbiAgICAgIGxldCBhY2N1ID0gcmVmIGluaXQgaW5cbiAgICAgIGZvciBpID0gMCB0byBBcnJheS5sZW5ndGggZCAtIDEgZG9cbiAgICAgICAgYWNjdSA6PSBkb19idWNrZXQgZC4oaSkgIWFjY3VcbiAgICAgIGRvbmU7XG4gICAgICAhYWNjdVxuXG4gICAgbGV0IGZpbHRlcl9tYXBfaW5wbGFjZSBmIGggPVxuICAgICAgbGV0IHJlYyBkb19idWNrZXQgPSBmdW5jdGlvblxuICAgICAgICB8IEVtcHR5IC0+XG4gICAgICAgICAgICBFbXB0eVxuICAgICAgICB8IENvbnMoaGssIGMsIHJlc3QpIC0+XG4gICAgICAgICAgICBtYXRjaCBILmdldF9rZXkgYywgSC5nZXRfZGF0YSBjIHdpdGhcbiAgICAgICAgICAgIHwgTm9uZSwgXyB8IF8sIE5vbmUgLT5cbiAgICAgICAgICAgICAgICBkb19idWNrZXQgcmVzdFxuICAgICAgICAgICAgfCBTb21lIGssIFNvbWUgZCAtPlxuICAgICAgICAgICAgICAgIG1hdGNoIGYgayBkIHdpdGhcbiAgICAgICAgICAgICAgICB8IE5vbmUgLT5cbiAgICAgICAgICAgICAgICAgICAgZG9fYnVja2V0IHJlc3RcbiAgICAgICAgICAgICAgICB8IFNvbWUgbmV3X2QgLT5cbiAgICAgICAgICAgICAgICAgICAgSC5zZXRfa2V5X2RhdGEgYyBrIG5ld19kO1xuICAgICAgICAgICAgICAgICAgICBDb25zKGhrLCBjLCBkb19idWNrZXQgcmVzdClcbiAgICAgIGluXG4gICAgICBsZXQgZCA9IGguZGF0YSBpblxuICAgICAgZm9yIGkgPSAwIHRvIEFycmF5Lmxlbmd0aCBkIC0gMSBkb1xuICAgICAgICBkLihpKSA8LSBkb19idWNrZXQgZC4oaSlcbiAgICAgIGRvbmVcblxuICAgIGxldCBsZW5ndGggaCA9IGguc2l6ZVxuXG4gICAgbGV0IHJlYyBidWNrZXRfbGVuZ3RoIGFjY3UgPSBmdW5jdGlvblxuICAgICAgfCBFbXB0eSAtPiBhY2N1XG4gICAgICB8IENvbnMoXywgXywgcmVzdCkgLT4gYnVja2V0X2xlbmd0aCAoYWNjdSArIDEpIHJlc3RcblxuICAgIGxldCBzdGF0cyBoID1cbiAgICAgIGxldCBtYmwgPVxuICAgICAgICBBcnJheS5mb2xkX2xlZnQgKGZ1biBtIGIgLT4gSW50Lm1heCBtIChidWNrZXRfbGVuZ3RoIDAgYikpIDAgaC5kYXRhIGluXG4gICAgICBsZXQgaGlzdG8gPSBBcnJheS5tYWtlIChtYmwgKyAxKSAwIGluXG4gICAgICBBcnJheS5pdGVyXG4gICAgICAgIChmdW4gYiAtPlxuICAgICAgICAgICBsZXQgbCA9IGJ1Y2tldF9sZW5ndGggMCBiIGluXG4gICAgICAgICAgIGhpc3RvLihsKSA8LSBoaXN0by4obCkgKyAxKVxuICAgICAgICBoLmRhdGE7XG4gICAgICB7IEhhc2h0YmwubnVtX2JpbmRpbmdzID0gaC5zaXplO1xuICAgICAgICBudW1fYnVja2V0cyA9IEFycmF5Lmxlbmd0aCBoLmRhdGE7XG4gICAgICAgIG1heF9idWNrZXRfbGVuZ3RoID0gbWJsO1xuICAgICAgICBidWNrZXRfaGlzdG9ncmFtID0gaGlzdG8gfVxuXG4gICAgbGV0IHJlYyBidWNrZXRfbGVuZ3RoX2FsaXZlIGFjY3UgPSBmdW5jdGlvblxuICAgICAgfCBFbXB0eSAtPiBhY2N1XG4gICAgICB8IENvbnMoXywgYywgcmVzdCkgd2hlbiBILmNoZWNrX2tleSBjIC0+XG4gICAgICAgICAgYnVja2V0X2xlbmd0aF9hbGl2ZSAoYWNjdSArIDEpIHJlc3RcbiAgICAgIHwgQ29ucyhfLCBfLCByZXN0KSAtPiBidWNrZXRfbGVuZ3RoX2FsaXZlIGFjY3UgcmVzdFxuXG4gICAgbGV0IHN0YXRzX2FsaXZlIGggPVxuICAgICAgbGV0IHNpemUgPSByZWYgMCBpblxuICAgICAgbGV0IG1ibCA9XG4gICAgICAgIEFycmF5LmZvbGRfbGVmdFxuICAgICAgICAgIChmdW4gbSBiIC0+IEludC5tYXggbSAoYnVja2V0X2xlbmd0aF9hbGl2ZSAwIGIpKSAwIGguZGF0YVxuICAgICAgaW5cbiAgICAgIGxldCBoaXN0byA9IEFycmF5Lm1ha2UgKG1ibCArIDEpIDAgaW5cbiAgICAgIEFycmF5Lml0ZXJcbiAgICAgICAgKGZ1biBiIC0+XG4gICAgICAgICAgIGxldCBsID0gYnVja2V0X2xlbmd0aF9hbGl2ZSAwIGIgaW5cbiAgICAgICAgICAgc2l6ZSA6PSAhc2l6ZSArIGw7XG4gICAgICAgICAgIGhpc3RvLihsKSA8LSBoaXN0by4obCkgKyAxKVxuICAgICAgICBoLmRhdGE7XG4gICAgICB7IEhhc2h0YmwubnVtX2JpbmRpbmdzID0gIXNpemU7XG4gICAgICAgIG51bV9idWNrZXRzID0gQXJyYXkubGVuZ3RoIGguZGF0YTtcbiAgICAgICAgbWF4X2J1Y2tldF9sZW5ndGggPSBtYmw7XG4gICAgICAgIGJ1Y2tldF9oaXN0b2dyYW0gPSBoaXN0byB9XG5cbiAgICBsZXQgdG9fc2VxIHRibCA9XG4gICAgICAoKiBjYXB0dXJlIGN1cnJlbnQgYXJyYXksIHNvIHRoYXQgZXZlbiBpZiB0aGUgdGFibGUgaXMgcmVzaXplZCB3ZVxuICAgICAgICAga2VlcCBpdGVyYXRpbmcgb24gdGhlIHNhbWUgYXJyYXkgKilcbiAgICAgIGxldCB0YmxfZGF0YSA9IHRibC5kYXRhIGluXG4gICAgICAoKiBzdGF0ZTogaW5kZXggKiBuZXh0IGJ1Y2tldCB0byB0cmF2ZXJzZSAqKVxuICAgICAgbGV0IHJlYyBhdXggaSBidWNrICgpID0gbWF0Y2ggYnVjayB3aXRoXG4gICAgICAgIHwgRW1wdHkgLT5cbiAgICAgICAgICAgIGlmIGkgPSBBcnJheS5sZW5ndGggdGJsX2RhdGFcbiAgICAgICAgICAgIHRoZW4gU2VxLk5pbFxuICAgICAgICAgICAgZWxzZSBhdXgoaSsxKSB0YmxfZGF0YS4oaSkgKClcbiAgICAgICAgfCBDb25zIChfLCBjLCBuZXh0KSAtPlxuICAgICAgICAgICAgYmVnaW4gbWF0Y2ggSC5nZXRfa2V5IGMsIEguZ2V0X2RhdGEgYyB3aXRoXG4gICAgICAgICAgICAgIHwgTm9uZSwgXyB8IF8sIE5vbmUgLT4gYXV4IGkgbmV4dCAoKVxuICAgICAgICAgICAgICB8IFNvbWUga2V5LCBTb21lIGRhdGEgLT5cbiAgICAgICAgICAgICAgICAgIFNlcS5Db25zICgoa2V5LCBkYXRhKSwgYXV4IGkgbmV4dClcbiAgICAgICAgICAgIGVuZFxuICAgICAgaW5cbiAgICAgIGF1eCAwIEVtcHR5XG5cbiAgICBsZXQgdG9fc2VxX2tleXMgbSA9IFNlcS5tYXAgZnN0ICh0b19zZXEgbSlcblxuICAgIGxldCB0b19zZXFfdmFsdWVzIG0gPSBTZXEubWFwIHNuZCAodG9fc2VxIG0pXG5cbiAgICBsZXQgYWRkX3NlcSB0YmwgaSA9XG4gICAgICBTZXEuaXRlciAoZnVuIChrLHYpIC0+IGFkZCB0YmwgayB2KSBpXG5cbiAgICBsZXQgcmVwbGFjZV9zZXEgdGJsIGkgPVxuICAgICAgU2VxLml0ZXIgKGZ1biAoayx2KSAtPiByZXBsYWNlIHRibCBrIHYpIGlcblxuICAgIGxldCBvZl9zZXEgaSA9XG4gICAgICBsZXQgdGJsID0gY3JlYXRlIDE2IGluXG4gICAgICByZXBsYWNlX3NlcSB0YmwgaTtcbiAgICAgIHRibFxuXG4gIGVuZFxuZW5kXG5cbm1vZHVsZSBPYmpFcGggPSBPYmouRXBoZW1lcm9uXG5cbmxldCBfb2JqX29wdCA6IE9iai50IG9wdGlvbiAtPiAnYSBvcHRpb24gPSBmdW4geCAtPlxuICBtYXRjaCB4IHdpdGhcbiAgfCBOb25lIC0+IHhcbiAgfCBTb21lIHYgLT4gU29tZSAoT2JqLm9iaiB2KVxuXG4oKiogVGhlIHByZXZpb3VzIGZ1bmN0aW9uIGlzIHR5cGVkIHNvIHRoaXMgb25lIGlzIGFsc28gY29ycmVjdCAqKVxubGV0IG9ial9vcHQgOiBPYmoudCBvcHRpb24gLT4gJ2Egb3B0aW9uID0gZnVuIHggLT4gT2JqLm1hZ2ljIHhcblxuXG5tb2R1bGUgSzEgPSBzdHJ1Y3RcbiAgdHlwZSAoJ2ssJ2QpIHQgPSBPYmpFcGgudFxuXG4gIGxldCBjcmVhdGUgKCkgOiAoJ2ssJ2QpIHQgPSBPYmpFcGguY3JlYXRlIDFcblxuICBsZXQgZ2V0X2tleSAodDooJ2ssJ2QpIHQpIDogJ2sgb3B0aW9uID0gb2JqX29wdCAoT2JqRXBoLmdldF9rZXkgdCAwKVxuICBsZXQgZ2V0X2tleV9jb3B5ICh0OignaywnZCkgdCkgOiAnayBvcHRpb24gPSBvYmpfb3B0IChPYmpFcGguZ2V0X2tleV9jb3B5IHQgMClcbiAgbGV0IHNldF9rZXkgKHQ6KCdrLCdkKSB0KSAoazonaykgOiB1bml0ID0gT2JqRXBoLnNldF9rZXkgdCAwIChPYmoucmVwciBrKVxuICBsZXQgdW5zZXRfa2V5ICh0OignaywnZCkgdCkgOiB1bml0ID0gT2JqRXBoLnVuc2V0X2tleSB0IDBcbiAgbGV0IGNoZWNrX2tleSAodDooJ2ssJ2QpIHQpIDogYm9vbCA9IE9iakVwaC5jaGVja19rZXkgdCAwXG5cbiAgbGV0IGJsaXRfa2V5ICh0MTooJ2ssJ2QpIHQpICh0MjooJ2ssJ2QpIHQpOiB1bml0ID1cbiAgICBPYmpFcGguYmxpdF9rZXkgdDEgMCB0MiAwIDFcblxuICBsZXQgZ2V0X2RhdGEgKHQ6KCdrLCdkKSB0KSA6ICdkIG9wdGlvbiA9IG9ial9vcHQgKE9iakVwaC5nZXRfZGF0YSB0KVxuICBsZXQgZ2V0X2RhdGFfY29weSAodDooJ2ssJ2QpIHQpIDogJ2Qgb3B0aW9uID0gb2JqX29wdCAoT2JqRXBoLmdldF9kYXRhX2NvcHkgdClcbiAgbGV0IHNldF9kYXRhICh0OignaywnZCkgdCkgKGQ6J2QpIDogdW5pdCA9IE9iakVwaC5zZXRfZGF0YSB0IChPYmoucmVwciBkKVxuICBsZXQgdW5zZXRfZGF0YSAodDooJ2ssJ2QpIHQpIDogdW5pdCA9IE9iakVwaC51bnNldF9kYXRhIHRcbiAgbGV0IGNoZWNrX2RhdGEgKHQ6KCdrLCdkKSB0KSA6IGJvb2wgPSBPYmpFcGguY2hlY2tfZGF0YSB0XG4gIGxldCBibGl0X2RhdGEgKHQxOihfLCdkKSB0KSAodDI6KF8sJ2QpIHQpIDogdW5pdCA9IE9iakVwaC5ibGl0X2RhdGEgdDEgdDJcblxuICBtb2R1bGUgTWFrZVNlZWRlZCAoSDpIYXNodGJsLlNlZWRlZEhhc2hlZFR5cGUpID1cbiAgICBHZW5IYXNoVGFibGUuTWFrZVNlZWRlZChzdHJ1Y3RcbiAgICAgIHR5cGUgJ2EgY29udGFpbmVyID0gKEgudCwnYSkgdFxuICAgICAgdHlwZSB0ID0gSC50XG4gICAgICBsZXQgY3JlYXRlIGsgZCA9XG4gICAgICAgIGxldCBjID0gY3JlYXRlICgpIGluXG4gICAgICAgIHNldF9kYXRhIGMgZDtcbiAgICAgICAgc2V0X2tleSBjIGs7XG4gICAgICAgIGNcbiAgICAgIGxldCBoYXNoID0gSC5oYXNoXG4gICAgICBsZXQgZXF1YWwgYyBrID1cbiAgICAgICAgKCogeyFnZXRfa2V5X2NvcHl9IGlzIG5vdCB1c2VkIGJlY2F1c2UgdGhlIGVxdWFsaXR5IG9mIHRoZSB1c2VyIGNhbiBiZVxuICAgICAgICAgICAgdGhlIHBoeXNpY2FsIGVxdWFsaXR5ICopXG4gICAgICAgIG1hdGNoIGdldF9rZXkgYyB3aXRoXG4gICAgICAgIHwgTm9uZSAtPiBHZW5IYXNoVGFibGUuRURlYWRcbiAgICAgICAgfCBTb21lIGsnIC0+XG4gICAgICAgICAgICBpZiBILmVxdWFsIGsgaycgdGhlbiBHZW5IYXNoVGFibGUuRVRydWUgZWxzZSBHZW5IYXNoVGFibGUuRUZhbHNlXG4gICAgICBsZXQgZ2V0X2RhdGEgPSBnZXRfZGF0YVxuICAgICAgbGV0IGdldF9rZXkgPSBnZXRfa2V5XG4gICAgICBsZXQgc2V0X2tleV9kYXRhIGMgayBkID1cbiAgICAgICAgdW5zZXRfZGF0YSBjO1xuICAgICAgICBzZXRfa2V5IGMgaztcbiAgICAgICAgc2V0X2RhdGEgYyBkXG4gICAgICBsZXQgY2hlY2tfa2V5ID0gY2hlY2tfa2V5XG4gICAgZW5kKVxuXG4gIG1vZHVsZSBNYWtlKEg6IEhhc2h0YmwuSGFzaGVkVHlwZSk6IChTIHdpdGggdHlwZSBrZXkgPSBILnQpID1cbiAgc3RydWN0XG4gICAgaW5jbHVkZSBNYWtlU2VlZGVkKHN0cnVjdFxuICAgICAgICB0eXBlIHQgPSBILnRcbiAgICAgICAgbGV0IGVxdWFsID0gSC5lcXVhbFxuICAgICAgICBsZXQgaGFzaCAoX3NlZWQ6IGludCkgeCA9IEguaGFzaCB4XG4gICAgICBlbmQpXG4gICAgbGV0IGNyZWF0ZSBzeiA9IGNyZWF0ZSB+cmFuZG9tOmZhbHNlIHN6XG4gICAgbGV0IG9mX3NlcSBpID1cbiAgICAgIGxldCB0YmwgPSBjcmVhdGUgMTYgaW5cbiAgICAgIHJlcGxhY2Vfc2VxIHRibCBpO1xuICAgICAgdGJsXG4gIGVuZFxuXG5lbmRcblxubW9kdWxlIEsyID0gc3RydWN0XG4gIHR5cGUgKCdrMSwgJ2syLCAnZCkgdCA9IE9iakVwaC50XG5cbiAgbGV0IGNyZWF0ZSAoKSA6ICgnazEsJ2syLCdkKSB0ID0gT2JqRXBoLmNyZWF0ZSAyXG5cbiAgbGV0IGdldF9rZXkxICh0OignazEsJ2syLCdkKSB0KSA6ICdrMSBvcHRpb24gPSBvYmpfb3B0IChPYmpFcGguZ2V0X2tleSB0IDApXG4gIGxldCBnZXRfa2V5MV9jb3B5ICh0OignazEsJ2syLCdkKSB0KSA6ICdrMSBvcHRpb24gPVxuICAgIG9ial9vcHQgKE9iakVwaC5nZXRfa2V5X2NvcHkgdCAwKVxuICBsZXQgc2V0X2tleTEgKHQ6KCdrMSwnazIsJ2QpIHQpIChrOidrMSkgOiB1bml0ID1cbiAgICBPYmpFcGguc2V0X2tleSB0IDAgKE9iai5yZXByIGspXG4gIGxldCB1bnNldF9rZXkxICh0OignazEsJ2syLCdkKSB0KSA6IHVuaXQgPSBPYmpFcGgudW5zZXRfa2V5IHQgMFxuICBsZXQgY2hlY2tfa2V5MSAodDooJ2sxLCdrMiwnZCkgdCkgOiBib29sID0gT2JqRXBoLmNoZWNrX2tleSB0IDBcblxuICBsZXQgZ2V0X2tleTIgKHQ6KCdrMSwnazIsJ2QpIHQpIDogJ2syIG9wdGlvbiA9IG9ial9vcHQgKE9iakVwaC5nZXRfa2V5IHQgMSlcbiAgbGV0IGdldF9rZXkyX2NvcHkgKHQ6KCdrMSwnazIsJ2QpIHQpIDogJ2syIG9wdGlvbiA9XG4gICAgb2JqX29wdCAoT2JqRXBoLmdldF9rZXlfY29weSB0IDEpXG4gIGxldCBzZXRfa2V5MiAodDooJ2sxLCdrMiwnZCkgdCkgKGs6J2syKSA6IHVuaXQgPVxuICAgIE9iakVwaC5zZXRfa2V5IHQgMSAoT2JqLnJlcHIgaylcbiAgbGV0IHVuc2V0X2tleTIgKHQ6KCdrMSwnazIsJ2QpIHQpIDogdW5pdCA9IE9iakVwaC51bnNldF9rZXkgdCAxXG4gIGxldCBjaGVja19rZXkyICh0OignazEsJ2syLCdkKSB0KSA6IGJvb2wgPSBPYmpFcGguY2hlY2tfa2V5IHQgMVxuXG5cbiAgbGV0IGJsaXRfa2V5MSAodDE6KCdrMSxfLF8pIHQpICh0MjooJ2sxLF8sXykgdCkgOiB1bml0ID1cbiAgICBPYmpFcGguYmxpdF9rZXkgdDEgMCB0MiAwIDFcbiAgbGV0IGJsaXRfa2V5MiAodDE6KF8sJ2syLF8pIHQpICh0MjooXywnazIsXykgdCkgOiB1bml0ID1cbiAgICBPYmpFcGguYmxpdF9rZXkgdDEgMSB0MiAxIDFcbiAgbGV0IGJsaXRfa2V5MTIgKHQxOignazEsJ2syLF8pIHQpICh0MjooJ2sxLCdrMixfKSB0KSA6IHVuaXQgPVxuICAgIE9iakVwaC5ibGl0X2tleSB0MSAwIHQyIDAgMlxuXG4gIGxldCBnZXRfZGF0YSAodDooJ2sxLCdrMiwnZCkgdCkgOiAnZCBvcHRpb24gPSBvYmpfb3B0IChPYmpFcGguZ2V0X2RhdGEgdClcbiAgbGV0IGdldF9kYXRhX2NvcHkgKHQ6KCdrMSwnazIsJ2QpIHQpIDogJ2Qgb3B0aW9uID1cbiAgICBvYmpfb3B0IChPYmpFcGguZ2V0X2RhdGFfY29weSB0KVxuICBsZXQgc2V0X2RhdGEgKHQ6KCdrMSwnazIsJ2QpIHQpIChkOidkKSA6IHVuaXQgPVxuICAgIE9iakVwaC5zZXRfZGF0YSB0IChPYmoucmVwciBkKVxuICBsZXQgdW5zZXRfZGF0YSAodDooJ2sxLCdrMiwnZCkgdCkgOiB1bml0ID0gT2JqRXBoLnVuc2V0X2RhdGEgdFxuICBsZXQgY2hlY2tfZGF0YSAodDooJ2sxLCdrMiwnZCkgdCkgOiBib29sID0gT2JqRXBoLmNoZWNrX2RhdGEgdFxuICBsZXQgYmxpdF9kYXRhICh0MTooXyxfLCdkKSB0KSAodDI6KF8sXywnZCkgdCkgOiB1bml0ID0gT2JqRXBoLmJsaXRfZGF0YSB0MSB0MlxuXG4gIG1vZHVsZSBNYWtlU2VlZGVkXG4gICAgICAoSDE6SGFzaHRibC5TZWVkZWRIYXNoZWRUeXBlKVxuICAgICAgKEgyOkhhc2h0YmwuU2VlZGVkSGFzaGVkVHlwZSkgPVxuICAgIEdlbkhhc2hUYWJsZS5NYWtlU2VlZGVkKHN0cnVjdFxuICAgICAgdHlwZSAnYSBjb250YWluZXIgPSAoSDEudCxIMi50LCdhKSB0XG4gICAgICB0eXBlIHQgPSBIMS50ICogSDIudFxuICAgICAgbGV0IGNyZWF0ZSAoazEsazIpIGQgPVxuICAgICAgICBsZXQgYyA9IGNyZWF0ZSAoKSBpblxuICAgICAgICBzZXRfZGF0YSBjIGQ7XG4gICAgICAgIHNldF9rZXkxIGMgazE7IHNldF9rZXkyIGMgazI7XG4gICAgICAgIGNcbiAgICAgIGxldCBoYXNoIHNlZWQgKGsxLGsyKSA9XG4gICAgICAgIEgxLmhhc2ggc2VlZCBrMSArIEgyLmhhc2ggc2VlZCBrMiAqIDY1NTk5XG4gICAgICBsZXQgZXF1YWwgYyAoazEsazIpID1cbiAgICAgICAgbWF0Y2ggZ2V0X2tleTEgYywgZ2V0X2tleTIgYyB3aXRoXG4gICAgICAgIHwgTm9uZSwgXyB8IF8gLCBOb25lIC0+IEdlbkhhc2hUYWJsZS5FRGVhZFxuICAgICAgICB8IFNvbWUgazEnLCBTb21lIGsyJyAtPlxuICAgICAgICAgICAgaWYgSDEuZXF1YWwgazEgazEnICYmIEgyLmVxdWFsIGsyIGsyJ1xuICAgICAgICAgICAgdGhlbiBHZW5IYXNoVGFibGUuRVRydWUgZWxzZSBHZW5IYXNoVGFibGUuRUZhbHNlXG4gICAgICBsZXQgZ2V0X2RhdGEgPSBnZXRfZGF0YVxuICAgICAgbGV0IGdldF9rZXkgYyA9XG4gICAgICAgIG1hdGNoIGdldF9rZXkxIGMsIGdldF9rZXkyIGMgd2l0aFxuICAgICAgICB8IE5vbmUsIF8gfCBfICwgTm9uZSAtPiBOb25lXG4gICAgICAgIHwgU29tZSBrMScsIFNvbWUgazInIC0+IFNvbWUgKGsxJywgazInKVxuICAgICAgbGV0IHNldF9rZXlfZGF0YSBjIChrMSxrMikgZCA9XG4gICAgICAgIHVuc2V0X2RhdGEgYztcbiAgICAgICAgc2V0X2tleTEgYyBrMTsgc2V0X2tleTIgYyBrMjtcbiAgICAgICAgc2V0X2RhdGEgYyBkXG4gICAgICBsZXQgY2hlY2tfa2V5IGMgPSBjaGVja19rZXkxIGMgJiYgY2hlY2tfa2V5MiBjXG4gICAgZW5kKVxuXG4gIG1vZHVsZSBNYWtlKEgxOiBIYXNodGJsLkhhc2hlZFR5cGUpKEgyOiBIYXNodGJsLkhhc2hlZFR5cGUpOlxuICAgIChTIHdpdGggdHlwZSBrZXkgPSBIMS50ICogSDIudCkgPVxuICBzdHJ1Y3RcbiAgICBpbmNsdWRlIE1ha2VTZWVkZWRcbiAgICAgICAgKHN0cnVjdFxuICAgICAgICAgIHR5cGUgdCA9IEgxLnRcbiAgICAgICAgICBsZXQgZXF1YWwgPSBIMS5lcXVhbFxuICAgICAgICAgIGxldCBoYXNoIChfc2VlZDogaW50KSB4ID0gSDEuaGFzaCB4XG4gICAgICAgIGVuZClcbiAgICAgICAgKHN0cnVjdFxuICAgICAgICAgIHR5cGUgdCA9IEgyLnRcbiAgICAgICAgICBsZXQgZXF1YWwgPSBIMi5lcXVhbFxuICAgICAgICAgIGxldCBoYXNoIChfc2VlZDogaW50KSB4ID0gSDIuaGFzaCB4XG4gICAgICAgIGVuZClcbiAgICBsZXQgY3JlYXRlIHN6ID0gY3JlYXRlIH5yYW5kb206ZmFsc2Ugc3pcbiAgICBsZXQgb2Zfc2VxIGkgPVxuICAgICAgbGV0IHRibCA9IGNyZWF0ZSAxNiBpblxuICAgICAgcmVwbGFjZV9zZXEgdGJsIGk7XG4gICAgICB0YmxcbiAgZW5kXG5cbmVuZFxuXG5tb2R1bGUgS24gPSBzdHJ1Y3RcbiAgdHlwZSAoJ2ssJ2QpIHQgPSBPYmpFcGgudFxuXG4gIGxldCBjcmVhdGUgbiA6ICgnaywnZCkgdCA9IE9iakVwaC5jcmVhdGUgblxuICBsZXQgbGVuZ3RoIChrOignaywnZCkgdCkgOiBpbnQgPSBPYmpFcGgubGVuZ3RoIGtcblxuICBsZXQgZ2V0X2tleSAodDooJ2ssJ2QpIHQpIChuOmludCkgOiAnayBvcHRpb24gPSBvYmpfb3B0IChPYmpFcGguZ2V0X2tleSB0IG4pXG4gIGxldCBnZXRfa2V5X2NvcHkgKHQ6KCdrLCdkKSB0KSAobjppbnQpIDogJ2sgb3B0aW9uID1cbiAgICBvYmpfb3B0IChPYmpFcGguZ2V0X2tleV9jb3B5IHQgbilcbiAgbGV0IHNldF9rZXkgKHQ6KCdrLCdkKSB0KSAobjppbnQpIChrOidrKSA6IHVuaXQgPVxuICAgIE9iakVwaC5zZXRfa2V5IHQgbiAoT2JqLnJlcHIgaylcbiAgbGV0IHVuc2V0X2tleSAodDooJ2ssJ2QpIHQpIChuOmludCkgOiB1bml0ID0gT2JqRXBoLnVuc2V0X2tleSB0IG5cbiAgbGV0IGNoZWNrX2tleSAodDooJ2ssJ2QpIHQpIChuOmludCkgOiBib29sID0gT2JqRXBoLmNoZWNrX2tleSB0IG5cblxuICBsZXQgYmxpdF9rZXkgKHQxOignaywnZCkgdCkgKG8xOmludCkgKHQyOignaywnZCkgdCkgKG8yOmludCkgKGw6aW50KSA6IHVuaXQgPVxuICAgIE9iakVwaC5ibGl0X2tleSB0MSBvMSB0MiBvMiBsXG5cbiAgbGV0IGdldF9kYXRhICh0OignaywnZCkgdCkgOiAnZCBvcHRpb24gPSBvYmpfb3B0IChPYmpFcGguZ2V0X2RhdGEgdClcbiAgbGV0IGdldF9kYXRhX2NvcHkgKHQ6KCdrLCdkKSB0KSA6ICdkIG9wdGlvbiA9IG9ial9vcHQgKE9iakVwaC5nZXRfZGF0YV9jb3B5IHQpXG4gIGxldCBzZXRfZGF0YSAodDooJ2ssJ2QpIHQpIChkOidkKSA6IHVuaXQgPSBPYmpFcGguc2V0X2RhdGEgdCAoT2JqLnJlcHIgZClcbiAgbGV0IHVuc2V0X2RhdGEgKHQ6KCdrLCdkKSB0KSA6IHVuaXQgPSBPYmpFcGgudW5zZXRfZGF0YSB0XG4gIGxldCBjaGVja19kYXRhICh0OignaywnZCkgdCkgOiBib29sID0gT2JqRXBoLmNoZWNrX2RhdGEgdFxuICBsZXQgYmxpdF9kYXRhICh0MTooXywnZCkgdCkgKHQyOihfLCdkKSB0KSA6IHVuaXQgPSBPYmpFcGguYmxpdF9kYXRhIHQxIHQyXG5cbiAgbW9kdWxlIE1ha2VTZWVkZWQgKEg6SGFzaHRibC5TZWVkZWRIYXNoZWRUeXBlKSA9XG4gICAgR2VuSGFzaFRhYmxlLk1ha2VTZWVkZWQoc3RydWN0XG4gICAgICB0eXBlICdhIGNvbnRhaW5lciA9IChILnQsJ2EpIHRcbiAgICAgIHR5cGUgdCA9IEgudCBhcnJheVxuICAgICAgbGV0IGNyZWF0ZSBrIGQgPVxuICAgICAgICBsZXQgYyA9IGNyZWF0ZSAoQXJyYXkubGVuZ3RoIGspIGluXG4gICAgICAgIHNldF9kYXRhIGMgZDtcbiAgICAgICAgZm9yIGk9MCB0byBBcnJheS5sZW5ndGggayAtMSBkb1xuICAgICAgICAgIHNldF9rZXkgYyBpIGsuKGkpO1xuICAgICAgICBkb25lO1xuICAgICAgICBjXG4gICAgICBsZXQgaGFzaCBzZWVkIGsgPVxuICAgICAgICBsZXQgaCA9IHJlZiAwIGluXG4gICAgICAgIGZvciBpPTAgdG8gQXJyYXkubGVuZ3RoIGsgLTEgZG9cbiAgICAgICAgICBoIDo9IEguaGFzaCBzZWVkIGsuKGkpICogNjU1OTkgKyAhaDtcbiAgICAgICAgZG9uZTtcbiAgICAgICAgIWhcbiAgICAgIGxldCBlcXVhbCBjIGsgPVxuICAgICAgICBsZXQgbGVuICA9IEFycmF5Lmxlbmd0aCBrIGluXG4gICAgICAgIGxldCBsZW4nID0gbGVuZ3RoIGMgaW5cbiAgICAgICAgaWYgbGVuICE9IGxlbicgdGhlbiBHZW5IYXNoVGFibGUuRUZhbHNlXG4gICAgICAgIGVsc2VcbiAgICAgICAgICBsZXQgcmVjIGVxdWFsX2FycmF5IGsgYyBpID1cbiAgICAgICAgICAgIGlmIGkgPCAwIHRoZW4gR2VuSGFzaFRhYmxlLkVUcnVlXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgIG1hdGNoIGdldF9rZXkgYyBpIHdpdGhcbiAgICAgICAgICAgICAgfCBOb25lIC0+IEdlbkhhc2hUYWJsZS5FRGVhZFxuICAgICAgICAgICAgICB8IFNvbWUga2kgLT5cbiAgICAgICAgICAgICAgICAgIGlmIEguZXF1YWwgay4oaSkga2lcbiAgICAgICAgICAgICAgICAgIHRoZW4gZXF1YWxfYXJyYXkgayBjIChpLTEpXG4gICAgICAgICAgICAgICAgICBlbHNlIEdlbkhhc2hUYWJsZS5FRmFsc2VcbiAgICAgICAgICBpblxuICAgICAgICAgIGVxdWFsX2FycmF5IGsgYyAobGVuLTEpXG4gICAgICBsZXQgZ2V0X2RhdGEgPSBnZXRfZGF0YVxuICAgICAgbGV0IGdldF9rZXkgYyA9XG4gICAgICAgIGxldCBsZW4gPSBsZW5ndGggYyBpblxuICAgICAgICBpZiBsZW4gPSAwIHRoZW4gU29tZSBbfHxdXG4gICAgICAgIGVsc2VcbiAgICAgICAgICBtYXRjaCBnZXRfa2V5IGMgMCB3aXRoXG4gICAgICAgICAgfCBOb25lIC0+IE5vbmVcbiAgICAgICAgICB8IFNvbWUgazAgLT5cbiAgICAgICAgICAgICAgbGV0IHJlYyBmaWxsIGEgaSA9XG4gICAgICAgICAgICAgICAgaWYgaSA8IDEgdGhlbiBTb21lIGFcbiAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICBtYXRjaCBnZXRfa2V5IGMgaSB3aXRoXG4gICAgICAgICAgICAgICAgICB8IE5vbmUgLT4gTm9uZVxuICAgICAgICAgICAgICAgICAgfCBTb21lIGtpIC0+XG4gICAgICAgICAgICAgICAgICAgICAgYS4oaSkgPC0ga2k7XG4gICAgICAgICAgICAgICAgICAgICAgZmlsbCBhIChpLTEpXG4gICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgIGxldCBhID0gQXJyYXkubWFrZSBsZW4gazAgaW5cbiAgICAgICAgICAgICAgZmlsbCBhIChsZW4tMSlcbiAgICAgIGxldCBzZXRfa2V5X2RhdGEgYyBrIGQgPVxuICAgICAgICB1bnNldF9kYXRhIGM7XG4gICAgICAgIGZvciBpPTAgdG8gQXJyYXkubGVuZ3RoIGsgLTEgZG9cbiAgICAgICAgICBzZXRfa2V5IGMgaSBrLihpKTtcbiAgICAgICAgZG9uZTtcbiAgICAgICAgc2V0X2RhdGEgYyBkXG4gICAgICBsZXQgY2hlY2tfa2V5IGMgPVxuICAgICAgICBsZXQgcmVjIGNoZWNrIGMgaSA9XG4gICAgICAgICAgaSA8IDAgfHwgKGNoZWNrX2tleSBjIGkgJiYgY2hlY2sgYyAoaS0xKSkgaW5cbiAgICAgICAgY2hlY2sgYyAobGVuZ3RoIGMgLSAxKVxuICAgIGVuZClcblxuICBtb2R1bGUgTWFrZShIOiBIYXNodGJsLkhhc2hlZFR5cGUpOiAoUyB3aXRoIHR5cGUga2V5ID0gSC50IGFycmF5KSA9XG4gIHN0cnVjdFxuICAgIGluY2x1ZGUgTWFrZVNlZWRlZChzdHJ1Y3RcbiAgICAgICAgdHlwZSB0ID0gSC50XG4gICAgICAgIGxldCBlcXVhbCA9IEguZXF1YWxcbiAgICAgICAgbGV0IGhhc2ggKF9zZWVkOiBpbnQpIHggPSBILmhhc2ggeFxuICAgICAgZW5kKVxuICAgIGxldCBjcmVhdGUgc3ogPSBjcmVhdGUgfnJhbmRvbTpmYWxzZSBzelxuICAgIGxldCBvZl9zZXEgaSA9XG4gICAgICBsZXQgdGJsID0gY3JlYXRlIDE2IGluXG4gICAgICByZXBsYWNlX3NlcSB0YmwgaTtcbiAgICAgIHRibFxuICBlbmRcbmVuZFxuIiwiKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQ2FtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgIFhhdmllciBMZXJveSBhbmQgRGFtaWVuIERvbGlnZXosIElOUklBIFJvY3F1ZW5jb3VydCAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBDb3B5cmlnaHQgMTk5NiBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0ICAgICAqKVxuKCogICAgIGVuIEF1dG9tYXRpcXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCogICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiAgICAqKVxuKCogICB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMi4xLCB3aXRoIHRoZSAgICAgICAgICAqKVxuKCogICBzcGVjaWFsIGV4Y2VwdGlvbiBvbiBsaW5raW5nIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBMSUNFTlNFLiAgICAgICAgICAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG5sZXQgZ2VuZXJpY19xdW90ZSBxdW90ZXF1b3RlIHMgPVxuICBsZXQgbCA9IFN0cmluZy5sZW5ndGggcyBpblxuICBsZXQgYiA9IEJ1ZmZlci5jcmVhdGUgKGwgKyAyMCkgaW5cbiAgQnVmZmVyLmFkZF9jaGFyIGIgJ1xcJyc7XG4gIGZvciBpID0gMCB0byBsIC0gMSBkb1xuICAgIGlmIHMuW2ldID0gJ1xcJydcbiAgICB0aGVuIEJ1ZmZlci5hZGRfc3RyaW5nIGIgcXVvdGVxdW90ZVxuICAgIGVsc2UgQnVmZmVyLmFkZF9jaGFyIGIgIHMuW2ldXG4gIGRvbmU7XG4gIEJ1ZmZlci5hZGRfY2hhciBiICdcXCcnO1xuICBCdWZmZXIuY29udGVudHMgYlxuXG4oKiBUaGlzIGZ1bmN0aW9uIGltcGxlbWVudHMgdGhlIE9wZW4gR3JvdXAgc3BlY2lmaWNhdGlvbiBmb3VuZCBoZXJlOlxuICBbWzFdXSBodHRwOi8vcHVicy5vcGVuZ3JvdXAub3JnL29ubGluZXB1YnMvOTY5OTkxOTc5OS91dGlsaXRpZXMvYmFzZW5hbWUuaHRtbFxuICBJbiBzdGVwIDEgb2YgW1sxXV0sIHdlIGNob29zZSB0byByZXR1cm4gXCIuXCIgZm9yIGVtcHR5IGlucHV0LlxuICAgIChmb3IgY29tcGF0aWJpbGl0eSB3aXRoIHByZXZpb3VzIHZlcnNpb25zIG9mIE9DYW1sKVxuICBJbiBzdGVwIDIsIHdlIGNob29zZSB0byBwcm9jZXNzIFwiLy9cIiBub3JtYWxseS5cbiAgU3RlcCA2IGlzIG5vdCBpbXBsZW1lbnRlZDogd2UgY29uc2lkZXIgdGhhdCB0aGUgW3N1ZmZpeF0gb3BlcmFuZCBpc1xuICAgIGFsd2F5cyBhYnNlbnQuICBTdWZmaXhlcyBhcmUgaGFuZGxlZCBieSBbY2hvcF9zdWZmaXhdIGFuZCBbY2hvcF9leHRlbnNpb25dLlxuKilcbmxldCBnZW5lcmljX2Jhc2VuYW1lIGlzX2Rpcl9zZXAgY3VycmVudF9kaXJfbmFtZSBuYW1lID1cbiAgbGV0IHJlYyBmaW5kX2VuZCBuID1cbiAgICBpZiBuIDwgMCB0aGVuIFN0cmluZy5zdWIgbmFtZSAwIDFcbiAgICBlbHNlIGlmIGlzX2Rpcl9zZXAgbmFtZSBuIHRoZW4gZmluZF9lbmQgKG4gLSAxKVxuICAgIGVsc2UgZmluZF9iZWcgbiAobiArIDEpXG4gIGFuZCBmaW5kX2JlZyBuIHAgPVxuICAgIGlmIG4gPCAwIHRoZW4gU3RyaW5nLnN1YiBuYW1lIDAgcFxuICAgIGVsc2UgaWYgaXNfZGlyX3NlcCBuYW1lIG4gdGhlbiBTdHJpbmcuc3ViIG5hbWUgKG4gKyAxKSAocCAtIG4gLSAxKVxuICAgIGVsc2UgZmluZF9iZWcgKG4gLSAxKSBwXG4gIGluXG4gIGlmIG5hbWUgPSBcIlwiXG4gIHRoZW4gY3VycmVudF9kaXJfbmFtZVxuICBlbHNlIGZpbmRfZW5kIChTdHJpbmcubGVuZ3RoIG5hbWUgLSAxKVxuXG4oKiBUaGlzIGZ1bmN0aW9uIGltcGxlbWVudHMgdGhlIE9wZW4gR3JvdXAgc3BlY2lmaWNhdGlvbiBmb3VuZCBoZXJlOlxuICBbWzJdXSBodHRwOi8vcHVicy5vcGVuZ3JvdXAub3JnL29ubGluZXB1YnMvOTY5OTkxOTc5OS91dGlsaXRpZXMvZGlybmFtZS5odG1sXG4gIEluIHN0ZXAgNiBvZiBbWzJdXSwgd2UgY2hvb3NlIHRvIHByb2Nlc3MgXCIvL1wiIG5vcm1hbGx5LlxuKilcbmxldCBnZW5lcmljX2Rpcm5hbWUgaXNfZGlyX3NlcCBjdXJyZW50X2Rpcl9uYW1lIG5hbWUgPVxuICBsZXQgcmVjIHRyYWlsaW5nX3NlcCBuID1cbiAgICBpZiBuIDwgMCB0aGVuIFN0cmluZy5zdWIgbmFtZSAwIDFcbiAgICBlbHNlIGlmIGlzX2Rpcl9zZXAgbmFtZSBuIHRoZW4gdHJhaWxpbmdfc2VwIChuIC0gMSlcbiAgICBlbHNlIGJhc2UgblxuICBhbmQgYmFzZSBuID1cbiAgICBpZiBuIDwgMCB0aGVuIGN1cnJlbnRfZGlyX25hbWVcbiAgICBlbHNlIGlmIGlzX2Rpcl9zZXAgbmFtZSBuIHRoZW4gaW50ZXJtZWRpYXRlX3NlcCBuXG4gICAgZWxzZSBiYXNlIChuIC0gMSlcbiAgYW5kIGludGVybWVkaWF0ZV9zZXAgbiA9XG4gICAgaWYgbiA8IDAgdGhlbiBTdHJpbmcuc3ViIG5hbWUgMCAxXG4gICAgZWxzZSBpZiBpc19kaXJfc2VwIG5hbWUgbiB0aGVuIGludGVybWVkaWF0ZV9zZXAgKG4gLSAxKVxuICAgIGVsc2UgU3RyaW5nLnN1YiBuYW1lIDAgKG4gKyAxKVxuICBpblxuICBpZiBuYW1lID0gXCJcIlxuICB0aGVuIGN1cnJlbnRfZGlyX25hbWVcbiAgZWxzZSB0cmFpbGluZ19zZXAgKFN0cmluZy5sZW5ndGggbmFtZSAtIDEpXG5cbm1vZHVsZSB0eXBlIFNZU0RFUFMgPSBzaWdcbiAgdmFsIG51bGwgOiBzdHJpbmdcbiAgdmFsIGN1cnJlbnRfZGlyX25hbWUgOiBzdHJpbmdcbiAgdmFsIHBhcmVudF9kaXJfbmFtZSA6IHN0cmluZ1xuICB2YWwgZGlyX3NlcCA6IHN0cmluZ1xuICB2YWwgaXNfZGlyX3NlcCA6IHN0cmluZyAtPiBpbnQgLT4gYm9vbFxuICB2YWwgaXNfcmVsYXRpdmUgOiBzdHJpbmcgLT4gYm9vbFxuICB2YWwgaXNfaW1wbGljaXQgOiBzdHJpbmcgLT4gYm9vbFxuICB2YWwgY2hlY2tfc3VmZml4IDogc3RyaW5nIC0+IHN0cmluZyAtPiBib29sXG4gIHZhbCBjaG9wX3N1ZmZpeF9vcHQgOiBzdWZmaXg6c3RyaW5nIC0+IHN0cmluZyAtPiBzdHJpbmcgb3B0aW9uXG4gIHZhbCB0ZW1wX2Rpcl9uYW1lIDogc3RyaW5nXG4gIHZhbCBxdW90ZSA6IHN0cmluZyAtPiBzdHJpbmdcbiAgdmFsIHF1b3RlX2NvbW1hbmQgOlxuICAgIHN0cmluZyAtPiA/c3RkaW46IHN0cmluZyAtPiA/c3Rkb3V0OiBzdHJpbmcgLT4gP3N0ZGVycjogc3RyaW5nXG4gICAgICAgICAgIC0+IHN0cmluZyBsaXN0IC0+IHN0cmluZ1xuICB2YWwgYmFzZW5hbWUgOiBzdHJpbmcgLT4gc3RyaW5nXG4gIHZhbCBkaXJuYW1lIDogc3RyaW5nIC0+IHN0cmluZ1xuZW5kXG5cbm1vZHVsZSBVbml4IDogU1lTREVQUyA9IHN0cnVjdFxuICBsZXQgbnVsbCA9IFwiL2Rldi9udWxsXCJcbiAgbGV0IGN1cnJlbnRfZGlyX25hbWUgPSBcIi5cIlxuICBsZXQgcGFyZW50X2Rpcl9uYW1lID0gXCIuLlwiXG4gIGxldCBkaXJfc2VwID0gXCIvXCJcbiAgbGV0IGlzX2Rpcl9zZXAgcyBpID0gcy5baV0gPSAnLydcbiAgbGV0IGlzX3JlbGF0aXZlIG4gPSBTdHJpbmcubGVuZ3RoIG4gPCAxIHx8IG4uWzBdIDw+ICcvJ1xuICBsZXQgaXNfaW1wbGljaXQgbiA9XG4gICAgaXNfcmVsYXRpdmUgblxuICAgICYmIChTdHJpbmcubGVuZ3RoIG4gPCAyIHx8IFN0cmluZy5zdWIgbiAwIDIgPD4gXCIuL1wiKVxuICAgICYmIChTdHJpbmcubGVuZ3RoIG4gPCAzIHx8IFN0cmluZy5zdWIgbiAwIDMgPD4gXCIuLi9cIilcbiAgbGV0IGNoZWNrX3N1ZmZpeCBuYW1lIHN1ZmYgPVxuICAgIFN0cmluZy5lbmRzX3dpdGggfnN1ZmZpeDpzdWZmIG5hbWVcblxuICBsZXQgY2hvcF9zdWZmaXhfb3B0IH5zdWZmaXggZmlsZW5hbWUgPVxuICAgIGxldCBsZW5fcyA9IFN0cmluZy5sZW5ndGggc3VmZml4IGFuZCBsZW5fZiA9IFN0cmluZy5sZW5ndGggZmlsZW5hbWUgaW5cbiAgICBpZiBsZW5fZiA+PSBsZW5fcyB0aGVuXG4gICAgICBsZXQgciA9IFN0cmluZy5zdWIgZmlsZW5hbWUgKGxlbl9mIC0gbGVuX3MpIGxlbl9zIGluXG4gICAgICBpZiByID0gc3VmZml4IHRoZW5cbiAgICAgICAgU29tZSAoU3RyaW5nLnN1YiBmaWxlbmFtZSAwIChsZW5fZiAtIGxlbl9zKSlcbiAgICAgIGVsc2VcbiAgICAgICAgTm9uZVxuICAgIGVsc2VcbiAgICAgIE5vbmVcblxuICBsZXQgdGVtcF9kaXJfbmFtZSA9XG4gICAgdHJ5IFN5cy5nZXRlbnYgXCJUTVBESVJcIiB3aXRoIE5vdF9mb3VuZCAtPiBcIi90bXBcIlxuICBsZXQgcXVvdGUgPSBnZW5lcmljX3F1b3RlIFwiJ1xcXFwnJ1wiXG4gIGxldCBxdW90ZV9jb21tYW5kIGNtZCA/c3RkaW4gP3N0ZG91dCA/c3RkZXJyIGFyZ3MgPVxuICAgIFN0cmluZy5jb25jYXQgXCIgXCIgKExpc3QubWFwIHF1b3RlIChjbWQgOjogYXJncykpXG4gICAgXiAobWF0Y2ggc3RkaW4gIHdpdGggTm9uZSAtPiBcIlwiIHwgU29tZSBmIC0+IFwiIDxcIiBeIHF1b3RlIGYpXG4gICAgXiAobWF0Y2ggc3Rkb3V0IHdpdGggTm9uZSAtPiBcIlwiIHwgU29tZSBmIC0+IFwiID5cIiBeIHF1b3RlIGYpXG4gICAgXiAobWF0Y2ggc3RkZXJyIHdpdGggTm9uZSAtPiBcIlwiIHwgU29tZSBmIC0+IGlmIHN0ZGVyciA9IHN0ZG91dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcIiAyPiYxXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXCIgMj5cIiBeIHF1b3RlIGYpXG4gIGxldCBiYXNlbmFtZSA9IGdlbmVyaWNfYmFzZW5hbWUgaXNfZGlyX3NlcCBjdXJyZW50X2Rpcl9uYW1lXG4gIGxldCBkaXJuYW1lID0gZ2VuZXJpY19kaXJuYW1lIGlzX2Rpcl9zZXAgY3VycmVudF9kaXJfbmFtZVxuZW5kXG5cbm1vZHVsZSBXaW4zMiA6IFNZU0RFUFMgPSBzdHJ1Y3RcbiAgbGV0IG51bGwgPSBcIk5VTFwiXG4gIGxldCBjdXJyZW50X2Rpcl9uYW1lID0gXCIuXCJcbiAgbGV0IHBhcmVudF9kaXJfbmFtZSA9IFwiLi5cIlxuICBsZXQgZGlyX3NlcCA9IFwiXFxcXFwiXG4gIGxldCBpc19kaXJfc2VwIHMgaSA9IGxldCBjID0gcy5baV0gaW4gYyA9ICcvJyB8fCBjID0gJ1xcXFwnIHx8IGMgPSAnOidcbiAgbGV0IGlzX3JlbGF0aXZlIG4gPVxuICAgIChTdHJpbmcubGVuZ3RoIG4gPCAxIHx8IG4uWzBdIDw+ICcvJylcbiAgICAmJiAoU3RyaW5nLmxlbmd0aCBuIDwgMSB8fCBuLlswXSA8PiAnXFxcXCcpXG4gICAgJiYgKFN0cmluZy5sZW5ndGggbiA8IDIgfHwgbi5bMV0gPD4gJzonKVxuICBsZXQgaXNfaW1wbGljaXQgbiA9XG4gICAgaXNfcmVsYXRpdmUgblxuICAgICYmIChTdHJpbmcubGVuZ3RoIG4gPCAyIHx8IFN0cmluZy5zdWIgbiAwIDIgPD4gXCIuL1wiKVxuICAgICYmIChTdHJpbmcubGVuZ3RoIG4gPCAyIHx8IFN0cmluZy5zdWIgbiAwIDIgPD4gXCIuXFxcXFwiKVxuICAgICYmIChTdHJpbmcubGVuZ3RoIG4gPCAzIHx8IFN0cmluZy5zdWIgbiAwIDMgPD4gXCIuLi9cIilcbiAgICAmJiAoU3RyaW5nLmxlbmd0aCBuIDwgMyB8fCBTdHJpbmcuc3ViIG4gMCAzIDw+IFwiLi5cXFxcXCIpXG4gIGxldCBjaGVja19zdWZmaXggbmFtZSBzdWZmID1cbiAgIFN0cmluZy5sZW5ndGggbmFtZSA+PSBTdHJpbmcubGVuZ3RoIHN1ZmYgJiZcbiAgIChsZXQgcyA9IFN0cmluZy5zdWIgbmFtZSAoU3RyaW5nLmxlbmd0aCBuYW1lIC0gU3RyaW5nLmxlbmd0aCBzdWZmKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChTdHJpbmcubGVuZ3RoIHN1ZmYpIGluXG4gICAgU3RyaW5nLmxvd2VyY2FzZV9hc2NpaSBzID0gU3RyaW5nLmxvd2VyY2FzZV9hc2NpaSBzdWZmKVxuXG4gIGxldCBjaG9wX3N1ZmZpeF9vcHQgfnN1ZmZpeCBmaWxlbmFtZSA9XG4gICAgbGV0IGxlbl9zID0gU3RyaW5nLmxlbmd0aCBzdWZmaXggYW5kIGxlbl9mID0gU3RyaW5nLmxlbmd0aCBmaWxlbmFtZSBpblxuICAgIGlmIGxlbl9mID49IGxlbl9zIHRoZW5cbiAgICAgIGxldCByID0gU3RyaW5nLnN1YiBmaWxlbmFtZSAobGVuX2YgLSBsZW5fcykgbGVuX3MgaW5cbiAgICAgIGlmIFN0cmluZy5sb3dlcmNhc2VfYXNjaWkgciA9IFN0cmluZy5sb3dlcmNhc2VfYXNjaWkgc3VmZml4IHRoZW5cbiAgICAgICAgU29tZSAoU3RyaW5nLnN1YiBmaWxlbmFtZSAwIChsZW5fZiAtIGxlbl9zKSlcbiAgICAgIGVsc2VcbiAgICAgICAgTm9uZVxuICAgIGVsc2VcbiAgICAgIE5vbmVcblxuXG4gIGxldCB0ZW1wX2Rpcl9uYW1lID1cbiAgICB0cnkgU3lzLmdldGVudiBcIlRFTVBcIiB3aXRoIE5vdF9mb3VuZCAtPiBcIi5cIlxuICBsZXQgcXVvdGUgcyA9XG4gICAgbGV0IGwgPSBTdHJpbmcubGVuZ3RoIHMgaW5cbiAgICBsZXQgYiA9IEJ1ZmZlci5jcmVhdGUgKGwgKyAyMCkgaW5cbiAgICBCdWZmZXIuYWRkX2NoYXIgYiAnXFxcIic7XG4gICAgbGV0IHJlYyBsb29wIGkgPVxuICAgICAgaWYgaSA9IGwgdGhlbiBCdWZmZXIuYWRkX2NoYXIgYiAnXFxcIicgZWxzZVxuICAgICAgbWF0Y2ggcy5baV0gd2l0aFxuICAgICAgfCAnXFxcIicgLT4gbG9vcF9icyAwIGk7XG4gICAgICB8ICdcXFxcJyAtPiBsb29wX2JzIDAgaTtcbiAgICAgIHwgYyAgICAtPiBCdWZmZXIuYWRkX2NoYXIgYiBjOyBsb29wIChpKzEpO1xuICAgIGFuZCBsb29wX2JzIG4gaSA9XG4gICAgICBpZiBpID0gbCB0aGVuIGJlZ2luXG4gICAgICAgIEJ1ZmZlci5hZGRfY2hhciBiICdcXFwiJztcbiAgICAgICAgYWRkX2JzIG47XG4gICAgICBlbmQgZWxzZSBiZWdpblxuICAgICAgICBtYXRjaCBzLltpXSB3aXRoXG4gICAgICAgIHwgJ1xcXCInIC0+IGFkZF9icyAoMipuKzEpOyBCdWZmZXIuYWRkX2NoYXIgYiAnXFxcIic7IGxvb3AgKGkrMSk7XG4gICAgICAgIHwgJ1xcXFwnIC0+IGxvb3BfYnMgKG4rMSkgKGkrMSk7XG4gICAgICAgIHwgXyAgICAtPiBhZGRfYnMgbjsgbG9vcCBpXG4gICAgICBlbmRcbiAgICBhbmQgYWRkX2JzIG4gPSBmb3IgX2ogPSAxIHRvIG4gZG8gQnVmZmVyLmFkZF9jaGFyIGIgJ1xcXFwnOyBkb25lXG4gICAgaW5cbiAgICBsb29wIDA7XG4gICAgQnVmZmVyLmNvbnRlbnRzIGJcbigqXG5RdW90aW5nIGNvbW1hbmRzIGZvciBleGVjdXRpb24gYnkgY21kLmV4ZSBpcyBkaWZmaWN1bHQuXG4xLSBFYWNoIGFyZ3VtZW50IGlzIGZpcnN0IHF1b3RlZCB1c2luZyB0aGUgXCJxdW90ZVwiIGZ1bmN0aW9uIGFib3ZlLCB0b1xuICAgcHJvdGVjdCBpdCBhZ2FpbnN0IHRoZSBwcm9jZXNzaW5nIHBlcmZvcm1lZCBieSB0aGUgQyBydW50aW1lIHN5c3RlbSxcbiAgIHRoZW4gY21kLmV4ZSdzIHNwZWNpYWwgY2hhcmFjdGVycyBhcmUgZXNjYXBlZCB3aXRoICdeJywgdXNpbmdcbiAgIHRoZSBcInF1b3RlX2NtZFwiIGZ1bmN0aW9uIGJlbG93LiAgRm9yIG1vcmUgZGV0YWlscywgc2VlXG4gICBodHRwczovL2Jsb2dzLm1zZG4ubWljcm9zb2Z0LmNvbS90d2lzdHlsaXR0bGVwYXNzYWdlc2FsbGFsaWtlLzIwMTEvMDQvMjNcbjItIFRoZSBjb21tYW5kIGFuZCB0aGUgcmVkaXJlY3Rpb24gZmlsZXMsIGlmIGFueSwgbXVzdCBiZSBkb3VibGUtcXVvdGVkXG4gICBpbiBjYXNlIHRoZXkgY29udGFpbiBzcGFjZXMuICBUaGlzIHF1b3RpbmcgaXMgaW50ZXJwcmV0ZWQgYnkgY21kLmV4ZSxcbiAgIG5vdCBieSB0aGUgQyBydW50aW1lIHN5c3RlbSwgaGVuY2UgdGhlIFwicXVvdGVcIiBmdW5jdGlvbiBhYm92ZVxuICAgY2Fubm90IGJlIHVzZWQuICBUaGUgdHdvIGNoYXJhY3RlcnMgd2UgZG9uJ3Qga25vdyBob3cgdG8gcXVvdGVcbiAgIGluc2lkZSBhIGRvdWJsZS1xdW90ZWQgY21kLmV4ZSBzdHJpbmcgYXJlIGRvdWJsZS1xdW90ZSBhbmQgcGVyY2VudC5cbiAgIFdlIGp1c3QgZmFpbCBpZiB0aGUgY29tbWFuZCBuYW1lIG9yIHRoZSByZWRpcmVjdGlvbiBmaWxlIG5hbWVzXG4gICBjb250YWluIGEgZG91YmxlIHF1b3RlIChub3QgYWxsb3dlZCBpbiBXaW5kb3dzIGZpbGUgbmFtZXMsIGFueXdheSlcbiAgIG9yIGEgcGVyY2VudC4gIFNlZSBmdW5jdGlvbiBcInF1b3RlX2NtZF9maWxlbmFtZVwiIGJlbG93LlxuMy0gVGhlIHdob2xlIHN0cmluZyBwYXNzZWQgdG8gU3lzLmNvbW1hbmQgaXMgdGhlbiBlbmNsb3NlZCBpbiBkb3VibGVcbiAgIHF1b3Rlcywgd2hpY2ggYXJlIGltbWVkaWF0ZWx5IHN0cmlwcGVkIGJ5IGNtZC5leGUuICBPdGhlcndpc2UsXG4gICBzb21lIG9mIHRoZSBkb3VibGUgcXVvdGVzIGZyb20gc3RlcCAyIGFib3ZlIGNhbiBiZSBtaXNwYXJzZWQuXG4gICBTZWUgZS5nLiBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvOTk2NTE0MVxuKilcbiAgbGV0IHF1b3RlX2NtZCBzID1cbiAgICBsZXQgYiA9IEJ1ZmZlci5jcmVhdGUgKFN0cmluZy5sZW5ndGggcyArIDIwKSBpblxuICAgIFN0cmluZy5pdGVyXG4gICAgICAoZnVuIGMgLT5cbiAgICAgICAgbWF0Y2ggYyB3aXRoXG4gICAgICAgIHwgJygnIHwgJyknIHwgJyEnIHwgJ14nIHwgJyUnIHwgJ1xcXCInIHwgJzwnIHwgJz4nIHwgJyYnIHwgJ3wnIC0+XG4gICAgICAgICAgICBCdWZmZXIuYWRkX2NoYXIgYiAnXic7IEJ1ZmZlci5hZGRfY2hhciBiIGNcbiAgICAgICAgfCBfIC0+XG4gICAgICAgICAgICBCdWZmZXIuYWRkX2NoYXIgYiBjKVxuICAgICAgcztcbiAgICBCdWZmZXIuY29udGVudHMgYlxuICBsZXQgcXVvdGVfY21kX2ZpbGVuYW1lIGYgPVxuICAgIGlmIFN0cmluZy5jb250YWlucyBmICdcXFwiJyB8fCBTdHJpbmcuY29udGFpbnMgZiAnJScgdGhlblxuICAgICAgZmFpbHdpdGggKFwiRmlsZW5hbWUucXVvdGVfY29tbWFuZDogYmFkIGZpbGUgbmFtZSBcIiBeIGYpXG4gICAgZWxzZSBpZiBTdHJpbmcuY29udGFpbnMgZiAnICcgdGhlblxuICAgICAgXCJcXFwiXCIgXiBmIF4gXCJcXFwiXCJcbiAgICBlbHNlXG4gICAgICBmXG4gICgqIFJlZGlyZWN0aW9ucyBpbiBjbWQuZXhlOiBzZWUgaHR0cHM6Ly9zczY0LmNvbS9udC9zeW50YXgtcmVkaXJlY3Rpb24uaHRtbFxuICAgICBhbmQgaHR0cHM6Ly9kb2NzLm1pY3Jvc29mdC5jb20vZW4tdXMvcHJldmlvdXMtdmVyc2lvbnMvd2luZG93cy9pdC1wcm8vd2luZG93cy14cC9iYjQ5MDk4Mih2PXRlY2huZXQuMTApXG4gICopXG4gIGxldCBxdW90ZV9jb21tYW5kIGNtZCA/c3RkaW4gP3N0ZG91dCA/c3RkZXJyIGFyZ3MgPVxuICAgIFN0cmluZy5jb25jYXQgXCJcIiBbXG4gICAgICBcIlxcXCJcIjtcbiAgICAgIHF1b3RlX2NtZF9maWxlbmFtZSBjbWQ7XG4gICAgICBcIiBcIjtcbiAgICAgIHF1b3RlX2NtZCAoU3RyaW5nLmNvbmNhdCBcIiBcIiAoTGlzdC5tYXAgcXVvdGUgYXJncykpO1xuICAgICAgKG1hdGNoIHN0ZGluICB3aXRoIE5vbmUgLT4gXCJcIiB8IFNvbWUgZiAtPiBcIiA8XCIgXiBxdW90ZV9jbWRfZmlsZW5hbWUgZik7XG4gICAgICAobWF0Y2ggc3Rkb3V0IHdpdGggTm9uZSAtPiBcIlwiIHwgU29tZSBmIC0+IFwiID5cIiBeIHF1b3RlX2NtZF9maWxlbmFtZSBmKTtcbiAgICAgIChtYXRjaCBzdGRlcnIgd2l0aCBOb25lIC0+IFwiXCIgfCBTb21lIGYgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBzdGRlcnIgPSBzdGRvdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFwiIDI+JjFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXCIgMj5cIiBeIHF1b3RlX2NtZF9maWxlbmFtZSBmKTtcbiAgICAgIFwiXFxcIlwiXG4gICAgXVxuICBsZXQgaGFzX2RyaXZlIHMgPVxuICAgIGxldCBpc19sZXR0ZXIgPSBmdW5jdGlvblxuICAgICAgfCAnQScgLi4gJ1onIHwgJ2EnIC4uICd6JyAtPiB0cnVlXG4gICAgICB8IF8gLT4gZmFsc2VcbiAgICBpblxuICAgIFN0cmluZy5sZW5ndGggcyA+PSAyICYmIGlzX2xldHRlciBzLlswXSAmJiBzLlsxXSA9ICc6J1xuICBsZXQgZHJpdmVfYW5kX3BhdGggcyA9XG4gICAgaWYgaGFzX2RyaXZlIHNcbiAgICB0aGVuIChTdHJpbmcuc3ViIHMgMCAyLCBTdHJpbmcuc3ViIHMgMiAoU3RyaW5nLmxlbmd0aCBzIC0gMikpXG4gICAgZWxzZSAoXCJcIiwgcylcbiAgbGV0IGRpcm5hbWUgcyA9XG4gICAgbGV0IChkcml2ZSwgcGF0aCkgPSBkcml2ZV9hbmRfcGF0aCBzIGluXG4gICAgbGV0IGRpciA9IGdlbmVyaWNfZGlybmFtZSBpc19kaXJfc2VwIGN1cnJlbnRfZGlyX25hbWUgcGF0aCBpblxuICAgIGRyaXZlIF4gZGlyXG4gIGxldCBiYXNlbmFtZSBzID1cbiAgICBsZXQgKF9kcml2ZSwgcGF0aCkgPSBkcml2ZV9hbmRfcGF0aCBzIGluXG4gICAgZ2VuZXJpY19iYXNlbmFtZSBpc19kaXJfc2VwIGN1cnJlbnRfZGlyX25hbWUgcGF0aFxuZW5kXG5cbm1vZHVsZSBDeWd3aW4gOiBTWVNERVBTID0gc3RydWN0XG4gIGxldCBudWxsID0gXCIvZGV2L251bGxcIlxuICBsZXQgY3VycmVudF9kaXJfbmFtZSA9IFwiLlwiXG4gIGxldCBwYXJlbnRfZGlyX25hbWUgPSBcIi4uXCJcbiAgbGV0IGRpcl9zZXAgPSBcIi9cIlxuICBsZXQgaXNfZGlyX3NlcCA9IFdpbjMyLmlzX2Rpcl9zZXBcbiAgbGV0IGlzX3JlbGF0aXZlID0gV2luMzIuaXNfcmVsYXRpdmVcbiAgbGV0IGlzX2ltcGxpY2l0ID0gV2luMzIuaXNfaW1wbGljaXRcbiAgbGV0IGNoZWNrX3N1ZmZpeCA9IFdpbjMyLmNoZWNrX3N1ZmZpeFxuICBsZXQgY2hvcF9zdWZmaXhfb3B0ID0gV2luMzIuY2hvcF9zdWZmaXhfb3B0XG4gIGxldCB0ZW1wX2Rpcl9uYW1lID0gVW5peC50ZW1wX2Rpcl9uYW1lXG4gIGxldCBxdW90ZSA9IFVuaXgucXVvdGVcbiAgbGV0IHF1b3RlX2NvbW1hbmQgPSBVbml4LnF1b3RlX2NvbW1hbmRcbiAgbGV0IGJhc2VuYW1lID0gZ2VuZXJpY19iYXNlbmFtZSBpc19kaXJfc2VwIGN1cnJlbnRfZGlyX25hbWVcbiAgbGV0IGRpcm5hbWUgPSBnZW5lcmljX2Rpcm5hbWUgaXNfZGlyX3NlcCBjdXJyZW50X2Rpcl9uYW1lXG5lbmRcblxubW9kdWxlIFN5c2RlcHMgPVxuICAodmFsIChtYXRjaCBTeXMub3NfdHlwZSB3aXRoXG4gICAgICAgfCBcIldpbjMyXCIgLT4gKG1vZHVsZSBXaW4zMjogU1lTREVQUylcbiAgICAgICB8IFwiQ3lnd2luXCIgLT4gKG1vZHVsZSBDeWd3aW46IFNZU0RFUFMpXG4gICAgICAgfCBfIC0+IChtb2R1bGUgVW5peDogU1lTREVQUykpKVxuXG5pbmNsdWRlIFN5c2RlcHNcblxubGV0IGNvbmNhdCBkaXJuYW1lIGZpbGVuYW1lID1cbiAgbGV0IGwgPSBTdHJpbmcubGVuZ3RoIGRpcm5hbWUgaW5cbiAgaWYgbCA9IDAgfHwgaXNfZGlyX3NlcCBkaXJuYW1lIChsLTEpXG4gIHRoZW4gZGlybmFtZSBeIGZpbGVuYW1lXG4gIGVsc2UgZGlybmFtZSBeIGRpcl9zZXAgXiBmaWxlbmFtZVxuXG5sZXQgY2hvcF9zdWZmaXggbmFtZSBzdWZmID1cbiAgbGV0IG4gPSBTdHJpbmcubGVuZ3RoIG5hbWUgLSBTdHJpbmcubGVuZ3RoIHN1ZmYgaW5cbiAgaWYgbiA8IDAgdGhlbiBpbnZhbGlkX2FyZyBcIkZpbGVuYW1lLmNob3Bfc3VmZml4XCIgZWxzZSBTdHJpbmcuc3ViIG5hbWUgMCBuXG5cbmxldCBleHRlbnNpb25fbGVuIG5hbWUgPVxuICBsZXQgcmVjIGNoZWNrIGkwIGkgPVxuICAgIGlmIGkgPCAwIHx8IGlzX2Rpcl9zZXAgbmFtZSBpIHRoZW4gMFxuICAgIGVsc2UgaWYgbmFtZS5baV0gPSAnLicgdGhlbiBjaGVjayBpMCAoaSAtIDEpXG4gICAgZWxzZSBTdHJpbmcubGVuZ3RoIG5hbWUgLSBpMFxuICBpblxuICBsZXQgcmVjIHNlYXJjaF9kb3QgaSA9XG4gICAgaWYgaSA8IDAgfHwgaXNfZGlyX3NlcCBuYW1lIGkgdGhlbiAwXG4gICAgZWxzZSBpZiBuYW1lLltpXSA9ICcuJyB0aGVuIGNoZWNrIGkgKGkgLSAxKVxuICAgIGVsc2Ugc2VhcmNoX2RvdCAoaSAtIDEpXG4gIGluXG4gIHNlYXJjaF9kb3QgKFN0cmluZy5sZW5ndGggbmFtZSAtIDEpXG5cbmxldCBleHRlbnNpb24gbmFtZSA9XG4gIGxldCBsID0gZXh0ZW5zaW9uX2xlbiBuYW1lIGluXG4gIGlmIGwgPSAwIHRoZW4gXCJcIiBlbHNlIFN0cmluZy5zdWIgbmFtZSAoU3RyaW5nLmxlbmd0aCBuYW1lIC0gbCkgbFxuXG5sZXQgY2hvcF9leHRlbnNpb24gbmFtZSA9XG4gIGxldCBsID0gZXh0ZW5zaW9uX2xlbiBuYW1lIGluXG4gIGlmIGwgPSAwIHRoZW4gaW52YWxpZF9hcmcgXCJGaWxlbmFtZS5jaG9wX2V4dGVuc2lvblwiXG4gIGVsc2UgU3RyaW5nLnN1YiBuYW1lIDAgKFN0cmluZy5sZW5ndGggbmFtZSAtIGwpXG5cbmxldCByZW1vdmVfZXh0ZW5zaW9uIG5hbWUgPVxuICBsZXQgbCA9IGV4dGVuc2lvbl9sZW4gbmFtZSBpblxuICBpZiBsID0gMCB0aGVuIG5hbWUgZWxzZSBTdHJpbmcuc3ViIG5hbWUgMCAoU3RyaW5nLmxlbmd0aCBuYW1lIC0gbClcblxuZXh0ZXJuYWwgb3Blbl9kZXNjOiBzdHJpbmcgLT4gb3Blbl9mbGFnIGxpc3QgLT4gaW50IC0+IGludCA9IFwiY2FtbF9zeXNfb3BlblwiXG5leHRlcm5hbCBjbG9zZV9kZXNjOiBpbnQgLT4gdW5pdCA9IFwiY2FtbF9zeXNfY2xvc2VcIlxuXG5sZXQgcHJuZyA9IGxhenkoUmFuZG9tLlN0YXRlLm1ha2Vfc2VsZl9pbml0ICgpKVxuXG5sZXQgdGVtcF9maWxlX25hbWUgdGVtcF9kaXIgcHJlZml4IHN1ZmZpeCA9XG4gIGxldCBybmQgPSAoUmFuZG9tLlN0YXRlLmJpdHMgKExhenkuZm9yY2UgcHJuZykpIGxhbmQgMHhGRkZGRkYgaW5cbiAgY29uY2F0IHRlbXBfZGlyIChQcmludGYuc3ByaW50ZiBcIiVzJTA2eCVzXCIgcHJlZml4IHJuZCBzdWZmaXgpXG5cblxubGV0IGN1cnJlbnRfdGVtcF9kaXJfbmFtZSA9IHJlZiB0ZW1wX2Rpcl9uYW1lXG5cbmxldCBzZXRfdGVtcF9kaXJfbmFtZSBzID0gY3VycmVudF90ZW1wX2Rpcl9uYW1lIDo9IHNcbmxldCBnZXRfdGVtcF9kaXJfbmFtZSAoKSA9ICFjdXJyZW50X3RlbXBfZGlyX25hbWVcblxubGV0IHRlbXBfZmlsZSA/KHRlbXBfZGlyID0gIWN1cnJlbnRfdGVtcF9kaXJfbmFtZSkgcHJlZml4IHN1ZmZpeCA9XG4gIGxldCByZWMgdHJ5X25hbWUgY291bnRlciA9XG4gICAgbGV0IG5hbWUgPSB0ZW1wX2ZpbGVfbmFtZSB0ZW1wX2RpciBwcmVmaXggc3VmZml4IGluXG4gICAgdHJ5XG4gICAgICBjbG9zZV9kZXNjKG9wZW5fZGVzYyBuYW1lIFtPcGVuX3dyb25seTsgT3Blbl9jcmVhdDsgT3Blbl9leGNsXSAwbzYwMCk7XG4gICAgICBuYW1lXG4gICAgd2l0aCBTeXNfZXJyb3IgXyBhcyBlIC0+XG4gICAgICBpZiBjb3VudGVyID49IDEwMDAgdGhlbiByYWlzZSBlIGVsc2UgdHJ5X25hbWUgKGNvdW50ZXIgKyAxKVxuICBpbiB0cnlfbmFtZSAwXG5cbmxldCBvcGVuX3RlbXBfZmlsZSA/KG1vZGUgPSBbT3Blbl90ZXh0XSkgPyhwZXJtcyA9IDBvNjAwKVxuICAgICAgICAgICAgICAgICAgID8odGVtcF9kaXIgPSAhY3VycmVudF90ZW1wX2Rpcl9uYW1lKSBwcmVmaXggc3VmZml4ID1cbiAgbGV0IHJlYyB0cnlfbmFtZSBjb3VudGVyID1cbiAgICBsZXQgbmFtZSA9IHRlbXBfZmlsZV9uYW1lIHRlbXBfZGlyIHByZWZpeCBzdWZmaXggaW5cbiAgICB0cnlcbiAgICAgIChuYW1lLFxuICAgICAgIG9wZW5fb3V0X2dlbiAoT3Blbl93cm9ubHk6Ok9wZW5fY3JlYXQ6Ok9wZW5fZXhjbDo6bW9kZSkgcGVybXMgbmFtZSlcbiAgICB3aXRoIFN5c19lcnJvciBfIGFzIGUgLT5cbiAgICAgIGlmIGNvdW50ZXIgPj0gMTAwMCB0aGVuIHJhaXNlIGUgZWxzZSB0cnlfbmFtZSAoY291bnRlciArIDEpXG4gIGluIHRyeV9uYW1lIDBcbiIsIigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0NhbWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgIFhhdmllciBMZXJveSwgcHJvamV0IENyaXN0YWwsIElOUklBIFJvY3F1ZW5jb3VydCAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQ29weXJpZ2h0IDIwMDIgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCAgICAgKilcbigqICAgICBlbiBBdXRvbWF0aXF1ZS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQWxsIHJpZ2h0cyByZXNlcnZlZC4gIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgICAgKilcbigqICAgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIuMSwgd2l0aCB0aGUgICAgICAgICAgKilcbigqICAgc3BlY2lhbCBleGNlcHRpb24gb24gbGlua2luZyBkZXNjcmliZWQgaW4gdGhlIGZpbGUgTElDRU5TRS4gICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcblxuKCogQ29tcGxleCBudW1iZXJzICopXG5cbnR5cGUgdCA9IHsgcmU6IGZsb2F0OyBpbTogZmxvYXQgfVxuXG5sZXQgemVybyA9IHsgcmUgPSAwLjA7IGltID0gMC4wIH1cbmxldCBvbmUgPSB7IHJlID0gMS4wOyBpbSA9IDAuMCB9XG5sZXQgaSA9IHsgcmUgPSAwLjA7IGltID0gMS4wIH1cblxubGV0IGFkZCB4IHkgPSB7IHJlID0geC5yZSArLiB5LnJlOyBpbSA9IHguaW0gKy4geS5pbSB9XG5cbmxldCBzdWIgeCB5ID0geyByZSA9IHgucmUgLS4geS5yZTsgaW0gPSB4LmltIC0uIHkuaW0gfVxuXG5sZXQgbmVnIHggPSB7IHJlID0gLS4geC5yZTsgaW0gPSAtLiB4LmltIH1cblxubGV0IGNvbmogeCA9IHsgcmUgPSB4LnJlOyBpbSA9IC0uIHguaW0gfVxuXG5sZXQgbXVsIHggeSA9IHsgcmUgPSB4LnJlICouIHkucmUgLS4geC5pbSAqLiB5LmltO1xuICAgICAgICAgICAgICAgIGltID0geC5yZSAqLiB5LmltICsuIHguaW0gKi4geS5yZSB9XG5cbmxldCBkaXYgeCB5ID1cbiAgaWYgYWJzX2Zsb2F0IHkucmUgPj0gYWJzX2Zsb2F0IHkuaW0gdGhlblxuICAgIGxldCByID0geS5pbSAvLiB5LnJlIGluXG4gICAgbGV0IGQgPSB5LnJlICsuIHIgKi4geS5pbSBpblxuICAgIHsgcmUgPSAoeC5yZSArLiByICouIHguaW0pIC8uIGQ7XG4gICAgICBpbSA9ICh4LmltIC0uIHIgKi4geC5yZSkgLy4gZCB9XG4gIGVsc2VcbiAgICBsZXQgciA9IHkucmUgLy4geS5pbSBpblxuICAgIGxldCBkID0geS5pbSArLiByICouIHkucmUgaW5cbiAgICB7IHJlID0gKHIgKi4geC5yZSArLiB4LmltKSAvLiBkO1xuICAgICAgaW0gPSAociAqLiB4LmltIC0uIHgucmUpIC8uIGQgfVxuXG5sZXQgaW52IHggPSBkaXYgb25lIHhcblxubGV0IG5vcm0yIHggPSB4LnJlICouIHgucmUgKy4geC5pbSAqLiB4LmltXG5cbmxldCBub3JtIHggPVxuICAoKiBXYXRjaCBvdXQgZm9yIG92ZXJmbG93IGluIGNvbXB1dGluZyByZV4yICsgaW1eMiAqKVxuICBsZXQgciA9IGFic19mbG9hdCB4LnJlIGFuZCBpID0gYWJzX2Zsb2F0IHguaW0gaW5cbiAgaWYgciA9IDAuMCB0aGVuIGlcbiAgZWxzZSBpZiBpID0gMC4wIHRoZW4gclxuICBlbHNlIGlmIHIgPj0gaSB0aGVuXG4gICAgbGV0IHEgPSBpIC8uIHIgaW4gciAqLiBzcXJ0KDEuMCArLiBxICouIHEpXG4gIGVsc2VcbiAgICBsZXQgcSA9IHIgLy4gaSBpbiBpICouIHNxcnQoMS4wICsuIHEgKi4gcSlcblxubGV0IGFyZyB4ID0gYXRhbjIgeC5pbSB4LnJlXG5cbmxldCBwb2xhciBuIGEgPSB7IHJlID0gY29zIGEgKi4gbjsgaW0gPSBzaW4gYSAqLiBuIH1cblxubGV0IHNxcnQgeCA9XG4gIGlmIHgucmUgPSAwLjAgJiYgeC5pbSA9IDAuMCB0aGVuIHsgcmUgPSAwLjA7IGltID0gMC4wIH1cbiAgZWxzZSBiZWdpblxuICAgIGxldCByID0gYWJzX2Zsb2F0IHgucmUgYW5kIGkgPSBhYnNfZmxvYXQgeC5pbSBpblxuICAgIGxldCB3ID1cbiAgICAgIGlmIHIgPj0gaSB0aGVuIGJlZ2luXG4gICAgICAgIGxldCBxID0gaSAvLiByIGluXG4gICAgICAgIHNxcnQocikgKi4gc3FydCgwLjUgKi4gKDEuMCArLiBzcXJ0KDEuMCArLiBxICouIHEpKSlcbiAgICAgIGVuZCBlbHNlIGJlZ2luXG4gICAgICAgIGxldCBxID0gciAvLiBpIGluXG4gICAgICAgIHNxcnQoaSkgKi4gc3FydCgwLjUgKi4gKHEgKy4gc3FydCgxLjAgKy4gcSAqLiBxKSkpXG4gICAgICBlbmQgaW5cbiAgICBpZiB4LnJlID49IDAuMFxuICAgIHRoZW4geyByZSA9IHc7ICBpbSA9IDAuNSAqLiB4LmltIC8uIHcgfVxuICAgIGVsc2UgeyByZSA9IDAuNSAqLiBpIC8uIHc7ICBpbSA9IGlmIHguaW0gPj0gMC4wIHRoZW4gdyBlbHNlIC0uIHcgfVxuICBlbmRcblxubGV0IGV4cCB4ID1cbiAgbGV0IGUgPSBleHAgeC5yZSBpbiB7IHJlID0gZSAqLiBjb3MgeC5pbTsgaW0gPSBlICouIHNpbiB4LmltIH1cblxubGV0IGxvZyB4ID0geyByZSA9IGxvZyAobm9ybSB4KTsgaW0gPSBhdGFuMiB4LmltIHgucmUgfVxuXG5sZXQgcG93IHggeSA9IGV4cCAobXVsIHkgKGxvZyB4KSlcbiIsIigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0NhbWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICBNYW51ZWwgU2VycmFubyBldCBYYXZpZXIgTGVyb3ksIElOUklBIFJvY3F1ZW5jb3VydCAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQ29weXJpZ2h0IDIwMDAgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCAgICAgKilcbigqICAgICBlbiBBdXRvbWF0aXF1ZS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQWxsIHJpZ2h0cyByZXNlcnZlZC4gIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgICAgKilcbigqICAgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIuMSwgd2l0aCB0aGUgICAgICAgICAgKilcbigqICAgc3BlY2lhbCBleGNlcHRpb24gb24gbGlua2luZyBkZXNjcmliZWQgaW4gdGhlIGZpbGUgTElDRU5TRS4gICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcblxuKCogTW9kdWxlIFtCaWdhcnJheV06IGxhcmdlLCBtdWx0aS1kaW1lbnNpb25hbCwgbnVtZXJpY2FsIGFycmF5cyAqKVxuXG4oKiBUaGVzZSB0eXBlcyBpbiBtdXN0IGJlIGtlcHQgaW4gc3luYyB3aXRoIHRoZSB0YWJsZXMgaW5cbiAgIC4uL3R5cGluZy90eXBlb3B0Lm1sICopXG5cbnR5cGUgZmxvYXQzMl9lbHQgPSBGbG9hdDMyX2VsdFxudHlwZSBmbG9hdDY0X2VsdCA9IEZsb2F0NjRfZWx0XG50eXBlIGludDhfc2lnbmVkX2VsdCA9IEludDhfc2lnbmVkX2VsdFxudHlwZSBpbnQ4X3Vuc2lnbmVkX2VsdCA9IEludDhfdW5zaWduZWRfZWx0XG50eXBlIGludDE2X3NpZ25lZF9lbHQgPSBJbnQxNl9zaWduZWRfZWx0XG50eXBlIGludDE2X3Vuc2lnbmVkX2VsdCA9IEludDE2X3Vuc2lnbmVkX2VsdFxudHlwZSBpbnQzMl9lbHQgPSBJbnQzMl9lbHRcbnR5cGUgaW50NjRfZWx0ID0gSW50NjRfZWx0XG50eXBlIGludF9lbHQgPSBJbnRfZWx0XG50eXBlIG5hdGl2ZWludF9lbHQgPSBOYXRpdmVpbnRfZWx0XG50eXBlIGNvbXBsZXgzMl9lbHQgPSBDb21wbGV4MzJfZWx0XG50eXBlIGNvbXBsZXg2NF9lbHQgPSBDb21wbGV4NjRfZWx0XG5cbnR5cGUgKCdhLCAnYikga2luZCA9XG4gICAgRmxvYXQzMiA6IChmbG9hdCwgZmxvYXQzMl9lbHQpIGtpbmRcbiAgfCBGbG9hdDY0IDogKGZsb2F0LCBmbG9hdDY0X2VsdCkga2luZFxuICB8IEludDhfc2lnbmVkIDogKGludCwgaW50OF9zaWduZWRfZWx0KSBraW5kXG4gIHwgSW50OF91bnNpZ25lZCA6IChpbnQsIGludDhfdW5zaWduZWRfZWx0KSBraW5kXG4gIHwgSW50MTZfc2lnbmVkIDogKGludCwgaW50MTZfc2lnbmVkX2VsdCkga2luZFxuICB8IEludDE2X3Vuc2lnbmVkIDogKGludCwgaW50MTZfdW5zaWduZWRfZWx0KSBraW5kXG4gIHwgSW50MzIgOiAoaW50MzIsIGludDMyX2VsdCkga2luZFxuICB8IEludDY0IDogKGludDY0LCBpbnQ2NF9lbHQpIGtpbmRcbiAgfCBJbnQgOiAoaW50LCBpbnRfZWx0KSBraW5kXG4gIHwgTmF0aXZlaW50IDogKG5hdGl2ZWludCwgbmF0aXZlaW50X2VsdCkga2luZFxuICB8IENvbXBsZXgzMiA6IChDb21wbGV4LnQsIGNvbXBsZXgzMl9lbHQpIGtpbmRcbiAgfCBDb21wbGV4NjQgOiAoQ29tcGxleC50LCBjb21wbGV4NjRfZWx0KSBraW5kXG4gIHwgQ2hhciA6IChjaGFyLCBpbnQ4X3Vuc2lnbmVkX2VsdCkga2luZFxuXG50eXBlIGNfbGF5b3V0ID0gQ19sYXlvdXRfdHlwXG50eXBlIGZvcnRyYW5fbGF5b3V0ID0gRm9ydHJhbl9sYXlvdXRfdHlwICgqKilcblxudHlwZSAnYSBsYXlvdXQgPVxuICAgIENfbGF5b3V0OiBjX2xheW91dCBsYXlvdXRcbiAgfCBGb3J0cmFuX2xheW91dDogZm9ydHJhbl9sYXlvdXQgbGF5b3V0XG5cbigqIEtlZXAgdGhvc2UgY29uc3RhbnRzIGluIHN5bmMgd2l0aCB0aGUgY2FtbF9iYV9raW5kIGVudW1lcmF0aW9uXG4gICBpbiBiaWdhcnJheS5oICopXG5cbmxldCBmbG9hdDMyID0gRmxvYXQzMlxubGV0IGZsb2F0NjQgPSBGbG9hdDY0XG5sZXQgaW50OF9zaWduZWQgPSBJbnQ4X3NpZ25lZFxubGV0IGludDhfdW5zaWduZWQgPSBJbnQ4X3Vuc2lnbmVkXG5sZXQgaW50MTZfc2lnbmVkID0gSW50MTZfc2lnbmVkXG5sZXQgaW50MTZfdW5zaWduZWQgPSBJbnQxNl91bnNpZ25lZFxubGV0IGludDMyID0gSW50MzJcbmxldCBpbnQ2NCA9IEludDY0XG5sZXQgaW50ID0gSW50XG5sZXQgbmF0aXZlaW50ID0gTmF0aXZlaW50XG5sZXQgY29tcGxleDMyID0gQ29tcGxleDMyXG5sZXQgY29tcGxleDY0ID0gQ29tcGxleDY0XG5sZXQgY2hhciA9IENoYXJcblxubGV0IGtpbmRfc2l6ZV9pbl9ieXRlcyA6IHR5cGUgYSBiLiAoYSwgYikga2luZCAtPiBpbnQgPSBmdW5jdGlvblxuICB8IEZsb2F0MzIgLT4gNFxuICB8IEZsb2F0NjQgLT4gOFxuICB8IEludDhfc2lnbmVkIC0+IDFcbiAgfCBJbnQ4X3Vuc2lnbmVkIC0+IDFcbiAgfCBJbnQxNl9zaWduZWQgLT4gMlxuICB8IEludDE2X3Vuc2lnbmVkIC0+IDJcbiAgfCBJbnQzMiAtPiA0XG4gIHwgSW50NjQgLT4gOFxuICB8IEludCAtPiBTeXMud29yZF9zaXplIC8gOFxuICB8IE5hdGl2ZWludCAtPiBTeXMud29yZF9zaXplIC8gOFxuICB8IENvbXBsZXgzMiAtPiA4XG4gIHwgQ29tcGxleDY0IC0+IDE2XG4gIHwgQ2hhciAtPiAxXG5cbigqIEtlZXAgdGhvc2UgY29uc3RhbnRzIGluIHN5bmMgd2l0aCB0aGUgY2FtbF9iYV9sYXlvdXQgZW51bWVyYXRpb25cbiAgIGluIGJpZ2FycmF5LmggKilcblxubGV0IGNfbGF5b3V0ID0gQ19sYXlvdXRcbmxldCBmb3J0cmFuX2xheW91dCA9IEZvcnRyYW5fbGF5b3V0XG5cbm1vZHVsZSBHZW5hcnJheSA9IHN0cnVjdFxuICB0eXBlICghJ2EsICEnYiwgISdjKSB0XG4gIGV4dGVybmFsIGNyZWF0ZTogKCdhLCAnYikga2luZCAtPiAnYyBsYXlvdXQgLT4gaW50IGFycmF5IC0+ICgnYSwgJ2IsICdjKSB0XG4gICAgID0gXCJjYW1sX2JhX2NyZWF0ZVwiXG4gIGV4dGVybmFsIGdldDogKCdhLCAnYiwgJ2MpIHQgLT4gaW50IGFycmF5IC0+ICdhXG4gICAgID0gXCJjYW1sX2JhX2dldF9nZW5lcmljXCJcbiAgZXh0ZXJuYWwgc2V0OiAoJ2EsICdiLCAnYykgdCAtPiBpbnQgYXJyYXkgLT4gJ2EgLT4gdW5pdFxuICAgICA9IFwiY2FtbF9iYV9zZXRfZ2VuZXJpY1wiXG5cbiAgbGV0IHJlYyBjbG9vcCBhcnIgaWR4IGYgY29sIG1heCA9XG4gICAgaWYgY29sID0gQXJyYXkubGVuZ3RoIGlkeCB0aGVuIHNldCBhcnIgaWR4IChmIGlkeClcbiAgICBlbHNlIGZvciBqID0gMCB0byBwcmVkIG1heC4oY29sKSBkb1xuICAgICAgICAgICBpZHguKGNvbCkgPC0gajtcbiAgICAgICAgICAgY2xvb3AgYXJyIGlkeCBmIChzdWNjIGNvbCkgbWF4XG4gICAgICAgICBkb25lXG4gIGxldCByZWMgZmxvb3AgYXJyIGlkeCBmIGNvbCBtYXggPVxuICAgIGlmIGNvbCA8IDAgdGhlbiBzZXQgYXJyIGlkeCAoZiBpZHgpXG4gICAgZWxzZSBmb3IgaiA9IDEgdG8gbWF4Lihjb2wpIGRvXG4gICAgICAgICAgIGlkeC4oY29sKSA8LSBqO1xuICAgICAgICAgICBmbG9vcCBhcnIgaWR4IGYgKHByZWQgY29sKSBtYXhcbiAgICAgICAgIGRvbmVcbiAgbGV0IGluaXQgKHR5cGUgdCkga2luZCAobGF5b3V0IDogdCBsYXlvdXQpIGRpbXMgZiA9XG4gICAgbGV0IGFyciA9IGNyZWF0ZSBraW5kIGxheW91dCBkaW1zIGluXG4gICAgbWF0Y2ggQXJyYXkubGVuZ3RoIGRpbXMsIGxheW91dCB3aXRoXG4gICAgfCAwLCBfIC0+IGFyclxuICAgIHwgZGxlbiwgQ19sYXlvdXQgLT4gY2xvb3AgYXJyIChBcnJheS5tYWtlIGRsZW4gMCkgZiAwIGRpbXM7IGFyclxuICAgIHwgZGxlbiwgRm9ydHJhbl9sYXlvdXQgLT4gZmxvb3AgYXJyIChBcnJheS5tYWtlIGRsZW4gMSkgZiAocHJlZCBkbGVuKSBkaW1zO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyXG5cbiAgZXh0ZXJuYWwgbnVtX2RpbXM6ICgnYSwgJ2IsICdjKSB0IC0+IGludCA9IFwiY2FtbF9iYV9udW1fZGltc1wiXG4gIGV4dGVybmFsIG50aF9kaW06ICgnYSwgJ2IsICdjKSB0IC0+IGludCAtPiBpbnQgPSBcImNhbWxfYmFfZGltXCJcbiAgbGV0IGRpbXMgYSA9XG4gICAgbGV0IG4gPSBudW1fZGltcyBhIGluXG4gICAgbGV0IGQgPSBBcnJheS5tYWtlIG4gMCBpblxuICAgIGZvciBpID0gMCB0byBuLTEgZG8gZC4oaSkgPC0gbnRoX2RpbSBhIGkgZG9uZTtcbiAgICBkXG5cbiAgZXh0ZXJuYWwga2luZDogKCdhLCAnYiwgJ2MpIHQgLT4gKCdhLCAnYikga2luZCA9IFwiY2FtbF9iYV9raW5kXCJcbiAgZXh0ZXJuYWwgbGF5b3V0OiAoJ2EsICdiLCAnYykgdCAtPiAnYyBsYXlvdXQgPSBcImNhbWxfYmFfbGF5b3V0XCJcbiAgZXh0ZXJuYWwgY2hhbmdlX2xheW91dDogKCdhLCAnYiwgJ2MpIHQgLT4gJ2QgbGF5b3V0IC0+ICgnYSwgJ2IsICdkKSB0XG4gICAgID0gXCJjYW1sX2JhX2NoYW5nZV9sYXlvdXRcIlxuXG4gIGxldCBzaXplX2luX2J5dGVzIGFyciA9XG4gICAgKGtpbmRfc2l6ZV9pbl9ieXRlcyAoa2luZCBhcnIpKSAqIChBcnJheS5mb2xkX2xlZnQgKCAqICkgMSAoZGltcyBhcnIpKVxuXG4gIGV4dGVybmFsIHN1Yl9sZWZ0OiAoJ2EsICdiLCBjX2xheW91dCkgdCAtPiBpbnQgLT4gaW50IC0+ICgnYSwgJ2IsIGNfbGF5b3V0KSB0XG4gICAgID0gXCJjYW1sX2JhX3N1YlwiXG4gIGV4dGVybmFsIHN1Yl9yaWdodDogKCdhLCAnYiwgZm9ydHJhbl9sYXlvdXQpIHQgLT4gaW50IC0+IGludCAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAoJ2EsICdiLCBmb3J0cmFuX2xheW91dCkgdFxuICAgICA9IFwiY2FtbF9iYV9zdWJcIlxuICBleHRlcm5hbCBzbGljZV9sZWZ0OiAoJ2EsICdiLCBjX2xheW91dCkgdCAtPiBpbnQgYXJyYXkgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgKCdhLCAnYiwgY19sYXlvdXQpIHRcbiAgICAgPSBcImNhbWxfYmFfc2xpY2VcIlxuICBleHRlcm5hbCBzbGljZV9yaWdodDogKCdhLCAnYiwgZm9ydHJhbl9sYXlvdXQpIHQgLT4gaW50IGFycmF5IC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICgnYSwgJ2IsIGZvcnRyYW5fbGF5b3V0KSB0XG4gICAgID0gXCJjYW1sX2JhX3NsaWNlXCJcbiAgZXh0ZXJuYWwgYmxpdDogKCdhLCAnYiwgJ2MpIHQgLT4gKCdhLCAnYiwgJ2MpIHQgLT4gdW5pdFxuICAgICA9IFwiY2FtbF9iYV9ibGl0XCJcbiAgZXh0ZXJuYWwgZmlsbDogKCdhLCAnYiwgJ2MpIHQgLT4gJ2EgLT4gdW5pdCA9IFwiY2FtbF9iYV9maWxsXCJcbmVuZFxuXG5tb2R1bGUgQXJyYXkwID0gc3RydWN0XG4gIHR5cGUgKCEnYSwgISdiLCAhJ2MpIHQgPSAoJ2EsICdiLCAnYykgR2VuYXJyYXkudFxuICBsZXQgY3JlYXRlIGtpbmQgbGF5b3V0ID1cbiAgICBHZW5hcnJheS5jcmVhdGUga2luZCBsYXlvdXQgW3x8XVxuICBsZXQgZ2V0IGFyciA9IEdlbmFycmF5LmdldCBhcnIgW3x8XVxuICBsZXQgc2V0IGFyciA9IEdlbmFycmF5LnNldCBhcnIgW3x8XVxuICBleHRlcm5hbCBraW5kOiAoJ2EsICdiLCAnYykgdCAtPiAoJ2EsICdiKSBraW5kID0gXCJjYW1sX2JhX2tpbmRcIlxuICBleHRlcm5hbCBsYXlvdXQ6ICgnYSwgJ2IsICdjKSB0IC0+ICdjIGxheW91dCA9IFwiY2FtbF9iYV9sYXlvdXRcIlxuXG4gIGV4dGVybmFsIGNoYW5nZV9sYXlvdXQ6ICgnYSwgJ2IsICdjKSB0IC0+ICdkIGxheW91dCAtPiAoJ2EsICdiLCAnZCkgdFxuICAgID0gXCJjYW1sX2JhX2NoYW5nZV9sYXlvdXRcIlxuXG4gIGxldCBzaXplX2luX2J5dGVzIGFyciA9IGtpbmRfc2l6ZV9pbl9ieXRlcyAoa2luZCBhcnIpXG5cbiAgZXh0ZXJuYWwgYmxpdDogKCdhLCAnYiwgJ2MpIHQgLT4gKCdhLCAnYiwgJ2MpIHQgLT4gdW5pdCA9IFwiY2FtbF9iYV9ibGl0XCJcbiAgZXh0ZXJuYWwgZmlsbDogKCdhLCAnYiwgJ2MpIHQgLT4gJ2EgLT4gdW5pdCA9IFwiY2FtbF9iYV9maWxsXCJcblxuICBsZXQgb2ZfdmFsdWUga2luZCBsYXlvdXQgdiA9XG4gICAgbGV0IGEgPSBjcmVhdGUga2luZCBsYXlvdXQgaW5cbiAgICBzZXQgYSB2O1xuICAgIGFcbiAgbGV0IGluaXQgPSBvZl92YWx1ZVxuZW5kXG5cbm1vZHVsZSBBcnJheTEgPSBzdHJ1Y3RcbiAgdHlwZSAoISdhLCAhJ2IsICEnYykgdCA9ICgnYSwgJ2IsICdjKSBHZW5hcnJheS50XG4gIGxldCBjcmVhdGUga2luZCBsYXlvdXQgZGltID1cbiAgICBHZW5hcnJheS5jcmVhdGUga2luZCBsYXlvdXQgW3xkaW18XVxuICBleHRlcm5hbCBnZXQ6ICgnYSwgJ2IsICdjKSB0IC0+IGludCAtPiAnYSA9IFwiJWNhbWxfYmFfcmVmXzFcIlxuICBleHRlcm5hbCBzZXQ6ICgnYSwgJ2IsICdjKSB0IC0+IGludCAtPiAnYSAtPiB1bml0ID0gXCIlY2FtbF9iYV9zZXRfMVwiXG4gIGV4dGVybmFsIHVuc2FmZV9nZXQ6ICgnYSwgJ2IsICdjKSB0IC0+IGludCAtPiAnYSA9IFwiJWNhbWxfYmFfdW5zYWZlX3JlZl8xXCJcbiAgZXh0ZXJuYWwgdW5zYWZlX3NldDogKCdhLCAnYiwgJ2MpIHQgLT4gaW50IC0+ICdhIC0+IHVuaXRcbiAgICAgPSBcIiVjYW1sX2JhX3Vuc2FmZV9zZXRfMVwiXG4gIGV4dGVybmFsIGRpbTogKCdhLCAnYiwgJ2MpIHQgLT4gaW50ID0gXCIlY2FtbF9iYV9kaW1fMVwiXG4gIGV4dGVybmFsIGtpbmQ6ICgnYSwgJ2IsICdjKSB0IC0+ICgnYSwgJ2IpIGtpbmQgPSBcImNhbWxfYmFfa2luZFwiXG4gIGV4dGVybmFsIGxheW91dDogKCdhLCAnYiwgJ2MpIHQgLT4gJ2MgbGF5b3V0ID0gXCJjYW1sX2JhX2xheW91dFwiXG5cbiAgZXh0ZXJuYWwgY2hhbmdlX2xheW91dDogKCdhLCAnYiwgJ2MpIHQgLT4gJ2QgbGF5b3V0IC0+ICgnYSwgJ2IsICdkKSB0XG4gICAgPSBcImNhbWxfYmFfY2hhbmdlX2xheW91dFwiXG5cbiAgbGV0IHNpemVfaW5fYnl0ZXMgYXJyID1cbiAgICAoa2luZF9zaXplX2luX2J5dGVzIChraW5kIGFycikpICogKGRpbSBhcnIpXG5cbiAgZXh0ZXJuYWwgc3ViOiAoJ2EsICdiLCAnYykgdCAtPiBpbnQgLT4gaW50IC0+ICgnYSwgJ2IsICdjKSB0ID0gXCJjYW1sX2JhX3N1YlwiXG4gIGxldCBzbGljZSAodHlwZSB0KSAoYSA6IChfLCBfLCB0KSBHZW5hcnJheS50KSBuID1cbiAgICBtYXRjaCBsYXlvdXQgYSB3aXRoXG4gICAgfCBDX2xheW91dCAtPiAoR2VuYXJyYXkuc2xpY2VfbGVmdCBhIFt8bnxdIDogKF8sIF8sIHQpIEdlbmFycmF5LnQpXG4gICAgfCBGb3J0cmFuX2xheW91dCAtPiAoR2VuYXJyYXkuc2xpY2VfcmlnaHQgYSBbfG58XTogKF8sIF8sIHQpIEdlbmFycmF5LnQpXG4gIGV4dGVybmFsIGJsaXQ6ICgnYSwgJ2IsICdjKSB0IC0+ICgnYSwgJ2IsICdjKSB0IC0+IHVuaXQgPSBcImNhbWxfYmFfYmxpdFwiXG4gIGV4dGVybmFsIGZpbGw6ICgnYSwgJ2IsICdjKSB0IC0+ICdhIC0+IHVuaXQgPSBcImNhbWxfYmFfZmlsbFwiXG4gIGxldCBjX2luaXQgYXJyIGRpbSBmID1cbiAgICBmb3IgaSA9IDAgdG8gcHJlZCBkaW0gZG8gdW5zYWZlX3NldCBhcnIgaSAoZiBpKSBkb25lXG4gIGxldCBmb3J0cmFuX2luaXQgYXJyIGRpbSBmID1cbiAgICBmb3IgaSA9IDEgdG8gZGltIGRvIHVuc2FmZV9zZXQgYXJyIGkgKGYgaSkgZG9uZVxuICBsZXQgaW5pdCAodHlwZSB0KSBraW5kIChsYXlvdXQgOiB0IGxheW91dCkgZGltIGYgPVxuICAgIGxldCBhcnIgPSBjcmVhdGUga2luZCBsYXlvdXQgZGltIGluXG4gICAgbWF0Y2ggbGF5b3V0IHdpdGhcbiAgICB8IENfbGF5b3V0IC0+IGNfaW5pdCBhcnIgZGltIGY7IGFyclxuICAgIHwgRm9ydHJhbl9sYXlvdXQgLT4gZm9ydHJhbl9pbml0IGFyciBkaW0gZjsgYXJyXG4gIGxldCBvZl9hcnJheSAodHlwZSB0KSBraW5kIChsYXlvdXQ6IHQgbGF5b3V0KSBkYXRhID1cbiAgICBsZXQgYmEgPSBjcmVhdGUga2luZCBsYXlvdXQgKEFycmF5Lmxlbmd0aCBkYXRhKSBpblxuICAgIGxldCBvZnMgPVxuICAgICAgbWF0Y2ggbGF5b3V0IHdpdGhcbiAgICAgICAgQ19sYXlvdXQgLT4gMFxuICAgICAgfCBGb3J0cmFuX2xheW91dCAtPiAxXG4gICAgaW5cbiAgICBmb3IgaSA9IDAgdG8gQXJyYXkubGVuZ3RoIGRhdGEgLSAxIGRvIHVuc2FmZV9zZXQgYmEgKGkgKyBvZnMpIGRhdGEuKGkpIGRvbmU7XG4gICAgYmFcbmVuZFxuXG5tb2R1bGUgQXJyYXkyID0gc3RydWN0XG4gIHR5cGUgKCEnYSwgISdiLCAhJ2MpIHQgPSAoJ2EsICdiLCAnYykgR2VuYXJyYXkudFxuICBsZXQgY3JlYXRlIGtpbmQgbGF5b3V0IGRpbTEgZGltMiA9XG4gICAgR2VuYXJyYXkuY3JlYXRlIGtpbmQgbGF5b3V0IFt8ZGltMTsgZGltMnxdXG4gIGV4dGVybmFsIGdldDogKCdhLCAnYiwgJ2MpIHQgLT4gaW50IC0+IGludCAtPiAnYSA9IFwiJWNhbWxfYmFfcmVmXzJcIlxuICBleHRlcm5hbCBzZXQ6ICgnYSwgJ2IsICdjKSB0IC0+IGludCAtPiBpbnQgLT4gJ2EgLT4gdW5pdCA9IFwiJWNhbWxfYmFfc2V0XzJcIlxuICBleHRlcm5hbCB1bnNhZmVfZ2V0OiAoJ2EsICdiLCAnYykgdCAtPiBpbnQgLT4gaW50IC0+ICdhXG4gICAgID0gXCIlY2FtbF9iYV91bnNhZmVfcmVmXzJcIlxuICBleHRlcm5hbCB1bnNhZmVfc2V0OiAoJ2EsICdiLCAnYykgdCAtPiBpbnQgLT4gaW50IC0+ICdhIC0+IHVuaXRcbiAgICAgPSBcIiVjYW1sX2JhX3Vuc2FmZV9zZXRfMlwiXG4gIGV4dGVybmFsIGRpbTE6ICgnYSwgJ2IsICdjKSB0IC0+IGludCA9IFwiJWNhbWxfYmFfZGltXzFcIlxuICBleHRlcm5hbCBkaW0yOiAoJ2EsICdiLCAnYykgdCAtPiBpbnQgPSBcIiVjYW1sX2JhX2RpbV8yXCJcbiAgZXh0ZXJuYWwga2luZDogKCdhLCAnYiwgJ2MpIHQgLT4gKCdhLCAnYikga2luZCA9IFwiY2FtbF9iYV9raW5kXCJcbiAgZXh0ZXJuYWwgbGF5b3V0OiAoJ2EsICdiLCAnYykgdCAtPiAnYyBsYXlvdXQgPSBcImNhbWxfYmFfbGF5b3V0XCJcblxuICBleHRlcm5hbCBjaGFuZ2VfbGF5b3V0OiAoJ2EsICdiLCAnYykgdCAtPiAnZCBsYXlvdXQgLT4gKCdhLCAnYiwgJ2QpIHRcbiAgICA9IFwiY2FtbF9iYV9jaGFuZ2VfbGF5b3V0XCJcblxuICBsZXQgc2l6ZV9pbl9ieXRlcyBhcnIgPVxuICAgIChraW5kX3NpemVfaW5fYnl0ZXMgKGtpbmQgYXJyKSkgKiAoZGltMSBhcnIpICogKGRpbTIgYXJyKVxuXG4gIGV4dGVybmFsIHN1Yl9sZWZ0OiAoJ2EsICdiLCBjX2xheW91dCkgdCAtPiBpbnQgLT4gaW50IC0+ICgnYSwgJ2IsIGNfbGF5b3V0KSB0XG4gICAgID0gXCJjYW1sX2JhX3N1YlwiXG4gIGV4dGVybmFsIHN1Yl9yaWdodDpcbiAgICAoJ2EsICdiLCBmb3J0cmFuX2xheW91dCkgdCAtPiBpbnQgLT4gaW50IC0+ICgnYSwgJ2IsIGZvcnRyYW5fbGF5b3V0KSB0XG4gICAgID0gXCJjYW1sX2JhX3N1YlwiXG4gIGxldCBzbGljZV9sZWZ0IGEgbiA9IEdlbmFycmF5LnNsaWNlX2xlZnQgYSBbfG58XVxuICBsZXQgc2xpY2VfcmlnaHQgYSBuID0gR2VuYXJyYXkuc2xpY2VfcmlnaHQgYSBbfG58XVxuICBleHRlcm5hbCBibGl0OiAoJ2EsICdiLCAnYykgdCAtPiAoJ2EsICdiLCAnYykgdCAtPiB1bml0ID0gXCJjYW1sX2JhX2JsaXRcIlxuICBleHRlcm5hbCBmaWxsOiAoJ2EsICdiLCAnYykgdCAtPiAnYSAtPiB1bml0ID0gXCJjYW1sX2JhX2ZpbGxcIlxuICBsZXQgY19pbml0IGFyciBkaW0xIGRpbTIgZiA9XG4gICAgZm9yIGkgPSAwIHRvIHByZWQgZGltMSBkb1xuICAgICAgZm9yIGogPSAwIHRvIHByZWQgZGltMiBkb1xuICAgICAgICB1bnNhZmVfc2V0IGFyciBpIGogKGYgaSBqKVxuICAgICAgZG9uZVxuICAgIGRvbmVcbiAgbGV0IGZvcnRyYW5faW5pdCBhcnIgZGltMSBkaW0yIGYgPVxuICAgIGZvciBqID0gMSB0byBkaW0yIGRvXG4gICAgICBmb3IgaSA9IDEgdG8gZGltMSBkb1xuICAgICAgICB1bnNhZmVfc2V0IGFyciBpIGogKGYgaSBqKVxuICAgICAgZG9uZVxuICAgIGRvbmVcbiAgbGV0IGluaXQgKHR5cGUgdCkga2luZCAobGF5b3V0IDogdCBsYXlvdXQpIGRpbTEgZGltMiBmID1cbiAgICBsZXQgYXJyID0gY3JlYXRlIGtpbmQgbGF5b3V0IGRpbTEgZGltMiBpblxuICAgIG1hdGNoIGxheW91dCB3aXRoXG4gICAgfCBDX2xheW91dCAtPiBjX2luaXQgYXJyIGRpbTEgZGltMiBmOyBhcnJcbiAgICB8IEZvcnRyYW5fbGF5b3V0IC0+IGZvcnRyYW5faW5pdCBhcnIgZGltMSBkaW0yIGY7IGFyclxuICBsZXQgb2ZfYXJyYXkgKHR5cGUgdCkga2luZCAobGF5b3V0OiB0IGxheW91dCkgZGF0YSA9XG4gICAgbGV0IGRpbTEgPSBBcnJheS5sZW5ndGggZGF0YSBpblxuICAgIGxldCBkaW0yID0gaWYgZGltMSA9IDAgdGhlbiAwIGVsc2UgQXJyYXkubGVuZ3RoIGRhdGEuKDApIGluXG4gICAgbGV0IGJhID0gY3JlYXRlIGtpbmQgbGF5b3V0IGRpbTEgZGltMiBpblxuICAgIGxldCBvZnMgPVxuICAgICAgbWF0Y2ggbGF5b3V0IHdpdGhcbiAgICAgICAgQ19sYXlvdXQgLT4gMFxuICAgICAgfCBGb3J0cmFuX2xheW91dCAtPiAxXG4gICAgaW5cbiAgICBmb3IgaSA9IDAgdG8gZGltMSAtIDEgZG9cbiAgICAgIGxldCByb3cgPSBkYXRhLihpKSBpblxuICAgICAgaWYgQXJyYXkubGVuZ3RoIHJvdyA8PiBkaW0yIHRoZW5cbiAgICAgICAgaW52YWxpZF9hcmcoXCJCaWdhcnJheS5BcnJheTIub2ZfYXJyYXk6IG5vbi1yZWN0YW5ndWxhciBkYXRhXCIpO1xuICAgICAgZm9yIGogPSAwIHRvIGRpbTIgLSAxIGRvXG4gICAgICAgIHVuc2FmZV9zZXQgYmEgKGkgKyBvZnMpIChqICsgb2ZzKSByb3cuKGopXG4gICAgICBkb25lXG4gICAgZG9uZTtcbiAgICBiYVxuZW5kXG5cbm1vZHVsZSBBcnJheTMgPSBzdHJ1Y3RcbiAgdHlwZSAoISdhLCAhJ2IsICEnYykgdCA9ICgnYSwgJ2IsICdjKSBHZW5hcnJheS50XG4gIGxldCBjcmVhdGUga2luZCBsYXlvdXQgZGltMSBkaW0yIGRpbTMgPVxuICAgIEdlbmFycmF5LmNyZWF0ZSBraW5kIGxheW91dCBbfGRpbTE7IGRpbTI7IGRpbTN8XVxuICBleHRlcm5hbCBnZXQ6ICgnYSwgJ2IsICdjKSB0IC0+IGludCAtPiBpbnQgLT4gaW50IC0+ICdhID0gXCIlY2FtbF9iYV9yZWZfM1wiXG4gIGV4dGVybmFsIHNldDogKCdhLCAnYiwgJ2MpIHQgLT4gaW50IC0+IGludCAtPiBpbnQgLT4gJ2EgLT4gdW5pdFxuICAgICA9IFwiJWNhbWxfYmFfc2V0XzNcIlxuICBleHRlcm5hbCB1bnNhZmVfZ2V0OiAoJ2EsICdiLCAnYykgdCAtPiBpbnQgLT4gaW50IC0+IGludCAtPiAnYVxuICAgICA9IFwiJWNhbWxfYmFfdW5zYWZlX3JlZl8zXCJcbiAgZXh0ZXJuYWwgdW5zYWZlX3NldDogKCdhLCAnYiwgJ2MpIHQgLT4gaW50IC0+IGludCAtPiBpbnQgLT4gJ2EgLT4gdW5pdFxuICAgICA9IFwiJWNhbWxfYmFfdW5zYWZlX3NldF8zXCJcbiAgZXh0ZXJuYWwgZGltMTogKCdhLCAnYiwgJ2MpIHQgLT4gaW50ID0gXCIlY2FtbF9iYV9kaW1fMVwiXG4gIGV4dGVybmFsIGRpbTI6ICgnYSwgJ2IsICdjKSB0IC0+IGludCA9IFwiJWNhbWxfYmFfZGltXzJcIlxuICBleHRlcm5hbCBkaW0zOiAoJ2EsICdiLCAnYykgdCAtPiBpbnQgPSBcIiVjYW1sX2JhX2RpbV8zXCJcbiAgZXh0ZXJuYWwga2luZDogKCdhLCAnYiwgJ2MpIHQgLT4gKCdhLCAnYikga2luZCA9IFwiY2FtbF9iYV9raW5kXCJcbiAgZXh0ZXJuYWwgbGF5b3V0OiAoJ2EsICdiLCAnYykgdCAtPiAnYyBsYXlvdXQgPSBcImNhbWxfYmFfbGF5b3V0XCJcblxuICBleHRlcm5hbCBjaGFuZ2VfbGF5b3V0OiAoJ2EsICdiLCAnYykgdCAtPiAnZCBsYXlvdXQgLT4gKCdhLCAnYiwgJ2QpIHRcbiAgICA9IFwiY2FtbF9iYV9jaGFuZ2VfbGF5b3V0XCJcblxuICBsZXQgc2l6ZV9pbl9ieXRlcyBhcnIgPVxuICAgIChraW5kX3NpemVfaW5fYnl0ZXMgKGtpbmQgYXJyKSkgKiAoZGltMSBhcnIpICogKGRpbTIgYXJyKSAqIChkaW0zIGFycilcblxuICBleHRlcm5hbCBzdWJfbGVmdDogKCdhLCAnYiwgY19sYXlvdXQpIHQgLT4gaW50IC0+IGludCAtPiAoJ2EsICdiLCBjX2xheW91dCkgdFxuICAgICA9IFwiY2FtbF9iYV9zdWJcIlxuICBleHRlcm5hbCBzdWJfcmlnaHQ6XG4gICAgICgnYSwgJ2IsIGZvcnRyYW5fbGF5b3V0KSB0IC0+IGludCAtPiBpbnQgLT4gKCdhLCAnYiwgZm9ydHJhbl9sYXlvdXQpIHRcbiAgICAgPSBcImNhbWxfYmFfc3ViXCJcbiAgbGV0IHNsaWNlX2xlZnRfMSBhIG4gbSA9IEdlbmFycmF5LnNsaWNlX2xlZnQgYSBbfG47IG18XVxuICBsZXQgc2xpY2VfcmlnaHRfMSBhIG4gbSA9IEdlbmFycmF5LnNsaWNlX3JpZ2h0IGEgW3xuOyBtfF1cbiAgbGV0IHNsaWNlX2xlZnRfMiBhIG4gPSBHZW5hcnJheS5zbGljZV9sZWZ0IGEgW3xufF1cbiAgbGV0IHNsaWNlX3JpZ2h0XzIgYSBuID0gR2VuYXJyYXkuc2xpY2VfcmlnaHQgYSBbfG58XVxuICBleHRlcm5hbCBibGl0OiAoJ2EsICdiLCAnYykgdCAtPiAoJ2EsICdiLCAnYykgdCAtPiB1bml0ID0gXCJjYW1sX2JhX2JsaXRcIlxuICBleHRlcm5hbCBmaWxsOiAoJ2EsICdiLCAnYykgdCAtPiAnYSAtPiB1bml0ID0gXCJjYW1sX2JhX2ZpbGxcIlxuICBsZXQgY19pbml0IGFyciBkaW0xIGRpbTIgZGltMyBmID1cbiAgICBmb3IgaSA9IDAgdG8gcHJlZCBkaW0xIGRvXG4gICAgICBmb3IgaiA9IDAgdG8gcHJlZCBkaW0yIGRvXG4gICAgICAgIGZvciBrID0gMCB0byBwcmVkIGRpbTMgZG9cbiAgICAgICAgICB1bnNhZmVfc2V0IGFyciBpIGogayAoZiBpIGogaylcbiAgICAgICAgZG9uZVxuICAgICAgZG9uZVxuICAgIGRvbmVcbiAgbGV0IGZvcnRyYW5faW5pdCBhcnIgZGltMSBkaW0yIGRpbTMgZiA9XG4gICAgZm9yIGsgPSAxIHRvIGRpbTMgZG9cbiAgICAgIGZvciBqID0gMSB0byBkaW0yIGRvXG4gICAgICAgIGZvciBpID0gMSB0byBkaW0xIGRvXG4gICAgICAgICAgdW5zYWZlX3NldCBhcnIgaSBqIGsgKGYgaSBqIGspXG4gICAgICAgIGRvbmVcbiAgICAgIGRvbmVcbiAgICBkb25lXG4gIGxldCBpbml0ICh0eXBlIHQpIGtpbmQgKGxheW91dCA6IHQgbGF5b3V0KSBkaW0xIGRpbTIgZGltMyBmID1cbiAgICBsZXQgYXJyID0gY3JlYXRlIGtpbmQgbGF5b3V0IGRpbTEgZGltMiBkaW0zIGluXG4gICAgbWF0Y2ggbGF5b3V0IHdpdGhcbiAgICB8IENfbGF5b3V0IC0+IGNfaW5pdCBhcnIgZGltMSBkaW0yIGRpbTMgZjsgYXJyXG4gICAgfCBGb3J0cmFuX2xheW91dCAtPiBmb3J0cmFuX2luaXQgYXJyIGRpbTEgZGltMiBkaW0zIGY7IGFyclxuICBsZXQgb2ZfYXJyYXkgKHR5cGUgdCkga2luZCAobGF5b3V0OiB0IGxheW91dCkgZGF0YSA9XG4gICAgbGV0IGRpbTEgPSBBcnJheS5sZW5ndGggZGF0YSBpblxuICAgIGxldCBkaW0yID0gaWYgZGltMSA9IDAgdGhlbiAwIGVsc2UgQXJyYXkubGVuZ3RoIGRhdGEuKDApIGluXG4gICAgbGV0IGRpbTMgPSBpZiBkaW0yID0gMCB0aGVuIDAgZWxzZSBBcnJheS5sZW5ndGggZGF0YS4oMCkuKDApIGluXG4gICAgbGV0IGJhID0gY3JlYXRlIGtpbmQgbGF5b3V0IGRpbTEgZGltMiBkaW0zIGluXG4gICAgbGV0IG9mcyA9XG4gICAgICBtYXRjaCBsYXlvdXQgd2l0aFxuICAgICAgICBDX2xheW91dCAtPiAwXG4gICAgICB8IEZvcnRyYW5fbGF5b3V0IC0+IDFcbiAgICBpblxuICAgIGZvciBpID0gMCB0byBkaW0xIC0gMSBkb1xuICAgICAgbGV0IHJvdyA9IGRhdGEuKGkpIGluXG4gICAgICBpZiBBcnJheS5sZW5ndGggcm93IDw+IGRpbTIgdGhlblxuICAgICAgICBpbnZhbGlkX2FyZyhcIkJpZ2FycmF5LkFycmF5My5vZl9hcnJheTogbm9uLWN1YmljIGRhdGFcIik7XG4gICAgICBmb3IgaiA9IDAgdG8gZGltMiAtIDEgZG9cbiAgICAgICAgbGV0IGNvbCA9IHJvdy4oaikgaW5cbiAgICAgICAgaWYgQXJyYXkubGVuZ3RoIGNvbCA8PiBkaW0zIHRoZW5cbiAgICAgICAgICBpbnZhbGlkX2FyZyhcIkJpZ2FycmF5LkFycmF5My5vZl9hcnJheTogbm9uLWN1YmljIGRhdGFcIik7XG4gICAgICAgIGZvciBrID0gMCB0byBkaW0zIC0gMSBkb1xuICAgICAgICAgIHVuc2FmZV9zZXQgYmEgKGkgKyBvZnMpIChqICsgb2ZzKSAoayArIG9mcykgY29sLihrKVxuICAgICAgICBkb25lXG4gICAgICBkb25lXG4gICAgZG9uZTtcbiAgICBiYVxuZW5kXG5cbmV4dGVybmFsIGdlbmFycmF5X29mX2FycmF5MDogKCdhLCAnYiwgJ2MpIEFycmF5MC50IC0+ICgnYSwgJ2IsICdjKSBHZW5hcnJheS50XG4gICA9IFwiJWlkZW50aXR5XCJcbmV4dGVybmFsIGdlbmFycmF5X29mX2FycmF5MTogKCdhLCAnYiwgJ2MpIEFycmF5MS50IC0+ICgnYSwgJ2IsICdjKSBHZW5hcnJheS50XG4gICA9IFwiJWlkZW50aXR5XCJcbmV4dGVybmFsIGdlbmFycmF5X29mX2FycmF5MjogKCdhLCAnYiwgJ2MpIEFycmF5Mi50IC0+ICgnYSwgJ2IsICdjKSBHZW5hcnJheS50XG4gICA9IFwiJWlkZW50aXR5XCJcbmV4dGVybmFsIGdlbmFycmF5X29mX2FycmF5MzogKCdhLCAnYiwgJ2MpIEFycmF5My50IC0+ICgnYSwgJ2IsICdjKSBHZW5hcnJheS50XG4gICA9IFwiJWlkZW50aXR5XCJcbmxldCBhcnJheTBfb2ZfZ2VuYXJyYXkgYSA9XG4gIGlmIEdlbmFycmF5Lm51bV9kaW1zIGEgPSAwIHRoZW4gYVxuICBlbHNlIGludmFsaWRfYXJnIFwiQmlnYXJyYXkuYXJyYXkwX29mX2dlbmFycmF5XCJcbmxldCBhcnJheTFfb2ZfZ2VuYXJyYXkgYSA9XG4gIGlmIEdlbmFycmF5Lm51bV9kaW1zIGEgPSAxIHRoZW4gYVxuICBlbHNlIGludmFsaWRfYXJnIFwiQmlnYXJyYXkuYXJyYXkxX29mX2dlbmFycmF5XCJcbmxldCBhcnJheTJfb2ZfZ2VuYXJyYXkgYSA9XG4gIGlmIEdlbmFycmF5Lm51bV9kaW1zIGEgPSAyIHRoZW4gYVxuICBlbHNlIGludmFsaWRfYXJnIFwiQmlnYXJyYXkuYXJyYXkyX29mX2dlbmFycmF5XCJcbmxldCBhcnJheTNfb2ZfZ2VuYXJyYXkgYSA9XG4gIGlmIEdlbmFycmF5Lm51bV9kaW1zIGEgPSAzIHRoZW4gYVxuICBlbHNlIGludmFsaWRfYXJnIFwiQmlnYXJyYXkuYXJyYXkzX29mX2dlbmFycmF5XCJcblxuZXh0ZXJuYWwgcmVzaGFwZTpcbiAgICgnYSwgJ2IsICdjKSBHZW5hcnJheS50IC0+IGludCBhcnJheSAtPiAoJ2EsICdiLCAnYykgR2VuYXJyYXkudFxuICAgPSBcImNhbWxfYmFfcmVzaGFwZVwiXG5sZXQgcmVzaGFwZV8wIGEgPSByZXNoYXBlIGEgW3x8XVxubGV0IHJlc2hhcGVfMSBhIGRpbTEgPSByZXNoYXBlIGEgW3xkaW0xfF1cbmxldCByZXNoYXBlXzIgYSBkaW0xIGRpbTIgPSByZXNoYXBlIGEgW3xkaW0xO2RpbTJ8XVxubGV0IHJlc2hhcGVfMyBhIGRpbTEgZGltMiBkaW0zID0gcmVzaGFwZSBhIFt8ZGltMTtkaW0yO2RpbTN8XVxuXG4oKiBGb3JjZSBjYW1sX2JhX2dldF97MSwyLDMsTn0gdG8gYmUgbGlua2VkIGluLCBzaW5jZSB3ZSBkb24ndCByZWZlclxuICAgdG8gdGhvc2UgcHJpbWl0aXZlcyBkaXJlY3RseSBpbiB0aGlzIGZpbGUgKilcblxubGV0IF8gPVxuICBsZXQgXyA9IEdlbmFycmF5LmdldCBpblxuICBsZXQgXyA9IEFycmF5MS5nZXQgaW5cbiAgbGV0IF8gPSBBcnJheTIuZ2V0IGluXG4gIGxldCBfID0gQXJyYXkzLmdldCBpblxuICAoKVxuXG5bQEBAb2NhbWwud2FybmluZyBcIi0zMlwiXVxuZXh0ZXJuYWwgZ2V0MTogdW5pdCAtPiB1bml0ID0gXCJjYW1sX2JhX2dldF8xXCJcbmV4dGVybmFsIGdldDI6IHVuaXQgLT4gdW5pdCA9IFwiY2FtbF9iYV9nZXRfMlwiXG5leHRlcm5hbCBnZXQzOiB1bml0IC0+IHVuaXQgPSBcImNhbWxfYmFfZ2V0XzNcIlxuZXh0ZXJuYWwgc2V0MTogdW5pdCAtPiB1bml0ID0gXCJjYW1sX2JhX3NldF8xXCJcbmV4dGVybmFsIHNldDI6IHVuaXQgLT4gdW5pdCA9IFwiY2FtbF9iYV9zZXRfMlwiXG5leHRlcm5hbCBzZXQzOiB1bml0IC0+IHVuaXQgPSBcImNhbWxfYmFfc2V0XzNcIlxuIiwiKCogZ2VuZXJhdGVkIGJ5IGR1bmUgKilcblxuKCoqIEBjYW5vbmljYWwgSnNvb19ydW50aW1lLlJ1bnRpbWVfdmVyc2lvbiAqKVxubW9kdWxlIFJ1bnRpbWVfdmVyc2lvbiA9IEpzb29fcnVudGltZV9fUnVudGltZV92ZXJzaW9uXG5cbm1vZHVsZSBKc29vX3J1bnRpbWVfXyA9IHN0cnVjdCBlbmRcbltAQGRlcHJlY2F0ZWQgXCJ0aGlzIG1vZHVsZSBpcyBzaGFkb3dlZFwiXVxuIiwibW9kdWxlIEpzID0gc3RydWN0XG4gIHR5cGUgdFxuXG4gIHR5cGUgJ2EganNfYXJyYXkgPSB0XG5cbiAgdHlwZSAoJ2EsICdiKSBtZXRoX2NhbGxiYWNrID0gdFxuXG4gIGV4dGVybmFsIHN0cmluZyA6IHN0cmluZyAtPiB0ID0gXCJjYW1sX2pzc3RyaW5nX29mX3N0cmluZ1wiXG5cbiAgZXh0ZXJuYWwgdG9fc3RyaW5nIDogdCAtPiBzdHJpbmcgPSBcImNhbWxfc3RyaW5nX29mX2pzc3RyaW5nXCJcblxuICBleHRlcm5hbCBieXRlc3RyaW5nIDogc3RyaW5nIC0+IHQgPSBcImNhbWxfanNieXRlc19vZl9zdHJpbmdcIlxuXG4gIGV4dGVybmFsIHRvX2J5dGVzdHJpbmcgOiB0IC0+IHN0cmluZyA9IFwiY2FtbF9zdHJpbmdfb2ZfanNieXRlc1wiXG5cbiAgZXh0ZXJuYWwgYm9vbCA6IGJvb2wgLT4gdCA9IFwiY2FtbF9qc19mcm9tX2Jvb2xcIlxuXG4gIGV4dGVybmFsIHRvX2Jvb2wgOiB0IC0+IGJvb2wgPSBcImNhbWxfanNfdG9fYm9vbFwiXG5cbiAgZXh0ZXJuYWwgYXJyYXkgOiAnYSBhcnJheSAtPiB0ID0gXCJjYW1sX2pzX2Zyb21fYXJyYXlcIlxuXG4gIGV4dGVybmFsIHRvX2FycmF5IDogdCAtPiAnYSBhcnJheSA9IFwiY2FtbF9qc190b19hcnJheVwiXG5cbiAgZXh0ZXJuYWwgbnVtYmVyX29mX2Zsb2F0IDogZmxvYXQgLT4gdCA9IFwiY2FtbF9qc19mcm9tX2Zsb2F0XCJcblxuICBleHRlcm5hbCBmbG9hdF9vZl9udW1iZXIgOiB0IC0+IGZsb2F0ID0gXCJjYW1sX2pzX3RvX2Zsb2F0XCJcblxuICBleHRlcm5hbCBudW1iZXJfb2ZfaW50MzIgOiBpbnQzMiAtPiB0ID0gXCJjYW1sX2pzX2Zyb21faW50MzJcIlxuXG4gIGV4dGVybmFsIGludDMyX29mX251bWJlciA6IHQgLT4gaW50MzIgPSBcImNhbWxfanNfdG9faW50MzJcIlxuXG4gIGV4dGVybmFsIG51bWJlcl9vZl9uYXRpdmVpbnQgOiBuYXRpdmVpbnQgLT4gdCA9IFwiY2FtbF9qc19mcm9tX25hdGl2ZWludFwiXG5cbiAgZXh0ZXJuYWwgbmF0aXZlaW50X29mX251bWJlciA6IHQgLT4gbmF0aXZlaW50ID0gXCJjYW1sX2pzX3RvX25hdGl2ZWludFwiXG5cbiAgZXh0ZXJuYWwgdHlwZW9mIDogdCAtPiB0ID0gXCJjYW1sX2pzX3R5cGVvZlwiXG5cbiAgZXh0ZXJuYWwgaW5zdGFuY2VvZiA6IHQgLT4gdCAtPiBib29sID0gXCJjYW1sX2pzX2luc3RhbmNlb2ZcIlxuXG4gIGV4dGVybmFsIGRlYnVnZ2VyIDogdW5pdCAtPiB1bml0ID0gXCJkZWJ1Z2dlclwiXG5cbiAgZXh0ZXJuYWwgZ2V0IDogdCAtPiB0IC0+IHQgPSBcImNhbWxfanNfZ2V0XCJcblxuICBleHRlcm5hbCBzZXQgOiB0IC0+IHQgLT4gdCAtPiB1bml0ID0gXCJjYW1sX2pzX3NldFwiXG5cbiAgZXh0ZXJuYWwgZGVsZXRlIDogdCAtPiB0IC0+IHVuaXQgPSBcImNhbWxfanNfZGVsZXRlXCJcblxuICBleHRlcm5hbCBjYWxsIDogdCAtPiB0IC0+IHQgYXJyYXkgLT4gdCA9IFwiY2FtbF9qc19jYWxsXCJcblxuICBleHRlcm5hbCBmdW5fY2FsbCA6IHQgLT4gdCBhcnJheSAtPiB0ID0gXCJjYW1sX2pzX2Z1bl9jYWxsXCJcblxuICBleHRlcm5hbCBtZXRoX2NhbGwgOiB0IC0+IHN0cmluZyAtPiB0IGFycmF5IC0+IHQgPSBcImNhbWxfanNfbWV0aF9jYWxsXCJcblxuICBleHRlcm5hbCBuZXdfb2JqIDogdCAtPiB0IGFycmF5IC0+IHQgPSBcImNhbWxfanNfbmV3XCJcblxuICBleHRlcm5hbCBuZXdfb2JqX2FyciA6IHQgLT4gdCBqc19hcnJheSAtPiB0ID0gXCJjYW1sX29qc19uZXdfYXJyXCJcblxuICBleHRlcm5hbCBvYmogOiAoc3RyaW5nICogdCkgYXJyYXkgLT4gdCA9IFwiY2FtbF9qc19vYmplY3RcIlxuXG4gIGV4dGVybmFsIGVxdWFscyA6IHQgLT4gdCAtPiBib29sID0gXCJjYW1sX2pzX2VxdWFsc1wiXG5cbiAgZXh0ZXJuYWwgc3RyaWN0X2VxdWFscyA6IHQgLT4gdCAtPiBib29sID0gXCJjYW1sX2pzX3N0cmljdF9lcXVhbHNcIlxuXG4gIGV4dGVybmFsIHB1cmVfZXhwciA6ICh1bml0IC0+ICdhKSAtPiAnYSA9IFwiY2FtbF9qc19wdXJlX2V4cHJcIlxuXG4gIGV4dGVybmFsIGV2YWxfc3RyaW5nIDogc3RyaW5nIC0+ICdhID0gXCJjYW1sX2pzX2V2YWxfc3RyaW5nXCJcblxuICBleHRlcm5hbCBqc19leHByIDogc3RyaW5nIC0+ICdhID0gXCJjYW1sX2pzX2V4cHJcIlxuXG4gIGV4dGVybmFsIHB1cmVfanNfZXhwciA6IHN0cmluZyAtPiAnYSA9IFwiY2FtbF9wdXJlX2pzX2V4cHJcIlxuXG4gIGV4dGVybmFsIGNhbGxiYWNrIDogKCdiIC0+ICdhKSAtPiAoJ2IsICdhKSBtZXRoX2NhbGxiYWNrXG4gICAgPSBcImNhbWxfanNfd3JhcF9jYWxsYmFja191bnNhZmVcIlxuXG4gIGV4dGVybmFsIGNhbGxiYWNrX3dpdGhfYXJndW1lbnRzIDpcbiAgICAodCBqc19hcnJheSAtPiAnYikgLT4gKCdjLCB0IGpzX2FycmF5IC0+ICdiKSBtZXRoX2NhbGxiYWNrXG4gICAgPSBcImNhbWxfanNfd3JhcF9jYWxsYmFja19hcmd1bWVudHNcIlxuXG4gIGV4dGVybmFsIGNhbGxiYWNrX3dpdGhfYXJpdHkgOiBpbnQgLT4gKCdhIC0+ICdiKSAtPiAoJ2MsICdhIC0+ICdiKSBtZXRoX2NhbGxiYWNrXG4gICAgPSBcImNhbWxfanNfd3JhcF9jYWxsYmFja19zdHJpY3RcIlxuXG4gIGV4dGVybmFsIG1ldGhfY2FsbGJhY2sgOiAoJ2IgLT4gJ2EpIC0+ICgnYiwgJ2EpIG1ldGhfY2FsbGJhY2tcbiAgICA9IFwiY2FtbF9qc193cmFwX21ldGhfY2FsbGJhY2tfdW5zYWZlXCJcblxuICBleHRlcm5hbCBtZXRoX2NhbGxiYWNrX3dpdGhfYXJpdHkgOiBpbnQgLT4gKCdiIC0+ICdhKSAtPiAoJ2IsICdhKSBtZXRoX2NhbGxiYWNrXG4gICAgPSBcImNhbWxfanNfd3JhcF9tZXRoX2NhbGxiYWNrX3N0cmljdFwiXG5cbiAgZXh0ZXJuYWwgbWV0aF9jYWxsYmFja193aXRoX2FyZ3VtZW50cyA6XG4gICAgKCdiIC0+IHQganNfYXJyYXkgLT4gJ2EpIC0+ICgnYiwgdCBqc19hcnJheSAtPiAnYSkgbWV0aF9jYWxsYmFja1xuICAgID0gXCJjYW1sX2pzX3dyYXBfbWV0aF9jYWxsYmFja19hcmd1bWVudHNcIlxuXG4gIGV4dGVybmFsIHdyYXBfY2FsbGJhY2sgOiAoJ2EgLT4gJ2IpIC0+ICgnYywgJ2EgLT4gJ2IpIG1ldGhfY2FsbGJhY2tcbiAgICA9IFwiY2FtbF9qc193cmFwX2NhbGxiYWNrXCJcblxuICBleHRlcm5hbCB3cmFwX21ldGhfY2FsbGJhY2sgOiAoJ2EgLT4gJ2IpIC0+ICgnYSwgJ2IpIG1ldGhfY2FsbGJhY2tcbiAgICA9IFwiY2FtbF9qc193cmFwX21ldGhfY2FsbGJhY2tcIlxuZW5kXG5cbm1vZHVsZSBTeXMgPSBzdHJ1Y3RcbiAgdHlwZSAnYSBjYWxsYmFjayA9ICdhXG5cbiAgZXh0ZXJuYWwgY3JlYXRlX2ZpbGUgOiBuYW1lOnN0cmluZyAtPiBjb250ZW50OnN0cmluZyAtPiB1bml0ID0gXCJjYW1sX2NyZWF0ZV9maWxlXCJcblxuICBleHRlcm5hbCByZWFkX2ZpbGUgOiBuYW1lOnN0cmluZyAtPiBzdHJpbmcgPSBcImNhbWxfcmVhZF9maWxlX2NvbnRlbnRcIlxuXG4gIGV4dGVybmFsIHNldF9jaGFubmVsX291dHB1dCcgOiBvdXRfY2hhbm5lbCAtPiAoanNfc3RyaW5nOkpzLnQgLT4gdW5pdCkgY2FsbGJhY2sgLT4gdW5pdFxuICAgID0gXCJjYW1sX21sX3NldF9jaGFubmVsX291dHB1dFwiXG5cbiAgZXh0ZXJuYWwgc2V0X2NoYW5uZWxfaW5wdXQnIDogaW5fY2hhbm5lbCAtPiAodW5pdCAtPiBzdHJpbmcpIGNhbGxiYWNrIC0+IHVuaXRcbiAgICA9IFwiY2FtbF9tbF9zZXRfY2hhbm5lbF9yZWZpbGxcIlxuXG4gIGV4dGVybmFsIG1vdW50X3BvaW50IDogdW5pdCAtPiBzdHJpbmcgbGlzdCA9IFwiY2FtbF9saXN0X21vdW50X3BvaW50XCJcblxuICBleHRlcm5hbCBtb3VudF9hdXRvbG9hZCA6IHN0cmluZyAtPiAoc3RyaW5nIC0+IHN0cmluZyAtPiBzdHJpbmcgb3B0aW9uKSBjYWxsYmFjayAtPiB1bml0XG4gICAgPSBcImNhbWxfbW91bnRfYXV0b2xvYWRcIlxuXG4gIGV4dGVybmFsIHVubW91bnQgOiBzdHJpbmcgLT4gdW5pdCA9IFwiY2FtbF91bm1vdW50XCJcblxuICB0eXBlIHJlZGlyZWN0aW9uXG5cbiAgZXh0ZXJuYWwgcmVkaXJlY3RfY2hhbm5lbCA6IG91dF9jaGFubmVsIC0+IGludG86b3V0X2NoYW5uZWwgLT4gcmVkaXJlY3Rpb25cbiAgICA9IFwiY2FtbF9tbF9jaGFubmVsX3JlZGlyZWN0XCJcblxuICBleHRlcm5hbCByZXN0b3JlX2NoYW5uZWwgOiBvdXRfY2hhbm5lbCAtPiByZWRpcmVjdGlvbiAtPiB1bml0XG4gICAgPSBcImNhbWxfbWxfY2hhbm5lbF9yZXN0b3JlXCJcblxuICBtb2R1bGUgQ29uZmlnID0gc3RydWN0XG4gICAgZXh0ZXJuYWwgdXNlX2pzX3N0cmluZyA6IHVuaXQgLT4gYm9vbCA9IFwiY2FtbF9qc29vX2ZsYWdzX3VzZV9qc19zdHJpbmdcIlxuXG4gICAgZXh0ZXJuYWwgZWZmZWN0cyA6IHVuaXQgLT4gYm9vbCA9IFwiY2FtbF9qc29vX2ZsYWdzX2VmZmVjdHNcIlxuICBlbmRcblxuICBsZXQgdmVyc2lvbiA9IFJ1bnRpbWVfdmVyc2lvbi5zXG5cbiAgbGV0IGdpdF92ZXJzaW9uID0gUnVudGltZV92ZXJzaW9uLmdpdF92ZXJzaW9uXG5lbmRcblxubW9kdWxlIEVycm9yIDogc2lnXG4gIHR5cGUgdFxuXG4gIHZhbCByYWlzZV8gOiB0IC0+ICdhXG5cbiAgdmFsIGF0dGFjaF9qc19iYWNrdHJhY2UgOiBleG4gLT4gZm9yY2U6Ym9vbCAtPiBleG5cbiAgKCoqIEF0dGFjaCBhIEphdmFzU2NyaXB0IGVycm9yIHRvIGFuIE9DYW1sIGV4Y2VwdGlvbi4gIGlmIFtmb3JjZSA9IGZhbHNlXSBhbmQgYVxuICAgIEphdmFzU2NyaXB0IGVycm9yIGlzIGFscmVhZHkgYXR0YWNoZWQsIGl0IHdpbGwgZG8gbm90aGluZy4gVGhpcyBmdW5jdGlvbiBpcyB1c2VmdWwgdG9cbiAgICBzdG9yZSBhbmQgcmV0cmlldmUgaW5mb3JtYXRpb24gYWJvdXQgSmF2YVNjcmlwdCBzdGFjayB0cmFjZXMuXG5cbiAgICBBdHRhY2hpbmcgSmF2YXNTY3JpcHQgZXJyb3JzIHdpbGwgaGFwcGVuIGF1dG9tYXRpY2FsbHkgd2hlbiBjb21waWxpbmcgd2l0aFxuICAgIFstLWVuYWJsZSB3aXRoLWpzLWVycm9yXS4gKilcblxuICB2YWwgb2ZfZXhuIDogZXhuIC0+IHQgb3B0aW9uXG4gICgqKiBFeHRyYWN0IGEgSmF2YVNjcmlwdCBlcnJvciBhdHRhY2hlZCB0byBhbiBPQ2FtbCBleGNlcHRpb24sIGlmIGFueS4gIFRoaXMgaXMgdXNlZnVsIHRvXG4gICAgICBpbnNwZWN0IGFuIGV2ZW50dWFsIHN0YWNrIHN0cmFjZSwgZXNwZWNpYWxseSB3aGVuIHNvdXJjZW1hcCBpcyBlbmFibGVkLiAqKVxuXG4gIGV4Y2VwdGlvbiBFeG4gb2YgdFxuICAoKiogVGhlIFtFcnJvcl0gZXhjZXB0aW9uIHdyYXAgamF2YXNjcmlwdCBleGNlcHRpb25zIHdoZW4gY2F1Z2h0IGJ5IE9DYW1sIGNvZGUuXG4gICAgICBJbiBjYXNlIHRoZSBqYXZhc2NyaXB0IGV4Y2VwdGlvbiBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgamF2YXNjcmlwdCBbRXJyb3JdLFxuICAgICAgaXQgd2lsbCBiZSBzZXJpYWxpemVkIGFuZCB3cmFwcGVkIGludG8gYSBbRmFpbHVyZV0gZXhjZXB0aW9uLlxuICAqKVxuZW5kID0gc3RydWN0XG4gIHR5cGUgdFxuXG4gIGV4Y2VwdGlvbiBFeG4gb2YgdFxuXG4gIGxldCBfID0gQ2FsbGJhY2sucmVnaXN0ZXJfZXhjZXB0aW9uIFwianNFcnJvclwiIChFeG4gKE9iai5tYWdpYyBbfHxdKSlcblxuICBsZXQgcmFpc2VfIDogdCAtPiAnYSA9IEpzLmpzX2V4cHIgXCIoZnVuY3Rpb24gKGV4bikgeyB0aHJvdyBleG4gfSlcIlxuXG4gIGV4dGVybmFsIG9mX2V4biA6IGV4biAtPiB0IG9wdGlvbiA9IFwiY2FtbF9qc19lcnJvcl9vcHRpb25fb2ZfZXhjZXB0aW9uXCJcblxuICBleHRlcm5hbCBhdHRhY2hfanNfYmFja3RyYWNlIDogZXhuIC0+IGZvcmNlOmJvb2wgLT4gZXhuID0gXCJjYW1sX2V4bl93aXRoX2pzX2JhY2t0cmFjZVwiXG5lbmRcblxuW0BAQG9jYW1sLndhcm5pbmcgXCItMzItNjBcIl1cblxubW9kdWxlIEZvcl9jb21wYXRpYmlsaXR5X29ubHkgPSBzdHJ1Y3RcbiAgKCogQWRkIHByaW1pdGl2ZXMgZm9yIGNvbXBhdGliaWxpdHkgcmVhc29ucy4gRXhpc3RpbmcgdXNlcnMgbWlnaHRcbiAgICAgZGVwZW5kIG9uIGl0IChlLmcuIGdlbl9qc19hcGkpLCB3ZSBkb250IHdhbnQgdGhlIG9jYW1sIGNvbXBpbGVyXG4gICAgIHRvIGNvbXBsYWluIGFib3V0IHRoZXNlcyBtaXNzaW5nIHByaW1pdGl2ZXMuICopXG5cbiAgZXh0ZXJuYWwgY2FtbF9qc19mcm9tX3N0cmluZyA6IHN0cmluZyAtPiBKcy50ID0gXCJjYW1sX2pzX2Zyb21fc3RyaW5nXCJcblxuICBleHRlcm5hbCBjYW1sX2pzX3RvX2J5dGVfc3RyaW5nIDogSnMudCAtPiBzdHJpbmcgPSBcImNhbWxfanNfdG9fYnl0ZV9zdHJpbmdcIlxuXG4gIGV4dGVybmFsIGNhbWxfanNfdG9fc3RyaW5nIDogSnMudCAtPiBzdHJpbmcgPSBcImNhbWxfanNfdG9fc3RyaW5nXCJcblxuICBleHRlcm5hbCBjYW1sX2xpc3Rfb2ZfanNfYXJyYXkgOiAnYSBKcy5qc19hcnJheSAtPiAnYSBsaXN0ID0gXCJjYW1sX2xpc3Rfb2ZfanNfYXJyYXlcIlxuXG4gIGV4dGVybmFsIGNhbWxfbGlzdF90b19qc19hcnJheSA6ICdhIGxpc3QgLT4gJ2EgSnMuanNfYXJyYXkgPSBcImNhbWxfbGlzdF90b19qc19hcnJheVwiXG5cbiAgZXh0ZXJuYWwgdmFyaWFibGUgOiBzdHJpbmcgLT4gJ2EgPSBcImNhbWxfanNfdmFyXCJcbmVuZFxuXG5tb2R1bGUgVHlwZWRfYXJyYXkgPSBzdHJ1Y3RcbiAgdHlwZSAoJ2EsICdiKSB0eXBlZEFycmF5ID0gSnMudFxuXG4gIHR5cGUgYXJyYXlCdWZmZXIgPSBKcy50XG5cbiAgdHlwZSB1aW50OEFycmF5ID0gSnMudFxuXG4gIGV4dGVybmFsIGtpbmQgOiAoJ2EsICdiKSB0eXBlZEFycmF5IC0+ICgnYSwgJ2IpIEJpZ2FycmF5LmtpbmRcbiAgICA9IFwiY2FtbF9iYV9raW5kX29mX3R5cGVkX2FycmF5XCJcblxuICBleHRlcm5hbCBmcm9tX2dlbmFycmF5IDpcbiAgICAoJ2EsICdiLCBCaWdhcnJheS5jX2xheW91dCkgQmlnYXJyYXkuR2VuYXJyYXkudCAtPiAoJ2EsICdiKSB0eXBlZEFycmF5XG4gICAgPSBcImNhbWxfYmFfdG9fdHlwZWRfYXJyYXlcIlxuXG4gIGV4dGVybmFsIHRvX2dlbmFycmF5IDpcbiAgICAoJ2EsICdiKSB0eXBlZEFycmF5IC0+ICgnYSwgJ2IsIEJpZ2FycmF5LmNfbGF5b3V0KSBCaWdhcnJheS5HZW5hcnJheS50XG4gICAgPSBcImNhbWxfYmFfZnJvbV90eXBlZF9hcnJheVwiXG5cbiAgbW9kdWxlIEJpZ3N0cmluZyA9IHN0cnVjdFxuICAgIHR5cGUgdCA9IChjaGFyLCBCaWdhcnJheS5pbnQ4X3Vuc2lnbmVkX2VsdCwgQmlnYXJyYXkuY19sYXlvdXQpIEJpZ2FycmF5LkFycmF5MS50XG5cbiAgICBleHRlcm5hbCB0b19hcnJheUJ1ZmZlciA6IHQgLT4gYXJyYXlCdWZmZXIgPSBcImJpZ3N0cmluZ190b19hcnJheV9idWZmZXJcIlxuXG4gICAgZXh0ZXJuYWwgdG9fdWludDhBcnJheSA6IHQgLT4gdWludDhBcnJheSA9IFwiYmlnc3RyaW5nX3RvX3R5cGVkX2FycmF5XCJcblxuICAgIGV4dGVybmFsIG9mX2FycmF5QnVmZmVyIDogYXJyYXlCdWZmZXIgLT4gdCA9IFwiYmlnc3RyaW5nX29mX2FycmF5X2J1ZmZlclwiXG5cbiAgICBleHRlcm5hbCBvZl91aW50OEFycmF5IDogdWludDhBcnJheSAtPiB0ID0gXCJiaWdzdHJpbmdfb2ZfdHlwZWRfYXJyYXlcIlxuICBlbmRcblxuICBleHRlcm5hbCBvZl91aW50OEFycmF5IDogdWludDhBcnJheSAtPiBzdHJpbmcgPSBcImNhbWxfc3RyaW5nX29mX2FycmF5XCJcbmVuZFxuXG5tb2R1bGUgSW50NjQgPSBzdHJ1Y3RcbiAgZXh0ZXJuYWwgY3JlYXRlX2ludDY0X2xvX21pX2hpIDogaW50IC0+IGludCAtPiBpbnQgLT4gSW50NjQudFxuICAgID0gXCJjYW1sX2ludDY0X2NyZWF0ZV9sb19taV9oaVwiXG5lbmRcbiIsIigqIGdlbmVyYXRlZCBieSBkdW5lICopXG5cbigqKiBAY2Fub25pY2FsIEpzX29mX29jYW1sLkNTUyAqKVxubW9kdWxlIENTUyA9IEpzX29mX29jYW1sX19DU1NcblxuKCoqIEBjYW5vbmljYWwgSnNfb2Zfb2NhbWwuRG9tICopXG5tb2R1bGUgRG9tID0gSnNfb2Zfb2NhbWxfX0RvbVxuXG4oKiogQGNhbm9uaWNhbCBKc19vZl9vY2FtbC5Eb21fZXZlbnRzICopXG5tb2R1bGUgRG9tX2V2ZW50cyA9IEpzX29mX29jYW1sX19Eb21fZXZlbnRzXG5cbigqKiBAY2Fub25pY2FsIEpzX29mX29jYW1sLkRvbV9odG1sICopXG5tb2R1bGUgRG9tX2h0bWwgPSBKc19vZl9vY2FtbF9fRG9tX2h0bWxcblxuKCoqIEBjYW5vbmljYWwgSnNfb2Zfb2NhbWwuRG9tX3N2ZyAqKVxubW9kdWxlIERvbV9zdmcgPSBKc19vZl9vY2FtbF9fRG9tX3N2Z1xuXG4oKiogQGNhbm9uaWNhbCBKc19vZl9vY2FtbC5FdmVudFNvdXJjZSAqKVxubW9kdWxlIEV2ZW50U291cmNlID0gSnNfb2Zfb2NhbWxfX0V2ZW50U291cmNlXG5cbigqKiBAY2Fub25pY2FsIEpzX29mX29jYW1sLkZpbGUgKilcbm1vZHVsZSBGaWxlID0gSnNfb2Zfb2NhbWxfX0ZpbGVcblxuKCoqIEBjYW5vbmljYWwgSnNfb2Zfb2NhbWwuRmlyZWJ1ZyAqKVxubW9kdWxlIEZpcmVidWcgPSBKc19vZl9vY2FtbF9fRmlyZWJ1Z1xuXG4oKiogQGNhbm9uaWNhbCBKc19vZl9vY2FtbC5Gb3JtICopXG5tb2R1bGUgRm9ybSA9IEpzX29mX29jYW1sX19Gb3JtXG5cbigqKiBAY2Fub25pY2FsIEpzX29mX29jYW1sLkdlb2xvY2F0aW9uICopXG5tb2R1bGUgR2VvbG9jYXRpb24gPSBKc19vZl9vY2FtbF9fR2VvbG9jYXRpb25cblxuKCoqIEBjYW5vbmljYWwgSnNfb2Zfb2NhbWwuSW1wb3J0ICopXG5tb2R1bGUgSW1wb3J0ID0gSnNfb2Zfb2NhbWxfX0ltcG9ydFxuXG4oKiogQGNhbm9uaWNhbCBKc19vZl9vY2FtbC5JbnRlcnNlY3Rpb25PYnNlcnZlciAqKVxubW9kdWxlIEludGVyc2VjdGlvbk9ic2VydmVyID0gSnNfb2Zfb2NhbWxfX0ludGVyc2VjdGlvbk9ic2VydmVyXG5cbigqKiBAY2Fub25pY2FsIEpzX29mX29jYW1sLkludGwgKilcbm1vZHVsZSBJbnRsID0gSnNfb2Zfb2NhbWxfX0ludGxcblxuKCoqIEBjYW5vbmljYWwgSnNfb2Zfb2NhbWwuSnMgKilcbm1vZHVsZSBKcyA9IEpzX29mX29jYW1sX19Kc1xuXG4oKiogQGNhbm9uaWNhbCBKc19vZl9vY2FtbC5Kc29uICopXG5tb2R1bGUgSnNvbiA9IEpzX29mX29jYW1sX19Kc29uXG5cbigqKiBAY2Fub25pY2FsIEpzX29mX29jYW1sLkpzdGFibGUgKilcbm1vZHVsZSBKc3RhYmxlID0gSnNfb2Zfb2NhbWxfX0pzdGFibGVcblxuKCoqIEBjYW5vbmljYWwgSnNfb2Zfb2NhbWwuTGliX3ZlcnNpb24gKilcbm1vZHVsZSBMaWJfdmVyc2lvbiA9IEpzX29mX29jYW1sX19MaWJfdmVyc2lvblxuXG4oKiogQGNhbm9uaWNhbCBKc19vZl9vY2FtbC5NdXRhdGlvbk9ic2VydmVyICopXG5tb2R1bGUgTXV0YXRpb25PYnNlcnZlciA9IEpzX29mX29jYW1sX19NdXRhdGlvbk9ic2VydmVyXG5cbigqKiBAY2Fub25pY2FsIEpzX29mX29jYW1sLlBlcmZvcm1hbmNlT2JzZXJ2ZXIgKilcbm1vZHVsZSBQZXJmb3JtYW5jZU9ic2VydmVyID0gSnNfb2Zfb2NhbWxfX1BlcmZvcm1hbmNlT2JzZXJ2ZXJcblxuKCoqIEBjYW5vbmljYWwgSnNfb2Zfb2NhbWwuUmVnZXhwICopXG5tb2R1bGUgUmVnZXhwID0gSnNfb2Zfb2NhbWxfX1JlZ2V4cFxuXG4oKiogQGNhbm9uaWNhbCBKc19vZl9vY2FtbC5SZXNpemVPYnNlcnZlciAqKVxubW9kdWxlIFJlc2l6ZU9ic2VydmVyID0gSnNfb2Zfb2NhbWxfX1Jlc2l6ZU9ic2VydmVyXG5cbigqKiBAY2Fub25pY2FsIEpzX29mX29jYW1sLlN5c19qcyAqKVxubW9kdWxlIFN5c19qcyA9IEpzX29mX29jYW1sX19TeXNfanNcblxuKCoqIEBjYW5vbmljYWwgSnNfb2Zfb2NhbWwuVHlwZWRfYXJyYXkgKilcbm1vZHVsZSBUeXBlZF9hcnJheSA9IEpzX29mX29jYW1sX19UeXBlZF9hcnJheVxuXG4oKiogQGNhbm9uaWNhbCBKc19vZl9vY2FtbC5VcmwgKilcbm1vZHVsZSBVcmwgPSBKc19vZl9vY2FtbF9fVXJsXG5cbigqKiBAY2Fub25pY2FsIEpzX29mX29jYW1sLldlYkdMICopXG5tb2R1bGUgV2ViR0wgPSBKc19vZl9vY2FtbF9fV2ViR0xcblxuKCoqIEBjYW5vbmljYWwgSnNfb2Zfb2NhbWwuV2ViU29ja2V0cyAqKVxubW9kdWxlIFdlYlNvY2tldHMgPSBKc19vZl9vY2FtbF9fV2ViU29ja2V0c1xuXG4oKiogQGNhbm9uaWNhbCBKc19vZl9vY2FtbC5Xb3JrZXIgKilcbm1vZHVsZSBXb3JrZXIgPSBKc19vZl9vY2FtbF9fV29ya2VyXG5cbigqKiBAY2Fub25pY2FsIEpzX29mX29jYW1sLlhtbEh0dHBSZXF1ZXN0ICopXG5tb2R1bGUgWG1sSHR0cFJlcXVlc3QgPSBKc19vZl9vY2FtbF9fWG1sSHR0cFJlcXVlc3RcblxubW9kdWxlIEpzX29mX29jYW1sX18gPSBzdHJ1Y3QgZW5kXG5bQEBkZXByZWNhdGVkIFwidGhpcyBtb2R1bGUgaXMgc2hhZG93ZWRcIl1cbiIsIigqIEpzX29mX29jYW1sXG4gKiBodHRwOi8vd3d3Lm9jc2lnZW4ub3JnL2pzX29mX29jYW1sL1xuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHdpdGggbGlua2luZyBleGNlcHRpb247XG4gKiBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcsIFVTQS5cbiAqKVxuXG5tb2R1bGUgUG9seSA9IHN0cnVjdFxuICBleHRlcm5hbCAoIDwgKSA6ICdhIC0+ICdhIC0+IGJvb2wgPSBcIiVsZXNzdGhhblwiXG5cbiAgZXh0ZXJuYWwgKCA8PSApIDogJ2EgLT4gJ2EgLT4gYm9vbCA9IFwiJWxlc3NlcXVhbFwiXG5cbiAgZXh0ZXJuYWwgKCA8PiApIDogJ2EgLT4gJ2EgLT4gYm9vbCA9IFwiJW5vdGVxdWFsXCJcblxuICBleHRlcm5hbCAoID0gKSA6ICdhIC0+ICdhIC0+IGJvb2wgPSBcIiVlcXVhbFwiXG5cbiAgZXh0ZXJuYWwgKCA+ICkgOiAnYSAtPiAnYSAtPiBib29sID0gXCIlZ3JlYXRlcnRoYW5cIlxuXG4gIGV4dGVybmFsICggPj0gKSA6ICdhIC0+ICdhIC0+IGJvb2wgPSBcIiVncmVhdGVyZXF1YWxcIlxuXG4gIGV4dGVybmFsIGNvbXBhcmUgOiAnYSAtPiAnYSAtPiBpbnQgPSBcIiVjb21wYXJlXCJcblxuICBleHRlcm5hbCBlcXVhbCA6ICdhIC0+ICdhIC0+IGJvb2wgPSBcIiVlcXVhbFwiXG5lbmRcblxubW9kdWxlIEludF9yZXBsYWNlX3BvbHltb3JwaGljX2NvbXBhcmUgPSBzdHJ1Y3RcbiAgZXh0ZXJuYWwgKCA8ICkgOiBpbnQgLT4gaW50IC0+IGJvb2wgPSBcIiVsZXNzdGhhblwiXG5cbiAgZXh0ZXJuYWwgKCA8PSApIDogaW50IC0+IGludCAtPiBib29sID0gXCIlbGVzc2VxdWFsXCJcblxuICBleHRlcm5hbCAoIDw+ICkgOiBpbnQgLT4gaW50IC0+IGJvb2wgPSBcIiVub3RlcXVhbFwiXG5cbiAgZXh0ZXJuYWwgKCA9ICkgOiBpbnQgLT4gaW50IC0+IGJvb2wgPSBcIiVlcXVhbFwiXG5cbiAgZXh0ZXJuYWwgKCA+ICkgOiBpbnQgLT4gaW50IC0+IGJvb2wgPSBcIiVncmVhdGVydGhhblwiXG5cbiAgZXh0ZXJuYWwgKCA+PSApIDogaW50IC0+IGludCAtPiBib29sID0gXCIlZ3JlYXRlcmVxdWFsXCJcblxuICBleHRlcm5hbCBjb21wYXJlIDogaW50IC0+IGludCAtPiBpbnQgPSBcIiVjb21wYXJlXCJcblxuICBleHRlcm5hbCBlcXVhbCA6IGludCAtPiBpbnQgLT4gYm9vbCA9IFwiJWVxdWFsXCJcblxuICBsZXQgbWF4ICh4IDogaW50KSB5ID0gaWYgeCA+PSB5IHRoZW4geCBlbHNlIHlcblxuICBsZXQgbWluICh4IDogaW50KSB5ID0gaWYgeCA8PSB5IHRoZW4geCBlbHNlIHlcbmVuZFxuXG5tb2R1bGUgU3RyaW5nID0gc3RydWN0XG4gIGluY2x1ZGUgU3RyaW5nXG5cbiAgbGV0IGVxdWFsICh4IDogc3RyaW5nKSAoeSA6IHN0cmluZykgPSBQb2x5LmVxdWFsIHggeVxuZW5kXG5cbm1vZHVsZSBDaGFyID0gc3RydWN0XG4gIGluY2x1ZGUgQ2hhclxuXG4gIGxldCBlcXVhbCAoeCA6IGNoYXIpICh5IDogY2hhcikgPSBQb2x5LmVxdWFsIHggeVxuZW5kXG5cbmluY2x1ZGUgSW50X3JlcGxhY2VfcG9seW1vcnBoaWNfY29tcGFyZVxuIiwiKCogSnNfb2Zfb2NhbWwgbGlicmFyeVxuICogaHR0cDovL3d3dy5vY3NpZ2VuLm9yZy9qc19vZl9vY2FtbC9cbiAqIENvcHlyaWdodCAoQykgMjAxMCBKw6lyw7RtZSBWb3VpbGxvblxuICogTGFib3JhdG9pcmUgUFBTIC0gQ05SUyBVbml2ZXJzaXTDqSBQYXJpcyBEaWRlcm90XG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgd2l0aCBsaW5raW5nIGV4Y2VwdGlvbjtcbiAqIGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4gKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLlxuICopXG5vcGVuISBJbXBvcnRcblxuKCogVGhpcyBsb2NhbCBtb2R1bGUgW0pzXSBpcyBuZWVkZWQgc28gdGhhdCB0aGUgcHB4X2pzIGV4dGVuc2lvbiB3b3JrIHdpdGhpbiB0aGF0IGZpbGUuICopXG5tb2R1bGUgSnMgPSBzdHJ1Y3RcbiAgdHlwZSArJ2EgdFxuXG4gIHR5cGUgKC0nYSwgKydiKSBtZXRoX2NhbGxiYWNrXG5cbiAgbW9kdWxlIFVuc2FmZSA9IHN0cnVjdFxuICAgIHR5cGUgdG9wXG5cbiAgICB0eXBlIGFueSA9IHRvcCB0XG5cbiAgICB0eXBlIGFueV9qc19hcnJheSA9IGFueVxuXG4gICAgZXh0ZXJuYWwgaW5qZWN0IDogJ2EgLT4gYW55ID0gXCIlaWRlbnRpdHlcIlxuXG4gICAgZXh0ZXJuYWwgY29lcmNlIDogXyB0IC0+IF8gdCA9IFwiJWlkZW50aXR5XCJcblxuICAgIGV4dGVybmFsIGdldCA6ICdhIC0+ICdiIC0+ICdjID0gXCJjYW1sX2pzX2dldFwiXG5cbiAgICBleHRlcm5hbCBzZXQgOiAnYSAtPiAnYiAtPiAnYyAtPiB1bml0ID0gXCJjYW1sX2pzX3NldFwiXG5cbiAgICBleHRlcm5hbCBkZWxldGUgOiAnYSAtPiAnYiAtPiB1bml0ID0gXCJjYW1sX2pzX2RlbGV0ZVwiXG5cbiAgICBleHRlcm5hbCBjYWxsIDogJ2EgLT4gJ2IgLT4gYW55IGFycmF5IC0+ICdjID0gXCJjYW1sX2pzX2NhbGxcIlxuXG4gICAgZXh0ZXJuYWwgZnVuX2NhbGwgOiAnYSAtPiBhbnkgYXJyYXkgLT4gJ2IgPSBcImNhbWxfanNfZnVuX2NhbGxcIlxuXG4gICAgZXh0ZXJuYWwgbWV0aF9jYWxsIDogJ2EgLT4gc3RyaW5nIC0+IGFueSBhcnJheSAtPiAnYiA9IFwiY2FtbF9qc19tZXRoX2NhbGxcIlxuXG4gICAgZXh0ZXJuYWwgbmV3X29iaiA6ICdhIC0+IGFueSBhcnJheSAtPiAnYiA9IFwiY2FtbF9qc19uZXdcIlxuXG4gICAgZXh0ZXJuYWwgbmV3X29ial9hcnIgOiAnYSAtPiBhbnlfanNfYXJyYXkgLT4gJ2IgPSBcImNhbWxfb2pzX25ld19hcnJcIlxuXG4gICAgZXh0ZXJuYWwgb2JqIDogKHN0cmluZyAqIGFueSkgYXJyYXkgLT4gJ2EgPSBcImNhbWxfanNfb2JqZWN0XCJcblxuICAgIGV4dGVybmFsIGVxdWFscyA6ICdhIC0+ICdiIC0+IGJvb2wgPSBcImNhbWxfanNfZXF1YWxzXCJcblxuICAgIGV4dGVybmFsIHN0cmljdF9lcXVhbHMgOiAnYSAtPiAnYiAtPiBib29sID0gXCJjYW1sX2pzX3N0cmljdF9lcXVhbHNcIlxuXG4gICAgZXh0ZXJuYWwgcHVyZV9leHByIDogKHVuaXQgLT4gJ2EpIC0+ICdhID0gXCJjYW1sX2pzX3B1cmVfZXhwclwiXG5cbiAgICBleHRlcm5hbCBldmFsX3N0cmluZyA6IHN0cmluZyAtPiAnYSA9IFwiY2FtbF9qc19ldmFsX3N0cmluZ1wiXG5cbiAgICBleHRlcm5hbCBqc19leHByIDogc3RyaW5nIC0+ICdhID0gXCJjYW1sX2pzX2V4cHJcIlxuXG4gICAgZXh0ZXJuYWwgcHVyZV9qc19leHByIDogc3RyaW5nIC0+ICdhID0gXCJjYW1sX3B1cmVfanNfZXhwclwiXG5cbiAgICBsZXQgZ2xvYmFsID0gcHVyZV9qc19leHByIFwiZ2xvYmFsVGhpc1wiXG5cbiAgICBleHRlcm5hbCBjYWxsYmFjayA6ICgnYSAtPiAnYikgLT4gKCdjLCAnYSAtPiAnYikgbWV0aF9jYWxsYmFja1xuICAgICAgPSBcImNhbWxfanNfd3JhcF9jYWxsYmFja191bnNhZmVcIlxuXG4gICAgZXh0ZXJuYWwgY2FsbGJhY2tfd2l0aF9hcmd1bWVudHMgOlxuICAgICAgKGFueV9qc19hcnJheSAtPiAnYikgLT4gKCdjLCBhbnlfanNfYXJyYXkgLT4gJ2IpIG1ldGhfY2FsbGJhY2tcbiAgICAgID0gXCJjYW1sX2pzX3dyYXBfY2FsbGJhY2tfYXJndW1lbnRzXCJcblxuICAgIGV4dGVybmFsIGNhbGxiYWNrX3dpdGhfYXJpdHkgOiBpbnQgLT4gKCdhIC0+ICdiKSAtPiAoJ2MsICdhIC0+ICdiKSBtZXRoX2NhbGxiYWNrXG4gICAgICA9IFwiY2FtbF9qc193cmFwX2NhbGxiYWNrX3N0cmljdFwiXG5cbiAgICBleHRlcm5hbCBtZXRoX2NhbGxiYWNrIDogKCdiIC0+ICdhKSAtPiAoJ2IsICdhKSBtZXRoX2NhbGxiYWNrXG4gICAgICA9IFwiY2FtbF9qc193cmFwX21ldGhfY2FsbGJhY2tfdW5zYWZlXCJcblxuICAgIGV4dGVybmFsIG1ldGhfY2FsbGJhY2tfd2l0aF9hcml0eSA6IGludCAtPiAoJ2IgLT4gJ2EpIC0+ICgnYiwgJ2EpIG1ldGhfY2FsbGJhY2tcbiAgICAgID0gXCJjYW1sX2pzX3dyYXBfbWV0aF9jYWxsYmFja19zdHJpY3RcIlxuXG4gICAgZXh0ZXJuYWwgbWV0aF9jYWxsYmFja193aXRoX2FyZ3VtZW50cyA6XG4gICAgICAoJ2IgLT4gYW55X2pzX2FycmF5IC0+ICdhKSAtPiAoJ2IsIGFueV9qc19hcnJheSAtPiAnYSkgbWV0aF9jYWxsYmFja1xuICAgICAgPSBcImNhbWxfanNfd3JhcF9tZXRoX2NhbGxiYWNrX2FyZ3VtZW50c1wiXG5cbiAgICAoKiBERVBSRUNBVEVEICopXG4gICAgZXh0ZXJuYWwgdmFyaWFibGUgOiBzdHJpbmcgLT4gJ2EgPSBcImNhbWxfanNfdmFyXCJcbiAgZW5kXG5cbiAgKCoqKiopXG5cbiAgdHlwZSAnYSBvcHQgPSAnYVxuXG4gIHR5cGUgJ2Egb3B0ZGVmID0gJ2FcblxuICBleHRlcm5hbCBkZWJ1Z2dlciA6IHVuaXQgLT4gdW5pdCA9IFwiZGVidWdnZXJcIlxuXG4gIGxldCBudWxsIDogJ2Egb3B0ID0gVW5zYWZlLnB1cmVfanNfZXhwciBcIm51bGxcIlxuXG4gIGV4dGVybmFsIHNvbWUgOiAnYSAtPiAnYSBvcHQgPSBcIiVpZGVudGl0eVwiXG5cbiAgbGV0IHVuZGVmaW5lZCA6ICdhIG9wdGRlZiA9IFVuc2FmZS5wdXJlX2pzX2V4cHIgXCJ1bmRlZmluZWRcIlxuXG4gIGV4dGVybmFsIGRlZiA6ICdhIC0+ICdhIG9wdGRlZiA9IFwiJWlkZW50aXR5XCJcblxuICBtb2R1bGUgdHlwZSBPUFQgPSBzaWdcbiAgICB0eXBlICdhIHRcblxuICAgIHZhbCBlbXB0eSA6ICdhIHRcblxuICAgIHZhbCByZXR1cm4gOiAnYSAtPiAnYSB0XG5cbiAgICB2YWwgbWFwIDogJ2EgdCAtPiAoJ2EgLT4gJ2IpIC0+ICdiIHRcblxuICAgIHZhbCBiaW5kIDogJ2EgdCAtPiAoJ2EgLT4gJ2IgdCkgLT4gJ2IgdFxuXG4gICAgdmFsIHRlc3QgOiAnYSB0IC0+IGJvb2xcblxuICAgIHZhbCBpdGVyIDogJ2EgdCAtPiAoJ2EgLT4gdW5pdCkgLT4gdW5pdFxuXG4gICAgdmFsIGNhc2UgOiAnYSB0IC0+ICh1bml0IC0+ICdiKSAtPiAoJ2EgLT4gJ2IpIC0+ICdiXG5cbiAgICB2YWwgZ2V0IDogJ2EgdCAtPiAodW5pdCAtPiAnYSkgLT4gJ2FcblxuICAgIHZhbCBvcHRpb24gOiAnYSBvcHRpb24gLT4gJ2EgdFxuXG4gICAgdmFsIHRvX29wdGlvbiA6ICdhIHQgLT4gJ2Egb3B0aW9uXG5cbiAgICBleHRlcm5hbCBlcXVhbHMgOiBfIHQgLT4gXyB0IC0+IGJvb2wgPSBcImNhbWxfanNfZXF1YWxzXCJcblxuICAgIGV4dGVybmFsIHN0cmljdF9lcXVhbHMgOiBfIHQgLT4gXyB0IC0+IGJvb2wgPSBcImNhbWxfanNfc3RyaWN0X2VxdWFsc1wiXG4gIGVuZFxuXG4gIG1vZHVsZSBPcHQgOiBPUFQgd2l0aCB0eXBlICdhIHQgPSAnYSBvcHQgPSBzdHJ1Y3RcbiAgICB0eXBlICdhIHQgPSAnYSBvcHRcblxuICAgIGxldCBlbXB0eSA9IG51bGxcblxuICAgIGxldCByZXR1cm4gPSBzb21lXG5cbiAgICBleHRlcm5hbCBlcXVhbHMgOiBfIHQgLT4gXyB0IC0+IGJvb2wgPSBcImNhbWxfanNfZXF1YWxzXCJcblxuICAgIGV4dGVybmFsIHN0cmljdF9lcXVhbHMgOiBfIHQgLT4gXyB0IC0+IGJvb2wgPSBcImNhbWxfanNfc3RyaWN0X2VxdWFsc1wiXG5cbiAgICBsZXQgbWFwIHggZiA9IGlmIGVxdWFscyB4IG51bGwgdGhlbiBudWxsIGVsc2UgcmV0dXJuIChmIHgpXG5cbiAgICBsZXQgYmluZCB4IGYgPSBpZiBlcXVhbHMgeCBudWxsIHRoZW4gbnVsbCBlbHNlIGYgeFxuXG4gICAgbGV0IHRlc3QgeCA9IG5vdCAoZXF1YWxzIHggbnVsbClcblxuICAgIGxldCBpdGVyIHggZiA9IGlmIG5vdCAoZXF1YWxzIHggbnVsbCkgdGhlbiBmIHhcblxuICAgIGxldCBjYXNlIHggZiBnID0gaWYgZXF1YWxzIHggbnVsbCB0aGVuIGYgKCkgZWxzZSBnIHhcblxuICAgIGxldCBnZXQgeCBmID0gaWYgZXF1YWxzIHggbnVsbCB0aGVuIGYgKCkgZWxzZSB4XG5cbiAgICBsZXQgb3B0aW9uIHggPVxuICAgICAgbWF0Y2ggeCB3aXRoXG4gICAgICB8IE5vbmUgLT4gZW1wdHlcbiAgICAgIHwgU29tZSB4IC0+IHJldHVybiB4XG5cbiAgICBsZXQgdG9fb3B0aW9uIHggPSBjYXNlIHggKGZ1biAoKSAtPiBOb25lKSAoZnVuIHggLT4gU29tZSB4KVxuICBlbmRcblxuICBtb2R1bGUgT3B0ZGVmIDogT1BUIHdpdGggdHlwZSAnYSB0ID0gJ2Egb3B0ZGVmID0gc3RydWN0XG4gICAgdHlwZSAnYSB0ID0gJ2Egb3B0ZGVmXG5cbiAgICBsZXQgZW1wdHkgPSB1bmRlZmluZWRcblxuICAgIGxldCByZXR1cm4gPSBkZWZcblxuICAgIGV4dGVybmFsIGVxdWFscyA6IF8gdCAtPiBfIHQgLT4gYm9vbCA9IFwiY2FtbF9qc19lcXVhbHNcIlxuXG4gICAgZXh0ZXJuYWwgc3RyaWN0X2VxdWFscyA6IF8gdCAtPiBfIHQgLT4gYm9vbCA9IFwiY2FtbF9qc19zdHJpY3RfZXF1YWxzXCJcblxuICAgIGxldCBtYXAgeCBmID0gaWYgc3RyaWN0X2VxdWFscyB4IHVuZGVmaW5lZCB0aGVuIHVuZGVmaW5lZCBlbHNlIHJldHVybiAoZiB4KVxuXG4gICAgbGV0IGJpbmQgeCBmID0gaWYgc3RyaWN0X2VxdWFscyB4IHVuZGVmaW5lZCB0aGVuIHVuZGVmaW5lZCBlbHNlIGYgeFxuXG4gICAgbGV0IHRlc3QgeCA9IG5vdCAoc3RyaWN0X2VxdWFscyB4IHVuZGVmaW5lZClcblxuICAgIGxldCBpdGVyIHggZiA9IGlmIG5vdCAoc3RyaWN0X2VxdWFscyB4IHVuZGVmaW5lZCkgdGhlbiBmIHhcblxuICAgIGxldCBjYXNlIHggZiBnID0gaWYgc3RyaWN0X2VxdWFscyB4IHVuZGVmaW5lZCB0aGVuIGYgKCkgZWxzZSBnIHhcblxuICAgIGxldCBnZXQgeCBmID0gaWYgc3RyaWN0X2VxdWFscyB4IHVuZGVmaW5lZCB0aGVuIGYgKCkgZWxzZSB4XG5cbiAgICBsZXQgb3B0aW9uIHggPVxuICAgICAgbWF0Y2ggeCB3aXRoXG4gICAgICB8IE5vbmUgLT4gZW1wdHlcbiAgICAgIHwgU29tZSB4IC0+IHJldHVybiB4XG5cbiAgICBsZXQgdG9fb3B0aW9uIHggPSBjYXNlIHggKGZ1biAoKSAtPiBOb25lKSAoZnVuIHggLT4gU29tZSB4KVxuICBlbmRcblxuICAoKioqKilcblxuICBsZXQgY29lcmNlIHggZiBnID0gT3B0LmdldCAoZiB4KSAoZnVuICgpIC0+IGcgeClcblxuICBsZXQgY29lcmNlX29wdCB4IGYgZyA9IE9wdC5nZXQgKE9wdC5iaW5kIHggZikgKGZ1biAoKSAtPiBnIHgpXG5cbiAgKCoqKiopXG5cbiAgdHlwZSArJ2EgbWV0aFxuXG4gIHR5cGUgKydhIGdlbl9wcm9wXG5cbiAgdHlwZSAnYSByZWFkb25seV9wcm9wID0gPCBnZXQgOiAnYSA+IGdlbl9wcm9wXG5cbiAgdHlwZSAnYSB3cml0ZW9ubHlfcHJvcCA9IDwgc2V0IDogJ2EgLT4gdW5pdCA+IGdlbl9wcm9wXG5cbiAgdHlwZSAnYSBwcm9wID0gPCBnZXQgOiAnYSA7IHNldCA6ICdhIC0+IHVuaXQgPiBnZW5fcHJvcFxuXG4gIHR5cGUgJ2Egb3B0ZGVmX3Byb3AgPSA8IGdldCA6ICdhIG9wdGRlZiA7IHNldCA6ICdhIC0+IHVuaXQgPiBnZW5fcHJvcFxuXG4gIHR5cGUgKydhIGNvbnN0clxuXG4gICgqKioqKVxuXG4gIHR5cGUgJ2EgY2FsbGJhY2sgPSAodW5pdCwgJ2EpIG1ldGhfY2FsbGJhY2tcblxuICBleHRlcm5hbCB3cmFwX2NhbGxiYWNrIDogKCdhIC0+ICdiKSAtPiAoJ2MsICdhIC0+ICdiKSBtZXRoX2NhbGxiYWNrXG4gICAgPSBcImNhbWxfanNfd3JhcF9jYWxsYmFja1wiXG5cbiAgZXh0ZXJuYWwgd3JhcF9tZXRoX2NhbGxiYWNrIDogKCdhIC0+ICdiKSAtPiAoJ2EsICdiKSBtZXRoX2NhbGxiYWNrXG4gICAgPSBcImNhbWxfanNfd3JhcF9tZXRoX2NhbGxiYWNrXCJcblxuICAoKioqKilcblxuICBleHRlcm5hbCBlcXVhbHMgOiBfIHQgLT4gXyB0IC0+IGJvb2wgPSBcImNhbWxfanNfZXF1YWxzXCJcblxuICBleHRlcm5hbCBzdHJpY3RfZXF1YWxzIDogXyB0IC0+IF8gdCAtPiBib29sID0gXCJjYW1sX2pzX3N0cmljdF9lcXVhbHNcIlxuXG4gICgqKioqKVxuXG4gIGxldCBfdHJ1ZSA9IFVuc2FmZS5wdXJlX2pzX2V4cHIgXCJ0cnVlXCJcblxuICBsZXQgX2ZhbHNlID0gVW5zYWZlLnB1cmVfanNfZXhwciBcImZhbHNlXCJcblxuICB0eXBlIG1hdGNoX3Jlc3VsdF9oYW5kbGVcblxuICB0eXBlIHN0cmluZ19hcnJheVxuXG4gIHR5cGUgbnVtYmVyX3QgPSBmbG9hdFxuXG4gIGNsYXNzIHR5cGUgbnVtYmVyID0gb2JqZWN0XG4gICAgbWV0aG9kIHRvU3RyaW5nIDoganNfc3RyaW5nIHQgbWV0aFxuXG4gICAgbWV0aG9kIHRvU3RyaW5nX3JhZGl4IDogaW50IC0+IGpzX3N0cmluZyB0IG1ldGhcblxuICAgIG1ldGhvZCB0b0xvY2FsZVN0cmluZyA6IGpzX3N0cmluZyB0IG1ldGhcblxuICAgIG1ldGhvZCB0b0ZpeGVkIDogaW50IC0+IGpzX3N0cmluZyB0IG1ldGhcblxuICAgIG1ldGhvZCB0b0V4cG9uZW50aWFsIDoganNfc3RyaW5nIHQgbWV0aFxuXG4gICAgbWV0aG9kIHRvRXhwb25lbnRpYWxfZGlnaXRzIDogaW50IC0+IGpzX3N0cmluZyB0IG1ldGhcblxuICAgIG1ldGhvZCB0b1ByZWNpc2lvbiA6IGludCAtPiBqc19zdHJpbmcgdCBtZXRoXG4gIGVuZFxuXG4gIGFuZCBqc19zdHJpbmcgPSBvYmplY3RcbiAgICBtZXRob2QgdG9TdHJpbmcgOiBqc19zdHJpbmcgdCBtZXRoXG5cbiAgICBtZXRob2QgdmFsdWVPZiA6IGpzX3N0cmluZyB0IG1ldGhcblxuICAgIG1ldGhvZCBjaGFyQXQgOiBpbnQgLT4ganNfc3RyaW5nIHQgbWV0aFxuXG4gICAgbWV0aG9kIGNoYXJDb2RlQXQgOiBpbnQgLT4gbnVtYmVyX3QgbWV0aFxuXG4gICAgKCogVGhpcyBtYXkgcmV0dXJuIE5hTi4uLiAqKVxuICAgIG1ldGhvZCBjb25jYXQgOiBqc19zdHJpbmcgdCAtPiBqc19zdHJpbmcgdCBtZXRoXG5cbiAgICBtZXRob2QgY29uY2F0XzIgOiBqc19zdHJpbmcgdCAtPiBqc19zdHJpbmcgdCAtPiBqc19zdHJpbmcgdCBtZXRoXG5cbiAgICBtZXRob2QgY29uY2F0XzMgOiBqc19zdHJpbmcgdCAtPiBqc19zdHJpbmcgdCAtPiBqc19zdHJpbmcgdCAtPiBqc19zdHJpbmcgdCBtZXRoXG5cbiAgICBtZXRob2QgY29uY2F0XzQgOlxuICAgICAganNfc3RyaW5nIHQgLT4ganNfc3RyaW5nIHQgLT4ganNfc3RyaW5nIHQgLT4ganNfc3RyaW5nIHQgLT4ganNfc3RyaW5nIHQgbWV0aFxuXG4gICAgbWV0aG9kIGluZGV4T2YgOiBqc19zdHJpbmcgdCAtPiBpbnQgbWV0aFxuXG4gICAgbWV0aG9kIGluZGV4T2ZfZnJvbSA6IGpzX3N0cmluZyB0IC0+IGludCAtPiBpbnQgbWV0aFxuXG4gICAgbWV0aG9kIGxhc3RJbmRleE9mIDoganNfc3RyaW5nIHQgLT4gaW50IG1ldGhcblxuICAgIG1ldGhvZCBsYXN0SW5kZXhPZl9mcm9tIDoganNfc3RyaW5nIHQgLT4gaW50IC0+IGludCBtZXRoXG5cbiAgICBtZXRob2QgbG9jYWxlQ29tcGFyZSA6IGpzX3N0cmluZyB0IC0+IG51bWJlcl90IG1ldGhcblxuICAgIG1ldGhvZCBfbWF0Y2ggOiByZWdFeHAgdCAtPiBtYXRjaF9yZXN1bHRfaGFuZGxlIHQgb3B0IG1ldGhcblxuICAgIG1ldGhvZCBub3JtYWxpemUgOiBqc19zdHJpbmcgdCBtZXRoXG5cbiAgICBtZXRob2Qgbm9ybWFsaXplX2Zvcm0gOiBub3JtYWxpemF0aW9uIHQgLT4ganNfc3RyaW5nIHQgbWV0aFxuXG4gICAgbWV0aG9kIHJlcGxhY2UgOiByZWdFeHAgdCAtPiBqc19zdHJpbmcgdCAtPiBqc19zdHJpbmcgdCBtZXRoXG5cbiAgICBtZXRob2QgcmVwbGFjZV9zdHJpbmcgOiBqc19zdHJpbmcgdCAtPiBqc19zdHJpbmcgdCAtPiBqc19zdHJpbmcgdCBtZXRoXG5cbiAgICBtZXRob2Qgc2VhcmNoIDogcmVnRXhwIHQgLT4gaW50IG1ldGhcblxuICAgIG1ldGhvZCBzbGljZSA6IGludCAtPiBpbnQgLT4ganNfc3RyaW5nIHQgbWV0aFxuXG4gICAgbWV0aG9kIHNsaWNlX2VuZCA6IGludCAtPiBqc19zdHJpbmcgdCBtZXRoXG5cbiAgICBtZXRob2Qgc3BsaXQgOiBqc19zdHJpbmcgdCAtPiBzdHJpbmdfYXJyYXkgdCBtZXRoXG5cbiAgICBtZXRob2Qgc3BsaXRfbGltaXRlZCA6IGpzX3N0cmluZyB0IC0+IGludCAtPiBzdHJpbmdfYXJyYXkgdCBtZXRoXG5cbiAgICBtZXRob2Qgc3BsaXRfcmVnRXhwIDogcmVnRXhwIHQgLT4gc3RyaW5nX2FycmF5IHQgbWV0aFxuXG4gICAgbWV0aG9kIHNwbGl0X3JlZ0V4cExpbWl0ZWQgOiByZWdFeHAgdCAtPiBpbnQgLT4gc3RyaW5nX2FycmF5IHQgbWV0aFxuXG4gICAgbWV0aG9kIHN1YnN0cmluZyA6IGludCAtPiBpbnQgLT4ganNfc3RyaW5nIHQgbWV0aFxuXG4gICAgbWV0aG9kIHN1YnN0cmluZ190b0VuZCA6IGludCAtPiBqc19zdHJpbmcgdCBtZXRoXG5cbiAgICBtZXRob2QgdG9Mb3dlckNhc2UgOiBqc19zdHJpbmcgdCBtZXRoXG5cbiAgICBtZXRob2QgdG9Mb2NhbGVMb3dlckNhc2UgOiBqc19zdHJpbmcgdCBtZXRoXG5cbiAgICBtZXRob2QgdG9VcHBlckNhc2UgOiBqc19zdHJpbmcgdCBtZXRoXG5cbiAgICBtZXRob2QgdG9Mb2NhbGVVcHBlckNhc2UgOiBqc19zdHJpbmcgdCBtZXRoXG5cbiAgICBtZXRob2QgdHJpbSA6IGpzX3N0cmluZyB0IG1ldGhcblxuICAgIG1ldGhvZCBsZW5ndGggOiBpbnQgcmVhZG9ubHlfcHJvcFxuICBlbmRcblxuICBhbmQgcmVnRXhwID0gb2JqZWN0XG4gICAgbWV0aG9kIGV4ZWMgOiBqc19zdHJpbmcgdCAtPiBtYXRjaF9yZXN1bHRfaGFuZGxlIHQgb3B0IG1ldGhcblxuICAgIG1ldGhvZCB0ZXN0IDoganNfc3RyaW5nIHQgLT4gYm9vbCB0IG1ldGhcblxuICAgIG1ldGhvZCB0b1N0cmluZyA6IGpzX3N0cmluZyB0IG1ldGhcblxuICAgIG1ldGhvZCBzb3VyY2UgOiBqc19zdHJpbmcgdCByZWFkb25seV9wcm9wXG5cbiAgICBtZXRob2QgZ2xvYmFsIDogYm9vbCB0IHJlYWRvbmx5X3Byb3BcblxuICAgIG1ldGhvZCBpZ25vcmVDYXNlIDogYm9vbCB0IHJlYWRvbmx5X3Byb3BcblxuICAgIG1ldGhvZCBtdWx0aWxpbmUgOiBib29sIHQgcmVhZG9ubHlfcHJvcFxuXG4gICAgbWV0aG9kIGxhc3RJbmRleCA6IGludCBwcm9wXG4gIGVuZFxuXG4gIGFuZCBub3JtYWxpemF0aW9uID0ganNfc3RyaW5nXG5cbiAgKCogc3RyaW5nIGlzIHVzZWQgYnkgcHB4X2pzLCBpdCBuZWVkcyB0byBjb21lIGJlZm9yZSBhbnkgdXNlIG9mIHRoZVxuICAgICBuZXcgc3ludGF4IGluIHRoaXMgZmlsZSAqKVxuICBleHRlcm5hbCBzdHJpbmcgOiBzdHJpbmcgLT4ganNfc3RyaW5nIHQgPSBcImNhbWxfanNzdHJpbmdfb2Zfc3RyaW5nXCJcblxuICBleHRlcm5hbCB0b19zdHJpbmcgOiBqc19zdHJpbmcgdCAtPiBzdHJpbmcgPSBcImNhbWxfc3RyaW5nX29mX2pzc3RyaW5nXCJcblxuICBsZXQgbmZjID0gc3RyaW5nIFwiTkZDXCJcblxuICBsZXQgbmZkID0gc3RyaW5nIFwiTkZEXCJcblxuICBsZXQgbmZrYyA9IHN0cmluZyBcIk5GS0NcIlxuXG4gIGxldCBuZmtkID0gc3RyaW5nIFwiTkZLRFwiXG5lbmRcblxuaW5jbHVkZSBKc1xuXG5jbGFzcyB0eXBlIHN0cmluZ19jb25zdHIgPSBvYmplY3RcbiAgbWV0aG9kIGZyb21DaGFyQ29kZSA6IGludCAtPiBqc19zdHJpbmcgdCBtZXRoXG5lbmRcblxubGV0IHN0cmluZ19jb25zdHIgPSBVbnNhZmUuZ2xvYmFsIyMuX1N0cmluZ1xuXG5sZXQgcmVnRXhwID0gVW5zYWZlLmdsb2JhbCMjLl9SZWdFeHBcblxubGV0IHJlZ0V4cF9jb3B5ID0gcmVnRXhwXG5cbmxldCByZWdFeHBfd2l0aEZsYWdzID0gcmVnRXhwXG5cbmNsYXNzIHR5cGUgWydhXSBqc19hcnJheSA9IG9iamVjdFxuICBtZXRob2QgdG9TdHJpbmcgOiBqc19zdHJpbmcgdCBtZXRoXG5cbiAgbWV0aG9kIHRvTG9jYWxlU3RyaW5nIDoganNfc3RyaW5nIHQgbWV0aFxuXG4gIG1ldGhvZCBjb25jYXQgOiAnYSBqc19hcnJheSB0IC0+ICdhIGpzX2FycmF5IHQgbWV0aFxuXG4gIG1ldGhvZCBqb2luIDoganNfc3RyaW5nIHQgLT4ganNfc3RyaW5nIHQgbWV0aFxuXG4gIG1ldGhvZCBwb3AgOiAnYSBvcHRkZWYgbWV0aFxuXG4gIG1ldGhvZCBwdXNoIDogJ2EgLT4gaW50IG1ldGhcblxuICBtZXRob2QgcHVzaF8yIDogJ2EgLT4gJ2EgLT4gaW50IG1ldGhcblxuICBtZXRob2QgcHVzaF8zIDogJ2EgLT4gJ2EgLT4gJ2EgLT4gaW50IG1ldGhcblxuICBtZXRob2QgcHVzaF80IDogJ2EgLT4gJ2EgLT4gJ2EgLT4gJ2EgLT4gaW50IG1ldGhcblxuICBtZXRob2QgcmV2ZXJzZSA6ICdhIGpzX2FycmF5IHQgbWV0aFxuXG4gIG1ldGhvZCBzaGlmdCA6ICdhIG9wdGRlZiBtZXRoXG5cbiAgbWV0aG9kIHNsaWNlIDogaW50IC0+IGludCAtPiAnYSBqc19hcnJheSB0IG1ldGhcblxuICBtZXRob2Qgc2xpY2VfZW5kIDogaW50IC0+ICdhIGpzX2FycmF5IHQgbWV0aFxuXG4gIG1ldGhvZCBzb3J0IDogKCdhIC0+ICdhIC0+IG51bWJlcl90KSBjYWxsYmFjayAtPiAnYSBqc19hcnJheSB0IG1ldGhcblxuICBtZXRob2Qgc29ydF9hc1N0cmluZ3MgOiAnYSBqc19hcnJheSB0IG1ldGhcblxuICBtZXRob2Qgc3BsaWNlIDogaW50IC0+IGludCAtPiAnYSBqc19hcnJheSB0IG1ldGhcblxuICBtZXRob2Qgc3BsaWNlXzEgOiBpbnQgLT4gaW50IC0+ICdhIC0+ICdhIGpzX2FycmF5IHQgbWV0aFxuXG4gIG1ldGhvZCBzcGxpY2VfMiA6IGludCAtPiBpbnQgLT4gJ2EgLT4gJ2EgLT4gJ2EganNfYXJyYXkgdCBtZXRoXG5cbiAgbWV0aG9kIHNwbGljZV8zIDogaW50IC0+IGludCAtPiAnYSAtPiAnYSAtPiAnYSAtPiAnYSBqc19hcnJheSB0IG1ldGhcblxuICBtZXRob2Qgc3BsaWNlXzQgOiBpbnQgLT4gaW50IC0+ICdhIC0+ICdhIC0+ICdhIC0+ICdhIC0+ICdhIGpzX2FycmF5IHQgbWV0aFxuXG4gIG1ldGhvZCB1bnNoaWZ0IDogJ2EgLT4gaW50IG1ldGhcblxuICBtZXRob2QgdW5zaGlmdF8yIDogJ2EgLT4gJ2EgLT4gaW50IG1ldGhcblxuICBtZXRob2QgdW5zaGlmdF8zIDogJ2EgLT4gJ2EgLT4gJ2EgLT4gaW50IG1ldGhcblxuICBtZXRob2QgdW5zaGlmdF80IDogJ2EgLT4gJ2EgLT4gJ2EgLT4gJ2EgLT4gaW50IG1ldGhcblxuICBtZXRob2Qgc29tZSA6ICgnYSAtPiBpbnQgLT4gJ2EganNfYXJyYXkgdCAtPiBib29sIHQpIGNhbGxiYWNrIC0+IGJvb2wgdCBtZXRoXG5cbiAgbWV0aG9kIGV2ZXJ5IDogKCdhIC0+IGludCAtPiAnYSBqc19hcnJheSB0IC0+IGJvb2wgdCkgY2FsbGJhY2sgLT4gYm9vbCB0IG1ldGhcblxuICBtZXRob2QgZm9yRWFjaCA6ICgnYSAtPiBpbnQgLT4gJ2EganNfYXJyYXkgdCAtPiB1bml0KSBjYWxsYmFjayAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgbWFwIDogKCdhIC0+IGludCAtPiAnYSBqc19hcnJheSB0IC0+ICdiKSBjYWxsYmFjayAtPiAnYiBqc19hcnJheSB0IG1ldGhcblxuICBtZXRob2QgZmlsdGVyIDogKCdhIC0+IGludCAtPiAnYSBqc19hcnJheSB0IC0+IGJvb2wgdCkgY2FsbGJhY2sgLT4gJ2EganNfYXJyYXkgdCBtZXRoXG5cbiAgbWV0aG9kIHJlZHVjZV9pbml0IDogKCdiIC0+ICdhIC0+IGludCAtPiAnYSBqc19hcnJheSB0IC0+ICdiKSBjYWxsYmFjayAtPiAnYiAtPiAnYiBtZXRoXG5cbiAgbWV0aG9kIHJlZHVjZSA6ICgnYSAtPiAnYSAtPiBpbnQgLT4gJ2EganNfYXJyYXkgdCAtPiAnYSkgY2FsbGJhY2sgLT4gJ2EgbWV0aFxuXG4gIG1ldGhvZCByZWR1Y2VSaWdodF9pbml0IDpcbiAgICAoJ2IgLT4gJ2EgLT4gaW50IC0+ICdhIGpzX2FycmF5IHQgLT4gJ2IpIGNhbGxiYWNrIC0+ICdiIC0+ICdiIG1ldGhcblxuICBtZXRob2QgcmVkdWNlUmlnaHQgOiAoJ2EgLT4gJ2EgLT4gaW50IC0+ICdhIGpzX2FycmF5IHQgLT4gJ2EpIGNhbGxiYWNrIC0+ICdhIG1ldGhcblxuICBtZXRob2QgbGVuZ3RoIDogaW50IHByb3BcbmVuZFxuXG5sZXQgb2JqZWN0X2NvbnN0cnVjdG9yID0gVW5zYWZlLmdsb2JhbCMjLl9PYmplY3RcblxubGV0IG9iamVjdF9rZXlzIG8gOiBqc19zdHJpbmcgdCBqc19hcnJheSB0ID0gb2JqZWN0X2NvbnN0cnVjdG9yIyNrZXlzIG9cblxubGV0IGFycmF5X2NvbnN0cnVjdG9yID0gVW5zYWZlLmdsb2JhbCMjLl9BcnJheVxuXG5sZXQgYXJyYXlfZW1wdHkgPSBhcnJheV9jb25zdHJ1Y3RvclxuXG5sZXQgYXJyYXlfbGVuZ3RoID0gYXJyYXlfY29uc3RydWN0b3JcblxubGV0IGFycmF5X2dldCA6ICdhICNqc19hcnJheSB0IC0+IGludCAtPiAnYSBvcHRkZWYgPSBVbnNhZmUuZ2V0XG5cbmxldCBhcnJheV9zZXQgOiAnYSAjanNfYXJyYXkgdCAtPiBpbnQgLT4gJ2EgLT4gdW5pdCA9IFVuc2FmZS5zZXRcblxubGV0IGFycmF5X21hcF9wb2x5IDpcbiAgICAnYSAjanNfYXJyYXkgdCAtPiAoJ2EgLT4gaW50IC0+ICdhICNqc19hcnJheSB0IC0+ICdiKSBjYWxsYmFjayAtPiAnYiAjanNfYXJyYXkgdCA9XG4gZnVuIGEgY2IgLT4gKFVuc2FmZS5jb2VyY2UgYSkjI21hcCBjYlxuXG5sZXQgYXJyYXlfbWFwIGYgYSA9IGFycmF5X21hcF9wb2x5IGEgKHdyYXBfY2FsbGJhY2sgKGZ1biB4IF9pZHggXyAtPiBmIHgpKVxuXG5sZXQgYXJyYXlfbWFwaSBmIGEgPSBhcnJheV9tYXBfcG9seSBhICh3cmFwX2NhbGxiYWNrIChmdW4geCBpZHggXyAtPiBmIGlkeCB4KSlcblxuY2xhc3MgdHlwZSBtYXRjaF9yZXN1bHQgPSBvYmplY3RcbiAgaW5oZXJpdCBbanNfc3RyaW5nIHRdIGpzX2FycmF5XG5cbiAgbWV0aG9kIGluZGV4IDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgaW5wdXQgOiBqc19zdHJpbmcgdCByZWFkb25seV9wcm9wXG5lbmRcblxubGV0IHN0cl9hcnJheSA6IHN0cmluZ19hcnJheSB0IC0+IGpzX3N0cmluZyB0IGpzX2FycmF5IHQgPSBVbnNhZmUuY29lcmNlXG5cbmxldCBtYXRjaF9yZXN1bHQgOiBtYXRjaF9yZXN1bHRfaGFuZGxlIHQgLT4gbWF0Y2hfcmVzdWx0IHQgPSBVbnNhZmUuY29lcmNlXG5cbmNsYXNzIHR5cGUgZGF0ZSA9IG9iamVjdFxuICBtZXRob2QgdG9TdHJpbmcgOiBqc19zdHJpbmcgdCBtZXRoXG5cbiAgbWV0aG9kIHRvRGF0ZVN0cmluZyA6IGpzX3N0cmluZyB0IG1ldGhcblxuICBtZXRob2QgdG9UaW1lU3RyaW5nIDoganNfc3RyaW5nIHQgbWV0aFxuXG4gIG1ldGhvZCB0b0xvY2FsZVN0cmluZyA6IGpzX3N0cmluZyB0IG1ldGhcblxuICBtZXRob2QgdG9Mb2NhbGVEYXRlU3RyaW5nIDoganNfc3RyaW5nIHQgbWV0aFxuXG4gIG1ldGhvZCB0b0xvY2FsZVRpbWVTdHJpbmcgOiBqc19zdHJpbmcgdCBtZXRoXG5cbiAgbWV0aG9kIHZhbHVlT2YgOiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIGdldFRpbWUgOiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIGdldEZ1bGxZZWFyIDogaW50IG1ldGhcblxuICBtZXRob2QgZ2V0VVRDRnVsbFllYXIgOiBpbnQgbWV0aFxuXG4gIG1ldGhvZCBnZXRNb250aCA6IGludCBtZXRoXG5cbiAgbWV0aG9kIGdldFVUQ01vbnRoIDogaW50IG1ldGhcblxuICBtZXRob2QgZ2V0RGF0ZSA6IGludCBtZXRoXG5cbiAgbWV0aG9kIGdldFVUQ0RhdGUgOiBpbnQgbWV0aFxuXG4gIG1ldGhvZCBnZXREYXkgOiBpbnQgbWV0aFxuXG4gIG1ldGhvZCBnZXRVVENEYXkgOiBpbnQgbWV0aFxuXG4gIG1ldGhvZCBnZXRIb3VycyA6IGludCBtZXRoXG5cbiAgbWV0aG9kIGdldFVUQ0hvdXJzIDogaW50IG1ldGhcblxuICBtZXRob2QgZ2V0TWludXRlcyA6IGludCBtZXRoXG5cbiAgbWV0aG9kIGdldFVUQ01pbnV0ZXMgOiBpbnQgbWV0aFxuXG4gIG1ldGhvZCBnZXRTZWNvbmRzIDogaW50IG1ldGhcblxuICBtZXRob2QgZ2V0VVRDU2Vjb25kcyA6IGludCBtZXRoXG5cbiAgbWV0aG9kIGdldE1pbGxpc2Vjb25kcyA6IGludCBtZXRoXG5cbiAgbWV0aG9kIGdldFVUQ01pbGxpc2Vjb25kcyA6IGludCBtZXRoXG5cbiAgbWV0aG9kIGdldFRpbWV6b25lT2Zmc2V0IDogaW50IG1ldGhcblxuICBtZXRob2Qgc2V0VGltZSA6IG51bWJlcl90IC0+IG51bWJlcl90IG1ldGhcblxuICBtZXRob2Qgc2V0RnVsbFllYXIgOiBpbnQgLT4gbnVtYmVyX3QgbWV0aFxuXG4gIG1ldGhvZCBzZXRVVENGdWxsWWVhciA6IGludCAtPiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIHNldE1vbnRoIDogaW50IC0+IG51bWJlcl90IG1ldGhcblxuICBtZXRob2Qgc2V0VVRDTW9udGggOiBpbnQgLT4gbnVtYmVyX3QgbWV0aFxuXG4gIG1ldGhvZCBzZXREYXRlIDogaW50IC0+IG51bWJlcl90IG1ldGhcblxuICBtZXRob2Qgc2V0VVRDRGF0ZSA6IGludCAtPiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIHNldERheSA6IGludCAtPiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIHNldFVUQ0RheSA6IGludCAtPiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIHNldEhvdXJzIDogaW50IC0+IG51bWJlcl90IG1ldGhcblxuICBtZXRob2Qgc2V0VVRDSG91cnMgOiBpbnQgLT4gbnVtYmVyX3QgbWV0aFxuXG4gIG1ldGhvZCBzZXRNaW51dGVzIDogaW50IC0+IG51bWJlcl90IG1ldGhcblxuICBtZXRob2Qgc2V0VVRDTWludXRlcyA6IGludCAtPiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIHNldFNlY29uZHMgOiBpbnQgLT4gbnVtYmVyX3QgbWV0aFxuXG4gIG1ldGhvZCBzZXRVVENTZWNvbmRzIDogaW50IC0+IG51bWJlcl90IG1ldGhcblxuICBtZXRob2Qgc2V0TWlsbGlzZWNvbmRzIDogaW50IC0+IG51bWJlcl90IG1ldGhcblxuICBtZXRob2Qgc2V0VVRDTWlsbGlzZWNvbmRzIDogaW50IC0+IG51bWJlcl90IG1ldGhcblxuICBtZXRob2QgdG9VVENTdHJpbmcgOiBqc19zdHJpbmcgdCBtZXRoXG5cbiAgbWV0aG9kIHRvSVNPU3RyaW5nIDoganNfc3RyaW5nIHQgbWV0aFxuXG4gIG1ldGhvZCB0b0pTT04gOiAnYSAtPiBqc19zdHJpbmcgdCBtZXRoXG5lbmRcblxuY2xhc3MgdHlwZSBkYXRlX2NvbnN0ciA9IG9iamVjdFxuICBtZXRob2QgcGFyc2UgOiBqc19zdHJpbmcgdCAtPiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIF9VVENfbW9udGggOiBpbnQgLT4gaW50IC0+IG51bWJlcl90IG1ldGhcblxuICBtZXRob2QgX1VUQ19kYXkgOiBpbnQgLT4gaW50IC0+IG51bWJlcl90IG1ldGhcblxuICBtZXRob2QgX1VUQ19ob3VyIDogaW50IC0+IGludCAtPiBpbnQgLT4gaW50IC0+IG51bWJlcl90IG1ldGhcblxuICBtZXRob2QgX1VUQ19taW4gOiBpbnQgLT4gaW50IC0+IGludCAtPiBpbnQgLT4gaW50IC0+IG51bWJlcl90IG1ldGhcblxuICBtZXRob2QgX1VUQ19zZWMgOiBpbnQgLT4gaW50IC0+IGludCAtPiBpbnQgLT4gaW50IC0+IGludCAtPiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIF9VVENfbXMgOiBpbnQgLT4gaW50IC0+IGludCAtPiBpbnQgLT4gaW50IC0+IGludCAtPiBpbnQgLT4gbnVtYmVyX3QgbWV0aFxuXG4gIG1ldGhvZCBub3cgOiBudW1iZXJfdCBtZXRoXG5lbmRcblxubGV0IGRhdGVfY29uc3RyID0gVW5zYWZlLmdsb2JhbCMjLl9EYXRlXG5cbmxldCBkYXRlIDogZGF0ZV9jb25zdHIgdCA9IGRhdGVfY29uc3RyXG5cbmxldCBkYXRlX25vdyA6IGRhdGUgdCBjb25zdHIgPSBkYXRlX2NvbnN0clxuXG5sZXQgZGF0ZV9mcm9tVGltZVZhbHVlIDogKG51bWJlcl90IC0+IGRhdGUgdCkgY29uc3RyID0gZGF0ZV9jb25zdHJcblxubGV0IGRhdGVfbW9udGggOiAoaW50IC0+IGludCAtPiBkYXRlIHQpIGNvbnN0ciA9IGRhdGVfY29uc3RyXG5cbmxldCBkYXRlX2RheSA6IChpbnQgLT4gaW50IC0+IGludCAtPiBkYXRlIHQpIGNvbnN0ciA9IGRhdGVfY29uc3RyXG5cbmxldCBkYXRlX2hvdXIgOiAoaW50IC0+IGludCAtPiBpbnQgLT4gaW50IC0+IGRhdGUgdCkgY29uc3RyID0gZGF0ZV9jb25zdHJcblxubGV0IGRhdGVfbWluIDogKGludCAtPiBpbnQgLT4gaW50IC0+IGludCAtPiBpbnQgLT4gZGF0ZSB0KSBjb25zdHIgPSBkYXRlX2NvbnN0clxuXG5sZXQgZGF0ZV9zZWMgOiAoaW50IC0+IGludCAtPiBpbnQgLT4gaW50IC0+IGludCAtPiBpbnQgLT4gZGF0ZSB0KSBjb25zdHIgPSBkYXRlX2NvbnN0clxuXG5sZXQgZGF0ZV9tcyA6IChpbnQgLT4gaW50IC0+IGludCAtPiBpbnQgLT4gaW50IC0+IGludCAtPiBpbnQgLT4gZGF0ZSB0KSBjb25zdHIgPVxuICBkYXRlX2NvbnN0clxuXG5jbGFzcyB0eXBlIG1hdGggPSBvYmplY3RcbiAgbWV0aG9kIF9FIDogbnVtYmVyX3QgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfTE4yIDogbnVtYmVyX3QgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfTE4xMCA6IG51bWJlcl90IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0xPRzJFIDogbnVtYmVyX3QgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfTE9HMTBFIDogbnVtYmVyX3QgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfUEkgOiBudW1iZXJfdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9TUVJUMV8yXyA6IG51bWJlcl90IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1NRUlQyIDogbnVtYmVyX3QgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBhYnMgOiBudW1iZXJfdCAtPiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIGFjb3MgOiBudW1iZXJfdCAtPiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIGFzaW4gOiBudW1iZXJfdCAtPiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIGF0YW4gOiBudW1iZXJfdCAtPiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIGF0YW4yIDogbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgbWV0aFxuXG4gIG1ldGhvZCBjZWlsIDogbnVtYmVyX3QgLT4gbnVtYmVyX3QgbWV0aFxuXG4gIG1ldGhvZCBjb3MgOiBudW1iZXJfdCAtPiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIGV4cCA6IG51bWJlcl90IC0+IG51bWJlcl90IG1ldGhcblxuICBtZXRob2QgZmxvb3IgOiBudW1iZXJfdCAtPiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIGxvZyA6IG51bWJlcl90IC0+IG51bWJlcl90IG1ldGhcblxuICBtZXRob2QgbWF4IDogbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgbWV0aFxuXG4gIG1ldGhvZCBtYXhfMyA6IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG51bWJlcl90IG1ldGhcblxuICBtZXRob2QgbWF4XzQgOiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIG1pbiA6IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG51bWJlcl90IG1ldGhcblxuICBtZXRob2QgbWluXzMgOiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIG1pbl80IDogbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgbWV0aFxuXG4gIG1ldGhvZCBwb3cgOiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIHJhbmRvbSA6IG51bWJlcl90IG1ldGhcblxuICBtZXRob2Qgcm91bmQgOiBudW1iZXJfdCAtPiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIHNpbiA6IG51bWJlcl90IC0+IG51bWJlcl90IG1ldGhcblxuICBtZXRob2Qgc3FydCA6IG51bWJlcl90IC0+IG51bWJlcl90IG1ldGhcblxuICBtZXRob2QgdGFuIDogbnVtYmVyX3QgLT4gbnVtYmVyX3QgbWV0aFxuZW5kXG5cbmxldCBtYXRoID0gVW5zYWZlLmdsb2JhbCMjLl9NYXRoXG5cbmNsYXNzIHR5cGUgZXJyb3IgPSBvYmplY3RcbiAgbWV0aG9kIG5hbWUgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIG1lc3NhZ2UgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHN0YWNrIDoganNfc3RyaW5nIHQgb3B0ZGVmIHByb3BcblxuICBtZXRob2QgdG9TdHJpbmcgOiBqc19zdHJpbmcgdCBtZXRoXG5lbmRcblxubGV0IGVycm9yX2NvbnN0ciA9IFVuc2FmZS5nbG9iYWwjIy5fRXJyb3JcblxubW9kdWxlIEpzX2Vycm9yID0gc3RydWN0XG4gIHR5cGUgZXJyb3JfdCA9IGVycm9yIHRcblxuICBpbmNsdWRlIEpzb29fcnVudGltZS5FcnJvclxuXG4gIGV4dGVybmFsIG9mX2Vycm9yIDogZXJyb3JfdCAtPiB0ID0gXCIlaWRlbnRpdHlcIlxuXG4gIGV4dGVybmFsIHRvX2Vycm9yIDogdCAtPiBlcnJvcl90ID0gXCIlaWRlbnRpdHlcIlxuXG4gIGxldCBuYW1lIGUgPSB0b19zdHJpbmcgKHRvX2Vycm9yIGUpIyMubmFtZVxuXG4gIGxldCBtZXNzYWdlIGUgPSB0b19zdHJpbmcgKHRvX2Vycm9yIGUpIyMubWVzc2FnZVxuXG4gIGxldCBzdGFjayAoZSA6IHQpIDogc3RyaW5nIG9wdGlvbiA9XG4gICAgT3B0LnRvX29wdGlvbiAoT3B0Lm1hcCAodG9fZXJyb3IgZSkjIy5zdGFjayB0b19zdHJpbmcpXG5cbiAgbGV0IHRvX3N0cmluZyBlID0gdG9fc3RyaW5nICh0b19lcnJvciBlKSMjdG9TdHJpbmdcbmVuZFxuXG5tb2R1bGUgTWFnaWMgPSBzdHJ1Y3RcbiAgbW9kdWxlIHR5cGUgVCA9IHNpZ1xuICAgIGV4Y2VwdGlvbiBFcnJvciBvZiBlcnJvciB0XG4gIGVuZFxuXG4gIHR5cGUgKCdhLCAnYikgZXEgPSBFcSA6ICgnYSwgJ2EpIGVxXG5cbiAgbGV0IChlcSA6IChlcnJvciB0LCBKc19lcnJvci50KSBlcSkgPSBPYmoubWFnaWMgRXFcblxuICBsZXQgbSA9XG4gICAgbWF0Y2ggZXEgd2l0aFxuICAgIHwgRXEgLT5cbiAgICAgICAgKG1vZHVsZSBzdHJ1Y3RcbiAgICAgICAgICBleGNlcHRpb24gRXJyb3IgPSBKc19lcnJvci5FeG5cbiAgICAgICAgZW5kIDogVClcblxuICBtb2R1bGUgRXJyb3IgPSAodmFsIG0gOiBUKVxuZW5kXG5cbmluY2x1ZGUgTWFnaWMuRXJyb3JcblxubGV0IHJhaXNlX2pzX2Vycm9yIGUgPSBKc19lcnJvci5yYWlzZV8gKEpzX2Vycm9yLm9mX2Vycm9yIGUpXG5cbmxldCBzdHJpbmdfb2ZfZXJyb3IgZSA9IEpzX2Vycm9yLnRvX3N0cmluZyAoSnNfZXJyb3Iub2ZfZXJyb3IgZSlcblxubGV0IGV4bl93aXRoX2pzX2JhY2t0cmFjZSA9IEpzX2Vycm9yLmF0dGFjaF9qc19iYWNrdHJhY2VcblxuZXh0ZXJuYWwganNfZXJyb3Jfb2ZfZXhuIDogZXhuIC0+IGVycm9yIHQgb3B0ID0gXCJjYW1sX2pzX2Vycm9yX29mX2V4Y2VwdGlvblwiXG5cbmNsYXNzIHR5cGUganNvbiA9IG9iamVjdFxuICBtZXRob2QgcGFyc2UgOiBqc19zdHJpbmcgdCAtPiAnYSBtZXRoXG5cbiAgbWV0aG9kIHN0cmluZ2lmeSA6ICdhIC0+IGpzX3N0cmluZyB0IG1ldGhcbmVuZFxuXG5sZXQgX0pTT04gOiBqc29uIHQgPSBVbnNhZmUuZ2xvYmFsIyMuX0pTT05cblxubGV0IGRlY29kZVVSSSAocyA6IGpzX3N0cmluZyB0KSA6IGpzX3N0cmluZyB0ID1cbiAgVW5zYWZlLmZ1bl9jYWxsIFVuc2FmZS5nbG9iYWwjIy5kZWNvZGVVUkkgW3wgVW5zYWZlLmluamVjdCBzIHxdXG5cbmxldCBkZWNvZGVVUklDb21wb25lbnQgKHMgOiBqc19zdHJpbmcgdCkgOiBqc19zdHJpbmcgdCA9XG4gIFVuc2FmZS5mdW5fY2FsbCBVbnNhZmUuZ2xvYmFsIyMuZGVjb2RlVVJJQ29tcG9uZW50IFt8IFVuc2FmZS5pbmplY3QgcyB8XVxuXG5sZXQgZW5jb2RlVVJJIChzIDoganNfc3RyaW5nIHQpIDoganNfc3RyaW5nIHQgPVxuICBVbnNhZmUuZnVuX2NhbGwgVW5zYWZlLmdsb2JhbCMjLmVuY29kZVVSSSBbfCBVbnNhZmUuaW5qZWN0IHMgfF1cblxubGV0IGVuY29kZVVSSUNvbXBvbmVudCAocyA6IGpzX3N0cmluZyB0KSA6IGpzX3N0cmluZyB0ID1cbiAgVW5zYWZlLmZ1bl9jYWxsIFVuc2FmZS5nbG9iYWwjIy5lbmNvZGVVUklDb21wb25lbnQgW3wgVW5zYWZlLmluamVjdCBzIHxdXG5cbmxldCBlc2NhcGUgKHMgOiBqc19zdHJpbmcgdCkgOiBqc19zdHJpbmcgdCA9XG4gIFVuc2FmZS5mdW5fY2FsbCBVbnNhZmUuZ2xvYmFsIyMuZXNjYXBlIFt8IFVuc2FmZS5pbmplY3QgcyB8XVxuXG5sZXQgdW5lc2NhcGUgKHMgOiBqc19zdHJpbmcgdCkgOiBqc19zdHJpbmcgdCA9XG4gIFVuc2FmZS5mdW5fY2FsbCBVbnNhZmUuZ2xvYmFsIyMudW5lc2NhcGUgW3wgVW5zYWZlLmluamVjdCBzIHxdXG5cbmV4dGVybmFsIGJvb2wgOiBib29sIC0+IGJvb2wgdCA9IFwiY2FtbF9qc19mcm9tX2Jvb2xcIlxuXG5leHRlcm5hbCB0b19ib29sIDogYm9vbCB0IC0+IGJvb2wgPSBcImNhbWxfanNfdG9fYm9vbFwiXG5cbmV4dGVybmFsIGFycmF5IDogJ2EgYXJyYXkgLT4gJ2EganNfYXJyYXkgdCA9IFwiY2FtbF9qc19mcm9tX2FycmF5XCJcblxuZXh0ZXJuYWwgdG9fYXJyYXkgOiAnYSBqc19hcnJheSB0IC0+ICdhIGFycmF5ID0gXCJjYW1sX2pzX3RvX2FycmF5XCJcblxuZXh0ZXJuYWwgYnl0ZXN0cmluZyA6IHN0cmluZyAtPiBqc19zdHJpbmcgdCA9IFwiY2FtbF9qc2J5dGVzX29mX3N0cmluZ1wiXG5cbmV4dGVybmFsIHRvX2J5dGVzdHJpbmcgOiBqc19zdHJpbmcgdCAtPiBzdHJpbmcgPSBcImNhbWxfc3RyaW5nX29mX2pzYnl0ZXNcIlxuXG5leHRlcm5hbCBmbG9hdCA6IGZsb2F0IC0+IG51bWJlcl90ID0gXCJjYW1sX2pzX2Zyb21fZmxvYXRcIlxuXG5leHRlcm5hbCB0b19mbG9hdCA6IG51bWJlcl90IC0+IGZsb2F0ID0gXCJjYW1sX2pzX3RvX2Zsb2F0XCJcblxuZXh0ZXJuYWwgbnVtYmVyX29mX2Zsb2F0IDogZmxvYXQgLT4gbnVtYmVyIHQgPSBcImNhbWxfanNfZnJvbV9mbG9hdFwiXG5cbmV4dGVybmFsIGZsb2F0X29mX251bWJlciA6IG51bWJlciB0IC0+IGZsb2F0ID0gXCJjYW1sX2pzX3RvX2Zsb2F0XCJcblxuZXh0ZXJuYWwgaW50MzIgOiBpbnQzMiAtPiBudW1iZXJfdCA9IFwiY2FtbF9qc19mcm9tX2ludDMyXCJcblxuZXh0ZXJuYWwgdG9faW50MzIgOiBudW1iZXJfdCAtPiBpbnQzMiA9IFwiY2FtbF9qc190b19pbnQzMlwiXG5cbmV4dGVybmFsIG5hdGl2ZWludCA6IG5hdGl2ZWludCAtPiBudW1iZXJfdCA9IFwiY2FtbF9qc19mcm9tX25hdGl2ZWludFwiXG5cbmV4dGVybmFsIHRvX25hdGl2ZWludCA6IG51bWJlcl90IC0+IG5hdGl2ZWludCA9IFwiY2FtbF9qc190b19uYXRpdmVpbnRcIlxuXG5leHRlcm5hbCB0eXBlb2YgOiBfIHQgLT4ganNfc3RyaW5nIHQgPSBcImNhbWxfanNfdHlwZW9mXCJcblxuZXh0ZXJuYWwgaW5zdGFuY2VvZiA6IF8gdCAtPiBfIGNvbnN0ciAtPiBib29sID0gXCJjYW1sX2pzX2luc3RhbmNlb2ZcIlxuXG5sZXQgaXNOYU4gKGkgOiAnYSkgOiBib29sID1cbiAgdG9fYm9vbCAoVW5zYWZlLmZ1bl9jYWxsIFVuc2FmZS5nbG9iYWwjIy5pc05hTiBbfCBVbnNhZmUuaW5qZWN0IGkgfF0pXG5cbmxldCBwYXJzZUludCAocyA6IGpzX3N0cmluZyB0KSA6IGludCA9XG4gIGxldCBzID0gVW5zYWZlLmZ1bl9jYWxsIFVuc2FmZS5nbG9iYWwjIy5wYXJzZUludCBbfCBVbnNhZmUuaW5qZWN0IHMgfF0gaW5cbiAgaWYgaXNOYU4gcyB0aGVuIGZhaWx3aXRoIFwicGFyc2VJbnRcIiBlbHNlIHNcblxubGV0IHBhcnNlRmxvYXQgKHMgOiBqc19zdHJpbmcgdCkgOiBudW1iZXJfdCA9XG4gIGxldCBzID0gVW5zYWZlLmZ1bl9jYWxsIFVuc2FmZS5nbG9iYWwjIy5wYXJzZUZsb2F0IFt8IFVuc2FmZS5pbmplY3QgcyB8XSBpblxuICBpZiBpc05hTiBzIHRoZW4gZmFpbHdpdGggXCJwYXJzZUZsb2F0XCIgZWxzZSBzXG5cbmxldCBfID1cbiAgUHJpbnRleGMucmVnaXN0ZXJfcHJpbnRlciAoZnVuY3Rpb25cbiAgICAgIHwgSnNfZXJyb3IuRXhuIGUgLT4gU29tZSAoSnNfZXJyb3IudG9fc3RyaW5nIGUpXG4gICAgICB8IF8gLT4gTm9uZSlcblxubGV0IF8gPVxuICBQcmludGV4Yy5yZWdpc3Rlcl9wcmludGVyIChmdW4gZSAtPlxuICAgICAgbGV0IGUgOiA8IC4uID4gdCA9IE9iai5tYWdpYyBlIGluXG4gICAgICBpZiBpbnN0YW5jZW9mIGUgYXJyYXlfY29uc3RydWN0b3IgdGhlbiBOb25lIGVsc2UgU29tZSAodG9fc3RyaW5nIGUjI3RvU3RyaW5nKSlcblxubGV0IGV4cG9ydF9qcyAoZmllbGQgOiBqc19zdHJpbmcgdCkgeCA9XG4gIFVuc2FmZS5zZXRcbiAgICAoVW5zYWZlLnB1cmVfanNfZXhwciBcImpzb29fZXhwb3J0c1wiKVxuICAgIGZpZWxkXG4gICAgKGlmIFN0cmluZy5lcXVhbCAoSnMudG9fc3RyaW5nICh0eXBlb2YgKE9iai5tYWdpYyB4KSkpIFwiZnVuY3Rpb25cIlxuICAgICAgICAoKiBmdW5jdGlvbiB3aXRoIGFyaXR5L2xlbmd0aCBlcXVhbCB0byB6ZXJvIGFyZSBhbHJlYWR5IHdyYXBwZWQgKilcbiAgICAgICAgJiYgVW5zYWZlLmdldCAoT2JqLm1hZ2ljIHgpIChKcy5zdHJpbmcgXCJsZW5ndGhcIikgPiAwXG4gICAgIHRoZW4gT2JqLm1hZ2ljICh3cmFwX2NhbGxiYWNrIChPYmoubWFnaWMgeCkpXG4gICAgIGVsc2UgeClcblxubGV0IGV4cG9ydCBmaWVsZCB4ID0gZXhwb3J0X2pzIChzdHJpbmcgZmllbGQpIHhcblxubGV0IGV4cG9ydF9hbGwgb2JqID1cbiAgbGV0IGtleXMgPSBvYmplY3Rfa2V5cyBvYmogaW5cbiAga2V5cyMjZm9yRWFjaFxuICAgICh3cmFwX2NhbGxiYWNrIChmdW4gKGtleSA6IGpzX3N0cmluZyB0KSBfIF8gLT4gZXhwb3J0X2pzIGtleSAoVW5zYWZlLmdldCBvYmoga2V5KSkpXG5cbigqKioqKVxuXG4oKiBERVBSRUNBVEVEICopXG5cbnR5cGUgZmxvYXRfcHJvcCA9IG51bWJlcl90IHByb3BcbiIsIigqIEpzX29mX29jYW1sIGxpYnJhcnlcbiAqIGh0dHA6Ly93d3cub2NzaWdlbi5vcmcvanNfb2Zfb2NhbWwvXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTAgSsOpcsO0bWUgVm91aWxsb25cbiAqIExhYm9yYXRvaXJlIFBQUyAtIENOUlMgVW5pdmVyc2l0w6kgUGFyaXMgRGlkZXJvdFxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHdpdGggbGlua2luZyBleGNlcHRpb247XG4gKiBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcsIFVTQS5cbiAqKVxuXG5vcGVuIEpzXG5vcGVuISBJbXBvcnRcblxuY2xhc3MgdHlwZSBbJ25vZGVdIG5vZGVMaXN0ID0gb2JqZWN0XG4gIG1ldGhvZCBpdGVtIDogaW50IC0+ICdub2RlIHQgb3B0IG1ldGhcblxuICBtZXRob2QgbGVuZ3RoIDogaW50IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG5sZXQgbGlzdF9vZl9ub2RlTGlzdCAobm9kZUxpc3QgOiAnYSBub2RlTGlzdCB0KSA9XG4gIGxldCBsZW5ndGggPSBub2RlTGlzdCMjLmxlbmd0aCBpblxuICBsZXQgcmVjIGFkZF9pdGVtIGFjYyBpID1cbiAgICBpZiBpIDwgbGVuZ3RoXG4gICAgdGhlblxuICAgICAgbWF0Y2ggT3B0LnRvX29wdGlvbiAobm9kZUxpc3QjI2l0ZW0gaSkgd2l0aFxuICAgICAgfCBOb25lIC0+IGFkZF9pdGVtIGFjYyAoaSArIDEpXG4gICAgICB8IFNvbWUgZSAtPiBhZGRfaXRlbSAoZSA6OiBhY2MpIChpICsgMSlcbiAgICBlbHNlIExpc3QucmV2IGFjY1xuICBpblxuICBhZGRfaXRlbSBbXSAwXG5cbnR5cGUgbm9kZVR5cGUgPVxuICB8IE9USEVSXG4gICgqIFdpbGwgbm90IGhhcHBlbiAqKVxuICB8IEVMRU1FTlRcbiAgfCBBVFRSSUJVVEVcbiAgfCBURVhUXG4gIHwgQ0RBVEFfU0VDVElPTlxuICB8IEVOVElUWV9SRUZFUkVOQ0VcbiAgfCBFTlRJVFlcbiAgfCBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OXG4gIHwgQ09NTUVOVFxuICB8IERPQ1VNRU5UXG4gIHwgRE9DVU1FTlRfVFlQRVxuICB8IERPQ1VNRU5UX0ZSQUdNRU5UXG4gIHwgTk9UQVRJT05cblxubW9kdWxlIERvY3VtZW50UG9zaXRpb24gPSBzdHJ1Y3RcbiAgdHlwZSB0ID0gaW50XG5cbiAgdHlwZSBtYXNrID0gaW50XG5cbiAgbGV0IGRpc2Nvbm5lY3RlZCA9IDB4MDFcblxuICBsZXQgcHJlY2VkaW5nID0gMHgwMlxuXG4gIGxldCBmb2xsb3dpbmcgPSAweDA0XG5cbiAgbGV0IGNvbnRhaW5zID0gMHgwOFxuXG4gIGxldCBjb250YWluZWRfYnkgPSAweDEwXG5cbiAgbGV0IGltcGxlbWVudGF0aW9uX3NwZWNpZmljID0gMHgyMFxuXG4gIGxldCBoYXMgdCBtYXNrID0gdCBsYW5kIG1hc2sgPSBtYXNrXG5cbiAgbGV0IGFkZCB4IHkgPSB4IGxvciB5XG5cbiAgbGV0ICggKyApID0gYWRkXG5lbmRcblxuY2xhc3MgdHlwZSBub2RlID0gb2JqZWN0XG4gIG1ldGhvZCBub2RlTmFtZSA6IGpzX3N0cmluZyB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgbm9kZVZhbHVlIDoganNfc3RyaW5nIHQgb3B0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgbm9kZVR5cGUgOiBub2RlVHlwZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHBhcmVudE5vZGUgOiBub2RlIHQgb3B0IHByb3BcblxuICBtZXRob2QgY2hpbGROb2RlcyA6IG5vZGUgbm9kZUxpc3QgdCBwcm9wXG5cbiAgbWV0aG9kIGZpcnN0Q2hpbGQgOiBub2RlIHQgb3B0IHByb3BcblxuICBtZXRob2QgbGFzdENoaWxkIDogbm9kZSB0IG9wdCBwcm9wXG5cbiAgbWV0aG9kIHByZXZpb3VzU2libGluZyA6IG5vZGUgdCBvcHQgcHJvcFxuXG4gIG1ldGhvZCBuZXh0U2libGluZyA6IG5vZGUgdCBvcHQgcHJvcFxuXG4gIG1ldGhvZCBuYW1lc3BhY2VVUkkgOiBqc19zdHJpbmcgdCBvcHQgcHJvcFxuXG4gIG1ldGhvZCBpbnNlcnRCZWZvcmUgOiBub2RlIHQgLT4gbm9kZSB0IG9wdCAtPiBub2RlIHQgbWV0aFxuXG4gIG1ldGhvZCByZXBsYWNlQ2hpbGQgOiBub2RlIHQgLT4gbm9kZSB0IC0+IG5vZGUgdCBtZXRoXG5cbiAgbWV0aG9kIHJlbW92ZUNoaWxkIDogbm9kZSB0IC0+IG5vZGUgdCBtZXRoXG5cbiAgbWV0aG9kIGFwcGVuZENoaWxkIDogbm9kZSB0IC0+IG5vZGUgdCBtZXRoXG5cbiAgbWV0aG9kIGhhc0NoaWxkTm9kZXMgOiBib29sIHQgbWV0aFxuXG4gIG1ldGhvZCBjbG9uZU5vZGUgOiBib29sIHQgLT4gbm9kZSB0IG1ldGhcblxuICBtZXRob2QgY29tcGFyZURvY3VtZW50UG9zaXRpb24gOiBub2RlIHQgLT4gRG9jdW1lbnRQb3NpdGlvbi50IG1ldGhcblxuICBtZXRob2QgbG9va3VwTmFtZXNwYWNlVVJJIDoganNfc3RyaW5nIHQgLT4ganNfc3RyaW5nIHQgb3B0IG1ldGhcblxuICBtZXRob2QgbG9va3VwUHJlZml4IDoganNfc3RyaW5nIHQgLT4ganNfc3RyaW5nIHQgb3B0IG1ldGhcbmVuZFxuXG5sZXQgYXBwZW5kQ2hpbGQgKHAgOiAjbm9kZSB0KSAobiA6ICNub2RlIHQpID0gaWdub3JlIChwIyNhcHBlbmRDaGlsZCAobiA6PiBub2RlIHQpKVxuXG5sZXQgcmVtb3ZlQ2hpbGQgKHAgOiAjbm9kZSB0KSAobiA6ICNub2RlIHQpID0gaWdub3JlIChwIyNyZW1vdmVDaGlsZCAobiA6PiBub2RlIHQpKVxuXG5sZXQgcmVwbGFjZUNoaWxkIChwIDogI25vZGUgdCkgKG4gOiAjbm9kZSB0KSAobyA6ICNub2RlIHQpID1cbiAgaWdub3JlIChwIyNyZXBsYWNlQ2hpbGQgKG4gOj4gbm9kZSB0KSAobyA6PiBub2RlIHQpKVxuXG5sZXQgaW5zZXJ0QmVmb3JlIChwIDogI25vZGUgdCkgKG4gOiAjbm9kZSB0KSAobyA6ICNub2RlIHQgb3B0KSA9XG4gIGlnbm9yZSAocCMjaW5zZXJ0QmVmb3JlIChuIDo+IG5vZGUgdCkgKG8gOj4gbm9kZSB0IG9wdCkpXG5cbigqKiBTcGVjaWZpY2F0aW9uIG9mIFtBdHRyXSBvYmplY3RzLiAqKVxuY2xhc3MgdHlwZSBhdHRyID0gb2JqZWN0XG4gIGluaGVyaXQgbm9kZVxuXG4gIG1ldGhvZCBuYW1lIDoganNfc3RyaW5nIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBzcGVjaWZpZWQgOiBib29sIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCB2YWx1ZSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2Qgb3duZXJFbGVtZW50IDogZWxlbWVudCB0IHByb3BcbmVuZFxuXG4oKiogU3BlY2lmaWNhdGlvbiBvZiBbTmFtZWROb2RlTWFwXSBvYmplY3RzLiAqKVxuYW5kIFsnbm9kZV0gbmFtZWROb2RlTWFwID0gb2JqZWN0XG4gIG1ldGhvZCBnZXROYW1lZEl0ZW0gOiBqc19zdHJpbmcgdCAtPiAnbm9kZSB0IG9wdCBtZXRoXG5cbiAgbWV0aG9kIHNldE5hbWVkSXRlbSA6ICdub2RlIHQgLT4gJ25vZGUgdCBvcHQgbWV0aFxuXG4gIG1ldGhvZCByZW1vdmVOYW1lZEl0ZW0gOiBqc19zdHJpbmcgdCAtPiAnbm9kZSB0IG9wdCBtZXRoXG5cbiAgbWV0aG9kIGl0ZW0gOiBpbnQgLT4gJ25vZGUgdCBvcHQgbWV0aFxuXG4gIG1ldGhvZCBsZW5ndGggOiBpbnQgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbigqKiBTcGVjaWZpY2F0aW9uIG9mIFtFbGVtZW50XSBvYmplY3RzLiAqKVxuYW5kIGVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBub2RlXG5cbiAgbWV0aG9kIHRhZ05hbWUgOiBqc19zdHJpbmcgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGdldEF0dHJpYnV0ZSA6IGpzX3N0cmluZyB0IC0+IGpzX3N0cmluZyB0IG9wdCBtZXRoXG5cbiAgbWV0aG9kIHNldEF0dHJpYnV0ZSA6IGpzX3N0cmluZyB0IC0+IGpzX3N0cmluZyB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCByZW1vdmVBdHRyaWJ1dGUgOiBqc19zdHJpbmcgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgaGFzQXR0cmlidXRlIDoganNfc3RyaW5nIHQgLT4gYm9vbCB0IG1ldGhcblxuICBtZXRob2QgZ2V0QXR0cmlidXRlTlMgOiBqc19zdHJpbmcgdCAtPiBqc19zdHJpbmcgdCAtPiBqc19zdHJpbmcgdCBvcHQgbWV0aFxuXG4gIG1ldGhvZCBzZXRBdHRyaWJ1dGVOUyA6IGpzX3N0cmluZyB0IC0+IGpzX3N0cmluZyB0IC0+IGpzX3N0cmluZyB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCByZW1vdmVBdHRyaWJ1dGVOUyA6IGpzX3N0cmluZyB0IC0+IGpzX3N0cmluZyB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBoYXNBdHRyaWJ1dGVOUyA6IGpzX3N0cmluZyB0IC0+IGpzX3N0cmluZyB0IC0+IGJvb2wgdCBtZXRoXG5cbiAgbWV0aG9kIGdldEF0dHJpYnV0ZU5vZGUgOiBqc19zdHJpbmcgdCAtPiBhdHRyIHQgb3B0IG1ldGhcblxuICBtZXRob2Qgc2V0QXR0cmlidXRlTm9kZSA6IGF0dHIgdCAtPiBhdHRyIHQgb3B0IG1ldGhcblxuICBtZXRob2QgcmVtb3ZlQXR0cmlidXRlTm9kZSA6IGF0dHIgdCAtPiBhdHRyIHQgbWV0aFxuXG4gIG1ldGhvZCBnZXRBdHRyaWJ1dGVOb2RlTlMgOiBqc19zdHJpbmcgdCAtPiBqc19zdHJpbmcgdCAtPiBhdHRyIHQgb3B0IG1ldGhcblxuICBtZXRob2Qgc2V0QXR0cmlidXRlTm9kZU5TIDogYXR0ciB0IC0+IGF0dHIgdCBvcHQgbWV0aFxuXG4gIG1ldGhvZCBnZXRFbGVtZW50c0J5VGFnTmFtZSA6IGpzX3N0cmluZyB0IC0+IGVsZW1lbnQgbm9kZUxpc3QgdCBtZXRoXG5cbiAgbWV0aG9kIGF0dHJpYnV0ZXMgOiBhdHRyIG5hbWVkTm9kZU1hcCB0IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG5jbGFzcyB0eXBlIGNoYXJhY3RlckRhdGEgPSBvYmplY3RcbiAgaW5oZXJpdCBub2RlXG5cbiAgbWV0aG9kIGRhdGEgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGxlbmd0aCA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHN1YmpzX3N0cmluZ0RhdGEgOiBpbnQgLT4gaW50IC0+IGpzX3N0cmluZyB0IG1ldGhcblxuICBtZXRob2QgYXBwZW5kRGF0YSA6IGpzX3N0cmluZyB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBpbnNlcnREYXRhIDogaW50IC0+IGpzX3N0cmluZyB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBkZWxldGVEYXRhIDogaW50IC0+IGludCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgcmVwbGFjZURhdGEgOiBpbnQgLT4gaW50IC0+IGpzX3N0cmluZyB0IC0+IHVuaXQgbWV0aFxuZW5kXG5cbmNsYXNzIHR5cGUgY29tbWVudCA9IGNoYXJhY3RlckRhdGFcblxuY2xhc3MgdHlwZSB0ZXh0ID0gY2hhcmFjdGVyRGF0YVxuXG5jbGFzcyB0eXBlIGRvY3VtZW50RnJhZ21lbnQgPSBub2RlXG5cbmNsYXNzIHR5cGUgWydlbGVtZW50XSBkb2N1bWVudCA9IG9iamVjdFxuICBpbmhlcml0IG5vZGVcblxuICBtZXRob2QgZG9jdW1lbnRFbGVtZW50IDogJ2VsZW1lbnQgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGNyZWF0ZURvY3VtZW50RnJhZ21lbnQgOiBkb2N1bWVudEZyYWdtZW50IHQgbWV0aFxuXG4gIG1ldGhvZCBjcmVhdGVFbGVtZW50IDoganNfc3RyaW5nIHQgLT4gJ2VsZW1lbnQgdCBtZXRoXG5cbiAgbWV0aG9kIGNyZWF0ZUVsZW1lbnROUyA6IGpzX3N0cmluZyB0IC0+IGpzX3N0cmluZyB0IC0+ICdlbGVtZW50IHQgbWV0aFxuXG4gIG1ldGhvZCBjcmVhdGVUZXh0Tm9kZSA6IGpzX3N0cmluZyB0IC0+IHRleHQgdCBtZXRoXG5cbiAgbWV0aG9kIGNyZWF0ZUF0dHJpYnV0ZSA6IGpzX3N0cmluZyB0IC0+IGF0dHIgdCBtZXRoXG5cbiAgbWV0aG9kIGNyZWF0ZUNvbW1lbnQgOiBqc19zdHJpbmcgdCAtPiBjb21tZW50IHQgbWV0aFxuXG4gIG1ldGhvZCBnZXRFbGVtZW50QnlJZCA6IGpzX3N0cmluZyB0IC0+ICdlbGVtZW50IHQgb3B0IG1ldGhcblxuICBtZXRob2QgZ2V0RWxlbWVudHNCeVRhZ05hbWUgOiBqc19zdHJpbmcgdCAtPiAnZWxlbWVudCBub2RlTGlzdCB0IG1ldGhcblxuICBtZXRob2QgaW1wb3J0Tm9kZSA6IGVsZW1lbnQgdCAtPiBib29sIHQgLT4gJ2VsZW1lbnQgdCBtZXRoXG5cbiAgbWV0aG9kIGFkb3B0Tm9kZSA6IGVsZW1lbnQgdCAtPiAnZWxlbWVudCB0IG1ldGhcbmVuZFxuXG50eXBlIG5vZGVfdHlwZSA9XG4gIHwgRWxlbWVudCBvZiBlbGVtZW50IHRcbiAgfCBBdHRyIG9mIGF0dHIgdFxuICB8IFRleHQgb2YgdGV4dCB0XG4gIHwgT3RoZXIgb2Ygbm9kZSB0XG5cbmxldCBub2RlVHlwZSBlID1cbiAgbWF0Y2ggZSMjLm5vZGVUeXBlIHdpdGhcbiAgfCBFTEVNRU5UIC0+IEVsZW1lbnQgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgfCBBVFRSSUJVVEUgLT4gQXR0ciAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICB8IENEQVRBX1NFQ1RJT04gfCBURVhUIC0+IFRleHQgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgfCBfIC0+IE90aGVyIChlIDo+IG5vZGUgdClcblxubW9kdWxlIENvZXJjZVRvID0gc3RydWN0XG4gIGxldCBjYXN0IChlIDogI25vZGUgSnMudCkgdCA9XG4gICAgaWYgZSMjLm5vZGVUeXBlID09IHQgdGhlbiBKcy5zb21lIChKcy5VbnNhZmUuY29lcmNlIGUpIGVsc2UgSnMubnVsbFxuXG4gIGxldCBlbGVtZW50IGUgOiBlbGVtZW50IEpzLnQgSnMub3B0ID0gY2FzdCBlIEVMRU1FTlRcblxuICBsZXQgdGV4dCBlIDogdGV4dCBKcy50IEpzLm9wdCA9XG4gICAgaWYgZSMjLm5vZGVUeXBlID09IFRFWFQgfHwgZSMjLm5vZGVUeXBlID09IENEQVRBX1NFQ1RJT05cbiAgICB0aGVuIEpzLnNvbWUgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICBlbHNlIEpzLm51bGxcblxuICBsZXQgYXR0ciBlIDogYXR0ciBKcy50IEpzLm9wdCA9IGNhc3QgZSBBVFRSSUJVVEVcbmVuZFxuXG50eXBlICgnYSwgJ2IpIGV2ZW50X2xpc3RlbmVyID0gKCdhLCAnYiAtPiBib29sIHQpIG1ldGhfY2FsbGJhY2sgb3B0XG4oKiogVGhlIHR5cGUgb2YgZXZlbnQgbGlzdGVuZXIgZnVuY3Rpb25zLiAgVGhlIGZpcnN0IHR5cGUgcGFyYW1ldGVyXG4gICAgICBbJ2FdIGlzIHRoZSB0eXBlIG9mIHRoZSB0YXJnZXQgb2JqZWN0OyB0aGUgc2Vjb25kIHBhcmFtZXRlclxuICAgICAgWydiXSBpcyB0aGUgdHlwZSBvZiB0aGUgZXZlbnQgb2JqZWN0LiAqKVxuXG5jbGFzcyB0eXBlIFsnYV0gZXZlbnQgPSBvYmplY3RcbiAgbWV0aG9kIF90eXBlIDoganNfc3RyaW5nIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCB0YXJnZXQgOiAnYSB0IG9wdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGN1cnJlbnRUYXJnZXQgOiAnYSB0IG9wdCByZWFkb25seV9wcm9wXG5cbiAgKCogTGVnYWN5IG1ldGhvZHMgKilcbiAgbWV0aG9kIHNyY0VsZW1lbnQgOiAnYSB0IG9wdCByZWFkb25seV9wcm9wXG5lbmRcblxuY2xhc3MgdHlwZSBbJ2EsICdiXSBjdXN0b21FdmVudCA9IG9iamVjdFxuICBpbmhlcml0IFsnYV0gZXZlbnRcblxuICBtZXRob2QgZGV0YWlsIDogJ2IgSnMub3B0IEpzLnJlYWRvbmx5X3Byb3BcbmVuZFxuXG5sZXQgbm9faGFuZGxlciA6ICgnYSwgJ2IpIGV2ZW50X2xpc3RlbmVyID0gSnMubnVsbFxuXG5sZXQgd2luZG93X2V2ZW50ICgpIDogJ2EgI2V2ZW50IHQgPSBKcy5VbnNhZmUucHVyZV9qc19leHByIFwiZXZlbnRcIlxuXG4oKiBUaGUgZnVuY3Rpb24gcHJldmVudERlZmF1bHQgbXVzdCBiZSBjYWxsZWQgZXhwbGljaXRseSB3aGVuXG4gICB1c2luZyBhZGRFdmVudExpc3RlbmVyLi4uICopXG5sZXQgaGFuZGxlciBmID1cbiAgSnMuc29tZVxuICAgIChKcy5VbnNhZmUuY2FsbGJhY2sgKGZ1biBlIC0+XG4gICAgICAgICAoKiBkZXBlbmRpbmcgb24gdGhlIGludGVybmV0IGV4cGxvcmVyIHZlcnNpb24sIGUgY2FuIGJlIG51bGwgb3IgdW5kZWZpbmVkLiAqKVxuICAgICAgICAgaWYgbm90IChKcy5PcHQudGVzdCAoc29tZSBlKSlcbiAgICAgICAgIHRoZW4gKFxuICAgICAgICAgICBsZXQgZSA9IHdpbmRvd19ldmVudCAoKSBpblxuICAgICAgICAgICBsZXQgcmVzID0gZiBlIGluXG4gICAgICAgICAgIGlmIG5vdCAoSnMudG9fYm9vbCByZXMpIHRoZW4gZSMjLnJldHVyblZhbHVlIDo9IHJlcztcbiAgICAgICAgICAgcmVzKVxuICAgICAgICAgZWxzZVxuICAgICAgICAgICBsZXQgcmVzID0gZiBlIGluXG4gICAgICAgICAgIGlmIG5vdCAoSnMudG9fYm9vbCByZXMpIHRoZW4gKEpzLlVuc2FmZS5jb2VyY2UgZSkjI3ByZXZlbnREZWZhdWx0O1xuICAgICAgICAgICByZXMpKVxuXG5sZXQgZnVsbF9oYW5kbGVyIGYgPVxuICBKcy5zb21lXG4gICAgKEpzLlVuc2FmZS5tZXRoX2NhbGxiYWNrIChmdW4gdGhpcyBlIC0+XG4gICAgICAgICAoKiBkZXBlbmRpbmcgb24gdGhlIGludGVybmV0IGV4cGxvcmVyIHZlcnNpb24sIGUgY2FuIGJlIG51bGwgb3IgdW5kZWZpbmVkICopXG4gICAgICAgICBpZiBub3QgKEpzLk9wdC50ZXN0IChzb21lIGUpKVxuICAgICAgICAgdGhlbiAoXG4gICAgICAgICAgIGxldCBlID0gd2luZG93X2V2ZW50ICgpIGluXG4gICAgICAgICAgIGxldCByZXMgPSBmIHRoaXMgZSBpblxuICAgICAgICAgICBpZiBub3QgKEpzLnRvX2Jvb2wgcmVzKSB0aGVuIGUjIy5yZXR1cm5WYWx1ZSA6PSByZXM7XG4gICAgICAgICAgIHJlcylcbiAgICAgICAgIGVsc2VcbiAgICAgICAgICAgbGV0IHJlcyA9IGYgdGhpcyBlIGluXG4gICAgICAgICAgIGlmIG5vdCAoSnMudG9fYm9vbCByZXMpIHRoZW4gKEpzLlVuc2FmZS5jb2VyY2UgZSkjI3ByZXZlbnREZWZhdWx0O1xuICAgICAgICAgICByZXMpKVxuXG5sZXQgaW52b2tlX2hhbmRsZXIgKGYgOiAoJ2EsICdiKSBldmVudF9saXN0ZW5lcikgKHRoaXMgOiAnYSkgKGV2ZW50IDogJ2IpIDogYm9vbCB0ID1cbiAgSnMuVW5zYWZlLmNhbGwgZiB0aGlzIFt8IEpzLlVuc2FmZS5pbmplY3QgZXZlbnQgfF1cblxubGV0IGV2ZW50VGFyZ2V0IChlIDogKDwgLi4gPiBhcyAnYSkgI2V2ZW50IHQpIDogJ2EgdCA9XG4gIGxldCB0YXJnZXQgPVxuICAgIE9wdC5nZXQgZSMjLnRhcmdldCAoZnVuICgpIC0+IE9wdC5nZXQgZSMjLnNyY0VsZW1lbnQgKGZ1biAoKSAtPiByYWlzZSBOb3RfZm91bmQpKVxuICBpblxuICBpZiBKcy5pbnN0YW5jZW9mIHRhcmdldCBKcy5VbnNhZmUuZ2xvYmFsIyMuX05vZGVcbiAgdGhlblxuICAgICgqIFdvcmthcm91bmQgZm9yIFNhZmFyaSBidWcgKilcbiAgICBsZXQgdGFyZ2V0JyA6IG5vZGUgSnMudCA9IEpzLlVuc2FmZS5jb2VyY2UgdGFyZ2V0IGluXG4gICAgaWYgdGFyZ2V0JyMjLm5vZGVUeXBlID09IFRFWFRcbiAgICB0aGVuIEpzLlVuc2FmZS5jb2VyY2UgKE9wdC5nZXQgdGFyZ2V0JyMjLnBhcmVudE5vZGUgKGZ1biAoKSAtPiBhc3NlcnQgZmFsc2UpKVxuICAgIGVsc2UgdGFyZ2V0XG4gIGVsc2UgdGFyZ2V0XG5cbm1vZHVsZSBFdmVudCA9IHN0cnVjdFxuICB0eXBlICdhIHR5cCA9IEpzLmpzX3N0cmluZyBKcy50XG5cbiAgbGV0IG1ha2UgcyA9IEpzLnN0cmluZyBzXG5lbmRcblxudHlwZSBldmVudF9saXN0ZW5lcl9pZCA9IHVuaXQgLT4gdW5pdFxuXG5jbGFzcyB0eXBlIGV2ZW50X2xpc3RlbmVyX29wdGlvbnMgPSBvYmplY3RcbiAgbWV0aG9kIGNhcHR1cmUgOiBib29sIHQgd3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2Qgb25jZSA6IGJvb2wgdCB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBwYXNzaXZlIDogYm9vbCB0IHdyaXRlb25seV9wcm9wXG5lbmRcblxubGV0IGFkZEV2ZW50TGlzdGVuZXJXaXRoT3B0aW9ucyAoZSA6ICg8IC4uID4gYXMgJ2EpIHQpIHR5cCA/Y2FwdHVyZSA/b25jZSA/cGFzc2l2ZSBoID1cbiAgaWYgbm90IChKcy5PcHRkZWYudGVzdCAoSnMuVW5zYWZlLmNvZXJjZSBlKSMjLmFkZEV2ZW50TGlzdGVuZXIpXG4gIHRoZW5cbiAgICBsZXQgZXYgPSAoSnMuc3RyaW5nIFwib25cIikjI2NvbmNhdCB0eXAgaW5cbiAgICBsZXQgY2FsbGJhY2sgZSA9IEpzLlVuc2FmZS5jYWxsIChoLCBlLCBbfHxdKSBpblxuICAgIGxldCAoKSA9IChKcy5VbnNhZmUuY29lcmNlIGUpIyNhdHRhY2hFdmVudCBldiBjYWxsYmFjayBpblxuICAgIGZ1biAoKSAtPiAoSnMuVW5zYWZlLmNvZXJjZSBlKSMjZGV0YWNoRXZlbnQgZXYgY2FsbGJhY2tcbiAgZWxzZVxuICAgIGxldCBvcHRzIDogZXZlbnRfbGlzdGVuZXJfb3B0aW9ucyB0ID0gSnMuVW5zYWZlLm9iaiBbfHxdIGluXG4gICAgbGV0IGl0ZXIgdCBmID1cbiAgICAgIG1hdGNoIHQgd2l0aFxuICAgICAgfCBOb25lIC0+ICgpXG4gICAgICB8IFNvbWUgYiAtPiBmIGJcbiAgICBpblxuICAgIGl0ZXIgY2FwdHVyZSAoZnVuIGIgLT4gb3B0cyMjLmNhcHR1cmUgOj0gYik7XG4gICAgaXRlciBvbmNlIChmdW4gYiAtPiBvcHRzIyMub25jZSA6PSBiKTtcbiAgICBpdGVyIHBhc3NpdmUgKGZ1biBiIC0+IG9wdHMjIy5wYXNzaXZlIDo9IGIpO1xuICAgIGxldCAoKSA9IChKcy5VbnNhZmUuY29lcmNlIGUpIyNhZGRFdmVudExpc3RlbmVyIHR5cCBoIG9wdHMgaW5cbiAgICBmdW4gKCkgLT4gKEpzLlVuc2FmZS5jb2VyY2UgZSkjI3JlbW92ZUV2ZW50TGlzdGVuZXIgdHlwIGggb3B0c1xuXG5sZXQgYWRkRXZlbnRMaXN0ZW5lciAoZSA6ICg8IC4uID4gYXMgJ2EpIHQpIHR5cCBoIGNhcHQgPVxuICBhZGRFdmVudExpc3RlbmVyV2l0aE9wdGlvbnMgZSB0eXAgfmNhcHR1cmU6Y2FwdCBoXG5cbmxldCByZW1vdmVFdmVudExpc3RlbmVyIGlkID0gaWQgKClcblxubGV0IHByZXZlbnREZWZhdWx0IGV2ID1cbiAgaWYgSnMuT3B0ZGVmLnRlc3QgKEpzLlVuc2FmZS5jb2VyY2UgZXYpIyMucHJldmVudERlZmF1bHQgKCogSUUgaGFjayAqKVxuICB0aGVuIChKcy5VbnNhZmUuY29lcmNlIGV2KSMjcHJldmVudERlZmF1bHRcbiAgZWxzZSAoSnMuVW5zYWZlLmNvZXJjZSBldikjIy5yZXR1cm5WYWx1ZSA6PSBKcy5ib29sIGZhbHNlXG5cbmxldCBjcmVhdGVDdXN0b21FdmVudCA/YnViYmxlcyA/Y2FuY2VsYWJsZSA/ZGV0YWlsIHR5cCA9XG4gIGxldCBvcHRfaXRlciBmID0gZnVuY3Rpb25cbiAgICB8IE5vbmUgLT4gKClcbiAgICB8IFNvbWUgeCAtPiBmIHhcbiAgaW5cbiAgbGV0IG9wdHMgPSBVbnNhZmUub2JqIFt8fF0gaW5cbiAgb3B0X2l0ZXIgKGZ1biB4IC0+IG9wdHMjIy5idWJibGVzIDo9IGJvb2wgeCkgYnViYmxlcztcbiAgb3B0X2l0ZXIgKGZ1biB4IC0+IG9wdHMjIy5jYW5jZWxhYmxlIDo9IGJvb2wgeCkgY2FuY2VsYWJsZTtcbiAgb3B0X2l0ZXIgKGZ1biB4IC0+IG9wdHMjIy5kZXRhaWwgOj0gc29tZSB4KSBkZXRhaWw7XG4gIGxldCBjb25zdHIgOlxuICAgICAgKCAgICgnYSwgJ2IpICNjdXN0b21FdmVudCBKcy50IEV2ZW50LnR5cFxuICAgICAgIC0+IDwgZGV0YWlsIDogJ2Igb3B0IHByb3AgPiB0XG4gICAgICAgLT4gKCdhLCAnYikgY3VzdG9tRXZlbnQgdClcbiAgICAgIGNvbnN0ciA9XG4gICAgVW5zYWZlLmdsb2JhbCMjLl9DdXN0b21FdmVudFxuICBpblxuICBuZXclanMgY29uc3RyIHR5cCBvcHRzXG5cbigqIElFIDwgOSAqKVxuXG5jbGFzcyB0eXBlIHN0cmluZ0xpc3QgPSBvYmplY3RcbiAgbWV0aG9kIGl0ZW0gOiBpbnQgLT4ganNfc3RyaW5nIHQgb3B0IG1ldGhcblxuICBtZXRob2QgbGVuZ3RoIDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgY29udGFpbnMgOiBqc19zdHJpbmcgdCAtPiBib29sIHQgbWV0aFxuZW5kXG4iLCIoKiBKc19vZl9vY2FtbCBsaWJyYXJ5XG4gKiBodHRwOi8vd3d3Lm9jc2lnZW4ub3JnL2pzX29mX29jYW1sL1xuICogQ29weXJpZ2h0IChDKSAyMDEyIErDqXLDtG1lIFZvdWlsbG9uXG4gKiBMYWJvcmF0b2lyZSBQUFMgLSBDTlJTIFVuaXZlcnNpdMOpIFBhcmlzIERpZGVyb3RcbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCB3aXRoIGxpbmtpbmcgZXhjZXB0aW9uO1xuICogZWl0aGVyIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuXG4gKilcbm9wZW4hIEltcG9ydFxub3BlbiBKc1xuXG50eXBlIHVpbnQzMiA9IGZsb2F0XG5cbmNsYXNzIHR5cGUgYXJyYXlCdWZmZXIgPSBvYmplY3RcbiAgbWV0aG9kIGJ5dGVMZW5ndGggOiBpbnQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBzbGljZSA6IGludCAtPiBpbnQgLT4gYXJyYXlCdWZmZXIgdCBtZXRoXG5cbiAgbWV0aG9kIHNsaWNlX3RvRW5kIDogaW50IC0+IGFycmF5QnVmZmVyIHQgbWV0aFxuZW5kXG5cbmxldCBhcnJheUJ1ZmZlciA6IChpbnQgLT4gYXJyYXlCdWZmZXIgdCkgY29uc3RyID0gSnMuVW5zYWZlLmdsb2JhbCMjLl9BcnJheUJ1ZmZlclxuXG5jbGFzcyB0eXBlIGFycmF5QnVmZmVyVmlldyA9IG9iamVjdFxuICBtZXRob2QgYnVmZmVyIDogYXJyYXlCdWZmZXIgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGJ5dGVPZmZzZXQgOiBpbnQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBieXRlTGVuZ3RoIDogaW50IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG5jbGFzcyB0eXBlIFsnYSwgJ2JdIHR5cGVkQXJyYXkgPSBvYmplY3RcbiAgaW5oZXJpdCBhcnJheUJ1ZmZlclZpZXdcblxuICBtZXRob2QgX0JZVEVTX1BFUl9FTEVNRU5UIDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgbGVuZ3RoIDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgc2V0X2Zyb21BcnJheSA6ICdhIGpzX2FycmF5IHQgLT4gaW50IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBzZXRfZnJvbVR5cGVkQXJyYXkgOiAoJ2EsICdiKSB0eXBlZEFycmF5IHQgLT4gaW50IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBzdWJhcnJheSA6IGludCAtPiBpbnQgLT4gKCdhLCAnYikgdHlwZWRBcnJheSB0IG1ldGhcblxuICBtZXRob2Qgc3ViYXJyYXlfdG9FbmQgOiBpbnQgLT4gKCdhLCAnYikgdHlwZWRBcnJheSB0IG1ldGhcblxuICBtZXRob2Qgc2xpY2UgOiBpbnQgLT4gaW50IC0+ICgnYSwgJ2IpIHR5cGVkQXJyYXkgdCBtZXRoXG5cbiAgbWV0aG9kIHNsaWNlX3RvRW5kIDogaW50IC0+ICgnYSwgJ2IpIHR5cGVkQXJyYXkgdCBtZXRoXG5cbiAgKCogVGhpcyBmYWtlIG1ldGhvZCBpcyBuZWVkZWQgZm9yIHR5cGluZyBwdXJwb3Nlcy5cbiAgICAgV2l0aG91dCBpdCwgWydiXSB3b3VsZCBub3QgYmUgY29uc3RyYWluZWQuICopXG4gIG1ldGhvZCBfY29udGVudF90eXBlXyA6ICdiIG9wdGRlZiByZWFkb25seV9wcm9wXG5lbmRcblxudHlwZSBpbnQ4QXJyYXkgPSAoaW50LCBCaWdhcnJheS5pbnQ4X3NpZ25lZF9lbHQpIHR5cGVkQXJyYXlcblxudHlwZSB1aW50OEFycmF5ID0gKGludCwgQmlnYXJyYXkuaW50OF91bnNpZ25lZF9lbHQpIHR5cGVkQXJyYXlcblxudHlwZSBpbnQxNkFycmF5ID0gKGludCwgQmlnYXJyYXkuaW50MTZfc2lnbmVkX2VsdCkgdHlwZWRBcnJheVxuXG50eXBlIHVpbnQxNkFycmF5ID0gKGludCwgQmlnYXJyYXkuaW50MTZfdW5zaWduZWRfZWx0KSB0eXBlZEFycmF5XG5cbnR5cGUgaW50MzJBcnJheSA9IChpbnQzMiwgQmlnYXJyYXkuaW50MzJfZWx0KSB0eXBlZEFycmF5XG5cbnR5cGUgdWludDMyQXJyYXkgPSAoaW50MzIsIEJpZ2FycmF5LmludDMyX2VsdCkgdHlwZWRBcnJheVxuXG50eXBlIGZsb2F0MzJBcnJheSA9IChmbG9hdCwgQmlnYXJyYXkuZmxvYXQzMl9lbHQpIHR5cGVkQXJyYXlcblxudHlwZSBmbG9hdDY0QXJyYXkgPSAoZmxvYXQsIEJpZ2FycmF5LmZsb2F0NjRfZWx0KSB0eXBlZEFycmF5XG5cbmV4dGVybmFsIGtpbmQgOiAoJ2EsICdiKSB0eXBlZEFycmF5IHQgLT4gKCdhLCAnYikgQmlnYXJyYXkua2luZFxuICA9IFwiY2FtbF9iYV9raW5kX29mX3R5cGVkX2FycmF5XCJcblxuZXh0ZXJuYWwgZnJvbV9nZW5hcnJheSA6XG4gICgnYSwgJ2IsIEJpZ2FycmF5LmNfbGF5b3V0KSBCaWdhcnJheS5HZW5hcnJheS50IC0+ICgnYSwgJ2IpIHR5cGVkQXJyYXkgdFxuICA9IFwiY2FtbF9iYV90b190eXBlZF9hcnJheVwiXG5cbmV4dGVybmFsIHRvX2dlbmFycmF5IDpcbiAgKCdhLCAnYikgdHlwZWRBcnJheSB0IC0+ICgnYSwgJ2IsIEJpZ2FycmF5LmNfbGF5b3V0KSBCaWdhcnJheS5HZW5hcnJheS50XG4gID0gXCJjYW1sX2JhX2Zyb21fdHlwZWRfYXJyYXlcIlxuXG5sZXQgaW50OEFycmF5ID0gSnMuVW5zYWZlLmdsb2JhbCMjLl9JbnQ4QXJyYXlcblxubGV0IGludDhBcnJheV9mcm9tQXJyYXkgPSBpbnQ4QXJyYXlcblxubGV0IGludDhBcnJheV9mcm9tVHlwZWRBcnJheSA9IGludDhBcnJheVxuXG5sZXQgaW50OEFycmF5X2Zyb21CdWZmZXIgPSBpbnQ4QXJyYXlcblxubGV0IGludDhBcnJheV9pbkJ1ZmZlciA9IGludDhBcnJheVxuXG5sZXQgdWludDhBcnJheSA9IEpzLlVuc2FmZS5nbG9iYWwjIy5fVWludDhBcnJheVxuXG5sZXQgdWludDhBcnJheV9mcm9tQXJyYXkgPSB1aW50OEFycmF5XG5cbmxldCB1aW50OEFycmF5X2Zyb21UeXBlZEFycmF5ID0gdWludDhBcnJheVxuXG5sZXQgdWludDhBcnJheV9mcm9tQnVmZmVyID0gdWludDhBcnJheVxuXG5sZXQgdWludDhBcnJheV9pbkJ1ZmZlciA9IHVpbnQ4QXJyYXlcblxubGV0IGludDE2QXJyYXkgPSBKcy5VbnNhZmUuZ2xvYmFsIyMuX0ludDE2QXJyYXlcblxubGV0IGludDE2QXJyYXlfZnJvbUFycmF5ID0gaW50MTZBcnJheVxuXG5sZXQgaW50MTZBcnJheV9mcm9tVHlwZWRBcnJheSA9IGludDE2QXJyYXlcblxubGV0IGludDE2QXJyYXlfZnJvbUJ1ZmZlciA9IGludDE2QXJyYXlcblxubGV0IGludDE2QXJyYXlfaW5CdWZmZXIgPSBpbnQxNkFycmF5XG5cbmxldCB1aW50MTZBcnJheSA9IEpzLlVuc2FmZS5nbG9iYWwjIy5fVWludDE2QXJyYXlcblxubGV0IHVpbnQxNkFycmF5X2Zyb21BcnJheSA9IHVpbnQxNkFycmF5XG5cbmxldCB1aW50MTZBcnJheV9mcm9tVHlwZWRBcnJheSA9IHVpbnQxNkFycmF5XG5cbmxldCB1aW50MTZBcnJheV9mcm9tQnVmZmVyID0gdWludDE2QXJyYXlcblxubGV0IHVpbnQxNkFycmF5X2luQnVmZmVyID0gdWludDE2QXJyYXlcblxubGV0IGludDMyQXJyYXkgPSBKcy5VbnNhZmUuZ2xvYmFsIyMuX0ludDMyQXJyYXlcblxubGV0IGludDMyQXJyYXlfZnJvbUFycmF5ID0gaW50MzJBcnJheVxuXG5sZXQgaW50MzJBcnJheV9mcm9tVHlwZWRBcnJheSA9IGludDMyQXJyYXlcblxubGV0IGludDMyQXJyYXlfZnJvbUJ1ZmZlciA9IGludDMyQXJyYXlcblxubGV0IGludDMyQXJyYXlfaW5CdWZmZXIgPSBpbnQzMkFycmF5XG5cbmxldCB1aW50MzJBcnJheSA9IEpzLlVuc2FmZS5nbG9iYWwjIy5fVWludDMyQXJyYXlcblxubGV0IHVpbnQzMkFycmF5X2Zyb21BcnJheSA9IHVpbnQzMkFycmF5XG5cbmxldCB1aW50MzJBcnJheV9mcm9tVHlwZWRBcnJheSA9IHVpbnQzMkFycmF5XG5cbmxldCB1aW50MzJBcnJheV9mcm9tQnVmZmVyID0gdWludDMyQXJyYXlcblxubGV0IHVpbnQzMkFycmF5X2luQnVmZmVyID0gdWludDMyQXJyYXlcblxubGV0IGZsb2F0MzJBcnJheSA9IEpzLlVuc2FmZS5nbG9iYWwjIy5fRmxvYXQzMkFycmF5XG5cbmxldCBmbG9hdDMyQXJyYXlfZnJvbUFycmF5ID0gZmxvYXQzMkFycmF5XG5cbmxldCBmbG9hdDMyQXJyYXlfZnJvbVR5cGVkQXJyYXkgPSBmbG9hdDMyQXJyYXlcblxubGV0IGZsb2F0MzJBcnJheV9mcm9tQnVmZmVyID0gZmxvYXQzMkFycmF5XG5cbmxldCBmbG9hdDMyQXJyYXlfaW5CdWZmZXIgPSBmbG9hdDMyQXJyYXlcblxubGV0IGZsb2F0NjRBcnJheSA9IEpzLlVuc2FmZS5nbG9iYWwjIy5fRmxvYXQ2NEFycmF5XG5cbmxldCBmbG9hdDY0QXJyYXlfZnJvbUFycmF5ID0gZmxvYXQ2NEFycmF5XG5cbmxldCBmbG9hdDY0QXJyYXlfZnJvbVR5cGVkQXJyYXkgPSBmbG9hdDY0QXJyYXlcblxubGV0IGZsb2F0NjRBcnJheV9mcm9tQnVmZmVyID0gZmxvYXQ2NEFycmF5XG5cbmxldCBmbG9hdDY0QXJyYXlfaW5CdWZmZXIgPSBmbG9hdDY0QXJyYXlcblxubGV0IHNldCA6ICgnYSwgJ2IpIHR5cGVkQXJyYXkgdCAtPiBpbnQgLT4gJ2EgLT4gdW5pdCA9XG4gZnVuIGEgaSB2IC0+IGFycmF5X3NldCAoVW5zYWZlLmNvZXJjZSBhKSBpIHZcblxubGV0IGdldCA6ICgnYSwgJ2IpIHR5cGVkQXJyYXkgdCAtPiBpbnQgLT4gJ2Egb3B0ZGVmID0gZnVuIGEgaSAtPiBKcy5VbnNhZmUuZ2V0IGEgaVxuXG5sZXQgdW5zYWZlX2dldCA6ICgnYSwgJ2IpIHR5cGVkQXJyYXkgdCAtPiBpbnQgLT4gJ2EgPSBmdW4gYSBpIC0+IEpzLlVuc2FmZS5nZXQgYSBpXG5cbmNsYXNzIHR5cGUgZGF0YVZpZXcgPSBvYmplY3RcbiAgaW5oZXJpdCBhcnJheUJ1ZmZlclZpZXdcblxuICBtZXRob2QgZ2V0SW50OCA6IGludCAtPiBpbnQgbWV0aFxuXG4gIG1ldGhvZCBnZXRVaW50OCA6IGludCAtPiBpbnQgbWV0aFxuXG4gIG1ldGhvZCBnZXRJbnQxNiA6IGludCAtPiBpbnQgbWV0aFxuXG4gIG1ldGhvZCBnZXRJbnQxNl8gOiBpbnQgLT4gYm9vbCB0IC0+IGludCBtZXRoXG5cbiAgbWV0aG9kIGdldFVpbnQxNiA6IGludCAtPiBpbnQgbWV0aFxuXG4gIG1ldGhvZCBnZXRVaW50MTZfIDogaW50IC0+IGJvb2wgdCAtPiBpbnQgbWV0aFxuXG4gIG1ldGhvZCBnZXRJbnQzMiA6IGludCAtPiBpbnQgbWV0aFxuXG4gIG1ldGhvZCBnZXRJbnQzMl8gOiBpbnQgLT4gYm9vbCB0IC0+IGludCBtZXRoXG5cbiAgbWV0aG9kIGdldFVpbnQzMiA6IGludCAtPiB1aW50MzIgbWV0aFxuXG4gIG1ldGhvZCBnZXRVaW50MzJfIDogaW50IC0+IGJvb2wgdCAtPiB1aW50MzIgbWV0aFxuXG4gIG1ldGhvZCBnZXRGbG9hdDMyIDogaW50IC0+IG51bWJlcl90IG1ldGhcblxuICBtZXRob2QgZ2V0RmxvYXQzMl8gOiBpbnQgLT4gYm9vbCB0IC0+IG51bWJlcl90IG1ldGhcblxuICBtZXRob2QgZ2V0RmxvYXQ2NCA6IGludCAtPiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIGdldEZsb2F0NjRfIDogaW50IC0+IGJvb2wgdCAtPiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIHNldEludDggOiBpbnQgLT4gaW50IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBzZXRVaW50OCA6IGludCAtPiBpbnQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHNldEludDE2IDogaW50IC0+IGludCAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgc2V0SW50MTZfIDogaW50IC0+IGludCAtPiBib29sIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHNldFVpbnQxNiA6IGludCAtPiBpbnQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHNldFVpbnQxNl8gOiBpbnQgLT4gaW50IC0+IGJvb2wgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgc2V0SW50MzIgOiBpbnQgLT4gaW50IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBzZXRJbnQzMl8gOiBpbnQgLT4gaW50IC0+IGJvb2wgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgc2V0VWludDMyIDogaW50IC0+IHVpbnQzMiAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgc2V0VWludDMyXyA6IGludCAtPiB1aW50MzIgLT4gYm9vbCB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBzZXRGbG9hdDMyIDogaW50IC0+IG51bWJlcl90IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBzZXRGbG9hdDMyXyA6IGludCAtPiBudW1iZXJfdCAtPiBib29sIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHNldEZsb2F0NjQgOiBpbnQgLT4gbnVtYmVyX3QgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHNldEZsb2F0NjRfIDogaW50IC0+IG51bWJlcl90IC0+IGJvb2wgdCAtPiB1bml0IG1ldGhcbmVuZFxuXG5sZXQgZGF0YVZpZXcgPSBKcy5VbnNhZmUuZ2xvYmFsIyMuX0RhdGFWaWV3XG5cbmxldCBkYXRhVmlld19pbkJ1ZmZlciA9IGRhdGFWaWV3XG5cbm1vZHVsZSBCaWdzdHJpbmcgPSBzdHJ1Y3RcbiAgdHlwZSB0ID0gKGNoYXIsIEJpZ2FycmF5LmludDhfdW5zaWduZWRfZWx0LCBCaWdhcnJheS5jX2xheW91dCkgQmlnYXJyYXkuQXJyYXkxLnRcblxuICBleHRlcm5hbCB0b19hcnJheUJ1ZmZlciA6IHQgLT4gYXJyYXlCdWZmZXIgSnMudCA9IFwiYmlnc3RyaW5nX3RvX2FycmF5X2J1ZmZlclwiXG5cbiAgZXh0ZXJuYWwgdG9fdWludDhBcnJheSA6IHQgLT4gdWludDhBcnJheSBKcy50ID0gXCJiaWdzdHJpbmdfdG9fdHlwZWRfYXJyYXlcIlxuXG4gIGV4dGVybmFsIG9mX2FycmF5QnVmZmVyIDogYXJyYXlCdWZmZXIgSnMudCAtPiB0ID0gXCJiaWdzdHJpbmdfb2ZfYXJyYXlfYnVmZmVyXCJcblxuICBleHRlcm5hbCBvZl91aW50OEFycmF5IDogdWludDhBcnJheSBKcy50IC0+IHQgPSBcImJpZ3N0cmluZ19vZl90eXBlZF9hcnJheVwiXG5lbmRcblxubW9kdWxlIFN0cmluZyA9IHN0cnVjdFxuICBleHRlcm5hbCBvZl91aW50OEFycmF5IDogdWludDhBcnJheSBKcy50IC0+IHN0cmluZyA9IFwiY2FtbF9zdHJpbmdfb2ZfYXJyYXlcIlxuXG4gIGxldCBvZl9hcnJheUJ1ZmZlciBhYiA9XG4gICAgbGV0IHVpbnQ4ID0gbmV3JWpzIHVpbnQ4QXJyYXlfZnJvbUJ1ZmZlciBhYiBpblxuICAgIG9mX3VpbnQ4QXJyYXkgdWludDhcbmVuZFxuXG5tb2R1bGUgQnl0ZXMgPSBzdHJ1Y3RcbiAgZXh0ZXJuYWwgb2ZfdWludDhBcnJheSA6IHVpbnQ4QXJyYXkgSnMudCAtPiBieXRlcyA9IFwiY2FtbF9ieXRlc19vZl9hcnJheVwiXG5cbiAgZXh0ZXJuYWwgdG9fdWludDhBcnJheSA6IGJ5dGVzIC0+IHVpbnQ4QXJyYXkgSnMudCA9IFwiY2FtbF91aW50OF9hcnJheV9vZl9ieXRlc1wiXG5cbiAgbGV0IG9mX2FycmF5QnVmZmVyIGFiID1cbiAgICBsZXQgdWludDggPSBuZXclanMgdWludDhBcnJheV9mcm9tQnVmZmVyIGFiIGluXG4gICAgb2ZfdWludDhBcnJheSB1aW50OFxuZW5kXG4iLCIoKiBKc19vZl9vY2FtbCBsaWJyYXJ5XG4gKiBodHRwOi8vd3d3Lm9jc2lnZW4ub3JnL2pzX29mX29jYW1sL1xuICogQ29weXJpZ2h0IChDKSAyMDExIFBpZXJyZSBDaGFtYmFydFxuICogTGFib3JhdG9pcmUgUFBTIC0gQ05SUyBVbml2ZXJzaXTDqSBQYXJpcyBEaWRlcm90XG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgd2l0aCBsaW5raW5nIGV4Y2VwdGlvbjtcbiAqIGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4gKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLlxuICopXG5cbm9wZW4gSnNcbm9wZW4gRG9tXG5vcGVuISBJbXBvcnRcblxuY2xhc3MgdHlwZSBibG9iID0gb2JqZWN0XG4gIG1ldGhvZCBzaXplIDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX3R5cGUgOiBqc19zdHJpbmcgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHNsaWNlIDogaW50IC0+IGludCAtPiBibG9iIHQgbWV0aFxuXG4gIG1ldGhvZCBzbGljZV93aXRoQ29udGVudFR5cGUgOiBpbnQgLT4gaW50IC0+IGpzX3N0cmluZyB0IC0+IGJsb2IgdCBtZXRoXG5lbmRcblxubGV0IGJsb2JfY29uc3RyID0gVW5zYWZlLmdsb2JhbCMjLl9CbG9iXG5cbnR5cGUgJ2EgbWFrZV9ibG9iID1cbiAgP2NvbnRlbnRUeXBlOnN0cmluZyAtPiA/ZW5kaW5nczpbIGBUcmFuc3BhcmVudCB8IGBOYXRpdmUgXSAtPiAnYSAtPiBibG9iIHRcblxubGV0IHJlYyBmaWx0ZXJfbWFwIGYgPSBmdW5jdGlvblxuICB8IFtdIC0+IFtdXG4gIHwgdiA6OiBxIC0+IChcbiAgICAgIG1hdGNoIGYgdiB3aXRoXG4gICAgICB8IE5vbmUgLT4gZmlsdGVyX21hcCBmIHFcbiAgICAgIHwgU29tZSB2JyAtPiB2JyA6OiBmaWx0ZXJfbWFwIGYgcSlcblxubGV0IG1ha2VfYmxvYl9vcHRpb25zIGNvbnRlbnRUeXBlIGVuZGluZ3MgPVxuICBsZXQgb3B0aW9ucyA9XG4gICAgZmlsdGVyX21hcFxuICAgICAgKGZ1biAobmFtZSwgdikgLT5cbiAgICAgICAgbWF0Y2ggdiB3aXRoXG4gICAgICAgIHwgTm9uZSAtPiBOb25lXG4gICAgICAgIHwgU29tZSB2IC0+IFNvbWUgKG5hbWUsIFVuc2FmZS5pbmplY3QgKHN0cmluZyB2KSkpXG4gICAgICBbIFwidHlwZVwiLCBjb250ZW50VHlwZVxuICAgICAgOyAoIFwiZW5kaW5nc1wiXG4gICAgICAgICwgbWF0Y2ggZW5kaW5ncyB3aXRoXG4gICAgICAgICAgfCBOb25lIC0+IE5vbmVcbiAgICAgICAgICB8IFNvbWUgYFRyYW5zcGFyZW50IC0+IFNvbWUgXCJ0cmFuc3BhcmVudFwiXG4gICAgICAgICAgfCBTb21lIGBOYXRpdmUgLT4gU29tZSBcIm5hdGl2ZVwiIClcbiAgICAgIF1cbiAgaW5cbiAgbWF0Y2ggb3B0aW9ucyB3aXRoXG4gIHwgW10gLT4gdW5kZWZpbmVkXG4gIHwgbCAtPiBVbnNhZmUub2JqIChBcnJheS5vZl9saXN0IGwpXG5cbmxldCBibG9iX3JhdyA/Y29udGVudFR5cGUgP2VuZGluZ3MgYSA9XG4gIGxldCBvcHRpb25zID0gbWFrZV9ibG9iX29wdGlvbnMgY29udGVudFR5cGUgZW5kaW5ncyBpblxuICBuZXclanMgYmxvYl9jb25zdHIgKGFycmF5IGEpIG9wdGlvbnNcblxubGV0IGJsb2JfZnJvbV9zdHJpbmcgP2NvbnRlbnRUeXBlID9lbmRpbmdzIHMgPVxuICBibG9iX3JhdyA/Y29udGVudFR5cGUgP2VuZGluZ3MgW3wgc3RyaW5nIHMgfF1cblxubGV0IGJsb2JfZnJvbV9hbnkgP2NvbnRlbnRUeXBlID9lbmRpbmdzIGwgPVxuICBsZXQgbCA9XG4gICAgTGlzdC5tYXBcbiAgICAgIChmdW5jdGlvblxuICAgICAgICB8IGBhcnJheUJ1ZmZlciBhIC0+IFVuc2FmZS5pbmplY3QgYVxuICAgICAgICB8IGBhcnJheUJ1ZmZlclZpZXcgYSAtPiBVbnNhZmUuaW5qZWN0IGFcbiAgICAgICAgfCBgc3RyaW5nIHMgLT4gVW5zYWZlLmluamVjdCAoc3RyaW5nIHMpXG4gICAgICAgIHwgYGpzX3N0cmluZyBzIC0+IFVuc2FmZS5pbmplY3Qgc1xuICAgICAgICB8IGBibG9iIGIgLT4gVW5zYWZlLmluamVjdCBiKVxuICAgICAgbFxuICBpblxuICBibG9iX3JhdyA/Y29udGVudFR5cGUgP2VuZGluZ3MgKEFycmF5Lm9mX2xpc3QgbClcblxuY2xhc3MgdHlwZSBmaWxlID0gb2JqZWN0XG4gIGluaGVyaXQgYmxvYlxuXG4gIG1ldGhvZCBuYW1lIDoganNfc3RyaW5nIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBsYXN0TW9kaWZpZWREYXRlIDoganNfc3RyaW5nIHQgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbigqIGluIGZpcmVmb3ggMy4wLTMuNSBmaWxlLm5hbWUgaXMgbm90IGF2YWlsYWJsZSwgd2UgdXNlIHRoZSBub25zdGFuZGFyZCBmaWxlTmFtZSBpbnN0ZWFkICopXG5jbGFzcyB0eXBlIGZpbGVfbmFtZV9vbmx5ID0gb2JqZWN0XG4gIG1ldGhvZCBuYW1lIDoganNfc3RyaW5nIHQgb3B0ZGVmIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZmlsZU5hbWUgOiBqc19zdHJpbmcgdCBvcHRkZWYgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbmxldCBmaWxlbmFtZSBmaWxlID1cbiAgbGV0IGZpbGUgOiBmaWxlX25hbWVfb25seSB0ID0gSnMuVW5zYWZlLmNvZXJjZSBmaWxlIGluXG4gIG1hdGNoIE9wdGRlZi50b19vcHRpb24gZmlsZSMjLm5hbWUgd2l0aFxuICB8IE5vbmUgLT4gKFxuICAgICAgbWF0Y2ggT3B0ZGVmLnRvX29wdGlvbiBmaWxlIyMuZmlsZU5hbWUgd2l0aFxuICAgICAgfCBOb25lIC0+IGZhaWx3aXRoIFwiY2FuJ3QgcmV0cmlldmUgZmlsZSBuYW1lOiBub3QgaW1wbGVtZW50ZWRcIlxuICAgICAgfCBTb21lIG5hbWUgLT4gbmFtZSlcbiAgfCBTb21lIG5hbWUgLT4gbmFtZVxuXG50eXBlIGZpbGVfYW55ID0gPCA+IHRcblxubGV0IGRvY19jb25zdHIgPSBVbnNhZmUuZ2xvYmFsIyMuX0RvY3VtZW50XG5cbm1vZHVsZSBDb2VyY2VUbyA9IHN0cnVjdFxuICBleHRlcm5hbCBqc29uIDogZmlsZV9hbnkgLT4gJ2EgT3B0LnQgPSBcIiVpZGVudGl0eVwiXG5cbiAgbGV0IGRvY3VtZW50IChlIDogZmlsZV9hbnkpID1cbiAgICBpZiBpbnN0YW5jZW9mIGUgZG9jX2NvbnN0clxuICAgIHRoZW4gSnMuc29tZSAoVW5zYWZlLmNvZXJjZSBlIDogZWxlbWVudCBkb2N1bWVudCB0KVxuICAgIGVsc2UgSnMubnVsbFxuXG4gIGxldCBibG9iIChlIDogZmlsZV9hbnkpID1cbiAgICBpZiBpbnN0YW5jZW9mIGUgYmxvYl9jb25zdHIgdGhlbiBKcy5zb21lIChVbnNhZmUuY29lcmNlIGUgOiAjYmxvYiB0KSBlbHNlIEpzLm51bGxcblxuICBsZXQgc3RyaW5nIChlIDogZmlsZV9hbnkpID1cbiAgICBpZiBKcy5lcXVhbHMgKHR5cGVvZiBlKSAoc3RyaW5nIFwic3RyaW5nXCIpXG4gICAgdGhlbiBKcy5zb21lIChVbnNhZmUuY29lcmNlIGUgOiBqc19zdHJpbmcgdClcbiAgICBlbHNlIEpzLm51bGxcblxuICBsZXQgYXJyYXlCdWZmZXIgKGUgOiBmaWxlX2FueSkgPVxuICAgIGlmIGluc3RhbmNlb2YgZSBUeXBlZF9hcnJheS5hcnJheUJ1ZmZlclxuICAgIHRoZW4gSnMuc29tZSAoVW5zYWZlLmNvZXJjZSBlIDogVHlwZWRfYXJyYXkuYXJyYXlCdWZmZXIgdClcbiAgICBlbHNlIEpzLm51bGxcbmVuZFxuXG5jbGFzcyB0eXBlIGZpbGVMaXN0ID0gb2JqZWN0XG4gIGluaGVyaXQgW2ZpbGVdIERvbS5ub2RlTGlzdFxuZW5kXG5cbmNsYXNzIHR5cGUgZmlsZUVycm9yID0gb2JqZWN0XG4gIG1ldGhvZCBjb2RlIDogaW50IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG5jbGFzcyB0eXBlIFsnYV0gcHJvZ3Jlc3NFdmVudCA9IG9iamVjdFxuICBpbmhlcml0IFsnYV0gZXZlbnRcblxuICBtZXRob2QgbGVuZ3RoQ29tcHV0YWJsZSA6IGJvb2wgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGxvYWRlZCA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHRvdGFsIDogaW50IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG5jbGFzcyB0eXBlIHByb2dyZXNzRXZlbnRUYXJnZXQgPSBvYmplY3QgKCdzZWxmKVxuICBtZXRob2Qgb25sb2Fkc3RhcnQgOiAoJ3NlbGYgdCwgJ3NlbGYgcHJvZ3Jlc3NFdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbnByb2dyZXNzIDogKCdzZWxmIHQsICdzZWxmIHByb2dyZXNzRXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgd3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2Qgb25sb2FkIDogKCdzZWxmIHQsICdzZWxmIHByb2dyZXNzRXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgd3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2Qgb25hYm9ydCA6ICgnc2VsZiB0LCAnc2VsZiBwcm9ncmVzc0V2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9uZXJyb3IgOiAoJ3NlbGYgdCwgJ3NlbGYgcHJvZ3Jlc3NFdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbmxvYWRlbmQgOiAoJ3NlbGYgdCwgJ3NlbGYgcHJvZ3Jlc3NFdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuZW5kXG5cbnR5cGUgcmVhZHlTdGF0ZSA9XG4gIHwgRU1QVFlcbiAgfCBMT0FESU5HXG4gIHwgRE9ORVxuXG5jbGFzcyB0eXBlIGZpbGVSZWFkZXIgPSBvYmplY3QgKCdzZWxmKVxuICBtZXRob2QgcmVhZEFzQXJyYXlCdWZmZXIgOiAjYmxvYiB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCByZWFkQXNCaW5hcnlTdHJpbmcgOiAjYmxvYiB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCByZWFkQXNUZXh0IDogI2Jsb2IgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgcmVhZEFzVGV4dF93aXRoRW5jb2RpbmcgOiAjYmxvYiB0IC0+IGpzX3N0cmluZyB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCByZWFkQXNEYXRhVVJMIDogI2Jsb2IgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgYWJvcnQgOiB1bml0IG1ldGhcblxuICBtZXRob2QgcmVhZHlTdGF0ZSA6IHJlYWR5U3RhdGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCByZXN1bHQgOiBmaWxlX2FueSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGVycm9yIDogZmlsZUVycm9yIHQgcmVhZG9ubHlfcHJvcFxuXG4gIGluaGVyaXQgcHJvZ3Jlc3NFdmVudFRhcmdldFxuZW5kXG5cbm1vZHVsZSBSZWFkZXJFdmVudCA9IHN0cnVjdFxuICB0eXBlIHR5cCA9IGZpbGVSZWFkZXIgcHJvZ3Jlc3NFdmVudCB0IERvbS5FdmVudC50eXBcblxuICBsZXQgbG9hZHN0YXJ0ID0gRXZlbnQubWFrZSBcImxvYWRzdGFydFwiXG5cbiAgbGV0IHByb2dyZXNzID0gRXZlbnQubWFrZSBcInByb2dyZXNzXCJcblxuICBsZXQgYWJvcnQgPSBFdmVudC5tYWtlIFwiYWJvcnRcIlxuXG4gIGxldCBlcnJvciA9IEV2ZW50Lm1ha2UgXCJlcnJvclwiXG5cbiAgbGV0IGxvYWQgPSBFdmVudC5tYWtlIFwibG9hZFwiXG5cbiAgbGV0IGxvYWRlbmQgPSBFdmVudC5tYWtlIFwibG9hZGVuZFwiXG5lbmRcblxubGV0IGZpbGVSZWFkZXIgOiBmaWxlUmVhZGVyIHQgY29uc3RyID0gSnMuVW5zYWZlLmdsb2JhbCMjLl9GaWxlUmVhZGVyXG5cbmxldCBhZGRFdmVudExpc3RlbmVyID0gRG9tLmFkZEV2ZW50TGlzdGVuZXJcbiIsIigqIEpzX29mX29jYW1sIGxpYnJhcnlcbiAqIGh0dHA6Ly93d3cub2NzaWdlbi5vcmcvanNfb2Zfb2NhbWwvXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTAgSsOpcsO0bWUgVm91aWxsb25cbiAqIExhYm9yYXRvaXJlIFBQUyAtIENOUlMgVW5pdmVyc2l0w6kgUGFyaXMgRGlkZXJvdFxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHdpdGggbGlua2luZyBleGNlcHRpb247XG4gKiBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcsIFVTQS5cbiAqKVxuXG5vcGVuIEpzXG5vcGVuISBJbXBvcnRcblxuZXh0ZXJuYWwgY2FtbF9qc19vbl9pZSA6IHVuaXQgLT4gYm9vbCB0ID0gXCJjYW1sX2pzX29uX2llXCJcblxubGV0IG9uSUUgPSBKcy50b19ib29sIChjYW1sX2pzX29uX2llICgpKVxuXG5leHRlcm5hbCBodG1sX2VzY2FwZSA6IGpzX3N0cmluZyB0IC0+IGpzX3N0cmluZyB0ID0gXCJjYW1sX2pzX2h0bWxfZXNjYXBlXCJcblxuZXh0ZXJuYWwgZGVjb2RlX2h0bWxfZW50aXRpZXMgOiBqc19zdHJpbmcgdCAtPiBqc19zdHJpbmcgdCA9IFwiY2FtbF9qc19odG1sX2VudGl0aWVzXCJcblxuY2xhc3MgdHlwZSBjc3NTdHlsZURlY2xhcmF0aW9uID0gb2JqZWN0XG4gIG1ldGhvZCBzZXRQcm9wZXJ0eSA6XG4gICAganNfc3RyaW5nIHQgLT4ganNfc3RyaW5nIHQgLT4ganNfc3RyaW5nIHQgb3B0ZGVmIC0+IGpzX3N0cmluZyB0IG1ldGhcblxuICBtZXRob2QgZ2V0UHJvcGVydHlWYWx1ZSA6IGpzX3N0cmluZyB0IC0+IGpzX3N0cmluZyB0IG1ldGhcblxuICBtZXRob2QgZ2V0UHJvcGVydHlQcmlvcml0eSA6IGpzX3N0cmluZyB0IC0+IGpzX3N0cmluZyB0IG1ldGhcblxuICBtZXRob2QgcmVtb3ZlUHJvcGVydHkgOiBqc19zdHJpbmcgdCAtPiBqc19zdHJpbmcgdCBtZXRoXG5cbiAgbWV0aG9kIGFuaW1hdGlvbiA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgYW5pbWF0aW9uRGVsYXkgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGFuaW1hdGlvbkRpcmVjdGlvbiA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgYW5pbWF0aW9uRHVyYXRpb24gOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGFuaW1hdGlvbkZpbGxNb2RlIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBhbmltYXRpb25JdGVyYXRpb25Db3VudCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgYW5pbWF0aW9uTmFtZSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgYW5pbWF0aW9uUGxheVN0YXRlIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBhbmltYXRpb25UaW1pbmdGdW5jdGlvbiA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgYmFja2dyb3VuZCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgYmFja2dyb3VuZEF0dGFjaG1lbnQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGJhY2tncm91bmRDb2xvciA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgYmFja2dyb3VuZEltYWdlIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBiYWNrZ3JvdW5kUG9zaXRpb24gOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGJhY2tncm91bmRSZXBlYXQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGJvcmRlciA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgYm9yZGVyQm90dG9tIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBib3JkZXJCb3R0b21Db2xvciA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgYm9yZGVyQm90dG9tU3R5bGUgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGJvcmRlckJvdHRvbVdpZHRoIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBib3JkZXJDb2xsYXBzZSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgYm9yZGVyQ29sb3IgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGJvcmRlckxlZnQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGJvcmRlckxlZnRDb2xvciA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgYm9yZGVyTGVmdFN0eWxlIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBib3JkZXJMZWZ0V2lkdGggOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGJvcmRlclJhZGl1cyA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgYm9yZGVyUmlnaHQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGJvcmRlclJpZ2h0Q29sb3IgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGJvcmRlclJpZ2h0U3R5bGUgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGJvcmRlclJpZ2h0V2lkdGggOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGJvcmRlclNwYWNpbmcgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGJvcmRlclN0eWxlIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBib3JkZXJUb3AgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGJvcmRlclRvcENvbG9yIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBib3JkZXJUb3BTdHlsZSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgYm9yZGVyVG9wV2lkdGggOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGJvcmRlcldpZHRoIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBib3R0b20gOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGNhcHRpb25TaWRlIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBjbGVhciA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgY2xpcCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgY29sb3IgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGNvbnRlbnQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGNvdW50ZXJJbmNyZW1lbnQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGNvdW50ZXJSZXNldCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgY3NzRmxvYXQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGNzc1RleHQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGN1cnNvciA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgZGlyZWN0aW9uIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBkaXNwbGF5IDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBlbXB0eUNlbGxzIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBmaWxsIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBmb250IDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBmb250RmFtaWx5IDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBmb250U2l6ZSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgZm9udFN0eWxlIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBmb250VmFyaWFudCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgZm9udFdlaWdodCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgaGVpZ2h0IDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBsZWZ0IDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBsZXR0ZXJTcGFjaW5nIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBsaW5lSGVpZ2h0IDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBsaXN0U3R5bGUgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGxpc3RTdHlsZUltYWdlIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBsaXN0U3R5bGVQb3NpdGlvbiA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgbGlzdFN0eWxlVHlwZSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgbWFyZ2luIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBtYXJnaW5Cb3R0b20gOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIG1hcmdpbkxlZnQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIG1hcmdpblJpZ2h0IDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBtYXJnaW5Ub3AgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIG1heEhlaWdodCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgbWF4V2lkdGggOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIG1pbkhlaWdodCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgbWluV2lkdGggOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIG9wYWNpdHkgOiBqc19zdHJpbmcgdCBvcHRkZWYgcHJvcFxuXG4gIG1ldGhvZCBvdXRsaW5lIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBvdXRsaW5lQ29sb3IgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIG91dGxpbmVPZmZzZXQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIG91dGxpbmVTdHlsZSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2Qgb3V0bGluZVdpZHRoIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBvdmVyZmxvdyA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2Qgb3ZlcmZsb3dYIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBvdmVyZmxvd1kgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHBhZGRpbmcgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHBhZGRpbmdCb3R0b20gOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHBhZGRpbmdMZWZ0IDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBwYWRkaW5nUmlnaHQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHBhZGRpbmdUb3AgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHBhZ2VCcmVha0FmdGVyIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBwYWdlQnJlYWtCZWZvcmUgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHBvaW50ZXJFdmVudHMgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHBvc2l0aW9uIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCByaWdodCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2Qgc3Ryb2tlIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBzdHJva2VXaWR0aCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgdGFibGVMYXlvdXQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHRleHRBbGlnbiA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgdGV4dEFuY2hvciA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgdGV4dERlY29yYXRpb24gOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHRleHRJbmRlbnQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHRleHRUcmFuc2Zvcm0gOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHRvcCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgdHJhbnNmb3JtIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCB2ZXJ0aWNhbEFsaWduIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCB2aXNpYmlsaXR5IDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCB3aGl0ZVNwYWNlIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCB3aWR0aCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2Qgd29yZFNwYWNpbmcgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHpJbmRleCA6IGpzX3N0cmluZyB0IHByb3BcbmVuZFxuXG50eXBlICgnYSwgJ2IpIGV2ZW50X2xpc3RlbmVyID0gKCdhLCAnYikgRG9tLmV2ZW50X2xpc3RlbmVyXG5cbnR5cGUgbW91c2VfYnV0dG9uID1cbiAgfCBOb19idXR0b25cbiAgfCBMZWZ0X2J1dHRvblxuICB8IE1pZGRsZV9idXR0b25cbiAgfCBSaWdodF9idXR0b25cblxudHlwZSBkZWx0YV9tb2RlID1cbiAgfCBEZWx0YV9waXhlbFxuICB8IERlbHRhX2xpbmVcbiAgfCBEZWx0YV9wYWdlXG5cbmNsYXNzIHR5cGUgZXZlbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBbZWxlbWVudF0gRG9tLmV2ZW50XG5lbmRcblxuYW5kIFsnYV0gY3VzdG9tRXZlbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBbZWxlbWVudCwgJ2FdIERvbS5jdXN0b21FdmVudFxuZW5kXG5cbmFuZCBmb2N1c0V2ZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZXZlbnRcblxuICBtZXRob2QgcmVsYXRlZFRhcmdldCA6IGVsZW1lbnQgdCBvcHQgb3B0ZGVmIHJlYWRvbmx5X3Byb3BcbmVuZFxuXG5hbmQgbW91c2VFdmVudCA9IG9iamVjdFxuICBpbmhlcml0IGV2ZW50XG5cbiAgbWV0aG9kIHJlbGF0ZWRUYXJnZXQgOiBlbGVtZW50IHQgb3B0IG9wdGRlZiByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGNsaWVudFggOiBpbnQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBjbGllbnRZIDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgc2NyZWVuWCA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHNjcmVlblkgOiBpbnQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvZmZzZXRYIDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgb2Zmc2V0WSA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGN0cmxLZXkgOiBib29sIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBzaGlmdEtleSA6IGJvb2wgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGFsdEtleSA6IGJvb2wgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIG1ldGFLZXkgOiBib29sIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBidXR0b24gOiBpbnQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCB3aGljaCA6IG1vdXNlX2J1dHRvbiBvcHRkZWYgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBmcm9tRWxlbWVudCA6IGVsZW1lbnQgdCBvcHQgb3B0ZGVmIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgdG9FbGVtZW50IDogZWxlbWVudCB0IG9wdCBvcHRkZWYgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBwYWdlWCA6IGludCBvcHRkZWYgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBwYWdlWSA6IGludCBvcHRkZWYgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbmFuZCBrZXlib2FyZEV2ZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZXZlbnRcblxuICBtZXRob2QgYWx0S2V5IDogYm9vbCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgc2hpZnRLZXkgOiBib29sIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBjdHJsS2V5IDogYm9vbCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgbWV0YUtleSA6IGJvb2wgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGxvY2F0aW9uIDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qga2V5IDoganNfc3RyaW5nIHQgb3B0ZGVmIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgY29kZSA6IGpzX3N0cmluZyB0IG9wdGRlZiByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHdoaWNoIDogaW50IG9wdGRlZiByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGNoYXJDb2RlIDogaW50IG9wdGRlZiByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGtleUNvZGUgOiBpbnQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBnZXRNb2RpZmllclN0YXRlIDoganNfc3RyaW5nIHQgLT4gYm9vbCB0IG1ldGhcblxuICBtZXRob2Qga2V5SWRlbnRpZmllciA6IGpzX3N0cmluZyB0IG9wdGRlZiByZWFkb25seV9wcm9wXG5lbmRcblxuYW5kIG1vdXNld2hlZWxFdmVudCA9IG9iamVjdFxuICAoKiBBbGwgbW9kZXJuIGJyb3dzZXJzICopXG4gIGluaGVyaXQgbW91c2VFdmVudFxuXG4gIG1ldGhvZCB3aGVlbERlbHRhIDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgd2hlZWxEZWx0YVggOiBpbnQgb3B0ZGVmIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgd2hlZWxEZWx0YVkgOiBpbnQgb3B0ZGVmIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZGVsdGFYIDogbnVtYmVyX3QgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBkZWx0YVkgOiBudW1iZXJfdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGRlbHRhWiA6IG51bWJlcl90IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZGVsdGFNb2RlIDogZGVsdGFfbW9kZSByZWFkb25seV9wcm9wXG5lbmRcblxuYW5kIG1vdXNlU2Nyb2xsRXZlbnQgPSBvYmplY3RcbiAgKCogRmlyZWZveCAqKVxuICBpbmhlcml0IG1vdXNlRXZlbnRcblxuICBtZXRob2QgZGV0YWlsIDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgYXhpcyA6IGludCBvcHRkZWYgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfSE9SSVpPTlRBTF9BWElTIDogaW50IG9wdGRlZiByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9WRVJUSUNBTF9BWElTIDogaW50IG9wdGRlZiByZWFkb25seV9wcm9wXG5lbmRcblxuYW5kIHRvdWNoRXZlbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBldmVudFxuXG4gIG1ldGhvZCB0b3VjaGVzIDogdG91Y2hMaXN0IHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCB0YXJnZXRUb3VjaGVzIDogdG91Y2hMaXN0IHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBjaGFuZ2VkVG91Y2hlcyA6IHRvdWNoTGlzdCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgY3RybEtleSA6IGJvb2wgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHNoaWZ0S2V5IDogYm9vbCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgYWx0S2V5IDogYm9vbCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgbWV0YUtleSA6IGJvb2wgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHJlbGF0ZWRUYXJnZXQgOiBlbGVtZW50IHQgb3B0IG9wdGRlZiByZWFkb25seV9wcm9wXG5lbmRcblxuYW5kIHRvdWNoTGlzdCA9IG9iamVjdFxuICBtZXRob2QgbGVuZ3RoIDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgaXRlbSA6IGludCAtPiB0b3VjaCB0IG9wdGRlZiBtZXRoXG5lbmRcblxuYW5kIHRvdWNoID0gb2JqZWN0XG4gIG1ldGhvZCBpZGVudGlmaWVyIDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgdGFyZ2V0IDogZWxlbWVudCB0IG9wdGRlZiByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHNjcmVlblggOiBpbnQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBzY3JlZW5ZIDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgY2xpZW50WCA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGNsaWVudFkgOiBpbnQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBwYWdlWCA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHBhZ2VZIDogaW50IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG5hbmQgc3VibWl0RXZlbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBldmVudFxuXG4gIG1ldGhvZCBzdWJtaXR0ZXIgOiBlbGVtZW50IHQgb3B0ZGVmIHJlYWRvbmx5X3Byb3BcbmVuZFxuXG5hbmQgZHJhZ0V2ZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgbW91c2VFdmVudFxuXG4gIG1ldGhvZCBkYXRhVHJhbnNmZXIgOiBkYXRhVHJhbnNmZXIgdCByZWFkb25seV9wcm9wXG5lbmRcblxuYW5kIGNsaXBib2FyZEV2ZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZXZlbnRcblxuICBtZXRob2QgY2xpcGJvYXJkRGF0YSA6IGRhdGFUcmFuc2ZlciB0IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG5hbmQgZGF0YVRyYW5zZmVyID0gb2JqZWN0XG4gIG1ldGhvZCBkcm9wRWZmZWN0IDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBlZmZlY3RBbGxvd2VkIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBmaWxlcyA6IEZpbGUuZmlsZUxpc3QgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHR5cGVzIDoganNfc3RyaW5nIHQganNfYXJyYXkgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGFkZEVsZW1lbnQgOiBlbGVtZW50IHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGNsZWFyRGF0YSA6IGpzX3N0cmluZyB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBjbGVhckRhdGFfYWxsIDogdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGdldERhdGEgOiBqc19zdHJpbmcgdCAtPiBqc19zdHJpbmcgdCBtZXRoXG5cbiAgbWV0aG9kIHNldERhdGEgOiBqc19zdHJpbmcgdCAtPiBqc19zdHJpbmcgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgc2V0RHJhZ0ltYWdlIDogZWxlbWVudCB0IC0+IGludCAtPiBpbnQgLT4gdW5pdCBtZXRoXG5lbmRcblxuYW5kIGV2ZW50VGFyZ2V0ID0gb2JqZWN0ICgnc2VsZilcbiAgbWV0aG9kIG9uY2xpY2sgOiAoJ3NlbGYgdCwgbW91c2VFdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbmRibGNsaWNrIDogKCdzZWxmIHQsIG1vdXNlRXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgd3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2Qgb25tb3VzZWRvd24gOiAoJ3NlbGYgdCwgbW91c2VFdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbm1vdXNldXAgOiAoJ3NlbGYgdCwgbW91c2VFdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbm1vdXNlb3ZlciA6ICgnc2VsZiB0LCBtb3VzZUV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9ubW91c2Vtb3ZlIDogKCdzZWxmIHQsIG1vdXNlRXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgd3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2Qgb25tb3VzZW91dCA6ICgnc2VsZiB0LCBtb3VzZUV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9ua2V5cHJlc3MgOiAoJ3NlbGYgdCwga2V5Ym9hcmRFdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbmtleWRvd24gOiAoJ3NlbGYgdCwga2V5Ym9hcmRFdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbmtleXVwIDogKCdzZWxmIHQsIGtleWJvYXJkRXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgd3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2Qgb25zY3JvbGwgOiAoJ3NlbGYgdCwgZXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgd3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2Qgb253aGVlbCA6ICgnc2VsZiB0LCBtb3VzZXdoZWVsRXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgd3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2Qgb25kcmFnc3RhcnQgOiAoJ3NlbGYgdCwgZHJhZ0V2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9uZHJhZ2VuZCA6ICgnc2VsZiB0LCBkcmFnRXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgd3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2Qgb25kcmFnZW50ZXIgOiAoJ3NlbGYgdCwgZHJhZ0V2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9uZHJhZ292ZXIgOiAoJ3NlbGYgdCwgZHJhZ0V2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9uZHJhZ2xlYXZlIDogKCdzZWxmIHQsIGRyYWdFdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbmRyYWcgOiAoJ3NlbGYgdCwgZHJhZ0V2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9uZHJvcCA6ICgnc2VsZiB0LCBkcmFnRXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgd3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2Qgb25hbmltYXRpb25zdGFydCA6ICgnc2VsZiB0LCBhbmltYXRpb25FdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbmFuaW1hdGlvbmVuZCA6ICgnc2VsZiB0LCBhbmltYXRpb25FdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbmFuaW1hdGlvbml0ZXJhdGlvbiA6ICgnc2VsZiB0LCBhbmltYXRpb25FdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbmFuaW1hdGlvbmNhbmNlbCA6ICgnc2VsZiB0LCBhbmltYXRpb25FdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbnRyYW5zaXRpb25ydW4gOiAoJ3NlbGYgdCwgdHJhbnNpdGlvbkV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9udHJhbnNpdGlvbnN0YXJ0IDogKCdzZWxmIHQsIHRyYW5zaXRpb25FdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbnRyYW5zaXRpb25lbmQgOiAoJ3NlbGYgdCwgdHJhbnNpdGlvbkV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9udHJhbnNpdGlvbmNhbmNlbCA6ICgnc2VsZiB0LCB0cmFuc2l0aW9uRXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgd3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2Qgb25nb3Rwb2ludGVyY2FwdHVyZSA6ICgnc2VsZiB0LCBwb2ludGVyRXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgd3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2Qgb25sb3N0cG9pbnRlcmNhcHR1cmUgOiAoJ3NlbGYgdCwgcG9pbnRlckV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9ucG9pbnRlcmVudGVyIDogKCdzZWxmIHQsIHBvaW50ZXJFdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbnBvaW50ZXJjYW5jZWwgOiAoJ3NlbGYgdCwgcG9pbnRlckV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9ucG9pbnRlcmRvd24gOiAoJ3NlbGYgdCwgcG9pbnRlckV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9ucG9pbnRlcmxlYXZlIDogKCdzZWxmIHQsIHBvaW50ZXJFdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbnBvaW50ZXJtb3ZlIDogKCdzZWxmIHQsIHBvaW50ZXJFdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbnBvaW50ZXJvdXQgOiAoJ3NlbGYgdCwgcG9pbnRlckV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9ucG9pbnRlcm92ZXIgOiAoJ3NlbGYgdCwgcG9pbnRlckV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9ucG9pbnRlcnVwIDogKCdzZWxmIHQsIHBvaW50ZXJFdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBkaXNwYXRjaEV2ZW50IDogZXZlbnQgdCAtPiBib29sIHQgbWV0aFxuZW5kXG5cbmFuZCBwb3BTdGF0ZUV2ZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZXZlbnRcblxuICBtZXRob2Qgc3RhdGUgOiBKcy5VbnNhZmUuYW55IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG5hbmQgcG9pbnRlckV2ZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgbW91c2VFdmVudFxuXG4gIG1ldGhvZCBwb2ludGVySWQgOiBpbnQgSnMucmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCB3aWR0aCA6IG51bWJlcl90IEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgaGVpZ2h0IDogbnVtYmVyX3QgSnMucmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBwcmVzc3VyZSA6IG51bWJlcl90IEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgdGFuZ2VudGlhbFByZXNzdXJlIDogbnVtYmVyX3QgSnMucmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCB0aWx0WCA6IGludCBKcy5yZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHRpbHRZIDogaW50IEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgdHdpc3QgOiBpbnQgSnMucmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBwb2ludGVyVHlwZSA6IEpzLmpzX3N0cmluZyBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgaXNQcmltYXJ5IDogYm9vbCBKcy50IEpzLnJlYWRvbmx5X3Byb3BcbmVuZFxuXG5hbmQgc3RvcmFnZUV2ZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZXZlbnRcblxuICBtZXRob2Qga2V5IDoganNfc3RyaW5nIHQgb3B0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgb2xkVmFsdWUgOiBqc19zdHJpbmcgdCBvcHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBuZXdWYWx1ZSA6IGpzX3N0cmluZyB0IG9wdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHVybCA6IGpzX3N0cmluZyB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgc3RvcmFnZUFyZWEgOiBzdG9yYWdlIHQgb3B0IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG5hbmQgc3RvcmFnZSA9IG9iamVjdFxuICBtZXRob2QgbGVuZ3RoIDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qga2V5IDogaW50IC0+IGpzX3N0cmluZyB0IG9wdCBtZXRoXG5cbiAgbWV0aG9kIGdldEl0ZW0gOiBqc19zdHJpbmcgdCAtPiBqc19zdHJpbmcgdCBvcHQgbWV0aFxuXG4gIG1ldGhvZCBzZXRJdGVtIDoganNfc3RyaW5nIHQgLT4ganNfc3RyaW5nIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHJlbW92ZUl0ZW0gOiBqc19zdHJpbmcgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgY2xlYXIgOiB1bml0IG1ldGhcbmVuZFxuXG5hbmQgaGFzaENoYW5nZUV2ZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZXZlbnRcblxuICBtZXRob2Qgb2xkVVJMIDoganNfc3RyaW5nIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBuZXdVUkwgOiBqc19zdHJpbmcgdCByZWFkb25seV9wcm9wXG5lbmRcblxuYW5kIGFuaW1hdGlvbkV2ZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZXZlbnRcblxuICBtZXRob2QgYW5pbWF0aW9uTmFtZSA6IGpzX3N0cmluZyB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZWxhcHNlZFRpbWUgOiBudW1iZXJfdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHBzZXVkb0VsZW1lbnQgOiBqc19zdHJpbmcgdCByZWFkb25seV9wcm9wXG5lbmRcblxuYW5kIHRyYW5zaXRpb25FdmVudCA9IG9iamVjdFxuICBpbmhlcml0IGV2ZW50XG5cbiAgbWV0aG9kIHByb3BlcnR5TmFtZSA6IGpzX3N0cmluZyB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZWxhcHNlZFRpbWUgOiBudW1iZXJfdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHBzZXVkb0VsZW1lbnQgOiBqc19zdHJpbmcgdCByZWFkb25seV9wcm9wXG5lbmRcblxuYW5kIG1lZGlhRXZlbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBldmVudFxuZW5kXG5cbmFuZCBtZXNzYWdlRXZlbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBldmVudFxuXG4gIG1ldGhvZCBkYXRhIDogVW5zYWZlLmFueSBvcHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBzb3VyY2UgOiBVbnNhZmUuYW55IG9wdCByZWFkb25seV9wcm9wXG5lbmRcblxuYW5kIG5vZGVTZWxlY3RvciA9IG9iamVjdFxuICBtZXRob2QgcXVlcnlTZWxlY3RvciA6IGpzX3N0cmluZyB0IC0+IGVsZW1lbnQgdCBvcHQgbWV0aFxuXG4gIG1ldGhvZCBxdWVyeVNlbGVjdG9yQWxsIDoganNfc3RyaW5nIHQgLT4gZWxlbWVudCBEb20ubm9kZUxpc3QgdCBtZXRoXG5lbmRcblxuYW5kIHRva2VuTGlzdCA9IG9iamVjdFxuICBtZXRob2QgbGVuZ3RoIDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgaXRlbSA6IGludCAtPiBqc19zdHJpbmcgdCBvcHRkZWYgbWV0aFxuXG4gIG1ldGhvZCBjb250YWlucyA6IGpzX3N0cmluZyB0IC0+IGJvb2wgdCBtZXRoXG5cbiAgbWV0aG9kIGFkZCA6IGpzX3N0cmluZyB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCByZW1vdmUgOiBqc19zdHJpbmcgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdG9nZ2xlIDoganNfc3RyaW5nIHQgLT4gYm9vbCB0IG1ldGhcblxuICBtZXRob2Qgc3RyaW5naWZpZXIgOiBqc19zdHJpbmcgdCBwcm9wXG5lbmRcblxuYW5kIGVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBEb20uZWxlbWVudFxuXG4gIGluaGVyaXQgbm9kZVNlbGVjdG9yXG5cbiAgbWV0aG9kIGlkIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCB0aXRsZSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgbGFuZyA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgZGlyIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBjbGFzc05hbWUgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGNsYXNzTGlzdCA6IHRva2VuTGlzdCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgY2xvc2VzdCA6IGpzX3N0cmluZyB0IC0+IGVsZW1lbnQgdCBvcHQgbWV0aFxuXG4gIG1ldGhvZCBzdHlsZSA6IGNzc1N0eWxlRGVjbGFyYXRpb24gdCBwcm9wXG5cbiAgbWV0aG9kIGlubmVySFRNTCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2Qgb3V0ZXJIVE1MIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCB0ZXh0Q29udGVudCA6IGpzX3N0cmluZyB0IG9wdCBwcm9wXG5cbiAgbWV0aG9kIGlubmVyVGV4dCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgY2xpZW50TGVmdCA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGNsaWVudFRvcCA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGNsaWVudFdpZHRoIDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgY2xpZW50SGVpZ2h0IDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgb2Zmc2V0TGVmdCA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIG9mZnNldFRvcCA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIG9mZnNldFBhcmVudCA6IGVsZW1lbnQgdCBvcHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvZmZzZXRXaWR0aCA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIG9mZnNldEhlaWdodCA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHNjcm9sbExlZnQgOiBpbnQgcHJvcFxuXG4gIG1ldGhvZCBzY3JvbGxUb3AgOiBpbnQgcHJvcFxuXG4gIG1ldGhvZCBzY3JvbGxXaWR0aCA6IGludCBwcm9wXG5cbiAgbWV0aG9kIHNjcm9sbEhlaWdodCA6IGludCBwcm9wXG5cbiAgbWV0aG9kIGdldENsaWVudFJlY3RzIDogY2xpZW50UmVjdExpc3QgdCBtZXRoXG5cbiAgbWV0aG9kIGdldEJvdW5kaW5nQ2xpZW50UmVjdCA6IGNsaWVudFJlY3QgdCBtZXRoXG5cbiAgbWV0aG9kIHNjcm9sbEludG9WaWV3IDogYm9vbCB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBjbGljayA6IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBmb2N1cyA6IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBibHVyIDogdW5pdCBtZXRoXG5cbiAgaW5oZXJpdCBldmVudFRhcmdldFxuZW5kXG5cbmFuZCBjbGllbnRSZWN0ID0gb2JqZWN0XG4gIG1ldGhvZCB0b3AgOiBudW1iZXJfdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHJpZ2h0IDogbnVtYmVyX3QgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBib3R0b20gOiBudW1iZXJfdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGxlZnQgOiBudW1iZXJfdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHdpZHRoIDogbnVtYmVyX3Qgb3B0ZGVmIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgaGVpZ2h0IDogbnVtYmVyX3Qgb3B0ZGVmIHJlYWRvbmx5X3Byb3BcbmVuZFxuXG5hbmQgY2xpZW50UmVjdExpc3QgPSBvYmplY3RcbiAgbWV0aG9kIGxlbmd0aCA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGl0ZW0gOiBpbnQgLT4gY2xpZW50UmVjdCB0IG9wdCBtZXRoXG5lbmRcblxubGV0IG5vX2hhbmRsZXIgOiAoJ2EsICdiKSBldmVudF9saXN0ZW5lciA9IERvbS5ub19oYW5kbGVyXG5cbmxldCBoYW5kbGVyID0gRG9tLmhhbmRsZXJcblxubGV0IGZ1bGxfaGFuZGxlciA9IERvbS5mdWxsX2hhbmRsZXJcblxubGV0IGludm9rZV9oYW5kbGVyID0gRG9tLmludm9rZV9oYW5kbGVyXG5cbm1vZHVsZSBFdmVudCA9IHN0cnVjdFxuICB0eXBlICdhIHR5cCA9ICdhIERvbS5FdmVudC50eXBcblxuICBsZXQgY2FuY2VsID0gRG9tLkV2ZW50Lm1ha2UgXCJjYW5jZWxcIlxuXG4gIGxldCBjbGljayA9IERvbS5FdmVudC5tYWtlIFwiY2xpY2tcIlxuXG4gIGxldCBjbG9zZSA9IERvbS5FdmVudC5tYWtlIFwiY2xvc2VcIlxuXG4gIGxldCBjb3B5ID0gRG9tLkV2ZW50Lm1ha2UgXCJjb3B5XCJcblxuICBsZXQgY3V0ID0gRG9tLkV2ZW50Lm1ha2UgXCJjdXRcIlxuXG4gIGxldCBwYXN0ZSA9IERvbS5FdmVudC5tYWtlIFwicGFzdGVcIlxuXG4gIGxldCBkYmxjbGljayA9IERvbS5FdmVudC5tYWtlIFwiZGJsY2xpY2tcIlxuXG4gIGxldCBtb3VzZWRvd24gPSBEb20uRXZlbnQubWFrZSBcIm1vdXNlZG93blwiXG5cbiAgbGV0IG1vdXNldXAgPSBEb20uRXZlbnQubWFrZSBcIm1vdXNldXBcIlxuXG4gIGxldCBtb3VzZW92ZXIgPSBEb20uRXZlbnQubWFrZSBcIm1vdXNlb3ZlclwiXG5cbiAgbGV0IG1vdXNlbW92ZSA9IERvbS5FdmVudC5tYWtlIFwibW91c2Vtb3ZlXCJcblxuICBsZXQgbW91c2VvdXQgPSBEb20uRXZlbnQubWFrZSBcIm1vdXNlb3V0XCJcblxuICBsZXQga2V5cHJlc3MgPSBEb20uRXZlbnQubWFrZSBcImtleXByZXNzXCJcblxuICBsZXQga2V5ZG93biA9IERvbS5FdmVudC5tYWtlIFwia2V5ZG93blwiXG5cbiAgbGV0IGtleXVwID0gRG9tLkV2ZW50Lm1ha2UgXCJrZXl1cFwiXG5cbiAgbGV0IG1vdXNld2hlZWwgPSBEb20uRXZlbnQubWFrZSBcIm1vdXNld2hlZWxcIlxuXG4gIGxldCB3aGVlbCA9IERvbS5FdmVudC5tYWtlIFwid2hlZWxcIlxuXG4gIGxldCBfRE9NTW91c2VTY3JvbGwgPSBEb20uRXZlbnQubWFrZSBcIkRPTU1vdXNlU2Nyb2xsXCJcblxuICBsZXQgdG91Y2hzdGFydCA9IERvbS5FdmVudC5tYWtlIFwidG91Y2hzdGFydFwiXG5cbiAgbGV0IHRvdWNobW92ZSA9IERvbS5FdmVudC5tYWtlIFwidG91Y2htb3ZlXCJcblxuICBsZXQgdG91Y2hlbmQgPSBEb20uRXZlbnQubWFrZSBcInRvdWNoZW5kXCJcblxuICBsZXQgdG91Y2hjYW5jZWwgPSBEb20uRXZlbnQubWFrZSBcInRvdWNoY2FuY2VsXCJcblxuICBsZXQgZHJhZ3N0YXJ0ID0gRG9tLkV2ZW50Lm1ha2UgXCJkcmFnc3RhcnRcIlxuXG4gIGxldCBkcmFnZW5kID0gRG9tLkV2ZW50Lm1ha2UgXCJkcmFnZW5kXCJcblxuICBsZXQgZHJhZ2VudGVyID0gRG9tLkV2ZW50Lm1ha2UgXCJkcmFnZW50ZXJcIlxuXG4gIGxldCBkcmFnb3ZlciA9IERvbS5FdmVudC5tYWtlIFwiZHJhZ292ZXJcIlxuXG4gIGxldCBkcmFnbGVhdmUgPSBEb20uRXZlbnQubWFrZSBcImRyYWdsZWF2ZVwiXG5cbiAgbGV0IGRyYWcgPSBEb20uRXZlbnQubWFrZSBcImRyYWdcIlxuXG4gIGxldCBkcm9wID0gRG9tLkV2ZW50Lm1ha2UgXCJkcm9wXCJcblxuICBsZXQgaGFzaGNoYW5nZSA9IERvbS5FdmVudC5tYWtlIFwiaGFzaGNoYW5nZVwiXG5cbiAgbGV0IGNoYW5nZSA9IERvbS5FdmVudC5tYWtlIFwiY2hhbmdlXCJcblxuICBsZXQgaW5wdXQgPSBEb20uRXZlbnQubWFrZSBcImlucHV0XCJcblxuICBsZXQgdGltZXVwZGF0ZSA9IERvbS5FdmVudC5tYWtlIFwidGltZXVwZGF0ZVwiXG5cbiAgbGV0IHN1Ym1pdCA9IERvbS5FdmVudC5tYWtlIFwic3VibWl0XCJcblxuICBsZXQgc2Nyb2xsID0gRG9tLkV2ZW50Lm1ha2UgXCJzY3JvbGxcIlxuXG4gIGxldCBmb2N1cyA9IERvbS5FdmVudC5tYWtlIFwiZm9jdXNcIlxuXG4gIGxldCBibHVyID0gRG9tLkV2ZW50Lm1ha2UgXCJibHVyXCJcblxuICBsZXQgbG9hZCA9IERvbS5FdmVudC5tYWtlIFwibG9hZFwiXG5cbiAgbGV0IHVubG9hZCA9IERvbS5FdmVudC5tYWtlIFwidW5sb2FkXCJcblxuICBsZXQgYmVmb3JldW5sb2FkID0gRG9tLkV2ZW50Lm1ha2UgXCJiZWZvcmV1bmxvYWRcIlxuXG4gIGxldCByZXNpemUgPSBEb20uRXZlbnQubWFrZSBcInJlc2l6ZVwiXG5cbiAgbGV0IG9yaWVudGF0aW9uY2hhbmdlID0gRG9tLkV2ZW50Lm1ha2UgXCJvcmllbnRhdGlvbmNoYW5nZVwiXG5cbiAgbGV0IHBvcHN0YXRlID0gRG9tLkV2ZW50Lm1ha2UgXCJwb3BzdGF0ZVwiXG5cbiAgbGV0IGVycm9yID0gRG9tLkV2ZW50Lm1ha2UgXCJlcnJvclwiXG5cbiAgbGV0IGFib3J0ID0gRG9tLkV2ZW50Lm1ha2UgXCJhYm9ydFwiXG5cbiAgbGV0IHNlbGVjdCA9IERvbS5FdmVudC5tYWtlIFwic2VsZWN0XCJcblxuICBsZXQgb25saW5lID0gRG9tLkV2ZW50Lm1ha2UgXCJvbmxpbmVcIlxuXG4gIGxldCBvZmZsaW5lID0gRG9tLkV2ZW50Lm1ha2UgXCJvZmZsaW5lXCJcblxuICBsZXQgY2hlY2tpbmcgPSBEb20uRXZlbnQubWFrZSBcImNoZWNraW5nXCJcblxuICBsZXQgbm91cGRhdGUgPSBEb20uRXZlbnQubWFrZSBcIm5vdXBkYXRlXCJcblxuICBsZXQgZG93bmxvYWRpbmcgPSBEb20uRXZlbnQubWFrZSBcImRvd25sb2FkaW5nXCJcblxuICBsZXQgcHJvZ3Jlc3MgPSBEb20uRXZlbnQubWFrZSBcInByb2dyZXNzXCJcblxuICBsZXQgdXBkYXRlcmVhZHkgPSBEb20uRXZlbnQubWFrZSBcInVwZGF0ZXJlYWR5XCJcblxuICBsZXQgY2FjaGVkID0gRG9tLkV2ZW50Lm1ha2UgXCJjYWNoZWRcIlxuXG4gIGxldCBvYnNvbGV0ZSA9IERvbS5FdmVudC5tYWtlIFwib2Jzb2xldGVcIlxuXG4gIGxldCBkb21Db250ZW50TG9hZGVkID0gRG9tLkV2ZW50Lm1ha2UgXCJET01Db250ZW50TG9hZGVkXCJcblxuICBsZXQgYW5pbWF0aW9uc3RhcnQgPSBEb20uRXZlbnQubWFrZSBcImFuaW1hdGlvbnN0YXJ0XCJcblxuICBsZXQgYW5pbWF0aW9uZW5kID0gRG9tLkV2ZW50Lm1ha2UgXCJhbmltYXRpb25lbmRcIlxuXG4gIGxldCBhbmltYXRpb25pdGVyYXRpb24gPSBEb20uRXZlbnQubWFrZSBcImFuaW1hdGlvbml0ZXJhdGlvblwiXG5cbiAgbGV0IGFuaW1hdGlvbmNhbmNlbCA9IERvbS5FdmVudC5tYWtlIFwiYW5pbWF0aW9uY2FuY2VsXCJcblxuICBsZXQgdHJhbnNpdGlvbnJ1biA9IERvbS5FdmVudC5tYWtlIFwidHJhbnNpdGlvbnJ1blwiXG5cbiAgbGV0IHRyYW5zaXRpb25zdGFydCA9IERvbS5FdmVudC5tYWtlIFwidHJhbnNpdGlvbnN0YXJ0XCJcblxuICBsZXQgdHJhbnNpdGlvbmVuZCA9IERvbS5FdmVudC5tYWtlIFwidHJhbnNpdGlvbmVuZFwiXG5cbiAgbGV0IHRyYW5zaXRpb25jYW5jZWwgPSBEb20uRXZlbnQubWFrZSBcInRyYW5zaXRpb25jYW5jZWxcIlxuXG4gIGxldCBjYW5wbGF5ID0gRG9tLkV2ZW50Lm1ha2UgXCJjYW5wbGF5XCJcblxuICBsZXQgY2FucGxheXRocm91Z2ggPSBEb20uRXZlbnQubWFrZSBcImNhbnBsYXl0aHJvdWdoXCJcblxuICBsZXQgZHVyYXRpb25jaGFuZ2UgPSBEb20uRXZlbnQubWFrZSBcImR1cmF0aW9uY2hhbmdlXCJcblxuICBsZXQgZW1wdGllZCA9IERvbS5FdmVudC5tYWtlIFwiZW1wdGllZFwiXG5cbiAgbGV0IGVuZGVkID0gRG9tLkV2ZW50Lm1ha2UgXCJlbmRlZFwiXG5cbiAgbGV0IGdvdHBvaW50ZXJjYXB0dXJlID0gRG9tLkV2ZW50Lm1ha2UgXCJnb3Rwb2ludGVyY2FwdHVyZVwiXG5cbiAgbGV0IGxvYWRlZGRhdGEgPSBEb20uRXZlbnQubWFrZSBcImxvYWRlZGRhdGFcIlxuXG4gIGxldCBsb2FkZWRtZXRhZGF0YSA9IERvbS5FdmVudC5tYWtlIFwibG9hZGVkbWV0YWRhdGFcIlxuXG4gIGxldCBsb2Fkc3RhcnQgPSBEb20uRXZlbnQubWFrZSBcImxvYWRzdGFydFwiXG5cbiAgbGV0IGxvc3Rwb2ludGVyY2FwdHVyZSA9IERvbS5FdmVudC5tYWtlIFwibG9zdHBvaW50ZXJjYXB0dXJlXCJcblxuICBsZXQgbWVzc2FnZSA9IERvbS5FdmVudC5tYWtlIFwibWVzc2FnZVwiXG5cbiAgbGV0IHBhdXNlID0gRG9tLkV2ZW50Lm1ha2UgXCJwYXVzZVwiXG5cbiAgbGV0IHBsYXkgPSBEb20uRXZlbnQubWFrZSBcInBsYXlcIlxuXG4gIGxldCBwbGF5aW5nID0gRG9tLkV2ZW50Lm1ha2UgXCJwbGF5aW5nXCJcblxuICBsZXQgcG9pbnRlcmVudGVyID0gRG9tLkV2ZW50Lm1ha2UgXCJwb2ludGVyZW50ZXJcIlxuXG4gIGxldCBwb2ludGVyY2FuY2VsID0gRG9tLkV2ZW50Lm1ha2UgXCJwb2ludGVyY2FuY2VsXCJcblxuICBsZXQgcG9pbnRlcmRvd24gPSBEb20uRXZlbnQubWFrZSBcInBvaW50ZXJkb3duXCJcblxuICBsZXQgcG9pbnRlcmxlYXZlID0gRG9tLkV2ZW50Lm1ha2UgXCJwb2ludGVybGVhdmVcIlxuXG4gIGxldCBwb2ludGVybW92ZSA9IERvbS5FdmVudC5tYWtlIFwicG9pbnRlcm1vdmVcIlxuXG4gIGxldCBwb2ludGVyb3V0ID0gRG9tLkV2ZW50Lm1ha2UgXCJwb2ludGVyb3V0XCJcblxuICBsZXQgcG9pbnRlcm92ZXIgPSBEb20uRXZlbnQubWFrZSBcInBvaW50ZXJvdmVyXCJcblxuICBsZXQgcG9pbnRlcnVwID0gRG9tLkV2ZW50Lm1ha2UgXCJwb2ludGVydXBcIlxuXG4gIGxldCByYXRlY2hhbmdlID0gRG9tLkV2ZW50Lm1ha2UgXCJyYXRlY2hhbmdlXCJcblxuICBsZXQgc2Vla2VkID0gRG9tLkV2ZW50Lm1ha2UgXCJzZWVrZWRcIlxuXG4gIGxldCBzZWVraW5nID0gRG9tLkV2ZW50Lm1ha2UgXCJzZWVraW5nXCJcblxuICBsZXQgc3RhbGxlZCA9IERvbS5FdmVudC5tYWtlIFwic3RhbGxlZFwiXG5cbiAgbGV0IHN1c3BlbmQgPSBEb20uRXZlbnQubWFrZSBcInN1c3BlbmRcIlxuXG4gIGxldCB2b2x1bWVjaGFuZ2UgPSBEb20uRXZlbnQubWFrZSBcInZvbHVtZWNoYW5nZVwiXG5cbiAgbGV0IHdhaXRpbmcgPSBEb20uRXZlbnQubWFrZSBcIndhaXRpbmdcIlxuXG4gIGxldCBtYWtlID0gRG9tLkV2ZW50Lm1ha2VcbmVuZFxuXG50eXBlIGV2ZW50X2xpc3RlbmVyX2lkID0gRG9tLmV2ZW50X2xpc3RlbmVyX2lkXG5cbmxldCBhZGRFdmVudExpc3RlbmVyID0gRG9tLmFkZEV2ZW50TGlzdGVuZXJcblxubGV0IGFkZEV2ZW50TGlzdGVuZXJXaXRoT3B0aW9ucyA9IERvbS5hZGRFdmVudExpc3RlbmVyV2l0aE9wdGlvbnNcblxubGV0IHJlbW92ZUV2ZW50TGlzdGVuZXIgPSBEb20ucmVtb3ZlRXZlbnRMaXN0ZW5lclxuXG5sZXQgY3JlYXRlQ3VzdG9tRXZlbnQgPSBEb20uY3JlYXRlQ3VzdG9tRXZlbnRcblxuY2xhc3MgdHlwZSBbJ25vZGVdIGNvbGxlY3Rpb24gPSBvYmplY3RcbiAgbWV0aG9kIGxlbmd0aCA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGl0ZW0gOiBpbnQgLT4gJ25vZGUgdCBvcHQgbWV0aFxuXG4gIG1ldGhvZCBuYW1lZEl0ZW0gOiBqc19zdHJpbmcgdCAtPiAnbm9kZSB0IG9wdCBtZXRoXG5lbmRcblxuY2xhc3MgdHlwZSBodG1sRWxlbWVudCA9IGVsZW1lbnRcblxuY2xhc3MgdHlwZSBoZWFkRWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBtZXRob2QgcHJvZmlsZSA6IGpzX3N0cmluZyB0IHByb3BcbmVuZFxuXG5jbGFzcyB0eXBlIGxpbmtFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIG1ldGhvZCBkaXNhYmxlZCA6IGJvb2wgdCBwcm9wXG5cbiAgbWV0aG9kIGNoYXJzZXQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGNyb3Nzb3JpZ2luIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBocmVmIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBocmVmbGFuZyA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgbWVkaWEgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHJlbCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgcmV2IDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCB0YXJnZXQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIF90eXBlIDoganNfc3RyaW5nIHQgcHJvcFxuZW5kXG5cbmNsYXNzIHR5cGUgdGl0bGVFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIG1ldGhvZCB0ZXh0IDoganNfc3RyaW5nIHQgcHJvcFxuZW5kXG5cbmNsYXNzIHR5cGUgbWV0YUVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgbWV0aG9kIGNvbnRlbnQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGh0dHBFcXVpdiA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgbmFtZSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2Qgc2NoZW1lIDoganNfc3RyaW5nIHQgcHJvcFxuZW5kXG5cbmNsYXNzIHR5cGUgYmFzZUVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgbWV0aG9kIGhyZWYgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHRhcmdldCA6IGpzX3N0cmluZyB0IHByb3BcbmVuZFxuXG5jbGFzcyB0eXBlIHN0eWxlRWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBtZXRob2QgZGlzYWJsZWQgOiBib29sIHQgcHJvcFxuXG4gIG1ldGhvZCBtZWRpYSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgX3R5cGUgOiBqc19zdHJpbmcgdCBwcm9wXG5lbmRcblxuY2xhc3MgdHlwZSBib2R5RWxlbWVudCA9IGVsZW1lbnRcblxuY2xhc3MgdHlwZSBmb3JtRWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBtZXRob2QgZWxlbWVudHMgOiBlbGVtZW50IGNvbGxlY3Rpb24gdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGxlbmd0aCA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGFjY2VwdENoYXJzZXQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGFjdGlvbiA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgZW5jdHlwZSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgX21ldGhvZCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgdGFyZ2V0IDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBzdWJtaXQgOiB1bml0IG1ldGhcblxuICBtZXRob2QgcmVzZXQgOiB1bml0IG1ldGhcblxuICBtZXRob2Qgb25zdWJtaXQgOiAoJ3NlbGYgdCwgc3VibWl0RXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgd3JpdGVvbmx5X3Byb3BcbmVuZFxuXG5jbGFzcyB0eXBlIG9wdEdyb3VwRWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBtZXRob2QgZGlzYWJsZWQgOiBib29sIHQgcHJvcFxuXG4gIG1ldGhvZCBsYWJlbCA6IGpzX3N0cmluZyB0IHByb3BcbmVuZFxuXG5jbGFzcyB0eXBlIG9wdGlvbkVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBvcHRHcm91cEVsZW1lbnRcblxuICBtZXRob2QgZm9ybSA6IGZvcm1FbGVtZW50IHQgb3B0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZGVmYXVsdFNlbGVjdGVkIDogYm9vbCB0IHByb3BcblxuICBtZXRob2QgdGV4dCA6IGpzX3N0cmluZyB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgaW5kZXggOiBpbnQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBzZWxlY3RlZCA6IGJvb2wgdCBwcm9wXG5cbiAgbWV0aG9kIHZhbHVlIDoganNfc3RyaW5nIHQgcHJvcFxuZW5kXG5cbmNsYXNzIHR5cGUgc2VsZWN0RWxlbWVudCA9IG9iamVjdCAoJ3NlbGYpXG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIG1ldGhvZCBfdHlwZSA6IGpzX3N0cmluZyB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgc2VsZWN0ZWRJbmRleCA6IGludCBwcm9wXG5cbiAgbWV0aG9kIHZhbHVlIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBsZW5ndGggOiBpbnQgcHJvcFxuXG4gIG1ldGhvZCBmb3JtIDogZm9ybUVsZW1lbnQgdCBvcHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvcHRpb25zIDogb3B0aW9uRWxlbWVudCBjb2xsZWN0aW9uIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBkaXNhYmxlZCA6IGJvb2wgdCBwcm9wXG5cbiAgbWV0aG9kIG11bHRpcGxlIDogYm9vbCB0IHByb3BcblxuICBtZXRob2QgbmFtZSA6IGpzX3N0cmluZyB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgc2l6ZSA6IGludCBwcm9wXG5cbiAgbWV0aG9kIHRhYkluZGV4IDogaW50IHByb3BcblxuICBtZXRob2QgYWRkIDogI29wdEdyb3VwRWxlbWVudCB0IC0+ICNvcHRHcm91cEVsZW1lbnQgdCBvcHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHJlbW92ZSA6IGludCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgcmVxdWlyZWQgOiBib29sIHQgd3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2Qgb25jaGFuZ2UgOiAoJ3NlbGYgdCwgZXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgcHJvcFxuXG4gIG1ldGhvZCBvbmlucHV0IDogKCdzZWxmIHQsIGV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHByb3BcbmVuZFxuXG5jbGFzcyB0eXBlIGlucHV0RWxlbWVudCA9IG9iamVjdCAoJ3NlbGYpXG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIG1ldGhvZCBkZWZhdWx0VmFsdWUgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGRlZmF1bHRDaGVja2VkIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBmb3JtIDogZm9ybUVsZW1lbnQgdCBvcHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBhY2NlcHQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGFjY2Vzc0tleSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgYWxpZ24gOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGFsdCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgY2hlY2tlZCA6IGJvb2wgdCBwcm9wXG5cbiAgbWV0aG9kIGRpc2FibGVkIDogYm9vbCB0IHByb3BcblxuICBtZXRob2QgbWF4TGVuZ3RoIDogaW50IHByb3BcblxuICBtZXRob2QgbmFtZSA6IGpzX3N0cmluZyB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgcmVhZE9ubHkgOiBib29sIHQgcHJvcFxuXG4gIG1ldGhvZCByZXF1aXJlZCA6IGJvb2wgdCB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBzaXplIDogaW50IHByb3BcblxuICBtZXRob2Qgc3JjIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCB0YWJJbmRleCA6IGludCBwcm9wXG5cbiAgbWV0aG9kIF90eXBlIDoganNfc3RyaW5nIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCB1c2VNYXAgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHZhbHVlIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBzZWxlY3QgOiB1bml0IG1ldGhcblxuICBtZXRob2QgZmlsZXMgOiBGaWxlLmZpbGVMaXN0IHQgb3B0ZGVmIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgcGxhY2Vob2xkZXIgOiBqc19zdHJpbmcgdCB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBzZWxlY3Rpb25EaXJlY3Rpb24gOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHNlbGVjdGlvblN0YXJ0IDogaW50IHByb3BcblxuICBtZXRob2Qgc2VsZWN0aW9uRW5kIDogaW50IHByb3BcblxuICBtZXRob2Qgb25zZWxlY3QgOiAoJ3NlbGYgdCwgZXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgcHJvcFxuXG4gIG1ldGhvZCBvbmNoYW5nZSA6ICgnc2VsZiB0LCBldmVudCB0KSBldmVudF9saXN0ZW5lciBwcm9wXG5cbiAgbWV0aG9kIG9uaW5wdXQgOiAoJ3NlbGYgdCwgZXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgcHJvcFxuXG4gIG1ldGhvZCBvbmJsdXIgOiAoJ3NlbGYgdCwgZm9jdXNFdmVudCB0KSBldmVudF9saXN0ZW5lciBwcm9wXG5cbiAgbWV0aG9kIG9uZm9jdXMgOiAoJ3NlbGYgdCwgZm9jdXNFdmVudCB0KSBldmVudF9saXN0ZW5lciBwcm9wXG5lbmRcblxuY2xhc3MgdHlwZSB0ZXh0QXJlYUVsZW1lbnQgPSBvYmplY3QgKCdzZWxmKVxuICBpbmhlcml0IGVsZW1lbnRcblxuICBtZXRob2QgZGVmYXVsdFZhbHVlIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBmb3JtIDogZm9ybUVsZW1lbnQgdCBvcHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBhY2Nlc3NLZXkgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGNvbHMgOiBpbnQgcHJvcFxuXG4gIG1ldGhvZCBkaXNhYmxlZCA6IGJvb2wgdCBwcm9wXG5cbiAgbWV0aG9kIG5hbWUgOiBqc19zdHJpbmcgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHJlYWRPbmx5IDogYm9vbCB0IHByb3BcblxuICBtZXRob2Qgcm93cyA6IGludCBwcm9wXG5cbiAgbWV0aG9kIHNlbGVjdGlvbkRpcmVjdGlvbiA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2Qgc2VsZWN0aW9uRW5kIDogaW50IHByb3BcblxuICBtZXRob2Qgc2VsZWN0aW9uU3RhcnQgOiBpbnQgcHJvcFxuXG4gIG1ldGhvZCB0YWJJbmRleCA6IGludCBwcm9wXG5cbiAgbWV0aG9kIF90eXBlIDoganNfc3RyaW5nIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCB2YWx1ZSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2Qgc2VsZWN0IDogdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHJlcXVpcmVkIDogYm9vbCB0IHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIHBsYWNlaG9sZGVyIDoganNfc3RyaW5nIHQgd3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2Qgb25zZWxlY3QgOiAoJ3NlbGYgdCwgZXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgcHJvcFxuXG4gIG1ldGhvZCBvbmNoYW5nZSA6ICgnc2VsZiB0LCBldmVudCB0KSBldmVudF9saXN0ZW5lciBwcm9wXG5cbiAgbWV0aG9kIG9uaW5wdXQgOiAoJ3NlbGYgdCwgZXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgcHJvcFxuXG4gIG1ldGhvZCBvbmJsdXIgOiAoJ3NlbGYgdCwgZm9jdXNFdmVudCB0KSBldmVudF9saXN0ZW5lciBwcm9wXG5cbiAgbWV0aG9kIG9uZm9jdXMgOiAoJ3NlbGYgdCwgZm9jdXNFdmVudCB0KSBldmVudF9saXN0ZW5lciBwcm9wXG5lbmRcblxuY2xhc3MgdHlwZSBidXR0b25FbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIG1ldGhvZCBmb3JtIDogZm9ybUVsZW1lbnQgdCBvcHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBhY2Nlc3NLZXkgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGRpc2FibGVkIDogYm9vbCB0IHByb3BcblxuICBtZXRob2QgbmFtZSA6IGpzX3N0cmluZyB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgdGFiSW5kZXggOiBpbnQgcHJvcFxuXG4gIG1ldGhvZCBfdHlwZSA6IGpzX3N0cmluZyB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgdmFsdWUgOiBqc19zdHJpbmcgdCBwcm9wXG5lbmRcblxuY2xhc3MgdHlwZSBsYWJlbEVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgbWV0aG9kIGZvcm0gOiBmb3JtRWxlbWVudCB0IG9wdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGFjY2Vzc0tleSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgaHRtbEZvciA6IGpzX3N0cmluZyB0IHByb3BcbmVuZFxuXG5jbGFzcyB0eXBlIGZpZWxkU2V0RWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBtZXRob2QgZm9ybSA6IGZvcm1FbGVtZW50IHQgb3B0IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG5jbGFzcyB0eXBlIGxlZ2VuZEVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgbWV0aG9kIGZvcm0gOiBmb3JtRWxlbWVudCB0IG9wdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGFjY2Vzc0tleSA6IGpzX3N0cmluZyB0IHByb3BcbmVuZFxuXG5jbGFzcyB0eXBlIHVMaXN0RWxlbWVudCA9IGVsZW1lbnRcblxuY2xhc3MgdHlwZSBvTGlzdEVsZW1lbnQgPSBlbGVtZW50XG5cbmNsYXNzIHR5cGUgZExpc3RFbGVtZW50ID0gZWxlbWVudFxuXG5jbGFzcyB0eXBlIGxpRWxlbWVudCA9IGVsZW1lbnRcblxuY2xhc3MgdHlwZSBkaWFsb2dFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIG1ldGhvZCBjbG9zZSA6IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBjbG9zZV9yZXR1cm5WYWx1ZSA6IGpzX3N0cmluZyB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBvcGVuXyA6IGJvb2wgdCBwcm9wXG5cbiAgbWV0aG9kIHJldHVyblZhbHVlIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBzaG93IDogdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHNob3dNb2RhbCA6IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBvbmNhbmNlbCA6ICgnc2VsZiB0LCBldmVudCB0KSBldmVudF9saXN0ZW5lciBwcm9wXG5cbiAgbWV0aG9kIG9uY2xvc2UgOiAoJ3NlbGYgdCwgZXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgcHJvcFxuZW5kXG5cbmNsYXNzIHR5cGUgZGl2RWxlbWVudCA9IGVsZW1lbnRcblxuY2xhc3MgdHlwZSBwYXJhZ3JhcGhFbGVtZW50ID0gZWxlbWVudFxuXG5jbGFzcyB0eXBlIGhlYWRpbmdFbGVtZW50ID0gZWxlbWVudFxuXG5jbGFzcyB0eXBlIHF1b3RlRWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBtZXRob2QgY2l0ZSA6IGpzX3N0cmluZyB0IHByb3BcbmVuZFxuXG5jbGFzcyB0eXBlIHByZUVsZW1lbnQgPSBlbGVtZW50XG5cbmNsYXNzIHR5cGUgYnJFbGVtZW50ID0gZWxlbWVudFxuXG5jbGFzcyB0eXBlIGhyRWxlbWVudCA9IGVsZW1lbnRcblxuY2xhc3MgdHlwZSBtb2RFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIG1ldGhvZCBjaXRlIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBkYXRlVGltZSA6IGpzX3N0cmluZyB0IHByb3BcbmVuZFxuXG5jbGFzcyB0eXBlIGFuY2hvckVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgbWV0aG9kIGFjY2Vzc0tleSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgY2hhcnNldCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgY29vcmRzIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBkb3dubG9hZCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgaHJlZiA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgaHJlZmxhbmcgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIG5hbWUgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHJlbCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgcmV2IDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBzaGFwZSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgdGFiSW5kZXggOiBpbnQgcHJvcFxuXG4gIG1ldGhvZCB0YXJnZXQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIF90eXBlIDoganNfc3RyaW5nIHQgcHJvcFxuZW5kXG5cbmNsYXNzIHR5cGUgaW1hZ2VFbGVtZW50ID0gb2JqZWN0ICgnc2VsZilcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgbWV0aG9kIGFsdCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2Qgc3JjIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCB1c2VNYXAgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGlzTWFwIDogYm9vbCB0IHByb3BcblxuICBtZXRob2Qgd2lkdGggOiBpbnQgcHJvcFxuXG4gIG1ldGhvZCBoZWlnaHQgOiBpbnQgcHJvcFxuXG4gIG1ldGhvZCBuYXR1cmFsV2lkdGggOiBpbnQgb3B0ZGVmIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgbmF0dXJhbEhlaWdodCA6IGludCBvcHRkZWYgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBjb21wbGV0ZSA6IGJvb2wgdCBwcm9wXG5cbiAgbWV0aG9kIG9ubG9hZCA6ICgnc2VsZiB0LCBldmVudCB0KSBldmVudF9saXN0ZW5lciBwcm9wXG5cbiAgbWV0aG9kIG9uZXJyb3IgOiAoJ3NlbGYgdCwgZXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgcHJvcFxuXG4gIG1ldGhvZCBvbmFib3J0IDogKCdzZWxmIHQsIGV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHByb3BcbmVuZFxuXG5jbGFzcyB0eXBlIG9iamVjdEVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgbWV0aG9kIGZvcm0gOiBmb3JtRWxlbWVudCB0IG9wdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGNvZGUgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGFyY2hpdmUgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGNvZGVCYXNlIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBjb2RlVHlwZSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgZGF0YSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgZGVjbGFyZSA6IGJvb2wgdCBwcm9wXG5cbiAgbWV0aG9kIGhlaWdodCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgbmFtZSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2Qgc3RhbmRieSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgdGFiSW5kZXggOiBpbnQgcHJvcFxuXG4gIG1ldGhvZCBfdHlwZSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgdXNlTWFwIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCB3aWR0aCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgZG9jdW1lbnQgOiBEb20uZWxlbWVudCBEb20uZG9jdW1lbnQgdCBvcHQgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbmNsYXNzIHR5cGUgcGFyYW1FbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIG1ldGhvZCBuYW1lIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBfdHlwZSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgdmFsdWUgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHZhbHVlVHlwZSA6IGpzX3N0cmluZyB0IHByb3BcbmVuZFxuXG5jbGFzcyB0eXBlIGFyZWFFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIG1ldGhvZCBhY2Nlc3NLZXkgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGFsdCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgY29vcmRzIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBocmVmIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBub0hyZWYgOiBib29sIHQgcHJvcFxuXG4gIG1ldGhvZCBzaGFwZSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgdGFiSW5kZXggOiBpbnQgcHJvcFxuXG4gIG1ldGhvZCB0YXJnZXQgOiBqc19zdHJpbmcgdCBwcm9wXG5lbmRcblxuY2xhc3MgdHlwZSBtYXBFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIG1ldGhvZCBhcmVhcyA6IGFyZWFFbGVtZW50IGNvbGxlY3Rpb24gdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIG5hbWUgOiBqc19zdHJpbmcgdCBwcm9wXG5lbmRcblxuY2xhc3MgdHlwZSBzY3JpcHRFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIG1ldGhvZCB0ZXh0IDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBjaGFyc2V0IDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBkZWZlciA6IGJvb2wgdCBwcm9wXG5cbiAgbWV0aG9kIHNyYyA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgX3R5cGUgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGFzeW5jIDogYm9vbCB0IHByb3BcbmVuZFxuXG5jbGFzcyB0eXBlIGVtYmVkRWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBtZXRob2Qgc3JjIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBoZWlnaHQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHdpZHRoIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBfdHlwZSA6IGpzX3N0cmluZyB0IHByb3BcbmVuZFxuXG5jbGFzcyB0eXBlIHRhYmxlQ2VsbEVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgbWV0aG9kIGNlbGxJbmRleCA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGFiYnIgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGFsaWduIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBheGlzIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBjaCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgY2hPZmYgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGNvbFNwYW4gOiBpbnQgcHJvcFxuXG4gIG1ldGhvZCBoZWFkZXJzIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCByb3dTcGFuIDogaW50IHByb3BcblxuICBtZXRob2Qgc2NvcGUgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHZBbGlnbiA6IGpzX3N0cmluZyB0IHByb3BcbmVuZFxuXG5jbGFzcyB0eXBlIHRhYmxlUm93RWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBtZXRob2Qgcm93SW5kZXggOiBpbnQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBzZWN0aW9uUm93SW5kZXggOiBpbnQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBjZWxscyA6IHRhYmxlQ2VsbEVsZW1lbnQgY29sbGVjdGlvbiB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgYWxpZ24gOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGNoIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBjaE9mZiA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgdkFsaWduIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBpbnNlcnRDZWxsIDogaW50IC0+IHRhYmxlQ2VsbEVsZW1lbnQgdCBtZXRoXG5cbiAgbWV0aG9kIGRlbGV0ZUNlbGwgOiBpbnQgLT4gdW5pdCBtZXRoXG5lbmRcblxuY2xhc3MgdHlwZSB0YWJsZUNvbEVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgbWV0aG9kIGFsaWduIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBjaCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgY2hPZmYgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHNwYW4gOiBpbnQgcHJvcFxuXG4gIG1ldGhvZCB2QWxpZ24gOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHdpZHRoIDoganNfc3RyaW5nIHQgcHJvcFxuZW5kXG5cbmNsYXNzIHR5cGUgdGFibGVTZWN0aW9uRWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBtZXRob2QgYWxpZ24gOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGNoIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBjaE9mZiA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgdkFsaWduIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCByb3dzIDogdGFibGVSb3dFbGVtZW50IGNvbGxlY3Rpb24gdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGluc2VydFJvdyA6IGludCAtPiB0YWJsZVJvd0VsZW1lbnQgdCBtZXRoXG5cbiAgbWV0aG9kIGRlbGV0ZVJvdyA6IGludCAtPiB1bml0IG1ldGhcbmVuZFxuXG5jbGFzcyB0eXBlIHRhYmxlQ2FwdGlvbkVsZW1lbnQgPSBlbGVtZW50XG5cbmNsYXNzIHR5cGUgdGFibGVFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIG1ldGhvZCBjYXB0aW9uIDogdGFibGVDYXB0aW9uRWxlbWVudCB0IHByb3BcblxuICBtZXRob2QgdEhlYWQgOiB0YWJsZVNlY3Rpb25FbGVtZW50IHQgcHJvcFxuXG4gIG1ldGhvZCB0Rm9vdCA6IHRhYmxlU2VjdGlvbkVsZW1lbnQgdCBwcm9wXG5cbiAgbWV0aG9kIHJvd3MgOiB0YWJsZVJvd0VsZW1lbnQgY29sbGVjdGlvbiB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgdEJvZGllcyA6IHRhYmxlU2VjdGlvbkVsZW1lbnQgY29sbGVjdGlvbiB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgYWxpZ24gOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGJvcmRlciA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgY2VsbFBhZGRpbmcgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGNlbGxTcGFjaW5nIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBmcmFtZSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgcnVsZXMgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHN1bW1hcnkgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHdpZHRoIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBjcmVhdGVUSGVhZCA6IHRhYmxlU2VjdGlvbkVsZW1lbnQgdCBtZXRoXG5cbiAgbWV0aG9kIGRlbGV0ZVRIZWFkIDogdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGNyZWF0ZVRGb290IDogdGFibGVTZWN0aW9uRWxlbWVudCB0IG1ldGhcblxuICBtZXRob2QgZGVsZXRlVEZvb3QgOiB1bml0IG1ldGhcblxuICBtZXRob2QgY3JlYXRlQ2FwdGlvbiA6IHRhYmxlQ2FwdGlvbkVsZW1lbnQgdCBtZXRoXG5cbiAgbWV0aG9kIGRlbGV0ZUNhcHRpb24gOiB1bml0IG1ldGhcblxuICBtZXRob2QgaW5zZXJ0Um93IDogaW50IC0+IHRhYmxlUm93RWxlbWVudCB0IG1ldGhcblxuICBtZXRob2QgZGVsZXRlUm93IDogaW50IC0+IHVuaXQgbWV0aFxuZW5kXG5cbmNsYXNzIHR5cGUgdGltZVJhbmdlcyA9IG9iamVjdFxuICBtZXRob2QgbGVuZ3RoIDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgc3RhcnQgOiBpbnQgLT4gbnVtYmVyX3QgbWV0aFxuXG4gIG1ldGhvZCBlbmRfIDogaW50IC0+IG51bWJlcl90IG1ldGhcbmVuZFxuXG50eXBlIG5ldHdvcmtTdGF0ZSA9XG4gIHwgTkVUV09SS19FTVBUWVxuICB8IE5FVFdPUktfSURMRVxuICB8IE5FVFdPUktfTE9BRElOR1xuICB8IE5FVFdPUktfTk9fU09VUkNFXG5cbnR5cGUgcmVhZHlTdGF0ZSA9XG4gIHwgSEFWRV9OT1RISU5HXG4gIHwgSEFWRV9NRVRBREFUQVxuICB8IEhBVkVfQ1VSUkVOVF9EQVRBXG4gIHwgSEFWRV9GVVRVUkVfREFUQVxuICB8IEhBVkVfRU5PVUdIX0RBVEFcblxuKCogaHR0cDovL3d3dy53M3NjaG9vbHMuY29tL3RhZ3MvcmVmX2F2X2RvbS5hc3AgKilcbigqIG9ubHkgZmVhdHVyZXMgc3VwcG9ydGVkIGJ5IGFsbCBicm93c2VyLiAoSUU5KykgKilcbmNsYXNzIHR5cGUgbWVkaWFFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIG1ldGhvZCBjYW5QbGF5VHlwZSA6IGpzX3N0cmluZyB0IC0+IGpzX3N0cmluZyB0IG1ldGhcblxuICBtZXRob2QgbG9hZCA6IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBwbGF5IDogdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHBhdXNlIDogdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGF1dG9wbGF5IDogYm9vbCB0IHByb3BcblxuICBtZXRob2QgYnVmZmVyZWQgOiB0aW1lUmFuZ2VzIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBjb250cm9scyA6IGJvb2wgdCBwcm9wXG5cbiAgbWV0aG9kIGN1cnJlbnRTcmMgOiBqc19zdHJpbmcgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGN1cnJlbnRUaW1lIDogbnVtYmVyX3QgcHJvcFxuXG4gIG1ldGhvZCBkdXJhdGlvbiA6IG51bWJlcl90IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZW5kZWQgOiBib29sIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBsb29wIDogYm9vbCB0IHByb3BcblxuICBtZXRob2QgbWVkaWFncm91cCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgbXV0ZWQgOiBib29sIHQgcHJvcFxuXG4gIG1ldGhvZCBuZXR3b3JrU3RhdGVfaW50IDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgbmV0d29ya1N0YXRlIDogbmV0d29ya1N0YXRlIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgcGF1c2VkIDogYm9vbCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgcGxheWJhY2tSYXRlIDogbnVtYmVyX3QgcHJvcFxuXG4gIG1ldGhvZCBwbGF5ZWQgOiB0aW1lUmFuZ2VzIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBwcmVsb2FkIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCByZWFkeVN0YXRlX2ludCA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHJlYWR5U3RhdGUgOiByZWFkeVN0YXRlIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgc2Vla2FibGUgOiB0aW1lUmFuZ2VzIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBzZWVraW5nIDogYm9vbCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgc3JjIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCB2b2x1bWUgOiBudW1iZXJfdCBwcm9wXG5cbiAgbWV0aG9kIG9uY2FucGxheSA6ICgnc2VsZiB0LCBtZWRpYUV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9uY2FucGxheXRocm91Z2ggOiAoJ3NlbGYgdCwgbWVkaWFFdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbmR1cmF0aW9uY2hhbmdlIDogKCdzZWxmIHQsIG1lZGlhRXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgd3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2Qgb25lbXB0aWVkIDogKCdzZWxmIHQsIG1lZGlhRXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgd3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2Qgb25lbmRlZCA6ICgnc2VsZiB0LCBtZWRpYUV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9ubG9hZGVkZGF0YSA6ICgnc2VsZiB0LCBtZWRpYUV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9ubG9hZGVkbWV0YWRhdGEgOiAoJ3NlbGYgdCwgbWVkaWFFdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbmxvYWRzdGFydCA6ICgnc2VsZiB0LCBtZWRpYUV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9ucGF1c2UgOiAoJ3NlbGYgdCwgbWVkaWFFdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbnBsYXkgOiAoJ3NlbGYgdCwgbWVkaWFFdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbnBsYXlpbmcgOiAoJ3NlbGYgdCwgbWVkaWFFdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbnJhdGVjaGFuZ2UgOiAoJ3NlbGYgdCwgbWVkaWFFdmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbnNlZWtlZCA6ICgnc2VsZiB0LCBtZWRpYUV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9uc2Vla2luZyA6ICgnc2VsZiB0LCBtZWRpYUV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9uc3RhbGxlZCA6ICgnc2VsZiB0LCBtZWRpYUV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9uc3VzcGVuZCA6ICgnc2VsZiB0LCBtZWRpYUV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9udm9sdW1lY2hhbmdlIDogKCdzZWxmIHQsIG1lZGlhRXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgd3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2Qgb253YWl0aW5nIDogKCdzZWxmIHQsIG1lZGlhRXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgd3JpdGVvbmx5X3Byb3BcbmVuZFxuXG5jbGFzcyB0eXBlIGF1ZGlvRWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IG1lZGlhRWxlbWVudFxuZW5kXG5cbmNsYXNzIHR5cGUgdmlkZW9FbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgbWVkaWFFbGVtZW50XG5lbmRcblxudHlwZSBjb250ZXh0ID0ganNfc3RyaW5nIHRcblxubGV0IF8yZF8gPSBKcy5zdHJpbmcgXCIyZFwiXG5cbnR5cGUgY2FudmFzUGF0dGVyblxuXG5jbGFzcyB0eXBlIGNhbnZhc0VsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgbWV0aG9kIHdpZHRoIDogaW50IHByb3BcblxuICBtZXRob2QgaGVpZ2h0IDogaW50IHByb3BcblxuICBtZXRob2QgdG9EYXRhVVJMIDoganNfc3RyaW5nIHQgbWV0aFxuXG4gIG1ldGhvZCB0b0RhdGFVUkxfdHlwZSA6IGpzX3N0cmluZyB0IC0+IGpzX3N0cmluZyB0IG1ldGhcblxuICBtZXRob2QgdG9EYXRhVVJMX3R5cGVfY29tcHJlc3Npb24gOiBqc19zdHJpbmcgdCAtPiBudW1iZXJfdCAtPiBqc19zdHJpbmcgdCBtZXRoXG5cbiAgbWV0aG9kIGdldENvbnRleHQgOiBqc19zdHJpbmcgdCAtPiBjYW52YXNSZW5kZXJpbmdDb250ZXh0MkQgdCBtZXRoXG5lbmRcblxuYW5kIGNhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCA9IG9iamVjdFxuICBtZXRob2QgY2FudmFzIDogY2FudmFzRWxlbWVudCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgc2F2ZSA6IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCByZXN0b3JlIDogdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHNjYWxlIDogbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHJvdGF0ZSA6IG51bWJlcl90IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB0cmFuc2xhdGUgOiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdHJhbnNmb3JtIDpcbiAgICBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgc2V0VHJhbnNmb3JtIDpcbiAgICBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgZ2xvYmFsQWxwaGEgOiBudW1iZXJfdCBwcm9wXG5cbiAgbWV0aG9kIGdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2Qgc3Ryb2tlU3R5bGUgOiBqc19zdHJpbmcgdCB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBzdHJva2VTdHlsZV9ncmFkaWVudCA6IGNhbnZhc0dyYWRpZW50IHQgd3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2Qgc3Ryb2tlU3R5bGVfcGF0dGVybiA6IGNhbnZhc1BhdHRlcm4gdCB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBmaWxsU3R5bGUgOiBqc19zdHJpbmcgdCB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBmaWxsU3R5bGVfZ3JhZGllbnQgOiBjYW52YXNHcmFkaWVudCB0IHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIGZpbGxTdHlsZV9wYXR0ZXJuIDogY2FudmFzUGF0dGVybiB0IHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIGNyZWF0ZUxpbmVhckdyYWRpZW50IDpcbiAgICBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBjYW52YXNHcmFkaWVudCB0IG1ldGhcblxuICBtZXRob2QgY3JlYXRlUmFkaWFsR3JhZGllbnQgOlxuICAgICAgIG51bWJlcl90XG4gICAgLT4gbnVtYmVyX3RcbiAgICAtPiBudW1iZXJfdFxuICAgIC0+IG51bWJlcl90XG4gICAgLT4gbnVtYmVyX3RcbiAgICAtPiBudW1iZXJfdFxuICAgIC0+IGNhbnZhc0dyYWRpZW50IHQgbWV0aFxuXG4gIG1ldGhvZCBjcmVhdGVQYXR0ZXJuIDogaW1hZ2VFbGVtZW50IHQgLT4ganNfc3RyaW5nIHQgLT4gY2FudmFzUGF0dGVybiB0IG1ldGhcblxuICBtZXRob2QgY3JlYXRlUGF0dGVybl9mcm9tQ2FudmFzIDogY2FudmFzRWxlbWVudCB0IC0+IGpzX3N0cmluZyB0IC0+IGNhbnZhc1BhdHRlcm4gdCBtZXRoXG5cbiAgbWV0aG9kIGNyZWF0ZVBhdHRlcm5fZnJvbVZpZGVvIDogdmlkZW9FbGVtZW50IHQgLT4ganNfc3RyaW5nIHQgLT4gY2FudmFzUGF0dGVybiB0IG1ldGhcblxuICBtZXRob2QgbGluZVdpZHRoIDogbnVtYmVyX3QgcHJvcFxuXG4gIG1ldGhvZCBsaW5lQ2FwIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBsaW5lSm9pbiA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgbWl0ZXJMaW1pdCA6IG51bWJlcl90IHByb3BcblxuICBtZXRob2Qgc2hhZG93T2Zmc2V0WCA6IG51bWJlcl90IHByb3BcblxuICBtZXRob2Qgc2hhZG93T2Zmc2V0WSA6IG51bWJlcl90IHByb3BcblxuICBtZXRob2Qgc2hhZG93Qmx1ciA6IG51bWJlcl90IHByb3BcblxuICBtZXRob2Qgc2hhZG93Q29sb3IgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGNsZWFyUmVjdCA6IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBmaWxsUmVjdCA6IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBzdHJva2VSZWN0IDogbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGJlZ2luUGF0aCA6IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBjbG9zZVBhdGggOiB1bml0IG1ldGhcblxuICBtZXRob2QgbW92ZVRvIDogbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGxpbmVUbyA6IG51bWJlcl90IC0+IG51bWJlcl90IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBxdWFkcmF0aWNDdXJ2ZVRvIDogbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGJlemllckN1cnZlVG8gOlxuICAgIG51bWJlcl90IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBhcmNUbyA6IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCByZWN0IDogbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGFyYyA6XG4gICAgbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gYm9vbCB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBlbGxpcHNlIDpcbiAgICAgICBudW1iZXJfdFxuICAgIC0+IG51bWJlcl90XG4gICAgLT4gbnVtYmVyX3RcbiAgICAtPiBudW1iZXJfdFxuICAgIC0+IG51bWJlcl90XG4gICAgLT4gbnVtYmVyX3RcbiAgICAtPiBudW1iZXJfdFxuICAgIC0+IGJvb2wgdFxuICAgIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBmaWxsIDogdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHN0cm9rZSA6IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBjbGlwIDogdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGlzUG9pbnRJblBhdGggOiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBib29sIHQgbWV0aFxuXG4gIG1ldGhvZCBkcmF3Rm9jdXNSaW5nIDogI2VsZW1lbnQgdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBib29sIHQgLT4gYm9vbCB0IG1ldGhcblxuICBtZXRob2QgZm9udCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgdGV4dEFsaWduIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCB0ZXh0QmFzZWxpbmUgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGZpbGxUZXh0IDoganNfc3RyaW5nIHQgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGZpbGxUZXh0X3dpdGhXaWR0aCA6IGpzX3N0cmluZyB0IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBzdHJva2VUZXh0IDoganNfc3RyaW5nIHQgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHN0cm9rZVRleHRfd2l0aFdpZHRoIDpcbiAgICBqc19zdHJpbmcgdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgbWVhc3VyZVRleHQgOiBqc19zdHJpbmcgdCAtPiB0ZXh0TWV0cmljcyB0IG1ldGhcblxuICBtZXRob2QgZHJhd0ltYWdlIDogaW1hZ2VFbGVtZW50IHQgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGRyYXdJbWFnZV93aXRoU2l6ZSA6XG4gICAgaW1hZ2VFbGVtZW50IHQgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGRyYXdJbWFnZV9mdWxsIDpcbiAgICAgICBpbWFnZUVsZW1lbnQgdFxuICAgIC0+IG51bWJlcl90XG4gICAgLT4gbnVtYmVyX3RcbiAgICAtPiBudW1iZXJfdFxuICAgIC0+IG51bWJlcl90XG4gICAgLT4gbnVtYmVyX3RcbiAgICAtPiBudW1iZXJfdFxuICAgIC0+IG51bWJlcl90XG4gICAgLT4gbnVtYmVyX3RcbiAgICAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgZHJhd0ltYWdlX2Zyb21DYW52YXMgOiBjYW52YXNFbGVtZW50IHQgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGRyYXdJbWFnZV9mcm9tQ2FudmFzV2l0aFNpemUgOlxuICAgIGNhbnZhc0VsZW1lbnQgdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgZHJhd0ltYWdlX2Z1bGxGcm9tQ2FudmFzIDpcbiAgICAgICBjYW52YXNFbGVtZW50IHRcbiAgICAtPiBudW1iZXJfdFxuICAgIC0+IG51bWJlcl90XG4gICAgLT4gbnVtYmVyX3RcbiAgICAtPiBudW1iZXJfdFxuICAgIC0+IG51bWJlcl90XG4gICAgLT4gbnVtYmVyX3RcbiAgICAtPiBudW1iZXJfdFxuICAgIC0+IG51bWJlcl90XG4gICAgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGRyYXdJbWFnZV9mcm9tVmlkZW9XaXRoVmlkZW8gOlxuICAgIHZpZGVvRWxlbWVudCB0IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBkcmF3SW1hZ2VfZnJvbVZpZGVvV2l0aFNpemUgOlxuICAgIHZpZGVvRWxlbWVudCB0IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBkcmF3SW1hZ2VfZnVsbEZyb21WaWRlbyA6XG4gICAgICAgdmlkZW9FbGVtZW50IHRcbiAgICAtPiBudW1iZXJfdFxuICAgIC0+IG51bWJlcl90XG4gICAgLT4gbnVtYmVyX3RcbiAgICAtPiBudW1iZXJfdFxuICAgIC0+IG51bWJlcl90XG4gICAgLT4gbnVtYmVyX3RcbiAgICAtPiBudW1iZXJfdFxuICAgIC0+IG51bWJlcl90XG4gICAgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGNyZWF0ZUltYWdlRGF0YSA6IGludCAtPiBpbnQgLT4gaW1hZ2VEYXRhIHQgbWV0aFxuXG4gIG1ldGhvZCBnZXRJbWFnZURhdGEgOiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBpbWFnZURhdGEgdCBtZXRoXG5cbiAgbWV0aG9kIHB1dEltYWdlRGF0YSA6IGltYWdlRGF0YSB0IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IHVuaXQgbWV0aFxuZW5kXG5cbmFuZCBjYW52YXNHcmFkaWVudCA9IG9iamVjdFxuICBtZXRob2QgYWRkQ29sb3JTdG9wIDogbnVtYmVyX3QgLT4ganNfc3RyaW5nIHQgLT4gdW5pdCBtZXRoXG5lbmRcblxuYW5kIHRleHRNZXRyaWNzID0gb2JqZWN0XG4gIG1ldGhvZCB3aWR0aCA6IG51bWJlcl90IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG5hbmQgaW1hZ2VEYXRhID0gb2JqZWN0XG4gIG1ldGhvZCB3aWR0aCA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGhlaWdodCA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGRhdGEgOiBjYW52YXNQaXhlbEFycmF5IHQgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbmFuZCBjYW52YXNQaXhlbEFycmF5ID0gb2JqZWN0XG4gIG1ldGhvZCBsZW5ndGggOiBpbnQgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbmV4dGVybmFsIHBpeGVsX2dldCA6IGNhbnZhc1BpeGVsQXJyYXkgdCAtPiBpbnQgLT4gaW50ID0gXCJjYW1sX2pzX2dldFwiXG5cbmV4dGVybmFsIHBpeGVsX3NldCA6IGNhbnZhc1BpeGVsQXJyYXkgdCAtPiBpbnQgLT4gaW50IC0+IHVuaXQgPSBcImNhbWxfanNfc2V0XCJcblxuY2xhc3MgdHlwZSByYW5nZSA9IG9iamVjdFxuICBtZXRob2QgY29sbGFwc2VkIDogYm9vbCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgc3RhcnRPZmZzZXQgOiBpbnQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBlbmRPZmZzZXQgOiBpbnQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBzdGFydENvbnRhaW5lciA6IERvbS5ub2RlIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBlbmRDb250YWluZXIgOiBEb20ubm9kZSB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgc2V0U3RhcnQgOiBEb20ubm9kZSB0IC0+IGludCAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgc2V0RW5kIDogRG9tLm5vZGUgdCAtPiBpbnQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHNldFN0YXJ0QmVmb3JlIDogRG9tLm5vZGUgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgc2V0RW5kQmVmb3JlIDogRG9tLm5vZGUgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgc2V0U3RhcnRBZnRlciA6IERvbS5ub2RlIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHNldEVuZEFmdGVyIDogRG9tLm5vZGUgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgc2VsZWN0Tm9kZSA6IERvbS5ub2RlIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHNlbGVjdE5vZGVDb250ZW50cyA6IERvbS5ub2RlIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGNvbGxhcHNlIDogYm9vbCB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBjbG9uZUNvbnRlbnRzIDogRG9tLmRvY3VtZW50RnJhZ21lbnQgdCBtZXRoXG5cbiAgbWV0aG9kIGV4dHJhY3RDb250ZW50cyA6IERvbS5kb2N1bWVudEZyYWdtZW50IHQgbWV0aFxuXG4gIG1ldGhvZCBkZWxldGVDb250ZW50cyA6IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBpbnNlcnROb2RlIDogRG9tLm5vZGUgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgc3Vycm91bmRDb250ZW50cyA6IERvbS5ub2RlIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGNsb25lUmFuZ2UgOiByYW5nZSB0IG1ldGhcblxuICBtZXRob2QgdG9TdHJpbmcgOiBqc19zdHJpbmcgdCBtZXRoXG5lbmRcblxuKCoqIEluZm9ybWF0aW9uIG9uIGN1cnJlbnQgc2VsZWN0aW9uICopXG5jbGFzcyB0eXBlIHNlbGVjdGlvbiA9IG9iamVjdFxuICBtZXRob2QgYW5jaG9yTm9kZSA6IERvbS5ub2RlIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBhbmNob3JPZmZzZXQgOiBpbnQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBmb2N1c05vZGUgOiBEb20ubm9kZSB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZm9jdXNPZmZzZXQgOiBpbnQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBpc0NvbGxhcHNlZCA6IGJvb2wgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHJhbmdlQ291bnQgOiBpbnQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBnZXRSYW5nZUF0IDogaW50IC0+IHJhbmdlIHQgbWV0aFxuXG4gIG1ldGhvZCBjb2xsYXBzZSA6IGJvb2wgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgZXh0ZW5kIDogRG9tLm5vZGUgdCAtPiBpbnQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIG1vZGlmeSA6IGpzX3N0cmluZyB0IC0+IGpzX3N0cmluZyB0IC0+IGpzX3N0cmluZyB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBjb2xsYXBzZVRvU3RhcnQgOiB1bml0IG1ldGhcblxuICBtZXRob2QgY29sbGFwc2VUb0VuZCA6IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBzZWxlY3RBbGxDaGlsZHJlbiA6IERvbS5ub2RlIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGFkZFJhbmdlIDogcmFuZ2UgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgcmVtb3ZlUmFuZ2UgOiByYW5nZSB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCByZW1vdmVBbGxSYW5nZXMgOiB1bml0IG1ldGhcblxuICBtZXRob2QgZGVsZXRlRnJvbURvY3VtZW50IDogdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGNvbnRhaW5zTm9kZSA6IERvbS5ub2RlIHQgLT4gYm9vbCB0IC0+IGJvb2wgdCBtZXRoXG5cbiAgbWV0aG9kIHRvU3RyaW5nIDoganNfc3RyaW5nIHQgbWV0aFxuZW5kXG5cbmNsYXNzIHR5cGUgZG9jdW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBbZWxlbWVudF0gRG9tLmRvY3VtZW50XG5cbiAgaW5oZXJpdCBub2RlU2VsZWN0b3JcblxuICBpbmhlcml0IGV2ZW50VGFyZ2V0XG5cbiAgbWV0aG9kIHRpdGxlIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCByZWZlcnJlciA6IGpzX3N0cmluZyB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZG9tYWluIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBfVVJMIDoganNfc3RyaW5nIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBoZWFkIDogaGVhZEVsZW1lbnQgdCBwcm9wXG5cbiAgbWV0aG9kIGJvZHkgOiBib2R5RWxlbWVudCB0IHByb3BcblxuICBtZXRob2QgZG9jdW1lbnRFbGVtZW50IDogaHRtbEVsZW1lbnQgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGltYWdlcyA6IGltYWdlRWxlbWVudCBjb2xsZWN0aW9uIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBhcHBsZXRzIDogZWxlbWVudCBjb2xsZWN0aW9uIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBsaW5rcyA6IGVsZW1lbnQgY29sbGVjdGlvbiB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZm9ybXMgOiBmb3JtRWxlbWVudCBjb2xsZWN0aW9uIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBhbmNob3JzIDogZWxlbWVudCBjb2xsZWN0aW9uIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBjb29raWUgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGRlc2lnbk1vZGUgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIG9wZW5fIDogdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGNsb3NlIDogdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHdyaXRlIDoganNfc3RyaW5nIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGV4ZWNDb21tYW5kIDoganNfc3RyaW5nIHQgLT4gYm9vbCB0IC0+IGpzX3N0cmluZyB0IG9wdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgY3JlYXRlUmFuZ2UgOiByYW5nZSB0IG1ldGhcblxuICBtZXRob2QgcmVhZHlTdGF0ZSA6IGpzX3N0cmluZyB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSA6IGpzX3N0cmluZyB0IC0+IGVsZW1lbnQgRG9tLm5vZGVMaXN0IHQgbWV0aFxuXG4gIG1ldGhvZCBnZXRFbGVtZW50c0J5TmFtZSA6IGpzX3N0cmluZyB0IC0+IGVsZW1lbnQgRG9tLm5vZGVMaXN0IHQgbWV0aFxuXG4gIG1ldGhvZCBhY3RpdmVFbGVtZW50IDogZWxlbWVudCB0IG9wdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGhpZGRlbiA6IGJvb2wgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIG9uZnVsbHNjcmVlbmNoYW5nZSA6IChkb2N1bWVudCB0LCBldmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbndlYmtpdGZ1bGxzY3JlZW5jaGFuZ2UgOiAoZG9jdW1lbnQgdCwgZXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgd3JpdGVvbmx5X3Byb3BcblxuICBpbmhlcml0IGV2ZW50VGFyZ2V0XG5lbmRcblxudHlwZSBpbnRlcnZhbF9pZFxuXG50eXBlIHRpbWVvdXRfaWRcblxudHlwZSBhbmltYXRpb25fZnJhbWVfcmVxdWVzdF9pZFxuXG5jbGFzcyB0eXBlIGxvY2F0aW9uID0gb2JqZWN0XG4gIG1ldGhvZCBocmVmIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBwcm90b2NvbCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgaG9zdCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgaG9zdG5hbWUgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIG9yaWdpbiA6IGpzX3N0cmluZyB0IG9wdGRlZiByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHBvcnQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHBhdGhuYW1lIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBzZWFyY2ggOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGhhc2ggOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGFzc2lnbiA6IGpzX3N0cmluZyB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCByZXBsYWNlIDoganNfc3RyaW5nIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHJlbG9hZCA6IHVuaXQgbWV0aFxuZW5kXG5cbmxldCBsb2NhdGlvbl9vcmlnaW4gKGxvYyA6IGxvY2F0aW9uIHQpID1cbiAgT3B0ZGVmLmNhc2VcbiAgICBsb2MjIy5vcmlnaW5cbiAgICAoZnVuICgpIC0+XG4gICAgICBsZXQgcHJvdG9jb2wgPSBsb2MjIy5wcm90b2NvbCBpblxuICAgICAgbGV0IGhvc3RuYW1lID0gbG9jIyMuaG9zdG5hbWUgaW5cbiAgICAgIGxldCBwb3J0ID0gbG9jIyMucG9ydCBpblxuICAgICAgaWYgcHJvdG9jb2wjIy5sZW5ndGggPSAwICYmIGhvc3RuYW1lIyMubGVuZ3RoID0gMFxuICAgICAgdGhlbiBKcy5zdHJpbmcgXCJcIlxuICAgICAgZWxzZVxuICAgICAgICBsZXQgb3JpZ2luID0gcHJvdG9jb2wjI2NvbmNhdF8yIChKcy5zdHJpbmcgXCIvL1wiKSBob3N0bmFtZSBpblxuICAgICAgICBpZiBwb3J0IyMubGVuZ3RoID4gMCB0aGVuIG9yaWdpbiMjY29uY2F0XzIgKEpzLnN0cmluZyBcIjpcIikgbG9jIyMucG9ydCBlbHNlIG9yaWdpbilcbiAgICAoZnVuIG8gLT4gbylcblxuY2xhc3MgdHlwZSBoaXN0b3J5ID0gb2JqZWN0XG4gIG1ldGhvZCBsZW5ndGggOiBpbnQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBzdGF0ZSA6IEpzLlVuc2FmZS5hbnkgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBnbyA6IGludCBvcHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGJhY2sgOiB1bml0IG1ldGhcblxuICBtZXRob2QgZm9yd2FyZCA6IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBwdXNoU3RhdGUgOiAnYS4gJ2EgLT4ganNfc3RyaW5nIHQgLT4ganNfc3RyaW5nIHQgb3B0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCByZXBsYWNlU3RhdGUgOiAnYS4gJ2EgLT4ganNfc3RyaW5nIHQgLT4ganNfc3RyaW5nIHQgb3B0IC0+IHVuaXQgbWV0aFxuZW5kXG5cbmNsYXNzIHR5cGUgdW5kb01hbmFnZXIgPSBvYmplY3QgZW5kXG5cbmNsYXNzIHR5cGUgbmF2aWdhdG9yID0gb2JqZWN0XG4gIG1ldGhvZCBhcHBDb2RlTmFtZSA6IGpzX3N0cmluZyB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgYXBwTmFtZSA6IGpzX3N0cmluZyB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgYXBwVmVyc2lvbiA6IGpzX3N0cmluZyB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgY29va2llRW5hYmxlZCA6IGJvb2wgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIG9uTGluZSA6IGJvb2wgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHBsYXRmb3JtIDoganNfc3RyaW5nIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCB2ZW5kb3IgOiBqc19zdHJpbmcgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHVzZXJBZ2VudCA6IGpzX3N0cmluZyB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgbGFuZ3VhZ2UgOiBqc19zdHJpbmcgdCBvcHRkZWYgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCB1c2VyTGFuZ3VhZ2UgOiBqc19zdHJpbmcgdCBvcHRkZWYgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBtYXhUb3VjaFBvaW50cyA6IGludCByZWFkb25seV9wcm9wXG5lbmRcblxuY2xhc3MgdHlwZSBzY3JlZW4gPSBvYmplY3RcbiAgbWV0aG9kIHdpZHRoIDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgaGVpZ2h0IDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgYXZhaWxXaWR0aCA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGF2YWlsSGVpZ2h0IDogaW50IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG5jbGFzcyB0eXBlIGFwcGxpY2F0aW9uQ2FjaGUgPSBvYmplY3RcbiAgbWV0aG9kIHN0YXR1cyA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHVwZGF0ZSA6IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBhYm9ydCA6IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBzd2FwQ2FjaGUgOiB1bml0IG1ldGhcblxuICBtZXRob2Qgb25jaGVja2luZyA6IChhcHBsaWNhdGlvbkNhY2hlIHQsIGV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHByb3BcblxuICBtZXRob2Qgb25lcnJvciA6IChhcHBsaWNhdGlvbkNhY2hlIHQsIGV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHByb3BcblxuICBtZXRob2Qgb25ub3VwZGF0ZSA6IChhcHBsaWNhdGlvbkNhY2hlIHQsIGV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHByb3BcblxuICBtZXRob2Qgb25kb3dubG9hZGluZyA6IChhcHBsaWNhdGlvbkNhY2hlIHQsIGV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHByb3BcblxuICBtZXRob2Qgb25wcm9ncmVzcyA6IChhcHBsaWNhdGlvbkNhY2hlIHQsIGV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHByb3BcblxuICBtZXRob2Qgb251cGRhdGVyZWFkeSA6IChhcHBsaWNhdGlvbkNhY2hlIHQsIGV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHByb3BcblxuICBtZXRob2Qgb25jYWNoZWQgOiAoYXBwbGljYXRpb25DYWNoZSB0LCBldmVudCB0KSBldmVudF9saXN0ZW5lciBwcm9wXG5cbiAgbWV0aG9kIG9ub2Jzb2xldGUgOiAoYXBwbGljYXRpb25DYWNoZSB0LCBldmVudCB0KSBldmVudF9saXN0ZW5lciBwcm9wXG5cbiAgaW5oZXJpdCBldmVudFRhcmdldFxuZW5kXG5cbmNsYXNzIHR5cGUgX1VSTCA9IG9iamVjdFxuICBtZXRob2QgY3JlYXRlT2JqZWN0VVJMIDogI0ZpbGUuYmxvYiB0IC0+IGpzX3N0cmluZyB0IG1ldGhcblxuICBtZXRob2QgcmV2b2tlT2JqZWN0VVJMIDoganNfc3RyaW5nIHQgLT4gdW5pdCBtZXRoXG5lbmRcblxuY2xhc3MgdHlwZSB3aW5kb3cgPSBvYmplY3RcbiAgaW5oZXJpdCBldmVudFRhcmdldFxuXG4gIG1ldGhvZCBkb2N1bWVudCA6IGRvY3VtZW50IHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBhcHBsaWNhdGlvbkNhY2hlIDogYXBwbGljYXRpb25DYWNoZSB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgbmFtZSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgbG9jYXRpb24gOiBsb2NhdGlvbiB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgaGlzdG9yeSA6IGhpc3RvcnkgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHVuZG9NYW5hZ2VyIDogdW5kb01hbmFnZXIgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIG5hdmlnYXRvciA6IG5hdmlnYXRvciB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZ2V0U2VsZWN0aW9uIDogc2VsZWN0aW9uIHQgbWV0aFxuXG4gIG1ldGhvZCBjbG9zZSA6IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBjbG9zZWQgOiBib29sIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBzdG9wIDogdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGZvY3VzIDogdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGJsdXIgOiB1bml0IG1ldGhcblxuICBtZXRob2Qgc2Nyb2xsIDogaW50IC0+IGludCAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgc2Nyb2xsQnkgOiBpbnQgLT4gaW50IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBzZXNzaW9uU3RvcmFnZSA6IHN0b3JhZ2UgdCBvcHRkZWYgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBsb2NhbFN0b3JhZ2UgOiBzdG9yYWdlIHQgb3B0ZGVmIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgdG9wIDogd2luZG93IHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBwYXJlbnQgOiB3aW5kb3cgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGZyYW1lRWxlbWVudCA6IGVsZW1lbnQgdCBvcHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvcGVuXyA6IGpzX3N0cmluZyB0IC0+IGpzX3N0cmluZyB0IC0+IGpzX3N0cmluZyB0IG9wdCAtPiB3aW5kb3cgdCBvcHQgbWV0aFxuXG4gIG1ldGhvZCBhbGVydCA6IGpzX3N0cmluZyB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBjb25maXJtIDoganNfc3RyaW5nIHQgLT4gYm9vbCB0IG1ldGhcblxuICBtZXRob2QgcHJvbXB0IDoganNfc3RyaW5nIHQgLT4ganNfc3RyaW5nIHQgLT4ganNfc3RyaW5nIHQgb3B0IG1ldGhcblxuICBtZXRob2QgcHJpbnQgOiB1bml0IG1ldGhcblxuICBtZXRob2Qgc2V0SW50ZXJ2YWwgOiAodW5pdCAtPiB1bml0KSBKcy5jYWxsYmFjayAtPiBudW1iZXJfdCAtPiBpbnRlcnZhbF9pZCBtZXRoXG5cbiAgbWV0aG9kIGNsZWFySW50ZXJ2YWwgOiBpbnRlcnZhbF9pZCAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgc2V0VGltZW91dCA6ICh1bml0IC0+IHVuaXQpIEpzLmNhbGxiYWNrIC0+IG51bWJlcl90IC0+IHRpbWVvdXRfaWQgbWV0aFxuXG4gIG1ldGhvZCBjbGVhclRpbWVvdXQgOiB0aW1lb3V0X2lkIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgOlxuICAgIChudW1iZXJfdCAtPiB1bml0KSBKcy5jYWxsYmFjayAtPiBhbmltYXRpb25fZnJhbWVfcmVxdWVzdF9pZCBtZXRoXG5cbiAgbWV0aG9kIGNhbmNlbEFuaW1hdGlvbkZyYW1lIDogYW5pbWF0aW9uX2ZyYW1lX3JlcXVlc3RfaWQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHNjcmVlbiA6IHNjcmVlbiB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgaW5uZXJXaWR0aCA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGlubmVySGVpZ2h0IDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgb3V0ZXJXaWR0aCA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIG91dGVySGVpZ2h0IDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZ2V0Q29tcHV0ZWRTdHlsZSA6ICNlbGVtZW50IHQgLT4gY3NzU3R5bGVEZWNsYXJhdGlvbiB0IG1ldGhcblxuICBtZXRob2QgZ2V0Q29tcHV0ZWRTdHlsZV9wc2V1ZG9FbHQgOlxuICAgICNlbGVtZW50IHQgLT4ganNfc3RyaW5nIHQgLT4gY3NzU3R5bGVEZWNsYXJhdGlvbiB0IG1ldGhcblxuICBtZXRob2QgYXRvYiA6IGpzX3N0cmluZyB0IC0+IGpzX3N0cmluZyB0IG1ldGhcblxuICBtZXRob2QgYnRvYSA6IGpzX3N0cmluZyB0IC0+IGpzX3N0cmluZyB0IG1ldGhcblxuICBtZXRob2Qgb25sb2FkIDogKHdpbmRvdyB0LCBldmVudCB0KSBldmVudF9saXN0ZW5lciBwcm9wXG5cbiAgbWV0aG9kIG9udW5sb2FkIDogKHdpbmRvdyB0LCBldmVudCB0KSBldmVudF9saXN0ZW5lciBwcm9wXG5cbiAgbWV0aG9kIG9uYmVmb3JldW5sb2FkIDogKHdpbmRvdyB0LCBldmVudCB0KSBldmVudF9saXN0ZW5lciBwcm9wXG5cbiAgbWV0aG9kIG9uYmx1ciA6ICh3aW5kb3cgdCwgZm9jdXNFdmVudCB0KSBldmVudF9saXN0ZW5lciBwcm9wXG5cbiAgbWV0aG9kIG9uZm9jdXMgOiAod2luZG93IHQsIGZvY3VzRXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgcHJvcFxuXG4gIG1ldGhvZCBvbnJlc2l6ZSA6ICh3aW5kb3cgdCwgZXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgcHJvcFxuXG4gIG1ldGhvZCBvbm9yaWVudGF0aW9uY2hhbmdlIDogKHdpbmRvdyB0LCBldmVudCB0KSBldmVudF9saXN0ZW5lciBwcm9wXG5cbiAgbWV0aG9kIG9ucG9wc3RhdGUgOiAod2luZG93IHQsIHBvcFN0YXRlRXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgcHJvcFxuXG4gIG1ldGhvZCBvbmhhc2hjaGFuZ2UgOiAod2luZG93IHQsIGhhc2hDaGFuZ2VFdmVudCB0KSBldmVudF9saXN0ZW5lciBwcm9wXG5cbiAgbWV0aG9kIG9ub25saW5lIDogKHdpbmRvdyB0LCBldmVudCB0KSBldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbm9mZmxpbmUgOiAod2luZG93IHQsIGV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIF9VUkwgOiBfVVJMIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBkZXZpY2VQaXhlbFJhdGlvIDogbnVtYmVyX3QgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbmxldCB3aW5kb3cgOiB3aW5kb3cgdCA9IEpzLlVuc2FmZS5nbG9iYWxcblxuKCogVGhlIHRvcGxldmVsIG9iamVjdCAqKVxuXG5sZXQgZG9jdW1lbnQgPSB3aW5kb3cjIy5kb2N1bWVudFxuXG5sZXQgZ2V0RWxlbWVudEJ5SWQgaWQgPVxuICBKcy5PcHQuY2FzZVxuICAgIChkb2N1bWVudCMjZ2V0RWxlbWVudEJ5SWQgKEpzLnN0cmluZyBpZCkpXG4gICAgKGZ1biAoKSAtPiByYWlzZSBOb3RfZm91bmQpXG4gICAgKGZ1biBwbm9kZSAtPiBwbm9kZSlcblxubGV0IGdldEVsZW1lbnRCeUlkX2V4biBpZCA9XG4gIEpzLk9wdC5jYXNlXG4gICAgKGRvY3VtZW50IyNnZXRFbGVtZW50QnlJZCAoSnMuc3RyaW5nIGlkKSlcbiAgICAoZnVuICgpIC0+IGZhaWx3aXRoIChQcmludGYuc3ByaW50ZiBcImdldEVsZW1lbnRCeUlkX2V4bjogJVMgbm90IGZvdW5kXCIgaWQpKVxuICAgIChmdW4gcG5vZGUgLT4gcG5vZGUpXG5cbmxldCBnZXRFbGVtZW50QnlJZF9vcHQgaWQgPSBKcy5PcHQudG9fb3B0aW9uIChkb2N1bWVudCMjZ2V0RWxlbWVudEJ5SWQgKEpzLnN0cmluZyBpZCkpXG5cbmxldCBnZXRFbGVtZW50QnlJZF9jb2VyY2UgaWQgY29lcmNlID1cbiAgSnMuT3B0LmNhc2VcbiAgICAoZG9jdW1lbnQjI2dldEVsZW1lbnRCeUlkIChKcy5zdHJpbmcgaWQpKVxuICAgIChmdW4gKCkgLT4gTm9uZSlcbiAgICAoZnVuIGUgLT4gSnMuT3B0LnRvX29wdGlvbiAoY29lcmNlIGUpKVxuXG4oKioqKilcblxuY2xhc3MgdHlwZSBmcmFtZVNldEVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgbWV0aG9kIGNvbHMgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHJvd3MgOiBqc19zdHJpbmcgdCBwcm9wXG5lbmRcblxuY2xhc3MgdHlwZSBmcmFtZUVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgbWV0aG9kIGZyYW1lQm9yZGVyIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBsb25nRGVzYyA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgbWFyZ2luSGVpZ2h0IDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBtYXJnaW5XaWR0aCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgbmFtZSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2Qgbm9SZXNpemUgOiBib29sIHQgcHJvcFxuXG4gIG1ldGhvZCBzY3JvbGxpbmcgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHNyYyA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgY29udGVudERvY3VtZW50IDogZG9jdW1lbnQgdCBvcHQgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbmNsYXNzIHR5cGUgaUZyYW1lRWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBtZXRob2QgZnJhbWVCb3JkZXIgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGhlaWdodCA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2Qgd2lkdGggOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGxvbmdEZXNjIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBtYXJnaW5IZWlnaHQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIG1hcmdpbldpZHRoIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBuYW1lIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBzY3JvbGxpbmcgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHNyYyA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgY29udGVudERvY3VtZW50IDogZG9jdW1lbnQgdCBvcHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBjb250ZW50V2luZG93IDogd2luZG93IHQgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbigqKioqKVxuXG4oKlhYWCBTaG91bGQgcHJvdmlkZSBjcmVhdGlvbiBmdW5jdGlvbnMgYSBsYSBsYWJsZ3RrLi4uICopXG5cbmxldCBvcHRfaXRlciB4IGYgPVxuICBtYXRjaCB4IHdpdGhcbiAgfCBOb25lIC0+ICgpXG4gIHwgU29tZSB2IC0+IGYgdlxuXG5sZXQgY3JlYXRlRWxlbWVudCAoZG9jIDogZG9jdW1lbnQgdCkgbmFtZSA9IGRvYyMjY3JlYXRlRWxlbWVudCAoSnMuc3RyaW5nIG5hbWUpXG5cbmxldCB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBuYW1lID0gSnMuVW5zYWZlLmNvZXJjZSAoY3JlYXRlRWxlbWVudCBkb2MgbmFtZSlcblxubGV0IGNyZWF0ZUVsZW1lbnRTeW50YXggPSByZWYgYFVua25vd25cblxubGV0IHJlYyB1bnNhZmVDcmVhdGVFbGVtZW50RXggP190eXBlID9uYW1lIGRvYyBlbHQgPVxuICBpZiBQb2x5LihfdHlwZSA9IE5vbmUpICYmIFBvbHkuKG5hbWUgPSBOb25lKVxuICB0aGVuIEpzLlVuc2FmZS5jb2VyY2UgKGNyZWF0ZUVsZW1lbnQgZG9jIGVsdClcbiAgZWxzZVxuICAgIG1hdGNoICFjcmVhdGVFbGVtZW50U3ludGF4IHdpdGhcbiAgICB8IGBTdGFuZGFyZCAtPlxuICAgICAgICBsZXQgcmVzID0gSnMuVW5zYWZlLmNvZXJjZSAoY3JlYXRlRWxlbWVudCBkb2MgZWx0KSBpblxuICAgICAgICBvcHRfaXRlciBfdHlwZSAoZnVuIHQgLT4gcmVzIyMuX3R5cGUgOj0gdCk7XG4gICAgICAgIG9wdF9pdGVyIG5hbWUgKGZ1biBuIC0+IHJlcyMjLm5hbWUgOj0gbik7XG4gICAgICAgIHJlc1xuICAgIHwgYEV4dGVuZGVkIC0+XG4gICAgICAgIGxldCBhID0gbmV3JWpzIEpzLmFycmF5X2VtcHR5IGluXG4gICAgICAgIGlnbm9yZSAoYSMjcHVzaF8yIChKcy5zdHJpbmcgXCI8XCIpIChKcy5zdHJpbmcgZWx0KSk7XG4gICAgICAgIG9wdF9pdGVyIF90eXBlIChmdW4gdCAtPlxuICAgICAgICAgICAgaWdub3JlIChhIyNwdXNoXzMgKEpzLnN0cmluZyBcIiB0eXBlPVxcXCJcIikgKGh0bWxfZXNjYXBlIHQpIChKcy5zdHJpbmcgXCJcXFwiXCIpKSk7XG4gICAgICAgIG9wdF9pdGVyIG5hbWUgKGZ1biBuIC0+XG4gICAgICAgICAgICBpZ25vcmUgKGEjI3B1c2hfMyAoSnMuc3RyaW5nIFwiIG5hbWU9XFxcIlwiKSAoaHRtbF9lc2NhcGUgbikgKEpzLnN0cmluZyBcIlxcXCJcIikpKTtcbiAgICAgICAgaWdub3JlIChhIyNwdXNoIChKcy5zdHJpbmcgXCI+XCIpKTtcbiAgICAgICAgSnMuVW5zYWZlLmNvZXJjZSAoZG9jIyNjcmVhdGVFbGVtZW50IChhIyNqb2luIChKcy5zdHJpbmcgXCJcIikpKVxuICAgIHwgYFVua25vd24gLT5cbiAgICAgICAgY3JlYXRlRWxlbWVudFN5bnRheCA6PVxuICAgICAgICAgIGlmIHRyeVxuICAgICAgICAgICAgICAgbGV0IGVsIDogaW5wdXRFbGVtZW50IEpzLnQgPVxuICAgICAgICAgICAgICAgICBKcy5VbnNhZmUuY29lcmNlXG4gICAgICAgICAgICAgICAgICAgKGRvY3VtZW50IyNjcmVhdGVFbGVtZW50IChKcy5zdHJpbmcgXCI8aW5wdXQgbmFtZT1cXFwieFxcXCI+XCIpKVxuICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgIEpzLmVxdWFscyBlbCMjLnRhZ05hbWUjI3RvTG93ZXJDYXNlIChKcy5zdHJpbmcgXCJpbnB1dFwiKVxuICAgICAgICAgICAgICAgJiYgSnMuZXF1YWxzIGVsIyMubmFtZSAoSnMuc3RyaW5nIFwieFwiKVxuICAgICAgICAgICAgIHdpdGggXyAtPiBmYWxzZVxuICAgICAgICAgIHRoZW4gYEV4dGVuZGVkXG4gICAgICAgICAgZWxzZSBgU3RhbmRhcmQ7XG4gICAgICAgIHVuc2FmZUNyZWF0ZUVsZW1lbnRFeCA/X3R5cGUgP25hbWUgZG9jIGVsdFxuXG5sZXQgY3JlYXRlSHRtbCBkb2MgOiBodG1sRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJodG1sXCJcblxubGV0IGNyZWF0ZUhlYWQgZG9jIDogaGVhZEVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwiaGVhZFwiXG5cbmxldCBjcmVhdGVMaW5rIGRvYyA6IGxpbmtFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcImxpbmtcIlxuXG5sZXQgY3JlYXRlVGl0bGUgZG9jIDogdGl0bGVFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcInRpdGxlXCJcblxubGV0IGNyZWF0ZU1ldGEgZG9jIDogbWV0YUVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwibWV0YVwiXG5cbmxldCBjcmVhdGVCYXNlIGRvYyA6IGJhc2VFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcImJhc2VcIlxuXG5sZXQgY3JlYXRlU3R5bGUgZG9jIDogc3R5bGVFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcInN0eWxlXCJcblxubGV0IGNyZWF0ZUJvZHkgZG9jIDogYm9keUVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwiYm9keVwiXG5cbmxldCBjcmVhdGVGb3JtIGRvYyA6IGZvcm1FbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcImZvcm1cIlxuXG5sZXQgY3JlYXRlT3B0Z3JvdXAgZG9jIDogb3B0R3JvdXBFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcIm9wdGdyb3VwXCJcblxubGV0IGNyZWF0ZU9wdGlvbiBkb2MgOiBvcHRpb25FbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcIm9wdGlvblwiXG5cbmxldCBjcmVhdGVTZWxlY3QgP190eXBlID9uYW1lIGRvYyA6IHNlbGVjdEVsZW1lbnQgdCA9XG4gIHVuc2FmZUNyZWF0ZUVsZW1lbnRFeCA/X3R5cGUgP25hbWUgZG9jIFwic2VsZWN0XCJcblxubGV0IGNyZWF0ZUlucHV0ID9fdHlwZSA/bmFtZSBkb2MgOiBpbnB1dEVsZW1lbnQgdCA9XG4gIHVuc2FmZUNyZWF0ZUVsZW1lbnRFeCA/X3R5cGUgP25hbWUgZG9jIFwiaW5wdXRcIlxuXG5sZXQgY3JlYXRlVGV4dGFyZWEgP190eXBlID9uYW1lIGRvYyA6IHRleHRBcmVhRWxlbWVudCB0ID1cbiAgdW5zYWZlQ3JlYXRlRWxlbWVudEV4ID9fdHlwZSA/bmFtZSBkb2MgXCJ0ZXh0YXJlYVwiXG5cbmxldCBjcmVhdGVCdXR0b24gP190eXBlID9uYW1lIGRvYyA6IGJ1dHRvbkVsZW1lbnQgdCA9XG4gIHVuc2FmZUNyZWF0ZUVsZW1lbnRFeCA/X3R5cGUgP25hbWUgZG9jIFwiYnV0dG9uXCJcblxubGV0IGNyZWF0ZUxhYmVsIGRvYyA6IGxhYmVsRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJsYWJlbFwiXG5cbmxldCBjcmVhdGVGaWVsZHNldCBkb2MgOiBmaWVsZFNldEVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwiZmllbGRzZXRcIlxuXG5sZXQgY3JlYXRlTGVnZW5kIGRvYyA6IGxlZ2VuZEVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwibGVnZW5kXCJcblxubGV0IGNyZWF0ZVVsIGRvYyA6IHVMaXN0RWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJ1bFwiXG5cbmxldCBjcmVhdGVPbCBkb2MgOiBvTGlzdEVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwib2xcIlxuXG5sZXQgY3JlYXRlRGwgZG9jIDogZExpc3RFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcImRsXCJcblxubGV0IGNyZWF0ZUxpIGRvYyA6IGxpRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJsaVwiXG5cbmxldCBjcmVhdGVEaWFsb2cgZG9jIDogZGlhbG9nRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJkaWFsb2dcIlxuXG5sZXQgY3JlYXRlRGl2IGRvYyA6IGRpdkVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwiZGl2XCJcblxubGV0IGNyZWF0ZUVtYmVkIGRvYyA6IGVtYmVkRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJlbWJlZFwiXG5cbmxldCBjcmVhdGVQIGRvYyA6IHBhcmFncmFwaEVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwicFwiXG5cbmxldCBjcmVhdGVIMSBkb2MgOiBoZWFkaW5nRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJoMVwiXG5cbmxldCBjcmVhdGVIMiBkb2MgOiBoZWFkaW5nRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJoMlwiXG5cbmxldCBjcmVhdGVIMyBkb2MgOiBoZWFkaW5nRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJoM1wiXG5cbmxldCBjcmVhdGVINCBkb2MgOiBoZWFkaW5nRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJoNFwiXG5cbmxldCBjcmVhdGVINSBkb2MgOiBoZWFkaW5nRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJoNVwiXG5cbmxldCBjcmVhdGVINiBkb2MgOiBoZWFkaW5nRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJoNlwiXG5cbmxldCBjcmVhdGVRIGRvYyA6IHF1b3RlRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJxXCJcblxubGV0IGNyZWF0ZUJsb2NrcXVvdGUgZG9jIDogcXVvdGVFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcImJsb2NrcXVvdGVcIlxuXG5sZXQgY3JlYXRlUHJlIGRvYyA6IHByZUVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwicHJlXCJcblxubGV0IGNyZWF0ZUJyIGRvYyA6IGJyRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJiclwiXG5cbmxldCBjcmVhdGVIciBkb2MgOiBockVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwiaHJcIlxuXG5sZXQgY3JlYXRlSW5zIGRvYyA6IG1vZEVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwiaW5zXCJcblxubGV0IGNyZWF0ZURlbCBkb2MgOiBtb2RFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcImRlbFwiXG5cbmxldCBjcmVhdGVBIGRvYyA6IGFuY2hvckVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwiYVwiXG5cbmxldCBjcmVhdGVJbWcgZG9jIDogaW1hZ2VFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcImltZ1wiXG5cbmxldCBjcmVhdGVPYmplY3QgZG9jIDogb2JqZWN0RWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJvYmplY3RcIlxuXG5sZXQgY3JlYXRlUGFyYW0gZG9jIDogcGFyYW1FbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcInBhcmFtXCJcblxubGV0IGNyZWF0ZU1hcCBkb2MgOiBtYXBFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcIm1hcFwiXG5cbmxldCBjcmVhdGVBcmVhIGRvYyA6IGFyZWFFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcImFyZWFcIlxuXG5sZXQgY3JlYXRlU2NyaXB0IGRvYyA6IHNjcmlwdEVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwic2NyaXB0XCJcblxubGV0IGNyZWF0ZVRhYmxlIGRvYyA6IHRhYmxlRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJ0YWJsZVwiXG5cbmxldCBjcmVhdGVDYXB0aW9uIGRvYyA6IHRhYmxlQ2FwdGlvbkVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwiY2FwdGlvblwiXG5cbmxldCBjcmVhdGVDb2wgZG9jIDogdGFibGVDb2xFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcImNvbFwiXG5cbmxldCBjcmVhdGVDb2xncm91cCBkb2MgOiB0YWJsZUNvbEVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwiY29sZ3JvdXBcIlxuXG5sZXQgY3JlYXRlVGhlYWQgZG9jIDogdGFibGVTZWN0aW9uRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJ0aGVhZFwiXG5cbmxldCBjcmVhdGVUZm9vdCBkb2MgOiB0YWJsZVNlY3Rpb25FbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcInRmb290XCJcblxubGV0IGNyZWF0ZVRib2R5IGRvYyA6IHRhYmxlU2VjdGlvbkVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwidGJvZHlcIlxuXG5sZXQgY3JlYXRlVHIgZG9jIDogdGFibGVSb3dFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcInRyXCJcblxubGV0IGNyZWF0ZVRoIGRvYyA6IHRhYmxlQ2VsbEVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwidGhcIlxuXG5sZXQgY3JlYXRlVGQgZG9jIDogdGFibGVDZWxsRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJ0ZFwiXG5cbmxldCBjcmVhdGVTdWIgZG9jID0gY3JlYXRlRWxlbWVudCBkb2MgXCJzdWJcIlxuXG5sZXQgY3JlYXRlU3VwIGRvYyA9IGNyZWF0ZUVsZW1lbnQgZG9jIFwic3VwXCJcblxubGV0IGNyZWF0ZVNwYW4gZG9jID0gY3JlYXRlRWxlbWVudCBkb2MgXCJzcGFuXCJcblxubGV0IGNyZWF0ZVR0IGRvYyA9IGNyZWF0ZUVsZW1lbnQgZG9jIFwidHRcIlxuXG5sZXQgY3JlYXRlSSBkb2MgPSBjcmVhdGVFbGVtZW50IGRvYyBcImlcIlxuXG5sZXQgY3JlYXRlQiBkb2MgPSBjcmVhdGVFbGVtZW50IGRvYyBcImJcIlxuXG5sZXQgY3JlYXRlQmlnIGRvYyA9IGNyZWF0ZUVsZW1lbnQgZG9jIFwiYmlnXCJcblxubGV0IGNyZWF0ZVNtYWxsIGRvYyA9IGNyZWF0ZUVsZW1lbnQgZG9jIFwic21hbGxcIlxuXG5sZXQgY3JlYXRlRW0gZG9jID0gY3JlYXRlRWxlbWVudCBkb2MgXCJlbVwiXG5cbmxldCBjcmVhdGVTdHJvbmcgZG9jID0gY3JlYXRlRWxlbWVudCBkb2MgXCJzdHJvbmdcIlxuXG5sZXQgY3JlYXRlQ2l0ZSBkb2MgPSBjcmVhdGVFbGVtZW50IGRvYyBcImNpdGVcIlxuXG5sZXQgY3JlYXRlRGZuIGRvYyA9IGNyZWF0ZUVsZW1lbnQgZG9jIFwiZGZuXCJcblxubGV0IGNyZWF0ZUNvZGUgZG9jID0gY3JlYXRlRWxlbWVudCBkb2MgXCJjb2RlXCJcblxubGV0IGNyZWF0ZVNhbXAgZG9jID0gY3JlYXRlRWxlbWVudCBkb2MgXCJzYW1wXCJcblxubGV0IGNyZWF0ZUtiZCBkb2MgPSBjcmVhdGVFbGVtZW50IGRvYyBcImtiZFwiXG5cbmxldCBjcmVhdGVWYXIgZG9jID0gY3JlYXRlRWxlbWVudCBkb2MgXCJ2YXJcIlxuXG5sZXQgY3JlYXRlQWJiciBkb2MgPSBjcmVhdGVFbGVtZW50IGRvYyBcImFiYnJcIlxuXG5sZXQgY3JlYXRlRGQgZG9jID0gY3JlYXRlRWxlbWVudCBkb2MgXCJkZFwiXG5cbmxldCBjcmVhdGVEdCBkb2MgPSBjcmVhdGVFbGVtZW50IGRvYyBcImR0XCJcblxubGV0IGNyZWF0ZU5vc2NyaXB0IGRvYyA9IGNyZWF0ZUVsZW1lbnQgZG9jIFwibm9zY3JpcHRcIlxuXG5sZXQgY3JlYXRlQWRkcmVzcyBkb2MgPSBjcmVhdGVFbGVtZW50IGRvYyBcImFkZHJlc3NcIlxuXG5sZXQgY3JlYXRlRnJhbWVzZXQgZG9jIDogZnJhbWVTZXRFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcImZyYW1lc2V0XCJcblxubGV0IGNyZWF0ZUZyYW1lIGRvYyA6IGZyYW1lRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJmcmFtZVwiXG5cbmxldCBjcmVhdGVJZnJhbWUgZG9jIDogaUZyYW1lRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJpZnJhbWVcIlxuXG5sZXQgY3JlYXRlQXVkaW8gZG9jIDogYXVkaW9FbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcImF1ZGlvXCJcblxubGV0IGNyZWF0ZVZpZGVvIGRvYyA6IGF1ZGlvRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJ2aWRlb1wiXG5cbmV4Y2VwdGlvbiBDYW52YXNfbm90X2F2YWlsYWJsZVxuXG5sZXQgY3JlYXRlQ2FudmFzIGRvYyA6IGNhbnZhc0VsZW1lbnQgdCA9XG4gIGxldCBjID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJjYW52YXNcIiBpblxuICBpZiBub3QgKE9wdC50ZXN0IGMjIy5nZXRDb250ZXh0KSB0aGVuIHJhaXNlIENhbnZhc19ub3RfYXZhaWxhYmxlO1xuICBjXG5cbmxldCBodG1sX2VsZW1lbnQgOiBodG1sRWxlbWVudCB0IGNvbnN0ciA9IEpzLlVuc2FmZS5nbG9iYWwjIy5fSFRNTEVsZW1lbnRcblxubW9kdWxlIENvZXJjZVRvID0gc3RydWN0XG4gIGxldCBlbGVtZW50IDogI0RvbS5ub2RlIEpzLnQgLT4gZWxlbWVudCBKcy50IEpzLm9wdCA9XG4gICAgaWYgbm90IChKcy5PcHRkZWYudGVzdCAoZGVmIGh0bWxfZWxlbWVudCkpXG4gICAgdGhlblxuICAgICAgKCogaWUgPCA5IGRvZXMgbm90IGhhdmUgSFRNTEVsZW1lbnQ6IHdlIGhhdmUgdG8gY2hlYXQgdG8gY2hlY2tcbiAgICAgICAgIHRoYXQgc29tZXRoaW5nIGlzIGFuIGh0bWwgZWxlbWVudCAqKVxuICAgICAgZnVuIGUgLT5cbiAgICAgIGlmIG5vdCAoSnMuT3B0ZGVmLnRlc3QgKGRlZiAoSnMuVW5zYWZlLmNvZXJjZSBlKSMjLmlubmVySFRNTCkpXG4gICAgICB0aGVuIEpzLm51bGxcbiAgICAgIGVsc2UgSnMuc29tZSAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICAgIGVsc2VcbiAgICAgIGZ1biBlIC0+XG4gICAgICBpZiBKcy5pbnN0YW5jZW9mIGUgaHRtbF9lbGVtZW50IHRoZW4gSnMuc29tZSAoSnMuVW5zYWZlLmNvZXJjZSBlKSBlbHNlIEpzLm51bGxcblxuICBsZXQgdW5zYWZlQ29lcmNlIHRhZyAoZSA6ICNlbGVtZW50IHQpID1cbiAgICBpZiBKcy5lcXVhbHMgZSMjLnRhZ05hbWUjI3RvTG93ZXJDYXNlIChKcy5zdHJpbmcgdGFnKVxuICAgIHRoZW4gSnMuc29tZSAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICAgIGVsc2UgSnMubnVsbFxuXG4gIGxldCBhIGUgPSB1bnNhZmVDb2VyY2UgXCJhXCIgZVxuXG4gIGxldCBhcmVhIGUgPSB1bnNhZmVDb2VyY2UgXCJhcmVhXCIgZVxuXG4gIGxldCBiYXNlIGUgPSB1bnNhZmVDb2VyY2UgXCJiYXNlXCIgZVxuXG4gIGxldCBibG9ja3F1b3RlIGUgPSB1bnNhZmVDb2VyY2UgXCJibG9ja3F1b3RlXCIgZVxuXG4gIGxldCBib2R5IGUgPSB1bnNhZmVDb2VyY2UgXCJib2R5XCIgZVxuXG4gIGxldCBiciBlID0gdW5zYWZlQ29lcmNlIFwiYnJcIiBlXG5cbiAgbGV0IGJ1dHRvbiBlID0gdW5zYWZlQ29lcmNlIFwiYnV0dG9uXCIgZVxuXG4gIGxldCBjYW52YXMgZSA9IHVuc2FmZUNvZXJjZSBcImNhbnZhc1wiIGVcblxuICBsZXQgY2FwdGlvbiBlID0gdW5zYWZlQ29lcmNlIFwiY2FwdGlvblwiIGVcblxuICBsZXQgY29sIGUgPSB1bnNhZmVDb2VyY2UgXCJjb2xcIiBlXG5cbiAgbGV0IGNvbGdyb3VwIGUgPSB1bnNhZmVDb2VyY2UgXCJjb2xncm91cFwiIGVcblxuICBsZXQgZGVsIGUgPSB1bnNhZmVDb2VyY2UgXCJkZWxcIiBlXG5cbiAgbGV0IGRpdiBlID0gdW5zYWZlQ29lcmNlIFwiZGl2XCIgZVxuXG4gIGxldCBkbCBlID0gdW5zYWZlQ29lcmNlIFwiZGxcIiBlXG5cbiAgbGV0IGZpZWxkc2V0IGUgPSB1bnNhZmVDb2VyY2UgXCJmaWVsZHNldFwiIGVcblxuICBsZXQgZW1iZWQgZSA9IHVuc2FmZUNvZXJjZSBcImVtYmVkXCIgZVxuXG4gIGxldCBmb3JtIGUgPSB1bnNhZmVDb2VyY2UgXCJmb3JtXCIgZVxuXG4gIGxldCBmcmFtZXNldCBlID0gdW5zYWZlQ29lcmNlIFwiZnJhbWVzZXRcIiBlXG5cbiAgbGV0IGZyYW1lIGUgPSB1bnNhZmVDb2VyY2UgXCJmcmFtZVwiIGVcblxuICBsZXQgaDEgZSA9IHVuc2FmZUNvZXJjZSBcImgxXCIgZVxuXG4gIGxldCBoMiBlID0gdW5zYWZlQ29lcmNlIFwiaDJcIiBlXG5cbiAgbGV0IGgzIGUgPSB1bnNhZmVDb2VyY2UgXCJoM1wiIGVcblxuICBsZXQgaDQgZSA9IHVuc2FmZUNvZXJjZSBcImg0XCIgZVxuXG4gIGxldCBoNSBlID0gdW5zYWZlQ29lcmNlIFwiaDVcIiBlXG5cbiAgbGV0IGg2IGUgPSB1bnNhZmVDb2VyY2UgXCJoNlwiIGVcblxuICBsZXQgaGVhZCBlID0gdW5zYWZlQ29lcmNlIFwiaGVhZFwiIGVcblxuICBsZXQgaHIgZSA9IHVuc2FmZUNvZXJjZSBcImhyXCIgZVxuXG4gIGxldCBodG1sIGUgPSB1bnNhZmVDb2VyY2UgXCJodG1sXCIgZVxuXG4gIGxldCBpZnJhbWUgZSA9IHVuc2FmZUNvZXJjZSBcImlmcmFtZVwiIGVcblxuICBsZXQgaW1nIGUgPSB1bnNhZmVDb2VyY2UgXCJpbWdcIiBlXG5cbiAgbGV0IGlucHV0IGUgPSB1bnNhZmVDb2VyY2UgXCJpbnB1dFwiIGVcblxuICBsZXQgaW5zIGUgPSB1bnNhZmVDb2VyY2UgXCJpbnNcIiBlXG5cbiAgbGV0IGxhYmVsIGUgPSB1bnNhZmVDb2VyY2UgXCJsYWJlbFwiIGVcblxuICBsZXQgbGVnZW5kIGUgPSB1bnNhZmVDb2VyY2UgXCJsZWdlbmRcIiBlXG5cbiAgbGV0IGxpIGUgPSB1bnNhZmVDb2VyY2UgXCJsaVwiIGVcblxuICBsZXQgbGluayBlID0gdW5zYWZlQ29lcmNlIFwibGlua1wiIGVcblxuICBsZXQgbWFwIGUgPSB1bnNhZmVDb2VyY2UgXCJtYXBcIiBlXG5cbiAgbGV0IG1ldGEgZSA9IHVuc2FmZUNvZXJjZSBcIm1ldGFcIiBlXG5cbiAgbGV0IF9vYmplY3QgZSA9IHVuc2FmZUNvZXJjZSBcIm9iamVjdFwiIGVcblxuICBsZXQgb2wgZSA9IHVuc2FmZUNvZXJjZSBcIm9sXCIgZVxuXG4gIGxldCBvcHRncm91cCBlID0gdW5zYWZlQ29lcmNlIFwib3B0Z3JvdXBcIiBlXG5cbiAgbGV0IG9wdGlvbiBlID0gdW5zYWZlQ29lcmNlIFwib3B0aW9uXCIgZVxuXG4gIGxldCBwIGUgPSB1bnNhZmVDb2VyY2UgXCJwXCIgZVxuXG4gIGxldCBwYXJhbSBlID0gdW5zYWZlQ29lcmNlIFwicGFyYW1cIiBlXG5cbiAgbGV0IHByZSBlID0gdW5zYWZlQ29lcmNlIFwicHJlXCIgZVxuXG4gIGxldCBxIGUgPSB1bnNhZmVDb2VyY2UgXCJxXCIgZVxuXG4gIGxldCBzY3JpcHQgZSA9IHVuc2FmZUNvZXJjZSBcInNjcmlwdFwiIGVcblxuICBsZXQgc2VsZWN0IGUgPSB1bnNhZmVDb2VyY2UgXCJzZWxlY3RcIiBlXG5cbiAgbGV0IHN0eWxlIGUgPSB1bnNhZmVDb2VyY2UgXCJzdHlsZVwiIGVcblxuICBsZXQgdGFibGUgZSA9IHVuc2FmZUNvZXJjZSBcInRhYmxlXCIgZVxuXG4gIGxldCB0Ym9keSBlID0gdW5zYWZlQ29lcmNlIFwidGJvZHlcIiBlXG5cbiAgbGV0IHRkIGUgPSB1bnNhZmVDb2VyY2UgXCJ0ZFwiIGVcblxuICBsZXQgdGV4dGFyZWEgZSA9IHVuc2FmZUNvZXJjZSBcInRleHRhcmVhXCIgZVxuXG4gIGxldCB0Zm9vdCBlID0gdW5zYWZlQ29lcmNlIFwidGZvb3RcIiBlXG5cbiAgbGV0IHRoIGUgPSB1bnNhZmVDb2VyY2UgXCJ0aFwiIGVcblxuICBsZXQgdGhlYWQgZSA9IHVuc2FmZUNvZXJjZSBcInRoZWFkXCIgZVxuXG4gIGxldCB0aXRsZSBlID0gdW5zYWZlQ29lcmNlIFwidGl0bGVcIiBlXG5cbiAgbGV0IHRyIGUgPSB1bnNhZmVDb2VyY2UgXCJ0clwiIGVcblxuICBsZXQgdWwgZSA9IHVuc2FmZUNvZXJjZSBcInVsXCIgZVxuXG4gIGxldCBhdWRpbyBlID0gdW5zYWZlQ29lcmNlIFwiYXVkaW9cIiBlXG5cbiAgbGV0IHZpZGVvIGUgPSB1bnNhZmVDb2VyY2UgXCJ2aWRlb1wiIGVcblxuICBsZXQgdW5zYWZlQ29lcmNlRXZlbnQgY29uc3RyIChldiA6ICNldmVudCB0KSA9XG4gICAgaWYgSnMuT3B0ZGVmLnRlc3QgKGRlZiBjb25zdHIpICYmIEpzLmluc3RhbmNlb2YgZXYgY29uc3RyXG4gICAgdGhlbiBKcy5zb21lIChKcy5VbnNhZmUuY29lcmNlIGV2KVxuICAgIGVsc2UgSnMubnVsbFxuXG4gIGxldCBtb3VzZUV2ZW50IGV2ID0gdW5zYWZlQ29lcmNlRXZlbnQgSnMuVW5zYWZlLmdsb2JhbCMjLl9Nb3VzZUV2ZW50IGV2XG5cbiAgbGV0IGtleWJvYXJkRXZlbnQgZXYgPSB1bnNhZmVDb2VyY2VFdmVudCBKcy5VbnNhZmUuZ2xvYmFsIyMuX0tleWJvYXJkRXZlbnQgZXZcblxuICBsZXQgd2hlZWxFdmVudCBldiA9IHVuc2FmZUNvZXJjZUV2ZW50IEpzLlVuc2FmZS5nbG9iYWwjIy5fV2hlZWxFdmVudCBldlxuXG4gIGxldCBtb3VzZVNjcm9sbEV2ZW50IGV2ID0gdW5zYWZlQ29lcmNlRXZlbnQgSnMuVW5zYWZlLmdsb2JhbCMjLl9Nb3VzZVNjcm9sbEV2ZW50IGV2XG5cbiAgbGV0IHBvcFN0YXRlRXZlbnQgZXYgPSB1bnNhZmVDb2VyY2VFdmVudCBKcy5VbnNhZmUuZ2xvYmFsIyMuX1BvcFN0YXRlRXZlbnQgZXZcblxuICBsZXQgbWVzc2FnZUV2ZW50IGV2ID0gdW5zYWZlQ29lcmNlRXZlbnQgSnMuVW5zYWZlLmdsb2JhbCMjLl9NZXNzYWdlRXZlbnQgZXZcbmVuZFxuXG4oKioqKilcblxubGV0IGV2ZW50VGFyZ2V0ID0gRG9tLmV2ZW50VGFyZ2V0XG5cbmxldCBldmVudFJlbGF0ZWRUYXJnZXQgKGUgOiAjbW91c2VFdmVudCB0KSA9XG4gIE9wdGRlZi5nZXQgZSMjLnJlbGF0ZWRUYXJnZXQgKGZ1biAoKSAtPlxuICAgICAgbWF0Y2ggSnMudG9fc3RyaW5nIGUjIy5fdHlwZSB3aXRoXG4gICAgICB8IFwibW91c2VvdmVyXCIgLT4gT3B0ZGVmLmdldCBlIyMuZnJvbUVsZW1lbnQgKGZ1biAoKSAtPiBhc3NlcnQgZmFsc2UpXG4gICAgICB8IFwibW91c2VvdXRcIiAtPiBPcHRkZWYuZ2V0IGUjIy50b0VsZW1lbnQgKGZ1biAoKSAtPiBhc3NlcnQgZmFsc2UpXG4gICAgICB8IF8gLT4gSnMubnVsbClcblxubGV0IGV2ZW50QWJzb2x1dGVQb3NpdGlvbicgKGUgOiAjbW91c2VFdmVudCB0KSA9XG4gIGxldCBib2R5ID0gZG9jdW1lbnQjIy5ib2R5IGluXG4gIGxldCBodG1sID0gZG9jdW1lbnQjIy5kb2N1bWVudEVsZW1lbnQgaW5cbiAgKCBlIyMuY2xpZW50WCArIGJvZHkjIy5zY3JvbGxMZWZ0ICsgaHRtbCMjLnNjcm9sbExlZnRcbiAgLCBlIyMuY2xpZW50WSArIGJvZHkjIy5zY3JvbGxUb3AgKyBodG1sIyMuc2Nyb2xsVG9wIClcblxubGV0IGV2ZW50QWJzb2x1dGVQb3NpdGlvbiAoZSA6ICNtb3VzZUV2ZW50IHQpID1cbiAgT3B0ZGVmLmNhc2VcbiAgICBlIyMucGFnZVhcbiAgICAoZnVuICgpIC0+IGV2ZW50QWJzb2x1dGVQb3NpdGlvbicgZSlcbiAgICAoZnVuIHggLT4gT3B0ZGVmLmNhc2UgZSMjLnBhZ2VZIChmdW4gKCkgLT4gZXZlbnRBYnNvbHV0ZVBvc2l0aW9uJyBlKSAoZnVuIHkgLT4geCwgeSkpXG5cbmxldCBlbGVtZW50Q2xpZW50UG9zaXRpb24gKGUgOiAjZWxlbWVudCB0KSA9XG4gIGxldCByID0gZSMjZ2V0Qm91bmRpbmdDbGllbnRSZWN0IGluXG4gIGxldCBib2R5ID0gZG9jdW1lbnQjIy5ib2R5IGluXG4gIGxldCBodG1sID0gZG9jdW1lbnQjIy5kb2N1bWVudEVsZW1lbnQgaW5cbiAgKCB0cnVuY2F0ZSAoSnMudG9fZmxvYXQgciMjLmxlZnQpIC0gYm9keSMjLmNsaWVudExlZnQgLSBodG1sIyMuY2xpZW50TGVmdFxuICAsIHRydW5jYXRlIChKcy50b19mbG9hdCByIyMudG9wKSAtIGJvZHkjIy5jbGllbnRUb3AgLSBodG1sIyMuY2xpZW50VG9wIClcblxubGV0IGdldERvY3VtZW50U2Nyb2xsICgpID1cbiAgbGV0IGJvZHkgPSBkb2N1bWVudCMjLmJvZHkgaW5cbiAgbGV0IGh0bWwgPSBkb2N1bWVudCMjLmRvY3VtZW50RWxlbWVudCBpblxuICBib2R5IyMuc2Nyb2xsTGVmdCArIGh0bWwjIy5zY3JvbGxMZWZ0LCBib2R5IyMuc2Nyb2xsVG9wICsgaHRtbCMjLnNjcm9sbFRvcFxuXG5sZXQgYnV0dG9uUHJlc3NlZCAoZXYgOiAjbW91c2VFdmVudCBKcy50KSA9XG4gIEpzLk9wdGRlZi5jYXNlXG4gICAgZXYjIy53aGljaFxuICAgIChmdW4gKCkgLT5cbiAgICAgIG1hdGNoIGV2IyMuYnV0dG9uIHdpdGhcbiAgICAgIHwgMSAtPiBMZWZ0X2J1dHRvblxuICAgICAgfCAyIC0+IFJpZ2h0X2J1dHRvblxuICAgICAgfCA0IC0+IE1pZGRsZV9idXR0b25cbiAgICAgIHwgXyAtPiBOb19idXR0b24pXG4gICAgKGZ1biB4IC0+IHgpXG5cbmxldCBhZGRNb3VzZXdoZWVsRXZlbnRMaXN0ZW5lcldpdGhPcHRpb25zIGUgP2NhcHR1cmUgP29uY2UgP3Bhc3NpdmUgaCA9XG4gIGFkZEV2ZW50TGlzdGVuZXJXaXRoT3B0aW9uc1xuICAgID9jYXB0dXJlXG4gICAgP29uY2VcbiAgICA/cGFzc2l2ZVxuICAgIGVcbiAgICBFdmVudC53aGVlbFxuICAgIChoYW5kbGVyIChmdW4gKGUgOiBtb3VzZXdoZWVsRXZlbnQgdCkgLT5cbiAgICAgICAgIGxldCBkeCA9IC1PcHRkZWYuZ2V0IGUjIy53aGVlbERlbHRhWCAoZnVuICgpIC0+IDApIC8gNDAgaW5cbiAgICAgICAgIGxldCBkeSA9IC1PcHRkZWYuZ2V0IGUjIy53aGVlbERlbHRhWSAoZnVuICgpIC0+IGUjIy53aGVlbERlbHRhKSAvIDQwIGluXG4gICAgICAgICBoIChlIDo+IG1vdXNlRXZlbnQgdCkgfmR4IH5keSkpXG5cbmxldCBhZGRNb3VzZXdoZWVsRXZlbnRMaXN0ZW5lciBlIGggY2FwdCA9XG4gIGFkZE1vdXNld2hlZWxFdmVudExpc3RlbmVyV2l0aE9wdGlvbnMgfmNhcHR1cmU6Y2FwdCBlIGhcblxuKCoqKioqKVxuXG5tb2R1bGUgS2V5Ym9hcmRfY29kZSA9IHN0cnVjdFxuICB0eXBlIHQgPVxuICAgIHwgVW5pZGVudGlmaWVkXG4gICAgKCogQWxwaGFiZXRpYyBDaGFyYWN0ZXJzICopXG4gICAgfCBLZXlBXG4gICAgfCBLZXlCXG4gICAgfCBLZXlDXG4gICAgfCBLZXlEXG4gICAgfCBLZXlFXG4gICAgfCBLZXlGXG4gICAgfCBLZXlHXG4gICAgfCBLZXlIXG4gICAgfCBLZXlJXG4gICAgfCBLZXlKXG4gICAgfCBLZXlLXG4gICAgfCBLZXlMXG4gICAgfCBLZXlNXG4gICAgfCBLZXlOXG4gICAgfCBLZXlPXG4gICAgfCBLZXlQXG4gICAgfCBLZXlRXG4gICAgfCBLZXlSXG4gICAgfCBLZXlTXG4gICAgfCBLZXlUXG4gICAgfCBLZXlVXG4gICAgfCBLZXlWXG4gICAgfCBLZXlXXG4gICAgfCBLZXlYXG4gICAgfCBLZXlZXG4gICAgfCBLZXlaXG4gICAgKCogRGlnaXRzICopXG4gICAgfCBEaWdpdDBcbiAgICB8IERpZ2l0MVxuICAgIHwgRGlnaXQyXG4gICAgfCBEaWdpdDNcbiAgICB8IERpZ2l0NFxuICAgIHwgRGlnaXQ1XG4gICAgfCBEaWdpdDZcbiAgICB8IERpZ2l0N1xuICAgIHwgRGlnaXQ4XG4gICAgfCBEaWdpdDlcbiAgICB8IE1pbnVzXG4gICAgfCBFcXVhbFxuICAgICgqIFdoaXRlc3BhY2UgKilcbiAgICB8IFRhYlxuICAgIHwgRW50ZXJcbiAgICB8IFNwYWNlXG4gICAgKCogRWRpdGluZyAqKVxuICAgIHwgRXNjYXBlXG4gICAgfCBCYWNrc3BhY2VcbiAgICB8IEluc2VydFxuICAgIHwgRGVsZXRlXG4gICAgfCBDYXBzTG9ja1xuICAgICgqIE1pc2MgUHJpbnRhYmxlICopXG4gICAgfCBCcmFja2V0TGVmdFxuICAgIHwgQnJhY2tldFJpZ2h0XG4gICAgfCBTZW1pY29sb25cbiAgICB8IFF1b3RlXG4gICAgfCBCYWNrcXVvdGVcbiAgICB8IEJhY2tzbGFzaFxuICAgIHwgQ29tbWFcbiAgICB8IFBlcmlvZFxuICAgIHwgU2xhc2hcbiAgICAoKiBGdW5jdGlvbiBrZXlzICopXG4gICAgfCBGMVxuICAgIHwgRjJcbiAgICB8IEYzXG4gICAgfCBGNFxuICAgIHwgRjVcbiAgICB8IEY2XG4gICAgfCBGN1xuICAgIHwgRjhcbiAgICB8IEY5XG4gICAgfCBGMTBcbiAgICB8IEYxMVxuICAgIHwgRjEyXG4gICAgKCogTnVtcGFkIGtleXMgKilcbiAgICB8IE51bXBhZDBcbiAgICB8IE51bXBhZDFcbiAgICB8IE51bXBhZDJcbiAgICB8IE51bXBhZDNcbiAgICB8IE51bXBhZDRcbiAgICB8IE51bXBhZDVcbiAgICB8IE51bXBhZDZcbiAgICB8IE51bXBhZDdcbiAgICB8IE51bXBhZDhcbiAgICB8IE51bXBhZDlcbiAgICB8IE51bXBhZE11bHRpcGx5XG4gICAgfCBOdW1wYWRTdWJ0cmFjdFxuICAgIHwgTnVtcGFkQWRkXG4gICAgfCBOdW1wYWREZWNpbWFsXG4gICAgfCBOdW1wYWRFcXVhbFxuICAgIHwgTnVtcGFkRW50ZXJcbiAgICB8IE51bXBhZERpdmlkZVxuICAgIHwgTnVtTG9ja1xuICAgICgqIE1vZGlmaWVyIGtleXMgKilcbiAgICB8IENvbnRyb2xMZWZ0XG4gICAgfCBDb250cm9sUmlnaHRcbiAgICB8IE1ldGFMZWZ0XG4gICAgfCBNZXRhUmlnaHRcbiAgICB8IFNoaWZ0TGVmdFxuICAgIHwgU2hpZnRSaWdodFxuICAgIHwgQWx0TGVmdFxuICAgIHwgQWx0UmlnaHRcbiAgICAoKiBBcnJvdyBrZXlzICopXG4gICAgfCBBcnJvd0xlZnRcbiAgICB8IEFycm93UmlnaHRcbiAgICB8IEFycm93VXBcbiAgICB8IEFycm93RG93blxuICAgICgqIE5hdmlnYXRpb24gKilcbiAgICB8IFBhZ2VVcFxuICAgIHwgUGFnZURvd25cbiAgICB8IEhvbWVcbiAgICB8IEVuZFxuICAgICgqIFNvdW5kICopXG4gICAgfCBWb2x1bWVNdXRlXG4gICAgfCBWb2x1bWVEb3duXG4gICAgfCBWb2x1bWVVcFxuICAgICgqIE1lZGlhICopXG4gICAgfCBNZWRpYVRyYWNrUHJldmlvdXNcbiAgICB8IE1lZGlhVHJhY2tOZXh0XG4gICAgfCBNZWRpYVBsYXlQYXVzZVxuICAgIHwgTWVkaWFTdG9wXG4gICAgKCogQnJvd3NlciBzcGVjaWFsICopXG4gICAgfCBDb250ZXh0TWVudVxuICAgIHwgQnJvd3NlclNlYXJjaFxuICAgIHwgQnJvd3NlckhvbWVcbiAgICB8IEJyb3dzZXJGYXZvcml0ZXNcbiAgICB8IEJyb3dzZXJSZWZyZXNoXG4gICAgfCBCcm93c2VyU3RvcFxuICAgIHwgQnJvd3NlckZvcndhcmRcbiAgICB8IEJyb3dzZXJCYWNrXG4gICAgKCogTWlzYyAqKVxuICAgIHwgT1NMZWZ0XG4gICAgfCBPU1JpZ2h0XG4gICAgfCBTY3JvbGxMb2NrXG4gICAgfCBQcmludFNjcmVlblxuICAgIHwgSW50bEJhY2tzbGFzaFxuICAgIHwgSW50bFllblxuICAgIHwgUGF1c2VcblxuICBsZXQgdHJ5X2NvZGUgdiA9XG4gICAgbWF0Y2ggSnMudG9fc3RyaW5nIHYgd2l0aFxuICAgICgqIEFscGhhYmV0aWMgQ2hhcmFjdGVycyAqKVxuICAgIHwgXCJLZXlBXCIgLT4gS2V5QVxuICAgIHwgXCJLZXlCXCIgLT4gS2V5QlxuICAgIHwgXCJLZXlDXCIgLT4gS2V5Q1xuICAgIHwgXCJLZXlEXCIgLT4gS2V5RFxuICAgIHwgXCJLZXlFXCIgLT4gS2V5RVxuICAgIHwgXCJLZXlGXCIgLT4gS2V5RlxuICAgIHwgXCJLZXlHXCIgLT4gS2V5R1xuICAgIHwgXCJLZXlIXCIgLT4gS2V5SFxuICAgIHwgXCJLZXlJXCIgLT4gS2V5SVxuICAgIHwgXCJLZXlKXCIgLT4gS2V5SlxuICAgIHwgXCJLZXlLXCIgLT4gS2V5S1xuICAgIHwgXCJLZXlMXCIgLT4gS2V5TFxuICAgIHwgXCJLZXlNXCIgLT4gS2V5TVxuICAgIHwgXCJLZXlOXCIgLT4gS2V5TlxuICAgIHwgXCJLZXlPXCIgLT4gS2V5T1xuICAgIHwgXCJLZXlQXCIgLT4gS2V5UFxuICAgIHwgXCJLZXlRXCIgLT4gS2V5UVxuICAgIHwgXCJLZXlSXCIgLT4gS2V5UlxuICAgIHwgXCJLZXlTXCIgLT4gS2V5U1xuICAgIHwgXCJLZXlUXCIgLT4gS2V5VFxuICAgIHwgXCJLZXlVXCIgLT4gS2V5VVxuICAgIHwgXCJLZXlWXCIgLT4gS2V5VlxuICAgIHwgXCJLZXlXXCIgLT4gS2V5V1xuICAgIHwgXCJLZXlYXCIgLT4gS2V5WFxuICAgIHwgXCJLZXlZXCIgLT4gS2V5WVxuICAgIHwgXCJLZXlaXCIgLT4gS2V5WlxuICAgICgqIERpZ2l0cyAqKVxuICAgIHwgXCJEaWdpdDBcIiAtPiBEaWdpdDBcbiAgICB8IFwiRGlnaXQxXCIgLT4gRGlnaXQxXG4gICAgfCBcIkRpZ2l0MlwiIC0+IERpZ2l0MlxuICAgIHwgXCJEaWdpdDNcIiAtPiBEaWdpdDNcbiAgICB8IFwiRGlnaXQ0XCIgLT4gRGlnaXQ0XG4gICAgfCBcIkRpZ2l0NVwiIC0+IERpZ2l0NVxuICAgIHwgXCJEaWdpdDZcIiAtPiBEaWdpdDZcbiAgICB8IFwiRGlnaXQ3XCIgLT4gRGlnaXQ3XG4gICAgfCBcIkRpZ2l0OFwiIC0+IERpZ2l0OFxuICAgIHwgXCJEaWdpdDlcIiAtPiBEaWdpdDlcbiAgICB8IFwiTWludXNcIiAtPiBNaW51c1xuICAgIHwgXCJFcXVhbFwiIC0+IEVxdWFsXG4gICAgKCogV2hpdGVzcGFjZSAqKVxuICAgIHwgXCJUYWJcIiAtPiBUYWJcbiAgICB8IFwiRW50ZXJcIiAtPiBFbnRlclxuICAgIHwgXCJTcGFjZVwiIC0+IFNwYWNlXG4gICAgKCogRWRpdGluZyAqKVxuICAgIHwgXCJFc2NhcGVcIiAtPiBFc2NhcGVcbiAgICB8IFwiQmFja3NwYWNlXCIgLT4gQmFja3NwYWNlXG4gICAgfCBcIkluc2VydFwiIC0+IEluc2VydFxuICAgIHwgXCJEZWxldGVcIiAtPiBEZWxldGVcbiAgICB8IFwiQ2Fwc0xvY2tcIiAtPiBDYXBzTG9ja1xuICAgICgqIE1pc2MgUHJpbnRhYmxlICopXG4gICAgfCBcIkJyYWNrZXRMZWZ0XCIgLT4gQnJhY2tldExlZnRcbiAgICB8IFwiQnJhY2tldFJpZ2h0XCIgLT4gQnJhY2tldFJpZ2h0XG4gICAgfCBcIlNlbWljb2xvblwiIC0+IFNlbWljb2xvblxuICAgIHwgXCJRdW90ZVwiIC0+IFF1b3RlXG4gICAgfCBcIkJhY2txdW90ZVwiIC0+IEJhY2txdW90ZVxuICAgIHwgXCJCYWNrc2xhc2hcIiAtPiBCYWNrc2xhc2hcbiAgICB8IFwiQ29tbWFcIiAtPiBDb21tYVxuICAgIHwgXCJQZXJpb2RcIiAtPiBQZXJpb2RcbiAgICB8IFwiU2xhc2hcIiAtPiBTbGFzaFxuICAgICgqIEZ1bmN0aW9uIGtleXMgKilcbiAgICB8IFwiRjFcIiAtPiBGMVxuICAgIHwgXCJGMlwiIC0+IEYyXG4gICAgfCBcIkYzXCIgLT4gRjNcbiAgICB8IFwiRjRcIiAtPiBGNFxuICAgIHwgXCJGNVwiIC0+IEY1XG4gICAgfCBcIkY2XCIgLT4gRjZcbiAgICB8IFwiRjdcIiAtPiBGN1xuICAgIHwgXCJGOFwiIC0+IEY4XG4gICAgfCBcIkY5XCIgLT4gRjlcbiAgICB8IFwiRjEwXCIgLT4gRjEwXG4gICAgfCBcIkYxMVwiIC0+IEYxMVxuICAgIHwgXCJGMTJcIiAtPiBGMTJcbiAgICAoKiBOdW1wYWQga2V5cyAqKVxuICAgIHwgXCJOdW1wYWQwXCIgLT4gTnVtcGFkMFxuICAgIHwgXCJOdW1wYWQxXCIgLT4gTnVtcGFkMVxuICAgIHwgXCJOdW1wYWQyXCIgLT4gTnVtcGFkMlxuICAgIHwgXCJOdW1wYWQzXCIgLT4gTnVtcGFkM1xuICAgIHwgXCJOdW1wYWQ0XCIgLT4gTnVtcGFkNFxuICAgIHwgXCJOdW1wYWQ1XCIgLT4gTnVtcGFkNVxuICAgIHwgXCJOdW1wYWQ2XCIgLT4gTnVtcGFkNlxuICAgIHwgXCJOdW1wYWQ3XCIgLT4gTnVtcGFkN1xuICAgIHwgXCJOdW1wYWQ4XCIgLT4gTnVtcGFkOFxuICAgIHwgXCJOdW1wYWQ5XCIgLT4gTnVtcGFkOVxuICAgIHwgXCJOdW1wYWRNdWx0aXBseVwiIC0+IE51bXBhZE11bHRpcGx5XG4gICAgfCBcIk51bXBhZFN1YnRyYWN0XCIgLT4gTnVtcGFkU3VidHJhY3RcbiAgICB8IFwiTnVtcGFkQWRkXCIgLT4gTnVtcGFkQWRkXG4gICAgfCBcIk51bXBhZERlY2ltYWxcIiAtPiBOdW1wYWREZWNpbWFsXG4gICAgfCBcIk51bXBhZEVxdWFsXCIgLT4gTnVtcGFkRXF1YWxcbiAgICB8IFwiTnVtcGFkRW50ZXJcIiAtPiBOdW1wYWRFbnRlclxuICAgIHwgXCJOdW1wYWREaXZpZGVcIiAtPiBOdW1wYWREaXZpZGVcbiAgICB8IFwiTnVtTG9ja1wiIC0+IE51bUxvY2tcbiAgICAoKiBNb2RpZmllciBrZXlzICopXG4gICAgfCBcIkNvbnRyb2xMZWZ0XCIgLT4gQ29udHJvbExlZnRcbiAgICB8IFwiQ29udHJvbFJpZ2h0XCIgLT4gQ29udHJvbFJpZ2h0XG4gICAgfCBcIk1ldGFMZWZ0XCIgLT4gTWV0YUxlZnRcbiAgICB8IFwiTWV0YVJpZ2h0XCIgLT4gTWV0YVJpZ2h0XG4gICAgfCBcIlNoaWZ0TGVmdFwiIC0+IFNoaWZ0TGVmdFxuICAgIHwgXCJTaGlmdFJpZ2h0XCIgLT4gU2hpZnRSaWdodFxuICAgIHwgXCJBbHRMZWZ0XCIgLT4gQWx0TGVmdFxuICAgIHwgXCJBbHRSaWdodFwiIC0+IEFsdFJpZ2h0XG4gICAgKCogQXJyb3cga2V5cyAqKVxuICAgIHwgXCJBcnJvd0xlZnRcIiAtPiBBcnJvd0xlZnRcbiAgICB8IFwiQXJyb3dSaWdodFwiIC0+IEFycm93UmlnaHRcbiAgICB8IFwiQXJyb3dVcFwiIC0+IEFycm93VXBcbiAgICB8IFwiQXJyb3dEb3duXCIgLT4gQXJyb3dEb3duXG4gICAgKCogTmF2aWdhdGlvbiAqKVxuICAgIHwgXCJQYWdlVXBcIiAtPiBQYWdlVXBcbiAgICB8IFwiUGFnZURvd25cIiAtPiBQYWdlRG93blxuICAgIHwgXCJIb21lXCIgLT4gSG9tZVxuICAgIHwgXCJFbmRcIiAtPiBFbmRcbiAgICAoKiBTb3VuZCAqKVxuICAgIHwgXCJWb2x1bWVNdXRlXCIgLT4gVm9sdW1lTXV0ZVxuICAgIHwgXCJWb2x1bWVEb3duXCIgLT4gVm9sdW1lRG93blxuICAgIHwgXCJWb2x1bWVVcFwiIC0+IFZvbHVtZVVwXG4gICAgKCogTWVkaWEgKilcbiAgICB8IFwiTWVkaWFUcmFja1ByZXZpb3VzXCIgLT4gTWVkaWFUcmFja1ByZXZpb3VzXG4gICAgfCBcIk1lZGlhVHJhY2tOZXh0XCIgLT4gTWVkaWFUcmFja05leHRcbiAgICB8IFwiTWVkaWFQbGF5UGF1c2VcIiAtPiBNZWRpYVBsYXlQYXVzZVxuICAgIHwgXCJNZWRpYVN0b3BcIiAtPiBNZWRpYVN0b3BcbiAgICAoKiBCcm93c2VyIHNwZWNpYWwgKilcbiAgICB8IFwiQ29udGV4dE1lbnVcIiAtPiBDb250ZXh0TWVudVxuICAgIHwgXCJCcm93c2VyU2VhcmNoXCIgLT4gQnJvd3NlclNlYXJjaFxuICAgIHwgXCJCcm93c2VySG9tZVwiIC0+IEJyb3dzZXJIb21lXG4gICAgfCBcIkJyb3dzZXJGYXZvcml0ZXNcIiAtPiBCcm93c2VyRmF2b3JpdGVzXG4gICAgfCBcIkJyb3dzZXJSZWZyZXNoXCIgLT4gQnJvd3NlclJlZnJlc2hcbiAgICB8IFwiQnJvd3NlclN0b3BcIiAtPiBCcm93c2VyU3RvcFxuICAgIHwgXCJCcm93c2VyRm9yd2FyZFwiIC0+IEJyb3dzZXJGb3J3YXJkXG4gICAgfCBcIkJyb3dzZXJCYWNrXCIgLT4gQnJvd3NlckJhY2tcbiAgICAoKiBNaXNjICopXG4gICAgfCBcIk9TTGVmdFwiIC0+IE9TTGVmdFxuICAgIHwgXCJPU1JpZ2h0XCIgLT4gT1NSaWdodFxuICAgIHwgXCJTY3JvbGxMb2NrXCIgLT4gU2Nyb2xsTG9ja1xuICAgIHwgXCJQcmludFNjcmVlblwiIC0+IFByaW50U2NyZWVuXG4gICAgfCBcIkludGxCYWNrc2xhc2hcIiAtPiBJbnRsQmFja3NsYXNoXG4gICAgfCBcIkludGxZZW5cIiAtPiBJbnRsWWVuXG4gICAgfCBcIlBhdXNlXCIgLT4gUGF1c2VcbiAgICB8IF8gLT4gVW5pZGVudGlmaWVkXG5cbiAgbGV0IHRyeV9rZXlfY29kZV9sZWZ0ID0gZnVuY3Rpb25cbiAgICB8IDE2IC0+IFNoaWZ0TGVmdFxuICAgIHwgMTcgLT4gQ29udHJvbExlZnRcbiAgICB8IDE4IC0+IEFsdExlZnRcbiAgICB8IDkxIC0+IE1ldGFMZWZ0XG4gICAgfCBfIC0+IFVuaWRlbnRpZmllZFxuXG4gIGxldCB0cnlfa2V5X2NvZGVfcmlnaHQgPSBmdW5jdGlvblxuICAgIHwgMTYgLT4gU2hpZnRSaWdodFxuICAgIHwgMTcgLT4gQ29udHJvbFJpZ2h0XG4gICAgfCAxOCAtPiBBbHRSaWdodFxuICAgIHwgOTEgLT4gTWV0YVJpZ2h0XG4gICAgfCBfIC0+IFVuaWRlbnRpZmllZFxuXG4gIGxldCB0cnlfa2V5X2NvZGVfbnVtcGFkID0gZnVuY3Rpb25cbiAgICB8IDQ2IC0+IE51bXBhZERlY2ltYWxcbiAgICB8IDQ1IC0+IE51bXBhZDBcbiAgICB8IDM1IC0+IE51bXBhZDFcbiAgICB8IDQwIC0+IE51bXBhZDJcbiAgICB8IDM0IC0+IE51bXBhZDNcbiAgICB8IDM3IC0+IE51bXBhZDRcbiAgICB8IDEyIC0+IE51bXBhZDVcbiAgICB8IDM5IC0+IE51bXBhZDZcbiAgICB8IDM2IC0+IE51bXBhZDdcbiAgICB8IDM4IC0+IE51bXBhZDhcbiAgICB8IDMzIC0+IE51bXBhZDlcbiAgICB8IDEzIC0+IE51bXBhZEVudGVyXG4gICAgfCAxMTEgLT4gTnVtcGFkRGl2aWRlXG4gICAgfCAxMDcgLT4gTnVtcGFkQWRkXG4gICAgfCAxMDkgLT4gTnVtcGFkU3VidHJhY3RcbiAgICB8IDEwNiAtPiBOdW1wYWRNdWx0aXBseVxuICAgIHwgMTEwIC0+IE51bXBhZERlY2ltYWxcbiAgICB8IDk2IC0+IE51bXBhZDBcbiAgICB8IDk3IC0+IE51bXBhZDFcbiAgICB8IDk4IC0+IE51bXBhZDJcbiAgICB8IDk5IC0+IE51bXBhZDNcbiAgICB8IDEwMCAtPiBOdW1wYWQ0XG4gICAgfCAxMDEgLT4gTnVtcGFkNVxuICAgIHwgMTAyIC0+IE51bXBhZDZcbiAgICB8IDEwMyAtPiBOdW1wYWQ3XG4gICAgfCAxMDQgLT4gTnVtcGFkOFxuICAgIHwgMTA1IC0+IE51bXBhZDlcbiAgICB8IF8gLT4gVW5pZGVudGlmaWVkXG5cbiAgbGV0IHRyeV9rZXlfY29kZV9ub3JtYWwgPSBmdW5jdGlvblxuICAgIHwgMjcgLT4gRXNjYXBlXG4gICAgfCAxMTIgLT4gRjFcbiAgICB8IDExMyAtPiBGMlxuICAgIHwgMTE0IC0+IEYzXG4gICAgfCAxMTUgLT4gRjRcbiAgICB8IDExNiAtPiBGNVxuICAgIHwgMTE3IC0+IEY2XG4gICAgfCAxMTggLT4gRjdcbiAgICB8IDExOSAtPiBGOFxuICAgIHwgMTIwIC0+IEY5XG4gICAgfCAxMjEgLT4gRjEwXG4gICAgfCAxMjIgLT4gRjExXG4gICAgfCAxMjMgLT4gRjEyXG4gICAgfCA0MiAtPiBQcmludFNjcmVlblxuICAgIHwgMTQ1IC0+IFNjcm9sbExvY2tcbiAgICB8IDE5IC0+IFBhdXNlXG4gICAgfCAxOTIgLT4gQmFja3F1b3RlXG4gICAgfCA0OSAtPiBEaWdpdDFcbiAgICB8IDUwIC0+IERpZ2l0MlxuICAgIHwgNTEgLT4gRGlnaXQzXG4gICAgfCA1MiAtPiBEaWdpdDRcbiAgICB8IDUzIC0+IERpZ2l0NVxuICAgIHwgNTQgLT4gRGlnaXQ2XG4gICAgfCA1NSAtPiBEaWdpdDdcbiAgICB8IDU2IC0+IERpZ2l0OFxuICAgIHwgNTcgLT4gRGlnaXQ5XG4gICAgfCA0OCAtPiBEaWdpdDBcbiAgICB8IDE4OSAtPiBNaW51c1xuICAgIHwgMTg3IC0+IEVxdWFsXG4gICAgfCA4IC0+IEJhY2tzcGFjZVxuICAgIHwgOSAtPiBUYWJcbiAgICB8IDgxIC0+IEtleVFcbiAgICB8IDg3IC0+IEtleVdcbiAgICB8IDY5IC0+IEtleUVcbiAgICB8IDgyIC0+IEtleVJcbiAgICB8IDg0IC0+IEtleVRcbiAgICB8IDg5IC0+IEtleVlcbiAgICB8IDg1IC0+IEtleVVcbiAgICB8IDczIC0+IEtleUlcbiAgICB8IDc5IC0+IEtleU9cbiAgICB8IDgwIC0+IEtleVBcbiAgICB8IDIxOSAtPiBCcmFja2V0TGVmdFxuICAgIHwgMjIxIC0+IEJyYWNrZXRSaWdodFxuICAgIHwgMjIwIC0+IEJhY2tzbGFzaFxuICAgIHwgMjAgLT4gQ2Fwc0xvY2tcbiAgICB8IDY1IC0+IEtleUFcbiAgICB8IDgzIC0+IEtleVNcbiAgICB8IDY4IC0+IEtleURcbiAgICB8IDcwIC0+IEtleUZcbiAgICB8IDcxIC0+IEtleUdcbiAgICB8IDcyIC0+IEtleUhcbiAgICB8IDc0IC0+IEtleUpcbiAgICB8IDc1IC0+IEtleUtcbiAgICB8IDc2IC0+IEtleUxcbiAgICB8IDE4NiAtPiBTZW1pY29sb25cbiAgICB8IDIyMiAtPiBRdW90ZVxuICAgIHwgMTMgLT4gRW50ZXJcbiAgICB8IDkwIC0+IEtleVpcbiAgICB8IDg4IC0+IEtleVhcbiAgICB8IDY3IC0+IEtleUNcbiAgICB8IDg2IC0+IEtleVZcbiAgICB8IDY2IC0+IEtleUJcbiAgICB8IDc4IC0+IEtleU5cbiAgICB8IDc3IC0+IEtleU1cbiAgICB8IDE4OCAtPiBDb21tYVxuICAgIHwgMTkwIC0+IFBlcmlvZFxuICAgIHwgMTkxIC0+IFNsYXNoXG4gICAgfCAzMiAtPiBTcGFjZVxuICAgIHwgOTMgLT4gQ29udGV4dE1lbnVcbiAgICB8IDQ1IC0+IEluc2VydFxuICAgIHwgMzYgLT4gSG9tZVxuICAgIHwgMzMgLT4gUGFnZVVwXG4gICAgfCA0NiAtPiBEZWxldGVcbiAgICB8IDM1IC0+IEVuZFxuICAgIHwgMzQgLT4gUGFnZURvd25cbiAgICB8IDM3IC0+IEFycm93TGVmdFxuICAgIHwgNDAgLT4gQXJyb3dEb3duXG4gICAgfCAzOSAtPiBBcnJvd1JpZ2h0XG4gICAgfCAzOCAtPiBBcnJvd1VwXG4gICAgfCBfIC0+IFVuaWRlbnRpZmllZFxuXG4gIGxldCBtYWtlX3VuaWRlbnRpZmllZCBfID0gVW5pZGVudGlmaWVkXG5cbiAgbGV0IHRyeV9uZXh0IHZhbHVlIGYgPSBmdW5jdGlvblxuICAgIHwgVW5pZGVudGlmaWVkIC0+IE9wdGRlZi5jYXNlIHZhbHVlIG1ha2VfdW5pZGVudGlmaWVkIGZcbiAgICB8IHYgLT4gdlxuXG4gIGxldCBydW5fbmV4dCB2YWx1ZSBmID0gZnVuY3Rpb25cbiAgICB8IFVuaWRlbnRpZmllZCAtPiBmIHZhbHVlXG4gICAgfCB2IC0+IHZcblxuICBsZXQgZ2V0X2tleV9jb2RlIGV2dCA9IGV2dCMjLmtleUNvZGVcblxuICBsZXQgdHJ5X2tleV9sb2NhdGlvbiBldnQgPVxuICAgIG1hdGNoIGV2dCMjLmxvY2F0aW9uIHdpdGhcbiAgICB8IDEgLT4gcnVuX25leHQgKGdldF9rZXlfY29kZSBldnQpIHRyeV9rZXlfY29kZV9sZWZ0XG4gICAgfCAyIC0+IHJ1bl9uZXh0IChnZXRfa2V5X2NvZGUgZXZ0KSB0cnlfa2V5X2NvZGVfcmlnaHRcbiAgICB8IDMgLT4gcnVuX25leHQgKGdldF9rZXlfY29kZSBldnQpIHRyeV9rZXlfY29kZV9udW1wYWRcbiAgICB8IF8gLT4gbWFrZV91bmlkZW50aWZpZWRcblxuICBsZXQgKCB8PiApIHggZiA9IGYgeFxuXG4gIGxldCBvZl9ldmVudCBldnQgPVxuICAgIFVuaWRlbnRpZmllZFxuICAgIHw+IHRyeV9uZXh0IGV2dCMjLmNvZGUgdHJ5X2NvZGVcbiAgICB8PiB0cnlfa2V5X2xvY2F0aW9uIGV2dFxuICAgIHw+IHJ1bl9uZXh0IChnZXRfa2V5X2NvZGUgZXZ0KSB0cnlfa2V5X2NvZGVfbm9ybWFsXG5cbiAgbGV0IG9mX2tleV9jb2RlID0gdHJ5X2tleV9jb2RlX25vcm1hbFxuZW5kXG5cbm1vZHVsZSBLZXlib2FyZF9rZXkgPSBzdHJ1Y3RcbiAgdHlwZSB0ID0gVWNoYXIudCBvcHRpb25cblxuICBsZXQgY2hhcl9vZl9pbnQgdmFsdWUgPVxuICAgIGlmIDAgPCB2YWx1ZSB0aGVuIHRyeSBTb21lIChVY2hhci5vZl9pbnQgdmFsdWUpIHdpdGggXyAtPiBOb25lIGVsc2UgTm9uZVxuXG4gIGxldCBlbXB0eV9zdHJpbmcgXyA9IEpzLnN0cmluZyBcIlwiXG5cbiAgbGV0IG5vbmUgXyA9IE5vbmVcblxuICBsZXQgb2ZfZXZlbnQgZXZ0ID1cbiAgICBsZXQga2V5ID0gT3B0ZGVmLmdldCBldnQjIy5rZXkgZW1wdHlfc3RyaW5nIGluXG4gICAgbWF0Y2gga2V5IyMubGVuZ3RoIHdpdGhcbiAgICB8IDAgLT4gT3B0ZGVmLmNhc2UgZXZ0IyMuY2hhckNvZGUgbm9uZSBjaGFyX29mX2ludFxuICAgIHwgMSAtPiBjaGFyX29mX2ludCAoaW50X29mX2Zsb2F0IChKcy50b19mbG9hdCAoa2V5IyNjaGFyQ29kZUF0IDApKSlcbiAgICB8IF8gLT4gTm9uZVxuZW5kXG5cbigqKioqKilcblxubGV0IGVsZW1lbnQgOiAjRG9tLmVsZW1lbnQgdCAtPiBlbGVtZW50IHQgPSBKcy5VbnNhZmUuY29lcmNlXG5cbnR5cGUgdGFnZ2VkRWxlbWVudCA9XG4gIHwgQSBvZiBhbmNob3JFbGVtZW50IHRcbiAgfCBBcmVhIG9mIGFyZWFFbGVtZW50IHRcbiAgfCBBdWRpbyBvZiBhdWRpb0VsZW1lbnQgdFxuICB8IEJhc2Ugb2YgYmFzZUVsZW1lbnQgdFxuICB8IEJsb2NrcXVvdGUgb2YgcXVvdGVFbGVtZW50IHRcbiAgfCBCb2R5IG9mIGJvZHlFbGVtZW50IHRcbiAgfCBCciBvZiBickVsZW1lbnQgdFxuICB8IEJ1dHRvbiBvZiBidXR0b25FbGVtZW50IHRcbiAgfCBDYW52YXMgb2YgY2FudmFzRWxlbWVudCB0XG4gIHwgQ2FwdGlvbiBvZiB0YWJsZUNhcHRpb25FbGVtZW50IHRcbiAgfCBDb2wgb2YgdGFibGVDb2xFbGVtZW50IHRcbiAgfCBDb2xncm91cCBvZiB0YWJsZUNvbEVsZW1lbnQgdFxuICB8IERlbCBvZiBtb2RFbGVtZW50IHRcbiAgfCBEaWFsb2cgb2YgZGlhbG9nRWxlbWVudCB0XG4gIHwgRGl2IG9mIGRpdkVsZW1lbnQgdFxuICB8IERsIG9mIGRMaXN0RWxlbWVudCB0XG4gIHwgRW1iZWQgb2YgZW1iZWRFbGVtZW50IHRcbiAgfCBGaWVsZHNldCBvZiBmaWVsZFNldEVsZW1lbnQgdFxuICB8IEZvcm0gb2YgZm9ybUVsZW1lbnQgdFxuICB8IEZyYW1lc2V0IG9mIGZyYW1lU2V0RWxlbWVudCB0XG4gIHwgRnJhbWUgb2YgZnJhbWVFbGVtZW50IHRcbiAgfCBIMSBvZiBoZWFkaW5nRWxlbWVudCB0XG4gIHwgSDIgb2YgaGVhZGluZ0VsZW1lbnQgdFxuICB8IEgzIG9mIGhlYWRpbmdFbGVtZW50IHRcbiAgfCBINCBvZiBoZWFkaW5nRWxlbWVudCB0XG4gIHwgSDUgb2YgaGVhZGluZ0VsZW1lbnQgdFxuICB8IEg2IG9mIGhlYWRpbmdFbGVtZW50IHRcbiAgfCBIZWFkIG9mIGhlYWRFbGVtZW50IHRcbiAgfCBIciBvZiBockVsZW1lbnQgdFxuICB8IEh0bWwgb2YgaHRtbEVsZW1lbnQgdFxuICB8IElmcmFtZSBvZiBpRnJhbWVFbGVtZW50IHRcbiAgfCBJbWcgb2YgaW1hZ2VFbGVtZW50IHRcbiAgfCBJbnB1dCBvZiBpbnB1dEVsZW1lbnQgdFxuICB8IElucyBvZiBtb2RFbGVtZW50IHRcbiAgfCBMYWJlbCBvZiBsYWJlbEVsZW1lbnQgdFxuICB8IExlZ2VuZCBvZiBsZWdlbmRFbGVtZW50IHRcbiAgfCBMaSBvZiBsaUVsZW1lbnQgdFxuICB8IExpbmsgb2YgbGlua0VsZW1lbnQgdFxuICB8IE1hcCBvZiBtYXBFbGVtZW50IHRcbiAgfCBNZXRhIG9mIG1ldGFFbGVtZW50IHRcbiAgfCBPYmplY3Qgb2Ygb2JqZWN0RWxlbWVudCB0XG4gIHwgT2wgb2Ygb0xpc3RFbGVtZW50IHRcbiAgfCBPcHRncm91cCBvZiBvcHRHcm91cEVsZW1lbnQgdFxuICB8IE9wdGlvbiBvZiBvcHRpb25FbGVtZW50IHRcbiAgfCBQIG9mIHBhcmFncmFwaEVsZW1lbnQgdFxuICB8IFBhcmFtIG9mIHBhcmFtRWxlbWVudCB0XG4gIHwgUHJlIG9mIHByZUVsZW1lbnQgdFxuICB8IFEgb2YgcXVvdGVFbGVtZW50IHRcbiAgfCBTY3JpcHQgb2Ygc2NyaXB0RWxlbWVudCB0XG4gIHwgU2VsZWN0IG9mIHNlbGVjdEVsZW1lbnQgdFxuICB8IFN0eWxlIG9mIHN0eWxlRWxlbWVudCB0XG4gIHwgVGFibGUgb2YgdGFibGVFbGVtZW50IHRcbiAgfCBUYm9keSBvZiB0YWJsZVNlY3Rpb25FbGVtZW50IHRcbiAgfCBUZCBvZiB0YWJsZUNlbGxFbGVtZW50IHRcbiAgfCBUZXh0YXJlYSBvZiB0ZXh0QXJlYUVsZW1lbnQgdFxuICB8IFRmb290IG9mIHRhYmxlU2VjdGlvbkVsZW1lbnQgdFxuICB8IFRoIG9mIHRhYmxlQ2VsbEVsZW1lbnQgdFxuICB8IFRoZWFkIG9mIHRhYmxlU2VjdGlvbkVsZW1lbnQgdFxuICB8IFRpdGxlIG9mIHRpdGxlRWxlbWVudCB0XG4gIHwgVHIgb2YgdGFibGVSb3dFbGVtZW50IHRcbiAgfCBVbCBvZiB1TGlzdEVsZW1lbnQgdFxuICB8IFZpZGVvIG9mIHZpZGVvRWxlbWVudCB0XG4gIHwgT3RoZXIgb2YgZWxlbWVudCB0XG5cbmxldCBvdGhlciBlID0gT3RoZXIgKGUgOiAjZWxlbWVudCB0IDo+IGVsZW1lbnQgdClcblxubGV0IHRhZ2dlZCAoZSA6ICNlbGVtZW50IHQpID1cbiAgbGV0IHRhZyA9IEpzLnRvX2J5dGVzdHJpbmcgZSMjLnRhZ05hbWUjI3RvTG93ZXJDYXNlIGluXG4gIGlmIFN0cmluZy5sZW5ndGggdGFnID0gMFxuICB0aGVuIG90aGVyIGVcbiAgZWxzZVxuICAgIG1hdGNoIFN0cmluZy51bnNhZmVfZ2V0IHRhZyAwIHdpdGhcbiAgICB8ICdhJyAtPiAoXG4gICAgICAgIG1hdGNoIHRhZyB3aXRoXG4gICAgICAgIHwgXCJhXCIgLT4gQSAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICAgICAgICB8IFwiYXJlYVwiIC0+IEFyZWEgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcImF1ZGlvXCIgLT4gQXVkaW8gKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBfIC0+IG90aGVyIGUpXG4gICAgfCAnYicgLT4gKFxuICAgICAgICBtYXRjaCB0YWcgd2l0aFxuICAgICAgICB8IFwiYmFzZVwiIC0+IEJhc2UgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcImJsb2NrcXVvdGVcIiAtPiBCbG9ja3F1b3RlIChKcy5VbnNhZmUuY29lcmNlIGUpXG4gICAgICAgIHwgXCJib2R5XCIgLT4gQm9keSAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICAgICAgICB8IFwiYnJcIiAtPiBCciAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICAgICAgICB8IFwiYnV0dG9uXCIgLT4gQnV0dG9uIChKcy5VbnNhZmUuY29lcmNlIGUpXG4gICAgICAgIHwgXyAtPiBvdGhlciBlKVxuICAgIHwgJ2MnIC0+IChcbiAgICAgICAgbWF0Y2ggdGFnIHdpdGhcbiAgICAgICAgfCBcImNhbnZhc1wiIC0+IENhbnZhcyAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICAgICAgICB8IFwiY2FwdGlvblwiIC0+IENhcHRpb24gKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcImNvbFwiIC0+IENvbCAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICAgICAgICB8IFwiY29sZ3JvdXBcIiAtPiBDb2xncm91cCAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICAgICAgICB8IF8gLT4gb3RoZXIgZSlcbiAgICB8ICdkJyAtPiAoXG4gICAgICAgIG1hdGNoIHRhZyB3aXRoXG4gICAgICAgIHwgXCJkZWxcIiAtPiBEZWwgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcImRpdlwiIC0+IERpdiAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICAgICAgICB8IFwiZGxcIiAtPiBEbCAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICAgICAgICB8IF8gLT4gb3RoZXIgZSlcbiAgICB8ICdlJyAtPiAoXG4gICAgICAgIG1hdGNoIHRhZyB3aXRoXG4gICAgICAgIHwgXCJlbWJlZFwiIC0+IEVtYmVkIChKcy5VbnNhZmUuY29lcmNlIGUpXG4gICAgICAgIHwgXyAtPiBvdGhlciBlKVxuICAgIHwgJ2YnIC0+IChcbiAgICAgICAgbWF0Y2ggdGFnIHdpdGhcbiAgICAgICAgfCBcImZpZWxkc2V0XCIgLT4gRmllbGRzZXQgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcImZvcm1cIiAtPiBGb3JtIChKcy5VbnNhZmUuY29lcmNlIGUpXG4gICAgICAgIHwgXCJmcmFtZXNldFwiIC0+IEZyYW1lc2V0IChKcy5VbnNhZmUuY29lcmNlIGUpXG4gICAgICAgIHwgXCJmcmFtZVwiIC0+IEZyYW1lIChKcy5VbnNhZmUuY29lcmNlIGUpXG4gICAgICAgIHwgXyAtPiBvdGhlciBlKVxuICAgIHwgJ2gnIC0+IChcbiAgICAgICAgbWF0Y2ggdGFnIHdpdGhcbiAgICAgICAgfCBcImgxXCIgLT4gSDEgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcImgyXCIgLT4gSDIgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcImgzXCIgLT4gSDMgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcImg0XCIgLT4gSDQgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcImg1XCIgLT4gSDUgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcImg2XCIgLT4gSDYgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcImhlYWRcIiAtPiBIZWFkIChKcy5VbnNhZmUuY29lcmNlIGUpXG4gICAgICAgIHwgXCJoclwiIC0+IEhyIChKcy5VbnNhZmUuY29lcmNlIGUpXG4gICAgICAgIHwgXCJodG1sXCIgLT4gSHRtbCAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICAgICAgICB8IF8gLT4gb3RoZXIgZSlcbiAgICB8ICdpJyAtPiAoXG4gICAgICAgIG1hdGNoIHRhZyB3aXRoXG4gICAgICAgIHwgXCJpZnJhbWVcIiAtPiBJZnJhbWUgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcImltZ1wiIC0+IEltZyAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICAgICAgICB8IFwiaW5wdXRcIiAtPiBJbnB1dCAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICAgICAgICB8IFwiaW5zXCIgLT4gSW5zIChKcy5VbnNhZmUuY29lcmNlIGUpXG4gICAgICAgIHwgXyAtPiBvdGhlciBlKVxuICAgIHwgJ2wnIC0+IChcbiAgICAgICAgbWF0Y2ggdGFnIHdpdGhcbiAgICAgICAgfCBcImxhYmVsXCIgLT4gTGFiZWwgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcImxlZ2VuZFwiIC0+IExlZ2VuZCAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICAgICAgICB8IFwibGlcIiAtPiBMaSAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICAgICAgICB8IFwibGlua1wiIC0+IExpbmsgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBfIC0+IG90aGVyIGUpXG4gICAgfCAnbScgLT4gKFxuICAgICAgICBtYXRjaCB0YWcgd2l0aFxuICAgICAgICB8IFwibWFwXCIgLT4gTWFwIChKcy5VbnNhZmUuY29lcmNlIGUpXG4gICAgICAgIHwgXCJtZXRhXCIgLT4gTWV0YSAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICAgICAgICB8IF8gLT4gb3RoZXIgZSlcbiAgICB8ICdvJyAtPiAoXG4gICAgICAgIG1hdGNoIHRhZyB3aXRoXG4gICAgICAgIHwgXCJvYmplY3RcIiAtPiBPYmplY3QgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcIm9sXCIgLT4gT2wgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcIm9wdGdyb3VwXCIgLT4gT3B0Z3JvdXAgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcIm9wdGlvblwiIC0+IE9wdGlvbiAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICAgICAgICB8IF8gLT4gb3RoZXIgZSlcbiAgICB8ICdwJyAtPiAoXG4gICAgICAgIG1hdGNoIHRhZyB3aXRoXG4gICAgICAgIHwgXCJwXCIgLT4gUCAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICAgICAgICB8IFwicGFyYW1cIiAtPiBQYXJhbSAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICAgICAgICB8IFwicHJlXCIgLT4gUHJlIChKcy5VbnNhZmUuY29lcmNlIGUpXG4gICAgICAgIHwgXyAtPiBvdGhlciBlKVxuICAgIHwgJ3EnIC0+IChcbiAgICAgICAgbWF0Y2ggdGFnIHdpdGhcbiAgICAgICAgfCBcInFcIiAtPiBRIChKcy5VbnNhZmUuY29lcmNlIGUpXG4gICAgICAgIHwgXyAtPiBvdGhlciBlKVxuICAgIHwgJ3MnIC0+IChcbiAgICAgICAgbWF0Y2ggdGFnIHdpdGhcbiAgICAgICAgfCBcInNjcmlwdFwiIC0+IFNjcmlwdCAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICAgICAgICB8IFwic2VsZWN0XCIgLT4gU2VsZWN0IChKcy5VbnNhZmUuY29lcmNlIGUpXG4gICAgICAgIHwgXCJzdHlsZVwiIC0+IFN0eWxlIChKcy5VbnNhZmUuY29lcmNlIGUpXG4gICAgICAgIHwgXyAtPiBvdGhlciBlKVxuICAgIHwgJ3QnIC0+IChcbiAgICAgICAgbWF0Y2ggdGFnIHdpdGhcbiAgICAgICAgfCBcInRhYmxlXCIgLT4gVGFibGUgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcInRib2R5XCIgLT4gVGJvZHkgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcInRkXCIgLT4gVGQgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcInRleHRhcmVhXCIgLT4gVGV4dGFyZWEgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcInRmb290XCIgLT4gVGZvb3QgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcInRoXCIgLT4gVGggKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcInRoZWFkXCIgLT4gVGhlYWQgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcInRpdGxlXCIgLT4gVGl0bGUgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBcInRyXCIgLT4gVHIgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICAgICAgfCBfIC0+IG90aGVyIGUpXG4gICAgfCAndScgLT4gKFxuICAgICAgICBtYXRjaCB0YWcgd2l0aFxuICAgICAgICB8IFwidWxcIiAtPiBVbCAoSnMuVW5zYWZlLmNvZXJjZSBlKVxuICAgICAgICB8IF8gLT4gb3RoZXIgZSlcbiAgICB8ICd2JyAtPiAoXG4gICAgICAgIG1hdGNoIHRhZyB3aXRoXG4gICAgICAgIHwgXCJ2aWRlb1wiIC0+IFZpZGVvIChKcy5VbnNhZmUuY29lcmNlIGUpXG4gICAgICAgIHwgXyAtPiBvdGhlciBlKVxuICAgIHwgXyAtPiBvdGhlciBlXG5cbmxldCBvcHRfdGFnZ2VkIGUgPSBPcHQuY2FzZSBlIChmdW4gKCkgLT4gTm9uZSkgKGZ1biBlIC0+IFNvbWUgKHRhZ2dlZCBlKSlcblxudHlwZSB0YWdnZWRFdmVudCA9XG4gIHwgTW91c2VFdmVudCBvZiBtb3VzZUV2ZW50IHRcbiAgfCBLZXlib2FyZEV2ZW50IG9mIGtleWJvYXJkRXZlbnQgdFxuICB8IE1lc3NhZ2VFdmVudCBvZiBtZXNzYWdlRXZlbnQgdFxuICB8IE1vdXNld2hlZWxFdmVudCBvZiBtb3VzZXdoZWVsRXZlbnQgdFxuICB8IE1vdXNlU2Nyb2xsRXZlbnQgb2YgbW91c2VTY3JvbGxFdmVudCB0XG4gIHwgUG9wU3RhdGVFdmVudCBvZiBwb3BTdGF0ZUV2ZW50IHRcbiAgfCBPdGhlckV2ZW50IG9mIGV2ZW50IHRcblxubGV0IHRhZ2dlZEV2ZW50IChldiA6ICNldmVudCBKcy50KSA9XG4gIEpzLk9wdC5jYXNlXG4gICAgKENvZXJjZVRvLm1vdXNlRXZlbnQgZXYpXG4gICAgKGZ1biAoKSAtPlxuICAgICAgSnMuT3B0LmNhc2VcbiAgICAgICAgKENvZXJjZVRvLmtleWJvYXJkRXZlbnQgZXYpXG4gICAgICAgIChmdW4gKCkgLT5cbiAgICAgICAgICBKcy5PcHQuY2FzZVxuICAgICAgICAgICAgKENvZXJjZVRvLndoZWVsRXZlbnQgZXYpXG4gICAgICAgICAgICAoZnVuICgpIC0+XG4gICAgICAgICAgICAgIEpzLk9wdC5jYXNlXG4gICAgICAgICAgICAgICAgKENvZXJjZVRvLm1vdXNlU2Nyb2xsRXZlbnQgZXYpXG4gICAgICAgICAgICAgICAgKGZ1biAoKSAtPlxuICAgICAgICAgICAgICAgICAgSnMuT3B0LmNhc2VcbiAgICAgICAgICAgICAgICAgICAgKENvZXJjZVRvLnBvcFN0YXRlRXZlbnQgZXYpXG4gICAgICAgICAgICAgICAgICAgIChmdW4gKCkgLT5cbiAgICAgICAgICAgICAgICAgICAgICBKcy5PcHQuY2FzZVxuICAgICAgICAgICAgICAgICAgICAgICAgKENvZXJjZVRvLm1lc3NhZ2VFdmVudCBldilcbiAgICAgICAgICAgICAgICAgICAgICAgIChmdW4gKCkgLT4gT3RoZXJFdmVudCAoZXYgOj4gZXZlbnQgdCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAoZnVuIGV2IC0+IE1lc3NhZ2VFdmVudCBldikpXG4gICAgICAgICAgICAgICAgICAgIChmdW4gZXYgLT4gUG9wU3RhdGVFdmVudCBldikpXG4gICAgICAgICAgICAgICAgKGZ1biBldiAtPiBNb3VzZVNjcm9sbEV2ZW50IGV2KSlcbiAgICAgICAgICAgIChmdW4gZXYgLT4gTW91c2V3aGVlbEV2ZW50IGV2KSlcbiAgICAgICAgKGZ1biBldiAtPiBLZXlib2FyZEV2ZW50IGV2KSlcbiAgICAoZnVuIGV2IC0+IE1vdXNlRXZlbnQgZXYpXG5cbmxldCBvcHRfdGFnZ2VkRXZlbnQgZXYgPSBPcHQuY2FzZSBldiAoZnVuICgpIC0+IE5vbmUpIChmdW4gZXYgLT4gU29tZSAodGFnZ2VkRXZlbnQgZXYpKVxuXG5sZXQgc3RvcFByb3BhZ2F0aW9uIGV2ID1cbiAgbGV0IGUgPSBKcy5VbnNhZmUuY29lcmNlIGV2IGluXG4gIE9wdGRlZi5jYXNlXG4gICAgZSMjLnN0b3BQcm9wYWdhdGlvblxuICAgIChmdW4gKCkgLT4gZSMjLmNhbmNlbEJ1YmJsZSA6PSBKcy5fdHJ1ZSlcbiAgICAoZnVuIF8gLT4gZSMjX3N0b3BQcm9wYWdhdGlvbilcblxubGV0IF9yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgOiAodW5pdCAtPiB1bml0KSBKcy5jYWxsYmFjayAtPiB1bml0ID1cbiAgSnMuVW5zYWZlLnB1cmVfZXhwciAoZnVuIF8gLT5cbiAgICAgIGxldCB3ID0gSnMuVW5zYWZlLmNvZXJjZSB3aW5kb3cgaW5cbiAgICAgIGxldCBsID1cbiAgICAgICAgWyB3IyMucmVxdWVzdEFuaW1hdGlvbkZyYW1lXG4gICAgICAgIDsgdyMjLm1velJlcXVlc3RBbmltYXRpb25GcmFtZVxuICAgICAgICA7IHcjIy53ZWJraXRSZXF1ZXN0QW5pbWF0aW9uRnJhbWVcbiAgICAgICAgOyB3IyMub1JlcXVlc3RBbmltYXRpb25GcmFtZVxuICAgICAgICA7IHcjIy5tc1JlcXVlc3RBbmltYXRpb25GcmFtZVxuICAgICAgICBdXG4gICAgICBpblxuICAgICAgdHJ5XG4gICAgICAgIGxldCByZXEgPSBMaXN0LmZpbmQgKGZ1biBjIC0+IEpzLk9wdGRlZi50ZXN0IGMpIGwgaW5cbiAgICAgICAgZnVuIGNhbGxiYWNrIC0+IEpzLlVuc2FmZS5mdW5fY2FsbCByZXEgW3wgSnMuVW5zYWZlLmluamVjdCBjYWxsYmFjayB8XVxuICAgICAgd2l0aCBOb3RfZm91bmQgLT5cbiAgICAgICAgbGV0IG5vdyAoKSA9IEpzLnRvX2Zsb2F0IChuZXclanMgSnMuZGF0ZV9ub3cpIyNnZXRUaW1lIGluXG4gICAgICAgIGxldCBsYXN0ID0gcmVmIChub3cgKCkpIGluXG4gICAgICAgIGZ1biBjYWxsYmFjayAtPlxuICAgICAgICAgIGxldCB0ID0gbm93ICgpIGluXG4gICAgICAgICAgbGV0IGR0ID0gIWxhc3QgKy4gKDEwMDAuIC8uIDYwLikgLS4gdCBpblxuICAgICAgICAgIGxldCBkdCA9IGlmIFBvbHkuKGR0IDwgMC4pIHRoZW4gMC4gZWxzZSBkdCBpblxuICAgICAgICAgIGxhc3QgOj0gdDtcbiAgICAgICAgICBpZ25vcmUgKHdpbmRvdyMjc2V0VGltZW91dCBjYWxsYmFjayAoSnMuZmxvYXQgZHQpKSlcblxuKCoqKiopXG5cbmxldCBoYXNQdXNoU3RhdGUgKCkgPSBKcy5PcHRkZWYudGVzdCAoSnMuVW5zYWZlLmNvZXJjZSB3aW5kb3cjIy5oaXN0b3J5KSMjLnB1c2hTdGF0ZVxuXG5sZXQgaGFzUGxhY2Vob2xkZXIgKCkgPVxuICBsZXQgaSA9IGNyZWF0ZUlucHV0IGRvY3VtZW50IGluXG4gIEpzLk9wdGRlZi50ZXN0IChKcy5VbnNhZmUuY29lcmNlIGkpIyMucGxhY2Vob2xkZXJcblxubGV0IGhhc1JlcXVpcmVkICgpID1cbiAgbGV0IGkgPSBjcmVhdGVJbnB1dCBkb2N1bWVudCBpblxuICBKcy5PcHRkZWYudGVzdCAoSnMuVW5zYWZlLmNvZXJjZSBpKSMjLnJlcXVpcmVkXG5cbmxldCBvdmVyZmxvd19saW1pdCA9IDIxNDc0ODNfMDAwLlxuXG4oKiBtcyAqKVxuXG50eXBlIHRpbWVvdXRfaWRfc2FmZSA9IHRpbWVvdXRfaWQgb3B0aW9uIHJlZlxuXG5sZXQgc2V0VGltZW91dCBjYWxsYmFjayBkIDogdGltZW91dF9pZF9zYWZlID1cbiAgbGV0IGlkID0gcmVmIE5vbmUgaW5cbiAgbGV0IHJlYyBsb29wIGQgKCkgPVxuICAgIGxldCBzdGVwLCByZW1haW4gPVxuICAgICAgaWYgUG9seS4oZCA+IG92ZXJmbG93X2xpbWl0KSB0aGVuIG92ZXJmbG93X2xpbWl0LCBkIC0uIG92ZXJmbG93X2xpbWl0IGVsc2UgZCwgMC5cbiAgICBpblxuICAgIGxldCBjYiA9IGlmIFBvbHkuKHJlbWFpbiA9IDAuKSB0aGVuIGNhbGxiYWNrIGVsc2UgbG9vcCByZW1haW4gaW5cbiAgICBpZCA6PSBTb21lICh3aW5kb3cjI3NldFRpbWVvdXQgKEpzLndyYXBfY2FsbGJhY2sgY2IpIChKcy5mbG9hdCBzdGVwKSlcbiAgaW5cbiAgbG9vcCBkICgpO1xuICBpZFxuXG5sZXQgY2xlYXJUaW1lb3V0IChpZCA6IHRpbWVvdXRfaWRfc2FmZSkgPVxuICBtYXRjaCAhaWQgd2l0aFxuICB8IE5vbmUgLT4gKClcbiAgfCBTb21lIHggLT5cbiAgICAgIGlkIDo9IE5vbmU7XG4gICAgICB3aW5kb3cjI2NsZWFyVGltZW91dCB4XG5cbmxldCBqc19hcnJheV9vZl9jb2xsZWN0aW9uIChjIDogI2VsZW1lbnQgY29sbGVjdGlvbiBKcy50KSA6ICNlbGVtZW50IEpzLnQgSnMuanNfYXJyYXkgSnMudFxuICAgID1cbiAgSnMuVW5zYWZlLihtZXRoX2NhbGwgKGpzX2V4cHIgXCJbXS5zbGljZVwiKSBcImNhbGxcIiBbfCBpbmplY3QgYyB8XSlcbiIsIigqIEpzX29mX29jYW1sIGxpYnJhcnlcbiAqIGh0dHA6Ly93d3cub2NzaWdlbi5vcmcvanNfb2Zfb2NhbWwvXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTEgUGllcnJlIENoYW1iYXJ0XG4gKiBMYWJvcmF0b2lyZSBQUFMgLSBDTlJTIFVuaXZlcnNpdMOpIFBhcmlzIERpZGVyb3RcbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCB3aXRoIGxpbmtpbmcgZXhjZXB0aW9uO1xuICogZWl0aGVyIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuXG4gKilcblxub3BlbiBKc1xub3BlbiBEb21faHRtbFxub3BlbiEgSW1wb3J0XG5cbmNsYXNzIHR5cGUgZm9ybURhdGEgPSBvYmplY3RcbiAgbWV0aG9kIGFwcGVuZCA6IGpzX3N0cmluZyB0IC0+IGpzX3N0cmluZyB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBhcHBlbmRfYmxvYiA6IGpzX3N0cmluZyB0IC0+IEZpbGUuYmxvYiB0IC0+IHVuaXQgbWV0aFxuZW5kXG5cbmxldCBmb3JtRGF0YSA6IGZvcm1EYXRhIHQgY29uc3RyID0gSnMuVW5zYWZlLmdsb2JhbCMjLl9Gb3JtRGF0YVxuXG5sZXQgZm9ybURhdGFfZm9ybSA6IChmb3JtRWxlbWVudCB0IC0+IGZvcm1EYXRhIHQpIGNvbnN0ciA9IEpzLlVuc2FmZS5nbG9iYWwjIy5fRm9ybURhdGFcblxudHlwZSBmb3JtX2VsdCA9XG4gIFsgYFN0cmluZyBvZiBqc19zdHJpbmcgdFxuICB8IGBGaWxlIG9mIEZpbGUuZmlsZSB0XG4gIF1cblxudHlwZSBmb3JtX2NvbnRlbnRzID1cbiAgWyBgRmllbGRzIG9mIChzdHJpbmcgKiBmb3JtX2VsdCkgbGlzdCByZWZcbiAgfCBgRm9ybURhdGEgb2YgZm9ybURhdGEgdFxuICBdXG5cbmxldCByZWMgZmlsdGVyX21hcCBmID0gZnVuY3Rpb25cbiAgfCBbXSAtPiBbXVxuICB8IHYgOjogcSAtPiAoXG4gICAgICBtYXRjaCBmIHYgd2l0aFxuICAgICAgfCBOb25lIC0+IGZpbHRlcl9tYXAgZiBxXG4gICAgICB8IFNvbWUgdicgLT4gdicgOjogZmlsdGVyX21hcCBmIHEpXG5cbmNsYXNzIHR5cGUgc3VibWl0dGFibGVFbGVtZW50ID0gb2JqZWN0XG4gIG1ldGhvZCBkaXNhYmxlZCA6IGJvb2wgdCBwcm9wXG5cbiAgbWV0aG9kIG5hbWUgOiBqc19zdHJpbmcgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHZhbHVlIDoganNfc3RyaW5nIHQgcHJvcFxuZW5kXG5cbmxldCBoYXZlX2NvbnRlbnQgKGVsdCA6IHN1Ym1pdHRhYmxlRWxlbWVudCB0KSA9XG4gIGVsdCMjLm5hbWUjIy5sZW5ndGggPiAwICYmIG5vdCAoSnMudG9fYm9vbCBlbHQjIy5kaXNhYmxlZClcblxubGV0IGdldF90ZXh0YXJlYV92YWwgKGVsdCA6IHRleHRBcmVhRWxlbWVudCB0KSA9XG4gIGlmIGhhdmVfY29udGVudCAoZWx0IDo+IHN1Ym1pdHRhYmxlRWxlbWVudCB0KVxuICB0aGVuXG4gICAgbGV0IG5hbWUgPSB0b19zdHJpbmcgZWx0IyMubmFtZSBpblxuICAgIFsgbmFtZSwgYFN0cmluZyBlbHQjIy52YWx1ZSBdXG4gIGVsc2UgW11cblxubGV0IGdldF9zZWxlY3RfdmFsIChlbHQgOiBzZWxlY3RFbGVtZW50IHQpID1cbiAgaWYgaGF2ZV9jb250ZW50IChlbHQgOj4gc3VibWl0dGFibGVFbGVtZW50IHQpXG4gIHRoZW5cbiAgICBsZXQgbmFtZSA9IHRvX3N0cmluZyBlbHQjIy5uYW1lIGluXG4gICAgaWYgdG9fYm9vbCBlbHQjIy5tdWx0aXBsZVxuICAgIHRoZW5cbiAgICAgIGxldCBvcHRpb25zID1cbiAgICAgICAgQXJyYXkuaW5pdCBlbHQjIy5vcHRpb25zIyMubGVuZ3RoIChmdW4gaSAtPiBPcHQudG9fb3B0aW9uIChlbHQjIy5vcHRpb25zIyNpdGVtIGkpKVxuICAgICAgaW5cbiAgICAgIGZpbHRlcl9tYXBcbiAgICAgICAgKGZ1bmN0aW9uXG4gICAgICAgICAgfCBOb25lIC0+IE5vbmVcbiAgICAgICAgICB8IFNvbWUgZSAtPlxuICAgICAgICAgICAgICBpZiBKcy50b19ib29sIGUjIy5zZWxlY3RlZCB0aGVuIFNvbWUgKG5hbWUsIGBTdHJpbmcgZSMjLnZhbHVlKSBlbHNlIE5vbmUpXG4gICAgICAgIChBcnJheS50b19saXN0IG9wdGlvbnMpXG4gICAgZWxzZSBbIG5hbWUsIGBTdHJpbmcgZWx0IyMudmFsdWUgXVxuICBlbHNlIFtdXG5cbmNsYXNzIHR5cGUgZmlsZV9pbnB1dCA9IG9iamVjdFxuICBpbmhlcml0IGlucHV0RWxlbWVudFxuXG4gIG1ldGhvZCBmaWxlcyA6IEZpbGUuZmlsZUxpc3QgdCBvcHRkZWYgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBtdWx0aXBsZSA6IGJvb2wgb3B0ZGVmIHJlYWRvbmx5X3Byb3BcbmVuZFxuXG5sZXQgZ2V0X2lucHV0X3ZhbCA/KGdldCA9IGZhbHNlKSAoZWx0IDogaW5wdXRFbGVtZW50IHQpID1cbiAgaWYgaGF2ZV9jb250ZW50IChlbHQgOj4gc3VibWl0dGFibGVFbGVtZW50IHQpXG4gIHRoZW5cbiAgICBsZXQgbmFtZSA9IHRvX3N0cmluZyBlbHQjIy5uYW1lIGluXG4gICAgbGV0IHZhbHVlID0gZWx0IyMudmFsdWUgaW5cbiAgICBtYXRjaCB0b19ieXRlc3RyaW5nIGVsdCMjLl90eXBlIyN0b0xvd2VyQ2FzZSB3aXRoXG4gICAgfCBcImNoZWNrYm94XCIgfCBcInJhZGlvXCIgLT5cbiAgICAgICAgaWYgdG9fYm9vbCBlbHQjIy5jaGVja2VkIHRoZW4gWyBuYW1lLCBgU3RyaW5nIHZhbHVlIF0gZWxzZSBbXVxuICAgIHwgXCJzdWJtaXRcIiB8IFwicmVzZXRcIiAtPiBbXVxuICAgIHwgXCJ0ZXh0XCIgfCBcInBhc3N3b3JkXCIgLT4gWyBuYW1lLCBgU3RyaW5nIHZhbHVlIF1cbiAgICB8IFwiZmlsZVwiIC0+IChcbiAgICAgICAgaWYgZ2V0XG4gICAgICAgIHRoZW4gWyBuYW1lLCBgU3RyaW5nIHZhbHVlIF1cbiAgICAgICAgZWxzZVxuICAgICAgICAgIGxldCBlbHQgOiBmaWxlX2lucHV0IHQgPSBVbnNhZmUuY29lcmNlIGVsdCBpblxuICAgICAgICAgIG1hdGNoIE9wdGRlZi50b19vcHRpb24gZWx0IyMuZmlsZXMgd2l0aFxuICAgICAgICAgIHwgTm9uZSAtPiBbXVxuICAgICAgICAgIHwgU29tZSBsaXN0IC0+IChcbiAgICAgICAgICAgICAgaWYgbGlzdCMjLmxlbmd0aCA9IDBcbiAgICAgICAgICAgICAgdGhlbiBbIG5hbWUsIGBTdHJpbmcgKEpzLnN0cmluZyBcIlwiKSBdXG4gICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBtYXRjaCBPcHRkZWYudG9fb3B0aW9uIGVsdCMjLm11bHRpcGxlIHdpdGhcbiAgICAgICAgICAgICAgICB8IE5vbmUgfCBTb21lIGZhbHNlIC0+IChcbiAgICAgICAgICAgICAgICAgICAgbWF0Y2ggT3B0LnRvX29wdGlvbiAobGlzdCMjaXRlbSAwKSB3aXRoXG4gICAgICAgICAgICAgICAgICAgIHwgTm9uZSAtPiBbXVxuICAgICAgICAgICAgICAgICAgICB8IFNvbWUgZmlsZSAtPiBbIG5hbWUsIGBGaWxlIGZpbGUgXSlcbiAgICAgICAgICAgICAgICB8IFNvbWUgdHJ1ZSAtPlxuICAgICAgICAgICAgICAgICAgICBmaWx0ZXJfbWFwXG4gICAgICAgICAgICAgICAgICAgICAgKGZ1biBmIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXRjaCBPcHQudG9fb3B0aW9uIGYgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgfCBOb25lIC0+IE5vbmVcbiAgICAgICAgICAgICAgICAgICAgICAgIHwgU29tZSBmaWxlIC0+IFNvbWUgKG5hbWUsIGBGaWxlIGZpbGUpKVxuICAgICAgICAgICAgICAgICAgICAgIChBcnJheS50b19saXN0IChBcnJheS5pbml0IGxpc3QjIy5sZW5ndGggKGZ1biBpIC0+IGxpc3QjI2l0ZW0gaSkpKSkpXG4gICAgfCBfIC0+IFsgbmFtZSwgYFN0cmluZyB2YWx1ZSBdXG4gIGVsc2UgW11cblxubGV0IGdldF9mb3JtX2VsZW1lbnRzIChmb3JtIDogZm9ybUVsZW1lbnQgdCkgPVxuICBsZXQgcmVjIGxvb3AgYWNjIGkgPVxuICAgIGlmIGkgPCAwXG4gICAgdGhlbiBhY2NcbiAgICBlbHNlXG4gICAgICBtYXRjaCBPcHQudG9fb3B0aW9uIChmb3JtIyMuZWxlbWVudHMjI2l0ZW0gaSkgd2l0aFxuICAgICAgfCBOb25lIC0+IGxvb3AgYWNjIChpIC0gaSlcbiAgICAgIHwgU29tZSB4IC0+IGxvb3AgKHggOjogYWNjKSAoaSAtIDEpXG4gIGluXG4gIGxvb3AgW10gKGZvcm0jIy5lbGVtZW50cyMjLmxlbmd0aCAtIDEpXG5cbmxldCBnZXRfZWxlbWVudF9jb250ZW50ID9nZXQgdiA9XG4gIG1hdGNoIHRhZ2dlZCB2IHdpdGhcbiAgfCBTZWxlY3QgdiAtPiBnZXRfc2VsZWN0X3ZhbCB2XG4gIHwgSW5wdXQgdiAtPiBnZXRfaW5wdXRfdmFsID9nZXQgdlxuICB8IFRleHRhcmVhIHYgLT4gZ2V0X3RleHRhcmVhX3ZhbCB2XG4gIHwgXyAtPiBbXVxuXG5sZXQgZm9ybV9lbGVtZW50cyA/Z2V0IChmb3JtIDogZm9ybUVsZW1lbnQgdCkgPVxuICBMaXN0LmZsYXR0ZW4gKExpc3QubWFwIChmdW4gdiAtPiBnZXRfZWxlbWVudF9jb250ZW50ID9nZXQgdikgKGdldF9mb3JtX2VsZW1lbnRzIGZvcm0pKVxuXG5sZXQgYXBwZW5kIChmb3JtX2NvbnRlbnRzIDogZm9ybV9jb250ZW50cykgKGZvcm1fZWx0IDogc3RyaW5nICogZm9ybV9lbHQpID1cbiAgbWF0Y2ggZm9ybV9jb250ZW50cyB3aXRoXG4gIHwgYEZpZWxkcyBsaXN0IC0+IGxpc3QgOj0gZm9ybV9lbHQgOjogIWxpc3RcbiAgfCBgRm9ybURhdGEgZiAtPiAoXG4gICAgICBtYXRjaCBmb3JtX2VsdCB3aXRoXG4gICAgICB8IG5hbWUsIGBTdHJpbmcgcyAtPiBmIyNhcHBlbmQgKHN0cmluZyBuYW1lKSBzXG4gICAgICB8IG5hbWUsIGBGaWxlIGZpbGUgLT4gZiMjYXBwZW5kX2Jsb2IgKHN0cmluZyBuYW1lKSAoZmlsZSA6PiBGaWxlLmJsb2IgdCkpXG5cbmxldCBlbXB0eV9mb3JtX2NvbnRlbnRzICgpID1cbiAgbWF0Y2ggT3B0ZGVmLnRvX29wdGlvbiAoSnMuZGVmIGZvcm1EYXRhKSB3aXRoXG4gIHwgTm9uZSAtPiBgRmllbGRzIChyZWYgW10pXG4gIHwgU29tZSBjb25zdHIgLT4gYEZvcm1EYXRhIChuZXclanMgY29uc3RyKVxuXG5sZXQgcG9zdF9mb3JtX2NvbnRlbnRzIGZvcm0gPVxuICBsZXQgY29udGVudHMgPSBlbXB0eV9mb3JtX2NvbnRlbnRzICgpIGluXG4gIExpc3QuaXRlciAoYXBwZW5kIGNvbnRlbnRzKSAoZm9ybV9lbGVtZW50cyBmb3JtKTtcbiAgY29udGVudHNcblxubGV0IGdldF9mb3JtX2NvbnRlbnRzIGZvcm0gPVxuICBMaXN0Lm1hcFxuICAgIChmdW5jdGlvblxuICAgICAgfCBuYW1lLCBgU3RyaW5nIHMgLT4gbmFtZSwgdG9fc3RyaW5nIHNcbiAgICAgIHwgXyAtPiBhc3NlcnQgZmFsc2UpXG4gICAgKGZvcm1fZWxlbWVudHMgfmdldDp0cnVlIGZvcm0pXG4iLCIoKiBKc19vZl9vY2FtbCBsaWJyYXJ5XG4gKiBodHRwOi8vd3d3Lm9jc2lnZW4ub3JnL2pzX29mX29jYW1sL1xuICogQ29weXJpZ2h0IChDKSAyMDEwIErDqXLDtG1lIFZvdWlsbG9uXG4gKiBMYWJvcmF0b2lyZSBQUFMgLSBDTlJTIFVuaXZlcnNpdMOpIFBhcmlzIERpZGVyb3RcbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCB3aXRoIGxpbmtpbmcgZXhjZXB0aW9uO1xuICogZWl0aGVyIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuXG4gKilcblxub3BlbiBKc1xub3BlbiEgSW1wb3J0XG5cbnR5cGUgcmVhZHlTdGF0ZSA9XG4gIHwgVU5TRU5UXG4gIHwgT1BFTkVEXG4gIHwgSEVBREVSU19SRUNFSVZFRFxuICB8IExPQURJTkdcbiAgfCBET05FXG5cbnR5cGUgXyByZXNwb25zZSA9XG4gIHwgQXJyYXlCdWZmZXIgOiBUeXBlZF9hcnJheS5hcnJheUJ1ZmZlciB0IE9wdC50IHJlc3BvbnNlXG4gIHwgQmxvYiA6ICNGaWxlLmJsb2IgdCBPcHQudCByZXNwb25zZVxuICB8IERvY3VtZW50IDogRG9tLmVsZW1lbnQgRG9tLmRvY3VtZW50IHQgT3B0LnQgcmVzcG9uc2VcbiAgfCBKU09OIDogJ2EgT3B0LnQgcmVzcG9uc2VcbiAgfCBUZXh0IDoganNfc3RyaW5nIHQgcmVzcG9uc2VcbiAgfCBEZWZhdWx0IDogc3RyaW5nIHJlc3BvbnNlXG5cbmNsYXNzIHR5cGUgeG1sSHR0cFJlcXVlc3QgPSBvYmplY3QgKCdzZWxmKVxuICBtZXRob2Qgb25yZWFkeXN0YXRlY2hhbmdlIDogKHVuaXQgLT4gdW5pdCkgSnMuY2FsbGJhY2sgSnMud3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2QgcmVhZHlTdGF0ZSA6IHJlYWR5U3RhdGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfb3BlbiA6IGpzX3N0cmluZyB0IC0+IGpzX3N0cmluZyB0IC0+IGJvb2wgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgX29wZW5fZnVsbCA6XG4gICAgICAganNfc3RyaW5nIHRcbiAgICAtPiBqc19zdHJpbmcgdFxuICAgIC0+IGJvb2wgdFxuICAgIC0+IGpzX3N0cmluZyB0IG9wdFxuICAgIC0+IGpzX3N0cmluZyB0IG9wdFxuICAgIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBzZXRSZXF1ZXN0SGVhZGVyIDoganNfc3RyaW5nIHQgLT4ganNfc3RyaW5nIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIG92ZXJyaWRlTWltZVR5cGUgOiBqc19zdHJpbmcgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgc2VuZCA6IGpzX3N0cmluZyB0IG9wdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgc2VuZF9ibG9iIDogI0ZpbGUuYmxvYiB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBzZW5kX2RvY3VtZW50IDogRG9tLmVsZW1lbnQgRG9tLmRvY3VtZW50IHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHNlbmRfZm9ybURhdGEgOiBGb3JtLmZvcm1EYXRhIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGFib3J0IDogdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHN0YXR1cyA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHN0YXR1c1RleHQgOiBqc19zdHJpbmcgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGdldFJlc3BvbnNlSGVhZGVyIDoganNfc3RyaW5nIHQgLT4ganNfc3RyaW5nIHQgb3B0IG1ldGhcblxuICBtZXRob2QgZ2V0QWxsUmVzcG9uc2VIZWFkZXJzIDoganNfc3RyaW5nIHQgbWV0aFxuXG4gIG1ldGhvZCByZXNwb25zZSA6IEZpbGUuZmlsZV9hbnkgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCByZXNwb25zZVRleHQgOiBqc19zdHJpbmcgdCBvcHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCByZXNwb25zZVhNTCA6IERvbS5lbGVtZW50IERvbS5kb2N1bWVudCB0IG9wdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHJlc3BvbnNlVHlwZSA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2Qgd2l0aENyZWRlbnRpYWxzIDogYm9vbCB0IHdyaXRlb25seV9wcm9wXG5cbiAgaW5oZXJpdCBGaWxlLnByb2dyZXNzRXZlbnRUYXJnZXRcblxuICBtZXRob2Qgb250aW1lb3V0IDpcbiAgICAoJ3NlbGYgdCwgJ3NlbGYgRmlsZS5wcm9ncmVzc0V2ZW50IHQpIERvbS5ldmVudF9saXN0ZW5lciB3cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCB1cGxvYWQgOiB4bWxIdHRwUmVxdWVzdFVwbG9hZCB0IG9wdGRlZiByZWFkb25seV9wcm9wXG5lbmRcblxuYW5kIHhtbEh0dHBSZXF1ZXN0VXBsb2FkID0gb2JqZWN0ICgnc2VsZilcbiAgaW5oZXJpdCBGaWxlLnByb2dyZXNzRXZlbnRUYXJnZXRcbmVuZFxuXG5tb2R1bGUgRXZlbnQgPSBzdHJ1Y3RcbiAgdHlwZSB0eXAgPSB4bWxIdHRwUmVxdWVzdCBGaWxlLnByb2dyZXNzRXZlbnQgdCBEb20uRXZlbnQudHlwXG5cbiAgbGV0IHJlYWR5c3RhdGVjaGFuZ2UgPSBEb20uRXZlbnQubWFrZSBcInJlYWR5c3RhdGVjaGFuZ2VcIlxuXG4gIGxldCBsb2Fkc3RhcnQgPSBEb20uRXZlbnQubWFrZSBcImxvYWRzdGFydFwiXG5cbiAgbGV0IHByb2dyZXNzID0gRG9tLkV2ZW50Lm1ha2UgXCJwcm9ncmVzc1wiXG5cbiAgbGV0IGFib3J0ID0gRG9tLkV2ZW50Lm1ha2UgXCJhYm9ydFwiXG5cbiAgbGV0IGVycm9yID0gRG9tLkV2ZW50Lm1ha2UgXCJlcnJvclwiXG5cbiAgbGV0IGxvYWQgPSBEb20uRXZlbnQubWFrZSBcImxvYWRcIlxuXG4gIGxldCB0aW1lb3V0ID0gRG9tLkV2ZW50Lm1ha2UgXCJ0aW1lb3V0XCJcblxuICBsZXQgbG9hZGVuZCA9IERvbS5FdmVudC5tYWtlIFwibG9hZGVuZFwiXG5lbmRcblxuZXh0ZXJuYWwgY3JlYXRlIDogdW5pdCAtPiB4bWxIdHRwUmVxdWVzdCBKcy50ID0gXCJjYW1sX3htbGh0dHByZXF1ZXN0X2NyZWF0ZVwiXG4iLCIoKiBKc19vZl9vY2FtbCBsaWJyYXJ5XG4gKiBodHRwOi8vd3d3Lm9jc2lnZW4ub3JnL2pzX29mX29jYW1sL1xuICogQ29weXJpZ2h0IChDKSAyMDE1IE9DYW1sUHJvOiBHcsOpZ29pcmUgSGVucnksIMOHYcSfZGHFnyBCb3ptYW4uXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgd2l0aCBsaW5raW5nIGV4Y2VwdGlvbjtcbiAqIGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4gKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLlxuICopXG5cbm9wZW4gSnNcbm9wZW4gRG9tX2h0bWxcbm9wZW4hIEltcG9ydFxuXG5jbGFzcyB0eXBlIFsnYSwgJ2JdIHdvcmtlciA9IG9iamVjdCAoJ3NlbGYpXG4gIGluaGVyaXQgZXZlbnRUYXJnZXRcblxuICBtZXRob2Qgb25lcnJvciA6ICgnc2VsZiB0LCBlcnJvckV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9ubWVzc2FnZSA6ICgnc2VsZiB0LCAnYiBtZXNzYWdlRXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgd3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2QgcG9zdE1lc3NhZ2UgOiAnYSAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdGVybWluYXRlIDogdW5pdCBtZXRoXG5lbmRcblxuYW5kIGVycm9yRXZlbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBldmVudFxuXG4gIG1ldGhvZCBtZXNzYWdlIDoganNfc3RyaW5nIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBmaWxlbmFtZSA6IGpzX3N0cmluZyB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgbGluZW5vIDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgY29sbm8gOiBpbnQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBlcnJvciA6IFVuc2FmZS5hbnkgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbmFuZCBbJ2FdIG1lc3NhZ2VFdmVudCA9IG9iamVjdFxuICBpbmhlcml0IGV2ZW50XG5cbiAgbWV0aG9kIGRhdGEgOiAnYSByZWFkb25seV9wcm9wXG5lbmRcblxubGV0IHdvcmtlciA9IFVuc2FmZS5nbG9iYWwjIy5fV29ya2VyXG5cbmxldCBjcmVhdGUgc2NyaXB0ID0gbmV3JWpzIHdvcmtlciAoc3RyaW5nIHNjcmlwdClcblxubGV0IGltcG9ydF9zY3JpcHRzIHNjcmlwdHMgOiB1bml0ID1cbiAgaWYgbm90IChKcy5PcHRkZWYudGVzdCBVbnNhZmUuZ2xvYmFsIyMuaW1wb3J0U2NyaXB0cylcbiAgdGhlbiBpbnZhbGlkX2FyZyBcIldvcmtlci5pbXBvcnRfc2NyaXB0cyBpcyB1bmRlZmluZWRcIjtcbiAgVW5zYWZlLmZ1bl9jYWxsXG4gICAgVW5zYWZlLmdsb2JhbCMjLmltcG9ydFNjcmlwdHNcbiAgICAoQXJyYXkubWFwIChmdW4gcyAtPiBVbnNhZmUuaW5qZWN0IChzdHJpbmcgcykpIChBcnJheS5vZl9saXN0IHNjcmlwdHMpKVxuXG5sZXQgc2V0X29ubWVzc2FnZSBoYW5kbGVyID1cbiAgaWYgbm90IChKcy5PcHRkZWYudGVzdCBVbnNhZmUuZ2xvYmFsIyMub25tZXNzYWdlKVxuICB0aGVuIGludmFsaWRfYXJnIFwiV29ya2VyLm9ubWVzc2FnZSBpcyB1bmRlZmluZWRcIjtcbiAgbGV0IGpzX2hhbmRsZXIgKGV2IDogJ2EgbWVzc2FnZUV2ZW50IEpzLnQpID0gaGFuZGxlciBldiMjLmRhdGEgaW5cbiAgVW5zYWZlLmdsb2JhbCMjLm9ubWVzc2FnZSA6PSB3cmFwX2NhbGxiYWNrIGpzX2hhbmRsZXJcblxubGV0IHBvc3RfbWVzc2FnZSBtc2cgPVxuICBpZiBub3QgKEpzLk9wdGRlZi50ZXN0IFVuc2FmZS5nbG9iYWwjIy5wb3N0TWVzc2FnZSlcbiAgdGhlbiBpbnZhbGlkX2FyZyBcIldvcmtlci5vbm1lc3NhZ2UgaXMgdW5kZWZpbmVkXCI7XG4gIFVuc2FmZS5nbG9iYWwjI3Bvc3RNZXNzYWdlIG1zZ1xuIiwiKCogSnNfb2Zfb2NhbWwgbGlicmFyeVxuICogaHR0cDovL3d3dy5vY3NpZ2VuLm9yZy9qc19vZl9vY2FtbC9cbiAqIENvcHlyaWdodCAoQykgMjAxMiBKYWNxdWVzLVBhc2NhbCBEZXBsYWl4XG4gKiBMYWJvcmF0b2lyZSBQUFMgLSBDTlJTIFVuaXZlcnNpdMOpIFBhcmlzIERpZGVyb3RcbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCB3aXRoIGxpbmtpbmcgZXhjZXB0aW9uO1xuICogZWl0aGVyIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuXG4gKilcblxub3BlbiEgSW1wb3J0XG5cbnR5cGUgcmVhZHlTdGF0ZSA9XG4gIHwgQ09OTkVDVElOR1xuICB8IE9QRU5cbiAgfCBDTE9TSU5HXG4gIHwgQ0xPU0VEXG5cbmNsYXNzIHR5cGUgWydhXSBjbG9zZUV2ZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgWydhXSBEb20uZXZlbnRcblxuICBtZXRob2QgY29kZSA6IGludCBKcy5yZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHJlYXNvbiA6IEpzLmpzX3N0cmluZyBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgd2FzQ2xlYW4gOiBib29sIEpzLnQgSnMucmVhZG9ubHlfcHJvcFxuZW5kXG5cbmNsYXNzIHR5cGUgWydhXSBtZXNzYWdlRXZlbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBbJ2FdIERvbS5ldmVudFxuXG4gIG1ldGhvZCBkYXRhIDogSnMuanNfc3RyaW5nIEpzLnQgSnMucmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBkYXRhX2J1ZmZlciA6IFR5cGVkX2FycmF5LmFycmF5QnVmZmVyIEpzLnQgSnMucmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBkYXRhX2Jsb2IgOiBGaWxlLmJsb2IgSnMudCBKcy5yZWFkb25seV9wcm9wXG5lbmRcblxuY2xhc3MgdHlwZSB3ZWJTb2NrZXQgPSBvYmplY3QgKCdzZWxmKVxuICBpbmhlcml0IERvbV9odG1sLmV2ZW50VGFyZ2V0XG5cbiAgbWV0aG9kIHVybCA6IEpzLmpzX3N0cmluZyBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgcmVhZHlTdGF0ZSA6IHJlYWR5U3RhdGUgSnMucmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBidWZmZXJlZEFtb3VudCA6IGludCBKcy5yZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIG9ub3BlbiA6ICgnc2VsZiBKcy50LCAnc2VsZiBEb20uZXZlbnQgSnMudCkgRG9tLmV2ZW50X2xpc3RlbmVyIEpzLndyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9uY2xvc2UgOlxuICAgICgnc2VsZiBKcy50LCAnc2VsZiBjbG9zZUV2ZW50IEpzLnQpIERvbS5ldmVudF9saXN0ZW5lciBKcy53cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvbmVycm9yIDogKCdzZWxmIEpzLnQsICdzZWxmIERvbS5ldmVudCBKcy50KSBEb20uZXZlbnRfbGlzdGVuZXIgSnMud3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2QgZXh0ZW5zaW9ucyA6IEpzLmpzX3N0cmluZyBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgcHJvdG9jb2wgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5yZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGNsb3NlIDogdW5pdCBKcy5tZXRoXG5cbiAgbWV0aG9kIGNsb3NlX3dpdGhDb2RlIDogaW50IC0+IHVuaXQgSnMubWV0aFxuXG4gIG1ldGhvZCBjbG9zZV93aXRoQ29kZUFuZFJlYXNvbiA6IGludCAtPiBKcy5qc19zdHJpbmcgSnMudCAtPiB1bml0IEpzLm1ldGhcblxuICBtZXRob2Qgb25tZXNzYWdlIDpcbiAgICAoJ3NlbGYgSnMudCwgJ3NlbGYgbWVzc2FnZUV2ZW50IEpzLnQpIERvbS5ldmVudF9saXN0ZW5lciBKcy53cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBiaW5hcnlUeXBlIDogSnMuanNfc3RyaW5nIEpzLnQgSnMucHJvcFxuXG4gIG1ldGhvZCBzZW5kIDogSnMuanNfc3RyaW5nIEpzLnQgLT4gdW5pdCBKcy5tZXRoXG5cbiAgbWV0aG9kIHNlbmRfYnVmZmVyIDogVHlwZWRfYXJyYXkuYXJyYXlCdWZmZXIgSnMudCAtPiB1bml0IEpzLm1ldGhcblxuICBtZXRob2Qgc2VuZF9ibG9iIDogRmlsZS5ibG9iIEpzLnQgLT4gdW5pdCBKcy5tZXRoXG5lbmRcblxubGV0IHdlYlNvY2tldCA9IEpzLlVuc2FmZS5nbG9iYWwjIy5fV2ViU29ja2V0XG5cbmxldCB3ZWJTb2NrZXRfd2l0aFByb3RvY29sID0gd2ViU29ja2V0XG5cbmxldCB3ZWJTb2NrZXRfd2l0aFByb3RvY29scyA9IHdlYlNvY2tldFxuXG5sZXQgaXNfc3VwcG9ydGVkICgpID0gSnMuT3B0ZGVmLnRlc3Qgd2ViU29ja2V0XG4iLCIoKiBKc19vZl9vY2FtbCBsaWJyYXJ5XG4gKiBodHRwOi8vd3d3Lm9jc2lnZW4ub3JnL2pzX29mX29jYW1sL1xuICogQ29weXJpZ2h0IChDKSAyMDEyIErDqXLDtG1lIFZvdWlsbG9uXG4gKiBMYWJvcmF0b2lyZSBQUFMgLSBDTlJTIFVuaXZlcnNpdMOpIFBhcmlzIERpZGVyb3RcbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCB3aXRoIGxpbmtpbmcgZXhjZXB0aW9uO1xuICogZWl0aGVyIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuXG4gKilcblxub3BlbiBKc1xub3BlbiEgSW1wb3J0XG5cbigqKiA1LjEgVHlwZXMgKilcblxudHlwZSBzaXplaSA9IGludFxuXG50eXBlIHNpemVpcHRyID0gaW50XG5cbnR5cGUgaW50cHRyID0gaW50XG5cbnR5cGUgdWludCA9IGludFxuXG50eXBlIGNsYW1wZiA9IG51bWJlcl90XG5cbnR5cGUgdm9pZFxuXG50eXBlIGNsZWFyQnVmZmVyTWFzayA9IGludFxuXG50eXBlIGJlZ2luTW9kZVxuXG50eXBlIGJsZW5kaW5nRmFjdG9yXG5cbnR5cGUgYmxlbmRNb2RlXG5cbnR5cGUgYnVmZmVyVGFyZ2V0XG5cbnR5cGUgYnVmZmVyVXNhZ2VcblxudHlwZSBjdWxsRmFjZU1vZGVcblxudHlwZSBkZXB0aEZ1bmN0aW9uXG5cbnR5cGUgZW5hYmxlQ2FwXG5cbnR5cGUgZXJyb3JDb2RlXG5cbnR5cGUgZnJvbnRGYWNlRGlyXG5cbnR5cGUgaGludFRhcmdldFxuXG50eXBlIGhpbnRNb2RlXG5cbnR5cGUgdGV4dHVyZVVuaXQgPSBpbnRcblxudHlwZSAnYSBwaXhlbFN0b3JlUGFyYW1cblxudHlwZSBzdGVuY2lsT3BcblxudHlwZSBmYlRhcmdldFxuXG50eXBlIGF0dGFjaG1lbnRQb2ludFxuXG50eXBlIHJiVGFyZ2V0XG5cbnR5cGUgdGV4VGFyZ2V0XG5cbnR5cGUgJ2EgcGFyYW1ldGVyXG5cbnR5cGUgJ2EgYnVmZmVyUGFyYW1ldGVyXG5cbnR5cGUgJ2EgdmVydGV4QXR0cmliUGFyYW1cblxudHlwZSB2ZXJ0ZXhBdHRyaWJQb2ludGVyUGFyYW1cblxudHlwZSAnYSBhdHRhY2hQYXJhbVxuXG50eXBlIGZyYW1lYnVmZmVyU3RhdHVzXG5cbnR5cGUgJ2EgcmVuZGVyYnVmZmVyUGFyYW1cblxudHlwZSBmb3JtYXRcblxudHlwZSBwaXhlbEZvcm1hdFxuXG50eXBlIHBpeGVsVHlwZVxuXG50eXBlICdhIHRleFBhcmFtXG5cbnR5cGUgZGF0YVR5cGVcblxudHlwZSBzaGFkZXJUeXBlXG5cbnR5cGUgJ2EgcHJvZ3JhbVBhcmFtXG5cbnR5cGUgJ2Egc2hhZGVyUGFyYW1cblxudHlwZSB0ZXh0dXJlRmlsdGVyXG5cbnR5cGUgd3JhcE1vZGVcblxudHlwZSB0ZXhGaWx0ZXJcblxudHlwZSB1bmlmb3JtVHlwZVxuXG50eXBlIGNvbG9yc3BhY2VDb252ZXJzaW9uXG5cbnR5cGUgc2hhZGVyUHJlY2lzaW9uVHlwZVxuXG50eXBlIG9iamVjdFR5cGVcblxuKCoqIDUuMiBXZWJHTENvbnRleHRBdHRyaWJ1dGVzICopXG5jbGFzcyB0eXBlIGNvbnRleHRBdHRyaWJ1dGVzID0gb2JqZWN0XG4gIG1ldGhvZCBhbHBoYSA6IGJvb2wgdCBwcm9wXG5cbiAgbWV0aG9kIGRlcHRoIDogYm9vbCB0IHByb3BcblxuICBtZXRob2Qgc3RlbmNpbCA6IGJvb2wgdCBwcm9wXG5cbiAgbWV0aG9kIGFudGlhbGlhcyA6IGJvb2wgdCBwcm9wXG5cbiAgbWV0aG9kIHByZW11bHRpcGxpZWRBbHBoYSA6IGJvb2wgdCBwcm9wXG5cbiAgbWV0aG9kIHByZXNlcnZlRHJhd2luZ0J1ZmZlciA6IGJvb2wgdCBwcm9wXG5cbiAgbWV0aG9kIHByZWZlckxvd1Bvd2VyVG9IaWdoUGVyZm9ybWFuY2UgOiBib29sIHQgcHJvcFxuXG4gIG1ldGhvZCBmYWlsSWZNYWpvclBlcmZvcm1hbmNlQ2F2ZWF0IDogYm9vbCB0IHByb3BcbmVuZFxuXG5sZXQgZGVmYXVsdENvbnRleHRBdHRyaWJ1dGVzID1cbiAgSnMuVW5zYWZlLihcbiAgICBvYmpcbiAgICAgIFt8IFwiYWxwaGFcIiwgaW5qZWN0IF90cnVlXG4gICAgICAgOyBcImRlcHRoXCIsIGluamVjdCBfdHJ1ZVxuICAgICAgIDsgXCJzdGVuY2lsXCIsIGluamVjdCBfZmFsc2VcbiAgICAgICA7IFwiYW50aWFsaWFzXCIsIGluamVjdCBfdHJ1ZVxuICAgICAgIDsgXCJwcmVtdWx0aXBsaWVkQWxwaGFcIiwgaW5qZWN0IF9mYWxzZVxuICAgICAgIDsgXCJwcmVzZXJ2ZURyYXdpbmdCdWZmZXJcIiwgaW5qZWN0IF9mYWxzZVxuICAgICAgIDsgXCJwcmVmZXJMb3dQb3dlclRvSGlnaFBlcmZvcm1hbmNlXCIsIGluamVjdCBfZmFsc2VcbiAgICAgICA7IFwiZmFpbElmTWFqb3JQZXJmb3JtYW5jZUNhdmVhdFwiLCBpbmplY3QgX2ZhbHNlXG4gICAgICB8XSlcblxudHlwZSBidWZmZXJcblxudHlwZSBmcmFtZWJ1ZmZlclxuXG50eXBlIHByb2dyYW1cblxudHlwZSByZW5kZXJidWZmZXJcblxudHlwZSBzaGFkZXJcblxudHlwZSB0ZXh0dXJlXG5cbnR5cGUgJ2EgdW5pZm9ybUxvY2F0aW9uXG5cbmNsYXNzIHR5cGUgYWN0aXZlSW5mbyA9IG9iamVjdFxuICBtZXRob2Qgc2l6ZSA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF90eXBlIDogdW5pZm9ybVR5cGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBuYW1lIDoganNfc3RyaW5nIHQgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbmNsYXNzIHR5cGUgc2hhZGVyUHJlY2lzaW9uRm9ybWF0ID0gb2JqZWN0XG4gIG1ldGhvZCByYW5nZU1pbiA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHJhbmdlTWF4IDogaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgcHJlY2lzaW9uIDogaW50IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG5jbGFzcyB0eXBlIHJlbmRlcmluZ0NvbnRleHQgPSBvYmplY3RcbiAgKCoqIDUuMTMuMSBBdHRyaWJ1dGVzICopXG5cbiAgbWV0aG9kIGNhbnZhcyA6IERvbV9odG1sLmNhbnZhc0VsZW1lbnQgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGRyYXdpbmdCdWZmZXJXaWR0aCA6IHNpemVpIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZHJhd2luZ0J1ZmZlckhlaWdodCA6IHNpemVpIHJlYWRvbmx5X3Byb3BcblxuICAoKiogNS4xMy4yIEdldHRpbmcgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGNvbnRleHQgKilcblxuICBtZXRob2QgZ2V0Q29udGV4dEF0dHJpYnV0ZXMgOiBjb250ZXh0QXR0cmlidXRlcyB0IG1ldGhcblxuICAoKiogNS4xMy4zIFNldHRpbmcgYW5kIGdldHRpbmcgc3RhdGUgKilcblxuICBtZXRob2QgYWN0aXZlVGV4dHVyZSA6IHRleHR1cmVVbml0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBibGVuZENvbG9yIDogY2xhbXBmIC0+IGNsYW1wZiAtPiBjbGFtcGYgLT4gY2xhbXBmIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBibGVuZEVxdWF0aW9uIDogYmxlbmRNb2RlIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBibGVuZEVxdWF0aW9uU2VwYXJhdGUgOiBibGVuZE1vZGUgLT4gYmxlbmRNb2RlIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBibGVuZEZ1bmMgOiBibGVuZGluZ0ZhY3RvciAtPiBibGVuZGluZ0ZhY3RvciAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgYmxlbmRGdW5jU2VwYXJhdGUgOlxuICAgIGJsZW5kaW5nRmFjdG9yIC0+IGJsZW5kaW5nRmFjdG9yIC0+IGJsZW5kaW5nRmFjdG9yIC0+IGJsZW5kaW5nRmFjdG9yIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBjbGVhckNvbG9yIDogY2xhbXBmIC0+IGNsYW1wZiAtPiBjbGFtcGYgLT4gY2xhbXBmIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBjbGVhckRlcHRoIDogY2xhbXBmIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBjbGVhclN0ZW5jaWwgOiBpbnQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGNvbG9yTWFzayA6IGJvb2wgdCAtPiBib29sIHQgLT4gYm9vbCB0IC0+IGJvb2wgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgY3VsbEZhY2UgOiBjdWxsRmFjZU1vZGUgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGRlcHRoRnVuYyA6IGRlcHRoRnVuY3Rpb24gLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGRlcHRoTWFzayA6IGJvb2wgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgZGVwdGhSYW5nZSA6IGNsYW1wZiAtPiBjbGFtcGYgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGRpc2FibGUgOiBlbmFibGVDYXAgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGVuYWJsZSA6IGVuYWJsZUNhcCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgZnJvbnRGYWNlIDogZnJvbnRGYWNlRGlyIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBnZXRQYXJhbWV0ZXIgOiAnYS4gJ2EgcGFyYW1ldGVyIC0+ICdhIG1ldGhcblxuICBtZXRob2QgZ2V0RXJyb3IgOiBlcnJvckNvZGUgbWV0aFxuXG4gIG1ldGhvZCBoaW50IDogaGludFRhcmdldCAtPiBoaW50TW9kZSAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgaXNFbmFibGVkIDogZW5hYmxlQ2FwIC0+IGJvb2wgdCBtZXRoXG5cbiAgbWV0aG9kIGxpbmVXaWR0aCA6IG51bWJlcl90IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBwaXhlbFN0b3JlaSA6ICdhLiAnYSBwaXhlbFN0b3JlUGFyYW0gLT4gJ2EgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHBvbHlnb25PZmZzZXQgOiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgc2FtcGxlQ292ZXJhZ2UgOiBjbGFtcGYgLT4gYm9vbCB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBzdGVuY2lsRnVuYyA6IGRlcHRoRnVuY3Rpb24gLT4gaW50IC0+IHVpbnQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHN0ZW5jaWxGdW5jU2VwYXJhdGUgOiBjdWxsRmFjZU1vZGUgLT4gZGVwdGhGdW5jdGlvbiAtPiBpbnQgLT4gdWludCAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgc3RlbmNpbE1hc2sgOiB1aW50IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBzdGVuY2lsTWFza1NlcGFyYXRlIDogY3VsbEZhY2VNb2RlIC0+IHVpbnQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHN0ZW5jaWxPcCA6IHN0ZW5jaWxPcCAtPiBzdGVuY2lsT3AgLT4gc3RlbmNpbE9wIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBzdGVuY2lsT3BTZXBhcmF0ZSA6XG4gICAgY3VsbEZhY2VNb2RlIC0+IHN0ZW5jaWxPcCAtPiBzdGVuY2lsT3AgLT4gc3RlbmNpbE9wIC0+IHVuaXQgbWV0aFxuXG4gICgqKiA1LjEzLjQgVmlld2luZyBhbmQgY2xpcHBpbmcgKilcblxuICBtZXRob2Qgc2Npc3NvciA6IGludCAtPiBpbnQgLT4gc2l6ZWkgLT4gc2l6ZWkgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHZpZXdwb3J0IDogaW50IC0+IGludCAtPiBzaXplaSAtPiBzaXplaSAtPiB1bml0IG1ldGhcblxuICAoKiogNS4xMy41IEJ1ZmZlciBvYmplY3RzICopXG5cbiAgbWV0aG9kIGJpbmRCdWZmZXIgOiBidWZmZXJUYXJnZXQgLT4gYnVmZmVyIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGJpbmRCdWZmZXJfIDogYnVmZmVyVGFyZ2V0IC0+IGJ1ZmZlciB0IG9wdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgYnVmZmVyRGF0YV9jcmVhdGUgOiBidWZmZXJUYXJnZXQgLT4gc2l6ZWlwdHIgLT4gYnVmZmVyVXNhZ2UgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGJ1ZmZlckRhdGEgOlxuICAgIGJ1ZmZlclRhcmdldCAtPiAjVHlwZWRfYXJyYXkuYXJyYXlCdWZmZXJWaWV3IHQgLT4gYnVmZmVyVXNhZ2UgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGJ1ZmZlckRhdGFfcmF3IDpcbiAgICBidWZmZXJUYXJnZXQgLT4gVHlwZWRfYXJyYXkuYXJyYXlCdWZmZXIgdCAtPiBidWZmZXJVc2FnZSAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgYnVmZmVyU3ViRGF0YSA6XG4gICAgYnVmZmVyVGFyZ2V0IC0+IGludHB0ciAtPiAjVHlwZWRfYXJyYXkuYXJyYXlCdWZmZXJWaWV3IHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGJ1ZmZlclN1YkRhdGFfcmF3IDpcbiAgICBidWZmZXJUYXJnZXQgLT4gaW50cHRyIC0+IFR5cGVkX2FycmF5LmFycmF5QnVmZmVyIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGNyZWF0ZUJ1ZmZlciA6IGJ1ZmZlciB0IG1ldGhcblxuICBtZXRob2QgZGVsZXRlQnVmZmVyIDogYnVmZmVyIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGdldEJ1ZmZlclBhcmFtZXRlciA6ICdhLiBidWZmZXJUYXJnZXQgLT4gJ2EgYnVmZmVyUGFyYW1ldGVyIC0+ICdhIG1ldGhcblxuICBtZXRob2QgaXNCdWZmZXIgOiBidWZmZXIgdCAtPiBib29sIHQgbWV0aFxuXG4gICgqKiA1LjEzLjYgRnJhbWVidWZmZXIgb2JqZWN0cyAqKVxuXG4gIG1ldGhvZCBiaW5kRnJhbWVidWZmZXIgOiBmYlRhcmdldCAtPiBmcmFtZWJ1ZmZlciB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBiaW5kRnJhbWVidWZmZXJfIDogZmJUYXJnZXQgLT4gZnJhbWVidWZmZXIgdCBvcHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGNoZWNrRnJhbWVidWZmZXJTdGF0dXMgOiBmYlRhcmdldCAtPiBmcmFtZWJ1ZmZlclN0YXR1cyBtZXRoXG5cbiAgbWV0aG9kIGNyZWF0ZUZyYW1lYnVmZmVyIDogZnJhbWVidWZmZXIgdCBtZXRoXG5cbiAgbWV0aG9kIGRlbGV0ZUZyYW1lYnVmZmVyIDogZnJhbWVidWZmZXIgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgZnJhbWVidWZmZXJSZW5kZXJidWZmZXIgOlxuICAgIGZiVGFyZ2V0IC0+IGF0dGFjaG1lbnRQb2ludCAtPiByYlRhcmdldCAtPiByZW5kZXJidWZmZXIgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgZnJhbWVidWZmZXJUZXh0dXJlMkQgOlxuICAgIGZiVGFyZ2V0IC0+IGF0dGFjaG1lbnRQb2ludCAtPiB0ZXhUYXJnZXQgLT4gdGV4dHVyZSB0IC0+IGludCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgZ2V0RnJhbWVidWZmZXJBdHRhY2htZW50UGFyYW1ldGVyIDpcbiAgICAnYS4gZmJUYXJnZXQgLT4gYXR0YWNobWVudFBvaW50IC0+ICdhIGF0dGFjaFBhcmFtIC0+ICdhIG1ldGhcblxuICBtZXRob2QgaXNGcmFtZWJ1ZmZlciA6IGZyYW1lYnVmZmVyIHQgLT4gYm9vbCB0IG1ldGhcblxuICAoKiogNS4xMy43IFJlbmRlcmJ1ZmZlciBvYmplY3RzICopXG5cbiAgbWV0aG9kIGJpbmRSZW5kZXJidWZmZXIgOiByYlRhcmdldCAtPiByZW5kZXJidWZmZXIgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgYmluZFJlbmRlcmJ1ZmZlcl8gOiByYlRhcmdldCAtPiByZW5kZXJidWZmZXIgdCBvcHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGNyZWF0ZVJlbmRlcmJ1ZmZlciA6IHJlbmRlcmJ1ZmZlciB0IG1ldGhcblxuICBtZXRob2QgZGVsZXRlUmVuZGVyYnVmZmVyIDogcmVuZGVyYnVmZmVyIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGdldFJlbmRlcmJ1ZmZlclBhcmFtZXRlciA6ICdhLiByYlRhcmdldCAtPiAnYSByZW5kZXJidWZmZXJQYXJhbSAtPiAnYSBtZXRoXG5cbiAgbWV0aG9kIGlzUmVuZGVyYnVmZmVyIDogcmVuZGVyYnVmZmVyIHQgLT4gYm9vbCB0IG1ldGhcblxuICBtZXRob2QgcmVuZGVyYnVmZmVyU3RvcmFnZSA6IHJiVGFyZ2V0IC0+IGZvcm1hdCAtPiBzaXplaSAtPiBzaXplaSAtPiB1bml0IG1ldGhcblxuICAoKiogNS4xMy44IFRleHR1cmUgb2JqZWN0cyAqKVxuXG4gIG1ldGhvZCBiaW5kVGV4dHVyZSA6IHRleFRhcmdldCAtPiB0ZXh0dXJlIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGJpbmRUZXh0dXJlXyA6IHRleFRhcmdldCAtPiB0ZXh0dXJlIHQgb3B0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBjb21wcmVzc2VkVGV4SW1hZ2UyRCA6XG4gICAgICAgdGV4VGFyZ2V0XG4gICAgLT4gaW50XG4gICAgLT4gcGl4ZWxGb3JtYXRcbiAgICAtPiBzaXplaVxuICAgIC0+IHNpemVpXG4gICAgLT4gaW50XG4gICAgLT4gI1R5cGVkX2FycmF5LmFycmF5QnVmZmVyVmlldyB0XG4gICAgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGNvbXByZXNzZWRUZXhTdWJJbWFnZTJEIDpcbiAgICAgICB0ZXhUYXJnZXRcbiAgICAtPiBpbnRcbiAgICAtPiBpbnRcbiAgICAtPiBpbnRcbiAgICAtPiBzaXplaVxuICAgIC0+IHNpemVpXG4gICAgLT4gcGl4ZWxGb3JtYXRcbiAgICAtPiAjVHlwZWRfYXJyYXkuYXJyYXlCdWZmZXJWaWV3IHRcbiAgICAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgY29weVRleEltYWdlMkQgOlxuICAgIHRleFRhcmdldCAtPiBpbnQgLT4gcGl4ZWxGb3JtYXQgLT4gaW50IC0+IGludCAtPiBzaXplaSAtPiBzaXplaSAtPiBpbnQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGNvcHlUZXhTdWJJbWFnZTJEIDpcbiAgICB0ZXhUYXJnZXQgLT4gaW50IC0+IGludCAtPiBpbnQgLT4gaW50IC0+IGludCAtPiBzaXplaSAtPiBzaXplaSAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgY3JlYXRlVGV4dHVyZSA6IHRleHR1cmUgdCBtZXRoXG5cbiAgbWV0aG9kIGRlbGV0ZVRleHR1cmUgOiB0ZXh0dXJlIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGdlbmVyYXRlTWlwbWFwIDogdGV4VGFyZ2V0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBnZXRUZXhQYXJhbWV0ZXIgOiB0ZXhUYXJnZXQgLT4gJ2EgdGV4UGFyYW0gLT4gJ2EgbWV0aFxuXG4gIG1ldGhvZCBpc1RleHR1cmUgOiB0ZXh0dXJlIHQgLT4gYm9vbCB0IG1ldGhcblxuICBtZXRob2QgdGV4SW1hZ2UyRF9uZXcgOlxuICAgICAgIHRleFRhcmdldFxuICAgIC0+IGludFxuICAgIC0+IHBpeGVsRm9ybWF0XG4gICAgLT4gc2l6ZWlcbiAgICAtPiBzaXplaVxuICAgIC0+IGludFxuICAgIC0+IHBpeGVsRm9ybWF0XG4gICAgLT4gcGl4ZWxUeXBlXG4gICAgLT4gdm9pZCBvcHRcbiAgICAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdGV4SW1hZ2UyRF9mcm9tVmlldyA6XG4gICAgICAgdGV4VGFyZ2V0XG4gICAgLT4gaW50XG4gICAgLT4gcGl4ZWxGb3JtYXRcbiAgICAtPiBzaXplaVxuICAgIC0+IHNpemVpXG4gICAgLT4gaW50XG4gICAgLT4gcGl4ZWxGb3JtYXRcbiAgICAtPiBwaXhlbFR5cGVcbiAgICAtPiAjVHlwZWRfYXJyYXkuYXJyYXlCdWZmZXJWaWV3IHRcbiAgICAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdGV4SW1hZ2UyRF9mcm9tSW1hZ2VEYXRhIDpcbiAgICAgICB0ZXhUYXJnZXRcbiAgICAtPiBpbnRcbiAgICAtPiBwaXhlbEZvcm1hdFxuICAgIC0+IHBpeGVsRm9ybWF0XG4gICAgLT4gcGl4ZWxUeXBlXG4gICAgLT4gRG9tX2h0bWwuaW1hZ2VEYXRhIHRcbiAgICAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdGV4SW1hZ2UyRF9mcm9tSW1hZ2UgOlxuICAgICAgIHRleFRhcmdldFxuICAgIC0+IGludFxuICAgIC0+IHBpeGVsRm9ybWF0XG4gICAgLT4gcGl4ZWxGb3JtYXRcbiAgICAtPiBwaXhlbFR5cGVcbiAgICAtPiBEb21faHRtbC5pbWFnZUVsZW1lbnQgdFxuICAgIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB0ZXhJbWFnZTJEX2Zyb21DYW52YXMgOlxuICAgICAgIHRleFRhcmdldFxuICAgIC0+IGludFxuICAgIC0+IHBpeGVsRm9ybWF0XG4gICAgLT4gcGl4ZWxGb3JtYXRcbiAgICAtPiBwaXhlbFR5cGVcbiAgICAtPiBEb21faHRtbC5jYW52YXNFbGVtZW50IHRcbiAgICAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdGV4SW1hZ2UyRF9mcm9tVmlkZW8gOlxuICAgICAgIHRleFRhcmdldFxuICAgIC0+IGludFxuICAgIC0+IHBpeGVsRm9ybWF0XG4gICAgLT4gcGl4ZWxGb3JtYXRcbiAgICAtPiBwaXhlbFR5cGVcbiAgICAtPiBEb21faHRtbC52aWRlb0VsZW1lbnQgdFxuICAgIC0+IHVuaXQgbWV0aFxuXG4gICgqIHtbXG4gICAgICBtZXRob2QgdGV4UGFyYW1ldGVyZiA6IHRleFRhcmdldCAtPiB0ZXhQYXJhbSAtPiBudW1iZXJfdCAtPiB1bml0IG1ldGhcbiAgICAgXX1cbiAgKilcbiAgbWV0aG9kIHRleFBhcmFtZXRlcmkgOiB0ZXhUYXJnZXQgLT4gJ2EgdGV4UGFyYW0gLT4gJ2EgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHRleFN1YkltYWdlMkRfZnJvbVZpZXcgOlxuICAgICAgIHRleFRhcmdldFxuICAgIC0+IGludFxuICAgIC0+IGludFxuICAgIC0+IGludFxuICAgIC0+IHNpemVpXG4gICAgLT4gc2l6ZWlcbiAgICAtPiBwaXhlbEZvcm1hdFxuICAgIC0+IHBpeGVsVHlwZVxuICAgIC0+ICNUeXBlZF9hcnJheS5hcnJheUJ1ZmZlclZpZXcgdFxuICAgIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB0ZXhTdWJJbWFnZTJEX2Zyb21JbWFnZURhdGEgOlxuICAgICAgIHRleFRhcmdldFxuICAgIC0+IGludFxuICAgIC0+IGludFxuICAgIC0+IGludFxuICAgIC0+IHBpeGVsRm9ybWF0XG4gICAgLT4gcGl4ZWxUeXBlXG4gICAgLT4gRG9tX2h0bWwuaW1hZ2VEYXRhIHRcbiAgICAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdGV4U3ViSW1hZ2UyRF9mcm9tSW1hZ2UgOlxuICAgICAgIHRleFRhcmdldFxuICAgIC0+IGludFxuICAgIC0+IGludFxuICAgIC0+IGludFxuICAgIC0+IHBpeGVsRm9ybWF0XG4gICAgLT4gcGl4ZWxUeXBlXG4gICAgLT4gRG9tX2h0bWwuaW1hZ2VFbGVtZW50IHRcbiAgICAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdGV4U3ViSW1hZ2UyRF9mcm9tQ2FudmFzIDpcbiAgICAgICB0ZXhUYXJnZXRcbiAgICAtPiBpbnRcbiAgICAtPiBpbnRcbiAgICAtPiBpbnRcbiAgICAtPiBwaXhlbEZvcm1hdFxuICAgIC0+IHBpeGVsVHlwZVxuICAgIC0+IERvbV9odG1sLmNhbnZhc0VsZW1lbnQgdFxuICAgIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB0ZXhTdWJJbWFnZTJEX2Zyb21WaWRlbyA6XG4gICAgICAgdGV4VGFyZ2V0XG4gICAgLT4gaW50XG4gICAgLT4gaW50XG4gICAgLT4gaW50XG4gICAgLT4gcGl4ZWxGb3JtYXRcbiAgICAtPiBwaXhlbFR5cGVcbiAgICAtPiBEb21faHRtbC52aWRlb0VsZW1lbnQgdFxuICAgIC0+IHVuaXQgbWV0aFxuXG4gICgqKiA1LjEzLjkgUHJvZ3JhbXMgYW5kIFNoYWRlcnMgKilcblxuICBtZXRob2QgYXR0YWNoU2hhZGVyIDogcHJvZ3JhbSB0IC0+IHNoYWRlciB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBiaW5kQXR0cmliTG9jYXRpb24gOiBwcm9ncmFtIHQgLT4gdWludCAtPiBqc19zdHJpbmcgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgY29tcGlsZVNoYWRlciA6IHNoYWRlciB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBjcmVhdGVQcm9ncmFtIDogcHJvZ3JhbSB0IG1ldGhcblxuICBtZXRob2QgY3JlYXRlU2hhZGVyIDogc2hhZGVyVHlwZSAtPiBzaGFkZXIgdCBtZXRoXG5cbiAgbWV0aG9kIGRlbGV0ZVByb2dyYW0gOiBwcm9ncmFtIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGRlbGV0ZVNoYWRlciA6IHNoYWRlciB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBkZXRhY2hTaGFkZXIgOiBwcm9ncmFtIHQgLT4gc2hhZGVyIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGdldEF0dGFjaGVkU2hhZGVycyA6IHByb2dyYW0gdCAtPiBzaGFkZXIgdCBqc19hcnJheSB0IG1ldGhcblxuICBtZXRob2QgZ2V0UHJvZ3JhbVBhcmFtZXRlciA6ICdhLiBwcm9ncmFtIHQgLT4gJ2EgcHJvZ3JhbVBhcmFtIC0+ICdhIG1ldGhcblxuICBtZXRob2QgZ2V0UHJvZ3JhbUluZm9Mb2cgOiBwcm9ncmFtIHQgLT4ganNfc3RyaW5nIHQgbWV0aFxuXG4gIG1ldGhvZCBnZXRTaGFkZXJQYXJhbWV0ZXIgOiAnYS4gc2hhZGVyIHQgLT4gJ2Egc2hhZGVyUGFyYW0gLT4gJ2EgbWV0aFxuXG4gIG1ldGhvZCBnZXRTaGFkZXJQcmVjaXNpb25Gb3JtYXQgOlxuICAgIHNoYWRlclR5cGUgLT4gc2hhZGVyUHJlY2lzaW9uVHlwZSAtPiBzaGFkZXJQcmVjaXNpb25Gb3JtYXQgdCBtZXRoXG5cbiAgbWV0aG9kIGdldFNoYWRlckluZm9Mb2cgOiBzaGFkZXIgdCAtPiBqc19zdHJpbmcgdCBtZXRoXG5cbiAgbWV0aG9kIGdldFNoYWRlclNvdXJjZSA6IHNoYWRlciB0IC0+IGpzX3N0cmluZyB0IG1ldGhcblxuICBtZXRob2QgaXNQcm9ncmFtIDogcHJvZ3JhbSB0IC0+IGJvb2wgdCBtZXRoXG5cbiAgbWV0aG9kIGlzU2hhZGVyIDogc2hhZGVyIHQgLT4gYm9vbCB0IG1ldGhcblxuICBtZXRob2QgbGlua1Byb2dyYW0gOiBwcm9ncmFtIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHNoYWRlclNvdXJjZSA6IHNoYWRlciB0IC0+IGpzX3N0cmluZyB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB1c2VQcm9ncmFtIDogcHJvZ3JhbSB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB2YWxpZGF0ZVByb2dyYW0gOiBwcm9ncmFtIHQgLT4gdW5pdCBtZXRoXG5cbiAgKCoqIDUuMTMuMTAgVW5pZm9ybXMgYW5kIGF0dHJpYnV0ZXMgKilcblxuICBtZXRob2QgZGlzYWJsZVZlcnRleEF0dHJpYkFycmF5IDogdWludCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgZW5hYmxlVmVydGV4QXR0cmliQXJyYXkgOiB1aW50IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBnZXRBY3RpdmVBdHRyaWIgOiBwcm9ncmFtIHQgLT4gdWludCAtPiBhY3RpdmVJbmZvIHQgbWV0aFxuXG4gIG1ldGhvZCBnZXRBY3RpdmVVbmlmb3JtIDogcHJvZ3JhbSB0IC0+IHVpbnQgLT4gYWN0aXZlSW5mbyB0IG1ldGhcblxuICBtZXRob2QgZ2V0QXR0cmliTG9jYXRpb24gOiBwcm9ncmFtIHQgLT4ganNfc3RyaW5nIHQgLT4gaW50IG1ldGhcblxuICBtZXRob2QgZ2V0VW5pZm9ybSA6ICdhICdiLiBwcm9ncmFtIHQgLT4gJ2EgdW5pZm9ybUxvY2F0aW9uIHQgLT4gJ2IgbWV0aFxuXG4gIG1ldGhvZCBnZXRVbmlmb3JtTG9jYXRpb24gOiAnYS4gcHJvZ3JhbSB0IC0+IGpzX3N0cmluZyB0IC0+ICdhIHVuaWZvcm1Mb2NhdGlvbiB0IG1ldGhcblxuICBtZXRob2QgZ2V0VmVydGV4QXR0cmliIDogJ2EuIHVpbnQgLT4gJ2EgdmVydGV4QXR0cmliUGFyYW0gLT4gJ2EgbWV0aFxuXG4gIG1ldGhvZCBnZXRWZXJ0ZXhBdHRyaWJPZmZzZXQgOiB1aW50IC0+IHZlcnRleEF0dHJpYlBvaW50ZXJQYXJhbSAtPiBzaXplaXB0ciBtZXRoXG5cbiAgbWV0aG9kIHVuaWZvcm0xZiA6IG51bWJlcl90IHVuaWZvcm1Mb2NhdGlvbiB0IC0+IG51bWJlcl90IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB1bmlmb3JtMWZ2X3R5cGVkIDpcbiAgICBudW1iZXJfdCB1bmlmb3JtTG9jYXRpb24gdCAtPiBUeXBlZF9hcnJheS5mbG9hdDMyQXJyYXkgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdW5pZm9ybTFmdiA6IG51bWJlcl90IHVuaWZvcm1Mb2NhdGlvbiB0IC0+IG51bWJlcl90IGpzX2FycmF5IHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHVuaWZvcm0xaSA6IGludCB1bmlmb3JtTG9jYXRpb24gdCAtPiBpbnQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHVuaWZvcm0xaXZfdHlwZWQgOiBpbnQgdW5pZm9ybUxvY2F0aW9uIHQgLT4gVHlwZWRfYXJyYXkuaW50MzJBcnJheSB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB1bmlmb3JtMWl2IDogaW50IHVuaWZvcm1Mb2NhdGlvbiB0IC0+IGludCBqc19hcnJheSB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB1bmlmb3JtMmYgOiBbIGB2ZWMyIF0gdW5pZm9ybUxvY2F0aW9uIHQgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHVuaWZvcm0yZnZfdHlwZWQgOlxuICAgIFsgYHZlYzIgXSB1bmlmb3JtTG9jYXRpb24gdCAtPiBUeXBlZF9hcnJheS5mbG9hdDMyQXJyYXkgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdW5pZm9ybTJmdiA6IFsgYHZlYzIgXSB1bmlmb3JtTG9jYXRpb24gdCAtPiBudW1iZXJfdCBqc19hcnJheSB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB1bmlmb3JtMmkgOiBbIGBpdmVjMiBdIHVuaWZvcm1Mb2NhdGlvbiB0IC0+IGludCAtPiBpbnQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHVuaWZvcm0yaXYgOiBbIGBpdmVjMiBdIHVuaWZvcm1Mb2NhdGlvbiB0IC0+IGludCBqc19hcnJheSB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB1bmlmb3JtMml2X3R5cGVkIDpcbiAgICBbIGBpdmVjMiBdIHVuaWZvcm1Mb2NhdGlvbiB0IC0+IFR5cGVkX2FycmF5LmludDMyQXJyYXkgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdW5pZm9ybTNmIDpcbiAgICBbIGB2ZWMzIF0gdW5pZm9ybUxvY2F0aW9uIHQgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHVuaWZvcm0zZnZfdHlwZWQgOlxuICAgIFsgYHZlYzMgXSB1bmlmb3JtTG9jYXRpb24gdCAtPiBUeXBlZF9hcnJheS5mbG9hdDMyQXJyYXkgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdW5pZm9ybTNmdiA6IFsgYHZlYzMgXSB1bmlmb3JtTG9jYXRpb24gdCAtPiBudW1iZXJfdCBqc19hcnJheSB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB1bmlmb3JtM2kgOiBbIGBpdmVjMyBdIHVuaWZvcm1Mb2NhdGlvbiB0IC0+IGludCAtPiBpbnQgLT4gaW50IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB1bmlmb3JtM2l2IDogWyBgaXZlYzMgXSB1bmlmb3JtTG9jYXRpb24gdCAtPiBpbnQganNfYXJyYXkgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdW5pZm9ybTNpdl90eXBlZCA6XG4gICAgWyBgaXZlYzMgXSB1bmlmb3JtTG9jYXRpb24gdCAtPiBUeXBlZF9hcnJheS5pbnQzMkFycmF5IHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHVuaWZvcm00ZiA6XG4gICAgICAgWyBgdmVjNCBdIHVuaWZvcm1Mb2NhdGlvbiB0XG4gICAgLT4gbnVtYmVyX3RcbiAgICAtPiBudW1iZXJfdFxuICAgIC0+IG51bWJlcl90XG4gICAgLT4gbnVtYmVyX3RcbiAgICAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdW5pZm9ybTRmdl90eXBlZCA6XG4gICAgWyBgdmVjNCBdIHVuaWZvcm1Mb2NhdGlvbiB0IC0+IFR5cGVkX2FycmF5LmZsb2F0MzJBcnJheSB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB1bmlmb3JtNGZ2IDogWyBgdmVjNCBdIHVuaWZvcm1Mb2NhdGlvbiB0IC0+IG51bWJlcl90IGpzX2FycmF5IHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHVuaWZvcm00aSA6IFsgYGl2ZWM0IF0gdW5pZm9ybUxvY2F0aW9uIHQgLT4gaW50IC0+IGludCAtPiBpbnQgLT4gaW50IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB1bmlmb3JtNGl2IDogWyBgaXZlYzQgXSB1bmlmb3JtTG9jYXRpb24gdCAtPiBpbnQganNfYXJyYXkgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdW5pZm9ybTRpdl90eXBlZCA6XG4gICAgWyBgaXZlYzQgXSB1bmlmb3JtTG9jYXRpb24gdCAtPiBUeXBlZF9hcnJheS5pbnQzMkFycmF5IHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHVuaWZvcm1NYXRyaXgyZnYgOlxuICAgIFsgYG1hdDIgXSB1bmlmb3JtTG9jYXRpb24gdCAtPiBib29sIHQgLT4gbnVtYmVyX3QganNfYXJyYXkgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdW5pZm9ybU1hdHJpeDJmdl90eXBlZCA6XG4gICAgWyBgbWF0MiBdIHVuaWZvcm1Mb2NhdGlvbiB0IC0+IGJvb2wgdCAtPiBUeXBlZF9hcnJheS5mbG9hdDMyQXJyYXkgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdW5pZm9ybU1hdHJpeDNmdiA6XG4gICAgWyBgbWF0MyBdIHVuaWZvcm1Mb2NhdGlvbiB0IC0+IGJvb2wgdCAtPiBudW1iZXJfdCBqc19hcnJheSB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB1bmlmb3JtTWF0cml4M2Z2X3R5cGVkIDpcbiAgICBbIGBtYXQzIF0gdW5pZm9ybUxvY2F0aW9uIHQgLT4gYm9vbCB0IC0+IFR5cGVkX2FycmF5LmZsb2F0MzJBcnJheSB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB1bmlmb3JtTWF0cml4NGZ2IDpcbiAgICBbIGBtYXQ0IF0gdW5pZm9ybUxvY2F0aW9uIHQgLT4gYm9vbCB0IC0+IG51bWJlcl90IGpzX2FycmF5IHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHVuaWZvcm1NYXRyaXg0ZnZfdHlwZWQgOlxuICAgIFsgYG1hdDQgXSB1bmlmb3JtTG9jYXRpb24gdCAtPiBib29sIHQgLT4gVHlwZWRfYXJyYXkuZmxvYXQzMkFycmF5IHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHZlcnRleEF0dHJpYjFmIDogdWludCAtPiBudW1iZXJfdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdmVydGV4QXR0cmliMWZ2IDogdWludCAtPiBudW1iZXJfdCBqc19hcnJheSB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB2ZXJ0ZXhBdHRyaWIxZnZfdHlwZWQgOiB1aW50IC0+IFR5cGVkX2FycmF5LmZsb2F0MzJBcnJheSB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB2ZXJ0ZXhBdHRyaWIyZiA6IHVpbnQgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHZlcnRleEF0dHJpYjJmdiA6IHVpbnQgLT4gbnVtYmVyX3QganNfYXJyYXkgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdmVydGV4QXR0cmliMmZ2X3R5cGVkIDogdWludCAtPiBUeXBlZF9hcnJheS5mbG9hdDMyQXJyYXkgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdmVydGV4QXR0cmliM2YgOiB1aW50IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB2ZXJ0ZXhBdHRyaWIzZnYgOiB1aW50IC0+IG51bWJlcl90IGpzX2FycmF5IHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHZlcnRleEF0dHJpYjNmdl90eXBlZCA6IHVpbnQgLT4gVHlwZWRfYXJyYXkuZmxvYXQzMkFycmF5IHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHZlcnRleEF0dHJpYjRmIDpcbiAgICB1aW50IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB2ZXJ0ZXhBdHRyaWI0ZnYgOiB1aW50IC0+IG51bWJlcl90IGpzX2FycmF5IHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHZlcnRleEF0dHJpYjRmdl90eXBlZCA6IHVpbnQgLT4gVHlwZWRfYXJyYXkuZmxvYXQzMkFycmF5IHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHZlcnRleEF0dHJpYlBvaW50ZXIgOlxuICAgIHVpbnQgLT4gaW50IC0+IGRhdGFUeXBlIC0+IGJvb2wgdCAtPiBzaXplaSAtPiBpbnRwdHIgLT4gdW5pdCBtZXRoXG5cbiAgKCoqIDUuMTMuMTEgV3JpdGluZyB0byB0aGUgZHJhd2luZyBidWZmZXIgKilcblxuICBtZXRob2QgY2xlYXIgOiBjbGVhckJ1ZmZlck1hc2sgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGRyYXdBcnJheXMgOiBiZWdpbk1vZGUgLT4gaW50IC0+IHNpemVpIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBkcmF3RWxlbWVudHMgOiBiZWdpbk1vZGUgLT4gc2l6ZWkgLT4gZGF0YVR5cGUgLT4gaW50cHRyIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBmaW5pc2ggOiB1bml0IG1ldGhcblxuICBtZXRob2QgZmx1c2ggOiB1bml0IG1ldGhcblxuICAoKiogNS4xMy4xMiBSZWFkaW5nIGJhY2sgcGl4ZWxzICopXG5cbiAgbWV0aG9kIHJlYWRQaXhlbHMgOlxuICAgICAgIGludFxuICAgIC0+IGludFxuICAgIC0+IHNpemVpXG4gICAgLT4gc2l6ZWlcbiAgICAtPiBwaXhlbEZvcm1hdFxuICAgIC0+IHBpeGVsVHlwZVxuICAgIC0+ICNUeXBlZF9hcnJheS5hcnJheUJ1ZmZlclZpZXcgdFxuICAgIC0+IHVuaXQgbWV0aFxuXG4gICgqKiA1LjEzLjEzIERldGVjdGluZyBjb250ZXh0IGxvc3QgZXZlbnRzICopXG5cbiAgbWV0aG9kIGlzQ29udGV4dExvc3QgOiBib29sIHQgbWV0aFxuXG4gICgqKiA1LjEzLjE0IERldGVjdGluZyBhbmQgZW5hYmxpbmcgZXh0ZW5zaW9ucyAqKVxuXG4gIG1ldGhvZCBnZXRTdXBwb3J0ZWRFeHRlbnNpb25zIDoganNfc3RyaW5nIHQganNfYXJyYXkgdCBtZXRoXG5cbiAgbWV0aG9kIGdldEV4dGVuc2lvbiA6ICdhLiBqc19zdHJpbmcgdCAtPiAnYSB0IG9wdCBtZXRoXG5cbiAgKCogVW50eXBlZCEgKilcbiAgKCoqIENvbnN0YW50cyAqKVxuXG4gIG1ldGhvZCBfREVQVEhfQlVGRkVSX0JJVF8gOiBjbGVhckJ1ZmZlck1hc2sgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfU1RFTkNJTF9CVUZGRVJfQklUXyA6IGNsZWFyQnVmZmVyTWFzayByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9DT0xPUl9CVUZGRVJfQklUXyA6IGNsZWFyQnVmZmVyTWFzayByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9QT0lOVFMgOiBiZWdpbk1vZGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfTElORVMgOiBiZWdpbk1vZGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfTElORV9MT09QXyA6IGJlZ2luTW9kZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9MSU5FX1NUUklQXyA6IGJlZ2luTW9kZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9UUklBTkdMRVMgOiBiZWdpbk1vZGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVFJJQU5HTEVfU1RSSVBfIDogYmVnaW5Nb2RlIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1RSSUFOR0xFX0ZBTl8gOiBiZWdpbk1vZGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfWkVSTyA6IGJsZW5kaW5nRmFjdG9yIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX09ORSA6IGJsZW5kaW5nRmFjdG9yIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1NSQ19DT0xPUl8gOiBibGVuZGluZ0ZhY3RvciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9PTkVfTUlOVVNfU1JDX0NPTE9SXyA6IGJsZW5kaW5nRmFjdG9yIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1NSQ19BTFBIQV8gOiBibGVuZGluZ0ZhY3RvciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9PTkVfTUlOVVNfU1JDX0FMUEhBXyA6IGJsZW5kaW5nRmFjdG9yIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0RTVF9BTFBIQV8gOiBibGVuZGluZ0ZhY3RvciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9PTkVfTUlOVVNfRFNUX0FMUEhBXyA6IGJsZW5kaW5nRmFjdG9yIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0RTVF9DT0xPUl8gOiBibGVuZGluZ0ZhY3RvciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9PTkVfTUlOVVNfRFNUX0NPTE9SXyA6IGJsZW5kaW5nRmFjdG9yIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1NSQ19BTFBIQV9TQVRVUkFURV8gOiBibGVuZGluZ0ZhY3RvciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9GVU5DX0FERF8gOiBibGVuZE1vZGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfRlVOQ19TVUJUUkFDVF8gOiBibGVuZE1vZGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfRlVOQ19SRVZFUlNFX1NVQlRSQUNUXyA6IGJsZW5kTW9kZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9DT05TVEFOVF9DT0xPUl8gOiBibGVuZE1vZGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfT05FX01JTlVTX0NPTlNUQU5UX0NPTE9SXyA6IGJsZW5kTW9kZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9DT05TVEFOVF9BTFBIQV8gOiBibGVuZE1vZGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfT05FX01JTlVTX0NPTlNUQU5UX0FMUEhBXyA6IGJsZW5kTW9kZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9BUlJBWV9CVUZGRVJfIDogYnVmZmVyVGFyZ2V0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0VMRU1FTlRfQVJSQVlfQlVGRkVSXyA6IGJ1ZmZlclRhcmdldCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9TVFJFQU1fRFJBV18gOiBidWZmZXJVc2FnZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9TVEFUSUNfRFJBV18gOiBidWZmZXJVc2FnZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9EWU5BTUlDX0RSQVdfIDogYnVmZmVyVXNhZ2UgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfRlJPTlQgOiBjdWxsRmFjZU1vZGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfQkFDSyA6IGN1bGxGYWNlTW9kZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9GUk9OVF9BTkRfQkFDS18gOiBjdWxsRmFjZU1vZGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfQ1VMTF9GQUNFXyA6IGVuYWJsZUNhcCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9CTEVORCA6IGVuYWJsZUNhcCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9ESVRIRVIgOiBlbmFibGVDYXAgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfU1RFTkNJTF9URVNUXyA6IGVuYWJsZUNhcCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9ERVBUSF9URVNUXyA6IGVuYWJsZUNhcCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9TQ0lTU09SX1RFU1RfIDogZW5hYmxlQ2FwIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1BPTFlHT05fT0ZGU0VUX0ZJTExfIDogZW5hYmxlQ2FwIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1NBTVBMRV9BTFBIQV9UT19DT1ZFUkFHRV8gOiBlbmFibGVDYXAgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfU0FNUExFX0NPVkVSQUdFXyA6IGVuYWJsZUNhcCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9OT19FUlJPUl8gOiBlcnJvckNvZGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfSU5WQUxJRF9FTlVNXyA6IGVycm9yQ29kZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9JTlZBTElEX1ZBTFVFXyA6IGVycm9yQ29kZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9JTlZBTElEX09QRVJBVElPTl8gOiBlcnJvckNvZGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfT1VUX09GX01FTU9SWV8gOiBlcnJvckNvZGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfQ09OVEVYVF9MT1NUX1dFQkdMXyA6IGVycm9yQ29kZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9JTlZBTElEX0ZSQU1FQlVGRkVSX09QRVJBVElPTl8gOiBlcnJvckNvZGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfQ1cgOiBmcm9udEZhY2VEaXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfQ0NXIDogZnJvbnRGYWNlRGlyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0RPTlRfQ0FSRV8gOiBoaW50TW9kZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9GQVNURVNUIDogaGludE1vZGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfTklDRVNUIDogaGludE1vZGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfR0VORVJBVEVfTUlQTUFQX0hJTlRfIDogaGludFRhcmdldCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9CTEVORF9FUVVBVElPTl8gOiBibGVuZE1vZGUgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0JMRU5EX0VRVUFUSU9OX1JHQl8gOiBibGVuZE1vZGUgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0JMRU5EX0VRVUFUSU9OX0FMUEhBXyA6IGJsZW5kTW9kZSBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfQkxFTkRfRFNUX1JHQl8gOiBibGVuZGluZ0ZhY3RvciBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfQkxFTkRfU1JDX1JHQl8gOiBibGVuZGluZ0ZhY3RvciBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfQkxFTkRfRFNUX0FMUEhBXyA6IGJsZW5kaW5nRmFjdG9yIHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9CTEVORF9TUkNfQUxQSEFfIDogYmxlbmRpbmdGYWN0b3IgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0JMRU5EX0NPTE9SXyA6IFR5cGVkX2FycmF5LmZsb2F0MzJBcnJheSB0IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9BUlJBWV9CVUZGRVJfQklORElOR18gOiBidWZmZXIgdCBvcHQgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0VMRU1FTlRfQVJSQVlfQlVGRkVSX0JJTkRJTkdfIDogYnVmZmVyIHQgb3B0IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9DVUxMX0ZBQ0VfUEFSQU0gOiBib29sIHQgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0JMRU5EX1BBUkFNIDogYm9vbCB0IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9ESVRIRVJfUEFSQU0gOiBib29sIHQgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1NURU5DSUxfVEVTVF9QQVJBTSA6IGJvb2wgdCBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfREVQVEhfVEVTVF9QQVJBTSA6IGJvb2wgdCBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfU0NJU1NPUl9URVNUX1BBUkFNIDogYm9vbCB0IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9QT0xZR09OX09GRlNFVF9GSUxMX1BBUkFNIDogYm9vbCB0IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9MSU5FX1dJRFRIXyA6IG51bWJlcl90IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9BTElBU0VEX1BPSU5UX1NJWkVfUkFOR0VfIDogVHlwZWRfYXJyYXkuZmxvYXQzMkFycmF5IHQgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0FMSUFTRURfTElORV9XSURUSF9SQU5HRV8gOiBUeXBlZF9hcnJheS5mbG9hdDMyQXJyYXkgdCBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfQ1VMTF9GQUNFX01PREVfIDogY3VsbEZhY2VNb2RlIHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9GUk9OVF9GQUNFXyA6IGZyb250RmFjZURpciBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfREVQVEhfUkFOR0VfIDogVHlwZWRfYXJyYXkuZmxvYXQzMkFycmF5IHQgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0RFUFRIX1dSSVRFTUFTS18gOiBib29sIHQgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0RFUFRIX0NMRUFSX1ZBTFVFXyA6IG51bWJlcl90IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9ERVBUSF9GVU5DXyA6IGRlcHRoRnVuY3Rpb24gcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1NURU5DSUxfQ0xFQVJfVkFMVUVfIDogaW50IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9TVEVOQ0lMX0ZVTkNfIDogaW50IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9TVEVOQ0lMX0ZBSUxfIDogaW50IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9TVEVOQ0lMX1BBU1NfREVQVEhfRkFJTF8gOiBpbnQgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1NURU5DSUxfUEFTU19ERVBUSF9QQVNTXyA6IGludCBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfU1RFTkNJTF9SRUZfIDogaW50IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9TVEVOQ0lMX1ZBTFVFX01BU0tfIDogaW50IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9TVEVOQ0lMX1dSSVRFTUFTS18gOiBpbnQgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1NURU5DSUxfQkFDS19GVU5DXyA6IGludCBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfU1RFTkNJTF9CQUNLX0ZBSUxfIDogaW50IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9TVEVOQ0lMX0JBQ0tfUEFTU19ERVBUSF9GQUlMXyA6IGludCBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfU1RFTkNJTF9CQUNLX1BBU1NfREVQVEhfUEFTU18gOiBpbnQgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1NURU5DSUxfQkFDS19SRUZfIDogaW50IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9TVEVOQ0lMX0JBQ0tfVkFMVUVfTUFTS18gOiBpbnQgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1NURU5DSUxfQkFDS19XUklURU1BU0tfIDogaW50IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9WSUVXUE9SVCA6IFR5cGVkX2FycmF5LmludDMyQXJyYXkgdCBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfU0NJU1NPUl9CT1hfIDogVHlwZWRfYXJyYXkuaW50MzJBcnJheSB0IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9DT0xPUl9DTEVBUl9WQUxVRV8gOiBUeXBlZF9hcnJheS5mbG9hdDMyQXJyYXkgdCBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfQ09MT1JfV1JJVEVNQVNLXyA6IGJvb2wgdCBqc19hcnJheSB0IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9VTlBBQ0tfQUxJR05NRU5UX1BBUkFNIDogaW50IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9QQUNLX0FMSUdOTUVOVF8gOiBpbnQgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX01BWF9URVhUVVJFX1NJWkVfIDogaW50IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9NQVhfVklFV1BPUlRfRElNU18gOiBUeXBlZF9hcnJheS5pbnQzMkFycmF5IHQgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1NVQlBJWEVMX0JJVFNfIDogaW50IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9SRURfQklUU18gOiBpbnQgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0dSRUVOX0JJVFNfIDogaW50IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9CTFVFX0JJVFNfIDogaW50IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9BTFBIQV9CSVRTXyA6IGludCBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfREVQVEhfQklUU18gOiBpbnQgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1NURU5DSUxfQklUU18gOiBpbnQgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1BPTFlHT05fT0ZGU0VUX1VOSVRTXyA6IG51bWJlcl90IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9QT0xZR09OX09GRlNFVF9GQUNUT1JfIDogbnVtYmVyX3QgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1RFWFRVUkVfQklORElOR18yRF8gOiB0ZXh0dXJlIHQgb3B0IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFX0JJTkRJTkdfQ1VCRV9NQVBfIDogdGV4dHVyZSB0IG9wdCBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfU0FNUExFX0JVRkZFUlNfIDogaW50IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9TQU1QTEVTXyA6IGludCBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfU0FNUExFX0NPVkVSQUdFX1ZBTFVFXyA6IG51bWJlcl90IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9TQU1QTEVfQ09WRVJBR0VfSU5WRVJUXyA6IGJvb2wgdCBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfTlVNX0NPTVBSRVNTRURfVEVYVFVSRV9GT1JNQVRTXyA6IGludCBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfQ09NUFJFU1NFRF9URVhUVVJFX0ZPUk1BVFNfIDogVHlwZWRfYXJyYXkudWludDMyQXJyYXkgdCBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfR0VORVJBVEVfTUlQTUFQX0hJTlRfUEFSQU1fIDogaGludE1vZGUgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0JVRkZFUl9TSVpFXyA6IGludCBidWZmZXJQYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfQlVGRkVSX1VTQUdFXyA6IGJ1ZmZlclVzYWdlIGJ1ZmZlclBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9CWVRFIDogZGF0YVR5cGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVU5TSUdORURfQllURV9EVCA6IGRhdGFUeXBlIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1NIT1JUIDogZGF0YVR5cGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVU5TSUdORURfU0hPUlRfIDogZGF0YVR5cGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfSU5UIDogZGF0YVR5cGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVU5TSUdORURfSU5UXyA6IGRhdGFUeXBlIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0ZMT0FUIDogZGF0YVR5cGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVU5TSUdORURfQllURV8gOiBwaXhlbFR5cGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVU5TSUdORURfU0hPUlRfNF80XzRfNF8gOiBwaXhlbFR5cGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVU5TSUdORURfU0hPUlRfNV81XzVfMV8gOiBwaXhlbFR5cGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVU5TSUdORURfU0hPUlRfNV82XzVfIDogcGl4ZWxUeXBlIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0FMUEhBIDogcGl4ZWxGb3JtYXQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfUkdCIDogcGl4ZWxGb3JtYXQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfUkdCQSA6IHBpeGVsRm9ybWF0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0xVTUlOQU5DRSA6IHBpeGVsRm9ybWF0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0xVTUlOQU5DRV9BTFBIQV8gOiBwaXhlbEZvcm1hdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9TVEVOQ0lMX0lOREVYXyA6IHBpeGVsRm9ybWF0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0RFUFRIX1NURU5DSUxfIDogcGl4ZWxGb3JtYXQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfREVQVEhfQ09NUE9ORU5UXyA6IHBpeGVsRm9ybWF0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0ZSQUdNRU5UX1NIQURFUl8gOiBzaGFkZXJUeXBlIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1ZFUlRFWF9TSEFERVJfIDogc2hhZGVyVHlwZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9NQVhfVkVSVEVYX0FUVFJJQlNfIDogaW50IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9NQVhfVkVSVEVYX1VOSUZPUk1fVkVDVE9SU18gOiBpbnQgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX01BWF9WQVJZSU5HX1ZFQ1RPUlNfIDogaW50IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9NQVhfQ09NQklORURfVEVYVFVSRV9JTUFHRV9VTklUU18gOiBpbnQgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX01BWF9WRVJURVhfVEVYVFVSRV9JTUFHRV9VTklUU18gOiBpbnQgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX01BWF9URVhUVVJFX0lNQUdFX1VOSVRTXyA6IGludCBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfTUFYX0ZSQUdNRU5UX1VOSUZPUk1fVkVDVE9SU18gOiBpbnQgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1NIQURFUl9UWVBFXyA6IHNoYWRlclR5cGUgc2hhZGVyUGFyYW0gcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfREVMRVRFX1NUQVRVU18gOiBib29sIHQgc2hhZGVyUGFyYW0gcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfQ09NUElMRV9TVEFUVVNfIDogYm9vbCB0IHNoYWRlclBhcmFtIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0RFTEVURV9TVEFUVVNfUFJPRyA6IGJvb2wgdCBwcm9ncmFtUGFyYW0gcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfTElOS19TVEFUVVNfIDogYm9vbCB0IHByb2dyYW1QYXJhbSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9WQUxJREFURV9TVEFUVVNfIDogYm9vbCB0IHByb2dyYW1QYXJhbSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9BVFRBQ0hFRF9TSEFERVJTXyA6IGludCBwcm9ncmFtUGFyYW0gcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfQUNUSVZFX1VOSUZPUk1TXyA6IGludCBwcm9ncmFtUGFyYW0gcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfQUNUSVZFX0FUVFJJQlVURVNfIDogaW50IHByb2dyYW1QYXJhbSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9TSEFESU5HX0xBTkdVQUdFX1ZFUlNJT05fIDoganNfc3RyaW5nIHQgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0NVUlJFTlRfUFJPR1JBTV8gOiBwcm9ncmFtIHQgb3B0IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9WRU5ET1IgOiBqc19zdHJpbmcgdCBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfUkVOREVSRVIgOiBqc19zdHJpbmcgdCBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVkVSU0lPTiA6IGpzX3N0cmluZyB0IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9NQVhfQ1VCRV9NQVBfVEVYVFVSRV9TSVpFXyA6IGludCBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfQUNUSVZFX1RFWFRVUkVfIDogaW50IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9GUkFNRUJVRkZFUl9CSU5ESU5HXyA6IGZyYW1lYnVmZmVyIHQgb3B0IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9SRU5ERVJCVUZGRVJfQklORElOR18gOiByZW5kZXJidWZmZXIgdCBvcHQgcGFyYW1ldGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX01BWF9SRU5ERVJCVUZGRVJfU0laRSA6IGludCBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfTkVWRVIgOiBkZXB0aEZ1bmN0aW9uIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0xFU1MgOiBkZXB0aEZ1bmN0aW9uIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0VRVUFMIDogZGVwdGhGdW5jdGlvbiByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9MRVFVQUwgOiBkZXB0aEZ1bmN0aW9uIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0dSRUFURVIgOiBkZXB0aEZ1bmN0aW9uIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX05PVEVRVUFMIDogZGVwdGhGdW5jdGlvbiByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9HRVFVQUwgOiBkZXB0aEZ1bmN0aW9uIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0FMV0FZUyA6IGRlcHRoRnVuY3Rpb24gcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfS0VFUCA6IHN0ZW5jaWxPcCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9SRVBMQUNFIDogc3RlbmNpbE9wIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0lOQ1IgOiBzdGVuY2lsT3AgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfREVDUiA6IHN0ZW5jaWxPcCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9JTlZFUlQgOiBzdGVuY2lsT3AgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfSU5DUl9XUkFQXyA6IHN0ZW5jaWxPcCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9ERUNSX1dSQVBfIDogc3RlbmNpbE9wIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1pFUk9fIDogc3RlbmNpbE9wIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX05FQVJFU1QgOiB0ZXhGaWx0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfTElORUFSIDogdGV4RmlsdGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX05FQVJFU1RfTUlQTUFQX05FQVJFU1RfIDogdGV4RmlsdGVyIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0xJTkVBUl9NSVBNQVBfTkVBUkVTVF8gOiB0ZXhGaWx0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfTkVBUkVTVF9NSVBNQVBfTElORUFSXyA6IHRleEZpbHRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9MSU5FQVJfTUlQTUFQX0xJTkVBUl8gOiB0ZXhGaWx0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVEVYVFVSRV9NQUdfRklMVEVSXyA6IHRleEZpbHRlciB0ZXhQYXJhbSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFX01JTl9GSUxURVJfIDogdGV4RmlsdGVyIHRleFBhcmFtIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1RFWFRVUkVfV1JBUF9TXyA6IHdyYXBNb2RlIHRleFBhcmFtIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1RFWFRVUkVfV1JBUF9UXyA6IHdyYXBNb2RlIHRleFBhcmFtIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX05PTkVfT1QgOiBvYmplY3RUeXBlIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1RFWFRVUkVfT1QgOiBvYmplY3RUeXBlIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1JFTkRFUkJVRkZFUl9PVCA6IG9iamVjdFR5cGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVEVYVFVSRV8yRF8gOiB0ZXhUYXJnZXQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVEVYVFVSRV9DVUJFX01BUF8gOiB0ZXhUYXJnZXQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVEVYVFVSRV9DVUJFX01BUF9QT1NJVElWRV9YXyA6IHRleFRhcmdldCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFX0NVQkVfTUFQX05FR0FUSVZFX1hfIDogdGV4VGFyZ2V0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1RFWFRVUkVfQ1VCRV9NQVBfUE9TSVRJVkVfWV8gOiB0ZXhUYXJnZXQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVEVYVFVSRV9DVUJFX01BUF9ORUdBVElWRV9ZXyA6IHRleFRhcmdldCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFX0NVQkVfTUFQX1BPU0lUSVZFX1pfIDogdGV4VGFyZ2V0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1RFWFRVUkVfQ1VCRV9NQVBfTkVHQVRJVkVfWl8gOiB0ZXhUYXJnZXQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVEVYVFVSRTAgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMSA6IHRleHR1cmVVbml0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1RFWFRVUkUyIDogdGV4dHVyZVVuaXQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVEVYVFVSRTMgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFNCA6IHRleHR1cmVVbml0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1RFWFRVUkU1IDogdGV4dHVyZVVuaXQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVEVYVFVSRTYgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFNyA6IHRleHR1cmVVbml0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1RFWFRVUkU4IDogdGV4dHVyZVVuaXQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVEVYVFVSRTkgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMTAgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMTEgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMTIgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMTMgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMTQgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMTUgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMTYgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMTcgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMTggOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMTkgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMjAgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMjEgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMjIgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMjMgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMjQgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMjUgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMjYgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMjcgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMjggOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMjkgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMzAgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9URVhUVVJFMzEgOiB0ZXh0dXJlVW5pdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9SRVBFQVQgOiB3cmFwTW9kZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9DTEFNUF9UT19FREdFXyA6IHdyYXBNb2RlIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX01JUlJPUkVEX1JFUEVBVF8gOiB3cmFwTW9kZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9GTE9BVF8gOiB1bmlmb3JtVHlwZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9GTE9BVF9WRUMyXyA6IHVuaWZvcm1UeXBlIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0ZMT0FUX1ZFQzNfIDogdW5pZm9ybVR5cGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfRkxPQVRfVkVDNF8gOiB1bmlmb3JtVHlwZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9JTlRfIDogdW5pZm9ybVR5cGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfSU5UX1ZFQzJfIDogdW5pZm9ybVR5cGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfSU5UX1ZFQzNfIDogdW5pZm9ybVR5cGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfSU5UX1ZFQzRfIDogdW5pZm9ybVR5cGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfQk9PTF8gOiB1bmlmb3JtVHlwZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9CT09MX1ZFQzJfIDogdW5pZm9ybVR5cGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfQk9PTF9WRUMzXyA6IHVuaWZvcm1UeXBlIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0JPT0xfVkVDNF8gOiB1bmlmb3JtVHlwZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9GTE9BVF9NQVQyXyA6IHVuaWZvcm1UeXBlIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0ZMT0FUX01BVDNfIDogdW5pZm9ybVR5cGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfRkxPQVRfTUFUNF8gOiB1bmlmb3JtVHlwZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9TQU1QTEVSXzJEXyA6IHVuaWZvcm1UeXBlIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1NBTVBMRVJfQ1VCRV8gOiB1bmlmb3JtVHlwZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9WRVJURVhfQVRUUklCX0FSUkFZX0VOQUJMRURfIDogYm9vbCB0IHZlcnRleEF0dHJpYlBhcmFtIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1ZFUlRFWF9BVFRSSUJfQVJSQVlfU0laRV8gOiBpbnQgdmVydGV4QXR0cmliUGFyYW0gcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVkVSVEVYX0FUVFJJQl9BUlJBWV9TVFJJREVfIDogaW50IHZlcnRleEF0dHJpYlBhcmFtIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1ZFUlRFWF9BVFRSSUJfQVJSQVlfVFlQRV8gOiBpbnQgdmVydGV4QXR0cmliUGFyYW0gcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVkVSVEVYX0FUVFJJQl9BUlJBWV9OT1JNQUxJWkVEXyA6IGJvb2wgdCB2ZXJ0ZXhBdHRyaWJQYXJhbSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9WRVJURVhfQVRUUklCX0FSUkFZX1BPSU5URVJfIDogdmVydGV4QXR0cmliUG9pbnRlclBhcmFtIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1ZFUlRFWF9BVFRSSUJfQVJSQVlfQlVGRkVSX0JJTkRJTkdfIDpcbiAgICBidWZmZXIgdCBvcHQgdmVydGV4QXR0cmliUGFyYW0gcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfQ1VSUkVOVF9WRVJURVhfQVRUUklCXyA6XG4gICAgVHlwZWRfYXJyYXkuZmxvYXQzMkFycmF5IHQgdmVydGV4QXR0cmliUGFyYW0gcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfTE9XX0ZMT0FUXyA6IHNoYWRlclByZWNpc2lvblR5cGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfTUVESVVNX0ZMT0FUXyA6IHNoYWRlclByZWNpc2lvblR5cGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfSElHSF9GTE9BVF8gOiBzaGFkZXJQcmVjaXNpb25UeXBlIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0xPV19JTlRfIDogc2hhZGVyUHJlY2lzaW9uVHlwZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9NRURJVU1fSU5UXyA6IHNoYWRlclByZWNpc2lvblR5cGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfSElHSF9JTlRfIDogc2hhZGVyUHJlY2lzaW9uVHlwZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9GUkFNRUJVRkZFUiA6IGZiVGFyZ2V0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1JFTkRFUkJVRkZFUiA6IHJiVGFyZ2V0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1JHQkE0IDogZm9ybWF0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1JHQjVfQTFfIDogZm9ybWF0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1JHQjU2NSA6IGZvcm1hdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9ERVBUSF9DT01QT05FTlQxNl8gOiBmb3JtYXQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfU1RFTkNJTF9JTkRFWDhfIDogZm9ybWF0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1JFTkRFUkJVRkZFUl9XSURUSF8gOiBpbnQgcmVuZGVyYnVmZmVyUGFyYW0gcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfUkVOREVSQlVGRkVSX0hFSUdIVF8gOiBpbnQgcmVuZGVyYnVmZmVyUGFyYW0gcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfUkVOREVSQlVGRkVSX0lOVEVSTkFMX0ZPUk1BVF8gOiBmb3JtYXQgcmVuZGVyYnVmZmVyUGFyYW0gcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfUkVOREVSQlVGRkVSX1JFRF9TSVpFXyA6IGludCByZW5kZXJidWZmZXJQYXJhbSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9SRU5ERVJCVUZGRVJfR1JFRU5fU0laRV8gOiBpbnQgcmVuZGVyYnVmZmVyUGFyYW0gcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfUkVOREVSQlVGRkVSX0JMVUVfU0laRV8gOiBpbnQgcmVuZGVyYnVmZmVyUGFyYW0gcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfUkVOREVSQlVGRkVSX0FMUEhBX1NJWkVfIDogaW50IHJlbmRlcmJ1ZmZlclBhcmFtIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1JFTkRFUkJVRkZFUl9ERVBUSF9TSVpFXyA6IGludCByZW5kZXJidWZmZXJQYXJhbSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9SRU5ERVJCVUZGRVJfU1RFTkNJTF9TSVpFXyA6IGludCByZW5kZXJidWZmZXJQYXJhbSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9GUkFNRUJVRkZFUl9BVFRBQ0hNRU5UX09CSkVDVF9UWVBFXyA6IG9iamVjdFR5cGUgYXR0YWNoUGFyYW0gcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfRlJBTUVCVUZGRVJfQVRUQUNITUVOVF9PQkpFQ1RfTkFNRV9SRU5ERVJCVUZGRVIgOlxuICAgIHJlbmRlcmJ1ZmZlciB0IGF0dGFjaFBhcmFtIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0ZSQU1FQlVGRkVSX0FUVEFDSE1FTlRfT0JKRUNUX05BTUVfVEVYVFVSRSA6IHRleHR1cmUgdCBhdHRhY2hQYXJhbSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9GUkFNRUJVRkZFUl9BVFRBQ0hNRU5UX1RFWFRVUkVfTEVWRUxfIDogaW50IGF0dGFjaFBhcmFtIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0ZSQU1FQlVGRkVSX0FUVEFDSE1FTlRfVEVYVFVSRV9DVUJFX01BUF9GQUNFXyA6IGludCBhdHRhY2hQYXJhbSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9DT0xPUl9BVFRBQ0hNRU5UMF8gOiBhdHRhY2htZW50UG9pbnQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfREVQVEhfQVRUQUNITUVOVF8gOiBhdHRhY2htZW50UG9pbnQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfU1RFTkNJTF9BVFRBQ0hNRU5UXyA6IGF0dGFjaG1lbnRQb2ludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9ERVBUSF9TVEVOQ0lMX0FUVEFDSE1FTlRfIDogYXR0YWNobWVudFBvaW50IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0ZSQU1FQlVGRkVSX0NPTVBMRVRFXyA6IGZyYW1lYnVmZmVyU3RhdHVzIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0ZSQU1FQlVGRkVSX0lOQ09NUExFVEVfQVRUQUNITUVOVF8gOiBmcmFtZWJ1ZmZlclN0YXR1cyByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9GUkFNRUJVRkZFUl9JTkNPTVBMRVRFX01JU1NJTkdfQVRUQUNITUVOVF8gOiBmcmFtZWJ1ZmZlclN0YXR1cyByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9GUkFNRUJVRkZFUl9JTkNPTVBMRVRFX0RJTUVOU0lPTlNfIDogZnJhbWVidWZmZXJTdGF0dXMgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfRlJBTUVCVUZGRVJfVU5TVVBQT1JURURfIDogZnJhbWVidWZmZXJTdGF0dXMgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVU5QQUNLX0ZMSVBfWV9XRUJHTF9QQVJBTSA6IGJvb2wgdCBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVU5QQUNLX1BSRU1VTFRJUExZX0FMUEhBX1dFQkdMX1BBUkFNIDogYm9vbCB0IHBhcmFtZXRlciByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9VTlBBQ0tfQ09MT1JTUEFDRV9DT05WRVJTSU9OX1dFQkdMX1BBUkFNIDpcbiAgICBjb2xvcnNwYWNlQ29udmVyc2lvbiBwYXJhbWV0ZXIgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfTk9ORSA6IGNvbG9yc3BhY2VDb252ZXJzaW9uIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX0JST1dTRVJfREVGQVVMVF9XRUJHTF8gOiBjb2xvcnNwYWNlQ29udmVyc2lvbiByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9VTlBBQ0tfQUxJR05NRU5UXyA6IGludCBwaXhlbFN0b3JlUGFyYW0gcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBfVU5QQUNLX0ZMSVBfWV9XRUJHTF8gOiBib29sIHQgcGl4ZWxTdG9yZVBhcmFtIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1VOUEFDS19QUkVNVUxUSVBMWV9BTFBIQV9XRUJHTF8gOiBib29sIHQgcGl4ZWxTdG9yZVBhcmFtIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1VOUEFDS19DT0xPUlNQQUNFX0NPTlZFUlNJT05fV0VCR0xfIDogaW50IHBpeGVsU3RvcmVQYXJhbSByZWFkb25seV9wcm9wXG5lbmRcblxuKCoqIDUuMTQgV2ViR0xDb250ZXh0RXZlbnQgKilcblxuY2xhc3MgdHlwZSBjb250ZXh0RXZlbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBEb21faHRtbC5ldmVudFxuXG4gIG1ldGhvZCBzdGF0dXNNZXNzYWdlIDoganNfc3RyaW5nIHQgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbm1vZHVsZSBFdmVudCA9IHN0cnVjdFxuICBsZXQgd2ViZ2xjb250ZXh0bG9zdCA9IERvbV9odG1sLkV2ZW50Lm1ha2UgXCJ3ZWJnbGNvbnRleHRsb3N0XCJcblxuICBsZXQgd2ViZ2xjb250ZXh0cmVzdG9yZWQgPSBEb21faHRtbC5FdmVudC5tYWtlIFwid2ViZ2xjb250ZXh0cmVzdG9yZWRcIlxuXG4gIGxldCB3ZWJnbGNvbnRleHRjcmVhdGlvbmVycm9yID0gRG9tX2h0bWwuRXZlbnQubWFrZSBcIndlYmdsY29udGV4dGNyZWF0aW9uZXJyb3JcIlxuZW5kXG5cbigqKioqKVxuXG5jbGFzcyB0eXBlIGNhbnZhc0VsZW1lbnQgPSBvYmplY3RcbiAgbWV0aG9kIGdldENvbnRleHQgOiBqc19zdHJpbmcgdCAtPiByZW5kZXJpbmdDb250ZXh0IHQgb3B0IG1ldGhcblxuICBtZXRob2QgZ2V0Q29udGV4dF8gOiBqc19zdHJpbmcgdCAtPiBjb250ZXh0QXR0cmlidXRlcyB0IC0+IHJlbmRlcmluZ0NvbnRleHQgdCBvcHQgbWV0aFxuZW5kXG5cbmxldCBnZXRDb250ZXh0IChjIDogRG9tX2h0bWwuY2FudmFzRWxlbWVudCB0KSA9XG4gIGxldCBjIDogY2FudmFzRWxlbWVudCB0ID0gSnMuVW5zYWZlLmNvZXJjZSBjIGluXG4gIGxldCBjdHggPSBjIyNnZXRDb250ZXh0IChKcy5zdHJpbmcgXCJ3ZWJnbFwiKSBpblxuICBpZiBPcHQudGVzdCBjdHggdGhlbiBjdHggZWxzZSBjICMjIChnZXRDb250ZXh0IChKcy5zdHJpbmcgXCJleHBlcmltZW50YWwtd2ViZ2xcIikpXG5cbmxldCBnZXRDb250ZXh0V2l0aEF0dHJpYnV0ZXMgKGMgOiBEb21faHRtbC5jYW52YXNFbGVtZW50IHQpIGF0dHJpYnMgPVxuICBsZXQgYyA6IGNhbnZhc0VsZW1lbnQgdCA9IEpzLlVuc2FmZS5jb2VyY2UgYyBpblxuICBsZXQgY3R4ID0gYyMjZ2V0Q29udGV4dF8gKEpzLnN0cmluZyBcIndlYmdsXCIpIGF0dHJpYnMgaW5cbiAgaWYgT3B0LnRlc3QgY3R4IHRoZW4gY3R4IGVsc2UgYyMjZ2V0Q29udGV4dF8gKEpzLnN0cmluZyBcImV4cGVyaW1lbnRhbC13ZWJnbFwiKSBhdHRyaWJzXG4iLCIoKiBKc19vZl9vY2FtbCBsaWJyYXJ5XG4gKiBodHRwOi8vd3d3Lm9jc2lnZW4ub3JnL2pzX29mX29jYW1sL1xuICogQ29weXJpZ2h0IChDKSAyMDEwIFJhcGhhw6tsIFByb3VzdCwgSsOpcsO0bWUgVm91aWxsb25cbiAqIExhYm9yYXRvaXJlIFBQUyAtIENOUlMgVW5pdmVyc2l0w6kgUGFyaXMgRGlkZXJvdFxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHdpdGggbGlua2luZyBleGNlcHRpb247XG4gKiBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcsIFVTQS5cbiAqKVxub3BlbiEgSW1wb3J0XG5cbnR5cGUgcmVnZXhwID0gSnMucmVnRXhwIEpzLnRcblxudHlwZSByZXN1bHQgPSBKcy5tYXRjaF9yZXN1bHQgSnMudFxuXG5sZXQgcmVnZXhwIHMgPSBuZXclanMgSnMucmVnRXhwX3dpdGhGbGFncyAoSnMuYnl0ZXN0cmluZyBzKSAoSnMuc3RyaW5nIFwiZ1wiKVxuXG5sZXQgcmVnZXhwX2Nhc2VfZm9sZCBzID0gbmV3JWpzIEpzLnJlZ0V4cF93aXRoRmxhZ3MgKEpzLmJ5dGVzdHJpbmcgcykgKEpzLnN0cmluZyBcImdpXCIpXG5cbmxldCByZWdleHBfd2l0aF9mbGFnIHMgZiA9XG4gIG5ldyVqcyBKcy5yZWdFeHBfd2l0aEZsYWdzIChKcy5ieXRlc3RyaW5nIHMpIChKcy5zdHJpbmcgKFwiZ1wiIF4gZikpXG5cbmxldCBibHVudF9zdHJfYXJyYXlfZ2V0IGEgaSA9XG4gIEpzLnRvX2J5dGVzdHJpbmcgKEpzLk9wdGRlZi5nZXQgKEpzLmFycmF5X2dldCBhIGkpIChmdW4gKCkgLT4gYXNzZXJ0IGZhbHNlKSlcblxubGV0IHN0cmluZ19tYXRjaCByIHMgaSA9XG4gIHIjIy5sYXN0SW5kZXggOj0gaTtcbiAgSnMuT3B0LnRvX29wdGlvbiAoSnMuT3B0Lm1hcCAociMjZXhlYyAoSnMuYnl0ZXN0cmluZyBzKSkgSnMubWF0Y2hfcmVzdWx0KVxuXG5sZXQgc2VhcmNoIHIgcyBpID1cbiAgciMjLmxhc3RJbmRleCA6PSBpO1xuICBKcy5PcHQudG9fb3B0aW9uXG4gICAgKEpzLk9wdC5tYXBcbiAgICAgICAociMjZXhlYyAoSnMuYnl0ZXN0cmluZyBzKSlcbiAgICAgICAoZnVuIHJlc19wcmUgLT5cbiAgICAgICAgIGxldCByZXMgPSBKcy5tYXRjaF9yZXN1bHQgcmVzX3ByZSBpblxuICAgICAgICAgcmVzIyMuaW5kZXgsIHJlcykpXG5cbmxldCBzZWFyY2hfZm9yd2FyZCA9IHNlYXJjaFxuXG5sZXQgbWF0Y2hlZF9zdHJpbmcgciA9IGJsdW50X3N0cl9hcnJheV9nZXQgciAwXG5cbmxldCBtYXRjaGVkX2dyb3VwIHIgaSA9XG4gIEpzLk9wdGRlZi50b19vcHRpb24gKEpzLk9wdGRlZi5tYXAgKEpzLmFycmF5X2dldCByIGkpIEpzLnRvX2J5dGVzdHJpbmcpXG5cbmxldCBxdW90ZV9yZXBsX3JlID0gbmV3JWpzIEpzLnJlZ0V4cF93aXRoRmxhZ3MgKEpzLnN0cmluZyBcIlskXVwiKSAoSnMuc3RyaW5nIFwiZ1wiKVxuXG5sZXQgcXVvdGVfcmVwbCBzID0gKEpzLmJ5dGVzdHJpbmcgcykjI3JlcGxhY2UgcXVvdGVfcmVwbF9yZSAoSnMuc3RyaW5nIFwiJCQkJFwiKVxuXG5sZXQgZ2xvYmFsX3JlcGxhY2UgciBzIHNfYnkgPVxuICByIyMubGFzdEluZGV4IDo9IDA7XG4gIEpzLnRvX2J5dGVzdHJpbmcgKEpzLmJ5dGVzdHJpbmcgcykgIyMgKHJlcGxhY2UgciAocXVvdGVfcmVwbCBzX2J5KSlcblxubGV0IHJlcGxhY2VfZmlyc3QgciBzIHNfYnkgPVxuICBsZXQgZmxhZ3MgPVxuICAgIG1hdGNoIEpzLnRvX2Jvb2wgciMjLmlnbm9yZUNhc2UsIEpzLnRvX2Jvb2wgciMjLm11bHRpbGluZSB3aXRoXG4gICAgfCBmYWxzZSwgZmFsc2UgLT4gSnMuc3RyaW5nIFwiXCJcbiAgICB8IGZhbHNlLCB0cnVlIC0+IEpzLnN0cmluZyBcIm1cIlxuICAgIHwgdHJ1ZSwgZmFsc2UgLT4gSnMuc3RyaW5nIFwiaVwiXG4gICAgfCB0cnVlLCB0cnVlIC0+IEpzLnN0cmluZyBcIm1pXCJcbiAgaW5cbiAgbGV0IHInID0gbmV3JWpzIEpzLnJlZ0V4cF93aXRoRmxhZ3MgciMjLnNvdXJjZSBmbGFncyBpblxuICBKcy50b19ieXRlc3RyaW5nIChKcy5ieXRlc3RyaW5nIHMpICMjIChyZXBsYWNlIHInIChxdW90ZV9yZXBsIHNfYnkpKVxuXG5sZXQgbGlzdF9vZl9qc19hcnJheSBhID1cbiAgbGV0IHJlYyBhdXggYWNjdSBpZHggPVxuICAgIGlmIGlkeCA8IDAgdGhlbiBhY2N1IGVsc2UgYXV4IChibHVudF9zdHJfYXJyYXlfZ2V0IGEgaWR4IDo6IGFjY3UpIChpZHggLSAxKVxuICBpblxuICBhdXggW10gKGEjIy5sZW5ndGggLSAxKVxuXG5sZXQgc3BsaXQgciBzID1cbiAgciMjLmxhc3RJbmRleCA6PSAwO1xuICBsaXN0X29mX2pzX2FycmF5IChKcy5zdHJfYXJyYXkgKEpzLmJ5dGVzdHJpbmcgcykgIyMgKHNwbGl0X3JlZ0V4cCByKSlcblxubGV0IGJvdW5kZWRfc3BsaXQgciBzIGkgPVxuICByIyMubGFzdEluZGV4IDo9IDA7XG4gIGxpc3Rfb2ZfanNfYXJyYXkgKEpzLnN0cl9hcnJheSAoSnMuYnl0ZXN0cmluZyBzKSAjIyAoc3BsaXRfcmVnRXhwTGltaXRlZCByIGkpKVxuXG4oKiBNb3JlIGNvbnN0cnVjdG9ycyAqKVxuXG5sZXQgcXVvdGVfcmUgPSByZWdleHAgXCJbXFxcXF1bKClcXFxcXFxcXHwrKi4/e31eJF1cIlxuXG5sZXQgcXVvdGUgcyA9IEpzLnRvX2J5dGVzdHJpbmcgKEpzLmJ5dGVzdHJpbmcgcykgIyMgKHJlcGxhY2UgcXVvdGVfcmUgKEpzLnN0cmluZyBcIlxcXFwkJlwiKSlcblxubGV0IHJlZ2V4cF9zdHJpbmcgcyA9IHJlZ2V4cCAocXVvdGUgcylcblxubGV0IHJlZ2V4cF9zdHJpbmdfY2FzZV9mb2xkIHMgPSByZWdleHBfY2FzZV9mb2xkIChxdW90ZSBzKVxuIiwiKCogSnNfb2Zfb2NhbWwgbGlicmFyeVxuICogaHR0cDovL3d3dy5vY3NpZ2VuLm9yZy9qc19vZl9vY2FtbC9cbiAqIENvcHlyaWdodCAoQykgMjAxMCBSYXBoYcOrbCBQcm91c3RcbiAqIExhYm9yYXRvaXJlIFBQUyAtIENOUlMgVW5pdmVyc2l0w6kgUGFyaXMgRGlkZXJvdFxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHdpdGggbGlua2luZyBleGNlcHRpb247XG4gKiBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcsIFVTQS5cbiAqKVxub3BlbiEgSW1wb3J0XG5cbigqIFVybCB0YW1wZXJpbmcuICopXG5cbmxldCBzcGxpdCBjIHMgPSBKcy5zdHJfYXJyYXkgKHMjI3NwbGl0IChKcy5zdHJpbmcgKFN0cmluZy5tYWtlIDEgYykpKVxuXG5sZXQgc3BsaXRfMiBjIHMgPVxuICBsZXQgaW5kZXggPSBzIyNpbmRleE9mIChKcy5zdHJpbmcgKFN0cmluZy5tYWtlIDEgYykpIGluXG4gIGlmIGluZGV4IDwgMCB0aGVuIEpzLnVuZGVmaW5lZCBlbHNlIEpzLmRlZiAocyMjc2xpY2UgMCBpbmRleCwgcyMjc2xpY2VfZW5kIChpbmRleCArIDEpKVxuXG5leGNlcHRpb24gTG9jYWxfZXhuXG5cbmxldCBpbnRlcnJ1cHQgKCkgPSByYWlzZSBMb2NhbF9leG5cblxuKCogdXJsIChBS0EgcGVyY2VudCkgZW5jb2RpbmcvZGVjb2RpbmcgKilcblxubGV0IHBsdXNfcmUgPSBSZWdleHAucmVnZXhwX3N0cmluZyBcIitcIlxuXG5sZXQgZXNjYXBlX3BsdXMgcyA9IFJlZ2V4cC5nbG9iYWxfcmVwbGFjZSBwbHVzX3JlIHMgXCIlMkJcIlxuXG5sZXQgdW5lc2NhcGVfcGx1cyBzID0gUmVnZXhwLmdsb2JhbF9yZXBsYWNlIHBsdXNfcmUgcyBcIiBcIlxuXG5sZXQgcGx1c19yZV9qc19zdHJpbmcgPSBuZXclanMgSnMucmVnRXhwX3dpdGhGbGFncyAoSnMuc3RyaW5nIFwiXFxcXCtcIikgKEpzLnN0cmluZyBcImdcIilcblxubGV0IHVuZXNjYXBlX3BsdXNfanNfc3RyaW5nIHMgPVxuICBwbHVzX3JlX2pzX3N0cmluZyMjLmxhc3RJbmRleCA6PSAwO1xuICBzIyNyZXBsYWNlIHBsdXNfcmVfanNfc3RyaW5nIChKcy5zdHJpbmcgXCIgXCIpXG5cbmxldCB1cmxkZWNvZGVfanNfc3RyaW5nX3N0cmluZyBzID1cbiAgSnMudG9fYnl0ZXN0cmluZyAoSnMudW5lc2NhcGUgKHVuZXNjYXBlX3BsdXNfanNfc3RyaW5nIHMpKVxuXG5sZXQgdXJsZGVjb2RlIHMgPSBKcy50b19ieXRlc3RyaW5nIChKcy51bmVzY2FwZSAoSnMuYnl0ZXN0cmluZyAodW5lc2NhcGVfcGx1cyBzKSkpXG5cbigqbGV0IHVybGVuY29kZV9qc19zdHJpbmdfc3RyaW5nIHMgPVxuICBKcy50b19ieXRlc3RyaW5nIChKcy5lc2NhcGUgcykqKVxuXG5sZXQgdXJsZW5jb2RlID8od2l0aF9wbHVzID0gdHJ1ZSkgcyA9XG4gIGlmIHdpdGhfcGx1c1xuICB0aGVuIGVzY2FwZV9wbHVzIChKcy50b19ieXRlc3RyaW5nIChKcy5lc2NhcGUgKEpzLmJ5dGVzdHJpbmcgcykpKVxuICBlbHNlIEpzLnRvX2J5dGVzdHJpbmcgKEpzLmVzY2FwZSAoSnMuYnl0ZXN0cmluZyBzKSlcblxudHlwZSBodHRwX3VybCA9XG4gIHsgaHVfaG9zdCA6IHN0cmluZyAgKCoqIFRoZSBob3N0IHBhcnQgb2YgdGhlIHVybC4gKilcbiAgOyBodV9wb3J0IDogaW50ICAoKiogVGhlIHBvcnQgZm9yIHRoZSBjb25uZWN0aW9uIGlmIGFueS4gKilcbiAgOyBodV9wYXRoIDogc3RyaW5nIGxpc3QgICgqKiBUaGUgcGF0aCBzcGxpdCBvbiBbJy8nXSBjaGFyYWN0ZXJzLiAqKVxuICA7IGh1X3BhdGhfc3RyaW5nIDogc3RyaW5nICAoKiogVGhlIG9yaWdpbmFsIGVudGlyZSBwYXRoLiAqKVxuICA7IGh1X2FyZ3VtZW50cyA6IChzdHJpbmcgKiBzdHJpbmcpIGxpc3RcbiAgICAgICAgKCoqIEFyZ3VtZW50cyBhcyBhIGZpZWxkLXZhbHVlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NvY2lhdGlvbiBsaXN0LiopXG4gIDsgaHVfZnJhZ21lbnQgOiBzdHJpbmcgICgqKiBUaGUgZnJhZ21lbnQgcGFydCAoYWZ0ZXIgdGhlIFsnIyddIGNoYXJhY3RlcikuICopXG4gIH1cbigqKiBUaGUgdHlwZSBmb3IgSFRUUCB1cmwuICopXG5cbnR5cGUgZmlsZV91cmwgPVxuICB7IGZ1X3BhdGggOiBzdHJpbmcgbGlzdFxuICA7IGZ1X3BhdGhfc3RyaW5nIDogc3RyaW5nXG4gIDsgZnVfYXJndW1lbnRzIDogKHN0cmluZyAqIHN0cmluZykgbGlzdFxuICA7IGZ1X2ZyYWdtZW50IDogc3RyaW5nXG4gIH1cbigqKiBUaGUgdHlwZSBmb3IgbG9jYWwgZmlsZSB1cmxzLiAqKVxuXG50eXBlIHVybCA9XG4gIHwgSHR0cCBvZiBodHRwX3VybFxuICB8IEh0dHBzIG9mIGh0dHBfdXJsXG4gIHwgRmlsZSBvZiBmaWxlX3VybFxuICAgICAgKCoqIFRoZSB0eXBlIGZvciB1cmxzLiBbRmlsZV0gaXMgZm9yIGxvY2FsIGZpbGVzIGFuZCBbRXhvdGljIHNdIGlzIGZvclxuICAgIHVua25vd24vdW5zdXBwb3J0ZWQgcHJvdG9jb2xzLiAqKVxuXG5leGNlcHRpb24gTm90X2FuX2h0dHBfcHJvdG9jb2xcblxubGV0IGlzX3NlY3VyZSBwcm90X3N0cmluZyA9XG4gIG1hdGNoIEpzLnRvX2J5dGVzdHJpbmcgcHJvdF9zdHJpbmcjI3RvTG93ZXJDYXNlIHdpdGhcbiAgfCBcImh0dHBzOlwiIHwgXCJodHRwc1wiIC0+IHRydWVcbiAgfCBcImh0dHA6XCIgfCBcImh0dHBcIiAtPiBmYWxzZVxuICB8IFwiZmlsZTpcIiB8IFwiZmlsZVwiIHwgXyAtPiByYWlzZSBOb3RfYW5faHR0cF9wcm90b2NvbFxuXG4oKiBwb3J0IG51bWJlciAqKVxubGV0IGRlZmF1bHRfaHR0cF9wb3J0ID0gODBcblxubGV0IGRlZmF1bHRfaHR0cHNfcG9ydCA9IDQ0M1xuXG4oKiBwYXRoICopXG5sZXQgcGF0aF9vZl9wYXRoX3N0cmluZyBzID1cbiAgbGV0IGwgPSBTdHJpbmcubGVuZ3RoIHMgaW5cbiAgbGV0IHJlYyBhdXggaSA9XG4gICAgbGV0IGogPSB0cnkgU3RyaW5nLmluZGV4X2Zyb20gcyBpICcvJyB3aXRoIE5vdF9mb3VuZCAtPiBsIGluXG4gICAgbGV0IHdvcmQgPSBTdHJpbmcuc3ViIHMgaSAoaiAtIGkpIGluXG4gICAgaWYgaiA+PSBsIHRoZW4gWyB3b3JkIF0gZWxzZSB3b3JkIDo6IGF1eCAoaiArIDEpXG4gIGluXG4gIG1hdGNoIGF1eCAwIHdpdGhcbiAgfCBbIFwiXCIgXSAtPiBbXVxuICB8IFsgXCJcIjsgXCJcIiBdIC0+IFsgXCJcIiBdXG4gIHwgYSAtPiBhXG5cbigqIEFyZ3VtZW50cyAqKVxubGV0IGVuY29kZV9hcmd1bWVudHMgbCA9XG4gIFN0cmluZy5jb25jYXQgXCImXCIgKExpc3QubWFwIChmdW4gKG4sIHYpIC0+IHVybGVuY29kZSBuIF4gXCI9XCIgXiB1cmxlbmNvZGUgdikgbClcblxubGV0IGRlY29kZV9hcmd1bWVudHNfanNfc3RyaW5nIHMgPVxuICBsZXQgYXJyID0gc3BsaXQgJyYnIHMgaW5cbiAgbGV0IGxlbiA9IGFyciMjLmxlbmd0aCBpblxuICBsZXQgbmFtZV92YWx1ZV9zcGxpdCBzID0gc3BsaXRfMiAnPScgcyBpblxuICBsZXQgcmVjIGF1eCBhY2MgaWR4ID1cbiAgICBpZiBpZHggPCAwXG4gICAgdGhlbiBhY2NcbiAgICBlbHNlXG4gICAgICB0cnlcbiAgICAgICAgYXV4XG4gICAgICAgICAgKEpzLk9wdGRlZi5jYXNlIChKcy5hcnJheV9nZXQgYXJyIGlkeCkgaW50ZXJydXB0IChmdW4gcyAtPlxuICAgICAgICAgICAgICAgSnMuT3B0ZGVmLmNhc2UgKG5hbWVfdmFsdWVfc3BsaXQgcykgaW50ZXJydXB0IChmdW4gKHgsIHkpIC0+XG4gICAgICAgICAgICAgICAgICAgbGV0IGdldCA9IHVybGRlY29kZV9qc19zdHJpbmdfc3RyaW5nIGluXG4gICAgICAgICAgICAgICAgICAgZ2V0IHgsIGdldCB5KSlcbiAgICAgICAgICA6OiBhY2MpXG4gICAgICAgICAgKHByZWQgaWR4KVxuICAgICAgd2l0aCBMb2NhbF9leG4gLT4gYXV4IGFjYyAocHJlZCBpZHgpXG4gIGluXG4gIGF1eCBbXSAobGVuIC0gMSlcblxubGV0IGRlY29kZV9hcmd1bWVudHMgcyA9IGRlY29kZV9hcmd1bWVudHNfanNfc3RyaW5nIChKcy5ieXRlc3RyaW5nIHMpXG5cbmxldCB1cmxfcmUgPVxuICBuZXclanMgSnMucmVnRXhwXG4gICAgKEpzLmJ5dGVzdHJpbmdcbiAgICAgICBcIl4oW0hoXVtUdF1bVHRdW1BwXVtTc10/KTovLyhbMC05YS16QS1aLi1dK3xcXFxcW1swLTlhLXpBLVouLV0rXFxcXF18XFxcXFtbMC05QS1GYS1mOi5dK1xcXFxdKT8oOihbMC05XSspKT8oLyhbXlxcXFw/I10qKShcXFxcPyhbXiNdKikpPygjKC4qKSk/KT8kXCIpXG5cbmxldCBmaWxlX3JlID1cbiAgbmV3JWpzIEpzLnJlZ0V4cFxuICAgIChKcy5ieXRlc3RyaW5nIFwiXihbRmZdW0lpXVtMbF1bRWVdKTovLyhbXlxcXFw/I10qKShcXFxcPyhbXiNdKikpPygjKC4qKSk/JFwiKVxuXG5sZXQgdXJsX29mX2pzX3N0cmluZyBzID1cbiAgSnMuT3B0LmNhc2VcbiAgICAodXJsX3JlIyNleGVjIHMpXG4gICAgKGZ1biAoKSAtPlxuICAgICAgSnMuT3B0LmNhc2VcbiAgICAgICAgKGZpbGVfcmUjI2V4ZWMgcylcbiAgICAgICAgKGZ1biAoKSAtPiBOb25lKVxuICAgICAgICAoZnVuIGhhbmRsZSAtPlxuICAgICAgICAgIGxldCByZXMgPSBKcy5tYXRjaF9yZXN1bHQgaGFuZGxlIGluXG4gICAgICAgICAgbGV0IHBhdGhfc3RyID1cbiAgICAgICAgICAgIHVybGRlY29kZV9qc19zdHJpbmdfc3RyaW5nIChKcy5PcHRkZWYuZ2V0IChKcy5hcnJheV9nZXQgcmVzIDIpIGludGVycnVwdClcbiAgICAgICAgICBpblxuICAgICAgICAgIFNvbWVcbiAgICAgICAgICAgIChGaWxlXG4gICAgICAgICAgICAgICB7IGZ1X3BhdGggPSBwYXRoX29mX3BhdGhfc3RyaW5nIHBhdGhfc3RyXG4gICAgICAgICAgICAgICA7IGZ1X3BhdGhfc3RyaW5nID0gcGF0aF9zdHJcbiAgICAgICAgICAgICAgIDsgZnVfYXJndW1lbnRzID1cbiAgICAgICAgICAgICAgICAgICBkZWNvZGVfYXJndW1lbnRzX2pzX3N0cmluZ1xuICAgICAgICAgICAgICAgICAgICAgKEpzLk9wdGRlZi5nZXQgKEpzLmFycmF5X2dldCByZXMgNCkgKGZ1biAoKSAtPiBKcy5ieXRlc3RyaW5nIFwiXCIpKVxuICAgICAgICAgICAgICAgOyBmdV9mcmFnbWVudCA9XG4gICAgICAgICAgICAgICAgICAgSnMudG9fYnl0ZXN0cmluZ1xuICAgICAgICAgICAgICAgICAgICAgKEpzLk9wdGRlZi5nZXQgKEpzLmFycmF5X2dldCByZXMgNikgKGZ1biAoKSAtPiBKcy5ieXRlc3RyaW5nIFwiXCIpKVxuICAgICAgICAgICAgICAgfSkpKVxuICAgIChmdW4gaGFuZGxlIC0+XG4gICAgICBsZXQgcmVzID0gSnMubWF0Y2hfcmVzdWx0IGhhbmRsZSBpblxuICAgICAgbGV0IHNzbCA9IGlzX3NlY3VyZSAoSnMuT3B0ZGVmLmdldCAoSnMuYXJyYXlfZ2V0IHJlcyAxKSBpbnRlcnJ1cHQpIGluXG4gICAgICBsZXQgcG9ydF9vZl9zdHJpbmcgPSBmdW5jdGlvblxuICAgICAgICB8IFwiXCIgLT4gaWYgc3NsIHRoZW4gNDQzIGVsc2UgODBcbiAgICAgICAgfCBzIC0+IGludF9vZl9zdHJpbmcgc1xuICAgICAgaW5cbiAgICAgIGxldCBwYXRoX3N0ciA9XG4gICAgICAgIHVybGRlY29kZV9qc19zdHJpbmdfc3RyaW5nXG4gICAgICAgICAgKEpzLk9wdGRlZi5nZXQgKEpzLmFycmF5X2dldCByZXMgNikgKGZ1biAoKSAtPiBKcy5ieXRlc3RyaW5nIFwiXCIpKVxuICAgICAgaW5cbiAgICAgIGxldCB1cmwgPVxuICAgICAgICB7IGh1X2hvc3QgPVxuICAgICAgICAgICAgdXJsZGVjb2RlX2pzX3N0cmluZ19zdHJpbmcgKEpzLk9wdGRlZi5nZXQgKEpzLmFycmF5X2dldCByZXMgMikgaW50ZXJydXB0KVxuICAgICAgICA7IGh1X3BvcnQgPVxuICAgICAgICAgICAgcG9ydF9vZl9zdHJpbmdcbiAgICAgICAgICAgICAgKEpzLnRvX2J5dGVzdHJpbmdcbiAgICAgICAgICAgICAgICAgKEpzLk9wdGRlZi5nZXQgKEpzLmFycmF5X2dldCByZXMgNCkgKGZ1biAoKSAtPiBKcy5ieXRlc3RyaW5nIFwiXCIpKSlcbiAgICAgICAgOyBodV9wYXRoID0gcGF0aF9vZl9wYXRoX3N0cmluZyBwYXRoX3N0clxuICAgICAgICA7IGh1X3BhdGhfc3RyaW5nID0gcGF0aF9zdHJcbiAgICAgICAgOyBodV9hcmd1bWVudHMgPVxuICAgICAgICAgICAgZGVjb2RlX2FyZ3VtZW50c19qc19zdHJpbmdcbiAgICAgICAgICAgICAgKEpzLk9wdGRlZi5nZXQgKEpzLmFycmF5X2dldCByZXMgOCkgKGZ1biAoKSAtPiBKcy5ieXRlc3RyaW5nIFwiXCIpKVxuICAgICAgICA7IGh1X2ZyYWdtZW50ID1cbiAgICAgICAgICAgIHVybGRlY29kZV9qc19zdHJpbmdfc3RyaW5nXG4gICAgICAgICAgICAgIChKcy5PcHRkZWYuZ2V0IChKcy5hcnJheV9nZXQgcmVzIDEwKSAoZnVuICgpIC0+IEpzLmJ5dGVzdHJpbmcgXCJcIikpXG4gICAgICAgIH1cbiAgICAgIGluXG4gICAgICBTb21lIChpZiBzc2wgdGhlbiBIdHRwcyB1cmwgZWxzZSBIdHRwIHVybCkpXG5cbmxldCB1cmxfb2Zfc3RyaW5nIHMgPSB1cmxfb2ZfanNfc3RyaW5nIChKcy5ieXRlc3RyaW5nIHMpXG5cbmxldCBzdHJpbmdfb2ZfdXJsID0gZnVuY3Rpb25cbiAgfCBGaWxlIHsgZnVfcGF0aCA9IHBhdGg7IGZ1X2FyZ3VtZW50cyA9IGFyZ3M7IGZ1X2ZyYWdtZW50ID0gZnJhZzsgXyB9IC0+IChcbiAgICAgIFwiZmlsZTovL1wiXG4gICAgICBeIFN0cmluZy5jb25jYXQgXCIvXCIgKExpc3QubWFwIChmdW4geCAtPiB1cmxlbmNvZGUgeCkgcGF0aClcbiAgICAgIF4gKG1hdGNoIGFyZ3Mgd2l0aFxuICAgICAgICB8IFtdIC0+IFwiXCJcbiAgICAgICAgfCBsIC0+IFwiP1wiIF4gZW5jb2RlX2FyZ3VtZW50cyBsKVxuICAgICAgXlxuICAgICAgbWF0Y2ggZnJhZyB3aXRoXG4gICAgICB8IFwiXCIgLT4gXCJcIlxuICAgICAgfCBzIC0+IFwiI1wiIF4gdXJsZW5jb2RlIHMpXG4gIHwgSHR0cFxuICAgICAgeyBodV9ob3N0ID0gaG9zdFxuICAgICAgOyBodV9wb3J0ID0gcG9ydFxuICAgICAgOyBodV9wYXRoID0gcGF0aFxuICAgICAgOyBodV9hcmd1bWVudHMgPSBhcmdzXG4gICAgICA7IGh1X2ZyYWdtZW50ID0gZnJhZ1xuICAgICAgOyBfXG4gICAgICB9IC0+IChcbiAgICAgIFwiaHR0cDovL1wiXG4gICAgICBeIHVybGVuY29kZSBob3N0XG4gICAgICBeIChtYXRjaCBwb3J0IHdpdGhcbiAgICAgICAgfCA4MCAtPiBcIlwiXG4gICAgICAgIHwgbiAtPiBcIjpcIiBeIHN0cmluZ19vZl9pbnQgbilcbiAgICAgIF4gXCIvXCJcbiAgICAgIF4gU3RyaW5nLmNvbmNhdCBcIi9cIiAoTGlzdC5tYXAgKGZ1biB4IC0+IHVybGVuY29kZSB4KSBwYXRoKVxuICAgICAgXiAobWF0Y2ggYXJncyB3aXRoXG4gICAgICAgIHwgW10gLT4gXCJcIlxuICAgICAgICB8IGwgLT4gXCI/XCIgXiBlbmNvZGVfYXJndW1lbnRzIGwpXG4gICAgICBeXG4gICAgICBtYXRjaCBmcmFnIHdpdGhcbiAgICAgIHwgXCJcIiAtPiBcIlwiXG4gICAgICB8IHMgLT4gXCIjXCIgXiB1cmxlbmNvZGUgcylcbiAgfCBIdHRwc1xuICAgICAgeyBodV9ob3N0ID0gaG9zdFxuICAgICAgOyBodV9wb3J0ID0gcG9ydFxuICAgICAgOyBodV9wYXRoID0gcGF0aFxuICAgICAgOyBodV9hcmd1bWVudHMgPSBhcmdzXG4gICAgICA7IGh1X2ZyYWdtZW50ID0gZnJhZ1xuICAgICAgOyBfXG4gICAgICB9IC0+IChcbiAgICAgIFwiaHR0cHM6Ly9cIlxuICAgICAgXiB1cmxlbmNvZGUgaG9zdFxuICAgICAgXiAobWF0Y2ggcG9ydCB3aXRoXG4gICAgICAgIHwgNDQzIC0+IFwiXCJcbiAgICAgICAgfCBuIC0+IFwiOlwiIF4gc3RyaW5nX29mX2ludCBuKVxuICAgICAgXiBcIi9cIlxuICAgICAgXiBTdHJpbmcuY29uY2F0IFwiL1wiIChMaXN0Lm1hcCAoZnVuIHggLT4gdXJsZW5jb2RlIHgpIHBhdGgpXG4gICAgICBeIChtYXRjaCBhcmdzIHdpdGhcbiAgICAgICAgfCBbXSAtPiBcIlwiXG4gICAgICAgIHwgbCAtPiBcIj9cIiBeIGVuY29kZV9hcmd1bWVudHMgbClcbiAgICAgIF5cbiAgICAgIG1hdGNoIGZyYWcgd2l0aFxuICAgICAgfCBcIlwiIC0+IFwiXCJcbiAgICAgIHwgcyAtPiBcIiNcIiBeIHVybGVuY29kZSBzKVxuXG5tb2R1bGUgQ3VycmVudCA9IHN0cnVjdFxuICBsZXQgbCA9XG4gICAgaWYgSnMuT3B0ZGVmLnRlc3QgKEpzLk9wdGRlZi5yZXR1cm4gRG9tX2h0bWwud2luZG93IyMubG9jYXRpb24pXG4gICAgdGhlbiBEb21faHRtbC53aW5kb3cjIy5sb2NhdGlvblxuICAgIGVsc2VcbiAgICAgIGxldCBlbXB0eSA9IEpzLnN0cmluZyBcIlwiIGluXG4gICAgICBvYmplY3QlanNcbiAgICAgICAgdmFsIG11dGFibGUgaHJlZiA9IGVtcHR5XG5cbiAgICAgICAgdmFsIG11dGFibGUgcHJvdG9jb2wgPSBlbXB0eVxuXG4gICAgICAgIHZhbCBtdXRhYmxlIGhvc3QgPSBlbXB0eVxuXG4gICAgICAgIHZhbCBtdXRhYmxlIGhvc3RuYW1lID0gZW1wdHlcblxuICAgICAgICB2YWwgbXV0YWJsZSBwb3J0ID0gZW1wdHlcblxuICAgICAgICB2YWwgbXV0YWJsZSBwYXRobmFtZSA9IGVtcHR5XG5cbiAgICAgICAgdmFsIG11dGFibGUgc2VhcmNoID0gZW1wdHlcblxuICAgICAgICB2YWwgbXV0YWJsZSBoYXNoID0gZW1wdHlcblxuICAgICAgICB2YWwgb3JpZ2luID0gSnMudW5kZWZpbmVkXG5cbiAgICAgICAgbWV0aG9kIHJlbG9hZCA9ICgpXG5cbiAgICAgICAgbWV0aG9kIHJlcGxhY2UgXyA9ICgpXG5cbiAgICAgICAgbWV0aG9kIGFzc2lnbiBfID0gKClcbiAgICAgIGVuZFxuXG4gIGxldCBob3N0ID0gdXJsZGVjb2RlX2pzX3N0cmluZ19zdHJpbmcgbCMjLmhvc3RuYW1lXG5cbiAgbGV0IHByb3RvY29sID0gdXJsZGVjb2RlX2pzX3N0cmluZ19zdHJpbmcgbCMjLnByb3RvY29sXG5cbiAgbGV0IHBvcnQgPVxuICAgIChmdW4gKCkgLT5cbiAgICAgIHRyeSBTb21lIChpbnRfb2Zfc3RyaW5nIChKcy50b19ieXRlc3RyaW5nIGwjIy5wb3J0KSkgd2l0aCBGYWlsdXJlIF8gLT4gTm9uZSlcbiAgICAgICgpXG5cbiAgbGV0IHBhdGhfc3RyaW5nID0gdXJsZGVjb2RlX2pzX3N0cmluZ19zdHJpbmcgbCMjLnBhdGhuYW1lXG5cbiAgbGV0IHBhdGggPSBwYXRoX29mX3BhdGhfc3RyaW5nIHBhdGhfc3RyaW5nXG5cbiAgbGV0IGFyZ3VtZW50cyA9XG4gICAgZGVjb2RlX2FyZ3VtZW50c19qc19zdHJpbmdcbiAgICAgIChpZiBKcy5lcXVhbHMgKGwjIy5zZWFyY2gjI2NoYXJBdCAwKSAoSnMuc3RyaW5nIFwiP1wiKVxuICAgICAgIHRoZW4gbCMjLnNlYXJjaCMjc2xpY2VfZW5kIDFcbiAgICAgICBlbHNlIGwjIy5zZWFyY2gpXG5cbiAgbGV0IGdldF9mcmFnbWVudCAoKSA9XG4gICAgbGV0IHMgPSBKcy50b19ieXRlc3RyaW5nIGwjIy5oYXNoIGluXG4gICAgaWYgU3RyaW5nLmxlbmd0aCBzID4gMCAmJiBDaGFyLmVxdWFsIHMuWzBdICcjJ1xuICAgIHRoZW4gU3RyaW5nLnN1YiBzIDEgKFN0cmluZy5sZW5ndGggcyAtIDEpXG4gICAgZWxzZSBzXG5cbiAgbGV0IHNldF9mcmFnbWVudCBzID0gbCMjLmhhc2ggOj0gSnMuYnl0ZXN0cmluZyBzXG5cbiAgbGV0IGdldCAoKSA9IHVybF9vZl9qc19zdHJpbmcgbCMjLmhyZWZcblxuICBsZXQgc2V0IHUgPSBsIyMuaHJlZiA6PSBKcy5ieXRlc3RyaW5nIChzdHJpbmdfb2ZfdXJsIHUpXG5cbiAgbGV0IGFzX3N0cmluZyA9IHVybGRlY29kZV9qc19zdHJpbmdfc3RyaW5nIGwjIy5ocmVmXG5lbmRcbiIsIigqIEpzX29mX29jYW1sIGxpYnJhcnlcbiAqIGh0dHA6Ly93d3cub2NzaWdlbi5vcmcvanNfb2Zfb2NhbWwvXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTQgSHVnbyBIZXV6YXJkXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgd2l0aCBsaW5raW5nIGV4Y2VwdGlvbjtcbiAqIGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4gKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLlxuICopXG5vcGVuISBJbXBvcnRcblxuZXh0ZXJuYWwgY3JlYXRlX2ZpbGUgOiBuYW1lOnN0cmluZyAtPiBjb250ZW50OnN0cmluZyAtPiB1bml0ID0gXCJjYW1sX2NyZWF0ZV9maWxlXCJcblxuZXh0ZXJuYWwgcmVhZF9maWxlIDogbmFtZTpzdHJpbmcgLT4gc3RyaW5nID0gXCJjYW1sX3JlYWRfZmlsZV9jb250ZW50XCJcblxubGV0IHVwZGF0ZV9maWxlIH5uYW1lIH5jb250ZW50ID1cbiAgbGV0IG9jID0gb3Blbl9vdXQgbmFtZSBpblxuICBvdXRwdXRfc3RyaW5nIG9jIGNvbnRlbnQ7XG4gIGNsb3NlX291dCBvY1xuXG5leHRlcm5hbCBzZXRfY2hhbm5lbF9vdXRwdXQnIDpcbiAgb3V0X2NoYW5uZWwgLT4gKEpzLmpzX3N0cmluZyBKcy50IC0+IHVuaXQpIEpzLmNhbGxiYWNrIC0+IHVuaXRcbiAgPSBcImNhbWxfbWxfc2V0X2NoYW5uZWxfb3V0cHV0XCJcblxuZXh0ZXJuYWwgc2V0X2NoYW5uZWxfaW5wdXQnIDogaW5fY2hhbm5lbCAtPiAodW5pdCAtPiBzdHJpbmcpIEpzLmNhbGxiYWNrIC0+IHVuaXRcbiAgPSBcImNhbWxfbWxfc2V0X2NoYW5uZWxfcmVmaWxsXCJcblxubGV0IHNldF9jaGFubmVsX2ZsdXNoZXIgKG91dF9jaGFubmVsIDogb3V0X2NoYW5uZWwpIChmIDogc3RyaW5nIC0+IHVuaXQpID1cbiAgbGV0IGYnIDogKEpzLmpzX3N0cmluZyBKcy50IC0+IHVuaXQpIEpzLmNhbGxiYWNrID1cbiAgICBKcy53cmFwX2NhbGxiYWNrIChmdW4gcyAtPiBmIChKcy50b19ieXRlc3RyaW5nIHMpKVxuICBpblxuICBzZXRfY2hhbm5lbF9vdXRwdXQnIG91dF9jaGFubmVsIGYnXG5cbmxldCBzZXRfY2hhbm5lbF9maWxsZXIgKGluX2NoYW5uZWwgOiBpbl9jaGFubmVsKSAoZiA6IHVuaXQgLT4gc3RyaW5nKSA9XG4gIGxldCBmJyA6ICh1bml0IC0+IHN0cmluZykgSnMuY2FsbGJhY2sgPSBKcy53cmFwX2NhbGxiYWNrIGYgaW5cbiAgc2V0X2NoYW5uZWxfaW5wdXQnIGluX2NoYW5uZWwgZidcblxuZXh0ZXJuYWwgbW91bnRfcG9pbnQgOiB1bml0IC0+IHN0cmluZyBsaXN0ID0gXCJjYW1sX2xpc3RfbW91bnRfcG9pbnRcIlxuXG5leHRlcm5hbCBtb3VudF9hdXRvbG9hZCA6XG4gIHN0cmluZyAtPiAoc3RyaW5nIC0+IHN0cmluZyAtPiBzdHJpbmcgb3B0aW9uKSBKcy5jYWxsYmFjayAtPiB1bml0XG4gID0gXCJjYW1sX21vdW50X2F1dG9sb2FkXCJcblxuZXh0ZXJuYWwgdW5tb3VudCA6IHN0cmluZyAtPiB1bml0ID0gXCJjYW1sX3VubW91bnRcIlxuXG5sZXQgbW91bnQgfnBhdGggZiA9XG4gIG1vdW50X2F1dG9sb2FkIHBhdGggKEpzLndyYXBfY2FsbGJhY2sgKGZ1biBwcmVmaXggcGF0aCAtPiBmIH5wcmVmaXggfnBhdGgpKVxuXG5sZXQgdW5tb3VudCB+cGF0aCA9IHVubW91bnQgcGF0aFxuXG5sZXQganNfb2Zfb2NhbWxfdmVyc2lvbiA9XG4gIGlmIFN0cmluZy5lcXVhbCBMaWJfdmVyc2lvbi5naXRfdmVyc2lvbiBcIlwiXG4gIHRoZW4gTGliX3ZlcnNpb24uc1xuICBlbHNlIExpYl92ZXJzaW9uLnMgXiBcIitcIiBeIExpYl92ZXJzaW9uLmdpdF92ZXJzaW9uXG4iLCIoKiBKc19vZl9vY2FtbCBsaWJyYXJ5XG4gKiBodHRwOi8vd3d3Lm9jc2lnZW4ub3JnL2pzX29mX29jYW1sL1xuICogQ29weXJpZ2h0IChDKSAyMDE5IEFsZXhhbmRlciBZYW5pblxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHdpdGggbGlua2luZyBleGNlcHRpb247XG4gKiBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcsIFVTQS5cbiAqKVxub3BlbiEgSW1wb3J0XG5cbmNsYXNzIHR5cGUgcmVzaXplT2JzZXJ2ZXJTaXplID0gb2JqZWN0XG4gIG1ldGhvZCBpbmxpbmVTaXplIDogSnMubnVtYmVyX3QgSnMucmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBibG9ja1NpemUgOiBKcy5udW1iZXJfdCBKcy5yZWFkb25seV9wcm9wXG5lbmRcblxuY2xhc3MgdHlwZSByZXNpemVPYnNlcnZlckVudHJ5ID0gb2JqZWN0XG4gIG1ldGhvZCB0YXJnZXQgOiBEb20ubm9kZSBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgY29udGVudFJlY3QgOiBEb21faHRtbC5jbGllbnRSZWN0IEpzLnQgSnMucmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBib3JkZXJCb3hTaXplIDogcmVzaXplT2JzZXJ2ZXJTaXplIEpzLnQgSnMuanNfYXJyYXkgSnMudCBKcy5yZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGNvbnRlbnRCb3hTaXplIDogcmVzaXplT2JzZXJ2ZXJTaXplIEpzLnQgSnMuanNfYXJyYXkgSnMudCBKcy5yZWFkb25seV9wcm9wXG5lbmRcblxuY2xhc3MgdHlwZSByZXNpemVPYnNlcnZlck9wdGlvbnMgPSBvYmplY3RcbiAgbWV0aG9kIGJveCA6IEpzLmpzX3N0cmluZyBKcy50IEpzLndyaXRlb25seV9wcm9wXG5lbmRcblxuY2xhc3MgdHlwZSByZXNpemVPYnNlcnZlciA9IG9iamVjdFxuICBtZXRob2Qgb2JzZXJ2ZSA6ICNEb20ubm9kZSBKcy50IC0+IHVuaXQgSnMubWV0aFxuXG4gIG1ldGhvZCBvYnNlcnZlX3dpdGhPcHRpb25zIDpcbiAgICAjRG9tLm5vZGUgSnMudCAtPiByZXNpemVPYnNlcnZlck9wdGlvbnMgSnMudCAtPiB1bml0IEpzLm1ldGhcblxuICBtZXRob2QgdW5vYnNlcnZlIDogI0RvbS5ub2RlIEpzLnQgLT4gdW5pdCBKcy5tZXRoXG5cbiAgbWV0aG9kIGRpc2Nvbm5lY3QgOiB1bml0IEpzLm1ldGhcbmVuZFxuXG5sZXQgZW1wdHlfcmVzaXplX29ic2VydmVyX29wdGlvbnMgKCkgOiByZXNpemVPYnNlcnZlck9wdGlvbnMgSnMudCA9IEpzLlVuc2FmZS5vYmogW3x8XVxuXG5sZXQgcmVzaXplT2JzZXJ2ZXIgPSBKcy5VbnNhZmUuZ2xvYmFsIyMuX1Jlc2l6ZU9ic2VydmVyXG5cbmxldCBpc19zdXBwb3J0ZWQgKCkgPSBKcy5PcHRkZWYudGVzdCByZXNpemVPYnNlcnZlclxuXG5sZXQgcmVzaXplT2JzZXJ2ZXIgOlxuICAgICggICAocmVzaXplT2JzZXJ2ZXJFbnRyeSBKcy50IEpzLmpzX2FycmF5IEpzLnQgLT4gcmVzaXplT2JzZXJ2ZXIgSnMudCAtPiB1bml0KVxuICAgICAgICBKcy5jYWxsYmFja1xuICAgICAtPiByZXNpemVPYnNlcnZlciBKcy50KVxuICAgIEpzLmNvbnN0ciA9XG4gIHJlc2l6ZU9ic2VydmVyXG5cbmxldCBvYnNlcnZlXG4gICAgfihub2RlIDogI0RvbS5ub2RlIEpzLnQpXG4gICAgfihmIDogcmVzaXplT2JzZXJ2ZXJFbnRyeSBKcy50IEpzLmpzX2FycmF5IEpzLnQgLT4gcmVzaXplT2JzZXJ2ZXIgSnMudCAtPiB1bml0KVxuICAgID8oYm94IDogSnMuanNfc3RyaW5nIEpzLnQgb3B0aW9uKVxuICAgICgpIDogcmVzaXplT2JzZXJ2ZXIgSnMudCA9XG4gIGxldCBvYnMgPSBuZXclanMgcmVzaXplT2JzZXJ2ZXIgKEpzLndyYXBfY2FsbGJhY2sgZikgaW5cbiAgKG1hdGNoIGJveCB3aXRoXG4gIHwgTm9uZSAtPiBvYnMjI29ic2VydmUgbm9kZVxuICB8IFNvbWUgYm94IC0+XG4gICAgICBsZXQgb3B0cyA9IGVtcHR5X3Jlc2l6ZV9vYnNlcnZlcl9vcHRpb25zICgpIGluXG4gICAgICBvcHRzIyMuYm94IDo9IGJveDtcbiAgICAgIG9icyMjb2JzZXJ2ZV93aXRoT3B0aW9ucyBub2RlIG9wdHMpO1xuICBvYnNcbiIsIigqIEpzX29mX29jYW1sIGxpYnJhcnlcbiAqIGh0dHA6Ly93d3cub2NzaWdlbi5vcmcvanNfb2Zfb2NhbWwvXG4gKiBDb3B5cmlnaHQgKEMpIDIwMjEgUGhpbGlwIFdoaXRlXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgd2l0aCBsaW5raW5nIGV4Y2VwdGlvbjtcbiAqIGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4gKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLlxuICopXG5cbm9wZW4hIEltcG9ydFxuXG5jbGFzcyB0eXBlIHBlcmZvcm1hbmNlT2JzZXJ2ZXJJbml0ID0gb2JqZWN0XG4gIG1ldGhvZCBlbnRyeVR5cGVzIDogSnMuanNfc3RyaW5nIEpzLnQgSnMuanNfYXJyYXkgSnMudCBKcy53cml0ZW9ubHlfcHJvcFxuZW5kXG5cbmNsYXNzIHR5cGUgcGVyZm9ybWFuY2VFbnRyeSA9IG9iamVjdFxuICBtZXRob2QgbmFtZSA6IEpzLmpzX3N0cmluZyBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZW50cnlUeXBlIDogSnMuanNfc3RyaW5nIEpzLnQgSnMucmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBzdGFydFRpbWUgOiBKcy5udW1iZXJfdCBKcy5yZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGR1cmF0aW9uIDogSnMubnVtYmVyX3QgSnMucmVhZG9ubHlfcHJvcFxuZW5kXG5cbmNsYXNzIHR5cGUgcGVyZm9ybWFuY2VPYnNlcnZlckVudHJ5TGlzdCA9IG9iamVjdFxuICBtZXRob2QgZ2V0RW50cmllcyA6IHBlcmZvcm1hbmNlRW50cnkgSnMudCBKcy5qc19hcnJheSBKcy50IEpzLm1ldGhcbmVuZFxuXG5jbGFzcyB0eXBlIHBlcmZvcm1hbmNlT2JzZXJ2ZXIgPSBvYmplY3RcbiAgbWV0aG9kIG9ic2VydmUgOiBwZXJmb3JtYW5jZU9ic2VydmVySW5pdCBKcy50IC0+IHVuaXQgSnMubWV0aFxuXG4gIG1ldGhvZCBkaXNjb25uZWN0IDogdW5pdCBKcy5tZXRoXG5cbiAgbWV0aG9kIHRha2VSZWNvcmRzIDogcGVyZm9ybWFuY2VFbnRyeSBKcy50IEpzLmpzX2FycmF5IEpzLnQgSnMubWV0aFxuZW5kXG5cbmxldCBwZXJmb3JtYW5jZU9ic2VydmVyID0gSnMuVW5zYWZlLmdsb2JhbCMjLl9QZXJmb3JtYW5jZU9ic2VydmVyXG5cbmxldCBpc19zdXBwb3J0ZWQgKCkgPSBKcy5PcHRkZWYudGVzdCBwZXJmb3JtYW5jZU9ic2VydmVyXG5cbmxldCBwZXJmb3JtYW5jZU9ic2VydmVyIDpcbiAgICAoICAgKHBlcmZvcm1hbmNlT2JzZXJ2ZXJFbnRyeUxpc3QgSnMudCAtPiBwZXJmb3JtYW5jZU9ic2VydmVyIEpzLnQgLT4gdW5pdCkgSnMuY2FsbGJhY2tcbiAgICAgLT4gcGVyZm9ybWFuY2VPYnNlcnZlciBKcy50KVxuICAgIEpzLmNvbnN0ciA9XG4gIHBlcmZvcm1hbmNlT2JzZXJ2ZXJcblxubGV0IG9ic2VydmUgfmVudHJ5X3R5cGVzIH5mID1cbiAgbGV0IGVudHJ5X3R5cGVzID0gZW50cnlfdHlwZXMgfD4gTGlzdC5tYXAgSnMuc3RyaW5nIHw+IEFycmF5Lm9mX2xpc3QgfD4gSnMuYXJyYXkgaW5cbiAgbGV0IHBlcmZvcm1hbmNlX29ic2VydmVyX2luaXQgOiBwZXJmb3JtYW5jZU9ic2VydmVySW5pdCBKcy50ID0gSnMuVW5zYWZlLm9iaiBbfHxdIGluXG4gIGxldCAoKSA9IHBlcmZvcm1hbmNlX29ic2VydmVyX2luaXQjIy5lbnRyeVR5cGVzIDo9IGVudHJ5X3R5cGVzIGluXG4gIGxldCBvYnMgPSBuZXclanMgcGVyZm9ybWFuY2VPYnNlcnZlciAoSnMud3JhcF9jYWxsYmFjayBmKSBpblxuICBsZXQgKCkgPSBvYnMjI29ic2VydmUgcGVyZm9ybWFuY2Vfb2JzZXJ2ZXJfaW5pdCBpblxuICBvYnNcbiIsIigqIEpzX29mX29jYW1sIGxpYnJhcnlcbiAqIGh0dHA6Ly93d3cub2NzaWdlbi5vcmcvanNfb2Zfb2NhbWwvXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTUgU3TDqXBoYW5lIExlZ3JhbmRcbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCB3aXRoIGxpbmtpbmcgZXhjZXB0aW9uO1xuICogZWl0aGVyIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuXG4gKilcbm9wZW4hIEltcG9ydFxuXG5jbGFzcyB0eXBlIG11dGF0aW9uT2JzZXJ2ZXJJbml0ID0gb2JqZWN0XG4gIG1ldGhvZCBjaGlsZExpc3QgOiBib29sIEpzLndyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIGF0dHJpYnV0ZXMgOiBib29sIEpzLndyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIGNoYXJhY3RlckRhdGEgOiBib29sIEpzLndyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIHN1YnRyZWUgOiBib29sIEpzLndyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIGF0dHJpYnV0ZU9sZFZhbHVlIDogYm9vbCBKcy53cml0ZW9ubHlfcHJvcFxuXG4gIG1ldGhvZCBjaGFyYWN0ZXJEYXRhT2xkVmFsdWUgOiBib29sIEpzLndyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIGF0dHJpYnV0ZUZpbHRlciA6IEpzLmpzX3N0cmluZyBKcy50IEpzLmpzX2FycmF5IEpzLnQgSnMud3JpdGVvbmx5X3Byb3BcbmVuZFxuXG5jbGFzcyB0eXBlIG11dGF0aW9uUmVjb3JkID0gb2JqZWN0XG4gIG1ldGhvZCBfdHlwZSA6IEpzLmpzX3N0cmluZyBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgdGFyZ2V0IDogRG9tLm5vZGUgSnMudCBKcy5yZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGFkZGVkTm9kZXMgOiBEb20ubm9kZSBEb20ubm9kZUxpc3QgSnMudCBKcy5yZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHJlbW92ZWROb2RlcyA6IERvbS5ub2RlIERvbS5ub2RlTGlzdCBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgcHJldmlvdXNTaWJsaW5nIDogRG9tLm5vZGUgSnMudCBKcy5vcHQgSnMucmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBuZXh0U2libGluZyA6IERvbS5ub2RlIEpzLnQgSnMub3B0IEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgYXR0cmlidXRlTmFtZSA6IEpzLmpzX3N0cmluZyBKcy50IEpzLm9wdCBKcy5yZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGF0dHJpYnV0ZU5hbWVzcGFjZSA6IEpzLmpzX3N0cmluZyBKcy50IEpzLm9wdCBKcy5yZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIG9sZFZhbHVlIDogSnMuanNfc3RyaW5nIEpzLnQgSnMub3B0IEpzLnJlYWRvbmx5X3Byb3BcbmVuZFxuXG5jbGFzcyB0eXBlIG11dGF0aW9uT2JzZXJ2ZXIgPSBvYmplY3RcbiAgbWV0aG9kIG9ic2VydmUgOiAjRG9tLm5vZGUgSnMudCAtPiBtdXRhdGlvbk9ic2VydmVySW5pdCBKcy50IC0+IHVuaXQgSnMubWV0aFxuXG4gIG1ldGhvZCBkaXNjb25uZWN0IDogdW5pdCBKcy5tZXRoXG5cbiAgbWV0aG9kIHRha2VSZWNvcmRzIDogbXV0YXRpb25SZWNvcmQgSnMudCBKcy5qc19hcnJheSBKcy50IEpzLm1ldGhcbmVuZFxuXG5sZXQgZW1wdHlfbXV0YXRpb25fb2JzZXJ2ZXJfaW5pdCAoKSA6IG11dGF0aW9uT2JzZXJ2ZXJJbml0IEpzLnQgPSBKcy5VbnNhZmUub2JqIFt8fF1cblxubGV0IG11dGF0aW9uT2JzZXJ2ZXIgPSBKcy5VbnNhZmUuZ2xvYmFsIyMuX011dGF0aW9uT2JzZXJ2ZXJcblxubGV0IGlzX3N1cHBvcnRlZCAoKSA9IEpzLk9wdGRlZi50ZXN0IG11dGF0aW9uT2JzZXJ2ZXJcblxubGV0IG11dGF0aW9uT2JzZXJ2ZXIgOlxuICAgICggICAobXV0YXRpb25SZWNvcmQgSnMudCBKcy5qc19hcnJheSBKcy50IC0+IG11dGF0aW9uT2JzZXJ2ZXIgSnMudCAtPiB1bml0KSBKcy5jYWxsYmFja1xuICAgICAtPiBtdXRhdGlvbk9ic2VydmVyIEpzLnQpXG4gICAgSnMuY29uc3RyID1cbiAgbXV0YXRpb25PYnNlcnZlclxuXG5sZXQgb2JzZXJ2ZVxuICAgIH4obm9kZSA6ICNEb20ubm9kZSBKcy50KVxuICAgIH4oZiA6IG11dGF0aW9uUmVjb3JkIEpzLnQgSnMuanNfYXJyYXkgSnMudCAtPiBtdXRhdGlvbk9ic2VydmVyIEpzLnQgLT4gdW5pdClcbiAgICA/KGNoaWxkX2xpc3QgOiBib29sIG9wdGlvbilcbiAgICA/KGF0dHJpYnV0ZXMgOiBib29sIG9wdGlvbilcbiAgICA/KGNoYXJhY3Rlcl9kYXRhIDogYm9vbCBvcHRpb24pXG4gICAgPyhzdWJ0cmVlIDogYm9vbCBvcHRpb24pXG4gICAgPyhhdHRyaWJ1dGVfb2xkX3ZhbHVlIDogYm9vbCBvcHRpb24pXG4gICAgPyhjaGFyYWN0ZXJfZGF0YV9vbGRfdmFsdWUgOiBib29sIG9wdGlvbilcbiAgICA/KGF0dHJpYnV0ZV9maWx0ZXIgOiBKcy5qc19zdHJpbmcgSnMudCBsaXN0IG9wdGlvbilcbiAgICAoKSA6IG11dGF0aW9uT2JzZXJ2ZXIgSnMudCA9XG4gIGxldCBvcHRfaXRlciB4IGYgPVxuICAgIG1hdGNoIHggd2l0aFxuICAgIHwgTm9uZSAtPiAoKVxuICAgIHwgU29tZSB4IC0+IGYgeFxuICBpblxuICBsZXQgb2JzID0gbmV3JWpzIG11dGF0aW9uT2JzZXJ2ZXIgKEpzLndyYXBfY2FsbGJhY2sgZikgaW5cbiAgbGV0IGNmZyA9IGVtcHR5X211dGF0aW9uX29ic2VydmVyX2luaXQgKCkgaW5cbiAgbGV0ICgpID0gb3B0X2l0ZXIgY2hpbGRfbGlzdCAoZnVuIHYgLT4gY2ZnIyMuY2hpbGRMaXN0IDo9IHYpIGluXG4gIGxldCAoKSA9IG9wdF9pdGVyIGF0dHJpYnV0ZXMgKGZ1biB2IC0+IGNmZyMjLmF0dHJpYnV0ZXMgOj0gdikgaW5cbiAgbGV0ICgpID0gb3B0X2l0ZXIgY2hhcmFjdGVyX2RhdGEgKGZ1biB2IC0+IGNmZyMjLmNoYXJhY3RlckRhdGEgOj0gdikgaW5cbiAgbGV0ICgpID0gb3B0X2l0ZXIgc3VidHJlZSAoZnVuIHYgLT4gY2ZnIyMuc3VidHJlZSA6PSB2KSBpblxuICBsZXQgKCkgPSBvcHRfaXRlciBhdHRyaWJ1dGVfb2xkX3ZhbHVlIChmdW4gdiAtPiBjZmcjIy5hdHRyaWJ1dGVPbGRWYWx1ZSA6PSB2KSBpblxuICBsZXQgKCkgPVxuICAgIG9wdF9pdGVyIGNoYXJhY3Rlcl9kYXRhX29sZF92YWx1ZSAoZnVuIHYgLT4gY2ZnIyMuY2hhcmFjdGVyRGF0YU9sZFZhbHVlIDo9IHYpXG4gIGluXG4gIGxldCAoKSA9XG4gICAgb3B0X2l0ZXIgYXR0cmlidXRlX2ZpbHRlciAoZnVuIGwgLT5cbiAgICAgICAgY2ZnIyMuYXR0cmlidXRlRmlsdGVyIDo9IEpzLmFycmF5IChBcnJheS5vZl9saXN0IGwpKVxuICBpblxuICBsZXQgKCkgPSBvYnMjI29ic2VydmUgbm9kZSBjZmcgaW5cbiAgb2JzXG4iLCIoKiBKc19vZl9vY2FtbCBsaWJyYXJ5XG4gKiBodHRwOi8vd3d3Lm9jc2lnZW4ub3JnL2pzX29mX29jYW1sL1xuICogQ29weXJpZ2h0IFBpZXJyZSBDaGFtYmFydCAyMDEyLlxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHdpdGggbGlua2luZyBleGNlcHRpb247XG4gKiBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcsIFVTQS5cbiAqKVxub3BlbiEgSW1wb3J0XG5cbnR5cGUgJ2EgdCA9IDwgPiBKcy50XG5cbmxldCBvYmogPSBKcy5VbnNhZmUuZ2xvYmFsIyMuX09iamVjdFxuXG5sZXQgY3JlYXRlICgpIDogJ2EgdCA9IG5ldyVqcyBvYmpcblxubGV0IGFkZCAodCA6ICdhIHQpIChrIDogSnMuanNfc3RyaW5nIEpzLnQpICh2IDogJ2EpID1cbiAgKCogJ18nIGlzIGFkZGVkIHRvIGF2b2lkIGNvbmZsaWN0cyB3aXRoIG9iamVjdHMgbWV0aG9kcyAqKVxuICBKcy5VbnNhZmUuc2V0IHQgKGsjI2NvbmNhdCAoSnMuc3RyaW5nIFwiX1wiKSkgdlxuXG5sZXQgcmVtb3ZlICh0IDogJ2EgdCkgKGsgOiBKcy5qc19zdHJpbmcgSnMudCkgPVxuICBKcy5VbnNhZmUuZGVsZXRlIHQgKGsjI2NvbmNhdCAoSnMuc3RyaW5nIFwiX1wiKSlcblxubGV0IGZpbmQgKHQgOiAnYSB0KSAoayA6IEpzLmpzX3N0cmluZyBKcy50KSA6ICdhIEpzLk9wdGRlZi50ID1cbiAgSnMuVW5zYWZlLmdldCB0IChrIyNjb25jYXQgKEpzLnN0cmluZyBcIl9cIikpXG5cbmxldCBrZXlzICh0IDogJ2EgdCkgOiBKcy5qc19zdHJpbmcgSnMudCBsaXN0ID1cbiAgbGV0IGtleV9hcnJheSA6IEpzLmpzX3N0cmluZyBKcy50IEpzLmpzX2FycmF5IEpzLnQgPVxuICAgIEpzLlVuc2FmZS5nbG9iYWwjIy5fT2JqZWN0IyNrZXlzIHRcbiAgaW5cbiAgbGV0IHJlcyA9IHJlZiBbXSBpblxuICBmb3IgaSA9IDAgdG8gcHJlZCBrZXlfYXJyYXkjIy5sZW5ndGggZG9cbiAgICBsZXQga2V5ID1cbiAgICAgIEpzLk9wdGRlZi5nZXQgKEpzLmFycmF5X2dldCBrZXlfYXJyYXkgaSkgKGZ1biAoKSAtPiBmYWlsd2l0aCBcIkpzdGFibGUua2V5c1wiKVxuICAgIGluXG4gICAgcmVzIDo9IGtleSMjc3Vic3RyaW5nIDAgKHByZWQga2V5IyMubGVuZ3RoKSA6OiAhcmVzXG4gIGRvbmU7XG4gIExpc3QucmV2ICFyZXNcbiIsIigqIEpzX29mX29jYW1sIGxpYnJhcnlcbiAqIGh0dHA6Ly93d3cub2NzaWdlbi5vcmcvanNfb2Zfb2NhbWwvXG4gKiBDb3B5cmlnaHQgR3LDqWdvaXJlIEhlbnJ5IDIwMTAuXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgd2l0aCBsaW5raW5nIGV4Y2VwdGlvbjtcbiAqIGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4gKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLlxuICopXG5cbm9wZW4gSnNcbm9wZW4hIEltcG9ydFxuXG5jbGFzcyB0eXBlIGpzb24gPSBvYmplY3RcbiAgbWV0aG9kIHBhcnNlIDogJ2EuIGpzX3N0cmluZyB0IC0+ICdhIG1ldGhcblxuICBtZXRob2QgcGFyc2VfIDpcbiAgICAnYSAnYiAnYyAnZC4ganNfc3RyaW5nIHQgLT4gKCdiIHQsIGpzX3N0cmluZyB0IC0+ICdjIC0+ICdkKSBtZXRoX2NhbGxiYWNrIC0+ICdhIG1ldGhcblxuICBtZXRob2Qgc3RyaW5naWZ5IDogJ2EuICdhIC0+IGpzX3N0cmluZyB0IG1ldGhcblxuICBtZXRob2Qgc3RyaW5naWZ5XyA6XG4gICAgJ2EgJ2IgJ2MgJ2QuICdhIC0+ICgnYiwganNfc3RyaW5nIHQgLT4gJ2MgLT4gJ2QpIG1ldGhfY2FsbGJhY2sgLT4ganNfc3RyaW5nIHQgbWV0aFxuZW5kXG5cbmxldCBqc29uIDoganNvbiBKcy50ID0gVW5zYWZlLmdsb2JhbCMjLl9KU09OXG5cbmxldCBpbnB1dF9yZXZpdmVyID1cbiAgbGV0IHJldml2ZXIgX3RoaXMgX2tleSAodmFsdWUgOiBVbnNhZmUuYW55KSA6IE9iai50ID1cbiAgICBpZiBKcy5lcXVhbHMgKHR5cGVvZiB2YWx1ZSkgKHN0cmluZyBcInN0cmluZ1wiKVxuICAgIHRoZW4gT2JqLnJlcHIgKHRvX2J5dGVzdHJpbmcgKFVuc2FmZS5jb2VyY2UgdmFsdWUpKVxuICAgIGVsc2UgaWYgaW5zdGFuY2VvZiB2YWx1ZSBKcy5hcnJheV9lbXB0eVxuICAgICAgICAgICAgJiYgKFVuc2FmZS5jb2VyY2UgdmFsdWUpIyMubGVuZ3RoID09IDRcbiAgICAgICAgICAgICYmIFVuc2FmZS5nZXQgdmFsdWUgMCA9PSAyNTVcbiAgICB0aGVuXG4gICAgICBPYmoucmVwclxuICAgICAgICAoSnNvb19ydW50aW1lLkludDY0LmNyZWF0ZV9pbnQ2NF9sb19taV9oaVxuICAgICAgICAgICAoVW5zYWZlLmdldCB2YWx1ZSAxKVxuICAgICAgICAgICAoVW5zYWZlLmdldCB2YWx1ZSAyKVxuICAgICAgICAgICAoVW5zYWZlLmdldCB2YWx1ZSAzKSlcbiAgICBlbHNlIE9iai5yZXByIHZhbHVlXG4gIGluXG4gIHdyYXBfbWV0aF9jYWxsYmFjayByZXZpdmVyXG5cbmxldCB1bnNhZmVfaW5wdXQgcyA9IGpzb24jI3BhcnNlXyBzIGlucHV0X3Jldml2ZXJcblxuY2xhc3MgdHlwZSBvYmogPSBvYmplY3RcbiAgbWV0aG9kIGNvbnN0cnVjdG9yIDogJ2EuICdhIGNvbnN0ciBKcy5yZWFkb25seV9wcm9wXG5lbmRcblxubGV0IG1sSW50NjRfY29uc3RyID1cbiAgbGV0IGR1bW15X2ludDY0ID0gMUwgaW5cbiAgbGV0IGR1bW15X29iaiA6IG9iaiB0ID0gT2JqLm1hZ2ljIGR1bW15X2ludDY0IGluXG4gIGR1bW15X29iaiMjLmNvbnN0cnVjdG9yXG5cbmxldCBvdXRwdXRfcmV2aXZlciBfa2V5ICh2YWx1ZSA6IFVuc2FmZS5hbnkpIDogT2JqLnQgPVxuICBpZiBPYmoudGFnIChPYmoucmVwciB2YWx1ZSkgPSBPYmouc3RyaW5nX3RhZ1xuICB0aGVuIE9iai5yZXByIChieXRlc3RyaW5nIChPYmoubWFnaWMgdmFsdWUgOiBzdHJpbmcpKVxuICBlbHNlIGlmIGluc3RhbmNlb2YgdmFsdWUgbWxJbnQ2NF9jb25zdHJcbiAgdGhlblxuICAgIGxldCB2YWx1ZSA9IFVuc2FmZS5jb2VyY2UgdmFsdWUgaW5cbiAgICBPYmoucmVwciAoYXJyYXkgW3wgMjU1OyB2YWx1ZSMjLmxvOyB2YWx1ZSMjLm1pOyB2YWx1ZSMjLmhpIHxdKVxuICBlbHNlIE9iai5yZXByIHZhbHVlXG5cbmxldCBvdXRwdXQgb2JqID0ganNvbiMjc3RyaW5naWZ5XyBvYmogKEpzLndyYXBfY2FsbGJhY2sgb3V0cHV0X3Jldml2ZXIpXG4iLCIoKiBKc19vZl9vY2FtbCBsaWJyYXJ5XG4gKiBodHRwOi8vd3d3Lm9jc2lnZW4ub3JnL2pzX29mX29jYW1sL1xuICogQ29weXJpZ2h0IChDKSAyMDEwIFJhcGhhw6tsIFByb3VzdFxuICogTGFib3JhdG9pcmUgUFBTIC0gQ05SUyBVbml2ZXJzaXTDqSBQYXJpcyBEaWRlcm90XG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgd2l0aCBsaW5raW5nIGV4Y2VwdGlvbjtcbiAqIGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4gKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLlxuICopXG5cbm9wZW4hIEltcG9ydFxuXG5tb2R1bGUgQ29sb3IgPSBzdHJ1Y3RcbiAgKCogVGhlIHR5cGUgb2YgQ1NTIGNvbG9ycy4gRmlyc3QgYnkgbmFtZSBhbmQgdGhlbiBieSBjb25zdHJ1Y3Rvci4gKilcbiAgdHlwZSBuYW1lID1cbiAgICB8IEFsaWNlYmx1ZVxuICAgIHwgQW50aXF1ZXdoaXRlXG4gICAgfCBBcXVhXG4gICAgfCBBcXVhbWFyaW5lXG4gICAgfCBBenVyZVxuICAgIHwgQmVpZ2VcbiAgICB8IEJpc3F1ZVxuICAgIHwgQmxhY2tcbiAgICB8IEJsYW5jaGVkYWxtb25kXG4gICAgfCBCbHVlXG4gICAgfCBCbHVldmlvbGV0XG4gICAgfCBCcm93blxuICAgIHwgQnVybHl3b29kXG4gICAgfCBDYWRldGJsdWVcbiAgICB8IENoYXJ0cmV1c2VcbiAgICB8IENob2NvbGF0ZVxuICAgIHwgQ29yYWxcbiAgICB8IENvcm5mbG93ZXJibHVlXG4gICAgfCBDb3Juc2lsa1xuICAgIHwgQ3JpbXNvblxuICAgIHwgQ3lhblxuICAgIHwgRGFya2JsdWVcbiAgICB8IERhcmtjeWFuXG4gICAgfCBEYXJrZ29sZGVucm9kXG4gICAgfCBEYXJrZ3JheVxuICAgIHwgRGFya2dyZWVuXG4gICAgfCBEYXJrZ3JleVxuICAgIHwgRGFya2toYWtpXG4gICAgfCBEYXJrbWFnZW50YVxuICAgIHwgRGFya29saXZlZ3JlZW5cbiAgICB8IERhcmtvcmFuZ2VcbiAgICB8IERhcmtvcmNoaWRcbiAgICB8IERhcmtyZWRcbiAgICB8IERhcmtzYWxtb25cbiAgICB8IERhcmtzZWFncmVlblxuICAgIHwgRGFya3NsYXRlYmx1ZVxuICAgIHwgRGFya3NsYXRlZ3JheVxuICAgIHwgRGFya3NsYXRlZ3JleVxuICAgIHwgRGFya3R1cnF1b2lzZVxuICAgIHwgRGFya3Zpb2xldFxuICAgIHwgRGVlcHBpbmtcbiAgICB8IERlZXBza3libHVlXG4gICAgfCBEaW1ncmF5XG4gICAgfCBEaW1ncmV5XG4gICAgfCBEb2RnZXJibHVlXG4gICAgfCBGaXJlYnJpY2tcbiAgICB8IEZsb3JhbHdoaXRlXG4gICAgfCBGb3Jlc3RncmVlblxuICAgIHwgRnVjaHNpYVxuICAgIHwgR2FpbnNib3JvXG4gICAgfCBHaG9zdHdoaXRlXG4gICAgfCBHb2xkXG4gICAgfCBHb2xkZW5yb2RcbiAgICB8IEdyYXlcbiAgICB8IEdyZXlcbiAgICB8IEdyZWVuXG4gICAgfCBHcmVlbnllbGxvd1xuICAgIHwgSG9uZXlkZXdcbiAgICB8IEhvdHBpbmtcbiAgICB8IEluZGlhbnJlZFxuICAgIHwgSW5kaWdvXG4gICAgfCBJdm9yeVxuICAgIHwgS2hha2lcbiAgICB8IExhdmVuZGVyXG4gICAgfCBMYXZlbmRlcmJsdXNoXG4gICAgfCBMYXduZ3JlZW5cbiAgICB8IExlbW9uY2hpZmZvblxuICAgIHwgTGlnaHRibHVlXG4gICAgfCBMaWdodGNvcmFsXG4gICAgfCBMaWdodGN5YW5cbiAgICB8IExpZ2h0Z29sZGVucm9keWVsbG93XG4gICAgfCBMaWdodGdyYXlcbiAgICB8IExpZ2h0Z3JlZW5cbiAgICB8IExpZ2h0Z3JleVxuICAgIHwgTGlnaHRwaW5rXG4gICAgfCBMaWdodHNhbG1vblxuICAgIHwgTGlnaHRzZWFncmVlblxuICAgIHwgTGlnaHRza3libHVlXG4gICAgfCBMaWdodHNsYXRlZ3JheVxuICAgIHwgTGlnaHRzbGF0ZWdyZXlcbiAgICB8IExpZ2h0c3RlZWxibHVlXG4gICAgfCBMaWdodHllbGxvd1xuICAgIHwgTGltZVxuICAgIHwgTGltZWdyZWVuXG4gICAgfCBMaW5lblxuICAgIHwgTWFnZW50YVxuICAgIHwgTWFyb29uXG4gICAgfCBNZWRpdW1hcXVhbWFyaW5lXG4gICAgfCBNZWRpdW1ibHVlXG4gICAgfCBNZWRpdW1vcmNoaWRcbiAgICB8IE1lZGl1bXB1cnBsZVxuICAgIHwgTWVkaXVtc2VhZ3JlZW5cbiAgICB8IE1lZGl1bXNsYXRlYmx1ZVxuICAgIHwgTWVkaXVtc3ByaW5nZ3JlZW5cbiAgICB8IE1lZGl1bXR1cnF1b2lzZVxuICAgIHwgTWVkaXVtdmlvbGV0cmVkXG4gICAgfCBNaWRuaWdodGJsdWVcbiAgICB8IE1pbnRjcmVhbVxuICAgIHwgTWlzdHlyb3NlXG4gICAgfCBNb2NjYXNpblxuICAgIHwgTmF2YWpvd2hpdGVcbiAgICB8IE5hdnlcbiAgICB8IE9sZGxhY2VcbiAgICB8IE9saXZlXG4gICAgfCBPbGl2ZWRyYWJcbiAgICB8IE9yYW5nZVxuICAgIHwgT3JhbmdlcmVkXG4gICAgfCBPcmNoaWRcbiAgICB8IFBhbGVnb2xkZW5yb2RcbiAgICB8IFBhbGVncmVlblxuICAgIHwgUGFsZXR1cnF1b2lzZVxuICAgIHwgUGFsZXZpb2xldHJlZFxuICAgIHwgUGFwYXlhd2hpcFxuICAgIHwgUGVhY2hwdWZmXG4gICAgfCBQZXJ1XG4gICAgfCBQaW5rXG4gICAgfCBQbHVtXG4gICAgfCBQb3dkZXJibHVlXG4gICAgfCBQdXJwbGVcbiAgICB8IFJlZFxuICAgIHwgUm9zeWJyb3duXG4gICAgfCBSb3lhbGJsdWVcbiAgICB8IFNhZGRsZWJyb3duXG4gICAgfCBTYWxtb25cbiAgICB8IFNhbmR5YnJvd25cbiAgICB8IFNlYWdyZWVuXG4gICAgfCBTZWFzaGVsbFxuICAgIHwgU2llbm5hXG4gICAgfCBTaWx2ZXJcbiAgICB8IFNreWJsdWVcbiAgICB8IFNsYXRlYmx1ZVxuICAgIHwgU2xhdGVncmF5XG4gICAgfCBTbGF0ZWdyZXlcbiAgICB8IFNub3dcbiAgICB8IFNwcmluZ2dyZWVuXG4gICAgfCBTdGVlbGJsdWVcbiAgICB8IFRhblxuICAgIHwgVGVhbFxuICAgIHwgVGhpc3RsZVxuICAgIHwgVG9tYXRvXG4gICAgfCBUdXJxdW9pc2VcbiAgICB8IFZpb2xldFxuICAgIHwgV2hlYXRcbiAgICB8IFdoaXRlXG4gICAgfCBXaGl0ZXNtb2tlXG4gICAgfCBZZWxsb3dcbiAgICB8IFllbGxvd2dyZWVuXG5cbiAgbGV0IHN0cmluZ19vZl9uYW1lID0gZnVuY3Rpb25cbiAgICB8IEFsaWNlYmx1ZSAtPiBcImFsaWNlYmx1ZVwiXG4gICAgfCBBbnRpcXVld2hpdGUgLT4gXCJhbnRpcXVld2hpdGVcIlxuICAgIHwgQXF1YSAtPiBcImFxdWFcIlxuICAgIHwgQXF1YW1hcmluZSAtPiBcImFxdWFtYXJpbmVcIlxuICAgIHwgQXp1cmUgLT4gXCJhenVyZVwiXG4gICAgfCBCZWlnZSAtPiBcImJlaWdlXCJcbiAgICB8IEJpc3F1ZSAtPiBcImJpc3F1ZVwiXG4gICAgfCBCbGFjayAtPiBcImJsYWNrXCJcbiAgICB8IEJsYW5jaGVkYWxtb25kIC0+IFwiYmxhbmNoZWRhbG1vbmRcIlxuICAgIHwgQmx1ZSAtPiBcImJsdWVcIlxuICAgIHwgQmx1ZXZpb2xldCAtPiBcImJsdWV2aW9sZXRcIlxuICAgIHwgQnJvd24gLT4gXCJicm93blwiXG4gICAgfCBCdXJseXdvb2QgLT4gXCJidXJseXdvb2RcIlxuICAgIHwgQ2FkZXRibHVlIC0+IFwiY2FkZXRibHVlXCJcbiAgICB8IENoYXJ0cmV1c2UgLT4gXCJjaGFydHJldXNlXCJcbiAgICB8IENob2NvbGF0ZSAtPiBcImNob2NvbGF0ZVwiXG4gICAgfCBDb3JhbCAtPiBcImNvcmFsXCJcbiAgICB8IENvcm5mbG93ZXJibHVlIC0+IFwiY29ybmZsb3dlcmJsdWVcIlxuICAgIHwgQ29ybnNpbGsgLT4gXCJjb3Juc2lsa1wiXG4gICAgfCBDcmltc29uIC0+IFwiY3JpbXNvblwiXG4gICAgfCBDeWFuIC0+IFwiY3lhblwiXG4gICAgfCBEYXJrYmx1ZSAtPiBcImRhcmtibHVlXCJcbiAgICB8IERhcmtjeWFuIC0+IFwiZGFya2N5YW5cIlxuICAgIHwgRGFya2dvbGRlbnJvZCAtPiBcImRhcmtnb2xkZW5yb2RcIlxuICAgIHwgRGFya2dyYXkgLT4gXCJkYXJrZ3JheVwiXG4gICAgfCBEYXJrZ3JlZW4gLT4gXCJkYXJrZ3JlZW5cIlxuICAgIHwgRGFya2dyZXkgLT4gXCJkYXJrZ3JleVwiXG4gICAgfCBEYXJra2hha2kgLT4gXCJkYXJra2hha2lcIlxuICAgIHwgRGFya21hZ2VudGEgLT4gXCJkYXJrbWFnZW50YVwiXG4gICAgfCBEYXJrb2xpdmVncmVlbiAtPiBcImRhcmtvbGl2ZWdyZWVuXCJcbiAgICB8IERhcmtvcmFuZ2UgLT4gXCJkYXJrb3JhbmdlXCJcbiAgICB8IERhcmtvcmNoaWQgLT4gXCJkYXJrb3JjaGlkXCJcbiAgICB8IERhcmtyZWQgLT4gXCJkYXJrcmVkXCJcbiAgICB8IERhcmtzYWxtb24gLT4gXCJkYXJrc2FsbW9uXCJcbiAgICB8IERhcmtzZWFncmVlbiAtPiBcImRhcmtzZWFncmVlblwiXG4gICAgfCBEYXJrc2xhdGVibHVlIC0+IFwiZGFya3NsYXRlYmx1ZVwiXG4gICAgfCBEYXJrc2xhdGVncmF5IC0+IFwiZGFya3NsYXRlZ3JheVwiXG4gICAgfCBEYXJrc2xhdGVncmV5IC0+IFwiZGFya3NsYXRlZ3JleVwiXG4gICAgfCBEYXJrdHVycXVvaXNlIC0+IFwiZGFya3R1cnF1b2lzZVwiXG4gICAgfCBEYXJrdmlvbGV0IC0+IFwiZGFya3Zpb2xldFwiXG4gICAgfCBEZWVwcGluayAtPiBcImRlZXBwaW5rXCJcbiAgICB8IERlZXBza3libHVlIC0+IFwiZGVlcHNreWJsdWVcIlxuICAgIHwgRGltZ3JheSAtPiBcImRpbWdyYXlcIlxuICAgIHwgRGltZ3JleSAtPiBcImRpbWdyZXlcIlxuICAgIHwgRG9kZ2VyYmx1ZSAtPiBcImRvZGdlcmJsdWVcIlxuICAgIHwgRmlyZWJyaWNrIC0+IFwiZmlyZWJyaWNrXCJcbiAgICB8IEZsb3JhbHdoaXRlIC0+IFwiZmxvcmFsd2hpdGVcIlxuICAgIHwgRm9yZXN0Z3JlZW4gLT4gXCJmb3Jlc3RncmVlblwiXG4gICAgfCBGdWNoc2lhIC0+IFwiZnVjaHNpYVwiXG4gICAgfCBHYWluc2Jvcm8gLT4gXCJnYWluc2Jvcm9cIlxuICAgIHwgR2hvc3R3aGl0ZSAtPiBcImdob3N0d2hpdGVcIlxuICAgIHwgR29sZCAtPiBcImdvbGRcIlxuICAgIHwgR29sZGVucm9kIC0+IFwiZ29sZGVucm9kXCJcbiAgICB8IEdyYXkgLT4gXCJncmF5XCJcbiAgICB8IEdyZWVuIC0+IFwiZ3JlZW5cIlxuICAgIHwgR3JlZW55ZWxsb3cgLT4gXCJncmVlbnllbGxvd1wiXG4gICAgfCBHcmV5IC0+IFwiZ3JleVwiXG4gICAgfCBIb25leWRldyAtPiBcImhvbmV5ZGV3XCJcbiAgICB8IEhvdHBpbmsgLT4gXCJob3RwaW5rXCJcbiAgICB8IEluZGlhbnJlZCAtPiBcImluZGlhbnJlZFwiXG4gICAgfCBJbmRpZ28gLT4gXCJpbmRpZ29cIlxuICAgIHwgSXZvcnkgLT4gXCJpdm9yeVwiXG4gICAgfCBLaGFraSAtPiBcImtoYWtpXCJcbiAgICB8IExhdmVuZGVyIC0+IFwibGF2ZW5kZXJcIlxuICAgIHwgTGF2ZW5kZXJibHVzaCAtPiBcImxhdmVuZGVyYmx1c2hcIlxuICAgIHwgTGF3bmdyZWVuIC0+IFwibGF3bmdyZWVuXCJcbiAgICB8IExlbW9uY2hpZmZvbiAtPiBcImxlbW9uY2hpZmZvblwiXG4gICAgfCBMaWdodGJsdWUgLT4gXCJsaWdodGJsdWVcIlxuICAgIHwgTGlnaHRjb3JhbCAtPiBcImxpZ2h0Y29yYWxcIlxuICAgIHwgTGlnaHRjeWFuIC0+IFwibGlnaHRjeWFuXCJcbiAgICB8IExpZ2h0Z29sZGVucm9keWVsbG93IC0+IFwibGlnaHRnb2xkZW5yb2R5ZWxsb3dcIlxuICAgIHwgTGlnaHRncmF5IC0+IFwibGlnaHRncmF5XCJcbiAgICB8IExpZ2h0Z3JlZW4gLT4gXCJsaWdodGdyZWVuXCJcbiAgICB8IExpZ2h0Z3JleSAtPiBcImxpZ2h0Z3JleVwiXG4gICAgfCBMaWdodHBpbmsgLT4gXCJsaWdodHBpbmtcIlxuICAgIHwgTGlnaHRzYWxtb24gLT4gXCJsaWdodHNhbG1vblwiXG4gICAgfCBMaWdodHNlYWdyZWVuIC0+IFwibGlnaHRzZWFncmVlblwiXG4gICAgfCBMaWdodHNreWJsdWUgLT4gXCJsaWdodHNreWJsdWVcIlxuICAgIHwgTGlnaHRzbGF0ZWdyYXkgLT4gXCJsaWdodHNsYXRlZ3JheVwiXG4gICAgfCBMaWdodHNsYXRlZ3JleSAtPiBcImxpZ2h0c2xhdGVncmV5XCJcbiAgICB8IExpZ2h0c3RlZWxibHVlIC0+IFwibGlnaHRzdGVlbGJsdWVcIlxuICAgIHwgTGlnaHR5ZWxsb3cgLT4gXCJsaWdodHllbGxvd1wiXG4gICAgfCBMaW1lIC0+IFwibGltZVwiXG4gICAgfCBMaW1lZ3JlZW4gLT4gXCJsaW1lZ3JlZW5cIlxuICAgIHwgTGluZW4gLT4gXCJsaW5lblwiXG4gICAgfCBNYWdlbnRhIC0+IFwibWFnZW50YVwiXG4gICAgfCBNYXJvb24gLT4gXCJtYXJvb25cIlxuICAgIHwgTWVkaXVtYXF1YW1hcmluZSAtPiBcIm1lZGl1bWFxdWFtYXJpbmVcIlxuICAgIHwgTWVkaXVtYmx1ZSAtPiBcIm1lZGl1bWJsdWVcIlxuICAgIHwgTWVkaXVtb3JjaGlkIC0+IFwibWVkaXVtb3JjaGlkXCJcbiAgICB8IE1lZGl1bXB1cnBsZSAtPiBcIm1lZGl1bXB1cnBsZVwiXG4gICAgfCBNZWRpdW1zZWFncmVlbiAtPiBcIm1lZGl1bXNlYWdyZWVuXCJcbiAgICB8IE1lZGl1bXNsYXRlYmx1ZSAtPiBcIm1lZGl1bXNsYXRlYmx1ZVwiXG4gICAgfCBNZWRpdW1zcHJpbmdncmVlbiAtPiBcIm1lZGl1bXNwcmluZ2dyZWVuXCJcbiAgICB8IE1lZGl1bXR1cnF1b2lzZSAtPiBcIm1lZGl1bXR1cnF1b2lzZVwiXG4gICAgfCBNZWRpdW12aW9sZXRyZWQgLT4gXCJtZWRpdW12aW9sZXRyZWRcIlxuICAgIHwgTWlkbmlnaHRibHVlIC0+IFwibWlkbmlnaHRibHVlXCJcbiAgICB8IE1pbnRjcmVhbSAtPiBcIm1pbnRjcmVhbVwiXG4gICAgfCBNaXN0eXJvc2UgLT4gXCJtaXN0eXJvc2VcIlxuICAgIHwgTW9jY2FzaW4gLT4gXCJtb2NjYXNpblwiXG4gICAgfCBOYXZham93aGl0ZSAtPiBcIm5hdmFqb3doaXRlXCJcbiAgICB8IE5hdnkgLT4gXCJuYXZ5XCJcbiAgICB8IE9sZGxhY2UgLT4gXCJvbGRsYWNlXCJcbiAgICB8IE9saXZlIC0+IFwib2xpdmVcIlxuICAgIHwgT2xpdmVkcmFiIC0+IFwib2xpdmVkcmFiXCJcbiAgICB8IE9yYW5nZSAtPiBcIm9yYW5nZVwiXG4gICAgfCBPcmFuZ2VyZWQgLT4gXCJvcmFuZ2VyZWRcIlxuICAgIHwgT3JjaGlkIC0+IFwib3JjaGlkXCJcbiAgICB8IFBhbGVnb2xkZW5yb2QgLT4gXCJwYWxlZ29sZGVucm9kXCJcbiAgICB8IFBhbGVncmVlbiAtPiBcInBhbGVncmVlblwiXG4gICAgfCBQYWxldHVycXVvaXNlIC0+IFwicGFsZXR1cnF1b2lzZVwiXG4gICAgfCBQYWxldmlvbGV0cmVkIC0+IFwicGFsZXZpb2xldHJlZFwiXG4gICAgfCBQYXBheWF3aGlwIC0+IFwicGFwYXlhd2hpcFwiXG4gICAgfCBQZWFjaHB1ZmYgLT4gXCJwZWFjaHB1ZmZcIlxuICAgIHwgUGVydSAtPiBcInBlcnVcIlxuICAgIHwgUGluayAtPiBcInBpbmtcIlxuICAgIHwgUGx1bSAtPiBcInBsdW1cIlxuICAgIHwgUG93ZGVyYmx1ZSAtPiBcInBvd2RlcmJsdWVcIlxuICAgIHwgUHVycGxlIC0+IFwicHVycGxlXCJcbiAgICB8IFJlZCAtPiBcInJlZFwiXG4gICAgfCBSb3N5YnJvd24gLT4gXCJyb3N5YnJvd25cIlxuICAgIHwgUm95YWxibHVlIC0+IFwicm95YWxibHVlXCJcbiAgICB8IFNhZGRsZWJyb3duIC0+IFwic2FkZGxlYnJvd25cIlxuICAgIHwgU2FsbW9uIC0+IFwic2FsbW9uXCJcbiAgICB8IFNhbmR5YnJvd24gLT4gXCJzYW5keWJyb3duXCJcbiAgICB8IFNlYWdyZWVuIC0+IFwic2VhZ3JlZW5cIlxuICAgIHwgU2Vhc2hlbGwgLT4gXCJzZWFzaGVsbFwiXG4gICAgfCBTaWVubmEgLT4gXCJzaWVubmFcIlxuICAgIHwgU2lsdmVyIC0+IFwic2lsdmVyXCJcbiAgICB8IFNreWJsdWUgLT4gXCJza3libHVlXCJcbiAgICB8IFNsYXRlYmx1ZSAtPiBcInNsYXRlYmx1ZVwiXG4gICAgfCBTbGF0ZWdyYXkgLT4gXCJzbGF0ZWdyYXlcIlxuICAgIHwgU2xhdGVncmV5IC0+IFwic2xhdGVncmV5XCJcbiAgICB8IFNub3cgLT4gXCJzbm93XCJcbiAgICB8IFNwcmluZ2dyZWVuIC0+IFwic3ByaW5nZ3JlZW5cIlxuICAgIHwgU3RlZWxibHVlIC0+IFwic3RlZWxibHVlXCJcbiAgICB8IFRhbiAtPiBcInRhblwiXG4gICAgfCBUZWFsIC0+IFwidGVhbFwiXG4gICAgfCBUaGlzdGxlIC0+IFwidGhpc3RsZVwiXG4gICAgfCBUb21hdG8gLT4gXCJ0b21hdG9cIlxuICAgIHwgVHVycXVvaXNlIC0+IFwidHVycXVvaXNlXCJcbiAgICB8IFZpb2xldCAtPiBcInZpb2xldFwiXG4gICAgfCBXaGVhdCAtPiBcIndoZWF0XCJcbiAgICB8IFdoaXRlIC0+IFwid2hpdGVcIlxuICAgIHwgV2hpdGVzbW9rZSAtPiBcIndoaXRlc21va2VcIlxuICAgIHwgWWVsbG93IC0+IFwieWVsbG93XCJcbiAgICB8IFllbGxvd2dyZWVuIC0+IFwieWVsbG93Z3JlZW5cIlxuXG4gIGxldCBuYW1lX29mX3N0cmluZyA9IGZ1bmN0aW9uXG4gICAgfCBcImFsaWNlYmx1ZVwiIC0+IEFsaWNlYmx1ZVxuICAgIHwgXCJhbnRpcXVld2hpdGVcIiAtPiBBbnRpcXVld2hpdGVcbiAgICB8IFwiYXF1YVwiIC0+IEFxdWFcbiAgICB8IFwiYXF1YW1hcmluZVwiIC0+IEFxdWFtYXJpbmVcbiAgICB8IFwiYXp1cmVcIiAtPiBBenVyZVxuICAgIHwgXCJiZWlnZVwiIC0+IEJlaWdlXG4gICAgfCBcImJpc3F1ZVwiIC0+IEJpc3F1ZVxuICAgIHwgXCJibGFja1wiIC0+IEJsYWNrXG4gICAgfCBcImJsYW5jaGVkYWxtb25kXCIgLT4gQmxhbmNoZWRhbG1vbmRcbiAgICB8IFwiYmx1ZVwiIC0+IEJsdWVcbiAgICB8IFwiYmx1ZXZpb2xldFwiIC0+IEJsdWV2aW9sZXRcbiAgICB8IFwiYnJvd25cIiAtPiBCcm93blxuICAgIHwgXCJidXJseXdvb2RcIiAtPiBCdXJseXdvb2RcbiAgICB8IFwiY2FkZXRibHVlXCIgLT4gQ2FkZXRibHVlXG4gICAgfCBcImNoYXJ0cmV1c2VcIiAtPiBDaGFydHJldXNlXG4gICAgfCBcImNob2NvbGF0ZVwiIC0+IENob2NvbGF0ZVxuICAgIHwgXCJjb3JhbFwiIC0+IENvcmFsXG4gICAgfCBcImNvcm5mbG93ZXJibHVlXCIgLT4gQ29ybmZsb3dlcmJsdWVcbiAgICB8IFwiY29ybnNpbGtcIiAtPiBDb3Juc2lsa1xuICAgIHwgXCJjcmltc29uXCIgLT4gQ3JpbXNvblxuICAgIHwgXCJjeWFuXCIgLT4gQ3lhblxuICAgIHwgXCJkYXJrYmx1ZVwiIC0+IERhcmtibHVlXG4gICAgfCBcImRhcmtjeWFuXCIgLT4gRGFya2N5YW5cbiAgICB8IFwiZGFya2dvbGRlbnJvZFwiIC0+IERhcmtnb2xkZW5yb2RcbiAgICB8IFwiZGFya2dyYXlcIiAtPiBEYXJrZ3JheVxuICAgIHwgXCJkYXJrZ3JlZW5cIiAtPiBEYXJrZ3JlZW5cbiAgICB8IFwiZGFya2dyZXlcIiAtPiBEYXJrZ3JleVxuICAgIHwgXCJkYXJra2hha2lcIiAtPiBEYXJra2hha2lcbiAgICB8IFwiZGFya21hZ2VudGFcIiAtPiBEYXJrbWFnZW50YVxuICAgIHwgXCJkYXJrb2xpdmVncmVlblwiIC0+IERhcmtvbGl2ZWdyZWVuXG4gICAgfCBcImRhcmtvcmFuZ2VcIiAtPiBEYXJrb3JhbmdlXG4gICAgfCBcImRhcmtvcmNoaWRcIiAtPiBEYXJrb3JjaGlkXG4gICAgfCBcImRhcmtyZWRcIiAtPiBEYXJrcmVkXG4gICAgfCBcImRhcmtzYWxtb25cIiAtPiBEYXJrc2FsbW9uXG4gICAgfCBcImRhcmtzZWFncmVlblwiIC0+IERhcmtzZWFncmVlblxuICAgIHwgXCJkYXJrc2xhdGVibHVlXCIgLT4gRGFya3NsYXRlYmx1ZVxuICAgIHwgXCJkYXJrc2xhdGVncmF5XCIgLT4gRGFya3NsYXRlZ3JheVxuICAgIHwgXCJkYXJrc2xhdGVncmV5XCIgLT4gRGFya3NsYXRlZ3JleVxuICAgIHwgXCJkYXJrdHVycXVvaXNlXCIgLT4gRGFya3R1cnF1b2lzZVxuICAgIHwgXCJkYXJrdmlvbGV0XCIgLT4gRGFya3Zpb2xldFxuICAgIHwgXCJkZWVwcGlua1wiIC0+IERlZXBwaW5rXG4gICAgfCBcImRlZXBza3libHVlXCIgLT4gRGVlcHNreWJsdWVcbiAgICB8IFwiZGltZ3JheVwiIC0+IERpbWdyYXlcbiAgICB8IFwiZGltZ3JleVwiIC0+IERpbWdyZXlcbiAgICB8IFwiZG9kZ2VyYmx1ZVwiIC0+IERvZGdlcmJsdWVcbiAgICB8IFwiZmlyZWJyaWNrXCIgLT4gRmlyZWJyaWNrXG4gICAgfCBcImZsb3JhbHdoaXRlXCIgLT4gRmxvcmFsd2hpdGVcbiAgICB8IFwiZm9yZXN0Z3JlZW5cIiAtPiBGb3Jlc3RncmVlblxuICAgIHwgXCJmdWNoc2lhXCIgLT4gRnVjaHNpYVxuICAgIHwgXCJnYWluc2Jvcm9cIiAtPiBHYWluc2Jvcm9cbiAgICB8IFwiZ2hvc3R3aGl0ZVwiIC0+IEdob3N0d2hpdGVcbiAgICB8IFwiZ29sZFwiIC0+IEdvbGRcbiAgICB8IFwiZ29sZGVucm9kXCIgLT4gR29sZGVucm9kXG4gICAgfCBcImdyYXlcIiAtPiBHcmF5XG4gICAgfCBcImdyZWVuXCIgLT4gR3JlZW5cbiAgICB8IFwiZ3JlZW55ZWxsb3dcIiAtPiBHcmVlbnllbGxvd1xuICAgIHwgXCJncmV5XCIgLT4gR3JleVxuICAgIHwgXCJob25leWRld1wiIC0+IEhvbmV5ZGV3XG4gICAgfCBcImhvdHBpbmtcIiAtPiBIb3RwaW5rXG4gICAgfCBcImluZGlhbnJlZFwiIC0+IEluZGlhbnJlZFxuICAgIHwgXCJpbmRpZ29cIiAtPiBJbmRpZ29cbiAgICB8IFwiaXZvcnlcIiAtPiBJdm9yeVxuICAgIHwgXCJraGFraVwiIC0+IEtoYWtpXG4gICAgfCBcImxhdmVuZGVyXCIgLT4gTGF2ZW5kZXJcbiAgICB8IFwibGF2ZW5kZXJibHVzaFwiIC0+IExhdmVuZGVyYmx1c2hcbiAgICB8IFwibGF3bmdyZWVuXCIgLT4gTGF3bmdyZWVuXG4gICAgfCBcImxlbW9uY2hpZmZvblwiIC0+IExlbW9uY2hpZmZvblxuICAgIHwgXCJsaWdodGJsdWVcIiAtPiBMaWdodGJsdWVcbiAgICB8IFwibGlnaHRjb3JhbFwiIC0+IExpZ2h0Y29yYWxcbiAgICB8IFwibGlnaHRjeWFuXCIgLT4gTGlnaHRjeWFuXG4gICAgfCBcImxpZ2h0Z29sZGVucm9keWVsbG93XCIgLT4gTGlnaHRnb2xkZW5yb2R5ZWxsb3dcbiAgICB8IFwibGlnaHRncmF5XCIgLT4gTGlnaHRncmF5XG4gICAgfCBcImxpZ2h0Z3JlZW5cIiAtPiBMaWdodGdyZWVuXG4gICAgfCBcImxpZ2h0Z3JleVwiIC0+IExpZ2h0Z3JleVxuICAgIHwgXCJsaWdodHBpbmtcIiAtPiBMaWdodHBpbmtcbiAgICB8IFwibGlnaHRzYWxtb25cIiAtPiBMaWdodHNhbG1vblxuICAgIHwgXCJsaWdodHNlYWdyZWVuXCIgLT4gTGlnaHRzZWFncmVlblxuICAgIHwgXCJsaWdodHNreWJsdWVcIiAtPiBMaWdodHNreWJsdWVcbiAgICB8IFwibGlnaHRzbGF0ZWdyYXlcIiAtPiBMaWdodHNsYXRlZ3JheVxuICAgIHwgXCJsaWdodHNsYXRlZ3JleVwiIC0+IExpZ2h0c2xhdGVncmV5XG4gICAgfCBcImxpZ2h0c3RlZWxibHVlXCIgLT4gTGlnaHRzdGVlbGJsdWVcbiAgICB8IFwibGlnaHR5ZWxsb3dcIiAtPiBMaWdodHllbGxvd1xuICAgIHwgXCJsaW1lXCIgLT4gTGltZVxuICAgIHwgXCJsaW1lZ3JlZW5cIiAtPiBMaW1lZ3JlZW5cbiAgICB8IFwibGluZW5cIiAtPiBMaW5lblxuICAgIHwgXCJtYWdlbnRhXCIgLT4gTWFnZW50YVxuICAgIHwgXCJtYXJvb25cIiAtPiBNYXJvb25cbiAgICB8IFwibWVkaXVtYXF1YW1hcmluZVwiIC0+IE1lZGl1bWFxdWFtYXJpbmVcbiAgICB8IFwibWVkaXVtYmx1ZVwiIC0+IE1lZGl1bWJsdWVcbiAgICB8IFwibWVkaXVtb3JjaGlkXCIgLT4gTWVkaXVtb3JjaGlkXG4gICAgfCBcIm1lZGl1bXB1cnBsZVwiIC0+IE1lZGl1bXB1cnBsZVxuICAgIHwgXCJtZWRpdW1zZWFncmVlblwiIC0+IE1lZGl1bXNlYWdyZWVuXG4gICAgfCBcIm1lZGl1bXNsYXRlYmx1ZVwiIC0+IE1lZGl1bXNsYXRlYmx1ZVxuICAgIHwgXCJtZWRpdW1zcHJpbmdncmVlblwiIC0+IE1lZGl1bXNwcmluZ2dyZWVuXG4gICAgfCBcIm1lZGl1bXR1cnF1b2lzZVwiIC0+IE1lZGl1bXR1cnF1b2lzZVxuICAgIHwgXCJtZWRpdW12aW9sZXRyZWRcIiAtPiBNZWRpdW12aW9sZXRyZWRcbiAgICB8IFwibWlkbmlnaHRibHVlXCIgLT4gTWlkbmlnaHRibHVlXG4gICAgfCBcIm1pbnRjcmVhbVwiIC0+IE1pbnRjcmVhbVxuICAgIHwgXCJtaXN0eXJvc2VcIiAtPiBNaXN0eXJvc2VcbiAgICB8IFwibW9jY2FzaW5cIiAtPiBNb2NjYXNpblxuICAgIHwgXCJuYXZham93aGl0ZVwiIC0+IE5hdmFqb3doaXRlXG4gICAgfCBcIm5hdnlcIiAtPiBOYXZ5XG4gICAgfCBcIm9sZGxhY2VcIiAtPiBPbGRsYWNlXG4gICAgfCBcIm9saXZlXCIgLT4gT2xpdmVcbiAgICB8IFwib2xpdmVkcmFiXCIgLT4gT2xpdmVkcmFiXG4gICAgfCBcIm9yYW5nZVwiIC0+IE9yYW5nZVxuICAgIHwgXCJvcmFuZ2VyZWRcIiAtPiBPcmFuZ2VyZWRcbiAgICB8IFwib3JjaGlkXCIgLT4gT3JjaGlkXG4gICAgfCBcInBhbGVnb2xkZW5yb2RcIiAtPiBQYWxlZ29sZGVucm9kXG4gICAgfCBcInBhbGVncmVlblwiIC0+IFBhbGVncmVlblxuICAgIHwgXCJwYWxldHVycXVvaXNlXCIgLT4gUGFsZXR1cnF1b2lzZVxuICAgIHwgXCJwYWxldmlvbGV0cmVkXCIgLT4gUGFsZXZpb2xldHJlZFxuICAgIHwgXCJwYXBheWF3aGlwXCIgLT4gUGFwYXlhd2hpcFxuICAgIHwgXCJwZWFjaHB1ZmZcIiAtPiBQZWFjaHB1ZmZcbiAgICB8IFwicGVydVwiIC0+IFBlcnVcbiAgICB8IFwicGlua1wiIC0+IFBpbmtcbiAgICB8IFwicGx1bVwiIC0+IFBsdW1cbiAgICB8IFwicG93ZGVyYmx1ZVwiIC0+IFBvd2RlcmJsdWVcbiAgICB8IFwicHVycGxlXCIgLT4gUHVycGxlXG4gICAgfCBcInJlZFwiIC0+IFJlZFxuICAgIHwgXCJyb3N5YnJvd25cIiAtPiBSb3N5YnJvd25cbiAgICB8IFwicm95YWxibHVlXCIgLT4gUm95YWxibHVlXG4gICAgfCBcInNhZGRsZWJyb3duXCIgLT4gU2FkZGxlYnJvd25cbiAgICB8IFwic2FsbW9uXCIgLT4gU2FsbW9uXG4gICAgfCBcInNhbmR5YnJvd25cIiAtPiBTYW5keWJyb3duXG4gICAgfCBcInNlYWdyZWVuXCIgLT4gU2VhZ3JlZW5cbiAgICB8IFwic2Vhc2hlbGxcIiAtPiBTZWFzaGVsbFxuICAgIHwgXCJzaWVubmFcIiAtPiBTaWVubmFcbiAgICB8IFwic2lsdmVyXCIgLT4gU2lsdmVyXG4gICAgfCBcInNreWJsdWVcIiAtPiBTa3libHVlXG4gICAgfCBcInNsYXRlYmx1ZVwiIC0+IFNsYXRlYmx1ZVxuICAgIHwgXCJzbGF0ZWdyYXlcIiAtPiBTbGF0ZWdyYXlcbiAgICB8IFwic2xhdGVncmV5XCIgLT4gU2xhdGVncmV5XG4gICAgfCBcInNub3dcIiAtPiBTbm93XG4gICAgfCBcInNwcmluZ2dyZWVuXCIgLT4gU3ByaW5nZ3JlZW5cbiAgICB8IFwic3RlZWxibHVlXCIgLT4gU3RlZWxibHVlXG4gICAgfCBcInRhblwiIC0+IFRhblxuICAgIHwgXCJ0ZWFsXCIgLT4gVGVhbFxuICAgIHwgXCJ0aGlzdGxlXCIgLT4gVGhpc3RsZVxuICAgIHwgXCJ0b21hdG9cIiAtPiBUb21hdG9cbiAgICB8IFwidHVycXVvaXNlXCIgLT4gVHVycXVvaXNlXG4gICAgfCBcInZpb2xldFwiIC0+IFZpb2xldFxuICAgIHwgXCJ3aGVhdFwiIC0+IFdoZWF0XG4gICAgfCBcIndoaXRlXCIgLT4gV2hpdGVcbiAgICB8IFwid2hpdGVzbW9rZVwiIC0+IFdoaXRlc21va2VcbiAgICB8IFwieWVsbG93XCIgLT4gWWVsbG93XG4gICAgfCBcInllbGxvd2dyZWVuXCIgLT4gWWVsbG93Z3JlZW5cbiAgICB8IHMgLT4gcmFpc2UgKEludmFsaWRfYXJndW1lbnQgKHMgXiBcIiBpcyBub3QgYSB2YWxpZCBjb2xvciBuYW1lXCIpKVxuXG4gIGxldCByZ2Jfb2ZfbmFtZSA9IGZ1bmN0aW9uXG4gICAgfCBBbGljZWJsdWUgLT4gMjQwLCAyNDgsIDI1NVxuICAgIHwgQW50aXF1ZXdoaXRlIC0+IDI1MCwgMjM1LCAyMTVcbiAgICB8IEFxdWEgLT4gMCwgMjU1LCAyNTVcbiAgICB8IEFxdWFtYXJpbmUgLT4gMTI3LCAyNTUsIDIxMlxuICAgIHwgQXp1cmUgLT4gMjQwLCAyNTUsIDI1NVxuICAgIHwgQmVpZ2UgLT4gMjQ1LCAyNDUsIDIyMFxuICAgIHwgQmlzcXVlIC0+IDI1NSwgMjI4LCAxOTZcbiAgICB8IEJsYWNrIC0+IDAsIDAsIDBcbiAgICB8IEJsYW5jaGVkYWxtb25kIC0+IDI1NSwgMjM1LCAyMDVcbiAgICB8IEJsdWUgLT4gMCwgMCwgMjU1XG4gICAgfCBCbHVldmlvbGV0IC0+IDEzOCwgNDMsIDIyNlxuICAgIHwgQnJvd24gLT4gMTY1LCA0MiwgNDJcbiAgICB8IEJ1cmx5d29vZCAtPiAyMjIsIDE4NCwgMTM1XG4gICAgfCBDYWRldGJsdWUgLT4gOTUsIDE1OCwgMTYwXG4gICAgfCBDaGFydHJldXNlIC0+IDEyNywgMjU1LCAwXG4gICAgfCBDaG9jb2xhdGUgLT4gMjEwLCAxMDUsIDMwXG4gICAgfCBDb3JhbCAtPiAyNTUsIDEyNywgODBcbiAgICB8IENvcm5mbG93ZXJibHVlIC0+IDEwMCwgMTQ5LCAyMzdcbiAgICB8IENvcm5zaWxrIC0+IDI1NSwgMjQ4LCAyMjBcbiAgICB8IENyaW1zb24gLT4gMjIwLCAyMCwgNjBcbiAgICB8IEN5YW4gLT4gMCwgMjU1LCAyNTVcbiAgICB8IERhcmtibHVlIC0+IDAsIDAsIDEzOVxuICAgIHwgRGFya2N5YW4gLT4gMCwgMTM5LCAxMzlcbiAgICB8IERhcmtnb2xkZW5yb2QgLT4gMTg0LCAxMzQsIDExXG4gICAgfCBEYXJrZ3JheSAtPiAxNjksIDE2OSwgMTY5XG4gICAgfCBEYXJrZ3JlZW4gLT4gMCwgMTAwLCAwXG4gICAgfCBEYXJrZ3JleSAtPiAxNjksIDE2OSwgMTY5XG4gICAgfCBEYXJra2hha2kgLT4gMTg5LCAxODMsIDEwN1xuICAgIHwgRGFya21hZ2VudGEgLT4gMTM5LCAwLCAxMzlcbiAgICB8IERhcmtvbGl2ZWdyZWVuIC0+IDg1LCAxMDcsIDQ3XG4gICAgfCBEYXJrb3JhbmdlIC0+IDI1NSwgMTQwLCAwXG4gICAgfCBEYXJrb3JjaGlkIC0+IDE1MywgNTAsIDIwNFxuICAgIHwgRGFya3JlZCAtPiAxMzksIDAsIDBcbiAgICB8IERhcmtzYWxtb24gLT4gMjMzLCAxNTAsIDEyMlxuICAgIHwgRGFya3NlYWdyZWVuIC0+IDE0MywgMTg4LCAxNDNcbiAgICB8IERhcmtzbGF0ZWJsdWUgLT4gNzIsIDYxLCAxMzlcbiAgICB8IERhcmtzbGF0ZWdyYXkgLT4gNDcsIDc5LCA3OVxuICAgIHwgRGFya3NsYXRlZ3JleSAtPiA0NywgNzksIDc5XG4gICAgfCBEYXJrdHVycXVvaXNlIC0+IDAsIDIwNiwgMjA5XG4gICAgfCBEYXJrdmlvbGV0IC0+IDE0OCwgMCwgMjExXG4gICAgfCBEZWVwcGluayAtPiAyNTUsIDIwLCAxNDdcbiAgICB8IERlZXBza3libHVlIC0+IDAsIDE5MSwgMjU1XG4gICAgfCBEaW1ncmF5IC0+IDEwNSwgMTA1LCAxMDVcbiAgICB8IERpbWdyZXkgLT4gMTA1LCAxMDUsIDEwNVxuICAgIHwgRG9kZ2VyYmx1ZSAtPiAzMCwgMTQ0LCAyNTVcbiAgICB8IEZpcmVicmljayAtPiAxNzgsIDM0LCAzNFxuICAgIHwgRmxvcmFsd2hpdGUgLT4gMjU1LCAyNTAsIDI0MFxuICAgIHwgRm9yZXN0Z3JlZW4gLT4gMzQsIDEzOSwgMzRcbiAgICB8IEZ1Y2hzaWEgLT4gMjU1LCAwLCAyNTVcbiAgICB8IEdhaW5zYm9ybyAtPiAyMjAsIDIyMCwgMjIwXG4gICAgfCBHaG9zdHdoaXRlIC0+IDI0OCwgMjQ4LCAyNTVcbiAgICB8IEdvbGQgLT4gMjU1LCAyMTUsIDBcbiAgICB8IEdvbGRlbnJvZCAtPiAyMTgsIDE2NSwgMzJcbiAgICB8IEdyYXkgLT4gMTI4LCAxMjgsIDEyOFxuICAgIHwgR3JlZW4gLT4gMCwgMTI4LCAwXG4gICAgfCBHcmVlbnllbGxvdyAtPiAxNzMsIDI1NSwgNDdcbiAgICB8IEdyZXkgLT4gMTI4LCAxMjgsIDEyOFxuICAgIHwgSG9uZXlkZXcgLT4gMjQwLCAyNTUsIDI0MFxuICAgIHwgSG90cGluayAtPiAyNTUsIDEwNSwgMTgwXG4gICAgfCBJbmRpYW5yZWQgLT4gMjA1LCA5MiwgOTJcbiAgICB8IEluZGlnbyAtPiA3NSwgMCwgMTMwXG4gICAgfCBJdm9yeSAtPiAyNTUsIDI1NSwgMjQwXG4gICAgfCBLaGFraSAtPiAyNDAsIDIzMCwgMTQwXG4gICAgfCBMYXZlbmRlciAtPiAyMzAsIDIzMCwgMjUwXG4gICAgfCBMYXZlbmRlcmJsdXNoIC0+IDI1NSwgMjQwLCAyNDVcbiAgICB8IExhd25ncmVlbiAtPiAxMjQsIDI1MiwgMFxuICAgIHwgTGVtb25jaGlmZm9uIC0+IDI1NSwgMjUwLCAyMDVcbiAgICB8IExpZ2h0Ymx1ZSAtPiAxNzMsIDIxNiwgMjMwXG4gICAgfCBMaWdodGNvcmFsIC0+IDI0MCwgMTI4LCAxMjhcbiAgICB8IExpZ2h0Y3lhbiAtPiAyMjQsIDI1NSwgMjU1XG4gICAgfCBMaWdodGdvbGRlbnJvZHllbGxvdyAtPiAyNTAsIDI1MCwgMjEwXG4gICAgfCBMaWdodGdyYXkgLT4gMjExLCAyMTEsIDIxMVxuICAgIHwgTGlnaHRncmVlbiAtPiAxNDQsIDIzOCwgMTQ0XG4gICAgfCBMaWdodGdyZXkgLT4gMjExLCAyMTEsIDIxMVxuICAgIHwgTGlnaHRwaW5rIC0+IDI1NSwgMTgyLCAxOTNcbiAgICB8IExpZ2h0c2FsbW9uIC0+IDI1NSwgMTYwLCAxMjJcbiAgICB8IExpZ2h0c2VhZ3JlZW4gLT4gMzIsIDE3OCwgMTcwXG4gICAgfCBMaWdodHNreWJsdWUgLT4gMTM1LCAyMDYsIDI1MFxuICAgIHwgTGlnaHRzbGF0ZWdyYXkgLT4gMTE5LCAxMzYsIDE1M1xuICAgIHwgTGlnaHRzbGF0ZWdyZXkgLT4gMTE5LCAxMzYsIDE1M1xuICAgIHwgTGlnaHRzdGVlbGJsdWUgLT4gMTc2LCAxOTYsIDIyMlxuICAgIHwgTGlnaHR5ZWxsb3cgLT4gMjU1LCAyNTUsIDIyNFxuICAgIHwgTGltZSAtPiAwLCAyNTUsIDBcbiAgICB8IExpbWVncmVlbiAtPiA1MCwgMjA1LCA1MFxuICAgIHwgTGluZW4gLT4gMjUwLCAyNDAsIDIzMFxuICAgIHwgTWFnZW50YSAtPiAyNTUsIDAsIDI1NVxuICAgIHwgTWFyb29uIC0+IDEyOCwgMCwgMFxuICAgIHwgTWVkaXVtYXF1YW1hcmluZSAtPiAxMDIsIDIwNSwgMTcwXG4gICAgfCBNZWRpdW1ibHVlIC0+IDAsIDAsIDIwNVxuICAgIHwgTWVkaXVtb3JjaGlkIC0+IDE4NiwgODUsIDIxMVxuICAgIHwgTWVkaXVtcHVycGxlIC0+IDE0NywgMTEyLCAyMTlcbiAgICB8IE1lZGl1bXNlYWdyZWVuIC0+IDYwLCAxNzksIDExM1xuICAgIHwgTWVkaXVtc2xhdGVibHVlIC0+IDEyMywgMTA0LCAyMzhcbiAgICB8IE1lZGl1bXNwcmluZ2dyZWVuIC0+IDAsIDI1MCwgMTU0XG4gICAgfCBNZWRpdW10dXJxdW9pc2UgLT4gNzIsIDIwOSwgMjA0XG4gICAgfCBNZWRpdW12aW9sZXRyZWQgLT4gMTk5LCAyMSwgMTMzXG4gICAgfCBNaWRuaWdodGJsdWUgLT4gMjUsIDI1LCAxMTJcbiAgICB8IE1pbnRjcmVhbSAtPiAyNDUsIDI1NSwgMjUwXG4gICAgfCBNaXN0eXJvc2UgLT4gMjU1LCAyMjgsIDIyNVxuICAgIHwgTW9jY2FzaW4gLT4gMjU1LCAyMjgsIDE4MVxuICAgIHwgTmF2YWpvd2hpdGUgLT4gMjU1LCAyMjIsIDE3M1xuICAgIHwgTmF2eSAtPiAwLCAwLCAxMjhcbiAgICB8IE9sZGxhY2UgLT4gMjUzLCAyNDUsIDIzMFxuICAgIHwgT2xpdmUgLT4gMTI4LCAxMjgsIDBcbiAgICB8IE9saXZlZHJhYiAtPiAxMDcsIDE0MiwgMzVcbiAgICB8IE9yYW5nZSAtPiAyNTUsIDE2NSwgMFxuICAgIHwgT3JhbmdlcmVkIC0+IDI1NSwgNjksIDBcbiAgICB8IE9yY2hpZCAtPiAyMTgsIDExMiwgMjE0XG4gICAgfCBQYWxlZ29sZGVucm9kIC0+IDIzOCwgMjMyLCAxNzBcbiAgICB8IFBhbGVncmVlbiAtPiAxNTIsIDI1MSwgMTUyXG4gICAgfCBQYWxldHVycXVvaXNlIC0+IDE3NSwgMjM4LCAyMzhcbiAgICB8IFBhbGV2aW9sZXRyZWQgLT4gMjE5LCAxMTIsIDE0N1xuICAgIHwgUGFwYXlhd2hpcCAtPiAyNTUsIDIzOSwgMjEzXG4gICAgfCBQZWFjaHB1ZmYgLT4gMjU1LCAyMTgsIDE4NVxuICAgIHwgUGVydSAtPiAyMDUsIDEzMywgNjNcbiAgICB8IFBpbmsgLT4gMjU1LCAxOTIsIDIwM1xuICAgIHwgUGx1bSAtPiAyMjEsIDE2MCwgMjIxXG4gICAgfCBQb3dkZXJibHVlIC0+IDE3NiwgMjI0LCAyMzBcbiAgICB8IFB1cnBsZSAtPiAxMjgsIDAsIDEyOFxuICAgIHwgUmVkIC0+IDI1NSwgMCwgMFxuICAgIHwgUm9zeWJyb3duIC0+IDE4OCwgMTQzLCAxNDNcbiAgICB8IFJveWFsYmx1ZSAtPiA2NSwgMTA1LCAyMjVcbiAgICB8IFNhZGRsZWJyb3duIC0+IDEzOSwgNjksIDE5XG4gICAgfCBTYWxtb24gLT4gMjUwLCAxMjgsIDExNFxuICAgIHwgU2FuZHlicm93biAtPiAyNDQsIDE2NCwgOTZcbiAgICB8IFNlYWdyZWVuIC0+IDQ2LCAxMzksIDg3XG4gICAgfCBTZWFzaGVsbCAtPiAyNTUsIDI0NSwgMjM4XG4gICAgfCBTaWVubmEgLT4gMTYwLCA4MiwgNDVcbiAgICB8IFNpbHZlciAtPiAxOTIsIDE5MiwgMTkyXG4gICAgfCBTa3libHVlIC0+IDEzNSwgMjA2LCAyMzVcbiAgICB8IFNsYXRlYmx1ZSAtPiAxMDYsIDkwLCAyMDVcbiAgICB8IFNsYXRlZ3JheSAtPiAxMTIsIDEyOCwgMTQ0XG4gICAgfCBTbGF0ZWdyZXkgLT4gMTEyLCAxMjgsIDE0NFxuICAgIHwgU25vdyAtPiAyNTUsIDI1MCwgMjUwXG4gICAgfCBTcHJpbmdncmVlbiAtPiAwLCAyNTUsIDEyN1xuICAgIHwgU3RlZWxibHVlIC0+IDcwLCAxMzAsIDE4MFxuICAgIHwgVGFuIC0+IDIxMCwgMTgwLCAxNDBcbiAgICB8IFRlYWwgLT4gMCwgMTI4LCAxMjhcbiAgICB8IFRoaXN0bGUgLT4gMjE2LCAxOTEsIDIxNlxuICAgIHwgVG9tYXRvIC0+IDI1NSwgOTksIDcxXG4gICAgfCBUdXJxdW9pc2UgLT4gNjQsIDIyNCwgMjA4XG4gICAgfCBWaW9sZXQgLT4gMjM4LCAxMzAsIDIzOFxuICAgIHwgV2hlYXQgLT4gMjQ1LCAyMjIsIDE3OVxuICAgIHwgV2hpdGUgLT4gMjU1LCAyNTUsIDI1NVxuICAgIHwgV2hpdGVzbW9rZSAtPiAyNDUsIDI0NSwgMjQ1XG4gICAgfCBZZWxsb3cgLT4gMjU1LCAyNTUsIDBcbiAgICB8IFllbGxvd2dyZWVuIC0+IDE1NCwgMjA1LCA1MFxuXG4gIHR5cGUgdCA9XG4gICAgfCBOYW1lIG9mIG5hbWVcbiAgICB8IFJHQiBvZiAoaW50ICogaW50ICogaW50KVxuICAgICAgICAoKiogUmVkLCBHcmVlbiBhbmQgQmx1ZSB2YWx1ZXMuIENsaXBwZWQgdG8gW1swLi4yNTVdXSBieSBtb3N0IChBbGw/KVxuICAgICAgICAgICAgYnJvd3NlcnMuICopXG4gICAgfCBSR0JfcGVyY2VudCBvZiAoaW50ICogaW50ICogaW50KVxuICAgICAgICAoKiogUkdCIGNoYW5uZWxzIGFyZSBzcGVjaWZpZWQgYXMgYSBwZXJjZW50YWdlIG9mIHRoZWlyIG1heGltYWwgdmFsdWUuICopXG4gICAgfCBSR0JBIG9mIChpbnQgKiBpbnQgKiBpbnQgKiBmbG9hdClcbiAgICAgICAgKCoqIFNhbWUgYXMgUkdCIHdpdGggYWRkaXRpb25hbCB0cmFuc3BhcmVuY3kgYXJndW1lbnQuIE9wYWNpdHkgc2hvdWxkIGJlIGluXG4gICAgICAgICAgICBbMC5dIChjb21wbGV0ZWx5IHRyYW5zcGFyZW50KSBhbmQgWzEuXSAoY29tcGxldGVseSBvcGFxdWUpLiAqKVxuICAgIHwgUkdCQV9wZXJjZW50IG9mIChpbnQgKiBpbnQgKiBpbnQgKiBmbG9hdClcbiAgICAgICAgKCoqIFJHQiBjaGFubmVscyBzcGVjaWZpZWQgYXMgcGVyY2VudGFnZSBvZiB0aGVpciBtYXhpbWFsIHZhbHVlLiBBbHBoYVxuICAgICAgICAgICAgY2hhbm5lbCAob3BhY2l0eSkgaXMgc3RpbGwgYSBbMC5dIHRvIFsxLl0gZmxvYXQuICopXG4gICAgfCBIU0wgb2YgKGludCAqIGludCAqIGludClcbiAgICAgICAgKCoqIEh1ZSwgU2F0dXJhdGlvbiBhbmQgTGlnaHRuZXNzIHZhbHVlcy4gSHVlIGlzIGFuIGFuZ2xlIGluIGRlZ3JlZSAoaW5cbiAgICAgICAgICAgIGludGVydmFsIFtbMC4uMzYwW10pLiBTYXR1cmF0aW9uIGlzIGEgcGVyY2VudGFnZSAoW1swLi4xMDBdXSkgd2l0aCBbMF1cbiAgICAgICAgICAgIGJlaW5nIGNvbG9ybGVzcy4gTGlnaHRuZXNzIGlzIGFsc28gYSBwZXJjZW50YWdlIChbWzAuLjEwMF1dKSB3aXRoIFswXVxuICAgICAgICAgICAgYmVpbmcgYmxhY2suICopXG4gICAgfCBIU0xBIG9mIChpbnQgKiBpbnQgKiBpbnQgKiBmbG9hdClcbiAgICAgICAgKCoqIFNhbWUgYXMgSFNMIHdpdGggYW4gb3BhY2l0eSBhcmd1bWVudCBiZXR3ZWVuIFswLl0gYW5kIFsxLl0uICopXG5cbiAgbGV0IHJnYiA/YSByIGcgYiA9XG4gICAgbWF0Y2ggYSB3aXRoXG4gICAgfCBOb25lIC0+IFJHQiAociwgZywgYilcbiAgICB8IFNvbWUgYSAtPiBSR0JBIChyLCBnLCBiLCBhKVxuXG4gIGxldCBoc2wgP2EgaCBzIGwgPVxuICAgIG1hdGNoIGEgd2l0aFxuICAgIHwgTm9uZSAtPiBIU0wgKGgsIHMsIGwpXG4gICAgfCBTb21lIGEgLT4gSFNMQSAoaCwgcywgbCwgYSlcblxuICBsZXQgc3RyaW5nX29mX3QgPSBmdW5jdGlvblxuICAgIHwgTmFtZSBuIC0+IHN0cmluZ19vZl9uYW1lIG5cbiAgICB8IFJHQiAociwgZywgYikgLT4gUHJpbnRmLnNwcmludGYgXCJyZ2IoJWQsJWQsJWQpXCIgciBnIGJcbiAgICB8IFJHQl9wZXJjZW50IChyLCBnLCBiKSAtPiBQcmludGYuc3ByaW50ZiBcInJnYiglZCUlLCVkJSUsJWQlJSlcIiByIGcgYlxuICAgIHwgUkdCQSAociwgZywgYiwgYSkgLT4gUHJpbnRmLnNwcmludGYgXCJyZ2JhKCVkLCVkLCVkLCVmKVwiIHIgZyBiIGFcbiAgICB8IFJHQkFfcGVyY2VudCAociwgZywgYiwgYSkgLT4gUHJpbnRmLnNwcmludGYgXCJyZ2JhKCVkJSUsJWQlJSwlZCUlLCVmKVwiIHIgZyBiIGFcbiAgICB8IEhTTCAoaCwgcywgbCkgLT4gUHJpbnRmLnNwcmludGYgXCJoc2woJWQsJWQlJSwlZCUlKVwiIGggcyBsXG4gICAgfCBIU0xBIChoLCBzLCBsLCBhKSAtPiBQcmludGYuc3ByaW50ZiBcImhzbGEoJWQsJWQlJSwlZCUlLCVmKVwiIGggcyBsIGFcblxuICBsZXQgaGV4X29mX3JnYiAocmVkLCBncmVlbiwgYmx1ZSkgPVxuICAgIGxldCBpbl9yYW5nZSBpID1cbiAgICAgIGlmIGkgPCAwIHx8IGkgPiAyNTVcbiAgICAgIHRoZW4gcmFpc2UgKEludmFsaWRfYXJndW1lbnQgKHN0cmluZ19vZl9pbnQgaSBeIFwiIGlzIG91dCBvZiB2YWxpZCByYW5nZVwiKSlcbiAgICBpblxuICAgIGluX3JhbmdlIHJlZDtcbiAgICBpbl9yYW5nZSBncmVlbjtcbiAgICBpbl9yYW5nZSBibHVlO1xuICAgIFByaW50Zi5zcHJpbnRmIFwiIyUwMlglMDJYJTAyWFwiIHJlZCBncmVlbiBibHVlXG5cbiAgKCogT2NhbWwgPC0+IEpTIHJlcHJlc2VudGF0aW9uICopXG4gIHR5cGUganNfdCA9IEpzLmpzX3N0cmluZyBKcy50XG5cbiAgKCogVE9ETz8gYmUgbW9yZSByZXN0cmljdGl2ZSwgY2xpcCB2YWx1ZXMgaW50byBzdGFuZGFyZCByYW5nZSAqKVxuICBsZXQganNfdF9vZl9qc19zdHJpbmcgcyA9XG4gICAgbGV0IHJnYl9yZSA9XG4gICAgICBuZXclanMgSnMucmVnRXhwIChKcy5ieXRlc3RyaW5nIFwiXnJnYlxcXFwoXFxcXHMqXFxcXGQqLFxcXFxzKlxcXFxkKixcXFxccypcXFxcZCpcXFxcKSRcIilcbiAgICBpblxuICAgIGxldCByZ2JfcGN0X3JlID1cbiAgICAgIG5ldyVqcyBKcy5yZWdFeHAgKEpzLmJ5dGVzdHJpbmcgXCJecmdiXFxcXChcXFxccypcXFxcZColLFxcXFxzKlxcXFxkKiUsXFxcXHMqXFxcXGQqJVxcXFwpJFwiKVxuICAgIGluXG4gICAgbGV0IHJnYmFfcmUgPVxuICAgICAgbmV3JWpzIEpzLnJlZ0V4cFxuICAgICAgICAoSnMuYnl0ZXN0cmluZyBcIl5yZ2JhXFxcXChcXFxccypcXFxcZCosXFxcXHMqXFxcXGQqLFxcXFxzKlxcXFxkKixcXFxcZCpcXFxcLj9cXFxcZCpcXFxcKSRcIilcbiAgICBpblxuICAgIGxldCByZ2JhX3BjdF9yZSA9XG4gICAgICBuZXclanMgSnMucmVnRXhwXG4gICAgICAgIChKcy5ieXRlc3RyaW5nIFwiXnJnYmFcXFxcKFxcXFxzKlxcXFxkKiUsXFxcXHMqXFxcXGQqJSxcXFxccypcXFxcZColLFxcXFxkKlxcXFwuP1xcXFxkKlxcXFwpJFwiKVxuICAgIGluXG4gICAgbGV0IGhzbF9yZSA9XG4gICAgICBuZXclanMgSnMucmVnRXhwIChKcy5ieXRlc3RyaW5nIFwiXmhzbFxcXFwoXFxcXHMqXFxcXGQqLFxcXFxzKlxcXFxkKiUsXFxcXHMqXFxcXGQqJVxcXFwpJFwiKVxuICAgIGluXG4gICAgbGV0IGhzbGFfcmUgPVxuICAgICAgbmV3JWpzIEpzLnJlZ0V4cFxuICAgICAgICAoSnMuYnl0ZXN0cmluZyBcIl5oc2xhXFxcXChcXFxccypcXFxcZCosXFxcXHMqXFxcXGQqJSxcXFxccypcXFxcZColLFxcXFxkKlxcXFwuP1xcXFxkKlxcXFwpJFwiKVxuICAgIGluXG4gICAgaWYgSnMudG9fYm9vbCAocmdiX3JlIyN0ZXN0IHMpXG4gICAgICAgfHwgSnMudG9fYm9vbCAocmdiYV9yZSMjdGVzdCBzKVxuICAgICAgIHx8IEpzLnRvX2Jvb2wgKHJnYl9wY3RfcmUjI3Rlc3QgcylcbiAgICAgICB8fCBKcy50b19ib29sIChyZ2JhX3BjdF9yZSMjdGVzdCBzKVxuICAgICAgIHx8IEpzLnRvX2Jvb2wgKGhzbF9yZSMjdGVzdCBzKVxuICAgICAgIHx8IEpzLnRvX2Jvb2wgKGhzbGFfcmUjI3Rlc3QgcylcbiAgICB0aGVuIHNcbiAgICBlbHNlIGlmIExpc3QubWVtXG4gICAgICAgICAgICAgIChKcy50b19zdHJpbmcgcylcbiAgICAgICAgICAgICAgWyBcImFsaWNlYmx1ZVwiXG4gICAgICAgICAgICAgIDsgXCJhbnRpcXVld2hpdGVcIlxuICAgICAgICAgICAgICA7IFwiYXF1YVwiXG4gICAgICAgICAgICAgIDsgXCJhcXVhbWFyaW5lXCJcbiAgICAgICAgICAgICAgOyBcImF6dXJlXCJcbiAgICAgICAgICAgICAgOyBcImJlaWdlXCJcbiAgICAgICAgICAgICAgOyBcImJpc3F1ZVwiXG4gICAgICAgICAgICAgIDsgXCJibGFja1wiXG4gICAgICAgICAgICAgIDsgXCJibGFuY2hlZGFsbW9uZFwiXG4gICAgICAgICAgICAgIDsgXCJibHVlXCJcbiAgICAgICAgICAgICAgOyBcImJsdWV2aW9sZXRcIlxuICAgICAgICAgICAgICA7IFwiYnJvd25cIlxuICAgICAgICAgICAgICA7IFwiYnVybHl3b29kXCJcbiAgICAgICAgICAgICAgOyBcImNhZGV0Ymx1ZVwiXG4gICAgICAgICAgICAgIDsgXCJjaGFydHJldXNlXCJcbiAgICAgICAgICAgICAgOyBcImNob2NvbGF0ZVwiXG4gICAgICAgICAgICAgIDsgXCJjb3JhbFwiXG4gICAgICAgICAgICAgIDsgXCJjb3JuZmxvd2VyYmx1ZVwiXG4gICAgICAgICAgICAgIDsgXCJjb3Juc2lsa1wiXG4gICAgICAgICAgICAgIDsgXCJjcmltc29uXCJcbiAgICAgICAgICAgICAgOyBcImN5YW5cIlxuICAgICAgICAgICAgICA7IFwiZGFya2JsdWVcIlxuICAgICAgICAgICAgICA7IFwiZGFya2N5YW5cIlxuICAgICAgICAgICAgICA7IFwiZGFya2dvbGRlbnJvZFwiXG4gICAgICAgICAgICAgIDsgXCJkYXJrZ3JheVwiXG4gICAgICAgICAgICAgIDsgXCJkYXJrZ3JlZW5cIlxuICAgICAgICAgICAgICA7IFwiZGFya2dyZXlcIlxuICAgICAgICAgICAgICA7IFwiZGFya2toYWtpXCJcbiAgICAgICAgICAgICAgOyBcImRhcmttYWdlbnRhXCJcbiAgICAgICAgICAgICAgOyBcImRhcmtvbGl2ZWdyZWVuXCJcbiAgICAgICAgICAgICAgOyBcImRhcmtvcmFuZ2VcIlxuICAgICAgICAgICAgICA7IFwiZGFya29yY2hpZFwiXG4gICAgICAgICAgICAgIDsgXCJkYXJrcmVkXCJcbiAgICAgICAgICAgICAgOyBcImRhcmtzYWxtb25cIlxuICAgICAgICAgICAgICA7IFwiZGFya3NlYWdyZWVuXCJcbiAgICAgICAgICAgICAgOyBcImRhcmtzbGF0ZWJsdWVcIlxuICAgICAgICAgICAgICA7IFwiZGFya3NsYXRlZ3JheVwiXG4gICAgICAgICAgICAgIDsgXCJkYXJrc2xhdGVncmV5XCJcbiAgICAgICAgICAgICAgOyBcImRhcmt0dXJxdW9pc2VcIlxuICAgICAgICAgICAgICA7IFwiZGFya3Zpb2xldFwiXG4gICAgICAgICAgICAgIDsgXCJkZWVwcGlua1wiXG4gICAgICAgICAgICAgIDsgXCJkZWVwc2t5Ymx1ZVwiXG4gICAgICAgICAgICAgIDsgXCJkaW1ncmF5XCJcbiAgICAgICAgICAgICAgOyBcImRpbWdyZXlcIlxuICAgICAgICAgICAgICA7IFwiZG9kZ2VyYmx1ZVwiXG4gICAgICAgICAgICAgIDsgXCJmaXJlYnJpY2tcIlxuICAgICAgICAgICAgICA7IFwiZmxvcmFsd2hpdGVcIlxuICAgICAgICAgICAgICA7IFwiZm9yZXN0Z3JlZW5cIlxuICAgICAgICAgICAgICA7IFwiZnVjaHNpYVwiXG4gICAgICAgICAgICAgIDsgXCJnYWluc2Jvcm9cIlxuICAgICAgICAgICAgICA7IFwiZ2hvc3R3aGl0ZVwiXG4gICAgICAgICAgICAgIDsgXCJnb2xkXCJcbiAgICAgICAgICAgICAgOyBcImdvbGRlbnJvZFwiXG4gICAgICAgICAgICAgIDsgXCJncmF5XCJcbiAgICAgICAgICAgICAgOyBcImdyZWVuXCJcbiAgICAgICAgICAgICAgOyBcImdyZWVueWVsbG93XCJcbiAgICAgICAgICAgICAgOyBcImdyZXlcIlxuICAgICAgICAgICAgICA7IFwiaG9uZXlkZXdcIlxuICAgICAgICAgICAgICA7IFwiaG90cGlua1wiXG4gICAgICAgICAgICAgIDsgXCJpbmRpYW5yZWRcIlxuICAgICAgICAgICAgICA7IFwiaW5kaWdvXCJcbiAgICAgICAgICAgICAgOyBcIml2b3J5XCJcbiAgICAgICAgICAgICAgOyBcImtoYWtpXCJcbiAgICAgICAgICAgICAgOyBcImxhdmVuZGVyXCJcbiAgICAgICAgICAgICAgOyBcImxhdmVuZGVyYmx1c2hcIlxuICAgICAgICAgICAgICA7IFwibGF3bmdyZWVuXCJcbiAgICAgICAgICAgICAgOyBcImxlbW9uY2hpZmZvblwiXG4gICAgICAgICAgICAgIDsgXCJsaWdodGJsdWVcIlxuICAgICAgICAgICAgICA7IFwibGlnaHRjb3JhbFwiXG4gICAgICAgICAgICAgIDsgXCJsaWdodGN5YW5cIlxuICAgICAgICAgICAgICA7IFwibGlnaHRnb2xkZW5yb2R5ZWxsb3dcIlxuICAgICAgICAgICAgICA7IFwibGlnaHRncmF5XCJcbiAgICAgICAgICAgICAgOyBcImxpZ2h0Z3JlZW5cIlxuICAgICAgICAgICAgICA7IFwibGlnaHRncmV5XCJcbiAgICAgICAgICAgICAgOyBcImxpZ2h0cGlua1wiXG4gICAgICAgICAgICAgIDsgXCJsaWdodHNhbG1vblwiXG4gICAgICAgICAgICAgIDsgXCJsaWdodHNlYWdyZWVuXCJcbiAgICAgICAgICAgICAgOyBcImxpZ2h0c2t5Ymx1ZVwiXG4gICAgICAgICAgICAgIDsgXCJsaWdodHNsYXRlZ3JheVwiXG4gICAgICAgICAgICAgIDsgXCJsaWdodHNsYXRlZ3JleVwiXG4gICAgICAgICAgICAgIDsgXCJsaWdodHN0ZWVsYmx1ZVwiXG4gICAgICAgICAgICAgIDsgXCJsaWdodHllbGxvd1wiXG4gICAgICAgICAgICAgIDsgXCJsaW1lXCJcbiAgICAgICAgICAgICAgOyBcImxpbWVncmVlblwiXG4gICAgICAgICAgICAgIDsgXCJsaW5lblwiXG4gICAgICAgICAgICAgIDsgXCJtYWdlbnRhXCJcbiAgICAgICAgICAgICAgOyBcIm1hcm9vblwiXG4gICAgICAgICAgICAgIDsgXCJtZWRpdW1hcXVhbWFyaW5lXCJcbiAgICAgICAgICAgICAgOyBcIm1lZGl1bWJsdWVcIlxuICAgICAgICAgICAgICA7IFwibWVkaXVtb3JjaGlkXCJcbiAgICAgICAgICAgICAgOyBcIm1lZGl1bXB1cnBsZVwiXG4gICAgICAgICAgICAgIDsgXCJtZWRpdW1zZWFncmVlblwiXG4gICAgICAgICAgICAgIDsgXCJtZWRpdW1zbGF0ZWJsdWVcIlxuICAgICAgICAgICAgICA7IFwibWVkaXVtc3ByaW5nZ3JlZW5cIlxuICAgICAgICAgICAgICA7IFwibWVkaXVtdHVycXVvaXNlXCJcbiAgICAgICAgICAgICAgOyBcIm1lZGl1bXZpb2xldHJlZFwiXG4gICAgICAgICAgICAgIDsgXCJtaWRuaWdodGJsdWVcIlxuICAgICAgICAgICAgICA7IFwibWludGNyZWFtXCJcbiAgICAgICAgICAgICAgOyBcIm1pc3R5cm9zZVwiXG4gICAgICAgICAgICAgIDsgXCJtb2NjYXNpblwiXG4gICAgICAgICAgICAgIDsgXCJuYXZham93aGl0ZVwiXG4gICAgICAgICAgICAgIDsgXCJuYXZ5XCJcbiAgICAgICAgICAgICAgOyBcIm9sZGxhY2VcIlxuICAgICAgICAgICAgICA7IFwib2xpdmVcIlxuICAgICAgICAgICAgICA7IFwib2xpdmVkcmFiXCJcbiAgICAgICAgICAgICAgOyBcIm9yYW5nZVwiXG4gICAgICAgICAgICAgIDsgXCJvcmFuZ2VyZWRcIlxuICAgICAgICAgICAgICA7IFwib3JjaGlkXCJcbiAgICAgICAgICAgICAgOyBcInBhbGVnb2xkZW5yb2RcIlxuICAgICAgICAgICAgICA7IFwicGFsZWdyZWVuXCJcbiAgICAgICAgICAgICAgOyBcInBhbGV0dXJxdW9pc2VcIlxuICAgICAgICAgICAgICA7IFwicGFsZXZpb2xldHJlZFwiXG4gICAgICAgICAgICAgIDsgXCJwYXBheWF3aGlwXCJcbiAgICAgICAgICAgICAgOyBcInBlYWNocHVmZlwiXG4gICAgICAgICAgICAgIDsgXCJwZXJ1XCJcbiAgICAgICAgICAgICAgOyBcInBpbmtcIlxuICAgICAgICAgICAgICA7IFwicGx1bVwiXG4gICAgICAgICAgICAgIDsgXCJwb3dkZXJibHVlXCJcbiAgICAgICAgICAgICAgOyBcInB1cnBsZVwiXG4gICAgICAgICAgICAgIDsgXCJyZWRcIlxuICAgICAgICAgICAgICA7IFwicm9zeWJyb3duXCJcbiAgICAgICAgICAgICAgOyBcInJveWFsYmx1ZVwiXG4gICAgICAgICAgICAgIDsgXCJzYWRkbGVicm93blwiXG4gICAgICAgICAgICAgIDsgXCJzYWxtb25cIlxuICAgICAgICAgICAgICA7IFwic2FuZHlicm93blwiXG4gICAgICAgICAgICAgIDsgXCJzZWFncmVlblwiXG4gICAgICAgICAgICAgIDsgXCJzZWFzaGVsbFwiXG4gICAgICAgICAgICAgIDsgXCJzaWVubmFcIlxuICAgICAgICAgICAgICA7IFwic2lsdmVyXCJcbiAgICAgICAgICAgICAgOyBcInNreWJsdWVcIlxuICAgICAgICAgICAgICA7IFwic2xhdGVibHVlXCJcbiAgICAgICAgICAgICAgOyBcInNsYXRlZ3JheVwiXG4gICAgICAgICAgICAgIDsgXCJzbGF0ZWdyZXlcIlxuICAgICAgICAgICAgICA7IFwic25vd1wiXG4gICAgICAgICAgICAgIDsgXCJzcHJpbmdncmVlblwiXG4gICAgICAgICAgICAgIDsgXCJzdGVlbGJsdWVcIlxuICAgICAgICAgICAgICA7IFwidGFuXCJcbiAgICAgICAgICAgICAgOyBcInRlYWxcIlxuICAgICAgICAgICAgICA7IFwidGhpc3RsZVwiXG4gICAgICAgICAgICAgIDsgXCJ0b21hdG9cIlxuICAgICAgICAgICAgICA7IFwidHVycXVvaXNlXCJcbiAgICAgICAgICAgICAgOyBcInZpb2xldFwiXG4gICAgICAgICAgICAgIDsgXCJ3aGVhdFwiXG4gICAgICAgICAgICAgIDsgXCJ3aGl0ZVwiXG4gICAgICAgICAgICAgIDsgXCJ3aGl0ZXNtb2tlXCJcbiAgICAgICAgICAgICAgOyBcInllbGxvd1wiXG4gICAgICAgICAgICAgIDsgXCJ5ZWxsb3dncmVlblwiXG4gICAgICAgICAgICAgIF1cbiAgICB0aGVuIHNcbiAgICBlbHNlIHJhaXNlIChJbnZhbGlkX2FyZ3VtZW50IChKcy50b19zdHJpbmcgcyBeIFwiIGlzIG5vdCBhIHZhbGlkIGNvbG9yXCIpKVxuXG4gIGxldCBuYW1lIGNuID0gSnMuc3RyaW5nIChzdHJpbmdfb2ZfbmFtZSBjbilcblxuICBsZXQganMgPSBmdW5jdGlvblxuICAgIHwgTmFtZSBuIC0+IG5hbWUgblxuICAgIHwgKFJHQiBfIHwgUkdCX3BlcmNlbnQgXyB8IFJHQkEgXyB8IFJHQkFfcGVyY2VudCBfIHwgSFNMIF8gfCBIU0xBIF8pIGFzIGMgLT5cbiAgICAgICAgSnMuc3RyaW5nIChzdHJpbmdfb2ZfdCBjKVxuXG4gIGxldCBtbCBjID1cbiAgICBsZXQgcyA9IEpzLnRvX3N0cmluZyBjIGluXG4gICAgdHJ5IE5hbWUgKG5hbWVfb2Zfc3RyaW5nIHMpXG4gICAgd2l0aCBJbnZhbGlkX2FyZ3VtZW50IF8gLT4gKFxuICAgICAgbGV0IGZhaWwgKCkgPSByYWlzZSAoSW52YWxpZF9hcmd1bWVudCAocyBeIFwiIGlzIG5vdCBhIHZhbGlkIGNvbG9yXCIpKSBpblxuICAgICAgbGV0IHJlX3JnYiA9XG4gICAgICAgIFJlZ2V4cC5yZWdleHAgXCIocmdiYT8pXFxcXCgoPzooXFxcXGQqKSwoXFxcXGQqKSwoXFxcXGQqKSg/OiwoXFxcXGQqKD86XFxcXC5cXFxcZCopPykpPylcXFxcKVwiXG4gICAgICBpblxuICAgICAgbGV0IHJlX3JnYl9wY3QgPVxuICAgICAgICBSZWdleHAucmVnZXhwIFwiKHJnYmE/KVxcXFwoKD86KFxcXFxkKiklLChcXFxcZCopJSwoXFxcXGQqKSUoPzosKFxcXFxkKig/OlxcXFwuXFxcXGQqKT8pKT8pXFxcXClcIlxuICAgICAgaW5cbiAgICAgIGxldCByZV9oc2wgPVxuICAgICAgICBSZWdleHAucmVnZXhwIFwiKGhzbGE/KVxcXFwoKD86KFxcXFxkKiksKFxcXFxkKiklLChcXFxcZCopJSg/OiwoXFxcXGQqKD86XFxcXC5cXFxcZCopPykpPylcXFxcKVwiXG4gICAgICBpblxuICAgICAgbGV0IGlfb2Zfc19vID0gZnVuY3Rpb25cbiAgICAgICAgfCBOb25lIC0+IGZhaWwgKClcbiAgICAgICAgfCBTb21lIGkgLT4gKFxuICAgICAgICAgICAgdHJ5IGludF9vZl9zdHJpbmcgaVxuICAgICAgICAgICAgd2l0aCBJbnZhbGlkX2FyZ3VtZW50IHMgfCBGYWlsdXJlIHMgLT5cbiAgICAgICAgICAgICAgcmFpc2UgKEludmFsaWRfYXJndW1lbnQgKFwiY29sb3IgY29udmVyc2lvbiBlcnJvciAoXCIgXiBpIF4gXCIpOiBcIiBeIHMpKSlcbiAgICAgIGluXG4gICAgICBsZXQgZl9vZl9zIGYgPVxuICAgICAgICB0cnkgZmxvYXRfb2Zfc3RyaW5nIGZcbiAgICAgICAgd2l0aCBJbnZhbGlkX2FyZ3VtZW50IHMgfCBGYWlsdXJlIHMgLT5cbiAgICAgICAgICByYWlzZSAoSW52YWxpZF9hcmd1bWVudCAoXCJjb2xvciBjb252ZXJzaW9uIGVycm9yIChcIiBeIGYgXiBcIik6IFwiIF4gcykpXG4gICAgICBpblxuICAgICAgbWF0Y2ggUmVnZXhwLnN0cmluZ19tYXRjaCByZV9yZ2IgcyAwIHdpdGhcbiAgICAgIHwgU29tZSByIC0+IChcbiAgICAgICAgICBsZXQgcmVkID0gUmVnZXhwLm1hdGNoZWRfZ3JvdXAgciAyIGluXG4gICAgICAgICAgbGV0IGdyZWVuID0gUmVnZXhwLm1hdGNoZWRfZ3JvdXAgciAzIGluXG4gICAgICAgICAgbGV0IGJsdWUgPSBSZWdleHAubWF0Y2hlZF9ncm91cCByIDQgaW5cbiAgICAgICAgICBsZXQgYWxwaGEgPSBSZWdleHAubWF0Y2hlZF9ncm91cCByIDUgaW5cbiAgICAgICAgICBtYXRjaCBSZWdleHAubWF0Y2hlZF9ncm91cCByIDEgd2l0aFxuICAgICAgICAgIHwgU29tZSBcInJnYlwiIC0+IChcbiAgICAgICAgICAgICAgbWF0Y2ggYWxwaGEgd2l0aFxuICAgICAgICAgICAgICB8IFNvbWUgXyAtPiBmYWlsICgpXG4gICAgICAgICAgICAgIHwgTm9uZSAtPiBSR0IgKGlfb2Zfc19vIHJlZCwgaV9vZl9zX28gZ3JlZW4sIGlfb2Zfc19vIGJsdWUpKVxuICAgICAgICAgIHwgU29tZSBcInJnYmFcIiAtPiAoXG4gICAgICAgICAgICAgIG1hdGNoIGFscGhhIHdpdGhcbiAgICAgICAgICAgICAgfCBOb25lIC0+IGZhaWwgKClcbiAgICAgICAgICAgICAgfCBTb21lIGEgLT4gUkdCQSAoaV9vZl9zX28gcmVkLCBpX29mX3NfbyBncmVlbiwgaV9vZl9zX28gYmx1ZSwgZl9vZl9zIGEpKVxuICAgICAgICAgIHwgU29tZSBfIHwgTm9uZSAtPiBmYWlsICgpKVxuICAgICAgfCBOb25lIC0+IChcbiAgICAgICAgICBtYXRjaCBSZWdleHAuc3RyaW5nX21hdGNoIHJlX3JnYl9wY3QgcyAwIHdpdGhcbiAgICAgICAgICB8IFNvbWUgciAtPiAoXG4gICAgICAgICAgICAgIGxldCByZWQgPSBSZWdleHAubWF0Y2hlZF9ncm91cCByIDIgaW5cbiAgICAgICAgICAgICAgbGV0IGdyZWVuID0gUmVnZXhwLm1hdGNoZWRfZ3JvdXAgciAzIGluXG4gICAgICAgICAgICAgIGxldCBibHVlID0gUmVnZXhwLm1hdGNoZWRfZ3JvdXAgciA0IGluXG4gICAgICAgICAgICAgIGxldCBhbHBoYSA9IFJlZ2V4cC5tYXRjaGVkX2dyb3VwIHIgNSBpblxuICAgICAgICAgICAgICBtYXRjaCBSZWdleHAubWF0Y2hlZF9ncm91cCByIDEgd2l0aFxuICAgICAgICAgICAgICB8IFNvbWUgXCJyZ2JcIiAtPiAoXG4gICAgICAgICAgICAgICAgICBtYXRjaCBhbHBoYSB3aXRoXG4gICAgICAgICAgICAgICAgICB8IFNvbWUgXyAtPiBmYWlsICgpXG4gICAgICAgICAgICAgICAgICB8IE5vbmUgLT4gUkdCX3BlcmNlbnQgKGlfb2Zfc19vIHJlZCwgaV9vZl9zX28gZ3JlZW4sIGlfb2Zfc19vIGJsdWUpKVxuICAgICAgICAgICAgICB8IFNvbWUgXCJyZ2JhXCIgLT4gKFxuICAgICAgICAgICAgICAgICAgbWF0Y2ggYWxwaGEgd2l0aFxuICAgICAgICAgICAgICAgICAgfCBOb25lIC0+IGZhaWwgKClcbiAgICAgICAgICAgICAgICAgIHwgU29tZSBhIC0+XG4gICAgICAgICAgICAgICAgICAgICAgUkdCQV9wZXJjZW50IChpX29mX3NfbyByZWQsIGlfb2Zfc19vIGdyZWVuLCBpX29mX3NfbyBibHVlLCBmX29mX3MgYSlcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgfCBTb21lIF8gfCBOb25lIC0+IGZhaWwgKCkpXG4gICAgICAgICAgfCBOb25lIC0+IChcbiAgICAgICAgICAgICAgbWF0Y2ggUmVnZXhwLnN0cmluZ19tYXRjaCByZV9oc2wgcyAwIHdpdGhcbiAgICAgICAgICAgICAgfCBTb21lIHIgLT4gKFxuICAgICAgICAgICAgICAgICAgbGV0IHJlZCA9IFJlZ2V4cC5tYXRjaGVkX2dyb3VwIHIgMiBpblxuICAgICAgICAgICAgICAgICAgbGV0IGdyZWVuID0gUmVnZXhwLm1hdGNoZWRfZ3JvdXAgciAzIGluXG4gICAgICAgICAgICAgICAgICBsZXQgYmx1ZSA9IFJlZ2V4cC5tYXRjaGVkX2dyb3VwIHIgNCBpblxuICAgICAgICAgICAgICAgICAgbGV0IGFscGhhID0gUmVnZXhwLm1hdGNoZWRfZ3JvdXAgciA1IGluXG4gICAgICAgICAgICAgICAgICBtYXRjaCBSZWdleHAubWF0Y2hlZF9ncm91cCByIDEgd2l0aFxuICAgICAgICAgICAgICAgICAgfCBTb21lIFwiaHNsXCIgLT4gKFxuICAgICAgICAgICAgICAgICAgICAgIG1hdGNoIGFscGhhIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICB8IFNvbWUgXyAtPiBmYWlsICgpXG4gICAgICAgICAgICAgICAgICAgICAgfCBOb25lIC0+IEhTTCAoaV9vZl9zX28gcmVkLCBpX29mX3NfbyBncmVlbiwgaV9vZl9zX28gYmx1ZSkpXG4gICAgICAgICAgICAgICAgICB8IFNvbWUgXCJoc2xhXCIgLT4gKFxuICAgICAgICAgICAgICAgICAgICAgIG1hdGNoIGFscGhhIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICB8IE5vbmUgLT4gZmFpbCAoKVxuICAgICAgICAgICAgICAgICAgICAgIHwgU29tZSBhIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIEhTTEEgKGlfb2Zfc19vIHJlZCwgaV9vZl9zX28gZ3JlZW4sIGlfb2Zfc19vIGJsdWUsIGZfb2ZfcyBhKSlcbiAgICAgICAgICAgICAgICAgIHwgU29tZSBfIHwgTm9uZSAtPiBmYWlsICgpKVxuICAgICAgICAgICAgICB8IE5vbmUgLT4gZmFpbCAoKSkpKVxuZW5kXG5cbm1vZHVsZSBMZW5ndGggPSBzdHJ1Y3RcbiAgKCogaHR0cDovL3d3dy53My5vcmcvVFIvY3NzMy12YWx1ZXMvI2xlbmd0aHMgKilcblxuICAoKiBUT0RPOlxuICAgICB7W1xuICAgICAgIHR5cGUganNfdCA9IHByaXZhdGUgSnMuc3RyaW5nIEpzLnRcbiAgICAgICB2YWwganNfdF9vZl90XG4gICAgICAgdmFsIHRfb2ZfanNfdFxuICAgICAgIHZhbCB0X29mX3N0cmluZ1xuICAgICBdfVxuICAqKVxuXG4gIHR5cGUgdCA9XG4gICAgfCBaZXJvXG4gICAgKCogcmVsYXRpdmUgKilcbiAgICB8IEVtIG9mIGZsb2F0XG4gICAgfCBFeCBvZiBmbG9hdFxuICAgIHwgUHggb2YgZmxvYXRcbiAgICB8IEdkIG9mIGZsb2F0XG4gICAgfCBSZW0gb2YgZmxvYXRcbiAgICB8IFZ3IG9mIGZsb2F0XG4gICAgfCBWaCBvZiBmbG9hdFxuICAgIHwgVm0gb2YgZmxvYXRcbiAgICB8IENoIG9mIGZsb2F0XG4gICAgKCogYWJzb2x1dGUgKilcbiAgICB8IE1tIG9mIGZsb2F0XG4gICAgfCBDbSBvZiBmbG9hdFxuICAgIHwgSW4gb2YgZmxvYXRcbiAgICB8IFB0IG9mIGZsb2F0XG4gICAgfCBQYyBvZiBmbG9hdFxuXG4gIGxldCBzdHJpbmdfb2ZfdCA9IGZ1bmN0aW9uXG4gICAgfCBaZXJvIC0+IFwiMFwiXG4gICAgfCBFbSBmIC0+IFByaW50Zi5zcHJpbnRmIFwiJWYlc1wiIGYgXCJlbVwiXG4gICAgfCBFeCBmIC0+IFByaW50Zi5zcHJpbnRmIFwiJWYlc1wiIGYgXCJleFwiXG4gICAgfCBQeCBmIC0+IFByaW50Zi5zcHJpbnRmIFwiJWYlc1wiIGYgXCJweFwiXG4gICAgfCBHZCBmIC0+IFByaW50Zi5zcHJpbnRmIFwiJWYlc1wiIGYgXCJnZFwiXG4gICAgfCBSZW0gZiAtPiBQcmludGYuc3ByaW50ZiBcIiVmJXNcIiBmIFwicmVtXCJcbiAgICB8IFZ3IGYgLT4gUHJpbnRmLnNwcmludGYgXCIlZiVzXCIgZiBcInZ3XCJcbiAgICB8IFZoIGYgLT4gUHJpbnRmLnNwcmludGYgXCIlZiVzXCIgZiBcInZoXCJcbiAgICB8IFZtIGYgLT4gUHJpbnRmLnNwcmludGYgXCIlZiVzXCIgZiBcInZtXCJcbiAgICB8IENoIGYgLT4gUHJpbnRmLnNwcmludGYgXCIlZiVzXCIgZiBcImNoXCJcbiAgICB8IE1tIGYgLT4gUHJpbnRmLnNwcmludGYgXCIlZiVzXCIgZiBcIm1tXCJcbiAgICB8IENtIGYgLT4gUHJpbnRmLnNwcmludGYgXCIlZiVzXCIgZiBcImNtXCJcbiAgICB8IEluIGYgLT4gUHJpbnRmLnNwcmludGYgXCIlZiVzXCIgZiBcImluXCJcbiAgICB8IFB0IGYgLT4gUHJpbnRmLnNwcmludGYgXCIlZiVzXCIgZiBcInB0XCJcbiAgICB8IFBjIGYgLT4gUHJpbnRmLnNwcmludGYgXCIlZiVzXCIgZiBcInBjXCJcblxuICB0eXBlIGpzX3QgPSBKcy5qc19zdHJpbmcgSnMudFxuXG4gIGxldCBqcyB0ID0gSnMuc3RyaW5nIChzdHJpbmdfb2ZfdCB0KVxuXG4gIGxldCBtbCB0ID1cbiAgICBsZXQgcyA9IEpzLnRvX3N0cmluZyB0IGluXG4gICAgaWYgU3RyaW5nLmVxdWFsIHMgXCIwXCJcbiAgICB0aGVuIFplcm9cbiAgICBlbHNlXG4gICAgICBsZXQgZmFpbCAoKSA9IHJhaXNlIChJbnZhbGlkX2FyZ3VtZW50IChzIF4gXCIgaXMgbm90IGEgdmFsaWQgbGVuZ3RoXCIpKSBpblxuICAgICAgbGV0IHJlID0gUmVnZXhwLnJlZ2V4cCBcIl4oXFxcXGQqKD86XFxcXC5cXFxcZCopPylcXFxccyooXFxcXFMqKSRcIiBpblxuICAgICAgbWF0Y2ggUmVnZXhwLnN0cmluZ19tYXRjaCByZSBzIDAgd2l0aFxuICAgICAgfCBOb25lIC0+IGZhaWwgKClcbiAgICAgIHwgU29tZSByIC0+IChcbiAgICAgICAgICBsZXQgZiA9XG4gICAgICAgICAgICBtYXRjaCBSZWdleHAubWF0Y2hlZF9ncm91cCByIDEgd2l0aFxuICAgICAgICAgICAgfCBOb25lIC0+IGZhaWwgKClcbiAgICAgICAgICAgIHwgU29tZSBmIC0+IChcbiAgICAgICAgICAgICAgICB0cnkgZmxvYXRfb2Zfc3RyaW5nIGZcbiAgICAgICAgICAgICAgICB3aXRoIEludmFsaWRfYXJndW1lbnQgcyAtPlxuICAgICAgICAgICAgICAgICAgcmFpc2UgKEludmFsaWRfYXJndW1lbnQgKFwibGVuZ3RoIGNvbnZlcnNpb24gZXJyb3I6IFwiIF4gcykpKVxuICAgICAgICAgIGluXG4gICAgICAgICAgbWF0Y2ggUmVnZXhwLm1hdGNoZWRfZ3JvdXAgciAyIHdpdGhcbiAgICAgICAgICB8IE5vbmUgLT4gZmFpbCAoKVxuICAgICAgICAgIHwgU29tZSBcImVtXCIgLT4gRW0gZlxuICAgICAgICAgIHwgU29tZSBcImV4XCIgLT4gRXggZlxuICAgICAgICAgIHwgU29tZSBcInB4XCIgLT4gUHggZlxuICAgICAgICAgIHwgU29tZSBcImdkXCIgLT4gR2QgZlxuICAgICAgICAgIHwgU29tZSBcInJlbVwiIC0+IFJlbSBmXG4gICAgICAgICAgfCBTb21lIFwidndcIiAtPiBWdyBmXG4gICAgICAgICAgfCBTb21lIFwidmhcIiAtPiBWaCBmXG4gICAgICAgICAgfCBTb21lIFwidm1cIiAtPiBWbSBmXG4gICAgICAgICAgfCBTb21lIFwiY2hcIiAtPiBDaCBmXG4gICAgICAgICAgfCBTb21lIFwibW1cIiAtPiBNbSBmXG4gICAgICAgICAgfCBTb21lIFwiY21cIiAtPiBDbSBmXG4gICAgICAgICAgfCBTb21lIFwiaW5cIiAtPiBJbiBmXG4gICAgICAgICAgfCBTb21lIFwicHRcIiAtPiBQdCBmXG4gICAgICAgICAgfCBTb21lIFwicGNcIiAtPiBQYyBmXG4gICAgICAgICAgfCBTb21lIF8gLT4gZmFpbCAoKSlcbmVuZFxuXG5tb2R1bGUgQW5nbGUgPSBzdHJ1Y3RcbiAgdHlwZSB0ID1cbiAgICB8IERlZyBvZiBmbG9hdFxuICAgIHwgR3JhZCBvZiBmbG9hdFxuICAgIHwgUmFkIG9mIGZsb2F0XG4gICAgfCBUdXJucyBvZiBmbG9hdFxuXG4gIGxldCBzdHJpbmdfb2ZfdCA9IGZ1bmN0aW9uXG4gICAgfCBEZWcgZiAtPiBQcmludGYuc3ByaW50ZiBcIiVmJXNcIiBmIFwiZGVnXCJcbiAgICB8IEdyYWQgZiAtPiBQcmludGYuc3ByaW50ZiBcIiVmJXNcIiBmIFwiZ3JhZFwiXG4gICAgfCBSYWQgZiAtPiBQcmludGYuc3ByaW50ZiBcIiVmJXNcIiBmIFwicmFkXCJcbiAgICB8IFR1cm5zIGYgLT4gUHJpbnRmLnNwcmludGYgXCIlZiVzXCIgZiBcInR1cm5zXCJcblxuICB0eXBlIGpzX3QgPSBKcy5qc19zdHJpbmcgSnMudFxuXG4gIGxldCBqcyB0ID0gSnMuc3RyaW5nIChzdHJpbmdfb2ZfdCB0KVxuXG4gIGxldCBtbCBqID1cbiAgICBsZXQgcyA9IEpzLnRvX3N0cmluZyBqIGluXG4gICAgbGV0IHJlID0gUmVnZXhwLnJlZ2V4cCBcIl4oXFxcXGQqKD86XFxcXC5cXFxcZCopKShkZWd8Z3JhZHxyYWR8dHVybnMpJFwiIGluXG4gICAgbGV0IGZhaWwgKCkgPSByYWlzZSAoSW52YWxpZF9hcmd1bWVudCAocyBeIFwiIGlzIG5vdCBhIHZhbGlkIGxlbmd0aFwiKSkgaW5cbiAgICBtYXRjaCBSZWdleHAuc3RyaW5nX21hdGNoIHJlIHMgMCB3aXRoXG4gICAgfCBOb25lIC0+IGZhaWwgKClcbiAgICB8IFNvbWUgciAtPiAoXG4gICAgICAgIGxldCBmID1cbiAgICAgICAgICBtYXRjaCBSZWdleHAubWF0Y2hlZF9ncm91cCByIDEgd2l0aFxuICAgICAgICAgIHwgTm9uZSAtPiBmYWlsICgpXG4gICAgICAgICAgfCBTb21lIGYgLT4gKFxuICAgICAgICAgICAgICB0cnkgZmxvYXRfb2Zfc3RyaW5nIGZcbiAgICAgICAgICAgICAgd2l0aCBJbnZhbGlkX2FyZ3VtZW50IHMgLT5cbiAgICAgICAgICAgICAgICByYWlzZSAoSW52YWxpZF9hcmd1bWVudCAoXCJsZW5ndGggY29udmVyc2lvbiBlcnJvcjogXCIgXiBzKSkpXG4gICAgICAgIGluXG4gICAgICAgIG1hdGNoIFJlZ2V4cC5tYXRjaGVkX2dyb3VwIHIgMiB3aXRoXG4gICAgICAgIHwgU29tZSBcImRlZ1wiIC0+IERlZyBmXG4gICAgICAgIHwgU29tZSBcImdyYWRcIiAtPiBHcmFkIGZcbiAgICAgICAgfCBTb21lIFwicmFkXCIgLT4gUmFkIGZcbiAgICAgICAgfCBTb21lIFwidHVybnNcIiAtPiBUdXJucyBmXG4gICAgICAgIHwgU29tZSBfIHwgTm9uZSAtPiBmYWlsICgpKVxuZW5kXG4iLCIoKiBKc19vZl9vY2FtbCBsaWJyYXJ5XG4gKiBodHRwOi8vd3d3Lm9jc2lnZW4ub3JnL2pzX29mX29jYW1sL1xuICogQ29weXJpZ2h0IChDKSAyMDEwIErDqXLDtG1lIFZvdWlsbG9uXG4gKiBMYWJvcmF0b2lyZSBQUFMgLSBDTlJTIFVuaXZlcnNpdMOpIFBhcmlzIERpZGVyb3RcbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCB3aXRoIGxpbmtpbmcgZXhjZXB0aW9uO1xuICogZWl0aGVyIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuXG4gKilcblxuKCoqIEphdmFzY3JpcHQgZXZlbnRzLiAqKVxuXG5vcGVuISBJbXBvcnRcbm1vZHVsZSBUeXAgPSBEb21faHRtbC5FdmVudFxuXG50eXBlIGxpc3RlbmVyID0gRG9tX2h0bWwuZXZlbnRfbGlzdGVuZXJfaWRcblxubGV0IGxpc3RlbiA/KGNhcHR1cmUgPSBmYWxzZSkgdGFyZ2V0IHR5cCBjYiA9XG4gIERvbV9odG1sLmFkZEV2ZW50TGlzdGVuZXJcbiAgICB0YXJnZXRcbiAgICB0eXBcbiAgICAoRG9tX2h0bWwuZnVsbF9oYW5kbGVyIChmdW4gbiBlIC0+IEpzLmJvb2wgKGNiIG4gZSkpKVxuICAgIChKcy5ib29sIGNhcHR1cmUpXG5cbmxldCBzdG9wX2xpc3RlbiA9IERvbV9odG1sLnJlbW92ZUV2ZW50TGlzdGVuZXJcbiIsIigqIEpzX29mX29jYW1sIGxpYnJhcnlcbiAqIGh0dHA6Ly93d3cub2NzaWdlbi5vcmcvanNfb2Zfb2NhbWwvXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTQgSHVnbyBIZXV6YXJkXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTQgSsOpcsO0bWUgVm91aWxsb25cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCB3aXRoIGxpbmtpbmcgZXhjZXB0aW9uO1xuICogZWl0aGVyIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuXG4gKilcblxub3BlbiBKc1xub3BlbiEgSW1wb3J0XG5cbmxldCB4bWxucyA9IEpzLnN0cmluZyBcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCJcblxuKCogdHJhbnNsYXRlIHNwZWMgZnJvbSBodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcvaWRsLmh0bWwgKilcbigqIGh0dHA6Ly93d3cudzMub3JnL1RSL1NWRy9zdHJ1Y3QuaHRtbCAqKVxuXG50eXBlIGVycm9yX2NvZGUgPVxuICB8IFdST05HX1RZUEVfRVJSXG4gIHwgSU5WQUxJRF9WQUxVRV9FUlJcbiAgfCBNQVRSSVhfTk9UX0lOVkVSVEFCTEVcblxuY2xhc3MgdHlwZSBzdmdfZXJyb3IgPSBvYmplY3RcbiAgaW5oZXJpdCBKcy5lcnJvclxuXG4gIG1ldGhvZCBjb2RlIDogZXJyb3JfY29kZSB0IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG5leGNlcHRpb24gU1ZHRXJyb3Igb2Ygc3ZnX2Vycm9yXG5cbnR5cGUgbGVuZ3RoVW5pdFR5cGUgPVxuICB8IExFTkdUSFRZUEVfVU5LTk9XTlxuICB8IExFTkdUSFRZUEVfTlVNQkVSXG4gIHwgTEVOR1RIVFlQRV9QRVJDRU5UQUdFXG4gIHwgTEVOR1RIVFlQRV9FTVNcbiAgfCBMRU5HVEhUWVBFX0VYU1xuICB8IExFTkdUSFRZUEVfUFhcbiAgfCBMRU5HVEhUWVBFX0NNXG4gIHwgTEVOR1RIVFlQRV9NTVxuICB8IExFTkdUSFRZUEVfSU5cbiAgfCBMRU5HVEhUWVBFX1BUXG4gIHwgTEVOR1RIVFlQRV9QQ1xuXG50eXBlIGFuZ2xlVW5pdFR5cGUgPVxuICB8IEFOR0xFVFlQRV9VTktOT1dOXG4gIHwgQU5HTEVUWVBFX1VOU1BFQ0lGSUVEXG4gIHwgQU5HTEVUWVBFX0RFR1xuICB8IEFOR0xFVFlQRV9SQURcbiAgfCBBTkdMRVRZUEVfR1JBRFxuXG50eXBlIGNvbG9yVHlwZSA9XG4gIHwgQ09MT1JUWVBFX1VOS05PV05cbiAgfCBDT0xPUlRZUEVfUkdCQ09MT1JcbiAgfCBDT0xPUlRZUEVfUkdCQ09MT1JfSUNDQ09MT1JcbiAgfCBDT0xPUlRZUEVfQ1VSUkVOVENPTE9SXG5cbnR5cGUgYWxpZ25tZW50VHlwZSA9XG4gIHwgUFJFU0VSVkVBU1BFQ1RSQVRJT19VTktOT1dOXG4gIHwgUFJFU0VSVkVBU1BFQ1RSQVRJT19OT05FXG4gIHwgUFJFU0VSVkVBU1BFQ1RSQVRJT19YTUlOWU1JTlxuICB8IFBSRVNFUlZFQVNQRUNUUkFUSU9fWE1JRFlNSU5cbiAgfCBQUkVTRVJWRUFTUEVDVFJBVElPX1hNQVhZTUlOXG4gIHwgUFJFU0VSVkVBU1BFQ1RSQVRJT19YTUlOWU1JRFxuICB8IFBSRVNFUlZFQVNQRUNUUkFUSU9fWE1JRFlNSURcbiAgfCBQUkVTRVJWRUFTUEVDVFJBVElPX1hNQVhZTUlEXG4gIHwgUFJFU0VSVkVBU1BFQ1RSQVRJT19YTUlOWU1BWFxuICB8IFBSRVNFUlZFQVNQRUNUUkFUSU9fWE1JRFlNQVhcbiAgfCBQUkVTRVJWRUFTUEVDVFJBVElPX1hNQVhZTUFYXG5cbnR5cGUgbWVldE9yU2xpY2VUeXBlID1cbiAgfCBNRUVUT1JTTElDRV9VTktOT1dOXG4gIHwgTUVFVE9SU0xJQ0VfTUVFVFxuICB8IE1FRVRPUlNMSUNFX1NMSUNFXG5cbnR5cGUgdHJhbnNmb3JtVHlwZSA9XG4gIHwgVFJBTlNGT1JNX1VOS05PV05cbiAgfCBUUkFOU0ZPUk1fTUFUUklYXG4gIHwgVFJBTlNGT1JNX1RSQU5TTEFURVxuICB8IFRSQU5TRk9STV9TQ0FMRVxuICB8IFRSQU5TRk9STV9ST1RBVEVcbiAgfCBUUkFOU0ZPUk1fU0tFV1hcbiAgfCBUUkFOU0ZPUk1fU0tFV1lcblxudHlwZSB6b29tQW5kUGFuVHlwZSA9XG4gIHwgWk9PTUFORFBBTl9VTktOT1dOXG4gIHwgWk9PTUFORFBBTl9ESVNBQkxFXG4gIHwgWk9PTUFORFBBTl9NQUdOSUZZXG5cbnR5cGUgbGVuZ3RoQWRqdXN0ID1cbiAgfCBMRU5HVEhBREpVU1RfVU5LTk9XTlxuICB8IExFTkdUSEFESlVTVF9TUEFDSU5HXG4gIHwgTEVOR1RIQURKVVNUX1NQQUNJTkdBTkRHTFlQSFNcblxudHlwZSB1bml0VHlwZSA9XG4gIHwgVU5JVF9UWVBFX1VOS05PV05cbiAgfCBVTklUX1RZUEVfVVNFUlNQQUNFT05VU0VcbiAgfCBVTklUX1RZUEVfT0JKRUNUQk9VTkRJTkdCT1hcblxuKCogaW50ZXJmYWNlIFNWR1JlbmRlcmluZ0ludGVudCAqKVxudHlwZSBpbnRlbnRUeXBlID1cbiAgfCBSRU5ERVJJTkdfSU5URU5UX1VOS05PV05cbiAgfCBSRU5ERVJJTkdfSU5URU5UX0FVVE9cbiAgfCBSRU5ERVJJTkdfSU5URU5UX1BFUkNFUFRVQUxcbiAgfCBSRU5ERVJJTkdfSU5URU5UX1JFTEFUSVZFX0NPTE9SSU1FVFJJQ1xuICB8IFJFTkRFUklOR19JTlRFTlRfU0FUVVJBVElPTlxuICB8IFJFTkRFUklOR19JTlRFTlRfQUJTT0xVVEVfQ09MT1JJTUVUUklDXG5cbigqIFBhdGggU2VnbWVudCBUeXBlcyAqKVxudHlwZSBwYXRoU2VnbWVudFR5cGUgPVxuICB8IFBBVEhTRUdfVU5LTk9XTlxuICB8IFBBVEhTRUdfQ0xPU0VQQVRIXG4gIHwgUEFUSFNFR19NT1ZFVE9fQUJTXG4gIHwgUEFUSFNFR19NT1ZFVE9fUkVMXG4gIHwgUEFUSFNFR19MSU5FVE9fQUJTXG4gIHwgUEFUSFNFR19MSU5FVE9fUkVMXG4gIHwgUEFUSFNFR19DVVJWRVRPX0NVQklDX0FCU1xuICB8IFBBVEhTRUdfQ1VSVkVUT19DVUJJQ19SRUxcbiAgfCBQQVRIU0VHX0NVUlZFVE9fUVVBRFJBVElDX0FCU1xuICB8IFBBVEhTRUdfQ1VSVkVUT19RVUFEUkFUSUNfUkVMXG4gIHwgUEFUSFNFR19BUkNfQUJTXG4gIHwgUEFUSFNFR19BUkNfUkVMXG4gIHwgUEFUSFNFR19MSU5FVE9fSE9SSVpPTlRBTF9BQlNcbiAgfCBQQVRIU0VHX0xJTkVUT19IT1JJWk9OVEFMX1JFTFxuICB8IFBBVEhTRUdfTElORVRPX1ZFUlRJQ0FMX0FCU1xuICB8IFBBVEhTRUdfTElORVRPX1ZFUlRJQ0FMX1JFTFxuICB8IFBBVEhTRUdfQ1VSVkVUT19DVUJJQ19TTU9PVEhfQUJTXG4gIHwgUEFUSFNFR19DVVJWRVRPX0NVQklDX1NNT09USF9SRUxcbiAgfCBQQVRIU0VHX0NVUlZFVE9fUVVBRFJBVElDX1NNT09USF9BQlNcbiAgfCBQQVRIU0VHX0NVUlZFVE9fUVVBRFJBVElDX1NNT09USF9SRUxcblxuKCogdGV4dFBhdGggTWV0aG9kIFR5cGVzICopXG50eXBlIHRleHRQYXRoTWV0aG9kVHlwZSA9XG4gIHwgVEVYVFBBVEhfTUVUSE9EVFlQRV9VTktOT1dOXG4gIHwgVEVYVFBBVEhfTUVUSE9EVFlQRV9BTElHTlxuICB8IFRFWFRQQVRIX01FVEhPRFRZUEVfU1RSRVRDSFxuXG4oKiB0ZXh0UGF0aCBTcGFjaW5nIFR5cGVzICopXG50eXBlIHRleHRQYXRoU3BhY2luZ1R5cGUgPVxuICB8IFRFWFRQQVRIX1NQQUNJTkdUWVBFX1VOS05PV05cbiAgfCBURVhUUEFUSF9TUEFDSU5HVFlQRV9BVVRPXG4gIHwgVEVYVFBBVEhfU1BBQ0lOR1RZUEVfRVhBQ1RcblxuKCogU3ByZWFkIE1ldGhvZCBUeXBlcyAqKVxudHlwZSBzcHJlYWRNZXRob2RUeXBlID1cbiAgfCBTUFJFQURNRVRIT0RfVU5LTk9XTlxuICB8IFNQUkVBRE1FVEhPRF9QQURcbiAgfCBTUFJFQURNRVRIT0RfUkVGTEVDVFxuICB8IFNQUkVBRE1FVEhPRF9SRVBFQVRcblxudHlwZSBzdXNwZW5kSGFuZGxlSURcblxuKCoqKiopXG5cbmNsYXNzIHR5cGUgWydhXSBhbmltYXRlZCA9IG9iamVjdFxuICBtZXRob2QgYmFzZVZhbCA6ICdhIHByb3BcblxuICBtZXRob2QgYW5pbVZhbCA6ICdhIHByb3BcbmVuZFxuXG5jbGFzcyB0eXBlIFsnYV0gbGlzdCA9IG9iamVjdFxuICBtZXRob2QgbnVtYmVyT2ZJdGVtcyA6IGludCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGNsZWFyIDogdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGluaXRpYWxpemUgOiAnYSAtPiAnYSBtZXRoXG5cbiAgbWV0aG9kIGdldEl0ZW0gOiBpbnQgLT4gJ2EgbWV0aFxuXG4gIG1ldGhvZCBpbnNlcnRJdGVtQmVmb3JlIDogJ2EgLT4gaW50IC0+ICdhIG1ldGhcblxuICBtZXRob2QgcmVwbGFjZUl0ZW0gOiAnYSAtPiBpbnQgLT4gJ2EgbWV0aFxuXG4gIG1ldGhvZCByZW1vdmVJdGVtIDogaW50IC0+ICdhIG1ldGhcblxuICBtZXRob2QgYXBwZW5kSXRlbSA6ICdhIC0+ICdhIG1ldGhcbmVuZFxuXG4oKioqKilcblxuKCogaW50ZXJmYWNlIFNWR0VsZW1lbnQgKilcbmNsYXNzIHR5cGUgZWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IERvbS5lbGVtZW50XG5cbiAgbWV0aG9kIGlkIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCB4bWxiYXNlIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBvd25lclNWR0VsZW1lbnQgOiBzdmdFbGVtZW50IHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCB2aWV3cG9ydEVsZW1lbnQgOiBlbGVtZW50IHQgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdBbmltYXRlZFN0cmluZyAqKVxuYW5kIGFuaW1hdGVkU3RyaW5nID0gW2pzX3N0cmluZyB0XSBhbmltYXRlZFxuXG4oKiBpbnRlcmZhY2UgU1ZHQW5pbWF0ZWRCb29sZWFuICopXG5hbmQgYW5pbWF0ZWRCb29sZWFuID0gW2Jvb2wgdF0gYW5pbWF0ZWRcblxuKCogaW50ZXJmYWNlIFNWR1N0cmluZ0xpc3QgKilcbmFuZCBzdHJpbmdMaXN0ID0gW2pzX3N0cmluZyB0XSBsaXN0XG5cbigqIGludGVyZmFjZSBTVkdBbmltYXRlZEVudW1lcmF0aW9uICopXG5hbmQgYW5pbWF0ZWRFbnVtZXJhdGlvbiA9IFtpbnQgKCpzaG9ydCopXSBhbmltYXRlZFxuXG4oKiBpbnRlcmZhY2UgU1ZHQW5pbWF0ZWRJbnRlZ2VyICopXG5hbmQgYW5pbWF0ZWRJbnRlZ2VyID0gW2ludF0gYW5pbWF0ZWRcblxuKCogaW50ZXJmYWNlIFNWR0FuaW1hdGVkTnVtYmVyICopXG5hbmQgYW5pbWF0ZWROdW1iZXIgPSBbbnVtYmVyX3RdIGFuaW1hdGVkXG5cbigqIGludGVyZmFjZSBTVkdOdW1iZXJMaXN0ICopXG5hbmQgbnVtYmVyTGlzdCA9IFtudW1iZXIgdF0gbGlzdFxuXG4oKiBpbnRlcmZhY2UgU1ZHQW5pbWF0ZWROdW1iZXJMaXN0ICopXG5hbmQgYW5pbWF0ZWROdW1iZXJMaXN0ID0gW251bWJlckxpc3QgdF0gYW5pbWF0ZWRcblxuKCogaW50ZXJmYWNlIFNWR0xlbmd0aCAqKVxuYW5kIGxlbmd0aCA9IG9iamVjdFxuICBtZXRob2QgdW5pdFR5cGUgOiBsZW5ndGhVbml0VHlwZSByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHZhbHVlIDogbnVtYmVyX3QgcHJvcFxuXG4gIG1ldGhvZCB2YWx1ZUluU3BlY2lmaWVkVW5pdHMgOiBudW1iZXJfdCBwcm9wXG5cbiAgbWV0aG9kIHZhbHVlQXNTdHJpbmcgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIG5ld1ZhbHVlU3BlY2lmaWVkVW5pdHMgOiBsZW5ndGhVbml0VHlwZSAtPiBudW1iZXJfdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgY29udmVydFRvU3BlY2lmaWVkVW5pdHMgOiBsZW5ndGhVbml0VHlwZSAtPiB1bml0IG1ldGhcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHQW5pbWF0ZWRMZW5ndGggKilcbmFuZCBhbmltYXRlZExlbmd0aCA9IFtsZW5ndGggdF0gYW5pbWF0ZWRcblxuKCogaW50ZXJmYWNlIFNWR0xlbmd0aExpc3QgKilcbmFuZCBsZW5ndGhMaXN0ID0gW2xlbmd0aCB0XSBsaXN0XG5cbigqIGludGVyZmFjZSBTVkdBbmltYXRlZExlbmd0aExpc3QgKilcbmFuZCBhbmltYXRlZExlbmd0aExpc3QgPSBbbGVuZ3RoTGlzdCB0XSBhbmltYXRlZFxuXG4oKiBpbnRlcmZhY2UgU1ZHQW5nbGUgKilcbmFuZCBhbmdsZSA9IG9iamVjdFxuICBtZXRob2QgdW5pdFR5cGUgOiBhbmdsZVVuaXRUeXBlIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgdmFsdWUgOiBudW1iZXJfdCBwcm9wXG5cbiAgbWV0aG9kIHZhbHVlSW5TcGVjaWZpZWRVbml0cyA6IG51bWJlcl90IHByb3BcblxuICBtZXRob2QgdmFsdWVBc1N0cmluZyA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgbmV3VmFsdWVTcGVjaWZpZWRVbml0cyA6IGFuZ2xlVW5pdFR5cGUgLT4gbnVtYmVyX3QgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGNvbnZlcnRUb1NwZWNpZmllZFVuaXRzIDogYW5nbGVVbml0VHlwZSAtPiB1bml0IG1ldGhcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHQW5pbWF0ZWRBbmdsZSAqKVxuYW5kIGFuaW1hdGVkQW5nbGUgPSBbYW5nbGUgdF0gYW5pbWF0ZWRcblxuKCogWFhYWFggTW92ZSBpdCAqKVxuYW5kIHJnYkNvbG9yID0gb2JqZWN0IGVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHQ29sb3IgKilcbmFuZCBjb2xvciA9IG9iamVjdFxuICAoKiBYWFggaW5oZXJpdCBjc3NWYWx1ZSAqKVxuICBtZXRob2QgY29sb3JUeXBlIDogY29sb3JUeXBlIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgcmdiQ29sb3IgOiByZ2JDb2xvciB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgaWNjQ29sb3IgOiBpY2NDb2xvciB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgc2V0UkdCQ29sb3IgOiBqc19zdHJpbmcgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgc2V0UkdCQ29sb3JJQ0NDb2xvciA6IGpzX3N0cmluZyB0IC0+IGpzX3N0cmluZyB0IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBzZXRDb2xvciA6IGNvbG9yVHlwZSAtPiBqc19zdHJpbmcgdCAtPiBqc19zdHJpbmcgdCAtPiB1bml0IG1ldGhcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHSUNDQ29sb3IgKilcbmFuZCBpY2NDb2xvciA9IG9iamVjdFxuICBtZXRob2QgY29sb3JQcm9maWxlIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBjb2xvcnMgOiBudW1iZXJMaXN0IHQgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdSZWN0ICopXG5hbmQgcmVjdCA9IG9iamVjdFxuICBtZXRob2QgeCA6IG51bWJlcl90IHByb3BcblxuICBtZXRob2QgeSA6IG51bWJlcl90IHByb3BcblxuICBtZXRob2Qgd2lkdGggOiBudW1iZXJfdCBwcm9wXG5cbiAgbWV0aG9kIGhlaWdodCA6IG51bWJlcl90IHByb3BcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHQW5pbWF0ZWRSZWN0ICopXG5hbmQgYW5pbWF0ZWRSZWN0ID0gW3JlY3QgdF0gYW5pbWF0ZWRcblxuKCogaW50ZXJmYWNlIFNWR1N0eWxhYmxlICopXG5hbmQgc3R5bGFibGUgPSBvYmplY3RcbiAgbWV0aG9kIGNsYXNzTmFtZSA6IGFuaW1hdGVkU3RyaW5nIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBzdHlsZSA6IERvbV9odG1sLmNzc1N0eWxlRGVjbGFyYXRpb24gdCByZWFkb25seV9wcm9wXG4gICgqICAgQ1NTVmFsdWUgZ2V0UHJlc2VudGF0aW9uQXR0cmlidXRlKGluIERPTVN0cmluZyBuYW1lKTsgKilcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHTG9jYXRhYmxlICopXG5hbmQgbG9jYXRhYmxlID0gb2JqZWN0XG4gIG1ldGhvZCBuZWFyZXN0Vmlld3BvcnRFbGVtZW50IDogZWxlbWVudCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZmFydGhlc3RWaWV3cG9ydEVsZW1lbnQgOiBlbGVtZW50IHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBnZXRCQm94IDogcmVjdCB0IG1ldGhcblxuICBtZXRob2QgZ2V0Q1RNIDogbWF0cml4IHQgbWV0aFxuXG4gIG1ldGhvZCBnZXRTY3JlZW5DVE0gOiBtYXRyaXggdCBtZXRoXG5cbiAgbWV0aG9kIGdldFRyYW5zZm9ybVRvRWxlbWVudCA6IGVsZW1lbnQgdCAtPiBtYXRyaXggdCBtZXRoXG5lbmRcblxuKCogaW50ZXJmYWNlIFNWR1RyYW5zZm9ybWFibGUgKilcbmFuZCB0cmFuc2Zvcm1hYmxlID0gb2JqZWN0XG4gIGluaGVyaXQgbG9jYXRhYmxlXG5cbiAgbWV0aG9kIHRyYW5zZm9ybSA6IGFuaW1hdGVkVHJhbnNmb3JtTGlzdCB0IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHVGVzdHMgKilcbmFuZCB0ZXN0cyA9IG9iamVjdFxuICBtZXRob2QgcmVxdWlyZWRGZWF0dXJlcyA6IHN0cmluZ0xpc3QgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHJlcXVpcmVkRXh0ZW5zaW9ucyA6IHN0cmluZ0xpc3QgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHN5c3RlbUxhbmd1YWdlIDogc3RyaW5nTGlzdCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgaGFzRXh0ZW5zaW9uIDoganNfc3RyaW5nIHQgLT4gYm9vbCB0IG1ldGhcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHTGFuZ1NwYWNlICopXG5hbmQgbGFuZ1NwYWNlID0gb2JqZWN0XG4gIG1ldGhvZCB4bWxsYW5nIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCB4bWxzcGFjZSA6IGpzX3N0cmluZyB0IHByb3BcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHRXh0ZXJuYWxSZXNvdXJjZXNSZXF1aXJlZCAqKVxuYW5kIGV4dGVybmFsUmVzb3VyY2VzUmVxdWlyZWQgPSBvYmplY3RcbiAgbWV0aG9kIGV4dGVybmFsUmVzb3VyY2VzUmVxdWlyZWQgOiBhbmltYXRlZEJvb2xlYW4gdCByZWFkb25seV9wcm9wXG5lbmRcblxuKCogaW50ZXJmYWNlIFNWR0ZpdFRvVmlld0JveCAqKVxuYW5kIGZpdFRvVmlld0JveCA9IG9iamVjdFxuICBtZXRob2Qgdmlld0JveCA6IGFuaW1hdGVkUmVjdCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgcHJlc2VydmVBc3BlY3RSYXRpbyA6IGFuaW1hdGVkUHJlc2VydmVBc3BlY3RSYXRpbyB0IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHWm9vbUFuZFBhbiAqKVxuYW5kIHpvb21BbmRQYW4gPSBvYmplY3RcbiAgbWV0aG9kIHpvb21BbmRQYW4gOiB6b29tQW5kUGFuVHlwZSBwcm9wXG5lbmRcblxuKCogaW50ZXJmYWNlIFNWR1ZpZXdTcGVjICopXG5hbmQgdmlld1NwZWMgPSBvYmplY3RcbiAgaW5oZXJpdCB6b29tQW5kUGFuXG5cbiAgaW5oZXJpdCBmaXRUb1ZpZXdCb3hcblxuICBtZXRob2QgdHJhbnNmb3JtIDogdHJhbnNmb3JtTGlzdCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgdmlld1RhcmdldCA6IGVsZW1lbnQgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHZpZXdCb3hTdHJpbmcgOiBqc19zdHJpbmcgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHByZXNlcnZlQXNwZWN0UmF0aW9TdHJpbmcgOiBqc19zdHJpbmcgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHRyYW5zZm9ybVN0cmluZyA6IGpzX3N0cmluZyB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgdmlld1RhcmdldFN0cmluZyA6IGpzX3N0cmluZyB0IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHVVJJUmVmZXJlbmNlICopXG5hbmQgdXJpUmVmZXJlbmNlID0gb2JqZWN0XG4gIG1ldGhvZCBocmVmIDogYW5pbWF0ZWRTdHJpbmcgdCByZWFkb25seV9wcm9wXG5lbmRcblxuKCogaW50ZXJmYWNlIFNWR0NTU1J1bGUgOiBDU1NSdWxlICopXG4oKiAgIGNvbnN0IHVuc2lnbmVkIHNob3J0IENPTE9SX1BST0ZJTEVfUlVMRSA9IDc7ICopXG4oKiB9OyAqKVxuXG4oKiBpbnRlcmZhY2UgU1ZHRG9jdW1lbnQgKilcbmFuZCBkb2N1bWVudCA9IG9iamVjdFxuICBpbmhlcml0IFtlbGVtZW50XSBEb20uZG9jdW1lbnRcblxuICAoKlhYWCBpbmhlcml0IGRvY3VtZW50RXZlbnQgKilcbiAgbWV0aG9kIHRpdGxlIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCByZWZlcnJlciA6IGpzX3N0cmluZyB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZG9tYWluIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBfVVJMIDoganNfc3RyaW5nIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCByb290RWxlbWVudCA6IHN2Z0VsZW1lbnQgdCBvcHQgcmVhZG9ubHlfcHJvcFxuICAoKiByb290RWxlbWVudCB3aWxsIGJlIG51bGwgb3IgdW5kZWZpbmVkIGluIGFuIGh0bWwgY29udGV4dCAqKVxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdTVkdFbGVtZW50ICopXG5hbmQgc3ZnRWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBpbmhlcml0IHRlc3RzXG5cbiAgaW5oZXJpdCBsYW5nU3BhY2VcblxuICBpbmhlcml0IGV4dGVybmFsUmVzb3VyY2VzUmVxdWlyZWRcblxuICBpbmhlcml0IHN0eWxhYmxlXG5cbiAgaW5oZXJpdCBsb2NhdGFibGVcblxuICBpbmhlcml0IGZpdFRvVmlld0JveFxuXG4gIGluaGVyaXQgem9vbUFuZFBhblxuXG4gICgqWFhYIGluaGVyaXQgZG9jdW1lbnRldmVudCwgdmlld2NzcywgZG9jdW1lbnRjc3MgKilcbiAgbWV0aG9kIHggOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgeSA6IGFuaW1hdGVkTGVuZ3RoIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCB3aWR0aCA6IGFuaW1hdGVkTGVuZ3RoIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBoZWlnaHQgOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgY29udGVudFNjcmlwdFR5cGUgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGNvbnRlbnRTdHlsZVR5cGUgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHZpZXdwb3J0IDogcmVjdCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgcGl4ZWxVbml0VG9NaWxsaW1ldGVyWCA6IG51bWJlcl90IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgcGl4ZWxVbml0VG9NaWxsaW1ldGVyWSA6IG51bWJlcl90IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgc2NyZWVuUGl4ZWxVbml0VG9NaWxsaW1ldGVyWCA6IG51bWJlcl90IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgc2NyZWVuUGl4ZWxVbml0VG9NaWxsaW1ldGVyWSA6IG51bWJlcl90IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgdXNlQ3VycmVudFZpZXcgOiBib29sIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBjdXJyZW50VmlldyA6IHZpZXdTcGVjIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBjdXJyZW50U2NhbGUgOiBudW1iZXJfdCBwcm9wXG5cbiAgbWV0aG9kIGN1cnJlbnRUcmFuc2xhdGUgOiBwb2ludCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgc3VzcGVuZFJlZHJhdyA6IGludCAtPiBzdXNwZW5kSGFuZGxlSUQgbWV0aFxuXG4gIG1ldGhvZCB1bnN1c3BlbmRSZWRyYXcgOiBzdXNwZW5kSGFuZGxlSUQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHVuc3VzcGVuZFJlZHJhd0FsbCA6IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBmb3JjZVJlZHJhdyA6IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBwYXVzZUFuaW1hdGlvbnMgOiB1bml0IG1ldGhcblxuICBtZXRob2QgdW5wYXVzZUFuaW1hdGlvbnMgOiB1bml0IG1ldGhcblxuICBtZXRob2QgYW5pbWF0aW9uc1BhdXNlZCA6IGJvb2wgdCBtZXRoXG5cbiAgbWV0aG9kIGdldEN1cnJlbnRUaW1lIDogbnVtYmVyX3QgbWV0aFxuXG4gIG1ldGhvZCBzZXRDdXJyZW50VGltZSA6IGludCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgZ2V0SW50ZXJzZWN0aW9uTGlzdCA6IHJlY3QgdCAtPiBlbGVtZW50IHQgLT4gZWxlbWVudCBEb20ubm9kZUxpc3QgdCBtZXRoXG5cbiAgbWV0aG9kIGdldEVuY2xvc3VyZUxpc3QgOiByZWN0IHQgLT4gZWxlbWVudCB0IC0+IGVsZW1lbnQgRG9tLm5vZGVMaXN0IHQgbWV0aFxuXG4gIG1ldGhvZCBjaGVja0ludGVyc2VjdGlvbiA6IGVsZW1lbnQgdCAtPiByZWN0IHQgLT4gYm9vbCB0XG5cbiAgbWV0aG9kIGNoZWNrRW5jbG9zdXJlIDogZWxlbWVudCB0IC0+IHJlY3QgdCAtPiBib29sIHRcblxuICBtZXRob2QgZGVzZWxlY3RBbGwgOiB1bml0IG1ldGhcblxuICBtZXRob2QgY3JlYXRlU1ZHTnVtYmVyIDogbnVtYmVyIHQgbWV0aFxuXG4gIG1ldGhvZCBjcmVhdGVTVkdMZW5ndGggOiBsZW5ndGggdCBtZXRoXG5cbiAgbWV0aG9kIGNyZWF0ZVNWR0FuZ2xlIDogYW5nbGUgdCBtZXRoXG5cbiAgbWV0aG9kIGNyZWF0ZVNWR1BvaW50IDogcG9pbnQgdCBtZXRoXG5cbiAgbWV0aG9kIGNyZWF0ZVNWR01hdHJpeCA6IG1hdHJpeCB0IG1ldGhcblxuICBtZXRob2QgY3JlYXRlU1ZHUmVjdCA6IHJlY3QgdCBtZXRoXG5cbiAgbWV0aG9kIGNyZWF0ZVNWR1RyYW5zZm9ybSA6IHRyYW5zZm9ybSB0IG1ldGhcblxuICBtZXRob2QgY3JlYXRlU1ZHVHJhbnNmb3JtRnJvbU1hdHJpeCA6IG1hdHJpeCB0IC0+IHRyYW5zZm9ybSB0IG1ldGhcblxuICBtZXRob2QgZ2V0RWxlbWVudEJ5SWQgOiBqc19zdHJpbmcgdCAtPiBEb20uZWxlbWVudCB0IG1ldGhcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHR0VsZW1lbnQgKilcbmFuZCBnRWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBpbmhlcml0IHRlc3RzXG5cbiAgaW5oZXJpdCBsYW5nU3BhY2VcblxuICBpbmhlcml0IGV4dGVybmFsUmVzb3VyY2VzUmVxdWlyZWRcblxuICBpbmhlcml0IHN0eWxhYmxlXG5cbiAgaW5oZXJpdCB0cmFuc2Zvcm1hYmxlXG5cbiAgaW5oZXJpdCBEb21faHRtbC5ldmVudFRhcmdldFxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdEZWZzRWxlbWVudCAqKVxuYW5kIGRlZnNFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIGluaGVyaXQgdGVzdHNcblxuICBpbmhlcml0IGxhbmdTcGFjZVxuXG4gIGluaGVyaXQgZXh0ZXJuYWxSZXNvdXJjZXNSZXF1aXJlZFxuXG4gIGluaGVyaXQgc3R5bGFibGVcblxuICBpbmhlcml0IHRyYW5zZm9ybWFibGVcbiAgKCogWFhYWFhYWCA/IGluaGVyaXQgRG9tX2h0bWwuZXZlbnRUYXJnZXQgKilcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHRGVzY0VsZW1lbnQgKilcbmFuZCBkZXNjRWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBpbmhlcml0IGxhbmdTcGFjZVxuXG4gIGluaGVyaXQgc3R5bGFibGVcbiAgKCogWFhYWFhYWCA/IGluaGVyaXQgRG9tX2h0bWwuZXZlbnRUYXJnZXQgKilcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHVGl0bGVFbGVtZW50ICopXG5hbmQgdGl0bGVFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIGluaGVyaXQgbGFuZ1NwYWNlXG5cbiAgaW5oZXJpdCBzdHlsYWJsZVxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdTeW1ib2xFbGVtZW50ICopXG5hbmQgc3ltYm9sRWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBpbmhlcml0IGxhbmdTcGFjZVxuXG4gIGluaGVyaXQgZXh0ZXJuYWxSZXNvdXJjZXNSZXF1aXJlZFxuXG4gIGluaGVyaXQgc3R5bGFibGVcblxuICBpbmhlcml0IGZpdFRvVmlld0JveFxuXG4gIGluaGVyaXQgRG9tX2h0bWwuZXZlbnRUYXJnZXRcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHVXNlRWxlbWVudCAqKVxuYW5kIHVzZUVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgaW5oZXJpdCB1cmlSZWZlcmVuY2VcblxuICBpbmhlcml0IHRlc3RzXG5cbiAgaW5oZXJpdCBsYW5nU3BhY2VcblxuICBpbmhlcml0IGV4dGVybmFsUmVzb3VyY2VzUmVxdWlyZWRcblxuICBpbmhlcml0IHN0eWxhYmxlXG5cbiAgaW5oZXJpdCB0cmFuc2Zvcm1hYmxlXG5cbiAgbWV0aG9kIHggOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgeSA6IGFuaW1hdGVkTGVuZ3RoIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCB3aWR0aCA6IGFuaW1hdGVkTGVuZ3RoIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBoZWlnaHQgOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgaW5zdGFuY2VSb290IDogZWxlbWVudEluc3RhbmNlIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBhbmltYXRlZEluc3RhbmNlUm9vdCA6IGVsZW1lbnRJbnN0YW5jZSB0IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG5hbmQgZWxlbWVudEluc3RhbmNlID0gb2JqZWN0XG4gIGluaGVyaXQgRG9tX2h0bWwuZXZlbnRUYXJnZXRcblxuICBtZXRob2QgY29ycmVzcG9uZGluZ0VsZW1lbnQgOiBlbGVtZW50IHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBjb3JyZXNwb25kaW5nVXNlRWxlbWVudCA6IHVzZUVsZW1lbnQgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHBhcmVudE5vZGUgOiBlbGVtZW50SW5zdGFuY2UgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGNoaWxkTm9kZXMgOiBlbGVtZW50SW5zdGFuY2VMaXN0IHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBmaXJzdENoaWxkIDogZWxlbWVudEluc3RhbmNlIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBsYXN0Q2hpbGQgOiBlbGVtZW50SW5zdGFuY2UgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHByZXZpb3VzU2libGluZyA6IGVsZW1lbnRJbnN0YW5jZSB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgbmV4dFNpYmxpbmcgOiBlbGVtZW50SW5zdGFuY2UgdCByZWFkb25seV9wcm9wXG5lbmRcblxuKCogaW50ZXJmYWNlIFNWR0VsZW1lbnRJbnN0YW5jZUxpc3QgKilcbmFuZCBlbGVtZW50SW5zdGFuY2VMaXN0ID0gb2JqZWN0XG4gIG1ldGhvZCBsZW5ndGggOiBpbnQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBpdGVtIDogaW50IC0+IGVsZW1lbnRJbnN0YW5jZSB0XG5lbmRcblxuKCogaW50ZXJmYWNlIFNWR0ltYWdlRWxlbWVudCAqKVxuYW5kIGltYWdlRWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBpbmhlcml0IHVyaVJlZmVyZW5jZVxuXG4gIGluaGVyaXQgdGVzdHNcblxuICBpbmhlcml0IGxhbmdTcGFjZVxuXG4gIGluaGVyaXQgZXh0ZXJuYWxSZXNvdXJjZXNSZXF1aXJlZFxuXG4gIGluaGVyaXQgc3R5bGFibGVcblxuICBpbmhlcml0IHRyYW5zZm9ybWFibGVcblxuICBtZXRob2QgeCA6IGFuaW1hdGVkTGVuZ3RoIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCB5IDogYW5pbWF0ZWRMZW5ndGggdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHdpZHRoIDogYW5pbWF0ZWRMZW5ndGggdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGhlaWdodCA6IGFuaW1hdGVkTGVuZ3RoIHQgcmVhZG9ubHlfcHJvcFxuICAoKiByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWRQcmVzZXJ2ZUFzcGVjdFJhdGlvIHByZXNlcnZlQXNwZWN0UmF0aW8gKilcbmVuZFxuXG5hbmQgc3dpdGNoRWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBpbmhlcml0IHRlc3RzXG5cbiAgaW5oZXJpdCBsYW5nU3BhY2VcblxuICBpbmhlcml0IGV4dGVybmFsUmVzb3VyY2VzUmVxdWlyZWRcblxuICBpbmhlcml0IHN0eWxhYmxlXG5cbiAgaW5oZXJpdCB0cmFuc2Zvcm1hYmxlXG5lbmRcblxuKCogWFhYIGRlcHJlY2F0ZWQgPT4gaW50ZXJmYWNlIEdldFNWR0RvY3VtZW50ID0+IFNWR0RvY3VtZW50IGdldFNWR0RvY3VtZW50KCkgKilcblxuKCogaW50ZXJmYWNlIFNWR1N0eWxlRWxlbWVudCAqKVxuYW5kIHN0eWxlRWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBpbmhlcml0IGxhbmdTcGFjZVxuXG4gIG1ldGhvZCB0eXBlXyA6IGpzX3N0cmluZyB0IHByb3BcblxuICBtZXRob2QgbWVkaWEgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHRpdGxlIDoganNfc3RyaW5nIHQgcHJvcFxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdQb2ludCAqKVxuYW5kIHBvaW50ID0gb2JqZWN0XG4gIG1ldGhvZCB4IDogbnVtYmVyX3QgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCB5IDogbnVtYmVyX3QgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBtYXRyaXhUcmFuc2Zvcm0gOiBtYXRyaXggdCAtPiBwb2ludCB0IG1ldGhcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHUG9pbnRMaXN0ICopXG5hbmQgcG9pbnRMaXN0ID0gW3BvaW50IHRdIGxpc3RcblxuKCogaW50ZXJmYWNlIFNWR01hdHJpeCAqKVxuYW5kIG1hdHJpeCA9IG9iamVjdFxuICBtZXRob2QgYSA6IG51bWJlcl90IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgYiA6IG51bWJlcl90IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgYyA6IG51bWJlcl90IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZCA6IG51bWJlcl90IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZSA6IG51bWJlcl90IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZiA6IG51bWJlcl90IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgbXVsdGlwbHkgOiBtYXRyaXggdCAtPiBtYXRyaXggdCBtZXRoXG5cbiAgbWV0aG9kIGludmVyc2UgOiBtYXRyaXggdCBtZXRoXG5cbiAgbWV0aG9kIHRyYW5zbGF0ZSA6IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG1hdHJpeCB0IG1ldGhcblxuICBtZXRob2Qgc2NhbGUgOiBudW1iZXJfdCAtPiBtYXRyaXggdCBtZXRoXG5cbiAgbWV0aG9kIHNjYWxlTm9uVW5pZm9ybSA6IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG1hdHJpeCB0IG1ldGhcblxuICBtZXRob2Qgcm90YXRlIDogbnVtYmVyX3QgLT4gbWF0cml4IHQgbWV0aFxuXG4gIG1ldGhvZCByb3RhdGVGcm9tVmVjdG9yIDogbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbWF0cml4IHQgbWV0aFxuXG4gIG1ldGhvZCBmbGlwWCA6IG1hdHJpeCB0IG1ldGhcblxuICBtZXRob2QgZmxpcFkgOiBtYXRyaXggdCBtZXRoXG5cbiAgbWV0aG9kIHNrZXdYIDogbnVtYmVyX3QgLT4gbWF0cml4IHQgbWV0aFxuXG4gIG1ldGhvZCBza2V3WSA6IG51bWJlcl90IC0+IG1hdHJpeCB0IG1ldGhcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHVHJhbnNmb3JtICopXG5hbmQgdHJhbnNmb3JtID0gb2JqZWN0XG4gIG1ldGhvZCBfdHlwZSA6IHRyYW5zZm9ybVR5cGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBtYXRyaXggOiBtYXRyaXggdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGFuZ2xlIDogbnVtYmVyX3QgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBzZXRNYXRyaXggOiBtYXRyaXggdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgc2V0VHJhbnNsYXRlIDogbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHNldFNjYWxlIDogbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHNldFJvdGF0ZSA6IG51bWJlcl90IC0+IG51bWJlcl90IC0+IG51bWJlcl90IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBzZXRTa2V3WCA6IG51bWJlcl90IC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBzZXRTa2V3WSA6IG51bWJlcl90IC0+IHVuaXQgbWV0aFxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdUcmFuc2Zvcm1MaXN0ICopXG5hbmQgdHJhbnNmb3JtTGlzdCA9IG9iamVjdFxuICBpbmhlcml0IFt0cmFuc2Zvcm0gdF0gbGlzdFxuXG4gIG1ldGhvZCBjcmVhdGVTVkdUcmFuc2Zvcm1Gcm9tTWF0cml4IDogbWF0cml4IC0+IHRyYW5zZm9ybSB0IG1ldGhcblxuICBtZXRob2QgY29uc29saWRhdGUgOiB0cmFuc2Zvcm0gdCBtZXRoXG5lbmRcblxuKCogaW50ZXJmYWNlIFNWR0FuaW1hdGVkVHJhbnNmb3JtTGlzdCAqKVxuYW5kIGFuaW1hdGVkVHJhbnNmb3JtTGlzdCA9IFt0cmFuc2Zvcm1MaXN0IHRdIGFuaW1hdGVkXG5cbigqIGludGVyZmFjZSBTVkdQcmVzZXJ2ZUFzcGVjdFJhdGlvICopXG5hbmQgcHJlc2VydmVBc3BlY3RSYXRpbyA9IG9iamVjdFxuICBtZXRob2QgYWxpZ24gOiBhbGlnbm1lbnRUeXBlIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgbWVldE9yU2xpY2UgOiBtZWV0T3JTbGljZVR5cGUgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdBbmltYXRlZFByZXNlcnZlQXNwZWN0UmF0aW8gKilcbmFuZCBhbmltYXRlZFByZXNlcnZlQXNwZWN0UmF0aW8gPSBbcHJlc2VydmVBc3BlY3RSYXRpbyB0XSBhbmltYXRlZFxuXG4oKiBpbnRlcmZhY2UgU1ZHUGF0aFNlZyAqKVxuYW5kIHBhdGhTZWcgPSBvYmplY3RcbiAgbWV0aG9kIHBhdGhTZWdUeXBlIDogcGF0aFNlZ21lbnRUeXBlIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgcGF0aFNlZ1R5cGVBc0xldHRlciA6IGpzX3N0cmluZyB0IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHUGF0aFNlZ0Nsb3NlUGF0aCAqKVxuYW5kIHBhdGhTZWdDbG9zZVBhdGggPSBwYXRoU2VnXG5cbigqIGludGVyZmFjZSBTVkdQYXRoU2VnTW92ZXRvQWJzICopXG4oKiBpbnRlcmZhY2UgU1ZHUGF0aFNlZ01vdmV0b1JlbCAqKVxuYW5kIHBhdGhTZWdNb3ZldG8gPSBvYmplY3RcbiAgaW5oZXJpdCBwYXRoU2VnXG5cbiAgbWV0aG9kIHggOiBudW1iZXJfdCBwcm9wXG5cbiAgbWV0aG9kIHkgOiBudW1iZXJfdCBwcm9wXG5lbmRcblxuKCogaW50ZXJmYWNlIFNWR1BhdGhTZWdMaW5ldG9BYnMgKilcbigqIGludGVyZmFjZSBTVkdQYXRoU2VnTGluZXRvUmVsICopXG5hbmQgcGF0aFNlZ0xpbmV0byA9IG9iamVjdFxuICBpbmhlcml0IHBhdGhTZWdcblxuICBtZXRob2QgeCA6IG51bWJlcl90IHByb3BcblxuICBtZXRob2QgeSA6IG51bWJlcl90IHByb3BcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHUGF0aFNlZ0N1cnZldG9DdWJpY0FicyAqKVxuKCogaW50ZXJmYWNlIFNWR1BhdGhTZWdDdXJ2ZXRvQ3ViaWNSZWwgKilcbmFuZCBwYXRoU2VnQ3VydmV0b0N1YmljID0gb2JqZWN0XG4gIGluaGVyaXQgcGF0aFNlZ1xuXG4gIG1ldGhvZCB4IDogbnVtYmVyX3QgcHJvcFxuXG4gIG1ldGhvZCB5IDogbnVtYmVyX3QgcHJvcFxuXG4gIG1ldGhvZCB4MSA6IG51bWJlcl90IHByb3BcblxuICBtZXRob2QgeTEgOiBudW1iZXJfdCBwcm9wXG5cbiAgbWV0aG9kIHgyIDogbnVtYmVyX3QgcHJvcFxuXG4gIG1ldGhvZCB5MiA6IG51bWJlcl90IHByb3BcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHUGF0aFNlZ0N1cnZldG9RdWFkcmF0aWNBYnMgKilcbigqIGludGVyZmFjZSBTVkdQYXRoU2VnQ3VydmV0b1F1YWRyYXRpY1JlbCAqKVxuYW5kIHBhdGhTZWdDdXJ2ZXRvUXVhZHJhdGljID0gb2JqZWN0XG4gIGluaGVyaXQgcGF0aFNlZ1xuXG4gIG1ldGhvZCB4IDogbnVtYmVyX3QgcHJvcFxuXG4gIG1ldGhvZCB5IDogbnVtYmVyX3QgcHJvcFxuXG4gIG1ldGhvZCB4MSA6IG51bWJlcl90IHByb3BcblxuICBtZXRob2QgeTEgOiBudW1iZXJfdCBwcm9wXG5lbmRcblxuKCogaW50ZXJmYWNlIFNWR1BhdGhTZWdBcmNBYnMgKilcbigqIGludGVyZmFjZSBTVkdQYXRoU2VnQXJjUmVsKilcbmFuZCBwYXRoU2VnQXJjID0gb2JqZWN0XG4gIGluaGVyaXQgcGF0aFNlZ1xuXG4gIG1ldGhvZCB5IDogbnVtYmVyX3QgcHJvcFxuXG4gIG1ldGhvZCByMSA6IG51bWJlcl90IHByb3BcblxuICBtZXRob2QgcjIgOiBudW1iZXJfdCBwcm9wXG5cbiAgbWV0aG9kIGFuZ2xlIDogbnVtYmVyX3QgcHJvcFxuXG4gIG1ldGhvZCBsYXJnZUFyY0ZsYWcgOiBib29sIHQgcHJvcFxuXG4gIG1ldGhvZCBzd2VlcEZsYWcgOiBib29sIHQgcHJvcFxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdQYXRoU2VnTGluZXRvSG9yaXpvbnRhbEFicyAqKVxuKCogaW50ZXJmYWNlIFNWR1BhdGhTZWdMaW5ldG9Ib3Jpem9udGFsUmVsICopXG5hbmQgcGF0aFNlZ0xpbmV0b0hvcml6b250YWwgPSBvYmplY3RcbiAgaW5oZXJpdCBwYXRoU2VnXG5cbiAgbWV0aG9kIHggOiBudW1iZXJfdFxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdQYXRoU2VnTGluZXRvVmVydGljYWxBYnMgKilcbigqIGludGVyZmFjZSBTVkdQYXRoU2VnTGluZXRvVmVydGljYWxSZWwgKilcbmFuZCBwYXRoU2VnTGluZXRvVmVydGljYWwgPSBvYmplY3RcbiAgaW5oZXJpdCBwYXRoU2VnXG5cbiAgbWV0aG9kIHkgOiBudW1iZXJfdFxuZW5kXG5cbmFuZCBwYXRoU2VnQ3VydmV0b0N1YmljU21vb3RoID0gb2JqZWN0XG4gIGluaGVyaXQgcGF0aFNlZ1xuXG4gIG1ldGhvZCB4IDogbnVtYmVyX3RcblxuICBtZXRob2QgeSA6IG51bWJlcl90XG5cbiAgbWV0aG9kIHgyIDogbnVtYmVyX3RcblxuICBtZXRob2QgeTIgOiBudW1iZXJfdFxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdQYXRoU2VnQ3VydmV0b1F1YWRyYXRpY1Ntb290aEFicyAqKVxuKCogaW50ZXJmYWNlIFNWR1BhdGhTZWdDdXJ2ZXRvUXVhZHJhdGljU21vb3RoUmVsICAqKVxuYW5kIHBhdGhTZWdDdXJ2ZXRvUXVhZHJhdGljU21vb3RoID0gb2JqZWN0XG4gIGluaGVyaXQgcGF0aFNlZ1xuXG4gIG1ldGhvZCB4IDogbnVtYmVyX3RcblxuICBtZXRob2QgeSA6IG51bWJlcl90XG5lbmRcblxuYW5kIHBhdGhTZWdMaXN0ID0gW3BhdGhTZWcgdF0gbGlzdFxuXG4oKiBpbnRlcmZhY2UgU1ZHQW5pbWF0ZWRQYXRoRGF0YSAqKVxuYW5kIGFuaW1hdGVkUGF0aERhdGEgPSBvYmplY3RcbiAgbWV0aG9kIHBhdGhTZWdMaXN0IDogcGF0aFNlZ0xpc3QgdCBwcm9wXG5cbiAgbWV0aG9kIG5vcm1hbGl6ZWRQYXRoU2VnTGlzdCA6IHBhdGhTZWdMaXN0IHQgcHJvcFxuXG4gIG1ldGhvZCBhbmltYXRlZFBhdGhTZWdMaXN0IDogcGF0aFNlZ0xpc3QgdCBwcm9wXG5cbiAgbWV0aG9kIGFuaW1hdGVkTm9ybWFsaXplZFBhdGhTZWdMaXN0IDogcGF0aFNlZ0xpc3QgdCBwcm9wXG5lbmRcblxuKCogaW50ZXJmYWNlIFNWR1BhdGhFbGVtZW50ICopXG5hbmQgcGF0aEVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgaW5oZXJpdCB0ZXN0c1xuXG4gIGluaGVyaXQgbGFuZ1NwYWNlXG5cbiAgaW5oZXJpdCBleHRlcm5hbFJlc291cmNlc1JlcXVpcmVkXG5cbiAgaW5oZXJpdCBzdHlsYWJsZVxuXG4gIGluaGVyaXQgdHJhbnNmb3JtYWJsZVxuXG4gIGluaGVyaXQgYW5pbWF0ZWRQYXRoRGF0YVxuXG4gIG1ldGhvZCBwYXRoTGVuZ3RoIDogYW5pbWF0ZWROdW1iZXIgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGdldFRvdGFsTGVuZ3RoIDogbnVtYmVyX3QgbWV0aFxuXG4gIG1ldGhvZCBnZXRQb2ludEF0TGVuZ3RoIDogbnVtYmVyX3QgLT4gcG9pbnQgdCBtZXRoXG5cbiAgbWV0aG9kIGdldFBhdGhTZWdBdExlbmd0aCA6IG51bWJlcl90IC0+IGludFxuXG4gIG1ldGhvZCBjcmVhdGVTVkdQYXRoU2VnQ2xvc2VQYXRoIDogcGF0aFNlZ0Nsb3NlUGF0aCBtZXRoXG5cbiAgbWV0aG9kIGNyZWF0ZVNWR1BhdGhTZWdNb3ZldG9BYnMgOiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBwYXRoU2VnTW92ZXRvIG1ldGhcblxuICBtZXRob2QgY3JlYXRlU1ZHUGF0aFNlZ01vdmV0b1JlbCA6IG51bWJlcl90IC0+IG51bWJlcl90IC0+IHBhdGhTZWdNb3ZldG8gbWV0aFxuXG4gIG1ldGhvZCBjcmVhdGVTVkdQYXRoU2VnTGluZXRvQWJzIDogbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gcGF0aFNlZ0xpbmV0byBtZXRoXG5cbiAgbWV0aG9kIGNyZWF0ZVNWR1BhdGhTZWdMaW5ldG9SZWwgOiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBwYXRoU2VnTGluZXRvIG1ldGhcblxuICBtZXRob2QgY3JlYXRlU1ZHUGF0aFNlZ0N1cnZldG9DdWJpY0FicyA6XG4gICAgICAgbnVtYmVyX3RcbiAgICAtPiBudW1iZXJfdFxuICAgIC0+IG51bWJlcl90XG4gICAgLT4gbnVtYmVyX3RcbiAgICAtPiBudW1iZXJfdFxuICAgIC0+IG51bWJlcl90XG4gICAgLT4gcGF0aFNlZ0N1cnZldG9DdWJpYyBtZXRoXG5cbiAgbWV0aG9kIGNyZWF0ZVNWR1BhdGhTZWdDdXJ2ZXRvQ3ViaWNSZWwgOlxuICAgICAgIG51bWJlcl90XG4gICAgLT4gbnVtYmVyX3RcbiAgICAtPiBudW1iZXJfdFxuICAgIC0+IG51bWJlcl90XG4gICAgLT4gbnVtYmVyX3RcbiAgICAtPiBudW1iZXJfdFxuICAgIC0+IHBhdGhTZWdDdXJ2ZXRvQ3ViaWMgbWV0aFxuXG4gIG1ldGhvZCBjcmVhdGVTVkdQYXRoU2VnQ3VydmV0b1F1YWRyYXRpY0FicyA6XG4gICAgbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gcGF0aFNlZ0N1cnZldG9RdWFkcmF0aWMgbWV0aFxuXG4gIG1ldGhvZCBjcmVhdGVTVkdQYXRoU2VnQ3VydmV0b1F1YWRyYXRpY1JlbCA6XG4gICAgbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gcGF0aFNlZ0N1cnZldG9RdWFkcmF0aWMgbWV0aFxuXG4gIG1ldGhvZCBjcmVhdGVTVkdQYXRoU2VnQXJjQWJzIDpcbiAgICAgICBudW1iZXJfdFxuICAgIC0+IG51bWJlcl90XG4gICAgLT4gbnVtYmVyX3RcbiAgICAtPiBudW1iZXJfdFxuICAgIC0+IG51bWJlcl90XG4gICAgLT4gYm9vbCB0XG4gICAgLT4gYm9vbCB0XG4gICAgLT4gcGF0aFNlZ0FyYyBtZXRoXG5cbiAgbWV0aG9kIGNyZWF0ZVNWR1BhdGhTZWdBcmNSZWwgOlxuICAgICAgIG51bWJlcl90XG4gICAgLT4gbnVtYmVyX3RcbiAgICAtPiBudW1iZXJfdFxuICAgIC0+IG51bWJlcl90XG4gICAgLT4gbnVtYmVyX3RcbiAgICAtPiBib29sIHRcbiAgICAtPiBib29sIHRcbiAgICAtPiBwYXRoU2VnQXJjIG1ldGhcblxuICBtZXRob2QgY3JlYXRlU1ZHUGF0aFNlZ0xpbmV0b0hvcml6b250YWxBYnMgOiBudW1iZXJfdCAtPiBwYXRoU2VnTGluZXRvSG9yaXpvbnRhbCBtZXRoXG5cbiAgbWV0aG9kIGNyZWF0ZVNWR1BhdGhTZWdMaW5ldG9Ib3Jpem9udGFsUmVsIDogbnVtYmVyX3QgLT4gcGF0aFNlZ0xpbmV0b0hvcml6b250YWwgbWV0aFxuXG4gIG1ldGhvZCBjcmVhdGVTVkdQYXRoU2VnTGluZXRvVmVydGljYWxBYnMgOiBudW1iZXJfdCAtPiBwYXRoU2VnTGluZXRvVmVydGljYWwgbWV0aFxuXG4gIG1ldGhvZCBjcmVhdGVTVkdQYXRoU2VnTGluZXRvVmVydGljYWxSZWwgOiBudW1iZXJfdCAtPiBwYXRoU2VnTGluZXRvVmVydGljYWwgbWV0aFxuXG4gIG1ldGhvZCBjcmVhdGVTVkdQYXRoU2VnQ3VydmV0b0N1YmljU21vb3RoQWJzIDpcbiAgICBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBwYXRoU2VnQ3VydmV0b0N1YmljU21vb3RoIG1ldGhcblxuICBtZXRob2QgY3JlYXRlU1ZHUGF0aFNlZ0N1cnZldG9DdWJpY1Ntb290aFJlbCA6XG4gICAgbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gbnVtYmVyX3QgLT4gcGF0aFNlZ0N1cnZldG9DdWJpY1Ntb290aCBtZXRoXG5cbiAgbWV0aG9kIGNyZWF0ZVNWR1BhdGhTZWdDdXJ2ZXRvUXVhZHJhdGljU21vb3RoQWJzIDpcbiAgICBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBwYXRoU2VnQ3VydmV0b1F1YWRyYXRpY1Ntb290aCBtZXRoXG5cbiAgbWV0aG9kIGNyZWF0ZVNWR1BhdGhTZWdDdXJ2ZXRvUXVhZHJhdGljU21vb3RoUmVsIDpcbiAgICBudW1iZXJfdCAtPiBudW1iZXJfdCAtPiBwYXRoU2VnQ3VydmV0b1F1YWRyYXRpY1Ntb290aCBtZXRoXG5lbmRcblxuKCogaW50ZXJmYWNlIFNWR1JlY3RFbGVtZW50ICopXG5hbmQgcmVjdEVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgaW5oZXJpdCB0ZXN0c1xuXG4gIGluaGVyaXQgbGFuZ1NwYWNlXG5cbiAgaW5oZXJpdCBleHRlcm5hbFJlc291cmNlc1JlcXVpcmVkXG5cbiAgaW5oZXJpdCBzdHlsYWJsZVxuXG4gIGluaGVyaXQgdHJhbnNmb3JtYWJsZVxuXG4gIG1ldGhvZCB4IDogYW5pbWF0ZWRMZW5ndGggdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHkgOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgd2lkdGggOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgaGVpZ2h0IDogYW5pbWF0ZWRMZW5ndGggdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHJ4IDogYW5pbWF0ZWRMZW5ndGggdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHJ5IDogYW5pbWF0ZWRMZW5ndGggdCByZWFkb25seV9wcm9wXG5lbmRcblxuKCogaW50ZXJmYWNlIFNWR0NpcmNsZUVsZW1lbnQgKilcbmFuZCBjaXJjbGVFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIGluaGVyaXQgdGVzdHNcblxuICBpbmhlcml0IGxhbmdTcGFjZVxuXG4gIGluaGVyaXQgZXh0ZXJuYWxSZXNvdXJjZXNSZXF1aXJlZFxuXG4gIGluaGVyaXQgc3R5bGFibGVcblxuICBpbmhlcml0IHRyYW5zZm9ybWFibGVcblxuICBtZXRob2QgY3ggOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgY3kgOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgciA6IGFuaW1hdGVkTGVuZ3RoIHQgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdFbGxpcHNlRWxlbWVudCAqKVxuYW5kIGVsbGlwc2VFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIGluaGVyaXQgdGVzdHNcblxuICBpbmhlcml0IGxhbmdTcGFjZVxuXG4gIGluaGVyaXQgZXh0ZXJuYWxSZXNvdXJjZXNSZXF1aXJlZFxuXG4gIGluaGVyaXQgc3R5bGFibGVcblxuICBpbmhlcml0IHRyYW5zZm9ybWFibGVcblxuICBtZXRob2QgY3ggOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgY3kgOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgcnggOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgcnkgOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHTGluZUVsZW1lbnQgKilcbmNsYXNzIHR5cGUgbGluZUVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgaW5oZXJpdCB0ZXN0c1xuXG4gIGluaGVyaXQgbGFuZ1NwYWNlXG5cbiAgaW5oZXJpdCBleHRlcm5hbFJlc291cmNlc1JlcXVpcmVkXG5cbiAgaW5oZXJpdCBzdHlsYWJsZVxuXG4gIGluaGVyaXQgdHJhbnNmb3JtYWJsZVxuXG4gIGluaGVyaXQgRG9tX2h0bWwuZXZlbnRUYXJnZXRcblxuICBtZXRob2QgeDEgOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgeTEgOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgeDIgOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgeTIgOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHQW5pbWF0ZWRQb2ludHMgKilcbmFuZCBhbmltYXRlZFBvaW50cyA9IG9iamVjdFxuICBtZXRob2QgcG9pbnRzIDogcG9pbnRMaXN0IHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBhbmltYXRlZHBvaW50cyA6IHBvaW50TGlzdCB0IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHUG9seWxpbmVFbGVtZW50ICopXG5hbmQgcG9seUxpbmVFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIGluaGVyaXQgdGVzdHNcblxuICBpbmhlcml0IGxhbmdTcGFjZVxuXG4gIGluaGVyaXQgZXh0ZXJuYWxSZXNvdXJjZXNSZXF1aXJlZFxuXG4gIGluaGVyaXQgc3R5bGFibGVcblxuICBpbmhlcml0IHRyYW5zZm9ybWFibGVcblxuICBpbmhlcml0IGFuaW1hdGVkUG9pbnRzXG5lbmRcblxuKCogaW50ZXJmYWNlIFNWR1BvbHlnb25FbGVtZW50ICopXG5hbmQgcG9seWdvbkVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgaW5oZXJpdCB0ZXN0c1xuXG4gIGluaGVyaXQgbGFuZ1NwYWNlXG5cbiAgaW5oZXJpdCBleHRlcm5hbFJlc291cmNlc1JlcXVpcmVkXG5cbiAgaW5oZXJpdCBzdHlsYWJsZVxuXG4gIGluaGVyaXQgdHJhbnNmb3JtYWJsZVxuXG4gIGluaGVyaXQgYW5pbWF0ZWRQb2ludHNcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHVGV4dENvbnRlbnRFbGVtZW50ICopXG5hbmQgdGV4dENvbnRlbnRFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIGluaGVyaXQgdGVzdHNcblxuICBpbmhlcml0IGxhbmdTcGFjZVxuXG4gIGluaGVyaXQgZXh0ZXJuYWxSZXNvdXJjZXNSZXF1aXJlZFxuXG4gIGluaGVyaXQgc3R5bGFibGVcblxuICBpbmhlcml0IERvbV9odG1sLmV2ZW50VGFyZ2V0XG5cbiAgbWV0aG9kIHRleHRMZW5ndGggOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgbGVuZ3RoQWRqdXN0IDogbGVuZ3RoQWRqdXN0IGFuaW1hdGVkIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBnZXROdW1iZXJPZkNoYXJzIDogaW50IG1ldGhcblxuICBtZXRob2QgZ2V0Q29tcHV0ZWRUZXh0TGVuZ3RoIDogbnVtYmVyX3QgbWV0aFxuXG4gIG1ldGhvZCBnZXRTdWJTdHJpbmdMZW5ndGggOiBpbnQgLT4gaW50IC0+IG51bWJlcl90IG1ldGhcblxuICBtZXRob2QgZ2V0U3RhcnRQb3NpdGlvbk9mQ2hhciA6IGludCAtPiBwb2ludCB0IG1ldGhcblxuICBtZXRob2QgZ2V0RW5kUG9zaXRpb25PZkNoYXIgOiBpbnQgLT4gcG9pbnQgdCBtZXRoXG5cbiAgbWV0aG9kIGdldEV4dGVudE9mQ2hhciA6IGludCAtPiByZWN0IHQgbWV0aFxuXG4gIG1ldGhvZCBnZXRSb3RhdGlvbk9mQ2hhciA6IGludCAtPiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIGdldENoYXJOdW1BdFBvc2l0aW9uIDogcG9pbnQgLT4gaW50IG1ldGhcblxuICBtZXRob2Qgc2VsZWN0U3ViU3RyaW5nIDogaW50IC0+IGludCAtPiB1bml0IG1ldGhcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHVGV4dFBvc2l0aW9uaW5nRWxlbWVudCAqKVxuYW5kIHRleHRQb3NpdGlvbmluZ0VsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCB0ZXh0Q29udGVudEVsZW1lbnRcblxuICBtZXRob2QgeCA6IGFuaW1hdGVkTGVuZ3RoTGlzdCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgeSA6IGFuaW1hdGVkTGVuZ3RoTGlzdCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZHggOiBhbmltYXRlZExlbmd0aExpc3QgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGR5IDogYW5pbWF0ZWRMZW5ndGhMaXN0IHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCByb3RhdGUgOiBhbmltYXRlZE51bWJlckxpc3QgdCByZWFkb25seV9wcm9wXG5lbmRcblxuKCogaW50ZXJmYWNlIFNWR1RleHRFbGVtZW50ICopXG5hbmQgdGV4dEVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCB0ZXh0UG9zaXRpb25pbmdFbGVtZW50XG5cbiAgaW5oZXJpdCB0cmFuc2Zvcm1hYmxlXG5lbmRcblxuYW5kIHRzcGFuRWxlbWVudCA9IHRleHRQb3NpdGlvbmluZ0VsZW1lbnRcblxuYW5kIHRyZWZFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgdGV4dFBvc2l0aW9uaW5nRWxlbWVudFxuXG4gIGluaGVyaXQgdXJpUmVmZXJlbmNlXG5lbmRcblxuKCogaW50ZXJmYWNlIFNWR1RleHRQYXRoRWxlbWVudCAqKVxuYW5kIHRleHRQYXRoRWxlbWVudE1ldGhvZCA9IFt0ZXh0UGF0aE1ldGhvZFR5cGVdIGFuaW1hdGVkXG5cbmFuZCB0ZXh0UGF0aEVsZW1lbnRTcGFjaW5nID0gW3RleHRQYXRoU3BhY2luZ1R5cGVdIGFuaW1hdGVkXG5cbmFuZCB0ZXh0UGF0aEVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCB0ZXh0Q29udGVudEVsZW1lbnRcblxuICBpbmhlcml0IHVyaVJlZmVyZW5jZVxuXG4gIG1ldGhvZCBzdGFydE9mZnNldCA6IGFuaW1hdGVkTGVuZ3RoIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBtZXRob2RfIDogdGV4dFBhdGhFbGVtZW50TWV0aG9kIHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgc3BhY2luZyA6IHRleHRQYXRoRWxlbWVudFNwYWNpbmcgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdBbHRHbHlwaEVsZW1lbnQgKilcbmFuZCBhbHRHbHlwaEVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCB0ZXh0UG9zaXRpb25pbmdFbGVtZW50XG5cbiAgaW5oZXJpdCB1cmlSZWZlcmVuY2VcblxuICBtZXRob2QgZ2x5cGhSZWYgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIGZvcm1hdCA6IGpzX3N0cmluZyB0IHByb3BcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHQWx0R2x5cGhEZWZFbGVtZW50ICopXG5hbmQgYWx0R2x5cGhEZWZFbGVtZW50ID0gZWxlbWVudFxuXG4oKiBpbnRlcmZhY2UgU1ZHQWx0R2x5cGhJdGVtRWxlbWVudCAqKVxuYW5kIGFsdEdseXBoSXRlbUVsZW1lbnQgPSBlbGVtZW50XG5cbigqIGludGVyZmFjZSBTVkdHbHlwaFJlZkVsZW1lbnQgKilcbmFuZCBnbHlwaFJlZkVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgaW5oZXJpdCB1cmlSZWZlcmVuY2VcblxuICBpbmhlcml0IHN0eWxhYmxlXG5cbiAgbWV0aG9kIGdseXBoUmVmIDoganNfc3RyaW5nIHQgcHJvcFxuXG4gIG1ldGhvZCBmb3JtYXQgOiBqc19zdHJpbmcgdCBwcm9wXG5cbiAgbWV0aG9kIHggOiBudW1iZXJfdCBwcm9wXG5cbiAgbWV0aG9kIHkgOiBudW1iZXJfdCBwcm9wXG5cbiAgbWV0aG9kIGR4IDogbnVtYmVyX3QgcHJvcFxuXG4gIG1ldGhvZCBkeSA6IG51bWJlcl90IHByb3BcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHUGFpbnQgOiBTVkdDb2xvciB7ICopXG5cbigqICAgLy8gUGFpbnQgVHlwZXMgKilcbigqICAgY29uc3QgdW5zaWduZWQgc2hvcnQgU1ZHX1BBSU5UVFlQRV9VTktOT1dOID0gMDsgKilcbigqICAgY29uc3QgdW5zaWduZWQgc2hvcnQgU1ZHX1BBSU5UVFlQRV9SR0JDT0xPUiA9IDE7ICopXG4oKiAgIGNvbnN0IHVuc2lnbmVkIHNob3J0IFNWR19QQUlOVFRZUEVfUkdCQ09MT1JfSUNDQ09MT1IgPSAyOyAqKVxuKCogICBjb25zdCB1bnNpZ25lZCBzaG9ydCBTVkdfUEFJTlRUWVBFX05PTkUgPSAxMDE7ICopXG4oKiAgIGNvbnN0IHVuc2lnbmVkIHNob3J0IFNWR19QQUlOVFRZUEVfQ1VSUkVOVENPTE9SID0gMTAyOyAqKVxuKCogICBjb25zdCB1bnNpZ25lZCBzaG9ydCBTVkdfUEFJTlRUWVBFX1VSSV9OT05FID0gMTAzOyAqKVxuKCogICBjb25zdCB1bnNpZ25lZCBzaG9ydCBTVkdfUEFJTlRUWVBFX1VSSV9DVVJSRU5UQ09MT1IgPSAxMDQ7ICopXG4oKiAgIGNvbnN0IHVuc2lnbmVkIHNob3J0IFNWR19QQUlOVFRZUEVfVVJJX1JHQkNPTE9SID0gMTA1OyAqKVxuKCogICBjb25zdCB1bnNpZ25lZCBzaG9ydCBTVkdfUEFJTlRUWVBFX1VSSV9SR0JDT0xPUl9JQ0NDT0xPUiA9IDEwNjsgKilcbigqICAgY29uc3QgdW5zaWduZWQgc2hvcnQgU1ZHX1BBSU5UVFlQRV9VUkkgPSAxMDc7ICopXG5cbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIHVuc2lnbmVkIHNob3J0IHBhaW50VHlwZTsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIERPTVN0cmluZyB1cmk7ICopXG5cbigqICAgdm9pZCBzZXRVcmkoaW4gRE9NU3RyaW5nIHVyaSk7ICopXG4oKiAgIHZvaWQgc2V0UGFpbnQoaW4gdW5zaWduZWQgc2hvcnQgcGFpbnRUeXBlLCBpbiBET01TdHJpbmcgdXJpLCBpbiBET01TdHJpbmcgcmdiQ29sb3IsIGluIERPTVN0cmluZyBpY2NDb2xvcikgcmFpc2VzKFNWR0V4Y2VwdGlvbik7ICopXG4oKiB9OyAqKVxuXG4oKiBpbnRlcmZhY2UgU1ZHTWFya2VyRWxlbWVudCA6IFNWR0VsZW1lbnQsICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNWR0xhbmdTcGFjZSwgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1ZHRXh0ZXJuYWxSZXNvdXJjZXNSZXF1aXJlZCwgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1ZHU3R5bGFibGUsICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNWR0ZpdFRvVmlld0JveCB7ICopXG5cbigqICAgLy8gTWFya2VyIFVuaXQgVHlwZXMgKilcbigqICAgY29uc3QgdW5zaWduZWQgc2hvcnQgU1ZHX01BUktFUlVOSVRTX1VOS05PV04gPSAwOyAqKVxuKCogICBjb25zdCB1bnNpZ25lZCBzaG9ydCBTVkdfTUFSS0VSVU5JVFNfVVNFUlNQQUNFT05VU0UgPSAxOyAqKVxuKCogICBjb25zdCB1bnNpZ25lZCBzaG9ydCBTVkdfTUFSS0VSVU5JVFNfU1RST0tFV0lEVEggPSAyOyAqKVxuXG4oKiAgIC8vIE1hcmtlciBPcmllbnRhdGlvbiBUeXBlcyAqKVxuKCogICBjb25zdCB1bnNpZ25lZCBzaG9ydCBTVkdfTUFSS0VSX09SSUVOVF9VTktOT1dOID0gMDsgKilcbigqICAgY29uc3QgdW5zaWduZWQgc2hvcnQgU1ZHX01BUktFUl9PUklFTlRfQVVUTyA9IDE7ICopXG4oKiAgIGNvbnN0IHVuc2lnbmVkIHNob3J0IFNWR19NQVJLRVJfT1JJRU5UX0FOR0xFID0gMjsgKilcblxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWRMZW5ndGggcmVmWDsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkTGVuZ3RoIHJlZlk7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZEVudW1lcmF0aW9uIG1hcmtlclVuaXRzOyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWRMZW5ndGggbWFya2VyV2lkdGg7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZExlbmd0aCBtYXJrZXJIZWlnaHQ7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZEVudW1lcmF0aW9uIG9yaWVudFR5cGU7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZEFuZ2xlIG9yaWVudEFuZ2xlOyAqKVxuXG4oKiAgIHZvaWQgc2V0T3JpZW50VG9BdXRvKCkgcmFpc2VzKERPTUV4Y2VwdGlvbik7ICopXG4oKiAgIHZvaWQgc2V0T3JpZW50VG9BbmdsZShpbiBTVkdBbmdsZSBhbmdsZSkgcmFpc2VzKERPTUV4Y2VwdGlvbik7ICopXG4oKiB9OyAqKVxuXG4oKiBpbnRlcmZhY2UgU1ZHQ29sb3JQcm9maWxlRWxlbWVudCA6IFNWR0VsZW1lbnQsICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNWR1VSSVJlZmVyZW5jZSwgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1ZHUmVuZGVyaW5nSW50ZW50IHsgKilcbigqICAgYXR0cmlidXRlIERPTVN0cmluZyBsb2NhbDsgKilcbigqICAgYXR0cmlidXRlIERPTVN0cmluZyBuYW1lOyAqKVxuKCogICBhdHRyaWJ1dGUgdW5zaWduZWQgc2hvcnQgcmVuZGVyaW5nSW50ZW50OyAqKVxuKCogfTsgKilcblxuKCogaW50ZXJmYWNlIFNWR0NvbG9yUHJvZmlsZVJ1bGUgOiBTVkdDU1NSdWxlLCAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTVkdSZW5kZXJpbmdJbnRlbnQgeyAqKVxuKCogICBhdHRyaWJ1dGUgRE9NU3RyaW5nIHNyYyBzZXRyYWlzZXMoRE9NRXhjZXB0aW9uKTsgKilcbigqICAgYXR0cmlidXRlIERPTVN0cmluZyBuYW1lIHNldHJhaXNlcyhET01FeGNlcHRpb24pOyAqKVxuKCogICBhdHRyaWJ1dGUgdW5zaWduZWQgc2hvcnQgcmVuZGVyaW5nSW50ZW50IHNldHJhaXNlcyhET01FeGNlcHRpb24pOyAqKVxuKCogfTsgKilcblxuKCogaW50ZXJmYWNlIFNWR0dyYWRpZW50RWxlbWVudCAqKVxuYW5kIGFuaW1hdGVkU3ByZWFkTWV0aG9kID0gW3NwcmVhZE1ldGhvZFR5cGVdIGFuaW1hdGVkXG5cbmFuZCBncmFkaWVudEVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgaW5oZXJpdCB1cmlSZWZlcmVuY2VcblxuICBpbmhlcml0IHN0eWxhYmxlXG5cbiAgKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWRFbnVtZXJhdGlvbiBncmFkaWVudFVuaXRzOyAqKVxuICBtZXRob2QgZ3JhZGllbnRUcmFuc2Zvcm0gOiBhbmltYXRlZFRyYW5zZm9ybUxpc3QgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHNwcmVhZE1ldGhvZCA6IGFuaW1hdGVkU3ByZWFkTWV0aG9kIHQgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdMaW5lYXJHcmFkaWVudEVsZW1lbnQgKilcbmFuZCBsaW5lYXJHcmFkaWVudEVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBncmFkaWVudEVsZW1lbnRcblxuICBtZXRob2QgeDEgOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgeTEgOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgeDIgOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgeTIgOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHUmFkaWFsR3JhZGllbnRFbGVtZW50ICopXG5hbmQgcmFkaWFsR3JhZGllbnRFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZ3JhZGllbnRFbGVtZW50XG5cbiAgbWV0aG9kIGN4IDogYW5pbWF0ZWRMZW5ndGggdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGN5IDogYW5pbWF0ZWRMZW5ndGggdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHIgOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZnggOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZnkgOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHU3RvcEVsZW1lbnQgKilcbmFuZCBzdG9wRWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBpbmhlcml0IHN0eWxhYmxlXG5cbiAgbWV0aG9kIG9mZnNldCA6IGFuaW1hdGVkTnVtYmVyIHQgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdQYXR0ZXJuRWxlbWVudCAqKVxuYW5kIHBhdHRlcm5FbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIGluaGVyaXQgdXJpUmVmZXJlbmNlXG5cbiAgaW5oZXJpdCB0ZXN0c1xuXG4gIGluaGVyaXQgbGFuZ1NwYWNlXG5cbiAgaW5oZXJpdCBleHRlcm5hbFJlc291cmNlc1JlcXVpcmVkXG5cbiAgaW5oZXJpdCBzdHlsYWJsZVxuXG4gIGluaGVyaXQgZml0VG9WaWV3Qm94XG5cbiAgKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWRFbnVtZXJhdGlvbiBwYXR0ZXJuVW5pdHM7ICopXG4gICgqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkRW51bWVyYXRpb24gcGF0dGVybkNvbnRlbnRVbml0czsgKilcbiAgbWV0aG9kIHBhdHRlcm5UcmFuc2Zvcm0gOiBhbmltYXRlZFRyYW5zZm9ybUxpc3QgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHggOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgeSA6IGFuaW1hdGVkTGVuZ3RoIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCB3aWR0aCA6IGFuaW1hdGVkTGVuZ3RoIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBoZWlnaHQgOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHQ2xpcFBhdGhFbGVtZW50ICopXG5hbmQgY2xpcFBhdGhFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIGluaGVyaXQgdGVzdHNcblxuICBpbmhlcml0IGxhbmdTcGFjZVxuXG4gIGluaGVyaXQgZXh0ZXJuYWxSZXNvdXJjZXNSZXF1aXJlZFxuXG4gIGluaGVyaXQgc3R5bGFibGVcblxuICBpbmhlcml0IHRyYW5zZm9ybWFibGVcbiAgKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWRFbnVtZXJhdGlvbiBjbGlwUGF0aFVuaXRzOyAqKVxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdNYXNrRWxlbWVudCAqKVxuYW5kIG1hc2tFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIGluaGVyaXQgdGVzdHNcblxuICBpbmhlcml0IGxhbmdTcGFjZVxuXG4gIGluaGVyaXQgZXh0ZXJuYWxSZXNvdXJjZXNSZXF1aXJlZFxuXG4gIGluaGVyaXQgc3R5bGFibGVcblxuICAoKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZEVudW1lcmF0aW9uIG1hc2tVbml0czsgKilcbiAgKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWRFbnVtZXJhdGlvbiBtYXNrQ29udGVudFVuaXRzOyAqKVxuICBtZXRob2QgeCA6IGFuaW1hdGVkTGVuZ3RoIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCB5IDogYW5pbWF0ZWRMZW5ndGggdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHdpZHRoIDogYW5pbWF0ZWRMZW5ndGggdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGhlaWdodCA6IGFuaW1hdGVkTGVuZ3RoIHQgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdGaWx0ZXJFbGVtZW50ICopXG5hbmQgZmlsdGVyRWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBpbmhlcml0IHVyaVJlZmVyZW5jZVxuXG4gIGluaGVyaXQgbGFuZ1NwYWNlXG5cbiAgaW5oZXJpdCBleHRlcm5hbFJlc291cmNlc1JlcXVpcmVkXG5cbiAgaW5oZXJpdCBzdHlsYWJsZVxuXG4gICgqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkRW51bWVyYXRpb24gZmlsdGVyVW5pdHM7ICopXG4gICgqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkRW51bWVyYXRpb24gcHJpbWl0aXZlVW5pdHM7ICopXG4gIG1ldGhvZCB4IDogYW5pbWF0ZWRMZW5ndGggdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHkgOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgd2lkdGggOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgaGVpZ2h0IDogYW5pbWF0ZWRMZW5ndGggdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGZpbHRlclJlc1ggOiBhbmltYXRlZEludGVnZXIgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGZpbHRlclJlc1kgOiBhbmltYXRlZEludGVnZXIgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHNldEZpbHRlclJlcyA6IGludCAtPiBpbnQgLT4gdW5pdCBtZXRoXG5lbmRcblxuKCogaW50ZXJmYWNlIFNWR0ZpbHRlclByaW1pdGl2ZVN0YW5kYXJkQXR0cmlidXRlcyA6IFNWR1N0eWxhYmxlIHsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkTGVuZ3RoIHg7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZExlbmd0aCB5OyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWRMZW5ndGggd2lkdGg7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZExlbmd0aCBoZWlnaHQ7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZFN0cmluZyByZXN1bHQ7ICopXG4oKiB9OyAqKVxuXG4oKiBpbnRlcmZhY2UgU1ZHRkVCbGVuZEVsZW1lbnQgOiBTVkdFbGVtZW50LCAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1ZHRmlsdGVyUHJpbWl0aXZlU3RhbmRhcmRBdHRyaWJ1dGVzIHsgKilcblxuKCogICAvLyBCbGVuZCBNb2RlIFR5cGVzICopXG4oKiAgIGNvbnN0IHVuc2lnbmVkIHNob3J0IFNWR19GRUJMRU5EX01PREVfVU5LTk9XTiA9IDA7ICopXG4oKiAgIGNvbnN0IHVuc2lnbmVkIHNob3J0IFNWR19GRUJMRU5EX01PREVfTk9STUFMID0gMTsgKilcbigqICAgY29uc3QgdW5zaWduZWQgc2hvcnQgU1ZHX0ZFQkxFTkRfTU9ERV9NVUxUSVBMWSA9IDI7ICopXG4oKiAgIGNvbnN0IHVuc2lnbmVkIHNob3J0IFNWR19GRUJMRU5EX01PREVfU0NSRUVOID0gMzsgKilcbigqICAgY29uc3QgdW5zaWduZWQgc2hvcnQgU1ZHX0ZFQkxFTkRfTU9ERV9EQVJLRU4gPSA0OyAqKVxuKCogICBjb25zdCB1bnNpZ25lZCBzaG9ydCBTVkdfRkVCTEVORF9NT0RFX0xJR0hURU4gPSA1OyAqKVxuXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZFN0cmluZyBpbjE7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZFN0cmluZyBpbjI7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZEVudW1lcmF0aW9uIG1vZGU7ICopXG4oKiB9OyAqKVxuXG4oKiBpbnRlcmZhY2UgU1ZHRkVDb2xvck1hdHJpeEVsZW1lbnQgOiBTVkdFbGVtZW50LCAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1ZHRmlsdGVyUHJpbWl0aXZlU3RhbmRhcmRBdHRyaWJ1dGVzIHsgKilcblxuKCogICAvLyBDb2xvciBNYXRyaXggVHlwZXMgKilcbigqICAgY29uc3QgdW5zaWduZWQgc2hvcnQgU1ZHX0ZFQ09MT1JNQVRSSVhfVFlQRV9VTktOT1dOID0gMDsgKilcbigqICAgY29uc3QgdW5zaWduZWQgc2hvcnQgU1ZHX0ZFQ09MT1JNQVRSSVhfVFlQRV9NQVRSSVggPSAxOyAqKVxuKCogICBjb25zdCB1bnNpZ25lZCBzaG9ydCBTVkdfRkVDT0xPUk1BVFJJWF9UWVBFX1NBVFVSQVRFID0gMjsgKilcbigqICAgY29uc3QgdW5zaWduZWQgc2hvcnQgU1ZHX0ZFQ09MT1JNQVRSSVhfVFlQRV9IVUVST1RBVEUgPSAzOyAqKVxuKCogICBjb25zdCB1bnNpZ25lZCBzaG9ydCBTVkdfRkVDT0xPUk1BVFJJWF9UWVBFX0xVTUlOQU5DRVRPQUxQSEEgPSA0OyAqKVxuXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZFN0cmluZyBpbjE7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZEVudW1lcmF0aW9uIHR5cGU7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZE51bWJlckxpc3QgdmFsdWVzOyAqKVxuKCogfTsgKilcblxuKCogaW50ZXJmYWNlIFNWR0ZFQ29tcG9uZW50VHJhbnNmZXJFbGVtZW50IDogU1ZHRWxlbWVudCwgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNWR0ZpbHRlclByaW1pdGl2ZVN0YW5kYXJkQXR0cmlidXRlcyB7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZFN0cmluZyBpbjE7ICopXG4oKiB9OyAqKVxuXG4oKiBpbnRlcmZhY2UgU1ZHQ29tcG9uZW50VHJhbnNmZXJGdW5jdGlvbkVsZW1lbnQgOiBTVkdFbGVtZW50IHsgKilcblxuKCogICAvLyBDb21wb25lbnQgVHJhbnNmZXIgVHlwZXMgKilcbigqICAgY29uc3QgdW5zaWduZWQgc2hvcnQgU1ZHX0ZFQ09NUE9ORU5UVFJBTlNGRVJfVFlQRV9VTktOT1dOID0gMDsgKilcbigqICAgY29uc3QgdW5zaWduZWQgc2hvcnQgU1ZHX0ZFQ09NUE9ORU5UVFJBTlNGRVJfVFlQRV9JREVOVElUWSA9IDE7ICopXG4oKiAgIGNvbnN0IHVuc2lnbmVkIHNob3J0IFNWR19GRUNPTVBPTkVOVFRSQU5TRkVSX1RZUEVfVEFCTEUgPSAyOyAqKVxuKCogICBjb25zdCB1bnNpZ25lZCBzaG9ydCBTVkdfRkVDT01QT05FTlRUUkFOU0ZFUl9UWVBFX0RJU0NSRVRFID0gMzsgKilcbigqICAgY29uc3QgdW5zaWduZWQgc2hvcnQgU1ZHX0ZFQ09NUE9ORU5UVFJBTlNGRVJfVFlQRV9MSU5FQVIgPSA0OyAqKVxuKCogICBjb25zdCB1bnNpZ25lZCBzaG9ydCBTVkdfRkVDT01QT05FTlRUUkFOU0ZFUl9UWVBFX0dBTU1BID0gNTsgKilcblxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWRFbnVtZXJhdGlvbiB0eXBlOyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWROdW1iZXJMaXN0IHRhYmxlVmFsdWVzOyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWROdW1iZXIgc2xvcGU7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZE51bWJlciBpbnRlcmNlcHQ7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZE51bWJlciBhbXBsaXR1ZGU7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZE51bWJlciBleHBvbmVudDsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkTnVtYmVyIG9mZnNldDsgKilcbigqIH07ICopXG5cbigqIGludGVyZmFjZSBTVkdGRUZ1bmNSRWxlbWVudCA6IFNWR0NvbXBvbmVudFRyYW5zZmVyRnVuY3Rpb25FbGVtZW50IHsgKilcbigqIH07ICopXG5cbigqIGludGVyZmFjZSBTVkdGRUZ1bmNHRWxlbWVudCA6IFNWR0NvbXBvbmVudFRyYW5zZmVyRnVuY3Rpb25FbGVtZW50IHsgKilcbigqIH07ICopXG5cbigqIGludGVyZmFjZSBTVkdGRUZ1bmNCRWxlbWVudCA6IFNWR0NvbXBvbmVudFRyYW5zZmVyRnVuY3Rpb25FbGVtZW50IHsgKilcbigqIH07ICopXG5cbigqIGludGVyZmFjZSBTVkdGRUZ1bmNBRWxlbWVudCA6IFNWR0NvbXBvbmVudFRyYW5zZmVyRnVuY3Rpb25FbGVtZW50IHsgKilcbigqIH07ICopXG5cbigqIGludGVyZmFjZSBTVkdGRUNvbXBvc2l0ZUVsZW1lbnQgOiBTVkdFbGVtZW50LCAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNWR0ZpbHRlclByaW1pdGl2ZVN0YW5kYXJkQXR0cmlidXRlcyB7ICopXG5cbigqICAgLy8gQ29tcG9zaXRlIE9wZXJhdG9ycyAqKVxuKCogICBjb25zdCB1bnNpZ25lZCBzaG9ydCBTVkdfRkVDT01QT1NJVEVfT1BFUkFUT1JfVU5LTk9XTiA9IDA7ICopXG4oKiAgIGNvbnN0IHVuc2lnbmVkIHNob3J0IFNWR19GRUNPTVBPU0lURV9PUEVSQVRPUl9PVkVSID0gMTsgKilcbigqICAgY29uc3QgdW5zaWduZWQgc2hvcnQgU1ZHX0ZFQ09NUE9TSVRFX09QRVJBVE9SX0lOID0gMjsgKilcbigqICAgY29uc3QgdW5zaWduZWQgc2hvcnQgU1ZHX0ZFQ09NUE9TSVRFX09QRVJBVE9SX09VVCA9IDM7ICopXG4oKiAgIGNvbnN0IHVuc2lnbmVkIHNob3J0IFNWR19GRUNPTVBPU0lURV9PUEVSQVRPUl9BVE9QID0gNDsgKilcbigqICAgY29uc3QgdW5zaWduZWQgc2hvcnQgU1ZHX0ZFQ09NUE9TSVRFX09QRVJBVE9SX1hPUiA9IDU7ICopXG4oKiAgIGNvbnN0IHVuc2lnbmVkIHNob3J0IFNWR19GRUNPTVBPU0lURV9PUEVSQVRPUl9BUklUSE1FVElDID0gNjsgKilcblxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWRTdHJpbmcgaW4xOyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWRTdHJpbmcgaW4yOyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWRFbnVtZXJhdGlvbiBvcGVyYXRvcjsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkTnVtYmVyIGsxOyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWROdW1iZXIgazI7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZE51bWJlciBrMzsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkTnVtYmVyIGs0OyAqKVxuKCogfTsgKilcblxuKCogaW50ZXJmYWNlIFNWR0ZFQ29udm9sdmVNYXRyaXhFbGVtZW50IDogU1ZHRWxlbWVudCwgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNWR0ZpbHRlclByaW1pdGl2ZVN0YW5kYXJkQXR0cmlidXRlcyB7ICopXG5cbigqICAgLy8gRWRnZSBNb2RlIFZhbHVlcyAqKVxuKCogICBjb25zdCB1bnNpZ25lZCBzaG9ydCBTVkdfRURHRU1PREVfVU5LTk9XTiA9IDA7ICopXG4oKiAgIGNvbnN0IHVuc2lnbmVkIHNob3J0IFNWR19FREdFTU9ERV9EVVBMSUNBVEUgPSAxOyAqKVxuKCogICBjb25zdCB1bnNpZ25lZCBzaG9ydCBTVkdfRURHRU1PREVfV1JBUCA9IDI7ICopXG4oKiAgIGNvbnN0IHVuc2lnbmVkIHNob3J0IFNWR19FREdFTU9ERV9OT05FID0gMzsgKilcblxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWRTdHJpbmcgaW4xOyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWRJbnRlZ2VyIG9yZGVyWDsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkSW50ZWdlciBvcmRlclk7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZE51bWJlckxpc3Qga2VybmVsTWF0cml4OyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWROdW1iZXIgZGl2aXNvcjsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkTnVtYmVyIGJpYXM7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZEludGVnZXIgdGFyZ2V0WDsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkSW50ZWdlciB0YXJnZXRZOyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWRFbnVtZXJhdGlvbiBlZGdlTW9kZTsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkTnVtYmVyIGtlcm5lbFVuaXRMZW5ndGhYOyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWROdW1iZXIga2VybmVsVW5pdExlbmd0aFk7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZEJvb2xlYW4gcHJlc2VydmVBbHBoYTsgKilcbigqIH07ICopXG5cbigqIGludGVyZmFjZSBTVkdGRURpZmZ1c2VMaWdodGluZ0VsZW1lbnQgOiBTVkdFbGVtZW50LCAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNWR0ZpbHRlclByaW1pdGl2ZVN0YW5kYXJkQXR0cmlidXRlcyB7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZFN0cmluZyBpbjE7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZE51bWJlciBzdXJmYWNlU2NhbGU7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZE51bWJlciBkaWZmdXNlQ29uc3RhbnQ7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZE51bWJlciBrZXJuZWxVbml0TGVuZ3RoWDsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkTnVtYmVyIGtlcm5lbFVuaXRMZW5ndGhZOyAqKVxuKCogfTsgKilcblxuKCogaW50ZXJmYWNlIFNWR0ZFRGlzdGFudExpZ2h0RWxlbWVudCA6IFNWR0VsZW1lbnQgeyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWROdW1iZXIgYXppbXV0aDsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkTnVtYmVyIGVsZXZhdGlvbjsgKilcbigqIH07ICopXG5cbigqIGludGVyZmFjZSBTVkdGRVBvaW50TGlnaHRFbGVtZW50IDogU1ZHRWxlbWVudCB7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZE51bWJlciB4OyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWROdW1iZXIgeTsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkTnVtYmVyIHo7ICopXG4oKiB9OyAqKVxuXG4oKiBpbnRlcmZhY2UgU1ZHRkVTcG90TGlnaHRFbGVtZW50IDogU1ZHRWxlbWVudCB7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZE51bWJlciB4OyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWROdW1iZXIgeTsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkTnVtYmVyIHo7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZE51bWJlciBwb2ludHNBdFg7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZE51bWJlciBwb2ludHNBdFk7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZE51bWJlciBwb2ludHNBdFo7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZE51bWJlciBzcGVjdWxhckV4cG9uZW50OyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWROdW1iZXIgbGltaXRpbmdDb25lQW5nbGU7ICopXG4oKiB9OyAqKVxuXG4oKiBpbnRlcmZhY2UgU1ZHRkVEaXNwbGFjZW1lbnRNYXBFbGVtZW50IDogU1ZHRWxlbWVudCwgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTVkdGaWx0ZXJQcmltaXRpdmVTdGFuZGFyZEF0dHJpYnV0ZXMgeyAqKVxuXG4oKiAgIC8vIENoYW5uZWwgU2VsZWN0b3JzICopXG4oKiAgIGNvbnN0IHVuc2lnbmVkIHNob3J0IFNWR19DSEFOTkVMX1VOS05PV04gPSAwOyAqKVxuKCogICBjb25zdCB1bnNpZ25lZCBzaG9ydCBTVkdfQ0hBTk5FTF9SID0gMTsgKilcbigqICAgY29uc3QgdW5zaWduZWQgc2hvcnQgU1ZHX0NIQU5ORUxfRyA9IDI7ICopXG4oKiAgIGNvbnN0IHVuc2lnbmVkIHNob3J0IFNWR19DSEFOTkVMX0IgPSAzOyAqKVxuKCogICBjb25zdCB1bnNpZ25lZCBzaG9ydCBTVkdfQ0hBTk5FTF9BID0gNDsgKilcblxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWRTdHJpbmcgaW4xOyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWRTdHJpbmcgaW4yOyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWROdW1iZXIgc2NhbGU7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZEVudW1lcmF0aW9uIHhDaGFubmVsU2VsZWN0b3I7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZEVudW1lcmF0aW9uIHlDaGFubmVsU2VsZWN0b3I7ICopXG4oKiB9OyAqKVxuXG4oKiBpbnRlcmZhY2UgU1ZHRkVGbG9vZEVsZW1lbnQgOiBTVkdFbGVtZW50LCAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1ZHRmlsdGVyUHJpbWl0aXZlU3RhbmRhcmRBdHRyaWJ1dGVzIHsgKilcbigqIH07ICopXG5cbigqIGludGVyZmFjZSBTVkdGRUdhdXNzaWFuQmx1ckVsZW1lbnQgOiBTVkdFbGVtZW50LCAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNWR0ZpbHRlclByaW1pdGl2ZVN0YW5kYXJkQXR0cmlidXRlcyB7ICopXG5cbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkU3RyaW5nIGluMTsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkTnVtYmVyIHN0ZERldmlhdGlvblg7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZE51bWJlciBzdGREZXZpYXRpb25ZOyAqKVxuXG4oKiAgIHZvaWQgc2V0U3RkRGV2aWF0aW9uKGluIGZsb2F0IHN0ZERldmlhdGlvblgsIGluIGZsb2F0IHN0ZERldmlhdGlvblkpIHJhaXNlcyhET01FeGNlcHRpb24pOyAqKVxuKCogfTsgKilcblxuKCogaW50ZXJmYWNlIFNWR0ZFSW1hZ2VFbGVtZW50IDogU1ZHRWxlbWVudCwgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNWR1VSSVJlZmVyZW5jZSwgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNWR0xhbmdTcGFjZSwgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNWR0V4dGVybmFsUmVzb3VyY2VzUmVxdWlyZWQsICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTVkdGaWx0ZXJQcmltaXRpdmVTdGFuZGFyZEF0dHJpYnV0ZXMgeyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWRQcmVzZXJ2ZUFzcGVjdFJhdGlvIHByZXNlcnZlQXNwZWN0UmF0aW87ICopXG4oKiB9OyAqKVxuXG4oKiBpbnRlcmZhY2UgU1ZHRkVNZXJnZUVsZW1lbnQgOiBTVkdFbGVtZW50LCAqKVxuKCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1ZHRmlsdGVyUHJpbWl0aXZlU3RhbmRhcmRBdHRyaWJ1dGVzIHsgKilcbigqIH07ICopXG5cbigqIGludGVyZmFjZSBTVkdGRU1lcmdlTm9kZUVsZW1lbnQgOiBTVkdFbGVtZW50IHsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkU3RyaW5nIGluMTsgKilcbigqIH07ICopXG5cbigqIGludGVyZmFjZSBTVkdGRU1vcnBob2xvZ3lFbGVtZW50IDogU1ZHRWxlbWVudCwgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1ZHRmlsdGVyUHJpbWl0aXZlU3RhbmRhcmRBdHRyaWJ1dGVzIHsgKilcblxuKCogICAvLyBNb3JwaG9sb2d5IE9wZXJhdG9ycyAqKVxuKCogICBjb25zdCB1bnNpZ25lZCBzaG9ydCBTVkdfTU9SUEhPTE9HWV9PUEVSQVRPUl9VTktOT1dOID0gMDsgKilcbigqICAgY29uc3QgdW5zaWduZWQgc2hvcnQgU1ZHX01PUlBIT0xPR1lfT1BFUkFUT1JfRVJPREUgPSAxOyAqKVxuKCogICBjb25zdCB1bnNpZ25lZCBzaG9ydCBTVkdfTU9SUEhPTE9HWV9PUEVSQVRPUl9ESUxBVEUgPSAyOyAqKVxuXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZFN0cmluZyBpbjE7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZEVudW1lcmF0aW9uIG9wZXJhdG9yOyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWROdW1iZXIgcmFkaXVzWDsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkTnVtYmVyIHJhZGl1c1k7ICopXG4oKiB9OyAqKVxuXG4oKiBpbnRlcmZhY2UgU1ZHRkVPZmZzZXRFbGVtZW50IDogU1ZHRWxlbWVudCwgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTVkdGaWx0ZXJQcmltaXRpdmVTdGFuZGFyZEF0dHJpYnV0ZXMgeyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWRTdHJpbmcgaW4xOyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWROdW1iZXIgZHg7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZE51bWJlciBkeTsgKilcbigqIH07ICopXG5cbigqIGludGVyZmFjZSBTVkdGRVNwZWN1bGFyTGlnaHRpbmdFbGVtZW50IDogU1ZHRWxlbWVudCwgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1ZHRmlsdGVyUHJpbWl0aXZlU3RhbmRhcmRBdHRyaWJ1dGVzIHsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkU3RyaW5nIGluMTsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkTnVtYmVyIHN1cmZhY2VTY2FsZTsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkTnVtYmVyIHNwZWN1bGFyQ29uc3RhbnQ7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZE51bWJlciBzcGVjdWxhckV4cG9uZW50OyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWROdW1iZXIga2VybmVsVW5pdExlbmd0aFg7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZE51bWJlciBrZXJuZWxVbml0TGVuZ3RoWTsgKilcbigqIH07ICopXG5cbigqIGludGVyZmFjZSBTVkdGRVRpbGVFbGVtZW50IDogU1ZHRWxlbWVudCwgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1ZHRmlsdGVyUHJpbWl0aXZlU3RhbmRhcmRBdHRyaWJ1dGVzIHsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkU3RyaW5nIGluMTsgKilcbigqIH07ICopXG5cbigqIGludGVyZmFjZSBTVkdGRVR1cmJ1bGVuY2VFbGVtZW50IDogU1ZHRWxlbWVudCwgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1ZHRmlsdGVyUHJpbWl0aXZlU3RhbmRhcmRBdHRyaWJ1dGVzIHsgKilcblxuKCogICAvLyBUdXJidWxlbmNlIFR5cGVzICopXG4oKiAgIGNvbnN0IHVuc2lnbmVkIHNob3J0IFNWR19UVVJCVUxFTkNFX1RZUEVfVU5LTk9XTiA9IDA7ICopXG4oKiAgIGNvbnN0IHVuc2lnbmVkIHNob3J0IFNWR19UVVJCVUxFTkNFX1RZUEVfRlJBQ1RBTE5PSVNFID0gMTsgKilcbigqICAgY29uc3QgdW5zaWduZWQgc2hvcnQgU1ZHX1RVUkJVTEVOQ0VfVFlQRV9UVVJCVUxFTkNFID0gMjsgKilcblxuKCogICAvLyBTdGl0Y2ggT3B0aW9ucyAqKVxuKCogICBjb25zdCB1bnNpZ25lZCBzaG9ydCBTVkdfU1RJVENIVFlQRV9VTktOT1dOID0gMDsgKilcbigqICAgY29uc3QgdW5zaWduZWQgc2hvcnQgU1ZHX1NUSVRDSFRZUEVfU1RJVENIID0gMTsgKilcbigqICAgY29uc3QgdW5zaWduZWQgc2hvcnQgU1ZHX1NUSVRDSFRZUEVfTk9TVElUQ0ggPSAyOyAqKVxuXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZE51bWJlciBiYXNlRnJlcXVlbmN5WDsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkTnVtYmVyIGJhc2VGcmVxdWVuY3lZOyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWRJbnRlZ2VyIG51bU9jdGF2ZXM7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdBbmltYXRlZE51bWJlciBzZWVkOyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHQW5pbWF0ZWRFbnVtZXJhdGlvbiBzdGl0Y2hUaWxlczsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIFNWR0FuaW1hdGVkRW51bWVyYXRpb24gdHlwZTsgKilcbigqIH07ICopXG5cbigqIGludGVyZmFjZSBTVkdDdXJzb3JFbGVtZW50ICopXG5hbmQgY3Vyc29yRWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBpbmhlcml0IHVyaVJlZmVyZW5jZVxuXG4gIGluaGVyaXQgdGVzdHNcblxuICBpbmhlcml0IGV4dGVybmFsUmVzb3VyY2VzUmVxdWlyZWRcblxuICBtZXRob2QgeCA6IGFuaW1hdGVkTGVuZ3RoIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCB5IDogYW5pbWF0ZWRMZW5ndGggdCByZWFkb25seV9wcm9wXG5lbmRcblxuKCogaW50ZXJmYWNlIFNWR0FFbGVtZW50ICopXG5hbmQgYUVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgaW5oZXJpdCB1cmlSZWZlcmVuY2VcblxuICBpbmhlcml0IHRlc3RzXG5cbiAgaW5oZXJpdCBsYW5nU3BhY2VcblxuICBpbmhlcml0IGV4dGVybmFsUmVzb3VyY2VzUmVxdWlyZWRcblxuICBpbmhlcml0IHN0eWxhYmxlXG5cbiAgaW5oZXJpdCB0cmFuc2Zvcm1hYmxlXG5cbiAgbWV0aG9kIHRhcmdldCA6IGFuaW1hdGVkU3RyaW5nIHQgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdWaWV3RWxlbWVudCAqKVxuYW5kIHZpZXdFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIGluaGVyaXQgZXh0ZXJuYWxSZXNvdXJjZXNSZXF1aXJlZFxuXG4gIGluaGVyaXQgZml0VG9WaWV3Qm94XG5cbiAgaW5oZXJpdCB6b29tQW5kUGFuXG5cbiAgbWV0aG9kIHZpZXdUYXJnZXQgOiBzdHJpbmdMaXN0IHQgcmVhZG9ubHlfcHJvcFxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdTY3JpcHRFbGVtZW50ICopXG5hbmQgc2NyaXB0RWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBpbmhlcml0IHVyaVJlZmVyZW5jZVxuXG4gIGluaGVyaXQgZXh0ZXJuYWxSZXNvdXJjZXNSZXF1aXJlZFxuXG4gIG1ldGhvZCB0eXBlXyA6IGpzX3N0cmluZyB0IHByb3BcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHWm9vbUV2ZW50IDogVUlFdmVudCAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHUmVjdCB6b29tUmVjdFNjcmVlbjsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIGZsb2F0IHByZXZpb3VzU2NhbGU7ICopXG4oKiAgIHJlYWRvbmx5IGF0dHJpYnV0ZSBTVkdQb2ludCBwcmV2aW91c1RyYW5zbGF0ZTsgKilcbigqICAgcmVhZG9ubHkgYXR0cmlidXRlIGZsb2F0IG5ld1NjYWxlOyAqKVxuKCogICByZWFkb25seSBhdHRyaWJ1dGUgU1ZHUG9pbnQgbmV3VHJhbnNsYXRlOyAqKVxuKCogfTsgKilcblxuKCogaW50ZXJmYWNlIFNWR0FuaW1hdGlvbkVsZW1lbnQgKilcbmFuZCBhbmltYXRpb25FbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIGluaGVyaXQgdGVzdHNcblxuICBpbmhlcml0IGV4dGVybmFsUmVzb3VyY2VzUmVxdWlyZWRcblxuICAoKiBpbmhlcml0IGVsZW1lbnRUaW1lQ29udHJvbCAqKVxuICBtZXRob2QgdGFyZ2V0RWxlbWVudCA6IGVsZW1lbnQgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGdldFN0YXJ0VGltZSA6IG51bWJlcl90IG1ldGhcblxuICBtZXRob2QgZ2V0Q3VycmVudFRpbWUgOiBudW1iZXJfdCBtZXRoXG5cbiAgbWV0aG9kIGdldFNpbXBsZUR1cmF0aW9uIDogbnVtYmVyX3QgbWV0aFxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdBbmltYXRlRWxlbWVudCAqKVxuYW5kIGFuaW1hdGVFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgYW5pbWF0aW9uRWxlbWVudFxuXG4gIGluaGVyaXQgc3R5bGFibGVcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHU2V0RWxlbWVudCAqKVxuYW5kIHNldEVsZW1lbnQgPSBhbmltYXRpb25FbGVtZW50XG5cbigqIGludGVyZmFjZSBTVkdBbmltYXRlTW90aW9uRWxlbWVudCAqKVxuYW5kIGFuaW1hdGVNb3Rpb25FbGVtZW50ID0gYW5pbWF0aW9uRWxlbWVudFxuXG4oKiBpbnRlcmZhY2UgU1ZHTVBhdGhFbGVtZW50ICopXG5hbmQgbVBhdGhFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgZWxlbWVudFxuXG4gIGluaGVyaXQgdXJpUmVmZXJlbmNlXG5cbiAgaW5oZXJpdCBleHRlcm5hbFJlc291cmNlc1JlcXVpcmVkXG5lbmRcblxuKCogaW50ZXJmYWNlIFNWR0FuaW1hdGVDb2xvckVsZW1lbnQgKilcbmFuZCBhbmltYXRlQ29sb3JFbGVtZW50ID0gb2JqZWN0XG4gIGluaGVyaXQgYW5pbWF0aW9uRWxlbWVudFxuXG4gIGluaGVyaXQgc3R5bGFibGVcbmVuZFxuXG4oKiBpbnRlcmZhY2UgU1ZHQW5pbWF0ZVRyYW5zZm9ybUVsZW1lbnQgKilcbmFuZCBhbmltYXRlVHJhbnNmb3JtRWxlbWVudCA9IGFuaW1hdGlvbkVsZW1lbnRcblxuKCogaW50ZXJmYWNlIFNWR0ZvbnRFbGVtZW50ICopXG5hbmQgZm9udEVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgaW5oZXJpdCBzdHlsYWJsZVxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdHbHlwaEVsZW1lbnQgKilcbigqIGludGVyZmFjZSBTVkdNaXNzaW5nR2x5cGhFbGVtZW50KilcbmFuZCBnbHlwaEVsZW1lbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBlbGVtZW50XG5cbiAgaW5oZXJpdCBzdHlsYWJsZVxuZW5kXG5cbigqIGludGVyZmFjZSBTVkdIS2VybkVsZW1lbnQgOiBTVkdFbGVtZW50ICopXG4oKiBpbnRlcmZhY2UgU1ZHVktlcm5FbGVtZW50IDogU1ZHRWxlbWVudCAqKVxuXG4oKiBpbnRlcmZhY2UgU1ZHRm9udEZhY2VFbGVtZW50ICopXG5jbGFzcyB0eXBlIGZvbnRGYWNlRWxlbWVudCA9IGVsZW1lbnRcblxuKCogaW50ZXJmYWNlIFNWR0ZvbnRGYWNlU3JjRWxlbWVudCAqKVxuY2xhc3MgdHlwZSBmb250RmFjZVNyY0VsZW1lbnQgPSBlbGVtZW50XG5cbigqIGludGVyZmFjZSBTVkdGb250RmFjZVVyaUVsZW1lbnQgKilcbmNsYXNzIHR5cGUgZm9udEZhY2VVcmlFbGVtZW50ID0gZWxlbWVudFxuXG4oKiBpbnRlcmZhY2UgU1ZHRm9udEZhY2VGb3JtYXRFbGVtZW50ICopXG5jbGFzcyB0eXBlIGZvbnRGYWNlRm9ybWF0RWxlbWVudCA9IGVsZW1lbnRcblxuKCogaW50ZXJmYWNlIFNWR0ZvbnRGYWNlTmFtZUVsZW1lbnQgKilcbmNsYXNzIHR5cGUgZm9udEZhY2VOYW1lRWxlbWVudCA9IGVsZW1lbnRcblxuKCogaW50ZXJmYWNlIFNWR01ldGFkYXRhRWxlbWVudCAqKVxuY2xhc3MgdHlwZSBtZXRhZGF0YUVsZW1lbnQgPSBlbGVtZW50XG5cbigqIGludGVyZmFjZSBTVkdGb3JlaWduT2JqZWN0RWxlbWVudCAqKVxuY2xhc3MgdHlwZSBmb3JlaWduT2JqZWN0RWxlbWVudCA9IG9iamVjdFxuICBpbmhlcml0IGVsZW1lbnRcblxuICBpbmhlcml0IHRlc3RzXG5cbiAgaW5oZXJpdCBsYW5nU3BhY2VcblxuICBpbmhlcml0IGV4dGVybmFsUmVzb3VyY2VzUmVxdWlyZWRcblxuICBpbmhlcml0IHN0eWxhYmxlXG5cbiAgaW5oZXJpdCB0cmFuc2Zvcm1hYmxlXG5cbiAgbWV0aG9kIHggOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgeSA6IGFuaW1hdGVkTGVuZ3RoIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCB3aWR0aCA6IGFuaW1hdGVkTGVuZ3RoIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBoZWlnaHQgOiBhbmltYXRlZExlbmd0aCB0IHJlYWRvbmx5X3Byb3BcbmVuZFxuXG5sZXQgY3JlYXRlRWxlbWVudCAoZG9jIDogZG9jdW1lbnQgdCkgbmFtZSA9IGRvYyMjY3JlYXRlRWxlbWVudE5TIHhtbG5zIChKcy5zdHJpbmcgbmFtZSlcblxubGV0IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIG5hbWUgPSBKcy5VbnNhZmUuY29lcmNlIChjcmVhdGVFbGVtZW50IGRvYyBuYW1lKVxuXG5sZXQgY3JlYXRlQSBkb2MgOiBhRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJhXCJcblxubGV0IGNyZWF0ZUFsdEdseXBoIGRvYyA6IGFsdEdseXBoRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJhbHRnbHlwaFwiXG5cbmxldCBjcmVhdGVBbHRHbHlwaERlZiBkb2MgOiBhbHRHbHlwaERlZkVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwiYWx0Z2x5cGhkZWZcIlxuXG5sZXQgY3JlYXRlQWx0R2x5cGhJdGVtIGRvYyA6IGFsdEdseXBoSXRlbUVsZW1lbnQgdCA9XG4gIHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwiYWx0Z2x5cGhpdGVtXCJcblxubGV0IGNyZWF0ZUFuaW1hdGUgZG9jIDogYW5pbWF0ZUVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwiYW5pbWF0ZVwiXG5cbmxldCBjcmVhdGVBbmltYXRlQ29sb3IgZG9jIDogYW5pbWF0ZUNvbG9yRWxlbWVudCB0ID1cbiAgdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJhbmltYXRlY29sb3JcIlxuXG5sZXQgY3JlYXRlQW5pbWF0ZU1vdGlvbiBkb2MgOiBhbmltYXRlTW90aW9uRWxlbWVudCB0ID1cbiAgdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJhbmltYXRlbW90aW9uXCJcblxubGV0IGNyZWF0ZUFuaW1hdGVUcmFuc2Zvcm0gZG9jIDogYW5pbWF0ZVRyYW5zZm9ybUVsZW1lbnQgdCA9XG4gIHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwiYW5pbWF0ZXRyYW5zZm9ybVwiXG5cbmxldCBjcmVhdGVDaXJjbGUgZG9jIDogY2lyY2xlRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJjaXJjbGVcIlxuXG5sZXQgY3JlYXRlQ2xpcFBhdGggZG9jIDogY2xpcFBhdGhFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcImNsaXBwYXRoXCJcblxuKCogbGV0IGNyZWF0ZUNvbG9yUHJvZmlsZSBkb2MgOiBjb2xvclByb2ZpbGUgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwiY29sb3ItcHJvZmlsZVwiICopXG5sZXQgY3JlYXRlQ3Vyc29yIGRvYyA6IGN1cnNvckVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwiY3Vyc29yXCJcblxubGV0IGNyZWF0ZURlZnMgZG9jIDogZGVmc0VsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwiZGVmc1wiXG5cbmxldCBjcmVhdGVEZXNjIGRvYyA6IGRlc2NFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcImRlc2NcIlxuXG5sZXQgY3JlYXRlRWxsaXBzZSBkb2MgOiBlbGxpcHNlRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJlbGxpcHNlXCJcblxuKCogbGV0IGNyZWF0ZUZlKiAqKVxubGV0IGNyZWF0ZUZpbHRlciBkb2MgOiBmaWx0ZXJFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcImZpbHRlclwiXG5cbmxldCBjcmVhdGVGb250IGRvYyA6IGZvbnRFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcImZvbnRcIlxuXG5sZXQgY3JlYXRlRm9udEZhY2UgZG9jIDogZm9udEVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwiZm9udC1mYWNlXCJcblxubGV0IGNyZWF0ZUZvbnRGYWNlRm9ybWF0IGRvYyA6IGZvbnRFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcImZvbnQtZmFjZS1mb3JtYXRcIlxuXG5sZXQgY3JlYXRlRm9udEZhY2VOYW1lIGRvYyA6IGZvbnRFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcImZvbnQtZmFjZS1uYW1lXCJcblxubGV0IGNyZWF0ZUZvbnRGYWNlU3JjIGRvYyA6IGZvbnRFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcImZvbnQtZmFjZS1zcmNcIlxuXG5sZXQgY3JlYXRlRm9udEZhY2VVcmkgZG9jIDogZm9udEVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwiZm9udC1mYWNlLXVyaVwiXG5cbmxldCBjcmVhdGVGb3JlaWduT2JqZWN0IGRvYyA6IGZvcmVpZ25PYmplY3RFbGVtZW50IHQgPVxuICB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcImZvcmVpZ25PYmplY3RcIlxuXG5sZXQgY3JlYXRlRyBkb2MgOiBnRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJnXCJcblxubGV0IGNyZWF0ZUdseXBoIGRvYyA6IGdseXBoRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJnbHlwaFwiXG5cbmxldCBjcmVhdGVHbHlwaFJlZiBkb2MgOiBnbHlwaEVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwiZ2x5cGhyZWZcIlxuXG5sZXQgY3JlYXRlaGtlcm4gZG9jIDogZWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJoa2VyblwiXG5cbmxldCBjcmVhdGVJbWFnZSBkb2MgOiBpbWFnZUVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwiaW1hZ2VcIlxuXG5sZXQgY3JlYXRlTGluZUVsZW1lbnQgZG9jIDogbGluZUVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwibGluZVwiXG5cbmxldCBjcmVhdGVMaW5lYXJFbGVtZW50IGRvYyA6IGxpbmVhckdyYWRpZW50RWxlbWVudCB0ID1cbiAgdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJsaW5lYXJncmFkaWVudFwiXG5cbigqIGxldCBjcmVhdGVNYXJrZXIgZG9jIDogbWFya2VyRWxlbWVudCAqKVxubGV0IGNyZWF0ZU1hc2sgZG9jIDogbWFza0VsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwibWFza1wiXG5cbmxldCBjcmVhdGVNZXRhRGF0YSBkb2MgOiBtZXRhZGF0YUVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwibWV0YWRhdGFcIlxuXG5sZXQgY3JlYXRlTWlzc2luZ0dseXBoIGRvYyA6IGdseXBoRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJtaXNzaW5nLWdseXBoXCJcblxubGV0IGNyZWF0ZU1QYXRoIGRvYyA6IG1QYXRoRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJtcGF0aFwiXG5cbmxldCBjcmVhdGVQYXRoIGRvYyA6IHBhdGhFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcInBhdGhcIlxuXG5sZXQgY3JlYXRlUGF0dGVybiBkb2MgOiBwYXR0ZXJuRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJwYXR0ZXJuXCJcblxubGV0IGNyZWF0ZVBvbHlnb24gZG9jIDogcG9seWdvbkVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwicG9seWdvblwiXG5cbmxldCBjcmVhdGVQb2x5bGluZSBkb2MgOiBwb2x5TGluZUVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwicG9seWxpbmVcIlxuXG5sZXQgY3JlYXRlUmFkaWFsZ3JhZGllbnQgZG9jIDogcmFkaWFsR3JhZGllbnRFbGVtZW50IHQgPVxuICB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcInJhZGlhbGdyYWRpZW50XCJcblxubGV0IGNyZWF0ZVJlY3QgZG9jIDogcmVjdEVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwicmVjdFwiXG5cbmxldCBjcmVhdGVTY3JpcHQgZG9jIDogc2NyaXB0RWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJzY3JpcHRcIlxuXG5sZXQgY3JlYXRlU2V0IGRvYyA6IHNldEVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwic2V0XCJcblxubGV0IGNyZWF0ZVN0b3AgZG9jIDogc3RvcEVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwic3RvcFwiXG5cbmxldCBjcmVhdGVTdHlsZSBkb2MgOiBzdHlsZUVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwic3R5bGVcIlxuXG5sZXQgY3JlYXRlU3ZnIGRvYyA6IHN2Z0VsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwic3ZnXCJcblxubGV0IGNyZWF0ZVN3aXRjaCBkb2MgOiBzd2l0Y2hFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcInN3aXRjaFwiXG5cbmxldCBjcmVhdGVTeW1ib2wgZG9jIDogc3ltYm9sRWxlbWVudCB0ID0gdW5zYWZlQ3JlYXRlRWxlbWVudCBkb2MgXCJzeW1ib2xcIlxuXG5sZXQgY3JlYXRlVGV4dEVsZW1lbnQgZG9jIDogdGV4dEVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwidGV4dFwiXG5cbmxldCBjcmVhdGVUZXh0cGF0aCBkb2MgOiB0ZXh0UGF0aEVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwidGV4dHBhdGhcIlxuXG5sZXQgY3JlYXRlVGl0bGUgZG9jIDogdGl0bGVFbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcInRpdGxlXCJcblxubGV0IGNyZWF0ZVRyZWYgZG9jIDogdHJlZkVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwidHJlZlwiXG5cbmxldCBjcmVhdGVUc3BhbiBkb2MgOiB0c3BhbkVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwidHNwYW5cIlxuXG5sZXQgY3JlYXRlVXNlIGRvYyA6IHVzZUVsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwidXNlXCJcblxubGV0IGNyZWF0ZVZpZXcgZG9jIDogdmlld0VsZW1lbnQgdCA9IHVuc2FmZUNyZWF0ZUVsZW1lbnQgZG9jIFwidmlld1wiXG5cbmxldCBjcmVhdGV2a2VybiBkb2MgOiBlbGVtZW50IHQgPSB1bnNhZmVDcmVhdGVFbGVtZW50IGRvYyBcInZrZXJuXCJcblxuKCoqKiopXG5cbmxldCBzdmdfZWxlbWVudCA6IGVsZW1lbnQgdCBjb25zdHIgPSBKcy5VbnNhZmUuZ2xvYmFsIyMuX1NWR0VsZW1lbnRcblxubGV0IGRvY3VtZW50ID0gSnMuVW5zYWZlLmdsb2JhbCMjLmRvY3VtZW50XG5cbmxldCBnZXRFbGVtZW50QnlJZCBpZCA6IGVsZW1lbnQgdCA9XG4gIEpzLk9wdC5jYXNlXG4gICAgKEpzLlVuc2FmZS5nbG9iYWwjIy5kb2N1bWVudCMjZ2V0RWxlbWVudEJ5SWQgKEpzLnN0cmluZyBpZCkpXG4gICAgKGZ1biAoKSAtPiByYWlzZSBOb3RfZm91bmQpXG4gICAgKGZ1biBlIC0+IGlmIEpzLmluc3RhbmNlb2YgZSBzdmdfZWxlbWVudCB0aGVuIGUgZWxzZSByYWlzZSBOb3RfZm91bmQpXG5cbm1vZHVsZSBDb2VyY2VUbyA9IHN0cnVjdFxuICBsZXQgZWxlbWVudCAoZSA6ICNEb20ubm9kZSBKcy50KSA6IGVsZW1lbnQgSnMudCBKcy5vcHQgPVxuICAgIGlmIEpzLmluc3RhbmNlb2YgZSBzdmdfZWxlbWVudCB0aGVuIEpzLnNvbWUgKEpzLlVuc2FmZS5jb2VyY2UgZSkgZWxzZSBKcy5udWxsXG5cbiAgbGV0IHVuc2FmZUNvZXJjZSAoZSA6ICNlbGVtZW50IHQpIHRhZyA9XG4gICAgaWYgSnMuZXF1YWxzIGUjIy50YWdOYW1lIyN0b0xvd2VyQ2FzZSAoSnMuc3RyaW5nIHRhZylcbiAgICB0aGVuIEpzLnNvbWUgKEpzLlVuc2FmZS5jb2VyY2UgZSlcbiAgICBlbHNlIEpzLm51bGxcblxuICBsZXQgYSBlIDogYUVsZW1lbnQgdCBvcHQgPSB1bnNhZmVDb2VyY2UgZSBcImFcIlxuXG4gIGxldCBhbHRHbHlwaCBlIDogYWx0R2x5cGhFbGVtZW50IHQgb3B0ID0gdW5zYWZlQ29lcmNlIGUgXCJhbHRnbHlwaFwiXG5cbiAgbGV0IGFsdEdseXBoRGVmIGUgOiBhbHRHbHlwaERlZkVsZW1lbnQgdCBvcHQgPSB1bnNhZmVDb2VyY2UgZSBcImFsdGdseXBoZGVmXCJcblxuICBsZXQgYWx0R2x5cGhJdGVtIGUgOiBhbHRHbHlwaEl0ZW1FbGVtZW50IHQgb3B0ID0gdW5zYWZlQ29lcmNlIGUgXCJhbHRnbHlwaGl0ZW1cIlxuXG4gIGxldCBhbmltYXRlIGUgOiBhbmltYXRlRWxlbWVudCB0IG9wdCA9IHVuc2FmZUNvZXJjZSBlIFwiYW5pbWF0ZVwiXG5cbiAgbGV0IGFuaW1hdGVDb2xvciBlIDogYW5pbWF0ZUNvbG9yRWxlbWVudCB0IG9wdCA9IHVuc2FmZUNvZXJjZSBlIFwiYW5pbWF0ZWNvbG9yXCJcblxuICBsZXQgYW5pbWF0ZU1vdGlvbiBlIDogYW5pbWF0ZU1vdGlvbkVsZW1lbnQgdCBvcHQgPSB1bnNhZmVDb2VyY2UgZSBcImFuaW1hdGVtb3Rpb25cIlxuXG4gIGxldCBhbmltYXRlVHJhbnNmb3JtIGUgOiBhbmltYXRlVHJhbnNmb3JtRWxlbWVudCB0IG9wdCA9XG4gICAgdW5zYWZlQ29lcmNlIGUgXCJhbmltYXRldHJhbnNmb3JtXCJcblxuICBsZXQgY2lyY2xlIGUgOiBjaXJjbGVFbGVtZW50IHQgb3B0ID0gdW5zYWZlQ29lcmNlIGUgXCJjaXJjbGVcIlxuXG4gIGxldCBjbGlwUGF0aCBlIDogY2xpcFBhdGhFbGVtZW50IHQgb3B0ID0gdW5zYWZlQ29lcmNlIGUgXCJjbGlwcGF0aFwiXG5cbiAgKCogbGV0IENvbG9yUHJvZmlsZSBlIDogY29sb3JQcm9maWxlIHQgb3B0ID0gdW5zYWZlQ29lcmNlIGUgXCJjb2xvci1wcm9maWxlXCIgKilcbiAgbGV0IGN1cnNvciBlIDogY3Vyc29yRWxlbWVudCB0IG9wdCA9IHVuc2FmZUNvZXJjZSBlIFwiY3Vyc29yXCJcblxuICBsZXQgZGVmcyBlIDogZGVmc0VsZW1lbnQgdCBvcHQgPSB1bnNhZmVDb2VyY2UgZSBcImRlZnNcIlxuXG4gIGxldCBkZXNjIGUgOiBkZXNjRWxlbWVudCB0IG9wdCA9IHVuc2FmZUNvZXJjZSBlIFwiZGVzY1wiXG5cbiAgbGV0IGVsbGlwc2UgZSA6IGVsbGlwc2VFbGVtZW50IHQgb3B0ID0gdW5zYWZlQ29lcmNlIGUgXCJlbGxpcHNlXCJcblxuICAoKiBsZXQgRmUqICopXG4gIGxldCBmaWx0ZXIgZSA6IGZpbHRlckVsZW1lbnQgdCBvcHQgPSB1bnNhZmVDb2VyY2UgZSBcImZpbHRlclwiXG5cbiAgbGV0IGZvbnQgZSA6IGZvbnRFbGVtZW50IHQgb3B0ID0gdW5zYWZlQ29lcmNlIGUgXCJmb250XCJcblxuICBsZXQgZm9udEZhY2UgZSA6IGZvbnRFbGVtZW50IHQgb3B0ID0gdW5zYWZlQ29lcmNlIGUgXCJmb250LWZhY2VcIlxuXG4gIGxldCBmb250RmFjZUZvcm1hdCBlIDogZm9udEVsZW1lbnQgdCBvcHQgPSB1bnNhZmVDb2VyY2UgZSBcImZvbnQtZmFjZS1mb3JtYXRcIlxuXG4gIGxldCBmb250RmFjZU5hbWUgZSA6IGZvbnRFbGVtZW50IHQgb3B0ID0gdW5zYWZlQ29lcmNlIGUgXCJmb250LWZhY2UtbmFtZVwiXG5cbiAgbGV0IGZvbnRGYWNlU3JjIGUgOiBmb250RWxlbWVudCB0IG9wdCA9IHVuc2FmZUNvZXJjZSBlIFwiZm9udC1mYWNlLXNyY1wiXG5cbiAgbGV0IGZvbnRGYWNlVXJpIGUgOiBmb250RWxlbWVudCB0IG9wdCA9IHVuc2FmZUNvZXJjZSBlIFwiZm9udC1mYWNlLXVyaVwiXG5cbiAgbGV0IGZvcmVpZ25PYmplY3QgZSA6IGZvcmVpZ25PYmplY3RFbGVtZW50IHQgb3B0ID0gdW5zYWZlQ29lcmNlIGUgXCJmb3JlaWdub2JqZWN0XCJcblxuICBsZXQgZyBlIDogZ0VsZW1lbnQgdCBvcHQgPSB1bnNhZmVDb2VyY2UgZSBcImdcIlxuXG4gIGxldCBnbHlwaCBlIDogZ2x5cGhFbGVtZW50IHQgb3B0ID0gdW5zYWZlQ29lcmNlIGUgXCJnbHlwaFwiXG5cbiAgbGV0IGdseXBoUmVmIGUgOiBnbHlwaEVsZW1lbnQgdCBvcHQgPSB1bnNhZmVDb2VyY2UgZSBcImdseXBocmVmXCJcblxuICBsZXQgaGtlcm4gZSA6IGVsZW1lbnQgdCBvcHQgPSB1bnNhZmVDb2VyY2UgZSBcImhrZXJuXCJcblxuICBsZXQgaW1hZ2UgZSA6IGltYWdlRWxlbWVudCB0IG9wdCA9IHVuc2FmZUNvZXJjZSBlIFwiaW1hZ2VcIlxuXG4gIGxldCBsaW5lRWxlbWVudCBlIDogbGluZUVsZW1lbnQgdCBvcHQgPSB1bnNhZmVDb2VyY2UgZSBcImxpbmVcIlxuXG4gIGxldCBsaW5lYXJFbGVtZW50IGUgOiBsaW5lYXJHcmFkaWVudEVsZW1lbnQgdCBvcHQgPSB1bnNhZmVDb2VyY2UgZSBcImxpbmVhcmdyYWRpZW50XCJcblxuICAoKiBsZXQgTWFya2VyIGUgOiBtYXJrZXJFbGVtZW50ICopXG4gIGxldCBtYXNrIGUgOiBtYXNrRWxlbWVudCB0IG9wdCA9IHVuc2FmZUNvZXJjZSBlIFwibWFza1wiXG5cbiAgbGV0IG1ldGFEYXRhIGUgOiBtZXRhZGF0YUVsZW1lbnQgdCBvcHQgPSB1bnNhZmVDb2VyY2UgZSBcIm1ldGFkYXRhXCJcblxuICBsZXQgbWlzc2luZ0dseXBoIGUgOiBnbHlwaEVsZW1lbnQgdCBvcHQgPSB1bnNhZmVDb2VyY2UgZSBcIm1pc3NpbmctZ2x5cGhcIlxuXG4gIGxldCBtUGF0aCBlIDogbVBhdGhFbGVtZW50IHQgb3B0ID0gdW5zYWZlQ29lcmNlIGUgXCJtcGF0aFwiXG5cbiAgbGV0IHBhdGggZSA6IHBhdGhFbGVtZW50IHQgb3B0ID0gdW5zYWZlQ29lcmNlIGUgXCJwYXRoXCJcblxuICBsZXQgcGF0dGVybiBlIDogcGF0dGVybkVsZW1lbnQgdCBvcHQgPSB1bnNhZmVDb2VyY2UgZSBcInBhdHRlcm5cIlxuXG4gIGxldCBwb2x5Z29uIGUgOiBwb2x5Z29uRWxlbWVudCB0IG9wdCA9IHVuc2FmZUNvZXJjZSBlIFwicG9seWdvblwiXG5cbiAgbGV0IHBvbHlsaW5lIGUgOiBwb2x5TGluZUVsZW1lbnQgdCBvcHQgPSB1bnNhZmVDb2VyY2UgZSBcInBvbHlsaW5lXCJcblxuICBsZXQgcmFkaWFsZ3JhZGllbnQgZSA6IHJhZGlhbEdyYWRpZW50RWxlbWVudCB0IG9wdCA9IHVuc2FmZUNvZXJjZSBlIFwicmFkaWFsZ3JhZGllbnRcIlxuXG4gIGxldCByZWN0IGUgOiByZWN0RWxlbWVudCB0IG9wdCA9IHVuc2FmZUNvZXJjZSBlIFwicmVjdFwiXG5cbiAgbGV0IHNjcmlwdCBlIDogc2NyaXB0RWxlbWVudCB0IG9wdCA9IHVuc2FmZUNvZXJjZSBlIFwic2NyaXB0XCJcblxuICBsZXQgc2V0IGUgOiBzZXRFbGVtZW50IHQgb3B0ID0gdW5zYWZlQ29lcmNlIGUgXCJzZXRcIlxuXG4gIGxldCBzdG9wIGUgOiBzdG9wRWxlbWVudCB0IG9wdCA9IHVuc2FmZUNvZXJjZSBlIFwic3RvcFwiXG5cbiAgbGV0IHN0eWxlIGUgOiBzdHlsZUVsZW1lbnQgdCBvcHQgPSB1bnNhZmVDb2VyY2UgZSBcInN0eWxlXCJcblxuICBsZXQgc3ZnIGUgOiBzdmdFbGVtZW50IHQgb3B0ID0gdW5zYWZlQ29lcmNlIGUgXCJzdmdcIlxuXG4gIGxldCBzd2l0Y2ggZSA6IHN3aXRjaEVsZW1lbnQgdCBvcHQgPSB1bnNhZmVDb2VyY2UgZSBcInN3aXRjaFwiXG5cbiAgbGV0IHN5bWJvbCBlIDogc3ltYm9sRWxlbWVudCB0IG9wdCA9IHVuc2FmZUNvZXJjZSBlIFwic3ltYm9sXCJcblxuICBsZXQgdGV4dEVsZW1lbnQgZSA6IHRleHRFbGVtZW50IHQgb3B0ID0gdW5zYWZlQ29lcmNlIGUgXCJ0ZXh0XCJcblxuICBsZXQgdGV4dHBhdGggZSA6IHRleHRQYXRoRWxlbWVudCB0IG9wdCA9IHVuc2FmZUNvZXJjZSBlIFwidGV4dHBhdGhcIlxuXG4gIGxldCB0aXRsZSBlIDogdGl0bGVFbGVtZW50IHQgb3B0ID0gdW5zYWZlQ29lcmNlIGUgXCJ0aXRsZVwiXG5cbiAgbGV0IHRyZWYgZSA6IHRyZWZFbGVtZW50IHQgb3B0ID0gdW5zYWZlQ29lcmNlIGUgXCJ0cmVmXCJcblxuICBsZXQgdHNwYW4gZSA6IHRzcGFuRWxlbWVudCB0IG9wdCA9IHVuc2FmZUNvZXJjZSBlIFwidHNwYW5cIlxuXG4gIGxldCB1c2UgZSA6IHVzZUVsZW1lbnQgdCBvcHQgPSB1bnNhZmVDb2VyY2UgZSBcInVzZVwiXG5cbiAgbGV0IHZpZXcgZSA6IHZpZXdFbGVtZW50IHQgb3B0ID0gdW5zYWZlQ29lcmNlIGUgXCJ2aWV3XCJcblxuICBsZXQgdmtlcm4gZSA6IGVsZW1lbnQgdCBvcHQgPSB1bnNhZmVDb2VyY2UgZSBcInZrZXJuXCJcbmVuZFxuIiwiKCogSnNfb2Zfb2NhbWwgbGlicmFyeVxuICogaHR0cDovL3d3dy5vY3NpZ2VuLm9yZy9qc19vZl9vY2FtbC9cbiAqIENvcHlyaWdodCAoQykgMjAxNCBIdWdvIEhldXphcmRcbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCB3aXRoIGxpbmtpbmcgZXhjZXB0aW9uO1xuICogZWl0aGVyIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuXG4gKilcblxuKCogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0V2ZW50U291cmNlICopXG5vcGVuIEpzXG5vcGVuIERvbVxub3BlbiEgSW1wb3J0XG5cbnR5cGUgc3RhdGUgPVxuICB8IENPTk5FQ1RJTkdcbiAgfCBPUEVOXG4gIHwgQ0xPU0VEXG5cbmNsYXNzIHR5cGUgWydhXSBtZXNzYWdlRXZlbnQgPSBvYmplY3RcbiAgaW5oZXJpdCBbJ2FdIERvbS5ldmVudFxuXG4gIG1ldGhvZCBkYXRhIDoganNfc3RyaW5nIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBvcmlnaW4gOiBqc19zdHJpbmcgdCByZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGxhc3RFdmVudElkIDoganNfc3RyaW5nIHQgcmVhZG9ubHlfcHJvcFxuICAoKiBtZXRob2Qgc291cmNlIDogdW5pdCAqKVxuZW5kXG5cbmNsYXNzIHR5cGUgZXZlbnRTb3VyY2UgPSBvYmplY3QgKCdzZWxmKVxuICBtZXRob2QgdXJsIDogc3RyaW5nIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCB3aXRoQ3JlZGVudGlhbHMgOiBib29sIHQgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCByZWFkeVN0YXRlIDogc3RhdGUgcmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBjbG9zZSA6IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBvbm9wZW4gOiAoJ3NlbGYgdCwgJ3NlbGYgbWVzc2FnZUV2ZW50IHQpIGV2ZW50X2xpc3RlbmVyIHdyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIG9ubWVzc2FnZSA6ICgnc2VsZiB0LCAnc2VsZiBtZXNzYWdlRXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgd3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2Qgb25lcnJvciA6ICgnc2VsZiB0LCAnc2VsZiBtZXNzYWdlRXZlbnQgdCkgZXZlbnRfbGlzdGVuZXIgd3JpdGVvbmx5X3Byb3BcbmVuZFxuXG5jbGFzcyB0eXBlIG9wdGlvbnMgPSBvYmplY3RcbiAgbWV0aG9kIHdpdGhDcmVkZW50aWFscyA6IGJvb2wgdCB3cml0ZW9ubHlfcHJvcFxuZW5kXG5cbmxldCB3aXRoQ3JlZGVudGlhbHMgYiA6IG9wdGlvbnMgdCA9XG4gIGxldCBpbml0ID0gSnMuVW5zYWZlLm9iaiBbfHxdIGluXG4gIGluaXQjIy53aXRoQ3JlZGVudGlhbHMgOj0gSnMuYm9vbCBiO1xuICBpbml0XG5cbmxldCBldmVudFNvdXJjZSA9IEpzLlVuc2FmZS5nbG9iYWwjIy5fRXZlbnRTb3VyY2VcblxubGV0IGV2ZW50U291cmNlX29wdGlvbnMgPSBKcy5VbnNhZmUuZ2xvYmFsIyMuX0V2ZW50U291cmNlXG5cbmxldCBhZGRFdmVudExpc3RlbmVyID0gRG9tLmFkZEV2ZW50TGlzdGVuZXJcbiIsIigqIEpzX29mX29jYW1sIGxpYnJhcnlcbiAqIGh0dHA6Ly93d3cub2NzaWdlbi5vcmcvanNfb2Zfb2NhbWwvXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTAgSsOpcsO0bWUgVm91aWxsb25cbiAqIExhYm9yYXRvaXJlIFBQUyAtIENOUlMgVW5pdmVyc2l0w6kgUGFyaXMgRGlkZXJvdFxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHdpdGggbGlua2luZyBleGNlcHRpb247XG4gKiBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcsIFVTQS5cbiAqKVxuXG5vcGVuIEpzXG5vcGVuISBJbXBvcnRcblxuY2xhc3MgdHlwZSBjb25zb2xlID0gb2JqZWN0XG4gIG1ldGhvZCBsb2cgOiBfIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBsb2dfMiA6IF8gLT4gXyAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgbG9nXzMgOiBfIC0+IF8gLT4gXyAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgbG9nXzQgOiBfIC0+IF8gLT4gXyAtPiBfIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBsb2dfNSA6IF8gLT4gXyAtPiBfIC0+IF8gLT4gXyAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgbG9nXzYgOiBfIC0+IF8gLT4gXyAtPiBfIC0+IF8gLT4gXyAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgbG9nXzcgOiBfIC0+IF8gLT4gXyAtPiBfIC0+IF8gLT4gXyAtPiBfIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBsb2dfOCA6IF8gLT4gXyAtPiBfIC0+IF8gLT4gXyAtPiBfIC0+IF8gLT4gXyAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgZGVidWcgOiBfIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBkZWJ1Z18yIDogXyAtPiBfIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBkZWJ1Z18zIDogXyAtPiBfIC0+IF8gLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGRlYnVnXzQgOiBfIC0+IF8gLT4gXyAtPiBfIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBkZWJ1Z181IDogXyAtPiBfIC0+IF8gLT4gXyAtPiBfIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBpbmZvIDogXyAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgaW5mb18yIDogXyAtPiBfIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBpbmZvXzMgOiBfIC0+IF8gLT4gXyAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgaW5mb180IDogXyAtPiBfIC0+IF8gLT4gXyAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgaW5mb181IDogXyAtPiBfIC0+IF8gLT4gXyAtPiBfIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB3YXJuIDogXyAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgd2Fybl8yIDogXyAtPiBfIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCB3YXJuXzMgOiBfIC0+IF8gLT4gXyAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgd2Fybl80IDogXyAtPiBfIC0+IF8gLT4gXyAtPiB1bml0IG1ldGhcblxuICBtZXRob2Qgd2Fybl81IDogXyAtPiBfIC0+IF8gLT4gXyAtPiBfIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBlcnJvciA6IF8gLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGVycm9yXzIgOiBfIC0+IF8gLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGVycm9yXzMgOiBfIC0+IF8gLT4gXyAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgZXJyb3JfNCA6IF8gLT4gXyAtPiBfIC0+IF8gLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGVycm9yXzUgOiBfIC0+IF8gLT4gXyAtPiBfIC0+IF8gLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGFzc2VydF8gOiBib29sIHQgLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGFzc2VydF8xIDogYm9vbCB0IC0+IF8gLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGFzc2VydF8yIDogYm9vbCB0IC0+IF8gLT4gXyAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgYXNzZXJ0XzMgOiBib29sIHQgLT4gXyAtPiBfIC0+IF8gLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGFzc2VydF80IDogYm9vbCB0IC0+IF8gLT4gXyAtPiBfIC0+IF8gLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGFzc2VydF81IDogYm9vbCB0IC0+IF8gLT4gXyAtPiBfIC0+IF8gLT4gXyAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgZGlyIDogXyAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgZGlyeG1sIDogRG9tLm5vZGUgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdHJhY2UgOiB1bml0IG1ldGhcblxuICBtZXRob2QgZ3JvdXAgOiBfIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBncm91cF8yIDogXyAtPiBfIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBncm91cF8zIDogXyAtPiBfIC0+IF8gLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGdyb3VwXzQgOiBfIC0+IF8gLT4gXyAtPiBfIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBncm91cF81IDogXyAtPiBfIC0+IF8gLT4gXyAtPiBfIC0+IHVuaXQgbWV0aFxuXG4gIG1ldGhvZCBncm91cENvbGxhcHNlZCA6IF8gLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGdyb3VwQ29sbGFwc2VkXzIgOiBfIC0+IF8gLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGdyb3VwQ29sbGFwc2VkXzMgOiBfIC0+IF8gLT4gXyAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgZ3JvdXBDb2xsYXBzZWRfNCA6IF8gLT4gXyAtPiBfIC0+IF8gLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGdyb3VwQ29sbGFwc2VkXzUgOiBfIC0+IF8gLT4gXyAtPiBfIC0+IF8gLT4gdW5pdCBtZXRoXG5cbiAgbWV0aG9kIGdyb3VwRW5kIDogdW5pdCBtZXRoXG5cbiAgbWV0aG9kIHRpbWUgOiBqc19zdHJpbmcgdCAtPiB1bml0IG1ldGhcblxuICBtZXRob2QgdGltZUVuZCA6IGpzX3N0cmluZyB0IC0+IHVuaXQgbWV0aFxuZW5kXG5cbmV4dGVybmFsIGdldF9jb25zb2xlIDogdW5pdCAtPiBjb25zb2xlIHQgPSBcImNhbWxfanNfZ2V0X2NvbnNvbGVcIlxuXG5sZXQgY29uc29sZSA9IGdldF9jb25zb2xlICgpXG4iLCIoKiBKc19vZl9vY2FtbCBsaWJyYXJ5XG4gKiBodHRwOi8vd3d3Lm9jc2lnZW4ub3JnL2pzX29mX29jYW1sL1xuICogQ29weXJpZ2h0IChDKSAyMDE1IFN0w6lwaGFuZSBMZWdyYW5kXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgd2l0aCBsaW5raW5nIGV4Y2VwdGlvbjtcbiAqIGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4gKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLlxuICopXG5vcGVuISBJbXBvcnRcblxudHlwZSBwb3NpdGlvbkVycm9yQ29kZVxuXG50eXBlIHdhdGNoSWRcblxuY2xhc3MgdHlwZSBjb29yZGluYXRlcyA9IG9iamVjdFxuICBtZXRob2QgbGF0aXR1ZGUgOiBKcy5udW1iZXJfdCBKcy5yZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGxvbmdpdHVkZSA6IEpzLm51bWJlcl90IEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgYWx0aXR1ZGUgOiBKcy5udW1iZXJfdCBKcy5vcHQgSnMucmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBhY2N1cmFjeSA6IEpzLm51bWJlcl90IEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgYWx0aXR1ZGVBY2N1cmFjeSA6IEpzLm51bWJlcl90IEpzLm9wdCBKcy5yZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGhlYWRpbmcgOiBKcy5udW1iZXJfdCBKcy5vcHQgSnMucmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBzcGVlZCA6IEpzLm51bWJlcl90IEpzLm9wdCBKcy5yZWFkb25seV9wcm9wXG5lbmRcblxuY2xhc3MgdHlwZSBwb3NpdGlvbiA9IG9iamVjdFxuICBtZXRob2QgY29vcmRzIDogY29vcmRpbmF0ZXMgSnMudCBKcy5yZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIHRpbWVzdGFtcCA6IEpzLmRhdGUgSnMucmVhZG9ubHlfcHJvcFxuZW5kXG5cbmNsYXNzIHR5cGUgcG9zaXRpb25PcHRpb25zID0gb2JqZWN0XG4gIG1ldGhvZCBlbmFibGVIaWdoQWNjdXJhY3kgOiBib29sIEpzLndyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIHRpbWVvdXQgOiBpbnQgSnMud3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2QgbWF4aW11bUFnZSA6IGludCBKcy53cml0ZW9ubHlfcHJvcFxuZW5kXG5cbmNsYXNzIHR5cGUgcG9zaXRpb25FcnJvciA9IG9iamVjdFxuICBtZXRob2QgX1BFUk1JU1NJT05fREVOSUVEXyA6IHBvc2l0aW9uRXJyb3JDb2RlIEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1BPU0lUSU9OX1VOQVZBSUxBQkxFXyA6IHBvc2l0aW9uRXJyb3JDb2RlIEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1RJTUVPVVQgOiBwb3NpdGlvbkVycm9yQ29kZSBKcy5yZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGNvZGUgOiBwb3NpdGlvbkVycm9yQ29kZSBKcy5yZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIG1lc3NhZ2UgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5yZWFkb25seV9wcm9wXG5lbmRcblxuY2xhc3MgdHlwZSBnZW9sb2NhdGlvbiA9IG9iamVjdFxuICBtZXRob2QgZ2V0Q3VycmVudFBvc2l0aW9uIDpcbiAgICAgICAocG9zaXRpb24gSnMudCAtPiB1bml0KSBKcy5jYWxsYmFja1xuICAgIC0+IChwb3NpdGlvbkVycm9yIEpzLnQgLT4gdW5pdCkgSnMuY2FsbGJhY2tcbiAgICAtPiBwb3NpdGlvbk9wdGlvbnMgSnMudFxuICAgIC0+IHVuaXQgSnMubWV0aFxuXG4gIG1ldGhvZCB3YXRjaFBvc2l0aW9uIDpcbiAgICAgICAocG9zaXRpb24gSnMudCAtPiB1bml0KSBKcy5jYWxsYmFja1xuICAgIC0+IChwb3NpdGlvbkVycm9yIEpzLnQgLT4gdW5pdCkgSnMuY2FsbGJhY2tcbiAgICAtPiBwb3NpdGlvbk9wdGlvbnMgSnMudFxuICAgIC0+IHdhdGNoSWQgSnMubWV0aFxuXG4gIG1ldGhvZCBjbGVhcldhdGNoIDogd2F0Y2hJZCAtPiB1bml0IEpzLm1ldGhcbmVuZFxuXG5sZXQgZW1wdHlfcG9zaXRpb25fb3B0aW9ucyAoKSA9IEpzLlVuc2FmZS5vYmogW3x8XVxuXG5sZXQgZ2VvbG9jYXRpb24gPVxuICBsZXQgeCA9IEpzLlVuc2FmZS5nbG9iYWwjIy5uYXZpZ2F0b3IgaW5cbiAgaWYgSnMuT3B0ZGVmLnRlc3QgeCB0aGVuIHgjIy5nZW9sb2NhdGlvbiBlbHNlIHhcblxuKCogdW5kZWZpbmVkICopXG5cbmxldCBpc19zdXBwb3J0ZWQgKCkgPSBKcy5PcHRkZWYudGVzdCBnZW9sb2NhdGlvblxuIiwiY2xhc3MgdHlwZSBpbnRlcnNlY3Rpb25PYnNlcnZlckVudHJ5ID0gb2JqZWN0XG4gIG1ldGhvZCB0YXJnZXQgOiBEb20ubm9kZSBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgYm91bmRpbmdDbGllbnRSZWN0IDogRG9tX2h0bWwuY2xpZW50UmVjdCBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2Qgcm9vdEJvdW5kcyA6IERvbV9odG1sLmNsaWVudFJlY3QgSnMudCBKcy5vcHQgSnMucmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCBpbnRlcnNlY3Rpb25SZWN0IDogRG9tX2h0bWwuY2xpZW50UmVjdCBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgaW50ZXJzZWN0aW9uUmF0aW8gOiBKcy5udW1iZXJfdCBKcy5yZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIGlzSW50ZXJzZWN0aW5nIDogYm9vbCBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgdGltZSA6IEpzLm51bWJlcl90IEpzLnJlYWRvbmx5X3Byb3BcbmVuZFxuXG5jbGFzcyB0eXBlIGludGVyc2VjdGlvbk9ic2VydmVyT3B0aW9ucyA9IG9iamVjdFxuICBtZXRob2Qgcm9vdCA6IERvbS5ub2RlIEpzLnQgSnMud3JpdGVvbmx5X3Byb3BcblxuICBtZXRob2Qgcm9vdE1hcmdpbiA6IEpzLmpzX3N0cmluZyBKcy50IEpzLndyaXRlb25seV9wcm9wXG5cbiAgbWV0aG9kIHRocmVzaG9sZCA6IEpzLm51bWJlcl90IEpzLmpzX2FycmF5IEpzLnQgSnMud3JpdGVvbmx5X3Byb3BcbmVuZFxuXG5jbGFzcyB0eXBlIGludGVyc2VjdGlvbk9ic2VydmVyID0gb2JqZWN0XG4gIG1ldGhvZCByb290IDogRG9tLm5vZGUgSnMudCBKcy5vcHQgSnMucmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCByb290TWFyZ2luIDogSnMuanNfc3RyaW5nIEpzLnQgSnMucmVhZG9ubHlfcHJvcFxuXG4gIG1ldGhvZCB0aHJlc2hvbGRzIDogSnMubnVtYmVyX3QgSnMuanNfYXJyYXkgSnMudCBKcy5yZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIG9ic2VydmUgOiAjRG9tLm5vZGUgSnMudCAtPiB1bml0IEpzLm1ldGhcblxuICBtZXRob2QgdW5vYnNlcnZlIDogI0RvbS5ub2RlIEpzLnQgLT4gdW5pdCBKcy5tZXRoXG5cbiAgbWV0aG9kIGRpc2Nvbm5lY3QgOiB1bml0IEpzLm1ldGhcblxuICBtZXRob2QgdGFrZVJlY29yZHMgOiBpbnRlcnNlY3Rpb25PYnNlcnZlckVudHJ5IEpzLnQgSnMuanNfYXJyYXkgSnMubWV0aFxuZW5kXG5cbmxldCBlbXB0eV9pbnRlcnNlY3Rpb25fb2JzZXJ2ZXJfb3B0aW9ucyAoKSA6IGludGVyc2VjdGlvbk9ic2VydmVyT3B0aW9ucyBKcy50ID1cbiAgSnMuVW5zYWZlLm9iaiBbfHxdXG5cbmxldCBpbnRlcnNlY3Rpb25PYnNlcnZlcl91bnNhZmUgPSBKcy5VbnNhZmUuZ2xvYmFsIyMuX0ludGVyc2VjdGlvbk9ic2VydmVyXG5cbmxldCBpc19zdXBwb3J0ZWQgKCkgPSBKcy5PcHRkZWYudGVzdCBpbnRlcnNlY3Rpb25PYnNlcnZlcl91bnNhZmVcblxubGV0IGludGVyc2VjdGlvbk9ic2VydmVyIDpcbiAgICAoICAgKCAgIGludGVyc2VjdGlvbk9ic2VydmVyRW50cnkgSnMudCBKcy5qc19hcnJheSBKcy50XG4gICAgICAgICAtPiBpbnRlcnNlY3Rpb25PYnNlcnZlciBKcy50XG4gICAgICAgICAtPiB1bml0KVxuICAgICAgICBKcy5jYWxsYmFja1xuICAgICAtPiBpbnRlcnNlY3Rpb25PYnNlcnZlck9wdGlvbnMgSnMudFxuICAgICAtPiBpbnRlcnNlY3Rpb25PYnNlcnZlciBKcy50KVxuICAgIEpzLmNvbnN0ciA9XG4gIGludGVyc2VjdGlvbk9ic2VydmVyX3Vuc2FmZVxuIiwiKCogSnNfb2Zfb2NhbWwgbGlicmFyeVxuICogaHR0cDovL3d3dy5vY3NpZ2VuLm9yZy9qc19vZl9vY2FtbC9cbiAqIENvcHlyaWdodCAoQykgMjAxOCBTdMOpcGhhbmUgTGVncmFuZFxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHdpdGggbGlua2luZyBleGNlcHRpb247XG4gKiBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcsIFVTQS5cbiAqKVxub3BlbiEgSW1wb3J0XG5cbm1vZHVsZSB0eXBlIFNoYXJlZCA9IHNpZ1xuICBjbGFzcyB0eXBlIG9iamVjdF9vcHRpb25zID0gb2JqZWN0XG4gICAgbWV0aG9kIGxvY2FsZU1hdGNoZXIgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5wcm9wXG4gIGVuZFxuXG4gIHZhbCBvYmplY3Rfb3B0aW9ucyA6IHVuaXQgLT4gb2JqZWN0X29wdGlvbnMgSnMudFxuXG4gIGNsYXNzIHR5cGUgX29iamVjdCA9IG9iamVjdFxuICAgIG1ldGhvZCBzdXBwb3J0ZWRMb2NhbGVzT2YgOlxuICAgICAgICAgSnMuanNfc3RyaW5nIEpzLnQgSnMuanNfYXJyYXkgSnMudFxuICAgICAgLT4gb2JqZWN0X29wdGlvbnMgSnMudCBKcy5vcHRkZWZcbiAgICAgIC0+IEpzLmpzX3N0cmluZyBKcy50IEpzLmpzX2FycmF5IEpzLnQgSnMubWV0aFxuICBlbmRcbmVuZFxuXG5tb2R1bGUgU2hhcmVkIDogU2hhcmVkID0gc3RydWN0XG4gIGNsYXNzIHR5cGUgb2JqZWN0X29wdGlvbnMgPSBvYmplY3RcbiAgICBtZXRob2QgbG9jYWxlTWF0Y2hlciA6IEpzLmpzX3N0cmluZyBKcy50IEpzLnByb3BcbiAgZW5kXG5cbiAgbGV0IG9iamVjdF9vcHRpb25zICgpID1cbiAgICBvYmplY3QlanNcbiAgICAgIHZhbCBtdXRhYmxlIGxvY2FsZU1hdGNoZXIgPSBKcy5zdHJpbmcgXCJiZXN0IGZpdFwiXG4gICAgZW5kXG5cbiAgY2xhc3MgdHlwZSBfb2JqZWN0ID0gb2JqZWN0XG4gICAgbWV0aG9kIHN1cHBvcnRlZExvY2FsZXNPZiA6XG4gICAgICAgICBKcy5qc19zdHJpbmcgSnMudCBKcy5qc19hcnJheSBKcy50XG4gICAgICAtPiBvYmplY3Rfb3B0aW9ucyBKcy50IEpzLm9wdGRlZlxuICAgICAgLT4gSnMuanNfc3RyaW5nIEpzLnQgSnMuanNfYXJyYXkgSnMudCBKcy5tZXRoXG4gIGVuZFxuZW5kXG5cbm1vZHVsZSBDb2xsYXRvciA9IHN0cnVjdFxuICBpbmNsdWRlIFNoYXJlZFxuXG4gIGNsYXNzIHR5cGUgcmVzb2x2ZWRfb3B0aW9ucyA9IG9iamVjdFxuICAgIG1ldGhvZCBsb2NhbGUgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5yZWFkb25seV9wcm9wXG5cbiAgICBtZXRob2QgdXNhZ2UgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5yZWFkb25seV9wcm9wXG5cbiAgICBtZXRob2Qgc2Vuc2l0aXZpdHkgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5yZWFkb25seV9wcm9wXG5cbiAgICBtZXRob2QgaWdub3JlUHVuY3R1YXRpb24gOiBib29sIEpzLnQgSnMucmVhZG9ubHlfcHJvcFxuXG4gICAgbWV0aG9kIGNvbGxhdGlvbiA6IEpzLmpzX3N0cmluZyBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICAgIG1ldGhvZCBudW1lcmljIDogYm9vbCBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICAgIG1ldGhvZCBjYXNlRmlyc3QgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5yZWFkb25seV9wcm9wXG4gIGVuZFxuXG4gIGNsYXNzIHR5cGUgb3B0aW9ucyA9IG9iamVjdFxuICAgIG1ldGhvZCBsb2NhbGVNYXRjaGVyIDogSnMuanNfc3RyaW5nIEpzLnQgSnMucHJvcFxuXG4gICAgbWV0aG9kIHVzYWdlIDogSnMuanNfc3RyaW5nIEpzLnQgSnMucHJvcFxuXG4gICAgbWV0aG9kIHNlbnNpdGl2aXR5IDogSnMuanNfc3RyaW5nIEpzLnQgSnMucHJvcFxuXG4gICAgbWV0aG9kIGlnbm9yZVB1bmN0dWF0aW9uIDogYm9vbCBKcy50IEpzLnByb3BcblxuICAgIG1ldGhvZCBudW1lcmljIDogYm9vbCBKcy50IEpzLnByb3BcblxuICAgIG1ldGhvZCBjYXNlRmlyc3QgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5wcm9wXG4gIGVuZFxuXG4gIGxldCBvcHRpb25zICgpID1cbiAgICBvYmplY3QlanNcbiAgICAgIHZhbCBtdXRhYmxlIGxvY2FsZU1hdGNoZXIgPSBKcy5zdHJpbmcgXCJiZXN0IGZpdFwiXG5cbiAgICAgIHZhbCBtdXRhYmxlIHVzYWdlID0gSnMuc3RyaW5nIFwic29ydFwiXG5cbiAgICAgIHZhbCBtdXRhYmxlIHNlbnNpdGl2aXR5ID0gSnMuc3RyaW5nIFwidmFyaWFudFwiXG5cbiAgICAgIHZhbCBtdXRhYmxlIGlnbm9yZVB1bmN0dWF0aW9uID0gSnMuX2ZhbHNlXG5cbiAgICAgIHZhbCBtdXRhYmxlIG51bWVyaWMgPSBKcy5fZmFsc2VcblxuICAgICAgdmFsIG11dGFibGUgY2FzZUZpcnN0ID0gSnMuc3RyaW5nIFwiZmFsc2VcIlxuICAgIGVuZFxuXG4gIGNsYXNzIHR5cGUgdCA9IG9iamVjdFxuICAgIG1ldGhvZCBjb21wYXJlIDogKEpzLmpzX3N0cmluZyBKcy50IC0+IEpzLmpzX3N0cmluZyBKcy50IC0+IGludCkgSnMucmVhZG9ubHlfcHJvcFxuXG4gICAgbWV0aG9kIHJlc29sdmVkT3B0aW9ucyA6IHVuaXQgLT4gcmVzb2x2ZWRfb3B0aW9ucyBKcy50IEpzLm1ldGhcbiAgZW5kXG5lbmRcblxubW9kdWxlIERhdGVUaW1lRm9ybWF0ID0gc3RydWN0XG4gIGluY2x1ZGUgU2hhcmVkXG5cbiAgY2xhc3MgdHlwZSByZXNvbHZlZF9vcHRpb25zID0gb2JqZWN0XG4gICAgbWV0aG9kIGxvY2FsZSA6IEpzLmpzX3N0cmluZyBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICAgIG1ldGhvZCBjYWxlbmRhciA6IEpzLmpzX3N0cmluZyBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICAgIG1ldGhvZCBudW1iZXJpbmdTeXN0ZW0gOiBKcy5qc19zdHJpbmcgSnMudCBKcy5yZWFkb25seV9wcm9wXG5cbiAgICBtZXRob2QgdGltZVpvbmUgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5yZWFkb25seV9wcm9wXG5cbiAgICBtZXRob2QgaG91cjEyIDogYm9vbCBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICAgIG1ldGhvZCB3ZWVrZGF5IDogSnMuanNfc3RyaW5nIEpzLnQgSnMub3B0ZGVmX3Byb3BcblxuICAgIG1ldGhvZCBlcmEgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5vcHRkZWZfcHJvcFxuXG4gICAgbWV0aG9kIHllYXIgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5vcHRkZWZfcHJvcFxuXG4gICAgbWV0aG9kIG1vbnRoIDogSnMuanNfc3RyaW5nIEpzLnQgSnMub3B0ZGVmX3Byb3BcblxuICAgIG1ldGhvZCBkYXkgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5vcHRkZWZfcHJvcFxuXG4gICAgbWV0aG9kIGhvdXIgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5vcHRkZWZfcHJvcFxuXG4gICAgbWV0aG9kIG1pbnV0ZSA6IEpzLmpzX3N0cmluZyBKcy50IEpzLm9wdGRlZl9wcm9wXG5cbiAgICBtZXRob2Qgc2Vjb25kIDogSnMuanNfc3RyaW5nIEpzLnQgSnMub3B0ZGVmX3Byb3BcblxuICAgIG1ldGhvZCB0aW1lWm9uZU5hbWUgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5vcHRkZWZfcHJvcFxuICBlbmRcblxuICBjbGFzcyB0eXBlIG9wdGlvbnMgPSBvYmplY3RcbiAgICBtZXRob2QgZGF0ZVN0eWxlIDogSnMuanNfc3RyaW5nIEpzLnQgSnMub3B0ZGVmIEpzLnByb3BcblxuICAgIG1ldGhvZCB0aW1lU3R5bGUgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5vcHRkZWYgSnMucHJvcFxuXG4gICAgbWV0aG9kIGNhbGVuZGFyIDogSnMuanNfc3RyaW5nIEpzLnQgSnMub3B0ZGVmIEpzLnByb3BcblxuICAgIG1ldGhvZCBkYXlQZXJpb2QgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5vcHRkZWYgSnMucHJvcFxuXG4gICAgbWV0aG9kIG51bWJlcmluZ1N5c3RlbSA6IEpzLmpzX3N0cmluZyBKcy50IEpzLm9wdGRlZiBKcy5wcm9wXG5cbiAgICBtZXRob2QgbG9jYWxlTWF0Y2hlciA6IEpzLmpzX3N0cmluZyBKcy50IEpzLnByb3BcblxuICAgIG1ldGhvZCB0aW1lWm9uZSA6IEpzLmpzX3N0cmluZyBKcy50IEpzLm9wdGRlZiBKcy5wcm9wXG5cbiAgICBtZXRob2QgaG91cjEyIDogYm9vbCBKcy50IEpzLm9wdGRlZiBKcy5wcm9wXG5cbiAgICBtZXRob2QgaG91ckN5Y2xlIDogSnMuanNfc3RyaW5nIEpzLnQgSnMub3B0ZGVmIEpzLnByb3BcblxuICAgIG1ldGhvZCBmb3JtYXRNYXRjaGVyIDogSnMuanNfc3RyaW5nIEpzLnQgSnMucHJvcFxuXG4gICAgbWV0aG9kIHdlZWtkYXkgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5vcHRkZWYgSnMucHJvcFxuXG4gICAgbWV0aG9kIGVyYSA6IEpzLmpzX3N0cmluZyBKcy50IEpzLm9wdGRlZiBKcy5wcm9wXG5cbiAgICBtZXRob2QgeWVhciA6IEpzLmpzX3N0cmluZyBKcy50IEpzLm9wdGRlZiBKcy5wcm9wXG5cbiAgICBtZXRob2QgbW9udGggOiBKcy5qc19zdHJpbmcgSnMudCBKcy5vcHRkZWYgSnMucHJvcFxuXG4gICAgbWV0aG9kIGRheSA6IEpzLmpzX3N0cmluZyBKcy50IEpzLm9wdGRlZiBKcy5wcm9wXG5cbiAgICBtZXRob2QgaG91ciA6IEpzLmpzX3N0cmluZyBKcy50IEpzLm9wdGRlZiBKcy5wcm9wXG5cbiAgICBtZXRob2QgbWludXRlIDogSnMuanNfc3RyaW5nIEpzLnQgSnMub3B0ZGVmIEpzLnByb3BcblxuICAgIG1ldGhvZCBzZWNvbmQgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5vcHRkZWYgSnMucHJvcFxuXG4gICAgbWV0aG9kIGZyYWN0aW9uYWxTZWNvbmREaWdpdHMgOiBpbnQgSnMub3B0ZGVmIEpzLnByb3BcblxuICAgIG1ldGhvZCB0aW1lWm9uZU5hbWUgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5vcHRkZWYgSnMucHJvcFxuICBlbmRcblxuICBsZXQgb3B0aW9ucyAoKSA6IG9wdGlvbnMgSnMudCA9XG4gICAgb2JqZWN0JWpzXG4gICAgICB2YWwgbXV0YWJsZSBkYXRlU3R5bGUgPSBKcy51bmRlZmluZWRcblxuICAgICAgdmFsIG11dGFibGUgdGltZVN0eWxlID0gSnMudW5kZWZpbmVkXG5cbiAgICAgIHZhbCBtdXRhYmxlIGNhbGVuZGFyID0gSnMudW5kZWZpbmVkXG5cbiAgICAgIHZhbCBtdXRhYmxlIGRheVBlcmlvZCA9IEpzLnVuZGVmaW5lZFxuXG4gICAgICB2YWwgbXV0YWJsZSBudW1iZXJpbmdTeXN0ZW0gPSBKcy51bmRlZmluZWRcblxuICAgICAgdmFsIG11dGFibGUgbG9jYWxlTWF0Y2hlciA9IEpzLnN0cmluZyBcImJlc3QgZml0XCJcblxuICAgICAgdmFsIG11dGFibGUgdGltZVpvbmUgPSBKcy51bmRlZmluZWRcblxuICAgICAgdmFsIG11dGFibGUgaG91cjEyID0gSnMudW5kZWZpbmVkXG5cbiAgICAgIHZhbCBtdXRhYmxlIGhvdXJDeWNsZSA9IEpzLnVuZGVmaW5lZFxuXG4gICAgICB2YWwgbXV0YWJsZSBmb3JtYXRNYXRjaGVyID0gSnMuc3RyaW5nIFwiYmVzdCBmaXRcIlxuXG4gICAgICB2YWwgbXV0YWJsZSB3ZWVrZGF5ID0gSnMudW5kZWZpbmVkXG5cbiAgICAgIHZhbCBtdXRhYmxlIGVyYSA9IEpzLnVuZGVmaW5lZFxuXG4gICAgICB2YWwgbXV0YWJsZSB5ZWFyID0gSnMudW5kZWZpbmVkXG5cbiAgICAgIHZhbCBtdXRhYmxlIG1vbnRoID0gSnMudW5kZWZpbmVkXG5cbiAgICAgIHZhbCBtdXRhYmxlIGRheSA9IEpzLnVuZGVmaW5lZFxuXG4gICAgICB2YWwgbXV0YWJsZSBob3VyID0gSnMudW5kZWZpbmVkXG5cbiAgICAgIHZhbCBtdXRhYmxlIG1pbnV0ZSA9IEpzLnVuZGVmaW5lZFxuXG4gICAgICB2YWwgbXV0YWJsZSBzZWNvbmQgPSBKcy51bmRlZmluZWRcblxuICAgICAgdmFsIG11dGFibGUgZnJhY3Rpb25hbFNlY29uZERpZ2l0cyA9IEpzLnVuZGVmaW5lZFxuXG4gICAgICB2YWwgbXV0YWJsZSB0aW1lWm9uZU5hbWUgPSBKcy51bmRlZmluZWRcbiAgICBlbmRcblxuICBjbGFzcyB0eXBlIGZvcm1hdF9wYXJ0ID0gb2JqZWN0XG4gICAgbWV0aG9kIF90eXBlIDogSnMuanNfc3RyaW5nIEpzLnQgSnMucmVhZG9ubHlfcHJvcFxuXG4gICAgbWV0aG9kIF92YWx1ZSA6IEpzLmpzX3N0cmluZyBKcy50IEpzLnJlYWRvbmx5X3Byb3BcbiAgZW5kXG5cbiAgY2xhc3MgdHlwZSB0ID0gb2JqZWN0XG4gICAgbWV0aG9kIGZvcm1hdCA6IChKcy5kYXRlIEpzLnQgLT4gSnMuanNfc3RyaW5nIEpzLnQpIEpzLnJlYWRvbmx5X3Byb3BcblxuICAgIG1ldGhvZCBmb3JtYXRUb1BhcnRzIDpcbiAgICAgIEpzLmRhdGUgSnMudCBKcy5vcHRkZWYgLT4gZm9ybWF0X3BhcnQgSnMudCBKcy5qc19hcnJheSBKcy50IEpzLm1ldGhcblxuICAgIG1ldGhvZCByZXNvbHZlZE9wdGlvbnMgOiB1bml0IC0+IHJlc29sdmVkX29wdGlvbnMgSnMudCBKcy5tZXRoXG4gIGVuZFxuZW5kXG5cbm1vZHVsZSBOdW1iZXJGb3JtYXQgPSBzdHJ1Y3RcbiAgaW5jbHVkZSBTaGFyZWRcblxuICBjbGFzcyB0eXBlIHJlc29sdmVkX29wdGlvbnMgPSBvYmplY3RcbiAgICBtZXRob2QgbG9jYWxlIDogSnMuanNfc3RyaW5nIEpzLnQgSnMucmVhZG9ubHlfcHJvcFxuXG4gICAgbWV0aG9kIG51bWJlcmluZ1N5c3RlbSA6IEpzLmpzX3N0cmluZyBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICAgIG1ldGhvZCBzdHlsZSA6IEpzLmpzX3N0cmluZyBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICAgIG1ldGhvZCBjdXJyZW5jeSA6IEpzLmpzX3N0cmluZyBKcy50IEpzLm9wdGRlZl9wcm9wXG5cbiAgICBtZXRob2QgY3VycmVuY3lEaXNwbGF5IDogSnMuanNfc3RyaW5nIEpzLnQgSnMub3B0ZGVmX3Byb3BcblxuICAgIG1ldGhvZCB1c2VHcm91cGluZyA6IGJvb2wgSnMudCBKcy5yZWFkb25seV9wcm9wXG5cbiAgICBtZXRob2QgbWluaW11bUludGVnZXJEaWdpdHMgOiBpbnQgSnMub3B0ZGVmX3Byb3BcblxuICAgIG1ldGhvZCBtaW5pbXVtRnJhY3Rpb25EaWdpdHMgOiBpbnQgSnMub3B0ZGVmX3Byb3BcblxuICAgIG1ldGhvZCBtYXhpbXVtRnJhY3Rpb25EaWdpdHMgOiBpbnQgSnMub3B0ZGVmX3Byb3BcblxuICAgIG1ldGhvZCBtaW5pbXVtU2lnbmlmaWNhbnREaWdpdHMgOiBpbnQgSnMub3B0ZGVmX3Byb3BcblxuICAgIG1ldGhvZCBtYXhpbXVtU2lnbmlmaWNhbnREaWdpdHMgOiBpbnQgSnMub3B0ZGVmX3Byb3BcbiAgZW5kXG5cbiAgY2xhc3MgdHlwZSBvcHRpb25zID0gb2JqZWN0XG4gICAgbWV0aG9kIGNvbXBhY3REaXNwbGF5IDogSnMuanNfc3RyaW5nIEpzLnQgSnMub3B0ZGVmIEpzLnByb3BcblxuICAgIG1ldGhvZCBjdXJyZW5jeSA6IEpzLmpzX3N0cmluZyBKcy50IEpzLm9wdGRlZiBKcy5wcm9wXG5cbiAgICBtZXRob2QgY3VycmVuY3lEaXNwbGF5IDogSnMuanNfc3RyaW5nIEpzLnQgSnMub3B0ZGVmIEpzLnByb3BcblxuICAgIG1ldGhvZCBjdXJyZW5jeVNpZ24gOiBKcy5qc19zdHJpbmcgSnMudCBKcy5vcHRkZWYgSnMucHJvcFxuXG4gICAgbWV0aG9kIGxvY2FsZU1hdGNoZXIgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5wcm9wXG5cbiAgICBtZXRob2Qgbm90YXRpb24gOiBKcy5qc19zdHJpbmcgSnMudCBKcy5vcHRkZWYgSnMucHJvcFxuXG4gICAgbWV0aG9kIG51bWJlcmluZ1N5c3RlbSA6IEpzLmpzX3N0cmluZyBKcy50IEpzLm9wdGRlZiBKcy5wcm9wXG5cbiAgICBtZXRob2Qgc2lnbkRpc3BsYXkgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5vcHRkZWYgSnMucHJvcFxuXG4gICAgbWV0aG9kIHN0eWxlIDogSnMuanNfc3RyaW5nIEpzLnQgSnMucHJvcFxuXG4gICAgbWV0aG9kIHVuaXQgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5vcHRkZWYgSnMucHJvcFxuXG4gICAgbWV0aG9kIHVuaXREaXNwbGF5IDogSnMuanNfc3RyaW5nIEpzLnQgSnMub3B0ZGVmIEpzLnByb3BcblxuICAgIG1ldGhvZCB1c2VHcm91cGluZyA6IGJvb2wgSnMudCBKcy5wcm9wXG5cbiAgICBtZXRob2Qgcm91bmRpbmdNb2RlIDogSnMuanNfc3RyaW5nIEpzLnQgSnMub3B0ZGVmIEpzLnByb3BcblxuICAgIG1ldGhvZCByb3VuZGluZ1ByaW9yaXR5IDogSnMuanNfc3RyaW5nIEpzLnQgSnMub3B0ZGVmIEpzLnByb3BcblxuICAgIG1ldGhvZCByb3VuZGluZ0luY3JlbWVudCA6IEpzLmpzX3N0cmluZyBKcy50IEpzLm9wdGRlZiBKcy5wcm9wXG5cbiAgICBtZXRob2QgdHJhaWxpbmdaZXJvRGlzcGxheSA6IEpzLmpzX3N0cmluZyBKcy50IEpzLm9wdGRlZiBKcy5wcm9wXG5cbiAgICBtZXRob2QgbWluaW11bUludGVnZXJEaWdpdHMgOiBpbnQgSnMub3B0ZGVmIEpzLnByb3BcblxuICAgIG1ldGhvZCBtaW5pbXVtRnJhY3Rpb25EaWdpdHMgOiBpbnQgSnMub3B0ZGVmIEpzLnByb3BcblxuICAgIG1ldGhvZCBtYXhpbXVtRnJhY3Rpb25EaWdpdHMgOiBpbnQgSnMub3B0ZGVmIEpzLnByb3BcblxuICAgIG1ldGhvZCBtaW5pbXVtU2lnbmlmaWNhbnREaWdpdHMgOiBpbnQgSnMub3B0ZGVmIEpzLnByb3BcblxuICAgIG1ldGhvZCBtYXhpbXVtU2lnbmlmaWNhbnREaWdpdHMgOiBpbnQgSnMub3B0ZGVmIEpzLnByb3BcbiAgZW5kXG5cbiAgbGV0IG9wdGlvbnMgKCkgOiBvcHRpb25zIEpzLnQgPVxuICAgIG9iamVjdCVqc1xuICAgICAgdmFsIG11dGFibGUgY29tcGFjdERpc3BsYXkgPSBKcy51bmRlZmluZWRcblxuICAgICAgdmFsIG11dGFibGUgY3VycmVuY3kgPSBKcy51bmRlZmluZWRcblxuICAgICAgdmFsIG11dGFibGUgY3VycmVuY3lEaXNwbGF5ID0gSnMudW5kZWZpbmVkXG5cbiAgICAgIHZhbCBtdXRhYmxlIGN1cnJlbmN5U2lnbiA9IEpzLnVuZGVmaW5lZFxuXG4gICAgICB2YWwgbXV0YWJsZSBsb2NhbGVNYXRjaGVyID0gSnMuc3RyaW5nIFwiYmVzdCBmaXRcIlxuXG4gICAgICB2YWwgbXV0YWJsZSBub3RhdGlvbiA9IEpzLnVuZGVmaW5lZFxuXG4gICAgICB2YWwgbXV0YWJsZSBudW1iZXJpbmdTeXN0ZW0gPSBKcy51bmRlZmluZWRcblxuICAgICAgdmFsIG11dGFibGUgc2lnbkRpc3BsYXkgPSBKcy51bmRlZmluZWRcblxuICAgICAgdmFsIG11dGFibGUgc3R5bGUgPSBKcy5zdHJpbmcgXCJkZWNpbWFsXCJcblxuICAgICAgdmFsIG11dGFibGUgdW5pdCA9IEpzLnVuZGVmaW5lZFxuXG4gICAgICB2YWwgbXV0YWJsZSB1bml0RGlzcGxheSA9IEpzLnVuZGVmaW5lZFxuXG4gICAgICB2YWwgbXV0YWJsZSB1c2VHcm91cGluZyA9IEpzLl90cnVlXG5cbiAgICAgIHZhbCBtdXRhYmxlIHJvdW5kaW5nTW9kZSA9IEpzLnVuZGVmaW5lZFxuXG4gICAgICB2YWwgbXV0YWJsZSByb3VuZGluZ1ByaW9yaXR5ID0gSnMudW5kZWZpbmVkXG5cbiAgICAgIHZhbCBtdXRhYmxlIHJvdW5kaW5nSW5jcmVtZW50ID0gSnMudW5kZWZpbmVkXG5cbiAgICAgIHZhbCBtdXRhYmxlIHRyYWlsaW5nWmVyb0Rpc3BsYXkgPSBKcy51bmRlZmluZWRcblxuICAgICAgdmFsIG11dGFibGUgbWluaW11bUludGVnZXJEaWdpdHMgPSBKcy51bmRlZmluZWRcblxuICAgICAgdmFsIG11dGFibGUgbWluaW11bUZyYWN0aW9uRGlnaXRzID0gSnMudW5kZWZpbmVkXG5cbiAgICAgIHZhbCBtdXRhYmxlIG1heGltdW1GcmFjdGlvbkRpZ2l0cyA9IEpzLnVuZGVmaW5lZFxuXG4gICAgICB2YWwgbXV0YWJsZSBtaW5pbXVtU2lnbmlmaWNhbnREaWdpdHMgPSBKcy51bmRlZmluZWRcblxuICAgICAgdmFsIG11dGFibGUgbWF4aW11bVNpZ25pZmljYW50RGlnaXRzID0gSnMudW5kZWZpbmVkXG4gICAgZW5kXG5cbiAgY2xhc3MgdHlwZSBmb3JtYXRfcGFydCA9IG9iamVjdFxuICAgIG1ldGhvZCBfdHlwZSA6IEpzLmpzX3N0cmluZyBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICAgIG1ldGhvZCBfdmFsdWUgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5yZWFkb25seV9wcm9wXG4gIGVuZFxuXG4gIGNsYXNzIHR5cGUgdCA9IG9iamVjdFxuICAgIG1ldGhvZCBmb3JtYXQgOiAoSnMubnVtYmVyIEpzLnQgLT4gSnMuanNfc3RyaW5nIEpzLnQpIEpzLnJlYWRvbmx5X3Byb3BcblxuICAgIG1ldGhvZCBmb3JtYXRUb1BhcnRzIDpcbiAgICAgIEpzLm51bWJlciBKcy50IEpzLm9wdGRlZiAtPiBmb3JtYXRfcGFydCBKcy50IEpzLmpzX2FycmF5IEpzLnQgSnMubWV0aFxuXG4gICAgbWV0aG9kIHJlc29sdmVkT3B0aW9ucyA6IHVuaXQgLT4gcmVzb2x2ZWRfb3B0aW9ucyBKcy50IEpzLm1ldGhcbiAgZW5kXG5lbmRcblxubW9kdWxlIFBsdXJhbFJ1bGVzID0gc3RydWN0XG4gIGluY2x1ZGUgU2hhcmVkXG5cbiAgY2xhc3MgdHlwZSByZXNvbHZlZF9vcHRpb25zID0gb2JqZWN0XG4gICAgbWV0aG9kIGxvY2FsZSA6IEpzLmpzX3N0cmluZyBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICAgIG1ldGhvZCBwbHVyYWxDYXRlZ29yaWVzIDogSnMuanNfc3RyaW5nIEpzLnQgSnMuanNfYXJyYXkgSnMudCBKcy5yZWFkb25seV9wcm9wXG5cbiAgICBtZXRob2QgX3R5cGUgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5yZWFkb25seV9wcm9wXG5cbiAgICBtZXRob2QgbWluaW11bUludGVnZXJEaWdpdHMgOiBpbnQgSnMub3B0ZGVmX3Byb3BcblxuICAgIG1ldGhvZCBtaW5pbXVtRnJhY3Rpb25EaWdpdHMgOiBpbnQgSnMub3B0ZGVmX3Byb3BcblxuICAgIG1ldGhvZCBtYXhpbXVtRnJhY3Rpb25EaWdpdHMgOiBpbnQgSnMub3B0ZGVmX3Byb3BcblxuICAgIG1ldGhvZCBtaW5pbXVtU2lnbmlmaWNhbnREaWdpdHMgOiBpbnQgSnMub3B0ZGVmX3Byb3BcblxuICAgIG1ldGhvZCBtYXhpbXVtU2lnbmlmaWNhbnREaWdpdHMgOiBpbnQgSnMub3B0ZGVmX3Byb3BcbiAgZW5kXG5cbiAgY2xhc3MgdHlwZSBvcHRpb25zID0gb2JqZWN0XG4gICAgbWV0aG9kIGxvY2FsZU1hdGNoZXIgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5wcm9wXG5cbiAgICBtZXRob2QgX3R5cGUgOiBKcy5qc19zdHJpbmcgSnMudCBKcy5wcm9wXG4gIGVuZFxuXG4gIGxldCBvcHRpb25zICgpIDogb3B0aW9ucyBKcy50ID1cbiAgICBvYmplY3QlanNcbiAgICAgIHZhbCBtdXRhYmxlIGxvY2FsZU1hdGNoZXIgPSBKcy5zdHJpbmcgXCJiZXN0IGZpdFwiXG5cbiAgICAgIHZhbCBtdXRhYmxlIF90eXBlID0gSnMuc3RyaW5nIFwiY2FyZGluYWxcIlxuICAgIGVuZFxuXG4gIGNsYXNzIHR5cGUgdCA9IG9iamVjdFxuICAgIG1ldGhvZCBzZWxlY3QgOiBKcy5udW1iZXIgSnMudCAtPiBKcy5qc19zdHJpbmcgSnMudCBKcy5tZXRoXG5cbiAgICBtZXRob2QgcmVzb2x2ZWRPcHRpb25zIDogdW5pdCAtPiByZXNvbHZlZF9vcHRpb25zIEpzLnQgSnMubWV0aFxuICBlbmRcbmVuZFxuXG5jbGFzcyB0eXBlIGludGwgPSBvYmplY3RcbiAgbWV0aG9kIF9Db2xsYXRvciA6IENvbGxhdG9yLl9vYmplY3QgSnMudCBKcy5yZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9EYXRlVGltZUZvcm1hdCA6IERhdGVUaW1lRm9ybWF0Ll9vYmplY3QgSnMudCBKcy5yZWFkb25seV9wcm9wXG5cbiAgbWV0aG9kIF9OdW1iZXJGb3JtYXQgOiBOdW1iZXJGb3JtYXQuX29iamVjdCBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgX1BsdXJhbFJ1bGVzIDogUGx1cmFsUnVsZXMuX29iamVjdCBKcy50IEpzLnJlYWRvbmx5X3Byb3BcblxuICBtZXRob2QgZ2V0Q2Fub25pY2FsTG9jYWxlcyA6XG4gICAgSnMuanNfc3RyaW5nIEpzLnQgSnMuanNfYXJyYXkgSnMudCAtPiBKcy5qc19zdHJpbmcgSnMudCBKcy5qc19hcnJheSBKcy50IEpzLm1ldGhcbmVuZFxuXG5sZXQgaW50bCA9IEpzLlVuc2FmZS5nbG9iYWwjIy5fSW50bFxuXG5sZXQgY29sbGF0b3JfY29uc3RyID0gSnMuVW5zYWZlLmdsb2JhbCMjLl9JbnRsIyMuX0NvbGxhdG9yXG5cbmxldCBkYXRlVGltZUZvcm1hdF9jb25zdHIgPSBKcy5VbnNhZmUuZ2xvYmFsIyMuX0ludGwjIy5fRGF0ZVRpbWVGb3JtYXRcblxubGV0IG51bWJlckZvcm1hdF9jb25zdHIgPSBKcy5VbnNhZmUuZ2xvYmFsIyMuX0ludGwjIy5fTnVtYmVyRm9ybWF0XG5cbmxldCBwbHVyYWxSdWxlc19jb25zdHIgPSBKcy5VbnNhZmUuZ2xvYmFsIyMuX0ludGwjIy5fUGx1cmFsUnVsZXNcblxubGV0IGlzX3N1cHBvcnRlZCAoKSA9IEpzLk9wdGRlZi50ZXN0IGludGxcbiIsIlxudHlwZSBjb3FfRGVjaXNpb24gPSBib29sXG5cbigqKiB2YWwgZGVjaWRlIDogY29xX0RlY2lzaW9uIC0+IGJvb2wgKiopXG5cbmxldCBkZWNpZGUgZGVjaXNpb24gPVxuICBkZWNpc2lvblxuXG50eXBlICgnYSwgJ2IpIGNvcV9SZWxEZWNpc2lvbiA9ICdhIC0+ICdiIC0+IGNvcV9EZWNpc2lvblxuXG4oKiogdmFsIGRlY2lkZV9yZWwgOlxuICAgICgnYTEsICdhMikgY29xX1JlbERlY2lzaW9uIC0+ICdhMSAtPiAnYTIgLT4gY29xX0RlY2lzaW9uICoqKVxuXG5sZXQgZGVjaWRlX3JlbCByZWxEZWNpc2lvbiA9XG4gIHJlbERlY2lzaW9uXG5cbnR5cGUgJ2EgY29xX1RvcCA9ICdhXG5cbigqKiB2YWwgdG9wIDogJ2ExIGNvcV9Ub3AgLT4gJ2ExICoqKVxuXG5sZXQgdG9wIHRvcDAgPVxuICB0b3AwXG5cbnR5cGUgJ2EgY29xX0JvdHRvbSA9ICdhXG5cbigqKiB2YWwgYm90dG9tIDogJ2ExIGNvcV9Cb3R0b20gLT4gJ2ExICoqKVxuXG5sZXQgYm90dG9tIGJvdHRvbTAgPVxuICBib3R0b20wXG4iLCJvcGVuIFVuaXZfZ2VuX2V4dFxuXG50eXBlIF9fID0gT2JqLnRcblxudHlwZSBjb3FfTVByb3BGID1cbnwgVmFyIG9mIGNoYXIgbGlzdFxufCBCb3RcbnwgSW1wIG9mIGNvcV9NUHJvcEYgKiBjb3FfTVByb3BGXG58IEJveCBvZiBjb3FfTVByb3BGXG5cbigqKiB2YWwgY29xX1RvcCA6IGNvcV9NUHJvcEYgKiopXG5cbmxldCBjb3FfVG9wID1cbiAgSW1wIChCb3QsIEJvdClcblxuKCoqIHZhbCBjb3FfTmVnIDogY29xX01Qcm9wRiAtPiBjb3FfTVByb3BGICoqKVxuXG5sZXQgY29xX05lZyBhID1cbiAgSW1wIChhLCBCb3QpXG5cbigqKiB2YWwgY29xX0FuZCA6IGNvcV9NUHJvcEYgLT4gY29xX01Qcm9wRiAtPiBjb3FfTVByb3BGICoqKVxuXG5sZXQgY29xX0FuZCBhIGIgPVxuICBjb3FfTmVnIChJbXAgKGEsIChjb3FfTmVnIGIpKSlcblxuKCoqIHZhbCBjb3FfT3IgOiBjb3FfTVByb3BGIC0+IGNvcV9NUHJvcEYgLT4gY29xX01Qcm9wRiAqKilcblxubGV0IGNvcV9PciBhIGIgPVxuICBJbXAgKChjb3FfTmVnIGEpLCBiKVxuXG4oKiogdmFsIGNvcV9EaWFtIDogY29xX01Qcm9wRiAtPiBjb3FfTVByb3BGICoqKVxuXG5sZXQgY29xX0RpYW0gYSA9XG4gIGNvcV9OZWcgKEJveCAoY29xX05lZyBhKSlcblxuKCoqIHZhbCBlcV9kZWNfZm9ybSA6IGNvcV9NUHJvcEYgLT4gY29xX01Qcm9wRiAtPiBib29sICoqKVxuXG5sZXQgcmVjIGVxX2RlY19mb3JtIG0geDAgPVxuICBtYXRjaCBtIHdpdGhcbiAgfCBWYXIgcyAtPlxuICAgIChtYXRjaCB4MCB3aXRoXG4gICAgIHwgVmFyIHMwIC0+XG4gICAgICAgbGV0IHJlYyBmIHMxIHgxID1cbiAgICAgICAgIG1hdGNoIHMxIHdpdGhcbiAgICAgICAgIHwgW10gLT4gKG1hdGNoIHgxIHdpdGhcbiAgICAgICAgICAgICAgICAgIHwgW10gLT4gdHJ1ZVxuICAgICAgICAgICAgICAgICAgfCBfOjpfIC0+IGZhbHNlKVxuICAgICAgICAgfCBhOjpzMiAtPlxuICAgICAgICAgICAobWF0Y2ggeDEgd2l0aFxuICAgICAgICAgICAgfCBbXSAtPiBmYWxzZVxuICAgICAgICAgICAgfCBhMDo6czMgLT5cbiAgICAgICAgICAgICAgKCogSWYgdGhpcyBhcHBlYXJzLCB5b3UncmUgdXNpbmcgQXNjaWkgaW50ZXJuYWxzLiBQbGVhc2UgZG9uJ3QgKilcbiAoZnVuIGYgYyAtPlxuICBsZXQgbiA9IENoYXIuY29kZSBjIGluXG4gIGxldCBoIGkgPSAobiBsYW5kICgxIGxzbCBpKSkgPD4gMCBpblxuICBmIChoIDApIChoIDEpIChoIDIpIChoIDMpIChoIDQpIChoIDUpIChoIDYpIChoIDcpKVxuICAgICAgICAgICAgICAgIChmdW4gYiBiMCBiMSBiMiBiMyBiNCBiNSBiNiAtPlxuICAgICAgICAgICAgICAgICgqIElmIHRoaXMgYXBwZWFycywgeW91J3JlIHVzaW5nIEFzY2lpIGludGVybmFscy4gUGxlYXNlIGRvbid0ICopXG4gKGZ1biBmIGMgLT5cbiAgbGV0IG4gPSBDaGFyLmNvZGUgYyBpblxuICBsZXQgaCBpID0gKG4gbGFuZCAoMSBsc2wgaSkpIDw+IDAgaW5cbiAgZiAoaCAwKSAoaCAxKSAoaCAyKSAoaCAzKSAoaCA0KSAoaCA1KSAoaCA2KSAoaCA3KSlcbiAgICAgICAgICAgICAgICAgIChmdW4gYjcgYjggYjkgYjEwIGIxMSBiMTIgYjEzIGIxNCAtPlxuICAgICAgICAgICAgICAgICAgaWYgYlxuICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiN1xuICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGlmIGIwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiOFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGlmIGI5XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiMTBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gaWYgYjExXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGlmIGI0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYjExXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGI0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGIxMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYjNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGlmIGIxMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI1XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGIxMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBiNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI1XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYjlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBiMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiMTBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gaWYgYjExXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGlmIGI0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYjExXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGI0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGIxMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYjNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGlmIGIxMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI1XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGIxMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBiNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI1XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGI4XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGIxXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gaWYgYjlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGlmIGIyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGlmIGIxMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGlmIGIzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiMTFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gaWYgYjRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI1XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBiMTFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYjRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI1XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYjEwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBiM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gaWYgYjExXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGlmIGI0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYjExXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGI0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBiOVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGIyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGlmIGIxMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGlmIGIzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiMTFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gaWYgYjRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI1XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBiMTFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYjRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI1XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYjEwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBiM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gaWYgYjExXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGlmIGI0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYjExXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGI0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICBlbHNlIGlmIGI3XG4gICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBiMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gaWYgYjhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gaWYgYjFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiOVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gaWYgYjJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gaWYgYjEwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gaWYgYjNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGlmIGIxMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI1XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGIxMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBiNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI1XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBiMTBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGIzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiMTFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gaWYgYjRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI1XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBiMTFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYjRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI1XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGI5XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYjJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gaWYgYjEwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gaWYgYjNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGlmIGIxMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI1XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGIxMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBiNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI1XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBiMTBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGIzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiMTFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gaWYgYjRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI1XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBiMTFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYjRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI1XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBiOFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBiMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGlmIGI5XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiMTBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gaWYgYjExXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGlmIGI0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYjExXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGI0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGIxMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYjNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGlmIGIxMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI1XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGIxMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBiNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI1XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYjlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBiMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiMTBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gaWYgYjExXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGlmIGI0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYjExXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGI0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGIxMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYjNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGlmIGIxMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBpZiBiNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI1XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGIxMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBiNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjEzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIHMyIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYjE0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGI1XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBiMTRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiBzMiBzM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGIxNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYgczIgczMpXG4gICAgICAgICAgICAgICAgICBhMClcbiAgICAgICAgICAgICAgICBhKVxuICAgICAgIGluIGYgcyBzMFxuICAgICB8IF8gLT4gZmFsc2UpXG4gIHwgQm90IC0+IChtYXRjaCB4MCB3aXRoXG4gICAgICAgICAgICB8IEJvdCAtPiB0cnVlXG4gICAgICAgICAgICB8IF8gLT4gZmFsc2UpXG4gIHwgSW1wIChtMCwgbTEpIC0+XG4gICAgKG1hdGNoIHgwIHdpdGhcbiAgICAgfCBJbXAgKG0yLCBtMykgLT4gaWYgZXFfZGVjX2Zvcm0gbTAgbTIgdGhlbiBlcV9kZWNfZm9ybSBtMSBtMyBlbHNlIGZhbHNlXG4gICAgIHwgXyAtPiBmYWxzZSlcbiAgfCBCb3ggbTAgLT4gKG1hdGNoIHgwIHdpdGhcbiAgICAgICAgICAgICAgIHwgQm94IG0xIC0+IGVxX2RlY19mb3JtIG0wIG0xXG4gICAgICAgICAgICAgICB8IF8gLT4gZmFsc2UpXG5cbnR5cGUgbm9ib3hfZ2VuX2V4dCA9IChjb3FfTVByb3BGLCBfXykgdW5pdl9nZW5fZXh0XG5cbigqKiB2YWwgdW5Cb3hfZm9ybXVsYSA6IGNvcV9NUHJvcEYgLT4gY29xX01Qcm9wRiAqKilcblxubGV0IHVuQm94X2Zvcm11bGEgPSBmdW5jdGlvblxufCBCb3ggYTAgLT4gYTBcbnwgeCAtPiB4XG5cbigqKiB2YWwgdW5ib3hlZF9saXN0IDogY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgbGlzdCAqKilcblxubGV0IHJlYyB1bmJveGVkX2xpc3QgPSBmdW5jdGlvblxufCBbXSAtPiBbXVxufCBoIDo6IHQgLT4gKHVuQm94X2Zvcm11bGEgaCkgOjogKHVuYm94ZWRfbGlzdCB0KVxuXG4oKiogdmFsIHRvcF9ib3hlcyA6IGNvcV9NUHJvcEYgbGlzdCAtPiBjb3FfTVByb3BGIGxpc3QgKiopXG5cbmxldCByZWMgdG9wX2JveGVzID0gZnVuY3Rpb25cbnwgW10gLT4gW11cbnwgaCA6OiB0IC0+XG4gIChtYXRjaCBoIHdpdGhcbiAgIHwgQm94IGEgLT4gKEJveCBhKSA6OiAodG9wX2JveGVzIHQpXG4gICB8IF8gLT4gdG9wX2JveGVzIHQpXG4iLCJcbnR5cGUgbmF0ID1cbnwgT1xufCBTIG9mIG5hdFxuXG50eXBlICgnYSwgJ2IpIHN1bSA9XG58IENvcV9pbmwgb2YgJ2FcbnwgQ29xX2luciBvZiAnYlxuXG4oKiogdmFsIGZzdCA6ICgnYTEgKiAnYTIpIC0+ICdhMSAqKilcblxubGV0IGZzdCA9IGZ1bmN0aW9uXG58ICh4LCBfKSAtPiB4XG5cbigqKiB2YWwgc25kIDogKCdhMSAqICdhMikgLT4gJ2EyICoqKVxuXG5sZXQgc25kID0gZnVuY3Rpb25cbnwgKF8sIHkpIC0+IHlcblxuKCoqIHZhbCBsZW5ndGggOiAnYTEgbGlzdCAtPiBuYXQgKiopXG5cbmxldCByZWMgbGVuZ3RoID0gZnVuY3Rpb25cbnwgW10gLT4gT1xufCBfIDo6IGwnIC0+IFMgKGxlbmd0aCBsJylcblxuKCoqIHZhbCBhcHAgOiAnYTEgbGlzdCAtPiAnYTEgbGlzdCAtPiAnYTEgbGlzdCAqKilcblxubGV0IHJlYyBhcHAgbCBtID1cbiAgbWF0Y2ggbCB3aXRoXG4gIHwgW10gLT4gbVxuICB8IGEgOjogbDEgLT4gYSA6OiAoYXBwIGwxIG0pXG5cbnR5cGUgY29tcGFyaXNvbiA9XG58IEVxXG58IEx0XG58IEd0XG4iLCJvcGVuIERhdGF0eXBlc1xuXG4oKiogdmFsIGxlX2x0X2RlYyA6IG5hdCAtPiBuYXQgLT4gYm9vbCAqKilcblxubGV0IHJlYyBsZV9sdF9kZWMgbiBtID1cbiAgbWF0Y2ggbiB3aXRoXG4gIHwgTyAtPiB0cnVlXG4gIHwgUyBuMCAtPiAobWF0Y2ggbSB3aXRoXG4gICAgICAgICAgICAgfCBPIC0+IGZhbHNlXG4gICAgICAgICAgICAgfCBTIG4xIC0+IGxlX2x0X2RlYyBuMCBuMSlcblxuKCoqIHZhbCBsZV9ndF9kZWMgOiBuYXQgLT4gbmF0IC0+IGJvb2wgKiopXG5cbmxldCBsZV9ndF9kZWMgPVxuICBsZV9sdF9kZWNcblxuKCoqIHZhbCBsZV9kZWMgOiBuYXQgLT4gbmF0IC0+IGJvb2wgKiopXG5cbmxldCBsZV9kZWMgPVxuICBsZV9ndF9kZWNcblxuKCoqIHZhbCBsdF9kZWMgOiBuYXQgLT4gbmF0IC0+IGJvb2wgKiopXG5cbmxldCBsdF9kZWMgbiBtID1cbiAgbGVfZGVjIChTIG4pIG1cbiIsIm9wZW4gRGF0YXR5cGVzXG5cbigqKiB2YWwgYWRkIDogbmF0IC0+IG5hdCAtPiBuYXQgKiopXG5cbmxldCByZWMgYWRkIG4gbSA9XG4gIG1hdGNoIG4gd2l0aFxuICB8IE8gLT4gbVxuICB8IFMgcCAtPiBTIChhZGQgcCBtKVxuIiwiXG4oKiogdmFsIHN0cmluZ19kZWMgOiBjaGFyIGxpc3QgLT4gY2hhciBsaXN0IC0+IGJvb2wgKiopXG5cbmxldCByZWMgc3RyaW5nX2RlYyBzIHggPVxuICBtYXRjaCBzIHdpdGhcbiAgfCBbXSAtPiAobWF0Y2ggeCB3aXRoXG4gICAgICAgICAgIHwgW10gLT4gdHJ1ZVxuICAgICAgICAgICB8IF86Ol8gLT4gZmFsc2UpXG4gIHwgYTo6czAgLT5cbiAgICAobWF0Y2ggeCB3aXRoXG4gICAgIHwgW10gLT4gZmFsc2VcbiAgICAgfCBhMDo6czEgLT4gaWYgKD0pIGEgYTAgdGhlbiBzdHJpbmdfZGVjIHMwIHMxIGVsc2UgZmFsc2UpXG4iLCJvcGVuIERhdGF0eXBlc1xub3BlbiBOYXRcbm9wZW4gU3RyaW5nXG5vcGVuIEJhc2VcblxudHlwZSB2YXJpYWJsZSA9IGNoYXIgbGlzdFxuXG50eXBlIGZvcm0gPVxufCBWYXIgb2YgdmFyaWFibGVcbnwgQm90XG58IEFuZCBvZiBmb3JtICogZm9ybVxufCBPciBvZiBmb3JtICogZm9ybVxufCBJbXBsaWVzIG9mIGZvcm0gKiBmb3JtXG58IEJveCBvZiBmb3JtXG5cbigqKiB2YWwgZm9tdWxhX2JvdHRvbSA6IGZvcm0gY29xX0JvdHRvbSAqKilcblxubGV0IGZvbXVsYV9ib3R0b20gPVxuICBCb3RcblxuKCoqIHZhbCBmb3JtX3RvcCA6IGZvcm0gY29xX1RvcCAqKilcblxubGV0IGZvcm1fdG9wID1cbiAgSW1wbGllcyAoQm90LCBCb3QpXG5cbigqKiB2YWwgc3RyaW5nX2RlYyA6IChjaGFyIGxpc3QsIGNoYXIgbGlzdCkgY29xX1JlbERlY2lzaW9uICoqKVxuXG5sZXQgc3RyaW5nX2RlYyA9XG4gIHN0cmluZ19kZWNcblxuKCoqIHZhbCBmb3JtX2VxX2RlYyA6IChmb3JtLCBmb3JtKSBjb3FfUmVsRGVjaXNpb24gKiopXG5cbmxldCByZWMgZm9ybV9lcV9kZWMgZiB4MCA9XG4gIG1hdGNoIGYgd2l0aFxuICB8IFZhciB2IC0+IChtYXRjaCB4MCB3aXRoXG4gICAgICAgICAgICAgIHwgVmFyIHYwIC0+IGRlY2lkZV9yZWwgc3RyaW5nX2RlYyB2IHYwXG4gICAgICAgICAgICAgIHwgXyAtPiBmYWxzZSlcbiAgfCBCb3QgLT4gKG1hdGNoIHgwIHdpdGhcbiAgICAgICAgICAgIHwgQm90IC0+IHRydWVcbiAgICAgICAgICAgIHwgXyAtPiBmYWxzZSlcbiAgfCBBbmQgKGYwLCBmMSkgLT5cbiAgICAobWF0Y2ggeDAgd2l0aFxuICAgICB8IEFuZCAoZjIsIGYzKSAtPiBpZiBmb3JtX2VxX2RlYyBmMCBmMiB0aGVuIGZvcm1fZXFfZGVjIGYxIGYzIGVsc2UgZmFsc2VcbiAgICAgfCBfIC0+IGZhbHNlKVxuICB8IE9yIChmMCwgZjEpIC0+XG4gICAgKG1hdGNoIHgwIHdpdGhcbiAgICAgfCBPciAoZjIsIGYzKSAtPiBpZiBmb3JtX2VxX2RlYyBmMCBmMiB0aGVuIGZvcm1fZXFfZGVjIGYxIGYzIGVsc2UgZmFsc2VcbiAgICAgfCBfIC0+IGZhbHNlKVxuICB8IEltcGxpZXMgKGYwLCBmMSkgLT5cbiAgICAobWF0Y2ggeDAgd2l0aFxuICAgICB8IEltcGxpZXMgKGYyLCBmMykgLT5cbiAgICAgICBpZiBmb3JtX2VxX2RlYyBmMCBmMiB0aGVuIGZvcm1fZXFfZGVjIGYxIGYzIGVsc2UgZmFsc2VcbiAgICAgfCBfIC0+IGZhbHNlKVxuICB8IEJveCBmMCAtPiAobWF0Y2ggeDAgd2l0aFxuICAgICAgICAgICAgICAgfCBCb3ggZjEgLT4gZm9ybV9lcV9kZWMgZjAgZjFcbiAgICAgICAgICAgICAgIHwgXyAtPiBmYWxzZSlcblxuKCoqIHZhbCB3ZWlnaHQgOiBmb3JtIC0+IG5hdCAqKilcblxubGV0IHJlYyB3ZWlnaHQgPSBmdW5jdGlvblxufCBBbmQgKF9VVTAzYzZfMCwgX1VVMDNjOF8pIC0+XG4gIGFkZCAoYWRkIChTIChTIE8pKSAod2VpZ2h0IF9VVTAzYzZfMCkpICh3ZWlnaHQgX1VVMDNjOF8pXG58IE9yIChfVVUwM2M2XzAsIF9VVTAzYzhfKSAtPlxuICBhZGQgKGFkZCAoUyAoUyAoUyBPKSkpICh3ZWlnaHQgX1VVMDNjNl8wKSkgKHdlaWdodCBfVVUwM2M4XylcbnwgSW1wbGllcyAoX1VVMDNjNl8wLCBfVVUwM2M4XykgLT5cbiAgYWRkIChhZGQgKFMgTykgKHdlaWdodCBfVVUwM2M2XzApKSAod2VpZ2h0IF9VVTAzYzhfKVxufCBCb3ggX1VVMDNjNl8wIC0+IGFkZCAoUyBPKSAod2VpZ2h0IF9VVTAzYzZfMClcbnwgXyAtPiBTIE9cbiIsIlxuKCoqIHZhbCBpbl9kZWMgOiAoJ2ExIC0+ICdhMSAtPiBib29sKSAtPiAnYTEgLT4gJ2ExIGxpc3QgLT4gYm9vbCAqKilcblxubGV0IHJlYyBpbl9kZWMgaCBhID0gZnVuY3Rpb25cbnwgW10gLT4gZmFsc2VcbnwgeSA6OiBsMCAtPiBsZXQgcyA9IGggeSBhIGluIGlmIHMgdGhlbiB0cnVlIGVsc2UgaW5fZGVjIGggYSBsMFxuXG4oKiogdmFsIHJlbW92ZSA6ICgnYTEgLT4gJ2ExIC0+IGJvb2wpIC0+ICdhMSAtPiAnYTEgbGlzdCAtPiAnYTEgbGlzdCAqKilcblxubGV0IHJlYyByZW1vdmUgZXFfZGVjIHggPSBmdW5jdGlvblxufCBbXSAtPiBbXVxufCB5IDo6IHRsIC0+XG4gIGlmIGVxX2RlYyB4IHkgdGhlbiByZW1vdmUgZXFfZGVjIHggdGwgZWxzZSB5IDo6IChyZW1vdmUgZXFfZGVjIHggdGwpXG5cbigqKiB2YWwgbGlzdF9lcV9kZWMgOiAoJ2ExIC0+ICdhMSAtPiBib29sKSAtPiAnYTEgbGlzdCAtPiAnYTEgbGlzdCAtPiBib29sICoqKVxuXG5sZXQgcmVjIGxpc3RfZXFfZGVjIGVxX2RlYyBsIGwnID1cbiAgbWF0Y2ggbCB3aXRoXG4gIHwgW10gLT4gKG1hdGNoIGwnIHdpdGhcbiAgICAgICAgICAgfCBbXSAtPiB0cnVlXG4gICAgICAgICAgIHwgXyA6OiBfIC0+IGZhbHNlKVxuICB8IHkgOjogbDAgLT5cbiAgICAobWF0Y2ggbCcgd2l0aFxuICAgICB8IFtdIC0+IGZhbHNlXG4gICAgIHwgYSA6OiBsMSAtPiBpZiBlcV9kZWMgeSBhIHRoZW4gbGlzdF9lcV9kZWMgZXFfZGVjIGwwIGwxIGVsc2UgZmFsc2UpXG5cbigqKiB2YWwgbWFwIDogKCdhMSAtPiAnYTIpIC0+ICdhMSBsaXN0IC0+ICdhMiBsaXN0ICoqKVxuXG5sZXQgcmVjIG1hcCBmID0gZnVuY3Rpb25cbnwgW10gLT4gW11cbnwgYSA6OiB0IC0+IChmIGEpIDo6IChtYXAgZiB0KVxuXG4oKiogdmFsIG5vZHVwIDogKCdhMSAtPiAnYTEgLT4gYm9vbCkgLT4gJ2ExIGxpc3QgLT4gJ2ExIGxpc3QgKiopXG5cbmxldCByZWMgbm9kdXAgZGVjQSA9IGZ1bmN0aW9uXG58IFtdIC0+IFtdXG58IHggOjogeHMgLT4gaWYgaW5fZGVjIGRlY0EgeCB4cyB0aGVuIG5vZHVwIGRlY0EgeHMgZWxzZSB4IDo6IChub2R1cCBkZWNBIHhzKVxuIiwib3BlbiBCYXNlXG5cbigqKiB2YWwgZm9sZGwgOiAoJ2ExIC0+ICdhMiAtPiAnYTEpIC0+ICdhMSAtPiAnYTIgbGlzdCAtPiAnYTEgKiopXG5cbmxldCByZWMgZm9sZGwgZiBhID0gZnVuY3Rpb25cbnwgW10gLT4gYVxufCB4IDo6IGwwIC0+IGZvbGRsIGYgKGYgYSB4KSBsMFxuXG4oKiogdmFsIGVsZW1fb2ZfbGlzdF9kZWMgOlxuICAgICgnYTEsICdhMSkgY29xX1JlbERlY2lzaW9uIC0+ICgnYTEsICdhMSBsaXN0KSBjb3FfUmVsRGVjaXNpb24gKiopXG5cbmxldCByZWMgZWxlbV9vZl9saXN0X2RlYyBkZWMgeCA9IGZ1bmN0aW9uXG58IFtdIC0+IGZhbHNlXG58IHkgOjogbDAgLT5cbiAgaWYgZGVjaWRlIChkZWNpZGVfcmVsIGRlYyB4IHkpIHRoZW4gdHJ1ZSBlbHNlIGVsZW1fb2ZfbGlzdF9kZWMgZGVjIHggbDBcbiIsIm9wZW4gRGF0YXR5cGVzXG5vcGVuIEJhc2VcblxuKCoqIHZhbCBjb21wYXJpc29uX2VxX2RlYyA6IChjb21wYXJpc29uLCBjb21wYXJpc29uKSBjb3FfUmVsRGVjaXNpb24gKiopXG5cbmxldCBjb21wYXJpc29uX2VxX2RlYyB4IHkgPVxuICBtYXRjaCB4IHdpdGhcbiAgfCBFcSAtPiAobWF0Y2ggeSB3aXRoXG4gICAgICAgICAgIHwgRXEgLT4gdHJ1ZVxuICAgICAgICAgICB8IF8gLT4gZmFsc2UpXG4gIHwgTHQgLT4gKG1hdGNoIHkgd2l0aFxuICAgICAgICAgICB8IEx0IC0+IHRydWVcbiAgICAgICAgICAgfCBfIC0+IGZhbHNlKVxuICB8IEd0IC0+IChtYXRjaCB5IHdpdGhcbiAgICAgICAgICAgfCBHdCAtPiB0cnVlXG4gICAgICAgICAgIHwgXyAtPiBmYWxzZSlcbiIsIm9wZW4gRGF0YXR5cGVzXG5vcGVuIEZvcm11bGFzXG5vcGVuIExpc3Rcbm9wZW4gQmFzZVxub3BlbiBMaXN0MFxub3BlbiBOdW1iZXJzXG5cbnR5cGUgX18gPSBPYmoudFxubGV0IF9fID0gbGV0IHJlYyBmIF8gPSBPYmoucmVwciBmIGluIE9iai5yZXByIGZcblxuKCoqIHZhbCBkZWNpZGFibGVfaXNfaW1wbGljYXRpb24gOiBmb3JtIC0+IGZvcm0gLT4gY29xX0RlY2lzaW9uICoqKVxuXG5sZXQgZGVjaWRhYmxlX2lzX2ltcGxpY2F0aW9uIF9VVTAzYzZfIF9VVTAzYzhfID1cbiAgbWF0Y2ggX1VVMDNjNl8gd2l0aFxuICB8IEltcGxpZXMgKF8sIGYpIC0+IGRlY2lkZSAoZGVjaWRlX3JlbCBmb3JtX2VxX2RlYyBmIF9VVTAzYzhfKVxuICB8IF8gLT4gZmFsc2VcblxuKCoqIHZhbCBkZWNpZGFibGVfaXNfbmVnYXRpb24gOiBmb3JtIC0+IGZvcm0gLT4gY29xX0RlY2lzaW9uICoqKVxuXG5sZXQgZGVjaWRhYmxlX2lzX25lZ2F0aW9uIF9VVTAzYzZfIF9VVTAzYzhfID1cbiAgZGVjaWRlIChkZWNpZGVfcmVsIGZvcm1fZXFfZGVjIF9VVTAzYzZfIChJbXBsaWVzIChfVVUwM2M4XywgQm90KSkpXG5cbigqKiB2YWwgb2J2aW91c2x5X3NtYWxsZXIgOiBmb3JtIC0+IGZvcm0gLT4gY29tcGFyaXNvbiAqKilcblxubGV0IHJlYyBvYnZpb3VzbHlfc21hbGxlciBfVVUwM2M2XyBfVVUwM2M4XyA9XG4gIG1hdGNoIF9VVTAzYzZfIHdpdGhcbiAgfCBWYXIgXyAtPlxuICAgIChtYXRjaCBfVVUwM2M4XyB3aXRoXG4gICAgIHwgQm90IC0+IEd0XG4gICAgIHwgSW1wbGllcyAoZiwgXykgLT5cbiAgICAgICAobWF0Y2ggZiB3aXRoXG4gICAgICAgIHwgQm90IC0+IEx0XG4gICAgICAgIHwgXyAtPlxuICAgICAgICAgIGlmIGRlY2lkZSAoZGVjaWRlX3JlbCBmb3JtX2VxX2RlYyBfVVUwM2M2XyBfVVUwM2M4XylcbiAgICAgICAgICB0aGVuIEx0XG4gICAgICAgICAgZWxzZSBpZiBkZWNpZGVcbiAgICAgICAgICAgICAgICAgICAgKGRlY2lkYWJsZV9pc19uZWdhdGlvbiBfVVUwM2M2XyAoSW1wbGllcyAoX1VVMDNjOF8sIEJvdCkpKVxuICAgICAgICAgICAgICAgdGhlbiBHdFxuICAgICAgICAgICAgICAgZWxzZSBpZiBkZWNpZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAoZGVjaWRhYmxlX2lzX25lZ2F0aW9uIF9VVTAzYzhfIChJbXBsaWVzIChfVVUwM2M2XyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIEJvdCkpKVxuICAgICAgICAgICAgICAgICAgICB0aGVuIEx0XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgZGVjaWRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZGVjaWRhYmxlX2lzX2ltcGxpY2F0aW9uIF9VVTAzYzZfIF9VVTAzYzhfKVxuICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gR3RcbiAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGRlY2lkZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZGVjaWRhYmxlX2lzX2ltcGxpY2F0aW9uIF9VVTAzYzhfXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX1VVMDNjNl8pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIEx0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIEVxKVxuICAgICB8IF8gLT5cbiAgICAgICBpZiBkZWNpZGUgKGRlY2lkZV9yZWwgZm9ybV9lcV9kZWMgX1VVMDNjNl8gX1VVMDNjOF8pXG4gICAgICAgdGhlbiBMdFxuICAgICAgIGVsc2UgaWYgZGVjaWRlXG4gICAgICAgICAgICAgICAgIChkZWNpZGFibGVfaXNfbmVnYXRpb24gX1VVMDNjNl8gKEltcGxpZXMgKF9VVTAzYzhfLCBCb3QpKSlcbiAgICAgICAgICAgIHRoZW4gR3RcbiAgICAgICAgICAgIGVsc2UgaWYgZGVjaWRlXG4gICAgICAgICAgICAgICAgICAgICAgKGRlY2lkYWJsZV9pc19uZWdhdGlvbiBfVVUwM2M4XyAoSW1wbGllcyAoX1VVMDNjNl8sXG4gICAgICAgICAgICAgICAgICAgICAgICBCb3QpKSlcbiAgICAgICAgICAgICAgICAgdGhlbiBMdFxuICAgICAgICAgICAgICAgICBlbHNlIGlmIGRlY2lkZSAoZGVjaWRhYmxlX2lzX2ltcGxpY2F0aW9uIF9VVTAzYzZfIF9VVTAzYzhfKVxuICAgICAgICAgICAgICAgICAgICAgIHRoZW4gR3RcbiAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGRlY2lkZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZGVjaWRhYmxlX2lzX2ltcGxpY2F0aW9uIF9VVTAzYzhfIF9VVTAzYzZfKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBMdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBFcSlcbiAgfCBCb3QgLT4gTHRcbiAgfCBBbmQgKF9VVTAzYzZfMCwgX1VVMDNjOF8wKSAtPlxuICAgIChtYXRjaCBfVVUwM2M4XyB3aXRoXG4gICAgIHwgQm90IC0+IEd0XG4gICAgIHwgSW1wbGllcyAoZiwgXykgLT5cbiAgICAgICAobWF0Y2ggZiB3aXRoXG4gICAgICAgIHwgQm90IC0+IEx0XG4gICAgICAgIHwgXyAtPlxuICAgICAgICAgIGxldCBjID0gb2J2aW91c2x5X3NtYWxsZXIgX1VVMDNjNl8wIF9VVTAzYzhfIGluXG4gICAgICAgICAgbGV0IGMwID0gb2J2aW91c2x5X3NtYWxsZXIgX1VVMDNjOF8wIF9VVTAzYzhfIGluXG4gICAgICAgICAgKG1hdGNoIGMgd2l0aFxuICAgICAgICAgICB8IEVxIC0+IChtYXRjaCBjMCB3aXRoXG4gICAgICAgICAgICAgICAgICAgIHwgTHQgLT4gTHRcbiAgICAgICAgICAgICAgICAgICAgfCBfIC0+IEVxKVxuICAgICAgICAgICB8IEx0IC0+IEx0XG4gICAgICAgICAgIHwgR3QgLT4gYzApKVxuICAgICB8IF8gLT5cbiAgICAgICBsZXQgYyA9IG9idmlvdXNseV9zbWFsbGVyIF9VVTAzYzZfMCBfVVUwM2M4XyBpblxuICAgICAgIGxldCBjMCA9IG9idmlvdXNseV9zbWFsbGVyIF9VVTAzYzhfMCBfVVUwM2M4XyBpblxuICAgICAgIChtYXRjaCBjIHdpdGhcbiAgICAgICAgfCBFcSAtPiAobWF0Y2ggYzAgd2l0aFxuICAgICAgICAgICAgICAgICB8IEx0IC0+IEx0XG4gICAgICAgICAgICAgICAgIHwgXyAtPiBFcSlcbiAgICAgICAgfCBMdCAtPiBMdFxuICAgICAgICB8IEd0IC0+IGMwKSlcbiAgfCBPciAoX1VVMDNjNl8wLCBfVVUwM2M4XzApIC0+XG4gICAgKG1hdGNoIF9VVTAzYzhfIHdpdGhcbiAgICAgfCBCb3QgLT4gR3RcbiAgICAgfCBJbXBsaWVzIChmLCBfKSAtPlxuICAgICAgIChtYXRjaCBmIHdpdGhcbiAgICAgICAgfCBCb3QgLT4gTHRcbiAgICAgICAgfCBfIC0+XG4gICAgICAgICAgbGV0IGMgPSBvYnZpb3VzbHlfc21hbGxlciBfVVUwM2M2XzAgX1VVMDNjOF8gaW5cbiAgICAgICAgICBsZXQgYzAgPSBvYnZpb3VzbHlfc21hbGxlciBfVVUwM2M4XzAgX1VVMDNjOF8gaW5cbiAgICAgICAgICAobWF0Y2ggYyB3aXRoXG4gICAgICAgICAgIHwgRXEgLT4gKG1hdGNoIGMwIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgfCBHdCAtPiBHdFxuICAgICAgICAgICAgICAgICAgICB8IF8gLT4gRXEpXG4gICAgICAgICAgIHwgTHQgLT4gYzBcbiAgICAgICAgICAgfCBHdCAtPiBHdCkpXG4gICAgIHwgXyAtPlxuICAgICAgIGxldCBjID0gb2J2aW91c2x5X3NtYWxsZXIgX1VVMDNjNl8wIF9VVTAzYzhfIGluXG4gICAgICAgbGV0IGMwID0gb2J2aW91c2x5X3NtYWxsZXIgX1VVMDNjOF8wIF9VVTAzYzhfIGluXG4gICAgICAgKG1hdGNoIGMgd2l0aFxuICAgICAgICB8IEVxIC0+IChtYXRjaCBjMCB3aXRoXG4gICAgICAgICAgICAgICAgIHwgR3QgLT4gR3RcbiAgICAgICAgICAgICAgICAgfCBfIC0+IEVxKVxuICAgICAgICB8IEx0IC0+IGMwXG4gICAgICAgIHwgR3QgLT4gR3QpKVxuICB8IEltcGxpZXMgKGYsIF8pIC0+XG4gICAgKG1hdGNoIGYgd2l0aFxuICAgICB8IFZhciBfIC0+XG4gICAgICAgKG1hdGNoIF9VVTAzYzhfIHdpdGhcbiAgICAgICAgfCBCb3QgLT4gR3RcbiAgICAgICAgfCBJbXBsaWVzIChmMSwgXykgLT5cbiAgICAgICAgICAobWF0Y2ggZjEgd2l0aFxuICAgICAgICAgICB8IEJvdCAtPiBMdFxuICAgICAgICAgICB8IF8gLT5cbiAgICAgICAgICAgICBpZiBkZWNpZGUgKGRlY2lkZV9yZWwgZm9ybV9lcV9kZWMgX1VVMDNjNl8gX1VVMDNjOF8pXG4gICAgICAgICAgICAgdGhlbiBMdFxuICAgICAgICAgICAgIGVsc2UgaWYgZGVjaWRlXG4gICAgICAgICAgICAgICAgICAgICAgIChkZWNpZGFibGVfaXNfbmVnYXRpb24gX1VVMDNjNl8gKEltcGxpZXMgKF9VVTAzYzhfLFxuICAgICAgICAgICAgICAgICAgICAgICAgIEJvdCkpKVxuICAgICAgICAgICAgICAgICAgdGhlbiBHdFxuICAgICAgICAgICAgICAgICAgZWxzZSBpZiBkZWNpZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZGVjaWRhYmxlX2lzX25lZ2F0aW9uIF9VVTAzYzhfIChJbXBsaWVzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoX1VVMDNjNl8sIEJvdCkpKVxuICAgICAgICAgICAgICAgICAgICAgICB0aGVuIEx0XG4gICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgZGVjaWRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZGVjaWRhYmxlX2lzX2ltcGxpY2F0aW9uIF9VVTAzYzZfIF9VVTAzYzhfKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gR3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGRlY2lkZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZGVjaWRhYmxlX2lzX2ltcGxpY2F0aW9uIF9VVTAzYzhfXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX1VVMDNjNl8pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIEx0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIEVxKVxuICAgICAgICB8IF8gLT5cbiAgICAgICAgICBpZiBkZWNpZGUgKGRlY2lkZV9yZWwgZm9ybV9lcV9kZWMgX1VVMDNjNl8gX1VVMDNjOF8pXG4gICAgICAgICAgdGhlbiBMdFxuICAgICAgICAgIGVsc2UgaWYgZGVjaWRlXG4gICAgICAgICAgICAgICAgICAgIChkZWNpZGFibGVfaXNfbmVnYXRpb24gX1VVMDNjNl8gKEltcGxpZXMgKF9VVTAzYzhfLCBCb3QpKSlcbiAgICAgICAgICAgICAgIHRoZW4gR3RcbiAgICAgICAgICAgICAgIGVsc2UgaWYgZGVjaWRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgKGRlY2lkYWJsZV9pc19uZWdhdGlvbiBfVVUwM2M4XyAoSW1wbGllcyAoX1VVMDNjNl8sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBCb3QpKSlcbiAgICAgICAgICAgICAgICAgICAgdGhlbiBMdFxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGRlY2lkZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRlY2lkYWJsZV9pc19pbXBsaWNhdGlvbiBfVVUwM2M2XyBfVVUwM2M4XylcbiAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIEd0XG4gICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBkZWNpZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRlY2lkYWJsZV9pc19pbXBsaWNhdGlvbiBfVVUwM2M4X1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9VVTAzYzZfKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBMdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBFcSlcbiAgICAgfCBCb3QgLT4gR3RcbiAgICAgfCBCb3ggXyAtPlxuICAgICAgIChtYXRjaCBfVVUwM2M4XyB3aXRoXG4gICAgICAgIHwgQm90IC0+IEd0XG4gICAgICAgIHwgSW1wbGllcyAoZjIsIF8pIC0+XG4gICAgICAgICAgKG1hdGNoIGYyIHdpdGhcbiAgICAgICAgICAgfCBCb3QgLT4gTHRcbiAgICAgICAgICAgfCBfIC0+XG4gICAgICAgICAgICAgaWYgZGVjaWRlIChkZWNpZGVfcmVsIGZvcm1fZXFfZGVjIF9VVTAzYzZfIF9VVTAzYzhfKVxuICAgICAgICAgICAgIHRoZW4gTHRcbiAgICAgICAgICAgICBlbHNlIGlmIGRlY2lkZVxuICAgICAgICAgICAgICAgICAgICAgICAoZGVjaWRhYmxlX2lzX25lZ2F0aW9uIF9VVTAzYzZfIChJbXBsaWVzIChfVVUwM2M4XyxcbiAgICAgICAgICAgICAgICAgICAgICAgICBCb3QpKSlcbiAgICAgICAgICAgICAgICAgIHRoZW4gR3RcbiAgICAgICAgICAgICAgICAgIGVsc2UgaWYgZGVjaWRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRlY2lkYWJsZV9pc19uZWdhdGlvbiBfVVUwM2M4XyAoSW1wbGllc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKF9VVTAzYzZfLCBCb3QpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBMdFxuICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGRlY2lkZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRlY2lkYWJsZV9pc19pbXBsaWNhdGlvbiBfVVUwM2M2XyBfVVUwM2M4XylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIEd0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBkZWNpZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRlY2lkYWJsZV9pc19pbXBsaWNhdGlvbiBfVVUwM2M4X1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9VVTAzYzZfKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBMdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBFcSlcbiAgICAgICAgfCBfIC0+XG4gICAgICAgICAgaWYgZGVjaWRlIChkZWNpZGVfcmVsIGZvcm1fZXFfZGVjIF9VVTAzYzZfIF9VVTAzYzhfKVxuICAgICAgICAgIHRoZW4gTHRcbiAgICAgICAgICBlbHNlIGlmIGRlY2lkZVxuICAgICAgICAgICAgICAgICAgICAoZGVjaWRhYmxlX2lzX25lZ2F0aW9uIF9VVTAzYzZfIChJbXBsaWVzIChfVVUwM2M4XywgQm90KSkpXG4gICAgICAgICAgICAgICB0aGVuIEd0XG4gICAgICAgICAgICAgICBlbHNlIGlmIGRlY2lkZVxuICAgICAgICAgICAgICAgICAgICAgICAgIChkZWNpZGFibGVfaXNfbmVnYXRpb24gX1VVMDNjOF8gKEltcGxpZXMgKF9VVTAzYzZfLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgQm90KSkpXG4gICAgICAgICAgICAgICAgICAgIHRoZW4gTHRcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBkZWNpZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkZWNpZGFibGVfaXNfaW1wbGljYXRpb24gX1VVMDNjNl8gX1VVMDNjOF8pXG4gICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBHdFxuICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgZGVjaWRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkZWNpZGFibGVfaXNfaW1wbGljYXRpb24gX1VVMDNjOF9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfVVUwM2M2XylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gTHRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgRXEpXG4gICAgIHwgXyAtPlxuICAgICAgIChtYXRjaCBfVVUwM2M4XyB3aXRoXG4gICAgICAgIHwgQm90IC0+IEd0XG4gICAgICAgIHwgSW1wbGllcyAoZjMsIF8pIC0+XG4gICAgICAgICAgKG1hdGNoIGYzIHdpdGhcbiAgICAgICAgICAgfCBCb3QgLT4gTHRcbiAgICAgICAgICAgfCBfIC0+XG4gICAgICAgICAgICAgaWYgZGVjaWRlIChkZWNpZGVfcmVsIGZvcm1fZXFfZGVjIF9VVTAzYzZfIF9VVTAzYzhfKVxuICAgICAgICAgICAgIHRoZW4gTHRcbiAgICAgICAgICAgICBlbHNlIGlmIGRlY2lkZVxuICAgICAgICAgICAgICAgICAgICAgICAoZGVjaWRhYmxlX2lzX25lZ2F0aW9uIF9VVTAzYzZfIChJbXBsaWVzIChfVVUwM2M4XyxcbiAgICAgICAgICAgICAgICAgICAgICAgICBCb3QpKSlcbiAgICAgICAgICAgICAgICAgIHRoZW4gR3RcbiAgICAgICAgICAgICAgICAgIGVsc2UgaWYgZGVjaWRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRlY2lkYWJsZV9pc19uZWdhdGlvbiBfVVUwM2M4XyAoSW1wbGllc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKF9VVTAzYzZfLCBCb3QpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBMdFxuICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGRlY2lkZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRlY2lkYWJsZV9pc19pbXBsaWNhdGlvbiBfVVUwM2M2XyBfVVUwM2M4XylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIEd0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBkZWNpZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRlY2lkYWJsZV9pc19pbXBsaWNhdGlvbiBfVVUwM2M4X1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9VVTAzYzZfKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBMdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBFcSlcbiAgICAgICAgfCBfIC0+XG4gICAgICAgICAgaWYgZGVjaWRlIChkZWNpZGVfcmVsIGZvcm1fZXFfZGVjIF9VVTAzYzZfIF9VVTAzYzhfKVxuICAgICAgICAgIHRoZW4gTHRcbiAgICAgICAgICBlbHNlIGlmIGRlY2lkZVxuICAgICAgICAgICAgICAgICAgICAoZGVjaWRhYmxlX2lzX25lZ2F0aW9uIF9VVTAzYzZfIChJbXBsaWVzIChfVVUwM2M4XywgQm90KSkpXG4gICAgICAgICAgICAgICB0aGVuIEd0XG4gICAgICAgICAgICAgICBlbHNlIGlmIGRlY2lkZVxuICAgICAgICAgICAgICAgICAgICAgICAgIChkZWNpZGFibGVfaXNfbmVnYXRpb24gX1VVMDNjOF8gKEltcGxpZXMgKF9VVTAzYzZfLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgQm90KSkpXG4gICAgICAgICAgICAgICAgICAgIHRoZW4gTHRcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBkZWNpZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkZWNpZGFibGVfaXNfaW1wbGljYXRpb24gX1VVMDNjNl8gX1VVMDNjOF8pXG4gICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBHdFxuICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgZGVjaWRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkZWNpZGFibGVfaXNfaW1wbGljYXRpb24gX1VVMDNjOF9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfVVUwM2M2XylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gTHRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgRXEpKVxuICB8IEJveCBfIC0+XG4gICAgKG1hdGNoIF9VVTAzYzhfIHdpdGhcbiAgICAgfCBCb3QgLT4gR3RcbiAgICAgfCBJbXBsaWVzIChmMCwgXykgLT5cbiAgICAgICAobWF0Y2ggZjAgd2l0aFxuICAgICAgICB8IEJvdCAtPiBMdFxuICAgICAgICB8IF8gLT5cbiAgICAgICAgICBpZiBkZWNpZGUgKGRlY2lkZV9yZWwgZm9ybV9lcV9kZWMgX1VVMDNjNl8gX1VVMDNjOF8pXG4gICAgICAgICAgdGhlbiBMdFxuICAgICAgICAgIGVsc2UgaWYgZGVjaWRlXG4gICAgICAgICAgICAgICAgICAgIChkZWNpZGFibGVfaXNfbmVnYXRpb24gX1VVMDNjNl8gKEltcGxpZXMgKF9VVTAzYzhfLCBCb3QpKSlcbiAgICAgICAgICAgICAgIHRoZW4gR3RcbiAgICAgICAgICAgICAgIGVsc2UgaWYgZGVjaWRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgKGRlY2lkYWJsZV9pc19uZWdhdGlvbiBfVVUwM2M4XyAoSW1wbGllcyAoX1VVMDNjNl8sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBCb3QpKSlcbiAgICAgICAgICAgICAgICAgICAgdGhlbiBMdFxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGRlY2lkZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRlY2lkYWJsZV9pc19pbXBsaWNhdGlvbiBfVVUwM2M2XyBfVVUwM2M4XylcbiAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIEd0XG4gICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBkZWNpZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRlY2lkYWJsZV9pc19pbXBsaWNhdGlvbiBfVVUwM2M4X1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9VVTAzYzZfKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBMdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBFcSlcbiAgICAgfCBfIC0+XG4gICAgICAgaWYgZGVjaWRlIChkZWNpZGVfcmVsIGZvcm1fZXFfZGVjIF9VVTAzYzZfIF9VVTAzYzhfKVxuICAgICAgIHRoZW4gTHRcbiAgICAgICBlbHNlIGlmIGRlY2lkZVxuICAgICAgICAgICAgICAgICAoZGVjaWRhYmxlX2lzX25lZ2F0aW9uIF9VVTAzYzZfIChJbXBsaWVzIChfVVUwM2M4XywgQm90KSkpXG4gICAgICAgICAgICB0aGVuIEd0XG4gICAgICAgICAgICBlbHNlIGlmIGRlY2lkZVxuICAgICAgICAgICAgICAgICAgICAgIChkZWNpZGFibGVfaXNfbmVnYXRpb24gX1VVMDNjOF8gKEltcGxpZXMgKF9VVTAzYzZfLFxuICAgICAgICAgICAgICAgICAgICAgICAgQm90KSkpXG4gICAgICAgICAgICAgICAgIHRoZW4gTHRcbiAgICAgICAgICAgICAgICAgZWxzZSBpZiBkZWNpZGUgKGRlY2lkYWJsZV9pc19pbXBsaWNhdGlvbiBfVVUwM2M2XyBfVVUwM2M4XylcbiAgICAgICAgICAgICAgICAgICAgICB0aGVuIEd0XG4gICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBkZWNpZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRlY2lkYWJsZV9pc19pbXBsaWNhdGlvbiBfVVUwM2M4XyBfVVUwM2M2XylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gTHRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgRXEpXG5cbigqKiB2YWwgY2hvb3NlX2NvbmogOiBmb3JtIC0+IGZvcm0gLT4gZm9ybSAqKilcblxubGV0IGNob29zZV9jb25qIF9VVTAzYzZfIF9VVTAzYzhfID1cbiAgbWF0Y2ggb2J2aW91c2x5X3NtYWxsZXIgX1VVMDNjNl8gX1VVMDNjOF8gd2l0aFxuICB8IEVxIC0+IEFuZCAoX1VVMDNjNl8sIF9VVTAzYzhfKVxuICB8IEx0IC0+IF9VVTAzYzZfXG4gIHwgR3QgLT4gX1VVMDNjOF9cblxuKCoqIHZhbCBtYWtlX2NvbmogOiBmb3JtIC0+IGZvcm0gLT4gZm9ybSAqKilcblxubGV0IG1ha2VfY29uaiBfVVUwM2M2XyBfVVUwM2M4XyA9IG1hdGNoIF9VVTAzYzhfIHdpdGhcbnwgQW5kIChfVVUwM2M4XzEsIF9VVTAzYzhfMikgLT5cbiAgKG1hdGNoIG9idmlvdXNseV9zbWFsbGVyIF9VVTAzYzZfIF9VVTAzYzhfMSB3aXRoXG4gICB8IEVxIC0+IEFuZCAoX1VVMDNjNl8sIChBbmQgKF9VVTAzYzhfMSwgX1VVMDNjOF8yKSkpXG4gICB8IEx0IC0+IEFuZCAoX1VVMDNjNl8sIF9VVTAzYzhfMilcbiAgIHwgR3QgLT4gQW5kIChfVVUwM2M4XzEsIF9VVTAzYzhfMikpXG58IE9yIChfVVUwM2M4XzEsIF9VVTAzYzhfMikgLT5cbiAgaWYgZGVjaWRlXG4gICAgICAgKGRlY2lkZV9yZWwgY29tcGFyaXNvbl9lcV9kZWMgKG9idmlvdXNseV9zbWFsbGVyIF9VVTAzYzZfIF9VVTAzYzhfMSlcbiAgICAgICAgIEx0KVxuICB0aGVuIF9VVTAzYzZfXG4gIGVsc2UgaWYgZGVjaWRlXG4gICAgICAgICAgICAoZGVjaWRlX3JlbCBjb21wYXJpc29uX2VxX2RlY1xuICAgICAgICAgICAgICAob2J2aW91c2x5X3NtYWxsZXIgX1VVMDNjNl8gX1VVMDNjOF8yKSBMdClcbiAgICAgICB0aGVuIF9VVTAzYzZfXG4gICAgICAgZWxzZSBjaG9vc2VfY29uaiBfVVUwM2M2XyAoT3IgKF9VVTAzYzhfMSwgX1VVMDNjOF8yKSlcbnwgSW1wbGllcyAoX1VVMDNjOF8xLCBfVVUwM2M4XzIpIC0+XG4gIGlmIGRlY2lkZVxuICAgICAgIChkZWNpZGVfcmVsIGNvbXBhcmlzb25fZXFfZGVjIChvYnZpb3VzbHlfc21hbGxlciBfVVUwM2M2XyBfVVUwM2M4XzEpXG4gICAgICAgICBMdClcbiAgdGhlbiBjaG9vc2VfY29uaiBfVVUwM2M2XyBfVVUwM2M4XzJcbiAgZWxzZSBjaG9vc2VfY29uaiBfVVUwM2M2XyBfVVUwM2M4X1xufCBfIC0+XG4gIChtYXRjaCBfVVUwM2M2XyB3aXRoXG4gICB8IEltcGxpZXMgKF9VVTAzYzZfMSwgX1VVMDNjNl8yKSAtPlxuICAgICBpZiBkZWNpZGVcbiAgICAgICAgICAoZGVjaWRlX3JlbCBjb21wYXJpc29uX2VxX2RlY1xuICAgICAgICAgICAgKG9idmlvdXNseV9zbWFsbGVyIF9VVTAzYzhfIF9VVTAzYzZfMSkgTHQpXG4gICAgIHRoZW4gY2hvb3NlX2NvbmogX1VVMDNjNl8yIF9VVTAzYzhfXG4gICAgIGVsc2UgY2hvb3NlX2NvbmogX1VVMDNjNl8gX1VVMDNjOF9cbiAgIHwgXyAtPiBjaG9vc2VfY29uaiBfVVUwM2M2XyBfVVUwM2M4XylcblxuKCoqIHZhbCBjaG9vc2VfZGlzaiA6IGZvcm0gLT4gZm9ybSAtPiBmb3JtICoqKVxuXG5sZXQgY2hvb3NlX2Rpc2ogX1VVMDNjNl8gX1VVMDNjOF8gPVxuICBtYXRjaCBvYnZpb3VzbHlfc21hbGxlciBfVVUwM2M2XyBfVVUwM2M4XyB3aXRoXG4gIHwgRXEgLT5cbiAgICAobWF0Y2ggb2J2aW91c2x5X3NtYWxsZXIgX1VVMDNjOF8gX1VVMDNjNl8gd2l0aFxuICAgICB8IEVxIC0+IE9yIChfVVUwM2M2XywgX1VVMDNjOF8pXG4gICAgIHwgTHQgLT4gX1VVMDNjNl9cbiAgICAgfCBHdCAtPiBfVVUwM2M4XylcbiAgfCBMdCAtPiBfVVUwM2M4X1xuICB8IEd0IC0+IF9VVTAzYzZfXG5cbigqKiB2YWwgbWFrZV9kaXNqIDogZm9ybSAtPiBmb3JtIC0+IGZvcm0gKiopXG5cbmxldCBtYWtlX2Rpc2ogX1VVMDNjNl8gX1VVMDNjOF8gPSBtYXRjaCBfVVUwM2M4XyB3aXRoXG58IEFuZCAoX1VVMDNjOF8xLCBfVVUwM2M4XzIpIC0+XG4gIGlmIGRlY2lkZVxuICAgICAgIChkZWNpZGVfcmVsIGNvbXBhcmlzb25fZXFfZGVjIChvYnZpb3VzbHlfc21hbGxlciBfVVUwM2M2XyBfVVUwM2M4XzEpXG4gICAgICAgICBHdClcbiAgdGhlbiBfVVUwM2M2X1xuICBlbHNlIGlmIGRlY2lkZVxuICAgICAgICAgICAgKGRlY2lkZV9yZWwgY29tcGFyaXNvbl9lcV9kZWNcbiAgICAgICAgICAgICAgKG9idmlvdXNseV9zbWFsbGVyIF9VVTAzYzZfIF9VVTAzYzhfMikgR3QpXG4gICAgICAgdGhlbiBfVVUwM2M2X1xuICAgICAgIGVsc2UgY2hvb3NlX2Rpc2ogX1VVMDNjNl8gKEFuZCAoX1VVMDNjOF8xLCBfVVUwM2M4XzIpKVxufCBPciAoX1VVMDNjOF8xLCBfVVUwM2M4XzIpIC0+XG4gIChtYXRjaCBvYnZpb3VzbHlfc21hbGxlciBfVVUwM2M2XyBfVVUwM2M4XzEgd2l0aFxuICAgfCBFcSAtPiBPciAoX1VVMDNjNl8sIChPciAoX1VVMDNjOF8xLCBfVVUwM2M4XzIpKSlcbiAgIHwgTHQgLT4gT3IgKF9VVTAzYzhfMSwgX1VVMDNjOF8yKVxuICAgfCBHdCAtPiBPciAoX1VVMDNjNl8sIF9VVTAzYzhfMikpXG58IF8gLT4gY2hvb3NlX2Rpc2ogX1VVMDNjNl8gX1VVMDNjOF9cblxuKCoqIHZhbCBtYWtlX2ltcGwgOiBmb3JtIC0+IGZvcm0gLT4gZm9ybSAqKilcblxubGV0IHJlYyBtYWtlX2ltcGwgX1VVMDNjNl8gX1VVMDNjOF8gPSBtYXRjaCBfVVUwM2M4XyB3aXRoXG58IEltcGxpZXMgKF9VVTAzYzhfMSwgX1VVMDNjOF8yKSAtPlxuICBtYWtlX2ltcGwgKG1ha2VfY29uaiBfVVUwM2M2XyBfVVUwM2M4XzEpIF9VVTAzYzhfMlxufCBfIC0+XG4gIGlmIGRlY2lkZVxuICAgICAgIChkZWNpZGVfcmVsIGNvbXBhcmlzb25fZXFfZGVjIChvYnZpb3VzbHlfc21hbGxlciBfVVUwM2M2XyBfVVUwM2M4XykgTHQpXG4gIHRoZW4gSW1wbGllcyAoQm90LCBCb3QpXG4gIGVsc2UgaWYgZGVjaWRlXG4gICAgICAgICAgICAoZGVjaWRlX3JlbCBjb21wYXJpc29uX2VxX2RlYyAob2J2aW91c2x5X3NtYWxsZXIgX1VVMDNjNl8gQm90KSBMdClcbiAgICAgICB0aGVuIEltcGxpZXMgKEJvdCwgQm90KVxuICAgICAgIGVsc2UgaWYgZGVjaWRlXG4gICAgICAgICAgICAgICAgIChkZWNpZGVfcmVsIGNvbXBhcmlzb25fZXFfZGVjXG4gICAgICAgICAgICAgICAgICAgKG9idmlvdXNseV9zbWFsbGVyIF9VVTAzYzhfIChJbXBsaWVzIChCb3QsIEJvdCkpKSBHdClcbiAgICAgICAgICAgIHRoZW4gSW1wbGllcyAoQm90LCBCb3QpXG4gICAgICAgICAgICBlbHNlIGlmIGRlY2lkZVxuICAgICAgICAgICAgICAgICAgICAgIChkZWNpZGVfcmVsIGNvbXBhcmlzb25fZXFfZGVjXG4gICAgICAgICAgICAgICAgICAgICAgICAob2J2aW91c2x5X3NtYWxsZXIgX1VVMDNjNl8gKEltcGxpZXMgKEJvdCwgQm90KSkpIEd0KVxuICAgICAgICAgICAgICAgICB0aGVuIF9VVTAzYzhfXG4gICAgICAgICAgICAgICAgIGVsc2UgaWYgZGVjaWRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAoZGVjaWRlX3JlbCBjb21wYXJpc29uX2VxX2RlY1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob2J2aW91c2x5X3NtYWxsZXIgX1VVMDNjOF8gQm90KSBMdClcbiAgICAgICAgICAgICAgICAgICAgICB0aGVuIEltcGxpZXMgKF9VVTAzYzZfLCBCb3QpXG4gICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiBkZWNpZGUgKGRlY2lkYWJsZV9pc19uZWdhdGlvbiBfVVUwM2M2XyBfVVUwM2M4XylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gSW1wbGllcyAoX1VVMDNjNl8sIEJvdClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgZGVjaWRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRlY2lkYWJsZV9pc19uZWdhdGlvbiBfVVUwM2M4XyBfVVUwM2M2XylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiBfVVUwM2M4X1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIEltcGxpZXMgKF9VVTAzYzZfLCBfVVUwM2M4XylcblxuKCoqIHZhbCBjb25qdW5jdGlvbiA6IGZvcm0gbGlzdCAtPiBmb3JtICoqKVxuXG5sZXQgY29uanVuY3Rpb24gbCA9XG4gIGZvbGRsIG1ha2VfY29uaiAoSW1wbGllcyAoQm90LCBCb3QpKSAobm9kdXAgZm9ybV9lcV9kZWMgbClcblxuKCoqIHZhbCBkaXNqdW5jdGlvbiA6IGZvcm0gbGlzdCAtPiBmb3JtICoqKVxuXG5sZXQgZGlzanVuY3Rpb24gbCA9XG4gIGZvbGRsIG1ha2VfZGlzaiBCb3QgKG5vZHVwIGZvcm1fZXFfZGVjIGwpXG5cbigqKiB2YWwgaW5fbWFwX2F1eCA6XG4gICAgZm9ybSBsaXN0IC0+IChmb3JtIC0+IF9fIC0+ICdhMSkgLT4gZm9ybSBsaXN0IC0+ICdhMSBsaXN0ICoqKVxuXG5sZXQgcmVjIGluX21hcF9hdXggX1VVMDM5M18gZiA9IGZ1bmN0aW9uXG58IFtdIC0+IFtdXG58IGEgOjogX1VVMDM5M18nMCAtPiAoZiBhIF9fKSA6OiAoaW5fbWFwX2F1eCBfVVUwMzkzXyBmIF9VVTAzOTNfJzApXG5cbigqKiB2YWwgaW5fbWFwIDogZm9ybSBsaXN0IC0+IChmb3JtIC0+IF9fIC0+ICdhMSkgLT4gJ2ExIGxpc3QgKiopXG5cbmxldCBpbl9tYXAgX1VVMDM5M18gZiA9XG4gIGluX21hcF9hdXggX1VVMDM5M18gZiBfVVUwMzkzX1xuXG4oKiogdmFsIHJtIDogZm9ybSAtPiBmb3JtIGxpc3QgLT4gZm9ybSBsaXN0ICoqKVxuXG5sZXQgcmVjIHJtIHggPSBmdW5jdGlvblxufCBbXSAtPiBbXVxufCBoIDo6IHQgLT4gaWYgZm9ybV9lcV9kZWMgeCBoIHRoZW4gdCBlbHNlIGggOjogKHJtIHggdClcblxuKCoqIHZhbCBvcGVuX2JveCA6IGZvcm0gLT4gZm9ybSAqKilcblxubGV0IG9wZW5fYm94IF9VVTAzYzZfID0gbWF0Y2ggX1VVMDNjNl8gd2l0aFxufCBCb3ggX1VVMDNjNl8wIC0+IF9VVTAzYzZfMFxufCBfIC0+IF9VVTAzYzZfXG4iLCJvcGVuIENNTF9TeW50YXhcblxuKCoqIHZhbCBjb3FfWEJveGVkX2xpc3QgOiBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiBsaXN0ICoqKVxuXG5sZXQgcmVjIGNvcV9YQm94ZWRfbGlzdCA9IGZ1bmN0aW9uXG58IFtdIC0+IFtdXG58IGggOjogdCAtPiAodW5Cb3hfZm9ybXVsYSBoKSA6OiAoaCA6OiAoY29xX1hCb3hlZF9saXN0IHQpKVxuXG50eXBlIGNvcV9TZXEgPSBjb3FfTVByb3BGIGxpc3QgKiBjb3FfTVByb3BGIGxpc3RcblxudHlwZSBjb3FfSWRQUnVsZSA9XG58IElkUFJ1bGVfSSBvZiBjaGFyIGxpc3QgKiBjb3FfTVByb3BGIGxpc3QgKiBjb3FfTVByb3BGIGxpc3RcbiAgICogY29xX01Qcm9wRiBsaXN0ICogY29xX01Qcm9wRiBsaXN0XG5cbnR5cGUgY29xX0lkQlJ1bGUgPVxufCBJZEJSdWxlX0kgb2YgY29xX01Qcm9wRiAqIGNvcV9NUHJvcEYgbGlzdCAqIGNvcV9NUHJvcEYgbGlzdFxuICAgKiBjb3FfTVByb3BGIGxpc3QgKiBjb3FfTVByb3BGIGxpc3RcblxudHlwZSBjb3FfQm90TFJ1bGUgPVxufCBCb3RMUnVsZV9JIG9mIGNvcV9NUHJvcEYgbGlzdCAqIGNvcV9NUHJvcEYgbGlzdCAqIGNvcV9NUHJvcEYgbGlzdFxuXG50eXBlIGNvcV9JbXBSUnVsZSA9XG58IEltcFJSdWxlX0kgb2YgY29xX01Qcm9wRiAqIGNvcV9NUHJvcEYgKiBjb3FfTVByb3BGIGxpc3QgKiBjb3FfTVByb3BGIGxpc3RcbiAgICogY29xX01Qcm9wRiBsaXN0ICogY29xX01Qcm9wRiBsaXN0XG5cbnR5cGUgY29xX0ltcExSdWxlID1cbnwgSW1wTFJ1bGVfSSBvZiBjb3FfTVByb3BGICogY29xX01Qcm9wRiAqIGNvcV9NUHJvcEYgbGlzdCAqIGNvcV9NUHJvcEYgbGlzdFxuICAgKiBjb3FfTVByb3BGIGxpc3QgKiBjb3FfTVByb3BGIGxpc3RcblxudHlwZSBjb3FfR0xSUnVsZSA9XG58IEdMUlJ1bGVfSSBvZiBjb3FfTVByb3BGICogY29xX01Qcm9wRiBsaXN0ICogY29xX01Qcm9wRiBsaXN0XG4gICAqIGNvcV9NUHJvcEYgbGlzdCAqIGNvcV9NUHJvcEYgbGlzdCAqIG5vYm94X2dlbl9leHRcbiIsIlxudHlwZSAnYSBjb3FfSW5UID1cbnwgSW5UX2VxJyBvZiAnYSAqICdhIGxpc3RcbnwgSW5UX2NvbnMgb2YgJ2EgKiAnYSBsaXN0ICogJ2EgY29xX0luVFxuXG4oKiogdmFsIGNvcV9JblRfZXEgOiAnYTEgLT4gJ2ExIGxpc3QgLT4gJ2ExIGNvcV9JblQgKiopXG5cbmxldCBjb3FfSW5UX2VxIGEgbCA9XG4gIEluVF9lcScgKGEsIGwpXG4iLCJvcGVuIERhdGF0eXBlc1xub3BlbiBHZW5UXG5cbigqKiB2YWwgY29xX0luVF9hcHBfb3IgOlxuICAgICdhMSBsaXN0IC0+ICdhMSBsaXN0IC0+ICdhMSAtPiAnYTEgY29xX0luVCAtPiAoJ2ExIGNvcV9JblQsICdhMSBjb3FfSW5UKVxuICAgIHN1bSAqKilcblxubGV0IHJlYyBjb3FfSW5UX2FwcF9vciBsIGwyIGEgeCA9XG4gIG1hdGNoIGwgd2l0aFxuICB8IFtdIC0+IENvcV9pbnIgeFxuICB8IHkgOjogbDAgLT5cbiAgICAobWF0Y2ggeCB3aXRoXG4gICAgIHwgSW5UX2VxJyAoXywgXykgLT4gQ29xX2lubCAoY29xX0luVF9lcSB5IGwwKVxuICAgICB8IEluVF9jb25zIChfLCBfLCBpKSAtPlxuICAgICAgIGxldCB4MCA9IGNvcV9JblRfYXBwX29yIGwwIGwyIGEgaSBpblxuICAgICAgIChtYXRjaCB4MCB3aXRoXG4gICAgICAgIHwgQ29xX2lubCBpMCAtPiBDb3FfaW5sIChJblRfY29ucyAoeSwgbDAsIGkwKSlcbiAgICAgICAgfCBDb3FfaW5yIGkwIC0+IENvcV9pbnIgaTApKVxuXG4oKiogdmFsIGNvcV9JblRfb3JfYXBwIDpcbiAgICAnYTEgbGlzdCAtPiAnYTEgbGlzdCAtPiAnYTEgLT4gKCdhMSBjb3FfSW5ULCAnYTEgY29xX0luVCkgc3VtIC0+ICdhMVxuICAgIGNvcV9JblQgKiopXG5cbmxldCByZWMgY29xX0luVF9vcl9hcHAgbCBsMiBhIHggPVxuICBtYXRjaCBsIHdpdGhcbiAgfCBbXSAtPlxuICAgIChtYXRjaCB4IHdpdGhcbiAgICAgfCBDb3FfaW5sIF8gLT4gYXNzZXJ0IGZhbHNlICgqIGFic3VyZCBjYXNlICopXG4gICAgIHwgQ29xX2luciBpIC0+IGkpXG4gIHwgeSA6OiBsMCAtPlxuICAgIChtYXRjaCB4IHdpdGhcbiAgICAgfCBDb3FfaW5sIGkgLT5cbiAgICAgICAobWF0Y2ggaSB3aXRoXG4gICAgICAgIHwgSW5UX2VxJyAoXywgXykgLT5cbiAgICAgICAgICBjb3FfSW5UX2VxIHlcbiAgICAgICAgICAgIChsZXQgcmVjIGFwcDAgbDEgbSA9XG4gICAgICAgICAgICAgICBtYXRjaCBsMSB3aXRoXG4gICAgICAgICAgICAgICB8IFtdIC0+IG1cbiAgICAgICAgICAgICAgIHwgYTAgOjogbDMgLT4gYTAgOjogKGFwcDAgbDMgbSlcbiAgICAgICAgICAgICBpbiBhcHAwIGwwIGwyKVxuICAgICAgICB8IEluVF9jb25zIChfLCBfLCBpMCkgLT5cbiAgICAgICAgICBJblRfY29ucyAoeSwgKGFwcCBsMCBsMiksIChjb3FfSW5UX29yX2FwcCBsMCBsMiBhIChDb3FfaW5sIGkwKSkpKVxuICAgICB8IENvcV9pbnIgaSAtPlxuICAgICAgIEluVF9jb25zICh5LCAoYXBwIGwwIGwyKSwgKGNvcV9JblRfb3JfYXBwIGwwIGwyIGEgKENvcV9pbnIgaSkpKSlcbiIsIm9wZW4gQ01MX1N5bnRheFxub3BlbiBEYXRhdHlwZXNcbm9wZW4gTGlzdFxub3BlbiBMaXN0X2xlbW1hc1Rcbm9wZW4gU3BlY2lmXG5vcGVuIEdlblRcbm9wZW4gR2VuX3RhY3NcblxudHlwZSBfXyA9IE9iai50XG5sZXQgX18gPSBsZXQgcmVjIGYgXyA9IE9iai5yZXByIGYgaW4gT2JqLnJlcHIgZlxuXG4oKiogdmFsIGluX3NwbGl0VCA6XG4gICAgY29xX01Qcm9wRiAtPiBjb3FfTVByb3BGIGxpc3QgLT4gKGNvcV9NUHJvcEYgbGlzdCwgKGNvcV9NUHJvcEYgbGlzdCwgX18pXG4gICAgc2lnVCkgc2lnVCAqKilcblxubGV0IHJlYyBpbl9zcGxpdFQgeCA9IGZ1bmN0aW9uXG58IFtdIC0+IGFzc2VydCBmYWxzZSAoKiBhYnN1cmQgY2FzZSAqKVxufCB5IDo6IGwwIC0+XG4gIGxldCBzID0gZXFfZGVjX2Zvcm0geCB5IGluXG4gIGlmIHNcbiAgdGhlbiBDb3FfZXhpc3RUIChbXSwgKENvcV9leGlzdFQgKGwwLCBfXykpKVxuICBlbHNlIGxldCBoMCA9IGluX3NwbGl0VCB4IGwwIGluXG4gICAgICAgbGV0IENvcV9leGlzdFQgKHgwLCBzMCkgPSBoMCBpblxuICAgICAgIGxldCBDb3FfZXhpc3RUICh4MSwgXykgPSBzMCBpblxuICAgICAgIENvcV9leGlzdFQgKChhcHAgKHkgOjogW10pIHgwKSwgKENvcV9leGlzdFQgKHgxLCBfXykpKVxuXG4oKiogdmFsIGVxX2RlY19saXN0c0YgOiBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiBsaXN0IC0+IGJvb2wgKiopXG5cbmxldCBlcV9kZWNfbGlzdHNGID1cbiAgbGlzdF9lcV9kZWMgZXFfZGVjX2Zvcm1cblxuKCoqIHZhbCBlcV9kZWNfc2VxcyA6IGNvcV9NUHJvcEYgbGlzdCByZWwgLT4gY29xX01Qcm9wRiBsaXN0IHJlbCAtPiBib29sICoqKVxuXG5sZXQgZXFfZGVjX3NlcXMgczAgczEgPVxuICBsZXQgKGwsIGwwKSA9IHMwIGluXG4gIGxldCAobDEsIGwyKSA9IHMxIGluXG4gIGxldCBzID0gZXFfZGVjX2xpc3RzRiBsIGwxIGluIGlmIHMgdGhlbiBlcV9kZWNfbGlzdHNGIGwwIGwyIGVsc2UgZmFsc2VcblxuKCoqIHZhbCBzZXFzX2luX3NwbGl0VCA6XG4gICAgY29xX01Qcm9wRiBsaXN0IHJlbCAtPiBjb3FfTVByb3BGIGxpc3QgcmVsIGxpc3QgLT4gKGNvcV9NUHJvcEYgbGlzdCByZWxcbiAgICBsaXN0LCAoY29xX01Qcm9wRiBsaXN0IHJlbCBsaXN0LCBfXykgc2lnVCkgc2lnVCAqKilcblxubGV0IHJlYyBzZXFzX2luX3NwbGl0VCB4ID0gZnVuY3Rpb25cbnwgW10gLT4gYXNzZXJ0IGZhbHNlICgqIGFic3VyZCBjYXNlICopXG58IHkgOjogbDAgLT5cbiAgbGV0IHMgPSBlcV9kZWNfc2VxcyB4IHkgaW5cbiAgaWYgc1xuICB0aGVuIENvcV9leGlzdFQgKFtdLCAoQ29xX2V4aXN0VCAobDAsIF9fKSkpXG4gIGVsc2UgbGV0IGgwID0gc2Vxc19pbl9zcGxpdFQgeCBsMCBpblxuICAgICAgIGxldCBDb3FfZXhpc3RUICh4MCwgczApID0gaDAgaW5cbiAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDEsIF8pID0gczAgaW5cbiAgICAgICBDb3FfZXhpc3RUICgoYXBwICh5IDo6IFtdKSB4MCksIChDb3FfZXhpc3RUICh4MSwgX18pKSlcblxuKCoqIHZhbCBjb3FfSW5fSW5UX3NlcXMgOlxuICAgIGNvcV9NUHJvcEYgbGlzdCByZWwgLT4gY29xX01Qcm9wRiBsaXN0IHJlbCBsaXN0IC0+IGNvcV9NUHJvcEYgbGlzdCByZWxcbiAgICBjb3FfSW5UICoqKVxuXG5sZXQgY29xX0luX0luVF9zZXFzIHNlcSA9IGZ1bmN0aW9uXG58IFtdIC0+IGFzc2VydCBmYWxzZSAoKiBhYnN1cmQgY2FzZSAqKVxufCB5IDo6IGwgLT5cbiAgbGV0IGggPSBzZXFzX2luX3NwbGl0VCBzZXEgKHkgOjogbCkgaW5cbiAgbGV0IENvcV9leGlzdFQgKHgsIHMpID0gaCBpblxuICBsZXQgQ29xX2V4aXN0VCAoeDAsIF8pID0gcyBpblxuICBjb3FfSW5UX29yX2FwcCB4IChzZXEgOjogeDApIHNlcSAoQ29xX2luciAoY29xX0luVF9lcSBzZXEgeDApKVxuIiwib3BlbiBDTUxfU3ludGF4XG5vcGVuIExpc3RcblxuKCoqIHZhbCBjb3FfSW5fZGVjIDogY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgLT4gYm9vbCAqKilcblxubGV0IGNvcV9Jbl9kZWMgbCBhID1cbiAgaW5fZGVjIGVxX2RlY19mb3JtIGEgbFxuXG4oKiogdmFsIHJlbW92ZV9saXN0IDpcbiAgICBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgbGlzdCAqKilcblxubGV0IHJlYyByZW1vdmVfbGlzdCBsMSBsMiA9XG4gIG1hdGNoIGwxIHdpdGhcbiAgfCBbXSAtPiBsMlxuICB8IGgxIDo6IHQxIC0+IHJlbW92ZSBlcV9kZWNfZm9ybSBoMSAocmVtb3ZlX2xpc3QgdDEgbDIpXG4iLCJvcGVuIENNTF9TeW50YXhcbm9wZW4gRGF0YXR5cGVzXG5vcGVuIEdMU19jYWxjc1xub3BlbiBTcGVjaWZcbm9wZW4gTGlzdF9sZW1zXG5vcGVuIFJlbW92ZV9saXN0X2xlbXNcblxudHlwZSBfXyA9IE9iai50XG5sZXQgX18gPSBsZXQgcmVjIGYgXyA9IE9iai5yZXByIGYgaW4gT2JqLnJlcHIgZlxuXG4oKiogdmFsIGRlY19wcm9wX3Zhcl9pbiA6XG4gICAgKGNvcV9NUHJvcEYgbGlzdCAqIGNvcV9NUHJvcEYgbGlzdCkgLT4gKChjaGFyIGxpc3QsIF9fKSBzaWdULCBfXykgc3VtICoqKVxuXG5sZXQgZGVjX3Byb3BfdmFyX2luID0gZnVuY3Rpb25cbnwgKGwsIGwwKSAtPlxuICBsZXQgcmVjIGYgPSBmdW5jdGlvblxuICB8IFtdIC0+IENvcV9pbnIgX19cbiAgfCB5IDo6IGwyIC0+XG4gICAgKG1hdGNoIGYgbDIgd2l0aFxuICAgICB8IENvcV9pbmwgczAgLT5cbiAgICAgICBsZXQgQ29xX2V4aXN0VCAoeCwgXykgPSBzMCBpbiBDb3FfaW5sIChDb3FfZXhpc3RUICh4LCBfXykpXG4gICAgIHwgQ29xX2luciBfIC0+XG4gICAgICAgKG1hdGNoIHkgd2l0aFxuICAgICAgICB8IFZhciBzMCAtPlxuICAgICAgICAgIGxldCBzMSA9IGNvcV9Jbl9kZWMgbDAgKFZhciBzMCkgaW5cbiAgICAgICAgICBpZiBzMSB0aGVuIENvcV9pbmwgKENvcV9leGlzdFQgKHMwLCBfXykpIGVsc2UgQ29xX2luciBfX1xuICAgICAgICB8IF8gLT4gQ29xX2luciBfXykpXG4gIGluIGYgbFxuXG4oKiogdmFsIGRlY19pc19ib3ggOiBjb3FfTVByb3BGIC0+ICgoY29xX01Qcm9wRiwgX18pIHNpZ1QsIF9fKSBzdW0gKiopXG5cbmxldCBkZWNfaXNfYm94ID0gZnVuY3Rpb25cbnwgQm94IG0gLT4gQ29xX2lubCAoQ29xX2V4aXN0VCAobSwgX18pKVxufCBfIC0+IENvcV9pbnIgX19cblxuKCoqIHZhbCBkZWNfYm94X2luIDpcbiAgICAoY29xX01Qcm9wRiBsaXN0ICogY29xX01Qcm9wRiBsaXN0KSAtPiAoKGNvcV9NUHJvcEYsIF9fKSBzaWdULCBfXykgc3VtICoqKVxuXG5sZXQgZGVjX2JveF9pbiA9IGZ1bmN0aW9uXG58IChsLCBsMCkgLT5cbiAgbGV0IHJlYyBmID0gZnVuY3Rpb25cbiAgfCBbXSAtPiBDb3FfaW5yIF9fXG4gIHwgeSA6OiBsMiAtPlxuICAgIChtYXRjaCBmIGwyIHdpdGhcbiAgICAgfCBDb3FfaW5sIHMwIC0+XG4gICAgICAgbGV0IENvcV9leGlzdFQgKHgsIF8pID0gczAgaW4gQ29xX2lubCAoQ29xX2V4aXN0VCAoeCwgX18pKVxuICAgICB8IENvcV9pbnIgXyAtPlxuICAgICAgIGxldCBzMCA9IGRlY19pc19ib3ggeSBpblxuICAgICAgIChtYXRjaCBzMCB3aXRoXG4gICAgICAgIHwgQ29xX2lubCBzMSAtPlxuICAgICAgICAgIGxldCBzMiA9IGNvcV9Jbl9kZWMgbDAgeSBpblxuICAgICAgICAgIGlmIHMyXG4gICAgICAgICAgdGhlbiBDb3FfaW5sIChsZXQgQ29xX2V4aXN0VCAoeCwgXykgPSBzMSBpbiBDb3FfZXhpc3RUICh4LCBfXykpXG4gICAgICAgICAgZWxzZSBDb3FfaW5yIF9fXG4gICAgICAgIHwgQ29xX2luciBfIC0+IENvcV9pbnIgX18pKVxuICBpbiBmIGxcblxuKCoqIHZhbCBkZWNfaW5pdF9ydWxlcyA6XG4gICAgY29xX1NlcSAtPiAoKChjb3FfSWRQUnVsZSwgY29xX0lkQlJ1bGUpIHN1bSwgY29xX0JvdExSdWxlKSBzdW0sIF9fKSBzdW0gKiopXG5cbmxldCBkZWNfaW5pdF9ydWxlcyA9IGZ1bmN0aW9uXG58IChsLCBsMCkgLT5cbiAgbGV0IHMwID0gZGVjX3Byb3BfdmFyX2luIChsLCBsMCkgaW5cbiAgKG1hdGNoIHMwIHdpdGhcbiAgIHwgQ29xX2lubCBzMSAtPlxuICAgICBsZXQgQ29xX2V4aXN0VCAoeCwgXykgPSBzMSBpblxuICAgICBDb3FfaW5sIChDb3FfaW5sIChDb3FfaW5sXG4gICAgIChsZXQgaCA9IGluX3NwbGl0VCAoVmFyIHgpIGwgaW5cbiAgICAgIGxldCBDb3FfZXhpc3RUICh4MCwgczIpID0gaCBpblxuICAgICAgbGV0IENvcV9leGlzdFQgKHgxLCBfKSA9IHMyIGluXG4gICAgICBsZXQgaDAgPSBpbl9zcGxpdFQgKFZhciB4KSBsMCBpblxuICAgICAgbGV0IENvcV9leGlzdFQgKHgyLCBzMykgPSBoMCBpblxuICAgICAgbGV0IENvcV9leGlzdFQgKHgzLCBfKSA9IHMzIGluIElkUFJ1bGVfSSAoeCwgeDAsIHgxLCB4MiwgeDMpKSkpXG4gICB8IENvcV9pbnIgXyAtPlxuICAgICBsZXQgczEgPSBjb3FfSW5fZGVjIGwgQm90IGluXG4gICAgIGlmIHMxXG4gICAgIHRoZW4gQ29xX2lubCAoQ29xX2luclxuICAgICAgICAgICAgKGxldCBpID0gaW5fc3BsaXRUIEJvdCBsIGluXG4gICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgsIHMyKSA9IGkgaW5cbiAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDAsIF8pID0gczIgaW4gQm90TFJ1bGVfSSAoeCwgeDAsIGwwKSkpXG4gICAgIGVsc2UgbGV0IHMyID0gZGVjX2JveF9pbiAobCwgbDApIGluXG4gICAgICAgICAgKG1hdGNoIHMyIHdpdGhcbiAgICAgICAgICAgfCBDb3FfaW5sIHMzIC0+XG4gICAgICAgICAgICAgQ29xX2lubCAoQ29xX2lubCAoQ29xX2luclxuICAgICAgICAgICAgICAgKGxldCBDb3FfZXhpc3RUICh4LCBfKSA9IHMzIGluXG4gICAgICAgICAgICAgICAgbGV0IGggPSBpbl9zcGxpdFQgKEJveCB4KSAoZnN0IChsLCBsMCkpIGluXG4gICAgICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgwLCBzNCkgPSBoIGluXG4gICAgICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgxLCBfKSA9IHM0IGluXG4gICAgICAgICAgICAgICAgbGV0IGgwID0gaW5fc3BsaXRUIChCb3ggeCkgKHNuZCAobCwgbDApKSBpblxuICAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MiwgczUpID0gaDAgaW5cbiAgICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDMsIF8pID0gczUgaW4gSWRCUnVsZV9JICh4LCB4MCwgeDEsIHgyLCB4MykpKSlcbiAgICAgICAgICAgfCBDb3FfaW5yIF8gLT4gQ29xX2luciBfXykpXG4iLCJvcGVuIERhdGF0eXBlc1xuXG5tb2R1bGUgTmF0ID1cbiBzdHJ1Y3RcbiAgKCoqIHZhbCBlcV9kZWMgOiBuYXQgLT4gbmF0IC0+IGJvb2wgKiopXG5cbiAgbGV0IHJlYyBlcV9kZWMgbiBtID1cbiAgICBtYXRjaCBuIHdpdGhcbiAgICB8IE8gLT4gKG1hdGNoIG0gd2l0aFxuICAgICAgICAgICAgfCBPIC0+IHRydWVcbiAgICAgICAgICAgIHwgUyBfIC0+IGZhbHNlKVxuICAgIHwgUyBuMCAtPiAobWF0Y2ggbSB3aXRoXG4gICAgICAgICAgICAgICB8IE8gLT4gZmFsc2VcbiAgICAgICAgICAgICAgIHwgUyBuMSAtPiBlcV9kZWMgbjAgbjEpXG4gZW5kXG4iLCJvcGVuIENNTF9TeW50YXhcbm9wZW4gRGF0YXR5cGVzXG5vcGVuIEdMU19jYWxjc1xub3BlbiBMaXN0XG5vcGVuIExpc3RfbGVtbWFzVFxub3BlbiBQZWFub05hdFxub3BlbiBTcGVjaWZcbm9wZW4gR2VuVFxub3BlbiBMaXN0X2xlbXNcbm9wZW4gVW5pdl9nZW5fZXh0XG5cbnR5cGUgX18gPSBPYmoudFxubGV0IF9fID0gbGV0IHJlYyBmIF8gPSBPYmoucmVwciBmIGluIE9iai5yZXByIGZcblxuKCoqIHZhbCBwcm9qMV9zaWdUMiA6ICgnYTEsICdhMikgc2lnVCAtPiAnYTEgKiopXG5cbmxldCBwcm9qMV9zaWdUMiA9IGZ1bmN0aW9uXG58IENvcV9leGlzdFQgKGEsIF8pIC0+IGFcblxuKCoqIHZhbCBwcm9qMl9zaWdUMiA6ICgnYTEsICdhMikgc2lnVCAtPiAnYTIgKiopXG5cbmxldCBwcm9qMl9zaWdUMiA9IGZ1bmN0aW9uXG58IENvcV9leGlzdFQgKF8sIGIpIC0+IGJcblxuKCoqIHZhbCBjb3FfSW5fSW5UX3BhaXIgOlxuICAgIGNvcV9NUHJvcEYgLT4gbmF0IC0+IChjb3FfTVByb3BGICogbmF0KSBsaXN0IC0+IChjb3FfTVByb3BGICogbmF0KSBjb3FfSW5UICoqKVxuXG5sZXQgcmVjIGNvcV9Jbl9JblRfcGFpciBhIG4gPSBmdW5jdGlvblxufCBbXSAtPiBhc3NlcnQgZmFsc2UgKCogYWJzdXJkIGNhc2UgKilcbnwgeSA6OiBsMCAtPlxuICBsZXQgaDAgPVxuICAgIGxldCAobSwgbjApID0geSBpblxuICAgIGxldCBzID0gZXFfZGVjX2Zvcm0gYSBtIGluIGlmIHMgdGhlbiBOYXQuZXFfZGVjIG4gbjAgZWxzZSBmYWxzZVxuICBpblxuICBpZiBoMFxuICB0aGVuIGNvcV9JblRfZXEgKGEsIG4pIGwwXG4gIGVsc2UgSW5UX2NvbnMgKHksIGwwLCAoY29xX0luX0luVF9wYWlyIGEgbiBsMCkpXG5cbigqKiB2YWwgY29xX0luVF9tYXBfaWZmIDpcbiAgICAoJ2ExIC0+ICdhMikgLT4gJ2ExIGxpc3QgLT4gJ2EyIC0+ICgnYTIgY29xX0luVCAtPiAoJ2ExLCBfXyAqICdhMVxuICAgIGNvcV9JblQpIHNpZ1QpICogKCgnYTEsIF9fICogJ2ExIGNvcV9JblQpIHNpZ1QgLT4gJ2EyIGNvcV9JblQpICoqKVxuXG5sZXQgcmVjIGNvcV9JblRfbWFwX2lmZiBmID0gZnVuY3Rpb25cbnwgW10gLT5cbiAgKGZ1biBfIC0+ICgoZnVuIF8gLT4gYXNzZXJ0IGZhbHNlICgqIGFic3VyZCBjYXNlICopKSwgKGZ1biBfIC0+XG4gICAgYXNzZXJ0IGZhbHNlICgqIGFic3VyZCBjYXNlICopKSkpXG58IHkgOjogbDAgLT5cbiAgbGV0IGlIbCA9IGNvcV9JblRfbWFwX2lmZiBmIGwwIGluXG4gIChmdW4geTAgLT4gKChmdW4geCAtPlxuICBtYXRjaCB4IHdpdGhcbiAgfCBJblRfZXEnIChfLCBfKSAtPiBDb3FfZXhpc3RUICh5LCAoX18sIChjb3FfSW5UX2VxIHkgbDApKSlcbiAgfCBJblRfY29ucyAoXywgXywgeDApIC0+XG4gICAgbGV0IHAgPSBpSGwgeTAgaW5cbiAgICBsZXQgKHMsIF8pID0gcCBpblxuICAgIGxldCB4MSA9IHMgeDAgaW5cbiAgICBsZXQgQ29xX2V4aXN0VCAoeDIsIHAwKSA9IHgxIGluXG4gICAgbGV0IChfLCBpKSA9IHAwIGluIENvcV9leGlzdFQgKHgyLCAoX18sIChJblRfY29ucyAoeSwgbDAsIGkpKSkpKSxcbiAgKGZ1biB4IC0+XG4gIGxldCBwID0gaUhsIHkwIGluXG4gIGxldCAoXywgaSkgPSBwIGluXG4gIGxldCBwMCA9IHByb2oyX3NpZ1QyIHggaW5cbiAgbGV0IChfLCBpMCkgPSBwMCBpblxuICAobWF0Y2ggaTAgd2l0aFxuICAgfCBJblRfZXEnIChfLCBfKSAtPiBjb3FfSW5UX2VxIChmIHkpIChtYXAgZiBsMClcbiAgIHwgSW5UX2NvbnMgKF8sIF8sIHgwKSAtPlxuICAgICBsZXQgeDEgPSBDb3FfZXhpc3RUICgocHJvajFfc2lnVDIgeCksIChfXywgeDApKSBpblxuICAgICBsZXQgeDIgPSBpIHgxIGluIEluVF9jb25zICgoZiB5KSwgKG1hcCBmIGwwKSwgeDIpKSkpKVxuXG4oKiogdmFsIHBvc190b3BfaW1wcyA6IGNvcV9NUHJvcEYgbGlzdCAtPiAoY29xX01Qcm9wRiAqIG5hdCkgbGlzdCAqKilcblxubGV0IHJlYyBwb3NfdG9wX2ltcHMgPSBmdW5jdGlvblxufCBbXSAtPiBbXVxufCBoIDo6IHQgLT5cbiAgKG1hdGNoIGggd2l0aFxuICAgfCBJbXAgKGEsIGIpIC0+XG4gICAgICgoSW1wIChhLCBiKSksIChTXG4gICAgICAgTykpIDo6IChtYXAgKGZ1biB5IC0+ICgoZnN0IHkpLCAoUyAoc25kIHkpKSkpIChwb3NfdG9wX2ltcHMgdCkpXG4gICB8IF8gLT4gbWFwIChmdW4geSAtPiAoKGZzdCB5KSwgKFMgKHNuZCB5KSkpKSAocG9zX3RvcF9pbXBzIHQpKVxuXG4oKiogdmFsIHRvcF9ib3hlc19ub2JveF9nZW5fZXh0IDogY29xX01Qcm9wRiBsaXN0IC0+IG5vYm94X2dlbl9leHQgKiopXG5cbmxldCByZWMgdG9wX2JveGVzX25vYm94X2dlbl9leHQgPSBmdW5jdGlvblxufCBbXSAtPiBDb3FfdW5pdl9nZW5fZXh0X25pbFxufCB5IDo6IGwwIC0+XG4gIChtYXRjaCB5IHdpdGhcbiAgIHwgQm94IG0gLT5cbiAgICAgQ29xX3VuaXZfZ2VuX2V4dF9jb25zICgoQm94IG0pLCAodG9wX2JveGVzIGwwKSwgbDAsXG4gICAgICAgKHRvcF9ib3hlc19ub2JveF9nZW5fZXh0IGwwKSlcbiAgIHwgeCAtPlxuICAgICBDb3FfdW5pdl9nZW5fZXh0X2V4dHJhICh4LCAodG9wX2JveGVzIGwwKSwgbDAsIF9fLFxuICAgICAgICh0b3BfYm94ZXNfbm9ib3hfZ2VuX2V4dCBsMCkpKVxuXG4oKiogdmFsIGZsYXR0ZW5fbGlzdCA6ICdhMSBsaXN0IGxpc3QgLT4gJ2ExIGxpc3QgKiopXG5cbmxldCByZWMgZmxhdHRlbl9saXN0ID0gZnVuY3Rpb25cbnwgW10gLT4gW11cbnwgaCA6OiB0IC0+IGFwcCBoIChmbGF0dGVuX2xpc3QgdClcblxuKCoqIHZhbCBjb3FfSW5UX2ZsYXR0ZW5fbGlzdF9JblRfZWxlbSA6XG4gICAgJ2ExIGxpc3QgbGlzdCAtPiAnYTEgLT4gJ2ExIGNvcV9JblQgLT4gKCdhMSBsaXN0LCAnYTEgY29xX0luVCAqICdhMSBsaXN0XG4gICAgY29xX0luVCkgc2lnVCAqKilcblxubGV0IHJlYyBjb3FfSW5UX2ZsYXR0ZW5fbGlzdF9JblRfZWxlbSBsIGIgeCA9XG4gIG1hdGNoIGwgd2l0aFxuICB8IFtdIC0+IGFzc2VydCBmYWxzZSAoKiBhYnN1cmQgY2FzZSAqKVxuICB8IHkgOjogbDAgLT5cbiAgICBsZXQgeDAgPSBjb3FfSW5UX2FwcF9vciB5IChmbGF0dGVuX2xpc3QgbDApIGIgeCBpblxuICAgIChtYXRjaCB4MCB3aXRoXG4gICAgIHwgQ29xX2lubCBpIC0+IENvcV9leGlzdFQgKHksIChpLCAoY29xX0luVF9lcSB5IGwwKSkpXG4gICAgIHwgQ29xX2luciBpIC0+XG4gICAgICAgbGV0IHMgPSBjb3FfSW5UX2ZsYXR0ZW5fbGlzdF9JblRfZWxlbSBsMCBiIGluXG4gICAgICAgbGV0IGkwID0gcyBpIGluXG4gICAgICAgbGV0IENvcV9leGlzdFQgKHgxLCBwKSA9IGkwIGluXG4gICAgICAgbGV0IChpMSwgaTIpID0gcCBpbiBDb3FfZXhpc3RUICh4MSwgKGkxLCAoSW5UX2NvbnMgKHksIGwwLCBpMikpKSkpXG5cbigqKiB2YWwgY29xX0luVF90cmFuc19mbGF0dGVuX2xpc3QgOlxuICAgICdhMSBsaXN0IGxpc3QgLT4gJ2ExIGxpc3QgLT4gJ2ExIC0+ICdhMSBjb3FfSW5UIC0+ICdhMSBsaXN0IGNvcV9JblQgLT5cbiAgICAnYTEgY29xX0luVCAqKilcblxubGV0IHJlYyBjb3FfSW5UX3RyYW5zX2ZsYXR0ZW5fbGlzdCBsIGJzIGIgeCB4MCA9XG4gIG1hdGNoIGwgd2l0aFxuICB8IFtdIC0+IGFzc2VydCBmYWxzZSAoKiBhYnN1cmQgY2FzZSAqKVxuICB8IHkgOjogbDAgLT5cbiAgICAobWF0Y2ggeDAgd2l0aFxuICAgICB8IEluVF9lcScgKF8sIF8pIC0+IGNvcV9JblRfb3JfYXBwIGJzIChmbGF0dGVuX2xpc3QgbDApIGIgKENvcV9pbmwgeClcbiAgICAgfCBJblRfY29ucyAoXywgXywgeDEpIC0+XG4gICAgICAgY29xX0luVF9vcl9hcHAgeSAoZmxhdHRlbl9saXN0IGwwKSBiIChDb3FfaW5yXG4gICAgICAgICAoY29xX0luVF90cmFuc19mbGF0dGVuX2xpc3QgbDAgYnMgYiB4IHgxKSkpXG5cbigqKiB2YWwgbGlzdF9vZl9zcGxpdHMgOlxuICAgIGNvcV9NUHJvcEYgbGlzdCAtPiAoKGNvcV9NUHJvcEYgbGlzdCAqIGNvcV9NUHJvcEYgbGlzdCkgbGlzdCwgX18pIHNpZ1QgKiopXG5cbmxldCByZWMgbGlzdF9vZl9zcGxpdHMgPSBmdW5jdGlvblxufCBbXSAtPiBDb3FfZXhpc3RUICgoKFtdLCBbXSkgOjogW10pLCBfXylcbnwgeSA6OiBsMCAtPlxuICBsZXQgQ29xX2V4aXN0VCAoeCwgXykgPSBsaXN0X29mX3NwbGl0cyBsMCBpblxuICBDb3FfZXhpc3RUXG4gICgoYXBwICgoW10sICh5IDo6IGwwKSkgOjogW10pXG4gICAgIChtYXAgKGZ1biB5MCAtPiAoKHkgOjogKGZzdCB5MCkpLCAoc25kIHkwKSkpIHgpKSwgX18pXG5cbigqKiB2YWwgbGlzdEluc2VydHMgOlxuICAgIGNvcV9NUHJvcEYgbGlzdCAtPiBjb3FfTVByb3BGIC0+IGNvcV9NUHJvcEYgbGlzdCBsaXN0ICoqKVxuXG5sZXQgbGlzdEluc2VydHMgbCBhID1cbiAgbWFwIChmdW4geSAtPiBhcHAgKGZzdCB5KSAoYSA6OiAoc25kIHkpKSkgKHByb2oxX3NpZ1QyIChsaXN0X29mX3NwbGl0cyBsKSlcblxuKCoqIHZhbCBsaXN0SW5zZXJ0c1JfU2VxcyA6XG4gICAgY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgbGlzdCAtPiBjb3FfTVByb3BGIC0+IChjb3FfTVByb3BGXG4gICAgbGlzdCAqIGNvcV9NUHJvcEYgbGlzdCkgbGlzdCAqKilcblxubGV0IGxpc3RJbnNlcnRzUl9TZXFzIF9VVTAzOTNfIF9VVTAzOTRfIGEgPVxuICBtYXAgKGZ1biB5IC0+ICh5LCBfVVUwMzk0XykpIChsaXN0SW5zZXJ0cyBfVVUwMzkzXyBhKVxuXG4oKiogdmFsIGxpc3RJbnNlcnRzTF9TZXFzIDpcbiAgICBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgLT4gKGNvcV9NUHJvcEZcbiAgICBsaXN0ICogY29xX01Qcm9wRiBsaXN0KSBsaXN0ICoqKVxuXG5sZXQgbGlzdEluc2VydHNMX1NlcXMgX1VVMDM5M18gX1VVMDM5NF8gYSA9XG4gIG1hcCAoZnVuIHkgLT4gKF9VVTAzOTNfLCB5KSkgKGxpc3RJbnNlcnRzIF9VVTAzOTRfIGEpXG5cbigqKiB2YWwgcmVtb3ZlX250aCA6XG4gICAgbmF0IC0+IGNvcV9NUHJvcEYgLT4gY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgbGlzdCAqKilcblxubGV0IHJlYyByZW1vdmVfbnRoIG4gYSBsID1cbiAgbWF0Y2ggbiB3aXRoXG4gIHwgTyAtPiBsXG4gIHwgUyBtIC0+XG4gICAgKG1hdGNoIG0gd2l0aFxuICAgICB8IE8gLT5cbiAgICAgICAobWF0Y2ggbCB3aXRoXG4gICAgICAgIHwgW10gLT4gW11cbiAgICAgICAgfCBiIDo6IHRsIC0+IGlmIGVxX2RlY19mb3JtIGEgYiB0aGVuIHRsIGVsc2UgYiA6OiB0bClcbiAgICAgfCBTIF8gLT4gKG1hdGNoIGwgd2l0aFxuICAgICAgICAgICAgICAgfCBbXSAtPiBbXVxuICAgICAgICAgICAgICAgfCBiIDo6IHRsIC0+IGIgOjogKHJlbW92ZV9udGggbSBhIHRsKSkpXG5cbigqKiB2YWwgbnRoX3NwbGl0IDpcbiAgICBuYXQgLT4gY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgbGlzdCAqIGNvcV9NUHJvcEYgbGlzdCAqKilcblxubGV0IHJlYyBudGhfc3BsaXQgbiBsID1cbiAgbWF0Y2ggbiB3aXRoXG4gIHwgTyAtPiAoW10sIGwpXG4gIHwgUyBtIC0+XG4gICAgKG1hdGNoIG0gd2l0aFxuICAgICB8IE8gLT4gKG1hdGNoIGwgd2l0aFxuICAgICAgICAgICAgIHwgW10gLT4gKFtdLCBbXSlcbiAgICAgICAgICAgICB8IGIgOjogdGwgLT4gKChiIDo6IFtdKSwgdGwpKVxuICAgICB8IFMgXyAtPlxuICAgICAgIChtYXRjaCBsIHdpdGhcbiAgICAgICAgfCBbXSAtPiAoW10sIFtdKVxuICAgICAgICB8IGIgOjogdGwgLT4gKChiIDo6IChmc3QgKG50aF9zcGxpdCBtIHRsKSkpLCAoc25kIChudGhfc3BsaXQgbSB0bCkpKSkpXG5cbigqKiB2YWwgcHJlbXNfSW1wX1IgOiAoY29xX01Qcm9wRiAqIG5hdCkgbGlzdCAtPiBjb3FfU2VxIC0+IGNvcV9TZXEgbGlzdCAqKilcblxubGV0IHJlYyBwcmVtc19JbXBfUiBsIHMgPVxuICBtYXRjaCBsIHdpdGhcbiAgfCBbXSAtPiBbXVxuICB8IHAgOjogdCAtPlxuICAgIGxldCAoYywgbikgPSBwIGluXG4gICAgKG1hdGNoIG4gd2l0aFxuICAgICB8IE8gLT4gcHJlbXNfSW1wX1IgdCBzXG4gICAgIHwgUyBtIC0+XG4gICAgICAgKG1hdGNoIGMgd2l0aFxuICAgICAgICB8IEltcCAoYSwgYikgLT5cbiAgICAgICAgICBhcHBcbiAgICAgICAgICAgIChsaXN0SW5zZXJ0c1JfU2VxcyAoZnN0IHMpXG4gICAgICAgICAgICAgIChhcHAgKGZzdCAobnRoX3NwbGl0IG0gKHJlbW92ZV9udGggKFMgbSkgYyAoc25kIHMpKSkpXG4gICAgICAgICAgICAgICAgKGIgOjogKHNuZCAobnRoX3NwbGl0IG0gKHJlbW92ZV9udGggKFMgbSkgYyAoc25kIHMpKSkpKSkgYSlcbiAgICAgICAgICAgIChwcmVtc19JbXBfUiB0IHMpXG4gICAgICAgIHwgXyAtPiBwcmVtc19JbXBfUiB0IHMpKVxuXG4oKiogdmFsIGNvcV9Jbl9wb3NfdG9wX2ltcHNfc3BsaXRfbCA6XG4gICAgY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgLT4gbmF0IC0+IChjb3FfTVByb3BGIGxpc3QsIChjb3FfTVByb3BGXG4gICAgbGlzdCwgX18pIHNpZ1QpIHNpZ1QgKiopXG5cbmxldCByZWMgY29xX0luX3Bvc190b3BfaW1wc19zcGxpdF9sIGwgYSBuID1cbiAgbWF0Y2ggbCB3aXRoXG4gIHwgW10gLT4gYXNzZXJ0IGZhbHNlICgqIGFic3VyZCBjYXNlICopXG4gIHwgeSA6OiBsMCAtPlxuICAgIChtYXRjaCB5IHdpdGhcbiAgICAgfCBJbXAgKG0sIG0wKSAtPlxuICAgICAgIGxldCBoID1cbiAgICAgICAgIGNvcV9Jbl9JblRfcGFpciBhIChTIG4pICgoKEltcCAobSwgbTApKSwgKFNcbiAgICAgICAgICAgTykpIDo6IChtYXAgKGZ1biB5MCAtPiAoKGZzdCB5MCksIChTIChzbmQgeTApKSkpIChwb3NfdG9wX2ltcHMgbDApKSlcbiAgICAgICBpblxuICAgICAgIChtYXRjaCBoIHdpdGhcbiAgICAgICAgfCBJblRfZXEnIChfLCBfKSAtPiBDb3FfZXhpc3RUIChbXSwgKENvcV9leGlzdFQgKGwwLCBfXykpKVxuICAgICAgICB8IEluVF9jb25zIChfLCBfLCBfKSAtPlxuICAgICAgICAgIChtYXRjaCBuIHdpdGhcbiAgICAgICAgICAgfCBPIC0+IGFzc2VydCBmYWxzZSAoKiBhYnN1cmQgY2FzZSAqKVxuICAgICAgICAgICB8IFMgbjAgLT5cbiAgICAgICAgICAgICBsZXQgcyA9IGNvcV9Jbl9wb3NfdG9wX2ltcHNfc3BsaXRfbCBsMCBhIG4wIGluXG4gICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgsIHMwKSA9IHMgaW5cbiAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDAsIF8pID0gczAgaW5cbiAgICAgICAgICAgICBDb3FfZXhpc3RUICgoKEltcCAobSwgbTApKSA6OiB4KSwgKENvcV9leGlzdFQgKHgwLCBfXykpKSkpXG4gICAgIHwgeCAtPlxuICAgICAgIChtYXRjaCBuIHdpdGhcbiAgICAgICAgfCBPIC0+IGFzc2VydCBmYWxzZSAoKiBhYnN1cmQgY2FzZSAqKVxuICAgICAgICB8IFMgbjAgLT5cbiAgICAgICAgICBsZXQgcyA9IGNvcV9Jbl9wb3NfdG9wX2ltcHNfc3BsaXRfbCBsMCBhIG4wIGluXG4gICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgwLCBzMCkgPSBzIGluXG4gICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgxLCBfKSA9IHMwIGluXG4gICAgICAgICAgQ29xX2V4aXN0VCAoKHggOjogeDApLCAoQ29xX2V4aXN0VCAoeDEsIF9fKSkpKSlcblxuKCoqIHZhbCBjb3FfSW1wUl9oZWxwMDEgOlxuICAgIGNvcV9TZXEgLT4gY29xX1NlcSAtPiAoY29xX01Qcm9wRiAqIG5hdCkgbGlzdCAtPiBjb3FfU2VxIGNvcV9JblQgLT4gKG5hdCxcbiAgICAoY29xX01Qcm9wRiwgKGNvcV9NUHJvcEYsIChjb3FfTVByb3BGIGxpc3QsIChjb3FfTVByb3BGIGxpc3QsIChjb3FfTVByb3BGXG4gICAgbGlzdCwgKGNvcV9NUHJvcEYgbGlzdCwgX18pIHNpZ1QpIHNpZ1QpIHNpZ1QpIHNpZ1QpIHNpZ1QpIHNpZ1QpIHNpZ1QgKiopXG5cbmxldCBjb3FfSW1wUl9oZWxwMDEgcHJlbSBzIGwzID1cbiAgbGV0IChsLCBsMCkgPSBzIGluXG4gIGxldCByZWMgZiBsMSB4ID1cbiAgICBtYXRjaCBsMSB3aXRoXG4gICAgfCBbXSAtPiBhc3NlcnQgZmFsc2UgKCogYWJzdXJkIGNhc2UgKilcbiAgICB8IHkgOjogbDIgLT5cbiAgICAgIGxldCAobSwgbikgPSB5IGluXG4gICAgICAobWF0Y2ggbSB3aXRoXG4gICAgICAgfCBJbXAgKG0wLCBtMSkgLT5cbiAgICAgICAgIChtYXRjaCBuIHdpdGhcbiAgICAgICAgICB8IE8gLT5cbiAgICAgICAgICAgIGxldCBzMCA9IGYgbDIgeCBpblxuICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgwLCBzMSkgPSBzMCBpblxuICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgxLCBzMikgPSBzMSBpblxuICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgyLCBzMykgPSBzMiBpblxuICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgzLCBzNCkgPSBzMyBpblxuICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHg0LCBzNSkgPSBzNCBpblxuICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHg1LCBzNikgPSBzNSBpblxuICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHg2LCBfKSA9IHM2IGluXG4gICAgICAgICAgICBDb3FfZXhpc3RUICh4MCwgKENvcV9leGlzdFQgKHgxLCAoQ29xX2V4aXN0VCAoeDIsIChDb3FfZXhpc3RUXG4gICAgICAgICAgICAoeDMsIChDb3FfZXhpc3RUICh4NCwgKENvcV9leGlzdFQgKHg1LCAoQ29xX2V4aXN0VCAoeDYsXG4gICAgICAgICAgICBfXykpKSkpKSkpKSkpKSlcbiAgICAgICAgICB8IFMgbjAgLT5cbiAgICAgICAgICAgIGxldCB4MCA9XG4gICAgICAgICAgICAgIGNvcV9JblRfYXBwX29yXG4gICAgICAgICAgICAgICAgKGxpc3RJbnNlcnRzUl9TZXFzIChmc3QgKGwsIGwwKSlcbiAgICAgICAgICAgICAgICAgIChhcHBcbiAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjBcbiAgICAgICAgICAgICAgICAgICAgICAgIChyZW1vdmVfbnRoIChTIG4wKSAoSW1wIChtMCwgbTEpKSAoc25kIChsLCBsMCkpKSkpXG4gICAgICAgICAgICAgICAgICAgIChtMSA6OiAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzbmQgKGwsIGwwKSkpKSkpKSBtMClcbiAgICAgICAgICAgICAgICAobGV0IHJlYyBwcmVtc19JbXBfUjAgbDQgczAgPVxuICAgICAgICAgICAgICAgICAgIG1hdGNoIGw0IHdpdGhcbiAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgfCBwIDo6IHQgLT5cbiAgICAgICAgICAgICAgICAgICAgIGxldCAoYywgbjEpID0gcCBpblxuICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIG4xIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICB8IE8gLT4gcHJlbXNfSW1wX1IwIHQgczBcbiAgICAgICAgICAgICAgICAgICAgICB8IFMgbTIgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBjIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICB8IEltcCAoYSwgYikgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobGlzdEluc2VydHNSX1NlcXMgKGZzdCBzMClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXBwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyBtMikgYyAoc25kIHMwKSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGIgOjogKHNuZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG0yXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgbTIpIGMgKHNuZCBzMCkpKSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGEpIChwcmVtc19JbXBfUjAgdCBzMClcbiAgICAgICAgICAgICAgICAgICAgICAgICB8IF8gLT4gcHJlbXNfSW1wX1IwIHQgczApKVxuICAgICAgICAgICAgICAgICBpbiBwcmVtc19JbXBfUjAgbDIgKGwsIGwwKSkgcHJlbSB4XG4gICAgICAgICAgICBpblxuICAgICAgICAgICAgKG1hdGNoIHgwIHdpdGhcbiAgICAgICAgICAgICB8IENvcV9pbmwgaSAtPlxuICAgICAgICAgICAgICAgbGV0IHgxID0gZnVuIGYwIGw0IHkwIC0+XG4gICAgICAgICAgICAgICAgIGxldCAoeDEsIF8pID0gY29xX0luVF9tYXBfaWZmIGYwIGw0IHkwIGluIHgxXG4gICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgbGV0IGkwID1cbiAgICAgICAgICAgICAgICAgeDEgKGZ1biB5MCAtPiAoeTAsXG4gICAgICAgICAgICAgICAgICAgKGFwcFxuICAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG4wIChyZW1vdmVfbnRoIChTIG4wKSAoSW1wIChtMCwgbTEpKSBsMCkpKVxuICAgICAgICAgICAgICAgICAgICAgKG0xIDo6IChzbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgbjApIChJbXAgKG0wLCBtMSkpIGwwKSkpKSkpKVxuICAgICAgICAgICAgICAgICAgIChsaXN0SW5zZXJ0cyBsIG0wKSBwcmVtIGlcbiAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDIsIHApID0gaTAgaW5cbiAgICAgICAgICAgICAgIGxldCAoXywgaTEpID0gcCBpblxuICAgICAgICAgICAgICAgbGV0IHgzID0gZnVuIGYwIGw0IHkwIC0+XG4gICAgICAgICAgICAgICAgIGxldCAoeDMsIF8pID0gY29xX0luVF9tYXBfaWZmIGYwIGw0IHkwIGluIHgzXG4gICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgbGV0IGkyID1cbiAgICAgICAgICAgICAgICAgeDMgKGZ1biB5MCAtPiBhcHAgKGZzdCB5MCkgKG0wIDo6IChzbmQgeTApKSlcbiAgICAgICAgICAgICAgICAgICAocHJvajFfc2lnVDIgKGxpc3Rfb2Zfc3BsaXRzIGwpKSB4MiBpMVxuICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4NCwgXykgPSBpMiBpblxuICAgICAgICAgICAgICAgbGV0IChsNCwgbDUpID0geDQgaW5cbiAgICAgICAgICAgICAgIENvcV9leGlzdFQgKG4wLCAoQ29xX2V4aXN0VCAobTAsIChDb3FfZXhpc3RUIChtMSwgKENvcV9leGlzdFRcbiAgICAgICAgICAgICAgIChsNCwgKENvcV9leGlzdFQgKGw1LCAoQ29xX2V4aXN0VFxuICAgICAgICAgICAgICAgKChmc3QgKG50aF9zcGxpdCBuMCAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSkgbDApKSksXG4gICAgICAgICAgICAgICAoQ29xX2V4aXN0VFxuICAgICAgICAgICAgICAgKChzbmQgKG50aF9zcGxpdCBuMCAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSkgbDApKSksXG4gICAgICAgICAgICAgICBfXykpKSkpKSkpKSkpKSlcbiAgICAgICAgICAgICB8IENvcV9pbnIgaSAtPlxuICAgICAgICAgICAgICAgbGV0IHMwID0gZiBsMiBpIGluXG4gICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDEsIHMxKSA9IHMwIGluXG4gICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDIsIHMyKSA9IHMxIGluXG4gICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDMsIHMzKSA9IHMyIGluXG4gICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDQsIHM0KSA9IHMzIGluXG4gICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDUsIHM1KSA9IHM0IGluXG4gICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDYsIHM2KSA9IHM1IGluXG4gICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDcsIF8pID0gczYgaW5cbiAgICAgICAgICAgICAgIENvcV9leGlzdFQgKHgxLCAoQ29xX2V4aXN0VCAoeDIsIChDb3FfZXhpc3RUICh4MywgKENvcV9leGlzdFRcbiAgICAgICAgICAgICAgICh4NCwgKENvcV9leGlzdFQgKHg1LCAoQ29xX2V4aXN0VCAoeDYsIChDb3FfZXhpc3RUICh4NyxcbiAgICAgICAgICAgICAgIF9fKSkpKSkpKSkpKSkpKSkpXG4gICAgICAgfCBfIC0+XG4gICAgICAgICBsZXQgczAgPSBmIGwyIHggaW5cbiAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MCwgczEpID0gczAgaW5cbiAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MSwgczIpID0gczEgaW5cbiAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MiwgczMpID0gczIgaW5cbiAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MywgczQpID0gczMgaW5cbiAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4NCwgczUpID0gczQgaW5cbiAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4NSwgczYpID0gczUgaW5cbiAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4NiwgXykgPSBzNiBpblxuICAgICAgICAgQ29xX2V4aXN0VCAoeDAsIChDb3FfZXhpc3RUICh4MSwgKENvcV9leGlzdFQgKHgyLCAoQ29xX2V4aXN0VCAoeDMsXG4gICAgICAgICAoQ29xX2V4aXN0VCAoeDQsIChDb3FfZXhpc3RUICh4NSwgKENvcV9leGlzdFQgKHg2LCBfXykpKSkpKSkpKSkpKSkpXG4gIGluIGYgbDNcblxuKCoqIHZhbCBjb3FfSW1wUl9oZWxwMSA6XG4gICAgY29xX1NlcSAtPiAoY29xX01Qcm9wRiBsaXN0ICogY29xX01Qcm9wRiBsaXN0KSAtPiBjb3FfU2VxIGNvcV9JblQgLT5cbiAgICBjb3FfSW1wUlJ1bGUgKiopXG5cbmxldCBjb3FfSW1wUl9oZWxwMSBwcmVtIHMgeCA9XG4gIGxldCBzMCA9IGNvcV9JbXBSX2hlbHAwMSBwcmVtIHMgKHBvc190b3BfaW1wcyAoc25kIHMpKSB4IGluXG4gIGxldCBDb3FfZXhpc3RUICh4MCwgczEpID0gczAgaW5cbiAgbGV0IChfLCBsKSA9IHMgaW5cbiAgbGV0IENvcV9leGlzdFQgKHgxLCBzMikgPSBzMSBpblxuICBsZXQgQ29xX2V4aXN0VCAoeDIsIHMzKSA9IHMyIGluXG4gIGxldCBDb3FfZXhpc3RUICh4MywgczQpID0gczMgaW5cbiAgbGV0IENvcV9leGlzdFQgKHg0LCBfKSA9IHM0IGluXG4gIGxldCBpID0gY29xX0luX3Bvc190b3BfaW1wc19zcGxpdF9sIGwgKEltcCAoeDEsIHgyKSkgeDAgaW5cbiAgbGV0IENvcV9leGlzdFQgKHg1LCBzNSkgPSBpIGluXG4gIGxldCBDb3FfZXhpc3RUICh4NiwgXykgPSBzNSBpbiBJbXBSUnVsZV9JICh4MSwgeDIsIHgzLCB4NCwgeDUsIHg2KVxuXG4oKiogdmFsIGNvcV9JbXBSX2hlbHAwMDIgOlxuICAgIGNvcV9NUHJvcEYgbGlzdCAtPiBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgbGlzdFxuICAgIC0+IGNvcV9NUHJvcEYgLT4gY29xX01Qcm9wRiAtPiAoY29xX01Qcm9wRiBsaXN0ICogY29xX01Qcm9wRiBsaXN0KSBjb3FfSW5UICoqKVxuXG5sZXQgY29xX0ltcFJfaGVscDAwMiBfVVUwMzkzXzAgX1VVMDM5M18xIF9VVTAzOTRfMCBfVVUwMzk0XzEgYSBiID1cbiAgbGV0IGYgPSBmdW4geSAtPiAoeSwgKGFwcCBfVVUwMzk0XzAgKGIgOjogX1VVMDM5NF8xKSkpIGluXG4gIGxldCBsID0gbGlzdEluc2VydHMgKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKSBhIGluXG4gIGxldCB5ID0gKChhcHAgX1VVMDM5M18wIChhIDo6IF9VVTAzOTNfMSkpLCAoYXBwIF9VVTAzOTRfMCAoYiA6OiBfVVUwMzk0XzEpKSlcbiAgaW5cbiAgbGV0IChfLCB4KSA9IGNvcV9JblRfbWFwX2lmZiBmIGwgeSBpblxuICB4IChDb3FfZXhpc3RUICgoYXBwIF9VVTAzOTNfMCAoYSA6OiBfVVUwMzkzXzEpKSwgKF9fLFxuICAgIChsZXQgZjAgPSBmdW4geTAgLT4gYXBwIChmc3QgeTApIChhIDo6IChzbmQgeTApKSBpblxuICAgICBsZXQgbDAgPSBwcm9qMV9zaWdUMiAobGlzdF9vZl9zcGxpdHMgKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKSkgaW5cbiAgICAgbGV0IHkwID0gYXBwIF9VVTAzOTNfMCAoYSA6OiBfVVUwMzkzXzEpIGluXG4gICAgIGxldCAoXywgeDApID0gY29xX0luVF9tYXBfaWZmIGYwIGwwIHkwIGluXG4gICAgIHgwIChDb3FfZXhpc3RUICgoX1VVMDM5M18wLCBfVVUwMzkzXzEpLCAoX18sXG4gICAgICAgKGxldCBzID0gbGlzdF9vZl9zcGxpdHMgKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKSBpblxuICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDEsIF8pID0gcyBpblxuICAgICAgICBjb3FfSW5fSW5UX3NlcXMgKF9VVTAzOTNfMCwgX1VVMDM5M18xKSB4MSkpKSkpKSkpXG5cbigqKiB2YWwgY29xX0ltcFJfaGVscDAyIDpcbiAgICBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgbGlzdCAtPiBjb3FfTVByb3BGIGxpc3RcbiAgICAtPiBjb3FfTVByb3BGIC0+IGNvcV9NUHJvcEYgLT4gKGNvcV9NUHJvcEYgKiBuYXQpIGxpc3QgLT4gbmF0IC0+XG4gICAgY29xX0ltcFJSdWxlIC0+IChjb3FfTVByb3BGIGxpc3QgKiBjb3FfTVByb3BGIGxpc3QpIGNvcV9JblQgKiopXG5cbmxldCByZWMgY29xX0ltcFJfaGVscDAyIF9VVTAzOTNfMCBfVVUwMzkzXzEgX1VVMDM5NF8wIF9VVTAzOTRfMSBhIGIgbCBuIHggPVxuICBtYXRjaCBsIHdpdGhcbiAgfCBbXSAtPiBhc3NlcnQgZmFsc2UgKCogYWJzdXJkIGNhc2UgKilcbiAgfCB5IDo6IGwwIC0+XG4gICAgbGV0IChtLCBuMCkgPSB5IGluXG4gICAgKG1hdGNoIG0gd2l0aFxuICAgICB8IEltcCAobTAsIG0xKSAtPlxuICAgICAgIGxldCBoMSA9XG4gICAgICAgICBjb3FfSW5fSW5UX3BhaXIgKEltcCAoYSwgYikpIChTIG4pICgoKEltcCAobTAsIG0xKSksIG4wKSA6OiBsMClcbiAgICAgICBpblxuICAgICAgIChtYXRjaCBoMSB3aXRoXG4gICAgICAgIHwgSW5UX2VxJyAoXywgXykgLT5cbiAgICAgICAgICAobWF0Y2ggX1VVMDM5NF8wIHdpdGhcbiAgICAgICAgICAgfCBbXSAtPlxuICAgICAgICAgICAgIGxldCBpID0gY29xX0ltcFJfaGVscDAwMiBfVVUwMzkzXzAgX1VVMDM5M18xIFtdIF9VVTAzOTRfMSBhIGIgaW5cbiAgICAgICAgICAgICBsZXQgcyA9IGVxX2RlY19mb3JtIChJbXAgKGEsIGIpKSAoSW1wIChhLCBiKSkgaW5cbiAgICAgICAgICAgICBpZiBzXG4gICAgICAgICAgICAgdGhlbiBjb3FfSW5UX29yX2FwcFxuICAgICAgICAgICAgICAgICAgICAobGlzdEluc2VydHNSX1NlcXMgKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKVxuICAgICAgICAgICAgICAgICAgICAgIChiIDo6IF9VVTAzOTRfMSkgYSlcbiAgICAgICAgICAgICAgICAgICAgKHByZW1zX0ltcF9SIGwwICgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLCAoKEltcCAoYSxcbiAgICAgICAgICAgICAgICAgICAgICBiKSkgOjogX1VVMDM5NF8xKSkpICgoYXBwIF9VVTAzOTNfMCAoYSA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgICAgICAgICAgICAgKGIgOjogX1VVMDM5NF8xKSkgKENvcV9pbmwgaSlcbiAgICAgICAgICAgICBlbHNlIGFzc2VydCBmYWxzZSAoKiBhYnN1cmQgY2FzZSAqKVxuICAgICAgICAgICB8IG0yIDo6IGwxIC0+XG4gICAgICAgICAgICAgY29xX0luVF9vcl9hcHBcbiAgICAgICAgICAgICAgIChsaXN0SW5zZXJ0c1JfU2Vxc1xuICAgICAgICAgICAgICAgICAoZnN0ICgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLFxuICAgICAgICAgICAgICAgICAgIChhcHAgKG0yIDo6IGwxKSAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTRfMSkpKSlcbiAgICAgICAgICAgICAgICAgKGFwcFxuICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgKGxlbmd0aCAobTIgOjogbDEpKVxuICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyAobGVuZ3RoIChtMiA6OiBsMSkpKSAoSW1wIChhLCBiKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAoc25kICgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFwcCAobTIgOjogbDEpICgoSW1wIChhLCBiKSkgOjogX1VVMDM5NF8xKSkpKSkpKVxuICAgICAgICAgICAgICAgICAgIChiIDo6IChzbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgKGxlbmd0aCAobTIgOjogbDEpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyAobGVuZ3RoIChtMiA6OiBsMSkpKSAoSW1wIChhLCBiKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc25kICgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFwcCAobTIgOjogbDEpICgoSW1wIChhLCBiKSkgOjogX1VVMDM5NF8xKSkpKSkpKSkpXG4gICAgICAgICAgICAgICAgIGEpXG4gICAgICAgICAgICAgICAobGV0IHJlYyBwcmVtc19JbXBfUjAgbDIgcyA9XG4gICAgICAgICAgICAgICAgICBtYXRjaCBsMiB3aXRoXG4gICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICB8IHAgOjogdCAtPlxuICAgICAgICAgICAgICAgICAgICBsZXQgKGMsIG4xKSA9IHAgaW5cbiAgICAgICAgICAgICAgICAgICAgKG1hdGNoIG4xIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgIHwgTyAtPiBwcmVtc19JbXBfUjAgdCBzXG4gICAgICAgICAgICAgICAgICAgICB8IFMgbTMgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIGMgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgfCBJbXAgKGEwLCBiMCkgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxpc3RJbnNlcnRzUl9TZXFzIChmc3QgcylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhcHBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbTMgKHJlbW92ZV9udGggKFMgbTMpIGMgKHNuZCBzKSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYjAgOjogKHNuZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG0zXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgbTMpIGMgKHNuZCBzKSkpKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhMCkgKHByZW1zX0ltcF9SMCB0IHMpXG4gICAgICAgICAgICAgICAgICAgICAgICB8IF8gLT4gcHJlbXNfSW1wX1IwIHQgcykpXG4gICAgICAgICAgICAgICAgaW4gcHJlbXNfSW1wX1IwIGwwICgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLFxuICAgICAgICAgICAgICAgICAgICAgKGFwcCAobTIgOjogbDEpICgoSW1wIChhLCBiKSkgOjogX1VVMDM5NF8xKSkpKVxuICAgICAgICAgICAgICAgKChhcHAgX1VVMDM5M18wIChhIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgICAgICAgICAgKGFwcCAobTIgOjogbDEpIChiIDo6IF9VVTAzOTRfMSkpKSAoQ29xX2lubFxuICAgICAgICAgICAgICAgKGNvcV9JbXBSX2hlbHAwMDIgX1VVMDM5M18wIF9VVTAzOTNfMSAobTIgOjogbDEpIF9VVTAzOTRfMSBhIGIpKSlcbiAgICAgICAgfCBJblRfY29ucyAoXywgXywgXykgLT5cbiAgICAgICAgICBsZXQgaSA9XG4gICAgICAgICAgICBjb3FfSW1wUl9oZWxwMDIgX1VVMDM5M18wIF9VVTAzOTNfMSBfVVUwMzk0XzAgX1VVMDM5NF8xIGEgYiBsMFxuICAgICAgICAgICAgICAobGVuZ3RoIF9VVTAzOTRfMCkgeFxuICAgICAgICAgIGluXG4gICAgICAgICAgKG1hdGNoIG4wIHdpdGhcbiAgICAgICAgICAgfCBPIC0+IGlcbiAgICAgICAgICAgfCBTIG4xIC0+XG4gICAgICAgICAgICAgY29xX0luVF9vcl9hcHBcbiAgICAgICAgICAgICAgIChsaXN0SW5zZXJ0c1JfU2VxcyAoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpXG4gICAgICAgICAgICAgICAgIChhcHBcbiAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG4xXG4gICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBuMSB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICB8IE8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIGFwcCBfVVUwMzk0XzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzk0XzEpIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgW10gLT4gW11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgYjAgOjogdGwgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgZXFfZGVjX2Zvcm0gKEltcCAobTAsIG0xKSkgYjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiB0bFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGIwIDo6IHRsKVxuICAgICAgICAgICAgICAgICAgICAgICAgfCBTIF8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIGFwcCBfVVUwMzk0XzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzk0XzEpIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgW10gLT4gW11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgYjAgOjogdGwgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYjAgOjogKHJlbW92ZV9udGggbjEgKEltcCAobTAsIG0xKSkgdGwpKSkpKVxuICAgICAgICAgICAgICAgICAgIChtMSA6OiAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBuMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIG4xIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IE8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBhcHAgX1VVMDM5NF8wICgoSW1wIChhLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYikpIDo6IF9VVTAzOTRfMSkgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgW10gLT4gW11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGIwIDo6IHRsIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBlcV9kZWNfZm9ybSAoSW1wIChtMCwgbTEpKSBiMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiB0bFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBiMCA6OiB0bClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFMgXyAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIGFwcCBfVVUwMzk0XzAgKChJbXAgKGEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiKSkgOjogX1VVMDM5NF8xKSB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBbXSAtPiBbXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgYjAgOjogdGwgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGIwIDo6IChyZW1vdmVfbnRoIG4xIChJbXAgKG0wLCBtMSkpIHRsKSkpKSkpKVxuICAgICAgICAgICAgICAgICBtMClcbiAgICAgICAgICAgICAgIChwcmVtc19JbXBfUiBsMCAoKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKSxcbiAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzk0XzEpKSkpXG4gICAgICAgICAgICAgICAoKGFwcCBfVVUwMzkzXzAgKGEgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCAoYiA6OiBfVVUwMzk0XzEpKSkgKENvcV9pbnIgaSkpKVxuICAgICB8IHgwIC0+XG4gICAgICAgbGV0IGgxID0gY29xX0luX0luVF9wYWlyIChJbXAgKGEsIGIpKSAoUyBuKSAoKHgwLCBuMCkgOjogbDApIGluXG4gICAgICAgKG1hdGNoIGgxIHdpdGhcbiAgICAgICAgfCBJblRfZXEnIChfLCBfKSAtPiBhc3NlcnQgZmFsc2UgKCogYWJzdXJkIGNhc2UgKilcbiAgICAgICAgfCBJblRfY29ucyAoXywgXywgXykgLT5cbiAgICAgICAgICBjb3FfSW1wUl9oZWxwMDIgX1VVMDM5M18wIF9VVTAzOTNfMSBfVVUwMzk0XzAgX1VVMDM5NF8xIGEgYiBsMFxuICAgICAgICAgICAgKGxlbmd0aCBfVVUwMzk0XzApIHgpKVxuXG4oKiogdmFsIGNvcV9JbXBSX2hlbHAyIDpcbiAgICBjb3FfU2VxIC0+IGNvcV9TZXEgLT4gY29xX0ltcFJSdWxlIC0+IGNvcV9TZXEgY29xX0luVCAqKilcblxubGV0IGNvcV9JbXBSX2hlbHAyIF8gXyB4ID0gbWF0Y2ggeCB3aXRoXG58IEltcFJSdWxlX0kgKGEsIGIsIF9VVTAzOTNfMCwgX1VVMDM5M18xLCBfVVUwMzk0XzAsIF9VVTAzOTRfMSkgLT5cbiAgY29xX0ltcFJfaGVscDAyIF9VVTAzOTNfMCBfVVUwMzkzXzEgX1VVMDM5NF8wIF9VVTAzOTRfMSBhIGJcbiAgICAocG9zX3RvcF9pbXBzIChhcHAgX1VVMDM5NF8wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5NF8xKSkpXG4gICAgKGxlbmd0aCBfVVUwMzk0XzApIHhcblxuKCoqIHZhbCBmaW5pdGVfSW1wUl9wcmVtaXNlc19vZl9TIDpcbiAgICBjb3FfU2VxIC0+IChjb3FfU2VxIGxpc3QgbGlzdCwgY29xX1NlcSBsaXN0IC0+IChjb3FfSW1wUlJ1bGUgLT4gY29xX1NlcVxuICAgIGxpc3QgY29xX0luVCkgKiAoY29xX1NlcSBsaXN0IGNvcV9JblQgLT4gY29xX0ltcFJSdWxlKSkgc2lnVCAqKilcblxubGV0IGZpbml0ZV9JbXBSX3ByZW1pc2VzX29mX1MgPSBmdW5jdGlvblxufCAobCwgbDApIC0+XG4gIENvcV9leGlzdFRcbiAgICAoKG1hcCAoZnVuIHkgLT4geSA6OiBbXSkgKHByZW1zX0ltcF9SIChwb3NfdG9wX2ltcHMgbDApIChsLCBsMCkpKSxcbiAgICAoZnVuIHByZW1zIC0+ICgoZnVuIGggLT5cbiAgICBsZXQgSW1wUlJ1bGVfSSAoYSwgYiwgX1VVMDM5M18wLCBfVVUwMzkzXzEsIF9VVTAzOTRfMCwgX1VVMDM5NF8xKSA9IGggaW5cbiAgICBsZXQgZiA9IGZ1biB5IC0+IHkgOjogW10gaW5cbiAgICBsZXQgbDEgPVxuICAgICAgcHJlbXNfSW1wX1IgKHBvc190b3BfaW1wcyAoYXBwIF9VVTAzOTRfMCAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTRfMSkpKVxuICAgICAgICAoKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKSxcbiAgICAgICAgKGFwcCBfVVUwMzk0XzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzk0XzEpKSlcbiAgICBpblxuICAgIGxldCB5ID0gKChhcHAgX1VVMDM5M18wIChhIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgKGFwcCBfVVUwMzk0XzAgKGIgOjogX1VVMDM5NF8xKSkpIDo6IFtdXG4gICAgaW5cbiAgICBsZXQgKF8sIHgpID0gY29xX0luVF9tYXBfaWZmIGYgbDEgeSBpblxuICAgIHggKENvcV9leGlzdFQgKCgoYXBwIF9VVTAzOTNfMCAoYSA6OiBfVVUwMzkzXzEpKSxcbiAgICAgIChhcHAgX1VVMDM5NF8wIChiIDo6IF9VVTAzOTRfMSkpKSwgKF9fLFxuICAgICAgKGNvcV9JbXBSX2hlbHAyICgoYXBwIF9VVTAzOTNfMCAoYSA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgKGFwcCBfVVUwMzk0XzAgKGIgOjogX1VVMDM5NF8xKSkpICgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLFxuICAgICAgICAoYXBwIF9VVTAzOTRfMCAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTRfMSkpKSBoKSkpKSksIChmdW4gaCAtPlxuICAgIGxldCB4ID0gZnVuIGYgbDEgeSAtPiBsZXQgKHgsIF8pID0gY29xX0luVF9tYXBfaWZmIGYgbDEgeSBpbiB4IGluXG4gICAgbGV0IGgwID1cbiAgICAgIHggKGZ1biB5IC0+IHkgOjogW10pIChwcmVtc19JbXBfUiAocG9zX3RvcF9pbXBzIGwwKSAobCwgbDApKSBwcmVtcyBoXG4gICAgaW5cbiAgICBsZXQgQ29xX2V4aXN0VCAoeDAsIHApID0gaDAgaW5cbiAgICBsZXQgKF8sIGkpID0gcCBpbiBjb3FfSW1wUl9oZWxwMSB4MCAobCwgbDApIGkpKSkpXG5cbigqKiB2YWwgcHJlbXNfSW1wX0wgOlxuICAgIChjb3FfTVByb3BGICogbmF0KSBsaXN0IC0+IGNvcV9TZXEgLT4gY29xX1NlcSBsaXN0IGxpc3QgKiopXG5cbmxldCByZWMgcHJlbXNfSW1wX0wgbCBzID1cbiAgbWF0Y2ggbCB3aXRoXG4gIHwgW10gLT4gW11cbiAgfCBwIDo6IHQgLT5cbiAgICBsZXQgKGMsIG4pID0gcCBpblxuICAgIChtYXRjaCBuIHdpdGhcbiAgICAgfCBPIC0+IHByZW1zX0ltcF9MIHQgc1xuICAgICB8IFMgbSAtPlxuICAgICAgIChtYXRjaCBjIHdpdGhcbiAgICAgICAgfCBJbXAgKGEsIGIpIC0+XG4gICAgICAgICAgYXBwXG4gICAgICAgICAgICAoZmxhdHRlbl9saXN0XG4gICAgICAgICAgICAgIChtYXAgKGZ1biB5IC0+XG4gICAgICAgICAgICAgICAgbWFwIChmdW4geiAtPiB6IDo6ICh5IDo6IFtdKSlcbiAgICAgICAgICAgICAgICAgIChsaXN0SW5zZXJ0c0xfU2Vxc1xuICAgICAgICAgICAgICAgICAgICAoYXBwIChmc3QgKG50aF9zcGxpdCBtIChyZW1vdmVfbnRoIChTIG0pIGMgKGZzdCBzKSkpKVxuICAgICAgICAgICAgICAgICAgICAgIChzbmQgKG50aF9zcGxpdCBtIChyZW1vdmVfbnRoIChTIG0pIGMgKGZzdCBzKSkpKSlcbiAgICAgICAgICAgICAgICAgICAgKHNuZCBzKSBhKSlcbiAgICAgICAgICAgICAgICAoKChhcHAgKGZzdCAobnRoX3NwbGl0IG0gKHJlbW92ZV9udGggKFMgbSkgYyAoZnN0IHMpKSkpXG4gICAgICAgICAgICAgICAgICAgIChiIDo6IChzbmQgKG50aF9zcGxpdCBtIChyZW1vdmVfbnRoIChTIG0pIGMgKGZzdCBzKSkpKSkpLFxuICAgICAgICAgICAgICAgIChzbmQgcykpIDo6IFtdKSkpIChwcmVtc19JbXBfTCB0IHMpXG4gICAgICAgIHwgXyAtPiBwcmVtc19JbXBfTCB0IHMpKVxuXG4oKiogdmFsIGNvcV9JbXBMX2hlbHAwMDIgOlxuICAgIGNvcV9NUHJvcEYgbGlzdCAtPiBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgbGlzdFxuICAgIC0+IGNvcV9NUHJvcEYgLT4gY29xX01Qcm9wRiAtPiAoY29xX01Qcm9wRiBsaXN0ICogY29xX01Qcm9wRiBsaXN0KSBsaXN0XG4gICAgY29xX0luVCAqKilcblxubGV0IGNvcV9JbXBMX2hlbHAwMDIgX1VVMDM5M18wIF9VVTAzOTNfMSBfVVUwMzk0XzAgX1VVMDM5NF8xIGEgYiA9XG4gIGNvcV9JblRfdHJhbnNfZmxhdHRlbl9saXN0XG4gICAgKG1hcCAoZnVuIHkgLT5cbiAgICAgIG1hcCAoZnVuIHogLT4geSA6OiAoeiA6OiBbXSkpICgoKGFwcCBfVVUwMzkzXzAgKGIgOjogX1VVMDM5M18xKSksXG4gICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpIDo6IFtdKSlcbiAgICAgIChsaXN0SW5zZXJ0c0xfU2VxcyAoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSlcbiAgICAgICAgYSkpXG4gICAgKG1hcCAoZnVuIHogLT4gKChhcHAgX1VVMDM5M18wIF9VVTAzOTNfMSksXG4gICAgICAoYXBwIF9VVTAzOTRfMCAoYSA6OiBfVVUwMzk0XzEpKSkgOjogKHogOjogW10pKVxuICAgICAgKCgoYXBwIF9VVTAzOTNfMCAoYiA6OiBfVVUwMzkzXzEpKSwgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkgOjogW10pKVxuICAgICgoKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKSxcbiAgICAoYXBwIF9VVTAzOTRfMCAoYSA6OiBfVVUwMzk0XzEpKSkgOjogKCgoYXBwIF9VVTAzOTNfMCAoYiA6OiBfVVUwMzkzXzEpKSxcbiAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSA6OiBbXSkpXG4gICAgKGxldCBwID1cbiAgICAgICBjb3FfSW5UX21hcF9pZmYgKGZ1biB6IC0+ICgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLFxuICAgICAgICAgKGFwcCBfVVUwMzk0XzAgKGEgOjogX1VVMDM5NF8xKSkpIDo6ICh6IDo6IFtdKSlcbiAgICAgICAgICgoKGFwcCBfVVUwMzkzXzAgKGIgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSA6OiBbXSkgKCgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLFxuICAgICAgICAgKGFwcCBfVVUwMzk0XzAgKGEgOjogX1VVMDM5NF8xKSkpIDo6ICgoKGFwcCBfVVUwMzkzXzBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGIgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSA6OiBbXSkpXG4gICAgIGluXG4gICAgIGxldCAoXywgaSkgPSBwIGluXG4gICAgIGkgKENvcV9leGlzdFQgKCgoYXBwIF9VVTAzOTNfMCAoYiA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSwgKF9fLFxuICAgICAgIChjb3FfSW5UX2VxICgoYXBwIF9VVTAzOTNfMCAoYiA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpIFtdKSkpKSlcbiAgICAobGV0IHAgPVxuICAgICAgIGNvcV9JblRfbWFwX2lmZiAoZnVuIHkgLT5cbiAgICAgICAgIG1hcCAoZnVuIHogLT4geSA6OiAoeiA6OiBbXSkpICgoKGFwcCBfVVUwMzkzXzAgKGIgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpIDo6IFtdKSlcbiAgICAgICAgIChsaXN0SW5zZXJ0c0xfU2VxcyAoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpXG4gICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkgYSlcbiAgICAgICAgIChtYXAgKGZ1biB6IC0+ICgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLFxuICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCAoYSA6OiBfVVUwMzk0XzEpKSkgOjogKHogOjogW10pKVxuICAgICAgICAgICAoKChhcHAgX1VVMDM5M18wIChiIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSA6OiBbXSkpXG4gICAgIGluXG4gICAgIGxldCAoXywgaSkgPSBwIGluXG4gICAgIGkgKENvcV9leGlzdFQgKCgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLFxuICAgICAgIChhcHAgX1VVMDM5NF8wIChhIDo6IF9VVTAzOTRfMSkpKSwgKF9fLFxuICAgICAgIChsZXQgcDAgPVxuICAgICAgICAgIGNvcV9JblRfbWFwX2lmZiAoZnVuIHkgLT4gKChhcHAgX1VVMDM5M18wIF9VVTAzOTNfMSksIHkpKVxuICAgICAgICAgICAgKGxpc3RJbnNlcnRzIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkgYSlcbiAgICAgICAgICAgICgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLCAoYXBwIF9VVTAzOTRfMCAoYSA6OiBfVVUwMzk0XzEpKSlcbiAgICAgICAgaW5cbiAgICAgICAgbGV0IChfLCBpMCkgPSBwMCBpblxuICAgICAgICBpMCAoQ29xX2V4aXN0VCAoKGFwcCBfVVUwMzk0XzAgKGEgOjogX1VVMDM5NF8xKSksIChfXyxcbiAgICAgICAgICAobGV0IHAxID1cbiAgICAgICAgICAgICBjb3FfSW5UX21hcF9pZmYgKGZ1biB5IC0+IGFwcCAoZnN0IHkpIChhIDo6IChzbmQgeSkpKVxuICAgICAgICAgICAgICAgKHByb2oxX3NpZ1QyIChsaXN0X29mX3NwbGl0cyAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSlcbiAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIChhIDo6IF9VVTAzOTRfMSkpXG4gICAgICAgICAgIGluXG4gICAgICAgICAgIGxldCAoXywgaTEpID0gcDEgaW5cbiAgICAgICAgICAgaTEgKENvcV9leGlzdFQgKChfVVUwMzk0XzAsIF9VVTAzOTRfMSksIChfXyxcbiAgICAgICAgICAgICAobGV0IHMgPSBsaXN0X29mX3NwbGl0cyAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpIGluXG4gICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4LCBfKSA9IHMgaW5cbiAgICAgICAgICAgICAgY29xX0luX0luVF9zZXFzIChfVVUwMzk0XzAsIF9VVTAzOTRfMSkgeCkpKSkpKSkpKSkpKSlcblxuKCoqIHZhbCBjb3FfSW1wTF9oZWxwMDIgOlxuICAgIGNvcV9NUHJvcEYgbGlzdCAtPiBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgbGlzdFxuICAgIC0+IGNvcV9NUHJvcEYgLT4gY29xX01Qcm9wRiAtPiAoY29xX01Qcm9wRiAqIG5hdCkgbGlzdCAtPiBuYXQgLT5cbiAgICBjb3FfSW1wTFJ1bGUgLT4gKGNvcV9NUHJvcEYgbGlzdCAqIGNvcV9NUHJvcEYgbGlzdCkgbGlzdCBjb3FfSW5UICoqKVxuXG5sZXQgcmVjIGNvcV9JbXBMX2hlbHAwMiBfVVUwMzkzXzAgX1VVMDM5M18xIF9VVTAzOTRfMCBfVVUwMzk0XzEgYSBiIGwgbiB4ID1cbiAgbWF0Y2ggbCB3aXRoXG4gIHwgW10gLT4gYXNzZXJ0IGZhbHNlICgqIGFic3VyZCBjYXNlICopXG4gIHwgeSA6OiBsMCAtPlxuICAgIGxldCAobSwgbjApID0geSBpblxuICAgIChtYXRjaCBtIHdpdGhcbiAgICAgfCBJbXAgKG0wLCBtMSkgLT5cbiAgICAgICBsZXQgaDEgPVxuICAgICAgICAgY29xX0luX0luVF9wYWlyIChJbXAgKGEsIGIpKSAoUyBuKSAoKChJbXAgKG0wLCBtMSkpLCBuMCkgOjogbDApXG4gICAgICAgaW5cbiAgICAgICAobWF0Y2ggaDEgd2l0aFxuICAgICAgICB8IEluVF9lcScgKF8sIF8pIC0+XG4gICAgICAgICAgbGV0IGkgPSBjb3FfSW1wTF9oZWxwMDAyIF9VVTAzOTNfMCBfVVUwMzkzXzEgX1VVMDM5NF8wIF9VVTAzOTRfMSBhIGJcbiAgICAgICAgICBpblxuICAgICAgICAgIGNvcV9JblRfb3JfYXBwXG4gICAgICAgICAgICAoZmxhdHRlbl9saXN0XG4gICAgICAgICAgICAgIChtYXAgKGZ1biB5MCAtPlxuICAgICAgICAgICAgICAgIG1hcCAoZnVuIHogLT4geiA6OiAoeTAgOjogW10pKVxuICAgICAgICAgICAgICAgICAgKGxpc3RJbnNlcnRzTF9TZXFzXG4gICAgICAgICAgICAgICAgICAgIChhcHBcbiAgICAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IChsZW5ndGggX1VVMDM5M18wKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyAobGVuZ3RoIF9VVTAzOTNfMCkpIChJbXAgKGEsIGIpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoYXBwIF9VVTAzOTNfMCAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkpKSkpXG4gICAgICAgICAgICAgICAgICAgICAgKHNuZFxuICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCAobGVuZ3RoIF9VVTAzOTNfMClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgKGxlbmd0aCBfVVUwMzkzXzApKSAoSW1wIChhLCBiKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKGFwcCBfVVUwMzkzXzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpKSkpKSlcbiAgICAgICAgICAgICAgICAgICAgKHNuZCAoKGFwcCBfVVUwMzkzXzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSkgYSkpXG4gICAgICAgICAgICAgICAgKCgoYXBwXG4gICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IChsZW5ndGggX1VVMDM5M18wKVxuICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgKGxlbmd0aCBfVVUwMzkzXzApKSAoSW1wIChhLCBiKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGZzdCAoKGFwcCBfVVUwMzkzXzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSkpKSlcbiAgICAgICAgICAgICAgICAgICAgKGIgOjogKHNuZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgKGxlbmd0aCBfVVUwMzkzXzApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyAobGVuZ3RoIF9VVTAzOTNfMCkpIChJbXAgKGEsIGIpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChhcHAgX1VVMDM5M18wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkpKSkpKSksXG4gICAgICAgICAgICAgICAgKHNuZCAoKGFwcCBfVVUwMzkzXzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpKSkgOjogW10pKSlcbiAgICAgICAgICAgIChsZXQgcmVjIHByZW1zX0ltcF9MMCBsMSBzID1cbiAgICAgICAgICAgICAgIG1hdGNoIGwxIHdpdGhcbiAgICAgICAgICAgICAgIHwgW10gLT4gW11cbiAgICAgICAgICAgICAgIHwgcCA6OiB0IC0+XG4gICAgICAgICAgICAgICAgIGxldCAoYywgbjEpID0gcCBpblxuICAgICAgICAgICAgICAgICAobWF0Y2ggbjEgd2l0aFxuICAgICAgICAgICAgICAgICAgfCBPIC0+IHByZW1zX0ltcF9MMCB0IHNcbiAgICAgICAgICAgICAgICAgIHwgUyBtMiAtPlxuICAgICAgICAgICAgICAgICAgICAobWF0Y2ggYyB3aXRoXG4gICAgICAgICAgICAgICAgICAgICB8IEltcCAoYTAsIGIwKSAtPlxuICAgICAgICAgICAgICAgICAgICAgICBhcHBcbiAgICAgICAgICAgICAgICAgICAgICAgICAoZmxhdHRlbl9saXN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAobWFwIChmdW4geTAgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwIChmdW4geiAtPiB6IDo6ICh5MCA6OiBbXSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxpc3RJbnNlcnRzTF9TZXFzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXBwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG0yXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyBtMikgYyAoZnN0IHMpKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG0yXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyBtMikgYyAoZnN0IHMpKSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNuZCBzKSBhMCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoKGFwcFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG0yXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgbTIpIGMgKGZzdCBzKSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGIwIDo6IChzbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgbTIpIGMgKGZzdCBzKSkpKSkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc25kIHMpKSA6OiBbXSkpKSAocHJlbXNfSW1wX0wwIHQgcylcbiAgICAgICAgICAgICAgICAgICAgIHwgXyAtPiBwcmVtc19JbXBfTDAgdCBzKSlcbiAgICAgICAgICAgICBpbiBwcmVtc19JbXBfTDAgbDAgKChhcHAgX1VVMDM5M18wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSkgKCgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLFxuICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgKGEgOjogX1VVMDM5NF8xKSkpIDo6ICgoKGFwcCBfVVUwMzkzXzBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGIgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSA6OiBbXSkpIChDb3FfaW5sXG4gICAgICAgICAgICAoY29xX0luVF90cmFuc19mbGF0dGVuX2xpc3RcbiAgICAgICAgICAgICAgKG1hcCAoZnVuIHkwIC0+XG4gICAgICAgICAgICAgICAgbWFwIChmdW4geiAtPiB6IDo6ICh5MCA6OiBbXSkpXG4gICAgICAgICAgICAgICAgICAobGlzdEluc2VydHNMX1NlcXNcbiAgICAgICAgICAgICAgICAgICAgKGFwcFxuICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgKGxlbmd0aCBfVVUwMzkzXzApXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChyZW1vdmVfbnRoIChTIChsZW5ndGggX1VVMDM5M18wKSkgKEltcCAoYSwgYikpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChhcHAgX1VVMDM5M18wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSkpKSlcbiAgICAgICAgICAgICAgICAgICAgICAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IChsZW5ndGggX1VVMDM5M18wKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyAobGVuZ3RoIF9VVTAzOTNfMCkpIChJbXAgKGEsIGIpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoYXBwIF9VVTAzOTNfMCAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkpKSkpKVxuICAgICAgICAgICAgICAgICAgICAoc25kICgoYXBwIF9VVTAzOTNfMCAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgICAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpKSBhKSlcbiAgICAgICAgICAgICAgICAoKChhcHBcbiAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgKGxlbmd0aCBfVVUwMzkzXzApXG4gICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyAobGVuZ3RoIF9VVTAzOTNfMCkpIChJbXAgKGEsIGIpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAoZnN0ICgoYXBwIF9VVTAzOTNfMCAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpKSkpKVxuICAgICAgICAgICAgICAgICAgICAoYiA6OiAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCAobGVuZ3RoIF9VVTAzOTNfMClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZW1vdmVfbnRoIChTIChsZW5ndGggX1VVMDM5M18wKSkgKEltcCAoYSwgYikpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKGFwcCBfVVUwMzkzXzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSkpKSkpKSxcbiAgICAgICAgICAgICAgICAoc25kICgoYXBwIF9VVTAzOTNfMCAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkpKSA6OiBbXSkpXG4gICAgICAgICAgICAgIChmbGF0dGVuX2xpc3RcbiAgICAgICAgICAgICAgICAobWFwIChmdW4geTAgLT4gKHkwIDo6ICgoKGFwcCBfVVUwMzkzXzAgKGIgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSA6OiBbXSkpIDo6IFtdKVxuICAgICAgICAgICAgICAgICAgKGxpc3RJbnNlcnRzTF9TZXFzIChhcHAgX1VVMDM5M18wIF9VVTAzOTNfMSlcbiAgICAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSBhKSkpXG4gICAgICAgICAgICAgICgoKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKSxcbiAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgKGEgOjogX1VVMDM5NF8xKSkpIDo6ICgoKGFwcCBfVVUwMzkzXzBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYiA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkgOjogW10pKSBpXG4gICAgICAgICAgICAgIChsZXQgZiA9IGZ1biB5MCAtPlxuICAgICAgICAgICAgICAgICBtYXAgKGZ1biB6IC0+IHogOjogKHkwIDo6IFtdKSlcbiAgICAgICAgICAgICAgICAgICAobGlzdEluc2VydHNMX1NlcXNcbiAgICAgICAgICAgICAgICAgICAgIChhcHBcbiAgICAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgKGxlbmd0aCBfVVUwMzkzXzApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyAobGVuZ3RoIF9VVTAzOTNfMCkpIChJbXAgKGEsIGIpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChhcHAgX1VVMDM5M18wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkpKSkpXG4gICAgICAgICAgICAgICAgICAgICAgIChzbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IChsZW5ndGggX1VVMDM5M18wKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgKGxlbmd0aCBfVVUwMzkzXzApKSAoSW1wIChhLCBiKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoYXBwIF9VVTAzOTNfMCAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpKSkpKSlcbiAgICAgICAgICAgICAgICAgICAgIChzbmQgKChhcHAgX1VVMDM5M18wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpKSBhKVxuICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgIGxldCBsMSA9XG4gICAgICAgICAgICAgICAgICgoYXBwXG4gICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IChsZW5ndGggX1VVMDM5M18wKVxuICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgKGxlbmd0aCBfVVUwMzkzXzApKSAoSW1wIChhLCBiKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGZzdCAoKGFwcCBfVVUwMzkzXzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSkpKSlcbiAgICAgICAgICAgICAgICAgICAgKGIgOjogKHNuZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgKGxlbmd0aCBfVVUwMzkzXzApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyAobGVuZ3RoIF9VVTAzOTNfMCkpIChJbXAgKGEsIGIpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChhcHAgX1VVMDM5M18wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkpKSkpKSksXG4gICAgICAgICAgICAgICAgIChzbmQgKChhcHAgX1VVMDM5M18wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkpKSA6OiBbXVxuICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgIGxldCB5MCA9XG4gICAgICAgICAgICAgICAgIGZsYXR0ZW5fbGlzdFxuICAgICAgICAgICAgICAgICAgIChtYXAgKGZ1biB5MCAtPiAoeTAgOjogKCgoYXBwIF9VVTAzOTNfMCAoYiA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpIDo6IFtdKSkgOjogW10pXG4gICAgICAgICAgICAgICAgICAgICAobGlzdEluc2VydHNMX1NlcXMgKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKVxuICAgICAgICAgICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpIGEpKVxuICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgIGxldCAoXywgeDApID0gY29xX0luVF9tYXBfaWZmIGYgbDEgeTAgaW5cbiAgICAgICAgICAgICAgIHgwIChDb3FfZXhpc3RUICgoKGFwcCBfVVUwMzkzXzAgKGIgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpLCAoX18sXG4gICAgICAgICAgICAgICAgIChsZXQgcyA9IGVxX2RlY19mb3JtIChJbXAgKGEsIGIpKSAoSW1wIChhLCBiKSkgaW5cbiAgICAgICAgICAgICAgICAgIGlmIHNcbiAgICAgICAgICAgICAgICAgIHRoZW4gY29xX0luVF9lcSAoKGFwcCBfVVUwMzkzXzAgKGIgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkgW11cbiAgICAgICAgICAgICAgICAgIGVsc2UgYXNzZXJ0IGZhbHNlICgqIGFic3VyZCBjYXNlICopKSkpKSkpKVxuICAgICAgICB8IEluVF9jb25zIChfLCBfLCBfKSAtPlxuICAgICAgICAgIGxldCBpID1cbiAgICAgICAgICAgIGNvcV9JbXBMX2hlbHAwMiBfVVUwMzkzXzAgX1VVMDM5M18xIF9VVTAzOTRfMCBfVVUwMzk0XzEgYSBiIGwwXG4gICAgICAgICAgICAgIChsZW5ndGggX1VVMDM5M18wKSB4XG4gICAgICAgICAgaW5cbiAgICAgICAgICAobWF0Y2ggbjAgd2l0aFxuICAgICAgICAgICB8IE8gLT4gaVxuICAgICAgICAgICB8IFMgbjEgLT5cbiAgICAgICAgICAgICBjb3FfSW5UX29yX2FwcFxuICAgICAgICAgICAgICAgKGFwcFxuICAgICAgICAgICAgICAgICAobWFwIChmdW4geiAtPlxuICAgICAgICAgICAgICAgICAgIHogOjogKCgoYXBwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBuMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggbjEgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBPIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBhcHAgX1VVMDM5M18wICgoSW1wIChhLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiKSkgOjogX1VVMDM5M18xKSB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGIwIDo6IHRsIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGVxX2RlY19mb3JtIChJbXAgKG0wLCBtMSkpIGIwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gdGxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBiMCA6OiB0bClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUyBfIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBhcHAgX1VVMDM5M18wICgoSW1wIChhLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiKSkgOjogX1VVMDM5M18xKSB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGIwIDo6IHRsIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGIwIDo6IChyZW1vdmVfbnRoIG4xIChJbXAgKG0wLCBtMSkpIHRsKSkpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAobTEgOjogKHNuZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBuMSB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBPIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggYXBwIF9VVTAzOTNfMCAoKEltcCAoYSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGIpKSA6OiBfVVUwMzkzXzEpIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBiMCA6OiB0bCAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgZXFfZGVjX2Zvcm0gKEltcCAobTAsIG0xKSkgYjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gdGxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgYjAgOjogdGwpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTIF8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBhcHAgX1VVMDM5M18wICgoSW1wIChhLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYikpIDo6IF9VVTAzOTNfMSkgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgW10gLT4gW11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGIwIDo6IHRsIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiMCA6OiAocmVtb3ZlX250aCBuMSAoSW1wIChtMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbTEpKSB0bCkpKSkpKSksXG4gICAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkgOjogW10pKVxuICAgICAgICAgICAgICAgICAgIChsaXN0SW5zZXJ0c0xfU2Vxc1xuICAgICAgICAgICAgICAgICAgICAgKGFwcFxuICAgICAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBuMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIG4xIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IE8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBhcHAgX1VVMDM5M18wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5M18xKSB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBbXSAtPiBbXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgYjAgOjogdGwgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGVxX2RlY19mb3JtIChJbXAgKG0wLCBtMSkpIGIwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIHRsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGIwIDo6IHRsKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUyBfIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggYXBwIF9VVTAzOTNfMCAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTNfMSkgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgW10gLT4gW11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGIwIDo6IHRsIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiMCA6OiAocmVtb3ZlX250aCBuMSAoSW1wIChtMCwgbTEpKSB0bCkpKSkpXG4gICAgICAgICAgICAgICAgICAgICAgIChzbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG4xXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggbjEgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgTyAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIGFwcCBfVVUwMzkzXzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzkzXzEpIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBiMCA6OiB0bCAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgZXFfZGVjX2Zvcm0gKEltcCAobTAsIG0xKSkgYjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gdGxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgYjAgOjogdGwpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTIF8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBhcHAgX1VVMDM5M18wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5M18xKSB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBbXSAtPiBbXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgYjAgOjogdGwgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGIwIDo6IChyZW1vdmVfbnRoIG4xIChJbXAgKG0wLCBtMSkpIHRsKSkpKSkpXG4gICAgICAgICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpIG0wKSkgW10pXG4gICAgICAgICAgICAgICAocHJlbXNfSW1wX0wgbDAgKChhcHAgX1VVMDM5M18wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpKSAoKChhcHAgX1VVMDM5M18wIF9VVTAzOTNfMSksXG4gICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCAoYSA6OiBfVVUwMzk0XzEpKSkgOjogKCgoYXBwIF9VVTAzOTNfMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYiA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpIDo6IFtdKSkgKENvcV9pbnIgaSkpKVxuICAgICB8IHgwIC0+XG4gICAgICAgbGV0IGgxID1cbiAgICAgICAgIGNvcV9Jbl9JblRfcGFpciAoSW1wIChhLCBiKSkgKFMgKGxlbmd0aCBfVVUwMzkzXzApKSAoKHgwLCBuMCkgOjogbDApXG4gICAgICAgaW5cbiAgICAgICAobWF0Y2ggaDEgd2l0aFxuICAgICAgICB8IEluVF9lcScgKF8sIF8pIC0+IGFzc2VydCBmYWxzZSAoKiBhYnN1cmQgY2FzZSAqKVxuICAgICAgICB8IEluVF9jb25zIChfLCBfLCBfKSAtPlxuICAgICAgICAgIGNvcV9JbXBMX2hlbHAwMiBfVVUwMzkzXzAgX1VVMDM5M18xIF9VVTAzOTRfMCBfVVUwMzk0XzEgYSBiIGwwXG4gICAgICAgICAgICAobGVuZ3RoIF9VVTAzOTNfMCkgeCkpXG5cbigqKiB2YWwgY29xX0ltcExfaGVscDIgOlxuICAgIGNvcV9TZXEgLT4gY29xX1NlcSAtPiBjb3FfU2VxIC0+IGNvcV9JbXBMUnVsZSAtPiBjb3FfU2VxIGxpc3QgY29xX0luVCAqKilcblxubGV0IGNvcV9JbXBMX2hlbHAyIF8gXyBfIHggPSBtYXRjaCB4IHdpdGhcbnwgSW1wTFJ1bGVfSSAoYSwgYiwgX1VVMDM5M18wLCBfVVUwMzkzXzEsIF9VVTAzOTRfMCwgX1VVMDM5NF8xKSAtPlxuICBjb3FfSW1wTF9oZWxwMDIgX1VVMDM5M18wIF9VVTAzOTNfMSBfVVUwMzk0XzAgX1VVMDM5NF8xIGEgYlxuICAgIChwb3NfdG9wX2ltcHMgKGFwcCBfVVUwMzkzXzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzkzXzEpKSlcbiAgICAobGVuZ3RoIF9VVTAzOTNfMCkgeFxuXG4oKiogdmFsIGNvcV9JbXBMX2hlbHAwMSA6XG4gICAgY29xX1NlcSBsaXN0IC0+IGNvcV9TZXEgLT4gKGNvcV9NUHJvcEYgKiBuYXQpIGxpc3QgLT4gY29xX1NlcSBsaXN0XG4gICAgY29xX0luVCAtPiAobmF0LCAoY29xX1NlcSwgKGNvcV9TZXEsIChjb3FfTVByb3BGLCAoY29xX01Qcm9wRixcbiAgICAoY29xX01Qcm9wRiBsaXN0LCAoY29xX01Qcm9wRiBsaXN0LCAoY29xX01Qcm9wRiBsaXN0LCAoY29xX01Qcm9wRiBsaXN0LFxuICAgIF9fKSBzaWdUKSBzaWdUKSBzaWdUKSBzaWdUKSBzaWdUKSBzaWdUKSBzaWdUKSBzaWdUKSBzaWdUICoqKVxuXG5sZXQgY29xX0ltcExfaGVscDAxIHByZW1zIHMgbDEgPVxuICBsZXQgKGwsIGwwKSA9IHMgaW5cbiAgbGV0IHJlYyBmIGwyIHggPVxuICAgIG1hdGNoIGwyIHdpdGhcbiAgICB8IFtdIC0+IGFzc2VydCBmYWxzZSAoKiBhYnN1cmQgY2FzZSAqKVxuICAgIHwgeSA6OiBsMyAtPlxuICAgICAgbGV0IChtLCBuKSA9IHkgaW5cbiAgICAgIChtYXRjaCBtIHdpdGhcbiAgICAgICB8IEltcCAobTAsIG0xKSAtPlxuICAgICAgICAgKG1hdGNoIG4gd2l0aFxuICAgICAgICAgIHwgTyAtPlxuICAgICAgICAgICAgbGV0IHMwID0gZiBsMyB4IGluXG4gICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDAsIHMxKSA9IHMwIGluXG4gICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDEsIHMyKSA9IHMxIGluXG4gICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDIsIHMzKSA9IHMyIGluXG4gICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDMsIHM0KSA9IHMzIGluXG4gICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDQsIHM1KSA9IHM0IGluXG4gICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDUsIHM2KSA9IHM1IGluXG4gICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDYsIHM3KSA9IHM2IGluXG4gICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDcsIHM4KSA9IHM3IGluXG4gICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDgsIF8pID0gczggaW5cbiAgICAgICAgICAgIENvcV9leGlzdFQgKHgwLCAoQ29xX2V4aXN0VCAoeDEsIChDb3FfZXhpc3RUICh4MiwgKENvcV9leGlzdFRcbiAgICAgICAgICAgICh4MywgKENvcV9leGlzdFQgKHg0LCAoQ29xX2V4aXN0VCAoeDUsIChDb3FfZXhpc3RUICh4NixcbiAgICAgICAgICAgIChDb3FfZXhpc3RUICh4NywgKENvcV9leGlzdFQgKHg4LCBfXykpKSkpKSkpKSkpKSkpKSkpXG4gICAgICAgICAgfCBTIG4wIC0+XG4gICAgICAgICAgICBsZXQgeDAgPVxuICAgICAgICAgICAgICBjb3FfSW5UX2FwcF9vclxuICAgICAgICAgICAgICAgIChmbGF0dGVuX2xpc3RcbiAgICAgICAgICAgICAgICAgIChtYXAgKGZ1biB5MCAtPlxuICAgICAgICAgICAgICAgICAgICBtYXAgKGZ1biB6IC0+IHogOjogKHkwIDo6IFtdKSlcbiAgICAgICAgICAgICAgICAgICAgICAobGlzdEluc2VydHNMX1NlcXNcbiAgICAgICAgICAgICAgICAgICAgICAgIChhcHBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZW1vdmVfbnRoIChTIG4wKSAoSW1wIChtMCwgbTEpKSAoZnN0IChsLCBsMCkpKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChzbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG4wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSkgKGZzdCAobCwgbDApKSkpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIChzbmQgKGwsIGwwKSkgbTApKVxuICAgICAgICAgICAgICAgICAgICAoKChhcHBcbiAgICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZW1vdmVfbnRoIChTIG4wKSAoSW1wIChtMCwgbTEpKSAoZnN0IChsLCBsMCkpKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAobTEgOjogKHNuZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZnN0IChsLCBsMCkpKSkpKSksXG4gICAgICAgICAgICAgICAgICAgIChzbmQgKGwsIGwwKSkpIDo6IFtdKSkpXG4gICAgICAgICAgICAgICAgKGxldCByZWMgcHJlbXNfSW1wX0wwIGw0IHMwID1cbiAgICAgICAgICAgICAgICAgICBtYXRjaCBsNCB3aXRoXG4gICAgICAgICAgICAgICAgICAgfCBbXSAtPiBbXVxuICAgICAgICAgICAgICAgICAgIHwgcCA6OiB0IC0+XG4gICAgICAgICAgICAgICAgICAgICBsZXQgKGMsIG4xKSA9IHAgaW5cbiAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBuMSB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgfCBPIC0+IHByZW1zX0ltcF9MMCB0IHMwXG4gICAgICAgICAgICAgICAgICAgICAgfCBTIG0yIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggYyB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgfCBJbXAgKGEsIGIpIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZsYXR0ZW5fbGlzdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXAgKGZ1biB5MCAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwIChmdW4geiAtPiB6IDo6ICh5MCA6OiBbXSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsaXN0SW5zZXJ0c0xfU2Vxc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhcHBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBtMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZW1vdmVfbnRoIChTIG0yKSBjIChmc3QgczApKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyBtMikgYyAoZnN0IHMwKSkpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc25kIHMwKSBhKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoKGFwcFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgbTIpIGMgKGZzdCBzMCkpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYiA6OiAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG0yXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZW1vdmVfbnRoIChTIG0yKSBjIChmc3QgczApKSkpKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc25kIHMwKSkgOjogW10pKSkgKHByZW1zX0ltcF9MMCB0IHMwKVxuICAgICAgICAgICAgICAgICAgICAgICAgIHwgXyAtPiBwcmVtc19JbXBfTDAgdCBzMCkpXG4gICAgICAgICAgICAgICAgIGluIHByZW1zX0ltcF9MMCBsMyAobCwgbDApKSBwcmVtcyB4XG4gICAgICAgICAgICBpblxuICAgICAgICAgICAgKG1hdGNoIHgwIHdpdGhcbiAgICAgICAgICAgICB8IENvcV9pbmwgaSAtPlxuICAgICAgICAgICAgICAgbGV0IGkwID1cbiAgICAgICAgICAgICAgICAgY29xX0luVF9mbGF0dGVuX2xpc3RfSW5UX2VsZW1cbiAgICAgICAgICAgICAgICAgICAobWFwIChmdW4geTAgLT5cbiAgICAgICAgICAgICAgICAgICAgIG1hcCAoZnVuIHogLT4geiA6OiAoeTAgOjogW10pKVxuICAgICAgICAgICAgICAgICAgICAgICAobGlzdEluc2VydHNMX1NlcXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAoYXBwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSkgbCkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNuZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG4wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgbjApIChJbXAgKG0wLCBtMSkpIGwpKSkpIGwwIG0wKSlcbiAgICAgICAgICAgICAgICAgICAgICgoKGFwcFxuICAgICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjAgKHJlbW92ZV9udGggKFMgbjApIChJbXAgKG0wLCBtMSkpIGwpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAobTEgOjogKHNuZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZW1vdmVfbnRoIChTIG4wKSAoSW1wIChtMCwgbTEpKSBsKSkpKSksXG4gICAgICAgICAgICAgICAgICAgICBsMCkgOjogW10pKSBwcmVtcyBpXG4gICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgxLCBwKSA9IGkwIGluXG4gICAgICAgICAgICAgICBsZXQgKGkxLCBpMikgPSBwIGluXG4gICAgICAgICAgICAgICBsZXQgeDIgPSBmdW4gZjAgbDQgeTAgLT5cbiAgICAgICAgICAgICAgICAgbGV0ICh4MiwgXykgPSBjb3FfSW5UX21hcF9pZmYgZjAgbDQgeTAgaW4geDJcbiAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICBsZXQgaTMgPVxuICAgICAgICAgICAgICAgICB4MiAoZnVuIHkwIC0+XG4gICAgICAgICAgICAgICAgICAgbWFwIChmdW4geiAtPiB6IDo6ICh5MCA6OiBbXSkpXG4gICAgICAgICAgICAgICAgICAgICAobGlzdEluc2VydHNMX1NlcXNcbiAgICAgICAgICAgICAgICAgICAgICAgKGFwcFxuICAgICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjAgKHJlbW92ZV9udGggKFMgbjApIChJbXAgKG0wLCBtMSkpIGwpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG4wIChyZW1vdmVfbnRoIChTIG4wKSAoSW1wIChtMCwgbTEpKSBsKSkpKVxuICAgICAgICAgICAgICAgICAgICAgICBsMCBtMCkpXG4gICAgICAgICAgICAgICAgICAgKCgoYXBwXG4gICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG4wIChyZW1vdmVfbnRoIChTIG4wKSAoSW1wIChtMCwgbTEpKSBsKSkpXG4gICAgICAgICAgICAgICAgICAgICAgIChtMSA6OiAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSkgbCkpKSkpLFxuICAgICAgICAgICAgICAgICAgIGwwKSA6OiBbXSkgeDEgaTJcbiAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoXywgcDApID0gaTMgaW5cbiAgICAgICAgICAgICAgIGxldCAoXywgaTQpID0gcDAgaW5cbiAgICAgICAgICAgICAgIChtYXRjaCBpNCB3aXRoXG4gICAgICAgICAgICAgICAgfCBJblRfZXEnIChfLCBfKSAtPlxuICAgICAgICAgICAgICAgICAgbGV0IHgzID0gZnVuIGYwIGw0IHkwIC0+XG4gICAgICAgICAgICAgICAgICAgIGxldCAoeDMsIF8pID0gY29xX0luVF9tYXBfaWZmIGYwIGw0IHkwIGluIHgzXG4gICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgbGV0IGk1ID1cbiAgICAgICAgICAgICAgICAgICAgeDMgKGZ1biB6IC0+XG4gICAgICAgICAgICAgICAgICAgICAgeiA6OiAoKChhcHBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG4wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBuMCB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IE8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIGwgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBbXSAtPiBbXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBiIDo6IHRsIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGVxX2RlY19mb3JtIChJbXAgKG0wLCBtMSkpIGJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiB0bFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGIgOjogdGwpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFMgXyAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggbCB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGIgOjogdGwgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYiA6OiAocmVtb3ZlX250aCBuMCAoSW1wIChtMCwgbTEpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGwpKSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtMSA6OiAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIG4wIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IE8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBsIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBiIDo6IHRsIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBlcV9kZWNfZm9ybSAoSW1wIChtMCwgbTEpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIHRsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGIgOjogdGwpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTIF8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBsIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBiIDo6IHRsIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiIDo6IChyZW1vdmVfbnRoIG4wIChJbXAgKG0wLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0xKSkgdGwpKSkpKSkpLFxuICAgICAgICAgICAgICAgICAgICAgIGwwKSA6OiBbXSkpXG4gICAgICAgICAgICAgICAgICAgICAgKGxpc3RJbnNlcnRzTF9TZXFzXG4gICAgICAgICAgICAgICAgICAgICAgICAoYXBwXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG4wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSkgbCkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgbjApIChJbXAgKG0wLCBtMSkpIGwpKSkpIGwwIG0wKVxuICAgICAgICAgICAgICAgICAgICAgIHByZW1zIGkxXG4gICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHg0LCBwMSkgPSBpNSBpblxuICAgICAgICAgICAgICAgICAgbGV0IChfLCBpNikgPSBwMSBpblxuICAgICAgICAgICAgICAgICAgbGV0IHg1ID0gZnVuIGYwIGw0IHkwIC0+XG4gICAgICAgICAgICAgICAgICAgIGxldCAoeDUsIF8pID0gY29xX0luVF9tYXBfaWZmIGYwIGw0IHkwIGluIHg1XG4gICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgbGV0IGk3ID1cbiAgICAgICAgICAgICAgICAgICAgeDUgKGZ1biB5MCAtPlxuICAgICAgICAgICAgICAgICAgICAgICgoYXBwXG4gICAgICAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBuMCAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSkgbCkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgIChzbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjAgKHJlbW92ZV9udGggKFMgbjApIChJbXAgKG0wLCBtMSkpIGwpKSkpLFxuICAgICAgICAgICAgICAgICAgICAgIHkwKSkgKGxpc3RJbnNlcnRzIGwwIG0wKSB4NCBpNlxuICAgICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4NiwgcDIpID0gaTcgaW5cbiAgICAgICAgICAgICAgICAgIGxldCAoXywgaTgpID0gcDIgaW5cbiAgICAgICAgICAgICAgICAgIGxldCB4NyA9IGZ1biBmMCBsNCB5MCAtPlxuICAgICAgICAgICAgICAgICAgICBsZXQgKHg3LCBfKSA9IGNvcV9JblRfbWFwX2lmZiBmMCBsNCB5MCBpbiB4N1xuICAgICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgICAgIGxldCBpOSA9XG4gICAgICAgICAgICAgICAgICAgIHg3IChmdW4geTAgLT4gYXBwIChmc3QgeTApIChtMCA6OiAoc25kIHkwKSkpXG4gICAgICAgICAgICAgICAgICAgICAgKHByb2oxX3NpZ1QyIChsaXN0X29mX3NwbGl0cyBsMCkpIHg2IGk4XG4gICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHg4LCBfKSA9IGk5IGluXG4gICAgICAgICAgICAgICAgICBsZXQgKGw0LCBsNSkgPSB4OCBpblxuICAgICAgICAgICAgICAgICAgQ29xX2V4aXN0VCAobjAsIChDb3FfZXhpc3RUXG4gICAgICAgICAgICAgICAgICAoKChhcHBcbiAgICAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG4wIChyZW1vdmVfbnRoIChTIG4wKSAoSW1wIChtMCwgbTEpKSBsKSkpXG4gICAgICAgICAgICAgICAgICAgICAgKHNuZFxuICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBuMCAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSkgbCkpKSksXG4gICAgICAgICAgICAgICAgICAoYXBwIGw0IChtMCA6OiBsNSkpKSwgKENvcV9leGlzdFRcbiAgICAgICAgICAgICAgICAgICgoKGFwcFxuICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIG4wIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgTyAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggbCB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGIwIDo6IHRsIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGVxX2RlY19mb3JtIChJbXAgKG0wLCBtMSkpIGIwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gdGxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBiMCA6OiB0bClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUyBfIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBsIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgW10gLT4gW11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgYjAgOjogdGwgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYjAgOjogKHJlbW92ZV9udGggbjAgKEltcCAobTAsIG0xKSkgdGwpKSkpKVxuICAgICAgICAgICAgICAgICAgICAgIChtMSA6OiAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIG4wIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IE8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBsIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBiMCA6OiB0bCAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgZXFfZGVjX2Zvcm0gKEltcCAobTAsIG0xKSkgYjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gdGxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgYjAgOjogdGwpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTIF8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBsIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBiMCA6OiB0bCAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYjAgOjogKHJlbW92ZV9udGggbjAgKEltcCAobTAsIG0xKSkgdGwpKSkpKSkpLFxuICAgICAgICAgICAgICAgICAgbDApLCAoQ29xX2V4aXN0VCAobTAsIChDb3FfZXhpc3RUIChtMSwgKENvcV9leGlzdFRcbiAgICAgICAgICAgICAgICAgICgoZnN0IChudGhfc3BsaXQgbjAgKHJlbW92ZV9udGggKFMgbjApIChJbXAgKG0wLCBtMSkpIGwpKSksXG4gICAgICAgICAgICAgICAgICAoQ29xX2V4aXN0VFxuICAgICAgICAgICAgICAgICAgKChzbmQgKG50aF9zcGxpdCBuMCAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSkgbCkpKSxcbiAgICAgICAgICAgICAgICAgIChDb3FfZXhpc3RUIChsNCwgKENvcV9leGlzdFQgKGw1LCBfXykpKSkpKSkpKSkpKSkpKSkpXG4gICAgICAgICAgICAgICAgfCBJblRfY29ucyAoXywgXywgXykgLT4gYXNzZXJ0IGZhbHNlICgqIGFic3VyZCBjYXNlICopKVxuICAgICAgICAgICAgIHwgQ29xX2luciBpIC0+XG4gICAgICAgICAgICAgICBsZXQgczAgPSBmIGwzIGkgaW5cbiAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MSwgczEpID0gczAgaW5cbiAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MiwgczIpID0gczEgaW5cbiAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MywgczMpID0gczIgaW5cbiAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4NCwgczQpID0gczMgaW5cbiAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4NSwgczUpID0gczQgaW5cbiAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4NiwgczYpID0gczUgaW5cbiAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4NywgczcpID0gczYgaW5cbiAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4OCwgczgpID0gczcgaW5cbiAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4OSwgXykgPSBzOCBpblxuICAgICAgICAgICAgICAgQ29xX2V4aXN0VCAoeDEsIChDb3FfZXhpc3RUICh4MiwgKENvcV9leGlzdFQgKHgzLCAoQ29xX2V4aXN0VFxuICAgICAgICAgICAgICAgKHg0LCAoQ29xX2V4aXN0VCAoeDUsIChDb3FfZXhpc3RUICh4NiwgKENvcV9leGlzdFQgKHg3LFxuICAgICAgICAgICAgICAgKENvcV9leGlzdFQgKHg4LCAoQ29xX2V4aXN0VCAoeDksIF9fKSkpKSkpKSkpKSkpKSkpKSkpKVxuICAgICAgIHwgXyAtPlxuICAgICAgICAgbGV0IHMwID0gZiBsMyB4IGluXG4gICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDAsIHMxKSA9IHMwIGluXG4gICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDEsIHMyKSA9IHMxIGluXG4gICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDIsIHMzKSA9IHMyIGluXG4gICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDMsIHM0KSA9IHMzIGluXG4gICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDQsIHM1KSA9IHM0IGluXG4gICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDUsIHM2KSA9IHM1IGluXG4gICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDYsIHM3KSA9IHM2IGluXG4gICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDcsIHM4KSA9IHM3IGluXG4gICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDgsIF8pID0gczggaW5cbiAgICAgICAgIENvcV9leGlzdFQgKHgwLCAoQ29xX2V4aXN0VCAoeDEsIChDb3FfZXhpc3RUICh4MiwgKENvcV9leGlzdFQgKHgzLFxuICAgICAgICAgKENvcV9leGlzdFQgKHg0LCAoQ29xX2V4aXN0VCAoeDUsIChDb3FfZXhpc3RUICh4NiwgKENvcV9leGlzdFQgKHg3LFxuICAgICAgICAgKENvcV9leGlzdFQgKHg4LCBfXykpKSkpKSkpKSkpKSkpKSkpKVxuICBpbiBmIGwxXG5cbigqKiB2YWwgY29xX0ltcExfaGVscDEgOlxuICAgIGNvcV9TZXEgbGlzdCAtPiAoY29xX01Qcm9wRiBsaXN0ICogY29xX01Qcm9wRiBsaXN0KSAtPiBjb3FfU2VxIGxpc3RcbiAgICBjb3FfSW5UIC0+IGNvcV9JbXBMUnVsZSAqKilcblxubGV0IGNvcV9JbXBMX2hlbHAxIHByZW0gcyB4ID1cbiAgbGV0IHMwID0gY29xX0ltcExfaGVscDAxIHByZW0gcyAocG9zX3RvcF9pbXBzIChmc3QgcykpIHggaW5cbiAgbGV0IENvcV9leGlzdFQgKHgwLCBzMSkgPSBzMCBpblxuICBsZXQgQ29xX2V4aXN0VCAoXywgczIpID0gczEgaW5cbiAgbGV0IENvcV9leGlzdFQgKF8sIHMzKSA9IHMyIGluXG4gIGxldCBDb3FfZXhpc3RUICh4MSwgczQpID0gczMgaW5cbiAgbGV0IENvcV9leGlzdFQgKHgyLCBzNSkgPSBzNCBpblxuICBsZXQgQ29xX2V4aXN0VCAoXywgczYpID0gczUgaW5cbiAgbGV0IENvcV9leGlzdFQgKF8sIHM3KSA9IHM2IGluXG4gIGxldCBDb3FfZXhpc3RUICh4MywgczgpID0gczcgaW5cbiAgbGV0IENvcV9leGlzdFQgKHg0LCBfKSA9IHM4IGluXG4gIGxldCAobCwgbDApID0gcyBpblxuICBsZXQgaSA9IGNvcV9Jbl9wb3NfdG9wX2ltcHNfc3BsaXRfbCAoZnN0IChsLCBsMCkpIChJbXAgKHgxLCB4MikpIHgwIGluXG4gIGxldCBDb3FfZXhpc3RUICh4NSwgXykgPSBpIGluXG4gIGxldCBfVVUwMzkzXzAnID1cbiAgICBmc3QgKG50aF9zcGxpdCAobGVuZ3RoIHg1KSAocmVtb3ZlX250aCAoUyAobGVuZ3RoIHg1KSkgKEltcCAoeDEsIHgyKSkgbCkpXG4gIGluXG4gIGxldCBfVVUwMzkzXzEnID1cbiAgICBzbmQgKG50aF9zcGxpdCAobGVuZ3RoIHg1KSAocmVtb3ZlX250aCAoUyAobGVuZ3RoIHg1KSkgKEltcCAoeDEsIHgyKSkgbCkpXG4gIGluXG4gIEltcExSdWxlX0kgKHgxLCB4MiwgX1VVMDM5M18wJywgX1VVMDM5M18xJywgeDMsIHg0KVxuXG4oKiogdmFsIGZpbml0ZV9JbXBMX3ByZW1pc2VzX29mX1MgOlxuICAgIGNvcV9TZXEgLT4gKGNvcV9TZXEgbGlzdCBsaXN0LCBjb3FfU2VxIGxpc3QgLT4gKGNvcV9JbXBMUnVsZSAtPiBjb3FfU2VxXG4gICAgbGlzdCBjb3FfSW5UKSAqIChjb3FfU2VxIGxpc3QgY29xX0luVCAtPiBjb3FfSW1wTFJ1bGUpKSBzaWdUICoqKVxuXG5sZXQgZmluaXRlX0ltcExfcHJlbWlzZXNfb2ZfUyA9IGZ1bmN0aW9uXG58IChsLCBsMCkgLT5cbiAgQ29xX2V4aXN0VCAoKHByZW1zX0ltcF9MIChwb3NfdG9wX2ltcHMgbCkgKGwsIGwwKSksIChmdW4gcHJlbXMgLT5cbiAgICAoKGZ1biBoIC0+XG4gICAgbGV0IEltcExSdWxlX0kgKGEsIGIsIF9VVTAzOTNfMCwgX1VVMDM5M18xLCBfVVUwMzk0XzAsIF9VVTAzOTRfMSkgPSBoIGluXG4gICAgY29xX0ltcExfaGVscDIgKChhcHAgX1VVMDM5M18wIF9VVTAzOTNfMSksXG4gICAgICAoYXBwIF9VVTAzOTRfMCAoYSA6OiBfVVUwMzk0XzEpKSkgKChhcHAgX1VVMDM5M18wIChiIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSlcbiAgICAgICgoYXBwIF9VVTAzOTNfMCAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkgaCksIChmdW4gaCAtPlxuICAgIGNvcV9JbXBMX2hlbHAxIHByZW1zIChsLCBsMCkgaCkpKSlcblxuKCoqIHZhbCBwcmVtc19Cb3hfUiA6IGNvcV9NUHJvcEYgbGlzdCAtPiBjb3FfU2VxIC0+IGNvcV9TZXEgbGlzdCBsaXN0ICoqKVxuXG5sZXQgcmVjIHByZW1zX0JveF9SIGwgcyA9XG4gIG1hdGNoIGwgd2l0aFxuICB8IFtdIC0+IFtdXG4gIHwgaCA6OiB0IC0+XG4gICAgKG1hdGNoIGggd2l0aFxuICAgICB8IEJveCBhIC0+XG4gICAgICAgKCgoYXBwIChjb3FfWEJveGVkX2xpc3QgKHRvcF9ib3hlcyAoZnN0IHMpKSkgKChCb3ggYSkgOjogW10pKSxcbiAgICAgICAgIChhIDo6IFtdKSkgOjogW10pIDo6IChwcmVtc19Cb3hfUiB0IHMpXG4gICAgIHwgXyAtPiBwcmVtc19Cb3hfUiB0IHMpXG5cbigqKiB2YWwgY29xX0dMUl9oZWxwMDEgOlxuICAgIGNvcV9TZXEgbGlzdCAtPiBjb3FfU2VxIC0+IGNvcV9NUHJvcEYgbGlzdCAtPiBjb3FfU2VxIGxpc3QgY29xX0luVCAtPlxuICAgIChjb3FfTVByb3BGLCBfXykgc2lnVCAqKilcblxubGV0IHJlYyBjb3FfR0xSX2hlbHAwMSBwcmVtcyBzIGwxIHggPVxuICBtYXRjaCBsMSB3aXRoXG4gIHwgW10gLT4gYXNzZXJ0IGZhbHNlICgqIGFic3VyZCBjYXNlICopXG4gIHwgeSA6OiBsIC0+XG4gICAgKG1hdGNoIHkgd2l0aFxuICAgICB8IEJveCBtIC0+XG4gICAgICAgKG1hdGNoIHggd2l0aFxuICAgICAgICB8IEluVF9lcScgKF8sIF8pIC0+IENvcV9leGlzdFQgKG0sIF9fKVxuICAgICAgICB8IEluVF9jb25zIChfLCBfLCB4MCkgLT5cbiAgICAgICAgICBsZXQgaDAgPSBjb3FfR0xSX2hlbHAwMSBwcmVtcyBzIGwgeDAgaW5cbiAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDEsIF8pID0gaDAgaW4gQ29xX2V4aXN0VCAoeDEsIF9fKSlcbiAgICAgfCBfIC0+XG4gICAgICAgbGV0IHgwID0gY29xX0dMUl9oZWxwMDEgcHJlbXMgcyBsIHggaW5cbiAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDEsIF8pID0geDAgaW4gQ29xX2V4aXN0VCAoeDEsIF9fKSlcblxuKCoqIHZhbCBjb3FfR0xSX2hlbHAxIDpcbiAgICBjb3FfU2VxIGxpc3QgLT4gKGNvcV9NUHJvcEYgbGlzdCAqIGNvcV9NUHJvcEYgbGlzdCkgLT4gY29xX1NlcSBsaXN0XG4gICAgY29xX0luVCAtPiBjb3FfR0xSUnVsZSAqKilcblxubGV0IGNvcV9HTFJfaGVscDEgcHJlbXMgcyB4ID1cbiAgbGV0IHMwID0gY29xX0dMUl9oZWxwMDEgcHJlbXMgcyAodG9wX2JveGVzIChzbmQgcykpIHggaW5cbiAgbGV0IENvcV9leGlzdFQgKHgwLCBfKSA9IHMwIGluXG4gIGxldCAobCwgbDApID0gcyBpblxuICBsZXQgaCA9IGluX3NwbGl0VCAoQm94IHgwKSBsMCBpblxuICBsZXQgQ29xX2V4aXN0VCAoeDEsIHMxKSA9IGggaW5cbiAgbGV0IENvcV9leGlzdFQgKHgyLCBfKSA9IHMxIGluXG4gIEdMUlJ1bGVfSSAoeDAsICh0b3BfYm94ZXMgKGZzdCAobCwgKGFwcCB4MSAoKEJveCB4MCkgOjogeDIpKSkpKSwgbCwgeDEsIHgyLFxuICAodG9wX2JveGVzX25vYm94X2dlbl9leHQgbCkpXG5cbigqKiB2YWwgY29xX0dMUl9oZWxwMDIgOlxuICAgIGNvcV9NUHJvcEYgbGlzdCAtPiBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgbGlzdFxuICAgIC0+IGNvcV9NUHJvcEYgLT4gY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9HTFJSdWxlIC0+IG5vYm94X2dlbl9leHQgLT5cbiAgICAoY29xX01Qcm9wRiBsaXN0ICogY29xX01Qcm9wRiBsaXN0KSBsaXN0IGNvcV9JblQgKiopXG5cbmxldCByZWMgY29xX0dMUl9oZWxwMDIgX1VVMDM5M18gX1VVMDM5NF8wIF9VVTAzOTRfMSBiX1VVMDM5M18gYSBsIHggeDAgPVxuICBtYXRjaCBsIHdpdGhcbiAgfCBbXSAtPiBhc3NlcnQgZmFsc2UgKCogYWJzdXJkIGNhc2UgKilcbiAgfCB5IDo6IGwwIC0+XG4gICAgKG1hdGNoIHkgd2l0aFxuICAgICB8IEJveCBtIC0+XG4gICAgICAgbGV0IGgxID1cbiAgICAgICAgIGxldCBoMCA9IGluX3NwbGl0VCAoQm94IGEpICgoQm94IG0pIDo6IGwwKSBpblxuICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgxLCBzKSA9IGgwIGluXG4gICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDIsIF8pID0gcyBpblxuICAgICAgICAgY29xX0luVF9vcl9hcHAgeDEgKChCb3ggYSkgOjogeDIpIChCb3ggYSkgKENvcV9pbnJcbiAgICAgICAgICAgKGNvcV9JblRfZXEgKEJveCBhKSB4MikpXG4gICAgICAgaW5cbiAgICAgICAobWF0Y2ggaDEgd2l0aFxuICAgICAgICB8IEluVF9lcScgKF8sIF8pIC0+XG4gICAgICAgICAgY29xX0luVF9lcVxuICAgICAgICAgICAgKCgoYXBwIChjb3FfWEJveGVkX2xpc3QgKHRvcF9ib3hlcyBfVVUwMzkzXykpICgoQm94IGEpIDo6IFtdKSksXG4gICAgICAgICAgICAoYSA6OiBbXSkpIDo6IFtdKVxuICAgICAgICAgICAgKHByZW1zX0JveF9SIGwwIChfVVUwMzkzXyxcbiAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgKChCb3ggYSkgOjogX1VVMDM5NF8xKSkpKVxuICAgICAgICB8IEluVF9jb25zIChfLCBfLCBfKSAtPlxuICAgICAgICAgIGxldCBpID1cbiAgICAgICAgICAgIGNvcV9HTFJfaGVscDAyIF9VVTAzOTNfIF9VVTAzOTRfMCBfVVUwMzk0XzEgYl9VVTAzOTNfIGEgbDAgeCB4MFxuICAgICAgICAgIGluXG4gICAgICAgICAgSW5UX2NvbnNcbiAgICAgICAgICAoKCgoYXBwIChjb3FfWEJveGVkX2xpc3QgKHRvcF9ib3hlcyBfVVUwMzkzXykpICgoQm94IG0pIDo6IFtdKSksXG4gICAgICAgICAgKG0gOjogW10pKSA6OiBbXSksXG4gICAgICAgICAgKHByZW1zX0JveF9SIGwwIChfVVUwMzkzXywgKGFwcCBfVVUwMzk0XzAgKChCb3ggYSkgOjogX1VVMDM5NF8xKSkpKSxcbiAgICAgICAgICBpKSlcbiAgICAgfCB4MSAtPlxuICAgICAgIGxldCBoMSA9XG4gICAgICAgICBsZXQgaDAgPSBpbl9zcGxpdFQgKEJveCBhKSAoeDEgOjogbDApIGluXG4gICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDIsIHMpID0gaDAgaW5cbiAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MywgXykgPSBzIGluXG4gICAgICAgICBjb3FfSW5UX29yX2FwcCB4MiAoKEJveCBhKSA6OiB4MykgKEJveCBhKSAoQ29xX2luclxuICAgICAgICAgICAoY29xX0luVF9lcSAoQm94IGEpIHgzKSlcbiAgICAgICBpblxuICAgICAgIChtYXRjaCBoMSB3aXRoXG4gICAgICAgIHwgSW5UX2VxJyAoXywgXykgLT4gYXNzZXJ0IGZhbHNlICgqIGFic3VyZCBjYXNlICopXG4gICAgICAgIHwgSW5UX2NvbnMgKF8sIF8sIF8pIC0+XG4gICAgICAgICAgY29xX0dMUl9oZWxwMDIgX1VVMDM5M18gX1VVMDM5NF8wIF9VVTAzOTRfMSBiX1VVMDM5M18gYSBsMCB4IHgwKSlcblxuKCoqIHZhbCBjb3FfR0xSX2hlbHAyIDpcbiAgICBjb3FfU2VxIC0+IGNvcV9TZXEgLT4gY29xX0dMUlJ1bGUgLT4gY29xX1NlcSBsaXN0IGNvcV9JblQgKiopXG5cbmxldCBjb3FfR0xSX2hlbHAyIF8gXyB4ID0gbWF0Y2ggeCB3aXRoXG58IEdMUlJ1bGVfSSAoYSwgYl9VVTAzOTNfLCBfVVUwMzkzXzAsIF9VVTAzOTRfMCwgX1VVMDM5NF8xLCB4MCkgLT5cbiAgY29xX0dMUl9oZWxwMDIgX1VVMDM5M18wIF9VVTAzOTRfMCBfVVUwMzk0XzEgYl9VVTAzOTNfIGFcbiAgICAodG9wX2JveGVzIChhcHAgX1VVMDM5NF8wICgoQm94IGEpIDo6IF9VVTAzOTRfMSkpKSB4IHgwXG5cbigqKiB2YWwgZmluaXRlX0dMUl9wcmVtaXNlc19vZl9TIDpcbiAgICBjb3FfU2VxIC0+IChjb3FfU2VxIGxpc3QgbGlzdCwgY29xX1NlcSBsaXN0IC0+IChjb3FfR0xSUnVsZSAtPiBjb3FfU2VxXG4gICAgbGlzdCBjb3FfSW5UKSAqIChjb3FfU2VxIGxpc3QgY29xX0luVCAtPiBjb3FfR0xSUnVsZSkpIHNpZ1QgKiopXG5cbmxldCBmaW5pdGVfR0xSX3ByZW1pc2VzX29mX1MgPSBmdW5jdGlvblxufCAobCwgbDApIC0+XG4gIENvcV9leGlzdFQgKChwcmVtc19Cb3hfUiAodG9wX2JveGVzIGwwKSAobCwgbDApKSwgKGZ1biBwcmVtcyAtPiAoKGZ1biB4IC0+XG4gICAgbGV0IEdMUlJ1bGVfSSAoYSwgYl9VVTAzOTNfLCBfLCBfVVUwMzk0XzAsIF9VVTAzOTRfMSwgXykgPSB4IGluXG4gICAgY29xX0dMUl9oZWxwMiAoKGFwcCAoY29xX1hCb3hlZF9saXN0IGJfVVUwMzkzXykgKChCb3ggYSkgOjogW10pKSxcbiAgICAgIChhIDo6IFtdKSkgKGwsIChhcHAgX1VVMDM5NF8wICgoQm94IGEpIDo6IF9VVTAzOTRfMSkpKSB4KSwgKGZ1biBoIC0+XG4gICAgY29xX0dMUl9oZWxwMSBwcmVtcyAobCwgbDApIGgpKSkpXG4iLCJvcGVuIENNTF9TeW50YXhcbm9wZW4gRGF0YXR5cGVzXG5vcGVuIEdMU19jYWxjc1xub3BlbiBSZW1vdmVfbGlzdF9sZW1zXG5cbigqKiB2YWwgc3ViZm9ybV9ib3hlc0YgOiBjb3FfTVByb3BGIC0+IGNvcV9NUHJvcEYgbGlzdCAqKilcblxubGV0IHJlYyBzdWJmb3JtX2JveGVzRiA9IGZ1bmN0aW9uXG58IEltcCAoYiwgYykgLT5cbiAgYXBwIChzdWJmb3JtX2JveGVzRiBiKSAocmVtb3ZlX2xpc3QgKHN1YmZvcm1fYm94ZXNGIGIpIChzdWJmb3JtX2JveGVzRiBjKSlcbnwgQm94IGIgLT4gKEJveCBiKSA6OiAoc3ViZm9ybV9ib3hlc0YgYilcbnwgXyAtPiBbXVxuXG4oKiogdmFsIHN1YmZvcm1fYm94ZXNMRiA6IGNvcV9NUHJvcEYgbGlzdCAtPiBjb3FfTVByb3BGIGxpc3QgKiopXG5cbmxldCByZWMgc3ViZm9ybV9ib3hlc0xGID0gZnVuY3Rpb25cbnwgW10gLT4gW11cbnwgaCA6OiB0IC0+XG4gIGFwcCAoc3ViZm9ybV9ib3hlc0YgaCkgKHJlbW92ZV9saXN0IChzdWJmb3JtX2JveGVzRiBoKSAoc3ViZm9ybV9ib3hlc0xGIHQpKVxuXG4oKiogdmFsIHN1YmZvcm1fYm94ZXNTIDogY29xX1NlcSAtPiBjb3FfTVByb3BGIGxpc3QgKiopXG5cbmxldCBzdWJmb3JtX2JveGVzUyBzID1cbiAgYXBwIChzdWJmb3JtX2JveGVzTEYgKGZzdCBzKSlcbiAgICAocmVtb3ZlX2xpc3QgKHN1YmZvcm1fYm94ZXNMRiAoZnN0IHMpKSAoc3ViZm9ybV9ib3hlc0xGIChzbmQgcykpKVxuXG4oKiogdmFsIHVzYWJsZV9ib3hlcyA6IGNvcV9TZXEgLT4gY29xX01Qcm9wRiBsaXN0ICoqKVxuXG5sZXQgdXNhYmxlX2JveGVzIHMgPVxuICByZW1vdmVfbGlzdCAodG9wX2JveGVzIChmc3QgcykpIChzdWJmb3JtX2JveGVzUyBzKVxuIiwib3BlbiBDTUxfU3ludGF4XG5vcGVuIERhdGF0eXBlc1xub3BlbiBLU19jYWxjXG5vcGVuIFNwZWNpZlxub3BlbiBMaXN0X2xlbXNcbm9wZW4gUmVtb3ZlX2xpc3RfbGVtc1xuXG50eXBlIF9fID0gT2JqLnRcbmxldCBfXyA9IGxldCByZWMgZiBfID0gT2JqLnJlcHIgZiBpbiBPYmoucmVwciBmXG5cbigqKiB2YWwgZGVjX2lzX1Byb3BWYXIgOiBjb3FfTVByb3BGIC0+ICgoY2hhciBsaXN0LCBfXykgc2lnVCwgX18pIHN1bSAqKilcblxubGV0IGRlY19pc19Qcm9wVmFyID0gZnVuY3Rpb25cbnwgVmFyIHMgLT4gQ29xX2lubCAoQ29xX2V4aXN0VCAocywgX18pKVxufCBfIC0+IENvcV9pbnIgX19cblxuKCoqIHZhbCBkZWNfcHJvcF92YXJfaW4gOlxuICAgIChjb3FfTVByb3BGIGxpc3QgKiBjb3FfTVByb3BGIGxpc3QpIC0+ICgoY2hhciBsaXN0LCBfXykgc2lnVCwgX18pIHN1bSAqKilcblxubGV0IGRlY19wcm9wX3Zhcl9pbiA9IGZ1bmN0aW9uXG58IChsLCBsMCkgLT5cbiAgbGV0IHJlYyBmID0gZnVuY3Rpb25cbiAgfCBbXSAtPiBDb3FfaW5yIF9fXG4gIHwgeSA6OiBsMiAtPlxuICAgIChtYXRjaCBmIGwyIHdpdGhcbiAgICAgfCBDb3FfaW5sIHMwIC0+XG4gICAgICAgbGV0IENvcV9leGlzdFQgKHgsIF8pID0gczAgaW4gQ29xX2lubCAoQ29xX2V4aXN0VCAoeCwgX18pKVxuICAgICB8IENvcV9pbnIgXyAtPlxuICAgICAgIGxldCBzMCA9IGRlY19pc19Qcm9wVmFyIHkgaW5cbiAgICAgICAobWF0Y2ggczAgd2l0aFxuICAgICAgICB8IENvcV9pbmwgczEgLT5cbiAgICAgICAgICBsZXQgczIgPSBjb3FfSW5fZGVjIGwwIHkgaW5cbiAgICAgICAgICBpZiBzMlxuICAgICAgICAgIHRoZW4gQ29xX2lubCAobGV0IENvcV9leGlzdFQgKHgsIF8pID0gczEgaW4gQ29xX2V4aXN0VCAoeCwgX18pKVxuICAgICAgICAgIGVsc2UgQ29xX2luciBfX1xuICAgICAgICB8IENvcV9pbnIgXyAtPiBDb3FfaW5yIF9fKSlcbiAgaW4gZiBsXG5cbigqKiB2YWwgZGVjX0tTX2luaXRfcnVsZXMgOlxuICAgIGNvcV9TZXEgLT4gKChjb3FfSWRQUnVsZSwgY29xX0JvdExSdWxlKSBzdW0sIF9fKSBzdW0gKiopXG5cbmxldCBkZWNfS1NfaW5pdF9ydWxlcyA9IGZ1bmN0aW9uXG58IChsLCBsMCkgLT5cbiAgbGV0IHMwID0gZGVjX3Byb3BfdmFyX2luIChsLCBsMCkgaW5cbiAgKG1hdGNoIHMwIHdpdGhcbiAgIHwgQ29xX2lubCBzMSAtPlxuICAgICBsZXQgQ29xX2V4aXN0VCAoeCwgXykgPSBzMSBpblxuICAgICBDb3FfaW5sIChDb3FfaW5sXG4gICAgIChsZXQgaCA9IGluX3NwbGl0VCAoVmFyIHgpIGwgaW5cbiAgICAgIGxldCBDb3FfZXhpc3RUICh4MCwgczIpID0gaCBpblxuICAgICAgbGV0IENvcV9leGlzdFQgKHgxLCBfKSA9IHMyIGluXG4gICAgICBsZXQgaDAgPSBpbl9zcGxpdFQgKFZhciB4KSBsMCBpblxuICAgICAgbGV0IENvcV9leGlzdFQgKHgyLCBzMykgPSBoMCBpblxuICAgICAgbGV0IENvcV9leGlzdFQgKHgzLCBfKSA9IHMzIGluIElkUFJ1bGVfSSAoeCwgeDAsIHgxLCB4MiwgeDMpKSlcbiAgIHwgQ29xX2luciBfIC0+XG4gICAgIGxldCBzMSA9IGNvcV9Jbl9kZWMgbCBCb3QgaW5cbiAgICAgaWYgczFcbiAgICAgdGhlbiBDb3FfaW5sXG4gICAgICAgICAgICAobGV0IGkgPSBpbl9zcGxpdFQgQm90IGwgaW5cbiAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeCwgczIpID0gaSBpblxuICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MCwgXykgPSBzMiBpbiBDb3FfaW5yIChCb3RMUnVsZV9JICh4LCB4MCwgbDApKSlcbiAgICAgZWxzZSBDb3FfaW5yIF9fKVxuIiwib3BlbiBDTUxfU3ludGF4XG5vcGVuIERhdGF0eXBlc1xub3BlbiBMaXN0XG5vcGVuIExpc3RfbGVtbWFzVFxub3BlbiBQZWFub05hdFxub3BlbiBTcGVjaWZcbm9wZW4gR2VuVFxub3BlbiBVbml2X2dlbl9leHRcblxudHlwZSBfXyA9IE9iai50XG5sZXQgX18gPSBsZXQgcmVjIGYgXyA9IE9iai5yZXByIGYgaW4gT2JqLnJlcHIgZlxuXG4oKiogdmFsIHByb2oxX3NpZ1QyIDogKCdhMSwgJ2EyKSBzaWdUIC0+ICdhMSAqKilcblxubGV0IHByb2oxX3NpZ1QyID0gZnVuY3Rpb25cbnwgQ29xX2V4aXN0VCAoYSwgXykgLT4gYVxuXG4oKiogdmFsIHByb2oyX3NpZ1QyIDogKCdhMSwgJ2EyKSBzaWdUIC0+ICdhMiAqKilcblxubGV0IHByb2oyX3NpZ1QyID0gZnVuY3Rpb25cbnwgQ29xX2V4aXN0VCAoXywgYikgLT4gYlxuXG4oKiogdmFsIGNvcV9Jbl9JblRfcGFpciA6XG4gICAgY29xX01Qcm9wRiAtPiBuYXQgLT4gKGNvcV9NUHJvcEYgKiBuYXQpIGxpc3QgLT4gKGNvcV9NUHJvcEYgKiBuYXQpIGNvcV9JblQgKiopXG5cbmxldCByZWMgY29xX0luX0luVF9wYWlyIGEgbiA9IGZ1bmN0aW9uXG58IFtdIC0+IGFzc2VydCBmYWxzZSAoKiBhYnN1cmQgY2FzZSAqKVxufCB5IDo6IGwwIC0+XG4gIGxldCBoMCA9XG4gICAgbGV0IChtLCBuMCkgPSB5IGluXG4gICAgbGV0IHMgPSBlcV9kZWNfZm9ybSBhIG0gaW4gaWYgcyB0aGVuIE5hdC5lcV9kZWMgbiBuMCBlbHNlIGZhbHNlXG4gIGluXG4gIGlmIGgwXG4gIHRoZW4gY29xX0luVF9lcSAoYSwgbikgbDBcbiAgZWxzZSBJblRfY29ucyAoeSwgbDAsIChjb3FfSW5fSW5UX3BhaXIgYSBuIGwwKSlcblxuKCoqIHZhbCBjb3FfSW5UX21hcF9pZmYgOlxuICAgICgnYTEgLT4gJ2EyKSAtPiAnYTEgbGlzdCAtPiAnYTIgLT4gKCdhMiBjb3FfSW5UIC0+ICgnYTEsIF9fICogJ2ExXG4gICAgY29xX0luVCkgc2lnVCkgKiAoKCdhMSwgX18gKiAnYTEgY29xX0luVCkgc2lnVCAtPiAnYTIgY29xX0luVCkgKiopXG5cbmxldCByZWMgY29xX0luVF9tYXBfaWZmIGYgPSBmdW5jdGlvblxufCBbXSAtPlxuICAoZnVuIF8gLT4gKChmdW4gXyAtPiBhc3NlcnQgZmFsc2UgKCogYWJzdXJkIGNhc2UgKikpLCAoZnVuIF8gLT5cbiAgICBhc3NlcnQgZmFsc2UgKCogYWJzdXJkIGNhc2UgKikpKSlcbnwgeSA6OiBsMCAtPlxuICBsZXQgaUhsID0gY29xX0luVF9tYXBfaWZmIGYgbDAgaW5cbiAgKGZ1biB5MCAtPiAoKGZ1biB4IC0+XG4gIG1hdGNoIHggd2l0aFxuICB8IEluVF9lcScgKF8sIF8pIC0+IENvcV9leGlzdFQgKHksIChfXywgKGNvcV9JblRfZXEgeSBsMCkpKVxuICB8IEluVF9jb25zIChfLCBfLCB4MCkgLT5cbiAgICBsZXQgcCA9IGlIbCB5MCBpblxuICAgIGxldCAocywgXykgPSBwIGluXG4gICAgbGV0IHgxID0gcyB4MCBpblxuICAgIGxldCBDb3FfZXhpc3RUICh4MiwgcDApID0geDEgaW5cbiAgICBsZXQgKF8sIGkpID0gcDAgaW4gQ29xX2V4aXN0VCAoeDIsIChfXywgKEluVF9jb25zICh5LCBsMCwgaSkpKSkpLFxuICAoZnVuIHggLT5cbiAgbGV0IHAgPSBpSGwgeTAgaW5cbiAgbGV0IChfLCBpKSA9IHAgaW5cbiAgbGV0IHAwID0gcHJvajJfc2lnVDIgeCBpblxuICBsZXQgKF8sIGkwKSA9IHAwIGluXG4gIChtYXRjaCBpMCB3aXRoXG4gICB8IEluVF9lcScgKF8sIF8pIC0+IGNvcV9JblRfZXEgKGYgeSkgKG1hcCBmIGwwKVxuICAgfCBJblRfY29ucyAoXywgXywgeDApIC0+XG4gICAgIGxldCB4MSA9IENvcV9leGlzdFQgKChwcm9qMV9zaWdUMiB4KSwgKF9fLCB4MCkpIGluXG4gICAgIGxldCB4MiA9IGkgeDEgaW4gSW5UX2NvbnMgKChmIHkpLCAobWFwIGYgbDApLCB4MikpKSkpXG5cbigqKiB2YWwgcG9zX3RvcF9pbXBzIDogY29xX01Qcm9wRiBsaXN0IC0+IChjb3FfTVByb3BGICogbmF0KSBsaXN0ICoqKVxuXG5sZXQgcmVjIHBvc190b3BfaW1wcyA9IGZ1bmN0aW9uXG58IFtdIC0+IFtdXG58IGggOjogdCAtPlxuICAobWF0Y2ggaCB3aXRoXG4gICB8IEltcCAoYSwgYikgLT5cbiAgICAgKChJbXAgKGEsIGIpKSwgKFNcbiAgICAgICBPKSkgOjogKG1hcCAoZnVuIHkgLT4gKChmc3QgeSksIChTIChzbmQgeSkpKSkgKHBvc190b3BfaW1wcyB0KSlcbiAgIHwgXyAtPiBtYXAgKGZ1biB5IC0+ICgoZnN0IHkpLCAoUyAoc25kIHkpKSkpIChwb3NfdG9wX2ltcHMgdCkpXG5cbigqKiB2YWwgdG9wX2JveGVzX25vYm94X2dlbl9leHQgOiBjb3FfTVByb3BGIGxpc3QgLT4gbm9ib3hfZ2VuX2V4dCAqKilcblxubGV0IHJlYyB0b3BfYm94ZXNfbm9ib3hfZ2VuX2V4dCA9IGZ1bmN0aW9uXG58IFtdIC0+IENvcV91bml2X2dlbl9leHRfbmlsXG58IHkgOjogbDAgLT5cbiAgKG1hdGNoIHkgd2l0aFxuICAgfCBCb3ggbSAtPlxuICAgICBDb3FfdW5pdl9nZW5fZXh0X2NvbnMgKChCb3ggbSksICh0b3BfYm94ZXMgbDApLCBsMCxcbiAgICAgICAodG9wX2JveGVzX25vYm94X2dlbl9leHQgbDApKVxuICAgfCB4IC0+XG4gICAgIENvcV91bml2X2dlbl9leHRfZXh0cmEgKHgsICh0b3BfYm94ZXMgbDApLCBsMCwgX18sXG4gICAgICAgKHRvcF9ib3hlc19ub2JveF9nZW5fZXh0IGwwKSkpXG5cbigqKiB2YWwgZmxhdHRlbl9saXN0IDogJ2ExIGxpc3QgbGlzdCAtPiAnYTEgbGlzdCAqKilcblxubGV0IHJlYyBmbGF0dGVuX2xpc3QgPSBmdW5jdGlvblxufCBbXSAtPiBbXVxufCBoIDo6IHQgLT4gYXBwIGggKGZsYXR0ZW5fbGlzdCB0KVxuXG4oKiogdmFsIGNvcV9JblRfZmxhdHRlbl9saXN0X0luVF9lbGVtIDpcbiAgICAnYTEgbGlzdCBsaXN0IC0+ICdhMSAtPiAnYTEgY29xX0luVCAtPiAoJ2ExIGxpc3QsICdhMSBjb3FfSW5UICogJ2ExIGxpc3RcbiAgICBjb3FfSW5UKSBzaWdUICoqKVxuXG5sZXQgcmVjIGNvcV9JblRfZmxhdHRlbl9saXN0X0luVF9lbGVtIGwgYiB4ID1cbiAgbWF0Y2ggbCB3aXRoXG4gIHwgW10gLT4gYXNzZXJ0IGZhbHNlICgqIGFic3VyZCBjYXNlICopXG4gIHwgeSA6OiBsMCAtPlxuICAgIGxldCB4MCA9IGNvcV9JblRfYXBwX29yIHkgKGZsYXR0ZW5fbGlzdCBsMCkgYiB4IGluXG4gICAgKG1hdGNoIHgwIHdpdGhcbiAgICAgfCBDb3FfaW5sIGkgLT4gQ29xX2V4aXN0VCAoeSwgKGksIChjb3FfSW5UX2VxIHkgbDApKSlcbiAgICAgfCBDb3FfaW5yIGkgLT5cbiAgICAgICBsZXQgcyA9IGNvcV9JblRfZmxhdHRlbl9saXN0X0luVF9lbGVtIGwwIGIgaW5cbiAgICAgICBsZXQgaTAgPSBzIGkgaW5cbiAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDEsIHApID0gaTAgaW5cbiAgICAgICBsZXQgKGkxLCBpMikgPSBwIGluIENvcV9leGlzdFQgKHgxLCAoaTEsIChJblRfY29ucyAoeSwgbDAsIGkyKSkpKSlcblxuKCoqIHZhbCBjb3FfSW5UX3RyYW5zX2ZsYXR0ZW5fbGlzdCA6XG4gICAgJ2ExIGxpc3QgbGlzdCAtPiAnYTEgbGlzdCAtPiAnYTEgLT4gJ2ExIGNvcV9JblQgLT4gJ2ExIGxpc3QgY29xX0luVCAtPlxuICAgICdhMSBjb3FfSW5UICoqKVxuXG5sZXQgcmVjIGNvcV9JblRfdHJhbnNfZmxhdHRlbl9saXN0IGwgYnMgYiB4IHgwID1cbiAgbWF0Y2ggbCB3aXRoXG4gIHwgW10gLT4gYXNzZXJ0IGZhbHNlICgqIGFic3VyZCBjYXNlICopXG4gIHwgeSA6OiBsMCAtPlxuICAgIChtYXRjaCB4MCB3aXRoXG4gICAgIHwgSW5UX2VxJyAoXywgXykgLT4gY29xX0luVF9vcl9hcHAgYnMgKGZsYXR0ZW5fbGlzdCBsMCkgYiAoQ29xX2lubCB4KVxuICAgICB8IEluVF9jb25zIChfLCBfLCB4MSkgLT5cbiAgICAgICBjb3FfSW5UX29yX2FwcCB5IChmbGF0dGVuX2xpc3QgbDApIGIgKENvcV9pbnJcbiAgICAgICAgIChjb3FfSW5UX3RyYW5zX2ZsYXR0ZW5fbGlzdCBsMCBicyBiIHggeDEpKSlcblxuKCoqIHZhbCBsaXN0X29mX3NwbGl0cyA6XG4gICAgY29xX01Qcm9wRiBsaXN0IC0+ICgoY29xX01Qcm9wRiBsaXN0ICogY29xX01Qcm9wRiBsaXN0KSBsaXN0LCBfXykgc2lnVCAqKilcblxubGV0IHJlYyBsaXN0X29mX3NwbGl0cyA9IGZ1bmN0aW9uXG58IFtdIC0+IENvcV9leGlzdFQgKCgoW10sIFtdKSA6OiBbXSksIF9fKVxufCB5IDo6IGwwIC0+XG4gIGxldCBDb3FfZXhpc3RUICh4LCBfKSA9IGxpc3Rfb2Zfc3BsaXRzIGwwIGluXG4gIENvcV9leGlzdFRcbiAgKChhcHAgKChbXSwgKHkgOjogbDApKSA6OiBbXSlcbiAgICAgKG1hcCAoZnVuIHkwIC0+ICgoeSA6OiAoZnN0IHkwKSksIChzbmQgeTApKSkgeCkpLCBfXylcblxuKCoqIHZhbCBsaXN0SW5zZXJ0cyA6XG4gICAgY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgLT4gY29xX01Qcm9wRiBsaXN0IGxpc3QgKiopXG5cbmxldCBsaXN0SW5zZXJ0cyBsIGEgPVxuICBtYXAgKGZ1biB5IC0+IGFwcCAoZnN0IHkpIChhIDo6IChzbmQgeSkpKSAocHJvajFfc2lnVDIgKGxpc3Rfb2Zfc3BsaXRzIGwpKVxuXG4oKiogdmFsIGxpc3RJbnNlcnRzUl9TZXFzIDpcbiAgICBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgLT4gKGNvcV9NUHJvcEZcbiAgICBsaXN0ICogY29xX01Qcm9wRiBsaXN0KSBsaXN0ICoqKVxuXG5sZXQgbGlzdEluc2VydHNSX1NlcXMgX1VVMDM5M18gX1VVMDM5NF8gYSA9XG4gIG1hcCAoZnVuIHkgLT4gKHksIF9VVTAzOTRfKSkgKGxpc3RJbnNlcnRzIF9VVTAzOTNfIGEpXG5cbigqKiB2YWwgbGlzdEluc2VydHNMX1NlcXMgOlxuICAgIGNvcV9NUHJvcEYgbGlzdCAtPiBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiAtPiAoY29xX01Qcm9wRlxuICAgIGxpc3QgKiBjb3FfTVByb3BGIGxpc3QpIGxpc3QgKiopXG5cbmxldCBsaXN0SW5zZXJ0c0xfU2VxcyBfVVUwMzkzXyBfVVUwMzk0XyBhID1cbiAgbWFwIChmdW4geSAtPiAoX1VVMDM5M18sIHkpKSAobGlzdEluc2VydHMgX1VVMDM5NF8gYSlcblxuKCoqIHZhbCByZW1vdmVfbnRoIDpcbiAgICBuYXQgLT4gY29xX01Qcm9wRiAtPiBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiBsaXN0ICoqKVxuXG5sZXQgcmVjIHJlbW92ZV9udGggbiBhIGwgPVxuICBtYXRjaCBuIHdpdGhcbiAgfCBPIC0+IGxcbiAgfCBTIG0gLT5cbiAgICAobWF0Y2ggbSB3aXRoXG4gICAgIHwgTyAtPlxuICAgICAgIChtYXRjaCBsIHdpdGhcbiAgICAgICAgfCBbXSAtPiBbXVxuICAgICAgICB8IGIgOjogdGwgLT4gaWYgZXFfZGVjX2Zvcm0gYSBiIHRoZW4gdGwgZWxzZSBiIDo6IHRsKVxuICAgICB8IFMgXyAtPiAobWF0Y2ggbCB3aXRoXG4gICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICB8IGIgOjogdGwgLT4gYiA6OiAocmVtb3ZlX250aCBtIGEgdGwpKSlcblxuKCoqIHZhbCBudGhfc3BsaXQgOlxuICAgIG5hdCAtPiBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiBsaXN0ICogY29xX01Qcm9wRiBsaXN0ICoqKVxuXG5sZXQgcmVjIG50aF9zcGxpdCBuIGwgPVxuICBtYXRjaCBuIHdpdGhcbiAgfCBPIC0+IChbXSwgbClcbiAgfCBTIG0gLT5cbiAgICAobWF0Y2ggbSB3aXRoXG4gICAgIHwgTyAtPiAobWF0Y2ggbCB3aXRoXG4gICAgICAgICAgICAgfCBbXSAtPiAoW10sIFtdKVxuICAgICAgICAgICAgIHwgYiA6OiB0bCAtPiAoKGIgOjogW10pLCB0bCkpXG4gICAgIHwgUyBfIC0+XG4gICAgICAgKG1hdGNoIGwgd2l0aFxuICAgICAgICB8IFtdIC0+IChbXSwgW10pXG4gICAgICAgIHwgYiA6OiB0bCAtPiAoKGIgOjogKGZzdCAobnRoX3NwbGl0IG0gdGwpKSksIChzbmQgKG50aF9zcGxpdCBtIHRsKSkpKSlcbiIsIm9wZW4gQ01MX1N5bnRheFxub3BlbiBEYXRhdHlwZXNcbm9wZW4gS1NfY2FsY1xub3BlbiBLU190ZXJtaW5hdGlvbl9wcmVsaW1zXG5vcGVuIExpc3Rcbm9wZW4gTGlzdF9sZW1tYXNUXG5vcGVuIFNwZWNpZlxub3BlbiBHZW5UXG5vcGVuIExpc3RfbGVtc1xuXG50eXBlIF9fID0gT2JqLnRcbmxldCBfXyA9IGxldCByZWMgZiBfID0gT2JqLnJlcHIgZiBpbiBPYmoucmVwciBmXG5cbigqKiB2YWwgcHJlbXNfSW1wX1IgOiAoY29xX01Qcm9wRiAqIG5hdCkgbGlzdCAtPiBjb3FfU2VxIC0+IGNvcV9TZXEgbGlzdCAqKilcblxubGV0IHJlYyBwcmVtc19JbXBfUiBsIHMgPVxuICBtYXRjaCBsIHdpdGhcbiAgfCBbXSAtPiBbXVxuICB8IHAgOjogdCAtPlxuICAgIGxldCAoYywgbikgPSBwIGluXG4gICAgKG1hdGNoIG4gd2l0aFxuICAgICB8IE8gLT4gcHJlbXNfSW1wX1IgdCBzXG4gICAgIHwgUyBtIC0+XG4gICAgICAgKG1hdGNoIGMgd2l0aFxuICAgICAgICB8IEltcCAoYSwgYikgLT5cbiAgICAgICAgICBhcHBcbiAgICAgICAgICAgIChsaXN0SW5zZXJ0c1JfU2VxcyAoZnN0IHMpXG4gICAgICAgICAgICAgIChhcHAgKGZzdCAobnRoX3NwbGl0IG0gKHJlbW92ZV9udGggKFMgbSkgYyAoc25kIHMpKSkpXG4gICAgICAgICAgICAgICAgKGIgOjogKHNuZCAobnRoX3NwbGl0IG0gKHJlbW92ZV9udGggKFMgbSkgYyAoc25kIHMpKSkpKSkgYSlcbiAgICAgICAgICAgIChwcmVtc19JbXBfUiB0IHMpXG4gICAgICAgIHwgXyAtPiBwcmVtc19JbXBfUiB0IHMpKVxuXG4oKiogdmFsIGNvcV9Jbl9wb3NfdG9wX2ltcHNfc3BsaXRfbCA6XG4gICAgY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgLT4gbmF0IC0+IChjb3FfTVByb3BGIGxpc3QsIChjb3FfTVByb3BGXG4gICAgbGlzdCwgX18pIHNpZ1QpIHNpZ1QgKiopXG5cbmxldCByZWMgY29xX0luX3Bvc190b3BfaW1wc19zcGxpdF9sIGwgYSBuID1cbiAgbWF0Y2ggbCB3aXRoXG4gIHwgW10gLT4gYXNzZXJ0IGZhbHNlICgqIGFic3VyZCBjYXNlICopXG4gIHwgeSA6OiBsMCAtPlxuICAgIChtYXRjaCB5IHdpdGhcbiAgICAgfCBJbXAgKG0sIG0wKSAtPlxuICAgICAgIGxldCBoID1cbiAgICAgICAgIGNvcV9Jbl9JblRfcGFpciBhIChTIG4pICgoKEltcCAobSwgbTApKSwgKFNcbiAgICAgICAgICAgTykpIDo6IChtYXAgKGZ1biB5MCAtPiAoKGZzdCB5MCksIChTIChzbmQgeTApKSkpIChwb3NfdG9wX2ltcHMgbDApKSlcbiAgICAgICBpblxuICAgICAgIChtYXRjaCBoIHdpdGhcbiAgICAgICAgfCBJblRfZXEnIChfLCBfKSAtPiBDb3FfZXhpc3RUIChbXSwgKENvcV9leGlzdFQgKGwwLCBfXykpKVxuICAgICAgICB8IEluVF9jb25zIChfLCBfLCBfKSAtPlxuICAgICAgICAgIChtYXRjaCBuIHdpdGhcbiAgICAgICAgICAgfCBPIC0+IGFzc2VydCBmYWxzZSAoKiBhYnN1cmQgY2FzZSAqKVxuICAgICAgICAgICB8IFMgbjAgLT5cbiAgICAgICAgICAgICBsZXQgcyA9IGNvcV9Jbl9wb3NfdG9wX2ltcHNfc3BsaXRfbCBsMCBhIG4wIGluXG4gICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgsIHMwKSA9IHMgaW5cbiAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDAsIF8pID0gczAgaW5cbiAgICAgICAgICAgICBDb3FfZXhpc3RUICgoKEltcCAobSwgbTApKSA6OiB4KSwgKENvcV9leGlzdFQgKHgwLCBfXykpKSkpXG4gICAgIHwgeCAtPlxuICAgICAgIChtYXRjaCBuIHdpdGhcbiAgICAgICAgfCBPIC0+IGFzc2VydCBmYWxzZSAoKiBhYnN1cmQgY2FzZSAqKVxuICAgICAgICB8IFMgbjAgLT5cbiAgICAgICAgICBsZXQgcyA9IGNvcV9Jbl9wb3NfdG9wX2ltcHNfc3BsaXRfbCBsMCBhIG4wIGluXG4gICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgwLCBzMCkgPSBzIGluXG4gICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgxLCBfKSA9IHMwIGluXG4gICAgICAgICAgQ29xX2V4aXN0VCAoKHggOjogeDApLCAoQ29xX2V4aXN0VCAoeDEsIF9fKSkpKSlcblxuKCoqIHZhbCBjb3FfSW1wUl9oZWxwMDEgOlxuICAgIGNvcV9TZXEgLT4gY29xX1NlcSAtPiAoY29xX01Qcm9wRiAqIG5hdCkgbGlzdCAtPiBjb3FfU2VxIGNvcV9JblQgLT4gKG5hdCxcbiAgICAoY29xX01Qcm9wRiwgKGNvcV9NUHJvcEYsIChjb3FfTVByb3BGIGxpc3QsIChjb3FfTVByb3BGIGxpc3QsIChjb3FfTVByb3BGXG4gICAgbGlzdCwgKGNvcV9NUHJvcEYgbGlzdCwgX18pIHNpZ1QpIHNpZ1QpIHNpZ1QpIHNpZ1QpIHNpZ1QpIHNpZ1QpIHNpZ1QgKiopXG5cbmxldCBjb3FfSW1wUl9oZWxwMDEgcHJlbSBzIGwzID1cbiAgbGV0IChsLCBsMCkgPSBzIGluXG4gIGxldCByZWMgZiBsMSB4ID1cbiAgICBtYXRjaCBsMSB3aXRoXG4gICAgfCBbXSAtPiBhc3NlcnQgZmFsc2UgKCogYWJzdXJkIGNhc2UgKilcbiAgICB8IHkgOjogbDIgLT5cbiAgICAgIGxldCAobSwgbikgPSB5IGluXG4gICAgICAobWF0Y2ggbSB3aXRoXG4gICAgICAgfCBJbXAgKG0wLCBtMSkgLT5cbiAgICAgICAgIChtYXRjaCBuIHdpdGhcbiAgICAgICAgICB8IE8gLT5cbiAgICAgICAgICAgIGxldCBzMCA9IGYgbDIgeCBpblxuICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgwLCBzMSkgPSBzMCBpblxuICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgxLCBzMikgPSBzMSBpblxuICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgyLCBzMykgPSBzMiBpblxuICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgzLCBzNCkgPSBzMyBpblxuICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHg0LCBzNSkgPSBzNCBpblxuICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHg1LCBzNikgPSBzNSBpblxuICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHg2LCBfKSA9IHM2IGluXG4gICAgICAgICAgICBDb3FfZXhpc3RUICh4MCwgKENvcV9leGlzdFQgKHgxLCAoQ29xX2V4aXN0VCAoeDIsIChDb3FfZXhpc3RUXG4gICAgICAgICAgICAoeDMsIChDb3FfZXhpc3RUICh4NCwgKENvcV9leGlzdFQgKHg1LCAoQ29xX2V4aXN0VCAoeDYsXG4gICAgICAgICAgICBfXykpKSkpKSkpKSkpKSlcbiAgICAgICAgICB8IFMgbjAgLT5cbiAgICAgICAgICAgIGxldCB4MCA9XG4gICAgICAgICAgICAgIGNvcV9JblRfYXBwX29yXG4gICAgICAgICAgICAgICAgKGxpc3RJbnNlcnRzUl9TZXFzIChmc3QgKGwsIGwwKSlcbiAgICAgICAgICAgICAgICAgIChhcHBcbiAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjBcbiAgICAgICAgICAgICAgICAgICAgICAgIChyZW1vdmVfbnRoIChTIG4wKSAoSW1wIChtMCwgbTEpKSAoc25kIChsLCBsMCkpKSkpXG4gICAgICAgICAgICAgICAgICAgIChtMSA6OiAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzbmQgKGwsIGwwKSkpKSkpKSBtMClcbiAgICAgICAgICAgICAgICAobGV0IHJlYyBwcmVtc19JbXBfUjAgbDQgczAgPVxuICAgICAgICAgICAgICAgICAgIG1hdGNoIGw0IHdpdGhcbiAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgfCBwIDo6IHQgLT5cbiAgICAgICAgICAgICAgICAgICAgIGxldCAoYywgbjEpID0gcCBpblxuICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIG4xIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICB8IE8gLT4gcHJlbXNfSW1wX1IwIHQgczBcbiAgICAgICAgICAgICAgICAgICAgICB8IFMgbTIgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBjIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICB8IEltcCAoYSwgYikgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobGlzdEluc2VydHNSX1NlcXMgKGZzdCBzMClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXBwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyBtMikgYyAoc25kIHMwKSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGIgOjogKHNuZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG0yXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgbTIpIGMgKHNuZCBzMCkpKSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGEpIChwcmVtc19JbXBfUjAgdCBzMClcbiAgICAgICAgICAgICAgICAgICAgICAgICB8IF8gLT4gcHJlbXNfSW1wX1IwIHQgczApKVxuICAgICAgICAgICAgICAgICBpbiBwcmVtc19JbXBfUjAgbDIgKGwsIGwwKSkgcHJlbSB4XG4gICAgICAgICAgICBpblxuICAgICAgICAgICAgKG1hdGNoIHgwIHdpdGhcbiAgICAgICAgICAgICB8IENvcV9pbmwgaSAtPlxuICAgICAgICAgICAgICAgbGV0IHgxID0gZnVuIGYwIGw0IHkwIC0+XG4gICAgICAgICAgICAgICAgIGxldCAoeDEsIF8pID0gY29xX0luVF9tYXBfaWZmIGYwIGw0IHkwIGluIHgxXG4gICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgbGV0IGkwID1cbiAgICAgICAgICAgICAgICAgeDEgKGZ1biB5MCAtPiAoeTAsXG4gICAgICAgICAgICAgICAgICAgKGFwcFxuICAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG4wIChyZW1vdmVfbnRoIChTIG4wKSAoSW1wIChtMCwgbTEpKSBsMCkpKVxuICAgICAgICAgICAgICAgICAgICAgKG0xIDo6IChzbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgbjApIChJbXAgKG0wLCBtMSkpIGwwKSkpKSkpKVxuICAgICAgICAgICAgICAgICAgIChsaXN0SW5zZXJ0cyBsIG0wKSBwcmVtIGlcbiAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDIsIHApID0gaTAgaW5cbiAgICAgICAgICAgICAgIGxldCAoXywgaTEpID0gcCBpblxuICAgICAgICAgICAgICAgbGV0IHgzID0gZnVuIGYwIGw0IHkwIC0+XG4gICAgICAgICAgICAgICAgIGxldCAoeDMsIF8pID0gY29xX0luVF9tYXBfaWZmIGYwIGw0IHkwIGluIHgzXG4gICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgbGV0IGkyID1cbiAgICAgICAgICAgICAgICAgeDMgKGZ1biB5MCAtPiBhcHAgKGZzdCB5MCkgKG0wIDo6IChzbmQgeTApKSlcbiAgICAgICAgICAgICAgICAgICAocHJvajFfc2lnVDIgKGxpc3Rfb2Zfc3BsaXRzIGwpKSB4MiBpMVxuICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4NCwgXykgPSBpMiBpblxuICAgICAgICAgICAgICAgbGV0IChsNCwgbDUpID0geDQgaW5cbiAgICAgICAgICAgICAgIENvcV9leGlzdFQgKG4wLCAoQ29xX2V4aXN0VCAobTAsIChDb3FfZXhpc3RUIChtMSwgKENvcV9leGlzdFRcbiAgICAgICAgICAgICAgIChsNCwgKENvcV9leGlzdFQgKGw1LCAoQ29xX2V4aXN0VFxuICAgICAgICAgICAgICAgKChmc3QgKG50aF9zcGxpdCBuMCAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSkgbDApKSksXG4gICAgICAgICAgICAgICAoQ29xX2V4aXN0VFxuICAgICAgICAgICAgICAgKChzbmQgKG50aF9zcGxpdCBuMCAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSkgbDApKSksXG4gICAgICAgICAgICAgICBfXykpKSkpKSkpKSkpKSlcbiAgICAgICAgICAgICB8IENvcV9pbnIgaSAtPlxuICAgICAgICAgICAgICAgbGV0IHMwID0gZiBsMiBpIGluXG4gICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDEsIHMxKSA9IHMwIGluXG4gICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDIsIHMyKSA9IHMxIGluXG4gICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDMsIHMzKSA9IHMyIGluXG4gICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDQsIHM0KSA9IHMzIGluXG4gICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDUsIHM1KSA9IHM0IGluXG4gICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDYsIHM2KSA9IHM1IGluXG4gICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDcsIF8pID0gczYgaW5cbiAgICAgICAgICAgICAgIENvcV9leGlzdFQgKHgxLCAoQ29xX2V4aXN0VCAoeDIsIChDb3FfZXhpc3RUICh4MywgKENvcV9leGlzdFRcbiAgICAgICAgICAgICAgICh4NCwgKENvcV9leGlzdFQgKHg1LCAoQ29xX2V4aXN0VCAoeDYsIChDb3FfZXhpc3RUICh4NyxcbiAgICAgICAgICAgICAgIF9fKSkpKSkpKSkpKSkpKSkpXG4gICAgICAgfCBfIC0+XG4gICAgICAgICBsZXQgczAgPSBmIGwyIHggaW5cbiAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MCwgczEpID0gczAgaW5cbiAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MSwgczIpID0gczEgaW5cbiAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MiwgczMpID0gczIgaW5cbiAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MywgczQpID0gczMgaW5cbiAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4NCwgczUpID0gczQgaW5cbiAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4NSwgczYpID0gczUgaW5cbiAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4NiwgXykgPSBzNiBpblxuICAgICAgICAgQ29xX2V4aXN0VCAoeDAsIChDb3FfZXhpc3RUICh4MSwgKENvcV9leGlzdFQgKHgyLCAoQ29xX2V4aXN0VCAoeDMsXG4gICAgICAgICAoQ29xX2V4aXN0VCAoeDQsIChDb3FfZXhpc3RUICh4NSwgKENvcV9leGlzdFQgKHg2LCBfXykpKSkpKSkpKSkpKSkpXG4gIGluIGYgbDNcblxuKCoqIHZhbCBjb3FfSW1wUl9oZWxwMSA6XG4gICAgY29xX1NlcSAtPiAoY29xX01Qcm9wRiBsaXN0ICogY29xX01Qcm9wRiBsaXN0KSAtPiBjb3FfU2VxIGNvcV9JblQgLT5cbiAgICBjb3FfSW1wUlJ1bGUgKiopXG5cbmxldCBjb3FfSW1wUl9oZWxwMSBwcmVtIHMgeCA9XG4gIGxldCBzMCA9IGNvcV9JbXBSX2hlbHAwMSBwcmVtIHMgKHBvc190b3BfaW1wcyAoc25kIHMpKSB4IGluXG4gIGxldCBDb3FfZXhpc3RUICh4MCwgczEpID0gczAgaW5cbiAgbGV0IChfLCBsKSA9IHMgaW5cbiAgbGV0IENvcV9leGlzdFQgKHgxLCBzMikgPSBzMSBpblxuICBsZXQgQ29xX2V4aXN0VCAoeDIsIHMzKSA9IHMyIGluXG4gIGxldCBDb3FfZXhpc3RUICh4MywgczQpID0gczMgaW5cbiAgbGV0IENvcV9leGlzdFQgKHg0LCBfKSA9IHM0IGluXG4gIGxldCBpID0gY29xX0luX3Bvc190b3BfaW1wc19zcGxpdF9sIGwgKEltcCAoeDEsIHgyKSkgeDAgaW5cbiAgbGV0IENvcV9leGlzdFQgKHg1LCBzNSkgPSBpIGluXG4gIGxldCBDb3FfZXhpc3RUICh4NiwgXykgPSBzNSBpbiBJbXBSUnVsZV9JICh4MSwgeDIsIHgzLCB4NCwgeDUsIHg2KVxuXG4oKiogdmFsIGNvcV9JbXBSX2hlbHAwMDIgOlxuICAgIGNvcV9NUHJvcEYgbGlzdCAtPiBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgbGlzdFxuICAgIC0+IGNvcV9NUHJvcEYgLT4gY29xX01Qcm9wRiAtPiAoY29xX01Qcm9wRiBsaXN0ICogY29xX01Qcm9wRiBsaXN0KSBjb3FfSW5UICoqKVxuXG5sZXQgY29xX0ltcFJfaGVscDAwMiBfVVUwMzkzXzAgX1VVMDM5M18xIF9VVTAzOTRfMCBfVVUwMzk0XzEgYSBiID1cbiAgbGV0IGYgPSBmdW4geSAtPiAoeSwgKGFwcCBfVVUwMzk0XzAgKGIgOjogX1VVMDM5NF8xKSkpIGluXG4gIGxldCBsID0gbGlzdEluc2VydHMgKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKSBhIGluXG4gIGxldCB5ID0gKChhcHAgX1VVMDM5M18wIChhIDo6IF9VVTAzOTNfMSkpLCAoYXBwIF9VVTAzOTRfMCAoYiA6OiBfVVUwMzk0XzEpKSlcbiAgaW5cbiAgbGV0IChfLCB4KSA9IGNvcV9JblRfbWFwX2lmZiBmIGwgeSBpblxuICB4IChDb3FfZXhpc3RUICgoYXBwIF9VVTAzOTNfMCAoYSA6OiBfVVUwMzkzXzEpKSwgKF9fLFxuICAgIChsZXQgZjAgPSBmdW4geTAgLT4gYXBwIChmc3QgeTApIChhIDo6IChzbmQgeTApKSBpblxuICAgICBsZXQgbDAgPSBwcm9qMV9zaWdUMiAobGlzdF9vZl9zcGxpdHMgKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKSkgaW5cbiAgICAgbGV0IHkwID0gYXBwIF9VVTAzOTNfMCAoYSA6OiBfVVUwMzkzXzEpIGluXG4gICAgIGxldCAoXywgeDApID0gY29xX0luVF9tYXBfaWZmIGYwIGwwIHkwIGluXG4gICAgIHgwIChDb3FfZXhpc3RUICgoX1VVMDM5M18wLCBfVVUwMzkzXzEpLCAoX18sXG4gICAgICAgKGxldCBzID0gbGlzdF9vZl9zcGxpdHMgKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKSBpblxuICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDEsIF8pID0gcyBpblxuICAgICAgICBjb3FfSW5fSW5UX3NlcXMgKF9VVTAzOTNfMCwgX1VVMDM5M18xKSB4MSkpKSkpKSkpXG5cbigqKiB2YWwgY29xX0ltcFJfaGVscDAyIDpcbiAgICBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgbGlzdCAtPiBjb3FfTVByb3BGIGxpc3RcbiAgICAtPiBjb3FfTVByb3BGIC0+IGNvcV9NUHJvcEYgLT4gKGNvcV9NUHJvcEYgKiBuYXQpIGxpc3QgLT4gbmF0IC0+XG4gICAgY29xX0ltcFJSdWxlIC0+IChjb3FfTVByb3BGIGxpc3QgKiBjb3FfTVByb3BGIGxpc3QpIGNvcV9JblQgKiopXG5cbmxldCByZWMgY29xX0ltcFJfaGVscDAyIF9VVTAzOTNfMCBfVVUwMzkzXzEgX1VVMDM5NF8wIF9VVTAzOTRfMSBhIGIgbCBuIHggPVxuICBtYXRjaCBsIHdpdGhcbiAgfCBbXSAtPiBhc3NlcnQgZmFsc2UgKCogYWJzdXJkIGNhc2UgKilcbiAgfCB5IDo6IGwwIC0+XG4gICAgbGV0IChtLCBuMCkgPSB5IGluXG4gICAgKG1hdGNoIG0gd2l0aFxuICAgICB8IEltcCAobTAsIG0xKSAtPlxuICAgICAgIGxldCBoMSA9XG4gICAgICAgICBjb3FfSW5fSW5UX3BhaXIgKEltcCAoYSwgYikpIChTIG4pICgoKEltcCAobTAsIG0xKSksIG4wKSA6OiBsMClcbiAgICAgICBpblxuICAgICAgIChtYXRjaCBoMSB3aXRoXG4gICAgICAgIHwgSW5UX2VxJyAoXywgXykgLT5cbiAgICAgICAgICAobWF0Y2ggX1VVMDM5NF8wIHdpdGhcbiAgICAgICAgICAgfCBbXSAtPlxuICAgICAgICAgICAgIGxldCBpID0gY29xX0ltcFJfaGVscDAwMiBfVVUwMzkzXzAgX1VVMDM5M18xIFtdIF9VVTAzOTRfMSBhIGIgaW5cbiAgICAgICAgICAgICBsZXQgcyA9IGVxX2RlY19mb3JtIChJbXAgKGEsIGIpKSAoSW1wIChhLCBiKSkgaW5cbiAgICAgICAgICAgICBpZiBzXG4gICAgICAgICAgICAgdGhlbiBjb3FfSW5UX29yX2FwcFxuICAgICAgICAgICAgICAgICAgICAobGlzdEluc2VydHNSX1NlcXMgKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKVxuICAgICAgICAgICAgICAgICAgICAgIChiIDo6IF9VVTAzOTRfMSkgYSlcbiAgICAgICAgICAgICAgICAgICAgKHByZW1zX0ltcF9SIGwwICgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLCAoKEltcCAoYSxcbiAgICAgICAgICAgICAgICAgICAgICBiKSkgOjogX1VVMDM5NF8xKSkpICgoYXBwIF9VVTAzOTNfMCAoYSA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgICAgICAgICAgICAgKGIgOjogX1VVMDM5NF8xKSkgKENvcV9pbmwgaSlcbiAgICAgICAgICAgICBlbHNlIGFzc2VydCBmYWxzZSAoKiBhYnN1cmQgY2FzZSAqKVxuICAgICAgICAgICB8IG0yIDo6IGwxIC0+XG4gICAgICAgICAgICAgY29xX0luVF9vcl9hcHBcbiAgICAgICAgICAgICAgIChsaXN0SW5zZXJ0c1JfU2Vxc1xuICAgICAgICAgICAgICAgICAoZnN0ICgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLFxuICAgICAgICAgICAgICAgICAgIChhcHAgKG0yIDo6IGwxKSAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTRfMSkpKSlcbiAgICAgICAgICAgICAgICAgKGFwcFxuICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgKGxlbmd0aCAobTIgOjogbDEpKVxuICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyAobGVuZ3RoIChtMiA6OiBsMSkpKSAoSW1wIChhLCBiKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAoc25kICgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFwcCAobTIgOjogbDEpICgoSW1wIChhLCBiKSkgOjogX1VVMDM5NF8xKSkpKSkpKVxuICAgICAgICAgICAgICAgICAgIChiIDo6IChzbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgKGxlbmd0aCAobTIgOjogbDEpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyAobGVuZ3RoIChtMiA6OiBsMSkpKSAoSW1wIChhLCBiKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc25kICgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFwcCAobTIgOjogbDEpICgoSW1wIChhLCBiKSkgOjogX1VVMDM5NF8xKSkpKSkpKSkpXG4gICAgICAgICAgICAgICAgIGEpXG4gICAgICAgICAgICAgICAobGV0IHJlYyBwcmVtc19JbXBfUjAgbDIgcyA9XG4gICAgICAgICAgICAgICAgICBtYXRjaCBsMiB3aXRoXG4gICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICB8IHAgOjogdCAtPlxuICAgICAgICAgICAgICAgICAgICBsZXQgKGMsIG4xKSA9IHAgaW5cbiAgICAgICAgICAgICAgICAgICAgKG1hdGNoIG4xIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgIHwgTyAtPiBwcmVtc19JbXBfUjAgdCBzXG4gICAgICAgICAgICAgICAgICAgICB8IFMgbTMgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIGMgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgfCBJbXAgKGEwLCBiMCkgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxpc3RJbnNlcnRzUl9TZXFzIChmc3QgcylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhcHBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbTMgKHJlbW92ZV9udGggKFMgbTMpIGMgKHNuZCBzKSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYjAgOjogKHNuZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG0zXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgbTMpIGMgKHNuZCBzKSkpKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhMCkgKHByZW1zX0ltcF9SMCB0IHMpXG4gICAgICAgICAgICAgICAgICAgICAgICB8IF8gLT4gcHJlbXNfSW1wX1IwIHQgcykpXG4gICAgICAgICAgICAgICAgaW4gcHJlbXNfSW1wX1IwIGwwICgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLFxuICAgICAgICAgICAgICAgICAgICAgKGFwcCAobTIgOjogbDEpICgoSW1wIChhLCBiKSkgOjogX1VVMDM5NF8xKSkpKVxuICAgICAgICAgICAgICAgKChhcHAgX1VVMDM5M18wIChhIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgICAgICAgICAgKGFwcCAobTIgOjogbDEpIChiIDo6IF9VVTAzOTRfMSkpKSAoQ29xX2lubFxuICAgICAgICAgICAgICAgKGNvcV9JbXBSX2hlbHAwMDIgX1VVMDM5M18wIF9VVTAzOTNfMSAobTIgOjogbDEpIF9VVTAzOTRfMSBhIGIpKSlcbiAgICAgICAgfCBJblRfY29ucyAoXywgXywgXykgLT5cbiAgICAgICAgICBsZXQgaSA9XG4gICAgICAgICAgICBjb3FfSW1wUl9oZWxwMDIgX1VVMDM5M18wIF9VVTAzOTNfMSBfVVUwMzk0XzAgX1VVMDM5NF8xIGEgYiBsMFxuICAgICAgICAgICAgICAobGVuZ3RoIF9VVTAzOTRfMCkgeFxuICAgICAgICAgIGluXG4gICAgICAgICAgKG1hdGNoIG4wIHdpdGhcbiAgICAgICAgICAgfCBPIC0+IGlcbiAgICAgICAgICAgfCBTIG4xIC0+XG4gICAgICAgICAgICAgY29xX0luVF9vcl9hcHBcbiAgICAgICAgICAgICAgIChsaXN0SW5zZXJ0c1JfU2VxcyAoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpXG4gICAgICAgICAgICAgICAgIChhcHBcbiAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG4xXG4gICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBuMSB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICB8IE8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIGFwcCBfVVUwMzk0XzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzk0XzEpIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgW10gLT4gW11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgYjAgOjogdGwgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgZXFfZGVjX2Zvcm0gKEltcCAobTAsIG0xKSkgYjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiB0bFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGIwIDo6IHRsKVxuICAgICAgICAgICAgICAgICAgICAgICAgfCBTIF8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIGFwcCBfVVUwMzk0XzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzk0XzEpIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgW10gLT4gW11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgYjAgOjogdGwgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYjAgOjogKHJlbW92ZV9udGggbjEgKEltcCAobTAsIG0xKSkgdGwpKSkpKVxuICAgICAgICAgICAgICAgICAgIChtMSA6OiAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBuMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIG4xIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IE8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBhcHAgX1VVMDM5NF8wICgoSW1wIChhLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYikpIDo6IF9VVTAzOTRfMSkgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgW10gLT4gW11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGIwIDo6IHRsIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBlcV9kZWNfZm9ybSAoSW1wIChtMCwgbTEpKSBiMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiB0bFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBiMCA6OiB0bClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFMgXyAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIGFwcCBfVVUwMzk0XzAgKChJbXAgKGEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiKSkgOjogX1VVMDM5NF8xKSB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBbXSAtPiBbXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgYjAgOjogdGwgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGIwIDo6IChyZW1vdmVfbnRoIG4xIChJbXAgKG0wLCBtMSkpIHRsKSkpKSkpKVxuICAgICAgICAgICAgICAgICBtMClcbiAgICAgICAgICAgICAgIChwcmVtc19JbXBfUiBsMCAoKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKSxcbiAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzk0XzEpKSkpXG4gICAgICAgICAgICAgICAoKGFwcCBfVVUwMzkzXzAgKGEgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCAoYiA6OiBfVVUwMzk0XzEpKSkgKENvcV9pbnIgaSkpKVxuICAgICB8IHgwIC0+XG4gICAgICAgbGV0IGgxID0gY29xX0luX0luVF9wYWlyIChJbXAgKGEsIGIpKSAoUyBuKSAoKHgwLCBuMCkgOjogbDApIGluXG4gICAgICAgKG1hdGNoIGgxIHdpdGhcbiAgICAgICAgfCBJblRfZXEnIChfLCBfKSAtPiBhc3NlcnQgZmFsc2UgKCogYWJzdXJkIGNhc2UgKilcbiAgICAgICAgfCBJblRfY29ucyAoXywgXywgXykgLT5cbiAgICAgICAgICBjb3FfSW1wUl9oZWxwMDIgX1VVMDM5M18wIF9VVTAzOTNfMSBfVVUwMzk0XzAgX1VVMDM5NF8xIGEgYiBsMFxuICAgICAgICAgICAgKGxlbmd0aCBfVVUwMzk0XzApIHgpKVxuXG4oKiogdmFsIGNvcV9JbXBSX2hlbHAyIDpcbiAgICBjb3FfU2VxIC0+IGNvcV9TZXEgLT4gY29xX0ltcFJSdWxlIC0+IGNvcV9TZXEgY29xX0luVCAqKilcblxubGV0IGNvcV9JbXBSX2hlbHAyIF8gXyB4ID0gbWF0Y2ggeCB3aXRoXG58IEltcFJSdWxlX0kgKGEsIGIsIF9VVTAzOTNfMCwgX1VVMDM5M18xLCBfVVUwMzk0XzAsIF9VVTAzOTRfMSkgLT5cbiAgY29xX0ltcFJfaGVscDAyIF9VVTAzOTNfMCBfVVUwMzkzXzEgX1VVMDM5NF8wIF9VVTAzOTRfMSBhIGJcbiAgICAocG9zX3RvcF9pbXBzIChhcHAgX1VVMDM5NF8wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5NF8xKSkpXG4gICAgKGxlbmd0aCBfVVUwMzk0XzApIHhcblxuKCoqIHZhbCBmaW5pdGVfSW1wUl9wcmVtaXNlc19vZl9TIDpcbiAgICBjb3FfU2VxIC0+IChjb3FfU2VxIGxpc3QgbGlzdCwgY29xX1NlcSBsaXN0IC0+IChjb3FfSW1wUlJ1bGUgLT4gY29xX1NlcVxuICAgIGxpc3QgY29xX0luVCkgKiAoY29xX1NlcSBsaXN0IGNvcV9JblQgLT4gY29xX0ltcFJSdWxlKSkgc2lnVCAqKilcblxubGV0IGZpbml0ZV9JbXBSX3ByZW1pc2VzX29mX1MgPSBmdW5jdGlvblxufCAobCwgbDApIC0+XG4gIENvcV9leGlzdFRcbiAgICAoKG1hcCAoZnVuIHkgLT4geSA6OiBbXSkgKHByZW1zX0ltcF9SIChwb3NfdG9wX2ltcHMgbDApIChsLCBsMCkpKSxcbiAgICAoZnVuIHByZW1zIC0+ICgoZnVuIGggLT5cbiAgICBsZXQgSW1wUlJ1bGVfSSAoYSwgYiwgX1VVMDM5M18wLCBfVVUwMzkzXzEsIF9VVTAzOTRfMCwgX1VVMDM5NF8xKSA9IGggaW5cbiAgICBsZXQgZiA9IGZ1biB5IC0+IHkgOjogW10gaW5cbiAgICBsZXQgbDEgPVxuICAgICAgcHJlbXNfSW1wX1IgKHBvc190b3BfaW1wcyAoYXBwIF9VVTAzOTRfMCAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTRfMSkpKVxuICAgICAgICAoKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKSxcbiAgICAgICAgKGFwcCBfVVUwMzk0XzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzk0XzEpKSlcbiAgICBpblxuICAgIGxldCB5ID0gKChhcHAgX1VVMDM5M18wIChhIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgKGFwcCBfVVUwMzk0XzAgKGIgOjogX1VVMDM5NF8xKSkpIDo6IFtdXG4gICAgaW5cbiAgICBsZXQgKF8sIHgpID0gY29xX0luVF9tYXBfaWZmIGYgbDEgeSBpblxuICAgIHggKENvcV9leGlzdFQgKCgoYXBwIF9VVTAzOTNfMCAoYSA6OiBfVVUwMzkzXzEpKSxcbiAgICAgIChhcHAgX1VVMDM5NF8wIChiIDo6IF9VVTAzOTRfMSkpKSwgKF9fLFxuICAgICAgKGNvcV9JbXBSX2hlbHAyICgoYXBwIF9VVTAzOTNfMCAoYSA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgKGFwcCBfVVUwMzk0XzAgKGIgOjogX1VVMDM5NF8xKSkpICgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLFxuICAgICAgICAoYXBwIF9VVTAzOTRfMCAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTRfMSkpKSBoKSkpKSksIChmdW4gaCAtPlxuICAgIGxldCB4ID0gZnVuIGYgbDEgeSAtPiBsZXQgKHgsIF8pID0gY29xX0luVF9tYXBfaWZmIGYgbDEgeSBpbiB4IGluXG4gICAgbGV0IGgwID1cbiAgICAgIHggKGZ1biB5IC0+IHkgOjogW10pIChwcmVtc19JbXBfUiAocG9zX3RvcF9pbXBzIGwwKSAobCwgbDApKSBwcmVtcyBoXG4gICAgaW5cbiAgICBsZXQgQ29xX2V4aXN0VCAoeDAsIHApID0gaDAgaW5cbiAgICBsZXQgKF8sIGkpID0gcCBpbiBjb3FfSW1wUl9oZWxwMSB4MCAobCwgbDApIGkpKSkpXG4iLCJvcGVuIENNTF9TeW50YXhcbm9wZW4gRGF0YXR5cGVzXG5vcGVuIEtTX2NhbGNcbm9wZW4gS1NfdGVybWluYXRpb25fSW1wUlxub3BlbiBLU190ZXJtaW5hdGlvbl9wcmVsaW1zXG5vcGVuIExpc3Rcbm9wZW4gTGlzdF9sZW1tYXNUXG5vcGVuIFNwZWNpZlxub3BlbiBHZW5UXG5vcGVuIExpc3RfbGVtc1xuXG50eXBlIF9fID0gT2JqLnRcbmxldCBfXyA9IGxldCByZWMgZiBfID0gT2JqLnJlcHIgZiBpbiBPYmoucmVwciBmXG5cbigqKiB2YWwgcHJlbXNfSW1wX0wgOlxuICAgIChjb3FfTVByb3BGICogbmF0KSBsaXN0IC0+IGNvcV9TZXEgLT4gY29xX1NlcSBsaXN0IGxpc3QgKiopXG5cbmxldCByZWMgcHJlbXNfSW1wX0wgbCBzID1cbiAgbWF0Y2ggbCB3aXRoXG4gIHwgW10gLT4gW11cbiAgfCBwIDo6IHQgLT5cbiAgICBsZXQgKGMsIG4pID0gcCBpblxuICAgIChtYXRjaCBuIHdpdGhcbiAgICAgfCBPIC0+IHByZW1zX0ltcF9MIHQgc1xuICAgICB8IFMgbSAtPlxuICAgICAgIChtYXRjaCBjIHdpdGhcbiAgICAgICAgfCBJbXAgKGEsIGIpIC0+XG4gICAgICAgICAgYXBwXG4gICAgICAgICAgICAoZmxhdHRlbl9saXN0XG4gICAgICAgICAgICAgIChtYXAgKGZ1biB5IC0+XG4gICAgICAgICAgICAgICAgbWFwIChmdW4geiAtPiB6IDo6ICh5IDo6IFtdKSlcbiAgICAgICAgICAgICAgICAgIChsaXN0SW5zZXJ0c0xfU2Vxc1xuICAgICAgICAgICAgICAgICAgICAoYXBwIChmc3QgKG50aF9zcGxpdCBtIChyZW1vdmVfbnRoIChTIG0pIGMgKGZzdCBzKSkpKVxuICAgICAgICAgICAgICAgICAgICAgIChzbmQgKG50aF9zcGxpdCBtIChyZW1vdmVfbnRoIChTIG0pIGMgKGZzdCBzKSkpKSlcbiAgICAgICAgICAgICAgICAgICAgKHNuZCBzKSBhKSlcbiAgICAgICAgICAgICAgICAoKChhcHAgKGZzdCAobnRoX3NwbGl0IG0gKHJlbW92ZV9udGggKFMgbSkgYyAoZnN0IHMpKSkpXG4gICAgICAgICAgICAgICAgICAgIChiIDo6IChzbmQgKG50aF9zcGxpdCBtIChyZW1vdmVfbnRoIChTIG0pIGMgKGZzdCBzKSkpKSkpLFxuICAgICAgICAgICAgICAgIChzbmQgcykpIDo6IFtdKSkpIChwcmVtc19JbXBfTCB0IHMpXG4gICAgICAgIHwgXyAtPiBwcmVtc19JbXBfTCB0IHMpKVxuXG4oKiogdmFsIGNvcV9JbXBMX2hlbHAwMDIgOlxuICAgIGNvcV9NUHJvcEYgbGlzdCAtPiBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgbGlzdFxuICAgIC0+IGNvcV9NUHJvcEYgLT4gY29xX01Qcm9wRiAtPiAoY29xX01Qcm9wRiBsaXN0ICogY29xX01Qcm9wRiBsaXN0KSBsaXN0XG4gICAgY29xX0luVCAqKilcblxubGV0IGNvcV9JbXBMX2hlbHAwMDIgX1VVMDM5M18wIF9VVTAzOTNfMSBfVVUwMzk0XzAgX1VVMDM5NF8xIGEgYiA9XG4gIGNvcV9JblRfdHJhbnNfZmxhdHRlbl9saXN0XG4gICAgKG1hcCAoZnVuIHkgLT5cbiAgICAgIG1hcCAoZnVuIHogLT4geSA6OiAoeiA6OiBbXSkpICgoKGFwcCBfVVUwMzkzXzAgKGIgOjogX1VVMDM5M18xKSksXG4gICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpIDo6IFtdKSlcbiAgICAgIChsaXN0SW5zZXJ0c0xfU2VxcyAoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSlcbiAgICAgICAgYSkpXG4gICAgKG1hcCAoZnVuIHogLT4gKChhcHAgX1VVMDM5M18wIF9VVTAzOTNfMSksXG4gICAgICAoYXBwIF9VVTAzOTRfMCAoYSA6OiBfVVUwMzk0XzEpKSkgOjogKHogOjogW10pKVxuICAgICAgKCgoYXBwIF9VVTAzOTNfMCAoYiA6OiBfVVUwMzkzXzEpKSwgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkgOjogW10pKVxuICAgICgoKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKSxcbiAgICAoYXBwIF9VVTAzOTRfMCAoYSA6OiBfVVUwMzk0XzEpKSkgOjogKCgoYXBwIF9VVTAzOTNfMCAoYiA6OiBfVVUwMzkzXzEpKSxcbiAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSA6OiBbXSkpXG4gICAgKGxldCBwID1cbiAgICAgICBjb3FfSW5UX21hcF9pZmYgKGZ1biB6IC0+ICgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLFxuICAgICAgICAgKGFwcCBfVVUwMzk0XzAgKGEgOjogX1VVMDM5NF8xKSkpIDo6ICh6IDo6IFtdKSlcbiAgICAgICAgICgoKGFwcCBfVVUwMzkzXzAgKGIgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSA6OiBbXSkgKCgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLFxuICAgICAgICAgKGFwcCBfVVUwMzk0XzAgKGEgOjogX1VVMDM5NF8xKSkpIDo6ICgoKGFwcCBfVVUwMzkzXzBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGIgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSA6OiBbXSkpXG4gICAgIGluXG4gICAgIGxldCAoXywgaSkgPSBwIGluXG4gICAgIGkgKENvcV9leGlzdFQgKCgoYXBwIF9VVTAzOTNfMCAoYiA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSwgKF9fLFxuICAgICAgIChjb3FfSW5UX2VxICgoYXBwIF9VVTAzOTNfMCAoYiA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpIFtdKSkpKSlcbiAgICAobGV0IHAgPVxuICAgICAgIGNvcV9JblRfbWFwX2lmZiAoZnVuIHkgLT5cbiAgICAgICAgIG1hcCAoZnVuIHogLT4geSA6OiAoeiA6OiBbXSkpICgoKGFwcCBfVVUwMzkzXzAgKGIgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpIDo6IFtdKSlcbiAgICAgICAgIChsaXN0SW5zZXJ0c0xfU2VxcyAoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpXG4gICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkgYSlcbiAgICAgICAgIChtYXAgKGZ1biB6IC0+ICgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLFxuICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCAoYSA6OiBfVVUwMzk0XzEpKSkgOjogKHogOjogW10pKVxuICAgICAgICAgICAoKChhcHAgX1VVMDM5M18wIChiIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSA6OiBbXSkpXG4gICAgIGluXG4gICAgIGxldCAoXywgaSkgPSBwIGluXG4gICAgIGkgKENvcV9leGlzdFQgKCgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLFxuICAgICAgIChhcHAgX1VVMDM5NF8wIChhIDo6IF9VVTAzOTRfMSkpKSwgKF9fLFxuICAgICAgIChsZXQgcDAgPVxuICAgICAgICAgIGNvcV9JblRfbWFwX2lmZiAoZnVuIHkgLT4gKChhcHAgX1VVMDM5M18wIF9VVTAzOTNfMSksIHkpKVxuICAgICAgICAgICAgKGxpc3RJbnNlcnRzIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkgYSlcbiAgICAgICAgICAgICgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLCAoYXBwIF9VVTAzOTRfMCAoYSA6OiBfVVUwMzk0XzEpKSlcbiAgICAgICAgaW5cbiAgICAgICAgbGV0IChfLCBpMCkgPSBwMCBpblxuICAgICAgICBpMCAoQ29xX2V4aXN0VCAoKGFwcCBfVVUwMzk0XzAgKGEgOjogX1VVMDM5NF8xKSksIChfXyxcbiAgICAgICAgICAobGV0IHAxID1cbiAgICAgICAgICAgICBjb3FfSW5UX21hcF9pZmYgKGZ1biB5IC0+IGFwcCAoZnN0IHkpIChhIDo6IChzbmQgeSkpKVxuICAgICAgICAgICAgICAgKHByb2oxX3NpZ1QyIChsaXN0X29mX3NwbGl0cyAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSlcbiAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIChhIDo6IF9VVTAzOTRfMSkpXG4gICAgICAgICAgIGluXG4gICAgICAgICAgIGxldCAoXywgaTEpID0gcDEgaW5cbiAgICAgICAgICAgaTEgKENvcV9leGlzdFQgKChfVVUwMzk0XzAsIF9VVTAzOTRfMSksIChfXyxcbiAgICAgICAgICAgICAobGV0IHMgPSBsaXN0X29mX3NwbGl0cyAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpIGluXG4gICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4LCBfKSA9IHMgaW5cbiAgICAgICAgICAgICAgY29xX0luX0luVF9zZXFzIChfVVUwMzk0XzAsIF9VVTAzOTRfMSkgeCkpKSkpKSkpKSkpKSlcblxuKCoqIHZhbCBjb3FfSW1wTF9oZWxwMDIgOlxuICAgIGNvcV9NUHJvcEYgbGlzdCAtPiBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgbGlzdFxuICAgIC0+IGNvcV9NUHJvcEYgLT4gY29xX01Qcm9wRiAtPiAoY29xX01Qcm9wRiAqIG5hdCkgbGlzdCAtPiBuYXQgLT5cbiAgICBjb3FfSW1wTFJ1bGUgLT4gKGNvcV9NUHJvcEYgbGlzdCAqIGNvcV9NUHJvcEYgbGlzdCkgbGlzdCBjb3FfSW5UICoqKVxuXG5sZXQgcmVjIGNvcV9JbXBMX2hlbHAwMiBfVVUwMzkzXzAgX1VVMDM5M18xIF9VVTAzOTRfMCBfVVUwMzk0XzEgYSBiIGwgbiB4ID1cbiAgbWF0Y2ggbCB3aXRoXG4gIHwgW10gLT4gYXNzZXJ0IGZhbHNlICgqIGFic3VyZCBjYXNlICopXG4gIHwgeSA6OiBsMCAtPlxuICAgIGxldCAobSwgbjApID0geSBpblxuICAgIChtYXRjaCBtIHdpdGhcbiAgICAgfCBJbXAgKG0wLCBtMSkgLT5cbiAgICAgICBsZXQgaDEgPVxuICAgICAgICAgY29xX0luX0luVF9wYWlyIChJbXAgKGEsIGIpKSAoUyBuKSAoKChJbXAgKG0wLCBtMSkpLCBuMCkgOjogbDApXG4gICAgICAgaW5cbiAgICAgICAobWF0Y2ggaDEgd2l0aFxuICAgICAgICB8IEluVF9lcScgKF8sIF8pIC0+XG4gICAgICAgICAgbGV0IGkgPSBjb3FfSW1wTF9oZWxwMDAyIF9VVTAzOTNfMCBfVVUwMzkzXzEgX1VVMDM5NF8wIF9VVTAzOTRfMSBhIGJcbiAgICAgICAgICBpblxuICAgICAgICAgIGNvcV9JblRfb3JfYXBwXG4gICAgICAgICAgICAoZmxhdHRlbl9saXN0XG4gICAgICAgICAgICAgIChtYXAgKGZ1biB5MCAtPlxuICAgICAgICAgICAgICAgIG1hcCAoZnVuIHogLT4geiA6OiAoeTAgOjogW10pKVxuICAgICAgICAgICAgICAgICAgKGxpc3RJbnNlcnRzTF9TZXFzXG4gICAgICAgICAgICAgICAgICAgIChhcHBcbiAgICAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IChsZW5ndGggX1VVMDM5M18wKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyAobGVuZ3RoIF9VVTAzOTNfMCkpIChJbXAgKGEsIGIpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoYXBwIF9VVTAzOTNfMCAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkpKSkpXG4gICAgICAgICAgICAgICAgICAgICAgKHNuZFxuICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCAobGVuZ3RoIF9VVTAzOTNfMClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgKGxlbmd0aCBfVVUwMzkzXzApKSAoSW1wIChhLCBiKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKGFwcCBfVVUwMzkzXzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpKSkpKSlcbiAgICAgICAgICAgICAgICAgICAgKHNuZCAoKGFwcCBfVVUwMzkzXzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSkgYSkpXG4gICAgICAgICAgICAgICAgKCgoYXBwXG4gICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IChsZW5ndGggX1VVMDM5M18wKVxuICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgKGxlbmd0aCBfVVUwMzkzXzApKSAoSW1wIChhLCBiKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGZzdCAoKGFwcCBfVVUwMzkzXzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSkpKSlcbiAgICAgICAgICAgICAgICAgICAgKGIgOjogKHNuZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgKGxlbmd0aCBfVVUwMzkzXzApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyAobGVuZ3RoIF9VVTAzOTNfMCkpIChJbXAgKGEsIGIpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChhcHAgX1VVMDM5M18wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkpKSkpKSksXG4gICAgICAgICAgICAgICAgKHNuZCAoKGFwcCBfVVUwMzkzXzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpKSkgOjogW10pKSlcbiAgICAgICAgICAgIChsZXQgcmVjIHByZW1zX0ltcF9MMCBsMSBzID1cbiAgICAgICAgICAgICAgIG1hdGNoIGwxIHdpdGhcbiAgICAgICAgICAgICAgIHwgW10gLT4gW11cbiAgICAgICAgICAgICAgIHwgcCA6OiB0IC0+XG4gICAgICAgICAgICAgICAgIGxldCAoYywgbjEpID0gcCBpblxuICAgICAgICAgICAgICAgICAobWF0Y2ggbjEgd2l0aFxuICAgICAgICAgICAgICAgICAgfCBPIC0+IHByZW1zX0ltcF9MMCB0IHNcbiAgICAgICAgICAgICAgICAgIHwgUyBtMiAtPlxuICAgICAgICAgICAgICAgICAgICAobWF0Y2ggYyB3aXRoXG4gICAgICAgICAgICAgICAgICAgICB8IEltcCAoYTAsIGIwKSAtPlxuICAgICAgICAgICAgICAgICAgICAgICBhcHBcbiAgICAgICAgICAgICAgICAgICAgICAgICAoZmxhdHRlbl9saXN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAobWFwIChmdW4geTAgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwIChmdW4geiAtPiB6IDo6ICh5MCA6OiBbXSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxpc3RJbnNlcnRzTF9TZXFzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXBwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG0yXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyBtMikgYyAoZnN0IHMpKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG0yXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyBtMikgYyAoZnN0IHMpKSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNuZCBzKSBhMCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoKGFwcFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG0yXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgbTIpIGMgKGZzdCBzKSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGIwIDo6IChzbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgbTIpIGMgKGZzdCBzKSkpKSkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc25kIHMpKSA6OiBbXSkpKSAocHJlbXNfSW1wX0wwIHQgcylcbiAgICAgICAgICAgICAgICAgICAgIHwgXyAtPiBwcmVtc19JbXBfTDAgdCBzKSlcbiAgICAgICAgICAgICBpbiBwcmVtc19JbXBfTDAgbDAgKChhcHAgX1VVMDM5M18wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSkgKCgoYXBwIF9VVTAzOTNfMCBfVVUwMzkzXzEpLFxuICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgKGEgOjogX1VVMDM5NF8xKSkpIDo6ICgoKGFwcCBfVVUwMzkzXzBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGIgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSA6OiBbXSkpIChDb3FfaW5sXG4gICAgICAgICAgICAoY29xX0luVF90cmFuc19mbGF0dGVuX2xpc3RcbiAgICAgICAgICAgICAgKG1hcCAoZnVuIHkwIC0+XG4gICAgICAgICAgICAgICAgbWFwIChmdW4geiAtPiB6IDo6ICh5MCA6OiBbXSkpXG4gICAgICAgICAgICAgICAgICAobGlzdEluc2VydHNMX1NlcXNcbiAgICAgICAgICAgICAgICAgICAgKGFwcFxuICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgKGxlbmd0aCBfVVUwMzkzXzApXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChyZW1vdmVfbnRoIChTIChsZW5ndGggX1VVMDM5M18wKSkgKEltcCAoYSwgYikpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChhcHAgX1VVMDM5M18wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSkpKSlcbiAgICAgICAgICAgICAgICAgICAgICAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IChsZW5ndGggX1VVMDM5M18wKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyAobGVuZ3RoIF9VVTAzOTNfMCkpIChJbXAgKGEsIGIpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoYXBwIF9VVTAzOTNfMCAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkpKSkpKVxuICAgICAgICAgICAgICAgICAgICAoc25kICgoYXBwIF9VVTAzOTNfMCAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgICAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpKSBhKSlcbiAgICAgICAgICAgICAgICAoKChhcHBcbiAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgKGxlbmd0aCBfVVUwMzkzXzApXG4gICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyAobGVuZ3RoIF9VVTAzOTNfMCkpIChJbXAgKGEsIGIpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAoZnN0ICgoYXBwIF9VVTAzOTNfMCAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpKSkpKVxuICAgICAgICAgICAgICAgICAgICAoYiA6OiAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCAobGVuZ3RoIF9VVTAzOTNfMClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZW1vdmVfbnRoIChTIChsZW5ndGggX1VVMDM5M18wKSkgKEltcCAoYSwgYikpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKGFwcCBfVVUwMzkzXzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSkpKSkpKSxcbiAgICAgICAgICAgICAgICAoc25kICgoYXBwIF9VVTAzOTNfMCAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkpKSA6OiBbXSkpXG4gICAgICAgICAgICAgIChmbGF0dGVuX2xpc3RcbiAgICAgICAgICAgICAgICAobWFwIChmdW4geTAgLT4gKHkwIDo6ICgoKGFwcCBfVVUwMzkzXzAgKGIgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSA6OiBbXSkpIDo6IFtdKVxuICAgICAgICAgICAgICAgICAgKGxpc3RJbnNlcnRzTF9TZXFzIChhcHAgX1VVMDM5M18wIF9VVTAzOTNfMSlcbiAgICAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSBhKSkpXG4gICAgICAgICAgICAgICgoKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKSxcbiAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgKGEgOjogX1VVMDM5NF8xKSkpIDo6ICgoKGFwcCBfVVUwMzkzXzBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYiA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkgOjogW10pKSBpXG4gICAgICAgICAgICAgIChsZXQgZiA9IGZ1biB5MCAtPlxuICAgICAgICAgICAgICAgICBtYXAgKGZ1biB6IC0+IHogOjogKHkwIDo6IFtdKSlcbiAgICAgICAgICAgICAgICAgICAobGlzdEluc2VydHNMX1NlcXNcbiAgICAgICAgICAgICAgICAgICAgIChhcHBcbiAgICAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgKGxlbmd0aCBfVVUwMzkzXzApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyAobGVuZ3RoIF9VVTAzOTNfMCkpIChJbXAgKGEsIGIpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChhcHAgX1VVMDM5M18wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkpKSkpXG4gICAgICAgICAgICAgICAgICAgICAgIChzbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IChsZW5ndGggX1VVMDM5M18wKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgKGxlbmd0aCBfVVUwMzkzXzApKSAoSW1wIChhLCBiKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoYXBwIF9VVTAzOTNfMCAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpKSkpKSlcbiAgICAgICAgICAgICAgICAgICAgIChzbmQgKChhcHAgX1VVMDM5M18wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpKSBhKVxuICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgIGxldCBsMSA9XG4gICAgICAgICAgICAgICAgICgoYXBwXG4gICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IChsZW5ndGggX1VVMDM5M18wKVxuICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgKGxlbmd0aCBfVVUwMzkzXzApKSAoSW1wIChhLCBiKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGZzdCAoKGFwcCBfVVUwMzkzXzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpKSkpKSlcbiAgICAgICAgICAgICAgICAgICAgKGIgOjogKHNuZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgKGxlbmd0aCBfVVUwMzkzXzApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyAobGVuZ3RoIF9VVTAzOTNfMCkpIChJbXAgKGEsIGIpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChhcHAgX1VVMDM5M18wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkpKSkpKSksXG4gICAgICAgICAgICAgICAgIChzbmQgKChhcHAgX1VVMDM5M18wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkpKSA6OiBbXVxuICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgIGxldCB5MCA9XG4gICAgICAgICAgICAgICAgIGZsYXR0ZW5fbGlzdFxuICAgICAgICAgICAgICAgICAgIChtYXAgKGZ1biB5MCAtPiAoeTAgOjogKCgoYXBwIF9VVTAzOTNfMCAoYiA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpIDo6IFtdKSkgOjogW10pXG4gICAgICAgICAgICAgICAgICAgICAobGlzdEluc2VydHNMX1NlcXMgKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKVxuICAgICAgICAgICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpIGEpKVxuICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgIGxldCAoXywgeDApID0gY29xX0luVF9tYXBfaWZmIGYgbDEgeTAgaW5cbiAgICAgICAgICAgICAgIHgwIChDb3FfZXhpc3RUICgoKGFwcCBfVVUwMzkzXzAgKGIgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpLCAoX18sXG4gICAgICAgICAgICAgICAgIChsZXQgcyA9IGVxX2RlY19mb3JtIChJbXAgKGEsIGIpKSAoSW1wIChhLCBiKSkgaW5cbiAgICAgICAgICAgICAgICAgIGlmIHNcbiAgICAgICAgICAgICAgICAgIHRoZW4gY29xX0luVF9lcSAoKGFwcCBfVVUwMzkzXzAgKGIgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkgW11cbiAgICAgICAgICAgICAgICAgIGVsc2UgYXNzZXJ0IGZhbHNlICgqIGFic3VyZCBjYXNlICopKSkpKSkpKVxuICAgICAgICB8IEluVF9jb25zIChfLCBfLCBfKSAtPlxuICAgICAgICAgIGxldCBpID1cbiAgICAgICAgICAgIGNvcV9JbXBMX2hlbHAwMiBfVVUwMzkzXzAgX1VVMDM5M18xIF9VVTAzOTRfMCBfVVUwMzk0XzEgYSBiIGwwXG4gICAgICAgICAgICAgIChsZW5ndGggX1VVMDM5M18wKSB4XG4gICAgICAgICAgaW5cbiAgICAgICAgICAobWF0Y2ggbjAgd2l0aFxuICAgICAgICAgICB8IE8gLT4gaVxuICAgICAgICAgICB8IFMgbjEgLT5cbiAgICAgICAgICAgICBjb3FfSW5UX29yX2FwcFxuICAgICAgICAgICAgICAgKGFwcFxuICAgICAgICAgICAgICAgICAobWFwIChmdW4geiAtPlxuICAgICAgICAgICAgICAgICAgIHogOjogKCgoYXBwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBuMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggbjEgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBPIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBhcHAgX1VVMDM5M18wICgoSW1wIChhLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiKSkgOjogX1VVMDM5M18xKSB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGIwIDo6IHRsIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGVxX2RlY19mb3JtIChJbXAgKG0wLCBtMSkpIGIwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gdGxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBiMCA6OiB0bClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUyBfIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBhcHAgX1VVMDM5M18wICgoSW1wIChhLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiKSkgOjogX1VVMDM5M18xKSB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGIwIDo6IHRsIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGIwIDo6IChyZW1vdmVfbnRoIG4xIChJbXAgKG0wLCBtMSkpIHRsKSkpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAobTEgOjogKHNuZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBuMSB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBPIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggYXBwIF9VVTAzOTNfMCAoKEltcCAoYSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGIpKSA6OiBfVVUwMzkzXzEpIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBiMCA6OiB0bCAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgZXFfZGVjX2Zvcm0gKEltcCAobTAsIG0xKSkgYjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gdGxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgYjAgOjogdGwpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTIF8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBhcHAgX1VVMDM5M18wICgoSW1wIChhLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYikpIDo6IF9VVTAzOTNfMSkgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgW10gLT4gW11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGIwIDo6IHRsIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiMCA6OiAocmVtb3ZlX250aCBuMSAoSW1wIChtMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbTEpKSB0bCkpKSkpKSksXG4gICAgICAgICAgICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkgOjogW10pKVxuICAgICAgICAgICAgICAgICAgIChsaXN0SW5zZXJ0c0xfU2Vxc1xuICAgICAgICAgICAgICAgICAgICAgKGFwcFxuICAgICAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBuMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIG4xIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IE8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBhcHAgX1VVMDM5M18wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5M18xKSB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBbXSAtPiBbXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgYjAgOjogdGwgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGVxX2RlY19mb3JtIChJbXAgKG0wLCBtMSkpIGIwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIHRsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGIwIDo6IHRsKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUyBfIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggYXBwIF9VVTAzOTNfMCAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTNfMSkgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgW10gLT4gW11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGIwIDo6IHRsIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiMCA6OiAocmVtb3ZlX250aCBuMSAoSW1wIChtMCwgbTEpKSB0bCkpKSkpXG4gICAgICAgICAgICAgICAgICAgICAgIChzbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG4xXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggbjEgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgTyAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIGFwcCBfVVUwMzkzXzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzkzXzEpIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBiMCA6OiB0bCAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgZXFfZGVjX2Zvcm0gKEltcCAobTAsIG0xKSkgYjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gdGxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgYjAgOjogdGwpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTIF8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBhcHAgX1VVMDM5M18wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5M18xKSB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBbXSAtPiBbXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgYjAgOjogdGwgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGIwIDo6IChyZW1vdmVfbnRoIG4xIChJbXAgKG0wLCBtMSkpIHRsKSkpKSkpXG4gICAgICAgICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCBfVVUwMzk0XzEpIG0wKSkgW10pXG4gICAgICAgICAgICAgICAocHJlbXNfSW1wX0wgbDAgKChhcHAgX1VVMDM5M18wICgoSW1wIChhLCBiKSkgOjogX1VVMDM5M18xKSksXG4gICAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpKSAoKChhcHAgX1VVMDM5M18wIF9VVTAzOTNfMSksXG4gICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCAoYSA6OiBfVVUwMzk0XzEpKSkgOjogKCgoYXBwIF9VVTAzOTNfMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYiA6OiBfVVUwMzkzXzEpKSxcbiAgICAgICAgICAgICAgIChhcHAgX1VVMDM5NF8wIF9VVTAzOTRfMSkpIDo6IFtdKSkgKENvcV9pbnIgaSkpKVxuICAgICB8IHgwIC0+XG4gICAgICAgbGV0IGgxID1cbiAgICAgICAgIGNvcV9Jbl9JblRfcGFpciAoSW1wIChhLCBiKSkgKFMgKGxlbmd0aCBfVVUwMzkzXzApKSAoKHgwLCBuMCkgOjogbDApXG4gICAgICAgaW5cbiAgICAgICAobWF0Y2ggaDEgd2l0aFxuICAgICAgICB8IEluVF9lcScgKF8sIF8pIC0+IGFzc2VydCBmYWxzZSAoKiBhYnN1cmQgY2FzZSAqKVxuICAgICAgICB8IEluVF9jb25zIChfLCBfLCBfKSAtPlxuICAgICAgICAgIGNvcV9JbXBMX2hlbHAwMiBfVVUwMzkzXzAgX1VVMDM5M18xIF9VVTAzOTRfMCBfVVUwMzk0XzEgYSBiIGwwXG4gICAgICAgICAgICAobGVuZ3RoIF9VVTAzOTNfMCkgeCkpXG5cbigqKiB2YWwgY29xX0ltcExfaGVscDIgOlxuICAgIGNvcV9TZXEgLT4gY29xX1NlcSAtPiBjb3FfU2VxIC0+IGNvcV9JbXBMUnVsZSAtPiBjb3FfU2VxIGxpc3QgY29xX0luVCAqKilcblxubGV0IGNvcV9JbXBMX2hlbHAyIF8gXyBfIHggPSBtYXRjaCB4IHdpdGhcbnwgSW1wTFJ1bGVfSSAoYSwgYiwgX1VVMDM5M18wLCBfVVUwMzkzXzEsIF9VVTAzOTRfMCwgX1VVMDM5NF8xKSAtPlxuICBjb3FfSW1wTF9oZWxwMDIgX1VVMDM5M18wIF9VVTAzOTNfMSBfVVUwMzk0XzAgX1VVMDM5NF8xIGEgYlxuICAgIChwb3NfdG9wX2ltcHMgKGFwcCBfVVUwMzkzXzAgKChJbXAgKGEsIGIpKSA6OiBfVVUwMzkzXzEpKSlcbiAgICAobGVuZ3RoIF9VVTAzOTNfMCkgeFxuXG4oKiogdmFsIGNvcV9JbXBMX2hlbHAwMSA6XG4gICAgY29xX1NlcSBsaXN0IC0+IGNvcV9TZXEgLT4gKGNvcV9NUHJvcEYgKiBuYXQpIGxpc3QgLT4gY29xX1NlcSBsaXN0XG4gICAgY29xX0luVCAtPiAobmF0LCAoY29xX1NlcSwgKGNvcV9TZXEsIChjb3FfTVByb3BGLCAoY29xX01Qcm9wRixcbiAgICAoY29xX01Qcm9wRiBsaXN0LCAoY29xX01Qcm9wRiBsaXN0LCAoY29xX01Qcm9wRiBsaXN0LCAoY29xX01Qcm9wRiBsaXN0LFxuICAgIF9fKSBzaWdUKSBzaWdUKSBzaWdUKSBzaWdUKSBzaWdUKSBzaWdUKSBzaWdUKSBzaWdUKSBzaWdUICoqKVxuXG5sZXQgY29xX0ltcExfaGVscDAxIHByZW1zIHMgbDEgPVxuICBsZXQgKGwsIGwwKSA9IHMgaW5cbiAgbGV0IHJlYyBmIGwyIHggPVxuICAgIG1hdGNoIGwyIHdpdGhcbiAgICB8IFtdIC0+IGFzc2VydCBmYWxzZSAoKiBhYnN1cmQgY2FzZSAqKVxuICAgIHwgeSA6OiBsMyAtPlxuICAgICAgbGV0IChtLCBuKSA9IHkgaW5cbiAgICAgIChtYXRjaCBtIHdpdGhcbiAgICAgICB8IEltcCAobTAsIG0xKSAtPlxuICAgICAgICAgKG1hdGNoIG4gd2l0aFxuICAgICAgICAgIHwgTyAtPlxuICAgICAgICAgICAgbGV0IHMwID0gZiBsMyB4IGluXG4gICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDAsIHMxKSA9IHMwIGluXG4gICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDEsIHMyKSA9IHMxIGluXG4gICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDIsIHMzKSA9IHMyIGluXG4gICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDMsIHM0KSA9IHMzIGluXG4gICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDQsIHM1KSA9IHM0IGluXG4gICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDUsIHM2KSA9IHM1IGluXG4gICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDYsIHM3KSA9IHM2IGluXG4gICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDcsIHM4KSA9IHM3IGluXG4gICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDgsIF8pID0gczggaW5cbiAgICAgICAgICAgIENvcV9leGlzdFQgKHgwLCAoQ29xX2V4aXN0VCAoeDEsIChDb3FfZXhpc3RUICh4MiwgKENvcV9leGlzdFRcbiAgICAgICAgICAgICh4MywgKENvcV9leGlzdFQgKHg0LCAoQ29xX2V4aXN0VCAoeDUsIChDb3FfZXhpc3RUICh4NixcbiAgICAgICAgICAgIChDb3FfZXhpc3RUICh4NywgKENvcV9leGlzdFQgKHg4LCBfXykpKSkpKSkpKSkpKSkpKSkpXG4gICAgICAgICAgfCBTIG4wIC0+XG4gICAgICAgICAgICBsZXQgeDAgPVxuICAgICAgICAgICAgICBjb3FfSW5UX2FwcF9vclxuICAgICAgICAgICAgICAgIChmbGF0dGVuX2xpc3RcbiAgICAgICAgICAgICAgICAgIChtYXAgKGZ1biB5MCAtPlxuICAgICAgICAgICAgICAgICAgICBtYXAgKGZ1biB6IC0+IHogOjogKHkwIDo6IFtdKSlcbiAgICAgICAgICAgICAgICAgICAgICAobGlzdEluc2VydHNMX1NlcXNcbiAgICAgICAgICAgICAgICAgICAgICAgIChhcHBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZW1vdmVfbnRoIChTIG4wKSAoSW1wIChtMCwgbTEpKSAoZnN0IChsLCBsMCkpKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChzbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG4wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSkgKGZzdCAobCwgbDApKSkpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIChzbmQgKGwsIGwwKSkgbTApKVxuICAgICAgICAgICAgICAgICAgICAoKChhcHBcbiAgICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZW1vdmVfbnRoIChTIG4wKSAoSW1wIChtMCwgbTEpKSAoZnN0IChsLCBsMCkpKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAobTEgOjogKHNuZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZnN0IChsLCBsMCkpKSkpKSksXG4gICAgICAgICAgICAgICAgICAgIChzbmQgKGwsIGwwKSkpIDo6IFtdKSkpXG4gICAgICAgICAgICAgICAgKGxldCByZWMgcHJlbXNfSW1wX0wwIGw0IHMwID1cbiAgICAgICAgICAgICAgICAgICBtYXRjaCBsNCB3aXRoXG4gICAgICAgICAgICAgICAgICAgfCBbXSAtPiBbXVxuICAgICAgICAgICAgICAgICAgIHwgcCA6OiB0IC0+XG4gICAgICAgICAgICAgICAgICAgICBsZXQgKGMsIG4xKSA9IHAgaW5cbiAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBuMSB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgfCBPIC0+IHByZW1zX0ltcF9MMCB0IHMwXG4gICAgICAgICAgICAgICAgICAgICAgfCBTIG0yIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggYyB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgfCBJbXAgKGEsIGIpIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZsYXR0ZW5fbGlzdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXAgKGZ1biB5MCAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwIChmdW4geiAtPiB6IDo6ICh5MCA6OiBbXSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsaXN0SW5zZXJ0c0xfU2Vxc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhcHBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBtMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZW1vdmVfbnRoIChTIG0yKSBjIChmc3QgczApKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyBtMikgYyAoZnN0IHMwKSkpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc25kIHMwKSBhKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoKGFwcFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbTJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgbTIpIGMgKGZzdCBzMCkpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYiA6OiAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG0yXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZW1vdmVfbnRoIChTIG0yKSBjIChmc3QgczApKSkpKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc25kIHMwKSkgOjogW10pKSkgKHByZW1zX0ltcF9MMCB0IHMwKVxuICAgICAgICAgICAgICAgICAgICAgICAgIHwgXyAtPiBwcmVtc19JbXBfTDAgdCBzMCkpXG4gICAgICAgICAgICAgICAgIGluIHByZW1zX0ltcF9MMCBsMyAobCwgbDApKSBwcmVtcyB4XG4gICAgICAgICAgICBpblxuICAgICAgICAgICAgKG1hdGNoIHgwIHdpdGhcbiAgICAgICAgICAgICB8IENvcV9pbmwgaSAtPlxuICAgICAgICAgICAgICAgbGV0IGkwID1cbiAgICAgICAgICAgICAgICAgY29xX0luVF9mbGF0dGVuX2xpc3RfSW5UX2VsZW1cbiAgICAgICAgICAgICAgICAgICAobWFwIChmdW4geTAgLT5cbiAgICAgICAgICAgICAgICAgICAgIG1hcCAoZnVuIHogLT4geiA6OiAoeTAgOjogW10pKVxuICAgICAgICAgICAgICAgICAgICAgICAobGlzdEluc2VydHNMX1NlcXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAoYXBwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSkgbCkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNuZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG4wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgbjApIChJbXAgKG0wLCBtMSkpIGwpKSkpIGwwIG0wKSlcbiAgICAgICAgICAgICAgICAgICAgICgoKGFwcFxuICAgICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjAgKHJlbW92ZV9udGggKFMgbjApIChJbXAgKG0wLCBtMSkpIGwpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAobTEgOjogKHNuZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZW1vdmVfbnRoIChTIG4wKSAoSW1wIChtMCwgbTEpKSBsKSkpKSksXG4gICAgICAgICAgICAgICAgICAgICBsMCkgOjogW10pKSBwcmVtcyBpXG4gICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgxLCBwKSA9IGkwIGluXG4gICAgICAgICAgICAgICBsZXQgKGkxLCBpMikgPSBwIGluXG4gICAgICAgICAgICAgICBsZXQgeDIgPSBmdW4gZjAgbDQgeTAgLT5cbiAgICAgICAgICAgICAgICAgbGV0ICh4MiwgXykgPSBjb3FfSW5UX21hcF9pZmYgZjAgbDQgeTAgaW4geDJcbiAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICBsZXQgaTMgPVxuICAgICAgICAgICAgICAgICB4MiAoZnVuIHkwIC0+XG4gICAgICAgICAgICAgICAgICAgbWFwIChmdW4geiAtPiB6IDo6ICh5MCA6OiBbXSkpXG4gICAgICAgICAgICAgICAgICAgICAobGlzdEluc2VydHNMX1NlcXNcbiAgICAgICAgICAgICAgICAgICAgICAgKGFwcFxuICAgICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjAgKHJlbW92ZV9udGggKFMgbjApIChJbXAgKG0wLCBtMSkpIGwpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG4wIChyZW1vdmVfbnRoIChTIG4wKSAoSW1wIChtMCwgbTEpKSBsKSkpKVxuICAgICAgICAgICAgICAgICAgICAgICBsMCBtMCkpXG4gICAgICAgICAgICAgICAgICAgKCgoYXBwXG4gICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG4wIChyZW1vdmVfbnRoIChTIG4wKSAoSW1wIChtMCwgbTEpKSBsKSkpXG4gICAgICAgICAgICAgICAgICAgICAgIChtMSA6OiAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSkgbCkpKSkpLFxuICAgICAgICAgICAgICAgICAgIGwwKSA6OiBbXSkgeDEgaTJcbiAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoXywgcDApID0gaTMgaW5cbiAgICAgICAgICAgICAgIGxldCAoXywgaTQpID0gcDAgaW5cbiAgICAgICAgICAgICAgIChtYXRjaCBpNCB3aXRoXG4gICAgICAgICAgICAgICAgfCBJblRfZXEnIChfLCBfKSAtPlxuICAgICAgICAgICAgICAgICAgbGV0IHgzID0gZnVuIGYwIGw0IHkwIC0+XG4gICAgICAgICAgICAgICAgICAgIGxldCAoeDMsIF8pID0gY29xX0luVF9tYXBfaWZmIGYwIGw0IHkwIGluIHgzXG4gICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgbGV0IGk1ID1cbiAgICAgICAgICAgICAgICAgICAgeDMgKGZ1biB6IC0+XG4gICAgICAgICAgICAgICAgICAgICAgeiA6OiAoKChhcHBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG4wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBuMCB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IE8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIGwgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBbXSAtPiBbXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBiIDo6IHRsIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGVxX2RlY19mb3JtIChJbXAgKG0wLCBtMSkpIGJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiB0bFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGIgOjogdGwpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFMgXyAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggbCB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGIgOjogdGwgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYiA6OiAocmVtb3ZlX250aCBuMCAoSW1wIChtMCwgbTEpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGwpKSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtMSA6OiAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIG4wIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IE8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBsIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBiIDo6IHRsIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBlcV9kZWNfZm9ybSAoSW1wIChtMCwgbTEpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIHRsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGIgOjogdGwpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTIF8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBsIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBiIDo6IHRsIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiIDo6IChyZW1vdmVfbnRoIG4wIChJbXAgKG0wLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0xKSkgdGwpKSkpKSkpLFxuICAgICAgICAgICAgICAgICAgICAgIGwwKSA6OiBbXSkpXG4gICAgICAgICAgICAgICAgICAgICAgKGxpc3RJbnNlcnRzTF9TZXFzXG4gICAgICAgICAgICAgICAgICAgICAgICAoYXBwXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG4wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSkgbCkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZV9udGggKFMgbjApIChJbXAgKG0wLCBtMSkpIGwpKSkpIGwwIG0wKVxuICAgICAgICAgICAgICAgICAgICAgIHByZW1zIGkxXG4gICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHg0LCBwMSkgPSBpNSBpblxuICAgICAgICAgICAgICAgICAgbGV0IChfLCBpNikgPSBwMSBpblxuICAgICAgICAgICAgICAgICAgbGV0IHg1ID0gZnVuIGYwIGw0IHkwIC0+XG4gICAgICAgICAgICAgICAgICAgIGxldCAoeDUsIF8pID0gY29xX0luVF9tYXBfaWZmIGYwIGw0IHkwIGluIHg1XG4gICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgbGV0IGk3ID1cbiAgICAgICAgICAgICAgICAgICAgeDUgKGZ1biB5MCAtPlxuICAgICAgICAgICAgICAgICAgICAgICgoYXBwXG4gICAgICAgICAgICAgICAgICAgICAgICAgKGZzdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBuMCAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSkgbCkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgIChzbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjAgKHJlbW92ZV9udGggKFMgbjApIChJbXAgKG0wLCBtMSkpIGwpKSkpLFxuICAgICAgICAgICAgICAgICAgICAgIHkwKSkgKGxpc3RJbnNlcnRzIGwwIG0wKSB4NCBpNlxuICAgICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4NiwgcDIpID0gaTcgaW5cbiAgICAgICAgICAgICAgICAgIGxldCAoXywgaTgpID0gcDIgaW5cbiAgICAgICAgICAgICAgICAgIGxldCB4NyA9IGZ1biBmMCBsNCB5MCAtPlxuICAgICAgICAgICAgICAgICAgICBsZXQgKHg3LCBfKSA9IGNvcV9JblRfbWFwX2lmZiBmMCBsNCB5MCBpbiB4N1xuICAgICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgICAgIGxldCBpOSA9XG4gICAgICAgICAgICAgICAgICAgIHg3IChmdW4geTAgLT4gYXBwIChmc3QgeTApIChtMCA6OiAoc25kIHkwKSkpXG4gICAgICAgICAgICAgICAgICAgICAgKHByb2oxX3NpZ1QyIChsaXN0X29mX3NwbGl0cyBsMCkpIHg2IGk4XG4gICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHg4LCBfKSA9IGk5IGluXG4gICAgICAgICAgICAgICAgICBsZXQgKGw0LCBsNSkgPSB4OCBpblxuICAgICAgICAgICAgICAgICAgQ29xX2V4aXN0VCAobjAsIChDb3FfZXhpc3RUXG4gICAgICAgICAgICAgICAgICAoKChhcHBcbiAgICAgICAgICAgICAgICAgICAgICAoZnN0XG4gICAgICAgICAgICAgICAgICAgICAgICAobnRoX3NwbGl0IG4wIChyZW1vdmVfbnRoIChTIG4wKSAoSW1wIChtMCwgbTEpKSBsKSkpXG4gICAgICAgICAgICAgICAgICAgICAgKHNuZFxuICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBuMCAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSkgbCkpKSksXG4gICAgICAgICAgICAgICAgICAoYXBwIGw0IChtMCA6OiBsNSkpKSwgKENvcV9leGlzdFRcbiAgICAgICAgICAgICAgICAgICgoKGFwcFxuICAgICAgICAgICAgICAgICAgICAgIChmc3RcbiAgICAgICAgICAgICAgICAgICAgICAgIChudGhfc3BsaXQgbjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIG4wIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgTyAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggbCB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGIwIDo6IHRsIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGVxX2RlY19mb3JtIChJbXAgKG0wLCBtMSkpIGIwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gdGxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBiMCA6OiB0bClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUyBfIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBsIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgW10gLT4gW11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgYjAgOjogdGwgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYjAgOjogKHJlbW92ZV9udGggbjAgKEltcCAobTAsIG0xKSkgdGwpKSkpKVxuICAgICAgICAgICAgICAgICAgICAgIChtMSA6OiAoc25kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG50aF9zcGxpdCBuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIG4wIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IE8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBsIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBiMCA6OiB0bCAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgZXFfZGVjX2Zvcm0gKEltcCAobTAsIG0xKSkgYjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gdGxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgYjAgOjogdGwpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTIF8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBsIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFtdIC0+IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBiMCA6OiB0bCAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYjAgOjogKHJlbW92ZV9udGggbjAgKEltcCAobTAsIG0xKSkgdGwpKSkpKSkpLFxuICAgICAgICAgICAgICAgICAgbDApLCAoQ29xX2V4aXN0VCAobTAsIChDb3FfZXhpc3RUIChtMSwgKENvcV9leGlzdFRcbiAgICAgICAgICAgICAgICAgICgoZnN0IChudGhfc3BsaXQgbjAgKHJlbW92ZV9udGggKFMgbjApIChJbXAgKG0wLCBtMSkpIGwpKSksXG4gICAgICAgICAgICAgICAgICAoQ29xX2V4aXN0VFxuICAgICAgICAgICAgICAgICAgKChzbmQgKG50aF9zcGxpdCBuMCAocmVtb3ZlX250aCAoUyBuMCkgKEltcCAobTAsIG0xKSkgbCkpKSxcbiAgICAgICAgICAgICAgICAgIChDb3FfZXhpc3RUIChsNCwgKENvcV9leGlzdFQgKGw1LCBfXykpKSkpKSkpKSkpKSkpKSkpXG4gICAgICAgICAgICAgICAgfCBJblRfY29ucyAoXywgXywgXykgLT4gYXNzZXJ0IGZhbHNlICgqIGFic3VyZCBjYXNlICopKVxuICAgICAgICAgICAgIHwgQ29xX2luciBpIC0+XG4gICAgICAgICAgICAgICBsZXQgczAgPSBmIGwzIGkgaW5cbiAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MSwgczEpID0gczAgaW5cbiAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MiwgczIpID0gczEgaW5cbiAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MywgczMpID0gczIgaW5cbiAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4NCwgczQpID0gczMgaW5cbiAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4NSwgczUpID0gczQgaW5cbiAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4NiwgczYpID0gczUgaW5cbiAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4NywgczcpID0gczYgaW5cbiAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4OCwgczgpID0gczcgaW5cbiAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4OSwgXykgPSBzOCBpblxuICAgICAgICAgICAgICAgQ29xX2V4aXN0VCAoeDEsIChDb3FfZXhpc3RUICh4MiwgKENvcV9leGlzdFQgKHgzLCAoQ29xX2V4aXN0VFxuICAgICAgICAgICAgICAgKHg0LCAoQ29xX2V4aXN0VCAoeDUsIChDb3FfZXhpc3RUICh4NiwgKENvcV9leGlzdFQgKHg3LFxuICAgICAgICAgICAgICAgKENvcV9leGlzdFQgKHg4LCAoQ29xX2V4aXN0VCAoeDksIF9fKSkpKSkpKSkpKSkpKSkpKSkpKVxuICAgICAgIHwgXyAtPlxuICAgICAgICAgbGV0IHMwID0gZiBsMyB4IGluXG4gICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDAsIHMxKSA9IHMwIGluXG4gICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDEsIHMyKSA9IHMxIGluXG4gICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDIsIHMzKSA9IHMyIGluXG4gICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDMsIHM0KSA9IHMzIGluXG4gICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDQsIHM1KSA9IHM0IGluXG4gICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDUsIHM2KSA9IHM1IGluXG4gICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDYsIHM3KSA9IHM2IGluXG4gICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDcsIHM4KSA9IHM3IGluXG4gICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDgsIF8pID0gczggaW5cbiAgICAgICAgIENvcV9leGlzdFQgKHgwLCAoQ29xX2V4aXN0VCAoeDEsIChDb3FfZXhpc3RUICh4MiwgKENvcV9leGlzdFQgKHgzLFxuICAgICAgICAgKENvcV9leGlzdFQgKHg0LCAoQ29xX2V4aXN0VCAoeDUsIChDb3FfZXhpc3RUICh4NiwgKENvcV9leGlzdFQgKHg3LFxuICAgICAgICAgKENvcV9leGlzdFQgKHg4LCBfXykpKSkpKSkpKSkpKSkpKSkpKVxuICBpbiBmIGwxXG5cbigqKiB2YWwgY29xX0ltcExfaGVscDEgOlxuICAgIGNvcV9TZXEgbGlzdCAtPiAoY29xX01Qcm9wRiBsaXN0ICogY29xX01Qcm9wRiBsaXN0KSAtPiBjb3FfU2VxIGxpc3RcbiAgICBjb3FfSW5UIC0+IGNvcV9JbXBMUnVsZSAqKilcblxubGV0IGNvcV9JbXBMX2hlbHAxIHByZW0gcyB4ID1cbiAgbGV0IHMwID0gY29xX0ltcExfaGVscDAxIHByZW0gcyAocG9zX3RvcF9pbXBzIChmc3QgcykpIHggaW5cbiAgbGV0IENvcV9leGlzdFQgKHgwLCBzMSkgPSBzMCBpblxuICBsZXQgQ29xX2V4aXN0VCAoXywgczIpID0gczEgaW5cbiAgbGV0IENvcV9leGlzdFQgKF8sIHMzKSA9IHMyIGluXG4gIGxldCBDb3FfZXhpc3RUICh4MSwgczQpID0gczMgaW5cbiAgbGV0IENvcV9leGlzdFQgKHgyLCBzNSkgPSBzNCBpblxuICBsZXQgQ29xX2V4aXN0VCAoXywgczYpID0gczUgaW5cbiAgbGV0IENvcV9leGlzdFQgKF8sIHM3KSA9IHM2IGluXG4gIGxldCBDb3FfZXhpc3RUICh4MywgczgpID0gczcgaW5cbiAgbGV0IENvcV9leGlzdFQgKHg0LCBfKSA9IHM4IGluXG4gIGxldCAobCwgbDApID0gcyBpblxuICBsZXQgaSA9IGNvcV9Jbl9wb3NfdG9wX2ltcHNfc3BsaXRfbCAoZnN0IChsLCBsMCkpIChJbXAgKHgxLCB4MikpIHgwIGluXG4gIGxldCBDb3FfZXhpc3RUICh4NSwgXykgPSBpIGluXG4gIGxldCBfVVUwMzkzXzAnID1cbiAgICBmc3QgKG50aF9zcGxpdCAobGVuZ3RoIHg1KSAocmVtb3ZlX250aCAoUyAobGVuZ3RoIHg1KSkgKEltcCAoeDEsIHgyKSkgbCkpXG4gIGluXG4gIGxldCBfVVUwMzkzXzEnID1cbiAgICBzbmQgKG50aF9zcGxpdCAobGVuZ3RoIHg1KSAocmVtb3ZlX250aCAoUyAobGVuZ3RoIHg1KSkgKEltcCAoeDEsIHgyKSkgbCkpXG4gIGluXG4gIEltcExSdWxlX0kgKHgxLCB4MiwgX1VVMDM5M18wJywgX1VVMDM5M18xJywgeDMsIHg0KVxuXG4oKiogdmFsIGZpbml0ZV9JbXBMX3ByZW1pc2VzX29mX1MgOlxuICAgIGNvcV9TZXEgLT4gKGNvcV9TZXEgbGlzdCBsaXN0LCBjb3FfU2VxIGxpc3QgLT4gKGNvcV9JbXBMUnVsZSAtPiBjb3FfU2VxXG4gICAgbGlzdCBjb3FfSW5UKSAqIChjb3FfU2VxIGxpc3QgY29xX0luVCAtPiBjb3FfSW1wTFJ1bGUpKSBzaWdUICoqKVxuXG5sZXQgZmluaXRlX0ltcExfcHJlbWlzZXNfb2ZfUyA9IGZ1bmN0aW9uXG58IChsLCBsMCkgLT5cbiAgQ29xX2V4aXN0VCAoKHByZW1zX0ltcF9MIChwb3NfdG9wX2ltcHMgbCkgKGwsIGwwKSksIChmdW4gcHJlbXMgLT5cbiAgICAoKGZ1biBoIC0+XG4gICAgbGV0IEltcExSdWxlX0kgKGEsIGIsIF9VVTAzOTNfMCwgX1VVMDM5M18xLCBfVVUwMzk0XzAsIF9VVTAzOTRfMSkgPSBoIGluXG4gICAgY29xX0ltcExfaGVscDIgKChhcHAgX1VVMDM5M18wIF9VVTAzOTNfMSksXG4gICAgICAoYXBwIF9VVTAzOTRfMCAoYSA6OiBfVVUwMzk0XzEpKSkgKChhcHAgX1VVMDM5M18wIChiIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSlcbiAgICAgICgoYXBwIF9VVTAzOTNfMCAoKEltcCAoYSwgYikpIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkgaCksIChmdW4gaCAtPlxuICAgIGNvcV9JbXBMX2hlbHAxIHByZW1zIChsLCBsMCkgaCkpKSlcbiIsIm9wZW4gQ01MX1N5bnRheFxub3BlbiBEYXRhdHlwZXNcbm9wZW4gS1NfY2FsY1xub3BlbiBLU190ZXJtaW5hdGlvbl9wcmVsaW1zXG5vcGVuIExpc3RfbGVtbWFzVFxub3BlbiBTcGVjaWZcbm9wZW4gR2VuVFxub3BlbiBMaXN0X2xlbXNcblxudHlwZSBfXyA9IE9iai50XG5sZXQgX18gPSBsZXQgcmVjIGYgXyA9IE9iai5yZXByIGYgaW4gT2JqLnJlcHIgZlxuXG4oKiogdmFsIHByZW1zX0JveF9SIDogY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9TZXEgLT4gY29xX1NlcSBsaXN0IGxpc3QgKiopXG5cbmxldCByZWMgcHJlbXNfQm94X1IgbCBzID1cbiAgbWF0Y2ggbCB3aXRoXG4gIHwgW10gLT4gW11cbiAgfCBoIDo6IHQgLT5cbiAgICAobWF0Y2ggaCB3aXRoXG4gICAgIHwgQm94IGEgLT5cbiAgICAgICAoKCh1bmJveGVkX2xpc3QgKHRvcF9ib3hlcyAoZnN0IHMpKSksXG4gICAgICAgICAoYSA6OiBbXSkpIDo6IFtdKSA6OiAocHJlbXNfQm94X1IgdCBzKVxuICAgICB8IF8gLT4gcHJlbXNfQm94X1IgdCBzKVxuXG4oKiogdmFsIGNvcV9LUl9oZWxwMDEgOlxuICAgIGNvcV9TZXEgbGlzdCAtPiBjb3FfU2VxIC0+IGNvcV9NUHJvcEYgbGlzdCAtPiBjb3FfU2VxIGxpc3QgY29xX0luVCAtPlxuICAgIChjb3FfTVByb3BGLCBfXykgc2lnVCAqKilcblxubGV0IHJlYyBjb3FfS1JfaGVscDAxIHByZW1zIHMgbDEgeCA9XG4gIG1hdGNoIGwxIHdpdGhcbiAgfCBbXSAtPiBhc3NlcnQgZmFsc2UgKCogYWJzdXJkIGNhc2UgKilcbiAgfCB5IDo6IGwgLT5cbiAgICAobWF0Y2ggeSB3aXRoXG4gICAgIHwgQm94IG0gLT5cbiAgICAgICAobWF0Y2ggeCB3aXRoXG4gICAgICAgIHwgSW5UX2VxJyAoXywgXykgLT4gQ29xX2V4aXN0VCAobSwgX18pXG4gICAgICAgIHwgSW5UX2NvbnMgKF8sIF8sIHgwKSAtPlxuICAgICAgICAgIGxldCBoMCA9IGNvcV9LUl9oZWxwMDEgcHJlbXMgcyBsIHgwIGluXG4gICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgxLCBfKSA9IGgwIGluIENvcV9leGlzdFQgKHgxLCBfXykpXG4gICAgIHwgXyAtPlxuICAgICAgIGxldCB4MCA9IGNvcV9LUl9oZWxwMDEgcHJlbXMgcyBsIHggaW5cbiAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDEsIF8pID0geDAgaW4gQ29xX2V4aXN0VCAoeDEsIF9fKSlcblxuKCoqIHZhbCBjb3FfS1JfaGVscDEgOlxuICAgIGNvcV9TZXEgbGlzdCAtPiAoY29xX01Qcm9wRiBsaXN0ICogY29xX01Qcm9wRiBsaXN0KSAtPiBjb3FfU2VxIGxpc3RcbiAgICBjb3FfSW5UIC0+IGNvcV9LUlJ1bGUgKiopXG5cbmxldCBjb3FfS1JfaGVscDEgcHJlbXMgcyB4ID1cbiAgbGV0IHMwID0gY29xX0tSX2hlbHAwMSBwcmVtcyBzICh0b3BfYm94ZXMgKHNuZCBzKSkgeCBpblxuICBsZXQgQ29xX2V4aXN0VCAoeDAsIF8pID0gczAgaW5cbiAgbGV0IChsLCBsMCkgPSBzIGluXG4gIGxldCBoID0gaW5fc3BsaXRUIChCb3ggeDApIGwwIGluXG4gIGxldCBDb3FfZXhpc3RUICh4MSwgczEpID0gaCBpblxuICBsZXQgQ29xX2V4aXN0VCAoeDIsIF8pID0gczEgaW5cbiAgS1JSdWxlX0kgKHgwLCAodG9wX2JveGVzIGwpLCBsLCB4MSwgeDIsICh0b3BfYm94ZXNfbm9ib3hfZ2VuX2V4dCBsKSlcblxuKCoqIHZhbCBjb3FfS1JfaGVscDAyIDpcbiAgICBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgbGlzdCAtPiBjb3FfTVByb3BGIGxpc3RcbiAgICAtPiBjb3FfTVByb3BGIC0+IGNvcV9NUHJvcEYgbGlzdCAtPiBjb3FfS1JSdWxlIC0+IG5vYm94X2dlbl9leHQgLT5cbiAgICAoY29xX01Qcm9wRiBsaXN0ICogY29xX01Qcm9wRiBsaXN0KSBsaXN0IGNvcV9JblQgKiopXG5cbmxldCByZWMgY29xX0tSX2hlbHAwMiBfVVUwMzkzXyBfVVUwMzk0XzAgX1VVMDM5NF8xIGJfVVUwMzkzXyBhIGwgeCB4MCA9XG4gIG1hdGNoIGwgd2l0aFxuICB8IFtdIC0+IGFzc2VydCBmYWxzZSAoKiBhYnN1cmQgY2FzZSAqKVxuICB8IHkgOjogbDAgLT5cbiAgICAobWF0Y2ggeSB3aXRoXG4gICAgIHwgQm94IG0gLT5cbiAgICAgICBsZXQgaDEgPVxuICAgICAgICAgbGV0IGgwID0gaW5fc3BsaXRUIChCb3ggYSkgKChCb3ggbSkgOjogbDApIGluXG4gICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDEsIHMpID0gaDAgaW5cbiAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MiwgXykgPSBzIGluXG4gICAgICAgICBjb3FfSW5UX29yX2FwcCB4MSAoKEJveCBhKSA6OiB4MikgKEJveCBhKSAoQ29xX2luclxuICAgICAgICAgICAoY29xX0luVF9lcSAoQm94IGEpIHgyKSlcbiAgICAgICBpblxuICAgICAgIChtYXRjaCBoMSB3aXRoXG4gICAgICAgIHwgSW5UX2VxJyAoXywgXykgLT5cbiAgICAgICAgICBjb3FfSW5UX2VxICgoKHVuYm94ZWRfbGlzdCAodG9wX2JveGVzIF9VVTAzOTNfKSksIChhIDo6IFtdKSkgOjogW10pXG4gICAgICAgICAgICAocHJlbXNfQm94X1IgbDAgKF9VVTAzOTNfLFxuICAgICAgICAgICAgICAoYXBwIF9VVTAzOTRfMCAoKEJveCBhKSA6OiBfVVUwMzk0XzEpKSkpXG4gICAgICAgIHwgSW5UX2NvbnMgKF8sIF8sIF8pIC0+XG4gICAgICAgICAgbGV0IGkgPVxuICAgICAgICAgICAgY29xX0tSX2hlbHAwMiBfVVUwMzkzXyBfVVUwMzk0XzAgX1VVMDM5NF8xIGJfVVUwMzkzXyBhIGwwIHggeDBcbiAgICAgICAgICBpblxuICAgICAgICAgIEluVF9jb25zICgoKCh1bmJveGVkX2xpc3QgKHRvcF9ib3hlcyBfVVUwMzkzXykpLCAobSA6OiBbXSkpIDo6IFtdKSxcbiAgICAgICAgICAocHJlbXNfQm94X1IgbDAgKF9VVTAzOTNfLCAoYXBwIF9VVTAzOTRfMCAoKEJveCBhKSA6OiBfVVUwMzk0XzEpKSkpLFxuICAgICAgICAgIGkpKVxuICAgICB8IHgxIC0+XG4gICAgICAgbGV0IGgxID1cbiAgICAgICAgIGxldCBoMCA9IGluX3NwbGl0VCAoQm94IGEpICh4MSA6OiBsMCkgaW5cbiAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MiwgcykgPSBoMCBpblxuICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgzLCBfKSA9IHMgaW5cbiAgICAgICAgIGNvcV9JblRfb3JfYXBwIHgyICgoQm94IGEpIDo6IHgzKSAoQm94IGEpIChDb3FfaW5yXG4gICAgICAgICAgIChjb3FfSW5UX2VxIChCb3ggYSkgeDMpKVxuICAgICAgIGluXG4gICAgICAgKG1hdGNoIGgxIHdpdGhcbiAgICAgICAgfCBJblRfZXEnIChfLCBfKSAtPiBhc3NlcnQgZmFsc2UgKCogYWJzdXJkIGNhc2UgKilcbiAgICAgICAgfCBJblRfY29ucyAoXywgXywgXykgLT5cbiAgICAgICAgICBjb3FfS1JfaGVscDAyIF9VVTAzOTNfIF9VVTAzOTRfMCBfVVUwMzk0XzEgYl9VVTAzOTNfIGEgbDAgeCB4MCkpXG5cbigqKiB2YWwgY29xX0tSX2hlbHAyIDpcbiAgICBjb3FfU2VxIC0+IGNvcV9TZXEgLT4gY29xX0tSUnVsZSAtPiBjb3FfU2VxIGxpc3QgY29xX0luVCAqKilcblxubGV0IGNvcV9LUl9oZWxwMiBfIF8geCA9IG1hdGNoIHggd2l0aFxufCBLUlJ1bGVfSSAoYSwgYl9VVTAzOTNfLCBfVVUwMzkzXzAsIF9VVTAzOTRfMCwgX1VVMDM5NF8xLCB4MCkgLT5cbiAgY29xX0tSX2hlbHAwMiBfVVUwMzkzXzAgX1VVMDM5NF8wIF9VVTAzOTRfMSBiX1VVMDM5M18gYVxuICAgICh0b3BfYm94ZXMgKGFwcCBfVVUwMzk0XzAgKChCb3ggYSkgOjogX1VVMDM5NF8xKSkpIHggeDBcblxuKCoqIHZhbCBmaW5pdGVfS1JfcHJlbWlzZXNfb2ZfUyA6XG4gICAgY29xX1NlcSAtPiAoY29xX1NlcSBsaXN0IGxpc3QsIGNvcV9TZXEgbGlzdCAtPiAoY29xX0tSUnVsZSAtPiBjb3FfU2VxXG4gICAgbGlzdCBjb3FfSW5UKSAqIChjb3FfU2VxIGxpc3QgY29xX0luVCAtPiBjb3FfS1JSdWxlKSkgc2lnVCAqKilcblxubGV0IGZpbml0ZV9LUl9wcmVtaXNlc19vZl9TID0gZnVuY3Rpb25cbnwgKGwsIGwwKSAtPlxuICBDb3FfZXhpc3RUICgocHJlbXNfQm94X1IgKHRvcF9ib3hlcyBsMCkgKGwsIGwwKSksIChmdW4gcHJlbXMgLT4gKChmdW4geCAtPlxuICAgIGxldCBLUlJ1bGVfSSAoYSwgYl9VVTAzOTNfLCBfLCBfVVUwMzk0XzAsIF9VVTAzOTRfMSwgXykgPSB4IGluXG4gICAgY29xX0tSX2hlbHAyICgodW5ib3hlZF9saXN0IGJfVVUwMzkzXyksIChhIDo6IFtdKSkgKGwsXG4gICAgICAoYXBwIF9VVTAzOTRfMCAoKEJveCBhKSA6OiBfVVUwMzk0XzEpKSkgeCksIChmdW4gaCAtPlxuICAgIGNvcV9LUl9oZWxwMSBwcmVtcyAobCwgbDApIGgpKSkpXG4iLCJvcGVuIERhdGF0eXBlc1xub3BlbiBFbnZpcm9ubWVudHNcbm9wZW4gRm9ybXVsYXNcbm9wZW4gTGlzdFxub3BlbiBPcmRlclxub3BlbiBCYXNlXG5vcGVuIExpc3QwXG5cbnR5cGUgX18gPSBPYmoudFxubGV0IF9fID0gbGV0IHJlYyBmIF8gPSBPYmoucmVwciBmIGluIE9iai5yZXByIGZcblxuKCoqIHZhbCBlX3J1bGUgOlxuICAgIHZhcmlhYmxlIC0+IGZvcm0gbGlzdCAtPiBmb3JtIC0+IChwb2ludGVkX2VudiAtPiBfXyAtPiBmb3JtICogZm9ybSkgLT5cbiAgICBmb3JtIC0+IGZvcm0gKiopXG5cbmxldCBlX3J1bGUgcCBfVVUwMzk0XyBfVVUwM2Q1XyBlQTAgX1VVMDNiOF8gPVxuICBsZXQgZSA9IGZ1biBfVVUwMzk0XzAgLT4gZnN0IChlQTAgKF9VVTAzOTRfMCwgX1VVMDNkNV8pIF9fKSBpblxuICBsZXQgYSA9IGZ1biBwZTAgLT4gc25kIChlQTAgcGUwIF9fKSBpblxuICBsZXQgX1VVMDM5NF8nID0gcm0gX1VVMDNiOF8gX1VVMDM5NF8gaW5cbiAgKG1hdGNoIF9VVTAzYjhfIHdpdGhcbiAgIHwgVmFyIHEgLT5cbiAgICAgaWYgZGVjaWRlIChkZWNpZGVfcmVsIHN0cmluZ19kZWMgcCBxKSB0aGVuIEltcGxpZXMgKEJvdCwgQm90KSBlbHNlIFZhciBxXG4gICB8IEJvdCAtPiBCb3RcbiAgIHwgQW5kIChfVVUwM2I0X19VVTIwODFfLCBfVVUwM2I0X19VVTIwODJfKSAtPlxuICAgICBlIChfVVUwM2I0X19VVTIwODJfIDo6IChfVVUwM2I0X19VVTIwODFfIDo6IF9VVTAzOTRfJykpXG4gICB8IE9yIChfVVUwM2I0X19VVTIwODFfLCBfVVUwM2I0X19VVTIwODJfKSAtPlxuICAgICBtYWtlX2Rpc2ogKGUgKF9VVTAzYjRfX1VVMjA4MV8gOjogX1VVMDM5NF8nKSlcbiAgICAgICAoZSAoX1VVMDNiNF9fVVUyMDgyXyA6OiBfVVUwMzk0XycpKVxuICAgfCBJbXBsaWVzIChmLCBfVVUwM2I0XzIpIC0+XG4gICAgIChtYXRjaCBmIHdpdGhcbiAgICAgIHwgVmFyIHEgLT5cbiAgICAgICAgaWYgZGVjaWRlIChkZWNpZGVfcmVsIChlbGVtX29mX2xpc3RfZGVjIGZvcm1fZXFfZGVjKSAoVmFyIHEpIF9VVTAzOTRfKVxuICAgICAgICB0aGVuIGUgKF9VVTAzYjRfMiA6OiBfVVUwMzk0XycpXG4gICAgICAgIGVsc2UgaWYgZGVjaWRlIChkZWNpZGVfcmVsIHN0cmluZ19kZWMgcCBxKVxuICAgICAgICAgICAgIHRoZW4gSW1wbGllcyAoQm90LCBCb3QpXG4gICAgICAgICAgICAgZWxzZSBtYWtlX2ltcGwgKFZhciBxKSAoZSAoX1VVMDNiNF8yIDo6IF9VVTAzOTRfJykpXG4gICAgICB8IEJvdCAtPiBJbXBsaWVzIChCb3QsIEJvdClcbiAgICAgIHwgQW5kIChfVVUwM2I0X19VVTIwODFfLCBfVVUwM2I0X19VVTIwODJfKSAtPlxuICAgICAgICBlICgoSW1wbGllcyAoX1VVMDNiNF9fVVUyMDgxXywgKEltcGxpZXMgKF9VVTAzYjRfX1VVMjA4Ml8sXG4gICAgICAgICAgX1VVMDNiNF8yKSkpKSA6OiBfVVUwMzk0XycpXG4gICAgICB8IE9yIChfVVUwM2I0X19VVTIwODFfLCBfVVUwM2I0X19VVTIwODJfKSAtPlxuICAgICAgICBlICgoSW1wbGllcyAoX1VVMDNiNF9fVVUyMDgyXywgX1VVMDNiNF8yKSkgOjogKChJbXBsaWVzXG4gICAgICAgICAgKF9VVTAzYjRfX1VVMjA4MV8sIF9VVTAzYjRfMikpIDo6IF9VVTAzOTRfJykpXG4gICAgICB8IEltcGxpZXMgKF9VVTAzYjRfX1VVMjA4MV8sIF9VVTAzYjRfX1VVMjA4Ml8pIC0+XG4gICAgICAgIG1ha2VfaW1wbFxuICAgICAgICAgIChtYWtlX2ltcGxcbiAgICAgICAgICAgIChlIChfVVUwM2I0X19VVTIwODFfIDo6ICgoSW1wbGllcyAoX1VVMDNiNF9fVVUyMDgyXyxcbiAgICAgICAgICAgICAgX1VVMDNiNF8yKSkgOjogX1VVMDM5NF8nKSkpXG4gICAgICAgICAgICAoYSAoKF9VVTAzYjRfX1VVMjA4MV8gOjogKChJbXBsaWVzIChfVVUwM2I0X19VVTIwODJfLFxuICAgICAgICAgICAgICBfVVUwM2I0XzIpKSA6OiBfVVUwMzk0XycpKSwgX1VVMDNiNF9fVVUyMDgyXykpKVxuICAgICAgICAgIChlIChfVVUwM2I0XzIgOjogX1VVMDM5NF8nKSlcbiAgICAgIHwgQm94IF9VVTAzYjRfMSAtPlxuICAgICAgICBtYWtlX2ltcGwgKEJveFxuICAgICAgICAgIChtYWtlX2ltcGxcbiAgICAgICAgICAgIChlICgoQm94IF9VVTAzYjRfMSkgOjogKF9VVTAzYjRfMiA6OiAobWFwIG9wZW5fYm94IF9VVTAzOTRfJykpKSlcbiAgICAgICAgICAgIChhICgoKEJveCBfVVUwM2I0XzEpIDo6IChfVVUwM2I0XzIgOjogKG1hcCBvcGVuX2JveCBfVVUwMzk0XycpKSksXG4gICAgICAgICAgICAgIF9VVTAzYjRfMSkpKSkgKGUgKF9VVTAzYjRfMiA6OiBfVVUwMzk0XycpKSlcbiAgIHwgQm94IF9VVTAzYzZfIC0+IEJveCAoZSAoX1VVMDNjNl8gOjogKG1hcCBvcGVuX2JveCBfVVUwMzk0XycpKSkpXG5cbigqKiB2YWwgYV9ydWxlX2VudiA6XG4gICAgdmFyaWFibGUgLT4gZm9ybSBsaXN0IC0+IGZvcm0gLT4gKHBvaW50ZWRfZW52IC0+IF9fIC0+IGZvcm0gKiBmb3JtKSAtPlxuICAgIGZvcm0gLT4gZm9ybSAqKilcblxubGV0IGFfcnVsZV9lbnYgcCBfVVUwMzk0XyBfVVUwM2Q1XyBlQTAgX1VVMDNiOF8gPVxuICBsZXQgZSA9IGZ1biBfVVUwMzk0XzAgLT4gZnN0IChlQTAgKF9VVTAzOTRfMCwgX1VVMDNkNV8pIF9fKSBpblxuICBsZXQgYSA9IGZ1biBwZTAgLT4gc25kIChlQTAgcGUwIF9fKSBpblxuICBsZXQgX1VVMDM5NF8nID0gcm0gX1VVMDNiOF8gX1VVMDM5NF8gaW5cbiAgKG1hdGNoIF9VVTAzYjhfIHdpdGhcbiAgIHwgVmFyIHEgLT5cbiAgICAgaWYgZGVjaWRlIChkZWNpZGVfcmVsIHN0cmluZ19kZWMgcCBxKVxuICAgICB0aGVuIGlmIGRlY2lkZSAoZGVjaWRlX3JlbCBmb3JtX2VxX2RlYyAoVmFyIHApIF9VVTAzZDVfKVxuICAgICAgICAgIHRoZW4gSW1wbGllcyAoQm90LCBCb3QpXG4gICAgICAgICAgZWxzZSBCb3RcbiAgICAgZWxzZSBCb3RcbiAgIHwgQW5kIChfVVUwM2I0X19VVTIwODFfLCBfVVUwM2I0X19VVTIwODJfKSAtPlxuICAgICBhICgoX1VVMDNiNF9fVVUyMDgyXyA6OiAoX1VVMDNiNF9fVVUyMDgxXyA6OiBfVVUwMzk0XycpKSwgX1VVMDNkNV8pXG4gICB8IE9yIChfVVUwM2I0X19VVTIwODFfLCBfVVUwM2I0X19VVTIwODJfKSAtPlxuICAgICBtYWtlX2NvbmpcbiAgICAgICAobWFrZV9pbXBsIChlIChfVVUwM2I0X19VVTIwODFfIDo6IF9VVTAzOTRfJykpXG4gICAgICAgICAoYSAoKF9VVTAzYjRfX1VVMjA4MV8gOjogX1VVMDM5NF8nKSwgX1VVMDNkNV8pKSlcbiAgICAgICAobWFrZV9pbXBsIChlIChfVVUwM2I0X19VVTIwODJfIDo6IF9VVTAzOTRfJykpXG4gICAgICAgICAoYSAoKF9VVTAzYjRfX1VVMjA4Ml8gOjogX1VVMDM5NF8nKSwgX1VVMDNkNV8pKSlcbiAgIHwgSW1wbGllcyAoZiwgX1VVMDNiNF8yKSAtPlxuICAgICAobWF0Y2ggZiB3aXRoXG4gICAgICB8IFZhciBxIC0+XG4gICAgICAgIGlmIGRlY2lkZSAoZGVjaWRlX3JlbCAoZWxlbV9vZl9saXN0X2RlYyBmb3JtX2VxX2RlYykgKFZhciBxKSBfVVUwMzk0XylcbiAgICAgICAgdGhlbiBhICgoX1VVMDNiNF8yIDo6IF9VVTAzOTRfJyksIF9VVTAzZDVfKVxuICAgICAgICBlbHNlIGlmIGRlY2lkZSAoZGVjaWRlX3JlbCBzdHJpbmdfZGVjIHAgcSlcbiAgICAgICAgICAgICB0aGVuIEJvdFxuICAgICAgICAgICAgIGVsc2UgbWFrZV9jb25qIChWYXIgcSkgKGEgKChfVVUwM2I0XzIgOjogX1VVMDM5NF8nKSwgX1VVMDNkNV8pKVxuICAgICAgfCBCb3QgLT4gQm90XG4gICAgICB8IEFuZCAoX1VVMDNiNF9fVVUyMDgxXywgX1VVMDNiNF9fVVUyMDgyXykgLT5cbiAgICAgICAgYSAoKChJbXBsaWVzIChfVVUwM2I0X19VVTIwODFfLCAoSW1wbGllcyAoX1VVMDNiNF9fVVUyMDgyXyxcbiAgICAgICAgICBfVVUwM2I0XzIpKSkpIDo6IF9VVTAzOTRfJyksIF9VVTAzZDVfKVxuICAgICAgfCBPciAoX1VVMDNiNF9fVVUyMDgxXywgX1VVMDNiNF9fVVUyMDgyXykgLT5cbiAgICAgICAgYSAoKChJbXBsaWVzIChfVVUwM2I0X19VVTIwODJfLCBfVVUwM2I0XzIpKSA6OiAoKEltcGxpZXNcbiAgICAgICAgICAoX1VVMDNiNF9fVVUyMDgxXywgX1VVMDNiNF8yKSkgOjogX1VVMDM5NF8nKSksIF9VVTAzZDVfKVxuICAgICAgfCBJbXBsaWVzIChfVVUwM2I0X19VVTIwODFfLCBfVVUwM2I0X19VVTIwODJfKSAtPlxuICAgICAgICBtYWtlX2NvbmpcbiAgICAgICAgICAobWFrZV9pbXBsXG4gICAgICAgICAgICAoZSAoX1VVMDNiNF9fVVUyMDgxXyA6OiAoKEltcGxpZXMgKF9VVTAzYjRfX1VVMjA4Ml8sXG4gICAgICAgICAgICAgIF9VVTAzYjRfMikpIDo6IF9VVTAzOTRfJykpKVxuICAgICAgICAgICAgKGEgKChfVVUwM2I0X19VVTIwODFfIDo6ICgoSW1wbGllcyAoX1VVMDNiNF9fVVUyMDgyXyxcbiAgICAgICAgICAgICAgX1VVMDNiNF8yKSkgOjogX1VVMDM5NF8nKSksIF9VVTAzYjRfX1VVMjA4Ml8pKSlcbiAgICAgICAgICAoYSAoKF9VVTAzYjRfMiA6OiBfVVUwMzk0XycpLCBfVVUwM2Q1XykpXG4gICAgICB8IEJveCBfVVUwM2I0XzEgLT5cbiAgICAgICAgQW5kICgoQm94XG4gICAgICAgICAgKG1ha2VfaW1wbFxuICAgICAgICAgICAgKGUgKChCb3ggX1VVMDNiNF8xKSA6OiAoX1VVMDNiNF8yIDo6IChtYXAgb3Blbl9ib3ggX1VVMDM5NF8nKSkpKVxuICAgICAgICAgICAgKGEgKCgoQm94IF9VVTAzYjRfMSkgOjogKF9VVTAzYjRfMiA6OiAobWFwIG9wZW5fYm94IF9VVTAzOTRfJykpKSxcbiAgICAgICAgICAgICAgX1VVMDNiNF8xKSkpKSwgKGEgKChfVVUwM2I0XzIgOjogX1VVMDM5NF8nKSwgX1VVMDNkNV8pKSkpXG4gICB8IF8gLT4gQm90KVxuXG4oKiogdmFsIGFfcnVsZV9mb3JtIDpcbiAgICB2YXJpYWJsZSAtPiBmb3JtIGxpc3QgLT4gZm9ybSAtPiAocG9pbnRlZF9lbnYgLT4gX18gLT4gZm9ybSAqIGZvcm0pIC0+XG4gICAgZm9ybSAqKilcblxubGV0IGFfcnVsZV9mb3JtIHAgX1VVMDM5NF8gX1VVMDNkNV8gZUEwID1cbiAgbGV0IGUgPSBmdW4gcGUwIC0+IGZzdCAoZUEwIHBlMCBfXykgaW5cbiAgbGV0IGEgPSBmdW4gcGUwIC0+IHNuZCAoZUEwIHBlMCBfXykgaW5cbiAgKG1hdGNoIF9VVTAzZDVfIHdpdGhcbiAgIHwgVmFyIHEgLT4gaWYgZGVjaWRlIChkZWNpZGVfcmVsIHN0cmluZ19kZWMgcCBxKSB0aGVuIEJvdCBlbHNlIFZhciBxXG4gICB8IEJvdCAtPiBCb3RcbiAgIHwgQW5kIChfVVUwM2Q1X19VVTIwODFfLCBfVVUwM2Q1X19VVTIwODJfKSAtPlxuICAgICBtYWtlX2NvbmogKGEgKF9VVTAzOTRfLCBfVVUwM2Q1X19VVTIwODFfKSlcbiAgICAgICAoYSAoX1VVMDM5NF8sIF9VVTAzZDVfX1VVMjA4Ml8pKVxuICAgfCBPciAoX1VVMDNkNV9fVVUyMDgxXywgX1VVMDNkNV9fVVUyMDgyXykgLT5cbiAgICAgbWFrZV9kaXNqIChhIChfVVUwMzk0XywgX1VVMDNkNV9fVVUyMDgxXykpXG4gICAgICAgKGEgKF9VVTAzOTRfLCBfVVUwM2Q1X19VVTIwODJfKSlcbiAgIHwgSW1wbGllcyAoX1VVMDNkNV9fVVUyMDgxXywgX1VVMDNkNV9fVVUyMDgyXykgLT5cbiAgICAgbWFrZV9pbXBsIChlICgoX1VVMDNkNV9fVVUyMDgxXyA6OiBfVVUwMzk0XyksIF9VVTAzZDVfX1VVMjA4Ml8pKVxuICAgICAgIChhICgoX1VVMDNkNV9fVVUyMDgxXyA6OiBfVVUwMzk0XyksIF9VVTAzZDVfX1VVMjA4Ml8pKVxuICAgfCBCb3ggX1VVMDNiNF8gLT5cbiAgICAgQm94XG4gICAgICAgKG1ha2VfaW1wbCAoZSAoKChCb3ggX1VVMDNiNF8pIDo6IChtYXAgb3Blbl9ib3ggX1VVMDM5NF8pKSwgX1VVMDNiNF8pKVxuICAgICAgICAgKGEgKCgoQm94IF9VVTAzYjRfKSA6OiAobWFwIG9wZW5fYm94IF9VVTAzOTRfKSksIF9VVTAzYjRfKSkpKVxuXG4oKiogdmFsIGNvcV9FQSA6IHZhcmlhYmxlIC0+IChmb3JtIGxpc3QgKiBmb3JtKSAtPiBmb3JtICogZm9ybSAqKilcblxubGV0IHJlYyBjb3FfRUEgcCB4ID1cbiAgbGV0IF9VVTAzOTRfID0gZnN0IHggaW5cbiAgKChjb25qdW5jdGlvblxuICAgICAoaW5fbWFwIF9VVTAzOTRfIChmdW4geDAgXyAtPlxuICAgICAgIGVfcnVsZSBwIChmc3QgeCkgKHNuZCB4KSAoZnVuIHBlIF8gLT4gY29xX0VBIHAgcGUpIHgwKSkpLFxuICAobWFrZV9kaXNqXG4gICAgKGRpc2p1bmN0aW9uXG4gICAgICAoaW5fbWFwIF9VVTAzOTRfIChmdW4geDAgXyAtPlxuICAgICAgICBhX3J1bGVfZW52IHAgKGZzdCB4KSAoc25kIHgpIChmdW4gcGUgXyAtPiBjb3FfRUEgcCBwZSkgeDApKSlcbiAgICAoYV9ydWxlX2Zvcm0gcCAoZnN0IHgpIChzbmQgeCkgKGZ1biBwZSBfIC0+IGNvcV9FQSBwIHBlKSkpKVxuXG4oKiogdmFsIGNvcV9FIDogdmFyaWFibGUgLT4gKGZvcm0gbGlzdCAqIGZvcm0pIC0+IGZvcm0gKiopXG5cbmxldCBjb3FfRSBwIHBlID1cbiAgZnN0IChjb3FfRUEgcCBwZSlcblxuKCoqIHZhbCBjb3FfQSA6IHZhcmlhYmxlIC0+IChmb3JtIGxpc3QgKiBmb3JtKSAtPiBmb3JtICoqKVxuXG5sZXQgY29xX0EgcCBwZSA9XG4gIHNuZCAoY29xX0VBIHAgcGUpXG5cbigqKiB2YWwgY29xX0VmIDogdmFyaWFibGUgLT4gZm9ybSAtPiBmb3JtICoqKVxuXG5sZXQgY29xX0VmIHAgX1VVMDNjOF8gPVxuICBjb3FfRSBwICgoX1VVMDNjOF8gOjogW10pLCBCb3QpXG5cbigqKiB2YWwgY29xX0FmIDogdmFyaWFibGUgLT4gZm9ybSAtPiBmb3JtICoqKVxuXG5sZXQgY29xX0FmIHAgX1VVMDNjOF8gPVxuICBjb3FfQSBwIChbXSwgX1VVMDNjOF8pXG4iLCJvcGVuIERhdGF0eXBlc1xub3BlbiBFbnZpcm9ubWVudHNcbm9wZW4gRm9ybXVsYXNcbm9wZW4gUHJvcFF1YW50aWZpZXJzXG5vcGVuIEJhc2Vcbm9wZW4gTnVtYmVyc1xuXG4oKiogdmFsIHNpbXBfb3JzIDogZm9ybSAtPiBmb3JtIC0+IGZvcm0gKiopXG5cbmxldCByZWMgc2ltcF9vcnMgX1VVMDNjNl8gX1VVMDNjOF8gPVxuICBtYXRjaCBfVVUwM2M2XyB3aXRoXG4gIHwgT3IgKF9VVTAzYzZfMSwgX1VVMDNjNl8yKSAtPlxuICAgIChtYXRjaCBfVVUwM2M4XyB3aXRoXG4gICAgIHwgT3IgKF9VVTAzYzhfMSwgX1VVMDNjOF8yKSAtPlxuICAgICAgIG1ha2VfZGlzaiBfVVUwM2M2XzFcbiAgICAgICAgIChtYWtlX2Rpc2ogX1VVMDNjOF8xIChzaW1wX29ycyBfVVUwM2M2XzIgX1VVMDNjOF8yKSlcbiAgICAgfCBfIC0+IG1ha2VfZGlzaiBfVVUwM2M4XyAoT3IgKF9VVTAzYzZfMSwgX1VVMDNjNl8yKSkpXG4gIHwgXyAtPlxuICAgIChtYXRjaCBfVVUwM2M4XyB3aXRoXG4gICAgIHwgT3IgKF9VVTAzYzhfMSwgX1VVMDNjOF8yKSAtPlxuICAgICAgIG1ha2VfZGlzaiBfVVUwM2M2XyAoT3IgKF9VVTAzYzhfMSwgX1VVMDNjOF8yKSlcbiAgICAgfCBfIC0+IG1ha2VfZGlzaiBfVVUwM2M2XyBfVVUwM2M4XylcblxuKCoqIHZhbCBzaW1wX2FuZHMgOiBmb3JtIC0+IGZvcm0gLT4gZm9ybSAqKilcblxubGV0IHJlYyBzaW1wX2FuZHMgX1VVMDNjNl8gX1VVMDNjOF8gPVxuICBtYXRjaCBfVVUwM2M2XyB3aXRoXG4gIHwgQW5kIChfVVUwM2M2XzEsIF9VVTAzYzZfMikgLT5cbiAgICAobWF0Y2ggX1VVMDNjOF8gd2l0aFxuICAgICB8IEFuZCAoX1VVMDNjOF8xLCBfVVUwM2M4XzIpIC0+XG4gICAgICAgbWFrZV9jb25qIF9VVTAzYzZfMVxuICAgICAgICAgKG1ha2VfY29uaiBfVVUwM2M4XzEgKHNpbXBfYW5kcyBfVVUwM2M2XzIgX1VVMDNjOF8yKSlcbiAgICAgfCBfIC0+IG1ha2VfY29uaiBfVVUwM2M4XyAoQW5kIChfVVUwM2M2XzEsIF9VVTAzYzZfMikpKVxuICB8IF8gLT5cbiAgICAobWF0Y2ggX1VVMDNjOF8gd2l0aFxuICAgICB8IEFuZCAoX1VVMDNjOF8xLCBfVVUwM2M4XzIpIC0+XG4gICAgICAgbWFrZV9jb25qIF9VVTAzYzZfIChBbmQgKF9VVTAzYzhfMSwgX1VVMDNjOF8yKSlcbiAgICAgfCBfIC0+IG1ha2VfY29uaiBfVVUwM2M2XyBfVVUwM2M4XylcblxuKCoqIHZhbCBzaW1wX2ltcCA6IGZvcm0gLT4gZm9ybSAtPiBmb3JtICoqKVxuXG5sZXQgc2ltcF9pbXAgX1VVMDNjNl8gX1VVMDNjOF8gPVxuICBpZiBkZWNpZGVcbiAgICAgICAoZGVjaWRlX3JlbCBjb21wYXJpc29uX2VxX2RlYyAob2J2aW91c2x5X3NtYWxsZXIgX1VVMDNjNl8gX1VVMDNjOF8pIEx0KVxuICB0aGVuIHRvcCBmb3JtX3RvcFxuICBlbHNlIGlmIGRlY2lkZVxuICAgICAgICAgICAgKGRlY2lkZV9yZWwgY29tcGFyaXNvbl9lcV9kZWNcbiAgICAgICAgICAgICAgKG9idmlvdXNseV9zbWFsbGVyIF9VVTAzYzZfIChib3R0b20gZm9tdWxhX2JvdHRvbSkpIEx0KVxuICAgICAgIHRoZW4gdG9wIGZvcm1fdG9wXG4gICAgICAgZWxzZSBpZiBkZWNpZGVcbiAgICAgICAgICAgICAgICAgKGRlY2lkZV9yZWwgY29tcGFyaXNvbl9lcV9kZWNcbiAgICAgICAgICAgICAgICAgICAob2J2aW91c2x5X3NtYWxsZXIgX1VVMDNjOF8gKHRvcCBmb3JtX3RvcCkpIEd0KVxuICAgICAgICAgICAgdGhlbiB0b3AgZm9ybV90b3BcbiAgICAgICAgICAgIGVsc2UgaWYgZGVjaWRlXG4gICAgICAgICAgICAgICAgICAgICAgKGRlY2lkZV9yZWwgY29tcGFyaXNvbl9lcV9kZWNcbiAgICAgICAgICAgICAgICAgICAgICAgIChvYnZpb3VzbHlfc21hbGxlciBfVVUwM2M2XyAodG9wIGZvcm1fdG9wKSkgR3QpXG4gICAgICAgICAgICAgICAgIHRoZW4gX1VVMDNjOF9cbiAgICAgICAgICAgICAgICAgZWxzZSBpZiBkZWNpZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIChkZWNpZGVfcmVsIGNvbXBhcmlzb25fZXFfZGVjXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvYnZpb3VzbHlfc21hbGxlciBfVVUwM2M4X1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChib3R0b20gZm9tdWxhX2JvdHRvbSkpIEx0KVxuICAgICAgICAgICAgICAgICAgICAgIHRoZW4gSW1wbGllcyAoX1VVMDNjNl8sIEJvdClcbiAgICAgICAgICAgICAgICAgICAgICBlbHNlIEltcGxpZXMgKF9VVTAzYzZfLCBfVVUwM2M4XylcblxuKCoqIHZhbCBzaW1wX2ltcHMgOiBmb3JtIC0+IGZvcm0gLT4gZm9ybSAqKilcblxubGV0IHJlYyBzaW1wX2ltcHMgX1VVMDNjNl8gX1VVMDNjOF8gPSBtYXRjaCBfVVUwM2M4XyB3aXRoXG58IEltcGxpZXMgKF9VVTAzYzhfMSwgX1VVMDNjOF8yKSAtPlxuICBzaW1wX2ltcHMgKHNpbXBfYW5kcyBfVVUwM2M2XyBfVVUwM2M4XzEpIF9VVTAzYzhfMlxufCBfIC0+IHNpbXBfaW1wIF9VVTAzYzZfIF9VVTAzYzhfXG5cbigqKiB2YWwgc2ltcCA6IGZvcm0gLT4gZm9ybSAqKilcblxubGV0IHJlYyBzaW1wIF9VVTAzYzZfID0gbWF0Y2ggX1VVMDNjNl8gd2l0aFxufCBBbmQgKF9VVTAzYzZfMCwgX1VVMDNjOF8pIC0+IHNpbXBfYW5kcyAoc2ltcCBfVVUwM2M2XzApIChzaW1wIF9VVTAzYzhfKVxufCBPciAoX1VVMDNjNl8wLCBfVVUwM2M4XykgLT4gc2ltcF9vcnMgKHNpbXAgX1VVMDNjNl8wKSAoc2ltcCBfVVUwM2M4XylcbnwgSW1wbGllcyAoX1VVMDNjNl8wLCBfVVUwM2M4XykgLT4gc2ltcF9pbXBzIChzaW1wIF9VVTAzYzZfMCkgKHNpbXAgX1VVMDNjOF8pXG58IEJveCBfVVUwM2M2XzAgLT4gQm94IChzaW1wIF9VVTAzYzZfMClcbnwgXyAtPiBfVVUwM2M2X1xuXG4oKiogdmFsIGNvcV9FX3NpbXBsaWZpZWQgOiB2YXJpYWJsZSAtPiBmb3JtIC0+IGZvcm0gKiopXG5cbmxldCBjb3FfRV9zaW1wbGlmaWVkIHAgX1VVMDNjOF8gPVxuICBzaW1wIChjb3FfRSBwICgoX1VVMDNjOF8gOjogW10pLCAoYm90dG9tIGZvbXVsYV9ib3R0b20pKSlcblxuKCoqIHZhbCBjb3FfQV9zaW1wbGlmaWVkIDogdmFyaWFibGUgLT4gZm9ybSAtPiBmb3JtICoqKVxuXG5sZXQgY29xX0Ffc2ltcGxpZmllZCBwIF9VVTAzYzhfID1cbiAgc2ltcCAoY29xX0FmIHAgX1VVMDNjOF8pXG4iLCJvcGVuIERhdGF0eXBlc1xuXG50eXBlIF9fID0gT2JqLnRcbmxldCBfXyA9IGxldCByZWMgZiBfID0gT2JqLnJlcHIgZiBpbiBPYmoucmVwciBmXG5cbigqKiB2YWwgbGlzdF9pc19uaWwgOiAnYTEgbGlzdCAtPiBib29sICoqKVxuXG5sZXQgbGlzdF9pc19uaWwgPSBmdW5jdGlvblxufCBbXSAtPiB0cnVlXG58IF8gOjogXyAtPiBmYWxzZVxuXG4oKiogdmFsIGZsYXRtYXAgOiAoJ2ExIC0+IF9fIC0+ICdhMSBsaXN0KSAtPiAnYTEgbGlzdCAtPiAnYTEgbGlzdCAqKilcblxubGV0IHJlYyBmbGF0bWFwIGYgPSBmdW5jdGlvblxufCBbXSAtPiBbXVxufCB4IDo6IGwwIC0+IGFwcCAoZiB4IF9fKSAoZmxhdG1hcCBmIGwwKVxuXG4oKiogdmFsIGlycmVkIDogKCdhMSAtPiAnYTEgbGlzdCkgLT4gJ2ExIC0+ICdhMSBsaXN0ICoqKVxuXG5sZXQgcmVjIGlycmVkIGYgeCA9XG4gIGlmIGxpc3RfaXNfbmlsIChmIHgpIHRoZW4geCA6OiBbXSBlbHNlIGZsYXRtYXAgKGZ1biB5IF8gLT4gaXJyZWQgZiB5KSAoZiB4KVxuIiwib3BlbiBDTUxfU3ludGF4XG5vcGVuIERhdGF0eXBlc1xub3BlbiBHTFNfY2FsY3Ncbm9wZW4gR0xTX2Rlcl9kZWNcbm9wZW4gTGlzdF9sZW1tYXNUXG5vcGVuIFNwZWNpZlxub3BlbiBVSUdMX2lycmVkX3Nob3J0XG5vcGVuIEdlblRcblxudHlwZSBfXyA9IE9iai50XG5sZXQgX18gPSBsZXQgcmVjIGYgXyA9IE9iai5yZXByIGYgaW4gT2JqLnJlcHIgZlxuXG4oKiogdmFsIGZpbml0ZV9JbXBSdWxlc19wcmVtaXNlc19vZl9TIDpcbiAgICBjb3FfU2VxIC0+IChjb3FfU2VxIGxpc3QgbGlzdCwgY29xX1NlcSBsaXN0IC0+ICgoY29xX0ltcFJSdWxlLFxuICAgIGNvcV9JbXBMUnVsZSkgc3VtIC0+IGNvcV9TZXEgbGlzdCBjb3FfSW5UKSAqIChjb3FfU2VxIGxpc3QgY29xX0luVCAtPlxuICAgIChjb3FfSW1wUlJ1bGUsIGNvcV9JbXBMUnVsZSkgc3VtKSkgc2lnVCAqKilcblxubGV0IGZpbml0ZV9JbXBSdWxlc19wcmVtaXNlc19vZl9TIHMgPVxuICBsZXQgczAgPSBmaW5pdGVfSW1wUl9wcmVtaXNlc19vZl9TIHMgaW5cbiAgbGV0IENvcV9leGlzdFQgKHgsIHApID0gczAgaW5cbiAgbGV0IHMxID0gZmluaXRlX0ltcExfcHJlbWlzZXNfb2ZfUyBzIGluXG4gIGxldCBDb3FfZXhpc3RUICh4MCwgcDApID0gczEgaW5cbiAgQ29xX2V4aXN0VCAoKGFwcCB4IHgwKSwgKGZ1biBwcmVtcyAtPiAoKGZ1biBoIC0+XG4gIG1hdGNoIGggd2l0aFxuICB8IENvcV9pbmwgaSAtPlxuICAgIGxldCBJbXBSUnVsZV9JIChhLCBiLCBfVVUwMzkzXzAsIF9VVTAzOTNfMSwgX1VVMDM5NF8wLCBfVVUwMzk0XzEpID0gaSBpblxuICAgIGNvcV9JblRfb3JfYXBwIHggeDAgKCgoYXBwIF9VVTAzOTNfMCAoYSA6OiBfVVUwMzkzXzEpKSxcbiAgICAgIChhcHAgX1VVMDM5NF8wIChiIDo6IF9VVTAzOTRfMSkpKSA6OiBbXSkgKENvcV9pbmxcbiAgICAgIChsZXQgcHJlbXMwID0gKChhcHAgX1VVMDM5M18wIChhIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgICAgKGFwcCBfVVUwMzk0XzAgKGIgOjogX1VVMDM5NF8xKSkpIDo6IFtdXG4gICAgICAgaW5cbiAgICAgICBsZXQgKHgxLCBfKSA9IHAgcHJlbXMwIGluXG4gICAgICAgeDEgKEltcFJSdWxlX0kgKGEsIGIsIF9VVTAzOTNfMCwgX1VVMDM5M18xLCBfVVUwMzk0XzAsIF9VVTAzOTRfMSkpKSlcbiAgfCBDb3FfaW5yIGkgLT5cbiAgICBsZXQgSW1wTFJ1bGVfSSAoYSwgYiwgX1VVMDM5M18wLCBfVVUwMzkzXzEsIF9VVTAzOTRfMCwgX1VVMDM5NF8xKSA9IGkgaW5cbiAgICBjb3FfSW5UX29yX2FwcCB4IHgwICgoKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKSxcbiAgICAgIChhcHAgX1VVMDM5NF8wIChhIDo6IF9VVTAzOTRfMSkpKSA6OiAoKChhcHAgX1VVMDM5M18wIChiIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkgOjogW10pKSAoQ29xX2luclxuICAgICAgKGxldCBwcmVtczAgPSAoKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKSxcbiAgICAgICAgIChhcHAgX1VVMDM5NF8wIChhIDo6IF9VVTAzOTRfMSkpKSA6OiAoKChhcHAgX1VVMDM5M18wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChiIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkgOjogW10pXG4gICAgICAgaW5cbiAgICAgICBsZXQgKHgxLCBfKSA9IHAwIHByZW1zMCBpblxuICAgICAgIHgxIChJbXBMUnVsZV9JIChhLCBiLCBfVVUwMzkzXzAsIF9VVTAzOTNfMSwgX1VVMDM5NF8wLCBfVVUwMzk0XzEpKSkpKSxcbiAgKGZ1biBoIC0+XG4gIGxldCBoMCA9IGNvcV9JblRfYXBwX29yIHggeDAgcHJlbXMgaCBpblxuICAobWF0Y2ggaDAgd2l0aFxuICAgfCBDb3FfaW5sIGkgLT4gQ29xX2lubCAobGV0IChfLCB4MSkgPSBwIHByZW1zIGluIHgxIGkpXG4gICB8IENvcV9pbnIgaSAtPiBDb3FfaW5yIChsZXQgKF8sIHgxKSA9IHAwIHByZW1zIGluIHgxIGkpKSkpKSlcblxuKCoqIHZhbCBpbnZfcHJlbXMgOiBjb3FfU2VxIC0+IGNvcV9TZXEgbGlzdCAqKilcblxubGV0IGludl9wcmVtcyBzID1cbiAgZmxhdHRlbl9saXN0IChwcm9qMV9zaWdUMiAoZmluaXRlX0ltcFJ1bGVzX3ByZW1pc2VzX29mX1MgcykpXG5cbigqKiB2YWwgY29xX0Nhbm9weSA6IGNvcV9TZXEgLT4gY29xX1NlcSBsaXN0ICoqKVxuXG5sZXQgY29xX0Nhbm9weSA9XG4gIGlycmVkIGludl9wcmVtc1xuXG4oKiogdmFsIGlzX1ByaW1lX2RlYyA6IGNvcV9NUHJvcEYgbGlzdCAtPiAoX18sIF9fKSBzdW0gKiopXG5cbmxldCByZWMgaXNfUHJpbWVfZGVjID0gZnVuY3Rpb25cbnwgW10gLT4gQ29xX2lubCBfX1xufCB5IDo6IGwwIC0+XG4gIChtYXRjaCBpc19QcmltZV9kZWMgbDAgd2l0aFxuICAgfCBDb3FfaW5sIF8gLT4gKG1hdGNoIHkgd2l0aFxuICAgICAgICAgICAgICAgICAgIHwgSW1wIChfLCBfKSAtPiBDb3FfaW5yIF9fXG4gICAgICAgICAgICAgICAgICAgfCBfIC0+IENvcV9pbmwgX18pXG4gICB8IENvcV9pbnIgXyAtPiBDb3FfaW5yIF9fKVxuXG4oKiogdmFsIGNyaXRpY2FsX1NlcV9kZWMgOiBjb3FfU2VxIC0+IChfXywgX18pIHN1bSAqKilcblxubGV0IGNyaXRpY2FsX1NlcV9kZWMgPSBmdW5jdGlvblxufCAobCwgbDApIC0+IGlzX1ByaW1lX2RlYyAoYXBwIGwgbDApXG4iLCJvcGVuIERhdGF0eXBlc1xub3BlbiBHTFNfY2FsY3Ncbm9wZW4gR0xTX2Rlcl9kZWNcblxudHlwZSBfXyA9IE9iai50XG5sZXQgX18gPSBsZXQgcmVjIGYgXyA9IE9iai5yZXByIGYgaW4gT2JqLnJlcHIgZlxuXG4oKiogdmFsIGNvcV9HTFJfcHJlbXMgOiBjb3FfU2VxIC0+IGNvcV9TZXEgbGlzdCAqKilcblxubGV0IGNvcV9HTFJfcHJlbXMgcyA9XG4gIGZsYXR0ZW5fbGlzdCAocHJvajFfc2lnVDIgKGZpbml0ZV9HTFJfcHJlbWlzZXNfb2ZfUyBzKSlcblxuKCoqIHZhbCBjb3FfTGV4U2VxX2luZCA6XG4gICAgKGNvcV9TZXEgLT4gKGNvcV9TZXEgLT4gX18gLT4gJ2ExKSAtPiAnYTEpIC0+IGNvcV9TZXEgLT4gJ2ExICoqKVxuXG5sZXQgcmVjIGNvcV9MZXhTZXFfaW5kIHggcyA9XG4gIHggcyAoZnVuIHMxIF8gLT4gY29xX0xleFNlcV9pbmQgeCBzMSlcblxuKCoqIHZhbCBlbXB0eV9zZXFfZGVjIDogY29xX1NlcSAtPiAoX18sIF9fKSBzdW0gKiopXG5cbmxldCBlbXB0eV9zZXFfZGVjID0gZnVuY3Rpb25cbnwgKGwsIGwwKSAtPlxuICAobWF0Y2ggbCB3aXRoXG4gICB8IFtdIC0+IChtYXRjaCBsMCB3aXRoXG4gICAgICAgICAgICB8IFtdIC0+IENvcV9pbmwgX19cbiAgICAgICAgICAgIHwgXyA6OiBfIC0+IENvcV9pbnIgX18pXG4gICB8IF8gOjogXyAtPiBDb3FfaW5yIF9fKVxuIiwib3BlbiBDTUxfU3ludGF4XG5vcGVuIERhdGF0eXBlc1xub3BlbiBMaXN0XG5cbigqKiB2YWwgbGlzdF9jb25qIDogY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgKiopXG5cbmxldCByZWMgbGlzdF9jb25qID0gZnVuY3Rpb25cbnwgW10gLT4gY29xX1RvcFxufCBoIDo6IHQgLT4gY29xX0FuZCBoIChsaXN0X2NvbmogdClcblxuKCoqIHZhbCBsaXN0X2Rpc2ogOiBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiAqKilcblxubGV0IHJlYyBsaXN0X2Rpc2ogPSBmdW5jdGlvblxufCBbXSAtPiBCb3RcbnwgaCA6OiB0IC0+IGNvcV9PciBoIChsaXN0X2Rpc2ogdClcblxuKCoqIHZhbCBsaXN0X3Byb3BfRiA6IGNvcV9NUHJvcEYgLT4gY29xX01Qcm9wRiBsaXN0ICoqKVxuXG5sZXQgbGlzdF9wcm9wX0YgPSBmdW5jdGlvblxufCBWYXIgcCAtPiAoVmFyIHApIDo6IFtdXG58IF8gLT4gW11cblxuKCoqIHZhbCBsaXN0X3Byb3BfTEYgOiBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiBsaXN0ICoqKVxuXG5sZXQgcmVjIGxpc3RfcHJvcF9MRiA9IGZ1bmN0aW9uXG58IFtdIC0+IFtdXG58IGggOjogdCAtPiBhcHAgKGxpc3RfcHJvcF9GIGgpIChsaXN0X3Byb3BfTEYgdClcblxuKCoqIHZhbCByZXN0cl9saXN0X3Byb3AgOiBjaGFyIGxpc3QgLT4gY29xX01Qcm9wRiBsaXN0IC0+IGNvcV9NUHJvcEYgbGlzdCAqKilcblxubGV0IHJlc3RyX2xpc3RfcHJvcCBwIGwgPVxuICByZW1vdmUgZXFfZGVjX2Zvcm0gKFZhciBwKSAobGlzdF9wcm9wX0xGIGwpXG4iLCJvcGVuIENNTF9TeW50YXhcbm9wZW4gRGF0YXR5cGVzXG5vcGVuIEdMU19jYWxjc1xub3BlbiBMaXN0XG5cbigqKiB2YWwgbm9kdXBzZXEgOiBjb3FfU2VxIC0+IGNvcV9NUHJvcEYgbGlzdCAqIGNvcV9NUHJvcEYgbGlzdCAqKilcblxubGV0IG5vZHVwc2VxIHMgPVxuICAoKG5vZHVwIGVxX2RlY19mb3JtIChmc3QgcykpLCAobm9kdXAgZXFfZGVjX2Zvcm0gKHNuZCBzKSkpXG4iLCJvcGVuIENNTF9TeW50YXhcbm9wZW4gQ29tcGFyZV9kZWNcbm9wZW4gRGF0YXR5cGVzXG5vcGVuIEdMU19jYWxjc1xub3BlbiBHTFNfZGVjXG5vcGVuIEdMU190ZXJtaW5hdGlvbl9tZWFzdXJlXG5vcGVuIExpc3Rcbm9wZW4gVUlHTF9DYW5vcHlcbm9wZW4gVUlHTF9MZXhTZXFcbm9wZW4gVUlHTF9iYXNpY3Ncbm9wZW4gVUlHTF9ub2R1cHNlcVxuXG50eXBlIF9fID0gT2JqLnRcbmxldCBfXyA9IGxldCByZWMgZiBfID0gT2JqLnJlcHIgZiBpbiBPYmoucmVwciBmXG5cbigqKiB2YWwgaW1hcCA6ICgnYTEgLT4gX18gLT4gJ2EyKSAtPiAnYTEgbGlzdCAtPiAnYTIgbGlzdCAqKilcblxubGV0IHJlYyBpbWFwIGYgPSBmdW5jdGlvblxufCBbXSAtPiBbXVxufCB4IDo6IGwwIC0+IChmIHggX18pIDo6IChpbWFwIGYgbDApXG5cbigqKiB2YWwgY29xX0dVSV90b3QgOiBjaGFyIGxpc3QgLT4gY29xX1NlcSAtPiBjb3FfTVByb3BGICoqKVxuXG5sZXQgY29xX0dVSV90b3QgcCA9XG4gIGNvcV9MZXhTZXFfaW5kIChmdW4gcyBpSCAtPlxuICAgIGxldCBzMCA9IGVtcHR5X3NlcV9kZWMgcyBpblxuICAgIChtYXRjaCBzMCB3aXRoXG4gICAgIHwgQ29xX2lubCBfIC0+IEJvdFxuICAgICB8IENvcV9pbnIgXyAtPlxuICAgICAgIGxldCBzMSA9IGNyaXRpY2FsX1NlcV9kZWMgcyBpblxuICAgICAgIChtYXRjaCBzMSB3aXRoXG4gICAgICAgIHwgQ29xX2lubCBfIC0+XG4gICAgICAgICAgbGV0IHMyID0gZGVjX2luaXRfcnVsZXMgcyBpblxuICAgICAgICAgIChtYXRjaCBzMiB3aXRoXG4gICAgICAgICAgIHwgQ29xX2lubCBfIC0+IGNvcV9Ub3BcbiAgICAgICAgICAgfCBDb3FfaW5yIF8gLT5cbiAgICAgICAgICAgICBsZXQgaDAgPSBmdW4geCAtPiBpSCB4IF9fIGluXG4gICAgICAgICAgICAgbGV0IHMzID0gZnVuIF8gLT5cbiAgICAgICAgICAgICAgIGltYXAgKGZ1biB4IF8gLT4gaDAgeCkgKGNvcV9HTFJfcHJlbXMgKG5vZHVwc2VxIHMpKVxuICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgbGV0IHM0ID0gczMgX18gaW5cbiAgICAgICAgICAgICBsZXQgajEwID0gZnVuIHogLT5cbiAgICAgICAgICAgICAgIGxldCBzNSA9IGRlY19pbml0X3J1bGVzIHogaW5cbiAgICAgICAgICAgICAgIChtYXRjaCBzNSB3aXRoXG4gICAgICAgICAgICAgICAgfCBDb3FfaW5sIF8gLT4gY29xX1RvcFxuICAgICAgICAgICAgICAgIHwgQ29xX2luciBfIC0+XG4gICAgICAgICAgICAgICAgICBsZXQgczYgPVxuICAgICAgICAgICAgICAgICAgICBsdF9kZWMgKGxlbmd0aCAodXNhYmxlX2JveGVzIHopKSAobGVuZ3RoICh1c2FibGVfYm94ZXMgcykpXG4gICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgaWYgczZcbiAgICAgICAgICAgICAgICAgIHRoZW4gaUggeiBfX1xuICAgICAgICAgICAgICAgICAgZWxzZSBsZXQgajEwMCA9IGZ1biB4MCAtPiBpSCB4MCBfXyBpblxuICAgICAgICAgICAgICAgICAgICAgICBsZXQgczcgPSBmdW4gXyAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgIGltYXAgKGZ1biB4MCBfIC0+IGoxMDAgeDApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAoY29xX0dMUl9wcmVtcyAobm9kdXBzZXEgeikpXG4gICAgICAgICAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICAgICAgICAgIGxldCBzOCA9IHM3IF9fIGluXG4gICAgICAgICAgICAgICAgICAgICAgIGNvcV9PciAobGlzdF9kaXNqIChyZXN0cl9saXN0X3Byb3AgcCAoc25kIHopKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAoY29xX09yXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAobGlzdF9kaXNqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXAgY29xX05lZyAocmVzdHJfbGlzdF9wcm9wIHAgKGZzdCB6KSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxpc3RfZGlzaiAobWFwIChmdW4geCAtPiBCb3ggeCkgczgpKSkpXG4gICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICBsZXQgczUgPSBmdW4gXyAtPlxuICAgICAgICAgICAgICAgaW1hcCAoZnVuIHogXyAtPiBqMTAgeilcbiAgICAgICAgICAgICAgICAgKGNvcV9DYW5vcHlcbiAgICAgICAgICAgICAgICAgICAobm9kdXBzZXEgKChjb3FfWEJveGVkX2xpc3QgKHRvcF9ib3hlcyAoZnN0IHMpKSksIFtdKSkpXG4gICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICBsZXQgczYgPSBzNSBfXyBpblxuICAgICAgICAgICAgIGNvcV9PciAobGlzdF9kaXNqIChyZXN0cl9saXN0X3Byb3AgcCAoc25kIHMpKSlcbiAgICAgICAgICAgICAgIChjb3FfT3IgKGxpc3RfZGlzaiAobWFwIGNvcV9OZWcgKHJlc3RyX2xpc3RfcHJvcCBwIChmc3QgcykpKSlcbiAgICAgICAgICAgICAgICAgKGNvcV9PciAobGlzdF9kaXNqIChtYXAgKGZ1biB4IC0+IEJveCB4KSBzNCkpXG4gICAgICAgICAgICAgICAgICAgKGNvcV9EaWFtIChsaXN0X2NvbmogczYpKSkpKVxuICAgICAgICB8IENvcV9pbnIgXyAtPlxuICAgICAgICAgIGxldCBoID0gZnVuIHggLT4gaUggeCBfXyBpblxuICAgICAgICAgIGxldCBzMiA9IGZ1biBfIC0+IGltYXAgKGZ1biB4IF8gLT4gaCB4KSAoY29xX0Nhbm9weSAobm9kdXBzZXEgcykpIGluXG4gICAgICAgICAgbGV0IHMzID0gczIgX18gaW4gbGlzdF9jb25qIHMzKSkpXG4iLCJvcGVuIERhdGF0eXBlc1xuXG50eXBlIF9fID0gT2JqLnRcbmxldCBfXyA9IGxldCByZWMgZiBfID0gT2JqLnJlcHIgZiBpbiBPYmoucmVwciBmXG5cbigqKiB2YWwgbGlzdF9pc19uaWwgOiAnYTEgbGlzdCAtPiBib29sICoqKVxuXG5sZXQgbGlzdF9pc19uaWwgPSBmdW5jdGlvblxufCBbXSAtPiB0cnVlXG58IF8gOjogXyAtPiBmYWxzZVxuXG4oKiogdmFsIGZsYXRtYXAgOiAoJ2ExIC0+IF9fIC0+ICdhMSBsaXN0KSAtPiAnYTEgbGlzdCAtPiAnYTEgbGlzdCAqKilcblxubGV0IHJlYyBmbGF0bWFwIGYgPSBmdW5jdGlvblxufCBbXSAtPiBbXVxufCB4IDo6IGwwIC0+IGFwcCAoZiB4IF9fKSAoZmxhdG1hcCBmIGwwKVxuXG4oKiogdmFsIGlycmVkIDogKCdhMSAtPiAnYTEgbGlzdCkgLT4gJ2ExIC0+ICdhMSBsaXN0ICoqKVxuXG5sZXQgcmVjIGlycmVkIGYgeCA9XG4gIGlmIGxpc3RfaXNfbmlsIChmIHgpIHRoZW4geCA6OiBbXSBlbHNlIGZsYXRtYXAgKGZ1biB5IF8gLT4gaXJyZWQgZiB5KSAoZiB4KVxuIiwib3BlbiBDTUxfU3ludGF4XG5vcGVuIERhdGF0eXBlc1xub3BlbiBLU19jYWxjXG5vcGVuIEtTX3Rlcm1pbmF0aW9uX0ltcExcbm9wZW4gS1NfdGVybWluYXRpb25fSW1wUlxub3BlbiBLU190ZXJtaW5hdGlvbl9wcmVsaW1zXG5vcGVuIExpc3RfbGVtbWFzVFxub3BlbiBTcGVjaWZcbm9wZW4gVUlLX2lycmVkX3Nob3J0XG5vcGVuIEdlblRcblxudHlwZSBfXyA9IE9iai50XG5sZXQgX18gPSBsZXQgcmVjIGYgXyA9IE9iai5yZXByIGYgaW4gT2JqLnJlcHIgZlxuXG4oKiogdmFsIGZpbml0ZV9JbXBSdWxlc19wcmVtaXNlc19vZl9TIDpcbiAgICBjb3FfU2VxIC0+IChjb3FfU2VxIGxpc3QgbGlzdCwgY29xX1NlcSBsaXN0IC0+ICgoY29xX0ltcFJSdWxlLFxuICAgIGNvcV9JbXBMUnVsZSkgc3VtIC0+IGNvcV9TZXEgbGlzdCBjb3FfSW5UKSAqIChjb3FfU2VxIGxpc3QgY29xX0luVCAtPlxuICAgIChjb3FfSW1wUlJ1bGUsIGNvcV9JbXBMUnVsZSkgc3VtKSkgc2lnVCAqKilcblxubGV0IGZpbml0ZV9JbXBSdWxlc19wcmVtaXNlc19vZl9TIHMgPVxuICBsZXQgczAgPSBmaW5pdGVfSW1wUl9wcmVtaXNlc19vZl9TIHMgaW5cbiAgbGV0IENvcV9leGlzdFQgKHgsIHApID0gczAgaW5cbiAgbGV0IHMxID0gZmluaXRlX0ltcExfcHJlbWlzZXNfb2ZfUyBzIGluXG4gIGxldCBDb3FfZXhpc3RUICh4MCwgcDApID0gczEgaW5cbiAgQ29xX2V4aXN0VCAoKGFwcCB4IHgwKSwgKGZ1biBwcmVtcyAtPiAoKGZ1biBoIC0+XG4gIG1hdGNoIGggd2l0aFxuICB8IENvcV9pbmwgaSAtPlxuICAgIGxldCBJbXBSUnVsZV9JIChhLCBiLCBfVVUwMzkzXzAsIF9VVTAzOTNfMSwgX1VVMDM5NF8wLCBfVVUwMzk0XzEpID0gaSBpblxuICAgIGNvcV9JblRfb3JfYXBwIHggeDAgKCgoYXBwIF9VVTAzOTNfMCAoYSA6OiBfVVUwMzkzXzEpKSxcbiAgICAgIChhcHAgX1VVMDM5NF8wIChiIDo6IF9VVTAzOTRfMSkpKSA6OiBbXSkgKENvcV9pbmxcbiAgICAgIChsZXQgcHJlbXMwID0gKChhcHAgX1VVMDM5M18wIChhIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgICAgKGFwcCBfVVUwMzk0XzAgKGIgOjogX1VVMDM5NF8xKSkpIDo6IFtdXG4gICAgICAgaW5cbiAgICAgICBsZXQgKHgxLCBfKSA9IHAgcHJlbXMwIGluXG4gICAgICAgeDEgKEltcFJSdWxlX0kgKGEsIGIsIF9VVTAzOTNfMCwgX1VVMDM5M18xLCBfVVUwMzk0XzAsIF9VVTAzOTRfMSkpKSlcbiAgfCBDb3FfaW5yIGkgLT5cbiAgICBsZXQgSW1wTFJ1bGVfSSAoYSwgYiwgX1VVMDM5M18wLCBfVVUwMzkzXzEsIF9VVTAzOTRfMCwgX1VVMDM5NF8xKSA9IGkgaW5cbiAgICBjb3FfSW5UX29yX2FwcCB4IHgwICgoKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKSxcbiAgICAgIChhcHAgX1VVMDM5NF8wIChhIDo6IF9VVTAzOTRfMSkpKSA6OiAoKChhcHAgX1VVMDM5M18wIChiIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkgOjogW10pKSAoQ29xX2luclxuICAgICAgKGxldCBwcmVtczAgPSAoKGFwcCBfVVUwMzkzXzAgX1VVMDM5M18xKSxcbiAgICAgICAgIChhcHAgX1VVMDM5NF8wIChhIDo6IF9VVTAzOTRfMSkpKSA6OiAoKChhcHAgX1VVMDM5M18wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChiIDo6IF9VVTAzOTNfMSkpLFxuICAgICAgICAgKGFwcCBfVVUwMzk0XzAgX1VVMDM5NF8xKSkgOjogW10pXG4gICAgICAgaW5cbiAgICAgICBsZXQgKHgxLCBfKSA9IHAwIHByZW1zMCBpblxuICAgICAgIHgxIChJbXBMUnVsZV9JIChhLCBiLCBfVVUwMzkzXzAsIF9VVTAzOTNfMSwgX1VVMDM5NF8wLCBfVVUwMzk0XzEpKSkpKSxcbiAgKGZ1biBoIC0+XG4gIGxldCBoMCA9IGNvcV9JblRfYXBwX29yIHggeDAgcHJlbXMgaCBpblxuICAobWF0Y2ggaDAgd2l0aFxuICAgfCBDb3FfaW5sIGkgLT4gQ29xX2lubCAobGV0IChfLCB4MSkgPSBwIHByZW1zIGluIHgxIGkpXG4gICB8IENvcV9pbnIgaSAtPiBDb3FfaW5yIChsZXQgKF8sIHgxKSA9IHAwIHByZW1zIGluIHgxIGkpKSkpKSlcblxuKCoqIHZhbCBpbnZfcHJlbXMgOiBjb3FfU2VxIC0+IGNvcV9TZXEgbGlzdCAqKilcblxubGV0IGludl9wcmVtcyBzID1cbiAgZmxhdHRlbl9saXN0IChwcm9qMV9zaWdUMiAoZmluaXRlX0ltcFJ1bGVzX3ByZW1pc2VzX29mX1MgcykpXG5cbigqKiB2YWwgY29xX0Nhbm9weSA6IGNvcV9TZXEgLT4gY29xX1NlcSBsaXN0ICoqKVxuXG5sZXQgY29xX0Nhbm9weSA9XG4gIGlycmVkIGludl9wcmVtc1xuXG4oKiogdmFsIGlzX1ByaW1lX2RlYyA6IGNvcV9NUHJvcEYgbGlzdCAtPiAoX18sIF9fKSBzdW0gKiopXG5cbmxldCByZWMgaXNfUHJpbWVfZGVjID0gZnVuY3Rpb25cbnwgW10gLT4gQ29xX2lubCBfX1xufCB5IDo6IGwwIC0+XG4gIChtYXRjaCBpc19QcmltZV9kZWMgbDAgd2l0aFxuICAgfCBDb3FfaW5sIF8gLT4gKG1hdGNoIHkgd2l0aFxuICAgICAgICAgICAgICAgICAgIHwgSW1wIChfLCBfKSAtPiBDb3FfaW5yIF9fXG4gICAgICAgICAgICAgICAgICAgfCBfIC0+IENvcV9pbmwgX18pXG4gICB8IENvcV9pbnIgXyAtPiBDb3FfaW5yIF9fKVxuXG4oKiogdmFsIGNyaXRpY2FsX1NlcV9kZWMgOiBjb3FfU2VxIC0+IChfXywgX18pIHN1bSAqKilcblxubGV0IGNyaXRpY2FsX1NlcV9kZWMgPSBmdW5jdGlvblxufCAobCwgbDApIC0+IGlzX1ByaW1lX2RlYyAoYXBwIGwgbDApXG4iLCJvcGVuIENNTF9TeW50YXhcbm9wZW4gRGF0YXR5cGVzXG5vcGVuIEtTX2NhbGNcbm9wZW4gS1NfdGVybWluYXRpb25fS1Jcbm9wZW4gS1NfdGVybWluYXRpb25fcHJlbGltc1xub3BlbiBMaXN0XG5cbnR5cGUgX18gPSBPYmoudFxubGV0IF9fID0gbGV0IHJlYyBmIF8gPSBPYmoucmVwciBmIGluIE9iai5yZXByIGZcblxuKCoqIHZhbCBsaXN0X2NvbmogOiBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiAqKilcblxubGV0IHJlYyBsaXN0X2NvbmogPSBmdW5jdGlvblxufCBbXSAtPiBjb3FfVG9wXG58IGggOjogdCAtPiBjb3FfQW5kIGggKGxpc3RfY29uaiB0KVxuXG4oKiogdmFsIGxpc3RfZGlzaiA6IGNvcV9NUHJvcEYgbGlzdCAtPiBjb3FfTVByb3BGICoqKVxuXG5sZXQgcmVjIGxpc3RfZGlzaiA9IGZ1bmN0aW9uXG58IFtdIC0+IEJvdFxufCBoIDo6IHQgLT4gY29xX09yIGggKGxpc3RfZGlzaiB0KVxuXG4oKiogdmFsIGxpc3RfcHJvcF9GIDogY29xX01Qcm9wRiAtPiBjb3FfTVByb3BGIGxpc3QgKiopXG5cbmxldCBsaXN0X3Byb3BfRiA9IGZ1bmN0aW9uXG58IFZhciBwIC0+IChWYXIgcCkgOjogW11cbnwgXyAtPiBbXVxuXG4oKiogdmFsIGxpc3RfcHJvcF9MRiA6IGNvcV9NUHJvcEYgbGlzdCAtPiBjb3FfTVByb3BGIGxpc3QgKiopXG5cbmxldCByZWMgbGlzdF9wcm9wX0xGID0gZnVuY3Rpb25cbnwgW10gLT4gW11cbnwgaCA6OiB0IC0+IGFwcCAobGlzdF9wcm9wX0YgaCkgKGxpc3RfcHJvcF9MRiB0KVxuXG4oKiogdmFsIHJlc3RyX2xpc3RfcHJvcCA6IGNoYXIgbGlzdCAtPiBjb3FfTVByb3BGIGxpc3QgLT4gY29xX01Qcm9wRiBsaXN0ICoqKVxuXG5sZXQgcmVzdHJfbGlzdF9wcm9wIHAgbCA9XG4gIHJlbW92ZSBlcV9kZWNfZm9ybSAoVmFyIHApIChsaXN0X3Byb3BfTEYgbClcblxuKCoqIHZhbCBjb3FfS1JfcHJlbXMgOiBjb3FfU2VxIC0+IGNvcV9TZXEgbGlzdCAqKilcblxubGV0IGNvcV9LUl9wcmVtcyBzID1cbiAgZmxhdHRlbl9saXN0IChwcm9qMV9zaWdUMiAoZmluaXRlX0tSX3ByZW1pc2VzX29mX1MgcykpXG5cbigqKiB2YWwgY29xX0x0U2VxX2luZCA6XG4gICAgKGNvcV9TZXEgLT4gKGNvcV9TZXEgLT4gX18gLT4gJ2ExKSAtPiAnYTEpIC0+IGNvcV9TZXEgLT4gJ2ExICoqKVxuXG5sZXQgcmVjIGNvcV9MdFNlcV9pbmQgeCBzID1cbiAgeCBzIChmdW4gczEgXyAtPiBjb3FfTHRTZXFfaW5kIHggczEpXG5cbigqKiB2YWwgZW1wdHlfc2VxX2RlYyA6IGNvcV9TZXEgLT4gKF9fLCBfXykgc3VtICoqKVxuXG5sZXQgZW1wdHlfc2VxX2RlYyA9IGZ1bmN0aW9uXG58IChsLCBsMCkgLT5cbiAgKG1hdGNoIGwgd2l0aFxuICAgfCBbXSAtPiAobWF0Y2ggbDAgd2l0aFxuICAgICAgICAgICAgfCBbXSAtPiBDb3FfaW5sIF9fXG4gICAgICAgICAgICB8IF8gOjogXyAtPiBDb3FfaW5yIF9fKVxuICAgfCBfIDo6IF8gLT4gQ29xX2luciBfXylcbiIsIm9wZW4gQ01MX1N5bnRheFxub3BlbiBEYXRhdHlwZXNcbm9wZW4gS1NfY2FsY1xub3BlbiBLU19kZWNcbm9wZW4gTGlzdFxub3BlbiBVSUtfQ2Fub3B5XG5vcGVuIFVJS19iYXNpY3Ncbm9wZW4gTGlzdF9sZW1zXG5cbnR5cGUgX18gPSBPYmoudFxubGV0IF9fID0gbGV0IHJlYyBmIF8gPSBPYmoucmVwciBmIGluIE9iai5yZXByIGZcblxuKCoqIHZhbCBpbWFwIDogKCdhMSAtPiBfXyAtPiAnYTIpIC0+ICdhMSBsaXN0IC0+ICdhMiBsaXN0ICoqKVxuXG5sZXQgcmVjIGltYXAgZiA9IGZ1bmN0aW9uXG58IFtdIC0+IFtdXG58IHggOjogbDAgLT4gKGYgeCBfXykgOjogKGltYXAgZiBsMClcblxuKCoqIHZhbCBjb3FfR1VJX3RvdCA6IGNoYXIgbGlzdCAtPiBjb3FfU2VxIC0+IGNvcV9NUHJvcEYgKiopXG5cbmxldCBjb3FfR1VJX3RvdCBwID1cbiAgY29xX0x0U2VxX2luZCAoZnVuIHMgaUggLT5cbiAgICBsZXQgczAgPSBlbXB0eV9zZXFfZGVjIHMgaW5cbiAgICAobWF0Y2ggczAgd2l0aFxuICAgICB8IENvcV9pbmwgXyAtPiBCb3RcbiAgICAgfCBDb3FfaW5yIF8gLT5cbiAgICAgICBsZXQgczEgPSBjcml0aWNhbF9TZXFfZGVjIHMgaW5cbiAgICAgICAobWF0Y2ggczEgd2l0aFxuICAgICAgICB8IENvcV9pbmwgXyAtPlxuICAgICAgICAgIGxldCBzMiA9IGRlY19LU19pbml0X3J1bGVzIHMgaW5cbiAgICAgICAgICAobWF0Y2ggczIgd2l0aFxuICAgICAgICAgICB8IENvcV9pbmwgXyAtPiBjb3FfVG9wXG4gICAgICAgICAgIHwgQ29xX2luciBfIC0+XG4gICAgICAgICAgICAgbGV0IGgwID0gZnVuIHggLT4gaUggeCBfXyBpblxuICAgICAgICAgICAgIGxldCBzMyA9IGZ1biBfIC0+IGltYXAgKGZ1biB4IF8gLT4gaDAgeCkgKGNvcV9LUl9wcmVtcyBzKSBpblxuICAgICAgICAgICAgIGxldCBzNCA9IHMzIF9fIGluXG4gICAgICAgICAgICAgbGV0IHM1ID0gZXFfZGVjX2xpc3RzRiAoZnN0IHMpIFtdIGluXG4gICAgICAgICAgICAgaWYgczVcbiAgICAgICAgICAgICB0aGVuIGNvcV9PciAobGlzdF9kaXNqIChyZXN0cl9saXN0X3Byb3AgcCAoc25kIHMpKSlcbiAgICAgICAgICAgICAgICAgICAgKGNvcV9PclxuICAgICAgICAgICAgICAgICAgICAgIChsaXN0X2Rpc2ogKG1hcCBjb3FfTmVnIChyZXN0cl9saXN0X3Byb3AgcCAoZnN0IHMpKSkpXG4gICAgICAgICAgICAgICAgICAgICAgKGNvcV9PciAobGlzdF9kaXNqIChtYXAgKGZ1biB4IC0+IEJveCB4KSBzNCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAoY29xX0RpYW0gQm90KSkpXG4gICAgICAgICAgICAgZWxzZSBsZXQgajEwID0gaUggKCh1bmJveGVkX2xpc3QgKHRvcF9ib3hlcyAoZnN0IHMpKSksIFtdKSBfXyBpblxuICAgICAgICAgICAgICAgICAgY29xX09yIChsaXN0X2Rpc2ogKHJlc3RyX2xpc3RfcHJvcCBwIChzbmQgcykpKVxuICAgICAgICAgICAgICAgICAgICAoY29xX09yXG4gICAgICAgICAgICAgICAgICAgICAgKGxpc3RfZGlzaiAobWFwIGNvcV9OZWcgKHJlc3RyX2xpc3RfcHJvcCBwIChmc3QgcykpKSlcbiAgICAgICAgICAgICAgICAgICAgICAoY29xX09yIChsaXN0X2Rpc2ogKG1hcCAoZnVuIHggLT4gQm94IHgpIHM0KSlcbiAgICAgICAgICAgICAgICAgICAgICAgIChjb3FfRGlhbSBqMTApKSkpXG4gICAgICAgIHwgQ29xX2luciBfIC0+XG4gICAgICAgICAgbGV0IGggPSBmdW4geCAtPiBpSCB4IF9fIGluXG4gICAgICAgICAgbGV0IHMyID0gZnVuIF8gLT4gaW1hcCAoZnVuIHggXyAtPiBoIHgpIChjb3FfQ2Fub3B5IHMpIGluXG4gICAgICAgICAgbGV0IHMzID0gczIgX18gaW4gbGlzdF9jb25qIHMzKSkpXG4iLCJvcGVuIENNTF9TeW50YXhcbm9wZW4gRm9ybXVsYXNcbm9wZW4gUHJvcFF1YW50aWZpZXJzXG5vcGVuIFNpbXBcbm9wZW4gVUlHTF9icmFnYVxub3BlbiBVSUtfYnJhZ2FcblxuKCoqIHZhbCBjb3FfTVByb3BGX29mX2Zvcm0gOiBmb3JtIC0+IGNvcV9NUHJvcEYgKiopXG5cbmxldCByZWMgY29xX01Qcm9wRl9vZl9mb3JtID0gZnVuY3Rpb25cbnwgVmFyIG4gLT4gQ01MX1N5bnRheC5WYXIgblxufCBCb3QgLT4gQ01MX1N5bnRheC5Cb3RcbnwgQW5kIChmMSwgZjIpIC0+XG4gIEltcCAoKEltcCAoKGNvcV9NUHJvcEZfb2ZfZm9ybSBmMSksIChJbXAgKChjb3FfTVByb3BGX29mX2Zvcm0gZjIpLFxuICAgIENNTF9TeW50YXguQm90KSkpKSwgQ01MX1N5bnRheC5Cb3QpXG58IE9yIChmMSwgZjIpIC0+XG4gIEltcCAoKEltcCAoKGNvcV9NUHJvcEZfb2ZfZm9ybSBmMSksIENNTF9TeW50YXguQm90KSksXG4gICAgKGNvcV9NUHJvcEZfb2ZfZm9ybSBmMikpXG58IEltcGxpZXMgKGYxLCBmMikgLT4gSW1wICgoY29xX01Qcm9wRl9vZl9mb3JtIGYxKSwgKGNvcV9NUHJvcEZfb2ZfZm9ybSBmMikpXG58IEJveCBmMCAtPiBDTUxfU3ludGF4LkJveCAoY29xX01Qcm9wRl9vZl9mb3JtIGYwKVxuXG4oKiogdmFsIGZvcm1fb2ZfTVByb3BGIDogY29xX01Qcm9wRiAtPiBmb3JtICoqKVxuXG5sZXQgcmVjIGZvcm1fb2ZfTVByb3BGID0gZnVuY3Rpb25cbnwgQ01MX1N5bnRheC5WYXIgbiAtPiBWYXIgblxufCBDTUxfU3ludGF4LkJvdCAtPiBCb3RcbnwgSW1wIChmMSwgZjIpIC0+IEltcGxpZXMgKChmb3JtX29mX01Qcm9wRiBmMSksIChmb3JtX29mX01Qcm9wRiBmMikpXG58IENNTF9TeW50YXguQm94IGYwIC0+IEJveCAoZm9ybV9vZl9NUHJvcEYgZjApXG5cbigqKiB2YWwgZ2xfVUkgOiBjaGFyIGxpc3QgLT4gZm9ybSAtPiBmb3JtICoqKVxuXG5sZXQgZ2xfVUkgcCBzID1cbiAgZm9ybV9vZl9NUHJvcEZcbiAgICAoVUlHTF9icmFnYS5jb3FfR1VJX3RvdCBwIChbXSwgKChjb3FfTVByb3BGX29mX2Zvcm0gcykgOjogW10pKSlcblxuKCoqIHZhbCBrX1VJIDogY2hhciBsaXN0IC0+IGZvcm0gLT4gZm9ybSAqKilcblxubGV0IGtfVUkgcCBzID1cbiAgZm9ybV9vZl9NUHJvcEYgKGNvcV9HVUlfdG90IHAgKFtdLCAoKGNvcV9NUHJvcEZfb2ZfZm9ybSBzKSA6OiBbXSkpKVxuXG4oKiogdmFsIGlzbF9FIDogdmFyaWFibGUgLT4gZm9ybSAtPiBmb3JtICoqKVxuXG5sZXQgaXNsX0UgPVxuICBjb3FfRWZcblxuKCoqIHZhbCBpc2xfQSA6IHZhcmlhYmxlIC0+IGZvcm0gLT4gZm9ybSAqKilcblxubGV0IGlzbF9BID1cbiAgY29xX0FmXG5cbigqKiB2YWwgaXNsX3NpbXAgOiBmb3JtIC0+IGZvcm0gKiopXG5cbmxldCBpc2xfc2ltcCA9XG4gIHNpbXBcblxuKCoqIHZhbCBpc2xfc2ltcGxpZmllZF9FIDogdmFyaWFibGUgLT4gZm9ybSAtPiBmb3JtICoqKVxuXG5sZXQgaXNsX3NpbXBsaWZpZWRfRSA9XG4gIGNvcV9FX3NpbXBsaWZpZWRcblxuKCoqIHZhbCBpc2xfc2ltcGxpZmllZF9BIDogdmFyaWFibGUgLT4gZm9ybSAtPiBmb3JtICoqKVxuXG5sZXQgaXNsX3NpbXBsaWZpZWRfQSA9XG4gIGNvcV9BX3NpbXBsaWZpZWRcbiIsIm9wZW4gRGF0YXR5cGVzXG5vcGVuIEVudmlyb25tZW50c1xub3BlbiBGb3JtdWxhc1xub3BlbiBMaXN0XG5vcGVuIFNwZWNpZlxub3BlbiBCYXNlXG5vcGVuIExpc3QwXG5cbnR5cGUgX18gPSBPYmoudFxubGV0IF9fID0gbGV0IHJlYyBmIF8gPSBPYmoucmVwciBmIGluIE9iai5yZXByIGZcblxuKCoqIHZhbCBleGlzdHNfZGVjIDogKCdhMSAtPiBib29sKSAtPiAnYTEgbGlzdCAtPiAoJ2ExLCBfXykgc2lnVCBvcHRpb24gKiopXG5cbmxldCByZWMgZXhpc3RzX2RlYyBwID0gZnVuY3Rpb25cbnwgW10gLT4gTm9uZVxufCB5IDo6IGwwIC0+XG4gIGlmIHAgeVxuICB0aGVuIFNvbWUgKENvcV9leGlzdFQgKHksIF9fKSlcbiAgZWxzZSAobWF0Y2ggZXhpc3RzX2RlYyBwIGwwIHdpdGhcbiAgICAgICAgfCBTb21lIHMgLT4gbGV0IENvcV9leGlzdFQgKHgsIF8pID0gcyBpbiBTb21lIChDb3FfZXhpc3RUICh4LCBfXykpXG4gICAgICAgIHwgTm9uZSAtPiBOb25lKVxuXG4oKiogdmFsIGNvcV9Qcm92YWJsZV9kZWMgOiBmb3JtIGxpc3QgLT4gZm9ybSAtPiAoX18sIF9fKSBzdW0gKiopXG5cbmxldCBjb3FfUHJvdmFibGVfZGVjIF9VVTAzOTNfIF9VVTAzYzZfID1cbiAgbGV0IHBlID0gKF9VVTAzOTNfLCBfVVUwM2M2XykgaW5cbiAgbGV0IHJlYyBmID0gZnVuY3Rpb25cbiAgfCAobCwgZjApIC0+XG4gICAgbGV0IGhpbmQnID0gZnVuIF9VVTAzOTNfJyBfVVUwM2M2XycgLT4gZiAoX1VVMDM5M18nLCBfVVUwM2M2XycpIGluXG4gICAgaWYgZGVjaWRlIChkZWNpZGVfcmVsIChlbGVtX29mX2xpc3RfZGVjIGZvcm1fZXFfZGVjKSBCb3QgbClcbiAgICB0aGVuIENvcV9pbmwgX19cbiAgICBlbHNlIGxldCBoQW5kUiA9XG4gICAgICAgICAgIG1hdGNoIGYwIHdpdGhcbiAgICAgICAgICAgfCBWYXIgXyAtPiBOb25lXG4gICAgICAgICAgIHwgQm90IC0+IE5vbmVcbiAgICAgICAgICAgfCBBbmQgKGYxLCBmMikgLT4gU29tZSAoQ29xX2V4aXN0VCAoZjEsIChDb3FfZXhpc3RUIChmMiwgX18pKSkpXG4gICAgICAgICAgIHwgXyAtPiBOb25lXG4gICAgICAgICBpblxuICAgICAgICAgKG1hdGNoIGhBbmRSIHdpdGhcbiAgICAgICAgICB8IFNvbWUgcyAtPlxuICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgwLCBzMCkgPSBzIGluXG4gICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDEsIF8pID0gczAgaW5cbiAgICAgICAgICAgIGxldCBzMSA9IGhpbmQnIGwgeDAgaW5cbiAgICAgICAgICAgIChtYXRjaCBzMSB3aXRoXG4gICAgICAgICAgICAgfCBDb3FfaW5sIF8gLT5cbiAgICAgICAgICAgICAgIGxldCBzMiA9IGhpbmQnIGwgeDEgaW5cbiAgICAgICAgICAgICAgIChtYXRjaCBzMiB3aXRoXG4gICAgICAgICAgICAgICAgfCBDb3FfaW5sIF8gLT4gQ29xX2lubCBfX1xuICAgICAgICAgICAgICAgIHwgQ29xX2luciBfIC0+IENvcV9pbnIgX18pXG4gICAgICAgICAgICAgfCBDb3FfaW5yIF8gLT4gQ29xX2luciBfXylcbiAgICAgICAgICB8IE5vbmUgLT5cbiAgICAgICAgICAgIGxldCBodmFyID1cbiAgICAgICAgICAgICAgbWF0Y2ggZjAgd2l0aFxuICAgICAgICAgICAgICB8IFZhciB2IC0+XG4gICAgICAgICAgICAgICAgaWYgZGVjaWRlXG4gICAgICAgICAgICAgICAgICAgICAoZGVjaWRlX3JlbCAoZWxlbV9vZl9saXN0X2RlYyBmb3JtX2VxX2RlYykgKFZhciB2KSBsKVxuICAgICAgICAgICAgICAgIHRoZW4gU29tZSAoQ29xX2V4aXN0VDIgKHYsIF9fLCBfXykpXG4gICAgICAgICAgICAgICAgZWxzZSBOb25lXG4gICAgICAgICAgICAgIHwgXyAtPiBOb25lXG4gICAgICAgICAgICBpblxuICAgICAgICAgICAgKG1hdGNoIGh2YXIgd2l0aFxuICAgICAgICAgICAgIHwgU29tZSBfIC0+IENvcV9pbmwgX19cbiAgICAgICAgICAgICB8IE5vbmUgLT5cbiAgICAgICAgICAgICAgIGxldCBoQW5kTCA9XG4gICAgICAgICAgICAgICAgIGxldCBmQSA9IGZ1biBfVVUwM2I4XyAtPlxuICAgICAgICAgICAgICAgICAgIG1hdGNoIF9VVTAzYjhfIHdpdGhcbiAgICAgICAgICAgICAgICAgICB8IEFuZCAoXywgXykgLT4gdHJ1ZVxuICAgICAgICAgICAgICAgICAgIHwgXyAtPiBmYWxzZVxuICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICBsZXQgcyA9IGV4aXN0c19kZWMgZkEgbCBpblxuICAgICAgICAgICAgICAgICAobWF0Y2ggcyB3aXRoXG4gICAgICAgICAgICAgICAgICB8IFNvbWUgczAgLT5cbiAgICAgICAgICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgwLCBfKSA9IHMwIGluXG4gICAgICAgICAgICAgICAgICAgIFNvbWVcbiAgICAgICAgICAgICAgICAgICAgKG1hdGNoIHgwIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgIHwgQW5kIChmMSwgZjIpIC0+IENvcV9leGlzdFQgKGYxLCAoQ29xX2V4aXN0VCAoZjIsIF9fKSkpXG4gICAgICAgICAgICAgICAgICAgICB8IF8gLT4gYXNzZXJ0IGZhbHNlICgqIGFic3VyZCBjYXNlICopKVxuICAgICAgICAgICAgICAgICAgfCBOb25lIC0+IE5vbmUpXG4gICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgKG1hdGNoIGhBbmRMIHdpdGhcbiAgICAgICAgICAgICAgICB8IFNvbWUgcyAtPlxuICAgICAgICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgwLCBzMCkgPSBzIGluXG4gICAgICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDEsIF8pID0gczAgaW5cbiAgICAgICAgICAgICAgICAgIGxldCBzMSA9IGhpbmQnICh4MCA6OiAoeDEgOjogKHJtIChBbmQgKHgwLCB4MSkpIGwpKSkgZjAgaW5cbiAgICAgICAgICAgICAgICAgIChtYXRjaCBzMSB3aXRoXG4gICAgICAgICAgICAgICAgICAgfCBDb3FfaW5sIF8gLT4gQ29xX2lubCBfX1xuICAgICAgICAgICAgICAgICAgIHwgQ29xX2luciBfIC0+IENvcV9pbnIgX18pXG4gICAgICAgICAgICAgICAgfCBOb25lIC0+XG4gICAgICAgICAgICAgICAgICBsZXQgaEltcFIgPVxuICAgICAgICAgICAgICAgICAgICBtYXRjaCBmMCB3aXRoXG4gICAgICAgICAgICAgICAgICAgIHwgVmFyIF8gLT4gTm9uZVxuICAgICAgICAgICAgICAgICAgICB8IEJvdCAtPiBOb25lXG4gICAgICAgICAgICAgICAgICAgIHwgQW5kIChfLCBfKSAtPiBOb25lXG4gICAgICAgICAgICAgICAgICAgIHwgT3IgKF8sIF8pIC0+IE5vbmVcbiAgICAgICAgICAgICAgICAgICAgfCBJbXBsaWVzIChmMSwgZjIpIC0+XG4gICAgICAgICAgICAgICAgICAgICAgU29tZSAoQ29xX2V4aXN0VCAoZjEsIChDb3FfZXhpc3RUIChmMiwgX18pKSkpXG4gICAgICAgICAgICAgICAgICAgIHwgQm94IF8gLT4gTm9uZVxuICAgICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgICAgIChtYXRjaCBoSW1wUiB3aXRoXG4gICAgICAgICAgICAgICAgICAgfCBTb21lIHMgLT5cbiAgICAgICAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MCwgczApID0gcyBpblxuICAgICAgICAgICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgxLCBfKSA9IHMwIGluXG4gICAgICAgICAgICAgICAgICAgICBsZXQgczEgPSBoaW5kJyAoeDAgOjogbCkgeDEgaW5cbiAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBzMSB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgfCBDb3FfaW5sIF8gLT4gQ29xX2lubCBfX1xuICAgICAgICAgICAgICAgICAgICAgIHwgQ29xX2luciBfIC0+IENvcV9pbnIgX18pXG4gICAgICAgICAgICAgICAgICAgfCBOb25lIC0+XG4gICAgICAgICAgICAgICAgICAgICBsZXQgaE9yTCA9XG4gICAgICAgICAgICAgICAgICAgICAgIGxldCBmQSA9IGZ1biBfVVUwM2I4XyAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoIF9VVTAzYjhfIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICB8IE9yIChfLCBfKSAtPiB0cnVlXG4gICAgICAgICAgICAgICAgICAgICAgICAgfCBfIC0+IGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICAgICAgICAgIGxldCBzID0gZXhpc3RzX2RlYyBmQSBsIGluXG4gICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBzIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgIHwgU29tZSBzMCAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDAsIF8pID0gczAgaW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgU29tZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggeDAgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBPciAoZjEsIGYyKSAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb3FfZXhpc3RUIChmMSwgKENvcV9leGlzdFQgKGYyLCBfXykpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBfIC0+IGFzc2VydCBmYWxzZSAoKiBhYnN1cmQgY2FzZSAqKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHwgTm9uZSAtPiBOb25lKVxuICAgICAgICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBoT3JMIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICB8IFNvbWUgcyAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgwLCBzMCkgPSBzIGluXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDEsIF8pID0gczAgaW5cbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzMSA9IGhpbmQnICh4MCA6OiAocm0gKE9yICh4MCwgeDEpKSBsKSkgZjAgaW5cbiAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBzMSB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgfCBDb3FfaW5sIF8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzMiA9IGhpbmQnICh4MSA6OiAocm0gKE9yICh4MCwgeDEpKSBsKSkgZjAgaW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBzMiB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBDb3FfaW5sIF8gLT4gQ29xX2lubCBfX1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQ29xX2luciBfIC0+IENvcV9pbnIgX18pXG4gICAgICAgICAgICAgICAgICAgICAgICAgfCBDb3FfaW5yIF8gLT4gQ29xX2luciBfXylcbiAgICAgICAgICAgICAgICAgICAgICB8IE5vbmUgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBoSW1wTFZhciA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBmSXAgPSBmdW4gcCBfVVUwM2I4XyAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoIF9VVTAzYjhfIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEltcGxpZXMgKGYxLCBfKSAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIGYxIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFZhciBxIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBkZWNpZGUgKGRlY2lkZV9yZWwgc3RyaW5nX2RlYyBwIHEpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIHRydWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IF8gLT4gZmFsc2UpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBfIC0+IGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBmcCA9IGZ1biBfVVUwM2I4XyAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoIF9VVTAzYjhfIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFZhciBwIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggZXhpc3RzX2RlYyAoZklwIHApIGwgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU29tZSBfIC0+IHRydWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IE5vbmUgLT4gZmFsc2UpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBfIC0+IGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzID0gZXhpc3RzX2RlYyBmcCBsIGluXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBzIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU29tZSBzMCAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDAsIF8pID0gczAgaW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU29tZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggeDAgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBWYXIgdiAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgczEgPSBleGlzdHNfZGVjIChmSXAgdikgbCBpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggczEgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTb21lIHMyIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MSwgXykgPSBzMiBpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggeDEgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBJbXBsaWVzIChmMSwgZjIpIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBmMSB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFZhciB2MCAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgczMgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY2lkZSAoZGVjaWRlX3JlbCBzdHJpbmdfZGVjIHYgdjApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIHMzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gQ29xX2V4aXN0VCAodjAsIChDb3FfZXhpc3RUXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZjIsIF9fKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgYXNzZXJ0IGZhbHNlICgqIGFic3VyZCBjYXNlICopXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IF8gLT4gYXNzZXJ0IGZhbHNlICgqIGFic3VyZCBjYXNlICopKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBfIC0+IGFzc2VydCBmYWxzZSAoKiBhYnN1cmQgY2FzZSAqKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgTm9uZSAtPiBhc3NlcnQgZmFsc2UgKCogYWJzdXJkIGNhc2UgKikpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IF8gLT4gYXNzZXJ0IGZhbHNlICgqIGFic3VyZCBjYXNlICopKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBOb25lIC0+IE5vbmUpXG4gICAgICAgICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIGhJbXBMVmFyIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICB8IFNvbWUgcyAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgwLCBzMCkgPSBzIGluXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDEsIF8pID0gczAgaW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzMSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpbmQnICh4MSA6OiAocm0gKEltcGxpZXMgKChWYXIgeDApLCB4MSkpIGwpKSBmMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBzMSB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBDb3FfaW5sIF8gLT4gQ29xX2lubCBfX1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQ29xX2luciBfIC0+IENvcV9pbnIgX18pXG4gICAgICAgICAgICAgICAgICAgICAgICAgfCBOb25lIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgaEltcExBbmQgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZklJID0gZnVuIF9VVTAzYjhfIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2ggX1VVMDNiOF8gd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgSW1wbGllcyAoZjEsIF8pIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggZjEgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQW5kIChfLCBfKSAtPiB0cnVlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBfIC0+IGZhbHNlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgXyAtPiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcyA9IGV4aXN0c19kZWMgZklJIGwgaW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIHMgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTb21lIHMwIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MCwgXykgPSBzMCBpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb21lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCB4MCB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEltcGxpZXMgKGYxLCBmMikgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIGYxIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQW5kIChmMywgZjQpIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvcV9leGlzdFQgKGYzLCAoQ29xX2V4aXN0VCAoZjQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKENvcV9leGlzdFQgKGYyLCBfXykpKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IF8gLT4gYXNzZXJ0IGZhbHNlICgqIGFic3VyZCBjYXNlICopKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBfIC0+IGFzc2VydCBmYWxzZSAoKiBhYnN1cmQgY2FzZSAqKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgTm9uZSAtPiBOb25lKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBoSW1wTEFuZCB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTb21lIHMgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MCwgczApID0gcyBpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgxLCBzMSkgPSBzMCBpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgyLCBfKSA9IHMxIGluXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgczIgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaW5kJyAoKEltcGxpZXMgKHgwLCAoSW1wbGllcyAoeDEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDIpKSkpIDo6IChybSAoSW1wbGllcyAoKEFuZCAoeDAsIHgxKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDIpKSBsKSkgZjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggczIgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQ29xX2lubCBfIC0+IENvcV9pbmwgX19cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IENvcV9pbnIgXyAtPiBDb3FfaW5yIF9fKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgTm9uZSAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGhJbXBMT3IgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZklJID0gZnVuIF9VVTAzYjhfIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2ggX1VVMDNiOF8gd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgSW1wbGllcyAoZjEsIF8pIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggZjEgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgT3IgKF8sIF8pIC0+IHRydWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IF8gLT4gZmFsc2UpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBfIC0+IGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzID0gZXhpc3RzX2RlYyBmSUkgbCBpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggcyB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFNvbWUgczAgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgwLCBfKSA9IHMwIGluXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvbWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIHgwIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgSW1wbGllcyAoZjEsIGYyKSAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggZjEgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBPciAoZjMsIGY0KSAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb3FfZXhpc3RUIChmMywgKENvcV9leGlzdFQgKGY0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChDb3FfZXhpc3RUIChmMiwgX18pKSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBfIC0+IGFzc2VydCBmYWxzZSAoKiBhYnN1cmQgY2FzZSAqKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgXyAtPiBhc3NlcnQgZmFsc2UgKCogYWJzdXJkIGNhc2UgKikpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IE5vbmUgLT4gTm9uZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggaEltcExPciB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTb21lIHMgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MCwgczApID0gcyBpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgxLCBzMSkgPSBzMCBpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgyLCBfKSA9IHMxIGluXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgczIgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaW5kJyAoKEltcGxpZXMgKHgxLCB4MikpIDo6ICgoSW1wbGllc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh4MCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4MikpIDo6IChybSAoSW1wbGllcyAoKE9yICh4MCwgeDEpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDIpKSBsKSkpIGYwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIHMyIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IENvcV9pbmwgXyAtPiBDb3FfaW5sIF9fXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBDb3FfaW5yIF8gLT4gQ29xX2luciBfXylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IE5vbmUgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBoT3JSMSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoIGYwIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBWYXIgXyAtPiBOb25lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQm90IC0+IE5vbmVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBBbmQgKF8sIF8pIC0+IE5vbmVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBPciAoZjEsIGYyKSAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzID0gaGluZCcgbCBmMSBpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBzIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBDb3FfaW5sIF8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb21lIChDb3FfZXhpc3RUIChmMSwgKENvcV9leGlzdFRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmMiwgX18pKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQ29xX2luciBfIC0+IE5vbmUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgXyAtPiBOb25lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIGhPclIxIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFNvbWUgXyAtPiBDb3FfaW5sIF9fXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBOb25lIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgaE9yUjIgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaCBmMCB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgVmFyIF8gLT4gTm9uZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEJvdCAtPiBOb25lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQW5kIChfLCBfKSAtPiBOb25lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgT3IgKGYxLCBmMikgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcyA9IGhpbmQnIGwgZjIgaW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggcyB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQ29xX2lubCBfIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU29tZSAoQ29xX2V4aXN0VCAoZjEsIChDb3FfZXhpc3RUXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZjIsIF9fKSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IENvcV9pbnIgXyAtPiBOb25lKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IF8gLT4gTm9uZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBoT3JSMiB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTb21lIF8gLT4gQ29xX2lubCBfX1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgTm9uZSAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGhCb3hSID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2ggZjAgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFZhciBfIC0+IE5vbmVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBCb3QgLT4gTm9uZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEFuZCAoXywgXykgLT4gTm9uZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IE9yIChfLCBfKSAtPiBOb25lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgSW1wbGllcyAoXywgXykgLT4gTm9uZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEJveCBmMSAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpbmQnICgoQm94XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYxKSA6OiAobWFwIG9wZW5fYm94IGwpKSBmMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIHMgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IENvcV9pbmwgXyAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvbWUgKENvcV9leGlzdFQgKGYxLCBfXykpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQ29xX2luciBfIC0+IE5vbmUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIGhCb3hSIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFNvbWUgXyAtPiBDb3FfaW5sIF9fXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBOb25lIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgaEltcExJbXAgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW4gX1VVMDM5M18yIF9VVTAzOTNfMSAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcmVjIGYxIGwwIF9VVTAzOTNfMyA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2ggbDAgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgW10gLT4gTm9uZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgeSA6OiBsMSAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHMgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmMSBsMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhcHAgX1VVMDM5M18zICh5IDo6IFtdKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggcyB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTb21lIHMwIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoeDAsIHMxKSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IENvcV9leGlzdFQgKHgxLCBzMikgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUICh4MiwgXykgPSBzMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvbWUgKENvcV9leGlzdFQgKHgwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKENvcV9leGlzdFQgKHgxLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKENvcV9leGlzdFQgKHgyLCBfXykpKSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgTm9uZSAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIHkgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgSW1wbGllcyAoZjIsIGYzKSAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIGYyIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEltcGxpZXMgKGY0LCBmNSkgLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzMCA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpbmQnICgoSW1wbGllc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmNSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmMykpIDo6IFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChybSAoSW1wbGllc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChJbXBsaWVzIChmNCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGY1KSksIGYzKSkgbCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEltcGxpZXMgKGY0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGY1KSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggczAgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQ29xX2lubCBfIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgczEgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaW5kJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmMyA6OiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocm0gKEltcGxpZXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoSW1wbGllc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGY0LCBmNSkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZjMpKSBsKSkgZjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggczEgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQ29xX2lubCBfIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb21lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChDb3FfZXhpc3RUXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmNCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKENvcV9leGlzdFRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGY1LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQ29xX2V4aXN0VFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZjMsIF9fKSkpKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBDb3FfaW5yIF8gLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vbmUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBDb3FfaW5yIF8gLT4gTm9uZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEJveCBfIC0+IE5vbmVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IF8gLT4gTm9uZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEJveCBfIC0+IE5vbmVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IF8gLT4gTm9uZSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluIGYxIF9VVTAzOTNfMiBfVVUwMzkzXzFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcyA9IGhJbXBMSW1wIGwgW10gaW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBzIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFNvbWUgXyAtPiBDb3FfaW5sIF9fXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBOb25lIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgaEltcExCb3ggPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW4gX1VVMDM5M18yIF9VVTAzOTNfMSAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcmVjIGYxIGwwIF9VVTAzOTNfMyA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2ggbDAgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgW10gLT4gTm9uZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgeSA6OiBsMSAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHMwID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZjEgbDFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXBwIF9VVTAzOTNfM1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHkgOjogW10pKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtYXRjaCBzMCB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTb21lIHMxIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgQ29xX2V4aXN0VCAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHgwLCBzMikgPSBzMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBDb3FfZXhpc3RUIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDEsIF8pID0gczJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb21lIChDb3FfZXhpc3RUICh4MCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChDb3FfZXhpc3RUICh4MSwgX18pKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBOb25lIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggeSB3aXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBJbXBsaWVzIChmMiwgZjMpIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggZjIgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQm94IGY0IC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgczEgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaW5kJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmMyA6OiAoKEJveFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGY0KSA6OiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWFwIG9wZW5fYm94XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocm1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEltcGxpZXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChCb3hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZjQpLCBmMykpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGwpKSkpIGY0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIHMxIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IENvcV9pbmwgXyAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHMyID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGluZCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZjMgOjogXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJtXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJbXBsaWVzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoQm94XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGY0KSwgZjMpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsKSkgZjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggczIgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQ29xX2lubCBfIC0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb21lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChDb3FfZXhpc3RUXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmNCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKENvcV9leGlzdFRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGYzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfXykpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IENvcV9pbnIgXyAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9uZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IENvcV9pbnIgXyAtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9uZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IF8gLT4gTm9uZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEJveCBfIC0+IE5vbmVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IF8gLT4gTm9uZSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluIGYxIF9VVTAzOTNfMiBfVVUwMzkzXzFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgczAgPSBoSW1wTEJveCBsIFtdIGluXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF0Y2ggczAgd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU29tZSBfIC0+IENvcV9pbmwgX19cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IE5vbmUgLT4gQ29xX2luciBfXykpKSkpKSkpKSkpKSlcbiAgaW4gZiBwZVxuIiwidHlwZSBiaWdzdHJpbmcgPVxuICAoY2hhciwgQmlnYXJyYXkuaW50OF91bnNpZ25lZF9lbHQsIEJpZ2FycmF5LmNfbGF5b3V0KSBCaWdhcnJheS5BcnJheTEudFxuXG50eXBlIHQgPSBiaWdzdHJpbmdcblxubGV0IGNyZWF0ZSBzaXplID0gQmlnYXJyYXkuKEFycmF5MS5jcmVhdGUgY2hhciBjX2xheW91dCBzaXplKVxubGV0IGVtcHR5ICAgICAgID0gY3JlYXRlIDBcblxubW9kdWxlIEJBMSA9IEJpZ2FycmF5LkFycmF5MVxuXG5sZXQgbGVuZ3RoIHQgPSBCQTEuZGltIHRcblxuZXh0ZXJuYWwgZ2V0IDogdCAtPiBpbnQgLT4gY2hhciA9IFwiJWNhbWxfYmFfcmVmXzFcIlxuZXh0ZXJuYWwgc2V0IDogdCAtPiBpbnQgLT4gY2hhciAtPiB1bml0ID0gXCIlY2FtbF9iYV9zZXRfMVwiXG5cbmV4dGVybmFsIHVuc2FmZV9nZXQgOiB0IC0+IGludCAtPiBjaGFyICAgICAgICAgPSBcIiVjYW1sX2JhX3Vuc2FmZV9yZWZfMVwiXG5leHRlcm5hbCB1bnNhZmVfc2V0IDogdCAtPiBpbnQgLT4gY2hhciAtPiB1bml0ID0gXCIlY2FtbF9iYV91bnNhZmVfc2V0XzFcIlxuXG5leHRlcm5hbCB1bnNhZmVfYmxpdCAgICAgICAgICAgIDogdCAgICAgICAtPiBzcmNfb2ZmOmludCAtPiB0ICAgICAgIC0+IGRzdF9vZmY6aW50IC0+IGxlbjppbnQgLT4gdW5pdCA9XG4gIFwiYmlnc3RyaW5nYWZfYmxpdF90b19iaWdzdHJpbmdcIiBbQEBub2FsbG9jXVxuXG5leHRlcm5hbCB1bnNhZmVfYmxpdF90b19ieXRlcyAgIDogdCAgICAgICAtPiBzcmNfb2ZmOmludCAtPiBCeXRlcy50IC0+IGRzdF9vZmY6aW50IC0+IGxlbjppbnQgLT4gdW5pdCA9XG4gIFwiYmlnc3RyaW5nYWZfYmxpdF90b19ieXRlc1wiICAgICBbQEBub2FsbG9jXVxuXG5leHRlcm5hbCB1bnNhZmVfYmxpdF9mcm9tX2J5dGVzIDogQnl0ZXMudCAtPiBzcmNfb2ZmOmludCAtPiB0ICAgICAgIC0+IGRzdF9vZmY6aW50IC0+IGxlbjppbnQgLT4gdW5pdCA9XG4gIFwiYmlnc3RyaW5nYWZfYmxpdF9mcm9tX2J5dGVzXCIgICBbQEBub2FsbG9jXVxuXG5leHRlcm5hbCB1bnNhZmVfYmxpdF9mcm9tX3N0cmluZyA6IHN0cmluZyAtPiBzcmNfb2ZmOmludCAtPiB0ICAgICAgIC0+IGRzdF9vZmY6aW50IC0+IGxlbjppbnQgLT4gdW5pdCA9XG4gIFwiYmlnc3RyaW5nYWZfYmxpdF9mcm9tX2J5dGVzXCIgICBbQEBub2FsbG9jXVxuXG5leHRlcm5hbCB1bnNhZmVfbWVtY21wIDogdCAtPiBpbnQgLT4gdCAtPiBpbnQgLT4gaW50IC0+IGludCA9XG4gIFwiYmlnc3RyaW5nYWZfbWVtY21wX2JpZ3N0cmluZ1wiIFtAQG5vYWxsb2NdXG5cbmV4dGVybmFsIHVuc2FmZV9tZW1jbXBfc3RyaW5nIDogdCAtPiBpbnQgLT4gc3RyaW5nIC0+IGludCAtPiBpbnQgLT4gaW50ID1cbiAgXCJiaWdzdHJpbmdhZl9tZW1jbXBfc3RyaW5nXCIgW0BAbm9hbGxvY11cblxuZXh0ZXJuYWwgdW5zYWZlX21lbWNociA6IHQgLT4gaW50IC0+IGNoYXIgLT4gaW50IC0+IGludCA9XG4gIFwiYmlnc3RyaW5nYWZfbWVtY2hyXCIgW0BAbm9hbGxvY11cblxubGV0IHN1YiB0IH5vZmYgfmxlbiA9XG4gIEJBMS5zdWIgdCBvZmYgbGVuXG5cbmxldFtAaW5saW5lIG5ldmVyXSBpbnZhbGlkX2JvdW5kcyBvcCBidWZmZXJfbGVuIG9mZiBsZW4gPVxuICBsZXQgbWVzc2FnZSA9XG4gICAgUHJpbnRmLnNwcmludGYgXCJCaWdzdHJpbmdhZi4lcyBpbnZhbGlkIHJhbmdlOiB7IGJ1ZmZlcl9sZW46ICVkLCBvZmY6ICVkLCBsZW46ICVkIH1cIlxuICAgIG9wIGJ1ZmZlcl9sZW4gb2ZmIGxlblxuICBpblxuICByYWlzZSAoSW52YWxpZF9hcmd1bWVudCBtZXNzYWdlKVxuOztcblxubGV0W0BpbmxpbmUgbmV2ZXJdIGludmFsaWRfYm91bmRzX2JsaXQgb3Agc3JjX2xlbiBzcmNfb2ZmIGRzdF9sZW4gZHN0X29mZiBsZW4gPVxuICBsZXQgbWVzc2FnZSA9XG4gICAgUHJpbnRmLnNwcmludGYgXCJCaWdzdHJpbmdhZi4lcyBpbnZhbGlkIHJhbmdlOiB7IHNyY19sZW46ICVkLCBzcmNfb2ZmOiAlZCwgZHN0X2xlbjogJWQsIGRzdF9vZmY6ICVkLCBsZW46ICVkIH1cIlxuICAgIG9wIHNyY19sZW4gc3JjX29mZiBkc3RfbGVuIGRzdF9vZmYgbGVuXG4gIGluXG4gIHJhaXNlIChJbnZhbGlkX2FyZ3VtZW50IG1lc3NhZ2UpXG47O1xuXG5sZXRbQGlubGluZSBuZXZlcl0gaW52YWxpZF9ib3VuZHNfbWVtY21wIG9wIGJ1ZjFfbGVuIGJ1ZjFfb2ZmIGJ1ZjJfbGVuIGJ1ZjJfb2ZmIGxlbiA9XG4gIGxldCBtZXNzYWdlID1cbiAgICBQcmludGYuc3ByaW50ZiBcIkJpZ3N0cmluZ2FmLiVzIGludmFsaWQgcmFuZ2U6IHsgYnVmMV9sZW46ICVkLCBidWYxX29mZjogJWQsIGJ1ZjJfbGVuOiAlZCwgYnVmMl9vZmY6ICVkLCBsZW46ICVkIH1cIlxuICAgIG9wIGJ1ZjFfbGVuIGJ1ZjFfb2ZmIGJ1ZjJfbGVuIGJ1ZjJfb2ZmIGxlblxuICBpblxuICByYWlzZSAoSW52YWxpZF9hcmd1bWVudCBtZXNzYWdlKVxuOztcblxuKCogQSBub3RlIG9uIGJvdW5kcyBjaGVja2luZy5cbiAqXG4gKiBUaGUgY29kZSBzaG91bGQgcGVyZm9ybSB0aGUgZm9sbG93aW5nIGNoZWNrIHRvIGVuc3VyZSB0aGF0IHRoZSBibGl0IGRvZXNuJ3RcbiAqIHJ1biBvZmYgdGhlIGVuZCBvZiB0aGUgaW5wdXQgYnVmZmVyOlxuICpcbiAqICAge1tvZmYgKyBsZW4gPD0gYnVmZmVyX2xlbl19XG4gKlxuICogSG93ZXZlciwgdGhpcyBtYXkgbGVhZCB0byBhbiBpbnRlZ2VyIG92ZXJmbG93IGZvciBsYXJnZSB2YWx1ZXMgb2YgW29mZl0sXG4gKiBlLmcuLCBbbWF4X2ludF0sIHdoaWNoIHdpbGwgY2F1c2UgdGhlIGNvbXBhcmlzb24gdG8gcmV0dXJuIFt0cnVlXSB3aGVuIGl0XG4gKiBzaG91bGQgcmVhbGx5IHJldHVybiBbZmFsc2VdLlxuICpcbiAqIEFuIGVxdWl2YWxlbnQgY29tcGFyaXNvbiB0aGF0IGRvZXMgbm90IHJ1biBpbnRvIHRoaXMgaW50ZWdlciBvdmVyZmxvd1xuICogcHJvYmxlbSBpczpcbiAqXG4gKiAgIHtbYnVmZmVyX2xlbiAtIG9mZiA9PiBsZW5dfVxuICpcbiAqIFRoaXMgaXMgY2hlY2tpbmcgdGhhdCB0aGUgaW5wdXQgYnVmZmVyLCBsZXNzIHRoZSBvZmZzZXQsIGlzIHN1ZmZpY2llbnRseVxuICogbG9uZyB0byBwZXJmb3JtIHRoZSBibGl0LiBTaW5jZSB0aGUgZXhwcmVzc2lvbiBpcyBzdWJ0cmFjdGluZyBbb2ZmXSByYXRoZXJcbiAqIHRoYW4gYWRkaW5nIGl0LCBpdCBkb2Vzbid0IHN1ZmZlciBmcm9tIHRoZSBvdmVyZmxvdyB0aGF0IHRoZSBwcmV2aW91c1xuICogaW5lcXVhbGl0eSBkaWQuIEFzIGxvbmcgYXMgdGhlcmUgaXMgYSBjaGVjayB0byBlbnN1cmUgdGhhdCBbb2ZmXSBpcyBub3RcbiAqIG5lZ2F0aXZlLCBpdCB3b24ndCB1bmRlcmZsb3cgZWl0aGVyLiAqKVxuXG5sZXQgY29weSB0IH5vZmYgfmxlbiA9XG4gIGxldCBidWZmZXJfbGVuID0gbGVuZ3RoIHQgaW5cbiAgaWYgbGVuIDwgMCB8fCBvZmYgPCAwIHx8IGJ1ZmZlcl9sZW4gLSBvZmYgPCBsZW5cbiAgdGhlbiBpbnZhbGlkX2JvdW5kcyBcImNvcHlcIiBidWZmZXJfbGVuIG9mZiBsZW47XG4gIGxldCBkc3QgPSBjcmVhdGUgbGVuIGluXG4gIHVuc2FmZV9ibGl0IHQgfnNyY19vZmY6b2ZmIGRzdCB+ZHN0X29mZjowIH5sZW47XG4gIGRzdFxuOztcblxubGV0IHN1YnN0cmluZyB0IH5vZmYgfmxlbiA9XG4gIGxldCBidWZmZXJfbGVuID0gbGVuZ3RoIHQgaW5cbiAgaWYgbGVuIDwgMCB8fCBvZmYgPCAwIHx8IGJ1ZmZlcl9sZW4gLSBvZmYgPCBsZW5cbiAgdGhlbiBpbnZhbGlkX2JvdW5kcyBcInN1YnN0cmluZ1wiIGJ1ZmZlcl9sZW4gb2ZmIGxlbjtcbiAgbGV0IGIgPSBCeXRlcy5jcmVhdGUgbGVuIGluXG4gIHVuc2FmZV9ibGl0X3RvX2J5dGVzIHQgfnNyY19vZmY6b2ZmIGIgfmRzdF9vZmY6MCB+bGVuO1xuICBCeXRlcy51bnNhZmVfdG9fc3RyaW5nIGJcbjs7XG5cbmxldCB0b19zdHJpbmcgdCA9XG4gIGxldCBsZW4gPSBsZW5ndGggdCBpblxuICBsZXQgYiA9IEJ5dGVzLmNyZWF0ZSBsZW4gaW5cbiAgdW5zYWZlX2JsaXRfdG9fYnl0ZXMgdCB+c3JjX29mZjowIGIgfmRzdF9vZmY6MCB+bGVuO1xuICBCeXRlcy51bnNhZmVfdG9fc3RyaW5nIGJcbjs7XG5cbmxldCBvZl9zdHJpbmcgfm9mZiB+bGVuIHMgPVxuICBsZXQgYnVmZmVyX2xlbiA9IFN0cmluZy5sZW5ndGggcyBpblxuICBpZiBsZW4gPCAwIHx8IG9mZiA8IDAgfHwgYnVmZmVyX2xlbiAtIG9mZiA8IGxlblxuICB0aGVuIGludmFsaWRfYm91bmRzIFwib2Zfc3RyaW5nXCIgYnVmZmVyX2xlbiBvZmYgbGVuO1xuICBsZXQgYiA9IGNyZWF0ZSBsZW4gaW5cbiAgdW5zYWZlX2JsaXRfZnJvbV9zdHJpbmcgcyB+c3JjX29mZjpvZmYgYiB+ZHN0X29mZjowIH5sZW47XG4gIGJcbjs7XG5cbmxldCBibGl0IHNyYyB+c3JjX29mZiBkc3QgfmRzdF9vZmYgfmxlbiA9XG4gIGxldCBzcmNfbGVuID0gbGVuZ3RoIHNyYyBpblxuICBsZXQgZHN0X2xlbiA9IGxlbmd0aCBkc3QgaW5cbiAgaWYgbGVuIDwgMFxuICB0aGVuIGludmFsaWRfYm91bmRzX2JsaXQgXCJibGl0XCIgc3JjX2xlbiBzcmNfb2ZmIGRzdF9sZW4gZHN0X29mZiBsZW47XG4gIGlmIHNyY19vZmYgPCAwIHx8IHNyY19sZW4gLSBzcmNfb2ZmIDwgbGVuXG4gIHRoZW4gaW52YWxpZF9ib3VuZHNfYmxpdCBcImJsaXRcIiBzcmNfbGVuIHNyY19vZmYgZHN0X2xlbiBkc3Rfb2ZmIGxlbjtcbiAgaWYgZHN0X29mZiA8IDAgfHwgZHN0X2xlbiAtIGRzdF9vZmYgPCBsZW5cbiAgdGhlbiBpbnZhbGlkX2JvdW5kc19ibGl0IFwiYmxpdFwiIHNyY19sZW4gc3JjX29mZiBkc3RfbGVuIGRzdF9vZmYgbGVuO1xuICB1bnNhZmVfYmxpdCBzcmMgfnNyY19vZmYgZHN0IH5kc3Rfb2ZmIH5sZW5cbjs7XG5cbmxldCBibGl0X2Zyb21fc3RyaW5nIHNyYyB+c3JjX29mZiBkc3QgfmRzdF9vZmYgfmxlbiA9XG4gIGxldCBzcmNfbGVuID0gU3RyaW5nLmxlbmd0aCBzcmMgaW5cbiAgbGV0IGRzdF9sZW4gPSBsZW5ndGggZHN0IGluXG4gIGlmIGxlbiA8IDBcbiAgdGhlbiBpbnZhbGlkX2JvdW5kc19ibGl0IFwiYmxpdF9mcm9tX3N0cmluZ1wiIHNyY19sZW4gc3JjX29mZiBkc3RfbGVuIGRzdF9vZmYgbGVuO1xuICBpZiBzcmNfb2ZmIDwgMCB8fCBzcmNfbGVuIC0gc3JjX29mZiA8IGxlblxuICB0aGVuIGludmFsaWRfYm91bmRzX2JsaXQgXCJibGl0X2Zyb21fc3RyaW5nXCIgc3JjX2xlbiBzcmNfb2ZmIGRzdF9sZW4gZHN0X29mZiBsZW47XG4gIGlmIGRzdF9vZmYgPCAwIHx8IGRzdF9sZW4gLSBkc3Rfb2ZmIDwgbGVuXG4gIHRoZW4gaW52YWxpZF9ib3VuZHNfYmxpdCBcImJsaXRfZnJvbV9zdHJpbmdcIiBzcmNfbGVuIHNyY19vZmYgZHN0X2xlbiBkc3Rfb2ZmIGxlbjtcbiAgdW5zYWZlX2JsaXRfZnJvbV9zdHJpbmcgc3JjIH5zcmNfb2ZmIGRzdCB+ZHN0X29mZiB+bGVuXG47O1xuXG5sZXQgYmxpdF9mcm9tX2J5dGVzIHNyYyB+c3JjX29mZiBkc3QgfmRzdF9vZmYgfmxlbiA9XG4gIGxldCBzcmNfbGVuID0gQnl0ZXMubGVuZ3RoIHNyYyBpblxuICBsZXQgZHN0X2xlbiA9IGxlbmd0aCBkc3QgaW5cbiAgaWYgbGVuIDwgMFxuICB0aGVuIGludmFsaWRfYm91bmRzX2JsaXQgXCJibGl0X2Zyb21fYnl0ZXNcIiBzcmNfbGVuIHNyY19vZmYgZHN0X2xlbiBkc3Rfb2ZmIGxlbjtcbiAgaWYgc3JjX29mZiA8IDAgfHwgc3JjX2xlbiAtIHNyY19vZmYgPCBsZW5cbiAgdGhlbiBpbnZhbGlkX2JvdW5kc19ibGl0IFwiYmxpdF9mcm9tX2J5dGVzXCIgc3JjX2xlbiBzcmNfb2ZmIGRzdF9sZW4gZHN0X29mZiBsZW47XG4gIGlmIGRzdF9vZmYgPCAwIHx8IGRzdF9sZW4gLSBkc3Rfb2ZmIDwgbGVuXG4gIHRoZW4gaW52YWxpZF9ib3VuZHNfYmxpdCBcImJsaXRfZnJvbV9ieXRlc1wiIHNyY19sZW4gc3JjX29mZiBkc3RfbGVuIGRzdF9vZmYgbGVuO1xuICB1bnNhZmVfYmxpdF9mcm9tX2J5dGVzIHNyYyB+c3JjX29mZiBkc3QgfmRzdF9vZmYgfmxlblxuOztcblxubGV0IGJsaXRfdG9fYnl0ZXMgc3JjIH5zcmNfb2ZmIGRzdCB+ZHN0X29mZiB+bGVuID1cbiAgbGV0IHNyY19sZW4gPSBsZW5ndGggc3JjIGluXG4gIGxldCBkc3RfbGVuID0gQnl0ZXMubGVuZ3RoIGRzdCBpblxuICBpZiBsZW4gPCAwXG4gIHRoZW4gaW52YWxpZF9ib3VuZHNfYmxpdCBcImJsaXRfdG9fYnl0ZXNcIiBzcmNfbGVuIHNyY19vZmYgZHN0X2xlbiBkc3Rfb2ZmIGxlbjtcbiAgaWYgc3JjX29mZiA8IDAgfHwgc3JjX2xlbiAtIHNyY19vZmYgPCBsZW5cbiAgdGhlbiBpbnZhbGlkX2JvdW5kc19ibGl0IFwiYmxpdF90b19ieXRlc1wiIHNyY19sZW4gc3JjX29mZiBkc3RfbGVuIGRzdF9vZmYgbGVuO1xuICBpZiBkc3Rfb2ZmIDwgMCB8fCBkc3RfbGVuIC0gZHN0X29mZiA8IGxlblxuICB0aGVuIGludmFsaWRfYm91bmRzX2JsaXQgXCJibGl0X3RvX2J5dGVzXCIgc3JjX2xlbiBzcmNfb2ZmIGRzdF9sZW4gZHN0X29mZiBsZW47XG4gIHVuc2FmZV9ibGl0X3RvX2J5dGVzIHNyYyB+c3JjX29mZiBkc3QgfmRzdF9vZmYgfmxlblxuOztcblxubGV0IG1lbWNtcCBidWYxIGJ1ZjFfb2ZmIGJ1ZjIgYnVmMl9vZmYgbGVuID1cbiAgbGV0IGJ1ZjFfbGVuID0gbGVuZ3RoIGJ1ZjEgaW5cbiAgbGV0IGJ1ZjJfbGVuID0gbGVuZ3RoIGJ1ZjIgaW5cbiAgaWYgbGVuIDwgMFxuICB0aGVuIGludmFsaWRfYm91bmRzX21lbWNtcCBcIm1lbWNtcFwiIGJ1ZjFfbGVuIGJ1ZjFfb2ZmIGJ1ZjJfbGVuIGJ1ZjJfb2ZmIGxlbjtcbiAgaWYgYnVmMV9vZmYgPCAwIHx8IGJ1ZjFfbGVuIC0gYnVmMV9vZmYgPCBsZW5cbiAgdGhlbiBpbnZhbGlkX2JvdW5kc19tZW1jbXAgXCJtZW1jbXBcIiBidWYxX2xlbiBidWYxX29mZiBidWYyX2xlbiBidWYyX29mZiBsZW47XG4gIGlmIGJ1ZjJfb2ZmIDwgMCB8fCBidWYyX2xlbiAtIGJ1ZjJfb2ZmIDwgbGVuXG4gIHRoZW4gaW52YWxpZF9ib3VuZHNfbWVtY21wIFwibWVtY21wXCIgYnVmMV9sZW4gYnVmMV9vZmYgYnVmMl9sZW4gYnVmMl9vZmYgbGVuO1xuICB1bnNhZmVfbWVtY21wIGJ1ZjEgYnVmMV9vZmYgYnVmMiBidWYyX29mZiBsZW5cbjs7XG5cbmxldCBtZW1jbXBfc3RyaW5nIGJ1ZjEgYnVmMV9vZmYgYnVmMiBidWYyX29mZiBsZW4gPVxuICBsZXQgYnVmMV9sZW4gPSBsZW5ndGggYnVmMSBpblxuICBsZXQgYnVmMl9sZW4gPSBTdHJpbmcubGVuZ3RoIGJ1ZjIgaW5cbiAgaWYgbGVuIDwgMFxuICB0aGVuIGludmFsaWRfYm91bmRzX21lbWNtcCBcIm1lbWNtcF9zdHJpbmdcIiBidWYxX2xlbiBidWYxX29mZiBidWYyX2xlbiBidWYyX29mZiBsZW47XG4gIGlmIGJ1ZjFfb2ZmIDwgMCB8fCBidWYxX2xlbiAtIGJ1ZjFfb2ZmIDwgbGVuXG4gIHRoZW4gaW52YWxpZF9ib3VuZHNfbWVtY21wIFwibWVtY21wX3N0cmluZ1wiIGJ1ZjFfbGVuIGJ1ZjFfb2ZmIGJ1ZjJfbGVuIGJ1ZjJfb2ZmIGxlbjtcbiAgaWYgYnVmMl9vZmYgPCAwIHx8IGJ1ZjJfbGVuIC0gYnVmMl9vZmYgPCBsZW5cbiAgdGhlbiBpbnZhbGlkX2JvdW5kc19tZW1jbXAgXCJtZW1jbXBfc3RyaW5nXCIgYnVmMV9sZW4gYnVmMV9vZmYgYnVmMl9sZW4gYnVmMl9vZmYgbGVuO1xuICB1bnNhZmVfbWVtY21wX3N0cmluZyBidWYxIGJ1ZjFfb2ZmIGJ1ZjIgYnVmMl9vZmYgbGVuXG47O1xuXG5sZXQgbWVtY2hyIGJ1ZiBidWZfb2ZmIGNociBsZW4gPVxuICBsZXQgYnVmX2xlbiA9IGxlbmd0aCBidWYgaW5cbiAgaWYgbGVuIDwgMFxuICB0aGVuIGludmFsaWRfYm91bmRzIFwibWVtY2hyXCIgYnVmX2xlbiBidWZfb2ZmIGxlbjtcbiAgaWYgYnVmX29mZiA8IDAgfHwgYnVmX2xlbiAtIGJ1Zl9vZmYgPCBsZW5cbiAgdGhlbiBpbnZhbGlkX2JvdW5kcyBcIm1lbWNoclwiIGJ1Zl9sZW4gYnVmX29mZiBsZW47XG4gIHVuc2FmZV9tZW1jaHIgYnVmIGJ1Zl9vZmYgY2hyIGxlblxuXG4oKiBTYWZlIG9wZXJhdGlvbnMgKilcblxuZXh0ZXJuYWwgY2FtbF9iaWdzdHJpbmdfc2V0XzE2IDogYmlnc3RyaW5nIC0+IGludCAtPiBpbnQgICAtPiB1bml0ID0gXCIlY2FtbF9iaWdzdHJpbmdfc2V0MTZcIlxuZXh0ZXJuYWwgY2FtbF9iaWdzdHJpbmdfc2V0XzMyIDogYmlnc3RyaW5nIC0+IGludCAtPiBpbnQzMiAtPiB1bml0ID0gXCIlY2FtbF9iaWdzdHJpbmdfc2V0MzJcIlxuZXh0ZXJuYWwgY2FtbF9iaWdzdHJpbmdfc2V0XzY0IDogYmlnc3RyaW5nIC0+IGludCAtPiBpbnQ2NCAtPiB1bml0ID0gXCIlY2FtbF9iaWdzdHJpbmdfc2V0NjRcIlxuXG5leHRlcm5hbCBjYW1sX2JpZ3N0cmluZ19nZXRfMTYgOiBiaWdzdHJpbmcgLT4gaW50IC0+IGludCAgID0gXCIlY2FtbF9iaWdzdHJpbmdfZ2V0MTZcIlxuZXh0ZXJuYWwgY2FtbF9iaWdzdHJpbmdfZ2V0XzMyIDogYmlnc3RyaW5nIC0+IGludCAtPiBpbnQzMiA9IFwiJWNhbWxfYmlnc3RyaW5nX2dldDMyXCJcbmV4dGVybmFsIGNhbWxfYmlnc3RyaW5nX2dldF82NCA6IGJpZ3N0cmluZyAtPiBpbnQgLT4gaW50NjQgPSBcIiVjYW1sX2JpZ3N0cmluZ19nZXQ2NFwiXG5cbm1vZHVsZSBTd2FwID0gc3RydWN0XG4gIGV4dGVybmFsIGJzd2FwMTYgOiBpbnQgLT4gaW50ID0gXCIlYnN3YXAxNlwiXG4gIGV4dGVybmFsIGJzd2FwX2ludDMyIDogaW50MzIgLT4gaW50MzIgPSBcIiVic3dhcF9pbnQzMlwiXG4gIGV4dGVybmFsIGJzd2FwX2ludDY0IDogaW50NjQgLT4gaW50NjQgPSBcIiVic3dhcF9pbnQ2NFwiXG5cbiAgbGV0IGNhbWxfYmlnc3RyaW5nX3NldF8xNiBicyBvZmYgaSA9XG4gICAgY2FtbF9iaWdzdHJpbmdfc2V0XzE2IGJzIG9mZiAoYnN3YXAxNiBpKVxuXG4gIGxldCBjYW1sX2JpZ3N0cmluZ19zZXRfMzIgYnMgb2ZmIGkgPVxuICAgIGNhbWxfYmlnc3RyaW5nX3NldF8zMiBicyBvZmYgKGJzd2FwX2ludDMyIGkpXG5cbiAgbGV0IGNhbWxfYmlnc3RyaW5nX3NldF82NCBicyBvZmYgaSA9XG4gICAgY2FtbF9iaWdzdHJpbmdfc2V0XzY0IGJzIG9mZiAoYnN3YXBfaW50NjQgaSlcblxuICBsZXQgY2FtbF9iaWdzdHJpbmdfZ2V0XzE2IGJzIG9mZiA9XG4gICAgYnN3YXAxNiAoY2FtbF9iaWdzdHJpbmdfZ2V0XzE2IGJzIG9mZilcblxuICBsZXQgY2FtbF9iaWdzdHJpbmdfZ2V0XzMyIGJzIG9mZiA9XG4gICAgYnN3YXBfaW50MzIgKGNhbWxfYmlnc3RyaW5nX2dldF8zMiBicyBvZmYpXG5cbiAgbGV0IGNhbWxfYmlnc3RyaW5nX2dldF82NCBicyBvZmYgPVxuICAgIGJzd2FwX2ludDY0IChjYW1sX2JpZ3N0cmluZ19nZXRfNjQgYnMgb2ZmKVxuXG4gIGxldCBnZXRfaW50MTZfc2lnbl9leHRlbmRlZCB4IG9mZiA9XG4gICAgKChjYW1sX2JpZ3N0cmluZ19nZXRfMTYgeCBvZmYpIGxzbCAoU3lzLmludF9zaXplIC0gMTYpKSBhc3IgKFN5cy5pbnRfc2l6ZSAtIDE2KVxuZW5kXG5cbmxldCBzZXRfaW50MTZfbGUsIHNldF9pbnQxNl9iZSA9XG4gIGlmIFN5cy5iaWdfZW5kaWFuXG4gIHRoZW4gU3dhcC5jYW1sX2JpZ3N0cmluZ19zZXRfMTYsIGNhbWxfYmlnc3RyaW5nX3NldF8xNlxuICBlbHNlIGNhbWxfYmlnc3RyaW5nX3NldF8xNiAgICAgLCBTd2FwLmNhbWxfYmlnc3RyaW5nX3NldF8xNlxuXG5sZXQgc2V0X2ludDMyX2xlLCBzZXRfaW50MzJfYmUgPVxuICBpZiBTeXMuYmlnX2VuZGlhblxuICB0aGVuIFN3YXAuY2FtbF9iaWdzdHJpbmdfc2V0XzMyLCBjYW1sX2JpZ3N0cmluZ19zZXRfMzJcbiAgZWxzZSBjYW1sX2JpZ3N0cmluZ19zZXRfMzIgICAgICwgU3dhcC5jYW1sX2JpZ3N0cmluZ19zZXRfMzJcblxubGV0IHNldF9pbnQ2NF9sZSwgc2V0X2ludDY0X2JlID1cbiAgaWYgU3lzLmJpZ19lbmRpYW5cbiAgdGhlbiBTd2FwLmNhbWxfYmlnc3RyaW5nX3NldF82NCwgY2FtbF9iaWdzdHJpbmdfc2V0XzY0XG4gIGVsc2UgY2FtbF9iaWdzdHJpbmdfc2V0XzY0ICAgICAsIFN3YXAuY2FtbF9iaWdzdHJpbmdfc2V0XzY0XG5cbmxldCBnZXRfaW50MTZfbGUsIGdldF9pbnQxNl9iZSA9XG4gIGlmIFN5cy5iaWdfZW5kaWFuXG4gIHRoZW4gU3dhcC5jYW1sX2JpZ3N0cmluZ19nZXRfMTYsIGNhbWxfYmlnc3RyaW5nX2dldF8xNlxuICBlbHNlIGNhbWxfYmlnc3RyaW5nX2dldF8xNiAgICAgLCBTd2FwLmNhbWxfYmlnc3RyaW5nX2dldF8xNlxuXG5sZXQgZ2V0X2ludDE2X3NpZ25fZXh0ZW5kZWRfbm9zd2FwIHggb2ZmID1cbiAgKChjYW1sX2JpZ3N0cmluZ19nZXRfMTYgICAgICB4IG9mZikgbHNsIChTeXMuaW50X3NpemUgLSAxNikpIGFzciAoU3lzLmludF9zaXplIC0gMTYpXG5cbmxldCBnZXRfaW50MTZfc2lnbl9leHRlbmRlZF9sZSwgZ2V0X2ludDE2X3NpZ25fZXh0ZW5kZWRfYmUgID1cbiAgaWYgU3lzLmJpZ19lbmRpYW5cbiAgdGhlbiBTd2FwLmdldF9pbnQxNl9zaWduX2V4dGVuZGVkICAsIGdldF9pbnQxNl9zaWduX2V4dGVuZGVkX25vc3dhcFxuICBlbHNlIGdldF9pbnQxNl9zaWduX2V4dGVuZGVkX25vc3dhcCwgU3dhcC5nZXRfaW50MTZfc2lnbl9leHRlbmRlZFxuXG5sZXQgZ2V0X2ludDMyX2xlLCBnZXRfaW50MzJfYmUgPVxuICBpZiBTeXMuYmlnX2VuZGlhblxuICB0aGVuIFN3YXAuY2FtbF9iaWdzdHJpbmdfZ2V0XzMyLCBjYW1sX2JpZ3N0cmluZ19nZXRfMzJcbiAgZWxzZSBjYW1sX2JpZ3N0cmluZ19nZXRfMzIgICAgICwgU3dhcC5jYW1sX2JpZ3N0cmluZ19nZXRfMzJcblxubGV0IGdldF9pbnQ2NF9sZSwgZ2V0X2ludDY0X2JlID1cbiAgaWYgU3lzLmJpZ19lbmRpYW5cbiAgdGhlbiBTd2FwLmNhbWxfYmlnc3RyaW5nX2dldF82NCwgY2FtbF9iaWdzdHJpbmdfZ2V0XzY0XG4gIGVsc2UgY2FtbF9iaWdzdHJpbmdfZ2V0XzY0ICAgICAsIFN3YXAuY2FtbF9iaWdzdHJpbmdfZ2V0XzY0XG5cbigqIFVuc2FmZSBvcGVyYXRpb25zICopXG5cbmV4dGVybmFsIGNhbWxfYmlnc3RyaW5nX3Vuc2FmZV9zZXRfMTYgOiBiaWdzdHJpbmcgLT4gaW50IC0+IGludCAgIC0+IHVuaXQgPSBcIiVjYW1sX2JpZ3N0cmluZ19zZXQxNnVcIlxuZXh0ZXJuYWwgY2FtbF9iaWdzdHJpbmdfdW5zYWZlX3NldF8zMiA6IGJpZ3N0cmluZyAtPiBpbnQgLT4gaW50MzIgLT4gdW5pdCA9IFwiJWNhbWxfYmlnc3RyaW5nX3NldDMydVwiXG5leHRlcm5hbCBjYW1sX2JpZ3N0cmluZ191bnNhZmVfc2V0XzY0IDogYmlnc3RyaW5nIC0+IGludCAtPiBpbnQ2NCAtPiB1bml0ID0gXCIlY2FtbF9iaWdzdHJpbmdfc2V0NjR1XCJcblxuZXh0ZXJuYWwgY2FtbF9iaWdzdHJpbmdfdW5zYWZlX2dldF8xNiA6IGJpZ3N0cmluZyAtPiBpbnQgLT4gaW50ICAgPSBcIiVjYW1sX2JpZ3N0cmluZ19nZXQxNnVcIlxuZXh0ZXJuYWwgY2FtbF9iaWdzdHJpbmdfdW5zYWZlX2dldF8zMiA6IGJpZ3N0cmluZyAtPiBpbnQgLT4gaW50MzIgPSBcIiVjYW1sX2JpZ3N0cmluZ19nZXQzMnVcIlxuZXh0ZXJuYWwgY2FtbF9iaWdzdHJpbmdfdW5zYWZlX2dldF82NCA6IGJpZ3N0cmluZyAtPiBpbnQgLT4gaW50NjQgPSBcIiVjYW1sX2JpZ3N0cmluZ19nZXQ2NHVcIlxuXG5tb2R1bGUgVVN3YXAgPSBzdHJ1Y3RcbiAgZXh0ZXJuYWwgYnN3YXAxNiA6IGludCAtPiBpbnQgPSBcIiVic3dhcDE2XCJcbiAgZXh0ZXJuYWwgYnN3YXBfaW50MzIgOiBpbnQzMiAtPiBpbnQzMiA9IFwiJWJzd2FwX2ludDMyXCJcbiAgZXh0ZXJuYWwgYnN3YXBfaW50NjQgOiBpbnQ2NCAtPiBpbnQ2NCA9IFwiJWJzd2FwX2ludDY0XCJcblxuICBsZXQgY2FtbF9iaWdzdHJpbmdfdW5zYWZlX3NldF8xNiBicyBvZmYgaSA9XG4gICAgY2FtbF9iaWdzdHJpbmdfdW5zYWZlX3NldF8xNiBicyBvZmYgKGJzd2FwMTYgaSlcblxuICBsZXQgY2FtbF9iaWdzdHJpbmdfdW5zYWZlX3NldF8zMiBicyBvZmYgaSA9XG4gICAgY2FtbF9iaWdzdHJpbmdfdW5zYWZlX3NldF8zMiBicyBvZmYgKGJzd2FwX2ludDMyIGkpXG5cbiAgbGV0IGNhbWxfYmlnc3RyaW5nX3Vuc2FmZV9zZXRfNjQgYnMgb2ZmIGkgPVxuICAgIGNhbWxfYmlnc3RyaW5nX3Vuc2FmZV9zZXRfNjQgYnMgb2ZmIChic3dhcF9pbnQ2NCBpKVxuXG4gIGxldCBjYW1sX2JpZ3N0cmluZ191bnNhZmVfZ2V0XzE2IGJzIG9mZiA9XG4gICAgYnN3YXAxNiAoY2FtbF9iaWdzdHJpbmdfdW5zYWZlX2dldF8xNiBicyBvZmYpXG5cbiAgbGV0IGNhbWxfYmlnc3RyaW5nX3Vuc2FmZV9nZXRfMzIgYnMgb2ZmID1cbiAgICBic3dhcF9pbnQzMiAoY2FtbF9iaWdzdHJpbmdfdW5zYWZlX2dldF8zMiBicyBvZmYpXG5cbiAgbGV0IGNhbWxfYmlnc3RyaW5nX3Vuc2FmZV9nZXRfNjQgYnMgb2ZmID1cbiAgICBic3dhcF9pbnQ2NCAoY2FtbF9iaWdzdHJpbmdfdW5zYWZlX2dldF82NCBicyBvZmYpXG5lbmRcblxubGV0IHVuc2FmZV9zZXRfaW50MTZfbGUsIHVuc2FmZV9zZXRfaW50MTZfYmUgPVxuICBpZiBTeXMuYmlnX2VuZGlhblxuICB0aGVuIFVTd2FwLmNhbWxfYmlnc3RyaW5nX3Vuc2FmZV9zZXRfMTYsIGNhbWxfYmlnc3RyaW5nX3Vuc2FmZV9zZXRfMTZcbiAgZWxzZSBjYW1sX2JpZ3N0cmluZ191bnNhZmVfc2V0XzE2ICAgICAgLCBVU3dhcC5jYW1sX2JpZ3N0cmluZ191bnNhZmVfc2V0XzE2XG5cbmxldCB1bnNhZmVfc2V0X2ludDMyX2xlLCB1bnNhZmVfc2V0X2ludDMyX2JlID1cbiAgaWYgU3lzLmJpZ19lbmRpYW5cbiAgdGhlbiBVU3dhcC5jYW1sX2JpZ3N0cmluZ191bnNhZmVfc2V0XzMyLCBjYW1sX2JpZ3N0cmluZ191bnNhZmVfc2V0XzMyXG4gIGVsc2UgY2FtbF9iaWdzdHJpbmdfdW5zYWZlX3NldF8zMiAgICAgICwgVVN3YXAuY2FtbF9iaWdzdHJpbmdfdW5zYWZlX3NldF8zMlxuXG5sZXQgdW5zYWZlX3NldF9pbnQ2NF9sZSwgdW5zYWZlX3NldF9pbnQ2NF9iZSA9XG4gIGlmIFN5cy5iaWdfZW5kaWFuXG4gIHRoZW4gVVN3YXAuY2FtbF9iaWdzdHJpbmdfdW5zYWZlX3NldF82NCwgY2FtbF9iaWdzdHJpbmdfdW5zYWZlX3NldF82NFxuICBlbHNlIGNhbWxfYmlnc3RyaW5nX3Vuc2FmZV9zZXRfNjQgICAgICAsIFVTd2FwLmNhbWxfYmlnc3RyaW5nX3Vuc2FmZV9zZXRfNjRcblxubGV0IHVuc2FmZV9nZXRfaW50MTZfbGUsIHVuc2FmZV9nZXRfaW50MTZfYmUgPVxuICBpZiBTeXMuYmlnX2VuZGlhblxuICB0aGVuIFVTd2FwLmNhbWxfYmlnc3RyaW5nX3Vuc2FmZV9nZXRfMTYsIGNhbWxfYmlnc3RyaW5nX3Vuc2FmZV9nZXRfMTZcbiAgZWxzZSBjYW1sX2JpZ3N0cmluZ191bnNhZmVfZ2V0XzE2ICAgICAgLCBVU3dhcC5jYW1sX2JpZ3N0cmluZ191bnNhZmVfZ2V0XzE2XG5cbmxldCB1bnNhZmVfZ2V0X2ludDE2X3NpZ25fZXh0ZW5kZWRfbGUgeCBvZmYgPVxuICAoKHVuc2FmZV9nZXRfaW50MTZfbGUgeCBvZmYpIGxzbCAoU3lzLmludF9zaXplIC0gMTYpKSBhc3IgKFN5cy5pbnRfc2l6ZSAtIDE2KVxuXG5sZXQgdW5zYWZlX2dldF9pbnQxNl9zaWduX2V4dGVuZGVkX2JlIHggb2ZmID1cbiAgKCh1bnNhZmVfZ2V0X2ludDE2X2JlIHggb2ZmICkgbHNsIChTeXMuaW50X3NpemUgLSAxNikpIGFzciAoU3lzLmludF9zaXplIC0gMTYpXG5cbmxldCB1bnNhZmVfZ2V0X2ludDMyX2xlLCB1bnNhZmVfZ2V0X2ludDMyX2JlID1cbiAgaWYgU3lzLmJpZ19lbmRpYW5cbiAgdGhlbiBVU3dhcC5jYW1sX2JpZ3N0cmluZ191bnNhZmVfZ2V0XzMyLCBjYW1sX2JpZ3N0cmluZ191bnNhZmVfZ2V0XzMyXG4gIGVsc2UgY2FtbF9iaWdzdHJpbmdfdW5zYWZlX2dldF8zMiAgICAgICwgVVN3YXAuY2FtbF9iaWdzdHJpbmdfdW5zYWZlX2dldF8zMlxuXG5sZXQgdW5zYWZlX2dldF9pbnQ2NF9sZSwgdW5zYWZlX2dldF9pbnQ2NF9iZSA9XG4gIGlmIFN5cy5iaWdfZW5kaWFuXG4gIHRoZW4gVVN3YXAuY2FtbF9iaWdzdHJpbmdfdW5zYWZlX2dldF82NCwgY2FtbF9iaWdzdHJpbmdfdW5zYWZlX2dldF82NFxuICBlbHNlIGNhbWxfYmlnc3RyaW5nX3Vuc2FmZV9nZXRfNjQgICAgICAsIFVTd2FwLmNhbWxfYmlnc3RyaW5nX3Vuc2FmZV9nZXRfNjRcbiIsInR5cGUgJ2Egc3RhdGUgPVxuICB8IFBhcnRpYWwgb2YgJ2EgcGFydGlhbFxuICB8IERvbmUgICAgb2YgaW50ICogJ2FcbiAgfCBGYWlsICAgIG9mIGludCAqIHN0cmluZyBsaXN0ICogc3RyaW5nXG5cbmFuZCAnYSBwYXJ0aWFsID1cbiAgeyBjb21taXR0ZWQgOiBpbnRcbiAgOyBjb250aW51ZSAgOiBCaWdzdHJpbmdhZi50IC0+IG9mZjppbnQgLT4gbGVuOmludCAtPiBNb3JlLnQgLT4gJ2Egc3RhdGUgfVxuXG5cbmxldCBzdGF0ZV90b19vcHRpb24geCA9IG1hdGNoIHggd2l0aFxuICB8IERvbmUoXywgdikgLT4gU29tZSB2XG4gIHwgRmFpbCBfICAgICAtPiBOb25lXG4gIHwgUGFydGlhbCBfICAtPiBOb25lXG5cbmxldCBmYWlsX3RvX3N0cmluZyBtYXJrcyBlcnIgPVxuICBTdHJpbmcuY29uY2F0IFwiID4gXCIgbWFya3MgXiBcIjogXCIgXiBlcnJcblxubGV0IHN0YXRlX3RvX3Jlc3VsdCB4ID0gbWF0Y2ggeCB3aXRoXG4gIHwgRG9uZShfLCB2KSAgICAgICAgICAtPiBPayB2XG4gIHwgUGFydGlhbCBfICAgICAgICAgICAtPiBFcnJvciBcImluY29tcGxldGUgaW5wdXRcIlxuICB8IEZhaWwoXywgbWFya3MsIGVycikgLT4gRXJyb3IgKGZhaWxfdG9fc3RyaW5nIG1hcmtzIGVycilcbiIsIigqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIENvcHlyaWdodCAoYykgMjAxNyBJbmhhYml0ZWQgVHlwZSBMTEMuXG5cbiAgICBBbGwgcmlnaHRzIHJlc2VydmVkLlxuXG4gICAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gICAgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zXG4gICAgYXJlIG1ldDpcblxuICAgIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0XG4gICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuXG4gICAgMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAgICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlXG4gICAgICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cblxuICAgIDMuIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIGF1dGhvciBub3IgdGhlIG5hbWVzIG9mIGhpcyBjb250cmlidXRvcnNcbiAgICAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiAgICAgICB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cblxuICAgIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTXG4gICAgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRURcbiAgICBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gICAgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SXG4gICAgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTFxuICAgIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTXG4gICAgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pXG4gICAgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULFxuICAgIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTlxuICAgIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuICAgIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKilcblxudHlwZSB0ID1cbiAgeyBtdXRhYmxlIHBhcnNlcl9jb21taXR0ZWRfYnl0ZXMgOiBpbnRcbiAgOyBjbGllbnRfY29tbWl0dGVkX2J5dGVzICAgICAgICAgOiBpbnRcbiAgOyBvZmYgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBpbnRcbiAgOyBsZW4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBpbnRcbiAgOyBidWZmZXIgICAgICAgICAgICAgICAgICAgICAgICAgOiBCaWdzdHJpbmdhZi50XG4gIH1cblxubGV0IGNyZWF0ZSBidWZmZXIgfm9mZiB+bGVuIH5jb21taXR0ZWRfYnl0ZXMgPVxuICB7IHBhcnNlcl9jb21taXR0ZWRfYnl0ZXMgPSBjb21taXR0ZWRfYnl0ZXNcbiAgOyBjbGllbnRfY29tbWl0dGVkX2J5dGVzID0gY29tbWl0dGVkX2J5dGVzXG4gIDsgb2ZmXG4gIDsgbGVuXG4gIDsgYnVmZmVyIH1cblxubGV0IGxlbmd0aCAgICAgICAgICAgICAgICAgdCA9IHQuY2xpZW50X2NvbW1pdHRlZF9ieXRlcyArIHQubGVuXG5sZXQgY2xpZW50X2NvbW1pdHRlZF9ieXRlcyB0ID0gdC5jbGllbnRfY29tbWl0dGVkX2J5dGVzXG5sZXQgcGFyc2VyX2NvbW1pdHRlZF9ieXRlcyB0ID0gdC5wYXJzZXJfY29tbWl0dGVkX2J5dGVzXG5cbmxldCBjb21taXR0ZWRfYnl0ZXNfZGlzY3JlcGFuY3kgdCA9IHQucGFyc2VyX2NvbW1pdHRlZF9ieXRlcyAtIHQuY2xpZW50X2NvbW1pdHRlZF9ieXRlc1xubGV0IGJ5dGVzX2Zvcl9jbGllbnRfdG9fY29tbWl0ICB0ID0gY29tbWl0dGVkX2J5dGVzX2Rpc2NyZXBhbmN5IHRcblxubGV0IHBhcnNlcl91bmNvbW1pdHRlZF9ieXRlcyB0ID0gdC5sZW4gLSBieXRlc19mb3JfY2xpZW50X3RvX2NvbW1pdCB0XG5cbmxldCBpbnZhcmlhbnQgdCA9XG4gIGFzc2VydCAocGFyc2VyX2NvbW1pdHRlZF9ieXRlcyB0ICsgcGFyc2VyX3VuY29tbWl0dGVkX2J5dGVzIHQgPSBsZW5ndGggdCk7XG4gIGFzc2VydCAocGFyc2VyX2NvbW1pdHRlZF9ieXRlcyB0IC0gY2xpZW50X2NvbW1pdHRlZF9ieXRlcyAgIHQgPSBieXRlc19mb3JfY2xpZW50X3RvX2NvbW1pdCB0KTtcbjs7XG5cbmxldCBvZmZzZXRfaW5fYnVmZmVyIHQgcG9zID1cbiAgdC5vZmYgKyBwb3MgLSB0LmNsaWVudF9jb21taXR0ZWRfYnl0ZXNcblxubGV0IGFwcGx5IHQgcG9zIGxlbiB+ZiA9XG4gIGxldCBvZmYgPSBvZmZzZXRfaW5fYnVmZmVyIHQgcG9zIGluXG4gIGYgdC5idWZmZXIgfm9mZiB+bGVuXG5cbmxldCB1bnNhZmVfZ2V0X2NoYXIgdCBwb3MgPVxuICBsZXQgb2ZmID0gb2Zmc2V0X2luX2J1ZmZlciB0IHBvcyBpblxuICBCaWdzdHJpbmdhZi51bnNhZmVfZ2V0IHQuYnVmZmVyIG9mZlxuXG5sZXQgdW5zYWZlX2dldF9pbnQxNl9sZSB0IHBvcyA9XG4gIGxldCBvZmYgPSBvZmZzZXRfaW5fYnVmZmVyIHQgcG9zIGluXG4gIEJpZ3N0cmluZ2FmLnVuc2FmZV9nZXRfaW50MTZfbGUgdC5idWZmZXIgb2ZmXG5cbmxldCB1bnNhZmVfZ2V0X2ludDMyX2xlIHQgcG9zID1cbiAgbGV0IG9mZiA9IG9mZnNldF9pbl9idWZmZXIgdCBwb3MgaW5cbiAgQmlnc3RyaW5nYWYudW5zYWZlX2dldF9pbnQzMl9sZSB0LmJ1ZmZlciBvZmZcblxubGV0IHVuc2FmZV9nZXRfaW50NjRfbGUgdCBwb3MgPVxuICBsZXQgb2ZmID0gb2Zmc2V0X2luX2J1ZmZlciB0IHBvcyBpblxuICBCaWdzdHJpbmdhZi51bnNhZmVfZ2V0X2ludDY0X2xlIHQuYnVmZmVyIG9mZlxuXG5sZXQgdW5zYWZlX2dldF9pbnQxNl9iZSB0IHBvcyA9XG4gIGxldCBvZmYgPSBvZmZzZXRfaW5fYnVmZmVyIHQgcG9zIGluXG4gIEJpZ3N0cmluZ2FmLnVuc2FmZV9nZXRfaW50MTZfYmUgdC5idWZmZXIgb2ZmXG5cbmxldCB1bnNhZmVfZ2V0X2ludDMyX2JlIHQgcG9zID1cbiAgbGV0IG9mZiA9IG9mZnNldF9pbl9idWZmZXIgdCBwb3MgaW5cbiAgQmlnc3RyaW5nYWYudW5zYWZlX2dldF9pbnQzMl9iZSB0LmJ1ZmZlciBvZmZcblxubGV0IHVuc2FmZV9nZXRfaW50NjRfYmUgdCBwb3MgPVxuICBsZXQgb2ZmID0gb2Zmc2V0X2luX2J1ZmZlciB0IHBvcyBpblxuICBCaWdzdHJpbmdhZi51bnNhZmVfZ2V0X2ludDY0X2JlIHQuYnVmZmVyIG9mZlxuXG5sZXQgY291bnRfd2hpbGUgdCBwb3MgfmYgPVxuICBsZXQgYnVmZmVyID0gdC5idWZmZXIgaW5cbiAgbGV0IG9mZiAgICA9IG9mZnNldF9pbl9idWZmZXIgdCBwb3MgaW5cbiAgbGV0IGkgICAgICA9IHJlZiBvZmYgaW5cbiAgbGV0IGxpbWl0ICA9IHQub2ZmICsgdC5sZW4gaW5cbiAgd2hpbGUgIWkgPCBsaW1pdCAmJiBmIChCaWdzdHJpbmdhZi51bnNhZmVfZ2V0IGJ1ZmZlciAhaSkgZG9cbiAgICBpbmNyIGlcbiAgZG9uZTtcbiAgIWkgLSBvZmZcbjs7XG5cbmxldCBjb21taXQgdCBwb3MgPVxuICB0LnBhcnNlcl9jb21taXR0ZWRfYnl0ZXMgPC0gcG9zXG47O1xuIiwibW9kdWxlIFN0YXRlID0gc3RydWN0XG4gIHR5cGUgJ2EgdCA9XG4gICAgfCBQYXJ0aWFsIG9mICdhIHBhcnRpYWxcbiAgICB8IExhenkgICAgb2YgJ2EgdCBMYXp5LnRcbiAgICB8IERvbmUgICAgb2YgaW50ICogJ2FcbiAgICB8IEZhaWwgICAgb2YgaW50ICogc3RyaW5nIGxpc3QgKiBzdHJpbmdcblxuICBhbmQgJ2EgcGFydGlhbCA9XG4gICAgeyBjb21taXR0ZWQgOiBpbnRcbiAgICA7IGNvbnRpbnVlICA6IEJpZ3N0cmluZ2FmLnQgLT4gb2ZmOmludCAtPiBsZW46aW50IC0+IE1vcmUudCAtPiAnYSB0IH1cblxuZW5kXG50eXBlICdhIHdpdGhfc3RhdGUgPSBJbnB1dC50IC0+ICBpbnQgLT4gTW9yZS50IC0+ICdhXG5cbnR5cGUgJ2EgZmFpbHVyZSA9IChzdHJpbmcgbGlzdCAtPiBzdHJpbmcgLT4gJ2EgU3RhdGUudCkgd2l0aF9zdGF0ZVxudHlwZSAoJ2EsICdyKSBzdWNjZXNzID0gKCdhIC0+ICdyIFN0YXRlLnQpIHdpdGhfc3RhdGVcblxudHlwZSAnYSB0ID1cbiAgeyBydW4gOiAnci4gKCdyIGZhaWx1cmUgLT4gKCdhLCAncikgc3VjY2VzcyAtPiAnciBTdGF0ZS50KSB3aXRoX3N0YXRlIH1cblxubGV0IGZhaWxfayAgICBpbnB1dCBwb3MgXyBtYXJrcyBtc2cgPVxuICBTdGF0ZS5GYWlsKHBvcyAtIElucHV0LmNsaWVudF9jb21taXR0ZWRfYnl0ZXMgaW5wdXQsIG1hcmtzLCBtc2cpXG5sZXQgc3VjY2VlZF9rIGlucHV0IHBvcyBfICAgICAgIHYgICA9XG4gIFN0YXRlLkRvbmUocG9zIC0gSW5wdXQuY2xpZW50X2NvbW1pdHRlZF9ieXRlcyBpbnB1dCwgdilcblxubGV0IHJlYyB0b19leHBvcnRlZF9zdGF0ZSA9IGZ1bmN0aW9uXG4gIHwgU3RhdGUuUGFydGlhbCB7Y29tbWl0dGVkO2NvbnRpbnVlfSAtPlxuICAgICBFeHBvcnRlZF9zdGF0ZS5QYXJ0aWFsXG4gICAgICAgeyBjb21taXR0ZWRcbiAgICAgICA7IGNvbnRpbnVlID1cbiAgICAgICAgICAgZnVuIGJzIH5vZmYgfmxlbiBtb3JlIC0+XG4gICAgICAgICAgIHRvX2V4cG9ydGVkX3N0YXRlIChjb250aW51ZSBicyB+b2ZmIH5sZW4gbW9yZSl9XG4gIHwgU3RhdGUuRG9uZSAoaSx4KSAtPiBFeHBvcnRlZF9zdGF0ZS5Eb25lIChpLHgpXG4gIHwgU3RhdGUuRmFpbCAoaSwgc2wsIHMpIC0+IEV4cG9ydGVkX3N0YXRlLkZhaWwgKGksIHNsLCBzKVxuICB8IFN0YXRlLkxhenkgeCAtPiB0b19leHBvcnRlZF9zdGF0ZSAoTGF6eS5mb3JjZSB4KVxuXG5sZXQgcGFyc2UgcCA9XG4gIGxldCBpbnB1dCA9IElucHV0LmNyZWF0ZSBCaWdzdHJpbmdhZi5lbXB0eSB+Y29tbWl0dGVkX2J5dGVzOjAgfm9mZjowIH5sZW46MCBpblxuICB0b19leHBvcnRlZF9zdGF0ZSAocC5ydW4gaW5wdXQgMCBJbmNvbXBsZXRlIGZhaWxfayBzdWNjZWVkX2spXG5cbmxldCBwYXJzZV9iaWdzdHJpbmcgcCBpbnB1dCA9XG4gIGxldCBpbnB1dCA9IElucHV0LmNyZWF0ZSBpbnB1dCB+Y29tbWl0dGVkX2J5dGVzOjAgfm9mZjowIH5sZW46KEJpZ3N0cmluZ2FmLmxlbmd0aCBpbnB1dCkgaW5cbiAgRXhwb3J0ZWRfc3RhdGUuc3RhdGVfdG9fcmVzdWx0ICh0b19leHBvcnRlZF9zdGF0ZSAocC5ydW4gaW5wdXQgMCBDb21wbGV0ZSBmYWlsX2sgc3VjY2VlZF9rKSlcblxubW9kdWxlIE1vbmFkID0gc3RydWN0XG4gIGxldCByZXR1cm4gdiA9XG4gICAgeyBydW4gPSBmdW4gaW5wdXQgcG9zIG1vcmUgX2ZhaWwgc3VjYyAtPlxuICAgICAgc3VjYyBpbnB1dCBwb3MgbW9yZSB2XG4gICAgfVxuXG4gIGxldCBmYWlsIG1zZyA9XG4gICAgeyBydW4gPSBmdW4gaW5wdXQgcG9zIG1vcmUgZmFpbCBfc3VjYyAtPlxuICAgICAgZmFpbCBpbnB1dCBwb3MgbW9yZSBbXSBtc2dcbiAgICB9XG5cbiAgbGV0ICg+Pj0pIHAgZiA9XG4gICAgeyBydW4gPSBmdW4gaW5wdXQgcG9zIG1vcmUgZmFpbCBzdWNjIC0+XG4gICAgICBsZXQgc3VjYycgaW5wdXQnIHBvcycgbW9yZScgdiA9IChmIHYpLnJ1biBpbnB1dCcgcG9zJyBtb3JlJyBmYWlsIHN1Y2MgaW5cbiAgICAgIHAucnVuIGlucHV0IHBvcyBtb3JlIGZhaWwgc3VjYydcbiAgICB9XG5cbiAgbGV0ICg+PnwpIHAgZiA9XG4gICAgeyBydW4gPSBmdW4gaW5wdXQgcG9zIG1vcmUgZmFpbCBzdWNjIC0+XG4gICAgICBsZXQgc3VjYycgaW5wdXQnIHBvcycgbW9yZScgdiA9IHN1Y2MgaW5wdXQnIHBvcycgbW9yZScgKGYgdikgaW5cbiAgICAgIHAucnVuIGlucHV0IHBvcyBtb3JlIGZhaWwgc3VjYydcbiAgICB9XG5cbiAgbGV0ICg8JD4pIGYgbSA9XG4gICAgbSA+PnwgZlxuXG4gIGxldCAoPCo+KSBmIG0gPVxuICAgICgqIGYgPj49IGZ1biBmIC0+IG0gPj58IGYgKilcbiAgICB7IHJ1biA9IGZ1biBpbnB1dCBwb3MgbW9yZSBmYWlsIHN1Y2MgLT5cbiAgICAgIGxldCBzdWNjMCBpbnB1dDAgcG9zMCBtb3JlMCBmID1cbiAgICAgICAgbGV0IHN1Y2MxIGlucHV0MSBwb3MxIG1vcmUxIG0gPSBzdWNjIGlucHV0MSBwb3MxIG1vcmUxIChmIG0pIGluXG4gICAgICAgIG0ucnVuIGlucHV0MCBwb3MwIG1vcmUwIGZhaWwgc3VjYzFcbiAgICAgIGluXG4gICAgICBmLnJ1biBpbnB1dCBwb3MgbW9yZSBmYWlsIHN1Y2MwIH1cblxuICBsZXQgbGlmdCBmIG0gPVxuICAgIGYgPCQ+IG1cblxuICBsZXQgbGlmdDIgZiBtMSBtMiA9XG4gICAgeyBydW4gPSBmdW4gaW5wdXQgcG9zIG1vcmUgZmFpbCBzdWNjIC0+XG4gICAgICBsZXQgc3VjYzEgaW5wdXQxIHBvczEgbW9yZTEgbTEgPVxuICAgICAgICBsZXQgc3VjYzIgaW5wdXQyIHBvczIgbW9yZTIgbTIgPSBzdWNjIGlucHV0MiBwb3MyIG1vcmUyIChmIG0xIG0yKSBpblxuICAgICAgICBtMi5ydW4gaW5wdXQxIHBvczEgbW9yZTEgZmFpbCBzdWNjMlxuICAgICAgaW5cbiAgICAgIG0xLnJ1biBpbnB1dCBwb3MgbW9yZSBmYWlsIHN1Y2MxIH1cblxuICBsZXQgbGlmdDMgZiBtMSBtMiBtMyA9XG4gICAgeyBydW4gPSBmdW4gaW5wdXQgcG9zIG1vcmUgZmFpbCBzdWNjIC0+XG4gICAgICBsZXQgc3VjYzEgaW5wdXQxIHBvczEgbW9yZTEgbTEgPVxuICAgICAgICBsZXQgc3VjYzIgaW5wdXQyIHBvczIgbW9yZTIgbTIgPVxuICAgICAgICAgIGxldCBzdWNjMyBpbnB1dDMgcG9zMyBtb3JlMyBtMyA9XG4gICAgICAgICAgICBzdWNjIGlucHV0MyBwb3MzIG1vcmUzIChmIG0xIG0yIG0zKSBpblxuICAgICAgICAgIG0zLnJ1biBpbnB1dDIgcG9zMiBtb3JlMiBmYWlsIHN1Y2MzIGluXG4gICAgICAgIG0yLnJ1biBpbnB1dDEgcG9zMSBtb3JlMSBmYWlsIHN1Y2MyXG4gICAgICBpblxuICAgICAgbTEucnVuIGlucHV0IHBvcyBtb3JlIGZhaWwgc3VjYzEgfVxuXG4gIGxldCBsaWZ0NCBmIG0xIG0yIG0zIG00ID1cbiAgICB7IHJ1biA9IGZ1biBpbnB1dCBwb3MgbW9yZSBmYWlsIHN1Y2MgLT5cbiAgICAgIGxldCBzdWNjMSBpbnB1dDEgcG9zMSBtb3JlMSBtMSA9XG4gICAgICAgIGxldCBzdWNjMiBpbnB1dDIgcG9zMiBtb3JlMiBtMiA9XG4gICAgICAgICAgbGV0IHN1Y2MzIGlucHV0MyBwb3MzIG1vcmUzIG0zID1cbiAgICAgICAgICAgIGxldCBzdWNjNCBpbnB1dDQgcG9zNCBtb3JlNCBtNCA9XG4gICAgICAgICAgICAgIHN1Y2MgaW5wdXQ0IHBvczQgbW9yZTQgKGYgbTEgbTIgbTMgbTQpIGluXG4gICAgICAgICAgICBtNC5ydW4gaW5wdXQzIHBvczMgbW9yZTMgZmFpbCBzdWNjNCBpblxuICAgICAgICAgIG0zLnJ1biBpbnB1dDIgcG9zMiBtb3JlMiBmYWlsIHN1Y2MzIGluXG4gICAgICAgIG0yLnJ1biBpbnB1dDEgcG9zMSBtb3JlMSBmYWlsIHN1Y2MyXG4gICAgICBpblxuICAgICAgbTEucnVuIGlucHV0IHBvcyBtb3JlIGZhaWwgc3VjYzEgfVxuXG4gIGxldCAoICo+KSBhIGIgPVxuICAgICgqIGEgPj49IGZ1biBfIC0+IGIgKilcbiAgICB7IHJ1biA9IGZ1biBpbnB1dCBwb3MgbW9yZSBmYWlsIHN1Y2MgLT5cbiAgICAgIGxldCBzdWNjJyBpbnB1dCcgcG9zJyBtb3JlJyBfID0gYi5ydW4gaW5wdXQnIHBvcycgbW9yZScgZmFpbCBzdWNjIGluXG4gICAgICBhLnJ1biBpbnB1dCBwb3MgbW9yZSBmYWlsIHN1Y2MnXG4gICAgfVxuXG4gIGxldCAoPCogKSBhIGIgPVxuICAgICgqIGEgPj49IGZ1biB4IC0+IGIgPj58IGZ1biBfIC0+IHggKilcbiAgICB7IHJ1biA9IGZ1biBpbnB1dCBwb3MgbW9yZSBmYWlsIHN1Y2MgLT5cbiAgICAgIGxldCBzdWNjMCBpbnB1dDAgcG9zMCBtb3JlMCB4ID1cbiAgICAgICAgbGV0IHN1Y2MxIGlucHV0MSBwb3MxIG1vcmUxIF8gPSBzdWNjIGlucHV0MSBwb3MxIG1vcmUxIHggaW5cbiAgICAgICAgYi5ydW4gaW5wdXQwIHBvczAgbW9yZTAgZmFpbCBzdWNjMVxuICAgICAgaW5cbiAgICAgIGEucnVuIGlucHV0IHBvcyBtb3JlIGZhaWwgc3VjYzAgfVxuZW5kXG5cbm1vZHVsZSBDaG9pY2UgPSBzdHJ1Y3RcbiAgbGV0ICg8Pz4pIHAgbWFyayA9XG4gICAgeyBydW4gPSBmdW4gaW5wdXQgcG9zIG1vcmUgZmFpbCBzdWNjIC0+XG4gICAgICBsZXQgZmFpbCcgaW5wdXQnIHBvcycgbW9yZScgbWFya3MgbXNnID1cbiAgICAgICAgZmFpbCBpbnB1dCcgcG9zJyBtb3JlJyAobWFyazo6bWFya3MpIG1zZyBpblxuICAgICAgcC5ydW4gaW5wdXQgcG9zIG1vcmUgZmFpbCcgc3VjY1xuICAgIH1cblxuICBsZXQgKDx8PikgcCBxID1cbiAgICB7IHJ1biA9IGZ1biBpbnB1dCBwb3MgbW9yZSBmYWlsIHN1Y2MgLT5cbiAgICAgIGxldCBmYWlsJyBpbnB1dCcgcG9zJyBtb3JlJyBtYXJrcyBtc2cgPVxuICAgICAgICAoKiBUaGUgb25seSB0d28gY29uc3RydWN0b3JzIHRoYXQgaW50cm9kdWNlIG5ldyBmYWlsdXJlIGNvbnRpbnVhdGlvbnMgYXJlXG4gICAgICAgICAqIFs8Pz5dIGFuZCBbPHw+XS4gSWYgdGhlIGluaXRpYWwgaW5wdXQgcG9zaXRpb24gaXMgbGVzcyB0aGFuIHRoZSBsZW5ndGhcbiAgICAgICAgICogb2YgdGhlIGNvbW1pdHRlZCBpbnB1dCwgdGhlbiBjYWxsaW5nIHRoZSBmYWlsdXJlIGNvbnRpbnVhdGlvbiB3aWxsXG4gICAgICAgICAqIGhhdmUgdGhlIGVmZmVjdCBvZiB1bndpbmRpbmcgYWxsIGNob2ljZXMgYW5kIGNvbGxlY3RpbmcgbWFya3MgYWxvbmdcbiAgICAgICAgICogdGhlIHdheS4gKilcbiAgICAgICAgaWYgcG9zIDwgSW5wdXQucGFyc2VyX2NvbW1pdHRlZF9ieXRlcyBpbnB1dCcgdGhlblxuICAgICAgICAgIGZhaWwgaW5wdXQnIHBvcycgbW9yZSBtYXJrcyBtc2dcbiAgICAgICAgZWxzZVxuICAgICAgICAgIHEucnVuIGlucHV0JyBwb3MgbW9yZScgZmFpbCBzdWNjIGluXG4gICAgICBwLnJ1biBpbnB1dCBwb3MgbW9yZSBmYWlsJyBzdWNjXG4gICAgfVxuZW5kXG5cbm1vZHVsZSBNb25hZF91c2VfZm9yX2RlYnVnZ2luZyA9IHN0cnVjdFxuICBsZXQgcmV0dXJuID0gTW9uYWQucmV0dXJuXG4gIGxldCBmYWlsICAgPSBNb25hZC5mYWlsXG4gIGxldCAoPj49KSAgPSBNb25hZC4oPj49KVxuXG4gIGxldCAoPj58KSBtIGYgPSBtID4+PSBmdW4geCAtPiByZXR1cm4gKGYgeClcblxuICBsZXQgKDwkPikgZiBtID0gbSA+PnwgZlxuICBsZXQgKDwqPikgZiBtID0gZiA+Pj0gZnVuIGYgLT4gbSA+PnwgZlxuXG4gIGxldCBsaWZ0ICA9ICg+PnwpXG4gIGxldCBsaWZ0MiBmIG0xIG0yICAgICAgID0gZiA8JD4gbTEgPCo+IG0yXG4gIGxldCBsaWZ0MyBmIG0xIG0yIG0zICAgID0gZiA8JD4gbTEgPCo+IG0yIDwqPiBtM1xuICBsZXQgbGlmdDQgZiBtMSBtMiBtMyBtNCA9IGYgPCQ+IG0xIDwqPiBtMiA8Kj4gbTMgPCo+IG00XG5cbiAgbGV0ICggKj4pIGEgYiA9IGEgPj49IGZ1biBfIC0+IGJcbiAgbGV0ICg8KiApIGEgYiA9IGEgPj49IGZ1biB4IC0+IGIgPj58IGZ1biBfIC0+IHhcbmVuZFxuIiwidHlwZSB0ID1cbiAgeyBtdXRhYmxlIGJ1ZiA6IEJpZ3N0cmluZ2FmLnRcbiAgOyBtdXRhYmxlIG9mZiA6IGludFxuICA7IG11dGFibGUgbGVuIDogaW50IH1cblxubGV0IG9mX2JpZ3N0cmluZyB+b2ZmIH5sZW4gYnVmID1cbiAgYXNzZXJ0IChvZmYgPj0gMCk7XG4gIGFzc2VydCAoQmlnc3RyaW5nYWYubGVuZ3RoIGJ1ZiA+PSBsZW4gLSBvZmYpO1xuICB7IGJ1Zjsgb2ZmOyBsZW4gfVxuXG5sZXQgY3JlYXRlIGxlbiA9XG4gIG9mX2JpZ3N0cmluZyB+b2ZmOjAgfmxlbjowIChCaWdzdHJpbmdhZi5jcmVhdGUgbGVuKVxuXG5sZXQgd3JpdGFibGVfc3BhY2UgdCA9XG4gIEJpZ3N0cmluZ2FmLmxlbmd0aCB0LmJ1ZiAtIHQubGVuXG5cbmxldCB0cmFpbGluZ19zcGFjZSB0ID1cbiAgQmlnc3RyaW5nYWYubGVuZ3RoIHQuYnVmIC0gKHQub2ZmICsgdC5sZW4pXG5cbmxldCBjb21wcmVzcyB0ID1cbiAgQmlnc3RyaW5nYWYudW5zYWZlX2JsaXQgdC5idWYgfnNyY19vZmY6dC5vZmYgdC5idWYgfmRzdF9vZmY6MCB+bGVuOnQubGVuO1xuICB0Lm9mZiA8LSAwXG5cbmxldCBncm93IHQgdG9fY29weSA9XG4gIGxldCBvbGRfbGVuID0gQmlnc3RyaW5nYWYubGVuZ3RoIHQuYnVmIGluXG4gIGxldCBuZXdfbGVuID0gcmVmIG9sZF9sZW4gaW5cbiAgbGV0IHNwYWNlID0gd3JpdGFibGVfc3BhY2UgdCBpblxuICB3aGlsZSBzcGFjZSArICFuZXdfbGVuIC0gb2xkX2xlbiA8IHRvX2NvcHkgZG9cbiAgICBuZXdfbGVuIDo9ICgzICogIW5ld19sZW4pIC8gMlxuICBkb25lO1xuICBsZXQgbmV3X2J1ZiA9IEJpZ3N0cmluZ2FmLmNyZWF0ZSAhbmV3X2xlbiBpblxuICBCaWdzdHJpbmdhZi51bnNhZmVfYmxpdCB0LmJ1ZiB+c3JjX29mZjp0Lm9mZiBuZXdfYnVmIH5kc3Rfb2ZmOjAgfmxlbjp0LmxlbjtcbiAgdC5idWYgPC0gbmV3X2J1ZjtcbiAgdC5vZmYgPC0gMFxuXG5sZXQgZW5zdXJlIHQgdG9fY29weSA9XG4gIGlmIHRyYWlsaW5nX3NwYWNlIHQgPCB0b19jb3B5IHRoZW5cbiAgICBpZiB3cml0YWJsZV9zcGFjZSB0ID49IHRvX2NvcHlcbiAgICB0aGVuIGNvbXByZXNzIHRcbiAgICBlbHNlIGdyb3cgdCB0b19jb3B5XG5cbmxldCB3cml0ZV9wb3MgdCA9XG4gIHQub2ZmICsgdC5sZW5cblxubGV0IGZlZWRfc3RyaW5nIHQgfm9mZiB+bGVuIHN0ciA9XG4gIGFzc2VydCAob2ZmID49IDApO1xuICBhc3NlcnQgKFN0cmluZy5sZW5ndGggc3RyID49IGxlbiAtIG9mZik7XG4gIGVuc3VyZSB0IGxlbjtcbiAgQmlnc3RyaW5nYWYudW5zYWZlX2JsaXRfZnJvbV9zdHJpbmcgc3RyIH5zcmNfb2ZmOm9mZiB0LmJ1ZiB+ZHN0X29mZjood3JpdGVfcG9zIHQpIH5sZW47XG4gIHQubGVuIDwtIHQubGVuICsgbGVuXG5cbmxldCBmZWVkX2JpZ3N0cmluZyB0IH5vZmYgfmxlbiBiID1cbiAgYXNzZXJ0IChvZmYgPj0gMCk7XG4gIGFzc2VydCAoQmlnc3RyaW5nYWYubGVuZ3RoIGIgPj0gbGVuIC0gb2ZmKTtcbiAgZW5zdXJlIHQgbGVuO1xuICBCaWdzdHJpbmdhZi51bnNhZmVfYmxpdCBiIH5zcmNfb2ZmOm9mZiB0LmJ1ZiB+ZHN0X29mZjood3JpdGVfcG9zIHQpIH5sZW47XG4gIHQubGVuIDwtIHQubGVuICsgbGVuXG5cbmxldCBmZWVkX2lucHV0IHQgPSBmdW5jdGlvblxuICB8IGBTdHJpbmcgICAgcyAtPiBmZWVkX3N0cmluZyAgICB0IH5vZmY6MCB+bGVuOihTdHJpbmcgICAgIC5sZW5ndGggcykgc1xuICB8IGBCaWdzdHJpbmcgYiAtPiBmZWVkX2JpZ3N0cmluZyB0IH5vZmY6MCB+bGVuOihCaWdzdHJpbmdhZi5sZW5ndGggYikgYlxuXG5sZXQgc2hpZnQgdCBuID1cbiAgYXNzZXJ0ICh0LmxlbiA+PSBuKTtcbiAgdC5vZmYgPC0gdC5vZmYgKyBuO1xuICB0LmxlbiA8LSB0LmxlbiAtIG5cblxubGV0IGZvcl9yZWFkaW5nIHsgYnVmOyBvZmY7IGxlbiB9ID1cbiAgQmlnc3RyaW5nYWYuc3ViIH5vZmYgfmxlbiBidWZcblxubW9kdWxlIFVuY29uc3VtZWQgPSBzdHJ1Y3RcbiAgdHlwZSB0ID1cbiAgICB7IGJ1ZiA6IEJpZ3N0cmluZ2FmLnRcbiAgICA7IG9mZiA6IGludFxuICAgIDsgbGVuIDogaW50IH1cbmVuZFxuXG5sZXQgdW5jb25zdW1lZCA/KHNoaWZ0PTApIHsgYnVmOyBvZmY7IGxlbiB9ID1cbiAgYXNzZXJ0IChsZW4gPj0gc2hpZnQpO1xuICB7IFVuY29uc3VtZWQuYnVmOyBvZmYgPSBvZmYgKyBzaGlmdDsgbGVuID0gbGVuIC0gc2hpZnQgfVxuXG5sZXQgb2ZfdW5jb25zdW1lZCB7IFVuY29uc3VtZWQuYnVmOyBvZmY7IGxlbiB9ID1cbiAgeyBidWY7IG9mZjsgbGVuIH1cblxudHlwZSB1bmNvbnN1bWVkID0gVW5jb25zdW1lZC50ID1cbiAgeyBidWYgOiBCaWdzdHJpbmdhZi50XG4gIDsgb2ZmIDogaW50XG4gIDsgbGVuIDogaW50IH1cbiIsIigqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIENvcHlyaWdodCAoYykgMjAxNiBJbmhhYml0ZWQgVHlwZSBMTEMuXG5cbiAgICBBbGwgcmlnaHRzIHJlc2VydmVkLlxuXG4gICAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gICAgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zXG4gICAgYXJlIG1ldDpcblxuICAgIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0XG4gICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuXG4gICAgMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAgICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlXG4gICAgICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cblxuICAgIDMuIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIGF1dGhvciBub3IgdGhlIG5hbWVzIG9mIGhpcyBjb250cmlidXRvcnNcbiAgICAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiAgICAgICB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cblxuICAgIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTXG4gICAgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRURcbiAgICBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gICAgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SXG4gICAgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTFxuICAgIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTXG4gICAgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pXG4gICAgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULFxuICAgIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTlxuICAgIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuICAgIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKilcblxubW9kdWxlIEJpZ2FycmF5ID0gc3RydWN0XG4gICgqIERvIG5vdCBhY2Nlc3MgQmlnYXJyYXkgb3BlcmF0aW9ucyBkaXJlY3RseS4gSWYgYW55dGhpbmcncyBuZWVkZWQsIHJlZmVyIHRvXG4gICAqIHRoZSBpbnRlcm5hbCBCaWdzdHJpbmcgbW9kdWxlLiAqKVxuZW5kXG5cbnR5cGUgYmlnc3RyaW5nID0gQmlnc3RyaW5nYWYudFxuXG5cbm1vZHVsZSBVbmJ1ZmZlcmVkID0gc3RydWN0XG4gIGluY2x1ZGUgUGFyc2VyXG5cbiAgaW5jbHVkZSBFeHBvcnRlZF9zdGF0ZVxuXG4gIHR5cGUgbW9yZSA9IE1vcmUudCA9XG4gICAgfCBDb21wbGV0ZVxuICAgIHwgSW5jb21wbGV0ZVxuZW5kXG5cbmluY2x1ZGUgVW5idWZmZXJlZFxuaW5jbHVkZSBQYXJzZXIuTW9uYWRcbmluY2x1ZGUgUGFyc2VyLkNob2ljZVxuXG5tb2R1bGUgQnVmZmVyZWQgPSBzdHJ1Y3RcbiAgdHlwZSB1bmNvbnN1bWVkID0gQnVmZmVyaW5nLnVuY29uc3VtZWQgPVxuICAgIHsgYnVmIDogYmlnc3RyaW5nXG4gICAgOyBvZmYgOiBpbnRcbiAgICA7IGxlbiA6IGludCB9XG5cbiAgdHlwZSBpbnB1dCA9XG4gICAgWyBgQmlnc3RyaW5nIG9mIGJpZ3N0cmluZ1xuICAgIHwgYFN0cmluZyAgICBvZiBzdHJpbmcgXVxuXG4gIHR5cGUgJ2Egc3RhdGUgPVxuICAgIHwgUGFydGlhbCBvZiAoWyBpbnB1dCB8IGBFb2YgXSAtPiAnYSBzdGF0ZSlcbiAgICB8IERvbmUgICAgb2YgdW5jb25zdW1lZCAqICdhXG4gICAgfCBGYWlsICAgIG9mIHVuY29uc3VtZWQgKiBzdHJpbmcgbGlzdCAqIHN0cmluZ1xuXG4gIGxldCBmcm9tX3VuYnVmZmVyZWRfc3RhdGUgfmYgYnVmZmVyaW5nID0gZnVuY3Rpb25cbiAgICB8IFVuYnVmZmVyZWQuUGFydGlhbCBwICAgICAgICAgLT4gUGFydGlhbCAoZiBwKVxuICAgIHwgVW5idWZmZXJlZC5Eb25lKGNvbnN1bWVkLCB2KSAtPlxuICAgICAgbGV0IHVuY29uc3VtZWQgPSBCdWZmZXJpbmcudW5jb25zdW1lZCB+c2hpZnQ6Y29uc3VtZWQgYnVmZmVyaW5nIGluXG4gICAgICBEb25lKHVuY29uc3VtZWQsIHYpXG4gICAgfCBVbmJ1ZmZlcmVkLkZhaWwoY29uc3VtZWQsIG1hcmtzLCBtc2cpIC0+XG4gICAgICBsZXQgdW5jb25zdW1lZCA9IEJ1ZmZlcmluZy51bmNvbnN1bWVkIH5zaGlmdDpjb25zdW1lZCBidWZmZXJpbmcgaW5cbiAgICAgIEZhaWwodW5jb25zdW1lZCwgbWFya3MsIG1zZylcblxuICBsZXQgcGFyc2UgPyhpbml0aWFsX2J1ZmZlcl9zaXplPTB4MTAwMCkgcCA9XG4gICAgaWYgaW5pdGlhbF9idWZmZXJfc2l6ZSA8IDEgdGhlblxuICAgICAgZmFpbHdpdGggXCJwYXJzZTogaW52YWxpZCBhcmd1bWVudCwgaW5pdGlhbF9idWZmZXJfc2l6ZSA8IDFcIjtcbiAgICBsZXQgYnVmZmVyaW5nID0gQnVmZmVyaW5nLmNyZWF0ZSBpbml0aWFsX2J1ZmZlcl9zaXplIGluXG4gICAgbGV0IHJlYyBmIHAgaW5wdXQgPVxuICAgICAgQnVmZmVyaW5nLnNoaWZ0IGJ1ZmZlcmluZyBwLmNvbW1pdHRlZDtcbiAgICAgIGxldCBtb3JlIDogTW9yZS50ID1cbiAgICAgICAgbWF0Y2ggaW5wdXQgd2l0aFxuICAgICAgICB8IGBFb2YgICAgICAgICAgICAtPiBDb21wbGV0ZVxuICAgICAgICB8ICNpbnB1dCBhcyBpbnB1dCAtPlxuICAgICAgICAgIEJ1ZmZlcmluZy5mZWVkX2lucHV0IGJ1ZmZlcmluZyBpbnB1dDtcbiAgICAgICAgICBJbmNvbXBsZXRlXG4gICAgICBpblxuICAgICAgbGV0IGZvcl9yZWFkaW5nID0gQnVmZmVyaW5nLmZvcl9yZWFkaW5nIGJ1ZmZlcmluZyBpblxuICAgICAgcC5jb250aW51ZSBmb3JfcmVhZGluZyB+b2ZmOjAgfmxlbjooQmlnc3RyaW5nYWYubGVuZ3RoIGZvcl9yZWFkaW5nKSBtb3JlXG4gICAgICB8PiBmcm9tX3VuYnVmZmVyZWRfc3RhdGUgYnVmZmVyaW5nIH5mXG4gICAgaW5cbiAgICBVbmJ1ZmZlcmVkLnBhcnNlIHBcbiAgICB8PiBmcm9tX3VuYnVmZmVyZWRfc3RhdGUgYnVmZmVyaW5nIH5mXG5cbiAgbGV0IGZlZWQgc3RhdGUgaW5wdXQgPVxuICAgIG1hdGNoIHN0YXRlIHdpdGhcbiAgICB8IFBhcnRpYWwgayAtPiBrIGlucHV0XG4gICAgfCBGYWlsKHVuY29uc3VtZWQsIG1hcmtzLCBtc2cpIC0+XG4gICAgICBiZWdpbiBtYXRjaCBpbnB1dCB3aXRoXG4gICAgICB8IGBFb2YgICAtPiBzdGF0ZVxuICAgICAgfCAjaW5wdXQgYXMgaW5wdXQgLT5cbiAgICAgICAgbGV0IGJ1ZmZlcmluZyA9IEJ1ZmZlcmluZy5vZl91bmNvbnN1bWVkIHVuY29uc3VtZWQgaW5cbiAgICAgICAgQnVmZmVyaW5nLmZlZWRfaW5wdXQgYnVmZmVyaW5nIGlucHV0O1xuICAgICAgICBGYWlsKEJ1ZmZlcmluZy51bmNvbnN1bWVkIGJ1ZmZlcmluZywgbWFya3MsIG1zZylcbiAgICAgIGVuZFxuICAgIHwgRG9uZSh1bmNvbnN1bWVkLCB2KSAtPlxuICAgICAgYmVnaW4gbWF0Y2ggaW5wdXQgd2l0aFxuICAgICAgfCBgRW9mICAgLT4gc3RhdGVcbiAgICAgIHwgI2lucHV0IGFzIGlucHV0IC0+XG4gICAgICAgIGxldCBidWZmZXJpbmcgPSBCdWZmZXJpbmcub2ZfdW5jb25zdW1lZCB1bmNvbnN1bWVkIGluXG4gICAgICAgIEJ1ZmZlcmluZy5mZWVkX2lucHV0IGJ1ZmZlcmluZyBpbnB1dDtcbiAgICAgICAgRG9uZShCdWZmZXJpbmcudW5jb25zdW1lZCBidWZmZXJpbmcsIHYpXG4gICAgICBlbmRcblxuICBsZXQgc3RhdGVfdG9fb3B0aW9uID0gZnVuY3Rpb25cbiAgICB8IERvbmUoXywgdikgLT4gU29tZSB2XG4gICAgfCBQYXJ0aWFsIF8gIC0+IE5vbmVcbiAgICB8IEZhaWwgXyAgICAgLT4gTm9uZVxuXG4gIGxldCBzdGF0ZV90b19yZXN1bHQgPSBmdW5jdGlvblxuICAgIHwgUGFydGlhbCBfICAgICAgICAgICAtPiBFcnJvciBcImluY29tcGxldGUgaW5wdXRcIlxuICAgIHwgRG9uZShfLCB2KSAgICAgICAgICAtPiBPayB2XG4gICAgfCBGYWlsKF8sIG1hcmtzLCBtc2cpIC0+IEVycm9yIChVbmJ1ZmZlcmVkLmZhaWxfdG9fc3RyaW5nIG1hcmtzIG1zZylcblxuICBsZXQgc3RhdGVfdG9fdW5jb25zdW1lZCA9IGZ1bmN0aW9uXG4gICAgfCBEb25lKHVuY29uc3VtZWQsIF8pXG4gICAgfCBGYWlsKHVuY29uc3VtZWQsIF8sIF8pIC0+IFNvbWUgdW5jb25zdW1lZFxuICAgIHwgUGFydGlhbCBfICAgICAgICAgICAgICAtPiBOb25lXG5cbmVuZFxuXG4oKiogQkVHSU46IGdldHRpbmcgaW5wdXQgKilcblxubGV0IHJlYyBwcm9tcHQgaW5wdXQgcG9zIGZhaWwgc3VjYyA9XG4gICgqIFtwcm9tcHRdIHNob3VsZCBvbmx5IGNhbGwgW3N1Y2NdIGlmIGl0IGhhcyByZWNlaXZlZCBtb3JlIGlucHV0LiBJZiB0aGVyZVxuICAgKiBpcyBubyBjaGFuY2UgdGhhdCB0aGUgaW5wdXQgd2lsbCBncm93LCBpLmUuLCBbbW9yZSA9IENvbXBsZXRlXSwgdGhlblxuICAgKiBbcHJvbXB0XSBzaG91bGQgY2FsbCBbZmFpbF0uIE90aGVyd2lzZSAoaW4gdGhlIGNhc2Ugd2hlcmUgdGhlIGlucHV0XG4gICAqIGhhc24ndCBncm93biBidXQgW21vcmUgPSBJbmNvbXBsZXRlXSBqdXN0IHByb21wdCBhZ2Fpbi4gKilcbiAgbGV0IHBhcnNlcl91bmNvbW1pdHRlZF9ieXRlcyA9IElucHV0LnBhcnNlcl91bmNvbW1pdHRlZF9ieXRlcyBpbnB1dCBpblxuICBsZXQgcGFyc2VyX2NvbW1pdHRlZF9ieXRlcyAgID0gSW5wdXQucGFyc2VyX2NvbW1pdHRlZF9ieXRlcyAgIGlucHV0IGluXG4gICgqIFRoZSBjb250aW51YXRpb24gc2hvdWxkIG5vdCBob2xkIGFueSByZWZlcmVuY2VzIHRvIGlucHV0IGFib3ZlLiAqKVxuICBsZXQgY29udGludWUgaW5wdXQgfm9mZiB+bGVuIG1vcmUgPVxuICAgIGlmIGxlbiA8IHBhcnNlcl91bmNvbW1pdHRlZF9ieXRlcyB0aGVuXG4gICAgICBmYWlsd2l0aCBcInByb21wdDogaW5wdXQgc2hydW5rIVwiO1xuICAgIGxldCBpbnB1dCA9IElucHV0LmNyZWF0ZSBpbnB1dCB+b2ZmIH5sZW4gfmNvbW1pdHRlZF9ieXRlczpwYXJzZXJfY29tbWl0dGVkX2J5dGVzIGluXG4gICAgaWYgbGVuID0gcGFyc2VyX3VuY29tbWl0dGVkX2J5dGVzIHRoZW5cbiAgICAgIG1hdGNoIChtb3JlIDogTW9yZS50KSB3aXRoXG4gICAgICB8IENvbXBsZXRlICAgLT4gZmFpbCBpbnB1dCBwb3MgTW9yZS5Db21wbGV0ZVxuICAgICAgfCBJbmNvbXBsZXRlIC0+IHByb21wdCBpbnB1dCBwb3MgZmFpbCBzdWNjXG4gICAgZWxzZVxuICAgICAgc3VjYyBpbnB1dCBwb3MgbW9yZVxuICBpblxuICBTdGF0ZS5QYXJ0aWFsIHsgY29tbWl0dGVkID0gSW5wdXQuYnl0ZXNfZm9yX2NsaWVudF90b19jb21taXQgaW5wdXQ7IGNvbnRpbnVlIH1cblxubGV0IGRlbWFuZF9pbnB1dCA9XG4gIHsgcnVuID0gZnVuIGlucHV0IHBvcyBtb3JlIGZhaWwgc3VjYyAtPlxuICAgIG1hdGNoIChtb3JlIDogTW9yZS50KSB3aXRoXG4gICAgfCBDb21wbGV0ZSAgIC0+IGZhaWwgaW5wdXQgcG9zIG1vcmUgW10gXCJub3QgZW5vdWdoIGlucHV0XCJcbiAgICB8IEluY29tcGxldGUgLT5cbiAgICAgIGxldCBzdWNjJyBpbnB1dCcgcG9zJyBtb3JlJyA9IHN1Y2MgaW5wdXQnIHBvcycgbW9yZScgKClcbiAgICAgIGFuZCBmYWlsJyBpbnB1dCcgcG9zJyBtb3JlJyA9IGZhaWwgaW5wdXQnIHBvcycgbW9yZScgW10gXCJub3QgZW5vdWdoIGlucHV0XCIgaW5cbiAgICAgIHByb21wdCBpbnB1dCBwb3MgZmFpbCcgc3VjYydcbiAgfVxuXG5sZXQgZW5zdXJlX3N1c3BlbmRlZCBuIGlucHV0IHBvcyBtb3JlIGZhaWwgc3VjYyA9XG4gIGxldCByZWMgZ28gPVxuICAgIHsgcnVuID0gZnVuIGlucHV0JyBwb3MnIG1vcmUnIGZhaWwnIHN1Y2MnIC0+XG4gICAgICBpZiBwb3MnICsgbiA8PSBJbnB1dC5sZW5ndGggaW5wdXQnIHRoZW5cbiAgICAgICAgc3VjYycgaW5wdXQnIHBvcycgbW9yZScgKClcbiAgICAgIGVsc2VcbiAgICAgICAgKGRlbWFuZF9pbnB1dCAqPiBnbykucnVuIGlucHV0JyBwb3MnIG1vcmUnIGZhaWwnIHN1Y2MnXG4gICAgfVxuICBpblxuICAoZGVtYW5kX2lucHV0ICo+IGdvKS5ydW4gaW5wdXQgcG9zIG1vcmUgZmFpbCBzdWNjXG5cbmxldCB1bnNhZmVfYXBwbHkgbGVuIH5mID1cbiAgeyBydW4gPSBmdW4gaW5wdXQgcG9zIG1vcmUgX2ZhaWwgc3VjYyAtPlxuICAgIHN1Y2MgaW5wdXQgKHBvcyArIGxlbikgbW9yZSAoSW5wdXQuYXBwbHkgaW5wdXQgcG9zIGxlbiB+ZilcbiAgfVxuXG5sZXQgdW5zYWZlX2FwcGx5X29wdCBsZW4gfmYgPVxuICB7IHJ1biA9IGZ1biBpbnB1dCBwb3MgbW9yZSBmYWlsIHN1Y2MgLT5cbiAgICBtYXRjaCBJbnB1dC5hcHBseSBpbnB1dCBwb3MgbGVuIH5mIHdpdGhcbiAgICB8IEVycm9yIGUgLT4gZmFpbCBpbnB1dCBwb3MgbW9yZSBbXSBlXG4gICAgfCBPayAgICB4IC0+IHN1Y2MgaW5wdXQgKHBvcyArIGxlbikgbW9yZSB4XG4gIH1cblxubGV0IGVuc3VyZSBuIHAgPVxuICB7IHJ1biA9IGZ1biBpbnB1dCBwb3MgbW9yZSBmYWlsIHN1Y2MgLT5cbiAgICBpZiBwb3MgKyBuIDw9IElucHV0Lmxlbmd0aCBpbnB1dFxuICAgIHRoZW4gcC5ydW4gaW5wdXQgcG9zIG1vcmUgZmFpbCBzdWNjXG4gICAgZWxzZVxuICAgICAgbGV0IHN1Y2MnIGlucHV0JyBwb3MnIG1vcmUnICgpID0gcC5ydW4gaW5wdXQnIHBvcycgbW9yZScgZmFpbCBzdWNjIGluXG4gICAgICBlbnN1cmVfc3VzcGVuZGVkIG4gaW5wdXQgcG9zIG1vcmUgZmFpbCBzdWNjJyB9XG5cbigqKiBFTkQ6IGdldHRpbmcgaW5wdXQgKilcblxubGV0IGF0X2VuZF9vZl9pbnB1dCA9XG4gIHsgcnVuID0gZnVuIGlucHV0IHBvcyBtb3JlIF8gc3VjYyAtPlxuICAgIGlmIHBvcyA8IElucHV0Lmxlbmd0aCBpbnB1dCB0aGVuXG4gICAgICBzdWNjIGlucHV0IHBvcyBtb3JlIGZhbHNlXG4gICAgZWxzZSBtYXRjaCBtb3JlIHdpdGhcbiAgICB8IENvbXBsZXRlIC0+IHN1Y2MgaW5wdXQgcG9zIG1vcmUgdHJ1ZVxuICAgIHwgSW5jb21wbGV0ZSAtPlxuICAgICAgbGV0IHN1Y2MnIGlucHV0JyBwb3MnIG1vcmUnID0gc3VjYyBpbnB1dCcgcG9zJyBtb3JlJyBmYWxzZVxuICAgICAgYW5kIGZhaWwnIGlucHV0JyBwb3MnIG1vcmUnID0gc3VjYyBpbnB1dCcgcG9zJyBtb3JlJyB0cnVlIGluXG4gICAgICBwcm9tcHQgaW5wdXQgcG9zIGZhaWwnIHN1Y2MnXG4gIH1cblxubGV0IGVuZF9vZl9pbnB1dCA9XG4gIGF0X2VuZF9vZl9pbnB1dFxuICA+Pj0gZnVuY3Rpb25cbiAgICB8IHRydWUgIC0+IHJldHVybiAoKVxuICAgIHwgZmFsc2UgLT4gZmFpbCBcImVuZF9vZl9pbnB1dFwiXG5cbmxldCBhZHZhbmNlIG4gPVxuICBpZiBuIDwgMFxuICB0aGVuIGZhaWwgXCJhZHZhbmNlXCJcbiAgZWxzZVxuICAgIGxldCBwID1cbiAgICAgIHsgcnVuID0gZnVuIGlucHV0IHBvcyBtb3JlIF9mYWlsIHN1Y2MgLT4gc3VjYyBpbnB1dCAocG9zICsgbikgbW9yZSAoKSB9XG4gICAgaW5cbiAgICBlbnN1cmUgbiBwXG5cbmxldCBwb3MgPVxuICB7IHJ1biA9IGZ1biBpbnB1dCBwb3MgbW9yZSBfZmFpbCBzdWNjIC0+IHN1Y2MgaW5wdXQgcG9zIG1vcmUgcG9zIH1cblxubGV0IGF2YWlsYWJsZSA9XG4gIHsgcnVuID0gZnVuIGlucHV0IHBvcyBtb3JlIF9mYWlsIHN1Y2MgLT5cbiAgICBzdWNjIGlucHV0IHBvcyBtb3JlIChJbnB1dC5sZW5ndGggaW5wdXQgLSBwb3MpXG4gIH1cblxubGV0IGNvbW1pdCA9XG4gIHsgcnVuID0gZnVuIGlucHV0IHBvcyBtb3JlIF9mYWlsIHN1Y2MgLT5cbiAgICBJbnB1dC5jb21taXQgaW5wdXQgcG9zO1xuICAgIHN1Y2MgaW5wdXQgcG9zIG1vcmUgKCkgfVxuXG4oKiBEbyBub3QgdXNlIHRoaXMgaWYgW3BdIGNvbnRhaW5zIGEgW2NvbW1pdF0uICopXG5sZXQgdW5zYWZlX2xvb2thaGVhZCBwID1cbiAgeyBydW4gPSBmdW4gaW5wdXQgcG9zIG1vcmUgZmFpbCBzdWNjIC0+XG4gICAgbGV0IHN1Y2MnIGlucHV0JyBfIG1vcmUnIHYgPSBzdWNjIGlucHV0JyBwb3MgbW9yZScgdiBpblxuICAgIHAucnVuIGlucHV0IHBvcyBtb3JlIGZhaWwgc3VjYycgfVxuXG5sZXQgcGVla19jaGFyID1cbiAgeyBydW4gPSBmdW4gaW5wdXQgcG9zIG1vcmUgX2ZhaWwgc3VjYyAtPlxuICAgIGlmIHBvcyA8IElucHV0Lmxlbmd0aCBpbnB1dCB0aGVuXG4gICAgICBzdWNjIGlucHV0IHBvcyBtb3JlIChTb21lIChJbnB1dC51bnNhZmVfZ2V0X2NoYXIgaW5wdXQgcG9zKSlcbiAgICBlbHNlIGlmIG1vcmUgPSBDb21wbGV0ZSB0aGVuXG4gICAgICBzdWNjIGlucHV0IHBvcyBtb3JlIE5vbmVcbiAgICBlbHNlXG4gICAgICBsZXQgc3VjYycgaW5wdXQnIHBvcycgbW9yZScgPVxuICAgICAgICBzdWNjIGlucHV0JyBwb3MnIG1vcmUnIChTb21lIChJbnB1dC51bnNhZmVfZ2V0X2NoYXIgaW5wdXQnIHBvcycpKVxuICAgICAgYW5kIGZhaWwnIGlucHV0JyBwb3MnIG1vcmUnID1cbiAgICAgICAgc3VjYyBpbnB1dCcgcG9zJyBtb3JlJyBOb25lIGluXG4gICAgICBwcm9tcHQgaW5wdXQgcG9zIGZhaWwnIHN1Y2MnXG4gIH1cblxuKCogVGhpcyBwYXJzZXIgaXMgdG9vIGltcG9ydGFudCB0byBub3QgYmUgb3B0aW1pemVkLiBEbyBhIGN1c3RvbSBqb2IuICopXG5sZXQgcmVjIHBlZWtfY2hhcl9mYWlsID1cbiAgeyBydW4gPSBmdW4gaW5wdXQgcG9zIG1vcmUgZmFpbCBzdWNjIC0+XG4gICAgaWYgcG9zIDwgSW5wdXQubGVuZ3RoIGlucHV0XG4gICAgdGhlbiBzdWNjIGlucHV0IHBvcyBtb3JlIChJbnB1dC51bnNhZmVfZ2V0X2NoYXIgaW5wdXQgcG9zKVxuICAgIGVsc2VcbiAgICAgIGxldCBzdWNjJyBpbnB1dCcgcG9zJyBtb3JlJyAoKSA9XG4gICAgICAgIHBlZWtfY2hhcl9mYWlsLnJ1biBpbnB1dCcgcG9zJyBtb3JlJyBmYWlsIHN1Y2MgaW5cbiAgICAgIGVuc3VyZV9zdXNwZW5kZWQgMSBpbnB1dCBwb3MgbW9yZSBmYWlsIHN1Y2MnIH1cblxubGV0IHNhdGlzZnkgZiA9XG4gIHsgcnVuID0gZnVuIGlucHV0IHBvcyBtb3JlIGZhaWwgc3VjYyAtPlxuICAgIGlmIHBvcyA8IElucHV0Lmxlbmd0aCBpbnB1dCB0aGVuXG4gICAgICBsZXQgYyA9IElucHV0LnVuc2FmZV9nZXRfY2hhciBpbnB1dCBwb3MgaW5cbiAgICAgIGlmIGYgY1xuICAgICAgdGhlbiBzdWNjIGlucHV0IChwb3MgKyAxKSBtb3JlIGNcbiAgICAgIGVsc2UgUHJpbnRmLmtzcHJpbnRmIChmYWlsIGlucHV0IHBvcyBtb3JlIFtdKSBcInNhdGlzZnk6ICVDXCIgY1xuICAgIGVsc2VcbiAgICAgIGxldCBzdWNjJyBpbnB1dCcgcG9zJyBtb3JlJyAoKSA9XG4gICAgICAgIGxldCBjID0gSW5wdXQudW5zYWZlX2dldF9jaGFyIGlucHV0JyBwb3MnIGluXG4gICAgICAgIGlmIGYgY1xuICAgICAgICB0aGVuIHN1Y2MgaW5wdXQnIChwb3MnICsgMSkgbW9yZScgY1xuICAgICAgICBlbHNlIFByaW50Zi5rc3ByaW50ZiAoZmFpbCBpbnB1dCcgcG9zJyBtb3JlJyBbXSkgXCJzYXRpc2Z5OiAlQ1wiIGNcbiAgICAgIGluXG4gICAgICBlbnN1cmVfc3VzcGVuZGVkIDEgaW5wdXQgcG9zIG1vcmUgZmFpbCBzdWNjJyB9XG5cbmxldCBjaGFyIGMgPVxuICBsZXQgcCA9XG4gICAgeyBydW4gPSBmdW4gaW5wdXQgcG9zIG1vcmUgZmFpbCBzdWNjIC0+XG4gICAgICBpZiBJbnB1dC51bnNhZmVfZ2V0X2NoYXIgaW5wdXQgcG9zID0gY1xuICAgICAgdGhlbiBzdWNjIGlucHV0IChwb3MgKyAxKSBtb3JlIGNcbiAgICAgIGVsc2UgZmFpbCBpbnB1dCBwb3MgbW9yZSBbXSAoUHJpbnRmLnNwcmludGYgXCJjaGFyICVDXCIgYykgfVxuICBpblxuICBlbnN1cmUgMSBwXG5cbmxldCBub3RfY2hhciBjID1cbiAgbGV0IHAgPVxuICAgIHsgcnVuID0gZnVuIGlucHV0IHBvcyBtb3JlIGZhaWwgc3VjYyAtPlxuICAgICAgbGV0IGMnID0gSW5wdXQudW5zYWZlX2dldF9jaGFyIGlucHV0IHBvcyBpblxuICAgICAgaWYgYyA8PiBjJ1xuICAgICAgdGhlbiBzdWNjIGlucHV0IChwb3MgKyAxKSBtb3JlIGMnXG4gICAgICBlbHNlIGZhaWwgaW5wdXQgcG9zIG1vcmUgW10gKFByaW50Zi5zcHJpbnRmIFwibm90IGNoYXIgJUNcIiBjKSB9XG4gIGluXG4gIGVuc3VyZSAxIHBcblxubGV0IGFueV9jaGFyID1cbiAgbGV0IHAgPVxuICAgIHsgcnVuID0gZnVuIGlucHV0IHBvcyBtb3JlIF9mYWlsIHN1Y2MgLT5cbiAgICAgIHN1Y2MgaW5wdXQgKHBvcyArIDEpIG1vcmUgKElucHV0LnVuc2FmZV9nZXRfY2hhciBpbnB1dCBwb3MpICB9XG4gIGluXG4gIGVuc3VyZSAxIHBcblxubGV0IGludDggaSA9XG4gIGxldCBwID1cbiAgICB7IHJ1biA9IGZ1biBpbnB1dCBwb3MgbW9yZSBmYWlsIHN1Y2MgLT5cbiAgICAgIGxldCBjID0gQ2hhci5jb2RlIChJbnB1dC51bnNhZmVfZ2V0X2NoYXIgaW5wdXQgcG9zKSBpblxuICAgICAgaWYgYyA9IGkgbGFuZCAweGZmXG4gICAgICB0aGVuIHN1Y2MgaW5wdXQgKHBvcyArIDEpIG1vcmUgY1xuICAgICAgZWxzZSBmYWlsIGlucHV0IHBvcyBtb3JlIFtdIChQcmludGYuc3ByaW50ZiBcImludDggJWRcIiBpKSB9XG4gIGluXG4gIGVuc3VyZSAxIHBcblxubGV0IGFueV91aW50OCA9XG4gIGxldCBwID1cbiAgICB7IHJ1biA9IGZ1biBpbnB1dCBwb3MgbW9yZSBfZmFpbCBzdWNjIC0+XG4gICAgICBsZXQgYyA9IElucHV0LnVuc2FmZV9nZXRfY2hhciBpbnB1dCBwb3MgaW5cbiAgICAgIHN1Y2MgaW5wdXQgKHBvcyArIDEpIG1vcmUgKENoYXIuY29kZSBjKSB9XG4gIGluXG4gIGVuc3VyZSAxIHBcblxubGV0IGFueV9pbnQ4ID1cbiAgKCogaHR0cHM6Ly9ncmFwaGljcy5zdGFuZm9yZC5lZHUvfnNlYW5kZXIvYml0aGFja3MuaHRtbCNWYXJpYWJsZVNpZ25FeHRlbmRSaXNreSAqKVxuICBsZXQgcyA9IFN5cy5pbnRfc2l6ZSAtIDggaW5cbiAgbGV0IHAgPVxuICAgIHsgcnVuID0gZnVuIGlucHV0IHBvcyBtb3JlIF9mYWlsIHN1Y2MgLT5cbiAgICAgIGxldCBjID0gSW5wdXQudW5zYWZlX2dldF9jaGFyIGlucHV0IHBvcyBpblxuICAgICAgc3VjYyBpbnB1dCAocG9zICsgMSkgbW9yZSAoKENoYXIuY29kZSBjIGxzbCBzKSBhc3IgcykgfVxuICBpblxuICBlbnN1cmUgMSBwXG5cbmxldCBza2lwIGYgPVxuICBsZXQgcCA9XG4gICAgeyBydW4gPSBmdW4gaW5wdXQgcG9zIG1vcmUgZmFpbCBzdWNjIC0+XG4gICAgICBpZiBmIChJbnB1dC51bnNhZmVfZ2V0X2NoYXIgaW5wdXQgcG9zKVxuICAgICAgdGhlbiBzdWNjIGlucHV0IChwb3MgKyAxKSBtb3JlICgpXG4gICAgICBlbHNlIGZhaWwgaW5wdXQgcG9zIG1vcmUgW10gXCJza2lwXCIgfVxuICBpblxuICBlbnN1cmUgMSBwXG5cbmxldCByZWMgY291bnRfd2hpbGUgfmluaXQgfmYgfndpdGhfYnVmZmVyID1cbiAgeyBydW4gPSBmdW4gaW5wdXQgcG9zIG1vcmUgZmFpbCBzdWNjIC0+XG4gICAgbGV0IGxlbiAgICAgICAgID0gSW5wdXQuY291bnRfd2hpbGUgaW5wdXQgKHBvcyArIGluaXQpIH5mIGluXG4gICAgbGV0IGlucHV0X2xlbiAgID0gSW5wdXQubGVuZ3RoIGlucHV0IGluXG4gICAgbGV0IGluaXQnICAgICAgID0gaW5pdCArIGxlbiBpblxuICAgICgqIENoZWNrIGlmIHRoZSBsb29wIHRlcm1pbmF0ZWQgYmVjYXVzZSBpdCByZWFjaGVkIHRoZSBlbmQgb2YgdGhlIGlucHV0XG4gICAgICogYnVmZmVyLiBJZiBzbywgdGhlbiBwcm9tcHQgZm9yIGFkZGl0aW9uYWwgaW5wdXQgYW5kIGNvbnRpbnVlLiAqKVxuICAgIGlmIHBvcyArIGluaXQnIDwgaW5wdXRfbGVuIHx8IG1vcmUgPSBDb21wbGV0ZVxuICAgIHRoZW4gc3VjYyBpbnB1dCAocG9zICsgaW5pdCcpIG1vcmUgKElucHV0LmFwcGx5IGlucHV0IHBvcyBpbml0JyB+Zjp3aXRoX2J1ZmZlcilcbiAgICBlbHNlXG4gICAgICBsZXQgc3VjYycgaW5wdXQnIHBvcycgbW9yZScgPVxuICAgICAgICAoY291bnRfd2hpbGUgfmluaXQ6aW5pdCcgfmYgfndpdGhfYnVmZmVyKS5ydW4gaW5wdXQnIHBvcycgbW9yZScgZmFpbCBzdWNjXG4gICAgICBhbmQgZmFpbCcgaW5wdXQnIHBvcycgbW9yZScgPVxuICAgICAgICBzdWNjIGlucHV0JyAocG9zJyArIGluaXQnKSBtb3JlJyAoSW5wdXQuYXBwbHkgaW5wdXQnIHBvcycgaW5pdCcgfmY6d2l0aF9idWZmZXIpXG4gICAgICBpblxuICAgICAgcHJvbXB0IGlucHV0IHBvcyBmYWlsJyBzdWNjJ1xuICB9XG5cbmxldCByZWMgY291bnRfd2hpbGUxIH5mIH53aXRoX2J1ZmZlciA9XG4gIHsgcnVuID0gZnVuIGlucHV0IHBvcyBtb3JlIGZhaWwgc3VjYyAtPlxuICAgIGxldCBsZW4gICAgICAgICA9IElucHV0LmNvdW50X3doaWxlIGlucHV0IHBvcyB+ZiBpblxuICAgIGxldCBpbnB1dF9sZW4gICA9IElucHV0Lmxlbmd0aCBpbnB1dCBpblxuICAgICgqIENoZWNrIGlmIHRoZSBsb29wIHRlcm1pbmF0ZWQgYmVjYXVzZSBpdCByZWFjaGVkIHRoZSBlbmQgb2YgdGhlIGlucHV0XG4gICAgICogYnVmZmVyLiBJZiBzbywgdGhlbiBwcm9tcHQgZm9yIGFkZGl0aW9uYWwgaW5wdXQgYW5kIGNvbnRpbnVlLiAqKVxuICAgIGlmIGxlbiA8IDFcbiAgICB0aGVuXG4gICAgICBpZiBwb3MgPCBpbnB1dF9sZW4gfHwgbW9yZSA9IENvbXBsZXRlXG4gICAgICB0aGVuIGZhaWwgaW5wdXQgcG9zIG1vcmUgW10gXCJjb3VudF93aGlsZTFcIlxuICAgICAgZWxzZVxuICAgICAgICBsZXQgc3VjYycgaW5wdXQnIHBvcycgbW9yZScgPVxuICAgICAgICAgIChjb3VudF93aGlsZTEgfmYgfndpdGhfYnVmZmVyKS5ydW4gaW5wdXQnIHBvcycgbW9yZScgZmFpbCBzdWNjXG4gICAgICAgIGFuZCBmYWlsJyBpbnB1dCcgcG9zJyBtb3JlJyA9XG4gICAgICAgICAgZmFpbCBpbnB1dCcgcG9zJyBtb3JlJyBbXSBcImNvdW50X3doaWxlMVwiXG4gICAgICAgIGluXG4gICAgICAgIHByb21wdCBpbnB1dCBwb3MgZmFpbCcgc3VjYydcbiAgICBlbHNlIGlmIHBvcyArIGxlbiA8IGlucHV0X2xlbiB8fCBtb3JlID0gQ29tcGxldGVcbiAgICB0aGVuIHN1Y2MgaW5wdXQgKHBvcyArIGxlbikgbW9yZSAoSW5wdXQuYXBwbHkgaW5wdXQgcG9zIGxlbiB+Zjp3aXRoX2J1ZmZlcilcbiAgICBlbHNlXG4gICAgICBsZXQgc3VjYycgaW5wdXQnIHBvcycgbW9yZScgPVxuICAgICAgICAoY291bnRfd2hpbGUgfmluaXQ6bGVuIH5mIH53aXRoX2J1ZmZlcikucnVuIGlucHV0JyBwb3MnIG1vcmUnIGZhaWwgc3VjY1xuICAgICAgYW5kIGZhaWwnIGlucHV0JyBwb3MnIG1vcmUnID1cbiAgICAgICAgc3VjYyBpbnB1dCcgKHBvcycgKyBsZW4pIG1vcmUnIChJbnB1dC5hcHBseSBpbnB1dCcgcG9zJyBsZW4gfmY6d2l0aF9idWZmZXIpXG4gICAgICBpblxuICAgICAgcHJvbXB0IGlucHV0IHBvcyBmYWlsJyBzdWNjJ1xuICB9XG5cbmxldCBzdHJpbmdfIGYgcyA9XG4gICgqIFhYWChzZWxpb3BvdSk6IEluZWZmaWNpZW50LiBDb3VsZCBjaGVjayBwcmVmaXggZXF1YWxpdHkgdG8gc2hvcnQtY2lyY3VpdFxuICAgKiB0aGUgaW8uICopXG4gIGxldCBsZW4gPSBTdHJpbmcubGVuZ3RoIHMgaW5cbiAgZW5zdXJlICBsZW4gKHVuc2FmZV9hcHBseV9vcHQgbGVuIH5mOihmdW4gYnVmZmVyIH5vZmYgfmxlbiAtPlxuICAgIGxldCBpID0gcmVmIDAgaW5cbiAgICB3aGlsZSAhaSA8IGxlbiAmJiBDaGFyLmVxdWFsIChmIChCaWdzdHJpbmdhZi51bnNhZmVfZ2V0IGJ1ZmZlciAob2ZmICsgIWkpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmIChTdHJpbmcudW5zYWZlX2dldCBzICFpKSlcbiAgICBkb1xuICAgICAgaW5jciBpXG4gICAgZG9uZTtcbiAgICBpZiBsZW4gPSAhaVxuICAgIHRoZW4gT2sgKEJpZ3N0cmluZ2FmLnN1YnN0cmluZyBidWZmZXIgfm9mZiB+bGVuKVxuICAgIGVsc2UgRXJyb3IgXCJzdHJpbmdcIikpXG5cbmxldCBzdHJpbmcgcyAgICA9IHN0cmluZ18gKGZ1biB4IC0+IHgpIHNcbmxldCBzdHJpbmdfY2kgcyA9IHN0cmluZ18gQ2hhci5sb3dlcmNhc2VfYXNjaWkgc1xuXG5sZXQgc2tpcF93aGlsZSBmID1cbiAgY291bnRfd2hpbGUgfmluaXQ6MCB+ZiB+d2l0aF9idWZmZXI6KGZ1biBfIH5vZmY6XyB+bGVuOl8gLT4gKCkpXG5cbmxldCB0YWtlIG4gPVxuICBpZiBuIDwgMFxuICB0aGVuIGZhaWwgXCJ0YWtlOiBuIDwgMFwiXG4gIGVsc2VcbiAgICBsZXQgbiA9IG1heCBuIDAgaW5cbiAgICBlbnN1cmUgbiAodW5zYWZlX2FwcGx5IG4gfmY6Qmlnc3RyaW5nYWYuc3Vic3RyaW5nKVxuXG5sZXQgdGFrZV9iaWdzdHJpbmcgbiA9XG4gIGlmIG4gPCAwXG4gIHRoZW4gZmFpbCBcInRha2VfYmlnc3RyaW5nOiBuIDwgMFwiXG4gIGVsc2VcbiAgICBsZXQgbiA9IG1heCBuIDAgaW5cbiAgICBlbnN1cmUgbiAodW5zYWZlX2FwcGx5IG4gfmY6Qmlnc3RyaW5nYWYuY29weSlcblxubGV0IHRha2VfYmlnc3RyaW5nX3doaWxlIGYgPVxuICBjb3VudF93aGlsZSB+aW5pdDowIH5mIH53aXRoX2J1ZmZlcjpCaWdzdHJpbmdhZi5jb3B5XG5cbmxldCB0YWtlX2JpZ3N0cmluZ193aGlsZTEgZiA9XG4gIGNvdW50X3doaWxlMSB+ZiB+d2l0aF9idWZmZXI6Qmlnc3RyaW5nYWYuY29weVxuXG5sZXQgdGFrZV9iaWdzdHJpbmdfdGlsbCBmID1cbiAgdGFrZV9iaWdzdHJpbmdfd2hpbGUgKGZ1biBjIC0+IG5vdCAoZiBjKSlcblxubGV0IHBlZWtfc3RyaW5nIG4gPVxuICB1bnNhZmVfbG9va2FoZWFkICh0YWtlIG4pXG5cbmxldCB0YWtlX3doaWxlIGYgPVxuICBjb3VudF93aGlsZSB+aW5pdDowIH5mIH53aXRoX2J1ZmZlcjpCaWdzdHJpbmdhZi5zdWJzdHJpbmdcblxubGV0IHRha2Vfd2hpbGUxIGYgPVxuICBjb3VudF93aGlsZTEgfmYgfndpdGhfYnVmZmVyOkJpZ3N0cmluZ2FmLnN1YnN0cmluZ1xuXG5sZXQgdGFrZV90aWxsIGYgPVxuICB0YWtlX3doaWxlIChmdW4gYyAtPiBub3QgKGYgYykpXG5cbmxldCBjaG9pY2UgPyhmYWlsdXJlX21zZz1cIm5vIG1vcmUgY2hvaWNlc1wiKSBwcyA9XG4gIExpc3QuZm9sZF9yaWdodCAoPHw+KSBwcyAoZmFpbCBmYWlsdXJlX21zZylcblxubGV0IGZpeF9kaXJlY3QgZiA9XG4gIGxldCByZWMgcCA9IGxhenkgKGYgcilcbiAgYW5kIHIgPSB7IHJ1biA9IGZ1biBidWYgcG9zIG1vcmUgZmFpbCBzdWNjIC0+XG4gICAgKExhenkuZm9yY2UgcCkucnVuIGJ1ZiBwb3MgbW9yZSBmYWlsIHN1Y2MgfVxuICBpblxuICByXG5cbmxldCBmaXhfbGF6eSB+bWF4X3N0ZXBzIGYgPVxuICBsZXQgc3RlcHMgPSByZWYgbWF4X3N0ZXBzIGluXG4gIGxldCByZWMgcCA9IGxhenkgKGYgcilcbiAgYW5kIHIgPSB7IHJ1biA9IGZ1biBidWYgcG9zIG1vcmUgZmFpbCBzdWNjIC0+XG4gICAgZGVjciBzdGVwcztcbiAgICBpZiAhc3RlcHMgPCAwXG4gICAgdGhlbiAoXG4gICAgICBzdGVwcyA6PSBtYXhfc3RlcHM7XG4gICAgICBTdGF0ZS5MYXp5IChsYXp5ICgoTGF6eS5mb3JjZSBwKS5ydW4gYnVmIHBvcyBtb3JlIGZhaWwgc3VjYykpKVxuICAgIGVsc2VcbiAgICAgIChMYXp5LmZvcmNlIHApLnJ1biBidWYgcG9zIG1vcmUgZmFpbCBzdWNjXG4gICAgICAgICAgfVxuICBpblxuICByXG5cbmxldCBmaXggPSBtYXRjaCBTeXMuYmFja2VuZF90eXBlIHdpdGhcbiAgfCBOYXRpdmUgLT4gZml4X2RpcmVjdFxuICB8IEJ5dGVjb2RlIC0+IGZpeF9kaXJlY3RcbiAgfCBPdGhlciBfIC0+IGZ1biBmIC0+IGZpeF9sYXp5IH5tYXhfc3RlcHM6MjAgZlxuXG5sZXQgb3B0aW9uIHggcCA9XG4gIHAgPHw+IHJldHVybiB4XG5cbmxldCBjb25zIHggeHMgPSB4IDo6IHhzXG5cbmxldCByZWMgbGlzdCBwcyA9XG4gIG1hdGNoIHBzIHdpdGhcbiAgfCBbXSAgICAtPiByZXR1cm4gW11cbiAgfCBwOjpwcyAtPiBsaWZ0MiBjb25zIHAgKGxpc3QgcHMpXG5cbmxldCBjb3VudCBuIHAgPVxuICBpZiBuIDwgMFxuICB0aGVuIGZhaWwgXCJjb3VudDogbiA8IDBcIlxuICBlbHNlXG4gICAgbGV0IHJlYyBsb29wID0gZnVuY3Rpb25cbiAgICAgIHwgMCAtPiByZXR1cm4gW11cbiAgICAgIHwgbiAtPiBsaWZ0MiBjb25zIHAgKGxvb3AgKG4gLSAxKSlcbiAgICBpblxuICAgIGxvb3AgblxuXG5sZXQgbWFueSBwID1cbiAgZml4IChmdW4gbSAtPlxuICAgIChsaWZ0MiBjb25zIHAgbSkgPHw+IHJldHVybiBbXSlcblxubGV0IG1hbnkxIHAgPVxuICBsaWZ0MiBjb25zIHAgKG1hbnkgcClcblxubGV0IG1hbnlfdGlsbCBwIHQgPVxuICBmaXggKGZ1biBtIC0+XG4gICAgKHQgKj4gcmV0dXJuIFtdKSA8fD4gKGxpZnQyIGNvbnMgcCBtKSlcblxubGV0IHNlcF9ieTEgcyBwID1cbiAgZml4IChmdW4gbSAtPlxuICAgIGxpZnQyIGNvbnMgcCAoKHMgKj4gbSkgPHw+IHJldHVybiBbXSkpXG5cbmxldCBzZXBfYnkgcyBwID1cbiAgKGxpZnQyIGNvbnMgcCAoKHMgKj4gc2VwX2J5MSBzIHApIDx8PiByZXR1cm4gW10pKSA8fD4gcmV0dXJuIFtdXG5cbmxldCBza2lwX21hbnkgcCA9XG4gIGZpeCAoZnVuIG0gLT5cbiAgICAgICgocCA+PnwgZnVuIF8gLT4gdHJ1ZSkgPHw+IHJldHVybiBmYWxzZSkgPj49IGZ1bmN0aW9uXG4gICAgICB8IHRydWUgLT4gbVxuICAgICAgfCBmYWxzZSAtPiByZXR1cm4gKClcbiAgICApXG5cbmxldCBza2lwX21hbnkxIHAgPVxuICBwICo+IHNraXBfbWFueSBwXG5cbmxldCBlbmRfb2ZfbGluZSA9XG4gIChjaGFyICdcXG4nICo+IHJldHVybiAoKSkgPHw+IChzdHJpbmcgXCJcXHJcXG5cIiAqPiByZXR1cm4gKCkpIDw/PiBcImVuZF9vZl9saW5lXCJcblxubGV0IHNjYW5fIHN0YXRlIGYgfndpdGhfYnVmZmVyID1cbiAgeyBydW4gPSBmdW4gaW5wdXQgcG9zIG1vcmUgZmFpbCBzdWNjIC0+XG4gICAgbGV0IHN0YXRlID0gcmVmIHN0YXRlIGluXG4gICAgbGV0IHBhcnNlciA9XG4gICAgICBjb3VudF93aGlsZSB+aW5pdDowIH5mOihmdW4gYyAtPlxuICAgICAgICBtYXRjaCBmICFzdGF0ZSBjIHdpdGhcbiAgICAgICAgfCBOb25lIC0+IGZhbHNlXG4gICAgICAgIHwgU29tZSBzdGF0ZScgLT4gc3RhdGUgOj0gc3RhdGUnOyB0cnVlKVxuICAgICAgfndpdGhfYnVmZmVyXG4gICAgICA+PnwgZnVuIHggLT4geCwgIXN0YXRlXG4gICAgaW5cbiAgICBwYXJzZXIucnVuIGlucHV0IHBvcyBtb3JlIGZhaWwgc3VjYyB9XG5cbmxldCBzY2FuIHN0YXRlIGYgPVxuICBzY2FuXyBzdGF0ZSBmIH53aXRoX2J1ZmZlcjpCaWdzdHJpbmdhZi5zdWJzdHJpbmdcblxubGV0IHNjYW5fc3RhdGUgc3RhdGUgZiA9XG4gIHNjYW5fIHN0YXRlIGYgfndpdGhfYnVmZmVyOihmdW4gXyB+b2ZmOl8gfmxlbjpfIC0+ICgpKVxuICA+PnwgZnVuICgoKSwgc3RhdGUpIC0+IHN0YXRlXG5cbmxldCBzY2FuX3N0cmluZyBzdGF0ZSBmID1cbiAgc2NhbiBzdGF0ZSBmID4+fCBmc3RcblxubGV0IGNvbnN1bWVfd2l0aCBwIGYgPVxuICB7IHJ1biA9IGZ1biBpbnB1dCBwb3MgbW9yZSBmYWlsIHN1Y2MgLT5cbiAgICBsZXQgc3RhcnQgPSBwb3MgaW5cbiAgICBsZXQgcGFyc2VyX2NvbW1pdHRlZF9ieXRlcyA9IElucHV0LnBhcnNlcl9jb21taXR0ZWRfYnl0ZXMgaW5wdXQgIGluXG4gICAgbGV0IHN1Y2MnIGlucHV0JyBwb3MnIG1vcmUnIF8gPVxuICAgICAgaWYgcGFyc2VyX2NvbW1pdHRlZF9ieXRlcyA8PiBJbnB1dC5wYXJzZXJfY29tbWl0dGVkX2J5dGVzIGlucHV0J1xuICAgICAgdGhlbiBmYWlsIGlucHV0JyBwb3MnIG1vcmUnIFtdIFwiY29uc3VtZWQ6IHBhcnNlciBjb21taXR0ZWRcIlxuICAgICAgZWxzZSAoXG4gICAgICAgIGxldCBsZW4gPSBwb3MnIC0gc3RhcnQgaW5cbiAgICAgICAgbGV0IGNvbnN1bWVkID0gSW5wdXQuYXBwbHkgaW5wdXQnIHN0YXJ0IGxlbiB+ZiBpblxuICAgICAgICBzdWNjIGlucHV0JyBwb3MnIG1vcmUnIGNvbnN1bWVkKVxuICAgIGluXG4gICAgcC5ydW4gaW5wdXQgcG9zIG1vcmUgZmFpbCBzdWNjJ1xuICB9XG5cbmxldCBjb25zdW1lZCAgICAgICAgICAgcCA9IGNvbnN1bWVfd2l0aCBwIEJpZ3N0cmluZ2FmLnN1YnN0cmluZ1xubGV0IGNvbnN1bWVkX2JpZ3N0cmluZyBwID0gY29uc3VtZV93aXRoIHAgQmlnc3RyaW5nYWYuY29weVxuXG5sZXQgYm90aCBhIGIgPSBsaWZ0MiAoZnVuIGEgYiAtPiBhLCBiKSBhIGJcbmxldCBtYXAgdCB+ZiA9IHQgPj58IGZcbmxldCBiaW5kIHQgfmYgPSB0ID4+PSBmXG5sZXQgbWFwMiBhIGIgfmYgPSBsaWZ0MiBmIGEgYlxubGV0IG1hcDMgYSBiIGMgfmYgPSBsaWZ0MyBmIGEgYiBjXG5sZXQgbWFwNCBhIGIgYyBkIH5mID0gbGlmdDQgZiBhIGIgYyBkXG5cbm1vZHVsZSBMZXRfc3ludGF4ID0gc3RydWN0XG4gIGxldCByZXR1cm4gPSByZXR1cm5cbiAgbGV0ICggPj58ICkgPSAoID4+fCApXG4gIGxldCAoID4+PSApID0gKCA+Pj0gKVxuXG4gIG1vZHVsZSBMZXRfc3ludGF4ID0gc3RydWN0XG4gICAgbGV0IHJldHVybiA9IHJldHVyblxuICAgIGxldCBtYXAgPSBtYXBcbiAgICBsZXQgYmluZCA9IGJpbmRcbiAgICBsZXQgYm90aCA9IGJvdGhcbiAgICBsZXQgbWFwMiA9IG1hcDJcbiAgICBsZXQgbWFwMyA9IG1hcDNcbiAgICBsZXQgbWFwNCA9IG1hcDRcbiAgZW5kXG5lbmRcblxubGV0ICggbGV0KyApID0gKCA+PnwgKVxubGV0ICggbGV0KiApID0gKCA+Pj0gKVxubGV0ICggYW5kKyApID0gYm90aFxuXG5tb2R1bGUgQkUgPSBzdHJ1Y3RcbiAgKCogWFhYKHNlbGlvcG91KTogVGhlIHBhdHRlcm4gaW4gYm90aCB0aGlzIG1vZHVsZSBhbmQgW0xFXSBhcmUgYSBjb21wcm9taXNlXG4gICAqIGJldHdlZW4gZWZmaWNpZW5jeSBhbmQgY29kZSByZXVzZS4gQnkgaW5saW5pbmcgW2Vuc3VyZV0geW91IGNhbiByZWNvdmVyXG4gICAqIGFib3V0IDIgbmFub3NlY29uZHMgb24gYXZlcmFnZS4gVGhhdCBtYXkgYWRkIHVwIGluIGNlcnRhaW4gYXBwbGljYXRpb25zLlxuICAgKlxuICAgKiBUaGlzIHBhdHRlcm4gZG9lcyBub3QgYWxsb2NhdGUgaW4gdGhlIGZhc3QgKHN1Y2Nlc3MpIHBhdGguXG4gICAqICopXG4gIGxldCBpbnQxNiBuID1cbiAgICBsZXQgYnl0ZXMgPSAyIGluXG4gICAgbGV0IHAgPVxuICAgICAgeyBydW4gPSBmdW4gaW5wdXQgcG9zIG1vcmUgZmFpbCBzdWNjIC0+XG4gICAgICAgIGlmIElucHV0LnVuc2FmZV9nZXRfaW50MTZfYmUgaW5wdXQgcG9zID0gKG4gbGFuZCAweGZmZmYpXG4gICAgICAgIHRoZW4gc3VjYyBpbnB1dCAocG9zICsgYnl0ZXMpIG1vcmUgKClcbiAgICAgICAgZWxzZSBmYWlsIGlucHV0IHBvcyBtb3JlIFtdIFwiQkUuaW50MTZcIiB9XG4gICAgaW5cbiAgICBlbnN1cmUgYnl0ZXMgcFxuXG4gIGxldCBpbnQzMiBuID1cbiAgICBsZXQgYnl0ZXMgPSA0IGluXG4gICAgbGV0IHAgPVxuICAgICAgeyBydW4gPSBmdW4gaW5wdXQgcG9zIG1vcmUgZmFpbCBzdWNjIC0+XG4gICAgICAgIGlmIEludDMyLmVxdWFsIChJbnB1dC51bnNhZmVfZ2V0X2ludDMyX2JlIGlucHV0IHBvcykgblxuICAgICAgICB0aGVuIHN1Y2MgaW5wdXQgKHBvcyArIGJ5dGVzKSBtb3JlICgpXG4gICAgICAgIGVsc2UgZmFpbCBpbnB1dCBwb3MgbW9yZSBbXSBcIkJFLmludDMyXCIgfVxuICAgIGluXG4gICAgZW5zdXJlIGJ5dGVzIHBcblxuICBsZXQgaW50NjQgbiA9XG4gICAgbGV0IGJ5dGVzID0gOCBpblxuICAgIGxldCBwID1cbiAgICAgIHsgcnVuID0gZnVuIGlucHV0IHBvcyBtb3JlIGZhaWwgc3VjYyAtPlxuICAgICAgICBpZiBJbnQ2NC5lcXVhbCAoSW5wdXQudW5zYWZlX2dldF9pbnQ2NF9iZSBpbnB1dCBwb3MpIG5cbiAgICAgICAgdGhlbiBzdWNjIGlucHV0IChwb3MgKyBieXRlcykgbW9yZSAoKVxuICAgICAgICBlbHNlIGZhaWwgaW5wdXQgcG9zIG1vcmUgW10gXCJCRS5pbnQ2NFwiIH1cbiAgICBpblxuICAgIGVuc3VyZSBieXRlcyBwXG5cbiAgbGV0IGFueV91aW50MTYgPVxuICAgIGVuc3VyZSAyICh1bnNhZmVfYXBwbHkgMiB+ZjooZnVuIGJzIH5vZmYgfmxlbjpfIC0+IEJpZ3N0cmluZ2FmLnVuc2FmZV9nZXRfaW50MTZfYmUgYnMgb2ZmKSlcblxuICBsZXQgYW55X2ludDE2ICA9XG4gICAgZW5zdXJlIDIgKHVuc2FmZV9hcHBseSAyIH5mOihmdW4gYnMgfm9mZiB+bGVuOl8gLT4gQmlnc3RyaW5nYWYudW5zYWZlX2dldF9pbnQxNl9zaWduX2V4dGVuZGVkX2JlICBicyBvZmYpKVxuXG4gIGxldCBhbnlfaW50MzIgID1cbiAgICBlbnN1cmUgNCAodW5zYWZlX2FwcGx5IDQgfmY6KGZ1biBicyB+b2ZmIH5sZW46XyAtPiBCaWdzdHJpbmdhZi51bnNhZmVfZ2V0X2ludDMyX2JlIGJzIG9mZikpXG5cbiAgbGV0IGFueV9pbnQ2NCA9XG4gICAgZW5zdXJlIDggKHVuc2FmZV9hcHBseSA4IH5mOihmdW4gYnMgfm9mZiB+bGVuOl8gLT4gQmlnc3RyaW5nYWYudW5zYWZlX2dldF9pbnQ2NF9iZSBicyBvZmYpKVxuXG4gIGxldCBhbnlfZmxvYXQgPVxuICAgIGVuc3VyZSA0ICh1bnNhZmVfYXBwbHkgNCB+ZjooZnVuIGJzIH5vZmYgfmxlbjpfIC0+IEludDMyLmZsb2F0X29mX2JpdHMgKEJpZ3N0cmluZ2FmLnVuc2FmZV9nZXRfaW50MzJfYmUgYnMgb2ZmKSkpXG5cbiAgbGV0IGFueV9kb3VibGUgPVxuICAgIGVuc3VyZSA4ICh1bnNhZmVfYXBwbHkgOCB+ZjooZnVuIGJzIH5vZmYgfmxlbjpfIC0+IEludDY0LmZsb2F0X29mX2JpdHMgKEJpZ3N0cmluZ2FmLnVuc2FmZV9nZXRfaW50NjRfYmUgYnMgb2ZmKSkpXG5lbmRcblxubW9kdWxlIExFID0gc3RydWN0XG4gIGxldCBpbnQxNiBuID1cbiAgICBsZXQgYnl0ZXMgPSAyIGluXG4gICAgbGV0IHAgPVxuICAgICAgeyBydW4gPSBmdW4gaW5wdXQgcG9zIG1vcmUgZmFpbCBzdWNjIC0+XG4gICAgICAgIGlmIElucHV0LnVuc2FmZV9nZXRfaW50MTZfbGUgaW5wdXQgcG9zID0gKG4gbGFuZCAweGZmZmYpXG4gICAgICAgIHRoZW4gc3VjYyBpbnB1dCAocG9zICsgYnl0ZXMpIG1vcmUgKClcbiAgICAgICAgZWxzZSBmYWlsIGlucHV0IHBvcyBtb3JlIFtdIFwiTEUuaW50MTZcIiB9XG4gICAgaW5cbiAgICBlbnN1cmUgYnl0ZXMgcFxuXG4gIGxldCBpbnQzMiBuID1cbiAgICBsZXQgYnl0ZXMgPSA0IGluXG4gICAgbGV0IHAgPVxuICAgICAgeyBydW4gPSBmdW4gaW5wdXQgcG9zIG1vcmUgZmFpbCBzdWNjIC0+XG4gICAgICAgIGlmIEludDMyLmVxdWFsIChJbnB1dC51bnNhZmVfZ2V0X2ludDMyX2xlIGlucHV0IHBvcykgblxuICAgICAgICB0aGVuIHN1Y2MgaW5wdXQgKHBvcyArIGJ5dGVzKSBtb3JlICgpXG4gICAgICAgIGVsc2UgZmFpbCBpbnB1dCBwb3MgbW9yZSBbXSBcIkxFLmludDMyXCIgfVxuICAgIGluXG4gICAgZW5zdXJlIGJ5dGVzIHBcblxuICBsZXQgaW50NjQgbiA9XG4gICAgbGV0IGJ5dGVzID0gOCBpblxuICAgIGxldCBwID1cbiAgICAgIHsgcnVuID0gZnVuIGlucHV0IHBvcyBtb3JlIGZhaWwgc3VjYyAtPlxuICAgICAgICBpZiBJbnQ2NC5lcXVhbCAoSW5wdXQudW5zYWZlX2dldF9pbnQ2NF9sZSBpbnB1dCBwb3MpIG5cbiAgICAgICAgdGhlbiBzdWNjIGlucHV0IChwb3MgKyBieXRlcykgbW9yZSAoKVxuICAgICAgICBlbHNlIGZhaWwgaW5wdXQgcG9zIG1vcmUgW10gXCJMRS5pbnQ2NFwiIH1cbiAgICBpblxuICAgIGVuc3VyZSBieXRlcyBwXG5cblxuICBsZXQgYW55X3VpbnQxNiA9XG4gICAgZW5zdXJlIDIgKHVuc2FmZV9hcHBseSAyIH5mOihmdW4gYnMgfm9mZiB+bGVuOl8gLT4gQmlnc3RyaW5nYWYudW5zYWZlX2dldF9pbnQxNl9sZSBicyBvZmYpKVxuXG4gIGxldCBhbnlfaW50MTYgID1cbiAgICBlbnN1cmUgMiAodW5zYWZlX2FwcGx5IDIgfmY6KGZ1biBicyB+b2ZmIH5sZW46XyAtPiBCaWdzdHJpbmdhZi51bnNhZmVfZ2V0X2ludDE2X3NpZ25fZXh0ZW5kZWRfbGUgIGJzIG9mZikpXG5cbiAgbGV0IGFueV9pbnQzMiAgPVxuICAgIGVuc3VyZSA0ICh1bnNhZmVfYXBwbHkgNCB+ZjooZnVuIGJzIH5vZmYgfmxlbjpfIC0+IEJpZ3N0cmluZ2FmLnVuc2FmZV9nZXRfaW50MzJfbGUgYnMgb2ZmKSlcblxuICBsZXQgYW55X2ludDY0ID1cbiAgICBlbnN1cmUgOCAodW5zYWZlX2FwcGx5IDggfmY6KGZ1biBicyB+b2ZmIH5sZW46XyAtPiBCaWdzdHJpbmdhZi51bnNhZmVfZ2V0X2ludDY0X2xlIGJzIG9mZikpXG5cbiAgbGV0IGFueV9mbG9hdCA9XG4gICAgZW5zdXJlIDQgKHVuc2FmZV9hcHBseSA0IH5mOihmdW4gYnMgfm9mZiB+bGVuOl8gLT4gSW50MzIuZmxvYXRfb2ZfYml0cyAoQmlnc3RyaW5nYWYudW5zYWZlX2dldF9pbnQzMl9sZSBicyBvZmYpKSlcblxuICBsZXQgYW55X2RvdWJsZSA9XG4gICAgZW5zdXJlIDggKHVuc2FmZV9hcHBseSA4IH5mOihmdW4gYnMgfm9mZiB+bGVuOl8gLT4gSW50NjQuZmxvYXRfb2ZfYml0cyAoQmlnc3RyaW5nYWYudW5zYWZlX2dldF9pbnQ2NF9sZSBicyBvZmYpKSlcbmVuZFxuXG5tb2R1bGUgVW5zYWZlID0gc3RydWN0XG4gIGxldCB0YWtlIG4gZiA9XG4gICAgbGV0IG4gPSBtYXggbiAwIGluXG4gICAgZW5zdXJlIG4gKHVuc2FmZV9hcHBseSBuIH5mKVxuXG4gIGxldCBwZWVrIG4gZiA9XG4gICAgdW5zYWZlX2xvb2thaGVhZCAodGFrZSBuIGYpXG5cbiAgbGV0IHRha2Vfd2hpbGUgY2hlY2sgZiA9XG4gICAgY291bnRfd2hpbGUgfmluaXQ6MCB+ZjpjaGVjayB+d2l0aF9idWZmZXI6ZlxuXG4gIGxldCB0YWtlX3doaWxlMSBjaGVjayBmID1cbiAgICBjb3VudF93aGlsZTEgfmY6Y2hlY2sgfndpdGhfYnVmZmVyOmZcblxuICBsZXQgdGFrZV90aWxsIGNoZWNrIGYgPVxuICAgIHRha2Vfd2hpbGUgKGZ1biBjIC0+IG5vdCAoY2hlY2sgYykpIGZcbmVuZFxuXG5tb2R1bGUgQ29uc3VtZSA9IHN0cnVjdFxuICB0eXBlIHQgPVxuICAgIHwgUHJlZml4XG4gICAgfCBBbGxcbmVuZFxuXG5sZXQgcGFyc2VfYmlnc3RyaW5nIH5jb25zdW1lIHAgYnMgPVxuICBsZXQgcCA9XG4gICAgbWF0Y2ggKGNvbnN1bWUgOiBDb25zdW1lLnQpIHdpdGhcbiAgICB8IFByZWZpeCAtPiBwXG4gICAgfCBBbGwgLT4gcCA8KiBlbmRfb2ZfaW5wdXRcbiAgaW5cbiAgVW5idWZmZXJlZC5wYXJzZV9iaWdzdHJpbmcgcCBic1xuXG5sZXQgcGFyc2Vfc3RyaW5nIH5jb25zdW1lIHAgcyA9XG4gIGxldCBsZW4gPSBTdHJpbmcubGVuZ3RoIHMgaW5cbiAgbGV0IGJzICA9IEJpZ3N0cmluZ2FmLmNyZWF0ZSBsZW4gaW5cbiAgQmlnc3RyaW5nYWYudW5zYWZlX2JsaXRfZnJvbV9zdHJpbmcgcyB+c3JjX29mZjowIGJzIH5kc3Rfb2ZmOjAgfmxlbjtcbiAgcGFyc2VfYmlnc3RyaW5nIH5jb25zdW1lIHAgYnNcbiIsIlxuKCoqKioqKioqKioqKioqKioqKiogIENvbnZlbmllbmNlIGZ1bmN0aW9ucyAgKioqKioqKioqKioqKioqKioqKioqKilcbmxldCBteWZvbGQgbCBhIGYgPSBMaXN0LmZvbGRfbGVmdCBmIGEgbFxubGV0IG15cmV2bWFwIGwgZiAgID0gTGlzdC5yZXZfbWFwIGYgbFxubGV0IG15cmV2bWFwMiBsMSBsMiBmICA9IExpc3QucmV2X21hcDIgZiBsMSBsMlxuXG4oKiBCdWlsZHMgYSBzdHJpbmcgZnJvbSBhIGxpc3Qgb2YgaXRlbXMgKilcbmxldCBzZXAgbWFwIHNwIGwgPSBMaXN0LmZvbGRfbGVmdCAoZnVuIGFjdSB4IC0+IGlmIGFjdSA9IFwiXCIgdGhlbiBtYXAgeCBlbHNlIGFjdSBeIHNwIF4gKG1hcCB4KSkgXCJcIiBsXG5cblxuXG4oKioqKioqKioqKioqKioqKioqKiAgU2hvcnRjdXRzIHRvIFphcml0aCAgKioqKioqKioqKioqKioqKioqKioqKiopXG5cbmxldCAoKyspID0gWi5hZGRcbmxldCAoKysrKSBiIGkgPSBiICsrIChaLm9mX2ludCBpKVxubGV0IHN1Y2MgPSBaLnN1Y2NcblxubGV0ICgtLSkgPSBaLnN1YlxubGV0IG1pbnVzID0gWi5uZWdcblxubGV0ICggKl4gKSBpIGogPSBsZXQgb3BlbiBaIGluIChaLm9mX2ludCBpKSAqKiBqXG5cbmxldCAoICoqICkgPSBaLm11bFxubGV0ICggKiouICkgaSBiID0gKFoub2ZfaW50IGkpICoqIGJcblxubGV0IHF1b21vZCA9IFouZGl2X3JlbVxubGV0IGJpZ21vZCBhIGIgPSBaLnJlbSBhIGJcblxubGV0IHNpZ24gPSBaLnNpZ25cbmxldCBiaWdfY29tcGFyZSA9IFouY29tcGFyZVxuXG5sZXQgYmlnemVybyA9IFouemVyb1xubGV0IGJpZ29uZSAgPSBaLm9uZVxuXG5sZXQgaXNfYmlnb25lIHggPSBaLmNvbXBhcmUgeCBiaWdvbmUgPSAwXG5cbmxldCBzb2IgPSBaLnRvX3N0cmluZ1xubGV0IGJvcyA9IFoub2Zfc3RyaW5nXG5cbmxldCBib2kgPSBaLm9mX2ludFxubGV0IGlvYiA9IFoudG9faW50XG5cbiIsIlxudHlwZSAnYSB0ID1cbiAgICB7IGRlZmF1bHRfdmFsdWUgOiAnYSA7XG4gICAgICBtdXRhYmxlIHJlYWxzaXplIDogaW50IDtcbiAgICAgIG11dGFibGUgdGFiIDogJ2EgYXJyYXkgfVxuICAgICAgXG5sZXQgY3JlYXRlIG4gdiA9XG4gIHsgZGVmYXVsdF92YWx1ZSA9IHYgO1xuICAgIHJlYWxzaXplID0gMCA7XG4gICAgdGFiID0gQXJyYXkubWFrZSBuIHYgfVxuXG5sZXQgY29weSB0ID0gXG4gIHsgZGVmYXVsdF92YWx1ZSA9IHQuZGVmYXVsdF92YWx1ZSA7XG4gICAgcmVhbHNpemUgPSB0LnJlYWxzaXplIDtcbiAgICB0YWIgPSBBcnJheS5jb3B5IHQudGFiIH1cblxubGV0IGdldCB0IGluZGV4ID0gXG4gIGlmIGluZGV4IDwgMCB0aGVuIGZhaWx3aXRoIFwiZXh0QXJyYXkuZ2V0LCBuZWdhdGl2ZSBpbmRleC5cIlxuICBlbHNlIGlmIGluZGV4ID49IHQucmVhbHNpemUgdGhlbiB0LmRlZmF1bHRfdmFsdWVcbiAgZWxzZSB0LnRhYi4oaW5kZXgpXG5cbmxldCBzZXQgdCBpbmRleCB2ID1cblxuICBsZXQgbGVuID0gQXJyYXkubGVuZ3RoIHQudGFiIGluXG4gIGlmIGluZGV4ID49IGxlbiB0aGVuXG4gICAgYmVnaW5cbiAgICAgICgqIFJlc2l6ZSAqKVxuICAgICAgbGV0IG5ld2FycmF5ID0gQXJyYXkubWFrZSAobWF4IChpbmRleCsxKSAoMiAqIGxlbikpIHQuZGVmYXVsdF92YWx1ZSBpblxuICAgICAgQXJyYXkuYmxpdCB0LnRhYiAwIG5ld2FycmF5IDAgbGVuIDtcbiAgICAgIHQudGFiIDwtIG5ld2FycmF5IDtcbiAgICBlbmQgO1xuXG4gIHQudGFiLihpbmRleCkgPC0gdiA7XG4gIHQucmVhbHNpemUgPC0gbWF4IHQucmVhbHNpemUgKGluZGV4KzEpIDtcbiAgKClcblxubGV0IHNpemUgdCA9IHQucmVhbHNpemVcblxubGV0IGZvbGQgdCBhY3UgZiA9XG4gIGxldCBha2sgPSByZWYgYWN1IGluXG4gIGZvciBpID0gMCB0byB0LnJlYWxzaXplIC0gMSBkb1xuICAgIGFrayA6PSBmIGkgdC50YWIuKGkpICFha2sgO1xuICBkb25lIDtcbiAgIWFra1xuXG5sZXQgaXRlciB0IGYgPVxuICBmb3IgaSA9IDAgdG8gdC5yZWFsc2l6ZSAtIDEgZG9cbiAgICBmIGkgdC50YWIuKGkpIDtcbiAgZG9uZVxuICBcblxuIiwib3BlbiBDb252ZW5pZW5jZVxuXG4oKioqIFNodWZmbGUsIGRldGVybWluaXN0aWNhbGx5LCB0aGUgdmFsdWVzIGluc2lkZSBwYXJ0cy4gKioqKVxuXG4oKiBTdGFydGluZyBmcm9tIHgsIGZpbmQgYSBudW1iZXIgcHJpbWUgd2l0aCB5LiAqKVxubGV0IHJlYyBmaW5kX3ByaW1lIHggeSA9XG4gIGxldCBnY2QgPSBaLmdjZCB4IHkgaW5cbiAgaWYgaXNfYmlnb25lIGdjZCB0aGVuIHhcbiAgZWxzZSBmaW5kX3ByaW1lIChaLnN1Y2MgeCkgeVxuXG5sZXQgY29tcHV0ZV9zaHVmZmxlIGNhcmQgY29tcHV0ZSA9XG5cbiAgKCogWiBkb2Mgc2F5cyBiaWdpbnRzIGNhbiBiZSBjb21wYXJlZCB1c2luZyA+ICAqKVxuICBpZiBjYXJkID0gWi56ZXJvIHRoZW5cbiAgICAoKiBUaGUgcGFydCBpcyBlbXB0eS4gKilcbiAgICAoZnVuIF8gLT4gYXNzZXJ0IGZhbHNlKSAoKiBTaG91bGQgbm90IGJlIGludm9rZWQuICopXG4gICAgICBcbiAgZWxzZVxuICBcbiAgKCogRmluZCBhIG51bWJlciB3aXRoaW4gdGhlIG9yZGVyIG9mIG1hZ25pdHVkZSBvZiBzcXJ0KGNhcmQpIFxuICAgKiBhbmQgdGhhdCBpcyBwcmltZSB3aXRoIGNhcmQuICopXG4gIGxldCBwcmltZSA9IGZpbmRfcHJpbWUgKFouc3FydCBjYXJkKSBjYXJkIGluXG5cbiAgZnVuIGluZGV4IC0+IFxuICAgIGxldCBuZXdfaW5kZXggPSBiaWdtb2QgKGluZGV4ICoqIHByaW1lKSBjYXJkIGluXG4gICAgY29tcHV0ZSBuZXdfaW5kZXhcblxuXG4iLCJvcGVuIENvbnZlbmllbmNlXG5cbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgIFBBUlRTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcblxuKCogQSBwYXJ0IGlzIGEgX2Zpbml0ZV8gc3ViLWVudW1lcmF0aW9uIGNvcnJlc3BvbmRpbmcgdG8gYSBnaXZlbiBkZXB0aC5cbiAqIFRoZSBkZXB0aCBpcyByb3VnaGx5IHRoZSBudW1iZXIgb2YgY29uc3RydWN0b3JzLiAqKVxudHlwZSAnYSBwYXJ0ID0ge1xuICAgICgqIENhcmRpbmFsIG9mIHRoaXMgcGFydC4gKilcbiAgICBwX2NhcmRpbmFsIDogWi50IDtcbiAgICBcbiAgICAoKiBDb21wdXRlIHRoZSBlbGVtZW50IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIGluZGV4LiAqKVxuICAgIGNvbXB1dGUgOiAoWi50IC0+ICdhKSA7XG4gIH1cblxubGV0IGdldF9jYXJkaW5hbCBwID0gcC5wX2NhcmRpbmFsXG5cbigqIERlYnVnOiB3ZSB0cnkgdHdvIG1vZGVzLiBTdGFuZGFyZCBhbmQgU2h1ZmZsZWQuIFxuICogSW4gc2h1ZmZsZWQgbW9kZSwgdmFsdWVzIGluIHBhcnRzIGFyZSAoZGV0ZXJtaW5pc3RpY2FsbHkpIHNodWZmbGVkLiAqKVxudHlwZSBtb2RlID0gU3RhbmRhcmQgfCBTaHVmZmxlZFxubGV0IG1vZGUgPSBTaHVmZmxlZFxuXG4oKiBTdXBwcmVzcyB3YXJuaW5nLiAqKVxubGV0IF8gPSBTdGFuZGFyZFxuXG5sZXQgc2h1ZmZsZSBwYXJ0ID1cbiAgbWF0Y2ggbW9kZSB3aXRoXG4gIHwgU3RhbmRhcmQgLT4gcGFydFxuICB8IFNodWZmbGVkIC0+IFxuICAgICAgeyBwX2NhcmRpbmFsID0gcGFydC5wX2NhcmRpbmFsIDtcblx0Y29tcHV0ZSAgICA9IFNodWZmbGUuY29tcHV0ZV9zaHVmZmxlIHBhcnQucF9jYXJkaW5hbCBwYXJ0LmNvbXB1dGUgfVxuXG4oKiBUaGUgRU1QVFkgcGFydCAqKVxubGV0IGVtcHR5X3BhcnQgPSB7XG4gIHBfY2FyZGluYWwgPSBiaWd6ZXJvIDtcbiAgY29tcHV0ZSA9IChmdW4gXyAtPiBhc3NlcnQgZmFsc2UpIDtcbn1cblxuKCogQSBEVU1NWSBwYXJ0LCBmb3IgY2VsbHMgdGhhdCByZW1haW4gdG8gYmUgaW5pdGlhbGl6ZWQuICopXG5sZXQgdW5pbml0aWFsaXplZF9wYXJ0ID0ge1xuICBwX2NhcmRpbmFsID0gYmlnemVybyA7XG4gIGNvbXB1dGUgPSAoZnVuIF8gLT4gYXNzZXJ0IGZhbHNlKSA7XG59XG5cbigqIE1hcHMgYSBwYXJ0IHRocm91Z2ggYSBwcmVzdW1hYmx5IGJpamVjdGl2ZSBmdW5jdGlvbiBmLiAqKVxubGV0IG1hcF9wYXJ0IGYgcGFydCA9XG4gIHsgcF9jYXJkaW5hbCA9IHBhcnQucF9jYXJkaW5hbCA7XG4gICAgY29tcHV0ZSAgICA9IChmdW4gaW5kZXggLT4gZiAocGFydC5jb21wdXRlIGluZGV4KSkgfVxuXG4oKiBCdWlsZHMgYSBwYXJ0IGZyb20gYSBmaW5pdGUgbGlzdCBvZiB2YWx1ZXMuICopXG5sZXQgcGFydF9mcm9tX2xpc3QgdmFsdWVzID1cbiAgbGV0IGF2YWx1ZXMgPSBBcnJheS5vZl9saXN0IHZhbHVlcyBpblxuICB7IHBfY2FyZGluYWwgPSBib2kgKEFycmF5Lmxlbmd0aCBhdmFsdWVzKSA7XG4gICAgY29tcHV0ZSA9IChmdW4gbiAtPiBhdmFsdWVzLihpb2IgbikpIH1cblxuKCoqKiBVbmlvbiAqKiopXG5cbigqIEZpbmRzIGluIHdoaWNoIHBhcnQgKG9mIHRoZSBnaXZlbiBsaXN0KSBpcyB0aGUgZ2l2ZW4gaW5kZXguICopXG5sZXQgcmVjIHN0YW5kYXJkX2NvbXB1dGVfdW5pb25fYXV4IHBhcnRsaXN0IGluZGV4ID1cbiAgbWF0Y2ggcGFydGxpc3Qgd2l0aFxuICB8IFtdIC0+XG4gICAgICAoKiBJbmRleCBpcyBvdXQgb2YgcGFydCBsaXN0LiBDYW5ub3QgaGFwcGVuLiAqKVxuICAgICAgYXNzZXJ0IGZhbHNlXG4gIHwgcCA6OiBwcyAtPlxuICAgICAgaWYgcC5wX2NhcmRpbmFsIDw9IGluZGV4IHRoZW4gc3RhbmRhcmRfY29tcHV0ZV91bmlvbl9hdXggcHMgKGluZGV4IC0tIHAucF9jYXJkaW5hbClcbiAgICAgIGVsc2UgKHAsIGluZGV4KVxuXG4oKiBEaXNqb2ludCB1bmlvbiBvZiB0aGVzZSBwYXJ0cy4gKilcbmxldCB1bmlvbl9wYXJ0cyBwYXJ0cyA9XG5cbiAgbGV0IHdoaWNocGFydCA9IHN0YW5kYXJkX2NvbXB1dGVfdW5pb25fYXV4IHBhcnRzIGluXG5cbiAgbGV0IGNvbXB1dGUgaW5kZXggPSBcbiAgICBsZXQgKHAsIGluZGV4KSA9IHdoaWNocGFydCBpbmRleCBpblxuICAgIHAuY29tcHV0ZSBpbmRleFxuICBpblxuXG4gICgqIFRoZSBjYXJkaW5hbCBvZiB0aGUgZGlzam9pbnQgdW5pb24gaXMgdGhlIHN1bSBvZiBjYXJkaW5hbHMuICopXG4gIGxldCBwcmVfcmVzdWx0ID1cbiAgICB7IHBfY2FyZGluYWwgPSBteWZvbGQgcGFydHMgYmlnemVybyAoZnVuIGFjdSBwIC0+IGFjdSArKyBwLnBfY2FyZGluYWwpIDtcbiAgICAgIGNvbXB1dGUgfVxuICBpblxuICBzaHVmZmxlIHByZV9yZXN1bHRcblxuXG4oKioqIFByb2R1Y3QgKioqKVxuXG4oKiBTcGxpdCB0aGUgaW5kZXggaW50byBjb29yZGluYXRlcyBpbiB0aGUgZGlmZmVyZW50IHBhcnRzLlxuICogV2UgdXNlIGRpdiAmIG1vZC4gKilcbmxldCByZWMgY29tcHV0ZV9wcm9kdWN0X3ZlY3RvciBpbmRleCBwYXJ0X3JldnZlY3RvciBhY3UgPVxuICBtYXRjaCBwYXJ0X3JldnZlY3RvciB3aXRoXG4gIHwgW10gLT4gYWN1XG4gIHwgcGNhcmQgOjogb3RoZXJzIC0+XG4gICAgICBhc3NlcnQgKHNpZ24gcGNhcmQgPSAxKSA7XG4gICAgICBsZXQgKGluZGV4JywgbW9kJykgPSBxdW9tb2QgaW5kZXggcGNhcmQgaW5cbiAgICAgIGNvbXB1dGVfcHJvZHVjdF92ZWN0b3IgaW5kZXgnIG90aGVycyAobW9kJyA6OiBhY3UpXG5cbmxldCBzdGFuZGFyZF9jb21wdXRlX3Byb2R1Y3RfYXV4IHBhcnRzID1cbiAgbGV0IHBhcnRfcmV2dmVjdG9yID0gbXlyZXZtYXAgcGFydHMgZ2V0X2NhcmRpbmFsIGluXG4gIGZ1biBpbmRleCAtPiBjb21wdXRlX3Byb2R1Y3RfdmVjdG9yIGluZGV4IHBhcnRfcmV2dmVjdG9yIFtdXG5cbigqIENhcnRlc2lhbiBwcm9kdWN0IG9mIHRoZXNlIHBhcnRzLiBcbiAqIENhdXRpb24hIGNvbXB1dGUgcmV0dXJucyBhIChwcm9kdWN0KSB2YWx1ZSBpbiB0aGUgcmV2ZXJzZWQgb3JkZXIgb2YgdGhlIHBhcnQgbGlzdC4gKilcbmxldCBwcm9kdWN0X3BhcnRzIHBhcnRzID1cblxuICBhc3NlcnQgKHBhcnRzIDw+IFtdKSA7XG4gIGxldCB3aGljaGluZGV4ZXMgPSBzdGFuZGFyZF9jb21wdXRlX3Byb2R1Y3RfYXV4IHBhcnRzIGluXG5cbiAgbGV0IGNvbXB1dGUgaW5kZXggPVxuICAgIGxldCB2ZWN0b3IgPSB3aGljaGluZGV4ZXMgaW5kZXggaW5cbiAgICAoKiBSZXN1bHQgaXMgcmV2ZXJzZWQuICopXG4gICAgbXlyZXZtYXAyIHZlY3RvciBwYXJ0cyAoZnVuIGluZGV4IHAgLT4gcC5jb21wdXRlIGluZGV4KSAgICBcbiAgaW5cblxuICBsZXQgcF9jYXJkaW5hbCA9IG15Zm9sZCBwYXJ0cyBiaWdvbmUgKGZ1biBhY3UgcCAtPiBhY3UgKiogcC5wX2NhcmRpbmFsKSBpblxuICAoKiBOb3RlOiBwX2NhcmRpbmFsIGNhbiBiZSA9IDAsIGlmIG9uZSBwYXJ0IGhhcyBzaXplIDAgKHRoaXMgY2FuIGhhcHBlbiBpZiBvbmUgZW51bWVyYXRpb24gaXMgZmluaXRlKS4gKilcbiAgXG4gICgqIFRoZSBjYXJkaW5hbCBvZiB0aGUgcHJvZHVjdCBpdCB0aGUgcHJvZHVjdCBvZiBjYXJkaW5hbHMuICopXG4gIGxldCBwcmVfcmVzdWx0ID0gXG4gICAgeyBwX2NhcmRpbmFsIDtcbiAgICAgIGNvbXB1dGUgfVxuICBpblxuICBzaHVmZmxlIHByZV9yZXN1bHRcblxuXG4iLCJvcGVuIFBhcnRzXG5vcGVuIENvbnZlbmllbmNlXG5cbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4oKiAgICAgICAgICAgICAgICAgIEVOVU1FUkFUSU9OUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcblxuKCogQW4gZW51bWVyYXRpb24gKilcbnR5cGUgJ2EgdCA9IHtcbiAgICAoKiBOdW1iZXIgb2YgZWxlbWVudHMuIE5vbmUgbWVhbnMgaW5maW5pdHkuICopXG4gICAgY2FyZGluYWwgOiBaLnQgb3B0aW9uIDtcbiAgICBcbiAgICAoKiBOdW1iZXIgb2YgcGFydHMuIE5vbmUgbWVhbnMgaW5maW5pdHkuICopXG4gICAgbl9wYXJ0cyAgOiBpbnQgb3B0aW9uIDtcblxuICAgICgqIEFuIGV4dGVuc2libGUgYXJyYXkgb2YgcGFydHMsIGluIG9yZGVyIHRvIGNvbXB1dGUgcGFydHMgbGF6aWx5LiAqKVxuICAgIHBhcnRzIDogKCdhIHBhcnQpIEV4dEFycmF5LnQgO1xuICAgIFxuICAgICgqIEZ1bmN0aW9uIHVzZWQgdG8gY3JlYXRlIGEgbmV3IHBhcnQgd2hlbiBuZWNlc3NhcnkuICopXG4gICAgbmV3X3BhcnQgOiAoaW50IC0+ICdhIHBhcnQpIDtcblxuICAgICgqIEEgdGl0bGUsIG1vc3RseSBmb3IgZGVidWdnaW5nLiAqKVxuICAgIHRpdGxlIDogc3RyaW5nIExhenkudCA7XG4gIH1cblxubGV0IGNhcmRpbmFsIGV4ZW4gPSBleGVuLmNhcmRpbmFsXG5cbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4oKiAgICAgICAgICAgICBBQ0NFU1NJTkcgRU5VTUVSQVRJT05TICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKVxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcblxuKCogQ2hlY2sgdGhhdCB0aGUgcmVxdWlyZWQgcGFydCBpbmRleCBleGlzdHMgaW4gdGhlIGdpdmVuIGVudW1lcmF0aW9uLiAqKVxubGV0IGNoZWNrX2FycmF5X2luZGV4IGluZGV4IGV4ZW4gPVxuICBtYXRjaCBleGVuLm5fcGFydHMgd2l0aFxuICB8IE5vbmUgLT4gdHJ1ZVxuICB8IFNvbWUgbiAtPiBpbmRleCA8IG5cblxuKCogR2V0IChwb3NzaWJseSBieSBmb3JjaW5nIGV2YWx1YXRpb24pIHRoZSBwYXJ0IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIGluZGV4LiAqKVxubGV0IGdldF9wYXJ0IGV4ZW4gYXJyYXlfaW5kZXggPVxuXG4gIGlmIGNoZWNrX2FycmF5X2luZGV4IGFycmF5X2luZGV4IGV4ZW4gdGhlblxuICAgIGxldCBwYXJ0ID0gRXh0QXJyYXkuZ2V0IGV4ZW4ucGFydHMgYXJyYXlfaW5kZXggaW5cblxuICAgIGxldCBwYXJ0ID1cbiAgICAgIGlmIHBhcnQgPT0gdW5pbml0aWFsaXplZF9wYXJ0IHRoZW5cblx0YmVnaW5cblx0ICAoKiBUaGlzIGNlbGwgaXMgdW5pbml0aWFsaXplZC4gU2V0IGl0IGZpcnN0LiAqKVxuXHQgIGxldCBuZXdjZWxsID0gZXhlbi5uZXdfcGFydCBhcnJheV9pbmRleCBpblxuXHQgIEV4dEFycmF5LnNldCBleGVuLnBhcnRzIGFycmF5X2luZGV4IG5ld2NlbGwgO1xuXHQgIG5ld2NlbGxcblx0ZW5kICBcbiAgICAgIGVsc2Vcblx0cGFydFxuICAgIGluXG5cbiAgICBwYXJ0XG5cbiAgZWxzZVxuICAgICAgZW1wdHlfcGFydFxuXG4oKiBGaW5kIGluIHdoaWNoIHBhcnQgb2YgYW4gZW51bWVhcmF0aW9uIGFuIGluZGV4IGhvbGRzLiAqKVxubGV0IHJlYyBnZXRfaW5fcGFydHMgZXhlbiB2YWx1ZV9pbmRleCBhcnJheV9pbmRleCA9XG5cbiAgbGV0IHBhcnQgPSBnZXRfcGFydCBleGVuIGFycmF5X2luZGV4IGluXG5cbiAgKCogSXMgdGhlIGluZGV4IGluIHJhbmdlIG9mIHRoaXMgcGFydCA/ICopXG4gIGlmIHBhcnQucF9jYXJkaW5hbCA8PSB2YWx1ZV9pbmRleCB0aGVuXG4gICAgKCogTm8uIEdvIHRvIG5leHQgcGFydC4gKilcbiAgICBnZXRfaW5fcGFydHMgZXhlbiAodmFsdWVfaW5kZXggLS0gcGFydC5wX2NhcmRpbmFsKSAoYXJyYXlfaW5kZXggKyAxKVxuICBlbHNlXG4gICAgKCogT0suIEdldCB0aGUgdmFsdWUgaW4gdGhpcyBwYXJ0LiAqKVxuICAgIHBhcnQuY29tcHV0ZSB2YWx1ZV9pbmRleFxuXG4oKiBHZXRzIGEgdmFsdWUsIGdpdmVuIGFuIGFic29sdXRlIGluZGV4LiAqKVxubGV0IGdldCBleGVuIGluZGV4ID1cbiAgYmVnaW4gbWF0Y2ggZXhlbi5jYXJkaW5hbCB3aXRoXG4gIHwgTm9uZSAtPiAoKVxuICB8IFNvbWUgbWF4IC0+IFxuICAgICAgaWYgbWF4IDw9IGluZGV4IHRoZW4gXG5cdGZhaWx3aXRoIChQcmludGYuc3ByaW50ZiBcIkV4ZW51bS5nZXQ6IGluZGV4IGlzIG91dCBvZiBib3VuZHMgOiAlcyAvICVzXCIgKHNvYiBpbmRleCkgKHNvYiAobWF4IC0tIGJpZ29uZSkpKVxuICBlbmQgO1xuICBcbiAgZ2V0X2luX3BhcnRzIGV4ZW4gaW5kZXggMFxuXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgICAgIEJVSUxESU5HIFNJTVBMRSBFTlVNRVJBVElPTlMgICAgICAgICAgICAgICAgICAgICAgKilcbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG5cbigqIEFuIGVudW1lcmF0aW9uIGZyb20gYSBzaW5nbGUgcGFydC4gKilcbmxldCBmcm9tX3NpbmdsZV9wYXJ0IHRpdGxlIGFfcGFydCA9XG4gIGxldCBwYXJ0cyA9IEV4dEFycmF5LmNyZWF0ZSAxIGVtcHR5X3BhcnQgaW5cbiAgRXh0QXJyYXkuc2V0IHBhcnRzIDAgYV9wYXJ0IDsgIFxuXG4gIHsgY2FyZGluYWwgPSBTb21lIChhX3BhcnQucF9jYXJkaW5hbCkgO1xuICAgIG5fcGFydHMgID0gU29tZSAxIDtcbiAgICBwYXJ0cyA7XG4gICAgKCogVGhpcyBlbnVtZXJhdGlvbiBpcyBmaW5pdGUuIFdlIHNob3VsZCBuZXZlciBuZWVkIHRvIGNyZWF0ZSBhIG5ldyBjZWxsLiAqKVxuICAgIG5ld19wYXJ0ID0gKGZ1biBfIC0+IGFzc2VydCBmYWxzZSkgO1xuICAgIHRpdGxlIH1cblxuKCogQW4gZW51bWVyYXRpb24gZnJvbSBhIGxpc3Qgb2YgdmFsdWVzLiAqKVxubGV0IGZyb21fbGlzdCA/KG5hbWU9XCJ1bm5hbWVkXCIpIHZhbHVlcyA9IGZyb21fc2luZ2xlX3BhcnQgKGxhenkgbmFtZSkgKHBhcnRfZnJvbV9saXN0IHZhbHVlcylcblxuXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuKCogICAgICAgICAgIEFMR0VCUkFJQyBPUEVSQVRJT05TIE9OIEVOVU1FUkFUSU9OUyAgICAgICAgICAgICAgICAgKilcbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG5cbigqIFBheSAqKVxubGV0IHBheSBsX2V4ZW4gPVxuXG4gIGxldCBwYXJ0cyA9IEV4dEFycmF5LmNyZWF0ZSAxIHVuaW5pdGlhbGl6ZWRfcGFydCBpblxuICBFeHRBcnJheS5zZXQgcGFydHMgMCBlbXB0eV9wYXJ0IDtcblxuICAoKiBPbiB0aGUgZmlyc3QgY2FsbCB0byBuZXdfcGFydCwgd2Ugd2lsbCBjaGVjayB0aGF0IHRoZSBhcmd1bWVudCBmdW5jdGlvbiBpcyBpbmRlZWQgaW5maW5pdGUuICopXG4gIGxldCBpc19pbmZpbml0ZSA9IGxhenlcbiAgICAgICgoTGF6eS5mb3JjZSBsX2V4ZW4pLmNhcmRpbmFsID0gTm9uZSlcbiAgaW5cblxuICBsZXQgbmV3X3BhcnQgYXJyYXlfaW5kZXggPVxuICAgIGFzc2VydCAoYXJyYXlfaW5kZXggPiAwKSA7XG4gICAgYXNzZXJ0IChMYXp5LmZvcmNlIGlzX2luZmluaXRlKSA7XG4gICAgZ2V0X3BhcnQgKExhenkuZm9yY2UgbF9leGVuKSAoYXJyYXlfaW5kZXggLSAxKVxuICBpblxuXG4gIHsgY2FyZGluYWwgPSBOb25lIDtcbiAgICBuX3BhcnRzID0gTm9uZSA7XG4gICAgcGFydHMgO1xuICAgIG5ld19wYXJ0IDtcbiAgICB0aXRsZSA9IGxhenkgKFwicGF5ICguLi4pXCIpIH1cblxuKCogTWFwcyBhbiBlbnVtZXJhdGlvbiAqKVxubGV0IG1hcCBleGVuIGYgPSBcblxuICBsZXQgcGFydHMgPSBFeHRBcnJheS5jcmVhdGUgMSB1bmluaXRpYWxpemVkX3BhcnQgaW5cblxuICBsZXQgbmV3X3BhcnQgYXJyYXlfaW5kZXggPVxuICAgIGxldCBwYXJ0ID0gZ2V0X3BhcnQgZXhlbiBhcnJheV9pbmRleCBpblxuICAgIG1hcF9wYXJ0IGYgcGFydFxuICBpblxuXG4gIHsgY2FyZGluYWwgPSBleGVuLmNhcmRpbmFsIDtcbiAgICBuX3BhcnRzID0gZXhlbi5uX3BhcnRzIDtcbiAgICBwYXJ0cyA7XG4gICAgbmV3X3BhcnQgO1xuICAgIHRpdGxlID0gbGF6eSAoXCJtYXAgKFwiIF4gTGF6eS5mb3JjZSBleGVuLnRpdGxlIF4gXCIpXCIpIH1cblxuXG4oKiBGaW5pdGUgc3ViLWVudW1lcmF0aW9uICopXG5sZXQgc3ViIH5tYXggZXhlbiA9XG5cbiAgbGV0IG5ld2NhcmRpbmFsID1cbiAgICBtYXRjaCBleGVuLmNhcmRpbmFsIHdpdGhcbiAgICB8IE5vbmUgLT4gU29tZSBtYXhcbiAgICB8IFNvbWUgYm91bmQgLT4gXG5cdGlmIG1heCA8PSBib3VuZCB0aGVuIFNvbWUgbWF4XG5cdGVsc2UgU29tZSBib3VuZFxuICBpblxuXG4gIHsgZXhlbiB3aXRoIGNhcmRpbmFsID0gbmV3Y2FyZGluYWwgfVxuXG4oKioqIERJU0pPSU5UIFVOSU9OICoqKilcblxuKCogQ29tcHV0ZSB0aGUgcG9zc2libHkgaW5maW5pdGUgc3VtIG9mIGNhcmRpbmFscy4gKilcbmxldCByZWMgc3VtX2NhcmRpbmFscyBhY3UgPSBmdW5jdGlvblxuICB8IFtdIC0+IFNvbWUgYWN1XG4gIHwgZXhlbiA6OiBleGVucyAtPlxuICAgICAgYmVnaW4gbWF0Y2ggZXhlbi5jYXJkaW5hbCB3aXRoXG4gICAgICB8IE5vbmUgLT4gTm9uZSAoKiBJbmZpbml0ZSAqKVxuICAgICAgfCBTb21lIG4gLT4gc3VtX2NhcmRpbmFscyAoYWN1ICsrIG4pIGV4ZW5zXG4gICAgICBlbmRcblxuKCogbWF4LCB0YWtpbmcgYWNjb3VudCBvZiBpbmZpbml0eSAoTm9uZSkgKilcbmxldCBpbmZtYXggYSBiID1cbiAgbWF0Y2ggKGEsYikgd2l0aFxuICB8IChOb25lLCBfKSB8IChfLCBOb25lKSAtPiBOb25lXG4gIHwgKFNvbWUgeCwgU29tZSB5KSAtPiBTb21lIChtYXggeCB5KVxuXG4oKiBSZXR1cm5zIHRoZSBtYXhpbWFsIG51bWJlciBvZiBwYXJ0cyBvZiB0aGVzZSBlbnVtZXJhdGlvbnMuICopXG5sZXQgbWF4X3BhcnRzIGV4ZW5zID0gbXlmb2xkIGV4ZW5zIChTb21lIDApIChmdW4gYWN1IGV4ZW4gLT4gaW5mbWF4IGFjdSBleGVuLm5fcGFydHMpXG5cbigqIERpc2pvaW50IHVuaW9uIG9mIGVudW1lcmF0aW9ucy4gKilcbmxldCB1bmlvbiBleGVucyA9XG4gIGxldCBjYXJkaW5hbCA9IHN1bV9jYXJkaW5hbHMgYmlnemVybyBleGVucyBpbiAgXG4gIGxldCBwYXJ0cyA9IEV4dEFycmF5LmNyZWF0ZSAxIHVuaW5pdGlhbGl6ZWRfcGFydCBpblxuICBsZXQgbmV3X3BhcnQgYXJyYXlfaW5kZXggPSB1bmlvbl9wYXJ0cyAoTGlzdC5tYXAgKGZ1biBleCAtPiBnZXRfcGFydCBleCBhcnJheV9pbmRleCkgZXhlbnMpIGluXG5cbiAgeyBjYXJkaW5hbCA7XG4gICAgbl9wYXJ0cyA9IG1heF9wYXJ0cyBleGVucyA7XG4gICAgcGFydHMgO1xuICAgIG5ld19wYXJ0IDtcbiAgICB0aXRsZSA9IGxhenkgKFwidW5pb24gKFwiIF4gKHNlcCAoZnVuIGUgLT4gTGF6eS5mb3JjZSBlLnRpdGxlKSBcIiwgXCIgZXhlbnMpIF4gXCIpXCIpIH1cblxuXG4oKioqIENBUlRFU0lBTiBQUk9EVUNUICoqKilcblxuKCogQ29tcHV0ZSB0aGUgcG9zc2libHkgaW5maW5pdGUgcHJvZHVjdCBvZiBjYXJkaW5hbHMuIFxuICogSWYgb25lIG9mIHRoZW0gaXMgZW1wdHksIHRoZSByZXN1bHQgaXMgZW1wdHkuICopXG5sZXQgcmVjIHByb2RfY2FyZGluYWxzIGFjdSA9IGZ1bmN0aW9uXG4gIHwgW10gLT4gYWN1XG4gIHwgZXhlbiA6OiBleGVucyAtPlxuICAgICAgYmVnaW4gbWF0Y2ggKGV4ZW4uY2FyZGluYWwsIGFjdSkgd2l0aFxuICAgICAgfCBOb25lLCBfIC0+IHByb2RfY2FyZGluYWxzIE5vbmUgZXhlbnNcbiAgICAgIHwgKFNvbWUgeixfKSB3aGVuIHogPSBiaWd6ZXJvIC0+IFNvbWUgYmlnemVyb1xuICAgICAgfCBTb21lIF8sIE5vbmUgLT4gcHJvZF9jYXJkaW5hbHMgTm9uZSBleGVuc1xuICAgICAgfCBTb21lIG4sIFNvbWUgayAtPiBwcm9kX2NhcmRpbmFscyAoU29tZSAobiAqKiBrKSkgZXhlbnNcbiAgICAgIGVuZFxuXG4oKiBGaW5kIGFsbCB2ZWN0b3JzIHRoYXQgcmVhY2ggdGhlIGdpdmVuIG1heCBkZXB0aC4gXG4gKiBJbnB1dDogdGhlIGV4cGVjdGVkIChtYXgpIGRlcHRoLiBcbiAqICAgICAgICB0aGUgdmVjdG9yIG9mIG1heGltYWwgaW5kZXhlcyByZWFjaGFibGUgYnkgZWFjaCBjb29yZGluYXRlLlxuICogICAgICAgICAgKHRoZXNlIG1heGltYWwgaW5kZXhlcyBhcmUgZ3VhcmFudGVlZCB0byBiZSA8PSBtYXggZGVwdGgpLiAqKVxuXG4oKiBBbGdvcml0aG06IGJydXQgZm9yY2UgZW51bWVyYXRpb24gb2YgYWxsIHR1cGxlcy5cbiAqIEFuIG9wdGltaXphdGlvbiwgdGhvdWdoOiB3ZSBrbm93IGlmIHRoZSBtYXggZGVwdGggaGFzIGJlZW4gcmVhY2hlZCBpbiB0aGUgY3VycmVudCB0ZW1wb3JhcnkgdmVjdG9yLFxuICogYW5kIHdlIGtub3cgYXQgd2hpY2ggcG9zaXRpb24gaXMgdGhlICdsYXN0IGNoYW5jZScgb2YgcmVhY2hpbmcgdGhlIG1heCBkZXB0aC4gKilcblxuKCogRm9yIGVmZmljaWVuY3ksIHJldl9tYXggaXMgdGhlIHJldmVyc2VkIGxpc3Qgb2YgbWF4X2luZGV4ZXMuIFxuICogZmxhZyBpbmRpY2F0ZXMgaWYgbWF4IGRlcHRoIGhhcyBiZWVuIHJlYWNoZWQgaW4gdGhlIGN1cnJlbnQgdGVtcG9yYXJ5IHZlY3Rvci4gXG4gKiBhY3UgaXMgdGhlIGxpc3Qgb2YgYWxsIHZlY3RvcnMuIFxuICogcG9zIGlzIHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSByZXZlcnNlZCBtYXhfaW5kZXhlcyBsaXN0LiAqKVxubGV0IHJlYyBmaW5kX3ZlY3RvcnNfYXV4IGxhc3RfY2hhbmNlIGRlcHRoIGZsYWcgYWN1IHRlbXBfdmVjdCBwb3MgcmV2X21heCA9IFxuXG4gIG1hdGNoIHJldl9tYXggd2l0aFxuICAoKiBUaGlzIHZlY3RvciBpcyBmaW5pc2hlZC4gQWRkIGl0IHRvIHRoZSBhY2N1bXVsYXRvci4gKilcbiAgfCBbXSAtPlxuICAgICAgYXNzZXJ0IGZsYWcgOyAoKiBUaGUgbWF4aW1hbCBkZXB0aCBtdXN0IGhhdmUgYmVlbiByZWFjaGVkLiAqKVxuICAgICAgdGVtcF92ZWN0IDo6IGFjdVxuXG4gIHwgY3VycmVudF92dXAgOjogb3RoZXJzIC0+XG5cbiAgICAgIGxldCAodmxvdywgdnVwKSA9XG5cdCgqIFBhcnRpY3VsYXIgY2FzZTogaWYgdGhpcyBpcyB0aGUgbGFzdCBjaGFuY2UgYW5kIGZsYWcgaXMgZmFsc2UuICopXG5cdGlmIChub3QgZmxhZykgJiYgcG9zID0gbGFzdF9jaGFuY2UgdGhlblxuXHQgIGJlZ2luXG5cdCAgICBhc3NlcnQgKGN1cnJlbnRfdnVwID0gZGVwdGgpIDtcblx0ICAgIChkZXB0aCwgZGVwdGgpXG5cdCAgZW5kXG5cblx0ZWxzZSAoMCwgY3VycmVudF92dXApXG4gICAgICBpblxuXG4gICAgICAoKiBJdGVyYXRlIG92ZXIgYWxsIHRoZXNlIHZhbHVlcy4gKilcbiAgICAgIGxldCByYWN1ID0gcmVmIGFjdSBpblxuICAgICAgXG4gICAgICBmb3IgY3VycmVudF9pbmRleCA9IHZsb3cgdG8gdnVwIGRvXG5cdHJhY3UgOj0gZmluZF92ZWN0b3JzX2F1eCBsYXN0X2NoYW5jZSBkZXB0aCAoZmxhZyB8fCBjdXJyZW50X2luZGV4ID0gZGVwdGgpICFyYWN1IChjdXJyZW50X2luZGV4IDo6IHRlbXBfdmVjdCkgKHBvcysxKSBvdGhlcnMgO1xuICAgICAgZG9uZSA7XG5cbiAgICAgICgqIEZpbmlzaGVkLiAqKVxuICAgICAgIXJhY3VcblxuICAgICAgXG5sZXQgZmluZF92ZWN0b3JzIGRlcHRoIHJldl9tYXhfaW5kZXhlcyA9IFxuIFxuICAoKiBGaW5kIHRoZSBwb3NpdGlvbiBvZiB0aGUgbGFzdCBjaGFuY2UuICopXG4gIGxldCAoXywgbGFzdF9jaGFuY2UpID0gbXlmb2xkIHJldl9tYXhfaW5kZXhlcyAoMCwgKC0xKSkgXG4gICAgICBiZWdpbiBmdW4gKGN1cnJlbnRfcG9zLCBsYXN0KSB2IC0+IGlmIHYgPSBkZXB0aCB0aGVuIChjdXJyZW50X3BvcysxLCBjdXJyZW50X3BvcykgZWxzZSAoY3VycmVudF9wb3MrMSwgbGFzdCkgZW5kXG4gIGluXG4gIGFzc2VydCAobGFzdF9jaGFuY2UgPj0gMCkgOyAoKiBUaGUgbWF4aW1hbCBkZXB0aCBtdXN0IGJlIHJlYWNoYWJsZS4gV2UgbmV2ZXIgdHJ5IHRvIGJ1aWxkIGEgcGFydCB0aGF0IGNhbm5vdCBiZSBidWlsdC4gKilcblxuICBmaW5kX3ZlY3RvcnNfYXV4IGxhc3RfY2hhbmNlIGRlcHRoIGZhbHNlIFtdIFtdIDAgcmV2X21heF9pbmRleGVzXG5cbigqIE1hcHMgYSB2ZWN0b3IgdG8gYSByZXZfbGlzdCBvZiBwYXJ0cy4gKilcbmxldCB2ZWN0b3JfdG9fcGFydF9saXN0IGV4ZW5zIHZlY3RvciA9IFxuICAodHJ5IG15cmV2bWFwMiBleGVucyB2ZWN0b3IgZ2V0X3BhcnQgd2l0aCBfIC0+IGFzc2VydCBmYWxzZSlcblxuKCogQ3JlYXRlcyBhIG5ldyBwYXJ0IHdpdGggZGVwdGggYXJyYXlfaW5kZXggY29ycmVzcG9uZGluZyB0byB0aGUgY2FydGVzaWFuIHByb2R1Y3Qgb2YgdGhlIGdpdmVuIGVudW1lcmF0aW9ucy4gKilcbmxldCBwcm9kX3BhcnRzIGFycmF5X2luZGV4IGV4ZW5zID1cbiAgKCogVGhpcyBwYXJ0IGlzIHRoZSB1bmlvbiBvZiBjYXJ0ZXNpYW4gcHJvZHVjdHMgb2YgUEFSVFMsIGF0IGxlYXN0IG9uZSBvZiB0aGVtIGJlaW5nIGF0IHRoZSBnaXZlbiBkZXB0aC4gKilcblxuICAoKiBEZWY6IGEgJ3ZlY3RvcicgaXMgYSB2ZWN0b3Igb2YgaW5kZXhlcy4gRWFjaCBpbmRleCBjb3JyZXNwb25kcyB0byBhbiBlbnVtZXJhdGlvbi4gXG4gICAqIFRoZSBsZW5ndGggb2YgdGhlIHZlY3RvciA9IHRoZSBsZW5ndGggb2YgdGhlIGxpc3QgJ2V4ZW5zJy4gKilcblxuICBhc3NlcnQgKGV4ZW5zIDw+IFtdKSA7XG5cbiAgKCogR2V0IHRoZSByZXZfdmVjdG9ycyBvZiBtYXhpbWFsIHBhcnQgaW5kZXhlcywgYnV0IG5ldmVyIGZ1cnRoZXIgdGhhbiBhcnJheV9pbmRleC4gKilcbiAgbGV0IG1heF9yZXZpbmRleGVzID0gbXlyZXZtYXAgZXhlbnNcbiAgICAgIGJlZ2luIGZ1biBleCAtPlxuXHRtYXRjaCBleC5uX3BhcnRzIHdpdGhcblx0fCBOb25lIC0+IGFycmF5X2luZGV4ICgqIEluZmluaXRlICopXG5cdHwgU29tZSBuIC0+IG1pbiAobi0xKSBhcnJheV9pbmRleFxuICAgICAgZW5kXG4gIGluXG5cbiAgKCogTGlzdCBhbGwgdmVjdG9ycyB0aGF0IHNhdGlzZnkgdGhlIGN1cnJlbnQgZGVwdGggKGkuZS4gYXQgbGVhc3Qgb25lIGluZGV4IGlzIHRoZSBleHBlY3RlZCBhcnJheV9pbmRleCkuICopXG4gIGxldCBhbGxfdmVjdG9ycyA9IGZpbmRfdmVjdG9ycyBhcnJheV9pbmRleCBtYXhfcmV2aW5kZXhlcyBpblxuXG4gIGFzc2VydCAoYWxsX3ZlY3RvcnMgPD4gW10pIDtcbiAgXG4gICgqIE1hcCB0aGVzZSB2ZWN0b3JzIHRvIHBhcnQgbGlzdHMuICopXG4gIGxldCBhbGxfcmV2X3BhcnRzID0gTGlzdC5yZXZfbWFwICh2ZWN0b3JfdG9fcGFydF9saXN0IGV4ZW5zKSBhbGxfdmVjdG9ycyBpblxuXG4gICgqIE1hcCBlYWNoIHBhcnQgbGlzdCB0byBhIHByb2R1Y3QgcGFydC4gXG4gICAqIHByb2R1Y3RfcGFydHMgcmV2ZXJzZXMgdGhlIHR1cGxlcy4gKilcbiAgbGV0IGFsbF9wcm9kX3BhcnRzID0gTGlzdC5yZXZfbWFwIHByb2R1Y3RfcGFydHMgYWxsX3Jldl9wYXJ0cyBpblxuXG4gICgqIEdldCB0aGUgdW5pb24gKilcbiAgdW5pb25fcGFydHMgYWxsX3Byb2RfcGFydHNcblxuKCogQ2FydGVzaWFuIHByb2R1Y3QuICopXG5sZXQgcHJvZHVjdCBleGVucyA9XG4gIFxuICBsZXQgY2FyZGluYWwgPSBwcm9kX2NhcmRpbmFscyAoU29tZSBiaWdvbmUpIGV4ZW5zIGluXG4gIGxldCBwYXJ0cyA9IEV4dEFycmF5LmNyZWF0ZSAxIHVuaW5pdGlhbGl6ZWRfcGFydCBpblxuXG4gIHsgY2FyZGluYWwgO1xuICAgIG5fcGFydHMgPSBtYXhfcGFydHMgZXhlbnMgO1xuICAgIHBhcnRzIDtcbiAgICBuZXdfcGFydCA9IChmdW4gYXJyYXlfaW5kZXggLT4gcHJvZF9wYXJ0cyBhcnJheV9pbmRleCBleGVucykgO1xuICAgIHRpdGxlID0gbGF6eSAoXCJwcm9kdWN0IChcIiBeIChzZXAgKGZ1biBlIC0+IExhenkuZm9yY2UgZS50aXRsZSkgXCIsIFwiIGV4ZW5zKSBeIFwiKVwiKSB9XG5cbiIsIm9wZW4gRXhlblxub3BlbiBDb252ZW5pZW5jZVxuXG4oKiBHZW5lcmljIHZlcnNpb24gdGhhdCBjYW4gYmUgaW5zdGFudGlhdGVkIHRvIGEgTHd0IHZlcnNpb24gYW5kIGEgbm9uLWx3dCB2ZXJzaW9uLiAqKVx0XHRcdFx0XHRcbmxldCBnZW5fdGVzdGVyIHByaW50ID90b3MgYmluZCB1bml0IGV4ZW4gPyhmcm9tPWJpZ3plcm8pID91cHRvID8odmVyYm9zZV9wZXJpb2Q9MTAwMDApIH5sZW4gZiA9XG4gIFxuICBhc3NlcnQgKGxlbiA+IDApIDtcbiAgYXNzZXJ0ICh2ZXJib3NlX3BlcmlvZCA+IDApIDtcblxuICBsZXQgYmlndmVyYm9zZV9wZXJpb2QgPSBib2kgdmVyYm9zZV9wZXJpb2QgaW5cblxuICBsZXQgdGVzdF9jdXJyZW50IGNvdW50IGluZGV4ID1cbiAgICBsZXQgdmVyYm9zZSA9IHZlcmJvc2VfcGVyaW9kID4gMCAmJiBaLmVxdWFsIGJpZ3plcm8gKGJpZ21vZCBjb3VudCBiaWd2ZXJib3NlX3BlcmlvZCkgaW5cbiAgICBsZXQgdGVzdF92YWx1ZSA9IGdldCBleGVuIGluZGV4IGluXG4gICAgXG4gICAgYmluZCAoaWYgdmVyYm9zZSB0aGVuIHByaW50IChQcmludGYuc3ByaW50ZiBcIlRlc3QgbnVtYmVyICVzLCBpbmRleCAjJXMgLi4uICVzXCIgKHNvYiBjb3VudCkgKHNvYiBpbmRleClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoIHRvcyB3aXRoIE5vbmUgLT4gXCJcIiB8IFNvbWUgdG9zIC0+IFwid2l0aCBcIiBeIHRvcyB0ZXN0X3ZhbHVlIF4gXCIgLi4uIFwiKSlcbiAgICAgICAgICBlbHNlIHVuaXQpXG4gICAgICBcblx0IChmdW4gKCkgLT5cblx0ICBiaW5kIChmIHRlc3RfdmFsdWUpXG5cdCAgICAgICAoZnVuICgpIC0+IGlmIHZlcmJvc2UgdGhlbiBwcmludCBcImRvbmVcXG5cIiBlbHNlIHVuaXQpKVxuICBpblxuICBcbiAgKCogZm9yIGxvb3AsIGluIHdoaWNoIHdlIGRvdWJsZSB0aGUgY3VycmVudCBpbmRleCBldmVyeSBsZW4gaXRlcmF0aW9ucy4gKilcbiAgbGV0IHJlYyBpdGVyYXRlIGNvdW50IGN1cnJlbnQgcmVtYWluaW5nID1cbiAgICAoKiBFbmQgb2YgdGhpcyBwYXJ0PyBJZiB5ZXMsIGN1cnJlbnQgOj0gY3VycmVudCAqIDIuICopXG4gICAgaWYgcmVtYWluaW5nID0gMCB0aGVuXG4gICAgICBpdGVyYXRlIGNvdW50ICgyICoqLiBjdXJyZW50KSBsZW5cblxuICAgIGVsc2VcbiAgICAgICgqIEhhdmUgd2UgcmVhY2hlZCB0aGUgdXBwZXIgYm91bmQ/ICopXG4gICAgICBsZXQgY29udGludWUgPVxuXHRtYXRjaCB1cHRvIHdpdGhcblx0fCBOb25lIC0+IHRydWVcblx0fCBTb21lIHVwcGVyX2JvdW5kIC0+IGJpZ19jb21wYXJlIGN1cnJlbnQgdXBwZXJfYm91bmQgPCAwXG4gICAgICBpblxuXG4gICAgICBpZiBjb250aW51ZSB0aGVuXG5cdGJlZ2luXG5cdCAgYmluZCAodGVzdF9jdXJyZW50IGNvdW50IGN1cnJlbnQpXG5cdCAgICAgICAoZnVuICgpIC0+IGl0ZXJhdGUgKHN1Y2MgY291bnQpIChzdWNjIGN1cnJlbnQpIChyZW1haW5pbmcgLSAxKSlcblx0ZW5kXG4gICAgICBlbHNlXG5cdCgqIFdlJ3JlIGRvbmUuICopXG5cdHVuaXRcbiAgaW5cblxuICBpdGVyYXRlIGJpZ3plcm8gZnJvbSBsZW5cbiIsIm9wZW4gRXhlbnVtX2ludGVybmFsc1xuXG5vcGVuIFBhcnRzXG5vcGVuIEV4ZW5cbm9wZW4gQ29udmVuaWVuY2VcblxudHlwZSAnYSBlbnVtID0gJ2EgRXhlbi50XG50eXBlICdhIHQgPSAnYSBlbnVtXG5cbmxldCBnZXRfZXhlbiB4ID0geFxuXG5sZXQgcHJvZHVjdCAgID0gRXhlbi5wcm9kdWN0XG5sZXQgdW5pb24gICAgID0gRXhlbi51bmlvblxubGV0IGZyb21fbGlzdCA9IEV4ZW4uZnJvbV9saXN0XG5sZXQgc2luZ2xlID9uYW1lIHggID0gZnJvbV9saXN0ID9uYW1lIFt4XVxubGV0IG1hcCAgICAgICA9IEV4ZW4ubWFwXG5sZXQgZ2V0ICAgICAgID0gRXhlbi5nZXRcbmxldCBjYXJkaW5hbCAgPSBFeGVuLmNhcmRpbmFsXG5sZXQgcGF5ICAgICAgID0gRXhlbi5wYXlcbmxldCBzdWIgICAgICAgPSBFeGVuLnN1YlxuXG4oKiBCb2lsZXJwbGF0ZSBjb2RlLiAqKVxudHlwZSAoJ2EsJ2IpIHR1cGxlMiA9IEMxXzIgb2YgJ2EgfCBDMl8yIG9mICdiXG5cbmxldCBjMV8yIHggPSBDMV8yIHhcbmxldCBjMl8yIHggPSBDMl8yIHhcblxubGV0IHByb2oyID0gZnVuY3Rpb25cbiAgfCBbQzFfMiBhIDsgQzJfMiBiXSAtPiAoYSxiKVxuICB8IF8gLT4gYXNzZXJ0IGZhbHNlXG5cbmxldCBwYWlyIGV4MSBleDIgPSBcbiAgbGV0IG1leDEgPSBtYXAgZXgxIGMxXzJcbiAgYW5kIG1leDIgPSBtYXAgZXgyIGMyXzIgaW5cbiAgbWFwIChwcm9kdWN0IFttZXgxIDsgbWV4Ml0pIHByb2oyXG5cbnR5cGUgKCdhLCdiLCdjKSB0dXBsZTMgPSBDMV8zIG9mICdhIHwgQzJfMyBvZiAnYiB8IEMzXzMgb2YgJ2NcblxubGV0IGMxXzMgeCA9IEMxXzMgeFxubGV0IGMyXzMgeCA9IEMyXzMgeFxubGV0IGMzXzMgeCA9IEMzXzMgeFxuXG5sZXQgcHJvajMgPSBmdW5jdGlvblxuICB8IFtDMV8zIGEgOyBDMl8zIGIgOyBDM18zIGNdIC0+IChhLGIsYylcbiAgfCBfIC0+IGFzc2VydCBmYWxzZVxuXG5sZXQgdHJpcGxlIGV4MSBleDIgZXgzID1cbiAgbGV0IG1leDEgPSBtYXAgZXgxIGMxXzNcbiAgYW5kIG1leDIgPSBtYXAgZXgyIGMyXzMgXG4gIGFuZCBtZXgzID0gbWFwIGV4MyBjM18zIGluXG4gIG1hcCAocHJvZHVjdCBbbWV4MSA7IG1leDIgOyBtZXgzXSkgcHJvajNcblxubGV0IHR1cGxlMiA9IHBhaXJcbmxldCB0dXBsZTMgPSB0cmlwbGVcbmxldCB0dXBsZTQgZTEgZTIgZTMgZTQgPSBtYXAgKHBhaXIgKHRyaXBsZSBlMSBlMiBlMykgZTQpIChmdW4gKChhLGIsYyksIGQpIC0+IChhLGIsYyxkKSlcblxubGV0IHR1cGxlNSBlMSBlMiBlMyBlNCBlNSA9IG1hcCAocGFpciAodHJpcGxlIGUxIGUyIGUzKSAocGFpciBlNCBlNSkpIChmdW4gKChhLGIsYyksIChkLGUpKSAtPiAoYSxiLGMsZCxlKSlcbmxldCB0dXBsZTYgZTEgZTIgZTMgZTQgZTUgZTYgPSBtYXAgKHBhaXIgKHRyaXBsZSBlMSBlMiBlMykgKHRyaXBsZSBlNCBlNSBlNikpIChmdW4gKChhLGIsYyksKGQsZSxmKSkgLT4gKGEsYixjLGQsZSxmKSlcblxuKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbigqICAgICAgICAgICAgICAgICAgICAgQlVJTFRJTlMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKVxuXG5sZXQgY2hhcl9wYXJ0ID1cbiAgeyBwX2NhcmRpbmFsID0gYm9pIDI1NiA7XG4gICAgY29tcHV0ZSA9IChmdW4gbiAtPiBDaGFyLmNociAoaW9iIG4pKSB9XG5cbigqIFVzdWFsIGNoYXJzOiBmcm9tIDMyIHRvIDEyNS4gKilcbmxldCB1c3VhbF9jaGFyX3BhcnQgPVxuICB7IHBfY2FyZGluYWwgPSBib2kgKDEyNSAtIDMyICsgMSkgO1xuICAgIGNvbXB1dGUgPSAoZnVuIG4gLT4gQ2hhci5jaHIgKDMyICsgaW9iIG4pKSB9XG5cbmxldCBlX3VuaXQgID0gZnJvbV9saXN0IH5uYW1lOlwiVW5pdFwiIFsgKCkgXVxubGV0IGVfYm9vbCAgPSBmcm9tX2xpc3Qgfm5hbWU6XCJCb29sXCIgW3RydWUgOyBmYWxzZV1cbmxldCBlX2NoYXIgID0gZnJvbV9zaW5nbGVfcGFydCAobGF6eSBcIkNoYXJcIikgY2hhcl9wYXJ0XG5sZXQgZV9wY2hhciA9IGZyb21fc2luZ2xlX3BhcnQgKGxhenkgXCJQcmludGFibGUtQ2hhclwiKSB1c3VhbF9jaGFyX3BhcnRcblxuKCogQmlnIGludHMgJiBpbnRzICopXG5sZXQgZV96ZXJvID0gZnJvbV9saXN0IH5uYW1lOlwiWmVyb1wiIFtiaWd6ZXJvXVxubGV0IGVfb25lID0gZnJvbV9saXN0IH5uYW1lOlwiT25lXCIgW2JpZ29uZV1cblxubGV0IGVfYmlncG9zID1cblxuICBsZXQgYmlnMm4gbiA9IG4gKysgbiBpblxuICBsZXQgYmlnMm5wMSBuID0gc3VjYyAoYmlnMm4gbikgaW5cbiAgXG4gIGxldCByZWMgZV9iaWdwb3MgPSBsYXp5ICh1bmlvbiBbZV9vbmUgOyBtYXAgKHBheSBlX2JpZ3BvcykgYmlnMm4gOyBtYXAgKHBheSBlX2JpZ3BvcykgYmlnMm5wMSBdKSBpblxuICBMYXp5LmZvcmNlIGVfYmlncG9zXG5cblxuXG5sZXQgZV9iaWduYXQgPSB1bmlvbiBbZV96ZXJvIDsgZV9iaWdwb3NdXG5cbmxldCBlX2JpZ25lZyA9IG1hcCBlX2JpZ3BvcyBtaW51c1xuXG5sZXQgZV9iaWdpbnQgPSB1bmlvbiBbZV96ZXJvIDsgZV9iaWduZWcgOyBlX2JpZ3Bvc11cblxubGV0IGJpZ2ludGVydmFsX3BhcnQgYSBiID1cbiAgeyBwX2NhcmRpbmFsID0gc3VjYyAoYiAtLSBhKSA7XG4gICAgY29tcHV0ZSA9IChmdW4gbiAtPiBhICsrIG4pIH1cblxubGV0IGVfYmlnaW50ZXJ2YWwgYSBiID0gZnJvbV9zaW5nbGVfcGFydCAobGF6eSAoUHJpbnRmLnNwcmludGYgXCJbJXMtJXNdXCIgKHNvYiBhKSAoc29iIGIpKSkgKGJpZ2ludGVydmFsX3BhcnQgYSBiKVxuXG5sZXQgaW50ZXJ2YWxfcGFydCBhIGIgPVxuICB7IHBfY2FyZGluYWwgPSBib2kgKGIgLSBhICsgMSkgO1xuICAgIGNvbXB1dGUgPSAoZnVuIG4gLT4gYSArIGlvYiBuKSB9XG5cbmxldCBlX2ludGVydmFsIGEgYiA9IGZyb21fc2luZ2xlX3BhcnQgKGxhenkgKFByaW50Zi5zcHJpbnRmIFwiWyVkLSVkXVwiIGEgYikpIChpbnRlcnZhbF9wYXJ0IGEgYilcblxubGV0IGJtYXhfaW50ID0gYm9pIG1heF9pbnRcblxubGV0IHRvaW50IGIgPSB0cnkgaW9iIChiaWdtb2QgYiBibWF4X2ludCkgd2l0aCBfIC0+IDBcblxubGV0IGVfbmF0ID0gbWFwIGVfYmlnbmF0IHRvaW50IFxubGV0IGVfcG9zID0gbWFwIGVfYmlncG9zIHRvaW50XG5sZXQgZV9uZWcgPSBtYXAgZV9iaWdwb3MgKGZ1biBiIC0+IC0gKHRvaW50IGIpKVxubGV0IGVfaW50ID0gdW5pb24gW3NpbmdsZSAwIDsgZV9wb3MgOyBlX25lZ11cbiAgICBcbigqIFN0cmluZ3MgKilcbmxldCBlX3N0cmluZ19mcm9tX2VjaGFyIGVudW1fY2hhcnMgPVxuICBsZXQgcmVjIGVudW0gPSBsYXp5ICggdW5pb24gWyBtYXAgZV91bml0IChmdW4gKCkgLT4gXCJcIikgOyBcblx0XHRcdFx0bWFwIChwYWlyIChtYXAgZW51bV9jaGFycyAoU3RyaW5nLm1ha2UgMSkpIChwYXkgZW51bSkpXG5cdFx0XHRcdCAgKGZ1biAoYSxiKSAtPiBhIF4gYikgXG5cdFx0XHQgICAgICBdIClcbiAgaW5cbiAgTGF6eS5mb3JjZSBlbnVtXG5cbmxldCBlX3N0cmluZyA9IGVfc3RyaW5nX2Zyb21fZWNoYXIgZV9wY2hhclxubGV0IGVfcnN0cmluZyBjaGFybGlzdCA9IGVfc3RyaW5nX2Zyb21fZWNoYXIgKGZyb21fbGlzdCB+bmFtZTpcIlRoZSBnaXZlbiBjaGFyc1wiIGNoYXJsaXN0KVxuXG5sZXQgZV9lbXB0eWxpc3QgKCkgPSBmcm9tX2xpc3Qgfm5hbWU6XCJFbXB0eWxpc3RcIiBbIFtdIF1cblxuKCogRW51bWVyYXRpb25zIG9mIGxpc3RzLiAqKVxubGV0IGVfbGlzdCBleGVuID1cbiAgbGV0IHJlYyBlbnVtID0gbGF6eSAodW5pb24gWyBlX2VtcHR5bGlzdCAoKSA7XG5cdFx0XHQgICAgICAgbWFwIChwYWlyIGV4ZW4gKHBheSBlbnVtKSlcblx0XHRcdFx0IChmdW4gKGEsYikgLT4gYSA6OiBiKVxuXHRcdFx0ICAgICBdIClcbiAgaW5cbiAgTGF6eS5mb3JjZSBlbnVtXG5cbmxldCBlX25lX2xpc3QgZXhlbiA9IG1hcCAocGFpciBleGVuIChlX2xpc3QgZXhlbikpIChmdW4gKGEsYikgLT4gYSA6OiBiKVxuICBcbigqIEVudW1lcmF0aW9ucyBvZiBhcnJheXMuICopXG5sZXQgZV9hcnJheSBleGVuID0gbWFwIChlX2xpc3QgZXhlbikgQXJyYXkub2ZfbGlzdFxuXG5sZXQgZV9vcHRpb24gZXhlbiA9IHVuaW9uIFtzaW5nbGUgTm9uZSA7IG1hcCBleGVuIChmdW4geCAtPiBTb21lIHgpXVxuXG5sZXQgYmlnc2hvdyBleGVuIHRvX3N0cmluZyBuMSBuMiA9XG4gIGZvciBpID0gMCB0byBuMiAtIDEgZG9cbiAgICBsZXQgaW5kZXggPSBuMSArKysgaSBpblxuICAgIFByaW50Zi5wcmludGYgXCJWYWx1ZSAjJWQgaXMgJXNcXG5cIiBpICh0b19zdHJpbmcgKGdldCBleGVuIGluZGV4KSkgO1xuICBkb25lIDtcbiAgKClcblxubGV0IHNob3cgZXhlbiB0b19zdHJpbmcgbjEgbjIgPSBiaWdzaG93IGV4ZW4gdG9fc3RyaW5nIChib2kgbjEpIG4yXG5cbmxldCB0ZXN0ZXIgZXhlbiA/ZnJvbSA/dXB0byA/dmVyYm9zZV9wZXJpb2QgP3RvcyB+bGVuIGYgPVxuICBUZXN0ZXIuZ2VuX3Rlc3RlciAoUHJpbnRmLnByaW50ZiBcIiVzJSFcIikgP3RvcyAoZnVuIGEgYiAtPiBpZ25vcmUoYSkgOyBiICgpKSAoKSBleGVuID9mcm9tID91cHRvID92ZXJib3NlX3BlcmlvZCB+bGVuIGZcblxuXG4iLCIoKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgVGhlIENvbXBjZXJ0IHZlcmlmaWVkIGNvbXBpbGVyICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICBYYXZpZXIgTGVyb3ksIElOUklBIFBhcmlzLVJvY3F1ZW5jb3VydCAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgQ29weXJpZ2h0IEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gICAgICopXG4oKiAgQXV0b21hdGlxdWUuICBBbGwgcmlnaHRzIHJlc2VydmVkLiAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkICAgICAgICopXG4oKiAgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgICAgICAgICopXG4oKiAgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDIuMSBvZiAgICopXG4oKiAgdGhlIExpY2Vuc2UsIG9yICAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLiAgICAgICAgICAgICAgICopXG4oKiAgVGhpcyBmaWxlIGlzIGFsc28gZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSAgICAgICAgICAgICAgICopXG4oKiAgSU5SSUEgTm9uLUNvbW1lcmNpYWwgTGljZW5zZSBBZ3JlZW1lbnQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICopXG4oKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopXG5cbmxldCBjYW1sc3RyaW5nX29mX2NvcXN0cmluZyAoczogY2hhciBsaXN0KSA9XG4gIGxldCByID0gQnl0ZXMuY3JlYXRlIChMaXN0Lmxlbmd0aCBzKSBpblxuICBsZXQgcmVjIGZpbGwgcG9zID0gZnVuY3Rpb25cbiAgfCBbXSAtPiByXG4gIHwgYyA6OiBzIC0+IEJ5dGVzLnNldCByIHBvcyBjOyBmaWxsIChwb3MgKyAxKSBzXG4gIGluIEJ5dGVzLnRvX3N0cmluZyAoZmlsbCAwIHMpXG5cblxubGV0IGNvcXN0cmluZ19vZl9jYW1sc3RyaW5nIHMgPVxuICBsZXQgcmVjIGNzdHJpbmcgYWNjdSBwb3MgPVxuICAgIGlmIHBvcyA8IDAgdGhlbiBhY2N1IGVsc2UgY3N0cmluZyAocy5bcG9zXSA6OiBhY2N1KSAocG9zIC0gMSlcbiAgaW4gY3N0cmluZyBbXSAoU3RyaW5nLmxlbmd0aCBzIC0gMSlcbiAgIiwib3BlbiBBbmdzdHJvbVxub3BlbiBVSU1MLkZvcm11bGFzXG5vcGVuIFVJTUwuRGF0YXR5cGVzXG5vcGVuIFN0cmluZ2NvbnZlcnNpb25cblxubGV0IGlzX3NwYWNlID1cbiAgZnVuY3Rpb24gfCAnICcgfCAnXFx0JyB8ICdcXG4nIC0+IHRydWUgfCBfIC0+IGZhbHNlXG5cbmxldCBzcGFjZXMgPSBza2lwX3doaWxlIGlzX3NwYWNlXG5cbmxldCBwYXJlbnMgcCA9IGNoYXIgJygnICo+IHAgPCogY2hhciAnKSdcblxubGV0IGJveCBwID0gKChjaGFyICdbJyAqPiBjaGFyICddJykgPHw+IChjaGFyICdcXHhFMicgKj4gY2hhciAnXFx4OTYnICo+IGNoYXIgJ1xceEExJykpICo+IHNwYWNlcyAqPiBwXG4gID4+fCBmdW4geCAtPiBCb3ggeFxubGV0IGRpYW1vbmQgcCA9ICgoY2hhciAnPCcgKj4gY2hhciAnPicpIDx8PiAoY2hhciAnXFx4RTInICo+IGNoYXIgJ1xceDhCJyAqPiBjaGFyICdcXHg4NCcpKSAqPiBzcGFjZXMgKj4gcFxuICA+PnwgZnVuIHggLT4gSW1wbGllcyAoQm94IChJbXBsaWVzKHgsIEJvdCkpLCBCb3QpXG5cbmxldCBuZWcgcCA9ICgoY2hhciAnficpIDx8PiAoY2hhciAnXFx4QzInICo+IGNoYXIgJ1xceEFDJykpICo+IHNwYWNlcyAqPiBwXG4gID4+fCBmdW4geCAtPiBJbXBsaWVzKHgsIEJvdClcblxubGV0IGRpc2ogPSBzcGFjZXMgKj4gKChjaGFyICdcXHhFMicgKj4gY2hhciAnXFx4ODgnICo+IGNoYXIgJ1xceEE4JykgPHw+IGNoYXIgJ3wnKSAqPiBzcGFjZXMgKj4gIHJldHVybiAoZnVuIHggeSAtPiBPcih4LCB5KSlcbmxldCBjb25qID0gc3BhY2VzICo+ICgoY2hhciAnXFx4RTInICo+IGNoYXIgJ1xceDg4JyAqPiBjaGFyICdcXHhBNycpIDx8PiBjaGFyICcmJykgKj4gc3BhY2VzICo+IHJldHVybiAoZnVuIHggeSAtPiBBbmQgKHgsIHkpKVxuXG5sZXQgbW9kYWwgKHAgOiBmb3JtIHQpIDogZm9ybSB0ID0gYm94IHAgPHw+IG5lZyBwIDx8PiBkaWFtb25kIHBcbmxldCBpbXBsID0gc3BhY2VzICo+ICgoY2hhciAnXFx4RTInICo+IGNoYXIgJ1xceDg2JyAqPiBjaGFyICdcXHg5MicpIDx8PiAoY2hhciAnLScgKj4gY2hhciAnPicpKSAqPiBzcGFjZXMgKj4gcmV0dXJuIChmdW4geCB5IC0+IEltcGxpZXMoeCwgeSkpXG5cbigqIHRoaXMgaXMg4oqlICopXG5sZXQgYm90ID0gc3BhY2VzICo+ICgoY2hhciAnXFx4RTInICo+IGNoYXIgJ1xceDhBJyAqPiBjaGFyICdcXHhBNScpIDx8PiBjaGFyICcjJ1xuICAgICAgICAgICAgICAgICAgICAgPHw+IGNoYXIgJ0YnKSAqPiBzcGFjZXMgKj4gcmV0dXJuIChCb3QpXG5sZXQgdG9wID0gc3BhY2VzICo+ICgoY2hhciAnXFx4RTInICo+IGNoYXIgJ1xceDhBJyAqPiBjaGFyICdcXHhBNCcpIDx8PiBjaGFyICdUJykgKj4gc3BhY2VzICo+IHJldHVybiAoSW1wbGllcyhCb3QsQm90KSlcblxuXG5sZXQgbGV0dGVyID0gZnVuY3Rpb24gfCAnYScgLi4gJ3onIC0+IHRydWUgfCBfIC0+IGZhbHNlXG5sZXQgbGV0dGVyX29yX2RpZ2l0ID0gZnVuY3Rpb24gfCAnYScgLi4gJ3onIHwgJ0EnIC4uICdaJyB8ICcwJyAuLiAnOScgLT4gdHJ1ZSB8IF8gLT4gZmFsc2VcblxubGV0IGlkZW50aWZpZXIgPSBsaWZ0MiAoXikgKHRha2Vfd2hpbGUxIGxldHRlcikgKHRha2Vfd2hpbGUgbGV0dGVyX29yX2RpZ2l0KSA+PnwgZnVuIHggLT4gVmFyIChjb3FzdHJpbmdfb2ZfY2FtbHN0cmluZyB4KVxuXG4oKiBjaGFpbiBvZiBsZWZ0LWFzc29jaWF0aXZlIG9wZXJhdGlvbnMgKilcbmxldCBjaGFpbmwxIGUgb3AgPVxuICBsZXQgcmVjIGdvIGFjYyA9XG4gICAgKGxpZnQyIChmdW4gZiB4IC0+IGYgYWNjIHgpIG9wIGUgPj49IGdvKSA8fD4gcmV0dXJuIGFjYyBpblxuICBlID4+PSBmdW4gaW5pdCAtPiBnbyBpbml0XG5cbiAgbGV0IGNoYWlucjEgZSBvcCA9XG4gICAgbGV0IHJlYyBnbyBhY2MgPVxuICAgICAgKGxpZnQyIChmdW4gZiB4IC0+IGYgYWNjIHgpIG9wIChlID4+PSBnbykpIDx8PiByZXR1cm4gYWNjIGluXG4gICAgZSA+Pj0gZ29cblxubGV0IGNoYWlubW9kIChlIDogJ2EgdCkgKG9wIDogJ2EgdCAtPiAnYSB0KSA6ICdhIHQgPVxuICBmaXggKGZ1biB4IC0+IG9wIHggPHw+IGUpXG5cbiAgKCpcbiAgbGV0IHJlYyBnbyAoYWNjIDogJ2EpID0gbGlmdCAoZnVuIGYgLT4gZiBhY2MpIG9wICAqPiAoZSA+Pj0gZ28pIDx8PiByZXR1cm4gYWNjIGluIGUgPj49IGdvXG4gICopXG4gICAgKCpcbiAgcCDigJhjaGFpbnIx4oCYIG9wID1cbiAgcCDigJhiaW5k4oCYIFxceCAtPlxuICBbZiB4IHkgfCBmIDwtIG9wLCB5IDwtIHAg4oCYY2hhaW5yMeKAmCBvcF0gKysgW3hdXG4qKVxubGV0IGV4cHIgOiBmb3JtIHQgPVxuICBmaXggKGZ1biBleHByIC0+XG4gICAgbGV0IGZhY3RvciA9IHBhcmVucyBleHByIDx8PiBpZGVudGlmaWVyIDx8PiBib3QgPHw+IHRvcCBpblxuICAgIGxldCBtb2RhbGl0eSA9IGNoYWlubW9kIGZhY3RvciBtb2RhbCAgaW5cbiAgICBsZXQgdGVybSAgID0gY2hhaW5sMSBtb2RhbGl0eSBjb25qIGluXG4gICAgbGV0IGRpc2p1bmN0aW9ucyA9IHNwYWNlcyAqPiBjaGFpbmwxIHRlcm0gZGlzaiA8KiBzcGFjZXMgaW5cbiAgICBzcGFjZXMgKj4gY2hhaW5yMSBkaXNqdW5jdGlvbnMgaW1wbCA8KiBzcGFjZXNcbiAgICApXG5cbmV4Y2VwdGlvbiBQYXJzZUVycm9yXG5sZXQgZXZhbCAoc3RyOnN0cmluZykgOiBmb3JtID1cbiAgbWF0Y2ggcGFyc2Vfc3RyaW5nIH5jb25zdW1lOkFsbCBleHByIHN0ciB3aXRoXG4gIHwgT2sgdiAgICAgIC0+IHZcbiAgfCBFcnJvciBfIC0+IHJhaXNlIFBhcnNlRXJyb3I7O1xuIiwib3BlbiBVSU1MLkZvcm11bGFzXG5vcGVuIFN0cmluZ2NvbnZlcnNpb25cbm9wZW4gVUlNTC5EYXRhdHlwZXNcblxubGV0IHJlYyBpbnRfb2ZfbmF0ID0gZnVuY3Rpb25cbnwgTyAtPiAwXG58IFMgbiAtPiAxICsgaW50X29mX25hdCBuXG5cblxubGV0IHN0cmluZ19vZl9mb3JtdWxhID8oY2xhc3NpY2FsID0gZmFsc2UpID1cbiAgbGV0IHJlYyBzdHJpbmdfb2ZfZm9ybXVsYSA9XG4gIGZ1bmN0aW9uXG58IFZhciB2IC0+IGNhbWxzdHJpbmdfb2ZfY29xc3RyaW5nIHZcbnwgQm90IC0+IFwi4oqlXCJcbnwgSW1wbGllcyhCb3QsIEJvdCkgLT4gXCLiiqRcIlxuKCogZGlhbW9uZCAqKVxufCBJbXBsaWVzKEJveChJbXBsaWVzKGYsIEJvdCkpLEJvdCkgd2hlbiBjbGFzc2ljYWwgLT4gXCLii4QgXCIgXiBicmFja2V0IGZcbigqIGRvdWJsZSBuZWdhdGlvbiAqKVxufCBJbXBsaWVzKEltcGxpZXMoZiwgQm90KSwgQm90KSB3aGVuIGNsYXNzaWNhbCAtPiBzdHJpbmdfb2ZfZm9ybXVsYSBmXG58IEJveCBmIC0+IFwi4pahIFwiIF4gYnJhY2tldCBmXG58IEFuZCAoZiwgZykgLT4gYnJhY2tldCBmIF4gXCIg4oinIFwiIF4gYnJhY2tldCBnXG58IE9yIChmLCBnKSAtPiBicmFja2V0IGYgXiBcIiDiiKggXCIgXiBicmFja2V0IGdcbnwgSW1wbGllcyAoZiwgQm90KSAtPiBcIsKsIFwiIF4gYnJhY2tldCBmICgqIHByZXR0eSBwcmludCDCrCAqKVxufCBJbXBsaWVzIChmLCBnKSAtPiBicmFja2V0IGYgXiBcIiDihpIgXCIgXiBicmFja2V0IGdcbmFuZCBicmFja2V0IGUgPSBtYXRjaCBlIHdpdGhcbnwgSW1wbGllcyhJbXBsaWVzKGYsIEJvdCksIEJvdCkgd2hlbiBjbGFzc2ljYWwgLT4gYnJhY2tldCBmXG58IEltcGxpZXMoQm94KEltcGxpZXMoZiwgQm90KSksQm90KSB3aGVuIGNsYXNzaWNhbCAtPiBcIuKLhCBcIiBeIGJyYWNrZXQgZlxufCBWYXIgXyB8IEJvdCB8IEltcGxpZXMoXywgQm90KSB8IEJveCBfIC0+IHN0cmluZ19vZl9mb3JtdWxhIGVcbnwgZSAtPiBcIihcIiBeIHN0cmluZ19vZl9mb3JtdWxhIGUgXiBcIilcIlxuICBpbiBzdHJpbmdfb2ZfZm9ybXVsYSIsIm9wZW4gVUlNTC5VSU1MX2V4dHJhY3Rpb25cbm9wZW4gVUlNTC5Gb3JtdWxhc1xub3BlbiBKc19vZl9vY2FtbFxub3BlbiBNb2RhbF9leHByZXNzaW9uc19wYXJzZXJcbm9wZW4gU3RyaW5nY29udmVyc2lvblxub3BlbiBQcmludGVyXG5cbmxldCBjYXRjaF9lIGYgPSB0cnkgZigpIHdpdGhcbiAgUGFyc2VFcnJvciAtPiBcIlBhcnNlIEVycm9yXCJcbnwgRmFpbHVyZSBzIC0+IFwiRXJyb3I6IFwiIF4gc1xufCBlIC0+IFwiRXJyb3I6IFwiIF4gUHJpbnRleGMudG9fc3RyaW5nIGVcblxubGV0IGZhaWxfb25fbW9kYWxpdHkgKGYgOiBmb3JtKSA6IGZvcm0gPVxuICBsZXQgcmVjIGF1eCA9IGZ1bmN0aW9uXG4gIHwgQm94IF8gLT4gZmFpbHdpdGggXCJUaGUgcHJvdmlkZWQgZm9ybXVsYSBjb250YWlucyBtb2RhbGl0aWVzXCJcbiAgfCBPcih4LCB5KSB8IEltcGxpZXMoeCwgeSkgfCBBbmQoeCwgeSkgLT4gYXV4IHggOyBhdXggeVxuICB8IF8gLT4gKClcbiAgaW4gKGF1eCBmOyBmKVxuXG4oKiBleHBvcnQgZnVuY3Rpb25zIHRvIGpzICopXG5cbmxldCB2IDogdmFyaWFibGUgPSBjb3FzdHJpbmdfb2ZfY2FtbHN0cmluZyBcInBcIlxubGV0IF8gPVxuICBKcy5leHBvcnQgXCJVSU1MXCJcbiAgICAob2JqZWN0JWpzXG4oKiBUT0RPOiBpRSBhbmQgaUEgYXJlIGp1c3QgYW4gYWxpYXMgZm9yIGlzbF9FIGFuZCBpc2xfQSxcbnRoZXJlIHNob3VsZCByZWFsbHkgYXQgbGVhc3QgYmUgYSBmdW5jdGlvbiB0aGF0IGNoZWNrcyB0aGF0XG5pRSBhbmQgaUEgYXJlIGdpdmVuIGJveC1mcmVlIGZvcm11bGFzIGFzIGlucHV0LiopXG4gICAgICAgbWV0aG9kIGlBIHMgPSAgY2F0Y2hfZSAoZnVuICgpIC0+IHMgfD4gZXZhbCB8PiBmYWlsX29uX21vZGFsaXR5IHw+IGlzbF9BIHYgfD4gc3RyaW5nX29mX2Zvcm11bGEpXG4gICAgICAgbWV0aG9kIGlFIHMgPSAgY2F0Y2hfZSAoZnVuICgpIC0+IHMgfD4gZXZhbCB8PiBmYWlsX29uX21vZGFsaXR5IHw+IGlzbF9FIHYgfD4gc3RyaW5nX29mX2Zvcm11bGEpXG4gICAgICAgbWV0aG9kIGlzbEEgcyA9IGNhdGNoX2UgKGZ1biAoKSAtPiBzIHw+IGV2YWwgfD4gaXNsX3NpbXBsaWZpZWRfQSB2IHw+IHN0cmluZ19vZl9mb3JtdWxhKVxuICAgICAgIG1ldGhvZCBpc2xFIHMgPSBjYXRjaF9lIChmdW4gKCkgLT4gcyB8PiBldmFsIHw+IGlzbF9zaW1wbGlmaWVkX0UgdiB8PiBzdHJpbmdfb2ZfZm9ybXVsYSlcbiAgICAgICBtZXRob2QgayBzID0gY2F0Y2hfZSAoZnVuICgpIC0+IHMgfD4gZXZhbCB8PiBnbF9VSSB2IHw+IHN0cmluZ19vZl9mb3JtdWxhIH5jbGFzc2ljYWw6IHRydWUpXG4gICAgICAgbWV0aG9kIGdsIHMgPSBjYXRjaF9lIChmdW4gKCkgLT4gcyB8PiBldmFsIHw+IGtfVUkgdiB8PiBzdHJpbmdfb2ZfZm9ybXVsYSB+Y2xhc3NpY2FsOiB0cnVlKVxuICAgICAgIG1ldGhvZCBwYXJzZSBzID0gY2F0Y2hfZSAoZnVuICgpIC0+IHMgfD4gZXZhbCB8PiBzdHJpbmdfb2ZfZm9ybXVsYSlcbiAgICAgZW5kKTs7XG5cbiIsIigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0NhbWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgIFhhdmllciBMZXJveSwgcHJvamV0IENyaXN0YWwsIElOUklBIFJvY3F1ZW5jb3VydCAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQ29weXJpZ2h0IDE5OTYgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCAgICAgKilcbigqICAgICBlbiBBdXRvbWF0aXF1ZS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqICAgQWxsIHJpZ2h0cyByZXNlcnZlZC4gIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgICAgKilcbigqICAgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIuMSwgd2l0aCB0aGUgICAgICAgICAgKilcbigqICAgc3BlY2lhbCBleGNlcHRpb24gb24gbGlua2luZyBkZXNjcmliZWQgaW4gdGhlIGZpbGUgTElDRU5TRS4gICAgICAgICAgKilcbigqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKilcbigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKilcblxuKCogRW5zdXJlIHRoYXQgW2F0X2V4aXRdIGZ1bmN0aW9ucyBhcmUgY2FsbGVkIGF0IHRoZSBlbmQgb2YgZXZlcnkgcHJvZ3JhbSAqKVxuXG5sZXQgXyA9IGRvX2F0X2V4aXQoKVxuIl19