├── .firebaserc ├── .idea ├── .gitignore ├── vcs.xml ├── inspectionProfiles │ └── Project_Default.xml ├── modules.xml └── podcast_app.iml ├── firebase.json ├── src ├── utils.js ├── styles.css ├── auth.js ├── index.html ├── app.js └── question.js ├── package.json ├── .github └── workflows │ ├── firebase-hosting-merge.yml │ └── firebase-hosting-pull-request.yml ├── webpack.config.js ├── .gitignore └── public ├── index.html └── bundle.08d1dbcd66acf7aa8ecc.js /.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "podcast--app-fd631" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "hosting": { 3 | "public": "public", 4 | "ignore": [ 5 | "firebase.json", 6 | "**/.*", 7 | "**/node_modules/**" 8 | ], 9 | "rewrites": [ 10 | { 11 | "source": "**", 12 | "destination": "/index.html" 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | export function isValid(value) { 2 | return value.length >= 10 3 | } 4 | 5 | export function createModal(title, content) { 6 | const modal = document.createElement('div') 7 | modal.classList.add('modal') 8 | 9 | const html = ` 10 |

${title}

11 | 12 | ` 13 | 14 | modal.innerHTML = html 15 | 16 | mui.overlay('on', modal) 17 | } -------------------------------------------------------------------------------- /.idea/podcast_app.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "podcast_app", 3 | "version": "1.0.0", 4 | "description": "podcast app Sensei", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --mode development --open", 8 | "build": "webpack --mode production" 9 | }, 10 | "keywords": [ 11 | "sensei" 12 | ], 13 | "author": "Omka", 14 | "license": "ISC", 15 | "devDependencies": { 16 | "clean-webpack-plugin": "^4.0.0", 17 | "css-loader": "^6.8.1", 18 | "html-webpack-plugin": "^5.5.3", 19 | "style-loader": "^3.3.3", 20 | "webpack": "^5.88.2", 21 | "webpack-cli": "^5.1.4", 22 | "webpack-dev-server": "^4.15.1" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.github/workflows/firebase-hosting-merge.yml: -------------------------------------------------------------------------------- 1 | # This file was auto-generated by the Firebase CLI 2 | # https://github.com/firebase/firebase-tools 3 | 4 | name: Deploy to Firebase Hosting on merge 5 | 'on': 6 | push: 7 | branches: 8 | - main 9 | jobs: 10 | build_and_deploy: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | - run: npm ci && npm run build 15 | - uses: FirebaseExtended/action-hosting-deploy@v0 16 | with: 17 | repoToken: '${{ secrets.GITHUB_TOKEN }}' 18 | firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_PODCAST__APP_FD631 }}' 19 | channelId: live 20 | projectId: podcast--app-fd631 21 | -------------------------------------------------------------------------------- /.github/workflows/firebase-hosting-pull-request.yml: -------------------------------------------------------------------------------- 1 | # This file was auto-generated by the Firebase CLI 2 | # https://github.com/firebase/firebase-tools 3 | 4 | name: Deploy to Firebase Hosting on PR 5 | 'on': pull_request 6 | jobs: 7 | build_and_preview: 8 | if: '${{ github.event.pull_request.head.repo.full_name == github.repository }}' 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | - run: npm ci && npm run build 13 | - uses: FirebaseExtended/action-hosting-deploy@v0 14 | with: 15 | repoToken: '${{ secrets.GITHUB_TOKEN }}' 16 | firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_PODCAST__APP_FD631 }}' 17 | projectId: podcast--app-fd631 18 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const HTMLPlugin = require('html-webpack-plugin'); 3 | const { CleanWebpackPlugin } = require('clean-webpack-plugin'); 4 | 5 | module.exports = { 6 | entry: './src/app.js', 7 | output: { 8 | filename: "bundle.[chunkhash].js", 9 | path: path.resolve(__dirname, 'public') 10 | }, 11 | devServer: { 12 | port: 3000 13 | }, 14 | plugins: [ 15 | new HTMLPlugin({ 16 | template: "./src/index.html" 17 | }), 18 | new CleanWebpackPlugin() 19 | ], 20 | module: { 21 | rules: [ 22 | { 23 | test: /\.css$/i, 24 | use: ['style-loader', 'css-loader'] 25 | } 26 | ] 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /src/styles.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Body CSS 3 | */ 4 | 5 | html, 6 | body { 7 | height: 100%; 8 | } 9 | 10 | html, 11 | body, 12 | input, 13 | textarea, 14 | button { 15 | -webkit-font-smoothing: antialiased; 16 | -moz-osx-font-smoothing: grayscale; 17 | text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.004); 18 | } 19 | 20 | 21 | /** 22 | * Sidebar CSS 23 | */ 24 | 25 | #sidebar { 26 | background-color: #2196f3; 27 | padding: 15px; 28 | } 29 | 30 | @media (min-width: 768px) { 31 | #sidebar { 32 | position: fixed; 33 | top: 0; 34 | bottom: 0; 35 | width: 180px; 36 | height: 100%; 37 | padding-top: 30px; 38 | } 39 | } 40 | 41 | .author { 42 | font-size: .8rem; 43 | } 44 | 45 | 46 | /** 47 | * Content CSS 48 | */ 49 | @media (min-width: 768px) { 50 | #content { 51 | margin-left: 180px; 52 | } 53 | } 54 | 55 | .floating-btn { 56 | position: fixed; 57 | bottom: 50px; 58 | right: 50px; 59 | } 60 | 61 | .modal { 62 | max-width: 600px; 63 | max-height: 300px; 64 | margin: 100px auto; 65 | overflow-y: auto; 66 | background-color: #fff; 67 | } 68 | 69 | .modal > h1{ 70 | text-align: center; 71 | } 72 | .modal .modal-content { 73 | padding: 1rem; 74 | } 75 | 76 | .error { 77 | color: red; 78 | } -------------------------------------------------------------------------------- /src/auth.js: -------------------------------------------------------------------------------- 1 | export function getAuthForm() { 2 | return ` 3 |
4 |
5 | 6 | 7 |
8 |
9 | 10 | 11 |
12 | 18 |
19 | ` 20 | } 21 | 22 | export function authWithEmailAndPassword(email, password) { 23 | const apiKey = 'AIzaSyDOYvjw4CQtRxLhOJZLwSK8KWDvEMrALz4' 24 | return fetch(`https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=${apiKey}`, { // Note the '=' after 'key' 25 | method: "POST", 26 | body: JSON.stringify({ 27 | email, 28 | password, 29 | returnSecureToken: true 30 | }), 31 | headers: { 32 | 'Content-Type': 'application/json' 33 | } 34 | }) 35 | .then(response => response.json()) 36 | .then(data => data.idToken) 37 | } 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | firebase-debug.log* 8 | firebase-debug.*.log* 9 | 10 | # Firebase cache 11 | .firebase/ 12 | 13 | # Firebase config 14 | 15 | # Uncomment this if you'd like others to create their own Firebase project. 16 | # For a team working on the same Firebase project(s), it is recommended to leave 17 | # it commented so all members can deploy to the same project(s) in .firebaserc. 18 | # .firebaserc 19 | 20 | # Runtime data 21 | pids 22 | *.pid 23 | *.seed 24 | *.pid.lock 25 | 26 | # Directory for instrumented libs generated by jscoverage/JSCover 27 | lib-cov 28 | 29 | # Coverage directory used by tools like istanbul 30 | coverage 31 | 32 | # nyc test coverage 33 | .nyc_output 34 | 35 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 36 | .grunt 37 | 38 | # Bower dependency directory (https://bower.io/) 39 | bower_components 40 | 41 | # node-waf configuration 42 | .lock-wscript 43 | 44 | # Compiled binary addons (http://nodejs.org/api/addons.html) 45 | build/Release 46 | 47 | # Dependency directories 48 | node_modules/ 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Optional REPL history 57 | .node_repl_history 58 | 59 | # Output of 'npm pack' 60 | *.tgz 61 | 62 | # Yarn Integrity file 63 | .yarn-integrity 64 | 65 | # dotenv environment variables file 66 | .env 67 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Podcast 10 | 11 | 12 | 13 | 14 | 18 |
19 |
20 |


21 |
Задай Вопрос
22 |
23 |
24 |
25 |
28 | 31 |
32 |
33 |
Ваши вопросы
34 |
35 |
36 |
37 |
38 |
39 |
40 | 41 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Podcast 10 | 11 | 12 | 13 | 20 |
21 |
22 |
23 |
24 |
25 |
Задай Вопрос
26 |
27 |
28 |
29 |
30 | 31 | 32 |
33 | 41 |
42 |
43 |
Ваши вопросы
44 |
45 |
46 | 47 |
48 |
49 |
50 |
51 | 52 | 53 | -------------------------------------------------------------------------------- /src/app.js: -------------------------------------------------------------------------------- 1 | import {Question} from './question' 2 | import './styles.css' 3 | import {createModal, isValid} from "./utils" 4 | import {authWithEmailAndPassword, getAuthForm} from "./auth"; 5 | 6 | const modalBtn = document.getElementById('modal-btn') 7 | const form = document.getElementById('form') 8 | const input = form.querySelector('#question-input') 9 | window.addEventListener('load', Question.renderList) 10 | 11 | const submitBtn = form.querySelector('#submit') 12 | form.addEventListener('submit', submitFormHandler) 13 | modalBtn.addEventListener('click', openModal) 14 | input.addEventListener('input', () => { 15 | submitBtn.disabled = !isValid(input.value) 16 | }) 17 | 18 | function submitFormHandler(event) { 19 | event.preventDefault() 20 | 21 | if (isValid(input.value)) { 22 | const question = { 23 | text: input.value.trim(), 24 | data: new Date().toJSON() 25 | } 26 | submitBtn.disabled = true 27 | //Async request to server to save question 28 | Question.create(question) 29 | .then(() => { 30 | input.value = '' 31 | input.className = '' 32 | submitBtn.disabled = false 33 | }) 34 | .catch(error => { 35 | console.error("Error while saving the question:", error) 36 | submitBtn.disabled = false 37 | }) 38 | } 39 | } 40 | 41 | function openModal() { 42 | createModal('Авторизация', getAuthForm()) 43 | document.getElementById('auth-form') 44 | .addEventListener('submit', authFormHandler, {once: true}) 45 | } 46 | 47 | function authFormHandler(event) { 48 | event.preventDefault() 49 | 50 | const btn = event.target.querySelector('button') 51 | const email = event.target.querySelector('#email').value 52 | const password = event.target.querySelector('#password').value 53 | 54 | btn.disabled = true 55 | authWithEmailAndPassword(email, password) 56 | .then(Question.fetch) 57 | .then(renderModalAfterAuth) 58 | .then(() => btn.disabled = false) 59 | } 60 | 61 | function renderModalAfterAuth(content) { 62 | if (typeof content === 'string') { 63 | createModal('Error' , content) 64 | }else { 65 | createModal('Список вопросов', Question.listToHtml(content)) 66 | } 67 | } -------------------------------------------------------------------------------- /src/question.js: -------------------------------------------------------------------------------- 1 | export class Question { 2 | static create(question) { 3 | return fetch('https://podcast--app-fd631-default-rtdb.asia-southeast1.firebasedatabase.app/questions.json', { 4 | method: "POST", 5 | body: JSON.stringify(question), 6 | headers: { 7 | 'Content-Type': 'application/json' 8 | } 9 | }) 10 | .then(response => response.json()) 11 | .then(response => { 12 | question.id = response.name 13 | return question 14 | }) 15 | .then(addToLocalStorage) 16 | .then(Question.renderList) 17 | .catch(error => { 18 | console.log('Error', error) 19 | throw error 20 | }) 21 | } 22 | 23 | static fetch(token) { 24 | if (!token) { 25 | return Promise.resolve('

У вас нету токена

') 26 | } 27 | return fetch(`https://podcast--app-fd631-default-rtdb.asia-southeast1.firebasedatabase.app/questions.json?auth=${token}`) 28 | .then(response => response.json()) 29 | .then(response => { 30 | if (response.error) { 31 | return `

${response && response.error}

` 32 | } 33 | return response ? Object.keys(response).map(key => ({ 34 | ...response[key], 35 | id: key 36 | })) : [] 37 | }) 38 | } 39 | 40 | static renderList() { 41 | const questions = getQuestionsFromLocalStorage() 42 | 43 | const html = questions.length ? questions.map(toCard) : `
Вы пока ничего не спрашивали
` 44 | 45 | const list = document.getElementById('list') 46 | list.innerHTML = html 47 | } 48 | 49 | static listToHtml(questions) { 50 | return questions.length ? `
    ${questions.map(q => `
  1. ${q.text}
  2. .join()`)}
` 51 | : '

Вопросов пока нет

' 52 | } 53 | } 54 | 55 | 56 | function addToLocalStorage(question) { 57 | question.date = new Date() 58 | const all = getQuestionsFromLocalStorage() 59 | all.push(question) 60 | localStorage.setItem('questions', JSON.stringify(all)) 61 | } 62 | 63 | function getQuestionsFromLocalStorage() { 64 | return JSON.parse(localStorage.getItem('questions') || '[] ' ) 65 | } 66 | 67 | function toCard(question) { 68 | return ` 69 |
70 | ${new Date(question.date).toLocaleDateString()} 71 | ${new Date(question.date).toLocaleTimeString()} 72 |
73 |
${question.text}
74 |
75 | ` 76 | } -------------------------------------------------------------------------------- /public/bundle.08d1dbcd66acf7aa8ecc.js: -------------------------------------------------------------------------------- 1 | (()=>{"use strict";var t={28:(t,e,n)=>{n.d(e,{Z:()=>s});var r=n(81),o=n.n(r),a=n(645),i=n.n(a)()(o());i.push([t.id,"/**\n * Body CSS\n */\n\nhtml,\nbody {\n height: 100%;\n}\n\nhtml,\nbody,\ninput,\ntextarea,\nbutton {\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.004);\n}\n\n\n/**\n * Sidebar CSS\n */\n\n#sidebar {\n background-color: #2196f3;\n padding: 15px;\n}\n\n@media (min-width: 768px) {\n #sidebar {\n position: fixed;\n top: 0;\n bottom: 0;\n width: 180px;\n height: 100%;\n padding-top: 30px;\n }\n}\n\n.author {\n font-size: .8rem;\n}\n\n\n/**\n * Content CSS\n */\n@media (min-width: 768px) {\n #content {\n margin-left: 180px;\n }\n}\n\n.floating-btn {\n position: fixed;\n bottom: 50px;\n right: 50px;\n}\n\n.modal {\n max-width: 600px;\n max-height: 300px;\n margin: 100px auto;\n overflow-y: auto;\n background-color: #fff;\n}\n\n.modal > h1{\n text-align: center;\n}\n.modal .modal-content {\n padding: 1rem;\n}\n\n.error {\n color: red;\n}",""]);const s=i},645:t=>{t.exports=function(t){var e=[];return e.toString=function(){return this.map((function(e){var n="",r=void 0!==e[5];return e[4]&&(n+="@supports (".concat(e[4],") {")),e[2]&&(n+="@media ".concat(e[2]," {")),r&&(n+="@layer".concat(e[5].length>0?" ".concat(e[5]):""," {")),n+=t(e),r&&(n+="}"),e[2]&&(n+="}"),e[4]&&(n+="}"),n})).join("")},e.i=function(t,n,r,o,a){"string"==typeof t&&(t=[[null,t,void 0]]);var i={};if(r)for(var s=0;s0?" ".concat(l[5]):""," {").concat(l[1],"}")),l[5]=a),n&&(l[2]?(l[1]="@media ".concat(l[2]," {").concat(l[1],"}"),l[2]=n):l[2]=n),o&&(l[4]?(l[1]="@supports (".concat(l[4],") {").concat(l[1],"}"),l[4]=o):l[4]="".concat(o)),e.push(l))}},e}},81:t=>{t.exports=function(t){return t[1]}},379:t=>{var e=[];function n(t){for(var n=-1,r=0;r{var e={};t.exports=function(t,n){var r=function(t){if(void 0===e[t]){var n=document.querySelector(t);if(window.HTMLIFrameElement&&n instanceof window.HTMLIFrameElement)try{n=n.contentDocument.head}catch(t){n=null}e[t]=n}return e[t]}(t);if(!r)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");r.appendChild(n)}},216:t=>{t.exports=function(t){var e=document.createElement("style");return t.setAttributes(e,t.attributes),t.insert(e,t.options),e}},565:(t,e,n)=>{t.exports=function(t){var e=n.nc;e&&t.setAttribute("nonce",e)}},795:t=>{t.exports=function(t){if("undefined"==typeof document)return{update:function(){},remove:function(){}};var e=t.insertStyleElement(t);return{update:function(n){!function(t,e,n){var r="";n.supports&&(r+="@supports (".concat(n.supports,") {")),n.media&&(r+="@media ".concat(n.media," {"));var o=void 0!==n.layer;o&&(r+="@layer".concat(n.layer.length>0?" ".concat(n.layer):""," {")),r+=n.css,o&&(r+="}"),n.media&&(r+="}"),n.supports&&(r+="}");var a=n.sourceMap;a&&"undefined"!=typeof btoa&&(r+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(a))))," */")),e.styleTagTransform(r,t,e.options)}(e,t,n)},remove:function(){!function(t){if(null===t.parentNode)return!1;t.parentNode.removeChild(t)}(e)}}}},589:t=>{t.exports=function(t,e){if(e.styleSheet)e.styleSheet.cssText=t;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(t))}}}},e={};function n(r){var o=e[r];if(void 0!==o)return o.exports;var a=e[r]={id:r,exports:{}};return t[r](a,a.exports,n),a.exports}n.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var r in e)n.o(e,r)&&!n.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n.nc=void 0,(()=>{class t{static create(n){return fetch("https://podcast--app-fd631-default-rtdb.asia-southeast1.firebasedatabase.app/questions.json",{method:"POST",body:JSON.stringify(n),headers:{"Content-Type":"application/json"}}).then((t=>t.json())).then((t=>(n.id=t.name,n))).then(e).then(t.renderList).catch((t=>{throw console.log("Error",t),t}))}static fetch(t){return t?fetch(`https://podcast--app-fd631-default-rtdb.asia-southeast1.firebasedatabase.app/questions.json?auth=${t}`).then((t=>t.json())).then((t=>t.error?`

${t&&t.error}

`:t?Object.keys(t).map((e=>({...t[e],id:e}))):[])):Promise.resolve('

У вас нету токена

')}static renderList(){const t=r(),e=t.length?t.map(o):'
Вы пока ничего не спрашивали
';document.getElementById("list").innerHTML=e}static listToHtml(t){return t.length?`
    ${t.map((t=>`
  1. ${t.text}
  2. .join()`))}
`:"

Вопросов пока нет

"}}function e(t){t.date=new Date;const e=r();e.push(t),localStorage.setItem("questions",JSON.stringify(e))}function r(){return JSON.parse(localStorage.getItem("questions")||"[] ")}function o(t){return`\n
\n ${new Date(t.date).toLocaleDateString()}\n ${new Date(t.date).toLocaleTimeString()}\n
\n
${t.text}
\n
\n `}var a=n(379),i=n.n(a),s=n(795),d=n.n(s),c=n(569),l=n.n(c),u=n(565),p=n.n(u),f=n(216),m=n.n(f),h=n(589),v=n.n(h),b=n(28),y={};function g(t){return t.length>=10}function x(t,e){const n=document.createElement("div");n.classList.add("modal");const r=`\n

${t}

\n \n `;n.innerHTML=r,mui.overlay("on",n)}y.styleTagTransform=v(),y.setAttributes=p(),y.insert=l().bind(null,"head"),y.domAPI=d(),y.insertStyleElement=m(),i()(b.Z,y),b.Z&&b.Z.locals&&b.Z.locals;const S=document.getElementById("modal-btn"),w=document.getElementById("form"),E=w.querySelector("#question-input");window.addEventListener("load",t.renderList);const T=w.querySelector("#submit");function L(e){e.preventDefault();const n=e.target.querySelector("button"),r=e.target.querySelector("#email").value,o=e.target.querySelector("#password").value;n.disabled=!0,function(t,e){return fetch("https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=AIzaSyDOYvjw4CQtRxLhOJZLwSK8KWDvEMrALz4",{method:"POST",body:JSON.stringify({email:t,password:e,returnSecureToken:!0}),headers:{"Content-Type":"application/json"}}).then((t=>t.json())).then((t=>t.idToken))}(r,o).then(t.fetch).then(C).then((()=>n.disabled=!1))}function C(e){"string"==typeof e?x("Error",e):x("Список вопросов",t.listToHtml(e))}w.addEventListener("submit",(function(e){if(e.preventDefault(),g(E.value)){const e={text:E.value.trim(),data:(new Date).toJSON()};T.disabled=!0,t.create(e).then((()=>{E.value="",E.className="",T.disabled=!1})).catch((t=>{console.error("Error while saving the question:",t),T.disabled=!1}))}})),S.addEventListener("click",(function(){x("Авторизация",'\n
\n
\n \n \n
\n
\n \n \n
\n \n Войти\n \n \n '),document.getElementById("auth-form").addEventListener("submit",L,{once:!0})})),E.addEventListener("input",(()=>{T.disabled=!g(E.value)}))})()})(); --------------------------------------------------------------------------------