\n \n \n \n \n Peer Meeting\n\n \n {{ $t(\"welcome.message\") }}\n \n\n
\n \n \n \n {{ $t(\"welcome.new\") }}\n \n \n \n \n {{ $t(\"welcome.startMeeting\") }}\n \n \n \n\n \n \n {{ $t(\"welcome.recent\") }}\n \n \n \n {{ new Date(item.date).toLocaleString() }} \n {{ item.id }}
\n \n \n \n \n \n \n \n
\n\n\n\n\n","import mod from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Welcome.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Welcome.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./Welcome.vue?vue&type=template&id=12a716fe&\"\nimport script from \"./Welcome.vue?vue&type=script&lang=js&\"\nexport * from \"./Welcome.vue?vue&type=script&lang=js&\"\nimport style0 from \"./Welcome.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","// Copyright 2021 Klabukov Erik.\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport Vue from 'vue'\nimport Router from 'vue-router'\nimport Welcome from './views/Welcome.vue'\n\nVue.use(Router)\n\nexport default new Router({\n mode: 'history',\n base: process.env.BASE_URL,\n routes: [\n {\n path: '/',\n name: 'home',\n component: Welcome\n },\n {\n path: '/:id',\n name: 'room',\n component: () => import(/* webpackChunkName: \"room\" */ './views/Room.vue')\n },\n {\n path: '/:id/ended',\n name: 'callEnded',\n component: () => import(/* webpackChunkName: \"callended\" */ './views/CallEnded.vue')\n }\n ]\n})\n","// Copyright 2021 Klabukov Erik.\n// SPDX-License-Identifier: GPL-3.0-only\n\n/* eslint-disable no-console */\n\nimport { register } from 'register-service-worker'\n\nif (process.env.NODE_ENV === 'production') {\n register(`${process.env.BASE_URL}service-worker.js`, {\n ready () {\n console.log(\n 'App is being served from cache by a service worker.\\n' +\n 'For more details, visit https://goo.gl/AFskqB'\n )\n },\n registered () {\n console.log('Service worker has been registered.')\n },\n cached () {\n console.log('Content has been cached for offline use.')\n },\n updatefound () {\n console.log('New content is downloading.')\n },\n updated () {\n console.log('New content is available; please refresh.')\n caches.keys().then(function (names) {\n for (let name of names) caches.delete(name)\n })\n },\n offline () {\n console.log('No internet connection found. App is running in offline mode.')\n },\n error (error) {\n console.error('Error during service worker registration:', error)\n }\n })\n}\n","// Copyright 2021 Klabukov Erik.\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport Vue from 'vue'\nimport Vuex from 'vuex'\n\nVue.use(Vuex)\n\nexport default new Vuex.Store({\n state: {\n application: {\n profile: null,\n deviceSettings: {\n audioInput: null,\n videoInput: null\n },\n turnSettings: null,\n turnOnly: false,\n chat: {\n hasNewMessages: false\n },\n roomHistory: [],\n mediaDevices: [],\n inputDeviceChangedCallbacks: [],\n theme: '',\n version: ''\n }\n },\n getters: {},\n mutations: {\n changeProfile (state, payload) {\n window.localStorage['profile'] = JSON.stringify(payload)\n state.application.profile = payload\n },\n changeDeviceSettings (state, payload) {\n window.localStorage['deviceSettings'] = JSON.stringify(payload)\n state.application.deviceSettings = payload\n },\n changeHasNewMessages (state, payload) {\n state.application.chat.hasNewMessages = payload\n },\n changeTurnOnly (state, payload) {\n window.localStorage['turnOnly'] = JSON.stringify(payload)\n state.application.turnOnly = payload\n },\n changeTheme (state, payload) {\n window.localStorage['theme'] = payload\n state.application.theme = payload\n },\n // eslint-disable-next-line\n clearProfile (state) {\n state.application.profile = null\n window.localStorage.removeItem('profile')\n },\n addRoomToHistory (state, payload) {\n if (state.application.roomHistory.length > 10) {\n var sliceAt = state.application.roomHistory.length - 10\n state.application.roomHistory = state.application.roomHistory.slice(sliceAt, state.application.roomHistory.length)\n }\n state.application.roomHistory.push(payload)\n window.localStorage['roomHistory'] = JSON.stringify(state.application.roomHistory)\n },\n updateRoomHistory (state, payload) {\n // eslint-disable-next-line\n var existRoom = state.application.roomHistory.find((e, i, a) => e.id === payload.id)\n if (!existRoom) {\n return\n }\n existRoom.date = payload.date\n window.localStorage['roomHistory'] = JSON.stringify(state.application.roomHistory)\n },\n // eslint-disable-next-line\n clearHistory (state, payload) {\n state.application.roomHistory = []\n window.localStorage.removeItem('roomHistory')\n },\n updateMediaDevices (state, payload) {\n state.application.mediaDevices = payload\n },\n updateTurnSettings (state, payload) {\n state.application.turnSettings = payload\n },\n addDeviceChangedCallback (state, payload) {\n state.application.inputDeviceChangedCallbacks.push(payload)\n },\n changeVersion (state, value) {\n state.application.version = value\n }\n },\n actions: {}\n})\n","// Copyright 2021 Klabukov Erik.\n// SPDX-License-Identifier: GPL-3.0-only\n/*eslint-disable*/\nconst ThemeHelper = function() {\n \n const preloadTheme = (href) => {\n let link = document.createElement('link');\n link.rel = \"stylesheet\";\n link.href = href;\n document.head.appendChild(link);\n \n return new Promise((resolve, reject) => {\n link.onload = e => {\n const sheet = e.target.sheet;\n sheet.disabled = true;\n resolve(sheet);\n };\n link.onerror = reject;\n });\n };\n \n const selectTheme = (themes, name) => {\n if (name && !themes[name]) {\n throw new Error(`\"${name}\" has not been defined as a theme.`); \n }\n Object.keys(themes).forEach(n => themes[n].disabled = (n !== name));\n }\n\n const availableThemes = {\n dark: \"/css/bootstrap.dark.min.css\",\n default: \"/css/bootstrap.default.css\"\n };\n \n let themes = {};\n\n return {\n init() {\n var themeLoader = Object.keys(availableThemes).map(n => preloadTheme(availableThemes[n]).then(s => themes[n] = s));\n return Promise.all(themeLoader).then(sheets => {\n console.log(`${sheets.length} themes loaded`);\n selectTheme(themes, \"default\");\n });\n },\n add(name, href) { return preloadTheme(href).then(s => themes[name] = s) },\n set theme(name) { selectTheme(themes, name) },\n get theme() { return Object.keys(themes).find(n => !themes[n].disabled) },\n get themes() { return Object.keys(themes) }\n };\n};\n\nexport default ThemeHelper;","// Copyright 2021 Klabukov Erik.\n// SPDX-License-Identifier: GPL-3.0-only\n/*eslint-disable*/\nimport Vue from 'vue'\nimport App from './App.vue'\nimport router from './router'\nimport './registerServiceWorker'\nimport language from './assets/lang.json'\nimport { BootstrapVue, IconsPlugin } from 'bootstrap-vue'\nimport { library } from '@fortawesome/fontawesome-svg-core'\nimport { faUserSecret, faVolumeUp } from '@fortawesome/free-solid-svg-icons'\nimport { faGithub } from '@fortawesome/free-brands-svg-icons'\nimport { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'\nimport 'bootstrap/dist/css/bootstrap.css'\nimport 'bootstrap-vue/dist/bootstrap-vue.css'\nimport store from './services/store'\nimport ThemeHelper from './services/ThemeHelper'\nimport VueSimpleMarkdown from 'vue-simple-markdown'\n// You need a specific loader for CSS files like https://github.com/webpack/css-loader\nimport 'vue-simple-markdown/dist/vue-simple-markdown.css'\n// Sentry\nimport * as Sentry from \"@sentry/vue\";\nimport { Integrations } from \"@sentry/tracing\";\nimport axios from 'axios'\n// i18n\nimport VueI18n from 'vue-i18n'\n\nVue.config.productionTip = false\n// Initialize FontAwesome\nlibrary.add(faUserSecret, faGithub, faVolumeUp)\nVue.component('font-awesome-icon', FontAwesomeIcon)\n// Install BootstrapVue\nVue.use(BootstrapVue)\n// Optionally install the BootstrapVue icon components plugin\nVue.use(IconsPlugin)\n// Markdown plugin\nVue.use(VueSimpleMarkdown)\n// i18n plugin\nVue.use(VueI18n)\n\n// Get profile from store\nvar profile = window.localStorage['profile']\nif (profile !== undefined) {\n store.commit('changeProfile', JSON.parse(profile))\n}\n// Restore device settings\nvar deviceSettings = window.localStorage['deviceSettings']\nif (deviceSettings !== undefined) {\n store.commit('changeDeviceSettings', JSON.parse(deviceSettings))\n}\n// Restore room settings\nvar roomHistory = window.localStorage['roomHistory']\nif (roomHistory !== undefined) {\n var parsedHistory = JSON.parse(roomHistory)\n parsedHistory.forEach(element => {\n store.commit('addRoomToHistory', element)\n })\n}\n// Restore turn only settings\nvar turnOnly = window.localStorage['turnOnly']\nif (turnOnly !== undefined) {\n store.commit('changeTurnOnly', JSON.parse(turnOnly))\n}\n// Restore theme settings\nvar themeHelper = new ThemeHelper()\nVue.prototype.$themeHelper = themeHelper\nvar themeHelperInitTask = themeHelper.init().then(r => {\n var theme = window.localStorage['theme']\n if (theme !== undefined) {\n store.commit('changeTheme', theme)\n }else{\n var detectedTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? \"dark\" : \"default\"\n store.commit('changeTheme', detectedTheme)\n }\n themeHelper.theme = store.state.application.theme\n})\n\n// Restore language settings\nvar currentLang = window.localStorage['lang']\nif (currentLang === undefined || currentLang !== \"ru\" && currentLang !== \"en\" ) {\n var browserLang = navigator.language || navigator.userLanguage;\n currentLang = browserLang === \"ru-RU\" ? \"ru\" : \"en\";\n window.localStorage['lang'] = currentLang;\n}\nconsole.log(language);\nconst messages = {\n en: language[\"en\"],\n ru: language[\"ru\"],\n}\nconst i18n = new VueI18n({\n locale: currentLang, // set locale\n messages, // set locale messages\n})\n\n// Detect getUserMedia\nnavigator.getUserMedia = navigator.getUserMedia ||\n navigator.webkitGetUserMedia ||\n navigator.mozGetUserMedia\n\n// Apply csrf\nif (document.cookie.indexOf('CSRF-TOKEN') > -1) {\n const v = document.cookie.match('(^|;) ?' + 'CSRF-TOKEN' + '=([^;]*)(;|$)')\n const r = v ? v[2] : ''\n var csrfToken = r\n axios.defaults.headers.common['X-CSRF-TOKEN'] = csrfToken\n}\n\n// Add Sentry exception handling\nvar sentryIntegrationTask = axios.get(\"/api/settings\").then(response => {\n if(response.data == null || response.status != 200)\n return;\n Sentry.init({\n Vue,\n dsn: response.data.sentryDsn,\n integrations: [\n new Integrations.BrowserTracing({\n routingInstrumentation: Sentry.vueRouterInstrumentation(router),\n tracingOrigins: [\"localhost\", \"peer-meetings.nb-47.ml\", document.location.host, /^\\//],\n }),\n ],\n tracesSampleRate: 0.5,\n });\n})\n\nPromise.all([\n themeHelperInitTask, \n sentryIntegrationTask\n]).then(result => {\n new Vue({\n i18n,\n store,\n router,\n render: h => h(App)\n }).$mount('#app')\n})\n","export * from \"-!../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../node_modules/css-loader/index.js??ref--6-oneOf-1-1!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./LogIn.vue?vue&type=style&index=0&lang=css&\"","export * from \"-!../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../node_modules/css-loader/index.js??ref--6-oneOf-1-1!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Welcome.vue?vue&type=style&index=0&lang=css&\"","module.exports = __webpack_public_path__ + \"img/logo.dbb29645.png\";","export * from \"-!../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../node_modules/css-loader/index.js??ref--6-oneOf-1-1!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./TopMenu.vue?vue&type=style&index=0&lang=css&\""],"sourceRoot":""}