memoscan
← all memos

Memo 0x91b6ef6e…11dd79 on Ethereum

lZCkKICAgICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAgICAgIAovLyBMb2dnZXIgLSBTdHJ1Y3R1cmVkIGxvZ2dpbmcgc3lzdGVtIGZvciBkZWJ1Z2dpbmcKLy8gQ3JpdGljYWwgZm9yIG1vYmlsZSBkZWJ1Z2dpbmcgYW5kIHJlbW90ZSB0ZXN0aW5nCgpjbGFzcyBMb2dnZXIgewogICAgc3RhdGljIGxldmVscyA9IHsKICAgICAgICBERUJVRzogMCwKICAgICAgICBJTkZPOiAxLAogICAgICAgIFdBUk46IDIsCiAgICAgICAgRVJST1I6IDMKICAgIH07CiAgICAKICAgIHN0YXRpYyBjdXJyZW50TGV2ZWwgPSBMb2dnZXIubGV2ZWxzLklORk87CiAgICBzdGF0aWMgbG9ncyA9IFtdOyAgLy8gU3RvcmUgbG9ncyBmb3IgcmVtb3RlIGRlYnVnZ2luZwogICAgc3RhdGljIG1heExvZ3MgPSAxMDAwOwogICAgCiAgICAvKioKICAgICAqIExvZyBhIG1lc3NhZ2Ugd2l0aCBsZXZlbCwgY29tcG9uZW50LCBhbmQgb3B0aW9uYWwgZGF0YQogICAgICovCiAgICBzdGF0aWMgbG9nKGxldmVsLCBjb21wb25lbnQsIG1lc3NhZ2UsIGRhdGEgPSBudWxsKSB7CiAgICAgICAgaWYgKGxldmVsIDwgTG9nZ2VyLmN1cnJlbnRMZXZlbCkgcmV0dXJuOwogICAgICAgIAogICAgICAgIGNvbnN0IHRpbWVzdGFtcCA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKTsKICAgICAgICBjb25zdCBsZXZlbE5hbWUgPSBPYmplY3Qua2V5cyhMb2dnZXIubGV2ZWxzKVtsZXZlbF07CiAgICAgICAgCiAgICAgICAgY29uc3QgbG9nRW50cnkgPSB7CiAgICAgICAgICAgIHRpbWVzdGFtcCwKICAgICAgICAgICAgbGV2ZWw6IGxldmVsTmFtZSwKICAgICAgICAgICAgY29tcG9uZW50LAogICAgICAgICAgICBtZXNzYWdlLAogICAgICAgICAgICBkYXRhCiAgICAgICAgfTsKICAgICAgICAKICAgICAgICAvLyBTdG9yZSBsb2cKICAgICAgICBMb2dnZXIubG9ncy5wdXNoKGxvZ0VudHJ5KTsKICAgICAgICAKICAgICAgICAvLyBLZWVwIG9ubHkgbGFzdCBOIGxvZ3MKICAgICAgICBpZiAoTG9nZ2VyLmxvZ3MubGVuZ3RoID4gTG9nZ2VyLm1heExvZ3MpIHsKICAgICAgICAgICAgTG9nZ2VyLmxvZ3Muc2hpZnQoKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gQ29uc29sZSBvdXRwdXQgd2l0aCBjb2xvciBjb2RpbmcKICAgICAgICBjb25zdCBjb25zb2xlTWV0aG9kID0gWydsb2cnLCAnaW5mbycsICd3YXJuJywgJ2Vycm9yJ11bbGV2ZWxdOwogICAgICAgIGNvbnN0IHByZWZpeCA9IGBbJHtsZXZlbE5hbWV9XSBbJHtjb21wb25lbnR9XWA7CiAgICAgICAgCiAgICAgICAgaWYgKGRhdGEgIT09IG51bGwpIHsKICAgICAgICAgICAgY29uc29sZVtjb25zb2xlTWV0aG9kXShwcmVmaXgsIG1lc3NhZ2UsIGRhdGEpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNvbnNvbGVbY29uc29sZU1ldGhvZF0ocHJlZml4LCBtZXNzYWdlKTsKICAgICAgICB9CiAgICB9CiAgICAKICAgIHN0YXRpYyBkZWJ1Zyhjb21wb25lbnQsIG1lc3NhZ2UsIGRhdGEgPSBudWxsKSB7CiAgICAgICAgTG9nZ2VyLmxvZyhMb2dnZXIubGV2ZWxzLkRFQlVHLCBjb21wb25lbnQsIG1lc3NhZ2UsIGRhdGEpOwogICAgfQogICAgCiAgICBzdGF0aWMgaW5mbyhjb21wb25lbnQsIG1lc3NhZ2UsIGRhdGEgPSBudWxsKSB7CiAgICAgICAgTG9nZ2VyLmxvZyhMb2dnZXIubGV2ZWxzLklORk8sIGNvbXBvbmVudCwgbWVzc2FnZSwgZGF0YSk7CiAgICB9CiAgICAKICAgIHN0YXRpYyB3YXJuKGNvbXBvbmVudCwgbWVzc2FnZSwgZGF0YSA9IG51bGwpIHsKICAgICAgICBMb2dnZXIubG9nKExvZ2dlci5sZXZlbHMuV0FSTiwgY29tcG9uZW50LCBtZXNzYWdlLCBkYXRhKTsKICAgIH0KICAgIAogICAgc3RhdGljIGVycm9yKGNvbXBvbmVudCwgbWVzc2FnZSwgZGF0YSA9IG51bGwpIHsKICAgICAgICBMb2dnZXIubG9nKExvZ2dlci5sZXZlbHMuRVJST1IsIGNvbXBvbmVudCwgbWVzc2FnZSwgZGF0YSk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogRXhwb3J0IGxvZ3MgYXMgSlNPTiAoZm9yIHJlbW90ZSBkZWJ1Z2dpbmcpCiAgICAgKi8KICAgIHN0YXRpYyBleHBvcnRMb2dzKCkgewogICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShMb2dnZXIubG9ncywgbnVsbCwgMik7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogRG93bmxvYWQgbG9ncyBhcyBmaWxlIChmb3IgbW9iaWxlIGRlYnVnZ2luZykKICAgICAqLwogICAgc3RhdGljIGRvd25sb2FkTG9ncygpIHsKICAgICAgICBjb25zdCBsb2dEYXRhID0gTG9nZ2VyLmV4cG9ydExvZ3MoKTsKICAgICAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW2xvZ0RhdGFdLCB7IHR5cGU6ICdhcHBsaWNhdGlvbi9qc29uJyB9KTsKICAgICAgICBjb25zdCB1cmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpOwogICAgICAgIAogICAgICAgIGNvbnN0IGxpbmsgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7CiAgICAgICAgbGluay5ocmVmID0gdXJsOwogICAgICAgIGxpbmsuZG93bmxvYWQgPSBgdHYtc3RhdGljLWxvZ3MtJHtEYXRlLm5vdygpfS5qc29uYDsKICAgICAgICBsaW5rLmNsaWNrKCk7CiAgICAgICAgCiAgICAgICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpOwogICAgICAgIExvZ2dlci5pbmZvKCdMT0dHRVInLCAnTG9ncyBkb3dubG9hZGVkJyk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2hvdyBkZWJ1ZyBvdmVybGF5IChmb3IgbW9iaWxlIGRlYnVnZ2luZykKICAgICAqLwogICAgc3RhdGljIHNob3dEZWJ1Z092ZXJsYXkoKSB7CiAgICAgICAgLy8gUmVtb3ZlIGV4aXN0aW5nIG92ZXJsYXkgaWYgcHJlc2VudAogICAgICAgIGNvbnN0IGV4aXN0aW5nID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RlYnVnLW92ZXJsYXknKTsKICAgICAgICBpZiAoZXhpc3RpbmcpIHsKICAgICAgICAgICAgZXhpc3RpbmcucmVtb3ZlKCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgY29uc3Qgb3ZlcmxheSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOwogICAgICAgIG92ZXJsYXkuaWQgPSAnZGVidWctb3ZlcmxheSc7CiAgICAgICAgb3ZlcmxheS5zdHlsZS5jc3NUZXh0ID0gYAogICAgICAgICAgICBwb3NpdGlvbjogZml4ZWQ7CiAgICAgICAgICAgIHRvcDogMTBweDsKICAgICAgICAgICAgcmlnaHQ6IDEwcHg7CiAgICAgICAgICAgIHdpZHRoOiAzMDBweDsKICAgICAgICAgICAgbWF4LWhlaWdodDogNDAwcHg7CiAgICAgICAgICAgIGJhY2tncm91bmQ6IHJnYmEoMCwgMCwgMCwgMC45KTsKICAgICAgICAgICAgY29sb3I6ICMwZjA7CiAgICAgICAgICAgIGZvbnQtZmFtaWx5OiBtb25vc3BhY2U7CiAgICAgICAgICAgIGZvbnQtc2l6ZTogMTBweDsKICAgICAgICAgICAgcGFkZGluZzogMTBweDsKICAgICAgICAgICAgb3ZlcmZsb3cteTogYXV0bzsKICAgICAgICAgICAgei1pbmRleDogMTAwMDA7CiAgICAgICAgICAgIGJvcmRlcjogMXB4IHNvbGlkICMwZjA7CiAgICAgICAgICAgIHBvaW50ZXItZXZlbnRzOiBub25lOwogICAgICAgIGA7CiAgICAgICAgCiAgICAgICAgLy8gRm9ybWF0IHJlY2VudCBsb2dzCiAgICAgICAgY29uc3QgcmVjZW50TG9ncyA9IExvZ2dlci5sb2dzLnNsaWNlKC01MCk7CiAgICAgICAgb3ZlcmxheS5pbm5lckhUTUwgPSByZWNlbnRMb2dzLm1hcChsb2cgPT4gCiAgICAgICAgICAgIGA8ZGl2IHN0eWxlPSJtYXJnaW4tYm90dG9tOiA1cHg7IGNvbG9yOiAkewogICAgICAgICAgICAgICAgbG9nLmxldmVsID09PSAnRVJST1InID8gJyNmMDAnIDogCiAgICAgICAgICAgICAgICBsb2cubGV2ZWwgPT09ICdXQVJOJyA/ICcjZmYwJyA6IAogICAgICAgICAgICAgICAgbG9nLmxldmVsID09PSAnSU5GTycgPyAnIzBmMCcgOiAKICAgICAgICAgICAgICAgICcjODg4JwogICAgICAgICAgICB9Ij4KICAgICAgICAgICAgICAgIFske2xvZy5sZXZlbH1dICR7bG9nLmNvbXBvbmVudH06ICR7bG9nLm1lc3NhZ2V9CiAgICAgICAgICAgIDwvZGl2PmAKICAgICAgICApLmpvaW4oJycpOwogICAgICAgIAogICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQob3ZlcmxheSk7CiAgICAgICAgTG9nZ2VyLmluZm8oJ0xPR0dFUicsICdEZWJ1ZyBvdmVybGF5IGRpc3BsYXllZCcpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIENsZWFyIGFsbCBsb2dzCiAgICAgKi8KICAgIHN0YXRpYyBjbGVhckxvZ3MoKSB7CiAgICAgICAgTG9nZ2VyLmxvZ3MgPSBbXTsKICAgICAgICBMb2dnZXIuaW5mbygnTE9HR0VSJywgJ0xvZ3MgY2xlYXJlZCcpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldCBsb2dnaW5nIGxldmVsCiAgICAgKi8KICAgIHN0YXRpYyBzZXRMZXZlbChsZXZlbCkgewogICAgICAgIExvZ2dlci5jdXJyZW50TGV2ZWwgPSBsZXZlbDsKICAgICAgICBMb2dnZXIuaW5mbygnTE9HR0VSJywgYExvZyBsZXZlbCBzZXQgdG8gJHtPYmplY3Qua2V5cyhMb2dnZXIubGV2ZWxzKVtsZXZlbF19YCk7CiAgICB9Cn0KCi8vIEdsb2JhbCBrZXlib2FyZCBzaG9ydGN1dHMgZm9yIGRlYnVnZ2luZyAoZGV2IG1vZGUpCmlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykgewogICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCAoZSkgPT4gewogICAgICAgIC8vIEN0cmwrU2hpZnQrRCA9IFRvZ2dsZSBkZWJ1ZyBvdmVybGF5CiAgICAgICAgaWYgKGUuY3RybEtleSAmJiBlLnNoaWZ0S2V5ICYmIGUua2V5ID09PSAnRCcpIHsKICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICBMb2dnZXIuc2hvd0RlYnVnT3ZlcmxheSgpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyBDdHJsK1NoaWZ0K0wgPSBEb3dubG9hZCBsb2dzCiAgICAgICAgaWYgKGUuY3RybEtleSAmJiBlLnNoaWZ0S2V5ICYmIGUua2V5ID09PSAnTCcpIHsKICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICBMb2dnZXIuZG93bmxvYWRMb2dzKCk7CiAgICAgICAgfQogICAgfSk7Cn0KCi8vIEV4cG9ydCBmb3IgRVMgbW9kdWxlcwpMb2dnZXI7CgoKLy8gSVJlbmRlcmVyLmpzIC0gQWJzdHJhY3QgcmVuZGVyZXIgaW50ZXJmYWNlCi8vIEJvdGggV2ViR1BVIGFuZCBXZWJHTCByZW5kZXJlcnMgbXVzdCBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UKLy8gRW5zdXJlcyB0aGV5IGNhbiBiZSB1c2VkIGludGVyY2hhbmdlYWJseSBieSB0aGUgYXBwbGljYXRpb24KCi8qKgogKiBBYnN0cmFjdCBiYXNlIGNsYXNzIGZvciByZW5kZXJlcnMKICogRGVmaW5lcyB0aGUgY29udHJhY3QgdGhhdCBib3RoIFdlYkdQVSBhbmQgV2ViR0wgcmVuZGVyZXJzIG11c3QgZm9sbG93CiAqLwpjbGFzcyBJUmVuZGVyZXIgewogICAgY29uc3RydWN0b3IodHlwZSkgewogICAgICAgIHRoaXMudHlwZSA9IHR5cGU7ICAvLyAnd2ViZ3B1JyBvciAnd2ViZ2wnCiAgICAgICAgCiAgICAgICAgdGhpcy5zdGF0ZSA9IHsKICAgICAgICAgICAgaXNJbml0aWFsaXplZDogZmFsc2UsCiAgICAgICAgICAgIGNhbnZhczogbnVsbAogICAgICAgIH07CiAgICB9CiAgICAKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZSB0aGUgcmVuZGVyZXIgd2l0aCBhIGNhbnZhcwogICAgICogQHBhcmFtIHtIVE1MQ2FudmFzRWxlbWVudH0gY2FudmFzIC0gVGFyZ2V0IGNhbnZhcyBlbGVtZW50CiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gVHJ1ZSBpZiBpbml0aWFsaXphdGlvbiBzdWNjZXNzZnVsCiAgICAgKi8KICAgIGFzeW5jIGluaXRpYWxpemUoY2FudmFzKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3RoaXMuY29uc3RydWN0b3IubmFtZX0gbXVzdCBpbXBsZW1lbnQgaW5pdGlhbGl6ZSgpYCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmVnaXN0ZXIgYW4gZWZmZWN0IHdpdGggdGhlIHJlbmRlcmVyCiAgICAgKiBAcGFyYW0ge0VmZmVjdH0gZWZmZWN0IC0gRWZmZWN0IGluc3RhbmNlIHRvIHJlZ2lzdGVyCiAgICAgKi8KICAgIGFzeW5jIHJlZ2lzdGVyRWZmZWN0KGVmZmVjdCkgewogICAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9IG11c3QgaW1wbGVtZW50IHJlZ2lzdGVyRWZmZWN0KClgKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDcmVhdGUgcmVuZGVyaW5nIHBpcGVsaW5lIGZvciBhbiBlZmZlY3QKICAgICAqIEBwYXJhbSB7RWZmZWN0fSBlZmZlY3QgLSBFZmZlY3QgdG8gY3JlYXRlIHBpcGVsaW5lIGZvcgogICAgICogQHBhcmFtIHtib29sZWFufSBuZWVkc1RleHR1cmVJbnB1dCAtIFdoZXRoZXIgZWZmZWN0IG5lZWRzIHRleHR1cmUgaW5wdXQgKGZvciBwb3N0LXByb2Nlc3NpbmcpCiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxhbnk+fSBDcmVhdGVkIHBpcGVsaW5lICh0eXBlIGRlcGVuZHMgb24gcmVuZGVyZXIpCiAgICAgKi8KICAgIGFzeW5jIGNyZWF0ZVBpcGVsaW5lKGVmZmVjdCwgbmVlZHNUZXh0dXJlSW5wdXQgPSBmYWxzZSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9IG11c3QgaW1wbGVtZW50IGNyZWF0ZVBpcGVsaW5lKClgKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDcmVhdGUgaW50ZXJtZWRpYXRlIHRleHR1cmUgZm9yIG11bHRpLXBhc3MgcmVuZGVyaW5nCiAgICAgKiBAcGFyYW0ge251bWJlcn0gd2lkdGggLSBUZXh0dXJlIHdpZHRoCiAgICAgKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0IC0gVGV4dHVyZSBoZWlnaHQKICAgICAqLwogICAgY3JlYXRlSW50ZXJtZWRpYXRlVGV4dHVyZSh3aWR0aCwgaGVpZ2h0KSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3RoaXMuY29uc3RydWN0b3IubmFtZX0gbXVzdCBpbXBsZW1lbnQgY3JlYXRlSW50ZXJtZWRpYXRlVGV4dHVyZSgpYCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmVuZGVyIGEgc2luZ2xlIGVmZmVjdCBkaXJlY3RseSB0byBzY3JlZW4KICAgICAqIEBwYXJhbSB7RWZmZWN0fSBlZmZlY3QgLSBFZmZlY3QgdG8gcmVuZGVyCiAgICAgKiBAcGFyYW0ge251bWJlcn0gdGltZXN0YW1wIC0gQ3VycmVudCB0aW1lc3RhbXAKICAgICAqIEBwYXJhbSB7bnVtYmVyfSB3aWR0aCAtIENhbnZhcyB3aWR0aAogICAgICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodCAtIENhbnZhcyBoZWlnaHQKICAgICAqLwogICAgcmVuZGVyU2luZ2xlUGFzcyhlZmZlY3QsIHRpbWVzdGFtcCwgd2lkdGgsIGhlaWdodCkgewogICAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9IG11c3QgaW1wbGVtZW50IHJlbmRlclNpbmdsZVBhc3MoKWApOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJlbmRlciB0d28gZWZmZWN0cyBpbiBzZXF1ZW5jZSAobXVsdGktcGFzcyByZW5kZXJpbmcpCiAgICAgKiBAcGFyYW0ge0VmZmVjdH0gZmlyc3RFZmZlY3QgLSBGaXJzdCBlZmZlY3QgKHJlbmRlcnMgdG8gaW50ZXJtZWRpYXRlIHRleHR1cmUpCiAgICAgKiBAcGFyYW0ge0VmZmVjdH0gc2Vjb25kRWZmZWN0IC0gU2Vjb25kIGVmZmVjdCAocmVhZHMgdGV4dHVyZSwgcmVuZGVycyB0byBzY3JlZW4pCiAgICAgKiBAcGFyYW0ge251bWJlcn0gdGltZXN0YW1wIC0gQ3VycmVudCB0aW1lc3RhbXAKICAgICAqIEBwYXJhbSB7bnVtYmVyfSB3aWR0aCAtIENhbnZhcyB3aWR0aAogICAgICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodCAtIENhbnZhcyBoZWlnaHQKICAgICAqLwogICAgcmVuZGVyTXVsdGlQYXNzKGZpcnN0RWZmZWN0LCBzZWNvbmRFZmZlY3QsIHRpbWVzdGFtcCwgd2lkdGgsIGhlaWdodCkgewogICAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9IG11c3QgaW1wbGVtZW50IHJlbmRlck11bHRpUGFzcygpYCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogSGFuZGxlIGNhbnZhcyByZXNpemUKICAgICAqIEBwYXJhbSB7bnVtYmVyfSB3aWR0aCAtIE5ldyB3aWR0aAogICAgICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodCAtIE5ldyBoZWlnaHQKICAgICAqLwogICAgcmVzaXplKHdpZHRoLCBoZWlnaHQpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpcy5jb25zdHJ1Y3Rvci5uYW1lfSBtdXN0IGltcGxlbWVudCByZXNpemUoKWApOwogICAgfQogICAgCiAgICAvKioKICAgICAqIEdldCByZW5kZXJlciB0eXBlICgnd2ViZ3B1JyBvciAnd2ViZ2wnKQogICAgICogQHJldHVybnMge3N0cmluZ30gUmVuZGVyZXIgdHlwZQogICAgICovCiAgICBnZXRUeXBlKCkgewogICAgICAgIHJldHVybiB0aGlzLnR5cGU7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogR2V0IHJlbmRlcmVyIHN0YXRlIGZvciBkZWJ1Z2dpbmcKICAgICAqIEByZXR1cm5zIHtPYmplY3R9IEN1cnJlbnQgc3RhdGUKICAgICAqLwogICAgZ2V0U3RhdGUoKSB7CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgdHlwZTogdGhpcy50eXBlLAogICAgICAgICAgICBpc0luaXRpYWxpemVkOiB0aGlzLnN0YXRlLmlzSW5pdGlhbGl6ZWQKICAgICAgICB9OwogICAgfQogICAgCiAgICAvKioKICAgICAqIENsZWFuIHVwIGFsbCBHUFUgcmVzb3VyY2VzCiAgICAgKi8KICAgIGRlc3Ryb3koKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3RoaXMuY29uc3RydWN0b3IubmFtZX0gbXVzdCBpbXBsZW1lbnQgZGVzdHJveSgpYCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogSGVscGVyIG1ldGhvZCBmb3IgbG9nZ2luZwogICAgICovCiAgICBsb2cobGV2ZWwsIG1lc3NhZ2UsIGRhdGEgPSBudWxsKSB7CiAgICAgICAgTG9nZ2VyW2xldmVsXSh0aGlzLnR5cGUudG9VcHBlckNhc2UoKSwgbWVzc2FnZSwgZGF0YSk7CiAgICB9Cn0KCklSZW5kZXJlcjsKCgovLyBXZWJHUFVSZW5kZXJlci5qcyAtIFdlYkdQVSByZW5kZXJpbmcgaW1wbGVtZW50YXRpb24KLy8gUmVmYWN0b3JlZCBmcm9tIHYxIG1haW4uanMgV2ViR1BVIGNvZGUKLy8gSW1wbGVtZW50cyBJUmVuZGVyZXIgaW50ZXJmYWNlIGZvciByZW5kZXJlciBhYnN0cmFjdGlvbgoKY2xhc3MgV2ViR1BVUmVuZGVyZXIgZXh0ZW5kcyBJUmVuZGVyZXIgewogICAgY29uc3RydWN0b3IoKSB7CiAgICAgICAgc3VwZXIoJ3dlYmdwdScpOwogICAgICAgIAogICAgICAgIHRoaXMuc3RhdGUgPSB7CiAgICAgICAgICAgIC4uLnRoaXMuc3RhdGUsICAvLyBJbmhlcml0IGZyb20gSVJlbmRlcmVyCiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBXZWJHUFUgcmVzb3VyY2VzCiAgICAgICAgICAgIGFkYXB0ZXI6IG51bGwsCiAgICAgICAgICAgIGRldmljZTogbnVsbCwKICAgICAgICAgICAgY29udGV4dDogbnVsbCwKICAgICAgICAgICAgZm9ybWF0OiBudWxsLAogICAgICAgICAgICAKICAgICAgICAgICAgLy8gTXVsdGktcGFzcyByZW5kZXJpbmcKICAgICAgICAgICAgbXVsdGlwYXNzOiB7CiAgICAgICAgICAgICAgICBpbnRlcm1lZGlhdGVUZXh0dXJlOiBudWxsLAogICAgICAgICAgICAgICAgaW50ZXJtZWRpYXRlVGV4dHVyZVZpZXc6IG51bGwsCiAgICAgICAgICAgICAgICBzYW1wbGVyOiBudWxsLAogICAgICAgICAgICAgICAgdGV4dHVyZUJpbmRHcm91cDogbnVsbCAgLy8gQ2FjaGVkIOKAlCByZWJ1aWx0IG9ubHkgb24gcmVzaXplLCBub3QgZXZlcnkgZnJhbWUKICAgICAgICAgICAgfSwKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIFBpcGVsaW5lcyAocmVnaXN0ZXJlZCBlZmZlY3RzKQogICAgICAgICAgICBwaXBlbGluZXM6IG5ldyBNYXAoKSwgIC8vIGVmZmVjdElkIOKGkiBHUFVSZW5kZXJQaXBlbGluZQogICAgICAgICAgICBlZmZlY3RzOiBuZXcgTWFwKCkgICAgIC8vIGVmZmVjdElkIOKGkiBFZmZlY3QgaW5zdGFuY2UKICAgICAgICB9OwogICAgfQogICAgCiAgICAvKioKICAgICAqIEluaXRpYWxpemUgV2ViR1BVCiAgICAgKiBAcGFyYW0ge0hUTUxDYW52YXNFbGVtZW50fSBjYW52YXMgLSBUYXJnZXQgY2FudmFzCiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gVHJ1ZSBpZiBzdWNjZXNzZnVsCiAgICAgKi8KICAgIGFzeW5jIGluaXRpYWxpemUoY2FudmFzLCBleGlzdGluZ0FkYXB0ZXIgPSBudWxsKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgdGhpcy5zdGF0ZS5jYW52YXMgPSBjYW52YXM7CiAgICAgICAgICAgIHRoaXMubG9nKCdpbmZvJywgJ0luaXRpYWxpemluZyBXZWJHUFUuLi4nKTsKCiAgICAgICAgICAgIC8vIENoZWNrIFdlYkdQVSBzdXBwb3J0CiAgICAgICAgICAgIGlmICghbmF2aWdhdG9yLmdwdSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZWJHUFUgbm90IHN1cHBvcnRlZCBpbiB0aGlzIGJyb3dzZXInKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gVXNlIHRoZSBhZGFwdGVyIGZyb20gUmVuZGVyZXJGYWN0b3J5IGRldGVjdGlvbiBpZiBwcm92aWRlZCwKICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIHJlcXVlc3QgYSBuZXcgb25lIChmYWxsYmFjayBmb3IgZGlyZWN0IGluc3RhbnRpYXRpb24pCiAgICAgICAgICAgIGlmIChleGlzdGluZ0FkYXB0ZXIpIHsKICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuYWRhcHRlciA9IGV4aXN0aW5nQWRhcHRlcjsKICAgICAgICAgICAgICAgIHRoaXMubG9nKCdpbmZvJywgJ1dlYkdQVSBhZGFwdGVyIHJldXNlZCBmcm9tIGRldGVjdGlvbiAoc2tpcHBpbmcgc2Vjb25kIHJlcXVlc3RBZGFwdGVyKScpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5hZGFwdGVyID0gYXdhaXQgbmF2aWdhdG9yLmdwdS5yZXF1ZXN0QWRhcHRlcih7CiAgICAgICAgICAgICAgICAgICAgcG93ZXJQcmVmZXJlbmNlOiAnaGlnaC1wZXJmb3JtYW5jZScKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIXRoaXMuc3RhdGUuYWRhcHRlcikgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBXZWJHUFUgYWRhcHRlciBmb3VuZCcpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLmxvZygnaW5mbycsICdXZWJHUFUgYWRhcHRlciBhY3F1aXJlZCcpOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gUmVxdWVzdCBkZXZpY2UKICAgICAgICAgICAgdGhpcy5zdGF0ZS5kZXZpY2UgPSBhd2FpdCB0aGlzLnN0YXRlLmFkYXB0ZXIucmVxdWVzdERldmljZSgpOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCF0aGlzLnN0YXRlLmRldmljZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gZ2V0IFdlYkdQVSBkZXZpY2UnKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgdGhpcy5sb2coJ2luZm8nLCAnV2ViR1BVIGRldmljZSBhY3F1aXJlZCcpOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gU2V0dXAgZGV2aWNlIGVycm9yIGhhbmRsaW5nIChjcml0aWNhbCBmb3IgaU9TIGRlYnVnZ2luZykKICAgICAgICAgICAgdGhpcy5zdGF0ZS5kZXZpY2UuYWRkRXZlbnRMaXN0ZW5lcigndW5jYXB0dXJlZGVycm9yJywgKGV2ZW50KSA9PiB7CiAgICAgICAgICAgICAgICB0aGlzLmxvZygnZXJyb3InLCAnV2ViR1BVIHVuY2FwdHVyZWQgZXJyb3I6JywgZXZlbnQuZXJyb3IpOwogICAgICAgICAgICAgICAgdGhpcy5sb2coJ2Vycm9yJywgJ0Vycm9yIHR5cGU6JywgZXZlbnQuZXJyb3IuY29uc3RydWN0b3IubmFtZSk7CiAgICAgICAgICAgICAgICB0aGlzLmxvZygnZXJyb3InLCAnRXJyb3IgbWVzc2FnZTonLCBldmVudC5lcnJvci5tZXNzYWdlKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBBbHNvIGxpc3RlbiBmb3IgZGV2aWNlIGxvc3QgZXZlbnRzIChpT1Mtc3BlY2lmaWMgaXNzdWVzKQogICAgICAgICAgICB0aGlzLnN0YXRlLmRldmljZS5sb3N0LnRoZW4oKGluZm8pID0+IHsKICAgICAgICAgICAgICAgIHRoaXMubG9nKCdlcnJvcicsIGBXZWJHUFUgZGV2aWNlIGxvc3Q6ICR7aW5mby5yZWFzb259YCk7CiAgICAgICAgICAgICAgICB0aGlzLmxvZygnZXJyb3InLCAnRGV2aWNlIGxvc3QgbWVzc2FnZTonLCBpbmZvLm1lc3NhZ2UpOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIFZhbGlkYXRlIGNhbnZhcyBiZWZvcmUgZ2V0dGluZyBjb250ZXh0CiAgICAgICAgICAgIGlmICghY2FudmFzIHx8ICEoY2FudmFzIGluc3RhbmNlb2YgSFRNTENhbnZhc0VsZW1lbnQpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY2FudmFzIGVsZW1lbnQgcHJvdmlkZWQnKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKCFjYW52YXMuaXNDb25uZWN0ZWQpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ2FudmFzIG11c3QgYmUgYXR0YWNoZWQgdG8gRE9NIGJlZm9yZSBnZXR0aW5nIFdlYkdQVSBjb250ZXh0Jyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIHRoaXMubG9nKCdkZWJ1ZycsIGBHZXR0aW5nIFdlYkdQVSBjb250ZXh0IGZyb20gY2FudmFzOiAke2NhbnZhcy5pZH0sICR7Y2FudmFzLndpZHRofXgke2NhbnZhcy5oZWlnaHR9YCk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBHZXQgY29udGV4dCAtIHRyeSB3aXRoIGVtcHR5IG9wdGlvbnMgZmlyc3QsIHRoZW4gd2l0aCBleHBsaWNpdCBvcHRpb25zCiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLmNvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dCgnd2ViZ3B1Jyk7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vIElmIHRoYXQgZGlkbid0IHdvcmssIHRyeSB3aXRoIGV4cGxpY2l0IG51bGwKICAgICAgICAgICAgICAgIGlmICghdGhpcy5zdGF0ZS5jb250ZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2coJ3dhcm4nLCAnRmlyc3QgY29udGV4dCBhdHRlbXB0IGZhaWxlZCwgdHJ5aW5nIHdpdGggZXhwbGljaXQgb3B0aW9ucy4uLicpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuY29udGV4dCA9IGNhbnZhcy5nZXRDb250ZXh0KCd3ZWJncHUnLCB7fSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGlmICghdGhpcy5zdGF0ZS5jb250ZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgLy8gRGV0YWlsZWQgZGlhZ25vc3RpYyBpbmZvCiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29udGV4dFR5cGVzID0gW107CiAgICAgICAgICAgICAgICAgICAgdHJ5IHsgaWYgKGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpKSBjb250ZXh0VHlwZXMucHVzaCgnMmQnKTsgfSBjYXRjaChlKSB7fQogICAgICAgICAgICAgICAgICAgIHRyeSB7IGlmIChjYW52YXMuZ2V0Q29udGV4dCgnd2ViZ2wnKSkgY29udGV4dFR5cGVzLnB1c2goJ3dlYmdsJyk7IH0gY2F0Y2goZSkge30KICAgICAgICAgICAgICAgICAgICB0cnkgeyBpZiAoY2FudmFzLmdldENvbnRleHQoJ3dlYmdsMicpKSBjb250ZXh0VHlwZXMucHVzaCgnd2ViZ2wyJyk7IH0gY2F0Y2goZSkge30KICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoCiAgICAgICAgICAgICAgICAgICAgICAgIGBGYWlsZWQgdG8gZ2V0IFdlYkdQVSBjb250ZXh0LlxuYCArCiAgICAgICAgICAgICAgICAgICAgICAgIGBDYW52YXMgSUQ6ICR7Y2FudmFzLmlkIHx8ICd1bm5hbWVkJ31cbmAgKwogICAgICAgICAgICAgICAgICAgICAgICBgRGltZW5zaW9uczogJHtjYW52YXMud2lkdGh9eCR7Y2FudmFzLmhlaWdodH1cbmAgKwogICAgICAgICAgICAgICAgICAgICAgICBgSW4gRE9NOiAke2NhbnZhcy5pc0Nvbm5lY3RlZH1cbmAgKwogICAgICAgICAgICAgICAgICAgICAgICBgUGFyZW50OiAke2NhbnZhcy5wYXJlbnRFbGVtZW50ID8gY2FudmFzLnBhcmVudEVsZW1lbnQudGFnTmFtZSA6ICdub25lJ31cbmAgKwogICAgICAgICAgICAgICAgICAgICAgICBgT3RoZXIgY29udGV4dHMgd29yazogJHtjb250ZXh0VHlwZXMuam9pbignLCAnKSB8fCAnbm9uZSB0cmllZCd9XG5gICsKICAgICAgICAgICAgICAgICAgICAgICAgYFRoaXMgbWF5IGJlIGNhdXNlZCBieSBhIGJyb3dzZXIgZXh0ZW5zaW9uIG9yIHRoZSBjYW52YXMgYWxyZWFkeSBoYXZpbmcgYSBjb250ZXh0LmAKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChlcnJvcikgewogICAgICAgICAgICAgICAgaWYgKGVycm9yLm1lc3NhZ2UgJiYgZXJyb3IubWVzc2FnZS5pbmNsdWRlcygnRmFpbGVkIHRvIGdldCBXZWJHUFUgY29udGV4dCcpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4Y2VwdGlvbiB3aGlsZSBnZXR0aW5nIFdlYkdQVSBjb250ZXh0OiAke2Vycm9yLm1lc3NhZ2V9YCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIHRoaXMubG9nKCdpbmZvJywgJ1dlYkdQVSBjb250ZXh0IG9idGFpbmVkIHN1Y2Nlc3NmdWxseScpOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gR2V0IHByZWZlcnJlZCBmb3JtYXQKICAgICAgICAgICAgdGhpcy5zdGF0ZS5mb3JtYXQgPSBuYXZpZ2F0b3IuZ3B1LmdldFByZWZlcnJlZENhbnZhc0Zvcm1hdCgpOwogICAgICAgICAgICAKICAgICAgICAgICAgdGhpcy5sb2coJ2luZm8nLCBgUHJlZmVycmVkIGNhbnZhcyBmb3JtYXQ6ICR7dGhpcy5zdGF0ZS5mb3JtYXR9YCk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBDb25maWd1cmUgY29udGV4dCAobWF0Y2ggdjEgc2V0dGluZ3MgZXhhY3RseSkKICAgICAgICAgICAgdGhpcy5zdGF0ZS5jb250ZXh0LmNvbmZpZ3VyZSh7CiAgICAgICAgICAgICAgICBkZXZpY2U6IHRoaXMuc3RhdGUuZGV2aWNlLAogICAgICAgICAgICAgICAgZm9ybWF0OiB0aGlzLnN0YXRlLmZvcm1hdCwKICAgICAgICAgICAgICAgIGFscGhhTW9kZTogJ29wYXF1ZScKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIAogICAgICAgICAgICB0aGlzLnN0YXRlLmlzSW5pdGlhbGl6ZWQgPSB0cnVlOwogICAgICAgICAgICB0aGlzLmxvZygnaW5mbycsIGBXZWJHUFUgaW5pdGlhbGl6ZWQgd2l0aCBmb3JtYXQ6ICR7dGhpcy5zdGF0ZS5mb3JtYXR9YCk7CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgCiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHsKICAgICAgICAgICAgdGhpcy5sb2coJ2Vycm9yJywgJ0ZhaWxlZCB0byBpbml0aWFsaXplIFdlYkdQVTonLCBlcnJvcik7CiAgICAgICAgICAgIHRocm93IGVycm9yOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZWdpc3RlciBhbiBlZmZlY3QgKGNyZWF0ZSBHUFUgcmVzb3VyY2VzKQogICAgICogQHBhcmFtIHtFZmZlY3R9IGVmZmVjdCAtIEVmZmVjdCBpbnN0YW5jZQogICAgICovCiAgICBhc3luYyByZWdpc3RlckVmZmVjdChlZmZlY3QpIHsKICAgICAgICBpZiAoIXRoaXMuc3RhdGUuaXNJbml0aWFsaXplZCkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlbmRlcmVyIG5vdCBpbml0aWFsaXplZCcpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICB0cnkgewogICAgICAgICAgICAvLyBDcmVhdGUgZWZmZWN0J3MgR1BVIHJlc291cmNlcyAodW5pZm9ybXMsIGJpbmQgZ3JvdXBzKQogICAgICAgICAgICBhd2FpdCBlZmZlY3QuY3JlYXRlVW5pZm9ybXModGhpcy5zdGF0ZS5kZXZpY2UpOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gU3RvcmUgZWZmZWN0IHJlZmVyZW5jZQogICAgICAgICAgICB0aGlzLnN0YXRlLmVmZmVjdHMuc2V0KGVmZmVjdC5pZCwgZWZmZWN0KTsKICAgICAgICAgICAgCiAgICAgICAgICAgIHRoaXMubG9nKCdkZWJ1ZycsIGBFZmZlY3QgcmVnaXN0ZXJlZDogJHtlZmZlY3QubmFtZX0gKElEOiAke2VmZmVjdC5pZH0pYCk7CiAgICAgICAgICAgIAogICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgICAgICAgIHRoaXMubG9nKCdlcnJvcicsIGBGYWlsZWQgdG8gcmVnaXN0ZXIgZWZmZWN0ICR7ZWZmZWN0Lm5hbWV9OmAsIGVycm9yKTsKICAgICAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgICAgfQogICAgfQogICAgCiAgICAvKioKICAgICAqIENyZWF0ZSByZW5kZXIgcGlwZWxpbmUgZm9yIGFuIGVmZmVjdAogICAgICogQHBhcmFtIHtFZmZlY3R9IGVmZmVjdCAtIEVmZmVjdCB0byBjcmVhdGUgcGlwZWxpbmUgZm9yCiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IG5lZWRzVGV4dHVyZUlucHV0IC0gV2hldGhlciBlZmZlY3QgbmVlZHMgdGV4dHVyZSBpbnB1dAogICAgICogQHJldHVybnMge1Byb21pc2U8R1BVUmVuZGVyUGlwZWxpbmU+fSBDcmVhdGVkIHBpcGVsaW5lCiAgICAgKi8KICAgIGFzeW5jIGNyZWF0ZVBpcGVsaW5lKGVmZmVjdCwgbmVlZHNUZXh0dXJlSW5wdXQgPSBmYWxzZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHRoaXMubG9nKCdkZWJ1ZycsIGBDcmVhdGluZyBwaXBlbGluZSBmb3IgJHtlZmZlY3QubmFtZX1gKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIFVzZSBlbWJlZGRlZCBzaGFkZXJzCiAgICAgICAgICAgIGNvbnN0IHZlcnRleENvZGUgPSBXRUJHUFVfU0hBREVSUy52ZXJ0ZXhfZnVsbHNjcmVlbjsKICAgICAgICAgICAgY29uc3QgZnJhZ21lbnRDb2RlID0gZWZmZWN0LmlkID09PSAwID8gV0VCR1BVX1NIQURFUlMudHZfc3RhdGljIDogV0VCR1BVX1NIQURFUlMucGl4ZWxpemF0aW9uOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gQ3JlYXRlIHNoYWRlciBtb2R1bGVzIHdpdGggdmFsaWRhdGlvbgogICAgICAgICAgICBjb25zdCB2ZXJ0ZXhNb2R1bGUgPSB0aGlzLnN0YXRlLmRldmljZS5jcmVhdGVTaGFkZXJNb2R1bGUoewogICAgICAgICAgICAgICAgY29kZTogdmVydGV4Q29kZSwKICAgICAgICAgICAgICAgIGxhYmVsOiBgJHtlZmZlY3QubmFtZX0gVmVydGV4IFNoYWRlcmAKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBDaGVjayBmb3Igc2hhZGVyIGNvbXBpbGF0aW9uIGVycm9ycyAoZXNwZWNpYWxseSBpbXBvcnRhbnQgZm9yIGlPUykKICAgICAgICAgICAgY29uc3QgdmVydGV4SW5mbyA9IGF3YWl0IHZlcnRleE1vZHVsZS5nZXRDb21waWxhdGlvbkluZm8oKTsKICAgICAgICAgICAgaWYgKHZlcnRleEluZm8ubWVzc2FnZXMubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgZm9yIChjb25zdCBtZXNzYWdlIG9mIHZlcnRleEluZm8ubWVzc2FnZXMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS50eXBlID09PSAnZXJyb3InKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nKCdlcnJvcicsIGBWZXJ0ZXggc2hhZGVyIGVycm9yOiAke21lc3NhZ2UubWVzc2FnZX1gKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBWZXJ0ZXggc2hhZGVyIGNvbXBpbGF0aW9uIGZhaWxlZDogJHttZXNzYWdlLm1lc3NhZ2V9YCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChtZXNzYWdlLnR5cGUgPT09ICd3YXJuaW5nJykgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZygnd2FybicsIGBWZXJ0ZXggc2hhZGVyIHdhcm5pbmc6ICR7bWVzc2FnZS5tZXNzYWdlfWApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgY29uc3QgZnJhZ21lbnRNb2R1bGUgPSB0aGlzLnN0YXRlLmRldmljZS5jcmVhdGVTaGFkZXJNb2R1bGUoewogICAgICAgICAgICAgICAgY29kZTogZnJhZ21lbnRDb2RlLAogICAgICAgICAgICAgICAgbGFiZWw6IGAke2VmZmVjdC5uYW1lfSBGcmFnbWVudCBTaGFkZXJgCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIGZyYWdtZW50IHNoYWRlciBjb21waWxhdGlvbiBlcnJvcnMKICAgICAgICAgICAgY29uc3QgZnJhZ21lbnRJbmZvID0gYXdhaXQgZnJhZ21lbnRNb2R1bGUuZ2V0Q29tcGlsYXRpb25JbmZvKCk7CiAgICAgICAgICAgIGlmIChmcmFnbWVudEluZm8ubWVzc2FnZXMubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgZm9yIChjb25zdCBtZXNzYWdlIG9mIGZyYWdtZW50SW5mby5tZXNzYWdlcykgewogICAgICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLnR5cGUgPT09ICdlcnJvcicpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2coJ2Vycm9yJywgYEZyYWdtZW50IHNoYWRlciBlcnJvcjogJHttZXNzYWdlLm1lc3NhZ2V9YCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRnJhZ21lbnQgc2hhZGVyIGNvbXBpbGF0aW9uIGZhaWxlZDogJHttZXNzYWdlLm1lc3NhZ2V9YC