diff --git a/app/script.js b/app/script.js index 5c242d8..ed68bf5 100644 --- a/app/script.js +++ b/app/script.js @@ -77,4 +77,4 @@ if ( }); } -webpackJsonp([0],{JkW7:function(e,t,n){"use strict";function o(){var e={},t=new Promise(function(t,n){e.resolve=t,e.reject=n});return e.promise=t,V(e,t)}function s(e,t){var n=o();return t===P.HTML?n.resolve({code:e}):t===P.MARKDOWN?n.resolve(window.marked?{code:marked(e)}:{code:e}):t===P.JADE&&n.resolve(window.jade?{code:jade.render(e)}:{code:e}),n.promise}function i(e,t,n){var s,i=o();if(t===D.CSS)i.resolve({code:e});else if(t===D.SCSS||t===D.SASS)window.sass&&e?window.sass.compile(e,{indentedSyntax:t===D.SASS},function(e){e.line&&e.message&&(s={lang:"css",data:[{lineNumber:e.line-1,message:e.message}]}),i.resolve({code:e.text,errors:s})}):i.resolve({code:e});else if(t===D.LESS)less.render(e).then(function(e){i.resolve({code:e.css})},function(e){s={lang:"css",data:[{lineNumber:e.line,message:e.message}]},i.resolve({code:"",errors:s})});else if(t===D.STYLUS)stylus(e).render(function(e,t){if(e){window.err=e;var n=e.message.split("\n");n.pop(),s={lang:"css",data:[{lineNumber:+e.message.match(/stylus:(\d+):/)[1]-298,message:n.pop()}]}}i.resolve({code:t,errors:s})});else if(t===D.ACSS)if(!window.atomizer)i.resolve({code:""});else{const t=atomizer.findClassNames(e);var a;try{a=atomizer.getConfig(t,JSON.parse(n.acssConfig))}catch(n){a=atomizer.getConfig(t,{})}const o=atomizer.getCss(a);i.resolve({code:o})}return i.promise}function a(e,t,n,s){var i,a=o();if(!e)return a.resolve(""),a.promise;if(t===F.JS)try{W.parse(e,{tolerant:!0})}catch(t){i={lang:"js",data:[{lineNumber:t.lineNumber-1,message:t.description}]}}finally{!1!==n&&(e=i?e:h(e,{timeout:s})),a.resolve({code:e,errors:i})}else if(t===F.COFFEESCRIPT){if(!window.CoffeeScript)return a.resolve(""),a.promise;try{e=CoffeeScript.compile(e,{bare:!0})}catch(t){i={lang:"js",data:[{lineNumber:t.location.first_line,message:t.message}]}}finally{!1!==n&&(e=i?e:h(e,{timeout:s})),a.resolve({code:e,errors:i})}}else if(t===F.ES6){if(!window.Babel)return a.resolve(""),a.promise;try{W.parse(e,{tolerant:!0,jsx:!0})}catch(t){i={lang:"js",data:[{lineNumber:t.lineNumber-1,message:t.description}]}}finally{e=Babel.transform(e,{presets:["latest","stage-2","react"]}).code,!1!==n&&(e=i?e:h(e,{timeout:s})),a.resolve({code:e,errors:i})}}else if(t===F.TS)try{if(!window.ts)return a.resolve({code:""}),a.promise;e=ts.transpileModule(e,{reportDiagnostics:!0,compilerOptions:{noEmitOnError:!0,diagnostics:!0,module:ts.ModuleKind.ES2015}}),e.diagnostics.length&&(i={lang:"js",data:[{message:e.diagnostics[0].messageText,lineNumber:ts.getLineOfLocalPosition(e.diagnostics[0].file,e.diagnostics[0].start)-1}]}),e=e.outputText,!1===n||i||(e=h(e,{timeout:s})),a.resolve({code:e,errors:i})}catch(t){}return a.promise}function r(e,t){for(var n=e.split("."),o=t.split("."),s=0;3>s;s++){var i=+n[s],a=+o[s];if(i>a)return 1;if(a>i)return-1;if(!isNaN(i)&&isNaN(a))return 1;if(isNaN(i)&&!isNaN(a))return-1}return 0}function l(e){for(var t="",n=e||10;n--;)t+=U[~~(Math.random()*U.length)];return t}function c(){window.DEBUG&&console.log(Date.now(),...arguments)}function h(e,{timeout:t}){var n=1,o=[],s="_wmloopvar",i=`\nif (Date.now() - %d > ${t}) { window.top.previewException(new Error("Infinite loop")); break;}\n`;return z.parse(e,{tolerant:!0,range:!0,jsx:!0},function(e){switch(e.type){case"DoWhileStatement":case"ForStatement":case"ForInStatement":case"ForOfStatement":case"WhileStatement":var t=1+e.body.range[0],a=e.body.range[1],r=i.replace("%d",s+n),l="";"BlockStatement"!==e.body.type&&(r="{"+r,l="}",--t),o.push({pos:t,str:r}),o.push({pos:a,str:l}),o.push({pos:e.range[0],str:"var %d = Date.now();\n".replace("%d",s+n)}),++n;break;default:}}),o.sort(function(e,t){return t.pos-e.pos}).forEach(function(t){e=e.slice(0,t.pos)+t.str+e.slice(t.pos)}),e}function d(e){var t=new Date(e),n=t.getDate()+" "+["January","February","March","April","May","June","July","August","September","October","November","December"][t.getMonth()]+" "+t.getFullYear();return n}function p(e,t){function n(){var n=document.createElement("a");n.href=window.URL.createObjectURL(t),n.download=e,n.style.display="none",document.body.appendChild(n),n.click(),n.remove()}window.IS_EXTENSION?chrome.downloads.download({url:window.URL.createObjectURL(t),filename:e,saveAs:!0},()=>{chrome.runtime.lastError&&n()}):n()}function u(e,t,n){function o(e){return function(){c(arguments),v("fn","error",e),u.errorCount=(u.errorCount||0)+1,4===u.errorCount&&setTimeout(function(){alert("Oops! Seems like your preview isn't updating. It's recommended to switch to the web app: https://webmakerapp.com/app/.\n\n If you still want to get the extension working, please try the following steps until it fixes:\n - Refresh Web Maker\n - Restart browser\n - Update browser\n - Reinstall Web Maker (don't forget to export all your creations from saved items pane (click the OPEN button) before reinstalling)\n\nIf nothing works, please tweet out to @webmakerApp."),v("ui","writeFileMessageSeen")},1e3)}}var s=!1;window.webkitRequestFileSystem(window.TEMPORARY,5242880,function(i){i.root.getFile(e,{create:!0},function(e){e.createWriter((e)=>{e.onwriteend=function(){return s?n():(s=!0,e.seek(0),e.write(t),!1)},e.truncate(0)},o("createWriterFail"))},o("getFileFail"))},o("webkitRequestFileSystemFail"))}function m(e){var t=o(),n=window.document.getElementsByTagName("script")[0],s=window.document.createElement("script");return s.src=e,s.async=!0,n.parentNode.insertBefore(s,n),s.onload=function(){t.resolve()},t.promise}function g(e,t,n,o,s){if(!o)return"";var i=o.externalLibs.js.split("\n").reduce(function(e,t){return e+(t?"\n":"")},""),a=o.externalLibs.css.split("\n").reduce(function(e,t){return e+(t?"\n":"")},""),r="\n\n\n\n"+a+"\n\n\n\n"+e+"\n"+i+"\n";if(s||(r+=""),o.jsMode===F.ES6&&(r+=""),"string"==typeof n)r+="\n\n",r}function f(e){var t=s(e.html,e.htmlMode),n=i(e.css,e.cssMode),o=a(e.js,e.jsMode,!1);Promise.all([t,n,o]).then(function(t){var n=t[0].code,o=t[1].code,s=t[2].code,i=g(n,o,s,e,!0),a=new Date,r=["web-maker",a.getFullYear(),a.getMonth()+1,a.getDate(),a.getHours(),a.getMinutes(),a.getSeconds()].join("-");e.title&&(r=e.title),r+=".html";var l=new Blob([i],{type:"text/html;charset=UTF-8"});p(r,l),v("fn","saveFileComplete")})}function b(){var e=o();return window.IS_EXTENSION?(chrome.permissions.contains({permissions:["downloads"]},function(t){t?e.resolve():chrome.permissions.request({permissions:["downloads"]},function(t){t?(v("fn","downloadsPermGiven"),e.resolve()):e.reject()})}),e.promise):(e.resolve(),e.promise)}function v(e,t,n,o){return window.DEBUG?void c("trackevent",e,t,n,o):void(window.ga&&ga("send","event",e,t,n,o))}function C(e,t){var n={};for(var o in e)0<=t.indexOf(o)||Object.prototype.hasOwnProperty.call(e,o)&&(n[o]=e[o]);return n}function y(e){return Object(O.h)(q,K({Tag:"a"},e))}function S(e){return Object(O.h)("div",{class:"main-header"},Object(O.h)("input",{type:"text",id:"titleInput",title:"Click to edit",class:"item-title-input",value:e.title,onBlur:e.titleInputBlurHandler}),Object(O.h)("div",{class:"main-header__btn-wrap flex flex-v-center"},Object(O.h)("a",{id:"runBtn",class:"hide flex flex-v-center hint--rounded hint--bottom-left","aria-label":"Run preview (Ctrl/\u2318 + Shift + 5)",onClick:e.runBtnClickHandler},Y,"Run"),Object(O.h)(y,{onClick:e.addLibraryBtnHandler,"data-event-category":"ui","data-event-action":"addLibraryButtonClick",class:"flex-v-center hint--rounded hint--bottom-left","aria-label":"Add a JS/CSS library"},"Add library"," ",Object(O.h)("span",{id:"js-external-lib-count",style:`display:${e.externalLibCount?"inline":"none"}`,class:"count-label"},e.externalLibCount)),Object(O.h)("a",{class:"flex flex-v-center hint--rounded hint--bottom-left","aria-label":"Start a new creation",onClick:e.newBtnHandler},G,"New"),Object(O.h)("a",{id:"saveBtn",class:`flex flex-v-center hint--rounded hint--bottom-left ${e.isSaving?"is-loading":""} ${e.unsavedEditCount?"is-marked":0}`,"aria-label":"Save current creation (Ctrl/\u2318 + S)",onClick:e.saveBtnHandler},Z,X,"Save"),Object(O.h)("a",{id:"openItemsBtn",class:`flex flex-v-center hint--rounded hint--bottom-left ${e.isFetchingItems?"is-loading":""}`,"aria-label":"Open a saved creation (Ctrl/\u2318 + O)",onClick:e.openBtnHandler},Q,ee,"Open"),Object(O.h)(y,{onClick:e.loginBtnHandler,"data-event-category":"ui","data-event-action":"loginButtonClick",class:"hide-on-login flex flex-v-center hint--rounded hint--bottom-left","aria-label":"Login/Signup"},"Login/Signup"),Object(O.h)(y,{onClick:e.profileBtnHandler,"data-event-category":"ui","data-event-action":"headerAvatarClick","aria-label":"See profile or Logout",class:"hide-on-logout hint--rounded hint--bottom-left"},Object(O.h)("img",{id:"headerAvatarImg",width:"20",src:e.user?e.user.photoURL||J:"",class:"main-header__avatar-img"}))))}function w(e,t){var n=t;return function(){0==--n&&e()}}function k(e,t){var n=ne.a.modes[e].dependencies;if(!n)return t();for(var o=[],s=0;s{e.root.getFile(d,{create:!0},(e)=>{e.createWriter((e)=>{e.onwriteend=t,e.write(i)},n)},n)},n)}function A(e){b().then(()=>{function t(n){var o=document.createElement("canvas"),s=e;o.width=s.width,o.height=s.height;var i=o.getContext("2d"),a=window.devicePixelRatio||1;i.drawImage(n,s.left*a,s.top*a,s.width*a,s.height*a,0,0,s.width,s.height),n.removeEventListener("load",t),H(o.toDataURL())}var n=document.createElement("style");n.textContent="[class*=\"hint\"]:after, [class*=\"hint\"]:before { display: none!important; }",document.body.appendChild(n),setTimeout(()=>{chrome.tabs.captureVisibleTab(null,{format:"png",quality:100},function(e){if(n.remove(),e){var o=new Image;o.src=e,o.addEventListener("load",()=>t(o,e))}})},50),v("ui","takeScreenshotBtnClick")})}function j({show:e,closeHandler:t,oldSavedCreationsCount:n,dontAskBtnClickHandler:o,importBtnClickHandler:s}){return Object(O.h)(gt,{extraClasses:"ask-to-import-modal",show:e,closeHandler:t},Lo,Object(O.h)("div",null,Object(O.h)("p",null,"You have ",Object(O.h)("span",null,n)," creations saved in your local machine. Do you want to import those creations in your account so they are more secure and accessible anywhere?"),Io,Object(O.h)("div",{class:"flex flex-h-end"},Object(O.h)("button",{onClick:o,class:"btn"},"Don't ask me again"),Object(O.h)("button",{onClick:s,class:"btn btn--primary ml-1"},"Yes, please import"))))}function B(e){return Object(O.h)(gt,{show:e.show,closeHandler:e.closeHandler},jo,Bo)}function E(e){return Object(O.h)(gt,{show:e.show,closeHandler:e.closeHandler},Eo,Oo,To,Vo)}Object.defineProperty(t,"__esModule",{value:!0});var O=n("KM04"),T=n.n(O),V=Object.assign||function(e){for(var t,n=1;n{}},window.$all=(e)=>[...document.querySelectorAll(e)],window.IS_EXTENSION=!!window.chrome.extension;const R=window.chrome.extension||window.DEBUG?"/":"/app";var U="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";Node.prototype.nextUntil=function(e){const t=Array.from(this.parentNode.querySelectorAll(e)),n=t.indexOf(this);return t[n+1]},Node.prototype.previousUntil=function(e){const t=Array.from(this.parentNode.querySelectorAll(e)),n=t.indexOf(this);return t[n-1]},window.requestIdleCallback=window.requestIdleCallback||function(e){setTimeout(e,10)},window.IS_EXTENSION?document.body.classList.add("is-extension"):document.body.classList.add("is-app"),!1;var K=Object.assign||function(e){for(var t,n=1;n{"function"==typeof this.props.onFocus&&this.props.onFocus(e)}),this.cm.on("change",this.props.onChange),this.cm.addKeyMap({"Ctrl-Space":"autocomplete"}),e.noAutocomplete||this.cm.on("inputRead",(e,t)=>{this.props.autoComplete&&"+input"===t.origin&&";"!==t.text[0]&&","!==t.text[0]&&" "!==t.text[0]&&se.commands.autocomplete(this.cm,null,{completeSingle:!1})}),this.props.onCreation(this.cm)}render(){return Object(O.h)("textarea",{ref:(e)=>this.textarea=e,name:"",id:"",cols:"30",rows:"10"})}};var dt=n("mSND"),ct=n.n(dt);let ht=class extends O.Component{componentDidMount(){this.updateSplit()}componentWillUpdate(){this.splitInstance&&this.splitInstance.destroy()}componentDidUpdate(){this.updateSplit()}updateSplit(){const e={direction:this.props.direction,minSize:this.props.minSize,gutterSize:6,sizes:this.props.sizes};this.props.onDragEnd&&(e.onDragEnd=this.props.onDragEnd),this.props.onDragStart&&(e.onDragStart=this.props.onDragStart),this.splitInstance=ct()(this.props.children.map((e)=>"#"+e.attributes.id),e),this.props.onSplit&&this.props.onSplit(this.splitInstance)}render(){const e=this.props,{children:t}=e,n=x(e,["children"]);return Object(O.h)("div",n,this.props.children)}},pt=class extends O.Component{componentDidMount(){this.initEditor()}shouldComponentUpdate(){return!1}initEditor(){this.cm=se.fromTextArea(this.textarea,this.props.options),this.props.onChange&&this.cm.on("change",this.props.onChange),this.props.onBlur&&this.cm.on("blur",this.props.onBlur),this.props.onCreation(this.cm)}render(){return Object(O.h)("textarea",{ref:(e)=>this.textarea=e,name:"",id:"",cols:"30",rows:"10"})}};var ut=n("q6qL"),mt=n.n(ut);let gt=class extends O.Component{componentDidMount(){window.addEventListener("keydown",this.onKeyDownHandler.bind(this))}componentWillUnmount(){window.removeEventListener("keydown",this.onKeyDownHandler.bind(this))}onKeyDownHandler(t){27===t.keyCode&&this.props.closeHandler()}onOverlayClick(t){t.target===this.overlayEl&&this.props.closeHandler()}componentDidUpdate(e){this.props.show!==e.show&&(document.body.classList[this.props.show?"add":"remove"]("overlay-visible"),this.props.show&&setTimeout(()=>{this.overlayEl.querySelector(".js-modal__close-btn").focus()},0))}render(){return this.props.show?Object(O.h)(mt.a,{into:"body"},Object(O.h)("div",{class:`${this.props.extraClasses||""} modal is-modal-visible`,ref:(e)=>this.overlayEl=e,onClick:this.onOverlayClick.bind(this)},Object(O.h)("div",{class:"modal__content"},Object(O.h)("button",{type:"button",onClick:this.props.closeHandler,"aria-label":"Close modal",title:"Close",class:"js-modal__close-btn modal__close-btn"},"Close"),this.props.children))):null}};var ft=Object(O.h)("h1",null,"Atomic CSS Settings"),bt=Object(O.h)("h3",null,"Configure Atomizer settings."," ",Object(O.h)("a",{href:"https://github.com/acss-io/atomizer#api",target:"_blank",rel:"noopener noreferrer"},"Read more")," ","about available settings.");let vt=class extends O.Component{componentDidUpdate(){this.props.show&&setTimeout(()=>{this.props.settings&&this.cm.setValue(this.props.settings.acssConfig),this.cm.refresh(),this.cm.focus()},500)}render(){return Object(O.h)(gt,{show:this.props.show,closeHandler:this.props.closeHandler},ft,bt,Object(O.h)("div",{style:"height: calc(100vh - 350px);"},Object(O.h)(pt,{options:{mode:"application/ld+json",theme:this.props.editorTheme},onCreation:(e)=>this.cm=e,onBlur:(e)=>this.props.onChange(e.getValue())})),Object(O.h)("div",{class:"flex flex-h-end"},Object(O.h)("button",{class:"btn btn--primary",onClick:this.props.closeHandler},"Apply and Close")))}};const Ct=33;var yt=Object(O.h)("span",{class:"caret"}),St=Object(O.h)("option",{value:"html"},"HTML"),wt=Object(O.h)("option",{value:"markdown"},"Markdown"),kt=Object(O.h)("option",{value:"jade"},"Pug"),xt=Object(O.h)("span",{class:"caret"}),Mt=Object(O.h)("option",{value:"css"},"CSS"),_t=Object(O.h)("option",{value:"scss"},"SCSS"),Lt=Object(O.h)("option",{value:"sass"},"SASS"),It=Object(O.h)("option",{value:"less"},"LESS"),Ht=Object(O.h)("option",{value:"stylus"},"Stylus"),At=Object(O.h)("option",{value:"acss"},"Atomic CSS"),jt=Object(O.h)("svg",null,Object(O.h)("use",{xlinkHref:"#settings-icon"})),Bt=Object(O.h)("span",{class:"caret"}),Et=Object(O.h)("option",{value:"js"},"JS"),Ot=Object(O.h)("option",{value:"coffee"},"CoffeeScript"),Tt=Object(O.h)("option",{value:"es6"},"ES6 (Babel)"),Vt=Object(O.h)("option",{value:"typescript"},"TypeScript"),Pt=Object(O.h)("span",{class:"code-wrap__header-label"},"Console (",Object(O.h)("span",{id:"logCountEl"},"0"),")"),Dt=Object(O.h)("svg",null,Object(O.h)("use",{xlinkHref:"#cancel-icon"})),Ft=Object(O.h)("svg",{width:"18",height:"18",fill:"#346fd2"},Object(O.h)("use",{xlinkHref:"#chevron-icon"}));let Nt=class extends O.Component{constructor(e){super(e),this.state={isConsoleOpen:!1,isCssSettingsModalOpen:!1},this.updateTimer=null,this.updateDelay=500,this.htmlMode=P.HTML,this.jsMode=P.HTML,this.cssMode=D.CSS,this.jsMode=F.JS,this.prefs={},this.codeInPreview={html:null,css:null,js:null},this.cmCodes={html:e.currentItem.html,css:"",js:""},this.cm={},this.logCount=0,window.onMessageFromConsole=this.onMessageFromConsole.bind(this),window.previewException=this.previewException.bind(this),window.clearConsole=this.clearConsole.bind(this)}shouldComponentUpdate(e,t){return this.state.isConsoleOpen!==t.isConsoleOpen||this.state.isCssSettingsModalOpen!==t.isCssSettingsModalOpen||this.state.codeSplitSizes!==t.codeSplitSizes||this.state.mainSplitSizes!==t.mainSplitSizes||this.props.currentLayoutMode!==e.currentLayoutMode||this.props.currentItem!==e.currentItem}componentDidUpdate(){window.logCountEl.textContent=this.logCount}componentDidMount(){this.props.onRef(this)}onHtmlCodeChange(e,t){this.cmCodes.html=e.getValue(),this.props.onCodeChange("html",this.cmCodes.html,"setValue"!==t.origin),this.onCodeChange(e,t)}onCssCodeChange(e,t){this.cmCodes.css=e.getValue(),this.props.onCodeChange("css",this.cmCodes.css,"setValue"!==t.origin),this.onCodeChange(e,t)}onJsCodeChange(e,t){this.cmCodes.js=e.getValue(),this.props.onCodeChange("js",this.cmCodes.js,"setValue"!==t.origin),this.onCodeChange(e,t)}onCodeChange(e,t){clearTimeout(this.updateTimer),this.updateTimer=setTimeout(()=>{"setValue"!==t.origin&&(!1!==this.prefs.autoPreview&&this.setPreviewContent(),v.previewCount=(v.previewCount||0)+1,4===v.previewCount&&v("fn","usingPreview"))},this.updateDelay)}createPreviewFile(e,t,n){const o=!window.webkitRequestFileSystem||!window.IS_EXTENSION;var s=g(e,t,o?n:null,this.props.currentItem),i=new Blob([s],{type:"text/plain;charset=UTF-8"}),a=new Blob([n],{type:"text/plain;charset=UTF-8"});!v.hasTrackedCode&&(e||t||n)&&(v("fn","hasCode"),v.hasTrackedCode=!0),o?this.detachedWindow?(c("\u2709\uFE0F Sending message to detached window"),this.detachedWindow.postMessage({contents:s},"*")):(this.frame.src=this.frame.src,setTimeout(()=>{this.frame.contentDocument.open(),this.frame.contentDocument.write(s),this.frame.contentDocument.close()},10)):u("script.js",a,()=>{u("preview.html",i,()=>{var e=chrome.i18n.getMessage()?`chrome-extension://${chrome.i18n.getMessage("@@extension_id")}`:`${location.origin}`,t=`filesystem:${e}/temporary/preview.html`;this.detachedWindow?this.detachedWindow.postMessage(t,"*"):this.frame.src=t})})}cleanupErrors(e){this.cm[e].clearGutter("error-gutter")}showErrors(e,t){var o=this.cm[e];t.forEach(function(t){o.operation(function(){var e=document.createElement("div");e.setAttribute("data-title",t.message),e.classList.add("gutter-error-marker"),o.setGutterMarker(t.lineNumber,"error-gutter",e)})})}setPreviewContent(e,t){if(!this.props.prefs.autoPreview&&!t)return;this.props.prefs.preserveConsoleLogs||this.clearConsole(),this.cleanupErrors("html"),this.cleanupErrors("css"),this.cleanupErrors("js");var n={html:this.cmCodes.html,css:this.cmCodes.css,js:this.cmCodes.js};c("\uD83D\uDD0E setPreviewContent",e);const o=this.detachedWindow?this.detachedWindow.document.querySelector("iframe"):this.frame,r=this.props.currentItem.cssMode;if(!e&&n.html===this.codeInPreview.html&&n.js===this.codeInPreview.js)i(r===D.ACSS?n.html:n.css,r,this.props.currentItem.cssSettings).then((e)=>{r===D.ACSS&&this.cm.css.setValue(e.code||""),o.contentDocument.querySelector("#webmakerstyle")&&(o.contentDocument.querySelector("#webmakerstyle").textContent=e.code||"")});else{var l=s(n.html,this.props.currentItem.htmlMode),d=i(r===D.ACSS?n.html:n.css,r,this.props.currentItem.cssSettings),h=a(n.js,this.props.currentItem.jsMode,!0,this.props.prefs.infiniteLoopTimeout);Promise.all([l,d,h]).then((e)=>{r===D.ACSS&&this.cm.css.setValue(e[1].code||""),this.createPreviewFile(e[0].code||"",e[1].code||"",e[2].code||""),e.forEach((e)=>{e.errors&&this.showErrors(e.errors.lang,e.errors.data)})})}this.codeInPreview.html=n.html,this.codeInPreview.css=n.css,this.codeInPreview.js=n.js}isValidItem(e){return!!e.title}refreshEditor(){this.cmCodes.html=this.props.currentItem.html,this.cmCodes.css=this.props.currentItem.css,this.cmCodes.js=this.props.currentItem.js,this.cm.html.setValue(this.cmCodes.html||""),this.cm.css.setValue(this.cmCodes.css||""),this.cm.js.setValue(this.cmCodes.js||""),this.cm.html.refresh(),this.cm.css.refresh(),this.cm.js.refresh(),this.clearConsole(),Promise.all([this.updateHtmlMode(this.props.currentItem.htmlMode),this.updateCssMode(this.props.currentItem.cssMode),this.updateJsMode(this.props.currentItem.jsMode)]).then(()=>this.setPreviewContent(!0))}applyCodemirrorSettings(e){this.cm&&(htmlCodeEl.querySelector(".CodeMirror").style.fontSize=cssCodeEl.querySelector(".CodeMirror").style.fontSize=jsCodeEl.querySelector(".CodeMirror").style.fontSize=`${parseInt(e.fontSize,10)}px`,window.consoleEl.querySelector(".CodeMirror").style.fontSize=`${parseInt(e.fontSize,10)}px`,window.editorThemeLinkTag.href=`lib/codemirror/theme/${e.editorTheme}.css`,window.fontStyleTag.textContent=window.fontStyleTemplate.textContent.replace(/fontname/g,("other"===e.editorFont?e.editorCustomFont:e.editorFont)||"FiraCode"),this.consoleCm.setOption("theme",e.editorTheme),["html","js","css"].forEach((t)=>{this.cm[t].setOption("indentWithTabs","spaces"!==e.indentWith),this.cm[t].setOption("blastCode",!!e.isCodeBlastOn&&{effect:2,shake:!1}),this.cm[t].setOption("indentUnit",+e.indentSize),this.cm[t].setOption("tabSize",+e.indentSize),this.cm[t].setOption("theme",e.editorTheme),this.cm[t].setOption("keyMap",e.keymap),this.cm[t].setOption("lineWrapping",e.lineWrap),this.cm[t].refresh()}))}updateCodeWrapCollapseStates(){clearTimeout(this.updateCodeWrapCollapseStates.timeout),this.updateCodeWrapCollapseStates.timeout=setTimeout(()=>{const{currentLayoutMode:e}=this.props,t=2===e||5===e?"width":"height";[htmlCodeEl,cssCodeEl,jsCodeEl].forEach(function(e){const n=e.getBoundingClientRect(),o=n[t];100>o?e.classList.add("is-minimized"):e.classList.remove("is-minimized"),-1===e.style[t].indexOf(`100% - ${2*Ct}px`)?e.classList.remove("is-maximized"):e.classList.add("is-maximized")})},50)}toggleCodeWrapCollapse(e){if(e.classList.contains("is-minimized")||e.classList.contains("is-maximized"))e.classList.remove("is-minimized"),e.classList.remove("is-maximized"),this.codeSplitInstance.setSizes([33.3,33.3,33.3]);else{const n=parseInt(e.dataset.codeWrapId,10);var t=[`${Ct}px`,`${Ct}px`,`${Ct}px`];t[n]=`calc(100% - ${2*Ct}px)`,this.codeSplitInstance.setSizes(t),e.classList.add("is-maximized")}}collapseBtnHandler(t){var e=t.currentTarget.parentElement.parentElement.parentElement;this.toggleCodeWrapCollapse(e),v("ui","paneCollapseBtnClick",e.dataset.type)}codeWrapHeaderDblClickHandler(t){if(t.target.classList.contains("js-code-wrap__header")){const e=t.target.parentElement;this.toggleCodeWrapCollapse(e),v("ui","paneHeaderDblClick",e.dataset.type)}}resetSplitting(){this.setState({codeSplitSizes:this.getCodeSplitSizes(),mainSplitSizes:this.getMainSplitSizesToApply()})}getMainSplitSizesToApply(){var e;const{currentItem:t,currentLayoutMode:n}=this.props;return e=t&&t.mainSizes?3===n?[t.mainSizes[1],t.mainSizes[0]]:t.mainSizes:5===n?[75,25]:[50,50],e}getCodeSplitSizes(){return this.props.currentItem&&this.props.currentItem.sizes?this.props.currentItem.sizes:[33.33,33.33,33.33]}mainSplitDragEndHandler(){this.props.prefs.refreshOnResize&&setTimeout(()=>{this.setPreviewContent(!0)},1)}codeSplitDragStart(){document.body.classList.add("is-dragging")}codeSplitDragEnd(){this.updateCodeWrapCollapseStates(),document.body.classList.remove("is-dragging")}handleModeRequirements(e){function t(){N[e].hasLoaded=!0,s.resolve()}const n="lib/transpilers";var s=o();return N[e].hasLoaded?(s.resolve(),s.promise):(e===P.JADE?m(`${n}/jade.js`).then(t):e===P.MARKDOWN?m(`${n}/marked.js`).then(t):e===D.LESS?m(`${n}/less.min.js`).then(t):e===D.SCSS||e===D.SASS?m(`${n}/sass.js`).then(function(){window.sass=new Sass(`${n}/sass.worker.js`),t()}):e===D.STYLUS?m(`${n}/stylus.min.js`).then(t):e===D.ACSS?m(`${n}/atomizer.browser.js`).then(t):e===F.COFFEESCRIPT?m(`${n}/coffee-script.js`).then(t):e===F.ES6?m(`${n}/babel.min.js`).then(t):e===F.TS?m(`${n}/typescript.js`).then(t):s.resolve(),s.promise)}updateHtmlMode(e){return this.props.onCodeModeChange("html",e),this.props.currentItem.htmlMode=e,this.cm.html.setOption("mode",N[e].cmMode),se.autoLoadMode(this.cm.html,N[e].cmPath||N[e].cmMode),this.handleModeRequirements(e)}updateCssMode(e){return this.props.onCodeModeChange("css",e),this.props.currentItem.cssMode=e,this.cm.css.setOption("mode",N[e].cmMode),this.cm.css.setOption("readOnly",N[e].cmDisable),window.cssSettingsBtn.classList[N[e].hasSettings?"remove":"add"]("hide"),se.autoLoadMode(this.cm.css,N[e].cmPath||N[e].cmMode),this.handleModeRequirements(e)}updateJsMode(e){return this.props.onCodeModeChange("js",e),this.props.currentItem.jsMode=e,this.cm.js.setOption("mode",N[e].cmMode),se.autoLoadMode(this.cm.js,N[e].cmPath||N[e].cmMode),this.handleModeRequirements(e)}codeModeChangeHandler(t){var e=t.target.value,n=t.target.dataset.type,o=this.props.currentItem["html"===n?"htmlMode":"css"===n?"cssMode":"jsMode"];o!==e&&("html"===n?this.updateHtmlMode(e).then(()=>this.setPreviewContent(!0)):"js"===n?this.updateJsMode(e).then(()=>this.setPreviewContent(!0)):"css"===n&&this.updateCssMode(e).then(()=>this.setPreviewContent(!0)),v("ui","updateCodeMode",e))}detachPreview(){if(this.detachedWindow)return void this.detachedWindow.focus();const e=this.frame.getBoundingClientRect(),t=e.width,n=e.height;document.body.classList.add("is-detached-mode"),window.globalConsoleContainerEl.insertBefore(window.consoleEl,null),this.detachedWindow=window.open("./preview.html","Web Maker",`width=${t},height=${n},resizable,scrollbars=yes,status=1`),setTimeout(()=>{this.setPreviewContent(!0)},1500);var o=window.setInterval(function(){this.detachedWindow&&this.detachedWindow.closed&&(clearInterval(o),document.body.classList.remove("is-detached-mode"),$("#js-demo-side").insertBefore(window.consoleEl,null),this.detachedWindow=null,this.setPreviewContent(!0))}.bind(this),500)}onMessageFromConsole(){[...arguments].forEach((e)=>{e&&e.indexOf&&-1!==e.indexOf("filesystem:chrome-extension")&&(e=e.replace(/filesystem:chrome-extension.*\.js:(\d+):*(\d*)/g,"script $1:$2"));try{this.consoleCm.replaceRange(e+" "+((e+"").match(/\[object \w+]/)?JSON.stringify(e):"")+"\n",{line:Infinity})}catch(t){this.consoleCm.replaceRange("\uD83C\uDF00\n",{line:Infinity})}this.consoleCm.scrollTo(0,Infinity),this.logCount++}),logCountEl.textContent=this.logCount}previewException(e){console.error("Possible infinite loop detected.",e.stack),this.onMessageFromConsole("Possible infinite loop detected.",e.stack)}toggleConsole(){this.setState({isConsoleOpen:!this.state.isConsoleOpen}),v("ui","consoleToggle")}consoleHeaderDblClickHandler(t){t.target.classList.contains("js-console__header")&&(v("ui","consoleToggleDblClick"),this.toggleConsole())}clearConsole(){this.consoleCm.setValue(""),this.logCount=0,window.logCountEl.textContent=this.logCount}clearConsoleBtnClickHandler(){this.clearConsole(),v("ui","consoleClearBtnClick")}evalConsoleExpr(t){(76===t.which||12===t.which)&&t.ctrlKey?(this.clearConsole(),v("ui","consoleClearKeyboardShortcut")):13===t.which&&(this.onMessageFromConsole("> "+t.target.value),this.frame.contentWindow._wmEvaluate(t.target.value),t.target.value="",v("fn","evalConsoleExpr"))}cssSettingsBtnClickHandler(){this.setState({isCssSettingsModalOpen:!0}),v("ui","cssSettingsBtnClick")}cssSettingsChangeHandler(e){this.props.onCodeSettingsChange("css",e),this.setPreviewContent(!0)}getDemoFrame(e){e(this.frame)}editorFocusHandler(e){this.props.onEditorFocus(e)}render(){return Object(O.h)(ht,{class:"content-wrap flex flex-grow",sizes:this.state.mainSplitSizes,minSize:150,style:"",direction:2===this.props.currentLayoutMode?"vertical":"horizontal",onDragEnd:this.mainSplitDragEndHandler.bind(this)},Object(O.h)(ht,{class:"code-side",id:"js-code-side",sizes:this.state.codeSplitSizes,minSize:Ct,direction:2===this.props.currentLayoutMode||5===this.props.currentLayoutMode?"horizontal":"vertical",onDragStart:this.codeSplitDragStart.bind(this),onDragEnd:this.codeSplitDragEnd.bind(this),onSplit:(e)=>this.codeSplitInstance=e},Object(O.h)("div",{"data-code-wrap-id":"0",id:"htmlCodeEl","data-type":"html",class:"code-wrap",onTransitionEnd:this.updateCodeWrapCollapseStates.bind(this)},Object(O.h)("div",{class:"js-code-wrap__header code-wrap__header",title:"Double click to toggle code pane",onDblClick:this.codeWrapHeaderDblClickHandler.bind(this)},Object(O.h)("label",{class:"btn-group",dropdow:!0,title:"Click to change"},Object(O.h)("span",{class:"code-wrap__header-label"},N[this.props.currentItem.htmlMode||"html"].label),yt,Object(O.h)("select",{"data-type":"html",class:"js-mode-select hidden-select",onChange:this.codeModeChangeHandler.bind(this),value:this.props.currentItem.htmlMode},St,wt,kt)),Object(O.h)("div",{class:"code-wrap__header-right-options"},Object(O.h)("a",{class:"js-code-collapse-btn code-wrap__header-btn code-wrap__collapse-btn",title:"Toggle code pane",onClick:this.collapseBtnHandler.bind(this)}))),Object(O.h)(lt,{options:{mode:"htmlmixed",profile:"xhtml",gutters:["CodeMirror-linenumbers","CodeMirror-foldgutter"],noAutocomplete:!0,matchTags:{bothTags:!0},emmet:!0},onChange:this.onHtmlCodeChange.bind(this),onCreation:(e)=>this.cm.html=e,onFocus:this.editorFocusHandler.bind(this)})),Object(O.h)("div",{"data-code-wrap-id":"1",id:"cssCodeEl","data-type":"css",class:"code-wrap",onTransitionEnd:this.updateCodeWrapCollapseStates.bind(this)},Object(O.h)("div",{class:"js-code-wrap__header code-wrap__header",title:"Double click to toggle code pane",onDblClick:this.codeWrapHeaderDblClickHandler.bind(this)},Object(O.h)("label",{class:"btn-group",title:"Click to change"},Object(O.h)("span",{class:"code-wrap__header-label"},N[this.props.currentItem.cssMode||"css"].label),xt,Object(O.h)("select",{"data-type":"css",class:"js-mode-select hidden-select",onChange:this.codeModeChangeHandler.bind(this),value:this.props.currentItem.cssMode},Mt,_t,Lt,It,Ht,At)),Object(O.h)("div",{class:"code-wrap__header-right-options"},Object(O.h)("a",{href:"#",id:"cssSettingsBtn",title:"Atomic CSS configuration",onClick:this.cssSettingsBtnClickHandler.bind(this),class:"code-wrap__header-btn hide"},jt),Object(O.h)("a",{class:"js-code-collapse-btn code-wrap__header-btn code-wrap__collapse-btn",title:"Toggle code pane",onClick:this.collapseBtnHandler.bind(this)}))),Object(O.h)(lt,{options:{mode:"css",gutters:["error-gutter","CodeMirror-linenumbers","CodeMirror-foldgutter"],emmet:!0},onChange:this.onCssCodeChange.bind(this),onCreation:(e)=>this.cm.css=e,onFocus:this.editorFocusHandler.bind(this)})),Object(O.h)("div",{"data-code-wrap-id":"2",id:"jsCodeEl","data-type":"js",class:"code-wrap",onTransitionEnd:this.updateCodeWrapCollapseStates.bind(this)},Object(O.h)("div",{class:"js-code-wrap__header code-wrap__header",title:"Double click to toggle code pane",onDblClick:this.codeWrapHeaderDblClickHandler.bind(this)},Object(O.h)("label",{class:"btn-group",title:"Click to change"},Object(O.h)("span",{class:"code-wrap__header-label"},N[this.props.currentItem.jsMode||"js"].label),Bt,Object(O.h)("select",{"data-type":"js",class:"js-mode-select hidden-select",onChange:this.codeModeChangeHandler.bind(this),value:this.props.currentItem.jsMode},Et,Ot,Tt,Vt)),Object(O.h)("div",{class:"code-wrap__header-right-options"},Object(O.h)("a",{class:"js-code-collapse-btn code-wrap__header-btn code-wrap__collapse-btn",title:"Toggle code pane",onClick:this.collapseBtnHandler.bind(this)}))),Object(O.h)(lt,{options:{mode:"javascript",gutters:["error-gutter","CodeMirror-linenumbers","CodeMirror-foldgutter"]},autoComplete:this.props.prefs.autoComplete,onChange:this.onJsCodeChange.bind(this),onCreation:(e)=>this.cm.js=e,onFocus:this.editorFocusHandler.bind(this)}))),Object(O.h)("div",{class:"demo-side",id:"js-demo-side",style:""},Object(O.h)("iframe",{ref:(e)=>this.frame=e,src:"about://blank",frameborder:"0",id:"demo-frame",allowfullscreen:!0}),Object(O.h)("div",{id:"consoleEl",class:`console ${this.state.isConsoleOpen?"":"is-minimized"}`},Object(O.h)("div",{id:"consoleLogEl",class:"console__log"},Object(O.h)("div",{class:"js-console__header code-wrap__header",title:"Double click to toggle console",onDblClick:this.toggleConsole.bind(this)},Pt,Object(O.h)("div",{class:"code-wrap__header-right-options"},Object(O.h)("a",{class:"code-wrap__header-btn",title:"Clear console (CTRL + L)",onClick:this.clearConsoleBtnClickHandler.bind(this)},Dt),Object(O.h)("a",{class:"code-wrap__header-btn code-wrap__collapse-btn",title:"Toggle console",onClick:this.toggleConsole.bind(this)}))),Object(O.h)(pt,{options:{mode:"javascript",lineWrapping:!0,theme:"monokai",foldGutter:!0,readOnly:!0,gutters:["CodeMirror-foldgutter"]},onCreation:(e)=>this.consoleCm=e})),Object(O.h)("div",{id:"consolePromptEl",class:"console__prompt flex flex-v-center"},Ft,Object(O.h)("input",{onKeyUp:this.evalConsoleExpr.bind(this),class:"console-exec-input"}))),Object(O.h)(vt,{show:this.state.isCssSettingsModalOpen,closeHandler:()=>this.setState({isCssSettingsModalOpen:!1}),onChange:this.cssSettingsChangeHandler.bind(this),settings:this.props.currentItem.cssSettings,editorTheme:this.props.prefs.editorTheme})))}};var Wt=Object(O.h)("svg",{viewBox:"0 0 24 24"},Object(O.h)("path",{d:"M5,20H19V18H5M19,9H15V3H9V9H5L12,16L19,9Z"})),zt=Object(O.h)("svg",{style:"display: none;",xmlns:"http://www.w3.org/2000/svg"},Object(O.h)("symbol",{id:"codepen-logo",viewBox:"0 0 120 120"},Object(O.h)("path",{class:"outer-ring",d:"M60.048 0C26.884 0 0 26.9 0 60.048s26.884 60 60 60.047c33.163 0 60.047-26.883 60.047-60.047 S93.211 0 60 0z M60.048 110.233c-27.673 0-50.186-22.514-50.186-50.186S32.375 9.9 60 9.9 c27.672 0 50.2 22.5 50.2 50.186S87.72 110.2 60 110.233z"}),Object(O.h)("path",{class:"inner-box",d:"M97.147 48.319c-0.007-0.047-0.019-0.092-0.026-0.139c-0.016-0.09-0.032-0.18-0.056-0.268 c-0.014-0.053-0.033-0.104-0.05-0.154c-0.025-0.078-0.051-0.156-0.082-0.232c-0.021-0.053-0.047-0.105-0.071-0.156 c-0.033-0.072-0.068-0.143-0.108-0.211c-0.029-0.051-0.061-0.1-0.091-0.148c-0.043-0.066-0.087-0.131-0.135-0.193 c-0.035-0.047-0.072-0.094-0.109-0.139c-0.051-0.059-0.104-0.117-0.159-0.172c-0.042-0.043-0.083-0.086-0.127-0.125 c-0.059-0.053-0.119-0.104-0.181-0.152c-0.048-0.037-0.095-0.074-0.145-0.109c-0.019-0.012-0.035-0.027-0.053-0.039L61.817 23.5 c-1.072-0.715-2.468-0.715-3.54 0L24.34 46.081c-0.018 0.012-0.034 0.027-0.053 0.039c-0.05 0.035-0.097 0.072-0.144 0.1 c-0.062 0.049-0.123 0.1-0.181 0.152c-0.045 0.039-0.086 0.082-0.128 0.125c-0.056 0.055-0.108 0.113-0.158 0.2 c-0.038 0.045-0.075 0.092-0.11 0.139c-0.047 0.062-0.092 0.127-0.134 0.193c-0.032 0.049-0.062 0.098-0.092 0.1 c-0.039 0.068-0.074 0.139-0.108 0.211c-0.024 0.051-0.05 0.104-0.071 0.156c-0.031 0.076-0.057 0.154-0.082 0.2 c-0.017 0.051-0.035 0.102-0.05 0.154c-0.023 0.088-0.039 0.178-0.056 0.268c-0.008 0.047-0.02 0.092-0.025 0.1 c-0.019 0.137-0.029 0.275-0.029 0.416V71.36c0 0.1 0 0.3 0 0.418c0.006 0 0 0.1 0 0.1 c0.017 0.1 0 0.2 0.1 0.268c0.015 0.1 0 0.1 0.1 0.154c0.025 0.1 0.1 0.2 0.1 0.2 c0.021 0.1 0 0.1 0.1 0.154c0.034 0.1 0.1 0.1 0.1 0.213c0.029 0 0.1 0.1 0.1 0.1 c0.042 0.1 0.1 0.1 0.1 0.193c0.035 0 0.1 0.1 0.1 0.139c0.05 0.1 0.1 0.1 0.2 0.2 c0.042 0 0.1 0.1 0.1 0.125c0.058 0.1 0.1 0.1 0.2 0.152c0.047 0 0.1 0.1 0.1 0.1 c0.019 0 0 0 0.1 0.039L58.277 96.64c0.536 0.4 1.2 0.5 1.8 0.537c0.616 0 1.233-0.18 1.77-0.537 l33.938-22.625c0.018-0.012 0.034-0.027 0.053-0.039c0.05-0.035 0.097-0.072 0.145-0.109c0.062-0.049 0.122-0.1 0.181-0.152 c0.044-0.039 0.085-0.082 0.127-0.125c0.056-0.055 0.108-0.113 0.159-0.172c0.037-0.045 0.074-0.09 0.109-0.139 c0.048-0.062 0.092-0.127 0.135-0.193c0.03-0.049 0.062-0.098 0.091-0.146c0.04-0.07 0.075-0.141 0.108-0.213 c0.024-0.051 0.05-0.102 0.071-0.154c0.031-0.078 0.057-0.156 0.082-0.234c0.017-0.051 0.036-0.102 0.05-0.154 c0.023-0.088 0.04-0.178 0.056-0.268c0.008-0.045 0.02-0.092 0.026-0.137c0.018-0.139 0.028-0.277 0.028-0.418V48.735 C97.176 48.6 97.2 48.5 97.1 48.319z M63.238 32.073l25.001 16.666L77.072 56.21l-13.834-9.254V32.073z M56.856 32.1 v14.883L43.023 56.21l-11.168-7.471L56.856 32.073z M29.301 54.708l7.983 5.34l-7.983 5.34V54.708z M56.856 88.022L31.855 71.4 l11.168-7.469l13.833 9.252V88.022z M60.048 67.597l-11.286-7.549l11.286-7.549l11.285 7.549L60.048 67.597z M63.238 88.022V73.14 l13.834-9.252l11.167 7.469L63.238 88.022z M90.794 65.388l-7.982-5.34l7.982-5.34V65.388z"}))),Rt=Object(O.h)("svg",null,Object(O.h)("use",{xlinkHref:"#codepen-logo"})),Ut=Object(O.h)("svg",{style:"width:24px;height:24px",viewBox:"0 0 24 24"},Object(O.h)("path",{d:"M4,4H7L9,2H15L17,4H20A2,2 0 0,1 22,6V18A2,2 0 0,1 20,20H4A2,2 0 0,1 2,18V6A2,2 0 0,1 4,4M12,7A5,5 0 0,0 7,12A5,5 0 0,0 12,17A5,5 0 0,0 17,12A5,5 0 0,0 12,7M12,9A3,3 0 0,1 15,12A3,3 0 0,1 12,15A3,3 0 0,1 9,12A3,3 0 0,1 12,9Z"})),Kt=Object(O.h)("div",{class:"footer__separator hide-on-mobile"}),qt=Object(O.h)("svg",{viewBox:"0 0 100 100",style:"transform:rotate(-90deg)"},Object(O.h)("use",{xlinkHref:"#mode-icon"})),Jt=Object(O.h)("svg",{viewBox:"0 0 100 100"},Object(O.h)("use",{xlinkHref:"#mode-icon"})),Yt=Object(O.h)("svg",{viewBox:"0 0 100 100",style:"transform:rotate(90deg)"},Object(O.h)("use",{xlinkHref:"#mode-icon"})),Gt=Object(O.h)("svg",{viewBox:"0 0 100 100"},Object(O.h)("use",{xlinkHref:"#vertical-mode-icon"})),Zt=Object(O.h)("svg",{viewBox:"0 0 100 100"},Object(O.h)("rect",{x:"0",y:"0",width:"100",height:"100"})),Xt=Object(O.h)("svg",{viewBox:"0 0 24 24"},Object(O.h)("path",{d:"M22,17V7H6V17H22M22,5A2,2 0 0,1 24,7V17C24,18.11 23.1,19 22,19H16V21H18V23H10V21H12V19H6C4.89,19 4,18.11 4,17V7A2,2 0 0,1 6,5H22M2,3V15H0V3A2,2 0 0,1 2,1H20V3H2Z"})),Qt=Object(O.h)("div",{class:"footer__separator"}),$t=Object(O.h)("svg",{viewBox:"0 0 24 24"},Object(O.h)("path",{d:"M14,20A2,2 0 0,1 12,22A2,2 0 0,1 10,20H14M12,2A1,1 0 0,1 13,3V4.08C15.84,4.56 18,7.03 18,10V16L21,19H3L6,16V10C6,7.03 8.16,4.56 11,4.08V3A1,1 0 0,1 12,2Z"})),en=Object(O.h)("span",{class:"notifications-btn__dot"}),tn=Object(O.h)("svg",null,Object(O.h)("use",{xlinkHref:"#settings-icon"})),nn=Object(O.h)("a",{href:"https://webmakerapp.com/",target:"_blank",rel:"noopener noreferrer"},Object(O.h)("div",{class:"logo"})),on=Object(O.h)("span",{class:"web-maker-with-tag"},"Web Maker"),sn=Object(O.h)("svg",{style:"width:20px; height:20px; vertical-align:text-bottom",viewBox:"0 0 24 24"},Object(O.h)("path",{d:"M15.07,11.25L14.17,12.17C13.45,12.89 13,13.5 13,15H11V14.5C11,13.39 11.45,12.39 12.17,11.67L13.41,10.41C13.78,10.05 14,9.55 14,9C14,7.89 13.1,7 12,7A2,2 0 0,0 10,9H8A4,4 0 0,1 12,5A4,4 0 0,1 16,9C16,9.88 15.64,10.67 15.07,11.25M13,19H11V17H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z"})),an=Object(O.h)("use",{xlinkHref:"#keyboard-icon"}),rn=Object(O.h)("use",{xlinkHref:"#twitter-icon"});let ln=class extends O.Component{constructor(e){super(e),this.state={isKeyboardShortcutsModalOpen:!1}}layoutBtnClickhandler(e){this.props.layoutBtnClickHandler(e)}render(){return Object(O.h)("div",{id:"footer",class:"footer"},Object(O.h)("div",{class:"footer__right fr"},Object(O.h)("a",{onClick:this.props.saveHtmlBtnClickHandler,id:"saveHtmlBtn",class:"mode-btn hint--rounded hint--top-left hide-on-mobile","data-hint":"Save as HTML file"},Wt),zt,Object(O.h)("a",{href:"",onClick:this.props.codepenBtnClickHandler,id:"codepenBtn",class:"mode-btn hint--rounded hint--top-left hide-on-mobile","aria-label":"Edit on CodePen"},Rt),Object(O.h)("a",{href:"",id:"screenshotBtn",class:"mode-btn hint--rounded hint--top-left show-when-extension",onClick:this.props.screenshotBtnClickHandler,"aria-label":"Take screenshot of preview"},Ut),Kt,Object(O.h)("a",{onClick:this.layoutBtnClickhandler.bind(this,1),id:"layoutBtn1",class:"mode-btn hide-on-mobile"},qt),Object(O.h)("a",{onClick:this.layoutBtnClickhandler.bind(this,2),id:"layoutBtn2",class:"mode-btn hide-on-mobile"},Jt),Object(O.h)("a",{onClick:this.layoutBtnClickhandler.bind(this,3),id:"layoutBtn3",class:"mode-btn hide-on-mobile"},Yt),Object(O.h)("a",{onClick:this.layoutBtnClickhandler.bind(this,5),id:"layoutBtn5",class:"mode-btn hide-on-mobile"},Gt),Object(O.h)("a",{onClick:this.layoutBtnClickhandler.bind(this,4),id:"layoutBtn4",class:"mode-btn hint--top-left hint--rounded hide-on-mobile","aria-label":"Full Screen"},Zt),Object(O.h)("a",{class:"mode-btn hint--top-left hint--rounded hide-on-mobile","aria-label":"Detach Preview",onClick:this.props.detachedPreviewBtnHandler},Xt),Qt,Object(O.h)("a",{onClick:this.props.notificationsBtnClickHandler,id:"notificationsBtn",class:`notifications-btn mode-btn hint--top-left hint--rounded ${this.props.hasUnseenChangelog?"has-new":""}`,"aria-label":"Notifications"},$t,en),Object(O.h)(y,{onClick:this.props.settingsBtnClickHandler,"data-event-category":"ui","data-event-action":"settingsBtnClick",class:"mode-btn hint--top-left hint--rounded","aria-label":"Settings"},tn)),nn,"\xA9",on," \xA0\xA0",Object(O.h)(y,{onClick:this.props.helpBtnClickHandler,"data-event-category":"ui","data-event-action":"helpButtonClick",class:"footer__link hint--rounded hint--top-right","aria-label":"Help"},sn),Object(O.h)(y,{onClick:this.props.keyboardShortcutsBtnClickHandler,"data-event-category":"ui","data-event-action":"keyboardShortcutButtonClick",class:"footer__link hint--rounded hint--top-right hide-on-mobile","aria-label":"Keyboard shortcuts"},Object(O.h)("svg",{style:{width:"20px",height:"20px",verticalAlign:"text-bottom"}},an)),Object(O.h)("a",{class:"footer__link hint--rounded hint--top-right","aria-label":"Tweet about 'Web Maker'",href:"http://twitter.com/share?url=https://webmakerapp.com/&text=Web Maker - A blazing fast %26 offline web playground! via @webmakerApp&related=webmakerApp&hashtags=web,frontend,playground,offline",target:"_blank",rel:"noopener noreferrer"},Object(O.h)("svg",{style:{width:"20px",height:"20px",verticalAlign:"text-bottom"}},rn)),Object(O.h)(y,{onClick:this.props.supportDeveloperBtnClickHandler,"data-event-action":"supportDeveloperFooterBtnClick",class:"footer__link ml-1 hint--rounded hint--top-right hide-on-mobile","aria-label":"Support the developer by pledging some amount",target:"_blank",rel:"noopener noreferrer"},"Support the developer"))}};var dn=n("gfUn"),cn=n.n(dn);const hn={async getItem(e){var t=await window.db.getDb();return t.doc(`items/${e}`).get().then((e)=>e.data())},async getUserItemIds(){if(window.user)return new Promise((e)=>{e(window.user.items||{})});var e=await window.db.getDb();return e.doc(`users/${window.user.uid}`).get().then((e)=>e.exists?e.data().items:{})},async getAllItems(){var e=Date.now(),t=o();let n=await this.getUserItemIds();n=Object.getOwnPropertyNames(n||{}),Object(dn.log)("itemids",n),n.length||t.resolve([]);var s=await window.db.getDb();const i=[];return s.collection("items").where("createdBy","==",window.user.uid).onSnapshot(function(n){n.forEach(function(e){i.push(e.data())}),Object(dn.log)("Items fetched in ",Date.now()-e,"ms"),t.resolve(i)},function(){t.resolve([])}),t.promise},async setUser(){const e=await window.db.getDb();return e.doc(`users/${window.user.uid}`).set({items:{}})},async setItem(e,t){const n=o();var s;if(db.local.set({[e]:t},()=>{!window.IS_EXTENSION&&window.user&&navigator.onLine||n.resolve()}),"code"===e)return!1;if(window.user){var i=await window.db.getDb();Object(dn.log)(`Starting to save item ${e}`),t.createdBy=window.user.uid,s=i.collection("items").doc(e).set(t,{merge:!0}).then((e)=>{Object(dn.log)("Document written",e),n.resolve()}).catch(n.reject)}return window.user&&navigator.onLine?s:n.promise},saveItems(e){var t=o();return window.user?window.db.getDb().then((n)=>{const o=n.batch();for(var s in e)e[s].createdBy=window.user.uid,o.set(n.doc(`items/${s}`),e[s]),o.update(n.doc(`users/${window.user.uid}`),{[`items.${s}`]:!0}),window.user.items=window.user.items||{},window.user.items[s]=!0;o.commit().then(t.resolve)}):(window.db.local.set(e,t.resolve),window.db.local.get({items:{}},function(t){for(var n in e)t.items[n]=!0;window.db.local.set({items:t.items})})),t.promise},async removeItem(e){if(!window.user){var t=o();return window.db.local.remove(e,t.resolve),t.promise}const n=await window.db.getDb();return Object(dn.log)(`Starting to save item ${e}`),n.collection("items").doc(e).delete().then((e)=>{Object(dn.log)("Document removed",e)}).catch((e)=>Object(dn.log)(e))},async setItemForUser(e){if(!window.user)return window.db.local.get({items:{}},function(t){t.items[e]=!0,window.db.local.set({items:t.items})});const t=await window.db.getDb();return t.collection("users").doc(window.user.uid).update({[`items.${e}`]:!0}).then((t)=>{Object(dn.log)(`Item ${e} set for user`,t),window.user.items=window.user.items||{},window.user.items[e]=!0}).catch((e)=>Object(dn.log)(e))},async unsetItemForUser(e){if(!window.user)return window.db.local.get({items:{}},function(t){delete t.items[e],window.db.local.set({items:t.items})});const t=await window.db.getDb();return t.collection("users").doc(window.user.uid).update({[`items.${e}`]:firebase.firestore.FieldValue.delete()}).then((t)=>{delete window.user.items[e],Object(dn.log)(`Item ${e} unset for user`,t)}).catch((e)=>Object(dn.log)(e))}};var pn;const un={add:function(e){const t=$("#js-alerts-container");t.textContent=e,t.classList.add("is-active"),clearTimeout(pn),pn=setTimeout(function(){t.classList.remove("is-active")},2e3)}};window.alertsService=un;var mn=Object(O.h)("div",{class:"mt-1"},"No match found."),gn=Object(O.h)("span",{class:"show-when-selected"},"(Ctrl/\u2318 + F)"),fn=Object(O.h)("h2",{class:"opacity--30"},"Nothing saved here.");let bn=class extends O.Component{constructor(e){super(e),this.items=[],this.state={filteredItems:[]}}componentWillUpdate(e){this.props.items!==e.items&&(this.items=Object.values(e.items),this.items.sort(function(e,t){return t.updatedOn-e.updatedOn}),this.setState({filteredItems:this.items}))}componentDidUpdate(e){this.props.isOpen&&!e.isOpen&&(window.searchInput.value="")}onCloseIntent(){this.props.closeHandler()}itemClickHandler(e){this.props.itemClickHandler(e)}itemRemoveBtnClickHandler(t,n){n.stopPropagation(),this.props.itemRemoveBtnClickHandler(t)}itemForkBtnClickHandler(t,n){n.stopPropagation(),this.props.itemForkBtnClickHandler(t)}keyDownHandler(e){if(this.props.isOpen){const t=e.ctrlKey||e.metaKey,n=t&&70===e.keyCode,o=40===e.keyCode,s=38===e.keyCode,i=13===e.keyCode,a=$(".js-saved-item-tile.selected"),r=0!==$all(".js-saved-item-tile").length;if((o||s)&&r){const e=o?"nextUntil":"previousUntil";a?(a.classList.remove("selected"),a[e](".js-saved-item-tile:not(.hide)").classList.add("selected")):$(".js-saved-item-tile:not(.hide)").classList.add("selected"),$(".js-saved-item-tile.selected").scrollIntoView(!1)}if(i&&a){const e=this.props.items[a.dataset.itemId];console.log("opening",e),this.props.itemClickHandler(e),v("ui","openItemKeyboardShortcut")}if(n){e.preventDefault();const t=this.props.items[a.dataset.itemId];this.props.itemForkBtnClickHandler(t),v("ui","forkKeyboardShortcut")}}}mergeImportedItems(e){var t=[],n={};const s=o(),i={};this.items.forEach((e)=>i[e.id]=e),e.forEach((e)=>{i[e.id]?t.push(e.id):(c("merging",e.id),n[e.id]=e)});var a=e.length-t.length;if(t.length){var r=confirm(t.length+" creations already exist. Do you want to replace them?");r&&(c("shouldreplace",r),e.forEach((e)=>{n[e.id]=e}),a=e.length)}return a?hn.saveItems(n).then(()=>{s.resolve(),un.add(a+" creations imported successfully."),v("fn","itemsImported",a)}):s.resolve(),this.props.closeHandler(),s.promise}importFileChangeHandler(t){var e=t.target.files[0],n=new FileReader;n.addEventListener("load",(e)=>{var t;try{t=JSON.parse(e.target.result),c(t),this.mergeImportedItems(t)}catch(e){c(e),alert("Oops! Selected file is corrupted. Please select a file that was generated by clicking the \"Export\" button.")}}),n.readAsText(e,"utf-8")}importBtnClickHandler(t){var e=document.createElement("input");e.type="file",e.style.display="none",e.accept="accept=\"application/json",document.body.appendChild(e),e.addEventListener("change",this.importFileChangeHandler.bind(this)),e.click(),v("ui","importBtnClicked"),t.preventDefault()}searchInputHandler(t){const e=t.target.value;e?this.setState({filteredItems:this.items.filter((t)=>-1!==t.title.toLowerCase().indexOf(e))}):this.setState({filteredItems:this.items}),v("ui","searchInputType")}render(){return Object(O.h)("div",{id:"js-saved-items-pane",class:`saved-items-pane ${this.props.isOpen?"is-open":""}`,onKeyDown:this.keyDownHandler.bind(this)},Object(O.h)("button",{onClick:this.onCloseIntent.bind(this),class:"btn saved-items-pane__close-btn",id:"js-saved-items-pane-close-btn"},"X"),Object(O.h)("div",{class:"flex flex-v-center",style:"justify-content: space-between;"},Object(O.h)("h3",null,"My Library (",this.items.length,")"),Object(O.h)("div",{class:"main-header__btn-wrap"},Object(O.h)("a",{onClick:this.props.exportBtnClickHandler,href:"",class:"btn btn-icon hint--bottom-left hint--rounded hint--medium","aria-label":"Export all your creations into a single importable file."},"Export"),Object(O.h)("a",{onClick:this.importBtnClickHandler.bind(this),href:"",class:"btn btn-icon hint--bottom-left hint--rounded hint--medium","aria-label":"Only the file that you export through the 'Export' button can be imported."},"Import"))),Object(O.h)("input",{id:"searchInput",class:"search-input",onInput:this.searchInputHandler.bind(this),placeholder:"Search your creations here..."}),Object(O.h)("div",{id:"js-saved-items-wrap",class:"saved-items-pane__container"},!this.state.filteredItems.length&&this.items.length&&mn,this.state.filteredItems.map((e)=>Object(O.h)("div",{class:"js-saved-item-tile saved-item-tile","data-item-id":e.id,onClick:this.itemClickHandler.bind(this,e)},Object(O.h)("div",{class:"saved-item-tile__btns"},Object(O.h)("a",{class:"js-saved-item-tile__fork-btn saved-item-tile__btn hint--left hint--medium","aria-label":"Creates a duplicate of this creation (Ctrl/\u2318 + F)",onClick:this.itemForkBtnClickHandler.bind(this,e)},"Fork",gn),Object(O.h)("a",{class:"js-saved-item-tile__remove-btn saved-item-tile__btn hint--left","aria-label":"Remove",onClick:this.itemRemoveBtnClickHandler.bind(this,e)},"X")),Object(O.h)("h3",{class:"saved-item-tile__title"},e.title),Object(O.h)("span",{class:"saved-item-tile__meta"},"Last updated: ",d(e.updatedOn)))),!this.items.length&&fn))}};const vn=[{url:"https://code.jquery.com/jquery-3.2.1.min.js",label:"jQuery",type:"js"},{url:"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js",label:"Bootstrap 3",type:"js"},{url:"https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js",label:"Bootstrap 4",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.3/js/foundation.min.js",label:"Foundation",type:"js"},{url:"https://semantic-ui.com/dist/semantic.min.js",label:"Semantic UI",type:"js"},{url:"https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.min.js",label:"Angular",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.production.min.js",label:"React",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.production.min.js",label:"React DOM",type:"js"},{url:"https://unpkg.com/vue/dist/vue.min.js",label:"Vue.js",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.min.js",label:"Three.js",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js",label:"D3",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.min.js",label:"P5.js",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/addons/p5.dom.min.js",label:"P5.js DOM",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/addons/p5.sound.min.js",label:"P5.js Sound",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js",label:"Underscore",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js",label:"Greensock TweenMax",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/uikit/2.27.5/js/uikit.min.js",label:"UIkit 2",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.42/js/uikit.min.js",label:"UIkit 3",type:"js"}],Cn=[{url:"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css",label:"Bootstrap 3",type:"css"},{url:"https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css",label:"Bootstrap 4",type:"css"},{url:"https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.3/css/foundation.min.css",label:"Foundation",type:"css"},{url:"https://semantic-ui.com/dist/semantic.min.css",label:"Semantic UI",type:"css"},{url:"https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css",label:"Bulma",type:"css"},{url:"https://cdnjs.cloudflare.com/ajax/libs/hint.css/2.5.0/hint.min.css",label:"Hint.css",type:"css"},{url:"https://cdn.jsdelivr.net/npm/tailwindcss/dist/tailwind.min.css",label:"Tailwind.css",type:"css"},{url:"https://cdnjs.cloudflare.com/ajax/libs/uikit/2.27.5/css/uikit.min.css",label:"UIkit 2",type:"css"},{url:"https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.42/css/uikit.min.css",label:"UIkit 3",type:"css"},{url:"https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css",label:"Animate.css",type:"css"},{url:"https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css",label:"FontAwesome 4",type:"css"},{url:"https://use.fontawesome.com/releases/v5.0.10/css/all.css",label:"FontAwesome 5",type:"css"}];let yn=class extends O.Component{componentDidMount(){this.t=this.wrap.querySelector("input,textarea"),this.filter=this.props.filter,this.selectedCallback=this.props.onSelect,setTimeout(()=>{requestIdleCallback(()=>{document.body.appendChild(this.list),this.list.style.position="fixed"})},100),this.t.addEventListener("input",(t)=>this.onInput(t)),this.t.addEventListener("keydown",(t)=>this.onKeyDown(t)),this.t.addEventListener("blur",(t)=>this.closeSuggestions(t)),this.list.addEventListener("mousedown",(t)=>this.onListMouseDown(t))}componentWillUnmount(){this.t.removeEventListener("input",(t)=>this.onInput(t)),this.t.removeEventListener("keydown",(t)=>this.onKeyDown(t)),this.t.removeEventListener("blur",(t)=>this.closeSuggestions(t)),this.list.removeEventListener("mousedown",(t)=>this.onListMouseDown(t))}get currentLineNumber(){return this.t.value.substr(0,this.t.selectionStart).split("\n").length}get currentLine(){var e=this.currentLineNumber;return this.t.value.split("\n")[e-1]}closeSuggestions(){this.list.classList.remove("is-open"),this.isShowingSuggestions=!1}getList(e){return fetch("https://api.cdnjs.com/libraries?search="+e).then((e)=>e.json().then((e)=>e.results))}replaceCurrentLine(e){var t=this.t.value.split("\n");t.splice(this.currentLineNumber-1,1,e),this.t.value=t.join("\n")}onInput(){var e=this.currentLine;if(e){if(-1!==e.indexOf("/")||e.match(/https*:\/\//))return;clearTimeout(this.timeout),this.timeout=setTimeout(()=>{this.loader.style.display="block",this.getList(e).then((e)=>{if(this.loader.style.display="none",!e.length)return void this.closeSuggestions();this.list.innerHTML="",this.filter&&(e=e.filter(this.filter));for(var t=0;t${e[t].name}`;this.isShowingSuggestions=!0,this.textareaBounds||(this.textareaBounds=this.t.getBoundingClientRect(),this.list.style.top=this.textareaBounds.bottom+"px",this.list.style.left=this.textareaBounds.left+"px",this.list.style.width=this.textareaBounds.width+"px"),this.list.classList.add("is-open")})},500)}}onKeyDown(e){var t;this.isShowingSuggestions&&(27===e.keyCode&&(this.closeSuggestions(),e.stopPropagation()),40===e.keyCode&&this.isShowingSuggestions?(t=this.list.querySelector(".selected"),t?(t.classList.remove("selected"),t.nextElementSibling.classList.add("selected")):this.list.querySelector("li:first-child").classList.add("selected"),this.list.querySelector(".selected").scrollIntoView(!1),e.preventDefault()):38===e.keyCode&&this.isShowingSuggestions?(t=this.list.querySelector(".selected"),t?(t.classList.remove("selected"),t.previousElementSibling.classList.add("selected")):this.list.querySelector("li:first-child").classList.add("selected"),this.list.querySelector(".selected").scrollIntoView(!1),e.preventDefault()):13===e.keyCode&&this.isShowingSuggestions&&(t=this.list.querySelector(".selected"),this.selectSuggestion(t.dataset.url),this.closeSuggestions()))}onListMouseDown(e){var t=e.target;t.parentElement.dataset.url&&this.selectSuggestion(t.parentElement.dataset.url)}selectSuggestion(e){this.t.focus(),v("ui","autoSuggestionLibSelected",e),this.selectedCallback?this.selectedCallback.call(null,e):this.replaceCurrentLine(e),this.closeSuggestions()}render(){return Object(O.h)("div",{class:`btn-group ${this.props.fullWidth?"flex-grow":""}`,ref:(e)=>this.wrap=e},this.props.children,Object(O.h)("ul",{ref:(e)=>this.list=e,class:"dropdown__menu autocomplete-dropdown"}),Object(O.h)("div",{ref:(e)=>this.loader=e,class:"loader autocomplete__loader",style:"display:none"}))}};var Sn=Object(O.h)("h1",null,"Add Library"),wn=Object(O.h)("svg",{style:"width: 30px; height: 30px;fill:#999"},Object(O.h)("use",{xlinkHref:"#search"})),kn=Object(O.h)("input",{type:"text",id:"externalLibrarySearchInput",class:"full-width",placeholder:"Type here to search libraries"}),xn=Object(O.h)("div",{class:"tar opacity--70"},Object(O.h)("small",null,"Powered by cdnjs")),Mn=Object(O.h)("option",{value:""},"-------"),_n=Object(O.h)("h3",{class:"mb-0"},"JS"),Ln=Object(O.h)("p",{class:"mt-0 help-text"},"Put each library in new line"),In=Object(O.h)("p",{style:"font-size: 0.8em;",class:"show-when-extension opacity--70"},"Note: You can load external scripts from following domains: localhost, https://ajax.googleapis.com, https://code.jquery.com, https://cdnjs.cloudflare.com, https://unpkg.com, https://maxcdn.com, https://cdn77.com, https://maxcdn.bootstrapcdn.com, https://cdn.jsdelivr.net/, https://rawgit.com, https://wzrd.in"),Hn=Object(O.h)("h3",{class:"mb-0"},"CSS"),An=Object(O.h)("p",{class:"mt-0 help-text"},"Put each library in new line");let jn=class extends O.Component{constructor(e){super(e),this.state={css:e.css||"",js:e.js||""}}onSelectChange(t){const e=t.target;if(e.value){const t=e.selectedOptions[0].dataset.type;"js"===t?this.setState({js:`${this.state.js}\n${e.value}`}):this.setState({css:`${this.state.css}\n${e.value}`}),v("ui","addLibrarySelect",e.selectedOptions[0].label),this.props.onChange({js:this.state.js,css:this.state.css}),e.value=""}}textareaBlurHandler(t,e){const n=t?t.target:e,o=n.dataset.lang;"js"===o?this.setState({js:n.value||""}):this.setState({css:n.value||""}),this.props.onChange({js:this.state.js,css:this.state.css})}suggestionSelectHandler(e){const t=e.match(/\.js$/)?window.externalJsTextarea:window.externalCssTextarea;t.value=`${t.value}\n${e}`,window.externalLibrarySearchInput.value="",this.textareaBlurHandler(null,t)}render(){return Object(O.h)("div",null,Sn,Object(O.h)("div",{class:"flex"},wn,Object(O.h)(yn,{fullWidth:!0,onSelect:this.suggestionSelectHandler.bind(this)},kn)),xn,Object(O.h)("div",{style:"margin:20px 0;"},"Choose from popular libraries:"," ",Object(O.h)("select",{name:"",id:"js-add-library-select",onChange:this.onSelectChange.bind(this)},Mn,Object(O.h)("optgroup",{label:"JavaScript Libraries"},vn.map((e)=>Object(O.h)("option",{"data-type":e.type,value:e.url},e.label))),Object(O.h)("optgroup",{label:"CSS Libraries"},Cn.map((e)=>Object(O.h)("option",{"data-type":e.type,value:e.url},e.label))))),_n,Ln,In,Object(O.h)("textarea",{onBlur:this.textareaBlurHandler.bind(this),"data-lang":"js",class:"full-width",id:"externalJsTextarea",cols:"30",rows:"5",placeholder:"Put each library in new line",value:this.state.js}),Hn,An,Object(O.h)("textarea",{onBlur:this.textareaBlurHandler.bind(this),"data-lang":"css",class:"full-width",id:"externalCssTextarea",cols:"30",rows:"5",placeholder:"Put each library in new line",value:this.state.css}))}};var Bn=n("ZUoI"),En=n.n(Bn);const On={logout(){En.a.auth().signOut()},login(e){var t;return"facebook"===e?t=new En.a.auth.FacebookAuthProvider:"twitter"===e?t=new En.a.auth.TwitterAuthProvider:"google"===e?(t=new En.a.auth.GoogleAuthProvider,t.addScope("https://www.googleapis.com/auth/userinfo.profile")):t=new En.a.auth.GithubAuthProvider,En.a.auth().signInWithPopup(t).then(function(){v("fn","loggedIn",e),window.db.local.set({lastAuthProvider:e})}).catch(function(e){c(e),"auth/account-exists-with-different-credential"===e.code&&alert("You have already signed up with the same email using different social login")})}};var Tn=Object(O.h)("h2",null,"Login / Signup"),Vn=Object(O.h)("svg",null,Object(O.h)("use",{xlinkHref:"#github-icon"})),Pn=Object(O.h)("svg",null,Object(O.h)("use",{xlinkHref:"#google-icon"})),Dn=Object(O.h)("svg",null,Object(O.h)("use",{xlinkHref:"#fb-icon"})),Fn=Object(O.h)("p",null,"Join a community of 50,000+ Developers");let Nn=class extends O.Component{login(t){const e=t.target.dataset.authProvider;v("ui","loginProviderClick",e),On.login(e)}componentDidMount(){window.db.local.get({lastAuthProvider:""},(e)=>{e.lastAuthProvider&&document.body.classList.add(`last-login-${e.lastAuthProvider}`)})}render(){return Object(O.h)("div",null,Tn,Object(O.h)("div",null,Object(O.h)("p",null,Object(O.h)("button",{type:"button",onClick:this.login.bind(this),class:"social-login-btn social-login-btn--github btn btn-icon btn--big full-width hint--right hint--always","data-auth-provider":"github","data-hint":"You logged in with Github last time"},Vn,"Login with Github")),Object(O.h)("p",null,Object(O.h)("button",{type:"button",onClick:this.login.bind(this),class:"social-login-btn social-login-btn--google btn btn-icon btn--big full-width hint--right hint--always","data-auth-provider":"google","data-hint":"You logged in with Google last time"},Pn,"Login with Google")),Object(O.h)("p",{class:"mb-2"},Object(O.h)("button",{type:"button",onClick:this.login.bind(this),class:"social-login-btn social-login-btn--facebook btn btn-icon btn--big full-width hint--right hint--always","data-auth-provider":"facebook","data-hint":"You logged in with Facebook last time"},Dn,"Login with Facebook")),Fn))}};En.a.initializeApp({apiKey:"AIzaSyBl8Dz7ZOE7aP75mipYl2zKdLSRzBU2fFc",authDomain:"web-maker-app.firebaseapp.com",databaseURL:"https://web-maker-app.firebaseio.com",projectId:"web-maker-app",storageBucket:"web-maker-app.appspot.com",messagingSenderId:"560473480645"});var Wn=n("7vHL"),zn=Object.assign||function(e){for(var t,n=1;n{async function e(){return s?s:(c("Initializing firestore"),s=new Promise((e,t)=>n?e(n):En.a.firestore().enablePersistence().then(function(){n=En.a.firestore(),c("firebase db ready",n),e(n)}).catch(function(e){t(e.code),"failed-precondition"===e.code?(alert("Opening Web Maker web app in multiple tabs isn't supported at present and it seems like you already have it opened in another tab. Please use in one tab."),v("fn","multiTabError")):"unimplemented"===e.code})),s)}const t=1;var n,s,i={get:(e,n)=>{const o={};"string"==typeof e?(o[e]=JSON.parse(window.localStorage.getItem(e)),setTimeout(()=>n(o),t)):(Object.keys(e).forEach((t)=>{const n=window.localStorage.getItem(t);o[t]=void 0===n||null===n?e[t]:JSON.parse(n)}),setTimeout(()=>n(o),t))},set:(e,n)=>{Object.keys(e).forEach((t)=>{window.localStorage.setItem(t,JSON.stringify(e[t]))}),setTimeout(()=>{if(n)return n()},t)},remove:(e,n)=>{window.localStorage.removeItem(e),setTimeout(()=>n(),t)}};const a=chrome&&chrome.storage?chrome.storage.local:i,r=chrome&&chrome.storage?chrome.storage.sync:i;window.db={getDb:e,getUser:async function(t){const n=await e();return n.doc(`users/${t}`).get().then((e)=>{if(!e.exists)return n.doc(`users/${t}`).set({},{merge:!0});const o=e.data();return zn(window.user,o),o})},getUserLastSeenVersion:async function(){const e=o();return r.get({lastSeenVersion:""},(t)=>{e.resolve(t.lastSeenVersion)}),e.promise},setUserLastSeenVersion:async function(t){if(r.set({lastSeenVersion:t},function(){}),window.user){const n=await e();n.doc(`users/${window.user.uid}`).update({lastSeenVersion:t})}},getSettings:function(e){const t=o();return r.get(e,(e)=>{t.resolve(e)}),t.promise},local:a,sync:r}})();var Rn=Object(O.h)("div",null,Object(O.h)("h1",null,"Whats new?"),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"3.2.0"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("strong",null,"\uD83D\uDE80 Loop timeout setting"),": You now have a setting to tweak the maximum timeout of a loop iteration before it's marked as infinite loop."),Object(O.h)("li",null,Object(O.h)("strong",null,"\u267F\uFE0F Accessibility"),": Modals now have proper keyboard navigation integrated."),Object(O.h)("li",null,Object(O.h)("strong",null,"\u267F\uFE0F Accessibility"),": Color contrast improvements."),Object(O.h)("li",null,"\uD83D\uDE80 Popular libraries list updated. Thanks",Object(O.h)("a",{href:"https://github.com/diomed",target:"_blank"},"@diomed")," ","&"," ",Object(O.h)("a",{href:"https://github.com/leninalbertolp",target:"_blank"},"@leninalbertolp")),Object(O.h)("li",null,Object(O.h)("strong",null,"\uD83D\uDD27 Bugfix"),": Modal take up appropriate width instead of spanning full width."),Object(O.h)("br",null),Object(O.h)("li",null,Object(O.h)("strong",null,"\uD83D\uDE80 Announcement"),": Hi! I am Kushagra Gour (creator of Web Maker) and I have launched a",Object(O.h)("a",{href:"https://patreon.com/kushagra",target:"_blank"},"Patreon campaign"),". If you love Web Maker, consider pledging to",Object(O.h)("a",{href:"https://patreon.com/kushagra",target:"_blank"},"support me")," ",":)"),Object(O.h)("li",null,Object(O.h)("a",{href:"https://github.com/chinchang/web-maker/issues",target:"_blank"},"Suggest features or report bugs.")),Object(O.h)("li",null,"Web Maker now has more than 50K weekly active users! Thank you for being a part of this community of awesome developers. If you find Web Maker helpful,",Object(O.h)("a",{href:"https://chrome.google.com/webstore/detail/web-maker/lkfkkhfhhdkiemehlpkgjeojomhpccnh/reviews",target:"_blank",class:"btn"},"Please rate Web Maker ",Object(O.h)("span",{class:"star"})),"\xA0",Object(O.h)("a",{href:"http://twitter.com/share?url=https://webmakerapp.com/&text=Web Maker - A blazing fast %26 offline web playground! via @webmakerApp&related=webmakerApp&hashtags=web,editor,chrome,extension",target:"_blank",target:"_blank",class:"btn"},"Share it"),"\xA0",Object(O.h)("a",{"aria-label":"Support the developer","d-click":"openSupportDeveloperModal","data-event-action":"supportDeveloperChangelogBtnClick",class:"btn btn-icon"},"Support the developer")))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"3.1.1"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix"),": Fix the \"Run\" button not refreshing the preview after release 3.0.4."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"3.1.0"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("strong",null,"Mobile Support (app only)."),": Make the Web Maker app usable on mobile. This is only for web app as Chrome extensions don't run on mobile."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"3.0.4"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix"),": Guarantee code doesn't execute when \"auto preview\" is off."),Object(O.h)("li",null,"Add link to our new",Object(O.h)("a",{href:"https://web-maker.slack.com",target:"_blank",rel:"noopener noreferrer"},"Slack channel")," ","\uD83E\uDD17."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"3.0.3"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix (extension)"),": \"Save as HTML\" file saves with correct extension."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"3.0.1"),Object(O.h)("ul",null,Object(O.h)("li",null,"After months of work, here is Web Maker 3.0.",Object(O.h)("a",{href:"https://medium.com/web-maker/web-maker-3-0-is-here-f158a40eeaee",target:"_blank",rel:"noopener noreferrer"},"Read the blog post about it"),"."),Object(O.h)("li",null,"Web Maker is no more just a Chrome extension, it is also available as web app that runs offline just like the extension! Checkout it out ->",Object(O.h)("a",{href:"https://webmakerapp.com/app/",target:"_blank",rel:"noopener noreferrer"},"https://webmakerapp.com/app/"),"."),Object(O.h)("li",null,"Now use Web Maker web app on any modern browser (tested with Chrome and Firefox)."),Object(O.h)("li",null,Object(O.h)("strong",null,"User Accounts")," - The much requested user accounts are here. Now maintain your account and store all your creations in the cloud and access them anywhere anytime."),Object(O.h)("li",null,Object(O.h)("strong",null,"New layout mode")," - One more layout mode, that lets you align all the panes vertically."),Object(O.h)("li",null,Object(O.h)("strong",null,"No more restriction on scripts (Web app only)")," - If you are using the web app, there is no more a restriction to load scripts from only specific domains. Load any script!"),Object(O.h)("li",null,Object(O.h)("strong",null,"Inline scripts (Web app only)")," - The restriction of writing JavaScript only in JS pane is also removed."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.9.7"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("a",{href:"https://tailwindcss.com/",target:"_blank",rel:"noopener noreferrer"},"Tailwind CSS")," ","added to popular CSS libraries list. Thanks",Object(O.h)("a",{href:"https://github.com/diomed",target:"_blank",rel:"noopener noreferrer"},"diomed"),"."),Object(O.h)("li",null,"Popular libraries list updated. Thanks",Object(O.h)("a",{href:"https://github.com/diomed",target:"_blank",rel:"noopener noreferrer"},"diomed"),"."),Object(O.h)("li",null,Object(O.h)("strong",null,"Dev"),": Bug fixes and code refactoring to make things simple. Thanks",Object(O.h)("a",{href:"https://github.com/iamandrewluca",target:"_blank",rel:"noopener noreferrer"},"iamandrewluca"),"."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.9.6"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix"),": Fix close buttons not working in notifications and keyboard shortcuts modal."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix"),": Fix keyboard shortcut to see keyboard shortcuts :) Thanks",Object(O.h)("a",{href:"https://github.com/ClassicOldSong",target:"_blank",rel:"noopener noreferrer"},"ClassicOldSong"),"."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.9.5"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("a",{href:"https://medium.com/web-maker/release-2-9-5-add-library-search-pane-collapsing-ux-improvements-more-1085216c1301",target:"_blank",rel:"noopener noreferrer"},"Read blog post about this release.")),Object(O.h)("li",null,Object(O.h)("strong",null,"Keyboard shortcuts panel"),": Add a list of all keyboard shotcuts. Access with",Object(O.h)("code",null," Ctrl/\u2318 + Shift + ?")," or click keyboard button in footer."),Object(O.h)("li",null,Object(O.h)("strong",null,"Add external library"),": Better UX for searching third party libraries."),Object(O.h)("li",null,Object(O.h)("strong",null,"Improvement"),": Code panes now go fullscreen when double-clicked on their headers - which is much more intuitive behavior based on feedback from lot of developers."),Object(O.h)("li",null,Object(O.h)("strong",null,"Improvement"),": Add",Object(O.h)("code",null,"allowfullscreen")," attribute on iframes. Thanks",Object(O.h)("a",{href:"https://github.com/ClassicOldSong",target:"_blank",rel:"noopener noreferrer"},"ClassicOldSong"),"."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix")," - Stop screenlog.js from showing up in the exported HTML."),Object(O.h)("li",null,"Popular external libraries list updated. Thanks",Object(O.h)("a",{href:"https://github.com/jlapitan",target:"_blank",rel:"noopener noreferrer"},"jlapitan"),"."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.9.4"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("strong",null,"Improvement"),": Atomic CSS (Atomizer) has been updated to latest version. Now you can do things like psuedo elements. Learn More."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix")," - Logging circular objects is now possible. It won't show in the Web Maker console, but will show fine in browser's console."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix")," - Console's z-index issue has been fixed."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.9.3"),Object(O.h)("ul",null,Object(O.h)("li",null,"Choose the save location while exporting your saved creations. Now easily sync them to your Dropbox or any cloud storage."),Object(O.h)("li",null,"All modals inside the app now have a close button."),Object(O.h)("li",null,"Checkbox that showed on clicking a boolean value is now removed. Thanks",Object(O.h)("a",{href:"https://github.com/gauravmuk",target:"_blank",rel:"noopener noreferrer"},"Gaurav Nanda"),"."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix")," - Screenshots on retina device are now correct. Thanks",Object(O.h)("a",{href:"https://github.com/AshBardhan",target:"_blank",rel:"noopener noreferrer"},"Ashish Bardhan"),"."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix")," - Double console log in detached mode fixed."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix")," - Console.clear now works in detached mode too."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix")," - DOCTYPE added in preview."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix")," - Typo correction in README. Thanks",Object(O.h)("a",{href:"https://github.com/AdilMah",target:"_blank",rel:"noopener noreferrer"},"Adil Mahmood"),"."),Object(O.h)("li",null,"gstatic.com is available to load external JavaScripts from."),Object(O.h)("li",null,"Popular libraries list updated. Thanks",Object(O.h)("a",{href:"https://github.com/diomed",target:"_blank",rel:"noopener noreferrer"},"diomed"),"."),Object(O.h)("li",null,"Added",Object(O.h)("a",{href:"https://github.com/chinchang/web-maker/blob/master/CONTRIBUTING.md",target:"_blank",rel:"noopener noreferrer"},"contribution guidelines")," ","in the Github repository."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.9.2"),Object(O.h)("ul",null,Object(O.h)("li",null,"Minor bug fixes."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.9.1"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("a",{href:"https://medium.com/web-maker/v2-9-lots-of-goodies-bd1e939571f6",target:"_blank",rel:"noopener noreferrer"},"Read blog post about last release.")),Object(O.h)("li",null,"Use Ctrl/Cmd+D to select next occurence of matching selection."),Object(O.h)("li",null,"Improve onboard experience."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.9.0"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("a",{href:"https://medium.com/web-maker/v2-9-lots-of-goodies-bd1e939571f6",target:"_blank",rel:"noopener noreferrer"},"Read blog post about this release.")),Object(O.h)("li",null,Object(O.h)("strong",null,"Detached Preview")," - Yes, you read that correct! You can now detach your preview and send it to your secondary monitor."),Object(O.h)("li",null,Object(O.h)("strong",null,"Find & Replace")," - Long awaited, now its there. Ctrl/Cmd+f to find and add Alt to replace."),Object(O.h)("li",null,Object(O.h)("strong",null,"Atomic CSS (Atomizer) configurations")," - Add custom config for Atomic CSS.",Object(O.h)("a",{href:"https://github.com/acss-io/atomizer#api",target:"_blank",rel:"noopener noreferrer"},"Read more"),"."),Object(O.h)("li",null,Object(O.h)("strong",null,"Light mode")," - This new setting makes Web Maker drop some heavy effects like blur etc to gain more performance. Thanks",Object(O.h)("a",{href:"https://github.com/iamandrewluca",target:"_blank",rel:"noopener noreferrer"},"Andrew"),"."),Object(O.h)("li",null,Object(O.h)("strong",null,"Preserve logs setting")," - Choose whether or not to preserve logs across preview refreshes. Thanks",Object(O.h)("a",{href:"https://github.com/BasitAli",target:"_blank",rel:"noopener noreferrer"},"Basit"),"."),Object(O.h)("li",null,Object(O.h)("strong",null,"Line wrap setting")," - As the name says."),Object(O.h)("li",null,"Semantic UI added to popular libraries."),Object(O.h)("li",null,"Bootstrap, Vue, UI-Kit and more updated to latest versions in popular libraries."),Object(O.h)("li",null,"UX improvements in settings UI"),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix")," - Trigger preview refresh anytime with Ctrl/\u2318 + Shift + 5. Even with auto-preview on."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.8.1"),Object(O.h)("ul",null,Object(O.h)("li",null,"Vue.js & UIKit version updated to latest version in 'Add Library' list."),Object(O.h)("li",null,"UTF-8 charset added to preview HTML to support universal characters."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.8.0"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("a",{href:"https://medium.com/web-maker/release-v2-8-is-out-f44e6ea5d9c4",target:"_blank",rel:"noopener noreferrer"},"Read blog post about this release.")),Object(O.h)("li",null,Object(O.h)("strong",null,"Auto Save")," - Your creations now auto-save after your first manual save. This is configurable from settings."),Object(O.h)("li",null,Object(O.h)("strong",null,"Base2Tone-Meadow Editor Theme")," - First user contributed theme. Thanks to Diomed."),Object(O.h)("li",null,Object(O.h)("strong",null,"Use System Fonts")," - You can now use any of your existing system fonts in the editor!"),Object(O.h)("li",null,Object(O.h)("strong",null,"Matching Tag Highlight")," - Cursor over any HTML tag would highlight the matching pair tag."),Object(O.h)("li",null,"Auto-completion suggestion can now be switched off from settings."),Object(O.h)("li",null,Object(O.h)("strong",null,"Improvement")," - Stop white flicker in editor when the app opens."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix")," - Add Babel Polyfill to enable use of next-gen built-ins like Promise or WeakMap."),Object(O.h)("li",null,"Vue.js version updated to 2.4.0 in popular library list."),Object(O.h)("li",null,"Downloads permission is optional. Asked only when you take screenshot."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.7.2"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("strong",null,"External Libraries")," - Add Foundation.js and update UIKit 3 to latest beta."),Object(O.h)("li",null,Object(O.h)("strong",null,"rawgit.com")," &",Object(O.h)("strong",null,"wzrd.in")," domains are now allowed for loading external libraries from."),Object(O.h)("li",null,"Minor booting speed improvements"))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.7.1"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("strong",null,"Framer.js support")," - You can now load the latest framer.js library from",Object(O.h)("a",{href:"https://builds.framerjs.com/",target:"_blank",rel:"noopener noreferrer"},"framer builds page")," ","and start coding framer prototypes."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix"),": Edit on CodePen is back in action."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix"),": Autocompletion menu doesn't show on cut and paste now."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix"),": Updated & fixed urls of some common external libraries to latest versions. UIKit3 & Bootstrap 4\u03B1 are now in the list."),Object(O.h)("li",null,"Preprocessor selector are now more accessible."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.7.0"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("strong",null,"Fork any creation!"),": Now you can fork any existing creation of yours to start a new work based on it. One big use case of this feature is \"Templates\"!",Object(O.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"https://kushagragour.in/blog/2017/05/web-maker-fork-templates/?utm_source=webmakerapp&utm_medium=referral"},"Read more about it"),"."),Object(O.h)("li",null,Object(O.h)("strong",null,"Fonts \uD83D\uDE0D "),": Super-awesome 4 fonts (mostly with ligature support) now available to choose from. Fira Code is the default font now."),Object(O.h)("li",null,"Updated most used external libraries to latest versions."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix"),": Add missing Bootstrap JS file to most used external libraries list."),Object(O.h)("li",null,"Several other minor bugfixes and improvements to make Web Maker awesome!"),Object(O.h)("li",null,"Great news to share with you - Web Maker has been featured on the Chrome Webstore homepage! Thanks for all the love :)"))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.6.1"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix"),": Emojis vanishing while exporting to Codepen has been fixed."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix"),":",Object(O.h)("code",null,"console.clear()")," now doesn't error and clears the inbuilt console."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix"),": External libraries added to the creation are exported as well to Codepen."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.6.0"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("strong",null,"The \"Console\""),": The most awaited feature is here! There is now an inbuilt console to see your logs, errors and for quickly evaluating JavaScript code inside your preview. Enjoy! I also a",Object(O.h)("a",{href:"https://kushagragour.in/blog/2017/05/web-maker-console-is-here/?utm_source=webmakerapp&utm_medium=referral",target:"_blank",rel:"noopener noreferrer"},"blog post about it"),"."),Object(O.h)("li",null,"Number slider which popped on clicking any number in the code has been removed due to poor user experience."),Object(O.h)("li",null,"Minor usability improvements."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.5.0"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("strong",null,"Atomic CSS"),": Use can now use Atomic CSS(ACSS) in your work!",Object(O.h)("a",{href:"https://acss.io/",target:"_blank",rel:"noopener noreferrer"},"Read more about it here"),"."),Object(O.h)("li",null,Object(O.h)("strong",null,"Search your saved creations"),": Easily search through all your saved creations by title."),Object(O.h)("li",null,Object(O.h)("strong",null,"Configurable Auto-preview")," - You can turn off the auto preview in settings if you don't want the preview to update as you type."),Object(O.h)("li",null,Object(O.h)("strong",null,"Configurable refresh on resize")," - You can configure whether you want the preview to refresh when you resize the preview panel."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix")," - Fix indentation",Object(O.h)("a",{href:"https://github.com/chinchang/web-maker/issues/104",target:"_blank",rel:"noopener noreferrer"},"issue")," ","with custom indentation size."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.4.2"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("strong",null,"Improved infinite loop protection"),": Infinite loop protection is now faster and more reliable. And works without the need of Escodegen. Thanks to Ariya Hidayat!"),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix")," - Default parameters not working in JavaScript is fixed."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.4.0"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("strong",null,"Import/Export"),": Your creations are most important. Now export all your creations into a single file as a backup that can be imported anytime & anywhere."),Object(O.h)("li",null,Object(O.h)("strong",null,"Editor themes"),": You have been heard. Now you can choose from a huge list of wonderful editor themes!"),Object(O.h)("li",null,Object(O.h)("strong",null,"Identation settings"),": Not a spaces fan? Switch to tabs and set your indentation size."),Object(O.h)("li",null,Object(O.h)("strong",null,"Vim key bindings"),": Rejoice Vim lovers!"),Object(O.h)("li",null,Object(O.h)("strong",null,"Code blast"),": Why don't you try coding with this switched on from the settings? Go on..."),Object(O.h)("li",null,Object(O.h)("strong",null,"Important"),": Due to security policy changes from Chrome 57 onwards, Web Maker now allows loading external JavaScript libraries only from certain whitelisted domains (localhost, https://ajax.googleapis.com, https://code.jquery.com, https://cdnjs.cloudflare.com, https://unpkg.com, https://maxcdn.com, https://cdn77.com, https://maxcdn.bootstrapcdn.com, https://cdn.jsdelivr.net/)"),Object(O.h)("li",null,"Save button now highlights when you have unsaved changes."),Object(O.h)("li",null,"Jade is now called Pug. Just a name change."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.3.2"),Object(O.h)("ul",null,Object(O.h)("li",null,"Update Babel to support latest and coolest ES6 features."),Object(O.h)("li",null,"Improve onboarding experience at first install."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.3.1"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix")," - Splitting of code and preview panes is remembered by the editor."),Object(O.h)("li",null,"Title of the creation is used for the file name when saving as HTML."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.3.0"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("strong",null,"Add Library Autocompletion")," - Just start typing the name of library and you'll be shown matching libraries from cdnjs."),Object(O.h)("li",null,Object(O.h)("strong",null,"Preview Screenshot Capture")," - Want to grab a nice screenshot of your creation. You have it! Click and capture."),Object(O.h)("li",null,Object(O.h)("strong",null,"Auto Indent Code")," - Select your code and hit Shift-Tab to auto-indent it!"),Object(O.h)("li",null,Object(O.h)("strong",null,"Keyboard Navigation in Saved List")," - Now select your creation using arrow keys and hit ENTER to open it."),Object(O.h)("li",null,"Highlight active line in code panes."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix")," - Fix in generated title of new creation."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix")," - HTML autocompletion is manual triggered now with Ctrl+Space."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.2.0"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("strong",null,"Code Autocompletion")," - See code suggestions while you type!"),Object(O.h)("li",null,Object(O.h)("strong",null,"Full Screen Preview")," - Checkout your creation in a full-screen layout."),Object(O.h)("li",null,Object(O.h)("strong",null,"SASS")," - SASS support added for CSS."),Object(O.h)("li",null,Object(O.h)("strong",null,"Faster CSS update")," - Preview updates instantly without refresh when just CSS is changed."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix")," - Indentation fixed while going on new line."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix")," - Works even in Chrome Canary now. Though libraries can be added only through CDNs."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.1.0"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("strong",null,"TypeScript")," - Now you can code in TypeScript too!"),Object(O.h)("li",null,Object(O.h)("strong",null,"Stylus Preprocessor")," - Stylus supported adding for CSS."),Object(O.h)("li",null,Object(O.h)("strong",null,"Code Folding")," - Collapse large code blocks for easy editing."),Object(O.h)("li",null,Object(O.h)("strong",null,"Bugfix")," - Support JSX in JavaScript."),Object(O.h)("li",null,"Better onboarding for first time users."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"2.0.0"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("strong",null,"Save and Load")," - Long pending and super-useful, now you can save your creations and resume them anytime later."),Object(O.h)("li",null,Object(O.h)("strong",null,"Insert JS & CSS")," - Load popular JavaScript & CSS libraries in your work without writing any code."),Object(O.h)("li",null,Object(O.h)("strong",null,"Collapsed Panes")," - Collapse/uncollapse code panes with a single click. Your pane configuration is even saved with every creation!"),Object(O.h)("li",null,Object(O.h)("strong",null,"Quick color & number change")," - Click on any color or number and experiment with quick values using a slider."),Object(O.h)("li",null,Object(O.h)("strong",null,"Linting")," - See your code errors right where you are coding."),Object(O.h)("li",null,"No more browser hang due to infinite loops!"))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"1.7.0"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("strong",null,"Preprocessors!")," - Enjoy a whole list of preprocessors for HTML(Jade & markdown), CSS(SCSS & LESS) and JavaScript(CoffeeScript & Babel)."),Object(O.h)("li",null,"More awesome font for code."))),Object(O.h)("div",{class:"notification"},Object(O.h)("span",{class:"notification__version"},"1.6.0"),Object(O.h)("ul",null,Object(O.h)("li",null,"You can now configure Web-Maker to not replace new tab page from the settings. It is always accessible from the icon in the top-right."),Object(O.h)("li",null,"Download current code as HTML file with Ctrl/\u2318 + S keyboard shortcut."),Object(O.h)("li",null,"New notifications panel added so you are always aware of the new changes in Web-Maker."))));const Un=["3024-day","3024-night","abcdef","ambiance","base2tone-meadow-dark","base16-dark","base16-light","bespin","blackboard","cobalt","colorforth","dracula","duotone-dark","duotone-light","eclipse","elegant","erlang-dark","hopscotch","icecoder","isotope","lesser-dark","liquibyte","material","mbo","mdn-like","midnight","monokai","neat","neo","night","panda-syntax","paraiso-dark","paraiso-light","pastel-on-dark","railscasts","rubyblue","seti","solarized dark","solarized light","the-matrix","tomorrow-night-bright","tomorrow-night-eighties","ttcn","twilight","vibrant-ink","xq-dark","xq-light","yeti","zenburn"];var Kn=Object(O.h)("h1",null,"Settings"),qn=Object(O.h)("h3",null,"Indentation"),Jn=Object(O.h)("datalist",{id:"indentationSizeList"},Object(O.h)("option",null,"1"),Object(O.h)("option",null,"2"),Object(O.h)("option",null,"3"),Object(O.h)("option",null,"4"),Object(O.h)("option",null,"5"),Object(O.h)("option",null,"6"),Object(O.h)("option",null,"7")),Yn=Object(O.h)("hr",null),Gn=Object(O.h)("h3",null,"Editor"),Zn=Object(O.h)("label",{class:"line"},"Default Preprocessors"),Xn=Object(O.h)("option",{value:"html"},"HTML"),Qn=Object(O.h)("option",{value:"markdown"},"Markdown"),$n=Object(O.h)("option",{value:"jade"},"Pug"),eo=Object(O.h)("option",{value:"css"},"CSS"),to=Object(O.h)("option",{value:"scss"},"SCSS"),no=Object(O.h)("option",{value:"sass"},"SASS"),oo=Object(O.h)("option",{value:"less"},"LESS"),so=Object(O.h)("option",{value:"stylus"},"Stylus"),io=Object(O.h)("option",{value:"acss"},"Atomic CSS"),ao=Object(O.h)("option",{value:"js"},"JS"),ro=Object(O.h)("option",{value:"coffee"},"CoffeeScript"),lo=Object(O.h)("option",{value:"es6"},"ES6 (Babel)"),co=Object(O.h)("option",{value:"typescript"},"TypeScript"),ho=Object(O.h)("option",{value:"FiraCode"},"Fira Code"),po=Object(O.h)("option",{value:"Inconsolata"},"Inconsolata"),uo=Object(O.h)("option",{value:"Monoid"},"Monoid"),mo=Object(O.h)("option",{value:"FixedSys"},"FixedSys"),go=Object(O.h)("option",{disabled:"disabled"},"----"),fo=Object(O.h)("option",{value:"other"},"Other font from system"),bo=Object(O.h)("hr",null),vo=Object(O.h)("h3",null,"Fun"),Co=Object(O.h)("hr",null),yo=Object(O.h)("h3",null,"Advanced"),So=Object(O.h)("div",{class:"help-text"},"If any loop iteration takes more than the defined time, it is detected as a potential infinite loop and further iterations are stopped.");let wo=class extends O.Component{updateSetting(t){this.props.onChange(t)}shouldComponentUpdate(){return!0}render(){return Object(O.h)("div",null,Kn,qn,Object(O.h)("div",{class:"line",title:"I know this is tough, but you have to decide one!"},Object(O.h)("label",null,Object(O.h)("input",{type:"radio",name:"indentation",value:"spaces",checked:"spaces"===this.props.prefs.indentation,onChange:this.updateSetting.bind(this),"data-setting":"indentWith"})," ","Spaces"),Object(O.h)("label",{class:"ml-1"},Object(O.h)("input",{type:"radio",name:"indentation",value:"tabs",checked:"tabs"===this.props.prefs.indentation,onChange:this.updateSetting.bind(this),"data-setting":"indentWith"})," ","Tabs")),Object(O.h)("label",{class:"line",title:""},"Indentation Size"," ",Object(O.h)("input",{type:"range",class:"va-m ml-1",value:this.props.prefs.indentSize,min:"1",max:"7",list:"indentationSizeList","data-setting":"indentSize",onChange:this.updateSetting.bind(this)}),Object(O.h)("span",{id:"indentationSizeValueEl"},this.props.prefs.indentSize),Jn),Yn,Gn,Object(O.h)("div",{class:"flex block--mobile"},Object(O.h)("div",null,Zn,Object(O.h)("div",{class:"flex line"},Object(O.h)("select",{style:"flex:1;margin-left:20px","data-setting":"htmlMode",value:this.props.prefs.htmlMode,onChange:this.updateSetting.bind(this)},Xn,Qn,$n),Object(O.h)("select",{style:"flex:1;margin-left:20px","data-setting":"cssMode",value:this.props.prefs.cssMode,onChange:this.updateSetting.bind(this)},eo,to,no,oo,so,io),Object(O.h)("select",{style:"flex:1;margin-left:20px","data-setting":"jsMode",value:this.props.prefs.jsMode,onChange:this.updateSetting.bind(this)},ao,ro,lo,co)),Object(O.h)("label",{class:"line"},"Theme",Object(O.h)("select",{style:"flex:1;margin:0 20px","data-setting":"editorTheme",value:this.props.prefs.editorTheme,onChange:this.updateSetting.bind(this)},Un.map((e)=>Object(O.h)("option",{value:e},e)))),Object(O.h)("label",{class:"line"},"Font",Object(O.h)("select",{style:"flex:1;margin:0 20px","data-setting":"editorFont",value:this.props.prefs.editorFont,onChange:this.updateSetting.bind(this)},ho,po,uo,mo,go,fo),"other"===this.props.prefs.editorFont&&Object(O.h)("input",{id:"customEditorFontInput",type:"text",value:this.props.prefs.editorCustomFont,placeholder:"Custom font name here","data-setting":"editorCustomFont",onChange:this.updateSetting.bind(this)})),Object(O.h)("label",{class:"line"},"Font Size"," ",Object(O.h)("input",{style:"width:70px",type:"number",value:this.props.prefs.fontSize,"data-setting":"fontSize",onChange:this.updateSetting.bind(this)})," ","px"),Object(O.h)("div",{class:"line"},"Key bindings",Object(O.h)("label",{class:"ml-1"},Object(O.h)("input",{type:"radio",name:"keymap",value:"sublime",checked:"sublime"===this.props.prefs.keymap,"data-setting":"keymap",onChange:this.updateSetting.bind(this)})," ","Sublime"),Object(O.h)("label",{class:"ml-1"},Object(O.h)("input",{type:"radio",name:"keymap",value:"vim",checked:"vim"===this.props.prefs.keymap,"data-setting":"keymap",onChange:this.updateSetting.bind(this)})," ","Vim"))),Object(O.h)("div",{class:"ml-2 ml-0--mobile"},Object(O.h)(M,{name:"lineWrap",title:"Toggle wrapping of long sentences onto new line",label:"Line wrap",pref:this.props.prefs.lineWrap,onChange:this.updateSetting.bind(this)}),Object(O.h)(M,{name:"refreshOnResize",title:"Your Preview will refresh when you resize the preview split",label:"Refresh preview on resize",pref:this.props.prefs.refreshOnResize,onChange:this.updateSetting.bind(this)}),Object(O.h)(M,{name:"autoComplete",title:"Turns on the auto-completion suggestions as you type",label:"Auto-complete suggestions",pref:this.props.prefs.autoComplete,onChange:this.updateSetting.bind(this)}),Object(O.h)(M,{name:"autoPreview",title:"Refreshes the preview as you code. Otherwise use the Run button",label:"Auto-preview",pref:this.props.prefs.autoPreview,onChange:this.updateSetting.bind(this)}),Object(O.h)(M,{name:"autoSave",title:"Auto-save keeps saving your code at regular intervals after you hit the first save manually",label:"Auto-save",pref:this.props.prefs.autoSave,onChange:this.updateSetting.bind(this)}),Object(O.h)(M,{name:"preserveLastCode",title:"Loads the last open creation when app starts",label:"Preserve last written code",pref:this.props.prefs.preserveLastCode,onChange:this.updateSetting.bind(this)}),Object(O.h)(M,{name:"replaceNewTab",title:"Turning this on will start showing Web Maker in every new tab you open",label:"Replace new tab page",pref:this.props.prefs.replaceNewTab,onChange:this.updateSetting.bind(this),showWhenExtension:!0}),Object(O.h)(M,{name:"preserveConsoleLogs",title:"Preserves the console logs across your preview refreshes",label:"Preserve console logs",pref:this.props.prefs.preserveConsoleLogs,onChange:this.updateSetting.bind(this)}),Object(O.h)(M,{name:"lightVersion",title:"Switch to lighter version for better performance. Removes things like blur etc.",label:"Fast/light version",pref:this.props.prefs.lightVersion,onChange:this.updateSetting.bind(this)}))),bo,vo,Object(O.h)("p",null,Object(O.h)(M,{title:"Enjoy wonderful particle blasts while you type",label:"Code blast!",name:"isCodeBlastOn",pref:this.props.prefs.isCodeBlastOn,onChange:this.updateSetting.bind(this)})),Co,yo,Object(O.h)("p",null,Object(O.h)("label",{class:"line",title:"This timeout is used to indentify a possible infinite loop and prevent it."},"Maximum time allowed in a loop iteration",Object(O.h)("input",{type:"number",value:this.props.prefs.infiniteLoopTimeout,"data-setting":"infiniteLoopTimeout",onChange:this.updateSetting.bind(this)})," ","ms"),So))}};n("zKjx");const ko="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='#ccc' d='M12,19.2C9.5,19.2 7.29,17.92 6,16C6.03,14 10,12.9 12,12.9C14,12.9 17.97,14 18,16C16.71,17.92 14.5,19.2 12,19.2M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z' /%3E%3C/svg%3E";var xo=Object(O.h)("div",{class:"tac"},Object(O.h)("h1",null,"Support the Developer"),Object(O.h)("p",null,"Hi,"," ",Object(O.h)("a",{href:"https://kushagragour.in",target:"_blank",rel:"noopener noreferrer"},"Kushagra")," ","here! Web Maker is a free and open-source project. To keep myself motivated for working on such open-source and free"," ",Object(O.h)("a",{href:"https://kushagragour.in/lab/",target:"_blank",rel:"noopener noreferrer"},"side projects"),", I am accepting donations. Your pledge, no matter how small, will act as an appreciation towards my work and keep me going forward making Web Maker more awesome\uD83D\uDD25. So please consider donating. \uD83D\uDE4F\uD83C\uDFFC (could be as small as $1/month)."),Object(O.h)("div",{class:"flex flex-h-center",id:"onboardDontShowInTabOptionBtn","d-click":"onDontShowInTabClicked"},Object(O.h)("a",{class:"onboard-selection",href:"https://patreon.com/kushagra",target:"_blank",rel:"noopener noreferrer","aria-label":"Make a monthly pledge on Patreon"},Object(O.h)("img",{src:"patreon.png",height:"60",alt:"Become a patron image"}),Object(O.h)("h3",{class:"onboard-selection-text"},"Make a monthly pledge on Patreon"))),Object(O.h)("a",{href:"https://www.paypal.me/kushagragour",target:"_blank",rel:"noopener noreferrer","aria-label":"Make a one time donation on Paypal"},"Or, make a one time donation")),Mo=Object(O.h)("h1",null,"Keyboard Shortcuts"),_o=Object(O.h)("div",{class:"flex"},Object(O.h)("div",null,Object(O.h)("h2",null,"Global"),Object(O.h)("p",null,Object(O.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + Shift + ?"),Object(O.h)("span",{class:"kbd-shortcut__details"},"See keyboard shortcuts")),Object(O.h)("p",null,Object(O.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + Shift + 5"),Object(O.h)("span",{class:"kbd-shortcut__details"},"Refresh preview")),Object(O.h)("p",null,Object(O.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + S"),Object(O.h)("span",{class:"kbd-shortcut__details"},"Save current creations")),Object(O.h)("p",null,Object(O.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + O"),Object(O.h)("span",{class:"kbd-shortcut__details"},"Open list of saved creations")),Object(O.h)("p",null,Object(O.h)("span",{class:"kbd-shortcut__keys"},"Ctrl + L"),Object(O.h)("span",{class:"kbd-shortcut__details"},"Clear console (works when console input is focused)")),Object(O.h)("p",null,Object(O.h)("span",{class:"kbd-shortcut__keys"},"Esc"),Object(O.h)("span",{class:"kbd-shortcut__details"},"Close saved creations panel & modals"))),Object(O.h)("div",{class:"ml-2"},Object(O.h)("h2",null,"Editor"),Object(O.h)("p",null,Object(O.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + F"),Object(O.h)("span",{class:"kbd-shortcut__details"},"Find")),Object(O.h)("p",null,Object(O.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + G"),Object(O.h)("span",{class:"kbd-shortcut__details"},"Select next match")),Object(O.h)("p",null,Object(O.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + Shift + G"),Object(O.h)("span",{class:"kbd-shortcut__details"},"Select previous match")),Object(O.h)("p",null,Object(O.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + Opt/Alt + F"),Object(O.h)("span",{class:"kbd-shortcut__details"},"Find & replace")),Object(O.h)("p",null,Object(O.h)("span",{class:"kbd-shortcut__keys"},"Shift + Tab"),Object(O.h)("span",{class:"kbd-shortcut__details"},"Realign code")),Object(O.h)("p",null,Object(O.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + ]"),Object(O.h)("span",{class:"kbd-shortcut__details"},"Indent code right")),Object(O.h)("p",null,Object(O.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + ["),Object(O.h)("span",{class:"kbd-shortcut__details"},"Indent code left")),Object(O.h)("p",null,Object(O.h)("span",{class:"kbd-shortcut__keys"},"Tab"),Object(O.h)("span",{class:"kbd-shortcut__details"},"Emmet code completion"," ",Object(O.h)("a",{href:"https://emmet.io/",target:"_blank",rel:"noopener noreferrer"},"Read more"))),Object(O.h)("p",null,Object(O.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + /"),Object(O.h)("span",{class:"kbd-shortcut__details"},"Single line comment")))),Lo=Object(O.h)("h2",null,"Import your creations in your account"),Io=Object(O.h)("p",null,"It's okay if you don't want to. You can simply logout and access them anytime on this browser."),Ho=Object(O.h)("div",{class:"alerts-container",id:"js-alerts-container"});let Ao=class extends O.Component{shouldComponentUpdate(){return!1}render(){return Ho}};var jo=Object(O.h)("h1",null,Object(O.h)("div",{class:"web-maker-with-tag"},"Web Maker"),Object(O.h)("small",{style:"font-size:14px;"}," v3.2.0")),Bo=Object(O.h)("div",null,Object(O.h)("p",null,"Made with ",Object(O.h)("span",{style:"margin-right: 8px;"},"\uD83D\uDC96")," &"," ",Object(O.h)("span",{style:"margin-right: 8px;"},"\uD83D\uDE4C")," by"," ",Object(O.h)("a",{href:"https://twitter.com/chinchang457",target:"_blank",rel:"noopener noreferrer"},"Kushagra Gour")),Object(O.h)("p",null,Object(O.h)("a",{href:"/docs",target:"_blank",rel:"noopener noreferrer"},"Read the documentation"),"."),Object(O.h)("p",null,"Tweet out your feature requests, comments & suggestions to"," ",Object(O.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"https://twitter.com/webmakerApp"},"@webmakerApp"),"."),Object(O.h)("p",null,"Like this extension? Please"," ",Object(O.h)("a",{href:"https://chrome.google.com/webstore/detail/web-maker/lkfkkhfhhdkiemehlpkgjeojomhpccnh/reviews",target:"_blank",rel:"noopener noreferrer"},"rate it here"),"."),Object(O.h)("p",null,Object(O.h)("button",{"aria-label":"Support the developer","d-click":"openSupportDeveloperModal","data-event-action":"supportDeveloperHelpBtnClick",class:"btn btn-icon"},Object(O.h)("svg",null,Object(O.h)("use",{xlinkHref:"#gift-icon"})),"Support the developer")," ",Object(O.h)("a",{"aria-label":"Rate Web Maker",href:"https://chrome.google.com/webstore/detail/web-maker/lkfkkhfhhdkiemehlpkgjeojomhpccnh/reviews",target:"_blank",rel:"noopener noreferrer",class:"btn btn-icon"},Object(O.h)("svg",null,Object(O.h)("use",{xlinkHref:"#heart-icon"})),"Share Web Maker")," ",Object(O.h)("a",{"aria-label":"Chat",href:"https://web-maker.slack.com",target:"_blank",rel:"noopener noreferrer",class:"btn btn-icon"},Object(O.h)("svg",null,Object(O.h)("use",{xlinkHref:"#chat-icon"})),"Chat")," ",Object(O.h)("a",{"aria-label":"Report a Bug",href:"https://github.com/chinchang/web-maker/issues",target:"_blank",rel:"noopener noreferrer",class:"btn btn-icon"},Object(O.h)("svg",null,Object(O.h)("use",{xlinkHref:"#bug-icon"})),"Report a bug")),Object(O.h)("p",null,Object(O.h)("h3",null,"Awesome libraries used"),Object(O.h)("ul",null,Object(O.h)("li",null,Object(O.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"https://kushagragour.in/lab/hint/"},"Hint.css")," ","&",Object(O.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"https://github.com/chinchang/screenlog.js"},"Screenlog.js")," ","- By me :)"),Object(O.h)("li",null,Object(O.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"https://nathancahill.github.io/Split.js/"},"Split.js")," ","- Nathan Cahill"),Object(O.h)("li",null,Object(O.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"https://codemirror.net/"},"Codemirror")," ","- Marijn Haverbeke"),Object(O.h)("li",null,Object(O.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"https://emmet.io/"},"Emmet")," ","- Sergey Chikuyonok"),Object(O.h)("li",null,Object(O.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"http://esprima.org/"},"Esprima")," ","- Ariya Hidayat"),Object(O.h)("li",null,Object(O.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"https://github.com/enjalot/Inlet"},"Inlet")," ","- Ian Johnson"),Object(O.h)("li",null,Object(O.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"https://webmakerapp.com/"},"Web Maker!")," ","- whhat!"))),Object(O.h)("p",null,Object(O.h)("h3",null,"License"),"\"Web Maker\" is"," ",Object(O.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"https://github.com/chinchang/web-maker"},"open-source")," ","under the"," ",Object(O.h)("a",{href:"https://opensource.org/licenses/MIT",target:"_blank",rel:"noopener noreferrer"},"MIT License"),".")),Eo=Object(O.h)("div",{class:"tac"},Object(O.h)("svg",{width:"130px",height:"50px","aria-hidden":"true"},Object(O.h)("use",{xlinkHref:"#logo"})),Object(O.h)("h1",{style:"margin-top:20px"},"Welcome to Web Maker")),Oo=Object(O.h)("div",{class:"flex",style:"margin-top:40px;"},Object(O.h)("div",{class:"onboard-step show-when-app"},Object(O.h)("div",{class:"tac"},Object(O.h)("svg",{class:"onboard-step__icon",viewBox:"0 0 24 24"},Object(O.h)("path",{d:"M13.64,21.97C13.14,22.21 12.54,22 12.31,21.5L10.13,16.76L7.62,18.78C7.45,18.92 7.24,19 7,19A1,1 0 0,1 6,18V3A1,1 0 0,1 7,2C7.24,2 7.47,2.09 7.64,2.23L7.65,2.22L19.14,11.86C19.57,12.22 19.62,12.85 19.27,13.27C19.12,13.45 18.91,13.57 18.7,13.61L15.54,14.23L17.74,18.96C18,19.46 17.76,20.05 17.26,20.28L13.64,21.97Z"}))),Object(O.h)("p",null,"Open Web Maker anytime by visiting"," ",Object(O.h)("a",null,"https://webmakerapp.com/app/")," - Even when you are offline! It just works! \uD83D\uDE31 ",Object(O.h)("strong",null,"Drag the following bookmarklet")," on your bookmark bar to create a quick access shortcut:",Object(O.h)("a",{class:"ml-1 bookmarklet",href:"https://webmakerapp.com/app/"},Object(O.h)("svg",{width:"20",height:"20","aria-hidden":"true"},Object(O.h)("use",{xlinkHref:"#logo"})),"Web Maker"))),Object(O.h)("div",{class:"onboard-step show-when-extension"},Object(O.h)("div",{class:"tac"},Object(O.h)("svg",{class:"onboard-step__icon",viewBox:"0 0 24 24"},Object(O.h)("path",{d:"M13.64,21.97C13.14,22.21 12.54,22 12.31,21.5L10.13,16.76L7.62,18.78C7.45,18.92 7.24,19 7,19A1,1 0 0,1 6,18V3A1,1 0 0,1 7,2C7.24,2 7.47,2.09 7.64,2.23L7.65,2.22L19.14,11.86C19.57,12.22 19.62,12.85 19.27,13.27C19.12,13.45 18.91,13.57 18.7,13.61L15.54,14.23L17.74,18.96C18,19.46 17.76,20.05 17.26,20.28L13.64,21.97Z"}))),Object(O.h)("p",null,"Open Web Maker anytime by clicking the",Object(O.h)("svg",{class:"relative",style:"top:5px;",width:"40",height:"30"},Object(O.h)("use",{xlinkHref:"#logo"}))," ","button in top-right side of your browser.")),Object(O.h)("div",{class:"onboard-step"},Object(O.h)("div",{class:"tac"},Object(O.h)("svg",{class:"onboard-step__icon",viewBox:"0 0 24 24"},Object(O.h)("use",{xlinkHref:"#settings-icon"}))),Object(O.h)("p",null,"Configure and customize settings by clicking the gear icon (",Object(O.h)("svg",{style:"width:18px;height:18px;position:relative;top:3px;fill:#888",viewBox:"0 0 24 24"},Object(O.h)("use",{xlinkHref:"#settings-icon"})),") in bottom right of the app.")),Object(O.h)("div",{class:"onboard-step"},Object(O.h)("div",{class:"tac"},Object(O.h)("svg",{class:"onboard-step__icon",style:"stroke-width:0.3px;"},Object(O.h)("use",{xlinkHref:"#twitter-icon"}))),Object(O.h)("p",null,"Follow"," ",Object(O.h)("a",{href:"https://twitter.com/intent/follow?screen_name=webmakerApp",targe:"_blank",rel:"noopener noreferrer"},"@webmakerApp")," ","to know about the new upcoming features!"))),To=Object(O.h)("p",{class:"tac show-when-app"},"If you are an existing Chrome extension user, you can import your creations from there to here."," ",Object(O.h)("a",{href:"https://medium.com/web-maker/importing-exporting-your-creations-d92e7de5c3dc",target:"_blank"},"Learn how to export/import"),"."),Vo=Object(O.h)("p",{class:"tac"},Object(O.h)("button",{class:"btn btn--primary","d-click":"closeAllOverlays"},"Lets start!")),Po=Object(O.h)("symbol",{id:"logo",viewBox:"-145 -2 372 175"},Object(O.h)("g",{stroke:"none",strokeWidth:1,fill:"none",fillRule:"evenodd",transform:"translate(-145.000000, -1.000000)"},Object(O.h)("polygon",{id:"Path-1",fill:"#FF4600",points:"31 0 232 0 132 173.310547"}),Object(O.h)("polygon",{id:"Path-1",fill:"#FF6C00",points:"0 0 201 0 101 173.310547"}),Object(O.h)("polygon",{id:"Path-1",fill:"#FF6C00",transform:"translate(271.500000, 86.500000) scale(1, -1) translate(-271.500000, -86.500000) ",points:"171 0 372 0 272 173.310547"}),Object(O.h)("polygon",{id:"Path-1",fill:"#FF4600",transform:"translate(241.500000, 86.500000) scale(1, -1) translate(-241.500000, -86.500000) ",points:"141 0 342 0 242 173.310547"}))),Do=Object(O.h)("symbol",{id:"bug-icon",viewBox:"0 0 24 24"},Object(O.h)("path",{d:"M14,12H10V10H14M14,16H10V14H14M20,8H17.19C16.74,7.22 16.12,6.55 15.37,6.04L17,4.41L15.59,3L13.42,5.17C12.96,5.06 12.5,5 12,5C11.5,5 11.04,5.06 10.59,5.17L8.41,3L7,4.41L8.62,6.04C7.88,6.55 7.26,7.22 6.81,8H4V10H6.09C6.04,10.33 6,10.66 6,11V12H4V14H6V15C6,15.34 6.04,15.67 6.09,16H4V18H6.81C7.85,19.79 9.78,21 12,21C14.22,21 16.15,19.79 17.19,18H20V16H17.91C17.96,15.67 18,15.34 18,15V14H20V12H18V11C18,10.66 17.96,10.33 17.91,10H20V8Z"})),Fo=Object(O.h)("symbol",{id:"google-icon",viewBox:"0 0 24 24"},Object(O.h)("path",{d:"M21.35,11.1H12.18V13.83H18.69C18.36,17.64 15.19,19.27 12.19,19.27C8.36,19.27 5,16.25 5,12C5,7.9 8.2,4.73 12.2,4.73C15.29,4.73 17.1,6.7 17.1,6.7L19,4.72C19,4.72 16.56,2 12.1,2C6.42,2 2.03,6.8 2.03,12C2.03,17.05 6.16,22 12.25,22C17.6,22 21.5,18.33 21.5,12.91C21.5,11.76 21.35,11.1 21.35,11.1V11.1Z"})),No=Object(O.h)("symbol",{id:"fb-icon",viewBox:"0 0 24 24"},Object(O.h)("path",{d:"M17,2V2H17V6H15C14.31,6 14,6.81 14,7.5V10H14L17,10V14H14V22H10V14H7V10H10V6A4,4 0 0,1 14,2H17Z"})),Wo=Object(O.h)("symbol",{id:"github-icon",viewBox:"0 0 24 24"},Object(O.h)("path",{d:"M12,2A10,10 0 0,0 2,12C2,16.42 4.87,20.17 8.84,21.5C9.34,21.58 9.5,21.27 9.5,21C9.5,20.77 9.5,20.14 9.5,19.31C6.73,19.91 6.14,17.97 6.14,17.97C5.68,16.81 5.03,16.5 5.03,16.5C4.12,15.88 5.1,15.9 5.1,15.9C6.1,15.97 6.63,16.93 6.63,16.93C7.5,18.45 8.97,18 9.54,17.76C9.63,17.11 9.89,16.67 10.17,16.42C7.95,16.17 5.62,15.31 5.62,11.5C5.62,10.39 6,9.5 6.65,8.79C6.55,8.54 6.2,7.5 6.75,6.15C6.75,6.15 7.59,5.88 9.5,7.17C10.29,6.95 11.15,6.84 12,6.84C12.85,6.84 13.71,6.95 14.5,7.17C16.41,5.88 17.25,6.15 17.25,6.15C17.8,7.5 17.45,8.54 17.35,8.79C18,9.5 18.38,10.39 18.38,11.5C18.38,15.32 16.04,16.16 13.81,16.41C14.17,16.72 14.5,17.33 14.5,18.26C14.5,19.6 14.5,20.68 14.5,21C14.5,21.27 14.66,21.59 15.17,21.5C19.14,20.16 22,16.42 22,12A10,10 0 0,0 12,2Z"})),zo=Object(O.h)("symbol",{id:"settings-icon",viewBox:"0 0 24 24"},Object(O.h)("path",{d:"M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z"})),Ro=Object(O.h)("symbol",{id:"twitter-icon",viewBox:"0 0 16 16"},Object(O.h)("path",{d:"M15.969,3.058c-0.586,0.26-1.217,0.436-1.878,0.515c0.675-0.405,1.194-1.045,1.438-1.809 c-0.632,0.375-1.332,0.647-2.076,0.793c-0.596-0.636-1.446-1.033-2.387-1.033c-1.806,0-3.27,1.464-3.27,3.27 c0,0.256,0.029,0.506,0.085,0.745C5.163,5.404,2.753,4.102,1.14,2.124C0.859,2.607,0.698,3.168,0.698,3.767 c0,1.134,0.577,2.135,1.455,2.722C1.616,6.472,1.112,6.325,0.671,6.08c0,0.014,0,0.027,0,0.041c0,1.584,1.127,2.906,2.623,3.206 C3.02,9.402,2.731,9.442,2.433,9.442c-0.211,0-0.416-0.021-0.615-0.059c0.416,1.299,1.624,2.245,3.055,2.271 c-1.119,0.877-2.529,1.4-4.061,1.4c-0.264,0-0.524-0.015-0.78-0.046c1.447,0.928,3.166,1.469,5.013,1.469 c6.015,0,9.304-4.983,9.304-9.304c0-0.142-0.003-0.283-0.009-0.423C14.976,4.29,15.531,3.714,15.969,3.058z"})),Uo=Object(O.h)("symbol",{id:"heart-icon",viewBox:"0 0 24 24"},Object(O.h)("path",{d:"M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"})),Ko=Object(O.h)("symbol",{id:"play-icon",viewBox:"0 0 24 24"},Object(O.h)("svg",null,Object(O.h)("path",{d:"M8,5.14V19.14L19,12.14L8,5.14Z"}))),qo=Object(O.h)("symbol",{id:"cancel-icon",viewBox:"0 0 24 24"},Object(O.h)("svg",null,Object(O.h)("path",{d:"M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12C4,13.85 4.63,15.55 5.68,16.91L16.91,5.68C15.55,4.63 13.85,4 12,4M12,20A8,8 0 0,0 20,12C20,10.15 19.37,8.45 18.32,7.09L7.09,18.32C8.45,19.37 10.15,20 12,20Z"}))),Jo=Object(O.h)("symbol",{id:"chevron-icon",viewBox:"0 0 24 24"},Object(O.h)("svg",null,Object(O.h)("path",{d:"M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z"}))),Yo=Object(O.h)("symbol",{id:"chat-icon",viewBox:"0 0 24 24"},Object(O.h)("path",{d:"M20,2H4A2,2 0 0,0 2,4V22L6,18H20A2,2 0 0,0 22,16V4A2,2 0 0,0 20,2M8,14H6V12H8V14M8,11H6V9H8V11M8,8H6V6H8V8M15,14H10V12H15V14M18,11H10V9H18V11M18,8H10V6H18V8Z"})),Go=Object(O.h)("path",{d:"M22,12V20A2,2 0 0,1 20,22H4A2,2 0 0,1 2,20V12A1,1 0 0,1 1,11V8A2,2 0 0,1 3,6H6.17C6.06,5.69 6,5.35 6,5A3,3 0 0,1 9,2C10,2 10.88,2.5 11.43,3.24V3.23L12,4L12.57,3.23V3.24C13.12,2.5 14,2 15,2A3,3 0 0,1 18,5C18,5.35 17.94,5.69 17.83,6H21A2,2 0 0,1 23,8V11A1,1 0 0,1 22,12M4,20H11V12H4V20M20,20V12H13V20H20M9,4A1,1 0 0,0 8,5A1,1 0 0,0 9,6A1,1 0 0,0 10,5A1,1 0 0,0 9,4M15,4A1,1 0 0,0 14,5A1,1 0 0,0 15,6A1,1 0 0,0 16,5A1,1 0 0,0 15,4M3,8V10H11V8H3M13,8V10H21V8H13Z"}),Zo=Object(O.h)("symbol",{id:"gift-icon",viewBox:"0 0 24 24"}),Xo=Object(O.h)("symbol",{id:"cross-icon",viewBox:"0 0 24 24"},Object(O.h)("path",{d:"M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"})),Qo=Object(O.h)("symbol",{id:"keyboard-icon",viewBox:"0 0 24 24"},Object(O.h)("path",{d:"M19,10H17V8H19M19,13H17V11H19M16,10H14V8H16M16,13H14V11H16M16,17H8V15H16M7,10H5V8H7M7,13H5V11H7M8,11H10V13H8M8,8H10V10H8M11,11H13V13H11M11,8H13V10H11M20,5H4C2.89,5 2,5.89 2,7V17A2,2 0 0,0 4,19H20A2,2 0 0,0 22,17V7C22,5.89 21.1,5 20,5Z"})),$o=Object(O.h)("symbol",{id:"mode-icon",viewBox:"0 0 100 100"},Object(O.h)("g",null,Object(O.h)("rect",{x:0,y:0,width:28,height:47}),Object(O.h)("rect",{x:36,y:0,width:28,height:47}),Object(O.h)("rect",{x:72,y:0,width:28,height:47}),Object(O.h)("rect",{x:0,y:53,width:100,height:47}))),es=Object(O.h)("symbol",{id:"vertical-mode-icon",viewBox:"0 0 100 100"},Object(O.h)("g",null,Object(O.h)("rect",{x:0,y:0,width:20,height:100}),Object(O.h)("rect",{x:23,y:0,width:20,height:100}),Object(O.h)("rect",{x:46,y:0,width:20,height:100}),Object(O.h)("rect",{x:69,y:0,width:32,height:100}))),ns=Object(O.h)("symbol",{id:"search",viewBox:"0 0 24 24"},Object(O.h)("path",{d:"M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z"})),os=Object(O.h)("g",{fill:"none",fillRule:"evenodd",strokeWidth:10},Object(O.h)("circle",{cx:22,cy:22,r:1},Object(O.h)("animate",{attributeName:"r",begin:"0s",dur:"1.8s",values:"1; 20",calcMode:"spline",keyTimes:"0; 1",keySplines:"0.165, 0.84, 0.44, 1",repeatCount:"indefinite"}),Object(O.h)("animate",{attributeName:"stroke-opacity",begin:"0s",dur:"1.8s",values:"1; 0",calcMode:"spline",keyTimes:"0; 1",keySplines:"0.3, 0.61, 0.355, 1",repeatCount:"indefinite"})),Object(O.h)("circle",{cx:22,cy:22,r:1},Object(O.h)("animate",{attributeName:"r",begin:"-0.9s",dur:"1.8s",values:"1; 20",calcMode:"spline",keyTimes:"0; 1",keySplines:"0.165, 0.84, 0.44, 1",repeatCount:"indefinite"}),Object(O.h)("animate",{attributeName:"stroke-opacity",begin:"-0.9s",dur:"1.8s",values:"1; 0",calcMode:"spline",keyTimes:"0; 1",keySplines:"0.3, 0.61, 0.355, 1",repeatCount:"indefinite"}))),ss=Object.assign||function(e){for(var t,n=1;nHello, World!\"}"})),hs=Object(O.h)(function(){return Rn},null),ps=Object(O.h)(Nn,null),us=Object(O.h)(function(){return Object(O.h)("svg",{version:"1.1",xmlns:"http://www.w3.org/2000/svg",style:{display:"none"}},Po,Do,Fo,No,Wo,zo,Ro,Uo,Ko,qo,Jo,Yo,Object(O.h)("symbol",{id:"gift-icon",viewBox:"0 0 24 24"},Go,Zo,Xo,Qo,$o,es,ns,Object(O.h)("symbol",{id:"loader-icon",viewBox:"0 0 44 44"},os)))},null),ms=Object(O.h)("form",{style:"display:none;",action:"https://codepen.io/pen/define",method:"POST",target:"_blank",id:"codepenForm"},Object(O.h)("input",{type:"hidden",name:"data",value:"{\"title\": \"New Pen!\", \"html\": \"
Hello, World!
\"}"}));let gs=class extends O.Component{constructor(){super(),this.AUTO_SAVE_INTERVAL=15000,this.state={isSavedItemPaneOpen:!1,isModalOpen:!1,isAddLibraryModalOpen:!1,isSettingsModalOpen:!1,isHelpModalOpen:!1,isNotificationsModalOpen:!1,isLoginModalOpen:!1,isProfileModalOpen:!1,isSupportDeveloperModalOpen:!1,isKeyboardShortcutsModalOpen:!1,isAskToImportModalOpen:!1,isOnboardModalOpen:!1,prefs:{},currentItem:{title:"",externalLibs:{js:"",css:""}}},this.defaultSettings={preserveLastCode:!0,replaceNewTab:!1,htmlMode:"html",jsMode:"js",cssMode:"css",isCodeBlastOn:!1,indentWith:"spaces",indentSize:2,editorTheme:"monokai",keymap:"sublime",fontSize:16,refreshOnResize:!1,autoPreview:!0,editorFont:"FiraCode",editorCustomFont:"",autoSave:!0,autoComplete:!0,preserveConsoleLogs:!0,lightVersion:!1,lineWrap:!0,infiniteLoopTimeout:1e3,layoutMode:2},this.prefs={},En.a.auth().onAuthStateChanged((e)=>{this.setState({isLoginModalOpen:!1}),e?(c("You are -> ",e),un.add("You are now logged in!"),this.setState({user:e}),window.user=e,!window.localStorage[is.ASKED_TO_IMPORT_CREATIONS]&&this.fetchItems(!1,!0).then((e)=>{e.length&&(this.oldSavedItems=e,this.oldSavedCreationsCount=e.length,this.setState({isAskToImportModalOpen:!0}),v("ui","askToImportModalSeen"))}),window.db.getUser(e.uid).then((t)=>{if(t){const t=ss({},this.state.prefs);ss(t,e.settings),this.setState({prefs:t}),this.updateSetting()}})):(this.setState({user:void 0}),delete window.user),this.updateProfileUi()})}componentWillMount(){var e;window.onunload=()=>{this.saveCode("code"),this.detachedWindow&&this.detachedWindow.close()},db.local.get({layoutMode:1,code:""},(t)=>{this.toggleLayout(t.layoutMode),this.state.prefs.layoutMode=t.layoutMode,t.code&&(e=t.code)}),db.getSettings(this.defaultSettings).then((t)=>{t.preserveLastCode&&e?(this.setState({unsavedEditCount:0}),e.id&&window.IS_EXTENSION?db.local.get(e.id,(t)=>{t[e.id]&&(c("Load item ",e.id),this.setCurrentItem(t[e.id]).then(()=>this.refreshEditor()))}):(c("Load last unsaved item",e),this.setCurrentItem(e).then(()=>this.refreshEditor()))):this.createNewItem(),ss(this.state.prefs,t),this.setState({prefs:this.state.prefs}),this.updateSetting()}),db.getUserLastSeenVersion().then((e)=>{e||(this.setState({isOnboardModalOpen:!0}),-1===document.cookie.indexOf("onboarded")&&(v("ui","onboardModalSeen",rs),document.cookie="onboarded=1"),window.db.setUserLastSeenVersion(rs)),e&&-1===r(e,rs)&&!window.localStorage.pledgeModalSeen&&(this.openSupportDeveloperModal(),window.localStorage.pledgeModalSeen=!0),e&&-1!==r(e,rs)||(this.setState({hasUnseenChangelog:!0}),this.hasSeenNotifications=!1)})}updateProfileUi(){this.state.user?document.body.classList.add("is-logged-in"):document.body.classList.remove("is-logged-in")}refreshEditor(){this.toggleLayout(this.state.currentItem.layoutMode||this.state.prefs.layoutMode),this.updateExternalLibCount(),this.contentWrap.refreshEditor()}forkItem(e){if(this.state.unsavedEditCount){var t=confirm("You have unsaved changes in your current work. Do you want to discard unsaved changes and continue?");if(!t)return}const n=JSON.parse(JSON.stringify(e));delete n.id,n.title="(Forked) "+e.title,n.updatedOn=Date.now(),this.setCurrentItem(n).then(()=>this.refreshEditor()),un.add(`"${e.title}" was forked`),v("fn","itemForked")}createNewItem(){var e=new Date;this.setCurrentItem({title:"Untitled "+e.getDate()+"-"+(e.getMonth()+1)+"-"+e.getHours()+":"+e.getMinutes(),html:"",css:"",js:"",externalLibs:{js:"",css:""},layoutMode:this.state.currentLayoutMode}).then(()=>this.refreshEditor()),un.add("New item created")}openItem(e){this.setCurrentItem(e).then(()=>this.refreshEditor()),un.add("Saved item loaded")}removeItem(e){var t=confirm(`Are you sure you want to delete "${e.title}"?`);t&&(hn.unsetItemForUser(e.id),hn.removeItem(e.id).then(()=>{un.add("Item removed.",e),this.state.currentItem.id===e.id&&this.createNewItem()}),delete this.state.savedItems[e.id],this.setState({savedItems:ss({},this.state.savedItems)}),v("fn","itemRemoved"))}setCurrentItem(e){const t=o();return e.htmlMode=e.htmlMode||this.state.prefs.htmlMode||P.HTML,e.cssMode=e.cssMode||this.state.prefs.cssMode||D.CSS,e.jsMode=e.jsMode||this.state.prefs.jsMode||F.JS,this.setState({currentItem:e},t.resolve),this.isAutoSavingEnabled=!1,this.setState({unsavedEditCount:0}),t.promise}saveBtnClickHandler(){v("ui","saveBtnClick",this.state.currentItem.id?"saved":"new"),this.saveItem()}populateItemsInSavedPane(){this.setState({savedItems:ss({},this.state.savedItems)}),this.toggleSavedItemsPane()}toggleSavedItemsPane(){this.setState({isSavedItemPaneOpen:!this.state.isSavedItemPaneOpen}),this.state.isSavedItemPaneOpen?window.searchInput.focus():window.searchInput.value="",document.body.classList[this.state.isSavedItemPaneOpen?"add":"remove"]("overlay-visible")}async fetchItems(e,t){var n=o();this.state.savedItems={};var s=[];return window.user&&!t?(s=await hn.getAllItems(),c("got items"),e&&s.forEach((e)=>{this.state.savedItems[e.id]=e}),n.resolve(s),n.promise):(db.local.get("items",(t)=>{var o=Object.getOwnPropertyNames(t.items||{});o.length||n.resolve([]),v("fn","fetchItems",o.length);for(let a=0;a{e&&(this.state.savedItems[o[a]]=t[o[a]]),s.push(t[o[a]]),o.length===s.length&&n.resolve(s)})}),n.promise)}openSavedItemsPane(){this.setState({isFetchingItems:!0}),this.fetchItems(!0).then((e)=>{this.setState({isFetchingItems:!1}),this.populateItemsInSavedPane(e)})}openAddLibrary(){this.setState({isAddLibraryModalOpen:!0})}closeSavedItemsPane(){this.setState({isSavedItemPaneOpen:!1}),document.body.classList.remove("overlay-visible"),this.editorWithFocus&&this.editorWithFocus.focus()}componentDidMount(){document.body.style.height=`${window.innerHeight}px`,window.addEventListener("keydown",(e)=>{(e.ctrlKey||e.metaKey)&&83===e.keyCode&&(e.preventDefault(),this.saveItem(),v("ui","saveItemKeyboardShortcut")),(e.ctrlKey||e.metaKey)&&e.shiftKey&&53===e.keyCode?(e.preventDefault(),this.contentWrap.setPreviewContent(!0,!0),v("ui","previewKeyboardShortcut")):(e.ctrlKey||e.metaKey)&&79===e.keyCode?(e.preventDefault(),this.openSavedItemsPane(),v("ui","openCreationKeyboardShortcut")):(e.ctrlKey||e.metaKey)&&e.shiftKey&&191===e.keyCode?(e.preventDefault(),this.setState({isKeyboardShortcutsModalOpen:!this.state.isKeyboardShortcutsModalOpen}),v("ui","showKeyboardShortcutsShortcut")):27===e.keyCode&&this.closeAllOverlays()})}closeAllOverlays(){this.state.isSavedItemPaneOpen&&this.closeSavedItemsPane()}onExternalLibChange(e){c("onExternalLibChange"),this.state.currentItem.externalLibs={js:e.js,css:e.css},this.updateExternalLibCount(),this.setState({currentItem:ss({},this.state.currentItem)}),this.contentWrap.setPreviewContent(!0),un.add("Libraries updated.")}updateExternalLibCount(){var e=0;e+=this.state.currentItem.externalLibs.js.split("\n").filter((e)=>!!e).length,e+=this.state.currentItem.externalLibs.css.split("\n").filter((e)=>!!e).length,this.setState({externalLibCount:e})}toggleLayout(e){return e=500>window.innerWidth?2:e,this.state.currentLayoutMode===e?(this.contentWrap.resetSplitting(),void this.setState({currentLayoutMode:e})):void([1,2,3,4,5].forEach((e)=>{window[`layoutBtn${e}`].classList.remove("selected"),document.body.classList.remove(`layout-${e}`)}),$("#layoutBtn"+e).classList.add("selected"),document.body.classList.add("layout-"+e),this.setState({currentLayoutMode:e},()=>{this.contentWrap.resetSplitting(),this.contentWrap.setPreviewContent(!0)}))}layoutBtnClickHandler(e){this.saveSetting("layoutMode",e),v("ui","toggleLayoutClick",e),this.toggleLayout(e)}getCodePaneSizes(){var e;const t=this.state.currentLayoutMode;var n=2===t||5===t?"width":"height";try{e=[htmlCodeEl.style[n],cssCodeEl.style[n],jsCodeEl.style[n]]}catch(t){e=[33.33,33.33,33.33]}finally{return e}}getMainPaneSizes(){var e;const t=this.state.currentLayoutMode;var n=2===t?"height":"width";try{e=[+$("#js-code-side").style[n].match(/([\d.]+)%/)[1],+$("#js-demo-side").style[n].match(/([\d.]+)%/)[1]]}catch(t){e=[50,50]}finally{return e}}saveSetting(e,t){const n=o();return db.local.set({[e]:t},n.resolve),n.promise}saveCode(e){return this.state.currentItem.updatedOn=Date.now(),this.state.currentItem.layoutMode=this.state.currentLayoutMode,this.state.currentItem.sizes=this.getCodePaneSizes(),this.state.currentItem.mainSizes=this.getMainPaneSizes(),c("saving key",e||this.state.currentItem.id,this.state.currentItem),hn.setItem(e||this.state.currentItem.id,this.state.currentItem).then(function(){window.user&&!navigator.onLine?un.add("Item saved locally. Will save to account when you are online."):un.add("Item saved."),this.setState({unsavedEditCount:0})}.bind(this))}saveItem(){if(!window.user&&!window.localStorage[is.LOGIN_AND_SAVE_MESSAGE_SEEN]){const e=confirm("Saving without signing in will save your work only on this machine and this browser. If you want it to be secure & available anywhere, please login in your account and then save.\n\nDo you still want to continue saving locally?");if(window.localStorage[is.LOGIN_AND_SAVE_MESSAGE_SEEN]=!0,!e)return v("ui",is.LOGIN_AND_SAVE_MESSAGE_SEEN,"login"),this.closeAllOverlays(),void this.setState({isLoginModalOpen:!0});v("ui",is.LOGIN_AND_SAVE_MESSAGE_SEEN,"local")}var e=!this.state.currentItem.id;this.state.currentItem.id=this.state.currentItem.id||"item-"+l(),this.setState({isSaving:!0}),this.saveCode().then(()=>{this.setState({isSaving:!1}),!this.isAutoSavingEnabled&&this.state.prefs.autoSave&&(this.isAutoSavingEnabled=!0,un.add("Auto-save enabled."))}),e&&hn.setItemForUser(this.state.currentItem.id)}onCodeModeChange(e,t){const n=ss({},this.state.currentItem);n[`${e}Mode`]=t,this.setState({currentItem:n})}onCodeChange(e,t,n){this.state.currentItem[e]=t,n&&(this.setState({unsavedEditCount:this.state.unsavedEditCount+1}),0==this.state.unsavedEditCount%as&&this.state.unsavedEditCount>=as&&(window.saveBtn.classList.add("animated"),window.saveBtn.classList.add("wobble"),window.saveBtn.addEventListener("animationend",()=>{window.saveBtn.classList.remove("animated"),window.saveBtn.classList.remove("wobble")})))}onCodeSettingsChange(e,t){this.state.currentItem[`${e}Settings`]={acssConfig:t}}titleInputBlurHandler(t){this.state.currentItem.title=t.target.value,this.state.currentItem.id&&(this.saveItem(),v("ui","titleChanged"))}updateSetting(t){if(t){var e=t.target.dataset.setting,n={},o=t.target;c(e,"checkbox"===o.type?o.checked:o.value);const s=ss({},this.state.prefs);s[e]="checkbox"===o.type?o.checked:o.value,n[e]=s[e],this.setState({prefs:s}),db.sync.set(n,function(){un.add("Setting saved")}),window.user&&window.db.getDb().then((t)=>{t.collection("users").doc(window.user.uid).update({[`settings.${e}`]:this.state.prefs[e]}).then((t)=>{c(`Setting "${e}" for user`,t)}).catch((e)=>c(e))}),v("ui","updatePref-"+e,s[e])}const s=this.state.prefs;runBtn.classList[s.autoPreview?"add":"remove"]("hide"),this.contentWrap.applyCodemirrorSettings(this.state.prefs),s.autoSave?!this.autoSaveInterval&&(this.autoSaveInterval=setInterval(()=>{this.autoSaveLoop()},this.AUTO_SAVE_INTERVAL)):(clearInterval(this.autoSaveInterval),this.autoSaveInterval=null),document.body.classList[s.lightVersion?"add":"remove"]("light-version")}autoSaveLoop(){this.isAutoSavingEnabled&&this.state.unsavedEditCount&&this.saveItem()}loginBtnClickHandler(){this.setState({isLoginModalOpen:!0})}profileBtnClickHandler(){this.setState({isProfileModalOpen:!0})}logout(){if(this.state.unsavedEditCount){var e=confirm("You have unsaved changes. Do you still want to logout?");if(!e)return}v("fn","loggedOut"),On.logout(),this.setState({isProfileModalOpen:!1}),un.add("Log out successfull")}itemClickHandler(e){setTimeout(()=>{this.openItem(e)},350),this.toggleSavedItemsPane()}itemRemoveBtnClickHandler(e){this.removeItem(e)}itemForkBtnClickHandler(e){this.toggleSavedItemsPane(),setTimeout(()=>{this.forkItem(e)},350)}newBtnClickHandler(){if(v("ui","newBtnClick"),this.state.unsavedEditCount){var e=confirm("You have unsaved changes. Do you still want to create something new?");e&&this.createNewItem()}else this.createNewItem()}openBtnClickHandler(){v("ui","openBtnClick"),this.openSavedItemsPane()}detachedPreviewBtnHandler(){v("ui","detachPreviewBtnClick"),this.contentWrap.detachPreview()}notificationsBtnClickHandler(){return this.setState({isNotificationsModalOpen:!0}),this.state.isNotificationsModalOpen&&!this.hasSeenNotifications&&(this.hasSeenNotifications=!0,this.setState({hasUnseenChangelog:!1}),window.db.setUserLastSeenVersion(rs)),v("ui","notificationButtonClick",rs),!1}codepenBtnClickHandler(t){if(this.state.currentItem.cssMode===D.ACSS)return alert("Oops! CodePen doesn't supports Atomic CSS currently. \nHere is something you can still do -> https://medium.com/web-maker/sharing-your-atomic-css-work-on-codepen-a402001b26ab"),void t.preventDefault();var e={title:"A Web Maker experiment",html:this.state.currentItem.html,css:this.state.currentItem.css,js:this.state.currentItem.js,html_pre_processor:N[this.state.currentItem.htmlMode].codepenVal,css_pre_processor:N[this.state.currentItem.cssMode].codepenVal,js_pre_processor:N[this.state.currentItem.jsMode].codepenVal,css_external:this.state.currentItem.externalLibs.css.split("\n").join(";"),js_external:this.state.currentItem.externalLibs.js.split("\n").join(";")};this.state.currentItem.title.match(/Untitled\s\d\d*-\d/)||(e.title=this.state.currentItem.title),e=JSON.stringify(e),window.codepenForm.querySelector("input").value=e,window.codepenForm.submit(),v("ui","openInCodepen"),t.preventDefault()}saveHtmlBtnClickHandler(t){f(this.state.currentItem),v("ui","saveHtmlClick"),t.preventDefault()}runBtnClickHandler(){this.contentWrap.setPreviewContent(!0,!0),v("ui","runBtnClick")}exportItems(){b().then(()=>{this.fetchItems().then((e)=>{var t=new Date,n=["web-maker-export",t.getFullYear(),t.getMonth()+1,t.getDate(),t.getHours(),t.getMinutes(),t.getSeconds()].join("-");n+=".json";var o=new Blob([JSON.stringify(e,!1,2)],{type:"application/json;charset=UTF-8"});p(n,o),v("fn","exportItems")})})}exportBtnClickHandler(t){this.exportItems(),t.preventDefault(),v("ui","exportBtnClicked")}screenshotBtnClickHandler(t){this.contentWrap.getDemoFrame((e)=>{A(e.getBoundingClientRect())}),t.preventDefault()}openSupportDeveloperModal(t){this.setState({isSupportDeveloperModalOpen:!0}),t&&v("ui",t.target.dataset.eventAction)}supportDeveloperBtnClickHandler(t){this.openSupportDeveloperModal(t)}dontAskToImportAnymore(t){this.setState({isAskToImportModalOpen:!1}),window.localStorage[is.ASKED_TO_IMPORT_CREATIONS]=!0,t&&v("ui","dontAskToImportBtnClick")}importCreationsAndSettingsIntoApp(){this.mergeImportedItems(this.oldSavedItems).then(()=>{v("fn","oldItemsImported"),this.dontAskToImportAnymore()})}editorFocusHandler(e){this.editorWithFocus=e}modalOverlayClickHandler(){this.closeAllOverlays()}render(){return Object(O.h)("div",null,Object(O.h)("div",{class:"main-container"},Object(O.h)(S,{externalLibCount:this.state.externalLibCount,openBtnHandler:this.openBtnClickHandler.bind(this),newBtnHandler:this.newBtnClickHandler.bind(this),saveBtnHandler:this.saveBtnClickHandler.bind(this),loginBtnHandler:this.loginBtnClickHandler.bind(this),profileBtnHandler:this.profileBtnClickHandler.bind(this),addLibraryBtnHandler:this.openAddLibrary.bind(this),runBtnClickHandler:this.runBtnClickHandler.bind(this),isFetchingItems:this.state.isFetchingItems,isSaving:this.state.isSaving,title:this.state.currentItem.title,titleInputBlurHandler:this.titleInputBlurHandler.bind(this),user:this.state.user,unsavedEditCount:this.state.unsavedEditCount}),Object(O.h)(Nt,{currentLayoutMode:this.state.currentLayoutMode,currentItem:this.state.currentItem,onCodeChange:this.onCodeChange.bind(this),onCodeSettingsChange:this.onCodeSettingsChange.bind(this),onCodeModeChange:this.onCodeModeChange.bind(this),onRef:(e)=>this.contentWrap=e,prefs:this.state.prefs,onEditorFocus:this.editorFocusHandler.bind(this)}),ls,Object(O.h)(ln,{layoutBtnClickHandler:this.layoutBtnClickHandler.bind(this),helpBtnClickHandler:()=>this.setState({isHelpModalOpen:!0}),settingsBtnClickHandler:()=>this.setState({isSettingsModalOpen:!0}),notificationsBtnClickHandler:this.notificationsBtnClickHandler.bind(this),supportDeveloperBtnClickHandler:this.supportDeveloperBtnClickHandler.bind(this),detachedPreviewBtnHandler:this.detachedPreviewBtnHandler.bind(this),codepenBtnClickHandler:this.codepenBtnClickHandler.bind(this),saveHtmlBtnClickHandler:this.saveHtmlBtnClickHandler.bind(this),keyboardShortcutsBtnClickHandler:()=>this.setState({isKeyboardShortcutsModalOpen:!0}),screenshotBtnClickHandler:this.screenshotBtnClickHandler.bind(this),hasUnseenChangelog:this.state.hasUnseenChangelog})),Object(O.h)(bn,{items:this.state.savedItems,isOpen:this.state.isSavedItemPaneOpen,closeHandler:this.closeSavedItemsPane.bind(this),itemClickHandler:this.itemClickHandler.bind(this),itemRemoveBtnClickHandler:this.itemRemoveBtnClickHandler.bind(this),itemForkBtnClickHandler:this.itemForkBtnClickHandler.bind(this),exportBtnClickHandler:this.exportBtnClickHandler.bind(this)}),ds,cs,Object(O.h)(gt,{show:this.state.isAddLibraryModalOpen,closeHandler:()=>this.setState({isAddLibraryModalOpen:!1})},Object(O.h)(jn,{js:this.state.currentItem.externalLibs?this.state.currentItem.externalLibs.js:"",css:this.state.currentItem.externalLibs?this.state.currentItem.externalLibs.css:"",onChange:this.onExternalLibChange.bind(this)})),Object(O.h)(gt,{show:this.state.isNotificationsModalOpen,closeHandler:()=>this.setState({isNotificationsModalOpen:!1})},hs),Object(O.h)(gt,{extraClasses:"modal--settings",show:this.state.isSettingsModalOpen,closeHandler:()=>this.setState({isSettingsModalOpen:!1})},Object(O.h)(wo,{prefs:this.state.prefs,onChange:this.updateSetting.bind(this)})),Object(O.h)(gt,{extraClasses:"login-modal",show:this.state.isLoginModalOpen,closeHandler:()=>this.setState({isLoginModalOpen:!1})},ps),Object(O.h)(gt,{show:this.state.isProfileModalOpen,closeHandler:()=>this.setState({isProfileModalOpen:!1})},Object(O.h)(_,{user:this.state.user,logoutBtnHandler:this.logout.bind(this)})),Object(O.h)(B,{show:this.state.isHelpModalOpen,closeHandler:()=>this.setState({isHelpModalOpen:!1})}),Object(O.h)(L,{show:this.state.isSupportDeveloperModalOpen,closeHandler:()=>this.setState({isSupportDeveloperModalOpen:!1})}),Object(O.h)(I,{show:this.state.isKeyboardShortcutsModalOpen,closeHandler:()=>this.setState({isKeyboardShortcutsModalOpen:!1})}),Object(O.h)(j,{show:this.state.isAskToImportModalOpen,closeHandler:()=>this.setState({isAskToImportModalOpen:!1}),oldSavedCreationsCount:this.oldSavedCreationsCount,importBtnClickHandler:this.importCreationsAndSettingsIntoApp.bind(this),dontAskBtnClickHandler:this.dontAskToImportAnymore.bind(this)}),Object(O.h)(E,{show:this.state.isOnboardModalOpen,closeHandler:()=>this.setState({isOnboardModalOpen:!1})}),Object(O.h)(mt.a,{into:"body"},Object(O.h)("div",{class:"modal-overlay",onClick:this.modalOverlayClickHandler.bind(this)})),us,ms)}};t["default"]=gs}},["pwNi"]); \ No newline at end of file +webpackJsonp([0],{JkW7:function(e,t,n){"use strict";function o(){var e={},t=new Promise(function(t,n){e.resolve=t,e.reject=n});return e.promise=t,D(e,t)}function s(e,t){var n=o();return t===F.HTML?n.resolve({code:e}):t===F.MARKDOWN?n.resolve(window.marked?{code:marked(e)}:{code:e}):t===F.JADE&&n.resolve(window.jade?{code:jade.render(e)}:{code:e}),n.promise}function i(e,t,n){var s,i=o();if(t===N.CSS)i.resolve({code:e});else if(t===N.SCSS||t===N.SASS)window.sass&&e?window.sass.compile(e,{indentedSyntax:t===N.SASS},function(e){e.line&&e.message&&(s={lang:"css",data:[{lineNumber:e.line-1,message:e.message}]}),i.resolve({code:e.text,errors:s})}):i.resolve({code:e});else if(t===N.LESS)less.render(e).then(function(e){i.resolve({code:e.css})},function(e){s={lang:"css",data:[{lineNumber:e.line,message:e.message}]},i.resolve({code:"",errors:s})});else if(t===N.STYLUS)stylus(e).render(function(e,t){if(e){window.err=e;var n=e.message.split("\n");n.pop(),s={lang:"css",data:[{lineNumber:+e.message.match(/stylus:(\d+):/)[1]-298,message:n.pop()}]}}i.resolve({code:t,errors:s})});else if(t===N.ACSS)if(!window.atomizer)i.resolve({code:""});else{const t=atomizer.findClassNames(e);var a;try{a=atomizer.getConfig(t,JSON.parse(n.acssConfig))}catch(n){a=atomizer.getConfig(t,{})}const o=atomizer.getCss(a);i.resolve({code:o})}return i.promise}function a(e,t,n,s){var i,a=o();if(!e)return a.resolve(""),a.promise;if(t===W.JS)try{R.parse(e,{tolerant:!0})}catch(t){i={lang:"js",data:[{lineNumber:t.lineNumber-1,message:t.description}]}}finally{!1!==n&&(e=i?e:h(e,{timeout:s})),a.resolve({code:e,errors:i})}else if(t===W.COFFEESCRIPT){if(!window.CoffeeScript)return a.resolve(""),a.promise;try{e=CoffeeScript.compile(e,{bare:!0})}catch(t){i={lang:"js",data:[{lineNumber:t.location.first_line,message:t.message}]}}finally{!1!==n&&(e=i?e:h(e,{timeout:s})),a.resolve({code:e,errors:i})}}else if(t===W.ES6){if(!window.Babel)return a.resolve(""),a.promise;try{R.parse(e,{tolerant:!0,jsx:!0})}catch(t){i={lang:"js",data:[{lineNumber:t.lineNumber-1,message:t.description}]}}finally{e=Babel.transform(e,{presets:["latest","stage-2","react"]}).code,!1!==n&&(e=i?e:h(e,{timeout:s})),a.resolve({code:e,errors:i})}}else if(t===W.TS)try{if(!window.ts)return a.resolve({code:""}),a.promise;e=ts.transpileModule(e,{reportDiagnostics:!0,compilerOptions:{noEmitOnError:!0,diagnostics:!0,module:ts.ModuleKind.ES2015}}),e.diagnostics.length&&(i={lang:"js",data:[{message:e.diagnostics[0].messageText,lineNumber:ts.getLineOfLocalPosition(e.diagnostics[0].file,e.diagnostics[0].start)-1}]}),e=e.outputText,!1===n||i||(e=h(e,{timeout:s})),a.resolve({code:e,errors:i})}catch(t){}return a.promise}function r(e,t){for(var n=e.split("."),o=t.split("."),s=0;3>s;s++){var i=+n[s],a=+o[s];if(i>a)return 1;if(a>i)return-1;if(!isNaN(i)&&isNaN(a))return 1;if(isNaN(i)&&!isNaN(a))return-1}return 0}function l(e){for(var t="",n=e||10;n--;)t+=q[~~(Math.random()*q.length)];return t}function c(){window.DEBUG&&console.log(Date.now(),...arguments)}function h(e,{timeout:t}){var n=1,o=[],s="_wmloopvar",i=`\nif (Date.now() - %d > ${t}) { window.top.previewException(new Error("Infinite loop")); break;}\n`;return U.parse(e,{tolerant:!0,range:!0,jsx:!0},function(e){switch(e.type){case"DoWhileStatement":case"ForStatement":case"ForInStatement":case"ForOfStatement":case"WhileStatement":var t=1+e.body.range[0],a=e.body.range[1],r=i.replace("%d",s+n),l="";"BlockStatement"!==e.body.type&&(r="{"+r,l="}",--t),o.push({pos:t,str:r}),o.push({pos:a,str:l}),o.push({pos:e.range[0],str:"var %d = Date.now();\n".replace("%d",s+n)}),++n;break;default:}}),o.sort(function(e,t){return t.pos-e.pos}).forEach(function(t){e=e.slice(0,t.pos)+t.str+e.slice(t.pos)}),e}function d(e){var t=new Date(e),n=t.getDate()+" "+["January","February","March","April","May","June","July","August","September","October","November","December"][t.getMonth()]+" "+t.getFullYear();return n}function p(e,t){function n(){var n=document.createElement("a");n.href=window.URL.createObjectURL(t),n.download=e,n.style.display="none",document.body.appendChild(n),n.click(),n.remove()}window.IS_EXTENSION?chrome.downloads.download({url:window.URL.createObjectURL(t),filename:e,saveAs:!0},()=>{chrome.runtime.lastError&&n()}):n()}function u(e,t,n){function o(e){return function(){c(arguments),v("fn","error",e),u.errorCount=(u.errorCount||0)+1,4===u.errorCount&&setTimeout(function(){alert("Oops! Seems like your preview isn't updating. It's recommended to switch to the web app: https://webmakerapp.com/app/.\n\n If you still want to get the extension working, please try the following steps until it fixes:\n - Refresh Web Maker\n - Restart browser\n - Update browser\n - Reinstall Web Maker (don't forget to export all your creations from saved items pane (click the OPEN button) before reinstalling)\n\nIf nothing works, please tweet out to @webmakerApp."),v("ui","writeFileMessageSeen")},1e3)}}var s=!1;window.webkitRequestFileSystem(window.TEMPORARY,5242880,function(i){i.root.getFile(e,{create:!0},function(e){e.createWriter((e)=>{e.onwriteend=function(){return s?n():(s=!0,e.seek(0),e.write(t),!1)},e.truncate(0)},o("createWriterFail"))},o("getFileFail"))},o("webkitRequestFileSystemFail"))}function m(e){var t=o(),n=window.document.getElementsByTagName("script")[0],s=window.document.createElement("script");return s.src=e,s.async=!0,n.parentNode.insertBefore(s,n),s.onload=function(){t.resolve()},t.promise}function g(e,t,n,o,s){if(!o)return"";var i=o.externalLibs.js.split("\n").reduce(function(e,t){return e+(t?"\n":"")},""),a=o.externalLibs.css.split("\n").reduce(function(e,t){return e+(t?"\n":"")},""),r="\n\n\n\n"+a+"\n\n\n\n"+e+"\n"+i+"\n";if(s||(r+=""),o.jsMode===W.ES6&&(r+=""),"string"==typeof n)r+="\n\n",r}function f(e){var t=s(e.html,e.htmlMode),n=i(e.css,e.cssMode),o=a(e.js,e.jsMode,!1);Promise.all([t,n,o]).then(function(t){var n=t[0].code,o=t[1].code,s=t[2].code,i=g(n,o,s,e,!0),a=new Date,r=["web-maker",a.getFullYear(),a.getMonth()+1,a.getDate(),a.getHours(),a.getMinutes(),a.getSeconds()].join("-");e.title&&(r=e.title),r+=".html";var l=new Blob([i],{type:"text/html;charset=UTF-8"});p(r,l),v("fn","saveFileComplete")})}function b(){var e=o();return window.IS_EXTENSION?(chrome.permissions.contains({permissions:["downloads"]},function(t){t?e.resolve():chrome.permissions.request({permissions:["downloads"]},function(t){t?(v("fn","downloadsPermGiven"),e.resolve()):e.reject()})}),e.promise):(e.resolve(),e.promise)}function v(e,t,n,o){return window.DEBUG?void c("trackevent",e,t,n,o):void(window.ga&&ga("send","event",e,t,n,o))}function C(e,t){var n={};for(var o in e)0<=t.indexOf(o)||Object.prototype.hasOwnProperty.call(e,o)&&(n[o]=e[o]);return n}function y(e){return Object(V.h)(Y,J({Tag:"a"},e))}function S(e){return Object(V.h)(Y,J({Tag:"button"},e))}function w(e){return Object(V.h)("div",{class:"main-header"},Object(V.h)("input",{type:"text",id:"titleInput",title:"Click to edit",class:"item-title-input",value:e.title,onBlur:e.titleInputBlurHandler}),Object(V.h)("div",{class:"main-header__btn-wrap flex flex-v-center"},Object(V.h)("a",{id:"runBtn",class:"hide flex flex-v-center hint--rounded hint--bottom-left","aria-label":"Run preview (Ctrl/\u2318 + Shift + 5)",onClick:e.runBtnClickHandler},Z,"Run"),Object(V.h)(y,{onClick:e.addLibraryBtnHandler,"data-event-category":"ui","data-event-action":"addLibraryButtonClick",class:"flex-v-center hint--rounded hint--bottom-left","aria-label":"Add a JS/CSS library"},"Add library"," ",Object(V.h)("span",{id:"js-external-lib-count",style:`display:${e.externalLibCount?"inline":"none"}`,class:"count-label"},e.externalLibCount)),Object(V.h)("a",{class:"flex flex-v-center hint--rounded hint--bottom-left","aria-label":"Start a new creation",onClick:e.newBtnHandler},X,"New"),Object(V.h)("a",{id:"saveBtn",class:`flex flex-v-center hint--rounded hint--bottom-left ${e.isSaving?"is-loading":""} ${e.unsavedEditCount?"is-marked":0}`,"aria-label":"Save current creation (Ctrl/\u2318 + S)",onClick:e.saveBtnHandler},Q,ee,"Save"),Object(V.h)("a",{id:"openItemsBtn",class:`flex flex-v-center hint--rounded hint--bottom-left ${e.isFetchingItems?"is-loading":""}`,"aria-label":"Open a saved creation (Ctrl/\u2318 + O)",onClick:e.openBtnHandler},te,ne,"Open"),Object(V.h)(y,{onClick:e.loginBtnHandler,"data-event-category":"ui","data-event-action":"loginButtonClick",class:"hide-on-login flex flex-v-center hint--rounded hint--bottom-left","aria-label":"Login/Signup"},"Login/Signup"),Object(V.h)(y,{onClick:e.profileBtnHandler,"data-event-category":"ui","data-event-action":"headerAvatarClick","aria-label":"See profile or Logout",class:"hide-on-logout hint--rounded hint--bottom-left"},Object(V.h)("img",{id:"headerAvatarImg",width:"20",src:e.user?e.user.photoURL||G:"",class:"main-header__avatar-img"}))))}function k(e,t){var n=t;return function(){0==--n&&e()}}function x(e,t){var n=se.a.modes[e].dependencies;if(!n)return t();for(var o=[],s=0;s{e.root.getFile(d,{create:!0},(e)=>{e.createWriter((e)=>{e.onwriteend=t,e.write(i)},n)},n)},n)}function B(e){b().then(()=>{function t(n){var o=document.createElement("canvas"),s=e;o.width=s.width,o.height=s.height;var i=o.getContext("2d"),a=window.devicePixelRatio||1;i.drawImage(n,s.left*a,s.top*a,s.width*a,s.height*a,0,0,s.width,s.height),n.removeEventListener("load",t),j(o.toDataURL())}var n=document.createElement("style");n.textContent="[class*=\"hint\"]:after, [class*=\"hint\"]:before { display: none!important; }",document.body.appendChild(n),setTimeout(()=>{chrome.tabs.captureVisibleTab(null,{format:"png",quality:100},function(e){if(n.remove(),e){var o=new Image;o.src=e,o.addEventListener("load",()=>t(o,e))}})},50),v("ui","takeScreenshotBtnClick")})}function E({show:e,closeHandler:t,oldSavedCreationsCount:n,dontAskBtnClickHandler:o,importBtnClickHandler:s}){return Object(V.h)(bt,{extraClasses:"ask-to-import-modal",show:e,closeHandler:t},vs,Object(V.h)("div",null,Object(V.h)("p",null,"You have ",Object(V.h)("span",null,n)," creations saved in your local machine. Do you want to import those creations in your account so they are more secure and accessible anywhere?"),Cs,Object(V.h)("div",{class:"flex flex-h-end"},Object(V.h)("button",{onClick:o,class:"btn"},"Don't ask me again"),Object(V.h)("button",{onClick:s,class:"btn btn--primary ml-1"},"Yes, please import"))))}function O(e){return Object(V.h)(bt,{show:e.show,closeHandler:e.closeHandler},ws,Object(V.h)("div",null,ks,xs,Ms,_s,Object(V.h)("p",null,Object(V.h)(S,{"aria-label":"Support the developer",onClick:e.onSupportBtnClick,"data-event-action":"supportDeveloperHelpBtnClick","data-event-category":"ui",class:"btn btn-icon"},Ls,"Support the developer")," ",Is," ",Hs," ",As),js,Bs))}function T(e){return Object(V.h)(bt,{show:e.show,closeHandler:e.closeHandler},Es,Os,Ts,Object(V.h)("p",{class:"tac"},Object(V.h)("button",{class:"btn btn--primary",onClick:e.closeHandler},"Lets start!")))}Object.defineProperty(t,"__esModule",{value:!0});var V=n("KM04"),P=n.n(V),D=Object.assign||function(e){for(var t,n=1;n{}},window.$all=(e)=>[...document.querySelectorAll(e)],window.IS_EXTENSION=!!window.chrome.extension;const K=window.chrome.extension||window.DEBUG?"/":"/app";var q="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";Node.prototype.nextUntil=function(e){const t=Array.from(this.parentNode.querySelectorAll(e)),n=t.indexOf(this);return t[n+1]},Node.prototype.previousUntil=function(e){const t=Array.from(this.parentNode.querySelectorAll(e)),n=t.indexOf(this);return t[n-1]},window.requestIdleCallback=window.requestIdleCallback||function(e){setTimeout(e,10)},window.IS_EXTENSION?document.body.classList.add("is-extension"):document.body.classList.add("is-app"),!1;var J=Object.assign||function(e){for(var t,n=1;n{"function"==typeof this.props.onFocus&&this.props.onFocus(e)}),this.cm.on("change",this.props.onChange),this.cm.addKeyMap({"Ctrl-Space":"autocomplete"}),e.noAutocomplete||this.cm.on("inputRead",(e,t)=>{this.props.autoComplete&&"+input"===t.origin&&";"!==t.text[0]&&","!==t.text[0]&&" "!==t.text[0]&&ae.commands.autocomplete(this.cm,null,{completeSingle:!1})}),this.props.onCreation(this.cm)}render(){return Object(V.h)("textarea",{ref:(e)=>this.textarea=e,name:"",id:"",cols:"30",rows:"10"})}};var ht=n("mSND"),pt=n.n(ht);let ut=class extends V.Component{componentDidMount(){this.updateSplit()}componentWillUpdate(){this.splitInstance&&this.splitInstance.destroy()}componentDidUpdate(){this.updateSplit()}updateSplit(){const e={direction:this.props.direction,minSize:this.props.minSize,gutterSize:6,sizes:this.props.sizes};this.props.onDragEnd&&(e.onDragEnd=this.props.onDragEnd),this.props.onDragStart&&(e.onDragStart=this.props.onDragStart),this.splitInstance=pt()(this.props.children.map((e)=>"#"+e.attributes.id),e),this.props.onSplit&&this.props.onSplit(this.splitInstance)}render(){const e=this.props,{children:t}=e,n=M(e,["children"]);return Object(V.h)("div",n,this.props.children)}},mt=class extends V.Component{componentDidMount(){this.initEditor()}shouldComponentUpdate(){return!1}initEditor(){this.cm=ae.fromTextArea(this.textarea,this.props.options),this.props.onChange&&this.cm.on("change",this.props.onChange),this.props.onBlur&&this.cm.on("blur",this.props.onBlur),this.props.onCreation(this.cm)}render(){return Object(V.h)("textarea",{ref:(e)=>this.textarea=e,name:"",id:"",cols:"30",rows:"10"})}};var gt=n("q6qL"),ft=n.n(gt);let bt=class extends V.Component{componentDidMount(){window.addEventListener("keydown",this.onKeyDownHandler.bind(this))}componentWillUnmount(){window.removeEventListener("keydown",this.onKeyDownHandler.bind(this))}onKeyDownHandler(t){27===t.keyCode&&this.props.closeHandler()}onOverlayClick(t){t.target===this.overlayEl&&this.props.closeHandler()}componentDidUpdate(e){this.props.show!==e.show&&(document.body.classList[this.props.show?"add":"remove"]("overlay-visible"),this.props.show&&setTimeout(()=>{this.overlayEl.querySelector(".js-modal__close-btn").focus()},0))}render(){return this.props.show?Object(V.h)(ft.a,{into:"body"},Object(V.h)("div",{class:`${this.props.extraClasses||""} modal is-modal-visible`,ref:(e)=>this.overlayEl=e,onClick:this.onOverlayClick.bind(this)},Object(V.h)("div",{class:"modal__content"},Object(V.h)("button",{type:"button",onClick:this.props.closeHandler,"aria-label":"Close modal",title:"Close",class:"js-modal__close-btn modal__close-btn"},"Close"),this.props.children))):null}};var vt=Object(V.h)("h1",null,"Atomic CSS Settings"),Ct=Object(V.h)("h3",null,"Configure Atomizer settings."," ",Object(V.h)("a",{href:"https://github.com/acss-io/atomizer#api",target:"_blank",rel:"noopener noreferrer"},"Read more")," ","about available settings.");let yt=class extends V.Component{componentDidUpdate(){this.props.show&&setTimeout(()=>{this.props.settings&&this.cm.setValue(this.props.settings.acssConfig),this.cm.refresh(),this.cm.focus()},500)}render(){return Object(V.h)(bt,{show:this.props.show,closeHandler:this.props.closeHandler},vt,Ct,Object(V.h)("div",{style:"height: calc(100vh - 350px);"},Object(V.h)(mt,{options:{mode:"application/ld+json",theme:this.props.editorTheme},onCreation:(e)=>this.cm=e,onBlur:(e)=>this.props.onChange(e.getValue())})),Object(V.h)("div",{class:"flex flex-h-end"},Object(V.h)("button",{class:"btn btn--primary",onClick:this.props.closeHandler},"Apply and Close")))}};const St=33;var wt=Object(V.h)("span",{class:"caret"}),kt=Object(V.h)("option",{value:"html"},"HTML"),xt=Object(V.h)("option",{value:"markdown"},"Markdown"),Mt=Object(V.h)("option",{value:"jade"},"Pug"),_t=Object(V.h)("span",{class:"caret"}),Lt=Object(V.h)("option",{value:"css"},"CSS"),It=Object(V.h)("option",{value:"scss"},"SCSS"),Ht=Object(V.h)("option",{value:"sass"},"SASS"),At=Object(V.h)("option",{value:"less"},"LESS"),jt=Object(V.h)("option",{value:"stylus"},"Stylus"),Bt=Object(V.h)("option",{value:"acss"},"Atomic CSS"),Et=Object(V.h)("svg",null,Object(V.h)("use",{xlinkHref:"#settings-icon"})),Ot=Object(V.h)("span",{class:"caret"}),Tt=Object(V.h)("option",{value:"js"},"JS"),Vt=Object(V.h)("option",{value:"coffee"},"CoffeeScript"),Pt=Object(V.h)("option",{value:"es6"},"ES6 (Babel)"),Dt=Object(V.h)("option",{value:"typescript"},"TypeScript"),Ft=Object(V.h)("span",{class:"code-wrap__header-label"},"Console (",Object(V.h)("span",{id:"logCountEl"},"0"),")"),Nt=Object(V.h)("svg",null,Object(V.h)("use",{xlinkHref:"#cancel-icon"})),Wt=Object(V.h)("svg",{width:"18",height:"18",fill:"#346fd2"},Object(V.h)("use",{xlinkHref:"#chevron-icon"}));let zt=class extends V.Component{constructor(e){super(e),this.state={isConsoleOpen:!1,isCssSettingsModalOpen:!1},this.updateTimer=null,this.updateDelay=500,this.htmlMode=F.HTML,this.jsMode=F.HTML,this.cssMode=N.CSS,this.jsMode=W.JS,this.prefs={},this.codeInPreview={html:null,css:null,js:null},this.cmCodes={html:e.currentItem.html,css:"",js:""},this.cm={},this.logCount=0,window.onMessageFromConsole=this.onMessageFromConsole.bind(this),window.previewException=this.previewException.bind(this),window.clearConsole=this.clearConsole.bind(this)}shouldComponentUpdate(e,t){return this.state.isConsoleOpen!==t.isConsoleOpen||this.state.isCssSettingsModalOpen!==t.isCssSettingsModalOpen||this.state.codeSplitSizes!==t.codeSplitSizes||this.state.mainSplitSizes!==t.mainSplitSizes||this.props.currentLayoutMode!==e.currentLayoutMode||this.props.currentItem!==e.currentItem}componentDidUpdate(){window.logCountEl.textContent=this.logCount}componentDidMount(){this.props.onRef(this)}onHtmlCodeChange(e,t){this.cmCodes.html=e.getValue(),this.props.onCodeChange("html",this.cmCodes.html,"setValue"!==t.origin),this.onCodeChange(e,t)}onCssCodeChange(e,t){this.cmCodes.css=e.getValue(),this.props.onCodeChange("css",this.cmCodes.css,"setValue"!==t.origin),this.onCodeChange(e,t)}onJsCodeChange(e,t){this.cmCodes.js=e.getValue(),this.props.onCodeChange("js",this.cmCodes.js,"setValue"!==t.origin),this.onCodeChange(e,t)}onCodeChange(e,t){clearTimeout(this.updateTimer),this.updateTimer=setTimeout(()=>{"setValue"!==t.origin&&(!1!==this.prefs.autoPreview&&this.setPreviewContent(),v.previewCount=(v.previewCount||0)+1,4===v.previewCount&&v("fn","usingPreview"))},this.updateDelay)}createPreviewFile(e,t,n){const o=!window.webkitRequestFileSystem||!window.IS_EXTENSION;var s=g(e,t,o?n:null,this.props.currentItem),i=new Blob([s],{type:"text/plain;charset=UTF-8"}),a=new Blob([n],{type:"text/plain;charset=UTF-8"});!v.hasTrackedCode&&(e||t||n)&&(v("fn","hasCode"),v.hasTrackedCode=!0),o?this.detachedWindow?(c("\u2709\uFE0F Sending message to detached window"),this.detachedWindow.postMessage({contents:s},"*")):(this.frame.src=this.frame.src,setTimeout(()=>{this.frame.contentDocument.open(),this.frame.contentDocument.write(s),this.frame.contentDocument.close()},10)):u("script.js",a,()=>{u("preview.html",i,()=>{var e=chrome.i18n.getMessage()?`chrome-extension://${chrome.i18n.getMessage("@@extension_id")}`:`${location.origin}`,t=`filesystem:${e}/temporary/preview.html`;this.detachedWindow?this.detachedWindow.postMessage(t,"*"):this.frame.src=t})})}cleanupErrors(e){this.cm[e].clearGutter("error-gutter")}showErrors(e,t){var o=this.cm[e];t.forEach(function(t){o.operation(function(){var e=document.createElement("div");e.setAttribute("data-title",t.message),e.classList.add("gutter-error-marker"),o.setGutterMarker(t.lineNumber,"error-gutter",e)})})}setPreviewContent(e,t){if(!this.props.prefs.autoPreview&&!t)return;this.props.prefs.preserveConsoleLogs||this.clearConsole(),this.cleanupErrors("html"),this.cleanupErrors("css"),this.cleanupErrors("js");var n={html:this.cmCodes.html,css:this.cmCodes.css,js:this.cmCodes.js};c("\uD83D\uDD0E setPreviewContent",e);const o=this.detachedWindow?this.detachedWindow.document.querySelector("iframe"):this.frame,r=this.props.currentItem.cssMode;if(!e&&n.html===this.codeInPreview.html&&n.js===this.codeInPreview.js)i(r===N.ACSS?n.html:n.css,r,this.props.currentItem.cssSettings).then((e)=>{r===N.ACSS&&this.cm.css.setValue(e.code||""),o.contentDocument.querySelector("#webmakerstyle")&&(o.contentDocument.querySelector("#webmakerstyle").textContent=e.code||"")});else{var l=s(n.html,this.props.currentItem.htmlMode),d=i(r===N.ACSS?n.html:n.css,r,this.props.currentItem.cssSettings),h=a(n.js,this.props.currentItem.jsMode,!0,this.props.prefs.infiniteLoopTimeout);Promise.all([l,d,h]).then((e)=>{r===N.ACSS&&this.cm.css.setValue(e[1].code||""),this.createPreviewFile(e[0].code||"",e[1].code||"",e[2].code||""),e.forEach((e)=>{e.errors&&this.showErrors(e.errors.lang,e.errors.data)})})}this.codeInPreview.html=n.html,this.codeInPreview.css=n.css,this.codeInPreview.js=n.js}isValidItem(e){return!!e.title}refreshEditor(){this.cmCodes.html=this.props.currentItem.html,this.cmCodes.css=this.props.currentItem.css,this.cmCodes.js=this.props.currentItem.js,this.cm.html.setValue(this.cmCodes.html||""),this.cm.css.setValue(this.cmCodes.css||""),this.cm.js.setValue(this.cmCodes.js||""),this.cm.html.refresh(),this.cm.css.refresh(),this.cm.js.refresh(),this.clearConsole(),Promise.all([this.updateHtmlMode(this.props.currentItem.htmlMode),this.updateCssMode(this.props.currentItem.cssMode),this.updateJsMode(this.props.currentItem.jsMode)]).then(()=>this.setPreviewContent(!0))}applyCodemirrorSettings(e){this.cm&&(htmlCodeEl.querySelector(".CodeMirror").style.fontSize=cssCodeEl.querySelector(".CodeMirror").style.fontSize=jsCodeEl.querySelector(".CodeMirror").style.fontSize=`${parseInt(e.fontSize,10)}px`,window.consoleEl.querySelector(".CodeMirror").style.fontSize=`${parseInt(e.fontSize,10)}px`,window.editorThemeLinkTag.href=`lib/codemirror/theme/${e.editorTheme}.css`,window.fontStyleTag.textContent=window.fontStyleTemplate.textContent.replace(/fontname/g,("other"===e.editorFont?e.editorCustomFont:e.editorFont)||"FiraCode"),this.consoleCm.setOption("theme",e.editorTheme),["html","js","css"].forEach((t)=>{this.cm[t].setOption("indentWithTabs","spaces"!==e.indentWith),this.cm[t].setOption("blastCode",!!e.isCodeBlastOn&&{effect:2,shake:!1}),this.cm[t].setOption("indentUnit",+e.indentSize),this.cm[t].setOption("tabSize",+e.indentSize),this.cm[t].setOption("theme",e.editorTheme),this.cm[t].setOption("keyMap",e.keymap),this.cm[t].setOption("lineWrapping",e.lineWrap),this.cm[t].refresh()}))}updateCodeWrapCollapseStates(){clearTimeout(this.updateCodeWrapCollapseStates.timeout),this.updateCodeWrapCollapseStates.timeout=setTimeout(()=>{const{currentLayoutMode:e}=this.props,t=2===e||5===e?"width":"height";[htmlCodeEl,cssCodeEl,jsCodeEl].forEach(function(e){const n=e.getBoundingClientRect(),o=n[t];100>o?e.classList.add("is-minimized"):e.classList.remove("is-minimized"),-1===e.style[t].indexOf(`100% - ${2*St}px`)?e.classList.remove("is-maximized"):e.classList.add("is-maximized")})},50)}toggleCodeWrapCollapse(e){if(e.classList.contains("is-minimized")||e.classList.contains("is-maximized"))e.classList.remove("is-minimized"),e.classList.remove("is-maximized"),this.codeSplitInstance.setSizes([33.3,33.3,33.3]);else{const n=parseInt(e.dataset.codeWrapId,10);var t=[`${St}px`,`${St}px`,`${St}px`];t[n]=`calc(100% - ${2*St}px)`,this.codeSplitInstance.setSizes(t),e.classList.add("is-maximized")}}collapseBtnHandler(t){var e=t.currentTarget.parentElement.parentElement.parentElement;this.toggleCodeWrapCollapse(e),v("ui","paneCollapseBtnClick",e.dataset.type)}codeWrapHeaderDblClickHandler(t){if(t.target.classList.contains("js-code-wrap__header")){const e=t.target.parentElement;this.toggleCodeWrapCollapse(e),v("ui","paneHeaderDblClick",e.dataset.type)}}resetSplitting(){this.setState({codeSplitSizes:this.getCodeSplitSizes(),mainSplitSizes:this.getMainSplitSizesToApply()})}getMainSplitSizesToApply(){var e;const{currentItem:t,currentLayoutMode:n}=this.props;return e=t&&t.mainSizes?3===n?[t.mainSizes[1],t.mainSizes[0]]:t.mainSizes:5===n?[75,25]:[50,50],e}getCodeSplitSizes(){return this.props.currentItem&&this.props.currentItem.sizes?this.props.currentItem.sizes:[33.33,33.33,33.33]}mainSplitDragEndHandler(){this.props.prefs.refreshOnResize&&setTimeout(()=>{this.setPreviewContent(!0)},1)}codeSplitDragStart(){document.body.classList.add("is-dragging")}codeSplitDragEnd(){this.updateCodeWrapCollapseStates(),document.body.classList.remove("is-dragging")}handleModeRequirements(e){function t(){z[e].hasLoaded=!0,s.resolve()}const n="lib/transpilers";var s=o();return z[e].hasLoaded?(s.resolve(),s.promise):(e===F.JADE?m(`${n}/jade.js`).then(t):e===F.MARKDOWN?m(`${n}/marked.js`).then(t):e===N.LESS?m(`${n}/less.min.js`).then(t):e===N.SCSS||e===N.SASS?m(`${n}/sass.js`).then(function(){window.sass=new Sass(`${n}/sass.worker.js`),t()}):e===N.STYLUS?m(`${n}/stylus.min.js`).then(t):e===N.ACSS?m(`${n}/atomizer.browser.js`).then(t):e===W.COFFEESCRIPT?m(`${n}/coffee-script.js`).then(t):e===W.ES6?m(`${n}/babel.min.js`).then(t):e===W.TS?m(`${n}/typescript.js`).then(t):s.resolve(),s.promise)}updateHtmlMode(e){return this.props.onCodeModeChange("html",e),this.props.currentItem.htmlMode=e,this.cm.html.setOption("mode",z[e].cmMode),ae.autoLoadMode(this.cm.html,z[e].cmPath||z[e].cmMode),this.handleModeRequirements(e)}updateCssMode(e){return this.props.onCodeModeChange("css",e),this.props.currentItem.cssMode=e,this.cm.css.setOption("mode",z[e].cmMode),this.cm.css.setOption("readOnly",z[e].cmDisable),window.cssSettingsBtn.classList[z[e].hasSettings?"remove":"add"]("hide"),ae.autoLoadMode(this.cm.css,z[e].cmPath||z[e].cmMode),this.handleModeRequirements(e)}updateJsMode(e){return this.props.onCodeModeChange("js",e),this.props.currentItem.jsMode=e,this.cm.js.setOption("mode",z[e].cmMode),ae.autoLoadMode(this.cm.js,z[e].cmPath||z[e].cmMode),this.handleModeRequirements(e)}codeModeChangeHandler(t){var e=t.target.value,n=t.target.dataset.type,o=this.props.currentItem["html"===n?"htmlMode":"css"===n?"cssMode":"jsMode"];o!==e&&("html"===n?this.updateHtmlMode(e).then(()=>this.setPreviewContent(!0)):"js"===n?this.updateJsMode(e).then(()=>this.setPreviewContent(!0)):"css"===n&&this.updateCssMode(e).then(()=>this.setPreviewContent(!0)),v("ui","updateCodeMode",e))}detachPreview(){if(this.detachedWindow)return void this.detachedWindow.focus();const e=this.frame.getBoundingClientRect(),t=e.width,n=e.height;document.body.classList.add("is-detached-mode"),window.globalConsoleContainerEl.insertBefore(window.consoleEl,null),this.detachedWindow=window.open("./preview.html","Web Maker",`width=${t},height=${n},resizable,scrollbars=yes,status=1`),setTimeout(()=>{this.setPreviewContent(!0)},1500);var o=window.setInterval(function(){this.detachedWindow&&this.detachedWindow.closed&&(clearInterval(o),document.body.classList.remove("is-detached-mode"),$("#js-demo-side").insertBefore(window.consoleEl,null),this.detachedWindow=null,this.setPreviewContent(!0))}.bind(this),500)}onMessageFromConsole(){[...arguments].forEach((e)=>{e&&e.indexOf&&-1!==e.indexOf("filesystem:chrome-extension")&&(e=e.replace(/filesystem:chrome-extension.*\.js:(\d+):*(\d*)/g,"script $1:$2"));try{this.consoleCm.replaceRange(e+" "+((e+"").match(/\[object \w+]/)?JSON.stringify(e):"")+"\n",{line:Infinity})}catch(t){this.consoleCm.replaceRange("\uD83C\uDF00\n",{line:Infinity})}this.consoleCm.scrollTo(0,Infinity),this.logCount++}),logCountEl.textContent=this.logCount}previewException(e){console.error("Possible infinite loop detected.",e.stack),this.onMessageFromConsole("Possible infinite loop detected.",e.stack)}toggleConsole(){this.setState({isConsoleOpen:!this.state.isConsoleOpen}),v("ui","consoleToggle")}consoleHeaderDblClickHandler(t){t.target.classList.contains("js-console__header")&&(v("ui","consoleToggleDblClick"),this.toggleConsole())}clearConsole(){this.consoleCm.setValue(""),this.logCount=0,window.logCountEl.textContent=this.logCount}clearConsoleBtnClickHandler(){this.clearConsole(),v("ui","consoleClearBtnClick")}evalConsoleExpr(t){(76===t.which||12===t.which)&&t.ctrlKey?(this.clearConsole(),v("ui","consoleClearKeyboardShortcut")):13===t.which&&(this.onMessageFromConsole("> "+t.target.value),this.frame.contentWindow._wmEvaluate(t.target.value),t.target.value="",v("fn","evalConsoleExpr"))}cssSettingsBtnClickHandler(){this.setState({isCssSettingsModalOpen:!0}),v("ui","cssSettingsBtnClick")}cssSettingsChangeHandler(e){this.props.onCodeSettingsChange("css",e),this.setPreviewContent(!0)}getDemoFrame(e){e(this.frame)}editorFocusHandler(e){this.props.onEditorFocus(e)}render(){return Object(V.h)(ut,{class:"content-wrap flex flex-grow",sizes:this.state.mainSplitSizes,minSize:150,style:"",direction:2===this.props.currentLayoutMode?"vertical":"horizontal",onDragEnd:this.mainSplitDragEndHandler.bind(this)},Object(V.h)(ut,{class:"code-side",id:"js-code-side",sizes:this.state.codeSplitSizes,minSize:St,direction:2===this.props.currentLayoutMode||5===this.props.currentLayoutMode?"horizontal":"vertical",onDragStart:this.codeSplitDragStart.bind(this),onDragEnd:this.codeSplitDragEnd.bind(this),onSplit:(e)=>this.codeSplitInstance=e},Object(V.h)("div",{"data-code-wrap-id":"0",id:"htmlCodeEl","data-type":"html",class:"code-wrap",onTransitionEnd:this.updateCodeWrapCollapseStates.bind(this)},Object(V.h)("div",{class:"js-code-wrap__header code-wrap__header",title:"Double click to toggle code pane",onDblClick:this.codeWrapHeaderDblClickHandler.bind(this)},Object(V.h)("label",{class:"btn-group",dropdow:!0,title:"Click to change"},Object(V.h)("span",{class:"code-wrap__header-label"},z[this.props.currentItem.htmlMode||"html"].label),wt,Object(V.h)("select",{"data-type":"html",class:"js-mode-select hidden-select",onChange:this.codeModeChangeHandler.bind(this),value:this.props.currentItem.htmlMode},kt,xt,Mt)),Object(V.h)("div",{class:"code-wrap__header-right-options"},Object(V.h)("a",{class:"js-code-collapse-btn code-wrap__header-btn code-wrap__collapse-btn",title:"Toggle code pane",onClick:this.collapseBtnHandler.bind(this)}))),Object(V.h)(ct,{options:{mode:"htmlmixed",profile:"xhtml",gutters:["CodeMirror-linenumbers","CodeMirror-foldgutter"],noAutocomplete:!0,matchTags:{bothTags:!0},emmet:!0},onChange:this.onHtmlCodeChange.bind(this),onCreation:(e)=>this.cm.html=e,onFocus:this.editorFocusHandler.bind(this)})),Object(V.h)("div",{"data-code-wrap-id":"1",id:"cssCodeEl","data-type":"css",class:"code-wrap",onTransitionEnd:this.updateCodeWrapCollapseStates.bind(this)},Object(V.h)("div",{class:"js-code-wrap__header code-wrap__header",title:"Double click to toggle code pane",onDblClick:this.codeWrapHeaderDblClickHandler.bind(this)},Object(V.h)("label",{class:"btn-group",title:"Click to change"},Object(V.h)("span",{class:"code-wrap__header-label"},z[this.props.currentItem.cssMode||"css"].label),_t,Object(V.h)("select",{"data-type":"css",class:"js-mode-select hidden-select",onChange:this.codeModeChangeHandler.bind(this),value:this.props.currentItem.cssMode},Lt,It,Ht,At,jt,Bt)),Object(V.h)("div",{class:"code-wrap__header-right-options"},Object(V.h)("a",{href:"#",id:"cssSettingsBtn",title:"Atomic CSS configuration",onClick:this.cssSettingsBtnClickHandler.bind(this),class:"code-wrap__header-btn hide"},Et),Object(V.h)("a",{class:"js-code-collapse-btn code-wrap__header-btn code-wrap__collapse-btn",title:"Toggle code pane",onClick:this.collapseBtnHandler.bind(this)}))),Object(V.h)(ct,{options:{mode:"css",gutters:["error-gutter","CodeMirror-linenumbers","CodeMirror-foldgutter"],emmet:!0},onChange:this.onCssCodeChange.bind(this),onCreation:(e)=>this.cm.css=e,onFocus:this.editorFocusHandler.bind(this)})),Object(V.h)("div",{"data-code-wrap-id":"2",id:"jsCodeEl","data-type":"js",class:"code-wrap",onTransitionEnd:this.updateCodeWrapCollapseStates.bind(this)},Object(V.h)("div",{class:"js-code-wrap__header code-wrap__header",title:"Double click to toggle code pane",onDblClick:this.codeWrapHeaderDblClickHandler.bind(this)},Object(V.h)("label",{class:"btn-group",title:"Click to change"},Object(V.h)("span",{class:"code-wrap__header-label"},z[this.props.currentItem.jsMode||"js"].label),Ot,Object(V.h)("select",{"data-type":"js",class:"js-mode-select hidden-select",onChange:this.codeModeChangeHandler.bind(this),value:this.props.currentItem.jsMode},Tt,Vt,Pt,Dt)),Object(V.h)("div",{class:"code-wrap__header-right-options"},Object(V.h)("a",{class:"js-code-collapse-btn code-wrap__header-btn code-wrap__collapse-btn",title:"Toggle code pane",onClick:this.collapseBtnHandler.bind(this)}))),Object(V.h)(ct,{options:{mode:"javascript",gutters:["error-gutter","CodeMirror-linenumbers","CodeMirror-foldgutter"]},autoComplete:this.props.prefs.autoComplete,onChange:this.onJsCodeChange.bind(this),onCreation:(e)=>this.cm.js=e,onFocus:this.editorFocusHandler.bind(this)}))),Object(V.h)("div",{class:"demo-side",id:"js-demo-side",style:""},Object(V.h)("iframe",{ref:(e)=>this.frame=e,src:"about://blank",frameborder:"0",id:"demo-frame",allowfullscreen:!0}),Object(V.h)("div",{id:"consoleEl",class:`console ${this.state.isConsoleOpen?"":"is-minimized"}`},Object(V.h)("div",{id:"consoleLogEl",class:"console__log"},Object(V.h)("div",{class:"js-console__header code-wrap__header",title:"Double click to toggle console",onDblClick:this.toggleConsole.bind(this)},Ft,Object(V.h)("div",{class:"code-wrap__header-right-options"},Object(V.h)("a",{class:"code-wrap__header-btn",title:"Clear console (CTRL + L)",onClick:this.clearConsoleBtnClickHandler.bind(this)},Nt),Object(V.h)("a",{class:"code-wrap__header-btn code-wrap__collapse-btn",title:"Toggle console",onClick:this.toggleConsole.bind(this)}))),Object(V.h)(mt,{options:{mode:"javascript",lineWrapping:!0,theme:"monokai",foldGutter:!0,readOnly:!0,gutters:["CodeMirror-foldgutter"]},onCreation:(e)=>this.consoleCm=e})),Object(V.h)("div",{id:"consolePromptEl",class:"console__prompt flex flex-v-center"},Wt,Object(V.h)("input",{onKeyUp:this.evalConsoleExpr.bind(this),class:"console-exec-input"}))),Object(V.h)(yt,{show:this.state.isCssSettingsModalOpen,closeHandler:()=>this.setState({isCssSettingsModalOpen:!1}),onChange:this.cssSettingsChangeHandler.bind(this),settings:this.props.currentItem.cssSettings,editorTheme:this.props.prefs.editorTheme})))}};var Rt=Object(V.h)("svg",{viewBox:"0 0 24 24"},Object(V.h)("path",{d:"M5,20H19V18H5M19,9H15V3H9V9H5L12,16L19,9Z"})),Ut=Object(V.h)("svg",{style:"display: none;",xmlns:"http://www.w3.org/2000/svg"},Object(V.h)("symbol",{id:"codepen-logo",viewBox:"0 0 120 120"},Object(V.h)("path",{class:"outer-ring",d:"M60.048 0C26.884 0 0 26.9 0 60.048s26.884 60 60 60.047c33.163 0 60.047-26.883 60.047-60.047 S93.211 0 60 0z M60.048 110.233c-27.673 0-50.186-22.514-50.186-50.186S32.375 9.9 60 9.9 c27.672 0 50.2 22.5 50.2 50.186S87.72 110.2 60 110.233z"}),Object(V.h)("path",{class:"inner-box",d:"M97.147 48.319c-0.007-0.047-0.019-0.092-0.026-0.139c-0.016-0.09-0.032-0.18-0.056-0.268 c-0.014-0.053-0.033-0.104-0.05-0.154c-0.025-0.078-0.051-0.156-0.082-0.232c-0.021-0.053-0.047-0.105-0.071-0.156 c-0.033-0.072-0.068-0.143-0.108-0.211c-0.029-0.051-0.061-0.1-0.091-0.148c-0.043-0.066-0.087-0.131-0.135-0.193 c-0.035-0.047-0.072-0.094-0.109-0.139c-0.051-0.059-0.104-0.117-0.159-0.172c-0.042-0.043-0.083-0.086-0.127-0.125 c-0.059-0.053-0.119-0.104-0.181-0.152c-0.048-0.037-0.095-0.074-0.145-0.109c-0.019-0.012-0.035-0.027-0.053-0.039L61.817 23.5 c-1.072-0.715-2.468-0.715-3.54 0L24.34 46.081c-0.018 0.012-0.034 0.027-0.053 0.039c-0.05 0.035-0.097 0.072-0.144 0.1 c-0.062 0.049-0.123 0.1-0.181 0.152c-0.045 0.039-0.086 0.082-0.128 0.125c-0.056 0.055-0.108 0.113-0.158 0.2 c-0.038 0.045-0.075 0.092-0.11 0.139c-0.047 0.062-0.092 0.127-0.134 0.193c-0.032 0.049-0.062 0.098-0.092 0.1 c-0.039 0.068-0.074 0.139-0.108 0.211c-0.024 0.051-0.05 0.104-0.071 0.156c-0.031 0.076-0.057 0.154-0.082 0.2 c-0.017 0.051-0.035 0.102-0.05 0.154c-0.023 0.088-0.039 0.178-0.056 0.268c-0.008 0.047-0.02 0.092-0.025 0.1 c-0.019 0.137-0.029 0.275-0.029 0.416V71.36c0 0.1 0 0.3 0 0.418c0.006 0 0 0.1 0 0.1 c0.017 0.1 0 0.2 0.1 0.268c0.015 0.1 0 0.1 0.1 0.154c0.025 0.1 0.1 0.2 0.1 0.2 c0.021 0.1 0 0.1 0.1 0.154c0.034 0.1 0.1 0.1 0.1 0.213c0.029 0 0.1 0.1 0.1 0.1 c0.042 0.1 0.1 0.1 0.1 0.193c0.035 0 0.1 0.1 0.1 0.139c0.05 0.1 0.1 0.1 0.2 0.2 c0.042 0 0.1 0.1 0.1 0.125c0.058 0.1 0.1 0.1 0.2 0.152c0.047 0 0.1 0.1 0.1 0.1 c0.019 0 0 0 0.1 0.039L58.277 96.64c0.536 0.4 1.2 0.5 1.8 0.537c0.616 0 1.233-0.18 1.77-0.537 l33.938-22.625c0.018-0.012 0.034-0.027 0.053-0.039c0.05-0.035 0.097-0.072 0.145-0.109c0.062-0.049 0.122-0.1 0.181-0.152 c0.044-0.039 0.085-0.082 0.127-0.125c0.056-0.055 0.108-0.113 0.159-0.172c0.037-0.045 0.074-0.09 0.109-0.139 c0.048-0.062 0.092-0.127 0.135-0.193c0.03-0.049 0.062-0.098 0.091-0.146c0.04-0.07 0.075-0.141 0.108-0.213 c0.024-0.051 0.05-0.102 0.071-0.154c0.031-0.078 0.057-0.156 0.082-0.234c0.017-0.051 0.036-0.102 0.05-0.154 c0.023-0.088 0.04-0.178 0.056-0.268c0.008-0.045 0.02-0.092 0.026-0.137c0.018-0.139 0.028-0.277 0.028-0.418V48.735 C97.176 48.6 97.2 48.5 97.1 48.319z M63.238 32.073l25.001 16.666L77.072 56.21l-13.834-9.254V32.073z M56.856 32.1 v14.883L43.023 56.21l-11.168-7.471L56.856 32.073z M29.301 54.708l7.983 5.34l-7.983 5.34V54.708z M56.856 88.022L31.855 71.4 l11.168-7.469l13.833 9.252V88.022z M60.048 67.597l-11.286-7.549l11.286-7.549l11.285 7.549L60.048 67.597z M63.238 88.022V73.14 l13.834-9.252l11.167 7.469L63.238 88.022z M90.794 65.388l-7.982-5.34l7.982-5.34V65.388z"}))),Kt=Object(V.h)("svg",null,Object(V.h)("use",{xlinkHref:"#codepen-logo"})),qt=Object(V.h)("svg",{style:"width:24px;height:24px",viewBox:"0 0 24 24"},Object(V.h)("path",{d:"M4,4H7L9,2H15L17,4H20A2,2 0 0,1 22,6V18A2,2 0 0,1 20,20H4A2,2 0 0,1 2,18V6A2,2 0 0,1 4,4M12,7A5,5 0 0,0 7,12A5,5 0 0,0 12,17A5,5 0 0,0 17,12A5,5 0 0,0 12,7M12,9A3,3 0 0,1 15,12A3,3 0 0,1 12,15A3,3 0 0,1 9,12A3,3 0 0,1 12,9Z"})),Jt=Object(V.h)("div",{class:"footer__separator hide-on-mobile"}),Yt=Object(V.h)("svg",{viewBox:"0 0 100 100",style:"transform:rotate(-90deg)"},Object(V.h)("use",{xlinkHref:"#mode-icon"})),Gt=Object(V.h)("svg",{viewBox:"0 0 100 100"},Object(V.h)("use",{xlinkHref:"#mode-icon"})),Zt=Object(V.h)("svg",{viewBox:"0 0 100 100",style:"transform:rotate(90deg)"},Object(V.h)("use",{xlinkHref:"#mode-icon"})),Xt=Object(V.h)("svg",{viewBox:"0 0 100 100"},Object(V.h)("use",{xlinkHref:"#vertical-mode-icon"})),Qt=Object(V.h)("svg",{viewBox:"0 0 100 100"},Object(V.h)("rect",{x:"0",y:"0",width:"100",height:"100"})),$t=Object(V.h)("svg",{viewBox:"0 0 24 24"},Object(V.h)("path",{d:"M22,17V7H6V17H22M22,5A2,2 0 0,1 24,7V17C24,18.11 23.1,19 22,19H16V21H18V23H10V21H12V19H6C4.89,19 4,18.11 4,17V7A2,2 0 0,1 6,5H22M2,3V15H0V3A2,2 0 0,1 2,1H20V3H2Z"})),en=Object(V.h)("div",{class:"footer__separator"}),tn=Object(V.h)("svg",{viewBox:"0 0 24 24"},Object(V.h)("path",{d:"M14,20A2,2 0 0,1 12,22A2,2 0 0,1 10,20H14M12,2A1,1 0 0,1 13,3V4.08C15.84,4.56 18,7.03 18,10V16L21,19H3L6,16V10C6,7.03 8.16,4.56 11,4.08V3A1,1 0 0,1 12,2Z"})),nn=Object(V.h)("span",{class:"notifications-btn__dot"}),on=Object(V.h)("svg",null,Object(V.h)("use",{xlinkHref:"#settings-icon"})),sn=Object(V.h)("a",{href:"https://webmakerapp.com/",target:"_blank",rel:"noopener noreferrer"},Object(V.h)("div",{class:"logo"})),an=Object(V.h)("span",{class:"web-maker-with-tag"},"Web Maker"),rn=Object(V.h)("svg",{style:"width:20px; height:20px; vertical-align:text-bottom",viewBox:"0 0 24 24"},Object(V.h)("path",{d:"M15.07,11.25L14.17,12.17C13.45,12.89 13,13.5 13,15H11V14.5C11,13.39 11.45,12.39 12.17,11.67L13.41,10.41C13.78,10.05 14,9.55 14,9C14,7.89 13.1,7 12,7A2,2 0 0,0 10,9H8A4,4 0 0,1 12,5A4,4 0 0,1 16,9C16,9.88 15.64,10.67 15.07,11.25M13,19H11V17H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z"})),ln=Object(V.h)("use",{xlinkHref:"#keyboard-icon"}),dn=Object(V.h)("use",{xlinkHref:"#twitter-icon"});let cn=class extends V.Component{constructor(e){super(e),this.state={isKeyboardShortcutsModalOpen:!1}}layoutBtnClickhandler(e){this.props.layoutBtnClickHandler(e)}render(){return Object(V.h)("div",{id:"footer",class:"footer"},Object(V.h)("div",{class:"footer__right fr"},Object(V.h)("a",{onClick:this.props.saveHtmlBtnClickHandler,id:"saveHtmlBtn",class:"mode-btn hint--rounded hint--top-left hide-on-mobile","data-hint":"Save as HTML file"},Rt),Ut,Object(V.h)("a",{href:"",onClick:this.props.codepenBtnClickHandler,id:"codepenBtn",class:"mode-btn hint--rounded hint--top-left hide-on-mobile","aria-label":"Edit on CodePen"},Kt),Object(V.h)("a",{href:"",id:"screenshotBtn",class:"mode-btn hint--rounded hint--top-left show-when-extension",onClick:this.props.screenshotBtnClickHandler,"aria-label":"Take screenshot of preview"},qt),Jt,Object(V.h)("a",{onClick:this.layoutBtnClickhandler.bind(this,1),id:"layoutBtn1",class:"mode-btn hide-on-mobile"},Yt),Object(V.h)("a",{onClick:this.layoutBtnClickhandler.bind(this,2),id:"layoutBtn2",class:"mode-btn hide-on-mobile"},Gt),Object(V.h)("a",{onClick:this.layoutBtnClickhandler.bind(this,3),id:"layoutBtn3",class:"mode-btn hide-on-mobile"},Zt),Object(V.h)("a",{onClick:this.layoutBtnClickhandler.bind(this,5),id:"layoutBtn5",class:"mode-btn hide-on-mobile"},Xt),Object(V.h)("a",{onClick:this.layoutBtnClickhandler.bind(this,4),id:"layoutBtn4",class:"mode-btn hint--top-left hint--rounded hide-on-mobile","aria-label":"Full Screen"},Qt),Object(V.h)("a",{class:"mode-btn hint--top-left hint--rounded hide-on-mobile","aria-label":"Detach Preview",onClick:this.props.detachedPreviewBtnHandler},$t),en,Object(V.h)("a",{onClick:this.props.notificationsBtnClickHandler,id:"notificationsBtn",class:`notifications-btn mode-btn hint--top-left hint--rounded ${this.props.hasUnseenChangelog?"has-new":""}`,"aria-label":"Notifications"},tn,nn),Object(V.h)(y,{onClick:this.props.settingsBtnClickHandler,"data-event-category":"ui","data-event-action":"settingsBtnClick",class:"mode-btn hint--top-left hint--rounded","aria-label":"Settings"},on)),sn,"\xA9",an," \xA0\xA0",Object(V.h)(y,{onClick:this.props.helpBtnClickHandler,"data-event-category":"ui","data-event-action":"helpButtonClick",class:"footer__link hint--rounded hint--top-right","aria-label":"Help"},rn),Object(V.h)(y,{onClick:this.props.keyboardShortcutsBtnClickHandler,"data-event-category":"ui","data-event-action":"keyboardShortcutButtonClick",class:"footer__link hint--rounded hint--top-right hide-on-mobile","aria-label":"Keyboard shortcuts"},Object(V.h)("svg",{style:{width:"20px",height:"20px",verticalAlign:"text-bottom"}},ln)),Object(V.h)("a",{class:"footer__link hint--rounded hint--top-right","aria-label":"Tweet about 'Web Maker'",href:"http://twitter.com/share?url=https://webmakerapp.com/&text=Web Maker - A blazing fast %26 offline web playground! via @webmakerApp&related=webmakerApp&hashtags=web,frontend,playground,offline",target:"_blank",rel:"noopener noreferrer"},Object(V.h)("svg",{style:{width:"20px",height:"20px",verticalAlign:"text-bottom"}},dn)),Object(V.h)(y,{onClick:this.props.supportDeveloperBtnClickHandler,"data-event-category":"ui","data-event-action":"supportDeveloperFooterBtnClick",class:"footer__link ml-1 hint--rounded hint--top-right hide-on-mobile","aria-label":"Support the developer by pledging some amount",target:"_blank",rel:"noopener noreferrer"},"Support the developer"))}};var hn=n("gfUn"),pn=n.n(hn);const un={async getItem(e){var t=await window.db.getDb();return t.doc(`items/${e}`).get().then((e)=>e.data())},async getUserItemIds(){if(window.user)return new Promise((e)=>{e(window.user.items||{})});var e=await window.db.getDb();return e.doc(`users/${window.user.uid}`).get().then((e)=>e.exists?e.data().items:{})},async getAllItems(){var e=Date.now(),t=o();let n=await this.getUserItemIds();n=Object.getOwnPropertyNames(n||{}),Object(hn.log)("itemids",n),n.length||t.resolve([]);var s=await window.db.getDb();const i=[];return s.collection("items").where("createdBy","==",window.user.uid).onSnapshot(function(n){n.forEach(function(e){i.push(e.data())}),Object(hn.log)("Items fetched in ",Date.now()-e,"ms"),t.resolve(i)},function(){t.resolve([])}),t.promise},async setUser(){const e=await window.db.getDb();return e.doc(`users/${window.user.uid}`).set({items:{}})},async setItem(e,t){const n=o();var s;if(db.local.set({[e]:t},()=>{!window.IS_EXTENSION&&window.user&&navigator.onLine||n.resolve()}),"code"===e)return!1;if(window.user){var i=await window.db.getDb();Object(hn.log)(`Starting to save item ${e}`),t.createdBy=window.user.uid,s=i.collection("items").doc(e).set(t,{merge:!0}).then((e)=>{Object(hn.log)("Document written",e),n.resolve()}).catch(n.reject)}return window.user&&navigator.onLine?s:n.promise},saveItems(e){var t=o();return window.user?window.db.getDb().then((n)=>{const o=n.batch();for(var s in e)e[s].createdBy=window.user.uid,o.set(n.doc(`items/${s}`),e[s]),o.update(n.doc(`users/${window.user.uid}`),{[`items.${s}`]:!0}),window.user.items=window.user.items||{},window.user.items[s]=!0;o.commit().then(t.resolve)}):(window.db.local.set(e,t.resolve),window.db.local.get({items:{}},function(t){for(var n in e)t.items[n]=!0;window.db.local.set({items:t.items})})),t.promise},async removeItem(e){if(!window.user){var t=o();return window.db.local.remove(e,t.resolve),t.promise}const n=await window.db.getDb();return Object(hn.log)(`Starting to save item ${e}`),n.collection("items").doc(e).delete().then((e)=>{Object(hn.log)("Document removed",e)}).catch((e)=>Object(hn.log)(e))},async setItemForUser(e){if(!window.user)return window.db.local.get({items:{}},function(t){t.items[e]=!0,window.db.local.set({items:t.items})});const t=await window.db.getDb();return t.collection("users").doc(window.user.uid).update({[`items.${e}`]:!0}).then((t)=>{Object(hn.log)(`Item ${e} set for user`,t),window.user.items=window.user.items||{},window.user.items[e]=!0}).catch((e)=>Object(hn.log)(e))},async unsetItemForUser(e){if(!window.user)return window.db.local.get({items:{}},function(t){delete t.items[e],window.db.local.set({items:t.items})});const t=await window.db.getDb();return t.collection("users").doc(window.user.uid).update({[`items.${e}`]:firebase.firestore.FieldValue.delete()}).then((t)=>{delete window.user.items[e],Object(hn.log)(`Item ${e} unset for user`,t)}).catch((e)=>Object(hn.log)(e))}};var mn;const gn={add:function(e){const t=$("#js-alerts-container");t.textContent=e,t.classList.add("is-active"),clearTimeout(mn),mn=setTimeout(function(){t.classList.remove("is-active")},2e3)}};window.alertsService=gn;var fn=Object(V.h)("div",{class:"mt-1"},"No match found."),bn=Object(V.h)("span",{class:"show-when-selected"},"(Ctrl/\u2318 + F)"),vn=Object(V.h)("h2",{class:"opacity--30"},"Nothing saved here.");let Cn=class extends V.Component{constructor(e){super(e),this.items=[],this.state={filteredItems:[]}}componentWillUpdate(e){this.props.items!==e.items&&(this.items=Object.values(e.items),this.items.sort(function(e,t){return t.updatedOn-e.updatedOn}),this.setState({filteredItems:this.items}))}componentDidUpdate(e){this.props.isOpen&&!e.isOpen&&(window.searchInput.value="")}onCloseIntent(){this.props.closeHandler()}itemClickHandler(e){this.props.itemClickHandler(e)}itemRemoveBtnClickHandler(t,n){n.stopPropagation(),this.props.itemRemoveBtnClickHandler(t)}itemForkBtnClickHandler(t,n){n.stopPropagation(),this.props.itemForkBtnClickHandler(t)}keyDownHandler(e){if(this.props.isOpen){const t=e.ctrlKey||e.metaKey,n=t&&70===e.keyCode,o=40===e.keyCode,s=38===e.keyCode,i=13===e.keyCode,a=$(".js-saved-item-tile.selected"),r=0!==$all(".js-saved-item-tile").length;if((o||s)&&r){const e=o?"nextUntil":"previousUntil";a?(a.classList.remove("selected"),a[e](".js-saved-item-tile:not(.hide)").classList.add("selected")):$(".js-saved-item-tile:not(.hide)").classList.add("selected"),$(".js-saved-item-tile.selected").scrollIntoView(!1)}if(i&&a){const e=this.props.items[a.dataset.itemId];console.log("opening",e),this.props.itemClickHandler(e),v("ui","openItemKeyboardShortcut")}if(n){e.preventDefault();const t=this.props.items[a.dataset.itemId];this.props.itemForkBtnClickHandler(t),v("ui","forkKeyboardShortcut")}}}mergeImportedItems(e){var t=[],n={};const s=o(),i={};this.items.forEach((e)=>i[e.id]=e),e.forEach((e)=>{i[e.id]?t.push(e.id):(c("merging",e.id),n[e.id]=e)});var a=e.length-t.length;if(t.length){var r=confirm(t.length+" creations already exist. Do you want to replace them?");r&&(c("shouldreplace",r),e.forEach((e)=>{n[e.id]=e}),a=e.length)}return a?un.saveItems(n).then(()=>{s.resolve(),gn.add(a+" creations imported successfully."),v("fn","itemsImported",a)}):s.resolve(),this.props.closeHandler(),s.promise}importFileChangeHandler(t){var e=t.target.files[0],n=new FileReader;n.addEventListener("load",(e)=>{var t;try{t=JSON.parse(e.target.result),c(t),this.mergeImportedItems(t)}catch(e){c(e),alert("Oops! Selected file is corrupted. Please select a file that was generated by clicking the \"Export\" button.")}}),n.readAsText(e,"utf-8")}importBtnClickHandler(t){var e=document.createElement("input");e.type="file",e.style.display="none",e.accept="accept=\"application/json",document.body.appendChild(e),e.addEventListener("change",this.importFileChangeHandler.bind(this)),e.click(),v("ui","importBtnClicked"),t.preventDefault()}searchInputHandler(t){const e=t.target.value;e?this.setState({filteredItems:this.items.filter((t)=>-1!==t.title.toLowerCase().indexOf(e))}):this.setState({filteredItems:this.items}),v("ui","searchInputType")}render(){return Object(V.h)("div",{id:"js-saved-items-pane",class:`saved-items-pane ${this.props.isOpen?"is-open":""}`,onKeyDown:this.keyDownHandler.bind(this)},Object(V.h)("button",{onClick:this.onCloseIntent.bind(this),class:"btn saved-items-pane__close-btn",id:"js-saved-items-pane-close-btn"},"X"),Object(V.h)("div",{class:"flex flex-v-center",style:"justify-content: space-between;"},Object(V.h)("h3",null,"My Library (",this.items.length,")"),Object(V.h)("div",{class:"main-header__btn-wrap"},Object(V.h)("a",{onClick:this.props.exportBtnClickHandler,href:"",class:"btn btn-icon hint--bottom-left hint--rounded hint--medium","aria-label":"Export all your creations into a single importable file."},"Export"),Object(V.h)("a",{onClick:this.importBtnClickHandler.bind(this),href:"",class:"btn btn-icon hint--bottom-left hint--rounded hint--medium","aria-label":"Only the file that you export through the 'Export' button can be imported."},"Import"))),Object(V.h)("input",{id:"searchInput",class:"search-input",onInput:this.searchInputHandler.bind(this),placeholder:"Search your creations here..."}),Object(V.h)("div",{id:"js-saved-items-wrap",class:"saved-items-pane__container"},!this.state.filteredItems.length&&this.items.length?fn:null,this.state.filteredItems.map((e)=>Object(V.h)("div",{class:"js-saved-item-tile saved-item-tile","data-item-id":e.id,onClick:this.itemClickHandler.bind(this,e)},Object(V.h)("div",{class:"saved-item-tile__btns"},Object(V.h)("a",{class:"js-saved-item-tile__fork-btn saved-item-tile__btn hint--left hint--medium","aria-label":"Creates a duplicate of this creation (Ctrl/\u2318 + F)",onClick:this.itemForkBtnClickHandler.bind(this,e)},"Fork",bn),Object(V.h)("a",{class:"js-saved-item-tile__remove-btn saved-item-tile__btn hint--left","aria-label":"Remove",onClick:this.itemRemoveBtnClickHandler.bind(this,e)},"X")),Object(V.h)("h3",{class:"saved-item-tile__title"},e.title),Object(V.h)("span",{class:"saved-item-tile__meta"},"Last updated: ",d(e.updatedOn)))),this.items.length?null:vn))}};const yn=[{url:"https://code.jquery.com/jquery-3.2.1.min.js",label:"jQuery",type:"js"},{url:"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js",label:"Bootstrap 3",type:"js"},{url:"https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js",label:"Bootstrap 4",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.3/js/foundation.min.js",label:"Foundation",type:"js"},{url:"https://semantic-ui.com/dist/semantic.min.js",label:"Semantic UI",type:"js"},{url:"https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.min.js",label:"Angular",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.production.min.js",label:"React",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.production.min.js",label:"React DOM",type:"js"},{url:"https://unpkg.com/vue/dist/vue.min.js",label:"Vue.js",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.min.js",label:"Three.js",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js",label:"D3",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.min.js",label:"P5.js",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/addons/p5.dom.min.js",label:"P5.js DOM",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/addons/p5.sound.min.js",label:"P5.js Sound",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js",label:"Underscore",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js",label:"Greensock TweenMax",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/uikit/2.27.5/js/uikit.min.js",label:"UIkit 2",type:"js"},{url:"https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.42/js/uikit.min.js",label:"UIkit 3",type:"js"}],Sn=[{url:"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css",label:"Bootstrap 3",type:"css"},{url:"https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css",label:"Bootstrap 4",type:"css"},{url:"https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.3/css/foundation.min.css",label:"Foundation",type:"css"},{url:"https://semantic-ui.com/dist/semantic.min.css",label:"Semantic UI",type:"css"},{url:"https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css",label:"Bulma",type:"css"},{url:"https://cdnjs.cloudflare.com/ajax/libs/hint.css/2.5.0/hint.min.css",label:"Hint.css",type:"css"},{url:"https://cdn.jsdelivr.net/npm/tailwindcss/dist/tailwind.min.css",label:"Tailwind.css",type:"css"},{url:"https://cdnjs.cloudflare.com/ajax/libs/uikit/2.27.5/css/uikit.min.css",label:"UIkit 2",type:"css"},{url:"https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.42/css/uikit.min.css",label:"UIkit 3",type:"css"},{url:"https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css",label:"Animate.css",type:"css"},{url:"https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css",label:"FontAwesome 4",type:"css"},{url:"https://use.fontawesome.com/releases/v5.0.10/css/all.css",label:"FontAwesome 5",type:"css"}];let wn=class extends V.Component{componentDidMount(){this.t=this.wrap.querySelector("input,textarea"),this.filter=this.props.filter,this.selectedCallback=this.props.onSelect,setTimeout(()=>{requestIdleCallback(()=>{document.body.appendChild(this.list),this.list.style.position="fixed"})},100),this.t.addEventListener("input",(t)=>this.onInput(t)),this.t.addEventListener("keydown",(t)=>this.onKeyDown(t)),this.t.addEventListener("blur",(t)=>this.closeSuggestions(t)),this.list.addEventListener("mousedown",(t)=>this.onListMouseDown(t))}componentWillUnmount(){this.t.removeEventListener("input",(t)=>this.onInput(t)),this.t.removeEventListener("keydown",(t)=>this.onKeyDown(t)),this.t.removeEventListener("blur",(t)=>this.closeSuggestions(t)),this.list.removeEventListener("mousedown",(t)=>this.onListMouseDown(t))}get currentLineNumber(){return this.t.value.substr(0,this.t.selectionStart).split("\n").length}get currentLine(){var e=this.currentLineNumber;return this.t.value.split("\n")[e-1]}closeSuggestions(){this.list.classList.remove("is-open"),this.isShowingSuggestions=!1}getList(e){return fetch("https://api.cdnjs.com/libraries?search="+e).then((e)=>e.json().then((e)=>e.results))}replaceCurrentLine(e){var t=this.t.value.split("\n");t.splice(this.currentLineNumber-1,1,e),this.t.value=t.join("\n")}onInput(){var e=this.currentLine;if(e){if(-1!==e.indexOf("/")||e.match(/https*:\/\//))return;clearTimeout(this.timeout),this.timeout=setTimeout(()=>{this.loader.style.display="block",this.getList(e).then((e)=>{if(this.loader.style.display="none",!e.length)return void this.closeSuggestions();this.list.innerHTML="",this.filter&&(e=e.filter(this.filter));for(var t=0;t${e[t].name}`;this.isShowingSuggestions=!0,this.textareaBounds||(this.textareaBounds=this.t.getBoundingClientRect(),this.list.style.top=this.textareaBounds.bottom+"px",this.list.style.left=this.textareaBounds.left+"px",this.list.style.width=this.textareaBounds.width+"px"),this.list.classList.add("is-open")})},500)}}onKeyDown(e){var t;this.isShowingSuggestions&&(27===e.keyCode&&(this.closeSuggestions(),e.stopPropagation()),40===e.keyCode&&this.isShowingSuggestions?(t=this.list.querySelector(".selected"),t?(t.classList.remove("selected"),t.nextElementSibling.classList.add("selected")):this.list.querySelector("li:first-child").classList.add("selected"),this.list.querySelector(".selected").scrollIntoView(!1),e.preventDefault()):38===e.keyCode&&this.isShowingSuggestions?(t=this.list.querySelector(".selected"),t?(t.classList.remove("selected"),t.previousElementSibling.classList.add("selected")):this.list.querySelector("li:first-child").classList.add("selected"),this.list.querySelector(".selected").scrollIntoView(!1),e.preventDefault()):13===e.keyCode&&this.isShowingSuggestions&&(t=this.list.querySelector(".selected"),this.selectSuggestion(t.dataset.url),this.closeSuggestions()))}onListMouseDown(e){var t=e.target;t.parentElement.dataset.url&&this.selectSuggestion(t.parentElement.dataset.url)}selectSuggestion(e){this.t.focus(),v("ui","autoSuggestionLibSelected",e),this.selectedCallback?this.selectedCallback.call(null,e):this.replaceCurrentLine(e),this.closeSuggestions()}render(){return Object(V.h)("div",{class:`btn-group ${this.props.fullWidth?"flex-grow":""}`,ref:(e)=>this.wrap=e},this.props.children,Object(V.h)("ul",{ref:(e)=>this.list=e,class:"dropdown__menu autocomplete-dropdown"}),Object(V.h)("div",{ref:(e)=>this.loader=e,class:"loader autocomplete__loader",style:"display:none"}))}};var kn=Object(V.h)("h1",null,"Add Library"),xn=Object(V.h)("svg",{style:"width: 30px; height: 30px;fill:#999"},Object(V.h)("use",{xlinkHref:"#search"})),Mn=Object(V.h)("input",{type:"text",id:"externalLibrarySearchInput",class:"full-width",placeholder:"Type here to search libraries"}),_n=Object(V.h)("div",{class:"tar opacity--70"},Object(V.h)("small",null,"Powered by cdnjs")),Ln=Object(V.h)("option",{value:""},"-------"),In=Object(V.h)("h3",{class:"mb-0"},"JS"),Hn=Object(V.h)("p",{class:"mt-0 help-text"},"Put each library in new line"),An=Object(V.h)("p",{style:"font-size: 0.8em;",class:"show-when-extension opacity--70"},"Note: You can load external scripts from following domains: localhost, https://ajax.googleapis.com, https://code.jquery.com, https://cdnjs.cloudflare.com, https://unpkg.com, https://maxcdn.com, https://cdn77.com, https://maxcdn.bootstrapcdn.com, https://cdn.jsdelivr.net/, https://rawgit.com, https://wzrd.in"),jn=Object(V.h)("h3",{class:"mb-0"},"CSS"),Bn=Object(V.h)("p",{class:"mt-0 help-text"},"Put each library in new line");let En=class extends V.Component{constructor(e){super(e),this.state={css:e.css||"",js:e.js||""}}onSelectChange(t){const e=t.target;if(e.value){const t=e.selectedOptions[0].dataset.type;"js"===t?this.setState({js:`${this.state.js}\n${e.value}`}):this.setState({css:`${this.state.css}\n${e.value}`}),v("ui","addLibrarySelect",e.selectedOptions[0].label),this.props.onChange({js:this.state.js,css:this.state.css}),e.value=""}}textareaBlurHandler(t,e){const n=t?t.target:e,o=n.dataset.lang;"js"===o?this.setState({js:n.value||""}):this.setState({css:n.value||""}),this.props.onChange({js:this.state.js,css:this.state.css})}suggestionSelectHandler(e){const t=e.match(/\.js$/)?window.externalJsTextarea:window.externalCssTextarea;t.value=`${t.value}\n${e}`,window.externalLibrarySearchInput.value="",this.textareaBlurHandler(null,t)}render(){return Object(V.h)("div",null,kn,Object(V.h)("div",{class:"flex"},xn,Object(V.h)(wn,{fullWidth:!0,onSelect:this.suggestionSelectHandler.bind(this)},Mn)),_n,Object(V.h)("div",{style:"margin:20px 0;"},"Choose from popular libraries:"," ",Object(V.h)("select",{name:"",id:"js-add-library-select",onChange:this.onSelectChange.bind(this)},Ln,Object(V.h)("optgroup",{label:"JavaScript Libraries"},yn.map((e)=>Object(V.h)("option",{"data-type":e.type,value:e.url},e.label))),Object(V.h)("optgroup",{label:"CSS Libraries"},Sn.map((e)=>Object(V.h)("option",{"data-type":e.type,value:e.url},e.label))))),In,Hn,An,Object(V.h)("textarea",{onBlur:this.textareaBlurHandler.bind(this),"data-lang":"js",class:"full-width",id:"externalJsTextarea",cols:"30",rows:"5",placeholder:"Put each library in new line",value:this.state.js}),jn,Bn,Object(V.h)("textarea",{onBlur:this.textareaBlurHandler.bind(this),"data-lang":"css",class:"full-width",id:"externalCssTextarea",cols:"30",rows:"5",placeholder:"Put each library in new line",value:this.state.css}))}};var On=n("ZUoI"),Tn=n.n(On);const Vn={logout(){Tn.a.auth().signOut()},login(e){var t;return"facebook"===e?t=new Tn.a.auth.FacebookAuthProvider:"twitter"===e?t=new Tn.a.auth.TwitterAuthProvider:"google"===e?(t=new Tn.a.auth.GoogleAuthProvider,t.addScope("https://www.googleapis.com/auth/userinfo.profile")):t=new Tn.a.auth.GithubAuthProvider,Tn.a.auth().signInWithPopup(t).then(function(){v("fn","loggedIn",e),window.db.local.set({lastAuthProvider:e})}).catch(function(e){c(e),"auth/account-exists-with-different-credential"===e.code&&alert("You have already signed up with the same email using different social login")})}};var Pn=Object(V.h)("h2",null,"Login / Signup"),Dn=Object(V.h)("svg",null,Object(V.h)("use",{xlinkHref:"#github-icon"})),Fn=Object(V.h)("svg",null,Object(V.h)("use",{xlinkHref:"#google-icon"})),Nn=Object(V.h)("svg",null,Object(V.h)("use",{xlinkHref:"#fb-icon"})),Wn=Object(V.h)("p",null,"Join a community of 50,000+ Developers");let zn=class extends V.Component{login(t){const e=t.target.dataset.authProvider;v("ui","loginProviderClick",e),Vn.login(e)}componentDidMount(){window.db.local.get({lastAuthProvider:""},(e)=>{e.lastAuthProvider&&document.body.classList.add(`last-login-${e.lastAuthProvider}`)})}render(){return Object(V.h)("div",null,Pn,Object(V.h)("div",null,Object(V.h)("p",null,Object(V.h)("button",{type:"button",onClick:this.login.bind(this),class:"social-login-btn social-login-btn--github btn btn-icon btn--big full-width hint--right hint--always","data-auth-provider":"github","data-hint":"You logged in with Github last time"},Dn,"Login with Github")),Object(V.h)("p",null,Object(V.h)("button",{type:"button",onClick:this.login.bind(this),class:"social-login-btn social-login-btn--google btn btn-icon btn--big full-width hint--right hint--always","data-auth-provider":"google","data-hint":"You logged in with Google last time"},Fn,"Login with Google")),Object(V.h)("p",{class:"mb-2"},Object(V.h)("button",{type:"button",onClick:this.login.bind(this),class:"social-login-btn social-login-btn--facebook btn btn-icon btn--big full-width hint--right hint--always","data-auth-provider":"facebook","data-hint":"You logged in with Facebook last time"},Nn,"Login with Facebook")),Wn))}};Tn.a.initializeApp({apiKey:"AIzaSyBl8Dz7ZOE7aP75mipYl2zKdLSRzBU2fFc",authDomain:"web-maker-app.firebaseapp.com",databaseURL:"https://web-maker-app.firebaseio.com",projectId:"web-maker-app",storageBucket:"web-maker-app.appspot.com",messagingSenderId:"560473480645"});var Rn=n("7vHL"),Un=Object.assign||function(e){for(var t,n=1;n{async function e(){return s?s:(c("Initializing firestore"),s=new Promise((e,t)=>n?e(n):Tn.a.firestore().enablePersistence().then(function(){n=Tn.a.firestore(),c("firebase db ready",n),e(n)}).catch(function(e){t(e.code),"failed-precondition"===e.code?(alert("Opening Web Maker web app in multiple tabs isn't supported at present and it seems like you already have it opened in another tab. Please use in one tab."),v("fn","multiTabError")):"unimplemented"===e.code})),s)}const t=1;var n,s,i={get:(e,n)=>{const o={};"string"==typeof e?(o[e]=JSON.parse(window.localStorage.getItem(e)),setTimeout(()=>n(o),t)):(Object.keys(e).forEach((t)=>{const n=window.localStorage.getItem(t);o[t]=void 0===n||null===n?e[t]:JSON.parse(n)}),setTimeout(()=>n(o),t))},set:(e,n)=>{Object.keys(e).forEach((t)=>{window.localStorage.setItem(t,JSON.stringify(e[t]))}),setTimeout(()=>{if(n)return n()},t)},remove:(e,n)=>{window.localStorage.removeItem(e),setTimeout(()=>n(),t)}};const a=chrome&&chrome.storage?chrome.storage.local:i,r=chrome&&chrome.storage?chrome.storage.sync:i;window.db={getDb:e,getUser:async function(t){const n=await e();return n.doc(`users/${t}`).get().then((e)=>{if(!e.exists)return n.doc(`users/${t}`).set({},{merge:!0});const o=e.data();return Un(window.user,o),o})},getUserLastSeenVersion:async function(){const e=o();return r.get({lastSeenVersion:""},(t)=>{e.resolve(t.lastSeenVersion)}),e.promise},setUserLastSeenVersion:async function(t){if(r.set({lastSeenVersion:t},function(){}),window.user){const n=await e();n.doc(`users/${window.user.uid}`).update({lastSeenVersion:t})}},getSettings:function(e){const t=o();return r.get(e,(e)=>{t.resolve(e)}),t.promise},local:a,sync:r}})();var Kn=Object(V.h)("h1",null,"Whats new?"),qn=Object(V.h)("span",{class:"notification__version"},"3.2.0"),Jn=Object(V.h)("li",null,Object(V.h)("strong",null,"\uD83D\uDE80 Loop timeout setting"),": You now have a setting to tweak the maximum timeout of a loop iteration before it's marked as infinite loop."),Yn=Object(V.h)("li",null,Object(V.h)("strong",null,"\u267F\uFE0F Accessibility"),": Modals now have proper keyboard navigation integrated."),Gn=Object(V.h)("li",null,Object(V.h)("strong",null,"\u267F\uFE0F Accessibility"),": Color contrast improvements."),Zn=Object(V.h)("li",null,"\uD83D\uDE80 Popular libraries list updated. Thanks",Object(V.h)("a",{href:"https://github.com/diomed",target:"_blank"},"@diomed")," ","&"," ",Object(V.h)("a",{href:"https://github.com/leninalbertolp",target:"_blank"},"@leninalbertolp")),Xn=Object(V.h)("li",null,Object(V.h)("strong",null,"\uD83D\uDD27 Bugfix"),": Modal take up appropriate width instead of spanning full width."),Qn=Object(V.h)("br",null),$n=Object(V.h)("li",null,Object(V.h)("strong",null,"\uD83D\uDE80 Announcement"),": Hi! I am Kushagra Gour (creator of Web Maker) and I have launched a",Object(V.h)("a",{href:"https://patreon.com/kushagra",target:"_blank"},"Patreon campaign"),". If you love Web Maker, consider pledging to",Object(V.h)("a",{href:"https://patreon.com/kushagra",target:"_blank"},"support me")," ",":)"),eo=Object(V.h)("li",null,Object(V.h)("a",{href:"https://github.com/chinchang/web-maker/issues",target:"_blank"},"Suggest features or report bugs.")),to=Object(V.h)("a",{href:"https://chrome.google.com/webstore/detail/web-maker/lkfkkhfhhdkiemehlpkgjeojomhpccnh/reviews",target:"_blank",class:"btn"},"Please rate Web Maker ",Object(V.h)("span",{class:"star"})),no=Object(V.h)("a",{href:"http://twitter.com/share?url=https://webmakerapp.com/&text=Web Maker - A blazing fast %26 offline web playground! via @webmakerApp&related=webmakerApp&hashtags=web,editor,chrome,extension",target:"_blank",target:"_blank",class:"btn"},"Share it"),oo=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"3.1.1"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix"),": Fix the \"Run\" button not refreshing the preview after release 3.0.4."))),so=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"3.1.0"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("strong",null,"Mobile Support (app only)."),": Make the Web Maker app usable on mobile. This is only for web app as Chrome extensions don't run on mobile."))),io=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"3.0.4"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix"),": Guarantee code doesn't execute when \"auto preview\" is off."),Object(V.h)("li",null,"Add link to our new",Object(V.h)("a",{href:"https://web-maker.slack.com",target:"_blank",rel:"noopener noreferrer"},"Slack channel")," ","\uD83E\uDD17."))),ao=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"3.0.3"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix (extension)"),": \"Save as HTML\" file saves with correct extension."))),ro=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"3.0.1"),Object(V.h)("ul",null,Object(V.h)("li",null,"After months of work, here is Web Maker 3.0.",Object(V.h)("a",{href:"https://medium.com/web-maker/web-maker-3-0-is-here-f158a40eeaee",target:"_blank",rel:"noopener noreferrer"},"Read the blog post about it"),"."),Object(V.h)("li",null,"Web Maker is no more just a Chrome extension, it is also available as web app that runs offline just like the extension! Checkout it out ->",Object(V.h)("a",{href:"https://webmakerapp.com/app/",target:"_blank",rel:"noopener noreferrer"},"https://webmakerapp.com/app/"),"."),Object(V.h)("li",null,"Now use Web Maker web app on any modern browser (tested with Chrome and Firefox)."),Object(V.h)("li",null,Object(V.h)("strong",null,"User Accounts")," - The much requested user accounts are here. Now maintain your account and store all your creations in the cloud and access them anywhere anytime."),Object(V.h)("li",null,Object(V.h)("strong",null,"New layout mode")," - One more layout mode, that lets you align all the panes vertically."),Object(V.h)("li",null,Object(V.h)("strong",null,"No more restriction on scripts (Web app only)")," - If you are using the web app, there is no more a restriction to load scripts from only specific domains. Load any script!"),Object(V.h)("li",null,Object(V.h)("strong",null,"Inline scripts (Web app only)")," - The restriction of writing JavaScript only in JS pane is also removed."))),lo=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.9.7"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("a",{href:"https://tailwindcss.com/",target:"_blank",rel:"noopener noreferrer"},"Tailwind CSS")," ","added to popular CSS libraries list. Thanks",Object(V.h)("a",{href:"https://github.com/diomed",target:"_blank",rel:"noopener noreferrer"},"diomed"),"."),Object(V.h)("li",null,"Popular libraries list updated. Thanks",Object(V.h)("a",{href:"https://github.com/diomed",target:"_blank",rel:"noopener noreferrer"},"diomed"),"."),Object(V.h)("li",null,Object(V.h)("strong",null,"Dev"),": Bug fixes and code refactoring to make things simple. Thanks",Object(V.h)("a",{href:"https://github.com/iamandrewluca",target:"_blank",rel:"noopener noreferrer"},"iamandrewluca"),"."))),co=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.9.6"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix"),": Fix close buttons not working in notifications and keyboard shortcuts modal."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix"),": Fix keyboard shortcut to see keyboard shortcuts :) Thanks",Object(V.h)("a",{href:"https://github.com/ClassicOldSong",target:"_blank",rel:"noopener noreferrer"},"ClassicOldSong"),"."))),ho=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.9.5"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("a",{href:"https://medium.com/web-maker/release-2-9-5-add-library-search-pane-collapsing-ux-improvements-more-1085216c1301",target:"_blank",rel:"noopener noreferrer"},"Read blog post about this release.")),Object(V.h)("li",null,Object(V.h)("strong",null,"Keyboard shortcuts panel"),": Add a list of all keyboard shotcuts. Access with",Object(V.h)("code",null," Ctrl/\u2318 + Shift + ?")," or click keyboard button in footer."),Object(V.h)("li",null,Object(V.h)("strong",null,"Add external library"),": Better UX for searching third party libraries."),Object(V.h)("li",null,Object(V.h)("strong",null,"Improvement"),": Code panes now go fullscreen when double-clicked on their headers - which is much more intuitive behavior based on feedback from lot of developers."),Object(V.h)("li",null,Object(V.h)("strong",null,"Improvement"),": Add",Object(V.h)("code",null,"allowfullscreen")," attribute on iframes. Thanks",Object(V.h)("a",{href:"https://github.com/ClassicOldSong",target:"_blank",rel:"noopener noreferrer"},"ClassicOldSong"),"."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix")," - Stop screenlog.js from showing up in the exported HTML."),Object(V.h)("li",null,"Popular external libraries list updated. Thanks",Object(V.h)("a",{href:"https://github.com/jlapitan",target:"_blank",rel:"noopener noreferrer"},"jlapitan"),"."))),po=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.9.4"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("strong",null,"Improvement"),": Atomic CSS (Atomizer) has been updated to latest version. Now you can do things like psuedo elements. Learn More."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix")," - Logging circular objects is now possible. It won't show in the Web Maker console, but will show fine in browser's console."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix")," - Console's z-index issue has been fixed."))),uo=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.9.3"),Object(V.h)("ul",null,Object(V.h)("li",null,"Choose the save location while exporting your saved creations. Now easily sync them to your Dropbox or any cloud storage."),Object(V.h)("li",null,"All modals inside the app now have a close button."),Object(V.h)("li",null,"Checkbox that showed on clicking a boolean value is now removed. Thanks",Object(V.h)("a",{href:"https://github.com/gauravmuk",target:"_blank",rel:"noopener noreferrer"},"Gaurav Nanda"),"."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix")," - Screenshots on retina device are now correct. Thanks",Object(V.h)("a",{href:"https://github.com/AshBardhan",target:"_blank",rel:"noopener noreferrer"},"Ashish Bardhan"),"."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix")," - Double console log in detached mode fixed."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix")," - Console.clear now works in detached mode too."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix")," - DOCTYPE added in preview."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix")," - Typo correction in README. Thanks",Object(V.h)("a",{href:"https://github.com/AdilMah",target:"_blank",rel:"noopener noreferrer"},"Adil Mahmood"),"."),Object(V.h)("li",null,"gstatic.com is available to load external JavaScripts from."),Object(V.h)("li",null,"Popular libraries list updated. Thanks",Object(V.h)("a",{href:"https://github.com/diomed",target:"_blank",rel:"noopener noreferrer"},"diomed"),"."),Object(V.h)("li",null,"Added",Object(V.h)("a",{href:"https://github.com/chinchang/web-maker/blob/master/CONTRIBUTING.md",target:"_blank",rel:"noopener noreferrer"},"contribution guidelines")," ","in the Github repository."))),mo=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.9.2"),Object(V.h)("ul",null,Object(V.h)("li",null,"Minor bug fixes."))),go=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.9.1"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("a",{href:"https://medium.com/web-maker/v2-9-lots-of-goodies-bd1e939571f6",target:"_blank",rel:"noopener noreferrer"},"Read blog post about last release.")),Object(V.h)("li",null,"Use Ctrl/Cmd+D to select next occurence of matching selection."),Object(V.h)("li",null,"Improve onboard experience."))),fo=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.9.0"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("a",{href:"https://medium.com/web-maker/v2-9-lots-of-goodies-bd1e939571f6",target:"_blank",rel:"noopener noreferrer"},"Read blog post about this release.")),Object(V.h)("li",null,Object(V.h)("strong",null,"Detached Preview")," - Yes, you read that correct! You can now detach your preview and send it to your secondary monitor."),Object(V.h)("li",null,Object(V.h)("strong",null,"Find & Replace")," - Long awaited, now its there. Ctrl/Cmd+f to find and add Alt to replace."),Object(V.h)("li",null,Object(V.h)("strong",null,"Atomic CSS (Atomizer) configurations")," - Add custom config for Atomic CSS.",Object(V.h)("a",{href:"https://github.com/acss-io/atomizer#api",target:"_blank",rel:"noopener noreferrer"},"Read more"),"."),Object(V.h)("li",null,Object(V.h)("strong",null,"Light mode")," - This new setting makes Web Maker drop some heavy effects like blur etc to gain more performance. Thanks",Object(V.h)("a",{href:"https://github.com/iamandrewluca",target:"_blank",rel:"noopener noreferrer"},"Andrew"),"."),Object(V.h)("li",null,Object(V.h)("strong",null,"Preserve logs setting")," - Choose whether or not to preserve logs across preview refreshes. Thanks",Object(V.h)("a",{href:"https://github.com/BasitAli",target:"_blank",rel:"noopener noreferrer"},"Basit"),"."),Object(V.h)("li",null,Object(V.h)("strong",null,"Line wrap setting")," - As the name says."),Object(V.h)("li",null,"Semantic UI added to popular libraries."),Object(V.h)("li",null,"Bootstrap, Vue, UI-Kit and more updated to latest versions in popular libraries."),Object(V.h)("li",null,"UX improvements in settings UI"),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix")," - Trigger preview refresh anytime with Ctrl/\u2318 + Shift + 5. Even with auto-preview on."))),bo=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.8.1"),Object(V.h)("ul",null,Object(V.h)("li",null,"Vue.js & UIKit version updated to latest version in 'Add Library' list."),Object(V.h)("li",null,"UTF-8 charset added to preview HTML to support universal characters."))),vo=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.8.0"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("a",{href:"https://medium.com/web-maker/release-v2-8-is-out-f44e6ea5d9c4",target:"_blank",rel:"noopener noreferrer"},"Read blog post about this release.")),Object(V.h)("li",null,Object(V.h)("strong",null,"Auto Save")," - Your creations now auto-save after your first manual save. This is configurable from settings."),Object(V.h)("li",null,Object(V.h)("strong",null,"Base2Tone-Meadow Editor Theme")," - First user contributed theme. Thanks to Diomed."),Object(V.h)("li",null,Object(V.h)("strong",null,"Use System Fonts")," - You can now use any of your existing system fonts in the editor!"),Object(V.h)("li",null,Object(V.h)("strong",null,"Matching Tag Highlight")," - Cursor over any HTML tag would highlight the matching pair tag."),Object(V.h)("li",null,"Auto-completion suggestion can now be switched off from settings."),Object(V.h)("li",null,Object(V.h)("strong",null,"Improvement")," - Stop white flicker in editor when the app opens."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix")," - Add Babel Polyfill to enable use of next-gen built-ins like Promise or WeakMap."),Object(V.h)("li",null,"Vue.js version updated to 2.4.0 in popular library list."),Object(V.h)("li",null,"Downloads permission is optional. Asked only when you take screenshot."))),Co=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.7.2"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("strong",null,"External Libraries")," - Add Foundation.js and update UIKit 3 to latest beta."),Object(V.h)("li",null,Object(V.h)("strong",null,"rawgit.com")," &",Object(V.h)("strong",null,"wzrd.in")," domains are now allowed for loading external libraries from."),Object(V.h)("li",null,"Minor booting speed improvements"))),yo=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.7.1"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("strong",null,"Framer.js support")," - You can now load the latest framer.js library from",Object(V.h)("a",{href:"https://builds.framerjs.com/",target:"_blank",rel:"noopener noreferrer"},"framer builds page")," ","and start coding framer prototypes."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix"),": Edit on CodePen is back in action."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix"),": Autocompletion menu doesn't show on cut and paste now."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix"),": Updated & fixed urls of some common external libraries to latest versions. UIKit3 & Bootstrap 4\u03B1 are now in the list."),Object(V.h)("li",null,"Preprocessor selector are now more accessible."))),So=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.7.0"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("strong",null,"Fork any creation!"),": Now you can fork any existing creation of yours to start a new work based on it. One big use case of this feature is \"Templates\"!",Object(V.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"https://kushagragour.in/blog/2017/05/web-maker-fork-templates/?utm_source=webmakerapp&utm_medium=referral"},"Read more about it"),"."),Object(V.h)("li",null,Object(V.h)("strong",null,"Fonts \uD83D\uDE0D "),": Super-awesome 4 fonts (mostly with ligature support) now available to choose from. Fira Code is the default font now."),Object(V.h)("li",null,"Updated most used external libraries to latest versions."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix"),": Add missing Bootstrap JS file to most used external libraries list."),Object(V.h)("li",null,"Several other minor bugfixes and improvements to make Web Maker awesome!"),Object(V.h)("li",null,"Great news to share with you - Web Maker has been featured on the Chrome Webstore homepage! Thanks for all the love :)"))),wo=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.6.1"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix"),": Emojis vanishing while exporting to Codepen has been fixed."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix"),":",Object(V.h)("code",null,"console.clear()")," now doesn't error and clears the inbuilt console."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix"),": External libraries added to the creation are exported as well to Codepen."))),ko=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.6.0"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("strong",null,"The \"Console\""),": The most awaited feature is here! There is now an inbuilt console to see your logs, errors and for quickly evaluating JavaScript code inside your preview. Enjoy! I also a",Object(V.h)("a",{href:"https://kushagragour.in/blog/2017/05/web-maker-console-is-here/?utm_source=webmakerapp&utm_medium=referral",target:"_blank",rel:"noopener noreferrer"},"blog post about it"),"."),Object(V.h)("li",null,"Number slider which popped on clicking any number in the code has been removed due to poor user experience."),Object(V.h)("li",null,"Minor usability improvements."))),xo=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.5.0"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("strong",null,"Atomic CSS"),": Use can now use Atomic CSS(ACSS) in your work!",Object(V.h)("a",{href:"https://acss.io/",target:"_blank",rel:"noopener noreferrer"},"Read more about it here"),"."),Object(V.h)("li",null,Object(V.h)("strong",null,"Search your saved creations"),": Easily search through all your saved creations by title."),Object(V.h)("li",null,Object(V.h)("strong",null,"Configurable Auto-preview")," - You can turn off the auto preview in settings if you don't want the preview to update as you type."),Object(V.h)("li",null,Object(V.h)("strong",null,"Configurable refresh on resize")," - You can configure whether you want the preview to refresh when you resize the preview panel."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix")," - Fix indentation",Object(V.h)("a",{href:"https://github.com/chinchang/web-maker/issues/104",target:"_blank",rel:"noopener noreferrer"},"issue")," ","with custom indentation size."))),Mo=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.4.2"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("strong",null,"Improved infinite loop protection"),": Infinite loop protection is now faster and more reliable. And works without the need of Escodegen. Thanks to Ariya Hidayat!"),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix")," - Default parameters not working in JavaScript is fixed."))),_o=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.4.0"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("strong",null,"Import/Export"),": Your creations are most important. Now export all your creations into a single file as a backup that can be imported anytime & anywhere."),Object(V.h)("li",null,Object(V.h)("strong",null,"Editor themes"),": You have been heard. Now you can choose from a huge list of wonderful editor themes!"),Object(V.h)("li",null,Object(V.h)("strong",null,"Identation settings"),": Not a spaces fan? Switch to tabs and set your indentation size."),Object(V.h)("li",null,Object(V.h)("strong",null,"Vim key bindings"),": Rejoice Vim lovers!"),Object(V.h)("li",null,Object(V.h)("strong",null,"Code blast"),": Why don't you try coding with this switched on from the settings? Go on..."),Object(V.h)("li",null,Object(V.h)("strong",null,"Important"),": Due to security policy changes from Chrome 57 onwards, Web Maker now allows loading external JavaScript libraries only from certain whitelisted domains (localhost, https://ajax.googleapis.com, https://code.jquery.com, https://cdnjs.cloudflare.com, https://unpkg.com, https://maxcdn.com, https://cdn77.com, https://maxcdn.bootstrapcdn.com, https://cdn.jsdelivr.net/)"),Object(V.h)("li",null,"Save button now highlights when you have unsaved changes."),Object(V.h)("li",null,"Jade is now called Pug. Just a name change."))),Lo=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.3.2"),Object(V.h)("ul",null,Object(V.h)("li",null,"Update Babel to support latest and coolest ES6 features."),Object(V.h)("li",null,"Improve onboarding experience at first install."))),Io=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.3.1"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix")," - Splitting of code and preview panes is remembered by the editor."),Object(V.h)("li",null,"Title of the creation is used for the file name when saving as HTML."))),Ho=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.3.0"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("strong",null,"Add Library Autocompletion")," - Just start typing the name of library and you'll be shown matching libraries from cdnjs."),Object(V.h)("li",null,Object(V.h)("strong",null,"Preview Screenshot Capture")," - Want to grab a nice screenshot of your creation. You have it! Click and capture."),Object(V.h)("li",null,Object(V.h)("strong",null,"Auto Indent Code")," - Select your code and hit Shift-Tab to auto-indent it!"),Object(V.h)("li",null,Object(V.h)("strong",null,"Keyboard Navigation in Saved List")," - Now select your creation using arrow keys and hit ENTER to open it."),Object(V.h)("li",null,"Highlight active line in code panes."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix")," - Fix in generated title of new creation."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix")," - HTML autocompletion is manual triggered now with Ctrl+Space."))),Ao=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.2.0"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("strong",null,"Code Autocompletion")," - See code suggestions while you type!"),Object(V.h)("li",null,Object(V.h)("strong",null,"Full Screen Preview")," - Checkout your creation in a full-screen layout."),Object(V.h)("li",null,Object(V.h)("strong",null,"SASS")," - SASS support added for CSS."),Object(V.h)("li",null,Object(V.h)("strong",null,"Faster CSS update")," - Preview updates instantly without refresh when just CSS is changed."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix")," - Indentation fixed while going on new line."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix")," - Works even in Chrome Canary now. Though libraries can be added only through CDNs."))),jo=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.1.0"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("strong",null,"TypeScript")," - Now you can code in TypeScript too!"),Object(V.h)("li",null,Object(V.h)("strong",null,"Stylus Preprocessor")," - Stylus supported adding for CSS."),Object(V.h)("li",null,Object(V.h)("strong",null,"Code Folding")," - Collapse large code blocks for easy editing."),Object(V.h)("li",null,Object(V.h)("strong",null,"Bugfix")," - Support JSX in JavaScript."),Object(V.h)("li",null,"Better onboarding for first time users."))),Bo=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"2.0.0"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("strong",null,"Save and Load")," - Long pending and super-useful, now you can save your creations and resume them anytime later."),Object(V.h)("li",null,Object(V.h)("strong",null,"Insert JS & CSS")," - Load popular JavaScript & CSS libraries in your work without writing any code."),Object(V.h)("li",null,Object(V.h)("strong",null,"Collapsed Panes")," - Collapse/uncollapse code panes with a single click. Your pane configuration is even saved with every creation!"),Object(V.h)("li",null,Object(V.h)("strong",null,"Quick color & number change")," - Click on any color or number and experiment with quick values using a slider."),Object(V.h)("li",null,Object(V.h)("strong",null,"Linting")," - See your code errors right where you are coding."),Object(V.h)("li",null,"No more browser hang due to infinite loops!"))),Eo=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"1.7.0"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("strong",null,"Preprocessors!")," - Enjoy a whole list of preprocessors for HTML(Jade & markdown), CSS(SCSS & LESS) and JavaScript(CoffeeScript & Babel)."),Object(V.h)("li",null,"More awesome font for code."))),Oo=Object(V.h)("div",{class:"notification"},Object(V.h)("span",{class:"notification__version"},"1.6.0"),Object(V.h)("ul",null,Object(V.h)("li",null,"You can now configure Web-Maker to not replace new tab page from the settings. It is always accessible from the icon in the top-right."),Object(V.h)("li",null,"Download current code as HTML file with Ctrl/\u2318 + S keyboard shortcut."),Object(V.h)("li",null,"New notifications panel added so you are always aware of the new changes in Web-Maker.")));const To=["3024-day","3024-night","abcdef","ambiance","base2tone-meadow-dark","base16-dark","base16-light","bespin","blackboard","cobalt","colorforth","dracula","duotone-dark","duotone-light","eclipse","elegant","erlang-dark","hopscotch","icecoder","isotope","lesser-dark","liquibyte","material","mbo","mdn-like","midnight","monokai","neat","neo","night","panda-syntax","paraiso-dark","paraiso-light","pastel-on-dark","railscasts","rubyblue","seti","solarized dark","solarized light","the-matrix","tomorrow-night-bright","tomorrow-night-eighties","ttcn","twilight","vibrant-ink","xq-dark","xq-light","yeti","zenburn"];var Vo=Object(V.h)("h1",null,"Settings"),Po=Object(V.h)("h3",null,"Indentation"),Do=Object(V.h)("datalist",{id:"indentationSizeList"},Object(V.h)("option",null,"1"),Object(V.h)("option",null,"2"),Object(V.h)("option",null,"3"),Object(V.h)("option",null,"4"),Object(V.h)("option",null,"5"),Object(V.h)("option",null,"6"),Object(V.h)("option",null,"7")),Fo=Object(V.h)("hr",null),No=Object(V.h)("h3",null,"Editor"),Wo=Object(V.h)("label",{class:"line"},"Default Preprocessors"),zo=Object(V.h)("option",{value:"html"},"HTML"),Ro=Object(V.h)("option",{value:"markdown"},"Markdown"),Uo=Object(V.h)("option",{value:"jade"},"Pug"),Ko=Object(V.h)("option",{value:"css"},"CSS"),qo=Object(V.h)("option",{value:"scss"},"SCSS"),Jo=Object(V.h)("option",{value:"sass"},"SASS"),Yo=Object(V.h)("option",{value:"less"},"LESS"),Go=Object(V.h)("option",{value:"stylus"},"Stylus"),Zo=Object(V.h)("option",{value:"acss"},"Atomic CSS"),Xo=Object(V.h)("option",{value:"js"},"JS"),Qo=Object(V.h)("option",{value:"coffee"},"CoffeeScript"),$o=Object(V.h)("option",{value:"es6"},"ES6 (Babel)"),es=Object(V.h)("option",{value:"typescript"},"TypeScript"),ns=Object(V.h)("option",{value:"FiraCode"},"Fira Code"),os=Object(V.h)("option",{value:"Inconsolata"},"Inconsolata"),ss=Object(V.h)("option",{value:"Monoid"},"Monoid"),is=Object(V.h)("option",{value:"FixedSys"},"FixedSys"),as=Object(V.h)("option",{disabled:"disabled"},"----"),rs=Object(V.h)("option",{value:"other"},"Other font from system"),ls=Object(V.h)("hr",null),ds=Object(V.h)("h3",null,"Fun"),cs=Object(V.h)("hr",null),hs=Object(V.h)("h3",null,"Advanced"),ps=Object(V.h)("div",{class:"help-text"},"If any loop iteration takes more than the defined time, it is detected as a potential infinite loop and further iterations are stopped.");let us=class extends V.Component{updateSetting(t){this.props.onChange(t)}shouldComponentUpdate(){return!0}render(){return Object(V.h)("div",null,Vo,Po,Object(V.h)("div",{class:"line",title:"I know this is tough, but you have to decide one!"},Object(V.h)("label",null,Object(V.h)("input",{type:"radio",name:"indentation",value:"spaces",checked:"spaces"===this.props.prefs.indentation,onChange:this.updateSetting.bind(this),"data-setting":"indentWith"})," ","Spaces"),Object(V.h)("label",{class:"ml-1"},Object(V.h)("input",{type:"radio",name:"indentation",value:"tabs",checked:"tabs"===this.props.prefs.indentation,onChange:this.updateSetting.bind(this),"data-setting":"indentWith"})," ","Tabs")),Object(V.h)("label",{class:"line",title:""},"Indentation Size"," ",Object(V.h)("input",{type:"range",class:"va-m ml-1",value:this.props.prefs.indentSize,min:"1",max:"7",list:"indentationSizeList","data-setting":"indentSize",onChange:this.updateSetting.bind(this)}),Object(V.h)("span",{id:"indentationSizeValueEl"},this.props.prefs.indentSize),Do),Fo,No,Object(V.h)("div",{class:"flex block--mobile"},Object(V.h)("div",null,Wo,Object(V.h)("div",{class:"flex line"},Object(V.h)("select",{style:"flex:1;margin-left:20px","data-setting":"htmlMode",value:this.props.prefs.htmlMode,onChange:this.updateSetting.bind(this)},zo,Ro,Uo),Object(V.h)("select",{style:"flex:1;margin-left:20px","data-setting":"cssMode",value:this.props.prefs.cssMode,onChange:this.updateSetting.bind(this)},Ko,qo,Jo,Yo,Go,Zo),Object(V.h)("select",{style:"flex:1;margin-left:20px","data-setting":"jsMode",value:this.props.prefs.jsMode,onChange:this.updateSetting.bind(this)},Xo,Qo,$o,es)),Object(V.h)("label",{class:"line"},"Theme",Object(V.h)("select",{style:"flex:1;margin:0 20px","data-setting":"editorTheme",value:this.props.prefs.editorTheme,onChange:this.updateSetting.bind(this)},To.map((e)=>Object(V.h)("option",{value:e},e)))),Object(V.h)("label",{class:"line"},"Font",Object(V.h)("select",{style:"flex:1;margin:0 20px","data-setting":"editorFont",value:this.props.prefs.editorFont,onChange:this.updateSetting.bind(this)},ns,os,ss,is,as,rs),"other"===this.props.prefs.editorFont&&Object(V.h)("input",{id:"customEditorFontInput",type:"text",value:this.props.prefs.editorCustomFont,placeholder:"Custom font name here","data-setting":"editorCustomFont",onChange:this.updateSetting.bind(this)})),Object(V.h)("label",{class:"line"},"Font Size"," ",Object(V.h)("input",{style:"width:70px",type:"number",value:this.props.prefs.fontSize,"data-setting":"fontSize",onChange:this.updateSetting.bind(this)})," ","px"),Object(V.h)("div",{class:"line"},"Key bindings",Object(V.h)("label",{class:"ml-1"},Object(V.h)("input",{type:"radio",name:"keymap",value:"sublime",checked:"sublime"===this.props.prefs.keymap,"data-setting":"keymap",onChange:this.updateSetting.bind(this)})," ","Sublime"),Object(V.h)("label",{class:"ml-1"},Object(V.h)("input",{type:"radio",name:"keymap",value:"vim",checked:"vim"===this.props.prefs.keymap,"data-setting":"keymap",onChange:this.updateSetting.bind(this)})," ","Vim"))),Object(V.h)("div",{class:"ml-2 ml-0--mobile"},Object(V.h)(L,{name:"lineWrap",title:"Toggle wrapping of long sentences onto new line",label:"Line wrap",pref:this.props.prefs.lineWrap,onChange:this.updateSetting.bind(this)}),Object(V.h)(L,{name:"refreshOnResize",title:"Your Preview will refresh when you resize the preview split",label:"Refresh preview on resize",pref:this.props.prefs.refreshOnResize,onChange:this.updateSetting.bind(this)}),Object(V.h)(L,{name:"autoComplete",title:"Turns on the auto-completion suggestions as you type",label:"Auto-complete suggestions",pref:this.props.prefs.autoComplete,onChange:this.updateSetting.bind(this)}),Object(V.h)(L,{name:"autoPreview",title:"Refreshes the preview as you code. Otherwise use the Run button",label:"Auto-preview",pref:this.props.prefs.autoPreview,onChange:this.updateSetting.bind(this)}),Object(V.h)(L,{name:"autoSave",title:"Auto-save keeps saving your code at regular intervals after you hit the first save manually",label:"Auto-save",pref:this.props.prefs.autoSave,onChange:this.updateSetting.bind(this)}),Object(V.h)(L,{name:"preserveLastCode",title:"Loads the last open creation when app starts",label:"Preserve last written code",pref:this.props.prefs.preserveLastCode,onChange:this.updateSetting.bind(this)}),Object(V.h)(L,{name:"replaceNewTab",title:"Turning this on will start showing Web Maker in every new tab you open",label:"Replace new tab page",pref:this.props.prefs.replaceNewTab,onChange:this.updateSetting.bind(this),showWhenExtension:!0}),Object(V.h)(L,{name:"preserveConsoleLogs",title:"Preserves the console logs across your preview refreshes",label:"Preserve console logs",pref:this.props.prefs.preserveConsoleLogs,onChange:this.updateSetting.bind(this)}),Object(V.h)(L,{name:"lightVersion",title:"Switch to lighter version for better performance. Removes things like blur etc.",label:"Fast/light version",pref:this.props.prefs.lightVersion,onChange:this.updateSetting.bind(this)}))),ls,ds,Object(V.h)("p",null,Object(V.h)(L,{title:"Enjoy wonderful particle blasts while you type",label:"Code blast!",name:"isCodeBlastOn",pref:this.props.prefs.isCodeBlastOn,onChange:this.updateSetting.bind(this)})),cs,hs,Object(V.h)("p",null,Object(V.h)("label",{class:"line",title:"This timeout is used to indentify a possible infinite loop and prevent it."},"Maximum time allowed in a loop iteration",Object(V.h)("input",{type:"number",value:this.props.prefs.infiniteLoopTimeout,"data-setting":"infiniteLoopTimeout",onChange:this.updateSetting.bind(this)})," ","ms"),ps))}};n("zKjx");const ms="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='#ccc' d='M12,19.2C9.5,19.2 7.29,17.92 6,16C6.03,14 10,12.9 12,12.9C14,12.9 17.97,14 18,16C16.71,17.92 14.5,19.2 12,19.2M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z' /%3E%3C/svg%3E";var gs=Object(V.h)("div",{class:"tac"},Object(V.h)("h1",null,"Support the Developer"),Object(V.h)("p",null,"Hi,"," ",Object(V.h)("a",{href:"https://kushagragour.in",target:"_blank",rel:"noopener noreferrer"},"Kushagra")," ","here! Web Maker is a free and open-source project. To keep myself motivated for working on such open-source and free"," ",Object(V.h)("a",{href:"https://kushagragour.in/lab/",target:"_blank",rel:"noopener noreferrer"},"side projects"),", I am accepting donations. Your pledge, no matter how small, will act as an appreciation towards my work and keep me going forward making Web Maker more awesome\uD83D\uDD25. So please consider donating. \uD83D\uDE4F\uD83C\uDFFC (could be as small as $1/month)."),Object(V.h)("div",{class:"flex flex-h-center",id:"onboardDontShowInTabOptionBtn","d-click":"onDontShowInTabClicked"},Object(V.h)("a",{class:"onboard-selection",href:"https://patreon.com/kushagra",target:"_blank",rel:"noopener noreferrer","aria-label":"Make a monthly pledge on Patreon"},Object(V.h)("img",{src:"patreon.png",height:"60",alt:"Become a patron image"}),Object(V.h)("h3",{class:"onboard-selection-text"},"Make a monthly pledge on Patreon"))),Object(V.h)("a",{href:"https://www.paypal.me/kushagragour",target:"_blank",rel:"noopener noreferrer","aria-label":"Make a one time donation on Paypal"},"Or, make a one time donation")),fs=Object(V.h)("h1",null,"Keyboard Shortcuts"),bs=Object(V.h)("div",{class:"flex"},Object(V.h)("div",null,Object(V.h)("h2",null,"Global"),Object(V.h)("p",null,Object(V.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + Shift + ?"),Object(V.h)("span",{class:"kbd-shortcut__details"},"See keyboard shortcuts")),Object(V.h)("p",null,Object(V.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + Shift + 5"),Object(V.h)("span",{class:"kbd-shortcut__details"},"Refresh preview")),Object(V.h)("p",null,Object(V.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + S"),Object(V.h)("span",{class:"kbd-shortcut__details"},"Save current creations")),Object(V.h)("p",null,Object(V.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + O"),Object(V.h)("span",{class:"kbd-shortcut__details"},"Open list of saved creations")),Object(V.h)("p",null,Object(V.h)("span",{class:"kbd-shortcut__keys"},"Ctrl + L"),Object(V.h)("span",{class:"kbd-shortcut__details"},"Clear console (works when console input is focused)")),Object(V.h)("p",null,Object(V.h)("span",{class:"kbd-shortcut__keys"},"Esc"),Object(V.h)("span",{class:"kbd-shortcut__details"},"Close saved creations panel & modals"))),Object(V.h)("div",{class:"ml-2"},Object(V.h)("h2",null,"Editor"),Object(V.h)("p",null,Object(V.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + F"),Object(V.h)("span",{class:"kbd-shortcut__details"},"Find")),Object(V.h)("p",null,Object(V.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + G"),Object(V.h)("span",{class:"kbd-shortcut__details"},"Select next match")),Object(V.h)("p",null,Object(V.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + Shift + G"),Object(V.h)("span",{class:"kbd-shortcut__details"},"Select previous match")),Object(V.h)("p",null,Object(V.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + Opt/Alt + F"),Object(V.h)("span",{class:"kbd-shortcut__details"},"Find & replace")),Object(V.h)("p",null,Object(V.h)("span",{class:"kbd-shortcut__keys"},"Shift + Tab"),Object(V.h)("span",{class:"kbd-shortcut__details"},"Realign code")),Object(V.h)("p",null,Object(V.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + ]"),Object(V.h)("span",{class:"kbd-shortcut__details"},"Indent code right")),Object(V.h)("p",null,Object(V.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + ["),Object(V.h)("span",{class:"kbd-shortcut__details"},"Indent code left")),Object(V.h)("p",null,Object(V.h)("span",{class:"kbd-shortcut__keys"},"Tab"),Object(V.h)("span",{class:"kbd-shortcut__details"},"Emmet code completion"," ",Object(V.h)("a",{href:"https://emmet.io/",target:"_blank",rel:"noopener noreferrer"},"Read more"))),Object(V.h)("p",null,Object(V.h)("span",{class:"kbd-shortcut__keys"},"Ctrl/\u2318 + /"),Object(V.h)("span",{class:"kbd-shortcut__details"},"Single line comment")))),vs=Object(V.h)("h2",null,"Import your creations in your account"),Cs=Object(V.h)("p",null,"It's okay if you don't want to. You can simply logout and access them anytime on this browser."),ys=Object(V.h)("div",{class:"alerts-container",id:"js-alerts-container"});let Ss=class extends V.Component{shouldComponentUpdate(){return!1}render(){return ys}};var ws=Object(V.h)("h1",null,Object(V.h)("div",{class:"web-maker-with-tag"},"Web Maker"),Object(V.h)("small",{style:"font-size:14px;"}," v3.2.0")),ks=Object(V.h)("p",null,"Made with ",Object(V.h)("span",{style:"margin-right: 8px;"},"\uD83D\uDC96")," &"," ",Object(V.h)("span",{style:"margin-right: 8px;"},"\uD83D\uDE4C")," by"," ",Object(V.h)("a",{href:"https://twitter.com/chinchang457",target:"_blank",rel:"noopener noreferrer"},"Kushagra Gour")),xs=Object(V.h)("p",null,Object(V.h)("a",{href:"/docs",target:"_blank",rel:"noopener noreferrer"},"Read the documentation"),"."),Ms=Object(V.h)("p",null,"Tweet out your feature requests, comments & suggestions to"," ",Object(V.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"https://twitter.com/webmakerApp"},"@webmakerApp"),"."),_s=Object(V.h)("p",null,"Like this extension? Please"," ",Object(V.h)("a",{href:"https://chrome.google.com/webstore/detail/web-maker/lkfkkhfhhdkiemehlpkgjeojomhpccnh/reviews",target:"_blank",rel:"noopener noreferrer"},"rate it here"),"."),Ls=Object(V.h)("svg",null,Object(V.h)("use",{xlinkHref:"#gift-icon"})),Is=Object(V.h)("a",{"aria-label":"Rate Web Maker",href:"https://chrome.google.com/webstore/detail/web-maker/lkfkkhfhhdkiemehlpkgjeojomhpccnh/reviews",target:"_blank",rel:"noopener noreferrer",class:"btn btn-icon"},Object(V.h)("svg",null,Object(V.h)("use",{xlinkHref:"#heart-icon"})),"Share Web Maker"),Hs=Object(V.h)("a",{"aria-label":"Chat",href:"https://web-maker.slack.com",target:"_blank",rel:"noopener noreferrer",class:"btn btn-icon"},Object(V.h)("svg",null,Object(V.h)("use",{xlinkHref:"#chat-icon"})),"Chat"),As=Object(V.h)("a",{"aria-label":"Report a Bug",href:"https://github.com/chinchang/web-maker/issues",target:"_blank",rel:"noopener noreferrer",class:"btn btn-icon"},Object(V.h)("svg",null,Object(V.h)("use",{xlinkHref:"#bug-icon"})),"Report a bug"),js=Object(V.h)("p",null,Object(V.h)("h3",null,"Awesome libraries used"),Object(V.h)("ul",null,Object(V.h)("li",null,Object(V.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"https://kushagragour.in/lab/hint/"},"Hint.css")," ","&",Object(V.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"https://github.com/chinchang/screenlog.js"},"Screenlog.js")," ","- By me :)"),Object(V.h)("li",null,Object(V.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"https://nathancahill.github.io/Split.js/"},"Split.js")," ","- Nathan Cahill"),Object(V.h)("li",null,Object(V.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"https://codemirror.net/"},"Codemirror")," ","- Marijn Haverbeke"),Object(V.h)("li",null,Object(V.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"https://emmet.io/"},"Emmet")," ","- Sergey Chikuyonok"),Object(V.h)("li",null,Object(V.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"http://esprima.org/"},"Esprima")," ","- Ariya Hidayat"),Object(V.h)("li",null,Object(V.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"https://github.com/enjalot/Inlet"},"Inlet")," ","- Ian Johnson"),Object(V.h)("li",null,Object(V.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"https://webmakerapp.com/"},"Web Maker!")," ","- whhat!"))),Bs=Object(V.h)("p",null,Object(V.h)("h3",null,"License"),"\"Web Maker\" is"," ",Object(V.h)("a",{target:"_blank",rel:"noopener noreferrer",href:"https://github.com/chinchang/web-maker"},"open-source")," ","under the"," ",Object(V.h)("a",{href:"https://opensource.org/licenses/MIT",target:"_blank",rel:"noopener noreferrer"},"MIT License"),"."),Es=Object(V.h)("div",{class:"tac"},Object(V.h)("svg",{width:"130px",height:"50px","aria-hidden":"true"},Object(V.h)("use",{xlinkHref:"#logo"})),Object(V.h)("h1",{style:"margin-top:20px"},"Welcome to Web Maker")),Os=Object(V.h)("div",{class:"flex",style:"margin-top:40px;"},Object(V.h)("div",{class:"onboard-step show-when-app"},Object(V.h)("div",{class:"tac"},Object(V.h)("svg",{class:"onboard-step__icon",viewBox:"0 0 24 24"},Object(V.h)("path",{d:"M13.64,21.97C13.14,22.21 12.54,22 12.31,21.5L10.13,16.76L7.62,18.78C7.45,18.92 7.24,19 7,19A1,1 0 0,1 6,18V3A1,1 0 0,1 7,2C7.24,2 7.47,2.09 7.64,2.23L7.65,2.22L19.14,11.86C19.57,12.22 19.62,12.85 19.27,13.27C19.12,13.45 18.91,13.57 18.7,13.61L15.54,14.23L17.74,18.96C18,19.46 17.76,20.05 17.26,20.28L13.64,21.97Z"}))),Object(V.h)("p",null,"Open Web Maker anytime by visiting"," ",Object(V.h)("a",null,"https://webmakerapp.com/app/")," - Even when you are offline! It just works! \uD83D\uDE31 ",Object(V.h)("strong",null,"Drag the following bookmarklet")," on your bookmark bar to create a quick access shortcut:",Object(V.h)("a",{class:"ml-1 bookmarklet",href:"https://webmakerapp.com/app/"},Object(V.h)("svg",{width:"20",height:"20","aria-hidden":"true"},Object(V.h)("use",{xlinkHref:"#logo"})),"Web Maker"))),Object(V.h)("div",{class:"onboard-step show-when-extension"},Object(V.h)("div",{class:"tac"},Object(V.h)("svg",{class:"onboard-step__icon",viewBox:"0 0 24 24"},Object(V.h)("path",{d:"M13.64,21.97C13.14,22.21 12.54,22 12.31,21.5L10.13,16.76L7.62,18.78C7.45,18.92 7.24,19 7,19A1,1 0 0,1 6,18V3A1,1 0 0,1 7,2C7.24,2 7.47,2.09 7.64,2.23L7.65,2.22L19.14,11.86C19.57,12.22 19.62,12.85 19.27,13.27C19.12,13.45 18.91,13.57 18.7,13.61L15.54,14.23L17.74,18.96C18,19.46 17.76,20.05 17.26,20.28L13.64,21.97Z"}))),Object(V.h)("p",null,"Open Web Maker anytime by clicking the",Object(V.h)("svg",{class:"relative",style:"top:5px;",width:"40",height:"30"},Object(V.h)("use",{xlinkHref:"#logo"}))," ","button in top-right side of your browser.")),Object(V.h)("div",{class:"onboard-step"},Object(V.h)("div",{class:"tac"},Object(V.h)("svg",{class:"onboard-step__icon",viewBox:"0 0 24 24"},Object(V.h)("use",{xlinkHref:"#settings-icon"}))),Object(V.h)("p",null,"Configure and customize settings by clicking the gear icon (",Object(V.h)("svg",{style:"width:18px;height:18px;position:relative;top:3px;fill:#888",viewBox:"0 0 24 24"},Object(V.h)("use",{xlinkHref:"#settings-icon"})),") in bottom right of the app.")),Object(V.h)("div",{class:"onboard-step"},Object(V.h)("div",{class:"tac"},Object(V.h)("svg",{class:"onboard-step__icon",style:"stroke-width:0.3px;"},Object(V.h)("use",{xlinkHref:"#twitter-icon"}))),Object(V.h)("p",null,"Follow"," ",Object(V.h)("a",{href:"https://twitter.com/intent/follow?screen_name=webmakerApp",targe:"_blank",rel:"noopener noreferrer"},"@webmakerApp")," ","to know about the new upcoming features!"))),Ts=Object(V.h)("p",{class:"tac show-when-app"},"If you are an existing Chrome extension user, you can import your creations from there to here."," ",Object(V.h)("a",{href:"https://medium.com/web-maker/importing-exporting-your-creations-d92e7de5c3dc",target:"_blank",rel:"noopener noreferrer"},"Learn how to export/import"),"."),Vs=Object(V.h)("symbol",{id:"logo",viewBox:"-145 -2 372 175"},Object(V.h)("g",{stroke:"none",strokeWidth:1,fill:"none",fillRule:"evenodd",transform:"translate(-145.000000, -1.000000)"},Object(V.h)("polygon",{id:"Path-1",fill:"#FF4600",points:"31 0 232 0 132 173.310547"}),Object(V.h)("polygon",{id:"Path-1",fill:"#FF6C00",points:"0 0 201 0 101 173.310547"}),Object(V.h)("polygon",{id:"Path-1",fill:"#FF6C00",transform:"translate(271.500000, 86.500000) scale(1, -1) translate(-271.500000, -86.500000) ",points:"171 0 372 0 272 173.310547"}),Object(V.h)("polygon",{id:"Path-1",fill:"#FF4600",transform:"translate(241.500000, 86.500000) scale(1, -1) translate(-241.500000, -86.500000) ",points:"141 0 342 0 242 173.310547"}))),Ps=Object(V.h)("symbol",{id:"bug-icon",viewBox:"0 0 24 24"},Object(V.h)("path",{d:"M14,12H10V10H14M14,16H10V14H14M20,8H17.19C16.74,7.22 16.12,6.55 15.37,6.04L17,4.41L15.59,3L13.42,5.17C12.96,5.06 12.5,5 12,5C11.5,5 11.04,5.06 10.59,5.17L8.41,3L7,4.41L8.62,6.04C7.88,6.55 7.26,7.22 6.81,8H4V10H6.09C6.04,10.33 6,10.66 6,11V12H4V14H6V15C6,15.34 6.04,15.67 6.09,16H4V18H6.81C7.85,19.79 9.78,21 12,21C14.22,21 16.15,19.79 17.19,18H20V16H17.91C17.96,15.67 18,15.34 18,15V14H20V12H18V11C18,10.66 17.96,10.33 17.91,10H20V8Z"})),Ds=Object(V.h)("symbol",{id:"google-icon",viewBox:"0 0 24 24"},Object(V.h)("path",{d:"M21.35,11.1H12.18V13.83H18.69C18.36,17.64 15.19,19.27 12.19,19.27C8.36,19.27 5,16.25 5,12C5,7.9 8.2,4.73 12.2,4.73C15.29,4.73 17.1,6.7 17.1,6.7L19,4.72C19,4.72 16.56,2 12.1,2C6.42,2 2.03,6.8 2.03,12C2.03,17.05 6.16,22 12.25,22C17.6,22 21.5,18.33 21.5,12.91C21.5,11.76 21.35,11.1 21.35,11.1V11.1Z"})),Fs=Object(V.h)("symbol",{id:"fb-icon",viewBox:"0 0 24 24"},Object(V.h)("path",{d:"M17,2V2H17V6H15C14.31,6 14,6.81 14,7.5V10H14L17,10V14H14V22H10V14H7V10H10V6A4,4 0 0,1 14,2H17Z"})),Ns=Object(V.h)("symbol",{id:"github-icon",viewBox:"0 0 24 24"},Object(V.h)("path",{d:"M12,2A10,10 0 0,0 2,12C2,16.42 4.87,20.17 8.84,21.5C9.34,21.58 9.5,21.27 9.5,21C9.5,20.77 9.5,20.14 9.5,19.31C6.73,19.91 6.14,17.97 6.14,17.97C5.68,16.81 5.03,16.5 5.03,16.5C4.12,15.88 5.1,15.9 5.1,15.9C6.1,15.97 6.63,16.93 6.63,16.93C7.5,18.45 8.97,18 9.54,17.76C9.63,17.11 9.89,16.67 10.17,16.42C7.95,16.17 5.62,15.31 5.62,11.5C5.62,10.39 6,9.5 6.65,8.79C6.55,8.54 6.2,7.5 6.75,6.15C6.75,6.15 7.59,5.88 9.5,7.17C10.29,6.95 11.15,6.84 12,6.84C12.85,6.84 13.71,6.95 14.5,7.17C16.41,5.88 17.25,6.15 17.25,6.15C17.8,7.5 17.45,8.54 17.35,8.79C18,9.5 18.38,10.39 18.38,11.5C18.38,15.32 16.04,16.16 13.81,16.41C14.17,16.72 14.5,17.33 14.5,18.26C14.5,19.6 14.5,20.68 14.5,21C14.5,21.27 14.66,21.59 15.17,21.5C19.14,20.16 22,16.42 22,12A10,10 0 0,0 12,2Z"})),Ws=Object(V.h)("symbol",{id:"settings-icon",viewBox:"0 0 24 24"},Object(V.h)("path",{d:"M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z"})),zs=Object(V.h)("symbol",{id:"twitter-icon",viewBox:"0 0 16 16"},Object(V.h)("path",{d:"M15.969,3.058c-0.586,0.26-1.217,0.436-1.878,0.515c0.675-0.405,1.194-1.045,1.438-1.809 c-0.632,0.375-1.332,0.647-2.076,0.793c-0.596-0.636-1.446-1.033-2.387-1.033c-1.806,0-3.27,1.464-3.27,3.27 c0,0.256,0.029,0.506,0.085,0.745C5.163,5.404,2.753,4.102,1.14,2.124C0.859,2.607,0.698,3.168,0.698,3.767 c0,1.134,0.577,2.135,1.455,2.722C1.616,6.472,1.112,6.325,0.671,6.08c0,0.014,0,0.027,0,0.041c0,1.584,1.127,2.906,2.623,3.206 C3.02,9.402,2.731,9.442,2.433,9.442c-0.211,0-0.416-0.021-0.615-0.059c0.416,1.299,1.624,2.245,3.055,2.271 c-1.119,0.877-2.529,1.4-4.061,1.4c-0.264,0-0.524-0.015-0.78-0.046c1.447,0.928,3.166,1.469,5.013,1.469 c6.015,0,9.304-4.983,9.304-9.304c0-0.142-0.003-0.283-0.009-0.423C14.976,4.29,15.531,3.714,15.969,3.058z"})),Rs=Object(V.h)("symbol",{id:"heart-icon",viewBox:"0 0 24 24"},Object(V.h)("path",{d:"M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"})),Us=Object(V.h)("symbol",{id:"play-icon",viewBox:"0 0 24 24"},Object(V.h)("svg",null,Object(V.h)("path",{d:"M8,5.14V19.14L19,12.14L8,5.14Z"}))),Ks=Object(V.h)("symbol",{id:"cancel-icon",viewBox:"0 0 24 24"},Object(V.h)("svg",null,Object(V.h)("path",{d:"M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12C4,13.85 4.63,15.55 5.68,16.91L16.91,5.68C15.55,4.63 13.85,4 12,4M12,20A8,8 0 0,0 20,12C20,10.15 19.37,8.45 18.32,7.09L7.09,18.32C8.45,19.37 10.15,20 12,20Z"}))),qs=Object(V.h)("symbol",{id:"chevron-icon",viewBox:"0 0 24 24"},Object(V.h)("svg",null,Object(V.h)("path",{d:"M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z"}))),Js=Object(V.h)("symbol",{id:"chat-icon",viewBox:"0 0 24 24"},Object(V.h)("path",{d:"M20,2H4A2,2 0 0,0 2,4V22L6,18H20A2,2 0 0,0 22,16V4A2,2 0 0,0 20,2M8,14H6V12H8V14M8,11H6V9H8V11M8,8H6V6H8V8M15,14H10V12H15V14M18,11H10V9H18V11M18,8H10V6H18V8Z"})),Ys=Object(V.h)("path",{d:"M22,12V20A2,2 0 0,1 20,22H4A2,2 0 0,1 2,20V12A1,1 0 0,1 1,11V8A2,2 0 0,1 3,6H6.17C6.06,5.69 6,5.35 6,5A3,3 0 0,1 9,2C10,2 10.88,2.5 11.43,3.24V3.23L12,4L12.57,3.23V3.24C13.12,2.5 14,2 15,2A3,3 0 0,1 18,5C18,5.35 17.94,5.69 17.83,6H21A2,2 0 0,1 23,8V11A1,1 0 0,1 22,12M4,20H11V12H4V20M20,20V12H13V20H20M9,4A1,1 0 0,0 8,5A1,1 0 0,0 9,6A1,1 0 0,0 10,5A1,1 0 0,0 9,4M15,4A1,1 0 0,0 14,5A1,1 0 0,0 15,6A1,1 0 0,0 16,5A1,1 0 0,0 15,4M3,8V10H11V8H3M13,8V10H21V8H13Z"}),Gs=Object(V.h)("symbol",{id:"gift-icon",viewBox:"0 0 24 24"}),Zs=Object(V.h)("symbol",{id:"cross-icon",viewBox:"0 0 24 24"},Object(V.h)("path",{d:"M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"})),Xs=Object(V.h)("symbol",{id:"keyboard-icon",viewBox:"0 0 24 24"},Object(V.h)("path",{d:"M19,10H17V8H19M19,13H17V11H19M16,10H14V8H16M16,13H14V11H16M16,17H8V15H16M7,10H5V8H7M7,13H5V11H7M8,11H10V13H8M8,8H10V10H8M11,11H13V13H11M11,8H13V10H11M20,5H4C2.89,5 2,5.89 2,7V17A2,2 0 0,0 4,19H20A2,2 0 0,0 22,17V7C22,5.89 21.1,5 20,5Z"})),Qs=Object(V.h)("symbol",{id:"mode-icon",viewBox:"0 0 100 100"},Object(V.h)("g",null,Object(V.h)("rect",{x:0,y:0,width:28,height:47}),Object(V.h)("rect",{x:36,y:0,width:28,height:47}),Object(V.h)("rect",{x:72,y:0,width:28,height:47}),Object(V.h)("rect",{x:0,y:53,width:100,height:47}))),$s=Object(V.h)("symbol",{id:"vertical-mode-icon",viewBox:"0 0 100 100"},Object(V.h)("g",null,Object(V.h)("rect",{x:0,y:0,width:20,height:100}),Object(V.h)("rect",{x:23,y:0,width:20,height:100}),Object(V.h)("rect",{x:46,y:0,width:20,height:100}),Object(V.h)("rect",{x:69,y:0,width:32,height:100}))),ei=Object(V.h)("symbol",{id:"search",viewBox:"0 0 24 24"},Object(V.h)("path",{d:"M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z"})),ti=Object(V.h)("g",{fill:"none",fillRule:"evenodd",strokeWidth:10},Object(V.h)("circle",{cx:22,cy:22,r:1},Object(V.h)("animate",{attributeName:"r",begin:"0s",dur:"1.8s",values:"1; 20",calcMode:"spline",keyTimes:"0; 1",keySplines:"0.165, 0.84, 0.44, 1",repeatCount:"indefinite"}),Object(V.h)("animate",{attributeName:"stroke-opacity",begin:"0s",dur:"1.8s",values:"1; 0",calcMode:"spline",keyTimes:"0; 1",keySplines:"0.3, 0.61, 0.355, 1",repeatCount:"indefinite"})),Object(V.h)("circle",{cx:22,cy:22,r:1},Object(V.h)("animate",{attributeName:"r",begin:"-0.9s",dur:"1.8s",values:"1; 20",calcMode:"spline",keyTimes:"0; 1",keySplines:"0.165, 0.84, 0.44, 1",repeatCount:"indefinite"}),Object(V.h)("animate",{attributeName:"stroke-opacity",begin:"-0.9s",dur:"1.8s",values:"1; 0",calcMode:"spline",keyTimes:"0; 1",keySplines:"0.3, 0.61, 0.355, 1",repeatCount:"indefinite"}))),ni=Object.assign||function(e){for(var t,n=1;nHello, World!\"}"})),di=Object(V.h)(zn,null),ci=Object(V.h)(function(){return Object(V.h)("svg",{version:"1.1",xmlns:"http://www.w3.org/2000/svg",style:{display:"none"}},Vs,Ps,Ds,Fs,Ns,Ws,zs,Rs,Us,Ks,qs,Js,Object(V.h)("symbol",{id:"gift-icon",viewBox:"0 0 24 24"},Ys,Gs,Zs,Xs,Qs,$s,ei,Object(V.h)("symbol",{id:"loader-icon",viewBox:"0 0 44 44"},ti)))},null),hi=Object(V.h)("form",{style:"display:none;",action:"https://codepen.io/pen/define",method:"POST",target:"_blank",id:"codepenForm"},Object(V.h)("input",{type:"hidden",name:"data",value:"{\"title\": \"New Pen!\", \"html\": \"
Hello, World!
\"}"}));let pi=class extends V.Component{constructor(){super(),this.AUTO_SAVE_INTERVAL=15000,this.state={isSavedItemPaneOpen:!1,isModalOpen:!1,isAddLibraryModalOpen:!1,isSettingsModalOpen:!1,isHelpModalOpen:!1,isNotificationsModalOpen:!1,isLoginModalOpen:!1,isProfileModalOpen:!1,isSupportDeveloperModalOpen:!1,isKeyboardShortcutsModalOpen:!1,isAskToImportModalOpen:!1,isOnboardModalOpen:!1,prefs:{},currentItem:{title:"",externalLibs:{js:"",css:""}}},this.defaultSettings={preserveLastCode:!0,replaceNewTab:!1,htmlMode:"html",jsMode:"js",cssMode:"css",isCodeBlastOn:!1,indentWith:"spaces",indentSize:2,editorTheme:"monokai",keymap:"sublime",fontSize:16,refreshOnResize:!1,autoPreview:!0,editorFont:"FiraCode",editorCustomFont:"",autoSave:!0,autoComplete:!0,preserveConsoleLogs:!0,lightVersion:!1,lineWrap:!0,infiniteLoopTimeout:1e3,layoutMode:2},this.prefs={},Tn.a.auth().onAuthStateChanged((e)=>{this.setState({isLoginModalOpen:!1}),e?(c("You are -> ",e),gn.add("You are now logged in!"),this.setState({user:e}),window.user=e,!window.localStorage[oi.ASKED_TO_IMPORT_CREATIONS]&&this.fetchItems(!1,!0).then((e)=>{e.length&&(this.oldSavedItems=e,this.oldSavedCreationsCount=e.length,this.setState({isAskToImportModalOpen:!0}),v("ui","askToImportModalSeen"))}),window.db.getUser(e.uid).then((t)=>{if(t){const t=ni({},this.state.prefs);ni(t,e.settings),this.setState({prefs:t}),this.updateSetting()}})):(this.setState({user:void 0}),delete window.user),this.updateProfileUi()})}componentWillMount(){var e;window.onunload=()=>{this.saveCode("code"),this.detachedWindow&&this.detachedWindow.close()},db.local.get({layoutMode:1,code:""},(t)=>{this.toggleLayout(t.layoutMode),this.state.prefs.layoutMode=t.layoutMode,t.code&&(e=t.code)}),db.getSettings(this.defaultSettings).then((t)=>{t.preserveLastCode&&e?(this.setState({unsavedEditCount:0}),e.id&&window.IS_EXTENSION?db.local.get(e.id,(t)=>{t[e.id]&&(c("Load item ",e.id),this.setCurrentItem(t[e.id]).then(()=>this.refreshEditor()))}):(c("Load last unsaved item",e),this.setCurrentItem(e).then(()=>this.refreshEditor()))):this.createNewItem(),ni(this.state.prefs,t),this.setState({prefs:this.state.prefs}),this.updateSetting()}),db.getUserLastSeenVersion().then((e)=>{e||(this.setState({isOnboardModalOpen:!0}),-1===document.cookie.indexOf("onboarded")&&(v("ui","onboardModalSeen",ii),document.cookie="onboarded=1"),window.db.setUserLastSeenVersion(ii)),e&&-1===r(e,ii)&&!window.localStorage.pledgeModalSeen&&(this.openSupportDeveloperModal(),window.localStorage.pledgeModalSeen=!0),e&&-1!==r(e,ii)||(this.setState({hasUnseenChangelog:!0}),this.hasSeenNotifications=!1)})}updateProfileUi(){this.state.user?document.body.classList.add("is-logged-in"):document.body.classList.remove("is-logged-in")}refreshEditor(){this.toggleLayout(this.state.currentItem.layoutMode||this.state.prefs.layoutMode),this.updateExternalLibCount(),this.contentWrap.refreshEditor()}forkItem(e){if(this.state.unsavedEditCount){var t=confirm("You have unsaved changes in your current work. Do you want to discard unsaved changes and continue?");if(!t)return}const n=JSON.parse(JSON.stringify(e));delete n.id,n.title="(Forked) "+e.title,n.updatedOn=Date.now(),this.setCurrentItem(n).then(()=>this.refreshEditor()),gn.add(`"${e.title}" was forked`),v("fn","itemForked")}createNewItem(){var e=new Date;this.setCurrentItem({title:"Untitled "+e.getDate()+"-"+(e.getMonth()+1)+"-"+e.getHours()+":"+e.getMinutes(),html:"",css:"",js:"",externalLibs:{js:"",css:""},layoutMode:this.state.currentLayoutMode}).then(()=>this.refreshEditor()),gn.add("New item created")}openItem(e){this.setCurrentItem(e).then(()=>this.refreshEditor()),gn.add("Saved item loaded")}removeItem(e){var t=confirm(`Are you sure you want to delete "${e.title}"?`);t&&(un.unsetItemForUser(e.id),un.removeItem(e.id).then(()=>{gn.add("Item removed.",e),this.state.currentItem.id===e.id&&this.createNewItem()}),delete this.state.savedItems[e.id],this.setState({savedItems:ni({},this.state.savedItems)}),v("fn","itemRemoved"))}setCurrentItem(e){const t=o();return e.htmlMode=e.htmlMode||this.state.prefs.htmlMode||F.HTML,e.cssMode=e.cssMode||this.state.prefs.cssMode||N.CSS,e.jsMode=e.jsMode||this.state.prefs.jsMode||W.JS,this.setState({currentItem:e},t.resolve),this.isAutoSavingEnabled=!1,this.setState({unsavedEditCount:0}),t.promise}saveBtnClickHandler(){v("ui","saveBtnClick",this.state.currentItem.id?"saved":"new"),this.saveItem()}populateItemsInSavedPane(){this.setState({savedItems:ni({},this.state.savedItems)}),this.toggleSavedItemsPane()}toggleSavedItemsPane(){this.setState({isSavedItemPaneOpen:!this.state.isSavedItemPaneOpen}),this.state.isSavedItemPaneOpen?window.searchInput.focus():window.searchInput.value="",document.body.classList[this.state.isSavedItemPaneOpen?"add":"remove"]("overlay-visible")}async fetchItems(e,t){var n=o();this.state.savedItems={};var s=[];return window.user&&!t?(s=await un.getAllItems(),c("got items"),e&&s.forEach((e)=>{this.state.savedItems[e.id]=e}),n.resolve(s),n.promise):(db.local.get("items",(t)=>{var o=Object.getOwnPropertyNames(t.items||{});o.length||n.resolve([]),v("fn","fetchItems",o.length);for(let a=0;a{e&&(this.state.savedItems[o[a]]=t[o[a]]),s.push(t[o[a]]),o.length===s.length&&n.resolve(s)})}),n.promise)}openSavedItemsPane(){this.setState({isFetchingItems:!0}),this.fetchItems(!0).then((e)=>{this.setState({isFetchingItems:!1}),this.populateItemsInSavedPane(e)})}openAddLibrary(){this.setState({isAddLibraryModalOpen:!0})}closeSavedItemsPane(){this.setState({isSavedItemPaneOpen:!1}),document.body.classList.remove("overlay-visible"),this.editorWithFocus&&this.editorWithFocus.focus()}componentDidMount(){document.body.style.height=`${window.innerHeight}px`,window.addEventListener("keydown",(e)=>{(e.ctrlKey||e.metaKey)&&83===e.keyCode&&(e.preventDefault(),this.saveItem(),v("ui","saveItemKeyboardShortcut")),(e.ctrlKey||e.metaKey)&&e.shiftKey&&53===e.keyCode?(e.preventDefault(),this.contentWrap.setPreviewContent(!0,!0),v("ui","previewKeyboardShortcut")):(e.ctrlKey||e.metaKey)&&79===e.keyCode?(e.preventDefault(),this.openSavedItemsPane(),v("ui","openCreationKeyboardShortcut")):(e.ctrlKey||e.metaKey)&&e.shiftKey&&191===e.keyCode?(e.preventDefault(),this.setState({isKeyboardShortcutsModalOpen:!this.state.isKeyboardShortcutsModalOpen}),v("ui","showKeyboardShortcutsShortcut")):27===e.keyCode&&this.closeSavedItemsPane()})}closeAllOverlays(){this.state.isSavedItemPaneOpen&&this.closeSavedItemsPane(),this.setState({isAddLibraryModalOpen:!1,isSettingsModalOpen:!1,isHelpModalOpen:!1,isNotificationsModalOpen:!1,isLoginModalOpen:!1,isProfileModalOpen:!1,isSupportDeveloperModalOpen:!1,isKeyboardShortcutsModalOpen:!1,isAskToImportModalOpen:!1,isOnboardModalOpen:!1})}onExternalLibChange(e){c("onExternalLibChange"),this.state.currentItem.externalLibs={js:e.js,css:e.css},this.updateExternalLibCount(),this.setState({currentItem:ni({},this.state.currentItem)}),this.contentWrap.setPreviewContent(!0),gn.add("Libraries updated.")}updateExternalLibCount(){var e=0;e+=this.state.currentItem.externalLibs.js.split("\n").filter((e)=>!!e).length,e+=this.state.currentItem.externalLibs.css.split("\n").filter((e)=>!!e).length,this.setState({externalLibCount:e})}toggleLayout(e){return e=500>window.innerWidth?2:e,this.state.currentLayoutMode===e?(this.contentWrap.resetSplitting(),void this.setState({currentLayoutMode:e})):void([1,2,3,4,5].forEach((e)=>{window[`layoutBtn${e}`].classList.remove("selected"),document.body.classList.remove(`layout-${e}`)}),$("#layoutBtn"+e).classList.add("selected"),document.body.classList.add("layout-"+e),this.setState({currentLayoutMode:e},()=>{this.contentWrap.resetSplitting(),this.contentWrap.setPreviewContent(!0)}))}layoutBtnClickHandler(e){this.saveSetting("layoutMode",e),v("ui","toggleLayoutClick",e),this.toggleLayout(e)}getCodePaneSizes(){var e;const t=this.state.currentLayoutMode;var n=2===t||5===t?"width":"height";try{e=[htmlCodeEl.style[n],cssCodeEl.style[n],jsCodeEl.style[n]]}catch(t){e=[33.33,33.33,33.33]}finally{return e}}getMainPaneSizes(){var e;const t=this.state.currentLayoutMode;var n=2===t?"height":"width";try{e=[+$("#js-code-side").style[n].match(/([\d.]+)%/)[1],+$("#js-demo-side").style[n].match(/([\d.]+)%/)[1]]}catch(t){e=[50,50]}finally{return e}}saveSetting(e,t){const n=o();return db.local.set({[e]:t},n.resolve),n.promise}saveCode(e){return this.state.currentItem.updatedOn=Date.now(),this.state.currentItem.layoutMode=this.state.currentLayoutMode,this.state.currentItem.sizes=this.getCodePaneSizes(),this.state.currentItem.mainSizes=this.getMainPaneSizes(),c("saving key",e||this.state.currentItem.id,this.state.currentItem),un.setItem(e||this.state.currentItem.id,this.state.currentItem).then(function(){window.user&&!navigator.onLine?gn.add("Item saved locally. Will save to account when you are online."):gn.add("Item saved."),this.setState({unsavedEditCount:0})}.bind(this))}saveItem(){if(!window.user&&!window.localStorage[oi.LOGIN_AND_SAVE_MESSAGE_SEEN]){const e=confirm("Saving without signing in will save your work only on this machine and this browser. If you want it to be secure & available anywhere, please login in your account and then save.\n\nDo you still want to continue saving locally?");if(window.localStorage[oi.LOGIN_AND_SAVE_MESSAGE_SEEN]=!0,!e)return v("ui",oi.LOGIN_AND_SAVE_MESSAGE_SEEN,"login"),this.closeAllOverlays(),void this.setState({isLoginModalOpen:!0});v("ui",oi.LOGIN_AND_SAVE_MESSAGE_SEEN,"local")}var e=!this.state.currentItem.id;this.state.currentItem.id=this.state.currentItem.id||"item-"+l(),this.setState({isSaving:!0}),this.saveCode().then(()=>{this.setState({isSaving:!1}),!this.isAutoSavingEnabled&&this.state.prefs.autoSave&&(this.isAutoSavingEnabled=!0,gn.add("Auto-save enabled."))}),e&&un.setItemForUser(this.state.currentItem.id)}onCodeModeChange(e,t){const n=ni({},this.state.currentItem);n[`${e}Mode`]=t,this.setState({currentItem:n})}onCodeChange(e,t,n){this.state.currentItem[e]=t,n&&(this.setState({unsavedEditCount:this.state.unsavedEditCount+1}),0==this.state.unsavedEditCount%si&&this.state.unsavedEditCount>=si&&(window.saveBtn.classList.add("animated"),window.saveBtn.classList.add("wobble"),window.saveBtn.addEventListener("animationend",()=>{window.saveBtn.classList.remove("animated"),window.saveBtn.classList.remove("wobble")})))}onCodeSettingsChange(e,t){this.state.currentItem[`${e}Settings`]={acssConfig:t}}titleInputBlurHandler(t){this.state.currentItem.title=t.target.value,this.state.currentItem.id&&(this.saveItem(),v("ui","titleChanged"))}updateSetting(t){if(t){var e=t.target.dataset.setting,n={},o=t.target;c(e,"checkbox"===o.type?o.checked:o.value);const s=ni({},this.state.prefs);s[e]="checkbox"===o.type?o.checked:o.value,n[e]=s[e],this.setState({prefs:s}),db.sync.set(n,function(){gn.add("Setting saved")}),window.user&&window.db.getDb().then((t)=>{t.collection("users").doc(window.user.uid).update({[`settings.${e}`]:this.state.prefs[e]}).then((t)=>{c(`Setting "${e}" for user`,t)}).catch((e)=>c(e))}),v("ui","updatePref-"+e,s[e])}const s=this.state.prefs;runBtn.classList[s.autoPreview?"add":"remove"]("hide"),this.contentWrap.applyCodemirrorSettings(this.state.prefs),s.autoSave?!this.autoSaveInterval&&(this.autoSaveInterval=setInterval(()=>{this.autoSaveLoop()},this.AUTO_SAVE_INTERVAL)):(clearInterval(this.autoSaveInterval),this.autoSaveInterval=null),document.body.classList[s.lightVersion?"add":"remove"]("light-version")}autoSaveLoop(){this.isAutoSavingEnabled&&this.state.unsavedEditCount&&this.saveItem()}loginBtnClickHandler(){this.setState({isLoginModalOpen:!0})}profileBtnClickHandler(){this.setState({isProfileModalOpen:!0})}logout(){if(this.state.unsavedEditCount){var e=confirm("You have unsaved changes. Do you still want to logout?");if(!e)return}v("fn","loggedOut"),Vn.logout(),this.setState({isProfileModalOpen:!1}),gn.add("Log out successfull")}itemClickHandler(e){setTimeout(()=>{this.openItem(e)},350),this.toggleSavedItemsPane()}itemRemoveBtnClickHandler(e){this.removeItem(e)}itemForkBtnClickHandler(e){this.toggleSavedItemsPane(),setTimeout(()=>{this.forkItem(e)},350)}newBtnClickHandler(){if(v("ui","newBtnClick"),this.state.unsavedEditCount){var e=confirm("You have unsaved changes. Do you still want to create something new?");e&&this.createNewItem()}else this.createNewItem()}openBtnClickHandler(){v("ui","openBtnClick"),this.openSavedItemsPane()}detachedPreviewBtnHandler(){v("ui","detachPreviewBtnClick"),this.contentWrap.detachPreview()}notificationsBtnClickHandler(){return this.setState({isNotificationsModalOpen:!0}),this.state.isNotificationsModalOpen&&!this.hasSeenNotifications&&(this.hasSeenNotifications=!0,this.setState({hasUnseenChangelog:!1}),window.db.setUserLastSeenVersion(ii)),v("ui","notificationButtonClick",ii),!1}codepenBtnClickHandler(t){if(this.state.currentItem.cssMode===N.ACSS)return alert("Oops! CodePen doesn't supports Atomic CSS currently. \nHere is something you can still do -> https://medium.com/web-maker/sharing-your-atomic-css-work-on-codepen-a402001b26ab"),void t.preventDefault();var e={title:"A Web Maker experiment",html:this.state.currentItem.html,css:this.state.currentItem.css,js:this.state.currentItem.js,html_pre_processor:z[this.state.currentItem.htmlMode].codepenVal,css_pre_processor:z[this.state.currentItem.cssMode].codepenVal,js_pre_processor:z[this.state.currentItem.jsMode].codepenVal,css_external:this.state.currentItem.externalLibs.css.split("\n").join(";"),js_external:this.state.currentItem.externalLibs.js.split("\n").join(";")};this.state.currentItem.title.match(/Untitled\s\d\d*-\d/)||(e.title=this.state.currentItem.title),e=JSON.stringify(e),window.codepenForm.querySelector("input").value=e,window.codepenForm.submit(),v("ui","openInCodepen"),t.preventDefault()}saveHtmlBtnClickHandler(t){f(this.state.currentItem),v("ui","saveHtmlClick"),t.preventDefault()}runBtnClickHandler(){this.contentWrap.setPreviewContent(!0,!0),v("ui","runBtnClick")}exportItems(){b().then(()=>{this.fetchItems().then((e)=>{var t=new Date,n=["web-maker-export",t.getFullYear(),t.getMonth()+1,t.getDate(),t.getHours(),t.getMinutes(),t.getSeconds()].join("-");n+=".json";var o=new Blob([JSON.stringify(e,!1,2)],{type:"application/json;charset=UTF-8"});p(n,o),v("fn","exportItems")})})}exportBtnClickHandler(t){this.exportItems(),t.preventDefault(),v("ui","exportBtnClicked")}screenshotBtnClickHandler(t){this.contentWrap.getDemoFrame((e)=>{B(e.getBoundingClientRect())}),t.preventDefault()}openSupportDeveloperModal(){this.closeAllOverlays(),this.setState({isSupportDeveloperModalOpen:!0})}supportDeveloperBtnClickHandler(t){this.openSupportDeveloperModal(t)}dontAskToImportAnymore(t){this.setState({isAskToImportModalOpen:!1}),window.localStorage[oi.ASKED_TO_IMPORT_CREATIONS]=!0,t&&v("ui","dontAskToImportBtnClick")}importCreationsAndSettingsIntoApp(){this.mergeImportedItems(this.oldSavedItems).then(()=>{v("fn","oldItemsImported"),this.dontAskToImportAnymore()})}editorFocusHandler(e){this.editorWithFocus=e}modalOverlayClickHandler(){this.closeAllOverlays()}render(){return Object(V.h)("div",null,Object(V.h)("div",{class:"main-container"},Object(V.h)(w,{externalLibCount:this.state.externalLibCount,openBtnHandler:this.openBtnClickHandler.bind(this),newBtnHandler:this.newBtnClickHandler.bind(this),saveBtnHandler:this.saveBtnClickHandler.bind(this),loginBtnHandler:this.loginBtnClickHandler.bind(this),profileBtnHandler:this.profileBtnClickHandler.bind(this),addLibraryBtnHandler:this.openAddLibrary.bind(this),runBtnClickHandler:this.runBtnClickHandler.bind(this),isFetchingItems:this.state.isFetchingItems,isSaving:this.state.isSaving,title:this.state.currentItem.title,titleInputBlurHandler:this.titleInputBlurHandler.bind(this),user:this.state.user,unsavedEditCount:this.state.unsavedEditCount}),Object(V.h)(zt,{currentLayoutMode:this.state.currentLayoutMode,currentItem:this.state.currentItem,onCodeChange:this.onCodeChange.bind(this),onCodeSettingsChange:this.onCodeSettingsChange.bind(this),onCodeModeChange:this.onCodeModeChange.bind(this),onRef:(e)=>this.contentWrap=e,prefs:this.state.prefs,onEditorFocus:this.editorFocusHandler.bind(this)}),ai,Object(V.h)(cn,{layoutBtnClickHandler:this.layoutBtnClickHandler.bind(this),helpBtnClickHandler:()=>this.setState({isHelpModalOpen:!0}),settingsBtnClickHandler:()=>this.setState({isSettingsModalOpen:!0}),notificationsBtnClickHandler:this.notificationsBtnClickHandler.bind(this),supportDeveloperBtnClickHandler:this.supportDeveloperBtnClickHandler.bind(this),detachedPreviewBtnHandler:this.detachedPreviewBtnHandler.bind(this),codepenBtnClickHandler:this.codepenBtnClickHandler.bind(this),saveHtmlBtnClickHandler:this.saveHtmlBtnClickHandler.bind(this),keyboardShortcutsBtnClickHandler:()=>this.setState({isKeyboardShortcutsModalOpen:!0}),screenshotBtnClickHandler:this.screenshotBtnClickHandler.bind(this),hasUnseenChangelog:this.state.hasUnseenChangelog})),Object(V.h)(Cn,{items:this.state.savedItems,isOpen:this.state.isSavedItemPaneOpen,closeHandler:this.closeSavedItemsPane.bind(this),itemClickHandler:this.itemClickHandler.bind(this),itemRemoveBtnClickHandler:this.itemRemoveBtnClickHandler.bind(this),itemForkBtnClickHandler:this.itemForkBtnClickHandler.bind(this),exportBtnClickHandler:this.exportBtnClickHandler.bind(this)}),ri,li,Object(V.h)(bt,{show:this.state.isAddLibraryModalOpen,closeHandler:()=>this.setState({isAddLibraryModalOpen:!1})},Object(V.h)(En,{js:this.state.currentItem.externalLibs?this.state.currentItem.externalLibs.js:"",css:this.state.currentItem.externalLibs?this.state.currentItem.externalLibs.css:"",onChange:this.onExternalLibChange.bind(this)})),Object(V.h)(bt,{show:this.state.isNotificationsModalOpen,closeHandler:()=>this.setState({isNotificationsModalOpen:!1})},Object(V.h)(_,{onSupportBtnClick:this.openSupportDeveloperModal.bind(this)})),Object(V.h)(bt,{extraClasses:"modal--settings",show:this.state.isSettingsModalOpen,closeHandler:()=>this.setState({isSettingsModalOpen:!1})},Object(V.h)(us,{prefs:this.state.prefs,onChange:this.updateSetting.bind(this)})),Object(V.h)(bt,{extraClasses:"login-modal",show:this.state.isLoginModalOpen,closeHandler:()=>this.setState({isLoginModalOpen:!1})},di),Object(V.h)(bt,{show:this.state.isProfileModalOpen,closeHandler:()=>this.setState({isProfileModalOpen:!1})},Object(V.h)(I,{user:this.state.user,logoutBtnHandler:this.logout.bind(this)})),Object(V.h)(O,{show:this.state.isHelpModalOpen,closeHandler:()=>this.setState({isHelpModalOpen:!1}),onSupportBtnClick:this.openSupportDeveloperModal.bind(this)}),Object(V.h)(H,{show:this.state.isSupportDeveloperModalOpen,closeHandler:()=>this.setState({isSupportDeveloperModalOpen:!1})}),Object(V.h)(A,{show:this.state.isKeyboardShortcutsModalOpen,closeHandler:()=>this.setState({isKeyboardShortcutsModalOpen:!1})}),Object(V.h)(E,{show:this.state.isAskToImportModalOpen,closeHandler:()=>this.setState({isAskToImportModalOpen:!1}),oldSavedCreationsCount:this.oldSavedCreationsCount,importBtnClickHandler:this.importCreationsAndSettingsIntoApp.bind(this),dontAskBtnClickHandler:this.dontAskToImportAnymore.bind(this)}),Object(V.h)(T,{show:this.state.isOnboardModalOpen,closeHandler:()=>this.setState({isOnboardModalOpen:!1})}),Object(V.h)(ft.a,{into:"body"},Object(V.h)("div",{class:"modal-overlay",onClick:this.modalOverlayClickHandler.bind(this)})),ci,hi)}};t["default"]=pi}},["pwNi"]); \ No newline at end of file diff --git a/app/service-worker.js b/app/service-worker.js index ef59101..1b34ad3 100644 --- a/app/service-worker.js +++ b/app/service-worker.js @@ -37,7 +37,7 @@ /* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */ 'use strict'; -var precacheConfig = [["FiraCode.ttf","fa1f8c8961adca519738d9518139579c"],["FixedSys.ttf","43cc87e8f9adba81b9d63b6e2d15db57"],["Inconsolata.ttf","b0639eb725c0df94f68b779889679457"],["Monoid.ttf","9b27db986ad2a74c522e9d3b6f7e2a63"],["detached-window.js","f05b0a0f2a8cc967028fb4f95f4a9614"],["icon-128.png","cf558ed413851d046b9dcc84c1d57543"],["icon-48.png","ca68956f464ed4fd2e09c66d5edaed5f"],["index.html","2df6e01f236e6c99bf7c4f84feeca789"],["lib/codemirror/mode/coffeescript/coffeescript.js","dea87b9f4c669789c4760605d947f1a9"],["lib/codemirror/mode/css/css.js","6c9ca32a78c120340e588ed3df734138"],["lib/codemirror/mode/css/gss.html","9afa6e2f3a7daa6127a3f26e2e68005c"],["lib/codemirror/mode/css/gss_test.js","e40c6fd9abdc6edc2b29e521bda726e1"],["lib/codemirror/mode/css/less.html","a35ff50857d48bb2f4df8ac737f35d64"],["lib/codemirror/mode/css/scss.html","8c96251f27727a9b23b45c41511e23a0"],["lib/codemirror/mode/haml/haml.js","9abc1679e0f54dcdd62d2326ed6133f5"],["lib/codemirror/mode/htmlembedded/htmlembedded.js","67f745ab3879bf7bc3029ac75ea3e181"],["lib/codemirror/mode/htmlmixed/htmlmixed.js","2d6915b576f267e93f0e1cf72f31af37"],["lib/codemirror/mode/javascript/javascript.js","3b2f1591e3175a24846cb182943f2a40"],["lib/codemirror/mode/javascript/json-ld.html","a2a5069194b78b6b5523cace263cab06"],["lib/codemirror/mode/javascript/typescript.html","76c2ffb883a133aa0fc5cc75ec0c56f5"],["lib/codemirror/mode/jsx/jsx.js","7bee6944931c2cc6ccd99b50fca637db"],["lib/codemirror/mode/markdown/markdown.js","30dd4984e2e929429d70cf5174b35c5d"],["lib/codemirror/mode/meta.js","6e456ea5fd8920c85d5281bd1efecb4c"],["lib/codemirror/mode/pug/pug.js","e988fd72c82f3b11836f6a06f7452436"],["lib/codemirror/mode/sass/sass.js","bd31ac70e9a457abc2789c2b83a21984"],["lib/codemirror/mode/stylus/stylus.js","81e2d281ecbb1dcf5c86857097ae60a7"],["lib/codemirror/mode/xml/xml.js","80f64aaafa6af7844d14f32f3219bb26"],["lib/codemirror/theme/3024-day.css","73c8f41583b4b71dbe1e5eac5c96f1a9"],["lib/codemirror/theme/3024-night.css","745180be9a932f24c6c0dd4ebdf5a0ed"],["lib/codemirror/theme/abcdef.css","8004cb71fd65e58bdfa64fdd55241315"],["lib/codemirror/theme/ambiance-mobile.css","256f2dd130b80c6afaa40fddf700d12a"],["lib/codemirror/theme/ambiance.css","6a200e1f3976929816cf3ac4675c810a"],["lib/codemirror/theme/base16-dark.css","84b6347918411d58d7f9b65a7ee87f65"],["lib/codemirror/theme/base16-light.css","037c7f3d16fe6d5ae2baa532e334172b"],["lib/codemirror/theme/base2tone-meadow-dark.css","f9dd12e2e51fc1575c57f3e5edc2232f"],["lib/codemirror/theme/bespin.css","cc414e4ec18bc89b3c79935b0e27fc20"],["lib/codemirror/theme/blackboard.css","cf9366960ff65c8101793bc64fe13e88"],["lib/codemirror/theme/cobalt.css","3488b576456693fd7ced2da0e10c8a16"],["lib/codemirror/theme/colorforth.css","b2ee8d2296277fc2811a7473ee4e9977"],["lib/codemirror/theme/dracula.css","e514d652ae86bfeaed34237b7d3afe44"],["lib/codemirror/theme/duotone-dark.css","02ec891b23125aaf625d978a39fd24ca"],["lib/codemirror/theme/duotone-light.css","608d11459665117d708651ce7f803fde"],["lib/codemirror/theme/eclipse.css","194369eec66630cfaf662ce5f0a193be"],["lib/codemirror/theme/elegant.css","0a4227e805a9d5f73a55dd248c1b052d"],["lib/codemirror/theme/erlang-dark.css","b5543f5273c968449760ab0d6a2af6dc"],["lib/codemirror/theme/hopscotch.css","b924ed31af30b1c68e5a01fc3c9b0553"],["lib/codemirror/theme/icecoder.css","576d776abdf7e28ea9f84e2eb161a20d"],["lib/codemirror/theme/isotope.css","7bb44bff5190c427de5ae750d6369633"],["lib/codemirror/theme/lesser-dark.css","da2c896bff035cec86fa98b6dc13f7cc"],["lib/codemirror/theme/liquibyte.css","9f37e7a4f3c02bec9bb735b78ed082d6"],["lib/codemirror/theme/material.css","11e812a3688805b5c187a6e6852bafe1"],["lib/codemirror/theme/mbo.css","55ff4bdd8a92c3dcbfd5421c532b3059"],["lib/codemirror/theme/mdn-like.css","79f8dabc5593d01d27bc824b801f9f05"],["lib/codemirror/theme/midnight.css","950e76dca6461ee1a2eac39f2d886613"],["lib/codemirror/theme/monokai.css","31c75ebee6311d49c046ffbbb91028f4"],["lib/codemirror/theme/neat.css","6b19894b9787c6791c250a95d0d4f8d6"],["lib/codemirror/theme/neo.css","2886072b53043c167e6f8765606c705c"],["lib/codemirror/theme/night.css","fe3ce7650a77e7e3887816dd7b6d880d"],["lib/codemirror/theme/panda-syntax.css","acbf94261e43c1f29c2252eb445de032"],["lib/codemirror/theme/paraiso-dark.css","3c24cee0dfac767713840b24e8359c99"],["lib/codemirror/theme/paraiso-light.css","e245bbfd22b4f61efe526ff13903f19e"],["lib/codemirror/theme/pastel-on-dark.css","48aae1a42733db57bd0a260ce0d83975"],["lib/codemirror/theme/railscasts.css","a5e7682d89da46244e5464d9572e24d8"],["lib/codemirror/theme/rubyblue.css","52bb601017a90bca522d66f6e82e73aa"],["lib/codemirror/theme/seti.css","f71668880eb1625f420ceaad670436f0"],["lib/codemirror/theme/solarized dark.css","4d05a166d713bb1ac24833061c1522d7"],["lib/codemirror/theme/solarized light.css","4d05a166d713bb1ac24833061c1522d7"],["lib/codemirror/theme/the-matrix.css","33c49ceeedafd0a08e712e465e3ad3ce"],["lib/codemirror/theme/tomorrow-night-bright.css","777d36e1c5bbfeb3bf2ca8dd607eee93"],["lib/codemirror/theme/tomorrow-night-eighties.css","5ceb5531fbe074d5190b55e8c725051e"],["lib/codemirror/theme/ttcn.css","d2cb74dfae563a10e9c286357429ea8b"],["lib/codemirror/theme/twilight.css","684040adf66ef89355cb7ebc6b54b00b"],["lib/codemirror/theme/vibrant-ink.css","f10004836fb29cc9a08c987d3e18938a"],["lib/codemirror/theme/xq-dark.css","60f162f0c4240e7352364d436b5598fa"],["lib/codemirror/theme/xq-light.css","447e80da7fe8c5c2bcf39127200cead2"],["lib/codemirror/theme/yeti.css","623dc805bc84dd6d25deef376593354e"],["lib/codemirror/theme/zenburn.css","94ad50bf3d048ed92cc513cd901dc685"],["lib/screenlog.js","974cb1ec0473b11ae4834028c1820816"],["lib/transpilers/atomizer.browser.js","c2925b84a627b017797664530f284618"],["lib/transpilers/babel-polyfill.min.js","6fef55c62df380d41c8f42f8b0c1f4da"],["lib/transpilers/babel.min.js","77a1a84bbc2661db874c738f9b3ba375"],["lib/transpilers/coffee-script.js","df68698ca5d438d7fb70c3c259155a37"],["lib/transpilers/jade.js","529e365c68f8d5efc4cea18be310bd76"],["lib/transpilers/less.min.js","6fd457ee80aaf9aa8758fe8a2345c970"],["lib/transpilers/marked.js","93163e72d380637970dc957c6cf75a77"],["lib/transpilers/sass.js","1263518af3f8b2090c9b08d195bd20d9"],["lib/transpilers/sass.worker.js","0d6c944b36008580fbedc09642f7f656"],["lib/transpilers/stylus.min.js","58f6030903ab52f596fb407dcd3df34f"],["lib/transpilers/typescript.js","cc0882a3185037052e21fa06a38ef077"],["partials/ask-to-import-modal.html","4c41c4fe11e4812ba6258d8e04d27d40"],["partials/changelog.html","d07acae211850ce1db53678b6258f9e5"],["partials/help-modal.html","c43bfe929337f371221503e83c62bdb8"],["partials/keyboard-shortcuts.html","d7c4124380a4eeb18968d55276d19591"],["partials/login-modal.html","7bb43bece90a93308919fb00162ee669"],["partials/onboard-modal.html","e9597ff891a70080a418e98abf198a5d"],["partials/pledge-modal.html","13f16984222c6447fb830250a818b763"],["patreon.png","8b4321f782e84764e556af3dee32a131"],["preview.html","ad041893596a3a2045aeab80feb24532"],["script.js","3bd018f1ac5fbda3d900a2c4feb89c42"],["style.css","52c81c000d75a52160976381ee0df9fb"],["vendor.css","6ed94306315b8aaf789c53091c23bb4b"],["vendor.js","e03ecbe2db9ff1eadc337415db0f1f80"]]; +var precacheConfig = [["FiraCode.ttf","fa1f8c8961adca519738d9518139579c"],["FixedSys.ttf","43cc87e8f9adba81b9d63b6e2d15db57"],["Inconsolata.ttf","b0639eb725c0df94f68b779889679457"],["Monoid.ttf","9b27db986ad2a74c522e9d3b6f7e2a63"],["detached-window.js","f05b0a0f2a8cc967028fb4f95f4a9614"],["icon-128.png","cf558ed413851d046b9dcc84c1d57543"],["icon-48.png","ca68956f464ed4fd2e09c66d5edaed5f"],["index.html","2df6e01f236e6c99bf7c4f84feeca789"],["lib/codemirror/mode/coffeescript/coffeescript.js","dea87b9f4c669789c4760605d947f1a9"],["lib/codemirror/mode/css/css.js","6c9ca32a78c120340e588ed3df734138"],["lib/codemirror/mode/css/gss.html","9afa6e2f3a7daa6127a3f26e2e68005c"],["lib/codemirror/mode/css/gss_test.js","e40c6fd9abdc6edc2b29e521bda726e1"],["lib/codemirror/mode/css/less.html","a35ff50857d48bb2f4df8ac737f35d64"],["lib/codemirror/mode/css/scss.html","8c96251f27727a9b23b45c41511e23a0"],["lib/codemirror/mode/haml/haml.js","9abc1679e0f54dcdd62d2326ed6133f5"],["lib/codemirror/mode/htmlembedded/htmlembedded.js","67f745ab3879bf7bc3029ac75ea3e181"],["lib/codemirror/mode/htmlmixed/htmlmixed.js","2d6915b576f267e93f0e1cf72f31af37"],["lib/codemirror/mode/javascript/javascript.js","3b2f1591e3175a24846cb182943f2a40"],["lib/codemirror/mode/javascript/json-ld.html","a2a5069194b78b6b5523cace263cab06"],["lib/codemirror/mode/javascript/typescript.html","76c2ffb883a133aa0fc5cc75ec0c56f5"],["lib/codemirror/mode/jsx/jsx.js","7bee6944931c2cc6ccd99b50fca637db"],["lib/codemirror/mode/markdown/markdown.js","30dd4984e2e929429d70cf5174b35c5d"],["lib/codemirror/mode/meta.js","6e456ea5fd8920c85d5281bd1efecb4c"],["lib/codemirror/mode/pug/pug.js","e988fd72c82f3b11836f6a06f7452436"],["lib/codemirror/mode/sass/sass.js","bd31ac70e9a457abc2789c2b83a21984"],["lib/codemirror/mode/stylus/stylus.js","81e2d281ecbb1dcf5c86857097ae60a7"],["lib/codemirror/mode/xml/xml.js","80f64aaafa6af7844d14f32f3219bb26"],["lib/codemirror/theme/3024-day.css","73c8f41583b4b71dbe1e5eac5c96f1a9"],["lib/codemirror/theme/3024-night.css","745180be9a932f24c6c0dd4ebdf5a0ed"],["lib/codemirror/theme/abcdef.css","8004cb71fd65e58bdfa64fdd55241315"],["lib/codemirror/theme/ambiance-mobile.css","256f2dd130b80c6afaa40fddf700d12a"],["lib/codemirror/theme/ambiance.css","6a200e1f3976929816cf3ac4675c810a"],["lib/codemirror/theme/base16-dark.css","84b6347918411d58d7f9b65a7ee87f65"],["lib/codemirror/theme/base16-light.css","037c7f3d16fe6d5ae2baa532e334172b"],["lib/codemirror/theme/base2tone-meadow-dark.css","f9dd12e2e51fc1575c57f3e5edc2232f"],["lib/codemirror/theme/bespin.css","cc414e4ec18bc89b3c79935b0e27fc20"],["lib/codemirror/theme/blackboard.css","cf9366960ff65c8101793bc64fe13e88"],["lib/codemirror/theme/cobalt.css","3488b576456693fd7ced2da0e10c8a16"],["lib/codemirror/theme/colorforth.css","b2ee8d2296277fc2811a7473ee4e9977"],["lib/codemirror/theme/dracula.css","e514d652ae86bfeaed34237b7d3afe44"],["lib/codemirror/theme/duotone-dark.css","02ec891b23125aaf625d978a39fd24ca"],["lib/codemirror/theme/duotone-light.css","608d11459665117d708651ce7f803fde"],["lib/codemirror/theme/eclipse.css","194369eec66630cfaf662ce5f0a193be"],["lib/codemirror/theme/elegant.css","0a4227e805a9d5f73a55dd248c1b052d"],["lib/codemirror/theme/erlang-dark.css","b5543f5273c968449760ab0d6a2af6dc"],["lib/codemirror/theme/hopscotch.css","b924ed31af30b1c68e5a01fc3c9b0553"],["lib/codemirror/theme/icecoder.css","576d776abdf7e28ea9f84e2eb161a20d"],["lib/codemirror/theme/isotope.css","7bb44bff5190c427de5ae750d6369633"],["lib/codemirror/theme/lesser-dark.css","da2c896bff035cec86fa98b6dc13f7cc"],["lib/codemirror/theme/liquibyte.css","9f37e7a4f3c02bec9bb735b78ed082d6"],["lib/codemirror/theme/material.css","11e812a3688805b5c187a6e6852bafe1"],["lib/codemirror/theme/mbo.css","55ff4bdd8a92c3dcbfd5421c532b3059"],["lib/codemirror/theme/mdn-like.css","79f8dabc5593d01d27bc824b801f9f05"],["lib/codemirror/theme/midnight.css","950e76dca6461ee1a2eac39f2d886613"],["lib/codemirror/theme/monokai.css","31c75ebee6311d49c046ffbbb91028f4"],["lib/codemirror/theme/neat.css","6b19894b9787c6791c250a95d0d4f8d6"],["lib/codemirror/theme/neo.css","2886072b53043c167e6f8765606c705c"],["lib/codemirror/theme/night.css","fe3ce7650a77e7e3887816dd7b6d880d"],["lib/codemirror/theme/panda-syntax.css","acbf94261e43c1f29c2252eb445de032"],["lib/codemirror/theme/paraiso-dark.css","3c24cee0dfac767713840b24e8359c99"],["lib/codemirror/theme/paraiso-light.css","e245bbfd22b4f61efe526ff13903f19e"],["lib/codemirror/theme/pastel-on-dark.css","48aae1a42733db57bd0a260ce0d83975"],["lib/codemirror/theme/railscasts.css","a5e7682d89da46244e5464d9572e24d8"],["lib/codemirror/theme/rubyblue.css","52bb601017a90bca522d66f6e82e73aa"],["lib/codemirror/theme/seti.css","f71668880eb1625f420ceaad670436f0"],["lib/codemirror/theme/solarized dark.css","4d05a166d713bb1ac24833061c1522d7"],["lib/codemirror/theme/solarized light.css","4d05a166d713bb1ac24833061c1522d7"],["lib/codemirror/theme/the-matrix.css","33c49ceeedafd0a08e712e465e3ad3ce"],["lib/codemirror/theme/tomorrow-night-bright.css","777d36e1c5bbfeb3bf2ca8dd607eee93"],["lib/codemirror/theme/tomorrow-night-eighties.css","5ceb5531fbe074d5190b55e8c725051e"],["lib/codemirror/theme/ttcn.css","d2cb74dfae563a10e9c286357429ea8b"],["lib/codemirror/theme/twilight.css","684040adf66ef89355cb7ebc6b54b00b"],["lib/codemirror/theme/vibrant-ink.css","f10004836fb29cc9a08c987d3e18938a"],["lib/codemirror/theme/xq-dark.css","60f162f0c4240e7352364d436b5598fa"],["lib/codemirror/theme/xq-light.css","447e80da7fe8c5c2bcf39127200cead2"],["lib/codemirror/theme/yeti.css","623dc805bc84dd6d25deef376593354e"],["lib/codemirror/theme/zenburn.css","94ad50bf3d048ed92cc513cd901dc685"],["lib/screenlog.js","974cb1ec0473b11ae4834028c1820816"],["lib/transpilers/atomizer.browser.js","c2925b84a627b017797664530f284618"],["lib/transpilers/babel-polyfill.min.js","6fef55c62df380d41c8f42f8b0c1f4da"],["lib/transpilers/babel.min.js","77a1a84bbc2661db874c738f9b3ba375"],["lib/transpilers/coffee-script.js","df68698ca5d438d7fb70c3c259155a37"],["lib/transpilers/jade.js","529e365c68f8d5efc4cea18be310bd76"],["lib/transpilers/less.min.js","6fd457ee80aaf9aa8758fe8a2345c970"],["lib/transpilers/marked.js","93163e72d380637970dc957c6cf75a77"],["lib/transpilers/sass.js","1263518af3f8b2090c9b08d195bd20d9"],["lib/transpilers/sass.worker.js","0d6c944b36008580fbedc09642f7f656"],["lib/transpilers/stylus.min.js","58f6030903ab52f596fb407dcd3df34f"],["lib/transpilers/typescript.js","cc0882a3185037052e21fa06a38ef077"],["partials/ask-to-import-modal.html","4c41c4fe11e4812ba6258d8e04d27d40"],["partials/changelog.html","d07acae211850ce1db53678b6258f9e5"],["partials/help-modal.html","c43bfe929337f371221503e83c62bdb8"],["partials/keyboard-shortcuts.html","d7c4124380a4eeb18968d55276d19591"],["partials/login-modal.html","7bb43bece90a93308919fb00162ee669"],["partials/onboard-modal.html","e9597ff891a70080a418e98abf198a5d"],["partials/pledge-modal.html","13f16984222c6447fb830250a818b763"],["patreon.png","8b4321f782e84764e556af3dee32a131"],["preview.html","ad041893596a3a2045aeab80feb24532"],["script.js","c2bfe11d5518028166f30341eb524156"],["style.css","b423a72dd541d4ffb321b914c329d120"],["vendor.css","6ed94306315b8aaf789c53091c23bb4b"],["vendor.js","416d6e23c564d952f01a9e8da2654315"]]; var cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : ''); diff --git a/app/style.css b/app/style.css index 8a9b436..111eab1 100644 --- a/app/style.css +++ b/app/style.css @@ -1 +1 @@ -:root{--color-bg:#252637;--color-sidebar:#3a2b63;--code-font-size:16px;--color-button:#0074d9}body{margin:0;padding:0;background:rgba(0,0,0,.5);background:var(--color-bg);color:rgba(255,255,255,.9);min-height:100vh;font-size:87.5%;position:relative;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Segoe UI Emoji','Segoe UI Symbol'}h1{margin-top:0}a{text-decoration:none;color:#d61237;cursor:pointer}p{line-height:1.65}.hide{display:none!important}.flex{display:flex}.flex-grow{flex-grow:1}.flex-v-center{align-items:center}.flex-h-center{justify-content:center}.flex-h-end{justify-content:flex-end}.fr{float:right}.relative{position:relative}.tac{text-align:center}.tar{text-align:right}.va-m{vertical-align:middle}.full-width{width:100%}.opacity--30{opacity:.3}.opacity--70{opacity:.7}.pointer-none{pointer-events:none}.ml-1{margin-left:1rem}.ml-2{margin-left:2rem}.mb-1{margin-bottom:1rem}.mb-2{margin-bottom:2rem}.mb-0{margin-bottom:0}.mt-0{margin-top:0}@media screen and (max-width:500px){.block--mobile{display:block}.ml-0--mobile{margin-left:0}.hide-on-mobile{display:none!important}}hr{background:0;border:0;border-bottom:1px solid #dedede}label{cursor:pointer}[class*=hint--]:after{text-transform:none;font-weight:400;letter-spacing:.5px;font-size:14px}.line{display:block;margin-bottom:1em}.caret{display:inline-block;width:0;height:0;border:6px solid transparent;border-top-color:currentColor;position:relative;top:5px;margin-left:8px}a>svg{fill:rgba(255,255,255,.2)}input[type=number],input[type=text],select,textarea{padding:3px 5px;font-size:inherit}.hidden-select{opacity:0;position:absolute;left:0;right:0;top:0;bottom:0}.btn{display:inline-block;color:var(--color-button);font-size:inherit;border:3px solid var(--color-button);border-radius:5px;padding:9px 15px;cursor:pointer;letter-spacing:.2px;line-height:1;transition:box-shadow .2s ease}.btn--primary{background:var(--color-button) linear-gradient(180deg,rgba(0,0,0,.5) 0,transparent);color:#fff}.btn--big{padding:15px 30px;border-radius:3px}.btn-icon{display:inline-flex;align-items:center}.btn:hover{text-decoration:none;box-shadow:0 5px 5px 0 rgba(0,0,0,.25)}.btn:focus{outline-width:4px;outline-color:#b76b29;outline-style:solid;outline-offset:1px}.btn-icon>svg{width:20px;height:20px;fill:currentColor;vertical-align:middle;margin-right:8px}.btn--big>svg{width:25px;height:25px;margin-right:12px}.btn-loader{display:none}.is-loading>svg{display:none}.is-loading .btn-loader{display:block}.star:after{content:'★';color:currentColor}.show-when-selected{display:none}.selected .show-when-selected{display:inline-block}.main-container{position:absolute;left:0;right:0;top:0;bottom:0;display:flex;flex-direction:column;overflow:hidden;transition:.1s ease .2s;will-change:filter}body:not(.light-version).overlay-visible .main-container{transition-duration:.5s;transition-delay:.4s;filter:blur(3px)}.content-wrap{height:1px;max-height:calc(100% - 70px)}.code-side,.demo-side{flex-basis:inherit;position:relative;width:50%}.layout-3 .content-wrap{flex-direction:row-reverse}.code-side{display:flex;flex-direction:column}.layout-2 .content-wrap{flex-direction:column}.layout-2 .code-side{flex-direction:row;width:auto}.layout-2 .demo-side{width:auto}.layout-5 .code-side{flex-direction:row;width:auto}.layout-5 .code-wrap{height:auto}.layout-4 .code-side{display:none}.layout-4 .code-side+.gutter{display:none}.layout-4 .demo-side{width:100%!important}.is-detached-mode .demo-side{display:none}.is-detached-mode .code-side{width:100%!important}.is-detached-mode.layout-2 .code-side{height:auto!important}.code-wrap{display:flex;flex-direction:column;flex-basis:inherit;height:33%;overflow:hidden;position:relative;background:var(--color-bg);transition:height .3s ease,width .3s ease;will-change:height}.layout-2 .code-wrap.is-minimized,.layout-5 .code-wrap.is-minimized{flex-direction:row}.is-dragging .code-wrap{transition:none}.layout-2 .code-wrap{height:auto;width:33%}.code-wrap__header{display:flex;flex-shrink:0;justify-content:space-between;align-items:center;padding:5px 10px;background:rgba(0,0,0,.2);color:#888;border-bottom:1px solid rgba(0,0,0,.3);font-weight:700;user-select:none}.code-wrap__header-label{display:inline-block;font-size:1.1em}.layout-2 .code-side .is-minimized .code-wrap__header,.layout-5 .code-side .is-minimized .code-wrap__header{writing-mode:vertical-lr;padding:10px 5px}.code-wrap__header .caret{transition:.2s ease}.is-minimized .code-wrap__header .caret{opacity:0}.code-wrap__header-btn{display:inline-block;vertical-align:top;margin-left:8px}.code-wrap__header-btn,.code-wrap__header-btn>svg{width:18px;height:18px}.code-wrap__header-right-options{position:relative;z-index:1}.code-wrap__collapse-btn:before{content:url('data:image/svg+xml;utf8,')}.is-maximized .code-wrap__collapse-btn:before{content:url('data:image/svg+xml;utf8,')}@keyframes pop-in{from{transform:scale(.9);opacity:0}to{transform:scale(1);opacity:1}}.CodeMirror{width:100%;height:calc(100% - 25px);font-size:var(--code-font-size)}.layout-2 .is-minimized .Codemirror,.layout-5 .is-minimized .Codemirror{height:calc(100%)}.CodeMirror pre{font-variant-ligatures:contextual}.cm-s-monokai .CodeMirror-linenumber{color:rgba(255,255,255,.2)}.cm-s-monokai .CodeMirror-gutters,.cm-s-monokai.CodeMirror{background:var(--color-bg)}.cm-s-monokai .CodeMirror-guttermarker-subtle{opacity:.4}.cm-s-monokai .CodeMirror-activeline-background,.cm-s-monokai .CodeMirror-activeline-gutter{background:rgba(0,0,0,.1)!important}.CodeMirror-hints{font-size:var(--code-font-size);border:0;background:#1e1e2c}.CodeMirror-hint{color:#bbb;padding:2px 4px}li.CodeMirror-hint-active{background:#5b429d}#demo-frame{border:0;width:100%;height:calc(100% - 29px);position:absolute;z-index:1;background:#fff}body>#demo-frame{height:100%}.footer,.main-header{padding:5px 10px;background-color:#12131b;color:rgba(255,255,255,.45);border-top:1px solid rgba(255,255,255,.14)}.footer{z-index:6}.main-header{display:flex;flex-wrap:nowrap;border:0;border-bottom:1px solid rgba(255,255,255,.14)}.main-header__btn-wrap>a{font-size:.8em;font-weight:700;line-height:20px;height:20px;letter-spacing:.6px;color:#9297b3;border-radius:3px;margin-left:10px;padding:0 8px;border:1px solid rgba(0,0,0,.9);background:linear-gradient(180deg,rgba(0,0,0,.5) 0,rgba(255,255,255,.1) 100%);box-shadow:0 -1px 0 0 rgba(255,255,255,.15);text-transform:uppercase}.main-header__btn-wrap>a>svg{fill:#9297b3;margin-right:4px}.main-header__btn-wrap>a.is-marked>svg{fill:#dc143c}.main-header__btn-wrap>a:hover{border-color:rgba(146,151,179,.5)}.main-header__btn-wrap>a.is-loading{pointer-events:none;opacity:.4}.main-header__avatar-img,.profile-modal__avatar-img{border-radius:50%}.logo{display:inline-block;height:25px;width:48px;margin-right:5px;background:url(icon-48.png) 0 -12px;background-repeat:no-repeat;vertical-align:middle;-webkit-filter:grayscale(.9);filter:grayscale(.9);transition:.4s ease;opacity:.3;will-change:opacity,filter}.footer:hover .logo{-webkit-filter:grayscale(0);filter:grayscale(0);opacity:1}.footer__right{font-size:0;line-height:0}.footer__separator{display:inline-block;height:24px;margin:0 10px 0 20px;border-left:1px solid rgba(255,255,255,.2)}.mode-btn{margin-left:10px;display:inline-block}.footer__link:first-of-type{margin-left:5px}.footer__link{display:inline-block;margin-right:5px;position:relative;top:2px}.footer a>svg{transition:.3s ease;fill:rgba(255,255,255,.2)}.footer a:hover svg{fill:rgba(255,255,255,.45)}.mode-btn svg{width:24px;height:24px}.mode-btn.selected svg{fill:rgba(255,255,255,.45)}.gutter{background:rgba(255,255,255,.05);flex-shrink:0}.gutter-horizontal{cursor:ew-resize}.gutter-vertical{cursor:ns-resize}.item-title-input{background:0 0;border:0;color:rgba(255,255,255,.6);flex:1}.search-input{background:rgba(255,255,255,.1);padding:10px 20px;border:0;width:100%;font-size:16px;color:#fff;border-radius:4px}.modal{position:fixed;top:0;left:0;width:100vw;height:100vh;overflow-y:auto;align-items:center;display:flex;align-items:baseline;justify-content:center;z-index:2000;visibility:hidden;will-change:transform}@keyframes anim-modal-overlay{to{opacity:1;transform:translateY(0) scale(1)}}.modal__close-btn{position:absolute;right:10px;top:10px;text-transform:uppercase;font-weight:700;opacity:.8;transition:.25s ease}.modal__close-btn>svg{fill:#000;width:30px;height:30px}.modal__close-btn:hover{opacity:.7}.modal__content{background:#fdfdfd;color:#444;position:relative;border-radius:8px;opacity:0;padding:3em;font-size:1.1em;line-height:1.4;max-width:85vw;margin:2rem auto;box-sizing:border-box;overflow-y:auto;pointer-events:auto;transform:translateY(50px) scale(.95);animation:anim-modal .3s ease forwards;animation-delay:150ms}@keyframes anim-modal{to{opacity:1;transform:translateY(0) scale(1)}}@media screen and (max-width:900px){.modal__content{max-width:95vw}}.is-modal-visible{visibility:visible}.modal-overlay{position:fixed;width:100%;height:100%;visibility:hidden;top:0;left:0;z-index:5;opacity:0;will-change:opacity;background:rgba(0,0,0,.6);transition:opacity .3s}.ask-to-import-modal .modal__content,.pledge-modal .modal__content{max-width:800px}.login-modal .modal__content{overflow-y:initial}.saved-items-pane{position:fixed;right:0;top:0;bottom:0;width:450px;padding:20px 30px;z-index:6;background-color:var(--color-sidebar);transition:.3s cubic-bezier(1,.13,.21,.87);transition-property:transform;will-change:transform;transform:translateX(100%)}.saved-items-pane.is-open{transition-duration:.4s;transform:translateX(0)}.is-modal-visible~.modal-overlay,.overlay-visible .modal-overlay,.saved-items-pane.is-open~.modal-overlay{opacity:1;visibility:visible}.saved-items-pane__close-btn{position:absolute;left:-18px;top:24px;opacity:0;visibility:hidden;border-radius:50%;padding:10px 14px;background:#dc143c;color:#fff;border:0;transform:scale(0);will-change:transform,opacity;transition:.3s ease;transition-delay:0}.saved-items-pane.is-open .saved-items-pane__close-btn{opacity:1;transition-delay:.4s;transform:scale(1);visibility:visible}.saved-item-tile{padding:20px;background-color:rgba(255,255,255,.06);position:relative;margin:20px 0;display:block;border-radius:4px;cursor:pointer;opacity:0;transform:translateX(50px);will-change:opacity,transform;box-shadow:0 2px 4px 0 rgba(0,0,0,.2);animation:slide-left .35s ease forwards}.saved-item-tile:nth-child(1){animation-delay:.2s}.saved-item-tile:nth-child(2){animation-delay:.25s}.saved-item-tile:nth-child(3){animation-delay:.3s}.saved-item-tile:nth-child(4){animation-delay:.35s}.saved-item-tile:nth-child(5){animation-delay:.4s}.saved-item-tile:nth-child(6){animation-delay:.45s}.saved-item-tile:nth-child(7){animation-delay:.5s}.saved-item-tile:nth-child(8){animation-delay:.55s}.saved-item-tile:nth-child(9){animation-delay:.6s}.saved-item-tile:nth-child(10){animation-delay:.65s}.saved-item-tile:nth-child(11){animation-delay:.7s}.saved-item-tile:nth-child(12){animation-delay:.75s}.saved-item-tile:nth-child(n+12){animation-delay:.8s}@keyframes slide-left{from{opacity:0;transform:translateX(50px)}to{opacity:1;transform:translateX(0)}}.saved-item-tile.selected,.saved-item-tile:hover{background:rgba(255,255,255,.1)}.saved-item-tile__btns{position:absolute;top:6px;z-index:1;right:8px;opacity:0;pointer-events:none;transition:.25s ease}.saved-item-tile.selected .saved-item-tile__btns,.saved-item-tile:hover .saved-item-tile__btns{opacity:1;pointer-events:auto}.saved-item-tile__btn{padding:7px 10px;color:rgba(255,255,255,.3);border-radius:20px;margin-left:2px;background:rgba(255,255,255,.05);text-transform:uppercase}.saved-item-tile__btn:hover{background:rgba(255,255,255,.8);color:#555}.saved-item-tile__title{pointer-events:none;font-size:1.4em;margin:0 0 1em 0;opacity:.8}.saved-item-tile__meta{pointer-events:none;opacity:.3}.saved-items-pane__container{overflow-y:scroll;max-height:calc(100vh - 90px)}.notifications-btn{position:relative}@keyframes shake{2%,22%{transform:translate3d(-1px,0,0)}20%,5%{transform:translate3d(2px,0,0)}12%,17%,7%{transform:translate3d(-4px,0,0)}10%,15%{transform:translate3d(4px,0,0)}}.notifications-btn.has-new{animation:shake 7s linear infinite;transform-origin:50% 10px}.notifications-btn__dot{position:absolute;right:1;top:-2px;background:#31fe45;border-radius:50%;width:12px;height:12px;display:none}.has-new .notifications-btn__dot{display:block}.notification{border:1px solid #f1f1f1;border-radius:5px;padding:20px;background:#f8f6f9;position:relative}.notification:not(:last-child){margin-bottom:10px}.notification li:not(:last-child){margin-bottom:10px}.notification__version{background:#ff8c00;color:#fff;padding:3px;border-radius:5px;position:absolute;top:2px;left:2px}.loader,.loader:after{border-radius:50%;width:3em;height:3em}.loader{font-size:5px;position:relative;text-indent:-9999em;border-top:1.1em solid rgba(118,57,229,.2);border-right:1.1em solid rgba(118,57,229,.2);border-bottom:1.1em solid rgba(118,57,229,.2);border-left:1.1em solid #7639e5;transform:translateZ(0);animation:load8 1.1s infinite linear}@keyframes load8{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.btn-group{position:relative;cursor:pointer}.dropdown__menu{position:absolute;top:100%;left:0;padding:0;margin:0;min-width:200px;display:block;font-size:.88rem;list-style:none;border-radius:4px;overflow:hidden;opacity:0;visibility:hidden;transition:transform .25s ease;transform:translateY(10px);z-index:5;background:#fff}.dropdown__menu>li>a{display:block;padding:6px 15px;color:#333;cursor:pointer}.dropdown__menu>li.selected>a,.dropdown__menu>li>a:hover{background:var(--color-sidebar);color:#fff}.dropdown__menu>li:not(:last-child){border-bottom:1px solid rgba(0,0,0,.05)}.dropdown__menu.is-open,.open>.dropdown__menu{opacity:1;visibility:visible;transform:translateY(0)}.alerts-container{position:fixed;will-change:transform;left:50%;top:-5px;padding:10px;background:#fff;border:1px solid #eee;color:#333;box-shadow:0 3px 5px rgba(0,0,0,.2);font-size:1rem;border-radius:3px;z-index:6;transform:translateX(-50%) translateY(-100%);transition:.3s ease}.alerts-container.is-active{transform:translateX(-50%) translateY(0)}.error-gutter{width:8px}.gutter-error-marker{width:8px;height:20px;background:red;border-radius:0;position:relative;top:0;left:1px}.gutter-error-marker:after{content:attr(data-title);background:red;color:#fff;padding:4px;opacity:0;visibility:hidden;position:absolute;top:14px;left:0;width:300px;transform:translateX(-10px);will-change:transform;transition:.2s ease}.gutter-error-marker:hover:after{opacity:1;visibility:visible;transform:translateX(0)}.count-label{color:rgba(0,0,0,.8);background:rgba(255,255,255,.53);border-radius:5px;padding:1px 6px;font-weight:700}.onboard-step{background:#f7f2f1;border:1px solid #ecdede;margin:15px;padding:20px 30px;background-color:#fff;border-radius:10px;box-shadow:0 16px 22px rgba(0,0,0,.1);flex:1;opacity:0;animation:onboard-step-show .6s ease forwards;animation-delay:.1s}.onboard-step:nth-child(2){animation-delay:.2s}.onboard-step:nth-child(3){animation-delay:.4s}.onboard-step__icon{fill:#fff2ed;stroke-width:.5px;stroke:#e79f80;width:80px;height:80px}@keyframes onboard-step-show{from{transform:translateY(10px);opacity:0}to{transform:translateY(0);opacity:1}}.autocomplete-dropdown{border-top-left-radius:0;border-top-right-radius:0;right:0;max-height:200px;overflow-y:auto;border:1px solid rgba(0,0,0,.5);z-index:2001}.autocomplete__loader{position:absolute;right:3px;bottom:1px}@keyframes wobble{from{transform:none}15%{transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}to{transform:none}}.animated{animation-duration:1s;animation-fill-mode:both}.wobble{animation-name:wobble}.console{background:var(--color-bg);z-index:6;position:absolute;bottom:0;min-height:80px;height:35vh;left:0;right:0;display:flex;flex-direction:column;transform:translateY(0);transition:transform .4s cubic-bezier(.76,.01,.13,.9)}.console.is-minimized{transform:translateY(calc(100% - 29px))}.console .CodeMirror{height:calc(100% - 30px)}.console__log{flex:1}.console-exec-input{padding:5px;font-size:1.3em;flex:1;background:rgba(0,0,0,.3);color:#fff;border:0;outline:0}.console:not(.is-minimized) .code-wrap__header{cursor:ns-resize}.global-console-container{display:none;position:relative;height:35px}.is-detached-mode .console,.is-detached-mode .footer{z-index:4}.is-detached-mode .global-console-container{display:block}.kbd-shortcut__keys{background:rgba(0,0,0,.1);border-radius:3px;padding:3px 8px;margin-right:5px;display:inline-block;font-size:.9rem;font-weight:700}.kbd-shortcut__details{display:inline-block}.web-maker-with-tag{position:relative;display:inline-block}.is-extension .web-maker-with-tag:after{display:none}.social-login-btn--github{color:#fff;background:#656b6f;border-color:#656b6f}.social-login-btn--facebook{color:#fff;background:#4e62c0;border-color:#4e62c0}.social-login-btn--google{background:#fff;border:2px solid currentColor;color:inherit}body.is-logged-in .hide-on-login,body:not(.is-app) .show-when-app,body:not(.is-extension) .show-when-extension,body:not(.is-logged-in) .hide-on-logout{display:none}.onboard-selection{padding:10px;margin:0 40px;border-radius:5px;transition:.25s ease;position:relative;border:1px solid transparent}.onboard-selection:hover{cursor:pointer;transform:scale(1.15)}.onboard-selection.selected:after{content:'';position:absolute;right:-20px;bottom:40px;width:80px;height:80px;border-radius:50%;background:#fff url('data:image/svg+xml;charset=UTF-8,')}.bookmarklet{display:inline-flex;align-items:center;border:1px #aaa solid;padding:0 5px;border-style:dashed;color:#333}.help-text{font-size:.9em;color:#616465}.social-login-btn:after,.social-login-btn:before,.social-login-btn:hover:after,.social-login-btn:hover:before{visibility:hidden}.last-login-github .social-login-btn--github:after,.last-login-github .social-login-btn--github:before{visibility:visible}.last-login-facebook .social-login-btn--facebook:after,.last-login-facebook .social-login-btn--facebook:before{visibility:visible}.last-login-google .social-login-btn--google:after,.last-login-google .social-login-btn--google:before{visibility:visible}@media screen and (max-width:500px){body{font-size:70%}.main-header{overflow-x:auto}.main-header__btn-wrap{flex-shrink:0}.modal__content{padding:1em}.saved-items-pane{width:77vw;padding:10px 20px}}.cm-s-paraiso-dark.CodeMirror{background:#2f1e2e;color:#b9b6b0}.cm-s-paraiso-dark .CodeMirror-gutters{background:#2f1e2e;border-right:0}.cm-s-paraiso-dark .CodeMirror-activeline-background{background:#4d344a}.cm-s-monokai.CodeMirror{background:#272822;color:#f8f8f2}.cm-s-monokai .CodeMirror-gutters{background:#272822;border-right:0}.cm-s-monokai .CodeMirror-activeline-background{background:#373831}.cm-s-3024-day.CodeMirror{background:#f7f7f7;color:#3a3432}.cm-s-3024-day .CodeMirror-gutters{background:#f7f7f7;border-right:0}.cm-s-3024-day .CodeMirror-activeline-background{background:#e8f2ff}.cm-s-material.CodeMirror{background-color:#263238;color:rgba(233,237,237,1)}.cm-s-material .CodeMirror-gutters{background:#263238;color:#537f7e}.cm-s-material .CodeMirror-activeline-background{background:rgba(0,0,0,0)}.cm-s-dracula .CodeMirror-gutters,.cm-s-dracula.CodeMirror{background-color:#282a36!important;color:#f8f8f2!important}.cm-s-dracula .CodeMirror-activeline-background{background:rgba(255,255,255,.1)}.cm-s-blackboard.CodeMirror{background:#0c1021;color:#f8f8f8}.cm-s-blackboard .CodeMirror-gutters{background:#0c1021;border-right:0}.cm-s-blackboard .CodeMirror-activeline-background{background:#3c3636}.cm-s-midnight.CodeMirror{background:#0f192a;color:#d1edff}.cm-s-midnight .CodeMirror-gutters{background:#0f192a;border-right:1px solid}.cm-s-midnight .CodeMirror-activeline-background{background:#253540} \ No newline at end of file +:root{--color-bg:#252637;--color-sidebar:#3a2b63;--code-font-size:16px;--color-button:#0074d9}body{margin:0;padding:0;background:rgba(0,0,0,.5);background:var(--color-bg);color:rgba(255,255,255,.9);min-height:100vh;font-size:87.5%;position:relative;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Segoe UI Emoji','Segoe UI Symbol'}h1{margin-top:0}a{text-decoration:none;color:#d61237;cursor:pointer}p{line-height:1.65}.hide{display:none!important}.flex{display:flex}.flex-grow{flex-grow:1}.flex-v-center{align-items:center}.flex-h-center{justify-content:center}.flex-h-end{justify-content:flex-end}.fr{float:right}.relative{position:relative}.tac{text-align:center}.tar{text-align:right}.va-m{vertical-align:middle}.full-width{width:100%}.opacity--30{opacity:.3}.opacity--70{opacity:.7}.pointer-none{pointer-events:none}.ml-1{margin-left:1rem}.ml-2{margin-left:2rem}.mb-1{margin-bottom:1rem}.mb-2{margin-bottom:2rem}.mt-1{margin-top:1rem}.mt-2{margin-top:2rem}.mb-0{margin-bottom:0}.mt-0{margin-top:0}@media screen and (max-width:500px){.block--mobile{display:block}.ml-0--mobile{margin-left:0}.hide-on-mobile{display:none!important}}hr{background:0;border:0;border-bottom:1px solid #dedede}label{cursor:pointer}[class*=hint--]:after{text-transform:none;font-weight:400;letter-spacing:.5px;font-size:14px}.line{display:block;margin-bottom:1em}.caret{display:inline-block;width:0;height:0;border:6px solid transparent;border-top-color:currentColor;position:relative;top:5px;margin-left:8px}a>svg{fill:rgba(255,255,255,.2)}input[type=number],input[type=text],select,textarea{padding:3px 5px;font-size:inherit}.hidden-select{opacity:0;position:absolute;left:0;right:0;top:0;bottom:0}.btn{display:inline-block;color:var(--color-button);font-size:inherit;border:3px solid var(--color-button);border-radius:5px;padding:9px 15px;cursor:pointer;letter-spacing:.2px;line-height:1;transition:box-shadow .2s ease}.btn--primary{background:var(--color-button) linear-gradient(180deg,rgba(0,0,0,.5) 0,transparent);color:#fff}.btn--big{padding:15px 30px;border-radius:3px}.btn-icon{display:inline-flex;align-items:center}.btn:hover{text-decoration:none;box-shadow:0 5px 5px 0 rgba(0,0,0,.25)}.btn:focus{outline-width:4px;outline-color:#b76b29;outline-style:solid;outline-offset:1px}.btn-icon>svg{width:20px;height:20px;fill:currentColor;vertical-align:middle;margin-right:8px}.btn--big>svg{width:25px;height:25px;margin-right:12px}.btn-loader{display:none}.is-loading>svg{display:none}.is-loading .btn-loader{display:block}.star:after{content:'★';color:currentColor}.show-when-selected{display:none}.selected .show-when-selected{display:inline-block}.main-container{position:absolute;left:0;right:0;top:0;bottom:0;display:flex;flex-direction:column;overflow:hidden;transition:.1s ease .2s;will-change:filter}body:not(.light-version).overlay-visible .main-container{transition-duration:.5s;transition-delay:.4s;filter:blur(3px)}.content-wrap{height:1px;max-height:calc(100% - 70px)}.code-side,.demo-side{flex-basis:inherit;position:relative;width:50%}.layout-3 .content-wrap{flex-direction:row-reverse}.code-side{display:flex;flex-direction:column}.layout-2 .content-wrap{flex-direction:column}.layout-2 .code-side{flex-direction:row;width:auto}.layout-2 .demo-side{width:auto}.layout-5 .code-side{flex-direction:row;width:auto}.layout-5 .code-wrap{height:auto}.layout-4 .code-side{display:none}.layout-4 .code-side+.gutter{display:none}.layout-4 .demo-side{width:100%!important}.is-detached-mode .demo-side{display:none}.is-detached-mode .code-side{width:100%!important}.is-detached-mode.layout-2 .code-side{height:auto!important}.code-wrap{display:flex;flex-direction:column;flex-basis:inherit;height:33%;overflow:hidden;position:relative;background:var(--color-bg);transition:height .3s ease,width .3s ease;will-change:height}.layout-2 .code-wrap.is-minimized,.layout-5 .code-wrap.is-minimized{flex-direction:row}.is-dragging .code-wrap{transition:none}.layout-2 .code-wrap{height:auto;width:33%}.code-wrap__header{display:flex;flex-shrink:0;justify-content:space-between;align-items:center;padding:5px 10px;background:rgba(0,0,0,.2);color:#888;border-bottom:1px solid rgba(0,0,0,.3);font-weight:700;user-select:none}.code-wrap__header-label{display:inline-block;font-size:1.1em}.layout-2 .code-side .is-minimized .code-wrap__header,.layout-5 .code-side .is-minimized .code-wrap__header{writing-mode:vertical-lr;padding:10px 5px}.code-wrap__header .caret{transition:.2s ease}.is-minimized .code-wrap__header .caret{opacity:0}.code-wrap__header-btn{display:inline-block;vertical-align:top;margin-left:8px}.code-wrap__header-btn,.code-wrap__header-btn>svg{width:18px;height:18px}.code-wrap__header-right-options{position:relative;z-index:1}.code-wrap__collapse-btn:before{content:url('data:image/svg+xml;utf8,')}.is-maximized .code-wrap__collapse-btn:before{content:url('data:image/svg+xml;utf8,')}@keyframes pop-in{from{transform:scale(.9);opacity:0}to{transform:scale(1);opacity:1}}.CodeMirror{width:100%;height:calc(100% - 25px);font-size:var(--code-font-size)}.layout-2 .is-minimized .Codemirror,.layout-5 .is-minimized .Codemirror{height:calc(100%)}.CodeMirror pre{font-variant-ligatures:contextual}.cm-s-monokai .CodeMirror-linenumber{color:rgba(255,255,255,.2)}.cm-s-monokai .CodeMirror-gutters,.cm-s-monokai.CodeMirror{background:var(--color-bg)}.cm-s-monokai .CodeMirror-guttermarker-subtle{opacity:.4}.cm-s-monokai .CodeMirror-activeline-background,.cm-s-monokai .CodeMirror-activeline-gutter{background:rgba(0,0,0,.1)!important}.CodeMirror-hints{font-size:var(--code-font-size);border:0;background:#1e1e2c}.CodeMirror-hint{color:#bbb;padding:2px 4px}li.CodeMirror-hint-active{background:#5b429d}#demo-frame{border:0;width:100%;height:calc(100% - 29px);position:absolute;z-index:1;background:#fff}body>#demo-frame{height:100%}.footer,.main-header{padding:5px 10px;background-color:#12131b;color:rgba(255,255,255,.45);border-top:1px solid rgba(255,255,255,.14)}.footer{z-index:6}.main-header{display:flex;flex-wrap:nowrap;border:0;border-bottom:1px solid rgba(255,255,255,.14)}.main-header__btn-wrap>a{font-size:.8em;font-weight:700;line-height:20px;height:20px;letter-spacing:.6px;color:#9297b3;border-radius:3px;margin-left:10px;padding:0 8px;border:1px solid rgba(0,0,0,.9);background:linear-gradient(180deg,rgba(0,0,0,.5) 0,rgba(255,255,255,.1) 100%);box-shadow:0 -1px 0 0 rgba(255,255,255,.15);text-transform:uppercase}.main-header__btn-wrap>a>svg{fill:#9297b3;margin-right:4px}.main-header__btn-wrap>a.is-marked>svg{fill:#dc143c}.main-header__btn-wrap>a:hover{border-color:rgba(146,151,179,.5)}.main-header__btn-wrap>a.is-loading{pointer-events:none;opacity:.4}.main-header__avatar-img,.profile-modal__avatar-img{border-radius:50%}.logo{display:inline-block;height:25px;width:48px;margin-right:5px;background:url(icon-48.png) 0 -12px;background-repeat:no-repeat;vertical-align:middle;-webkit-filter:grayscale(.9);filter:grayscale(.9);transition:.4s ease;opacity:.3;will-change:opacity,filter}.footer:hover .logo{-webkit-filter:grayscale(0);filter:grayscale(0);opacity:1}.footer__right{font-size:0;line-height:0}.footer__separator{display:inline-block;height:24px;margin:0 10px 0 20px;border-left:1px solid rgba(255,255,255,.2)}.mode-btn{margin-left:10px;display:inline-block}.footer__link:first-of-type{margin-left:5px}.footer__link{display:inline-block;margin-right:5px;position:relative;top:2px}.footer a>svg{transition:.3s ease;fill:rgba(255,255,255,.2)}.footer a:hover svg{fill:rgba(255,255,255,.45)}.mode-btn svg{width:24px;height:24px}.mode-btn.selected svg{fill:rgba(255,255,255,.45)}.gutter{background:rgba(255,255,255,.05);flex-shrink:0}.gutter-horizontal{cursor:ew-resize}.gutter-vertical{cursor:ns-resize}.item-title-input{background:0 0;border:0;color:rgba(255,255,255,.6);flex:1}.search-input{background:rgba(255,255,255,.1);padding:10px 20px;border:0;width:100%;font-size:16px;color:#fff;border-radius:4px}.modal{position:fixed;top:0;left:0;width:100vw;height:100vh;overflow-y:auto;align-items:center;display:flex;align-items:baseline;justify-content:center;z-index:2000;visibility:hidden;will-change:transform}@keyframes anim-modal-overlay{to{opacity:1;transform:translateY(0) scale(1)}}.modal__close-btn{position:absolute;right:10px;top:10px;text-transform:uppercase;font-weight:700;opacity:.8;transition:.25s ease}.modal__close-btn>svg{fill:#000;width:30px;height:30px}.modal__close-btn:hover{opacity:.7}.modal__content{background:#fdfdfd;color:#444;position:relative;border-radius:8px;opacity:0;padding:3em;font-size:1.1em;line-height:1.4;max-width:85vw;margin:2rem auto;box-sizing:border-box;overflow-y:auto;pointer-events:auto;transform:translateY(50px) scale(.95);animation:anim-modal .3s ease forwards;animation-delay:150ms}@keyframes anim-modal{to{opacity:1;transform:translateY(0) scale(1)}}@media screen and (max-width:900px){.modal__content{max-width:95vw}}.is-modal-visible{visibility:visible}.modal-overlay{position:fixed;width:100%;height:100%;visibility:hidden;top:0;left:0;z-index:5;opacity:0;will-change:opacity;background:rgba(0,0,0,.6);transition:opacity .3s}.ask-to-import-modal .modal__content,.pledge-modal .modal__content{max-width:800px}.login-modal .modal__content{overflow-y:initial}.saved-items-pane{position:fixed;right:0;top:0;bottom:0;width:450px;padding:20px 30px;z-index:6;background-color:var(--color-sidebar);transition:.3s cubic-bezier(1,.13,.21,.87);transition-property:transform;will-change:transform;transform:translateX(100%)}.saved-items-pane.is-open{transition-duration:.4s;transform:translateX(0)}.is-modal-visible~.modal-overlay,.overlay-visible .modal-overlay,.saved-items-pane.is-open~.modal-overlay{opacity:1;visibility:visible}.saved-items-pane__close-btn{position:absolute;left:-18px;top:24px;opacity:0;visibility:hidden;border-radius:50%;padding:10px 14px;background:#dc143c;color:#fff;border:0;transform:scale(0);will-change:transform,opacity;transition:.3s ease;transition-delay:0}.saved-items-pane.is-open .saved-items-pane__close-btn{opacity:1;transition-delay:.4s;transform:scale(1);visibility:visible}.saved-item-tile{padding:20px;background-color:rgba(255,255,255,.06);position:relative;margin:20px 0;display:block;border-radius:4px;cursor:pointer;opacity:0;transform:translateX(50px);will-change:opacity,transform;box-shadow:0 2px 4px 0 rgba(0,0,0,.2);animation:slide-left .35s ease forwards}.saved-item-tile:nth-child(1){animation-delay:.2s}.saved-item-tile:nth-child(2){animation-delay:.25s}.saved-item-tile:nth-child(3){animation-delay:.3s}.saved-item-tile:nth-child(4){animation-delay:.35s}.saved-item-tile:nth-child(5){animation-delay:.4s}.saved-item-tile:nth-child(6){animation-delay:.45s}.saved-item-tile:nth-child(7){animation-delay:.5s}.saved-item-tile:nth-child(8){animation-delay:.55s}.saved-item-tile:nth-child(9){animation-delay:.6s}.saved-item-tile:nth-child(10){animation-delay:.65s}.saved-item-tile:nth-child(11){animation-delay:.7s}.saved-item-tile:nth-child(12){animation-delay:.75s}.saved-item-tile:nth-child(n+12){animation-delay:.8s}@keyframes slide-left{from{opacity:0;transform:translateX(50px)}to{opacity:1;transform:translateX(0)}}.saved-item-tile.selected,.saved-item-tile:hover{background:rgba(255,255,255,.1)}.saved-item-tile__btns{position:absolute;top:6px;z-index:1;right:8px;opacity:0;pointer-events:none;transition:.25s ease}.saved-item-tile.selected .saved-item-tile__btns,.saved-item-tile:hover .saved-item-tile__btns{opacity:1;pointer-events:auto}.saved-item-tile__btn{padding:7px 10px;color:rgba(255,255,255,.3);border-radius:20px;margin-left:2px;background:rgba(255,255,255,.05);text-transform:uppercase}.saved-item-tile__btn:hover{background:rgba(255,255,255,.8);color:#555}.saved-item-tile__title{pointer-events:none;font-size:1.4em;margin:0 0 1em 0;opacity:.8}.saved-item-tile__meta{pointer-events:none;opacity:.3}.saved-items-pane__container{overflow-y:scroll;max-height:calc(100vh - 90px)}.notifications-btn{position:relative}@keyframes shake{2%,22%{transform:translate3d(-1px,0,0)}20%,5%{transform:translate3d(2px,0,0)}12%,17%,7%{transform:translate3d(-4px,0,0)}10%,15%{transform:translate3d(4px,0,0)}}.notifications-btn.has-new{animation:shake 7s linear infinite;transform-origin:50% 10px}.notifications-btn__dot{position:absolute;right:1;top:-2px;background:#31fe45;border-radius:50%;width:12px;height:12px;display:none}.has-new .notifications-btn__dot{display:block}.notification{border:1px solid #f1f1f1;border-radius:5px;padding:20px;background:#f8f6f9;position:relative}.notification:not(:last-child){margin-bottom:10px}.notification li:not(:last-child){margin-bottom:10px}.notification__version{background:#ff8c00;color:#fff;padding:3px;border-radius:5px;position:absolute;top:2px;left:2px}.loader,.loader:after{border-radius:50%;width:3em;height:3em}.loader{font-size:5px;position:relative;text-indent:-9999em;border-top:1.1em solid rgba(118,57,229,.2);border-right:1.1em solid rgba(118,57,229,.2);border-bottom:1.1em solid rgba(118,57,229,.2);border-left:1.1em solid #7639e5;transform:translateZ(0);animation:load8 1.1s infinite linear}@keyframes load8{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.btn-group{position:relative;cursor:pointer}.dropdown__menu{position:absolute;top:100%;left:0;padding:0;margin:0;min-width:200px;display:block;font-size:.88rem;list-style:none;border-radius:4px;overflow:hidden;opacity:0;visibility:hidden;transition:transform .25s ease;transform:translateY(10px);z-index:5;background:#fff}.dropdown__menu>li>a{display:block;padding:6px 15px;color:#333;cursor:pointer}.dropdown__menu>li.selected>a,.dropdown__menu>li>a:hover{background:var(--color-sidebar);color:#fff}.dropdown__menu>li:not(:last-child){border-bottom:1px solid rgba(0,0,0,.05)}.dropdown__menu.is-open,.open>.dropdown__menu{opacity:1;visibility:visible;transform:translateY(0)}.alerts-container{position:fixed;will-change:transform;left:50%;top:-5px;padding:10px;background:#fff;border:1px solid #eee;color:#333;box-shadow:0 3px 5px rgba(0,0,0,.2);font-size:1rem;border-radius:3px;z-index:6;transform:translateX(-50%) translateY(-100%);transition:.3s ease}.alerts-container.is-active{transform:translateX(-50%) translateY(0)}.error-gutter{width:8px}.gutter-error-marker{width:8px;height:20px;background:red;border-radius:0;position:relative;top:0;left:1px}.gutter-error-marker:after{content:attr(data-title);background:red;color:#fff;padding:4px;opacity:0;visibility:hidden;position:absolute;top:14px;left:0;width:300px;transform:translateX(-10px);will-change:transform;transition:.2s ease}.gutter-error-marker:hover:after{opacity:1;visibility:visible;transform:translateX(0)}.count-label{color:rgba(0,0,0,.8);background:rgba(255,255,255,.53);border-radius:5px;padding:1px 6px;font-weight:700}.onboard-step{background:#f7f2f1;border:1px solid #ecdede;margin:15px;padding:20px 30px;background-color:#fff;border-radius:10px;box-shadow:0 16px 22px rgba(0,0,0,.1);flex:1;opacity:0;animation:onboard-step-show .6s ease forwards;animation-delay:.1s}.onboard-step:nth-child(2){animation-delay:.2s}.onboard-step:nth-child(3){animation-delay:.4s}.onboard-step__icon{fill:#fff2ed;stroke-width:.5px;stroke:#e79f80;width:80px;height:80px}@keyframes onboard-step-show{from{transform:translateY(10px);opacity:0}to{transform:translateY(0);opacity:1}}.autocomplete-dropdown{border-top-left-radius:0;border-top-right-radius:0;right:0;max-height:200px;overflow-y:auto;border:1px solid rgba(0,0,0,.5);z-index:2001}.autocomplete__loader{position:absolute;right:3px;bottom:1px}@keyframes wobble{from{transform:none}15%{transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}to{transform:none}}.animated{animation-duration:1s;animation-fill-mode:both}.wobble{animation-name:wobble}.console{background:var(--color-bg);z-index:6;position:absolute;bottom:0;min-height:80px;height:35vh;left:0;right:0;display:flex;flex-direction:column;transform:translateY(0);transition:transform .4s cubic-bezier(.76,.01,.13,.9)}.console.is-minimized{transform:translateY(calc(100% - 29px))}.console .CodeMirror{height:calc(100% - 30px)}.console__log{flex:1}.console-exec-input{padding:5px;font-size:1.3em;flex:1;background:rgba(0,0,0,.3);color:#fff;border:0;outline:0}.console:not(.is-minimized) .code-wrap__header{cursor:ns-resize}.global-console-container{display:none;position:relative;height:35px}.is-detached-mode .console,.is-detached-mode .footer{z-index:4}.is-detached-mode .global-console-container{display:block}.kbd-shortcut__keys{background:rgba(0,0,0,.1);border-radius:3px;padding:3px 8px;margin-right:5px;display:inline-block;font-size:.9rem;font-weight:700}.kbd-shortcut__details{display:inline-block}.web-maker-with-tag{position:relative;display:inline-block}.is-extension .web-maker-with-tag:after{display:none}.social-login-btn--github{color:#fff;background:#656b6f;border-color:#656b6f}.social-login-btn--facebook{color:#fff;background:#4e62c0;border-color:#4e62c0}.social-login-btn--google{background:#fff;border:2px solid currentColor;color:inherit}body.is-logged-in .hide-on-login,body:not(.is-app) .show-when-app,body:not(.is-extension) .show-when-extension,body:not(.is-logged-in) .hide-on-logout{display:none}.onboard-selection{padding:10px;margin:0 40px;border-radius:5px;transition:.25s ease;position:relative;border:1px solid transparent}.onboard-selection:hover{cursor:pointer;transform:scale(1.15)}.onboard-selection.selected:after{content:'';position:absolute;right:-20px;bottom:40px;width:80px;height:80px;border-radius:50%;background:#fff url('data:image/svg+xml;charset=UTF-8,')}.bookmarklet{display:inline-flex;align-items:center;border:1px #aaa solid;padding:0 5px;border-style:dashed;color:#333}.help-text{font-size:.9em;color:#616465}.social-login-btn:after,.social-login-btn:before,.social-login-btn:hover:after,.social-login-btn:hover:before{visibility:hidden}.last-login-github .social-login-btn--github:after,.last-login-github .social-login-btn--github:before{visibility:visible}.last-login-facebook .social-login-btn--facebook:after,.last-login-facebook .social-login-btn--facebook:before{visibility:visible}.last-login-google .social-login-btn--google:after,.last-login-google .social-login-btn--google:before{visibility:visible}@media screen and (max-width:500px){body{font-size:70%}.main-header{overflow-x:auto}.main-header__btn-wrap{flex-shrink:0}.modal__content{padding:1em}.saved-items-pane{width:77vw;padding:10px 20px}}.cm-s-paraiso-dark.CodeMirror{background:#2f1e2e;color:#b9b6b0}.cm-s-paraiso-dark .CodeMirror-gutters{background:#2f1e2e;border-right:0}.cm-s-paraiso-dark .CodeMirror-activeline-background{background:#4d344a}.cm-s-monokai.CodeMirror{background:#272822;color:#f8f8f2}.cm-s-monokai .CodeMirror-gutters{background:#272822;border-right:0}.cm-s-monokai .CodeMirror-activeline-background{background:#373831}.cm-s-3024-day.CodeMirror{background:#f7f7f7;color:#3a3432}.cm-s-3024-day .CodeMirror-gutters{background:#f7f7f7;border-right:0}.cm-s-3024-day .CodeMirror-activeline-background{background:#e8f2ff}.cm-s-material.CodeMirror{background-color:#263238;color:rgba(233,237,237,1)}.cm-s-material .CodeMirror-gutters{background:#263238;color:#537f7e}.cm-s-material .CodeMirror-activeline-background{background:rgba(0,0,0,0)}.cm-s-dracula .CodeMirror-gutters,.cm-s-dracula.CodeMirror{background-color:#282a36!important;color:#f8f8f2!important}.cm-s-dracula .CodeMirror-activeline-background{background:rgba(255,255,255,.1)}.cm-s-blackboard.CodeMirror{background:#0c1021;color:#f8f8f8}.cm-s-blackboard .CodeMirror-gutters{background:#0c1021;border-right:0}.cm-s-blackboard .CodeMirror-activeline-background{background:#3c3636}.cm-s-midnight.CodeMirror{background:#0f192a;color:#d1edff}.cm-s-midnight .CodeMirror-gutters{background:#0f192a;border-right:1px solid}.cm-s-midnight .CodeMirror-activeline-background{background:#253540} \ No newline at end of file diff --git a/app/vendor.js b/app/vendor.js index abd701b..e74a3f1 100644 --- a/app/vendor.js +++ b/app/vendor.js @@ -1,55834 +1 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ // install a JSONP callback for chunk loading -/******/ var parentJsonpFunction = window["webpackJsonp"]; -/******/ window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) { -/******/ // add "moreModules" to the modules object, -/******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0, resolves = [], result; -/******/ for(;i < chunkIds.length; i++) { -/******/ chunkId = chunkIds[i]; -/******/ if(installedChunks[chunkId]) { -/******/ resolves.push(installedChunks[chunkId][0]); -/******/ } -/******/ installedChunks[chunkId] = 0; -/******/ } -/******/ for(moduleId in moreModules) { -/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { -/******/ modules[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules); -/******/ while(resolves.length) { -/******/ resolves.shift()(); -/******/ } -/******/ if(executeModules) { -/******/ for(i=0; i < executeModules.length; i++) { -/******/ result = __webpack_require__(__webpack_require__.s = executeModules[i]); -/******/ } -/******/ } -/******/ return result; -/******/ }; -/******/ -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // objects to store loaded and loading chunks -/******/ var installedChunks = { -/******/ 2: 0 -/******/ }; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = "/"; -/******/ -/******/ // on error function for async loading -/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; }; -/******/ }) -/************************************************************************/ -/******/ ({ - -/***/ "/QFk": -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; - -// CONCATENATED MODULE: ../node_modules/@emmetio/config/dist/config.es.js -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -var defaultSyntaxes = { - markup: 'html', - stylesheet: 'css' -}; - -var knownSyntaxes = { - markup: ['html', 'xml', 'xsl', 'jsx', 'js', 'pug', 'slim', 'haml'], - stylesheet: ['css', 'sass', 'scss', 'less', 'sss', 'stylus'] -}; - -/** - * Config resolver: returns compiled config that can be used in - * `@emmetio/expand-abbreviation` module for expanding abbreviations - * @param {EmmetConfig} config Config object - * @param {EmmetConfigParams} [params] Additional params like `.syntax` and `.project` for - * config resolving - * @returns {Object} - */ -function compileConfig(config, params) { - params = createParams(config, params || {}); - - var resolved = resolveConfig(config, params); - - // Copy extra fields from original config - var knownFields = ['globals', 'syntax', 'project']; - for (var p in config) { - if (knownFields.indexOf(p) === -1) { - resolved[p] = config[p]; - } - } - - return resolved; -} - -/** - * Resolves config for markup syntax - * @param {EmmetConfig} config - * @param {EmmetConfigParams} params - * @return {Object} - */ -function resolveConfig(config, ref) { - var type = ref.type; - var syntax = ref.syntax; - var project = ref.project; - - return { - syntax: syntax, - type: type, - project: project, - format: mergeConfig(config, 'format', type, syntax, project), - profile: mergeConfig(config, 'profile', type, syntax, project), - options: mergeConfig(config, 'options', type, syntax, project), - variables: mergeConfig(config, 'variables', type, syntax, project), - snippets: getConfig(config, 'snippets', type, syntax, project).filter(Boolean) - }; -} - -/** - * @param {EmmetConfig} config - * @param {EmmetConfigParams} params - * @returns {EmmetConfigParams} - */ -function createParams(config, params) { - var type = params.type; - var syntax = params.syntax; - - if (!type && !syntax) { - type = 'markup'; - syntax = defaultSyntaxes[type]; - } else if (!type && syntax) { - if (knownSyntaxes.markup.indexOf(syntax) !== -1) { - type = 'markup'; - } else if (knownSyntaxes.stylesheet.indexOf(syntax) !== -1) { - type = 'stylesheet'; - } else { - type = get(config, ['syntax', syntax, 'type']) || get(config, ['project', params.project, 'syntax', syntax, 'type']); - } - } else if (!syntax) { - syntax = defaultSyntaxes[type]; - } - - return _extends({}, params, { type: type, syntax: syntax }); -} - -function mergeConfig(config, key, type, syntax, project) { - return getConfig(config, key, type, syntax, project).reduce(function (out, obj) { - return _extends({}, out, obj); - }, {}); -} - -function getConfig(config, key, type, syntax, project) { - return [get(config, ['globals', type, key]), get(config, ['project', project, 'globals', type, key]), get(config, ['syntax', syntax, key]), get(config, ['project', project, 'syntax', syntax, key])].filter(Boolean); -} - -/** - * Safe dot-property getter for `obj`: returns value of `obj` by given `key`, - * separated by `.`, but doesn’t throw error if any of the property key exists - * @param {Object} obj - * @param {String[]} key - * @param {*} [defaultValue] - * @return {*} - */ -function get(obj, key, defaultValue) { - var result = obj; - - for (var i = 0; i < key.length; i++) { - if (result == null) { - break; - } - - result = result[key[i]]; - } - - return result != null ? result : defaultValue; -} - -/* harmony default export */ var config_es = (compileConfig); -//# sourceMappingURL=config.es.js.map -// CONCATENATED MODULE: ../node_modules/@emmetio/stream-reader/dist/stream-reader.es.js -/** - * A streaming, character code-based string reader - */ -let StreamReader = class StreamReader { - constructor(string, start, end) { - if (end == null && typeof string === 'string') { - end = string.length; - } - - this.string = string; - this.pos = this.start = start || 0; - this.end = end; - } - - /** - * Returns true only if the stream is at the end of the file. - * @returns {Boolean} - */ - eof() { - return this.pos >= this.end; - } - - /** - * Creates a new stream instance which is limited to given `start` and `end` - * range. E.g. its `eof()` method will look at `end` property, not actual - * stream end - * @param {Point} start - * @param {Point} end - * @return {StreamReader} - */ - limit(start, end) { - return new this.constructor(this.string, start, end); - } - - /** - * Returns the next character code in the stream without advancing it. - * Will return NaN at the end of the file. - * @returns {Number} - */ - peek() { - return this.string.charCodeAt(this.pos); - } - - /** - * Returns the next character in the stream and advances it. - * Also returns undefined when no more characters are available. - * @returns {Number} - */ - next() { - if (this.pos < this.string.length) { - return this.string.charCodeAt(this.pos++); - } - } - - /** - * `match` can be a character code or a function that takes a character code - * and returns a boolean. If the next character in the stream 'matches' - * the given argument, it is consumed and returned. - * Otherwise, `false` is returned. - * @param {Number|Function} match - * @returns {Boolean} - */ - eat(match) { - const ch = this.peek(); - const ok = typeof match === 'function' ? match(ch) : ch === match; - - if (ok) { - this.next(); - } - - return ok; - } - - /** - * Repeatedly calls eat with the given argument, until it - * fails. Returns true if any characters were eaten. - * @param {Object} match - * @returns {Boolean} - */ - eatWhile(match) { - const start = this.pos; - while (!this.eof() && this.eat(match)) {} - return this.pos !== start; - } - - /** - * Backs up the stream n characters. Backing it up further than the - * start of the current token will cause things to break, so be careful. - * @param {Number} n - */ - backUp(n) { - this.pos -= n || 1; - } - - /** - * Get the string between the start of the current token and the - * current stream position. - * @returns {String} - */ - current() { - return this.substring(this.start, this.pos); - } - - /** - * Returns substring for given range - * @param {Number} start - * @param {Number} [end] - * @return {String} - */ - substring(start, end) { - return this.string.slice(start, end); - } - - /** - * Creates error object with current stream state - * @param {String} message - * @return {Error} - */ - error(message) { - const err = new Error(`${message} at char ${this.pos + 1}`); - err.originalMessage = message; - err.pos = this.pos; - err.string = this.string; - return err; - } -}; - - -/* harmony default export */ var stream_reader_es = (StreamReader); -// CONCATENATED MODULE: ../node_modules/@emmetio/stream-reader-utils/dist/stream-reader-utils.es.js -var stream_reader_utils_es__extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -/** - * Methods for consuming quoted values - */ - -const SINGLE_QUOTE = 39; // ' -const DOUBLE_QUOTE = 34; // " - -const defaultOptions = { - escape: 92, // \ character - throws: false -}; - -/** - * Consumes 'single' or "double"-quoted string from given string, if possible - * @param {StreamReader} stream - * @param {Number} options.escape A character code of quote-escape symbol - * @param {Boolean} options.throws Throw error if quotes string can’t be properly consumed - * @return {Boolean} `true` if quoted string was consumed. The contents - * of quoted string will be availabe as `stream.current()` - */ -var eatQuoted = function (stream, options) { - options = options ? stream_reader_utils_es__extends({}, defaultOptions, options) : defaultOptions; - const start = stream.pos; - const quote = stream.peek(); - - if (stream.eat(isQuote)) { - while (!stream.eof()) { - switch (stream.next()) { - case quote: - stream.start = start; - return true; - - case options.escape: - stream.next(); - break; - } - } - - // If we’re here then stream wasn’t properly consumed. - // Revert stream and decide what to do - stream.pos = start; - - if (options.throws) { - throw stream.error('Unable to consume quoted string'); - } - } - - return false; -}; - -function isQuote(code) { - return code === SINGLE_QUOTE || code === DOUBLE_QUOTE; -} - -/** - * Check if given code is a number - * @param {Number} code - * @return {Boolean} - */ -function isNumber(code) { - return code > 47 && code < 58; -} - -/** - * Check if given character code is alpha code (letter through A to Z) - * @param {Number} code - * @param {Number} [from] - * @param {Number} [to] - * @return {Boolean} - */ -function isAlpha(code, from, to) { - from = from || 65; // A - to = to || 90; // Z - code &= ~32; // quick hack to convert any char code to uppercase char code - - return code >= from && code <= to; -} - -/** - * Check if given character code is alpha-numeric (letter through A to Z or number) - * @param {Number} code - * @return {Boolean} - */ -function isAlphaNumeric(code) { - return isNumber(code) || isAlpha(code); -} - -function isWhiteSpace(code) { - return code === 32 /* space */ - || code === 9 /* tab */ - || code === 160; /* non-breaking space */ -} - -/** - * Check if given character code is a space - * @param {Number} code - * @return {Boolean} - */ -function isSpace(code) { - return isWhiteSpace(code) || code === 10 /* LF */ - || code === 13; /* CR */ -} - -const defaultOptions$1 = { - escape: 92, // \ character - throws: false -}; - -/** - * Eats paired characters substring, for example `(foo)` or `[bar]` - * @param {StreamReader} stream - * @param {Number} open Character code of pair openinig - * @param {Number} close Character code of pair closing - * @param {Object} [options] - * @return {Boolean} Returns `true` if chacarter pair was successfully - * consumed, it’s content will be available as `stream.current()` - */ -function eatPair(stream, open, close, options) { - options = options ? stream_reader_utils_es__extends({}, defaultOptions$1, options) : defaultOptions$1; - const start = stream.pos; - - if (stream.eat(open)) { - let stack = 1, - ch; - - while (!stream.eof()) { - if (eatQuoted(stream, options)) { - continue; - } - - ch = stream.next(); - if (ch === open) { - stack++; - } else if (ch === close) { - stack--; - if (!stack) { - stream.start = start; - return true; - } - } else if (ch === options.escape) { - stream.next(); - } - } - - // If we’re here then paired character can’t be consumed - stream.pos = start; - - if (options.throws) { - throw stream.error(`Unable to find matching pair for ${String.fromCharCode(open)}`); - } - } - - return false; -} - - -// CONCATENATED MODULE: ../node_modules/@emmetio/field-parser/dist/field-parser.es.js - - - -const DOLLAR = 36; // $ -const COLON = 58; // : -const ESCAPE = 92; // \ -const OPEN_BRACE = 123; // { -const CLOSE_BRACE = 125; // } - -/** - * Finds fields in given string and returns object with field-less string - * and array of fields found - * @param {String} string - * @return {Object} - */ -function parse(string) { - const stream = new stream_reader_es(string); - const fields = []; - let cleanString = '', - offset = 0, - pos = 0; - let code, field; - - while (!stream.eof()) { - code = stream.peek(); - pos = stream.pos; - - if (code === ESCAPE) { - stream.next(); - stream.next(); - } else if (field = consumeField(stream, cleanString.length + pos - offset)) { - fields.push(field); - cleanString += stream.string.slice(offset, pos) + field.placeholder; - offset = stream.pos; - } else { - stream.next(); - } - } - - return new FieldString(cleanString + stream.string.slice(offset), fields); -} - -/** - * Marks given `string` with `fields`: wraps each field range with - * `${index:placeholder}` (by default) or any other token produced by `token` - * function, if provided - * @param {String} string String to mark - * @param {Array} fields Array of field descriptor. A field descriptor is a - * `{index, location, length}` array. It is important that fields in array - * must be ordered by their location in string: some fields my refer the same - * location so they must appear in order that user expects. - * @param {Function} [token] Function that generates field token. This function - * received two arguments: `index` and `placeholder` and should return string - * @return {String} String with marked fields - */ -function mark(string, fields, token) { - token = token || createToken; - - // order fields by their location and appearence - // NB field ranges should not overlap! (not supported yet) - const ordered = fields.map((field, order) => ({ order, field, end: field.location + field.length })).sort((a, b) => a.end - b.end || a.order - b.order); - - // mark ranges in string - let offset = 0; - const result = ordered.map(item => { - const placeholder = string.substr(item.field.location, item.field.length); - const prefix = string.slice(offset, item.field.location); - offset = item.end; - return prefix + token(item.field.index, placeholder); - }); - - return result.join('') + string.slice(offset); -} - -/** - * Creates field token for string - * @param {Number} index Field index - * @param {String} placeholder Field placeholder, could be empty string - * @return {String} - */ -function createToken(index, placeholder) { - return placeholder ? `\${${index}:${placeholder}}` : `\${${index}}`; -} - -/** - * Consumes field from current stream position: it can be an `$index` or - * or `${index}` or `${index:placeholder}` - * @param {StreamReader} stream - * @param {Number} location Field location in *clean* string - * @return {Field} Object with `index` and `placeholder` properties if - * field was successfully consumed, `null` otherwise - */ -function consumeField(stream, location) { - const start = stream.pos; - - if (stream.eat(DOLLAR)) { - // Possible start of field - let index = consumeIndex(stream); - let placeholder = ''; - - // consumed $index placeholder - if (index != null) { - return new Field(index, placeholder, location); - } - - if (stream.eat(OPEN_BRACE)) { - index = consumeIndex(stream); - if (index != null) { - if (stream.eat(COLON)) { - placeholder = consumePlaceholder(stream); - } - - if (stream.eat(CLOSE_BRACE)) { - return new Field(index, placeholder, location); - } - } - } - } - - // If we reached here then there’s no valid field here, revert - // back to starting position - stream.pos = start; -} - -/** - * Consumes a placeholder: value right after `:` in field. Could be empty - * @param {StreamReader} stream - * @return {String} - */ -function consumePlaceholder(stream) { - let code; - const stack = []; - stream.start = stream.pos; - - while (!stream.eof()) { - code = stream.peek(); - - if (code === OPEN_BRACE) { - stack.push(stream.pos); - } else if (code === CLOSE_BRACE) { - if (!stack.length) { - break; - } - stack.pop(); - } - stream.next(); - } - - if (stack.length) { - throw stream.error('Unable to find matching "}" for curly brace at ' + stack.pop()); - } - - return stream.current(); -} - -/** - * Consumes integer from current stream position - * @param {StreamReader} stream - * @return {Number} - */ -function consumeIndex(stream) { - stream.start = stream.pos; - if (stream.eatWhile(isNumber)) { - return Number(stream.current()); - } -} - -let Field = class Field { - constructor(index, placeholder, location) { - this.index = index; - this.placeholder = placeholder; - this.location = location; - this.length = this.placeholder.length; - } -}; -let FieldString = class FieldString { - /** - * @param {String} string - * @param {Field[]} fields - */ - constructor(string, fields) { - this.string = string; - this.fields = fields; - } - - mark(token) { - return mark(this.string, this.fields, token); - } - - toString() { - return this.string; - } -}; - - -/* harmony default export */ var field_parser_es = (parse); - -//# sourceMappingURL=field-parser.es.js.map -// CONCATENATED MODULE: ../node_modules/@emmetio/extract-abbreviation/dist/extract-abbreviation.es.js -var extract_abbreviation_es__extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -/** - * Minimalistic backwards stream reader - */ -let extract_abbreviation_es_StreamReader = class StreamReader { - constructor(string, start) { - this.string = string; - this.start = start || 0; - this.pos = this.string.length; - } - - sol() { - return this.pos === this.start; - } - - peek(offset) { - return this.string.charCodeAt(this.pos - 1 + (offset || 0)); - } - - prev() { - if (!this.sol()) { - return this.string.charCodeAt(--this.pos); - } - } - - eat(match) { - if (this.sol()) { - return false; - } - - const ok = typeof match === 'function' ? match(this.peek()) : match === this.peek(); - - if (ok) { - this.pos--; - } - - return ok; - } - - eatWhile(match) { - const start = this.pos; - while (this.eat(match)) {} - return this.pos < start; - } -}; - -/** - * Quotes-related utilities - */ - -const extract_abbreviation_es_SINGLE_QUOTE = 39; // ' -const extract_abbreviation_es_DOUBLE_QUOTE = 34; // " -const extract_abbreviation_es_ESCAPE = 92; // \ - -/** - * Check if given character code is a quote - * @param {Number} c - * @return {Boolean} - */ -function extract_abbreviation_es_isQuote(c) { - return c === extract_abbreviation_es_SINGLE_QUOTE || c === extract_abbreviation_es_DOUBLE_QUOTE; -} - -/** - * Consumes quoted value, if possible - * @param {StreamReader} stream - * @return {Boolean} Returns `true` is value was consumed - */ -function extract_abbreviation_es_eatQuoted(stream) { - const start = stream.pos; - const quote = stream.prev(); - - if (extract_abbreviation_es_isQuote(quote)) { - while (!stream.sol()) { - if (stream.prev() === quote && stream.peek() !== extract_abbreviation_es_ESCAPE) { - return true; - } - } - } - - stream.pos = start; - return false; -} - -const TAB = 9; -const SPACE = 32; -const DASH = 45; // - -const SLASH = 47; // / -const extract_abbreviation_es_COLON = 58; // : -const EQUALS = 61; // = -const ANGLE_LEFT = 60; // < -const ANGLE_RIGHT = 62; // > - -/** - * Check if given reader’s current position points at the end of HTML tag - * @param {StreamReader} stream - * @return {Boolean} - */ -var isAtHTMLTag = function (stream) { - const start = stream.pos; - - if (!stream.eat(ANGLE_RIGHT)) { - return false; - } - - let ok = false; - stream.eat(SLASH); // possibly self-closed element - - while (!stream.sol()) { - stream.eatWhile(extract_abbreviation_es_isWhiteSpace); - - if (eatIdent(stream)) { - // ate identifier: could be a tag name, boolean attribute or unquoted - // attribute value - if (stream.eat(SLASH)) { - // either closing tag or invalid tag - ok = stream.eat(ANGLE_LEFT); - break; - } else if (stream.eat(ANGLE_LEFT)) { - // opening tag - ok = true; - break; - } else if (stream.eat(extract_abbreviation_es_isWhiteSpace)) { - // boolean attribute - continue; - } else if (stream.eat(EQUALS)) { - // simple unquoted value or invalid attribute - if (eatIdent(stream)) { - continue; - } - break; - } else if (eatAttributeWithUnquotedValue(stream)) { - // identifier was a part of unquoted value - ok = true; - break; - } - - // invalid tag - break; - } - - if (eatAttribute(stream)) { - continue; - } - - break; - } - - stream.pos = start; - return ok; -}; - -/** - * Eats HTML attribute from given string. - * @param {StreamReader} state - * @return {Boolean} `true` if attribute was consumed. - */ -function eatAttribute(stream) { - return eatAttributeWithQuotedValue(stream) || eatAttributeWithUnquotedValue(stream); -} - -/** - * @param {StreamReader} stream - * @return {Boolean} - */ -function eatAttributeWithQuotedValue(stream) { - const start = stream.pos; - if (extract_abbreviation_es_eatQuoted(stream) && stream.eat(EQUALS) && eatIdent(stream)) { - return true; - } - - stream.pos = start; - return false; -} - -/** - * @param {StreamReader} stream - * @return {Boolean} - */ -function eatAttributeWithUnquotedValue(stream) { - const start = stream.pos; - if (stream.eatWhile(isUnquotedValue) && stream.eat(EQUALS) && eatIdent(stream)) { - return true; - } - - stream.pos = start; - return false; -} - -/** - * Eats HTML identifier from stream - * @param {StreamReader} stream - * @return {Boolean} - */ -function eatIdent(stream) { - return stream.eatWhile(isIdent); -} - -/** - * Check if given character code belongs to HTML identifier - * @param {Number} c - * @return {Boolean} - */ -function isIdent(c) { - return c === extract_abbreviation_es_COLON || c === DASH || extract_abbreviation_es_isAlpha(c) || extract_abbreviation_es_isNumber(c); -} - -/** - * Check if given character code is alpha code (letter though A to Z) - * @param {Number} c - * @return {Boolean} - */ -function extract_abbreviation_es_isAlpha(c) { - c &= ~32; // quick hack to convert any char code to uppercase char code - return c >= 65 && c <= 90; // A-Z -} - -/** - * Check if given code is a number - * @param {Number} c - * @return {Boolean} - */ -function extract_abbreviation_es_isNumber(c) { - return c > 47 && c < 58; -} - -/** - * Check if given code is a whitespace - * @param {Number} c - * @return {Boolean} - */ -function extract_abbreviation_es_isWhiteSpace(c) { - return c === SPACE || c === TAB; -} - -/** - * Check if given code may belong to unquoted attribute value - * @param {Number} c - * @return {Boolean} - */ -function isUnquotedValue(c) { - return c && c !== EQUALS && !extract_abbreviation_es_isWhiteSpace(c) && !extract_abbreviation_es_isQuote(c); -} - -const extract_abbreviation_es_code = ch => ch.charCodeAt(0); -const SQUARE_BRACE_L = extract_abbreviation_es_code('['); -const SQUARE_BRACE_R = extract_abbreviation_es_code(']'); -const ROUND_BRACE_L = extract_abbreviation_es_code('('); -const ROUND_BRACE_R = extract_abbreviation_es_code(')'); -const CURLY_BRACE_L = extract_abbreviation_es_code('{'); -const CURLY_BRACE_R = extract_abbreviation_es_code('}'); - -const specialChars = new Set('#.*:$-_!@%^+>/'.split('').map(extract_abbreviation_es_code)); -const bracePairs = new Map().set(SQUARE_BRACE_L, SQUARE_BRACE_R).set(ROUND_BRACE_L, ROUND_BRACE_R).set(CURLY_BRACE_L, CURLY_BRACE_R); - -const extract_abbreviation_es_defaultOptions = { - syntax: 'markup', - lookAhead: null, - prefix: '' -}; - -/** - * Extracts Emmet abbreviation from given string. - * The goal of this module is to extract abbreviation from current editor’s line, - * e.g. like this: `.foo[title=bar|]` -> `.foo[title=bar]`, where - * `|` is a current caret position. - * @param {String} line A text line where abbreviation should be expanded - * @param {Number} [pos] Caret position in line. If not given, uses end-of-line - * @param {Object} [options] - * @param {Boolean} [options.lookAhead] Allow parser to look ahead of `pos` index for - * searching of missing abbreviation parts. Most editors automatically inserts - * closing braces for `[`, `{` and `(`, which will most likely be right after - * current caret position. So in order to properly expand abbreviation, user - * must explicitly move caret right after auto-inserted braces. With this option - * enabled, parser will search for closing braces right after `pos`. Default is `true` - * @param {String} [options.syntax] Name of context syntax of expanded abbreviation. - * Either 'markup' (default) or 'stylesheet'. In 'stylesheet' syntax, braces `[]` - * and `{}` are not supported thus not extracted. - * @param {String} [options.prefix] A string that should precede abbreviation in - * order to make it successfully extracted. If given, the abbreviation will be - * extracted from the nearest `prefix` occurrence. - * @return {Object} Object with `abbreviation` and its `location` in given line - * if abbreviation can be extracted, `null` otherwise - */ -function extractAbbreviation(line, pos, options) { - // make sure `pos` is within line range - pos = Math.min(line.length, Math.max(0, pos == null ? line.length : pos)); - - if (typeof options === 'boolean') { - options = extract_abbreviation_es__extends({}, extract_abbreviation_es_defaultOptions, { lookAhead: options }); - } else { - options = extract_abbreviation_es__extends({}, extract_abbreviation_es_defaultOptions, options); - } - - if (options.lookAhead == null || options.lookAhead === true) { - pos = offsetPastAutoClosed(line, pos, options); - } - - let c; - const start = getStartOffset(line, pos, options.prefix); - if (start === -1) { - return null; - } - - const stream = new extract_abbreviation_es_StreamReader(line, start); - stream.pos = pos; - const stack = []; - - while (!stream.sol()) { - c = stream.peek(); - - if (isCloseBrace(c, options.syntax)) { - stack.push(c); - } else if (isOpenBrace(c, options.syntax)) { - if (stack.pop() !== bracePairs.get(c)) { - // unexpected brace - break; - } - } else if (has(stack, SQUARE_BRACE_R) || has(stack, CURLY_BRACE_R)) { - // respect all characters inside attribute sets or text nodes - stream.pos--; - continue; - } else if (isAtHTMLTag(stream) || !isAbbreviation(c)) { - break; - } - - stream.pos--; - } - - if (!stack.length && stream.pos !== pos) { - // found something, remove some invalid symbols from the - // beginning and return abbreviation - const abbreviation = line.slice(stream.pos, pos).replace(/^[*+>^]+/, ''); - return { - abbreviation, - location: pos - abbreviation.length, - start: options.prefix ? start - options.prefix.length : pos - abbreviation.length, - end: pos - }; - } -} - -/** - * Returns new `line` index which is right after characters beyound `pos` that - * editor will likely automatically close, e.g. }, ], and quotes - * @param {String} line - * @param {Number} pos - * @return {Number} - */ -function offsetPastAutoClosed(line, pos, options) { - // closing quote is allowed only as a next character - if (extract_abbreviation_es_isQuote(line.charCodeAt(pos))) { - pos++; - } - - // offset pointer until non-autoclosed character is found - while (isCloseBrace(line.charCodeAt(pos), options.syntax)) { - pos++; - } - - return pos; -} - -/** - * Returns start offset (left limit) in `line` where we should stop looking for - * abbreviation: it’s nearest to `pos` location of `prefix` token - * @param {String} line - * @param {Number} pos - * @param {String} prefix - * @return {Number} - */ -function getStartOffset(line, pos, prefix) { - if (!prefix) { - return 0; - } - - const stream = new extract_abbreviation_es_StreamReader(line); - const compiledPrefix = String(prefix).split('').map(extract_abbreviation_es_code); - stream.pos = pos; - let result; - - while (!stream.sol()) { - if (consumePair(stream, SQUARE_BRACE_R, SQUARE_BRACE_L) || consumePair(stream, CURLY_BRACE_R, CURLY_BRACE_L)) { - continue; - } - - result = stream.pos; - if (consumeArray(stream, compiledPrefix)) { - return result; - } - - stream.pos--; - } - - return -1; -} - -/** - * Consumes full character pair, if possible - * @param {StreamReader} stream - * @param {Number} close - * @param {Number} open - * @return {Boolean} - */ -function consumePair(stream, close, open) { - const start = stream.pos; - if (stream.eat(close)) { - while (!stream.sol()) { - if (stream.eat(open)) { - return true; - } - - stream.pos--; - } - } - - stream.pos = start; - return false; -} - -/** - * Consumes all character codes from given array, right-to-left, if possible - * @param {StreamReader} stream - * @param {Number[]} arr - */ -function consumeArray(stream, arr) { - const start = stream.pos; - let consumed = false; - - for (let i = arr.length - 1; i >= 0 && !stream.sol(); i--) { - if (!stream.eat(arr[i])) { - break; - } - - consumed = i === 0; - } - - if (!consumed) { - stream.pos = start; - } - - return consumed; -} - -function has(arr, value) { - return arr.indexOf(value) !== -1; -} - -function isAbbreviation(c) { - return c > 64 && c < 91 || // uppercase letter - c > 96 && c < 123 // lowercase letter - || c > 47 && c < 58 // number - || specialChars.has(c); // special character -} - -function isOpenBrace(c, syntax) { - return c === ROUND_BRACE_L || syntax === 'markup' && (c === SQUARE_BRACE_L || c === CURLY_BRACE_L); -} - -function isCloseBrace(c, syntax) { - return c === ROUND_BRACE_R || syntax === 'markup' && (c === SQUARE_BRACE_R || c === CURLY_BRACE_R); -} - -/* harmony default export */ var extract_abbreviation_es = (extractAbbreviation); -// CONCATENATED MODULE: ../node_modules/@emmetio/node/dist/node.es.js -var node_es__extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -/** - * Attribute descriptor of parsed abbreviation node - * @param {String} name Attribute name - * @param {String} value Attribute value - * @param {Object} options Additional custom attribute options - * @param {Boolean} options.boolean Attribute is boolean (e.g. name equals value) - * @param {Boolean} options.implied Attribute is implied (e.g. must be outputted - * only if contains non-null value) - */ -let Attribute = class Attribute { - constructor(name, value, options) { - this.name = name; - this.value = value != null ? value : null; - this.options = options || {}; - } - - /** - * Create a copy of current attribute - * @return {Attribute} - */ - clone() { - return new Attribute(this.name, this.value, node_es__extends({}, this.options)); - } - - /** - * A string representation of current node - */ - valueOf() { - return `${this.name}="${this.value}"`; - } -}; - -/** - * A parsed abbreviation AST node. Nodes build up an abbreviation AST tree - */ - -let Node = class Node { - /** - * Creates a new node - * @param {String} [name] Node name - * @param {Array} [attributes] Array of attributes to add - */ - constructor(name, attributes) { - // own properties - this.name = name || null; - this.value = null; - this.repeat = null; - this.selfClosing = false; - - this.children = []; - - /** @type {Node} Pointer to parent node */ - this.parent = null; - - /** @type {Node} Pointer to next sibling */ - this.next = null; - - /** @type {Node} Pointer to previous sibling */ - this.previous = null; - - this._attributes = []; - - if (Array.isArray(attributes)) { - attributes.forEach(attr => this.setAttribute(attr)); - } - } - - /** - * Array of current node attributes - * @return {Attribute[]} Array of attributes - */ - get attributes() { - return this._attributes; - } - - /** - * A shorthand to retreive node attributes as map - * @return {Object} - */ - get attributesMap() { - return this.attributes.reduce((out, attr) => { - out[attr.name] = attr.options.boolean ? attr.name : attr.value; - return out; - }, {}); - } - - /** - * Check if current node is a grouping one, e.g. has no actual representation - * and is used for grouping subsequent nodes only - * @return {Boolean} - */ - get isGroup() { - return !this.name && !this.value && !this._attributes.length; - } - - /** - * Check if given node is a text-only node, e.g. contains only value - * @return {Boolean} - */ - get isTextOnly() { - return !this.name && !!this.value && !this._attributes.length; - } - - /** - * Returns first child node - * @return {Node} - */ - get firstChild() { - return this.children[0]; - } - - /** - * Returns last child of current node - * @return {Node} - */ - get lastChild() { - return this.children[this.children.length - 1]; - } - - /** - * Return index of current node in its parent child list - * @return {Number} Returns -1 if current node is a root one - */ - get childIndex() { - return this.parent ? this.parent.children.indexOf(this) : -1; - } - - /** - * Returns next sibling of current node - * @return {Node} - */ - get nextSibling() { - return this.next; - } - - /** - * Returns previous sibling of current node - * @return {Node} - */ - get previousSibling() { - return this.previous; - } - - /** - * Returns array of unique class names in current node - * @return {String[]} - */ - get classList() { - const attr = this.getAttribute('class'); - return attr && attr.value ? attr.value.split(/\s+/g).filter(uniqueClass) : []; - } - - /** - * Convenient alias to create a new node instance - * @param {String} [name] Node name - * @param {Object} [attributes] Attributes hash - * @return {Node} - */ - create(name, attributes) { - return new Node(name, attributes); - } - - /** - * Sets given attribute for current node - * @param {String|Object|Attribute} name Attribute name or attribute object - * @param {String} [value] Attribute value - */ - setAttribute(name, value) { - const attr = createAttribute(name, value); - const curAttr = this.getAttribute(name); - if (curAttr) { - this.replaceAttribute(curAttr, attr); - } else { - this._attributes.push(attr); - } - } - - /** - * Check if attribute with given name exists in node - * @param {String} name - * @return {Boolean} - */ - hasAttribute(name) { - return !!this.getAttribute(name); - } - - /** - * Returns attribute object by given name - * @param {String} name - * @return {Attribute} - */ - getAttribute(name) { - if (typeof name === 'object') { - name = name.name; - } - - for (var i = 0; i < this._attributes.length; i++) { - const attr = this._attributes[i]; - if (attr.name === name) { - return attr; - } - } - } - - /** - * Replaces attribute with new instance - * @param {String|Attribute} curAttribute Current attribute name or instance - * to replace - * @param {String|Object|Attribute} newName New attribute name or attribute object - * @param {String} [newValue] New attribute value - */ - replaceAttribute(curAttribute, newName, newValue) { - if (typeof curAttribute === 'string') { - curAttribute = this.getAttribute(curAttribute); - } - - const ix = this._attributes.indexOf(curAttribute); - if (ix !== -1) { - this._attributes.splice(ix, 1, createAttribute(newName, newValue)); - } - } - - /** - * Removes attribute with given name - * @param {String|Attribute} attr Atrtibute name or instance - */ - removeAttribute(attr) { - if (typeof attr === 'string') { - attr = this.getAttribute(attr); - } - - const ix = this._attributes.indexOf(attr); - if (ix !== -1) { - this._attributes.splice(ix, 1); - } - } - - /** - * Removes all attributes from current node - */ - clearAttributes() { - this._attributes.length = 0; - } - - /** - * Adds given class name to class attribute - * @param {String} token Class name token - */ - addClass(token) { - token = normalize(token); - - if (!this.hasAttribute('class')) { - this.setAttribute('class', token); - } else if (token && !this.hasClass(token)) { - this.setAttribute('class', this.classList.concat(token).join(' ')); - } - } - - /** - * Check if current node contains given class name - * @param {String} token Class name token - * @return {Boolean} - */ - hasClass(token) { - return this.classList.indexOf(normalize(token)) !== -1; - } - - /** - * Removes given class name from class attribute - * @param {String} token Class name token - */ - removeClass(token) { - token = normalize(token); - if (this.hasClass(token)) { - this.setAttribute('class', this.classList.filter(name => name !== token).join(' ')); - } - } - - /** - * Appends child to current node - * @param {Node} node - */ - appendChild(node) { - this.insertAt(node, this.children.length); - } - - /** - * Inserts given `newNode` before `refNode` child node - * @param {Node} newNode - * @param {Node} refNode - */ - insertBefore(newNode, refNode) { - this.insertAt(newNode, this.children.indexOf(refNode)); - } - - /** - * Insert given `node` at `pos` position of child list - * @param {Node} node - * @param {Number} pos - */ - insertAt(node, pos) { - if (pos < 0 || pos > this.children.length) { - throw new Error('Unable to insert node: position is out of child list range'); - } - - const prev = this.children[pos - 1]; - const next = this.children[pos]; - - node.remove(); - node.parent = this; - this.children.splice(pos, 0, node); - - if (prev) { - node.previous = prev; - prev.next = node; - } - - if (next) { - node.next = next; - next.previous = node; - } - } - - /** - * Removes given child from current node - * @param {Node} node - */ - removeChild(node) { - const ix = this.children.indexOf(node); - if (ix !== -1) { - this.children.splice(ix, 1); - if (node.previous) { - node.previous.next = node.next; - } - - if (node.next) { - node.next.previous = node.previous; - } - - node.parent = node.next = node.previous = null; - } - } - - /** - * Removes current node from its parent - */ - remove() { - if (this.parent) { - this.parent.removeChild(this); - } - } - - /** - * Creates a detached copy of current node - * @param {Boolean} deep Clone node contents as well - * @return {Node} - */ - clone(deep) { - const clone = new Node(this.name); - clone.value = this.value; - clone.selfClosing = this.selfClosing; - if (this.repeat) { - clone.repeat = node_es__extends({}, this.repeat); - } - - this._attributes.forEach(attr => clone.setAttribute(attr.clone())); - - if (deep) { - this.children.forEach(child => clone.appendChild(child.clone(true))); - } - - return clone; - } - - /** - * Walks on each descendant node and invokes given `fn` function on it. - * The function receives two arguments: the node itself and its depth level - * from current node. If function returns `false`, it stops walking - * @param {Function} fn - */ - walk(fn, _level) { - _level = _level || 0; - let ctx = this.firstChild; - - while (ctx) { - // in case if context node will be detached during `fn` call - const next = ctx.next; - - if (fn(ctx, _level) === false || ctx.walk(fn, _level + 1) === false) { - return false; - } - - ctx = next; - } - } - - /** - * A helper method for transformation chaining: runs given `fn` function on - * current node and returns the same node - */ - use(fn) { - const args = [this]; - for (var i = 1; i < arguments.length; i++) { - args.push(arguments[i]); - } - - fn.apply(null, args); - return this; - } - - toString() { - const attrs = this.attributes.map(attr => { - attr = this.getAttribute(attr.name); - const opt = attr.options; - let out = `${opt && opt.implied ? '!' : ''}${attr.name || ''}`; - if (opt && opt.boolean) { - out += '.'; - } else if (attr.value != null) { - out += `="${attr.value}"`; - } - return out; - }); - - let out = `${this.name || ''}`; - if (attrs.length) { - out += `[${attrs.join(' ')}]`; - } - - if (this.value != null) { - out += `{${this.value}}`; - } - - if (this.selfClosing) { - out += '/'; - } - - if (this.repeat) { - out += `*${this.repeat.count ? this.repeat.count : ''}`; - if (this.repeat.value != null) { - out += `@${this.repeat.value}`; - } - } - - return out; - } -}; - -/** - * Attribute factory - * @param {String|Attribute|Object} name Attribute name or attribute descriptor - * @param {*} value Attribute value - * @return {Attribute} - */ - -function createAttribute(name, value) { - if (name instanceof Attribute) { - return name; - } - - if (typeof name === 'string') { - return new Attribute(name, value); - } - - if (name && typeof name === 'object') { - return new Attribute(name.name, name.value, name.options); - } -} - -/** - * @param {String} str - * @return {String} - */ -function normalize(str) { - return String(str).trim(); -} - -function uniqueClass(item, i, arr) { - return item && arr.indexOf(item) === i; -} - -/* harmony default export */ var node_es = (Node); -// CONCATENATED MODULE: ../node_modules/@emmetio/abbreviation/dist/abbreviation.es.js - - - - -const ASTERISK = 42; // * - -/** - * Consumes node repeat token from current stream position and returns its - * parsed value - * @param {StringReader} stream - * @return {Object} - */ -function consumeRepeat(stream) { - if (stream.eat(ASTERISK)) { - stream.start = stream.pos; - - // XXX think about extending repeat syntax with through numbering - return { count: stream.eatWhile(isNumber) ? +stream.current() : null }; - } -} - -const opt = { throws: true }; - -/** - * Consumes quoted literal from current stream position and returns it’s inner, - * unquoted, value - * @param {StringReader} stream - * @return {String} Returns `null` if unable to consume quoted value from current - * position - */ -function consumeQuoted(stream) { - if (eatQuoted(stream, opt)) { - return stream.current().slice(1, -1); - } -} - -const TEXT_START = 123; // { -const TEXT_END = 125; // } -const abbreviation_es_ESCAPE = 92; // \ character - -/** - * Consumes text node `{...}` from stream - * @param {StreamReader} stream - * @return {String} Returns consumed text value (without surrounding braces) or - * `null` if there’s no text at starting position - */ -function consumeText(stream) { - // NB using own implementation instead of `eatPair()` from @emmetio/stream-reader-utils - // to disable quoted value consuming - const start = stream.pos; - - if (stream.eat(TEXT_START)) { - let stack = 1, - ch; - let result = ''; - let offset = stream.pos; - - while (!stream.eof()) { - ch = stream.next(); - if (ch === TEXT_START) { - stack++; - } else if (ch === TEXT_END) { - stack--; - if (!stack) { - stream.start = start; - return result + stream.substring(offset, stream.pos - 1); - } - } else if (ch === abbreviation_es_ESCAPE) { - ch = stream.next(); - if (ch === TEXT_START || ch === TEXT_END) { - result += stream.substring(offset, stream.pos - 2) + String.fromCharCode(ch); - offset = stream.pos; - } - } - } - - // If we’re here then paired character can’t be consumed - stream.pos = start; - throw stream.error(`Unable to find closing ${String.fromCharCode(TEXT_END)} for text start`); - } - - return null; -} - -const EXCL = 33; // . -const DOT = 46; // . -const abbreviation_es_EQUALS = 61; // = -const ATTR_OPEN = 91; // [ -const ATTR_CLOSE = 93; // ] - -const reAttributeName = /^\!?[\w\-:\$@]+\.?$/; - -/** - * Consumes attributes defined in square braces from given stream. - * Example: - * [attr col=3 title="Quoted string" selected. support={react}] - * @param {StringReader} stream - * @returns {Array} Array of consumed attributes - */ -function consumeAttributes(stream) { - if (!stream.eat(ATTR_OPEN)) { - return null; - } - - const result = []; - let token, attr; - - while (!stream.eof()) { - stream.eatWhile(isWhiteSpace); - - if (stream.eat(ATTR_CLOSE)) { - return result; // End of attribute set - } else if ((token = consumeQuoted(stream)) != null) { - // Consumed quoted value: anonymous attribute - result.push({ - name: null, - value: token - }); - } else if (eatUnquoted(stream)) { - // Consumed next word: could be either attribute name or unquoted default value - token = stream.current(); - if (!reAttributeName.test(token)) { - // anonymous attribute - result.push({ name: null, value: token }); - } else { - // Looks like a regular attribute - attr = parseAttributeName(token); - result.push(attr); - - if (stream.eat(abbreviation_es_EQUALS)) { - // Explicitly defined value. Could be a word, a quoted string - // or React-like expression - if ((token = consumeQuoted(stream)) != null) { - attr.value = token; - } else if ((token = consumeText(stream)) != null) { - attr.value = token; - attr.options = { - before: '{', - after: '}' - }; - } else if (eatUnquoted(stream)) { - attr.value = stream.current(); - } - } - } - } else { - throw stream.error('Expected attribute name'); - } - } - - throw stream.error('Expected closing "]" brace'); -} - -function parseAttributeName(name) { - const options = {}; - - // If a first character in attribute name is `!` — it’s an implied - // default attribute - if (name.charCodeAt(0) === EXCL) { - name = name.slice(1); - options.implied = true; - } - - // Check for last character: if it’s a `.`, user wants boolean attribute - if (name.charCodeAt(name.length - 1) === DOT) { - name = name.slice(0, name.length - 1); - options.boolean = true; - } - - const attr = { name }; - if (Object.keys(options).length) { - attr.options = options; - } - - return attr; -} - -/** - * Eats token that can be an unquoted value from given stream - * @param {StreamReader} stream - * @return {Boolean} - */ -function eatUnquoted(stream) { - const start = stream.pos; - if (stream.eatWhile(isUnquoted)) { - stream.start = start; - return true; - } -} - -function isUnquoted(code) { - return !isSpace(code) && !isQuote(code) && code !== ATTR_OPEN && code !== ATTR_CLOSE && code !== abbreviation_es_EQUALS; -} - -const HASH = 35; // # -const DOT$1 = 46; // . -const abbreviation_es_SLASH = 47; // / - -/** - * Consumes a single element node from current abbreviation stream - * @param {StringReader} stream - * @return {Node} - */ -function consumeElement(stream) { - // consume element name, if provided - const start = stream.pos; - const node = new node_es(eatName(stream)); - let next; - - while (!stream.eof()) { - if (stream.eat(DOT$1)) { - node.addClass(eatName(stream)); - } else if (stream.eat(HASH)) { - node.setAttribute('id', eatName(stream)); - } else if (stream.eat(abbreviation_es_SLASH)) { - // A self-closing indicator must be at the end of non-grouping node - if (node.isGroup) { - stream.backUp(1); - throw stream.error('Unexpected self-closing indicator'); - } - node.selfClosing = true; - if (next = consumeRepeat(stream)) { - node.repeat = next; - } - break; - } else if (next = consumeAttributes(stream)) { - for (let i = 0, il = next.length; i < il; i++) { - node.setAttribute(next[i]); - } - } else if ((next = consumeText(stream)) !== null) { - node.value = next; - } else if (next = consumeRepeat(stream)) { - node.repeat = next; - } else { - break; - } - } - - if (start === stream.pos) { - throw stream.error(`Unable to consume abbreviation node, unexpected ${stream.peek()}`); - } - - return node; -} - -function eatName(stream) { - stream.start = stream.pos; - stream.eatWhile(isName); - return stream.current(); -} - -function isName(code) { - return isAlphaNumeric(code) || code === 45 /* - */ - || code === 58 /* : */ - || code === 36 /* $ */ - || code === 64 /* @ */ - || code === 33 /* ! */ - || code === 95 /* _ */ - || code === 37 /* % */; -} - -const GROUP_START = 40; // ( -const GROUP_END = 41; // ) -const OP_SIBLING = 43; // + -const OP_CHILD = 62; // > -const OP_CLIMB = 94; // ^ - -/** - * Parses given string into a node tree - * @param {String} str Abbreviation to parse - * @return {Node} - */ -function abbreviation_es_parse(str) { - const stream = new stream_reader_es(str.trim()); - const root = new node_es(); - let ctx = root, - groupStack = [], - ch; - - while (!stream.eof()) { - ch = stream.peek(); - - if (ch === GROUP_START) { - // start of group - // The grouping node should be detached to properly handle - // out-of-bounds `^` operator. Node will be attached right on group end - const node = new node_es(); - groupStack.push([node, ctx, stream.pos]); - ctx = node; - stream.next(); - continue; - } else if (ch === GROUP_END) { - // end of group - const lastGroup = groupStack.pop(); - if (!lastGroup) { - throw stream.error('Unexpected ")" group end'); - } - - const node = lastGroup[0]; - ctx = lastGroup[1]; - stream.next(); - - // a group can have a repeater - if (node.repeat = consumeRepeat(stream)) { - ctx.appendChild(node); - } else { - // move all children of group into parent node - while (node.firstChild) { - ctx.appendChild(node.firstChild); - } - } - // for convenience, groups can be joined with optional `+` operator - stream.eat(OP_SIBLING); - - continue; - } - - const node = consumeElement(stream); - ctx.appendChild(node); - - if (stream.eof()) { - break; - } - - switch (stream.peek()) { - case OP_SIBLING: - stream.next(); - continue; - - case OP_CHILD: - stream.next(); - ctx = node; - continue; - - case OP_CLIMB: - // it’s perfectly valid to have multiple `^` operators - while (stream.eat(OP_CLIMB)) { - ctx = ctx.parent || ctx; - } - continue; - } - } - - if (groupStack.length) { - stream.pos = groupStack.pop()[2]; - throw stream.error('Expected group close'); - } - - return root; -} - -/** - * Parses given abbreviation and un-rolls it into a full tree: recursively - * replaces repeated elements with actual nodes - * @param {String} abbr - * @return {Node} - */ -function index(abbr) { - const tree = abbreviation_es_parse(abbr); - tree.walk(unroll); - return tree; -} - -function unroll(node) { - if (!node.repeat || !node.repeat.count) { - return; - } - - const parent = node.parent; - let ix = parent.children.indexOf(node); - - for (let i = 0; i < node.repeat.count; i++) { - const clone = node.clone(true); - clone.repeat.value = i + 1; - clone.walk(unroll); - - if (clone.isGroup) { - while (clone.children.length > 0) { - clone.firstChild.repeat = clone.repeat; - parent.insertAt(clone.firstChild, ix++); - } - } else { - parent.insertAt(clone, ix++); - } - } - - node.parent.removeChild(node); -} - -/* harmony default export */ var abbreviation_es = (index); -//# sourceMappingURL=abbreviation.es.js.map -// CONCATENATED MODULE: ../node_modules/@emmetio/html-snippets-resolver/dist/html-snippets-resolver.es.js -var html_snippets_resolver_es__extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - - - -/** - * For every node in given `tree`, finds matching snippet from `registry` and - * resolves it into a parsed abbreviation. Resolved node is then updated or - * replaced with matched abbreviation tree. - * - * A HTML registry basically contains aliases to another Emmet abbreviations, - * e.g. a predefined set of name, attribues and so on, possibly a complex - * abbreviation with multiple elements. So we have to get snippet, parse it - * and recursively resolve it. - * - * @param {Node} tree Parsed Emmet abbreviation - * @param {SnippetsRegistry} registry Registry with all available snippets - * @return {Node} Updated tree - */ - -var html_snippets_resolver_es_index = function (tree, registry) { - tree.walk(node => resolveNode(node, registry)); - return tree; -}; - -function resolveNode(node, registry) { - const stack = new Set(); - const resolve = node => { - const snippet = registry.resolve(node.name); - // A snippet in stack means circular reference. - // It can be either a user error or a perfectly valid snippet like - // "img": "img[src alt]/", e.g. an element with predefined shape. - // In any case, simply stop parsing and keep element as is - if (!snippet || stack.has(snippet)) { - return; - } - - // In case if matched snippet is a function, pass control into it - if (typeof snippet.value === 'function') { - return snippet.value(node, registry, resolve); - } - - const tree = abbreviation_es(snippet.value); - - stack.add(snippet); - tree.walk(resolve); - stack.delete(snippet); - - // move current node contents into new tree - const childTarget = findDeepestNode(tree); - merge(childTarget, node); - - while (tree.firstChild) { - node.parent.insertBefore(tree.firstChild, node); - } - - childTarget.parent.insertBefore(node, childTarget); - childTarget.remove(); - }; - - resolve(node); -} - -/** - * Adds data from first node into second node and returns it - * @param {Node} from - * @param {Node} to - * @return {Node} - */ -function merge(from, to) { - to.name = from.name; - - if (from.selfClosing) { - to.selfClosing = true; - } - - if (from.value != null) { - to.value = from.value; - } - - if (from.repeat) { - to.repeat = html_snippets_resolver_es__extends({}, from.repeat); - } - - return mergeAttributes(from, to); -} - -/** - * Transfer attributes from first element to second one and preserve first - * element’s attributes order - * @param {Node} from - * @param {Node} to - * @return {Node} - */ -function mergeAttributes(from, to) { - mergeClassNames(from, to); - - // It’s important to preserve attributes order: ones in `from` have higher - // pripority than in `to`. Collect attributes in map in order they should - // appear in `to` - const attrMap = new Map(); - - let attrs = from.attributes; - for (let i = 0; i < attrs.length; i++) { - attrMap.set(attrs[i].name, attrs[i].clone()); - } - - attrs = to.attributes.slice(); - for (let i = 0, attr, a; i < attrs.length; i++) { - attr = attrs[i]; - if (attrMap.has(attr.name)) { - a = attrMap.get(attr.name); - a.value = attr.value; - - // If user explicitly wrote attribute in abbreviation, it’s no longer - // implied and should be outputted even if value is empty - if (a.options.implied) { - a.options.implied = false; - } - } else { - attrMap.set(attr.name, attr); - } - - to.removeAttribute(attr); - } - - const newAttrs = Array.from(attrMap.values()); - for (let i = 0; i < newAttrs.length; i++) { - to.setAttribute(newAttrs[i]); - } - - return to; -} - -/** - * Adds class names from first node to second one - * @param {Node} from - * @param {Node} to - * @return {Node} - */ -function mergeClassNames(from, to) { - const classNames = from.classList; - for (let i = 0; i < classNames.length; i++) { - to.addClass(classNames[i]); - } - - return to; -} - -/** - * Finds node which is the deepest for in current node or node iteself. - * @param {Node} node - * @return {Node} - */ -function findDeepestNode(node) { - while (node.children.length) { - node = node.children[node.children.length - 1]; - } - - return node; -} - -/* harmony default export */ var html_snippets_resolver_es = (html_snippets_resolver_es_index); -// CONCATENATED MODULE: ../node_modules/@emmetio/implicit-tag/dist/implicit-tag.es.js -const inlineElements = new Set('a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'.split(',')); -const elementMap = { - p: 'span', - ul: 'li', - ol: 'li', - table: 'tr', - tr: 'td', - tbody: 'tr', - thead: 'tr', - tfoot: 'tr', - colgroup: 'col', - select: 'option', - optgroup: 'option', - audio: 'source', - video: 'source', - object: 'param', - map: 'area' -}; - -/** - * Returns best child node name for given parent node name - * @param {String} parentName Name of parent node - * @return {String} - */ -function resolveImplicitName(parentName) { - parentName = (parentName || '').toLowerCase(); - return elementMap[parentName] || (inlineElements.has(parentName) ? 'span' : 'div'); -} - -/* harmony default export */ var implicit_tag_es = (resolveImplicitName); -// CONCATENATED MODULE: ../node_modules/@emmetio/html-transform/dist/html-transform.es.js -var html_transform_es__extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - - - -/** - * Adds missing tag names for given tree depending on node’s parent name - */ -var implicitTags = function (tree) { - tree.walk(node => { - // resolve only nameless nodes without content - if (node.name == null && node.attributes.length) { - node.name = implicit_tag_es(node.parent.name); - } - }); - return tree; -}; - -/** - * Locates all occurances of given `token` which are not escaped (e.g. are not - * preceded with `\`) given in `str` - * @param {String} str - * @return {Array} Array of token ranges - */ -function findUnescapedTokens(str, token) { - const result = new Set(); - const tlen = token.length; - - // 1. Find all occurances of tokens - let pos = 0; - while ((pos = str.indexOf(token, pos)) !== -1) { - result.add(pos); - pos += tlen; - } - - if (result.size) { - // 2. Remove ones that escaped - let pos = 0; - const len = str.length; - - while (pos < len) { - if (str[pos++] === '\\') { - result.delete(pos++); - } - } - } - - return Array.from(result).map(ix => html_transform_es_range(ix, tlen)); -} - -/** - * Replaces `ranges`, generated by `range()` function, with given `value` in `str` - * @param {String} str Where to replace ranges - * @param {Array} ranges Ranes, created by `range()` function - * @param {String|Function} value Replacement value. If it’s a function, it - * will take a range value as argument and should return a new string - * @return {String} - */ -function replaceRanges(str, ranges, value) { - // should walk from the end of array to keep ranges valid after replacement - for (let i = ranges.length - 1; i >= 0; i--) { - const r = ranges[i]; - - let offset = 0; - let offsetLength = 0; - let descendingOrder = false; - - if (str.substr(r[0] + r[1], 1) === '@') { - if (str.substr(r[0] + r[1] + 1, 1) === '-') { - descendingOrder = true; - } - const matches = str.substr(r[0] + r[1] + 1 + Number(descendingOrder)).match(/^(\d+)/); - if (matches) { - offsetLength = matches[1].length + 1 + Number(descendingOrder); - offset = parseInt(matches[1]) - 1; - } else { - offsetLength = 2; - } - } - - str = str.substring(0, r[0]) + (typeof value === 'function' ? value(str.substr(r[0], r[1]), offset, descendingOrder) : value) + str.substring(r[0] + r[1] + offsetLength); - } - - return str; -} - -function html_transform_es_range(start, length) { - return [start, length]; -} - -const numberingToken = '$'; - -/** - * Numbering of expanded abbreviation: finds all nodes with `$` in value - * or attributes and replaces its occurances with repeater value - */ -var applyNumbering = function (tree) { - tree.walk(applyNumbering$1); - return tree; -}; - -/** - * Applies numbering for given node: replaces occurances of numbering token - * in node’s name, content and attributes - * @param {Node} node - * @return {Node} - */ -function applyNumbering$1(node) { - const repeater = findRepeater(node); - - if (repeater && repeater.value != null) { - // NB replace numbering in nodes with explicit repeater only: - // it solves issues with abbreviations like `xsl:if[test=$foo]` where - // `$foo` is preferred output - const value = repeater.value; - const count = repeater.count; - - node.name = replaceNumbering(node.name, value, count); - node.value = replaceNumbering(node.value, value, count); - node.attributes.forEach(attr => { - const copy = node.getAttribute(attr.name).clone(); - copy.name = replaceNumbering(attr.name, value, count); - copy.value = replaceNumbering(attr.value, value, count); - node.replaceAttribute(attr.name, copy); - }); - } - - return node; -} - -/** - * Returns repeater object for given node - * @param {Node} node - * @return {Object} - */ -function findRepeater(node) { - while (node) { - if (node.repeat) { - return node.repeat; - } - - node = node.parent; - } -} - -/** - * Replaces numbering in given string - * @param {String} str - * @param {Number} value - * @return {String} - */ -function replaceNumbering(str, value, count) { - // replace numbering in strings only: skip explicit wrappers that could - // contain unescaped numbering tokens - if (typeof str === 'string') { - const ranges = getNumberingRanges(str); - return replaceNumberingRanges(str, ranges, value, count); - } - - return str; -} - -/** - * Returns numbering ranges, e.g. ranges of `$` occurances, in given string. - * Multiple adjacent ranges are combined - * @param {String} str - * @return {Array} - */ -function getNumberingRanges(str) { - return findUnescapedTokens(str || '', numberingToken).reduce((out, range$$1) => { - // skip ranges that actually belongs to output placeholder or tabstops - if (!/[#{]/.test(str[range$$1[0] + 1] || '')) { - const lastRange = out[out.length - 1]; - if (lastRange && lastRange[0] + lastRange[1] === range$$1[0]) { - lastRange[1] += range$$1[1]; - } else { - out.push(range$$1); - } - } - - return out; - }, []); -} - -/** - * @param {String} str - * @param {Array} ranges - * @param {Number} value - * @return {String} - */ -function replaceNumberingRanges(str, ranges, value, count) { - const replaced = replaceRanges(str, ranges, (token, offset, descendingOrder) => { - let _value = descendingOrder ? String(offset + count - value + 1) : String(value + offset); - // pad values for multiple numbering tokens, e.g. 3 for $$$ becomes 003 - while (_value.length < token.length) { - _value = '0' + _value; - } - return _value; - }); - - // unescape screened numbering tokens - return unescapeString(replaced); -} - -/** - * Unescapes characters, screened with `\`, in given string - * @param {String} str - * @return {String} - */ -function unescapeString(str) { - let i = 0, - result = ''; - const len = str.length; - - while (i < len) { - const ch = str[i++]; - result += ch === '\\' ? str[i++] || '' : ch; - } - - return result; -} - -/** Placeholder for inserted content */ -const placeholder = '$#'; - -/** Placeholder for caret */ -const caret = '|'; - -const reUrl = /^((?:https?|ftp|file):\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/; -const reEmail = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/; -const reProto = /^([a-z]+:)?\/\//i; - -/** - * Inserts content into node with implicit repeat count: this node is then - * duplicated for each content item and content itself is inserted either into - * deepest child or instead of a special token. - * - * This method uses two distinct steps: `prepare()` and `insert()` since most - * likely these steps will be used separately to properly insert content - * with unescaped `$` numbering markers. - * - * @param {Node} tree Parsed abbreviation - * @param {String[]} content Array of content items to insert - * @return {Node} - */ -/** - * Finds nodes with implicit repeat and creates `amount` copies of it in tree - * @param {Node} tree - * @param {Number} amount - * @return {Node} - */ -function prepare(tree, amount) { - amount = amount || 1; - tree.walk(node => { - if (node.repeat && node.repeat.count === null) { - for (let i = 0; i < amount; i++) { - const clone = node.clone(true); - clone.repeat.implicit = true; - clone.repeat.count = amount; - clone.repeat.value = i + 1; - clone.repeat.index = i; - node.parent.insertBefore(clone, node); - } - - node.remove(); - } - }); - - return tree; -} - -/** - * Inserts content into implicitly repeated nodes, created by `prepare()` method - * @param {Node} tree - * @param {String[]} content - * @return {Node} - */ -function insert(tree, content) { - if (Array.isArray(content) && content.length) { - let updated = false; - tree.walk(node => { - if (node.repeat && node.repeat.implicit) { - updated = true; - insertContent(node, content[node.repeat.index]); - } - }); - - if (!updated) { - // no node with implicit repeat was found, insert content as - // deepest child - setNodeContent(html_transform_es_findDeepestNode(tree), content.join('\n')); - } - } - - return tree; -} - -/** - * Inserts `content` into given `node`: either replaces output placeholders - * or inserts it into deepest child node - * @param {Node} node - * @param {String} content - * @return {Node} - */ -function insertContent(node, content) { - let inserted = insertContentIntoPlaceholder(node, content); - node.walk(child => inserted |= insertContentIntoPlaceholder(child, content)); - - if (!inserted) { - // no placeholders were found in node, insert content into deepest child - setNodeContent(html_transform_es_findDeepestNode(node), content); - } - - return node; -} - -/** - * Inserts given `content` into placeholders for given `node`. Placeholders - * might be available in attribute values and node content - * @param {Node} node - * @param {String} content - * @return {Boolean} Returns `true` if placeholders were found and replaced in node - */ -function insertContentIntoPlaceholder(node, content) { - const state = { replaced: false }; - - node.value = replacePlaceholder(node.value, content, state); - node.attributes.forEach(attr => { - if (attr.value) { - node.setAttribute(attr.name, replacePlaceholder(attr.value, content, state)); - } - }); - - return state.replaced; -} - -/** - * Replaces all placeholder occurances in given `str` with `value` - * @param {String} str - * @param {String} value - * @param {Object} [_state] If provided, set `replaced` property of given - * object to `true` if placeholder was found and replaced - * @return {String} - */ -function replacePlaceholder(str, value, _state) { - if (typeof str === 'string') { - const ranges = findUnescapedTokens(str, placeholder); - if (ranges.length) { - if (_state) { - _state.replaced = true; - } - - str = replaceRanges(str, ranges, value); - } - } - - return str; -} - -/** - * Finds node which is the deepest for in current node or node iteself. - * @param {Node} node - * @return {Node} - */ -function html_transform_es_findDeepestNode(node) { - while (node.children.length) { - node = node.children[node.children.length - 1]; - } - - return node; -} - -/** - * Updates content of given node - * @param {Node} node - * @param {String} content - */ -function setNodeContent(node, content) { - // find caret position and replace it with content, if possible - if (node.value) { - const ranges = findUnescapedTokens(node.value, caret); - if (ranges.length) { - node.value = replaceRanges(node.value, ranges, content); - return; - } - } - - if (node.name.toLowerCase() === 'a' || node.hasAttribute('href')) { - // special case: inserting content into `` tag - if (reUrl.test(content)) { - node.setAttribute('href', (reProto.test(content) ? '' : 'http://') + content); - } else if (reEmail.test(content)) { - node.setAttribute('href', 'mailto:' + content); - } - } - - node.value = content; -} - -const html_transform_es_defaultOptions = { - element: '__', - modifier: '_' -}; - -const reElement = /^(-+)([a-z0-9]+[a-z0-9-]*)/i; -const reModifier = /^(_+)([a-z0-9]+[a-z0-9-_]*)/i; -const blockCandidates1 = className => /^[a-z]\-/i.test(className); -const blockCandidates2 = className => /^[a-z]/i.test(className); - -/** - * BEM transformer: updates class names written as `-element` and - * `_modifier` into full class names as described in BEM specs. Also adds missing - * class names: fir example, if node contains `.block_modifier` class, ensures - * that element contains `.block` class as well - */ -var bem = function (tree, options) { - options = html_transform_es__extends({}, html_transform_es_defaultOptions, options); - - tree.walk(node => expandClassNames(node, options)); - - const lookup = createBlockLookup(tree); - tree.walk(node => expandShortNotation(node, lookup, options)); - - return tree; -}; - -/** - * Expands existing class names in BEM notation in given `node`. - * For example, if node contains `b__el_mod` class name, this method ensures - * that element contains `b__el` class as well - * @param {Node} node - * @param {Object} options - * @return {Set} - */ -function expandClassNames(node, options) { - const classNames = node.classList.reduce((out, cl) => { - // remove all modifiers and element prefixes from class name to get a base element name - const ix = cl.indexOf('_'); - if (ix > 0 && !cl.startsWith('-')) { - out.add(cl.slice(0, ix)); - out.add(cl.slice(ix)); - return out; - } - - return out.add(cl); - }, new Set()); - - if (classNames.size) { - node.setAttribute('class', Array.from(classNames).join(' ')); - } -} - -/** - * Expands short BEM notation, e.g. `-element` and `_modifier` - * @param {Node} node Parsed Emmet abbreviation node - * @param {Map} lookup BEM block name lookup - * @param {Object} options - */ -function expandShortNotation(node, lookup, options) { - const classNames = node.classList.reduce((out, cl) => { - let prefix, m; - const originalClass = cl; - - // parse element definition (could be only one) - if (m = cl.match(reElement)) { - prefix = getBlockName(node, lookup, m[1]) + options.element + m[2]; - out.add(prefix); - cl = cl.slice(m[0].length); - } - - // parse modifiers definitions - if (m = cl.match(reModifier)) { - if (!prefix) { - prefix = getBlockName(node, lookup, m[1]); - out.add(prefix); - } - - out.add(`${prefix}${options.modifier}${m[2]}`); - cl = cl.slice(m[0].length); - } - - if (cl === originalClass) { - // class name wasn’t modified: it’s not a BEM-specific class, - // add it as-is into output - out.add(originalClass); - } - - return out; - }, new Set()); - - const arrClassNames = Array.from(classNames).filter(Boolean); - if (arrClassNames.length) { - node.setAttribute('class', arrClassNames.join(' ')); - } -} - -/** - * Creates block name lookup for each node in given tree, e.g. finds block - * name explicitly for each node - * @param {Node} tree - * @return {Map} - */ -function createBlockLookup(tree) { - const lookup = new Map(); - - tree.walk(node => { - const classNames = node.classList; - if (classNames.length) { - // guess best block name from class or use parent’s block name - lookup.set(node, find(classNames, blockCandidates1) || find(classNames, blockCandidates2) || lookup.get(node.parent)); - } - }); - - return lookup; -} - -/** - * Returns block name for given `node` by `prefix`, which tells the depth of - * of parent node lookup - * @param {Node} node - * @param {Map} lookup - * @param {String} prefix - * @return {String} - */ -function getBlockName(node, lookup, prefix) { - let depth = prefix.length > 1 ? prefix.length : 0; - - // NB don’t walk up to root node, stay at first root child in case of - // too deep prefix - while (node.parent && node.parent.parent && depth--) { - node = node.parent; - } - - return lookup.get(node) || ''; -} - -function find(arr, filter) { - for (let i = 0; i < arr.length; i++) { - if (reElement.test(arr[i]) || reModifier.test(arr[i])) { - break; - } - if (filter(arr[i])) { - return arr[i]; - } - } -} - -/** - * JSX transformer: replaces `class` and `for` attributes with `className` and - * `htmlFor` attributes respectively - */ -var jsx = function (tree) { - tree.walk(node => { - replace(node, 'class', 'className'); - replace(node, 'for', 'htmlFor'); - }); - return tree; -}; - -function replace(node, oldName, newName) { - let attr = node.getAttribute(oldName); - if (attr) { - attr.name = newName; - } -} - -const reSupporterNames = /^xsl:(variable|with\-param)$/i; - -/** - * XSL transformer: removes `select` attributes from certain nodes that contain - * children - */ -var xsl = function (tree) { - tree.walk(node => { - if (reSupporterNames.test(node.name || '') && (node.children.length || node.value)) { - node.removeAttribute('select'); - } - }); - return tree; -}; - -const supportedAddons = { bem, jsx, xsl }; - -/** - * Runs additional transforms on given tree. - * These transforms may introduce side-effects and unexpected result - * so they are not applied by default, authors must specify which addons - * in `addons` argument as `{addonName: addonOptions}` - * @param {Node} tree Parsed Emmet abbreviation - * @param {Object} addons Add-ons to apply and their options - */ -var addons = function (tree, addons) { - Object.keys(addons || {}).forEach(key => { - if (key in supportedAddons) { - const addonOpt = typeof addons[key] === 'object' ? addons[key] : null; - tree = tree.use(supportedAddons[key], addonOpt); - } - }); - - return tree; -}; - -/** - * Applies basic HTML-specific transformations for given parsed abbreviation: - * – resolve implied tag names - * – insert repeated content - * – resolve node numbering - */ -var html_transform_es_index = function (tree, content, appliedAddons) { - if (typeof content === 'string') { - content = [content]; - } else if (content && typeof content === 'object' && !Array.isArray(content)) { - appliedAddons = content; - content = null; - } - - return tree.use(implicitTags).use(prepare, Array.isArray(content) ? content.length : null).use(applyNumbering).use(insert, content).use(addons, appliedAddons); -}; - -/* harmony default export */ var html_transform_es = (html_transform_es_index); -// CONCATENATED MODULE: ../node_modules/@emmetio/variable-resolver/dist/variable-resolver.es.js -/** - * Replaces all unescaped ${variable} occurances in given parsed abbreviation - * `tree` with values provided in `variables` hash. Precede `$` with `\` to - * escape it and skip replacement - * @param {Node} tree Parsed abbreviation tree - * @param {Object} variables Variables values - * @return {Node} - */ -function replaceVariables(tree, variables) { - variables = variables || {}; - tree.walk(node => replaceInNode(node, variables)); - return tree; -} - -function replaceInNode(node, variables) { - // Replace variables in attributes. - const attrs = node.attributes; - - for (let i = 0, il = attrs.length; i < il; i++) { - const attr = attrs[i]; - if (typeof attr.value === 'string') { - node.setAttribute(attr.name, replaceInString(attr.value, variables)); - } - } - - if (node.value != null) { - node.value = replaceInString(node.value, variables); - } - - return node; -} - -/** - * Replaces all unescaped `${variable}` occurances in given string with values - * from `variables` object - * @param {String} string - * @param {Object} variables - * @return {String} - */ -function replaceInString(string, variables) { - const model = createModel(string); - let offset = 0; - let output = ''; - - for (let i = 0, il = model.variables.length; i < il; i++) { - const v = model.variables[i]; - let value = v.name in variables ? variables[v.name] : v.name; - if (typeof value === 'function') { - value = value(model.string, v, offset + v.location); - } - - output += model.string.slice(offset, v.location) + value; - offset = v.location + v.length; - } - - return output + model.string.slice(offset); -} - -/** - * Creates variable model from given string. The model contains a `string` with - * all escaped variable tokens written without escape symbol and `variables` - * property with all unescaped variables and their ranges - * @param {String} string - * @return {Object} - */ -function createModel(string) { - const reVariable = /\$\{([a-z][\w\-]*)\}/ig; - const escapeCharCode = 92; // `\` symbol - const variables = []; - - // We have to replace unescaped (e.g. not preceded with `\`) tokens. - // Instead of writing a stream parser, we’ll cut some edges here: - // 1. Find all tokens - // 2. Walk string char-by-char and resolve only tokens that are not escaped - const tokens = new Map(); - let m; - while (m = reVariable.exec(string)) { - tokens.set(m.index, m); - } - - if (tokens.size) { - let start = 0, - pos = 0, - len = string.length; - let output = ''; - while (pos < len) { - if (string.charCodeAt(pos) === escapeCharCode && tokens.has(pos + 1)) { - // Found escape symbol that escapes variable: we should - // omit this symbol in output string and skip variable - const token = tokens.get(pos + 1); - output += string.slice(start, pos) + token[0]; - start = pos = token.index + token[0].length; - tokens.delete(pos + 1); - continue; - } - - pos++; - } - - string = output + string.slice(start); - - // Not using `.map()` here to reduce memory allocations - const validMatches = Array.from(tokens.values()); - for (let i = 0, il = validMatches.length; i < il; i++) { - const token = validMatches[i]; - variables.push({ - name: token[1], - location: token.index, - length: token[0].length - }); - } - } - - return { string, variables }; -} - -/* harmony default export */ var variable_resolver_es = (replaceVariables); -// CONCATENATED MODULE: ../node_modules/@emmetio/output-renderer/dist/output-renderer.es.js -var output_renderer_es__extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - - - -const defaultFieldsRenderer = text => text; - -/** - * Output node is an object containing generated output for given Emmet - * abbreviation node. Output node can be passed to various processors that - * may shape-up final node output. The final output is simply a concatenation - * of `.open`, `.text` and `.close` properties and its `.before*` and `.after*` - * satellites - * @param {Node} node Parsed Emmet abbreviation node - * @param {Function} fieldsRenderer A function for rendering fielded text (text with - * tabstops) for current node. @see ./render.js for details - */ -let OutputNode = class OutputNode { - constructor(node, fieldsRenderer, options) { - if (typeof fieldsRenderer === 'object') { - options = fieldsRenderer; - fieldsRenderer = null; - } - - this.node = node; - this._fieldsRenderer = fieldsRenderer || defaultFieldsRenderer; - - this.open = null; - this.beforeOpen = ''; - this.afterOpen = ''; - - this.close = null; - this.beforeClose = ''; - this.afterClose = ''; - - this.text = null; - this.beforeText = ''; - this.afterText = ''; - - this.indent = ''; - this.newline = ''; - - if (options) { - output_renderer_es__extends(this, options); - } - } - - clone() { - return new this.constructor(this.node, this); - } - - /** - * Properly indents given multiline text - * @param {String} text - */ - indentText(text) { - const lines = splitByLines(text); - if (lines.length === 1) { - // no newlines, nothing to indent - return text; - } - - // No newline and no indent means no formatting at all: - // in this case we should replace newlines with spaces - const nl = !this.newline && !this.indent ? ' ' : this.newline; - return lines.map((line, i) => i ? this.indent + line : line).join(nl); - } - - /** - * Renders given text with fields - * @param {String} text - * @return {String} - */ - renderFields(text) { - return this._fieldsRenderer(text); - } - - toString(children) { - const open = this._wrap(this.open, this.beforeOpen, this.afterOpen); - const close = this._wrap(this.close, this.beforeClose, this.afterClose); - const text = this._wrap(this.text, this.beforeText, this.afterText); - - return open + text + (children != null ? children : '') + close; - } - - _wrap(str, before, after) { - before = before != null ? before : ''; - after = after != null ? after : ''; - - // automatically trim whitespace for non-empty wraps - if (str != null) { - str = before ? str.replace(/^\s+/, '') : str; - str = after ? str.replace(/\s+$/, '') : str; - return before + this.indentText(str) + after; - } - - return ''; - } -}; - -/** - * Splits given text by lines - * @param {String} text - * @return {String[]} - */ - -function splitByLines(text) { - return (text || '').split(/\r\n|\r|\n/g); -} - -/** - * Default output of field (tabstop) - * @param {Number} index Field index - * @param {String} placeholder Field placeholder, can be null - * @return {String} - */ -const defaultField = (index, placeholder) => placeholder || ''; - -/** - * Renders given parsed abbreviation `tree` via `formatter` function. - - * @param {Node} tree Parsed Emmet abbreviation - * @param {Function} [field] Optional function to format field/tabstop (@see `defaultField`) - * @param {Function} formatter Output formatter function. It takes an output node— - * a special wrapper for parsed node that holds formatting and output properties— - * and updates its output properties to shape-up node’s output. - * Function arguments: - * – `outNode`: OutputNode - * – `renderFields`: a helper function that parses fields/tabstops from given - * text and replaces them with `field` function output. - * It also takes care about field indicies and ensures that the same indicies - * from different nodes won’t collide - */ -function render(tree, field, formatter) { - if (typeof formatter === 'undefined') { - formatter = field; - field = null; - } - - field = field || defaultField; - - // Each node may contain fields like `${1:placeholder}`. - // Since most modern editors will link all fields with the same - // index, we have to ensure that different nodes has their own indicies. - // We’ll use this `fieldState` object to globally increment field indices - // during output - const fieldState = { index: 1 }; - - const fieldsRenderer = text => text == null ? field(fieldState.index++) : getFieldsModel(text, fieldState).mark(field); - - return run(tree.children, formatter, fieldsRenderer); -} - -function run(nodes, formatter, fieldsRenderer) { - return nodes.map(node => { - const outNode = formatter(new OutputNode(node, fieldsRenderer)); - return outNode ? outNode.toString(run(node.children, formatter, fieldsRenderer)) : ''; - }).join(''); -} - -/** - * Returns fields (tab-stops) model with properly updated indices that won’t - * collide with fields in other nodes of foprmatted tree - * @param {String|Object} text Text to get fields model from or model itself - * @param {Object} fieldState Abbreviation tree-wide field state reference - * @return {Object} Field model - */ -function getFieldsModel(text, fieldState) { - const model = typeof text === 'object' ? text : field_parser_es(text); - let largestIndex = -1; - - model.fields.forEach(field => { - field.index += fieldState.index; - if (field.index > largestIndex) { - largestIndex = field.index; - } - }); - - if (largestIndex !== -1) { - fieldState.index = largestIndex + 1; - } - - return model; -} - -/* harmony default export */ var output_renderer_es = (render); -// CONCATENATED MODULE: ../node_modules/@emmetio/markup-formatters/dist/markup-formatters.es.js -var markup_formatters_es__extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - - - - -const TOKEN = /^(.*?)([A-Z_]+)(.*?)$/; -const TOKEN_OPEN = 91; // [ -const TOKEN_CLOSE = 93; // ] - -/** - * A basic templating engine. - * Takes every `[TOKEN]` from given string and replaces it with - * `TOKEN` value from given `data` attribute. The token itself may contain - * various characters between `[`, token name and `]`. Contents of `[...]` will - * be outputted only if `TOKEN` value is not empty. Also, only `TOKEN` name will - * be replaced with actual value, all other characters will remain as is. - * - * Example: - * ``` - * template('[]', {NAME: 'foo'}) -> "" - * template('[]', {}) -> "" - * ``` - */ -function template(str, data) { - if (str == null) { - return str; - } - - // NB since token may contain inner `[` and `]`, we can’t just use regexp - // for replacement, should manually parse string instead - const stack = []; - const replacer = (str, left, token, right) => data[token] != null ? left + data[token] + right : ''; - - let output = ''; - let offset = 0, - i = 0; - let code, lastPos; - - while (i < str.length) { - code = str.charCodeAt(i); - if (code === TOKEN_OPEN) { - stack.push(i); - } else if (code === TOKEN_CLOSE) { - lastPos = stack.pop(); - if (!stack.length) { - output += str.slice(offset, lastPos) + str.slice(lastPos + 1, i).replace(TOKEN, replacer); - offset = i + 1; - } - } - - i++; - } - - return output + str.slice(offset); -} - -/** - * Various utility methods used by formatters - */ - -/** - * Splits given text by lines - * @param {String} text - * @return {String[]} - */ -function markup_formatters_es_splitByLines(text) { - return (text || '').split(/\r\n|\r|\n/g); -} - -/** - * Check if given node is a first child in its parent - * @param {Node} node - * @return {Boolean} - */ -function isFirstChild(node) { - return node.parent.firstChild === node; -} - -/** - * Check if given node is a root node - * @param {Node} node - * @return {Boolean} - */ -function isRoot(node) { - return node && !node.parent; -} - -/** - * Check if given node is a pseudo-snippet: a text-only node with explicitly - * defined children - * @param {Node} node - * @return {Boolean} - */ -function isPseudoSnippet(node) { - return node.isTextOnly && !!node.children.length; -} - -/** - * Handles pseudo-snippet node. - * A pseudo-snippet is a text-only node with explicitly defined children. - * For such case, we have to figure out if pseudo-snippet contains fields - * (tab-stops) in node value and “split” it: make contents before field with - * lowest index node’s “open” part and contents after lowest index — “close” - * part. With this trick a final output will look like node’s children - * are nested inside node value - * @param {OutputNode} outNode - * @return {Boolean} Returns “true” if given node is a pseudo-snippets, - * `false` otherwise - */ -function handlePseudoSnippet(outNode) { - const node = outNode.node; // original abbreviaiton node - - if (isPseudoSnippet(node)) { - const fieldsModel = field_parser_es(node.value); - const field = findLowestIndexField(fieldsModel); - if (field) { - const parts = splitFieldsModel(fieldsModel, field); - outNode.open = outNode.renderFields(parts[0]); - outNode.close = outNode.renderFields(parts[1]); - } else { - outNode.text = outNode.renderFields(fieldsModel); - } - - return true; - } - - return false; -} - -/** - * Finds field with lowest index in given text - * @param {Object} model - * @return {Object} - */ -function findLowestIndexField(model) { - return model.fields.reduce((result, field) => !result || field.index < result.index ? field : result, null); -} - -/** - * Splits given fields model in two parts by given field - * @param {Object} model - * @param {Object} field - * @return {Array} Two-items array - */ -function splitFieldsModel(model, field) { - const ix = model.fields.indexOf(field); - - const left = new model.constructor(model.string.slice(0, field.location), model.fields.slice(0, ix)); - - const right = new model.constructor(model.string.slice(field.location + field.length), model.fields.slice(ix + 1)); - - return [left, right]; -} - -const commentOptions = { - // enable node commenting - enabled: false, - - // attributes that should trigger node commenting on specific node, - // if commenting is enabled - trigger: ['id', 'class'], - - // comment before opening tag - before: '', - - // comment after closing tag - after: '\n' -}; - -/** - * Renders given parsed Emmet abbreviation as HTML, formatted according to - * `profile` options - * @param {Node} tree Parsed Emmet abbreviation - * @param {Profile} profile Output profile - * @param {Object} [options] Additional formatter options - * @return {String} - */ -function html(tree, profile, options) { - options = markup_formatters_es__extends({}, options); - const format = getFormatOptions(options); - - return output_renderer_es(tree, options.field, outNode => { - outNode = setFormatting(outNode, profile); - - if (!handlePseudoSnippet(outNode)) { - const node = outNode.node; - - if (node.name) { - const name = profile.name(node.name); - const attrs = formatAttributes(outNode, profile); - - outNode.open = `<${name}${attrs}${node.selfClosing ? profile.selfClose() : ''}>`; - if (!node.selfClosing) { - outNode.close = ``; - } - - commentNode(outNode, format.comment); - } - - // Do not generate fields for nodes with empty value and children - // or if node is self-closed - if (node.value || !node.children.length && !node.selfClosing) { - outNode.text = outNode.renderFields(node.value); - } - } - - return outNode; - }); -} - -/** - * Updates formatting properties for given output node - * @param {OutputNode} outNode Output wrapper of farsed abbreviation node - * @param {Profile} profile Output profile - * @return {OutputNode} - */ -function setFormatting(outNode, profile) { - const node = outNode.node; - - if (shouldFormatNode(node, profile)) { - outNode.indent = profile.indent(getIndentLevel(node, profile)); - outNode.newline = '\n'; - const prefix = outNode.newline + outNode.indent; - - // do not format the very first node in output - if (!isRoot(node.parent) || !isFirstChild(node)) { - outNode.beforeOpen = prefix; - if (node.isTextOnly) { - outNode.beforeText = prefix; - } - } - - if (hasInnerFormatting(node, profile)) { - if (!node.isTextOnly) { - outNode.beforeText = prefix + profile.indent(1); - } - outNode.beforeClose = prefix; - } - } - - return outNode; -} - -/** - * Check if given node should be formatted - * @param {Node} node - * @param {Profile} profile - * @return {Boolean} - */ -function shouldFormatNode(node, profile) { - if (!profile.get('format')) { - return false; - } - - if (node.parent.isTextOnly && node.parent.children.length === 1 && field_parser_es(node.parent.value).fields.length) { - // Edge case: do not format the only child of text-only node, - // but only if parent contains fields - return false; - } - - return isInline(node, profile) ? shouldFormatInline(node, profile) : true; -} - -/** - * Check if given inline node should be formatted as well, e.g. it contains - * enough adjacent siblings that should force formatting - * @param {Node} node - * @param {Profile} profile - * @return {Boolean} - */ -function shouldFormatInline(node, profile) { - if (!isInline(node, profile)) { - return false; - } - - if (isPseudoSnippet(node)) { - return true; - } - - // check if inline node is the next sibling of block-level node - if (node.childIndex === 0) { - // first node in parent: format if it’s followed by a block-level element - let next = node; - while (next = next.nextSibling) { - if (!isInline(next, profile)) { - return true; - } - } - } else if (!isInline(node.previousSibling, profile)) { - // node is right after block-level element - return true; - } - - if (profile.get('inlineBreak')) { - // check for adjacent inline elements before and after current element - let adjacentInline = 1; - let before = node, - after = node; - - while (isInlineElement(before = before.previousSibling, profile)) { - adjacentInline++; - } - - while (isInlineElement(after = after.nextSibling, profile)) { - adjacentInline++; - } - - if (adjacentInline >= profile.get('inlineBreak')) { - return true; - } - } - - // Another edge case: inline node contains node that should receive foramtting - for (let i = 0, il = node.children.length; i < il; i++) { - if (shouldFormatNode(node.children[i], profile)) { - return true; - } - } - - return false; -} - -/** - * Check if given node contains inner formatting, e.g. any of its children should - * be formatted - * @param {Node} node - * @param {Profile} profile - * @return {Boolean} - */ -function hasInnerFormatting(node, profile) { - // check if node if forced for inner formatting - const nodeName = (node.name || '').toLowerCase(); - if (profile.get('formatForce').indexOf(nodeName) !== -1) { - return true; - } - - // check if any of children should receive formatting - // NB don’t use `childrent.some()` to reduce memory allocations - for (let i = 0; i < node.children.length; i++) { - if (shouldFormatNode(node.children[i], profile)) { - return true; - } - } - - return false; -} - -/** - * Outputs attributes of given abbreviation node as HTML attributes - * @param {OutputNode} outNode - * @param {Profile} profile - * @return {String} - */ -function formatAttributes(outNode, profile) { - const node = outNode.node; - - return node.attributes.map(attr => { - if (attr.options.implied && attr.value == null) { - return null; - } - - const attrName = profile.attribute(attr.name); - let attrValue = null; - - // handle boolean attributes - if (attr.options.boolean || profile.get('booleanAttributes').indexOf(attrName.toLowerCase()) !== -1) { - if (profile.get('compactBooleanAttributes') && attr.value == null) { - return ` ${attrName}`; - } else if (attr.value == null) { - attrValue = attrName; - } - } - - if (attrValue == null) { - attrValue = outNode.renderFields(attr.value); - } - - return ` ${attrName}=${profile.quote(attrValue)}`; - }).join(''); -} - -/** - * Check if given node is inline-level - * @param {Node} node - * @param {Profile} profile - * @return {Boolean} - */ -function isInline(node, profile) { - return node && node.isTextOnly || isInlineElement(node, profile); -} - -/** - * Check if given node is inline-level element, e.g. element with explicitly - * defined node name - * @param {Node} node - * @param {Profile} profile - * @return {Boolean} - */ -function isInlineElement(node, profile) { - return node && profile.isInline(node); -} - -/** - * Computes indent level for given node - * @param {Node} node - * @param {Profile} profile - * @param {Number} level - * @return {Number} - */ -function getIndentLevel(node, profile) { - // Increase indent level IF NOT: - // * parent is text-only node - // * there’s a parent node with a name that is explicitly set to decrease level - const skip = profile.get('formatSkip') || []; - let level = node.parent.isTextOnly ? -2 : -1; - let ctx = node; - while (ctx = ctx.parent) { - if (skip.indexOf((ctx.name || '').toLowerCase()) === -1) { - level++; - } - } - - return level < 0 ? 0 : level; -} - -/** - * Comments given output node, if required - * @param {OutputNode} outNode - * @param {Object} options - */ -function commentNode(outNode, options) { - const node = outNode.node; - - if (!options.enabled || !options.trigger || !node.name) { - return; - } - - const attrs = outNode.node.attributes.reduce((out, attr) => { - if (attr.name && attr.value != null) { - out[attr.name.toUpperCase().replace(/-/g, '_')] = attr.value; - } - - return out; - }, {}); - - // add comment only if attribute trigger is present - for (let i = 0, il = options.trigger.length; i < il; i++) { - if (options.trigger[i].toUpperCase() in attrs) { - outNode.open = template(options.before, attrs) + outNode.open; - if (outNode.close) { - outNode.close += template(options.after, attrs); - } - break; - } - } -} - -function getFormatOptions(options) { - const format = markup_formatters_es__extends({}, options && options.format); - format.comment = markup_formatters_es__extends({}, commentOptions, format.comment); - return format; -} - -const reId = /^id$/i; -const reClass = /^class$/i; -const defaultAttrOptions = { - primary: attrs => attrs.join(''), - secondary: attrs => attrs.map(attr => attr.isBoolean ? attr.name : `${attr.name}=${attr.value}`).join(', ') -}; - -const defaultNodeOptions = { - open: null, - close: null, - omitName: /^div$/i, - attributes: defaultAttrOptions -}; - -function indentFormat(outNode, profile, options) { - options = markup_formatters_es__extends({}, defaultNodeOptions, options); - const node = outNode.node; - - outNode.indent = profile.indent(getIndentLevel$1(node, profile)); - outNode.newline = '\n'; - - // Do not format the very first node in output - if (!isRoot(node.parent) || !isFirstChild(node)) { - outNode.beforeOpen = outNode.newline + outNode.indent; - } - - if (node.name) { - const data = markup_formatters_es__extends({ - NAME: profile.name(node.name), - SELF_CLOSE: node.selfClosing ? options.selfClose : null - }, getAttributes(outNode, profile, options.attributes)); - - // omit tag name if node has primary attributes - if (options.omitName && options.omitName.test(data.NAME) && data.PRIMARY_ATTRS) { - data.NAME = null; - } - - if (options.open != null) { - outNode.open = template(options.open, data); - } - - if (options.close != null) { - outNode.close = template(options.close, data); - } - } - - return outNode; -} - -/** - * Formats attributes of given node into a string. - * @param {OutputNode} node Output node wrapper - * @param {Profile} profile Output profile - * @param {Object} options Additional formatting options - * @return {String} - */ -function getAttributes(outNode, profile, options) { - options = markup_formatters_es__extends({}, defaultAttrOptions, options); - const primary = [], - secondary = []; - const node = outNode.node; - - node.attributes.forEach(attr => { - if (attr.options.implied && attr.value == null) { - return null; - } - - const name = profile.attribute(attr.name); - const value = outNode.renderFields(attr.value); - - if (reId.test(name)) { - value && primary.push(`#${value}`); - } else if (reClass.test(name)) { - value && primary.push(`.${value.replace(/\s+/g, '.')}`); - } else { - const isBoolean = attr.value == null && (attr.options.boolean || profile.get('booleanAttributes').indexOf(name.toLowerCase()) !== -1); - - secondary.push({ name, value, isBoolean }); - } - }); - - return { - PRIMARY_ATTRS: options.primary(primary) || null, - SECONDARY_ATTRS: options.secondary(secondary) || null - }; -} - -/** - * Computes indent level for given node - * @param {Node} node - * @return {Number} - */ -function getIndentLevel$1(node) { - let level = node.parent.isTextOnly ? -2 : -1; - let ctx = node; - while (ctx = ctx.parent) { - level++; - } - - return level < 0 ? 0 : level; -} - -const reNl = /\n|\r/; - -/** - * Renders given parsed Emmet abbreviation as HAML, formatted according to - * `profile` options - * @param {Node} tree Parsed Emmet abbreviation - * @param {Profile} profile Output profile - * @param {Object} [options] Additional formatter options - * @return {String} - */ -function haml(tree, profile, options) { - options = options || {}; - const nodeOptions = { - open: '[%NAME][PRIMARY_ATTRS][(SECONDARY_ATTRS)][SELF_CLOSE]', - selfClose: '/', - attributes: { - secondary(attrs) { - return attrs.map(attr => attr.isBoolean ? `${attr.name}${profile.get('compactBooleanAttributes') ? '' : '=true'}` : `${attr.name}=${profile.quote(attr.value)}`).join(' '); - } - } - }; - - return output_renderer_es(tree, options.field, outNode => { - outNode = indentFormat(outNode, profile, nodeOptions); - outNode = updateFormatting(outNode, profile); - - if (!handlePseudoSnippet(outNode)) { - const node = outNode.node; - - // Do not generate fields for nodes with empty value and children - // or if node is self-closed - if (node.value || !node.children.length && !node.selfClosing) { - outNode.text = outNode.renderFields(formatNodeValue(node, profile)); - } - } - - return outNode; - }); -} - -/** - * Updates formatting properties for given output node - * NB Unlike HTML, HAML is indent-based format so some formatting options from - * `profile` will not take effect, otherwise output will be broken - * @param {OutputNode} outNode Output wrapper of parsed abbreviation node - * @param {Profile} profile Output profile - * @return {OutputNode} - */ -function updateFormatting(outNode, profile) { - const node = outNode.node; - - if (!node.isTextOnly && node.value) { - // node with text: put a space before single-line text - outNode.beforeText = reNl.test(node.value) ? outNode.newline + outNode.indent + profile.indent(1) : ' '; - } - - return outNode; -} -/** - * Formats value of given node: for multiline text we should add a ` |` suffix - * at the end of each line. Also ensure that text is perfectly aligned. - * @param {Node} node - * @param {Profile} profile - * @return {String|null} - */ -function formatNodeValue(node, profile) { - if (node.value != null && reNl.test(node.value)) { - const lines = markup_formatters_es_splitByLines(node.value); - const indent = profile.indent(1); - const maxLength = lines.reduce((prev, line) => Math.max(prev, line.length), 0); - - return lines.map((line, i) => `${i ? indent : ''}${pad(line, maxLength)} |`).join('\n'); - } - - return node.value; -} - -function pad(text, len) { - while (text.length < len) { - text += ' '; - } - - return text; -} - -const reNl$1 = /\n|\r/; -const secondaryAttrs = { - none: '[ SECONDARY_ATTRS]', - round: '[(SECONDARY_ATTRS)]', - curly: '[{SECONDARY_ATTRS}]', - square: '[[SECONDARY_ATTRS]' -}; - -/** - * Renders given parsed Emmet abbreviation as Slim, formatted according to - * `profile` options - * @param {Node} tree Parsed Emmet abbreviation - * @param {Profile} profile Output profile - * @param {Object} [options] Additional formatter options - * @return {String} - */ -function slim(tree, profile, options) { - options = options || {}; - const SECONDARY_ATTRS = options.attributeWrap && secondaryAttrs[options.attributeWrap] || secondaryAttrs.none; - - const booleanAttr = SECONDARY_ATTRS === secondaryAttrs.none ? attr => `${attr.name}=true` : attr => attr.name; - - const nodeOptions = { - open: `[NAME][PRIMARY_ATTRS]${SECONDARY_ATTRS}[SELF_CLOSE]`, - selfClose: '/', - attributes: { - secondary(attrs) { - return attrs.map(attr => attr.isBoolean ? booleanAttr(attr) : `${attr.name}=${profile.quote(attr.value)}`).join(' '); - } - } - }; - - return output_renderer_es(tree, options.field, outNode => { - outNode = indentFormat(outNode, profile, nodeOptions); - outNode = updateFormatting$1(outNode, profile); - - if (!handlePseudoSnippet(outNode)) { - const node = outNode.node; - - // Do not generate fields for nodes with empty value and children - // or if node is self-closed - if (node.value || !node.children.length && !node.selfClosing) { - outNode.text = outNode.renderFields(formatNodeValue$1(node, profile)); - } - } - - return outNode; - }); -} - -/** - * Updates formatting properties for given output node - * NB Unlike HTML, Slim is indent-based format so some formatting options from - * `profile` will not take effect, otherwise output will be broken - * @param {OutputNode} outNode Output wrapper of farsed abbreviation node - * @param {Profile} profile Output profile - * @return {OutputNode} - */ -function updateFormatting$1(outNode, profile) { - const node = outNode.node; - const parent = node.parent; - - // Edge case: a single inline-level child inside node without text: - // allow it to be inlined - if (profile.get('inlineBreak') === 0 && isInline$1(node, profile) && !isRoot(parent) && parent.value == null && parent.children.length === 1) { - outNode.beforeOpen = ': '; - } - - if (!node.isTextOnly && node.value) { - // node with text: put a space before single-line text - outNode.beforeText = reNl$1.test(node.value) ? outNode.newline + outNode.indent + profile.indent(1) : ' '; - } - - return outNode; -} - -/** - * Formats value of given node: for multiline text we should precede each - * line with `| ` with one-level deep indent - * @param {Node} node - * @param {Profile} profile - * @return {String|null} - */ -function formatNodeValue$1(node, profile) { - if (node.value != null && reNl$1.test(node.value)) { - const indent = profile.indent(1); - return markup_formatters_es_splitByLines(node.value).map((line, i) => `${indent}${i ? ' ' : '|'} ${line}`).join('\n'); - } - - return node.value; -} - -/** - * Check if given node is inline-level - * @param {Node} node - * @param {Profile} profile - * @return {Boolean} - */ -function isInline$1(node, profile) { - return node && (node.isTextOnly || profile.isInline(node)); -} - -const reNl$2 = /\n|\r/; - -/** - * Renders given parsed Emmet abbreviation as Pug, formatted according to - * `profile` options - * @param {Node} tree Parsed Emmet abbreviation - * @param {Profile} profile Output profile - * @param {Object} [options] Additional formatter options - * @return {String} - */ -function pug(tree, profile, options) { - options = options || {}; - const nodeOptions = { - open: '[NAME][PRIMARY_ATTRS][(SECONDARY_ATTRS)]', - attributes: { - secondary(attrs) { - return attrs.map(attr => attr.isBoolean ? attr.name : `${attr.name}=${profile.quote(attr.value)}`).join(', '); - } - } - }; - - return output_renderer_es(tree, options.field, outNode => { - outNode = indentFormat(outNode, profile, nodeOptions); - outNode = updateFormatting$2(outNode, profile); - - if (!handlePseudoSnippet(outNode)) { - const node = outNode.node; - // Do not generate fields for nodes with empty value and children - // or if node is self-closed - if (node.value || !node.children.length && !node.selfClosing) { - outNode.text = outNode.renderFields(formatNodeValue$2(node, profile)); - } - } - - return outNode; - }); -} - -/** - * Updates formatting properties for given output node - * NB Unlike HTML, Pug is indent-based format so some formatting options from - * `profile` will not take effect, otherwise output will be broken - * @param {OutputNode} outNode Output wrapper of parsed abbreviation node - * @param {Profile} profile Output profile - * @return {OutputNode} - */ -function updateFormatting$2(outNode, profile) { - const node = outNode.node; - - if (!node.isTextOnly && node.value) { - // node with text: put a space before single-line text - outNode.beforeText = reNl$2.test(node.value) ? outNode.newline + outNode.indent + profile.indent(1) : ' '; - } - - return outNode; -} - -/** - * Formats value of given node: for multiline text we should precede each - * line with `| ` with one-level deep indent - * @param {Node} node - * @param {Profile} profile - * @return {String|null} - */ -function formatNodeValue$2(node, profile) { - if (node.value != null && reNl$2.test(node.value)) { - const indent = profile.indent(1); - return markup_formatters_es_splitByLines(node.value).map(line => `${indent}| ${line}`).join('\n'); - } - - return node.value; -} - -const supportedSyntaxes = { html, haml, slim, pug }; - -/** - * Outputs given parsed abbreviation in specified syntax - * @param {Node} tree Parsed abbreviation tree - * @param {Profile} profile Output profile - * @param {String} [syntax] Output syntax. If not given, `html` syntax is used - * @param {Function} options.field A function to output field/tabstop for - * host editor. This function takes two arguments: `index` and `placeholder` and - * should return a string that represents tabstop in host editor. By default - * only a placeholder is returned - * @example - * { - * field(index, placeholder) { - * // return field in TextMate-style, e.g. ${1} or ${2:foo} - * return `\${${index}${placeholder ? ':' + placeholder : ''}}`; - * } - * } - * @return {String} - */ -function markup_formatters_es_index(tree, profile, syntax, options) { - if (typeof syntax === 'object') { - options = syntax; - syntax = null; - } - - if (!supports(syntax)) { - // fallback to HTML if given syntax is not supported - syntax = 'html'; - } - - return supportedSyntaxes[syntax](tree, profile, options); -} - -/** - * Check if given syntax is supported - * @param {String} syntax - * @return {Boolean} - */ -function supports(syntax) { - return !!syntax && syntax in supportedSyntaxes; -} - -/* harmony default export */ var markup_formatters_es = (markup_formatters_es_index); - -//# sourceMappingURL=markup-formatters.es.js.map -// CONCATENATED MODULE: ../node_modules/@emmetio/css-abbreviation/dist/css-abbreviation.es.js - - - - -/** - * A wrapper for holding CSS value - */ -let CSSValue = class CSSValue { - constructor() { - this.type = 'css-value'; - this.value = []; - } - - get size() { - return this.value.length; - } - - add(value) { - this.value.push(value); - } - - has(value) { - return this.value.indexOf(value) !== -1; - } - - toString() { - return this.value.join(' '); - } -}; - - -const css_abbreviation_es_HASH = 35; // # -const css_abbreviation_es_DOT = 46; // . - -/** - * Consumes a color token from given string - * @param {StreamReader} stream - * @return {Color} Returns consumend color object, `undefined` otherwise - */ -function consumeColor(stream) { - // supported color variations: - // #abc → #aabbccc - // #0 → #000000 - // #fff.5 → rgba(255, 255, 255, 0.5) - // #t → transparent - if (stream.peek() === css_abbreviation_es_HASH) { - stream.start = stream.pos; - stream.next(); - - stream.eat(116) /* t */ || stream.eatWhile(isHex); - const base = stream.current(); - - // a hex color can be followed by `.num` alpha value - stream.start = stream.pos; - if (stream.eat(css_abbreviation_es_DOT) && !stream.eatWhile(isNumber)) { - throw stream.error('Unexpected character for alpha value of color'); - } - - return new Color(base, stream.current()); - } -} - -let Color = class Color { - constructor(value, alpha) { - this.type = 'color'; - this.raw = value; - this.alpha = Number(alpha != null && alpha !== '' ? alpha : 1); - value = value.slice(1); // remove # - - let r = 0, - g = 0, - b = 0; - - if (value === 't') { - this.alpha = 0; - } else { - switch (value.length) { - case 0: - break; - - case 1: - r = g = b = value + value; - break; - - case 2: - r = g = b = value; - break; - - case 3: - r = value[0] + value[0]; - g = value[1] + value[1]; - b = value[2] + value[2]; - break; - - default: - value += value; - r = value.slice(0, 2); - g = value.slice(2, 4); - b = value.slice(4, 6); - } - } - - this.r = parseInt(r, 16); - this.g = parseInt(g, 16); - this.b = parseInt(b, 16); - } - - /** - * Output current color as hex value - * @param {Boolean} shor Produce short value (e.g. #fff instead of #ffffff), if possible - * @return {String} - */ - toHex(short) { - const fn = short && isShortHex(this.r) && isShortHex(this.g) && isShortHex(this.b) ? toShortHex : toHex; - - return '#' + fn(this.r) + fn(this.g) + fn(this.b); - } - - /** - * Output current color as `rgba?(...)` CSS color - * @return {String} - */ - toRGB() { - const values = [this.r, this.g, this.b]; - if (this.alpha !== 1) { - values.push(this.alpha.toFixed(8).replace(/\.?0+$/, '')); - } - - return `${values.length === 3 ? 'rgb' : 'rgba'}(${values.join(', ')})`; - } - - toString(short) { - if (!this.r && !this.g && !this.b && !this.alpha) { - return 'transparent'; - } - return this.alpha === 1 ? this.toHex(short) : this.toRGB(); - } -}; - -/** - * Check if given code is a hex value (/0-9a-f/) - * @param {Number} code - * @return {Boolean} - */ - -function isHex(code) { - return isNumber(code) || isAlpha(code, 65, 70); // A-F -} - -function isShortHex(hex) { - return !(hex % 17); -} - -function toShortHex(num) { - return (num >> 4).toString(16); -} - -function toHex(num) { - return css_abbreviation_es_pad(num.toString(16), 2); -} - -function css_abbreviation_es_pad(value, len) { - while (value.length < len) { - value = '0' + value; - } - return value; -} - -/** - * @param {Number} code - * @return {Boolean} - */ -function isAlphaNumericWord(code) { - return isNumber(code) || isAlphaWord(code); -} - -/** - * @param {Number} code - * @return {Boolean} - */ -function isAlphaWord(code) { - return code === 95 /* _ */ || isAlpha(code); -} - -const PERCENT = 37; // % -const css_abbreviation_es_DOT$1 = 46; // . -const css_abbreviation_es_DASH = 45; // - - -/** - * Consumes numeric CSS value (number with optional unit) from current stream, - * if possible - * @param {StreamReader} stream - * @return {NumericValue} - */ -function consumeNumericValue(stream) { - stream.start = stream.pos; - if (eatNumber(stream)) { - const num = stream.current(); - stream.start = stream.pos; - - // eat unit, which can be a % or alpha word - stream.eat(PERCENT) || stream.eatWhile(isAlphaWord); - return new NumericValue(num, stream.current()); - } -} - -/** - * A numeric CSS value with optional unit - */ -let NumericValue = class NumericValue { - constructor(value, unit) { - this.type = 'numeric'; - this.value = Number(value); - this.unit = unit || ''; - } - - toString() { - return `${this.value}${this.unit}`; - } -}; - -/** - * Eats number value from given stream - * @param {StreamReader} stream - * @return {Boolean} Returns `true` if number was consumed - */ - -function eatNumber(stream) { - const start = stream.pos; - const negative = stream.eat(css_abbreviation_es_DASH); - const afterNegative = stream.pos; - - stream.eatWhile(isNumber); - - const prevPos = stream.pos; - if (stream.eat(css_abbreviation_es_DOT$1) && !stream.eatWhile(isNumber)) { - // Number followed by a dot, but then no number - stream.pos = prevPos; - } - - // Edge case: consumed dash only: not a number, bail-out - if (stream.pos === afterNegative) { - stream.pos = start; - } - - return stream.pos !== start; -} - -const css_abbreviation_es_DOLLAR = 36; // $ -const DASH$1 = 45; // - -const AT = 64; // @ - -/** - * Consumes a keyword: either a variable (a word that starts with $ or @) or CSS - * keyword or shorthand - * @param {StreamReader} stream - * @param {Boolean} [short] Use short notation for consuming value. - * The difference between “short” and “full” notation is that first one uses - * alpha characters only and used for extracting keywords from abbreviation, - * while “full” notation also supports numbers and dashes - * @return {String} Consumed variable - */ -function consumeKeyword(stream, short) { - stream.start = stream.pos; - - if (stream.eat(css_abbreviation_es_DOLLAR) || stream.eat(AT)) { - // SCSS or LESS variable - stream.eatWhile(isVariableName); - } else if (short) { - stream.eatWhile(isAlphaWord); - } else { - stream.eatWhile(isKeyword); - } - - return stream.start !== stream.pos ? new Keyword(stream.current()) : null; -} - -let Keyword = class Keyword { - constructor(value) { - this.type = 'keyword'; - this.value = value; - } - - toString() { - return this.value; - } -}; - - -function isKeyword(code) { - return isAlphaNumericWord(code) || code === DASH$1; -} - -function isVariableName(code) { - return code === 45 /* - */ || isAlphaNumericWord(code); -} - -const css_abbreviation_es_opt = { throws: true }; - -/** - * Consumes 'single' or "double"-quoted string from given string, if possible - * @param {StreamReader} stream - * @return {String} - */ -function css_abbreviation_es_consumeQuoted(stream) { - if (eatQuoted(stream, css_abbreviation_es_opt)) { - return new QuotedString(stream.current()); - } -} - -let QuotedString = class QuotedString { - constructor(value) { - this.type = 'string'; - this.value = value; - } - - toString() { - return this.value; - } -}; - - -const LBRACE = 40; // ( -const RBRACE = 41; // ) -const COMMA = 44; // , - -/** - * Consumes arguments from given string. - * Arguments are comma-separated list of CSS values inside round braces, e.g. - * `(1, a2, 'a3')`. Nested lists and quoted strings are supported - * @param {StreamReader} stream - * @return {Array} Array of arguments, `null` if arguments cannot be consumed - */ -function consumeArgumentList(stream) { - if (!stream.eat(LBRACE)) { - // not an argument list - return null; - } - - let arg; - const argsList = []; - - while (!stream.eof()) { - if (arg = consumeArgument(stream)) { - argsList.push(arg); - } else { - // didn’t consumed argument, expect argument separator or end-of-arguments - stream.eatWhile(isWhiteSpace); - - if (stream.eat(RBRACE)) { - // end of arguments list - break; - } - - if (!stream.eat(COMMA)) { - throw stream.error('Expected , or )'); - } - } - } - - return argsList; -} - -/** - * Consumes a single argument. An argument is a `CSSValue`, e.g. it could be - * a space-separated string of value - * @param {StreamReader} stream - * @return {CSSValue} - */ -function consumeArgument(stream) { - const result = new CSSValue(); - let value; - - while (!stream.eof()) { - stream.eatWhile(isWhiteSpace); - value = consumeNumericValue(stream) || consumeColor(stream) || css_abbreviation_es_consumeQuoted(stream) || consumeKeywordOrFunction(stream); - - if (!value) { - break; - } - - result.add(value); - } - - return result.size ? result : null; -} - -/** - * Consumes either function call like `foo()` or keyword like `foo` - * @param {StreamReader} stream - * @return {Keyword|FunctionCall} - */ -function consumeKeywordOrFunction(stream) { - const kw = consumeKeyword(stream); - if (kw) { - const args = consumeArgumentList(stream); - return args ? new FunctionCall(kw.toString(), args) : kw; - } -} - -let FunctionCall = class FunctionCall { - /** - * @param {String} name Function name - * @param {Array} args Function arguments - */ - constructor(name, args) { - this.type = 'function'; - this.name = name; - this.args = args || []; - } - - toString() { - return `${this.name}(${this.args.join(', ')})`; - } -}; - - -const css_abbreviation_es_EXCL = 33; // ! -const DOLLAR$1 = 36; // $ -const PLUS = 43; // + -const DASH$2 = 45; // - -const css_abbreviation_es_COLON = 58; // : -const AT$1 = 64; // @ - -/** - * Parses given Emmet CSS abbreviation and returns it as parsed Node tree - * @param {String} abbr - * @return {Node} - */ -function css_abbreviation_es_index(abbr) { - const root = new node_es(); - const stream = new stream_reader_es(abbr); - - while (!stream.eof()) { - let node = new node_es(consumeIdent(stream)); - node.value = consumeValue(stream); - - const args = consumeArgumentList(stream); - if (args) { - // technically, arguments in CSS are anonymous Emmet Node attributes, - // but since Emmet can support only one anonymous, `null`-name - // attribute (for good reasons), we’ll use argument index as name - for (let i = 0; i < args.length; i++) { - node.setAttribute(String(i), args[i]); - } - } - - // Consume `!important` modifier at the end of expression - if (stream.eat(css_abbreviation_es_EXCL)) { - node.value.add('!'); - } - - root.appendChild(node); - - // CSS abbreviations cannot be nested, only listed - if (!stream.eat(PLUS)) { - break; - } - } - - if (!stream.eof()) { - throw stream.error('Unexpected character'); - } - - return root; -} - -/** - * Consumes CSS property identifier from given stream - * @param {StreamReader} stream - * @return {String} - */ -function consumeIdent(stream) { - stream.start = stream.pos; - stream.eatWhile(isIdentPrefix); - stream.eatWhile(css_abbreviation_es_isIdent); - return stream.start !== stream.pos ? stream.current() : null; -} - -/** - * Consumes embedded value from Emmet CSS abbreviation stream - * @param {StreamReader} stream - * @return {CSSValue} - */ -function consumeValue(stream) { - const values = new CSSValue(); - let value; - - while (!stream.eof()) { - // use colon as value separator - stream.eat(css_abbreviation_es_COLON); - if (value = consumeNumericValue(stream) || consumeColor(stream)) { - // edge case: a dash after unit-less numeric value or color should - // be treated as value separator, not negative sign - if (!value.unit) { - stream.eat(DASH$2); - } - } else { - stream.eat(DASH$2); - value = consumeKeyword(stream, true); - } - - if (!value) { - break; - } - - values.add(value); - } - - return values; -} - -/** - * @param {Number} code - * @return {Boolean} - */ -function css_abbreviation_es_isIdent(code) { - return isAlphaWord(code); -} - -/** - * @param {Number} code - * @return {Boolean} - */ -function isIdentPrefix(code) { - return code === AT$1 || code === DOLLAR$1 || code === css_abbreviation_es_EXCL; -} - -/* harmony default export */ var css_abbreviation_es = (css_abbreviation_es_index); -// CONCATENATED MODULE: ../node_modules/@emmetio/expand-abbreviation/node_modules/@emmetio/css-snippets-resolver/dist/css-snippets-resolver.es.js -var css_snippets_resolver_es__extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -const css_snippets_resolver_es_DASH = 45; // - - -/** - * Calculates fuzzy match score of how close `abbr` matches given `string`. - * @param {String} abbr Abbreviation to score - * @param {String} string String to match - * @param {Number} [fuzziness] Fuzzy factor - * @return {Number} Match score - */ -function stringScore(abbr, string) { - abbr = abbr.toLowerCase(); - string = string.toLowerCase(); - - if (abbr === string) { - return 1; - } - - // a string MUST start with the same character as abbreviation - if (!string || abbr.charCodeAt(0) !== string.charCodeAt(0)) { - return 0; - } - - const abbrLength = abbr.length; - const stringLength = string.length; - let i = 1, - j = 1, - score = stringLength; - let ch1, ch2, found, acronym; - - while (i < abbrLength) { - ch1 = abbr.charCodeAt(i); - found = false; - acronym = false; - - while (j < stringLength) { - ch2 = string.charCodeAt(j); - - if (ch1 === ch2) { - found = true; - score += (stringLength - j) * (acronym ? 2 : 1); - break; - } - - // add acronym bonus for exactly next match after unmatched `-` - acronym = ch2 === css_snippets_resolver_es_DASH; - j++; - } - - if (!found) { - break; - } - - i++; - } - - return score && score * (i / abbrLength) / sum(stringLength); -} - -/** - * Calculates sum of first `n` natural numbers, e.g. 1+2+3+...n - * @param {Number} n - * @return {Number} - */ -function sum(n) { - return n * (n + 1) / 2; -} - -const reProperty = /^([a-z-]+)(?:\s*:\s*([^\n\r]+))?$/; -const css_snippets_resolver_es_DASH$1 = 45; // - - -/** - * Creates a special structure for resolving CSS properties from plain CSS - * snippets. - * Almost all CSS snippets are aliases for real CSS properties with available - * value variants, optionally separated by `|`. Most values are keywords that - * can be fuzzy-resolved as well. Some CSS properties are shorthands for other, - * more specific properties, like `border` and `border-style`. For such cases - * keywords from more specific properties should be available in shorthands too. - * @param {Snippet[]} snippets - * @return {CSSSnippet[]} - */ -function cssSnippets(snippets) { - return nest(snippets.map(snippet => new CSSSnippet(snippet.key, snippet.value))); -} - -let CSSSnippet = class CSSSnippet { - constructor(key, value) { - this.key = key; - this.value = value; - this.property = null; - - // detect if given snippet is a property - const m = value && value.match(reProperty); - if (m) { - this.property = m[1]; - this.value = m[2]; - } - - this.dependencies = []; - } - - addDependency(dep) { - this.dependencies.push(dep); - } - - get defaultValue() { - return this.value != null ? splitValue(this.value)[0] : null; - } - - /** - * Returns list of unique keywords for current CSS snippet and its dependencies - * @return {String[]} - */ - keywords() { - const stack = []; - const keywords = new Set(); - let i = 0, - item, - candidates; - - if (this.property) { - // scan valid CSS-properties only - stack.push(this); - } - - while (i < stack.length) { - // NB Keep items in stack instead of push/pop to avoid possible - // circular references - item = stack[i++]; - - if (item.value) { - candidates = splitValue(item.value).filter(css_snippets_resolver_es_isKeyword); - - // extract possible keywords from snippet value - for (let j = 0; j < candidates.length; j++) { - keywords.add(candidates[j].trim()); - } - - // add dependencies into scan stack - for (let j = 0, deps = item.dependencies; j < deps.length; j++) { - if (stack.indexOf(deps[j]) === -1) { - stack.push(deps[j]); - } - } - } - } - - return Array.from(keywords); - } -}; - -/** - * Nests more specific CSS properties into shorthand ones, e.g. - * background-position-x -> background-position -> background - * @param {CSSSnippet[]} snippets - * @return {CSSSnippet[]} - */ - -function nest(snippets) { - snippets = snippets.sort(snippetsSort); - const stack = []; - - // For sorted list of CSS properties, create dependency graph where each - // shorthand property contains its more specific one, e.g. - // background -> background-position -> background-position-x - for (let i = 0, cur, prev; i < snippets.length; i++) { - cur = snippets[i]; - - if (!cur.property) { - // not a CSS property, skip it - continue; - } - - // Check if current property belongs to one from parent stack. - // Since `snippets` array is sorted, items are perfectly aligned - // from shorthands to more specific variants - while (stack.length) { - prev = stack[stack.length - 1]; - - if (cur.property.indexOf(prev.property) === 0 && cur.property.charCodeAt(prev.property.length) === css_snippets_resolver_es_DASH$1) { - prev.addDependency(cur); - stack.push(cur); - break; - } - - stack.pop(); - } - - if (!stack.length) { - stack.push(cur); - } - } - - return snippets; -} - -/** - * A sorting function for array of snippets - * @param {CSSSnippet} a - * @param {CSSSnippet} b - * @return {Number} - */ -function snippetsSort(a, b) { - if (a.key === b.key) { - return 0; - } - - return a.key < b.key ? -1 : 1; -} - -/** - * Check if given string is a keyword candidate - * @param {String} str - * @return {Boolean} - */ -function css_snippets_resolver_es_isKeyword(str) { - return (/^\s*[\w-]+/.test(str) - ); -} - -function splitValue(value) { - return String(value).split('|'); -} - -const globalKeywords = ['auto', 'inherit', 'unset']; -const unitlessProperties = ['z-index', 'line-height', 'opacity', 'font-weight', 'zoom', 'flex', 'flex-grow', 'flex-shrink']; - -const css_snippets_resolver_es_defaultOptions = { - intUnit: 'px', - floatUnit: 'em', - unitAliases: { - e: 'em', - p: '%', - x: 'ex', - r: 'rem' - }, - fuzzySearchMinScore: 0 -}; - -/** - * For every node in given `tree`, finds matching snippet from `registry` and - * updates node with snippet data. - * - * This resolver uses fuzzy matching for searching matched snippets and their - * keyword values. - */ - -function css_snippets_resolver_es_index(tree, registry, options) { - options = css_snippets_resolver_es__extends({}, css_snippets_resolver_es_defaultOptions, options); - options.unitAliases = css_snippets_resolver_es__extends({}, css_snippets_resolver_es_defaultOptions.unitAliases, options && options.unitAliases); - - const snippets = convertToCSSSnippets(registry); - - tree.walk(node => css_snippets_resolver_es_resolveNode(node, snippets, options)); - return tree; -} - -function convertToCSSSnippets(registry) { - return cssSnippets(registry.all({ type: 'string' })); -} - -/** - * Resolves given node: finds matched CSS snippets using fuzzy match and resolves - * keyword aliases from node value - * @param {Node} node - * @param {CSSSnippet[]} snippets - * @param {Object} options - * @return {Node} - */ -function css_snippets_resolver_es_resolveNode(node, snippets, options) { - if (options.property) { - // Resolve as value of given CSS property - return resolveAsPropertyValue(node, snippets.find(snippet => snippet.property === options.property), options); - } - - const snippet = findBestMatch(node.name, snippets, 'key', options.fuzzySearchMinScore); - - if (!snippet) { - // Edge case: `!important` snippet - return node.name === '!' ? setNodeAsText(node, '!important') : node; - } - - return snippet.property ? resolveAsProperty(node, snippet, options) : resolveAsSnippet(node, snippet); -} - -/** - * Resolves given parsed abbreviation node as CSS property - * @param {Node} node - * @param {CSSSnippet} snippet - * @param {Object} formatOptions - * @return {Node} - */ -function resolveAsProperty(node, snippet, formatOptions) { - const abbr = node.name; - node.name = snippet.property; - - if (node.value && typeof node.value === 'object') { - // resolve keyword shortcuts - const keywords = snippet.keywords(); - - if (!node.value.size) { - // no value defined, try to resolve unmatched part as a keyword alias - let kw = findBestMatch(getUnmatchedPart(abbr, snippet.key), keywords); - - if (!kw) { - // no matching value, try to get default one - kw = snippet.defaultValue; - if (kw && kw.indexOf('${') === -1) { - // Quick and dirty test for existing field. If not, wrap - // default value in a field - kw = `\${1:${kw}}`; - } - } - - if (kw) { - node.value.add(kw); - } - } else { - // replace keyword aliases in current node value - for (let i = 0, token; i < node.value.value.length; i++) { - token = node.value.value[i]; - - if (token === '!') { - token = `${!i ? '${1} ' : ''}!important`; - } else if (isKeyword$1(token)) { - token = findBestMatch(token.value, keywords) || findBestMatch(token.value, globalKeywords) || token; - } else if (isNumericValue(token)) { - token = resolveNumericValue(node.name, token, formatOptions); - } - - node.value.value[i] = token; - } - } - } - - return node; -} - -/** - * Resolves given parsed abbreviation node as a snippet: a plain code chunk - * @param {Node} node - * @param {CSSSnippet} snippet - * @return {Node} - */ -function resolveAsSnippet(node, snippet) { - return setNodeAsText(node, snippet.value); -} - -/** - * Resolves given parsed abbreviation node as property value of given `snippet`: - * tries to find best matching keyword from CSS snippet - * @param {Node} node - * @param {CSSSnippet} snippet - * @param {Object} options - * @return {Node} - */ -function resolveAsPropertyValue(node, snippet, options) { - // Possible resolved result for CSS property: - // * matched snippet keyword - // * color (starts with #) - // Everything else should result the same as input abbreviation - let keywords = globalKeywords.slice(); - if (snippet) { - keywords = keywords.concat(snippet.keywords()); - } - - const values = [node.name].concat(node.value.value).filter(Boolean).map(value => { - if (typeof value === 'string' || value.type === 'keyword') { - value = String(value); - return findBestMatch(value, keywords, null, options.fuzzySearchMinScore) || value; - } - - return value; - }); - - node.name = null; - node.value.value = values; - - return node; -} - -/** - * Sets given parsed abbreviation node as a text snippet - * @param {Node} node - * @param {String} text - * @return {Node} - */ -function setNodeAsText(node, text) { - node.name = null; - node.value = text; - return node; -} - -/** - * Finds best matching item from `items` array - * @param {String} abbr Abbreviation to match - * @param {Array} items List of items for match - * @param {String} [key] If `items` is a list of objects, use `key` as object - * property to test against - * @param {Number} fuzzySearchMinScore The minimum score the best matched item should have to be a valid match. - * @return {*} - */ -function findBestMatch(abbr, items, key, fuzzySearchMinScore) { - if (!abbr) { - return null; - } - - let matchedItem = null; - let maxScore = 0; - fuzzySearchMinScore = fuzzySearchMinScore || 0; - - for (let i = 0, item; i < items.length; i++) { - item = items[i]; - const score = stringScore(abbr, getScoringPart(item, key)); - - if (score === 1) { - // direct hit, no need to look further - return item; - } - - if (score && score >= maxScore) { - maxScore = score; - matchedItem = item; - } - } - - return maxScore >= fuzzySearchMinScore ? matchedItem : null; -} - -function getScoringPart(item, key) { - const value = item && typeof item === 'object' ? item[key] : item; - const m = (value || '').match(/^[\w-@]+/); - return m ? m[0] : value; -} - -/** - * Returns a part of `abbr` that wasn’t directly matched agains `string`. - * For example, if abbreviation `poas` is matched against `position`, the unmatched part will be `as` - * since `a` wasn’t found in string stream - * @param {String} abbr - * @param {String} string - * @return {String} - */ -function getUnmatchedPart(abbr, string) { - for (let i = 0, lastPos = 0; i < abbr.length; i++) { - lastPos = string.indexOf(abbr[i], lastPos); - if (lastPos === -1) { - return abbr.slice(i); - } - lastPos++; - } - - return ''; -} - -/** - * Check if given CSS value token is a keyword - * @param {*} token - * @return {Boolean} - */ -function isKeyword$1(token) { - return tokenTypeOf(token, 'keyword'); -} - -/** - * Check if given CSS value token is a numeric value - * @param {*} token - * @return {Boolean} - */ -function isNumericValue(token) { - return tokenTypeOf(token, 'numeric'); -} - -function tokenTypeOf(token, type) { - return token && typeof token === 'object' && token.type === type; -} - -/** - * Resolves numeric value for given CSS property - * @param {String} property CSS property name - * @param {NumericValue} token CSS numeric value token - * @param {Object} formatOptions Formatting options for units - * @return {NumericValue} - */ -function resolveNumericValue(property, token, formatOptions) { - if (token.unit) { - token.unit = formatOptions.unitAliases[token.unit] || token.unit; - } else if (token.value !== 0 && unitlessProperties.indexOf(property) === -1) { - // use `px` for integers, `em` for floats - // NB: num|0 is a quick alternative to Math.round(0) - token.unit = token.value === (token.value | 0) ? formatOptions.intUnit : formatOptions.floatUnit; - } - - return token; -} - -/* harmony default export */ var css_snippets_resolver_es = (css_snippets_resolver_es_index); - -//# sourceMappingURL=css-snippets-resolver.es.js.map -// CONCATENATED MODULE: ../node_modules/@emmetio/stylesheet-formatters/dist/stylesheet-formatters.es.js -var stylesheet_formatters_es__extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - - - - -const defaultFormatOptions = { - shortHex: true, - between: ': ', - after: ';' -}; - -/** - * Renders given parsed Emmet CSS abbreviation as CSS-like - * stylesheet, formatted according to `profile` options - * @param {Node} tree Parsed Emmet abbreviation - * @param {Profile} profile Output profile - * @param {Object} [options] Additional formatter options - * @return {String} - */ -function css(tree, profile, options) { - options = options || {}; - const formatOpt = stylesheet_formatters_es__extends({}, defaultFormatOptions, options && options.format); - - return output_renderer_es(tree, options.field, outNode => { - const node = outNode.node; - let value = stringifyValue(node, formatOpt); - - if (node.attributes.length) { - const fieldValues = node.attributes.map(attr => stringifyValue(attr, formatOpt)); - value = injectFields(value, fieldValues); - } - - outNode.open = node.name && profile.name(node.name); - outNode.afterOpen = formatOpt.between; - outNode.text = outNode.renderFields(value || null); - - if (outNode.open && (!outNode.text || !outNode.text.endsWith(';'))) { - outNode.afterText = formatOpt.after; - } - - if (profile.get('format')) { - outNode.newline = '\n'; - if (tree.lastChild !== node) { - outNode.afterText += outNode.newline; - } - } - - return outNode; - }); -} - -/** - * Injects given field values at each field of given string - * @param {String} string - * @param {String[]} attributes - * @return {FieldString} - */ -function injectFields(string, values) { - const fieldsModel = field_parser_es(string); - const fieldsAmount = fieldsModel.fields.length; - - if (fieldsAmount) { - values = values.slice(); - if (values.length > fieldsAmount) { - // More values that output fields: collapse rest values into - // a single token - values = values.slice(0, fieldsAmount - 1).concat(values.slice(fieldsAmount - 1).join(', ')); - } - - while (values.length) { - const value = values.shift(); - const field = fieldsModel.fields.shift(); - const delta = value.length - field.length; - - fieldsModel.string = fieldsModel.string.slice(0, field.location) + value + fieldsModel.string.slice(field.location + field.length); - - // Update location of the rest fields in string - for (let i = 0, il = fieldsModel.fields.length; i < il; i++) { - fieldsModel.fields[i].location += delta; - } - } - } - - return fieldsModel; -} - -function stringifyValue(node, options) { - if (node.value && typeof node.value === 'object' && node.value.type === 'css-value') { - return node.value.value.map(token => { - if (token && typeof token === 'object') { - return token.type === 'color' ? token.toString(options.shortHex) : token.toString(); - } - - return String(token); - }).join(' '); - } - - return node.value != null ? String(node.value) : ''; -} - -const syntaxFormat = { - css: { - between: ': ', - after: ';' - }, - scss: 'css', - less: 'css', - sass: { - between: ': ', - after: '' - }, - stylus: { - between: ' ', - after: '' - } -}; - -/** - * Outputs given parsed abbreviation in specified stylesheet syntax - * @param {Node} tree Parsed abbreviation tree - * @param {Profile} profile Output profile - * @param {String} [syntax] Output syntax. If not given, `css` syntax is used - * @param {Function} options.field A function to output field/tabstop for - * host editor. This function takes two arguments: `index` and `placeholder` and - * should return a string that represents tabstop in host editor. By default - * only a placeholder is returned - * @example - * { - * field(index, placeholder) { - * // return field in TextMate-style, e.g. ${1} or ${2:foo} - * return `\${${index}${placeholder ? ':' + placeholder : ''}}`; - * } - * } - * @return {String} - */ -function stylesheet_formatters_es_index(tree, profile, syntax, options) { - if (typeof syntax === 'object') { - options = syntax; - syntax = null; - } - - if (!stylesheet_formatters_es_supports(syntax)) { - // fallback to CSS if given syntax is not supported - syntax = 'css'; - } - - options = stylesheet_formatters_es__extends({}, options, { - format: getFormat(syntax, options) - }); - - // CSS abbreviations doesn’t support nesting so simply - // output root node children - return css(tree, profile, options); -} - -/** - * Check if given syntax is supported - * @param {String} syntax - * @return {Boolean} - */ -function stylesheet_formatters_es_supports(syntax) { - return !!syntax && syntax in syntaxFormat; -} - -/** - * Returns formatter object for given syntax - * @param {String} syntax - * @param {Object} [options] - * @return {Object} Formatter object as defined in `syntaxFormat` - */ -function getFormat(syntax, options) { - let format = syntaxFormat[syntax]; - if (typeof format === 'string') { - format = syntaxFormat[format]; - } - - return stylesheet_formatters_es__extends({}, format, options && options.format); -} - -/* harmony default export */ var stylesheet_formatters_es = (stylesheet_formatters_es_index); - -//# sourceMappingURL=stylesheet-formatters.es.js.map -// CONCATENATED MODULE: ../node_modules/@emmetio/snippets/dist/snippets.es.js -var snippets_es_html = { - "a": "a[href]", - "a:link": "a[href='http://${0}']", - "a:mail": "a[href='mailto:${0}']", - "a:tel": "a[href='tel:+${0}']", - "abbr": "abbr[title]", - "acr|acronym": "acronym[title]", - "base": "base[href]/", - "basefont": "basefont/", - "br": "br/", - "frame": "frame/", - "hr": "hr/", - "bdo": "bdo[dir]", - "bdo:r": "bdo[dir=rtl]", - "bdo:l": "bdo[dir=ltr]", - "col": "col/", - "link": "link[rel=stylesheet href]/", - "link:css": "link[href='${1:style}.css']", - "link:print": "link[href='${1:print}.css' media=print]", - "link:favicon": "link[rel='shortcut icon' type=image/x-icon href='${1:favicon.ico}']", - "link:touch": "link[rel=apple-touch-icon href='${1:favicon.png}']", - "link:rss": "link[rel=alternate type=application/rss+xml title=RSS href='${1:rss.xml}']", - "link:atom": "link[rel=alternate type=application/atom+xml title=Atom href='${1:atom.xml}']", - "link:im|link:import": "link[rel=import href='${1:component}.html']", - "meta": "meta/", - "meta:utf": "meta[http-equiv=Content-Type content='text/html;charset=UTF-8']", - "meta:vp": "meta[name=viewport content='width=${1:device-width}, initial-scale=${2:1.0}']", - "meta:compat": "meta[http-equiv=X-UA-Compatible content='${1:IE=7}']", - "meta:edge": "meta:compat[content='${1:ie=edge}']", - "meta:redirect": "meta[http-equiv=refresh content='0; url=${1:http://example.com}']", - "style": "style", - "script": "script[!src]", - "script:src": "script[src]", - "img": "img[src alt]/", - "img:s|img:srcset": "img[srcset src alt]", - "img:z|img:sizes": "img[sizes srcset src alt]", - "picture": "picture", - "src|source": "source/", - "src:sc|source:src": "source[src type]", - "src:s|source:srcset": "source[srcset]", - "src:t|source:type": "source[srcset type='${1:image/}']", - "src:z|source:sizes": "source[sizes srcset]", - "src:m|source:media": "source[media='(${1:min-width: })' srcset]", - "src:mt|source:media:type": "source:media[type='${2:image/}']", - "src:mz|source:media:sizes": "source:media[sizes srcset]", - "src:zt|source:sizes:type": "source[sizes srcset type='${1:image/}']", - "iframe": "iframe[src frameborder=0]", - "embed": "embed[src type]/", - "object": "object[data type]", - "param": "param[name value]/", - "map": "map[name]", - "area": "area[shape coords href alt]/", - "area:d": "area[shape=default]", - "area:c": "area[shape=circle]", - "area:r": "area[shape=rect]", - "area:p": "area[shape=poly]", - "form": "form[action]", - "form:get": "form[method=get]", - "form:post": "form[method=post]", - "label": "label[for]", - "input": "input[type=${1:text}]/", - "inp": "input[name=${1} id=${1}]", - "input:h|input:hidden": "input[type=hidden name]", - "input:t|input:text": "inp[type=text]", - "input:search": "inp[type=search]", - "input:email": "inp[type=email]", - "input:url": "inp[type=url]", - "input:p|input:password": "inp[type=password]", - "input:datetime": "inp[type=datetime]", - "input:date": "inp[type=date]", - "input:datetime-local": "inp[type=datetime-local]", - "input:month": "inp[type=month]", - "input:week": "inp[type=week]", - "input:time": "inp[type=time]", - "input:tel": "inp[type=tel]", - "input:number": "inp[type=number]", - "input:color": "inp[type=color]", - "input:c|input:checkbox": "inp[type=checkbox]", - "input:r|input:radio": "inp[type=radio]", - "input:range": "inp[type=range]", - "input:f|input:file": "inp[type=file]", - "input:s|input:submit": "input[type=submit value]", - "input:i|input:image": "input[type=image src alt]", - "input:b|input:button": "input[type=button value]", - "input:reset": "input:button[type=reset]", - "isindex": "isindex/", - "select": "select[name=${1} id=${1}]", - "select:d|select:disabled": "select[disabled.]", - "opt|option": "option[value]", - "textarea": "textarea[name=${1} id=${1} cols=${2:30} rows=${3:10}]", - "marquee": "marquee[behavior direction]", - "menu:c|menu:context": "menu[type=context]", - "menu:t|menu:toolbar": "menu[type=toolbar]", - "video": "video[src]", - "audio": "audio[src]", - "html:xml": "html[xmlns=http://www.w3.org/1999/xhtml]", - "keygen": "keygen/", - "command": "command/", - "btn:s|button:s|button:submit": "button[type=submit]", - "btn:r|button:r|button:reset": "button[type=reset]", - "btn:d|button:d|button:disabled": "button[disabled.]", - "fst:d|fset:d|fieldset:d|fieldset:disabled": "fieldset[disabled.]", - - "bq": "blockquote", - "fig": "figure", - "figc": "figcaption", - "pic": "picture", - "ifr": "iframe", - "emb": "embed", - "obj": "object", - "cap": "caption", - "colg": "colgroup", - "fst": "fieldset", - "btn": "button", - "optg": "optgroup", - "tarea": "textarea", - "leg": "legend", - "sect": "section", - "art": "article", - "hdr": "header", - "ftr": "footer", - "adr": "address", - "dlg": "dialog", - "str": "strong", - "prog": "progress", - "mn": "main", - "tem": "template", - "fset": "fieldset", - "datag": "datagrid", - "datal": "datalist", - "kg": "keygen", - "out": "output", - "det": "details", - "cmd": "command", - - "ri:d|ri:dpr": "img:s", - "ri:v|ri:viewport": "img:z", - "ri:a|ri:art": "pic>src:m+img", - "ri:t|ri:type": "pic>src:t+img", - - "!!!": "{}", - "doc": "html[lang=${lang}]>(head>meta[charset=${charset}]+meta:vp+meta:edge+title{${1:Document}})+body", - "!|html:5": "!!!+doc", - - "c": "{}", - "cc:ie": "{}", - "cc:noie": "{${0}}" -}; - -var snippets_es_css = { - "@f": "@font-face {\n\tfont-family: ${1};\n\tsrc: url(${1});\n}", - "@ff": "@font-face {\n\tfont-family: '${1:FontName}';\n\tsrc: url('${2:FileName}.eot');\n\tsrc: url('${2:FileName}.eot?#iefix') format('embedded-opentype'),\n\t\t url('${2:FileName}.woff') format('woff'),\n\t\t url('${2:FileName}.ttf') format('truetype'),\n\t\t url('${2:FileName}.svg#${1:FontName}') format('svg');\n\tfont-style: ${3:normal};\n\tfont-weight: ${4:normal};\n}", - "@i|@import": "@import url(${0});", - "@kf": "@keyframes ${1:identifier} {\n\t${2}\n}", - "@m|@media": "@media ${1:screen} {\n\t${0}\n}", - "ac": "align-content:flex-start|flex-end|center|space-between|space-around|stretch", - "ai": "align-items:flex-start|flex-end|center|baseline|stretch", - "anim": "animation:${1:name} ${2:duration} ${3:timing-function} ${4:delay} ${5:iteration-count} ${6:direction} ${7:fill-mode}", - "animdel": "animation-delay:${1:time}", - "animdir": "animation-direction:normal|reverse|alternate|alternate-reverse", - "animdur": "animation-duration:${1:0}s", - "animfm": "animation-fill-mode:both|forwards|backwards", - "animic": "animation-iteration-count:1|infinite", - "animn": "animation-name", - "animps": "animation-play-state:running|paused", - "animtf": "animation-timing-function:linear|ease|ease-in|ease-out|ease-in-out|cubic-bezier(${1:0.1}, ${2:0.7}, ${3:1.0}, ${3:0.1})", - "ap": "appearance:none", - "as": "align-self:auto|flex-start|flex-end|center|baseline|stretch", - "b": "bottom", - "bd": "border:${1:1px} ${2:solid} ${3:#000}", - "bdb": "border-bottom:${1:1px} ${2:solid} ${3:#000}", - "bdbc": "border-bottom-color:#${1:000}", - "bdbi": "border-bottom-image:url(${0})", - "bdbk": "border-break:close", - "bdbli": "border-bottom-left-image:url(${0})|continue", - "bdblrs": "border-bottom-left-radius", - "bdbri": "border-bottom-right-image:url(${0})|continue", - "bdbrrs": "border-bottom-right-radius", - "bdbs": "border-bottom-style", - "bdbw": "border-bottom-width", - "bdc": "border-color:#${1:000}", - "bdci": "border-corner-image:url(${0})|continue", - "bdcl": "border-collapse:collapse|separate", - "bdf": "border-fit:repeat|clip|scale|stretch|overwrite|overflow|space", - "bdi": "border-image:url(${0})", - "bdl": "border-left:${1:1px} ${2:solid} ${3:#000}", - "bdlc": "border-left-color:#${1:000}", - "bdlen": "border-length", - "bdli": "border-left-image:url(${0})", - "bdls": "border-left-style", - "bdlw": "border-left-width", - "bdr": "border-right:${1:1px} ${2:solid} ${3:#000}", - "bdrc": "border-right-color:#${1:000}", - "bdri": "border-right-image:url(${0})", - "bdrs": "border-radius", - "bdrst": "border-right-style", - "bdrw": "border-right-width", - "bds": "border-style:none|hidden|dotted|dashed|solid|double|dot-dash|dot-dot-dash|wave|groove|ridge|inset|outset", - "bdsp": "border-spacing", - "bdt": "border-top:${1:1px} ${2:solid} ${3:#000}", - "bdtc": "border-top-color:#${1:000}", - "bdti": "border-top-image:url(${0})", - "bdtli": "border-top-left-image:url(${0})|continue", - "bdtlrs": "border-top-left-radius", - "bdtri": "border-top-right-image:url(${0})|continue", - "bdtrrs": "border-top-right-radius", - "bdts": "border-top-style", - "bdtw": "border-top-width", - "bdw": "border-width", - "bfv": "backface-visibility:hidden|visible", - "bg": "background:#${1:000}", - "bga": "background-attachment:fixed|scroll", - "bgbk": "background-break:bounding-box|each-box|continuous", - "bgc": "background-color:#${1:fff}", - "bgcp": "background-clip:padding-box|border-box|content-box|no-clip", - "bgi": "background-image:url(${0})", - "bgo": "background-origin:padding-box|border-box|content-box", - "bgp": "background-position:${1:0} ${2:0}", - "bgpx": "background-position-x", - "bgpy": "background-position-y", - "bgr": "background-repeat:no-repeat|repeat-x|repeat-y|space|round", - "bgsz": "background-size:contain|cover", - "bxsh": "box-shadow:${1:inset }${2:hoff} ${3:voff} ${4:blur} #${5:000}|none", - "bxsz": "box-sizing:border-box|content-box|border-box", - "c": "color:#${1:000}", - "cl": "clear:both|left|right|none", - "cm": "/* ${0} */", - "cnt": "content:'${0}'|normal|open-quote|no-open-quote|close-quote|no-close-quote|attr(${0})|counter(${0})|counters({$0})", - "coi": "counter-increment", - "colm": "columns", - "colmc": "column-count", - "colmf": "column-fill", - "colmg": "column-gap", - "colmr": "column-rule", - "colmrc": "column-rule-color", - "colmrs": "column-rule-style", - "colmrw": "column-rule-width", - "colms": "column-span", - "colmw": "column-width", - "cor": "counter-reset", - "cp": "clip:auto|rect(${1:top} ${2:right} ${3:bottom} ${4:left})", - "cps": "caption-side:top|bottom", - "cur": "cursor:pointer|auto|default|crosshair|hand|help|move|pointer|text", - "d": "display:block|none|flex|inline-flex|inline|inline-block|list-item|run-in|compact|table|inline-table|table-caption|table-column|table-column-group|table-header-group|table-footer-group|table-row|table-row-group|table-cell|ruby|ruby-base|ruby-base-group|ruby-text|ruby-text-group", - "ec": "empty-cells:show|hide", - "f": "font:${1:1em} ${2:sans-serif}", - "fef": "font-effect:none|engrave|emboss|outline", - "fem": "font-emphasize", - "femp": "font-emphasize-position:before|after", - "fems": "font-emphasize-style:none|accent|dot|circle|disc", - "ff": "font-family:serif|sans-serif|cursive|fantasy|monospace", - "fl": "float:left|right|none", - "fs": "font-style:italic|normal|oblique", - "fsm": "font-smoothing:antialiased|subpixel-antialiased|none", - "fst": "font-stretch:normal|ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded", - "fv": "font-variant:normal|small-caps", - "fw": "font-weight:normal|bold|bolder|lighter", - "fx": "flex", - "fxb": "flex-basis:fill|max-content|min-content|fit-content|content", - "fxd": "flex-direction:row|row-reverse|column|column-reverse", - "fxf": "flex-flow", - "fxg": "flex-grow", - "fxsh": "flex-shrink", - "fxw": "flex-wrap:nowrap|wrap|wrap-reverse", - "fz": "font-size", - "fza": "font-size-adjust", - "h": "height", - "jc": "justify-content:flex-start|flex-end|center|space-between|space-around", - "l": "left", - "lg": "background-image:linear-gradient(${1})", - "lh": "line-height", - "lis": "list-style", - "lisi": "list-style-image", - "lisp": "list-style-position:inside|outside", - "list": "list-style-type:disc|circle|square|decimal|decimal-leading-zero|lower-roman|upper-roman", - "lts": "letter-spacing:normal", - "m": "margin", - "mah": "max-height", - "mar": "max-resolution", - "maw": "max-width", - "mb": "margin-bottom", - "mih": "min-height", - "mir": "min-resolution", - "miw": "min-width", - "ml": "margin-left", - "mr": "margin-right", - "mt": "margin-top", - "ol": "outline", - "olc": "outline-color:#${1:000}|invert", - "olo": "outline-offset", - "ols": "outline-style:none|dotted|dashed|solid|double|groove|ridge|inset|outset", - "olw": "outline-width|thin|medium|thick", - "op": "opacity", - "ord": "order", - "ori": "orientation:landscape|portrait", - "orp": "orphans", - "ov": "overflow:hidden|visible|hidden|scroll|auto", - "ovs": "overflow-style:scrollbar|auto|scrollbar|panner|move|marquee", - "ovx": "overflow-x:hidden|visible|hidden|scroll|auto", - "ovy": "overflow-y:hidden|visible|hidden|scroll|auto", - "p": "padding", - "pb": "padding-bottom", - "pgba": "page-break-after:auto|always|left|right", - "pgbb": "page-break-before:auto|always|left|right", - "pgbi": "page-break-inside:auto|avoid", - "pl": "padding-left", - "pos": "position:relative|absolute|relative|fixed|static", - "pr": "padding-right", - "pt": "padding-top", - "q": "quotes", - "qen": "quotes:'\\201C' '\\201D' '\\2018' '\\2019'", - "qru": "quotes:'\\00AB' '\\00BB' '\\201E' '\\201C'", - "r": "right", - "rsz": "resize:none|both|horizontal|vertical", - "t": "top", - "ta": "text-align:left|center|right|justify", - "tal": "text-align-last:left|center|right", - "tbl": "table-layout:fixed", - "td": "text-decoration:none|underline|overline|line-through", - "te": "text-emphasis:none|accent|dot|circle|disc|before|after", - "th": "text-height:auto|font-size|text-size|max-size", - "ti": "text-indent", - "tj": "text-justify:auto|inter-word|inter-ideograph|inter-cluster|distribute|kashida|tibetan", - "to": "text-outline:${1:0} ${2:0} ${3:#000}", - "tov": "text-overflow:ellipsis|clip", - "tr": "text-replace", - "trf": "transform:${1}|skewX(${1:angle})|skewY(${1:angle})|scale(${1:x}, ${2:y})|scaleX(${1:x})|scaleY(${1:y})|scaleZ(${1:z})|scale3d(${1:x}, ${2:y}, ${3:z})|rotate(${1:angle})|rotateX(${1:angle})|rotateY(${1:angle})|rotateZ(${1:angle})|translate(${1:x}, ${2:y})|translateX(${1:x})|translateY(${1:y})|translateZ(${1:z})|translate3d(${1:tx}, ${2:ty}, ${3:tz})", - "trfo": "transform-origin", - "trfs": "transform-style:preserve-3d", - "trs": "transition:${1:prop} ${2:time}", - "trsde": "transition-delay:${1:time}", - "trsdu": "transition-duration:${1:time}", - "trsp": "transition-property:${1:prop}", - "trstf": "transition-timing-function:${1:fn}", - "tsh": "text-shadow:${1:hoff} ${2:voff} ${3:blur} ${4:#000}", - "tt": "text-transform:uppercase|lowercase|capitalize|none", - "tw": "text-wrap:none|normal|unrestricted|suppress", - "us": "user-select:none", - "v": "visibility:hidden|visible|collapse", - "va": "vertical-align:top|super|text-top|middle|baseline|bottom|text-bottom|sub", - "w": "width", - "whs": "white-space:nowrap|pre|pre-wrap|pre-line|normal", - "whsc": "white-space-collapse:normal|keep-all|loose|break-strict|break-all", - "wid": "widows", - "wm": "writing-mode:lr-tb|lr-tb|lr-bt|rl-tb|rl-bt|tb-rl|tb-lr|bt-lr|bt-rl", - "wob": "word-break:normal|keep-all|break-all", - "wos": "word-spacing", - "wow": "word-wrap:none|unrestricted|suppress|break-word|normal", - "z": "z-index", - "zom": "zoom:1" -}; - -var snippets_es_xsl = { - "tm|tmatch": "xsl:template[match mode]", - "tn|tname": "xsl:template[name]", - "call": "xsl:call-template[name]", - "ap": "xsl:apply-templates[select mode]", - "api": "xsl:apply-imports", - "imp": "xsl:import[href]", - "inc": "xsl:include[href]", - "ch": "xsl:choose", - "wh|xsl:when": "xsl:when[test]", - "ot": "xsl:otherwise", - "if": "xsl:if[test]", - "par": "xsl:param[name]", - "pare": "xsl:param[name select]", - "var": "xsl:variable[name]", - "vare": "xsl:variable[name select]", - "wp": "xsl:with-param[name select]", - "key": "xsl:key[name match use]", - "elem": "xsl:element[name]", - "attr": "xsl:attribute[name]", - "attrs": "xsl:attribute-set[name]", - "cp": "xsl:copy[select]", - "co": "xsl:copy-of[select]", - "val": "xsl:value-of[select]", - "for|each": "xsl:for-each[select]", - "tex": "xsl:text", - "com": "xsl:comment", - "msg": "xsl:message[terminate=no]", - "fall": "xsl:fallback", - "num": "xsl:number[value]", - "nam": "namespace-alias[stylesheet-prefix result-prefix]", - "pres": "xsl:preserve-space[elements]", - "strip": "xsl:strip-space[elements]", - "proc": "xsl:processing-instruction[name]", - "sort": "xsl:sort[select order]", - "choose": "xsl:choose>xsl:when+xsl:otherwise", - "xsl": "!!!+xsl:stylesheet[version=1.0 xmlns:xsl=http://www.w3.org/1999/XSL/Transform]>{\n|}", - "!!!": "{}" -}; - -var snippets_es_index = { html: snippets_es_html, css: snippets_es_css, xsl: snippets_es_xsl }; - -/* harmony default export */ var snippets_es = (snippets_es_index); -// CONCATENATED MODULE: ../node_modules/@emmetio/lorem/dist/lorem.es.js -var lorem_es__extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - - - -var latin = { - "common": ["lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipisicing", "elit"], - "words": ["exercitationem", "perferendis", "perspiciatis", "laborum", "eveniet", "sunt", "iure", "nam", "nobis", "eum", "cum", "officiis", "excepturi", "odio", "consectetur", "quasi", "aut", "quisquam", "vel", "eligendi", "itaque", "non", "odit", "tempore", "quaerat", "dignissimos", "facilis", "neque", "nihil", "expedita", "vitae", "vero", "ipsum", "nisi", "animi", "cumque", "pariatur", "velit", "modi", "natus", "iusto", "eaque", "sequi", "illo", "sed", "ex", "et", "voluptatibus", "tempora", "veritatis", "ratione", "assumenda", "incidunt", "nostrum", "placeat", "aliquid", "fuga", "provident", "praesentium", "rem", "necessitatibus", "suscipit", "adipisci", "quidem", "possimus", "voluptas", "debitis", "sint", "accusantium", "unde", "sapiente", "voluptate", "qui", "aspernatur", "laudantium", "soluta", "amet", "quo", "aliquam", "saepe", "culpa", "libero", "ipsa", "dicta", "reiciendis", "nesciunt", "doloribus", "autem", "impedit", "minima", "maiores", "repudiandae", "ipsam", "obcaecati", "ullam", "enim", "totam", "delectus", "ducimus", "quis", "voluptates", "dolores", "molestiae", "harum", "dolorem", "quia", "voluptatem", "molestias", "magni", "distinctio", "omnis", "illum", "dolorum", "voluptatum", "ea", "quas", "quam", "corporis", "quae", "blanditiis", "atque", "deserunt", "laboriosam", "earum", "consequuntur", "hic", "cupiditate", "quibusdam", "accusamus", "ut", "rerum", "error", "minus", "eius", "ab", "ad", "nemo", "fugit", "officia", "at", "in", "id", "quos", "reprehenderit", "numquam", "iste", "fugiat", "sit", "inventore", "beatae", "repellendus", "magnam", "recusandae", "quod", "explicabo", "doloremque", "aperiam", "consequatur", "asperiores", "commodi", "optio", "dolor", "labore", "temporibus", "repellat", "veniam", "architecto", "est", "esse", "mollitia", "nulla", "a", "similique", "eos", "alias", "dolore", "tenetur", "deleniti", "porro", "facere", "maxime", "corrupti"] -}; - -var ru = { - "common": ["далеко-далеко", "за", "словесными", "горами", "в стране", "гласных", "и согласных", "живут", "рыбные", "тексты"], - "words": ["вдали", "от всех", "они", "буквенных", "домах", "на берегу", "семантика", "большого", "языкового", "океана", "маленький", "ручеек", "даль", "журчит", "по всей", "обеспечивает", "ее", "всеми", "необходимыми", "правилами", "эта", "парадигматическая", "страна", "которой", "жаренные", "предложения", "залетают", "прямо", "рот", "даже", "всемогущая", "пунктуация", "не", "имеет", "власти", "над", "рыбными", "текстами", "ведущими", "безорфографичный", "образ", "жизни", "однажды", "одна", "маленькая", "строчка", "рыбного", "текста", "имени", "lorem", "ipsum", "решила", "выйти", "большой", "мир", "грамматики", "великий", "оксмокс", "предупреждал", "о", "злых", "запятых", "диких", "знаках", "вопроса", "коварных", "точках", "запятой", "но", "текст", "дал", "сбить", "себя", "толку", "он", "собрал", "семь", "своих", "заглавных", "букв", "подпоясал", "инициал", "за", "пояс", "пустился", "дорогу", "взобравшись", "первую", "вершину", "курсивных", "гор", "бросил", "последний", "взгляд", "назад", "силуэт", "своего", "родного", "города", "буквоград", "заголовок", "деревни", "алфавит", "подзаголовок", "своего", "переулка", "грустный", "реторический", "вопрос", "скатился", "его", "щеке", "продолжил", "свой", "путь", "дороге", "встретил", "рукопись", "она", "предупредила", "моей", "все", "переписывается", "несколько", "раз", "единственное", "что", "меня", "осталось", "это", "приставка", "возвращайся", "ты", "лучше", "свою", "безопасную", "страну", "послушавшись", "рукописи", "наш", "продолжил", "свой", "путь", "вскоре", "ему", "повстречался", "коварный", "составитель", "рекламных", "текстов", "напоивший", "языком", "речью", "заманивший", "свое", "агентство", "которое", "использовало", "снова", "снова", "своих", "проектах", "если", "переписали", "то", "живет", "там", "до", "сих", "пор"] -}; - -var sp = { - "common": ["mujer", "uno", "dolor", "más", "de", "poder", "mismo", "si"], - "words": ["ejercicio", "preferencia", "perspicacia", "laboral", "paño", "suntuoso", "molde", "namibia", "planeador", "mirar", "demás", "oficinista", "excepción", "odio", "consecuencia", "casi", "auto", "chicharra", "velo", "elixir", "ataque", "no", "odio", "temporal", "cuórum", "dignísimo", "facilismo", "letra", "nihilista", "expedición", "alma", "alveolar", "aparte", "león", "animal", "como", "paria", "belleza", "modo", "natividad", "justo", "ataque", "séquito", "pillo", "sed", "ex", "y", "voluminoso", "temporalidad", "verdades", "racional", "asunción", "incidente", "marejada", "placenta", "amanecer", "fuga", "previsor", "presentación", "lejos", "necesariamente", "sospechoso", "adiposidad", "quindío", "pócima", "voluble", "débito", "sintió", "accesorio", "falda", "sapiencia", "volutas", "queso", "permacultura", "laudo", "soluciones", "entero", "pan", "litro", "tonelada", "culpa", "libertario", "mosca", "dictado", "reincidente", "nascimiento", "dolor", "escolar", "impedimento", "mínima", "mayores", "repugnante", "dulce", "obcecado", "montaña", "enigma", "total", "deletéreo", "décima", "cábala", "fotografía", "dolores", "molesto", "olvido", "paciencia", "resiliencia", "voluntad", "molestias", "magnífico", "distinción", "ovni", "marejada", "cerro", "torre", "y", "abogada", "manantial", "corporal", "agua", "crepúsculo", "ataque", "desierto", "laboriosamente", "angustia", "afortunado", "alma", "encefalograma", "materialidad", "cosas", "o", "renuncia", "error", "menos", "conejo", "abadía", "analfabeto", "remo", "fugacidad", "oficio", "en", "almácigo", "vos", "pan", "represión", "números", "triste", "refugiado", "trote", "inventor", "corchea", "repelente", "magma", "recusado", "patrón", "explícito", "paloma", "síndrome", "inmune", "autoinmune", "comodidad", "ley", "vietnamita", "demonio", "tasmania", "repeler", "apéndice", "arquitecto", "columna", "yugo", "computador", "mula", "a", "propósito", "fantasía", "alias", "rayo", "tenedor", "deleznable", "ventana", "cara", "anemia", "corrupto"] -}; - -const langs = { latin, ru, sp }; - -const lorem_es_defaultOptions = { - wordCount: 30, - skipCommon: false, - lang: 'latin' -}; - -/** - * Replaces given parsed Emmet abbreviation node with nodes filled with - * Lorem Ipsum stub text. - * @param {Node} node - * @return {Node} - */ -var lorem_es_index = function (node, options) { - options = lorem_es__extends({}, lorem_es_defaultOptions, options); - const dict = langs[options.lang] || langs.latin; - const startWithCommon = !options.skipCommon && !isRepeating(node); - - if (!node.repeat && !lorem_es_isRoot(node.parent)) { - // non-repeating element, insert text stub as a content of parent node - // and remove current one - node.parent.value = paragraph(dict, options.wordCount, startWithCommon); - node.remove(); - } else { - // Replace named node with generated content - node.value = paragraph(dict, options.wordCount, startWithCommon); - node.name = node.parent.name ? implicit_tag_es(node.parent.name) : null; - } - - return node; -}; - -function lorem_es_isRoot(node) { - return !node.parent; -} - -/** - * Returns random integer between from and to values - * @param {Number} from - * @param {Number} to - * @returns {Number} - */ -function rand(from, to) { - return Math.floor(Math.random() * (to - from) + from); -} - -/** - * @param {Array} arr - * @param {Number} count - * @returns {Array} - */ -function sample(arr, count) { - const len = arr.length; - const iterations = Math.min(len, count); - const result = new Set(); - - while (result.size < iterations) { - result.add(arr[rand(0, len)]); - } - - return Array.from(result); -} - -function choice(val) { - return val[rand(0, val.length - 1)]; -} - -function sentence(words, end) { - if (words.length) { - words = [capitalize(words[0])].concat(words.slice(1)); - } - - return words.join(' ') + (end || choice('?!...')); // more dots than question marks -} - -function capitalize(word) { - return word[0].toUpperCase() + word.slice(1); -} - -/** - * Insert commas at randomly selected words. This function modifies values - * inside words array - * @param {Array} words - */ -function insertCommas(words) { - if (words.length < 2) { - return words; - } - - words = words.slice(); - const len = words.length; - const hasComma = /,$/; - let totalCommas = 0; - - if (len > 3 && len <= 6) { - totalCommas = rand(0, 1); - } else if (len > 6 && len <= 12) { - totalCommas = rand(0, 2); - } else { - totalCommas = rand(1, 4); - } - - for (let i = 0, pos, word; i < totalCommas; i++) { - pos = rand(0, len - 2); - if (!hasComma.test(words[pos])) { - words[pos] += ','; - } - } - - return words; -} - -/** - * Generate a paragraph of "Lorem ipsum" text - * @param {Object} dict Words dictionary (see `lang/*.json`) - * @param {Number} wordCount Words count in paragraph - * @param {Boolean} startWithCommon Should paragraph start with common - * "lorem ipsum" sentence. - * @returns {String} - */ -function paragraph(dict, wordCount, startWithCommon) { - const result = []; - let totalWords = 0; - let words; - - if (startWithCommon && dict.common) { - words = dict.common.slice(0, wordCount); - totalWords += words.length; - result.push(sentence(insertCommas(words), '.')); - } - - while (totalWords < wordCount) { - words = sample(dict.words, Math.min(rand(2, 30), wordCount - totalWords)); - totalWords += words.length; - result.push(sentence(insertCommas(words))); - } - - return result.join(' '); -} - -/** - * Check if given node is in repeating context, e.g. node itself or one of its - * parent is repeated - * @param {Node} node - * @return {Boolean} - */ -function isRepeating(node) { - while (node.parent) { - if (node.repeat && node.repeat.value && node.repeat.value > 1) { - return true; - } - - node = node.parent; - } - - return false; -} - -/* harmony default export */ var lorem_es = (lorem_es_index); -// CONCATENATED MODULE: ../node_modules/@emmetio/snippets-registry/dist/snippets-registry.es.js -let Snippet = class Snippet { - constructor(key, value) { - this.key = key; - this.value = value; - } -}; -let SnippetsStorage = class SnippetsStorage { - constructor(data) { - this._string = new Map(); - this._regexp = new Map(); - this._disabled = false; - - this.load(data); - } - - get disabled() { - return this._disabled; - } - - /** - * Disables current store. A disabled store always returns `undefined` - * on `get()` method - */ - disable() { - this._disabled = true; - } - - /** - * Enables current store. - */ - enable() { - this._disabled = false; - } - - /** - * Registers a new snippet item - * @param {String|Regexp} key - * @param {String|Function} value - */ - set(key, value) { - if (typeof key === 'string') { - key.split('|').forEach(k => this._string.set(k, new Snippet(k, value))); - } else if (key instanceof RegExp) { - this._regexp.set(key, new Snippet(key, value)); - } else { - throw new Error('Unknow snippet key: ' + key); - } - - return this; - } - - /** - * Returns a snippet matching given key. It first tries to find snippet - * exact match in a string key map, then tries to match one with regexp key - * @param {String} key - * @return {Snippet} - */ - get(key) { - if (this.disabled) { - return undefined; - } - - if (this._string.has(key)) { - return this._string.get(key); - } - - const keys = Array.from(this._regexp.keys()); - for (let i = 0, il = keys.length; i < il; i++) { - if (keys[i].test(key)) { - return this._regexp.get(keys[i]); - } - } - } - - /** - * Batch load of snippets data - * @param {Object|Map} data - */ - load(data) { - this.reset(); - if (data instanceof Map) { - data.forEach((value, key) => this.set(key, value)); - } else if (data && typeof data === 'object') { - Object.keys(data).forEach(key => this.set(key, data[key])); - } - } - - /** - * Clears all stored snippets - */ - reset() { - this._string.clear(); - this._regexp.clear(); - } - - /** - * Returns all available snippets from given store - */ - values() { - if (this.disabled) { - return []; - } - - const string = Array.from(this._string.values()); - const regexp = Array.from(this._regexp.values()); - return string.concat(regexp); - } -}; - -/** - * A snippets registry. Contains snippets, separated by store and sorted by - * priority: a store with higher priority takes precedence when resolving snippet - * for given key - */ - -let SnippetsRegistry = class SnippetsRegistry { - /** - * Creates snippets registry, filled with given `data` - * @param {Object|Array} data Registry snippets. If array is given, adds items - * from array in order of precedence, registers global snippets otherwise - */ - constructor(data) { - this._registry = []; - - if (Array.isArray(data)) { - data.forEach((snippets, level) => this.add(level, snippets)); - } else if (typeof data === 'object') { - this.add(data); - } - } - - /** - * Return store for given level - * @param {Number} level - * @return {SnippetsStorage} - */ - get(level) { - for (let i = 0; i < this._registry.length; i++) { - const item = this._registry[i]; - if (item.level === level) { - return item.store; - } - } - } - - /** - * Adds new store for given level - * @param {Number} [level] Store level (priority). Store with higher level - * takes precedence when resolving snippets - * @param {Object} [snippets] A snippets data for new store - * @return {SnipetsStorage} - */ - add(level, snippets) { - if (level != null && typeof level === 'object') { - snippets = level; - level = 0; - } - - const store = new SnippetsStorage(snippets); - - // remove previous store from same level - this.remove(level); - - this._registry.push({ level, store }); - this._registry.sort((a, b) => b.level - a.level); - - return store; - } - - /** - * Remove registry with given level or store - * @param {Number|SnippetsStorage} data Either level or snippets store - */ - remove(data) { - this._registry = this._registry.filter(item => item.level !== data && item.store !== data); - } - - /** - * Returns snippet from registry that matches given name - * @param {String} name - * @return {Snippet} - */ - resolve(name) { - for (let i = 0; i < this._registry.length; i++) { - const snippet = this._registry[i].store.get(name); - if (snippet) { - return snippet; - } - } - } - - /** - * Returns all available snippets from current registry. Snippets with the - * same key are resolved by their storage priority. - * @param {Object} options - * @param {Object} options.type Return snippets only of given type: 'string' - * or 'regexp'. Returns all snippets if not defined - * @return {Array} - */ - all(options) { - options = options || {}; - const result = new Map(); - - const fillResult = snippet => { - const type = snippet.key instanceof RegExp ? 'regexp' : 'string'; - if ((!options.type || options.type === type) && !result.has(snippet.key)) { - result.set(snippet.key, snippet); - } - }; - - this._registry.forEach(item => { - item.store.values().forEach(fillResult); - }); - - return Array.from(result.values()); - } - - /** - * Removes all stores from registry - */ - clear() { - this._registry.length = 0; - } -}; - - -/* harmony default export */ var snippets_registry_es = (SnippetsRegistry); -// CONCATENATED MODULE: ../node_modules/@emmetio/output-profile/dist/output-profile.es.js -var output_profile_es__extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -/** - * @type {EmmetOutputProfile} - */ -var output_profile_es_defaultOptions = { - indent: '\t', - tagCase: '', - attributeCase: '', - attributeQuotes: 'double', - format: true, - formatSkip: ['html'], - formatForce: ['body'], - inlineBreak: 3, - compactBooleanAttributes: false, - booleanAttributes: ['contenteditable', 'seamless', 'async', 'autofocus', 'autoplay', 'checked', 'controls', 'defer', 'disabled', 'formnovalidate', 'hidden', 'ismap', 'loop', 'multiple', 'muted', 'novalidate', 'readonly', 'required', 'reversed', 'selected', 'typemustmatch'], - selfClosingStyle: 'html', - inlineElements: ['a', 'abbr', 'acronym', 'applet', 'b', 'basefont', 'bdo', 'big', 'br', 'button', 'cite', 'code', 'del', 'dfn', 'em', 'font', 'i', 'iframe', 'img', 'input', 'ins', 'kbd', 'label', 'map', 'object', 'q', 's', 'samp', 'select', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'textarea', 'tt', 'u', 'var'] -}; - -/** - * Creates output profile for given options - */ -let Profile = class Profile { - /** - * @param {EmmetOutputProfile} options - */ - constructor(options) { - /** @type {EmmetOutputProfile} */ - this.options = output_profile_es__extends({}, output_profile_es_defaultOptions, options); - this.quoteChar = this.options.attributeQuotes === 'single' ? '\'' : '"'; - } - - /** - * Returns value of given option name - * @param {String} name - * @return {*} - */ - get(name) { - return this.options[name]; - } - - /** - * Quote given string according to profile - * @param {String} str String to quote - * @return {String} - */ - quote(str) { - return `${this.quoteChar}${str != null ? str : ''}${this.quoteChar}`; - } - - /** - * Output given tag name according to options - * @param {String} name - * @return {String} - */ - name(name) { - return strcase(name, this.options.tagCase); - } - - /** - * Outputs attribute name according to current settings - * @param {String} attr Attribute name - * @return {String} - */ - attribute(attr) { - return strcase(attr, this.options.attributeCase); - } - - /** - * Check if given attribute is boolean - * @param {Object} attr - * @return {Boolean} - */ - isBooleanAttribute(attr) { - return attr.options.boolean || this.get('booleanAttributes').indexOf((attr.name || '').toLowerCase()) !== -1; - } - - /** - * Returns a token for self-closing tag, depending on current options - * @return {String} - */ - selfClose() { - switch (this.options.selfClosingStyle) { - case 'xhtml': - return ' /'; - case 'xml': - return '/'; - default: - return ''; - } - } - - /** - * Returns indent for given level - * @param {Number} level Indentation level - * @return {String} - */ - indent(level) { - level = level || 0; - let output = ''; - while (level--) { - output += this.options.indent; - } - - return output; - } - - /** - * Check if given tag name belongs to inline-level element - * @param {Object|String} node Parsed node or tag name - * @return {Boolean} - */ - isInline(node) { - if (typeof node === 'string') { - return this.get('inlineElements').indexOf(node.toLowerCase()) !== -1; - } - - // inline node is a node either with inline-level name or text-only node - return node.name != null ? this.isInline(node.name) : node.isTextOnly; - } - - /** - * Outputs formatted field for given params - * @param {Number} index Field index - * @param {String} [placeholder] Field placeholder, can be empty - * @return {String} - */ - field(index, placeholder) { - return this.options.field(index, placeholder); - } -}; - -function strcase(string, type) { - if (type) { - return type === 'upper' ? string.toUpperCase() : string.toLowerCase(); - } - - return string; -} - -/* harmony default export */ var output_profile_es = (Profile); -// CONCATENATED MODULE: ../node_modules/@emmetio/expand-abbreviation/dist/expand.es.js -var expand_es__extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - - - - - - - - - - - - - - -/** - * Expands given abbreviation into code - * @param {String|Node} abbr Abbreviation to parse or already parsed abbreviation - * @param {Object} config - * @return {String} - */ -function expand(abbr, config) { - config = expand_es__extends({}, config); - - if (typeof abbr === 'string') { - abbr = expand_es_parse(abbr, config); - } - - return markup_formatters_es(abbr, config.profile, config.syntax, config); -} - -/** - * Parses given Emmet abbreviation into a final abbreviation tree with all - * required transformations applied - * @param {String} Abbreviation to parse - * @param {Object} config - * @return {Node} - */ -function expand_es_parse(abbr, config) { - return abbreviation_es(abbr).use(html_snippets_resolver_es, config.snippets).use(variable_resolver_es, config.variables).use(html_transform_es, config.text, config.options); -} - -/** - * Expands given abbreviation into code - * @param {String|Node} abbr Abbreviation to parse or already parsed abbreviation - * @param {Object} config - * @return {String} - */ -function expand$1(abbr, config) { - config = config || {}; - - if (typeof abbr === 'string') { - abbr = parse$1(abbr, config); - } - - return stylesheet_formatters_es(abbr, config.profile, config.syntax, config); -} - -/** - * Parses given Emmet abbreviation into a final abbreviation tree with all - * required transformations applied - * @param {String|Node} abbr Abbreviation to parse or already parsed abbreviation - * @param {Object} config - * @return {Node} - */ -function parse$1(abbr, config) { - if (typeof abbr === 'string') { - abbr = css_abbreviation_es(abbr); - } - - return abbr.use(css_snippets_resolver_es, config.snippets, config.options); -} - -const reLorem = /^lorem([a-z]*)(\d*)$/i; - -/** - * Constructs a snippets registry, filled with snippets, for given options - * @param {String} syntax Abbreviation syntax - * @param {Object|Object[]} snippets Additional snippets - * @return {SnippetsRegistry} - */ -function snippetsRegistryFactory(type, syntax, snippets) { - const registrySnippets = []; - - if (type === 'markup') { - registrySnippets.push(snippets_es.html); - } else if (type === 'stylesheet') { - registrySnippets.push(snippets_es.css); - } - - if (syntax in snippets_es && registrySnippets.indexOf(snippets_es[syntax]) === -1) { - registrySnippets.push(snippets_es[syntax]); - } - - if (Array.isArray(snippets)) { - snippets.forEach(item => { - // if array item is a string, treat it as a reference to globally - // defined snippets - registrySnippets.push(typeof item === 'string' ? snippets_es[item] : item); - }); - } else if (typeof snippets === 'object') { - registrySnippets.push(snippets); - } - - const registry = new snippets_registry_es(registrySnippets.filter(Boolean)); - - // for non-stylesheet syntaxes add Lorem Ipsum generator - if (type !== 'stylesheet') { - registry.get(0).set(reLorem, loremGenerator); - } - - return registry; -} - -function loremGenerator(node) { - const options = {}; - const m = node.name.match(reLorem); - if (m[1]) { - options.lang = m[1]; - } - - if (m[2]) { - options.wordCount = +m[2]; - } - - return lorem_es(node, options); -} - -/** - * Default variables used in snippets to insert common values into predefined snippets - * @type {Object} - */ -const defaultVariables = { - lang: 'en', - locale: 'en-US', - charset: 'UTF-8' -}; - -/** - * A list of syntaxes that should use Emmet CSS abbreviations: - * a variations of default abbreviation that holds values right in abbreviation name - * @type {Array} - */ -const stylesheetSyntaxes = ['css', 'sass', 'scss', 'less', 'stylus', 'sss']; - -const expand_es_defaultOptions = { - /** - * Type of abbreviation to parse: 'markup' or 'stylesheet'. - * Can be auto-detected from `syntax` property. Default is 'markup' - */ - type: null, - - /** - * Abbreviation output syntax - * @type {String} - */ - syntax: 'html', - - /** - * Field/tabstop generator for editor. Most editors support TextMate-style - * fields: ${0} or ${1:item}. So for TextMate-style fields this function - * will look like this: - * @example - * (index, placeholder) => `\${${index}${placeholder ? ':' + placeholder : ''}}` - * - * @param {Number} index Placeholder index. Fields with the same indices - * should be linked - * @param {String} [placeholder] Field placeholder - * @return {String} - */ - field: (index, placeholder) => placeholder || '', - - /** - * Insert given text string(s) into expanded abbreviation - * If array of strings is given, the implicitly repeated element (e.g. `li*`) - * will be repeated by the amount of items in array - * @type {String|String[]} - */ - text: null, - - /** - * Either predefined output profile or options for output profile. Used for - * abbreviation output - * @type {Profile|Object} - */ - profile: null, - - /** - * Custom variables for variable resolver - * @see @emmetio/variable-resolver - * @type {Object} - */ - variables: {}, - - /** - * Custom predefined snippets for abbreviation. The expanded abbreviation - * will try to match given snippets that may contain custom elements, - * predefined attributes etc. - * May also contain array of items: either snippets (Object) or references - * to default syntax snippets (String; the key in default snippets hash) - * @see @emmetio/snippets - * @type {Object|SnippetsRegistry} - */ - snippets: {}, - - /** - * Hash of additional transformations that should be applied to expanded - * abbreviation, like BEM or JSX. Since these transformations introduce - * side-effect, they are disabled by default and should be enabled by - * providing a transform name as a key and transform options as value: - * @example - * { - * bem: {element: '--'}, - * jsx: true // no options, just enable transform - * } - * @see @emmetio/html-transform/lib/addons - * @type {Object} - */ - options: null, - - /** - * Additional options for syntax formatter - * @see @emmetio/markup-formatters - * @type {Object} - */ - format: null -}; - -/** - * Expands given abbreviation into string, formatted according to provided - * syntax and options - * @param {String|Node} abbr Abbreviation string or parsed abbreviation tree - * @param {String|Object} [config] Parsing and formatting options (object) or - * abbreviation syntax (string) - * @return {String} - */ -function expand$2(abbr, config) { - config = createOptions(config); - - return getType(config.type, config.syntax) === 'stylesheet' ? expand$1(abbr, config) : expand(abbr, config); -} - -/** - * Parses given abbreviation into AST tree. This tree can be later formatted to - * string with `expand` function - * @param {String} abbr Abbreviation to parse - * @param {String|Object} [options] Parsing and formatting options (object) or - * abbreviation syntax (string) - * @return {Node} - */ -function parse$2(abbr, options) { - options = createOptions(options); - - return getType(options.type, options.syntax) === 'stylesheet' ? parse$1(abbr, options) : expand_es_parse(abbr, options); -} - -/** - * Creates snippets registry for given syntax and additional `snippets` - * @param {String} type Abbreviation type, 'markup' or 'stylesheet' - * @param {String} syntax Snippets syntax, used for retrieving predefined snippets - * @param {SnippetsRegistry|Object|Object[]} [snippets] Additional snippets - * @return {SnippetsRegistry} - */ -function createSnippetsRegistry(type, syntax, snippets) { - // Backward-compatibility with <0.6 - if (type && type !== 'markup' && type !== 'stylesheet') { - snippets = syntax; - syntax = type; - type = 'markup'; - } - - return snippets instanceof snippets_registry_es ? snippets : snippetsRegistryFactory(type, syntax, snippets); -} - -function createOptions(options) { - if (typeof options === 'string') { - options = { syntax: options }; - } - - options = expand_es__extends({}, expand_es_defaultOptions, options); - if (options.type == null && options.syntax) { - options.type = isStylesheet(options.syntax) ? 'stylesheet' : 'markup'; - } - - options.format = expand_es__extends({ field: options.field }, options.format); - options.profile = createProfile(options); - options.variables = expand_es__extends({}, defaultVariables, options.variables); - options.snippets = createSnippetsRegistry(options.type, options.syntax, options.snippets); - - return options; -} - -/** - * Check if given syntax belongs to stylesheet markup. - * Emmet uses different abbreviation flavours: one is a default markup syntax, - * used for HTML, Slim, Pug etc, the other one is used for stylesheets and - * allows embedded values in abbreviation name - * @param {String} syntax - * @return {Boolean} - */ -function isStylesheet(syntax) { - return stylesheetSyntaxes.indexOf(syntax) !== -1; -} - -/** - * Creates output profile from given options - * @param {Object} options - * @return {Profile} - */ -function createProfile(options) { - return options.profile instanceof output_profile_es ? options.profile : new output_profile_es(options.profile); -} - -/** - * Returns type of abbreviation expander: either 'markup' or 'stylesheet' - * @param {String} type - * @param {String} [syntax] - */ -function getType(type, syntax) { - if (type) { - return type === 'stylesheet' ? 'stylesheet' : 'markup'; - } - - return isStylesheet(syntax) ? 'stylesheet' : 'markup'; -} - - -//# sourceMappingURL=expand.es.js.map -// CONCATENATED MODULE: ../node_modules/@emmetio/css-snippets-resolver/dist/css-snippets-resolver.es.js -var dist_css_snippets_resolver_es__extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -const dist_css_snippets_resolver_es_DASH = 45; // - - -/** - * Calculates fuzzy match score of how close `abbr` matches given `string`. - * @param {String} abbr Abbreviation to score - * @param {String} string String to match - * @param {Number} [fuzziness] Fuzzy factor - * @return {Number} Match score - */ -function css_snippets_resolver_es_stringScore(abbr, string) { - abbr = abbr.toLowerCase(); - string = string.toLowerCase(); - - if (abbr === string) { - return 1; - } - - // a string MUST start with the same character as abbreviation - if (!string || abbr.charCodeAt(0) !== string.charCodeAt(0)) { - return 0; - } - - const abbrLength = abbr.length; - const stringLength = string.length; - let i = 1, - j = 1, - score = stringLength; - let ch1, ch2, found, acronym; - - while (i < abbrLength) { - ch1 = abbr.charCodeAt(i); - found = false; - acronym = false; - - while (j < stringLength) { - ch2 = string.charCodeAt(j); - - if (ch1 === ch2) { - found = true; - score += (stringLength - j) * (acronym ? 2 : 1); - break; - } - - // add acronym bonus for exactly next match after unmatched `-` - acronym = ch2 === dist_css_snippets_resolver_es_DASH; - j++; - } - - if (!found) { - break; - } - - i++; - } - - return score && score * (i / abbrLength) / css_snippets_resolver_es_sum(stringLength); -} - -/** - * Calculates sum of first `n` natural numbers, e.g. 1+2+3+...n - * @param {Number} n - * @return {Number} - */ -function css_snippets_resolver_es_sum(n) { - return n * (n + 1) / 2; -} - -const css_snippets_resolver_es_reProperty = /^([a-z\-]+)(?:\s*:\s*([^\n\r]+))?$/; -const dist_css_snippets_resolver_es_DASH$1 = 45; // - - -/** - * Creates a special structure for resolving CSS properties from plain CSS - * snippets. - * Almost all CSS snippets are aliases for real CSS properties with available - * value variants, optionally separated by `|`. Most values are keywords that - * can be fuzzy-resolved as well. Some CSS properties are shorthands for other, - * more specific properties, like `border` and `border-style`. For such cases - * keywords from more specific properties should be available in shorthands too. - * @param {Snippet[]} snippets - * @return {CSSSnippet[]} - */ -function css_snippets_resolver_es_cssSnippets(snippets) { - return css_snippets_resolver_es_nest(snippets.map(snippet => new css_snippets_resolver_es_CSSSnippet(snippet.key, snippet.value))); -} - -let css_snippets_resolver_es_CSSSnippet = class CSSSnippet { - constructor(key, value) { - this.key = key; - this.value = value; - this.property = null; - - // detect if given snippet is a property - const m = value && value.match(css_snippets_resolver_es_reProperty); - if (m) { - this.property = m[1]; - this.value = m[2]; - } - - this.dependencies = []; - } - - addDependency(dep) { - this.dependencies.push(dep); - } - - get defaultValue() { - return this.value != null ? css_snippets_resolver_es_splitValue(this.value)[0] : null; - } - - /** - * Returns list of unique keywords for current CSS snippet and its dependencies - * @return {String[]} - */ - keywords() { - const stack = []; - const keywords = new Set(); - let i = 0, - item, - candidates; - - if (this.property) { - // scan valid CSS-properties only - stack.push(this); - } - - while (i < stack.length) { - // NB Keep items in stack instead of push/pop to avoid possible - // circular references - item = stack[i++]; - - if (item.value) { - candidates = css_snippets_resolver_es_splitValue(item.value).filter(dist_css_snippets_resolver_es_isKeyword); - - // extract possible keywords from snippet value - for (let j = 0; j < candidates.length; j++) { - keywords.add(candidates[j].trim()); - } - - // add dependencies into scan stack - for (let j = 0, deps = item.dependencies; j < deps.length; j++) { - if (stack.indexOf(deps[j]) === -1) { - stack.push(deps[j]); - } - } - } - } - - return Array.from(keywords); - } -}; - -/** - * Nests more specific CSS properties into shorthand ones, e.g. - * background-position-x -> background-position -> background - * @param {CSSSnippet[]} snippets - * @return {CSSSnippet[]} - */ - -function css_snippets_resolver_es_nest(snippets) { - snippets = snippets.sort(css_snippets_resolver_es_snippetsSort); - const stack = []; - - // For sorted list of CSS properties, create dependency graph where each - // shorthand property contains its more specific one, e.g. - // backgound -> background-position -> background-position-x - for (let i = 0, cur, prev; i < snippets.length; i++) { - cur = snippets[i]; - - if (!cur.property) { - // not a CSS property, skip it - continue; - } - - // Check if current property belongs to one from parent stack. - // Since `snippets` array is sorted, items are perfectly aligned - // from shorthands to more specific variants - while (stack.length) { - prev = stack[stack.length - 1]; - - if (cur.property.indexOf(prev.property) === 0 && cur.property.charCodeAt(prev.property.length) === dist_css_snippets_resolver_es_DASH$1) { - prev.addDependency(cur); - stack.push(cur); - break; - } - - stack.pop(); - } - - if (!stack.length) { - stack.push(cur); - } - } - - return snippets; -} - -/** - * A sorting function for array of snippets - * @param {CSSSnippet} a - * @param {CSSSnippet} b - * @return {Number} - */ -function css_snippets_resolver_es_snippetsSort(a, b) { - if (a.key === b.key) { - return 0; - } - - return a.key < b.key ? -1 : 1; -} - -/** - * Check if given string is a keyword candidate - * @param {String} str - * @return {Boolean} - */ -function dist_css_snippets_resolver_es_isKeyword(str) { - return (/^\s*[\w-]+/.test(str) - ); -} - -function css_snippets_resolver_es_splitValue(value) { - return String(value).split('|'); -} - -const css_snippets_resolver_es_globalKeywords = ['auto', 'inherit', 'unset']; -const css_snippets_resolver_es_unitlessProperties = ['z-index', 'line-height', 'opacity', 'font-weight', 'zoom', 'flex', 'flex-grow', 'flex-shrink']; - -const dist_css_snippets_resolver_es_defaultOptions = { - intUnit: 'px', - floatUnit: 'em', - unitAliases: { - e: 'em', - p: '%', - x: 'ex', - r: 'rem' - }, - fuzzySearchMinScore: 0 -}; - -/** - * For every node in given `tree`, finds matching snippet from `registry` and - * updates node with snippet data. - * - * This resolver uses fuzzy matching for searching matched snippets and their - * keyword values. - */ - -function dist_css_snippets_resolver_es_index(tree, registry, options) { - options = dist_css_snippets_resolver_es__extends({}, dist_css_snippets_resolver_es_defaultOptions, options); - options.unitAliases = dist_css_snippets_resolver_es__extends({}, dist_css_snippets_resolver_es_defaultOptions.unitAliases, options && options.unitAliases); - - const snippets = css_snippets_resolver_es_convertToCSSSnippets(registry); - - tree.walk(node => dist_css_snippets_resolver_es_resolveNode(node, snippets, options)); - return tree; -} - -function css_snippets_resolver_es_convertToCSSSnippets(registry) { - return css_snippets_resolver_es_cssSnippets(registry.all({ type: 'string' })); -} - -/** - * Resolves given node: finds matched CSS snippets using fuzzy match and resolves - * keyword aliases from node value - * @param {Node} node - * @param {CSSSnippet[]} snippets - * @param {Object} options - * @return {Node} - */ -function dist_css_snippets_resolver_es_resolveNode(node, snippets, options) { - const snippet = css_snippets_resolver_es_findBestMatch(node.name, snippets, 'key', options.fuzzySearchMinScore); - - if (!snippet) { - // Edge case: `!important` snippet - return node.name === '!' ? css_snippets_resolver_es_setNodeAsText(node, '!important') : node; - } - - return snippet.property ? css_snippets_resolver_es_resolveAsProperty(node, snippet, options) : css_snippets_resolver_es_resolveAsSnippet(node, snippet); -} - -/** - * Resolves given parsed abbreviation node as CSS property - * @param {Node} node - * @param {CSSSnippet} snippet - * @param {Object} formatOptions - * @return {Node} - */ -function css_snippets_resolver_es_resolveAsProperty(node, snippet, formatOptions) { - const abbr = node.name; - node.name = snippet.property; - - if (node.value && typeof node.value === 'object') { - // resolve keyword shortcuts - const keywords = snippet.keywords(); - - if (!node.value.size) { - // no value defined, try to resolve unmatched part as a keyword alias - let kw = css_snippets_resolver_es_findBestMatch(css_snippets_resolver_es_getUnmatchedPart(abbr, snippet.key), keywords); - - if (!kw) { - // no matching value, try to get default one - kw = snippet.defaultValue; - if (kw && kw.indexOf('${') === -1) { - // Quick and dirty test for existing field. If not, wrap - // default value in a field - kw = `\${1:${kw}}`; - } - } - - if (kw) { - node.value.add(kw); - } - } else { - // replace keyword aliases in current node value - for (let i = 0, token; i < node.value.value.length; i++) { - token = node.value.value[i]; - - if (token === '!') { - token = `${!i ? '${1} ' : ''}!important`; - } else if (css_snippets_resolver_es_isKeyword$1(token)) { - token = css_snippets_resolver_es_findBestMatch(token.value, keywords) || css_snippets_resolver_es_findBestMatch(token.value, css_snippets_resolver_es_globalKeywords) || token; - } else if (css_snippets_resolver_es_isNumericValue(token)) { - token = css_snippets_resolver_es_resolveNumericValue(node.name, token, formatOptions); - } - - node.value.value[i] = token; - } - } - } - - return node; -} - -/** - * Resolves given parsed abbreviation node as a snippet: a plain code chunk - * @param {Node} node - * @param {CSSSnippet} snippet - * @return {Node} - */ -function css_snippets_resolver_es_resolveAsSnippet(node, snippet) { - return css_snippets_resolver_es_setNodeAsText(node, snippet.value); -} - -/** - * Sets given parsed abbreviation node as a text snippet - * @param {Node} node - * @param {String} text - * @return {Node} - */ -function css_snippets_resolver_es_setNodeAsText(node, text) { - node.name = null; - node.value = text; - return node; -} - -/** - * Finds best matching item from `items` array - * @param {String} abbr Abbreviation to match - * @param {Array} items List of items for match - * @param {String} [key] If `items` is a list of objects, use `key` as object - * property to test against - * @param {Number} fuzzySearchMinScore The minimum score the best matched item should have to be a valid match. - * @return {*} - */ -function css_snippets_resolver_es_findBestMatch(abbr, items, key, fuzzySearchMinScore) { - if (!abbr) { - return null; - } - - let matchedItem = null; - let maxScore = 0; - fuzzySearchMinScore = fuzzySearchMinScore || 0; - - for (let i = 0, item; i < items.length; i++) { - item = items[i]; - const score = css_snippets_resolver_es_stringScore(abbr, css_snippets_resolver_es_getScoringPart(item, key)); - - if (score === 1) { - // direct hit, no need to look further - return item; - } - - if (score && score >= maxScore) { - maxScore = score; - matchedItem = item; - } - } - - return maxScore >= fuzzySearchMinScore ? matchedItem : null; -} - -function css_snippets_resolver_es_getScoringPart(item, key) { - const value = item && typeof item === 'object' ? item[key] : item; - const m = (value || '').match(/^[\w-@]+/); - return m ? m[0] : value; -} - -/** - * Returns a part of `abbr` that wasn’t directly matched agains `string`. - * For example, if abbreviation `poas` is matched against `position`, the unmatched part will be `as` - * since `a` wasn’t found in string stream - * @param {String} abbr - * @param {String} string - * @return {String} - */ -function css_snippets_resolver_es_getUnmatchedPart(abbr, string) { - for (let i = 0, lastPos = 0; i < abbr.length; i++) { - lastPos = string.indexOf(abbr[i], lastPos); - if (lastPos === -1) { - return abbr.slice(i); - } - lastPos++; - } - - return ''; -} - -/** - * Check if given CSS value token is a keyword - * @param {*} token - * @return {Boolean} - */ -function css_snippets_resolver_es_isKeyword$1(token) { - return css_snippets_resolver_es_tokenTypeOf(token, 'keyword'); -} - -/** - * Check if given CSS value token is a numeric value - * @param {*} token - * @return {Boolean} - */ -function css_snippets_resolver_es_isNumericValue(token) { - return css_snippets_resolver_es_tokenTypeOf(token, 'numeric'); -} - -function css_snippets_resolver_es_tokenTypeOf(token, type) { - return token && typeof token === 'object' && token.type === type; -} - -/** - * Resolves numeric value for given CSS property - * @param {String} property CSS property name - * @param {NumericValue} token CSS numeric value token - * @param {Object} formatOptions Formatting options for units - * @return {NumericValue} - */ -function css_snippets_resolver_es_resolveNumericValue(property, token, formatOptions) { - if (token.unit) { - token.unit = formatOptions.unitAliases[token.unit] || token.unit; - } else if (token.value !== 0 && css_snippets_resolver_es_unitlessProperties.indexOf(property) === -1) { - // use `px` for integers, `em` for floats - // NB: num|0 is a quick alternative to Math.round(0) - token.unit = token.value === (token.value | 0) ? formatOptions.intUnit : formatOptions.floatUnit; - } - - return token; -} - -/* harmony default export */ var dist_css_snippets_resolver_es = (dist_css_snippets_resolver_es_index); - -//# sourceMappingURL=css-snippets-resolver.es.js.map -// CONCATENATED MODULE: ../node_modules/@emmetio/html-matcher/dist/html-matcher.es.js -var html_matcher_es__extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - - - - -let html_matcher_es_Node = class Node { - constructor(stream, type, open, close) { - this.stream = stream; - this.type = type; - this.open = open; - this.close = close; - - this.children = []; - this.parent = null; - } - - /** - * Returns node name - * @return {String} - */ - get name() { - if (this.type === 'tag' && this.open) { - return this.open && this.open.name && this.open.name.value; - } - - return '#' + this.type; - } - - /** - * Returns attributes of current node - * @return {Array} - */ - get attributes() { - return this.open && this.open.attributes; - } - - /** - * Returns node’s start position in stream - * @return {*} - */ - get start() { - return this.open && this.open.start; - } - - /** - * Returns node’s start position in stream - * @return {*} - */ - get end() { - return this.close ? this.close.end : this.open && this.open.end; - } - - get firstChild() { - return this.children[0]; - } - - get nextSibling() { - const ix = this.getIndex(); - return ix !== -1 ? this.parent.children[ix + 1] : null; - } - - get previousSibling() { - const ix = this.getIndex(); - return ix !== -1 ? this.parent.children[ix - 1] : null; - } - - /** - * Returns current element’s index in parent list of child nodes - * @return {Number} - */ - getIndex() { - return this.parent ? this.parent.children.indexOf(this) : -1; - } - - /** - * Adds given node as a child - * @param {Node} node - * @return {Node} Current node - */ - addChild(node) { - this.removeChild(node); - this.children.push(node); - node.parent = this; - return this; - } - - /** - * Removes given node from current node’s child list - * @param {Node} node - * @return {Node} Current node - */ - removeChild(node) { - const ix = this.children.indexOf(node); - if (ix !== -1) { - this.children.splice(ix, 1); - node.parent = null; - } - - return this; - } -}; - -/** - * A token factory method - * @param {StreamReader} stream - * @param {Point|Function} start Tokens’ start location or stream consumer - * @param {Point} [end] Tokens’ end location - * @return {Token} - */ - -var html_matcher_es_token = function (stream, start, end) { - return typeof start === 'function' ? eatToken(stream, start) : new Token(stream, start, end); -}; - -/** - * Consumes characters from given stream that matches `fn` call and returns it - * as token, if consumed - * @param {StreamReader} stream - * @param {Function} test - * @return {Token} - */ -function eatToken(stream, test) { - const start = stream.pos; - if (stream.eatWhile(test)) { - return new Token(stream, start, stream.pos); - } - - stream.pos = start; -} - -/** - * A structure describing text fragment in content stream - */ -let Token = class Token { - /** - * @param {ContentStreamReader} stream - * @param {Point} start Tokens’ start location in content stream - * @param {Point} end Tokens’ end location in content stream - */ - constructor(stream, start, end) { - this.stream = stream; - this.start = start != null ? start : stream.start; - this.end = end != null ? end : stream.pos; - this._value = null; - } - - /** - * Returns token textual value - * NB implemented as getter to reduce unnecessary memory allocations for - * strings that not required - * @return {String} - */ - get value() { - if (this._value === null) { - const start = this.stream.start; - const end = this.stream.pos; - - this.stream.start = this.start; - this.stream.pos = this.end; - this._value = this.stream.current(); - - this.stream.start = start; - this.stream.pos = end; - } - - return this._value; - } - - toString() { - return this.value; - } - - valueOf() { - return `${this.value} [${this.start}; ${this.end}]`; - } -}; - - -const LANGLE = 60; -const RANGLE = 62; // < and > -const LSQUARE = 91; -const RSQUARE = 93; // [ and ] -const LROUND = 40; -const RROUND = 41; // ( and ) -const LCURLY = 123; -const RCURLY = 125; // { and } - -const html_matcher_es_opt = { throws: true }; - -/** - * Consumes paired tokens (like `[` and `]`) with respect of nesting and embedded - * quoted values - * @param {StreamReader} stream - * @return {Token} A token with consumed paired character - */ -var eatPaired = function (stream) { - const start = stream.pos; - const consumed = eatPair(stream, LANGLE, RANGLE, html_matcher_es_opt) || eatPair(stream, LSQUARE, RSQUARE, html_matcher_es_opt) || eatPair(stream, LROUND, RROUND, html_matcher_es_opt) || eatPair(stream, LCURLY, RCURLY, html_matcher_es_opt); - - if (consumed) { - return html_matcher_es_token(stream, start); - } -}; - -const SLASH$1 = 47; // / -const html_matcher_es_EQUALS = 61; // = -const RIGHT_ANGLE$1 = 62; // > - -/** - * Consumes attributes from given stream - * @param {StreamReader} stream - * @return {Array} Array of consumed attributes - */ -var eatAttributes = function (stream) { - const result = []; - let name, value, attr; - - while (!stream.eof()) { - stream.eatWhile(isSpace); - attr = { start: stream.pos }; - - // A name could be a regular name or expression: - // React-style –
- // Angular-style –
- if (attr.name = eatAttributeName(stream)) { - // Consumed attribute name. Can be an attribute with name - // or boolean attribute. The value can be React-like expression - if (stream.eat(html_matcher_es_EQUALS)) { - attr.value = eatAttributeValue(stream); - } else { - attr.boolean = true; - } - attr.end = stream.pos; - result.push(attr); - } else if (isTerminator(stream.peek())) { - // look for tag terminator in order to skip any other possible characters - // (maybe junk) - break; - } else { - stream.next(); - } - } - - return result; -}; - -/** - * Consumes attribute name from current location - * @param {StreamReader} stream - * @return {Token} - */ -function eatAttributeName(stream) { - return eatPaired(stream) || html_matcher_es_token(stream, isAttributeName); -} - -/** - * Consumes attribute value from given location - * @param {StreamReader} stream - * @return {Token} - */ -function eatAttributeValue(stream) { - const start = stream.pos; - if (eatQuoted(stream)) { - // Should return token that points to unquoted value. - // Use stream readers’ public API to traverse instead of direct - // manipulation - const current = stream.pos; - let valueStart, valueEnd; - - stream.pos = start; - stream.next(); - valueStart = stream.start = stream.pos; - - stream.pos = current; - stream.backUp(1); - valueEnd = stream.pos; - - const result = html_matcher_es_token(stream, valueStart, valueEnd); - stream.pos = current; - return result; - } - - return eatPaired(stream) || html_matcher_es_eatUnquoted(stream); -} - -/** - * Check if given code belongs to attribute name. - * NB some custom HTML variations allow non-default values in name, like `*ngFor` - * @param {Number} code - * @return {Boolean} - */ -function isAttributeName(code) { - return code !== html_matcher_es_EQUALS && !isTerminator(code) && !isSpace(code); -} - -/** - * Check if given code is tag terminator - * @param {Number} code - * @return {Boolean} - */ -function isTerminator(code) { - return code === RIGHT_ANGLE$1 || code === SLASH$1; -} - -/** - * Eats unquoted value from stream - * @param {StreamReader} stream - * @return {Token} - */ -function html_matcher_es_eatUnquoted(stream) { - return html_matcher_es_token(stream, html_matcher_es_isUnquoted); -} - -/** - * Check if given character code is valid unquoted value - * @param {Number} code - * @return {Boolean} - */ -function html_matcher_es_isUnquoted(code) { - return !isNaN(code) && !isQuote(code) && !isSpace(code) && !isTerminator(code); -} - -const html_matcher_es_DASH = 45; // - -const html_matcher_es_DOT = 46; // . -const html_matcher_es_SLASH = 47; // / -const html_matcher_es_COLON = 58; // : -const LEFT_ANGLE = 60; // < -const RIGHT_ANGLE = 62; // > -const UNDERSCORE = 95; // _ - -/** - * Parses tag definition (open or close tag) from given stream state - * @param {StreamReader} stream Content stream reader - * @return {Object} - */ -var tag = function (stream) { - const start = stream.pos; - - if (stream.eat(LEFT_ANGLE)) { - const model = { type: stream.eat(html_matcher_es_SLASH) ? 'close' : 'open' }; - - if (model.name = eatTagName(stream)) { - if (model.type !== 'close') { - model.attributes = eatAttributes(stream); - stream.eatWhile(isSpace); - model.selfClosing = stream.eat(html_matcher_es_SLASH); - } - - if (stream.eat(RIGHT_ANGLE)) { - // tag properly closed - return html_matcher_es__extends(html_matcher_es_token(stream, start), model); - } - } - } - - // invalid tag, revert to original position - stream.pos = start; - return null; -}; - -/** - * Eats HTML identifier (tag or attribute name) from given stream - * @param {StreamReader} stream - * @return {Token} - */ -function eatTagName(stream) { - return html_matcher_es_token(stream, isTagName); -} - -/** - * Check if given character code can be used as HTML/XML tag name - * @param {Number} code - * @return {Boolean} - */ -function isTagName(code) { - return isAlphaNumeric(code) || code === html_matcher_es_COLON // colon is used for namespaces - || code === html_matcher_es_DOT // in rare cases declarative tag names may have dots in names - || code === html_matcher_es_DASH || code === UNDERSCORE; -} - -/** - * Eats array of character codes from given stream - * @param {StreamReader} stream - * @param {Number[]} codes Array of character codes - * @return {Boolean} - */ -function eatArray(stream, codes) { - const start = stream.pos; - - for (let i = 0; i < codes.length; i++) { - if (!stream.eat(codes[i])) { - stream.pos = start; - return false; - } - } - - stream.start = start; - return true; -} - -/** - * Consumes section from given string which starts with `open` character codes - * and ends with `close` character codes - * @param {StreamReader} stream - * @param {Number[]} open - * @param {Number[]} close - * @return {Boolean} Returns `true` if section was consumed - */ -function eatSection(stream, open, close, allowUnclosed) { - const start = stream.pos; - if (eatArray(stream, open)) { - // consumed `'); - -/** - * Consumes HTML comment from given stream - * @param {StreamReader} stream - * @return {Token} - */ -var comment = function (stream) { - const start = stream.pos; - if (eatSection(stream, html_matcher_es_open, html_matcher_es_close, true)) { - const result = html_matcher_es_token(stream, start); - result.type = 'comment'; - return result; - } - - return null; -}; - -const open$1 = toCharCodes(''); - -/** - * Consumes CDATA from given stream - * @param {StreamReader} stream - * @return {Token} - */ -var cdata = function (stream) { - const start = stream.pos; - if (eatSection(stream, open$1, close$1, true)) { - const result = html_matcher_es_token(stream, start); - result.type = 'cdata'; - return result; - } - - return null; -}; - -const html_matcher_es_defaultOptions = { - /** - * Expect XML content in searching content. It alters how should-be-empty - * elements are treated: for example, in XML mode parser will try to locate - * closing pair for `
` tag - * @type {Boolean} - */ - xml: false, - - special: ['script', 'style'], - - /** - * List of elements that should be treated as empty (e.g. without closing tag) - * in non-XML syntax - * @type {Array} - */ - empty: ['img', 'meta', 'link', 'br', 'base', 'hr', 'area', 'wbr', 'col', 'embed', 'input', 'param', 'source', 'track'] -}; - -/** - * Parses given content into a DOM-like structure - * @param {String|StreamReader} content - * @param {Object} options - * @return {Node} - */ -function html_matcher_es_parse(content, options) { - options = html_matcher_es__extends({}, html_matcher_es_defaultOptions, options); - const stream = typeof content === 'string' ? new stream_reader_es(content) : content; - - const root = new html_matcher_es_Node(stream, 'root'); - const empty = new Set(options.empty); - const special = options.special.reduce((map, name) => map.set(name, toCharCodes(``)), new Map()); - const isEmpty = (token, name) => token.selfClosing || !options.xml && empty.has(name); - - let m, - node, - name, - stack = [root]; - - while (!stream.eof()) { - if (m = match(stream)) { - name = getName(m); - - if (m.type === 'open') { - // opening tag - node = new html_matcher_es_Node(stream, 'tag', m); - last(stack).addChild(node); - if (special.has(name)) { - node.close = consumeSpecial(stream, special.get(name)); - } else if (!isEmpty(m, name)) { - stack.push(node); - } - } else if (m.type === 'close') { - // closing tag, find it’s matching opening tag - for (let i = stack.length - 1; i > 0; i--) { - if (stack[i].name.toLowerCase() === name) { - stack[i].close = m; - stack = stack.slice(0, i); - break; - } - } - } else { - last(stack).addChild(new html_matcher_es_Node(stream, m.type, m)); - } - } else { - stream.next(); - } - } - - return root; -} - -/** - * Matches known token in current state of given stream - * @param {ContentStreamReader} stream - * @return {Token} - */ -function match(stream) { - // fast-path optimization: check for `<` code - if (stream.peek() === 60 /* < */) { - return comment(stream) || cdata(stream) || tag(stream); - } -} - -/** - * @param {StreamReader} stream - * @param {Number[]} codes - * @return {Token} - */ -function consumeSpecial(stream, codes) { - const start = stream.pos; - let m; - - while (!stream.eof()) { - if (eatArray(stream, codes)) { - stream.pos = stream.start; - return tag(stream); - } - stream.next(); - } - - stream.pos = start; - return null; -} - -/** - * Returns name of given matched token - * @param {Token} tag - * @return {String} - */ -function getName(tag$$1) { - return tag$$1.name ? tag$$1.name.value.toLowerCase() : `#${tag$$1.type}`; -} - -function last(arr) { - return arr[arr.length - 1]; -} - -/* harmony default export */ var html_matcher_es = (html_matcher_es_parse); -// CONCATENATED MODULE: ../node_modules/@emmetio/codemirror-plugin/dist/emmet-codemirror-plugin.es.js -var emmet_codemirror_plugin_es__extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - - - - - - - - - - -const editorField = (index, placeholder = '') => `\${${index}${placeholder ? ':' + placeholder : ''}}`; - -/** - * Returns resolved Emmet config for `pos` location of given editor - * @param {CodeMirror.Editor} editor - * @param {CodeMirror.Position} [pos] Point in editor where syntax should be detected. - * Uses `editor.getCursor()` if not given - * @param {Object} [options] Additional options to override before config resolve - * @return {Object} - */ -function createConfig(editor, pos, options) { - pos = pos || editor.getCursor(); - const syntax = getSyntax(editor, pos); - - /** @type {EmmetConfig} */ - const config = config_es(emmet_codemirror_plugin_es__extends({ field: editorField }, editor.getOption('emmet'), options), { syntax }); - - const mode = editor.getModeAt(pos); - if (syntax === 'jsx') { - config.profile = emmet_codemirror_plugin_es__extends({ selfClosingStyle: 'xml' }, config.profile); - config.options = emmet_codemirror_plugin_es__extends({ jsx: true }, config.options); - } else if (mode.name === 'xml') { - config.profile = emmet_codemirror_plugin_es__extends({ selfClosingStyle: mode.configuration }, config.profile); - } - - return config; -} - -/** - * Detect Emmet syntax from given editor’s position. - * @param {CodeMirror.Editor} editor - * @param {CodeMirror.Position} [pos] - * @return {String} Returns `null` if Emmet syntax can’t be detected - */ -function getSyntax(editor, pos) { - const rootMode = editor.getMode(); - if (rootMode.name === 'jsx' || rootMode.name === 'javascript') { - return rootMode.name; - } - - const mode = editor.getModeAt(pos); - return mode.name === 'xml' ? 'html' : mode.name; -} - -const LINE_END = 10; // \n - -/** - * A stream reader for CodeMirror editor - */ -let CodeMirrorStreamReader = class CodeMirrorStreamReader extends stream_reader_es { - /** - * @param {CodeMirror.Editor} editor - * @param {CodeMirror.Position} [pos] - * @param {CodeMirror.Range} [limit] - */ - constructor(editor, pos, limit) { - super(); - const CodeMirror = editor.constructor; - this.editor = editor; - this.start = this.pos = pos || CodeMirror.Pos(0, 0); - - const lastLine = editor.lastLine(); - this._eof = limit ? limit.to : CodeMirror.Pos(lastLine, this._lineLength(lastLine)); - this._sof = limit ? limit.from : CodeMirror.Pos(0, 0); - } - - /** - * Returns true only if the stream is at the beginning of the file. - * @returns {Boolean} - */ - sof() { - return comparePos(this.pos, this._sof) <= 0; - } - - /** - * Returns true only if the stream is at the end of the file. - * @returns {Boolean} - */ - eof() { - return comparePos(this.pos, this._eof) >= 0; - } - - /** - * Creates a new stream instance which is limited to given `start` and `end` - * points for underlying buffer - * @param {CodeMirror.Pos} start - * @param {CodeMirror.Pos} end - * @return {CodeMirrorStreamReader} - */ - limit(from, to) { - return new this.constructor(this.editor, from, { from, to }); - } - - /** - * Returns the next character code in the stream without advancing it. - * Will return NaN at the end of the file. - * @returns {Number} - */ - peek() { - const { line, ch } = this.pos; - const lineStr = this.editor.getLine(line); - return ch < lineStr.length ? lineStr.charCodeAt(ch) : LINE_END; - } - - /** - * Returns the next character in the stream and advances it. - * Also returns NaN when no more characters are available. - * @returns {Number} - */ - next() { - if (!this.eof()) { - const code = this.peek(); - this.pos = emmet_codemirror_plugin_es__extends({}, this.pos, { ch: this.pos.ch + 1 }); - - if (this.pos.ch >= this._lineLength(this.pos.line)) { - this.pos.line++; - this.pos.ch = 0; - } - - if (this.eof()) { - // handle edge case where position can move on next line - // after EOF - this.pos = emmet_codemirror_plugin_es__extends({}, this._eof); - } - - return code; - } - - return NaN; - } - - /** - * Backs up the stream n characters. Backing it up further than the - * start of the current token will cause things to break, so be careful. - * @param {Number} n - */ - backUp(n) { - const CodeMirror = this.editor.constructor; - - let { line, ch } = this.pos; - ch -= n || 1; - - while (line >= 0 && ch < 0) { - line--; - ch += this._lineLength(line); - } - - this.pos = line < 0 || ch < 0 ? CodeMirror.Pos(0, 0) : CodeMirror.Pos(line, ch); - - return this.peek(); - } - - /** - * Get the string between the start of the current token and the - * current stream position. - * @returns {String} - */ - current() { - return this.substring(this.start, this.pos); - } - - /** - * Returns contents for given range - * @param {Point} from - * @param {Point} to - * @return {String} - */ - substring(from, to) { - return this.editor.getRange(from, to); - } - - /** - * Creates error object with current stream state - * @param {String} message - * @return {Error} - */ - error(message) { - const err = new Error(`${message} at line ${this.pos.line}, column ${this.pos.ch}`); - err.originalMessage = message; - err.pos = this.pos; - err.string = this.string; - return err; - } - - /** - * Returns length of given line, including line ending - * @param {Number} line - * @return {Number} - */ - _lineLength(line) { - const isLast = line === this.editor.lastLine(); - return this.editor.getLine(line).length + (isLast ? 0 : 1); - } -}; - - -function comparePos(a, b) { - return a.line - b.line || a.ch - b.ch; -} - -/** - * Returns token used for single indentation in given editor - * @param {CodeMirror.Editor} editor - * @return {String} - */ -function getIndentation(editor) { - if (!editor.getOption('indentWithTabs')) { - return repeatString(' ', editor.getOption('indentUnit')); - } - - return '\t'; -} - -/** - * Normalizes text according to given CodeMirror instance indentation - * preferences - * @param {String} text - * @param {CodeMirror.Editor} editor - * @param {String} [indentation] Applies `indentText()` with given argument, if provided - * @return {String} - */ -function normalizeText(editor, text, indentation) { - let lines = emmet_codemirror_plugin_es_splitByLines(text); - const indent = getIndentation(editor); - - if (indent !== '\t') { - lines = lines.map(line => line.replace(/^\t+/, tabs => repeatString(indent, tabs.length))); - } - - if (indentation) { - lines = lines.map((line, i) => i ? indentation + line : line); - } - - return lines.join('\n'); -} - -/** - * Splits given text by lines - * @param {String} text - * @return {String[]} Lines of text - */ -function emmet_codemirror_plugin_es_splitByLines(text) { - return Array.isArray(text) ? text : text.split(/\r\n|\r|\n/g); -} - -function repeatString(str, count) { - let result = ''; - while (0 < count--) { - result += str; - } - - return result; -} - -/** - * Quick and dirty way to remove fields from given string - * @param {String} str - * @return {String} - */ -function removeFields(str) { - return field_parser_es(str).string; -} - -/** - * Check if given range contains point - * @param {CodeMirror.Range} range - * @param {CodeMirror.Position} pos - * @param {Boolean} [exclude] Exclude range and and start - * @return {Boolean} - */ -function containsPos(range, pos, exclude) { - return exclude ? comparePos$1(pos, range.from) > 0 && comparePos$1(pos, range.to) < 0 : comparePos$1(pos, range.from) >= 0 && comparePos$1(pos, range.to) <= 0; -} - -function comparePos$1(a, b) { - return a.line - b.line || a.ch - b.ch; -} - -function rangeFromNode(node) { - return { - from: node.start, - to: node.end - }; -} - -/** - * Narrows given `{from, to}` range to first non-whitespace characters in given - * editor content - * @param {CodeMirror.Editor} editor - * @param {CodeMirror.Position} from - * @param {CodeMirror.Position} [to] - * @returns {Object} - */ -function narrowToNonSpace(editor, from, to) { - const stream = new CodeMirrorStreamReader(editor, from); - - stream.eatWhile(isSpace); - from = stream.pos; - - if (to) { - stream.pos = to; - stream.backUp(); - - while (!stream.sof() && isSpace(stream.peek())) { - stream.backUp(); - } - - stream.next(); - to = stream.pos; - } else { - to = from; - } - - return { from, to }; -} - -/** - * Returns nearest CSS property name, left to given position - * @param {CodeMirror.Editor} editor - * @param {CodeMirror.Position} pos - * @returns {String} - */ -function getCSSPropertyName(editor, pos) { - const line = pos.line; - let ch = pos.ch, - token; - - while (ch >= 0) { - token = editor.getTokenAt({ line, ch }); - if (token.type === 'property') { - return token.string; - } - - if (token.start !== ch) { - ch = token.start; - } else { - break; - } - } -} - -/** - * Check if given position is inside CSS property value - * @param {CodeMirror.Editor} editor - * @param {CodeMirror.Position} pos - * @return {Boolean} - */ -function isCSSPropertyValue(editor, pos) { - const mode = editor.getModeAt(pos); - if (mode && mode.name === 'css') { - const token = editor.getTokenAt(pos); - const state = token.state && token.state.localState || token.state; - return state && state.context && state.context.type === 'prop'; - } - - return false; -} - -/** - * Context-aware abbreviation extraction from given editor. - * Detects syntax context in `pos` editor location and, if it allows Emmet - * abbreviation to be extracted here, returns object with extracted abbreviation, - * its location and config. - * @param {CodeMirror.Editor} editor - * @param {CodeMirror.Position} pos - */ -function emmet_codemirror_plugin_es_extractAbbreviation(editor, pos, contextAware) { - const config = createConfig(editor, pos); - - if (contextAware && !canExtract(editor, pos, config)) { - return null; - } - - const extracted = extract_abbreviation_es(editor.getLine(pos.line), pos.ch, { - lookAhead: true, - syntax: config.type, - prefix: config.syntax === 'jsx' && editor.getOption('jsxBracket') ? '<' : '' - }); - - if (extracted) { - const from = { - line: pos.line, - ch: extracted.start - }; - const to = { - line: pos.line, - ch: extracted.end - }; - - if (config.type === 'stylesheet' && contextAware) { - // In case of stylesheet syntaxes (CSS, LESS) we should narrow down - // expand context to property value, if possible - if (isCSSPropertyValue(editor, pos)) { - config.options = emmet_codemirror_plugin_es__extends({ property: getCSSPropertyName(editor, pos) }, config.options); - } - } - - return { - abbreviation: extracted.abbreviation, - range: { from, to }, - config - }; - } -} - -/** - * Check if abbreviation can be extracted from given position - * @param {CodeMirror.Editor} editor - * @param {CodeMirror.Position} pos - * @param {Object} config - * @return {Boolean} - */ -function canExtract(editor, pos, config) { - const tokenType = editor.getTokenTypeAt(pos); - - if (config.type === 'stylesheet') { - return tokenType !== 'comment' && tokenType !== 'string'; - } - - if (config.syntax === 'html') { - return tokenType === null; - } - - if (config.syntax === 'slim' || config.syntax === 'pug') { - return tokenType === null || tokenType === 'tag' || tokenType && /attribute/.test(tokenType); - } - - if (config.syntax === 'haml') { - return tokenType === null || tokenType === 'attribute'; - } - - if (config.syntax === 'jsx') { - // JSX a bit tricky, delegate it to caller - return true; - } - - return false; -} - -/** - * Replaces `range` in `editor` with `text` snippet. A snippet is a string containing - * tabstops/fields like `${index:placeholder}`: this function will locate such - * fields and place cursor at first one. - * Inserted snippet will be automatically matched with current editor indentation - * @param {CodeMirror.Editor} editor - * @param {CodeMirror.Range} range - * @param {String} text - */ -function insertSnippet(editor, range, text) { - const line = editor.getLine(range.from.line); - const matchIndent = line.match(/^\s+/); - let snippet = normalizeText(editor, text, matchIndent && matchIndent[0]); - const fieldModel = field_parser_es(snippet); - - return editor.operation(() => { - editor.replaceRange(fieldModel.string, range.from, range.to); - - // Position cursor - const startIx = editor.indexFromPos(range.from); - if (fieldModel.fields.length) { - const field = fieldModel.fields[0]; - const from = editor.posFromIndex(field.location + startIx); - const to = editor.posFromIndex(field.location + field.length + startIx); - editor.setSelection(from, to); - } else { - editor.setCursor(editor.posFromIndex(startIx + fieldModel.string.length)); - } - - return true; - }); -} - -const emmetMarkerClass = 'emmet-abbreviation'; - -/** - * Returns parsed abbreviation from given position in `editor`, if possible. - * @param {CodeMirror.Editor} editor - * @param {CodeMirror.Position} pos - * @param {Boolean} [contextAware] Use context-aware abbreviation detection - * @returns {Abbreviation} - */ -function abbreviationFromPosition(editor, pos, contextAware) { - // Try to find abbreviation marker from given position - const marker = findMarker(editor, pos); - if (marker && marker.model) { - return marker.model; - } - - // Try to extract abbreviation from given position - const extracted = emmet_codemirror_plugin_es_extractAbbreviation(editor, pos, contextAware); - if (extracted) { - try { - const abbr = new emmet_codemirror_plugin_es_Abbreviation(extracted.abbreviation, extracted.range, extracted.config); - return abbr.valid(editor, contextAware) ? abbr : null; - } catch (err) { - // skip - // console.warn(err); - } - } -} - -/** - * Returns *valid* Emmet abbreviation marker (if any) for given position of editor - * @param {CodeMirror.Editor} editor - * @param {CodeMirror.Position} [pos] - * @return {CodeMirror.TextMarker} - */ -function findMarker(editor, pos) { - const markers = editor.findMarksAt(pos); - for (let i = 0, marker; i < markers.length; i++) { - marker = markers[i]; - if (marker.className === emmetMarkerClass) { - if (isValidMarker(editor, marker)) { - return marker; - } - - marker.clear(); - } - } -} - -/** - * Removes Emmet abbreviation markers from given editor - * @param {CodeMirror.Editor} editor - */ -function clearMarkers(editor) { - const markers = editor.getAllMarks(); - for (let i = 0; i < markers.length; i++) { - if (markers[i].className === emmetMarkerClass) { - markers[i].clear(); - } - } -} - -/** - * Marks Emmet abbreviation for given editor position, if possible - * @param {CodeMirror.Editor} editor Editor where abbreviation marker should be created - * @param {Abbreviation} model Parsed abbreviation model - * @return {CodeMirror.TextMarker} Returns `undefined` if no valid abbreviation under caret - */ -function createMarker(editor, model) { - const { from, to } = model.range; - const marker = editor.markText(from, to, { - inclusiveLeft: true, - inclusiveRight: true, - clearWhenEmpty: true, - className: emmetMarkerClass - }); - marker.model = model; - return marker; -} - -/** - * Ensures that given editor Emmet abbreviation marker contains valid Emmet abbreviation - * and updates abbreviation model if required - * @param {CodeMirror} editor - * @param {CodeMirror.TextMarket} marker - * @return {Boolean} `true` if marker contains valid abbreviation - */ -function isValidMarker(editor, marker) { - const range = marker.find(); - - // No newlines inside abbreviation - if (range.from.line !== range.to.line) { - return false; - } - - // Make sure marker contains valid abbreviation - let text = editor.getRange(range.from, range.to); - if (!text || /^\s|\s$/g.test(text)) { - return false; - } - - if (marker.model && marker.model.config.syntax === 'jsx' && text[0] === '<') { - text = text.slice(1); - } - - if (!marker.model || marker.model.abbreviation !== text) { - // marker contents was updated, re-parse abbreviation - try { - marker.model = new emmet_codemirror_plugin_es_Abbreviation(text, range, marker.model.config); - if (!marker.model.valid(editor, true)) { - marker.model = null; - } - } catch (err) { - console.warn(err); - marker.model = null; - } - } - - return Boolean(marker.model && marker.model.snippet); -} - -let emmet_codemirror_plugin_es_Abbreviation = class Abbreviation { - /** - * @param {String} abbreviation Abbreviation string - * @param {CodeMirror.Range} range Abbreviation location in editor - * @param {Object} [config] - */ - constructor(abbreviation, range, config) { - this.abbreviation = abbreviation; - this.range = range; - this.config = config; - this.ast = parse$2(abbreviation, config); - this.snippet = expand$2(this.ast, config); - this.preview = removeFields(this.snippet); - } - - /** - * Inserts current expanded abbreviation into given `editor` by replacing - * `range` - * @param {CodeMirror.Editor} editor - * @param {CodeMirror.Range} [range] - */ - insert(editor, range) { - return insertSnippet(editor, range || this.range, this.snippet); - } - - /** - * Check if parsed abbreviation is valid - * @param {Boolean} [contextAware] Perform context-aware validation: ensure - * that expanded result is expected at abbreviation location - */ - valid(editor, contextAware) { - if (this.preview && this.abbreviation !== this.preview) { - return contextAware && this.config.type === 'stylesheet' ? this._isValidForStylesheet(editor) : true; - } - - return false; - } - - _isValidForStylesheet(editor) { - const pos = this.range.from; - const token = editor.getTokenAt(pos); - - if (/^[#!]/.test(this.abbreviation)) { - // Abbreviation is a property value - return isCSSPropertyValue(editor, pos); - } - - // All expanded nodes are properties? Properties has names, regular snippets don’t. - const isProperty = this.ast.children.every(node => node.name); - const state = token.state && token.state.localState || token.state; - - if (isProperty) { - // Expanded abbreviation consists of properties: make sure we’re inside - // block context - // NB: in Sass, no actual block context since it’s indetation-based - return this.config.syntax === 'sass' || state && state.context && state.context.type === 'block'; - } - - // Expanded abbreviations are basic snippets: allow them everywhere, but forbid - // if expanded result equals abbreviation (meaningless). - return true; - } -}; - -/** - * Expand abbreviation command - * @param {CodeMirror.Editor} editor - * @param {Boolean} contextAware - */ - -function expandAbbreviation(editor, contextAware) { - if (editor.somethingSelected()) { - return editor.constructor.Pass; - } - - const abbr = abbreviationFromPosition(editor, editor.getCursor(), contextAware); - - if (abbr) { - abbr.insert(editor); - clearMarkers(editor); - return true; - } - - // If no abbreviation was expanded, allow editor to handle different - // action for keyboard shortcut (Tab key mostly) - return editor.constructor.Pass; -} - -function emmetInsertLineBreak(editor) { - const between = editor.listSelections().map(sel => betweenTags(editor, sel)); - - if (!between.some(Boolean)) { - return editor.constructor.Pass; - } - - editor.operation(() => { - let sels = editor.listSelections(); - const singleSep = editor.doc.lineSeparator(); - const doubleSep = singleSep + singleSep; - - // Step 1: insert newlines either single or double depending on selection - for (let i = sels.length - 1; i >= 0; i--) { - editor.replaceRange(between[i] ? doubleSep : singleSep, sels[i].anchor, sels[i].head, '+newline'); - } - - // Step 2: indent inserted lines - sels = editor.listSelections(); - for (let i = 0; i < sels.length; i++) { - editor.indentLine(sels[i].from().line, null, true); - - if (between[i]) { - editor.indentLine(sels[i].from().line - 1, null, true); - } - } - - // Step 3: adjust caret positions - editor.setSelections(editor.listSelections().map((sel, i) => { - if (between[i]) { - const line = sel.from().line - 1; - const cursor = { - line, - ch: editor.getLine(line).length - }; - return { anchor: cursor, head: cursor }; - } - - return sel; - })); - }); -} - -/** - * Check if given range is a single caret between tags - * @param {CodeMirror} editor - * @param {CodeMirror.range} range - */ -function betweenTags(editor, range) { - if (equalCursorPos(range.anchor, range.head)) { - const cursor = range.anchor; - const mode = editor.getModeAt(cursor); - - if (mode.name === 'xml') { - const left = editor.getTokenAt(cursor); - const right = editor.getTokenAt(emmet_codemirror_plugin_es__extends({}, cursor, { ch: cursor.ch + 1 })); - - return left.type === 'tag bracket' && left.string === '>' && right.type === 'tag bracket' && right.string === ' line.trim()); - - prompt(editor, 'Enter abbreviation to wrap with:', abbr => { - if (abbr) { - const model = new emmet_codemirror_plugin_es_Abbreviation(abbr, range, createConfig(editor, range.from, { text })); - model.insert(editor); - } - }); - } else { - console.warn('Nothing to wrap'); - } -} - -/** - * Returns content range that should be wrapped - * @param {CodeMirror} editor - */ -function getWrappingContentRange(editor) { - if (editor.somethingSelected()) { - const sel = editor.listSelections().filter(sel => sel.anchor !== sel.head)[0]; - if (sel) { - return comparePos$1(sel.anchor, sel.head) < 0 ? { from: sel.anchor, to: sel.head } : { from: sel.head, to: sel.anchor }; - } - } - - // Nothing selected, find parent HTML node and return range for its content - return getTagRangeForPos(editor, editor.getCursor()); -} - -/** - * Returns either inner or outer tag range (depending on `pos` location) - * for given position - * @param {CodeMirror} editor - * @param {Object} pos - * @return {Object} - */ -function getTagRangeForPos(editor, pos) { - const model = editor.getEmmetDocumentModel(); - const tag = model && model.nodeForPoint(pos); - - if (!tag) { - return null; - } - - // Depending on given position, return either outer or inner tag range - if (inRange(tag.open, pos) || inRange(tag.close, pos)) { - // Outer range - return rangeFromNode(tag); - } - - // Inner range - const from = tag.open.end; - const to = tag.close ? tag.close.start : tag.open.end; - - return narrowToNonSpace(editor, from, to); -} - -function inRange(tag, pos) { - return tag && containsPos(rangeFromNode(tag), pos); -} - -function defaultPrompt(editor, message, callback) { - callback(window.prompt(message)); -} - -/** - * Marks Emmet abbreviation for given editor position, if possible - * @param {CodeMirror.Editor} editor Editor where abbreviation marker should be created - * @param {CodeMirror.Position} pos Editor position where abbreviation marker - * should be created. Abbreviation will be automatically extracted from given position - * @return {CodeMirror.TextMarker} Returns `undefined` if no valid abbreviation under caret - */ -function markAbbreviation(editor, pos) { - const marker = findMarker(editor, pos); - if (marker) { - // there’s active marker with valid abbreviation - return marker; - } - - // No active marker: remove previous markers and create new one, if possible - clearMarkers(editor); - - const model = abbreviationFromPosition(editor, pos, true); - - if (model) { - return createMarker(editor, model); - } -} - -/** - * Returns available completions from given editor - * @param {CodeMirror.Editor} editor - * @param {Abbreviation} abbrModel Parsed Emmet abbreviation model for which - * completions should be populated - * @param {CodeMirror.Position} abbrPos Abbreviation location in editor - * @param {CodeMirror.Position} [pos] Cursor position in editor - * @return {EmmetCompletion[]} - */ -function autocompleteProvider(editor, pos) { - pos = pos || editor.getCursor(); - let completions = []; - - // Provide two types of completions: - // 1. Expanded abbreviation - // 2. Snippets - - const abbreviation = abbreviationFromPosition(editor, pos, true); - // NB: Check for edge case: expanded abbreviation equals to original - // abbreviation (for example, `li.item` expands to `li.item` in Slim), - // no need to provide completion for this case - if (abbreviation && abbreviation.abbreviation !== abbreviation.snippet) { - completions.push(expandedAbbreviationCompletion(editor, pos, abbreviation)); - } - - const config = abbreviation ? abbreviation.config : createConfig(editor, pos); - - if (config.type === 'stylesheet') { - completions = completions.concat(getStylesheetCompletions(editor, pos, config)); - } else { - completions = completions.concat(getMarkupCompletions(editor, pos, config)); - } - - return { - type: config.type, - syntax: config.syntax, - abbreviation, - completions: completions.filter(Boolean) - }; -} - -/** - * Returns completions for markup syntaxes (HTML, Slim, Pug etc.) - * @param {CodeMirror} editor - * @param {CodeMirror.Position} pos Cursor position in editor - * @param {Object} config Resolved Emmet config - * @return {EmmetCompletion[]} - */ -function getMarkupCompletions(editor, pos, config) { - const line = editor.getLine(pos.line).slice(0, pos.ch); - const prefix = extractPrefix(line, /[\w:\-$@]/); - - // Make sure that current position precedes element name (e.g. not attribute, - // class, id etc.) - if (prefix) { - const prefixRange = { - from: { line: pos.line, ch: pos.ch - prefix.length }, - to: pos - }; - - return getSnippetCompletions(editor, pos, config).filter(completion => completion.key !== prefix && completion.key.indexOf(prefix) === 0).map(completion => new EmmetCompletion('snippet', editor, prefixRange, completion.key, completion.preview, completion.snippet)); - } - - return []; -} - -/** - * Returns completions for stylesheet syntaxes - * @param {CodeMirror} editor - * @param {CodeMirror.Position} pos Cursor position in editor - * @param {Object} config Resolved Emmet config - * @return {EmmetCompletion[]} - */ -function getStylesheetCompletions(editor, pos, config) { - const line = editor.getLine(pos.line).slice(0, pos.ch); - const prefix = extractPrefix(line, /[\w-@$]/); - - if (prefix) { - // Make sure that current position precedes element name (e.g. not attribute, - // class, id etc.) - const prefixRange = { - from: { line: pos.line, ch: pos.ch - prefix.length }, - to: pos - }; - - if (config.options && config.options.property) { - const lowerProp = config.options.property.toLowerCase(); - // Find matching CSS property snippet for keyword completions - const completion = getSnippetCompletions(editor, pos, config).find(item => item.property && item.property === lowerProp); - - if (completion && completion.keywords.length) { - return completion.keywords.map(kw => { - return kw.key.indexOf(prefix) === 0 && new EmmetCompletion('value', editor, prefixRange, kw.key, kw.preview, kw.snippet); - }).filter(Boolean); - } - } else { - return getSnippetCompletions(editor, pos, config).filter(completion => completion.key !== prefix && completion.key.indexOf(prefix) === 0).map(completion => new EmmetCompletion('snippet', editor, prefixRange, completion.key, completion.preview, completion.snippet)); - } - } - - return []; -} - -/** - * Returns all possible snippets completions for given editor context. - * Completions are cached in editor for for re-use - * @param {CodeMirror.Editor} editor - * @param {CodeMirror.Position} pos - * @param {Object} config - * @return {Array} - */ -function getSnippetCompletions(editor, pos, config) { - const { type, syntax } = config; - - if (!editor.state.emmetCompletions) { - editor.state.emmetCompletions = {}; - } - - const cache = editor.state.emmetCompletions; - - if (!(syntax in cache)) { - const registry = createSnippetsRegistry(type, syntax, config.snippets); - - cache[syntax] = type === 'stylesheet' ? getStylesheetSnippets(registry, config) : getMarkupSnippets(registry, config); - } - - return cache[syntax]; -} - -/** - * Returns stylesheet snippets list - * @param {SnippetsRegistry} registry - * @return {Array} - */ -function getStylesheetSnippets(registry) { - return css_snippets_resolver_es_convertToCSSSnippets(registry).map(snippet => { - let preview = snippet.property; - const keywords = snippet.keywords(); - if (keywords.length) { - preview += `: ${removeFields(keywords.join(' | '))}`; - } else if (snippet.value) { - preview += `: ${removeFields(snippet.value)}`; - } - - return { - key: snippet.key, - value: snippet.value, - snippet: snippet.key, - property: snippet.property, - keywords: keywords.map(kw => { - const m = kw.match(/^[\w-]+/); - return m && { - key: m[0], - preview: removeFields(kw), - snippet: kw - }; - }).filter(Boolean), - preview - }; - }); -} - -/** - * Returns markup snippets list - * @param {SnippetsRegistry} registry - * @param {Object} config - * @return {Array} - */ -function getMarkupSnippets(registry, config) { - return registry.all({ type: 'string' }).map(snippet => ({ - key: snippet.key, - value: snippet.value, - preview: removeFields(expand$2(snippet.value, config)), - snippet: snippet.key - })); -} - -function expandedAbbreviationCompletion(editor, pos, abbrModel) { - let preview = abbrModel.preview; - if (preview.length > 500) { - preview = preview.slice(0, 500) + '...'; - } - - return new EmmetCompletion('expanded-abbreviation', editor, abbrModel.range, 'Expand abbreviation', preview, (editor, range) => abbrModel.insert(editor, range)); -} - -/** - * Extracts prefix from the end of given string that matches `match` regexp - * @param {String} str - * @param {RegExp} match - * @return {String} Extracted prefix - */ -function extractPrefix(str, match) { - let offset = str.length; - - while (offset > 0) { - if (!match.test(str[offset - 1])) { - break; - } - offset--; - } - - return str.slice(offset); -} - -let EmmetCompletion = class EmmetCompletion { - /** - * @param {String} type - * @param {CodeMirror.Editor} editor - * @param {CodeMirror.Range} range - * @param {String} name - * @param {String} preview - * @param {Function} snippet - */ - constructor(type, editor, range, name, preview, snippet) { - this.type = type; - this.editor = editor; - this.range = range; - this.name = name; - this.preview = preview; - this.snippet = snippet; - - this._inserted = false; - } - - insert() { - if (!this._inserted) { - this._inserted = true; - if (typeof this.snippet === 'function') { - this.snippet(this.editor, this.range); - } else { - insertSnippet(this.editor, this.range, this.snippet); - } - clearMarkers(this.editor); - } - } -}; - -/** - * A syntax-specific model container, used to get unified access to underlying - * parsed document - */ - -let SyntaxModel = class SyntaxModel { - /** - * @param {Object} dom Parsed document tree - * @param {String} type Type of document (html, stylesheet, etc.) - * @param {String} [syntax] Optional document syntax like html, xhtml or xml - */ - constructor(dom, type, syntax) { - this.dom = dom; - this.type = type; - this.syntax = syntax; - } - - /** - * Returns best matching node for given point - * @param {CodeMirror.Pos} pos - * @param {Boolean} [exclude] Exclude node’s start and end positions from - * search - * @return {Node} - */ - nodeForPoint(pos, exclude) { - let ctx = this.dom.firstChild; - let found = null; - - while (ctx) { - if (containsPos(rangeFromNode(ctx), pos, exclude)) { - // Found matching tag. Try to find deeper, more accurate match - found = ctx; - ctx = ctx.firstChild; - } else { - ctx = ctx.nextSibling; - } - } - - return found; - } -}; - -/** - * Creates DOM-like model for given text editor - * @param {CodeMirror} editor - * @param {String} syntax - * @return {Node} - */ - -function create(editor, syntax) { - const stream = new CodeMirrorStreamReader(editor); - const xml = syntax === 'xml'; - - try { - return new SyntaxModel(html_matcher_es(stream, { xml }), 'html', syntax || 'html'); - } catch (err) { - console.warn(err); - } -} - -function getModel(editor) { - const syntax = getSyntax$1(editor); - return create(editor, syntax); -} - -function getCachedModel(editor) { - if (!editor.state._emmetModel) { - editor.state._emmetModel = getModel(editor); - } - - return editor.state._emmetModel; -} - -function resetCachedModel(editor) { - editor.state._emmetModel = null; -} - -/** - * Returns parser-supported syntax of given editor (like 'html', 'css' etc.). - * Returns `null` if editor’s syntax is unsupported - * @param {CodeMirror} editor - * @return {String} - */ -function getSyntax$1(editor) { - const mode = editor.getMode(); - - if (mode.name === 'htmlmixed') { - return 'html'; - } - - return mode.name === 'xml' ? mode.configuration : mode.name; -} - -const openTagMark = 'emmet-open-tag'; -const closeTagMark = 'emmet-close-tag'; - -/** - * Finds matching tag pair for given position in editor - * @param {CodeMirror.Editor} editor - * @param {CodeMirror.Position} pos - * @return {Object} - */ -function matchTag(editor, pos) { - pos = pos || editor.getCursor(); - - // First, check if there are tag markers in editor - const marked = getMarkedTag(editor); - - // If marks found, validate them: make sure cursor is either in open - // or close tag - if (marked) { - if (containsPos(marked.open.find(), pos)) { - // Point is inside open tag, make sure if there’s a closing tag, - // it matches open tag content - if (!marked.close || emmet_codemirror_plugin_es_text(editor, marked.open) === emmet_codemirror_plugin_es_text(editor, marked.close)) { - return marked; - } - } else if (marked.close) { - // There’s a close tag, make sure pointer is inside it and it matches - // open tag - if (containsPos(marked.close.find(), pos) && emmet_codemirror_plugin_es_text(editor, marked.open) === emmet_codemirror_plugin_es_text(editor, marked.close)) { - return marked; - } - } - } - - // Markers are not valid anymore, remove them - clearTagMatch(editor); - - // Find new tag pair from parsed HTML model and mark them - const node = findTagPair(editor, pos); - if (node && node.type === 'tag') { - return { - open: createTagMark(editor, node.open.name, openTagMark), - close: node.close && createTagMark(editor, node.close.name, closeTagMark) - }; - } -} - -function getMarkedTag(editor) { - let open, close; - editor.getAllMarks().forEach(mark => { - if (mark.className === openTagMark) { - open = mark; - } else if (mark.className === closeTagMark) { - close = mark; - } - }); - - return open ? { open, close } : null; -} - -/** - * Removes all matched tag pair markers from editor - * @param {CodeMirror.Editor} editor - */ -function clearTagMatch(editor) { - editor.getAllMarks().forEach(mark => { - if (mark.className === openTagMark || mark.className === closeTagMark) { - mark.clear(); - } - }); -} - -/** - * Finds tag pair (open and close, if any) form parsed HTML model of given editor - * @param {CodeMirror.Editor} editor - * @param {CodeMirror.Position} pos - * @return {Object} - */ -function findTagPair(editor, pos) { - const model = editor.getEmmetDocumentModel(); - return model && model.nodeForPoint(pos || editor.getCursor()); -} - -function createTagMark(editor, tag, className) { - return editor.markText(tag.start, tag.end, { - className, - inclusiveLeft: true, - inclusiveRight: true, - clearWhenEmpty: false - }); -} - -function emmet_codemirror_plugin_es_text(editor, mark) { - const range = mark.find(); - return range ? editor.getRange(range.from, range.to) : ''; -} - -function renameTag(editor, obj) { - const tag = getMarkedTag(editor); - const pos = obj.from; - - if (!tag) { - return; - } - - if (containsPos(tag.open.find(), pos) && tag.close) { - // Update happened inside open tag, update close tag as well - updateTag(editor, tag.open, tag.close); - } else if (tag.close && containsPos(tag.close.find(), pos)) { - // Update happened inside close tag, update open tag as well - updateTag(editor, tag.close, tag.open); - } -} - -function updateTag(editor, source, dest) { - const name = text$1(editor, source); - const range = dest.find(); - const m = name.match(/[\w:.-]+/); - const newName = !name ? '' : m && m[0]; - - if (newName != null) { - if (editor.getRange(range.from, range.to) !== newName) { - editor.replaceRange(newName, range.from, range.to); - } - } else { - // User entered something that wasn’t a valid tag name. - clearTagMatch(editor); - } -} - -function text$1(editor, mark) { - const range = mark.find(); - return range ? editor.getRange(range.from, range.to) : ''; -} - -/** - * Registers Emmet extension on given CodeMirror constructor. - * This file is designed to be imported somehow into the app (CommonJS, ES6, - * Rollup/Webpack/whatever). If you simply want to add a