From f61d02b2b8f93ecd473e4f5a85cdbde55539c6a8 Mon Sep 17 00:00:00 2001 From: allEyezOnCode Date: Thu, 26 Nov 2020 11:46:19 +0100 Subject: [PATCH 1/5] change url gen --- package-lock.json | 5 +++++ package.json | 1 + src/db/MongoDB.js | 3 ++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 4d46a00..d26ad35 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1417,6 +1417,11 @@ "sqlstring": "2.3.1" } }, + "nanoid": { + "version": "3.1.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.18.tgz", + "integrity": "sha512-rndlDjbbHbcV3xi+R2fpJ+PbGMdfBxz5v1fATIQFq0DP64FsicQdwnKLy47K4kZHdRpmQXtz24eGsxQqamzYTA==" + }, "native-request": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/native-request/-/native-request-1.0.8.tgz", diff --git a/package.json b/package.json index b36176d..a1abbeb 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "mongodb": "^3.6.3", "morgan": "^1.10.0", "mysql": "^2.18.1", + "nanoid": "^3.1.18", "nunjucks": "^3.2.2", "prom-client": "^12.0.0", "prometheus-api-metrics": "^3.1.0", diff --git a/src/db/MongoDB.js b/src/db/MongoDB.js index 2a86831..09e2560 100644 --- a/src/db/MongoDB.js +++ b/src/db/MongoDB.js @@ -1,5 +1,6 @@ const { MongoClient, ObjectID } = require("mongodb"); var crypto = require('crypto'); +const { nanoid } = require('nanoid'); const configs = require('../config/config'); const utils = require('../utils'); @@ -50,7 +51,7 @@ class MongoDB { try { let results = (await this.documentsCollection.insertOne(doc)); const documentLink = utils.uuid(results.insertedId.toString()); - const linkView = utils.uuid(documentLink); + const linkView = nanoid(5); this.documentsCollection.updateOne({_id: results.insertedId}, {$set: {documentLink: documentLink, linkView: linkView}}); return documentLink; } catch (err) { From 77a8d8cc4f90699f9fe9ea1181190828aa99af34 Mon Sep 17 00:00:00 2001 From: allEyezOnCode Date: Thu, 26 Nov 2020 11:59:33 +0100 Subject: [PATCH 2/5] FIX bug when one line --- src/db/MongoDB.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/db/MongoDB.js b/src/db/MongoDB.js index 09e2560..1b787d2 100644 --- a/src/db/MongoDB.js +++ b/src/db/MongoDB.js @@ -118,7 +118,7 @@ class MongoDB { let index = doc.content.findIndex(line => { return line.uuid == previousUuid; }); - if (index) { + if (index || index == 0) { this.documentsCollection.updateOne({documentLink: documentLink}, { $push: { content: { From d7830952d89a39cd1e6afb0cbff333012245970f Mon Sep 17 00:00:00 2001 From: allEyezOnCode Date: Thu, 26 Nov 2020 12:01:53 +0100 Subject: [PATCH 3/5] fix bug with one line(be sure ) --- src/db/MongoDB.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/db/MongoDB.js b/src/db/MongoDB.js index 1b787d2..806f2ef 100644 --- a/src/db/MongoDB.js +++ b/src/db/MongoDB.js @@ -118,7 +118,7 @@ class MongoDB { let index = doc.content.findIndex(line => { return line.uuid == previousUuid; }); - if (index || index == 0) { + if (index || index === 0) { this.documentsCollection.updateOne({documentLink: documentLink}, { $push: { content: { From 803f2015a677e80301fcea541b6bf3a722e35fd4 Mon Sep 17 00:00:00 2001 From: Brieuc Dubois <45831883+BhasherBEL@users.noreply.github.com> Date: Thu, 26 Nov 2020 12:05:31 +0100 Subject: [PATCH 4/5] Delete .gitattributes --- .gitattributes | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 728c9a4..0000000 --- a/.gitattributes +++ /dev/null @@ -1,5 +0,0 @@ -* text=auto - -/imgs export-ignore -/src/publics/img export-ignore -/src/views/legal/archive export-ignore From 8647463aab82f4966f6ec7a8c703330441de5a1a Mon Sep 17 00:00:00 2001 From: Brieuc Dubois <45831883+BhasherBEL@users.noreply.github.com> Date: Thu, 26 Nov 2020 12:07:06 +0100 Subject: [PATCH 5/5] Delete editor.min.js --- src/publics/js/dist/editor.min.js | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/publics/js/dist/editor.min.js diff --git a/src/publics/js/dist/editor.min.js b/src/publics/js/dist/editor.min.js deleted file mode 100644 index 8f69eae..0000000 --- a/src/publics/js/dist/editor.min.js +++ /dev/null @@ -1 +0,0 @@ -(()=>{"use strict";class t{static isDebug(){return!0}}class e{static id(t){return document.getElementById(t)}static class(t){return document.getElementsByClassName(t)}static attribute(t,e){return document.querySelector("["+t+'"'+e+'"]')}}function n(){return 0===window.getSelection().rangeCount?null:window.getSelection().getRangeAt(0).startContainer}function s(t,e=n()){try{return e.nodeType!==Node.TEXT_NODE&&e.hasAttribute(t)?e:s(t,e.parentElement)}catch(t){return null}}function i(t,e=n()){try{return t.includes(e.nodeName.toLowerCase())?e:i(t,e.parentElement)}catch(t){return null}}class r{static trigger(t,e){document.dispatchEvent(new CustomEvent(t,e))}static triggerCustom(t,e){document.dispatchEvent(new CustomEvent(t,{detail:e}))}}class o{static string(t,e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"){let n="";for(let s=0;s"+t+"

"+e+"

",document.getElementById("body").appendChild(r),setTimeout((()=>{r.remove()}),n)}const c=[16,17,18,19,20,27,33,34,35,36,37,38,39,40,45,112,113,114,115,116,117,118,119,120,121,122,123,144,145,225];class u{static isExtra(t){return c.includes(t)}static ctrl(t){return window.navigator.platform.match("Mac")?t.metaKey:t.ctrlKey}}const l={generic:[{matches:{1:[{name:"keyword.operator",pattern:/\=|\+/g},{name:"keyword.dot",pattern:/\./g}],2:{name:"string",matches:{name:"constant.character.escape",pattern:/\\('|"){1}/g}}},pattern:/(\(|\s|\[|\=|:|\+|\.|\{|,)(('|")([^\\\1]|\\.)*?(\3))/gm},{name:"comment",pattern:/\/\*[\s\S]*?\*\/|(\/\/|\#)(?!.*('|").*?[^:](\/\/|\#)).*?$/gm},{name:"constant.numeric",pattern:/\b(\d+(\.\d+)?(e(\+|\-)?\d+)?(f|d)?|0x[\da-f]+)\b/gi},{matches:{1:"keyword"},pattern:/\b(and|array|as|b(ool(ean)?|reak)|c(ase|atch|har|lass|on(st|tinue))|d(ef|elete|o(uble)?)|e(cho|lse(if)?|xit|xtends|xcept)|f(inally|loat|or(each)?|unction)|global|if|import|int(eger)?|long|new|object|or|pr(int|ivate|otected)|public|return|self|st(ring|ruct|atic)|switch|th(en|is|row)|try|(un)?signed|var|void|while)(?=\b)/gi},{name:"constant.language",pattern:/true|false|null/g},{name:"keyword.operator",pattern:/\+|\!|\-|&(gt|lt|amp);|\||\*|\=/g},{matches:{1:"function.call"},pattern:/(\w+?)(?=\()/g},{matches:{1:"storage.function",2:"entity.name.function"},pattern:/(function)\s(.*?)(?=\()/g}],python:[{name:"variable.self",pattern:/self/g},{name:"constant.language",pattern:/None|True|False|NotImplemented|\.\.\./g},{name:"support.object",pattern:/object/g},{name:"support.function.python",pattern:/\b(bs|divmod|input|open|staticmethod|all|enumerate|int|ord|str|any|eval|isinstance|pow|sum|basestring|execfile|issubclass|print|super|bin|file|iter|property|tuple|bool|filter|len|range|type|bytearray|float|list|raw_input|unichr|callable|format|locals|reduce|unicode|chr|frozenset|long|reload|vars|classmethod|getattr|map|repr|xrange|cmp|globals|max|reversed|zip|compile|hasattr|memoryview|round|__import__|complex|hash|min|set|apply|delattr|help|next|setattr|buffer|dict|hex|object|slice|coerce|dir|id|oct|sorted|intern)(?=\()/g},{matches:{1:"keyword"},pattern:/\b(pass|lambda|with|is|not|in|from|elif|raise|del)(?=\b)/g},{matches:{1:"storage.class",2:"entity.name.class",3:"entity.other.inherited-class"},pattern:/(class)\s+(\w+)\((\w+?)\)/g},{matches:{1:"storage.function",2:"support.magic"},pattern:/(def)\s+(__\w+)(?=\()/g},{name:"support.magic",pattern:/__(name)__/g},{matches:{1:"keyword.control",2:"support.exception.type"},pattern:/(except) (\w+):/g},{matches:{1:"storage.function",2:"entity.name.function"},pattern:/(def)\s+(\w+)(?=\()/g},{name:"entity.name.function.decorator",pattern:/@([\w\.]+)/g},{name:"comment.docstring",pattern:/('{3}|"{3})[\s\S]*?\1/gm}]};function d(t,e,n,s){const i=s.substr(t);return n=n.replace(/\$/g,"$$$$"),s.substr(0,t)+i.replace(e,n)}function h(t){const e=[];for(const n in t)t.hasOwnProperty(n)&&e.push(n);return e.sort(((t,e)=>e-t))}function p(t,e,n,s){return n>=t&&nt&&s${e}`}function i(t,i,r,o=0){let a=i.pattern;if(!a)return!1;const c=!a.global;a=function(t){let e="";return t.ignoreCase&&(e+="i"),t.multiline&&(e+="m"),new RegExp(t.source,e)}(a);const u=a.exec(r);if(!u)return!1;!i.name&&i.matches&&"string"==typeof i.matches[0]&&(i.name=i.matches[0],delete i.matches[0]);let l=u[0];const m=u.index+o,f=u[0].length+m;if(m===f)return!1;if(function(t,s){for(let c in n)if(c=parseInt(c,10),i=c,r=n[c],a=s,((o=t)!==i||a!==r)&&o<=i&&a>=r&&(delete n[c],delete e[c]),p(c,n[c],t,s))return!0;var i,r,o,a;return!1}(m,f))return{remaining:r.substr(f-o),offset:f};function w(t,e){const n=u[e];if(!n)return;const r=i.matches[e],o=r.language,a=r.name&&r.matches?r.matches:r,c=function(t,n,i){l=d(function(t,e){let n=0;for(let s=1;s0)if(t.nodeType===Node.TEXT_NODE)t.textContent.length=0){let n=document.getSelection(),s=m.createRange(t,{count:e});s&&(s.collapse(!1),n.removeAllRanges(),n.addRange(s))}}static setRangeStart(t,e){if(e>=0){let n=document.getSelection(),s=m.createRange(t,{count:e});n.getRangeAt(0).setStart(s.endContainer,s.endOffset)}}static getEndPosition(t){let e=0;const n=document.getSelection();if(n&&n.rangeCount>0){let s=n.getRangeAt(0),i=s.cloneRange();i.selectNodeContents(t),i.setEnd(s.endContainer,s.endOffset),e=i.toString().length}return e}static getBeginPosition(t){let e=0;const n=document.getSelection();if(n&&n.rangeCount>0){let s=n.getRangeAt(0),i=s.cloneRange();i.selectNodeContents(t),i.setEnd(s.startContainer,s.startOffset),e=i.toString().length}return e}}class f{constructor(t=0){this.size=t,this.stack=[]}push(t){this.stack.push(t),this.size>=1&&(this.stack=this.stack.slice(-this.size))}get(t){return t<0?this.stack[this.stack.length+t]:this.stack[t]}}class w{constructor(t){this.size=t,this.stack={},this.old=new f(t)}push(t,e){this.stack[t]=e}get(t){return this.stack[t]}add(t,e){this.push(t,{send:Date.now(),data:e})}archive(t,e,n=null){const s=this.stack[t];return delete this.stack[t],s.server=e,s.received=n||Date.now(),this.old.push(s),s}getAll(){return this.stack}getSize(){return Object.keys(this.stack).length}}class y{constructor(t,e,...n){this.name=t,this.verbosity=e,this.fcts=n}}const b={DEBUG:new y("DEBUG",6,console.debug),INFO:new y("INFO",5,console.info),LOG:new y("LOG",4,console.log),WARN:new y("WARN",3,console.warn),ERROR:new y("ERROR",2,console.error),CRITICAL:new y("CRITICAL",1,console.error)},v=window.location.origin,E=new f(1e3);class k{static has(){return t.isDebug()}static entry(t,e,...n){let s=null;e&&e.stack&&(s=e.stack.toString().split(/\r\n|\n/)[1].replace(v,""));const i=class{static full(){const t=new Date;return`${t.getFullYear()}.${t.getMonth()+1}.${t.getDate()}-${t.getHours()}:${t.getMinutes()}:${t.getSeconds()}`}static day(){const t=new Date;return`${t.getFullYear()}.${t.getMonth()+1}.${t.getDate()}`}}.full();if(E.push([i,t,s,n]),k.has()||t.verbosity<=2)for(const e of t.fcts)e(`${i} - ${t.name} - ${s} - `,...n)}static debug(...t){k.entry(b.DEBUG,new Error,...t)}static info(...t){k.entry(b.INFO,new Error,...t)}static log(...t){k.entry(b.LOG,new Error,...t)}static warn(...t){k.entry(b.WARN,new Error,...t)}static error(...t){k.entry(b.ERROR,new Error,...t)}static critical(...t){k.entry(b.CRITICAL,new Error,...t)}}function C(t){return String(t).replaceAll("<","<").replaceAll(">",">")}class S{constructor(t,e){this.element=t,this.lang=e,this.pattern=l[e].concat(l.generic)}setLang(t){this.lang=t,this.pattern=l[t]|this.pattern}getLang(){return this.lang}getElement(){return this.element}getPattern(){return this.pattern}apply(){const t=new g(this.pattern);this.element.innerHTML=t.refract(C(this.element.innerText)).replaceAll("\n",""),""===this.element.innerHTML.replaceAll("\n","")&&(this.element.innerHTML="
")}ApplyWithCaret(){const t=m.getBeginPosition(this.element);this.apply(),m.setPosition(this.element,t)}static onCurrent(t){return new S(s("uuid"),t)}}class T{constructor(t){this.editable=t,this.history=new f(2),this.change=!1,this.getAll()}hasChange(){return this.change}select(t){return document.querySelector(`[uuid='${t}']`)}getAll(){let t=[];for(let e of this.editable.children)e.hasAttribute("uuid")?t.push({uuid:e.getAttribute("uuid"),content:e.innerText.replaceAll("\n","")}):k.error("Error when trying to get all content of lines: ",e," has no UUID attribute.");return this.history.push(t),t}update(t,e){let n=this.select(t);n?(n.innerText=C(e),new S(n,"python").apply()):k.warn(`Error when trying to update element with uuid '${t}': No div has this uuid.`)}new(t,e,n){if(this.select(t))k.warn(`Children with uuid ${t} still exist.`);else{const s=this.select(e);s.parentNode.insertBefore(function(t,e,n){const s=document.createElement("div");s.innerHTML=e;for(const[t,e]of Object.entries(n))s.setAttribute(t,e);return s}(0,n+"
",{uuid:t}),s.nextSibling)}}remove(t){let e=this.select(t);e?e.remove():k.warn(`The element with uuid '${t}' can't be removed: it doesn't exist.`)}decompose(t){let e=[],n={};for(const s of t)e.push(s.uuid),n[s.uuid]=s.content;return[e,n]}getDiff(t){const[e,n]=this.decompose(this.history.get(-2)),[s,i]=this.decompose(this.history.get(-1));let r=[];for(const[s,i]of this.history.get(-1).entries())e.includes(i.uuid)?n[i.uuid]===i.content||i.uuid in t&&t[i.uuid]===i.content||r.push(["set",[i.uuid,i.content]]):i.uuid in t?i.content!==t[i.uuid]&&r.push(["set",[i.uuid,i.content]]):r.push(["new",[i.uuid,this.history.get(-1)[s-1].uuid,i.content]]);for(const t of this.history.get(-2))s.includes(t.uuid)||r.push(["delete",[t.uuid]]);return r}}class L{static setLine(t,e){return{type:"set-line",data:{id:t,content:e}}}static newLine(t,e,n){return{type:"new-line",data:{id:t,previous:e,content:n}}}static deleteLine(t){return{type:"delete-line",data:{id:t}}}static save(t){return{type:"save",data:t}}}class A{constructor(t,e=1,n=null){this.element=t,this.set(e,n),console.log(this)}set(t,e=null){this.type=t,this.setSize(e),console.log(this)}setSize(t){0===this.type?(this.size=t,this.size||(this.size=8),this.element.style.tabSize=this.size+"px"):1===this.type?(this.size=t,this.size||(this.size=4),console.log(this.size,t),this.element.style.tabSize=2*this.size+"px"):(this.size=t,this.element.style.tabSize="inherit")}get(){return 1===this.type?" ".repeat(this.size):0===this.type?"\t":void 0}getCompletion(t){return 1===this.type?" ".repeat(this.size-t%this.size):0===this.type?"\t":void 0}getCompletionSize(t){return 1===this.type?this.size-t%this.size:1}}class N{constructor(t){window.WebSocket?(this.options=t||{},k.debug("Websocket connection to",this.uri()),this.ws=new WebSocket(this.uri().href),this.ws.onmessage=this.onMessage,this.waitingStack=new w(120),document.addEventListener("socket.confirm",(t=>{this.confirm(t.detail)})),setInterval((()=>{const t=this.waitingStack.getSize();t>20?a("Connexion","It seems than you are disconnected",2e3,"#ff501e"):t>5&&a("Connexion","It seems than you are disconnected",2e3,"#ff9000")}),1e3),document.addEventListener("socket.receive.ping",(t=>{this.send(JSON.stringify({event:"pong",time:Date.now()}))}))):k.critical("Browser doesn\t support websockets")}uri(){const t=new URL("ws://localhost");if(t.protocol=this.options.secure?"wss":"ws",t.port=this.port(t.protocol.endsWith(":")?t.protocol.slice(0,-1):t.protocol),t.hostname=this.options.hostname||window.location.origin,t.pathname=void 0!==this.options.pathname?"/"+this.options.pathname||0:"",this.options.params)for(const[e,n]of Object.entries(this.options.params))t.searchParams.set(e,n);return t}port(t){return this.options.port&&("wss"===t&&443!==Number(this.options.port)||"ws"===t&&80!==Number(this.options.port))?this.options.port:""}send(t){if("join"!==t.event){const e=o.string(9);this.waitingStack.add(e,t),k.debug(`SEND ${e} to '${t.event}': `,t),t.uuid=e}this.ws.send(JSON.stringify(t))}onMessage(t){try{const e=JSON.parse(t.data);k.debug("RECEIVE PACKET",e),e.event&&e.data?r.triggerCustom(`socket.receive.${e.event}`,e.data):e.code&&e.uuid&&e.time?r.triggerCustom("socket.confirm",e):k.error("This packet hasn't valid event and data.",e)}catch(e){k.debug(e),k.error("This packet can't be parsed as JSON.",t)}}confirm(t){const e=t.code,n=t.uuid,s=t.time;"OK"!==e&&k.warn(`${n} come back with a non OK code.`);const i=this.waitingStack.archive(n,s);k.debug(`up: ${i.server-i.send}ms, down: ${i.received-i.server}ms`)}}new class{constructor(t,e=1e3){this.doc_id=t,this.ws=new N({secure:"https:"===document.location.protocol,port:window.location.port,hostname:window.location.host.includes(":")?window.location.host.split(":")[0]:window.location.host}),this.stack={UPDATE_EVENT:[]},this.preprocess=[],this.ws.ws.onopen=()=>{this.join(),setInterval((()=>{for(const t of this.preprocess)t[0](...t[1]);this.stack.UPDATE_EVENT.length&&this.send("update",this.stack.UPDATE_EVENT.splice(0,this.stack.UPDATE_EVENT.length))}),e)},document.addEventListener("socket.send",(t=>{t.detail.hasOwnProperty("request")&&this.stack.UPDATE_EVENT.push(t.detail.request),t.detail.hasOwnProperty("requests")&&this.stack.UPDATE_EVENT.push(...t.detail.requests)})),document.addEventListener("socket.send_now",(t=>{this.send(t.detail.name,t.detail.requests)})),document.addEventListener("socket.preprocess",(t=>{const e=t.detail[0];let n=t.detail[1];if(void 0===e)return;void 0===n&&(n=[]);const s=[e,n];this.preprocess.includes(s)||(this.preprocess.push(s),k.debug("New socket.preprocess",s))}))}send(t,e={}){this.ws.send({event:t,room:this.doc_id,data:e})}join(){this.send("join")}}(doc_id),new class{constructor(t){this.editable=t,this.tab=new A(t,1,4),this.linesManager=new T(t),this.last_request={},this.keepSpace=!1,document.addEventListener("socket.receive.update",(t=>{if(t&&t.detail&&t.detail&&"function"==typeof t.detail[Symbol.iterator])for(const e of t.detail)e.type?r.triggerCustom("editor."+e.type,e.data):k.warn("Trying to trigger a null received event.");else k.warn("Trying to iterate on non-iterable data.")})),r.triggerCustom("socket.preprocess",[this.coroutine,[this]]),this.editable.addEventListener("keyup",(t=>{if(!u.isExtra(t.keyCode)){switch(t.keyCode){case 13:try{this.keepSpace=!1;let t=s("uuid"),e=t.previousElementSibling,n=o.string(10);t.setAttribute("uuid",n);let i=e.innerText.search(/\S/);i<0&&(i=0),e.innerText.trimEnd().endsWith(":")&&(i+=this.tab.getCompletionSize(i)),t.innerHTML=" ".repeat(i)+t.innerHTML,m.setPosition(t,i),0===t.innerText.length&&(t.innerHTML="
")}catch(t){k.error("Error when trying to customize the new line")}break;default:t.ctrlKey||t.altKey||S.onCurrent("python").ApplyWithCaret()}this.linesManager.change=!0}})),this.editable.addEventListener("paste",(t=>{const e=document.getSelection();let n=(t.clipboardData||window.clipboardData).getData("text");if(n){const s=n.split("\n");!function(t){return!!i(["div","section"]).hasAttribute("uuid")&&i(["div","section"],e.anchorNode)===i(["div","section"],e.focusNode)&&(1===t.length||e.anchorNode===e.focusNode&&e.anchorOffset===e.focusOffset)}(s)?(t.preventDefault(),k.debug("Prevent action when trying to paste on multiple line."),a("Paste Event","Sorry, you can't past over a multiline selection",5e3)):s.length>1&&(t.preventDefault(),this.multilinesInsert(s))}else t.preventDefault(),k.warn("Error when trying to get the content of your clipboard."),a("Paste Event","Error with content of your clipboard",5e3)})),this.editable.addEventListener("keydown",(t=>{if(u.ctrl(t)&&83===t.keyCode)return t.preventDefault(),void a("Save","Your document is still saved automatically",5e3,"#228b22");if(u.isExtra(t.keyCode))return;const e=document.getSelection(),n=i(["div","section"],e.anchorNode),r=i(["div","section"],e.focusNode),o=s("uuid");if(!o)return t.preventDefault(),void a("Editor","Sorry, your action has been canceled because you are not on any line.",5e3);switch(n.hasAttribute("uuid")&&r.hasAttribute("uuid")&&(0!==m.getBeginPosition(o)&&0!==m.getEndPosition(o)||n===r)||m.setRangeStart(o,1),t.keyCode){case 9:t.preventDefault(),this.insertTab();break;case 13:if(t.shiftKey)return a("Shift+Enter","Please just use Enter to avoid any bugs.",5e3),void t.preventDefault();this.keepSpace?(k.debug("Prevent action when trying to add new line (key is probably maintain)."),t.preventDefault()):this.keepSpace=!0;break;case 8:0===m.getBeginPosition(o)&&(t.preventDefault(),this.removeLine(o))}})),document.addEventListener("editor.set-line",(t=>{const e=t.detail.id,n=t.detail.content;this.last_request[e]=n,this.linesManager.update(e,n)})),document.addEventListener("editor.new-line",(t=>{const e=t.detail.id,n=t.detail.previous,s=t.detail.content;this.last_request[e]=s,this.linesManager.new(e,n,s)})),document.addEventListener("editor.delete-line",(t=>{const e=t.detail.id;e in this.last_request&&delete this.last_request[e],this.linesManager.remove(e)}))}insertTab(){document.getSelection().collapseToStart(),document.getSelection().getRangeAt(0).insertNode(document.createTextNode(this.tab.getCompletion(m.getBeginPosition(s("uuid"))))),document.getSelection().collapseToEnd(),S.onCurrent("python").ApplyWithCaret()}multilinesInsert(t){const e=s("uuid");var n,i,r;e.innerHTML=(n=e.innerText,i=t[0],r=m.getBeginPosition(e),n.slice(0,r)+i+n.slice(r)),S.onCurrent("python").apply();let a=e.getAttribute("uuid");for(let e=1;e{this.update(t)})),document.dispatchEvent(new CustomEvent("socket.preprocess",{detail:[this.sendCursorPosition,[this]]})),this.editor.addEventListener("focus",(()=>{n()!==this.editor&&(this.request=this.cursorRequest())})),this.editor.addEventListener("click",(()=>{n()!==this.editor&&(this.request=this.cursorRequest())})),this.editor.addEventListener("keypress",(()=>{n()!==this.editor&&(this.request=this.cursorRequest())}))}cursorRequest(){let t=s("uuid");for(const e of this.current.entries())if(e[0]!==this.uuid&&e[1][1]===t)return{};return t.hasAttribute("uuid")?{type:"cursor-moves",data:{uuid:t.getAttribute("uuid"),userId:this.uuid,color:this.color}}:{}}sendCursorPosition(t){const e=t.request;t&&Object.keys(e).length>0&&(r.triggerCustom("socket.send",{request:e}),t.request={})}update(n){const s=n.detail;this.current.has(s.userId)&&(this.current.get(s.userId)[0].remove(),this.current.get(s.userId)[1].removeAttribute("contenteditable"),this.current.get(s.userId)[1].classList.remove("noteditable"),this.current.delete(s.userId));const i=document.querySelector('div[uuid="'+s.uuid+'"]');if(null===i)return void(t.isDebug()&&console.log("Cursor position doesn't exist"));const r=document.createElement("div");r.classList.add("pointer"),r.style.top=i.offsetTop+"px",r.style.backgroundColor="rgb("+s.color[0]+", "+s.color[1]+", "+s.color[2]+")",t.isDebug()&&(r.id=o.string(20)),e.id("body").appendChild(r),i.setAttribute("contenteditable","false"),i.classList.add("noteditable"),setTimeout((()=>{this.current.has(s.userId)&&Date.now()-this.current.get(s.userId)[2]>9e3&&(this.current.get(s.userId)[0].remove(),this.current.get(s.userId)[1].removeAttribute("contenteditable"),this.current.get(s.userId)[1].classList.remove("noteditable"),this.current.delete(s.userId))}),1e4),this.current.set(s.userId,[r,i,Date.now()])}}(e.id("editor"));for(const t of e.id("editor").children)new S(t,"python").ApplyWithCaret();var D,x;D=e.id("download"),x=e.id("editor"),D.addEventListener("click",(()=>{const t=x.innerText.replaceAll("\n\n","\n");D.setAttribute("href","data:Content-type, "+escape(t))}))})(); \ No newline at end of file