############################################################################
# Pyth version 1.0.1 #
# 6-24-2014 #
# Changes from 1.0.0: Added backslash, improved sum, added [_], removed #
# str(), because repr() exists. ' is now in, ] is now [_], out of #
# similarity to }. #
# #
# This python program is an interpreter for the pyth programming language. #
# It is still in development - expect new versions often. #
# #
# To use, provide pyth code on one line of stdin. #
# Further input on further lines. #
# Prints out resultant python code for debugging purposes, then runs the #
# pyth program. #
# #
# More information: #
# The parse function takes a string of pyth code, and returns a single #
# python expression ready to be executed. #
# general_parse is the same but for multiple expressions. #
# This program also defines the built-ins that the resultant expression #
# uses, once expanded. #
############################################################################
def parse(code,spacing="\n "):
assert type(code)==type('')
# If we've reached the end of the string, give up.
if len(code)==0:
return '',''
# Separate active character from the rest of the code.
active_char=code[0]
rest_code=code[1:]
# Deal with numbers
if active_char in ".0123456789":
output=active_char
while (len(rest_code)>0
and rest_code[0] in ".0123456789"
and (output+rest_code[0]).count(".")<=1):
output+=rest_code[0]
rest_code=rest_code[1:]
return output,rest_code
# String literals
if active_char=='"':
output=active_char
while (len(rest_code)>0
and output.count('"')<2):
output+=rest_code[0]
rest_code=rest_code[1:]
if output[-1]!='"':
output+='"'
return output,rest_code
# Python code literals
if active_char=='$':
output=''
while (len(rest_code)>0
and rest_code[0]!='$'):
output+=rest_code[0]
rest_code=rest_code[1:]
return output,rest_code[1:]
# End paren is magic.
if active_char==')':
return '',rest_code
# Backslash is more magic.
if active_char=='\\':
if rest_code=='':
return '',''
else:
return '','\\'+rest_code
# Designated variables
if active_char in variables:
return active_char,rest_code
# Now for the two letter variables/functions
if active_char=='#':
assert len(rest_code)>0
return rest_code[0]*2,rest_code[1:]
# And for general functions
global c_to_f
global next_c_to_f
if active_char in c_to_f or active_char==',':
if active_char==',':
func_name=rest_code[0]*2
init_paren=True
arity=-1
rest_code=rest_code[1:]
else:
func_name,arity=c_to_f[active_char]
init_paren = (active_char not in no_init_paren)
# Swap what variables are used in the map, filter or reduce.
if active_char in next_c_to_f:
c_to_f[active_char]=next_c_to_f[active_char]
next_c_to_f[active_char]=c_to_f[active_char]
# Recurse until terminated by end paren or EOF
# or received enough arguments
args_list=[]
parsed='Not empty'
while len(args_list) != arity and parsed != '':
parsed,rest_code=parse(rest_code)
args_list.append(parsed)
# Build the output string.
py_code=func_name
if init_paren:
py_code+='('
if len(args_list)>0 and args_list[-1]=='':
args_list=args_list[:-1]
py_code+=','.join(args_list)
py_code+=')'
return py_code,rest_code
# General format functions/operators
# Also, comment characters, \, \n and \t
if active_char in c_to_i:
infixes,arity=c_to_i[active_char]
args_list=[]
parsed='Not empty'
while len(args_list) != arity and parsed != '':
parsed,rest_code=parse(rest_code)
args_list.append(parsed)
# Statements that cannot have anything after them
if active_char in end_statement:
rest_code=")"+rest_code
py_code=infixes[0]
for i in range(len(args_list)):
py_code+=args_list[i]
py_code+=infixes[i+1]
return py_code, rest_code
# Statements:
if active_char in c_to_s:
# Handle the initial portion (head)
infixes,arity=c_to_s[active_char]
args_list=[]
parsed='Not empty'
while len(args_list) != arity and parsed != '':
parsed,rest_code=parse(rest_code)
args_list.append(parsed)
part_py_code=infixes[0]
for i in range(len(args_list)):
part_py_code+=args_list[i]
part_py_code+=infixes[i+1]
# Handle the body - return ends object as well.
assert rest_code != ''
args_list=[]
parsed='Not empty'
while parsed != '':
parsed,rest_code=parse(rest_code,spacing+' ')
args_list.append(parsed)
# Trim the '' away and combine.
if args_list[-1]=='':
args_list=args_list[:-1]
all_pieces=[part_py_code]+args_list
return spacing.join(all_pieces),rest_code
print("Something's wrong.")
print("Current char is ",active_char)
print("The rest of the code is ",rest_code)
raise NotImplementedError
import random
import copy
import string
# Function library, descriptions of everything.
# += # ~ Y
# repr # ` Y
def _not(a):return not a # ! Y
# _[_] # @ Y
# # is special - 2 character variable Y
# $ is special - python literal Y
def mod(a,b):return a%b # % Y
# pow # ^ Y
# and # & Y
def times(a,b):return a*b # * Y
def _tuple(*a):return a # ( Y
# ) is special - end extensible Y
def minus(a,b):return a-b # - Y
def neg(a):return -a # _ Y
def plus(a,b):return a+b # + Y
# = deepcopy # = Y
copy = copy.deepcopy
def _list(*a):return list(a) # [ Y
# set # { Y
# [_] # ] Y
# dict # } Y
# or # | Y
# break out of all containing Y
# slice # : Y
def pop(a):return a.pop() # ; Y
# in # ' Y
# " is special - string literal Y
# , is special - 2 character function Y
def lt(a,b):return a<b # < Y
# . is special - numbers # . Y
def gt(a,b):return a>b # > Y
def div(a,b):return a//b # / Y
# if else # ? Y
# 0-9 are special - numbers # 0-9 Y
# (x) #| | Y
# all # A Y
# .append() # a Y
# break # B Y
b="\n" # b Y
# chr # C Y
def count(a,b):return a.count(b) # c Y
# def # D Y
# variable - associated with map # d Y
d='"'
# else # E Y
def lower(a):return a.lower() # e Y
# for # F Y
def _filter(a,b): # f Y
return list(filter(a,b))
# variable - associated with reduce # G Y
G=string.ascii_lowercase
def gte(a,b):return a>=b # g Y
# variable - associated with reduce # H Y
H={}
def read_file(): # h Y
a="\n".join(open(input()))
return a
# h assigns the text of the user
# inputted file to the variable given.
# if # I Y
def _round(a,b=None): # i Y
if b is None:
return float(a)
if b is 0:
return int(a)
return round(a,b)
# designated function # J Y
def join(a,b):return a.join(b) # j Y
# designated function # K Y
k='' # k Y
def lte(a,b):return a<=b # L Y
# len # l Y
# max # M Y
def _map(a,b):return list(map(a,b)) # m Y
N=None # N Y
# min # n Y
def rand(a,b): # O Y
return random.randint(a,b)
# ord # o Y
def split(a,b=None): # P Y
if b:
return a.split(b)
else:
return a.split()
# print # p Y
def quotient(a,b):return a/b # Q Y
def equal(a,b):return a==b # q Y
# return # R Y
def _range(a,b=None): # r Y
if b:
return list(range(a,b))
else:
return list(range(a))
# sorted # S Y
def _sum(a):
return reduce(lambda b,c:b+c,a) # s Y
# T is associated with filter # T Y
T=10
def tail(a):return a[1:] # t Y
def upper(a):return a.upper() # U Y
def reduce(a,b): # u Y
acc=b[0]
seq=b[1:]
while len(seq)>0:
h=seq[0]
acc=a(acc,h)
seq=seq[1:]
return acc
def rev(a): return a[::-1] # V Y
# eval(parse # v Y
# while # W Y
# input # w Y
def index(a,b): # X Y
if b in a:
return a.index(b)
# replicate functionality from str.find
else:
return -1
# exec(general_parse # x Y
Y=[] # Y Y
# any # y Y
Z=0 # Z Y
def _zip(a,b):return list(zip(a,b)) # z Y
no_init_paren='fmu'
end_statement='BR'
variables='bdGHkNTYZ'
# To do: even preassociated variables deserve to be initialized.
# Variables cheat sheet:
# b = "\n"
# d is for map, d='"'
# G is for reduce, G=string.ascii_lowercase (abc..xyz)
# H is for reduce, H = {}
# k = ''
# N = None, second option variable for map,filter,reduce
# T is for filter, second variable option for reduce, T=10
# Y = []
# Z = 0
c_to_s={
'D':(('def ',':'),1),
'E':(('else:'),0),
'F':(('for ',' in ',':'),2),
'I':(('if ',':'),1),
'W':(('while ',':'),1),
}
# Arbitrary format operators - use for assignment, infix, etc.
# All surrounding strings, arity
c_to_i={
'\\':(('',''),1),
'\n':(('',''),1),
'\t':(('',''),1),
'~':(('','+=',''),2),
'@':(('','[',']'),2),
'&':(('(',' and ',')'),2),
'|':(('(',' or ',')'),2),
'=':(('','=copy(',')'),2),
']':(('[',']'),1),
"'":(('(',' in ',')'),2),
'?':(('(',' if ',' else ',')'),3),
'a':(('','.append(',')'),2),
'B':(('break',),0),
'h':(('','=read_file()'),1),
'R':(('return ',''),1),
'x':(('exec(general_parse(','))'),1),
}
# Simple functions only.
# Extensible is allowed, nothing else complicated is.
# -1 means extensible
# name,arity
c_to_f={
'`':('repr',1),
'!':('_not',1),
'%':('mod',2),
'^':('pow',2),
'*':('times',2),
'(':('_tuple',-1),
'-':('minus',2),
'_':('neg',1),
'+':('plus',2),
'[':('_list',-1),
'{':('set',1),
'}':('dict',0),
':':('slice',2),
';':('pop',1),
'<':('lt',2),
'>':('gt',2),
'/':('div',2),
' ':('',1),
'A':('all',1),
'C':('chr',1),
'c':('count',2),
'e':('lower',1),
'f':('_filter(lambda T:',2),
'g':('gte',2),
'i':('_round',2),
'J':('J',-1),
'j':('join',2),
'K':('K',-1),
'L':('lte',2),
'l':('len',1),
'M':('max',1),
'm':('_map(lambda d:',2),
'O':('rand',0),
'o':('ord',1),
'P':('split',2),
'p':('print',1),
'Q':('quotient',2),
'q':('equal',2),
'r':('_range',2),
'S':('sorted',1),
's':('_sum',1),
't':('tail',1),
'U':('upper',1),
'u':('reduce(lambda G,H:',2),
'V':('rev',1),
'v':('eval',1),
'w':('input',0),
'X':('index',2),
'z':('_zip',2),
}
# Gives next function header to use - for filter, map, reduce.
next_c_to_f={
'f':('_filter(lambda N:',2),
'm':('_map(lambda N:',2),
'u':('reduce(lambda N,T',2),
}
assert set(c_to_f.keys())&set(c_to_i.keys())==set()
# Run it!
def general_parse(code):
args_list=[]
parsed='Not empty'
while parsed != '':
parsed,code=parse(code)
# Necessary for backslash not to infinite loop
if code and code[0]=='\\':
code=code[1:]
args_list.append(parsed)
# Build the output string.
py_code='\n'.join(args_list[:-1])
return py_code
code=input()
py_code=general_parse(code)
print(py_code)
print('='*50)
exec(py_code)
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5dGggdmVyc2lvbiAxLjAuMSAgICAgICAgICAgICAgICAgICAgICAgICAgICAjCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDYtMjQtMjAxNCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMKIyBDaGFuZ2VzIGZyb20gMS4wLjA6IEFkZGVkIGJhY2tzbGFzaCwgaW1wcm92ZWQgc3VtLCBhZGRlZCBbX10sIHJlbW92ZWQgICAgIwojIHN0cigpLCBiZWNhdXNlIHJlcHIoKSBleGlzdHMuICcgaXMgbm93IGluLCBdIGlzIG5vdyBbX10sIG91dCBvZiAgICAgICAgICAjCiMgc2ltaWxhcml0eSB0byB9LiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIwojIFRoaXMgcHl0aG9uIHByb2dyYW0gaXMgYW4gaW50ZXJwcmV0ZXIgZm9yIHRoZSBweXRoIHByb2dyYW1taW5nIGxhbmd1YWdlLiAjCiMgSXQgaXMgc3RpbGwgaW4gZGV2ZWxvcG1lbnQgLSBleHBlY3QgbmV3IHZlcnNpb25zIG9mdGVuLiAgICAgICAgICAgICAgICAgICMKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIwojIFRvIHVzZSwgcHJvdmlkZSBweXRoIGNvZGUgb24gb25lIGxpbmUgb2Ygc3RkaW4uICAgICAgICAgICAgICAgICAgICAgICAgICAjCiMgRnVydGhlciBpbnB1dCBvbiBmdXJ0aGVyIGxpbmVzLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMKIyBQcmludHMgb3V0IHJlc3VsdGFudCBweXRob24gY29kZSBmb3IgZGVidWdnaW5nIHB1cnBvc2VzLCB0aGVuIHJ1bnMgdGhlICAgIwojIHB5dGggcHJvZ3JhbS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMKIyBNb3JlIGluZm9ybWF0aW9uOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIwojIFRoZSBwYXJzZSBmdW5jdGlvbiB0YWtlcyBhIHN0cmluZyBvZiBweXRoIGNvZGUsIGFuZCByZXR1cm5zIGEgc2luZ2xlICAgICAjCiMgcHl0aG9uIGV4cHJlc3Npb24gcmVhZHkgdG8gYmUgZXhlY3V0ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMKIyBnZW5lcmFsX3BhcnNlIGlzIHRoZSBzYW1lIGJ1dCBmb3IgbXVsdGlwbGUgZXhwcmVzc2lvbnMuICAgICAgICAgICAgICAgICAgIwojIFRoaXMgcHJvZ3JhbSBhbHNvIGRlZmluZXMgdGhlIGJ1aWx0LWlucyB0aGF0IHRoZSByZXN1bHRhbnQgZXhwcmVzc2lvbiAgICAjCiMgdXNlcywgb25jZSBleHBhbmRlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKZGVmIHBhcnNlKGNvZGUsc3BhY2luZz0iXG4gIik6CiAgICBhc3NlcnQgdHlwZShjb2RlKT09dHlwZSgnJykKICAgICMgSWYgd2UndmUgcmVhY2hlZCB0aGUgZW5kIG9mIHRoZSBzdHJpbmcsIGdpdmUgdXAuCiAgICBpZiBsZW4oY29kZSk9PTA6CiAgICAgICAgcmV0dXJuICcnLCcnCiAgICAjIFNlcGFyYXRlIGFjdGl2ZSBjaGFyYWN0ZXIgZnJvbSB0aGUgcmVzdCBvZiB0aGUgY29kZS4KICAgIGFjdGl2ZV9jaGFyPWNvZGVbMF0KICAgIHJlc3RfY29kZT1jb2RlWzE6XQogICAgIyBEZWFsIHdpdGggbnVtYmVycwogICAgaWYgYWN0aXZlX2NoYXIgaW4gIi4wMTIzNDU2Nzg5IjoKICAgICAgICBvdXRwdXQ9YWN0aXZlX2NoYXIKICAgICAgICB3aGlsZSAobGVuKHJlc3RfY29kZSk+MAogICAgICAgICAgICAgICBhbmQgcmVzdF9jb2RlWzBdIGluICIuMDEyMzQ1Njc4OSIKICAgICAgICAgICAgICAgYW5kIChvdXRwdXQrcmVzdF9jb2RlWzBdKS5jb3VudCgiLiIpPD0xKToKICAgICAgICAgICAgb3V0cHV0Kz1yZXN0X2NvZGVbMF0KICAgICAgICAgICAgcmVzdF9jb2RlPXJlc3RfY29kZVsxOl0KICAgICAgICByZXR1cm4gb3V0cHV0LHJlc3RfY29kZQogICAgIyBTdHJpbmcgbGl0ZXJhbHMKICAgIGlmIGFjdGl2ZV9jaGFyPT0nIic6CiAgICAgICAgb3V0cHV0PWFjdGl2ZV9jaGFyCiAgICAgICAgd2hpbGUgKGxlbihyZXN0X2NvZGUpPjAKICAgICAgICAgICAgICAgYW5kIG91dHB1dC5jb3VudCgnIicpPDIpOgogICAgICAgICAgICBvdXRwdXQrPXJlc3RfY29kZVswXQogICAgICAgICAgICByZXN0X2NvZGU9cmVzdF9jb2RlWzE6XQogICAgICAgIGlmIG91dHB1dFstMV0hPSciJzoKICAgICAgICAgICAgb3V0cHV0Kz0nIicKICAgICAgICByZXR1cm4gb3V0cHV0LHJlc3RfY29kZQogICAgIyBQeXRob24gY29kZSBsaXRlcmFscwogICAgaWYgYWN0aXZlX2NoYXI9PSckJzoKICAgICAgICBvdXRwdXQ9JycKICAgICAgICB3aGlsZSAobGVuKHJlc3RfY29kZSk+MAogICAgICAgICAgICAgICBhbmQgcmVzdF9jb2RlWzBdIT0nJCcpOgogICAgICAgICAgICBvdXRwdXQrPXJlc3RfY29kZVswXQogICAgICAgICAgICByZXN0X2NvZGU9cmVzdF9jb2RlWzE6XQogICAgICAgIHJldHVybiBvdXRwdXQscmVzdF9jb2RlWzE6XQogICAgIyBFbmQgcGFyZW4gaXMgbWFnaWMuCiAgICBpZiBhY3RpdmVfY2hhcj09JyknOgogICAgICAgIHJldHVybiAnJyxyZXN0X2NvZGUKICAgICMgQmFja3NsYXNoIGlzIG1vcmUgbWFnaWMuCiAgICBpZiBhY3RpdmVfY2hhcj09J1xcJzoKICAgICAgICBpZiByZXN0X2NvZGU9PScnOgogICAgICAgICAgICByZXR1cm4gJycsJycKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gJycsJ1xcJytyZXN0X2NvZGUKICAgICMgRGVzaWduYXRlZCB2YXJpYWJsZXMKICAgIGlmIGFjdGl2ZV9jaGFyIGluIHZhcmlhYmxlczoKICAgICAgICByZXR1cm4gYWN0aXZlX2NoYXIscmVzdF9jb2RlCiAgICAjIE5vdyBmb3IgdGhlIHR3byBsZXR0ZXIgdmFyaWFibGVzL2Z1bmN0aW9ucwogICAgaWYgYWN0aXZlX2NoYXI9PScjJzoKICAgICAgICBhc3NlcnQgbGVuKHJlc3RfY29kZSk+MAogICAgICAgIHJldHVybiByZXN0X2NvZGVbMF0qMixyZXN0X2NvZGVbMTpdCiAgICAjIEFuZCBmb3IgZ2VuZXJhbCBmdW5jdGlvbnMKICAgIGdsb2JhbCBjX3RvX2YKICAgIGdsb2JhbCBuZXh0X2NfdG9fZgogICAgaWYgYWN0aXZlX2NoYXIgaW4gY190b19mIG9yIGFjdGl2ZV9jaGFyPT0nLCc6CiAgICAgICAgaWYgYWN0aXZlX2NoYXI9PScsJzoKICAgICAgICAgICAgZnVuY19uYW1lPXJlc3RfY29kZVswXSoyCiAgICAgICAgICAgIGluaXRfcGFyZW49VHJ1ZQogICAgICAgICAgICBhcml0eT0tMQogICAgICAgICAgICByZXN0X2NvZGU9cmVzdF9jb2RlWzE6XQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGZ1bmNfbmFtZSxhcml0eT1jX3RvX2ZbYWN0aXZlX2NoYXJdCiAgICAgICAgICAgIGluaXRfcGFyZW4gPSAoYWN0aXZlX2NoYXIgbm90IGluIG5vX2luaXRfcGFyZW4pCiAgICAgICAgIyBTd2FwIHdoYXQgdmFyaWFibGVzIGFyZSB1c2VkIGluIHRoZSBtYXAsIGZpbHRlciBvciByZWR1Y2UuCiAgICAgICAgaWYgYWN0aXZlX2NoYXIgaW4gbmV4dF9jX3RvX2Y6CiAgICAgICAgICAgIGNfdG9fZlthY3RpdmVfY2hhcl09bmV4dF9jX3RvX2ZbYWN0aXZlX2NoYXJdCiAgICAgICAgICAgIG5leHRfY190b19mW2FjdGl2ZV9jaGFyXT1jX3RvX2ZbYWN0aXZlX2NoYXJdCiAgICAgICAgIyBSZWN1cnNlIHVudGlsIHRlcm1pbmF0ZWQgYnkgZW5kIHBhcmVuIG9yIEVPRgogICAgICAgICMgb3IgcmVjZWl2ZWQgZW5vdWdoIGFyZ3VtZW50cwogICAgICAgIGFyZ3NfbGlzdD1bXQogICAgICAgIHBhcnNlZD0nTm90IGVtcHR5JwogICAgICAgIHdoaWxlIGxlbihhcmdzX2xpc3QpICE9IGFyaXR5IGFuZCBwYXJzZWQgIT0gJyc6CiAgICAgICAgICAgIHBhcnNlZCxyZXN0X2NvZGU9cGFyc2UocmVzdF9jb2RlKQogICAgICAgICAgICBhcmdzX2xpc3QuYXBwZW5kKHBhcnNlZCkKICAgICAgICAjIEJ1aWxkIHRoZSBvdXRwdXQgc3RyaW5nLgogICAgICAgIHB5X2NvZGU9ZnVuY19uYW1lCiAgICAgICAgaWYgaW5pdF9wYXJlbjoKICAgICAgICAgICAgcHlfY29kZSs9JygnCiAgICAgICAgaWYgbGVuKGFyZ3NfbGlzdCk+MCBhbmQgYXJnc19saXN0Wy0xXT09Jyc6CiAgICAgICAgICAgIGFyZ3NfbGlzdD1hcmdzX2xpc3RbOi0xXQogICAgICAgIHB5X2NvZGUrPScsJy5qb2luKGFyZ3NfbGlzdCkKICAgICAgICBweV9jb2RlKz0nKScKICAgICAgICByZXR1cm4gcHlfY29kZSxyZXN0X2NvZGUKICAgICMgR2VuZXJhbCBmb3JtYXQgZnVuY3Rpb25zL29wZXJhdG9ycwogICAgIyBBbHNvLCBjb21tZW50IGNoYXJhY3RlcnMsIFwsIFxuIGFuZCBcdAogICAgaWYgYWN0aXZlX2NoYXIgaW4gY190b19pOgogICAgICAgIGluZml4ZXMsYXJpdHk9Y190b19pW2FjdGl2ZV9jaGFyXQogICAgICAgIGFyZ3NfbGlzdD1bXQogICAgICAgIHBhcnNlZD0nTm90IGVtcHR5JwogICAgICAgIHdoaWxlIGxlbihhcmdzX2xpc3QpICE9IGFyaXR5IGFuZCBwYXJzZWQgIT0gJyc6CiAgICAgICAgICAgIHBhcnNlZCxyZXN0X2NvZGU9cGFyc2UocmVzdF9jb2RlKQogICAgICAgICAgICBhcmdzX2xpc3QuYXBwZW5kKHBhcnNlZCkKICAgICAgICAjIFN0YXRlbWVudHMgdGhhdCBjYW5ub3QgaGF2ZSBhbnl0aGluZyBhZnRlciB0aGVtCiAgICAgICAgaWYgYWN0aXZlX2NoYXIgaW4gZW5kX3N0YXRlbWVudDoKICAgICAgICAgICAgcmVzdF9jb2RlPSIpIityZXN0X2NvZGUKICAgICAgICBweV9jb2RlPWluZml4ZXNbMF0KICAgICAgICBmb3IgaSBpbiByYW5nZShsZW4oYXJnc19saXN0KSk6CiAgICAgICAgICAgIHB5X2NvZGUrPWFyZ3NfbGlzdFtpXQogICAgICAgICAgICBweV9jb2RlKz1pbmZpeGVzW2krMV0KICAgICAgICByZXR1cm4gcHlfY29kZSwgcmVzdF9jb2RlCiAgICAjIFN0YXRlbWVudHM6CiAgICBpZiBhY3RpdmVfY2hhciBpbiBjX3RvX3M6CiAgICAgICAgIyBIYW5kbGUgdGhlIGluaXRpYWwgcG9ydGlvbiAoaGVhZCkKICAgICAgICBpbmZpeGVzLGFyaXR5PWNfdG9fc1thY3RpdmVfY2hhcl0KICAgICAgICBhcmdzX2xpc3Q9W10KICAgICAgICBwYXJzZWQ9J05vdCBlbXB0eScKICAgICAgICB3aGlsZSBsZW4oYXJnc19saXN0KSAhPSBhcml0eSBhbmQgcGFyc2VkICE9ICcnOgogICAgICAgICAgICBwYXJzZWQscmVzdF9jb2RlPXBhcnNlKHJlc3RfY29kZSkKICAgICAgICAgICAgYXJnc19saXN0LmFwcGVuZChwYXJzZWQpCiAgICAgICAgcGFydF9weV9jb2RlPWluZml4ZXNbMF0KICAgICAgICBmb3IgaSBpbiByYW5nZShsZW4oYXJnc19saXN0KSk6CiAgICAgICAgICAgIHBhcnRfcHlfY29kZSs9YXJnc19saXN0W2ldCiAgICAgICAgICAgIHBhcnRfcHlfY29kZSs9aW5maXhlc1tpKzFdCiAgICAgICAgIyBIYW5kbGUgdGhlIGJvZHkgLSByZXR1cm4gZW5kcyBvYmplY3QgYXMgd2VsbC4KICAgICAgICBhc3NlcnQgcmVzdF9jb2RlICE9ICcnCiAgICAgICAgYXJnc19saXN0PVtdCiAgICAgICAgcGFyc2VkPSdOb3QgZW1wdHknCiAgICAgICAgd2hpbGUgcGFyc2VkICE9ICcnOgogICAgICAgICAgICBwYXJzZWQscmVzdF9jb2RlPXBhcnNlKHJlc3RfY29kZSxzcGFjaW5nKycgJykKICAgICAgICAgICAgYXJnc19saXN0LmFwcGVuZChwYXJzZWQpCiAgICAgICAgIyBUcmltIHRoZSAnJyBhd2F5IGFuZCBjb21iaW5lLgogICAgICAgIGlmIGFyZ3NfbGlzdFstMV09PScnOgogICAgICAgICAgICBhcmdzX2xpc3Q9YXJnc19saXN0WzotMV0KICAgICAgICBhbGxfcGllY2VzPVtwYXJ0X3B5X2NvZGVdK2FyZ3NfbGlzdAogICAgICAgIHJldHVybiBzcGFjaW5nLmpvaW4oYWxsX3BpZWNlcykscmVzdF9jb2RlCiAgICBwcmludCgiU29tZXRoaW5nJ3Mgd3JvbmcuIikKICAgIHByaW50KCJDdXJyZW50IGNoYXIgaXMgIixhY3RpdmVfY2hhcikKICAgIHByaW50KCJUaGUgcmVzdCBvZiB0aGUgY29kZSBpcyAiLHJlc3RfY29kZSkKICAgIHJhaXNlIE5vdEltcGxlbWVudGVkRXJyb3IKCmltcG9ydCByYW5kb20KaW1wb3J0IGNvcHkKaW1wb3J0IHN0cmluZwojIEZ1bmN0aW9uIGxpYnJhcnksIGRlc2NyaXB0aW9ucyBvZiBldmVyeXRoaW5nLgojICs9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIH4gICAgIFkKIyByZXByICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBgICAgICBZCmRlZiBfbm90KGEpOnJldHVybiBub3QgYSAgICAgICAgICAgICMgISAgICAgWQojIF9bX10gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEAgICAgIFkKIyAjIGlzIHNwZWNpYWwgLSAyIGNoYXJhY3RlciB2YXJpYWJsZSAgICAgICBZCiMgJCBpcyBzcGVjaWFsIC0gcHl0aG9uIGxpdGVyYWwgICAgICAgICAgICAgWQpkZWYgbW9kKGEsYik6cmV0dXJuIGElYiAgICAgICAgICAgICAjICUgICAgIFkKIyBwb3cgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBeICAgICBZCiMgYW5kICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgJiAgICAgWQpkZWYgdGltZXMoYSxiKTpyZXR1cm4gYSpiICAgICAgICAgICAjICogICAgIFkKZGVmIF90dXBsZSgqYSk6cmV0dXJuIGEgICAgICAgICAgICAgIyAoICAgICBZCiMgKSBpcyBzcGVjaWFsIC0gZW5kIGV4dGVuc2libGUgICAgICAgICAgICAgWQpkZWYgbWludXMoYSxiKTpyZXR1cm4gYS1iICAgICAgICAgICAjIC0gICAgIFkKZGVmIG5lZyhhKTpyZXR1cm4gLWEgICAgICAgICAgICAgICAgIyBfICAgICBZCmRlZiBwbHVzKGEsYik6cmV0dXJuIGErYiAgICAgICAgICAgICMgKyAgICAgWQojID0gZGVlcGNvcHkgICAgICAgICAgICAgICAgICAgICAgICAjID0gICAgIFkKY29weSA9IGNvcHkuZGVlcGNvcHkKZGVmIF9saXN0KCphKTpyZXR1cm4gbGlzdChhKSAgICAgICAgIyBbICAgICBZCiMgc2V0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeyAgICAgWQojIFtfXSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIF0gICAgIFkKIyBkaWN0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB9ICAgICBZCiMgb3IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgfCAgICAgWQojIGJyZWFrIG91dCBvZiBhbGwgY29udGFpbmluZyAgICAgICAgICAgICAgIFkKIyBzbGljZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyA6ICAgICBZCmRlZiBwb3AoYSk6cmV0dXJuIGEucG9wKCkgICAgICAgICAgICMgOyAgICAgWQojIGluICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjICcgICAgIFkKIyAiIGlzIHNwZWNpYWwgLSBzdHJpbmcgbGl0ZXJhbCAgICAgICAgICAgICBZCiMgLCBpcyBzcGVjaWFsIC0gMiBjaGFyYWN0ZXIgZnVuY3Rpb24gICAgICAgWQpkZWYgbHQoYSxiKTpyZXR1cm4gYTxiICAgICAgICAgICAgICAjIDwgICAgIFkKIyAuIGlzIHNwZWNpYWwgLSBudW1iZXJzICAgICAgICAgICAgIyAuICAgICBZCmRlZiBndChhLGIpOnJldHVybiBhPmIgICAgICAgICAgICAgICMgPiAgICAgWQpkZWYgZGl2KGEsYik6cmV0dXJuIGEvL2IgICAgICAgICAgICAjIC8gICAgIFkKIyBpZiBlbHNlICAgICAgICAgICAgICAgICAgICAgICAgICAgIyA/ICAgICBZCiMgMC05IGFyZSBzcGVjaWFsIC0gbnVtYmVycyAgICAgICAgICMgMC05ICAgWQojICh4KSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjfCB8ICAgIFkKIyBhbGwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBBICAgICBZCiMgLmFwcGVuZCgpICAgICAgICAgICAgICAgICAgICAgICAgICMgYSAgICAgWQojIGJyZWFrICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEIgICAgIFkKYj0iXG4iICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBiICAgICBZCiMgY2hyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQyAgICAgWQpkZWYgY291bnQoYSxiKTpyZXR1cm4gYS5jb3VudChiKSAgICAjIGMgICAgIFkKIyBkZWYgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEICAgICBZCiMgdmFyaWFibGUgLSBhc3NvY2lhdGVkIHdpdGggbWFwICAgICMgZCAgICAgWQpkPSciJwojIGVsc2UgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEUgICAgIFkKZGVmIGxvd2VyKGEpOnJldHVybiBhLmxvd2VyKCkgICAgICAgIyBlICAgICBZCiMgZm9yICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRiAgICAgWQpkZWYgX2ZpbHRlcihhLGIpOiAgICAgICAgICAgICAgICAgICAjIGYgICAgIFkKICAgIHJldHVybiBsaXN0KGZpbHRlcihhLGIpKQojIHZhcmlhYmxlIC0gYXNzb2NpYXRlZCB3aXRoIHJlZHVjZSAjIEcgICAgIFkKRz1zdHJpbmcuYXNjaWlfbG93ZXJjYXNlCmRlZiBndGUoYSxiKTpyZXR1cm4gYT49YiAgICAgICAgICAgICMgZyAgICAgWQojIHZhcmlhYmxlIC0gYXNzb2NpYXRlZCB3aXRoIHJlZHVjZSAjIEggICAgIFkKSD17fQpkZWYgcmVhZF9maWxlKCk6ICAgICAgICAgICAgICAgICAgICAjIGggICAgIFkKICAgIGE9IlxuIi5qb2luKG9wZW4oaW5wdXQoKSkpCiAgICByZXR1cm4gYQojIGggYXNzaWducyB0aGUgdGV4dCBvZiB0aGUgdXNlciAKIyBpbnB1dHRlZCBmaWxlIHRvIHRoZSB2YXJpYWJsZSBnaXZlbi4KIyBpZiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBJICAgICBZCmRlZiBfcm91bmQoYSxiPU5vbmUpOiAgICAgICAgICAgICAgICMgaSAgICAgWQogICAgaWYgYiBpcyBOb25lOgogICAgICAgIHJldHVybiBmbG9hdChhKQogICAgaWYgYiBpcyAwOgogICAgICAgIHJldHVybiBpbnQoYSkKICAgIHJldHVybiByb3VuZChhLGIpCiMgZGVzaWduYXRlZCBmdW5jdGlvbiAgICAgICAgICAgICAgICMgSiAgICAgWQpkZWYgam9pbihhLGIpOnJldHVybiBhLmpvaW4oYikgICAgICAjIGogICAgIFkKIyBkZXNpZ25hdGVkIGZ1bmN0aW9uICAgICAgICAgICAgICAgIyBLICAgICBZCms9JycgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgayAgICAgWQpkZWYgbHRlKGEsYik6cmV0dXJuIGE8PWIgICAgICAgICAgICAjIEwgICAgIFkKIyBsZW4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBsICAgICBZCiMgbWF4ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgTSAgICAgWQpkZWYgX21hcChhLGIpOnJldHVybiBsaXN0KG1hcChhLGIpKSAjIG0gICAgIFkKTj1Ob25lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBOICAgICBZCiMgbWluICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbiAgICAgWQpkZWYgcmFuZChhLGIpOiAgICAgICAgICAgICAgICAgICAgICAjIE8gICAgIFkKICAgIHJldHVybiByYW5kb20ucmFuZGludChhLGIpCiMgb3JkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbyAgICAgWQpkZWYgc3BsaXQoYSxiPU5vbmUpOiAgICAgICAgICAgICAgICAjIFAgICAgIFkKICAgIGlmIGI6CiAgICAgICAgcmV0dXJuIGEuc3BsaXQoYikKICAgIGVsc2U6CiAgICAgICAgcmV0dXJuIGEuc3BsaXQoKQojIHByaW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHAgICAgIFkKZGVmIHF1b3RpZW50KGEsYik6cmV0dXJuIGEvYiAgICAgICAgIyBRICAgICBZCmRlZiBlcXVhbChhLGIpOnJldHVybiBhPT1iICAgICAgICAgICMgcSAgICAgWQojIHJldHVybiAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIFIgICAgIFkKZGVmIF9yYW5nZShhLGI9Tm9uZSk6ICAgICAgICAgICAgICAgIyByICAgICBZCiAgICBpZiBiOgogICAgICAgIHJldHVybiBsaXN0KHJhbmdlKGEsYikpCiAgICBlbHNlOgogICAgICAgIHJldHVybiBsaXN0KHJhbmdlKGEpKQojIHNvcnRlZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIFMgICAgIFkKZGVmIF9zdW0oYSk6CiAgICByZXR1cm4gcmVkdWNlKGxhbWJkYSBiLGM6YitjLGEpICMgcyAgICAgWQojIFQgaXMgYXNzb2NpYXRlZCB3aXRoIGZpbHRlciAgICAgICAjIFQgICAgIFkKVD0xMApkZWYgdGFpbChhKTpyZXR1cm4gYVsxOl0gICAgICAgICAgICAjIHQgICAgIFkKZGVmIHVwcGVyKGEpOnJldHVybiBhLnVwcGVyKCkgICAgICAgIyBVICAgICBZCmRlZiByZWR1Y2UoYSxiKTogICAgICAgICAgICAgICAgICAgICMgdSAgICAgWQogICAgYWNjPWJbMF0KICAgIHNlcT1iWzE6XQogICAgd2hpbGUgbGVuKHNlcSk+MDoKICAgICAgICBoPXNlcVswXQogICAgICAgIGFjYz1hKGFjYyxoKQogICAgICAgIHNlcT1zZXFbMTpdCiAgICByZXR1cm4gYWNjCmRlZiByZXYoYSk6IHJldHVybiBhWzo6LTFdICAgICAgICAgICMgViAgICAgWQojIGV2YWwocGFyc2UgICAgICAgICAgICAgICAgICAgICAgICAjIHYgICAgIFkKIyB3aGlsZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBXICAgICBZCiMgaW5wdXQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgdyAgICAgWQpkZWYgaW5kZXgoYSxiKTogICAgICAgICAgICAgICAgICAgICAjIFggICAgIFkKICAgIGlmIGIgaW4gYToKICAgICAgICByZXR1cm4gYS5pbmRleChiKQogICAgIyByZXBsaWNhdGUgZnVuY3Rpb25hbGl0eSBmcm9tIHN0ci5maW5kCiAgICBlbHNlOgogICAgICAgIHJldHVybiAtMQojIGV4ZWMoZ2VuZXJhbF9wYXJzZSAgICAgICAgICAgICAgICAjIHggICAgIFkKWT1bXSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBZICAgICBZCiMgYW55ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeSAgICAgWQpaPTAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIFogICAgIFkKZGVmIF96aXAoYSxiKTpyZXR1cm4gbGlzdCh6aXAoYSxiKSkgIyB6ICAgICBZCgpub19pbml0X3BhcmVuPSdmbXUnCmVuZF9zdGF0ZW1lbnQ9J0JSJwp2YXJpYWJsZXM9J2JkR0hrTlRZWicKCiMgVG8gZG86IGV2ZW4gcHJlYXNzb2NpYXRlZCB2YXJpYWJsZXMgZGVzZXJ2ZSB0byBiZSBpbml0aWFsaXplZC4KIyBWYXJpYWJsZXMgY2hlYXQgc2hlZXQ6CiMgYiA9ICJcbiIKIyBkIGlzIGZvciBtYXAsIGQ9JyInCiMgRyBpcyBmb3IgcmVkdWNlLCBHPXN0cmluZy5hc2NpaV9sb3dlcmNhc2UgKGFiYy4ueHl6KQojIEggaXMgZm9yIHJlZHVjZSwgSCA9IHt9CiMgayA9ICcnCiMgTiA9IE5vbmUsIHNlY29uZCBvcHRpb24gdmFyaWFibGUgZm9yIG1hcCxmaWx0ZXIscmVkdWNlCiMgVCBpcyBmb3IgZmlsdGVyLCBzZWNvbmQgdmFyaWFibGUgb3B0aW9uIGZvciByZWR1Y2UsIFQ9MTAKIyBZID0gW10KIyBaID0gMAoKY190b19zPXsKICAgICdEJzooKCdkZWYgJywnOicpLDEpLAogICAgJ0UnOigoJ2Vsc2U6JyksMCksCiAgICAnRic6KCgnZm9yICcsJyBpbiAnLCc6JyksMiksCiAgICAnSSc6KCgnaWYgJywnOicpLDEpLAogICAgJ1cnOigoJ3doaWxlICcsJzonKSwxKSwKICAgIH0KIyBBcmJpdHJhcnkgZm9ybWF0IG9wZXJhdG9ycyAtIHVzZSBmb3IgYXNzaWdubWVudCwgaW5maXgsIGV0Yy4KIyBBbGwgc3Vycm91bmRpbmcgc3RyaW5ncywgYXJpdHkKY190b19pPXsKICAgICdcXCc6KCgnJywnJyksMSksCiAgICAnXG4nOigoJycsJycpLDEpLAogICAgJ1x0JzooKCcnLCcnKSwxKSwKICAgICd+JzooKCcnLCcrPScsJycpLDIpLAogICAgJ0AnOigoJycsJ1snLCddJyksMiksCiAgICAnJic6KCgnKCcsJyBhbmQgJywnKScpLDIpLAogICAgJ3wnOigoJygnLCcgb3IgJywnKScpLDIpLAogICAgJz0nOigoJycsJz1jb3B5KCcsJyknKSwyKSwKICAgICddJzooKCdbJywnXScpLDEpLAogICAgIiciOigoJygnLCcgaW4gJywnKScpLDIpLAogICAgJz8nOigoJygnLCcgaWYgJywnIGVsc2UgJywnKScpLDMpLAogICAgJ2EnOigoJycsJy5hcHBlbmQoJywnKScpLDIpLAogICAgJ0InOigoJ2JyZWFrJywpLDApLAogICAgJ2gnOigoJycsJz1yZWFkX2ZpbGUoKScpLDEpLAogICAgJ1InOigoJ3JldHVybiAnLCcnKSwxKSwKICAgICd4JzooKCdleGVjKGdlbmVyYWxfcGFyc2UoJywnKSknKSwxKSwKICAgIH0KCiMgU2ltcGxlIGZ1bmN0aW9ucyBvbmx5LgojIEV4dGVuc2libGUgaXMgYWxsb3dlZCwgbm90aGluZyBlbHNlIGNvbXBsaWNhdGVkIGlzLgojIC0xIG1lYW5zIGV4dGVuc2libGUKIyBuYW1lLGFyaXR5CmNfdG9fZj17CiAgICAnYCc6KCdyZXByJywxKSwKICAgICchJzooJ19ub3QnLDEpLAogICAgJyUnOignbW9kJywyKSwKICAgICdeJzooJ3BvdycsMiksCiAgICAnKic6KCd0aW1lcycsMiksCiAgICAnKCc6KCdfdHVwbGUnLC0xKSwKICAgICctJzooJ21pbnVzJywyKSwKICAgICdfJzooJ25lZycsMSksCiAgICAnKyc6KCdwbHVzJywyKSwKICAgICdbJzooJ19saXN0JywtMSksCiAgICAneyc6KCdzZXQnLDEpLAogICAgJ30nOignZGljdCcsMCksCiAgICAnOic6KCdzbGljZScsMiksCiAgICAnOyc6KCdwb3AnLDEpLAogICAgJzwnOignbHQnLDIpLAogICAgJz4nOignZ3QnLDIpLAogICAgJy8nOignZGl2JywyKSwKICAgICcgJzooJycsMSksCiAgICAnQSc6KCdhbGwnLDEpLAogICAgJ0MnOignY2hyJywxKSwKICAgICdjJzooJ2NvdW50JywyKSwKICAgICdlJzooJ2xvd2VyJywxKSwKICAgICdmJzooJ19maWx0ZXIobGFtYmRhIFQ6JywyKSwKICAgICdnJzooJ2d0ZScsMiksCiAgICAnaSc6KCdfcm91bmQnLDIpLAogICAgJ0onOignSicsLTEpLAogICAgJ2onOignam9pbicsMiksCiAgICAnSyc6KCdLJywtMSksCiAgICAnTCc6KCdsdGUnLDIpLAogICAgJ2wnOignbGVuJywxKSwKICAgICdNJzooJ21heCcsMSksCiAgICAnbSc6KCdfbWFwKGxhbWJkYSBkOicsMiksCiAgICAnTyc6KCdyYW5kJywwKSwKICAgICdvJzooJ29yZCcsMSksCiAgICAnUCc6KCdzcGxpdCcsMiksCiAgICAncCc6KCdwcmludCcsMSksCiAgICAnUSc6KCdxdW90aWVudCcsMiksCiAgICAncSc6KCdlcXVhbCcsMiksCiAgICAncic6KCdfcmFuZ2UnLDIpLAogICAgJ1MnOignc29ydGVkJywxKSwKICAgICdzJzooJ19zdW0nLDEpLAogICAgJ3QnOigndGFpbCcsMSksCiAgICAnVSc6KCd1cHBlcicsMSksCiAgICAndSc6KCdyZWR1Y2UobGFtYmRhIEcsSDonLDIpLAogICAgJ1YnOigncmV2JywxKSwKICAgICd2JzooJ2V2YWwnLDEpLAogICAgJ3cnOignaW5wdXQnLDApLAogICAgJ1gnOignaW5kZXgnLDIpLAogICAgJ3onOignX3ppcCcsMiksCiAgICB9CgojIEdpdmVzIG5leHQgZnVuY3Rpb24gaGVhZGVyIHRvIHVzZSAtIGZvciBmaWx0ZXIsIG1hcCwgcmVkdWNlLgpuZXh0X2NfdG9fZj17CiAgICAnZic6KCdfZmlsdGVyKGxhbWJkYSBOOicsMiksCiAgICAnbSc6KCdfbWFwKGxhbWJkYSBOOicsMiksCiAgICAndSc6KCdyZWR1Y2UobGFtYmRhIE4sVCcsMiksCiAgICB9CmFzc2VydCBzZXQoY190b19mLmtleXMoKSkmc2V0KGNfdG9faS5rZXlzKCkpPT1zZXQoKQojIFJ1biBpdCEKZGVmIGdlbmVyYWxfcGFyc2UoY29kZSk6CiAgICBhcmdzX2xpc3Q9W10KICAgIHBhcnNlZD0nTm90IGVtcHR5JwogICAgd2hpbGUgcGFyc2VkICE9ICcnOgogICAgICAgIHBhcnNlZCxjb2RlPXBhcnNlKGNvZGUpCiAgICAgICAgIyBOZWNlc3NhcnkgZm9yIGJhY2tzbGFzaCBub3QgdG8gaW5maW5pdGUgbG9vcAogICAgICAgIGlmIGNvZGUgYW5kIGNvZGVbMF09PSdcXCc6CiAgICAgICAgICAgIGNvZGU9Y29kZVsxOl0KICAgICAgICBhcmdzX2xpc3QuYXBwZW5kKHBhcnNlZCkKICAgICMgQnVpbGQgdGhlIG91dHB1dCBzdHJpbmcuCiAgICBweV9jb2RlPSdcbicuam9pbihhcmdzX2xpc3RbOi0xXSkKICAgIHJldHVybiBweV9jb2RlCmNvZGU9aW5wdXQoKQpweV9jb2RlPWdlbmVyYWxfcGFyc2UoY29kZSkKcHJpbnQocHlfY29kZSkKcHJpbnQoJz0nKjUwKQpleGVjKHB5X2NvZGUp