KEXEL/git
0
1<!DOCTYPE html>2<html lang="pt-br">3 4<head>5 <meta charset="UTF-8">6 <title>VOTYMEHJONG</title>7 <meta name="viewport" content="width=device-width, initial-scale=1" />8 <meta name="description" content="VOTYMEHJONG GAME ADAPTÁVEL..." />9 <meta name="mobile-web-app-capable" content="yes" />10 <meta name="apple-mobile-web-app-capable" content="yes" />11 <meta name="application-name" content="VOTYMEHJONG" />12 <meta name="apple-mobile-web-app-title" content="VOTYMEHJONG" />13 <meta name="msapplication-starturl" content="https://kexel-git.static.hf.space/VotyMehjong.html?Installe=votymehjong" />14 <meta name="theme-color" content="#222" />15 <meta name="msapplication-navbutton-color" content="#222" />16 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />17 <meta name="apple-touch-fullscreen" content="yes" />18 <meta name="robots" content="index, follow" />19 <meta name="googlebot" content="index, follow" />20 <meta property="og:image" content="https://placehold.co/512/3b2d50/bdbac1.png?font=roboto&text=VOTY.MEHJONG" />21 <link rel="icon" type="image/png" sizes="512x512" href="https://placehold.co/512/3b2d50/bdbac1.png?font=roboto&text=VOTY.MEHJONG" />22 <link rel="apple-touch-icon" type="image/png" sizes="512x512" href="https://placehold.co/512/3b2d50/bdbac1.png?font=roboto&text=VOTY.MEHJONG" />23 <link rel="icon" type="image/png" sizes="192x192" href="https://placehold.co/192/3b2d50/bdbac1.png?font=roboto&text=VOTY.MEHJONG" />24 <link rel="apple-touch-icon" type="image/png" sizes="192x192" href="https://placehold.co/192/3b2d50/bdbac1.png?font=roboto&text=VOTY.MEHJONG" />25 <link rel="icon" type="image/png" sizes="144x144" href="https://placehold.co/144/3b2d50/bdbac1.png?font=roboto&text=VOTY.MEHJONG" />26 <link rel="apple-touch-icon" type="image/png" sizes="144x144" href="https://placehold.co/144/3b2d50/bdbac1.png?font=roboto&text=VOTY.MEHJONG" />27 <link rel="icon" type="image/png" sizes="96x96" href="https://placehold.co/96/3b2d50/bdbac1.png?font=roboto&text=VOTY.MEHJONG" />28 <link rel="apple-touch-icon" type="image/png" sizes="96x96" href="https://placehold.co/96/3b2d50/bdbac1.png?font=roboto&text=VOTY.MEHJONG" />29 <link rel="icon" type="image/png" sizes="72x72" href="https://placehold.co/72/3b2d50/bdbac1.png?font=roboto&text=VOTY.MEHJONG" />30 <link rel="apple-touch-icon" type="image/png" sizes="72x72" href="https://placehold.co/72/3b2d50/bdbac1.png?font=roboto&text=VOTY.MEHJONG" />31 <link rel="icon" type="image/png" sizes="48x48" href="https://placehold.co/48/3b2d50/bdbac1.png?font=roboto&text=VOTY.MEHJONG" />32 <link rel="apple-touch-icon" type="image/png" sizes="48x48" href="https://placehold.co/48/3b2d50/bdbac1.png?font=roboto&text=VOTY.MEHJONG" />33 <link rel="icon" type="image/png" sizes="36x36" href="https://placehold.co/36/3b2d50/bdbac1.png?font=roboto&text=VOTY.MEHJONG" />34 <link rel="apple-touch-icon" type="image/png" sizes="36x36" href="https://placehold.co/36/3b2d50/bdbac1.png?font=roboto&text=VOTY.MEHJONG" />35 36 <script src="data:application/javascript;charset=utf-8;base64,dmFyIGNvbG9iZD0iIzJiMzAzNWM3Iixjb2xvbGlzPSIjNzI2ZDNiIixjb2xvdHh0PSIjZmZmOSI7ZG9jdW1lbnQud3JpdGUoJzxzdHlsZT4ucGFjZXtwb2ludGVyLWV2ZW50czpub25lO3VzZXItc2VsZWN0Om5vbmU7ei1pbmRleDo5OTk5OTk5O3Bvc2l0aW9uOmZpeGVkO3RvcDowO2xlZnQ6MDtyaWdodDowO2JvdHRvbTowO2hlaWdodDoxMDAlO3dpZHRoOjEwMCU7YmFja2dyb3VuZDonK2NvbG9iZCsnO292ZXJmbG93OmhpZGRlbn0ucGFjZTo6YmVmb3Jle2NvbnRlbnQ6IkNBUlJFR0FORE8uLi4iO2NvbG9yOicrY29sb3R4dCsnO3Bvc2l0aW9uOmFic29sdXRlO3RvcDo0NyU7bGVmdDo1MCU7dHJhbnNmb3JtOnRyYW5zbGF0ZSgtNTAlLC01MCUpfS5wYWNlIC5wYWNlLXByb2dyZXNze2JveC1zaXppbmc6Ym9yZGVyLWJveDt0cmFuc2Zvcm06dHJhbnNsYXRlM2QoMCwwLDApO21heC13aWR0aDoxMDAlO3Bvc2l0aW9uOmZpeGVkO3otaW5kZXg6MjAwMDtkaXNwbGF5OmJsb2NrO3Bvc2l0aW9uOmFic29sdXRlO2JvdHRvbTo1MCU7cmlnaHQ6MTAwJTtoZWlnaHQ6NXB4O3dpZHRoOjEwMCU7YmFja2dyb3VuZDonK2NvbG9saXMrJ30ucGFjZS5wYWNlLWluYWN0aXZle2Rpc3BsYXk6bm9uZX08L3N0eWxlPicpOyhmdW5jdGlvbigpe2Z1bmN0aW9uIG8odCxlKXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gdC5hcHBseShlLGFyZ3VtZW50cyl9fXZhciB1LGMsaSxuLHksdCxsLHYscixzLGEsZSxwLHcsYixoLGYsZCxnLG0sayxTLHEseCxMLFAsVCxSLGosTyxFLE0sQSxDLE4sXyxGLFUsVyxYLEQsSCxJLHosRyxCPVtdLnNsaWNlLEo9e30uaGFzT3duUHJvcGVydHksSz1mdW5jdGlvbih0LGUpe2Zvcih2YXIgbiBpbiBlKUouY2FsbChlLG4pJiYodFtuXT1lW25dKTtmdW5jdGlvbiByKCl7dGhpcy5jb25zdHJ1Y3Rvcj10fXJldHVybiByLnByb3RvdHlwZT1lLnByb3RvdHlwZSx0LnByb3RvdHlwZT1uZXcgcix0Ll9fc3VwZXJfXz1lLnByb3RvdHlwZSx0fSxRPVtdLmluZGV4T2Z8fGZ1bmN0aW9uKHQpe2Zvcih2YXIgZT0wLG49dGhpcy5sZW5ndGg7ZTxuO2UrKylpZihlIGluIHRoaXMmJnRoaXNbZV09PT10KXJldHVybiBlO3JldHVybi0xfTtmdW5jdGlvbiBWKCl7fWZvcihmPXtjbGFzc05hbWU6IiIsY2F0Y2h1cFRpbWU6MTAwLGluaXRpYWxSYXRlOi4wMyxtaW5UaW1lOjI1MCxnaG9zdFRpbWU6MTAwLG1heFByb2dyZXNzUGVyRnJhbWU6MjAsZWFzZUZhY3RvcjoxLjI1LHN0YXJ0T25QYWdlTG9hZDohMCxyZXN0YXJ0T25QdXNoU3RhdGU6ITAscmVzdGFydE9uUmVxdWVzdEFmdGVyOjUwMCx0YXJnZXQ6ImJvZHkiLGVsZW1lbnRzOntjaGVja0ludGVydmFsOjEwMCxzZWxlY3RvcnM6WyJib2R5Il19LGV2ZW50TGFnOnttaW5TYW1wbGVzOjEwLHNhbXBsZUNvdW50OjMsbGFnVGhyZXNob2xkOjN9LGFqYXg6e3RyYWNrTWV0aG9kczpbIkdFVCJdLHRyYWNrV2ViU29ja2V0czohMCxpZ25vcmVVUkxzOltdfX0sTD1mdW5jdGlvbigpe3ZhciB0O3JldHVybiBudWxsIT0odD0idW5kZWZpbmVkIiE9dHlwZW9mIHBlcmZvcm1hbmNlJiZudWxsIT09cGVyZm9ybWFuY2UmJiJmdW5jdGlvbiI9PXR5cGVvZiBwZXJmb3JtYW5jZS5ub3c/cGVyZm9ybWFuY2Uubm93KCk6dm9pZCAwKT90OituZXcgRGF0ZX0sVD13aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lfHx3aW5kb3cubW96UmVxdWVzdEFuaW1hdGlvbkZyYW1lfHx3aW5kb3cud2Via2l0UmVxdWVzdEFuaW1hdGlvbkZyYW1lfHx3aW5kb3cubXNSZXF1ZXN0QW5pbWF0aW9uRnJhbWUsaD13aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWV8fHdpbmRvdy5tb3pDYW5jZWxBbmltYXRpb25GcmFtZSxhPWZ1bmN0aW9uKHQsZSxuKXtyZXR1cm4oImZ1bmN0aW9uIj09dHlwZW9mIHQuYWRkRXZlbnRMaXN0ZW5lcj90LmFkZEV2ZW50TGlzdGVuZXIoZSxuLCExKTp2b2lkIDApfHwodFsib24iK2VdPW4pfSxudWxsPT1UJiYoVD1mdW5jdGlvbih0KXtyZXR1cm4gc2V0VGltZW91dCh0LDUwKX0saD1mdW5jdGlvbih0KXtyZXR1cm4gY2xlYXJUaW1lb3V0KHQpfSksaj1mdW5jdGlvbihlKXt2YXIgbj1MKCkscj1mdW5jdGlvbigpe3ZhciB0PUwoKS1uO3JldHVybiAzMzw9dD8obj1MKCksZSh0LGZ1bmN0aW9uKCl7cmV0dXJuIFQocil9KSk6c2V0VGltZW91dChyLDMzLXQpfTtyZXR1cm4gcigpfSxSPWZ1bmN0aW9uKCl7dmFyIHQ9YXJndW1lbnRzWzBdLGU9YXJndW1lbnRzWzFdLG49Mzw9YXJndW1lbnRzLmxlbmd0aD9CLmNhbGwoYXJndW1lbnRzLDIpOltdO3JldHVybiJmdW5jdGlvbiI9PXR5cGVvZiB0W2VdP3RbZV0uYXBwbHkodCxuKTp0W2VdfSxkPWZ1bmN0aW9uKCl7Zm9yKHZhciB0LGUsbixyPWFyZ3VtZW50c1swXSxzPTI8PWFyZ3VtZW50cy5sZW5ndGg/Qi5jYWxsKGFyZ3VtZW50cywxKTpbXSxvPTAsaT1zLmxlbmd0aDtvPGk7bysrKWlmKGU9c1tvXSlmb3IodCBpbiBlKUouY2FsbChlLHQpJiYobj1lW3RdLG51bGwhPXJbdF0mJiJvYmplY3QiPT10eXBlb2Ygclt0XSYmbnVsbCE9biYmIm9iamVjdCI9PXR5cGVvZiBuP2Qoclt0XSxuKTpyW3RdPW4pO3JldHVybiByfSxwPWZ1bmN0aW9uKHQpe2Zvcih2YXIgZSxuLHI9ZT0wLHM9MCxvPXQubGVuZ3RoO3M8bztzKyspbj10W3NdLHIrPU1hdGguYWJzKG4pLGUrKztyZXR1cm4gci9lfSxtPWZ1bmN0aW9uKHQsZSl7dmFyIG4scjtpZihudWxsPT10JiYodD0ib3B0aW9ucyIpLG51bGw9PWUmJihlPSEwKSxyPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIltkYXRhLXBhY2UtIit0KyJdIikpe2lmKG49ci5nZXRBdHRyaWJ1dGUoImRhdGEtcGFjZS0iK3QpLCFlKXJldHVybiBuO3RyeXtyZXR1cm4gSlNPTi5wYXJzZShuKX1jYXRjaCh0KXtyZXR1cm4idW5kZWZpbmVkIiE9dHlwZW9mIGNvbnNvbGUmJm51bGwhPT1jb25zb2xlP2NvbnNvbGUuZXJyb3IoIkVycm9yIHBhcnNpbmcgaW5saW5lIHBhY2Ugb3B0aW9ucyIsdCk6dm9pZCAwfX19LFYucHJvdG90eXBlLm9uPWZ1bmN0aW9uKHQsZSxuLHIpe3ZhciBzO3JldHVybiBudWxsPT1yJiYocj0hMSksbnVsbD09dGhpcy5iaW5kaW5ncyYmKHRoaXMuYmluZGluZ3M9e30pLG51bGw9PShzPXRoaXMuYmluZGluZ3MpW3RdJiYoc1t0XT1bXSksdGhpcy5iaW5kaW5nc1t0XS5wdXNoKHtoYW5kbGVyOmUsY3R4Om4sb25jZTpyfSl9LFYucHJvdG90eXBlLm9uY2U9ZnVuY3Rpb24odCxlLG4pe3JldHVybiB0aGlzLm9uKHQsZSxuLCEwKX0sVi5wcm90b3R5cGUub2ZmPWZ1bmN0aW9uKHQsZSl7dmFyIG4scixzO2lmKG51bGwhPShudWxsIT0ocj10aGlzLmJpbmRpbmdzKT9yW3RdOnZvaWQgMCkpe2lmKG51bGw9PWUpcmV0dXJuIGRlbGV0ZSB0aGlzLmJpbmRpbmdzW3RdO2ZvcihuPTAscz1bXTtuPHRoaXMuYmluZGluZ3NbdF0ubGVuZ3RoOyl0aGlzLmJpbmRpbmdzW3RdW25dLmhhbmRsZXI9PT1lP3MucHVzaCh0aGlzLmJpbmRpbmdzW3RdLnNwbGljZShuLDEpKTpzLnB1c2gobisrKTtyZXR1cm4gc319LFYucHJvdG90eXBlLnRyaWdnZXI9ZnVuY3Rpb24oKXt2YXIgdCxlLG4scixzLG8saT1hcmd1bWVudHNbMF0sYT0yPD1hcmd1bWVudHMubGVuZ3RoP0IuY2FsbChhcmd1bWVudHMsMSk6W107aWYobnVsbCE9KHI9dGhpcy5iaW5kaW5ncykmJnJbaV0pe2ZvcihuPTAsbz1bXTtuPHRoaXMuYmluZGluZ3NbaV0ubGVuZ3RoOyllPShzPXRoaXMuYmluZGluZ3NbaV1bbl0pLmhhbmRsZXIsdD1zLmN0eCxzPXMub25jZSxlLmFwcGx5KG51bGwhPXQ/dDp0aGlzLGEpLHM/by5wdXNoKHRoaXMuYmluZGluZ3NbaV0uc3BsaWNlKG4sMSkpOm8ucHVzaChuKyspO3JldHVybiBvfX0sRz1WLHk9d2luZG93LlBhY2V8fHt9LHdpbmRvdy5QYWNlPXksZCh5LEcucHJvdG90eXBlKSxQPXkub3B0aW9ucz1kKHt9LGYsd2luZG93LnBhY2VPcHRpb25zLG0oKSksVz0wLEQ9KEk9WyJhamF4IiwiZG9jdW1lbnQiLCJldmVudExhZyIsImVsZW1lbnRzIl0pLmxlbmd0aDtXPEQ7VysrKSEwPT09UFtBPUlbV11dJiYoUFtBXT1mW0FdKTtmdW5jdGlvbiBZKCl7cmV0dXJuIFkuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsYXJndW1lbnRzKX1mdW5jdGlvbiBaKCl7dGhpcy5wcm9ncmVzcz0wfWZ1bmN0aW9uICQoKXt0aGlzLmJpbmRpbmdzPXt9fWZ1bmN0aW9uIHR0KCl7dmFyIGUsbz10aGlzO3R0Ll9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLGFyZ3VtZW50cyksZT1mdW5jdGlvbihyKXt2YXIgcz1yLm9wZW47cmV0dXJuIHIub3Blbj1mdW5jdGlvbih0LGUsbil7cmV0dXJuIE0odCkmJm8udHJpZ2dlcigicmVxdWVzdCIse3R5cGU6dCx1cmw6ZSxyZXF1ZXN0OnJ9KSxzLmFwcGx5KHIsYXJndW1lbnRzKX19LHdpbmRvdy5YTUxIdHRwUmVxdWVzdD1mdW5jdGlvbih0KXt0PW5ldyBVKHQpO3JldHVybiBlKHQpLHR9O3RyeXtnKHdpbmRvdy5YTUxIdHRwUmVxdWVzdCxVKX1jYXRjaCh0KXt9aWYobnVsbCE9Ril7d2luZG93LlhEb21haW5SZXF1ZXN0PWZ1bmN0aW9uKCl7dmFyIHQ9bmV3IEY7cmV0dXJuIGUodCksdH07dHJ5e2cod2luZG93LlhEb21haW5SZXF1ZXN0LEYpfWNhdGNoKHQpe319aWYobnVsbCE9XyYmUC5hamF4LnRyYWNrV2ViU29ja2V0cyl7d2luZG93LldlYlNvY2tldD1mdW5jdGlvbih0LGUpe3ZhciBuPW51bGwhPWU/bmV3IF8odCxlKTpuZXcgXyh0KTtyZXR1cm4gTSgic29ja2V0IikmJm8udHJpZ2dlcigicmVxdWVzdCIse3R5cGU6InNvY2tldCIsdXJsOnQscHJvdG9jb2xzOmUscmVxdWVzdDpufSksbn07dHJ5e2cod2luZG93LldlYlNvY2tldCxfKX1jYXRjaCh0KXt9fX1mdW5jdGlvbiBldCgpe3RoaXMuY29tcGxldGU9byh0aGlzLmNvbXBsZXRlLHRoaXMpO3ZhciB0PXRoaXM7dGhpcy5lbGVtZW50cz1bXSxrKCkub24oInJlcXVlc3QiLGZ1bmN0aW9uKCl7cmV0dXJuIHQud2F0Y2guYXBwbHkodCxhcmd1bWVudHMpfSl9ZnVuY3Rpb24gbnQodCl7dmFyIGUsbixyLHM7Zm9yKG51bGw9PXQmJih0PXt9KSx0aGlzLmNvbXBsZXRlPW8odGhpcy5jb21wbGV0ZSx0aGlzKSx0aGlzLmVsZW1lbnRzPVtdLG51bGw9PXQuc2VsZWN0b3JzJiYodC5zZWxlY3RvcnM9W10pLG49MCxyPShzPXQuc2VsZWN0b3JzKS5sZW5ndGg7bjxyO24rKyllPXNbbl0sdGhpcy5lbGVtZW50cy5wdXNoKG5ldyBpKGUsdGhpcy5jb21wbGV0ZSkpfWZ1bmN0aW9uIHJ0KHQsZSl7dGhpcy5zZWxlY3Rvcj10LHRoaXMuY29tcGxldGVDYWxsYmFjaz1lLHRoaXMucHJvZ3Jlc3M9MCx0aGlzLmNoZWNrKCl9ZnVuY3Rpb24gc3QoKXt2YXIgdCxlLG49dGhpczt0aGlzLnByb2dyZXNzPW51bGwhPShlPXRoaXMuc3RhdGVzW2RvY3VtZW50LnJlYWR5U3RhdGVdKT9lOjEwMCx0PWRvY3VtZW50Lm9ucmVhZHlzdGF0ZWNoYW5nZSxkb2N1bWVudC5vbnJlYWR5c3RhdGVjaGFuZ2U9ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbCE9bi5zdGF0ZXNbZG9jdW1lbnQucmVhZHlTdGF0ZV0mJihuLnByb2dyZXNzPW4uc3RhdGVzW2RvY3VtZW50LnJlYWR5U3RhdGVdKSwiZnVuY3Rpb24iPT10eXBlb2YgdD90LmFwcGx5KG51bGwsYXJndW1lbnRzKTp2b2lkIDB9fWZ1bmN0aW9uIG90KHQpe3RoaXMuc291cmNlPXQsdGhpcy5sYXN0PXRoaXMuc2luY2VMYXN0VXBkYXRlPTAsdGhpcy5yYXRlPVAuaW5pdGlhbFJhdGUsdGhpcy5jYXRjaHVwPTAsdGhpcy5wcm9ncmVzcz10aGlzLmxhc3RQcm9ncmVzcz0wLG51bGwhPXRoaXMuc291cmNlJiYodGhpcy5wcm9ncmVzcz1SKHRoaXMuc291cmNlLCJwcm9ncmVzcyIpKX1HPUVycm9yLEsoWSxHKSxuPVksWi5wcm90b3R5cGUuZ2V0RWxlbWVudD1mdW5jdGlvbigpe3ZhciB0O2lmKG51bGw9PXRoaXMuZWwpe2lmKCEodD1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKFAudGFyZ2V0KSkpdGhyb3cgbmV3IG47dGhpcy5lbD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKSx0aGlzLmVsLmNsYXNzTmFtZT0icGFjZSBwYWNlLWFjdGl2ZSIsZG9jdW1lbnQuYm9keS5jbGFzc05hbWU9ZG9jdW1lbnQuYm9keS5jbGFzc05hbWUucmVwbGFjZSgvKHBhY2UtZG9uZSApfC8sInBhY2UtcnVubmluZyAiKTt2YXIgZT0iIiE9PVAuY2xhc3NOYW1lPyIgIitQLmNsYXNzTmFtZToiIjt0aGlzLmVsLmlubmVySFRNTD0nPGRpdiBjbGFzcz0icGFjZS1wcm9ncmVzcycrZSsnIj48ZGl2IGNsYXNzPSJwYWNlLXByb2dyZXNzLWlubmVyIj48L2Rpdj48L2Rpdj48ZGl2IGNsYXNzPSJwYWNlLWFjdGl2aXR5Ij48L2Rpdj4nLG51bGwhPXQuZmlyc3RDaGlsZD90Lmluc2VydEJlZm9yZSh0aGlzLmVsLHQuZmlyc3RDaGlsZCk6dC5hcHBlbmRDaGlsZCh0aGlzLmVsKX1yZXR1cm4gdGhpcy5lbH0sWi5wcm90b3R5cGUuZmluaXNoPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5nZXRFbGVtZW50KCk7cmV0dXJuIHQuY2xhc3NOYW1lPXQuY2xhc3NOYW1lLnJlcGxhY2UoInBhY2UtYWN0aXZlIiwicGFjZS1pbmFjdGl2ZSIpLGRvY3VtZW50LmJvZHkuY2xhc3NOYW1lPWRvY3VtZW50LmJvZHkuY2xhc3NOYW1lLnJlcGxhY2UoInBhY2UtcnVubmluZyAiLCJwYWNlLWRvbmUgIil9LFoucHJvdG90eXBlLnVwZGF0ZT1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5wcm9ncmVzcz10LHkudHJpZ2dlcigicHJvZ3Jlc3MiLHQpLHRoaXMucmVuZGVyKCl9LFoucHJvdG90eXBlLmRlc3Ryb3k9ZnVuY3Rpb24oKXt0cnl7dGhpcy5nZXRFbGVtZW50KCkucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLmdldEVsZW1lbnQoKSl9Y2F0Y2godCl7bj10fXJldHVybiB0aGlzLmVsPXZvaWQgMH0sWi5wcm90b3R5cGUucmVuZGVyPWZ1bmN0aW9uKCl7dmFyIHQsZSxuLHIscyxvLGk7aWYobnVsbD09ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihQLnRhcmdldCkpcmV0dXJuITE7Zm9yKHQ9dGhpcy5nZXRFbGVtZW50KCkscj0idHJhbnNsYXRlM2QoIit0aGlzLnByb2dyZXNzKyIlLCAwLCAwKSIscz0wLG89KGk9WyJ3ZWJraXRUcmFuc2Zvcm0iLCJtc1RyYW5zZm9ybSIsInRyYW5zZm9ybSJdKS5sZW5ndGg7czxvO3MrKyllPWlbc10sdC5jaGlsZHJlblswXS5zdHlsZVtlXT1yO3JldHVybighdGhpcy5sYXN0UmVuZGVyZWRQcm9ncmVzc3x8dGhpcy5sYXN0UmVuZGVyZWRQcm9ncmVzc3wwIT09dGhpcy5wcm9ncmVzc3wwKSYmKHQuY2hpbGRyZW5bMF0uc2V0QXR0cmlidXRlKCJkYXRhLXByb2dyZXNzLXRleHQiLCgwfHRoaXMucHJvZ3Jlc3MpKyIlIiksMTAwPD10aGlzLnByb2dyZXNzP249Ijk5Ijoobj10aGlzLnByb2dyZXNzPDEwPyIwIjoiIixuKz0wfHRoaXMucHJvZ3Jlc3MpLHQuY2hpbGRyZW5bMF0uc2V0QXR0cmlidXRlKCJkYXRhLXByb2dyZXNzIiwiIituKSkseS50cmlnZ2VyKCJjaGFuZ2UiLHRoaXMucHJvZ3Jlc3MpLHRoaXMubGFzdFJlbmRlcmVkUHJvZ3Jlc3M9dGhpcy5wcm9ncmVzc30sWi5wcm90b3R5cGUuZG9uZT1mdW5jdGlvbigpe3JldHVybiAxMDA8PXRoaXMucHJvZ3Jlc3N9LGM9WiwkLnByb3RvdHlwZS50cmlnZ2VyPWZ1bmN0aW9uKHQsZSl7dmFyIG4scixzLG8saTtpZihudWxsIT10aGlzLmJpbmRpbmdzW3RdKXtmb3IoaT1bXSxyPTAscz0obz10aGlzLmJpbmRpbmdzW3RdKS5sZW5ndGg7cjxzO3IrKyluPW9bcl0saS5wdXNoKG4uY2FsbCh0aGlzLGUpKTtyZXR1cm4gaX19LCQucHJvdG90eXBlLm9uPWZ1bmN0aW9uKHQsZSl7dmFyIG47cmV0dXJuIG51bGw9PShuPXRoaXMuYmluZGluZ3MpW3RdJiYoblt0XT1bXSksdGhpcy5iaW5kaW5nc1t0XS5wdXNoKGUpfSxtPSQsVT13aW5kb3cuWE1MSHR0cFJlcXVlc3QsRj13aW5kb3cuWERvbWFpblJlcXVlc3QsXz13aW5kb3cuV2ViU29ja2V0LGc9ZnVuY3Rpb24odCxlKXt2YXIgbixyPVtdO2ZvcihuIGluIGUucHJvdG90eXBlKXRyeXtudWxsPT10W25dJiYiZnVuY3Rpb24iIT10eXBlb2YgZVtuXT8iZnVuY3Rpb24iPT10eXBlb2YgT2JqZWN0LmRlZmluZVByb3BlcnR5P3IucHVzaChPYmplY3QuZGVmaW5lUHJvcGVydHkodCxuLHtnZXQ6ZnVuY3Rpb24odCl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGUucHJvdG90eXBlW3RdfX0obiksY29uZmlndXJhYmxlOiEwLGVudW1lcmFibGU6ITB9KSk6ci5wdXNoKHRbbl09ZS5wcm90b3R5cGVbbl0pOnIucHVzaCh2b2lkIDApfWNhdGNoKHQpezB9cmV0dXJuIHJ9LHE9W10seS5pZ25vcmU9ZnVuY3Rpb24oKXt2YXIgdD1hcmd1bWVudHNbMF0sZT0yPD1hcmd1bWVudHMubGVuZ3RoP0IuY2FsbChhcmd1bWVudHMsMSk6W107cmV0dXJuIHEudW5zaGlmdCgiaWdub3JlIiksZT10LmFwcGx5KG51bGwsZSkscS5zaGlmdCgpLGV9LHkudHJhY2s9ZnVuY3Rpb24oKXt2YXIgdD1hcmd1bWVudHNbMF0sZT0yPD1hcmd1bWVudHMubGVuZ3RoP0IuY2FsbChhcmd1bWVudHMsMSk6W107cmV0dXJuIHEudW5zaGlmdCgidHJhY2siKSxlPXQuYXBwbHkobnVsbCxlKSxxLnNoaWZ0KCksZX0sTT1mdW5jdGlvbih0KXtpZihudWxsPT10JiYodD0iR0VUIiksInRyYWNrIj09PXFbMF0pcmV0dXJuImZvcmNlIjtpZighcS5sZW5ndGgmJlAuYWpheCl7aWYoInNvY2tldCI9PT10JiZQLmFqYXgudHJhY2tXZWJTb2NrZXRzKXJldHVybiEwO2lmKHQ9dC50b1VwcGVyQ2FzZSgpLDA8PVEuY2FsbChQLmFqYXgudHJhY2tNZXRob2RzLHQpKXJldHVybiEwfXJldHVybiExfSxLKHR0LG0pLHQ9dHQsWD1udWxsLEU9ZnVuY3Rpb24odCl7Zm9yKHZhciBlLG49UC5hamF4Lmlnbm9yZVVSTHMscj0wLHM9bi5sZW5ndGg7cjxzO3IrKylpZigic3RyaW5nIj09dHlwZW9mKGU9bltyXSkpe2lmKC0xIT09dC5pbmRleE9mKGUpKXJldHVybiEwfWVsc2UgaWYoZS50ZXN0KHQpKXJldHVybiEwO3JldHVybiExfSwoaz1mdW5jdGlvbigpe3JldHVybiBudWxsPT1YJiYoWD1uZXcgdCksWH0pKCkub24oInJlcXVlc3QiLGZ1bmN0aW9uKHQpe3ZhciBvLGk9dC50eXBlLGE9dC5yZXF1ZXN0LGU9dC51cmw7aWYoIUUoZSkpcmV0dXJuIHkucnVubmluZ3x8ITE9PT1QLnJlc3RhcnRPblJlcXVlc3RBZnRlciYmImZvcmNlIiE9PU0oaSk/dm9pZCAwOihvPWFyZ3VtZW50cywiYm9vbGVhbiI9PXR5cGVvZihlPVAucmVzdGFydE9uUmVxdWVzdEFmdGVyfHwwKSYmKGU9MCksc2V0VGltZW91dChmdW5jdGlvbigpe3ZhciB0LGUsbixyLHM9InNvY2tldCI9PT1pP2EucmVhZHlTdGF0ZTwxOjA8KHM9YS5yZWFkeVN0YXRlKSYmczw0O2lmKHMpe2Zvcih5LnJlc3RhcnQoKSxyPVtdLHQ9MCxlPShuPXkuc291cmNlcykubGVuZ3RoO3Q8ZTt0Kyspe2lmKChBPW5bdF0paW5zdGFuY2VvZiB1KXtBLndhdGNoLmFwcGx5KEEsbyk7YnJlYWt9ci5wdXNoKHZvaWQgMCl9cmV0dXJuIHJ9fSxlKSl9KSxldC5wcm90b3R5cGUud2F0Y2g9ZnVuY3Rpb24odCl7dmFyIGU9dC50eXBlLG49dC5yZXF1ZXN0LHQ9dC51cmw7aWYoIUUodCkpcmV0dXJuIG49bmV3KCJzb2NrZXQiPT09ZT9yOnMpKG4sdGhpcy5jb21wbGV0ZSksdGhpcy5lbGVtZW50cy5wdXNoKG4pfSxldC5wcm90b3R5cGUuY29tcGxldGU9ZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMuZWxlbWVudHM9dGhpcy5lbGVtZW50cy5maWx0ZXIoZnVuY3Rpb24odCl7cmV0dXJuIHQhPT1lfSl9LHU9ZXQscz1mdW5jdGlvbihlLG4pe3ZhciB0LHIscyxvLGk9dGhpcztpZih0aGlzLnByb2dyZXNzPTAsbnVsbCE9d2luZG93LlByb2dyZXNzRXZlbnQpZm9yKGEoZSwicHJvZ3Jlc3MiLGZ1bmN0aW9uKHQpe3JldHVybiB0Lmxlbmd0aENvbXB1dGFibGU/aS5wcm9ncmVzcz0xMDAqdC5sb2FkZWQvdC50b3RhbDppLnByb2dyZXNzPWkucHJvZ3Jlc3MrKDEwMC1pLnByb2dyZXNzKS8yfSksdD0wLHI9KG89WyJsb2FkIiwiYWJvcnQiLCJ0aW1lb3V0IiwiZXJyb3IiXSkubGVuZ3RoO3Q8cjt0KyspYShlLG9bdF0sZnVuY3Rpb24oKXtyZXR1cm4gbihpKSxpLnByb2dyZXNzPTEwMH0pO2Vsc2Ugcz1lLm9ucmVhZHlzdGF0ZWNoYW5nZSxlLm9ucmVhZHlzdGF0ZWNoYW5nZT1mdW5jdGlvbigpe3ZhciB0O3JldHVybiAwPT09KHQ9ZS5yZWFkeVN0YXRlKXx8ND09PXQ/KG4oaSksaS5wcm9ncmVzcz0xMDApOjM9PT1lLnJlYWR5U3RhdGUmJihpLnByb2dyZXNzPTUwKSwiZnVuY3Rpb24iPT10eXBlb2Ygcz9zLmFwcGx5KG51bGwsYXJndW1lbnRzKTp2b2lkIDB9fSxyPWZ1bmN0aW9uKHQsZSl7Zm9yKHZhciBuLHI9dGhpcyxzPXRoaXMucHJvZ3Jlc3M9MCxvPShuPVsiZXJyb3IiLCJvcGVuIl0pLmxlbmd0aDtzPG87cysrKWEodCxuW3NdLGZ1bmN0aW9uKCl7cmV0dXJuIGUociksci5wcm9ncmVzcz0xMDB9KX0sbnQucHJvdG90eXBlLmNvbXBsZXRlPWZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLmVsZW1lbnRzPXRoaXMuZWxlbWVudHMuZmlsdGVyKGZ1bmN0aW9uKHQpe3JldHVybiB0IT09ZX0pfSxHPW50LHJ0LnByb3RvdHlwZS5jaGVjaz1mdW5jdGlvbigpe3ZhciB0PXRoaXM7cmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5zZWxlY3Rvcik/dGhpcy5kb25lKCk6c2V0VGltZW91dChmdW5jdGlvbigpe3JldHVybiB0LmNoZWNrKCl9LFAuZWxlbWVudHMuY2hlY2tJbnRlcnZhbCl9LHJ0LnByb3RvdHlwZS5kb25lPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuY29tcGxldGVDYWxsYmFjayh0aGlzKSx0aGlzLmNvbXBsZXRlQ2FsbGJhY2s9bnVsbCx0aGlzLnByb2dyZXNzPTEwMH0saT1ydCxzdC5wcm90b3R5cGUuc3RhdGVzPXtsb2FkaW5nOjAsaW50ZXJhY3RpdmU6NTAsY29tcGxldGU6MTAwfSxLPXN0LG09ZnVuY3Rpb24oKXt2YXIgZSxuLHIscyxvLGk9dGhpczt0aGlzLnByb2dyZXNzPTAsbz1bXSxzPTAscj1MKCksbj1zZXRJbnRlcnZhbChmdW5jdGlvbigpe3ZhciB0PUwoKS1yLTUwO3JldHVybiByPUwoKSxvLnB1c2godCksby5sZW5ndGg+UC5ldmVudExhZy5zYW1wbGVDb3VudCYmby5zaGlmdCgpLGU9cChvKSwrK3M+PVAuZXZlbnRMYWcubWluU2FtcGxlcyYmZTxQLmV2ZW50TGFnLmxhZ1RocmVzaG9sZD8oaS5wcm9ncmVzcz0xMDAsY2xlYXJJbnRlcnZhbChuKSk6aS5wcm9ncmVzcz0zLyhlKzMpKjEwMH0sNTApfSxvdC5wcm90b3R5cGUudGljaz1mdW5jdGlvbih0LGUpe3JldHVybiBudWxsPT1lJiYoZT1SKHRoaXMuc291cmNlLCJwcm9ncmVzcyIpKSwxMDA8PWUmJih0aGlzLmRvbmU9ITApLGU9PT10aGlzLmxhc3Q/dGhpcy5zaW5jZUxhc3RVcGRhdGUrPXQ6KHRoaXMuc2luY2VMYXN0VXBkYXRlJiYodGhpcy5yYXRlPShlLXRoaXMubGFzdCkvdGhpcy5zaW5jZUxhc3RVcGRhdGUpLHRoaXMuY2F0Y2h1cD0oZS10aGlzLnByb2dyZXNzKS9QLmNhdGNodXBUaW1lLHRoaXMuc2luY2VMYXN0VXBkYXRlPTAsdGhpcy5sYXN0PWUpLGU+dGhpcy5wcm9ncmVzcyYmKHRoaXMucHJvZ3Jlc3MrPXRoaXMuY2F0Y2h1cCp0KSxlPTEtTWF0aC5wb3codGhpcy5wcm9ncmVzcy8xMDAsUC5lYXNlRmFjdG9yKSx0aGlzLnByb2dyZXNzKz1lKnRoaXMucmF0ZSp0LHRoaXMucHJvZ3Jlc3M9TWF0aC5taW4odGhpcy5sYXN0UHJvZ3Jlc3MrUC5tYXhQcm9ncmVzc1BlckZyYW1lLHRoaXMucHJvZ3Jlc3MpLHRoaXMucHJvZ3Jlc3M9TWF0aC5tYXgoMCx0aGlzLnByb2dyZXNzKSx0aGlzLnByb2dyZXNzPU1hdGgubWluKDEwMCx0aGlzLnByb2dyZXNzKSx0aGlzLmxhc3RQcm9ncmVzcz10aGlzLnByb2dyZXNzLHRoaXMucHJvZ3Jlc3N9LHY9b3QsYj1lPU49dz1PPUM9bnVsbCx5LnJ1bm5pbmc9ITEsUz1mdW5jdGlvbigpe2lmKFAucmVzdGFydE9uUHVzaFN0YXRlKXJldHVybiB5LnJlc3RhcnQoKX0sbnVsbCE9d2luZG93Lmhpc3RvcnkucHVzaFN0YXRlJiYoSD13aW5kb3cuaGlzdG9yeS5wdXNoU3RhdGUsd2luZG93Lmhpc3RvcnkucHVzaFN0YXRlPWZ1bmN0aW9uKCl7cmV0dXJuIFMoKSxILmFwcGx5KHdpbmRvdy5oaXN0b3J5LGFyZ3VtZW50cyl9KSxudWxsIT13aW5kb3cuaGlzdG9yeS5yZXBsYWNlU3RhdGUmJih6PXdpbmRvdy5oaXN0b3J5LnJlcGxhY2VTdGF0ZSx3aW5kb3cuaGlzdG9yeS5yZXBsYWNlU3RhdGU9ZnVuY3Rpb24oKXtyZXR1cm4gUygpLHouYXBwbHkod2luZG93Lmhpc3RvcnksYXJndW1lbnRzKX0pLGw9e2FqYXg6dSxlbGVtZW50czpHLGRvY3VtZW50OkssZXZlbnRMYWc6bX0sKHg9ZnVuY3Rpb24oKXt2YXIgdCxlLG4scixzLG8saSxhO2Zvcih5LnNvdXJjZXM9Qz1bXSxlPTAscj0obz1bImFqYXgiLCJlbGVtZW50cyIsImRvY3VtZW50IiwiZXZlbnRMYWciXSkubGVuZ3RoO2U8cjtlKyspITEhPT1QW3Q9b1tlXV0mJkMucHVzaChuZXcgbFt0XShQW3RdKSk7Zm9yKG49MCxzPShhPW51bGwhPShpPVAuZXh0cmFTb3VyY2VzKT9pOltdKS5sZW5ndGg7bjxzO24rKylBPWFbbl0sQy5wdXNoKG5ldyBBKFApKTtyZXR1cm4geS5iYXI9dz1uZXcgYyxPPVtdLE49bmV3IHZ9KSgpLHkuc3RvcD1mdW5jdGlvbigpe3JldHVybiB5LnRyaWdnZXIoInN0b3AiKSx5LnJ1bm5pbmc9ITEsdy5kZXN0cm95KCksYj0hMCxudWxsIT1lJiYoImZ1bmN0aW9uIj09dHlwZW9mIGgmJmgoZSksZT1udWxsKSx4KCl9LHkucmVzdGFydD1mdW5jdGlvbigpe3JldHVybiB5LnRyaWdnZXIoInJlc3RhcnQiKSx5LnN0b3AoKSx5LnN0YXJ0KCl9LHkuZ289ZnVuY3Rpb24oKXt2YXIgbTtyZXR1cm4geS5ydW5uaW5nPSEwLHcucmVuZGVyKCksbT1MKCksYj0hMSxlPWooZnVuY3Rpb24odCxlKXt3LnByb2dyZXNzO2Zvcih2YXIgbixyLHMsbyxpLGEsdSxjLGwscCxoPWE9MCxmPSEwLGQ9dT0wLGc9Qy5sZW5ndGg7dTxnO2Q9Kyt1KWZvcihBPUNbZF0saT1udWxsIT1PW2RdP09bZF06T1tkXT1bXSxzPWM9MCxsPShyPW51bGwhPShwPUEuZWxlbWVudHMpP3A6W0FdKS5sZW5ndGg7YzxsO3M9KytjKW89cltzXSxmJj0obz1udWxsIT1pW3NdP2lbc106aVtzXT1uZXcgdihvKSkuZG9uZSxvLmRvbmV8fChoKyssYSs9by50aWNrKHQpKTtyZXR1cm4gbj1hL2gsdy51cGRhdGUoTi50aWNrKHQsbikpLHcuZG9uZSgpfHxmfHxiPyh3LnVwZGF0ZSgxMDApLHkudHJpZ2dlcigiZG9uZSIpLHNldFRpbWVvdXQoZnVuY3Rpb24oKXtyZXR1cm4gdy5maW5pc2goKSx5LnJ1bm5pbmc9ITEseS50cmlnZ2VyKCJoaWRlIil9LE1hdGgubWF4KFAuZ2hvc3RUaW1lLE1hdGgubWF4KFAubWluVGltZS0oTCgpLW0pLDApKSkpOmUoKX0pfSx5LnN0YXJ0PWZ1bmN0aW9uKHQpe2QoUCx0KSx5LnJ1bm5pbmc9ITA7dHJ5e3cucmVuZGVyKCl9Y2F0Y2godCl7bj10fXJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIucGFjZSIpPyh5LnRyaWdnZXIoInN0YXJ0IikseS5nbygpKTpzZXRUaW1lb3V0KHkuc3RhcnQsNTApfSwiZnVuY3Rpb24iPT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kP2RlZmluZShmdW5jdGlvbigpe3JldHVybiB5fSk6Im9iamVjdCI9PXR5cGVvZiBleHBvcnRzP21vZHVsZS5leHBvcnRzPXk6UC5zdGFydE9uUGFnZUxvYWQmJnkuc3RhcnQoKX0pLmNhbGwodGhpcyk7"></script>37 38 <link href='data:application/manifest+json;charset=utf-8,%7B%0A%20%20%20%20%22name%22%3A%20%22VOTYMEHJONG%22%2C%0A%20%20%20%20%22short_name%22%3A%20%22VOTYMEHJONG%22%2C%0A%20%20%20%20%22lang%22%3A%20%22pt-BR%22%2C%0A%20%20%20%20%22description%22%3A%20%22VOTYMEHJONG%20ADAPT%C3%81VEL.%20APLICATIVO%20BY%20DEVELOPER%20DAVIDSONBPE.%22%2C%0A%20%20%20%20%22theme_color%22%3A%20%22%23222%22%2C%0A%20%20%20%20%22background_color%22%3A%20%22%23222%22%2C%0A%20%20%20%20%22display%22%3A%20%22standalone%22%2C%0A%20%20%20%20%22orientation%22%3A%20%22any%22%2C%0A%20%20%20%20%22start_url%22%3A%20%22https%3A%2F%2Fkexel-git.static.hf.space%2FVotyMehjong.html%3FInstalle%3Dvotymehjong%22%2C%0A%20%20%20%20%22id%22%3A%20%22votymehjong%22%2C%0A%20%20%20%20%22iarc_rating_id%22%3A%20%221455-UI88-NH10-NM36-KK89-JD12-PP23-GT20-2025%22%2C%0A%20%20%20%20%22dir%22%3A%20%22auto%22%2C%0A%20%20%20%20%22display_override%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%22standalone%22%0A%20%20%20%20%5D%2C%0A%20%20%20%20%22categories%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%22books%22%0A%20%20%20%20%5D%2C%0A%20%20%20%20%22icons%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22src%22%3A%20%22https%3A%2F%2Fplacehold.co%2F144%2F3b2d50%2Fbdbac1.png%3Ffont%3Droboto%26text%3DVOTY.MEHJONG%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22sizes%22%3A%20%22144x144%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22type%22%3A%20%22image%2Fpng%22%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22src%22%3A%20%22https%3A%2F%2Fplacehold.co%2F36%2F3b2d50%2Fbdbac1.png%3Ffont%3Droboto%26text%3DVOTY.MEHJONG%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22sizes%22%3A%20%2236x36%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22type%22%3A%20%22image%2Fpng%22%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22src%22%3A%20%22https%3A%2F%2Fplacehold.co%2F48%2F3b2d50%2Fbdbac1.png%3Ffont%3Droboto%26text%3DVOTY.MEHJONG%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22sizes%22%3A%20%2248x48%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22type%22%3A%20%22image%2Fpng%22%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22src%22%3A%20%22https%3A%2F%2Fplacehold.co%2F72%2F3b2d50%2Fbdbac1.png%3Ffont%3Droboto%26text%3DVOTY.MEHJONG%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22sizes%22%3A%20%2272x72%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22type%22%3A%20%22image%2Fpng%22%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22src%22%3A%20%22https%3A%2F%2Fplacehold.co%2F96%2F3b2d50%2Fbdbac1.png%3Ffont%3Droboto%26text%3DVOTY.MEHJONG%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22sizes%22%3A%20%2296x96%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22type%22%3A%20%22image%2Fpng%22%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22src%22%3A%20%22https%3A%2F%2Fplacehold.co%2F192%2F3b2d50%2Fbdbac1.png%3Ffont%3Droboto%26text%3DVOTY.MEHJONG%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22sizes%22%3A%20%22192x192%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22type%22%3A%20%22image%2Fpng%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22purpose%22%3A%20%22any%20maskable%20monochrome%22%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22src%22%3A%20%22https%3A%2F%2Fplacehold.co%2F512%2F3b2d50%2Fbdbac1.png%3Ffont%3Droboto%26text%3DVOTY.MEHJONG%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22sizes%22%3A%20%22512x512%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22type%22%3A%20%22image%2Fpng%22%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%5D%2C%0A%20%20%20%20%22screenshots%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22src%22%3A%20%22https%3A%2F%2Fplacehold.co%2F512%2F3b2d50%2Fbdbac1.png%3Ffont%3Droboto%26text%3DVOTY.MEHJONG%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22sizes%22%3A%20%22512x512%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22type%22%3A%20%22image%2Fpng%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22platform%22%3A%20%22wide%22%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%5D%0A%7D' rel='manifest'/>39 <script> if (navigator.serviceWorker) { navigator.serviceWorker.register } </script>40 41 <script src="https://cdn.jsdelivr.net/gh/davserv/d-framework@refs/heads/cdn.tailwindcss/tailwindcss.js"></script>42 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6/css/all.min.css"/>43 <style>44 @keyframes tileHover {45 0% { transform: translateY(0); }46 50% { transform: translateY(-5px); }47 100% { transform: translateY(0); }48 }49 50 .tile-hover:hover {51 animation: tileHover 0.3s ease;52 transform: translateY(-5px);53 box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.2);54 }55 56 .tile-selected {57 transform: translateY(-15px);58 box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.2);59 z-index: 10;60 }61 62 .tile-matched {63 animation: fadeOut 0.5s ease forwards;64 }65 66 @keyframes fadeOut {67 to {68 opacity: 0;69 transform: scale(0.8);70 }71 }72 73 .board-container {74 perspective: 1000px;75 }76 77 .tile {78 transition: all 0.3s ease;79 transform-style: preserve-3d;80 }81 82 .tile-inner {83 position: relative;84 width: 100%;85 height: 100%;86 transform-style: preserve-3d;87 }88 89 .tile-front, .tile-back {90 position: absolute;91 width: 100%;92 height: 100%;93 backface-visibility: hidden;94 border-radius: 8px;95 display: flex;96 align-items: center;97 justify-content: center;98 }99 100 .tile-front {101 background: linear-gradient(145deg, #f0f0f0, #ffffff);102 transform: rotateY(180deg);103 }104 105 .tile-back {106 background: linear-gradient(145deg, #4f46e5, #7c3aed);107 color: white;108 }109 110 .flipped {111 transform: rotateY(180deg);112 }113 114 .level-complete {115 animation: pulse 2s infinite;116 }117 118 @keyframes pulse {119 0% { transform: scale(1); }120 50% { transform: scale(1.05); }121 100% { transform: scale(1); }122 }123 124 /* Mobile-specific styles */125 @media (max-width: 640px) {126 .tile-front span, .tile-back i {127 font-size: 50px !important;128 }129 130 .header-container {131 flex-direction: column;132 align-items: center;133 gap: 1rem;134 }135 136 .stats-container {137 width: 100%;138 justify-content: space-between;139 }140 141 .controls-container {142 flex-direction: column;143 gap: 0.5rem;144 }145 146 .controls-container > div {147 width: 100%;148 }149 150 .controls-container button {151 width: 100%;152 padding: 0.5rem;153 }154 155 .modal-content {156 width: 90%;157 padding: 1.5rem;158 }159 }160 .text-mtg{161 font-size: 50px !important;162 }163 </style>164</head>165<body class="bg-gray-100 min-h-screen font-sans">166 <div class="container mx-auto px-2 sm:px-4 py-4 sm:py-8">167 <!-- Header - Made responsive with flex column on mobile -->168 <header class="header-container flex flex-col sm:flex-row justify-between items-center mb-4 sm:mb-8">169 <div class="flex items-center mb-2 sm:mb-0">170 <i class="fa-brands fa-fort-awesome text-3xl sm:text-4xl text-purple-600 mr-2 sm:mr-3"></i>171 <h1 class="text-2xl sm:text-3xl font-bold text-gray-800 uppercase">Voty Mehjong</h1>172 </div>173 <div class="stats-container flex items-center space-x-2 sm:space-x-4 w-full sm:w-auto justify-center sm:justify-start">174 <div class="bg-white rounded-lg shadow p-2 sm:p-3 flex items-center text-sm sm:text-base">175 <i class="fas fa-clock text-purple-600 mr-1 sm:mr-2 text-sm sm:text-base"></i>176 <span id="timer" class="font-bold">00:00</span>177 </div>178 <div class="bg-white rounded-lg shadow p-2 sm:p-3 flex items-center text-sm sm:text-base">179 <i class="fas fa-layer-group text-purple-600 mr-1 sm:mr-2 text-sm sm:text-base"></i>180 <span id="level" class="font-bold">Level 1</span>181 </div>182 <div class="bg-white rounded-lg shadow p-2 sm:p-3 flex items-center text-sm sm:text-base">183 <i class="fas fa-star text-yellow-500 mr-1 sm:mr-2 text-sm sm:text-base"></i>184 <span id="score" class="font-bold">0</span>185 </div>186 </div>187 </header>188 189 <!-- Game Controls - Stacked vertically on mobile -->190 <div class="controls-container flex flex-col sm:flex-row justify-between mb-4 sm:mb-6">191 <div class="flex space-x-2 sm:space-x-3 mb-2 sm:mb-0">192 <button id="new-game" class="bg-purple-600 hover:bg-purple-700 text-white px-3 sm:px-4 py-1 sm:py-2 rounded-lg shadow flex items-center text-sm sm:text-base">193 <i class="fas fa-plus-circle mr-1 sm:mr-2"></i> New Game194 </button>195 <button id="hint" class="bg-amber-500 hover:bg-amber-600 text-white px-3 sm:px-4 py-1 sm:py-2 rounded-lg shadow flex items-center text-sm sm:text-base">196 <i class="fas fa-lightbulb mr-1 sm:mr-2"></i> Hint197 </button>198 </div>199 <div>200 <button id="sound-toggle" class="bg-gray-200 hover:bg-gray-300 text-gray-800 px-3 sm:px-4 py-1 sm:py-2 rounded-lg shadow flex items-center text-sm sm:text-base">201 <i class="fas fa-volume-up mr-1 sm:mr-2"></i> Sound On202 </button>203 </div>204 </div>205 206 <!-- Game Board - Responsive grid with smaller tiles on mobile -->207 <div class="board-container bg-white rounded-xl shadow-xl p-3 sm:p-6 mb-4 sm:mb-6 overflow-auto">208 <div id="board" class="grid grid-cols-4 sm:grid-cols-6 md:grid-cols-8 gap-2 sm:gap-3 mx-auto"></div>209 </div>210 211 <!-- Game Status -->212 <div id="game-status" class="text-center mb-4 sm:mb-6 hidden">213 <div class="inline-block bg-green-100 border-l-4 border-green-500 text-green-700 p-3 sm:p-4 rounded-lg text-sm sm:text-base">214 <p class="font-bold">Level Complete!</p>215 </div>216 </div>217 218 <!-- Level Complete Modal - Responsive sizing -->219 <div id="level-complete-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50 p-2 sm:p-4">220 <div class="modal-content bg-white rounded-xl shadow-2xl p-4 sm:p-8 w-full max-w-sm sm:max-w-md level-complete">221 <div class="text-center">222 <div class="text-4xl sm:text-6xl text-yellow-500 mb-2 sm:mb-4">223 <i class="fas fa-trophy"></i>224 </div>225 <h2 class="text-xl sm:text-3xl font-bold text-gray-800 mb-1 sm:mb-2">Level Complete!</h2>226 <p class="text-sm sm:text-base text-gray-600 mb-4 sm:mb-6">Great job! Ready for the next challenge?</p>227 <div class="grid grid-cols-2 gap-2 sm:gap-4 mb-4 sm:mb-6">228 <div class="bg-purple-50 rounded-lg p-2 sm:p-3">229 <p class="text-xs sm:text-sm text-purple-600">Time</p>230 <p id="level-time" class="font-bold text-lg sm:text-xl">00:45</p>231 </div>232 <div class="bg-purple-50 rounded-lg p-2 sm:p-3">233 <p class="text-xs sm:text-sm text-purple-600">Score</p>234 <p id="level-score" class="font-bold text-lg sm:text-xl">+250</p>235 </div>236 </div>237 <button id="next-level" class="w-full bg-purple-600 hover:bg-purple-700 text-white py-2 sm:py-3 rounded-lg shadow-lg font-bold text-sm sm:text-base">238 Next Level <i class="fas fa-arrow-right ml-1 sm:ml-2"></i>239 </button>240 </div>241 </div>242 </div>243 244 <!-- Game Over Modal - Responsive sizing -->245 <div id="game-over-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50 p-2 sm:p-4">246 <div class="modal-content bg-white rounded-xl shadow-2xl p-4 sm:p-8 w-full max-w-sm sm:max-w-md">247 <div class="text-center">248 <div class="text-4xl sm:text-6xl text-red-500 mb-2 sm:mb-4">249 <i class="fas fa-gamepad"></i>250 </div>251 <h2 class="text-xl sm:text-3xl font-bold text-gray-800 mb-1 sm:mb-2">Game Over</h2>252 <p class="text-sm sm:text-base text-gray-600 mb-4 sm:mb-6">Better luck next time!</p>253 <div class="grid grid-cols-2 gap-2 sm:gap-4 mb-4 sm:mb-6">254 <div class="bg-purple-50 rounded-lg p-2 sm:p-3">255 <p class="text-xs sm:text-sm text-purple-600">Level Reached</p>256 <p id="final-level" class="font-bold text-lg sm:text-xl">3</p>257 </div>258 <div class="bg-purple-50 rounded-lg p-2 sm:p-3">259 <p class="text-xs sm:text-sm text-purple-600">Total Score</p>260 <p id="final-score" class="font-bold text-lg sm:text-xl">750</p>261 </div>262 </div>263 <button id="play-again" class="w-full bg-purple-600 hover:bg-purple-700 text-white py-2 sm:py-3 rounded-lg shadow-lg font-bold text-sm sm:text-base">264 Play Again <i class="fas fa-redo ml-1 sm:ml-2"></i>265 </button>266 </div>267 </div>268 </div>269 </div>270 271 <!-- Audio elements for sound effects -->272 <audio id="flip-sound" src="https://kexel-git.static.hf.space/gsom/zapsplat_multimedia_button_click.mp3" preload="auto"></audio>273 <audio id="match-sound" src="https://kexel-git.static.hf.space/gsom/positive-beeps.mp3" preload="auto"></audio>274 <audio id="mismatch-sound" src="https://kexel-git.static.hf.space/gsom/mixkit-quick-jump-arcade-game-239.mp3" preload="auto"></audio>275 <audio id="hint-sound" src="https://kexel-git.static.hf.space/gsom/unlock-game-notification.mp3" preload="auto"></audio>276 <audio id="level-complete-sound" src="https://kexel-git.static.hf.space/gsom/2015-preview.mp3" preload="auto"></audio>277 <audio id="game-over-sound" src="https://kexel-git.static.hf.space/gsom/2027-preview.mp3" preload="auto"></audio>278 <audio id="button-click-sound" src="https://kexel-git.static.hf.space/gsom/mixkit-mouse-click-close-1113.mp3" preload="auto"></audio>279 280 <script>281 document.addEventListener('DOMContentLoaded', () => {282 // Game state283 const state = {284 board: [],285 level: 1,286 score: 0,287 time: 0,288 timerInterval: null,289 selectedTiles: [],290 matchedPairs: 0,291 totalPairs: 0,292 soundEnabled: true,293 gameActive: false,294 isMobile: window.innerWidth < 640 // Check if mobile device295 };296 297 // Audio elements298 const flipSound = document.getElementById('flip-sound');299 const matchSound = document.getElementById('match-sound');300 const mismatchSound = document.getElementById('mismatch-sound');301 const hintSound = document.getElementById('hint-sound');302 const levelCompleteSound = document.getElementById('level-complete-sound');303 const gameOverSound = document.getElementById('game-over-sound');304 const buttonClickSound = document.getElementById('button-click-sound');305 306 // DOM elements307 const boardElement = document.getElementById('board');308 const timerElement = document.getElementById('timer');309 const levelElement = document.getElementById('level');310 const scoreElement = document.getElementById('score');311 const newGameButton = document.getElementById('new-game');312 const hintButton = document.getElementById('hint');313 const soundToggleButton = document.getElementById('sound-toggle');314 const gameStatusElement = document.getElementById('game-status');315 const levelCompleteModal = document.getElementById('level-complete-modal');316 const gameOverModal = document.getElementById('game-over-modal');317 const nextLevelButton = document.getElementById('next-level');318 const playAgainButton = document.getElementById('play-again');319 const levelTimeElement = document.getElementById('level-time');320 const levelScoreElement = document.getElementById('level-score');321 const finalLevelElement = document.getElementById('final-level');322 const finalScoreElement = document.getElementById('final-score');323 324 // Tile types (Vita Mahjong style)325 const tileTypes = [326 '1m', '2m', '3m', '4m', '5m', '6m', '7m', '8m', '9m', // Characters327 '1s', '2s', '3s', '4s', '5s', '6s', '7s', '8s', '9s', // Bamboo328 '1p', '2p', '3p', '4p', '5p', '6p', '7p', '8p', '9p', // Circles329 'ew', 'sw', 'ww', 'nw', // Winds330 'wd', 'gd', 'rd' // Dragons331 ];332 333 // Initialize game334 function initGame() {335 state.level = 1;336 state.score = 0;337 state.time = 0;338 state.matchedPairs = 0;339 state.gameActive = true;340 341 clearInterval(state.timerInterval);342 startTimer();343 344 updateUI();345 createBoard();346 347 // Play button click sound348 playSound('button-click');349 }350 351 // Create game board based on current level352 function createBoard() {353 boardElement.innerHTML = '';354 state.board = [];355 state.selectedTiles = [];356 state.matchedPairs = 0;357 358 // Determine number of pairs based on level and screen size359 const basePairs = state.isMobile ? 2 : 4;360 const pairs = Math.min(basePairs + state.level, state.isMobile ? 12 : 32);361 state.totalPairs = pairs;362 363 // Create array of tile pairs364 let tiles = [];365 const availableTypes = [...tileTypes].sort(() => 0.5 - Math.random()).slice(0, pairs);366 367 availableTypes.forEach(type => {368 tiles.push(type, type);369 });370 371 // Shuffle tiles372 tiles = shuffleArray(tiles);373 374 // Determine grid columns based on screen size375 const cols = state.isMobile ? 4 : (window.innerWidth < 768 ? 6 : 8);376 const rows = Math.ceil(tiles.length / cols);377 378 for (let i = 0; i < rows; i++) {379 const row = [];380 for (let j = 0; j < cols; j++) {381 const index = i * cols + j;382 if (index < tiles.length) {383 row.push({384 type: tiles[index],385 flipped: false,386 matched: false,387 row: i,388 col: j389 });390 } else {391 row.push(null); // Empty slot for uneven boards392 }393 }394 state.board.push(row);395 }396 397 // Render tiles398 renderBoard();399 }400 401 // Render the game board402 function renderBoard() {403 boardElement.innerHTML = '';404 405 // Calculate grid columns based on screen size406 const cols = state.isMobile ? 4 : (window.innerWidth < 768 ? 6 : 8);407 boardElement.className = `grid gap-2 sm:gap-3 mx-auto`;408 boardElement.style.gridTemplateColumns = `repeat(${cols}, minmax(0, 1fr))`;409 410 state.board.forEach((row, rowIndex) => {411 row.forEach((tile, colIndex) => {412 if (!tile) return;413 414 const tileElement = document.createElement('div');415 tileElement.className = `tile aspect-square cursor-pointer transition-all duration-300 ${tile.matched ? 'opacity-0' : ''}`;416 417 tileElement.innerHTML = `418 <div class="border-t-2 border-r-2 border-indigo-500/50 border-l-8 border-b-8 tile-inner ${419 tile.flipped ? "flipped" : ""420 }">421 <div class="rounded-none tile-back flex items-center justify-center">422 <i class="fa-brands fa-fort-awesome text-sm sm:text-5xl"></i>423 </div>424 <div class="tile-front">425 <span class="text-xl sm:text-4xl font-bold">${getTileSymbol(426 tile.type427 )}</span>428 </div>429 </div>430 `;431 432 tileElement.addEventListener('click', () => handleTileClick(tile));433 434 if (!tile.matched) {435 tileElement.classList.add('tile-hover');436 }437 438 boardElement.appendChild(tileElement);439 });440 });441 }442 443 // Handle tile click444 function handleTileClick(tile) {445 if (!state.gameActive || tile.matched || tile.flipped || state.selectedTiles.length >= 2) {446 return;447 }448 449 // Flip the tile450 tile.flipped = true;451 state.selectedTiles.push(tile);452 453 // Play sound454 playSound('flip');455 456 renderBoard();457 458 // Check for match if two tiles are selected459 if (state.selectedTiles.length === 2) {460 const [tile1, tile2] = state.selectedTiles;461 462 if (tile1.type === tile2.type) {463 // Match found464 tile1.matched = true;465 tile2.matched = true;466 state.matchedPairs++;467 state.score += 50 * state.level;468 469 // Play success sound470 playSound('match');471 472 // Check if level is complete473 if (state.matchedPairs === state.totalPairs) {474 levelComplete();475 }476 477 // Clear selection after delay478 setTimeout(() => {479 state.selectedTiles = [];480 renderBoard();481 }, 500);482 } else {483 // No match484 setTimeout(() => {485 tile1.flipped = false;486 tile2.flipped = false;487 state.selectedTiles = [];488 renderBoard();489 490 // Play mismatch sound491 playSound('mismatch');492 }, 1000);493 }494 }495 496 updateUI();497 }498 499 // Level complete500 function levelComplete() {501 state.gameActive = false;502 clearInterval(state.timerInterval);503 504 // Calculate bonus points based on time505 const timeBonus = Math.max(0, 300 - state.time);506 state.score += timeBonus;507 508 // Show level complete modal509 levelTimeElement.textContent = formatTime(state.time);510 levelScoreElement.textContent = `+${timeBonus}`;511 levelCompleteModal.classList.remove('hidden');512 513 // Play level complete sound514 playSound('level-complete');515 516 updateUI();517 }518 519 // Next level520 function nextLevel() {521 playSound('button-click');522 523 state.level++;524 state.time = 0;525 state.gameActive = true;526 527 levelCompleteModal.classList.add('hidden');528 startTimer();529 createBoard();530 updateUI();531 532 // Show level up message533 gameStatusElement.classList.remove('hidden');534 gameStatusElement.querySelector('p').textContent = `Level ${state.level}!`;535 536 setTimeout(() => {537 gameStatusElement.classList.add('hidden');538 }, 2000);539 }540 541 // Game over542 function gameOver() {543 state.gameActive = false;544 clearInterval(state.timerInterval);545 546 // Update final stats547 finalLevelElement.textContent = state.level;548 finalScoreElement.textContent = state.score;549 550 // Show game over modal551 gameOverModal.classList.remove('hidden');552 553 // Play game over sound554 playSound('game-over');555 }556 557 // Start timer558 function startTimer() {559 state.time = 0;560 updateTimerDisplay();561 562 state.timerInterval = setInterval(() => {563 state.time++;564 updateTimerDisplay();565 566 // Game over if time exceeds limit (5 minutes)567 if (state.time >= 300) {568 gameOver();569 }570 }, 1000);571 }572 573 // Update timer display574 function updateTimerDisplay() {575 timerElement.textContent = formatTime(state.time);576 }577 578 // Format time as MM:SS579 function formatTime(seconds) {580 const mins = Math.floor(seconds / 60).toString().padStart(2, '0');581 const secs = (seconds % 60).toString().padStart(2, '0');582 return `${mins}:${secs}`;583 }584 585 // Update UI elements586 function updateUI() {587 levelElement.textContent = `Level ${state.level}`;588 scoreElement.textContent = state.score;589 }590 591 // Get tile symbol for display592 function getTileSymbol(type) {593 const symbols = {594 '1m': '一', '2m': '二', '3m': '三', '4m': '四', '5m': '五',595 '6m': '六', '7m': '七', '8m': '八', '9m': '九',596 '1s': '1', '2s': '2', '3s': '3', '4s': '4', '5s': '5',597 '6s': '6', '7s': '7', '8s': '8', '9s': '9',598 '1p': '❶', '2p': '❷', '3p': '❸', '4p': '❹', '5p': '❺',599 '6p': '❻', '7p': '❼', '8p': '❽', '9p': '❾',600 'ew': '東', 'sw': '南', 'ww': '西', 'nw': '北',601 'wd': '白', 'gd': '發', 'rd': '中'602 };603 return symbols[type] || type;604 }605 606 // Shuffle array607 function shuffleArray(array) {608 const newArray = [...array];609 for (let i = newArray.length - 1; i > 0; i--) {610 const j = Math.floor(Math.random() * (i + 1));611 [newArray[i], newArray[j]] = [newArray[j], newArray[i]];612 }613 return newArray;614 }615 616 // Play sound617 function playSound(type) {618 if (!state.soundEnabled) return;619 620 try {621 switch (type) {622 case 'flip':623 flipSound.currentTime = 0;624 flipSound.play();625 break;626 case 'match':627 matchSound.currentTime = 0;628 matchSound.play();629 break;630 case 'mismatch':631 mismatchSound.currentTime = 0;632 mismatchSound.play();633 break;634 case 'hint':635 hintSound.currentTime = 0;636 hintSound.play();637 break;638 case 'level-complete':639 levelCompleteSound.currentTime = 0;640 levelCompleteSound.play();641 break;642 case 'game-over':643 gameOverSound.currentTime = 0;644 gameOverSound.play();645 break;646 case 'button-click':647 buttonClickSound.currentTime = 0;648 buttonClickSound.play();649 break;650 }651 } catch (e) {652 console.error('Error playing sound:', e);653 }654 }655 656 // Provide hint657 function provideHint() {658 if (!state.gameActive || state.matchedPairs === state.totalPairs) {659 return;660 }661 662 // Play button click sound663 playSound('button-click');664 665 // Find all unflipped, unmatched tiles666 const unflippedTiles = [];667 state.board.forEach(row => {668 row.forEach(tile => {669 if (tile && !tile.flipped && !tile.matched) {670 unflippedTiles.push(tile);671 }672 });673 });674 675 if (unflippedTiles.length < 2) return;676 677 // Find a matching pair678 const tileCount = {};679 let hintTile1 = null;680 let hintTile2 = null;681 682 for (const tile of unflippedTiles) {683 if (tileCount[tile.type]) {684 hintTile1 = tileCount[tile.type];685 hintTile2 = tile;686 break;687 }688 tileCount[tile.type] = tile;689 }690 691 if (hintTile1 && hintTile2) {692 // Highlight the hint tiles693 const tileElements = boardElement.querySelectorAll('.tile');694 695 tileElements.forEach((element, index) => {696 const cols = state.isMobile ? 4 : (window.innerWidth < 768 ? 6 : 8);697 const row = Math.floor(index / cols);698 const col = index % cols;699 const tile = state.board[row]?.[col];700 701 if (tile === hintTile1 || tile === hintTile2) {702 element.classList.add('ring-4', 'ring-yellow-400', 'ring-opacity-75');703 704 // Remove highlight after delay705 setTimeout(() => {706 element.classList.remove('ring-4', 'ring-yellow-400', 'ring-opacity-75');707 }, 2000);708 }709 });710 711 // Deduct points for using hint712 state.score = Math.max(0, state.score - 25);713 updateUI();714 715 // Play hint sound716 playSound('hint');717 }718 }719 720 // Event listeners721 newGameButton.addEventListener('click', initGame);722 hintButton.addEventListener('click', provideHint);723 soundToggleButton.addEventListener('click', () => {724 state.soundEnabled = !state.soundEnabled;725 soundToggleButton.innerHTML = state.soundEnabled 726 ? '<i class="fas fa-volume-up mr-1 sm:mr-2"></i> Sound On' 727 : '<i class="fas fa-volume-mute mr-1 sm:mr-2"></i> Sound Off';728 playSound('button-click');729 });730 nextLevelButton.addEventListener('click', nextLevel);731 playAgainButton.addEventListener('click', () => {732 playSound('button-click');733 gameOverModal.classList.add('hidden');734 initGame();735 });736 737 // Handle window resize738 window.addEventListener('resize', () => {739 state.isMobile = window.innerWidth < 640;740 if (state.gameActive) {741 createBoard();742 }743 });744 745 // Initialize the game746 initGame();747 });748 </script>749</body>750</html>751 752 753<!--<!DOCTYPE html>754<html lang="en">755<head>756 <meta charset="UTF-8">757 <meta name="viewport" content="width=device-width, initial-scale=1.0">758 <title>Vita Mahjong</title>759 <script src="https://cdn.tailwindcss.com"></script>760 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">761 <style>762 @keyframes tileHover {763 0% { transform: translateY(0); }764 50% { transform: translateY(-5px); }765 100% { transform: translateY(0); }766 }767 768 .tile-hover:hover {769 animation: tileHover 0.3s ease;770 transform: translateY(-5px);771 box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.2);772 }773 774 .tile-selected {775 transform: translateY(-15px);776 box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.2);777 z-index: 10;778 }779 780 .tile-matched {781 animation: fadeOut 0.5s ease forwards;782 }783 784 @keyframes fadeOut {785 to {786 opacity: 0;787 transform: scale(0.8);788 }789 }790 791 .board-container {792 perspective: 1000px;793 }794 795 .tile {796 transition: all 0.3s ease;797 transform-style: preserve-3d;798 }799 800 .tile-inner {801 position: relative;802 width: 100%;803 height: 100%;804 transform-style: preserve-3d;805 }806 807 .tile-front, .tile-back {808 position: absolute;809 width: 100%;810 height: 100%;811 backface-visibility: hidden;812 border-radius: 8px;813 display: flex;814 align-items: center;815 justify-content: center;816 }817 818 .tile-front {819 background: linear-gradient(145deg, #f0f0f0, #ffffff);820 transform: rotateY(180deg);821 }822 823 .tile-back {824 background: linear-gradient(145deg, #4f46e5, #7c3aed);825 color: white;826 }827 828 .flipped {829 transform: rotateY(180deg);830 }831 832 .level-complete {833 animation: pulse 2s infinite;834 }835 836 @keyframes pulse {837 0% { transform: scale(1); }838 50% { transform: scale(1.05); }839 100% { transform: scale(1); }840 }841 </style>842</head>843<body class="bg-gray-100 min-h-screen font-sans">844 <div class="container mx-auto px-4 py-8">845 846 <header class="flex justify-between items-center mb-8">847 <div class="flex items-center">848 <i class="fas fa-dragon text-4xl text-purple-600 mr-3"></i>849 <h1 class="text-3xl font-bold text-gray-800">Vita Mahjong</h1>850 </div>851 <div class="flex items-center space-x-4">852 <div class="bg-white rounded-lg shadow p-3 flex items-center">853 <i class="fas fa-clock text-purple-600 mr-2"></i>854 <span id="timer" class="font-bold">00:00</span>855 </div>856 <div class="bg-white rounded-lg shadow p-3 flex items-center">857 <i class="fas fa-layer-group text-purple-600 mr-2"></i>858 <span id="level" class="font-bold">Level 1</span>859 </div>860 <div class="bg-white rounded-lg shadow p-3 flex items-center">861 <i class="fas fa-star text-yellow-500 mr-2"></i>862 <span id="score" class="font-bold">0</span>863 </div>864 </div>865 </header>866 867 868 <div class="flex justify-between mb-6">869 <div class="flex space-x-3">870 <button id="new-game" class="bg-purple-600 hover:bg-purple-700 text-white px-4 py-2 rounded-lg shadow flex items-center">871 <i class="fas fa-plus-circle mr-2"></i> New Game872 </button>873 <button id="hint" class="bg-amber-500 hover:bg-amber-600 text-white px-4 py-2 rounded-lg shadow flex items-center">874 <i class="fas fa-lightbulb mr-2"></i> Hint875 </button>876 </div>877 <div>878 <button id="sound-toggle" class="bg-gray-200 hover:bg-gray-300 text-gray-800 px-4 py-2 rounded-lg shadow flex items-center">879 <i class="fas fa-volume-up mr-2"></i> Sound On880 </button>881 </div>882 </div>883 884 885 <div class="board-container bg-white rounded-xl shadow-xl p-6 mb-6">886 <div id="board" class="grid grid-cols-8 gap-3 mx-auto"></div>887 </div>888 889 890 <div id="game-status" class="text-center mb-6 hidden">891 <div class="inline-block bg-green-100 border-l-4 border-green-500 text-green-700 p-4 rounded-lg">892 <p class="font-bold">Level Complete!</p>893 </div>894 </div>895 896 897 <div id="level-complete-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50">898 <div class="bg-white rounded-xl shadow-2xl p-8 max-w-md w-full level-complete">899 <div class="text-center">900 <div class="text-6xl text-yellow-500 mb-4">901 <i class="fas fa-trophy"></i>902 </div>903 <h2 class="text-3xl font-bold text-gray-800 mb-2">Level Complete!</h2>904 <p class="text-gray-600 mb-6">Great job! Ready for the next challenge?</p>905 <div class="grid grid-cols-2 gap-4 mb-6">906 <div class="bg-purple-50 rounded-lg p-3">907 <p class="text-sm text-purple-600">Time</p>908 <p id="level-time" class="font-bold text-xl">00:45</p>909 </div>910 <div class="bg-purple-50 rounded-lg p-3">911 <p class="text-sm text-purple-600">Score</p>912 <p id="level-score" class="font-bold text-xl">+250</p>913 </div>914 </div>915 <button id="next-level" class="w-full bg-purple-600 hover:bg-purple-700 text-white py-3 rounded-lg shadow-lg font-bold">916 Next Level <i class="fas fa-arrow-right ml-2"></i>917 </button>918 </div>919 </div>920 </div>921 922 923 <div id="game-over-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50">924 <div class="bg-white rounded-xl shadow-2xl p-8 max-w-md w-full">925 <div class="text-center">926 <div class="text-6xl text-red-500 mb-4">927 <i class="fas fa-gamepad"></i>928 </div>929 <h2 class="text-3xl font-bold text-gray-800 mb-2">Game Over</h2>930 <p class="text-gray-600 mb-6">Better luck next time!</p>931 <div class="grid grid-cols-2 gap-4 mb-6">932 <div class="bg-purple-50 rounded-lg p-3">933 <p class="text-sm text-purple-600">Level Reached</p>934 <p id="final-level" class="font-bold text-xl">3</p>935 </div>936 <div class="bg-purple-50 rounded-lg p-3">937 <p class="text-sm text-purple-600">Total Score</p>938 <p id="final-score" class="font-bold text-xl">750</p>939 </div>940 </div>941 <button id="play-again" class="w-full bg-purple-600 hover:bg-purple-700 text-white py-3 rounded-lg shadow-lg font-bold">942 Play Again <i class="fas fa-redo ml-2"></i>943 </button>944 </div>945 </div>946 </div>947 </div>948 949 950 <audio id="flip-sound" src="https://kexel-git.static.hf.space/gsom/zapsplat_multimedia_button_click.mp3" preload="auto"></audio>951 <audio id="match-sound" src="https://kexel-git.static.hf.space/gsom/positive-beeps.mp3" preload="auto"></audio>952 <audio id="mismatch-sound" src="https://kexel-git.static.hf.space/gsom/mixkit-quick-jump-arcade-game-239.mp3" preload="auto"></audio>953 <audio id="hint-sound" src="https://kexel-git.static.hf.space/gsom/unlock-game-notification.mp3" preload="auto"></audio>954 955 <audio id="level-complete-sound" src="https://kexel-git.static.hf.space/gsom/2015-preview.mp3" preload="auto"></audio>956 <audio id="game-over-sound" src="https://kexel-git.static.hf.space/gsom/2027-preview.mp3" preload="auto"></audio>957 <audio id="button-click-sound" src="https://kexel-git.static.hf.space/gsom/mixkit-mouse-click-close-1113.mp3" preload="auto"></audio>958 959 <script>960 document.addEventListener('DOMContentLoaded', () => {961 // Game state962 const state = {963 board: [],964 level: 1,965 score: 0,966 time: 0,967 timerInterval: null,968 selectedTiles: [],969 matchedPairs: 0,970 totalPairs: 0,971 soundEnabled: true,972 gameActive: false973 };974 975 // Audio elements976 const flipSound = document.getElementById('flip-sound');977 const matchSound = document.getElementById('match-sound');978 const mismatchSound = document.getElementById('mismatch-sound');979 const hintSound = document.getElementById('hint-sound');980 const levelCompleteSound = document.getElementById('level-complete-sound');981 const gameOverSound = document.getElementById('game-over-sound');982 const buttonClickSound = document.getElementById('button-click-sound');983 984 // DOM elements985 const boardElement = document.getElementById('board');986 const timerElement = document.getElementById('timer');987 const levelElement = document.getElementById('level');988 const scoreElement = document.getElementById('score');989 const newGameButton = document.getElementById('new-game');990 const hintButton = document.getElementById('hint');991 const soundToggleButton = document.getElementById('sound-toggle');992 const gameStatusElement = document.getElementById('game-status');993 const levelCompleteModal = document.getElementById('level-complete-modal');994 const gameOverModal = document.getElementById('game-over-modal');995 const nextLevelButton = document.getElementById('next-level');996 const playAgainButton = document.getElementById('play-again');997 const levelTimeElement = document.getElementById('level-time');998 const levelScoreElement = document.getElementById('level-score');999 const finalLevelElement = document.getElementById('final-level');1000 const finalScoreElement = document.getElementById('final-score');1001 1002 // Tile types (Vita Mahjong style)1003 const tileTypes = [1004 '1m', '2m', '3m', '4m', '5m', '6m', '7m', '8m', '9m', // Characters1005 '1s', '2s', '3s', '4s', '5s', '6s', '7s', '8s', '9s', // Bamboo1006 '1p', '2p', '3p', '4p', '5p', '6p', '7p', '8p', '9p', // Circles1007 'ew', 'sw', 'ww', 'nw', // Winds1008 'wd', 'gd', 'rd' // Dragons1009 ];1010 1011 // Initialize game1012 function initGame() {1013 state.level = 1;1014 state.score = 0;1015 state.time = 0;1016 state.matchedPairs = 0;1017 state.gameActive = true;1018 1019 clearInterval(state.timerInterval);1020 startTimer();1021 1022 updateUI();1023 createBoard();1024 1025 // Play button click sound1026 playSound('button-click');1027 }1028 1029 // Create game board based on current level1030 function createBoard() {1031 boardElement.innerHTML = '';1032 state.board = [];1033 state.selectedTiles = [];1034 state.matchedPairs = 0;1035 1036 // Determine number of pairs based on level1037 const pairs = Math.min(4 + state.level, 32); // Max 32 pairs (64 tiles)1038 state.totalPairs = pairs;1039 1040 // Create array of tile pairs1041 let tiles = [];1042 const availableTypes = [...tileTypes].sort(() => 0.5 - Math.random()).slice(0, pairs);1043 1044 availableTypes.forEach(type => {1045 tiles.push(type, type);1046 });1047 1048 // Shuffle tiles1049 tiles = shuffleArray(tiles);1050 1051 // Create board matrix (8 columns, rows as needed)1052 const cols = 8;1053 const rows = Math.ceil(tiles.length / cols);1054 1055 for (let i = 0; i < rows; i++) {1056 const row = [];1057 for (let j = 0; j < cols; j++) {1058 const index = i * cols + j;1059 if (index < tiles.length) {1060 row.push({1061 type: tiles[index],1062 flipped: false,1063 matched: false,1064 row: i,1065 col: j1066 });1067 } else {1068 row.push(null); // Empty slot for uneven boards1069 }1070 }1071 state.board.push(row);1072 }1073 1074 // Render tiles1075 renderBoard();1076 }1077 1078 // Render the game board1079 function renderBoard() {1080 boardElement.innerHTML = '';1081 1082 // Calculate grid rows based on board rows1083 boardElement.className = `grid gap-3 mx-auto`;1084 boardElement.style.gridTemplateColumns = `repeat(8, minmax(0, 1fr))`;1085 1086 state.board.forEach((row, rowIndex) => {1087 row.forEach((tile, colIndex) => {1088 if (!tile) return;1089 1090 const tileElement = document.createElement('div');1091 tileElement.className = `tile aspect-square cursor-pointer transition-all duration-300 ${tile.matched ? 'opacity-0' : ''}`;1092 1093 tileElement.innerHTML = `1094 <div class="tile-inner ${tile.flipped ? 'flipped' : ''}">1095 <div class="tile-back flex items-center justify-center">1096 <i class="fas fa-dragon text-2xl"></i>1097 </div>1098 <div class="tile-front">1099 <span class="text-3xl font-bold">${getTileSymbol(tile.type)}</span>1100 </div>1101 </div>1102 `;1103 1104 tileElement.addEventListener('click', () => handleTileClick(tile));1105 1106 if (!tile.matched) {1107 tileElement.classList.add('tile-hover');1108 }1109 1110 boardElement.appendChild(tileElement);1111 });1112 });1113 }1114 1115 // Handle tile click1116 function handleTileClick(tile) {1117 if (!state.gameActive || tile.matched || tile.flipped || state.selectedTiles.length >= 2) {1118 return;1119 }1120 1121 // Flip the tile1122 tile.flipped = true;1123 state.selectedTiles.push(tile);1124 1125 // Play sound1126 playSound('flip');1127 1128 renderBoard();1129 1130 // Check for match if two tiles are selected1131 if (state.selectedTiles.length === 2) {1132 const [tile1, tile2] = state.selectedTiles;1133 1134 if (tile1.type === tile2.type) {1135 // Match found1136 tile1.matched = true;1137 tile2.matched = true;1138 state.matchedPairs++;1139 state.score += 50 * state.level;1140 1141 // Play success sound1142 playSound('match');1143 1144 // Check if level is complete1145 if (state.matchedPairs === state.totalPairs) {1146 levelComplete();1147 }1148 1149 // Clear selection after delay1150 setTimeout(() => {1151 state.selectedTiles = [];1152 renderBoard();1153 }, 500);1154 } else {1155 // No match1156 setTimeout(() => {1157 tile1.flipped = false;1158 tile2.flipped = false;1159 state.selectedTiles = [];1160 renderBoard();1161 1162 // Play mismatch sound1163 playSound('mismatch');1164 }, 1000);1165 }1166 }1167 1168 updateUI();1169 }1170 1171 // Level complete1172 function levelComplete() {1173 state.gameActive = false;1174 clearInterval(state.timerInterval);1175 1176 // Calculate bonus points based on time1177 const timeBonus = Math.max(0, 300 - state.time);1178 state.score += timeBonus;1179 1180 // Show level complete modal1181 levelTimeElement.textContent = formatTime(state.time);1182 levelScoreElement.textContent = `+${timeBonus}`;1183 levelCompleteModal.classList.remove('hidden');1184 1185 // Play level complete sound1186 playSound('level-complete');1187 1188 updateUI();1189 }1190 1191 // Next level1192 function nextLevel() {1193 playSound('button-click');1194 1195 state.level++;1196 state.time = 0;1197 state.gameActive = true;1198 1199 levelCompleteModal.classList.add('hidden');1200 startTimer();