import json
import re
def pathSegmentParse(path):
'''
Parses a ppath string into logical segments that
can be applied individually.
There are 2 kinds of segments, paths and filters.
Paths indicate a path through the structure.
Filters evaluate an array of substructures to only
those that match
'''
segments = []
parts = re.split('\[|\]',path)
for part in parts:
if not part:
continue
seg = {}
if part[0]=='.':
part = part[1:]
if '=' in part:
sub_parts = part.split('=')
seg['path'] = sub_parts[0]
seg['type'] = 'filter'
seg['value'] = part.split('=')[1]
else:
seg['type'] = 'path'
seg['path'] = part
segments.append(seg)
return segments
def applyPath(segment,pointers):
'''
Takes an array of pointers and a ppath segment and returns
a new array of pointers that match the given path
'''
path = segment['path']
parts = path.split('.')
for part in parts:
new_pointers = []
for i in range(0,len(pointers)):
if isinstance(pointers[i], (dict,list)): #then we're not at a simple value
if pointers[i].get(part):
if isinstance(pointers[i][part], list):
for p in pointers[i][part]:
new_pointers.append(p)
else:
new_pointers.append(pointers[i][part])
pointers = new_pointers
return pointers
def applyFilter(segment,pointers):
'''
Takes a filter segment of a ppath and applied it
to each pointer and returns an array of pointers
that resolve to the value given in the segment
'''
new_pointers = []
for p in pointers:
value = applyPath(segment,[p])
if value:
if segment['value'] in value:
new_pointers.append(p)
return new_pointers
def getFromPPath(data,path,default=[]):
'''
Takes a python dict and a ppath string and finds the
matching data in the dict. If no data can be found the
default is returned
'''
pointers = [data]
segments = pathSegmentParse(path)
for segment in segments:
if segment['type'] == 'path':
pointers = applyPath(segment,pointers)
if segment['type'] == 'filter':
pointers = applyFilter(segment,pointers)
if len(pointers)==0:
return default
return pointers
JSON = '''
{
"friends" : [
{"first_name": "Wendell", "last_name": "Jordan", "phone":[{"type":"mobile","number":"440-123-8126"},{"type":"home","number":"440-890-5573"}],"gender":"male"},
{"first_name": "Jeanne", "last_name": "Morris", "phone":[{"type":"mobile","number":"216-123-0079"},{"type":"home","number":"216-890-7830"}],"gender":"female"},
{"first_name": "Herman", "last_name": "Mcdaniel", "phone":[{"type":"mobile","number":"440-123-1344"},{"type":"home","number":"440-890-8825"}],"gender":"male"},
{"first_name": "Emanuel", "last_name": "Becker", "phone":[{"type":"mobile","number":"216-123-8825"},{"type":"home","number":"216-890-8332"}],"gender":"female"},
{"first_name": "Sara", "last_name": "Todd", "phone":[{"type":"mobile","number":"216-123-6117"},{"type":"home","number":"216-890-2899"}],"gender":"female"},
{"first_name": "Victoria", "last_name": "Gray", "phone":[{"type":"mobile","number":"216-123-8456"},{"type":"home","number":"216-890-4469"}],"gender":"female"},
{"first_name": "Ronnie", "last_name": "Cook", "phone":[{"type":"mobile","number":"216-123-2006"},{"type":"home","number":"216-890-2006"}],"gender":"female"},
{"first_name": "Gilbert", "last_name": "Morton", "phone":[{"type":"mobile","number":"440-123-4567"},{"type":"home","number":"440-890-4567"}],"gender":"male"},
{"first_name": "Claudia", "last_name": "Padilla", "phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Doris", "last_name": "Maxwell", "phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Luis", "last_name": "Stokes", "phone":[{"type":"mobile","number":"440-123-4567"},{"type":"home","number":"440-890-4567"}],"gender":"male"},
{"first_name": "Byron", "last_name": "Kelley", "phone":[{"type":"mobile","number":"440-123-4567"},{"type":"home","number":"440-890-4567"}],"gender":"male"},
{"first_name": "Terri", "last_name": "Hayes", "phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Flora", "last_name": "Greene", "phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Guadalupe", "last_name": "Strickland","phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Sylvia", "last_name": "Sutton", "phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Caroline", "last_name": "Perkins", "phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Sherri", "last_name": "Ross", "phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Lloyd", "last_name": "Townsend", "phone":[{"type":"mobile","number":"440-123-4567"},{"type":"home","number":"440-890-4567"}],"gender":"male"},
{"first_name": "Cody", "last_name": "Erickson", "phone":[{"type":"mobile","number":"440-123-4567"},{"type":"home","number":"440-890-4567"}],"gender":"male"},
{"first_name": "Ron", "last_name": "Williams", "phone":[{"type":"mobile","number":"440-123-4567"},{"type":"home","number":"440-890-4567"}],"gender":"male"},
{"first_name": "Francis", "last_name": "Fitzgerald","phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Kenneth", "last_name": "Hopkins", "phone":[{"type":"mobile","number":"440-123-4567"},{"type":"home","number":"440-890-4567"}],"gender":"male"},
{"first_name": "Mary", "last_name": "Ballard", "phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Andre", "last_name": "Lewis", "phone":[{"type":"mobile","number":"440-123-4567"},{"type":"home","number":"440-890-4567"}],"gender":"male"},
{"first_name": "Marguerite", "last_name": "Medina", "phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Rachael", "last_name": "Brown", "phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Daryl", "last_name": "Mccarthy", "phone":[{"type":"mobile","number":"440-123-4567"},{"type":"home","number":"440-890-4567"}],"gender":"male"},
{"first_name": "Shelia", "last_name": "Schultz", "phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Geoffrey", "last_name": "Mcdonald", "phone":[{"type":"mobile","number":"440-123-4567"},{"type":"home","number":"440-890-4567"}],"gender":"male"},
{"first_name": "Tyler", "last_name": "Nichols", "phone":[{"type":"mobile","number":"440-123-4567"},{"type":"home","number":"440-890-4567"}],"gender":"male"},
{"first_name": "Gretchen", "last_name": "Graves", "phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Lora", "last_name": "Pearson", "phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Katie", "last_name": "Watts", "phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Taylor", "last_name": "Jennings", "phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Pamela", "last_name": "Buchanan", "phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Mark", "last_name": "Potter", "phone":[{"type":"mobile","number":"440-123-4567"},{"type":"home","number":"440-890-4567"}],"gender":"male"},
{"first_name": "Domingo", "last_name": "Allen", "phone":[{"type":"mobile","number":"440-123-4567"},{"type":"home","number":"440-890-4567"}],"gender":"male"},
{"first_name": "Jean", "last_name": "Kim", "phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Monique", "last_name": "Sullivan", "phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Theresa", "last_name": "Beck", "phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Morris", "last_name": "Moreno", "phone":[ {"type":"home","number":"440-890-4567"}],"gender":"male"},
{"first_name": "Wade", "last_name": "Luna", "phone":[{"type":"mobile","number":"440-123-4567"},{"type":"home","number":"440-890-4567"}],"gender":"male"},
{"first_name": "Traci", "last_name": "Garcia", "phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "Alan", "last_name": "Washington","phone":[{"type":"mobile","number":"440-123-4567"},{"type":"home","number":"440-890-4567"}],"gender":"male"},
{"first_name": "Toni", "last_name": "Weaver", "phone":[{"type":"mobile","number":"216-123-4567"},{"type":"home","number":"216-890-4567"}],"gender":"female"},
{"first_name": "David", "last_name": "Brown", "phone":[{"type":"mobile","number":"440-123-4567"},{"type":"home","number":"440-890-4567"}],"gender":"male"},
{"first_name": "Sergio", "last_name": "Marsh", "phone":[{"type":"mobile","number":"440-123-4567"},{"type":"home","number":"440-890-4567"}],"gender":"male"},
{"first_name": "Charlie", "last_name": "Rice", "phone":[{"type":"mobile","number":"440-123-4567"},{"type":"home","number":"440-890-4567"}],"gender":"male"},
{"first_name": "Bernard", "last_name": "Hogan", "phone":[{"type":"mobile","number":"440-123-4567"},{"type":"home","number":"440-890-4567"}],"gender":"male"}
]
}
'''
data = json.loads(JSON)
# how many friends do I have?
assert(len(getFromPPath(data,'friends'))==50)
# how many friends with the last name brown?
assert(len(getFromPPath(data,'friends[last_name=Brown]'))==2)
# What are the first names of the friends whose last names are brown?
assert(getFromPPath(data,'friends[last_name=Brown].first_name')[0]=="Rachael")
assert(getFromPPath(data,'friends[last_name=Brown].first_name')[1]=="David")
# what's the first name of the person with this phone number?
assert(len(getFromPPath(data,"friends[phone.number=216-890-7830].first_name"))==1)
assert(getFromPPath(data,"friends[phone.number=216-890-7830].first_name")[0]=="Jeanne")
# what about this phone number?
assert(len(getFromPPath(data,"friends[phone.number=216-123-0079].first_name"))==1)
assert(getFromPPath(data,"friends[phone.number=216-123-0079].first_name")[0]=="Jeanne")
# How many friends are female?
assert(len(getFromPPath(data,"friends[gender=female]"))==28)
# First names of female friends
assert(len(getFromPPath(data,"friends[gender=female].first_name"))==28)
assert(getFromPPath(data,"friends[gender=female].first_name")[0]=="Jeanne")
assert(getFromPPath(data,"friends[gender=female].first_name")[10]=="Sylvia")
assert(getFromPPath(data,"friends[gender=female].first_name")[27]=="Toni")
# Phone numbers of female friends
assert(len(getFromPPath(data,"friends[gender=female].phone.number"))==56)
assert(getFromPPath(data,"friends[gender=female].phone.number")[0]=="216-123-0079")
assert(getFromPPath(data,"friends[gender=female].phone.number")[10]=="216-123-4567")
assert(getFromPPath(data,"friends[gender=female].phone.number")[55]=="216-890-4567")
# Mobile phone numbers of female friends
assert(len(getFromPPath(data,"friends[gender=female].phone[type=mobile].number"))==28)
assert(getFromPPath(data,"friends[gender=female].phone[type=mobile].number")[0]=="216-123-0079")
assert(getFromPPath(data,"friends[gender=female].phone[type=mobile].number")[10]=="216-123-4567")
assert(getFromPPath(data,"friends[gender=female].phone[type=mobile].number")[27]=="216-123-4567")
# Male friends
assert(len(getFromPPath(data,"friends[gender=male]"))==22)
# Male friends with mobile phones
assert(len(getFromPPath(data,"friends[gender=male][phone.type=mobile]"))==21)
# Male friends with home phones
assert(len(getFromPPath(data,"friends[gender=male][phone.type=home]"))==22)
# First names of male friends with home phones
assert(getFromPPath(data,"friends[gender=male][phone.type=home].first_name")[0]=="Wendell")
assert(getFromPPath(data,"friends[gender=male][phone.type=home].first_name")[10]=="Daryl")
assert(getFromPPath(data,"friends[gender=male][phone.type=home].first_name")[21]=="Bernard")
# Male friends with fax numbers
assert(len(getFromPPath(data,"friends[gender=male][phone.type=fax]"))==0)
aW1wb3J0IGpzb24KaW1wb3J0IHJlCgoKZGVmIHBhdGhTZWdtZW50UGFyc2UocGF0aCk6CiAgICAnJycKICAgIFBhcnNlcyBhIHBwYXRoIHN0cmluZyBpbnRvIGxvZ2ljYWwgc2VnbWVudHMgdGhhdCAKICAgIGNhbiBiZSBhcHBsaWVkIGluZGl2aWR1YWxseS4gCiAgICBUaGVyZSBhcmUgMiBraW5kcyBvZiBzZWdtZW50cywgcGF0aHMgYW5kIGZpbHRlcnMuCiAgICBQYXRocyBpbmRpY2F0ZSBhIHBhdGggdGhyb3VnaCB0aGUgc3RydWN0dXJlLgogICAgRmlsdGVycyBldmFsdWF0ZSBhbiBhcnJheSBvZiBzdWJzdHJ1Y3R1cmVzIHRvIG9ubHkgCiAgICB0aG9zZSB0aGF0IG1hdGNoCiAgICAnJycKICAgIHNlZ21lbnRzID0gW10KICAgIHBhcnRzID0gcmUuc3BsaXQoJ1xbfFxdJyxwYXRoKQogICAgZm9yIHBhcnQgaW4gcGFydHM6CiAgICAgICAgaWYgbm90IHBhcnQ6IAogICAgICAgICAgICBjb250aW51ZQogICAgICAgIHNlZyA9IHt9CiAgICAgICAgaWYgcGFydFswXT09Jy4nOgogICAgICAgICAgICBwYXJ0ID0gcGFydFsxOl0KICAgICAgICBpZiAnPScgaW4gcGFydDoKICAgICAgICAgICAgc3ViX3BhcnRzID0gcGFydC5zcGxpdCgnPScpCiAgICAgICAgICAgIHNlZ1sncGF0aCddID0gc3ViX3BhcnRzWzBdCiAgICAgICAgICAgIHNlZ1sndHlwZSddID0gJ2ZpbHRlcicKICAgICAgICAgICAgc2VnWyd2YWx1ZSddID0gcGFydC5zcGxpdCgnPScpWzFdCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VnWyd0eXBlJ10gPSAncGF0aCcKICAgICAgICAgICAgc2VnWydwYXRoJ10gPSBwYXJ0CiAgICAgICAgc2VnbWVudHMuYXBwZW5kKHNlZykKICAgIHJldHVybiBzZWdtZW50cwoKZGVmIGFwcGx5UGF0aChzZWdtZW50LHBvaW50ZXJzKToKICAgICcnJwogICAgVGFrZXMgYW4gYXJyYXkgb2YgcG9pbnRlcnMgYW5kIGEgcHBhdGggc2VnbWVudCBhbmQgcmV0dXJucwogICAgYSBuZXcgYXJyYXkgb2YgcG9pbnRlcnMgdGhhdCBtYXRjaCB0aGUgZ2l2ZW4gcGF0aAogICAgJycnCiAgICBwYXRoID0gc2VnbWVudFsncGF0aCddCiAgICBwYXJ0cyA9IHBhdGguc3BsaXQoJy4nKQogICAgZm9yIHBhcnQgaW4gcGFydHM6CiAgICAgICAgbmV3X3BvaW50ZXJzID0gW10KICAgICAgICBmb3IgaSBpbiByYW5nZSgwLGxlbihwb2ludGVycykpOgogICAgICAgICAgICBpZiBpc2luc3RhbmNlKHBvaW50ZXJzW2ldLCAoZGljdCxsaXN0KSk6ICN0aGVuIHdlJ3JlIG5vdCBhdCBhIHNpbXBsZSB2YWx1ZQogICAgICAgICAgICAgICAgaWYgcG9pbnRlcnNbaV0uZ2V0KHBhcnQpOgogICAgICAgICAgICAgICAgICAgIGlmIGlzaW5zdGFuY2UocG9pbnRlcnNbaV1bcGFydF0sIGxpc3QpOgogICAgICAgICAgICAgICAgICAgICAgICBmb3IgcCBpbiBwb2ludGVyc1tpXVtwYXJ0XToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld19wb2ludGVycy5hcHBlbmQocCkKICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICBuZXdfcG9pbnRlcnMuYXBwZW5kKHBvaW50ZXJzW2ldW3BhcnRdKQogICAgICAgIHBvaW50ZXJzID0gbmV3X3BvaW50ZXJzCiAgICByZXR1cm4gcG9pbnRlcnMKCmRlZiBhcHBseUZpbHRlcihzZWdtZW50LHBvaW50ZXJzKToKICAgICcnJwogICAgVGFrZXMgYSBmaWx0ZXIgc2VnbWVudCBvZiBhIHBwYXRoIGFuZCBhcHBsaWVkIGl0CiAgICB0byBlYWNoIHBvaW50ZXIgYW5kIHJldHVybnMgYW4gYXJyYXkgb2YgcG9pbnRlcnMKICAgIHRoYXQgcmVzb2x2ZSB0byB0aGUgdmFsdWUgZ2l2ZW4gaW4gdGhlIHNlZ21lbnQKICAgICcnJwogICAgbmV3X3BvaW50ZXJzID0gW10KICAgIGZvciBwIGluIHBvaW50ZXJzOgogICAgICAgIHZhbHVlID0gYXBwbHlQYXRoKHNlZ21lbnQsW3BdKQogICAgICAgIGlmIHZhbHVlOgogICAgICAgICAgICBpZiBzZWdtZW50Wyd2YWx1ZSddIGluIHZhbHVlOgogICAgICAgICAgICAgICAgbmV3X3BvaW50ZXJzLmFwcGVuZChwKQogICAgcmV0dXJuIG5ld19wb2ludGVycwoKCmRlZiBnZXRGcm9tUFBhdGgoZGF0YSxwYXRoLGRlZmF1bHQ9W10pOgogICAgJycnCiAgICBUYWtlcyBhIHB5dGhvbiBkaWN0IGFuZCBhIHBwYXRoIHN0cmluZyBhbmQgZmluZHMgdGhlIAogICAgbWF0Y2hpbmcgZGF0YSBpbiB0aGUgZGljdC4gSWYgbm8gZGF0YSBjYW4gYmUgZm91bmQgdGhlIAogICAgZGVmYXVsdCBpcyByZXR1cm5lZAogICAgJycnCiAgICBwb2ludGVycyA9IFtkYXRhXQogICAgc2VnbWVudHMgPSBwYXRoU2VnbWVudFBhcnNlKHBhdGgpCiAgICBmb3Igc2VnbWVudCBpbiBzZWdtZW50czoKICAgICAgICBpZiBzZWdtZW50Wyd0eXBlJ10gPT0gJ3BhdGgnOgogICAgICAgICAgICBwb2ludGVycyA9IGFwcGx5UGF0aChzZWdtZW50LHBvaW50ZXJzKQogICAgICAgIGlmIHNlZ21lbnRbJ3R5cGUnXSA9PSAnZmlsdGVyJzoKICAgICAgICAgICAgcG9pbnRlcnMgPSBhcHBseUZpbHRlcihzZWdtZW50LHBvaW50ZXJzKQogICAgaWYgbGVuKHBvaW50ZXJzKT09MDoKICAgICAgICByZXR1cm4gZGVmYXVsdAogICAgcmV0dXJuIHBvaW50ZXJzCgoKCkpTT04gPSAnJycKewogICJmcmllbmRzIiA6IFsKICAgICAgICB7ImZpcnN0X25hbWUiOiAiV2VuZGVsbCIsICAgICJsYXN0X25hbWUiOiAiSm9yZGFuIiwgICAgInBob25lIjpbeyJ0eXBlIjoibW9iaWxlIiwibnVtYmVyIjoiNDQwLTEyMy04MTI2In0seyJ0eXBlIjoiaG9tZSIsIm51bWJlciI6IjQ0MC04OTAtNTU3MyJ9XSwiZ2VuZGVyIjoibWFsZSJ9LAogICAgICAgIHsiZmlyc3RfbmFtZSI6ICJKZWFubmUiLCAgICAgImxhc3RfbmFtZSI6ICJNb3JyaXMiLCAgICAicGhvbmUiOlt7InR5cGUiOiJtb2JpbGUiLCJudW1iZXIiOiIyMTYtMTIzLTAwNzkifSx7InR5cGUiOiJob21lIiwibnVtYmVyIjoiMjE2LTg5MC03ODMwIn1dLCJnZW5kZXIiOiJmZW1hbGUifSwKICAgICAgICB7ImZpcnN0X25hbWUiOiAiSGVybWFuIiwgICAgICJsYXN0X25hbWUiOiAiTWNkYW5pZWwiLCAgInBob25lIjpbeyJ0eXBlIjoibW9iaWxlIiwibnVtYmVyIjoiNDQwLTEyMy0xMzQ0In0seyJ0eXBlIjoiaG9tZSIsIm51bWJlciI6IjQ0MC04OTAtODgyNSJ9XSwiZ2VuZGVyIjoibWFsZSJ9LAogICAgICAgIHsiZmlyc3RfbmFtZSI6ICJFbWFudWVsIiwgICAgImxhc3RfbmFtZSI6ICJCZWNrZXIiLCAgICAicGhvbmUiOlt7InR5cGUiOiJtb2JpbGUiLCJudW1iZXIiOiIyMTYtMTIzLTg4MjUifSx7InR5cGUiOiJob21lIiwibnVtYmVyIjoiMjE2LTg5MC04MzMyIn1dLCJnZW5kZXIiOiJmZW1hbGUifSwKICAgICAgICB7ImZpcnN0X25hbWUiOiAiU2FyYSIsICAgICAgICJsYXN0X25hbWUiOiAiVG9kZCIsICAgICAgInBob25lIjpbeyJ0eXBlIjoibW9iaWxlIiwibnVtYmVyIjoiMjE2LTEyMy02MTE3In0seyJ0eXBlIjoiaG9tZSIsIm51bWJlciI6IjIxNi04OTAtMjg5OSJ9XSwiZ2VuZGVyIjoiZmVtYWxlIn0sCiAgICAgICAgeyJmaXJzdF9uYW1lIjogIlZpY3RvcmlhIiwgICAibGFzdF9uYW1lIjogIkdyYXkiLCAgICAgICJwaG9uZSI6W3sidHlwZSI6Im1vYmlsZSIsIm51bWJlciI6IjIxNi0xMjMtODQ1NiJ9LHsidHlwZSI6ImhvbWUiLCJudW1iZXIiOiIyMTYtODkwLTQ0NjkifV0sImdlbmRlciI6ImZlbWFsZSJ9LAogICAgICAgIHsiZmlyc3RfbmFtZSI6ICJSb25uaWUiLCAgICAgImxhc3RfbmFtZSI6ICJDb29rIiwgICAgICAicGhvbmUiOlt7InR5cGUiOiJtb2JpbGUiLCJudW1iZXIiOiIyMTYtMTIzLTIwMDYifSx7InR5cGUiOiJob21lIiwibnVtYmVyIjoiMjE2LTg5MC0yMDA2In1dLCJnZW5kZXIiOiJmZW1hbGUifSwKICAgICAgICB7ImZpcnN0X25hbWUiOiAiR2lsYmVydCIsICAgICJsYXN0X25hbWUiOiAiTW9ydG9uIiwgICAgInBob25lIjpbeyJ0eXBlIjoibW9iaWxlIiwibnVtYmVyIjoiNDQwLTEyMy00NTY3In0seyJ0eXBlIjoiaG9tZSIsIm51bWJlciI6IjQ0MC04OTAtNDU2NyJ9XSwiZ2VuZGVyIjoibWFsZSJ9LAogICAgICAgIHsiZmlyc3RfbmFtZSI6ICJDbGF1ZGlhIiwgICAgImxhc3RfbmFtZSI6ICJQYWRpbGxhIiwgICAicGhvbmUiOlt7InR5cGUiOiJtb2JpbGUiLCJudW1iZXIiOiIyMTYtMTIzLTQ1NjcifSx7InR5cGUiOiJob21lIiwibnVtYmVyIjoiMjE2LTg5MC00NTY3In1dLCJnZW5kZXIiOiJmZW1hbGUifSwKICAgICAgICB7ImZpcnN0X25hbWUiOiAiRG9yaXMiLCAgICAgICJsYXN0X25hbWUiOiAiTWF4d2VsbCIsICAgInBob25lIjpbeyJ0eXBlIjoibW9iaWxlIiwibnVtYmVyIjoiMjE2LTEyMy00NTY3In0seyJ0eXBlIjoiaG9tZSIsIm51bWJlciI6IjIxNi04OTAtNDU2NyJ9XSwiZ2VuZGVyIjoiZmVtYWxlIn0sCiAgICAgICAgeyJmaXJzdF9uYW1lIjogIkx1aXMiLCAgICAgICAibGFzdF9uYW1lIjogIlN0b2tlcyIsICAgICJwaG9uZSI6W3sidHlwZSI6Im1vYmlsZSIsIm51bWJlciI6IjQ0MC0xMjMtNDU2NyJ9LHsidHlwZSI6ImhvbWUiLCJudW1iZXIiOiI0NDAtODkwLTQ1NjcifV0sImdlbmRlciI6Im1hbGUifSwKICAgICAgICB7ImZpcnN0X25hbWUiOiAiQnlyb24iLCAgICAgICJsYXN0X25hbWUiOiAiS2VsbGV5IiwgICAgInBob25lIjpbeyJ0eXBlIjoibW9iaWxlIiwibnVtYmVyIjoiNDQwLTEyMy00NTY3In0seyJ0eXBlIjoiaG9tZSIsIm51bWJlciI6IjQ0MC04OTAtNDU2NyJ9XSwiZ2VuZGVyIjoibWFsZSJ9LAogICAgICAgIHsiZmlyc3RfbmFtZSI6ICJUZXJyaSIsICAgICAgImxhc3RfbmFtZSI6ICJIYXllcyIsICAgICAicGhvbmUiOlt7InR5cGUiOiJtb2JpbGUiLCJudW1iZXIiOiIyMTYtMTIzLTQ1NjcifSx7InR5cGUiOiJob21lIiwibnVtYmVyIjoiMjE2LTg5MC00NTY3In1dLCJnZW5kZXIiOiJmZW1hbGUifSwKICAgICAgICB7ImZpcnN0X25hbWUiOiAiRmxvcmEiLCAgICAgICJsYXN0X25hbWUiOiAiR3JlZW5lIiwgICAgInBob25lIjpbeyJ0eXBlIjoibW9iaWxlIiwibnVtYmVyIjoiMjE2LTEyMy00NTY3In0seyJ0eXBlIjoiaG9tZSIsIm51bWJlciI6IjIxNi04OTAtNDU2NyJ9XSwiZ2VuZGVyIjoiZmVtYWxlIn0sCiAgICAgICAgeyJmaXJzdF9uYW1lIjogIkd1YWRhbHVwZSIsICAibGFzdF9uYW1lIjogIlN0cmlja2xhbmQiLCJwaG9uZSI6W3sidHlwZSI6Im1vYmlsZSIsIm51bWJlciI6IjIxNi0xMjMtNDU2NyJ9LHsidHlwZSI6ImhvbWUiLCJudW1iZXIiOiIyMTYtODkwLTQ1NjcifV0sImdlbmRlciI6ImZlbWFsZSJ9LAogICAgICAgIHsiZmlyc3RfbmFtZSI6ICJTeWx2aWEiLCAgICAgImxhc3RfbmFtZSI6ICJTdXR0b24iLCAgICAicGhvbmUiOlt7InR5cGUiOiJtb2JpbGUiLCJudW1iZXIiOiIyMTYtMTIzLTQ1NjcifSx7InR5cGUiOiJob21lIiwibnVtYmVyIjoiMjE2LTg5MC00NTY3In1dLCJnZW5kZXIiOiJmZW1hbGUifSwKICAgICAgICB7ImZpcnN0X25hbWUiOiAiQ2Fyb2xpbmUiLCAgICJsYXN0X25hbWUiOiAiUGVya2lucyIsICAgInBob25lIjpbeyJ0eXBlIjoibW9iaWxlIiwibnVtYmVyIjoiMjE2LTEyMy00NTY3In0seyJ0eXBlIjoiaG9tZSIsIm51bWJlciI6IjIxNi04OTAtNDU2NyJ9XSwiZ2VuZGVyIjoiZmVtYWxlIn0sCiAgICAgICAgeyJmaXJzdF9uYW1lIjogIlNoZXJyaSIsICAgICAibGFzdF9uYW1lIjogIlJvc3MiLCAgICAgICJwaG9uZSI6W3sidHlwZSI6Im1vYmlsZSIsIm51bWJlciI6IjIxNi0xMjMtNDU2NyJ9LHsidHlwZSI6ImhvbWUiLCJudW1iZXIiOiIyMTYtODkwLTQ1NjcifV0sImdlbmRlciI6ImZlbWFsZSJ9LAogICAgICAgIHsiZmlyc3RfbmFtZSI6ICJMbG95ZCIsICAgICAgImxhc3RfbmFtZSI6ICJUb3duc2VuZCIsICAicGhvbmUiOlt7InR5cGUiOiJtb2JpbGUiLCJudW1iZXIiOiI0NDAtMTIzLTQ1NjcifSx7InR5cGUiOiJob21lIiwibnVtYmVyIjoiNDQwLTg5MC00NTY3In1dLCJnZW5kZXIiOiJtYWxlIn0sCiAgICAgICAgeyJmaXJzdF9uYW1lIjogIkNvZHkiLCAgICAgICAibGFzdF9uYW1lIjogIkVyaWNrc29uIiwgICJwaG9uZSI6W3sidHlwZSI6Im1vYmlsZSIsIm51bWJlciI6IjQ0MC0xMjMtNDU2NyJ9LHsidHlwZSI6ImhvbWUiLCJudW1iZXIiOiI0NDAtODkwLTQ1NjcifV0sImdlbmRlciI6Im1hbGUifSwKICAgICAgICB7ImZpcnN0X25hbWUiOiAiUm9uIiwgICAgICAgICJsYXN0X25hbWUiOiAiV2lsbGlhbXMiLCAgInBob25lIjpbeyJ0eXBlIjoibW9iaWxlIiwibnVtYmVyIjoiNDQwLTEyMy00NTY3In0seyJ0eXBlIjoiaG9tZSIsIm51bWJlciI6IjQ0MC04OTAtNDU2NyJ9XSwiZ2VuZGVyIjoibWFsZSJ9LAogICAgICAgIHsiZmlyc3RfbmFtZSI6ICJGcmFuY2lzIiwgICAgImxhc3RfbmFtZSI6ICJGaXR6Z2VyYWxkIiwicGhvbmUiOlt7InR5cGUiOiJtb2JpbGUiLCJudW1iZXIiOiIyMTYtMTIzLTQ1NjcifSx7InR5cGUiOiJob21lIiwibnVtYmVyIjoiMjE2LTg5MC00NTY3In1dLCJnZW5kZXIiOiJmZW1hbGUifSwKICAgICAgICB7ImZpcnN0X25hbWUiOiAiS2VubmV0aCIsICAgICJsYXN0X25hbWUiOiAiSG9wa2lucyIsICAgInBob25lIjpbeyJ0eXBlIjoibW9iaWxlIiwibnVtYmVyIjoiNDQwLTEyMy00NTY3In0seyJ0eXBlIjoiaG9tZSIsIm51bWJlciI6IjQ0MC04OTAtNDU2NyJ9XSwiZ2VuZGVyIjoibWFsZSJ9LAogICAgICAgIHsiZmlyc3RfbmFtZSI6ICJNYXJ5IiwgICAgICAgImxhc3RfbmFtZSI6ICJCYWxsYXJkIiwgICAicGhvbmUiOlt7InR5cGUiOiJtb2JpbGUiLCJudW1iZXIiOiIyMTYtMTIzLTQ1NjcifSx7InR5cGUiOiJob21lIiwibnVtYmVyIjoiMjE2LTg5MC00NTY3In1dLCJnZW5kZXIiOiJmZW1hbGUifSwKICAgICAgICB7ImZpcnN0X25hbWUiOiAiQW5kcmUiLCAgICAgICJsYXN0X25hbWUiOiAiTGV3aXMiLCAgICAgInBob25lIjpbeyJ0eXBlIjoibW9iaWxlIiwibnVtYmVyIjoiNDQwLTEyMy00NTY3In0seyJ0eXBlIjoiaG9tZSIsIm51bWJlciI6IjQ0MC04OTAtNDU2NyJ9XSwiZ2VuZGVyIjoibWFsZSJ9LAogICAgICAgIHsiZmlyc3RfbmFtZSI6ICJNYXJndWVyaXRlIiwgImxhc3RfbmFtZSI6ICJNZWRpbmEiLCAgICAicGhvbmUiOlt7InR5cGUiOiJtb2JpbGUiLCJudW1iZXIiOiIyMTYtMTIzLTQ1NjcifSx7InR5cGUiOiJob21lIiwibnVtYmVyIjoiMjE2LTg5MC00NTY3In1dLCJnZW5kZXIiOiJmZW1hbGUifSwKICAgICAgICB7ImZpcnN0X25hbWUiOiAiUmFjaGFlbCIsICAgICJsYXN0X25hbWUiOiAiQnJvd24iLCAgICAgInBob25lIjpbeyJ0eXBlIjoibW9iaWxlIiwibnVtYmVyIjoiMjE2LTEyMy00NTY3In0seyJ0eXBlIjoiaG9tZSIsIm51bWJlciI6IjIxNi04OTAtNDU2NyJ9XSwiZ2VuZGVyIjoiZmVtYWxlIn0sCiAgICAgICAgeyJmaXJzdF9uYW1lIjogIkRhcnlsIiwgICAgICAibGFzdF9uYW1lIjogIk1jY2FydGh5IiwgICJwaG9uZSI6W3sidHlwZSI6Im1vYmlsZSIsIm51bWJlciI6IjQ0MC0xMjMtNDU2NyJ9LHsidHlwZSI6ImhvbWUiLCJudW1iZXIiOiI0NDAtODkwLTQ1NjcifV0sImdlbmRlciI6Im1hbGUifSwKICAgICAgICB7ImZpcnN0X25hbWUiOiAiU2hlbGlhIiwgICAgICJsYXN0X25hbWUiOiAiU2NodWx0eiIsICAgInBob25lIjpbeyJ0eXBlIjoibW9iaWxlIiwibnVtYmVyIjoiMjE2LTEyMy00NTY3In0seyJ0eXBlIjoiaG9tZSIsIm51bWJlciI6IjIxNi04OTAtNDU2NyJ9XSwiZ2VuZGVyIjoiZmVtYWxlIn0sCiAgICAgICAgeyJmaXJzdF9uYW1lIjogIkdlb2ZmcmV5IiwgICAibGFzdF9uYW1lIjogIk1jZG9uYWxkIiwgICJwaG9uZSI6W3sidHlwZSI6Im1vYmlsZSIsIm51bWJlciI6IjQ0MC0xMjMtNDU2NyJ9LHsidHlwZSI6ImhvbWUiLCJudW1iZXIiOiI0NDAtODkwLTQ1NjcifV0sImdlbmRlciI6Im1hbGUifSwKICAgICAgICB7ImZpcnN0X25hbWUiOiAiVHlsZXIiLCAgICAgICJsYXN0X25hbWUiOiAiTmljaG9scyIsICAgInBob25lIjpbeyJ0eXBlIjoibW9iaWxlIiwibnVtYmVyIjoiNDQwLTEyMy00NTY3In0seyJ0eXBlIjoiaG9tZSIsIm51bWJlciI6IjQ0MC04OTAtNDU2NyJ9XSwiZ2VuZGVyIjoibWFsZSJ9LAogICAgICAgIHsiZmlyc3RfbmFtZSI6ICJHcmV0Y2hlbiIsICAgImxhc3RfbmFtZSI6ICJHcmF2ZXMiLCAgICAicGhvbmUiOlt7InR5cGUiOiJtb2JpbGUiLCJudW1iZXIiOiIyMTYtMTIzLTQ1NjcifSx7InR5cGUiOiJob21lIiwibnVtYmVyIjoiMjE2LTg5MC00NTY3In1dLCJnZW5kZXIiOiJmZW1hbGUifSwKICAgICAgICB7ImZpcnN0X25hbWUiOiAiTG9yYSIsICAgICAgICJsYXN0X25hbWUiOiAiUGVhcnNvbiIsICAgInBob25lIjpbeyJ0eXBlIjoibW9iaWxlIiwibnVtYmVyIjoiMjE2LTEyMy00NTY3In0seyJ0eXBlIjoiaG9tZSIsIm51bWJlciI6IjIxNi04OTAtNDU2NyJ9XSwiZ2VuZGVyIjoiZmVtYWxlIn0sCiAgICAgICAgeyJmaXJzdF9uYW1lIjogIkthdGllIiwgICAgICAibGFzdF9uYW1lIjogIldhdHRzIiwgICAgICJwaG9uZSI6W3sidHlwZSI6Im1vYmlsZSIsIm51bWJlciI6IjIxNi0xMjMtNDU2NyJ9LHsidHlwZSI6ImhvbWUiLCJudW1iZXIiOiIyMTYtODkwLTQ1NjcifV0sImdlbmRlciI6ImZlbWFsZSJ9LAogICAgICAgIHsiZmlyc3RfbmFtZSI6ICJUYXlsb3IiLCAgICAgImxhc3RfbmFtZSI6ICJKZW5uaW5ncyIsICAicGhvbmUiOlt7InR5cGUiOiJtb2JpbGUiLCJudW1iZXIiOiIyMTYtMTIzLTQ1NjcifSx7InR5cGUiOiJob21lIiwibnVtYmVyIjoiMjE2LTg5MC00NTY3In1dLCJnZW5kZXIiOiJmZW1hbGUifSwKICAgICAgICB7ImZpcnN0X25hbWUiOiAiUGFtZWxhIiwgICAgICJsYXN0X25hbWUiOiAiQnVjaGFuYW4iLCAgInBob25lIjpbeyJ0eXBlIjoibW9iaWxlIiwibnVtYmVyIjoiMjE2LTEyMy00NTY3In0seyJ0eXBlIjoiaG9tZSIsIm51bWJlciI6IjIxNi04OTAtNDU2NyJ9XSwiZ2VuZGVyIjoiZmVtYWxlIn0sCiAgICAgICAgeyJmaXJzdF9uYW1lIjogIk1hcmsiLCAgICAgICAibGFzdF9uYW1lIjogIlBvdHRlciIsICAgICJwaG9uZSI6W3sidHlwZSI6Im1vYmlsZSIsIm51bWJlciI6IjQ0MC0xMjMtNDU2NyJ9LHsidHlwZSI6ImhvbWUiLCJudW1iZXIiOiI0NDAtODkwLTQ1NjcifV0sImdlbmRlciI6Im1hbGUifSwKICAgICAgICB7ImZpcnN0X25hbWUiOiAiRG9taW5nbyIsICAgICJsYXN0X25hbWUiOiAiQWxsZW4iLCAgICAgInBob25lIjpbeyJ0eXBlIjoibW9iaWxlIiwibnVtYmVyIjoiNDQwLTEyMy00NTY3In0seyJ0eXBlIjoiaG9tZSIsIm51bWJlciI6IjQ0MC04OTAtNDU2NyJ9XSwiZ2VuZGVyIjoibWFsZSJ9LAogICAgICAgIHsiZmlyc3RfbmFtZSI6ICJKZWFuIiwgICAgICAgImxhc3RfbmFtZSI6ICJLaW0iLCAgICAgICAicGhvbmUiOlt7InR5cGUiOiJtb2JpbGUiLCJudW1iZXIiOiIyMTYtMTIzLTQ1NjcifSx7InR5cGUiOiJob21lIiwibnVtYmVyIjoiMjE2LTg5MC00NTY3In1dLCJnZW5kZXIiOiJmZW1hbGUifSwKICAgICAgICB7ImZpcnN0X25hbWUiOiAiTW9uaXF1ZSIsICAgICJsYXN0X25hbWUiOiAiU3VsbGl2YW4iLCAgInBob25lIjpbeyJ0eXBlIjoibW9iaWxlIiwibnVtYmVyIjoiMjE2LTEyMy00NTY3In0seyJ0eXBlIjoiaG9tZSIsIm51bWJlciI6IjIxNi04OTAtNDU2NyJ9XSwiZ2VuZGVyIjoiZmVtYWxlIn0sCiAgICAgICAgeyJmaXJzdF9uYW1lIjogIlRoZXJlc2EiLCAgICAibGFzdF9uYW1lIjogIkJlY2siLCAgICAgICJwaG9uZSI6W3sidHlwZSI6Im1vYmlsZSIsIm51bWJlciI6IjIxNi0xMjMtNDU2NyJ9LHsidHlwZSI6ImhvbWUiLCJudW1iZXIiOiIyMTYtODkwLTQ1NjcifV0sImdlbmRlciI6ImZlbWFsZSJ9LAogICAgICAgIHsiZmlyc3RfbmFtZSI6ICJNb3JyaXMiLCAgICAgImxhc3RfbmFtZSI6ICJNb3Jlbm8iLCAgICAicGhvbmUiOlsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7InR5cGUiOiJob21lIiwibnVtYmVyIjoiNDQwLTg5MC00NTY3In1dLCJnZW5kZXIiOiJtYWxlIn0sCiAgICAgICAgeyJmaXJzdF9uYW1lIjogIldhZGUiLCAgICAgICAibGFzdF9uYW1lIjogIkx1bmEiLCAgICAgICJwaG9uZSI6W3sidHlwZSI6Im1vYmlsZSIsIm51bWJlciI6IjQ0MC0xMjMtNDU2NyJ9LHsidHlwZSI6ImhvbWUiLCJudW1iZXIiOiI0NDAtODkwLTQ1NjcifV0sImdlbmRlciI6Im1hbGUifSwKICAgICAgICB7ImZpcnN0X25hbWUiOiAiVHJhY2kiLCAgICAgICJsYXN0X25hbWUiOiAiR2FyY2lhIiwgICAgInBob25lIjpbeyJ0eXBlIjoibW9iaWxlIiwibnVtYmVyIjoiMjE2LTEyMy00NTY3In0seyJ0eXBlIjoiaG9tZSIsIm51bWJlciI6IjIxNi04OTAtNDU2NyJ9XSwiZ2VuZGVyIjoiZmVtYWxlIn0sCiAgICAgICAgeyJmaXJzdF9uYW1lIjogIkFsYW4iLCAgICAgICAibGFzdF9uYW1lIjogIldhc2hpbmd0b24iLCJwaG9uZSI6W3sidHlwZSI6Im1vYmlsZSIsIm51bWJlciI6IjQ0MC0xMjMtNDU2NyJ9LHsidHlwZSI6ImhvbWUiLCJudW1iZXIiOiI0NDAtODkwLTQ1NjcifV0sImdlbmRlciI6Im1hbGUifSwKICAgICAgICB7ImZpcnN0X25hbWUiOiAiVG9uaSIsICAgICAgICJsYXN0X25hbWUiOiAiV2VhdmVyIiwgICAgInBob25lIjpbeyJ0eXBlIjoibW9iaWxlIiwibnVtYmVyIjoiMjE2LTEyMy00NTY3In0seyJ0eXBlIjoiaG9tZSIsIm51bWJlciI6IjIxNi04OTAtNDU2NyJ9XSwiZ2VuZGVyIjoiZmVtYWxlIn0sCiAgICAgICAgeyJmaXJzdF9uYW1lIjogIkRhdmlkIiwgICAgICAibGFzdF9uYW1lIjogIkJyb3duIiwgICAgICJwaG9uZSI6W3sidHlwZSI6Im1vYmlsZSIsIm51bWJlciI6IjQ0MC0xMjMtNDU2NyJ9LHsidHlwZSI6ImhvbWUiLCJudW1iZXIiOiI0NDAtODkwLTQ1NjcifV0sImdlbmRlciI6Im1hbGUifSwKICAgICAgICB7ImZpcnN0X25hbWUiOiAiU2VyZ2lvIiwgICAgICJsYXN0X25hbWUiOiAiTWFyc2giLCAgICAgInBob25lIjpbeyJ0eXBlIjoibW9iaWxlIiwibnVtYmVyIjoiNDQwLTEyMy00NTY3In0seyJ0eXBlIjoiaG9tZSIsIm51bWJlciI6IjQ0MC04OTAtNDU2NyJ9XSwiZ2VuZGVyIjoibWFsZSJ9LAogICAgICAgIHsiZmlyc3RfbmFtZSI6ICJDaGFybGllIiwgICAgImxhc3RfbmFtZSI6ICJSaWNlIiwgICAgICAicGhvbmUiOlt7InR5cGUiOiJtb2JpbGUiLCJudW1iZXIiOiI0NDAtMTIzLTQ1NjcifSx7InR5cGUiOiJob21lIiwibnVtYmVyIjoiNDQwLTg5MC00NTY3In1dLCJnZW5kZXIiOiJtYWxlIn0sCiAgICAgICAgeyJmaXJzdF9uYW1lIjogIkJlcm5hcmQiLCAgICAibGFzdF9uYW1lIjogIkhvZ2FuIiwgICAgICJwaG9uZSI6W3sidHlwZSI6Im1vYmlsZSIsIm51bWJlciI6IjQ0MC0xMjMtNDU2NyJ9LHsidHlwZSI6ImhvbWUiLCJudW1iZXIiOiI0NDAtODkwLTQ1NjcifV0sImdlbmRlciI6Im1hbGUifSAKICBdCn0KJycnCgpkYXRhID0ganNvbi5sb2FkcyhKU09OKQoKIyBob3cgbWFueSBmcmllbmRzIGRvIEkgaGF2ZT8KYXNzZXJ0KGxlbihnZXRGcm9tUFBhdGgoZGF0YSwnZnJpZW5kcycpKT09NTApCiMgaG93IG1hbnkgZnJpZW5kcyB3aXRoIHRoZSBsYXN0IG5hbWUgYnJvd24/CmFzc2VydChsZW4oZ2V0RnJvbVBQYXRoKGRhdGEsJ2ZyaWVuZHNbbGFzdF9uYW1lPUJyb3duXScpKT09MikKIyBXaGF0IGFyZSB0aGUgZmlyc3QgbmFtZXMgb2YgdGhlIGZyaWVuZHMgd2hvc2UgbGFzdCBuYW1lcyBhcmUgYnJvd24/CmFzc2VydChnZXRGcm9tUFBhdGgoZGF0YSwnZnJpZW5kc1tsYXN0X25hbWU9QnJvd25dLmZpcnN0X25hbWUnKVswXT09IlJhY2hhZWwiKQphc3NlcnQoZ2V0RnJvbVBQYXRoKGRhdGEsJ2ZyaWVuZHNbbGFzdF9uYW1lPUJyb3duXS5maXJzdF9uYW1lJylbMV09PSJEYXZpZCIpCiMgd2hhdCdzIHRoZSBmaXJzdCBuYW1lIG9mIHRoZSBwZXJzb24gd2l0aCB0aGlzIHBob25lIG51bWJlcj8KYXNzZXJ0KGxlbihnZXRGcm9tUFBhdGgoZGF0YSwiZnJpZW5kc1twaG9uZS5udW1iZXI9MjE2LTg5MC03ODMwXS5maXJzdF9uYW1lIikpPT0xKQphc3NlcnQoZ2V0RnJvbVBQYXRoKGRhdGEsImZyaWVuZHNbcGhvbmUubnVtYmVyPTIxNi04OTAtNzgzMF0uZmlyc3RfbmFtZSIpWzBdPT0iSmVhbm5lIikKIyB3aGF0IGFib3V0IHRoaXMgcGhvbmUgbnVtYmVyPwphc3NlcnQobGVuKGdldEZyb21QUGF0aChkYXRhLCJmcmllbmRzW3Bob25lLm51bWJlcj0yMTYtMTIzLTAwNzldLmZpcnN0X25hbWUiKSk9PTEpCmFzc2VydChnZXRGcm9tUFBhdGgoZGF0YSwiZnJpZW5kc1twaG9uZS5udW1iZXI9MjE2LTEyMy0wMDc5XS5maXJzdF9uYW1lIilbMF09PSJKZWFubmUiKQojIEhvdyBtYW55IGZyaWVuZHMgYXJlIGZlbWFsZT8KYXNzZXJ0KGxlbihnZXRGcm9tUFBhdGgoZGF0YSwiZnJpZW5kc1tnZW5kZXI9ZmVtYWxlXSIpKT09MjgpCiMgRmlyc3QgbmFtZXMgb2YgZmVtYWxlIGZyaWVuZHMKYXNzZXJ0KGxlbihnZXRGcm9tUFBhdGgoZGF0YSwiZnJpZW5kc1tnZW5kZXI9ZmVtYWxlXS5maXJzdF9uYW1lIikpPT0yOCkKYXNzZXJ0KGdldEZyb21QUGF0aChkYXRhLCJmcmllbmRzW2dlbmRlcj1mZW1hbGVdLmZpcnN0X25hbWUiKVswXT09IkplYW5uZSIpCmFzc2VydChnZXRGcm9tUFBhdGgoZGF0YSwiZnJpZW5kc1tnZW5kZXI9ZmVtYWxlXS5maXJzdF9uYW1lIilbMTBdPT0iU3lsdmlhIikKYXNzZXJ0KGdldEZyb21QUGF0aChkYXRhLCJmcmllbmRzW2dlbmRlcj1mZW1hbGVdLmZpcnN0X25hbWUiKVsyN109PSJUb25pIikKIyBQaG9uZSBudW1iZXJzIG9mIGZlbWFsZSBmcmllbmRzCmFzc2VydChsZW4oZ2V0RnJvbVBQYXRoKGRhdGEsImZyaWVuZHNbZ2VuZGVyPWZlbWFsZV0ucGhvbmUubnVtYmVyIikpPT01NikKYXNzZXJ0KGdldEZyb21QUGF0aChkYXRhLCJmcmllbmRzW2dlbmRlcj1mZW1hbGVdLnBob25lLm51bWJlciIpWzBdPT0iMjE2LTEyMy0wMDc5IikKYXNzZXJ0KGdldEZyb21QUGF0aChkYXRhLCJmcmllbmRzW2dlbmRlcj1mZW1hbGVdLnBob25lLm51bWJlciIpWzEwXT09IjIxNi0xMjMtNDU2NyIpCmFzc2VydChnZXRGcm9tUFBhdGgoZGF0YSwiZnJpZW5kc1tnZW5kZXI9ZmVtYWxlXS5waG9uZS5udW1iZXIiKVs1NV09PSIyMTYtODkwLTQ1NjciKQojIE1vYmlsZSBwaG9uZSBudW1iZXJzIG9mIGZlbWFsZSBmcmllbmRzCmFzc2VydChsZW4oZ2V0RnJvbVBQYXRoKGRhdGEsImZyaWVuZHNbZ2VuZGVyPWZlbWFsZV0ucGhvbmVbdHlwZT1tb2JpbGVdLm51bWJlciIpKT09MjgpCmFzc2VydChnZXRGcm9tUFBhdGgoZGF0YSwiZnJpZW5kc1tnZW5kZXI9ZmVtYWxlXS5waG9uZVt0eXBlPW1vYmlsZV0ubnVtYmVyIilbMF09PSIyMTYtMTIzLTAwNzkiKQphc3NlcnQoZ2V0RnJvbVBQYXRoKGRhdGEsImZyaWVuZHNbZ2VuZGVyPWZlbWFsZV0ucGhvbmVbdHlwZT1tb2JpbGVdLm51bWJlciIpWzEwXT09IjIxNi0xMjMtNDU2NyIpCmFzc2VydChnZXRGcm9tUFBhdGgoZGF0YSwiZnJpZW5kc1tnZW5kZXI9ZmVtYWxlXS5waG9uZVt0eXBlPW1vYmlsZV0ubnVtYmVyIilbMjddPT0iMjE2LTEyMy00NTY3IikKIyBNYWxlIGZyaWVuZHMKYXNzZXJ0KGxlbihnZXRGcm9tUFBhdGgoZGF0YSwiZnJpZW5kc1tnZW5kZXI9bWFsZV0iKSk9PTIyKQojIE1hbGUgZnJpZW5kcyB3aXRoIG1vYmlsZSBwaG9uZXMKYXNzZXJ0KGxlbihnZXRGcm9tUFBhdGgoZGF0YSwiZnJpZW5kc1tnZW5kZXI9bWFsZV1bcGhvbmUudHlwZT1tb2JpbGVdIikpPT0yMSkKIyBNYWxlIGZyaWVuZHMgd2l0aCBob21lIHBob25lcwphc3NlcnQobGVuKGdldEZyb21QUGF0aChkYXRhLCJmcmllbmRzW2dlbmRlcj1tYWxlXVtwaG9uZS50eXBlPWhvbWVdIikpPT0yMikKIyBGaXJzdCBuYW1lcyBvZiBtYWxlIGZyaWVuZHMgd2l0aCBob21lIHBob25lcwphc3NlcnQoZ2V0RnJvbVBQYXRoKGRhdGEsImZyaWVuZHNbZ2VuZGVyPW1hbGVdW3Bob25lLnR5cGU9aG9tZV0uZmlyc3RfbmFtZSIpWzBdPT0iV2VuZGVsbCIpCmFzc2VydChnZXRGcm9tUFBhdGgoZGF0YSwiZnJpZW5kc1tnZW5kZXI9bWFsZV1bcGhvbmUudHlwZT1ob21lXS5maXJzdF9uYW1lIilbMTBdPT0iRGFyeWwiKQphc3NlcnQoZ2V0RnJvbVBQYXRoKGRhdGEsImZyaWVuZHNbZ2VuZGVyPW1hbGVdW3Bob25lLnR5cGU9aG9tZV0uZmlyc3RfbmFtZSIpWzIxXT09IkJlcm5hcmQiKQojIE1hbGUgZnJpZW5kcyB3aXRoIGZheCBudW1iZXJzCmFzc2VydChsZW4oZ2V0RnJvbVBQYXRoKGRhdGEsImZyaWVuZHNbZ2VuZGVyPW1hbGVdW3Bob25lLnR5cGU9ZmF4XSIpKT09MCkKCgoKCg==