(**************Interfacer avec le terminal******1************)
type joueur
= { prenom
: string ; mutable credit
: int ; mutable nbre_batailles_gagnees
: int } ;;
(**************Avant de jouer ...****************************)
type couleur = Coeur | Carreau | Trefle | Pique;;
type carte
= C
of int * couleur
;; let c = C( 10 ,Coeur) ;;
let nc = C( 15 ,Carreau) ;;
let valide carte =
let C( n,c) = carte in ( n > 0 ) && ( n < 14 )
;;
valide c;;
valide nc;;
let string_of_couleur = function
| Coeur -> "Coeur"
| Carreau -> "Carreau"
| Trefle -> "Trefle"
| Pique -> "Pique"
;;
string_of_couleur Trefle;;
let string_of_num = function
| 1 -> "As de"
| 11 -> "Valet de"
| 12 -> "Dame de"
| 13 -> "Roi de"
;;
string_of_num 6 ;;
string_of_num 12 ;;
let rec affiche_liste_cartes cl =
let rec aux = function
| [ ] -> "Il n'y a pas de cartes."
| h:: t when not ( valide h) -> failwith "Ce ne sont pas des cartes !"
| [ x] (*Fin de l'affichage*) -> let C( n,c) = x in
( string_of_num n) ^ " " ^ ( string_of_couleur c) ^ "."
| h:: t (*La première carte est valide*) -> let C( n,c) = h in
( string_of_num n) ^ " " ^ ( string_of_couleur c)
^ ", " ^ ( aux t)
in
;;
let lcv = [ ] ;;
let lc = [ C( 1 ,Coeur) ; C( 10 ,Pique) ; C( 13 ,Trefle) ] ;;
(*affiche_liste_cartes lcv;;
affiche_liste_cartes lc;;*)
let genere_jeu ( ) =
let rec aux n l =
match n with
| 0 -> l
| m when ( m > 0 ) && ( m < 14 ) -> aux ( m- 1 ) ( C( m,Coeur) :: l)
| m when ( m > 13 ) && ( m < 27 ) -> aux ( m- 1 ) ( C( m- 13 ,Carreau) :: l)
| m when ( m > 26 ) && ( m < 40 ) -> aux ( m- 1 ) ( C( m- 26 ,Trefle) :: l)
| m when ( m > 39 ) && ( m < 53 ) -> aux ( m- 1 ) ( C( m- 39 ,Pique) :: l)
| m -> failwith "Probleme dans la fonction aux de genere_jeu"
in
aux 52 [ ]
;;
genere_jeu( ) ;;
let rec genere_mini_jeu = function
| m when m < 14 -> C( m,Coeur) :: C( m,Pique) :: ( genere_mini_jeu ( m+ 1 ) )
| _ -> [ ]
;;
genere_mini_jeu 13 ;;
genere_mini_jeu 5 ;;
let rec liste_nth n l = (*Fonction auxiliaire à mélanger : permet de prendre un élèment de numéro donné dans la liste et renvoie l'élement et la liste restante.*)
match l with
| [ ] -> failwith "liste vide"
| h:: t -> match n with
| 0 -> h,t
| _ -> let e,r = liste_nth ( n- 1 ) t in e,h:: r
;;
(*On crée une nouvelle liste ; on prend un élement aléatoire dans la première,
on l'ajoute à la nouvelle liste tout en le supprimant de la première.*)
let melanger
( cl
: carte
list ) : carte
list = let rec aux l1 l2 =
match l1 with
| [ ] -> l2
let e,r = liste_nth n l1 in
aux r ( e:: l2)
in
aux cl [ ]
;;
lc;;
melanger lc;;
let rec distribue
( cl
: carte
list ) : carte
list * carte
list = match cl with
| [ ] -> [ ] ,[ ]
| [ x] -> [ x] ,[ ]
| h1:: h2:: t -> let l1,l2 = distribue t in h1:: l1,h2:: l2
;;
lc;;
distribue [ ] ;;
distribue [ C( 1 ,Coeur) ] ;;
distribue lc;;
match n,cl with
| 0 ,[ ] -> [ ] ,[ ]
| _,[ ] -> failwith "Il n'y a pas assez de cartes dans la pioche !"
| 0 ,l -> [ ] ,l
| n,h:: t -> let p,pr = piocher ( n- 1 ) t in h:: p,pr
;;
lc;;
piocher 0 lc;;
piocher 0 [ ] ;;
piocher 1 lc;;
piocher 3 lc;;
(*piocher 4 lc;;*)
let rec empiler_cartes
( mc
: carte
list ) ( t
: carte
list ) : carte
list = match t with
| [ ] -> mc
| h:: tl -> h:: ( empiler_cartes mc tl)
;;
lc;;
empiler_cartes lc [ C( 7 ,Carreau) ] ;;
empiler_cartes [ C( 7 ,Carreau) ; C( 8 ,Carreau) ] lc;;
(*****************************Blackjack************************************)
type plateau_blackjack
= carte
list (*Cartes du joueur*) * carte
list (*Cartes de la banque*) * carte
list (*Pioche*) ;;
let creer_blackjack ( ) : plateau_blackjack = [ ] ,[ ] ,melanger ( genere_jeu( ) ) ;;
let p = creer_blackjack( ) ;;
let banque_pioche
( n
: int ) ( p
: plateau_blackjack
) : plateau_blackjack
= let cj,cb,pi = p in
let o,r = piocher n pi in
cj,o@cb,r
;;
banque_pioche 0 p = p;;
banque_pioche 52 p;;
let joueur_pioche
( n
: int ) ( p
: plateau_blackjack
) : plateau_blackjack
= let cj,cb,pi = p in
let o,r = piocher n pi in
o@cj,cb,r
;;
joueur_pioche 0 p = p;;
joueur_pioche 52 p;;
let valeur = function
| 11 | 12 | 13 -> 10
| k -> k
;;
valeur 12 ;;
valeur 9 ;;
let rec total_cartes cl =
match cl with
| [ ] -> 0
| h:: t -> let C( k,c) = h in
( valeur k) + total_cartes t
;;
lc;;
total_cartes lc;;
let faire_jouer_banque p =
let rec aux t pl =
match t with
| n when n < 17 -> ( let cj,cb,pi = banque_pioche 1 pl in
match cb with
| [ ] -> failwith "Probleme de pioche."
| C( k,c) :: ta -> aux ( n+ ( valeur k) ) ( cj,cb,pi) )
| _ -> pl
in
let pj,pb,ppi = p in
let n = total_cartes pb in
aux n p
;;
let pm = let j,b,pi = p in j,b,melanger pi;;
faire_jouer_banque pm;;
let afficher_jeu ( p : plateau_blackjack) =
let cj,cb,pi = p in
affiche_liste_cartes cj;
affiche_liste_cartes cb;
;;
(*affiche_jeu pm;;*)
let faire_jouer_joueur p = (*A FAIRE : rattraper l'exception int_of_string*)
let rec aux k pl =
match k with
| 2 -> pl
| 1 -> ( let pn = joueur_pioche 1 pl in
afficher_jeu pn;
aux l pn)
| _
-> ( print_endline "Ceci n'est pas une maniere de jouer acceptable. Voulez-vous piocher une carte ?" ; aux l pl)
in
afficher_jeu p;
aux m p
;;
(*faire_jouer_joueur pm;;*)
let jouer_blackjack j =
let p = creer_blackjack( ) in
let pb = banque_pioche 1 p in
let pj = joueur_pioche 2 pb in
let pl_en_jeu = faire_jouer_joueur pj in
let cj,cb,pi = pl_en_jeu in
let tj = total_cartes cj in
match tj with
| _ -> let pb_en_jeu = faire_jouer_banque pl_en_jeu in
let pj,pb,ppi = pb_en_jeu in
let tb = total_cartes pb in
( match tb with
| n when ( n > 21 ) || ( n < tj) ->
( j. credit <- j. credit+ 1 ;
| n when n > tj ->
)
;;
(*L'égalité n'est pas une réussite.*)
let j = { prenom = "J" ; credit = 0 ; nbre_batailles_gagnees = 0 } ;;
(*jouer_blackjack j;;*)
(*******************************Menteur*******************************)
let jO1 = { prenom = "Or1" ; credit = 0 ; nbre_batailles_gagnees = 0 } ;;
let jO2 = { prenom = "Or2" ; credit = 0 ; nbre_batailles_gagnees = 0 } ;;
let jO3 = { prenom = "Or3" ; credit = 0 ; nbre_batailles_gagnees = 0 } ;;
(*Jeu du menteur : HOW TO, WHAT TO :
On a besoin des 4 tas de cartes ; on voudrait qu'ils soient triés par couleur.
-> FONCTION de tri par couleur. DONE
On a besoin de savoir quel est la couleur annoncée par le 1er joueur.
On a besoin de savoir la carte posée sur la table. -> liste soit vide, soit
composée d'un seul élément.
*)
type table_menteur = (*Pile J, Pile o1, Pile o2, Pile o3, couleur annoncée,
Carte posée sur la table *)
(*carte list pour le dernier champ pour pouvoir initialiser en liste vide.??*)
(*
let rec tri_1carte_couleur c l =(*insérer une carte d'une couleur donée dans une
liste de cartes triées par couleurs.*)
let C(r1,t1) = c in
match l with
|[] -> [c]
|h::ta -> let C(r2,t2) = h in
if t1 = t2 then c::l
else h::(tri_1carte_couleur c ta)
;;
lc;;
tri_1carte_couleur (C(2,Coeur)) lc;;
tri_1carte_couleur (C(2,Pique)) lc;;
tri_1carte_couleur (C(2,Trefle)) lc;;
let tri_couleur cl =
let rec aux l1 l2 =
match l1 with
|[] -> l2
|h::t -> aux t (tri_1carte_couleur h l2)
in
aux cl []
;;
let lct = genere_mini_jeu 10;;
let lctm = melanger lct;;
tri_couleur lctm;;
*)
let color c =
let C( r,t) = c in t;;
color ( C( 10 ,Trefle) ) ;;
let rec compte_couleurs = function
| [ ] -> ( 0 ,0 ,0 ,0 )
| h:: t when ( color h) = Coeur -> let ( a,b,c,d) = compte_couleurs t in
( 1 + a,b,c,d)
| h:: t when ( color h) = Carreau -> let ( a,b,c,d) = compte_couleurs t in
( a,1 + b,c,d)
| h:: t when ( color h) = Trefle -> let ( a,b,c,d) = compte_couleurs t in
( a,b,1 + c,d)
| h:: t (*when (color h) = Pique*) -> let ( a,b,c,d) = compte_couleurs t in
( a,b,c,1 + d)
;;
let rec inna_nb_cartes l couleur= match l with
[ ] -> 0
| h:: tl -> match h with
C( _,clr) when clr= couleur -> 1 + ( inna_nb_cartes tl couleur)
| _ -> inna_nb_cartes tl couleur;;
(* inna_affiche_pile_selon_couleur pile couleur l Pique ->(2,20) veut dire "2 Piques, 20 non-Piques" *)
let inna_affiche_table_menteur tm
= let ( j,o1,o2,o3,cl,c
) = tm
in inna_affiche_pile_selon_couleur j cl
; inna_affiche_pile_selon_couleur o1 cl
; inna_affiche_pile_selon_couleur o2 cl
; inna_affiche_pile_selon_couleur o3 cl
; print_newline ( ) ;;
let lct = genere_mini_jeu 10 ;;
let lctm = melanger lct;;
lctm;;
compte_couleurs lctm;;
let creer_menteur ( ) : table_menteur =
let jeu = genere_jeu ( ) in
let jeu_m = melanger jeu in
let t1,t2 = distribue jeu_m in
let j1,j2 = distribue t1 and j3,j4 = distribue t2 in
( j1,j2,j3,j4,Pique,[ ] ) ;; (*Initialisation arbitraire de la couleur.*)
creer_menteur( ) ;;
let rec choisir cl c = (*choisir une carte de la couleur donnée, ou n'importe quelle autre carte sinon : nécessaire pour faire jouer l'ordinateur*)
(*let col = color c in*)
match cl with
| [ ] -> failwith "Il n'y a pas de cartes !"
| [ x] -> x,[ ]
| C( r,t) :: ta when t = c -> ( C( r,t) ) ,ta
| h:: ta -> let f,s = choisir ta c in f,h:: s
;; (*A REPRENDRE*)
lc;;
choisir lc Carreau;;
let next = function
| 0 -> 1
| 1 -> 2
| 2 -> 3
| 3 -> 0
| _ -> failwith "Ceci n'est pas un joueur existant"
;;
let prec = function
| 0 -> 3
| 1 -> 0
| 2 -> 1
| 3 -> 2
| _ -> failwith "Ceci n'est pas un joueur existant"
;;
let jouer_ordinateur_pose n ( tm : table_menteur) : table_menteur =
let ( j,o1,o2,o3,c,cl) = tm in
match n with
| 1 -> let carte,reste = choisir o1 c in
j,reste,o2,o3,c,carte:: cl
| 2 -> let carte,reste = choisir o2 c in
j,o1,reste,o3,c,carte:: cl
| 3 -> let carte,reste = choisir o3 c in
j,o1,o2,reste,c,carte:: cl
| _ -> failwith "Ce joueur n'existe pas."
;;
let jouer_ordinateur_pose1 n ( tm : table_menteur) : table_menteur =
let ( j,o1,o2,o3,c,cl) = tm in
match num_couleur with
| 0 -> jouer_ordinateur_pose n ( j,o1,o2,o3,Coeur,cl)
| 1 -> jouer_ordinateur_pose n ( j,o1,o2,o3,Carreau,cl)
| 2 -> jouer_ordinateur_pose n ( j,o1,o2,o3,Trefle,cl)
| _ -> jouer_ordinateur_pose n ( j,o1,o2,o3,Pique,cl)
;;
(*Déroulement du jeu :
Le premier joueur donne une couleur.
Stratégie des ordinateurs : Stratégie 1 : mettre une carte de la couleur annoncée
jusqu'à ce qu'il n'y en ait plus, puis mettre n'importe quelle carte.
Stratégie 2 : accuser le joueur précédent. Proba d'1/2 de choix de l'une ou l'autre.
Joueur : 1. S'il est le premier à jouer : demander une couleur. 2. S'il n'est pas
le premier, demander une carte ou une accusation.*)
(*
let be_of_color co ca =
let C(r,t) = ca in co = t;;
be_of_color Trefle (C(3,Trefle));;
be_of_color Trefle (C(3,Coeur));;
let rec list_find p l =
match l with
|[] -> raise Not_found
|h::t -> if (p h) then h,t
else let m,r = list_find p t in
m,h::r
;;
list_find (be_of_color Coeur) lc;;
let jouer_pile c p =
if List.exists (be_of_color c) p then
list_find (be_of_color c) p
else match p with
|[] -> failwith "Il n'y a plus de cartes ; il y a du y avoir une erreur !"
|h::t -> h,t
;;
lc;;
(*jouer_pile Coeur [];;*)
jouer_pile Carreau lc;;
let rec list_nth n l =
match l with
|[] -> failwith "La liste est trop courte"
|h::t -> match n with
|0 -> h,t
|_ -> let e,r = list_nth (n-1) t in e,h::r
;;
let choisir_couleur p =
Random.self_init ();
match p with
|[] -> failwith "Il n'y a plus de cartes ; il y a du y avoir une erreur !"
|h::ta -> let n = List.length p in
let m = Random.int n in
let (C(r,t),reste) = liste_nth m p in t,reste
;;
choisir_couleur lc;;*)
let recupere_cartes ( tm : table_menteur) n : table_menteur=
let ( j,o1,o2,o3,c,cl) = tm in
match n with
| 0 -> ( empiler_cartes cl j,o1,o2,o3,c,[ ] )
| 1 -> ( j,empiler_cartes cl o1,o2,o3,c,[ ] )
| 2 -> ( j,o1,empiler_cartes cl o2,o3,c,[ ] )
| 3 -> ( j,o1,o2,empiler_cartes cl o3,c,[ ] )
| _ -> failwith "Joueur inexistant"
;;
let jouer_ordinateur_accusateur n ( tm : table_menteur) =
match tm with
| _,_,_,_,c,[ ] -> failwith "Ordre du joueur"
| _,_,_,_,c,
( C
( r,t
) ) :: ta
when c
= t
-> print_endline "L'accusateur a perdu. Il recupere toutes les cartes." ; recupere_cartes tm n,( prec n)
| _
-> print_endline "L'accusateur a gagne. Le joueur accuse recupere toutes les cartes." ; recupere_cartes tm ( prec n) ,n
;;
let jouer_ordinateur o(*ordre du joueur*) n(*numéro de l'ordinateur*)
( tm
: table_menteur
) : table_menteur
* int = match o with
| 1 -> jouer_ordinateur_pose1 n tm,4
match x with
| 0 -> jouer_ordinateur_pose n tm,4
jouer_ordinateur_accusateur n tm)
| _ -> failwith "La partie est déjà finie !"
;;
(*Faire jouer le joueur : on lui dit combien de cartes de chaque couleur il a.
Il suffit donc qu'il dise la couleur de la carte qu'il veut jouer pour jouer.*)
let rec couleur_of_string s =
match s with
| "Coeur" -> Coeur
| "Carreau" -> Carreau
| "Trefle" -> Trefle
| "Pique" -> Pique
| _
-> print_endline "Ceci n'est pas une couleur. Choisissez une couleur, s'il vous plait !" ; ;;
let rec selectionner_carte_existante c lc =
match lc with
| [ ] -> failwith "Pas de carte de cette couleur !"
| ( C( r,t) ) :: ta when t = c -> ( C( r,t) ) ,ta
| h:: t -> let carte,reste = selectionner_carte_existante c t in carte,h:: reste
;;
lc;;
let rec selectionner_carte c lc =
try ( selectionner_carte_existante c lc) with
| Failure "Pas de carte de cette couleur !" -> print_endline "Vous n'avez pas de cartes de cette couleur. Choisissez une autre couleur, s'il vous plait !" ; selectionner_carte ( couleur_of_string s) lc
;;
(*selectionner_carte (couleur_of_string "Carreau") lc;;*)
let affiche_main ( tm : table_menteur) =
let ( j,o1,o2,o3,c,cd) = tm in
let ( co,ca,t,p) = compte_couleurs j in
;;
lc;;
(*affiche_main (lc,[],[],[],Trefle,[]);;*)
let jouer_joueur_poser ( tm : table_menteur) : table_menteur =
let ( j,o1,o2,o3,c,cd) = tm in
let nc = couleur_of_string s in
let carte,nj = selectionner_carte nc j in
( nj,o1,o2,o3,nc,carte:: cd)
;;
let jouer_joueur_poser1 ( tm : table_menteur) : table_menteur =
let ( j,o1,o2,o3,c,cd) = tm in
print_endline "Choisissez une couleur a annoncer, s'il vous plait." ; let nc = couleur_of_string s in
jouer_joueur_poser ( j,o1,o2,o3,nc,cd)
;;
let affiche_carte c =
let C( r,t) = c in
;;
(*affiche_carte (C(13,Pique));;*)
let jouer_joueur_accuser
( tm
: table_menteur
) : table_menteur
* int (*_,g*) = match tm with
| _,_,_,_,c,[ ] -> failwith "Ordre du joueur"
| _,_,_,_,c,
( C
( r,t
) ) :: ta
when c
= t
-> print_string "Vous avez menti ! La carte posee etait " ; affiche_carte ( C( r,t) ) ;
recupere_cartes tm 0 ,3
| _,_,_,_,c,
( C
( r,t
) ) :: ta
-> print_string "Vous avez gagne ! La carte posee etait " ; affiche_carte ( C( r,t) ) ;
recupere_cartes tm 3 ,0
;;
let jouer_joueur o
( tm
: table_menteur
) : table_menteur
* int = let ( j,o1,o2,o3,c,cl) = tm in
match o with
| 1 -> affiche_main tm;
jouer_joueur_poser1 tm,4
| 2 -> affiche_main tm;
print_endline ( "La couleur annoncee est : " ^ ( string_of_couleur c
) ^ "." ) ; let rec aux = function
| 1 -> jouer_joueur_poser tm,4
| 2 -> jouer_joueur_accuser tm
| _
-> print_endline "Ceci n'est pas un choix propose. Quel est votre choix ?" ; in
aux n
| _ -> failwith "Ceci n'est pas un ordre valable !"
;;
let init_menteur( ) =
let tm = creer_menteur( ) in
match n with
| 0 -> jouer_joueur 1 tm,( next n)
| 1 -> jouer_ordinateur 1 1 tm,( next n)
| 2 -> jouer_ordinateur 1 2 tm,( next n)
| _ -> jouer_ordinateur 1 3 tm,( next n)
;; (*table,gagnant,n*)
let debut_manche ( tm : table_menteur) g =
match g with
| 0 -> jouer_joueur 1 tm,( next g)
| _ -> jouer_ordinateur 1 g tm,( next g)
;; (*table,gagnant,n*)
let manche ( tm : table_menteur) n =
match n with
| 0 -> jouer_joueur 2 tm,( next n)
| _ -> jouer_ordinateur 2 n tm,( next n)
;; (*table,gagnant,n*)
(*Il faut assurer l'hérédité.
Test : tant qu'aucun des 4 tas n'est vide, on continue à jouer.
Continuer à jouer : fonction tm -> tm*)
(*PROBLEME : comment différencier les manches ?! Pour le moment, après l'accusation,
le jeu continue, et on ne revient jamais à l'ordre 0, d'où le problème.*)
let rec jeu_menteur ( tm : table_menteur) n g j =
inna_affiche_table_menteur tm;
match tm with
| [ ] ,_,_,_,_,_
-> print_endline "Felicitations ! Vous avez gagne la partie." ; j. credit <- j. credit + 1
| _,
[ ] ,_,_,_,_
| _,_,
[ ] ,_,_,_
| _,_,_,
[ ] ,_,_
-> print_endline "Malheureusement, vous avez perdu ..." | _,_,_,_,_,[ ] -> let ( ntm,ng) ,m = debut_manche tm g in
jeu_menteur ntm m ng j
| _ -> let ( ntm,ng) ,m = manche tm n in
jeu_menteur ntm m ng j
;;
let table1 = [ ] ,[ C( 1 ,Pique) ] ,[ C( 2 ,Pique) ] ,[ C( 3 ,Pique) ] ,Trefle,[ ] ;;
let table2 = [ C( 1 ,Pique) ] ,[ ] ,[ C( 2 ,Pique) ] ,[ C( 3 ,Pique) ] ,Trefle,[ ] ;;
let table3 = [ C( 10 ,Pique) ] ,[ C( 1 ,Pique) ] ,[ C( 2 ,Pique) ] ,[ C( 3 ,Pique) ] ,Trefle,[ ] ;;
(*jeu_menteur table2 0 0;;
jeu_menteur table1 0 0;;
jeu_menteur table3 2 1;;*)
let joue_menteur j =
let ( tm,g) ,n = init_menteur( ) in
jeu_menteur tm n g j
;;
j;;
(*joue_menteur j;;*)
(*********************************Bataille******************************)
let creer_bataille n : table_bataille =
match n with
| m when m > 1 ->
let jeu = C( 1 ,Coeur) :: C( 1 ,Pique) :: ( genere_mini_jeu n) in
let jeum = melanger jeu in
let t1,t2 = distribue jeum in ( t1,t2,[ ] ,[ ] )
| _ -> let jeu = genere_jeu( ) in
let jeum = melanger jeu in
let t1,t2 = distribue jeum in ( t1,t2,[ ] ,[ ] )
;;
creer_bataille 13 ;;
(*
jeu normal : table_bataille -> table_bataille,bool (j1 gagne),bool (j2 gagne) :
tb = (csj1,csj2,h1::t1,h2::t2)
Si csj1 = [] on s'arrête et J1 a gagné.
Si csj2 = [] on s'arrête et J2 a gagné.
Sinon :
csj1 = ha::ta, csj2 = hb::tb
Si ha > hb, le joueur 1 récupère les deux tas (il faut les mélanger avant de les
ajouter à la fin du paquet du joueur 1).
Si ha < hb, le joueur 2 récupère les deux tas.
Si ha = hb, alors bataille.*)
(*bataille : table_bataille -> table_bataille :
Description précise de la bataille :
tb = (csj1,csj2,tete1::q1,tete2::q2)
tete1 = tete2
On vérifie : si csj1 = ha1::ha2::ta et csj2 = hb1::hb2::tb, alors on lance le jeu
"normal" sur tnb = (ta,tb,ha1::ha2::tete1::q1,hb1::hb2::tete2::q2)
Sinon : les joueurs sont déclarés ex-aequo, et la partie est finie.
*)
let egal c1 c2 =
let C( r1,t1) = c1 and C( r2,t2) = c2 in r1 = r2;;
let superieur c1 c2 =
let C( r1,t1) = c1 and C( r2,t2) = c2 in
match r1 with
| 1 -> not ( r2 = 1 )
| r when r > r2 -> ( match r2 with
| 1 -> false
| _ -> true )
| _ -> false
;;
superieur ( C( 2 ,Trefle) ) ( C( 1 ,Trefle) ) ;;
(*lc;;
List.length lc;;
affiche_liste_cartes;;*)
(*
let inferieur c1 c2 = superieur c2 c1;;
inferieur (C(2,Trefle)) (C(1,Trefle));;*)
let rec tour_bataille ( table_b : table_bataille) ( j : joueur) =
let rec bataille = function
| ( _,_,[ ] ,[ ] ) -> failwith "Ceci n'est pas un cas de bataille"
| ( j1,j2,h1:: t1,h2:: t2) when ( egal h1 h2) -> ( match j1,j2 with
| ha1:: ha2:: ta,hb1:: hb2:: tb ->
tour_bataille ( ta,tb,ha1:: ha2:: h1:: t1,hb1:: hb2:: h2:: t2) j
| _
-> print_endline "Egalite ! Mais l'egalite n'est pas une victoire ..." ; )
| _ -> failwith "Ceci n'est pas un cas de bataille"
in
match table_b with
| ( [ ] ,_,_,_
) -> print_endline "Vous n'avez plus de cartes. Malheureusement, vous avez perdu ..." ; print_endline ( " carte(s), alors que votre adversaire n'en a plus. Felicitations " ^ ( j
. prenom
) ^ ", vous avez gagne !" ) ; j. nbre_batailles_gagnees <- j. nbre_batailles_gagnees + 1 ;
affiche_carte ha;
affiche_carte hb;
tour_bataille ( ta,tb,[ ha] ,[ hb] ) j)
| ( j1,j2,ha:: ta,hb:: tb) when ( superieur ha hb) ->
let tas = melanger ( empiler_cartes ( ha:: ta) ( hb:: tb) ) in
tour_bataille ( ( empiler_cartes tas j1) ,j2,[ ] ,[ ] ) j
)
| ( j1,j2,ha:: ta,hb:: tb) when ( superieur hb ha) ->
let tas = melanger ( empiler_cartes ( ha:: ta) ( hb:: tb) ) in
tour_bataille ( j1,( empiler_cartes tas j2) ,[ ] ,[ ] ) j
)
bataille table_b
;;
let joue_bataille j =
if j
. credit
= 0 then ( print_endline "Nous sommes desoles, mais vous n'avez pas assez de jetons pour jouer ... revenez plus tard !" ; )
else
( j. credit <- j. credit - 1 ;
print_endline "Quelle est la taille du mini-jeu sur lequel vous souhaitez voir se derouler la bataille ? Entrez la plus petite valeur disponible." ; let tb = creer_bataille n in
tour_bataille tb j)
;;
(*j.credit <- j.credit + 1;;
joue_bataille j;;
*)
(******************************Triche************************)
(*****************************Terminal***********************)
let rec inna_menu_principal j =
try
let rec aux = function
| 1 -> jouer_blackjack j;
inna_menu_principal j
| 2 -> joue_menteur j;
inna_menu_principal j
| 3 -> joue_bataille j;
inna_menu_principal j
| 4 -> let menu_triche joueur =
print_endline "Bienvenue, cher tricheur ! Quelle est l'aide que vous aimeriez obtenir ?" ; print_endline "1. Regarder la carte posee par l'adversaire avant de se prononcer durant une partie de menteur" ; print_endline "3. Obtenir au moins deux As lors de la distribution des cartes pour la bataille" ; let rec aux_triche = function
| 1 -> failwith "Not implemented"
| 2 -> joueur. credit <- joueur. credit + 1 ;
inna_menu_principal joueur;
| 3 -> failwith "Not implemented"
| 4 -> inna_menu_principal joueur;
| _
-> ( print_endline "Nous sommes desoles, mais ce choix n'est pas propose." ; in
aux_triche l) in
menu_triche j
| 5 -> print_endline "Merci pour votre visite. En esperant vous revoir bientot !" | _
-> ( print_endline "Nous sommes desoles, mais ce choix n'est pas propose." ; in
aux i
with Failure "int_of_string" -> begin print_string "inna Your choice is not valide.Repeat, please:" ; inna_menu_principal j
end ;;
let menu_debut( ) =
let j = { prenom = s ; credit = 1 ; nbre_batailles_gagnees = 0 } in
inna_menu_principal j
;;
menu_debut( ) ;;
KCoqKioqKioqKioqKioqSW50ZXJmYWNlciBhdmVjIGxlIHRlcm1pbmFsKioqKioqMSoqKioqKioqKioqKikKdHlwZSBqb3VldXIgPXtwcmVub20gOiBzdHJpbmc7IG11dGFibGUgY3JlZGl0IDogaW50OyBtdXRhYmxlIG5icmVfYmF0YWlsbGVzX2dhZ25lZXMgOiBpbnR9OzsKCigqKioqKioqKioqKioqKkF2YW50IGRlIGpvdWVyIC4uLioqKioqKioqKioqKioqKioqKioqKioqKioqKiopCnR5cGUgY291bGV1ciA9IENvZXVyIHwgQ2FycmVhdSB8IFRyZWZsZSB8IFBpcXVlOzsKCnR5cGUgY2FydGUgPSBDIG9mIGludCAqIGNvdWxldXI7OwpsZXQgYyA9IEMoMTAsQ29ldXIpOzsKbGV0IG5jID0gQygxNSxDYXJyZWF1KTs7CgpsZXQgdmFsaWRlIGNhcnRlID0gCiAgbGV0IEMobixjKSA9IGNhcnRlIGluIChuID4gMCkgJiYgKG4gPCAxNCkKOzsKdmFsaWRlIGM7Owp2YWxpZGUgbmM7OwoKbGV0IHN0cmluZ19vZl9jb3VsZXVyID0gZnVuY3Rpb24KICB8Q29ldXIgLT4gIkNvZXVyIgogIHxDYXJyZWF1IC0+ICJDYXJyZWF1IgogIHxUcmVmbGUgLT4gIlRyZWZsZSIKICB8UGlxdWUgLT4gIlBpcXVlIgo7OwpzdHJpbmdfb2ZfY291bGV1ciBUcmVmbGU7OwoKbGV0IHN0cmluZ19vZl9udW0gPSBmdW5jdGlvbgogIHwxIC0+ICJBcyBkZSIKICB8MTEgLT4gIlZhbGV0IGRlIgogIHwxMiAtPiAiRGFtZSBkZSIKICB8MTMgLT4gIlJvaSBkZSIKICB8ayAtPiAoc3RyaW5nX29mX2ludCBrKV4iIGRlIgo7OwpzdHJpbmdfb2ZfbnVtIDY7OwpzdHJpbmdfb2ZfbnVtIDEyOzsKCmxldCByZWMgYWZmaWNoZV9saXN0ZV9jYXJ0ZXMgY2wgPSAKICBsZXQgcmVjIGF1eCA9IGZ1bmN0aW9uCiAgfFtdIC0+ICJJbCBuJ3kgYSBwYXMgZGUgY2FydGVzLiIKICB8aDo6dCB3aGVuIG5vdCAodmFsaWRlIGgpIC0+IGZhaWx3aXRoICJDZSBuZSBzb250IHBhcyBkZXMgY2FydGVzICEiCiAgfFt4XSAoKkZpbiBkZSBsJ2FmZmljaGFnZSopIC0+IGxldCBDKG4sYykgPSB4IGluIAoJICAoc3RyaW5nX29mX251bSBuKV4iICJeKHN0cmluZ19vZl9jb3VsZXVyIGMpXiIuIgogIHxoOjp0ICgqTGEgcHJlbWnDqHJlIGNhcnRlIGVzdCB2YWxpZGUqKSAtPiBsZXQgQyhuLGMpID0gaCBpbgoJCQkJCSAgIChzdHJpbmdfb2ZfbnVtIG4pXiIgIl4oc3RyaW5nX29mX2NvdWxldXIgYykKCQkJCQkgICBeIiwgIl4oYXV4IHQpCiAgaW4gCiAgcHJpbnRfc3RyaW5nIChhdXggY2wpCjs7CmxldCBsY3YgPSBbXTs7CmxldCBsYyA9IFtDKDEsQ29ldXIpIDsgQygxMCxQaXF1ZSkgOyBDKDEzLFRyZWZsZSldOzsKKCphZmZpY2hlX2xpc3RlX2NhcnRlcyBsY3Y7OwphZmZpY2hlX2xpc3RlX2NhcnRlcyBsYzs7KikKCmxldCBnZW5lcmVfamV1ICgpID0gCiAgbGV0IHJlYyBhdXggbiBsID0gCiAgICBtYXRjaCBuIHdpdGgKICAgfDAgLT4gbAogICB8bSB3aGVuIChtID4gMCkmJihtIDwgMTQpIC0+IGF1eCAobS0xKSAoQyhtLENvZXVyKTo6bCkKICAgfG0gd2hlbiAobSA+IDEzKSYmKG0gPCAyNykgLT4gYXV4IChtLTEpIChDKG0tMTMsQ2FycmVhdSk6OmwpCiAgIHxtIHdoZW4gKG0gPiAyNikmJihtIDwgNDApIC0+IGF1eCAobS0xKSAoQyhtLTI2LFRyZWZsZSk6OmwpCiAgIHxtIHdoZW4gKG0gPiAzOSkmJihtIDwgNTMpIC0+IGF1eCAobS0xKSAoQyhtLTM5LFBpcXVlKTo6bCkKICAgfG0gLT4gZmFpbHdpdGggIlByb2JsZW1lIGRhbnMgbGEgZm9uY3Rpb24gYXV4IGRlIGdlbmVyZV9qZXUiCiAgaW4gCiAgYXV4IDUyIFtdCjs7CmdlbmVyZV9qZXUoKTs7CgpsZXQgcmVjIGdlbmVyZV9taW5pX2pldSA9IGZ1bmN0aW9uCiAgIHxtIHdoZW4gbSA8IDE0IC0+IEMobSxDb2V1cik6OkMobSxQaXF1ZSk6OihnZW5lcmVfbWluaV9qZXUgKG0rMSkpCiAgIHxfIC0+IFtdCjs7CmdlbmVyZV9taW5pX2pldSAxMzs7CmdlbmVyZV9taW5pX2pldSA1OzsKCgpsZXQgcmVjIGxpc3RlX250aCBuIGwgPSAoKkZvbmN0aW9uIGF1eGlsaWFpcmUgw6AgbcOpbGFuZ2VyIDogcGVybWV0IGRlIHByZW5kcmUgdW4gw6lsw6htZW50IGRlIG51bcOpcm8gZG9ubsOpIGRhbnMgbGEgbGlzdGUgZXQgcmVudm9pZSBsJ8OpbGVtZW50IGV0IGxhIGxpc3RlIHJlc3RhbnRlLiopCiAgbWF0Y2ggbCB3aXRoCiB8W10gLT4gZmFpbHdpdGggImxpc3RlIHZpZGUiCiB8aDo6dCAtPiBtYXRjaCBuIHdpdGgKICAgICAgICAgfDAgLT4gaCx0CgkgfF8gLT4gbGV0IGUsciA9IGxpc3RlX250aCAobi0xKSB0IGluIGUsaDo6cgo7OyAKCigqT24gY3LDqWUgdW5lIG5vdXZlbGxlIGxpc3RlIDsgb24gcHJlbmQgdW4gw6lsZW1lbnQgYWzDqWF0b2lyZSBkYW5zIGxhIHByZW1pw6hyZSwKb24gbCdham91dGUgw6AgbGEgbm91dmVsbGUgbGlzdGUgdG91dCBlbiBsZSBzdXBwcmltYW50IGRlIGxhIHByZW1pw6hyZS4qKQoKbGV0IG1lbGFuZ2VyIChjbCA6IGNhcnRlIGxpc3QpIDogY2FydGUgbGlzdCA9IAogIFJhbmRvbS5zZWxmX2luaXQgKCk7CiAgbGV0IHJlYyBhdXggbDEgbDIgPSAKICAgIG1hdGNoIGwxIHdpdGgKICAgfFtdIC0+IGwyCiAgIHxfIC0+IGxldCBuID0gUmFuZG9tLmludCAoTGlzdC5sZW5ndGggbDEpIGluIAoJICAgIGxldCBlLHIgPSBsaXN0ZV9udGggbiBsMSBpbgogICAgICAgICAgICBhdXggciAoZTo6bDIpCiAgaW4KICBhdXggY2wgW10KOzsKbGM7OwptZWxhbmdlciBsYzs7CgpsZXQgcmVjIGRpc3RyaWJ1ZSAoY2wgOiBjYXJ0ZSBsaXN0KSA6IGNhcnRlIGxpc3QgKiBjYXJ0ZSBsaXN0ID0gCiAgbWF0Y2ggY2wgd2l0aAogIHxbXSAtPiBbXSxbXQogIHxbeF0gLT4gW3hdLFtdCiAgfGgxOjpoMjo6dCAtPiBsZXQgbDEsbDIgPSBkaXN0cmlidWUgdCBpbiBoMTo6bDEsaDI6OmwyCjs7CmxjOzsKZGlzdHJpYnVlIFtdOzsKZGlzdHJpYnVlIFtDKDEsQ29ldXIpXTs7CmRpc3RyaWJ1ZSBsYzs7CgpsZXQgcmVjIHBpb2NoZXIgKG4gOiBpbnQpIChjbCA6IGNhcnRlIGxpc3QpIDogKGNhcnRlIGxpc3QgKiBjYXJ0ZSBsaXN0KSA9IAogIG1hdGNoIG4sY2wgd2l0aAogfDAsW10gLT4gW10sW10KIHxfLFtdIC0+IGZhaWx3aXRoICJJbCBuJ3kgYSBwYXMgYXNzZXogZGUgY2FydGVzIGRhbnMgbGEgcGlvY2hlICEiCiB8MCxsIC0+IFtdLGwKIHxuLGg6OnQgLT4gbGV0IHAscHIgPSBwaW9jaGVyIChuLTEpIHQgaW4gaDo6cCxwcgo7OwpsYzs7CnBpb2NoZXIgMCBsYzs7CnBpb2NoZXIgMCBbXTs7CnBpb2NoZXIgMSBsYzs7CnBpb2NoZXIgMyBsYzs7CigqcGlvY2hlciA0IGxjOzsqKQoKbGV0IHJlYyBlbXBpbGVyX2NhcnRlcyAobWMgOiBjYXJ0ZSBsaXN0KSAodCA6IGNhcnRlIGxpc3QpIDogY2FydGUgbGlzdCA9CiAgbWF0Y2ggdCB3aXRoCiB8W10gLT4gbWMKIHxoOjp0bCAtPiBoOjooZW1waWxlcl9jYXJ0ZXMgbWMgdGwpCjs7CmxjOzsKZW1waWxlcl9jYXJ0ZXMgbGMgW0MoNyxDYXJyZWF1KV07OwplbXBpbGVyX2NhcnRlcyBbQyg3LENhcnJlYXUpO0MoOCxDYXJyZWF1KV0gbGM7OwoKCgooKioqKioqKioqKioqKioqKioqKioqKioqKioqKipCbGFja2phY2sqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopCgp0eXBlIHBsYXRlYXVfYmxhY2tqYWNrID0gY2FydGUgbGlzdCAoKkNhcnRlcyBkdSBqb3VldXIqKSAqIApjYXJ0ZSBsaXN0ICgqQ2FydGVzIGRlIGxhIGJhbnF1ZSopICogY2FydGUgbGlzdCAoKlBpb2NoZSopCjs7CgpsZXQgY3JlZXJfYmxhY2tqYWNrICgpIDogcGxhdGVhdV9ibGFja2phY2sgPSBbXSxbXSxtZWxhbmdlciAoZ2VuZXJlX2pldSgpKTs7CmxldCBwID0gY3JlZXJfYmxhY2tqYWNrKCk7OwogIApsZXQgYmFucXVlX3Bpb2NoZSAobiA6IGludCkgKHAgOiBwbGF0ZWF1X2JsYWNramFjaykgOiBwbGF0ZWF1X2JsYWNramFjayA9IAogIGxldCBjaixjYixwaSA9IHAgaW4KICAgICBsZXQgbyxyID0gcGlvY2hlciBuIHBpIGluCiAgICAgICBjaixvQGNiLHIKOzsKYmFucXVlX3Bpb2NoZSAwIHAgPSBwOzsKYmFucXVlX3Bpb2NoZSA1MiBwOzsKCmxldCBqb3VldXJfcGlvY2hlIChuIDogaW50KSAocCA6IHBsYXRlYXVfYmxhY2tqYWNrKSA6IHBsYXRlYXVfYmxhY2tqYWNrID0gCiAgbGV0IGNqLGNiLHBpID0gcCBpbgogICAgIGxldCBvLHIgPSBwaW9jaGVyIG4gcGkgaW4KICAgICAgICBvQGNqLGNiLHIKOzsKam91ZXVyX3Bpb2NoZSAwIHAgPSBwOzsKam91ZXVyX3Bpb2NoZSA1MiBwOzsKCmxldCB2YWxldXIgPSBmdW5jdGlvbgogIHwxMSB8MTIgfDEzIC0+IDEwCiAgfGsgLT4gawo7OyAKdmFsZXVyIDEyOzsKdmFsZXVyIDk7OwoKbGV0IHJlYyB0b3RhbF9jYXJ0ZXMgY2wgPSAKICBtYXRjaCBjbCB3aXRoIAogfFtdIC0+IDAKIHxoOjp0IC0+IGxldCBDKGssYykgPSBoIGluIAogICAgICAgICAgICh2YWxldXIgaykgKyB0b3RhbF9jYXJ0ZXMgdAo7OwpsYzs7CnRvdGFsX2NhcnRlcyBsYzs7CgpsZXQgZmFpcmVfam91ZXJfYmFucXVlIHAgPQogIGxldCByZWMgYXV4IHQgcGwgPQogICAgbWF0Y2ggdCB3aXRoCiAgIHxuIHdoZW4gbiA8IDE3IC0+IChsZXQgY2osY2IscGkgPSBiYW5xdWVfcGlvY2hlIDEgcGwgaW4KCQkgICAgICBtYXRjaCBjYiB3aXRoCgkJICAgICB8W10gLT4gZmFpbHdpdGggIlByb2JsZW1lIGRlIHBpb2NoZS4iCgkJICAgICB8QyhrLGMpOjp0YSAtPiBhdXggKG4rICh2YWxldXIgaykpIChjaixjYixwaSkpICAKICAgfF8gLT4gcGwKICBpbiAKICBsZXQgcGoscGIscHBpID0gcCBpbiAKICAgICBsZXQgbiA9IHRvdGFsX2NhcnRlcyBwYiBpbgogICAgICAgIGF1eCBuIHAKOzsKbGV0IHBtID0gbGV0IGosYixwaSA9IHAgaW4gaixiLG1lbGFuZ2VyIHBpOzsKZmFpcmVfam91ZXJfYmFucXVlIHBtOzsKCgpsZXQgYWZmaWNoZXJfamV1IChwIDogcGxhdGVhdV9ibGFja2phY2spID0KICBsZXQgY2osY2IscGkgPSBwIGluCiAgcHJpbnRfc3RyaW5nICJDYXJ0ZXMgZHUgam91ZXVyIDogIjsKICBhZmZpY2hlX2xpc3RlX2NhcnRlcyBjajsKICBwcmludF9zdHJpbmcgIiBDYXJ0ZXMgZGUgbGEgYmFucXVlIDogIjsKICBhZmZpY2hlX2xpc3RlX2NhcnRlcyBjYjsKICBwcmludF9uZXdsaW5lKCk7CiAgcHJpbnRfc3RyaW5nICJUb3RhbCBqb3VldXIgOiAiOwogIHByaW50X2ludCAodG90YWxfY2FydGVzIGNqKTsKICBwcmludF9zdHJpbmcgIi4gVG90YWwgYmFucXVlIDogIjsKICBwcmludF9pbnQgKHRvdGFsX2NhcnRlcyBjYik7CiAgcHJpbnRfbmV3bGluZSgpCjs7CigqYWZmaWNoZV9qZXUgcG07OyopCiAKbGV0IGZhaXJlX2pvdWVyX2pvdWV1ciBwID0gKCpBIEZBSVJFIDogcmF0dHJhcGVyIGwnZXhjZXB0aW9uIGludF9vZl9zdHJpbmcqKQogIGxldCByZWMgYXV4IGsgcGwgPSAKICAgbWF0Y2ggayB3aXRoCiAgfDIgLT4gcGwKICB8MSAtPiAobGV0IHBuID0gam91ZXVyX3Bpb2NoZSAxIHBsIGluCglhZmZpY2hlcl9qZXUgcG47CiAgICAgICAgcHJpbnRfZW5kbGluZSAiVm91bGV6LXZvdXMgcGlvY2hlciB1bmUgY2FydGUgPyI7CglwcmludF9lbmRsaW5lICIxIC0gT3VpIjsKCXByaW50X2VuZGxpbmUgIjIgLSBOb24iOwogICAgICAgIGxldCBsID0gcmVhZF9pbnQoKSBpbiAKCWF1eCBsIHBuKQogIHxfIC0+IChwcmludF9lbmRsaW5lICJDZWNpIG4nZXN0IHBhcyB1bmUgbWFuaWVyZSBkZSBqb3VlciBhY2NlcHRhYmxlLiBWb3VsZXotdm91cyBwaW9jaGVyIHVuZSBjYXJ0ZSA/IjsKICAgICAgICBwcmludF9lbmRsaW5lICIxIC0gT3VpIjsKICAgICAgICBwcmludF9lbmRsaW5lICIyIC0gTm9uIjsKICAgICAgICBsZXQgbCA9IHJlYWRfaW50KCkgaW4KCWF1eCBsIHBsKQogIGluCiAgICAgIGFmZmljaGVyX2pldSBwOwogICAgICBwcmludF9uZXdsaW5lKCk7CiAgICAgIHByaW50X2VuZGxpbmUgIlZvdWxlei12b3VzIHBpb2NoZXIgdW5lIGNhcnRlID8iOwogICAgICBwcmludF9lbmRsaW5lICIxIC0gT3VpIjsKICAgICAgcHJpbnRfZW5kbGluZSAiMiAtIE5vbiI7CiAgICAgIGxldCBtID0gcmVhZF9pbnQoKSBpbgogICAgICAgICAgYXV4IG0gcAo7OwooKmZhaXJlX2pvdWVyX2pvdWV1ciBwbTs7KikKCmxldCBqb3Vlcl9ibGFja2phY2sgaiA9IAogIHByaW50X2VuZGxpbmUgIioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiI7CiAgcHJpbnRfZW5kbGluZSAiKiAgICAgICAgICAgICAgIEJsYWNramFjayAgICAgICAgICAgICAgICAqIjsKICBwcmludF9lbmRsaW5lICIqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioiOwogIGxldCBwID0gY3JlZXJfYmxhY2tqYWNrKCkgaW4KICAgICBsZXQgcGIgPSBiYW5xdWVfcGlvY2hlIDEgcCBpbgogICAgICAgIGxldCBwaiA9IGpvdWV1cl9waW9jaGUgMiBwYiBpbgoJICAgIGxldCBwbF9lbl9qZXUgPSBmYWlyZV9qb3Vlcl9qb3VldXIgcGogaW4gCiAgICAgICAgICAgICAgICBsZXQgY2osY2IscGkgPSBwbF9lbl9qZXUgaW4KCQkgICAgbGV0IHRqID0gdG90YWxfY2FydGVzIGNqIGluCgkJICAgIG1hdGNoIHRqIHdpdGgKCSAgICAgICAgICAgIHxuIHdoZW4gbiA+IDIxIC0+IHByaW50X2VuZGxpbmUgIlZvdXMgYXZleiBwZXJkdS4iCgkgICAgICAgICAgICB8XyAtPiBsZXQgcGJfZW5famV1ID0gZmFpcmVfam91ZXJfYmFucXVlIHBsX2VuX2pldSBpbgoJCQkgICAgICAgbGV0IHBqLHBiLHBwaSA9IHBiX2VuX2pldSBpbiAgCgkJICAgICAgICAgICAgICAgICAgIGxldCB0YiA9IHRvdGFsX2NhcnRlcyBwYiBpbgoJCSAgICAgICAgICAgICAgICAgICAgICAoIG1hdGNoIHRiIHdpdGgKCQkJCSAgICAgIHxuIHdoZW4gKG4gPiAyMSkgfHwgKG4gPCB0aikgLT4gCgkJCQkJKGouY3JlZGl0IDwtIGouY3JlZGl0KzE7CgkJCQkJcHJpbnRfZW5kbGluZSAiVm91cyBhdmV6IGdhZ25lICEiKQoJCQkJICAgICAgfG4gd2hlbiBuID4gdGogLT4gCgkJCQkJKHByaW50X3N0cmluZyAiVm91cyBhdmV6IHBlcmR1LiI7CgkJCQkJcHJpbnRfbmV3bGluZSgpOwoJCQkJCXByaW50X3N0cmluZyAiVG90YWwgZGUgbGEgYmFucXVlIDoiOwoJCQkJCXByaW50X2ludCB0YjsKCQkJCQlwcmludF9uZXdsaW5lKCk7KQoJCQkJICAgICAgfF8gLT4gcHJpbnRfZW5kbGluZSAiRWdhbGl0ZSAhIgoJCQkJICAgICAgCiApCjs7CigqTCfDqWdhbGl0w6kgbidlc3QgcGFzIHVuZSByw6l1c3NpdGUuKikKbGV0IGogPSB7cHJlbm9tID0gIkoiOyBjcmVkaXQgPSAwIDsgbmJyZV9iYXRhaWxsZXNfZ2FnbmVlcyA9IDB9OzsKKCpqb3Vlcl9ibGFja2phY2sgajs7KikKCgoKKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipNZW50ZXVyKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKikKbGV0IGpPMSA9IHtwcmVub20gPSAiT3IxIjsgY3JlZGl0ID0gMDsgbmJyZV9iYXRhaWxsZXNfZ2FnbmVlcyA9IDB9OzsKbGV0IGpPMiA9IHtwcmVub20gPSAiT3IyIjsgY3JlZGl0ID0gMDsgbmJyZV9iYXRhaWxsZXNfZ2FnbmVlcyA9IDB9OzsKbGV0IGpPMyA9IHtwcmVub20gPSAiT3IzIjsgY3JlZGl0ID0gMDsgbmJyZV9iYXRhaWxsZXNfZ2FnbmVlcyA9IDB9OzsKCgooKkpldSBkdSBtZW50ZXVyIDogSE9XIFRPLCBXSEFUIFRPIDoKT24gYSBiZXNvaW4gZGVzIDQgdGFzIGRlIGNhcnRlcyA7IG9uIHZvdWRyYWl0IHF1J2lscyBzb2llbnQgdHJpw6lzIHBhciBjb3VsZXVyLgotPiBGT05DVElPTiBkZSB0cmkgcGFyIGNvdWxldXIuIERPTkUKT24gYSBiZXNvaW4gZGUgc2F2b2lyIHF1ZWwgZXN0IGxhIGNvdWxldXIgYW5ub25jw6llIHBhciBsZSAxZXIgam91ZXVyLgpPbiBhIGJlc29pbiBkZSBzYXZvaXIgbGEgY2FydGUgcG9zw6llIHN1ciBsYSB0YWJsZS4gLT4gbGlzdGUgc29pdCB2aWRlLCBzb2l0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9zw6llIGQndW4gc2V1bCDDqWzDqW1lbnQuCgoqKQp0eXBlIHRhYmxlX21lbnRldXIgPSAoKlBpbGUgSiwgUGlsZSBvMSwgUGlsZSBvMiwgUGlsZSBvMywgY291bGV1ciBhbm5vbmPDqWUsIApDYXJ0ZSBwb3PDqWUgc3VyIGxhIHRhYmxlICopCiBjYXJ0ZSBsaXN0ICogY2FydGUgbGlzdCAqIGNhcnRlIGxpc3QgKiBjYXJ0ZSBsaXN0ICogY291bGV1ciAqIGNhcnRlIGxpc3Q7OwooKmNhcnRlIGxpc3QgcG91ciBsZSBkZXJuaWVyIGNoYW1wIHBvdXIgcG91dm9pciBpbml0aWFsaXNlciBlbiBsaXN0ZSB2aWRlLj8/KikKKCoKbGV0IHJlYyB0cmlfMWNhcnRlX2NvdWxldXIgYyBsID0oKmluc8OpcmVyIHVuZSBjYXJ0ZSBkJ3VuZSBjb3VsZXVyIGRvbsOpZSBkYW5zIHVuZSAKCQkJCSAgbGlzdGUgZGUgY2FydGVzIHRyacOpZXMgcGFyIGNvdWxldXJzLiopCiAgbGV0IEMocjEsdDEpID0gYyBpbiAKICBtYXRjaCBsIHdpdGgKIHxbXSAtPiBbY10KIHxoOjp0YSAtPiBsZXQgQyhyMix0MikgPSBoIGluCgkgICBpZiB0MSA9IHQyIHRoZW4gYzo6bAoJICAgZWxzZSBoOjoodHJpXzFjYXJ0ZV9jb3VsZXVyIGMgdGEpCjs7CmxjOzsKdHJpXzFjYXJ0ZV9jb3VsZXVyIChDKDIsQ29ldXIpKSBsYzs7CnRyaV8xY2FydGVfY291bGV1ciAoQygyLFBpcXVlKSkgbGM7Owp0cmlfMWNhcnRlX2NvdWxldXIgKEMoMixUcmVmbGUpKSBsYzs7CgpsZXQgdHJpX2NvdWxldXIgY2wgPSAKICBsZXQgcmVjIGF1eCBsMSBsMiA9CiAgICBtYXRjaCBsMSB3aXRoCiAgIHxbXSAtPiBsMgogICB8aDo6dCAtPiBhdXggdCAodHJpXzFjYXJ0ZV9jb3VsZXVyIGggbDIpCiAgaW4gCiAgYXV4IGNsIFtdCjs7CmxldCBsY3QgPSBnZW5lcmVfbWluaV9qZXUgMTA7OwpsZXQgbGN0bSA9IG1lbGFuZ2VyIGxjdDs7CnRyaV9jb3VsZXVyIGxjdG07OwoqKQpsZXQgY29sb3IgYyA9IAogIGxldCBDKHIsdCkgPSBjIGluIHQ7Owpjb2xvciAoQygxMCxUcmVmbGUpKTs7CgpsZXQgcmVjIGNvbXB0ZV9jb3VsZXVycyA9IGZ1bmN0aW9uCiAgfFtdIC0+ICgwLDAsMCwwKQogIHxoOjp0IHdoZW4gKGNvbG9yIGgpID0gQ29ldXIgLT4gbGV0IChhLGIsYyxkKSA9IGNvbXB0ZV9jb3VsZXVycyB0IGluCgkJCQkgICgxK2EsYixjLGQpCiAgfGg6OnQgd2hlbiAoY29sb3IgaCkgPSBDYXJyZWF1IC0+IGxldCAoYSxiLGMsZCkgPSBjb21wdGVfY291bGV1cnMgdCBpbgoJCQkJICAoYSwxK2IsYyxkKQogIHxoOjp0IHdoZW4gKGNvbG9yIGgpID0gVHJlZmxlIC0+IGxldCAoYSxiLGMsZCkgPSBjb21wdGVfY291bGV1cnMgdCBpbgoJCQkJICAoYSxiLDErYyxkKQogIHxoOjp0ICgqd2hlbiAoY29sb3IgaCkgPSBQaXF1ZSopIC0+IGxldCAoYSxiLGMsZCkgPSBjb21wdGVfY291bGV1cnMgdCBpbgoJCQkJICAoYSxiLGMsMStkKQo7OwoKbGV0IHJlYyBpbm5hX25iX2NhcnRlcyBsIGNvdWxldXI9bWF0Y2ggbCB3aXRoCltdLT4wCnwgaDo6dGwgLT4gbWF0Y2ggaCB3aXRoCiAgICAgICAgICAgQyhfLGNscikgd2hlbiBjbHI9Y291bGV1ciAtPjErKGlubmFfbmJfY2FydGVzIHRsIGNvdWxldXIpCiAgICAgICAgICAgfF8gLT4gaW5uYV9uYl9jYXJ0ZXMgdGwgY291bGV1cjs7CgooKiBpbm5hX2FmZmljaGVfcGlsZV9zZWxvbl9jb3VsZXVyIHBpbGUgY291bGV1ciBsIFBpcXVlIC0+KDIsMjApIHZldXQgZGlyZSAiMiBQaXF1ZXMsIDIwIG5vbi1QaXF1ZXMiICopCmxldCBpbm5hX2FmZmljaGVfcGlsZV9zZWxvbl9jb3VsZXVyIHBpbGUgY291bGV1ciA9cHJpbnRfc3RyaW5nIigiO3ByaW50X2ludChpbm5hX25iX2NhcnRlcyBwaWxlIGNvdWxldXIpO3ByaW50X3N0cmluZyAiLCI7cHJpbnRfaW50KChMaXN0Lmxlbmd0aCBwaWxlKS0oaW5uYV9uYl9jYXJ0ZXMgcGlsZSBjb3VsZXVyKSk7cHJpbnRfc3RyaW5nIikiOzsKCmxldCBpbm5hX2FmZmljaGVfdGFibGVfbWVudGV1ciB0bT0gbGV0IChqLG8xLG8yLG8zLGNsLGMpID0gdG0gaW4gaW5uYV9hZmZpY2hlX3BpbGVfc2Vsb25fY291bGV1ciBqIGNsO2lubmFfYWZmaWNoZV9waWxlX3NlbG9uX2NvdWxldXIgbzEgY2w7aW5uYV9hZmZpY2hlX3BpbGVfc2Vsb25fY291bGV1ciBvMiBjbDtpbm5hX2FmZmljaGVfcGlsZV9zZWxvbl9jb3VsZXVyIG8zIGNsO3ByaW50X25ld2xpbmUoKTs7CgpsZXQgbGN0ID0gZ2VuZXJlX21pbmlfamV1IDEwOzsKbGV0IGxjdG0gPSBtZWxhbmdlciBsY3Q7OwpsY3RtOzsJCQkJICAgCmNvbXB0ZV9jb3VsZXVycyBsY3RtOzsJCQkJIAoKbGV0IGNyZWVyX21lbnRldXIgKCkgOiB0YWJsZV9tZW50ZXVyID0gCiAgbGV0IGpldSA9IGdlbmVyZV9qZXUgKCkgaW4KICBsZXQgamV1X20gPSBtZWxhbmdlciBqZXUgaW4KICBsZXQgdDEsdDIgPSBkaXN0cmlidWUgamV1X20gaW4KICBsZXQgajEsajIgPSBkaXN0cmlidWUgdDEgYW5kIGozLGo0ID0gZGlzdHJpYnVlIHQyIGluCiAgICAgKGoxLGoyLGozLGo0LFBpcXVlLFtdKTs7ICgqSW5pdGlhbGlzYXRpb24gYXJiaXRyYWlyZSBkZSBsYSBjb3VsZXVyLiopCmNyZWVyX21lbnRldXIoKTs7CgpsZXQgcmVjIGNob2lzaXIgY2wgYyA9ICgqY2hvaXNpciB1bmUgY2FydGUgZGUgbGEgY291bGV1ciBkb25uw6llLCBvdSBuJ2ltcG9ydGUgcXVlbGxlIGF1dHJlIGNhcnRlIHNpbm9uIDogbsOpY2Vzc2FpcmUgcG91ciBmYWlyZSBqb3VlciBsJ29yZGluYXRldXIqKQogICgqbGV0IGNvbCA9IGNvbG9yIGMgaW4qKQogIG1hdGNoIGNsIHdpdGgKIHxbXSAtPiBmYWlsd2l0aCAiSWwgbid5IGEgcGFzIGRlIGNhcnRlcyAhIgogfFt4XSAtPiB4LFtdCiB8QyhyLHQpOjp0YSB3aGVuIHQgPSBjIC0+IChDKHIsdCkpLHRhCiB8aDo6dGEgLT4gbGV0IGYscyA9IGNob2lzaXIgdGEgYyBpbiBmLGg6OnMKOzsoKkEgUkVQUkVORFJFKikKbGM7OwpjaG9pc2lyIGxjIENhcnJlYXU7OwoKbGV0IG5leHQgPSBmdW5jdGlvbgogIHwwIC0+IDEKICB8MSAtPiAyCiAgfDIgLT4gMwogIHwzIC0+IDAKICB8XyAtPiBmYWlsd2l0aCAiQ2VjaSBuJ2VzdCBwYXMgdW4gam91ZXVyIGV4aXN0YW50Igo7OwoKbGV0IHByZWMgPSBmdW5jdGlvbgogIHwwIC0+IDMKICB8MSAtPiAwCiAgfDIgLT4gMQogIHwzIC0+IDIKICB8XyAtPiBmYWlsd2l0aCAiQ2VjaSBuJ2VzdCBwYXMgdW4gam91ZXVyIGV4aXN0YW50Igo7OwoKbGV0IGpvdWVyX29yZGluYXRldXJfcG9zZSBuICh0bSA6IHRhYmxlX21lbnRldXIpIDogdGFibGVfbWVudGV1ciA9CiAgbGV0IChqLG8xLG8yLG8zLGMsY2wpID0gdG0gaW4KICBwcmludF9zdHJpbmcgIkxlIGpvdWV1ciAiOwogIHByaW50X2ludCBuOwogIHByaW50X2VuZGxpbmUgIiBwb3NlIHVuZSBjYXJ0ZS4iOwogIG1hdGNoIG4gd2l0aAogfDEgLT4gbGV0IGNhcnRlLHJlc3RlID0gY2hvaXNpciBvMSBjIGluIAogICAgICAgaixyZXN0ZSxvMixvMyxjLGNhcnRlOjpjbAogfDIgLT4gbGV0IGNhcnRlLHJlc3RlID0gY2hvaXNpciBvMiBjIGluIAogICAgICAgaixvMSxyZXN0ZSxvMyxjLGNhcnRlOjpjbAogfDMgLT4gbGV0IGNhcnRlLHJlc3RlID0gY2hvaXNpciBvMyBjIGluIAogICAgICAgaixvMSxvMixyZXN0ZSxjLGNhcnRlOjpjbAogfF8gLT4gZmFpbHdpdGggIkNlIGpvdWV1ciBuJ2V4aXN0ZSBwYXMuIgo7OwoKbGV0IGpvdWVyX29yZGluYXRldXJfcG9zZTEgbiAodG0gOiB0YWJsZV9tZW50ZXVyKSA6IHRhYmxlX21lbnRldXIgPQogIGxldCAoaixvMSxvMixvMyxjLGNsKSA9IHRtIGluCiAgcHJpbnRfc3RyaW5nICJMZSBqb3VldXIgIjsKICBwcmludF9pbnQgbjsKICBwcmludF9lbmRsaW5lICIgY2hvaXNpdCB1bmUgY291bGV1ci4iOwogIFJhbmRvbS5zZWxmX2luaXQoKTsKICBsZXQgbnVtX2NvdWxldXIgPSBSYW5kb20uaW50IDQgaW4KICBtYXRjaCBudW1fY291bGV1ciB3aXRoCiB8MCAtPiBqb3Vlcl9vcmRpbmF0ZXVyX3Bvc2UgbiAoaixvMSxvMixvMyxDb2V1cixjbCkKIHwxIC0+IGpvdWVyX29yZGluYXRldXJfcG9zZSBuIChqLG8xLG8yLG8zLENhcnJlYXUsY2wpCiB8MiAtPiBqb3Vlcl9vcmRpbmF0ZXVyX3Bvc2UgbiAoaixvMSxvMixvMyxUcmVmbGUsY2wpCiB8XyAtPiBqb3Vlcl9vcmRpbmF0ZXVyX3Bvc2UgbiAoaixvMSxvMixvMyxQaXF1ZSxjbCkKOzsKCigqRMOpcm91bGVtZW50IGR1IGpldSA6CkxlIHByZW1pZXIgam91ZXVyIGRvbm5lIHVuZSBjb3VsZXVyLgpTdHJhdMOpZ2llIGRlcyBvcmRpbmF0ZXVycyA6IFN0cmF0w6lnaWUgMSA6IG1ldHRyZSB1bmUgY2FydGUgZGUgbGEgY291bGV1ciBhbm5vbmPDqWUKanVzcXUnw6AgY2UgcXUnaWwgbid5IGVuIGFpdCBwbHVzLCBwdWlzIG1ldHRyZSBuJ2ltcG9ydGUgcXVlbGxlIGNhcnRlLgpTdHJhdMOpZ2llIDIgOiBhY2N1c2VyIGxlIGpvdWV1ciBwcsOpY8OpZGVudC4gUHJvYmEgZCcxLzIgZGUgY2hvaXggZGUgbCd1bmUgb3UgbCdhdXRyZS4KSm91ZXVyIDogMS4gUydpbCBlc3QgbGUgcHJlbWllciDDoCBqb3VlciA6IGRlbWFuZGVyIHVuZSBjb3VsZXVyLiAyLiBTJ2lsIG4nZXN0IHBhcwpsZSBwcmVtaWVyLCBkZW1hbmRlciB1bmUgY2FydGUgb3UgdW5lIGFjY3VzYXRpb24uKikKKCoKbGV0IGJlX29mX2NvbG9yIGNvIGNhID0gCiAgbGV0IEMocix0KSA9IGNhIGluIGNvID0gdDs7CmJlX29mX2NvbG9yIFRyZWZsZSAoQygzLFRyZWZsZSkpOzsKYmVfb2ZfY29sb3IgVHJlZmxlIChDKDMsQ29ldXIpKTs7CgpsZXQgcmVjIGxpc3RfZmluZCBwIGwgPSAKICBtYXRjaCBsIHdpdGgKIHxbXSAtPiByYWlzZSBOb3RfZm91bmQKIHxoOjp0IC0+IGlmIChwIGgpIHRoZW4gaCx0CiAgICAgICAgICBlbHNlIGxldCBtLHIgPSBsaXN0X2ZpbmQgcCB0IGluCgkgICAgICAgbSxoOjpyCjs7Cmxpc3RfZmluZCAoYmVfb2ZfY29sb3IgQ29ldXIpIGxjOzsKCmxldCBqb3Vlcl9waWxlIGMgcCA9CiAgaWYgTGlzdC5leGlzdHMgKGJlX29mX2NvbG9yIGMpIHAgdGhlbgogICAgbGlzdF9maW5kIChiZV9vZl9jb2xvciBjKSBwIAogIGVsc2UgbWF0Y2ggcCB3aXRoCiAgICAgIHxbXSAtPiBmYWlsd2l0aCAiSWwgbid5IGEgcGx1cyBkZSBjYXJ0ZXMgOyBpbCB5IGEgZHUgeSBhdm9pciB1bmUgZXJyZXVyICEiCiAgICAgIHxoOjp0IC0+IGgsdAo7OwpsYzs7Cigqam91ZXJfcGlsZSBDb2V1ciBbXTs7KikKam91ZXJfcGlsZSBDYXJyZWF1IGxjOzsKCmxldCByZWMgbGlzdF9udGggbiBsID0gCiAgbWF0Y2ggbCB3aXRoCiB8W10gLT4gZmFpbHdpdGggIkxhIGxpc3RlIGVzdCB0cm9wIGNvdXJ0ZSIKIHxoOjp0IC0+IG1hdGNoIG4gd2l0aAogICAgICAgICB8MCAtPiBoLHQKCSB8XyAtPiBsZXQgZSxyID0gbGlzdF9udGggKG4tMSkgdCBpbiBlLGg6OnIKOzsgCgpsZXQgY2hvaXNpcl9jb3VsZXVyIHAgPSAKICAgICBSYW5kb20uc2VsZl9pbml0ICgpOwogICAgIG1hdGNoIHAgd2l0aAogICAgfFtdIC0+IGZhaWx3aXRoICJJbCBuJ3kgYSBwbHVzIGRlIGNhcnRlcyA7IGlsIHkgYSBkdSB5IGF2b2lyIHVuZSBlcnJldXIgISIKICAgIHxoOjp0YSAtPiBsZXQgbiA9IExpc3QubGVuZ3RoIHAgaW4gCgkgICAgICBsZXQgbSA9IFJhbmRvbS5pbnQgbiBpbgoJICAgICAgbGV0IChDKHIsdCkscmVzdGUpID0gbGlzdGVfbnRoIG0gcCBpbiB0LHJlc3RlCjs7CmNob2lzaXJfY291bGV1ciBsYzs7KikKCmxldCByZWN1cGVyZV9jYXJ0ZXMgKHRtIDogdGFibGVfbWVudGV1cikgbiA6IHRhYmxlX21lbnRldXI9IAogIGxldCAoaixvMSxvMixvMyxjLGNsKSA9IHRtIGluCiAgbWF0Y2ggbiB3aXRoCiB8MCAtPiAoZW1waWxlcl9jYXJ0ZXMgY2wgaixvMSxvMixvMyxjLFtdKQogfDEgLT4gKGosZW1waWxlcl9jYXJ0ZXMgY2wgbzEsbzIsbzMsYyxbXSkKIHwyIC0+IChqLG8xLGVtcGlsZXJfY2FydGVzIGNsIG8yLG8zLGMsW10pCiB8MyAtPiAoaixvMSxvMixlbXBpbGVyX2NhcnRlcyBjbCBvMyxjLFtdKQogfF8gLT4gZmFpbHdpdGggIkpvdWV1ciBpbmV4aXN0YW50Igo7OwoKCmxldCBqb3Vlcl9vcmRpbmF0ZXVyX2FjY3VzYXRldXIgbiAodG0gOiB0YWJsZV9tZW50ZXVyKSA9CiAgbWF0Y2ggdG0gd2l0aAogfF8sXyxfLF8sYyxbXSAtPiBmYWlsd2l0aCAiT3JkcmUgZHUgam91ZXVyIgogfF8sXyxfLF8sYywoQyhyLHQpKTo6dGEgd2hlbiBjID0gdCAtPiBwcmludF9lbmRsaW5lICJMJ2FjY3VzYXRldXIgYSBwZXJkdS4gSWwgcmVjdXBlcmUgdG91dGVzIGxlcyBjYXJ0ZXMuIjsKCQkJCSAgIHJlY3VwZXJlX2NhcnRlcyB0bSBuLChwcmVjIG4pCiB8XyAtPiBwcmludF9lbmRsaW5lICJMJ2FjY3VzYXRldXIgYSBnYWduZS4gTGUgam91ZXVyIGFjY3VzZSByZWN1cGVyZSB0b3V0ZXMgbGVzIGNhcnRlcy4iOwoJCQlyZWN1cGVyZV9jYXJ0ZXMgdG0gKHByZWMgbiksbgo7OwoKbGV0IGpvdWVyX29yZGluYXRldXIgbygqb3JkcmUgZHUgam91ZXVyKikgbigqbnVtw6lybyBkZSBsJ29yZGluYXRldXIqKSAKKHRtIDogdGFibGVfbWVudGV1cikgOiB0YWJsZV9tZW50ZXVyKmludCA9CiAgUmFuZG9tLnNlbGZfaW5pdCgpOwogIG1hdGNoIG8gd2l0aAogfDEgLT4gam91ZXJfb3JkaW5hdGV1cl9wb3NlMSBuIHRtLDQKIHwyIC0+IChsZXQgeCA9IFJhbmRvbS5pbnQgMiBpbgoJbWF0Y2ggeCB3aXRoCiAgICAgICB8MCAtPiBqb3Vlcl9vcmRpbmF0ZXVyX3Bvc2UgbiB0bSw0CiAgICAgICB8XyAoKmRvbmMgMSopIC0+IHByaW50X3N0cmluZyAiTGUgam91ZXVyICI7CgkgICAgICAgICAgICAgICAgcHJpbnRfaW50IG47CgkJCXByaW50X2VuZGxpbmUgIiBhY2N1c2UgISI7CgkJCWpvdWVyX29yZGluYXRldXJfYWNjdXNhdGV1ciBuIHRtKQogfF8gLT4gZmFpbHdpdGggIkxhIHBhcnRpZSBlc3QgZMOpasOgIGZpbmllICEiCjs7CiAgCigqRmFpcmUgam91ZXIgbGUgam91ZXVyIDogb24gbHVpIGRpdCBjb21iaWVuIGRlIGNhcnRlcyBkZSBjaGFxdWUgY291bGV1ciBpbCBhLgpJbCBzdWZmaXQgZG9uYyBxdSdpbCBkaXNlIGxhIGNvdWxldXIgZGUgbGEgY2FydGUgcXUnaWwgdmV1dCBqb3VlciBwb3VyIGpvdWVyLiopCmxldCByZWMgY291bGV1cl9vZl9zdHJpbmcgcyA9IAogIG1hdGNoIHMgd2l0aAogfCJDb2V1ciIgLT4gQ29ldXIKIHwiQ2FycmVhdSIgLT4gQ2FycmVhdQogfCJUcmVmbGUiIC0+IFRyZWZsZQogfCJQaXF1ZSIgLT4gUGlxdWUKIHxfIC0+IHByaW50X2VuZGxpbmUgIkNlY2kgbidlc3QgcGFzIHVuZSBjb3VsZXVyLiBDaG9pc2lzc2V6IHVuZSBjb3VsZXVyLCBzJ2lsIHZvdXMgcGxhaXQgISI7CiAgIGxldCBucyA9IHJlYWRfbGluZSgpIGluIGNvdWxldXJfb2Zfc3RyaW5nIG5zCjs7CgoKbGV0IHJlYyBzZWxlY3Rpb25uZXJfY2FydGVfZXhpc3RhbnRlIGMgbGMgPSAKIG1hdGNoIGxjIHdpdGgKICAgfFtdIC0+IGZhaWx3aXRoICJQYXMgZGUgY2FydGUgZGUgY2V0dGUgY291bGV1ciAhIgogICB8KEMocix0KSk6OnRhIHdoZW4gdCA9IGMgLT4gKEMocix0KSksdGEKICAgfGg6OnQgLT4gbGV0IGNhcnRlLHJlc3RlID0gc2VsZWN0aW9ubmVyX2NhcnRlX2V4aXN0YW50ZSBjIHQgaW4gY2FydGUsaDo6cmVzdGUKOzsKbGM7OwoKbGV0IHJlYyBzZWxlY3Rpb25uZXJfY2FydGUgYyBsYyA9IAp0cnkgKHNlbGVjdGlvbm5lcl9jYXJ0ZV9leGlzdGFudGUgYyBsYykgd2l0aAogIHxGYWlsdXJlICJQYXMgZGUgY2FydGUgZGUgY2V0dGUgY291bGV1ciAhIiAtPiBwcmludF9lbmRsaW5lICJWb3VzIG4nYXZleiBwYXMgZGUgY2FydGVzIGRlIGNldHRlIGNvdWxldXIuIENob2lzaXNzZXogdW5lIGF1dHJlIGNvdWxldXIsIHMnaWwgdm91cyBwbGFpdCAhIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzID0gcmVhZF9saW5lKCkgaW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGlvbm5lcl9jYXJ0ZSAoY291bGV1cl9vZl9zdHJpbmcgcykgbGMKOzsKICAKKCpzZWxlY3Rpb25uZXJfY2FydGUgKGNvdWxldXJfb2Zfc3RyaW5nICJDYXJyZWF1IikgbGM7OyopCgpsZXQgYWZmaWNoZV9tYWluICh0bSA6IHRhYmxlX21lbnRldXIpID0KICAgICAgbGV0IChqLG8xLG8yLG8zLGMsY2QpID0gdG0gaW4KICAgICAgbGV0IChjbyxjYSx0LHApID0gY29tcHRlX2NvdWxldXJzIGogaW4gCiAgICAgIHByaW50X3N0cmluZyAiVm90cmUgbWFpbiA6ICI7CiAgICAgIHByaW50X2ludCBjbzsKICAgICAgcHJpbnRfc3RyaW5nIiBjYXJ0ZShzKSBkZSBDb2V1ciwgIjsKICAgICAgcHJpbnRfaW50IGNhOwogICAgICBwcmludF9zdHJpbmciIGNhcnRlKHMpIGRlIENhcnJlYXUsICI7CiAgICAgIHByaW50X2ludCB0OwogICAgICBwcmludF9zdHJpbmcgIiBjYXJ0ZShzKSBkZSBUcmVmbGUsICI7CiAgICAgIHByaW50X2ludCBwOwogICAgICBwcmludF9zdHJpbmcgIiBjYXJ0ZShzKSBkZSBQaXF1ZS4gIgo7OwpsYzs7CigqYWZmaWNoZV9tYWluIChsYyxbXSxbXSxbXSxUcmVmbGUsW10pOzsqKQoKbGV0IGpvdWVyX2pvdWV1cl9wb3NlciAodG0gOiB0YWJsZV9tZW50ZXVyKSA6IHRhYmxlX21lbnRldXIgPSAKICBsZXQgKGosbzEsbzIsbzMsYyxjZCkgPSB0bSBpbgogICAgICBwcmludF9lbmRsaW5lICJDaG9pc2lzc2V6IHVuZSBjb3VsZXVyLCBzJ2lsIHZvdXMgcGxhaXQuIjsKICAgICAgbGV0IHMgPSByZWFkX2xpbmUoKSBpbgogICAgICAgICAgbGV0IG5jID0gY291bGV1cl9vZl9zdHJpbmcgcyBpbgogICAgICAgICAgICAgICAgICBsZXQgY2FydGUsbmogPSBzZWxlY3Rpb25uZXJfY2FydGUgbmMgaiBpbiAKICAgICAgICAgICAgICAgICAgICAgKG5qLG8xLG8yLG8zLG5jLGNhcnRlOjpjZCkKOzsKCmxldCBqb3Vlcl9qb3VldXJfcG9zZXIxICh0bSA6IHRhYmxlX21lbnRldXIpIDogdGFibGVfbWVudGV1ciA9IAogIGxldCAoaixvMSxvMixvMyxjLGNkKSA9IHRtIGluCiAgICAgIHByaW50X2VuZGxpbmUgIkNob2lzaXNzZXogdW5lIGNvdWxldXIgYSBhbm5vbmNlciwgcydpbCB2b3VzIHBsYWl0LiI7CiAgICAgIGxldCBzID0gcmVhZF9saW5lKCkgaW4KICAgICAgICAgIGxldCBuYyA9IGNvdWxldXJfb2Zfc3RyaW5nIHMgaW4gCgkgICAgICBqb3Vlcl9qb3VldXJfcG9zZXIgKGosbzEsbzIsbzMsbmMsY2QpCjs7CgpsZXQgYWZmaWNoZV9jYXJ0ZSBjID0gCiAgbGV0IEMocix0KSA9IGMgaW4KICBwcmludF9zdHJpbmcgKChzdHJpbmdfb2ZfbnVtIHIpXiIgIl4oc3RyaW5nX29mX2NvdWxldXIgdCkpCjs7CigqYWZmaWNoZV9jYXJ0ZSAoQygxMyxQaXF1ZSkpOzsqKQoKbGV0IGpvdWVyX2pvdWV1cl9hY2N1c2VyICh0bSA6IHRhYmxlX21lbnRldXIpIDogdGFibGVfbWVudGV1cippbnQgKCpfLGcqKSA9CiBtYXRjaCB0bSB3aXRoCiB8XyxfLF8sXyxjLFtdIC0+IGZhaWx3aXRoICJPcmRyZSBkdSBqb3VldXIiCiB8XyxfLF8sXyxjLChDKHIsdCkpOjp0YSB3aGVuIGMgPSB0IC0+IHByaW50X3N0cmluZyAiVm91cyBhdmV6IG1lbnRpICEgTGEgY2FydGUgcG9zZWUgZXRhaXQgIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWZmaWNoZV9jYXJ0ZSAoQyhyLHQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRfZW5kbGluZSAgIi4gVm91cyByZWN1cGVyZXogdG91dGVzIGxlcyBjYXJ0ZXMuIjsKCQkJCSAgICAgICByZWN1cGVyZV9jYXJ0ZXMgdG0gMCwzCiB8XyxfLF8sXyxjLChDKHIsdCkpOjp0YSAtPiBwcmludF9zdHJpbmcgIlZvdXMgYXZleiBnYWduZSAhIExhIGNhcnRlIHBvc2VlIGV0YWl0ICI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFmZmljaGVfY2FydGUgKEMocix0KSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW50X2VuZGxpbmUgICIuIExlIGpvdWV1ciBhY2N1c2UgcmVjdXBlcmUgdG91dGVzIGxlcyBjYXJ0ZXMuIjsKCQkJcmVjdXBlcmVfY2FydGVzIHRtIDMsMAo7OwoKbGV0IGpvdWVyX2pvdWV1ciBvICh0bSA6IHRhYmxlX21lbnRldXIpIDogdGFibGVfbWVudGV1cippbnQgPSAKICBsZXQgKGosbzEsbzIsbzMsYyxjbCkgPSB0bSBpbgogbWF0Y2ggbyB3aXRoCnwxIC0+IGFmZmljaGVfbWFpbiB0bTsKICAgICAgam91ZXJfam91ZXVyX3Bvc2VyMSB0bSw0CnwyIC0+IGFmZmljaGVfbWFpbiB0bTsKICAgICAgcHJpbnRfbmV3bGluZSgpOwogICAgICBwcmludF9lbmRsaW5lICgiTGEgY291bGV1ciBhbm5vbmNlZSBlc3QgOiAiXihzdHJpbmdfb2ZfY291bGV1ciBjKV4iLiIpOwogICAgICBwcmludF9lbmRsaW5lICJRdWUgdm91bGV6IHZvdXMgZmFpcmUgPyI7CiAgICAgIHByaW50X2VuZGxpbmUgIjEgLSBQb3NlciB1bmUgY2FydGUiOwogICAgICBwcmludF9lbmRsaW5lICIyIC0gQWNjdXNlciBsZSBqb3VldXIgcHJlY2VkZW50IjsKICAgICAgbGV0IG4gPSByZWFkX2ludCgpIGluCiAgICAgICAgICAgbGV0IHJlYyBhdXggPSBmdW5jdGlvbgoJICB8MSAtPiBqb3Vlcl9qb3VldXJfcG9zZXIgdG0sNAogICAgICAgICAgfDIgLT4gam91ZXJfam91ZXVyX2FjY3VzZXIgdG0KCSAgfF8gLT4gcHJpbnRfZW5kbGluZSAiQ2VjaSBuJ2VzdCBwYXMgdW4gY2hvaXggcHJvcG9zZS4gUXVlbCBlc3Qgdm90cmUgY2hvaXggPyI7IAogICAgICAgICAgICBsZXQgayA9IHJlYWRfaW50KCkgaW4gYXV4IGsKICAgICAgICAgICBpbgoJICAgYXV4IG4KfF8gLT4gZmFpbHdpdGggIkNlY2kgbidlc3QgcGFzIHVuIG9yZHJlIHZhbGFibGUgISIKOzsKCmxldCBpbml0X21lbnRldXIoKSA9IAogICBSYW5kb20uc2VsZl9pbml0ICgpOwogICBsZXQgdG0gPSBjcmVlcl9tZW50ZXVyKCkgaW4KICAgbGV0IG4gPSBSYW5kb20uaW50IDQgaW4gCiAgICAgbWF0Y2ggbiB3aXRoCiAgICAgfDAgLT4gam91ZXJfam91ZXVyIDEgdG0sKG5leHQgbikKICAgICB8MSAtPiBqb3Vlcl9vcmRpbmF0ZXVyIDEgMSB0bSwobmV4dCBuKQogICAgIHwyIC0+IGpvdWVyX29yZGluYXRldXIgMSAyIHRtLChuZXh0IG4pCiAgICAgfF8gLT4gam91ZXJfb3JkaW5hdGV1ciAxIDMgdG0sKG5leHQgbikKOzsoKnRhYmxlLGdhZ25hbnQsbiopCgpsZXQgZGVidXRfbWFuY2hlICh0bSA6IHRhYmxlX21lbnRldXIpIGcgPSAKICBtYXRjaCBnIHdpdGgKIHwwIC0+IGpvdWVyX2pvdWV1ciAxIHRtLChuZXh0IGcpCiB8XyAtPiBqb3Vlcl9vcmRpbmF0ZXVyIDEgZyB0bSwobmV4dCBnKQo7OygqdGFibGUsZ2FnbmFudCxuKikKCmxldCBtYW5jaGUgKHRtIDogdGFibGVfbWVudGV1cikgbiA9CiAgbWF0Y2ggbiB3aXRoCiB8MCAtPiBqb3Vlcl9qb3VldXIgMiB0bSwobmV4dCBuKQogfF8gLT4gam91ZXJfb3JkaW5hdGV1ciAyIG4gdG0sKG5leHQgbikKIDs7KCp0YWJsZSxnYWduYW50LG4qKQogIAooKklsIGZhdXQgYXNzdXJlciBsJ2jDqXLDqWRpdMOpLiAKVGVzdCA6IHRhbnQgcXUnYXVjdW4gZGVzIDQgdGFzIG4nZXN0IHZpZGUsIG9uIGNvbnRpbnVlIMOgIGpvdWVyLgpDb250aW51ZXIgw6Agam91ZXIgOiBmb25jdGlvbiB0bSAtPiB0bSopCgooKlBST0JMRU1FIDogY29tbWVudCBkaWZmw6lyZW5jaWVyIGxlcyBtYW5jaGVzID8hIFBvdXIgbGUgbW9tZW50LCBhcHLDqHMgbCdhY2N1c2F0aW9uLApsZSBqZXUgY29udGludWUsIGV0IG9uIG5lIHJldmllbnQgamFtYWlzIMOgIGwnb3JkcmUgMCwgZCdvw7kgbGUgcHJvYmzDqG1lLiopCgpsZXQgcmVjIGpldV9tZW50ZXVyICh0bSA6IHRhYmxlX21lbnRldXIpIG4gZyBqID0gCiAgcHJpbnRfbmV3bGluZSgpOwogIGlubmFfYWZmaWNoZV90YWJsZV9tZW50ZXVyIHRtOwogIHByaW50X25ld2xpbmUoKTsKICBtYXRjaCB0bSB3aXRoCiAgfFtdLF8sXyxfLF8sXyAtPiBwcmludF9lbmRsaW5lICJGZWxpY2l0YXRpb25zICEgVm91cyBhdmV6IGdhZ25lIGxhIHBhcnRpZS4iOwogICAgICAgICAgICAgICAgICAgai5jcmVkaXQgPC0gai5jcmVkaXQgKyAxCiAgfF8sW10sXyxfLF8sXyB8XyxfLFtdLF8sXyxfIHxfLF8sXyxbXSxfLF8gLT4gcHJpbnRfZW5kbGluZSAiTWFsaGV1cmV1c2VtZW50LCB2b3VzIGF2ZXogcGVyZHUgLi4uIiAKICB8XyxfLF8sXyxfLFtdIC0+IGxldCAobnRtLG5nKSxtID0gZGVidXRfbWFuY2hlIHRtIGcgaW4KCQkgICBqZXVfbWVudGV1ciBudG0gbSBuZyBqCiAgfF8gLT4gbGV0IChudG0sbmcpLG0gPSBtYW5jaGUgdG0gbiBpbgogICAgICAgIGpldV9tZW50ZXVyIG50bSBtIG5nIGoKOzsKbGV0IHRhYmxlMSA9IFtdLFtDKDEsUGlxdWUpXSxbQygyLFBpcXVlKV0sW0MoMyxQaXF1ZSldLFRyZWZsZSxbXTs7ICAKbGV0IHRhYmxlMiA9IFtDKDEsUGlxdWUpXSxbXSxbQygyLFBpcXVlKV0sW0MoMyxQaXF1ZSldLFRyZWZsZSxbXTs7ICAKbGV0IHRhYmxlMyA9IFtDKDEwLFBpcXVlKV0sW0MoMSxQaXF1ZSldLFtDKDIsUGlxdWUpXSxbQygzLFBpcXVlKV0sVHJlZmxlLFtdOzsgIAooKmpldV9tZW50ZXVyIHRhYmxlMiAwIDA7OwpqZXVfbWVudGV1ciB0YWJsZTEgMCAwOzsKamV1X21lbnRldXIgdGFibGUzIDIgMTs7KikKCmxldCBqb3VlX21lbnRldXIgaiA9IAogIHByaW50X2VuZGxpbmUgIioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiI7CiAgcHJpbnRfZW5kbGluZSAiKiAgICAgICAgICAgICAgICAgTWVudGV1ciAgICAgICAgICAgICAgICAqIjsKICBwcmludF9lbmRsaW5lICIqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioiOwogIGxldCAodG0sZyksbiA9IGluaXRfbWVudGV1cigpIGluCiAgamV1X21lbnRldXIgdG0gbiBnIGoKOzsKajs7ICAKKCpqb3VlX21lbnRldXIgajs7KikKCgoKCigqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipCYXRhaWxsZSoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKikKdHlwZSB0YWJsZV9iYXRhaWxsZSA9IGNhcnRlIGxpc3QgKiBjYXJ0ZSBsaXN0ICogY2FydGUgbGlzdCAqIGNhcnRlIGxpc3Q7OwoKbGV0IGNyZWVyX2JhdGFpbGxlIG4gOiB0YWJsZV9iYXRhaWxsZSA9IAogIG1hdGNoIG4gd2l0aAogfG0gd2hlbiBtID4gMSAtPiAKICAgbGV0IGpldSA9IEMoMSxDb2V1cik6OkMoMSxQaXF1ZSk6OihnZW5lcmVfbWluaV9qZXUgbikgaW4KICAgbGV0IGpldW0gPSBtZWxhbmdlciBqZXUgaW4gCiAgIGxldCB0MSx0MiA9IGRpc3RyaWJ1ZSBqZXVtIGluICh0MSx0MixbXSxbXSkKIHxfIC0+IGxldCBqZXUgPSBnZW5lcmVfamV1KCkgaW4KICAgICAgIGxldCBqZXVtID0gbWVsYW5nZXIgamV1IGluIAogICAgICAgbGV0IHQxLHQyID0gZGlzdHJpYnVlIGpldW0gaW4gKHQxLHQyLFtdLFtdKQo7OwpjcmVlcl9iYXRhaWxsZSAxMzs7CgoKKCoKamV1IG5vcm1hbCA6IHRhYmxlX2JhdGFpbGxlIC0+IHRhYmxlX2JhdGFpbGxlLGJvb2wgKGoxIGdhZ25lKSxib29sIChqMiBnYWduZSkgOgp0YiA9IChjc2oxLGNzajIsaDE6OnQxLGgyOjp0MikKU2kgY3NqMSA9IFtdIG9uIHMnYXJyw6p0ZSBldCBKMSBhIGdhZ27DqS4KU2kgY3NqMiA9IFtdIG9uIHMnYXJyw6p0ZSBldCBKMiBhIGdhZ27DqS4KU2lub24gOiAKY3NqMSA9IGhhOjp0YSwgY3NqMiA9IGhiOjp0YgpTaSBoYSA+IGhiLCBsZSBqb3VldXIgMSByw6ljdXDDqHJlIGxlcyBkZXV4IHRhcyAoaWwgZmF1dCBsZXMgbcOpbGFuZ2VyIGF2YW50IGRlIGxlcwpham91dGVyIMOgIGxhIGZpbiBkdSBwYXF1ZXQgZHUgam91ZXVyIDEpLgpTaSBoYSA8IGhiLCBsZSBqb3VldXIgMiByw6ljdXDDqHJlIGxlcyBkZXV4IHRhcy4KU2kgaGEgPSBoYiwgYWxvcnMgYmF0YWlsbGUuKikKKCpiYXRhaWxsZSA6IHRhYmxlX2JhdGFpbGxlIC0+IHRhYmxlX2JhdGFpbGxlIDogCkRlc2NyaXB0aW9uIHByw6ljaXNlIGRlIGxhIGJhdGFpbGxlIDogCnRiID0gKGNzajEsY3NqMix0ZXRlMTo6cTEsdGV0ZTI6OnEyKQp0ZXRlMSA9IHRldGUyCk9uIHbDqXJpZmllIDogc2kgY3NqMSA9IGhhMTo6aGEyOjp0YSBldCBjc2oyID0gaGIxOjpoYjI6OnRiLCBhbG9ycyBvbiBsYW5jZSBsZSBqZXUgCiJub3JtYWwiIHN1ciB0bmIgPSAodGEsdGIsaGExOjpoYTI6OnRldGUxOjpxMSxoYjE6OmhiMjo6dGV0ZTI6OnEyKQpTaW5vbiA6IGxlcyBqb3VldXJzIHNvbnQgZMOpY2xhcsOpcyBleC1hZXF1bywgZXQgbGEgcGFydGllIGVzdCBmaW5pZS4KKikKbGV0IGVnYWwgYzEgYzIgPSAKICBsZXQgQyhyMSx0MSkgPSBjMSBhbmQgQyhyMix0MikgPSBjMiBpbiByMSA9IHIyOzsKCmxldCBzdXBlcmlldXIgYzEgYzIgPSAKICBsZXQgQyhyMSx0MSkgPSBjMSBhbmQgQyhyMix0MikgPSBjMiBpbgogIG1hdGNoIHIxIHdpdGgKIHwxIC0+IG5vdCAocjIgPSAxKQogfHIgd2hlbiByID4gcjIgLT4gKG1hdGNoIHIyIHdpdGgKICAgICAgICAgICAgICAgICAgfDEgLT4gZmFsc2UKCQkgIHxfIC0+IHRydWUpCiB8XyAtPiBmYWxzZQo7OwpzdXBlcmlldXIgKEMoMixUcmVmbGUpKSAoQygxLFRyZWZsZSkpOzsKCigqbGM7OwpMaXN0Lmxlbmd0aCBsYzs7CmFmZmljaGVfbGlzdGVfY2FydGVzOzsqKQooKgpsZXQgaW5mZXJpZXVyIGMxIGMyID0gc3VwZXJpZXVyIGMyIGMxOzsKaW5mZXJpZXVyIChDKDIsVHJlZmxlKSkgKEMoMSxUcmVmbGUpKTs7KikKCgoKbGV0IHJlYyB0b3VyX2JhdGFpbGxlICh0YWJsZV9iIDogdGFibGVfYmF0YWlsbGUpIChqIDogam91ZXVyKSAgPSAKICBsZXQgcmVjIGJhdGFpbGxlID0gZnVuY3Rpb24KICAgICAgfChfLF8sW10sW10pIC0+IGZhaWx3aXRoICJDZWNpIG4nZXN0IHBhcyB1biBjYXMgZGUgYmF0YWlsbGUiCiAgICAgIHwoajEsajIsaDE6OnQxLGgyOjp0Mikgd2hlbiAoZWdhbCBoMSBoMikgLT4gKG1hdGNoIGoxLGoyIHdpdGgKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxoYTE6OmhhMjo6dGEsaGIxOjpoYjI6OnRiIC0+IAoJCSAgICB0b3VyX2JhdGFpbGxlICh0YSx0YixoYTE6OmhhMjo6aDE6OnQxLGhiMTo6aGIyOjpoMjo6dDIpIGogCgkJCQkgICAgICAgICAgICB8XyAtPiBwcmludF9lbmRsaW5lICJFZ2FsaXRlICEgTWFpcyBsJ2VnYWxpdGUgbidlc3QgcGFzIHVuZSB2aWN0b2lyZSAuLi4iOwoJCQkJCSAgICAgICAgICApCiAgICAgIHxfIC0+IGZhaWx3aXRoICJDZWNpIG4nZXN0IHBhcyB1biBjYXMgZGUgYmF0YWlsbGUiCiAgaW4KICBtYXRjaCB0YWJsZV9iIHdpdGgKIHwoW10sXyxfLF8pIC0+cHJpbnRfZW5kbGluZSAiVm91cyBuJ2F2ZXogcGx1cyBkZSBjYXJ0ZXMuIE1hbGhldXJldXNlbWVudCwgdm91cyBhdmV6IHBlcmR1IC4uLiI7CiB8KGoxLFtdLF8sXykgLT5wcmludF9zdHJpbmcgIlZvdXMgYXZleiAiOwogICAgICAgICAgICAgICAgcHJpbnRfaW50IChMaXN0Lmxlbmd0aCBqMSk7CgkJcHJpbnRfZW5kbGluZSAoIiBjYXJ0ZShzKSwgYWxvcnMgcXVlIHZvdHJlIGFkdmVyc2FpcmUgbidlbiBhIHBsdXMuIEZlbGljaXRhdGlvbnMgIl4oai5wcmVub20pXiIsIHZvdXMgYXZleiBnYWduZSAhIik7CiAgICAgICAgICAgICAgICBqLm5icmVfYmF0YWlsbGVzX2dhZ25lZXMgPC0gai5uYnJlX2JhdGFpbGxlc19nYWduZWVzICsgMTsKIHwoaGE6OnRhLGhiOjp0YixbXSxbXSkgLT4gKHByaW50X3N0cmluZyAiVm91cyBhdmV6ICI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW50X2ludCAoTGlzdC5sZW5ndGggKGhhOjp0YSkpOwoJCQkgICBwcmludF9lbmRsaW5lICIgY2FydGUocykuIjsKCQkJICAgcHJpbnRfc3RyaW5nICJWb3RyZSBhZHZlcnNhaXJlIGEgIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRfaW50IChMaXN0Lmxlbmd0aCAoaGI6OnRiKSk7CgkJCSAgIHByaW50X2VuZGxpbmUgIiBjYXJ0ZShzKS4iOwoJCQkgICBwcmludF9zdHJpbmcgIk9uIG9wcHBvc2UgIjsKCQkJICAgYWZmaWNoZV9jYXJ0ZSBoYTsKCQkJICAgcHJpbnRfc3RyaW5nICIgYSAiOwoJCQkgICBhZmZpY2hlX2NhcnRlIGhiOwogICAgICAgICAgICAgICAgICAgICAgICAgICB0b3VyX2JhdGFpbGxlICh0YSx0YixbaGFdLFtoYl0pIGopCiB8KGoxLGoyLGhhOjp0YSxoYjo6dGIpIHdoZW4gKHN1cGVyaWV1ciBoYSBoYikgLT4gCiAgICAgICAgICggcHJpbnRfZW5kbGluZSAiLiBWb3VzIGdhZ25leiBsZXMgY2FydGVzICEiOwogICAgICAgICAgbGV0IHRhcyA9IG1lbGFuZ2VyIChlbXBpbGVyX2NhcnRlcyAoaGE6OnRhKSAoaGI6OnRiKSkgaW4KICB0b3VyX2JhdGFpbGxlICgoZW1waWxlcl9jYXJ0ZXMgdGFzIGoxKSxqMixbXSxbXSkgagogICAgICAgICAgKQogfChqMSxqMixoYTo6dGEsaGI6OnRiKSB3aGVuIChzdXBlcmlldXIgaGIgaGEpIC0+IAogICAgICAgICAoIHByaW50X2VuZGxpbmUgIi4gVm90cmUgYWR2ZXJzYWlyZSBnYWduZSBsZXMgY2FydGVzLiI7CiAgICAgICAgICBsZXQgdGFzID0gbWVsYW5nZXIgKGVtcGlsZXJfY2FydGVzIChoYTo6dGEpIChoYjo6dGIpKSBpbgogIHRvdXJfYmF0YWlsbGUgKGoxLChlbXBpbGVyX2NhcnRlcyB0YXMgajIpLFtdLFtdKSBqCiAgICAgICAgICApIAogfF8gLT4gcHJpbnRfc3RyaW5nICIuIEJBVEFJTExFICEhISAiOwogICAgICAgYmF0YWlsbGUgdGFibGVfYgo7OwoKbGV0IGpvdWVfYmF0YWlsbGUgaiA9IAogIHByaW50X2VuZGxpbmUgIioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiI7CiAgcHJpbnRfZW5kbGluZSAiKiAgICAgICAgICAgICAgICBCYXRhaWxsZSAgICAgICAgICAgICAgICAqIjsKICBwcmludF9lbmRsaW5lICIqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioiOwogIGlmIGouY3JlZGl0ID0gMCB0aGVuIChwcmludF9lbmRsaW5lICJOb3VzIHNvbW1lcyBkZXNvbGVzLCBtYWlzIHZvdXMgbidhdmV6IHBhcyBhc3NleiBkZSBqZXRvbnMgcG91ciBqb3VlciAuLi4gcmV2ZW5leiBwbHVzIHRhcmQgISI7CiAgICAgICAgICAgICAgICAgICAgICAgKQogIGVsc2UKICAoai5jcmVkaXQgPC0gai5jcmVkaXQgLSAxOwogIHByaW50X2VuZGxpbmUgIlF1ZWxsZSBlc3QgbGEgdGFpbGxlIGR1IG1pbmktamV1IHN1ciBsZXF1ZWwgdm91cyBzb3VoYWl0ZXogdm9pciBzZSBkZXJvdWxlciBsYSBiYXRhaWxsZSA/IEVudHJleiBsYSBwbHVzIHBldGl0ZSB2YWxldXIgZGlzcG9uaWJsZS4iOwogIGxldCBuID0gcmVhZF9pbnQoKSBpbiAKICBsZXQgdGIgPSBjcmVlcl9iYXRhaWxsZSBuIGluCiAgdG91cl9iYXRhaWxsZSB0YiBqKQo7OwooKmouY3JlZGl0IDwtIGouY3JlZGl0ICsgMTs7CmpvdWVfYmF0YWlsbGUgajs7CiopCgooKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqVHJpY2hlKioqKioqKioqKioqKioqKioqKioqKioqKQoKKCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqVGVybWluYWwqKioqKioqKioqKioqKioqKioqKioqKikKCmxldCByZWMgaW5uYV9tZW51X3ByaW5jaXBhbCBqID0KICAgcHJpbnRfc3RyaW5nICgiQm9uam91ciAiXihqLnByZW5vbSleIiAhIFZvdXMgYXZleiAiKTsKICAgcHJpbnRfaW50IGouY3JlZGl0OwogICBwcmludF9zdHJpbmcgIiBqZXRvbihzKS4gVm91cyBhdmV6IGdhZ25lICI7CiAgIHByaW50X2ludCBqLm5icmVfYmF0YWlsbGVzX2dhZ25lZXM7CiAgIHByaW50X2VuZGxpbmUgIiBwYXJ0aWUocykgZGUgYmF0YWlsbGUuIjsKICAgcHJpbnRfZW5kbGluZSAiUXVlIHZvdWxlei12b3VzIGZhaXJlID8iOwogICBwcmludF9lbmRsaW5lICIxLiBKb3VlciBhdSBibGFja2phY2siOwogICBwcmludF9lbmRsaW5lICIyLiBKb3VlciBhdSBtZW50ZXVyIjsKICAgcHJpbnRfZW5kbGluZSAiMy4gSm91ZXIgYSBsYSBiYXRhaWxsZSI7CiAgIHByaW50X2VuZGxpbmUgIjQuIFRyaWNoZXIgKGMnZXN0IHBhcyBiaWVuICEpIjsgICAgCiAgIHByaW50X2VuZGxpbmUgIjUuIFF1aXR0ZXIiOwogICB0cnkgCiAgIGxldCBpID0gcmVhZF9pbnQoKSBpbiAKICAgbGV0IHJlYyBhdXggPSBmdW5jdGlvbgogIHwxIC0+IGpvdWVyX2JsYWNramFjayBqOwogICAgICAgIGlubmFfbWVudV9wcmluY2lwYWwgagogIHwyIC0+IGpvdWVfbWVudGV1ciBqOwogICAgICAgIGlubmFfbWVudV9wcmluY2lwYWwgagogIHwzIC0+IGpvdWVfYmF0YWlsbGUgajsKICAgICAgICBpbm5hX21lbnVfcHJpbmNpcGFsIGoKICB8NCAtPiBsZXQgbWVudV90cmljaGUgam91ZXVyID0gCgkgIHByaW50X2VuZGxpbmUgIkJpZW52ZW51ZSwgY2hlciB0cmljaGV1ciAhIFF1ZWxsZSBlc3QgbCdhaWRlIHF1ZSB2b3VzIGFpbWVyaWV6IG9idGVuaXIgPyI7CgkgIHByaW50X2VuZGxpbmUgIjEuIFJlZ2FyZGVyIGxhIGNhcnRlIHBvc2VlIHBhciBsJ2FkdmVyc2FpcmUgYXZhbnQgZGUgc2UgcHJvbm9uY2VyIGR1cmFudCB1bmUgcGFydGllIGRlIG1lbnRldXIiOyAKCSAgcHJpbnRfZW5kbGluZSAiMi4gT2J0ZW5pciB1biBqZXRvbiBzdXBwbGVtZW50YWlyZSI7CgkgIHByaW50X2VuZGxpbmUgIjMuIE9idGVuaXIgYXUgbW9pbnMgZGV1eCBBcyBsb3JzIGRlIGxhIGRpc3RyaWJ1dGlvbiBkZXMgY2FydGVzIHBvdXIgbGEgYmF0YWlsbGUiOwoJICBwcmludF9lbmRsaW5lICI0LiBSZXZlbmlyIGF1IG1lbnUgcHJpbmNpcGFsIjsKCSAgKGxldCBsID0gcmVhZF9pbnQoKSBpbiAKCSAgbGV0IHJlYyBhdXhfdHJpY2hlID0gZnVuY3Rpb24KCSAgICB8MSAtPiBmYWlsd2l0aCAiTm90IGltcGxlbWVudGVkIgoJICAgIHwyIC0+IGpvdWV1ci5jcmVkaXQgPC0gam91ZXVyLmNyZWRpdCArIDE7CiAgICAgICAgICAgICAgICAgIGlubmFfbWVudV9wcmluY2lwYWwgam91ZXVyOwoJICAgIHwzIC0+IGZhaWx3aXRoICJOb3QgaW1wbGVtZW50ZWQiCgkgICAgfDQgLT4gaW5uYV9tZW51X3ByaW5jaXBhbCBqb3VldXI7CgkgICAgfF8gLT4oIHByaW50X2VuZGxpbmUgIk5vdXMgc29tbWVzIGRlc29sZXMsIG1haXMgY2UgY2hvaXggbidlc3QgcGFzIHByb3Bvc2UuIjsKICAgICAgICAgICAgICAgICAgIHByaW50X2VuZGxpbmUgIlF1ZSB2b3VsZXotdm91cyBmYWlyZSA/IjsKCQkgICBsZXQgbSA9IHJlYWRfaW50KCkgaW4gYXV4X3RyaWNoZSBtKQoJICAgICAgICAgICBpbiAKCSAgYXV4X3RyaWNoZSBsKSBpbgogICAgICAgICAgbWVudV90cmljaGUgagogIHw1IC0+IHByaW50X2VuZGxpbmUgIk1lcmNpIHBvdXIgdm90cmUgdmlzaXRlLiBFbiBlc3BlcmFudCB2b3VzIHJldm9pciBiaWVudG90ICEiCiAgfF8gLT4oIHByaW50X2VuZGxpbmUgIk5vdXMgc29tbWVzIGRlc29sZXMsIG1haXMgY2UgY2hvaXggbidlc3QgcGFzIHByb3Bvc2UuIjsKICAgICAgICBwcmludF9lbmRsaW5lICJRdWUgdm91bGV6LXZvdXMgZmFpcmUgPyI7CiAgICAgICAgbGV0IGsgPSByZWFkX2ludCgpIGluIGF1eCBrKQogICBpbiAKICAgYXV4IGkKICAgd2l0aCBGYWlsdXJlICJpbnRfb2Zfc3RyaW5nIiAtPmJlZ2luIHByaW50X3N0cmluZyAiaW5uYSBZb3VyIGNob2ljZSBpcyBub3QgdmFsaWRlLlJlcGVhdCwgcGxlYXNlOiI7aW5uYV9tZW51X3ByaW5jaXBhbCBqIGVuZAo7OwogICAgICAgCmxldCBtZW51X2RlYnV0KCkgPSAKICBwcmludF9lbmRsaW5lICIqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqIjsKICBwcmludF9lbmRsaW5lICIqICAgICAgQmllbnZlbnVlIGF1IEdhbWUgQ2VudGVyICEgICAgICAqIjsKICBwcmludF9lbmRsaW5lICIqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqIjsKICBwcmludF9lbmRsaW5lICJDb21tZW50IHZvdXMgYXBwZWxlei12b3VzID8iOwogIGxldCBzID0gcmVhZF9saW5lKCkgaW4gCiAgbGV0IGogPSB7cHJlbm9tID0gcyA7IGNyZWRpdCA9IDEgOyBuYnJlX2JhdGFpbGxlc19nYWduZWVzID0gMH0gaW4KICAgICAgaW5uYV9tZW51X3ByaW5jaXBhbCBqCjs7CgptZW51X2RlYnV0KCk7OwoK