diff --git a/dist/css/app.7903d5c6.css b/dist/css/app.e25fb2a6.css similarity index 96% rename from dist/css/app.7903d5c6.css rename to dist/css/app.e25fb2a6.css index 7d6628f..20c5ea3 100644 --- a/dist/css/app.7903d5c6.css +++ b/dist/css/app.e25fb2a6.css @@ -1 +1 @@ -:root{--bg-color:#282a36;--accent:#353744;--current-line:#44475a;--comment:#6272a4;--foreground:#f8f8f2;--orange:#ffb86c;--cyan:#8be9fd}body{background:var(--bg-color);margin:0}#app{height:100vh;width:100vw;font-family:Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-align:center;color:var(--foreground);display:grid;grid-template-areas:"header header" "filters body " "stats body " "footer body ";grid-template-columns:1fr 5fr;grid-template-rows:auto 1fr auto auto}@media only screen and (max-width:922px){#app{grid-template-areas:"header header" "filters filters" "body body ";grid-template-rows:auto auto 1fr}}header{grid-area:header;height:64px;background:var(--bg-color);color:var(--foreground)}nav{display:flex;flex-direction:row;text-align:center;vertical-align:middle}nav a{font-weight:700;color:var(--foreground)}nav a.router-link-exact-active{color:var(--orange)}.navbar-element{text-align:center;line-height:16px;padding:24px 32px}.navbar-element:hover{background:var(--current-line)}.spacer{width:100%}[data-v-227422ef]{box-sizing:border-box}.playerTable[data-v-227422ef]{margin-right:1rem;overflow:auto;height:100%}.playerHeaders[data-v-227422ef],.playerRow[data-v-227422ef]{box-sizing:border-box;display:grid;grid-template-columns:4ch 20ch 6ch 6ch 6ch 10ch 1fr;background:var(--bg-color);text-align:left;cursor:pointer;margin:0;transition:border .25s;height:2em}.playerHeaders[data-v-227422ef]{position:sticky;top:0;height:3em}.playerHeaders>span[data-v-227422ef],.playerRow>div[data-v-227422ef]{padding:.5em .8em 0 .25em}.playerHeaders[data-v-227422ef],.playerRow[data-v-227422ef]:nth-child(2n){background:var(--current-line)}.playerRow[data-v-227422ef]:nth-child(odd){background:var(--accent)}.playerHeaders div[data-v-227422ef]:hover,.playerRow[data-v-227422ef]:hover{background:var(--bg-color)}.playerHeaders>div[data-v-227422ef]:not(:last-child),.playerRow>div[data-v-227422ef]:not(:last-child){border-right:solid var(--bg-color) 2px}.playerHeaders>span[data-v-227422ef]:last-child{width:100%}@media only screen and (max-width:600px){.playerHeaders>span[data-v-227422ef]:nth-child(6),.playerHeaders>span[data-v-227422ef]:nth-child(7),.playerRow>div[data-v-227422ef]:nth-child(6),.playerRow>div[data-v-227422ef]:nth-child(7){display:none}.playerHeaders[data-v-227422ef],.playerRow[data-v-227422ef]{grid-template-columns:4ch 20ch 6ch 6ch 1fr}}.player span[data-v-227422ef]{pointer-events:none}.selected[data-v-227422ef]{background:var(--comment)!important}canvas[data-v-cf8f72c6]{background:var(--accent)}@media only screen and (max-width:922px){canvas[data-v-cf8f72c6]{display:none!important}}fieldset[disabled] .multiselect{pointer-events:none}.multiselect__spinner{position:absolute;right:1px;top:1px;width:40px;height:38px;background:#fff;display:block}.multiselect__spinner:after,.multiselect__spinner:before{position:absolute;content:"";top:50%;left:50%;margin:-8px 0 0 -8px;width:16px;height:16px;border-radius:100%;border-color:#41b883 transparent transparent;border-style:solid;border-width:2px;box-shadow:0 0 0 1px transparent}.multiselect__spinner:before{animation:spinning 2.4s cubic-bezier(.41,.26,.2,.62);animation-iteration-count:infinite}.multiselect__spinner:after{animation:spinning 2.4s cubic-bezier(.51,.09,.21,.8);animation-iteration-count:infinite}.multiselect__loading-enter-active,.multiselect__loading-leave-active{transition:opacity .4s ease-in-out;opacity:1}.multiselect__loading-enter,.multiselect__loading-leave-active{opacity:0}.multiselect,.multiselect__input,.multiselect__single{font-family:inherit;font-size:16px;touch-action:manipulation}.multiselect{box-sizing:content-box;display:block;position:relative;width:100%;min-height:40px;text-align:left;color:#35495e}.multiselect *{box-sizing:border-box}.multiselect:focus{outline:none}.multiselect--disabled{background:#ededed;pointer-events:none;opacity:.6}.multiselect--active{z-index:50}.multiselect--active:not(.multiselect--above) .multiselect__current,.multiselect--active:not(.multiselect--above) .multiselect__input,.multiselect--active:not(.multiselect--above) .multiselect__tags{border-bottom-left-radius:0;border-bottom-right-radius:0}.multiselect--active .multiselect__select{transform:rotate(180deg)}.multiselect--above.multiselect--active .multiselect__current,.multiselect--above.multiselect--active .multiselect__input,.multiselect--above.multiselect--active .multiselect__tags{border-top-left-radius:0;border-top-right-radius:0}.multiselect__input,.multiselect__single{position:relative;display:inline-block;min-height:20px;line-height:20px;border:none;border-radius:5px;background:#fff;padding:0 0 0 5px;width:100%;transition:border .1s ease;box-sizing:border-box;margin-bottom:8px;vertical-align:top}.multiselect__input::-moz-placeholder{color:#35495e}.multiselect__input::placeholder{color:#35495e}.multiselect__tag~.multiselect__input,.multiselect__tag~.multiselect__single{width:auto}.multiselect__input:hover,.multiselect__single:hover{border-color:#cfcfcf}.multiselect__input:focus,.multiselect__single:focus{border-color:#a8a8a8;outline:none}.multiselect__single{padding-left:5px;margin-bottom:8px}.multiselect__tags-wrap{display:inline}.multiselect__tags{min-height:40px;display:block;padding:8px 40px 0 8px;border-radius:5px;border:1px solid #e8e8e8;background:#fff;font-size:14px}.multiselect__tag{position:relative;display:inline-block;padding:4px 26px 4px 10px;border-radius:5px;margin-right:10px;color:#fff;line-height:1;background:#41b883;margin-bottom:5px;white-space:nowrap;overflow:hidden;max-width:100%;text-overflow:ellipsis}.multiselect__tag-icon{cursor:pointer;margin-left:7px;position:absolute;right:0;top:0;bottom:0;font-weight:700;font-style:normal;width:22px;text-align:center;line-height:22px;transition:all .2s ease;border-radius:5px}.multiselect__tag-icon:after{content:"×";color:#266d4d;font-size:14px}.multiselect__tag-icon:focus:after,.multiselect__tag-icon:hover:after{color:#fff}.multiselect__current{min-height:40px;overflow:hidden;padding:8px 12px 0;padding-right:30px;white-space:nowrap;border-radius:5px;border:1px solid #e8e8e8}.multiselect__current,.multiselect__select{line-height:16px;box-sizing:border-box;display:block;margin:0;text-decoration:none;cursor:pointer}.multiselect__select{position:absolute;width:40px;height:38px;right:1px;top:1px;padding:4px 8px;text-align:center;transition:transform .2s ease}.multiselect__select:before{position:relative;right:0;top:65%;color:#999;margin-top:4px;border-style:solid;border-width:5px 5px 0 5px;border-color:#999 transparent transparent transparent;content:""}.multiselect__placeholder{color:#adadad;display:inline-block;margin-bottom:10px;padding-top:2px}.multiselect--active .multiselect__placeholder{display:none}.multiselect__content-wrapper{position:absolute;display:block;background:#fff;width:100%;max-height:240px;overflow:auto;border:1px solid #e8e8e8;border-top:none;border-bottom-left-radius:5px;border-bottom-right-radius:5px;z-index:50;-webkit-overflow-scrolling:touch}.multiselect__content{list-style:none;display:inline-block;padding:0;margin:0;min-width:100%;vertical-align:top}.multiselect--above .multiselect__content-wrapper{bottom:100%;border-bottom-left-radius:0;border-bottom-right-radius:0;border-top-left-radius:5px;border-top-right-radius:5px;border-bottom:none;border-top:1px solid #e8e8e8}.multiselect__content::-webkit-scrollbar{display:none}.multiselect__element{display:block}.multiselect__option{display:block;padding:12px;min-height:40px;line-height:16px;text-decoration:none;text-transform:none;vertical-align:middle;position:relative;cursor:pointer;white-space:nowrap}.multiselect__option:after{top:0;right:0;position:absolute;line-height:40px;padding-right:12px;padding-left:20px;font-size:13px}.multiselect__option--highlight{background:#41b883;outline:none;color:#fff}.multiselect__option--highlight:after{content:attr(data-select);background:#41b883;color:#fff}.multiselect__option--selected{background:#f3f3f3;color:#35495e;font-weight:700}.multiselect__option--selected:after{content:attr(data-selected);color:silver;background:inherit}.multiselect__option--selected.multiselect__option--highlight{background:#ff6a6a;color:#fff}.multiselect__option--selected.multiselect__option--highlight:after{background:#ff6a6a;content:attr(data-deselect);color:#fff}.multiselect--disabled .multiselect__current,.multiselect--disabled .multiselect__select{background:#ededed;color:#a6a6a6}.multiselect__option--disabled{background:#ededed!important;color:#a6a6a6!important;cursor:text;pointer-events:none}.multiselect__option--group{background:#ededed;color:#35495e}.multiselect__option--group.multiselect__option--highlight{background:#35495e;color:#fff}.multiselect__option--group.multiselect__option--highlight:after{background:#35495e}.multiselect__option--disabled.multiselect__option--highlight{background:#dedede}.multiselect__option--group-selected.multiselect__option--highlight{background:#ff6a6a;color:#fff}.multiselect__option--group-selected.multiselect__option--highlight:after{background:#ff6a6a;content:attr(data-deselect);color:#fff}.multiselect-enter-active,.multiselect-leave-active{transition:all .15s ease}.multiselect-enter,.multiselect-leave-active{opacity:0}.multiselect__strong{margin-bottom:8px;line-height:20px;display:inline-block;vertical-align:top}[dir=rtl] .multiselect{text-align:right}[dir=rtl] .multiselect__select{right:auto;left:1px}[dir=rtl] .multiselect__tags{padding:8px 8px 0 40px}[dir=rtl] .multiselect__content{text-align:right}[dir=rtl] .multiselect__option:after{right:auto;left:0}[dir=rtl] .multiselect__clear{right:auto;left:12px}[dir=rtl] .multiselect__spinner{right:auto;left:1px}@keyframes spinning{0%{transform:rotate(0)}to{transform:rotate(2turn)}}.multiselect[data-v-6d0e9369]{margin:0 .5em 1em .5em}#playerView[data-v-6d0e9369]{margin:0 1rem 1rem 1rem;display:grid;overflow:auto;grid-template-columns:50% 50%}@media only screen and (max-width:922px){#playerView[data-v-6d0e9369]{margin:0 1rem 1rem 1rem;display:grid;overflow:auto;grid-template-columns:100%;width:calc(100vw - 1em);margin:0 0 1rem 1rem}.multiselect[data-v-6d0e9369]{width:calc(100% - 1em)}}#filters[data-v-6d0e9369]{grid-area:filters} \ No newline at end of file +:root{--bg-color:#282a36;--accent:#353744;--current-line:#44475a;--comment:#6272a4;--foreground:#f8f8f2;--orange:#ffb86c;--cyan:#8be9fd}body{background:var(--bg-color);margin:0}#app{height:100vh;width:100vw;font-family:Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-align:center;color:var(--foreground);display:grid;grid-template-areas:"header header" "filters body " "stats body " "footer body ";grid-template-columns:1fr 5fr;grid-template-rows:auto 1fr auto auto}@media only screen and (max-width:922px){#app{grid-template-areas:"header header" "filters filters" "body body ";grid-template-rows:auto auto 1fr}}header{grid-area:header;height:64px;background:var(--bg-color);color:var(--foreground)}nav{display:flex;flex-direction:row;text-align:center;vertical-align:middle}nav a{font-weight:700;color:var(--foreground)}nav a.router-link-exact-active{color:var(--orange)}.navbar-element{text-align:center;line-height:16px;padding:24px 32px}.navbar-element:hover{background:var(--current-line)}.spacer{width:100%}[data-v-227422ef]{box-sizing:border-box}.playerTable[data-v-227422ef]{margin-right:1rem;overflow:auto;height:100%}.playerHeaders[data-v-227422ef],.playerRow[data-v-227422ef]{box-sizing:border-box;display:grid;grid-template-columns:4ch 20ch 6ch 6ch 6ch 10ch 1fr;background:var(--bg-color);text-align:left;cursor:pointer;margin:0;transition:border .25s;height:2em}.playerHeaders[data-v-227422ef]{position:sticky;top:0;height:3em}.playerHeaders>span[data-v-227422ef],.playerRow>div[data-v-227422ef]{padding:.5em .8em 0 .25em}.playerHeaders[data-v-227422ef],.playerRow[data-v-227422ef]:nth-child(2n){background:var(--current-line)}.playerRow[data-v-227422ef]:nth-child(odd){background:var(--accent)}.playerHeaders div[data-v-227422ef]:hover,.playerRow[data-v-227422ef]:hover{background:var(--bg-color)}.playerHeaders>div[data-v-227422ef]:not(:last-child),.playerRow>div[data-v-227422ef]:not(:last-child){border-right:solid var(--bg-color) 2px}.playerHeaders>span[data-v-227422ef]:last-child{width:100%}@media only screen and (max-width:600px){.playerHeaders>span[data-v-227422ef]:nth-child(6),.playerHeaders>span[data-v-227422ef]:nth-child(7),.playerRow>div[data-v-227422ef]:nth-child(6),.playerRow>div[data-v-227422ef]:nth-child(7){display:none}.playerHeaders[data-v-227422ef],.playerRow[data-v-227422ef]{grid-template-columns:4ch 20ch 6ch 6ch 1fr}}.player span[data-v-227422ef]{pointer-events:none}.selected[data-v-227422ef]{background:var(--comment)!important}canvas[data-v-cf8f72c6]{background:var(--accent)}@media only screen and (max-width:922px){canvas[data-v-cf8f72c6]{display:none!important}}fieldset[disabled] .multiselect{pointer-events:none}.multiselect__spinner{position:absolute;right:1px;top:1px;width:40px;height:38px;background:#fff;display:block}.multiselect__spinner:after,.multiselect__spinner:before{position:absolute;content:"";top:50%;left:50%;margin:-8px 0 0 -8px;width:16px;height:16px;border-radius:100%;border-color:#41b883 transparent transparent;border-style:solid;border-width:2px;box-shadow:0 0 0 1px transparent}.multiselect__spinner:before{animation:spinning 2.4s cubic-bezier(.41,.26,.2,.62);animation-iteration-count:infinite}.multiselect__spinner:after{animation:spinning 2.4s cubic-bezier(.51,.09,.21,.8);animation-iteration-count:infinite}.multiselect__loading-enter-active,.multiselect__loading-leave-active{transition:opacity .4s ease-in-out;opacity:1}.multiselect__loading-enter,.multiselect__loading-leave-active{opacity:0}.multiselect,.multiselect__input,.multiselect__single{font-family:inherit;font-size:16px;touch-action:manipulation}.multiselect{box-sizing:content-box;display:block;position:relative;width:100%;min-height:40px;text-align:left;color:#35495e}.multiselect *{box-sizing:border-box}.multiselect:focus{outline:none}.multiselect--disabled{background:#ededed;pointer-events:none;opacity:.6}.multiselect--active{z-index:50}.multiselect--active:not(.multiselect--above) .multiselect__current,.multiselect--active:not(.multiselect--above) .multiselect__input,.multiselect--active:not(.multiselect--above) .multiselect__tags{border-bottom-left-radius:0;border-bottom-right-radius:0}.multiselect--active .multiselect__select{transform:rotate(180deg)}.multiselect--above.multiselect--active .multiselect__current,.multiselect--above.multiselect--active .multiselect__input,.multiselect--above.multiselect--active .multiselect__tags{border-top-left-radius:0;border-top-right-radius:0}.multiselect__input,.multiselect__single{position:relative;display:inline-block;min-height:20px;line-height:20px;border:none;border-radius:5px;background:#fff;padding:0 0 0 5px;width:100%;transition:border .1s ease;box-sizing:border-box;margin-bottom:8px;vertical-align:top}.multiselect__input::-moz-placeholder{color:#35495e}.multiselect__input::placeholder{color:#35495e}.multiselect__tag~.multiselect__input,.multiselect__tag~.multiselect__single{width:auto}.multiselect__input:hover,.multiselect__single:hover{border-color:#cfcfcf}.multiselect__input:focus,.multiselect__single:focus{border-color:#a8a8a8;outline:none}.multiselect__single{padding-left:5px;margin-bottom:8px}.multiselect__tags-wrap{display:inline}.multiselect__tags{min-height:40px;display:block;padding:8px 40px 0 8px;border-radius:5px;border:1px solid #e8e8e8;background:#fff;font-size:14px}.multiselect__tag{position:relative;display:inline-block;padding:4px 26px 4px 10px;border-radius:5px;margin-right:10px;color:#fff;line-height:1;background:#41b883;margin-bottom:5px;white-space:nowrap;overflow:hidden;max-width:100%;text-overflow:ellipsis}.multiselect__tag-icon{cursor:pointer;margin-left:7px;position:absolute;right:0;top:0;bottom:0;font-weight:700;font-style:normal;width:22px;text-align:center;line-height:22px;transition:all .2s ease;border-radius:5px}.multiselect__tag-icon:after{content:"×";color:#266d4d;font-size:14px}.multiselect__tag-icon:focus:after,.multiselect__tag-icon:hover:after{color:#fff}.multiselect__current{min-height:40px;overflow:hidden;padding:8px 12px 0;padding-right:30px;white-space:nowrap;border-radius:5px;border:1px solid #e8e8e8}.multiselect__current,.multiselect__select{line-height:16px;box-sizing:border-box;display:block;margin:0;text-decoration:none;cursor:pointer}.multiselect__select{position:absolute;width:40px;height:38px;right:1px;top:1px;padding:4px 8px;text-align:center;transition:transform .2s ease}.multiselect__select:before{position:relative;right:0;top:65%;color:#999;margin-top:4px;border-style:solid;border-width:5px 5px 0 5px;border-color:#999 transparent transparent transparent;content:""}.multiselect__placeholder{color:#adadad;display:inline-block;margin-bottom:10px;padding-top:2px}.multiselect--active .multiselect__placeholder{display:none}.multiselect__content-wrapper{position:absolute;display:block;background:#fff;width:100%;max-height:240px;overflow:auto;border:1px solid #e8e8e8;border-top:none;border-bottom-left-radius:5px;border-bottom-right-radius:5px;z-index:50;-webkit-overflow-scrolling:touch}.multiselect__content{list-style:none;display:inline-block;padding:0;margin:0;min-width:100%;vertical-align:top}.multiselect--above .multiselect__content-wrapper{bottom:100%;border-bottom-left-radius:0;border-bottom-right-radius:0;border-top-left-radius:5px;border-top-right-radius:5px;border-bottom:none;border-top:1px solid #e8e8e8}.multiselect__content::-webkit-scrollbar{display:none}.multiselect__element{display:block}.multiselect__option{display:block;padding:12px;min-height:40px;line-height:16px;text-decoration:none;text-transform:none;vertical-align:middle;position:relative;cursor:pointer;white-space:nowrap}.multiselect__option:after{top:0;right:0;position:absolute;line-height:40px;padding-right:12px;padding-left:20px;font-size:13px}.multiselect__option--highlight{background:#41b883;outline:none;color:#fff}.multiselect__option--highlight:after{content:attr(data-select);background:#41b883;color:#fff}.multiselect__option--selected{background:#f3f3f3;color:#35495e;font-weight:700}.multiselect__option--selected:after{content:attr(data-selected);color:silver;background:inherit}.multiselect__option--selected.multiselect__option--highlight{background:#ff6a6a;color:#fff}.multiselect__option--selected.multiselect__option--highlight:after{background:#ff6a6a;content:attr(data-deselect);color:#fff}.multiselect--disabled .multiselect__current,.multiselect--disabled .multiselect__select{background:#ededed;color:#a6a6a6}.multiselect__option--disabled{background:#ededed!important;color:#a6a6a6!important;cursor:text;pointer-events:none}.multiselect__option--group{background:#ededed;color:#35495e}.multiselect__option--group.multiselect__option--highlight{background:#35495e;color:#fff}.multiselect__option--group.multiselect__option--highlight:after{background:#35495e}.multiselect__option--disabled.multiselect__option--highlight{background:#dedede}.multiselect__option--group-selected.multiselect__option--highlight{background:#ff6a6a;color:#fff}.multiselect__option--group-selected.multiselect__option--highlight:after{background:#ff6a6a;content:attr(data-deselect);color:#fff}.multiselect-enter-active,.multiselect-leave-active{transition:all .15s ease}.multiselect-enter,.multiselect-leave-active{opacity:0}.multiselect__strong{margin-bottom:8px;line-height:20px;display:inline-block;vertical-align:top}[dir=rtl] .multiselect{text-align:right}[dir=rtl] .multiselect__select{right:auto;left:1px}[dir=rtl] .multiselect__tags{padding:8px 8px 0 40px}[dir=rtl] .multiselect__content{text-align:right}[dir=rtl] .multiselect__option:after{right:auto;left:0}[dir=rtl] .multiselect__clear{right:auto;left:12px}[dir=rtl] .multiselect__spinner{right:auto;left:1px}@keyframes spinning{0%{transform:rotate(0)}to{transform:rotate(2turn)}}.multiselect[data-v-4e27cb3c]{margin:0 .5em 1em .5em}#playerView[data-v-4e27cb3c]{margin:0 1rem 1rem 1rem;display:grid;overflow:auto;grid-template-columns:50% 50%}@media only screen and (max-width:922px){#playerView[data-v-4e27cb3c]{margin:0 1rem 1rem 1rem;display:grid;overflow:auto;grid-template-columns:100%;width:calc(100vw - 1em);margin:0 0 1rem 1rem}.multiselect[data-v-4e27cb3c]{width:calc(100% - 1em)}}#filters[data-v-4e27cb3c]{grid-area:filters} \ No newline at end of file diff --git a/dist/index.html b/dist/index.html index e6bddf3..760e3b4 100644 --- a/dist/index.html +++ b/dist/index.html @@ -1 +1 @@ -toneapi_webclient
\ No newline at end of file +toneapi_webclient
\ No newline at end of file diff --git a/dist/js/app.3775bac5.js b/dist/js/app.3775bac5.js new file mode 100644 index 0000000..9876e16 --- /dev/null +++ b/dist/js/app.3775bac5.js @@ -0,0 +1,2 @@ +(function(){"use strict";var e={271:function(e,t,s){var r=s(9242),a=s(3396);const l=(0,a.uE)('
',4);function i(e,t){const s=(0,a.up)("router-link"),r=(0,a.up)("router-view");return(0,a.wg)(),(0,a.iD)(a.HY,null,[(0,a._)("header",null,[(0,a._)("nav",null,[l,(0,a.Wm)(s,{to:"/",class:"navbar-element"},{default:(0,a.w5)((()=>[(0,a.Uk)("Players")])),_:1})])]),(0,a.Wm)(r)],64)}var n=s(89);const o={},d=(0,n.Z)(o,[["render",i]]);var c=d,h=s(2483);const p={id:"filters"},u={id:"playerView"};function y(e,t,s,r,l,i){const n=(0,a.up)("VueMultiselect"),o=(0,a.up)("PlayerList"),d=(0,a.up)("PlayerChart");return(0,a.wg)(),(0,a.iD)(a.HY,null,[(0,a._)("div",p,[(0,a.Wm)(n,{selectLabel:"",deselectLabel:"remove",placeholder:"Select server",modelValue:e.models.server,"onUpdate:modelValue":t[0]||(t[0]=t=>e.models.server=t),options:e.servers,"allow-empty":!0,"custom-label":e=>e.name,onSelect:t[1]||(t[1]=t=>e.changeFilter({server:t.id})),onRemove:t[2]||(t[2]=t=>e.changeFilter({server:""}))},null,8,["modelValue","options","custom-label"]),(0,a.Wm)(n,{selectLabel:"",deselectLabel:"remove",placeholder:"Select weapon",modelValue:e.models.weapon,"onUpdate:modelValue":t[3]||(t[3]=t=>e.models.weapon=t),options:e.sortedWeaponList,"allow-empty":!0,onSelect:t[4]||(t[4]=t=>e.changeFilter({weapon:t})),onRemove:t[5]||(t[5]=t=>e.changeFilter({weapon:""}))},null,8,["modelValue","options"]),(0,a.Wm)(n,{selectLabel:"",deselectLabel:"remove",placeholder:"Search player",modelValue:e.playerHighlighted,"onUpdate:modelValue":t[6]||(t[6]=t=>e.playerHighlighted=t),options:e.sortedPlayerList,"allow-empty":!0,"custom-label":t=>e.players[t]?.username},null,8,["modelValue","options","custom-label"])]),(0,a._)("div",u,[(0,a.Wm)(o,{filters:e.filters,onHighlightPlayer:t[7]||(t[7]=t=>e.playerHighlighted=t),playerHighlighted:e.playerHighlighted},null,8,["filters","playerHighlighted"]),(0,a.Wm)(d,{filters:e.filters,onHighlightPlayer:t[8]||(t[8]=t=>e.playerHighlighted=t),playerHighlighted:e.playerHighlighted},null,8,["filters","playerHighlighted"])])],64)}s(7658);var g=s(65),f=s(7139);const m=e=>((0,a.dD)("data-v-227422ef"),e=e(),(0,a.Cn)(),e),v={class:"playerHeaders"},b=m((()=>(0,a._)("span",null,null,-1))),w=["onClick"];function _(e,t,s,r,l,i){return(0,a.wg)(),(0,a.iD)("div",{class:"playerTable",onKeydown:t[6]||(t[6]=(...t)=>e.selectNextPlayer&&e.selectNextPlayer(...t)),tabindex:"0"},[(0,a._)("div",v,[b,(0,a._)("span",{onClick:t[0]||(t[0]=t=>e.sortPlayerList("username")),class:(0,f.C_)("username"==e.sortingData.argument?"selected":"")},"Username",2),(0,a._)("span",{onClick:t[1]||(t[1]=t=>e.sortPlayerList("kills")),class:(0,f.C_)("kills"==e.sortingData.argument?"selected":"")},"K",2),(0,a._)("span",{onClick:t[2]||(t[2]=t=>e.sortPlayerList("deaths")),class:(0,f.C_)("deaths"==e.sortingData.argument?"selected":"")},"D",2),(0,a._)("span",{onClick:t[3]||(t[3]=t=>e.sortPlayerList("k/d")),class:(0,f.C_)("k/d"==e.sortingData.argument?"selected":"")},"K/D",2),(0,a._)("span",{onClick:t[4]||(t[4]=t=>e.sortPlayerList("max_kill_distance")),class:(0,f.C_)("max_kill_distance"==e.sortingData.argument?"selected":"")},"max distance",2),(0,a._)("span",{onClick:t[5]||(t[5]=t=>e.sortPlayerList("avg_kill_distance")),class:(0,f.C_)("avg_kill_distance"==e.sortingData.argument?"selected":"")},"average distance",2)]),((0,a.wg)(!0),(0,a.iD)(a.HY,null,(0,a.Ko)(e.playerIdList,((t,s)=>((0,a.wg)(),(0,a.iD)("div",{class:"playerRow",key:t,onClick:s=>e.$emit("highlightPlayer",t),ref_for:!0,ref:"player:"+t},[(0,a._)("div",null,[(0,a._)("span",null,(0,f.zw)(s),1)]),(0,a._)("div",null,[(0,a._)("span",null,(0,f.zw)(e.players[t].username),1)]),(0,a._)("div",null,[(0,a._)("span",null,(0,f.zw)(e.players[t].kills),1)]),(0,a._)("div",null,[(0,a._)("span",null,(0,f.zw)(e.players[t].deaths),1)]),(0,a._)("div",null,[(0,a._)("span",null,(0,f.zw)(Math.round(e.players[t].kills/e.players[t].deaths*100)/100),1)]),(0,a._)("div",null,[(0,a._)("span",null,(0,f.zw)(e.players[t].max_kill_distance),1)]),(0,a._)("div",null,[(0,a._)("span",null,(0,f.zw)(Math.round(100*e.players[t].avg_kill_distance)/100),1)])],8,w)))),128))],32)}var k=(0,a.aZ)({props:{filters:Object,playerHighlighted:String},emits:["highlightPlayer"],data(){return{sortingData:{direction:-1,argument:"kills"},playerIdList:[],store:(0,g.oR)(),selected:void 0}},computed:{players(){return this.store.getters.getPlayerList(this.filters)}},watch:{players:{handler(e){e&&(this.playerIdList=[],this.sortingData.direction*=-1,this.playerIdList=Object.keys(e),this.sortPlayerList(this.sortingData.argument),this.$nextTick((()=>{const e=this.$refs["player:"+this.selected];e&&e.length>0&&e[0].classList.add("selected")})))},immediate:!0},playerHighlighted(e,t){const s=this.$refs["player:"+t];s&&(s[0].classList.remove("selected"),delete this.selected);const r=this.$refs["player:"+e];r&&(r[0].classList.add("selected"),r[0].scrollIntoView({behavior:"smooth",block:"center"}),this.selected=e)}},updated(){const e=this.$refs["player:"+this.$props.playerHighlighted];e&&e[0]&&e[0].scrollIntoView({behavior:"smooth",block:"center"})},methods:{sortPlayerList(e){e===this.sortingData.argument?this.sortingData.direction*=-1:"username"===e&&(this.sortingData.direction=1),this.sortingData.argument=e,this.playerIdList.sort(((t,s)=>{if(!this.players)return 0;let r,a;return"k/d"===e?(r=this.players[t].kills/this.players[t].deaths,a=this.players[s].kills/this.players[s].deaths):(r=this.players[t][e],a=this.players[s][e]),ra?1*this.sortingData.direction:0}))},selectNextPlayer(e){const t={Home:-1/0,End:1/0,PageDown:100,PageUp:-100,ArrowUp:-1,ArrowDown:1,ArrowRight:10,ArrowLeft:-10};if(!this.selected)return;if(!Object.keys(t).includes(e.key))return;e.preventDefault();const s=this.playerIdList.indexOf(this.selected);let r=s+t[e.key];r>=this.playerIdList.length&&(r=this.playerIdList.length-1),r<0&&(r=0),this.$emit("highlightPlayer",this.playerIdList[r])}}});const L=(0,n.Z)(k,[["render",_],["__scopeId","data-v-227422ef"]]);var P=L;const C={class:"playerChart",ref:"container"};function x(e,t,s,r,l,i){const n=(0,a.up)("Scatter");return(0,a.wg)(),(0,a.iD)("div",C,[(0,a.Wm)(n,{data:e.chart,options:e.chartOptions},null,8,["data","options"])],512)}var O=s(3254),D=s(9152),I=s(3013),H=s(5866);O.kL.register(O.f$,O.od,O.jn,O.u,O.De,D.Z,I.Z);var S=(0,a.aZ)({name:"PlayerChart",props:{filters:Object,playerHighlighted:String},emits:["highlightPlayer"],components:{Scatter:H.bp},mounted(){this.refreshColors++},computed:{colors(){this.refreshColors;const e={};if(this.$refs.container){const t=getComputedStyle(this.$refs.container);e.fg=t.getPropertyValue("--foreground"),e.bg=t.getPropertyValue("--bg-color"),e.orange=t.getPropertyValue("--orange"),e.cyan=t.getPropertyValue("--cyan"),e.currentLine=t.getPropertyValue("--current-line")}else e.fg="#ffffff";return e},chart(){const e={datasets:[{label:"Players",labels:[],borderColor:[this.colors.fg],backgroundColor:[this.colors.fg],pointRadius:[1],pointStyle:["dot"],hoverRadius:[4],data:[]}]};if(!this.players)return e;if(e.datasets[0].labels=this.playerIdList,e.datasets[0].data=this.playerIdList.map((e=>this.players?{x:this.players[e].deaths,y:this.players[e].kills}:{x:0,y:0})),e.datasets[0].pointRadius=Array(e.datasets[0].labels.length).fill(1),e.datasets[0].pointStyle=Array(e.datasets[0].labels.length).fill("dot"),e.datasets[0].borderColor=Array(e.datasets[0].labels.length).fill(this.colors.cyan),e.datasets[0].backgroundColor=e.datasets[0].borderColor,e.datasets[0].hoverRadius=Array(e.datasets[0].labels.length).fill(4),this.$props.playerHighlighted){const t=this.playerIdList.indexOf(this.$props.playerHighlighted);e.datasets[0].pointRadius[t]=20,e.datasets[0].pointStyle[t]="crossRot",e.datasets[0].borderColor[t]=this.colors.orange,e.datasets[0].hoverRadius[t]=30}return e},chartOptions(){const e={responsive:!0,maintainAspectRatio:!0,animation:{duration:500},layout:{autoPadding:!1},scales:{y:{title:{text:"Kills",display:!0,color:this.colors.fg},ticks:{color:this.colors.fg}},x:{title:{text:"Deaths",display:!0,color:this.colors.fg},ticks:{color:this.colors.fg}}},plugins:{tooltip:{callbacks:{label:e=>{let t;return t=this.players?this.players[e.dataset.labels[e.dataIndex]].username:e.dataset.labels[e.dataIndex],t+=" ("+e.parsed.y+" kills "+e.parsed.x+" deaths)",t}}},annotation:{},legend:{display:!1},datalabels:{formatter:(e,t)=>this.players[this.playerIdList[t.dataIndex]].username,backgroundColor:Array(this.playerIdList.length).fill(null),borderColor:this.colors.fg,borderWidth:Array(this.playerIdList.length).fill(0),borderRadius:5,display:Array(this.playerIdList.length).fill("auto"),align:"-45",anchor:"end",clamp:!0,color:Array(this.playerIdList.length).fill(this.colors.fg)}},onClick:(e,t)=>{this.$emit("highlightPlayer",t.length>0?this.playerIdList[t[0].index]:void 0)},onHover:(e,t)=>{e.native.target&&(e.native.target.style.cursor=t[0]?"pointer":"default")}};if(!this.players)return e;const t=Math.max(...Object.values(this.players).map((e=>e.deaths))),s=Math.max(...Object.values(this.players).map((e=>e.kills)));let r,a;if(s>t?(r=t,a=t/s*s):(a=s,r=s/t*t),e.plugins.annotation={annotations:{line:{type:"line",yMin:0,xMin:0,yMax:a,xMax:r,borderWidth:2,borderColor:this.colors.orange,borderDash:[1,5]}}},this.$props.playerHighlighted){const t=this.playerIdList.indexOf(this.$props.playerHighlighted);e.plugins.datalabels.display[t]=!0,e.plugins.datalabels.backgroundColor[t]=this.colors.orange,e.plugins.datalabels.borderWidth[t]=1,e.plugins.datalabels.color[t]=this.colors.bg}return e},players(){return this.store.getters.getPlayerList(this.filters)||{}},playerIdList(){return Object.keys(this.players)}},data(){return{store:(0,g.oR)(),refreshColors:0}}});const j=(0,n.Z)(S,[["render",x],["__scopeId","data-v-cf8f72c6"]]);var W=j,V=s(6368),R=(0,a.aZ)({name:"PlayerView",components:{PlayerList:P,PlayerChart:W,VueMultiselect:V.ZP},data(){return{models:{},filters:{minKills:100,minDeaths:100},store:(0,g.oR)(),playerHighlighted:void 0}},computed:{servers(){return this.store.state.servers},weapons(){return this.store.getters.getWeaponList(this.filters)},sortedWeaponList(){if(!this.weapons)return[];const e=Object.keys(this.weapons);return e.sort()},players(){return this.store.getters.getPlayerList(this.filters)},sortedPlayerList(){if(!this.players)return[];const e=Object.keys(this.players);return e.sort(((e,t)=>this.players?this.players[e].usernamethis.players[t].username?1:0:0))}},watch:{test:function(e){console.log(e)}},methods:{async changeFilter({weapon:e,server:t}){console.log(e);const s=JSON.parse(JSON.stringify(this.filters));void 0!==e&&(s.weapon=e),void 0!==t&&(s.server=t),""===e&&delete s.weapon,""===t&&delete s.server;const r=[];this.store.getters.getPlayerList(s)||r.push(this.store.dispatch("fetchPlayers",s)),this.store.getters.getWeaponList(s)||r.push(this.store.dispatch("fetchWeapons",s)),await Promise.all(r),this.filters=s}}});const $=(0,n.Z)(R,[["render",y],["__scopeId","data-v-4e27cb3c"]]);var A=$;const M=[{path:"/",name:"home",component:A}],N=(0,h.p7)({history:(0,h.PO)("/Tone_WebClient/"),routes:M});var Z=N;Symbol();var z=(0,g.MT)({state:{servers:[],players:{},weapons:{}},getters:{getPlayerList:e=>({server:t,weapon:s,minKills:r,minDeaths:a})=>{let l=[];return e.players[""]&&(l=Object.entries(e.players[""]).filter((([,e])=>e.kills>=r||e.deaths>=a)).map((e=>e[0]))),l.length>0&&e.players[(t||"")+(s||"")]?Object.fromEntries(Object.entries(e.players[(t||"")+(s||"")]).filter((([e])=>l.includes(e)))):e.players[(t||"")+(s||"")]},getWeaponList:e=>({server:t,player:s})=>e.weapons[(t||"")+(s||"")]},mutations:{setPlayers(e,t){e.players[(t.filters.server||"")+(t.filters.weapon||"")]=t.data},setWeapons(e,t){e.weapons[(t.filters.server||"")+(t.filters.player||"")]=t.data},setServers(e,t){e.servers=t}},actions:{async fetchPlayers(e,{weapon:t,server:s}){const r={};t?.toString()&&(r.weapon=t),s?.toString()&&(r.server=s);const a=await fetch("https://tone.sleepycat.date/v1/client/players?"+new URLSearchParams(r)),l=await a.json();Object.keys(l).forEach((e=>{l[e].kills=Number(l[e].kills),l[e].deaths=Number(l[e].deaths),l[e].max_kill_distance=Number(l[e].max_kill_distance),l[e].avg_kill_distance=Number(l[e].avg_kill_distance)})),e.commit("setPlayers",{data:l,filters:{weapon:t,server:s}})},async fetchWeapons(e,{player:t,server:s}){const r={};t?.toString()&&(r.player=t),s?.toString()&&(r.server=s);const a=await fetch("https://tone.sleepycat.date/v1/client/weapons?"+new URLSearchParams(r)),l=await a.json();e.commit("setWeapons",{data:l,filters:{player:t,server:s}})},async fetchServers(e){const t=await fetch("https://tone.sleepycat.date/v1/client/servers"),s=await t.json();e.commit("setServers",s)}},modules:{}});(0,r.ri)(c).use(z).use(Z).mount("#app"),z.dispatch("fetchServers",{}),z.dispatch("fetchPlayers",{}),z.dispatch("fetchWeapons",{})}},t={};function s(r){var a=t[r];if(void 0!==a)return a.exports;var l=t[r]={exports:{}};return e[r](l,l.exports,s),l.exports}s.m=e,function(){var e=[];s.O=function(t,r,a,l){if(!r){var i=1/0;for(c=0;c=l)&&Object.keys(s.O).every((function(e){return s.O[e](r[o])}))?r.splice(o--,1):(n=!1,l0&&e[c-1][2]>l;c--)e[c]=e[c-1];e[c]=[r,a,l]}}(),function(){s.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return s.d(t,{a:t}),t}}(),function(){s.d=function(e,t){for(var r in t)s.o(t,r)&&!s.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}}(),function(){s.g=function(){if("object"===typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"===typeof window)return window}}()}(),function(){s.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}}(),function(){var e={143:0};s.O.j=function(t){return 0===e[t]};var t=function(t,r){var a,l,i=r[0],n=r[1],o=r[2],d=0;if(i.some((function(t){return 0!==e[t]}))){for(a in n)s.o(n,a)&&(s.m[a]=n[a]);if(o)var c=o(s)}for(t&&t(r);d\n
\n \n
\n \n\n\n\n","import { render } from \"./App.vue?vue&type=template&id=3e556bf7\"\nconst script = {}\n\nimport \"./App.vue?vue&type=style&index=0&id=3e556bf7&lang=css\"\n\nimport exportComponent from \"C:\\\\Users\\\\legon\\\\Documents\\\\Code\\\\toneapi_webclient\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import { resolveComponent as _resolveComponent, createVNode as _createVNode, createElementVNode as _createElementVNode, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, pushScopeId as _pushScopeId, popScopeId as _popScopeId } from \"vue\"\n\nconst _withScopeId = n => (_pushScopeId(\"data-v-4e27cb3c\"),n=n(),_popScopeId(),n)\nconst _hoisted_1 = { id: \"filters\" }\nconst _hoisted_2 = { id: \"playerView\" }\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n const _component_VueMultiselect = _resolveComponent(\"VueMultiselect\")!\n const _component_PlayerList = _resolveComponent(\"PlayerList\")!\n const _component_PlayerChart = _resolveComponent(\"PlayerChart\")!\n\n return (_openBlock(), _createElementBlock(_Fragment, null, [\n _createElementVNode(\"div\", _hoisted_1, [\n _createVNode(_component_VueMultiselect, {\n selectLabel: \"\",\n deselectLabel: \"remove\",\n placeholder: \"Select server\",\n modelValue: _ctx.models.server,\n \"onUpdate:modelValue\": _cache[0] || (_cache[0] = ($event: any) => ((_ctx.models.server) = $event)),\n options: _ctx.servers,\n \"allow-empty\": true,\n \"custom-label\": ((e) => e.name),\n onSelect: _cache[1] || (_cache[1] = ($event: any) => (_ctx.changeFilter({ server: $event.id }))),\n onRemove: _cache[2] || (_cache[2] = ($event: any) => (_ctx.changeFilter({ server: '' })))\n }, null, 8, [\"modelValue\", \"options\", \"custom-label\"]),\n _createVNode(_component_VueMultiselect, {\n selectLabel: \"\",\n deselectLabel: \"remove\",\n placeholder: \"Select weapon\",\n modelValue: _ctx.models.weapon,\n \"onUpdate:modelValue\": _cache[3] || (_cache[3] = ($event: any) => ((_ctx.models.weapon) = $event)),\n options: _ctx.sortedWeaponList,\n \"allow-empty\": true,\n onSelect: _cache[4] || (_cache[4] = ($event: any) => (_ctx.changeFilter({ weapon: $event }))),\n onRemove: _cache[5] || (_cache[5] = ($event: any) => (_ctx.changeFilter({ weapon: '' })))\n }, null, 8, [\"modelValue\", \"options\"]),\n _createVNode(_component_VueMultiselect, {\n selectLabel: \"\",\n deselectLabel: \"remove\",\n placeholder: \"Search player\",\n modelValue: _ctx.playerHighlighted,\n \"onUpdate:modelValue\": _cache[6] || (_cache[6] = ($event: any) => ((_ctx.playerHighlighted) = $event)),\n options: _ctx.sortedPlayerList,\n \"allow-empty\": true,\n \"custom-label\": ((e) => _ctx.players[e]?.username)\n }, null, 8, [\"modelValue\", \"options\", \"custom-label\"])\n ]),\n _createElementVNode(\"div\", _hoisted_2, [\n _createVNode(_component_PlayerList, {\n filters: _ctx.filters,\n onHighlightPlayer: _cache[7] || (_cache[7] = ($event: any) => (_ctx.playerHighlighted = $event)),\n playerHighlighted: _ctx.playerHighlighted\n }, null, 8, [\"filters\", \"playerHighlighted\"]),\n _createVNode(_component_PlayerChart, {\n filters: _ctx.filters,\n onHighlightPlayer: _cache[8] || (_cache[8] = ($event: any) => (_ctx.playerHighlighted = $event)),\n playerHighlighted: _ctx.playerHighlighted\n }, null, 8, [\"filters\", \"playerHighlighted\"])\n ])\n ], 64))\n}","import { createElementVNode as _createElementVNode, normalizeClass as _normalizeClass, renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, toDisplayString as _toDisplayString, pushScopeId as _pushScopeId, popScopeId as _popScopeId } from \"vue\"\n\nconst _withScopeId = n => (_pushScopeId(\"data-v-227422ef\"),n=n(),_popScopeId(),n)\nconst _hoisted_1 = { class: \"playerHeaders\" }\nconst _hoisted_2 = /*#__PURE__*/ _withScopeId(() => /*#__PURE__*/_createElementVNode(\"span\", null, null, -1))\nconst _hoisted_3 = [\"onClick\"]\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n return (_openBlock(), _createElementBlock(\"div\", {\n class: \"playerTable\",\n onKeydown: _cache[6] || (_cache[6] = \n//@ts-ignore\n(...args) => (_ctx.selectNextPlayer && _ctx.selectNextPlayer(...args))),\n tabindex: \"0\"\n }, [\n _createElementVNode(\"div\", _hoisted_1, [\n _hoisted_2,\n _createElementVNode(\"span\", {\n onClick: _cache[0] || (_cache[0] = ($event: any) => (_ctx.sortPlayerList('username'))),\n class: _normalizeClass(_ctx.sortingData.argument == 'username' ? 'selected' : '')\n }, \"Username\", 2),\n _createElementVNode(\"span\", {\n onClick: _cache[1] || (_cache[1] = ($event: any) => (_ctx.sortPlayerList('kills'))),\n class: _normalizeClass(_ctx.sortingData.argument == 'kills' ? 'selected' : '')\n }, \"K\", 2),\n _createElementVNode(\"span\", {\n onClick: _cache[2] || (_cache[2] = ($event: any) => (_ctx.sortPlayerList('deaths'))),\n class: _normalizeClass(_ctx.sortingData.argument == 'deaths' ? 'selected' : '')\n }, \"D\", 2),\n _createElementVNode(\"span\", {\n onClick: _cache[3] || (_cache[3] = ($event: any) => (_ctx.sortPlayerList('k/d'))),\n class: _normalizeClass(_ctx.sortingData.argument == 'k/d' ? 'selected' : '')\n }, \"K/D\", 2),\n _createElementVNode(\"span\", {\n onClick: _cache[4] || (_cache[4] = ($event: any) => (_ctx.sortPlayerList('max_kill_distance'))),\n class: _normalizeClass(_ctx.sortingData.argument == 'max_kill_distance' ? 'selected' : '')\n }, \"max distance\", 2),\n _createElementVNode(\"span\", {\n onClick: _cache[5] || (_cache[5] = ($event: any) => (_ctx.sortPlayerList('avg_kill_distance'))),\n class: _normalizeClass(_ctx.sortingData.argument == 'avg_kill_distance' ? 'selected' : '')\n }, \"average distance\", 2)\n ]),\n (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.playerIdList, (playerId, index) => {\n return (_openBlock(), _createElementBlock(\"div\", {\n class: \"playerRow\",\n key: playerId,\n onClick: ($event: any) => (_ctx.$emit('highlightPlayer', playerId)),\n ref_for: true,\n ref: `player:` + playerId\n }, [\n _createElementVNode(\"div\", null, [\n _createElementVNode(\"span\", null, _toDisplayString(index), 1)\n ]),\n _createElementVNode(\"div\", null, [\n _createElementVNode(\"span\", null, _toDisplayString(_ctx.players[playerId].username), 1)\n ]),\n _createElementVNode(\"div\", null, [\n _createElementVNode(\"span\", null, _toDisplayString(_ctx.players[playerId].kills), 1)\n ]),\n _createElementVNode(\"div\", null, [\n _createElementVNode(\"span\", null, _toDisplayString(_ctx.players[playerId].deaths), 1)\n ]),\n _createElementVNode(\"div\", null, [\n _createElementVNode(\"span\", null, _toDisplayString(Math.round(_ctx.players[playerId].kills / _ctx.players[playerId].deaths * 100) / 100), 1)\n ]),\n _createElementVNode(\"div\", null, [\n _createElementVNode(\"span\", null, _toDisplayString(_ctx.players[playerId].max_kill_distance), 1)\n ]),\n _createElementVNode(\"div\", null, [\n _createElementVNode(\"span\", null, _toDisplayString(Math.round(_ctx.players[playerId].avg_kill_distance * 100) / 100), 1)\n ])\n ], 8, _hoisted_3))\n }), 128))\n ], 32))\n}","\nimport { defineComponent } from 'vue'\nimport { Player } from '@/store/index'\nimport { useStore } from 'vuex'\nimport { Vue } from 'vue-class-component'\n\nexport default defineComponent({\n props: {\n filters: Object,\n playerHighlighted: String\n },\n emits: ['highlightPlayer'],\n data () {\n return {\n sortingData: { direction: -1, argument: 'kills' as keyof Player | 'k/d' },\n playerIdList: [] as string[],\n store: useStore(),\n selected: undefined as string | undefined\n }\n },\n computed: {\n players (): { [key: string]: Player } { return this.store.getters.getPlayerList(this.filters) }\n },\n watch: {\n players: {\n handler (newval: { [key: string]: Player }): void {\n if (!newval) return\n this.playerIdList = []\n this.sortingData.direction *= -1\n this.playerIdList = Object.keys(newval)\n this.sortPlayerList(this.sortingData.argument)\n this.$nextTick(() => {\n const element = (this.$refs['player:' + this.selected] as HTMLElement[])\n if (element && element.length > 0) element[0].classList.add('selected')\n })\n },\n immediate: true\n },\n playerHighlighted (newval, oldval) {\n const oldElement = this.$refs['player:' + oldval] as HTMLElement[]\n if (oldElement) {\n oldElement[0].classList.remove('selected')\n delete this.selected\n }\n const newElement = this.$refs['player:' + newval] as HTMLElement[]\n if (!newElement) return\n newElement[0].classList.add('selected')\n newElement[0].scrollIntoView({ behavior: 'smooth', block: 'center' })\n this.selected = newval\n }\n },\n updated () {\n const element = this.$refs['player:' + this.$props.playerHighlighted] as HTMLElement[]\n if (!element || !element[0]) return\n element[0].scrollIntoView({ behavior: 'smooth', block: 'center' })\n },\n methods: {\n sortPlayerList (arg: ((keyof Player) | 'k/d')) {\n if (arg === this.sortingData.argument) {\n this.sortingData.direction *= -1\n } else {\n if (arg === 'username') {\n this.sortingData.direction = 1\n }\n }\n this.sortingData.argument = arg\n\n this.playerIdList.sort((a: string, b: string) => {\n if (!this.players) {\n return 0\n }\n let varA, varB\n if (arg === 'k/d') {\n varA = this.players[a].kills / this.players[a].deaths\n varB = this.players[b].kills / this.players[b].deaths\n } else {\n varA = this.players[a][arg]\n varB = this.players[b][arg]\n }\n\n if (varA < varB) {\n return -1 * this.sortingData.direction\n }\n if (varA > varB) {\n return 1 * this.sortingData.direction\n }\n return 0\n })\n },\n selectNextPlayer (e: KeyboardEvent) {\n const values = {\n Home: -Infinity,\n End: Infinity,\n PageDown: 100,\n PageUp: -100,\n ArrowUp: -1,\n ArrowDown: 1,\n ArrowRight: 10,\n ArrowLeft: -10\n } as { [key: string]: number }\n if (!this.selected) return\n if (!Object.keys(values).includes(e.key)) return\n e.preventDefault()\n const index = this.playerIdList.indexOf(this.selected)\n let nextIndex = (index + values[e.key])\n if (nextIndex >= this.playerIdList.length) nextIndex = this.playerIdList.length - 1\n if (nextIndex < 0) nextIndex = 0\n this.$emit('highlightPlayer', this.playerIdList[nextIndex])\n }\n }\n\n})\n","import { render } from \"./PlayerList.vue?vue&type=template&id=227422ef&scoped=true&ts=true\"\nimport script from \"./PlayerList.vue?vue&type=script&lang=ts\"\nexport * from \"./PlayerList.vue?vue&type=script&lang=ts\"\n\nimport \"./PlayerList.vue?vue&type=style&index=0&id=227422ef&scoped=true&lang=css\"\n\nimport exportComponent from \"C:\\\\Users\\\\legon\\\\Documents\\\\Code\\\\toneapi_webclient\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-227422ef\"]])\n\nexport default __exports__","import { resolveComponent as _resolveComponent, createVNode as _createVNode, openBlock as _openBlock, createElementBlock as _createElementBlock, pushScopeId as _pushScopeId, popScopeId as _popScopeId } from \"vue\"\n\nconst _withScopeId = n => (_pushScopeId(\"data-v-cf8f72c6\"),n=n(),_popScopeId(),n)\nconst _hoisted_1 = {\n class: \"playerChart\",\n ref: \"container\"\n}\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n const _component_Scatter = _resolveComponent(\"Scatter\")!\n\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1, [\n _createVNode(_component_Scatter, {\n data: _ctx.chart,\n options: _ctx.chartOptions\n }, null, 8, [\"data\", \"options\"])\n ], 512))\n}","\nimport {\n Chart as ChartJS,\n LinearScale,\n PointElement,\n LineElement,\n Tooltip,\n Legend\n} from 'chart.js'\nimport annotationPlugin from 'chartjs-plugin-annotation'\nimport dataLabel from 'chartjs-plugin-datalabels'\nimport { Store, useStore } from 'vuex'\nimport { Player, Weapon } from '@/store/index'\n\nimport { Scatter } from 'vue-chartjs'\nimport { defineComponent } from 'vue'\n\nChartJS.register(LinearScale, PointElement, LineElement, Tooltip, Legend, annotationPlugin, dataLabel)\n\nexport default defineComponent({\n name: 'PlayerChart',\n props: {\n filters: Object,\n playerHighlighted: String\n },\n emits: ['highlightPlayer'],\n components: {\n Scatter\n },\n mounted () {\n this.refreshColors++\n },\n computed: {\n colors () {\n // eslint-disable-next-line no-unused-expressions\n this.refreshColors\n const colors = {} as {[key:string]:string}\n if (this.$refs.container) {\n const style = getComputedStyle(this.$refs.container as Element)\n colors.fg = style.getPropertyValue('--foreground')\n colors.bg = style.getPropertyValue('--bg-color')\n colors.orange = style.getPropertyValue('--orange')\n colors.cyan = style.getPropertyValue('--cyan')\n colors.currentLine = style.getPropertyValue('--current-line')\n } else {\n colors.fg = '#ffffff'\n }\n return colors\n },\n chart () {\n const chartData = {\n datasets: [\n {\n label: 'Players',\n labels: [] as string[],\n borderColor: [this.colors.fg],\n backgroundColor: [this.colors.fg],\n pointRadius: [1],\n pointStyle: ['dot'],\n hoverRadius: [4],\n data: [] as {x:number, y:number}[]\n }\n ]\n }\n if (!this.players) {\n return chartData\n }\n chartData.datasets[0].labels = this.playerIdList\n chartData.datasets[0].data = this.playerIdList.map(e => {\n if (!this.players) {\n return { x: 0, y: 0 }\n }\n return { x: this.players[e].deaths, y: this.players[e].kills }\n })\n chartData.datasets[0].pointRadius = Array(chartData.datasets[0].labels.length).fill(1)\n chartData.datasets[0].pointStyle = Array(chartData.datasets[0].labels.length).fill('dot')\n chartData.datasets[0].borderColor = Array(chartData.datasets[0].labels.length).fill(this.colors.cyan)\n chartData.datasets[0].backgroundColor = chartData.datasets[0].borderColor\n chartData.datasets[0].hoverRadius = Array(chartData.datasets[0].labels.length).fill(4)\n if (this.$props.playerHighlighted) {\n const index = this.playerIdList.indexOf(this.$props.playerHighlighted)\n chartData.datasets[0].pointRadius[index] = 20\n chartData.datasets[0].pointStyle[index] = 'crossRot'\n chartData.datasets[0].borderColor[index] = this.colors.orange\n // No need to do that since arrays are already the same (reference)\n // chartData.datasets[0].backgroundColor[index] = chartData.datasets[0].borderColor[index]\n chartData.datasets[0].hoverRadius[index] = 30\n }\n return chartData\n },\n chartOptions () {\n const options = {\n responsive: true,\n maintainAspectRatio: true,\n animation: { duration: 500 },\n layout: { autoPadding: false },\n scales: {\n y: {\n title: {\n text: 'Kills',\n display: true,\n color: this.colors.fg\n },\n ticks: {\n color: this.colors.fg\n }\n },\n x: {\n title: {\n text: 'Deaths',\n display: true,\n color: this.colors.fg\n },\n ticks: {\n color: this.colors.fg\n }\n }\n },\n plugins: {\n tooltip: {\n callbacks: {\n label: (ctx:any) => {\n let label:string\n if (!this.players) {\n label = ctx.dataset.labels[ctx.dataIndex]\n } else {\n label = this.players[ctx.dataset.labels[ctx.dataIndex]].username\n }\n label += ' (' + ctx.parsed.y + ' kills ' + ctx.parsed.x + ' deaths)'\n return label\n }\n }\n },\n annotation: {},\n legend: { display: false },\n datalabels: {\n formatter: (value:any, context:any) => {\n return this.players[this.playerIdList[context.dataIndex]].username\n },\n backgroundColor: Array(this.playerIdList.length).fill(null),\n borderColor: this.colors.fg,\n borderWidth: Array(this.playerIdList.length).fill(0),\n borderRadius: 5,\n display: Array(this.playerIdList.length).fill('auto'),\n align: '-45',\n anchor: 'end',\n clamp: true,\n color: Array(this.playerIdList.length).fill(this.colors.fg)\n }\n },\n onClick: (e:Event, element:any) => {\n this.$emit('highlightPlayer', element.length > 0 ? this.playerIdList[element[0].index] : undefined)\n },\n onHover: (e:any, element:any) => {\n if (!e.native.target) return\n (e.native.target as HTMLElement).style.cursor = element[0] ? 'pointer' : 'default'\n }\n }\n if (!this.players) {\n return options\n }\n const maxX = Math.max(...Object.values(this.players).map(e => e.deaths))\n const maxY = Math.max(...Object.values(this.players).map(e => e.kills))\n let endX, endY\n if (maxY > maxX) {\n endX = maxX\n endY = (maxX / maxY) * maxY\n } else {\n endY = maxY\n endX = (maxY / maxX) * maxX\n }\n options.plugins.annotation = {\n annotations: {\n line: {\n type: 'line',\n yMin: 0,\n xMin: 0,\n yMax: endY,\n xMax: endX,\n borderWidth: 2,\n borderColor: this.colors.orange,\n borderDash: [1, 5]\n }\n }\n }\n\n if (this.$props.playerHighlighted) {\n const index = this.playerIdList.indexOf(this.$props.playerHighlighted)\n options.plugins.datalabels.display[index] = true\n options.plugins.datalabels.backgroundColor[index] = this.colors.orange\n options.plugins.datalabels.borderWidth[index] = 1\n options.plugins.datalabels.color[index] = this.colors.bg\n }\n return options\n },\n players ():{[key:string]:Player} { return this.store.getters.getPlayerList(this.filters) || {} },\n playerIdList ():string[] { return Object.keys(this.players) }\n\n },\n data () {\n return {\n store: useStore(),\n refreshColors: 0\n }\n }\n})\n","import { render } from \"./PlayerChart.vue?vue&type=template&id=cf8f72c6&scoped=true&ts=true\"\nimport script from \"./PlayerChart.vue?vue&type=script&lang=ts\"\nexport * from \"./PlayerChart.vue?vue&type=script&lang=ts\"\n\nimport \"./PlayerChart.vue?vue&type=style&index=0&id=cf8f72c6&scoped=true&lang=css\"\n\nimport exportComponent from \"C:\\\\Users\\\\legon\\\\Documents\\\\Code\\\\toneapi_webclient\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-cf8f72c6\"]])\n\nexport default __exports__","\nimport { Store, useStore } from 'vuex'\nimport { Player, Weapon, Server } from '@/store/index'\nimport PlayerList from '@/components/PlayerList.vue'\nimport PlayerChart from '@/components/PlayerChart.vue'\nimport { defineComponent } from 'vue'\nimport VueMultiselect from 'vue-multiselect'\nimport 'vue-multiselect/dist/vue-multiselect.css'\n\nexport default defineComponent({\n name: 'PlayerView',\n components: {\n PlayerList, PlayerChart, VueMultiselect\n },\n\n data () {\n return {\n models: {},\n filters: { minKills: 100, minDeaths: 100 },\n store: useStore(),\n playerHighlighted: undefined\n } as { filters: { weapon?: string, server?: string }, store: Store, playerHighlighted?: string }\n },\n computed: {\n servers (): Server[] { return this.store.state.servers },\n weapons (): { [key: string]: Weapon } { return this.store.getters.getWeaponList(this.filters) },\n sortedWeaponList (): string[] {\n if (!this.weapons) return []\n const weapons = Object.keys(this.weapons)\n return weapons.sort()\n },\n players (): { [key: string]: Player } { return this.store.getters.getPlayerList(this.filters) },\n sortedPlayerList (): string[] {\n if (!this.players) return []\n const players = Object.keys(this.players)\n return players.sort((a: string, b: string) => {\n if (!this.players) {\n return 0\n }\n\n if (this.players[a].username < this.players[b].username) {\n return -1\n }\n if (this.players[a].username > this.players[b].username) {\n return 1\n }\n return 0\n })\n }\n },\n watch: {\n test: function (newval) {\n console.log(newval)\n }\n },\n methods: {\n async changeFilter ({ weapon, server }: { weapon?: string, server?: string }) {\n console.log(weapon)\n const filters = JSON.parse(JSON.stringify(this.filters))\n if (weapon !== undefined) filters.weapon = weapon\n if (server !== undefined) filters.server = server\n if (weapon === '') delete filters.weapon\n if (server === '') delete filters.server\n const promises = []\n if (!this.store.getters.getPlayerList(filters)) promises.push(this.store.dispatch('fetchPlayers', filters))\n if (!this.store.getters.getWeaponList(filters)) promises.push(this.store.dispatch('fetchWeapons', filters))\n await Promise.all(promises)\n // Delay the update of filters propery after we fetch the data to the API as changing it will cause subcomponents to reload before data is fetched\n this.filters = filters\n }\n }\n})\n","import { render } from \"./PlayerView.vue?vue&type=template&id=4e27cb3c&scoped=true&ts=true\"\nimport script from \"./PlayerView.vue?vue&type=script&lang=ts\"\nexport * from \"./PlayerView.vue?vue&type=script&lang=ts\"\n\nimport \"./PlayerView.vue?vue&type=style&index=0&id=4e27cb3c&scoped=true&lang=css\"\n\nimport exportComponent from \"C:\\\\Users\\\\legon\\\\Documents\\\\Code\\\\toneapi_webclient\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-4e27cb3c\"]])\n\nexport default __exports__","import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'\nimport HomeView from '../views/HomeView.vue'\nimport PlayerView from '../views/PlayerView.vue'\n\nconst routes: Array = [\n {\n path: '/',\n name: 'home',\n component: PlayerView\n }\n // {\n // path: '/players',\n // name: 'players',\n // component: PlayerView\n // },\n // {\n // path: '/about',\n // name: 'about',\n // // route level code-splitting\n // // this generates a separate chunk (about.[hash].js) for this route\n // // which is lazy-loaded when the route is visited.\n // component: () => import(/* webpackChunkName: \"about\" */ '../views/AboutView.vue')\n // }\n]\n\nconst router = createRouter({\n history: createWebHistory(process.env.BASE_URL),\n routes\n})\n\nexport default router\n","// store.ts\nimport { InjectionKey } from 'vue'\nimport { createStore, Store } from 'vuex'\n\nexport interface Player {\n deaths: number;\n username: string;\n // eslint-disable-next-line camelcase\n max_kill_distance: number;\n // eslint-disable-next-line camelcase\n avg_kill_distance: number;\n kills: number;\n}\n\nexport interface Weapon {\n // eslint-disable-next-line camelcase\n max_kill_distance: number;\n // eslint-disable-next-line camelcase\n avg_kill_distance: number;\n kills: number;\n}\n\nexport interface Server{\n name:string;\n id:number;\n description:string\n}\n// define your typings for the store state\nexport interface State {\n servers: Server[]\n players: { [key: string]: { [key: string]: Player } };\n weapons: { [key: string]:{ [key: string]: Weapon }};\n}\n\n// define injection key\n// eslint-disable-next-line symbol-description\nexport const key: InjectionKey> = Symbol()\n\nexport default createStore({\n state: {\n servers: [],\n players: {},\n weapons: {}\n },\n getters: {\n getPlayerList: (state) => ({ server, weapon, minKills, minDeaths }: { server?: number, weapon?: string, minKills:number, minDeaths:number }) => {\n let playerFilter: string[] = []\n if (state.players['']) {\n playerFilter = Object.entries(state.players['']).filter(([, value]:any) => { return (value.kills >= minKills) || (value.deaths >= minDeaths) }).map(e => e[0])\n }\n if (playerFilter.length > 0 && state.players[(server || '') + (weapon || '')]) {\n return Object.fromEntries(Object.entries(state.players[(server || '') + (weapon || '')]).filter(([key]) => playerFilter.includes(key)))\n }\n\n return state.players[(server || '') + (weapon || '')]\n },\n getWeaponList: (state) => ({ server, player }: { server?: number, player?: string }) => {\n return state.weapons[(server || '') + (player || '')]\n }\n },\n mutations: {\n setPlayers (state, data: { data: { [key: string]: Player }, filters: { weapon: string, server: number } }) {\n state.players[(data.filters.server || '') + (data.filters.weapon || '')] = data.data\n },\n setWeapons (state, data:{data: {[key:string]:Weapon}, filters:{server:string, player:string}}) {\n state.weapons[(data.filters.server || '') + (data.filters.player || '')] = data.data\n },\n setServers (state, data) {\n state.servers = data\n }\n },\n actions: {\n async fetchPlayers (context, { weapon, server }) {\n const searchParams: Record = {}\n if (weapon?.toString()) { searchParams.weapon = weapon }\n if (server?.toString()) { searchParams.server = server }\n const response = await fetch(\n 'https://tone.sleepycat.date/v1/client/players?' + new URLSearchParams(searchParams)\n )\n const data = await response.json()\n Object.keys(data).forEach(e => {\n data[e].kills = Number(data[e].kills)\n data[e].deaths = Number(data[e].deaths)\n data[e].max_kill_distance = Number(data[e].max_kill_distance)\n data[e].avg_kill_distance = Number(data[e].avg_kill_distance)\n })\n\n context.commit('setPlayers', { data, filters: { weapon, server } })\n },\n async fetchWeapons (context, { player, server }) {\n const searchParams: Record = {}\n if (player?.toString()) { searchParams.player = player }\n if (server?.toString()) { searchParams.server = server }\n const response = await fetch(\n 'https://tone.sleepycat.date/v1/client/weapons?' + new URLSearchParams(searchParams)\n )\n const data = await response.json()\n context.commit('setWeapons', { data, filters: { player, server } })\n },\n async fetchServers (context) {\n const response = await fetch(\n 'https://tone.sleepycat.date/v1/client/servers'\n )\n const data = await response.json()\n context.commit('setServers', data)\n }\n },\n modules: {}\n})\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).use(store).use(router).mount('#app')\r\n\r\nstore.dispatch('fetchServers', {})\r\nstore.dispatch('fetchPlayers', {})\r\nstore.dispatch('fetchWeapons', {})\r\n","// 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__.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); }","// 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// no chunk on demand loading\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[\"webpackChunktoneapi_webclient\"] = self[\"webpackChunktoneapi_webclient\"] || [];\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__(271); })\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["_createElementVNode","_hoisted_1","_createVNode","_component_router_link","to","class","_component_router_view","script","__exports__","render","id","_hoisted_2","_ctx","_cache","$props","$setup","$data","$options","_component_VueMultiselect","_resolveComponent","_component_PlayerList","_component_PlayerChart","_openBlock","_createElementBlock","_Fragment","selectLabel","deselectLabel","placeholder","modelValue","models","server","$event","options","servers","e","name","onSelect","changeFilter","onRemove","weapon","sortedWeaponList","playerHighlighted","sortedPlayerList","players","username","filters","onHighlightPlayer","_withScopeId","n","_pushScopeId","_popScopeId","_hoisted_3","onKeydown","args","selectNextPlayer","tabindex","onClick","sortPlayerList","_normalizeClass","sortingData","argument","_renderList","playerIdList","playerId","index","key","$emit","ref_for","ref","_toDisplayString","kills","deaths","Math","round","max_kill_distance","avg_kill_distance","defineComponent","props","Object","String","emits","data","direction","store","useStore","selected","undefined","computed","this","getters","getPlayerList","watch","handler","newval","keys","$nextTick","element","$refs","length","classList","add","immediate","oldval","oldElement","remove","newElement","scrollIntoView","behavior","block","updated","methods","arg","sort","a","b","varA","varB","values","Home","Infinity","End","PageDown","PageUp","ArrowUp","ArrowDown","ArrowRight","ArrowLeft","includes","preventDefault","indexOf","nextIndex","_component_Scatter","chart","chartOptions","ChartJS","LinearScale","PointElement","LineElement","Tooltip","Legend","annotationPlugin","dataLabel","components","Scatter","mounted","refreshColors","colors","container","style","getComputedStyle","fg","getPropertyValue","bg","orange","cyan","currentLine","chartData","datasets","label","labels","borderColor","backgroundColor","pointRadius","pointStyle","hoverRadius","map","x","y","Array","fill","responsive","maintainAspectRatio","animation","duration","layout","autoPadding","scales","title","text","display","color","ticks","plugins","tooltip","callbacks","ctx","dataset","dataIndex","parsed","annotation","legend","datalabels","formatter","value","context","borderWidth","borderRadius","align","anchor","clamp","onHover","native","target","cursor","maxX","max","maxY","endX","endY","annotations","line","type","yMin","xMin","yMax","xMax","borderDash","PlayerList","PlayerChart","VueMultiselect","minKills","minDeaths","state","weapons","getWeaponList","test","console","log","async","JSON","parse","stringify","promises","push","dispatch","Promise","all","routes","path","component","PlayerView","router","createRouter","history","createWebHistory","process","Symbol","createStore","playerFilter","entries","filter","fromEntries","player","mutations","setPlayers","setWeapons","setServers","actions","searchParams","toString","response","fetch","URLSearchParams","json","forEach","Number","commit","modules","createApp","App","use","mount","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","exports","module","__webpack_modules__","m","deferred","O","result","chunkIds","fn","priority","notFulfilled","i","fulfilled","j","every","splice","r","getter","__esModule","d","definition","o","defineProperty","enumerable","get","g","globalThis","Function","window","obj","prop","prototype","hasOwnProperty","call","installedChunks","chunkId","webpackJsonpCallback","parentChunkLoadingFunction","moreModules","runtime","some","chunkLoadingGlobal","self","bind","__webpack_exports__"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/js/app.9c5f7aa2.js b/dist/js/app.9c5f7aa2.js deleted file mode 100644 index 92a2a66..0000000 --- a/dist/js/app.9c5f7aa2.js +++ /dev/null @@ -1,2 +0,0 @@ -(function(){"use strict";var e={9111:function(e,t,s){var r=s(9242),a=s(3396);const l=(0,a.uE)('
',4);function i(e,t){const s=(0,a.up)("router-link"),r=(0,a.up)("router-view");return(0,a.wg)(),(0,a.iD)(a.HY,null,[(0,a._)("header",null,[(0,a._)("nav",null,[l,(0,a.Wm)(s,{to:"/",class:"navbar-element"},{default:(0,a.w5)((()=>[(0,a.Uk)("Players")])),_:1})])]),(0,a.Wm)(r)],64)}var n=s(89);const o={},d=(0,n.Z)(o,[["render",i]]);var c=d,h=s(2483);const p={id:"filters"},u={id:"playerView"};function y(e,t,s,r,l,i){const n=(0,a.up)("VueMultiselect"),o=(0,a.up)("PlayerList"),d=(0,a.up)("PlayerChart");return(0,a.wg)(),(0,a.iD)(a.HY,null,[(0,a._)("div",p,[(0,a.Wm)(n,{showLabels:!1,placeholder:"Select server",modelValue:e.models.server,"onUpdate:modelValue":t[0]||(t[0]=t=>e.models.server=t),options:e.servers,"allow-empty":!0,"custom-label":e=>e.name,onSelect:t[1]||(t[1]=t=>e.changeFilter({server:t.id})),onRemove:t[2]||(t[2]=t=>e.changeFilter({server:""}))},null,8,["modelValue","options","custom-label"]),(0,a.Wm)(n,{showLabels:!1,selectLabel:"",placeholder:"Select weapon",modelValue:e.models.weapon,"onUpdate:modelValue":t[3]||(t[3]=t=>e.models.weapon=t),options:e.sortedWeaponList,"allow-empty":!0,onSelect:t[4]||(t[4]=t=>e.changeFilter({weapon:t})),onRemove:t[5]||(t[5]=t=>e.changeFilter({weapon:""}))},null,8,["modelValue","options"]),(0,a.Wm)(n,{showLabels:!1,selectLabel:"",placeholder:"Search player",modelValue:e.playerHighlighted,"onUpdate:modelValue":t[6]||(t[6]=t=>e.playerHighlighted=t),options:e.sortedPlayerList,"allow-empty":!0,"custom-label":t=>e.players[t]?.username},null,8,["modelValue","options","custom-label"])]),(0,a._)("div",u,[(0,a.Wm)(o,{filters:e.filters,onHighlightPlayer:t[7]||(t[7]=t=>e.playerHighlighted=t),playerHighlighted:e.playerHighlighted},null,8,["filters","playerHighlighted"]),(0,a.Wm)(d,{filters:e.filters,onHighlightPlayer:t[8]||(t[8]=t=>e.playerHighlighted=t),playerHighlighted:e.playerHighlighted},null,8,["filters","playerHighlighted"])])],64)}s(7658);var g=s(65),f=s(7139);const m=e=>((0,a.dD)("data-v-227422ef"),e=e(),(0,a.Cn)(),e),v={class:"playerHeaders"},b=m((()=>(0,a._)("span",null,null,-1))),w=["onClick"];function _(e,t,s,r,l,i){return(0,a.wg)(),(0,a.iD)("div",{class:"playerTable",onKeydown:t[6]||(t[6]=(...t)=>e.selectNextPlayer&&e.selectNextPlayer(...t)),tabindex:"0"},[(0,a._)("div",v,[b,(0,a._)("span",{onClick:t[0]||(t[0]=t=>e.sortPlayerList("username")),class:(0,f.C_)("username"==e.sortingData.argument?"selected":"")},"Username",2),(0,a._)("span",{onClick:t[1]||(t[1]=t=>e.sortPlayerList("kills")),class:(0,f.C_)("kills"==e.sortingData.argument?"selected":"")},"K",2),(0,a._)("span",{onClick:t[2]||(t[2]=t=>e.sortPlayerList("deaths")),class:(0,f.C_)("deaths"==e.sortingData.argument?"selected":"")},"D",2),(0,a._)("span",{onClick:t[3]||(t[3]=t=>e.sortPlayerList("k/d")),class:(0,f.C_)("k/d"==e.sortingData.argument?"selected":"")},"K/D",2),(0,a._)("span",{onClick:t[4]||(t[4]=t=>e.sortPlayerList("max_kill_distance")),class:(0,f.C_)("max_kill_distance"==e.sortingData.argument?"selected":"")},"max distance",2),(0,a._)("span",{onClick:t[5]||(t[5]=t=>e.sortPlayerList("avg_kill_distance")),class:(0,f.C_)("avg_kill_distance"==e.sortingData.argument?"selected":"")},"average distance",2)]),((0,a.wg)(!0),(0,a.iD)(a.HY,null,(0,a.Ko)(e.playerIdList,((t,s)=>((0,a.wg)(),(0,a.iD)("div",{class:"playerRow",key:t,onClick:s=>e.$emit("highlightPlayer",t),ref_for:!0,ref:"player:"+t},[(0,a._)("div",null,[(0,a._)("span",null,(0,f.zw)(s),1)]),(0,a._)("div",null,[(0,a._)("span",null,(0,f.zw)(e.players[t].username),1)]),(0,a._)("div",null,[(0,a._)("span",null,(0,f.zw)(e.players[t].kills),1)]),(0,a._)("div",null,[(0,a._)("span",null,(0,f.zw)(e.players[t].deaths),1)]),(0,a._)("div",null,[(0,a._)("span",null,(0,f.zw)(Math.round(e.players[t].kills/e.players[t].deaths*100)/100),1)]),(0,a._)("div",null,[(0,a._)("span",null,(0,f.zw)(e.players[t].max_kill_distance),1)]),(0,a._)("div",null,[(0,a._)("span",null,(0,f.zw)(Math.round(100*e.players[t].avg_kill_distance)/100),1)])],8,w)))),128))],32)}var k=(0,a.aZ)({props:{filters:Object,playerHighlighted:String},emits:["highlightPlayer"],data(){return{sortingData:{direction:-1,argument:"kills"},playerIdList:[],store:(0,g.oR)(),selected:void 0}},computed:{players(){return this.store.getters.getPlayerList(this.filters)}},watch:{players:{handler(e){e&&(this.playerIdList=[],this.sortingData.direction*=-1,this.playerIdList=Object.keys(e),this.sortPlayerList(this.sortingData.argument),this.$nextTick((()=>{const e=this.$refs["player:"+this.selected];e&&e.length>0&&e[0].classList.add("selected")})))},immediate:!0},playerHighlighted(e,t){const s=this.$refs["player:"+t];s&&(s[0].classList.remove("selected"),delete this.selected);const r=this.$refs["player:"+e];r&&(r[0].classList.add("selected"),r[0].scrollIntoView({behavior:"smooth",block:"center"}),this.selected=e)}},updated(){const e=this.$refs["player:"+this.$props.playerHighlighted];e&&e[0]&&e[0].scrollIntoView({behavior:"smooth",block:"center"})},methods:{sortPlayerList(e){e===this.sortingData.argument?this.sortingData.direction*=-1:"username"===e&&(this.sortingData.direction=1),this.sortingData.argument=e,this.playerIdList.sort(((t,s)=>{if(!this.players)return 0;let r,a;return"k/d"===e?(r=this.players[t].kills/this.players[t].deaths,a=this.players[s].kills/this.players[s].deaths):(r=this.players[t][e],a=this.players[s][e]),ra?1*this.sortingData.direction:0}))},selectNextPlayer(e){const t={Home:-1/0,End:1/0,PageDown:100,PageUp:-100,ArrowUp:-1,ArrowDown:1,ArrowRight:10,ArrowLeft:-10};if(!this.selected)return;if(!Object.keys(t).includes(e.key))return;e.preventDefault();const s=this.playerIdList.indexOf(this.selected);let r=s+t[e.key];r>=this.playerIdList.length&&(r=this.playerIdList.length-1),r<0&&(r=0),this.$emit("highlightPlayer",this.playerIdList[r])}}});const L=(0,n.Z)(k,[["render",_],["__scopeId","data-v-227422ef"]]);var P=L;const C={class:"playerChart",ref:"container"};function x(e,t,s,r,l,i){const n=(0,a.up)("Scatter");return(0,a.wg)(),(0,a.iD)("div",C,[(0,a.Wm)(n,{data:e.chart,options:e.chartOptions},null,8,["data","options"])],512)}var O=s(3254),D=s(9152),I=s(3013),H=s(5866);O.kL.register(O.f$,O.od,O.jn,O.u,O.De,D.Z,I.Z);var S=(0,a.aZ)({name:"PlayerChart",props:{filters:Object,playerHighlighted:String},emits:["highlightPlayer"],components:{Scatter:H.bp},mounted(){this.refreshColors++},computed:{colors(){this.refreshColors;const e={};if(this.$refs.container){const t=getComputedStyle(this.$refs.container);e.fg=t.getPropertyValue("--foreground"),e.bg=t.getPropertyValue("--bg-color"),e.orange=t.getPropertyValue("--orange"),e.cyan=t.getPropertyValue("--cyan"),e.currentLine=t.getPropertyValue("--current-line")}else e.fg="#ffffff";return e},chart(){const e={datasets:[{label:"Players",labels:[],borderColor:[this.colors.fg],backgroundColor:[this.colors.fg],pointRadius:[1],pointStyle:["dot"],hoverRadius:[4],data:[]}]};if(!this.players)return e;if(e.datasets[0].labels=this.playerIdList,e.datasets[0].data=this.playerIdList.map((e=>this.players?{x:this.players[e].deaths,y:this.players[e].kills}:{x:0,y:0})),e.datasets[0].pointRadius=Array(e.datasets[0].labels.length).fill(1),e.datasets[0].pointStyle=Array(e.datasets[0].labels.length).fill("dot"),e.datasets[0].borderColor=Array(e.datasets[0].labels.length).fill(this.colors.cyan),e.datasets[0].backgroundColor=e.datasets[0].borderColor,e.datasets[0].hoverRadius=Array(e.datasets[0].labels.length).fill(4),this.$props.playerHighlighted){const t=this.playerIdList.indexOf(this.$props.playerHighlighted);e.datasets[0].pointRadius[t]=20,e.datasets[0].pointStyle[t]="crossRot",e.datasets[0].borderColor[t]=this.colors.orange,e.datasets[0].hoverRadius[t]=30}return e},chartOptions(){const e={responsive:!0,maintainAspectRatio:!0,animation:{duration:500},layout:{autoPadding:!1},scales:{y:{title:{text:"Kills",display:!0,color:this.colors.fg},ticks:{color:this.colors.fg}},x:{title:{text:"Deaths",display:!0,color:this.colors.fg},ticks:{color:this.colors.fg}}},plugins:{tooltip:{callbacks:{label:e=>{let t;return t=this.players?this.players[e.dataset.labels[e.dataIndex]].username:e.dataset.labels[e.dataIndex],t+=" ("+e.parsed.y+" kills "+e.parsed.x+" deaths)",t}}},annotation:{},legend:{display:!1},datalabels:{formatter:(e,t)=>this.players[this.playerIdList[t.dataIndex]].username,backgroundColor:Array(this.playerIdList.length).fill(null),borderColor:this.colors.fg,borderWidth:Array(this.playerIdList.length).fill(0),borderRadius:5,display:Array(this.playerIdList.length).fill("auto"),align:"-45",anchor:"end",clamp:!0,color:Array(this.playerIdList.length).fill(this.colors.fg)}},onClick:(e,t)=>{this.$emit("highlightPlayer",t.length>0?this.playerIdList[t[0].index]:void 0)},onHover:(e,t)=>{e.native.target&&(e.native.target.style.cursor=t[0]?"pointer":"default")}};if(!this.players)return e;const t=Math.max(...Object.values(this.players).map((e=>e.deaths))),s=Math.max(...Object.values(this.players).map((e=>e.kills)));let r,a;if(s>t?(r=t,a=t/s*s):(a=s,r=s/t*t),e.plugins.annotation={annotations:{line:{type:"line",yMin:0,xMin:0,yMax:a,xMax:r,borderWidth:2,borderColor:this.colors.orange,borderDash:[1,5]}}},this.$props.playerHighlighted){const t=this.playerIdList.indexOf(this.$props.playerHighlighted);e.plugins.datalabels.display[t]=!0,e.plugins.datalabels.backgroundColor[t]=this.colors.orange,e.plugins.datalabels.borderWidth[t]=1,e.plugins.datalabels.color[t]=this.colors.bg}return e},players(){return this.store.getters.getPlayerList(this.filters)||{}},playerIdList(){return Object.keys(this.players)}},data(){return{store:(0,g.oR)(),refreshColors:0}}});const j=(0,n.Z)(S,[["render",x],["__scopeId","data-v-cf8f72c6"]]);var W=j,V=s(6368),R=(0,a.aZ)({name:"PlayerView",components:{PlayerList:P,PlayerChart:W,VueMultiselect:V.ZP},data(){return{models:{},filters:{minKills:100,minDeaths:100},store:(0,g.oR)(),playerHighlighted:void 0}},computed:{servers(){return this.store.state.servers},weapons(){return this.store.getters.getWeaponList(this.filters)},sortedWeaponList(){if(!this.weapons)return[];const e=Object.keys(this.weapons);return e.sort()},players(){return this.store.getters.getPlayerList(this.filters)},sortedPlayerList(){if(!this.players)return[];const e=Object.keys(this.players);return e.sort(((e,t)=>this.players?this.players[e].usernamethis.players[t].username?1:0:0))}},watch:{test:function(e){console.log(e)}},methods:{async changeFilter({weapon:e,server:t}){console.log(e);const s=JSON.parse(JSON.stringify(this.filters));void 0!==e&&(s.weapon=e),void 0!==t&&(s.server=t),""===e&&delete s.weapon,""===t&&delete s.server;const r=[];this.store.getters.getPlayerList(s)||r.push(this.store.dispatch("fetchPlayers",s)),this.store.getters.getWeaponList(s)||r.push(this.store.dispatch("fetchWeapons",s)),await Promise.all(r),this.filters=s}}});const $=(0,n.Z)(R,[["render",y],["__scopeId","data-v-6d0e9369"]]);var A=$;const M=[{path:"/",name:"home",component:A}],N=(0,h.p7)({history:(0,h.PO)("/Tone_WebClient/"),routes:M});var Z=N;Symbol();var z=(0,g.MT)({state:{servers:[],players:{},weapons:{}},getters:{getPlayerList:e=>({server:t,weapon:s,minKills:r,minDeaths:a})=>{let l=[];return e.players[""]&&(l=Object.entries(e.players[""]).filter((([,e])=>e.kills>=r||e.deaths>=a)).map((e=>e[0]))),l.length>0&&e.players[(t||"")+(s||"")]?Object.fromEntries(Object.entries(e.players[(t||"")+(s||"")]).filter((([e])=>l.includes(e)))):e.players[(t||"")+(s||"")]},getWeaponList:e=>({server:t,player:s})=>e.weapons[(t||"")+(s||"")]},mutations:{setPlayers(e,t){e.players[(t.filters.server||"")+(t.filters.weapon||"")]=t.data},setWeapons(e,t){e.weapons[(t.filters.server||"")+(t.filters.player||"")]=t.data},setServers(e,t){e.servers=t}},actions:{async fetchPlayers(e,{weapon:t,server:s}){const r={};t?.toString()&&(r.weapon=t),s?.toString()&&(r.server=s);const a=await fetch("https://tone.sleepycat.date/v1/client/players?"+new URLSearchParams(r)),l=await a.json();Object.keys(l).forEach((e=>{l[e].kills=Number(l[e].kills),l[e].deaths=Number(l[e].deaths),l[e].max_kill_distance=Number(l[e].max_kill_distance),l[e].avg_kill_distance=Number(l[e].avg_kill_distance)})),e.commit("setPlayers",{data:l,filters:{weapon:t,server:s}})},async fetchWeapons(e,{player:t,server:s}){const r={};t?.toString()&&(r.player=t),s?.toString()&&(r.server=s);const a=await fetch("https://tone.sleepycat.date/v1/client/weapons?"+new URLSearchParams(r)),l=await a.json();e.commit("setWeapons",{data:l,filters:{player:t,server:s}})},async fetchServers(e){const t=await fetch("https://tone.sleepycat.date/v1/client/servers"),s=await t.json();e.commit("setServers",s)}},modules:{}});(0,r.ri)(c).use(z).use(Z).mount("#app"),z.dispatch("fetchServers",{}),z.dispatch("fetchPlayers",{}),z.dispatch("fetchWeapons",{})}},t={};function s(r){var a=t[r];if(void 0!==a)return a.exports;var l=t[r]={exports:{}};return e[r](l,l.exports,s),l.exports}s.m=e,function(){var e=[];s.O=function(t,r,a,l){if(!r){var i=1/0;for(c=0;c=l)&&Object.keys(s.O).every((function(e){return s.O[e](r[o])}))?r.splice(o--,1):(n=!1,l0&&e[c-1][2]>l;c--)e[c]=e[c-1];e[c]=[r,a,l]}}(),function(){s.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return s.d(t,{a:t}),t}}(),function(){s.d=function(e,t){for(var r in t)s.o(t,r)&&!s.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}}(),function(){s.g=function(){if("object"===typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"===typeof window)return window}}()}(),function(){s.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}}(),function(){var e={143:0};s.O.j=function(t){return 0===e[t]};var t=function(t,r){var a,l,i=r[0],n=r[1],o=r[2],d=0;if(i.some((function(t){return 0!==e[t]}))){for(a in n)s.o(n,a)&&(s.m[a]=n[a]);if(o)var c=o(s)}for(t&&t(r);d\n
\n \n
\n \n\n\n\n","import { render } from \"./App.vue?vue&type=template&id=3e556bf7\"\nconst script = {}\n\nimport \"./App.vue?vue&type=style&index=0&id=3e556bf7&lang=css\"\n\nimport exportComponent from \"C:\\\\Users\\\\legon\\\\Documents\\\\Code\\\\toneapi_webclient\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import { resolveComponent as _resolveComponent, createVNode as _createVNode, createElementVNode as _createElementVNode, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, pushScopeId as _pushScopeId, popScopeId as _popScopeId } from \"vue\"\n\nconst _withScopeId = n => (_pushScopeId(\"data-v-6d0e9369\"),n=n(),_popScopeId(),n)\nconst _hoisted_1 = { id: \"filters\" }\nconst _hoisted_2 = { id: \"playerView\" }\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n const _component_VueMultiselect = _resolveComponent(\"VueMultiselect\")!\n const _component_PlayerList = _resolveComponent(\"PlayerList\")!\n const _component_PlayerChart = _resolveComponent(\"PlayerChart\")!\n\n return (_openBlock(), _createElementBlock(_Fragment, null, [\n _createElementVNode(\"div\", _hoisted_1, [\n _createVNode(_component_VueMultiselect, {\n showLabels: false,\n placeholder: \"Select server\",\n modelValue: _ctx.models.server,\n \"onUpdate:modelValue\": _cache[0] || (_cache[0] = ($event: any) => ((_ctx.models.server) = $event)),\n options: _ctx.servers,\n \"allow-empty\": true,\n \"custom-label\": ((e) => e.name),\n onSelect: _cache[1] || (_cache[1] = ($event: any) => (_ctx.changeFilter({ server: $event.id }))),\n onRemove: _cache[2] || (_cache[2] = ($event: any) => (_ctx.changeFilter({ server: '' })))\n }, null, 8, [\"modelValue\", \"options\", \"custom-label\"]),\n _createVNode(_component_VueMultiselect, {\n showLabels: false,\n selectLabel: \"\",\n placeholder: \"Select weapon\",\n modelValue: _ctx.models.weapon,\n \"onUpdate:modelValue\": _cache[3] || (_cache[3] = ($event: any) => ((_ctx.models.weapon) = $event)),\n options: _ctx.sortedWeaponList,\n \"allow-empty\": true,\n onSelect: _cache[4] || (_cache[4] = ($event: any) => (_ctx.changeFilter({ weapon: $event }))),\n onRemove: _cache[5] || (_cache[5] = ($event: any) => (_ctx.changeFilter({ weapon: '' })))\n }, null, 8, [\"modelValue\", \"options\"]),\n _createVNode(_component_VueMultiselect, {\n showLabels: false,\n selectLabel: \"\",\n placeholder: \"Search player\",\n modelValue: _ctx.playerHighlighted,\n \"onUpdate:modelValue\": _cache[6] || (_cache[6] = ($event: any) => ((_ctx.playerHighlighted) = $event)),\n options: _ctx.sortedPlayerList,\n \"allow-empty\": true,\n \"custom-label\": ((e) => _ctx.players[e]?.username)\n }, null, 8, [\"modelValue\", \"options\", \"custom-label\"])\n ]),\n _createElementVNode(\"div\", _hoisted_2, [\n _createVNode(_component_PlayerList, {\n filters: _ctx.filters,\n onHighlightPlayer: _cache[7] || (_cache[7] = ($event: any) => (_ctx.playerHighlighted = $event)),\n playerHighlighted: _ctx.playerHighlighted\n }, null, 8, [\"filters\", \"playerHighlighted\"]),\n _createVNode(_component_PlayerChart, {\n filters: _ctx.filters,\n onHighlightPlayer: _cache[8] || (_cache[8] = ($event: any) => (_ctx.playerHighlighted = $event)),\n playerHighlighted: _ctx.playerHighlighted\n }, null, 8, [\"filters\", \"playerHighlighted\"])\n ])\n ], 64))\n}","import { createElementVNode as _createElementVNode, normalizeClass as _normalizeClass, renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, toDisplayString as _toDisplayString, pushScopeId as _pushScopeId, popScopeId as _popScopeId } from \"vue\"\n\nconst _withScopeId = n => (_pushScopeId(\"data-v-227422ef\"),n=n(),_popScopeId(),n)\nconst _hoisted_1 = { class: \"playerHeaders\" }\nconst _hoisted_2 = /*#__PURE__*/ _withScopeId(() => /*#__PURE__*/_createElementVNode(\"span\", null, null, -1))\nconst _hoisted_3 = [\"onClick\"]\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n return (_openBlock(), _createElementBlock(\"div\", {\n class: \"playerTable\",\n onKeydown: _cache[6] || (_cache[6] = \n//@ts-ignore\n(...args) => (_ctx.selectNextPlayer && _ctx.selectNextPlayer(...args))),\n tabindex: \"0\"\n }, [\n _createElementVNode(\"div\", _hoisted_1, [\n _hoisted_2,\n _createElementVNode(\"span\", {\n onClick: _cache[0] || (_cache[0] = ($event: any) => (_ctx.sortPlayerList('username'))),\n class: _normalizeClass(_ctx.sortingData.argument == 'username' ? 'selected' : '')\n }, \"Username\", 2),\n _createElementVNode(\"span\", {\n onClick: _cache[1] || (_cache[1] = ($event: any) => (_ctx.sortPlayerList('kills'))),\n class: _normalizeClass(_ctx.sortingData.argument == 'kills' ? 'selected' : '')\n }, \"K\", 2),\n _createElementVNode(\"span\", {\n onClick: _cache[2] || (_cache[2] = ($event: any) => (_ctx.sortPlayerList('deaths'))),\n class: _normalizeClass(_ctx.sortingData.argument == 'deaths' ? 'selected' : '')\n }, \"D\", 2),\n _createElementVNode(\"span\", {\n onClick: _cache[3] || (_cache[3] = ($event: any) => (_ctx.sortPlayerList('k/d'))),\n class: _normalizeClass(_ctx.sortingData.argument == 'k/d' ? 'selected' : '')\n }, \"K/D\", 2),\n _createElementVNode(\"span\", {\n onClick: _cache[4] || (_cache[4] = ($event: any) => (_ctx.sortPlayerList('max_kill_distance'))),\n class: _normalizeClass(_ctx.sortingData.argument == 'max_kill_distance' ? 'selected' : '')\n }, \"max distance\", 2),\n _createElementVNode(\"span\", {\n onClick: _cache[5] || (_cache[5] = ($event: any) => (_ctx.sortPlayerList('avg_kill_distance'))),\n class: _normalizeClass(_ctx.sortingData.argument == 'avg_kill_distance' ? 'selected' : '')\n }, \"average distance\", 2)\n ]),\n (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.playerIdList, (playerId, index) => {\n return (_openBlock(), _createElementBlock(\"div\", {\n class: \"playerRow\",\n key: playerId,\n onClick: ($event: any) => (_ctx.$emit('highlightPlayer', playerId)),\n ref_for: true,\n ref: `player:` + playerId\n }, [\n _createElementVNode(\"div\", null, [\n _createElementVNode(\"span\", null, _toDisplayString(index), 1)\n ]),\n _createElementVNode(\"div\", null, [\n _createElementVNode(\"span\", null, _toDisplayString(_ctx.players[playerId].username), 1)\n ]),\n _createElementVNode(\"div\", null, [\n _createElementVNode(\"span\", null, _toDisplayString(_ctx.players[playerId].kills), 1)\n ]),\n _createElementVNode(\"div\", null, [\n _createElementVNode(\"span\", null, _toDisplayString(_ctx.players[playerId].deaths), 1)\n ]),\n _createElementVNode(\"div\", null, [\n _createElementVNode(\"span\", null, _toDisplayString(Math.round(_ctx.players[playerId].kills / _ctx.players[playerId].deaths * 100) / 100), 1)\n ]),\n _createElementVNode(\"div\", null, [\n _createElementVNode(\"span\", null, _toDisplayString(_ctx.players[playerId].max_kill_distance), 1)\n ]),\n _createElementVNode(\"div\", null, [\n _createElementVNode(\"span\", null, _toDisplayString(Math.round(_ctx.players[playerId].avg_kill_distance * 100) / 100), 1)\n ])\n ], 8, _hoisted_3))\n }), 128))\n ], 32))\n}","\nimport { defineComponent } from 'vue'\nimport { Player } from '@/store/index'\nimport { useStore } from 'vuex'\nimport { Vue } from 'vue-class-component'\n\nexport default defineComponent({\n props: {\n filters: Object,\n playerHighlighted: String\n },\n emits: ['highlightPlayer'],\n data () {\n return {\n sortingData: { direction: -1, argument: 'kills' as keyof Player | 'k/d' },\n playerIdList: [] as string[],\n store: useStore(),\n selected: undefined as string | undefined\n }\n },\n computed: {\n players (): { [key: string]: Player } { return this.store.getters.getPlayerList(this.filters) }\n },\n watch: {\n players: {\n handler (newval: { [key: string]: Player }): void {\n if (!newval) return\n this.playerIdList = []\n this.sortingData.direction *= -1\n this.playerIdList = Object.keys(newval)\n this.sortPlayerList(this.sortingData.argument)\n this.$nextTick(() => {\n const element = (this.$refs['player:' + this.selected] as HTMLElement[])\n if (element && element.length > 0) element[0].classList.add('selected')\n })\n },\n immediate: true\n },\n playerHighlighted (newval, oldval) {\n const oldElement = this.$refs['player:' + oldval] as HTMLElement[]\n if (oldElement) {\n oldElement[0].classList.remove('selected')\n delete this.selected\n }\n const newElement = this.$refs['player:' + newval] as HTMLElement[]\n if (!newElement) return\n newElement[0].classList.add('selected')\n newElement[0].scrollIntoView({ behavior: 'smooth', block: 'center' })\n this.selected = newval\n }\n },\n updated () {\n const element = this.$refs['player:' + this.$props.playerHighlighted] as HTMLElement[]\n if (!element || !element[0]) return\n element[0].scrollIntoView({ behavior: 'smooth', block: 'center' })\n },\n methods: {\n sortPlayerList (arg: ((keyof Player) | 'k/d')) {\n if (arg === this.sortingData.argument) {\n this.sortingData.direction *= -1\n } else {\n if (arg === 'username') {\n this.sortingData.direction = 1\n }\n }\n this.sortingData.argument = arg\n\n this.playerIdList.sort((a: string, b: string) => {\n if (!this.players) {\n return 0\n }\n let varA, varB\n if (arg === 'k/d') {\n varA = this.players[a].kills / this.players[a].deaths\n varB = this.players[b].kills / this.players[b].deaths\n } else {\n varA = this.players[a][arg]\n varB = this.players[b][arg]\n }\n\n if (varA < varB) {\n return -1 * this.sortingData.direction\n }\n if (varA > varB) {\n return 1 * this.sortingData.direction\n }\n return 0\n })\n },\n selectNextPlayer (e: KeyboardEvent) {\n const values = {\n Home: -Infinity,\n End: Infinity,\n PageDown: 100,\n PageUp: -100,\n ArrowUp: -1,\n ArrowDown: 1,\n ArrowRight: 10,\n ArrowLeft: -10\n } as { [key: string]: number }\n if (!this.selected) return\n if (!Object.keys(values).includes(e.key)) return\n e.preventDefault()\n const index = this.playerIdList.indexOf(this.selected)\n let nextIndex = (index + values[e.key])\n if (nextIndex >= this.playerIdList.length) nextIndex = this.playerIdList.length - 1\n if (nextIndex < 0) nextIndex = 0\n this.$emit('highlightPlayer', this.playerIdList[nextIndex])\n }\n }\n\n})\n","import { render } from \"./PlayerList.vue?vue&type=template&id=227422ef&scoped=true&ts=true\"\nimport script from \"./PlayerList.vue?vue&type=script&lang=ts\"\nexport * from \"./PlayerList.vue?vue&type=script&lang=ts\"\n\nimport \"./PlayerList.vue?vue&type=style&index=0&id=227422ef&scoped=true&lang=css\"\n\nimport exportComponent from \"C:\\\\Users\\\\legon\\\\Documents\\\\Code\\\\toneapi_webclient\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-227422ef\"]])\n\nexport default __exports__","import { resolveComponent as _resolveComponent, createVNode as _createVNode, openBlock as _openBlock, createElementBlock as _createElementBlock, pushScopeId as _pushScopeId, popScopeId as _popScopeId } from \"vue\"\n\nconst _withScopeId = n => (_pushScopeId(\"data-v-cf8f72c6\"),n=n(),_popScopeId(),n)\nconst _hoisted_1 = {\n class: \"playerChart\",\n ref: \"container\"\n}\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n const _component_Scatter = _resolveComponent(\"Scatter\")!\n\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1, [\n _createVNode(_component_Scatter, {\n data: _ctx.chart,\n options: _ctx.chartOptions\n }, null, 8, [\"data\", \"options\"])\n ], 512))\n}","\nimport {\n Chart as ChartJS,\n LinearScale,\n PointElement,\n LineElement,\n Tooltip,\n Legend\n} from 'chart.js'\nimport annotationPlugin from 'chartjs-plugin-annotation'\nimport dataLabel from 'chartjs-plugin-datalabels'\nimport { Store, useStore } from 'vuex'\nimport { Player, Weapon } from '@/store/index'\n\nimport { Scatter } from 'vue-chartjs'\nimport { defineComponent } from 'vue'\n\nChartJS.register(LinearScale, PointElement, LineElement, Tooltip, Legend, annotationPlugin, dataLabel)\n\nexport default defineComponent({\n name: 'PlayerChart',\n props: {\n filters: Object,\n playerHighlighted: String\n },\n emits: ['highlightPlayer'],\n components: {\n Scatter\n },\n mounted () {\n this.refreshColors++\n },\n computed: {\n colors () {\n // eslint-disable-next-line no-unused-expressions\n this.refreshColors\n const colors = {} as {[key:string]:string}\n if (this.$refs.container) {\n const style = getComputedStyle(this.$refs.container as Element)\n colors.fg = style.getPropertyValue('--foreground')\n colors.bg = style.getPropertyValue('--bg-color')\n colors.orange = style.getPropertyValue('--orange')\n colors.cyan = style.getPropertyValue('--cyan')\n colors.currentLine = style.getPropertyValue('--current-line')\n } else {\n colors.fg = '#ffffff'\n }\n return colors\n },\n chart () {\n const chartData = {\n datasets: [\n {\n label: 'Players',\n labels: [] as string[],\n borderColor: [this.colors.fg],\n backgroundColor: [this.colors.fg],\n pointRadius: [1],\n pointStyle: ['dot'],\n hoverRadius: [4],\n data: [] as {x:number, y:number}[]\n }\n ]\n }\n if (!this.players) {\n return chartData\n }\n chartData.datasets[0].labels = this.playerIdList\n chartData.datasets[0].data = this.playerIdList.map(e => {\n if (!this.players) {\n return { x: 0, y: 0 }\n }\n return { x: this.players[e].deaths, y: this.players[e].kills }\n })\n chartData.datasets[0].pointRadius = Array(chartData.datasets[0].labels.length).fill(1)\n chartData.datasets[0].pointStyle = Array(chartData.datasets[0].labels.length).fill('dot')\n chartData.datasets[0].borderColor = Array(chartData.datasets[0].labels.length).fill(this.colors.cyan)\n chartData.datasets[0].backgroundColor = chartData.datasets[0].borderColor\n chartData.datasets[0].hoverRadius = Array(chartData.datasets[0].labels.length).fill(4)\n if (this.$props.playerHighlighted) {\n const index = this.playerIdList.indexOf(this.$props.playerHighlighted)\n chartData.datasets[0].pointRadius[index] = 20\n chartData.datasets[0].pointStyle[index] = 'crossRot'\n chartData.datasets[0].borderColor[index] = this.colors.orange\n // No need to do that since arrays are already the same (reference)\n // chartData.datasets[0].backgroundColor[index] = chartData.datasets[0].borderColor[index]\n chartData.datasets[0].hoverRadius[index] = 30\n }\n return chartData\n },\n chartOptions () {\n const options = {\n responsive: true,\n maintainAspectRatio: true,\n animation: { duration: 500 },\n layout: { autoPadding: false },\n scales: {\n y: {\n title: {\n text: 'Kills',\n display: true,\n color: this.colors.fg\n },\n ticks: {\n color: this.colors.fg\n }\n },\n x: {\n title: {\n text: 'Deaths',\n display: true,\n color: this.colors.fg\n },\n ticks: {\n color: this.colors.fg\n }\n }\n },\n plugins: {\n tooltip: {\n callbacks: {\n label: (ctx:any) => {\n let label:string\n if (!this.players) {\n label = ctx.dataset.labels[ctx.dataIndex]\n } else {\n label = this.players[ctx.dataset.labels[ctx.dataIndex]].username\n }\n label += ' (' + ctx.parsed.y + ' kills ' + ctx.parsed.x + ' deaths)'\n return label\n }\n }\n },\n annotation: {},\n legend: { display: false },\n datalabels: {\n formatter: (value:any, context:any) => {\n return this.players[this.playerIdList[context.dataIndex]].username\n },\n backgroundColor: Array(this.playerIdList.length).fill(null),\n borderColor: this.colors.fg,\n borderWidth: Array(this.playerIdList.length).fill(0),\n borderRadius: 5,\n display: Array(this.playerIdList.length).fill('auto'),\n align: '-45',\n anchor: 'end',\n clamp: true,\n color: Array(this.playerIdList.length).fill(this.colors.fg)\n }\n },\n onClick: (e:Event, element:any) => {\n this.$emit('highlightPlayer', element.length > 0 ? this.playerIdList[element[0].index] : undefined)\n },\n onHover: (e:any, element:any) => {\n if (!e.native.target) return\n (e.native.target as HTMLElement).style.cursor = element[0] ? 'pointer' : 'default'\n }\n }\n if (!this.players) {\n return options\n }\n const maxX = Math.max(...Object.values(this.players).map(e => e.deaths))\n const maxY = Math.max(...Object.values(this.players).map(e => e.kills))\n let endX, endY\n if (maxY > maxX) {\n endX = maxX\n endY = (maxX / maxY) * maxY\n } else {\n endY = maxY\n endX = (maxY / maxX) * maxX\n }\n options.plugins.annotation = {\n annotations: {\n line: {\n type: 'line',\n yMin: 0,\n xMin: 0,\n yMax: endY,\n xMax: endX,\n borderWidth: 2,\n borderColor: this.colors.orange,\n borderDash: [1, 5]\n }\n }\n }\n\n if (this.$props.playerHighlighted) {\n const index = this.playerIdList.indexOf(this.$props.playerHighlighted)\n options.plugins.datalabels.display[index] = true\n options.plugins.datalabels.backgroundColor[index] = this.colors.orange\n options.plugins.datalabels.borderWidth[index] = 1\n options.plugins.datalabels.color[index] = this.colors.bg\n }\n return options\n },\n players ():{[key:string]:Player} { return this.store.getters.getPlayerList(this.filters) || {} },\n playerIdList ():string[] { return Object.keys(this.players) }\n\n },\n data () {\n return {\n store: useStore(),\n refreshColors: 0\n }\n }\n})\n","import { render } from \"./PlayerChart.vue?vue&type=template&id=cf8f72c6&scoped=true&ts=true\"\nimport script from \"./PlayerChart.vue?vue&type=script&lang=ts\"\nexport * from \"./PlayerChart.vue?vue&type=script&lang=ts\"\n\nimport \"./PlayerChart.vue?vue&type=style&index=0&id=cf8f72c6&scoped=true&lang=css\"\n\nimport exportComponent from \"C:\\\\Users\\\\legon\\\\Documents\\\\Code\\\\toneapi_webclient\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-cf8f72c6\"]])\n\nexport default __exports__","\nimport { Store, useStore } from 'vuex'\nimport { Player, Weapon, Server } from '@/store/index'\nimport PlayerList from '@/components/PlayerList.vue'\nimport PlayerChart from '@/components/PlayerChart.vue'\nimport { defineComponent } from 'vue'\nimport VueMultiselect from 'vue-multiselect'\nimport 'vue-multiselect/dist/vue-multiselect.css'\n\nexport default defineComponent({\n name: 'PlayerView',\n components: {\n PlayerList, PlayerChart, VueMultiselect\n },\n\n data () {\n return {\n models: {},\n filters: { minKills: 100, minDeaths: 100 },\n store: useStore(),\n playerHighlighted: undefined\n } as { filters: { weapon?: string, server?: string }, store: Store, playerHighlighted?: string }\n },\n computed: {\n servers (): Server[] { return this.store.state.servers },\n weapons (): { [key: string]: Weapon } { return this.store.getters.getWeaponList(this.filters) },\n sortedWeaponList (): string[] {\n if (!this.weapons) return []\n const weapons = Object.keys(this.weapons)\n return weapons.sort()\n },\n players (): { [key: string]: Player } { return this.store.getters.getPlayerList(this.filters) },\n sortedPlayerList (): string[] {\n if (!this.players) return []\n const players = Object.keys(this.players)\n return players.sort((a: string, b: string) => {\n if (!this.players) {\n return 0\n }\n\n if (this.players[a].username < this.players[b].username) {\n return -1\n }\n if (this.players[a].username > this.players[b].username) {\n return 1\n }\n return 0\n })\n }\n },\n watch: {\n test: function (newval) {\n console.log(newval)\n }\n },\n methods: {\n async changeFilter ({ weapon, server }: { weapon?: string, server?: string }) {\n console.log(weapon)\n const filters = JSON.parse(JSON.stringify(this.filters))\n if (weapon !== undefined) filters.weapon = weapon\n if (server !== undefined) filters.server = server\n if (weapon === '') delete filters.weapon\n if (server === '') delete filters.server\n const promises = []\n if (!this.store.getters.getPlayerList(filters)) promises.push(this.store.dispatch('fetchPlayers', filters))\n if (!this.store.getters.getWeaponList(filters)) promises.push(this.store.dispatch('fetchWeapons', filters))\n await Promise.all(promises)\n // Delay the update of filters propery after we fetch the data to the API as changing it will cause subcomponents to reload before data is fetched\n this.filters = filters\n }\n }\n})\n","import { render } from \"./PlayerView.vue?vue&type=template&id=6d0e9369&scoped=true&ts=true\"\nimport script from \"./PlayerView.vue?vue&type=script&lang=ts\"\nexport * from \"./PlayerView.vue?vue&type=script&lang=ts\"\n\nimport \"./PlayerView.vue?vue&type=style&index=0&id=6d0e9369&scoped=true&lang=css\"\n\nimport exportComponent from \"C:\\\\Users\\\\legon\\\\Documents\\\\Code\\\\toneapi_webclient\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-6d0e9369\"]])\n\nexport default __exports__","import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'\nimport HomeView from '../views/HomeView.vue'\nimport PlayerView from '../views/PlayerView.vue'\n\nconst routes: Array = [\n {\n path: '/',\n name: 'home',\n component: PlayerView\n }\n // {\n // path: '/players',\n // name: 'players',\n // component: PlayerView\n // },\n // {\n // path: '/about',\n // name: 'about',\n // // route level code-splitting\n // // this generates a separate chunk (about.[hash].js) for this route\n // // which is lazy-loaded when the route is visited.\n // component: () => import(/* webpackChunkName: \"about\" */ '../views/AboutView.vue')\n // }\n]\n\nconst router = createRouter({\n history: createWebHistory(process.env.BASE_URL),\n routes\n})\n\nexport default router\n","// store.ts\nimport { InjectionKey } from 'vue'\nimport { createStore, Store } from 'vuex'\n\nexport interface Player {\n deaths: number;\n username: string;\n // eslint-disable-next-line camelcase\n max_kill_distance: number;\n // eslint-disable-next-line camelcase\n avg_kill_distance: number;\n kills: number;\n}\n\nexport interface Weapon {\n // eslint-disable-next-line camelcase\n max_kill_distance: number;\n // eslint-disable-next-line camelcase\n avg_kill_distance: number;\n kills: number;\n}\n\nexport interface Server{\n name:string;\n id:number;\n description:string\n}\n// define your typings for the store state\nexport interface State {\n servers: Server[]\n players: { [key: string]: { [key: string]: Player } };\n weapons: { [key: string]:{ [key: string]: Weapon }};\n}\n\n// define injection key\n// eslint-disable-next-line symbol-description\nexport const key: InjectionKey> = Symbol()\n\nexport default createStore({\n state: {\n servers: [],\n players: {},\n weapons: {}\n },\n getters: {\n getPlayerList: (state) => ({ server, weapon, minKills, minDeaths }: { server?: number, weapon?: string, minKills:number, minDeaths:number }) => {\n let playerFilter: string[] = []\n if (state.players['']) {\n playerFilter = Object.entries(state.players['']).filter(([, value]:any) => { return (value.kills >= minKills) || (value.deaths >= minDeaths) }).map(e => e[0])\n }\n if (playerFilter.length > 0 && state.players[(server || '') + (weapon || '')]) {\n return Object.fromEntries(Object.entries(state.players[(server || '') + (weapon || '')]).filter(([key]) => playerFilter.includes(key)))\n }\n\n return state.players[(server || '') + (weapon || '')]\n },\n getWeaponList: (state) => ({ server, player }: { server?: number, player?: string }) => {\n return state.weapons[(server || '') + (player || '')]\n }\n },\n mutations: {\n setPlayers (state, data: { data: { [key: string]: Player }, filters: { weapon: string, server: number } }) {\n state.players[(data.filters.server || '') + (data.filters.weapon || '')] = data.data\n },\n setWeapons (state, data:{data: {[key:string]:Weapon}, filters:{server:string, player:string}}) {\n state.weapons[(data.filters.server || '') + (data.filters.player || '')] = data.data\n },\n setServers (state, data) {\n state.servers = data\n }\n },\n actions: {\n async fetchPlayers (context, { weapon, server }) {\n const searchParams: Record = {}\n if (weapon?.toString()) { searchParams.weapon = weapon }\n if (server?.toString()) { searchParams.server = server }\n const response = await fetch(\n 'https://tone.sleepycat.date/v1/client/players?' + new URLSearchParams(searchParams)\n )\n const data = await response.json()\n Object.keys(data).forEach(e => {\n data[e].kills = Number(data[e].kills)\n data[e].deaths = Number(data[e].deaths)\n data[e].max_kill_distance = Number(data[e].max_kill_distance)\n data[e].avg_kill_distance = Number(data[e].avg_kill_distance)\n })\n\n context.commit('setPlayers', { data, filters: { weapon, server } })\n },\n async fetchWeapons (context, { player, server }) {\n const searchParams: Record = {}\n if (player?.toString()) { searchParams.player = player }\n if (server?.toString()) { searchParams.server = server }\n const response = await fetch(\n 'https://tone.sleepycat.date/v1/client/weapons?' + new URLSearchParams(searchParams)\n )\n const data = await response.json()\n context.commit('setWeapons', { data, filters: { player, server } })\n },\n async fetchServers (context) {\n const response = await fetch(\n 'https://tone.sleepycat.date/v1/client/servers'\n )\n const data = await response.json()\n context.commit('setServers', data)\n }\n },\n modules: {}\n})\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).use(store).use(router).mount('#app')\r\n\r\nstore.dispatch('fetchServers', {})\r\nstore.dispatch('fetchPlayers', {})\r\nstore.dispatch('fetchWeapons', {})\r\n","// 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__.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); }","// 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// no chunk on demand loading\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[\"webpackChunktoneapi_webclient\"] = self[\"webpackChunktoneapi_webclient\"] || [];\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__(9111); })\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["_createElementVNode","_hoisted_1","_createVNode","_component_router_link","to","class","_component_router_view","script","__exports__","render","id","_hoisted_2","_ctx","_cache","$props","$setup","$data","$options","_component_VueMultiselect","_resolveComponent","_component_PlayerList","_component_PlayerChart","_openBlock","_createElementBlock","_Fragment","showLabels","placeholder","modelValue","models","server","$event","options","servers","e","name","onSelect","changeFilter","onRemove","selectLabel","weapon","sortedWeaponList","playerHighlighted","sortedPlayerList","players","username","filters","onHighlightPlayer","_withScopeId","n","_pushScopeId","_popScopeId","_hoisted_3","onKeydown","args","selectNextPlayer","tabindex","onClick","sortPlayerList","_normalizeClass","sortingData","argument","_renderList","playerIdList","playerId","index","key","$emit","ref_for","ref","_toDisplayString","kills","deaths","Math","round","max_kill_distance","avg_kill_distance","defineComponent","props","Object","String","emits","data","direction","store","useStore","selected","undefined","computed","this","getters","getPlayerList","watch","handler","newval","keys","$nextTick","element","$refs","length","classList","add","immediate","oldval","oldElement","remove","newElement","scrollIntoView","behavior","block","updated","methods","arg","sort","a","b","varA","varB","values","Home","Infinity","End","PageDown","PageUp","ArrowUp","ArrowDown","ArrowRight","ArrowLeft","includes","preventDefault","indexOf","nextIndex","_component_Scatter","chart","chartOptions","ChartJS","LinearScale","PointElement","LineElement","Tooltip","Legend","annotationPlugin","dataLabel","components","Scatter","mounted","refreshColors","colors","container","style","getComputedStyle","fg","getPropertyValue","bg","orange","cyan","currentLine","chartData","datasets","label","labels","borderColor","backgroundColor","pointRadius","pointStyle","hoverRadius","map","x","y","Array","fill","responsive","maintainAspectRatio","animation","duration","layout","autoPadding","scales","title","text","display","color","ticks","plugins","tooltip","callbacks","ctx","dataset","dataIndex","parsed","annotation","legend","datalabels","formatter","value","context","borderWidth","borderRadius","align","anchor","clamp","onHover","native","target","cursor","maxX","max","maxY","endX","endY","annotations","line","type","yMin","xMin","yMax","xMax","borderDash","PlayerList","PlayerChart","VueMultiselect","minKills","minDeaths","state","weapons","getWeaponList","test","console","log","async","JSON","parse","stringify","promises","push","dispatch","Promise","all","routes","path","component","PlayerView","router","createRouter","history","createWebHistory","process","Symbol","createStore","playerFilter","entries","filter","fromEntries","player","mutations","setPlayers","setWeapons","setServers","actions","searchParams","toString","response","fetch","URLSearchParams","json","forEach","Number","commit","modules","createApp","App","use","mount","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","exports","module","__webpack_modules__","m","deferred","O","result","chunkIds","fn","priority","notFulfilled","i","fulfilled","j","every","splice","r","getter","__esModule","d","definition","o","defineProperty","enumerable","get","g","globalThis","Function","window","obj","prop","prototype","hasOwnProperty","call","installedChunks","chunkId","webpackJsonpCallback","parentChunkLoadingFunction","moreModules","runtime","some","chunkLoadingGlobal","self","bind","__webpack_exports__"],"sourceRoot":""} \ No newline at end of file