LyoKICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCiAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAogKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCiAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCiAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCiAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICovCgpwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5sYW5nOwoKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLmlvLlN0cmluZ1dyaXRlcjsKaW1wb3J0IGphdmEuaW8uV3JpdGVyOwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLlRyZWVNYXA7CgovKioKICogPHA+CiAqIFByb3ZpZGVzIEhUTUwgYW5kIFhNTCBlbnRpdHkgdXRpbGl0aWVzLgogKiA8L3A+CiAqIAogKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly9ob3R3aXJlZC5seWNvcy5jb20vd2VibW9ua2V5L3JlZmVyZW5jZS9zcGVjaWFsX2NoYXJhY3RlcnMvIj5JU08gRW50aXRpZXM8L2E+CiAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWwzMiNsYXRpbjEiPkhUTUwgMy4yIENoYXJhY3RlciBFbnRpdGllcyBmb3IgSVNPIExhdGluLTE8L2E+CiAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MC9zZ21sL2VudGl0aWVzLmh0bWwiPkhUTUwgNC4wIENoYXJhY3RlciBlbnRpdHkgcmVmZXJlbmNlczwvYT4KICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9odG1sNDAxL2NoYXJzZXQuaHRtbCNoLTUuMyI+SFRNTCA0LjAxIENoYXJhY3RlciBSZWZlcmVuY2VzPC9hPgogKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL2h0bWw0MDEvY2hhcnNldC5odG1sI2NvZGUtcG9zaXRpb24iPkhUTUwgNC4wMSBDb2RlIHBvc2l0aW9uczwvYT4KICogCiAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOmFsZXhAcHVycGxldGVjaC5jb20iPkFsZXhhbmRlciBEYXkgQ2hhZmZlZTwvYT4KICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86Z2dyZWdvcnlAc2VhZ3VsbHN3LmNvbSI+R2FyeSBHcmVnb3J5PC9hPgogKiBAc2luY2UgMi4wCiAqIEB2ZXJzaW9uICRJZCQKICovCmNsYXNzIEVudGl0aWVzIHsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXVtdIEJBU0lDX0FSUkFZID0ge3sicXVvdCIsICIzNCJ9LCAvLyAiIC0gZG91YmxlLXF1b3RlCiAgICAgICAgeyJhbXAiLCAiMzgifSwgLy8gJiAtIGFtcGVyc2FuZAogICAgICAgIHsibHQiLCAiNjAifSwgLy8gPCAtIGxlc3MtdGhhbgogICAgICAgIHsiZ3QiLCAiNjIifSwgLy8gPiAtIGdyZWF0ZXItdGhhbgogICAgfTsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXVtdIEFQT1NfQVJSQVkgPSB7eyJhcG9zIiwgIjM5In0sIC8vIFhNTCBhcG9zdHJvcGhlCiAgICB9OwoKICAgIC8vIHBhY2thZ2Ugc2NvcGVkIGZvciB0ZXN0aW5nCiAgICBzdGF0aWMgZmluYWwgU3RyaW5nW11bXSBJU084ODU5XzFfQVJSQVkgPSB7eyJuYnNwIiwgIjE2MCJ9LCAvLyBub24tYnJlYWtpbmcgc3BhY2UKICAgICAgICB7ImlleGNsIiwgIjE2MSJ9LCAvLyBpbnZlcnRlZCBleGNsYW1hdGlvbiBtYXJrCiAgICAgICAgeyJjZW50IiwgIjE2MiJ9LCAvLyBjZW50IHNpZ24KICAgICAgICB7InBvdW5kIiwgIjE2MyJ9LCAvLyBwb3VuZCBzaWduCiAgICAgICAgeyJjdXJyZW4iLCAiMTY0In0sIC8vIGN1cnJlbmN5IHNpZ24KICAgICAgICB7InllbiIsICIxNjUifSwgLy8geWVuIHNpZ24gPSB5dWFuIHNpZ24KICAgICAgICB7ImJydmJhciIsICIxNjYifSwgLy8gYnJva2VuIGJhciA9IGJyb2tlbiB2ZXJ0aWNhbCBiYXIKICAgICAgICB7InNlY3QiLCAiMTY3In0sIC8vIHNlY3Rpb24gc2lnbgogICAgICAgIHsidW1sIiwgIjE2OCJ9LCAvLyBkaWFlcmVzaXMgPSBzcGFjaW5nIGRpYWVyZXNpcwogICAgICAgIHsiY29weSIsICIxNjkifSwgLy8gqSAtIGNvcHlyaWdodCBzaWduCiAgICAgICAgeyJvcmRmIiwgIjE3MCJ9LCAvLyBmZW1pbmluZSBvcmRpbmFsIGluZGljYXRvcgogICAgICAgIHsibGFxdW8iLCAiMTcxIn0sIC8vIGxlZnQtcG9pbnRpbmcgZG91YmxlIGFuZ2xlIHF1b3RhdGlvbiBtYXJrID0gbGVmdCBwb2ludGluZyBndWlsbGVtZXQKICAgICAgICB7Im5vdCIsICIxNzIifSwgLy8gbm90IHNpZ24KICAgICAgICB7InNoeSIsICIxNzMifSwgLy8gc29mdCBoeXBoZW4gPSBkaXNjcmV0aW9uYXJ5IGh5cGhlbgogICAgICAgIHsicmVnIiwgIjE3NCJ9LCAvLyCuIC0gcmVnaXN0ZXJlZCB0cmFkZW1hcmsgc2lnbgogICAgICAgIHsibWFjciIsICIxNzUifSwgLy8gbWFjcm9uID0gc3BhY2luZyBtYWNyb24gPSBvdmVybGluZSA9IEFQTCBvdmVyYmFyCiAgICAgICAgeyJkZWciLCAiMTc2In0sIC8vIGRlZ3JlZSBzaWduCiAgICAgICAgeyJwbHVzbW4iLCAiMTc3In0sIC8vIHBsdXMtbWludXMgc2lnbiA9IHBsdXMtb3ItbWludXMgc2lnbgogICAgICAgIHsic3VwMiIsICIxNzgifSwgLy8gc3VwZXJzY3JpcHQgdHdvID0gc3VwZXJzY3JpcHQgZGlnaXQgdHdvID0gc3F1YXJlZAogICAgICAgIHsic3VwMyIsICIxNzkifSwgLy8gc3VwZXJzY3JpcHQgdGhyZWUgPSBzdXBlcnNjcmlwdCBkaWdpdCB0aHJlZSA9IGN1YmVkCiAgICAgICAgeyJhY3V0ZSIsICIxODAifSwgLy8gYWN1dGUgYWNjZW50ID0gc3BhY2luZyBhY3V0ZQogICAgICAgIHsibWljcm8iLCAiMTgxIn0sIC8vIG1pY3JvIHNpZ24KICAgICAgICB7InBhcmEiLCAiMTgyIn0sIC8vIHBpbGNyb3cgc2lnbiA9IHBhcmFncmFwaCBzaWduCiAgICAgICAgeyJtaWRkb3QiLCAiMTgzIn0sIC8vIG1pZGRsZSBkb3QgPSBHZW9yZ2lhbiBjb21tYSA9IEdyZWVrIG1pZGRsZSBkb3QKICAgICAgICB7ImNlZGlsIiwgIjE4NCJ9LCAvLyBjZWRpbGxhID0gc3BhY2luZyBjZWRpbGxhCiAgICAgICAgeyJzdXAxIiwgIjE4NSJ9LCAvLyBzdXBlcnNjcmlwdCBvbmUgPSBzdXBlcnNjcmlwdCBkaWdpdCBvbmUKICAgICAgICB7Im9yZG0iLCAiMTg2In0sIC8vIG1hc2N1bGluZSBvcmRpbmFsIGluZGljYXRvcgogICAgICAgIHsicmFxdW8iLCAiMTg3In0sIC8vIHJpZ2h0LXBvaW50aW5nIGRvdWJsZSBhbmdsZSBxdW90YXRpb24gbWFyayA9IHJpZ2h0IHBvaW50aW5nIGd1aWxsZW1ldAogICAgICAgIHsiZnJhYzE0IiwgIjE4OCJ9LCAvLyB2dWxnYXIgZnJhY3Rpb24gb25lIHF1YXJ0ZXIgPSBmcmFjdGlvbiBvbmUgcXVhcnRlcgogICAgICAgIHsiZnJhYzEyIiwgIjE4OSJ9LCAvLyB2dWxnYXIgZnJhY3Rpb24gb25lIGhhbGYgPSBmcmFjdGlvbiBvbmUgaGFsZgogICAgICAgIHsiZnJhYzM0IiwgIjE5MCJ9LCAvLyB2dWxnYXIgZnJhY3Rpb24gdGhyZWUgcXVhcnRlcnMgPSBmcmFjdGlvbiB0aHJlZSBxdWFydGVycwogICAgICAgIHsiaXF1ZXN0IiwgIjE5MSJ9LCAvLyBpbnZlcnRlZCBxdWVzdGlvbiBtYXJrID0gdHVybmVkIHF1ZXN0aW9uIG1hcmsKICAgICAgICB7IkFncmF2ZSIsICIxOTIifSwgLy8gwCAtIHVwcGVyY2FzZSBBLCBncmF2ZSBhY2NlbnQKICAgICAgICB7IkFhY3V0ZSIsICIxOTMifSwgLy8gwSAtIHVwcGVyY2FzZSBBLCBhY3V0ZSBhY2NlbnQKICAgICAgICB7IkFjaXJjIiwgIjE5NCJ9LCAvLyDCIC0gdXBwZXJjYXNlIEEsIGNpcmN1bWZsZXggYWNjZW50CiAgICAgICAgeyJBdGlsZGUiLCAiMTk1In0sIC8vIMMgLSB1cHBlcmNhc2UgQSwgdGlsZGUKICAgICAgICB7IkF1bWwiLCAiMTk2In0sIC8vIMQgLSB1cHBlcmNhc2UgQSwgdW1sYXV0CiAgICAgICAgeyJBcmluZyIsICIxOTcifSwgLy8gxSAtIHVwcGVyY2FzZSBBLCByaW5nCiAgICAgICAgeyJBRWxpZyIsICIxOTgifSwgLy8gxiAtIHVwcGVyY2FzZSBBRQogICAgICAgIHsiQ2NlZGlsIiwgIjE5OSJ9LCAvLyDHIC0gdXBwZXJjYXNlIEMsIGNlZGlsbGEKICAgICAgICB7IkVncmF2ZSIsICIyMDAifSwgLy8gyCAtIHVwcGVyY2FzZSBFLCBncmF2ZSBhY2NlbnQKICAgICAgICB7IkVhY3V0ZSIsICIyMDEifSwgLy8gySAtIHVwcGVyY2FzZSBFLCBhY3V0ZSBhY2NlbnQKICAgICAgICB7IkVjaXJjIiwgIjIwMiJ9LCAvLyDKIC0gdXBwZXJjYXNlIEUsIGNpcmN1bWZsZXggYWNjZW50CiAgICAgICAgeyJFdW1sIiwgIjIwMyJ9LCAvLyDLIC0gdXBwZXJjYXNlIEUsIHVtbGF1dAogICAgICAgIHsiSWdyYXZlIiwgIjIwNCJ9LCAvLyDMIC0gdXBwZXJjYXNlIEksIGdyYXZlIGFjY2VudAogICAgICAgIHsiSWFjdXRlIiwgIjIwNSJ9LCAvLyDNIC0gdXBwZXJjYXNlIEksIGFjdXRlIGFjY2VudAogICAgICAgIHsiSWNpcmMiLCAiMjA2In0sIC8vIM4gLSB1cHBlcmNhc2UgSSwgY2lyY3VtZmxleCBhY2NlbnQKICAgICAgICB7Ikl1bWwiLCAiMjA3In0sIC8vIM8gLSB1cHBlcmNhc2UgSSwgdW1sYXV0CiAgICAgICAgeyJFVEgiLCAiMjA4In0sIC8vINAgLSB1cHBlcmNhc2UgRXRoLCBJY2VsYW5kaWMKICAgICAgICB7Ik50aWxkZSIsICIyMDkifSwgLy8g0SAtIHVwcGVyY2FzZSBOLCB0aWxkZQogICAgICAgIHsiT2dyYXZlIiwgIjIxMCJ9LCAvLyDSIC0gdXBwZXJjYXNlIE8sIGdyYXZlIGFjY2VudAogICAgICAgIHsiT2FjdXRlIiwgIjIxMSJ9LCAvLyDTIC0gdXBwZXJjYXNlIE8sIGFjdXRlIGFjY2VudAogICAgICAgIHsiT2NpcmMiLCAiMjEyIn0sIC8vINQgLSB1cHBlcmNhc2UgTywgY2lyY3VtZmxleCBhY2NlbnQKICAgICAgICB7Ik90aWxkZSIsICIyMTMifSwgLy8g1SAtIHVwcGVyY2FzZSBPLCB0aWxkZQogICAgICAgIHsiT3VtbCIsICIyMTQifSwgLy8g1iAtIHVwcGVyY2FzZSBPLCB1bWxhdXQKICAgICAgICB7InRpbWVzIiwgIjIxNSJ9LCAvLyBtdWx0aXBsaWNhdGlvbiBzaWduCiAgICAgICAgeyJPc2xhc2giLCAiMjE2In0sIC8vINggLSB1cHBlcmNhc2UgTywgc2xhc2gKICAgICAgICB7IlVncmF2ZSIsICIyMTcifSwgLy8g2SAtIHVwcGVyY2FzZSBVLCBncmF2ZSBhY2NlbnQKICAgICAgICB7IlVhY3V0ZSIsICIyMTgifSwgLy8g2iAtIHVwcGVyY2FzZSBVLCBhY3V0ZSBhY2NlbnQKICAgICAgICB7IlVjaXJjIiwgIjIxOSJ9LCAvLyDbIC0gdXBwZXJjYXNlIFUsIGNpcmN1bWZsZXggYWNjZW50CiAgICAgICAgeyJVdW1sIiwgIjIyMCJ9LCAvLyDcIC0gdXBwZXJjYXNlIFUsIHVtbGF1dAogICAgICAgIHsiWWFjdXRlIiwgIjIyMSJ9LCAvLyDdIC0gdXBwZXJjYXNlIFksIGFjdXRlIGFjY2VudAogICAgICAgIHsiVEhPUk4iLCAiMjIyIn0sIC8vIN4gLSB1cHBlcmNhc2UgVEhPUk4sIEljZWxhbmRpYwogICAgICAgIHsic3psaWciLCAiMjIzIn0sIC8vIN8gLSBsb3dlcmNhc2Ugc2hhcnBzLCBHZXJtYW4KICAgICAgICB7ImFncmF2ZSIsICIyMjQifSwgLy8g4CAtIGxvd2VyY2FzZSBhLCBncmF2ZSBhY2NlbnQKICAgICAgICB7ImFhY3V0ZSIsICIyMjUifSwgLy8g4SAtIGxvd2VyY2FzZSBhLCBhY3V0ZSBhY2NlbnQKICAgICAgICB7ImFjaXJjIiwgIjIyNiJ9LCAvLyDiIC0gbG93ZXJjYXNlIGEsIGNpcmN1bWZsZXggYWNjZW50CiAgICAgICAgeyJhdGlsZGUiLCAiMjI3In0sIC8vIOMgLSBsb3dlcmNhc2UgYSwgdGlsZGUKICAgICAgICB7ImF1bWwiLCAiMjI4In0sIC8vIOQgLSBsb3dlcmNhc2UgYSwgdW1sYXV0CiAgICAgICAgeyJhcmluZyIsICIyMjkifSwgLy8g5SAtIGxvd2VyY2FzZSBhLCByaW5nCiAgICAgICAgeyJhZWxpZyIsICIyMzAifSwgLy8g5iAtIGxvd2VyY2FzZSBhZQogICAgICAgIHsiY2NlZGlsIiwgIjIzMSJ9LCAvLyDnIC0gbG93ZXJjYXNlIGMsIGNlZGlsbGEKICAgICAgICB7ImVncmF2ZSIsICIyMzIifSwgLy8g6CAtIGxvd2VyY2FzZSBlLCBncmF2ZSBhY2NlbnQKICAgICAgICB7ImVhY3V0ZSIsICIyMzMifSwgLy8g6SAtIGxvd2VyY2FzZSBlLCBhY3V0ZSBhY2NlbnQKICAgICAgICB7ImVjaXJjIiwgIjIzNCJ9LCAvLyDqIC0gbG93ZXJjYXNlIGUsIGNpcmN1bWZsZXggYWNjZW50CiAgICAgICAgeyJldW1sIiwgIjIzNSJ9LCAvLyDrIC0gbG93ZXJjYXNlIGUsIHVtbGF1dAogICAgICAgIHsiaWdyYXZlIiwgIjIzNiJ9LCAvLyDsIC0gbG93ZXJjYXNlIGksIGdyYXZlIGFjY2VudAogICAgICAgIHsiaWFjdXRlIiwgIjIzNyJ9LCAvLyDtIC0gbG93ZXJjYXNlIGksIGFjdXRlIGFjY2VudAogICAgICAgIHsiaWNpcmMiLCAiMjM4In0sIC8vIO4gLSBsb3dlcmNhc2UgaSwgY2lyY3VtZmxleCBhY2NlbnQKICAgICAgICB7Iml1bWwiLCAiMjM5In0sIC8vIO8gLSBsb3dlcmNhc2UgaSwgdW1sYXV0CiAgICAgICAgeyJldGgiLCAiMjQwIn0sIC8vIPAgLSBsb3dlcmNhc2UgZXRoLCBJY2VsYW5kaWMKICAgICAgICB7Im50aWxkZSIsICIyNDEifSwgLy8g8SAtIGxvd2VyY2FzZSBuLCB0aWxkZQogICAgICAgIHsib2dyYXZlIiwgIjI0MiJ9LCAvLyDyIC0gbG93ZXJjYXNlIG8sIGdyYXZlIGFjY2VudAogICAgICAgIHsib2FjdXRlIiwgIjI0MyJ9LCAvLyDzIC0gbG93ZXJjYXNlIG8sIGFjdXRlIGFjY2VudAogICAgICAgIHsib2NpcmMiLCAiMjQ0In0sIC8vIPQgLSBsb3dlcmNhc2UgbywgY2lyY3VtZmxleCBhY2NlbnQKICAgICAgICB7Im90aWxkZSIsICIyNDUifSwgLy8g9SAtIGxvd2VyY2FzZSBvLCB0aWxkZQogICAgICAgIHsib3VtbCIsICIyNDYifSwgLy8g9iAtIGxvd2VyY2FzZSBvLCB1bWxhdXQKICAgICAgICB7ImRpdmlkZSIsICIyNDcifSwgLy8gZGl2aXNpb24gc2lnbgogICAgICAgIHsib3NsYXNoIiwgIjI0OCJ9LCAvLyD4IC0gbG93ZXJjYXNlIG8sIHNsYXNoCiAgICAgICAgeyJ1Z3JhdmUiLCAiMjQ5In0sIC8vIPkgLSBsb3dlcmNhc2UgdSwgZ3JhdmUgYWNjZW50CiAgICAgICAgeyJ1YWN1dGUiLCAiMjUwIn0sIC8vIPogLSBsb3dlcmNhc2UgdSwgYWN1dGUgYWNjZW50CiAgICAgICAgeyJ1Y2lyYyIsICIyNTEifSwgLy8g+yAtIGxvd2VyY2FzZSB1LCBjaXJjdW1mbGV4IGFjY2VudAogICAgICAgIHsidXVtbCIsICIyNTIifSwgLy8g/CAtIGxvd2VyY2FzZSB1LCB1bWxhdXQKICAgICAgICB7InlhY3V0ZSIsICIyNTMifSwgLy8g/SAtIGxvd2VyY2FzZSB5LCBhY3V0ZSBhY2NlbnQKICAgICAgICB7InRob3JuIiwgIjI1NCJ9LCAvLyD+IC0gbG93ZXJjYXNlIHRob3JuLCBJY2VsYW5kaWMKICAgICAgICB7Inl1bWwiLCAiMjU1In0sIC8vIP8gLSBsb3dlcmNhc2UgeSwgdW1sYXV0CiAgICB9OwoKICAgIC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy1odG1sNDAvc2dtbC9lbnRpdGllcy5odG1sCiAgICAvLyBwYWNrYWdlIHNjb3BlZCBmb3IgdGVzdGluZwogICAgc3RhdGljIGZpbmFsIFN0cmluZ1tdW10gSFRNTDQwX0FSUkFZID0gewogICAgLy8gPCEtLSBMYXRpbiBFeHRlbmRlZC1CIC0tPgogICAgICAgIHsiZm5vZiIsICI0MDIifSwgLy8gbGF0aW4gc21hbGwgZiB3aXRoIGhvb2sgPSBmdW5jdGlvbj0gZmxvcmluLCBVKzAxOTIgSVNPdGVjaCAtLT4KICAgICAgICAvLyA8IS0tIEdyZWVrIC0tPgogICAgICAgIHsiQWxwaGEiLCAiOTEzIn0sIC8vIGdyZWVrIGNhcGl0YWwgbGV0dGVyIGFscGhhLCBVKzAzOTEgLS0+CiAgICAgICAgeyJCZXRhIiwgIjkxNCJ9LCAvLyBncmVlayBjYXBpdGFsIGxldHRlciBiZXRhLCBVKzAzOTIgLS0+CiAgICAgICAgeyJHYW1tYSIsICI5MTUifSwgLy8gZ3JlZWsgY2FwaXRhbCBsZXR0ZXIgZ2FtbWEsVSswMzkzIElTT2dyazMgLS0+CiAgICAgICAgeyJEZWx0YSIsICI5MTYifSwgLy8gZ3JlZWsgY2FwaXRhbCBsZXR0ZXIgZGVsdGEsVSswMzk0IElTT2dyazMgLS0+CiAgICAgICAgeyJFcHNpbG9uIiwgIjkxNyJ9LCAvLyBncmVlayBjYXBpdGFsIGxldHRlciBlcHNpbG9uLCBVKzAzOTUgLS0+CiAgICAgICAgeyJaZXRhIiwgIjkxOCJ9LCAvLyBncmVlayBjYXBpdGFsIGxldHRlciB6ZXRhLCBVKzAzOTYgLS0+CiAgICAgICAgeyJFdGEiLCAiOTE5In0sIC8vIGdyZWVrIGNhcGl0YWwgbGV0dGVyIGV0YSwgVSswMzk3IC0tPgogICAgICAgIHsiVGhldGEiLCAiOTIwIn0sIC8vIGdyZWVrIGNhcGl0YWwgbGV0dGVyIHRoZXRhLFUrMDM5OCBJU09ncmszIC0tPgogICAgICAgIHsiSW90YSIsICI5MjEifSwgLy8gZ3JlZWsgY2FwaXRhbCBsZXR0ZXIgaW90YSwgVSswMzk5IC0tPgogICAgICAgIHsiS2FwcGEiLCAiOTIyIn0sIC8vIGdyZWVrIGNhcGl0YWwgbGV0dGVyIGthcHBhLCBVKzAzOUEgLS0+CiAgICAgICAgeyJMYW1iZGEiLCAiOTIzIn0sIC8vIGdyZWVrIGNhcGl0YWwgbGV0dGVyIGxhbWJkYSxVKzAzOUIgSVNPZ3JrMyAtLT4KICAgICAgICB7Ik11IiwgIjkyNCJ9LCAvLyBncmVlayBjYXBpdGFsIGxldHRlciBtdSwgVSswMzlDIC0tPgogICAgICAgIHsiTnUiLCAiOTI1In0sIC8vIGdyZWVrIGNhcGl0YWwgbGV0dGVyIG51LCBVKzAzOUQgLS0+CiAgICAgICAgeyJYaSIsICI5MjYifSwgLy8gZ3JlZWsgY2FwaXRhbCBsZXR0ZXIgeGksIFUrMDM5RSBJU09ncmszIC0tPgogICAgICAgIHsiT21pY3JvbiIsICI5MjcifSwgLy8gZ3JlZWsgY2FwaXRhbCBsZXR0ZXIgb21pY3JvbiwgVSswMzlGIC0tPgogICAgICAgIHsiUGkiLCAiOTI4In0sIC8vIGdyZWVrIGNhcGl0YWwgbGV0dGVyIHBpLCBVKzAzQTAgSVNPZ3JrMyAtLT4KICAgICAgICB7IlJobyIsICI5MjkifSwgLy8gZ3JlZWsgY2FwaXRhbCBsZXR0ZXIgcmhvLCBVKzAzQTEgLS0+CiAgICAgICAgLy8gPCEtLSB0aGVyZSBpcyBubyBTaWdtYWYsIGFuZCBubyBVKzAzQTIgY2hhcmFjdGVyIGVpdGhlciAtLT4KICAgICAgICB7IlNpZ21hIiwgIjkzMSJ9LCAvLyBncmVlayBjYXBpdGFsIGxldHRlciBzaWdtYSxVKzAzQTMgSVNPZ3JrMyAtLT4KICAgICAgICB7IlRhdSIsICI5MzIifSwgLy8gZ3JlZWsgY2FwaXRhbCBsZXR0ZXIgdGF1LCBVKzAzQTQgLS0+CiAgICAgICAgeyJVcHNpbG9uIiwgIjkzMyJ9LCAvLyBncmVlayBjYXBpdGFsIGxldHRlciB1cHNpbG9uLFUrMDNBNSBJU09ncmszIC0tPgogICAgICAgIHsiUGhpIiwgIjkzNCJ9LCAvLyBncmVlayBjYXBpdGFsIGxldHRlciBwaGksVSswM0E2IElTT2dyazMgLS0+CiAgICAgICAgeyJDaGkiLCAiOTM1In0sIC8vIGdyZWVrIGNhcGl0YWwgbGV0dGVyIGNoaSwgVSswM0E3IC0tPgogICAgICAgIHsiUHNpIiwgIjkzNiJ9LCAvLyBncmVlayBjYXBpdGFsIGxldHRlciBwc2ksVSswM0E4IElTT2dyazMgLS0+CiAgICAgICAgeyJPbWVnYSIsICI5MzcifSwgLy8gZ3JlZWsgY2FwaXRhbCBsZXR0ZXIgb21lZ2EsVSswM0E5IElTT2dyazMgLS0+CiAgICAgICAgeyJhbHBoYSIsICI5NDUifSwgLy8gZ3JlZWsgc21hbGwgbGV0dGVyIGFscGhhLFUrMDNCMSBJU09ncmszIC0tPgogICAgICAgIHsiYmV0YSIsICI5NDYifSwgLy8gZ3JlZWsgc21hbGwgbGV0dGVyIGJldGEsIFUrMDNCMiBJU09ncmszIC0tPgogICAgICAgIHsiZ2FtbWEiLCAiOTQ3In0sIC8vIGdyZWVrIHNtYWxsIGxldHRlciBnYW1tYSxVKzAzQjMgSVNPZ3JrMyAtLT4KICAgICAgICB7ImRlbHRhIiwgIjk0OCJ9LCAvLyBncmVlayBzbWFsbCBsZXR0ZXIgZGVsdGEsVSswM0I0IElTT2dyazMgLS0+CiAgICAgICAgeyJlcHNpbG9uIiwgIjk0OSJ9LCAvLyBncmVlayBzbWFsbCBsZXR0ZXIgZXBzaWxvbixVKzAzQjUgSVNPZ3JrMyAtLT4KICAgICAgICB7InpldGEiLCAiOTUwIn0sIC8vIGdyZWVrIHNtYWxsIGxldHRlciB6ZXRhLCBVKzAzQjYgSVNPZ3JrMyAtLT4KICAgICAgICB7ImV0YSIsICI5NTEifSwgLy8gZ3JlZWsgc21hbGwgbGV0dGVyIGV0YSwgVSswM0I3IElTT2dyazMgLS0+CiAgICAgICAgeyJ0aGV0YSIsICI5NTIifSwgLy8gZ3JlZWsgc21hbGwgbGV0dGVyIHRoZXRhLFUrMDNCOCBJU09ncmszIC0tPgogICAgICAgIHsiaW90YSIsICI5NTMifSwgLy8gZ3JlZWsgc21hbGwgbGV0dGVyIGlvdGEsIFUrMDNCOSBJU09ncmszIC0tPgogICAgICAgIHsia2FwcGEiLCAiOTU0In0sIC8vIGdyZWVrIHNtYWxsIGxldHRlciBrYXBwYSxVKzAzQkEgSVNPZ3JrMyAtLT4KICAgICAgICB7ImxhbWJkYSIsICI5NTUifSwgLy8gZ3JlZWsgc21hbGwgbGV0dGVyIGxhbWJkYSxVKzAzQkIgSVNPZ3JrMyAtLT4KICAgICAgICB7Im11IiwgIjk1NiJ9LCAvLyBncmVlayBzbWFsbCBsZXR0ZXIgbXUsIFUrMDNCQyBJU09ncmszIC0tPgogICAgICAgIHsibnUiLCAiOTU3In0sIC8vIGdyZWVrIHNtYWxsIGxldHRlciBudSwgVSswM0JEIElTT2dyazMgLS0+CiAgICAgICAgeyJ4aSIsICI5NTgifSwgLy8gZ3JlZWsgc21hbGwgbGV0dGVyIHhpLCBVKzAzQkUgSVNPZ3JrMyAtLT4KICAgICAgICB7Im9taWNyb24iLCAiOTU5In0sIC8vIGdyZWVrIHNtYWxsIGxldHRlciBvbWljcm9uLCBVKzAzQkYgTkVXIC0tPgogICAgICAgIHsicGkiLCAiOTYwIn0sIC8vIGdyZWVrIHNtYWxsIGxldHRlciBwaSwgVSswM0MwIElTT2dyazMgLS0+CiAgICAgICAgeyJyaG8iLCAiOTYxIn0sIC8vIGdyZWVrIHNtYWxsIGxldHRlciByaG8sIFUrMDNDMSBJU09ncmszIC0tPgogICAgICAgIHsic2lnbWFmIiwgIjk2MiJ9LCAvLyBncmVlayBzbWFsbCBsZXR0ZXIgZmluYWwgc2lnbWEsVSswM0MyIElTT2dyazMgLS0+CiAgICAgICAgeyJzaWdtYSIsICI5NjMifSwgLy8gZ3JlZWsgc21hbGwgbGV0dGVyIHNpZ21hLFUrMDNDMyBJU09ncmszIC0tPgogICAgICAgIHsidGF1IiwgIjk2NCJ9LCAvLyBncmVlayBzbWFsbCBsZXR0ZXIgdGF1LCBVKzAzQzQgSVNPZ3JrMyAtLT4KICAgICAgICB7InVwc2lsb24iLCAiOTY1In0sIC8vIGdyZWVrIHNtYWxsIGxldHRlciB1cHNpbG9uLFUrMDNDNSBJU09ncmszIC0tPgogICAgICAgIHsicGhpIiwgIjk2NiJ9LCAvLyBncmVlayBzbWFsbCBsZXR0ZXIgcGhpLCBVKzAzQzYgSVNPZ3JrMyAtLT4KICAgICAgICB7ImNoaSIsICI5NjcifSwgLy8gZ3JlZWsgc21hbGwgbGV0dGVyIGNoaSwgVSswM0M3IElTT2dyazMgLS0+CiAgICAgICAgeyJwc2kiLCAiOTY4In0sIC8vIGdyZWVrIHNtYWxsIGxldHRlciBwc2ksIFUrMDNDOCBJU09ncmszIC0tPgogICAgICAgIHsib21lZ2EiLCAiOTY5In0sIC8vIGdyZWVrIHNtYWxsIGxldHRlciBvbWVnYSxVKzAzQzkgSVNPZ3JrMyAtLT4KICAgICAgICB7InRoZXRhc3ltIiwgIjk3NyJ9LCAvLyBncmVlayBzbWFsbCBsZXR0ZXIgdGhldGEgc3ltYm9sLFUrMDNEMSBORVcgLS0+CiAgICAgICAgeyJ1cHNpaCIsICI5NzgifSwgLy8gZ3JlZWsgdXBzaWxvbiB3aXRoIGhvb2sgc3ltYm9sLFUrMDNEMiBORVcgLS0+CiAgICAgICAgeyJwaXYiLCAiOTgyIn0sIC8vIGdyZWVrIHBpIHN5bWJvbCwgVSswM0Q2IElTT2dyazMgLS0+CiAgICAgICAgLy8gPCEtLSBHZW5lcmFsIFB1bmN0dWF0aW9uIC0tPgogICAgICAgIHsiYnVsbCIsICI4MjI2In0sIC8vIGJ1bGxldCA9IGJsYWNrIHNtYWxsIGNpcmNsZSxVKzIwMjIgSVNPcHViIC0tPgogICAgICAgIC8vIDwhLS0gYnVsbGV0IGlzIE5PVCB0aGUgc2FtZSBhcyBidWxsZXQgb3BlcmF0b3IsIFUrMjIxOSAtLT4KICAgICAgICB7ImhlbGxpcCIsICI4MjMwIn0sIC8vIGhvcml6b250YWwgZWxsaXBzaXMgPSB0aHJlZSBkb3QgbGVhZGVyLFUrMjAyNiBJU09wdWIgLS0+CiAgICAgICAgeyJwcmltZSIsICI4MjQyIn0sIC8vIHByaW1lID0gbWludXRlcyA9IGZlZXQsIFUrMjAzMiBJU090ZWNoIC0tPgogICAgICAgIHsiUHJpbWUiLCAiODI0MyJ9LCAvLyBkb3VibGUgcHJpbWUgPSBzZWNvbmRzID0gaW5jaGVzLFUrMjAzMyBJU090ZWNoIC0tPgogICAgICAgIHsib2xpbmUiLCAiODI1NCJ9LCAvLyBvdmVybGluZSA9IHNwYWNpbmcgb3ZlcnNjb3JlLFUrMjAzRSBORVcgLS0+CiAgICAgICAgeyJmcmFzbCIsICI4MjYwIn0sIC8vIGZyYWN0aW9uIHNsYXNoLCBVKzIwNDQgTkVXIC0tPgogICAgICAgIC8vIDwhLS0gTGV0dGVybGlrZSBTeW1ib2xzIC0tPgogICAgICAgIHsid2VpZXJwIiwgIjg0NzIifSwgLy8gc2NyaXB0IGNhcGl0YWwgUCA9IHBvd2VyIHNldD0gV2VpZXJzdHJhc3MgcCwgVSsyMTE4IElTT2Ftc28gLS0+CiAgICAgICAgeyJpbWFnZSIsICI4NDY1In0sIC8vIGJsYWNrbGV0dGVyIGNhcGl0YWwgSSA9IGltYWdpbmFyeSBwYXJ0LFUrMjExMSBJU09hbXNvIC0tPgogICAgICAgIHsicmVhbCIsICI4NDc2In0sIC8vIGJsYWNrbGV0dGVyIGNhcGl0YWwgUiA9IHJlYWwgcGFydCBzeW1ib2wsVSsyMTFDIElTT2Ftc28gLS0+CiAgICAgICAgeyJ0cmFkZSIsICI4NDgyIn0sIC8vIHRyYWRlIG1hcmsgc2lnbiwgVSsyMTIyIElTT251bSAtLT4KICAgICAgICB7ImFsZWZzeW0iLCAiODUwMSJ9LCAvLyBhbGVmIHN5bWJvbCA9IGZpcnN0IHRyYW5zZmluaXRlIGNhcmRpbmFsLFUrMjEzNSBORVcgLS0+CiAgICAgICAgLy8gPCEtLSBhbGVmIHN5bWJvbCBpcyBOT1QgdGhlIHNhbWUgYXMgaGVicmV3IGxldHRlciBhbGVmLFUrMDVEMCBhbHRob3VnaCB0aGUKICAgICAgICAvLyBzYW1lIGdseXBoIGNvdWxkIGJlIHVzZWQgdG8gZGVwaWN0IGJvdGggY2hhcmFjdGVycyAtLT4KICAgICAgICAvLyA8IS0tIEFycm93cyAtLT4KICAgICAgICB7ImxhcnIiLCAiODU5MiJ9LCAvLyBsZWZ0d2FyZHMgYXJyb3csIFUrMjE5MCBJU09udW0gLS0+CiAgICAgICAgeyJ1YXJyIiwgIjg1OTMifSwgLy8gdXB3YXJkcyBhcnJvdywgVSsyMTkxIElTT251bS0tPgogICAgICAgIHsicmFyciIsICI4NTk0In0sIC8vIHJpZ2h0d2FyZHMgYXJyb3csIFUrMjE5MiBJU09udW0gLS0+CiAgICAgICAgeyJkYXJyIiwgIjg1OTUifSwgLy8gZG93bndhcmRzIGFycm93LCBVKzIxOTMgSVNPbnVtIC0tPgogICAgICAgIHsiaGFyciIsICI4NTk2In0sIC8vIGxlZnQgcmlnaHQgYXJyb3csIFUrMjE5NCBJU09hbXNhIC0tPgogICAgICAgIHsiY3JhcnIiLCAiODYyOSJ9LCAvLyBkb3dud2FyZHMgYXJyb3cgd2l0aCBjb3JuZXIgbGVmdHdhcmRzPSBjYXJyaWFnZSByZXR1cm4sIFUrMjFCNSBORVcgLS0+CiAgICAgICAgeyJsQXJyIiwgIjg2NTYifSwgLy8gbGVmdHdhcmRzIGRvdWJsZSBhcnJvdywgVSsyMUQwIElTT3RlY2ggLS0+CiAgICAgICAgLy8gPCEtLSBJU08gMTA2NDYgZG9lcyBub3Qgc2F5IHRoYXQgbEFyciBpcyB0aGUgc2FtZSBhcyB0aGUgJ2lzIGltcGxpZWQgYnknCiAgICAgICAgLy8gYXJyb3cgYnV0IGFsc28gZG9lcyBub3QgaGF2ZSBhbnkgb3RoZXIgY2hhcmFjdGVyIGZvciB0aGF0IGZ1bmN0aW9uLgogICAgICAgIC8vIFNvID8gbEFyciBjYW5iZSB1c2VkIGZvciAnaXMgaW1wbGllZCBieScgYXMgSVNPdGVjaCBzdWdnZXN0cyAtLT4KICAgICAgICB7InVBcnIiLCAiODY1NyJ9LCAvLyB1cHdhcmRzIGRvdWJsZSBhcnJvdywgVSsyMUQxIElTT2Ftc2EgLS0+CiAgICAgICAgeyJyQXJyIiwgIjg2NTgifSwgLy8gcmlnaHR3YXJkcyBkb3VibGUgYXJyb3csVSsyMUQyIElTT3RlY2ggLS0+CiAgICAgICAgLy8gPCEtLSBJU08gMTA2NDYgZG9lcyBub3Qgc2F5IHRoaXMgaXMgdGhlICdpbXBsaWVzJyBjaGFyYWN0ZXIgYnV0IGRvZXMgbm90CiAgICAgICAgLy8gaGF2ZSBhbm90aGVyIGNoYXJhY3RlciB3aXRoIHRoaXMgZnVuY3Rpb24gc28gP3JBcnIgY2FuIGJlIHVzZWQgZm9yCiAgICAgICAgLy8gJ2ltcGxpZXMnIGFzIElTT3RlY2ggc3VnZ2VzdHMgLS0+CiAgICAgICAgeyJkQXJyIiwgIjg2NTkifSwgLy8gZG93bndhcmRzIGRvdWJsZSBhcnJvdywgVSsyMUQzIElTT2Ftc2EgLS0+CiAgICAgICAgeyJoQXJyIiwgIjg2NjAifSwgLy8gbGVmdCByaWdodCBkb3VibGUgYXJyb3csVSsyMUQ0IElTT2Ftc2EgLS0+CiAgICAgICAgLy8gPCEtLSBNYXRoZW1hdGljYWwgT3BlcmF0b3JzIC0tPgogICAgICAgIHsiZm9yYWxsIiwgIjg3MDQifSwgLy8gZm9yIGFsbCwgVSsyMjAwIElTT3RlY2ggLS0+CiAgICAgICAgeyJwYXJ0IiwgIjg3MDYifSwgLy8gcGFydGlhbCBkaWZmZXJlbnRpYWwsIFUrMjIwMiBJU090ZWNoIC0tPgogICAgICAgIHsiZXhpc3QiLCAiODcwNyJ9LCAvLyB0aGVyZSBleGlzdHMsIFUrMjIwMyBJU090ZWNoIC0tPgogICAgICAgIHsiZW1wdHkiLCAiODcwOSJ9LCAvLyBlbXB0eSBzZXQgPSBudWxsIHNldCA9IGRpYW1ldGVyLFUrMjIwNSBJU09hbXNvIC0tPgogICAgICAgIHsibmFibGEiLCAiODcxMSJ9LCAvLyBuYWJsYSA9IGJhY2t3YXJkIGRpZmZlcmVuY2UsVSsyMjA3IElTT3RlY2ggLS0+CiAgICAgICAgeyJpc2luIiwgIjg3MTIifSwgLy8gZWxlbWVudCBvZiwgVSsyMjA4IElTT3RlY2ggLS0+CiAgICAgICAgeyJub3RpbiIsICI4NzEzIn0sIC8vIG5vdCBhbiBlbGVtZW50IG9mLCBVKzIyMDkgSVNPdGVjaCAtLT4KICAgICAgICB7Im5pIiwgIjg3MTUifSwgLy8gY29udGFpbnMgYXMgbWVtYmVyLCBVKzIyMEIgSVNPdGVjaCAtLT4KICAgICAgICAvLyA8IS0tIHNob3VsZCB0aGVyZSBiZSBhIG1vcmUgbWVtb3JhYmxlIG5hbWUgdGhhbiAnbmknPyAtLT4KICAgICAgICB7InByb2QiLCAiODcxOSJ9LCAvLyBuLWFyeSBwcm9kdWN0ID0gcHJvZHVjdCBzaWduLFUrMjIwRiBJU09hbXNiIC0tPgogICAgICAgIC8vIDwhLS0gcHJvZCBpcyBOT1QgdGhlIHNhbWUgY2hhcmFjdGVyIGFzIFUrMDNBMCAnZ3JlZWsgY2FwaXRhbCBsZXR0ZXIgcGknCiAgICAgICAgLy8gdGhvdWdoIHRoZSBzYW1lIGdseXBoIG1pZ2h0IGJlIHVzZWQgZm9yIGJvdGggLS0+CiAgICAgICAgeyJzdW0iLCAiODcyMSJ9LCAvLyBuLWFyeSBzdW1tYXRpb24sIFUrMjIxMSBJU09hbXNiIC0tPgogICAgICAgIC8vIDwhLS0gc3VtIGlzIE5PVCB0aGUgc2FtZSBjaGFyYWN0ZXIgYXMgVSswM0EzICdncmVlayBjYXBpdGFsIGxldHRlciBzaWdtYScKICAgICAgICAvLyB0aG91Z2ggdGhlIHNhbWUgZ2x5cGggbWlnaHQgYmUgdXNlZCBmb3IgYm90aCAtLT4KICAgICAgICB7Im1pbnVzIiwgIjg3MjIifSwgLy8gbWludXMgc2lnbiwgVSsyMjEyIElTT3RlY2ggLS0+CiAgICAgICAgeyJsb3dhc3QiLCAiODcyNyJ9LCAvLyBhc3RlcmlzayBvcGVyYXRvciwgVSsyMjE3IElTT3RlY2ggLS0+CiAgICAgICAgeyJyYWRpYyIsICI4NzMwIn0sIC8vIHNxdWFyZSByb290ID0gcmFkaWNhbCBzaWduLFUrMjIxQSBJU090ZWNoIC0tPgogICAgICAgIHsicHJvcCIsICI4NzMzIn0sIC8vIHByb3BvcnRpb25hbCB0bywgVSsyMjFEIElTT3RlY2ggLS0+CiAgICAgICAgeyJpbmZpbiIsICI4NzM0In0sIC8vIGluZmluaXR5LCBVKzIyMUUgSVNPdGVjaCAtLT4KICAgICAgICB7ImFuZyIsICI4NzM2In0sIC8vIGFuZ2xlLCBVKzIyMjAgSVNPYW1zbyAtLT4KICAgICAgICB7ImFuZCIsICI4NzQzIn0sIC8vIGxvZ2ljYWwgYW5kID0gd2VkZ2UsIFUrMjIyNyBJU090ZWNoIC0tPgogICAgICAgIHsib3IiLCAiODc0NCJ9LCAvLyBsb2dpY2FsIG9yID0gdmVlLCBVKzIyMjggSVNPdGVjaCAtLT4KICAgICAgICB7ImNhcCIsICI4NzQ1In0sIC8vIGludGVyc2VjdGlvbiA9IGNhcCwgVSsyMjI5IElTT3RlY2ggLS0+CiAgICAgICAgeyJjdXAiLCAiODc0NiJ9LCAvLyB1bmlvbiA9IGN1cCwgVSsyMjJBIElTT3RlY2ggLS0+CiAgICAgICAgeyJpbnQiLCAiODc0NyJ9LCAvLyBpbnRlZ3JhbCwgVSsyMjJCIElTT3RlY2ggLS0+CiAgICAgICAgeyJ0aGVyZTQiLCAiODc1NiJ9LCAvLyB0aGVyZWZvcmUsIFUrMjIzNCBJU090ZWNoIC0tPgogICAgICAgIHsic2ltIiwgIjg3NjQifSwgLy8gdGlsZGUgb3BlcmF0b3IgPSB2YXJpZXMgd2l0aCA9IHNpbWlsYXIgdG8sVSsyMjNDIElTT3RlY2ggLS0+CiAgICAgICAgLy8gPCEtLSB0aWxkZSBvcGVyYXRvciBpcyBOT1QgdGhlIHNhbWUgY2hhcmFjdGVyIGFzIHRoZSB0aWxkZSwgVSswMDdFLGFsdGhvdWdoCiAgICAgICAgLy8gdGhlIHNhbWUgZ2x5cGggbWlnaHQgYmUgdXNlZCB0byByZXByZXNlbnQgYm90aCAtLT4KICAgICAgICB7ImNvbmciLCAiODc3MyJ9LCAvLyBhcHByb3hpbWF0ZWx5IGVxdWFsIHRvLCBVKzIyNDUgSVNPdGVjaCAtLT4KICAgICAgICB7ImFzeW1wIiwgIjg3NzYifSwgLy8gYWxtb3N0IGVxdWFsIHRvID0gYXN5bXB0b3RpYyB0byxVKzIyNDggSVNPYW1zciAtLT4KICAgICAgICB7Im5lIiwgIjg4MDAifSwgLy8gbm90IGVxdWFsIHRvLCBVKzIyNjAgSVNPdGVjaCAtLT4KICAgICAgICB7ImVxdWl2IiwgIjg4MDEifSwgLy8gaWRlbnRpY2FsIHRvLCBVKzIyNjEgSVNPdGVjaCAtLT4KICAgICAgICB7ImxlIiwgIjg4MDQifSwgLy8gbGVzcy10aGFuIG9yIGVxdWFsIHRvLCBVKzIyNjQgSVNPdGVjaCAtLT4KICAgICAgICB7ImdlIiwgIjg4MDUifSwgLy8gZ3JlYXRlci10aGFuIG9yIGVxdWFsIHRvLFUrMjI2NSBJU090ZWNoIC0tPgogICAgICAgIHsic3ViIiwgIjg4MzQifSwgLy8gc3Vic2V0IG9mLCBVKzIyODIgSVNPdGVjaCAtLT4KICAgICAgICB7InN1cCIsICI4ODM1In0sIC8vIHN1cGVyc2V0IG9mLCBVKzIyODMgSVNPdGVjaCAtLT4KICAgICAgICAvLyA8IS0tIG5vdGUgdGhhdCBuc3VwLCAnbm90IGEgc3VwZXJzZXQgb2YsIFUrMjI4MycgaXMgbm90IGNvdmVyZWQgYnkgdGhlCiAgICAgICAgLy8gU3ltYm9sIGZvbnQgZW5jb2RpbmcgYW5kIGlzIG5vdCBpbmNsdWRlZC4gU2hvdWxkIGl0IGJlLCBmb3Igc3ltbWV0cnk/CiAgICAgICAgLy8gSXQgaXMgaW4gSVNPYW1zbiAtLT4gPCFFTlRJVFkgbnN1YiIsICI4ODM2In0sCiAgICAgICAgLy8gbm90IGEgc3Vic2V0IG9mLCBVKzIyODQgSVNPYW1zbiAtLT4KICAgICAgICB7InN1YmUiLCAiODgzOCJ9LCAvLyBzdWJzZXQgb2Ygb3IgZXF1YWwgdG8sIFUrMjI4NiBJU090ZWNoIC0tPgogICAgICAgIHsic3VwZSIsICI4ODM5In0sIC8vIHN1cGVyc2V0IG9mIG9yIGVxdWFsIHRvLFUrMjI4NyBJU090ZWNoIC0tPgogICAgICAgIHsib3BsdXMiLCAiODg1MyJ9LCAvLyBjaXJjbGVkIHBsdXMgPSBkaXJlY3Qgc3VtLFUrMjI5NSBJU09hbXNiIC0tPgogICAgICAgIHsib3RpbWVzIiwgIjg4NTUifSwgLy8gY2lyY2xlZCB0aW1lcyA9IHZlY3RvciBwcm9kdWN0LFUrMjI5NyBJU09hbXNiIC0tPgogICAgICAgIHsicGVycCIsICI4ODY5In0sIC8vIHVwIHRhY2sgPSBvcnRob2dvbmFsIHRvID0gcGVycGVuZGljdWxhcixVKzIyQTUgSVNPdGVjaCAtLT4KICAgICAgICB7InNkb3QiLCAiODkwMSJ9LCAvLyBkb3Qgb3BlcmF0b3IsIFUrMjJDNSBJU09hbXNiIC0tPgogICAgICAgIC8vIDwhLS0gZG90IG9wZXJhdG9yIGlzIE5PVCB0aGUgc2FtZSBjaGFyYWN0ZXIgYXMgVSswMEI3IG1pZGRsZSBkb3QgLS0+CiAgICAgICAgLy8gPCEtLSBNaXNjZWxsYW5lb3VzIFRlY2huaWNhbCAtLT4KICAgICAgICB7ImxjZWlsIiwgIjg5NjgifSwgLy8gbGVmdCBjZWlsaW5nID0gYXBsIHVwc3RpbGUsVSsyMzA4IElTT2Ftc2MgLS0+CiAgICAgICAgeyJyY2VpbCIsICI4OTY5In0sIC8vIHJpZ2h0IGNlaWxpbmcsIFUrMjMwOSBJU09hbXNjIC0tPgogICAgICAgIHsibGZsb29yIiwgIjg5NzAifSwgLy8gbGVmdCBmbG9vciA9IGFwbCBkb3duc3RpbGUsVSsyMzBBIElTT2Ftc2MgLS0+CiAgICAgICAgeyJyZmxvb3IiLCAiODk3MSJ9LCAvLyByaWdodCBmbG9vciwgVSsyMzBCIElTT2Ftc2MgLS0+CiAgICAgICAgeyJsYW5nIiwgIjkwMDEifSwgLy8gbGVmdC1wb2ludGluZyBhbmdsZSBicmFja2V0ID0gYnJhLFUrMjMyOSBJU090ZWNoIC0tPgogICAgICAgIC8vIDwhLS0gbGFuZyBpcyBOT1QgdGhlIHNhbWUgY2hhcmFjdGVyIGFzIFUrMDAzQyAnbGVzcyB0aGFuJyBvciBVKzIwMzkgJ3NpbmdsZSBsZWZ0LXBvaW50aW5nIGFuZ2xlIHF1b3RhdGlvbgogICAgICAgIC8vIG1hcmsnIC0tPgogICAgICAgIHsicmFuZyIsICI5MDAyIn0sIC8vIHJpZ2h0LXBvaW50aW5nIGFuZ2xlIGJyYWNrZXQgPSBrZXQsVSsyMzJBIElTT3RlY2ggLS0+CiAgICAgICAgLy8gPCEtLSByYW5nIGlzIE5PVCB0aGUgc2FtZSBjaGFyYWN0ZXIgYXMgVSswMDNFICdncmVhdGVyIHRoYW4nIG9yIFUrMjAzQQogICAgICAgIC8vICdzaW5nbGUgcmlnaHQtcG9pbnRpbmcgYW5nbGUgcXVvdGF0aW9uIG1hcmsnIC0tPgogICAgICAgIC8vIDwhLS0gR2VvbWV0cmljIFNoYXBlcyAtLT4KICAgICAgICB7ImxveiIsICI5Njc0In0sIC8vIGxvemVuZ2UsIFUrMjVDQSBJU09wdWIgLS0+CiAgICAgICAgLy8gPCEtLSBNaXNjZWxsYW5lb3VzIFN5bWJvbHMgLS0+CiAgICAgICAgeyJzcGFkZXMiLCAiOTgyNCJ9LCAvLyBibGFjayBzcGFkZSBzdWl0LCBVKzI2NjAgSVNPcHViIC0tPgogICAgICAgIC8vIDwhLS0gYmxhY2sgaGVyZSBzZWVtcyB0byBtZWFuIGZpbGxlZCBhcyBvcHBvc2VkIHRvIGhvbGxvdyAtLT4KICAgICAgICB7ImNsdWJzIiwgIjk4MjcifSwgLy8gYmxhY2sgY2x1YiBzdWl0ID0gc2hhbXJvY2ssVSsyNjYzIElTT3B1YiAtLT4KICAgICAgICB7ImhlYXJ0cyIsICI5ODI5In0sIC8vIGJsYWNrIGhlYXJ0IHN1aXQgPSB2YWxlbnRpbmUsVSsyNjY1IElTT3B1YiAtLT4KICAgICAgICB7ImRpYW1zIiwgIjk4MzAifSwgLy8gYmxhY2sgZGlhbW9uZCBzdWl0LCBVKzI2NjYgSVNPcHViIC0tPgoKICAgICAgICAvLyA8IS0tIExhdGluIEV4dGVuZGVkLUEgLS0+CiAgICAgICAgeyJPRWxpZyIsICIzMzgifSwgLy8gLS0gbGF0aW4gY2FwaXRhbCBsaWdhdHVyZSBPRSxVKzAxNTIgSVNPbGF0MiAtLT4KICAgICAgICB7Im9lbGlnIiwgIjMzOSJ9LCAvLyAtLSBsYXRpbiBzbWFsbCBsaWdhdHVyZSBvZSwgVSswMTUzIElTT2xhdDIgLS0+CiAgICAgICAgLy8gPCEtLSBsaWdhdHVyZSBpcyBhIG1pc25vbWVyLCB0aGlzIGlzIGEgc2VwYXJhdGUgY2hhcmFjdGVyIGluIHNvbWUgbGFuZ3VhZ2VzIC0tPgogICAgICAgIHsiU2Nhcm9uIiwgIjM1MiJ9LCAvLyAtLSBsYXRpbiBjYXBpdGFsIGxldHRlciBTIHdpdGggY2Fyb24sVSswMTYwIElTT2xhdDIgLS0+CiAgICAgICAgeyJzY2Fyb24iLCAiMzUzIn0sIC8vIC0tIGxhdGluIHNtYWxsIGxldHRlciBzIHdpdGggY2Fyb24sVSswMTYxIElTT2xhdDIgLS0+CiAgICAgICAgeyJZdW1sIiwgIjM3NiJ9LCAvLyAtLSBsYXRpbiBjYXBpdGFsIGxldHRlciBZIHdpdGggZGlhZXJlc2lzLFUrMDE3OCBJU09sYXQyIC0tPgogICAgICAgIC8vIDwhLS0gU3BhY2luZyBNb2RpZmllciBMZXR0ZXJzIC0tPgogICAgICAgIHsiY2lyYyIsICI3MTAifSwgLy8gLS0gbW9kaWZpZXIgbGV0dGVyIGNpcmN1bWZsZXggYWNjZW50LFUrMDJDNiBJU09wdWIgLS0+CiAgICAgICAgeyJ0aWxkZSIsICI3MzIifSwgLy8gc21hbGwgdGlsZGUsIFUrMDJEQyBJU09kaWEgLS0+CiAgICAgICAgLy8gPCEtLSBHZW5lcmFsIFB1bmN0dWF0aW9uIC0tPgogICAgICAgIHsiZW5zcCIsICI4MTk0In0sIC8vIGVuIHNwYWNlLCBVKzIwMDIgSVNPcHViIC0tPgogICAgICAgIHsiZW1zcCIsICI4MTk1In0sIC8vIGVtIHNwYWNlLCBVKzIwMDMgSVNPcHViIC0tPgogICAgICAgIHsidGhpbnNwIiwgIjgyMDEifSwgLy8gdGhpbiBzcGFjZSwgVSsyMDA5IElTT3B1YiAtLT4KICAgICAgICB7Inp3bmoiLCAiODIwNCJ9LCAvLyB6ZXJvIHdpZHRoIG5vbi1qb2luZXIsVSsyMDBDIE5FVyBSRkMgMjA3MCAtLT4KICAgICAgICB7Inp3aiIsICI4MjA1In0sIC8vIHplcm8gd2lkdGggam9pbmVyLCBVKzIwMEQgTkVXIFJGQyAyMDcwIC0tPgogICAgICAgIHsibHJtIiwgIjgyMDYifSwgLy8gbGVmdC10by1yaWdodCBtYXJrLCBVKzIwMEUgTkVXIFJGQyAyMDcwIC0tPgogICAgICAgIHsicmxtIiwgIjgyMDcifSwgLy8gcmlnaHQtdG8tbGVmdCBtYXJrLCBVKzIwMEYgTkVXIFJGQyAyMDcwIC0tPgogICAgICAgIHsibmRhc2giLCAiODIxMSJ9LCAvLyBlbiBkYXNoLCBVKzIwMTMgSVNPcHViIC0tPgogICAgICAgIHsibWRhc2giLCAiODIxMiJ9LCAvLyBlbSBkYXNoLCBVKzIwMTQgSVNPcHViIC0tPgogICAgICAgIHsibHNxdW8iLCAiODIxNiJ9LCAvLyBsZWZ0IHNpbmdsZSBxdW90YXRpb24gbWFyayxVKzIwMTggSVNPbnVtIC0tPgogICAgICAgIHsicnNxdW8iLCAiODIxNyJ9LCAvLyByaWdodCBzaW5nbGUgcXVvdGF0aW9uIG1hcmssVSsyMDE5IElTT251bSAtLT4KICAgICAgICB7InNicXVvIiwgIjgyMTgifSwgLy8gc2luZ2xlIGxvdy05IHF1b3RhdGlvbiBtYXJrLCBVKzIwMUEgTkVXIC0tPgogICAgICAgIHsibGRxdW8iLCAiODIyMCJ9LCAvLyBsZWZ0IGRvdWJsZSBxdW90YXRpb24gbWFyayxVKzIwMUMgSVNPbnVtIC0tPgogICAgICAgIHsicmRxdW8iLCAiODIyMSJ9LCAvLyByaWdodCBkb3VibGUgcXVvdGF0aW9uIG1hcmssVSsyMDFEIElTT251bSAtLT4KICAgICAgICB7ImJkcXVvIiwgIjgyMjIifSwgLy8gZG91YmxlIGxvdy05IHF1b3RhdGlvbiBtYXJrLCBVKzIwMUUgTkVXIC0tPgogICAgICAgIHsiZGFnZ2VyIiwgIjgyMjQifSwgLy8gZGFnZ2VyLCBVKzIwMjAgSVNPcHViIC0tPgogICAgICAgIHsiRGFnZ2VyIiwgIjgyMjUifSwgLy8gZG91YmxlIGRhZ2dlciwgVSsyMDIxIElTT3B1YiAtLT4KICAgICAgICB7InBlcm1pbCIsICI4MjQwIn0sIC8vIHBlciBtaWxsZSBzaWduLCBVKzIwMzAgSVNPdGVjaCAtLT4KICAgICAgICB7ImxzYXF1byIsICI4MjQ5In0sIC8vIHNpbmdsZSBsZWZ0LXBvaW50aW5nIGFuZ2xlIHF1b3RhdGlvbiBtYXJrLFUrMjAzOSBJU08gcHJvcG9zZWQgLS0+CiAgICAgICAgLy8gPCEtLSBsc2FxdW8gaXMgcHJvcG9zZWQgYnV0IG5vdCB5ZXQgSVNPIHN0YW5kYXJkaXplZCAtLT4KICAgICAgICB7InJzYXF1byIsICI4MjUwIn0sIC8vIHNpbmdsZSByaWdodC1wb2ludGluZyBhbmdsZSBxdW90YXRpb24gbWFyayxVKzIwM0EgSVNPIHByb3Bvc2VkIC0tPgogICAgICAgIC8vIDwhLS0gcnNhcXVvIGlzIHByb3Bvc2VkIGJ1dCBub3QgeWV0IElTTyBzdGFuZGFyZGl6ZWQgLS0+CiAgICAgICAgeyJldXJvIiwgIjgzNjQifSwgLy8gLS0gZXVybyBzaWduLCBVKzIwQUMgTkVXIC0tPgogICAgfTsKCiAgICAvKioKICAgICAqIDxwPgogICAgICogVGhlIHNldCBvZiBlbnRpdGllcyBzdXBwb3J0ZWQgYnkgc3RhbmRhcmQgWE1MLgogICAgICogPC9wPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEVudGl0aWVzIFhNTDsKCiAgICAvKioKICAgICAqIDxwPgogICAgICogVGhlIHNldCBvZiBlbnRpdGllcyBzdXBwb3J0ZWQgYnkgSFRNTCAzLjIuCiAgICAgKiA8L3A+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRW50aXRpZXMgSFRNTDMyOwoKICAgIC8qKgogICAgICogPHA+CiAgICAgKiBUaGUgc2V0IG9mIGVudGl0aWVzIHN1cHBvcnRlZCBieSBIVE1MIDQuMC4KICAgICAqIDwvcD4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBFbnRpdGllcyBIVE1MNDA7CgogICAgc3RhdGljIHsKICAgICAgICBFbnRpdGllcyB4bWwgPSBuZXcgRW50aXRpZXMoKTsKICAgICAgICB4bWwuYWRkRW50aXRpZXMoQkFTSUNfQVJSQVkpOwogICAgICAgIHhtbC5hZGRFbnRpdGllcyhBUE9TX0FSUkFZKTsKICAgICAgICBYTUwgPSB4bWw7CiAgICB9CgogICAgc3RhdGljIHsKICAgICAgICBFbnRpdGllcyBodG1sMzIgPSBuZXcgRW50aXRpZXMoKTsKICAgICAgICBodG1sMzIuYWRkRW50aXRpZXMoQkFTSUNfQVJSQVkpOwogICAgICAgIGh0bWwzMi5hZGRFbnRpdGllcyhJU084ODU5XzFfQVJSQVkpOwogICAgICAgIEhUTUwzMiA9IGh0bWwzMjsKICAgIH0KCiAgICBzdGF0aWMgewogICAgICAgIEVudGl0aWVzIGh0bWw0MCA9IG5ldyBFbnRpdGllcygpOwogICAgICAgIGZpbGxXaXRoSHRtbDQwRW50aXRpZXMoaHRtbDQwKTsKICAgICAgICBIVE1MNDAgPSBodG1sNDA7CiAgICB9CgogICAgLyoqCiAgICAgKiA8cD4KICAgICAqIEZpbGxzIHRoZSBzcGVjaWZpZWQgZW50aXRpZXMgaW5zdGFuY2Ugd2l0aCBIVE1MIDQwIGVudGl0aWVzLgogICAgICogPC9wPgogICAgICogCiAgICAgKiBAcGFyYW0gZW50aXRpZXMKICAgICAqICAgICAgICAgICAgdGhlIGluc3RhbmNlIHRvIGJlIGZpbGxlZC4KICAgICAqLwogICAgc3RhdGljIHZvaWQgZmlsbFdpdGhIdG1sNDBFbnRpdGllcyhFbnRpdGllcyBlbnRpdGllcykgewogICAgICAgIGVudGl0aWVzLmFkZEVudGl0aWVzKEJBU0lDX0FSUkFZKTsKICAgICAgICBlbnRpdGllcy5hZGRFbnRpdGllcyhJU084ODU5XzFfQVJSQVkpOwogICAgICAgIGVudGl0aWVzLmFkZEVudGl0aWVzKEhUTUw0MF9BUlJBWSk7CiAgICB9CgogICAgc3RhdGljIGludGVyZmFjZSBFbnRpdHlNYXAgewogICAgICAgIC8qKgogICAgICAgICAqIDxwPgogICAgICAgICAqIEFkZCBhbiBlbnRyeSB0byB0aGlzIGVudGl0eSBtYXAuCiAgICAgICAgICogPC9wPgogICAgICAgICAqIAogICAgICAgICAqIEBwYXJhbSBuYW1lCiAgICAgICAgICogICAgICAgICAgICB0aGUgZW50aXR5IG5hbWUKICAgICAgICAgKiBAcGFyYW0gdmFsdWUKICAgICAgICAgKiAgICAgICAgICAgIHRoZSBlbnRpdHkgdmFsdWUKICAgICAgICAgKi8KICAgICAgICB2b2lkIGFkZChTdHJpbmcgbmFtZSwgaW50IHZhbHVlKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogPHA+CiAgICAgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgZW50aXR5IGlkZW50aWZpZWQgYnkgdGhlIHNwZWNpZmllZCB2YWx1ZS4KICAgICAgICAgKiA8L3A+CiAgICAgICAgICogCiAgICAgICAgICogQHBhcmFtIHZhbHVlCiAgICAgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gbG9jYXRlCiAgICAgICAgICogQHJldHVybiBlbnRpdHkgbmFtZSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCB2YWx1ZQogICAgICAgICAqLwogICAgICAgIFN0cmluZyBuYW1lKGludCB2YWx1ZSk7CgogICAgICAgIC8qKgogICAgICAgICAqIDxwPgogICAgICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBlbnRpdHkgaWRlbnRpZmllZCBieSB0aGUgc3BlY2lmaWVkIG5hbWUuCiAgICAgICAgICogPC9wPgogICAgICAgICAqIAogICAgICAgICAqIEBwYXJhbSBuYW1lCiAgICAgICAgICogICAgICAgICAgICB0aGUgbmFtZSB0byBsb2NhdGUKICAgICAgICAgKiBAcmV0dXJuIGVudGl0eSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lCiAgICAgICAgICovCiAgICAgICAgaW50IHZhbHVlKFN0cmluZyBuYW1lKTsKICAgIH0KCiAgICBzdGF0aWMgY2xhc3MgUHJpbWl0aXZlRW50aXR5TWFwIGltcGxlbWVudHMgRW50aXR5TWFwIHsKICAgICAgICBwcml2YXRlIGZpbmFsIE1hcCBtYXBOYW1lVG9WYWx1ZSA9IG5ldyBIYXNoTWFwKCk7CgogICAgICAgIHByaXZhdGUgZmluYWwgSW50SGFzaE1hcCBtYXBWYWx1ZVRvTmFtZSA9IG5ldyBJbnRIYXNoTWFwKCk7CgogICAgICAgIC8qKgogICAgICAgICAqIHtAaW5oZXJpdERvY30KICAgICAgICAgKi8KICAgICAgICAvLyBUT0RPIG5vdCB0aHJlYWQtc2FmZSBhcyB0aGVyZSBpcyBhIHdpbmRvdyBiZXR3ZWVuIGNoYW5naW5nIHRoZSB0d28gbWFwcwogICAgICAgIHB1YmxpYyB2b2lkIGFkZChTdHJpbmcgbmFtZSwgaW50IHZhbHVlKSB7CiAgICAgICAgICAgIG1hcE5hbWVUb1ZhbHVlLnB1dChuYW1lLCBuZXcgSW50ZWdlcih2YWx1ZSkpOwogICAgICAgICAgICBtYXBWYWx1ZVRvTmFtZS5wdXQodmFsdWUsIG5hbWUpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoge0Bpbmhlcml0RG9jfQogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBTdHJpbmcgbmFtZShpbnQgdmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIChTdHJpbmcpIG1hcFZhbHVlVG9OYW1lLmdldCh2YWx1ZSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGludCB2YWx1ZShTdHJpbmcgbmFtZSkgewogICAgICAgICAgICBPYmplY3QgdmFsdWUgPSBtYXBOYW1lVG9WYWx1ZS5nZXQobmFtZSk7CiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICgoSW50ZWdlcikgdmFsdWUpLmludFZhbHVlKCk7CiAgICAgICAgfQogICAgfQoKICAgIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBNYXBJbnRNYXAgaW1wbGVtZW50cyBFbnRpdGllcy5FbnRpdHlNYXAgewogICAgICAgIHByb3RlY3RlZCBmaW5hbCBNYXAgbWFwTmFtZVRvVmFsdWU7CgogICAgICAgIHByb3RlY3RlZCBmaW5hbCBNYXAgbWFwVmFsdWVUb05hbWU7CgogICAgICAgIC8qKgogICAgICAgICAqIENvbnN0cnVjdCBhIG5ldyBpbnN0YW5jZSB3aXRoIHNwZWNpZmllZCBtYXBzLgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIG5hbWVUb1ZhbHVlIG5hbWUgdG8gdmFsdWUgbWFwCiAgICAgICAgICogQHBhcmFtIHZhbHVlVG9OYW1lIHZhbHVlIHRvIG5hbWVlIG1hcAogICAgICAgICAqLwogICAgICAgIE1hcEludE1hcChNYXAgbmFtZVRvVmFsdWUsIE1hcCB2YWx1ZVRvTmFtZSl7CiAgICAgICAgICAgIG1hcE5hbWVUb1ZhbHVlID0gbmFtZVRvVmFsdWU7CiAgICAgICAgICAgIG1hcFZhbHVlVG9OYW1lID0gdmFsdWVUb05hbWU7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHZvaWQgYWRkKFN0cmluZyBuYW1lLCBpbnQgdmFsdWUpIHsKICAgICAgICAgICAgbWFwTmFtZVRvVmFsdWUucHV0KG5hbWUsIG5ldyBJbnRlZ2VyKHZhbHVlKSk7CiAgICAgICAgICAgIG1hcFZhbHVlVG9OYW1lLnB1dChuZXcgSW50ZWdlcih2YWx1ZSksIG5hbWUpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoge0Bpbmhlcml0RG9jfQogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBTdHJpbmcgbmFtZShpbnQgdmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIChTdHJpbmcpIG1hcFZhbHVlVG9OYW1lLmdldChuZXcgSW50ZWdlcih2YWx1ZSkpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoge0Bpbmhlcml0RG9jfQogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBpbnQgdmFsdWUoU3RyaW5nIG5hbWUpIHsKICAgICAgICAgICAgT2JqZWN0IHZhbHVlID0gbWFwTmFtZVRvVmFsdWUuZ2V0KG5hbWUpOwogICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAoKEludGVnZXIpIHZhbHVlKS5pbnRWYWx1ZSgpOwogICAgICAgIH0KICAgIH0KCiAgICBzdGF0aWMgY2xhc3MgSGFzaEVudGl0eU1hcCBleHRlbmRzIE1hcEludE1hcCB7CiAgICAgICAgLyoqCiAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiA8Y29kZT5IYXNoRW50aXR5TWFwPC9jb2RlPi4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgSGFzaEVudGl0eU1hcCgpIHsKICAgICAgICAgICAgc3VwZXIobmV3IEhhc2hNYXAoKSwgbmV3IEhhc2hNYXAoKSk7CiAgICAgICAgfQogICAgfQoKICAgIHN0YXRpYyBjbGFzcyBUcmVlRW50aXR5TWFwIGV4dGVuZHMgTWFwSW50TWFwIHsKICAgICAgICAvKioKICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIDxjb2RlPlRyZWVFbnRpdHlNYXA8L2NvZGU+LgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBUcmVlRW50aXR5TWFwKCkgewogICAgICAgICAgICBzdXBlcihuZXcgVHJlZU1hcCgpLCBuZXcgVHJlZU1hcCgpKTsKICAgICAgICB9CiAgICB9CgogICAgc3RhdGljIGNsYXNzIExvb2t1cEVudGl0eU1hcCBleHRlbmRzIFByaW1pdGl2ZUVudGl0eU1hcCB7CiAgICAgICAgLy8gVE9ETyB0aGlzIGNsYXNzIGlzIG5vdCB0aHJlYWQtc2FmZQogICAgICAgIHByaXZhdGUgU3RyaW5nW10gbG9va3VwVGFibGU7CgogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBMT09LVVBfVEFCTEVfU0laRSA9IDI1NjsKCiAgICAgICAgLyoqCiAgICAgICAgICoge0Bpbmhlcml0RG9jfQogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBTdHJpbmcgbmFtZShpbnQgdmFsdWUpIHsKICAgICAgICAgICAgaWYgKHZhbHVlIDwgTE9PS1VQX1RBQkxFX1NJWkUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBsb29rdXBUYWJsZSgpW3ZhbHVlXTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gc3VwZXIubmFtZSh2YWx1ZSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiA8cD4KICAgICAgICAgKiBSZXR1cm5zIHRoZSBsb29rdXAgdGFibGUgZm9yIHRoaXMgZW50aXR5IG1hcC4gVGhlIGxvb2t1cCB0YWJsZSBpcyBjcmVhdGVkIGlmIGl0IGhhcyBub3QgYmVlbiBwcmV2aW91c2x5LgogICAgICAgICAqIDwvcD4KICAgICAgICAgKiAKICAgICAgICAgKiBAcmV0dXJuIHRoZSBsb29rdXAgdGFibGUKICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIFN0cmluZ1tdIGxvb2t1cFRhYmxlKCkgewogICAgICAgICAgICBpZiAobG9va3VwVGFibGUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgY3JlYXRlTG9va3VwVGFibGUoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbG9va3VwVGFibGU7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiA8cD4KICAgICAgICAgKiBDcmVhdGVzIGFuIGVudGl0eSBsb29rdXAgdGFibGUgb2YgTE9PS1VQX1RBQkxFX1NJWkUgZWxlbWVudHMsIGluaXRpYWxpemVkIHdpdGggZW50aXR5IG5hbWVzLgogICAgICAgICAqIDwvcD4KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIHZvaWQgY3JlYXRlTG9va3VwVGFibGUoKSB7CiAgICAgICAgICAgIGxvb2t1cFRhYmxlID0gbmV3IFN0cmluZ1tMT09LVVBfVEFCTEVfU0laRV07CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTE9PS1VQX1RBQkxFX1NJWkU7ICsraSkgewogICAgICAgICAgICAgICAgbG9va3VwVGFibGVbaV0gPSBzdXBlci5uYW1lKGkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHN0YXRpYyBjbGFzcyBBcnJheUVudGl0eU1hcCBpbXBsZW1lbnRzIEVudGl0eU1hcCB7CiAgICAgICAgLy8gVE9ETyB0aGlzIGNsYXNzIGlzIG5vdCB0aHJlYWQtc2FmZQogICAgICAgIHByb3RlY3RlZCBmaW5hbCBpbnQgZ3Jvd0J5OwoKICAgICAgICBwcm90ZWN0ZWQgaW50IHNpemUgPSAwOwoKICAgICAgICBwcm90ZWN0ZWQgU3RyaW5nW10gbmFtZXM7CgogICAgICAgIHByb3RlY3RlZCBpbnRbXSB2YWx1ZXM7CgogICAgICAgIC8qKgogICAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgPGNvZGU+QXJyYXlFbnRpdHlNYXA8L2NvZGU+LgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBBcnJheUVudGl0eU1hcCgpIHsKICAgICAgICAgICAgdGhpcy5ncm93QnkgPSAxMDA7CiAgICAgICAgICAgIG5hbWVzID0gbmV3IFN0cmluZ1tncm93QnldOwogICAgICAgICAgICB2YWx1ZXMgPSBuZXcgaW50W2dyb3dCeV07CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIDxjb2RlPkFycmF5RW50aXR5TWFwPC9jb2RlPiBzcGVjaWZ5aW5nIHRoZSBzaXplIGJ5IHdoaWNoIHRoZSBhcnJheSBzaG91bGQKICAgICAgICAgKiBncm93LgogICAgICAgICAqIAogICAgICAgICAqIEBwYXJhbSBncm93QnkKICAgICAgICAgKiAgICAgICAgICAgIGFycmF5IHdpbGwgYmUgaW5pdGlhbGl6ZWQgdG8gYW5kIHdpbGwgZ3JvdyBieSB0aGlzIGFtb3VudAogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBBcnJheUVudGl0eU1hcChpbnQgZ3Jvd0J5KSB7CiAgICAgICAgICAgIHRoaXMuZ3Jvd0J5ID0gZ3Jvd0J5OwogICAgICAgICAgICBuYW1lcyA9IG5ldyBTdHJpbmdbZ3Jvd0J5XTsKICAgICAgICAgICAgdmFsdWVzID0gbmV3IGludFtncm93QnldOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoge0Bpbmhlcml0RG9jfQogICAgICAgICAqLwogICAgICAgIHB1YmxpYyB2b2lkIGFkZChTdHJpbmcgbmFtZSwgaW50IHZhbHVlKSB7CiAgICAgICAgICAgIGVuc3VyZUNhcGFjaXR5KHNpemUgKyAxKTsKICAgICAgICAgICAgbmFtZXNbc2l6ZV0gPSBuYW1lOwogICAgICAgICAgICB2YWx1ZXNbc2l6ZV0gPSB2YWx1ZTsKICAgICAgICAgICAgc2l6ZSsrOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogVmVyaWZpZXMgdGhlIGNhcGFjaXR5IG9mIHRoZSBlbnRpdHkgYXJyYXksIGFkanVzdGluZyB0aGUgc2l6ZSBpZiBuZWNlc3NhcnkuCiAgICAgICAgICogCiAgICAgICAgICogQHBhcmFtIGNhcGFjaXR5CiAgICAgICAgICogICAgICAgICAgICBzaXplIHRoZSBhcnJheSBzaG91bGQgYmUKICAgICAgICAgKi8KICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbnN1cmVDYXBhY2l0eShpbnQgY2FwYWNpdHkpIHsKICAgICAgICAgICAgaWYgKGNhcGFjaXR5ID4gbmFtZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBpbnQgbmV3U2l6ZSA9IE1hdGgubWF4KGNhcGFjaXR5LCBzaXplICsgZ3Jvd0J5KTsKICAgICAgICAgICAgICAgIFN0cmluZ1tdIG5ld05hbWVzID0gbmV3IFN0cmluZ1tuZXdTaXplXTsKICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobmFtZXMsIDAsIG5ld05hbWVzLCAwLCBzaXplKTsKICAgICAgICAgICAgICAgIG5hbWVzID0gbmV3TmFtZXM7CiAgICAgICAgICAgICAgICBpbnRbXSBuZXdWYWx1ZXMgPSBuZXcgaW50W25ld1NpemVdOwogICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh2YWx1ZXMsIDAsIG5ld1ZhbHVlcywgMCwgc2l6ZSk7CiAgICAgICAgICAgICAgICB2YWx1ZXMgPSBuZXdWYWx1ZXM7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIHtAaW5oZXJpdERvY30KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgU3RyaW5nIG5hbWUoaW50IHZhbHVlKSB7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgKytpKSB7CiAgICAgICAgICAgICAgICBpZiAodmFsdWVzW2ldID09IHZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5hbWVzW2ldOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoge0Bpbmhlcml0RG9jfQogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBpbnQgdmFsdWUoU3RyaW5nIG5hbWUpIHsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyArK2kpIHsKICAgICAgICAgICAgICAgIGlmIChuYW1lc1tpXS5lcXVhbHMobmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVzW2ldOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICB9CgogICAgc3RhdGljIGNsYXNzIEJpbmFyeUVudGl0eU1hcCBleHRlbmRzIEFycmF5RW50aXR5TWFwIHsKCiAgICAgICAgLy8gVE9ETyAtIG5vdCB0aHJlYWQtc2FmZSwgYmVjYXVzZSBwYXJlbnQgaXMgbm90LiBBbHNvIHJlZmVyZW5jZXMgc2l6ZS4KCiAgICAgICAgLyoqCiAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiA8Y29kZT5CaW5hcnlFbnRpdHlNYXA8L2NvZGU+LgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCaW5hcnlFbnRpdHlNYXAoKSB7CiAgICAgICAgICAgIHN1cGVyKCk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIDxjb2RlPkFycmF5RW50aXR5TWFwPC9jb2RlPiBzcGVjaWZ5aW5nIHRoZSBzaXplIGJ5IHdoaWNoIHRoZSB1bmRlcmx5aW5nIGFycmF5CiAgICAgICAgICogc2hvdWxkIGdyb3cuCiAgICAgICAgICogCiAgICAgICAgICogQHBhcmFtIGdyb3dCeQogICAgICAgICAqICAgICAgICAgICAgYXJyYXkgd2lsbCBiZSBpbml0aWFsaXplZCB0byBhbmQgd2lsbCBncm93IGJ5IHRoaXMgYW1vdW50CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJpbmFyeUVudGl0eU1hcChpbnQgZ3Jvd0J5KSB7CiAgICAgICAgICAgIHN1cGVyKGdyb3dCeSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBQZXJmb3JtcyBhIGJpbmFyeSBzZWFyY2ggb2YgdGhlIGVudGl0eSBhcnJheSBmb3IgdGhlIHNwZWNpZmllZCBrZXkuIFRoaXMgbWV0aG9kIGlzIGJhc2VkIG9uIGNvZGUgaW4KICAgICAgICAgKiB7QGxpbmsgamF2YS51dGlsLkFycmF5c30uCiAgICAgICAgICogCiAgICAgICAgICogQHBhcmFtIGtleQogICAgICAgICAqICAgICAgICAgICAgdGhlIGtleSB0byBiZSBmb3VuZAogICAgICAgICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBlbnRpdHkgYXJyYXkgbWF0Y2hpbmcgdGhlIHNwZWNpZmllZCBrZXkKICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIGludCBiaW5hcnlTZWFyY2goaW50IGtleSkgewogICAgICAgICAgICBpbnQgbG93ID0gMDsKICAgICAgICAgICAgaW50IGhpZ2ggPSBzaXplIC0gMTsKCiAgICAgICAgICAgIHdoaWxlIChsb3cgPD0gaGlnaCkgewogICAgICAgICAgICAgICAgaW50IG1pZCA9IChsb3cgKyBoaWdoKSA+Pj4gMTsKICAgICAgICAgICAgICAgIGludCBtaWRWYWwgPSB2YWx1ZXNbbWlkXTsKCiAgICAgICAgICAgICAgICBpZiAobWlkVmFsIDwga2V5KSB7CiAgICAgICAgICAgICAgICAgICAgbG93ID0gbWlkICsgMTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobWlkVmFsID4ga2V5KSB7CiAgICAgICAgICAgICAgICAgICAgaGlnaCA9IG1pZCAtIDE7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBtaWQ7IC8vIGtleSBmb3VuZAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAtKGxvdyArIDEpOyAvLyBrZXkgbm90IGZvdW5kLgogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoge0Bpbmhlcml0RG9jfQogICAgICAgICAqLwogICAgICAgIHB1YmxpYyB2b2lkIGFkZChTdHJpbmcgbmFtZSwgaW50IHZhbHVlKSB7CiAgICAgICAgICAgIGVuc3VyZUNhcGFjaXR5KHNpemUgKyAxKTsKICAgICAgICAgICAgaW50IGluc2VydEF0ID0gYmluYXJ5U2VhcmNoKHZhbHVlKTsKICAgICAgICAgICAgaWYgKGluc2VydEF0ID4gMCkgewogICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBub3RlOiB0aGlzIG1lYW5zIHlvdSBjYW4ndCBpbnNlcnQgdGhlIHNhbWUgdmFsdWUgdHdpY2UKICAgICAgICAgICAgfQogICAgICAgICAgICBpbnNlcnRBdCA9IC0oaW5zZXJ0QXQgKyAxKTsgLy8gYmluYXJ5U2VhcmNoIHJldHVybnMgaXQgbmVnYXRpdmUgYW5kIG9mZi1ieS1vbmUKICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh2YWx1ZXMsIGluc2VydEF0LCB2YWx1ZXMsIGluc2VydEF0ICsgMSwgc2l6ZSAtIGluc2VydEF0KTsKICAgICAgICAgICAgdmFsdWVzW2luc2VydEF0XSA9IHZhbHVlOwogICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG5hbWVzLCBpbnNlcnRBdCwgbmFtZXMsIGluc2VydEF0ICsgMSwgc2l6ZSAtIGluc2VydEF0KTsKICAgICAgICAgICAgbmFtZXNbaW5zZXJ0QXRdID0gbmFtZTsKICAgICAgICAgICAgc2l6ZSsrOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoge0Bpbmhlcml0RG9jfQogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBTdHJpbmcgbmFtZShpbnQgdmFsdWUpIHsKICAgICAgICAgICAgaW50IGluZGV4ID0gYmluYXJ5U2VhcmNoKHZhbHVlKTsKICAgICAgICAgICAgaWYgKGluZGV4IDwgMCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5hbWVzW2luZGV4XTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBFbnRpdHlNYXAgbWFwOwoKICAgIC8qKgogICAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4KICAgICAqLwogICAgcHVibGljIEVudGl0aWVzKCl7CiAgICAgICAgbWFwID0gbmV3IEVudGl0aWVzLkxvb2t1cEVudGl0eU1hcCgpOwogICAgfQoKICAgIC8qKgogICAgICogcGFja2FnZSBzY29wZWQgY29uc3RydWN0b3IgZm9yIHRlc3RpbmcuCiAgICAgKgogICAgICogQHBhcmFtIGVtYXAgZW50aXR5IG1hcC4KICAgICAqLwogICAgRW50aXRpZXMoRW50aXR5TWFwIGVtYXApewogICAgICAgIG1hcCA9IGVtYXA7CiAgICB9CgogICAgLyoqCiAgICAgKiA8cD4KICAgICAqIEFkZHMgZW50aXRpZXMgdG8gdGhpcyBlbnRpdHkuCiAgICAgKiA8L3A+CiAgICAgKiAKICAgICAqIEBwYXJhbSBlbnRpdHlBcnJheQogICAgICogICAgICAgICAgICBhcnJheSBvZiBlbnRpdGllcyB0byBiZSBhZGRlZAogICAgICovCiAgICBwdWJsaWMgdm9pZCBhZGRFbnRpdGllcyhTdHJpbmdbXVtdIGVudGl0eUFycmF5KSB7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbnRpdHlBcnJheS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBhZGRFbnRpdHkoZW50aXR5QXJyYXlbaV1bMF0sIEludGVnZXIucGFyc2VJbnQoZW50aXR5QXJyYXlbaV1bMV0pKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiA8cD4KICAgICAqIEFkZCBhbiBlbnRpdHkgdG8gdGhpcyBlbnRpdHkuCiAgICAgKiA8L3A+CiAgICAgKiAKICAgICAqIEBwYXJhbSBuYW1lCiAgICAgKiAgICAgICAgICAgIG5hbWUgb2YgdGhlIGVudGl0eQogICAgICogQHBhcmFtIHZhbHVlCiAgICAgKiAgICAgICAgICAgIHZhbGUgb2YgdGhlIGVudGl0eQogICAgICovCiAgICBwdWJsaWMgdm9pZCBhZGRFbnRpdHkoU3RyaW5nIG5hbWUsIGludCB2YWx1ZSkgewogICAgICAgIG1hcC5hZGQobmFtZSwgdmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogPHA+CiAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBlbnRpdHkgaWRlbnRpZmllZCBieSB0aGUgc3BlY2lmaWVkIHZhbHVlLgogICAgICogPC9wPgogICAgICogCiAgICAgKiBAcGFyYW0gdmFsdWUKICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIGxvY2F0ZQogICAgICogQHJldHVybiBlbnRpdHkgbmFtZSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCB2YWx1ZQogICAgICovCiAgICBwdWJsaWMgU3RyaW5nIGVudGl0eU5hbWUoaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIG1hcC5uYW1lKHZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIDxwPgogICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIGVudGl0eSBpZGVudGlmaWVkIGJ5IHRoZSBzcGVjaWZpZWQgbmFtZS4KICAgICAqIDwvcD4KICAgICAqIAogICAgICogQHBhcmFtIG5hbWUKICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgdG8gbG9jYXRlCiAgICAgKiBAcmV0dXJuIGVudGl0eSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZW50aXR5VmFsdWUoU3RyaW5nIG5hbWUpIHsKICAgICAgICByZXR1cm4gbWFwLnZhbHVlKG5hbWUpOwogICAgfQoKICAgIC8qKgogICAgICogPHA+CiAgICAgKiBFc2NhcGVzIHRoZSBjaGFyYWN0ZXJzIGluIGEgPGNvZGU+U3RyaW5nPC9jb2RlPi4KICAgICAqIDwvcD4KICAgICAqIAogICAgICogPHA+CiAgICAgKiBGb3IgZXhhbXBsZSwgaWYgeW91IGhhdmUgY2FsbGVkIGFkZEVudGl0eSgmcXVvdDtmb28mcXVvdDssIDB4QTEpLCBlc2NhcGUoJnF1b3Q7XHUwMEExJnF1b3Q7KSB3aWxsIHJldHVybgogICAgICogJnF1b3Q7JmFtcDtmb287JnF1b3Q7CiAgICAgKiA8L3A+CiAgICAgKiAKICAgICAqIEBwYXJhbSBzdHIKICAgICAqICAgICAgICAgICAgVGhlIDxjb2RlPlN0cmluZzwvY29kZT4gdG8gZXNjYXBlLgogICAgICogQHJldHVybiBBIG5ldyBlc2NhcGVkIDxjb2RlPlN0cmluZzwvY29kZT4uCiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmcgZXNjYXBlKFN0cmluZyBzdHIpIHsKICAgICAgICBTdHJpbmdXcml0ZXIgc3RyaW5nV3JpdGVyID0gY3JlYXRlU3RyaW5nV3JpdGVyKHN0cik7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgdGhpcy5lc2NhcGUoc3RyaW5nV3JpdGVyLCBzdHIpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgLy8gVGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuIGJlY2F1c2UgQUxMIHRoZSBTdHJpbmdXcml0ZXIgbWV0aG9kcyBjYWxsZWQgYnkgI2VzY2FwZShXcml0ZXIsIFN0cmluZykgZG8gbm90CiAgICAgICAgICAgIC8vIHRocm93IElPRXhjZXB0aW9ucy4KICAgICAgICAgICAgdGhyb3cgbmV3IFVuaGFuZGxlZEV4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN0cmluZ1dyaXRlci50b1N0cmluZygpOwogICAgfQoKICAgIC8qKgogICAgICogPHA+CiAgICAgKiBFc2NhcGVzIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHBhc3NlZCBhbmQgd3JpdGVzIHRoZSByZXN1bHQgdG8gdGhlIDxjb2RlPldyaXRlcjwvY29kZT4KICAgICAqIHBhc3NlZC4KICAgICAqIDwvcD4KICAgICAqIAogICAgICogQHBhcmFtIHdyaXRlcgogICAgICogICAgICAgICAgICBUaGUgPGNvZGU+V3JpdGVyPC9jb2RlPiB0byB3cml0ZSB0aGUgcmVzdWx0cyBvZiB0aGUgZXNjYXBpbmcgdG8uIEFzc3VtZWQgdG8gYmUgYSBub24tbnVsbCB2YWx1ZS4KICAgICAqIEBwYXJhbSBzdHIKICAgICAqICAgICAgICAgICAgVGhlIDxjb2RlPlN0cmluZzwvY29kZT4gdG8gZXNjYXBlLiBBc3N1bWVkIHRvIGJlIGEgbm9uLW51bGwgdmFsdWUuCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCiAgICAgKiAgICAgICAgICAgICB3aGVuIDxjb2RlPldyaXRlcjwvY29kZT4gcGFzc2VkIHRocm93cyB0aGUgZXhjZXB0aW9uIGZyb20gY2FsbHMgdG8gdGhlIHtAbGluayBXcml0ZXIjd3JpdGUoaW50KX0KICAgICAqICAgICAgICAgICAgIG1ldGhvZHMuCiAgICAgKiAKICAgICAqIEBzZWUgI2VzY2FwZShTdHJpbmcpCiAgICAgKiBAc2VlIFdyaXRlcgogICAgICovCiAgICBwdWJsaWMgdm9pZCBlc2NhcGUoV3JpdGVyIHdyaXRlciwgU3RyaW5nIHN0cikgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBpbnQgbGVuID0gc3RyLmxlbmd0aCgpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgICAgICAgY2hhciBjID0gc3RyLmNoYXJBdChpKTsKICAgICAgICAgICAgU3RyaW5nIGVudGl0eU5hbWUgPSB0aGlzLmVudGl0eU5hbWUoYyk7CiAgICAgICAgICAgIGlmIChlbnRpdHlOYW1lID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGlmIChjID4gMHg3RikgewogICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiJiMiKTsKICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoSW50ZWdlci50b1N0cmluZyhjLCAxMCkpOwogICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnOycpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoYyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJyYnKTsKICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShlbnRpdHlOYW1lKTsKICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnOycpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogPHA+CiAgICAgKiBVbmVzY2FwZXMgdGhlIGVudGl0aWVzIGluIGEgPGNvZGU+U3RyaW5nPC9jb2RlPi4KICAgICAqIDwvcD4KICAgICAqIAogICAgICogPHA+CiAgICAgKiBGb3IgZXhhbXBsZSwgaWYgeW91IGhhdmUgY2FsbGVkIGFkZEVudGl0eSgmcXVvdDtmb28mcXVvdDssIDB4QTEpLCB1bmVzY2FwZSgmcXVvdDsmYW1wO2ZvbzsmcXVvdDspIHdpbGwgcmV0dXJuCiAgICAgKiAmcXVvdDtcdTAwQTEmcXVvdDsKICAgICAqIDwvcD4KICAgICAqIAogICAgICogQHBhcmFtIHN0cgogICAgICogICAgICAgICAgICBUaGUgPGNvZGU+U3RyaW5nPC9jb2RlPiB0byBlc2NhcGUuCiAgICAgKiBAcmV0dXJuIEEgbmV3IGVzY2FwZWQgPGNvZGU+U3RyaW5nPC9jb2RlPi4KICAgICAqLwogICAgcHVibGljIFN0cmluZyB1bmVzY2FwZShTdHJpbmcgc3RyKSB7CiAgICAgICAgaW50IGZpcnN0QW1wID0gc3RyLmluZGV4T2YoJyYnKTsKICAgICAgICBpZiAoZmlyc3RBbXAgPCAwKSB7CiAgICAgICAgICAgIHJldHVybiBzdHI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgU3RyaW5nV3JpdGVyIHN0cmluZ1dyaXRlciA9IGNyZWF0ZVN0cmluZ1dyaXRlcihzdHIpOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5kb1VuZXNjYXBlKHN0cmluZ1dyaXRlciwgc3RyLCBmaXJzdEFtcCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIC8vIFRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbiBiZWNhdXNlIEFMTCB0aGUgU3RyaW5nV3JpdGVyIG1ldGhvZHMgY2FsbGVkIGJ5ICNlc2NhcGUoV3JpdGVyLCBTdHJpbmcpIAogICAgICAgICAgICAgICAgLy8gZG8gbm90IHRocm93IElPRXhjZXB0aW9ucy4KICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbmhhbmRsZWRFeGNlcHRpb24oZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHN0cmluZ1dyaXRlci50b1N0cmluZygpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIE1ha2UgdGhlIFN0cmluZ1dyaXRlciAxMCUgbGFyZ2VyIHRoYW4gdGhlIHNvdXJjZSBTdHJpbmcgdG8gYXZvaWQgZ3Jvd2luZyB0aGUgd3JpdGVyCiAgICAgKgogICAgICogQHBhcmFtIHN0ciBUaGUgc291cmNlIHN0cmluZwogICAgICogQHJldHVybiBBIG5ld2x5IGNyZWF0ZWQgU3RyaW5nV3JpdGVyCiAgICAgKi8KICAgIHByaXZhdGUgU3RyaW5nV3JpdGVyIGNyZWF0ZVN0cmluZ1dyaXRlcihTdHJpbmcgc3RyKSB7CiAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdXcml0ZXIoKGludCkgKHN0ci5sZW5ndGgoKSArIChzdHIubGVuZ3RoKCkgKiAwLjEpKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiA8cD4KICAgICAqIFVuZXNjYXBlcyB0aGUgZXNjYXBlZCBlbnRpdGllcyBpbiB0aGUgPGNvZGU+U3RyaW5nPC9jb2RlPiBwYXNzZWQgYW5kIHdyaXRlcyB0aGUgcmVzdWx0IHRvIHRoZQogICAgICogPGNvZGU+V3JpdGVyPC9jb2RlPiBwYXNzZWQuCiAgICAgKiA8L3A+CiAgICAgKiAKICAgICAqIEBwYXJhbSB3cml0ZXIKICAgICAqICAgICAgICAgICAgVGhlIDxjb2RlPldyaXRlcjwvY29kZT4gdG8gd3JpdGUgdGhlIHJlc3VsdHMgdG87IGFzc3VtZWQgdG8gYmUgbm9uLW51bGwuCiAgICAgKiBAcGFyYW0gc3RyCiAgICAgKiAgICAgICAgICAgIFRoZSBzb3VyY2UgPGNvZGU+U3RyaW5nPC9jb2RlPiB0byB1bmVzY2FwZTsgYXNzdW1lZCB0byBiZSBub24tbnVsbC4KICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KICAgICAqICAgICAgICAgICAgIHdoZW4gPGNvZGU+V3JpdGVyPC9jb2RlPiBwYXNzZWQgdGhyb3dzIHRoZSBleGNlcHRpb24gZnJvbSBjYWxscyB0byB0aGUge0BsaW5rIFdyaXRlciN3cml0ZShpbnQpfQogICAgICogICAgICAgICAgICAgbWV0aG9kcy4KICAgICAqIAogICAgICogQHNlZSAjZXNjYXBlKFN0cmluZykKICAgICAqIEBzZWUgV3JpdGVyCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHVuZXNjYXBlKFdyaXRlciB3cml0ZXIsIFN0cmluZyBzdHIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgaW50IGZpcnN0QW1wID0gc3RyLmluZGV4T2YoJyYnKTsKICAgICAgICBpZiAoZmlyc3RBbXAgPCAwKSB7CiAgICAgICAgICAgIHdyaXRlci53cml0ZShzdHIpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZG9VbmVzY2FwZSh3cml0ZXIsIHN0ciwgZmlyc3RBbXApOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFVuZGVybHlpbmcgdW5lc2NhcGUgbWV0aG9kIHRoYXQgYWxsb3dzIHRoZSBvcHRpbWlzYXRpb24gb2Ygbm90IHN0YXJ0aW5nIGZyb20gdGhlIDAgaW5kZXggYWdhaW4uCiAgICAgKgogICAgICogQHBhcmFtIHdyaXRlcgogICAgICogICAgICAgICAgICBUaGUgPGNvZGU+V3JpdGVyPC9jb2RlPiB0byB3cml0ZSB0aGUgcmVzdWx0cyB0bzsgYXNzdW1lZCB0byBiZSBub24tbnVsbC4KICAgICAqIEBwYXJhbSBzdHIKICAgICAqICAgICAgICAgICAgVGhlIHNvdXJjZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIHVuZXNjYXBlOyBhc3N1bWVkIHRvIGJlIG5vbi1udWxsLgogICAgICogQHBhcmFtIGZpcnN0QW1wCiAgICAgKiAgICAgICAgICAgIFRoZSA8Y29kZT5pbnQ8L2NvZGU+IGluZGV4IG9mIHRoZSBmaXJzdCBhbXBlcnNhbmQgaW4gdGhlIHNvdXJjZSBTdHJpbmcuCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCiAgICAgKiAgICAgICAgICAgICB3aGVuIDxjb2RlPldyaXRlcjwvY29kZT4gcGFzc2VkIHRocm93cyB0aGUgZXhjZXB0aW9uIGZyb20gY2FsbHMgdG8gdGhlIHtAbGluayBXcml0ZXIjd3JpdGUoaW50KX0KICAgICAqICAgICAgICAgICAgIG1ldGhvZHMuCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBkb1VuZXNjYXBlKFdyaXRlciB3cml0ZXIsIFN0cmluZyBzdHIsIGludCBmaXJzdEFtcCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICB3cml0ZXIud3JpdGUoc3RyLCAwLCBmaXJzdEFtcCk7CiAgICAgICAgaW50IGxlbiA9IHN0ci5sZW5ndGgoKTsKICAgICAgICBmb3IgKGludCBpID0gZmlyc3RBbXA7IGkgPCBsZW47IGkrKykgewogICAgICAgICAgICBjaGFyIGMgPSBzdHIuY2hhckF0KGkpOwogICAgICAgICAgICBpZiAoYyA9PSAnJicpIHsKICAgICAgICAgICAgICAgIGludCBuZXh0SWR4ID0gaSArIDE7CiAgICAgICAgICAgICAgICBpbnQgc2VtaUNvbG9uSWR4ID0gc3RyLmluZGV4T2YoJzsnLCBuZXh0SWR4KTsKICAgICAgICAgICAgICAgIGlmIChzZW1pQ29sb25JZHggPT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoYyk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnQgYW1waGVyc2FuZElkeCA9IHN0ci5pbmRleE9mKCcmJywgaSArIDEpOwogICAgICAgICAgICAgICAgaWYgKGFtcGhlcnNhbmRJZHggIT0gLTEgJiYgYW1waGVyc2FuZElkeCA8IHNlbWlDb2xvbklkeCkgewogICAgICAgICAgICAgICAgICAgIC8vIFRoZW4gdGhlIHRleHQgbG9va3MgbGlrZSAmLi4uJi4uLjsKICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoYyk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBTdHJpbmcgZW50aXR5Q29udGVudCA9IHN0ci5zdWJzdHJpbmcobmV4dElkeCwgc2VtaUNvbG9uSWR4KTsKICAgICAgICAgICAgICAgIGludCBlbnRpdHlWYWx1ZSA9IC0xOwogICAgICAgICAgICAgICAgaW50IGVudGl0eUNvbnRlbnRMZW4gPSBlbnRpdHlDb250ZW50Lmxlbmd0aCgpOwogICAgICAgICAgICAgICAgaWYgKGVudGl0eUNvbnRlbnRMZW4gPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGVudGl0eUNvbnRlbnQuY2hhckF0KDApID09ICcjJykgeyAvLyBlc2NhcGVkIHZhbHVlIGNvbnRlbnQgaXMgYW4gaW50ZWdlciAoZGVjaW1hbCBvcgogICAgICAgICAgICAgICAgICAgICAgICAvLyBoZXhpZGVjaW1hbCkKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVudGl0eUNvbnRlbnRMZW4gPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyIGlzSGV4Q2hhciA9IGVudGl0eUNvbnRlbnQuY2hhckF0KDEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGlzSGV4Q2hhcikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdYJyA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3gnIDogewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW50aXR5VmFsdWUgPSBJbnRlZ2VyLnBhcnNlSW50KGVudGl0eUNvbnRlbnQuc3Vic3RyaW5nKDIpLCAxNik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0IDogewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW50aXR5VmFsdWUgPSBJbnRlZ2VyLnBhcnNlSW50KGVudGl0eUNvbnRlbnQuc3Vic3RyaW5nKDEpLCAxMCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVudGl0eVZhbHVlID4gMHhGRkZGKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudGl0eVZhbHVlID0gLTE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnRpdHlWYWx1ZSA9IC0xOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gZXNjYXBlZCB2YWx1ZSBjb250ZW50IGlzIGFuIGVudGl0eSBuYW1lCiAgICAgICAgICAgICAgICAgICAgICAgIGVudGl0eVZhbHVlID0gdGhpcy5lbnRpdHlWYWx1ZShlbnRpdHlDb250ZW50KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKGVudGl0eVZhbHVlID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCcmJyk7CiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKGVudGl0eUNvbnRlbnQpOwogICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnOycpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoZW50aXR5VmFsdWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaSA9IHNlbWlDb2xvbklkeDsgLy8gbW92ZSBpbmRleCB1cCB0byB0aGUgc2VtaS1jb2xvbgogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKGMpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKfQo=