# Nalvo node installer for Ubuntu Server 24.04.5 LTS # ISO: ubuntu-24.04.5-live-server-amd64.iso # sha256 97f3d7ffb032c3eb3b23d2c8be9cc76e60c2c1f2c0146ba5ba9fe01cafae0fd8 (releases.ubuntu.com/24.04/SHA256SUMS) # Made by the Fleet Manager's "Make a Nalvo node" maker (supports Vast.ai). # The served file contains no passwords, keys or codes. A stick made by the # maker contains one single-use installer code valid for 24 hours. # What the person sees: # One empty internal disk found: Ubuntu asks "Continue with autoinstall? (yes|no)" # once, then erases and installs that disk and restarts by itself. # Otherwise (existing data such as Windows, several disks, or a probe failure) # there is no yes/no question: the disk screen opens, the person picks the disk # and confirms "Confirm destructive action", and at the end must choose "Reboot Now". # Either way, when the screen says "Please remove the installation medium, then # press ENTER", remove the stick and press ENTER. # The identity below is only a fallback (a locked account, no password); the early # commands replace it with the stick's computer name and a random, never-shown hash. # Generated from installer/autoinstall.template.yaml by ops/make-autoinstall.py; do not edit by hand. # Keep all embedded asset lines intact. #NALVO-PAIR: #NALVO-NAME: #NALVO-B64:IyEvYmluL2Jhc2gKIyBOYWx2byBub2RlIGZpcnN0LWJvb3Qgc2V0dXAgZm9yIFVidW50dSBTZXJ2ZXIgMjQuMDQuNSBMVFMsIGluc3RhbGxlZCBieSB0aGUKIyBOYWx2byBhdXRvaW5zdGFsbCBmaWxlIChpbnN0YWxsZXIvYXV0b2luc3RhbGwudGVtcGxhdGUueWFtbCkuIFJ1bnMgYXMgcm9vdCBvbgojIHR0eTEgb24gdGhlIGZpcnN0IGJvb3RzIG9mIHRoZSBJTlNUQUxMRUQgc3lzdGVtLCBuZXZlciBmcm9tIHRoZSBVU0Igc2Vzc2lvbi4KIwojIFN0ZXBzLCBlYWNoIGlkZW1wb3RlbnQgd2l0aCBhIG1hcmtlciBpbiAkU1RBVEU6CiMgICBndWFyZCAgICAgIHJlZnVzZSBvbiBhIGxpdmUvaW5zdGFsbGVyIHNlc3Npb24gKG92ZXJsYXkvc3F1YXNoZnMvdG1wZnMgcm9vdCwgYm9vdD1jYXNwZXIpCiMgICBoeWdpZW5lICAgIGF1dG9tYXRpYyB1cGdyYWRlcyBvZmYsIHJlbGVhc2UgdXBncmFkZXMgb2ZmLCBTU0ggcGFzc3dvcmQgbG9naW4gb2ZmCiMgICBkb2NrZXIgICAgIERvY2tlciBzdG9yYWdlIG9uIHRoZSByZXN0IG9mIHRoZSBpbnN0YWxsIGRpc2s6IExWTSB2b2x1bWUsIFhGUywgcHF1b3RhLCAvdmFyL2xpYi9kb2NrZXIKIyAgIGRyaXZlciAgICAgTlZJRElBIGRyaXZlciBleGFjdGx5IGFzIFZhc3QgZG9jdW1lbnRzIGl0IChyZXBvLCBwaW5uaW5nIHBhY2thZ2UsIGhvbGQpLCBvbmUgcmVib290CiMgICBhZ2VudCAgICAgIE5hbHZvIE5vZGUgQWdlbnQgZG93bmxvYWRlZCBmcm9tIHRoZSBGbGVldCBNYW5hZ2VyIGFuZCBjaGVja2VkIGFnYWluc3QgaXRzIG1hbmlmZXN0CiMgICBwYWlyICAgICAgIHVzZSB0aGUgc3RpY2sncyBpbnN0YWxsZXIgY29kZSwgb3IgYXNrIHRoZSBvd25lciBmb3Igb25lCiMgICBmaW5pc2ggICAgIGtlZXAgYSBwcml2YXRlIHN1cHBvcnQgY3JlZGVudGlhbCBhbmQgY29tcGxldGUgc2V0dXAKIyBUaGUgbm9kZSBlbmRzIHVwIHJlYWR5IGZvciBFSVRIRVIgTmFsdm8gb3IgVmFzdDsgbm90aGluZyBoZXJlIGxpc3RzIGl0IGFueXdoZXJlLgojIEFmdGVyIHRoZSBpbnN0YWxsIG5vdGhpbmcgaGVyZSBlcmFzZXMgZGF0YTogbmV3IHZvbHVtZXMgb25seSB1c2UgZnJlZSBzcGFjZS4KIwojIFVzYWdlOiBuYWx2by1maXJzdGJvb3QgaW5zdGFsbCAgICAoZnJvbSB0aGUgaW5zdGFsbGVyJ3MgbGF0ZS1jb21tYW5kcywgaW4tdGFyZ2V0KQojICAgICAgICBuYWx2by1maXJzdGJvb3QgcnVuICAgICAgICAoc3lzdGVtZCwgb24gdHR5MSkKIyAgICAgICAgbmFsdm8tZmlyc3Rib290IHJlYWRpbmVzcyAgKHByaW50IGFuZCByZWNvcmQgdGhlIFZhc3QgcmVhZGluZXNzIGZhY3RzKQpzZXQgLXUKRkxFRVQ9IiR7TkFMVk9fRkxFRVQ6LWh0dHBzOi8vZmxlZXQubmFsdm8uYWl9IgpTVEFURT0vdmFyL2xpYi9uYWx2by1maXJzdGJvb3QKQ09OU09MRV9QQVNTV09SRF9GSUxFPS9yb290L25hbHZvLWNvbnNvbGUtcGFzc3dvcmQKTE9HPS92YXIvbG9nL25hbHZvL2ZpcnN0Ym9vdC5sb2cKQUdFTlRfRElSPS9vcHQvbmFsdm8KQUdFTlQ9IiRBR0VOVF9ESVIvbmFsdm9fbm9kZS5weSIKVU5JVD0vZXRjL3N5c3RlbWQvc3lzdGVtL25hbHZvLWZpcnN0Ym9vdC5zZXJ2aWNlClNFTEY9L3Vzci9sb2NhbC9zYmluL25hbHZvLWZpcnN0Ym9vdApMT0NLPS9ydW4vbmFsdm8tZmlyc3Rib290LmxvY2sKR1VBUkRfT0s9MCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyAxIG9uY2UgdGhpcyBpcyBrbm93biB0byBiZSB0aGUgaW5zdGFsbGVkIHN5c3RlbSwgbm90IHRoZSBVU0Igc2Vzc2lvbgpXSUZJX0ZJUk1XQVJFX0FUVEVNUFRFRD0wCiMgVmFzdCdzIGRvY3VtZW50ZWQgbWluaW11bSBkcml2ZXJzIChkb2NzLnZhc3QuYWkvaG9zdC91cGdyYWRlLW52aWRpYS1kcml2ZXIsIHJlYWQgMjAyNi0xMS0wMSkKT1BFTl9EUklWRVJfVkVSU0lPTj02MTAuNTcuMDQgICAgICAgICAgIyBjb21wdXRlIGNhcGFiaWxpdHkgNy41KyAoVHVyaW5nIGFuZCBuZXdlciksIGZyZXNoIG1hY2hpbmUKT1BFTl9EUklWRVJfUEFDS0FHRT1udmlkaWEtb3BlbgpMRUdBQ1lfRFJJVkVSX1ZFUlNJT049NTgwLjE3OC4wNCAgICAgICAjIE1heHdlbGwsIFBhc2NhbCwgVm9sdGEKTEVHQUNZX0RSSVZFUl9QQUNLQUdFPW52aWRpYS1kcml2ZXItNTgwCkRPQ0tFUl9NSU5fR0I9MjAwICAgICAgICAgICAgICAgICAgICAgICMgVmFzdDogZGVkaWNhdGVkIERvY2tlciBzdG9yYWdlIDIwMCBHQgpST09UX0ZSRUVfTUlOX0dCPTIwICAgICAgICAgICAgICAgICAgICAjIFZhc3Q6IHJvb3QgcGFydGl0aW9uIGZyZWUgc3BhY2UgMjAgR0IKQVBUPSJhcHQtZ2V0IC1vIERQa2c6OkxvY2s6OlRpbWVvdXQ9NjAwIC1vIERwa2c6Ok9wdGlvbnM6Oj0tLWZvcmNlLWNvbmZkZWYgLW8gRHBrZzo6T3B0aW9uczo6PS0tZm9yY2UtY29uZm9sZCIKZXhwb3J0IERFQklBTl9GUk9OVEVORD1ub25pbnRlcmFjdGl2ZQoKc2F5KCkgeyBwcmludGYgJyVzXG4nICIkKiI7IHByaW50ZiAnJXMgJXNcbicgIiQoZGF0ZSAtdSArJUZUJVRaKSIgIiQqIiA+PiIkTE9HIjsgfQpzdGVwKCkgeyBzYXkgIk5hbHZvIG5vZGUgc2V0dXAgLSBzdGVwICQxIG9mIDY6ICQyIjsgfQpzaG93X2luc3RhbGxfZ3VpZGUoKSB7CiAgICBsb2NhbCB1cmw9J2h0dHBzOi8vZmxlZXQubmFsdm8uYWkvaW5zdGFsbC1ndWlkZS5odG1sI3N0ZXA9Zmlyc3Rib290JwogICAgcHJpbnRmICdGb2xsb3cgc2V0dXAgb24geW91ciBwaG9uZTogJXNcbicgIiR1cmwiCiAgICBQWVRIT05JT0VOQ09ESU5HPXV0Zi04IHB5dGhvbjMgLUkgLSAvdXNyL2xvY2FsL2xpYi9uYWx2by9xci5weSAiJHVybCIgMj4vZGV2L251bGwgPDwnUFknIHx8IHRydWUKaW1wb3J0IHJ1bnB5LCBzeXMKbWF0cml4ID0gcnVucHkucnVuX3BhdGgoc3lzLmFyZ3ZbMV0pWyJlbmNvZGUiXShzeXMuYXJndlsyXS5lbmNvZGUoInV0Zi04IikpCndpZHRoID0gbGVuKG1hdHJpeCkgKyA4CnJvd3MgPSBbW0ZhbHNlXSAqIHdpZHRoIGZvciBfIGluIHJhbmdlKDQpXQpyb3dzICs9IFtbRmFsc2VdICogNCArIHJvdyArIFtGYWxzZV0gKiA0IGZvciByb3cgaW4gbWF0cml4XQpyb3dzICs9IFtbRmFsc2VdICogd2lkdGggZm9yIF8gaW4gcmFuZ2UoNCldCmlmIGxlbihyb3dzKSAlIDI6CiAgICByb3dzLmFwcGVuZChbRmFsc2VdICogd2lkdGgpCmJsb2NrcyA9ICgiICIsICJcdTI1ODQiLCAiXHUyNTgwIiwgIlx1MjU4OCIpCmxpbmVzID0gWyIiLmpvaW4oYmxvY2tzWzIgKiBhICsgYl0gZm9yIGEsIGIgaW4gemlwKHJvd3NbeV0sIHJvd3NbeSArIDFdKSkKICAgICAgICAgZm9yIHkgaW4gcmFuZ2UoMCwgbGVuKHJvd3MpLCAyKV0Kc3lzLnN0ZG91dC5idWZmZXIud3JpdGUoKCJcMDMzWzMwOzQ3bSIgKyAiXG4iLmpvaW4obGluZXMpICsgIlwwMzNbMG1cbiIpLmVuY29kZSgidXRmLTgiKSkKUFkKfQptYXJrKCkgeyB0b3VjaCAiJFNUQVRFLyQxIjsgfQpkb25lXygpIHsgWyAtZSAiJFNUQVRFLyQxIiBdOyB9CnN0b3BfaGVyZSgpIHsgICAjIGtlZXAgdHR5MSB3aXRoIHNldHVwLCBhbmQgcmV0cnkgdGhlIGlkZW1wb3RlbnQgc3RlcHMgb24gcmVxdWVzdAogICAgIyBJbnN0YWxsYXRpb24gaGFzIGFscmVhZHkgdGFrZW4gcGxhY2U7IGRvIG5vdCBjbGFpbSB0aGF0IG5vIGRpc2sgd2FzIGVyYXNlZC4KICAgIHNheSAiWW91ciBjb21wdXRlciBpcyBzYWZlLiBTZXR1cCBoYXMgcGF1c2VkLiIKICAgIHNheSAiJCoiCiAgICBzYXkgIkRldGFpbHMgYXJlIHNhdmVkIGZvciBOYWx2byBzdXBwb3J0LiIKICAgIHNob3dfaW5zdGFsbF9ndWlkZQogICAgc2F5ICJQcmVzcyBSIHRvIHRyeSBhZ2Fpbi4gU2V0dXAgYWxzbyBjb250aW51ZXMgYWZ0ZXIgYSByZXN0YXJ0LiIKICAgIGxvY2FsIGtleQogICAgd2hpbGUgOjsgZG8KICAgICAgICBpZiBJRlM9IHJlYWQgLXIgLXMgLW4gMSBrZXk7IHRoZW4KICAgICAgICAgICAgY2FzZSAiJGtleSIgaW4KICAgICAgICAgICAgICAgIHJ8UikgZXhlYyA5PiYtOyBleGVjICIkU0VMRiIgcnVuIDs7CiAgICAgICAgICAgIGVzYWMKICAgICAgICBlbHNlCiAgICAgICAgICAgIHNsZWVwIDEKICAgICAgICBmaQogICAgZG9uZQp9CnNzaGRfY2ZnKCkgeyBpbnN0YWxsIC1kIC1tIDA3NTUgLW8gcm9vdCAtZyByb290IC9ydW4vc3NoZCAyPi9kZXYvbnVsbDsgc3NoZCAtVCAyPi9kZXYvbnVsbDsgfQpudmlkaWFfdmVyc2lvbigpIHsgICAjIHRoZSBkcml2ZXIgdmVyc2lvbiBudmlkaWEtc21pIHJlcG9ydHMsIG9yIG5vdGhpbmcgKGl0cyBlcnJvciB0ZXh0IGlzIG5ldmVyIGEgdmVyc2lvbikKICAgIGxvY2FsIHYKICAgIHY9JChudmlkaWEtc21pIC0tcXVlcnktZ3B1PWRyaXZlcl92ZXJzaW9uIC0tZm9ybWF0PWNzdixub2hlYWRlciAyPi9kZXYvbnVsbCkgfHwgdj0iIgogICAgcHJpbnRmICclc1xuJyAiJHYiIHwgZ3JlcCAtRSAnXlswLTldKyhcLlswLTldKykrJCcgfCBzb3J0IC11ViB8IGhlYWQgLTEKfQoKaW5zdGFsbF91bml0KCkgewogICAgaW5zdGFsbCAtZCAtbSAwNzAwICIkU1RBVEUiCiAgICBpbnN0YWxsIC1kIC1tIDA3NTUgL3Zhci9sb2cvbmFsdm8gIiRBR0VOVF9ESVIiCiAgICBpbnN0YWxsIC1tIDA3NTUgIiQwIiAiJFNFTEYiIDI+L2Rldi9udWxsIHx8IHRydWUKICAgIGNhdCA+IiRVTklUIiA8PEVPRgpbVW5pdF0KRGVzY3JpcHRpb249TmFsdm8gbm9kZSBmaXJzdC1ib290IHNldHVwCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldCBzeXN0ZW1kLXVzZXItc2Vzc2lvbnMuc2VydmljZQpXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKQmVmb3JlPWdldHR5QHR0eTEuc2VydmljZQpDb25mbGljdHM9Z2V0dHlAdHR5MS5zZXJ2aWNlCgpbU2VydmljZV0KVHlwZT1pZGxlCkV4ZWNTdGFydD0kU0VMRiBydW4KU3RhbmRhcmRJbnB1dD10dHkKU3RhbmRhcmRPdXRwdXQ9dHR5ClN0YW5kYXJkRXJyb3I9dHR5ClRUWVBhdGg9L2Rldi90dHkxClRUWVJlc2V0PXllcwpUVFlWSGFuZ3VwPXllcwpUaW1lb3V0U3RhcnRTZWM9MApSZXN0YXJ0PWFsd2F5cwpSZXN0YXJ0U2VjPTEKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldApFT0YKICAgICMgTWFzayBwZXJzaXN0cyBhY3Jvc3MgY3Jhc2hlcyBhbmQgcmVib290cy4gT25seSBmaW5pc2hfc2V0dXAgdW5tYXNrcyBpdC4KICAgIHN5c3RlbWN0bCBtYXNrIGdldHR5QHR0eTEuc2VydmljZSA+L2Rldi9udWxsIDI+JjEgfHwgcmV0dXJuIDEKICAgIHN5c3RlbWN0bCBlbmFibGUgbmFsdm8tZmlyc3Rib290LnNlcnZpY2UgPi9kZXYvbnVsbCAyPiYxIHx8IGxuIC1zZiAiJFVOSVQiIC9ldGMvc3lzdGVtZC9zeXN0ZW0vbXVsdGktdXNlci50YXJnZXQud2FudHMvbmFsdm8tZmlyc3Rib290LnNlcnZpY2UKICAgIGVjaG8gIm5hbHZvLWZpcnN0Ym9vdCBpbnN0YWxsZWQiCn0KCmd1YXJkX2luc3RhbGxlZF9zeXN0ZW0oKSB7CiAgICBsb2NhbCByb290ZnMKICAgIHJvb3Rmcz0kKGF3ayAnJDI9PSIvIiB7cHJpbnQgJDN9JyAvcHJvYy9tb3VudHMgfCB0YWlsIC0xKQogICAgY2FzZSAiJHJvb3RmcyIgaW4gb3ZlcmxheXxzcXVhc2hmc3x0bXBmcykKICAgICAgICBzdG9wX2hlcmUgIlJlbW92ZSB0aGUgVVNCIHN0aWNrIGFuZCByZXN0YXJ0IHRoaXMgY29tcHV0ZXIuIjs7CiAgICBlc2FjCiAgICBpZiBncmVwIC1xdyAnYm9vdD1jYXNwZXInIC9wcm9jL2NtZGxpbmU7IHRoZW4KICAgICAgICBzdG9wX2hlcmUgIlJlbW92ZSB0aGUgVVNCIHN0aWNrIGFuZCByZXN0YXJ0IHRoaXMgY29tcHV0ZXIuIgogICAgZmkKfQoKd2lmaV9zY2FuX3BhcnNlKCkgeyAjIGl3IHNjYW4gb24gc3RkaW47IFNTSUQsIGRldGVjdGVkIHNlY3VyaXR5IGFuZCBzaWduYWwgYmFycyBhcyBUU1YKICAgIHB5dGhvbjMgLUkgLWMgJwppbXBvcnQgcmUsIHN5cwoKbmV0d29ya3MgPSB7fQpmb3IgYmxvY2sgaW4gcmUuc3BsaXQociIoP20pXkJTUyAiLCBzeXMuc3RkaW4ucmVhZCgpKToKICAgIG5hbWUgPSByZS5zZWFyY2gociIoP20pXlxzKlNTSUQ6ID8oLiopJCIsIGJsb2NrKQogICAgc2lnbmFsID0gcmUuc2VhcmNoKHIiKD9tKV5ccypzaWduYWw6XHMqKC0/XGQrKD86XC5cZCspPykiLCBibG9jaykKICAgIGlmIG5vdCBuYW1lOgogICAgICAgIGNvbnRpbnVlCiAgICByYXcgPSBuYW1lLmdyb3VwKDEpLmVuY29kZSgidXRmLTgiKQogICAgcmF3ID0gcmUuc3ViKHJiIlxceChbMC05YS1mQS1GXXsyfSkiLCBsYW1iZGEgbTogYnl0ZXMoW2ludChtLmdyb3VwKDEpLCAxNildKSwgcmF3KQogICAgdHJ5OgogICAgICAgIHNzaWQgPSByYXcuZGVjb2RlKCJ1dGYtOCIpCiAgICBleGNlcHQgVW5pY29kZURlY29kZUVycm9yOgogICAgICAgIGNvbnRpbnVlCiAgICBpZiBub3QgMSA8PSBsZW4ocmF3KSA8PSAzMiBvciBhbnkob3JkKGMpIDwgMzIgb3Igb3JkKGMpID09IDEyNyBmb3IgYyBpbiBzc2lkKToKICAgICAgICBjb250aW51ZQogICAgc3VpdGVzID0gIiAiLmpvaW4ocmUuZmluZGFsbChyIig/bWkpXlxzKkF1dGhlbnRpY2F0aW9uIHN1aXRlczpccyooLiopJCIsIGJsb2NrKSkudXBwZXIoKQogICAgaWYgcmUuc2VhcmNoKHIiXGJTQUVcYiIsIHN1aXRlcyk6CiAgICAgICAgc2VjdXJpdHkgPSAid3BhMyIKICAgIGVsaWYgcmUuc2VhcmNoKHIiXGJQU0tcYiIsIHN1aXRlcyk6CiAgICAgICAgc2VjdXJpdHkgPSAid3BhMiIKICAgIGVsaWYgcmUuc2VhcmNoKHIiKD9taSleXHMqKD86UlNOfFdQQSk6IiwgYmxvY2spIG9yIHJlLnNlYXJjaChyIig/bWkpXlxzKmNhcGFiaWxpdHk6LipcYlByaXZhY3lcYiIsIGJsb2NrKToKICAgICAgICBjb250aW51ZSAgIyBkbyBub3QgY2FsbCB1bnN1cHBvcnRlZCBwcm90ZWN0ZWQgbmV0d29ya3Mgb3BlbgogICAgZWxzZToKICAgICAgICBzZWN1cml0eSA9ICJvcGVuIgogICAgc3RyZW5ndGggPSBmbG9hdChzaWduYWwuZ3JvdXAoMSkpIGlmIHNpZ25hbCBlbHNlIC0xMDAuMAogICAgYmFycyA9IG1heCgxLCBtaW4oNCwgaW50KChzdHJlbmd0aCArIDEwMCkgLy8gMTUpICsgMSkpCiAgICBrZXkgPSAoc3NpZCwgc2VjdXJpdHkpCiAgICBpZiBrZXkgbm90IGluIG5ldHdvcmtzIG9yIHN0cmVuZ3RoID4gbmV0d29ya3Nba2V5XVswXToKICAgICAgICBuZXR3b3Jrc1trZXldID0gKHN0cmVuZ3RoLCBiYXJzKQpmb3IgKHNzaWQsIHNlY3VyaXR5KSwgKF8sIGJhcnMpIGluIHNvcnRlZChuZXR3b3Jrcy5pdGVtcygpLCBrZXk9bGFtYmRhIGl0ZW06ICgtaXRlbVsxXVswXSwgaXRlbVswXSkpOgogICAgcHJpbnQoInt9XHR7fVx0e30iLmZvcm1hdChzc2lkLCBzZWN1cml0eSwgInwiICogYmFycykpCicKfQoKd2lmaV93cml0ZV9uZXRwbGFuKCkgeyAjIGludGVyZmFjZSwgU1NJRCwgc2VjdXJpdHksIHBhc3N3b3JkOyBubyBzZWNyZXQgaW4gYXJndiBvciBsb2dzCiAgICBwcmludGYgJyVzXDAlc1wwJXNcMCVzXDAnICIkMSIgIiQyIiAiJDMiICIkNCIgfCBweXRob24zIC1JIC1jICcKaW1wb3J0IGpzb24sIG9zLCByZSwgc3lzLCB0ZW1wZmlsZQp0cnk6CiAgICBmaWVsZHMgPSBzeXMuc3RkaW4uYnVmZmVyLnJlYWQoKS5zcGxpdChiIlwwIikKICAgIGlmIGxlbihmaWVsZHMpICE9IDUgb3IgZmllbGRzWy0xXSAhPSBiIiI6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigpCiAgICBpZmFjZSwgc3NpZCwgc2VjdXJpdHksIHBhc3N3b3JkID0gKHYuZGVjb2RlKCJ1dGYtOCIpIGZvciB2IGluIGZpZWxkc1s6NF0pCiAgICBpZiAobm90IHJlLmZ1bGxtYXRjaChyIltBLVphLXowLTlfLi1dezEsMTV9IiwgaWZhY2UpCiAgICAgICAgb3Igbm90IDEgPD0gbGVuKHNzaWQuZW5jb2RlKCJ1dGYtOCIpKSA8PSAzMgogICAgICAgIG9yIGFueShvcmQoYykgPCAzMiBvciBvcmQoYykgPT0gMTI3IGZvciBjIGluIHNzaWQgKyBwYXNzd29yZCkKICAgICAgICBvciBzZWN1cml0eSBub3QgaW4gKCJvcGVuIiwgIndwYTIiLCAid3BhMyIpCiAgICAgICAgb3IgKHNlY3VyaXR5ID09ICJvcGVuIiBhbmQgcGFzc3dvcmQpCiAgICAgICAgb3IgKHNlY3VyaXR5ICE9ICJvcGVuIiBhbmQgbm90ICg4IDw9IGxlbihwYXNzd29yZCkgPD0gNjMgb3IgcmUuZnVsbG1hdGNoKHIiWzAtOWEtZkEtRl17NjR9IiwgcGFzc3dvcmQpKSkpOgogICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoKQogICAgcSA9IGxhbWJkYSB2YWx1ZToganNvbi5kdW1wcyh2YWx1ZSwgZW5zdXJlX2FzY2lpPVRydWUpCiAgICBpZiBzZWN1cml0eSA9PSAib3BlbiI6CiAgICAgICAgYXAgPSAiICAgICAgICAgIHt9XG4iCiAgICBlbGlmIHNlY3VyaXR5ID09ICJ3cGEzIjoKICAgICAgICBhcCA9ICIgICAgICAgICAgYXV0aDpcbiAgICAgICAgICAgIGtleS1tYW5hZ2VtZW50OiBzYWVcbiAgICAgICAgICAgIHBhc3N3b3JkOiAiICsgcShwYXNzd29yZCkgKyAiXG4iCiAgICBlbHNlOgogICAgICAgIGFwID0gIiAgICAgICAgICBwYXNzd29yZDogIiArIHEocGFzc3dvcmQpICsgIlxuIgogICAgY29udGVudCA9ICgibmV0d29yazpcbiAgdmVyc2lvbjogMlxuICByZW5kZXJlcjogbmV0d29ya2RcbiAgd2lmaXM6XG4gICAgIiArIGlmYWNlICsKICAgICAgICAgICAgICAgIjpcbiAgICAgIGRoY3A0OiB0cnVlXG4gICAgICBvcHRpb25hbDogZmFsc2VcbiAgICAgIGFjY2Vzcy1wb2ludHM6XG4gICAgICAgICIgKyBxKHNzaWQpICsgIjpcbiIgKyBhcCkKICAgIHBhdGggPSBvcy5lbnZpcm9uLmdldCgiTkFMVk9fTkVUUExBTl9XSUZJX1BBVEgiLCAiL2V0Yy9uZXRwbGFuLzkwLW5hbHZvLXdpZmkueWFtbCIpCiAgICBmZCwgdGVtcCA9IHRlbXBmaWxlLm1rc3RlbXAocHJlZml4PSIubmFsdm8td2lmaS0iLCBkaXI9b3MucGF0aC5kaXJuYW1lKHBhdGgpKQogICAgdHJ5OgogICAgICAgIG9zLmZjaG1vZChmZCwgMG82MDApCiAgICAgICAgd2l0aCBvcy5mZG9wZW4oZmQsICJ3IiwgZW5jb2Rpbmc9InV0Zi04IikgYXMgb3V0OgogICAgICAgICAgICBvdXQud3JpdGUoY29udGVudCkKICAgICAgICBvcy5yZXBsYWNlKHRlbXAsIHBhdGgpCiAgICBmaW5hbGx5OgogICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKHRlbXApOgogICAgICAgICAgICBvcy51bmxpbmsodGVtcCkKZXhjZXB0IChPU0Vycm9yLCBVbmljb2RlRXJyb3IsIFZhbHVlRXJyb3IpOgogICAgc3lzLmV4aXQoMSkKJwp9Cgp3aWZpX2Nob29zZV9uZXR3b3JrKCkgeyAjIGZpbGUgb2YgcGFyc2VkIHNjYW4gcmVzdWx0czsga2V5Ym9hcmQgb24gc3RkaW4sIHJlc3VsdCBpbiBXSUZJXyogZ2xvYmFscwogICAgbG9jYWwgZmlsZT0kMSBrZXkgcmVzdCBpIHNlbGVjdGVkPTAgbGluZQogICAgbG9jYWwgLWEgZW50cmllcwogICAgbWFwZmlsZSAtdCBlbnRyaWVzIDwiJGZpbGUiCiAgICBbICR7I2VudHJpZXNbQF19IC1ndCAwIF0gfHwgcmV0dXJuIDEKICAgIHdoaWxlIDo7IGRvCiAgICAgICAgcHJpbnRmICdcbkNob29zZSB5b3VyIFdpLUZpIG5ldHdvcmsgKG51bWJlciwgb3IgYXJyb3dzIGFuZCBFbnRlcjsgMCB0byBnbyBiYWNrKTpcbicKICAgICAgICBmb3IgKChpPTA7IGk8JHsjZW50cmllc1tAXX07IGkrKykpOyBkbwogICAgICAgICAgICBJRlM9JCdcdCcgcmVhZCAtciBXSUZJX1NTSUQgV0lGSV9TRUNVUklUWSBXSUZJX0JBUlMgPDw8IiR7ZW50cmllc1tpXX0iCiAgICAgICAgICAgIGlmIFsgIiRpIiA9ICIkc2VsZWN0ZWQiIF07IHRoZW4gcHJpbnRmICcgPiAnOyBlbHNlIHByaW50ZiAnICAgJzsgZmkKICAgICAgICAgICAgcHJpbnRmICclcy4gJXMgIFslc10gICVzXG4nICIkKChpKzEpKSIgIiRXSUZJX1NTSUQiICIkV0lGSV9CQVJTIiAiJFdJRklfU0VDVVJJVFkiCiAgICAgICAgZG9uZQogICAgICAgIGlmICEgSUZTPSByZWFkIC1yc24xIGtleTsgdGhlbiBzbGVlcCAxOyBjb250aW51ZTsgZmkKICAgICAgICBjYXNlICIka2V5IiBpbgogICAgICAgICAgICAwKSByZXR1cm4gMTs7CiAgICAgICAgICAgIFsxLTldKSBpPSQoKGtleS0xKSk7IFsgIiRpIiAtbHQgIiR7I2VudHJpZXNbQF19IiBdICYmIHNlbGVjdGVkPSRpICYmIGJyZWFrOzsKICAgICAgICAgICAgJycpIGJyZWFrOzsKICAgICAgICAgICAgJCdcZScpCiAgICAgICAgICAgICAgICBJRlM9IHJlYWQgLXJzbjEgLXQgMC4xIHJlc3QgfHwgY29udGludWUKICAgICAgICAgICAgICAgIFsgIiRyZXN0IiA9ICdbJyBdIHx8IGNvbnRpbnVlCiAgICAgICAgICAgICAgICBJRlM9IHJlYWQgLXJzbjEgLXQgMC4xIHJlc3QgfHwgY29udGludWUKICAgICAgICAgICAgICAgIGNhc2UgIiRyZXN0IiBpbiBBKSBzZWxlY3RlZD0kKCggKHNlbGVjdGVkICsgJHsjZW50cmllc1tAXX0gLSAxKSAlICR7I2VudHJpZXNbQF19ICkpOzsgQikgc2VsZWN0ZWQ9JCgoIChzZWxlY3RlZCArIDEpICUgJHsjZW50cmllc1tAXX0gKSk7OyBlc2FjOzsKICAgICAgICBlc2FjCiAgICBkb25lCiAgICBsaW5lPSR7ZW50cmllc1tzZWxlY3RlZF19CiAgICBJRlM9JCdcdCcgcmVhZCAtciBXSUZJX1NTSUQgV0lGSV9TRUNVUklUWSBXSUZJX0JBUlMgPDw8IiRsaW5lIgp9Cgp3aWZpX2Nvbm5lY3QoKSB7CiAgICBsb2NhbCBpZmFjZT0nJyBkIHNjYW4gcGFzc3dvcmQ9JycgaQogICAgaWYgISB3aWZpX2Vuc3VyZV9zY2FubmVyOyB0aGVuCiAgICAgICAgcHJpbnRmICdXaS1GaSBzY2FubmluZyBpcyBub3QgcmVhZHkgeWV0LiBJbnNlcnQgdGhlIGluc3RhbGxhdGlvbiBVU0Igc3RpY2sgb3IgdXNlIGFuIEV0aGVybmV0IGNhYmxlLlxuJwogICAgICAgIHJldHVybiAxCiAgICBmaQogICAgZm9yIGQgaW4gIiR7TkFMVk9fU1lTX05FVDotL3N5cy9jbGFzcy9uZXR9Ii8qL3dpcmVsZXNzOyBkbwogICAgICAgIFsgLWQgIiRkIiBdIHx8IGNvbnRpbnVlCiAgICAgICAgaWZhY2U9JChiYXNlbmFtZSAiJChkaXJuYW1lICIkZCIpIikKICAgICAgICBbWyAiJGlmYWNlIiA9fiBeW0EtWmEtejAtOV8uLV17MSwxNX0kIF1dICYmIGJyZWFrCiAgICAgICAgaWZhY2U9JycKICAgIGRvbmUKICAgIGlmIFsgLXogIiRpZmFjZSIgXTsgdGhlbgogICAgICAgIHByaW50ZiAnV2ktRmkgaXMgbm90IHJlYWR5IHlldC4gSW5zZXJ0IHRoZSBmaXJtd2FyZSBzdGljayBvciB1c2UgYW4gRXRoZXJuZXQgY2FibGUuXG4nCiAgICAgICAgcmV0dXJuIDEKICAgIGZpCiAgICBwcmludGYgJ0xvb2tpbmcgZm9yIG5lYXJieSBXaS1GaSBuZXR3b3Jrcy4uLlxuJwogICAgcmZraWxsIHVuYmxvY2sgYWxsID4+IiRMT0ciIDI+JjEgfHwgdHJ1ZQogICAgaXAgbGluayBzZXQgIiRpZmFjZSIgdXAgPj4iJExPRyIgMj4mMSB8fCB0cnVlCiAgICBzbGVlcCAyCiAgICBzY2FuPSQobWt0ZW1wICIkU1RBVEUvd2lmaS1zY2FuLlhYWFhYWCIpIHx8IHJldHVybiAxCiAgICBjaG1vZCAwNjAwICIkc2NhbiIKICAgIHdpZmlfc2Nhbl9yYXcgIiRpZmFjZSIgfCB3aWZpX3NjYW5fcGFyc2UgPiIkc2NhbiIKICAgIGlmIFsgISAtcyAiJHNjYW4iIF0gJiYgd2lmaV9wY2llX2ZhbGxiYWNrOyB0aGVuCiAgICAgICAgaXAgbGluayBzZXQgIiRpZmFjZSIgdXAgPj4iJExPRyIgMj4mMSB8fCB0cnVlCiAgICAgICAgc2xlZXAgMgogICAgICAgIHdpZmlfc2Nhbl9yYXcgIiRpZmFjZSIgfCB3aWZpX3NjYW5fcGFyc2UgPiIkc2NhbiIKICAgIGZpCiAgICBXSUZJX0xBU1RfU0NBTj0iJCh3YyAtbCA8IiRzY2FuIiB8IHRyIC1kICcgJykgbmV0d29yayhzKSIKICAgIGlmIFsgISAtcyAiJHNjYW4iIF07IHRoZW4KICAgICAgICBybSAtZiAiJHNjYW4iCiAgICAgICAgcHJpbnRmICdObyBzdXBwb3J0ZWQgV2ktRmkgbmV0d29ya3MgZm91bmQuIFlvdSBjYW4gdHJ5IGFnYWluIG9yIHVzZSBhbiBFdGhlcm5ldCBjYWJsZS5cbicKICAgICAgICByZXR1cm4gMQogICAgZmkKICAgIGlmICEgd2lmaV9jaG9vc2VfbmV0d29yayAiJHNjYW4iOyB0aGVuCiAgICAgICAgcm0gLWYgIiRzY2FuIgogICAgICAgIHJldHVybiAxCiAgICBmaQogICAgcm0gLWYgIiRzY2FuIgogICAgaWYgWyAiJFdJRklfU0VDVVJJVFkiICE9IG9wZW4gXTsgdGhlbgogICAgICAgIHByaW50ZiAnV2ktRmkgcGFzc3dvcmQgKGhpZGRlbik6ICcKICAgICAgICBJRlM9IHJlYWQgLXJzIHBhc3N3b3JkIHx8IHBhc3N3b3JkPScnCiAgICAgICAgcHJpbnRmICdcbicKICAgIGZpCiAgICBpZiAhIHdpZmlfd3JpdGVfbmV0cGxhbiAiJGlmYWNlIiAiJFdJRklfU1NJRCIgIiRXSUZJX1NFQ1VSSVRZIiAiJHBhc3N3b3JkIjsgdGhlbgogICAgICAgIHBhc3N3b3JkPScnCiAgICAgICAgcHJpbnRmICdUaG9zZSBXaS1GaSBkZXRhaWxzIGNvdWxkIG5vdCBiZSBzYXZlZC4gUGxlYXNlIHRyeSBhZ2Fpbi5cbicKICAgICAgICByZXR1cm4gMQogICAgZmkKICAgIHBhc3N3b3JkPScnCiAgICAjIG5ldHBsYW4gZGlhZ25vc3RpY3MgY2FuIGVjaG8gY29uZmlndXJhdGlvbiBsaW5lcywgaW5jbHVkaW5nIHNlY3JldHMuCiAgICBpZiAhIG5ldHBsYW4gZ2VuZXJhdGUgPi9kZXYvbnVsbCAyPiYxOyB0aGVuCiAgICAgICAgcHJpbnRmICdXaS1GaSBjb3VsZCBub3QgYmUgcHJlcGFyZWQuIFBsZWFzZSB0cnkgYWdhaW4uXG4nCiAgICAgICAgcmV0dXJuIDEKICAgIGZpCiAgICBuZXRwbGFuIGFwcGx5ID4vZGV2L251bGwgMj4mMSB8fCB0cnVlCiAgICB0aW1lZGF0ZWN0bCBzZXQtbnRwIHRydWUgPj4iJExPRyIgMj4mMSB8fCB0cnVlCiAgICBwcmludGYgJ0Nvbm5lY3RpbmcgdG8gV2ktRmknCiAgICBmb3IgaSBpbiAkKHNlcSAxIDMwKTsgZG8KICAgICAgICBpZiBjdXJsIC1mc1MgLS1tYXgtdGltZSA1ICIkRkxFRVQvYWdlbnQvbWFuaWZlc3QuanNvbiIgLW8gL2Rldi9udWxsIDI+PiIkTE9HIjsgdGhlbgogICAgICAgICAgICBwcmludGYgJy4uLiBjb25uZWN0ZWQuXG4nCiAgICAgICAgICAgIHJldHVybiAwCiAgICAgICAgZmkKICAgICAgICBwcmludGYgJy4nCiAgICAgICAgc2xlZXAgMgogICAgZG9uZQogICAgcHJpbnRmICdcbldpLUZpIGNvdWxkIG5vdCByZWFjaCBGbGVldCBNYW5hZ2VyLiBUcnkgYWdhaW4gb3IgdXNlIGFuIEV0aGVybmV0IGNhYmxlLlxuJwogICAgcmV0dXJuIDEKfQoKIyBWaXNpdCBhbHJlYWR5IG1vdW50ZWQgbWVkaWEgYW5kIHJlbW92YWJsZSBVU0IgcGFydGl0aW9ucywgbW91bnRpbmcgdGhlIGxhdHRlcgojIHJlYWQtb25seSBvbmx5IGZvciB0aGUgZHVyYXRpb24gb2YgdGhlIGNhbGxiYWNrLiBOZXZlciBzY2FuIGludGVybmFsIGRpc2tzLgp3aWZpX3dpdGhfbWVkaWEoKSB7CiAgICBsb2NhbCBjYWxsYmFjaz0iJDEiIHBhdGggZGV2aWNlIHR5cGUgbW91bnRlZCB0bXAgZm91bmQ9MQogICAgZm9yIHBhdGggaW4gL2Nkcm9tIC9tZWRpYS8qIC9tZWRpYS8qLyogL3J1bi9tZWRpYS8qLyogL21udDsgZG8KICAgICAgICBbIC1kICIkcGF0aCIgXSB8fCBjb250aW51ZQogICAgICAgICIkY2FsbGJhY2siICIkcGF0aCIgJiYgZm91bmQ9MAogICAgZG9uZQogICAgd2hpbGUgcmVhZCAtciBkZXZpY2UgdHlwZTsgZG8KICAgICAgICBjYXNlICIkdHlwZSIgaW4gcGFydHxkaXNrfHJvbSkgOzsgKikgY29udGludWUgOzsgZXNhYwogICAgICAgIFsgIiR0eXBlIiA9IHJvbSBdIHx8IGxzYmxrIC1zIC1sIC1uIC1vIFRSQU4gIiRkZXZpY2UiIDI+L2Rldi9udWxsIHwgZ3JlcCAtcXggdXNiIHx8IGNvbnRpbnVlCiAgICAgICAgbW91bnRlZD0kKGZpbmRtbnQgLXJuIC1TICIkZGV2aWNlIiAtbyBUQVJHRVQgMj4vZGV2L251bGwgfCBoZWFkIC0xKQogICAgICAgIGlmIFsgLW4gIiRtb3VudGVkIiBdOyB0aGVuCiAgICAgICAgICAgICIkY2FsbGJhY2siICIkbW91bnRlZCIgJiYgZm91bmQ9MAogICAgICAgICAgICBjb250aW51ZQogICAgICAgIGZpCiAgICAgICAgdG1wPSQobWt0ZW1wIC1kIC9ydW4vbmFsdm8tbWVkaWEuWFhYWFhYKSB8fCBjb250aW51ZQogICAgICAgIGlmIG1vdW50IC1vIHJvLG5vc3VpZCxub2Rldixub2V4ZWMgIiRkZXZpY2UiICIkdG1wIiA+PiIkTE9HIiAyPiYxOyB0aGVuCiAgICAgICAgICAgICIkY2FsbGJhY2siICIkdG1wIiAmJiBmb3VuZD0wCiAgICAgICAgICAgIHVtb3VudCAiJHRtcCIgPj4iJExPRyIgMj4mMSB8fCB0cnVlCiAgICAgICAgZmkKICAgICAgICBybWRpciAiJHRtcCIgMj4vZGV2L251bGwgfHwgdHJ1ZQogICAgZG9uZSA8IDwobHNibGsgLWxucG8gTkFNRSxUWVBFIDI+L2Rldi9udWxsKQogICAgcmV0dXJuICIkZm91bmQiCn0KCndpZmlfY29weV9maXJtd2FyZSgpIHsKICAgIGxvY2FsIG1lZGlhPSIkMSIgc291cmNlIGZpbGUgcmVsYXRpdmUgdGFyZ2V0IGNoYW5nZWQ9MCBwcmVzZW50PTAKICAgIGZvciBzb3VyY2UgaW4gIiRtZWRpYS9uYWx2by9maXJtd2FyZSIgIiRtZWRpYS9ydHc4OSI7IGRvCiAgICAgICAgWyAtZCAiJHNvdXJjZSIgXSAmJiBbICEgLUwgIiRzb3VyY2UiIF0gfHwgY29udGludWUKICAgICAgICB3aGlsZSBJRlM9IHJlYWQgLXIgLWQgJycgZmlsZTsgZG8KICAgICAgICAgICAgcHJlc2VudD0xCiAgICAgICAgICAgIHJlbGF0aXZlPSR7ZmlsZSMiJHNvdXJjZSIvfQogICAgICAgICAgICBbICIkc291cmNlIiA9ICIkbWVkaWEvcnR3ODkiIF0gJiYgcmVsYXRpdmU9InJ0dzg5LyRyZWxhdGl2ZSIKICAgICAgICAgICAgdGFyZ2V0PSIvbGliL2Zpcm13YXJlLyRyZWxhdGl2ZSIKICAgICAgICAgICAgaWYgISBjbXAgLXMgIiRmaWxlIiAiJHRhcmdldCI7IHRoZW4KICAgICAgICAgICAgICAgIGluc3RhbGwgLWQgLW0gMDc1NSAiJChkaXJuYW1lICIkdGFyZ2V0IikiIHx8IGNvbnRpbnVlCiAgICAgICAgICAgICAgICBpbnN0YWxsIC1tIDA2NDQgIiRmaWxlIiAiJHRhcmdldCIgJiYgY2hhbmdlZD0xCiAgICAgICAgICAgIGZpCiAgICAgICAgZG9uZSA8IDwoZmluZCAiJHNvdXJjZSIgLXR5cGUgZiBcKCAtbmFtZSAnKi5iaW4nIC1vIC1uYW1lICcqLmJpbi56c3QnIC1vIC1uYW1lICcqLnVjb2RlJyAtbyAtbmFtZSAnKi51Y29kZS56c3QnIFwpIC1wcmludDAgMj4vZGV2L251bGwpCiAgICBkb25lCiAgICAjIEFsc28gcmV0cnkgdGhlIGRyaXZlciBvbmNlIHdoZW4gdGhlIHNhbWUgZmlybXdhcmUgd2FzIGFscmVhZHkgaW5zdGFsbGVkOwogICAgIyBpdCBtYXkgaGF2ZSBmYWlsZWQgaXRzIGVhcmxpZXIgcHJvYmUgYmVmb3JlIHRoZSBzdGljayB3YXMgYXZhaWxhYmxlLgogICAgWyAiJGNoYW5nZWQiID0gMSBdIHx8IHsgWyAiJHByZXNlbnQiID0gMSBdICYmIFsgIiRXSUZJX0ZJUk1XQVJFX0FUVEVNUFRFRCIgPSAwIF07IH0gfHwgcmV0dXJuIDEKICAgIFdJRklfRklSTVdBUkVfQ0hBTkdFRD0xCn0KCndpZmlfcmVjb3Zlcl9maXJtd2FyZSgpIHsKICAgIGxvY2FsIGRldiB2ZW5kb3IgcHJvZHVjdCBtb2R1bGUKICAgIFdJRklfRklSTVdBUkVfQ0hBTkdFRD0wCiAgICB3aWZpX3dpdGhfbWVkaWEgd2lmaV9jb3B5X2Zpcm13YXJlIHx8IHRydWUKICAgIFsgIiRXSUZJX0ZJUk1XQVJFX0NIQU5HRUQiID0gMSBdIHx8IHJldHVybiAxCiAgICBXSUZJX0ZJUk1XQVJFX0FUVEVNUFRFRD0xCiAgICAjIEtlZXAgdGhlIHJlY292ZXJlZCBmaXJtd2FyZSBhdmFpbGFibGUgaWYgYSBkcml2ZXIgbG9hZHMgaW4gaW5pdHJhbWZzLgogICAgdXBkYXRlLWluaXRyYW1mcyAtdSAtayBhbGwgPj4iJExPRyIgMj4mMSB8fCB0cnVlCiAgICAjIFJldHJ5IG9ubHkgZHJpdmVycyBtYXRjaGluZyBhY3R1YWwgUENJIGhhcmR3YXJlOyBkbyBub3QgdW5sb2FkIHVucmVsYXRlZAogICAgIyBhZGFwdGVycyBvciBmb3JjZSByZW1vdmFsIHdoZW4gYSBtb2R1bGUgaXMgaW4gdXNlLgogICAgZm9yIGRldiBpbiAvc3lzL2J1cy9wY2kvZGV2aWNlcy8qOyBkbwogICAgICAgIFsgLXIgIiRkZXYvdmVuZG9yIiBdICYmIFsgLXIgIiRkZXYvZGV2aWNlIiBdIHx8IGNvbnRpbnVlCiAgICAgICAgcmVhZCAtciB2ZW5kb3IgPCIkZGV2L3ZlbmRvciI7IHJlYWQgLXIgcHJvZHVjdCA8IiRkZXYvZGV2aWNlIgogICAgICAgIGNhc2UgIiR2ZW5kb3I6JHByb2R1Y3QiIGluCiAgICAgICAgICAgIDB4MTBlYzoweDg5MjIpIG1vZHVsZT1ydHc4OV84OTIyYWUgOzsKICAgICAgICAgICAgMHgxMGVjOjB4ODg1MikgbW9kdWxlPXJ0dzg5Xzg4NTJhZSA7OwogICAgICAgICAgICAweDEwZWM6MHhiODUyKSBtb2R1bGU9cnR3ODlfODg1MmJlIDs7CiAgICAgICAgICAgIDB4MTBlYzoweGM4NTIpIG1vZHVsZT1ydHc4OV84ODUyY2UgOzsKICAgICAgICAgICAgMHgxNGMzOjB4NzkyNSkgbW9kdWxlPW10NzkyNWUgOzsKICAgICAgICAgICAgMHg4MDg2OjB4MjcyYikgbW9kdWxlPWl3bHdpZmkgOzsKICAgICAgICAgICAgKikgY29udGludWUgOzsKICAgICAgICBlc2FjCiAgICAgICAgbW9kaW5mbyAiJG1vZHVsZSIgPi9kZXYvbnVsbCAyPiYxIHx8IGNvbnRpbnVlCiAgICAgICAgaWYgWyAiJG1vZHVsZSIgPSBydHc4OV84OTIyYWUgXTsgdGhlbgogICAgICAgICAgICBtb2Rwcm9iZSAtciAiJG1vZHVsZSIgcnR3ODlfODkyMmEgcnR3ODlfcGNpIHJ0dzg5X2NvcmUgPj4iJExPRyIgMj4mMSB8fCB0cnVlCiAgICAgICAgZWxzZQogICAgICAgICAgICBtb2Rwcm9iZSAtciAiJG1vZHVsZSIgPj4iJExPRyIgMj4mMSB8fCB0cnVlCiAgICAgICAgZmkKICAgICAgICBtb2Rwcm9iZSAiJG1vZHVsZSIgPj4iJExPRyIgMj4mMSB8fCB0cnVlCiAgICBkb25lCiAgICByZXR1cm4gMAp9CgojIEEgUmVhbHRlayBjYXJkIHRoYXQgc2NhbnMgYnV0IHNlZXMgbm90aGluZyBvbiBzb21lIGJvYXJkczogUENJZSBwb3dlciBzYXZpbmcKIyBrZWVwcyB0aGUgcmFkaW8gaGFsZiBhc2xlZXAuIFR1cm4gaXQgb2ZmIG9uY2UgKHRoZSBub2RlIGFnZW50IGRvZXMgdGhlIHNhbWUKIyBhZnRlciBwYWlyaW5nKSwgcmVsb2FkIHRoZSBkcml2ZXIgYW5kIGxldCB0aGUgY2FsbGVyIHNjYW4gYWdhaW4uCndpZmlfcGNpZV9mYWxsYmFjaygpIHsKICAgIGxvY2FsIGRldiB2ZW5kb3IgcHJvZHVjdCBtb2R1bGU9JycKICAgIFsgLWYgIiRTVEFURS93aWZpLXBjaWUtdHJpZWQiIF0gJiYgcmV0dXJuIDEKICAgIGZvciBkZXYgaW4gL3N5cy9idXMvcGNpL2RldmljZXMvKjsgZG8KICAgICAgICBbIC1yICIkZGV2L3ZlbmRvciIgXSAmJiBbIC1yICIkZGV2L2RldmljZSIgXSB8fCBjb250aW51ZQogICAgICAgIHJlYWQgLXIgdmVuZG9yIDwiJGRldi92ZW5kb3IiOyByZWFkIC1yIHByb2R1Y3QgPCIkZGV2L2RldmljZSIKICAgICAgICBjYXNlICIkdmVuZG9yOiRwcm9kdWN0IiBpbgogICAgICAgICAgICAweDEwZWM6MHg4OTIyKSBtb2R1bGU9cnR3ODlfODkyMmFlIDs7CiAgICAgICAgICAgIDB4MTBlYzoweDg4NTIpIG1vZHVsZT1ydHc4OV84ODUyYWUgOzsKICAgICAgICAgICAgMHgxMGVjOjB4Yjg1MikgbW9kdWxlPXJ0dzg5Xzg4NTJiZSA7OwogICAgICAgICAgICAweDEwZWM6MHhjODUyKSBtb2R1bGU9cnR3ODlfODg1MmNlIDs7CiAgICAgICAgICAgICopIGNvbnRpbnVlIDs7CiAgICAgICAgZXNhYwogICAgICAgIGJyZWFrCiAgICBkb25lCiAgICBbIC1uICIkbW9kdWxlIiBdIHx8IHJldHVybiAxCiAgICBkYXRlIC11ICslRlQlVFogPiIkU1RBVEUvd2lmaS1wY2llLXRyaWVkIgogICAgcHJpbnRmICdBZGp1c3RpbmcgdGhlIFdpLUZpIGNhcmQgcG93ZXIgc2V0dGluZ3MuLi5cbicKICAgIHByaW50ZiAnb3B0aW9ucyBydHc4OV9wY2kgZGlzYWJsZV9jbGtyZXE9eSBkaXNhYmxlX2FzcG1fbDE9eSBkaXNhYmxlX2FzcG1fbDFzcz15XG4nID4vZXRjL21vZHByb2JlLmQvbmFsdm8tcnR3ODkuY29uZgogICAgbW9kcHJvYmUgLXIgIiRtb2R1bGUiIHJ0dzg5Xzg5MjJhIHJ0dzg5X3BjaSBydHc4OV9jb3JlID4+IiRMT0ciIDI+JjEgfHwgdHJ1ZQogICAgc2xlZXAgMgogICAgbW9kcHJvYmUgIiRtb2R1bGUiID4+IiRMT0ciIDI+JjEgfHwgdHJ1ZQogICAgc2xlZXAgNQogICAgcmZraWxsIHVuYmxvY2sgYWxsID4+IiRMT0ciIDI+JjEgfHwgdHJ1ZQogICAgaWYgWyAtZiAvZXRjL25ldHBsYW4vOTAtbmFsdm8td2lmaS55YW1sIF07IHRoZW4gbmV0cGxhbiBhcHBseSA+L2Rldi9udWxsIDI+JjEgfHwgdHJ1ZTsgZmkKICAgIHJldHVybiAwCn0KCndpZmlfaW5zdGFsbF9pd19mcm9tX21lZGlhKCkgewogICAgbG9jYWwgbWVkaWE9IiQxIiBkZWIKICAgIGxvY2FsIC1hIHBhY2thZ2VzPSgpCiAgICBbIC1kICIkbWVkaWEvcG9vbCIgXSB8fCByZXR1cm4gMQogICAgIyBJbnN0YWxsIG9ubHkgaXcgYW5kIGl0cyBsaWJubCBkZXBlbmRlbmNpZXMgZnJvbSB0aGUgbG9jYWwgSVNPIHBvb2wuCiAgICB3aGlsZSBJRlM9IHJlYWQgLXIgLWQgJycgZGViOyBkbyBwYWNrYWdlcys9KCIkZGViIik7IGRvbmUgPCA8KAogICAgICAgIGZpbmQgIiRtZWRpYS9wb29sIiAtdHlwZSBmIFwoIC1uYW1lICdpd18qLmRlYicgLW8gLW5hbWUgJ2xpYm5sLTMtMjAwXyouZGViJyAtbyAtbmFtZSAnbGlibmwtZ2VubC0zLTIwMF8qLmRlYicgXCkgLXByaW50MCAyPi9kZXYvbnVsbAogICAgKQogICAgWyAiJHsjcGFja2FnZXNbQF19IiAtZ3QgMCBdIHx8IHJldHVybiAxCiAgICBkcGtnIC1pICIke3BhY2thZ2VzW0BdfSIgPj4iJExPRyIgMj4mMSB8fCB0cnVlCiAgICBjb21tYW5kIC12IGl3ID4vZGV2L251bGwgMj4mMQp9Cgp3aWZpX2Vuc3VyZV9pdygpIHsKICAgIGNvbW1hbmQgLXYgaXcgPi9kZXYvbnVsbCAyPiYxICYmIHJldHVybiAwCiAgICB3aWZpX3dpdGhfbWVkaWEgd2lmaV9pbnN0YWxsX2l3X2Zyb21fbWVkaWEgfHwgdHJ1ZQogICAgY29tbWFuZCAtdiBpdyA+L2Rldi9udWxsIDI+JjEKfQoKIyBUaGUgVWJ1bnR1IFNlcnZlciBpbWFnZSBoYXMgbm8gIml3IiAoY2hlY2tlZCB0aGUgMjQuMDQuNSBwb29sLCAyMDI2LTExLTAzKSBidXQgc2hpcHMKIyB3cGFzdXBwbGljYW50LCBzbyBzY2FubmluZyBmYWxscyBiYWNrIHRvIGEgdGVtcG9yYXJ5IHdwYV9zdXBwbGljYW50IHBsdXMgd3BhX2NsaS4Kd2lmaV9lbnN1cmVfc2Nhbm5lcigpIHsKICAgIHdpZmlfZW5zdXJlX2l3ICYmIHJldHVybiAwCiAgICBjb21tYW5kIC12IHdwYV9zdXBwbGljYW50ID4vZGV2L251bGwgMj4mMSAmJiBjb21tYW5kIC12IHdwYV9jbGkgPi9kZXYvbnVsbCAyPiYxCn0KCndpZmlfc2Nhbl9yYXcoKSB7ICMgaW50ZXJmYWNlOyBwcmludHMgYW4gaXctc3R5bGUgc2NhbiB0aGF0IHdpZmlfc2Nhbl9wYXJzZSB1bmRlcnN0YW5kcwogICAgbG9jYWwgaWZhY2U9IiQxIiBwaWRmaWxlPS9ydW4vbmFsdm8td3BhLXNjYW4ucGlkIHN0YXJ0ZWQ9MAogICAgaWYgY29tbWFuZCAtdiBpdyA+L2Rldi9udWxsIDI+JjE7IHRoZW4KICAgICAgICBpdyBkZXYgIiRpZmFjZSIgc2NhbiAyPj4iJExPRyIKICAgICAgICByZXR1cm4gMAogICAgZmkKICAgICMgV2hlbiB0aGUgc2F2ZWQgV2ktRmkgd2FzIGFwcGxpZWQsIG5ldHBsYW4gYWxyZWFkeSBydW5zIGEgd3BhX3N1cHBsaWNhbnQgdGhhdCBvd25zCiAgICAjIHRoaXMgY2FyZC4gVGFsayB0byB0aGF0IG9uZTsgYSBzZWNvbmQgc3VwcGxpY2FudCBvbiB0aGUgc2FtZSByYWRpbyBzY2FucyBub3RoaW5nCiAgICAjIChyZWFsIG5vZGUgMjAyNi0xMS0wNDogZXZlcnkgc2NhbiBzaG93ZWQgMCBuZXR3b3JrcyBmb3IgZXhhY3RseSB0aGlzIHJlYXNvbikuCiAgICBpZiBbICEgLVMgIi9ydW4vd3BhX3N1cHBsaWNhbnQvJGlmYWNlIiBdOyB0aGVuCiAgICAgICAgaW5zdGFsbCAtZCAtbSAwNzU1IC9ydW4vd3BhX3N1cHBsaWNhbnQKICAgICAgICB3cGFfc3VwcGxpY2FudCAtQiAtaSAiJGlmYWNlIiAtQyAvcnVuL3dwYV9zdXBwbGljYW50IC1QICIkcGlkZmlsZSIgPj4iJExPRyIgMj4mMSAmJiBzdGFydGVkPTEKICAgIGZpCiAgICB3cGFfY2xpIC1pICIkaWZhY2UiIHNjYW4gPj4iJExPRyIgMj4mMSB8fCB0cnVlCiAgICBzbGVlcCA2CiAgICBpZiAhIHdwYV9jbGkgLWkgIiRpZmFjZSIgc2Nhbl9yZXN1bHRzIDI+PiIkTE9HIiB8IGF3ayAnTlIgPiAxICYmIE5GID49IDUgeyBmb3VuZCA9IDEgfSBFTkQgeyBleGl0ICFmb3VuZCB9JzsgdGhlbgogICAgICAgIHdwYV9jbGkgLWkgIiRpZmFjZSIgc2NhbiA+PiIkTE9HIiAyPiYxIHx8IHRydWUgICAjIGEgYnVzeSBzdXBwbGljYW50IHJlZnVzZXMgdGhlIGZpcnN0IHJlcXVlc3QgbWlkLWFzc29jaWF0aW9uCiAgICAgICAgc2xlZXAgNgogICAgZmkKICAgIHdwYV9jbGkgLWkgIiRpZmFjZSIgc2Nhbl9yZXN1bHRzIDI+PiIkTE9HIiB8IGF3ayAtRicJJyAnTlIgPiAxICYmIE5GID49IDUgewogICAgICAgIGZsYWdzID0gJDQ7IHN1aXRlcyA9ICIiOwogICAgICAgIGlmIChmbGFncyB+IC9TQUUvKSBzdWl0ZXMgPSBzdWl0ZXMgIiBTQUUiOwogICAgICAgIGlmIChmbGFncyB+IC9QU0svKSBzdWl0ZXMgPSBzdWl0ZXMgIiBQU0siOwogICAgICAgIHByaW50ZiAiQlNTICVzCglzaWduYWw6ICVzIGRCbQoJU1NJRDogJXMKIiwgJDEsICQzLCAkNTsKICAgICAgICBpZiAoZmxhZ3MgfiAvV1BBfFJTTnxTQUUvKSBwcmludGYgIglSU046CgkJQXV0aGVudGljYXRpb24gc3VpdGVzOiVzCiIsIHN1aXRlczsKICAgIH0nCiAgICBbICIkc3RhcnRlZCIgPSAxIF0gJiYgWyAtZiAiJHBpZGZpbGUiIF0gJiYga2lsbCAiJChjYXQgIiRwaWRmaWxlIikiIDI+L2Rldi9udWxsOyBybSAtZiAiJHBpZGZpbGUiCiAgICByZXR1cm4gMAp9CgojIFdpLUZpIHNhdmVkIG9uIHRoZSBzdGljayBieSB0aGUgTm9kZSBNYWtlciwgYXBwbGllZCBoZXJlIHdoZW4gdGhlIGluc3RhbGxlciBjb3VsZCBub3QgdXNlCiMgaXQgKHRoZSBhZGFwdGVyIGhhZCBubyBmaXJtd2FyZSBhdCBpbnN0YWxsIHRpbWUpLiBOZWVkcyB0aGUgaW5zdGFsbGVyIGNvZGUgdGhlIHN0aWNrIGNhcnJpZWQuCndpZmlfYXBwbHlfc2F2ZWQoKSB7CiAgICBsb2NhbCBpZmFjZT0nJyBkIHNzaWQgYXV0aCBwc2sKICAgIFsgLWYgIiRTVEFURS93aWZpLmVuYyIgXSAmJiBbIC1mICIkU1RBVEUvcGFpci1jb2RlIiBdIHx8IHJldHVybiAxCiAgICBbIC1mIC9ldGMvbmV0cGxhbi85MC1uYWx2by13aWZpLnlhbWwgXSAmJiByZXR1cm4gMQogICAgZm9yIGQgaW4gIiR7TkFMVk9fU1lTX05FVDotL3N5cy9jbGFzcy9uZXR9Ii8qL3dpcmVsZXNzOyBkbwogICAgICAgIFsgLWQgIiRkIiBdIHx8IGNvbnRpbnVlCiAgICAgICAgaWZhY2U9JChiYXNlbmFtZSAiJChkaXJuYW1lICIkZCIpIikKICAgICAgICBbWyAiJGlmYWNlIiA9fiBeW0EtWmEtejAtOV8uLV17MSwxNX0kIF1dICYmIGJyZWFrCiAgICAgICAgaWZhY2U9JycKICAgIGRvbmUKICAgIFsgLW4gIiRpZmFjZSIgXSB8fCByZXR1cm4gMQogICAgSUZTPSByZWFkIC1yIC1kICcnIHNzaWQgPCA8KHdpZmlfZGVjcnlwdF9zYXZlZCAxKSB8fCB0cnVlCiAgICBJRlM9IHJlYWQgLXIgLWQgJycgYXV0aCA8IDwod2lmaV9kZWNyeXB0X3NhdmVkIDIpIHx8IHRydWUKICAgIElGUz0gcmVhZCAtciAtZCAnJyBwc2sgPCA8KHdpZmlfZGVjcnlwdF9zYXZlZCAzKSB8fCB0cnVlCiAgICBbIC1uICIkc3NpZCIgXSAmJiBbIC1uICIkYXV0aCIgXSB8fCB7IHBzaz0nJzsgcmV0dXJuIDE7IH0KICAgIGlmIHdpZmlfd3JpdGVfbmV0cGxhbiAiJGlmYWNlIiAiJHNzaWQiICIkYXV0aCIgIiRwc2siOyB0aGVuCiAgICAgICAgcHNrPScnCiAgICAgICAgcHJpbnRmICdVc2luZyB0aGUgV2ktRmkgc2F2ZWQgb24gdGhlIHN0aWNrICglcykuCicgIiRzc2lkIgogICAgICAgIG5ldHBsYW4gZ2VuZXJhdGUgPi9kZXYvbnVsbCAyPiYxICYmIG5ldHBsYW4gYXBwbHkgPi9kZXYvbnVsbCAyPiYxIHx8IHRydWUKICAgICAgICB0aW1lZGF0ZWN0bCBzZXQtbnRwIHRydWUgPj4iJExPRyIgMj4mMSB8fCB0cnVlCiAgICAgICAgcm0gLWYgIiRTVEFURS93aWZpLmVuYyIKICAgICAgICByZXR1cm4gMAogICAgZmkKICAgIHBzaz0nJwogICAgcmV0dXJuIDEKfQoKd2lmaV9kZWNyeXB0X3NhdmVkKCkgeyAjIGZpZWxkIG51bWJlciAoMSBzc2lkLCAyIGF1dGgsIDMgcHNrKTsgTlVMLXRlcm1pbmF0ZWQ7IG5vdGhpbmcgaXMgbG9nZ2VkCiAgICBweXRob24zIC1JIC0gIiRTVEFURS93aWZpLmVuYyIgIiRTVEFURS9wYWlyLWNvZGUiICIkMSIgPDwnUFknIDI+L2Rldi9udWxsCmltcG9ydCBoYXNobGliLCBobWFjLCBqc29uLCByZSwgc3VicHJvY2Vzcywgc3lzCmVuYywgY29kZV9wYXRoLCBmaWVsZCA9IHN5cy5hcmd2WzFdLCBzeXMuYXJndlsyXSwgaW50KHN5cy5hcmd2WzNdKQpjb2RlID0gb3Blbihjb2RlX3BhdGgsIGVuY29kaW5nPSJhc2NpaSIpLnJlYWQoKS5zdHJpcCgpCmRhdGEgPSBvcGVuKGVuYywgInJiIikucmVhZCg2NTUzNykKaWYgKG5vdCByZS5mdWxsbWF0Y2gociJbMC05QS1ISktNTlAtVFYtWl17MjB9IiwgY29kZSkgb3IgbGVuKGRhdGEpIDwgODggb3IgbGVuKGRhdGEpID4gNjU1MzYKICAgICAgICBvciBkYXRhWzo4XSAhPSBiIk5BTFZPV0YxIiBvciAobGVuKGRhdGEpIC0gNzIpICUgMTYpOgogICAgc3lzLmV4aXQoMSkKa2V5cyA9IGhhc2hsaWIucGJrZGYyX2htYWMoInNoYTI1NiIsIGNvZGUuZW5jb2RlKCJ1dGYtOCIpLCBkYXRhWzg6MjRdLCAyMDAwMDAsIDY0KQppZiBub3QgaG1hYy5jb21wYXJlX2RpZ2VzdChobWFjLm5ldyhrZXlzWzMyOl0sIGRhdGFbOi0zMl0sIGhhc2hsaWIuc2hhMjU2KS5kaWdlc3QoKSwgZGF0YVstMzI6XSk6CiAgICBzeXMuZXhpdCgxKQpwbGFpbiA9IHN1YnByb2Nlc3MucnVuKFsib3BlbnNzbCIsICJlbmMiLCAiLWQiLCAiLWFlcy0yNTYtY2JjIiwgIi1LIiwga2V5c1s6MzJdLmhleCgpLCAiLWl2IiwgZGF0YVsyNDo0MF0uaGV4KCldLAogICAgICAgICAgICAgICAgICAgICAgIGlucHV0PWRhdGFbNDA6LTMyXSwgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuREVWTlVMTCwgY2hlY2s9VHJ1ZSkuc3Rkb3V0CnByb2ZpbGUgPSBqc29uLmxvYWRzKHBsYWluLmRlY29kZSgidXRmLTgiKSkKdmFsdWUgPSBbcHJvZmlsZVsic3NpZCJdLCBwcm9maWxlWyJhdXRoIl0sIHByb2ZpbGVbInBzayJdXVtmaWVsZCAtIDFdCmlmIG5vdCBpc2luc3RhbmNlKHZhbHVlLCBzdHIpOgogICAgc3lzLmV4aXQoMSkKc3lzLnN0ZG91dC53cml0ZSh2YWx1ZSArICJcMCIpClBZCn0KCiMgUGxhaW4gZmFjdHMgZm9yIHRoZSBob3N0OiB3aGF0IHRoZSBzZXR1cCBmb3VuZCBhbmQgd2h5IGl0IGlzIHN0aWxsIHdhaXRpbmcuCndpZmlfc3RhdHVzX3JlcG9ydCgpIHsKICAgIGxvY2FsIGFkYXB0ZXIgZHJpdmVycyBmdyBpZmFjZT0nJyBkIHJmIHNhdmVkIG5ldHBsYW4KICAgIGFkYXB0ZXI9JChsc3BjaSAtbm4gMj4vZGV2L251bGwgfCBncmVwIC1pIC1FICduZXR3b3JrIGNvbnRyb2xsZXJ8d2lyZWxlc3MnIHwgaGVhZCAtMSB8IHNlZCAncy9eWzAtOWEtZjouXSogLy8nIHwgY3V0IC1jMS03MCkKICAgIGRyaXZlcnM9JChsc21vZCAyPi9kZXYvbnVsbCB8IGdyZXAgLWMgLUUgJ14ocnR3ODl8cnR3ODh8aXdsd2lmaXxtdDc2fGF0aFswLTldK2t8YnJjbWZtYWMpJykKICAgIGZ3PSQobHMgL2xpYi9maXJtd2FyZS9ydHc4OSAyPi9kZXYvbnVsbCB8IHdjIC1sKQogICAgZm9yIGQgaW4gIiR7TkFMVk9fU1lTX05FVDotL3N5cy9jbGFzcy9uZXR9Ii8qL3dpcmVsZXNzOyBkbyBbIC1kICIkZCIgXSAmJiBpZmFjZT0kKGJhc2VuYW1lICIkKGRpcm5hbWUgIiRkIikiKSAmJiBicmVhazsgZG9uZQogICAgcmY9JChyZmtpbGwgbGlzdCAyPi9kZXYvbnVsbCB8IGdyZXAgLWMgJ2Jsb2NrZWQ6IHllcycpCiAgICBzYXZlZD1ubzsgWyAtZiAiJFNUQVRFL3dpZmkuZW5jIiBdICYmIHNhdmVkPXllcwogICAgbmV0cGxhbj1ubzsgWyAtZiAvZXRjL25ldHBsYW4vOTAtbmFsdm8td2lmaS55YW1sIF0gJiYgbmV0cGxhbj15ZXMKICAgIHByaW50ZiAnXG5XaGF0IHRoZSBzZXR1cCBmb3VuZDpcbicKICAgIHByaW50ZiAnICBXaS1GaSBhZGFwdGVyOiAlc1xuJyAiJHthZGFwdGVyOi1ub25lfSIKICAgIHByaW50ZiAnICBEcml2ZXIgbG9hZGVkOiAlcyB8IGZpcm13YXJlIGZpbGVzOiAlcyB8IFdpLUZpIGludGVyZmFjZTogJXMgfCByYWRpbyBibG9ja2VkOiAlc1xuJyBcCiAgICAgICAgIiQoWyAiJHtkcml2ZXJzOi0wfSIgLWd0IDAgXSAmJiBlY2hvIHllcyB8fCBlY2hvIG5vKSIgIiRmdyIgIiR7aWZhY2U6LW5vbmV9IiAiJChbICIke3JmOi0wfSIgLWd0IDAgXSAmJiBlY2hvIHllcyB8fCBlY2hvIG5vKSIKICAgIHByaW50ZiAnICBXaS1GaSBzYXZlZCBvbiB0aGUgc3RpY2s6ICVzIHwgV2ktRmkgY29uZmlndXJlZDogJXMgfCBsYXN0IHNjYW46ICVzXG4nICIkc2F2ZWQiICIkbmV0cGxhbiIgIiR7V0lGSV9MQVNUX1NDQU46LW5vdCB5ZXR9IgogICAgbG9jYWwgc3RhdGU9JycgaXA0PScnCiAgICBpZiBbIC1uICIkaWZhY2UiIF0gJiYgY29tbWFuZCAtdiB3cGFfY2xpID4vZGV2L251bGwgMj4mMTsgdGhlbgogICAgICAgIHN0YXRlPSQod3BhX2NsaSAtaSAiJGlmYWNlIiBzdGF0dXMgMj4vZGV2L251bGwgfCBhd2sgLUY9ICckMSA9PSAid3BhX3N0YXRlIiB7IHByaW50IHRvbG93ZXIoJDIpIH0nKQogICAgICAgIGlwND0kKGlwIC00IC1icmllZiBhZGRyIHNob3cgIiRpZmFjZSIgMj4vZGV2L251bGwgfCBhd2sgJ3sgcHJpbnQgJDMgfScgfCBoZWFkIC0xKQogICAgZmkKICAgIHByaW50ZiAnICBXaS1GaSBjb25uZWN0aW9uOiAlcyB8IGFkZHJlc3M6ICVzXG4nICIke3N0YXRlOi1ub3Qgc3RhcnRlZH0iICIke2lwNDotbm9uZX0iCiAgICBwcmludGYgJyAgUmVwb3J0IGZvciBzdXBwb3J0OiAlc1xuJyAiJHtESUFHX1NUQVRVUzotbm90IHdyaXR0ZW4geWV0fSIKICAgIHByaW50ZiAnICBBIHBob25lIG9uIGEgVVNCIGNhYmxlIHdpdGggVVNCIHRldGhlcmluZyB0dXJuZWQgb24gYWxzbyB3b3JrcyBsaWtlIGEgY2FibGUuXG4nCn0KCiMgRXZlcnkgd2lyZWQtbG9va2luZyBpbnRlcmZhY2UgKEV0aGVybmV0LCBhbmQgYSBwaG9uZSBvbiBVU0IgdGV0aGVyaW5nKSBnZXRzIERIQ1AsCiMgd2hhdGV2ZXIgaXRzIG5hbWUsIHNvIHBsdWdnaW5nIGFueSBjYWJsZSBvciBhIHRldGhlcmVkIHBob25lIGFsd2F5cyB3b3Jrcy4KbmV0X2VuYWJsZV9hbnl3aXJlKCkgewogICAgbG9jYWwgcGF0aD0vZXRjL25ldHBsYW4vODUtbmFsdm8tYW55d2lyZS55YW1sCiAgICBbIC1mICIkcGF0aCIgXSAmJiByZXR1cm4gMAogICAgdW1hc2sgMDc3CiAgICBjYXQgPiAiJHBhdGgiIDw8J1lBTUwnCm5ldHdvcms6CiAgdmVyc2lvbjogMgogIGV0aGVybmV0czoKICAgIG5hbHZvLWFueXdpcmU6CiAgICAgIG1hdGNoOiB7IG5hbWU6ICJlbioiIH0KICAgICAgZGhjcDQ6IHRydWUKICAgICAgb3B0aW9uYWw6IHRydWUKICAgICAgZGhjcDQtb3ZlcnJpZGVzOiB7IHJvdXRlLW1ldHJpYzogMTAwIH0KICAgIG5hbHZvLWV0aHdpcmU6CiAgICAgIG1hdGNoOiB7IG5hbWU6ICJldGgqIiB9CiAgICAgIGRoY3A0OiB0cnVlCiAgICAgIG9wdGlvbmFsOiB0cnVlCiAgICAgIGRoY3A0LW92ZXJyaWRlczogeyByb3V0ZS1tZXRyaWM6IDEwMCB9CiAgICBuYWx2by11c2J3aXJlOgogICAgICBtYXRjaDogeyBuYW1lOiAidXNiKiIgfQogICAgICBkaGNwNDogdHJ1ZQogICAgICBvcHRpb25hbDogdHJ1ZQogICAgICBkaGNwNC1vdmVycmlkZXM6IHsgcm91dGUtbWV0cmljOiAxMTAgfQpZQU1MCiAgICBjaG1vZCAwNjAwICIkcGF0aCIKICAgIG5ldHBsYW4gZ2VuZXJhdGUgPi9kZXYvbnVsbCAyPiYxICYmIG5ldHBsYW4gYXBwbHkgPi9kZXYvbnVsbCAyPiYxIHx8IHRydWUKfQoKIyBBIGRpYWdub3N0aWMgcmVwb3J0IHdyaXR0ZW4gb250byB0aGUgTmFsdm8gc3RpY2sgKG5hbHZvL2RpYWcvcmVwb3J0LnR4dCwgbm8gc2VjcmV0cyksCiMgc28gc3VwcG9ydCBjYW4gc2VlIHdoYXQgaGFwcGVuZWQgd2l0aG91dCBhbnlvbmUgbG9nZ2luZyBpbiB0byB0aGUgbm9kZS4Kc3RpY2tfd3JpdGVfZGlhZygpIHsKICAgIGxvY2FsIGRldj0nJyB0bXAgbm93IGV4aXN0aW5nIHRhcmdldD0nJyBjbGVhbnVwPTAKICAgIG5vdz0kKGRhdGUgKyVzKTsgWyAkKChub3cgLSAke0RJQUdfTEFTVDotMH0pKSAtZ2UgNjAgXSB8fCByZXR1cm4gMAogICAgRElBR19MQVNUPSRub3cKICAgICMgVGhlIHJlcG9ydCBhbHdheXMgc3RheXMgb24gdGhlIG5vZGUgdG9vIChzdXBwb3J0IG92ZXIgU1NIIGxhdGVyKS4KICAgIHN0aWNrX2RpYWdfdGV4dCA+ICIkU1RBVEUvZGlhZy1yZXBvcnQudHh0IiAyPi9kZXYvbnVsbCB8fCB0cnVlCiAgICBkZXY9JChibGtpZCAtTCBOQUxWTyAyPi9kZXYvbnVsbCB8fCB0cnVlKQogICAgWyAtbiAiJGRldiIgXSB8fCBkZXY9JChsc2JsayAtbG5wbyBOQU1FLFRZUEUsTEFCRUwgMj4vZGV2L251bGwgfCBhd2sgJyQyID09ICJwYXJ0IiAmJiAkMyA9PSAiTkFMVk8iIHsgcHJpbnQgJDE7IGV4aXQgfScpCiAgICBpZiBbIC16ICIkZGV2IiBdOyB0aGVuIERJQUdfU1RBVFVTPSJubyBOYWx2byBzdGljayBmb3VuZCBhdCAkKGRhdGUgKyVIOiVNKSI7IHJldHVybiAwOyBmaQogICAgZXhpc3Rpbmc9JChmaW5kbW50IC1ybiAtUyAiJGRldiIgLW8gVEFSR0VUIDI+L2Rldi9udWxsIHwgaGVhZCAtMSkKICAgIGlmIFsgLW4gIiRleGlzdGluZyIgXTsgdGhlbgogICAgICAgIHRhcmdldD0iJGV4aXN0aW5nIgogICAgICAgIG1vdW50IC1vIHJlbW91bnQscncgIiR0YXJnZXQiID4+IiRMT0ciIDI+JjEgfHwgdHJ1ZQogICAgZWxzZQogICAgICAgIHRtcD0kKG1rdGVtcCAtZCAvcnVuL25hbHZvLWRpYWcuWFhYWFhYKSB8fCB7IERJQUdfU1RBVFVTPSJubyB0ZW1wIGZvbGRlciI7IHJldHVybiAwOyB9CiAgICAgICAgaWYgbW91bnQgLW8gcncsbm9zdWlkLG5vZGV2LG5vZXhlYyAiJGRldiIgIiR0bXAiID4+IiRMT0ciIDI+JjE7IHRoZW4gdGFyZ2V0PSIkdG1wIjsgY2xlYW51cD0xCiAgICAgICAgZWxzZSBybWRpciAiJHRtcCIgMj4vZGV2L251bGwgfHwgdHJ1ZTsgRElBR19TVEFUVVM9InN0aWNrICRkZXYgY291bGQgbm90IGJlIG9wZW5lZCBmb3Igd3JpdGluZyBhdCAkKGRhdGUgKyVIOiVNKSI7IHJldHVybiAwOyBmaQogICAgZmkKICAgIGlmIG1rZGlyIC1wICIkdGFyZ2V0L25hbHZvL2RpYWciIDI+PiIkTE9HIiAmJiBjcCAiJFNUQVRFL2RpYWctcmVwb3J0LnR4dCIgIiR0YXJnZXQvbmFsdm8vZGlhZy9yZXBvcnQudHh0IiAyPj4iJExPRyI7IHRoZW4KICAgICAgICBzeW5jOyBESUFHX1NUQVRVUz0id3JpdHRlbiB0byB0aGUgc3RpY2sgYXQgJChkYXRlICslSDolTSkgKG5hbHZvL2RpYWcvcmVwb3J0LnR4dCkiCiAgICBlbHNlCiAgICAgICAgRElBR19TVEFUVVM9InN0aWNrICRkZXYgaXMgcmVhZC1vbmx5IG9yIGZ1bGwgYXQgJChkYXRlICslSDolTSkiCiAgICBmaQogICAgaWYgWyAiJGNsZWFudXAiID0gMSBdOyB0aGVuIHVtb3VudCAiJHRhcmdldCIgPj4iJExPRyIgMj4mMSB8fCB0cnVlOyBybWRpciAiJHRhcmdldCIgMj4vZGV2L251bGwgfHwgdHJ1ZTsgZmkKICAgIHJldHVybiAwCn0KCnN0aWNrX2RpYWdfdGV4dCgpIHsKICAgICAgICB7CiAgICAgICAgICAgIHByaW50ZiAnTmFsdm8gbm9kZSBkaWFnbm9zdGljICVzXG4nICIkKGRhdGUgLXUgKyVGVCVUWikiCiAgICAgICAgICAgIHdpZmlfc3RhdHVzX3JlcG9ydAogICAgICAgICAgICBwcmludGYgJ1xuPT0gbmV0d29yayBkZXZpY2VzID09XG4nOyBsc3BjaSAtbm4gMj4vZGV2L251bGwgfCBncmVwIC1pIC1FICduZXR3b3JrfGV0aGVybmV0JzsgaXAgLWJyaWVmIGxpbmsgMj4vZGV2L251bGwKICAgICAgICAgICAgcHJpbnRmICdcbj09IHJma2lsbCA9PVxuJzsgcmZraWxsIGxpc3QgMj4vZGV2L251bGwKICAgICAgICAgICAgcHJpbnRmICdcbj09IGZpcm13YXJlID09XG4nOyBscyAtbGEgL2xpYi9maXJtd2FyZS9ydHc4OS8gMj4vZGV2L251bGwKICAgICAgICAgICAgcHJpbnRmICdcbj09IGtlcm5lbCAod2lmaSkgPT1cbic7IGRtZXNnIDI+L2Rldi9udWxsIHwgZ3JlcCAtaSAtRSAncnR3fHdsYW58ZmlybXdhcmV8ODAyMTEnIHwgdGFpbCAtNDAKICAgICAgICAgICAgcHJpbnRmICdcbj09IG5ldHBsYW4gKHNlY3JldHMgaGlkZGVuKSA9PVxuJzsgc2VkICdzL3Bhc3N3b3JkOi4qL3Bhc3N3b3JkOiBbaGlkZGVuXS8nIC9ldGMvbmV0cGxhbi8qLnlhbWwgMj4vZGV2L251bGwKICAgICAgICAgICAgcHJpbnRmICdcbj09IHNldHVwIGxvZyAodGFpbCkgPT1cbic7IHRhaWwgLTYwICIkTE9HIiAyPi9kZXYvbnVsbAogICAgICAgIH0KfQoKd2FpdF9uZXR3b3JrKCkgewogICAgbG9jYWwgaT0wIHNlbGVjdGVkPTAga2V5IHJlc3QgZnJhbWVzPSd8Ly1cJyBmcmFtZQogICAgcHJpbnRmICclcyBXYWl0aW5nIGZvciBGbGVldCBNYW5hZ2VyLlxuJyAiJChkYXRlIC11ICslRlQlVFopIiA+PiIkTE9HIgogICAgcHJpbnRmICdcbldhaXRpbmcgZm9yIHRoZSBpbnRlcm5ldC4gV2ktRmkgZmlybXdhcmUgb24gYSBVU0Igc3RpY2sgaXMgYXBwbGllZCBhdXRvbWF0aWNhbGx5LlxuJwogICAgcHJpbnRmICcgIDEuIENvbm5lY3QgdG8gV2ktRmlcbiAgMi4gVXNlIGFuIEV0aGVybmV0IGNhYmxlIGluc3RlYWRcbicKICAgIHByaW50ZiAnQ2hvb3NlIGEgbnVtYmVyLCBvciB1c2UgYXJyb3dzIGFuZCBFbnRlci5cbicKICAgICMgU29tZSBib2FyZHMgc3RhcnQgd2l0aCB0aGUgcmFkaW8gc29mdC1ibG9ja2VkOyBub3RoaW5nIHNjYW5zIHVudGlsIGl0IGlzIHJlbGVhc2VkLgogICAgcmZraWxsIHVuYmxvY2sgYWxsID4+IiRMT0ciIDI+JjEgfHwgdHJ1ZQogICAgbmV0X2VuYWJsZV9hbnl3aXJlIHx8IHRydWUKICAgIHdpZmlfc3RhdHVzX3JlcG9ydAogICAgU1RBVFVTX0xBU1Q9JChkYXRlICslcykKICAgIFdBSVRfU1RBUlRFRD0kKGRhdGUgKyVzKQogICAgd2hpbGUgOjsgZG8KICAgICAgICB3aWZpX3JlY292ZXJfZmlybXdhcmUgfHwgdHJ1ZQogICAgICAgIHdpZmlfYXBwbHlfc2F2ZWQgfHwgdHJ1ZQogICAgICAgICMgVGhlIHNhdmVkIG5ldHdvcmsgaXMgY29uZmlndXJlZCBidXQgbm90aGluZyBjb25uZWN0ZWQgYWZ0ZXIgOTAgczogdHJ5IHRoZSBjYXJkIHBvd2VyIGZpeCBvbmNlLgogICAgICAgIGlmIFsgLWYgL2V0Yy9uZXRwbGFuLzkwLW5hbHZvLXdpZmkueWFtbCBdICYmIFsgJCgoICQoZGF0ZSArJXMpIC0gV0FJVF9TVEFSVEVEICkpIC1nZSA5MCBdOyB0aGVuIHdpZmlfcGNpZV9mYWxsYmFjayB8fCB0cnVlOyBmaQogICAgICAgIHN0aWNrX3dyaXRlX2RpYWcgfHwgdHJ1ZQogICAgICAgIGlmIFsgJCgoICQoZGF0ZSArJXMpIC0gJHtTVEFUVVNfTEFTVDotMH0gKSkgLWdlIDMwIF07IHRoZW4gcHJpbnRmICdcbic7IHdpZmlfc3RhdHVzX3JlcG9ydDsgU1RBVFVTX0xBU1Q9JChkYXRlICslcyk7IGZpCiAgICAgICAgaWYgY3VybCAtZnNTIC0tbWF4LXRpbWUgNSAiJEZMRUVUL2FnZW50L21hbmlmZXN0Lmpzb24iIC1vIC9kZXYvbnVsbCAyPj4iJExPRyI7IHRoZW4KICAgICAgICAgICAgcHJpbnRmICdcckNvbm5lY3RlZCB0byBGbGVldCBNYW5hZ2VyLiAgICAgICAgICAgICAgICAgICAgICAgICBcbicKICAgICAgICAgICAgcmV0dXJuIDAKICAgICAgICBmaQogICAgICAgIGZyYW1lPSR7ZnJhbWVzOiQoKCBpICUgNCApKToxfTsgaT0kKChpICsgMSkpCiAgICAgICAgaWYgWyAiJHNlbGVjdGVkIiA9IDAgXTsgdGhlbgogICAgICAgICAgICBwcmludGYgJ1xyV2FpdGluZyBmb3IgdGhlIGludGVybmV0Li4uICVzICBbMS4gQ29ubmVjdCB0byBXaS1GaV0gIDIuIEV0aGVybmV0ICAgJyAiJGZyYW1lIgogICAgICAgIGVsc2UKICAgICAgICAgICAgcHJpbnRmICdccldhaXRpbmcgZm9yIHRoZSBpbnRlcm5ldC4uLiAlcyAgMS4gV2ktRmkgIFsyLiBVc2UgYW4gRXRoZXJuZXQgY2FibGUgaW5zdGVhZF0gICAnICIkZnJhbWUiCiAgICAgICAgZmkKICAgICAgICBpZiBJRlM9IHJlYWQgLXJzbjEgLXQgMiBrZXk7IHRoZW4KICAgICAgICAgICAgY2FzZSAiJGtleSIgaW4KICAgICAgICAgICAgICAgIDEpIHNlbGVjdGVkPTA7IHByaW50ZiAnXG4nOyB3aWZpX2Nvbm5lY3QgJiYgcmV0dXJuIDA7OwogICAgICAgICAgICAgICAgMikgc2VsZWN0ZWQ9MTsgcHJpbnRmICdcbkNvbm5lY3QgdGhlIEV0aGVybmV0IGNhYmxlLiBTZXR1cCB3aWxsIGNvbnRpbnVlIGF1dG9tYXRpY2FsbHkuXG4nOzsKICAgICAgICAgICAgICAgICcnKSBpZiBbICIkc2VsZWN0ZWQiID0gMCBdOyB0aGVuIHByaW50ZiAnXG4nOyB3aWZpX2Nvbm5lY3QgJiYgcmV0dXJuIDA7IGVsc2UgcHJpbnRmICdcbkNvbm5lY3QgdGhlIEV0aGVybmV0IGNhYmxlLiBTZXR1cCB3aWxsIGNvbnRpbnVlIGF1dG9tYXRpY2FsbHkuXG4nOyBmaTs7CiAgICAgICAgICAgICAgICAkJ1xlJykKICAgICAgICAgICAgICAgICAgICBJRlM9IHJlYWQgLXJzbjEgLXQgMC4xIHJlc3QgfHwgY29udGludWUKICAgICAgICAgICAgICAgICAgICBbICIkcmVzdCIgPSAnWycgXSB8fCBjb250aW51ZQogICAgICAgICAgICAgICAgICAgIElGUz0gcmVhZCAtcnNuMSAtdCAwLjEgcmVzdCB8fCBjb250aW51ZQogICAgICAgICAgICAgICAgICAgIGNhc2UgIiRyZXN0IiBpbiBBfEIpIHNlbGVjdGVkPSQoKDEtc2VsZWN0ZWQpKTs7IGVzYWM7OwogICAgICAgICAgICBlc2FjCiAgICAgICAgZmkKICAgIGRvbmUKfQoKd2FpdF9mb3JfY2xvY2soKSB7CiAgICBzYXkgIkNoZWNraW5nIHRoZSBjb21wdXRlcidzIGNsb2NrLiBUaGlzIGNhbiB0YWtlIGEgbWludXRlLiIKICAgICMgQm91bmQgdGhlIHdob2xlIHBvbGxpbmcgcHJvY2VzcywgaW5jbHVkaW5nIGEgc3R1Y2sgdGltZWRhdGVjdGwsIHJhdGhlcgogICAgIyB0aGFuIG9ubHkgY291bnRpbmcgc2xlZXBzLiBFc2NhbGF0aW9uIGxlYXZlcyBhdCBtb3N0IG9uZSBzZWNvbmQgZm9yIFRFUk0uCiAgICBpZiB0aW1lb3V0IC0ta2lsbC1hZnRlcj0xcyA1OXMgYmFzaCAtYyAnCiAgICAgICAgd2hpbGUgOjsgZG8KICAgICAgICAgICAgWyAiJCh0aW1lZGF0ZWN0bCBzaG93IC1wIE5UUFN5bmNocm9uaXplZCAtLXZhbHVlKSIgPSB5ZXMgXSAmJiBleGl0IDAKICAgICAgICAgICAgc2xlZXAgMQogICAgICAgIGRvbmUKICAgICcgPj4iJExPRyIgMj4mMTsgdGhlbgogICAgICAgIHJldHVybiAwCiAgICBmaQogICAgIyBPZmZsaW5lIGNsb2NrcyBjYW5ub3Qgc3luY2hyb25pemUuIENvbnRpbnVlIHRvIHRoZSBuZXR3b3JrIHdhaXQgc28gdGhlCiAgICAjIG93bmVyIHNlZXMgdGhlIGNvbm5lY3Rpb24gZ3VpZGFuY2U7IFRMUyB3aWxsIHN1Y2NlZWQgb25jZSB0aW1lIGlzIHZhbGlkLgogICAgcHJpbnRmICclcyBDbG9jayBub3Qgc3luY2hyb25pemVkIHlldDsgd2FpdGluZyBmb3IgbmV0d29yay5cbicgIiQoZGF0ZSAtdSArJUZUJVRaKSIgPj4iJExPRyIKfQoKaHlnaWVuZSgpIHsKICAgIGRvbmVfIGh5Z2llbmUgJiYgcmV0dXJuIDAKICAgICMgbm8gYXV0b21hdGljIHVwZ3JhZGVzOiBwYXRjaGVzIGFyZSBhcHBsaWVkIGRlbGliZXJhdGVseSAoVmFzdDogZGlzYWJsZSBhdXRvLXVwZGF0ZXMpCiAgICBwcmludGYgJ0FQVDo6UGVyaW9kaWM6OlVwZGF0ZS1QYWNrYWdlLUxpc3RzICIwIjtcbkFQVDo6UGVyaW9kaWM6OlVuYXR0ZW5kZWQtVXBncmFkZSAiMCI7XG4nIFwKICAgICAgICA+L2V0Yy9hcHQvYXB0LmNvbmYuZC8yMGF1dG8tdXBncmFkZXMKICAgIHN5c3RlbWN0bCBkaXNhYmxlIC0tbm93IHVuYXR0ZW5kZWQtdXBncmFkZXMuc2VydmljZSA+L2Rldi9udWxsIDI+JjEgfHwgdHJ1ZQogICAgIyBvbmUgVWJ1bnR1IHZlcnNpb246IG5ldmVyIG9mZmVyIGEgcmVsZWFzZSB1cGdyYWRlCiAgICBbIC1mIC9ldGMvdXBkYXRlLW1hbmFnZXIvcmVsZWFzZS11cGdyYWRlcyBdICYmIHNlZCAtaSAncy9eUHJvbXB0PS4qL1Byb21wdD1uZXZlci8nIC9ldGMvdXBkYXRlLW1hbmFnZXIvcmVsZWFzZS11cGdyYWRlcwogICAgIyBTU0g6IGtleXMgb25seSAoVmFzdCB2ZXJpZmljYXRpb24pLiBBIGRyb3AtaW4gdGhhdCBzb3J0cyBmaXJzdCB3aW5zIG92ZXIgbGF0ZXIgZmlsZXMuCiAgICBpbnN0YWxsIC1kIC1tIDA3NTUgL2V0Yy9zc2gvc3NoZF9jb25maWcuZAogICAgcHJpbnRmICdQYXNzd29yZEF1dGhlbnRpY2F0aW9uIG5vXG5LYmRJbnRlcmFjdGl2ZUF1dGhlbnRpY2F0aW9uIG5vXG4nID4vZXRjL3NzaC9zc2hkX2NvbmZpZy5kLzAwLW5hbHZvLmNvbmYKICAgIGlmICEgc3NoZF9jZmcgfCBncmVwIC1xaXggJ3Bhc3N3b3JkYXV0aGVudGljYXRpb24gbm8nOyB0aGVuCiAgICAgICAgc3RvcF9oZXJlICJDb250YWN0IE5hbHZvIHN1cHBvcnQgZm9yIGhlbHAgd2l0aCBzZXR1cC4iCiAgICBmaQogICAgeyBpbnN0YWxsIC1kIC1tIDA3NTUgL3J1bi9zc2hkOyBzc2hkIC10ICYmIHN5c3RlbWN0bCB0cnktcmVsb2FkLW9yLXJlc3RhcnQgc3NoLnNlcnZpY2U7IH0gPj4iJExPRyIgMj4mMSB8fCB0cnVlCiAgICBtYXJrIGh5Z2llbmUKICAgIHNheSAiVGhlIGNvbXB1dGVyJ3Mgc2V0dGluZ3MgYXJlIHJlYWR5LiIKfQoKZG9ja2VyX3N0b3JhZ2UoKSB7CiAgICBkb25lXyBkb2NrZXIgJiYgcmV0dXJuIDAKICAgIGlmIG1vdW50cG9pbnQgLXEgL3Zhci9saWIvZG9ja2VyOyB0aGVuIG1hcmsgZG9ja2VyOyByZXR1cm4gMDsgZmkKICAgIGxvY2FsIFZHIHJvb3Rfc3JjIGZyZWVfZyBhZGRlZD0wIGRldgogICAgcm9vdF9zcmM9JChmaW5kbW50IC1udm8gU09VUkNFIC8gMj4vZGV2L251bGwpCiAgICBWRz0kKGx2cyAtLW5vaGVhZGluZ3MgLW8gdmdfbmFtZSAiJHJvb3Rfc3JjIiAyPi9kZXYvbnVsbCB8IHRyIC1kICdbOnNwYWNlOl0nKQogICAgaWYgWyAteiAiJFZHIiBdIHx8ICEgdmdzICIkVkciID4vZGV2L251bGwgMj4mMTsgdGhlbgogICAgICAgIHNheSAiTmFsdm8gY2FuIGNvbnRpbnVlLiBDb250YWN0IHN1cHBvcnQgYmVmb3JlIHVzaW5nIFZhc3Qgb24gdGhpcyBjb21wdXRlci4iCiAgICAgICAgbWFyayBkb2NrZXI7IHJldHVybiAwCiAgICBmaQogICAgZGV2PSIvZGV2LyRWRy9kb2NrZXIiCiAgICBpZiAhIGx2cyAiJFZHL2RvY2tlciIgPi9kZXYvbnVsbCAyPiYxOyB0aGVuCiAgICAgICAgZnJlZV9nPSQodmdzIC0tbm9oZWFkaW5ncyAtLXVuaXRzIGcgLS1ub3N1ZmZpeCAtbyB2Z19mcmVlICIkVkciIHwgYXdrICd7cHJpbnRmICIlZCIsICQxfScpCiAgICAgICAgaWYgWyAiJHtmcmVlX2c6LTB9IiAtbHQgMTAgXTsgdGhlbgogICAgICAgICAgICBzYXkgIk5hbHZvIGNhbiBjb250aW51ZS4gQ29udGFjdCBzdXBwb3J0IGJlZm9yZSB1c2luZyBWYXN0IG9uIHRoaXMgY29tcHV0ZXIuIgogICAgICAgICAgICBtYXJrIGRvY2tlcjsgcmV0dXJuIDAKICAgICAgICBmaQogICAgICAgIGx2Y3JlYXRlIC15IC1sIDEwMCVGUkVFIC1uIGRvY2tlciAiJFZHIiA+PiIkTE9HIiAyPiYxIHx8IHsgc2F5ICJOYWx2byBjYW4gY29udGludWUuIENvbnRhY3Qgc3VwcG9ydCBiZWZvcmUgdXNpbmcgVmFzdCBvbiB0aGlzIGNvbXB1dGVyLiI7IG1hcmsgZG9ja2VyOyByZXR1cm4gMDsgfQogICAgZmkKICAgICMgbmV2ZXIgcmVmb3JtYXQgYSB2b2x1bWUgdGhhdCBhbHJlYWR5IGNhcnJpZXMgYSBmaWxlc3lzdGVtIChhbiBlYXJsaWVyIGludGVycnVwdGVkIHJ1bikKICAgIGlmICEgYmxraWQgLXAgIiRkZXYiID4vZGV2L251bGwgMj4mMTsgdGhlbgogICAgICAgIG1rZnMueGZzIC1mIC1MIG5hbHZvLWRvY2tlciAiJGRldiIgPj4iJExPRyIgMj4mMSB8fCB7IHNheSAiTmFsdm8gY2FuIGNvbnRpbnVlLiBDb250YWN0IHN1cHBvcnQgYmVmb3JlIHVzaW5nIFZhc3Qgb24gdGhpcyBjb21wdXRlci4iOyBtYXJrIGRvY2tlcjsgcmV0dXJuIDA7IH0KICAgIGZpCiAgICBpbnN0YWxsIC1kIC1tIDA3MTEgL3Zhci9saWIvZG9ja2VyCiAgICBpZiBtb3VudCAtdCB4ZnMgLW8gcHF1b3RhICIkZGV2IiAvdmFyL2xpYi9kb2NrZXIgPj4iJExPRyIgMj4mMTsgdGhlbgogICAgICAgIGlmICEgZ3JlcCAtcSAnIC92YXIvbGliL2RvY2tlciAnIC9ldGMvZnN0YWI7IHRoZW4KICAgICAgICAgICAgZWNobyAiJGRldiAvdmFyL2xpYi9kb2NrZXIgeGZzIGRlZmF1bHRzLHBxdW90YSxub2ZhaWwseC1zeXN0ZW1kLmRldmljZS10aW1lb3V0PTMwcyAwIDAiID4+L2V0Yy9mc3RhYiAmJiBhZGRlZD0xCiAgICAgICAgZmkKICAgICAgICBpbnN0YWxsIC1kIC9ldGMvc3lzdGVtZC9zeXN0ZW0vZG9ja2VyLnNlcnZpY2UuZAogICAgICAgIHByaW50ZiAnW1VuaXRdXG5SZXF1aXJlc01vdW50c0Zvcj0vdmFyL2xpYi9kb2NrZXJcbicgPi9ldGMvc3lzdGVtZC9zeXN0ZW0vZG9ja2VyLnNlcnZpY2UuZC9uYWx2by1zdG9yYWdlLmNvbmYKICAgICAgICBzeXN0ZW1jdGwgZGFlbW9uLXJlbG9hZCA+PiIkTE9HIiAyPiYxCiAgICAgICAgbWFyayBkb2NrZXIKICAgICAgICBzYXkgIlN0b3JhZ2UgaXMgcmVhZHkuIgogICAgZWxzZQogICAgICAgIFsgIiRhZGRlZCIgPSAxIF0gJiYgc2VkIC1pICdcfCAvdmFyL2xpYi9kb2NrZXIgeGZzIHxkJyAvZXRjL2ZzdGFiCiAgICAgICAgc2F5ICJOYWx2byBjYW4gY29udGludWUuIENvbnRhY3Qgc3VwcG9ydCBiZWZvcmUgdXNpbmcgVmFzdCBvbiB0aGlzIGNvbXB1dGVyLiIKICAgICAgICBtYXJrIGRvY2tlcgogICAgZmkKfQoKZ3B1X2RyaXZlcl9jaG9pY2UoKSB7ICAgIyBwcmludHMgIjx2ZXJzaW9uPiA8cGFja2FnZT4iLCAiTUlYRUQiLCAiVE9PX09MRCIsIG9yIG5vdGhpbmcgd2hlbiB0aGVyZSBpcyBubyBOVklESUEgR1BVCiAgICBsb2NhbCBncHVzCiAgICBncHVzPSQobHNwY2kgLW5uIDI+L2Rldi9udWxsIHwgZ3JlcCAtRWkgJyhWR0F8M0R8RGlzcGxheSkuKk5WSURJQScgfHwgdHJ1ZSkKICAgIFsgLXogIiRncHVzIiBdICYmIHJldHVybiAwCiAgICBpZiBwcmludGYgJyVzXG4nICIkZ3B1cyIgfCBncmVwIC1FcSAnXGIoR0t8R0Z8R1QpWzAtOV17M30nOyB0aGVuIGVjaG8gVE9PX09MRDsgcmV0dXJuIDA7IGZpCiAgICBsb2NhbCBsZWdhY3kgb3RoZXIKICAgIGxlZ2FjeT0kKHByaW50ZiAnJXNcbicgIiRncHVzIiB8IGdyZXAgLUVjICdcYihHTXxHUHxHVilbMC05XXszfScpCiAgICBvdGhlcj0kKHByaW50ZiAnJXNcbicgIiRncHVzIiB8IGdyZXAgLUV2YyAnXGIoR018R1B8R1YpWzAtOV17M30nKSAgICAgIyBhbnl0aGluZyBsc3BjaSBjYW5ub3QgbmFtZSBpcyBuZXdlciB0aGFuIFZvbHRhCiAgICBpZiBbICIkbGVnYWN5IiAtZ3QgMCBdICYmIFsgIiRvdGhlciIgLWd0IDAgXTsgdGhlbiBlY2hvIE1JWEVEOyByZXR1cm4gMDsgZmkKICAgIGlmIFsgIiRsZWdhY3kiIC1ndCAwIF07IHRoZW4gZWNobyAiJExFR0FDWV9EUklWRVJfVkVSU0lPTiAkTEVHQUNZX0RSSVZFUl9QQUNLQUdFIjsgZWxzZSBlY2hvICIkT1BFTl9EUklWRVJfVkVSU0lPTiAkT1BFTl9EUklWRVJfUEFDS0FHRSI7IGZpCn0KCmRyaXZlcl9vaygpIHsgICAjICQxID0gbWluaW11bSB2ZXJzaW9uCiAgICBsb2NhbCB2CiAgICB2PSQobnZpZGlhX3ZlcnNpb24pCiAgICBbIC1uICIkdiIgXSAmJiBkcGtnIC0tY29tcGFyZS12ZXJzaW9ucyAiJHYiIGdlICIkMSIKfQoKbnZpZGlhX2RyaXZlcigpIHsKICAgIGxvY2FsIGNob2ljZSB2ZXIgcGtnCiAgICBjaG9pY2U9JChncHVfZHJpdmVyX2Nob2ljZSkKICAgIGlmIFsgLXogIiRjaG9pY2UiIF07IHRoZW4gc2F5ICJObyBOVklESUEgZ3JhcGhpY3MgY2FyZCB3YXMgZm91bmQuIFNldHVwIGNhbiBjb250aW51ZS4iOyBtYXJrIGRyaXZlcjsgcmV0dXJuIDA7IGZpCiAgICBjYXNlICIkY2hvaWNlIiBpbgogICAgICAgIFRPT19PTEQpIHNheSAiVGhpcyBncmFwaGljcyBjYXJkIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIE5hbHZvIG9yIFZhc3QuIFNldHVwIGNhbiBjb250aW51ZS4iOyBtYXJrIGRyaXZlcjsgcmV0dXJuIDA7OwogICAgICAgIE1JWEVEKSBzdG9wX2hlcmUgIkNvbnRhY3QgTmFsdm8gc3VwcG9ydCBmb3IgaGVscCB3aXRoIHRoZSBncmFwaGljcyBjYXJkcyBpbiB0aGlzIGNvbXB1dGVyLiI7OwogICAgZXNhYwogICAgdmVyPSR7Y2hvaWNlJSAqfTsgcGtnPSR7Y2hvaWNlIyogfQogICAgaWYgZG9uZV8gZHJpdmVyOyB0aGVuCiAgICAgICAgaWYgZHJpdmVyX29rICIkdmVyIjsgdGhlbiBzYXkgIlRoZSBncmFwaGljcyBkcml2ZXIgaXMgcmVhZHkuIjsgcmV0dXJuIDA7IGZpCiAgICAgICAgc2F5ICJHcmFwaGljcyBzZXR1cCBuZWVkcyBhdHRlbnRpb24uIENvbnRpbnVlIHNldHVwLCB0aGVuIGNoZWNrIEZsZWV0IE1hbmFnZXIuIgogICAgICAgIHJldHVybiAwCiAgICBmaQogICAgaWYgbW9rdXRpbCAtLXNiLXN0YXRlIDI+L2Rldi9udWxsIHwgZ3JlcCAtcWkgJ1NlY3VyZUJvb3QgZW5hYmxlZCc7IHRoZW4KICAgICAgICBzdG9wX2hlcmUgIk9wZW4geW91ciBjb21wdXRlcidzIEJJT1Mgc2V0dGluZ3MsIHR1cm4gb2ZmIFNlY3VyZSBCb290LCBhbmQgcmVzdGFydC4iCiAgICBmaQogICAgZHJpdmVyX29rICIkdmVyIiAmJiB7IG1hcmsgZHJpdmVyOyBzYXkgIlRoZSBncmFwaGljcyBkcml2ZXIgaXMgcmVhZHkuIjsgcmV0dXJuIDA7IH0KICAgIHNheSAiUHJlcGFyaW5nIGdyYXBoaWNzLiBQbGVhc2Uga2VlcCB0aGlzIGNvbXB1dGVyIG9uOyB0aGlzIGNhbiB0YWtlIHNldmVyYWwgbWludXRlcy4iCiAgICAjIGZpbmlzaCBhbnkgcGFja2FnZSBydW4gY3V0IHNob3J0IGJ5IGEgcmVzdGFydCBvciBwb3dlciBsb3NzIChkb2VzIG5vdGhpbmcgb24gYSBjbGVhbiBzeXN0ZW0pCiAgICB7IGZvciBfIGluIDEgMiAzIDQgNSA2OyBkbyBkcGtnIC0tY29uZmlndXJlIC1hICYmIGJyZWFrOyBzbGVlcCAyMDsgZG9uZTsgJEFQVCAteSAtZiBpbnN0YWxsOyB9ID4+IiRMT0ciIDI+JjEgXAogICAgICAgIHx8IHN0b3BfaGVyZSAiQ29udGFjdCBOYWx2byBzdXBwb3J0IGZvciBoZWxwIHdpdGggdGhlIGdyYXBoaWNzIHNldHVwLiIKICAgIHsKICAgICAgICAkQVBUIHVwZGF0ZSAmJgogICAgICAgICRBUFQgaW5zdGFsbCAteSAibGludXgtaGVhZGVycy0kKHVuYW1lIC1yKSIgJChkcGtnLXF1ZXJ5IC1XIC1mPScke2RiOlN0YXR1cy1BYmJyZXZ9ICR7UGFja2FnZX0gJHtzb3VyY2U6UGFja2FnZX1cbicgJ2xpbnV4LWltYWdlLSonIDI+L2Rldi9udWxsIHwgYXdrICckMSB+IC9eW2hpXWkvICYmICQzIH4gL15saW51eC1tZXRhLyB7IHN1YigvXmxpbnV4LWltYWdlLShleHRyYS0pPy8sICJsaW51eC1oZWFkZXJzLSIsICQyKTsgcHJpbnQgJDIgfScgfCBzb3J0IC11KSAmJgogICAgICAgICRBUFQgaW5zdGFsbCAteSAkKHNlZCAtbiAnc3xeQ09ORklHX0NDX1ZFUlNJT05fVEVYVD0iKlteIiBdKi1cKGdjYy1bMC05XSpcKSAuKnxcMXxwJyAvbGliL21vZHVsZXMvKi9idWlsZC8uY29uZmlnIHwgc29ydCAtdSkgJiYKICAgICAgICBjdXJsIC1mc1NMIC1vIC90bXAvY3VkYS1rZXlyaW5nLmRlYiAiaHR0cHM6Ly9kZXZlbG9wZXIuZG93bmxvYWQubnZpZGlhLmNvbS9jb21wdXRlL2N1ZGEvcmVwb3MvdWJ1bnR1MjQwNC8kKHVuYW1lIC1tIHwgc2VkICdzL2FhcmNoNjQvc2JzYS8nKS9jdWRhLWtleXJpbmdfMS4xLTFfYWxsLmRlYiIgJiYKICAgICAgICBkcGtnIC1pIC90bXAvY3VkYS1rZXlyaW5nLmRlYiAmJiAkQVBUIHVwZGF0ZQogICAgfSA+PiIkTE9HIiAyPiYxIHx8IHN0b3BfaGVyZSAiQ2hlY2sgdGhlIGludGVybmV0IGNvbm5lY3Rpb24gYW5kIHJlc3RhcnQgdGhpcyBjb21wdXRlci4iCiAgICBpZiBbIC16ICIkKGFwdC1jYWNoZSBwb2xpY3kgIm52aWRpYS1kcml2ZXItcGlubmluZy0kdmVyIiAyPi9kZXYvbnVsbCB8IGdyZXAgQ2FuZGlkYXRlIHwgZ3JlcCAtdiBub25lKSIgXTsgdGhlbgogICAgICAgIHN0b3BfaGVyZSAiQ29udGFjdCBOYWx2byBzdXBwb3J0IGZvciBoZWxwIHdpdGggdGhlIGdyYXBoaWNzIHNldHVwLiIKICAgIGZpCiAgICBsb2NhbCBleHRyYT0iIgogICAgaWYgbHNwY2kgLWQgMTBkZTogLW5uIDI+L2Rldi9udWxsIHwgZ3JlcCAtRXFpICdCcmlkZ2UgXFswNjgwXF0uKk5WU3dpdGNoJzsgdGhlbiAgICAgICAjIEhHWC9ER1ggY2xhc3MgbWFjaGluZXMKICAgICAgICBleHRyYT0ibnZpZGlhLWZhYnJpY21hbmFnZXIgbGlibnZpZGlhLW5zY3EgbnZpZGlhLWltZXgiCiAgICAgICAgWyAiJCh1bmFtZSAtbSkiID0geDg2XzY0IF0gJiYgZXh0cmE9IiRleHRyYSBsaWJudnNkbSIKICAgIGZpCiAgICB7ICRBUFQgaW5zdGFsbCAteSAibnZpZGlhLWRyaXZlci1waW5uaW5nLSR2ZXIiICYmICRBUFQgaW5zdGFsbCAteSAiJHBrZyIgJGV4dHJhOyB9ID4+IiRMT0ciIDI+JjEgXAogICAgICAgIHx8IHN0b3BfaGVyZSAiUmVzdGFydCB0aGlzIGNvbXB1dGVyIHRvIHRyeSB0aGUgZ3JhcGhpY3Mgc2V0dXAgYWdhaW4uIgogICAgWyAtbiAiJGV4dHJhIiBdICYmIHN5c3RlbWN0bCBlbmFibGUgbnZpZGlhLWZhYnJpY21hbmFnZXIuc2VydmljZSA+PiIkTE9HIiAyPiYxCiAgICBsb2NhbCBuZXdlc3QgYnVpbHQKICAgIG5ld2VzdD0kKGxzIC9ib290L3ZtbGludXotKiB8IHNlZCAnc3wuKi92bWxpbnV6LXx8JyB8IHNvcnQgLVYgfCB0YWlsIC0xKQogICAgYnVpbHQ9JChtb2RpbmZvIC1rICIkbmV3ZXN0IiAtRiB2ZXJzaW9uIG52aWRpYSAyPi9kZXYvbnVsbCkKICAgIFsgIiRidWlsdCIgPSAiJHZlciIgXSB8fCB7IGRrbXMgYXV0b2luc3RhbGwgLWsgIiRuZXdlc3QiID4+IiRMT0ciIDI+JjE7IGJ1aWx0PSQobW9kaW5mbyAtayAiJG5ld2VzdCIgLUYgdmVyc2lvbiBudmlkaWEgMj4vZGV2L251bGwpOyB9CiAgICBbICIkYnVpbHQiID0gIiR2ZXIiIF0gfHwgc3RvcF9oZXJlICJDb250YWN0IE5hbHZvIHN1cHBvcnQgZm9yIGhlbHAgd2l0aCB0aGUgZ3JhcGhpY3Mgc2V0dXAuIgogICAgbG9jYWwgaGVsZAogICAgaGVsZD0kKGRwa2ctcXVlcnkgLVcgLWY9JyR7ZGI6U3RhdHVzLUFiYnJldn1cdCR7YmluYXJ5OlBhY2thZ2V9XHQke3NvdXJjZTpQYWNrYWdlfVxuJyB8IGF3ayAtRidcdCcgJyQxIH4gL15baGldaS8gJiYgJDMgfiAvXihudmlkaWEtZ3JhcGhpY3MtZHJpdmVyc3xudmlkaWEta21vZC1vcGVufG52aWRpYS1vcGVufGN1ZGEtZHJpdmVyc3xudmlkaWEtc2V0dGluZ3N8bnZpZGlhLXBlcnNpc3RlbmNlZHxudmlkaWEtbW9kcHJvYmV8bnZpZGlhLXhjb25maWd8KG52aWRpYS0pP2ZhYnJpYy0/bWFuYWdlcnxsaWJudmlkaWEtbnNjcXxsaWJudnNkbXwobnZpZGlhLSk/aW1leHxudmxpbms1fG52aWRpYS1kcml2ZXItcGlubmluZykvIHsgcHJpbnQgJDIgfScpCiAgICB7IFsgLW4gIiRoZWxkIiBdICYmIGFwdC1tYXJrIGhvbGQgJGhlbGQ7IH0gPj4iJExPRyIgMj4mMSB8fCBzdG9wX2hlcmUgIkNvbnRhY3QgTmFsdm8gc3VwcG9ydCBmb3IgaGVscCB3aXRoIHRoZSBncmFwaGljcyBzZXR1cC4iCiAgICBtYXJrIGRyaXZlcgogICAgc2F5ICJHcmFwaGljcyBzZXR1cCBpcyByZWFkeS4gVGhpcyBjb21wdXRlciB3aWxsIHJlc3RhcnQgb25jZS4iCiAgICBzbGVlcCA1CiAgICBzeXN0ZW1jdGwgcmVib290CiAgICBleGl0IDAKfQoKZmV0Y2hfYWdlbnQoKSB7CiAgICBsb2NhbCB3YW50IGdvdAogICAgaW5zdGFsbCAtZCAtbSAwNzU1ICIkQUdFTlRfRElSIgogICAgd2FudD0kKGN1cmwgLWZzUyAtLW1heC10aW1lIDMwICIkRkxFRVQvYWdlbnQvbWFuaWZlc3QuanNvbiIgMj4+IiRMT0ciIHwgcHl0aG9uMyAtSSAtYyAnaW1wb3J0IGpzb24sc3lzOyBwcmludChqc29uLmxvYWQoc3lzLnN0ZGluKVsic2hhMjU2Il0pJyAyPj4iJExPRyIpIFwKICAgICAgICB8fCBzdG9wX2hlcmUgIkNoZWNrIHRoZSBpbnRlcm5ldCBjb25uZWN0aW9uIGFuZCByZXN0YXJ0IHRoaXMgY29tcHV0ZXIuIgogICAgY3VybCAtZnNTIC0tbWF4LXRpbWUgNjAgIiRGTEVFVC9hZ2VudC9uYWx2b19ub2RlLnB5IiAtbyAiJEFHRU5ULnRtcCIgMj4+IiRMT0ciIHx8IHN0b3BfaGVyZSAiQ2hlY2sgdGhlIGludGVybmV0IGNvbm5lY3Rpb24gYW5kIHJlc3RhcnQgdGhpcyBjb21wdXRlci4iCiAgICBnb3Q9JChzaGEyNTZzdW0gIiRBR0VOVC50bXAiIHwgY3V0IC1jMS02NCkKICAgIFsgIiRnb3QiID0gIiR3YW50IiBdIHx8IHsgcm0gLWYgIiRBR0VOVC50bXAiOyBzdG9wX2hlcmUgIkNvbnRhY3QgTmFsdm8gc3VwcG9ydCBmb3IgaGVscCB3aXRoIHNldHVwLiI7IH0KICAgIG12IC1mICIkQUdFTlQudG1wIiAiJEFHRU5UIjsgY2htb2QgMDY0NCAiJEFHRU5UIgp9CgpyZWFkaW5lc3MoKSB7ICAgIyBWYXN0IHJlYWRpbmVzcyBmYWN0cywgcHJpbnRlZCBvbmNlIGFuZCBrZXB0IG9uIHRoZSBtYWNoaW5lICh0aGUgRmxlZXQgTWFuYWdlciB3aWxsIHJlYWQgdGhlbSBpbiBhIGxhdGVyIGFnZW50IHZlcnNpb24pCiAgICBsb2NhbCBzYiBkb2NrZXJfZ2Igcm9vdF9mcmVlIHNzaCBkcnYKICAgIGluc3RhbGwgLWQgLW0gMDcwMCAiJFNUQVRFIgogICAgaW5zdGFsbCAtZCAtbSAwNzU1IC92YXIvbG9nL25hbHZvCiAgICBzYj0kKG1va3V0aWwgLS1zYi1zdGF0ZSAyPi9kZXYvbnVsbCB8IGdyZXAgLXFpICdTZWN1cmVCb290IGVuYWJsZWQnICYmIGVjaG8gb24gfHwgZWNobyBvZmYpCiAgICBkb2NrZXJfZ2I9JCggKG1vdW50cG9pbnQgLXEgL3Zhci9saWIvZG9ja2VyICYmIGRmIC1CRyAtLW91dHB1dD1zaXplIC92YXIvbGliL2RvY2tlciB8IHRhaWwgLTEgfCB0ciAtZGMgMC05KSB8fCBlY2hvIDApCiAgICByb290X2ZyZWU9JChkZiAtQkcgLS1vdXRwdXQ9YXZhaWwgLyB8IHRhaWwgLTEgfCB0ciAtZGMgMC05KQogICAgc3NoPSQoc3NoZF9jZmcgfCBhd2sgJ3RvbG93ZXIoJDEpPT0icGFzc3dvcmRhdXRoZW50aWNhdGlvbiJ7cHJpbnQgJDJ9JykKICAgIGRydj0kKG52aWRpYV92ZXJzaW9uKQogICAgcHJpbnRmICd7InNlY3VyZV9ib290IjoiJXMiLCJkb2NrZXJfc3RvcmFnZV9nYiI6JXMsInJvb3RfZnJlZV9nYiI6JXMsInNzaF9wYXNzd29yZCI6IiVzIiwibnZpZGlhX2RyaXZlciI6IiVzIn1cbicgXAogICAgICAgICIkc2IiICIke2RvY2tlcl9nYjotMH0iICIke3Jvb3RfZnJlZTotMH0iICIke3NzaDotdW5rbm93bn0iICIke2Rydjotbm9uZX0iID4iJFNUQVRFL3JlYWRpbmVzcy5qc29uIgogICAgc2F5ICJUaGUgY29tcHV0ZXIncyBzZXR1cCBkZXRhaWxzIGFyZSBzYXZlZCBmb3IgRmxlZXQgTWFuYWdlci4iCn0KCnBhaXJfYXR0ZW1wdCgpIHsgICAjICQxID0gY29kZSwgcGFzc2VkIG9ubHkgYXMgYW4gYXJndW1lbnQgKG5ldmVyIHByaW50ZWQpLiBSZXR1cm5zIHRoZSBhZ2VudCdzIGV4aXQgY29kZSwKICAgICMgZXhjZXB0IHRoYXQgYSB0ZW1wb3JhcnkgcmVmdXNhbCBieSB0aGUgRmxlZXQgTWFuYWdlciAoNXh4LCBidXN5LCByYXRlIGxpbWl0ZWQpIGNvdW50cyBhcyA1OgogICAgIyAibm90IHJlYWNoYWJsZSByaWdodCBub3csIG91dGNvbWUgdW5rbm93biIsIHNvIGl0IGlzIHJldHJpZWQgbGlrZSBhIG5ldHdvcmsgZmFpbHVyZS4KICAgIGxvY2FsIG91dD0iJFNUQVRFL3BhaXItb3V0cHV0IiByYwogICAgcHl0aG9uMyAtSSAiJEFHRU5UIiBwYWlyIC0tZmxlZXQgIiRGTEVFVCIgLS1jb2RlPSIkMSIgPiIkb3V0IiAyPj4iJExPRyI7IHJjPSQ/CiAgICBjYXQgIiRvdXQiID4+IiRMT0ciIDI+L2Rldi9udWxsCiAgICBpZiBbICIkcmMiID0gNyBdICYmIGdyZXAgLUVxICdecGFpci1lcnJvciAoaHR0cC01WzAtOV1bMC05XXxodHRwLTQyOXxzdG9yYWdlLWJ1c3l8aW50ZXJuYWx8cmF0ZS1saW1pdGVkKSQnICIkb3V0IiAyPi9kZXYvbnVsbDsgdGhlbgogICAgICAgIHJjPTUKICAgIGZpCiAgICBybSAtZiAiJG91dCIKICAgIHJldHVybiAiJHJjIgp9Cgpmb3JnZXRfc3RpY2tfY29kZSgpIHsgcm0gLWYgIiRTVEFURS9wYWlyLWNvZGUiICIkU1RBVEUvcGFpci1jb2RlLXVuc3VyZSI7IH0KCnBhaXJfbm9kZSgpIHsKICAgIGxvY2FsIGNvZGUgbm9ybSByYyBpIGRlbGF5IHVuc3VyZT0wCiAgICBpZiBbIC1mICIkU1RBVEUvcGFpci1jb2RlIiBdOyB0aGVuCiAgICAgICAgY29kZT0kKGNhdCAiJFNUQVRFL3BhaXItY29kZSIpCiAgICAgICAgIyBBbiBlYXJsaWVyIGF0dGVtcHQgKG1heWJlIG9uIGFuIGVhcmxpZXIgYm9vdCkgZW5kZWQgd2l0aCBhbiB1bmtub3duIG91dGNvbWU6CiAgICAgICAgIyB0aGUgRmxlZXQgTWFuYWdlciBtYXkgYWxyZWFkeSBoYXZlIGFjY2VwdGVkIHRoZSBjb2RlIHdpdGhvdXQgdGhpcyBjb21wdXRlcgogICAgICAgICMgcmVjZWl2aW5nIHRoZSBhbnN3ZXIuCiAgICAgICAgWyAtZSAiJFNUQVRFL3BhaXItY29kZS11bnN1cmUiIF0gJiYgdW5zdXJlPTEKICAgICAgICBpZiBbWyAiJGNvZGUiID1+IF5bMC05QS1ISktNTlAtVFYtWl17MjB9JCBdXTsgdGhlbgogICAgICAgICAgICBzYXkgIkNvbm5lY3RpbmcgdGhpcyBjb21wdXRlciB0byB5b3VyIEZsZWV0IE1hbmFnZXIgYXV0b21hdGljYWxseS4uLiIKICAgICAgICAgICAgIyBUaGUgd2FpdHMgYWRkIHVwIHRvIGZpdmUgbWludXRlcy4gQSBuZXR3b3JrIGZhaWx1cmUgaGFzIGFuIHVua25vd24KICAgICAgICAgICAgIyBvdXRjb21lLCBzbyByZXRhaW4gdGhlIGNvZGUgZm9yIHRoZSBuZXh0IGJvb3QgaWYgcmV0cmllcyBydW4gb3V0LgogICAgICAgICAgICBmb3IgZGVsYXkgaW4gNSAxMCAyMCA0MCA2MCA2MCA2MCA0NSAwOyBkbwogICAgICAgICAgICAgICAgcGFpcl9hdHRlbXB0ICIkY29kZSI7IHJjPSQ/CiAgICAgICAgICAgICAgICBjYXNlICIkcmMiIGluCiAgICAgICAgICAgICAgICAgICAgMCkgZm9yZ2V0X3N0aWNrX2NvZGU7IHNheSAiUGFpcmVkIGF1dG9tYXRpY2FsbHkuIFRoaXMgY29tcHV0ZXIgbm93IGFwcGVhcnMgaW4geW91ciBGbGVldCBNYW5hZ2VyOyBjaG9vc2UgTmFsdm8gb3IgVmFzdCB0aGVyZS4iOyByZXR1cm4gMDs7CiAgICAgICAgICAgICAgICAgICAgM3w2KSBmb3JnZXRfc3RpY2tfY29kZQogICAgICAgICAgICAgICAgICAgICAgICAgaWYgWyAiJHJjIiA9IDMgXSAmJiBbICIkdW5zdXJlIiA9IDEgXTsgdGhlbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNheSAiVGhlIGNvbm5lY3Rpb24gZHJvcHBlZCB3aGlsZSB0aGlzIGNvbXB1dGVyIHdhcyBiZWluZyBjb25uZWN0ZWQsIHNvIHRoZSBGbGVldCBNYW5hZ2VyIG1heSBhbHJlYWR5IGxpc3QgaXQgYXMgcGFpcmVkLiBJZiBpdCBkb2VzLCByZW1vdmUgaXQgdGhlcmUsIHRoZW4gZ2V0IGEgbmV3IGNvZGUgYmVsb3cuIgogICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNheSAiVGhlIGNvZGUgb24gdGhlIHN0aWNrIHdhcyBhbHJlYWR5IHVzZWQgb3IgaXMgb2xkZXIgdGhhbiAyNCBob3VyczsgZ2V0IGEgbmV3IGNvZGUgYmVsb3cuIgogICAgICAgICAgICAgICAgICAgICAgICAgZmkKICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOzsKICAgICAgICAgICAgICAgICAgICA0KSBmb3JnZXRfc3RpY2tfY29kZTsgc2F5ICJUaGlzIGNvbXB1dGVyIGlzIGFscmVhZHkgcGFpcmVkIGFzIGFub3RoZXIgbm9kZSBpbiB0aGUgRmxlZXQgTWFuYWdlci4gUmVtb3ZlIHRoYXQgbm9kZSB0aGVyZSBmaXJzdCwgdGhlbiB0eXBlIGEgbmV3IGNvZGUuIjsgYnJlYWs7OwogICAgICAgICAgICAgICAgICAgIDUpIHVuc3VyZT0xCiAgICAgICAgICAgICAgICAgICAgICAgKCB1bWFzayAwNzc7IDogPiIkU1RBVEUvcGFpci1jb2RlLXVuc3VyZSIgKSAyPi9kZXYvbnVsbCAgICMgbm8gY29kZSBpbnNpZGU7IGtlcHQgZm9yIHRoZSBuZXh0IGJvb3QKICAgICAgICAgICAgICAgICAgICAgICBpZiBbICIkZGVsYXkiID0gMCBdOyB0aGVuCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNheSAiVGhlIEZsZWV0IE1hbmFnZXIgY291bGQgbm90IGJlIHJlYWNoZWQuIENoZWNrIHRoZSBjb25uZWN0aW9uIG9yIGVudGVyIGEgY29kZSBiZWxvdzsgdGhlIHN0aWNrIGNvZGUgd2lsbCBiZSBrZXB0IGZvciB0aGUgbmV4dCBib290LiIKICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgICAgICAgICBmaQogICAgICAgICAgICAgICAgICAgICAgIHNsZWVwICIkZGVsYXkiOzsKICAgICAgICAgICAgICAgICAgICAqKSBwcmludGYgJ0F1dG9tYXRpYyBwYWlyaW5nIHN0b3BwZWQgd2l0aCBzdGF0dXMgJXNcbicgIiRyYyIgPj4iJExPRyI7IHNheSAiRW50ZXIgYSBuZXcgY29kZSBiZWxvdyB0byBjb25uZWN0IHRoaXMgY29tcHV0ZXIuIjsgYnJlYWs7OwogICAgICAgICAgICAgICAgZXNhYwogICAgICAgICAgICBkb25lCiAgICAgICAgZWxzZQogICAgICAgICAgICBmb3JnZXRfc3RpY2tfY29kZQogICAgICAgICAgICBzYXkgIlRoZSBjb2RlIG9uIHRoZSBzdGljayBpcyBpbnZhbGlkOyBnZXQgYSBuZXcgY29kZSBiZWxvdy4iCiAgICAgICAgZmkKICAgICAgICB1bnNldCBjb2RlCiAgICBmaQogICAgZm9yIGkgaW4gMSAyIDMgNCA1OyBkbwogICAgICAgIHNheSAiIgogICAgICAgIHNheSAiQ29ubmVjdCB0aGlzIGNvbXB1dGVyIHRvIHlvdXIgRmxlZXQgTWFuYWdlci4iCiAgICAgICAgc2F5ICIgIDEuIE9uIHlvdXIgcGhvbmUgb3BlbiAkRkxFRVQgYW5kIHNpZ24gaW4uIgogICAgICAgIHNheSAiICAyLiBUYXAgJysgQWRkIGEgY29tcHV0ZXInLCBuYW1lIGl0LCB0YXAgJ0dldCBhIHBhaXJpbmcgY29tbWFuZCcuIgogICAgICAgIHNheSAiICAzLiBUeXBlIHRoZSAnaW5zdGFsbGVyIGNvZGUnIHNob3duIHRoZXJlIChsZXR0ZXJzIGFuZCBudW1iZXJzOyBkYXNoZXMgYW5kIGNhcGl0YWxzIG9wdGlvbmFsKS4iCiAgICAgICAgcHJpbnRmICdJbnN0YWxsZXIgY29kZTogJwogICAgICAgIHJlYWQgLWUgLXIgY29kZSB8fCBjb2RlPSIiCiAgICAgICAgbm9ybT0kKHByaW50ZiAnJXMnICIkY29kZSIgfCB0ciAtY2QgJ0EtWmEtejAtOV8tJykKICAgICAgICBbIC16ICIkbm9ybSIgXSAmJiBjb250aW51ZQogICAgICAgIHBhaXJfYXR0ZW1wdCAiJG5vcm0iOyByYz0kPwogICAgICAgIGNhc2UgIiRyYyIgaW4KICAgICAgICAgICAgMCkgZm9yZ2V0X3N0aWNrX2NvZGU7IHNheSAiUGFpcmVkLiBUaGlzIGNvbXB1dGVyIG5vdyBhcHBlYXJzIGluIHlvdXIgRmxlZXQgTWFuYWdlcjsgY2hvb3NlIE5hbHZvIG9yIFZhc3QgdGhlcmUuIjsgcmV0dXJuIDA7OwogICAgICAgICAgICAzKSBzYXkgIlRoYXQgY29kZSB3YXMgbm90IGFjY2VwdGVkOiBtaXN0eXBlZCwgYWxyZWFkeSB1c2VkLCBvciBvbGRlciB0aGFuIDE1IG1pbnV0ZXMuIENoZWNrIGl0IGFuZCB0eXBlIGl0IGFnYWluLCBvciBnZXQgYSBuZXcgb25lLiI7OwogICAgICAgICAgICA0KSBzYXkgIlRoaXMgY29tcHV0ZXIgaXMgYWxyZWFkeSBwYWlyZWQgYXMgYW5vdGhlciBub2RlIGluIHRoZSBGbGVldCBNYW5hZ2VyLiBSZW1vdmUgdGhhdCBub2RlIHRoZXJlIGZpcnN0LCB0aGVuIHR5cGUgYSBuZXcgY29kZS4iOzsKICAgICAgICAgICAgNSkgc2F5ICJUaGUgRmxlZXQgTWFuYWdlciBjb3VsZCBub3QgYmUgcmVhY2hlZCB3aGlsZSBwYWlyaW5nLiBDaGVjayB0aGUgaW50ZXJuZXQgY29ubmVjdGlvbjsgaWYgdGhlIGNvbXB1dGVyIGFscmVhZHkgYXBwZWFycyBpbiB5b3VyIEZsZWV0IE1hbmFnZXIsIHJlc3RhcnQgaXQgaW5zdGVhZCBvZiBwYWlyaW5nIGFnYWluLiI7OwogICAgICAgICAgICA2KSBzYXkgIlRoaXMgbm9kZSB3YXMgcmV2b2tlZCBpbiB0aGUgRmxlZXQgTWFuYWdlci4gR2V0IGEgbmV3IGNvZGUgZm9yIGEgbmV3IG5vZGUuIjs7CiAgICAgICAgICAgICopIHByaW50ZiAnUGFpcmluZyBzdG9wcGVkIHdpdGggc3RhdHVzICVzXG4nICIkcmMiID4+IiRMT0ciOyBzYXkgIlBsZWFzZSB0cnkgdGhlIGNvZGUgYWdhaW4uIjs7CiAgICAgICAgZXNhYwogICAgZG9uZQogICAgc3RvcF9oZXJlICJSZXN0YXJ0IHRoaXMgY29tcHV0ZXIgdG8gdHJ5IGNvbm5lY3RpbmcgYWdhaW4uIgp9Cgpsb2NrX2NvbnNvbGUoKSB7CiAgICAjIE5vIGNvbnNvbGUgcGFzc3dvcmQgaXMgY3JlYXRlZCBhbnkgbW9yZS4gVGhlIGxvY2sgZW5kcyB0aGUgb25seSBwYXNzd29yZAogICAgIyB0aGlzIGNvbXB1dGVyIGV2ZXIgaGFkOiBHUlVCIHJlY292ZXJ5IG9mZiwgZXZlcnkgbWVudSBlbnRyeSB1bnJlc3RyaWN0ZWQsCiAgICAjIGFuZCB0aGUgbmFsdm8gYWNjb3VudCBnaXZlbiBhbiB1bmtub3dhYmxlIHBhc3N3b3JkLiBUaGUgb3duZXIgc2V0cyBoaXMgb3duCiAgICAjIGZyb20gdGhlIGNvbXB1dGVyJ3MgY2FyZCAoam9iIG5vZGUuYWNjZXNzKS4gT25lIHNvdXJjZSwgcnVuIGJ5IGZpcnN0IGJvb3QKICAgICMgaGVyZSBhbmQgYnkgdGhlIGFnZW50J3MgY29uc29sZV9sb2NrX3RpY2sgb24gaW5zdGFsbGVkIG5vZGVzLiBGYWlsLW9wZW46IGEKICAgICMgY29tcHV0ZXIgbmV2ZXIgd2FpdHMgYXQgYSBwYXNzd29yZCBwcm9tcHQgYmVjYXVzZSBvZiBpdC4KICAgIGRvbmVfIGNvbnNvbGUtbG9jayAmJiByZXR1cm4gMAogICAgcHl0aG9uMyAtSSAiJEFHRU5UIiBjb25zb2xlLWxvY2stYXBwbHkgPj4iJExPRyIgMj4mMSB8fCB0cnVlCiAgICBtYXJrIGNvbnNvbGUtbG9jayB8fCByZXR1cm4gMQp9CgpmaW5pc2hfc2V0dXAoKSB7CiAgICAjIFRoZSBtYXJrZXIgbXVzdCBwcmVjZWRlIHVubWFza2luZywgaW5jbHVkaW5nIGFmdGVyIGFuIGludGVycnVwdGVkIGZpbmlzaC4KICAgIG1hcmsgZG9uZSB8fCByZXR1cm4gMQogICAgc3lzdGVtY3RsIHVubWFzayBnZXR0eUB0dHkxLnNlcnZpY2UgPj4iJExPRyIgMj4mMSB8fCByZXR1cm4gMQogICAgc3lzdGVtY3RsIGRpc2FibGUgbmFsdm8tZmlyc3Rib290LnNlcnZpY2UgPj4iJExPRyIgMj4mMSB8fCByZXR1cm4gMQogICAgc3lzdGVtY3RsIC0tbm8tYmxvY2sgc3RhcnQgZ2V0dHlAdHR5MS5zZXJ2aWNlID4+IiRMT0ciIDI+JjEgfHwgcmV0dXJuIDEKfQoKdmFzdGhlbHBlcigpIHsKICAgIGRvbmVfIHZhc3RoZWxwZXIgJiYgcmV0dXJuIDAKICAgICMgVGhlc2UgYXNzZXRzIGNhbWUgZnJvbSB0aGUgcmV2aWV3ZWQsIHNlbGYtY29udGFpbmVkIGluc3RhbGxhdGlvbiBpbWFnZSwKICAgICMgdGhlIHJlbGVhc2Ugc2lnbmVyIHRvbyAoaW5zdGFsbGVyL25hbHZvLXJlbGVhc2UuYWxsb3dlZF9zaWduZXJzKS4gV2hpbGUKICAgICMgaXQgc3RpbGwgaG9sZHMgdGhlIHBsYWNlaG9sZGVyLCBzaWduYXR1cmUgdmVyaWZpY2F0aW9uIGZhaWxzIGNsb3NlZC4KICAgIGxvY2FsIHNyYz0vdXNyL2xvY2FsL3NoYXJlL25hbHZvLXZhc3QKICAgIGluc3RhbGwgLWQgLW0gMDc1NSAtbyByb290IC1nIHJvb3QgL3Vzci9sb2NhbC9saWIvbmFsdm8gL2V0Yy9uYWx2by12YXN0IHx8IHJldHVybiAxCiAgICBpbnN0YWxsIC1kIC1tIDA3MDAgLW8gcm9vdCAtZyByb290IC92YXIvbGliL25hbHZvLXZhc3QgfHwgcmV0dXJuIDEKICAgICMgQ3JlYXRlIHRoZSB3YXRjaGVkIHBhcmVudCBiZWZvcmUgZW5hYmxpbmcgdGhlIHBhdGggdW5pdCwgZXZlbiBiZWZvcmUgcGFpcmluZy4KICAgIGluc3RhbGwgLWQgLW0gMDcwMCAtbyByb290IC1nIHJvb3QgL3Zhci9saWIvbmFsdm8tbm9kZSAvdmFyL2xpYi9uYWx2by1ub2RlL3Zhc3QgfHwgcmV0dXJuIDEKICAgIGluc3RhbGwgLW0gMDc1NSAtbyByb290IC1nIHJvb3QgIiRzcmMvbmFsdm8tdmFzdC1oZWxwZXIucHkiIC91c3IvbG9jYWwvbGliL25hbHZvL25hbHZvLXZhc3QtaGVscGVyLnB5IHx8IHJldHVybiAxCiAgICBpbnN0YWxsIC1tIDA2NDQgLW8gcm9vdCAtZyByb290ICIkc3JjL25hbHZvLXZhc3QtaGVscGVyLnBhdGgiIC9ldGMvc3lzdGVtZC9zeXN0ZW0vbmFsdm8tdmFzdC1oZWxwZXIucGF0aCB8fCByZXR1cm4gMQogICAgaW5zdGFsbCAtbSAwNjQ0IC1vIHJvb3QgLWcgcm9vdCAiJHNyYy9uYWx2by12YXN0LWhlbHBlci5zZXJ2aWNlIiAvZXRjL3N5c3RlbWQvc3lzdGVtL25hbHZvLXZhc3QtaGVscGVyLnNlcnZpY2UgfHwgcmV0dXJuIDEKICAgIGluc3RhbGwgLW0gMDY0NCAtbyByb290IC1nIHJvb3QgIiRzcmMvYWxsb3dlZF9zaWduZXJzIiAvZXRjL25hbHZvLXZhc3QvYWxsb3dlZF9zaWduZXJzIHx8IHJldHVybiAxCiAgICBzeXN0ZW1jdGwgZGFlbW9uLXJlbG9hZCB8fCByZXR1cm4gMQogICAgc3lzdGVtY3RsIGVuYWJsZSAtLW5vdyBuYWx2by12YXN0LWhlbHBlci5wYXRoIHx8IHJldHVybiAxCiAgICBtYXJrIHZhc3RoZWxwZXIKfQoKcnVuKCkgewogICAgaW5zdGFsbCAtZCAtbSAwNzAwICIkU1RBVEUiCiAgICBpbnN0YWxsIC1kIC1tIDA3NTUgL3Zhci9sb2cvbmFsdm8KICAgIGV4ZWMgOT4iJExPQ0siOyBmbG9jayAtbiA5IHx8IGV4aXQgMAogICAgaWYgZG9uZV8gZG9uZTsgdGhlbiBmaW5pc2hfc2V0dXA7IGV4aXQgJD87IGZpCiAgICAjIE5vIGNvbW1hbmQgZGlhZ25vc3RpY3Mgc2hvdWxkIHJlYWNoIHRoZSBzZXR1cCBzY3JlZW4uCiAgICBleGVjIDI+PiIkTE9HIgogICAgZG1lc2cgLW4gMSA+PiIkTE9HIiAyPiYxIHx8IHRydWUKICAgIGNsZWFyIDI+L2Rldi9udWxsIHx8IHRydWUKICAgIHN0ZXAgMSAiQ2hlY2sgdGhlIGNvbXB1dGVyIgogICAgc2hvd19pbnN0YWxsX2d1aWRlCiAgICBndWFyZF9pbnN0YWxsZWRfc3lzdGVtCiAgICBHVUFSRF9PSz0xCiAgICBpZiBbIC1mICIkU1RBVEUvd2lmaS1kcml2ZXItbWlzc2luZyIgXTsgdGhlbgogICAgICAgIHNheSAiVGhpcyBjb21wdXRlcidzIFdpLUZpIG5lZWRzIGEgZHJpdmVyIHRoYXQgd2FzIG5vdCBvbiB0aGUgc3RpY2suIFBsdWcgaW4gYW4gRXRoZXJuZXQgY2FibGUgZm9yIHNldHVwOyBOYWx2byB3aWxsIGFkZCBXaS1GaSBzdXBwb3J0IGFmdGVyd2FyZHMuIgogICAgZmkKICAgIGlmIGRvbmVfIGZpbmlzaGVkOyB0aGVuCiAgICAgICAgIyBFdmVyeXRoaW5nIHdhcyBzZXQgdXAgb24gYW4gZWFybGllciBib290OyBjb21wbGV0ZSB0aGUgaGFuZG9mZi4KICAgICAgICBzYXkgIlNldHVwIGZpbmlzaGVkLiBZb3UgY2FuIGxlYXZlIHRoaXMgY29tcHV0ZXIgcnVubmluZy4iCiAgICAgICAgZmluaXNoX3NldHVwCiAgICAgICAgZXhpdCAwCiAgICBmaQogICAgc3RlcCAyICJDb25uZWN0IHRvIHRoZSBpbnRlcm5ldCIKICAgIHdhaXRfZm9yX2Nsb2NrCiAgICB3YWl0X25ldHdvcmsKICAgICMgUGFpciBhcyBzb29uIGFzIHRoZXJlIGlzIGludGVybmV0LCBzbyB0aGUgY29tcHV0ZXIgYXBwZWFycyBpbiB0aGUgRmxlZXQgTWFuYWdlcgogICAgIyByaWdodCBhd2F5IGFuZCB0aGUgb3duZXIgY2FuIGZvbGxvdyB0aGUgcmVtYWluaW5nIHN0ZXBzIHRoZXJlLgogICAgc3RlcCAzICJDb25uZWN0IHRvIEZsZWV0IE1hbmFnZXIiCiAgICBpZiBbICEgLWUgL3Zhci9saWIvbmFsdm8tbm9kZS9jb25maWcuanNvbiBdOyB0aGVuCiAgICAgICAgZmV0Y2hfYWdlbnQKICAgICAgICBwYWlyX25vZGUKICAgIGZpCiAgICBzdGVwIDQgIlByZXBhcmUgdGhlIGNvbXB1dGVyIgogICAgaHlnaWVuZQogICAgdmFzdGhlbHBlciA+PiIkTE9HIiAyPiYxIHx8IHN0b3BfaGVyZSAiUmVzdGFydCB0aGlzIGNvbXB1dGVyIHRvIHRyeSBhZ2Fpbi4iCiAgICBkb2NrZXJfc3RvcmFnZQogICAgc3RlcCA1ICJQcmVwYXJlIGdyYXBoaWNzIgogICAgbnZpZGlhX2RyaXZlcgogICAgcmVhZGluZXNzCiAgICBzdGVwIDYgIkZpbmlzaCBzZXR1cCIKICAgIGxvY2tfY29uc29sZSB8fCBzdG9wX2hlcmUgIlJlc3RhcnQgdGhpcyBjb21wdXRlciB0byB0cnkgYWdhaW4uIgogICAgbWFyayBmaW5pc2hlZAogICAgc2F5ICJTZXR1cCBmaW5pc2hlZC4gWW91IGNhbiBsZWF2ZSB0aGlzIGNvbXB1dGVyIHJ1bm5pbmcuIgogICAgZmluaXNoX3NldHVwCn0KCmNhc2UgIiR7MTotfSIgaW4KICAgIGluc3RhbGwpIGluc3RhbGxfdW5pdCA7OwogICAgcnVuKSBydW4gOzsKICAgIHJlYWRpbmVzcykgcmVhZGluZXNzIDs7CiAgICAqKSBlY2hvICJ1c2FnZTogJDAgaW5zdGFsbHxydW58cmVhZGluZXNzIiA+JjI7IGV4aXQgMiA7Owplc2FjCg== #NALVO-EARLY-B64:IyEvYmluL2Jhc2gKIyBQcmVwYXJlIGlkZW50aXR5IGFuZCwgb25seSBmb3IgYSBzaW5nbGUgZW1wdHkgaW50ZXJuYWwgZGlzaywgc3RvcmFnZS4KIyBUaGlzIHJ1bnMgaW4gdGhlIFVidW50dSBsaXZlIGluc3RhbGxlciBiZWZvcmUgU3ViaXF1aXR5IHByb2JlcyBzdG9yYWdlLgojIEl0IG5ldmVyIHdyaXRlcyB0byBhIGJsb2NrIGRldmljZS4gQWxsIHByb2JlIGZhaWx1cmVzIGxlYXZlIHN0b3JhZ2UgaW50ZXJhY3RpdmUuCnNldCAtdQoKc2hvd19pbnN0YWxsX2d1aWRlKCkgewogICAgbG9jYWwgdXJsPSdodHRwczovL2ZsZWV0Lm5hbHZvLmFpL2luc3RhbGwtZ3VpZGUuaHRtbCcKICAgIHByaW50ZiAnTmFsdm8gbm9kZSBzZXR1cCAtIHN0ZXAgMSBvZiA2OiBQcmVwYXJlIHRoZSBjb21wdXRlclxuJwogICAgcHJpbnRmICdGb2xsb3cgdGhlIGluc3RhbGxhdGlvbiBvbiB5b3VyIHBob25lOiAlc1xuJyAiJHVybCIKICAgIFBZVEhPTklPRU5DT0RJTkc9dXRmLTggcHl0aG9uMyAtSSAtIC9ydW4vbmFsdm8tcXIucHkgIiR1cmwiIDI+L2Rldi9udWxsIDw8J1BZJyB8fCB0cnVlCmltcG9ydCBydW5weSwgc3lzCm1hdHJpeCA9IHJ1bnB5LnJ1bl9wYXRoKHN5cy5hcmd2WzFdKVsiZW5jb2RlIl0oc3lzLmFyZ3ZbMl0uZW5jb2RlKCJ1dGYtOCIpKQp3aWR0aCA9IGxlbihtYXRyaXgpICsgOApyb3dzID0gW1tGYWxzZV0gKiB3aWR0aCBmb3IgXyBpbiByYW5nZSg0KV0Kcm93cyArPSBbW0ZhbHNlXSAqIDQgKyByb3cgKyBbRmFsc2VdICogNCBmb3Igcm93IGluIG1hdHJpeF0Kcm93cyArPSBbW0ZhbHNlXSAqIHdpZHRoIGZvciBfIGluIHJhbmdlKDQpXQppZiBsZW4ocm93cykgJSAyOgogICAgcm93cy5hcHBlbmQoW0ZhbHNlXSAqIHdpZHRoKQpibG9ja3MgPSAoIiAiLCAiXHUyNTg0IiwgIlx1MjU4MCIsICJcdTI1ODgiKQpsaW5lcyA9IFsiIi5qb2luKGJsb2Nrc1syICogYSArIGJdIGZvciBhLCBiIGluIHppcChyb3dzW3ldLCByb3dzW3kgKyAxXSkpCiAgICAgICAgIGZvciB5IGluIHJhbmdlKDAsIGxlbihyb3dzKSwgMildCnN5cy5zdGRvdXQuYnVmZmVyLndyaXRlKCgiXDAzM1szMDs0N20iICsgIlxuIi5qb2luKGxpbmVzKSArICJcMDMzWzBtXG4iKS5lbmNvZGUoInV0Zi04IikpClBZCn0KCiMgQSBmYWlsZWQgZGVjb2RlciBvciBtaXNzaW5nIGNvbnNvbGUgbmV2ZXIgcHJldmVudHMgdGhlIGluc3RhbGxlciBmcm9tIGNvbnRpbnVpbmcuCnNlZCAtbiAncy9eI05BTFZPLVFSLUI2NDovL3AnIC9jZHJvbS9hdXRvaW5zdGFsbC55YW1sIHwgYmFzZTY0IC1kID4gL3J1bi9uYWx2by1xci5weSAyPi9kZXYvbnVsbCB8fCB0cnVlCnNob3duPTAKZm9yIHRlcm1pbmFsIGluIC9kZXYvY29uc29sZSAvZGV2L3R0eTE7IGRvCiAgICBpZiAoIFsgLXQgMSBdICkgPiIkdGVybWluYWwiIDI+L2Rldi9udWxsOyB0aGVuCiAgICAgICAgc2hvd19pbnN0YWxsX2d1aWRlID4iJHRlcm1pbmFsIiAyPi9kZXYvbnVsbCB8fCB0cnVlCiAgICAgICAgc2hvd249MQogICAgZmkKZG9uZQppZiBbICIkc2hvd24iID0gMSBdOyB0aGVuIHNsZWVwIDE1IHx8IHRydWU7IGZpCgpweXRob24zIC0gPj4iJHtOQUxWT19FQVJMWV9MT0c6LS92YXIvbG9nL25hbHZvLWVhcmx5LmxvZ30iIDI+JjEgPDwnUFknIHx8IHRydWUKaW1wb3J0IGpzb24KaW1wb3J0IGhhc2hsaWIKaW1wb3J0IGhtYWMKaW1wb3J0IG9zCmltcG9ydCByZQppbXBvcnQgc2VjcmV0cwppbXBvcnQgc3VicHJvY2VzcwppbXBvcnQgdGVtcGZpbGUKaW1wb3J0IGdsb2IKaW1wb3J0IHNodXRpbAppbXBvcnQgdGltZQoKaW1wb3J0IHlhbWwKCmNvbmZpZ19wYXRoID0gb3MuZW52aXJvbi5nZXQoIk5BTFZPX0VBUkxZX0NPTkZJRyIsICIvYXV0b2luc3RhbGwueWFtbCIpCnNvdXJjZV9wYXRoID0gb3MuZW52aXJvbi5nZXQoIk5BTFZPX0VBUkxZX1NPVVJDRSIsICIvY2Ryb20vYXV0b2luc3RhbGwueWFtbCIpCmxvZ19wYXRoID0gb3MuZW52aXJvbi5nZXQoIk5BTFZPX0VBUkxZX0xPRyIsICIvdmFyL2xvZy9uYWx2by1lYXJseS5sb2ciKQp3aWZpX3BhdGggPSBvcy5lbnZpcm9uLmdldCgiTkFMVk9fRUFSTFlfV0lGSSIsICIvY2Ryb20vbmFsdm8td2lmaS5qc29uLmVuYyIpCnN5c19uZXQgPSBvcy5lbnZpcm9uLmdldCgiTkFMVk9fRUFSTFlfU1lTX05FVCIsICIvc3lzL2NsYXNzL25ldCIpCndpZmlfb3V0cHV0ID0gb3MuZW52aXJvbi5nZXQoIk5BTFZPX0VBUkxZX1dJRklfT1VUUFVUIiwgIi9ydW4vbmFsdm8td2lmaS55YW1sIikKd2lmaV9tYXJrZXIgPSBvcy5lbnZpcm9uLmdldCgiTkFMVk9fRUFSTFlfV0lGSV9NQVJLRVIiLCAiL3J1bi9uYWx2by13aWZpLWRyaXZlci1taXNzaW5nIikKcGNpX3BhdGggPSBvcy5lbnZpcm9uLmdldCgiTkFMVk9fRUFSTFlfUENJIiwgIi9zeXMvYnVzL3BjaS9kZXZpY2VzIikKZmlybXdhcmVfc291cmNlID0gb3MuZW52aXJvbi5nZXQoIk5BTFZPX0VBUkxZX0ZJUk1XQVJFIiwgIi9jZHJvbS9uYWx2by9maXJtd2FyZS9ydHc4OSIpCmZpcm13YXJlX3RhcmdldCA9IG9zLmVudmlyb24uZ2V0KCJOQUxWT19FQVJMWV9GSVJNV0FSRV9UQVJHRVQiLCAiL2xpYi9maXJtd2FyZS9ydHc4OSIpCgoKZGVmIGxvZyhtZXNzYWdlKToKICAgICMgTmV2ZXIgbG9nIHRoZSBjb25maWd1cmF0aW9uLCBzdWJwcm9jZXNzIG91dHB1dCwgb3Igc3VwcGxpZWQgbWFya2VyIHZhbHVlcy4KICAgIHRyeToKICAgICAgICB3aXRoIG9wZW4obG9nX3BhdGgsICJhIiwgZW5jb2Rpbmc9InV0Zi04IikgYXMgb3V0OgogICAgICAgICAgICBvdXQud3JpdGUobWVzc2FnZSArICJcbiIpCiAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICBwYXNzCgoKZGVmIHNhdmUoZGF0YSk6CiAgICAjIEEgY29tcGxldGUgc2VyaWFsaXplZCBkb2N1bWVudCBpcyBzd2FwcGVkIGluIG9ubHkgYWZ0ZXIgaXQgaXMgd3JpdHRlbi4KICAgIGRpcmVjdG9yeSA9IG9zLnBhdGguZGlybmFtZShvcy5wYXRoLmFic3BhdGgoY29uZmlnX3BhdGgpKQogICAgZmQsIHRlbXAgPSB0ZW1wZmlsZS5ta3N0ZW1wKHByZWZpeD0iLm5hbHZvLWF1dG9pbnN0YWxsLSIsIGRpcj1kaXJlY3RvcnkpCiAgICB0cnk6CiAgICAgICAgd2l0aCBvcy5mZG9wZW4oZmQsICJ3IiwgZW5jb2Rpbmc9InV0Zi04IiwgbmV3bGluZT0iXG4iKSBhcyBvdXQ6CiAgICAgICAgICAgIHlhbWwuc2FmZV9kdW1wKGRhdGEsIG91dCwgc29ydF9rZXlzPUZhbHNlLCBhbGxvd191bmljb2RlPVRydWUpCiAgICAgICAgb3MucmVwbGFjZSh0ZW1wLCBjb25maWdfcGF0aCkKICAgIGZpbmFsbHk6CiAgICAgICAgaWYgb3MucGF0aC5leGlzdHModGVtcCk6CiAgICAgICAgICAgIG9zLnVubGluayh0ZW1wKQoKCmRlZiBjb21tYW5kKGFyZ3MpOgogICAgcmV0dXJuIHN1YnByb2Nlc3MucnVuKGFyZ3MsIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHN0ZGVycj1zdWJwcm9jZXNzLkRFVk5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dD1UcnVlLCBjaGVjaz1GYWxzZSkKCgpkZWYgd2lyZWxlc3NfZGV2aWNlX3dpdGhvdXRfaW50ZXJmYWNlKCk6CiAgICAjIFBDSSBuZXR3b3JrLW90aGVyIGNsYXNzIDAyODAgYW5kIFVTQiB3aXJlbGVzcy1jb250cm9sbGVyIGNsYXNzIGUwLgogICAgIyBUaGUgcHJpbnRlZCBuYW1lIGlzIGhhcmR3YXJlIG1ldGFkYXRhLCBuZXZlciBjb25maWd1cmF0aW9uIG9yIGEgc2VjcmV0LgogICAgdHJ5OgogICAgICAgIHBjaSA9IGNvbW1hbmQoWyJsc3BjaSIsICItbm4iLCAiLWQiLCAiOjowMjgwIl0pCiAgICAgICAgaWYgcGNpLnJldHVybmNvZGUgPT0gMCBhbmQgcGNpLnN0ZG91dC5zdHJpcCgpOgogICAgICAgICAgICByZXR1cm4gcGNpLnN0ZG91dC5zcGxpdGxpbmVzKClbMF1bOjIwMF0KICAgIGV4Y2VwdCBPU0Vycm9yOgogICAgICAgIHBhc3MKICAgIHRyeToKICAgICAgICB1c2IgPSBjb21tYW5kKFsibHN1c2IiLCAiLXYiXSkKICAgICAgICBibG9ja3MgPSByZS5zcGxpdChyIig/PV5CdXMgXGQrIERldmljZSBcZCs6KSIsIHVzYi5zdGRvdXQsIGZsYWdzPXJlLk1VTFRJTElORSkKICAgICAgICBmb3IgYmxvY2sgaW4gYmxvY2tzOgogICAgICAgICAgICBpZiByZS5zZWFyY2gociJeXHMqYig/OkRldmljZXxJbnRlcmZhY2UpQ2xhc3NccysyMjRcYiIsIGJsb2NrLCByZS5NVUxUSUxJTkUpOgogICAgICAgICAgICAgICAgcmV0dXJuIGJsb2NrLnNwbGl0bGluZXMoKVswXVs6MjAwXQogICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgcGFzcwogICAgcmV0dXJuIE5vbmUKCgojIFBDSSBJRHMgZnJvbSB0aGUgdXBzdHJlYW0gZHJpdmVyczsgSW50ZWwgZG9jdW1lbnRzIEJFMjAwIGFzIDgwODY6MjcyYjoKIyBodHRwczovL2dpdGh1Yi5jb20vdG9ydmFsZHMvbGludXgvdHJlZS9tYXN0ZXIvZHJpdmVycy9uZXQvd2lyZWxlc3MKIyBodHRwczovL2dpdGh1Yi5jb20vaW50ZWwvSW50ZWwtd2lyZWxlc3MvYmxvYi9tYWluL2RvY3MvYnVpbGQvaW5kZXgubWQKV0lGSV9QQ0lfRFJJVkVSUyA9IHsKICAgICgiMTBlYyIsICI4OTIyIik6ICJydHc4OV84OTIyYWUiLAogICAgKCIxMGVjIiwgIjg4NTIiKTogInJ0dzg5Xzg4NTJhZSIsCiAgICAoIjEwZWMiLCAiYjg1MiIpOiAicnR3ODlfODg1MmJlIiwKICAgICgiMTBlYyIsICJjODUyIik6ICJydHc4OV84ODUyY2UiLAogICAgKCIxNGMzIiwgIjc5MjUiKTogIm10NzkyNWUiLAogICAgKCI4MDg2IiwgIjI3MmIiKTogIml3bHdpZmkiLAp9CgoKZGVmIHJlY292ZXJfa25vd25fd2lmaSgpOgogICAgIiIiQWRkIHN0aWNrIGZpcm13YXJlIGJlZm9yZSBwcm9iaW5nOyBuZXZlciBkaXN0dXJiIGFuIGFscmVhZHkgd29ya2luZyBjYXJkLiIiIgogICAgZm9yIGRldmljZSBpbiBzb3J0ZWQoZ2xvYi5nbG9iKG9zLnBhdGguam9pbihwY2lfcGF0aCwgIioiKSkpOgogICAgICAgIHRyeToKICAgICAgICAgICAgd2l0aCBvcGVuKG9zLnBhdGguam9pbihkZXZpY2UsICJ2ZW5kb3IiKSwgZW5jb2Rpbmc9ImFzY2lpIikgYXMgc3JjOgogICAgICAgICAgICAgICAgdmVuZG9yID0gc3JjLnJlYWQoKS5zdHJpcCgpLmxvd2VyKCkucmVtb3ZlcHJlZml4KCIweCIpCiAgICAgICAgICAgIHdpdGggb3Blbihvcy5wYXRoLmpvaW4oZGV2aWNlLCAiZGV2aWNlIiksIGVuY29kaW5nPSJhc2NpaSIpIGFzIHNyYzoKICAgICAgICAgICAgICAgIHByb2R1Y3QgPSBzcmMucmVhZCgpLnN0cmlwKCkubG93ZXIoKS5yZW1vdmVwcmVmaXgoIjB4IikKICAgICAgICAgICAgbW9kdWxlID0gV0lGSV9QQ0lfRFJJVkVSUy5nZXQoKHZlbmRvciwgcHJvZHVjdCkpCiAgICAgICAgICAgIGlmIG5vdCBtb2R1bGUgb3IgZ2xvYi5nbG9iKG9zLnBhdGguam9pbihkZXZpY2UsICJuZXQiLCAiKiIsICJ3aXJlbGVzcyIpKToKICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIGlmIHZlbmRvciA9PSAiMTBlYyI6CiAgICAgICAgICAgICAgICBmaWxlcyA9IHNvcnRlZCgoZ2xvYi5nbG9iKG9zLnBhdGguam9pbihmaXJtd2FyZV9zb3VyY2UsICJydHcqLmJpbiIpKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2xvYi5nbG9iKG9zLnBhdGguam9pbihmaXJtd2FyZV9zb3VyY2UsICJydHcqLmJpbi56c3QiKSkpKQogICAgICAgICAgICAgICAgaWYgbm90IGZpbGVzOgogICAgICAgICAgICAgICAgICAgIGxvZygiS25vd24gUmVhbHRlayBXaS1GaSBhZGFwdGVyIGhhcyBubyBmaXJtd2FyZSBvbiB0aGUgc3RpY2suIikKICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICAgICAgb3MubWFrZWRpcnMoZmlybXdhcmVfdGFyZ2V0LCBtb2RlPTBvNzU1LCBleGlzdF9vaz1UcnVlKQogICAgICAgICAgICAgICAgZm9yIHNvdXJjZSBpbiBmaWxlczoKICAgICAgICAgICAgICAgICAgICBpZiBvcy5wYXRoLmlzZmlsZShzb3VyY2UpOgogICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQgPSBvcy5wYXRoLmpvaW4oZmlybXdhcmVfdGFyZ2V0LCBvcy5wYXRoLmJhc2VuYW1lKHNvdXJjZSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHNodXRpbC5jb3B5ZmlsZShzb3VyY2UsIHRhcmdldCkKICAgICAgICAgICAgICAgICAgICAgICAgb3MuY2htb2QodGFyZ2V0LCAwbzY0NCkKICAgICAgICAgICAgIyBBcyBpbiB0aGUgdGVzdGVkIHJlc2N1ZSBraXQsIHVubG9hZCB0aGUgY2hpcCBhbmQgY29tbW9uIHJ0dzg5CiAgICAgICAgICAgICMgbW9kdWxlcyBiZWZvcmUgbG9hZGluZyBhZ2FpbiBzbyBhIGZhaWxlZCBmaXJtd2FyZSBwcm9iZSBpcyByZXRyaWVkLgogICAgICAgICAgICAjIE90aGVyIHdvcmtpbmcgZGV2aWNlcyBtYXkgcHJldmVudCB0aGUgdW5sb2FkOyBuZXZlciBmb3JjZSBpdC4KICAgICAgICAgICAgaWYgY29tbWFuZChbIm1vZGluZm8iLCBtb2R1bGVdKS5yZXR1cm5jb2RlICE9IDA6CiAgICAgICAgICAgICAgICBsb2coIktub3duIFdpLUZpIGFkYXB0ZXIncyBkcml2ZXIgaXMgYWJzZW50IGZyb20gdGhlIGxpdmUga2VybmVsLiIpCiAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICByZW1vdmUgPSBbIm1vZHByb2JlIiwgIi1yIiwgbW9kdWxlXQogICAgICAgICAgICBpZiBtb2R1bGUgPT0gInJ0dzg5Xzg5MjJhZSI6CiAgICAgICAgICAgICAgICByZW1vdmUuZXh0ZW5kKFsicnR3ODlfODkyMmEiLCAicnR3ODlfcGNpIiwgInJ0dzg5X2NvcmUiXSkKICAgICAgICAgICAgY29tbWFuZChyZW1vdmUpCiAgICAgICAgICAgIGlmIGNvbW1hbmQoWyJtb2Rwcm9iZSIsIG1vZHVsZV0pLnJldHVybmNvZGUgPT0gMDoKICAgICAgICAgICAgICAgIGZvciBfIGluIHJhbmdlKDEwKToKICAgICAgICAgICAgICAgICAgICBpZiBnbG9iLmdsb2Iob3MucGF0aC5qb2luKGRldmljZSwgIm5ldCIsICIqIiwgIndpcmVsZXNzIikpOgogICAgICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgICAgIHRpbWUuc2xlZXAoMSkKICAgICAgICBleGNlcHQgKE9TRXJyb3IsIFZhbHVlRXJyb3IpOgogICAgICAgICAgICBsb2coIldpLUZpIGZpcm13YXJlIHJlY292ZXJ5IGNvdWxkIG5vdCBjb21wbGV0ZTsgc2V0dXAgY2FuIHVzZSBFdGhlcm5ldC4iKQoKZGVmIHByZXBhcmVfd2lmaShhdXRvaW5zdGFsbCwgbWFya2VyX3RleHQpOgogICAgIyBEbyBub3QgbGV0IGEgZmFpbGVkIHJlcGVhdCB1c2UgYW4gb2xkIGNvbmZpZ3VyYXRpb24gZm9yIGNsZWFudXAuCiAgICB0cnk6CiAgICAgICAgb3MudW5saW5rKHdpZmlfb3V0cHV0KQogICAgZXhjZXB0IEZpbGVOb3RGb3VuZEVycm9yOgogICAgICAgIHBhc3MKICAgIHRyeToKICAgICAgICBvcy51bmxpbmsod2lmaV9tYXJrZXIpCiAgICBleGNlcHQgRmlsZU5vdEZvdW5kRXJyb3I6CiAgICAgICAgcGFzcwogICAgdHJ5OgogICAgICAgIGludGVyZmFjZXMgPSBzb3J0ZWQobmFtZSBmb3IgbmFtZSBpbiBvcy5saXN0ZGlyKHN5c19uZXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiByZS5mdWxsbWF0Y2gociJbQS1aYS16MC05Xy4tXXsxLDE1fSIsIG5hbWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmQgb3MucGF0aC5pc2Rpcihvcy5wYXRoLmpvaW4oc3lzX25ldCwgbmFtZSwgIndpcmVsZXNzIikpKQogICAgICAgIGlmIG5vdCBpbnRlcmZhY2VzOgogICAgICAgICAgICBkZXZpY2UgPSB3aXJlbGVzc19kZXZpY2Vfd2l0aG91dF9pbnRlcmZhY2UoKQogICAgICAgICAgICBpZiBkZXZpY2U6CiAgICAgICAgICAgICAgICB3aXRoIG9wZW4od2lmaV9tYXJrZXIsICJ3IiwgZW5jb2Rpbmc9InV0Zi04IikgYXMgb3V0OgogICAgICAgICAgICAgICAgICAgIG91dC53cml0ZSgiV2ktRmkgaXMgbm90IHJlYWR5IG9uIHRoaXMgY29tcHV0ZXIuIENvbm5lY3QgYW4gRXRoZXJuZXQgY2FibGUuXG4iKQogICAgICAgICAgICAgICAgbG9nKCJXaS1GaSBhZGFwdGVyIG5lZWRzIGFuIHVuc2hpcHBlZCBkcml2ZXI7IHVzZSBFdGhlcm5ldC4iKQogICAgICAgICAgICBlbGlmIG9zLnBhdGguaXNmaWxlKHdpZmlfcGF0aCk6CiAgICAgICAgICAgICAgICBsb2coIk5vIHVzYWJsZSBXaS1GaSBpbnRlcmZhY2Ugd2FzIGZvdW5kOyB1c2UgRXRoZXJuZXQuIikKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgaWYgbm90IG9zLnBhdGguaXNmaWxlKHdpZmlfcGF0aCk6CiAgICAgICAgICAgIHJldHVybgogICAgICAgIGNvZGVzID0gcmUuZmluZGFsbChyIl4jTkFMVk8tUEFJUjooW15cclxuXSopJCIsIG1hcmtlcl90ZXh0LCByZS5NVUxUSUxJTkUpCiAgICAgICAgaWYgbGVuKGNvZGVzKSAhPSAxIG9yIG5vdCByZS5mdWxsbWF0Y2gociJbMC05QS1ISktNTlAtVFYtWl17MjB9IiwgY29kZXNbMF0pOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJpbnZhbGlkIGluc3RhbGxlciBjb2RlIikKICAgICAgICBkYXRhID0gb3Blbih3aWZpX3BhdGgsICJyYiIpLnJlYWQoNjU1MzcpCiAgICAgICAgIyBOQUxWT1dGMSB8fCBzYWx0KDE2KSB8fCBJVigxNikgfHwgQ0JDIGNpcGhlcnRleHQgfHwgSE1BQygzMikuCiAgICAgICAgIyBQQktERjItSE1BQy1TSEEyNTYoY29kZSBVVEYtOCwgc2FsdCwgMjAwMDAwLCA2NCksIGZpcnN0IDMyCiAgICAgICAgIyBieXRlcyBBRVMtMjU2IGtleSwgbGFzdCAzMiBITUFDIGtleS4gSE1BQyBjb3ZlcnMgdGhlIHdob2xlIHByZWZpeC4KICAgICAgICBpZiAobGVuKGRhdGEpIDwgODggb3IgbGVuKGRhdGEpID4gNjU1MzYgb3IgZGF0YVs6OF0gIT0gYiJOQUxWT1dGMSIKICAgICAgICAgICAgICAgIG9yIChsZW4oZGF0YSkgLSA3MikgJSAxNik6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoImludmFsaWQgZW52ZWxvcGUiKQogICAgICAgIGtleXMgPSBoYXNobGliLnBia2RmMl9obWFjKCJzaGEyNTYiLCBjb2Rlc1swXS5lbmNvZGUoInV0Zi04IiksIGRhdGFbODoyNF0sIDIwMDAwMCwgNjQpCiAgICAgICAgaWYgbm90IGhtYWMuY29tcGFyZV9kaWdlc3QoaG1hYy5uZXcoa2V5c1szMjpdLCBkYXRhWzotMzJdLCBoYXNobGliLnNoYTI1NikuZGlnZXN0KCksIGRhdGFbLTMyOl0pOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJpbnZhbGlkIGF1dGhlbnRpY2F0aW9uIikKICAgICAgICBwbGFpbiA9IHN1YnByb2Nlc3MucnVuKFsib3BlbnNzbCIsICJlbmMiLCAiLWQiLCAiLWFlcy0yNTYtY2JjIiwgIi1LIiwga2V5c1s6MzJdLmhleCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICItaXYiLCBkYXRhWzI0OjQwXS5oZXgoKV0sIGlucHV0PWRhdGFbNDA6LTMyXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHN0ZGVycj1zdWJwcm9jZXNzLkRFVk5VTEwsIGNoZWNrPVRydWUpLnN0ZG91dAogICAgICAgIHByb2ZpbGUgPSBqc29uLmxvYWRzKHBsYWluLmRlY29kZSgidXRmLTgiKSkKICAgICAgICBzc2lkLCBhdXRoLCBwc2sgPSBwcm9maWxlWyJzc2lkIl0sIHByb2ZpbGVbImF1dGgiXSwgcHJvZmlsZVsicHNrIl0KICAgICAgICBpZiAobm90IGlzaW5zdGFuY2Uoc3NpZCwgc3RyKSBvciBub3QgMSA8PSBsZW4oc3NpZC5lbmNvZGUoInV0Zi04IikpIDw9IDMyCiAgICAgICAgICAgICAgICBvciBub3QgaXNpbnN0YW5jZShwc2ssIHN0cikgb3IgYXV0aCBub3QgaW4gKCJ3cGEyIiwgIndwYTMiLCAib3BlbiIpCiAgICAgICAgICAgICAgICBvciBhbnkob3JkKGMpIDwgMzIgb3Igb3JkKGMpID09IDEyNyBmb3IgYyBpbiBzc2lkICsgcHNrKQogICAgICAgICAgICAgICAgb3IgKGF1dGggPT0gIm9wZW4iIGFuZCBwc2sgIT0gIiIpCiAgICAgICAgICAgICAgICBvciAoYXV0aCAhPSAib3BlbiIgYW5kIG5vdCAoOCA8PSBsZW4ocHNrKSA8PSA2MyBvciByZS5mdWxsbWF0Y2gociJbMC05YS1mQS1GXXs2NH0iLCBwc2spKSkpOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJpbnZhbGlkIHByb2ZpbGUiKQogICAgICAgIGFjY2Vzc19wb2ludCA9IHt9IGlmIGF1dGggPT0gIm9wZW4iIGVsc2UgeyJwYXNzd29yZCI6IHBza30KICAgICAgICBpZiBhdXRoID09ICJ3cGEzIjoKICAgICAgICAgICAgYWNjZXNzX3BvaW50ID0geyJhdXRoIjogeyJrZXktbWFuYWdlbWVudCI6ICJzYWUiLCAicGFzc3dvcmQiOiBwc2t9fQogICAgICAgIG5ldHdvcmsgPSB7InZlcnNpb24iOiAyLCAid2lmaXMiOiB7aW50ZXJmYWNlc1swXTogewogICAgICAgICAgICAiZGhjcDQiOiBUcnVlLCAiZGhjcDQtb3ZlcnJpZGVzIjogeyJyb3V0ZS1tZXRyaWMiOiA2MDB9LAogICAgICAgICAgICAiYWNjZXNzLXBvaW50cyI6IHtzc2lkOiBhY2Nlc3NfcG9pbnR9fX19CiAgICAgICAgZXRoZXJuZXQgPSB7fQogICAgICAgIGZvciBuYW1lIGluIHNvcnRlZChvcy5saXN0ZGlyKHN5c19uZXQpKToKICAgICAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihzeXNfbmV0LCBuYW1lKQogICAgICAgICAgICBpZiAocmUuZnVsbG1hdGNoKHIiW0EtWmEtejAtOV8uLV17MSwxNX0iLCBuYW1lKSBhbmQgbmFtZSAhPSAibG8iCiAgICAgICAgICAgICAgICAgICAgYW5kIG5vdCBvcy5wYXRoLmlzZGlyKG9zLnBhdGguam9pbihwYXRoLCAid2lyZWxlc3MiKSkKICAgICAgICAgICAgICAgICAgICBhbmQgb3MucGF0aC5leGlzdHMob3MucGF0aC5qb2luKHBhdGgsICJkZXZpY2UiKSkpOgogICAgICAgICAgICAgICAgZXRoZXJuZXRbbmFtZV0gPSB7ImRoY3A0IjogVHJ1ZSwgImRoY3A0LW92ZXJyaWRlcyI6IHsicm91dGUtbWV0cmljIjogMTAwfSwgIm9wdGlvbmFsIjogVHJ1ZX0KICAgICAgICBpZiBldGhlcm5ldDoKICAgICAgICAgICAgbmV0d29ya1siZXRoZXJuZXRzIl0gPSBldGhlcm5ldAogICAgICAgICAgICBuZXR3b3JrWyJ3aWZpcyJdW2ludGVyZmFjZXNbMF1dWyJvcHRpb25hbCJdID0gVHJ1ZQogICAgICAgICMgQm90aCBmaWxlcyBhcmUgcHJpdmF0ZTogU3ViaXF1aXR5IHJlcmVhZHMgL2F1dG9pbnN0YWxsLnlhbWwsIGFuZCBsYXRlCiAgICAgICAgIyBjb21tYW5kcyBjb3B5IHRoZSBzZWNvbmQgaW50byB0aGUgaW5zdGFsbGVkIHN5c3RlbSB3aXRoIG1vZGUgMDYwMC4KICAgICAgICBmZCA9IG9zLm9wZW4od2lmaV9vdXRwdXQsIG9zLk9fV1JPTkxZIHwgb3MuT19DUkVBVCB8IG9zLk9fVFJVTkMsIDBvNjAwKQogICAgICAgIHdpdGggb3MuZmRvcGVuKGZkLCAidyIsIGVuY29kaW5nPSJ1dGYtOCIpIGFzIG91dDoKICAgICAgICAgICAgb3MuZmNobW9kKG91dC5maWxlbm8oKSwgMG82MDApCiAgICAgICAgICAgIHlhbWwuc2FmZV9kdW1wKHsibmV0d29yayI6IG5ldHdvcmt9LCBvdXQsIHNvcnRfa2V5cz1GYWxzZSwgYWxsb3dfdW5pY29kZT1UcnVlKQogICAgICAgIGF1dG9pbnN0YWxsWyJuZXR3b3JrIl0gPSBuZXR3b3JrCiAgICAgICAgbG9nKCJXaS1GaSBjb25maWd1cmF0aW9uIHByZXBhcmVkOyBFdGhlcm5ldCBpcyBwcmVmZXJyZWQgd2hlbiBhdmFpbGFibGUuIikKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgdHJ5OgogICAgICAgICAgICBvcy51bmxpbmsod2lmaV9vdXRwdXQpCiAgICAgICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgICAgIHBhc3MKICAgICAgICBsb2coIldpLUZpIHNldHVwIGZhaWxlZDsgdXNlIEV0aGVybmV0LiBUaGUgZW5jcnlwdGVkIGZpbGUgd2lsbCBiZSByZW1vdmVkIGF0IHRoZSBlbmQgaWYgcG9zc2libGUuIikKCgpkZWYgbm9kZXModHJlZSk6CiAgICBmb3Igbm9kZSBpbiB0cmVlOgogICAgICAgIGlmIG5vdCBpc2luc3RhbmNlKG5vZGUsIGRpY3QpOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJpbnZhbGlkIGRldmljZSIpCiAgICAgICAgaWYgKG5vdCBpc2luc3RhbmNlKG5vZGUuZ2V0KCJwYXRoIiksIHN0cikKICAgICAgICAgICAgICAgIG9yIG5vdCByZS5mdWxsbWF0Y2gociIvZGV2L1tBLVphLXowLTkuXysvLV0rIiwgbm9kZVsicGF0aCJdKQogICAgICAgICAgICAgICAgb3Igbm90IGlzaW5zdGFuY2Uobm9kZS5nZXQoInR5cGUiKSwgc3RyKSk6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoImludmFsaWQgZGV2aWNlIHByb3BlcnRpZXMiKQogICAgICAgIHlpZWxkIG5vZGUKICAgICAgICBjaGlsZHJlbiA9IG5vZGUuZ2V0KCJjaGlsZHJlbiIsIFtdKQogICAgICAgIGlmIG5vdCBpc2luc3RhbmNlKGNoaWxkcmVuLCBsaXN0KToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiaW52YWxpZCBjaGlsZHJlbiIpCiAgICAgICAgeWllbGQgZnJvbSBub2RlcyhjaGlsZHJlbikKCgpkZWYgY2hvb3NlX2Rpc2soKToKICAgIHNvdXJjZSA9IGNvbW1hbmQoWyJmaW5kbW50IiwgIi1uIiwgIi1vIiwgIlNPVVJDRSIsICItLXRhcmdldCIsICIvY2Ryb20iXSkKICAgIGlmIHNvdXJjZS5yZXR1cm5jb2RlICE9IDA6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiY2Fubm90IGlkZW50aWZ5IGluc3RhbGxlciBkZXZpY2UiKQogICAgc291cmNlX3BhdGggPSBzb3VyY2Uuc3Rkb3V0LnN0cmlwKCkKICAgIGlmIG5vdCBzb3VyY2VfcGF0aC5zdGFydHN3aXRoKCIvZGV2LyIpIG9yICJcbiIgaW4gc291cmNlX3BhdGg6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiY2Fubm90IGlkZW50aWZ5IGluc3RhbGxlciBkZXZpY2UiKQogICAgc291cmNlX3BhdGggPSBvcy5wYXRoLnJlYWxwYXRoKHNvdXJjZV9wYXRoKQoKICAgIHJlc3VsdCA9IGNvbW1hbmQoWyJsc2JsayIsICItSiIsICItYiIsICItcCIsICItbyIsICJQQVRILFRZUEUsU0laRSxSTSxUUkFOLFNFUklBTCJdKQogICAgaWYgcmVzdWx0LnJldHVybmNvZGUgIT0gMDoKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJjYW5ub3QgbGlzdCBkZXZpY2VzIikKICAgIGRhdGEgPSBqc29uLmxvYWRzKHJlc3VsdC5zdGRvdXQpCiAgICBkaXNrcyA9IGRhdGFbImJsb2NrZGV2aWNlcyJdCiAgICBpZiBub3QgaXNpbnN0YW5jZShkaXNrcywgbGlzdCk6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiaW52YWxpZCBkZXZpY2UgbGlzdCIpCiAgICAjIFdhbGsgdGhlIHRyZWUgdG8gaWRlbnRpZnkgdGhlIHdob2xlIHBoeXNpY2FsIGRpc2sgYmFja2luZyAvY2Ryb20uIElmIGl0CiAgICAjIGNhbm5vdCBiZSBpZGVudGlmaWVkLCBkbyBub3QgZ3Vlc3Mgd2hpY2ggZGlzayBpcyB0aGUgaW5zdGFsbGVyLgogICAgYWxsX3Jvb3RzID0gWyhyb290LCBsaXN0KG5vZGVzKFtyb290XSkpKSBmb3Igcm9vdCBpbiBkaXNrc10KICAgIHNvdXJjZV9yb290cyA9IFtyb290IGZvciByb290LCBkZXNjZW5kYW50cyBpbiBhbGxfcm9vdHMKICAgICAgICAgICAgICAgICAgICBpZiBhbnkob3MucGF0aC5yZWFscGF0aChuWyJwYXRoIl0pID09IHNvdXJjZV9wYXRoIGZvciBuIGluIGRlc2NlbmRhbnRzKV0KICAgIGlmIGxlbihzb3VyY2Vfcm9vdHMpICE9IDE6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiY2Fubm90IGlkZW50aWZ5IGluc3RhbGxlciBkZXZpY2UiKQogICAgaWYgc291cmNlX3Jvb3RzWzBdLmdldCgidHlwZSIpID09ICJsb29wIjoKICAgICAgICAjIEEgbG9vcCBkZXZpY2UgY2FuIGNvbmNlYWwgd2hpY2ggcGh5c2ljYWwgZGlzayBjb250YWlucyBpdHMgYmFja2luZyBmaWxlLgogICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoImluc3RhbGxlciBiYWNraW5nIGRpc2sgaXMgYW1iaWd1b3VzIikKCiAgICBjYW5kaWRhdGVzID0gW10KICAgIGZvciBkaXNrIGluIGRpc2tzOgogICAgICAgIGlmIG5vdCBpc2luc3RhbmNlKGRpc2ssIGRpY3QpIG9yIGRpc2suZ2V0KCJ0eXBlIikgIT0gImRpc2siOgogICAgICAgICAgICBjb250aW51ZQogICAgICAgIHBhdGggPSBkaXNrLmdldCgicGF0aCIpCiAgICAgICAgc2l6ZSA9IGRpc2suZ2V0KCJzaXplIikKICAgICAgICByZW1vdmFibGUgPSBkaXNrLmdldCgicm0iKQogICAgICAgIHRyYW5zcG9ydCA9IGRpc2suZ2V0KCJ0cmFuIikKICAgICAgICBpZiAobm90IHsicGF0aCIsICJ0eXBlIiwgInNpemUiLCAicm0iLCAidHJhbiJ9Lmlzc3Vic2V0KGRpc2spCiAgICAgICAgICAgICAgICBvciBub3QgaXNpbnN0YW5jZShwYXRoLCBzdHIpIG9yIG5vdCByZS5mdWxsbWF0Y2gociIvZGV2L1tBLVphLXowLTkuXysvLV0rIiwgcGF0aCkKICAgICAgICAgICAgICAgIG9yIGlzaW5zdGFuY2Uoc2l6ZSwgYm9vbCkgb3Igbm90IGlzaW5zdGFuY2Uoc2l6ZSwgaW50KQogICAgICAgICAgICAgICAgb3IgcmVtb3ZhYmxlIG5vdCBpbiAoRmFsc2UsIFRydWUsIDAsIDEpCiAgICAgICAgICAgICAgICBvciAodHJhbnNwb3J0IGlzIG5vdCBOb25lIGFuZCBub3QgaXNpbnN0YW5jZSh0cmFuc3BvcnQsIHN0cikpKToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiaW52YWxpZCBkaXNrIHByb3BlcnRpZXMiKQogICAgICAgIGlmIChkaXNrIGlzIHNvdXJjZV9yb290c1swXSBvciByZW1vdmFibGUgb3IgKHRyYW5zcG9ydCBvciAiIikubG93ZXIoKSA9PSAidXNiIgogICAgICAgICAgICAgICAgb3IgcmUubWF0Y2gociJeL2Rldi8oPzpsb29wfHNyfHpyYW18bWQpIiwgcGF0aCkgb3Igc2l6ZSA8IDEwMF8wMDBfMDAwXzAwMCk6CiAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgY2FuZGlkYXRlcy5hcHBlbmQoZGlzaykKICAgIGlmIGxlbihjYW5kaWRhdGVzKSAhPSAxOgogICAgICAgIHJldHVybiBOb25lLCAiU3RvcmFnZSByZW1haW5zIGludGVyYWN0aXZlOiBjYW5kaWRhdGUgY291bnQgaXMgbm90IG9uZS4iCgogICAgZGlzayA9IGNhbmRpZGF0ZXNbMF0KICAgICMgQW55IGNoaWxkIGluY2x1ZGVzIHBhcnRpdGlvbnMgYW5kIG1hcHBlZC9SQUlEIG1lbWJlcnMuIEV2ZW4gYW4gdW5mb3JtYXR0ZWQKICAgICMgcGFydGl0aW9uIGNvdW50cyBhcyBkYXRhIGFuZCBtdXN0IGdvIHRocm91Z2ggdGhlIGh1bWFuIGRpc2sgc2NyZWVuLgogICAgaWYgZGlzay5nZXQoImNoaWxkcmVuIik6CiAgICAgICAgcmV0dXJuIE5vbmUsICJTdG9yYWdlIHJlbWFpbnMgaW50ZXJhY3RpdmU6IGNhbmRpZGF0ZSBoYXMgZXhpc3RpbmcgY2hpbGRyZW4uIgogICAgcGF0aCA9IGRpc2tbInBhdGgiXQogICAgd2lwZSA9IGNvbW1hbmQoWyJ3aXBlZnMiLCAiLW4iLCAiLS1ub2hlYWRpbmdzIiwgIi0tb3V0cHV0IiwgIlRZUEUiLCAiLS0iLCBwYXRoXSkKICAgIHByb2JlID0gY29tbWFuZChbImJsa2lkIiwgIi1wIiwgcGF0aF0pCiAgICBpZiB3aXBlLnJldHVybmNvZGUgIT0gMCBvciB3aXBlLnN0ZG91dC5zdHJpcCgpIG9yIHByb2JlLnJldHVybmNvZGUgIT0gMiBvciBwcm9iZS5zdGRvdXQuc3RyaXAoKToKICAgICAgICByZXR1cm4gTm9uZSwgIlN0b3JhZ2UgcmVtYWlucyBpbnRlcmFjdGl2ZTogc2lnbmF0dXJlIGZvdW5kIG9yIHByb2JlIGZhaWxlZC4iCiAgICByZXR1cm4gcGF0aCwgIlN0b3JhZ2Ugc2VsZWN0ZWQgYXV0b21hdGljYWxseTogb25lIGVtcHR5IGludGVybmFsIGRpc2suIgoKCnRyeToKICAgIHdpdGggb3Blbihjb25maWdfcGF0aCwgZW5jb2Rpbmc9InV0Zi04IikgYXMgc291cmNlOgogICAgICAgIG9yaWdpbmFsID0gc291cmNlLnJlYWQoKQogICAgZG9jdW1lbnQgPSB5YW1sLnNhZmVfbG9hZChvcmlnaW5hbCkKICAgIGF1dG9pbnN0YWxsID0gZG9jdW1lbnRbImF1dG9pbnN0YWxsIl0KICAgIGlmIG5vdCBpc2luc3RhbmNlKGF1dG9pbnN0YWxsLCBkaWN0KToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJpbnZhbGlkIGF1dG9pbnN0YWxsIikKICAgIHRyeToKICAgICAgICB3aXRoIG9wZW4oc291cmNlX3BhdGgsIGVuY29kaW5nPSJ1dGYtOCIpIGFzIHN0aWNrOgogICAgICAgICAgICBtYXJrZXJfdGV4dCA9IHN0aWNrLnJlYWQoKQogICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgbWFya2VyX3RleHQgPSAiIgogICAgbmFtZXMgPSByZS5maW5kYWxsKHIiXiNOQUxWTy1OQU1FOihbXlxyXG5dKikkIiwgbWFya2VyX3RleHQsIHJlLk1VTFRJTElORSkKICAgIGhvc3RuYW1lID0gbmFtZXNbMF0gaWYgbGVuKG5hbWVzKSA9PSAxIGFuZCByZS5mdWxsbWF0Y2goCiAgICAgICAgciJbYS16MC05XSg/OlthLXowLTktXXswLDYxfVthLXowLTldKT8iLCBuYW1lc1swXSwgcmUuQVNDSUkpIGVsc2UgIm5hbHZvLW5vZGUiCiAgICAjIFRoZSByYW5kb20gc2VjcmV0IGlzIHBhc3NlZCBvbiBzdGRpbiwgbmV2ZXIgYXMgYW4gYXJndW1lbnQsIGFuZCBkaXNjYXJkZWQuCiAgICBoYXNoX2ZhaWxlZCA9IEZhbHNlCiAgICB0cnk6CiAgICAgICAgaGFzaGVkID0gc3VicHJvY2Vzcy5ydW4oWyJvcGVuc3NsIiwgInBhc3N3ZCIsICItNiIsICItc3RkaW4iXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dD1zZWNyZXRzLnRva2VuX3VybHNhZmUoNDgpICsgIlxuIiwgdGV4dD1UcnVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHN0ZGVycj1zdWJwcm9jZXNzLkRFVk5VTEwsIGNoZWNrPVRydWUpLnN0ZG91dC5zdHJpcCgpCiAgICAgICAgaWYgbm90IGhhc2hlZC5zdGFydHN3aXRoKCIkNiQiKToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigicGFzc3dvcmQgaGFzaCB1bmF2YWlsYWJsZSIpCiAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgIGhhc2hfZmFpbGVkID0gVHJ1ZQogICAgICAgICMgUHJlc2VydmUgYSB1c2FibGUgaW5zdGFsbGVyIGNvbmZpZyBldmVuIGlmIHRoZSBsaXZlIGltYWdlIGxhY2tzIGEKICAgICAgICAjIHdvcmtpbmcgb3BlbnNzbC4gUHl0aG9uJ3MgU0hBLTUxMiBjcnlwdCB1c2VzIGEgZnJlc2ggcmFuZG9tIHNhbHQuCiAgICAgICAgdHJ5OgogICAgICAgICAgICBpbXBvcnQgY3J5cHQKICAgICAgICAgICAgaGFzaGVkID0gY3J5cHQuY3J5cHQoc2VjcmV0cy50b2tlbl91cmxzYWZlKDQ4KSwgY3J5cHQubWtzYWx0KGNyeXB0Lk1FVEhPRF9TSEE1MTIpKQogICAgICAgICAgICBpZiBub3QgaGFzaGVkIG9yIG5vdCBoYXNoZWQuc3RhcnRzd2l0aCgiJDYkIik6CiAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJwYXNzd29yZCBoYXNoIHVuYXZhaWxhYmxlIikKICAgICAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgICAgICAjIEFuIHVudXNhYmxlIHBhc3N3b3JkIGlzIHNhZmVyIHRoYW4gZXZlciBpbnN0YWxsaW5nIGEga25vd24gb25lLgogICAgICAgICAgICBoYXNoZWQgPSAiISIKICAgICAgICAgICAgbG9nKCJQYXNzd29yZCBoYXNoaW5nIGZhaWxlZDsgdGhlIHRlbXBvcmFyeSBhY2NvdW50IHBhc3N3b3JkIGlzIGxvY2tlZC4iKQogICAgYXV0b2luc3RhbGxbImlkZW50aXR5Il0gPSB7Imhvc3RuYW1lIjogaG9zdG5hbWUsICJ1c2VybmFtZSI6ICJuYWx2byIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmVhbG5hbWUiOiAiTmFsdm8gbm9kZSIsICJwYXNzd29yZCI6IGhhc2hlZH0KICAgIHNlY3Rpb25zID0gYXV0b2luc3RhbGwuZ2V0KCJpbnRlcmFjdGl2ZS1zZWN0aW9ucyIsIFtdKQogICAgaWYgbm90IGlzaW5zdGFuY2Uoc2VjdGlvbnMsIGxpc3QpOgogICAgICAgIHNlY3Rpb25zID0gW10KICAgIHNlY3Rpb25zID0gW3NlY3Rpb24gZm9yIHNlY3Rpb24gaW4gc2VjdGlvbnMgaWYgc2VjdGlvbiBub3QgaW4gKCJzdG9yYWdlIiwgImlkZW50aXR5IildCiAgICBzZWN0aW9ucy5hcHBlbmQoInN0b3JhZ2UiKQogICAgYXV0b2luc3RhbGxbImludGVyYWN0aXZlLXNlY3Rpb25zIl0gPSBzZWN0aW9ucwogICAgIyBDb21taXQgdGhlIHNhZmUgYmFzZWxpbmUgZmlyc3Q6IGV2ZW4gYSBmYWlsZWQgZGlzayBwcm9iZSBzdGF5cyBpbnRlcmFjdGl2ZS4KICAgIHNhdmUoZG9jdW1lbnQpCiAgICBoYWRfbmV0d29yayA9ICJuZXR3b3JrIiBpbiBhdXRvaW5zdGFsbAogICAgb3JpZ2luYWxfbmV0d29yayA9IGF1dG9pbnN0YWxsLmdldCgibmV0d29yayIpCiAgICB0cnk6CiAgICAgICAgcmVjb3Zlcl9rbm93bl93aWZpKCkKICAgICAgICBwcmVwYXJlX3dpZmkoYXV0b2luc3RhbGwsIG1hcmtlcl90ZXh0KQogICAgICAgIGlmICJuZXR3b3JrIiBpbiBhdXRvaW5zdGFsbDoKICAgICAgICAgICAgc2F2ZShkb2N1bWVudCkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgaWYgaGFkX25ldHdvcms6CiAgICAgICAgICAgIGF1dG9pbnN0YWxsWyJuZXR3b3JrIl0gPSBvcmlnaW5hbF9uZXR3b3JrCiAgICAgICAgZWxzZToKICAgICAgICAgICAgYXV0b2luc3RhbGwucG9wKCJuZXR3b3JrIiwgTm9uZSkKICAgICAgICB0cnk6CiAgICAgICAgICAgIG9zLnVubGluayh3aWZpX291dHB1dCkKICAgICAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICAgICAgcGFzcwogICAgICAgIGxvZygiV2ktRmkgY29uZmlndXJhdGlvbiBjb3VsZCBub3QgYmUgc2F2ZWQ7IHVzZSBFdGhlcm5ldC4iKQogICAgdHJ5OgogICAgICAgIGlmIGhhc2hfZmFpbGVkOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJwYXNzd29yZCBoYXNoaW5nIHJlcXVpcmVkIGZhbGxiYWNrIikKICAgICAgICBwYXRoLCBkZWNpc2lvbiA9IGNob29zZV9kaXNrKCkKICAgICAgICBpZiBwYXRoIGlzIG5vdCBOb25lOgogICAgICAgICAgICBhdXRvaW5zdGFsbFsic3RvcmFnZSJdID0geyJsYXlvdXQiOiB7Im5hbWUiOiAibHZtIiwgInNpemluZy1wb2xpY3kiOiAic2NhbGVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibWF0Y2giOiB7InBhdGgiOiBwYXRofX19CiAgICAgICAgICAgIGF1dG9pbnN0YWxsWyJpbnRlcmFjdGl2ZS1zZWN0aW9ucyJdID0gW3MgZm9yIHMgaW4gc2VjdGlvbnMgaWYgcyAhPSAic3RvcmFnZSJdCiAgICAgICAgICAgIHNhdmUoZG9jdW1lbnQpCiAgICAgICAgbG9nKGRlY2lzaW9uKQogICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICBsb2coIlN0b3JhZ2UgcmVtYWlucyBpbnRlcmFjdGl2ZTogZGV2aWNlIGluc3BlY3Rpb24gZmFpbGVkLiIpCmV4Y2VwdCBFeGNlcHRpb246CiAgICBsb2coIkVhcmx5IHNldHVwIGZhaWxlZDsgc3RvcmFnZSByZW1haW5zIGludGVyYWN0aXZlLiIpClBZCg== #NALVO-QR-B64:IiIiU21hbGwgUVIgQ29kZSBlbmNvZGVyOiBieXRlIG1vZGUsIGVycm9yIGNvcnJlY3Rpb24gTSwgdmVyc2lvbnMgMeKAkzEwLgoKYGBlbmNvZGVgYCByZXR1cm5zIHRoZSBzcXVhcmUgc3ltYm9sIHdpdGhvdXQgaXRzIHF1aWV0IHpvbmUsIGFzIHJvd3Mgb2YgYm9vbGVhbnMuCmBgdG9fc3ZnYGAgYWRkcyB0aGUgcmVxdWlyZWQgZm91ci1tb2R1bGUgd2hpdGUgcXVpZXQgem9uZS4gRGF0YSBpcyBhcmJpdHJhcnkKYnl0ZXM7IGNhbGxlcnMgY2hvb3NpbmcgdGV4dCBhcmUgcmVzcG9uc2libGUgZm9yIGl0cyBlbmNvZGluZy4KIiIiCgpfRUNDID0gKDAsIDEwLCAxNiwgMjYsIDE4LCAyNCwgMTYsIDE4LCAyMiwgMjIsIDI2KQpfQkxPQ0tTID0gKDAsIDEsIDEsIDEsIDIsIDIsIDQsIDQsIDQsIDUsIDUpCgoKZGVmIF9yYXdfbW9kdWxlcyh2ZXJzaW9uKToKICAgIHJlc3VsdCA9ICgxNiAqIHZlcnNpb24gKyAxMjgpICogdmVyc2lvbiArIDY0CiAgICBpZiB2ZXJzaW9uID49IDI6CiAgICAgICAgYWxpZ24gPSB2ZXJzaW9uIC8vIDcgKyAyCiAgICAgICAgcmVzdWx0IC09ICgyNSAqIGFsaWduIC0gMTApICogYWxpZ24gLSA1NQogICAgICAgIGlmIHZlcnNpb24gPj0gNzoKICAgICAgICAgICAgcmVzdWx0IC09IDM2CiAgICByZXR1cm4gcmVzdWx0CgoKZGVmIF9tdWx0aXBseSh4LCB5KToKICAgIHJlc3VsdCA9IDAKICAgIGZvciBpIGluIHJhbmdlKDcsIC0xLCAtMSk6CiAgICAgICAgcmVzdWx0ID0gKHJlc3VsdCA8PCAxKSBeICgocmVzdWx0ID4+IDcpICogMHgxMUQpCiAgICAgICAgcmVzdWx0IF49ICgoeSA+PiBpKSAmIDEpICogeAogICAgcmV0dXJuIHJlc3VsdAoKCmRlZiBfZGl2aXNvcihkZWdyZWUpOgogICAgcmVzdWx0ID0gWzBdICogKGRlZ3JlZSAtIDEpICsgWzFdCiAgICByb290ID0gMQogICAgZm9yIF8gaW4gcmFuZ2UoZGVncmVlKToKICAgICAgICBmb3IgaiBpbiByYW5nZShkZWdyZWUpOgogICAgICAgICAgICByZXN1bHRbal0gPSBfbXVsdGlwbHkocmVzdWx0W2pdLCByb290KQogICAgICAgICAgICBpZiBqICsgMSA8IGRlZ3JlZToKICAgICAgICAgICAgICAgIHJlc3VsdFtqXSBePSByZXN1bHRbaiArIDFdCiAgICAgICAgcm9vdCA9IF9tdWx0aXBseShyb290LCAyKQogICAgcmV0dXJuIHJlc3VsdAoKCmRlZiBfcmVtYWluZGVyKGRhdGEsIGRpdmlzb3IpOgogICAgcmVzdWx0ID0gWzBdICogbGVuKGRpdmlzb3IpCiAgICBmb3IgdmFsdWUgaW4gZGF0YToKICAgICAgICBmYWN0b3IgPSB2YWx1ZSBeIHJlc3VsdC5wb3AoMCkKICAgICAgICByZXN1bHQuYXBwZW5kKDApCiAgICAgICAgZm9yIGksIGNvZWZmaWNpZW50IGluIGVudW1lcmF0ZShkaXZpc29yKToKICAgICAgICAgICAgcmVzdWx0W2ldIF49IF9tdWx0aXBseShjb2VmZmljaWVudCwgZmFjdG9yKQogICAgcmV0dXJuIHJlc3VsdAoKCmRlZiBfY29kZXdvcmRzKGRhdGEsIHZlcnNpb24pOgogICAgYmxvY2tzLCBlY2MgPSBfQkxPQ0tTW3ZlcnNpb25dLCBfRUNDW3ZlcnNpb25dCiAgICByYXcgPSBfcmF3X21vZHVsZXModmVyc2lvbikgLy8gOAogICAgY2FwYWNpdHkgPSByYXcgLSBibG9ja3MgKiBlY2MKICAgIGJpdHMgPSBbMCwgMSwgMCwgMF0KICAgIGNvdW50X2JpdHMgPSA4IGlmIHZlcnNpb24gPD0gOSBlbHNlIDE2CiAgICBiaXRzLmV4dGVuZCgobGVuKGRhdGEpID4+IGkpICYgMSBmb3IgaSBpbiByYW5nZShjb3VudF9iaXRzIC0gMSwgLTEsIC0xKSkKICAgIGZvciBieXRlIGluIGRhdGE6CiAgICAgICAgYml0cy5leHRlbmQoKGJ5dGUgPj4gaSkgJiAxIGZvciBpIGluIHJhbmdlKDcsIC0xLCAtMSkpCiAgICBiaXRzLmV4dGVuZChbMF0gKiBtaW4oNCwgY2FwYWNpdHkgKiA4IC0gbGVuKGJpdHMpKSkKICAgIGJpdHMuZXh0ZW5kKFswXSAqICgtbGVuKGJpdHMpICUgOCkpCiAgICB3b3JkcyA9IFtzdW0oYml0c1tpICsgal0gPDwgKDcgLSBqKSBmb3IgaiBpbiByYW5nZSg4KSkKICAgICAgICAgICAgIGZvciBpIGluIHJhbmdlKDAsIGxlbihiaXRzKSwgOCldCiAgICB3aGlsZSBsZW4od29yZHMpIDwgY2FwYWNpdHk6CiAgICAgICAgd29yZHMuYXBwZW5kKDB4RUMgaWYgKGxlbih3b3JkcykgLSAobGVuKGJpdHMpIC8vIDgpKSAlIDIgPT0gMCBlbHNlIDB4MTEpCiAgICBzaG9ydF9jb3VudCA9IGJsb2NrcyAtIHJhdyAlIGJsb2NrcwogICAgc2hvcnRfbGVuZ3RoID0gcmF3IC8vIGJsb2NrcwogICAgZGl2aXNvciA9IF9kaXZpc29yKGVjYykKICAgIHBpZWNlcywgcG9zID0gW10sIDAKICAgIGZvciBpIGluIHJhbmdlKGJsb2Nrcyk6CiAgICAgICAgbiA9IHNob3J0X2xlbmd0aCAtIGVjYyArIChpID49IHNob3J0X2NvdW50KQogICAgICAgIGNodW5rID0gd29yZHNbcG9zOnBvcyArIG5dCiAgICAgICAgcG9zICs9IG4KICAgICAgICBwaWVjZXMuYXBwZW5kKChjaHVuaywgX3JlbWFpbmRlcihjaHVuaywgZGl2aXNvcikpKQogICAgcmVzdWx0ID0gW10KICAgIGZvciBpIGluIHJhbmdlKHNob3J0X2xlbmd0aCAtIGVjYyArIDEpOgogICAgICAgIHJlc3VsdC5leHRlbmQoY2h1bmtbaV0gZm9yIGNodW5rLCBfIGluIHBpZWNlcyBpZiBpIDwgbGVuKGNodW5rKSkKICAgIGZvciBpIGluIHJhbmdlKGVjYyk6CiAgICAgICAgcmVzdWx0LmV4dGVuZChwYXJpdHlbaV0gZm9yIF8sIHBhcml0eSBpbiBwaWVjZXMpCiAgICBhc3NlcnQgbGVuKHJlc3VsdCkgPT0gcmF3CiAgICByZXR1cm4gcmVzdWx0CgoKZGVmIF9tYXNrKG1hc2ssIHgsIHkpOgogICAgcmV0dXJuICgoeCArIHkpICUgMiA9PSAwLCB5ICUgMiA9PSAwLCB4ICUgMyA9PSAwLAogICAgICAgICAgICAoeCArIHkpICUgMyA9PSAwLCAoeCAvLyAzICsgeSAvLyAyKSAlIDIgPT0gMCwKICAgICAgICAgICAgeCAqIHkgJSAyICsgeCAqIHkgJSAzID09IDAsCiAgICAgICAgICAgICh4ICogeSAlIDIgKyB4ICogeSAlIDMpICUgMiA9PSAwLAogICAgICAgICAgICAoKHggKyB5KSAlIDIgKyB4ICogeSAlIDMpICUgMiA9PSAwKVttYXNrXQoKCmRlZiBfc3ltYm9sKHZlcnNpb24sIHdvcmRzLCBtYXNrKToKICAgIHNpemUgPSB2ZXJzaW9uICogNCArIDE3CiAgICBtb2R1bGVzID0gW1tGYWxzZV0gKiBzaXplIGZvciBfIGluIHJhbmdlKHNpemUpXQogICAgZnVuY3Rpb24gPSBbW0ZhbHNlXSAqIHNpemUgZm9yIF8gaW4gcmFuZ2Uoc2l6ZSldCgogICAgZGVmIHNldGYoeCwgeSwgZGFyayk6CiAgICAgICAgaWYgMCA8PSB4IDwgc2l6ZSBhbmQgMCA8PSB5IDwgc2l6ZToKICAgICAgICAgICAgbW9kdWxlc1t5XVt4XSwgZnVuY3Rpb25beV1beF0gPSBib29sKGRhcmspLCBUcnVlCgogICAgZm9yIGkgaW4gcmFuZ2Uoc2l6ZSk6CiAgICAgICAgc2V0Zig2LCBpLCBpICUgMiA9PSAwKQogICAgICAgIHNldGYoaSwgNiwgaSAlIDIgPT0gMCkKICAgIGZvciBjeCwgY3kgaW4gKCgzLCAzKSwgKHNpemUgLSA0LCAzKSwgKDMsIHNpemUgLSA0KSk6CiAgICAgICAgZm9yIGR5IGluIHJhbmdlKC00LCA1KToKICAgICAgICAgICAgZm9yIGR4IGluIHJhbmdlKC00LCA1KToKICAgICAgICAgICAgICAgIHNldGYoY3ggKyBkeCwgY3kgKyBkeSwgbWF4KGFicyhkeCksIGFicyhkeSkpIG5vdCBpbiAoMiwgNCkpCiAgICBpZiB2ZXJzaW9uID49IDI6CiAgICAgICAgY291bnQgPSB2ZXJzaW9uIC8vIDcgKyAyCiAgICAgICAgc3RlcCA9ICh2ZXJzaW9uICogNCArIGNvdW50ICogMiArIDEpIC8vIChjb3VudCAqIDIgLSAyKSAqIDIKICAgICAgICBwb3NpdGlvbnMgPSBbNl0gKyBbc2l6ZSAtIDcgLSBpICogc3RlcCBmb3IgaSBpbiByYW5nZShjb3VudCAtIDIsIC0xLCAtMSldCiAgICAgICAgZm9yIHkgaW4gcG9zaXRpb25zOgogICAgICAgICAgICBmb3IgeCBpbiBwb3NpdGlvbnM6CiAgICAgICAgICAgICAgICBpZiAoeCwgeSkgaW4gKCg2LCA2KSwgKDYsIHNpemUgLSA3KSwgKHNpemUgLSA3LCA2KSk6CiAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgICAgIGZvciBkeSBpbiByYW5nZSgtMiwgMyk6CiAgICAgICAgICAgICAgICAgICAgZm9yIGR4IGluIHJhbmdlKC0yLCAzKToKICAgICAgICAgICAgICAgICAgICAgICAgc2V0Zih4ICsgZHgsIHkgKyBkeSwgbWF4KGFicyhkeCksIGFicyhkeSkpICE9IDEpCgogICAgIyBNIGhhcyBmb3JtYXQgZXJyb3IgY29ycmVjdGlvbiBiaXRzIDAwLiBSZXNlcnZlIGFuZCB3cml0ZSBib3RoIGNvcGllcy4KICAgIHJlbWFpbmRlciA9IG1hc2sKICAgIGZvciBfIGluIHJhbmdlKDEwKToKICAgICAgICByZW1haW5kZXIgPSAocmVtYWluZGVyIDw8IDEpIF4gKChyZW1haW5kZXIgPj4gOSkgKiAweDUzNykKICAgIGZtdCA9ICgobWFzayA8PCAxMCkgfCByZW1haW5kZXIpIF4gMHg1NDEyCiAgICBiaXQgPSBsYW1iZGEgaTogKGZtdCA+PiBpKSAmIDEKICAgIGZvciBpIGluIHJhbmdlKDYpOgogICAgICAgIHNldGYoOCwgaSwgYml0KGkpKQogICAgc2V0Zig4LCA3LCBiaXQoNikpOyBzZXRmKDgsIDgsIGJpdCg3KSk7IHNldGYoNywgOCwgYml0KDgpKQogICAgZm9yIGkgaW4gcmFuZ2UoOSwgMTUpOgogICAgICAgIHNldGYoMTQgLSBpLCA4LCBiaXQoaSkpCiAgICBmb3IgaSBpbiByYW5nZSg4KToKICAgICAgICBzZXRmKHNpemUgLSAxIC0gaSwgOCwgYml0KGkpKQogICAgZm9yIGkgaW4gcmFuZ2UoOCwgMTUpOgogICAgICAgIHNldGYoOCwgc2l6ZSAtIDE1ICsgaSwgYml0KGkpKQogICAgc2V0Zig4LCBzaXplIC0gOCwgVHJ1ZSkKICAgIGlmIHZlcnNpb24gPj0gNzoKICAgICAgICByZW1haW5kZXIgPSB2ZXJzaW9uCiAgICAgICAgZm9yIF8gaW4gcmFuZ2UoMTIpOgogICAgICAgICAgICByZW1haW5kZXIgPSAocmVtYWluZGVyIDw8IDEpIF4gKChyZW1haW5kZXIgPj4gMTEpICogMHgxRjI1KQogICAgICAgIGJpdHMgPSB2ZXJzaW9uIDw8IDEyIHwgcmVtYWluZGVyCiAgICAgICAgZm9yIGkgaW4gcmFuZ2UoMTgpOgogICAgICAgICAgICBhLCBiID0gc2l6ZSAtIDExICsgaSAlIDMsIGkgLy8gMwogICAgICAgICAgICBzZXRmKGEsIGIsIChiaXRzID4+IGkpICYgMSkKICAgICAgICAgICAgc2V0ZihiLCBhLCAoYml0cyA+PiBpKSAmIDEpCiAgICBpbmRleCA9IDAKICAgIHJpZ2h0ID0gc2l6ZSAtIDEKICAgIHdoaWxlIHJpZ2h0ID49IDE6CiAgICAgICAgaWYgcmlnaHQgPT0gNjoKICAgICAgICAgICAgcmlnaHQgPSA1CiAgICAgICAgZm9yIHZlcnRpY2FsIGluIHJhbmdlKHNpemUpOgogICAgICAgICAgICB5ID0gc2l6ZSAtIDEgLSB2ZXJ0aWNhbCBpZiAoKHJpZ2h0ICsgMSkgJiAyKSA9PSAwIGVsc2UgdmVydGljYWwKICAgICAgICAgICAgZm9yIHggaW4gKHJpZ2h0LCByaWdodCAtIDEpOgogICAgICAgICAgICAgICAgaWYgbm90IGZ1bmN0aW9uW3ldW3hdOgogICAgICAgICAgICAgICAgICAgIGRhcmsgPSBpbmRleCA8IGxlbih3b3JkcykgKiA4IGFuZCAoKHdvcmRzW2luZGV4IC8vIDhdID4+ICg3IC0gaW5kZXggJSA4KSkgJiAxKQogICAgICAgICAgICAgICAgICAgIG1vZHVsZXNbeV1beF0gPSBib29sKGRhcmspIF4gX21hc2sobWFzaywgeCwgeSkKICAgICAgICAgICAgICAgICAgICBpbmRleCArPSAxCiAgICAgICAgcmlnaHQgLT0gMgogICAgcmV0dXJuIG1vZHVsZXMKCgpkZWYgX2ZpbmRlcl9wZW5hbHR5KGxpbmUpOgogICAgIiIiUGVuYWx0eSBmb3IgZmluZGVyLWxpa2UgcnVuIHJhdGlvcywgaW5jbHVkaW5nIHNjYWxlZCBwYXR0ZXJucy4iIiIKICAgIHNpemUgPSBsZW4obGluZSkKICAgIHJ1bnMgPSBbXQogICAgZm9yIHZhbHVlIGluIFtGYWxzZV0gKiAoc2l6ZSAqIDQpICsgbGluZSArIFtGYWxzZV0gKiAoc2l6ZSAqIDQpOgogICAgICAgIGlmIHJ1bnMgYW5kIHJ1bnNbLTFdWzBdID09IHZhbHVlOgogICAgICAgICAgICBydW5zWy0xXVsxXSArPSAxCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcnVucy5hcHBlbmQoW3ZhbHVlLCAxXSkKICAgIHNjb3JlID0gMAogICAgZm9yIGkgaW4gcmFuZ2UoMSwgbGVuKHJ1bnMpIC0gNSk6CiAgICAgICAgaWYgbm90IHJ1bnNbaV1bMF06CiAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgdW5pdCA9IHJ1bnNbaV1bMV0KICAgICAgICBpZiBbclsxXSBmb3IgciBpbiBydW5zW2k6aSArIDVdXSAhPSBbdW5pdCwgdW5pdCwgMyAqIHVuaXQsIHVuaXQsIHVuaXRdOgogICAgICAgICAgICBjb250aW51ZQogICAgICAgIGlmIHJ1bnNbaSAtIDFdWzFdID49IDQgKiB1bml0OgogICAgICAgICAgICBzY29yZSArPSA0MAogICAgICAgIGlmIHJ1bnNbaSArIDVdWzFdID49IDQgKiB1bml0OgogICAgICAgICAgICBzY29yZSArPSA0MAogICAgcmV0dXJuIHNjb3JlCgoKZGVmIF9wZW5hbHR5KG1hdHJpeCk6CiAgICBzaXplID0gbGVuKG1hdHJpeCkKICAgIHNjb3JlID0gMAogICAgZm9yIGxpbmUgaW4gbGlzdChtYXRyaXgpICsgW2xpc3QoY29sKSBmb3IgY29sIGluIHppcCgqbWF0cml4KV06CiAgICAgICAgcnVuID0gMQogICAgICAgIGZvciBpIGluIHJhbmdlKDEsIHNpemUpOgogICAgICAgICAgICBpZiBsaW5lW2ldID09IGxpbmVbaSAtIDFdOgogICAgICAgICAgICAgICAgcnVuICs9IDEKICAgICAgICAgICAgICAgIGlmIHJ1biA9PSA1OgogICAgICAgICAgICAgICAgICAgIHNjb3JlICs9IDMKICAgICAgICAgICAgICAgIGVsaWYgcnVuID4gNToKICAgICAgICAgICAgICAgICAgICBzY29yZSArPSAxCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBydW4gPSAxCiAgICAgICAgc2NvcmUgKz0gX2ZpbmRlcl9wZW5hbHR5KGxpbmUpCiAgICBmb3IgeSBpbiByYW5nZShzaXplIC0gMSk6CiAgICAgICAgZm9yIHggaW4gcmFuZ2Uoc2l6ZSAtIDEpOgogICAgICAgICAgICBpZiBtYXRyaXhbeV1beF0gPT0gbWF0cml4W3ldW3ggKyAxXSA9PSBtYXRyaXhbeSArIDFdW3hdID09IG1hdHJpeFt5ICsgMV1beCArIDFdOgogICAgICAgICAgICAgICAgc2NvcmUgKz0gMwogICAgZGFyayA9IHN1bShzdW0ocm93KSBmb3Igcm93IGluIG1hdHJpeCkKICAgIHNjb3JlICs9IGFicyhkYXJrICogMjAgLSBzaXplICogc2l6ZSAqIDEwKSAvLyAoc2l6ZSAqIHNpemUpICogMTAKICAgIHJldHVybiBzY29yZQoKCmRlZiBlbmNvZGUoZGF0YTogYnl0ZXMpOgogICAgIiIiRW5jb2RlIGJ5dGVzIGludG8gYSBRUiBzeW1ib2wgYXQgZXJyb3IgY29ycmVjdGlvbiBsZXZlbCBNICh1cCB0byB2MTApLiIiIgogICAgaWYgbm90IGlzaW5zdGFuY2UoZGF0YSwgYnl0ZXMpOgogICAgICAgIHJhaXNlIFR5cGVFcnJvcigiZGF0YSBtdXN0IGJlIGJ5dGVzIikKICAgIGZvciB2ZXJzaW9uIGluIHJhbmdlKDEsIDExKToKICAgICAgICBjYXBhY2l0eSA9IChfcmF3X21vZHVsZXModmVyc2lvbikgLy8gOCAtIF9FQ0NbdmVyc2lvbl0gKiBfQkxPQ0tTW3ZlcnNpb25dKSAqIDgKICAgICAgICBjb3VudF9iaXRzID0gOCBpZiB2ZXJzaW9uIDwgMTAgZWxzZSAxNgogICAgICAgIGlmIGxlbihkYXRhKSA8IDEgPDwgY291bnRfYml0cyBhbmQgNCArIGNvdW50X2JpdHMgKyBsZW4oZGF0YSkgKiA4IDw9IGNhcGFjaXR5OgogICAgICAgICAgICB3b3JkcyA9IF9jb2Rld29yZHMoZGF0YSwgdmVyc2lvbikKICAgICAgICAgICAgcmV0dXJuIG1pbigoX3N5bWJvbCh2ZXJzaW9uLCB3b3JkcywgbWFzaykgZm9yIG1hc2sgaW4gcmFuZ2UoOCkpLCBrZXk9X3BlbmFsdHkpCiAgICByYWlzZSBWYWx1ZUVycm9yKCJkYXRhIHRvbyBsb25nIGZvciBRUiB2ZXJzaW9uIDEwIGF0IGVycm9yIGNvcnJlY3Rpb24gTSIpCgoKZGVmIHRvX3N2ZyhtYXRyaXgsIG1vZHVsZV9weD00KToKICAgICIiIlJlbmRlciBhIGJvb2xlYW4gc3ltYm9sIHdpdGggYSBmb3VyLW1vZHVsZSBxdWlldCB6b25lIGFzIGEgY29tcGFjdCBTVkcuIiIiCiAgICBzaXplID0gbGVuKG1hdHJpeCkKICAgIGlmIG5vdCBzaXplIG9yIGFueShsZW4ocm93KSAhPSBzaXplIGZvciByb3cgaW4gbWF0cml4KToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJtYXRyaXggbXVzdCBiZSBzcXVhcmUiKQogICAgaWYgdHlwZShtb2R1bGVfcHgpIGlzIG5vdCBpbnQgb3IgbW9kdWxlX3B4IDwgMToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJtb2R1bGVfcHggbXVzdCBiZSBhIHBvc2l0aXZlIGludGVnZXIiKQogICAgcGF0aHMgPSBbXQogICAgZm9yIHksIHJvdyBpbiBlbnVtZXJhdGUobWF0cml4KToKICAgICAgICB4ID0gMAogICAgICAgIHdoaWxlIHggPCBzaXplOgogICAgICAgICAgICBpZiBub3Qgcm93W3hdOgogICAgICAgICAgICAgICAgeCArPSAxCiAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICBzdGFydCA9IHgKICAgICAgICAgICAgd2hpbGUgeCA8IHNpemUgYW5kIHJvd1t4XToKICAgICAgICAgICAgICAgIHggKz0gMQogICAgICAgICAgICBwYXRocy5hcHBlbmQoIk0lZCAlZGglZHYxaC0lZHoiICUgKHN0YXJ0ICsgNCwgeSArIDQsIHggLSBzdGFydCwgeCAtIHN0YXJ0KSkKICAgIGV4dGVudCA9IHNpemUgKyA4CiAgICByZXR1cm4gKCc8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IiVkIiBoZWlnaHQ9IiVkIiAnCiAgICAgICAgICAgICd2aWV3Qm94PSIwIDAgJWQgJWQiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyI+JwogICAgICAgICAgICAnPHJlY3Qgd2lkdGg9IjEwMCUlIiBoZWlnaHQ9IjEwMCUlIiBmaWxsPSJ3aGl0ZSIvPicKICAgICAgICAgICAgJzxwYXRoIGZpbGw9ImJsYWNrIiBkPSIlcyIvPjwvc3ZnPlxuJykgJSAoZXh0ZW50ICogbW9kdWxlX3B4LCBleHRlbnQgKiBtb2R1bGVfcHgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVudCwgZXh0ZW50LCAnJy5qb2luKHBhdGhzKSkK #NALVO-VAST-HELPER-B64:IyEvdXNyL2Jpbi9weXRob24zCiIiIlJvb3Qtb25seSBWYXN0IGJyaWRnZS4gUmVxdWVzdHMgYW5kIHJlcGxpZXMgYXJlIHVudHJ1c3RlZCwgbmV2ZXIgY29tbWFuZHMuCgpUaGUgcmVsZWFzZSBrZXkgYW5kIHRoZSBGbGVldCBvcmlnaW4gYXJlIGluc3RhbGxlZCBpbmRlcGVuZGVudGx5IG9mIHRoZSBhZ2VudC4KT25lIGluc3RhbGwgYXR0ZW1wdCBwZXIgY29tcHV0ZXIuIFdoaWNoIGNvbXB1dGVyIG1heSB0cnkgZmlyc3QgaXMgdGhlIEZsZWV0J3MKcnVsZSAodGhlIGZpcnN0IGluc3RhbGwgb24gb25lIGlkbGUgY29tcHV0ZXIgaXMgdGhlIHRlc3QpLCBub3QgdGhpcyBmaWxlJ3MuCiIiIgppbXBvcnQgYmFzZTY0CmltcG9ydCBkYXRldGltZQppbXBvcnQgZGlmZmxpYgppbXBvcnQgc29ja2V0CmltcG9ydCBoYXNobGliCmltcG9ydCBobWFjCmltcG9ydCBqc29uCmltcG9ydCBvcwppbXBvcnQgcmUKaW1wb3J0IHNodXRpbAppbXBvcnQgc3RhdAppbXBvcnQgc3VicHJvY2VzcwppbXBvcnQgdGVtcGZpbGUKaW1wb3J0IHRpbWUKaW1wb3J0IHVybGxpYi5lcnJvcgppbXBvcnQgdXJsbGliLnJlcXVlc3QKCkZMRUVUID0gImh0dHBzOi8vZmxlZXQubmFsdm8uYWkiCklOU1RBTExFUiA9ICJodHRwczovL2NvbnNvbGUudmFzdC5haS9pbnN0YWxsIgpJTlNUQUxMRVJfUkVESVJFQ1QgPSAiaHR0cHM6Ly9zMy5hbWF6b25hd3MuY29tL3B1YmxpYy52YXN0LmFpL2thYWxpYS9zY3JpcHRzL3Zhc3RfaG9zdF9pbnN0YWxsZXIucHkiClNJR05FUlMgPSAiL2V0Yy9uYWx2by12YXN0L2FsbG93ZWRfc2lnbmVycyIKTk9ERV9ESVIgPSAiL3Zhci9saWIvbmFsdm8tbm9kZSIKU1RBVEUgPSAiL3Zhci9saWIvbmFsdm8tdmFzdCIKUlVOVElNRSA9ICIvcnVuL25hbHZvLXZhc3QiCkxPR19ESVIgPSAiL3Zhci9sb2cvbmFsdm8iCkRPQ0tFUiA9ICIvdmFyL2xpYi9kb2NrZXIiClZBU1QgPSAiL3Zhci9saWIvdmFzdGFpX2thYWxpYSIKTUFYX1JFUVVFU1QgPSA2NTUzNgpUT0tFTiA9IHJlLmNvbXBpbGUociJbQS1aYS16MC05XysvPS1dezE2LDUxMn1cWiIpCkhFWCA9IHJlLmNvbXBpbGUociJbMC05YS1mXXs2NH1cWiIpClNBRkVfSUQgPSByZS5jb21waWxlKHIiW0EtWmEtejAtOV8tXXsxLDgwfVxaIikKIyBGaXhlZCByb290LW93bmVkIGNvbmZpZ3VyYXRpb24gb25seTsgcmVxdWVzdCBkYXRhIG5ldmVyIGNob29zZXMgdGhlc2UgcGF0aHMuCkNPTkZJR19QQVRIUyA9ICgiL2V0Yy9kb2NrZXIvZGFlbW9uLmpzb24iLCAiL2V0Yy9jb250YWluZXJkL2NvbmZpZy50b21sIiwKICAgICAgICAgICAgICAgICIvZXRjL2FwdC9wcmVmZXJlbmNlcyIsICIvZXRjL2FwdC9wcmVmZXJlbmNlcy5kIikKIyB2ZXJpZnkoKTogb25seSB0aGVzZSBmaXZlIGRlY2lkZSBgdmVyaWZpZWRgOyB0aGUgZm91ciBhZHZpc29yeSBvbmVzIGFyZSByZWNvcmRlZCBhcyBldmlkZW5jZSBhbmQgbmV2ZXIgYmxvY2suClZFUklGWV9SRVFVSVJFRCA9ICgic2FtZV9kZXZpY2UiLCAibWFjaGluZV9udW1faWQiLCAiZGFlbW9uIiwgImZzdGFiIiwgInNzaCIpClZFUklGWV9BRFZJU09SWSA9ICgibmFsdm9fc3RvcmFnZSIsICJwb3J0cyIsICJkYWVtb25fZnJlc2giLCAiZ3B1X2NvbnRhaW5lciIpCiMgV2hlcmUgYSBEb2NrZXIgcHJvZ3JhbSB3b3VsZCBiZTsgd2l0aCBub25lIG9mIHRoZW0gdGhlcmUgaXMgbm8gRG9ja2VyLCBzbyBubyBjb250YWluZXIgY2FuIGJlIHJ1bm5pbmcuCkRPQ0tFUl9QUk9HUkFNUyA9ICgiL3Vzci9iaW4vZG9ja2VyIiwgIi91c3IvbG9jYWwvYmluL2RvY2tlciIsICIvc25hcC9iaW4vZG9ja2VyIiwgIi9iaW4vZG9ja2VyIikKCgpjbGFzcyBSZWZ1c2VkKEV4Y2VwdGlvbik6CiAgICBwYXNzCgoKZGVmIGNvbW1hbmQoYXJncywgdGltZW91dD0zMCwgaW5wdXRfYnl0ZXM9Tm9uZSk6CiAgICB0cnk6CiAgICAgICAgcCA9IHN1YnByb2Nlc3MucnVuKGFyZ3MsIGlucHV0PWlucHV0X2J5dGVzLCBzdGRvdXQ9c3VicHJvY2Vzcy5QSVBFLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzdGRlcnI9c3VicHJvY2Vzcy5ERVZOVUxMLCB0aW1lb3V0PXRpbWVvdXQsIGNoZWNrPUZhbHNlKQogICAgICAgIHJldHVybiBwLnJldHVybmNvZGUsIHAuc3Rkb3V0LmRlY29kZSgidXRmLTgiLCAicmVwbGFjZSIpWzo2NTUzNl0KICAgIGV4Y2VwdCAoT1NFcnJvciwgc3VicHJvY2Vzcy5UaW1lb3V0RXhwaXJlZCk6CiAgICAgICAgcmV0dXJuIDEsICIiCgoKZGVmIF9yZWFkX2ZkKGZkLCBsaW1pdCk6CiAgICBzdCA9IG9zLmZzdGF0KGZkKQogICAgaWYgbm90IHN0YXQuU19JU1JFRyhzdC5zdF9tb2RlKSBvciBzdC5zdF9ubGluayAhPSAxIG9yIHN0LnN0X3NpemUgPiBsaW1pdDoKICAgICAgICByYWlzZSBSZWZ1c2VkKCJ1bnNhZmUtZmlsZSIpCiAgICBkYXRhID0gYiIiCiAgICB3aGlsZSBsZW4oZGF0YSkgPD0gbGltaXQ6CiAgICAgICAgY2h1bmsgPSBvcy5yZWFkKGZkLCBtaW4oODE5MiwgbGltaXQgKyAxIC0gbGVuKGRhdGEpKSkKICAgICAgICBpZiBub3QgY2h1bms6CiAgICAgICAgICAgIGJyZWFrCiAgICAgICAgZGF0YSArPSBjaHVuawogICAgaWYgbGVuKGRhdGEpID4gbGltaXQ6CiAgICAgICAgcmFpc2UgUmVmdXNlZCgidW5zYWZlLWZpbGUiKQogICAgcmV0dXJuIGRhdGEKCgpkZWYgX29wZW5fZGlyKHBhdGgsIHBhcmVudD1Ob25lKToKICAgIHJldHVybiBvcy5vcGVuKHBhdGgsIG9zLk9fUkRPTkxZIHwgb3MuT19ESVJFQ1RPUlkgfCBnZXRhdHRyKG9zLCAiT19OT0ZPTExPVyIsIDApLCBkaXJfZmQ9cGFyZW50KQoKCmRlZiBfcmVhZF9hdChkaXJlY3RvcnksIG5hbWUsIGxpbWl0KToKICAgIGZkID0gb3Mub3BlbihuYW1lLCBvcy5PX1JET05MWSB8IGdldGF0dHIob3MsICJPX05PRk9MTE9XIiwgMCkgfCBnZXRhdHRyKG9zLCAiT19OT05CTE9DSyIsIDApLCBkaXJfZmQ9ZGlyZWN0b3J5KQogICAgdHJ5OgogICAgICAgIHJldHVybiBfcmVhZF9mZChmZCwgbGltaXQpCiAgICBmaW5hbGx5OgogICAgICAgIG9zLmNsb3NlKGZkKQoKCmRlZiBfcmVhZF9maXhlZChwYXRoLCBsaW1pdCk6CiAgICBmZCA9IG9zLm9wZW4ocGF0aCwgb3MuT19SRE9OTFkgfCBnZXRhdHRyKG9zLCAiT19OT0ZPTExPVyIsIDApIHwgZ2V0YXR0cihvcywgIk9fTk9OQkxPQ0siLCAwKSkKICAgIHRyeToKICAgICAgICByZXR1cm4gX3JlYWRfZmQoZmQsIGxpbWl0KQogICAgZmluYWxseToKICAgICAgICBvcy5jbG9zZShmZCkKCgpkZWYgX29iamVjdChkYXRhKToKICAgIGRlZiB1bmlxdWUocGFpcnMpOgogICAgICAgIHJlc3VsdCA9IHt9CiAgICAgICAgZm9yIGssIHYgaW4gcGFpcnM6CiAgICAgICAgICAgIGlmIGsgaW4gcmVzdWx0OgogICAgICAgICAgICAgICAgcmFpc2UgUmVmdXNlZCgiaW52YWxpZC1yZXF1ZXN0IikKICAgICAgICAgICAgcmVzdWx0W2tdID0gdgogICAgICAgIHJldHVybiByZXN1bHQKICAgIHRyeToKICAgICAgICByZXR1cm4ganNvbi5sb2FkcyhkYXRhLmRlY29kZSgidXRmLTgiKSwgb2JqZWN0X3BhaXJzX2hvb2s9dW5pcXVlKQogICAgZXhjZXB0IChWYWx1ZUVycm9yLCBVbmljb2RlRXJyb3IsIFJlY3Vyc2lvbkVycm9yKToKICAgICAgICByYWlzZSBSZWZ1c2VkKCJpbnZhbGlkLXJlcXVlc3QiKQoKCmRlZiBfaW50ZWdlcih4LCBsbz0xLCBoaT0yMTQ3NDgzNjQ3KToKICAgIHJldHVybiB0eXBlKHgpIGlzIGludCBhbmQgbG8gPD0geCA8PSBoaQoKCmRlZiB2YWxpZGF0ZShyZXF1ZXN0KToKICAgIGlmIHR5cGUocmVxdWVzdCkgaXMgbm90IGRpY3Qgb3IgcmVxdWVzdC5nZXQoIm9wZXJhdGlvbiIpIG5vdCBpbiAoImluc3BlY3QiLCAiaW5zdGFsbCIsICJ2ZXJpZnkiLCAic2NydWIiKToKICAgICAgICByYWlzZSBSZWZ1c2VkKCJpbnZhbGlkLXJlcXVlc3QiKQogICAgb3AgPSByZXF1ZXN0WyJvcGVyYXRpb24iXQogICAga2V5cyA9IHsib3BlcmF0aW9uIiwgInBsYW5faWQiLCAiYXR0ZW1wdCJ9CiAgICBpZiBvcCA9PSAiaW5zdGFsbCI6CiAgICAgICAga2V5cyB8PSB7InJ1bl9pZCIsICJwb3J0c19maXJzdCIsICJwb3J0c19sYXN0IiwgImluc3RhbGxlcl9zaGEyNTYiLCAiYWxsb3dsaXN0IiwgImFsbG93bGlzdF9zaWciLCAibGlidmlydCJ9CiAgICBpZiBzZXQocmVxdWVzdCkgIT0ga2V5czoKICAgICAgICByYWlzZSBSZWZ1c2VkKCJpbnZhbGlkLXJlcXVlc3QiKQogICAgaWYgbm90IF9pbnRlZ2VyKHJlcXVlc3RbInBsYW5faWQiXSkgb3Igbm90IF9pbnRlZ2VyKHJlcXVlc3RbImF0dGVtcHQiXSwgMSwgOTk5OTk5KToKICAgICAgICByYWlzZSBSZWZ1c2VkKCJpbnZhbGlkLXJlcXVlc3QiKQogICAgaWYgb3AgPT0gImluc3RhbGwiOgogICAgICAgIGlmIG5vdCBpc2luc3RhbmNlKHJlcXVlc3RbInJ1bl9pZCJdLCBzdHIpIG9yIG5vdCBTQUZFX0lELmZ1bGxtYXRjaChyZXF1ZXN0WyJydW5faWQiXSk6CiAgICAgICAgICAgIHJhaXNlIFJlZnVzZWQoImludmFsaWQtcmVxdWVzdCIpCiAgICAgICAgIyB0aGUgY29tcHV0ZXIncyBvd24gcmFuZ2UgKFBPUlRTLVNIQVBFUyAyLjQpOiA1IHRvIDEwMCBwb3J0cyBpbnNpZGUgMTAyNS02NTUzNQogICAgICAgIGEsIGIgPSByZXF1ZXN0WyJwb3J0c19maXJzdCJdLCByZXF1ZXN0WyJwb3J0c19sYXN0Il0KICAgICAgICBpZiBub3QgX2ludGVnZXIoYSwgMTAyNSwgNjU1MzUpIG9yIG5vdCBfaW50ZWdlcihiLCBhLCA2NTUzNSkgb3IgYiAtIGEgPCA0IG9yIGIgLSBhID4gOTk6CiAgICAgICAgICAgIHJhaXNlIFJlZnVzZWQoImludmFsaWQtcG9ydHMiKQogICAgaWYgb3AgPT0gImluc3RhbGwiOgogICAgICAgIGlmIHJlcXVlc3RbImxpYnZpcnQiXSBpcyBub3QgRmFsc2Ugb3Igbm90IGlzaW5zdGFuY2UocmVxdWVzdFsiaW5zdGFsbGVyX3NoYTI1NiJdLCBzdHIpIG9yIG5vdCBIRVguZnVsbG1hdGNoKHJlcXVlc3RbImluc3RhbGxlcl9zaGEyNTYiXSk6CiAgICAgICAgICAgIHJhaXNlIFJlZnVzZWQoImludmFsaWQtcmVxdWVzdCIpCiAgICAgICAgZm9yIGZpZWxkIGluICgiYWxsb3dsaXN0IiwgImFsbG93bGlzdF9zaWciKToKICAgICAgICAgICAgaWYgbm90IGlzaW5zdGFuY2UocmVxdWVzdFtmaWVsZF0sIHN0cikgb3IgbGVuKHJlcXVlc3RbZmllbGRdKSA+IDMyNzY4OgogICAgICAgICAgICAgICAgcmFpc2UgUmVmdXNlZCgiaW52YWxpZC1yZXF1ZXN0IikKICAgIHJldHVybiByZXF1ZXN0CgoKZGVmIF9hdG9taWNfYXQoZGlyZWN0b3J5LCBuYW1lLCBkYXRhLCBtb2RlPTBvNjQ0KToKICAgIHRlbXAgPSAiLnN0YXR1cy0iICsgb3MudXJhbmRvbSgxNikuaGV4KCkKICAgIGZkID0gb3Mub3Blbih0ZW1wLCBvcy5PX1dST05MWSB8IG9zLk9fQ1JFQVQgfCBvcy5PX0VYQ0wgfCBnZXRhdHRyKG9zLCAiT19OT0ZPTExPVyIsIDApLCBtb2RlLCBkaXJfZmQ9ZGlyZWN0b3J5KQogICAgdHJ5OgogICAgICAgIHdpdGggb3MuZmRvcGVuKGZkLCAid2IiKSBhcyBmOgogICAgICAgICAgICBmLndyaXRlKGRhdGEpCiAgICAgICAgICAgIGYuZmx1c2goKQogICAgICAgICAgICBvcy5mc3luYyhmLmZpbGVubygpKQogICAgICAgIG9zLnJlcGxhY2UodGVtcCwgbmFtZSwgc3JjX2Rpcl9mZD1kaXJlY3RvcnksIGRzdF9kaXJfZmQ9ZGlyZWN0b3J5KQogICAgZmluYWxseToKICAgICAgICB0cnk6CiAgICAgICAgICAgIG9zLnVubGluayh0ZW1wLCBkaXJfZmQ9ZGlyZWN0b3J5KQogICAgICAgIGV4Y2VwdCBGaWxlTm90Rm91bmRFcnJvcjoKICAgICAgICAgICAgcGFzcwoKCmRlZiBfcHJpdmF0ZShwYXRoLCBkYXRhKToKICAgIGRpcmVjdG9yeSA9IG9zLnBhdGguZGlybmFtZShwYXRoKQogICAgZmQsIHRtcCA9IHRlbXBmaWxlLm1rc3RlbXAocHJlZml4PSIubmV3LSIsIGRpcj1kaXJlY3RvcnkpCiAgICB0cnk6CiAgICAgICAgaWYgaGFzYXR0cihvcywgImZjaG1vZCIpOgogICAgICAgICAgICBvcy5mY2htb2QoZmQsIDBvNjAwKQogICAgICAgIHdpdGggb3MuZmRvcGVuKGZkLCAid2IiKSBhcyBmOgogICAgICAgICAgICBmLndyaXRlKGRhdGEpCiAgICAgICAgICAgIGYuZmx1c2goKQogICAgICAgICAgICBvcy5mc3luYyhmLmZpbGVubygpKQogICAgICAgIG9zLnJlcGxhY2UodG1wLCBwYXRoKQogICAgICAgICMgUGVyc2lzdCB0aGUgZGlyZWN0b3J5IGVudHJ5IGFzIHdlbGwgYXMgdGhlIGZpbGUgYmVmb3JlIGxhdW5jaGluZyB3b3JrLgogICAgICAgIGlmIG9zLm5hbWUgPT0gInBvc2l4IjoKICAgICAgICAgICAgZGlyZmQgPSBvcy5vcGVuKGRpcmVjdG9yeSwgb3MuT19SRE9OTFkgfCBnZXRhdHRyKG9zLCAiT19ESVJFQ1RPUlkiLCAwKSkKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgb3MuZnN5bmMoZGlyZmQpCiAgICAgICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgICAgICBvcy5jbG9zZShkaXJmZCkKICAgIGZpbmFsbHk6CiAgICAgICAgaWYgb3MucGF0aC5leGlzdHModG1wKToKICAgICAgICAgICAgb3MudW5saW5rKHRtcCkKCgpkZWYgX2pzb25fcHJpdmF0ZShwYXRoLCBvYmopOgogICAgX3ByaXZhdGUocGF0aCwgKGpzb24uZHVtcHMob2JqLCBzb3J0X2tleXM9VHJ1ZSwgc2VwYXJhdG9ycz0oIiwiLCAiOiIpKSArICJcbiIpLmVuY29kZSgpKQoKCmRlZiBhbGxvd2xpc3Rfb2socmVxLCAqLCBmZXRjaF9jdXJyZW50PUZhbHNlKToKICAgICIiIlZlcmlmeSB0aGUgam9iJ3Mgc2lnbmF0dXJlOyBpbnN0YWxscyBhbHNvIHJlcXVpcmUgY3VycmVudCBGbGVldCBieXRlcy4iIiIKICAgIHRyeToKICAgICAgICBhbGxvdyA9IGJhc2U2NC5iNjRkZWNvZGUocmVxWyJhbGxvd2xpc3QiXSwgdmFsaWRhdGU9VHJ1ZSkKICAgICAgICBzaWduYXR1cmUgPSByZXFbImFsbG93bGlzdF9zaWciXS5lbmNvZGUoImFzY2lpIikKICAgICAgICAjIFVzZSB0aGUgY3VycmVudCByZWxlYXNlJ3MgcmVhZC1vbmx5IGluc3RhbGxlciBmaWxlcywgbm90IGEgZG9jdW1lbnQKICAgICAgICAjIGNob3NlbiBieSB0aGUgdW5wcml2aWxlZ2VkIGpvYi4gUmVxdWlyZSB0aGUgam9iIHRvIHJlZmVyIHRvIHRob3NlCiAgICAgICAgIyBleGFjdCBieXRlcyBzbyBhIHJlbGVhc2UgY2hhbmdlIGZhaWxzIGNsb3NlZCB1bnRpbCBpdCBpcyByZXRyaWVkLgogICAgICAgIGlmIGZldGNoX2N1cnJlbnQ6CiAgICAgICAgICAgIHVybCA9IEZMRUVUICsgIi9pbnN0YWxsZXIvdmFzdC1pbnN0YWxsZXItYWxsb3dsaXN0Lmpzb24iCiAgICAgICAgICAgIGlmIChub3QgaG1hYy5jb21wYXJlX2RpZ2VzdChhbGxvdywgX2ZldGNoKHVybCwgbGltaXQ9NjU1MzYpKQogICAgICAgICAgICAgICAgICAgIG9yIG5vdCBobWFjLmNvbXBhcmVfZGlnZXN0KHNpZ25hdHVyZSwgX2ZldGNoKHVybCArICIuc2lnIiwgbGltaXQ9ODE5MikpKToKICAgICAgICAgICAgICAgIHJldHVybiBGYWxzZQogICAgICAgIG9iaiA9IF9vYmplY3QoYWxsb3cpCiAgICAgICAgaWYgdHlwZShvYmopIGlzIG5vdCBkaWN0IG9yIHNldChvYmopICE9IHsiZm9ybWF0IiwgInNoYTI1NiJ9IG9yIHR5cGUob2JqWyJmb3JtYXQiXSkgaXMgbm90IGludCBvciBvYmpbImZvcm1hdCJdICE9IDE6CiAgICAgICAgICAgIHJldHVybiBGYWxzZQogICAgICAgIGhhc2hlcyA9IG9ialsic2hhMjU2Il0KICAgICAgICBpZiB0eXBlKGhhc2hlcykgaXMgbm90IGxpc3Qgb3Igbm90IGhhc2hlcyBvciBhbnkodHlwZSh4KSBpcyBub3Qgc3RyIG9yIG5vdCBIRVguZnVsbG1hdGNoKHgpIGZvciB4IGluIGhhc2hlcyk6CiAgICAgICAgICAgIHJldHVybiBGYWxzZQogICAgICAgIGlmIHJlcVsiaW5zdGFsbGVyX3NoYTI1NiJdIG5vdCBpbiBoYXNoZXM6CiAgICAgICAgICAgIHJldHVybiBGYWxzZQogICAgICAgICMgT25seSB0aGUgc2lnbmF0dXJlIGlzIHRyYW5zaWVudCBvbiBkaXNrLCBpbiB0aGUgcm9vdC1vbmx5IHJ1bnRpbWUgZGlyZWN0b3J5LgogICAgICAgIGZkLCBzaWdwYXRoID0gdGVtcGZpbGUubWtzdGVtcChwcmVmaXg9InNpZy0iLCBkaXI9UlVOVElNRSkKICAgICAgICB0cnk6CiAgICAgICAgICAgIHdpdGggb3MuZmRvcGVuKGZkLCAid2IiKSBhcyBmOgogICAgICAgICAgICAgICAgZi53cml0ZShzaWduYXR1cmUpCiAgICAgICAgICAgIGNvZGUsIF8gPSBjb21tYW5kKFsic3NoLWtleWdlbiIsICItWSIsICJ2ZXJpZnkiLCAiLWYiLCBTSUdORVJTLCAiLUkiLCAicmVsZWFzZUBuYWx2by5haSIsICItbiIsICJuYWx2by1yZWxlYXNlIiwgIi1zIiwgc2lncGF0aF0sIGlucHV0X2J5dGVzPWFsbG93KQogICAgICAgICAgICByZXR1cm4gY29kZSA9PSAwCiAgICAgICAgZmluYWxseToKICAgICAgICAgICAgb3MudW5saW5rKHNpZ3BhdGgpCiAgICBleGNlcHQgKE9TRXJyb3IsIFZhbHVlRXJyb3IsIFJlZnVzZWQsIHVybGxpYi5lcnJvci5VUkxFcnJvcik6CiAgICAgICAgcmV0dXJuIEZhbHNlCgoKZGVmIGRvY2tlcl9tb3VudCgpOgogICAgcmMsIHNvdXJjZSA9IGNvbW1hbmQoWyJmaW5kbW50IiwgIi1ubyIsICJTT1VSQ0UiLCBET0NLRVJdKQogICAgcmMyLCBkZXRhaWxzID0gY29tbWFuZChbImZpbmRtbnQiLCAiLW5ibyIsICJTT1VSQ0UsVEFSR0VULEZTVFlQRSxPUFRJT05TLFNJWkUiLCAiLS1tb3VudHBvaW50IiwgRE9DS0VSXSkKICAgIHBhcnRzID0gZGV0YWlscy5zdHJpcCgpLnNwbGl0KCkKICAgIGlmIHJjIG9yIHJjMiBvciBsZW4ocGFydHMpICE9IDU6CiAgICAgICAgcmFpc2UgUmVmdXNlZCgic3RvcmFnZSIpCiAgICBzcmMsIHRhcmdldCwgZnN0eXBlLCBvcHRpb25zLCBzaXplID0gcGFydHMKICAgIGlmIHNvdXJjZS5zdHJpcCgpICE9IHNyYyBvciB0YXJnZXQgIT0gRE9DS0VSIG9yIGZzdHlwZSAhPSAieGZzIjoKICAgICAgICByYWlzZSBSZWZ1c2VkKCJzdG9yYWdlIikKICAgIGlmIG5vdCBzcmMuc3RhcnRzd2l0aCgoIi9kZXYvbWFwcGVyLyIsICIvZGV2L2RtLSIpKSBvciBub3QgKHsicHF1b3RhIiwgInByanF1b3RhIn0gJiBzZXQob3B0aW9ucy5zcGxpdCgiLCIpKSk6CiAgICAgICAgcmFpc2UgUmVmdXNlZCgic3RvcmFnZSIpCiAgICBpZiBub3Qgc2l6ZS5pc2RpZ2l0KCkgb3IgaW50KHNpemUpIDwgMjAwXzAwMF8wMDBfMDAwOgogICAgICAgIHJhaXNlIFJlZnVzZWQoInN0b3JhZ2UiKQogICAgIyBSZXNvbHZlIHRoZSBtb3VudCBkZXZpY2UgdHdpY2UgaW1tZWRpYXRlbHkgYmVmb3JlIHVzZSwgbm90IGZyb20gdGhlIHJlcXVlc3QuCiAgICByYzMsIGN1cnJlbnQgPSBjb21tYW5kKFsiZmluZG1udCIsICItbm8iLCAiU09VUkNFIiwgRE9DS0VSXSkKICAgIGlmIHJjMyBvciBjdXJyZW50LnN0cmlwKCkgIT0gc3JjOgogICAgICAgIHJhaXNlIFJlZnVzZWQoInN0b3JhZ2UiKQogICAgcmV0dXJuIHNyYwoKCmRlZiBfbWFjaGluZV9udW0oKToKICAgIHRyeToKICAgICAgICB2YWx1ZSA9IF9yZWFkX2ZpeGVkKG9zLnBhdGguam9pbihWQVNULCAibWFjaGluZV9udW1faWQiKSwgNjQpLmRlY29kZSgiYXNjaWkiKS5zdHJpcCgpCiAgICAgICAgcmV0dXJuIGludCh2YWx1ZSkgaWYgdmFsdWUuaXNkaWdpdCgpIGFuZCBpbnQodmFsdWUpID4gMCBlbHNlIE5vbmUKICAgIGV4Y2VwdCAoT1NFcnJvciwgVW5pY29kZUVycm9yLCBSZWZ1c2VkKToKICAgICAgICByZXR1cm4gTm9uZQoKCmRlZiBfZHBrZ191bmxvY2tlZCgpOgogICAgdHJ5OgogICAgICAgIGltcG9ydCBmY250bAogICAgICAgIGhhbmRsZXMgPSBbXQogICAgICAgIHRyeToKICAgICAgICAgICAgZm9yIHBhdGggaW4gKCIvdmFyL2xpYi9kcGtnL2xvY2siLCAiL3Zhci9saWIvZHBrZy9sb2NrLWZyb250ZW5kIik6CiAgICAgICAgICAgICAgICBmZCA9IG9zLm9wZW4ocGF0aCwgb3MuT19SRFdSIHwgZ2V0YXR0cihvcywgIk9fTk9GT0xMT1ciLCAwKSkKICAgICAgICAgICAgICAgIGhhbmRsZXMuYXBwZW5kKGZkKQogICAgICAgICAgICAgICAgZmNudGwubG9ja2YoZmQsIGZjbnRsLkxPQ0tfRVggfCBmY250bC5MT0NLX05CKQogICAgICAgICAgICByZXR1cm4gVHJ1ZQogICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgIGZvciBmZCBpbiBoYW5kbGVzOgogICAgICAgICAgICAgICAgb3MuY2xvc2UoZmQpCiAgICBleGNlcHQgKEltcG9ydEVycm9yLCBPU0Vycm9yKToKICAgICAgICByZXR1cm4gRmFsc2UKCgpkZWYgX25ldHdvcmtfcmVhZHkoKToKICAgICMgVExTIGhhbmRzaGFrZSBhbmQgRE5TIGFyZSB0ZXN0ZWQgYWdhaW5zdCB0aGVzZSBmaXhlZCBob3N0cywgd2l0aG91dAogICAgIyBhY2NlcHRpbmcgYSByZWRpcmVjdCBvciByZWFkaW5nIHJlc3BvbnNlIGJvZGllcyBpbnRvIHRoZSBzdGF0dXMuCiAgICBmb3IgaG9zdCBpbiAoImNvbnNvbGUudmFzdC5haSIsICJzMy5hbWF6b25hd3MuY29tIiwgImRvd25sb2FkLmRvY2tlci5jb20iLCAibnZpZGlhLmdpdGh1Yi5pbyIpOgogICAgICAgIHRyeToKICAgICAgICAgICAgc29ja2V0LmdldGFkZHJpbmZvKGhvc3QsIDQ0MywgdHlwZT1zb2NrZXQuU09DS19TVFJFQU0pCiAgICAgICAgICAgIHJlcSA9IHVybGxpYi5yZXF1ZXN0LlJlcXVlc3QoImh0dHBzOi8vIiArIGhvc3QgKyAiLyIsIG1ldGhvZD0iSEVBRCIpCiAgICAgICAgICAgIG9wZW5lciA9IHVybGxpYi5yZXF1ZXN0LmJ1aWxkX29wZW5lcihfUmVkaXJlY3RzKE5vbmUpKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB3aXRoIG9wZW5lci5vcGVuKHJlcSwgdGltZW91dD01KToKICAgICAgICAgICAgICAgICAgICBwYXNzCiAgICAgICAgICAgIGV4Y2VwdCB1cmxsaWIuZXJyb3IuSFRUUEVycm9yOgogICAgICAgICAgICAgICAgcGFzcyAgIyBUaGUgSFRUUFMgc2VydmVyIGFuc3dlcmVkIGV2ZW4gaWYgSEVBRCBpcyBub3Qgc3VwcG9ydGVkLgogICAgICAgIGV4Y2VwdCAoT1NFcnJvciwgdXJsbGliLmVycm9yLlVSTEVycm9yLCBSZWZ1c2VkKToKICAgICAgICAgICAgcmV0dXJuIEZhbHNlCiAgICByZXR1cm4gVHJ1ZQoKCmRlZiBfZG9ja2VyX3ByZXNlbnQoKToKICAgICIiIkEgRG9ja2VyIHByb2dyYW0gaXMgaW5zdGFsbGVkIChvbiB0aGUgc2VydmljZSdzIFBBVEggb3IgYXQgYSB1c3VhbCBwbGFjZSkuIiIiCiAgICByZXR1cm4gc2h1dGlsLndoaWNoKCJkb2NrZXIiKSBpcyBub3QgTm9uZSBvciBhbnkob3MucGF0aC5pc2ZpbGUocCkgZm9yIHAgaW4gRE9DS0VSX1BST0dSQU1TKQoKCmRlZiBpbnNwZWN0KCk6CiAgICBjaGVja3MgPSB7fQogICAgdHJ5OgogICAgICAgIG9zX3JlbGVhc2UgPSBfcmVhZF9maXhlZCgiL3Vzci9saWIvb3MtcmVsZWFzZSIsIDgxOTIpLmRlY29kZSgidXRmLTgiLCAicmVwbGFjZSIpCiAgICAgICAgY2hlY2tzWyJ1YnVudHVfMjQwNCJdID0gYm9vbChyZS5zZWFyY2gocicoP20pXklEPXVidW50dSQnLCBvc19yZWxlYXNlKSBhbmQgcmUuc2VhcmNoKHInKD9tKV5WRVJTSU9OX0lEPVsiXCddPzI0XC4wNFsiXCddPyQnLCBvc19yZWxlYXNlKSkKICAgIGV4Y2VwdCAoT1NFcnJvciwgUmVmdXNlZCk6CiAgICAgICAgY2hlY2tzWyJ1YnVudHVfMjQwNCJdID0gRmFsc2UKICAgIHJjLCBzbWkgPSBjb21tYW5kKFsibnZpZGlhLXNtaSIsICItLXF1ZXJ5LWdwdT1uYW1lLG1lbW9yeS50b3RhbCIsICItLWZvcm1hdD1jc3Ysbm9oZWFkZXIsbm91bml0cyJdKQogICAgcm93cyA9IFt4LnN0cmlwKCkucnNwbGl0KCIsIiwgMSkgZm9yIHggaW4gc21pLnNwbGl0bGluZXMoKSBpZiB4LnN0cmlwKCldCiAgICB0cnk6CiAgICAgICAgZ3B1cyA9IFsoYS5zdHJpcCgpLCBpbnQoYi5zdHJpcCgpKSkgZm9yIGEsIGIgaW4gcm93c10KICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgIGdwdXMgPSBbXQogICAgY2hlY2tzWyJncHUiXSA9IHJjID09IDAgYW5kIGJvb2woZ3B1cykgYW5kIGxlbihzZXQoZ3B1cykpID09IDEgYW5kIGFsbChtID4gNzE2OCBmb3IgXywgbSBpbiBncHVzKQogICAgY2hlY2tzWyJjb3JlcyJdID0gYm9vbChncHVzKSBhbmQgKG9zLmNwdV9jb3VudCgpIG9yIDApID49IDIgKiBsZW4oZ3B1cykKICAgIHRyeToKICAgICAgICBtZW0gPSBfcmVhZF9maXhlZCgiL3Byb2MvbWVtaW5mbyIsIDgxOTIpLmRlY29kZSgpCiAgICAgICAgbWF0Y2ggPSByZS5zZWFyY2gociIoP20pXk1lbVRvdGFsOlxzKyhcZCspXHMra0IiLCBtZW0pCiAgICAgICAgY2hlY2tzWyJyYW0iXSA9IGJvb2wobWF0Y2ggYW5kIGdwdXMgYW5kIGludChtYXRjaC5ncm91cCgxKSkgKiAxMDI0ID49IHN1bSh4WzFdIGZvciB4IGluIGdwdXMpICogMTAyNCAqIDEwMjQgKiAuOTUpCiAgICBleGNlcHQgKE9TRXJyb3IsIFJlZnVzZWQpOgogICAgICAgIGNoZWNrc1sicmFtIl0gPSBGYWxzZQogICAgcmMsIGN1ZGEgPSBjb21tYW5kKFsibnZpZGlhLXNtaSJdKQogICAgbWF0Y2ggPSByZS5zZWFyY2gociJDVURBIFZlcnNpb246XHMqKFxkKylcLihcZCspIiwgY3VkYSkKICAgIGNoZWNrc1siY3VkYSJdID0gcmMgPT0gMCBhbmQgYm9vbChtYXRjaCBhbmQgKGludChtYXRjaC5ncm91cCgxKSksIGludChtYXRjaC5ncm91cCgyKSkpID49ICgxMSwgOCkpCiAgICByYywgc2VjdXJlID0gY29tbWFuZChbIm1va3V0aWwiLCAiLS1zYi1zdGF0ZSJdKQogICAgY2hlY2tzWyJzZWN1cmVfYm9vdF9vZmYiXSA9IHJjID09IDAgYW5kICJzZWN1cmVib290IGRpc2FibGVkIiBpbiBzZWN1cmUubG93ZXIoKQogICAgdHJ5OgogICAgICAgIHNvdXJjZSA9IGRvY2tlcl9tb3VudCgpCiAgICAgICAgY2hlY2tzWyJzdG9yYWdlIl0gPSBUcnVlCiAgICBleGNlcHQgUmVmdXNlZDoKICAgICAgICBzb3VyY2UgPSBOb25lCiAgICAgICAgY2hlY2tzWyJzdG9yYWdlIl0gPSBGYWxzZQogICAgdHJ5OgogICAgICAgIGNoZWNrc1sicm9vdF9mcmVlIl0gPSBzaHV0aWwuZGlza191c2FnZSgiLyIpLmZyZWUgPj0gMjBfMDAwXzAwMF8wMDAKICAgIGV4Y2VwdCBPU0Vycm9yOgogICAgICAgIGNoZWNrc1sicm9vdF9mcmVlIl0gPSBGYWxzZQogICAgcmMsIHNzaCA9IGNvbW1hbmQoWyJzc2hkIiwgIi1UIl0pCiAgICBjaGVja3NbInNzaCJdID0gcmMgPT0gMCBhbmQgInBhc3N3b3JkYXV0aGVudGljYXRpb24gbm8iIGluIHNzaCBhbmQgImtiZGludGVyYWN0aXZlYXV0aGVudGljYXRpb24gbm8iIGluIHNzaAogICAgcmMsIF8gPSBjb21tYW5kKFsicHl0aG9uMyIsICItSSIsICItYyIsICJpbXBvcnQgcmVxdWVzdHMiXSkKICAgIGNoZWNrc1sicmVxdWVzdHMiXSA9IHJjID09IDAKICAgIHJjLCBhdWRpdCA9IGNvbW1hbmQoWyJkcGtnIiwgIi0tYXVkaXQiXSkKICAgIGNoZWNrc1siZHBrZ19jbGVhbiJdID0gcmMgPT0gMCBhbmQgbm90IGF1ZGl0LnN0cmlwKCkKICAgIGNoZWNrc1sicmVib290X2NsZWFyIl0gPSBub3Qgb3MucGF0aC5leGlzdHMoIi92YXIvcnVuL3JlYm9vdC1yZXF1aXJlZCIpCiAgICByYywgbnRwID0gY29tbWFuZChbInRpbWVkYXRlY3RsIiwgInNob3ciLCAiLS1wcm9wZXJ0eT1OVFBTeW5jaHJvbml6ZWQiLCAiLS12YWx1ZSJdKQogICAgY2hlY2tzWyJudHAiXSA9IHJjID09IDAgYW5kIG50cC5zdHJpcCgpLmxvd2VyKCkgPT0gInllcyIKICAgIGNoZWNrc1siZHBrZ191bmxvY2tlZCJdID0gX2Rwa2dfdW5sb2NrZWQoKQogICAgY2hlY2tzWyJuZXR3b3JrIl0gPSBfbmV0d29ya19yZWFkeSgpCiAgICAjIE5vIHJ1bm5pbmcgY29udGFpbmVyIG9yIEdQVSBwcm9jZXNzIGlzIGEgY29uc2VydmF0aXZlIGlkbGUgY2hlY2suIEEgY29tcHV0ZXIgd2l0aCBubyBEb2NrZXIgYXQgYWxsIHJ1bnMgbm8KICAgICMgY29udGFpbmVyOyBhIERvY2tlciB0aGF0IGlzIHRoZXJlIGFuZCBjYW5ub3QgYW5zd2VyIGlzIHVua25vd24sIG5ldmVyIGlkbGUuCiAgICBpZiBfZG9ja2VyX3ByZXNlbnQoKToKICAgICAgICByYzEsIGNvbnRhaW5lcnMgPSBjb21tYW5kKFsiZG9ja2VyIiwgInBzIiwgIi1xIl0pCiAgICBlbHNlOgogICAgICAgIHJjMSwgY29udGFpbmVycyA9IDAsICIiCiAgICByYzIsIHByb2Nlc3NlcyA9IGNvbW1hbmQoWyJudmlkaWEtc21pIiwgIi0tcXVlcnktY29tcHV0ZS1hcHBzPXBpZCIsICItLWZvcm1hdD1jc3Ysbm9oZWFkZXIsbm91bml0cyJdKQogICAgY2hlY2tzWyJuYWx2b19pZGxlIl0gPSByYzEgPT0gMCBhbmQgcmMyID09IDAgYW5kIG5vdCBjb250YWluZXJzLnN0cmlwKCkgYW5kIG5vdCBwcm9jZXNzZXMuc3RyaXAoKQogICAgcmMsIF8gPSBjb21tYW5kKFsic3lzdGVtY3RsIiwgImlzLWFjdGl2ZSIsICItLXF1aWV0IiwgInZhc3RhaSJdKQogICAgcmV0dXJuIHsiY2hlY2tzIjogY2hlY2tzLCAiZG9ja2VyX3NvdXJjZSI6IHNvdXJjZSwgIm1hY2hpbmVfbnVtX2lkIjogX21hY2hpbmVfbnVtKCksICJ2YXN0X2FjdGl2ZSI6IHJjID09IDAsCiAgICAgICAgICAgICJpbnN0YWxsX2hpc3RvcnkiOiBfaW5zdGFsbF9oaXN0b3J5KCl9CgoKZGVmIF9zdHJlYW0oa2V5LCBub25jZSwgbGVuZ3RoKToKICAgIG91dCA9IGJ5dGVhcnJheSgpCiAgICBuID0gMAogICAgd2hpbGUgbGVuKG91dCkgPCBsZW5ndGg6CiAgICAgICAgb3V0LmV4dGVuZChoYXNobGliLmJsYWtlMmIobm9uY2UgKyBuLnRvX2J5dGVzKDgsICJiaWciKSwga2V5PWtleSwgZGlnZXN0X3NpemU9NjQpLmRpZ2VzdCgpKQogICAgICAgIG4gKz0gMQogICAgcmV0dXJuIGJ5dGVzKG91dFs6bGVuZ3RoXSkKCgpkZWYgX25vZGVfY3JlZGVudGlhbHMoKToKICAgIHJvb3QgPSBfb3Blbl9kaXIoTk9ERV9ESVIpCiAgICB0cnk6CiAgICAgICAgY2ZnID0gX29iamVjdChfcmVhZF9hdChyb290LCAiY29uZmlnLmpzb24iLCA2NTUzNikpCiAgICAgICAgbm9kZV9pZCwgdG9rZW4gPSBjZmcuZ2V0KCJub2RlX2lkIiksIGNmZy5nZXQoIm5vZGVfdG9rZW5fcHJvdGVjdGVkIikKICAgICAgICBpZiBub3QgX2ludGVnZXIobm9kZV9pZCkgb3Igbm90IGlzaW5zdGFuY2UodG9rZW4sIHN0cik6CiAgICAgICAgICAgIHJhaXNlIFJlZnVzZWQoIm5vZGUtY3JlZGVudGlhbHMiKQogICAgICAgIGlmIHRva2VuLnN0YXJ0c3dpdGgoImxvY2FsOiIpOgogICAgICAgICAgICByYXcgPSBiYXNlNjQuYjY0ZGVjb2RlKHRva2VuWzY6XSwgdmFsaWRhdGU9VHJ1ZSkKICAgICAgICAgICAga2V5ID0gX3JlYWRfYXQocm9vdCwgImFnZW50LmtleSIsIDMyKQogICAgICAgICAgICBpZiBsZW4oa2V5KSAhPSAzMiBvciBsZW4ocmF3KSA8IDQ4OgogICAgICAgICAgICAgICAgcmFpc2UgUmVmdXNlZCgibm9kZS1jcmVkZW50aWFscyIpCiAgICAgICAgICAgIG5vbmNlLCBib2R5LCBtYWMgPSByYXdbOjE2XSwgcmF3WzE2Oi0zMl0sIHJhd1stMzI6XQogICAgICAgICAgICBpZiBub3QgaG1hYy5jb21wYXJlX2RpZ2VzdChtYWMsIGhhc2hsaWIuYmxha2UyYihub25jZSArIGJvZHksIGtleT1rZXksIGRpZ2VzdF9zaXplPTMyKS5kaWdlc3QoKSk6CiAgICAgICAgICAgICAgICByYWlzZSBSZWZ1c2VkKCJub2RlLWNyZWRlbnRpYWxzIikKICAgICAgICAgICAgdG9rZW4gPSBieXRlcyhhIF4gYiBmb3IgYSwgYiBpbiB6aXAoYm9keSwgX3N0cmVhbShrZXksIG5vbmNlLCBsZW4oYm9keSkpKSkuZGVjb2RlKCJ1dGYtOCIpCiAgICAgICAgZWxpZiB0b2tlbi5zdGFydHN3aXRoKCJwbGFpbjoiKToKICAgICAgICAgICAgdG9rZW4gPSB0b2tlbls2Ol0KICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBSZWZ1c2VkKCJub2RlLWNyZWRlbnRpYWxzIikKICAgICAgICBpZiBub3QgVE9LRU4uZnVsbG1hdGNoKHRva2VuKToKICAgICAgICAgICAgcmFpc2UgUmVmdXNlZCgibm9kZS1jcmVkZW50aWFscyIpCiAgICAgICAgcmV0dXJuIG5vZGVfaWQsIHRva2VuCiAgICBmaW5hbGx5OgogICAgICAgIG9zLmNsb3NlKHJvb3QpCgoKY2xhc3MgX1JlZGlyZWN0cyh1cmxsaWIucmVxdWVzdC5IVFRQUmVkaXJlY3RIYW5kbGVyKToKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBhbGxvd2VkKToKICAgICAgICBzZWxmLmFsbG93ZWQgPSBhbGxvd2VkCiAgICBkZWYgcmVkaXJlY3RfcmVxdWVzdChzZWxmLCByZXEsIGZwLCBjb2RlLCBtc2csIGhlYWRlcnMsIG5ld3VybCk6CiAgICAgICAgaWYgcmVxLmZ1bGxfdXJsICE9IElOU1RBTExFUiBvciBuZXd1cmwgIT0gc2VsZi5hbGxvd2VkOgogICAgICAgICAgICByYWlzZSBSZWZ1c2VkKCJ1bmV4cGVjdGVkLXJlZGlyZWN0IikKICAgICAgICByZXR1cm4gc3VwZXIoKS5yZWRpcmVjdF9yZXF1ZXN0KHJlcSwgZnAsIGNvZGUsIG1zZywgaGVhZGVycywgbmV3dXJsKQoKCmRlZiBfZmV0Y2godXJsLCBkYXRhPU5vbmUsIGxpbWl0PTE2ICogMTAyNCAqIDEwMjQsIHJlZGlyZWN0PU5vbmUpOgogICAgb3BlbmVyID0gdXJsbGliLnJlcXVlc3QuYnVpbGRfb3BlbmVyKF9SZWRpcmVjdHMocmVkaXJlY3QpKQogICAgcmVxID0gdXJsbGliLnJlcXVlc3QuUmVxdWVzdCh1cmwsIGRhdGE9ZGF0YSwgaGVhZGVycz17IkNvbnRlbnQtVHlwZSI6ICJhcHBsaWNhdGlvbi9qc29uIn0sIG1ldGhvZD0iUE9TVCIgaWYgZGF0YSBpcyBub3QgTm9uZSBlbHNlICJHRVQiKQogICAgd2l0aCBvcGVuZXIub3BlbihyZXEsIHRpbWVvdXQ9NjApIGFzIHJlc3BvbnNlOgogICAgICAgIGJvZHkgPSByZXNwb25zZS5yZWFkKGxpbWl0ICsgMSkKICAgIGlmIGxlbihib2R5KSA+IGxpbWl0OgogICAgICAgIHJhaXNlIFJlZnVzZWQoInJlc3BvbnNlLXRvby1sYXJnZSIpCiAgICByZXR1cm4gYm9keQoKCmRlZiBfZ2V0X2tleShyZXEpOgogICAgbm9kZV9pZCwgdG9rZW4gPSBfbm9kZV9jcmVkZW50aWFscygpCiAgICBkYXRhID0ganNvbi5kdW1wcyh7Im5vZGVfaWQiOiBub2RlX2lkLCAibm9kZV90b2tlbiI6IHRva2VuLCAicnVuX2lkIjogcmVxWyJydW5faWQiXSwgImF0dGVtcHQiOiByZXFbImF0dGVtcHQiXX0sIHNlcGFyYXRvcnM9KCIsIiwgIjoiKSkuZW5jb2RlKCkKICAgIHJlc3BvbnNlID0gX29iamVjdChfZmV0Y2goRkxFRVQgKyAiL2FwaS9hZ2VudC92YXN0LWluc3RhbGwtYXV0aCIsIGRhdGE9ZGF0YSwgbGltaXQ9NDA5NikpCiAgICBrZXkgPSByZXNwb25zZS5nZXQoImtleSIpIGlmIHR5cGUocmVzcG9uc2UpIGlzIGRpY3QgZWxzZSBOb25lCiAgICBpZiBub3QgaXNpbnN0YW5jZShrZXksIHN0cikgb3Igbm90IFRPS0VOLmZ1bGxtYXRjaChrZXkpOgogICAgICAgIHJhaXNlIFJlZnVzZWQoImtleS11bmF2YWlsYWJsZSIpCiAgICByZXR1cm4ga2V5CgoKZGVmIF9zbmFwc2hvdCgpOgogICAgYmFja3VwID0gb3MucGF0aC5qb2luKFNUQVRFLCAiYmVmb3JlIikKICAgIG9zLm1ha2VkaXJzKGJhY2t1cCwgbW9kZT0wbzcwMCwgZXhpc3Rfb2s9VHJ1ZSkKICAgIHBhdGhzID0gWyIvZXRjL2ZzdGFiIiwgIi9ldGMvc3Vkb2VycyIsICIvZXRjL2RvY2tlci9kYWVtb24uanNvbiIsICIvZXRjL2NvbnRhaW5lcmQvY29uZmlnLnRvbWwiLCAiL2V0Yy9hcHQvc291cmNlcy5saXN0IiwgIi9ldGMvYXB0L3NvdXJjZXMubGlzdC5kIiwgIi9ldGMvYXB0L3ByZWZlcmVuY2VzIiwgIi9ldGMvYXB0L3ByZWZlcmVuY2VzLmQiLCAiL2V0Yy9zeXN0ZW1kL3N5c3RlbS9kb2NrZXIuc2VydmljZS5kL25hbHZvLXN0b3JhZ2UuY29uZiJdCiAgICBmb3IgcGF0aCBpbiBwYXRoczoKICAgICAgICBkZXN0ID0gb3MucGF0aC5qb2luKGJhY2t1cCwgcGF0aC5sc3RyaXAoIi8iKS5yZXBsYWNlKCIvIiwgIl9fIikpCiAgICAgICAgaWYgb3MucGF0aC5pc2ZpbGUocGF0aCkgYW5kIG5vdCBvcy5wYXRoLmlzbGluayhwYXRoKToKICAgICAgICAgICAgc2h1dGlsLmNvcHlmaWxlKHBhdGgsIGRlc3QpCiAgICAgICAgICAgIG9zLmNobW9kKGRlc3QsIDBvNjAwKQogICAgICAgIGVsaWYgb3MucGF0aC5pc2RpcihwYXRoKSBhbmQgbm90IG9zLnBhdGguaXNsaW5rKHBhdGgpOgogICAgICAgICAgICBzaHV0aWwuY29weXRyZWUocGF0aCwgZGVzdCwgZGlyc19leGlzdF9vaz1UcnVlLCBzeW1saW5rcz1UcnVlKQogICAgcmMsIHBhY2thZ2VzID0gY29tbWFuZChbImRwa2ctcXVlcnkiLCAiLVciLCAiLWY9JHtiaW5hcnk6UGFja2FnZX0gJHtWZXJzaW9ufVxcbiJdLCB0aW1lb3V0PTYwKQogICAgaWYgcmM6CiAgICAgICAgcmFpc2UgUmVmdXNlZCgic25hcHNob3QiKQogICAgX3ByaXZhdGUob3MucGF0aC5qb2luKGJhY2t1cCwgInBhY2thZ2VzIiksIHBhY2thZ2VzLmVuY29kZSgpKQogICAgX2pzb25fcHJpdmF0ZShvcy5wYXRoLmpvaW4oU1RBVEUsICJjb25maWctYmVmb3JlLmpzb24iKSwgX2NhcHR1cmVfY29uZmlnKCkpCgoKZGVmIF9jYXB0dXJlX2NvbmZpZygpOgogICAgIiIiQ2FwdHVyZSBib3VuZGVkIGZpeGVkIHBhdGhzOyBhIHN5bWxpbmsgb3IgdW5yZWFkYWJsZSBmaWxlIGlzIHVua25vd24sIG5vdCBjbGVhbi4iIiIKICAgIHJlc3VsdCA9IHt9CiAgICBmb3IgcGF0aCBpbiBDT05GSUdfUEFUSFM6CiAgICAgICAgaWYgb3MucGF0aC5pc2xpbmsocGF0aCk6CiAgICAgICAgICAgIHJhaXNlIFJlZnVzZWQoImNvbmZpZy1zbmFwc2hvdCIpCiAgICAgICAgaWYgbm90IG9zLnBhdGguZXhpc3RzKHBhdGgpOgogICAgICAgICAgICByZXN1bHRbcGF0aF0gPSBOb25lCiAgICAgICAgZWxpZiBvcy5wYXRoLmlzZmlsZShwYXRoKToKICAgICAgICAgICAgcmVzdWx0W3BhdGhdID0gX3JlYWRfZml4ZWQocGF0aCwgMTAyNCAqIDEwMjQpLmRlY29kZSgidXRmLTgiKQogICAgICAgIGVsaWYgb3MucGF0aC5pc2RpcihwYXRoKToKICAgICAgICAgICAgZm9yIHJvb3QsIGRpcnMsIGZpbGVzIGluIG9zLndhbGsocGF0aCwgZm9sbG93bGlua3M9RmFsc2UpOgogICAgICAgICAgICAgICAgaWYgYW55KG9zLnBhdGguaXNsaW5rKG9zLnBhdGguam9pbihyb290LCBuKSkgZm9yIG4gaW4gZGlycyArIGZpbGVzKToKICAgICAgICAgICAgICAgICAgICByYWlzZSBSZWZ1c2VkKCJjb25maWctc25hcHNob3QiKQogICAgICAgICAgICAgICAgZm9yIG5hbWUgaW4gc29ydGVkKGZpbGVzKToKICAgICAgICAgICAgICAgICAgICBjaGlsZCA9IG9zLnBhdGguam9pbihyb290LCBuYW1lKQogICAgICAgICAgICAgICAgICAgIHJlc3VsdFtjaGlsZF0gPSBfcmVhZF9maXhlZChjaGlsZCwgMTAyNCAqIDEwMjQpLmRlY29kZSgidXRmLTgiKQogICAgICAgICAgICAgICAgICAgIGlmIGxlbihyZXN1bHQpID4gMjU2OgogICAgICAgICAgICAgICAgICAgICAgICByYWlzZSBSZWZ1c2VkKCJjb25maWctc25hcHNob3QiKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIFJlZnVzZWQoImNvbmZpZy1zbmFwc2hvdCIpCiAgICBpZiBzdW0obGVuKHYuZW5jb2RlKCJ1dGYtOCIpKSBmb3IgdiBpbiByZXN1bHQudmFsdWVzKCkgaWYgdiBpcyBub3QgTm9uZSkgPiA4ICogMTAyNCAqIDEwMjQ6CiAgICAgICAgcmFpc2UgUmVmdXNlZCgiY29uZmlnLXNuYXBzaG90IikKICAgIHJldHVybiByZXN1bHQKCgpkZWYgX3JlY29yZF9jb25maWdfZGlmZigpOgogICAgIiIiV3JpdGUgcHJpdmF0ZSwgcmVkYWN0ZWQgZXZpZGVuY2UuIFJldmlldyBpcyBhbHdheXMgYSBzZXBhcmF0ZSBkZWNpc2lvbi4iIiIKICAgIGJlZm9yZSA9IF9vYmplY3QoX3JlYWRfZml4ZWQob3MucGF0aC5qb2luKFNUQVRFLCAiY29uZmlnLWJlZm9yZS5qc29uIiksIDE2ICogMTAyNCAqIDEwMjQpKQogICAgaWYgdHlwZShiZWZvcmUpIGlzIG5vdCBkaWN0IG9yIGFueSh0eXBlKGspIGlzIG5vdCBzdHIgb3IgKHYgaXMgbm90IE5vbmUgYW5kIHR5cGUodikgaXMgbm90IHN0cikgZm9yIGssIHYgaW4gYmVmb3JlLml0ZW1zKCkpOgogICAgICAgIHJhaXNlIFJlZnVzZWQoImNvbmZpZy1zbmFwc2hvdCIpCiAgICBhZnRlciA9IF9jYXB0dXJlX2NvbmZpZygpCiAgICBjaGFuZ2VzID0gW10KICAgIGZvciBwYXRoIGluIHNvcnRlZChzZXQoYmVmb3JlKSB8IHNldChhZnRlcikpOgogICAgICAgIG9sZCwgbmV3ID0gYmVmb3JlLmdldChwYXRoKSwgYWZ0ZXIuZ2V0KHBhdGgpCiAgICAgICAgaWYgb2xkID09IG5ldzoKICAgICAgICAgICAgY29udGludWUKICAgICAgICBsaW5lcyA9IGxpc3QoZGlmZmxpYi51bmlmaWVkX2RpZmYoKG9sZCBvciAiIikuc3BsaXRsaW5lcygpLCAobmV3IG9yICIiKS5zcGxpdGxpbmVzKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb21maWxlPSJiZWZvcmUiLCB0b2ZpbGU9ImFmdGVyIiwgbGluZXRlcm09IiIpKQogICAgICAgICMgS2VlcCBjb25maWd1cmF0aW9uIGV2aWRlbmNlIHVzZWZ1bCB3aXRob3V0IGNvcHlpbmcgY3JlZGVudGlhbHMgaW50byBhIHJlcG9ydC4KICAgICAgICBzYWZlID0gW10KICAgICAgICBmb3IgbGluZSBpbiBsaW5lc1s6MjAwMF06CiAgICAgICAgICAgIGlmIHJlLnNlYXJjaChyIig/aSkocGFzc3dvcmR8cGFzc3dkfHRva2VufHNlY3JldHxjcmVkZW50aWFsfGF1dGhvcml6YXRpb258YXBpW18tXT9rZXkpIiwgbGluZSk6CiAgICAgICAgICAgICAgICBzYWZlLmFwcGVuZCgiW3NlbnNpdGl2ZSBsaW5lIHJlZGFjdGVkXSIpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzYWZlLmFwcGVuZChyZS5zdWIociJbQS1aYS16MC05XysvPS1dezMyLH0iLCAiW3JlZGFjdGVkXSIsIGxpbmUpWzoxMDAwXSkKICAgICAgICBjaGFuZ2VzLmFwcGVuZCh7InBhdGgiOiBwYXRoLCAiYmVmb3JlX3NoYTI1NiI6IGhhc2hsaWIuc2hhMjU2KG9sZC5lbmNvZGUoKSkuaGV4ZGlnZXN0KCkgaWYgb2xkIGlzIG5vdCBOb25lIGVsc2UgTm9uZSwKICAgICAgICAgICAgICAgICAgICAgICAgImFmdGVyX3NoYTI1NiI6IGhhc2hsaWIuc2hhMjU2KG5ldy5lbmNvZGUoKSkuaGV4ZGlnZXN0KCkgaWYgbmV3IGlzIG5vdCBOb25lIGVsc2UgTm9uZSwKICAgICAgICAgICAgICAgICAgICAgICAgImRpZmYiOiBzYWZlLCAidHJ1bmNhdGVkIjogbGVuKGxpbmVzKSA+IDIwMDB9KQogICAgcmVwb3J0ID0geyJyZXZpZXdfcmVxdWlyZWQiOiBUcnVlLCAiY2hhbmdlcyI6IGNoYW5nZXN9CiAgICBfanNvbl9wcml2YXRlKG9zLnBhdGguam9pbihTVEFURSwgImNvbmZpZy1kaWZmLmpzb24iKSwgcmVwb3J0KQogICAgcmV0dXJuIHJlcG9ydAoKCmRlZiBfbWFya2VyKG5hbWUpOgogICAgcmV0dXJuIG9zLnBhdGguam9pbihTVEFURSwgbmFtZSArICIuanNvbiIpCgoKZGVmIF9yZWNvdmVyeV9uZWVkZWQoKToKICAgIHJldHVybiBvcy5wYXRoLmV4aXN0cyhfbWFya2VyKCJpbnN0YWxsLXN0YXJ0ZWQiKSkgYW5kIG5vdCBvcy5wYXRoLmV4aXN0cyhfbWFya2VyKCJpbnN0YWxsLWV4aXRlZCIpKQoKCmRlZiBfaW5zdGFsbF9oaXN0b3J5KCk6CiAgICBpZiBub3Qgb3MucGF0aC5leGlzdHMoX21hcmtlcigiaW5zdGFsbC1zdGFydGVkIikpOgogICAgICAgIHJldHVybiB7InN0YXRlIjogIm5ldmVyLXN0YXJ0ZWQifQogICAgdHJ5OgogICAgICAgIHN0YXJ0ZWQgPSBfb2JqZWN0KF9yZWFkX2ZpeGVkKF9tYXJrZXIoImluc3RhbGwtc3RhcnRlZCIpLCA0MDk2KSkKICAgICAgICBpZiB0eXBlKHN0YXJ0ZWQpIGlzIG5vdCBkaWN0IG9yIG5vdCBfaW50ZWdlcihzdGFydGVkLmdldCgicGxhbl9pZCIpKSBvciBub3QgX2ludGVnZXIoc3RhcnRlZC5nZXQoImF0dGVtcHQiKSk6CiAgICAgICAgICAgIHJldHVybiB7InN0YXRlIjogInVua25vd24ifQogICAgICAgIHJlc3VsdCA9IHsic3RhdGUiOiAiaW50ZXJydXB0ZWQiLCAicGxhbl9pZCI6IHN0YXJ0ZWRbInBsYW5faWQiXSwgImF0dGVtcHQiOiBzdGFydGVkWyJhdHRlbXB0Il19CiAgICAgICAgaWYgb3MucGF0aC5leGlzdHMoX21hcmtlcigiaW5zdGFsbC1leGl0ZWQiKSk6CiAgICAgICAgICAgIGV4aXRlZCA9IF9vYmplY3QoX3JlYWRfZml4ZWQoX21hcmtlcigiaW5zdGFsbC1leGl0ZWQiKSwgNDA5NikpCiAgICAgICAgICAgIGlmICh0eXBlKGV4aXRlZCkgaXMgbm90IGRpY3Qgb3IgZXhpdGVkLmdldCgicGxhbl9pZCIpICE9IHN0YXJ0ZWRbInBsYW5faWQiXSBvcgogICAgICAgICAgICAgICAgICAgIGV4aXRlZC5nZXQoImF0dGVtcHQiKSAhPSBzdGFydGVkWyJhdHRlbXB0Il0gb3IgdHlwZShleGl0ZWQuZ2V0KCJyZXR1cm5jb2RlIikpIGlzIG5vdCBpbnQpOgogICAgICAgICAgICAgICAgcmV0dXJuIHsic3RhdGUiOiAidW5rbm93biJ9CiAgICAgICAgICAgIHJlc3VsdC51cGRhdGUoc3RhdGU9ImNvbXBsZXRlZCIsIHJldHVybmNvZGU9ZXhpdGVkWyJyZXR1cm5jb2RlIl0pCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGZhaWx1cmUgPSBfb2JqZWN0KF9yZWFkX2ZpeGVkKF9tYXJrZXIoImluc3RhbGwtY2xhc3NpZmllZCIpLCA0MDk2KSkKICAgICAgICAgICAgICAgIGlmICh0eXBlKGZhaWx1cmUpIGlzIGRpY3QgYW5kIGZhaWx1cmUuZ2V0KCJwbGFuX2lkIikgPT0gc3RhcnRlZFsicGxhbl9pZCJdIGFuZAogICAgICAgICAgICAgICAgICAgICAgICBmYWlsdXJlLmdldCgiYXR0ZW1wdCIpID09IHN0YXJ0ZWRbImF0dGVtcHQiXSBhbmQKICAgICAgICAgICAgICAgICAgICAgICAgZmFpbHVyZS5nZXQoImZhaWx1cmVfY2xhc3MiKSBpbiAoInNzaCIsICJzdG9yYWdlIiwgImlkZW50aWZ5IiwgImdwdSBmYXVsdCIsICJkb3dubG9hZCIsICJ1bmtub3duIikpOgogICAgICAgICAgICAgICAgICAgIHJlc3VsdFsiZmFpbHVyZV9jbGFzcyJdID0gZmFpbHVyZVsiZmFpbHVyZV9jbGFzcyJdCiAgICAgICAgICAgIGV4Y2VwdCAoT1NFcnJvciwgUmVmdXNlZCk6CiAgICAgICAgICAgICAgICBwYXNzCiAgICAgICAgcmV0dXJuIHJlc3VsdAogICAgZXhjZXB0IChPU0Vycm9yLCBSZWZ1c2VkKToKICAgICAgICByZXR1cm4geyJzdGF0ZSI6ICJ1bmtub3duIn0KCgpkZWYgX3JlY292ZXJfaW5zcGVjdCgpOgogICAgIyBSZWNvcmQgaW50ZW50IGZpcnN0OiBhIHNlY29uZCBpbnRlcnJ1cHRpb24gY2FuIG5ldmVyIGJlIG1pc3Rha2VuIGZvciBhIGNsZWFuIHJlY292ZXJ5LgogICAgX2pzb25fcHJpdmF0ZShfbWFya2VyKCJyZWNvdmVyeS1zdGFydGVkIiksIHsiaGlzdG9yeSI6IF9pbnN0YWxsX2hpc3RvcnkoKX0pCiAgICByYywgXyA9IGNvbW1hbmQoWyJkcGtnIiwgIi0tY29uZmlndXJlIiwgIi1hIl0sIHRpbWVvdXQ9MTgwMCkKICAgIHJlc3VsdCA9IHsib3V0Y29tZSI6ICJyZWNvdmVyeS1yZXF1aXJlZCIsICJkcGtnX2NvbmZpZ3VyZWQiOiByYyA9PSAwLAogICAgICAgICAgICAgICJtYWNoaW5lX251bV9pZCI6IF9tYWNoaW5lX251bSgpLCAibWFjaGluZV9pZF9wcmVzZW50Ijogb3MucGF0aC5pc2ZpbGUob3MucGF0aC5qb2luKFZBU1QsICJtYWNoaW5lX2lkIikpfQogICAgdHJ5OgogICAgICAgIF9yZWNvcmRfY29uZmlnX2RpZmYoKQogICAgICAgIHJlc3VsdFsiY29uZmlnX2RpZmZfcmVjb3JkZWQiXSA9IFRydWUKICAgIGV4Y2VwdCAoT1NFcnJvciwgVW5pY29kZUVycm9yLCBSZWZ1c2VkKToKICAgICAgICByZXN1bHRbImNvbmZpZ19kaWZmX3JlY29yZGVkIl0gPSBGYWxzZQogICAgX2pzb25fcHJpdmF0ZShfbWFya2VyKCJyZWNvdmVyeS1pbnNwZWN0ZWQiKSwgcmVzdWx0KQogICAgcmV0dXJuIHJlc3VsdAoKCmRlZiBfY2xhc3NpZnlfZmFpbHVyZShjb2RlLCBsb2cpOgogICAgIiIiRW1pdCBhIGZpeGVkIGxhYmVsIG9ubHk7IG5vIHJhdyBpbnN0YWxsZXIgb3V0cHV0IGxlYXZlcyB0aGUgaGVscGVyLiIiIgogICAgaWYgY29kZSA9PSAwOgogICAgICAgIHJldHVybiBOb25lCiAgICB2YWx1ZSA9IGxvZy5sb3dlcigpCiAgICBpZiAicGFzc3dvcmQgbG9naW4gaXMgZW5hYmxlZCIgaW4gdmFsdWU6CiAgICAgICAgcmV0dXJuICJzc2giCiAgICBpZiBhbnkoeCBpbiB2YWx1ZSBmb3IgeCBpbiAoInN0b3JhZ2UgYXNzZXJ0IiwgImRpZmZlcmVudCBkZXZpY2UiLCAicHF1b3RhIiwgInhmcyIpKToKICAgICAgICByZXR1cm4gInN0b3JhZ2UiCiAgICBpZiAoImlkZW50aWZ5IiBpbiB2YWx1ZSBhbmQgKCI0MDEiIGluIHZhbHVlIG9yICI0MDMiIGluIHZhbHVlKSk6CiAgICAgICAgcmV0dXJuICJpZGVudGlmeSIKICAgIGlmICJudm1sIiBpbiB2YWx1ZSBhbmQgImVycm9yIiBpbiB2YWx1ZToKICAgICAgICByZXR1cm4gImdwdSBmYXVsdCIKICAgIGlmIGNvZGUgPT0gMTI0IG9yIGFueSh4IGluIHZhbHVlIGZvciB4IGluICgiYXB0IiwgImRvd25sb2FkIiwgInRpbWVvdXQiLCAidGltZWQgb3V0IiwgInB1bGwiKSk6CiAgICAgICAgcmV0dXJuICJkb3dubG9hZCIKICAgIHJldHVybiAidW5rbm93biIKCgpkZWYgaW5zdGFsbChyZXEpOgogICAgaWYgX3JlY292ZXJ5X25lZWRlZCgpOgogICAgICAgIHJldHVybiBfcmVjb3Zlcl9pbnNwZWN0KCkKICAgIGlmIG9zLnBhdGguZXhpc3RzKF9tYXJrZXIoImluc3RhbGwtc3RhcnRlZCIpKToKICAgICAgICByYWlzZSBSZWZ1c2VkKCJhbHJlYWR5LWF0dGVtcHRlZCIpCiAgICBpZiBub3QgYWxsb3dsaXN0X29rKHJlcSwgZmV0Y2hfY3VycmVudD1UcnVlKToKICAgICAgICByYWlzZSBSZWZ1c2VkKCJpbnN0YWxsZXItc2lnbmF0dXJlIikKICAgIHNvdXJjZSA9IGRvY2tlcl9tb3VudCgpCiAgICBpbmZvID0gaW5zcGVjdCgpCiAgICBpZiBub3QgYWxsKGluZm9bImNoZWNrcyJdLnZhbHVlcygpKSBvciBpbmZvWyJtYWNoaW5lX251bV9pZCJdIG9yIGluZm9bInZhc3RfYWN0aXZlIl06CiAgICAgICAgcmFpc2UgUmVmdXNlZCgicHJlY2hlY2siKQogICAgc3RhZ2UgPSB0ZW1wZmlsZS5ta2R0ZW1wKHByZWZpeD0iaW5zdGFsbC0iLCBkaXI9UlVOVElNRSkKICAgIGluc3RhbGxlciA9IG9zLnBhdGguam9pbihzdGFnZSwgImluc3RhbGwiKQogICAgZGF0YSA9IF9mZXRjaChJTlNUQUxMRVIsIHJlZGlyZWN0PUlOU1RBTExFUl9SRURJUkVDVCkKICAgIGlmIGhhc2hsaWIuc2hhMjU2KGRhdGEpLmhleGRpZ2VzdCgpICE9IHJlcVsiaW5zdGFsbGVyX3NoYTI1NiJdOgogICAgICAgIHJhaXNlIFJlZnVzZWQoImluc3RhbGxlci1oYXNoIikKICAgIF9wcml2YXRlKGluc3RhbGxlciwgZGF0YSkKICAgIF9zbmFwc2hvdCgpCiAgICAjIFJlY2hlY2sgYWZ0ZXIgZG93bmxvYWRzIGFuZCBiYWNrdXBzLCBpbW1lZGlhdGVseSBiZWZvcmUgb2J0YWluaW5nIHRoZSBvbmUtc2hvdCBrZXkuCiAgICBpZiBkb2NrZXJfbW91bnQoKSAhPSBzb3VyY2U6CiAgICAgICAgcmFpc2UgUmVmdXNlZCgic3RvcmFnZSIpCiAgICBrZXkgPSBfZ2V0X2tleShyZXEpCiAgICBpZiBkb2NrZXJfbW91bnQoKSAhPSBzb3VyY2U6CiAgICAgICAgcmFpc2UgUmVmdXNlZCgic3RvcmFnZSIpCiAgICBfanNvbl9wcml2YXRlKF9tYXJrZXIoImluc3RhbGwtc3RhcnRlZCIpLCB7InBsYW5faWQiOiByZXFbInBsYW5faWQiXSwgImF0dGVtcHQiOiByZXFbImF0dGVtcHQiXSwgInJ1bl9pZCI6IHJlcVsicnVuX2lkIl0sICJkb2NrZXJfc291cmNlIjogc291cmNlLCAicG9ydHNfZmlyc3QiOiByZXFbInBvcnRzX2ZpcnN0Il0sICJwb3J0c19sYXN0IjogcmVxWyJwb3J0c19sYXN0Il19KQogICAgcmF3X2xvZyA9IG9zLnBhdGguam9pbihzdGFnZSwgImluc3RhbGxlci5sb2ciKQogICAgYXJncyA9IFsicHl0aG9uMyIsICItSSIsICIuL2luc3RhbGwiLCBrZXksICItLW5vLWRyaXZlciIsICItLWRvY2tlci1wYXJ0aXRpb24iLCBzb3VyY2UsICItLXBvcnRzIiwgc3RyKHJlcVsicG9ydHNfZmlyc3QiXSksIHN0cihyZXFbInBvcnRzX2xhc3QiXSksICItLW5vLWxpYnZpcnQiLCAiLWwiLCByYXdfbG9nXQogICAgdHJ5OgogICAgICAgIHJlc3VsdCA9IHN1YnByb2Nlc3MucnVuKGFyZ3MsIGN3ZD1zdGFnZSwgc3RkaW49c3VicHJvY2Vzcy5ERVZOVUxMLCBzdGRvdXQ9c3VicHJvY2Vzcy5ERVZOVUxMLCBzdGRlcnI9c3VicHJvY2Vzcy5ERVZOVUxMLCB0aW1lb3V0PTcyMDAsIGNoZWNrPUZhbHNlKQogICAgICAgIGNvZGUgPSByZXN1bHQucmV0dXJuY29kZQogICAgZXhjZXB0IHN1YnByb2Nlc3MuVGltZW91dEV4cGlyZWQ6CiAgICAgICAgY29kZSA9IDEyNAogICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgY29kZSA9IDEyNQogICAgZmluYWxseToKICAgICAgICBkZWwgYXJncwogICAgX2pzb25fcHJpdmF0ZShfbWFya2VyKCJpbnN0YWxsLWV4aXRlZCIpLCB7InBsYW5faWQiOiByZXFbInBsYW5faWQiXSwgImF0dGVtcHQiOiByZXFbImF0dGVtcHQiXSwgInJ1bl9pZCI6IHJlcVsicnVuX2lkIl0sICJyZXR1cm5jb2RlIjogY29kZX0pCiAgICB0cnk6CiAgICAgICAgcmF3ID0gX3JlYWRfZml4ZWQocmF3X2xvZywgNCAqIDEwMjQgKiAxMDI0KS5kZWNvZGUoInV0Zi04IiwgInJlcGxhY2UiKQogICAgZXhjZXB0IChPU0Vycm9yLCBSZWZ1c2VkKToKICAgICAgICByYXcgPSAiIgogICAgZmFpbHVyZV9jbGFzcyA9IF9jbGFzc2lmeV9mYWlsdXJlKGNvZGUsIHJhd1stNjU1MzY6XSkKICAgIGlmIGZhaWx1cmVfY2xhc3MgaXMgbm90IE5vbmU6CiAgICAgICAgX2pzb25fcHJpdmF0ZShfbWFya2VyKCJpbnN0YWxsLWNsYXNzaWZpZWQiKSwgeyJwbGFuX2lkIjogcmVxWyJwbGFuX2lkIl0sICJhdHRlbXB0IjogcmVxWyJhdHRlbXB0Il0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmFpbHVyZV9jbGFzcyI6IGZhaWx1cmVfY2xhc3N9KQogICAgdHJ5OgogICAgICAgIF9yZWNvcmRfY29uZmlnX2RpZmYoKQogICAgZXhjZXB0IChPU0Vycm9yLCBVbmljb2RlRXJyb3IsIFJlZnVzZWQpOgogICAgICAgICMgTWlzc2luZyBkaWZmIGlzIGFsd2F5cyB1bnJldmlld2VkLCBhbmQgdmVyaWZ5IHJlbWFpbnMgZmFpbC1jbG9zZWQuCiAgICAgICAgcGFzcwogICAgc2FuaXRpemVkID0gcmUuc3ViKHIiW0EtWmEtejAtOV8rLz0tXXszMix9IiwgIltyZWRhY3RlZF0iLCByYXcucmVwbGFjZShrZXksICJbcmVkYWN0ZWRdIikpCiAgICBvcy5tYWtlZGlycyhMT0dfRElSLCBtb2RlPTBvNzUwLCBleGlzdF9vaz1UcnVlKQogICAgX3ByaXZhdGUob3MucGF0aC5qb2luKExPR19ESVIsICJ2YXN0LWluc3RhbGwtJWQubG9nIiAlIHJlcVsiYXR0ZW1wdCJdKSwgc2FuaXRpemVkLmVuY29kZSgpKQogICAgdHJ5OgogICAgICAgIG9zLnVubGluayhyYXdfbG9nKQogICAgZXhjZXB0IEZpbGVOb3RGb3VuZEVycm9yOgogICAgICAgIHBhc3MKICAgIGRlbCBrZXksIHJhdywgc2FuaXRpemVkCiAgICByZXN1bHQgPSB7Im91dGNvbWUiOiAiZXhpdGVkIiwgInJldHVybmNvZGUiOiBjb2RlfQogICAgaWYgZmFpbHVyZV9jbGFzcyBpcyBub3QgTm9uZToKICAgICAgICByZXN1bHRbImZhaWx1cmVfY2xhc3MiXSA9IGZhaWx1cmVfY2xhc3MKICAgIHJldHVybiByZXN1bHQKCgpkZWYgX3NlbmRpbmdfcmVjZW50KCk6CiAgICB0cnk6CiAgICAgICAgZGF0YSA9IF9yZWFkX2ZpeGVkKG9zLnBhdGguam9pbihWQVNULCAia2FhbGlhLmxvZyIpLCA4ICogMTAyNCAqIDEwMjQpLmRlY29kZSgidXRmLTgiLCAicmVwbGFjZSIpCiAgICAgICAgbm93ID0gdGltZS50aW1lKCkKICAgICAgICBmb3IgbGluZSBpbiByZXZlcnNlZChkYXRhLnNwbGl0bGluZXMoKSk6CiAgICAgICAgICAgIGlmICJzZW5kaW5nIiBub3QgaW4gbGluZS5sb3dlcigpOgogICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgbWF0Y2ggPSByZS5zZWFyY2gociIoXGR7NH0tXGR7Mn0tXGR7Mn1bVCBdXGR7Mn06XGR7Mn06XGR7Mn0pKD86XC5cZCspPyg/Olp8XCswMDowMCkiLCBsaW5lKQogICAgICAgICAgICBpZiBtYXRjaDoKICAgICAgICAgICAgICAgIHN0YW1wID0gZGF0ZXRpbWUuZGF0ZXRpbWUuZnJvbWlzb2Zvcm1hdChtYXRjaC5ncm91cCgxKS5yZXBsYWNlKCIgIiwgIlQiKSkucmVwbGFjZSh0emluZm89ZGF0ZXRpbWUudGltZXpvbmUudXRjKS50aW1lc3RhbXAoKQogICAgICAgICAgICAgICAgcmV0dXJuIDAgPD0gbm93IC0gc3RhbXAgPD0gMzAwCiAgICAgICAgcmV0dXJuIEZhbHNlCiAgICBleGNlcHQgKE9TRXJyb3IsIFZhbHVlRXJyb3IsIFJlZnVzZWQpOgogICAgICAgIHJldHVybiBGYWxzZQoKZGVmIHZlcmlmeShyZXEpOgogICAgY2hlY2tzID0ge30KICAgIHRyeToKICAgICAgICBfcmVjb3JkX2NvbmZpZ19kaWZmKCkKICAgIGV4Y2VwdCAoT1NFcnJvciwgVW5pY29kZUVycm9yLCBSZWZ1c2VkKToKICAgICAgICBwYXNzICAjIE5vIHJlcG9ydCBpcyBub3QgYSBjbGVhbiByZXBvcnQuCiAgICB0cnk6CiAgICAgICAgc3RhcnRlZCA9IF9vYmplY3QoX3JlYWRfZml4ZWQoX21hcmtlcigiaW5zdGFsbC1zdGFydGVkIiksIDQwOTYpKQogICAgICAgIGNoZWNrc1sic2FtZV9kZXZpY2UiXSA9IGRvY2tlcl9tb3VudCgpID09IHN0YXJ0ZWQuZ2V0KCJkb2NrZXJfc291cmNlIikKICAgIGV4Y2VwdCAoT1NFcnJvciwgUmVmdXNlZCk6CiAgICAgICAgY2hlY2tzWyJzYW1lX2RldmljZSJdID0gRmFsc2UKICAgIGNoZWNrc1sibWFjaGluZV9udW1faWQiXSA9IF9tYWNoaW5lX251bSgpIGlzIG5vdCBOb25lCiAgICByYywgXyA9IGNvbW1hbmQoWyJzeXN0ZW1jdGwiLCAiaXMtYWN0aXZlIiwgIi0tcXVpZXQiLCAidmFzdGFpIl0pCiAgICBjaGVja3NbImRhZW1vbiJdID0gcmMgPT0gMAogICAgdHJ5OgogICAgICAgIGZzdGFiID0gX3JlYWRfZml4ZWQoIi9ldGMvZnN0YWIiLCA2NTUzNikuZGVjb2RlKCJ1dGYtOCIsICJyZXBsYWNlIikKICAgICAgICBjaGVja3NbImZzdGFiIl0gPSBzdW0oMSBmb3IgbGluZSBpbiBmc3RhYi5zcGxpdGxpbmVzKCkgaWYgbm90IGxpbmUubHN0cmlwKCkuc3RhcnRzd2l0aCgiIyIpIGFuZCBsZW4obGluZS5zcGxpdCgpKSA+PSAyIGFuZCBsaW5lLnNwbGl0KClbMV0gPT0gRE9DS0VSKSA9PSAxCiAgICBleGNlcHQgKE9TRXJyb3IsIFJlZnVzZWQpOgogICAgICAgIGNoZWNrc1siZnN0YWIiXSA9IEZhbHNlCiAgICByYywgc3NoID0gY29tbWFuZChbInNzaGQiLCAiLVQiXSkKICAgIGNoZWNrc1sic3NoIl0gPSByYyA9PSAwIGFuZCAicGFzc3dvcmRhdXRoZW50aWNhdGlvbiBubyIgaW4gc3NoIGFuZCAia2JkaW50ZXJhY3RpdmVhdXRoZW50aWNhdGlvbiBubyIgaW4gc3NoCiAgICBjaGVja3NbIm5hbHZvX3N0b3JhZ2UiXSA9IG9zLnBhdGguaXNmaWxlKCIvZXRjL3N5c3RlbWQvc3lzdGVtL2RvY2tlci5zZXJ2aWNlLmQvbmFsdm8tc3RvcmFnZS5jb25mIikKICAgIHRyeToKICAgICAgICBwb3J0cyA9IF9yZWFkX2ZpeGVkKG9zLnBhdGguam9pbihWQVNULCAiaG9zdF9wb3J0X3JhbmdlIiksIDEyOCkuZGVjb2RlKCJhc2NpaSIpLnN0cmlwKCkKICAgICAgICBjaGVja3NbInBvcnRzIl0gPSBwb3J0cyBpbiAoIiVzLSVzIiAlIChzdGFydGVkWyJwb3J0c19maXJzdCJdLCBzdGFydGVkWyJwb3J0c19sYXN0Il0pLCAiJXMgJXMiICUgKHN0YXJ0ZWRbInBvcnRzX2ZpcnN0Il0sIHN0YXJ0ZWRbInBvcnRzX2xhc3QiXSkpCiAgICBleGNlcHQgKE9TRXJyb3IsIEtleUVycm9yLCBVbmljb2RlRXJyb3IsIFJlZnVzZWQsIFVuYm91bmRMb2NhbEVycm9yKToKICAgICAgICBjaGVja3NbInBvcnRzIl0gPSBGYWxzZQogICAgY2hlY2tzWyJkYWVtb25fZnJlc2giXSA9IF9zZW5kaW5nX3JlY2VudCgpCiAgICByYywgZ3B1X25hbWVzID0gY29tbWFuZChbIm52aWRpYS1zbWkiLCAiLUwiXSkKICAgIGhvc3RfY291bnQgPSBsZW4oW2xpbmUgZm9yIGxpbmUgaW4gZ3B1X25hbWVzLnNwbGl0bGluZXMoKSBpZiBsaW5lLnN0YXJ0c3dpdGgoIkdQVSAiKV0pIGlmIHJjID09IDAgZWxzZSAwCiAgICBpbWFnZSA9ICJudmlkaWEvY3VkYToxMi40LjEtYmFzZS11YnVudHUyMi4wNCIKICAgIHJjLCBfID0gY29tbWFuZChbImRvY2tlciIsICJpbWFnZSIsICJpbnNwZWN0IiwgaW1hZ2VdKQogICAgaWYgcmMgPT0gMDoKICAgICAgICByYywgbGlzdGVkID0gY29tbWFuZChbImRvY2tlciIsICJydW4iLCAiLS1ybSIsICItLW5ldHdvcmsiLCAibm9uZSIsICItLXB1bGwiLCAibmV2ZXIiLCAiLS1ncHVzIiwgImFsbCIsIGltYWdlLCAibnZpZGlhLXNtaSIsICItTCJdLCB0aW1lb3V0PTEyMCkKICAgICAgICBjaGVja3NbImdwdV9jb250YWluZXIiXSA9IHJjID09IDAgYW5kIGhvc3RfY291bnQgPiAwIGFuZCBsZW4oW2xpbmUgZm9yIGxpbmUgaW4gbGlzdGVkLnNwbGl0bGluZXMoKSBpZiBsaW5lLnN0YXJ0c3dpdGgoIkdQVSAiKV0pID09IGhvc3RfY291bnQKICAgIGVsc2U6CiAgICAgICAgY2hlY2tzWyJncHVfY29udGFpbmVyIl0gPSBGYWxzZQogICAgIyBGaXZlIHJlcXVpcmVkIGNoZWNrcyBkZWNpZGU7IHRoZSBmb3VyIGFkdmlzb3J5IG9uZXMgKGFuZCB0aGUgY29uZmlnIGRpZmYgYWJvdmUpIGFyZSBldmlkZW5jZSBvbmx5LgogICAgcmV0dXJuIHsiY2hlY2tzIjogY2hlY2tzLCAibWFjaGluZV9udW1faWQiOiBfbWFjaGluZV9udW0oKSwKICAgICAgICAgICAgInZlcmlmaWVkIjogYWxsKGNoZWNrcy5nZXQobmFtZSkgaXMgVHJ1ZSBmb3IgbmFtZSBpbiBWRVJJRllfUkVRVUlSRUQpfQoKCmRlZiBzY3J1YihyZXEpOgogICAgIyBEbyBub3QgcmVtb3ZlIGEgc3RhZ2luZyBkaXJlY3Rvcnkgd2hpbGUgVmFzdCdzIGNoaWxkIG1heSBzdGlsbCB1c2UgaXRzIGtleS4KICAgIHRyeToKICAgICAgICByYyA9IHN1YnByb2Nlc3MucnVuKFsicGdyZXAiLCAiLWYiLCAiW3NddGFydF9zZWxmX3Rlc3Quc2giXSwgc3Rkb3V0PXN1YnByb2Nlc3MuREVWTlVMTCwgc3RkZXJyPXN1YnByb2Nlc3MuREVWTlVMTCwgdGltZW91dD0xMCwgY2hlY2s9RmFsc2UpLnJldHVybmNvZGUKICAgIGV4Y2VwdCAoT1NFcnJvciwgc3VicHJvY2Vzcy5UaW1lb3V0RXhwaXJlZCk6CiAgICAgICAgcmFpc2UgUmVmdXNlZCgic2VsZnRlc3QtcnVubmluZy1vci11bmtub3duIikKICAgIGlmIHJjICE9IDE6CiAgICAgICAgcmFpc2UgUmVmdXNlZCgic2VsZnRlc3QtcnVubmluZy1vci11bmtub3duIikKICAgIGZvciBuYW1lIGluIG9zLmxpc3RkaXIoUlVOVElNRSk6CiAgICAgICAgaWYgbmFtZS5zdGFydHN3aXRoKCJpbnN0YWxsLSIpOgogICAgICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKFJVTlRJTUUsIG5hbWUpCiAgICAgICAgICAgIGlmIG9zLnBhdGguaXNkaXIocGF0aCkgYW5kIG5vdCBvcy5wYXRoLmlzbGluayhwYXRoKToKICAgICAgICAgICAgICAgIHNodXRpbC5ybXRyZWUocGF0aCkKICAgIHJldHVybiB7Im91dGNvbWUiOiAic2NydWJiZWQifQoKCmRlZiBtYWluKCk6CiAgICByb290ID0gcmVxdWVzdF9kaXIgPSBOb25lCiAgICByZXEgPSBOb25lCiAgICB0cnk6CiAgICAgICAgb3MudW1hc2soMG8wNzcpCiAgICAgICAgb3MubWFrZWRpcnMoU1RBVEUsIG1vZGU9MG83MDAsIGV4aXN0X29rPVRydWUpCiAgICAgICAgb3MubWFrZWRpcnMoUlVOVElNRSwgbW9kZT0wbzcwMCwgZXhpc3Rfb2s9VHJ1ZSkKICAgICAgICByb290ID0gX29wZW5fZGlyKE5PREVfRElSKQogICAgICAgIHJlcXVlc3RfZGlyID0gX29wZW5fZGlyKCJ2YXN0Iiwgcm9vdCkKICAgICAgICBjbGFpbSA9ICIuY2xhaW1lZC0iICsgb3MudXJhbmRvbSgxNikuaGV4KCkKICAgICAgICBvcy5yZW5hbWUoInJlcXVlc3QuanNvbiIsIGNsYWltLCBzcmNfZGlyX2ZkPXJlcXVlc3RfZGlyLCBkc3RfZGlyX2ZkPXJlcXVlc3RfZGlyKQogICAgICAgIHRyeToKICAgICAgICAgICAgZm9yIGF0dGVtcHQgaW4gcmFuZ2UoMTApOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIGRhdGEgPSBfcmVhZF9hdChyZXF1ZXN0X2RpciwgY2xhaW0sIE1BWF9SRVFVRVNUKQogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICBleGNlcHQgUmVmdXNlZDoKICAgICAgICAgICAgICAgICAgICBpZiBhdHRlbXB0ID09IDk6CiAgICAgICAgICAgICAgICAgICAgICAgIHJhaXNlCiAgICAgICAgICAgICAgICAgICAgdGltZS5zbGVlcCgwLjA1KQogICAgICAgICAgICByZXEgPSB2YWxpZGF0ZShfb2JqZWN0KGRhdGEpKQogICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIG9zLnVubGluayhjbGFpbSwgZGlyX2ZkPXJlcXVlc3RfZGlyKQogICAgICAgICAgICBleGNlcHQgRmlsZU5vdEZvdW5kRXJyb3I6CiAgICAgICAgICAgICAgICBwYXNzCiAgICAgICAgcmVzdWx0ID0geyJpbnNwZWN0IjogbGFtYmRhOiBpbnNwZWN0KCksICJpbnN0YWxsIjogbGFtYmRhOiBpbnN0YWxsKHJlcSksICJ2ZXJpZnkiOiBsYW1iZGE6IHZlcmlmeShyZXEpLCAic2NydWIiOiBsYW1iZGE6IHNjcnViKHJlcSl9W3JlcVsib3BlcmF0aW9uIl1dKCkKICAgICAgICBzdGF0dXMgPSB7Im9wZXJhdGlvbiI6IHJlcVsib3BlcmF0aW9uIl0sICJyZXN1bHQiOiByZXN1bHR9CiAgICBleGNlcHQgUmVmdXNlZCBhcyBleGM6CiAgICAgICAgc3RhdHVzID0geyJlcnJvciI6IHN0cihleGMpfQogICAgZXhjZXB0IChPU0Vycm9yLCBWYWx1ZUVycm9yLCBVbmljb2RlRXJyb3IsIHVybGxpYi5lcnJvci5VUkxFcnJvcik6CiAgICAgICAgc3RhdHVzID0geyJlcnJvciI6ICJ1bmF2YWlsYWJsZSJ9CiAgICBpZiByZXEgaXMgbm90IE5vbmU6CiAgICAgICAgc3RhdHVzWyJwbGFuX2lkIl0gPSByZXFbInBsYW5faWQiXQogICAgICAgIHN0YXR1c1siYXR0ZW1wdCJdID0gcmVxWyJhdHRlbXB0Il0KICAgIGlmIHJlcXVlc3RfZGlyIGlzIG5vdCBOb25lOgogICAgICAgIHRyeToKICAgICAgICAgICAgX2F0b21pY19hdChyZXF1ZXN0X2RpciwgInN0YXR1cy5qc29uIiwgKGpzb24uZHVtcHMoc3RhdHVzLCBzb3J0X2tleXM9VHJ1ZSwgc2VwYXJhdG9ycz0oIiwiLCAiOiIpKSArICJcbiIpLmVuY29kZSgpLCAwbzY0NCkKICAgICAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICAgICAgcGFzcwogICAgICAgIG9zLmNsb3NlKHJlcXVlc3RfZGlyKQogICAgaWYgcm9vdCBpcyBub3QgTm9uZToKICAgICAgICBvcy5jbG9zZShyb290KQogICAgcmV0dXJuIDAgaWYgImVycm9yIiBub3QgaW4gc3RhdHVzIGVsc2UgMQoKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICByYWlzZSBTeXN0ZW1FeGl0KG1haW4oKSkK #NALVO-VAST-PATH-B64:W1VuaXRdCkRlc2NyaXB0aW9uPVdhdGNoIGZvciBOYWx2byBWYXN0IGhlbHBlciByZXF1ZXN0cwoKW1BhdGhdClBhdGhDaGFuZ2VkPS92YXIvbGliL25hbHZvLW5vZGUvdmFzdC9yZXF1ZXN0Lmpzb24KVW5pdD1uYWx2by12YXN0LWhlbHBlci5zZXJ2aWNlCgpbSW5zdGFsbF0KV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQK #NALVO-VAST-SERVICE-B64:W1VuaXRdCkRlc2NyaXB0aW9uPU5hbHZvIFZhc3QgcHJpdmlsZWdlZCBoZWxwZXIKQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0CldhbnRzPW5ldHdvcmstb25saW5lLnRhcmdldAoKW1NlcnZpY2VdClR5cGU9b25lc2hvdApVc2VyPXJvb3QKR3JvdXA9cm9vdApVTWFzaz0wMDc3ClJ1bnRpbWVEaXJlY3Rvcnk9bmFsdm8tdmFzdApSdW50aW1lRGlyZWN0b3J5TW9kZT0wNzAwClJ1bnRpbWVEaXJlY3RvcnlQcmVzZXJ2ZT15ZXMKVGltZW91dFN0YXJ0U2VjPTJoCkV4ZWNTdGFydD0vdXNyL2Jpbi9lbnYgLWkgUEFUSD0vdXNyL3NiaW46L3Vzci9iaW46L3NiaW46L2JpbiAvdXNyL2Jpbi9weXRob24zIC1JIC91c3IvbG9jYWwvbGliL25hbHZvL25hbHZvLXZhc3QtaGVscGVyLnB5Cg== #NALVO-VAST-SIGNERS-B64:cmVsZWFzZUBuYWx2by5haSBuYW1lc3BhY2VzPSJuYWx2by1yZWxlYXNlIiBzc2gtZWQyNTUxOSBBQUFBQzNOemFDMWxaREkxTlRFNUFBQUFJTk5vS2dlaTNkaEdId0FQQXU5TkJZL1loaDJINEJoZkJwWjIxaERYeDFIaAo= autoinstall: version: 1 interactive-sections: - storage locale: en_US.UTF-8 keyboard: layout: us identity: hostname: nalvo-node username: nalvo realname: Nalvo node password: "!" storage: layout: name: lvm sizing-policy: scaled kernel: flavor: hwe ssh: install-server: true allow-pw: false updates: security drivers: install: false packages: - xfsprogs - lvm2 - pciutils - usbutils - mokutil - curl - python3 - python3-requests # Wake-on-LAN. Already in this ISO's ubuntu-server-minimal layer, so this downloads nothing. - ethtool # Required for systemd-networkd/netplan Wi-Fi and in-tree adapter firmware. # ISO package contents have not been verified offline; request both explicitly. - wpasupplicant - linux-firmware # the model's home-only rule (MODEL-HOST 6.9) - nftables early-commands: - "sed -n 's/^#NALVO-EARLY-B64://p' /cdrom/autoinstall.yaml | base64 -d > /run/nalvo-early && bash /run/nalvo-early || true" late-commands: - install -d -m 0755 /target/usr/local/lib/nalvo - "sed -n 's/^#NALVO-QR-B64://p' /cdrom/autoinstall.yaml | base64 -d > /target/usr/local/lib/nalvo/qr.py && test -s /target/usr/local/lib/nalvo/qr.py" - chmod 0644 /target/usr/local/lib/nalvo/qr.py - "sed -n 's/^#NALVO-B64://p' /cdrom/autoinstall.yaml | base64 -d > /target/usr/local/sbin/nalvo-firstboot && test -s /target/usr/local/sbin/nalvo-firstboot" - chmod 0755 /target/usr/local/sbin/nalvo-firstboot # The Wi-Fi the Node Maker saved on the stick, for first boot when the installer could not use it. - "if [ -f /cdrom/nalvo-wifi.json.enc ]; then install -d -m 0700 /target/var/lib/nalvo-firstboot && install -m 0600 /cdrom/nalvo-wifi.json.enc /target/var/lib/nalvo-firstboot/wifi.enc; fi" - install -d -m 0755 /target/usr/local/share/nalvo-vast - "sed -n 's/^#NALVO-VAST-HELPER-B64://p' /cdrom/autoinstall.yaml | base64 -d > /target/usr/local/share/nalvo-vast/nalvo-vast-helper.py && test -s /target/usr/local/share/nalvo-vast/nalvo-vast-helper.py" - "sed -n 's/^#NALVO-VAST-PATH-B64://p' /cdrom/autoinstall.yaml | base64 -d > /target/usr/local/share/nalvo-vast/nalvo-vast-helper.path && test -s /target/usr/local/share/nalvo-vast/nalvo-vast-helper.path" - "sed -n 's/^#NALVO-VAST-SERVICE-B64://p' /cdrom/autoinstall.yaml | base64 -d > /target/usr/local/share/nalvo-vast/nalvo-vast-helper.service && test -s /target/usr/local/share/nalvo-vast/nalvo-vast-helper.service" - "sed -n 's/^#NALVO-VAST-SIGNERS-B64://p' /cdrom/autoinstall.yaml | base64 -d > /target/usr/local/share/nalvo-vast/allowed_signers && test -s /target/usr/local/share/nalvo-vast/allowed_signers" - chmod 0644 /target/usr/local/share/nalvo-vast/nalvo-vast-helper.py /target/usr/local/share/nalvo-vast/nalvo-vast-helper.path /target/usr/local/share/nalvo-vast/nalvo-vast-helper.service /target/usr/local/share/nalvo-vast/allowed_signers - | python3 - <<'PY' import os, re from pathlib import Path lines = Path('/cdrom/autoinstall.yaml').read_text(encoding='utf-8').splitlines() codes = [line[len('#NALVO-PAIR:'):] for line in lines if line.startswith('#NALVO-PAIR:')] if len(codes) == 1 and re.fullmatch(r'[0-9A-HJKMNP-TV-Z]{20}', codes[0]): directory = Path('/target/var/lib/nalvo-firstboot') directory.mkdir(mode=0o700, parents=True, exist_ok=True) os.chmod(directory, 0o700) fd = os.open(str(directory / 'pair-code'), os.O_WRONLY | os.O_CREAT | os.O_TRUNC | os.O_NOFOLLOW, 0o600) with os.fdopen(fd, 'w', encoding='ascii') as out: os.fchmod(out.fileno(), 0o600) out.write(codes[0] + '\n') PY - | if [ -f /run/nalvo-wifi-driver-missing ]; then install -D -m 0644 /run/nalvo-wifi-driver-missing /target/var/lib/nalvo-firstboot/wifi-driver-missing || true fi if [ -f /run/nalvo-wifi.yaml ]; then install -D -m 0600 /run/nalvo-wifi.yaml /target/etc/netplan/90-nalvo-wifi.yaml || echo 'Could not save the Wi-Fi configuration; use Ethernet.' >> /var/log/nalvo-early.log fi if [ -f /cdrom/nalvo-wifi.json.enc ]; then if rm -f /cdrom/nalvo-wifi.json.enc 2>/dev/null || { mount -o remount,rw /cdrom >/dev/null 2>&1 && rm -f /cdrom/nalvo-wifi.json.enc 2>/dev/null; }; then echo 'Encrypted Wi-Fi file removed from the installer stick.' >> /var/log/nalvo-early.log else echo 'Could not remove encrypted Wi-Fi file from the installer stick; remove it manually.' >> /var/log/nalvo-early.log fi fi # The same verified stick firmware must be present on the installed system, # including the initramfs, before the first boot without the USB stick. - | if [ -d /cdrom/nalvo/firmware/rtw89 ]; then install -d -m 0755 /target/lib/firmware/rtw89 for file in /cdrom/nalvo/firmware/rtw89/rtw*.bin /cdrom/nalvo/firmware/rtw89/rtw*.bin.zst; do [ -f "$file" ] || continue install -m 0644 "$file" /target/lib/firmware/rtw89/ done curtin in-target -- update-initramfs -u -k all fi # If the installed kernel cannot supply the RTL8922AE module, preserve an # actionable first-boot marker even when the live kernel had working Wi-Fi. # Ubuntu normally boots its newest installed kernel; a missing boot image or # an inconclusive modinfo check is treated as not yet verified. - | for dev in /sys/bus/pci/devices/*; do [ -r "$dev/vendor" ] && [ -r "$dev/device" ] || continue [ "$(cat "$dev/vendor")" = 0x10ec ] && [ "$(cat "$dev/device")" = 0x8922 ] || continue image=$(find /target/boot -maxdepth 1 -type f -name 'vmlinuz-*' -printf '%f\n' 2>/dev/null | sort -V | tail -n 1) if [ -z "$image" ] || ! modinfo -b /target -k "${image#vmlinuz-}" rtw89_8922ae >/dev/null 2>&1; then install -d -m 0700 /target/var/lib/nalvo-firstboot printf '%s\n' 'Wi-Fi is not ready on this computer. Connect an Ethernet cable.' > /target/var/lib/nalvo-firstboot/wifi-driver-missing fi done # Apply to every installed netplan file, including Subiquity's generated # Ethernet configuration. A missing cable must not hold up a Wi-Fi boot. - | python3 - <<'PY' import glob, os, stat, tempfile, yaml paths = sorted(glob.glob('/target/etc/netplan/*.yaml')) documents = [] for path in paths: with open(path, encoding='utf-8') as source: doc = yaml.safe_load(source) or {} documents.append((path, doc)) has_ethernet = any(bool(doc.get('network', {}).get('ethernets')) for _, doc in documents) for path, doc in documents: network = doc.get('network', {}) for interface in (network.get('ethernets') or {}).values(): interface['optional'] = True if has_ethernet: for interface in (network.get('wifis') or {}).values(): interface['optional'] = True mode = stat.S_IMODE(os.stat(path).st_mode) fd, temp = tempfile.mkstemp(dir=os.path.dirname(path), prefix='.nalvo-netplan-') try: with os.fdopen(fd, 'w', encoding='utf-8') as out: os.fchmod(out.fileno(), mode) yaml.safe_dump(doc, out, sort_keys=False, allow_unicode=True) os.replace(temp, path) finally: if os.path.exists(temp): os.unlink(temp) PY - | install -d -m 0755 /target/etc/default/grub.d /target/etc/systemd/system/systemd-networkd-wait-online.service.d printf '%s\n' 'GRUB_CMDLINE_LINUX_DEFAULT="quiet splash loglevel=3"' 'GRUB_CMDLINE_LINUX="${GRUB_CMDLINE_LINUX:+$GRUB_CMDLINE_LINUX }systemd.show_status=false"' > /target/etc/default/grub.d/99-nalvo-quiet.cfg printf '%s\n' '[Service]' 'ExecStart=' 'ExecStart=/lib/systemd/systemd-networkd-wait-online --any --timeout=30' > /target/etc/systemd/system/systemd-networkd-wait-online.service.d/nalvo.conf - curtin in-target -- update-grub - "install -D -m 0644 /var/log/nalvo-early.log /target/var/log/nalvo-early.log || true" - curtin in-target -- /usr/local/sbin/nalvo-firstboot install # When the early commands chose the disk the install is non-interactive, so the # installer wrote this file and casper would reboot without asking to remove the # stick (the machine could then start the stick again). Bring the prompt back. - rm -f /run/casper-no-prompt shutdown: reboot