From 0f720f2201847884001e015d787a75b837ef2c63 Mon Sep 17 00:00:00 2001 From: Eugene Serb <46799701+eugene-serb@users.noreply.github.com> Date: Mon, 29 Aug 2022 14:20:59 +0300 Subject: [PATCH] - added model IQueryRoute for made IQueryRoute list in queryRoutes.ts. - improve and decomposited QueryRouter. - updated router index block of modules and imports. - updated version. - build. --- docs/index.html | 2 +- docs/js/app.0de30deb.js | 2 -- docs/js/app.0de30deb.js.map | 1 - docs/js/app.9a519cb2.js | 2 ++ docs/js/app.9a519cb2.js.map | 1 + package-lock.json | 4 ++-- package.json | 2 +- src/router/assets/queryRoutes.ts | 30 ++++++++++++++++++++++++++++++ src/router/index.ts | 16 +++++++++++++--- src/router/models/IQueryRoute.ts | 6 ++++++ src/router/modules/QueryRouter.ts | 29 ++++++++--------------------- 11 files changed, 64 insertions(+), 31 deletions(-) delete mode 100644 docs/js/app.0de30deb.js delete mode 100644 docs/js/app.0de30deb.js.map create mode 100644 docs/js/app.9a519cb2.js create mode 100644 docs/js/app.9a519cb2.js.map create mode 100644 src/router/assets/queryRoutes.ts create mode 100644 src/router/models/IQueryRoute.ts diff --git a/docs/index.html b/docs/index.html index cc4e92a..03e237f 100644 --- a/docs/index.html +++ b/docs/index.html @@ -15,4 +15,4 @@ webvisor: true });
\ No newline at end of file + }
\ No newline at end of file diff --git a/docs/js/app.0de30deb.js b/docs/js/app.0de30deb.js deleted file mode 100644 index 64b6ae1..0000000 --- a/docs/js/app.0de30deb.js +++ /dev/null @@ -1,2 +0,0 @@ -(function(){"use strict";var e={1592:function(e,t,a){var n=a(9242),o=a(3396);const r={class:"page container"},i={class:"wavelovers"};function s(e,t,a,n,s,c){const d=(0,o.up)("HeaderItem"),u=(0,o.up)("router-view"),m=(0,o.up)("FooterItem");return(0,o.wg)(),(0,o.iD)(o.HY,null,[(0,o.Wm)(d),(0,o._)("main",r,[(0,o._)("div",i,[(0,o.Wm)(u)])]),(0,o.Wm)(m)],64)}var c=a(1746);const d={class:"header"},u={class:"header-wrapper container"},m=(0,o._)("div",{class:"logo-wrapper"},[(0,o._)("span",{class:"logo-wrapper__logo",translate:"no"},"Wavelovers")],-1),l={class:"menu-wrapper"},v={class:"navigation"},p={class:"navigation__item"},g=(0,o.Uk)("Home"),f={class:"navigation__item"},h=(0,o.Uk)("FAQ"),b={class:"navigation__item"},w=(0,o.Uk)("About"),y={class:"navigation__item"},W=(0,o.Uk)("Donate");function k(e,t,a,n,r,i){const s=(0,o.up)("router-link");return(0,o.wg)(),(0,o.iD)("header",d,[(0,o._)("div",u,[m,(0,o._)("nav",l,[(0,o._)("ul",v,[(0,o._)("li",p,[(0,o.Wm)(s,{to:"/"},{default:(0,o.w5)((()=>[g])),_:1})]),(0,o._)("li",f,[(0,o.Wm)(s,{to:"/faq"},{default:(0,o.w5)((()=>[h])),_:1})]),(0,o._)("li",b,[(0,o.Wm)(s,{to:"/about"},{default:(0,o.w5)((()=>[w])),_:1})]),(0,o._)("li",y,[(0,o.Wm)(s,{to:"/donate"},{default:(0,o.w5)((()=>[W])),_:1})])])])])])}var _=(0,o.aZ)({name:"HeaderItem"}),V=a(89);const G=(0,V.Z)(_,[["render",k]]);var M=G;const A={class:"footer"},T=(0,o.uE)('',1),P=[T];function Z(e,t,a,n,r,i){return(0,o.wg)(),(0,o.iD)("footer",A,P)}var C=(0,o.aZ)({name:"FooterItem"});const E=(0,V.Z)(C,[["render",Z]]);var L=E,x=(0,o.aZ)({name:"App",components:{HeaderItem:M,FooterItem:L},methods:{addGamepad:function(e){c.Z.dispatch("addGamepad",e)},deleteGamepad:function(e){c.Z.dispatch("deleteGamepad",e)},addEventListeners:function(){window.addEventListener("gamepadconnected",this.addGamepad),window.addEventListener("gamepaddisconnected",this.deleteGamepad)},removeEventListeners:function(){window.removeEventListener("gamepadconnected",this.addGamepad),window.removeEventListener("gamepaddisconnected",this.deleteGamepad)}},mounted(){this.addEventListeners()},unmounted(){this.removeEventListeners()}});const D=(0,V.Z)(x,[["render",s]]);var I=D,j=a(2483);const U=(0,o._)("h1",{class:"visually-hidden"},"Wavelovers",-1);function S(e,t,a,n,r,i){const s=(0,o.up)("AppPatterns");return(0,o.wg)(),(0,o.iD)(o.HY,null,[U,(0,o.Wm)(s)],64)}const O={class:"app-patterns"},N=(0,o.Uk)("Loading..."),q=(0,o.Uk)("Press any gamepad button or connect a new gamepad to vibrate.");function F(e,t,a,n,r,i){const s=(0,o.up)("NavigationList"),c=(0,o.up)("PatternList"),d=(0,o.up)("MessageItem"),u=(0,o.up)("GamepadList");return(0,o.wg)(),(0,o.iD)(o.HY,null,[(0,o.Wm)(s),(0,o._)("div",O,[e.patterns.length>0?((0,o.wg)(),(0,o.j4)(c,{key:0,patterns:e.patterns,mode:e.mode,isActive:e.isActive,onChange:e.change},null,8,["patterns","mode","isActive","onChange"])):((0,o.wg)(),(0,o.j4)(d,{key:1},{default:(0,o.w5)((()=>[N])),_:1}))]),e.gamepads.length>0?((0,o.wg)(),(0,o.j4)(u,{key:0,gamepads:e.gamepads},null,8,["gamepads"])):((0,o.wg)(),(0,o.j4)(d,{key:1},{default:(0,o.w5)((()=>[q])),_:1}))],64)}var z=a(4246),H=a(3375),R=a(9808);const B={class:"content-item pattern-list"};function Q(e,t,a,n,r,i){const s=(0,o.up)("PatternItem");return(0,o.wg)(),(0,o.iD)("div",B,[((0,o.wg)(!0),(0,o.iD)(o.HY,null,(0,o.Ko)(e.patterns,((t,a)=>((0,o.wg)(),(0,o.j4)(s,{key:t.name,pattern:t,index:a,mode:e.mode,isActive:e.isActive,onChange:e.change},null,8,["pattern","index","mode","isActive","onChange"])))),128))])}var Y=a(7139);const K=["textContent"],$={class:"pattern-item__info-container"},J=["textContent"],X=["textContent"];function ee(e,t,a,n,r,i){return(0,o.wg)(),(0,o.iD)("div",{onClick:t[0]||(t[0]=t=>e.change(e.index)),class:(0,Y.C_)(["pattern-item",e.index===e.mode&&!0===e.isActive?"pattern-item_selected":""])},[(0,o._)("span",{class:"pattern-item__icon",textContent:(0,Y.zw)(e.pattern.icon)},null,8,K),(0,o._)("div",$,[(0,o._)("span",{class:"pattern-item__name",textContent:(0,Y.zw)(e.pattern.name)},null,8,J),(0,o._)("span",{class:"pattern-item__type",textContent:(0,Y.zw)(e.pattern.type)},null,8,X)])],2)}var te=(0,o.aZ)({name:"PatternItem",props:{pattern:{type:Object},index:{type:Number},mode:{type:Number},isActive:{type:Boolean}},methods:{change:function(e){this.$emit("change",e)}}});const ae=(0,V.Z)(te,[["render",ee]]);var ne=ae,oe=(0,o.aZ)({name:"PatternList",props:{patterns:{type:Array},mode:{type:Number},isActive:{type:Boolean}},components:{PatternItem:ne},methods:{change:function(e){this.$emit("change",e)}}});const re=(0,V.Z)(oe,[["render",Q]]);var ie=re,se=(0,o.aZ)({name:"AppPatterns",components:{PatternList:ie,NavigationList:z.Z,GamepadList:H.Z,MessageItem:R.Z},computed:{gamepads:function(){return c.Z.getters.gamepads},patterns:function(){return c.Z.getters.patterns},mode:function(){return c.Z.getters.mode},isActive:function(){return c.Z.getters.isActive}},methods:{change(e){c.Z.dispatch("change",e)}},mounted(){c.Z.dispatch("loadPatterns")}});const ce=(0,V.Z)(se,[["render",F]]);var de=ce,ue=(0,o.aZ)({name:"PatternsView",components:{AppPatterns:de}});const me=(0,V.Z)(ue,[["render",S]]);var le=me;function ve(e,t,a){switch(e.fullPath){case"/?custom":ke.push("/custom");break;case"/?manual":ke.push("/manual");break;case"/?diagnostic":ke.push("/diagnostic");break;case"/?faq":ke.push("/faq");break;case"/?about":ke.push("/about");break;case"/?donate":ke.push("/donate");break}return a()}const pe={update:ve};var ge=pe;function fe(e,t){e.map((e=>{const a=document.createElement(t);return Object.keys(e).forEach((t=>{a.setAttribute(t,e[t])})),a.setAttribute("data-vue-router-controlled",""),a})).forEach((e=>document.head.appendChild(e)))}function he(e,t,a){const n=e.matched.slice().reverse().find((e=>e.meta&&e.meta.title)),o=e.matched.slice().reverse().find((e=>e.meta&&e.meta.metaTags&&e.meta.linkTags));if(n&&(document.title=n.meta.title),Array.from(document.querySelectorAll("[data-vue-router-controlled]")).map((e=>{e.parentNode&&e.parentNode.removeChild(e)})),!o)return a();const r=o.meta.linkTags,i=o.meta.metaTags;return fe(r,"link"),fe(i,"meta"),a()}const be={update:he};var we=be;const ye=[{path:"/",name:"patterns-view",component:le,meta:{title:"Wavelovers",metaTags:[{name:"keywords",content:"Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона"},{name:"description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."},{name:"og:title",content:"Wavelovers"},{name:"og:description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."},{name:"og:url",content:"https://wavelovers.ru/"},{name:"twitter:title",content:"Wavelovers"},{name:"twitter:description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."}],linkTags:[{rel:"canonical",href:"https://wavelovers.ru/"}]}},{path:"/custom",name:"custom-view",component:()=>a.e(219).then(a.bind(a,219)),meta:{title:"Wavelovers – Custom",metaTags:[{name:"keywords",content:"Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона"},{name:"description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."},{name:"og:title",content:"Wavelovers – Custom"},{name:"og:description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."},{name:"og:url",content:"https://wavelovers.ru/custom"},{name:"twitter:title",content:"Wavelovers – Custom"},{name:"twitter:description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."}],linkTags:[{rel:"canonical",href:"https://wavelovers.ru/custom"}]}},{path:"/manual",name:"manual-view",component:()=>a.e(807).then(a.bind(a,6807)),meta:{title:"Wavelovers – Manual",metaTags:[{name:"keywords",content:"Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона"},{name:"description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."},{name:"og:title",content:"Wavelovers – Manual"},{name:"og:description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."},{name:"og:url",content:"https://wavelovers.ru/manual"},{name:"twitter:title",content:"Wavelovers – Manual"},{name:"twitter:description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."}],linkTags:[{rel:"canonical",href:"https://wavelovers.ru/manual"}]}},{path:"/diagnostic",name:"diagnostic-view",component:()=>a.e(582).then(a.bind(a,6582)),meta:{title:"Wavelovers – Diagnostic",metaTags:[{name:"keywords",content:"Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона"},{name:"description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."},{name:"og:title",content:"Wavelovers – Diagnostic"},{name:"og:description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."},{name:"og:url",content:"https://wavelovers.ru/diagnostic"},{name:"twitter:title",content:"Wavelovers – Diagnostic"},{name:"twitter:description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."}],linkTags:[{rel:"canonical",href:"https://wavelovers.ru/diagnostic"}]}},{path:"/faq",name:"faq-view",component:()=>a.e(645).then(a.bind(a,645)),meta:{title:"Wavelovers – FAQ",metaTags:[{name:"keywords",content:"Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, FAQ, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона, часто задаваемые вопросы"},{name:"description",content:"Wavelovers. Frequently asked questions page."},{name:"og:title",content:"Wavelovers – FAQ"},{name:"og:description",content:"Wavelovers. Frequently asked questions page."},{name:"og:url",content:"https://wavelovers.ru/faq"},{name:"twitter:title",content:"Wavelovers – FAQ"},{name:"twitter:description",content:"Wavelovers. Frequently asked questions page."}],linkTags:[{rel:"canonical",href:"https://wavelovers.ru/faq"}]}},{path:"/about",name:"about-view",component:()=>a.e(672).then(a.bind(a,2672)),meta:{title:"Wavelovers – About",metaTags:[{name:"keywords",content:"Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, advertise, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона, реклама"},{name:"description",content:"Wavelovers. Page with information about the project and data on donations."},{name:"og:title",content:"Wavelovers – About"},{name:"og:description",content:"Wavelovers. Page with information about the project and data on donations."},{name:"og:url",content:"https://wavelovers.ru/about"},{name:"twitter:title",content:"Wavelovers – About"},{name:"twitter:description",content:"Wavelovers. Page with information about the project and data on donations."}],linkTags:[{rel:"canonical",href:"https://wavelovers.ru/about"}]}},{path:"/donate",name:"donate-view",component:()=>a.e(66).then(a.bind(a,1066)),meta:{title:"Wavelovers – Donate",metaTags:[{name:"keywords",content:"Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, Donate, Support, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона, задонатить, пожертвовать, помочь, поблагодарить"},{name:"description",content:"Wavelovers. Donate to the author."},{name:"og:title",content:"Wavelovers – Donate"},{name:"og:description",content:"Wavelovers. Donate to the author."},{name:"og:url",content:"https://wavelovers.ru/donate"},{name:"twitter:title",content:"Wavelovers – Donate"},{name:"twitter:description",content:"Wavelovers. Donate to the author."}],linkTags:[{rel:"canonical",href:"https://wavelovers.ru/donate"}]}},{path:"/404",name:"404",component:()=>a.e(531).then(a.bind(a,4066)),meta:{title:"Wavelovers – Page not found",metaTags:[{name:"og:title",content:"Wavelovers – Page not found"},{name:"og:url",content:"https://wavelovers.ru/404"}],linkTags:[{rel:"canonical",href:"https://wavelovers.ru/404"}]}},{path:"/:catchAll(.*)*",redirect:"/404"}],We=(0,j.p7)({history:(0,j.PO)("/"),routes:ye});We.beforeEach(ge.update),We.beforeEach(we.update);var ke=We;(0,n.ri)(I).use(c.Z).use(ke).mount("#app")},1746:function(e,t,a){a.d(t,{Z:function(){return l}});var n=a(65),o=a(2482);class r{constructor(e){(0,o.Z)(this,"unit",void 0),(0,o.Z)(this,"id",void 0),(0,o.Z)(this,"canVibrate",void 0),(0,o.Z)(this,"isVibrating",void 0),(0,o.Z)(this,"interval",void 0),this.unit=e,this.id=Date.now(),this.canVibrate=!!this.unit.vibrationActuator,this.isVibrating=!1,this.update=this.update.bind(this),this.interval=setInterval(this.update,1)}update(){const e=navigator.getGamepads();this.unit=e[this.unit.index]}async loop(e){this.isVibrating=!0;const t=10;while(!0===this.isVibrating)for(let a=0;asetTimeout(t,e)))}}var i=r;const s={state:()=>({gamepads:[]}),getters:{gamepads:function(e){return e.gamepads}},mutations:{addGamepad:function(e,t){e.gamepads.push(t)},deleteGamepad:function(e,t){e.gamepads.splice(t,1)}},actions:{addGamepad:function(e,t){const a=t;e.getters.gamepads.length>=1||e.commit("addGamepad",new i(a.gamepad))},deleteGamepad:function(e,t){e.getters.gamepads.forEach(((a,n)=>{a.unit.id===t.gamepad.id&&e.commit("deleteGamepad",n)}))},loop:function(e,t){e.getters.gamepads.forEach((e=>{e.loop(t)}))},vibrate:function(e,t){e.getters.gamepads.forEach((e=>{e.vibrate(t)}))},reset:function(e){e.getters.gamepads.forEach((e=>{e.reset()}))}}};var c=s;const d={state:()=>({patterns:[]}),getters:{patterns:function(e){return e.patterns}},mutations:{setPatterns:function(e,t){e.patterns=t}},actions:{loadPatterns:async function(e){const t="https://wavelovers.ru/assets/patterns.json";try{const a=await fetch(t);if(a.ok){const t=await a.json();e.commit("setPatterns",t)}else console.log("Connect to the Internet for download more patterns...")}catch(a){console.log(a)}}}};var u=d;const m=(0,n.MT)({state:()=>({mode:0,isActive:!1}),getters:{mode:function(e){return e.mode},isActive:function(e){return e.isActive}},mutations:{setMode:function(e,t){e.mode=t},setIsActive:function(e,t){e.isActive=t}},actions:{setMode:function(e,t){e.commit("setMode",t)},setIsActive:function(e,t){e.commit("setIsActive",t)},change:function(e,t){e.getters.mode===t?e.dispatch("setIsActive",!e.getters.isActive):(e.dispatch("setIsActive",!0),e.dispatch("setMode",t)),!0===e.getters.isActive?(e.dispatch("reset"),e.dispatch("loop",e.getters.patterns[e.getters.mode].pattern)):e.dispatch("reset")},startCustom:function(e,t){e.dispatch("setIsActive",!1),e.dispatch("setMode",0),e.dispatch("reset"),e.dispatch("loop",t)}},modules:{MGamepads:c,MPatterns:u}});var l=m},3375:function(e,t,a){a.d(t,{Z:function(){return g}});var n=a(3396),o=a(7139);const r={class:"content-item device-list"};function i(e,t,a,i,s,c){const d=(0,n.up)("GamepadItem");return(0,n.wg)(),(0,n.iD)("div",r,[((0,n.wg)(!0),(0,n.iD)(n.HY,null,(0,n.Ko)(e.gamepads,(e=>((0,n.wg)(),(0,n.j4)(d,{key:e.id,textContent:(0,o.zw)(e.unit.id)},null,8,["textContent"])))),128))])}const s={class:"list-item"};function c(e,t,a,o,r,i){return(0,n.wg)(),(0,n.iD)("div",s)}var d=(0,n.aZ)({name:"GamepadItem"}),u=a(89);const m=(0,u.Z)(d,[["render",c]]);var l=m,v=(0,n.aZ)({name:"GamepadList",props:{gamepads:{type:Array}},components:{GamepadItem:l}});const p=(0,u.Z)(v,[["render",i]]);var g=p},9808:function(e,t,a){a.d(t,{Z:function(){return d}});var n=a(3396);const o={class:"content-item message"};function r(e,t,a,r,i,s){return(0,n.wg)(),(0,n.iD)("div",o,[(0,n._)("span",null,[(0,n.WI)(e.$slots,"default")])])}var i=(0,n.aZ)({name:"MessageItem"}),s=a(89);const c=(0,s.Z)(i,[["render",r]]);var d=c},4246:function(e,t,a){a.d(t,{Z:function(){return v}});var n=a(3396);const o={class:"content-item navigation-list"},r=(0,n.Uk)("Patterns"),i=(0,n.Uk)("Custom"),s=(0,n.Uk)("Manual"),c=(0,n.Uk)("Diagnostic");function d(e,t,a,d,u,m){const l=(0,n.up)("router-link");return(0,n.wg)(),(0,n.iD)("div",o,[(0,n.Wm)(l,{to:"/",class:"navigation-list__item"},{default:(0,n.w5)((()=>[r])),_:1}),(0,n.Wm)(l,{to:"/custom",class:"navigation-list__item"},{default:(0,n.w5)((()=>[i])),_:1}),(0,n.Wm)(l,{to:"/manual",class:"navigation-list__item"},{default:(0,n.w5)((()=>[s])),_:1}),(0,n.Wm)(l,{to:"/diagnostic",class:"navigation-list__item"},{default:(0,n.w5)((()=>[c])),_:1})])}var u=(0,n.aZ)({name:"NavigationList"}),m=a(89);const l=(0,m.Z)(u,[["render",d]]);var v=l}},t={};function a(n){var o=t[n];if(void 0!==o)return o.exports;var r=t[n]={exports:{}};return e[n](r,r.exports,a),r.exports}a.m=e,function(){var e=[];a.O=function(t,n,o,r){if(!n){var i=1/0;for(u=0;u=r)&&Object.keys(a.O).every((function(e){return a.O[e](n[c])}))?n.splice(c--,1):(s=!1,r0&&e[u-1][2]>r;u--)e[u]=e[u-1];e[u]=[n,o,r]}}(),function(){a.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return a.d(t,{a:t}),t}}(),function(){a.d=function(e,t){for(var n in t)a.o(t,n)&&!a.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})}}(),function(){a.f={},a.e=function(e){return Promise.all(Object.keys(a.f).reduce((function(t,n){return a.f[n](e,t),t}),[]))}}(),function(){a.u=function(e){return"js/"+e+"."+{66:"54b2ec35",219:"4c3a113b",531:"6af13e76",582:"c3117d29",645:"b32a0b62",672:"270ec4e0",807:"369d563e"}[e]+".js"}}(),function(){a.miniCssF=function(e){return"css/"+e+"."+{66:"bb6440f7",219:"19a8cda3",582:"10b8ac32",672:"278b2bb3",807:"06b3a622"}[e]+".css"}}(),function(){a.g=function(){if("object"===typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"===typeof window)return window}}()}(),function(){a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}}(),function(){var e={},t="wavelovers:";a.l=function(n,o,r,i){if(e[n])e[n].push(o);else{var s,c;if(void 0!==r)for(var d=document.getElementsByTagName("script"),u=0;u [\n _hoisted_7\n ]),\n _: 1\n })\n ]),\n _createElementVNode(\"li\", _hoisted_8, [\n _createVNode(_component_router_link, { to: \"/faq\" }, {\n default: _withCtx(() => [\n _hoisted_9\n ]),\n _: 1\n })\n ]),\n _createElementVNode(\"li\", _hoisted_10, [\n _createVNode(_component_router_link, { to: \"/about\" }, {\n default: _withCtx(() => [\n _hoisted_11\n ]),\n _: 1\n })\n ]),\n _createElementVNode(\"li\", _hoisted_12, [\n _createVNode(_component_router_link, { to: \"/donate\" }, {\n default: _withCtx(() => [\n _hoisted_13\n ]),\n _: 1\n })\n ])\n ])\n ])\n ])\n ]))\n}","\r\n import { defineComponent } from 'vue';\r\n\r\n export default defineComponent({\r\n name: 'HeaderItem',\r\n });\r\n","import { render } from \"./HeaderItem.vue?vue&type=template&id=27217e3d&ts=true\"\nimport script from \"./HeaderItem.vue?vue&type=script&lang=ts\"\nexport * from \"./HeaderItem.vue?vue&type=script&lang=ts\"\n\nimport \"./HeaderItem.vue?vue&type=style&index=0&id=27217e3d&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import { createElementVNode as _createElementVNode, createStaticVNode as _createStaticVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"footer\" }\nconst _hoisted_2 = /*#__PURE__*/_createStaticVNode(\"
© 2022 Wavelovers. Content licensed under GNU General Public License v3.0
This site is open source. Improve this page.
Created byEugene Serb
\", 1)\nconst _hoisted_3 = [\n _hoisted_2\n]\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n return (_openBlock(), _createElementBlock(\"footer\", _hoisted_1, _hoisted_3))\n}","\r\n import { defineComponent } from 'vue';\r\n\r\n export default defineComponent({\r\n name: 'FooterItem',\r\n });\r\n","import { render } from \"./FooterItem.vue?vue&type=template&id=494b1bc6&ts=true\"\nimport script from \"./FooterItem.vue?vue&type=script&lang=ts\"\nexport * from \"./FooterItem.vue?vue&type=script&lang=ts\"\n\nimport \"./FooterItem.vue?vue&type=style&index=0&id=494b1bc6&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","\r\n import { defineComponent } from 'vue';\r\n import store from '@/store/index';\r\n import HeaderItem from '@/components/HeaderItem.vue';\r\n import FooterItem from '@/components/FooterItem.vue';\r\n\r\n export default defineComponent({\r\n name: 'App',\r\n components: {\r\n HeaderItem: HeaderItem,\r\n FooterItem: FooterItem,\r\n },\r\n methods: {\r\n addGamepad: function (event: GamepadEvent): void {\r\n store.dispatch('addGamepad', event);\r\n },\r\n deleteGamepad: function (event: GamepadEvent): void {\r\n store.dispatch('deleteGamepad', event);\r\n },\r\n addEventListeners: function (): void {\r\n window.addEventListener('gamepadconnected', this.addGamepad);\r\n window.addEventListener('gamepaddisconnected', this.deleteGamepad);\r\n },\r\n removeEventListeners: function (): void {\r\n window.removeEventListener('gamepadconnected', this.addGamepad);\r\n window.removeEventListener('gamepaddisconnected', this.deleteGamepad);\r\n },\r\n },\r\n mounted() {\r\n this.addEventListeners();\r\n },\r\n unmounted() {\r\n this.removeEventListeners();\r\n },\r\n });\r\n","import { render } from \"./App.vue?vue&type=template&id=d319ea34&ts=true\"\nimport script from \"./App.vue?vue&type=script&lang=ts\"\nexport * from \"./App.vue?vue&type=script&lang=ts\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import { createElementVNode as _createElementVNode, resolveComponent as _resolveComponent, createVNode as _createVNode, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = /*#__PURE__*/_createElementVNode(\"h1\", { class: \"visually-hidden\" }, \"Wavelovers\", -1)\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n const _component_AppPatterns = _resolveComponent(\"AppPatterns\")!\n\n return (_openBlock(), _createElementBlock(_Fragment, null, [\n _hoisted_1,\n _createVNode(_component_AppPatterns)\n ], 64))\n}","import { resolveComponent as _resolveComponent, createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock, createCommentVNode as _createCommentVNode, createTextVNode as _createTextVNode, withCtx as _withCtx, createElementVNode as _createElementVNode, Fragment as _Fragment, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"app-patterns\" }\nconst _hoisted_2 = /*#__PURE__*/_createTextVNode(\"Loading...\")\nconst _hoisted_3 = /*#__PURE__*/_createTextVNode(\"Press any gamepad button or connect a new gamepad to vibrate.\")\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n const _component_NavigationList = _resolveComponent(\"NavigationList\")!\n const _component_PatternList = _resolveComponent(\"PatternList\")!\n const _component_MessageItem = _resolveComponent(\"MessageItem\")!\n const _component_GamepadList = _resolveComponent(\"GamepadList\")!\n\n return (_openBlock(), _createElementBlock(_Fragment, null, [\n _createVNode(_component_NavigationList),\n _createElementVNode(\"div\", _hoisted_1, [\n (_ctx.patterns.length > 0)\n ? (_openBlock(), _createBlock(_component_PatternList, {\n key: 0,\n patterns: _ctx.patterns,\n mode: _ctx.mode,\n isActive: _ctx.isActive,\n onChange: _ctx.change\n }, null, 8, [\"patterns\", \"mode\", \"isActive\", \"onChange\"]))\n : (_openBlock(), _createBlock(_component_MessageItem, { key: 1 }, {\n default: _withCtx(() => [\n _hoisted_2\n ]),\n _: 1\n }))\n ]),\n (_ctx.gamepads.length > 0)\n ? (_openBlock(), _createBlock(_component_GamepadList, {\n key: 0,\n gamepads: _ctx.gamepads\n }, null, 8, [\"gamepads\"]))\n : (_openBlock(), _createBlock(_component_MessageItem, { key: 1 }, {\n default: _withCtx(() => [\n _hoisted_3\n ]),\n _: 1\n }))\n ], 64))\n}","import { renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, resolveComponent as _resolveComponent, createBlock as _createBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"content-item pattern-list\" }\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n const _component_PatternItem = _resolveComponent(\"PatternItem\")!\n\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1, [\n (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.patterns, (pattern, index) => {\n return (_openBlock(), _createBlock(_component_PatternItem, {\n key: pattern.name,\n pattern: pattern,\n index: index,\n mode: _ctx.mode,\n isActive: _ctx.isActive,\n onChange: _ctx.change\n }, null, 8, [\"pattern\", \"index\", \"mode\", \"isActive\", \"onChange\"]))\n }), 128))\n ]))\n}","import { toDisplayString as _toDisplayString, createElementVNode as _createElementVNode, normalizeClass as _normalizeClass, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = [\"textContent\"]\nconst _hoisted_2 = { class: \"pattern-item__info-container\" }\nconst _hoisted_3 = [\"textContent\"]\nconst _hoisted_4 = [\"textContent\"]\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n return (_openBlock(), _createElementBlock(\"div\", {\n onClick: _cache[0] || (_cache[0] = ($event: any) => (_ctx.change(_ctx.index))),\n class: _normalizeClass(['pattern-item',\r\n _ctx.index === _ctx.mode && _ctx.isActive === true ?\r\n 'pattern-item_selected' : '',\r\n ])\n }, [\n _createElementVNode(\"span\", {\n class: \"pattern-item__icon\",\n textContent: _toDisplayString(_ctx.pattern.icon)\n }, null, 8, _hoisted_1),\n _createElementVNode(\"div\", _hoisted_2, [\n _createElementVNode(\"span\", {\n class: \"pattern-item__name\",\n textContent: _toDisplayString(_ctx.pattern.name)\n }, null, 8, _hoisted_3),\n _createElementVNode(\"span\", {\n class: \"pattern-item__type\",\n textContent: _toDisplayString(_ctx.pattern.type)\n }, null, 8, _hoisted_4)\n ])\n ], 2))\n}","\r\n import { defineComponent } from 'vue';\r\n\r\n export default defineComponent({\r\n name: 'PatternItem',\r\n props: {\r\n pattern: {\r\n type: Object,\r\n },\r\n index: {\r\n type: Number,\r\n },\r\n mode: {\r\n type: Number,\r\n },\r\n isActive: {\r\n type: Boolean,\r\n },\r\n },\r\n methods: {\r\n change: function (index: number): void {\r\n this.$emit('change', index as number);\r\n },\r\n },\r\n });\r\n","import { render } from \"./PatternItem.vue?vue&type=template&id=81514550&ts=true\"\nimport script from \"./PatternItem.vue?vue&type=script&lang=ts\"\nexport * from \"./PatternItem.vue?vue&type=script&lang=ts\"\n\nimport \"./PatternItem.vue?vue&type=style&index=0&id=81514550&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","\r\n import { defineComponent } from 'vue';\r\n import PatternItem from '@/components/PatternItem.vue';\r\n\r\n export default defineComponent({\r\n name: 'PatternList',\r\n props: {\r\n patterns: {\r\n type: Array,\r\n },\r\n mode: {\r\n type: Number,\r\n },\r\n isActive: {\r\n type: Boolean,\r\n },\r\n },\r\n components: {\r\n PatternItem: PatternItem,\r\n },\r\n methods: {\r\n change: function (index: number): void {\r\n this.$emit('change', index as number);\r\n },\r\n },\r\n });\r\n","import { render } from \"./PatternList.vue?vue&type=template&id=210779ce&ts=true\"\nimport script from \"./PatternList.vue?vue&type=script&lang=ts\"\nexport * from \"./PatternList.vue?vue&type=script&lang=ts\"\n\nimport \"./PatternList.vue?vue&type=style&index=0&id=210779ce&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","\r\n import { defineComponent } from 'vue';\r\n import store from '@/store/index';\r\n import NavigationList from '@/components/NavigationList.vue';\r\n import GamepadList from '@/components/GamepadList.vue';\r\n import MessageItem from '@/components/MessageItem.vue';\r\n import PatternList from '@/components/PatternList.vue';\r\n import Vibrator from '@/models/Vibrator';\r\n import TPattern from '@/models/TPattern';\r\n\r\n export default defineComponent({\r\n name: 'AppPatterns',\r\n components: {\r\n PatternList: PatternList,\r\n NavigationList: NavigationList,\r\n GamepadList: GamepadList,\r\n MessageItem: MessageItem,\r\n },\r\n computed: {\r\n gamepads: function (): Vibrator[] {\r\n return store.getters.gamepads as Vibrator[];\r\n },\r\n patterns: function (): TPattern[] {\r\n return store.getters.patterns as TPattern[];\r\n },\r\n mode: function (): number {\r\n return store.getters.mode as number;\r\n },\r\n isActive: function (): boolean {\r\n return store.getters.isActive as boolean;\r\n },\r\n },\r\n methods: {\r\n change(index: number): void {\r\n store.dispatch('change', index as number);\r\n },\r\n },\r\n mounted() {\r\n store.dispatch('loadPatterns');\r\n },\r\n });\r\n","import { render } from \"./AppPatterns.vue?vue&type=template&id=99e866c8&ts=true\"\nimport script from \"./AppPatterns.vue?vue&type=script&lang=ts\"\nexport * from \"./AppPatterns.vue?vue&type=script&lang=ts\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","\r\n import { defineComponent } from 'vue';\r\n import AppPatterns from '@/components/AppPatterns.vue';\r\n\r\n export default defineComponent({\r\n name: 'PatternsView',\r\n components: {\r\n AppPatterns: AppPatterns,\r\n },\r\n });\r\n","import { render } from \"./PatternsView.vue?vue&type=template&id=3768dde1&ts=true\"\nimport script from \"./PatternsView.vue?vue&type=script&lang=ts\"\nexport * from \"./PatternsView.vue?vue&type=script&lang=ts\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import router from '@/router';\r\nimport { NavigationGuardNext, RouteLocationNormalized } from \"vue-router\";\r\n\r\nfunction updateRoute(\r\n to: RouteLocationNormalized,\r\n from: RouteLocationNormalized,\r\n next: NavigationGuardNext\r\n) {\r\n switch (to.fullPath) {\r\n case '/?custom':\r\n router.push('/custom');\r\n break;\r\n case '/?manual':\r\n router.push('/manual');\r\n break;\r\n case '/?diagnostic':\r\n router.push('/diagnostic');\r\n break;\r\n case '/?faq':\r\n router.push('/faq');\r\n break;\r\n case '/?about':\r\n router.push('/about');\r\n break;\r\n case '/?donate':\r\n router.push('/donate');\r\n break;\r\n }\r\n return next();\r\n}\r\n\r\nconst QueryRouter = {\r\n update: updateRoute,\r\n};\r\n\r\nexport default QueryRouter;\r\n\r\n","import { NavigationGuardNext, RouteLocationNormalized, RouteRecordNormalized } from \"vue-router\";\r\n\r\nfunction appendTags(tagsArray: object[], type: string) {\r\n tagsArray.map((meta: object) => {\r\n const tag = document.createElement(type);\r\n (Object.keys(meta) as Array)\r\n .forEach((key) => {\r\n tag.setAttribute(key, meta[key] as string);\r\n });\r\n tag.setAttribute('data-vue-router-controlled', '');\r\n return tag;\r\n }).forEach(tag => document.head.appendChild(tag));\r\n}\r\n\r\nfunction updateMetatag(\r\n to: RouteLocationNormalized,\r\n from: RouteLocationNormalized,\r\n next: NavigationGuardNext\r\n) {\r\n const nearestWithTitle: RouteRecordNormalized =\r\n to.matched.slice().reverse()\r\n .find(r => r.meta && r.meta.title) as RouteRecordNormalized;\r\n const nearestWithMeta: RouteRecordNormalized =\r\n to.matched.slice().reverse()\r\n .find(r => r.meta && r.meta.metaTags && r.meta.linkTags) as RouteRecordNormalized;\r\n if (nearestWithTitle) {\r\n document.title = nearestWithTitle.meta.title as string;\r\n }\r\n Array.from(document.querySelectorAll('[data-vue-router-controlled]'))\r\n .map(el => {\r\n if (el.parentNode) {\r\n el.parentNode.removeChild(el);\r\n }\r\n });\r\n if (!nearestWithMeta) return next();\r\n const linkTags: object[] = nearestWithMeta.meta.linkTags as object[];\r\n const metaTags: object[] = nearestWithMeta.meta.metaTags as object[];\r\n appendTags(linkTags, 'link');\r\n appendTags(metaTags, 'meta');\r\n return next();\r\n}\r\n\r\nconst MetaTagUpdater = {\r\n update: updateMetatag,\r\n};\r\n\r\nexport default MetaTagUpdater;\r\n\r\n","import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';\r\nimport PatternsView from '@/views/PatternsView.vue';\r\nimport QueryRouter from '@/router/modules/QueryRouter';\r\nimport MetaTagUpdater from '@/router/modules/MetaTagUpdater';\r\n\r\nconst routes: Array = [\r\n {\r\n path: '/',\r\n name: 'patterns-view',\r\n component: PatternsView,\r\n meta: {\r\n title: 'Wavelovers',\r\n metaTags: [\r\n {\r\n name: 'keywords',\r\n content: 'Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона',\r\n },\r\n {\r\n name: 'description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n {\r\n name: 'og:title',\r\n content: 'Wavelovers',\r\n },\r\n {\r\n name: 'og:description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n {\r\n name: 'og:url',\r\n content: 'https://wavelovers.ru/',\r\n },\r\n {\r\n name: 'twitter:title',\r\n content: 'Wavelovers',\r\n },\r\n {\r\n name: 'twitter:description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n ],\r\n linkTags: [\r\n {\r\n rel: 'canonical',\r\n href: 'https://wavelovers.ru/',\r\n },\r\n ],\r\n },\r\n },\r\n {\r\n path: '/custom',\r\n name: 'custom-view',\r\n component: () => import('@/views/CustomView.vue'),\r\n meta: {\r\n title: 'Wavelovers – Custom',\r\n metaTags: [\r\n {\r\n name: 'keywords',\r\n content: 'Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона',\r\n },\r\n {\r\n name: 'description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n {\r\n name: 'og:title',\r\n content: 'Wavelovers – Custom',\r\n },\r\n {\r\n name: 'og:description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n {\r\n name: 'og:url',\r\n content: 'https://wavelovers.ru/custom',\r\n },\r\n {\r\n name: 'twitter:title',\r\n content: 'Wavelovers – Custom',\r\n },\r\n {\r\n name: 'twitter:description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n ],\r\n linkTags: [\r\n {\r\n rel: 'canonical',\r\n href: 'https://wavelovers.ru/custom',\r\n },\r\n ],\r\n },\r\n },\r\n {\r\n path: '/manual',\r\n name: 'manual-view',\r\n component: () => import('@/views/ManualView.vue'),\r\n meta: {\r\n title: 'Wavelovers – Manual',\r\n metaTags: [\r\n {\r\n name: 'keywords',\r\n content: 'Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона',\r\n },\r\n {\r\n name: 'description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n {\r\n name: 'og:title',\r\n content: 'Wavelovers – Manual',\r\n },\r\n {\r\n name: 'og:description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n {\r\n name: 'og:url',\r\n content: 'https://wavelovers.ru/manual',\r\n },\r\n {\r\n name: 'twitter:title',\r\n content: 'Wavelovers – Manual',\r\n },\r\n {\r\n name: 'twitter:description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n ],\r\n linkTags: [\r\n {\r\n rel: 'canonical',\r\n href: 'https://wavelovers.ru/manual',\r\n },\r\n ],\r\n },\r\n },\r\n {\r\n path: '/diagnostic',\r\n name: 'diagnostic-view',\r\n component: () => import('@/views/DiagnosticView.vue'),\r\n meta: {\r\n title: 'Wavelovers – Diagnostic',\r\n metaTags: [\r\n {\r\n name: 'keywords',\r\n content: 'Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона',\r\n },\r\n {\r\n name: 'description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n {\r\n name: 'og:title',\r\n content: 'Wavelovers – Diagnostic',\r\n },\r\n {\r\n name: 'og:description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n {\r\n name: 'og:url',\r\n content: 'https://wavelovers.ru/diagnostic',\r\n },\r\n {\r\n name: 'twitter:title',\r\n content: 'Wavelovers – Diagnostic',\r\n },\r\n {\r\n name: 'twitter:description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n ],\r\n linkTags: [\r\n {\r\n rel: 'canonical',\r\n href: 'https://wavelovers.ru/diagnostic',\r\n },\r\n ],\r\n },\r\n },\r\n {\r\n path: '/faq',\r\n name: 'faq-view',\r\n component: () => import('@/views/FaqView.vue'),\r\n meta: {\r\n title: 'Wavelovers – FAQ',\r\n metaTags: [\r\n {\r\n name: 'keywords',\r\n content: 'Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, FAQ, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона, часто задаваемые вопросы',\r\n },\r\n {\r\n name: 'description',\r\n content: 'Wavelovers. Frequently asked questions page.',\r\n },\r\n {\r\n name: 'og:title',\r\n content: 'Wavelovers – FAQ',\r\n },\r\n {\r\n name: 'og:description',\r\n content: 'Wavelovers. Frequently asked questions page.',\r\n },\r\n {\r\n name: 'og:url',\r\n content: 'https://wavelovers.ru/faq',\r\n },\r\n {\r\n name: 'twitter:title',\r\n content: 'Wavelovers – FAQ',\r\n },\r\n {\r\n name: 'twitter:description',\r\n content: 'Wavelovers. Frequently asked questions page.',\r\n },\r\n ],\r\n linkTags: [\r\n {\r\n rel: 'canonical',\r\n href: 'https://wavelovers.ru/faq',\r\n },\r\n ],\r\n },\r\n },\r\n {\r\n path: '/about',\r\n name: 'about-view',\r\n component: () => import('@/views/AboutView.vue'),\r\n meta: {\r\n title: 'Wavelovers – About',\r\n metaTags: [\r\n {\r\n name: 'keywords',\r\n content: 'Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, advertise, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона, реклама',\r\n },\r\n {\r\n name: 'description',\r\n content: 'Wavelovers. Page with information about the project and data on donations.',\r\n },\r\n {\r\n name: 'og:title',\r\n content: 'Wavelovers – About',\r\n },\r\n {\r\n name: 'og:description',\r\n content: 'Wavelovers. Page with information about the project and data on donations.',\r\n },\r\n {\r\n name: 'og:url',\r\n content: 'https://wavelovers.ru/about',\r\n },\r\n {\r\n name: 'twitter:title',\r\n content: 'Wavelovers – About',\r\n },\r\n {\r\n name: 'twitter:description',\r\n content: 'Wavelovers. Page with information about the project and data on donations.',\r\n },\r\n ],\r\n linkTags: [\r\n {\r\n rel: 'canonical',\r\n href: 'https://wavelovers.ru/about',\r\n },\r\n ],\r\n },\r\n },\r\n {\r\n path: '/donate',\r\n name: 'donate-view',\r\n component: () => import('@/views/DonateView.vue'),\r\n meta: {\r\n title: 'Wavelovers – Donate',\r\n metaTags: [\r\n {\r\n name: 'keywords',\r\n content: 'Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, Donate, Support, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона, задонатить, пожертвовать, помочь, поблагодарить',\r\n },\r\n {\r\n name: 'description',\r\n content: 'Wavelovers. Donate to the author.',\r\n },\r\n {\r\n name: 'og:title',\r\n content: 'Wavelovers – Donate',\r\n },\r\n {\r\n name: 'og:description',\r\n content: 'Wavelovers. Donate to the author.',\r\n },\r\n {\r\n name: 'og:url',\r\n content: 'https://wavelovers.ru/donate',\r\n },\r\n {\r\n name: 'twitter:title',\r\n content: 'Wavelovers – Donate',\r\n },\r\n {\r\n name: 'twitter:description',\r\n content: 'Wavelovers. Donate to the author.',\r\n },\r\n ],\r\n linkTags: [\r\n {\r\n rel: 'canonical',\r\n href: 'https://wavelovers.ru/donate',\r\n },\r\n ],\r\n },\r\n },\r\n {\r\n path: '/404',\r\n name: '404',\r\n component: () => import('@/views/NotFoundView.vue'),\r\n meta: {\r\n title: 'Wavelovers – Page not found',\r\n metaTags: [\r\n {\r\n name: 'og:title',\r\n content: 'Wavelovers – Page not found',\r\n },\r\n {\r\n name: 'og:url',\r\n content: 'https://wavelovers.ru/404',\r\n },\r\n ],\r\n linkTags: [\r\n {\r\n rel: 'canonical',\r\n href: 'https://wavelovers.ru/404',\r\n },\r\n ],\r\n },\r\n },\r\n {\r\n path: '/:catchAll(.*)*',\r\n redirect: '/404',\r\n },\r\n];\r\n\r\nconst router = createRouter({\r\n history: createWebHistory(process.env.BASE_URL),\r\n routes,\r\n});\r\n\r\nrouter.beforeEach(QueryRouter.update);\r\nrouter.beforeEach(MetaTagUpdater.update);\r\n\r\nexport default router;\r\n\r\n","import { createApp } from 'vue';\r\nimport App from '@/App.vue';\r\nimport router from '@/router';\r\nimport store from '@/store';\r\n\r\ncreateApp(App)\r\n .use(store)\r\n .use(router)\r\n .mount('#app');\r\n\r\n","import TPatternUnit from '@/models/TPatternUnit';\r\nimport IGamepad from '@/models/IGamepad';\r\nimport IVibrator from '@/models/IVibrator';\r\n\r\nclass Vibrator implements IVibrator {\r\n\r\n unit: IGamepad;\r\n readonly id: number;\r\n readonly canVibrate: boolean;\r\n isVibrating: boolean;\r\n interval: number;\r\n\r\n constructor(unit: IGamepad) {\r\n this.unit = unit;\r\n this.id = Date.now();\r\n this.canVibrate = (this.unit.vibrationActuator) ? true : false;\r\n this.isVibrating = false;\r\n this.update = this.update.bind(this);\r\n this.interval = setInterval(this.update, 1);\r\n }\r\n\r\n update(): void {\r\n const gamepads = navigator.getGamepads();\r\n this.unit = gamepads[this.unit.index] as unknown as IGamepad;\r\n }\r\n\r\n async loop(pattern: TPatternUnit[]): Promise {\r\n this.isVibrating = true;\r\n const offsetTime = 10;\r\n while (this.isVibrating === true) {\r\n for (let i = 0; i < pattern.length; i++) {\r\n if (this.isVibrating === true) {\r\n this.vibrate(pattern[i]);\r\n await this.sleep(pattern[i].startDelay + pattern[i].duration - offsetTime);\r\n } else {\r\n return;\r\n }\r\n }\r\n }\r\n }\r\n\r\n vibrate(pattern: TPatternUnit): void {\r\n this.unit.vibrationActuator.playEffect('dual-rumble', pattern);\r\n }\r\n\r\n reset(): void {\r\n this.isVibrating = false;\r\n this.unit.vibrationActuator.reset();\r\n }\r\n\r\n sleep(ms: number): Promise {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n }\r\n}\r\n\r\nexport default Vibrator;\r\n\r\n","import { ActionContext, Module } from 'vuex';\r\nimport IRootState from '@/store/models/IRootState';\r\nimport IGamepadsState from '@/store/models/IGamepadsState';\r\nimport Vibrator from '@/models/Vibrator';\r\nimport IGamepad from '@/models/IGamepad';\r\nimport IGamepadEvent from '@/models/IGamepadEvent';\r\nimport TPatternUnit from '@/models/TPatternUnit';\r\n\r\nconst MGamepads: Module = {\r\n state: () => ({\r\n gamepads: [] as Vibrator[],\r\n }),\r\n getters: {\r\n gamepads: function (state: IGamepadsState): Vibrator[] {\r\n return state.gamepads as Vibrator[];\r\n },\r\n },\r\n mutations: {\r\n addGamepad: function (state: IGamepadsState, gamepad: Vibrator): void {\r\n state.gamepads.push(gamepad as Vibrator);\r\n },\r\n deleteGamepad: function (state: IGamepadsState, index: number): void {\r\n state.gamepads.splice(index, 1);\r\n },\r\n },\r\n actions: {\r\n addGamepad: function (\r\n context: ActionContext,\r\n event: GamepadEvent\r\n ): void {\r\n const iEvent: IGamepadEvent = event as unknown as IGamepadEvent;\r\n if (context.getters.gamepads.length >= 1) {\r\n return;\r\n } else {\r\n context.commit('addGamepad', new Vibrator(iEvent.gamepad as IGamepad));\r\n }\r\n },\r\n deleteGamepad: function (\r\n context: ActionContext,\r\n event: GamepadEvent\r\n ): void {\r\n context.getters.gamepads.forEach((gamepad: Vibrator, index: number) => {\r\n if (gamepad.unit.id === event.gamepad.id) {\r\n context.commit('deleteGamepad', index as number);\r\n }\r\n });\r\n },\r\n loop: function (\r\n context: ActionContext,\r\n pattern: TPatternUnit[]\r\n ): void {\r\n context.getters.gamepads.forEach((gamepad: Vibrator) => {\r\n gamepad.loop(pattern);\r\n });\r\n },\r\n vibrate: function (\r\n context: ActionContext,\r\n pattern: TPatternUnit\r\n ): void {\r\n context.getters.gamepads.forEach((gamepad: Vibrator) => {\r\n gamepad.vibrate(pattern);\r\n });\r\n },\r\n reset: function (\r\n context: ActionContext\r\n ): void {\r\n context.getters.gamepads.forEach((gamepad: Vibrator) => {\r\n gamepad.reset();\r\n });\r\n },\r\n },\r\n};\r\n\r\nexport default MGamepads;\r\n\r\n","import { ActionContext, Module } from 'vuex';\r\nimport IRootState from '@/store/models/IRootState';\r\nimport IPatternState from '@/store/models/IPatternState';\r\nimport TPattern from '@/models/TPattern';\r\n\r\nconst MPatterns: Module = {\r\n state: () => ({\r\n patterns: [] as TPattern[],\r\n }),\r\n getters: {\r\n patterns: function (state: IPatternState): TPattern[] {\r\n return state.patterns as TPattern[];\r\n },\r\n },\r\n mutations: {\r\n setPatterns: function (state: IPatternState, patterns: TPattern[]): void {\r\n state.patterns = patterns as TPattern[];\r\n },\r\n },\r\n actions: {\r\n loadPatterns: async function (\r\n context: ActionContext\r\n ): Promise {\r\n const url = 'https://wavelovers.ru/assets/patterns.json';\r\n try {\r\n const response: Response = await fetch(url);\r\n if (response.ok) {\r\n const json: TPattern[] = await response.json();\r\n context.commit('setPatterns', json as TPattern[]);\r\n } else {\r\n // eslint-disable-next-line\r\n console.log('Connect to the Internet for download more patterns...');\r\n }\r\n } catch (error) {\r\n // eslint-disable-next-line\r\n console.log(error);\r\n }\r\n },\r\n },\r\n};\r\n\r\nexport default MPatterns;\r\n\r\n","import { createStore, Store } from 'vuex';\r\nimport IRootState from '@/store/models/IRootState';\r\nimport MGamepads from '@/store/modules/MGamepads';\r\nimport MPatterns from '@/store/modules/MPatterns';\r\nimport TPatternUnit from '@/models/TPatternUnit';\r\n\r\nconst store: Store = createStore({\r\n state: () => ({\r\n mode: 0 as number,\r\n isActive: false as boolean,\r\n }),\r\n getters: {\r\n mode: function (state: IRootState): number {\r\n return state.mode as number;\r\n },\r\n isActive: function (state: IRootState): boolean {\r\n return state.isActive as boolean;\r\n },\r\n },\r\n mutations: {\r\n setMode: function (state: IRootState, mode: number): void {\r\n state.mode = mode as number;\r\n },\r\n setIsActive: function (state: IRootState, isActive: boolean): void {\r\n state.isActive = isActive as boolean;\r\n },\r\n },\r\n actions: {\r\n setMode: function (context, index: number): void {\r\n context.commit('setMode', index as number);\r\n },\r\n setIsActive: function (context, isActive: boolean): void {\r\n context.commit('setIsActive', isActive as boolean);\r\n },\r\n change: function (context, index: number): void {\r\n if (context.getters.mode === index) {\r\n context.dispatch('setIsActive', !context.getters.isActive);\r\n } else {\r\n context.dispatch('setIsActive', true);\r\n context.dispatch('setMode', index);\r\n }\r\n if (context.getters.isActive === true) {\r\n context.dispatch('reset');\r\n context.dispatch('loop', context.getters.patterns[context.getters.mode].pattern);\r\n } else {\r\n context.dispatch('reset');\r\n }\r\n },\r\n startCustom: function (context, pattern: TPatternUnit[]): void {\r\n context.dispatch('setIsActive', false);\r\n context.dispatch('setMode', 0);\r\n context.dispatch('reset');\r\n context.dispatch('loop', pattern);\r\n },\r\n },\r\n modules: {\r\n MGamepads: MGamepads,\r\n MPatterns: MPatterns,\r\n },\r\n});\r\n\r\nexport default store;\r\n\r\n","import { renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, resolveComponent as _resolveComponent, toDisplayString as _toDisplayString, createBlock as _createBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"content-item device-list\" }\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n const _component_GamepadItem = _resolveComponent(\"GamepadItem\")!\n\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1, [\n (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.gamepads, (gamepad) => {\n return (_openBlock(), _createBlock(_component_GamepadItem, {\n key: gamepad.id,\n textContent: _toDisplayString(gamepad.unit.id)\n }, null, 8, [\"textContent\"]))\n }), 128))\n ]))\n}","import { openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"list-item\" }\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1))\n}","\r\n import { defineComponent } from 'vue';\r\n\r\n export default defineComponent({\r\n name: 'GamepadItem',\r\n });\r\n","import { render } from \"./GamepadItem.vue?vue&type=template&id=7c902388&ts=true\"\nimport script from \"./GamepadItem.vue?vue&type=script&lang=ts\"\nexport * from \"./GamepadItem.vue?vue&type=script&lang=ts\"\n\nimport \"./GamepadItem.vue?vue&type=style&index=0&id=7c902388&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","\r\n import { defineComponent } from 'vue';\r\n import GamepadItem from '@/components/GamepadItem.vue';\r\n\r\n export default defineComponent({\r\n name: 'GamepadList',\r\n props: {\r\n gamepads: {\r\n type: Array,\r\n },\r\n },\r\n components: {\r\n GamepadItem: GamepadItem,\r\n },\r\n });\r\n","import { render } from \"./GamepadList.vue?vue&type=template&id=b6851174&ts=true\"\nimport script from \"./GamepadList.vue?vue&type=script&lang=ts\"\nexport * from \"./GamepadList.vue?vue&type=script&lang=ts\"\n\nimport \"./GamepadList.vue?vue&type=style&index=0&id=b6851174&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import { renderSlot as _renderSlot, createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"content-item message\" }\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1, [\n _createElementVNode(\"span\", null, [\n _renderSlot(_ctx.$slots, \"default\")\n ])\n ]))\n}","\r\n import { defineComponent } from 'vue';\r\n\r\n export default defineComponent({\r\n name: 'MessageItem',\r\n });\r\n","import { render } from \"./MessageItem.vue?vue&type=template&id=50d3c0d7&ts=true\"\nimport script from \"./MessageItem.vue?vue&type=script&lang=ts\"\nexport * from \"./MessageItem.vue?vue&type=script&lang=ts\"\n\nimport \"./MessageItem.vue?vue&type=style&index=0&id=50d3c0d7&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import { createTextVNode as _createTextVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, createVNode as _createVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"content-item navigation-list\" }\nconst _hoisted_2 = /*#__PURE__*/_createTextVNode(\"Patterns\")\nconst _hoisted_3 = /*#__PURE__*/_createTextVNode(\"Custom\")\nconst _hoisted_4 = /*#__PURE__*/_createTextVNode(\"Manual\")\nconst _hoisted_5 = /*#__PURE__*/_createTextVNode(\"Diagnostic\")\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n const _component_router_link = _resolveComponent(\"router-link\")!\n\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1, [\n _createVNode(_component_router_link, {\n to: \"/\",\n class: \"navigation-list__item\"\n }, {\n default: _withCtx(() => [\n _hoisted_2\n ]),\n _: 1\n }),\n _createVNode(_component_router_link, {\n to: \"/custom\",\n class: \"navigation-list__item\"\n }, {\n default: _withCtx(() => [\n _hoisted_3\n ]),\n _: 1\n }),\n _createVNode(_component_router_link, {\n to: \"/manual\",\n class: \"navigation-list__item\"\n }, {\n default: _withCtx(() => [\n _hoisted_4\n ]),\n _: 1\n }),\n _createVNode(_component_router_link, {\n to: \"/diagnostic\",\n class: \"navigation-list__item\"\n }, {\n default: _withCtx(() => [\n _hoisted_5\n ]),\n _: 1\n })\n ]))\n}","\r\n import { defineComponent } from 'vue';\r\n\r\n export default defineComponent({\r\n name: 'NavigationList',\r\n });\r\n","import { render } from \"./NavigationList.vue?vue&type=template&id=5b991a16&ts=true\"\nimport script from \"./NavigationList.vue?vue&type=script&lang=ts\"\nexport * from \"./NavigationList.vue?vue&type=script&lang=ts\"\n\nimport \"./NavigationList.vue?vue&type=style&index=0&id=5b991a16&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","var deferred = [];\n__webpack_require__.O = function(result, chunkIds, fn, priority) {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar chunkIds = deferred[i][0];\n\t\tvar fn = deferred[i][1];\n\t\tvar priority = deferred[i][2];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.f = {};\n// This file contains only the entry chunk.\n// The chunk loading function for additional chunks\n__webpack_require__.e = function(chunkId) {\n\treturn Promise.all(Object.keys(__webpack_require__.f).reduce(function(promises, key) {\n\t\t__webpack_require__.f[key](chunkId, promises);\n\t\treturn promises;\n\t}, []));\n};","// This function allow to reference async chunks\n__webpack_require__.u = function(chunkId) {\n\t// return url for filenames based on template\n\treturn \"js/\" + chunkId + \".\" + {\"66\":\"54b2ec35\",\"219\":\"4c3a113b\",\"531\":\"6af13e76\",\"582\":\"c3117d29\",\"645\":\"b32a0b62\",\"672\":\"270ec4e0\",\"807\":\"369d563e\"}[chunkId] + \".js\";\n};","// This function allow to reference async chunks\n__webpack_require__.miniCssF = function(chunkId) {\n\t// return url for filenames based on template\n\treturn \"css/\" + chunkId + \".\" + {\"66\":\"bb6440f7\",\"219\":\"19a8cda3\",\"582\":\"10b8ac32\",\"672\":\"278b2bb3\",\"807\":\"06b3a622\"}[chunkId] + \".css\";\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","var inProgress = {};\nvar dataWebpackPrefix = \"wavelovers:\";\n// loadScript function to load a script via script tag\n__webpack_require__.l = function(url, done, key, chunkId) {\n\tif(inProgress[url]) { inProgress[url].push(done); return; }\n\tvar script, needAttach;\n\tif(key !== undefined) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tfor(var i = 0; i < scripts.length; i++) {\n\t\t\tvar s = scripts[i];\n\t\t\tif(s.getAttribute(\"src\") == url || s.getAttribute(\"data-webpack\") == dataWebpackPrefix + key) { script = s; break; }\n\t\t}\n\t}\n\tif(!script) {\n\t\tneedAttach = true;\n\t\tscript = document.createElement('script');\n\n\t\tscript.charset = 'utf-8';\n\t\tscript.timeout = 120;\n\t\tif (__webpack_require__.nc) {\n\t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n\t\t}\n\t\tscript.setAttribute(\"data-webpack\", dataWebpackPrefix + key);\n\t\tscript.src = url;\n\t}\n\tinProgress[url] = [done];\n\tvar onScriptComplete = function(prev, event) {\n\t\t// avoid mem leaks in IE.\n\t\tscript.onerror = script.onload = null;\n\t\tclearTimeout(timeout);\n\t\tvar doneFns = inProgress[url];\n\t\tdelete inProgress[url];\n\t\tscript.parentNode && script.parentNode.removeChild(script);\n\t\tdoneFns && doneFns.forEach(function(fn) { return fn(event); });\n\t\tif(prev) return prev(event);\n\t}\n\t;\n\tvar timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);\n\tscript.onerror = onScriptComplete.bind(null, script.onerror);\n\tscript.onload = onScriptComplete.bind(null, script.onload);\n\tneedAttach && document.head.appendChild(script);\n};","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.p = \"/\";","var createStylesheet = function(chunkId, fullhref, resolve, reject) {\n\tvar linkTag = document.createElement(\"link\");\n\n\tlinkTag.rel = \"stylesheet\";\n\tlinkTag.type = \"text/css\";\n\tvar onLinkComplete = function(event) {\n\t\t// avoid mem leaks.\n\t\tlinkTag.onerror = linkTag.onload = null;\n\t\tif (event.type === 'load') {\n\t\t\tresolve();\n\t\t} else {\n\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n\t\t\tvar realHref = event && event.target && event.target.href || fullhref;\n\t\t\tvar err = new Error(\"Loading CSS chunk \" + chunkId + \" failed.\\n(\" + realHref + \")\");\n\t\t\terr.code = \"CSS_CHUNK_LOAD_FAILED\";\n\t\t\terr.type = errorType;\n\t\t\terr.request = realHref;\n\t\t\tlinkTag.parentNode.removeChild(linkTag)\n\t\t\treject(err);\n\t\t}\n\t}\n\tlinkTag.onerror = linkTag.onload = onLinkComplete;\n\tlinkTag.href = fullhref;\n\n\tdocument.head.appendChild(linkTag);\n\treturn linkTag;\n};\nvar findStylesheet = function(href, fullhref) {\n\tvar existingLinkTags = document.getElementsByTagName(\"link\");\n\tfor(var i = 0; i < existingLinkTags.length; i++) {\n\t\tvar tag = existingLinkTags[i];\n\t\tvar dataHref = tag.getAttribute(\"data-href\") || tag.getAttribute(\"href\");\n\t\tif(tag.rel === \"stylesheet\" && (dataHref === href || dataHref === fullhref)) return tag;\n\t}\n\tvar existingStyleTags = document.getElementsByTagName(\"style\");\n\tfor(var i = 0; i < existingStyleTags.length; i++) {\n\t\tvar tag = existingStyleTags[i];\n\t\tvar dataHref = tag.getAttribute(\"data-href\");\n\t\tif(dataHref === href || dataHref === fullhref) return tag;\n\t}\n};\nvar loadStylesheet = function(chunkId) {\n\treturn new Promise(function(resolve, reject) {\n\t\tvar href = __webpack_require__.miniCssF(chunkId);\n\t\tvar fullhref = __webpack_require__.p + href;\n\t\tif(findStylesheet(href, fullhref)) return resolve();\n\t\tcreateStylesheet(chunkId, fullhref, resolve, reject);\n\t});\n}\n// object to store loaded CSS chunks\nvar installedCssChunks = {\n\t143: 0\n};\n\n__webpack_require__.f.miniCss = function(chunkId, promises) {\n\tvar cssChunks = {\"66\":1,\"219\":1,\"582\":1,\"672\":1,\"807\":1};\n\tif(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]);\n\telse if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) {\n\t\tpromises.push(installedCssChunks[chunkId] = loadStylesheet(chunkId).then(function() {\n\t\t\tinstalledCssChunks[chunkId] = 0;\n\t\t}, function(e) {\n\t\t\tdelete installedCssChunks[chunkId];\n\t\t\tthrow e;\n\t\t}));\n\t}\n};\n\n// no hmr","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t143: 0\n};\n\n__webpack_require__.f.j = function(chunkId, promises) {\n\t\t// JSONP chunk loading for javascript\n\t\tvar installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;\n\t\tif(installedChunkData !== 0) { // 0 means \"already installed\".\n\n\t\t\t// a Promise means \"currently loading\".\n\t\t\tif(installedChunkData) {\n\t\t\t\tpromises.push(installedChunkData[2]);\n\t\t\t} else {\n\t\t\t\tif(true) { // all chunks have JS\n\t\t\t\t\t// setup Promise in chunk cache\n\t\t\t\t\tvar promise = new Promise(function(resolve, reject) { installedChunkData = installedChunks[chunkId] = [resolve, reject]; });\n\t\t\t\t\tpromises.push(installedChunkData[2] = promise);\n\n\t\t\t\t\t// start chunk loading\n\t\t\t\t\tvar url = __webpack_require__.p + __webpack_require__.u(chunkId);\n\t\t\t\t\t// create error before stack unwound to get useful stacktrace later\n\t\t\t\t\tvar error = new Error();\n\t\t\t\t\tvar loadingEnded = function(event) {\n\t\t\t\t\t\tif(__webpack_require__.o(installedChunks, chunkId)) {\n\t\t\t\t\t\t\tinstalledChunkData = installedChunks[chunkId];\n\t\t\t\t\t\t\tif(installedChunkData !== 0) installedChunks[chunkId] = undefined;\n\t\t\t\t\t\t\tif(installedChunkData) {\n\t\t\t\t\t\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n\t\t\t\t\t\t\t\tvar realSrc = event && event.target && event.target.src;\n\t\t\t\t\t\t\t\terror.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';\n\t\t\t\t\t\t\t\terror.name = 'ChunkLoadError';\n\t\t\t\t\t\t\t\terror.type = errorType;\n\t\t\t\t\t\t\t\terror.request = realSrc;\n\t\t\t\t\t\t\t\tinstalledChunkData[1](error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\t__webpack_require__.l(url, loadingEnded, \"chunk-\" + chunkId, chunkId);\n\t\t\t\t} else installedChunks[chunkId] = 0;\n\t\t\t}\n\t\t}\n};\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; };\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = function(parentChunkLoadingFunction, data) {\n\tvar chunkIds = data[0];\n\tvar moreModules = data[1];\n\tvar runtime = data[2];\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunkwavelovers\"] = self[\"webpackChunkwavelovers\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [998], function() { return __webpack_require__(1592); })\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["_hoisted_1","class","_hoisted_2","render","_ctx","_cache","$props","$setup","$data","$options","_component_HeaderItem","_resolveComponent","_component_router_view","_component_FooterItem","_openBlock","_createElementBlock","_Fragment","_createVNode","_createElementVNode","_hoisted_3","translate","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_createTextVNode","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_component_router_link","to","default","_withCtx","_","defineComponent","name","__exports__","_createStaticVNode","components","HeaderItem","FooterItem","methods","addGamepad","event","store","deleteGamepad","addEventListeners","window","addEventListener","this","removeEventListeners","removeEventListener","mounted","unmounted","_component_AppPatterns","_component_NavigationList","_component_PatternList","_component_MessageItem","_component_GamepadList","patterns","length","_createBlock","key","mode","isActive","onChange","change","gamepads","_component_PatternItem","_renderList","pattern","index","onClick","$event","_normalizeClass","textContent","_toDisplayString","icon","type","props","Object","Number","Boolean","$emit","Array","PatternItem","PatternList","NavigationList","GamepadList","MessageItem","computed","AppPatterns","updateRoute","from","next","fullPath","router","QueryRouter","update","appendTags","tagsArray","map","meta","tag","document","createElement","keys","forEach","setAttribute","head","appendChild","updateMetatag","nearestWithTitle","matched","slice","reverse","find","r","title","nearestWithMeta","metaTags","linkTags","querySelectorAll","el","parentNode","removeChild","MetaTagUpdater","routes","path","component","PatternsView","content","rel","href","redirect","createRouter","history","createWebHistory","process","beforeEach","createApp","App","use","mount","Vibrator","constructor","unit","id","Date","now","canVibrate","vibrationActuator","isVibrating","bind","interval","setInterval","navigator","getGamepads","offsetTime","i","vibrate","sleep","startDelay","duration","playEffect","reset","ms","Promise","resolve","setTimeout","MGamepads","state","getters","mutations","gamepad","push","splice","actions","context","iEvent","commit","loop","MPatterns","setPatterns","loadPatterns","async","url","response","fetch","ok","json","console","log","error","createStore","setMode","setIsActive","dispatch","startCustom","modules","_component_GamepadItem","GamepadItem","_renderSlot","$slots","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","module","__webpack_modules__","m","deferred","O","result","chunkIds","fn","priority","notFulfilled","Infinity","fulfilled","j","every","n","getter","__esModule","d","a","definition","o","defineProperty","enumerable","get","f","e","chunkId","all","reduce","promises","u","miniCssF","g","globalThis","Function","obj","prop","prototype","hasOwnProperty","call","inProgress","dataWebpackPrefix","l","done","script","needAttach","scripts","getElementsByTagName","s","getAttribute","charset","timeout","nc","src","onScriptComplete","prev","onerror","onload","clearTimeout","doneFns","target","Symbol","toStringTag","value","p","createStylesheet","fullhref","reject","linkTag","onLinkComplete","errorType","realHref","err","Error","code","request","findStylesheet","existingLinkTags","dataHref","existingStyleTags","loadStylesheet","installedCssChunks","miniCss","cssChunks","then","installedChunks","installedChunkData","promise","loadingEnded","realSrc","message","webpackJsonpCallback","parentChunkLoadingFunction","data","moreModules","runtime","some","chunkLoadingGlobal","self","__webpack_exports__"],"sourceRoot":""} \ No newline at end of file diff --git a/docs/js/app.9a519cb2.js b/docs/js/app.9a519cb2.js new file mode 100644 index 0000000..e6a6737 --- /dev/null +++ b/docs/js/app.9a519cb2.js @@ -0,0 +1,2 @@ +(function(){"use strict";var e={2368:function(e,t,a){var n=a(9242),o=a(3396);const r={class:"page container"},i={class:"wavelovers"};function s(e,t,a,n,s,c){const d=(0,o.up)("HeaderItem"),u=(0,o.up)("router-view"),m=(0,o.up)("FooterItem");return(0,o.wg)(),(0,o.iD)(o.HY,null,[(0,o.Wm)(d),(0,o._)("main",r,[(0,o._)("div",i,[(0,o.Wm)(u)])]),(0,o.Wm)(m)],64)}var c=a(1746);const d={class:"header"},u={class:"header-wrapper container"},m=(0,o._)("div",{class:"logo-wrapper"},[(0,o._)("span",{class:"logo-wrapper__logo",translate:"no"},"Wavelovers")],-1),l={class:"menu-wrapper"},v={class:"navigation"},p={class:"navigation__item"},g=(0,o.Uk)("Home"),f={class:"navigation__item"},h=(0,o.Uk)("FAQ"),b={class:"navigation__item"},w=(0,o.Uk)("About"),y={class:"navigation__item"},W=(0,o.Uk)("Donate");function k(e,t,a,n,r,i){const s=(0,o.up)("router-link");return(0,o.wg)(),(0,o.iD)("header",d,[(0,o._)("div",u,[m,(0,o._)("nav",l,[(0,o._)("ul",v,[(0,o._)("li",p,[(0,o.Wm)(s,{to:"/"},{default:(0,o.w5)((()=>[g])),_:1})]),(0,o._)("li",f,[(0,o.Wm)(s,{to:"/faq"},{default:(0,o.w5)((()=>[h])),_:1})]),(0,o._)("li",b,[(0,o.Wm)(s,{to:"/about"},{default:(0,o.w5)((()=>[w])),_:1})]),(0,o._)("li",y,[(0,o.Wm)(s,{to:"/donate"},{default:(0,o.w5)((()=>[W])),_:1})])])])])])}var _=(0,o.aZ)({name:"HeaderItem"}),V=a(89);const G=(0,V.Z)(_,[["render",k]]);var M=G;const A={class:"footer"},T=(0,o.uE)('',1),P=[T];function Z(e,t,a,n,r,i){return(0,o.wg)(),(0,o.iD)("footer",A,P)}var C=(0,o.aZ)({name:"FooterItem"});const E=(0,V.Z)(C,[["render",Z]]);var L=E,x=(0,o.aZ)({name:"App",components:{HeaderItem:M,FooterItem:L},methods:{addGamepad:function(e){c.Z.dispatch("addGamepad",e)},deleteGamepad:function(e){c.Z.dispatch("deleteGamepad",e)},addEventListeners:function(){window.addEventListener("gamepadconnected",this.addGamepad),window.addEventListener("gamepaddisconnected",this.deleteGamepad)},removeEventListeners:function(){window.removeEventListener("gamepadconnected",this.addGamepad),window.removeEventListener("gamepaddisconnected",this.deleteGamepad)}},mounted(){this.addEventListeners()},unmounted(){this.removeEventListeners()}});const D=(0,V.Z)(x,[["render",s]]);var I=D,j=a(2483);const U=(0,o._)("h1",{class:"visually-hidden"},"Wavelovers",-1);function q(e,t,a,n,r,i){const s=(0,o.up)("AppPatterns");return(0,o.wg)(),(0,o.iD)(o.HY,null,[U,(0,o.Wm)(s)],64)}const S={class:"app-patterns"},O=(0,o.Uk)("Loading..."),N=(0,o.Uk)("Press any gamepad button or connect a new gamepad to vibrate.");function F(e,t,a,n,r,i){const s=(0,o.up)("NavigationList"),c=(0,o.up)("PatternList"),d=(0,o.up)("MessageItem"),u=(0,o.up)("GamepadList");return(0,o.wg)(),(0,o.iD)(o.HY,null,[(0,o.Wm)(s),(0,o._)("div",S,[e.patterns.length>0?((0,o.wg)(),(0,o.j4)(c,{key:0,patterns:e.patterns,mode:e.mode,isActive:e.isActive,onChange:e.change},null,8,["patterns","mode","isActive","onChange"])):((0,o.wg)(),(0,o.j4)(d,{key:1},{default:(0,o.w5)((()=>[O])),_:1}))]),e.gamepads.length>0?((0,o.wg)(),(0,o.j4)(u,{key:0,gamepads:e.gamepads},null,8,["gamepads"])):((0,o.wg)(),(0,o.j4)(d,{key:1},{default:(0,o.w5)((()=>[N])),_:1}))],64)}var z=a(4246),H=a(3375),R=a(9808);const B={class:"content-item pattern-list"};function Q(e,t,a,n,r,i){const s=(0,o.up)("PatternItem");return(0,o.wg)(),(0,o.iD)("div",B,[((0,o.wg)(!0),(0,o.iD)(o.HY,null,(0,o.Ko)(e.patterns,((t,a)=>((0,o.wg)(),(0,o.j4)(s,{key:t.name,pattern:t,index:a,mode:e.mode,isActive:e.isActive,onChange:e.change},null,8,["pattern","index","mode","isActive","onChange"])))),128))])}var Y=a(7139);const K=["textContent"],$={class:"pattern-item__info-container"},J=["textContent"],X=["textContent"];function ee(e,t,a,n,r,i){return(0,o.wg)(),(0,o.iD)("div",{onClick:t[0]||(t[0]=t=>e.change(e.index)),class:(0,Y.C_)(["pattern-item",e.index===e.mode&&!0===e.isActive?"pattern-item_selected":""])},[(0,o._)("span",{class:"pattern-item__icon",textContent:(0,Y.zw)(e.pattern.icon)},null,8,K),(0,o._)("div",$,[(0,o._)("span",{class:"pattern-item__name",textContent:(0,Y.zw)(e.pattern.name)},null,8,J),(0,o._)("span",{class:"pattern-item__type",textContent:(0,Y.zw)(e.pattern.type)},null,8,X)])],2)}var te=(0,o.aZ)({name:"PatternItem",props:{pattern:{type:Object},index:{type:Number},mode:{type:Number},isActive:{type:Boolean}},methods:{change:function(e){this.$emit("change",e)}}});const ae=(0,V.Z)(te,[["render",ee]]);var ne=ae,oe=(0,o.aZ)({name:"PatternList",props:{patterns:{type:Array},mode:{type:Number},isActive:{type:Boolean}},components:{PatternItem:ne},methods:{change:function(e){this.$emit("change",e)}}});const re=(0,V.Z)(oe,[["render",Q]]);var ie=re,se=(0,o.aZ)({name:"AppPatterns",components:{PatternList:ie,NavigationList:z.Z,GamepadList:H.Z,MessageItem:R.Z},computed:{gamepads:function(){return c.Z.getters.gamepads},patterns:function(){return c.Z.getters.patterns},mode:function(){return c.Z.getters.mode},isActive:function(){return c.Z.getters.isActive}},methods:{change(e){c.Z.dispatch("change",e)}},mounted(){c.Z.dispatch("loadPatterns")}});const ce=(0,V.Z)(se,[["render",F]]);var de=ce,ue=(0,o.aZ)({name:"PatternsView",components:{AppPatterns:de}});const me=(0,V.Z)(ue,[["render",q]]);var le=me;function ve(e,t,a,n){return n.forEach((t=>{t.query===e.fullPath&&Ve.push(t.to)})),a()}const pe={update:ve};var ge=pe;function fe(e,t){e.map((e=>{const a=document.createElement(t);return Object.keys(e).forEach((t=>{a.setAttribute(t,e[t])})),a.setAttribute("data-vue-router-controlled",""),a})).forEach((e=>document.head.appendChild(e)))}function he(e,t,a){const n=e.matched.slice().reverse().find((e=>e.meta&&e.meta.title)),o=e.matched.slice().reverse().find((e=>e.meta&&e.meta.metaTags&&e.meta.linkTags));if(n&&(document.title=n.meta.title),Array.from(document.querySelectorAll("[data-vue-router-controlled]")).map((e=>{e.parentNode&&e.parentNode.removeChild(e)})),!o)return a();const r=o.meta.linkTags,i=o.meta.metaTags;return fe(r,"link"),fe(i,"meta"),a()}const be={update:he};var we=be;const ye=[{query:"/?custom",to:"/custom"},{query:"/?manual",to:"/manual"},{query:"/?diagnostic",to:"/diagnostic"},{query:"/?faq",to:"/faq"},{query:"/?about",to:"/about"},{query:"/?donate",to:"/donate"}];var We=ye;const ke=[{path:"/",name:"patterns-view",component:le,meta:{title:"Wavelovers",metaTags:[{name:"keywords",content:"Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона"},{name:"description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."},{name:"og:title",content:"Wavelovers"},{name:"og:description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."},{name:"og:url",content:"https://wavelovers.ru/"},{name:"twitter:title",content:"Wavelovers"},{name:"twitter:description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."}],linkTags:[{rel:"canonical",href:"https://wavelovers.ru/"}]}},{path:"/custom",name:"custom-view",component:()=>a.e(219).then(a.bind(a,219)),meta:{title:"Wavelovers – Custom",metaTags:[{name:"keywords",content:"Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона"},{name:"description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."},{name:"og:title",content:"Wavelovers – Custom"},{name:"og:description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."},{name:"og:url",content:"https://wavelovers.ru/custom"},{name:"twitter:title",content:"Wavelovers – Custom"},{name:"twitter:description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."}],linkTags:[{rel:"canonical",href:"https://wavelovers.ru/custom"}]}},{path:"/manual",name:"manual-view",component:()=>a.e(807).then(a.bind(a,6807)),meta:{title:"Wavelovers – Manual",metaTags:[{name:"keywords",content:"Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона"},{name:"description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."},{name:"og:title",content:"Wavelovers – Manual"},{name:"og:description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."},{name:"og:url",content:"https://wavelovers.ru/manual"},{name:"twitter:title",content:"Wavelovers – Manual"},{name:"twitter:description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."}],linkTags:[{rel:"canonical",href:"https://wavelovers.ru/manual"}]}},{path:"/diagnostic",name:"diagnostic-view",component:()=>a.e(582).then(a.bind(a,6582)),meta:{title:"Wavelovers – Diagnostic",metaTags:[{name:"keywords",content:"Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона"},{name:"description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."},{name:"og:title",content:"Wavelovers – Diagnostic"},{name:"og:description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."},{name:"og:url",content:"https://wavelovers.ru/diagnostic"},{name:"twitter:title",content:"Wavelovers – Diagnostic"},{name:"twitter:description",content:"Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad."}],linkTags:[{rel:"canonical",href:"https://wavelovers.ru/diagnostic"}]}},{path:"/faq",name:"faq-view",component:()=>a.e(645).then(a.bind(a,645)),meta:{title:"Wavelovers – FAQ",metaTags:[{name:"keywords",content:"Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, FAQ, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона, часто задаваемые вопросы"},{name:"description",content:"Wavelovers. Frequently asked questions page."},{name:"og:title",content:"Wavelovers – FAQ"},{name:"og:description",content:"Wavelovers. Frequently asked questions page."},{name:"og:url",content:"https://wavelovers.ru/faq"},{name:"twitter:title",content:"Wavelovers – FAQ"},{name:"twitter:description",content:"Wavelovers. Frequently asked questions page."}],linkTags:[{rel:"canonical",href:"https://wavelovers.ru/faq"}]}},{path:"/about",name:"about-view",component:()=>a.e(672).then(a.bind(a,2672)),meta:{title:"Wavelovers – About",metaTags:[{name:"keywords",content:"Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, advertise, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона, реклама"},{name:"description",content:"Wavelovers. Page with information about the project and data on donations."},{name:"og:title",content:"Wavelovers – About"},{name:"og:description",content:"Wavelovers. Page with information about the project and data on donations."},{name:"og:url",content:"https://wavelovers.ru/about"},{name:"twitter:title",content:"Wavelovers – About"},{name:"twitter:description",content:"Wavelovers. Page with information about the project and data on donations."}],linkTags:[{rel:"canonical",href:"https://wavelovers.ru/about"}]}},{path:"/donate",name:"donate-view",component:()=>a.e(66).then(a.bind(a,1066)),meta:{title:"Wavelovers – Donate",metaTags:[{name:"keywords",content:"Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, Donate, Support, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона, задонатить, пожертвовать, помочь, поблагодарить"},{name:"description",content:"Wavelovers. Donate to the author."},{name:"og:title",content:"Wavelovers – Donate"},{name:"og:description",content:"Wavelovers. Donate to the author."},{name:"og:url",content:"https://wavelovers.ru/donate"},{name:"twitter:title",content:"Wavelovers – Donate"},{name:"twitter:description",content:"Wavelovers. Donate to the author."}],linkTags:[{rel:"canonical",href:"https://wavelovers.ru/donate"}]}},{path:"/404",name:"404",component:()=>a.e(531).then(a.bind(a,4066)),meta:{title:"Wavelovers – Page not found",metaTags:[{name:"og:title",content:"Wavelovers – Page not found"},{name:"og:url",content:"https://wavelovers.ru/404"}],linkTags:[{rel:"canonical",href:"https://wavelovers.ru/404"}]}},{path:"/:catchAll(.*)*",redirect:"/404"}],_e=(0,j.p7)({history:(0,j.PO)("/"),routes:ke});_e.beforeEach(((e,t,a)=>{ge.update(e,t,a,We),we.update(e,t,a)}));var Ve=_e;(0,n.ri)(I).use(c.Z).use(Ve).mount("#app")},1746:function(e,t,a){a.d(t,{Z:function(){return l}});var n=a(65),o=a(2482);class r{constructor(e){(0,o.Z)(this,"unit",void 0),(0,o.Z)(this,"id",void 0),(0,o.Z)(this,"canVibrate",void 0),(0,o.Z)(this,"isVibrating",void 0),(0,o.Z)(this,"interval",void 0),this.unit=e,this.id=Date.now(),this.canVibrate=!!this.unit.vibrationActuator,this.isVibrating=!1,this.update=this.update.bind(this),this.interval=setInterval(this.update,1)}update(){const e=navigator.getGamepads();this.unit=e[this.unit.index]}async loop(e){this.isVibrating=!0;const t=10;while(!0===this.isVibrating)for(let a=0;asetTimeout(t,e)))}}var i=r;const s={state:()=>({gamepads:[]}),getters:{gamepads:function(e){return e.gamepads}},mutations:{addGamepad:function(e,t){e.gamepads.push(t)},deleteGamepad:function(e,t){e.gamepads.splice(t,1)}},actions:{addGamepad:function(e,t){const a=t;e.getters.gamepads.length>=1||e.commit("addGamepad",new i(a.gamepad))},deleteGamepad:function(e,t){e.getters.gamepads.forEach(((a,n)=>{a.unit.id===t.gamepad.id&&e.commit("deleteGamepad",n)}))},loop:function(e,t){e.getters.gamepads.forEach((e=>{e.loop(t)}))},vibrate:function(e,t){e.getters.gamepads.forEach((e=>{e.vibrate(t)}))},reset:function(e){e.getters.gamepads.forEach((e=>{e.reset()}))}}};var c=s;const d={state:()=>({patterns:[]}),getters:{patterns:function(e){return e.patterns}},mutations:{setPatterns:function(e,t){e.patterns=t}},actions:{loadPatterns:async function(e){const t="https://wavelovers.ru/assets/patterns.json";try{const a=await fetch(t);if(a.ok){const t=await a.json();e.commit("setPatterns",t)}else console.log("Connect to the Internet for download more patterns...")}catch(a){console.log(a)}}}};var u=d;const m=(0,n.MT)({state:()=>({mode:0,isActive:!1}),getters:{mode:function(e){return e.mode},isActive:function(e){return e.isActive}},mutations:{setMode:function(e,t){e.mode=t},setIsActive:function(e,t){e.isActive=t}},actions:{setMode:function(e,t){e.commit("setMode",t)},setIsActive:function(e,t){e.commit("setIsActive",t)},change:function(e,t){e.getters.mode===t?e.dispatch("setIsActive",!e.getters.isActive):(e.dispatch("setIsActive",!0),e.dispatch("setMode",t)),!0===e.getters.isActive?(e.dispatch("reset"),e.dispatch("loop",e.getters.patterns[e.getters.mode].pattern)):e.dispatch("reset")},startCustom:function(e,t){e.dispatch("setIsActive",!1),e.dispatch("setMode",0),e.dispatch("reset"),e.dispatch("loop",t)}},modules:{MGamepads:c,MPatterns:u}});var l=m},3375:function(e,t,a){a.d(t,{Z:function(){return g}});var n=a(3396),o=a(7139);const r={class:"content-item device-list"};function i(e,t,a,i,s,c){const d=(0,n.up)("GamepadItem");return(0,n.wg)(),(0,n.iD)("div",r,[((0,n.wg)(!0),(0,n.iD)(n.HY,null,(0,n.Ko)(e.gamepads,(e=>((0,n.wg)(),(0,n.j4)(d,{key:e.id,textContent:(0,o.zw)(e.unit.id)},null,8,["textContent"])))),128))])}const s={class:"list-item"};function c(e,t,a,o,r,i){return(0,n.wg)(),(0,n.iD)("div",s)}var d=(0,n.aZ)({name:"GamepadItem"}),u=a(89);const m=(0,u.Z)(d,[["render",c]]);var l=m,v=(0,n.aZ)({name:"GamepadList",props:{gamepads:{type:Array}},components:{GamepadItem:l}});const p=(0,u.Z)(v,[["render",i]]);var g=p},9808:function(e,t,a){a.d(t,{Z:function(){return d}});var n=a(3396);const o={class:"content-item message"};function r(e,t,a,r,i,s){return(0,n.wg)(),(0,n.iD)("div",o,[(0,n._)("span",null,[(0,n.WI)(e.$slots,"default")])])}var i=(0,n.aZ)({name:"MessageItem"}),s=a(89);const c=(0,s.Z)(i,[["render",r]]);var d=c},4246:function(e,t,a){a.d(t,{Z:function(){return v}});var n=a(3396);const o={class:"content-item navigation-list"},r=(0,n.Uk)("Patterns"),i=(0,n.Uk)("Custom"),s=(0,n.Uk)("Manual"),c=(0,n.Uk)("Diagnostic");function d(e,t,a,d,u,m){const l=(0,n.up)("router-link");return(0,n.wg)(),(0,n.iD)("div",o,[(0,n.Wm)(l,{to:"/",class:"navigation-list__item"},{default:(0,n.w5)((()=>[r])),_:1}),(0,n.Wm)(l,{to:"/custom",class:"navigation-list__item"},{default:(0,n.w5)((()=>[i])),_:1}),(0,n.Wm)(l,{to:"/manual",class:"navigation-list__item"},{default:(0,n.w5)((()=>[s])),_:1}),(0,n.Wm)(l,{to:"/diagnostic",class:"navigation-list__item"},{default:(0,n.w5)((()=>[c])),_:1})])}var u=(0,n.aZ)({name:"NavigationList"}),m=a(89);const l=(0,m.Z)(u,[["render",d]]);var v=l}},t={};function a(n){var o=t[n];if(void 0!==o)return o.exports;var r=t[n]={exports:{}};return e[n](r,r.exports,a),r.exports}a.m=e,function(){var e=[];a.O=function(t,n,o,r){if(!n){var i=1/0;for(u=0;u=r)&&Object.keys(a.O).every((function(e){return a.O[e](n[c])}))?n.splice(c--,1):(s=!1,r0&&e[u-1][2]>r;u--)e[u]=e[u-1];e[u]=[n,o,r]}}(),function(){a.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return a.d(t,{a:t}),t}}(),function(){a.d=function(e,t){for(var n in t)a.o(t,n)&&!a.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})}}(),function(){a.f={},a.e=function(e){return Promise.all(Object.keys(a.f).reduce((function(t,n){return a.f[n](e,t),t}),[]))}}(),function(){a.u=function(e){return"js/"+e+"."+{66:"54b2ec35",219:"4c3a113b",531:"6af13e76",582:"c3117d29",645:"b32a0b62",672:"270ec4e0",807:"369d563e"}[e]+".js"}}(),function(){a.miniCssF=function(e){return"css/"+e+"."+{66:"bb6440f7",219:"19a8cda3",582:"10b8ac32",672:"278b2bb3",807:"06b3a622"}[e]+".css"}}(),function(){a.g=function(){if("object"===typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"===typeof window)return window}}()}(),function(){a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}}(),function(){var e={},t="wavelovers:";a.l=function(n,o,r,i){if(e[n])e[n].push(o);else{var s,c;if(void 0!==r)for(var d=document.getElementsByTagName("script"),u=0;u [\n _hoisted_7\n ]),\n _: 1\n })\n ]),\n _createElementVNode(\"li\", _hoisted_8, [\n _createVNode(_component_router_link, { to: \"/faq\" }, {\n default: _withCtx(() => [\n _hoisted_9\n ]),\n _: 1\n })\n ]),\n _createElementVNode(\"li\", _hoisted_10, [\n _createVNode(_component_router_link, { to: \"/about\" }, {\n default: _withCtx(() => [\n _hoisted_11\n ]),\n _: 1\n })\n ]),\n _createElementVNode(\"li\", _hoisted_12, [\n _createVNode(_component_router_link, { to: \"/donate\" }, {\n default: _withCtx(() => [\n _hoisted_13\n ]),\n _: 1\n })\n ])\n ])\n ])\n ])\n ]))\n}","\r\n import { defineComponent } from 'vue';\r\n\r\n export default defineComponent({\r\n name: 'HeaderItem',\r\n });\r\n","import { render } from \"./HeaderItem.vue?vue&type=template&id=27217e3d&ts=true\"\nimport script from \"./HeaderItem.vue?vue&type=script&lang=ts\"\nexport * from \"./HeaderItem.vue?vue&type=script&lang=ts\"\n\nimport \"./HeaderItem.vue?vue&type=style&index=0&id=27217e3d&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import { createElementVNode as _createElementVNode, createStaticVNode as _createStaticVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"footer\" }\nconst _hoisted_2 = /*#__PURE__*/_createStaticVNode(\"
© 2022 Wavelovers. Content licensed under GNU General Public License v3.0
This site is open source. Improve this page.
Created byEugene Serb
\", 1)\nconst _hoisted_3 = [\n _hoisted_2\n]\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n return (_openBlock(), _createElementBlock(\"footer\", _hoisted_1, _hoisted_3))\n}","\r\n import { defineComponent } from 'vue';\r\n\r\n export default defineComponent({\r\n name: 'FooterItem',\r\n });\r\n","import { render } from \"./FooterItem.vue?vue&type=template&id=494b1bc6&ts=true\"\nimport script from \"./FooterItem.vue?vue&type=script&lang=ts\"\nexport * from \"./FooterItem.vue?vue&type=script&lang=ts\"\n\nimport \"./FooterItem.vue?vue&type=style&index=0&id=494b1bc6&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","\r\n import { defineComponent } from 'vue';\r\n import store from '@/store/index';\r\n import HeaderItem from '@/components/HeaderItem.vue';\r\n import FooterItem from '@/components/FooterItem.vue';\r\n\r\n export default defineComponent({\r\n name: 'App',\r\n components: {\r\n HeaderItem: HeaderItem,\r\n FooterItem: FooterItem,\r\n },\r\n methods: {\r\n addGamepad: function (event: GamepadEvent): void {\r\n store.dispatch('addGamepad', event);\r\n },\r\n deleteGamepad: function (event: GamepadEvent): void {\r\n store.dispatch('deleteGamepad', event);\r\n },\r\n addEventListeners: function (): void {\r\n window.addEventListener('gamepadconnected', this.addGamepad);\r\n window.addEventListener('gamepaddisconnected', this.deleteGamepad);\r\n },\r\n removeEventListeners: function (): void {\r\n window.removeEventListener('gamepadconnected', this.addGamepad);\r\n window.removeEventListener('gamepaddisconnected', this.deleteGamepad);\r\n },\r\n },\r\n mounted() {\r\n this.addEventListeners();\r\n },\r\n unmounted() {\r\n this.removeEventListeners();\r\n },\r\n });\r\n","import { render } from \"./App.vue?vue&type=template&id=d319ea34&ts=true\"\nimport script from \"./App.vue?vue&type=script&lang=ts\"\nexport * from \"./App.vue?vue&type=script&lang=ts\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import { createElementVNode as _createElementVNode, resolveComponent as _resolveComponent, createVNode as _createVNode, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = /*#__PURE__*/_createElementVNode(\"h1\", { class: \"visually-hidden\" }, \"Wavelovers\", -1)\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n const _component_AppPatterns = _resolveComponent(\"AppPatterns\")!\n\n return (_openBlock(), _createElementBlock(_Fragment, null, [\n _hoisted_1,\n _createVNode(_component_AppPatterns)\n ], 64))\n}","import { resolveComponent as _resolveComponent, createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock, createCommentVNode as _createCommentVNode, createTextVNode as _createTextVNode, withCtx as _withCtx, createElementVNode as _createElementVNode, Fragment as _Fragment, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"app-patterns\" }\nconst _hoisted_2 = /*#__PURE__*/_createTextVNode(\"Loading...\")\nconst _hoisted_3 = /*#__PURE__*/_createTextVNode(\"Press any gamepad button or connect a new gamepad to vibrate.\")\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n const _component_NavigationList = _resolveComponent(\"NavigationList\")!\n const _component_PatternList = _resolveComponent(\"PatternList\")!\n const _component_MessageItem = _resolveComponent(\"MessageItem\")!\n const _component_GamepadList = _resolveComponent(\"GamepadList\")!\n\n return (_openBlock(), _createElementBlock(_Fragment, null, [\n _createVNode(_component_NavigationList),\n _createElementVNode(\"div\", _hoisted_1, [\n (_ctx.patterns.length > 0)\n ? (_openBlock(), _createBlock(_component_PatternList, {\n key: 0,\n patterns: _ctx.patterns,\n mode: _ctx.mode,\n isActive: _ctx.isActive,\n onChange: _ctx.change\n }, null, 8, [\"patterns\", \"mode\", \"isActive\", \"onChange\"]))\n : (_openBlock(), _createBlock(_component_MessageItem, { key: 1 }, {\n default: _withCtx(() => [\n _hoisted_2\n ]),\n _: 1\n }))\n ]),\n (_ctx.gamepads.length > 0)\n ? (_openBlock(), _createBlock(_component_GamepadList, {\n key: 0,\n gamepads: _ctx.gamepads\n }, null, 8, [\"gamepads\"]))\n : (_openBlock(), _createBlock(_component_MessageItem, { key: 1 }, {\n default: _withCtx(() => [\n _hoisted_3\n ]),\n _: 1\n }))\n ], 64))\n}","import { renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, resolveComponent as _resolveComponent, createBlock as _createBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"content-item pattern-list\" }\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n const _component_PatternItem = _resolveComponent(\"PatternItem\")!\n\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1, [\n (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.patterns, (pattern, index) => {\n return (_openBlock(), _createBlock(_component_PatternItem, {\n key: pattern.name,\n pattern: pattern,\n index: index,\n mode: _ctx.mode,\n isActive: _ctx.isActive,\n onChange: _ctx.change\n }, null, 8, [\"pattern\", \"index\", \"mode\", \"isActive\", \"onChange\"]))\n }), 128))\n ]))\n}","import { toDisplayString as _toDisplayString, createElementVNode as _createElementVNode, normalizeClass as _normalizeClass, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = [\"textContent\"]\nconst _hoisted_2 = { class: \"pattern-item__info-container\" }\nconst _hoisted_3 = [\"textContent\"]\nconst _hoisted_4 = [\"textContent\"]\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n return (_openBlock(), _createElementBlock(\"div\", {\n onClick: _cache[0] || (_cache[0] = ($event: any) => (_ctx.change(_ctx.index))),\n class: _normalizeClass(['pattern-item',\r\n _ctx.index === _ctx.mode && _ctx.isActive === true ?\r\n 'pattern-item_selected' : '',\r\n ])\n }, [\n _createElementVNode(\"span\", {\n class: \"pattern-item__icon\",\n textContent: _toDisplayString(_ctx.pattern.icon)\n }, null, 8, _hoisted_1),\n _createElementVNode(\"div\", _hoisted_2, [\n _createElementVNode(\"span\", {\n class: \"pattern-item__name\",\n textContent: _toDisplayString(_ctx.pattern.name)\n }, null, 8, _hoisted_3),\n _createElementVNode(\"span\", {\n class: \"pattern-item__type\",\n textContent: _toDisplayString(_ctx.pattern.type)\n }, null, 8, _hoisted_4)\n ])\n ], 2))\n}","\r\n import { defineComponent } from 'vue';\r\n\r\n export default defineComponent({\r\n name: 'PatternItem',\r\n props: {\r\n pattern: {\r\n type: Object,\r\n },\r\n index: {\r\n type: Number,\r\n },\r\n mode: {\r\n type: Number,\r\n },\r\n isActive: {\r\n type: Boolean,\r\n },\r\n },\r\n methods: {\r\n change: function (index: number): void {\r\n this.$emit('change', index as number);\r\n },\r\n },\r\n });\r\n","import { render } from \"./PatternItem.vue?vue&type=template&id=81514550&ts=true\"\nimport script from \"./PatternItem.vue?vue&type=script&lang=ts\"\nexport * from \"./PatternItem.vue?vue&type=script&lang=ts\"\n\nimport \"./PatternItem.vue?vue&type=style&index=0&id=81514550&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","\r\n import { defineComponent } from 'vue';\r\n import PatternItem from '@/components/PatternItem.vue';\r\n\r\n export default defineComponent({\r\n name: 'PatternList',\r\n props: {\r\n patterns: {\r\n type: Array,\r\n },\r\n mode: {\r\n type: Number,\r\n },\r\n isActive: {\r\n type: Boolean,\r\n },\r\n },\r\n components: {\r\n PatternItem: PatternItem,\r\n },\r\n methods: {\r\n change: function (index: number): void {\r\n this.$emit('change', index as number);\r\n },\r\n },\r\n });\r\n","import { render } from \"./PatternList.vue?vue&type=template&id=210779ce&ts=true\"\nimport script from \"./PatternList.vue?vue&type=script&lang=ts\"\nexport * from \"./PatternList.vue?vue&type=script&lang=ts\"\n\nimport \"./PatternList.vue?vue&type=style&index=0&id=210779ce&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","\r\n import { defineComponent } from 'vue';\r\n import store from '@/store/index';\r\n import NavigationList from '@/components/NavigationList.vue';\r\n import GamepadList from '@/components/GamepadList.vue';\r\n import MessageItem from '@/components/MessageItem.vue';\r\n import PatternList from '@/components/PatternList.vue';\r\n import Vibrator from '@/models/Vibrator';\r\n import TPattern from '@/models/TPattern';\r\n\r\n export default defineComponent({\r\n name: 'AppPatterns',\r\n components: {\r\n PatternList: PatternList,\r\n NavigationList: NavigationList,\r\n GamepadList: GamepadList,\r\n MessageItem: MessageItem,\r\n },\r\n computed: {\r\n gamepads: function (): Vibrator[] {\r\n return store.getters.gamepads as Vibrator[];\r\n },\r\n patterns: function (): TPattern[] {\r\n return store.getters.patterns as TPattern[];\r\n },\r\n mode: function (): number {\r\n return store.getters.mode as number;\r\n },\r\n isActive: function (): boolean {\r\n return store.getters.isActive as boolean;\r\n },\r\n },\r\n methods: {\r\n change(index: number): void {\r\n store.dispatch('change', index as number);\r\n },\r\n },\r\n mounted() {\r\n store.dispatch('loadPatterns');\r\n },\r\n });\r\n","import { render } from \"./AppPatterns.vue?vue&type=template&id=99e866c8&ts=true\"\nimport script from \"./AppPatterns.vue?vue&type=script&lang=ts\"\nexport * from \"./AppPatterns.vue?vue&type=script&lang=ts\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","\r\n import { defineComponent } from 'vue';\r\n import AppPatterns from '@/components/AppPatterns.vue';\r\n\r\n export default defineComponent({\r\n name: 'PatternsView',\r\n components: {\r\n AppPatterns: AppPatterns,\r\n },\r\n });\r\n","import { render } from \"./PatternsView.vue?vue&type=template&id=3768dde1&ts=true\"\nimport script from \"./PatternsView.vue?vue&type=script&lang=ts\"\nexport * from \"./PatternsView.vue?vue&type=script&lang=ts\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import router from '@/router';\r\nimport { NavigationGuardNext, RouteLocationNormalized } from \"vue-router\";\r\nimport IQueryRoute from '@/router/models/IQueryRoute';\r\n\r\nfunction updateRoute(\r\n to: RouteLocationNormalized,\r\n from: RouteLocationNormalized,\r\n next: NavigationGuardNext,\r\n queryRoutes: Array\r\n) {\r\n queryRoutes.forEach((route) => {\r\n if (route.query === to.fullPath) {\r\n router.push(route.to);\r\n }\r\n });\r\n return next();\r\n}\r\n\r\nconst QueryRouter = {\r\n update: updateRoute,\r\n};\r\n\r\nexport default QueryRouter;\r\n\r\n","import { NavigationGuardNext, RouteLocationNormalized, RouteRecordNormalized } from \"vue-router\";\r\n\r\nfunction appendTags(tagsArray: object[], type: string) {\r\n tagsArray.map((meta: object) => {\r\n const tag = document.createElement(type);\r\n (Object.keys(meta) as Array)\r\n .forEach((key) => {\r\n tag.setAttribute(key, meta[key] as string);\r\n });\r\n tag.setAttribute('data-vue-router-controlled', '');\r\n return tag;\r\n }).forEach(tag => document.head.appendChild(tag));\r\n}\r\n\r\nfunction updateMetatag(\r\n to: RouteLocationNormalized,\r\n from: RouteLocationNormalized,\r\n next: NavigationGuardNext\r\n) {\r\n const nearestWithTitle: RouteRecordNormalized =\r\n to.matched.slice().reverse()\r\n .find(r => r.meta && r.meta.title) as RouteRecordNormalized;\r\n const nearestWithMeta: RouteRecordNormalized =\r\n to.matched.slice().reverse()\r\n .find(r => r.meta && r.meta.metaTags && r.meta.linkTags) as RouteRecordNormalized;\r\n if (nearestWithTitle) {\r\n document.title = nearestWithTitle.meta.title as string;\r\n }\r\n Array.from(document.querySelectorAll('[data-vue-router-controlled]'))\r\n .map(el => {\r\n if (el.parentNode) {\r\n el.parentNode.removeChild(el);\r\n }\r\n });\r\n if (!nearestWithMeta) return next();\r\n const linkTags: object[] = nearestWithMeta.meta.linkTags as object[];\r\n const metaTags: object[] = nearestWithMeta.meta.metaTags as object[];\r\n appendTags(linkTags, 'link');\r\n appendTags(metaTags, 'meta');\r\n return next();\r\n}\r\n\r\nconst MetaTagUpdater = {\r\n update: updateMetatag,\r\n};\r\n\r\nexport default MetaTagUpdater;\r\n\r\n","import IQueryRoute from '@/router/models/IQueryRoute';\r\n\r\nconst queryRoutes: Array = [\r\n {\r\n query: '/?custom',\r\n to: '/custom',\r\n },\r\n {\r\n query: '/?manual',\r\n to: '/manual',\r\n },\r\n {\r\n query: '/?diagnostic',\r\n to: '/diagnostic',\r\n },\r\n {\r\n query: '/?faq',\r\n to: '/faq',\r\n },\r\n {\r\n query: '/?about',\r\n to: '/about',\r\n },\r\n {\r\n query: '/?donate',\r\n to: '/donate',\r\n }\r\n];\r\n\r\nexport default queryRoutes;\r\n","import {\r\n createRouter, createWebHistory, RouteRecordRaw,\r\n NavigationGuardNext, RouteLocationNormalized\r\n} from 'vue-router';\r\nimport PatternsView from '@/views/PatternsView.vue';\r\nimport QueryRouter from '@/router/modules/QueryRouter';\r\nimport MetaTagUpdater from '@/router/modules/MetaTagUpdater';\r\nimport queryRoutes from '@/router/assets/queryRoutes';\r\n\r\nconst routes: Array = [\r\n {\r\n path: '/',\r\n name: 'patterns-view',\r\n component: PatternsView,\r\n meta: {\r\n title: 'Wavelovers',\r\n metaTags: [\r\n {\r\n name: 'keywords',\r\n content: 'Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона',\r\n },\r\n {\r\n name: 'description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n {\r\n name: 'og:title',\r\n content: 'Wavelovers',\r\n },\r\n {\r\n name: 'og:description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n {\r\n name: 'og:url',\r\n content: 'https://wavelovers.ru/',\r\n },\r\n {\r\n name: 'twitter:title',\r\n content: 'Wavelovers',\r\n },\r\n {\r\n name: 'twitter:description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n ],\r\n linkTags: [\r\n {\r\n rel: 'canonical',\r\n href: 'https://wavelovers.ru/',\r\n },\r\n ],\r\n },\r\n },\r\n {\r\n path: '/custom',\r\n name: 'custom-view',\r\n component: () => import('@/views/CustomView.vue'),\r\n meta: {\r\n title: 'Wavelovers – Custom',\r\n metaTags: [\r\n {\r\n name: 'keywords',\r\n content: 'Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона',\r\n },\r\n {\r\n name: 'description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n {\r\n name: 'og:title',\r\n content: 'Wavelovers – Custom',\r\n },\r\n {\r\n name: 'og:description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n {\r\n name: 'og:url',\r\n content: 'https://wavelovers.ru/custom',\r\n },\r\n {\r\n name: 'twitter:title',\r\n content: 'Wavelovers – Custom',\r\n },\r\n {\r\n name: 'twitter:description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n ],\r\n linkTags: [\r\n {\r\n rel: 'canonical',\r\n href: 'https://wavelovers.ru/custom',\r\n },\r\n ],\r\n },\r\n },\r\n {\r\n path: '/manual',\r\n name: 'manual-view',\r\n component: () => import('@/views/ManualView.vue'),\r\n meta: {\r\n title: 'Wavelovers – Manual',\r\n metaTags: [\r\n {\r\n name: 'keywords',\r\n content: 'Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона',\r\n },\r\n {\r\n name: 'description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n {\r\n name: 'og:title',\r\n content: 'Wavelovers – Manual',\r\n },\r\n {\r\n name: 'og:description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n {\r\n name: 'og:url',\r\n content: 'https://wavelovers.ru/manual',\r\n },\r\n {\r\n name: 'twitter:title',\r\n content: 'Wavelovers – Manual',\r\n },\r\n {\r\n name: 'twitter:description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n ],\r\n linkTags: [\r\n {\r\n rel: 'canonical',\r\n href: 'https://wavelovers.ru/manual',\r\n },\r\n ],\r\n },\r\n },\r\n {\r\n path: '/diagnostic',\r\n name: 'diagnostic-view',\r\n component: () => import('@/views/DiagnosticView.vue'),\r\n meta: {\r\n title: 'Wavelovers – Diagnostic',\r\n metaTags: [\r\n {\r\n name: 'keywords',\r\n content: 'Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона',\r\n },\r\n {\r\n name: 'description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n {\r\n name: 'og:title',\r\n content: 'Wavelovers – Diagnostic',\r\n },\r\n {\r\n name: 'og:description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n {\r\n name: 'og:url',\r\n content: 'https://wavelovers.ru/diagnostic',\r\n },\r\n {\r\n name: 'twitter:title',\r\n content: 'Wavelovers – Diagnostic',\r\n },\r\n {\r\n name: 'twitter:description',\r\n content: 'Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.',\r\n },\r\n ],\r\n linkTags: [\r\n {\r\n rel: 'canonical',\r\n href: 'https://wavelovers.ru/diagnostic',\r\n },\r\n ],\r\n },\r\n },\r\n {\r\n path: '/faq',\r\n name: 'faq-view',\r\n component: () => import('@/views/FaqView.vue'),\r\n meta: {\r\n title: 'Wavelovers – FAQ',\r\n metaTags: [\r\n {\r\n name: 'keywords',\r\n content: 'Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, FAQ, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона, часто задаваемые вопросы',\r\n },\r\n {\r\n name: 'description',\r\n content: 'Wavelovers. Frequently asked questions page.',\r\n },\r\n {\r\n name: 'og:title',\r\n content: 'Wavelovers – FAQ',\r\n },\r\n {\r\n name: 'og:description',\r\n content: 'Wavelovers. Frequently asked questions page.',\r\n },\r\n {\r\n name: 'og:url',\r\n content: 'https://wavelovers.ru/faq',\r\n },\r\n {\r\n name: 'twitter:title',\r\n content: 'Wavelovers – FAQ',\r\n },\r\n {\r\n name: 'twitter:description',\r\n content: 'Wavelovers. Frequently asked questions page.',\r\n },\r\n ],\r\n linkTags: [\r\n {\r\n rel: 'canonical',\r\n href: 'https://wavelovers.ru/faq',\r\n },\r\n ],\r\n },\r\n },\r\n {\r\n path: '/about',\r\n name: 'about-view',\r\n component: () => import('@/views/AboutView.vue'),\r\n meta: {\r\n title: 'Wavelovers – About',\r\n metaTags: [\r\n {\r\n name: 'keywords',\r\n content: 'Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, advertise, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона, реклама',\r\n },\r\n {\r\n name: 'description',\r\n content: 'Wavelovers. Page with information about the project and data on donations.',\r\n },\r\n {\r\n name: 'og:title',\r\n content: 'Wavelovers – About',\r\n },\r\n {\r\n name: 'og:description',\r\n content: 'Wavelovers. Page with information about the project and data on donations.',\r\n },\r\n {\r\n name: 'og:url',\r\n content: 'https://wavelovers.ru/about',\r\n },\r\n {\r\n name: 'twitter:title',\r\n content: 'Wavelovers – About',\r\n },\r\n {\r\n name: 'twitter:description',\r\n content: 'Wavelovers. Page with information about the project and data on donations.',\r\n },\r\n ],\r\n linkTags: [\r\n {\r\n rel: 'canonical',\r\n href: 'https://wavelovers.ru/about',\r\n },\r\n ],\r\n },\r\n },\r\n {\r\n path: '/donate',\r\n name: 'donate-view',\r\n component: () => import('@/views/DonateView.vue'),\r\n meta: {\r\n title: 'Wavelovers – Donate',\r\n metaTags: [\r\n {\r\n name: 'keywords',\r\n content: 'Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, Donate, Support, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона, задонатить, пожертвовать, помочь, поблагодарить',\r\n },\r\n {\r\n name: 'description',\r\n content: 'Wavelovers. Donate to the author.',\r\n },\r\n {\r\n name: 'og:title',\r\n content: 'Wavelovers – Donate',\r\n },\r\n {\r\n name: 'og:description',\r\n content: 'Wavelovers. Donate to the author.',\r\n },\r\n {\r\n name: 'og:url',\r\n content: 'https://wavelovers.ru/donate',\r\n },\r\n {\r\n name: 'twitter:title',\r\n content: 'Wavelovers – Donate',\r\n },\r\n {\r\n name: 'twitter:description',\r\n content: 'Wavelovers. Donate to the author.',\r\n },\r\n ],\r\n linkTags: [\r\n {\r\n rel: 'canonical',\r\n href: 'https://wavelovers.ru/donate',\r\n },\r\n ],\r\n },\r\n },\r\n {\r\n path: '/404',\r\n name: '404',\r\n component: () => import('@/views/NotFoundView.vue'),\r\n meta: {\r\n title: 'Wavelovers – Page not found',\r\n metaTags: [\r\n {\r\n name: 'og:title',\r\n content: 'Wavelovers – Page not found',\r\n },\r\n {\r\n name: 'og:url',\r\n content: 'https://wavelovers.ru/404',\r\n },\r\n ],\r\n linkTags: [\r\n {\r\n rel: 'canonical',\r\n href: 'https://wavelovers.ru/404',\r\n },\r\n ],\r\n },\r\n },\r\n {\r\n path: '/:catchAll(.*)*',\r\n redirect: '/404',\r\n },\r\n];\r\n\r\nconst router = createRouter({\r\n history: createWebHistory(process.env.BASE_URL),\r\n routes,\r\n});\r\n\r\nrouter.beforeEach((\r\n to: RouteLocationNormalized,\r\n from: RouteLocationNormalized,\r\n next: NavigationGuardNext\r\n) => {\r\n QueryRouter.update(to, from, next, queryRoutes);\r\n MetaTagUpdater.update(to, from, next)\r\n});\r\n\r\nexport default router;\r\n\r\n","import { createApp } from 'vue';\r\nimport App from '@/App.vue';\r\nimport router from '@/router';\r\nimport store from '@/store';\r\n\r\ncreateApp(App)\r\n .use(store)\r\n .use(router)\r\n .mount('#app');\r\n\r\n","import TPatternUnit from '@/models/TPatternUnit';\r\nimport IGamepad from '@/models/IGamepad';\r\nimport IVibrator from '@/models/IVibrator';\r\n\r\nclass Vibrator implements IVibrator {\r\n\r\n unit: IGamepad;\r\n readonly id: number;\r\n readonly canVibrate: boolean;\r\n isVibrating: boolean;\r\n interval: number;\r\n\r\n constructor(unit: IGamepad) {\r\n this.unit = unit;\r\n this.id = Date.now();\r\n this.canVibrate = (this.unit.vibrationActuator) ? true : false;\r\n this.isVibrating = false;\r\n this.update = this.update.bind(this);\r\n this.interval = setInterval(this.update, 1);\r\n }\r\n\r\n update(): void {\r\n const gamepads = navigator.getGamepads();\r\n this.unit = gamepads[this.unit.index] as unknown as IGamepad;\r\n }\r\n\r\n async loop(pattern: TPatternUnit[]): Promise {\r\n this.isVibrating = true;\r\n const offsetTime = 10;\r\n while (this.isVibrating === true) {\r\n for (let i = 0; i < pattern.length; i++) {\r\n if (this.isVibrating === true) {\r\n this.vibrate(pattern[i]);\r\n await this.sleep(pattern[i].startDelay + pattern[i].duration - offsetTime);\r\n } else {\r\n return;\r\n }\r\n }\r\n }\r\n }\r\n\r\n vibrate(pattern: TPatternUnit): void {\r\n this.unit.vibrationActuator.playEffect('dual-rumble', pattern);\r\n }\r\n\r\n reset(): void {\r\n this.isVibrating = false;\r\n this.unit.vibrationActuator.reset();\r\n }\r\n\r\n sleep(ms: number): Promise {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n }\r\n}\r\n\r\nexport default Vibrator;\r\n\r\n","import { ActionContext, Module } from 'vuex';\r\nimport IRootState from '@/store/models/IRootState';\r\nimport IGamepadsState from '@/store/models/IGamepadsState';\r\nimport Vibrator from '@/models/Vibrator';\r\nimport IGamepad from '@/models/IGamepad';\r\nimport IGamepadEvent from '@/models/IGamepadEvent';\r\nimport TPatternUnit from '@/models/TPatternUnit';\r\n\r\nconst MGamepads: Module = {\r\n state: () => ({\r\n gamepads: [] as Vibrator[],\r\n }),\r\n getters: {\r\n gamepads: function (state: IGamepadsState): Vibrator[] {\r\n return state.gamepads as Vibrator[];\r\n },\r\n },\r\n mutations: {\r\n addGamepad: function (state: IGamepadsState, gamepad: Vibrator): void {\r\n state.gamepads.push(gamepad as Vibrator);\r\n },\r\n deleteGamepad: function (state: IGamepadsState, index: number): void {\r\n state.gamepads.splice(index, 1);\r\n },\r\n },\r\n actions: {\r\n addGamepad: function (\r\n context: ActionContext,\r\n event: GamepadEvent\r\n ): void {\r\n const iEvent: IGamepadEvent = event as unknown as IGamepadEvent;\r\n if (context.getters.gamepads.length >= 1) {\r\n return;\r\n } else {\r\n context.commit('addGamepad', new Vibrator(iEvent.gamepad as IGamepad));\r\n }\r\n },\r\n deleteGamepad: function (\r\n context: ActionContext,\r\n event: GamepadEvent\r\n ): void {\r\n context.getters.gamepads.forEach((gamepad: Vibrator, index: number) => {\r\n if (gamepad.unit.id === event.gamepad.id) {\r\n context.commit('deleteGamepad', index as number);\r\n }\r\n });\r\n },\r\n loop: function (\r\n context: ActionContext,\r\n pattern: TPatternUnit[]\r\n ): void {\r\n context.getters.gamepads.forEach((gamepad: Vibrator) => {\r\n gamepad.loop(pattern);\r\n });\r\n },\r\n vibrate: function (\r\n context: ActionContext,\r\n pattern: TPatternUnit\r\n ): void {\r\n context.getters.gamepads.forEach((gamepad: Vibrator) => {\r\n gamepad.vibrate(pattern);\r\n });\r\n },\r\n reset: function (\r\n context: ActionContext\r\n ): void {\r\n context.getters.gamepads.forEach((gamepad: Vibrator) => {\r\n gamepad.reset();\r\n });\r\n },\r\n },\r\n};\r\n\r\nexport default MGamepads;\r\n\r\n","import { ActionContext, Module } from 'vuex';\r\nimport IRootState from '@/store/models/IRootState';\r\nimport IPatternState from '@/store/models/IPatternState';\r\nimport TPattern from '@/models/TPattern';\r\n\r\nconst MPatterns: Module = {\r\n state: () => ({\r\n patterns: [] as TPattern[],\r\n }),\r\n getters: {\r\n patterns: function (state: IPatternState): TPattern[] {\r\n return state.patterns as TPattern[];\r\n },\r\n },\r\n mutations: {\r\n setPatterns: function (state: IPatternState, patterns: TPattern[]): void {\r\n state.patterns = patterns as TPattern[];\r\n },\r\n },\r\n actions: {\r\n loadPatterns: async function (\r\n context: ActionContext\r\n ): Promise {\r\n const url = 'https://wavelovers.ru/assets/patterns.json';\r\n try {\r\n const response: Response = await fetch(url);\r\n if (response.ok) {\r\n const json: TPattern[] = await response.json();\r\n context.commit('setPatterns', json as TPattern[]);\r\n } else {\r\n // eslint-disable-next-line\r\n console.log('Connect to the Internet for download more patterns...');\r\n }\r\n } catch (error) {\r\n // eslint-disable-next-line\r\n console.log(error);\r\n }\r\n },\r\n },\r\n};\r\n\r\nexport default MPatterns;\r\n\r\n","import { createStore, Store } from 'vuex';\r\nimport IRootState from '@/store/models/IRootState';\r\nimport MGamepads from '@/store/modules/MGamepads';\r\nimport MPatterns from '@/store/modules/MPatterns';\r\nimport TPatternUnit from '@/models/TPatternUnit';\r\n\r\nconst store: Store = createStore({\r\n state: () => ({\r\n mode: 0 as number,\r\n isActive: false as boolean,\r\n }),\r\n getters: {\r\n mode: function (state: IRootState): number {\r\n return state.mode as number;\r\n },\r\n isActive: function (state: IRootState): boolean {\r\n return state.isActive as boolean;\r\n },\r\n },\r\n mutations: {\r\n setMode: function (state: IRootState, mode: number): void {\r\n state.mode = mode as number;\r\n },\r\n setIsActive: function (state: IRootState, isActive: boolean): void {\r\n state.isActive = isActive as boolean;\r\n },\r\n },\r\n actions: {\r\n setMode: function (context, index: number): void {\r\n context.commit('setMode', index as number);\r\n },\r\n setIsActive: function (context, isActive: boolean): void {\r\n context.commit('setIsActive', isActive as boolean);\r\n },\r\n change: function (context, index: number): void {\r\n if (context.getters.mode === index) {\r\n context.dispatch('setIsActive', !context.getters.isActive);\r\n } else {\r\n context.dispatch('setIsActive', true);\r\n context.dispatch('setMode', index);\r\n }\r\n if (context.getters.isActive === true) {\r\n context.dispatch('reset');\r\n context.dispatch('loop', context.getters.patterns[context.getters.mode].pattern);\r\n } else {\r\n context.dispatch('reset');\r\n }\r\n },\r\n startCustom: function (context, pattern: TPatternUnit[]): void {\r\n context.dispatch('setIsActive', false);\r\n context.dispatch('setMode', 0);\r\n context.dispatch('reset');\r\n context.dispatch('loop', pattern);\r\n },\r\n },\r\n modules: {\r\n MGamepads: MGamepads,\r\n MPatterns: MPatterns,\r\n },\r\n});\r\n\r\nexport default store;\r\n\r\n","import { renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, resolveComponent as _resolveComponent, toDisplayString as _toDisplayString, createBlock as _createBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"content-item device-list\" }\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n const _component_GamepadItem = _resolveComponent(\"GamepadItem\")!\n\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1, [\n (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.gamepads, (gamepad) => {\n return (_openBlock(), _createBlock(_component_GamepadItem, {\n key: gamepad.id,\n textContent: _toDisplayString(gamepad.unit.id)\n }, null, 8, [\"textContent\"]))\n }), 128))\n ]))\n}","import { openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"list-item\" }\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1))\n}","\r\n import { defineComponent } from 'vue';\r\n\r\n export default defineComponent({\r\n name: 'GamepadItem',\r\n });\r\n","import { render } from \"./GamepadItem.vue?vue&type=template&id=7c902388&ts=true\"\nimport script from \"./GamepadItem.vue?vue&type=script&lang=ts\"\nexport * from \"./GamepadItem.vue?vue&type=script&lang=ts\"\n\nimport \"./GamepadItem.vue?vue&type=style&index=0&id=7c902388&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","\r\n import { defineComponent } from 'vue';\r\n import GamepadItem from '@/components/GamepadItem.vue';\r\n\r\n export default defineComponent({\r\n name: 'GamepadList',\r\n props: {\r\n gamepads: {\r\n type: Array,\r\n },\r\n },\r\n components: {\r\n GamepadItem: GamepadItem,\r\n },\r\n });\r\n","import { render } from \"./GamepadList.vue?vue&type=template&id=b6851174&ts=true\"\nimport script from \"./GamepadList.vue?vue&type=script&lang=ts\"\nexport * from \"./GamepadList.vue?vue&type=script&lang=ts\"\n\nimport \"./GamepadList.vue?vue&type=style&index=0&id=b6851174&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import { renderSlot as _renderSlot, createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"content-item message\" }\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1, [\n _createElementVNode(\"span\", null, [\n _renderSlot(_ctx.$slots, \"default\")\n ])\n ]))\n}","\r\n import { defineComponent } from 'vue';\r\n\r\n export default defineComponent({\r\n name: 'MessageItem',\r\n });\r\n","import { render } from \"./MessageItem.vue?vue&type=template&id=50d3c0d7&ts=true\"\nimport script from \"./MessageItem.vue?vue&type=script&lang=ts\"\nexport * from \"./MessageItem.vue?vue&type=script&lang=ts\"\n\nimport \"./MessageItem.vue?vue&type=style&index=0&id=50d3c0d7&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import { createTextVNode as _createTextVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, createVNode as _createVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"content-item navigation-list\" }\nconst _hoisted_2 = /*#__PURE__*/_createTextVNode(\"Patterns\")\nconst _hoisted_3 = /*#__PURE__*/_createTextVNode(\"Custom\")\nconst _hoisted_4 = /*#__PURE__*/_createTextVNode(\"Manual\")\nconst _hoisted_5 = /*#__PURE__*/_createTextVNode(\"Diagnostic\")\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n const _component_router_link = _resolveComponent(\"router-link\")!\n\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1, [\n _createVNode(_component_router_link, {\n to: \"/\",\n class: \"navigation-list__item\"\n }, {\n default: _withCtx(() => [\n _hoisted_2\n ]),\n _: 1\n }),\n _createVNode(_component_router_link, {\n to: \"/custom\",\n class: \"navigation-list__item\"\n }, {\n default: _withCtx(() => [\n _hoisted_3\n ]),\n _: 1\n }),\n _createVNode(_component_router_link, {\n to: \"/manual\",\n class: \"navigation-list__item\"\n }, {\n default: _withCtx(() => [\n _hoisted_4\n ]),\n _: 1\n }),\n _createVNode(_component_router_link, {\n to: \"/diagnostic\",\n class: \"navigation-list__item\"\n }, {\n default: _withCtx(() => [\n _hoisted_5\n ]),\n _: 1\n })\n ]))\n}","\r\n import { defineComponent } from 'vue';\r\n\r\n export default defineComponent({\r\n name: 'NavigationList',\r\n });\r\n","import { render } from \"./NavigationList.vue?vue&type=template&id=5b991a16&ts=true\"\nimport script from \"./NavigationList.vue?vue&type=script&lang=ts\"\nexport * from \"./NavigationList.vue?vue&type=script&lang=ts\"\n\nimport \"./NavigationList.vue?vue&type=style&index=0&id=5b991a16&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","var deferred = [];\n__webpack_require__.O = function(result, chunkIds, fn, priority) {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar chunkIds = deferred[i][0];\n\t\tvar fn = deferred[i][1];\n\t\tvar priority = deferred[i][2];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.f = {};\n// This file contains only the entry chunk.\n// The chunk loading function for additional chunks\n__webpack_require__.e = function(chunkId) {\n\treturn Promise.all(Object.keys(__webpack_require__.f).reduce(function(promises, key) {\n\t\t__webpack_require__.f[key](chunkId, promises);\n\t\treturn promises;\n\t}, []));\n};","// This function allow to reference async chunks\n__webpack_require__.u = function(chunkId) {\n\t// return url for filenames based on template\n\treturn \"js/\" + chunkId + \".\" + {\"66\":\"54b2ec35\",\"219\":\"4c3a113b\",\"531\":\"6af13e76\",\"582\":\"c3117d29\",\"645\":\"b32a0b62\",\"672\":\"270ec4e0\",\"807\":\"369d563e\"}[chunkId] + \".js\";\n};","// This function allow to reference async chunks\n__webpack_require__.miniCssF = function(chunkId) {\n\t// return url for filenames based on template\n\treturn \"css/\" + chunkId + \".\" + {\"66\":\"bb6440f7\",\"219\":\"19a8cda3\",\"582\":\"10b8ac32\",\"672\":\"278b2bb3\",\"807\":\"06b3a622\"}[chunkId] + \".css\";\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","var inProgress = {};\nvar dataWebpackPrefix = \"wavelovers:\";\n// loadScript function to load a script via script tag\n__webpack_require__.l = function(url, done, key, chunkId) {\n\tif(inProgress[url]) { inProgress[url].push(done); return; }\n\tvar script, needAttach;\n\tif(key !== undefined) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tfor(var i = 0; i < scripts.length; i++) {\n\t\t\tvar s = scripts[i];\n\t\t\tif(s.getAttribute(\"src\") == url || s.getAttribute(\"data-webpack\") == dataWebpackPrefix + key) { script = s; break; }\n\t\t}\n\t}\n\tif(!script) {\n\t\tneedAttach = true;\n\t\tscript = document.createElement('script');\n\n\t\tscript.charset = 'utf-8';\n\t\tscript.timeout = 120;\n\t\tif (__webpack_require__.nc) {\n\t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n\t\t}\n\t\tscript.setAttribute(\"data-webpack\", dataWebpackPrefix + key);\n\t\tscript.src = url;\n\t}\n\tinProgress[url] = [done];\n\tvar onScriptComplete = function(prev, event) {\n\t\t// avoid mem leaks in IE.\n\t\tscript.onerror = script.onload = null;\n\t\tclearTimeout(timeout);\n\t\tvar doneFns = inProgress[url];\n\t\tdelete inProgress[url];\n\t\tscript.parentNode && script.parentNode.removeChild(script);\n\t\tdoneFns && doneFns.forEach(function(fn) { return fn(event); });\n\t\tif(prev) return prev(event);\n\t}\n\t;\n\tvar timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);\n\tscript.onerror = onScriptComplete.bind(null, script.onerror);\n\tscript.onload = onScriptComplete.bind(null, script.onload);\n\tneedAttach && document.head.appendChild(script);\n};","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.p = \"/\";","var createStylesheet = function(chunkId, fullhref, resolve, reject) {\n\tvar linkTag = document.createElement(\"link\");\n\n\tlinkTag.rel = \"stylesheet\";\n\tlinkTag.type = \"text/css\";\n\tvar onLinkComplete = function(event) {\n\t\t// avoid mem leaks.\n\t\tlinkTag.onerror = linkTag.onload = null;\n\t\tif (event.type === 'load') {\n\t\t\tresolve();\n\t\t} else {\n\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n\t\t\tvar realHref = event && event.target && event.target.href || fullhref;\n\t\t\tvar err = new Error(\"Loading CSS chunk \" + chunkId + \" failed.\\n(\" + realHref + \")\");\n\t\t\terr.code = \"CSS_CHUNK_LOAD_FAILED\";\n\t\t\terr.type = errorType;\n\t\t\terr.request = realHref;\n\t\t\tlinkTag.parentNode.removeChild(linkTag)\n\t\t\treject(err);\n\t\t}\n\t}\n\tlinkTag.onerror = linkTag.onload = onLinkComplete;\n\tlinkTag.href = fullhref;\n\n\tdocument.head.appendChild(linkTag);\n\treturn linkTag;\n};\nvar findStylesheet = function(href, fullhref) {\n\tvar existingLinkTags = document.getElementsByTagName(\"link\");\n\tfor(var i = 0; i < existingLinkTags.length; i++) {\n\t\tvar tag = existingLinkTags[i];\n\t\tvar dataHref = tag.getAttribute(\"data-href\") || tag.getAttribute(\"href\");\n\t\tif(tag.rel === \"stylesheet\" && (dataHref === href || dataHref === fullhref)) return tag;\n\t}\n\tvar existingStyleTags = document.getElementsByTagName(\"style\");\n\tfor(var i = 0; i < existingStyleTags.length; i++) {\n\t\tvar tag = existingStyleTags[i];\n\t\tvar dataHref = tag.getAttribute(\"data-href\");\n\t\tif(dataHref === href || dataHref === fullhref) return tag;\n\t}\n};\nvar loadStylesheet = function(chunkId) {\n\treturn new Promise(function(resolve, reject) {\n\t\tvar href = __webpack_require__.miniCssF(chunkId);\n\t\tvar fullhref = __webpack_require__.p + href;\n\t\tif(findStylesheet(href, fullhref)) return resolve();\n\t\tcreateStylesheet(chunkId, fullhref, resolve, reject);\n\t});\n}\n// object to store loaded CSS chunks\nvar installedCssChunks = {\n\t143: 0\n};\n\n__webpack_require__.f.miniCss = function(chunkId, promises) {\n\tvar cssChunks = {\"66\":1,\"219\":1,\"582\":1,\"672\":1,\"807\":1};\n\tif(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]);\n\telse if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) {\n\t\tpromises.push(installedCssChunks[chunkId] = loadStylesheet(chunkId).then(function() {\n\t\t\tinstalledCssChunks[chunkId] = 0;\n\t\t}, function(e) {\n\t\t\tdelete installedCssChunks[chunkId];\n\t\t\tthrow e;\n\t\t}));\n\t}\n};\n\n// no hmr","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t143: 0\n};\n\n__webpack_require__.f.j = function(chunkId, promises) {\n\t\t// JSONP chunk loading for javascript\n\t\tvar installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;\n\t\tif(installedChunkData !== 0) { // 0 means \"already installed\".\n\n\t\t\t// a Promise means \"currently loading\".\n\t\t\tif(installedChunkData) {\n\t\t\t\tpromises.push(installedChunkData[2]);\n\t\t\t} else {\n\t\t\t\tif(true) { // all chunks have JS\n\t\t\t\t\t// setup Promise in chunk cache\n\t\t\t\t\tvar promise = new Promise(function(resolve, reject) { installedChunkData = installedChunks[chunkId] = [resolve, reject]; });\n\t\t\t\t\tpromises.push(installedChunkData[2] = promise);\n\n\t\t\t\t\t// start chunk loading\n\t\t\t\t\tvar url = __webpack_require__.p + __webpack_require__.u(chunkId);\n\t\t\t\t\t// create error before stack unwound to get useful stacktrace later\n\t\t\t\t\tvar error = new Error();\n\t\t\t\t\tvar loadingEnded = function(event) {\n\t\t\t\t\t\tif(__webpack_require__.o(installedChunks, chunkId)) {\n\t\t\t\t\t\t\tinstalledChunkData = installedChunks[chunkId];\n\t\t\t\t\t\t\tif(installedChunkData !== 0) installedChunks[chunkId] = undefined;\n\t\t\t\t\t\t\tif(installedChunkData) {\n\t\t\t\t\t\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n\t\t\t\t\t\t\t\tvar realSrc = event && event.target && event.target.src;\n\t\t\t\t\t\t\t\terror.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';\n\t\t\t\t\t\t\t\terror.name = 'ChunkLoadError';\n\t\t\t\t\t\t\t\terror.type = errorType;\n\t\t\t\t\t\t\t\terror.request = realSrc;\n\t\t\t\t\t\t\t\tinstalledChunkData[1](error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\t__webpack_require__.l(url, loadingEnded, \"chunk-\" + chunkId, chunkId);\n\t\t\t\t} else installedChunks[chunkId] = 0;\n\t\t\t}\n\t\t}\n};\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; };\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = function(parentChunkLoadingFunction, data) {\n\tvar chunkIds = data[0];\n\tvar moreModules = data[1];\n\tvar runtime = data[2];\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunkwavelovers\"] = self[\"webpackChunkwavelovers\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [998], function() { return __webpack_require__(2368); })\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["_hoisted_1","class","_hoisted_2","render","_ctx","_cache","$props","$setup","$data","$options","_component_HeaderItem","_resolveComponent","_component_router_view","_component_FooterItem","_openBlock","_createElementBlock","_Fragment","_createVNode","_createElementVNode","_hoisted_3","translate","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_createTextVNode","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_component_router_link","to","default","_withCtx","_","defineComponent","name","__exports__","_createStaticVNode","components","HeaderItem","FooterItem","methods","addGamepad","event","store","deleteGamepad","addEventListeners","window","addEventListener","this","removeEventListeners","removeEventListener","mounted","unmounted","_component_AppPatterns","_component_NavigationList","_component_PatternList","_component_MessageItem","_component_GamepadList","patterns","length","_createBlock","key","mode","isActive","onChange","change","gamepads","_component_PatternItem","_renderList","pattern","index","onClick","$event","_normalizeClass","textContent","_toDisplayString","icon","type","props","Object","Number","Boolean","$emit","Array","PatternItem","PatternList","NavigationList","GamepadList","MessageItem","computed","AppPatterns","updateRoute","from","next","queryRoutes","forEach","route","query","fullPath","router","QueryRouter","update","appendTags","tagsArray","map","meta","tag","document","createElement","keys","setAttribute","head","appendChild","updateMetatag","nearestWithTitle","matched","slice","reverse","find","r","title","nearestWithMeta","metaTags","linkTags","querySelectorAll","el","parentNode","removeChild","MetaTagUpdater","routes","path","component","PatternsView","content","rel","href","redirect","createRouter","history","createWebHistory","process","beforeEach","createApp","App","use","mount","Vibrator","constructor","unit","id","Date","now","canVibrate","vibrationActuator","isVibrating","bind","interval","setInterval","navigator","getGamepads","offsetTime","i","vibrate","sleep","startDelay","duration","playEffect","reset","ms","Promise","resolve","setTimeout","MGamepads","state","getters","mutations","gamepad","push","splice","actions","context","iEvent","commit","loop","MPatterns","setPatterns","loadPatterns","async","url","response","fetch","ok","json","console","log","error","createStore","setMode","setIsActive","dispatch","startCustom","modules","_component_GamepadItem","GamepadItem","_renderSlot","$slots","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","module","__webpack_modules__","m","deferred","O","result","chunkIds","fn","priority","notFulfilled","Infinity","fulfilled","j","every","n","getter","__esModule","d","a","definition","o","defineProperty","enumerable","get","f","e","chunkId","all","reduce","promises","u","miniCssF","g","globalThis","Function","obj","prop","prototype","hasOwnProperty","call","inProgress","dataWebpackPrefix","l","done","script","needAttach","scripts","getElementsByTagName","s","getAttribute","charset","timeout","nc","src","onScriptComplete","prev","onerror","onload","clearTimeout","doneFns","target","Symbol","toStringTag","value","p","createStylesheet","fullhref","reject","linkTag","onLinkComplete","errorType","realHref","err","Error","code","request","findStylesheet","existingLinkTags","dataHref","existingStyleTags","loadStylesheet","installedCssChunks","miniCss","cssChunks","then","installedChunks","installedChunkData","promise","loadingEnded","realSrc","message","webpackJsonpCallback","parentChunkLoadingFunction","data","moreModules","runtime","some","chunkLoadingGlobal","self","__webpack_exports__"],"sourceRoot":""} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 50ec877..63accd8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "wavelovers", - "version": "1.0.8", + "version": "1.0.9", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "wavelovers", - "version": "1.0.8", + "version": "1.0.9", "license": "GNU GPL v3", "dependencies": { "core-js": "^3.8.3", diff --git a/package.json b/package.json index f2ae78d..2beb8c7 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "wavelovers", "description": "Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.", "keywords": [ "wavelovers", "gamepad-vibrator", "gamepad-test-tool", "gamepad-vibration-test-tool" ], - "version": "1.0.8", + "version": "1.0.9", "license": "GNU GPL v3", "homepage": "https://wavelovers.ru/", "author": { diff --git a/src/router/assets/queryRoutes.ts b/src/router/assets/queryRoutes.ts new file mode 100644 index 0000000..219c5e9 --- /dev/null +++ b/src/router/assets/queryRoutes.ts @@ -0,0 +1,30 @@ +import IQueryRoute from '@/router/models/IQueryRoute'; + +const queryRoutes: Array = [ + { + query: '/?custom', + to: '/custom', + }, + { + query: '/?manual', + to: '/manual', + }, + { + query: '/?diagnostic', + to: '/diagnostic', + }, + { + query: '/?faq', + to: '/faq', + }, + { + query: '/?about', + to: '/about', + }, + { + query: '/?donate', + to: '/donate', + } +]; + +export default queryRoutes; diff --git a/src/router/index.ts b/src/router/index.ts index ee832f8..cfc3b0c 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,7 +1,11 @@ -import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'; +import { + createRouter, createWebHistory, RouteRecordRaw, + NavigationGuardNext, RouteLocationNormalized +} from 'vue-router'; import PatternsView from '@/views/PatternsView.vue'; import QueryRouter from '@/router/modules/QueryRouter'; import MetaTagUpdater from '@/router/modules/MetaTagUpdater'; +import queryRoutes from '@/router/assets/queryRoutes'; const routes: Array = [ { @@ -347,8 +351,14 @@ const router = createRouter({ routes, }); -router.beforeEach(QueryRouter.update); -router.beforeEach(MetaTagUpdater.update); +router.beforeEach(( + to: RouteLocationNormalized, + from: RouteLocationNormalized, + next: NavigationGuardNext +) => { + QueryRouter.update(to, from, next, queryRoutes); + MetaTagUpdater.update(to, from, next) +}); export default router; diff --git a/src/router/models/IQueryRoute.ts b/src/router/models/IQueryRoute.ts new file mode 100644 index 0000000..52d40af --- /dev/null +++ b/src/router/models/IQueryRoute.ts @@ -0,0 +1,6 @@ +interface IQueryRoute { + query: string; + to: string; +} + +export default IQueryRoute; diff --git a/src/router/modules/QueryRouter.ts b/src/router/modules/QueryRouter.ts index 82a7218..70d3372 100644 --- a/src/router/modules/QueryRouter.ts +++ b/src/router/modules/QueryRouter.ts @@ -1,31 +1,18 @@ import router from '@/router'; import { NavigationGuardNext, RouteLocationNormalized } from "vue-router"; +import IQueryRoute from '@/router/models/IQueryRoute'; function updateRoute( to: RouteLocationNormalized, from: RouteLocationNormalized, - next: NavigationGuardNext + next: NavigationGuardNext, + queryRoutes: Array ) { - switch (to.fullPath) { - case '/?custom': - router.push('/custom'); - break; - case '/?manual': - router.push('/manual'); - break; - case '/?diagnostic': - router.push('/diagnostic'); - break; - case '/?faq': - router.push('/faq'); - break; - case '/?about': - router.push('/about'); - break; - case '/?donate': - router.push('/donate'); - break; - } + queryRoutes.forEach((route) => { + if (route.query === to.fullPath) { + router.push(route.to); + } + }); return next(); }